diff --git a/.agents b/.agents new file mode 160000 index 0000000000..c677fd615f --- /dev/null +++ b/.agents @@ -0,0 +1 @@ +Subproject commit c677fd615fbcc4cef329ef12e4e9ad7eea4cff3d diff --git a/roles/importer/files/importer/azure2022ff/__init__.py b/.codex similarity index 100% rename from roles/importer/files/importer/azure2022ff/__init__.py rename to .codex diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000000..0baf3a7bfe --- /dev/null +++ b/.editorconfig @@ -0,0 +1,18 @@ +# top-level editorconfig file +# should be the same file as the one for solution in roles directory + +root = true + +[*] +end_of_line = lf +insert_final_newline = true +charset = utf-8 + +[*.cs] +indent_style = space +indent_size = 4 +trim_trailing_whitespace = false + +[*.razor] +indent_style = space +indent_size = 4 diff --git a/.gitattributes b/.gitattributes index 703f86ebc2..3586e38043 100644 --- a/.gitattributes +++ b/.gitattributes @@ -23,3 +23,7 @@ roles/sample-data-connect-sting/** -linguist-detectable roles/sample-data/** -linguist-detectable roles/test/** -linguist-detectable ############################################################# + +# Git canonical EOL policy +* text=auto eol=lf + diff --git a/.githooks/post-checkout b/.githooks/post-checkout new file mode 100755 index 0000000000..83b88fb5a1 --- /dev/null +++ b/.githooks/post-checkout @@ -0,0 +1,2 @@ +#!/usr/bin/env bash +"$(dirname "$0")/submodule-sync" diff --git a/.githooks/post-merge b/.githooks/post-merge new file mode 100755 index 0000000000..83b88fb5a1 --- /dev/null +++ b/.githooks/post-merge @@ -0,0 +1,2 @@ +#!/usr/bin/env bash +"$(dirname "$0")/submodule-sync" diff --git a/.githooks/post-rewrite b/.githooks/post-rewrite new file mode 100755 index 0000000000..83b88fb5a1 --- /dev/null +++ b/.githooks/post-rewrite @@ -0,0 +1,2 @@ +#!/usr/bin/env bash +"$(dirname "$0")/submodule-sync" diff --git a/.githooks/pre-commit b/.githooks/pre-commit new file mode 100755 index 0000000000..32a482dffb --- /dev/null +++ b/.githooks/pre-commit @@ -0,0 +1,87 @@ +#!/usr/bin/env bash +set -euo pipefail + +VENV_BIN="" + +# Load config file +CONFIG_FILE=".githooks/tooling.env" +set -a +source "$CONFIG_FILE" +set +a + +if [ -d ".venv/Scripts" ]; then + # Using virtual environment from .venv (Windows) + VENV_BIN=".venv/Scripts/" + source ".venv/Scripts/activate" +elif [ -d ".venv/bin" ]; then + # Using virtual environment from .venv (Unix) + VENV_BIN=".venv/bin/" + source ".venv/bin/activate" +elif command -v conda >/dev/null 2>&1; then + # Using conda + CONDA_BASE="$(conda info --base)" + source "$CONDA_BASE/etc/profile.d/conda.sh" + conda activate "$CONDA_ENV" + if [ -d "$CONDA_PREFIX/Scripts" ]; then + # Conda Windows + VENV_BIN="$CONDA_PREFIX/Scripts/" + else + # Conda Unix + VENV_BIN="$CONDA_PREFIX/bin/" + fi +fi + +if [ -z "$VENV_BIN" ]; then + echo "Warning: No virtual environment found. Assuming python (with ruff and pyright) is available in base environment." +fi + +# Assure dotnet and python are available +UNAVAILABLE_DEPENDENCIES=false +for cmd in "dotnet" "python"; do + command -v "$cmd" >/dev/null 2>&1 || { + echo "Error: '$cmd' not found. Please install it or activate your environment." + UNAVAILABLE_DEPENDENCIES=true + } +done +if $UNAVAILABLE_DEPENDENCIES; then + exit 1; +fi + +PYTHON_PATH="$(command -v python)" + +# Assure ruff and pyright are available +for python_tool in ruff pyright; do + if ! "$PYTHON_PATH" -m "$python_tool" --version >/dev/null 2>&1; then + echo "Error: 'python -m $python_tool' is not available. Please install $python_tool in the active environment." + exit 1 + fi +done + +# Python Checks +"$PYTHON_PATH" -m ruff check --fix +"$PYTHON_PATH" -m ruff format +"$PYTHON_PATH" -m pyright + +# Determine changed Dotnet files +STAGED_ROLES_DOTNET_FORMAT_FILES=() +while IFS= read -r -d '' staged_file; do + case "$staged_file" in + roles/*.cs|roles/*.razor|roles/*.cshtml) + STAGED_ROLES_DOTNET_FORMAT_FILES+=("${staged_file#roles/}") + ;; + esac +done < <(git diff --cached --name-only -z --diff-filter=ACMR -- '*.cs' '*.razor' '*.cshtml') + +# If any Dontet files have been changed run +# Dotnet checks +if [ "${#STAGED_ROLES_DOTNET_FORMAT_FILES[@]}" -gt 0 ]; then + dotnet format roles --no-restore --include "${STAGED_ROLES_DOTNET_FORMAT_FILES[@]}" +fi + +# Prevent committing submodule pointer updates (auto-unstage) +for submodule in $CHECK_SUBMODULE_POINTERS; do + if ! git diff --cached --quiet --ignore-submodules=none -- "$submodule"; then + echo "Info: Unstaging '$submodule' submodule pointer change (not allowed in commits)." + git restore --staged -- "$submodule" >/dev/null 2>&1 + fi +done diff --git a/.githooks/submodule-sync b/.githooks/submodule-sync new file mode 100755 index 0000000000..4677c2c97c --- /dev/null +++ b/.githooks/submodule-sync @@ -0,0 +1,71 @@ +#!/usr/bin/env bash +set -euo pipefail + +# Sync submodules quietly after common Git operations. + +# Resolve repository root; bail out if not inside a Git repo. +repo_root="$(git rev-parse --show-toplevel 2>/dev/null || true)" +if [[ -z "${repo_root}" ]]; then + exit 0 +fi + +cd "${repo_root}" + +# No submodules configured. +if [[ ! -f .gitmodules ]]; then + exit 0 +fi + +# No submodule paths registered in .gitmodules. +if ! git config --file .gitmodules --get-regexp '^submodule\..*\.path$' >/dev/null 2>&1; then + exit 0 +fi + +# Disable prompts and keep this hook silent for users without repo access. +export GIT_TERMINAL_PROMPT=0 +export GIT_ASKPASS=/bin/true +export GIT_SSH_COMMAND="ssh -o BatchMode=yes" + +run_quiet() { + # Ignore failures to avoid blocking normal Git operations. + "$@" >/dev/null 2>&1 || true +} + +# Initialize submodules first so each path exists. +run_quiet git submodule update --init --recursive + +# Iterate configured submodules to ensure we are on a branch (not detached). +while read -r key path; do + # Convert `submodule..path` -> ``. + name="${key#submodule.}" + name="${name%.path}" + + # Skip if the submodule path is missing or not initialized. + if [[ ! -d "${path}" ]]; then + continue + fi + + # Skip if the path is not a Git repo. + if ! git -C "${path}" rev-parse --git-dir >/dev/null 2>&1; then + continue + fi + + # Prefer repo-local submodule..branch, fallback to .gitmodules. + branch="$(git config --get "submodule.${name}.branch" || true)" + if [[ -z "${branch}" ]]; then + branch="$(git config --file .gitmodules --get "submodule.${name}.branch" || true)" + fi + + if [[ -n "${branch}" ]]; then + # Try to checkout the branch if it already exists locally. + run_quiet git -C "${path}" checkout -q "${branch}" + + # If still detached, create/reset the branch from origin. + if ! git -C "${path}" symbolic-ref -q HEAD >/dev/null 2>&1; then + run_quiet git -C "${path}" checkout -q -B "${branch}" "origin/${branch}" + fi + fi +done < <(git config --file .gitmodules --get-regexp '^submodule\..*\.path$') + +# Move submodules to the newest commit on their tracking branch, merging instead of detaching. +run_quiet git submodule update --remote --merge --recursive diff --git a/.githooks/tooling.env b/.githooks/tooling.env new file mode 100644 index 0000000000..d425827ae5 --- /dev/null +++ b/.githooks/tooling.env @@ -0,0 +1,2 @@ +CONDA_ENV=fwo +CHECK_SUBMODULE_POINTERS=".agents" \ No newline at end of file diff --git a/.github/dependabot.yml b/.github/dependabot.yml index 69add6874a..525b77ec5e 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -1,8 +1,17 @@ version: 2 +registries: + private-github: + type: git + url: https://github.com + username: x-access-token + password: ${{ secrets.PRIVATE_SUBMODULE_TOKEN }} + updates: - package-ecosystem: "nuget" directory: "/roles/" target-branch: "develop" schedule: interval: "daily" + registries: + - private-github diff --git a/.github/workflows/auto-sync-develop-to-importer-rework.yml.disabled b/.github/workflows/auto-sync-develop-to-importer-rework.yml.disabled new file mode 100644 index 0000000000..aea616f26a --- /dev/null +++ b/.github/workflows/auto-sync-develop-to-importer-rework.yml.disabled @@ -0,0 +1,82 @@ +name: Sync develop to importer-rework + +on: + push: + branches: [develop] + +permissions: + contents: write + pull-requests: write + +jobs: + sync-branches: + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - name: Set up Git + run: | + git config --global user.name "github-actions[bot]" + git config --global user.email "github-actions[bot]@users.noreply.github.com" + + - name: Ensure "automation" label exists + run: | + gh label create automation \ + --color "0e8a16" \ + --description "Automatically created for syncing branches" \ + --force + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + + - name: Compute ahead/behind + id: ab + run: | + git fetch origin develop importer-rework + read behind ahead < <(git rev-list --left-right --count origin/importer-rework...origin/develop) + echo "ahead=$ahead" >> $GITHUB_OUTPUT + echo "behind=$behind" >> $GITHUB_OUTPUT + # rev-list separates counts with a TAB. :contentReference[oaicite:2]{index=2} + + - name: Push sync branch (mirror develop) + if: steps.ab.outputs.ahead != '0' + run: | + BR=bot/sync-develop-into-importer-rework + git checkout -B "$BR" origin/develop + git push -f origin "HEAD:$BR" + + - name: Check for existing PR (sync branch → importer-rework) + id: pr_check + if: steps.ab.outputs.ahead != '0' + run: | + existing_pr=$(gh pr list \ + --base importer-rework \ + --head bot/sync-develop-into-importer-rework \ + --state open \ + --json number \ + --jq '.[0].number // empty') + echo "existing_pr=$existing_pr" >> $GITHUB_OUTPUT + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + + - name: Create PR from sync branch to importer-rework + if: steps.ab.outputs.ahead != '0' && steps.pr_check.outputs.existing_pr == '' + run: | + gh pr create \ + --base importer-rework \ + --head bot/sync-develop-into-importer-rework \ + --title "Sync develop → importer-rework" \ + --body "Auto-sync from \`develop\` via sync branch." \ + --label automation + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + + # OPTIONAL: Automatically merge the PR if all checks pass + # - name: Auto-merge PR + # if: steps.pr_check.outputs.existing_pr != '' + # run: | + # gh pr merge "${{ steps.pr_check.outputs.existing_pr }}" --merge --admin + # env: + # GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/full-test-install.yml b/.github/workflows/full-test-install.yml new file mode 100644 index 0000000000..be582c37d1 --- /dev/null +++ b/.github/workflows/full-test-install.yml @@ -0,0 +1,48 @@ +name: Full Test Install + +on: + push: + branches: + - main + +jobs: + test-install: + name: Test install on ${{ matrix.os }} with Python ${{ matrix.python-version }} + runs-on: ${{ matrix.os }} + env: + RUNNING_ON_GITHUB_ACTIONS: true + strategy: + fail-fast: false + matrix: + os: [ubuntu-24.04, ubuntu-22.04] + python-version: ['3.10', '3.11', '3.12', '3.13', '3.14'] + steps: + - uses: actions/checkout@v6 + + - uses: actions/setup-dotnet@v5 + with: + dotnet-version: '8.0.x' + + - uses: actions/setup-python@v6 + with: + python-version: ${{ matrix.python-version }} + + - name: Install dependencies + run: | + sudo apt update + sudo DEBIAN_FRONTEND=noninteractive apt install build-essential ldap-utils libldap2-dev libsasl2-dev -y + python -m pip install ansible psycopg2-binary python-ldap requests + + - name: Run Ansible test install + run: | + cd ${{ github.workspace }} + ansible-playbook -e force_install=true -e "ansible_python_interpreter=$(which python)" site.yml -K + + - name: Running in GitHub actions requires testing puppeteer pdf creation separately + if: ${{ env.RUNNING_ON_GITHUB_ACTIONS == 'true' }} + run: | + cd ${{ github.workspace }}/roles/tests-unit/files/FWO.Test + dotnet restore + dotnet build + dotnet test --filter "Name=HtmlToPdfTest" + diff --git a/.github/workflows/test-install.yml b/.github/workflows/test-install.yml index 9eb0b10d4a..e53917e0fd 100644 --- a/.github/workflows/test-install.yml +++ b/.github/workflows/test-install.yml @@ -1,49 +1,64 @@ - -name: Build - -# Controls when the action will run. Triggers the workflow on push or pull request -# events but only for the master branch -# test change +name: FWO Test Install on: push: - branches: [ main, develop ] - paths-ignore: - - 'documentation/**' - - 'design/**' + branches: + - main + - develop + - importer-rework pull_request: - types: [ ready_for_review, review_requested ] - branches: [ main, develop ] - paths-ignore: - - 'documentation/**' - - 'design/**' -# A workflow run is made up of one or more jobs that can run sequentially or in parallel jobs: - # ubuntu18 was unstable at github (2022-07-06 - 2022-07-11) - # test_ubuntu_18: - # name: test build on ubuntu_18 - # runs-on: ubuntu-18.04 - # steps: - # - uses: actions/checkout@v3 - # - name: do test install in case of merged pull request - # run: cd /home/runner/work/firewall-orchestrator/firewall-orchestrator && ansible-playbook -e run_on_github=yes --skip-tags test site.yml -K - - test_ubuntu_20: - name: test build on ubuntu_20 - runs-on: ubuntu-20.04 + test-install: + name: Test install on ${{ matrix.os }} + runs-on: ${{ matrix.os }} + env: + RUNNING_ON_GITHUB_ACTIONS: true + strategy: + matrix: + os: [ubuntu-latest] + steps: + - uses: actions/checkout@v6 + + - uses: actions/setup-dotnet@v5 + with: + dotnet-version: '8.0.x' + + - name: Run Ansible test install + run: | + cd /home/runner/work/firewall-orchestrator/firewall-orchestrator + ansible-playbook -e force_install=true site.yml -K + + - name: Running in GitHub actions requires testing puppeteer pdf creation separately + if: ${{ env.RUNNING_ON_GITHUB_ACTIONS == 'true' }} + run: | + cd /home/runner/work/firewall-orchestrator/firewall-orchestrator/roles/tests-unit/files/FWO.Test + dotnet restore + dotnet build + dotnet test --filter "Name=HtmlToPdfTest" + + + python-code-check: + name: Python Code Check + runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 - - name: do test install in case of merged pull request - run: cd /home/runner/work/firewall-orchestrator/firewall-orchestrator && ansible-playbook -e run_on_github=yes site.yml -K -# run: cd /home/runner/work/firewall-orchestrator/firewall-orchestrator && ansible-playbook -e run_on_github=yes --skip-tags test site.yml -K - - # test_ubuntu_22: - # name: test build on ubuntu_22 - # runs-on: ubuntu-22.04 - # steps: - # - uses: actions/checkout@v3 - # - name: do test install in case of merged pull request - # run: cd /home/runner/work/firewall-orchestrator/firewall-orchestrator && ansible-playbook -e run_on_github=yes site.yml -K - # run: cd /home/runner/work/firewall-orchestrator/firewall-orchestrator && ansible-playbook -e run_on_github=yes --skip-tags test site.yml -K + - uses: actions/checkout@v6 + + - uses: actions/setup-python@v6 + with: + python-version: '3.11' + + - run: pip install -r roles/importer/files/importer/requirements.txt + + - run: pip install -r scripts/customizing/app_data_import/requirements-for-app-data-import.txt + + - uses: astral-sh/ruff-action@0ce1b0bf8b818ef400413f810f8a11cdbda0034b + with: + version: "0.15.0" + + - run: pyright + + - run: ruff check + + - run: ruff format --exit-non-zero-on-format \ No newline at end of file diff --git a/.github/workflows/update-agents-submodule-pr.yml.disabled b/.github/workflows/update-agents-submodule-pr.yml.disabled new file mode 100644 index 0000000000..d1b7a86343 --- /dev/null +++ b/.github/workflows/update-agents-submodule-pr.yml.disabled @@ -0,0 +1,71 @@ +name: Update agents submodule pointer + +on: + schedule: + - cron: "*/5 * * * *" + workflow_dispatch: + +permissions: + contents: write + pull-requests: write + +concurrency: + group: update-agents-submodule-pointer + cancel-in-progress: true + +jobs: + update-submodule: + runs-on: ubuntu-latest + + steps: + - name: Checkout repository + uses: actions/checkout@0c366fd6a839edf440554fa01a7085ccba70ac98 + with: + fetch-depth: 0 # get full repo history + submodules: recursive + token: ${{ secrets.SUBMODULE_READ_TOKEN }} # read-only token for submodules / main repo + persist-credentials: true + + - name: Advance agents submodule to configured upstream branch + id: submodule + run: | + set -euo pipefail + + before_sha="$(git ls-tree HEAD .agents | awk '{print $3}')" + source_branch="$(git config -f .gitmodules --get submodule.agents.branch)" + source_url="$(git config -f .gitmodules --get submodule.agents.url)" + + git -C .agents fetch origin "$source_branch" --quiet + git -C .agents checkout --quiet --detach "origin/$source_branch" + after_sha="$(git -C .agents rev-parse HEAD)" + + echo "before_sha=$before_sha" >> "$GITHUB_OUTPUT" + echo "after_sha=$after_sha" >> "$GITHUB_OUTPUT" + echo "source_branch=$source_branch" >> "$GITHUB_OUTPUT" + echo "source_url=$source_url" >> "$GITHUB_OUTPUT" + + if [ "$before_sha" = "$after_sha" ]; then + echo "changed=false" >> "$GITHUB_OUTPUT" + exit 0 + fi + + git add .agents + echo "changed=true" >> "$GITHUB_OUTPUT" + + - name: Create or update pull request + if: steps.submodule.outputs.changed == 'true' + uses: peter-evans/create-pull-request@3f3b473b8c148f5a7520efb4d1f9a70eea3d9d1f + with: + base: develop # target + token: ${{ secrets.GITHUB_TOKEN }} + branch: bot/update-agents-submodule # source + delete-branch: true # delete branch after merge + commit-message: "Chore(submodule): Update agents to ${{ steps.submodule.outputs.after_sha }}" + title: "Chore(submodule): Update agents to ${{ steps.submodule.outputs.after_sha }}" + body: | + Automated submodule pointer update for `agents`. + + - Previous pointer: `${{ steps.submodule.outputs.before_sha }}` + - New pointer: `${{ steps.submodule.outputs.after_sha }}` + - Source repository: `${{ steps.submodule.outputs.source_url }}` + - Source branch: `${{ steps.submodule.outputs.source_branch }}` diff --git a/.gitignore b/.gitignore index 7cd4f17718..e9f18b0740 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,72 @@ .vs/ -.idea/ +.vscode/launch.json +.vscode/settings.local.json +.vscode/settings.json +.vscode/launch.json .test_data/ roles/importer/venv/ +ansible_venv/ +*.todo +**/.venv/ +**/__pycache__/ +**/*.pyc + +# Created by https://www.toptal.com/developers/gitignore/api/jetbrains+iml +# Edit at https://www.toptal.com/developers/gitignore?templates=jetbrains+iml + +### JetBrains+iml ### +# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio, WebStorm and Rider +# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839 + +# Jetbrains IDE generated content +**/.idea/ +# Specifically instructed to keep this file out of the ignore +!.idea/ +!.idea/ruff.xml + +# Gradle and Maven with auto-import +# When using Gradle or Maven with auto-import, you should exclude module files, +# since they will be recreated, and may cause churn. Uncomment if using +# auto-import. +# *.iml +# *.ipr + +# CMake +cmake-build-*/ + +# File-based project format +*.iws + +# IntelliJ +out/ + +# mpeltonen/sbt-idea plugin +.idea_modules/ + +# JIRA plugin +atlassian-ide-plugin.xml + +# Crashlytics plugin (for Android Studio and IntelliJ) +com_crashlytics_export_strings.xml +crashlytics.properties +crashlytics-build.properties +fabric.properties + +### JetBrains+iml Patch ### +# Reason: https://github.com/joeblau/gitignore.io/issues/186#issuecomment-249601023 + +*.iml +modules.xml +*.ipr + +# End of https://www.toptal.com/developers/gitignore/api/jetbrains+iml + +.idea/copilot* +.idea/vcs.xml +.idea/inspectionProfiles +.idea/.gitignore +cov.xml +.coverage +.DS_Store +.dotnet +**/.codex/ diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000000..4633cb3c5f --- /dev/null +++ b/.gitmodules @@ -0,0 +1,4 @@ +[submodule "agents"] + path = .agents + url = https://github.com/CactuseSecurity/firewall-orchestrator-agents + branch = main diff --git a/.idea/ruff.xml b/.idea/ruff.xml new file mode 100644 index 0000000000..01e90d2137 --- /dev/null +++ b/.idea/ruff.xml @@ -0,0 +1,8 @@ + + + + + \ No newline at end of file diff --git a/.sonarlint/FWO.json b/.sonarlint/FWO.json new file mode 100644 index 0000000000..3d268041d8 --- /dev/null +++ b/.sonarlint/FWO.json @@ -0,0 +1,6 @@ +{ + "sonarCloudOrganization": "cactusesecurity", + "projectKey": "CactuseSecurity_firewall-orchestrator", + "region": "EU", + "sonar.scanner.scanAll": false +} diff --git a/.vscode/launch.json b/.vscode/launch.json deleted file mode 100644 index 6bd4e9b140..0000000000 --- a/.vscode/launch.json +++ /dev/null @@ -1,308 +0,0 @@ -{ - "version": "0.2.0", - "configurations": [ - { - "name": "c#-MiddlewareServer", - "type": "coreclr", - "request": "launch", - "preLaunchTask": "build_middleware", - "enableStepFiltering": false, - "program": "${workspaceFolder}/roles/middleware/files/FWO.Middleware.Server/bin/Debug/net6.0/FWO.Middleware.Server.dll", - "args": [], - "cwd": "${workspaceFolder}/roles/middleware/files/FWO.Middleware.Server", - "console": "internalConsole", - "stopAtEntry": false, - "requireExactSource": false, - "serverReadyAction": { - "action": "openExternally", - "pattern": "\\bNow listening on:\\s+(https?://\\S+)", - "uriFormat": "%s/swagger" - }, - "logging": { - "moduleLoad": false - } - }, - { - "name": "c#-Blazor UI", - "type": "coreclr", - "request": "launch", - "preLaunchTask": "build_UI", - "program": "${workspaceFolder}/roles/ui/files/FWO.UI/bin/Debug/net6.0/FWO.Ui.dll", - "args": [], - "cwd": "${workspaceFolder}/roles/ui/files/FWO.UI", - "stopAtEntry": false, - "requireExactSource": false, - "serverReadyAction": { - "action": "openExternally", - "pattern": "\\bNow listening on:\\s+(https?://\\S+)" - }, - "env": { - "ASPNETCORE_ENVIRONMENT": "Development" - }, - "sourceFileMap": { - "/Views": "${workspaceFolder}/Views" - }, - "logging": { - "moduleLoad": false - } - }, - { - "name": "py-import-mgm", - "type": "python", - "request": "launch", - "program": "${workspaceFolder}/roles/importer/files/importer/import-mgm.py", - "console": "integratedTerminal", - "env": { - "PYTHONPATH": "${PYTHONPATH}:${workspaceRoot}" - }, - "args": [ - "-m68", - "-d6", - "-f", - "-s", - //"-c" - //"-l250" - // 41 - lab fortimanager - //"-nhttps://fwodemodata.cactus.de/demo07_dummyGw1.json" - //"-ihttps://fwodemodata.cactus.de/demo04_cpr8x.json", - //"-ihttps://fwodemodata.cactus.de/demo01_fortiMgrLab.json" - //"-ihttps://fwodemodata.cactus.de/demo05_fortiMgr2.json" - //"-ihttps://fwodemodata.cactus.de/big/xxx.json", - ] - }, - { - "name": "py-acquire-lock", - "type": "python", - "request": "launch", - "program": "${workspaceFolder}/roles/common/files/acquire_lock.py", - "console": "integratedTerminal", - "env": { - "PYTHONPATH": "${PYTHONPATH}:${workspaceRoot}" - }, - "args": [ - "/var/fworch/lock/FWO.Middleware.Server_log.lock" - ] - }, - { - "name": "py-generate-tenant-data", - "type": "python", - "request": "launch", - "program": "${workspaceFolder}/roles/test/files/tenant_networks/create_tenant_network_data.py", - "console": "integratedTerminal", - "env": { - "PYTHONPATH": "${PYTHONPATH}:${workspaceRoot}" - }, - "args": [] - }, - { - "name": "py-change-comment", - "type": "python", - "request": "launch", - "program": "${workspaceFolder}/roles/sample-data/files/config_changes/write_date_to_comment.py", - "console": "integratedTerminal", - "env": { - "PYTHONPATH": "${PYTHONPATH}:${workspaceRoot}" - }, - "args": [] - }, - { - "name": "py-change-rule", - "type": "python", - "request": "launch", - "program": "${workspaceFolder}/roles/sample-data/files/config_changes/enlarge_rule.py", - "console": "integratedTerminal", - "env": { - "PYTHONPATH": "${PYTHONPATH}:${workspaceRoot}" - }, - "args": [] - }, - { - "name": "py-cpr8x-get-config", - "type": "python", - "request": "launch", - "program": "${workspaceFolder}/roles/importer/files/importer/checkpointR8x/get_config.py", - "console": "integratedTerminal", - "env": { - "PYTHONPATH": "${PYTHONPATH}:${workspaceRoot}" - }, - "args": [ - "-asting-mgmt", - "-uitsecorg", - "-w/home/tim/tmp/passwd", - "-lFirstLayer shared with inline layer", - "-kTestPolicyWithLayers", - "-o/home/tim/tmp/sting.cfg" - ] - }, - { - "name": "py-cpr8x-enrich-config", - "type": "python", - "request": "launch", - "program": "${workspaceFolder}/roles/importer/files/importer/checkpointR8x/enrich_config.py", - "console": "integratedTerminal", - "env": { - "PYTHONPATH": "${PYTHONPATH}:${workspaceRoot}" - }, - "args": [ - "-asting-mgmt", - "-uitsecorg", - "-w/home/tim/tmp/passwd", - "-lFirstLayer shared with inline layer", - "-c/home/tim/tmp/sting.cfg" - ] - }, - { - "name": "py-cpr8x-parse-config", - "type": "python", - "request": "launch", - "program": "${workspaceFolder}/roles/importer/files/importer/checkpointR8x/parse_config.py", - "console": "integratedTerminal", - "env": { - "PYTHONPATH": "${PYTHONPATH}:${workspaceRoot}" - }, - "args": [ - "-f/home/tim/tmp/sting.cfg", - "-rFirstLayer shared with inline layer" - ] - }, - { - "name": "py-cpr8x-api-test-call", - "type": "python", - "request": "launch", - "program": "${workspaceFolder}/roles/importer/files/importer/checkpointR8x/api-test-call.py", - "console": "integratedTerminal", - "env": { - "PYTHONPATH": "${PYTHONPATH}:${workspaceRoot}" - }, - "args": [ - "--help" - ] - }, - { - "name": "py-get-config-fm7", - "type": "python", - "request": "launch", - "program": "${workspaceFolder}/roles/importer/files/importer/fortimanager5ff/get_config.py", - "console": "integratedTerminal", - "env": { - "PYTHONPATH": "${PYTHONPATH}:${workspaceRoot}" - }, - "args": [ - "-a10.5.1.55", - "-uapiuser", - "-w/home/tim/tmp/passwd", - "-llayer1", - "-d1", - "-o/tmp/outfile" - ] - }, - { - "name": "py-export-itsecorg", - "type": "python", - "request": "launch", - "program": "${workspaceFolder}/roles/api/files/scripts/fwo-export-itsecorg-devices.py", - "console": "integratedTerminal", - "env": { - "PYTHONPATH": "${PYTHONPATH}:${workspaceRoot}" - }, - "args": [ - "-m/usr/local/fworch/tmp/mgm.csv", - "-d/usr/local/fworch/tmp/dev.csv", - "-o/usr/local/fworch/tmp/devices.graphql", - "-sfworch", - "-f7" - ] - }, - { - "name": "py-export-config", - "type": "python", - "request": "launch", - "program": "${workspaceFolder}/roles/api/files/scripts/fwo-export-config.py", - "console": "integratedTerminal", - "env": { - "PYTHONPATH": "${PYTHONPATH}:${workspaceRoot}" - }, - "args": [ - "-o/tmp/fworch-config" - ] - }, - { - "name": "py-execute-graphql", - "type": "python", - "request": "launch", - "program": "${workspaceFolder}/roles/api/files/scripts/fwo-execute-graphql.py", - "console": "integratedTerminal", - "env": { - "PYTHONPATH": "${PYTHONPATH}:${workspaceRoot}" - }, - "args": [ - "-i/tmp/fworch-config.graphql" - ] - }, - { - "name": "py-execute-graphql-query", - "type": "python", - "request": "launch", - "program": "${workspaceFolder}/roles/api/files/scripts/fwo-execute-graphql-query.py", - "console": "integratedTerminal", - "env": { - "PYTHONPATH": "${PYTHONPATH}:${workspaceRoot}" - }, - "args": [ - "-i/tmp/fworch-config.graphql" - ] - }, - { - "name": "py-cpr8x-autodiscovery", - "type": "python", - "request": "launch", - "program": "${workspaceFolder}/roles/importer/files/importer/checkpointR8x/auto-discover.py", - "console": "integratedTerminal", - "cwd": "${workspaceFolder}/roles/importer/files/importer/checkpointR8x", - "env": { - "PYTHONPATH": "${PYTHONPATH}:${workspaceRoot}" - }, - "args": [ - "-a192.168.100.110", - "-w/home/tim/secrets/cp_apiuser_pwd", - "-uitsecorg", - "-d4", - "-fjson" - ] - }, - { - "name": "py-import-main-loop", - "type": "python", - "request": "launch", - "program": "${workspaceFolder}/roles/importer/files/importer/import-main-loop.py", - "console": "integratedTerminal", - "env": { - "PYTHONPATH": "${PYTHONPATH}:${workspaceRoot}" - }, - "args": [ - //"-c", - //"-f", - "-d0" - ] - }, - { - "name": "c#-FWO Test", - "type": "coreclr", - "request": "launch", - "preLaunchTask": "build_test", - "program": "/usr/bin/dotnet", - "args": [ - "test" - ], - "cwd": "${workspaceFolder}/roles/test/files/FWO.Test", - "stopAtEntry": true, - "console": "integratedTerminal" - }, - { - "name": "c#-.NET Core Attach ", - "type": "coreclr", - "request": "attach", - "processId": "${command:pickProcess}" - } - ] -} \ No newline at end of file diff --git a/.vscode/launch.template.json b/.vscode/launch.template.json new file mode 100644 index 0000000000..21f13c9865 --- /dev/null +++ b/.vscode/launch.template.json @@ -0,0 +1,460 @@ +{ + "version": "0.2.0", + "compounds": [ + { + "name": "Launch MW and UI", + "configurations": [ + "c#-MiddlewareServer", + "c#-Blazor UI" + ] + } + ], + "configurations": [ + { + "name": ".NET Core SSH Attach ubu20", + "type": "coreclr", + "request": "attach", + "processId": "${command:pickRemoteProcess}", + "pipeTransport": { + "pipeProgram": "ssh", + "pipeArgs": [ + "-T", + "-p 22006", + "tim@localhost" + ], + "debuggerPath": "~/vsdbg-root/vsdbg", + "pipeCwd": "${workspaceRoot}", + "quoteArgs": true + }, + "sourceFileMap": { + "/home/tim/firewall-orchestrator/roles": "${workspaceRoot}" + }, + "logging": { + "logging.diagnosticsLog.protocolMessages": true + } + }, + { + "name": "c#-MiddlewareServer", + "type": "coreclr", + "request": "launch", + "preLaunchTask": "build_middleware", + "enableStepFiltering": false, + "program": "${workspaceFolder}/roles/middleware/files/FWO.Middleware.Server/bin/Debug/net10.0/FWO.Middleware.Server.dll", + "args": [], + "cwd": "${workspaceFolder}/roles/middleware/files/FWO.Middleware.Server", + "console": "internalConsole", + "stopAtEntry": false, + "requireExactSource": false, + "serverReadyAction": { + "action": "openExternally", + "pattern": "\\bNow listening on:\\s+(https?://\\S+)", + "uriFormat": "%s/swagger" + }, + "logging": { + "moduleLoad": false + } + }, + { + "name": "c#-MiddlewareServer - Hot Reload", + "type": "coreclr", + "request": "launch", + "preLaunchTask": "build_middleware", + "enableStepFiltering": false, + "program": "dotnet", + "args": [ + "watch", + "run" + ], + "cwd": "${workspaceFolder}/roles/middleware/files/FWO.Middleware.Server", + "console": "internalConsole", + "stopAtEntry": false, + "requireExactSource": false, + "serverReadyAction": { + "action": "openExternally", + "pattern": "\\bNow listening on:\\s+(https?://\\S+)", + "uriFormat": "%s/swagger" + }, + "env": { + "ASPNETCORE_ENVIRONMENT": "Development" + }, + "logging": { + "moduleLoad": false + } + }, + { + "name": "c#-Blazor UI", + "type": "coreclr", + "request": "launch", + "preLaunchTask": "build_UI", + "program": "${workspaceFolder}/roles/ui/files/FWO.UI/bin/Debug/net10.0/FWO.Ui.dll", + "args": [], + "cwd": "${workspaceFolder}/roles/ui/files/FWO.UI", + "stopAtEntry": false, + "requireExactSource": false, + "serverReadyAction": { + "action": "openExternally", + "pattern": "\\bNow listening on:\\s+(https?://\\S+)" + }, + "env": { + "ASPNETCORE_ENVIRONMENT": "Development" + }, + "sourceFileMap": { + "/Views": "${workspaceFolder}/Views" + }, + "logging": { + "moduleLoad": false + } + }, + { + "name": "c#-Blazor UI - Hot Reload", + "type": "coreclr", + "request": "launch", + "preLaunchTask": "build_UI", + "program": "dotnet", + "args": [ + "watch", + "run" + ], + "cwd": "${workspaceFolder}/roles/ui/files/FWO.UI", + "stopAtEntry": false, + "requireExactSource": false, + "env": { + "ASPNETCORE_ENVIRONMENT": "Development" + }, + "sourceFileMap": { + "/Views": "${workspaceFolder}/Views" + }, + "logging": { + "moduleLoad": false + } + }, + { + "name": "py-normalizeRlmOwners", + "type": "debugpy", + "request": "launch", + "program": "${workspaceFolder}/scripts/customizing/modelling/getOwnersFromTufinRlm.py", + "console": "integratedTerminal", + "env": { + "PYTHONPATH": "${PYTHONPATH}:${workspaceRoot}" + }, + "args": [ + "-c${workspaceFolder}/scripts/customizing/modelling/customizingConfig.json" + ] + }, + { + "name": "py-normalizeNwData", + "type": "debugpy", + "request": "launch", + "program": "${workspaceFolder}/scripts/customizing/modelling/convertNwObjDataFromGitPlain.py", + "console": "integratedTerminal", + "env": { + "PYTHONPATH": "${PYTHONPATH}:${workspaceRoot}" + }, + "args": [ + "-c${workspaceFolder}/scripts/customizing/modelling/customizingConfig.json" + ] + }, + { + "name": "py-import-mgm", + "type": "debugpy", + "request": "launch", + "program": "${workspaceFolder}/roles/importer/files/importer/import_mgm.py", + "console": "integratedTerminal", + "env": { + "PYTHONPATH": "${PYTHONPATH}:${workspaceRoot}" + }, + "args": [ + "-m1", + "-d1", + "-f", + "-s" + ] + }, + { + "name": "py-test-ruleorder", + "type": "debugpy", + "request": "launch", + "program": "${workspaceFolder}/roles/importer/files/test/ruleorder.py", + "console": "integratedTerminal", + "env": { + "PYTHONPATH": "${PYTHONPATH}:${workspaceRoot}" + }, + "args": [] + }, + { + "name": "py-kimport", + "type": "debugpy", + "request": "launch", + "program": "${workspaceFolder}/roles/importer/files/importer/checkpointR8x/scripts/Python-nsPYm-v2/get_all_firewall_data.py", + "console": "integratedTerminal", + "env": { + "PYTHONPATH": "${PYTHONPATH}:${workspaceRoot}" + }, + "args": [ + "itsecorg", + "st8chel" + ] + }, + { + "name": "py-customize-FWO-sample", + "type": "debugpy", + "request": "launch", + "program": "${workspaceFolder}/scripts/customizing/customizing.py", + "console": "integratedTerminal", + "env": { + "PYTHONPATH": "${PYTHONPATH}:${workspaceRoot}" + }, + "args": [ + "-c${workspaceFolder}/scripts/customizing/sampleCustomSettings.json" + ] + }, + { + "name": "py-acquire-lock", + "type": "debugpy", + "request": "launch", + "program": "${workspaceFolder}/roles/common/files/acquire_lock.py", + "console": "integratedTerminal", + "env": { + "PYTHONPATH": "${PYTHONPATH}:${workspaceRoot}" + }, + "args": [ + "/var/fworch/lock/FWO.Middleware.Server_log.lock" + ] + }, + { + "name": "py-generate-tenant-data", + "type": "debugpy", + "request": "launch", + "program": "${workspaceFolder}/roles/tests-unit/files/tenant_networks/create_tenant_network_data.py", + "console": "integratedTerminal", + "env": { + "PYTHONPATH": "${PYTHONPATH}:${workspaceRoot}" + }, + "args": [] + }, + { + "name": "py-change-comment", + "type": "debugpy", + "request": "launch", + "program": "${workspaceFolder}/roles/sample-data/files/config_changes/write_date_to_comment.py", + "console": "integratedTerminal", + "env": { + "PYTHONPATH": "${PYTHONPATH}:${workspaceRoot}" + }, + "args": [] + }, + { + "name": "py-change-rule", + "type": "debugpy", + "request": "launch", + "program": "${workspaceFolder}/roles/sample-data/files/config_changes/enlarge_rule.py", + "console": "integratedTerminal", + "env": { + "PYTHONPATH": "${PYTHONPATH}:${workspaceRoot}" + }, + "args": [] + }, + { + "name": "py-cpr8x-get-config", + "type": "debugpy", + "request": "launch", + "program": "${workspaceFolder}/roles/importer/files/importer/checkpointR8x/get_config.py", + "console": "integratedTerminal", + "env": { + "PYTHONPATH": "${PYTHONPATH}:${workspaceRoot}" + }, + "args": [ + "-asting-mgmt", + "-uitsecorg", + "-w/home/tim/tmp/passwd", + "-lFirstLayer shared with inline layer", + "-kTestPolicyWithLayers", + "-o/home/tim/tmp/sting.cfg" + ] + }, + { + "name": "py-cpr8x-enrich-config", + "type": "debugpy", + "request": "launch", + "program": "${workspaceFolder}/roles/importer/files/importer/checkpointR8x/enrich_config.py", + "console": "integratedTerminal", + "env": { + "PYTHONPATH": "${PYTHONPATH}:${workspaceRoot}" + }, + "args": [ + "-asting-mgmt", + "-uitsecorg", + "-w/home/tim/tmp/passwd", + "-lFirstLayer shared with inline layer", + "-c/home/tim/tmp/sting.cfg" + ] + }, + { + "name": "py-cpr8x-parse-config", + "type": "debugpy", + "request": "launch", + "program": "${workspaceFolder}/roles/importer/files/importer/checkpointR8x/parse_config.py", + "console": "integratedTerminal", + "env": { + "PYTHONPATH": "${PYTHONPATH}:${workspaceRoot}" + }, + "args": [ + "-f/home/tim/tmp/sting.cfg", + "-rFirstLayer shared with inline layer" + ] + }, + { + "name": "py-cpr8x-api-test-call", + "type": "debugpy", + "request": "launch", + "program": "${workspaceFolder}/roles/importer/files/importer/checkpointR8x/api-test-call.py", + "console": "integratedTerminal", + "env": { + "PYTHONPATH": "${PYTHONPATH}:${workspaceRoot}" + }, + "args": [ + "--help" + ] + }, + { + "name": "py-get-config-fm7", + "type": "debugpy", + "request": "launch", + "program": "${workspaceFolder}/roles/importer/files/importer/fortimanager5ff/get_config.py", + "console": "integratedTerminal", + "env": { + "PYTHONPATH": "${PYTHONPATH}:${workspaceRoot}" + }, + "args": [ + "-a10.5.1.55", + "-uapiuser", + "-w/home/tim/tmp/passwd", + "-llayer1", + "-d1", + "-o/tmp/outfile" + ] + }, + { + "name": "py-export-itsecorg", + "type": "debugpy", + "request": "launch", + "program": "${workspaceFolder}/roles/api/files/scripts/fwo-export-itsecorg-devices.py", + "console": "integratedTerminal", + "env": { + "PYTHONPATH": "${PYTHONPATH}:${workspaceRoot}" + }, + "args": [ + "-m/usr/local/fworch/tmp/mgm.csv", + "-d/usr/local/fworch/tmp/dev.csv", + "-o/usr/local/fworch/tmp/devices.graphql", + "-sfworch", + "-f7" + ] + }, + { + "name": "py-export-config", + "type": "debugpy", + "request": "launch", + "program": "${workspaceFolder}/roles/api/files/scripts/fwo-export-config.py", + "console": "integratedTerminal", + "env": { + "PYTHONPATH": "${PYTHONPATH}:${workspaceRoot}" + }, + "args": [ + "-o/tmp/fworch-config" + ] + }, + { + "name": "py-execute-graphql", + "type": "debugpy", + "request": "launch", + "program": "${workspaceFolder}/roles/api/files/scripts/fwo-execute-graphql.py", + "console": "integratedTerminal", + "env": { + "PYTHONPATH": "${PYTHONPATH}:${workspaceRoot}" + }, + "args": [ + "-i/tmp/fworch-config.graphql" + ] + }, + { + "name": "py-execute-graphql-query", + "type": "debugpy", + "request": "launch", + "program": "${workspaceFolder}/roles/api/files/scripts/fwo-execute-graphql-query.py", + "console": "integratedTerminal", + "env": { + "PYTHONPATH": "${PYTHONPATH}:${workspaceRoot}" + }, + "args": [ + "-i/tmp/fworch-config.graphql" + ] + }, + { + "name": "py-import_main_loop", + "type": "debugpy", + "request": "launch", + "program": "${workspaceFolder}/roles/importer/files/importer/import_main_loop.py", + "console": "integratedTerminal", + "env": { + "PYTHONPATH": "${PYTHONPATH}:${workspaceRoot}" + }, + "args": [ + "-d0" + ] + }, + { + "name": "py-create-mock-config", + "type": "debugpy", + "request": "launch", + "program": "${workspaceFolder}/roles/importer/files/importer/test/tools/create_mock_config_file.py", + "console": "integratedTerminal", + "cwd": "${workspaceFolder}/roles/importer/files/importer", + "env": { + "PYTHONPATH": "${workspaceFolder}/roles/importer/files/importer:${env:PYTHONPATH}" + } + }, + { + "name": "c#-FWO Test", + "type": "coreclr", + "request": "launch", + "program": "/usr/bin/dotnet", + "args": [ + "test" + ], + "cwd": "${workspaceFolder}/roles/tests-unit/files/FWO.Test", + "stopAtEntry": false, + "console": "integratedTerminal" + }, + { + "name": "c#-.NET Core Attach ", + "type": "coreclr", + "request": "attach", + "processId": "${command:pickProcess}" + }, + { + "name": "Create mock_config", + "type": "python", + "request": "launch", + "module": "roles.importer.files.test.mocking.mock_config" + }, + { + "name": "pytest current file", + "type": "debugpy", + "request": "launch", + "module": "pytest", + "args": [ + "-s", + "-vv", + "--cov-report", "xml:cov.xml", + "--cov", ".", + "${file}" + ], + "console": "integratedTerminal", + "env": { + "PYTHONPATH": "${PYTHONPATH}:${workspaceRoot}" + }, + "cwd": "${workspaceFolder}" + } + ] +} diff --git a/.vscode/settings.json b/.vscode/settings.json deleted file mode 100644 index f5a8c5a52e..0000000000 --- a/.vscode/settings.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "editor.formatOnPaste": false, - "editor.formatOnSave": false -} \ No newline at end of file diff --git a/.vscode/settings.local.template.json b/.vscode/settings.local.template.json new file mode 100644 index 0000000000..b276514844 --- /dev/null +++ b/.vscode/settings.local.template.json @@ -0,0 +1,5 @@ +{ + "test.unittests.csharp.verbose": true, + "test.unittests.python.verbose": true, + "log.compliancecheck.verbose": true +} diff --git a/.vscode/settings.template.json b/.vscode/settings.template.json new file mode 100644 index 0000000000..596954da91 --- /dev/null +++ b/.vscode/settings.template.json @@ -0,0 +1,36 @@ +{ + "editor.formatOnPaste": false, + "editor.formatOnSave": false, + "[csharp]": { + "editor.formatOnSave": true, + "editor.defaultFormatter": "ms-dotnettools.csharp" + }, + "files.associations": { + "launch.template.json": "jsonc" + }, + "python.testing.unittestArgs": [ + "-v", + "-p", + "test_*.py", + "-s", + "./roles/importer/files/importer/test" + ], + "python.testing.pytestEnabled": true, + "python.testing.unittestEnabled": false, + "[python]": { + "editor.formatOnSave": true, + "editor.codeActionsOnSave": { + "source.fixAll": "explicit", + "source.organizeImports": "explicit" + }, + "editor.defaultFormatter": "charliermarsh.ruff" + }, + "sonarlint.connectedMode.project": { + "connectionId": "cactusesecurity", + "projectKey": "CactuseSecurity_firewall-orchestrator" + }, + "files.watcherExclude": { + "**/.git/objects/**": true, + "**/.git/subtree-cache/**": true + } +} diff --git a/.vscode/tasks.json b/.vscode/tasks.json index 91282a2d18..41a8b3636c 100644 --- a/.vscode/tasks.json +++ b/.vscode/tasks.json @@ -1,6 +1,16 @@ { "version": "2.0.0", "tasks": [ + { + "label": "kill_middleware_port_8880", + "type": "shell", + "command": "bash", + "args": [ + "-lc", + "pid=$(ss -tlpn \"sport = :8880\" | awk -F\"pid=|,\" \"\\$4 ~ /127\\\\.0\\\\.0\\\\.1:8880/ {print \\$2; exit}\"); if [ -n \"$pid\" ]; then kill \"$pid\"; fi" + ], + "problemMatcher": [] + }, { "label": "build", "command": "dotnet", @@ -25,6 +35,15 @@ ], "problemMatcher": "$msCompile" }, + { + "label": "build_middleware_with_kill", + "dependsOn": [ + "kill_middleware_port_8880", + "build_middleware" + ], + "dependsOrder": "sequence", + "problemMatcher": [] + }, { "label": "build_test", "command": "dotnet", @@ -63,4 +82,4 @@ "problemMatcher": "$msCompile" } ] -} \ No newline at end of file +} diff --git a/AGENTS.md b/AGENTS.md new file mode 120000 index 0000000000..41280d2fa8 --- /dev/null +++ b/AGENTS.md @@ -0,0 +1 @@ +.agents/AGENTS.md \ No newline at end of file diff --git a/CODING_GUIDELINES.md b/CODING_GUIDELINES.md index dd77d416f5..ac5aed3476 100644 --- a/CODING_GUIDELINES.md +++ b/CODING_GUIDELINES.md @@ -27,3 +27,117 @@ ## C# specific - avoid null references - methods should be preceded with standard comment header (///) + +## Conventional Commits +The Conventional Commits specification is a lightweight convention on top of commit messages. It provides an easy set of rules for creating an explicit commit history; which makes it easier to write automated tools on top of + +### Why Use Conventional Commits +- Automatically generating CHANGELOGs. +- Automatically determining a semantic version bump (based on the types of commits landed). +- Communicating the nature of changes to teammates, the public, and other stakeholders. +- Triggering build and publish processes. +- Making it easier for people to contribute to your projects, by allowing them to explore a more structured commit history. + +The commit message should be structured as follows: +``` +[optional scope]: +[optional body] +[optional footer(s)] +``` + +The commit contains the following structural elements, to communicate intent to the consumers: + +- fix: a commit of the type fix patches a bug in your codebase (this correlates with PATCH in Semantic Versioning). +- feat: a commit of the type feat introduces a new feature to the codebase (this correlates with MINOR in Semantic Versioning). +- BREAKING CHANGE: a commit that has a footer BREAKING CHANGE:, or appends a ! after the type/scope, introduces a breaking API change (correlating with MAJOR in Semantic Versioning). A BREAKING CHANGE can be part of commits of any type. +- types other than fix: and feat: are allowed, for example @commitlint/config-conventional (based on the Angular convention) recommends build:, chore:, ci:, docs:, style:, refactor:, perf:, test:, and others. +- footers other than BREAKING CHANGE: may be provided and follow a convention similar to git trailer format. + +### Examples +Commit message with description and breaking change footer +``` +feat: allow provided config object to extend other configs + +BREAKING CHANGE: `extends` key in config file is now used for extending other config files +``` + +Commit message with ! to draw attention to breaking change +``` +feat!: send an email to the customer when a product is shipped +``` + +Commit message with scope and ! to draw attention to breaking change +``` +feat(api)!: send an email to the customer when a product is shipped +``` + +Commit message with ! to draw attention to breaking change +``` +chore!: drop support for Node 6 + +BREAKING CHANGE: use JavaScript features not available in Node 6. +``` + +Commit message with no body +``` +docs: correct spelling of CHANGELOG +``` + +Commit message with multi-paragraph body and multiple footers +``` +fix: prevent racing of requests + +Introduce a request id and a reference to latest request. Dismiss +incoming responses other than from latest request. + +Remove timeouts which were used to mitigate the racing issue but are +obsolete now. + +Reviewed-by: Z +Refs: #123 +``` + + +## UI Specific Coding Guidelines + +### General +- Close your tag - Leaving some tags open is simply a bad practice. Only self-closing tags are valid. Normal elements can never have self-closing tags. +- Don't use inline styles(if possible) - When creating your markup, do not use inline styling because it would be very hard to override these styles in case you need to. +- Try not to use "!important" - Using the !important declaration is often considered bad practice because it has side effects that mess with one of CSS's core mechanisms: specificity. In many cases, using it could indicate poor CSS architecture. + +### Components +- Organize files and components in a folder structure like this. This makes it easy to find the code related to a page, without having to browse the entire file explorer. Try, as much as possible, to respect the SOLID principles. Mainly by creating autonomous and extensible components: inject the smallest possible service or parameter, manage all the possibilities offered by the component. For example, a data modification page should display the data, check their values and save the data at the end of the process. + + +### Responsiveness +- Use the bootstrap grid and it's column classes to have easy and responsive design. [Bootstrap](https://getbootstrap.com/docs/5.3/layout/columns/) +- Decide if you want to develop mobile or desktop design first and test respectively. + +### CSS Guidelines for Clean Design + +There are no mandatory CSS attributes for all divs, but some conventions help keep designs clean and consistent: +- Reset/normalize styles: Apply a reset or use box-sizing: border-box; universally (often via * { box-sizing: border-box; }). +- Spacing: Apply margins/paddings only where needed. Don’t force every div to have them. +- Flexbox/Grid: If a div is used as a layout container, give it display: flex; or display: grid;. +- Width & max-width: Constrain large content areas with something like: +```css +.container { + max-width: 1200px; + margin: 0 auto; + padding: 0 1rem; +} +``` +- Consistent typography: Use global font rules in body, not in every div. +- Avoid redundancy: Don’t apply generic attributes (e.g., color, font-size) on all divs—cascade from body or semantic wrappers instead. + +#### Recommended Practices +- Use classes, not bare div styles: class="card", class="section", etc. +- Keep base styles minimal. For example: +```css +div { + display: block; /* default, often unnecessary */ +} +``` +is redundant and shouldn’t be forced on all divs. +- Leverage utility-first CSS (like Tailwind) or your own utility classes to keep styles DRY. +- Semantic HTML first: div should be a fallback, not your default. diff --git a/LICENSE b/LICENSE index 261eeb9e9f..be75dcc9a3 100644 --- a/LICENSE +++ b/LICENSE @@ -199,3 +199,50 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. + +## Third-Party Notices + +This project includes the following third-party components. License names use SPDX identifiers. + +Package/Library | Language | Version | License +-- | -- | -- | -- +bunit | C# | 1.40.0 | MIT +GraphQL.Client | C# | >=6.1.0 | MIT +GraphQL.Client.Serializer.Newtonsoft | C# | >=6.1.0 | MIT +GraphQL.Client.Serializer.SystemTextJson | C# | >=6.1.0 | MIT +HtmlAgilityPack | C# | >=1.12.2 | MIT +IPAddressRange | C# | >=6.2.0 | MPL-2.0 +IPNetwork2 | C# | 3.4.832 | BSD 2-Clause "Simplified" License +MailKit | C# | >=4.13.0 | Apache-2.0 +Microsoft.AspNetCore.Authentication.JwtBearer | C# | >=8.0.15 | Apache-2.0 +Microsoft.AspNetCore.Components | C# | >=8.0.15 | Apache-2.0 +Microsoft.AspNetCore.Components.Authorization | C# | >=8.0.15 | Apache-2.0 +Microsoft.AspNetCore.Http | C# | >=2.3.0 | Apache-2.0 +Microsoft.IdentityModel.Tokens | C# | >=6.7.1 | MIT +Microsoft.IdentityModel.Tokens | C# | >=8.14.0 | MIT +Microsoft.NET.Test.Sdk | C# | >=17.14.1 | MIT +Microsoft.Rest.ClientRuntime | C# | >=2.3.24 | MIT +MimeKit | C# | >=4.13.0 | Apache-2.0 +Novell.Directory.Ldap.NETStandard | C# | >=4.0.0 | MIT +NSubstitute | C# | >=5.3.0 | BSD-2-Clause +NUnit | C# | >=4.4.0 | MIT +NUnit3TestAdapter | C# | >=5.1.0 | MIT +PuppeteerSharp | C# | >=20.2.2 | MIT +RestSharp | C# | >=112.1.0 | Apache-2.0 +RestSharp.Serializers.NewtonsoftJson | C# | >=112.1.0 | Apache-2.0 +Swashbuckle.AspNetCore | C# | >=8.1.1 | MIT +System.IdentityModel.Tokens.Jwt | C# | >=8.14.0 | MIT +System.Text.Encodings.Web | C# | >=9.0.8 | MIT +Phosphor icons | CSS | >=2.1.0 | [MIT](https://raw.githubusercontent.com/phosphor-icons/homepage/master/LICENSE) +cryptography | python | >=40.0 | Apache-2.0 OR BSD-3-Clause +graphql-core | python | >=3.0 | BSD-3-Clause +jsonpickle | python | >=3.0 | BSD-3-Clause +netaddr | python | >=1.0 | BSD-2-Clause +netmiko | python | ? | MIT +paramiko | python | ? | LGPL-2.1-only +pydantic | python | >=2.0 | MIT +PyJWT | python | ? | MIT +pytest | python | >=7.0 | MIT +python-dateutil | python | >=2.8 | BSD-3-Clause +requests | python | >=2.0 | Apache-2.0 +urllib3 | python | >=2.0 | MIT diff --git a/README.md b/README.md index 3b298e7d14..7250badde9 100644 --- a/README.md +++ b/README.md @@ -1,21 +1,23 @@ # ![FWO_logo-40px](https://user-images.githubusercontent.com/19877770/123625365-fc10ca80-d80f-11eb-80bf-0a858149b1d9.png) Firewall Orchestrator ![Build passing](https://github.com/CactuseSecurity/firewall-orchestrator/workflows/Build/badge.svg) +[![Quality Gate Status](https://sonarcloud.io/api/project_badges/measure?project=CactuseSecurity_firewall-orchestrator&metric=alert_status)](https://sonarcloud.io/summary/new_code?id=CactuseSecurity_firewall-orchestrator) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) [![Open Source Love svg1](https://github.com/ellerbrock/open-source-badges/blob/master/badges/open-source-v1/open-source.svg)](https://github.com/ellerbrock/open-source-badges/) [![PRs Welcome](https://img.shields.io/badge/PRs-welcome-brightgreen.svg?style=flat-square)](http://makeapullrequest.com) - Import firewall configurations (rules) of various brands (Check Point, Fortinet, Cisco, Azure, Palo Alto, Juniper, Barracuda, Netscreen) -- Request changes on your firewall configuration using the new workflow module in v6.0 -- Display reports on firewall configuration and changes -- Regularly re-certify firewall rules to clean up your rulebase -- Use the built-in GraphQL API to integrate with your existing infrastructure (Directory Service, ITSM, IPAM, ...) +- Request changes on your firewall configuration using the versatile workflow module +- Generate reports on firewall configuration and changes +- Regularly re-certify firewall rules to clean up your rulebase and so meet regulatory requirements like those stated in [DORA](https://www.eiopa.europa.eu/digital-operational-resilience-act-dora_en) +- Let application owners de-centrally model network communication requirements for all of your organisation's applications +- Automate creation of firewall rules from the modelled connections +- Use the built-in API to integrate with your existing infrastructure (Directory Service, ITSM, IPAM, ...) Reporting Demo: ![fwo-demo-reporting-vsmall](https://github.com/CactuseSecurity/firewall-orchestrator/assets/19877770/f9ffe37f-b059-44cf-b056-30a8f3e008a6) - -Further Demo: if you want to see what it looks like in advance, visit (user: test, password: drive2). +Further Demo: if you want to see what it looks like in advance, visit . ## Installation instructions diff --git a/SECURITY.md b/SECURITY.md index a69ab915e8..e641c6ba33 100644 --- a/SECURITY.md +++ b/SECURITY.md @@ -38,5 +38,8 @@ A public disclosure date is negotiated by the security team and the bug submitte | 1.x | :x: | | 2.x | :x: | | 3.x | :x: | -| 4.x | :white_check_mark: (until 2022-12-31) | -| 5.x | :white_check_mark: | +| 4.x | :x: (until 2022-12-31) | +| 5.x | :x: (until 2023-12-31) | +| 6.x | :x: (until 2024-12-31) | +| 7.x | :white_check_mark: (until 2025-12-31) | +| 8.x | :white_check_mark: | diff --git a/ansible.cfg b/ansible.cfg index 4da73e6e41..1a3c9ecee6 100644 --- a/ansible.cfg +++ b/ansible.cfg @@ -1,12 +1,9 @@ # ansible.cfg [defaults] inventory = inventory -#timeout = 60 +remote_tmp = /tmp/.ansible-${USER}/tmp force_handlers = True -stdout_callback = yaml - -# gathering = smart -# gather_subset = !hardware,!facter,!ohai +result_format = yaml ansible_conditional_bare_vars=false diff --git a/design/UI/settings-management.md b/design/UI/settings-management.md deleted file mode 100644 index f1cc8ded57..0000000000 --- a/design/UI/settings-management.md +++ /dev/null @@ -1,75 +0,0 @@ -```graphql -query getManagement { - management { - mgm_id - mgm_name - dev_typ_id - config_path - importer_hostname - mgm_comment - ssh_hostname - ssh_port - secret - ssh_public_key - ssh_user - hide_in_gui - force_initial_import - do_not_import - } -} -# $importerHostname should be picked from a list of available importers - no table yet -mutation newManagement( - $mgmName: String!, - $devTypId: Int!, - $configPath: String, - $importerHostname: String!, - $mgmComment: String, - $sshHostname: String!, - $sshPort: Int!, - $sshPublicKey: String, - $secret: String!, - $sshUser: String, - $hideInGui: Boolean!, - $forceInitialImport: Boolean!, - $doNotImport: Boolean! -) { - insert_management( - objects: { - mgm_name: $mgmName, - dev_typ_id: $devTypId, - config_path: $configPath, - importer_hostname: $importerHostname, - mgm_comment: $mgmComment, - ssh_hostname: $sshHostname, - ssh_port: $sshPort, - ssh_public_key: $sshPublicKey, - secret: $secret, - ssh_user: $sshUser, - hide_in_gui: $hideInGui, - force_initial_import: $forceInitialImport, - do_not_import: $doNotImport - }) { - affected_rows - } -} - -# Query variables: -{ - "mgmName": "hugo", - "devTypId": 7, - "importerHostname": "install-srv", - "sshHostname": "install-srv", - "sshPort": 22, - "secret": "private-key", - "sshUser": "fworch-import-user", - "hideInGui": false, - "doNotImport": false, - "forceInitialImport": false -} - -mutation setManagement($devTypId: Int!, $mgm_name: String!, $secret: String!) { - insert_management(objects: {config_path: "", dev_typ_id: 10, importer_hostname: "", mgm_name: "$mgm_name", ssh_hostname: "", secret: "", ssh_user: ""}) { - affected_rows - } -} -``` diff --git a/design/UI/settings.md b/design/UI/settings.md deleted file mode 100644 index 8987ad7e83..0000000000 --- a/design/UI/settings.md +++ /dev/null @@ -1,27 +0,0 @@ -# content of settings page in UI -graphical descriptions, see -- all values that do not have a default value and are not nullable will be mandatory (!) - -- settings - - manage user settings (for currently logged in user only) - - select UI lanaguage (additionally offer language selection on top level menu with little flags) - - change password (only for local users!) - - manage devices (managements + devices) - for API queries see - - add management - - modify management (enable/disable import of management, change details, ...) - - add device - - modify device (enable/disable import of device, change details, ...) - - manage users and roles - - manage authentication servers (external ldap) - - assign tenants to (external) users (currently simply done by using tenant level, might have to be enhanced in phase 2) - - manage users - - manage roles - - assign roles to (external) users - - manage tenants - ------ phase 2 ----- - - - manage workflows - - manage config backups - - manage reporting - - manage reporting scheduling (sending results via email) diff --git a/design/UI/ui-filter-grammar.g4 b/design/UI/ui-filter-grammar.g4 deleted file mode 100644 index a8af619185..0000000000 --- a/design/UI/ui-filter-grammar.g4 +++ /dev/null @@ -1,5 +0,0 @@ -// Define a grammar called Hello -grammar Hello; -r : 'hello' ID ; // match keyword hello followed by an identifier -ID : [a-z]+ ; // match lower-case identifiers -WS : [ \t\r\n]+ -> skip ; // skip spaces, tabs, newlines diff --git a/design/UI/webassembly.md b/design/UI/webassembly.md deleted file mode 100644 index bc1998f8da..0000000000 --- a/design/UI/webassembly.md +++ /dev/null @@ -1,16 +0,0 @@ -# Webassembly (WASM) as implemented in Blazor - -- [heise article](https://www.heise.de/news/Microsoft-Build-2020-Blazor-WebAssembly-ist-fertig-4725818.html) -- [limitations of WASM](https://blazor-university.com/javascript-interop/) -- [Comparison Javascript vs Webassembly](https://www.bizety.com/2018/11/14/webassembly-vs-javascript/) - -## Pros - -- speed -- "no javascript" -- standardized -- modern approach - -## Cons - -- high implementation effort diff --git a/design/directory_structure.md b/design/directory_structure.md deleted file mode 100644 index b9fbad6e6e..0000000000 --- a/design/directory_structure.md +++ /dev/null @@ -1,10 +0,0 @@ - -# documentation - -- put docu into top-level documentation folder (structure already defined) - -# tests - -- put tests into roles/ - - /files/test folders to allow installation and initial testing diff --git a/design/readme.md b/design/readme.md deleted file mode 100644 index 85f1287288..0000000000 --- a/design/readme.md +++ /dev/null @@ -1,62 +0,0 @@ -# Design topics - -## competition - -https://www.networkstraining.com/best-firewall-management-software-tools - -## Design goals - -- simple & enjoyable development in an easily expandable team -- Open Source -- High code quality (documentation, tests, code readability, coding best practices ...) -- Strict modularisation (among others using API), avoid logic in client as muchas possible -- secure code, include tenant concept, RBAC -- modern & "non-aging" GUI -- supportability (easy update mechanisms, build updater functionality?) - -## Design, method, architecture decisions - -- language: - - - develoopment in English - - GUI language: parallel English, German, allow for others - -- use agile approach (Rapid Prototyping, trial & error, MuP) - -## Tool decisions - -- using GitHub.com for - - version control - - project management - - test automation - -- PostgreSQL -- API: GraphQL - - - using hasura - -- Client - - - browser-only - -## Functional requirements (high-Level) - -- low-cost alternative to core functionality of competition (Tufin, Algosec, Skybox, Firemon) -- fullfil regulatory requirements (documentation of config changes, recertification of config) -- "network CMDB" -- do not include high risk functionality (e.g. write config changes to firewalls) in core product at first -- offer full API for automation purposes -- include granular role-basd access model - -## Architecture: "encapsulate everything" - -- API - - - API modules () - - no direct DB access without API - -- UI - - - UI display and data methods - -- first impression, see diff --git a/design/requirements_collection.md b/design/requirements_collection.md deleted file mode 100644 index 103d037daa..0000000000 --- a/design/requirements_collection.md +++ /dev/null @@ -1,91 +0,0 @@ -# Requirements - -## functional requirements - -### UI - -#### UI general - -- resizing of areas (e.g. navigation menue) -- multi-language support (start with German + English) -- cross-plattform support runs on windows, macos, linux (or browser when moving logic into webserver) -- authentication, rbac, ... -- allow for tenants (rbac per firewall device or management plus IP-ranges - at least that is the status quo) -- use symbols in menues in addition to text (e.g. oi cog) - -##### multi-purpose filter - -- implement as text box and graphical element in parallel -- text filter is derived and automatically displayed when clicking filters -- user is able to choose filter modules -- UI must prevent filters from being displayed that do not belong to the current data (dependencies) -- low prio: display further info per element (ip, client, manufacturer), might be implemented by mouse-over functionality - -#### reporting - -- create templates that define report -- provide filter line with simple language containing logical operators -- easy to adapt (eg. add new reports) -- nfr (non-functional): modern look -- report visibility should be definable (group, users) -- nice to have: positional bar at upper edge (see nzz.ch) -- part of UI functionality must be "schedulable" (report generation) - -#### admin gui parts - -- add/edit/delete management -- add/edit/delete device -- add/edit/delete client/tenant -- add/edit/delete user -- add/edit/delete external LDAP - -#### workflow creation - -#### worklow deployment - -### rest - -- fulfill regulatory requirements of financial institutions - - - change reports - - config reports - - ticket link (documentation) - - re-certification workflow - - access request workflow - - todo: research regulatory requirements in detail - -- reports - - - config report - - change report - -- re-certification workflow -- change request workflow - - - rule request (add/delete rules) - - object request (add/delete objects) - -- integrated help/manual -- documentation of undocumented config changes - - - add new feature: define pattern of ticket id to parse ticket number from comment fields and add to new meta data field - -- gui - see separate task -- import modules - - - can run on separate servers - - planning to access db via api (phase 2) - - support cp r7x (phase out), r8x (api), fortigate (add api support), junos (keep as is), iptables, palo alto (start with api), baracuda (drop support), netscreen #(drop support), ... - -## non-functional requirements - -- database: - - - keep database size down (e.g. clean-up jobs removing all data older than 5 years) - - this could be an issue with documentation data - - or split database into archive and live - -- gui: - - - modern look & feel - - fast response (immediate, max 5 secs) diff --git a/design/storing-config-data.md b/design/storing-config-data.md deleted file mode 100644 index cadd4a3143..0000000000 --- a/design/storing-config-data.md +++ /dev/null @@ -1,43 +0,0 @@ -# Where to store which configuration data -Differntiation between config data and non-config data: -all data whose knowledge is not potentially dependant on the user's role or tenant. - -Most config data will be stored in the database and only be accessible via API call. - -## All data necessary for making an API call needs to be held in a config file -The following needs to be stored in a configuration file fworch.yaml on each module that needs the config data: -### public, can be stored in user context -- API URI (needed by UI, Middleware, Importer modules) -- Middleware server URI (needd by UI, Middleware, Importer modules) -- JWT generation public key (needed by Middleware, API, Importer to verfiy JWTs) - -### private, not to be shared with user -- JWT generation private key (needed by Middleware for each JWT generation) - -## Config data that can be retrieved via API -### public -this data together with the -- JWT Hash algorithm (needed by API, Middleware, UI) -- texts in multiple languages (UI) -- default language per user (UI) -- device_type (UI, Importer) -- stm_ - - action - - change_type - - color - - dev_typ - - ip_proto - - nattyp (needed?) - - obj_typ - - report_typ - - svc_typ - - track - - usr_typ - -### confidential -- LDAP Connections (needed by Middleware module only; confidential, containing ldap user passwords) - -## Config data only needed during installation phase -Data that is only needed during ansible installation phase will be dealt with either in variables or stored in config files if needed -- LDAP manager for local instance (superuser for local ldap server; Middleware module; confidential) -- hasuar admin secret (needed for testing only; confidential) diff --git a/design/todo.md b/design/todo.md deleted file mode 100644 index eae1faae4e..0000000000 --- a/design/todo.md +++ /dev/null @@ -1,30 +0,0 @@ - -# team work - -- done: all developers: setup github account and send name to tim for granting access -- all developers: create ssh key and send public key to tim for granting access - -# security - -- secure passwords in inventory and in set_vars.sh script - -# api - -- add authentication -- test role based access - -# client - -- create first client prototype using api - -# testing - -- add tests - -# div - -- done: prevent database from being deleted (add force_db_replace variable) - -# installation - -- add wrapper to simplify installation further diff --git a/documentation/SBOM/fwo-sbom.json b/documentation/SBOM/fwo-sbom.json new file mode 100644 index 0000000000..75ab8f8cfa --- /dev/null +++ b/documentation/SBOM/fwo-sbom.json @@ -0,0 +1,4899 @@ +{ + "bomFormat": "CycloneDX", + "specVersion": "1.6", + "serialNumber": "urn:uuid:c0ab5e8e-6381-4090-a17c-b5efdcc7a26e", + "version": 1, + "metadata": { + "timestamp": "2026-03-02T09:07:31Z", + "tools": [ + { + "vendor": "CycloneDX", + "name": "CycloneDX module for .NET", + "version": "5.4.0.0" + } + ], + "component": { + "type": "application", + "bom-ref": "FWO@0.0.0", + "name": "FWO", + "version": "0.0.0" + } + }, + "components": [ + { + "type": "library", + "bom-ref": "pkg:nuget/AngleSharp@1.4.0", + "authors": [ + { + "name": "AngleSharp" + } + ], + "name": "AngleSharp", + "version": "1.4.0", + "description": "AngleSharp is the ultimate angle brackets parser library. It parses HTML5, CSS3, and XML to construct a DOM based on the official W3C specification.", + "scope": "excluded", + "hashes": [ + { + "alg": "SHA-512", + "content": "483864D7675FB7768BEFC44C98FC5A0A995EEABBF7CBD0CF11C62265121E90ADECFC3376E8DA856335314CE62F7879F20D2F44B068A39831F175E6D9FA3C5139" + } + ], + "licenses": [ + { + "license": { + "id": "MIT" + } + } + ], + "copyright": "Copyright 2013-2025, AngleSharp.", + "purl": "pkg:nuget/AngleSharp@1.4.0", + "externalReferences": [ + { + "url": "https://anglesharp.github.io/", + "type": "website" + }, + { + "url": "https://github.com/AngleSharp/AngleSharp", + "type": "vcs" + } + ] + }, + { + "type": "library", + "bom-ref": "pkg:nuget/AngleSharp.Css@1.0.0-beta.157", + "authors": [ + { + "name": "AngleSharp" + } + ], + "name": "AngleSharp.Css", + "version": "1.0.0-beta.157", + "description": "Extends the CSSOM from the core AngleSharp library.", + "scope": "excluded", + "hashes": [ + { + "alg": "SHA-512", + "content": "A861AF56F61DCB4D58ED6F654AABA359BDBD1C648C8F66C55018F694C61F50B05F61795CB1B70C46BB48CB0EEBA982A4C1BBEAD63D371FB9B116E88A7031344E" + } + ], + "licenses": [ + { + "license": { + "id": "MIT" + } + } + ], + "copyright": "Copyright 2016-2025, AngleSharp", + "purl": "pkg:nuget/AngleSharp.Css@1.0.0-beta.157", + "externalReferences": [ + { + "url": "https://anglesharp.github.io/", + "type": "website" + }, + { + "url": "https://github.com/AngleSharp/AngleSharp.Css", + "type": "vcs" + } + ] + }, + { + "type": "library", + "bom-ref": "pkg:nuget/AngleSharp.Diffing@1.1.1", + "authors": [ + { + "name": "AngleSharp" + } + ], + "name": "AngleSharp.Diffing", + "version": "1.1.1", + "description": "Provides a complete diffing model of HTML.", + "scope": "excluded", + "hashes": [ + { + "alg": "SHA-512", + "content": "3C758734ECE12F87213A818A654DBA885C7C1BDC04A9D35B1145A2ACF09CB749B7764CF8AE7AF98E2C4D0F672E3E3A78EADD727A6A05FAB9C02914F8C34A9D2B" + } + ], + "licenses": [ + { + "license": { + "id": "MIT" + } + } + ], + "copyright": "Egil Hansen", + "purl": "pkg:nuget/AngleSharp.Diffing@1.1.1", + "externalReferences": [ + { + "url": "https://anglesharp.github.io/", + "type": "website" + }, + { + "url": "https://github.com/AngleSharp/AngleSharp.Diffing", + "type": "vcs" + } + ] + }, + { + "type": "library", + "bom-ref": "pkg:nuget/BlazorTable@1.17.0", + "authors": [ + { + "name": "Ivan Josipovic" + } + ], + "name": "BlazorTable", + "version": "1.17.0", + "description": "Blazor Table Component with Sorting, Paging and Filtering", + "scope": "required", + "hashes": [ + { + "alg": "SHA-512", + "content": "7DE7B3A3050833C3F500E338DAAB9025079553D7B9F69DA74685EA3EB012AE7ABE8C6AD7506C28CC63862C9166D257E8C7415EFD3E9588B57C91DCA5412F16DB" + } + ], + "licenses": [ + { + "license": { + "id": "MIT" + } + } + ], + "purl": "pkg:nuget/BlazorTable@1.17.0", + "externalReferences": [ + { + "url": "https://blazortable.netlify.app/", + "type": "website" + }, + { + "url": "https://github.com/IvanJosipovic/BlazorTable", + "type": "vcs" + } + ] + }, + { + "type": "library", + "bom-ref": "pkg:nuget/BouncyCastle.Cryptography@2.6.1", + "authors": [ + { + "name": "Legion of the Bouncy Castle Inc." + } + ], + "name": "BouncyCastle.Cryptography", + "version": "2.6.1", + "description": "BouncyCastle.NET is a popular cryptography library for .NET", + "scope": "required", + "hashes": [ + { + "alg": "SHA-512", + "content": "0EB46E4254A042D52720767F86D1C7762CAE6A8C4C19FA391946A728A930859E9C7F89DD1D7C7BA5FE60EFF5B7CB7371647B933FCCC28DBA4398FD4EE83A391C" + } + ], + "licenses": [ + { + "license": { + "id": "MIT" + } + } + ], + "copyright": "Copyright \u00A9 Legion of the Bouncy Castle Inc. 2000-2025", + "purl": "pkg:nuget/BouncyCastle.Cryptography@2.6.1", + "externalReferences": [ + { + "url": "https://www.bouncycastle.org/stable/nuget/csharp/website", + "type": "website" + }, + { + "url": "https://github.com/bcgit/bc-csharp", + "type": "vcs" + } + ] + }, + { + "type": "library", + "bom-ref": "pkg:nuget/bunit@2.5.3", + "authors": [ + { + "name": "Egil Hansen" + } + ], + "name": "bunit", + "version": "2.5.3", + "description": "bUnit is a testing library for Blazor components.\n\n\t\t\tYou can easily define components under test in C# or Razor syntax and verify outcome\n\t\t\tusing semantic HTML diffing/comparison logic.\n\t\t\tYou can interact with and inspect the component under test, trigger event handlers,\n\t\t\tprovide cascading values, and inject services.\n\n\t\t\tbUnit also includes a complete fake implementation of Blazor\u0027s authentication and\n\t\t\tauthorization logic, navigation manager, and\n\t\t\tJSInterop.", + "scope": "excluded", + "hashes": [ + { + "alg": "SHA-512", + "content": "1EBDFFF8670001DDAC3F3C7852B8ABF16E8152AEBABA277E98FC13877CBE66AD0253BAB9A80D3434F4DD268E3CEB81FF3BF3FBBA025443D7DB99B5200790AD93" + } + ], + "licenses": [ + { + "license": { + "id": "MIT" + } + } + ], + "copyright": "Egil Hansen", + "purl": "pkg:nuget/bunit@2.5.3", + "externalReferences": [ + { + "url": "https://bunit.egilhansen.com/", + "type": "website" + }, + { + "url": "https://github.com/bUnit-dev/bUnit", + "type": "vcs" + } + ] + }, + { + "type": "library", + "bom-ref": "pkg:nuget/Castle.Core@5.1.1", + "authors": [ + { + "name": "Castle Project Contributors" + } + ], + "name": "Castle.Core", + "version": "5.1.1", + "description": "Castle Core, including DynamicProxy, Logging Abstractions and DictionaryAdapter", + "scope": "excluded", + "hashes": [ + { + "alg": "SHA-512", + "content": "378A149EBFAA12D00CB35BCAEE8806803DF7BC75980C9E0C67F36E3E057D6AF2ABAEAD24CD8274A9595C7AC74CB9597C9D6913B1125B86E6B156A66F7A1AC2FA" + } + ], + "licenses": [ + { + "license": { + "id": "Apache-2.0" + } + } + ], + "copyright": "Copyright (c) 2004-2022 Castle Project - http://www.castleproject.org/", + "purl": "pkg:nuget/Castle.Core@5.1.1", + "externalReferences": [ + { + "url": "http://www.castleproject.org/", + "type": "website" + }, + { + "url": "https://github.com/castleproject/Core", + "type": "vcs" + } + ] + }, + { + "type": "library", + "bom-ref": "pkg:nuget/DnsClient@1.8.0", + "authors": [ + { + "name": "MichaCo" + } + ], + "name": "DnsClient", + "version": "1.8.0", + "description": "DnsClient.NET is a simple yet very powerful and high performance open source library for the .NET Framework to do DNS lookups", + "scope": "required", + "hashes": [ + { + "alg": "SHA-512", + "content": "45F7793D0E8766BA7909C0DF144FFF043AF2AB8B961DDA1ED33787328BE869A2C760927E22802BC29E0C9DD4A5DA3590068543AD95EEF97E904A787BDA5298AA" + } + ], + "licenses": [ + { + "license": { + "id": "Apache-2.0" + } + } + ], + "copyright": "Copyright (c) 2024 Michael Conrad", + "purl": "pkg:nuget/DnsClient@1.8.0", + "externalReferences": [ + { + "url": "http://dnsclient.michaco.net/", + "type": "website" + }, + { + "url": "https://github.com/MichaCo/DnsClient.NET", + "type": "vcs" + } + ] + }, + { + "type": "library", + "bom-ref": "pkg:nuget/GraphQL.Client@6.1.0", + "authors": [ + { + "name": "Deinok,Alexander Rose,graphql-dotnet" + } + ], + "name": "GraphQL.Client", + "version": "6.1.0", + "description": "A GraphQL Client for .NET Standard", + "scope": "required", + "hashes": [ + { + "alg": "SHA-512", + "content": "26311D1FF197CFA2C69ACABB98EAC28D665ACE7189228B5900C031F97B2241824EB9765EB33244F36F4C4D522BA7D9E37633EFCD9F8A549B891B3B26596F08A3" + } + ], + "licenses": [ + { + "license": { + "id": "MIT" + } + } + ], + "purl": "pkg:nuget/GraphQL.Client@6.1.0", + "externalReferences": [ + { + "url": "https://github.com/graphql-dotnet/graphql-client", + "type": "website" + }, + { + "url": "https://github.com/graphql-dotnet/graphql-client", + "type": "vcs" + } + ] + }, + { + "type": "library", + "bom-ref": "pkg:nuget/GraphQL.Client.Abstractions@6.1.0", + "authors": [ + { + "name": "Deinok,Alexander Rose,graphql-dotnet" + } + ], + "name": "GraphQL.Client.Abstractions", + "version": "6.1.0", + "description": "Abstractions for GraphQL.Client", + "scope": "required", + "hashes": [ + { + "alg": "SHA-512", + "content": "9A7FF3EB230CCD81B2CE7EFC2D5A8DA711D69B4F8A1254E6195F0CF8B0CAADDB34837686FA650E03954C89EF32CB14F8E271E6907A37EFA234E2DE328E79D87A" + } + ], + "licenses": [ + { + "license": { + "id": "MIT" + } + } + ], + "purl": "pkg:nuget/GraphQL.Client.Abstractions@6.1.0", + "externalReferences": [ + { + "url": "https://github.com/graphql-dotnet/graphql-client", + "type": "website" + }, + { + "url": "https://github.com/graphql-dotnet/graphql-client", + "type": "vcs" + } + ] + }, + { + "type": "library", + "bom-ref": "pkg:nuget/GraphQL.Client.Abstractions.Websocket@6.1.0", + "authors": [ + { + "name": "Deinok,Alexander Rose,graphql-dotnet" + } + ], + "name": "GraphQL.Client.Abstractions.Websocket", + "version": "6.1.0", + "description": "Abstractions for the Websocket transport used in GraphQL.Client", + "scope": "required", + "hashes": [ + { + "alg": "SHA-512", + "content": "A69A1EA4C2F2EF1EAEF872EBAC965CB13E8A764B8B7041A965CA1E2E7F3D66E3F8BF5AF1C1EF462A2E618A0E540A53F9B5D8AFA52E1DA72136D4414034693BFA" + } + ], + "licenses": [ + { + "license": { + "id": "MIT" + } + } + ], + "purl": "pkg:nuget/GraphQL.Client.Abstractions.Websocket@6.1.0", + "externalReferences": [ + { + "url": "https://github.com/graphql-dotnet/graphql-client", + "type": "website" + }, + { + "url": "https://github.com/graphql-dotnet/graphql-client", + "type": "vcs" + } + ] + }, + { + "type": "library", + "bom-ref": "pkg:nuget/GraphQL.Client.Serializer.Newtonsoft@6.1.0", + "authors": [ + { + "name": "Deinok,Alexander Rose,graphql-dotnet" + } + ], + "name": "GraphQL.Client.Serializer.Newtonsoft", + "version": "6.1.0", + "description": "A serializer implementation for GraphQL.Client using Newtonsoft.Json as underlying JSON library", + "scope": "required", + "hashes": [ + { + "alg": "SHA-512", + "content": "B55EF566284C0B4C5F27BF4EE8AF071024438FE4D4AE8F0253AAFF87893A94E6A9737F131C7057D7F1C0E07247B0CA05AD3FE14896D2B257DAA3DC3CC2014492" + } + ], + "licenses": [ + { + "license": { + "id": "MIT" + } + } + ], + "purl": "pkg:nuget/GraphQL.Client.Serializer.Newtonsoft@6.1.0", + "externalReferences": [ + { + "url": "https://github.com/graphql-dotnet/graphql-client", + "type": "website" + }, + { + "url": "https://github.com/graphql-dotnet/graphql-client", + "type": "vcs" + } + ] + }, + { + "type": "library", + "bom-ref": "pkg:nuget/GraphQL.Client.Serializer.SystemTextJson@6.1.0", + "authors": [ + { + "name": "Deinok,Alexander Rose,graphql-dotnet" + } + ], + "name": "GraphQL.Client.Serializer.SystemTextJson", + "version": "6.1.0", + "description": "A serializer implementation for GraphQL.Client using System.Text.Json as underlying JSON library", + "scope": "required", + "hashes": [ + { + "alg": "SHA-512", + "content": "BF9E078A200D88E43F727C22327572EB4495F068FD9D3935D6947C964B5AF50769255B8F278A44B720F2840D9CBB6FB0F5718666AD538A5EE7B1BF0D442D263A" + } + ], + "licenses": [ + { + "license": { + "id": "MIT" + } + } + ], + "purl": "pkg:nuget/GraphQL.Client.Serializer.SystemTextJson@6.1.0", + "externalReferences": [ + { + "url": "https://github.com/graphql-dotnet/graphql-client", + "type": "website" + }, + { + "url": "https://github.com/graphql-dotnet/graphql-client", + "type": "vcs" + } + ] + }, + { + "type": "library", + "bom-ref": "pkg:nuget/GraphQL.Primitives@6.1.0", + "authors": [ + { + "name": "Deinok,Alexander Rose,graphql-dotnet" + } + ], + "name": "GraphQL.Primitives", + "version": "6.1.0", + "description": "GraphQL basic types", + "scope": "required", + "hashes": [ + { + "alg": "SHA-512", + "content": "0D8A1965AD88ACB97BE1891EFC50B2770D5EADCB4792C193C616B20C3FE77E516624670387DADC33FBEFFEB4F0BD55516F6D1DE2050C0A81723125D656F325E6" + } + ], + "licenses": [ + { + "license": { + "id": "MIT" + } + } + ], + "purl": "pkg:nuget/GraphQL.Primitives@6.1.0", + "externalReferences": [ + { + "url": "https://github.com/graphql-dotnet/graphql-client", + "type": "website" + }, + { + "url": "https://github.com/graphql-dotnet/graphql-client", + "type": "vcs" + } + ] + }, + { + "type": "library", + "bom-ref": "pkg:nuget/HtmlAgilityPack@1.12.4", + "authors": [ + { + "name": "ZZZ Projects,Simon Mourrier,Jeff Klawiter,Stephan Grell" + } + ], + "name": "HtmlAgilityPack", + "version": "1.12.4", + "description": "This is an agile HTML parser that builds a read/write DOM and supports plain XPATH or XSLT (you actually don\u0027t HAVE to understand XPATH nor XSLT to use it, don\u0027t worry...). It is a .NET code library that allows you to parse \u0022out of the web\u0022 HTML files. The parser is very tolerant with \u0022real world\u0022 malformed HTML. The object model is very similar to what proposes System.Xml, but for HTML documents (or streams).", + "scope": "required", + "hashes": [ + { + "alg": "SHA-512", + "content": "80C5D48460411BC7D862C64CE5059E3BFFFB295C4E11393D9A380293579F0A28FC7B94CF02202112F753510EA94879405163C079A50663ADDEB4F4C968E54F5D" + } + ], + "licenses": [ + { + "license": { + "id": "MIT" + } + } + ], + "copyright": "Copyright \u00A9 ZZZ Projects Inc.", + "purl": "pkg:nuget/HtmlAgilityPack@1.12.4", + "externalReferences": [ + { + "url": "http://html-agility-pack.net/", + "type": "website" + }, + { + "url": "https://github.com/zzzprojects/html-agility-pack/", + "type": "vcs" + } + ] + }, + { + "type": "library", + "bom-ref": "pkg:nuget/IPAddressRange@6.3.0", + "authors": [ + { + "name": "J.Sakamoto" + } + ], + "name": "IPAddressRange", + "version": "6.3.0", + "description": "This library allows you to parse range of IP address string, and can contains check.", + "scope": "required", + "hashes": [ + { + "alg": "SHA-512", + "content": "F2E320E9E10500DC20E20AB022F06ED3C6C73DC5E5B9F52B6FD8A2F7A05D2831D032305F13D14006981D46AC75AC84C70963747DD60B6E121D76A200300290F3" + } + ], + "licenses": [ + { + "license": { + "id": "MPL-2.0" + } + } + ], + "copyright": "Copyright \u00A9 2012-2025 J.Sakamoto, Mozilla Public License 2.0", + "purl": "pkg:nuget/IPAddressRange@6.3.0", + "externalReferences": [ + { + "url": "https://github.com/jsakamoto/ipaddressrange/", + "type": "website" + } + ] + }, + { + "type": "library", + "bom-ref": "pkg:nuget/IPNetwork2@3.4.853", + "authors": [ + { + "name": "Luc Dvchosal" + } + ], + "name": "IPNetwork2", + "version": "3.4.853", + "description": "IPNetwork C# library take care of complex network, ip, ipv4, ipv6, netmask, cidr, subnet, subnetting, supernet and supernetting calculation for .Net developpers. It works with IPv4 and IPv6 as well. It is written in C# for .NetStandard and coreclr and has a light and clean API and is fully unit tested.", + "scope": "required", + "hashes": [ + { + "alg": "SHA-512", + "content": "BFB4D8FC043055A16A6CBA6B72CD4834C261B1C13D594CA503837E02BB1829C07CA65AD74C157C20DB706C9F3944988904A7A171B6356495BA8BB8806204676B" + } + ], + "licenses": [ + { + "license": { + "id": "BSD-2-Clause" + } + } + ], + "copyright": "Copyright 2025", + "purl": "pkg:nuget/IPNetwork2@3.4.853", + "externalReferences": [ + { + "url": "https://github.com/lduchosal/ipnetwork", + "type": "website" + }, + { + "url": "https://github.com/lduchosal/ipnetwork.git", + "type": "vcs" + } + ] + }, + { + "type": "library", + "bom-ref": "pkg:nuget/LinqKit.Core@1.1.26", + "authors": [ + { + "name": "Joseph Albahari,Tomas Petricek,Scott Smith,Tuomas Hietanen,Stef Heyenrath" + } + ], + "name": "LinqKit.Core", + "version": "1.1.26", + "description": "LinqKit.Core contains extensions for LINQ to SQL and Entity Framework. Note that Include(...), IAsync and IDbAsync are not supported.", + "scope": "required", + "hashes": [ + { + "alg": "SHA-512", + "content": "AD6F2FD049D72C4E64C46DEC1C45B36CC2FD63E63FA9924E4A15743A0E00267874A45241B496A95B936F2F495255F7DAC4B0774B15CE1669A45196E45C378889" + } + ], + "licenses": [ + { + "license": { + "id": "MIT" + } + } + ], + "purl": "pkg:nuget/LinqKit.Core@1.1.26", + "externalReferences": [ + { + "url": "https://github.com/scottksmith95/LINQKit", + "type": "website" + }, + { + "url": "https://github.com/scottksmith95/LINQKit", + "type": "vcs" + } + ] + }, + { + "type": "library", + "bom-ref": "pkg:nuget/MailKit@4.14.1", + "authors": [ + { + "name": "Jeffrey Stedfast" + } + ], + "name": "MailKit", + "version": "4.14.1", + "description": "An Open Source .NET mail-client library for Windows, Mac, Linux, and mobile platforms such as iOS and Android.", + "scope": "required", + "hashes": [ + { + "alg": "SHA-512", + "content": "6D471FCCAF708A8F4413FF634FF58432A65307264869AC25173AA1D73844EACA000766FE32A9AD09481CD32E191A88437D8C4D604807E82F521422B2E862960C" + } + ], + "licenses": [ + { + "license": { + "id": "MIT" + } + } + ], + "copyright": ".NET Foundation and Contributors", + "purl": "pkg:nuget/MailKit@4.14.1", + "externalReferences": [ + { + "url": "http://www.mimekit.net/", + "type": "website" + }, + { + "url": "https://github.com/jstedfast/MailKit", + "type": "vcs" + } + ] + }, + { + "type": "library", + "bom-ref": "pkg:nuget/Microsoft.ApplicationInsights@2.23.0", + "authors": [ + { + "name": "Microsoft" + } + ], + "name": "Microsoft.ApplicationInsights", + "version": "2.23.0", + "description": "Application Insights Base API. This package provides core functionality for transmission of all Application Insights Telemetry Types and is a dependent package for all other Application Insights packages. Please install the platform specific package for the best experience. Privacy statement: https://go.microsoft.com/fwlink/?LinkId=512156", + "scope": "excluded", + "hashes": [ + { + "alg": "SHA-512", + "content": "DD497BFAD0C65E54A4F78D2A1644F3D0854D4CD01DD83BA506F8D5D53635E28152C7C13210DD5DD3985780AAB146A7620DE3EBAEAD8EF12C6F87088676C2157F" + } + ], + "licenses": [ + { + "license": { + "id": "MIT" + } + } + ], + "copyright": "\u00A9 Microsoft Corporation. All rights reserved.", + "purl": "pkg:nuget/Microsoft.ApplicationInsights@2.23.0", + "externalReferences": [ + { + "url": "https://go.microsoft.com/fwlink/?LinkId=392727", + "type": "website" + }, + { + "url": "https://github.com/Microsoft/ApplicationInsights-dotnet", + "type": "vcs" + } + ] + }, + { + "type": "library", + "bom-ref": "pkg:nuget/Microsoft.AspNetCore.App.Internal.Assets@10.0.3", + "authors": [ + { + "name": "Microsoft" + } + ], + "name": "Microsoft.AspNetCore.App.Internal.Assets", + "version": "10.0.3", + "description": "ASP.NET Core static framework assets\n\nThis package was built from the source code at https://github.com/dotnet/dotnet/tree/c2435c3e0f46de784341ac3ed62863ce77e117b4", + "scope": "required", + "hashes": [ + { + "alg": "SHA-512", + "content": "7A051C6D0C7B9E6A65B268ED03B540BD74BAAFA772A1ADD6F37F9D26F7F465377A3768B44D29EE8DB766B6E6DF49CCD1F71FEF3E543D8262E892E164792B9E85" + } + ], + "licenses": [ + { + "license": { + "id": "MIT" + } + } + ], + "copyright": "\u00A9 Microsoft Corporation. All rights reserved.", + "purl": "pkg:nuget/Microsoft.AspNetCore.App.Internal.Assets@10.0.3", + "externalReferences": [ + { + "url": "https://asp.net/", + "type": "website" + }, + { + "url": "https://github.com/dotnet/dotnet", + "type": "vcs" + } + ] + }, + { + "type": "library", + "bom-ref": "pkg:nuget/Microsoft.AspNetCore.Authentication.JwtBearer@10.0.2", + "authors": [ + { + "name": "Microsoft" + } + ], + "name": "Microsoft.AspNetCore.Authentication.JwtBearer", + "version": "10.0.2", + "description": "ASP.NET Core middleware that enables an application to receive an OpenID Connect bearer token.\n\nThis package was built from the source code at https://github.com/dotnet/dotnet/tree/44525024595742ebe09023abe709df51de65009b", + "scope": "required", + "hashes": [ + { + "alg": "SHA-512", + "content": "9736628DAFC4BFAF16FA94AA638A2109EFA068EA0377A8CFF0CFA01885952C6020A67AC1B22FC1BF5FD94EEDBCBEA8C731BFCD9F0E27952788459CB8A94E2EE5" + } + ], + "licenses": [ + { + "license": { + "id": "MIT" + } + } + ], + "copyright": "\u00A9 Microsoft Corporation. All rights reserved.", + "purl": "pkg:nuget/Microsoft.AspNetCore.Authentication.JwtBearer@10.0.2", + "externalReferences": [ + { + "url": "https://asp.net/", + "type": "website" + }, + { + "url": "https://github.com/dotnet/dotnet", + "type": "vcs" + } + ] + }, + { + "type": "library", + "bom-ref": "pkg:nuget/Microsoft.AspNetCore.Authorization@10.0.2", + "authors": [ + { + "name": "Microsoft" + } + ], + "name": "Microsoft.AspNetCore.Authorization", + "version": "10.0.2", + "description": "ASP.NET Core authorization classes.\nCommonly used types:\nMicrosoft.AspNetCore.Authorization.AllowAnonymousAttribute\nMicrosoft.AspNetCore.Authorization.AuthorizeAttribute\n\nThis package was built from the source code at https://github.com/dotnet/dotnet/tree/44525024595742ebe09023abe709df51de65009b", + "scope": "required", + "hashes": [ + { + "alg": "SHA-512", + "content": "493BDA5D1DF79441DE1602A9DCC4B746BC3C99FE97BF5167DA24F117617C6E477BD925757CECA2870380E1FD06D796CA9886D0772B2BA3D4EBB20E73D021AC2C" + } + ], + "licenses": [ + { + "license": { + "id": "MIT" + } + } + ], + "copyright": "\u00A9 Microsoft Corporation. All rights reserved.", + "purl": "pkg:nuget/Microsoft.AspNetCore.Authorization@10.0.2", + "externalReferences": [ + { + "url": "https://asp.net/", + "type": "website" + }, + { + "url": "https://github.com/dotnet/dotnet", + "type": "vcs" + } + ] + }, + { + "type": "library", + "bom-ref": "pkg:nuget/Microsoft.AspNetCore.Components@10.0.2", + "authors": [ + { + "name": "Microsoft" + } + ], + "name": "Microsoft.AspNetCore.Components", + "version": "10.0.2", + "description": "Components feature for ASP.NET Core.\n\nThis package was built from the source code at https://github.com/dotnet/dotnet/tree/44525024595742ebe09023abe709df51de65009b", + "scope": "required", + "hashes": [ + { + "alg": "SHA-512", + "content": "ADD6776972F6437FAA39BEAAC2521430F9E7F66042DF2C28F898EE562274FB43B752150577956DF66E7369B66AF1486FD4B2C0D2C202935A915DB186ACEAF44E" + } + ], + "licenses": [ + { + "license": { + "id": "MIT" + } + } + ], + "copyright": "\u00A9 Microsoft Corporation. All rights reserved.", + "purl": "pkg:nuget/Microsoft.AspNetCore.Components@10.0.2", + "externalReferences": [ + { + "url": "https://asp.net/", + "type": "website" + }, + { + "url": "https://github.com/dotnet/dotnet", + "type": "vcs" + } + ] + }, + { + "type": "library", + "bom-ref": "pkg:nuget/Microsoft.AspNetCore.Components.Analyzers@10.0.2", + "authors": [ + { + "name": "Microsoft" + } + ], + "name": "Microsoft.AspNetCore.Components.Analyzers", + "version": "10.0.2", + "description": "Roslyn analyzers for ASP.NET Core Components.\n\nThis package was built from the source code at https://github.com/dotnet/dotnet/tree/44525024595742ebe09023abe709df51de65009b", + "scope": "required", + "hashes": [ + { + "alg": "SHA-512", + "content": "6D30AF1423DF94AEEBF62B7048CD3F49D015A9D63BB5F3C631DFCA8D566B2B1CF7CB1E26F46D4B8F687A70660A1DDDFF7CF592DBC7F01477FAB48616F9FFBD65" + } + ], + "licenses": [ + { + "license": { + "id": "MIT" + } + } + ], + "copyright": "\u00A9 Microsoft Corporation. All rights reserved.", + "purl": "pkg:nuget/Microsoft.AspNetCore.Components.Analyzers@10.0.2", + "externalReferences": [ + { + "url": "https://asp.net/", + "type": "website" + }, + { + "url": "https://github.com/dotnet/dotnet", + "type": "vcs" + } + ] + }, + { + "type": "library", + "bom-ref": "pkg:nuget/Microsoft.AspNetCore.Components.Authorization@10.0.0", + "authors": [ + { + "name": "Microsoft" + } + ], + "name": "Microsoft.AspNetCore.Components.Authorization", + "version": "10.0.0", + "description": "Authentication and authorization support for Blazor applications.\n\nThis package was built from the source code at https://github.com/dotnet/dotnet/tree/b0f34d51fccc69fd334253924abd8d6853fad7aa", + "scope": "excluded", + "hashes": [ + { + "alg": "SHA-512", + "content": "62B2BD3B5B07C4509375E3F9AF986147369E359AB3E2C3FA0F54ACAE0B85993EBF8C8B1739883E9F1C3CED94DBF68E4533492735CB18106D4EBB4E33DB0625AA" + } + ], + "licenses": [ + { + "license": { + "id": "MIT" + } + } + ], + "copyright": "\u00A9 Microsoft Corporation. All rights reserved.", + "purl": "pkg:nuget/Microsoft.AspNetCore.Components.Authorization@10.0.0", + "externalReferences": [ + { + "url": "https://asp.net/", + "type": "website" + }, + { + "url": "https://github.com/dotnet/dotnet", + "type": "vcs" + } + ] + }, + { + "type": "library", + "bom-ref": "pkg:nuget/Microsoft.AspNetCore.Components.Forms@10.0.0", + "authors": [ + { + "name": "Microsoft" + } + ], + "name": "Microsoft.AspNetCore.Components.Forms", + "version": "10.0.0", + "description": "Forms and validation support for Blazor applications.\n\nThis package was built from the source code at https://github.com/dotnet/dotnet/tree/b0f34d51fccc69fd334253924abd8d6853fad7aa", + "scope": "excluded", + "hashes": [ + { + "alg": "SHA-512", + "content": "CD27F3ABC275F6F972679471AF1422EEB5BEDDF8F613DAEF20EAA7B43F293F06E66D42DFC4F71950B84DAA1927A41B830A50D03045358E59642AF00FED4B85C0" + } + ], + "licenses": [ + { + "license": { + "id": "MIT" + } + } + ], + "copyright": "\u00A9 Microsoft Corporation. All rights reserved.", + "purl": "pkg:nuget/Microsoft.AspNetCore.Components.Forms@10.0.0", + "externalReferences": [ + { + "url": "https://asp.net/", + "type": "website" + }, + { + "url": "https://github.com/dotnet/dotnet", + "type": "vcs" + } + ] + }, + { + "type": "library", + "bom-ref": "pkg:nuget/Microsoft.AspNetCore.Components.Web@10.0.0", + "authors": [ + { + "name": "Microsoft" + } + ], + "name": "Microsoft.AspNetCore.Components.Web", + "version": "10.0.0", + "description": "Support for rendering ASP.NET Core components for browsers.\n\nThis package was built from the source code at https://github.com/dotnet/dotnet/tree/b0f34d51fccc69fd334253924abd8d6853fad7aa", + "scope": "excluded", + "hashes": [ + { + "alg": "SHA-512", + "content": "733ADD2131C9A84482929C63B59158186FBAB739E5170B1C57ED69733E0E37BB13C243C1E55AA2C0E27BAF8B15BAF8C105119B2D5D7C7520CA56B1CB4D14521D" + } + ], + "licenses": [ + { + "license": { + "id": "MIT" + } + } + ], + "copyright": "\u00A9 Microsoft Corporation. All rights reserved.", + "purl": "pkg:nuget/Microsoft.AspNetCore.Components.Web@10.0.0", + "externalReferences": [ + { + "url": "https://asp.net/", + "type": "website" + }, + { + "url": "https://github.com/dotnet/dotnet", + "type": "vcs" + } + ] + }, + { + "type": "library", + "bom-ref": "pkg:nuget/Microsoft.AspNetCore.Components.WebAssembly@10.0.0", + "authors": [ + { + "name": "Microsoft" + } + ], + "name": "Microsoft.AspNetCore.Components.WebAssembly", + "version": "10.0.0", + "description": "Build client-side single-page applications (SPAs) with Blazor running under WebAssembly.\n\nThis package was built from the source code at https://github.com/dotnet/dotnet/tree/b0f34d51fccc69fd334253924abd8d6853fad7aa", + "scope": "excluded", + "hashes": [ + { + "alg": "SHA-512", + "content": "1E3B6EAB7DBB36B473755E2AA3BC784C3C294158791719AA3F6E0C70D11EEE50B59AF2EDBD3F95E3D08FE038B628A4D049AB8693FEBDCD95D914B49B58B9BAE9" + } + ], + "licenses": [ + { + "license": { + "id": "MIT" + } + } + ], + "copyright": "\u00A9 Microsoft Corporation. All rights reserved.", + "purl": "pkg:nuget/Microsoft.AspNetCore.Components.WebAssembly@10.0.0", + "externalReferences": [ + { + "url": "https://asp.net/", + "type": "website" + }, + { + "url": "https://github.com/dotnet/dotnet", + "type": "vcs" + } + ] + }, + { + "type": "library", + "bom-ref": "pkg:nuget/Microsoft.AspNetCore.Components.WebAssembly.Authentication@10.0.0", + "authors": [ + { + "name": "Microsoft" + } + ], + "name": "Microsoft.AspNetCore.Components.WebAssembly.Authentication", + "version": "10.0.0", + "description": "Build client-side authentication for single-page applications (SPAs).\n\nThis package was built from the source code at https://github.com/dotnet/dotnet/tree/b0f34d51fccc69fd334253924abd8d6853fad7aa", + "scope": "excluded", + "hashes": [ + { + "alg": "SHA-512", + "content": "5357D2317ED2992C3098F12C13B3FF751FD95DA01EFA1AA68652A0BC90F5005C74076BBEA363827CE2D61F424865F615C8C293DA3C200904E8131CD263505122" + } + ], + "licenses": [ + { + "license": { + "id": "MIT" + } + } + ], + "copyright": "\u00A9 Microsoft Corporation. All rights reserved.", + "purl": "pkg:nuget/Microsoft.AspNetCore.Components.WebAssembly.Authentication@10.0.0", + "externalReferences": [ + { + "url": "https://asp.net/", + "type": "website" + }, + { + "url": "https://github.com/dotnet/dotnet", + "type": "vcs" + } + ] + }, + { + "type": "library", + "bom-ref": "pkg:nuget/Microsoft.AspNetCore.Http@2.3.9", + "authors": [ + { + "name": "Microsoft" + } + ], + "name": "Microsoft.AspNetCore.Http", + "version": "2.3.9", + "description": "ASP.NET Core default HTTP feature implementations.", + "scope": "required", + "hashes": [ + { + "alg": "SHA-512", + "content": "ACD2AE902210BB227113846990B0868C8C480D173270994EAFD0DBF5371306AA5F3CB6EF81C1219F07095E597EC81C978CAB1762A8C5946E6873FBCE87110CD9" + } + ], + "licenses": [ + { + "license": { + "name": "Unknown - See URL", + "url": "https://raw.githubusercontent.com/aspnet/AspNetCore/2.0.0/LICENSE.txt" + } + } + ], + "copyright": "\u00A9 Microsoft Corporation. All rights reserved.", + "purl": "pkg:nuget/Microsoft.AspNetCore.Http@2.3.9", + "externalReferences": [ + { + "url": "https://asp.net/", + "type": "website" + }, + { + "url": "https://github.com/dotnet/aspnetcore", + "type": "vcs" + } + ] + }, + { + "type": "library", + "bom-ref": "pkg:nuget/Microsoft.AspNetCore.Http.Abstractions@2.3.0", + "authors": [ + { + "name": "Microsoft" + } + ], + "name": "Microsoft.AspNetCore.Http.Abstractions", + "version": "2.3.0", + "description": "ASP.NET Core HTTP object model for HTTP requests and responses and also common extension methods for registering middleware in an IApplicationBuilder.\nCommonly used types:\nMicrosoft.AspNetCore.Builder.IApplicationBuilder\nMicrosoft.AspNetCore.Http.HttpContext\nMicrosoft.AspNetCore.Http.HttpRequest\nMicrosoft.AspNetCore.Http.HttpResponse", + "scope": "required", + "hashes": [ + { + "alg": "SHA-512", + "content": "3BE806268DDFFD3F30F4A2FB90E69A876EBECAE1C7B6BDB9EADCF655A17D953DA2219E71E22AAC6823E68FAD34A21AB5D67BA69DED691EBC2CF370F454BD7ACC" + } + ], + "licenses": [ + { + "license": { + "name": "Unknown - See URL", + "url": "https://raw.githubusercontent.com/aspnet/AspNetCore/2.0.0/LICENSE.txt" + } + } + ], + "copyright": "\u00A9 Microsoft Corporation. All rights reserved.", + "purl": "pkg:nuget/Microsoft.AspNetCore.Http.Abstractions@2.3.0", + "externalReferences": [ + { + "url": "https://asp.net/", + "type": "website" + }, + { + "url": "https://github.com/dotnet/aspnetcore", + "type": "vcs" + } + ] + }, + { + "type": "library", + "bom-ref": "pkg:nuget/Microsoft.AspNetCore.Http.Features@2.3.0", + "authors": [ + { + "name": "Microsoft" + } + ], + "name": "Microsoft.AspNetCore.Http.Features", + "version": "2.3.0", + "description": "ASP.NET Core HTTP feature interface definitions.", + "scope": "required", + "hashes": [ + { + "alg": "SHA-512", + "content": "B528E315A3F62DE75D67A023FE4E69CB2323AB345E475D9A2F1DF0C0701A4184A325AAE8D30193042881C514F9CD6F5ACC372F5DEECF0DFFB33F4D700AC69EDF" + } + ], + "licenses": [ + { + "license": { + "name": "Unknown - See URL", + "url": "https://raw.githubusercontent.com/aspnet/AspNetCore/2.0.0/LICENSE.txt" + } + } + ], + "copyright": "\u00A9 Microsoft Corporation. All rights reserved.", + "purl": "pkg:nuget/Microsoft.AspNetCore.Http.Features@2.3.0", + "externalReferences": [ + { + "url": "https://asp.net/", + "type": "website" + }, + { + "url": "https://github.com/dotnet/aspnetcore", + "type": "vcs" + } + ] + }, + { + "type": "library", + "bom-ref": "pkg:nuget/Microsoft.AspNetCore.Metadata@10.0.2", + "authors": [ + { + "name": "Microsoft" + } + ], + "name": "Microsoft.AspNetCore.Metadata", + "version": "10.0.2", + "description": "ASP.NET Core metadata.\n\nThis package was built from the source code at https://github.com/dotnet/dotnet/tree/44525024595742ebe09023abe709df51de65009b", + "scope": "required", + "hashes": [ + { + "alg": "SHA-512", + "content": "ACDEB6AD48E09CA65E692AEB03968DBBF2BD1B746547A2463180D4BD9FF14E5A38630B673F1FE28111E630E34D049B96834D5D0B3C322AB4DABC1056D9AF549A" + } + ], + "licenses": [ + { + "license": { + "id": "MIT" + } + } + ], + "copyright": "\u00A9 Microsoft Corporation. All rights reserved.", + "purl": "pkg:nuget/Microsoft.AspNetCore.Metadata@10.0.2", + "externalReferences": [ + { + "url": "https://asp.net/", + "type": "website" + }, + { + "url": "https://github.com/dotnet/dotnet", + "type": "vcs" + } + ] + }, + { + "type": "library", + "bom-ref": "pkg:nuget/Microsoft.AspNetCore.WebUtilities@2.3.0", + "authors": [ + { + "name": "Microsoft" + } + ], + "name": "Microsoft.AspNetCore.WebUtilities", + "version": "2.3.0", + "description": "ASP.NET Core utilities, such as for working with forms, multipart messages, and query strings.", + "scope": "required", + "hashes": [ + { + "alg": "SHA-512", + "content": "EC68D50355CC8D4D674836E619925370F6DD5433FF01FD6D5D6935332E22D71D2E2CA5B2BA80CAA271AF06D5EBEB4B28F14ABDD912B99250913450591EB52334" + } + ], + "licenses": [ + { + "license": { + "name": "Unknown - See URL", + "url": "https://raw.githubusercontent.com/aspnet/AspNetCore/2.0.0/LICENSE.txt" + } + } + ], + "copyright": "\u00A9 Microsoft Corporation. All rights reserved.", + "purl": "pkg:nuget/Microsoft.AspNetCore.WebUtilities@2.3.0", + "externalReferences": [ + { + "url": "https://asp.net/", + "type": "website" + }, + { + "url": "https://github.com/dotnet/aspnetcore", + "type": "vcs" + } + ] + }, + { + "type": "library", + "bom-ref": "pkg:nuget/Microsoft.CodeCoverage@18.0.1", + "authors": [ + { + "name": "Microsoft" + } + ], + "name": "Microsoft.CodeCoverage", + "version": "18.0.1", + "description": "Microsoft.CodeCoverage package brings infra for collecting code coverage from vstest.console.exe and \u0022dotnet test\u0022.", + "scope": "excluded", + "hashes": [ + { + "alg": "SHA-512", + "content": "D1BCEBCFEBD1E3D13F8ED741C925DA2523CFE299709CC1C4DAAB3225981926E0DD20EB4B505B3022755AEE4AF1215CF6BABE8A25915D4CF5EBDD63177E09C336" + } + ], + "licenses": [ + { + "license": { + "id": "MIT" + } + } + ], + "copyright": "\u00A9 Microsoft Corporation. All rights reserved.", + "purl": "pkg:nuget/Microsoft.CodeCoverage@18.0.1", + "externalReferences": [ + { + "url": "https://github.com/microsoft/vstest", + "type": "website" + }, + { + "url": "https://github.com/microsoft/vstest", + "type": "vcs" + } + ] + }, + { + "type": "library", + "bom-ref": "pkg:nuget/Microsoft.Extensions.ApiDescription.Server@10.0.0", + "authors": [ + { + "name": "Microsoft" + } + ], + "name": "Microsoft.Extensions.ApiDescription.Server", + "version": "10.0.0", + "description": "MSBuild tasks and targets for build-time Swagger and OpenApi document generation\n\nThis package was built from the source code at https://github.com/dotnet/dotnet/tree/b0f34d51fccc69fd334253924abd8d6853fad7aa", + "scope": "required", + "hashes": [ + { + "alg": "SHA-512", + "content": "25E9DDC666061CCBB34870E47B511EEAB7693CF1C8965E5A6F479650A4539138176DD67591575F15700534A7F67D2E13F2F0E9DC295BEF6B0D2875739D1C5AE7" + } + ], + "licenses": [ + { + "license": { + "id": "MIT" + } + } + ], + "copyright": "\u00A9 Microsoft Corporation. All rights reserved.", + "purl": "pkg:nuget/Microsoft.Extensions.ApiDescription.Server@10.0.0", + "externalReferences": [ + { + "url": "https://asp.net/", + "type": "website" + }, + { + "url": "https://github.com/dotnet/dotnet", + "type": "vcs" + } + ] + }, + { + "type": "library", + "bom-ref": "pkg:nuget/Microsoft.Extensions.Caching.Abstractions@10.0.0", + "authors": [ + { + "name": "Microsoft" + } + ], + "name": "Microsoft.Extensions.Caching.Abstractions", + "version": "10.0.0", + "description": "Caching abstractions for in-memory cache and distributed cache.\n\nCommonly Used Types:\nMicrosoft.Extensions.Caching.Distributed.IDistributedCache\nMicrosoft.Extensions.Caching.Memory.IMemoryCache", + "scope": "excluded", + "hashes": [ + { + "alg": "SHA-512", + "content": "3F74F6CB1EAEDD0A4F9615447DB5BFC626487B11E8DB92060D8E6A813D9D4CC2722D0D329D6639048EA34E4C152845BFB5241D572BD300489BD95BB8AF6F4F84" + } + ], + "licenses": [ + { + "license": { + "id": "MIT" + } + } + ], + "copyright": "\u00A9 Microsoft Corporation. All rights reserved.", + "purl": "pkg:nuget/Microsoft.Extensions.Caching.Abstractions@10.0.0", + "externalReferences": [ + { + "url": "https://dot.net/", + "type": "website" + }, + { + "url": "https://github.com/dotnet/dotnet", + "type": "vcs" + } + ] + }, + { + "type": "library", + "bom-ref": "pkg:nuget/Microsoft.Extensions.Caching.Memory@10.0.0", + "authors": [ + { + "name": "Microsoft" + } + ], + "name": "Microsoft.Extensions.Caching.Memory", + "version": "10.0.0", + "description": "In-memory cache implementation of Microsoft.Extensions.Caching.Memory.IMemoryCache.", + "scope": "excluded", + "hashes": [ + { + "alg": "SHA-512", + "content": "9B0F09CB24C6BF17EBAE2F27F9D1AAE3C08FCE7DEBB698CDA50EB375A24B78069F667F3F0E06EF4C1DF8B67EFDF142CF3733E7D269446BE509BF9C9A79D19E5B" + } + ], + "licenses": [ + { + "license": { + "id": "MIT" + } + } + ], + "copyright": "\u00A9 Microsoft Corporation. All rights reserved.", + "purl": "pkg:nuget/Microsoft.Extensions.Caching.Memory@10.0.0", + "externalReferences": [ + { + "url": "https://dot.net/", + "type": "website" + }, + { + "url": "https://github.com/dotnet/dotnet", + "type": "vcs" + } + ] + }, + { + "type": "library", + "bom-ref": "pkg:nuget/Microsoft.Extensions.Configuration@10.0.2", + "authors": [ + { + "name": "Microsoft" + } + ], + "name": "Microsoft.Extensions.Configuration", + "version": "10.0.2", + "description": "Implementation of key-value pair based configuration for Microsoft.Extensions.Configuration. Includes the memory configuration provider.", + "scope": "required", + "hashes": [ + { + "alg": "SHA-512", + "content": "48F66F857A9E6E2A63DF4B4CC07A377575C755BF7900C3EB743103DBF6E7EC1DC9046EEE6A7A2C5B0A010E224DE66252E2395704A766A5F16CF57DBF11492B98" + } + ], + "licenses": [ + { + "license": { + "id": "MIT" + } + } + ], + "copyright": "\u00A9 Microsoft Corporation. All rights reserved.", + "purl": "pkg:nuget/Microsoft.Extensions.Configuration@10.0.2", + "externalReferences": [ + { + "url": "https://dot.net/", + "type": "website" + }, + { + "url": "https://github.com/dotnet/dotnet", + "type": "vcs" + } + ] + }, + { + "type": "library", + "bom-ref": "pkg:nuget/Microsoft.Extensions.Configuration.Abstractions@10.0.2", + "authors": [ + { + "name": "Microsoft" + } + ], + "name": "Microsoft.Extensions.Configuration.Abstractions", + "version": "10.0.2", + "description": "Provides abstractions of key-value pair based configuration. Interfaces defined in this package are implemented by classes in Microsoft.Extensions.Configuration and other configuration packages.", + "scope": "required", + "hashes": [ + { + "alg": "SHA-512", + "content": "5F2BDDAEFBD16434C97DD8B84EA8B8867BB891F3209645780489C9B21CE84991C272356422094BD2636A225E779142AC7E3A9C1457282EA9AD0FBC6ED9B34CC8" + } + ], + "licenses": [ + { + "license": { + "id": "MIT" + } + } + ], + "copyright": "\u00A9 Microsoft Corporation. All rights reserved.", + "purl": "pkg:nuget/Microsoft.Extensions.Configuration.Abstractions@10.0.2", + "externalReferences": [ + { + "url": "https://dot.net/", + "type": "website" + }, + { + "url": "https://github.com/dotnet/dotnet", + "type": "vcs" + } + ] + }, + { + "type": "library", + "bom-ref": "pkg:nuget/Microsoft.Extensions.Configuration.Binder@10.0.2", + "authors": [ + { + "name": "Microsoft" + } + ], + "name": "Microsoft.Extensions.Configuration.Binder", + "version": "10.0.2", + "description": "Provides the functionality to bind an object to data in configuration providers for Microsoft.Extensions.Configuration. This package enables you to represent the configuration data as strongly-typed classes defined in the application code. To bind a configuration, use the Microsoft.Extensions.Configuration.ConfigurationBinder.Get extension method on the IConfiguration object. To use this package, you also need to install a package for the configuration provider, for example, Microsoft.Extensions.Configuration.Json for the JSON provider.", + "scope": "required", + "hashes": [ + { + "alg": "SHA-512", + "content": "2BFC24FC3585D145694D4F4B4B43C74AA4AA2BE64FE805055B3755A452852F2A2643375807663747E707722835814705C894822D3B21370F8F4F46DF12AA56AB" + } + ], + "licenses": [ + { + "license": { + "id": "MIT" + } + } + ], + "copyright": "\u00A9 Microsoft Corporation. All rights reserved.", + "purl": "pkg:nuget/Microsoft.Extensions.Configuration.Binder@10.0.2", + "externalReferences": [ + { + "url": "https://dot.net/", + "type": "website" + }, + { + "url": "https://github.com/dotnet/dotnet", + "type": "vcs" + } + ] + }, + { + "type": "library", + "bom-ref": "pkg:nuget/Microsoft.Extensions.Configuration.FileExtensions@10.0.0", + "authors": [ + { + "name": "Microsoft" + } + ], + "name": "Microsoft.Extensions.Configuration.FileExtensions", + "version": "10.0.0", + "description": "Provides a base class for file-based configuration providers used with Microsoft.Extensions.Configuration and extension methods for configuring them.", + "scope": "excluded", + "hashes": [ + { + "alg": "SHA-512", + "content": "82EA39465BAB27E29F4261CF34543B8B974E629F73FA2CB0ED9E0391D4F6A5108180235BC13A454A1CA3AA97DE3CAF5B4B715DE867CD4D104ED7CE06D1915B9C" + } + ], + "licenses": [ + { + "license": { + "id": "MIT" + } + } + ], + "copyright": "\u00A9 Microsoft Corporation. All rights reserved.", + "purl": "pkg:nuget/Microsoft.Extensions.Configuration.FileExtensions@10.0.0", + "externalReferences": [ + { + "url": "https://dot.net/", + "type": "website" + }, + { + "url": "https://github.com/dotnet/dotnet", + "type": "vcs" + } + ] + }, + { + "type": "library", + "bom-ref": "pkg:nuget/Microsoft.Extensions.Configuration.Json@10.0.0", + "authors": [ + { + "name": "Microsoft" + } + ], + "name": "Microsoft.Extensions.Configuration.Json", + "version": "10.0.0", + "description": "JSON configuration provider implementation for Microsoft.Extensions.Configuration. This package enables you to read your application\u0027s settings from a JSON file. You can use JsonConfigurationExtensions.AddJsonFile extension method on IConfigurationBuilder to add the JSON configuration provider to the configuration builder.", + "scope": "excluded", + "hashes": [ + { + "alg": "SHA-512", + "content": "FC29FA355F942259FB1550EEB2967DED70899D0DA31E5EF7EDCD8A7735F9E38716C4C2B1FA15BF36EE807161F28F332D0B1E3DCCE719FE38EF8EC89F536BB804" + } + ], + "licenses": [ + { + "license": { + "id": "MIT" + } + } + ], + "copyright": "\u00A9 Microsoft Corporation. All rights reserved.", + "purl": "pkg:nuget/Microsoft.Extensions.Configuration.Json@10.0.0", + "externalReferences": [ + { + "url": "https://dot.net/", + "type": "website" + }, + { + "url": "https://github.com/dotnet/dotnet", + "type": "vcs" + } + ] + }, + { + "type": "library", + "bom-ref": "pkg:nuget/Microsoft.Extensions.DependencyInjection@10.0.0", + "authors": [ + { + "name": "Microsoft" + } + ], + "name": "Microsoft.Extensions.DependencyInjection", + "version": "10.0.0", + "description": "Default implementation of dependency injection for Microsoft.Extensions.DependencyInjection.", + "scope": "excluded", + "hashes": [ + { + "alg": "SHA-512", + "content": "8CA54E7DFCB35BBCAA9A292F0107FAF6808A8CF94C8879A7AAFE31AE841174D29009895421CE2BBC9BFAFD86D0CAABD402BBEBCC84F1961774740DCC155229BB" + } + ], + "licenses": [ + { + "license": { + "id": "MIT" + } + } + ], + "copyright": "\u00A9 Microsoft Corporation. All rights reserved.", + "purl": "pkg:nuget/Microsoft.Extensions.DependencyInjection@10.0.0", + "externalReferences": [ + { + "url": "https://dot.net/", + "type": "website" + }, + { + "url": "https://github.com/dotnet/dotnet", + "type": "vcs" + } + ] + }, + { + "type": "library", + "bom-ref": "pkg:nuget/Microsoft.Extensions.DependencyInjection@8.0.0", + "authors": [ + { + "name": "Microsoft" + } + ], + "name": "Microsoft.Extensions.DependencyInjection", + "version": "8.0.0", + "description": "Default implementation of dependency injection for Microsoft.Extensions.DependencyInjection.", + "scope": "required", + "hashes": [ + { + "alg": "SHA-512", + "content": "96391AF4AE0542F4AE96C8009C9FFBF304ACADF476CDA262A8EA73E33B172529541044186C59D656377BB2DE42C9F5925E0632A81F6E7516F2A646E8916F16EC" + } + ], + "licenses": [ + { + "license": { + "id": "MIT" + } + } + ], + "copyright": "\u00A9 Microsoft Corporation. All rights reserved.", + "purl": "pkg:nuget/Microsoft.Extensions.DependencyInjection@8.0.0", + "externalReferences": [ + { + "url": "https://dot.net/", + "type": "website" + }, + { + "url": "https://github.com/dotnet/runtime", + "type": "vcs" + } + ] + }, + { + "type": "library", + "bom-ref": "pkg:nuget/Microsoft.Extensions.DependencyInjection.Abstractions@10.0.0", + "authors": [ + { + "name": "Microsoft" + } + ], + "name": "Microsoft.Extensions.DependencyInjection.Abstractions", + "version": "10.0.0", + "description": "Abstractions for dependency injection.\n\nCommonly Used Types:\nMicrosoft.Extensions.DependencyInjection.IServiceCollection", + "scope": "required", + "hashes": [ + { + "alg": "SHA-512", + "content": "475254983871F35CD70118FBFF743049EC623BD94D1363C13D7C8AE3BB1B9521883A5E0977AD222D8F30B6627F3738695ED3C1892393327D8A158B9FED069123" + } + ], + "licenses": [ + { + "license": { + "id": "MIT" + } + } + ], + "copyright": "\u00A9 Microsoft Corporation. All rights reserved.", + "purl": "pkg:nuget/Microsoft.Extensions.DependencyInjection.Abstractions@10.0.0", + "externalReferences": [ + { + "url": "https://dot.net/", + "type": "website" + }, + { + "url": "https://github.com/dotnet/dotnet", + "type": "vcs" + } + ] + }, + { + "type": "library", + "bom-ref": "pkg:nuget/Microsoft.Extensions.DependencyInjection.Abstractions@10.0.2", + "authors": [ + { + "name": "Microsoft" + } + ], + "name": "Microsoft.Extensions.DependencyInjection.Abstractions", + "version": "10.0.2", + "description": "Abstractions for dependency injection.\n\nCommonly Used Types:\nMicrosoft.Extensions.DependencyInjection.IServiceCollection", + "scope": "required", + "hashes": [ + { + "alg": "SHA-512", + "content": "2B6512AA95ED978B789BA917883948236BE5DC353F0FD4148077B51E63C6E0DD6AD1BE9CEB4614F94222A07A559ECAFD4FC593520A26CEA835619053E03C240C" + } + ], + "licenses": [ + { + "license": { + "id": "MIT" + } + } + ], + "copyright": "\u00A9 Microsoft Corporation. All rights reserved.", + "purl": "pkg:nuget/Microsoft.Extensions.DependencyInjection.Abstractions@10.0.2", + "externalReferences": [ + { + "url": "https://dot.net/", + "type": "website" + }, + { + "url": "https://github.com/dotnet/dotnet", + "type": "vcs" + } + ] + }, + { + "type": "library", + "bom-ref": "pkg:nuget/Microsoft.Extensions.DependencyInjection.Abstractions@8.0.0", + "authors": [ + { + "name": "Microsoft" + } + ], + "name": "Microsoft.Extensions.DependencyInjection.Abstractions", + "version": "8.0.0", + "description": "Abstractions for dependency injection.\n\nCommonly Used Types:\nMicrosoft.Extensions.DependencyInjection.IServiceCollection", + "scope": "required", + "hashes": [ + { + "alg": "SHA-512", + "content": "94BC05ED29755109565D9CDFC901087EE1FA08302DDA393106BC9A0BD7384F0DC2B6C2F123C1BD53FCE06BABDBFA845DC6D22A163C4B0646C5251DCC5AEAC282" + } + ], + "licenses": [ + { + "license": { + "id": "MIT" + } + } + ], + "copyright": "\u00A9 Microsoft Corporation. All rights reserved.", + "purl": "pkg:nuget/Microsoft.Extensions.DependencyInjection.Abstractions@8.0.0", + "externalReferences": [ + { + "url": "https://dot.net/", + "type": "website" + }, + { + "url": "https://github.com/dotnet/runtime", + "type": "vcs" + } + ] + }, + { + "type": "library", + "bom-ref": "pkg:nuget/Microsoft.Extensions.Diagnostics@10.0.2", + "authors": [ + { + "name": "Microsoft" + } + ], + "name": "Microsoft.Extensions.Diagnostics", + "version": "10.0.2", + "description": "This package includes the default implementation of IMeterFactory and additional extension methods to easily register it with the Dependency Injection framework.", + "scope": "required", + "hashes": [ + { + "alg": "SHA-512", + "content": "5AB70AD3448EE35B4D1E202011EE10E0738B6BE2FC79861C64FFBAAAD8B9DD7626B12ECDC2A2BF1F49040F3DACB4A353AECBF55D0C8A0077C423445FE08DB67B" + } + ], + "licenses": [ + { + "license": { + "id": "MIT" + } + } + ], + "copyright": "\u00A9 Microsoft Corporation. All rights reserved.", + "purl": "pkg:nuget/Microsoft.Extensions.Diagnostics@10.0.2", + "externalReferences": [ + { + "url": "https://dot.net/", + "type": "website" + }, + { + "url": "https://github.com/dotnet/dotnet", + "type": "vcs" + } + ] + }, + { + "type": "library", + "bom-ref": "pkg:nuget/Microsoft.Extensions.Diagnostics.Abstractions@10.0.2", + "authors": [ + { + "name": "Microsoft" + } + ], + "name": "Microsoft.Extensions.Diagnostics.Abstractions", + "version": "10.0.2", + "description": "Diagnostic abstractions for Microsoft.Extensions.Diagnostics.\n\nCommonly Used Types:\nMicrosoft.Extensions.Diagnostics.Metrics.IMetricsBuilder\nMicrosoft.Extensions.Diagnostics.Metrics.IMetricsListener\nMicrosoft.Extensions.Diagnostics.Metrics.InstrumentRule\nMicrosoft.Extensions.Diagnostics.Metrics.MeterScope\nMicrosoft.Extensions.Diagnostics.Metrics.MetricsBuilderExtensions\nMicrosoft.Extensions.Diagnostics.Metrics.MetricsOptions", + "scope": "required", + "hashes": [ + { + "alg": "SHA-512", + "content": "C201C9B29AECA29AD89AE9AB7956FD1C696C150445720481FD78F3C4BF1E36895F1DEE21A1FD2E9F8F09423C08E6B22201EB02380818C021D6BCA84DDB45882D" + } + ], + "licenses": [ + { + "license": { + "id": "MIT" + } + } + ], + "copyright": "\u00A9 Microsoft Corporation. All rights reserved.", + "purl": "pkg:nuget/Microsoft.Extensions.Diagnostics.Abstractions@10.0.2", + "externalReferences": [ + { + "url": "https://dot.net/", + "type": "website" + }, + { + "url": "https://github.com/dotnet/dotnet", + "type": "vcs" + } + ] + }, + { + "type": "library", + "bom-ref": "pkg:nuget/Microsoft.Extensions.FileProviders.Abstractions@10.0.0", + "authors": [ + { + "name": "Microsoft" + } + ], + "name": "Microsoft.Extensions.FileProviders.Abstractions", + "version": "10.0.0", + "description": "Abstractions of files and directories.\n\nCommonly Used Types:\nMicrosoft.Extensions.FileProviders.IDirectoryContents\nMicrosoft.Extensions.FileProviders.IFileInfo\nMicrosoft.Extensions.FileProviders.IFileProvider", + "scope": "excluded", + "hashes": [ + { + "alg": "SHA-512", + "content": "974C24652FF64ECEB9752C814BE807BA76F80CBACACBC0A9EB7DAE8D1D9D5C1184F56A7679FA0CB36F3A024F480FFFC620735034DDAD5C5C7AE8F787FA3AAB4E" + } + ], + "licenses": [ + { + "license": { + "id": "MIT" + } + } + ], + "copyright": "\u00A9 Microsoft Corporation. All rights reserved.", + "purl": "pkg:nuget/Microsoft.Extensions.FileProviders.Abstractions@10.0.0", + "externalReferences": [ + { + "url": "https://dot.net/", + "type": "website" + }, + { + "url": "https://github.com/dotnet/dotnet", + "type": "vcs" + } + ] + }, + { + "type": "library", + "bom-ref": "pkg:nuget/Microsoft.Extensions.FileProviders.Physical@10.0.0", + "authors": [ + { + "name": "Microsoft" + } + ], + "name": "Microsoft.Extensions.FileProviders.Physical", + "version": "10.0.0", + "description": "File provider for physical files for Microsoft.Extensions.FileProviders.", + "scope": "excluded", + "hashes": [ + { + "alg": "SHA-512", + "content": "35BBF2AFF668B879FB9D33D29E115D8E8E78946C6F5D88C21660CFACB9D51FD4850872F74C77E6823C8E998A9F244A882931E148E0BF5E5DE1A11A549144B497" + } + ], + "licenses": [ + { + "license": { + "id": "MIT" + } + } + ], + "copyright": "\u00A9 Microsoft Corporation. All rights reserved.", + "purl": "pkg:nuget/Microsoft.Extensions.FileProviders.Physical@10.0.0", + "externalReferences": [ + { + "url": "https://dot.net/", + "type": "website" + }, + { + "url": "https://github.com/dotnet/dotnet", + "type": "vcs" + } + ] + }, + { + "type": "library", + "bom-ref": "pkg:nuget/Microsoft.Extensions.FileSystemGlobbing@10.0.0", + "authors": [ + { + "name": "Microsoft" + } + ], + "name": "Microsoft.Extensions.FileSystemGlobbing", + "version": "10.0.0", + "description": "File system globbing to find files matching a specified pattern.", + "scope": "excluded", + "hashes": [ + { + "alg": "SHA-512", + "content": "EC80416600238FF8028C04E116A34D748F1F688AD6A318737C9C3F7ED7E1B49DF0773EC0294A91D456796C96B4846192124A38DA69AF1292AB611494A9794FF6" + } + ], + "licenses": [ + { + "license": { + "id": "MIT" + } + } + ], + "copyright": "\u00A9 Microsoft Corporation. All rights reserved.", + "purl": "pkg:nuget/Microsoft.Extensions.FileSystemGlobbing@10.0.0", + "externalReferences": [ + { + "url": "https://dot.net/", + "type": "website" + }, + { + "url": "https://github.com/dotnet/dotnet", + "type": "vcs" + } + ] + }, + { + "type": "library", + "bom-ref": "pkg:nuget/Microsoft.Extensions.Hosting.Abstractions@9.0.0", + "authors": [ + { + "name": "Microsoft" + } + ], + "name": "Microsoft.Extensions.Hosting.Abstractions", + "version": "9.0.0", + "description": "Hosting and startup abstractions for applications.", + "scope": "excluded", + "hashes": [ + { + "alg": "SHA-512", + "content": "50D29238DB63BCF23232A4B39890748A6D3E7832F8DD85884C6CFF2A8FE8074C4E37750D96748B66FA0DCF5848712054F766ED7E032FC3271C49868CA10EFCCC" + } + ], + "licenses": [ + { + "license": { + "id": "MIT" + } + } + ], + "copyright": "\u00A9 Microsoft Corporation. All rights reserved.", + "purl": "pkg:nuget/Microsoft.Extensions.Hosting.Abstractions@9.0.0", + "externalReferences": [ + { + "url": "https://dot.net/", + "type": "website" + }, + { + "url": "https://github.com/dotnet/runtime", + "type": "vcs" + } + ] + }, + { + "type": "library", + "bom-ref": "pkg:nuget/Microsoft.Extensions.Localization@3.1.18", + "authors": [ + { + "name": "Microsoft" + } + ], + "name": "Microsoft.Extensions.Localization", + "version": "3.1.18", + "description": "Application localization services and default implementation based on ResourceManager to load localized assembly resources.", + "scope": "excluded", + "hashes": [ + { + "alg": "SHA-512", + "content": "14E55CC0F23D22458057A750672CDABF688EA929EB4A8D6902A202B8476405329ED11CC7619F1553CB78E82797CA8D470715E282145431AB8822FFF9B148EC6C" + } + ], + "licenses": [ + { + "license": { + "id": "Apache-2.0" + } + } + ], + "copyright": "\u00A9 Microsoft Corporation. All rights reserved.", + "purl": "pkg:nuget/Microsoft.Extensions.Localization@3.1.18", + "externalReferences": [ + { + "url": "https://asp.net/", + "type": "website" + }, + { + "url": "https://github.com/aspnet/Extensions", + "type": "vcs" + } + ] + }, + { + "type": "library", + "bom-ref": "pkg:nuget/Microsoft.Extensions.Localization.Abstractions@10.0.0", + "authors": [ + { + "name": "Microsoft" + } + ], + "name": "Microsoft.Extensions.Localization.Abstractions", + "version": "10.0.0", + "description": "Abstractions of application localization services.\nCommonly used types:\nMicrosoft.Extensions.Localization.IStringLocalizer\nMicrosoft.Extensions.Localization.IStringLocalizer\u003CT\u003E\n\nThis package was built from the source code at https://github.com/dotnet/dotnet/tree/b0f34d51fccc69fd334253924abd8d6853fad7aa", + "scope": "excluded", + "hashes": [ + { + "alg": "SHA-512", + "content": "D55304B532EEEC2751A2CECFB8D1CBCF09561FB856DB1229C1C80EE95B004172A09A3B68DAC23681093DB7FDBCFF83FF1E233A128C67A45A9C75C1E592017F7F" + } + ], + "licenses": [ + { + "license": { + "id": "MIT" + } + } + ], + "copyright": "\u00A9 Microsoft Corporation. All rights reserved.", + "purl": "pkg:nuget/Microsoft.Extensions.Localization.Abstractions@10.0.0", + "externalReferences": [ + { + "url": "https://asp.net/", + "type": "website" + }, + { + "url": "https://github.com/dotnet/dotnet", + "type": "vcs" + } + ] + }, + { + "type": "library", + "bom-ref": "pkg:nuget/Microsoft.Extensions.Logging@10.0.0", + "authors": [ + { + "name": "Microsoft" + } + ], + "name": "Microsoft.Extensions.Logging", + "version": "10.0.0", + "description": "Logging infrastructure default implementation for Microsoft.Extensions.Logging.", + "scope": "excluded", + "hashes": [ + { + "alg": "SHA-512", + "content": "E14F295D608F7D8523FFAE4B623593E1E89CE3E6D04D5D653B45FA3A6C3CEC033C6E9E4521299745615347FF071C258AE898AD59D7274235E4A955FCB64DA729" + } + ], + "licenses": [ + { + "license": { + "id": "MIT" + } + } + ], + "copyright": "\u00A9 Microsoft Corporation. All rights reserved.", + "purl": "pkg:nuget/Microsoft.Extensions.Logging@10.0.0", + "externalReferences": [ + { + "url": "https://dot.net/", + "type": "website" + }, + { + "url": "https://github.com/dotnet/dotnet", + "type": "vcs" + } + ] + }, + { + "type": "library", + "bom-ref": "pkg:nuget/Microsoft.Extensions.Logging@8.0.0", + "authors": [ + { + "name": "Microsoft" + } + ], + "name": "Microsoft.Extensions.Logging", + "version": "8.0.0", + "description": "Logging infrastructure default implementation for Microsoft.Extensions.Logging.", + "scope": "required", + "hashes": [ + { + "alg": "SHA-512", + "content": "AA30576C428DFF69BAC5F5D71721AF6C4EF583BC524EDBD0A94B49CBD80F698905021260E1A432C32E6D48CE5A30F6822C209F11DCF7C819ABA1FA8347925B06" + } + ], + "licenses": [ + { + "license": { + "id": "MIT" + } + } + ], + "copyright": "\u00A9 Microsoft Corporation. All rights reserved.", + "purl": "pkg:nuget/Microsoft.Extensions.Logging@8.0.0", + "externalReferences": [ + { + "url": "https://dot.net/", + "type": "website" + }, + { + "url": "https://github.com/dotnet/runtime", + "type": "vcs" + } + ] + }, + { + "type": "library", + "bom-ref": "pkg:nuget/Microsoft.Extensions.Logging.Abstractions@10.0.0", + "authors": [ + { + "name": "Microsoft" + } + ], + "name": "Microsoft.Extensions.Logging.Abstractions", + "version": "10.0.0", + "description": "Logging abstractions for Microsoft.Extensions.Logging.\n\nCommonly Used Types:\nMicrosoft.Extensions.Logging.ILogger\nMicrosoft.Extensions.Logging.ILoggerFactory\nMicrosoft.Extensions.Logging.ILogger\u003CTCategoryName\u003E\nMicrosoft.Extensions.Logging.LogLevel\nMicrosoft.Extensions.Logging.Logger\u003CT\u003E\nMicrosoft.Extensions.Logging.LoggerMessage\nMicrosoft.Extensions.Logging.Abstractions.NullLogger", + "scope": "required", + "hashes": [ + { + "alg": "SHA-512", + "content": "0849462F3EA2EE5A06D8AB8A8B13F05F3CF466DE66EBBC6A0A9CAC4BEFC91CEB180AE03C42089AB0CA7A26CA7FE5B4ED1A8F73E235E1308D9997C9529C369DD1" + } + ], + "licenses": [ + { + "license": { + "id": "MIT" + } + } + ], + "copyright": "\u00A9 Microsoft Corporation. All rights reserved.", + "purl": "pkg:nuget/Microsoft.Extensions.Logging.Abstractions@10.0.0", + "externalReferences": [ + { + "url": "https://dot.net/", + "type": "website" + }, + { + "url": "https://github.com/dotnet/dotnet", + "type": "vcs" + } + ] + }, + { + "type": "library", + "bom-ref": "pkg:nuget/Microsoft.Extensions.Logging.Abstractions@10.0.2", + "authors": [ + { + "name": "Microsoft" + } + ], + "name": "Microsoft.Extensions.Logging.Abstractions", + "version": "10.0.2", + "description": "Logging abstractions for Microsoft.Extensions.Logging.\n\nCommonly Used Types:\nMicrosoft.Extensions.Logging.ILogger\nMicrosoft.Extensions.Logging.ILoggerFactory\nMicrosoft.Extensions.Logging.ILogger\u003CTCategoryName\u003E\nMicrosoft.Extensions.Logging.LogLevel\nMicrosoft.Extensions.Logging.Logger\u003CT\u003E\nMicrosoft.Extensions.Logging.LoggerMessage\nMicrosoft.Extensions.Logging.Abstractions.NullLogger", + "scope": "required", + "hashes": [ + { + "alg": "SHA-512", + "content": "20E1D42B416FAA6294C0AA9F1257ED3B24D7522C5F0DEF2AFD09D5E8855CAAD0052D1D52D2F7611ACB4BCC45DA14A5308305C13E0FD539D466AFC2A54ABA5808" + } + ], + "licenses": [ + { + "license": { + "id": "MIT" + } + } + ], + "copyright": "\u00A9 Microsoft Corporation. All rights reserved.", + "purl": "pkg:nuget/Microsoft.Extensions.Logging.Abstractions@10.0.2", + "externalReferences": [ + { + "url": "https://dot.net/", + "type": "website" + }, + { + "url": "https://github.com/dotnet/dotnet", + "type": "vcs" + } + ] + }, + { + "type": "library", + "bom-ref": "pkg:nuget/Microsoft.Extensions.ObjectPool@8.0.11", + "authors": [ + { + "name": "Microsoft" + } + ], + "name": "Microsoft.Extensions.ObjectPool", + "version": "8.0.11", + "description": "A simple object pool implementation.\n\nThis package was built from the source code at https://github.com/dotnet/aspnetcore/tree/47576478939fdd59b4400ad135f47938af486ab3", + "scope": "required", + "hashes": [ + { + "alg": "SHA-512", + "content": "692FCA320340FF1B02FD9C6C11504695825818CBD0C5A0D3C82D76F2302A5866C9B232F91B3F9AD619F0990AB60D0D9DB28ED0101715821A0BBFC6A4E66D65B1" + } + ], + "licenses": [ + { + "license": { + "id": "MIT" + } + } + ], + "copyright": "\u00A9 Microsoft Corporation. All rights reserved.", + "purl": "pkg:nuget/Microsoft.Extensions.ObjectPool@8.0.11", + "externalReferences": [ + { + "url": "https://asp.net/", + "type": "website" + }, + { + "url": "https://github.com/dotnet/aspnetcore", + "type": "vcs" + } + ] + }, + { + "type": "library", + "bom-ref": "pkg:nuget/Microsoft.Extensions.Options@10.0.2", + "authors": [ + { + "name": "Microsoft" + } + ], + "name": "Microsoft.Extensions.Options", + "version": "10.0.2", + "description": "Provides a strongly typed way of specifying and accessing settings using dependency injection.", + "scope": "required", + "hashes": [ + { + "alg": "SHA-512", + "content": "BB03B9AEF5310EA62C840F146D3B7D8AD917B90B83D725E4FA7161DD5504168ADD83AA00F6103ACE127C80705148078C3AE1E05FF7F4B8313EDA906BBB530F02" + } + ], + "licenses": [ + { + "license": { + "id": "MIT" + } + } + ], + "copyright": "\u00A9 Microsoft Corporation. All rights reserved.", + "purl": "pkg:nuget/Microsoft.Extensions.Options@10.0.2", + "externalReferences": [ + { + "url": "https://dot.net/", + "type": "website" + }, + { + "url": "https://github.com/dotnet/dotnet", + "type": "vcs" + } + ] + }, + { + "type": "library", + "bom-ref": "pkg:nuget/Microsoft.Extensions.Options@8.0.2", + "authors": [ + { + "name": "Microsoft" + } + ], + "name": "Microsoft.Extensions.Options", + "version": "8.0.2", + "description": "Provides a strongly typed way of specifying and accessing settings using dependency injection.", + "scope": "required", + "hashes": [ + { + "alg": "SHA-512", + "content": "CC0C10336580C9519740A042B1E42D391BCB32B63732163AE1161E1C5B55A4CD4A736E1902EB2A4DBB89D784B0ACF584B5042B4F3481A61DD30A4E229FB523C5" + } + ], + "licenses": [ + { + "license": { + "id": "MIT" + } + } + ], + "copyright": "\u00A9 Microsoft Corporation. All rights reserved.", + "purl": "pkg:nuget/Microsoft.Extensions.Options@8.0.2", + "externalReferences": [ + { + "url": "https://dot.net/", + "type": "website" + }, + { + "url": "https://github.com/dotnet/runtime", + "type": "vcs" + } + ] + }, + { + "type": "library", + "bom-ref": "pkg:nuget/Microsoft.Extensions.Options.ConfigurationExtensions@10.0.2", + "authors": [ + { + "name": "Microsoft" + } + ], + "name": "Microsoft.Extensions.Options.ConfigurationExtensions", + "version": "10.0.2", + "description": "Provides additional configuration specific functionality related to Options.", + "scope": "required", + "hashes": [ + { + "alg": "SHA-512", + "content": "486B68AB31C70E3F2C6DF772DB7CC07D8C45400892DD61801531A9B0F42A3021B9013BB339202E4B7C3E1980154664C86D712D96EB1F8B747E88E316C01A4F7F" + } + ], + "licenses": [ + { + "license": { + "id": "MIT" + } + } + ], + "copyright": "\u00A9 Microsoft Corporation. All rights reserved.", + "purl": "pkg:nuget/Microsoft.Extensions.Options.ConfigurationExtensions@10.0.2", + "externalReferences": [ + { + "url": "https://dot.net/", + "type": "website" + }, + { + "url": "https://github.com/dotnet/dotnet", + "type": "vcs" + } + ] + }, + { + "type": "library", + "bom-ref": "pkg:nuget/Microsoft.Extensions.Primitives@10.0.2", + "authors": [ + { + "name": "Microsoft" + } + ], + "name": "Microsoft.Extensions.Primitives", + "version": "10.0.2", + "description": "Primitives shared by framework extensions. Commonly used types include:\n\nCommonly Used Types:\nMicrosoft.Extensions.Primitives.IChangeToken\nMicrosoft.Extensions.Primitives.StringValues\nMicrosoft.Extensions.Primitives.StringSegment", + "scope": "required", + "hashes": [ + { + "alg": "SHA-512", + "content": "315880CE2CD28BACA3A27166A2C8F7A96B6711194D6C5BB2BDCDE5698A74151819624D256F3D8CCE898066079C55E2257D0BDA10312759F016C994144658FA3F" + } + ], + "licenses": [ + { + "license": { + "id": "MIT" + } + } + ], + "copyright": "\u00A9 Microsoft Corporation. All rights reserved.", + "purl": "pkg:nuget/Microsoft.Extensions.Primitives@10.0.2", + "externalReferences": [ + { + "url": "https://dot.net/", + "type": "website" + }, + { + "url": "https://github.com/dotnet/dotnet", + "type": "vcs" + } + ] + }, + { + "type": "library", + "bom-ref": "pkg:nuget/Microsoft.Extensions.Primitives@8.0.0", + "authors": [ + { + "name": "Microsoft" + } + ], + "name": "Microsoft.Extensions.Primitives", + "version": "8.0.0", + "description": "Primitives shared by framework extensions. Commonly used types include:\n\nCommonly Used Types:\nMicrosoft.Extensions.Primitives.IChangeToken\nMicrosoft.Extensions.Primitives.StringValues\nMicrosoft.Extensions.Primitives.StringSegment", + "scope": "required", + "hashes": [ + { + "alg": "SHA-512", + "content": "1F5475CA3D3CE18463456DD135AFAC502D6F82FEA6E4E4814A61F86616C348DECF28B73D15C2BB276D1A3C039EA6064F75E1329F6F3A64CAA3520D70AB92C32D" + } + ], + "licenses": [ + { + "license": { + "id": "MIT" + } + } + ], + "copyright": "\u00A9 Microsoft Corporation. All rights reserved.", + "purl": "pkg:nuget/Microsoft.Extensions.Primitives@8.0.0", + "externalReferences": [ + { + "url": "https://dot.net/", + "type": "website" + }, + { + "url": "https://github.com/dotnet/runtime", + "type": "vcs" + } + ] + }, + { + "type": "library", + "bom-ref": "pkg:nuget/Microsoft.Extensions.Validation@10.0.0", + "authors": [ + { + "name": "Microsoft" + } + ], + "name": "Microsoft.Extensions.Validation", + "version": "10.0.0", + "description": "Common validation abstractions and validation infrastructure for .NET applications.\n\nThis package was built from the source code at https://github.com/dotnet/dotnet/tree/b0f34d51fccc69fd334253924abd8d6853fad7aa", + "scope": "excluded", + "hashes": [ + { + "alg": "SHA-512", + "content": "0ED142C82827FF2674595F76245760AA9B1655EBD91311EB9422180BE812A93D52E7C03B6D0A2552ECBD098234BA27184156D2C4A1FB04A8071286B488846759" + } + ], + "licenses": [ + { + "license": { + "id": "MIT" + } + } + ], + "copyright": "\u00A9 Microsoft Corporation. All rights reserved.", + "purl": "pkg:nuget/Microsoft.Extensions.Validation@10.0.0", + "externalReferences": [ + { + "url": "https://asp.net/", + "type": "website" + }, + { + "url": "https://github.com/dotnet/dotnet", + "type": "vcs" + } + ] + }, + { + "type": "library", + "bom-ref": "pkg:nuget/Microsoft.IdentityModel.Abstractions@8.15.0", + "authors": [ + { + "name": "Microsoft" + } + ], + "name": "Microsoft.IdentityModel.Abstractions", + "version": "8.15.0", + "description": "A package containing thin abstractions for Microsoft.IdentityModel.", + "scope": "required", + "hashes": [ + { + "alg": "SHA-512", + "content": "0D5D2C4EBA3991AF030832327C443E19D77F40062249B80E0B78AFA3228B6B3ED1AAE18BF9564693C3EF02C30DEA4A734787851154E9908D0180BB3227AFEC13" + } + ], + "licenses": [ + { + "license": { + "id": "MIT" + } + } + ], + "copyright": "\u00A9 Microsoft Corporation. All rights reserved.", + "purl": "pkg:nuget/Microsoft.IdentityModel.Abstractions@8.15.0", + "externalReferences": [ + { + "url": "https://github.com/AzureAD/azure-activedirectory-identitymodel-extensions-for-dotnet", + "type": "website" + }, + { + "url": "https://github.com/AzureAD/azure-activedirectory-identitymodel-extensions-for-dotnet", + "type": "vcs" + } + ] + }, + { + "type": "library", + "bom-ref": "pkg:nuget/Microsoft.IdentityModel.JsonWebTokens@8.15.0", + "authors": [ + { + "name": "Microsoft" + } + ], + "name": "Microsoft.IdentityModel.JsonWebTokens", + "version": "8.15.0", + "description": "Includes types that provide support for creating, serializing and validating JSON Web Tokens. This is a newer, faster version of System.IdentityModel.Tokens.Jwt that has additional functionality.", + "scope": "required", + "hashes": [ + { + "alg": "SHA-512", + "content": "E4FF62221EF91F4D8A08A69559B31094ACBE3AD977C6EB0AB94715867910661F0C0EEDDEA24D2868624FAD06F4C2A8499B5182E86A928E6D7A1CA21EC926B14A" + } + ], + "licenses": [ + { + "license": { + "id": "MIT" + } + } + ], + "copyright": "\u00A9 Microsoft Corporation. All rights reserved.", + "purl": "pkg:nuget/Microsoft.IdentityModel.JsonWebTokens@8.15.0", + "externalReferences": [ + { + "url": "https://github.com/AzureAD/azure-activedirectory-identitymodel-extensions-for-dotnet", + "type": "website" + }, + { + "url": "https://github.com/AzureAD/azure-activedirectory-identitymodel-extensions-for-dotnet", + "type": "vcs" + } + ] + }, + { + "type": "library", + "bom-ref": "pkg:nuget/Microsoft.IdentityModel.Logging@8.15.0", + "authors": [ + { + "name": "Microsoft" + } + ], + "name": "Microsoft.IdentityModel.Logging", + "version": "8.15.0", + "description": "Includes Event Source based logging support.", + "scope": "required", + "hashes": [ + { + "alg": "SHA-512", + "content": "B50D90321B5D31B2462933D541334F454F982F2800635920559248285AF3504752A8E25D35907C5958154C6DAABF85A85B5FBF45BBE60C867448D63309AAECC5" + } + ], + "licenses": [ + { + "license": { + "id": "MIT" + } + } + ], + "copyright": "\u00A9 Microsoft Corporation. All rights reserved.", + "purl": "pkg:nuget/Microsoft.IdentityModel.Logging@8.15.0", + "externalReferences": [ + { + "url": "https://github.com/AzureAD/azure-activedirectory-identitymodel-extensions-for-dotnet", + "type": "website" + }, + { + "url": "https://github.com/AzureAD/azure-activedirectory-identitymodel-extensions-for-dotnet", + "type": "vcs" + } + ] + }, + { + "type": "library", + "bom-ref": "pkg:nuget/Microsoft.IdentityModel.Protocols@8.0.1", + "authors": [ + { + "name": "Microsoft" + } + ], + "name": "Microsoft.IdentityModel.Protocols", + "version": "8.0.1", + "description": "Provides base protocol support for OpenIdConnect and WsFederation.", + "scope": "required", + "hashes": [ + { + "alg": "SHA-512", + "content": "73FC6C8C2FE65F9986EF725A58C2D799058B21397ED4DA67AAA295955A35936C4369454BE99CC0595F49D22B4F1BD04B250EBF0F9FDF58F7239B9953A9705C0D" + } + ], + "licenses": [ + { + "license": { + "id": "MIT" + } + } + ], + "copyright": "\u00A9 Microsoft Corporation. All rights reserved.", + "purl": "pkg:nuget/Microsoft.IdentityModel.Protocols@8.0.1", + "externalReferences": [ + { + "url": "https://github.com/AzureAD/azure-activedirectory-identitymodel-extensions-for-dotnet", + "type": "website" + }, + { + "url": "https://github.com/AzureAD/azure-activedirectory-identitymodel-extensions-for-dotnet", + "type": "vcs" + } + ] + }, + { + "type": "library", + "bom-ref": "pkg:nuget/Microsoft.IdentityModel.Protocols.OpenIdConnect@8.0.1", + "authors": [ + { + "name": "Microsoft" + } + ], + "name": "Microsoft.IdentityModel.Protocols.OpenIdConnect", + "version": "8.0.1", + "description": "Includes types that provide support for OpenIdConnect protocol.", + "scope": "required", + "hashes": [ + { + "alg": "SHA-512", + "content": "8DFBFAFA65D92E9BDFEE9BD5E1C2DDEE7832B7C167BB79D7A9D726903126AB05EE031339CD3CB832C9A6F8E5A090F929A3F6C6F11B1CCDDAE8F850CADCCD3ADD" + } + ], + "licenses": [ + { + "license": { + "id": "MIT" + } + } + ], + "copyright": "\u00A9 Microsoft Corporation. All rights reserved.", + "purl": "pkg:nuget/Microsoft.IdentityModel.Protocols.OpenIdConnect@8.0.1", + "externalReferences": [ + { + "url": "https://github.com/AzureAD/azure-activedirectory-identitymodel-extensions-for-dotnet", + "type": "website" + }, + { + "url": "https://github.com/AzureAD/azure-activedirectory-identitymodel-extensions-for-dotnet", + "type": "vcs" + } + ] + }, + { + "type": "library", + "bom-ref": "pkg:nuget/Microsoft.IdentityModel.Tokens@8.15.0", + "authors": [ + { + "name": "Microsoft" + } + ], + "name": "Microsoft.IdentityModel.Tokens", + "version": "8.15.0", + "description": "Includes types that provide support for SecurityTokens, Cryptographic operations: Signing, Verifying Signatures, Encryption.", + "scope": "required", + "hashes": [ + { + "alg": "SHA-512", + "content": "C967AB5FCD98D72EAE9AC7461879AB9A2140C171AF83638759BE8577D187E4BAFBCD7C26099A921A553A21E347CD42E833774BF3D1CEE4ACDE6D085583218017" + } + ], + "licenses": [ + { + "license": { + "id": "MIT" + } + } + ], + "copyright": "\u00A9 Microsoft Corporation. All rights reserved.", + "purl": "pkg:nuget/Microsoft.IdentityModel.Tokens@8.15.0", + "externalReferences": [ + { + "url": "https://github.com/AzureAD/azure-activedirectory-identitymodel-extensions-for-dotnet", + "type": "website" + }, + { + "url": "https://github.com/AzureAD/azure-activedirectory-identitymodel-extensions-for-dotnet", + "type": "vcs" + } + ] + }, + { + "type": "library", + "bom-ref": "pkg:nuget/Microsoft.JSInterop@10.0.0", + "authors": [ + { + "name": "Microsoft" + } + ], + "name": "Microsoft.JSInterop", + "version": "10.0.0", + "description": "Abstractions and features for interop between .NET and JavaScript code.\n\nThis package was built from the source code at https://github.com/dotnet/dotnet/tree/b0f34d51fccc69fd334253924abd8d6853fad7aa", + "scope": "excluded", + "hashes": [ + { + "alg": "SHA-512", + "content": "AFC193BF3D46186111F308296AE8F85DF22C3CEEE75DA3786FD12C8DE5BF93DBC24EA424C89E6352A795D01A8429C449FFFC4FBF087A49FB315F333C5852785D" + } + ], + "licenses": [ + { + "license": { + "id": "MIT" + } + } + ], + "copyright": "\u00A9 Microsoft Corporation. All rights reserved.", + "purl": "pkg:nuget/Microsoft.JSInterop@10.0.0", + "externalReferences": [ + { + "url": "https://asp.net/", + "type": "website" + }, + { + "url": "https://github.com/dotnet/dotnet", + "type": "vcs" + } + ] + }, + { + "type": "library", + "bom-ref": "pkg:nuget/Microsoft.JSInterop.WebAssembly@10.0.0", + "authors": [ + { + "name": "Microsoft" + } + ], + "name": "Microsoft.JSInterop.WebAssembly", + "version": "10.0.0", + "description": "Abstractions and features for interop between .NET WebAssembly and JavaScript code.\n\nThis package was built from the source code at https://github.com/dotnet/dotnet/tree/b0f34d51fccc69fd334253924abd8d6853fad7aa", + "scope": "excluded", + "hashes": [ + { + "alg": "SHA-512", + "content": "D2D4662F2DF3D590D17FE7C75D2E198D9404DC00614330CD8DD39DE5527C08FC52D042948DC870F0F03A2D24DDFD892D7092F911F9A5DAB069775CDCD6F0568E" + } + ], + "licenses": [ + { + "license": { + "id": "MIT" + } + } + ], + "copyright": "\u00A9 Microsoft Corporation. All rights reserved.", + "purl": "pkg:nuget/Microsoft.JSInterop.WebAssembly@10.0.0", + "externalReferences": [ + { + "url": "https://asp.net/", + "type": "website" + }, + { + "url": "https://github.com/dotnet/dotnet", + "type": "vcs" + } + ] + }, + { + "type": "library", + "bom-ref": "pkg:nuget/Microsoft.Net.Http.Headers@2.3.8", + "authors": [ + { + "name": "Microsoft" + } + ], + "name": "Microsoft.Net.Http.Headers", + "version": "2.3.8", + "description": "HTTP header parser implementations.", + "scope": "required", + "hashes": [ + { + "alg": "SHA-512", + "content": "39657B1379B027537143D29F09E80E2DDF5842964066E6843D4953AB292B3C029CE9847875724F616C1D62D632043735738B0BFF731833CA8FA88365328485FB" + } + ], + "licenses": [ + { + "license": { + "name": "Unknown - See URL", + "url": "https://raw.githubusercontent.com/aspnet/AspNetCore/2.0.0/LICENSE.txt" + } + } + ], + "copyright": "\u00A9 Microsoft Corporation. All rights reserved.", + "purl": "pkg:nuget/Microsoft.Net.Http.Headers@2.3.8", + "externalReferences": [ + { + "url": "https://asp.net/", + "type": "website" + }, + { + "url": "https://github.com/dotnet/aspnetcore", + "type": "vcs" + } + ] + }, + { + "type": "library", + "bom-ref": "pkg:nuget/Microsoft.NET.Test.Sdk@18.0.1", + "authors": [ + { + "name": "Microsoft" + } + ], + "name": "Microsoft.NET.Test.Sdk", + "version": "18.0.1", + "description": "The MSbuild targets and properties for building .NET test projects.", + "scope": "excluded", + "hashes": [ + { + "alg": "SHA-512", + "content": "71FA67E085B443E7A6203F1E528712EF17E6C306200FF257E52FB309903697B81C633C59D6FBDF71D64770A92ECC21F880C6C162A719AAD067F6E65AD1625152" + } + ], + "licenses": [ + { + "license": { + "id": "MIT" + } + } + ], + "copyright": "\u00A9 Microsoft Corporation. All rights reserved.", + "purl": "pkg:nuget/Microsoft.NET.Test.Sdk@18.0.1", + "externalReferences": [ + { + "url": "https://github.com/microsoft/vstest", + "type": "website" + }, + { + "url": "https://github.com/microsoft/vstest", + "type": "vcs" + } + ] + }, + { + "type": "library", + "bom-ref": "pkg:nuget/Microsoft.OpenApi@2.4.1", + "authors": [ + { + "name": "Microsoft" + } + ], + "name": "Microsoft.OpenApi", + "version": "2.4.1", + "description": ".NET models with JSON and YAML writers for OpenAPI specification", + "scope": "required", + "hashes": [ + { + "alg": "SHA-512", + "content": "5A1D83D105A21A57F427C2C4C8C1D3A9619951B1E63DCC013410B68959877AF64C3CDB528B94C93CE31E40548C589DB5E5988484B6B7AAA1D1412FB9B974FF49" + } + ], + "licenses": [ + { + "license": { + "id": "MIT" + } + } + ], + "copyright": "\u00A9 Microsoft Corporation. All rights reserved.", + "purl": "pkg:nuget/Microsoft.OpenApi@2.4.1", + "externalReferences": [ + { + "url": "https://github.com/Microsoft/OpenAPI.NET", + "type": "website" + }, + { + "url": "https://github.com/Microsoft/OpenAPI.NET", + "type": "vcs" + } + ] + }, + { + "type": "library", + "bom-ref": "pkg:nuget/Microsoft.Rest.ClientRuntime@2.3.24", + "authors": [ + { + "name": "Microsoft" + } + ], + "name": "Microsoft.Rest.ClientRuntime", + "version": "2.3.24", + "description": "Infrastructure for error handling, tracing, and HttpClient pipeline configuration. Required by client libraries generated using AutoRest.", + "scope": "required", + "hashes": [ + { + "alg": "SHA-512", + "content": "B144E7678423671B986289070259D6E9C33D1F865C3F6BD81D2CFDC72A71195588E29AAF700E0053E4C1E396025DB307B342C5712D67083D44D747F24EB5715F" + } + ], + "licenses": [ + { + "license": { + "name": "Unknown - See URL", + "url": "https://raw.githubusercontent.com/Microsoft/dotnet/master/LICENSE" + } + } + ], + "copyright": "\u00A9 Microsoft Corporation. All rights reserved.", + "purl": "pkg:nuget/Microsoft.Rest.ClientRuntime@2.3.24", + "externalReferences": [ + { + "url": "https://github.com/Azure/azure-sdk-for-net", + "type": "website" + }, + { + "url": "https://github.com/Azure/azure-sdk-for-net", + "type": "vcs" + } + ] + }, + { + "type": "library", + "bom-ref": "pkg:nuget/Microsoft.Testing.Extensions.Telemetry@2.0.2", + "authors": [ + { + "name": "Microsoft" + } + ], + "name": "Microsoft.Testing.Extensions.Telemetry", + "version": "2.0.2", + "description": "Microsoft Testing is a set of platform, framework and protocol intended to make it possible to run any test on any target or device.\n\nThis package provides telemetry for the platform.", + "scope": "excluded", + "hashes": [ + { + "alg": "SHA-512", + "content": "AE82D85684E9CDB088B8CDF39CA61642CA1F65D29ADA494F002148F48123EED60D7578FBEA90442A1D342B8216C0C05C95F6C23591ACD1224E5EEB176C071098" + } + ], + "licenses": [ + { + "license": { + "id": "MIT" + } + } + ], + "copyright": "\u00A9 Microsoft Corporation. All rights reserved.", + "purl": "pkg:nuget/Microsoft.Testing.Extensions.Telemetry@2.0.2", + "externalReferences": [ + { + "url": "https://github.com/microsoft/testfx", + "type": "website" + }, + { + "url": "https://github.com/microsoft/testfx", + "type": "vcs" + } + ] + }, + { + "type": "library", + "bom-ref": "pkg:nuget/Microsoft.Testing.Extensions.TrxReport.Abstractions@2.0.2", + "authors": [ + { + "name": "Microsoft" + } + ], + "name": "Microsoft.Testing.Extensions.TrxReport.Abstractions", + "version": "2.0.2", + "description": "Package Description", + "scope": "excluded", + "hashes": [ + { + "alg": "SHA-512", + "content": "714F9D29FFCF04806179A0F4863B3EAB92C3ACA954781C878BF0DC6C6119156BDFC0B1077A9C2407A6C3C7FA69E93745D1EEA8E096FCB37B9712A867574ACB5F" + } + ], + "licenses": [ + { + "license": { + "id": "MIT" + } + } + ], + "copyright": "\u00A9 Microsoft Corporation. All rights reserved.", + "purl": "pkg:nuget/Microsoft.Testing.Extensions.TrxReport.Abstractions@2.0.2", + "externalReferences": [ + { + "url": "https://github.com/microsoft/testfx", + "type": "website" + }, + { + "url": "https://github.com/microsoft/testfx", + "type": "vcs" + } + ] + }, + { + "type": "library", + "bom-ref": "pkg:nuget/Microsoft.Testing.Extensions.VSTestBridge@2.0.2", + "authors": [ + { + "name": "Microsoft" + } + ], + "name": "Microsoft.Testing.Extensions.VSTestBridge", + "version": "2.0.2", + "description": "Microsoft Testing is a set of platform, framework and protocol intended to make it possible to run any test on any target or device.\n\nThis package provides a bridge integration for test adapters wanting to target both VSTest and Microsoft.Testing.Platform test platforms.", + "scope": "excluded", + "hashes": [ + { + "alg": "SHA-512", + "content": "F7CA49CE950F40122F86F9CEFEEB6467C2767DDE71EF060F9FB766A4501F5EE0CD2F7557E45EA96F4EB6A7B60214B17740DF6A976AD71DC0881D1CEB984F2C40" + } + ], + "licenses": [ + { + "license": { + "id": "MIT" + } + } + ], + "copyright": "\u00A9 Microsoft Corporation. All rights reserved.", + "purl": "pkg:nuget/Microsoft.Testing.Extensions.VSTestBridge@2.0.2", + "externalReferences": [ + { + "url": "https://github.com/microsoft/testfx", + "type": "website" + }, + { + "url": "https://github.com/microsoft/testfx", + "type": "vcs" + } + ] + }, + { + "type": "library", + "bom-ref": "pkg:nuget/Microsoft.Testing.Platform@2.0.2", + "authors": [ + { + "name": "Microsoft" + } + ], + "name": "Microsoft.Testing.Platform", + "version": "2.0.2", + "description": "Microsoft Testing is a set of platform, framework and protocol intended to make it possible to run any test on any target or device.\n\nThis package provides the core platform and the .NET implementation of the protocol.", + "scope": "excluded", + "hashes": [ + { + "alg": "SHA-512", + "content": "19AA3F0C4FAF774EFA1F3930422374A28D561517F4BFA1D512D95BA6800A322649105BFC523B584332A979C86F54E3F5B4285857EAB821AD8302E3CE2699FDEB" + } + ], + "licenses": [ + { + "license": { + "id": "MIT" + } + } + ], + "copyright": "\u00A9 Microsoft Corporation. All rights reserved.", + "purl": "pkg:nuget/Microsoft.Testing.Platform@2.0.2", + "externalReferences": [ + { + "url": "https://github.com/microsoft/testfx", + "type": "website" + }, + { + "url": "https://github.com/microsoft/testfx", + "type": "vcs" + } + ] + }, + { + "type": "library", + "bom-ref": "pkg:nuget/Microsoft.Testing.Platform.MSBuild@2.0.2", + "authors": [ + { + "name": "Microsoft" + } + ], + "name": "Microsoft.Testing.Platform.MSBuild", + "version": "2.0.2", + "description": "Microsoft Testing is a set of platform, framework and protocol intended to make it possible to run any test on any target or device.\n\nThis package provides MSBuild integration of the platform, its extensions and configuration files.", + "scope": "excluded", + "hashes": [ + { + "alg": "SHA-512", + "content": "5A854867DE4B2D0CDEE21AB09D3C838FF9447D4BB73F07DD62CE8A15C76017A1829BC20C8910C6A5B13547FA5083903258B239F98C7566ABA12669F52B26A343" + } + ], + "licenses": [ + { + "license": { + "id": "MIT" + } + } + ], + "copyright": "\u00A9 Microsoft Corporation. All rights reserved.", + "purl": "pkg:nuget/Microsoft.Testing.Platform.MSBuild@2.0.2", + "externalReferences": [ + { + "url": "https://github.com/microsoft/testfx", + "type": "website" + }, + { + "url": "https://github.com/microsoft/testfx", + "type": "vcs" + } + ] + }, + { + "type": "library", + "bom-ref": "pkg:nuget/Microsoft.TestPlatform.AdapterUtilities@18.0.1", + "authors": [ + { + "name": "Microsoft" + } + ], + "name": "Microsoft.TestPlatform.AdapterUtilities", + "version": "18.0.1", + "description": "Includes helpers for the Test Platform\u0027s modern functionality such as standardized fully qualified names and hierarchical test case names.", + "scope": "excluded", + "hashes": [ + { + "alg": "SHA-512", + "content": "570C23A2CB9B56E1FD58E4B06DD7A6B5B72A78AA738A12C43C6D27F043D68864384D56AC250DCF493FD02EA60A7CB1DAA9150C9FB585DDDEA5DFCD4546717439" + } + ], + "licenses": [ + { + "license": { + "id": "MIT" + } + } + ], + "copyright": "\u00A9 Microsoft Corporation. All rights reserved.", + "purl": "pkg:nuget/Microsoft.TestPlatform.AdapterUtilities@18.0.1", + "externalReferences": [ + { + "url": "https://github.com/microsoft/vstest", + "type": "website" + }, + { + "url": "https://github.com/microsoft/vstest", + "type": "vcs" + } + ] + }, + { + "type": "library", + "bom-ref": "pkg:nuget/Microsoft.TestPlatform.ObjectModel@18.0.1", + "authors": [ + { + "name": "Microsoft" + } + ], + "name": "Microsoft.TestPlatform.ObjectModel", + "version": "18.0.1", + "description": "The Microsoft Test Platform Object Model.", + "scope": "excluded", + "hashes": [ + { + "alg": "SHA-512", + "content": "A9929CB12E6637B18CC2DA5DFAD45F02DE039A0F3255BB56926F6219FA98D8634E1B6A96F79347EB37FF16B4CB5D3892EEB07BCEA8A158611C4ACA4E6922BC4D" + } + ], + "licenses": [ + { + "license": { + "id": "MIT" + } + } + ], + "copyright": "\u00A9 Microsoft Corporation. All rights reserved.", + "purl": "pkg:nuget/Microsoft.TestPlatform.ObjectModel@18.0.1", + "externalReferences": [ + { + "url": "https://github.com/microsoft/vstest", + "type": "website" + }, + { + "url": "https://github.com/microsoft/vstest", + "type": "vcs" + } + ] + }, + { + "type": "library", + "bom-ref": "pkg:nuget/Microsoft.TestPlatform.TestHost@18.0.1", + "authors": [ + { + "name": "Microsoft" + } + ], + "name": "Microsoft.TestPlatform.TestHost", + "version": "18.0.1", + "description": "Testplatform host executes the test using specified adapter.", + "scope": "excluded", + "hashes": [ + { + "alg": "SHA-512", + "content": "497D459D803CCDC36FFE56D62B71A32E7031F778DA966C87C903158BE4CD580EB547AC7390B30DA42DDFA2D6DFA4385E5C2161C32FF5ACAA142F268E39ED2312" + } + ], + "licenses": [ + { + "license": { + "id": "MIT" + } + } + ], + "copyright": "\u00A9 Microsoft Corporation. All rights reserved.", + "purl": "pkg:nuget/Microsoft.TestPlatform.TestHost@18.0.1", + "externalReferences": [ + { + "url": "https://github.com/microsoft/vstest", + "type": "website" + }, + { + "url": "https://github.com/microsoft/vstest", + "type": "vcs" + } + ] + }, + { + "type": "library", + "bom-ref": "pkg:nuget/MimeKit@4.14.0", + "authors": [ + { + "name": "Jeffrey Stedfast" + } + ], + "name": "MimeKit", + "version": "4.14.0", + "description": "An Open Source library for creating and parsing MIME, S/MIME and PGP messages on desktop and mobile platforms.", + "scope": "required", + "hashes": [ + { + "alg": "SHA-512", + "content": "CE8A26BFC40B3153C8C184D439EBE002FC0BE932287E57D801E7B77FCE13BA8A0BE4025B36CDBCA191114B2AA222C6AE0C513271191450B4D53325024A6BA9EF" + } + ], + "licenses": [ + { + "license": { + "id": "MIT" + } + } + ], + "copyright": ".NET Foundation and Contributors", + "purl": "pkg:nuget/MimeKit@4.14.0", + "externalReferences": [ + { + "url": "https://www.mimekit.net/", + "type": "website" + }, + { + "url": "https://github.com/jstedfast/MimeKit", + "type": "vcs" + } + ] + }, + { + "type": "library", + "bom-ref": "pkg:nuget/Moq@4.20.72", + "authors": [ + { + "name": "Daniel Cazzulino, kzu" + } + ], + "name": "Moq", + "version": "4.20.72", + "description": "Moq is the most popular and friendly mocking framework for .NET.", + "scope": "excluded", + "hashes": [ + { + "alg": "SHA-512", + "content": "1DE2DD00ACC57B61B87D483EB546B55917FF3327BDCDB922BF9EE31D149BE48562EC65D53E059B6C46943FC49A3A9B78DC9245465598F4DE58AE8DF6FED811A5" + } + ], + "licenses": [ + { + "license": { + "id": "BSD-3-Clause" + } + } + ], + "copyright": "Copyright (c) 2007, Clarius Consulting, Manas Technology Solutions, InSTEDD, and Contributors. All rights reserved.", + "purl": "pkg:nuget/Moq@4.20.72", + "externalReferences": [ + { + "url": "https://github.com/moq/moq", + "type": "website" + }, + { + "url": "https://github.com/moq/moq", + "type": "vcs" + } + ] + }, + { + "type": "library", + "bom-ref": "pkg:nuget/Newtonsoft.Json@13.0.3", + "authors": [ + { + "name": "James Newton-King" + } + ], + "name": "Newtonsoft.Json", + "version": "13.0.3", + "description": "Json.NET is a popular high-performance JSON framework for .NET", + "scope": "required", + "hashes": [ + { + "alg": "SHA-512", + "content": "99B252BC77D1C5F5F7B51FD4EA7D5653E9961D7B3061CF9207F8643A9C7CC9965EEBC84D6467F2989BB4723B1A244915CC232A78F894E8B748CA882A7C89FB92" + } + ], + "licenses": [ + { + "license": { + "id": "MIT" + } + } + ], + "copyright": "Copyright \u00A9 James Newton-King 2008", + "purl": "pkg:nuget/Newtonsoft.Json@13.0.3", + "externalReferences": [ + { + "url": "https://www.newtonsoft.com/json", + "type": "website" + }, + { + "url": "https://github.com/JamesNK/Newtonsoft.Json", + "type": "vcs" + } + ] + }, + { + "type": "library", + "bom-ref": "pkg:nuget/Novell.Directory.Ldap.NETStandard@4.0.0", + "authors": [ + { + "name": "Novell,dsbenghe" + } + ], + "name": "Novell.Directory.Ldap.NETStandard", + "version": "4.0.0", + "description": "LDAP client library - .NET Standard 2.0/2.1, - compatible .NET platforms: .NET \u003E= NET6, NET8, NET9, .NET Framework \u003E= 4.6, Universal Windows Platform, Xamarin. Works with any LDAP server (including Microsoft Active Directory - AD)", + "scope": "required", + "hashes": [ + { + "alg": "SHA-512", + "content": "CBA13A23E39B192DA58081C7052211A3695446D59C88D260D02DF01707ECBA214E934C5E36132722FDE03C62ED93952A37D48FA5A64A5FB182C29A29502F4DBF" + } + ], + "licenses": [ + { + "license": { + "id": "MIT" + } + } + ], + "purl": "pkg:nuget/Novell.Directory.Ldap.NETStandard@4.0.0", + "externalReferences": [ + { + "url": "https://github.com/dsbenghe/Novell.Directory.Ldap.NETStandard", + "type": "website" + } + ] + }, + { + "type": "library", + "bom-ref": "pkg:nuget/NSubstitute@5.3.0", + "authors": [ + { + "name": "Anthony Egerton,David Tchepak,Alexandr Nikitin,Oleksandr Povar" + } + ], + "name": "NSubstitute", + "version": "5.3.0", + "description": "NSubstitute is a friendly substitute for .NET mocking libraries. It has a simple, succinct syntax to help developers write clearer tests. NSubstitute is designed for Arrange-Act-Assert (AAA) testing and with Test Driven Development (TDD) in mind.", + "scope": "excluded", + "hashes": [ + { + "alg": "SHA-512", + "content": "4BD79C67F48E84FE44631B3A5F5E31E22B24FF83AC92FD0E7DD6AE319D89B2724240296F0CAEAA92A05E6012426D6269AE650CB25F95A6CB6E814225819888A0" + } + ], + "licenses": [ + { + "license": { + "id": "BSD-3-Clause" + } + } + ], + "purl": "pkg:nuget/NSubstitute@5.3.0", + "externalReferences": [ + { + "url": "https://nsubstitute.github.io/", + "type": "website" + }, + { + "url": "https://github.com/nsubstitute/NSubstitute", + "type": "vcs" + } + ] + }, + { + "type": "library", + "bom-ref": "pkg:nuget/NUnit@4.4.0", + "authors": [ + { + "name": "Charlie Poole, Rob Prouse" + } + ], + "name": "NUnit", + "version": "4.4.0", + "description": "NUnit is a unit-testing framework for all .NET languages with a strong TDD focus.", + "scope": "excluded", + "hashes": [ + { + "alg": "SHA-512", + "content": "6D98C0D40568E032E6D94DA9589F99518866DFE4653391FA4D22C114B5619B557845EA3367773357ABA429A3AB5EFC3209DEE43F549B9E41794173CDC668317C" + } + ], + "licenses": [ + { + "license": { + "id": "MIT" + } + } + ], + "copyright": "Copyright (c) Charlie Poole, Rob Prouse and Contributors. MIT License.", + "purl": "pkg:nuget/NUnit@4.4.0", + "externalReferences": [ + { + "url": "https://nunit.org/", + "type": "website" + }, + { + "url": "https://github.com/nunit/nunit", + "type": "vcs" + } + ] + }, + { + "type": "library", + "bom-ref": "pkg:nuget/NUnit3TestAdapter@6.1.0", + "authors": [ + { + "name": "Charlie Poole, Terje Sandstrom" + } + ], + "name": "NUnit3TestAdapter", + "version": "6.1.0", + "description": "NUnit3 adapter for running tests in Visual Studio and DotNet.", + "scope": "excluded", + "hashes": [ + { + "alg": "SHA-512", + "content": "882141F86459D65DB52066D0F7D004060426FA7718BC9CCE275B2DD98793C5182AE3A5E1591CCB805AD09C68F1F730F8C83BD61729D769772925405888416A07" + } + ], + "licenses": [ + { + "license": { + "id": "MIT" + } + } + ], + "copyright": "Copyright (c) 2011-2021 Charlie Poole, 2014-2026 Terje Sandstrom", + "purl": "pkg:nuget/NUnit3TestAdapter@6.1.0", + "externalReferences": [ + { + "url": "https://docs.nunit.org/articles/vs-test-adapter/Index.html", + "type": "website" + }, + { + "url": "https://github.com/nunit/nunit3-vs-adapter", + "type": "vcs" + } + ] + }, + { + "type": "library", + "bom-ref": "pkg:nuget/PuppeteerSharp@20.2.6", + "authors": [ + { + "name": "Dar\u00EDo Kondratiuk" + } + ], + "name": "PuppeteerSharp", + "version": "20.2.6", + "description": "Headless Browser .NET API", + "scope": "required", + "hashes": [ + { + "alg": "SHA-512", + "content": "DF989B75F559D9819B9082BF466BC550695A09C6DDD8A8D4F4C32ACEBAE52CFDF8E95A8349235702EBE1E1A41429DCA20F1724C6D6F0A28C75F7322B92850BBC" + } + ], + "licenses": [ + { + "license": { + "id": "MIT" + } + } + ], + "purl": "pkg:nuget/PuppeteerSharp@20.2.6", + "externalReferences": [ + { + "url": "https://github.com/hardkoded/puppeteer-sharp", + "type": "website" + }, + { + "url": "https://github.com/hardkoded/puppeteer-sharp", + "type": "vcs" + } + ] + }, + { + "type": "library", + "bom-ref": "pkg:nuget/Quartz@3.15.1", + "authors": [ + { + "name": "Marko Lahma, Quartz.NET" + } + ], + "name": "Quartz", + "version": "3.15.1", + "description": "Quartz Scheduling Framework for .NET", + "scope": "required", + "hashes": [ + { + "alg": "SHA-512", + "content": "3D4128FE217F584D2EC40E2276E5594604D12B51B876A407AE119B7FB2FC8DBF482AB567E136AFA7E471AFB49AD11CCD009928611B53909C93E45838EF274F72" + } + ], + "licenses": [ + { + "license": { + "id": "Apache-2.0" + } + } + ], + "copyright": "Copyright Marko Lahma", + "purl": "pkg:nuget/Quartz@3.15.1", + "externalReferences": [ + { + "url": "https://www.quartz-scheduler.net/", + "type": "website" + }, + { + "url": "https://github.com/quartznet/quartznet", + "type": "vcs" + } + ] + }, + { + "type": "library", + "bom-ref": "pkg:nuget/Quartz.Extensions.DependencyInjection@3.15.1", + "authors": [ + { + "name": "Facundo Glaeser, Marko Lahma, Quartz.NET" + } + ], + "name": "Quartz.Extensions.DependencyInjection", + "version": "3.15.1", + "description": "Quartz.NET Microsoft.Extensions.DependencyInjection integration; Quartz Scheduling Framework for .NET", + "scope": "required", + "hashes": [ + { + "alg": "SHA-512", + "content": "93ECE40AA160FB707CF99D6AE8AFBC1536660CBD4D7FD9907880CB6EB146271A2BC3D7D95923B5B3CD18541A9A38BBB7B186626450FC350D8FCDA033A5CDB9CB" + } + ], + "licenses": [ + { + "license": { + "id": "Apache-2.0" + } + } + ], + "copyright": "Copyright Marko Lahma", + "purl": "pkg:nuget/Quartz.Extensions.DependencyInjection@3.15.1", + "externalReferences": [ + { + "url": "https://www.quartz-scheduler.net/", + "type": "website" + }, + { + "url": "https://github.com/quartznet/quartznet", + "type": "vcs" + } + ] + }, + { + "type": "library", + "bom-ref": "pkg:nuget/Quartz.Extensions.Hosting@3.15.1", + "authors": [ + { + "name": "Andrew Lock, Marko Lahma, Quartz.NET" + } + ], + "name": "Quartz.Extensions.Hosting", + "version": "3.15.1", + "description": "Quartz.NET Generic Host integration; Quartz Scheduling Framework for .NET", + "scope": "required", + "hashes": [ + { + "alg": "SHA-512", + "content": "9DDF492BE837D6C38151C60D0CB9884D7D40DF5071C99FEB1176242EF0C5A5E15BB7F3AA4AC5329F02DCCE5198D1A8766ECD11F1DA8742318E4D1DF1B58FA517" + } + ], + "licenses": [ + { + "license": { + "id": "Apache-2.0" + } + } + ], + "copyright": "Copyright Marko Lahma", + "purl": "pkg:nuget/Quartz.Extensions.Hosting@3.15.1", + "externalReferences": [ + { + "url": "https://www.quartz-scheduler.net/", + "type": "website" + }, + { + "url": "https://github.com/quartznet/quartznet", + "type": "vcs" + } + ] + }, + { + "type": "library", + "bom-ref": "pkg:nuget/Quartz.Serialization.Json@3.15.1", + "authors": [ + { + "name": "Marko Lahma, Quartz.NET" + } + ], + "name": "Quartz.Serialization.Json", + "version": "3.15.1", + "description": "Quartz.NET JSON Serialization Support; Quartz Scheduling Framework for .NET", + "scope": "required", + "hashes": [ + { + "alg": "SHA-512", + "content": "B4B761742F805EE649B9781F221A5A118EAF460919C1DB2BEEAC757BCFF5DB795D56624CEBE645C2CB81A8A26B15118A701B4ED7B006D7393590A4D13660E1C2" + } + ], + "licenses": [ + { + "license": { + "id": "Apache-2.0" + } + } + ], + "copyright": "Copyright Marko Lahma", + "purl": "pkg:nuget/Quartz.Serialization.Json@3.15.1", + "externalReferences": [ + { + "url": "https://www.quartz-scheduler.net/", + "type": "website" + }, + { + "url": "https://github.com/quartznet/quartznet", + "type": "vcs" + } + ] + }, + { + "type": "library", + "bom-ref": "pkg:nuget/RestSharp@113.1.0", + "authors": [ + { + "name": ".NET Foundation and Contributors" + } + ], + "name": "RestSharp", + "version": "113.1.0", + "description": "Simple REST and HTTP API Client", + "scope": "required", + "hashes": [ + { + "alg": "SHA-512", + "content": "80DBA36F36D1348DA47D5F88BC9C33F465859C6FF6A6F44933EC6968669FE3B4D5CF05824C1028DD478160E4626394DEF9D23A3E0C9E89FE0AB610FAAEA57B0E" + } + ], + "licenses": [ + { + "license": { + "id": "Apache-2.0" + } + } + ], + "copyright": "Copyright \u00A9 .NET Foundation and Contributors 2026", + "purl": "pkg:nuget/RestSharp@113.1.0", + "externalReferences": [ + { + "url": "https://restsharp.dev/", + "type": "website" + }, + { + "url": "https://github.com/restsharp/RestSharp.git", + "type": "vcs" + } + ] + }, + { + "type": "library", + "bom-ref": "pkg:nuget/RestSharp.Serializers.NewtonsoftJson@113.1.0", + "authors": [ + { + "name": ".NET Foundation and Contributors" + } + ], + "name": "RestSharp.Serializers.NewtonsoftJson", + "version": "113.1.0", + "description": "Simple REST and HTTP API Client", + "scope": "required", + "hashes": [ + { + "alg": "SHA-512", + "content": "EDC5645B9EA8EA82C3FCB012A2C78442EA3B3DCF5A1F8B07215C10E437925131197AEAB8B56A6680ECC922F7BB45FF94EAF1643D2035FA6FE3109D383E526A46" + } + ], + "licenses": [ + { + "license": { + "id": "Apache-2.0" + } + } + ], + "copyright": "Copyright \u00A9 .NET Foundation and Contributors 2026", + "purl": "pkg:nuget/RestSharp.Serializers.NewtonsoftJson@113.1.0", + "externalReferences": [ + { + "url": "https://restsharp.dev/", + "type": "website" + }, + { + "url": "https://github.com/restsharp/RestSharp.git", + "type": "vcs" + } + ] + }, + { + "type": "library", + "bom-ref": "pkg:nuget/Swashbuckle.AspNetCore@10.1.1", + "authors": [ + { + "name": "domaindrivendev" + } + ], + "name": "Swashbuckle.AspNetCore", + "version": "10.1.1", + "description": "Swagger tools for documenting APIs built on ASP.NET Core", + "scope": "required", + "hashes": [ + { + "alg": "SHA-512", + "content": "0FD7F9D8EACA91845C47B109C0473F1A2A3F99A1826949F474F0B20AC7F335604C1A84E4F3C3D8CED6A942DEB58F72BFE4E0FE80541D1298A3596E08B787DAD3" + } + ], + "licenses": [ + { + "license": { + "id": "MIT" + } + } + ], + "purl": "pkg:nuget/Swashbuckle.AspNetCore@10.1.1", + "externalReferences": [ + { + "url": "https://github.com/domaindrivendev/Swashbuckle.AspNetCore", + "type": "website" + }, + { + "url": "https://github.com/domaindrivendev/Swashbuckle.AspNetCore.git", + "type": "vcs" + } + ] + }, + { + "type": "library", + "bom-ref": "pkg:nuget/Swashbuckle.AspNetCore.Swagger@10.1.1", + "authors": [ + { + "name": "domaindrivendev" + } + ], + "name": "Swashbuckle.AspNetCore.Swagger", + "version": "10.1.1", + "description": "Middleware to expose Swagger JSON endpoints from APIs built on ASP.NET Core", + "scope": "required", + "hashes": [ + { + "alg": "SHA-512", + "content": "843E3CA86B59600D5F1120D36DF3E1C9D0199A88EC5F8EC1297E66774581E28D552182C393C5EE9627B30BBD8F84B33D7FC1C36E462958D5266E4715B8DF6B05" + } + ], + "licenses": [ + { + "license": { + "id": "MIT" + } + } + ], + "copyright": "Copyright (c) 2016-2026 Richard Morris", + "purl": "pkg:nuget/Swashbuckle.AspNetCore.Swagger@10.1.1", + "externalReferences": [ + { + "url": "https://github.com/domaindrivendev/Swashbuckle.AspNetCore", + "type": "website" + }, + { + "url": "https://github.com/domaindrivendev/Swashbuckle.AspNetCore.git", + "type": "vcs" + } + ] + }, + { + "type": "library", + "bom-ref": "pkg:nuget/Swashbuckle.AspNetCore.SwaggerGen@10.1.1", + "authors": [ + { + "name": "domaindrivendev" + } + ], + "name": "Swashbuckle.AspNetCore.SwaggerGen", + "version": "10.1.1", + "description": "Swagger Generator for APIs built on ASP.NET Core", + "scope": "required", + "hashes": [ + { + "alg": "SHA-512", + "content": "B2A2E6609C759A237506EAC79C3AEED6394A632E81B8721B298668DD5D345903FC57C10675BD2D8167CE463D82071111AB3AFCB0D3644B0348CB142C7517CA39" + } + ], + "licenses": [ + { + "license": { + "id": "MIT" + } + } + ], + "copyright": "Copyright (c) 2016-2026 Richard Morris", + "purl": "pkg:nuget/Swashbuckle.AspNetCore.SwaggerGen@10.1.1", + "externalReferences": [ + { + "url": "https://github.com/domaindrivendev/Swashbuckle.AspNetCore", + "type": "website" + }, + { + "url": "https://github.com/domaindrivendev/Swashbuckle.AspNetCore.git", + "type": "vcs" + } + ] + }, + { + "type": "library", + "bom-ref": "pkg:nuget/Swashbuckle.AspNetCore.SwaggerUI@10.1.1", + "authors": [ + { + "name": "domaindrivendev" + } + ], + "name": "Swashbuckle.AspNetCore.SwaggerUI", + "version": "10.1.1", + "description": "Middleware to expose an embedded version of the swagger-ui from an ASP.NET Core application", + "scope": "required", + "hashes": [ + { + "alg": "SHA-512", + "content": "8A4021290B9701F9A218FFF032E7E9DB8E1D8DB2CAE93FFB67115ADAB471970180B930C6FE78EB47B36CB5F2E8F92A9D7CF0A0B1CB28C4A92BB67ED68FDF1C00" + } + ], + "licenses": [ + { + "license": { + "id": "MIT" + } + } + ], + "copyright": "Copyright (c) 2016-2026 Richard Morris", + "purl": "pkg:nuget/Swashbuckle.AspNetCore.SwaggerUI@10.1.1", + "externalReferences": [ + { + "url": "https://github.com/domaindrivendev/Swashbuckle.AspNetCore", + "type": "website" + }, + { + "url": "https://github.com/domaindrivendev/Swashbuckle.AspNetCore.git", + "type": "vcs" + } + ] + }, + { + "type": "library", + "bom-ref": "pkg:nuget/System.Diagnostics.EventLog@6.0.0", + "authors": [ + { + "name": "Microsoft" + } + ], + "name": "System.Diagnostics.EventLog", + "version": "6.0.0", + "description": "Provides the System.Diagnostics.EventLog class, which allows the applications to use the windows event log service.\n\nCommonly Used Types:\nSystem.Diagnostics.EventLog", + "scope": "excluded", + "hashes": [ + { + "alg": "SHA-512", + "content": "40103D5B7CB2B41C7CAFCA629C112C5526BB773D11367CA62918D8864FBA8DAC2B48151F37671BCF50499D8F8B268489EE1CADE2FB8947CC06E205A1FAC6784C" + } + ], + "licenses": [ + { + "license": { + "id": "MIT" + } + } + ], + "copyright": "\u00A9 Microsoft Corporation. All rights reserved.", + "purl": "pkg:nuget/System.Diagnostics.EventLog@6.0.0", + "externalReferences": [ + { + "url": "https://dot.net/", + "type": "website" + }, + { + "url": "https://github.com/dotnet/runtime", + "type": "vcs" + } + ] + }, + { + "type": "library", + "bom-ref": "pkg:nuget/System.IdentityModel.Tokens.Jwt@8.15.0", + "authors": [ + { + "name": "Microsoft" + } + ], + "name": "System.IdentityModel.Tokens.Jwt", + "version": "8.15.0", + "description": "Includes types that provide support for creating, serializing and validating JSON Web Tokens. As of IdentityModel 7x, this is a legacy tool that should be replaced with Microsoft.IdentityModel.JsonWebTokens.", + "scope": "required", + "hashes": [ + { + "alg": "SHA-512", + "content": "BC4C29F7816BE381A90116602535B19DB1486CA23746FD4B2FB3AAB437186DD2E9AEF17C49CB1B2EE9F3F49C542504F092D99BD7541307BBE3C178A25E8C582B" + } + ], + "licenses": [ + { + "license": { + "id": "MIT" + } + } + ], + "copyright": "\u00A9 Microsoft Corporation. All rights reserved.", + "purl": "pkg:nuget/System.IdentityModel.Tokens.Jwt@8.15.0", + "externalReferences": [ + { + "url": "https://github.com/AzureAD/azure-activedirectory-identitymodel-extensions-for-dotnet", + "type": "website" + }, + { + "url": "https://github.com/AzureAD/azure-activedirectory-identitymodel-extensions-for-dotnet", + "type": "vcs" + } + ] + }, + { + "type": "library", + "bom-ref": "pkg:nuget/System.Reactive@6.0.0", + "authors": [ + { + "name": ".NET Foundation and Contributors" + } + ], + "name": "System.Reactive", + "version": "6.0.0", + "description": "Reactive Extensions (Rx) for .NET", + "scope": "required", + "hashes": [ + { + "alg": "SHA-512", + "content": "9303EA0EFE2B4B1782BBEB87CE88469E7DBDE14AD441F153D2D79A518F7FE8AEC76F6407D69B726A0383F1F272232C833FD79421F7BA56DFDA110F45DEB48B72" + } + ], + "licenses": [ + { + "license": { + "id": "MIT" + } + } + ], + "copyright": "Copyright (c) .NET Foundation and Contributors.", + "purl": "pkg:nuget/System.Reactive@6.0.0", + "externalReferences": [ + { + "url": "https://github.com/dotnet/reactive", + "type": "website" + }, + { + "url": "https://github.com/dotnet/reactive", + "type": "vcs" + } + ] + }, + { + "type": "library", + "bom-ref": "pkg:nuget/System.Security.Cryptography.Pkcs@8.0.1", + "authors": [ + { + "name": "Microsoft" + } + ], + "name": "System.Security.Cryptography.Pkcs", + "version": "8.0.1", + "description": "Provides support for PKCS and CMS algorithms.\n\nCommonly Used Types:\nSystem.Security.Cryptography.Pkcs.EnvelopedCms", + "scope": "required", + "hashes": [ + { + "alg": "SHA-512", + "content": "31B0606701DCE4008B189DBC0BCFA0D855A2DEB2EC83A3D3150D81DB001955F81B6D1BFC30FAD953E75C5704B478830006BA81C7B84BDF9A50E8241055CA6450" + } + ], + "licenses": [ + { + "license": { + "id": "MIT" + } + } + ], + "copyright": "\u00A9 Microsoft Corporation. All rights reserved.", + "purl": "pkg:nuget/System.Security.Cryptography.Pkcs@8.0.1", + "externalReferences": [ + { + "url": "https://dot.net/", + "type": "website" + }, + { + "url": "https://github.com/dotnet/runtime", + "type": "vcs" + } + ] + } + ], + "dependencies": [ + { + "ref": "FWO@0.0.0", + "dependsOn": [ + "pkg:nuget/DnsClient@1.8.0", + "pkg:nuget/GraphQL.Client@6.1.0", + "pkg:nuget/GraphQL.Client.Serializer.Newtonsoft@6.1.0", + "pkg:nuget/GraphQL.Client.Serializer.SystemTextJson@6.1.0", + "pkg:nuget/IPAddressRange@6.3.0", + "pkg:nuget/IPNetwork2@3.4.853", + "pkg:nuget/Microsoft.AspNetCore.Components@10.0.2", + "pkg:nuget/Microsoft.IdentityModel.Tokens@8.15.0", + "pkg:nuget/Microsoft.Rest.ClientRuntime@2.3.24", + "pkg:nuget/RestSharp@113.1.0", + "pkg:nuget/RestSharp.Serializers.NewtonsoftJson@113.1.0", + "pkg:nuget/System.IdentityModel.Tokens.Jwt@8.15.0", + "pkg:nuget/HtmlAgilityPack@1.12.4", + "pkg:nuget/MailKit@4.14.1", + "pkg:nuget/Microsoft.AspNetCore.Http@2.3.9", + "pkg:nuget/MimeKit@4.14.0", + "pkg:nuget/PuppeteerSharp@20.2.6", + "pkg:nuget/Microsoft.AspNetCore.Authentication.JwtBearer@10.0.2", + "pkg:nuget/Novell.Directory.Ldap.NETStandard@4.0.0", + "pkg:nuget/Quartz@3.15.1", + "pkg:nuget/Quartz.Extensions.Hosting@3.15.1", + "pkg:nuget/Quartz.Serialization.Json@3.15.1", + "pkg:nuget/Swashbuckle.AspNetCore@10.1.1", + "pkg:nuget/BlazorTable@1.17.0", + "pkg:nuget/Microsoft.AspNetCore.App.Internal.Assets@10.0.3", + "pkg:nuget/bunit@2.5.3", + "pkg:nuget/Microsoft.NET.Test.Sdk@18.0.1", + "pkg:nuget/Moq@4.20.72", + "pkg:nuget/NSubstitute@5.3.0", + "pkg:nuget/NUnit@4.4.0", + "pkg:nuget/NUnit3TestAdapter@6.1.0" + ] + }, + { + "ref": "pkg:nuget/AngleSharp.Css@1.0.0-beta.157", + "dependsOn": [ + "pkg:nuget/AngleSharp@1.4.0" + ] + }, + { + "ref": "pkg:nuget/AngleSharp.Diffing@1.1.1", + "dependsOn": [ + "pkg:nuget/AngleSharp@1.4.0", + "pkg:nuget/AngleSharp.Css@1.0.0-beta.157" + ] + }, + { + "ref": "pkg:nuget/AngleSharp@1.4.0", + "dependsOn": [] + }, + { + "ref": "pkg:nuget/BlazorTable@1.17.0", + "dependsOn": [] + }, + { + "ref": "pkg:nuget/BouncyCastle.Cryptography@2.6.1", + "dependsOn": [] + }, + { + "ref": "pkg:nuget/bunit@2.5.3", + "dependsOn": [ + "pkg:nuget/AngleSharp@1.4.0", + "pkg:nuget/AngleSharp.Css@1.0.0-beta.157", + "pkg:nuget/AngleSharp.Diffing@1.1.1", + "pkg:nuget/Microsoft.AspNetCore.Components@10.0.2", + "pkg:nuget/Microsoft.AspNetCore.Components.Authorization@10.0.0", + "pkg:nuget/Microsoft.AspNetCore.Components.Web@10.0.0", + "pkg:nuget/Microsoft.AspNetCore.Components.WebAssembly@10.0.0", + "pkg:nuget/Microsoft.AspNetCore.Components.WebAssembly.Authentication@10.0.0", + "pkg:nuget/Microsoft.Extensions.Caching.Memory@10.0.0", + "pkg:nuget/Microsoft.Extensions.Localization.Abstractions@10.0.0", + "pkg:nuget/Microsoft.Extensions.Logging@10.0.0", + "pkg:nuget/Microsoft.Extensions.Logging.Abstractions@10.0.2" + ] + }, + { + "ref": "pkg:nuget/Castle.Core@5.1.1", + "dependsOn": [ + "pkg:nuget/System.Diagnostics.EventLog@6.0.0" + ] + }, + { + "ref": "pkg:nuget/DnsClient@1.8.0", + "dependsOn": [] + }, + { + "ref": "pkg:nuget/GraphQL.Client.Abstractions.Websocket@6.1.0", + "dependsOn": [ + "pkg:nuget/GraphQL.Client.Abstractions@6.1.0" + ] + }, + { + "ref": "pkg:nuget/GraphQL.Client.Abstractions@6.1.0", + "dependsOn": [ + "pkg:nuget/GraphQL.Primitives@6.1.0" + ] + }, + { + "ref": "pkg:nuget/GraphQL.Client.Serializer.Newtonsoft@6.1.0", + "dependsOn": [ + "pkg:nuget/GraphQL.Client.Abstractions.Websocket@6.1.0", + "pkg:nuget/Newtonsoft.Json@13.0.3" + ] + }, + { + "ref": "pkg:nuget/GraphQL.Client.Serializer.SystemTextJson@6.1.0", + "dependsOn": [ + "pkg:nuget/GraphQL.Client.Abstractions.Websocket@6.1.0" + ] + }, + { + "ref": "pkg:nuget/GraphQL.Client@6.1.0", + "dependsOn": [ + "pkg:nuget/GraphQL.Client.Abstractions@6.1.0", + "pkg:nuget/GraphQL.Client.Abstractions.Websocket@6.1.0", + "pkg:nuget/System.Reactive@6.0.0" + ] + }, + { + "ref": "pkg:nuget/GraphQL.Primitives@6.1.0", + "dependsOn": [] + }, + { + "ref": "pkg:nuget/HtmlAgilityPack@1.12.4", + "dependsOn": [] + }, + { + "ref": "pkg:nuget/IPAddressRange@6.3.0", + "dependsOn": [] + }, + { + "ref": "pkg:nuget/IPNetwork2@3.4.853", + "dependsOn": [] + }, + { + "ref": "pkg:nuget/LinqKit.Core@1.1.26", + "dependsOn": [] + }, + { + "ref": "pkg:nuget/MailKit@4.14.1", + "dependsOn": [ + "pkg:nuget/MimeKit@4.14.0" + ] + }, + { + "ref": "pkg:nuget/Microsoft.ApplicationInsights@2.23.0", + "dependsOn": [] + }, + { + "ref": "pkg:nuget/Microsoft.AspNetCore.App.Internal.Assets@10.0.3", + "dependsOn": [] + }, + { + "ref": "pkg:nuget/Microsoft.AspNetCore.Authentication.JwtBearer@10.0.2", + "dependsOn": [ + "pkg:nuget/Microsoft.IdentityModel.Protocols.OpenIdConnect@8.0.1" + ] + }, + { + "ref": "pkg:nuget/Microsoft.AspNetCore.Authorization@10.0.2", + "dependsOn": [ + "pkg:nuget/Microsoft.AspNetCore.Metadata@10.0.2", + "pkg:nuget/Microsoft.Extensions.Diagnostics@10.0.2", + "pkg:nuget/Microsoft.Extensions.Logging.Abstractions@10.0.2", + "pkg:nuget/Microsoft.Extensions.Options@10.0.2" + ] + }, + { + "ref": "pkg:nuget/Microsoft.AspNetCore.Components.Analyzers@10.0.2", + "dependsOn": [] + }, + { + "ref": "pkg:nuget/Microsoft.AspNetCore.Components.Authorization@10.0.0", + "dependsOn": [ + "pkg:nuget/Microsoft.AspNetCore.Authorization@10.0.2", + "pkg:nuget/Microsoft.AspNetCore.Components@10.0.2" + ] + }, + { + "ref": "pkg:nuget/Microsoft.AspNetCore.Components.Forms@10.0.0", + "dependsOn": [ + "pkg:nuget/Microsoft.AspNetCore.Components@10.0.2", + "pkg:nuget/Microsoft.Extensions.Validation@10.0.0" + ] + }, + { + "ref": "pkg:nuget/Microsoft.AspNetCore.Components.Web@10.0.0", + "dependsOn": [ + "pkg:nuget/Microsoft.AspNetCore.Components@10.0.2", + "pkg:nuget/Microsoft.AspNetCore.Components.Forms@10.0.0", + "pkg:nuget/Microsoft.Extensions.DependencyInjection@10.0.0", + "pkg:nuget/Microsoft.Extensions.Primitives@10.0.2", + "pkg:nuget/Microsoft.JSInterop@10.0.0" + ] + }, + { + "ref": "pkg:nuget/Microsoft.AspNetCore.Components.WebAssembly.Authentication@10.0.0", + "dependsOn": [ + "pkg:nuget/Microsoft.AspNetCore.Components.Authorization@10.0.0", + "pkg:nuget/Microsoft.AspNetCore.Components.Web@10.0.0" + ] + }, + { + "ref": "pkg:nuget/Microsoft.AspNetCore.Components.WebAssembly@10.0.0", + "dependsOn": [ + "pkg:nuget/Microsoft.AspNetCore.Components.Web@10.0.0", + "pkg:nuget/Microsoft.Extensions.Configuration.Binder@10.0.2", + "pkg:nuget/Microsoft.Extensions.Configuration.Json@10.0.0", + "pkg:nuget/Microsoft.Extensions.Logging@10.0.0", + "pkg:nuget/Microsoft.JSInterop.WebAssembly@10.0.0" + ] + }, + { + "ref": "pkg:nuget/Microsoft.AspNetCore.Components@10.0.2", + "dependsOn": [ + "pkg:nuget/Microsoft.AspNetCore.Authorization@10.0.2", + "pkg:nuget/Microsoft.AspNetCore.Components.Analyzers@10.0.2" + ] + }, + { + "ref": "pkg:nuget/Microsoft.AspNetCore.Http.Abstractions@2.3.0", + "dependsOn": [ + "pkg:nuget/Microsoft.AspNetCore.Http.Features@2.3.0" + ] + }, + { + "ref": "pkg:nuget/Microsoft.AspNetCore.Http.Features@2.3.0", + "dependsOn": [ + "pkg:nuget/Microsoft.Extensions.Primitives@10.0.2" + ] + }, + { + "ref": "pkg:nuget/Microsoft.AspNetCore.Http@2.3.9", + "dependsOn": [ + "pkg:nuget/Microsoft.AspNetCore.Http.Abstractions@2.3.0", + "pkg:nuget/Microsoft.AspNetCore.WebUtilities@2.3.0", + "pkg:nuget/Microsoft.Extensions.ObjectPool@8.0.11", + "pkg:nuget/Microsoft.Extensions.Options@10.0.2", + "pkg:nuget/Microsoft.Net.Http.Headers@2.3.8" + ] + }, + { + "ref": "pkg:nuget/Microsoft.AspNetCore.Metadata@10.0.2", + "dependsOn": [] + }, + { + "ref": "pkg:nuget/Microsoft.AspNetCore.WebUtilities@2.3.0", + "dependsOn": [ + "pkg:nuget/Microsoft.Net.Http.Headers@2.3.8" + ] + }, + { + "ref": "pkg:nuget/Microsoft.CodeCoverage@18.0.1", + "dependsOn": [] + }, + { + "ref": "pkg:nuget/Microsoft.Extensions.ApiDescription.Server@10.0.0", + "dependsOn": [] + }, + { + "ref": "pkg:nuget/Microsoft.Extensions.Caching.Abstractions@10.0.0", + "dependsOn": [ + "pkg:nuget/Microsoft.Extensions.Primitives@10.0.2" + ] + }, + { + "ref": "pkg:nuget/Microsoft.Extensions.Caching.Memory@10.0.0", + "dependsOn": [ + "pkg:nuget/Microsoft.Extensions.Caching.Abstractions@10.0.0", + "pkg:nuget/Microsoft.Extensions.DependencyInjection.Abstractions@10.0.2", + "pkg:nuget/Microsoft.Extensions.Logging.Abstractions@10.0.2", + "pkg:nuget/Microsoft.Extensions.Options@10.0.2", + "pkg:nuget/Microsoft.Extensions.Primitives@10.0.2" + ] + }, + { + "ref": "pkg:nuget/Microsoft.Extensions.Configuration.Abstractions@10.0.2", + "dependsOn": [ + "pkg:nuget/Microsoft.Extensions.Primitives@10.0.2" + ] + }, + { + "ref": "pkg:nuget/Microsoft.Extensions.Configuration.Binder@10.0.2", + "dependsOn": [ + "pkg:nuget/Microsoft.Extensions.Configuration@10.0.2", + "pkg:nuget/Microsoft.Extensions.Configuration.Abstractions@10.0.2" + ] + }, + { + "ref": "pkg:nuget/Microsoft.Extensions.Configuration.FileExtensions@10.0.0", + "dependsOn": [ + "pkg:nuget/Microsoft.Extensions.Configuration@10.0.2", + "pkg:nuget/Microsoft.Extensions.Configuration.Abstractions@10.0.2", + "pkg:nuget/Microsoft.Extensions.FileProviders.Abstractions@10.0.0", + "pkg:nuget/Microsoft.Extensions.FileProviders.Physical@10.0.0", + "pkg:nuget/Microsoft.Extensions.Primitives@10.0.2" + ] + }, + { + "ref": "pkg:nuget/Microsoft.Extensions.Configuration.Json@10.0.0", + "dependsOn": [ + "pkg:nuget/Microsoft.Extensions.Configuration@10.0.2", + "pkg:nuget/Microsoft.Extensions.Configuration.Abstractions@10.0.2", + "pkg:nuget/Microsoft.Extensions.Configuration.FileExtensions@10.0.0", + "pkg:nuget/Microsoft.Extensions.FileProviders.Abstractions@10.0.0" + ] + }, + { + "ref": "pkg:nuget/Microsoft.Extensions.Configuration@10.0.2", + "dependsOn": [ + "pkg:nuget/Microsoft.Extensions.Configuration.Abstractions@10.0.2", + "pkg:nuget/Microsoft.Extensions.Primitives@10.0.2" + ] + }, + { + "ref": "pkg:nuget/Microsoft.Extensions.DependencyInjection.Abstractions@10.0.0", + "dependsOn": [] + }, + { + "ref": "pkg:nuget/Microsoft.Extensions.DependencyInjection.Abstractions@10.0.2", + "dependsOn": [] + }, + { + "ref": "pkg:nuget/Microsoft.Extensions.DependencyInjection.Abstractions@8.0.0", + "dependsOn": [] + }, + { + "ref": "pkg:nuget/Microsoft.Extensions.DependencyInjection@10.0.0", + "dependsOn": [ + "pkg:nuget/Microsoft.Extensions.DependencyInjection.Abstractions@10.0.2" + ] + }, + { + "ref": "pkg:nuget/Microsoft.Extensions.DependencyInjection@8.0.0", + "dependsOn": [ + "pkg:nuget/Microsoft.Extensions.DependencyInjection.Abstractions@10.0.2" + ] + }, + { + "ref": "pkg:nuget/Microsoft.Extensions.Diagnostics.Abstractions@10.0.2", + "dependsOn": [ + "pkg:nuget/Microsoft.Extensions.DependencyInjection.Abstractions@10.0.2", + "pkg:nuget/Microsoft.Extensions.Options@10.0.2" + ] + }, + { + "ref": "pkg:nuget/Microsoft.Extensions.Diagnostics@10.0.2", + "dependsOn": [ + "pkg:nuget/Microsoft.Extensions.Configuration@10.0.2", + "pkg:nuget/Microsoft.Extensions.Diagnostics.Abstractions@10.0.2", + "pkg:nuget/Microsoft.Extensions.Options.ConfigurationExtensions@10.0.2" + ] + }, + { + "ref": "pkg:nuget/Microsoft.Extensions.FileProviders.Abstractions@10.0.0", + "dependsOn": [ + "pkg:nuget/Microsoft.Extensions.Primitives@10.0.2" + ] + }, + { + "ref": "pkg:nuget/Microsoft.Extensions.FileProviders.Physical@10.0.0", + "dependsOn": [ + "pkg:nuget/Microsoft.Extensions.FileProviders.Abstractions@10.0.0", + "pkg:nuget/Microsoft.Extensions.FileSystemGlobbing@10.0.0", + "pkg:nuget/Microsoft.Extensions.Primitives@10.0.2" + ] + }, + { + "ref": "pkg:nuget/Microsoft.Extensions.FileSystemGlobbing@10.0.0", + "dependsOn": [] + }, + { + "ref": "pkg:nuget/Microsoft.Extensions.Hosting.Abstractions@9.0.0", + "dependsOn": [ + "pkg:nuget/Microsoft.Extensions.Configuration.Abstractions@10.0.2", + "pkg:nuget/Microsoft.Extensions.DependencyInjection.Abstractions@10.0.2", + "pkg:nuget/Microsoft.Extensions.Diagnostics.Abstractions@10.0.2", + "pkg:nuget/Microsoft.Extensions.FileProviders.Abstractions@10.0.0", + "pkg:nuget/Microsoft.Extensions.Logging.Abstractions@10.0.2" + ] + }, + { + "ref": "pkg:nuget/Microsoft.Extensions.Localization.Abstractions@10.0.0", + "dependsOn": [] + }, + { + "ref": "pkg:nuget/Microsoft.Extensions.Localization@3.1.18", + "dependsOn": [ + "pkg:nuget/Microsoft.Extensions.DependencyInjection.Abstractions@10.0.2", + "pkg:nuget/Microsoft.Extensions.Localization.Abstractions@10.0.0", + "pkg:nuget/Microsoft.Extensions.Logging.Abstractions@10.0.2", + "pkg:nuget/Microsoft.Extensions.Options@10.0.2" + ] + }, + { + "ref": "pkg:nuget/Microsoft.Extensions.Logging.Abstractions@10.0.0", + "dependsOn": [ + "pkg:nuget/Microsoft.Extensions.DependencyInjection.Abstractions@10.0.0" + ] + }, + { + "ref": "pkg:nuget/Microsoft.Extensions.Logging.Abstractions@10.0.2", + "dependsOn": [ + "pkg:nuget/Microsoft.Extensions.DependencyInjection.Abstractions@10.0.2" + ] + }, + { + "ref": "pkg:nuget/Microsoft.Extensions.Logging@10.0.0", + "dependsOn": [ + "pkg:nuget/Microsoft.Extensions.DependencyInjection@10.0.0", + "pkg:nuget/Microsoft.Extensions.Logging.Abstractions@10.0.2", + "pkg:nuget/Microsoft.Extensions.Options@10.0.2" + ] + }, + { + "ref": "pkg:nuget/Microsoft.Extensions.Logging@8.0.0", + "dependsOn": [ + "pkg:nuget/Microsoft.Extensions.DependencyInjection@8.0.0", + "pkg:nuget/Microsoft.Extensions.Logging.Abstractions@10.0.2", + "pkg:nuget/Microsoft.Extensions.Options@10.0.2" + ] + }, + { + "ref": "pkg:nuget/Microsoft.Extensions.ObjectPool@8.0.11", + "dependsOn": [] + }, + { + "ref": "pkg:nuget/Microsoft.Extensions.Options.ConfigurationExtensions@10.0.2", + "dependsOn": [ + "pkg:nuget/Microsoft.Extensions.Configuration.Abstractions@10.0.2", + "pkg:nuget/Microsoft.Extensions.Configuration.Binder@10.0.2", + "pkg:nuget/Microsoft.Extensions.DependencyInjection.Abstractions@10.0.2", + "pkg:nuget/Microsoft.Extensions.Options@10.0.2", + "pkg:nuget/Microsoft.Extensions.Primitives@10.0.2" + ] + }, + { + "ref": "pkg:nuget/Microsoft.Extensions.Options@10.0.2", + "dependsOn": [ + "pkg:nuget/Microsoft.Extensions.DependencyInjection.Abstractions@10.0.2", + "pkg:nuget/Microsoft.Extensions.Primitives@10.0.2" + ] + }, + { + "ref": "pkg:nuget/Microsoft.Extensions.Options@8.0.2", + "dependsOn": [ + "pkg:nuget/Microsoft.Extensions.DependencyInjection.Abstractions@8.0.0", + "pkg:nuget/Microsoft.Extensions.Primitives@8.0.0" + ] + }, + { + "ref": "pkg:nuget/Microsoft.Extensions.Primitives@10.0.2", + "dependsOn": [] + }, + { + "ref": "pkg:nuget/Microsoft.Extensions.Primitives@8.0.0", + "dependsOn": [] + }, + { + "ref": "pkg:nuget/Microsoft.Extensions.Validation@10.0.0", + "dependsOn": [ + "pkg:nuget/Microsoft.Extensions.DependencyInjection.Abstractions@10.0.2", + "pkg:nuget/Microsoft.Extensions.Options@10.0.2" + ] + }, + { + "ref": "pkg:nuget/Microsoft.IdentityModel.Abstractions@8.15.0", + "dependsOn": [] + }, + { + "ref": "pkg:nuget/Microsoft.IdentityModel.JsonWebTokens@8.15.0", + "dependsOn": [ + "pkg:nuget/Microsoft.IdentityModel.Tokens@8.15.0" + ] + }, + { + "ref": "pkg:nuget/Microsoft.IdentityModel.Logging@8.15.0", + "dependsOn": [ + "pkg:nuget/Microsoft.IdentityModel.Abstractions@8.15.0" + ] + }, + { + "ref": "pkg:nuget/Microsoft.IdentityModel.Protocols.OpenIdConnect@8.0.1", + "dependsOn": [ + "pkg:nuget/Microsoft.IdentityModel.Protocols@8.0.1", + "pkg:nuget/System.IdentityModel.Tokens.Jwt@8.15.0" + ] + }, + { + "ref": "pkg:nuget/Microsoft.IdentityModel.Protocols@8.0.1", + "dependsOn": [ + "pkg:nuget/Microsoft.IdentityModel.Tokens@8.15.0" + ] + }, + { + "ref": "pkg:nuget/Microsoft.IdentityModel.Tokens@8.15.0", + "dependsOn": [ + "pkg:nuget/Microsoft.Extensions.Logging.Abstractions@10.0.2", + "pkg:nuget/Microsoft.IdentityModel.Logging@8.15.0" + ] + }, + { + "ref": "pkg:nuget/Microsoft.JSInterop.WebAssembly@10.0.0", + "dependsOn": [ + "pkg:nuget/Microsoft.JSInterop@10.0.0" + ] + }, + { + "ref": "pkg:nuget/Microsoft.JSInterop@10.0.0", + "dependsOn": [] + }, + { + "ref": "pkg:nuget/Microsoft.Net.Http.Headers@2.3.8", + "dependsOn": [ + "pkg:nuget/Microsoft.Extensions.Primitives@10.0.2" + ] + }, + { + "ref": "pkg:nuget/Microsoft.NET.Test.Sdk@18.0.1", + "dependsOn": [ + "pkg:nuget/Microsoft.CodeCoverage@18.0.1", + "pkg:nuget/Microsoft.TestPlatform.TestHost@18.0.1" + ] + }, + { + "ref": "pkg:nuget/Microsoft.OpenApi@2.4.1", + "dependsOn": [] + }, + { + "ref": "pkg:nuget/Microsoft.Rest.ClientRuntime@2.3.24", + "dependsOn": [ + "pkg:nuget/Newtonsoft.Json@13.0.3" + ] + }, + { + "ref": "pkg:nuget/Microsoft.Testing.Extensions.Telemetry@2.0.2", + "dependsOn": [ + "pkg:nuget/Microsoft.ApplicationInsights@2.23.0", + "pkg:nuget/Microsoft.Testing.Platform@2.0.2" + ] + }, + { + "ref": "pkg:nuget/Microsoft.Testing.Extensions.TrxReport.Abstractions@2.0.2", + "dependsOn": [ + "pkg:nuget/Microsoft.Testing.Platform@2.0.2" + ] + }, + { + "ref": "pkg:nuget/Microsoft.Testing.Extensions.VSTestBridge@2.0.2", + "dependsOn": [ + "pkg:nuget/Microsoft.TestPlatform.AdapterUtilities@18.0.1", + "pkg:nuget/Microsoft.TestPlatform.ObjectModel@18.0.1", + "pkg:nuget/Microsoft.Testing.Extensions.Telemetry@2.0.2", + "pkg:nuget/Microsoft.Testing.Extensions.TrxReport.Abstractions@2.0.2", + "pkg:nuget/Microsoft.Testing.Platform@2.0.2" + ] + }, + { + "ref": "pkg:nuget/Microsoft.Testing.Platform.MSBuild@2.0.2", + "dependsOn": [ + "pkg:nuget/Microsoft.Testing.Platform@2.0.2" + ] + }, + { + "ref": "pkg:nuget/Microsoft.Testing.Platform@2.0.2", + "dependsOn": [] + }, + { + "ref": "pkg:nuget/Microsoft.TestPlatform.AdapterUtilities@18.0.1", + "dependsOn": [] + }, + { + "ref": "pkg:nuget/Microsoft.TestPlatform.ObjectModel@18.0.1", + "dependsOn": [] + }, + { + "ref": "pkg:nuget/Microsoft.TestPlatform.TestHost@18.0.1", + "dependsOn": [ + "pkg:nuget/Microsoft.TestPlatform.ObjectModel@18.0.1", + "pkg:nuget/Newtonsoft.Json@13.0.3" + ] + }, + { + "ref": "pkg:nuget/MimeKit@4.14.0", + "dependsOn": [ + "pkg:nuget/BouncyCastle.Cryptography@2.6.1", + "pkg:nuget/System.Security.Cryptography.Pkcs@8.0.1" + ] + }, + { + "ref": "pkg:nuget/Moq@4.20.72", + "dependsOn": [ + "pkg:nuget/Castle.Core@5.1.1" + ] + }, + { + "ref": "pkg:nuget/Newtonsoft.Json@13.0.3", + "dependsOn": [] + }, + { + "ref": "pkg:nuget/Novell.Directory.Ldap.NETStandard@4.0.0", + "dependsOn": [] + }, + { + "ref": "pkg:nuget/NSubstitute@5.3.0", + "dependsOn": [ + "pkg:nuget/Castle.Core@5.1.1" + ] + }, + { + "ref": "pkg:nuget/NUnit@4.4.0", + "dependsOn": [] + }, + { + "ref": "pkg:nuget/NUnit3TestAdapter@6.1.0", + "dependsOn": [ + "pkg:nuget/Microsoft.Testing.Extensions.VSTestBridge@2.0.2", + "pkg:nuget/Microsoft.Testing.Platform.MSBuild@2.0.2" + ] + }, + { + "ref": "pkg:nuget/PuppeteerSharp@20.2.6", + "dependsOn": [ + "pkg:nuget/Microsoft.Extensions.Logging@8.0.0" + ] + }, + { + "ref": "pkg:nuget/Quartz.Extensions.DependencyInjection@3.15.1", + "dependsOn": [ + "pkg:nuget/Quartz@3.15.1" + ] + }, + { + "ref": "pkg:nuget/Quartz.Extensions.Hosting@3.15.1", + "dependsOn": [ + "pkg:nuget/Quartz.Extensions.DependencyInjection@3.15.1" + ] + }, + { + "ref": "pkg:nuget/Quartz.Serialization.Json@3.15.1", + "dependsOn": [ + "pkg:nuget/Newtonsoft.Json@13.0.3", + "pkg:nuget/Quartz@3.15.1" + ] + }, + { + "ref": "pkg:nuget/Quartz@3.15.1", + "dependsOn": [] + }, + { + "ref": "pkg:nuget/RestSharp.Serializers.NewtonsoftJson@113.1.0", + "dependsOn": [ + "pkg:nuget/Newtonsoft.Json@13.0.3", + "pkg:nuget/RestSharp@113.1.0" + ] + }, + { + "ref": "pkg:nuget/RestSharp@113.1.0", + "dependsOn": [] + }, + { + "ref": "pkg:nuget/Swashbuckle.AspNetCore.Swagger@10.1.1", + "dependsOn": [ + "pkg:nuget/Microsoft.OpenApi@2.4.1" + ] + }, + { + "ref": "pkg:nuget/Swashbuckle.AspNetCore.SwaggerGen@10.1.1", + "dependsOn": [ + "pkg:nuget/Swashbuckle.AspNetCore.Swagger@10.1.1" + ] + }, + { + "ref": "pkg:nuget/Swashbuckle.AspNetCore.SwaggerUI@10.1.1", + "dependsOn": [] + }, + { + "ref": "pkg:nuget/Swashbuckle.AspNetCore@10.1.1", + "dependsOn": [ + "pkg:nuget/Microsoft.Extensions.ApiDescription.Server@10.0.0", + "pkg:nuget/Swashbuckle.AspNetCore.Swagger@10.1.1", + "pkg:nuget/Swashbuckle.AspNetCore.SwaggerGen@10.1.1", + "pkg:nuget/Swashbuckle.AspNetCore.SwaggerUI@10.1.1" + ] + }, + { + "ref": "pkg:nuget/System.Diagnostics.EventLog@6.0.0", + "dependsOn": [] + }, + { + "ref": "pkg:nuget/System.IdentityModel.Tokens.Jwt@8.15.0", + "dependsOn": [ + "pkg:nuget/Microsoft.IdentityModel.JsonWebTokens@8.15.0", + "pkg:nuget/Microsoft.IdentityModel.Tokens@8.15.0" + ] + }, + { + "ref": "pkg:nuget/System.Reactive@6.0.0", + "dependsOn": [] + }, + { + "ref": "pkg:nuget/System.Security.Cryptography.Pkcs@8.0.1", + "dependsOn": [] + } + ] +} \ No newline at end of file diff --git a/documentation/SBOM/github-sbom.json b/documentation/SBOM/github-sbom.json new file mode 100644 index 0000000000..a2faf2c303 --- /dev/null +++ b/documentation/SBOM/github-sbom.json @@ -0,0 +1,4153 @@ +{ + "spdxVersion": "SPDX-2.3", + "dataLicense": "CC0-1.0", + "SPDXID": "SPDXRef-DOCUMENT", + "name": "com.github.CactuseSecurity/firewall-orchestrator", + "documentNamespace": "https://spdx.org/spdxdocs/protobom/64153841-aba6-49d0-ac52-3faf21f93218", + "comment": "Exact versions could not be resolved for some packages. For more information: https://docs.github.com/en/code-security/supply-chain-security/understanding-your-software-supply-chain/about-the-dependency-graph#dependencies-included.", + "creationInfo": { + "creators": [ + "Tool: protobom-v0.0.0-20251111180015-44acb8c1ef9f+dirty", + "Tool: GitHub.com-Dependency-Graph", + "Tool: Automatic Dependency Submission" + ], + "created": "2025-11-11T20:34:11Z" + }, + "packages": [ + { + "name": "Microsoft.Extensions.Logging.Abstractions", + "SPDXID": "SPDXRef-nuget-Microsoft.Extensions.Logging.Abstractions-8.0.3-0d07ba", + "versionInfo": "8.0.3", + "downloadLocation": "NOASSERTION", + "filesAnalyzed": false, + "licenseConcluded": "MIT", + "copyrightText": "(c) 1997-2005 Sean Eron Anderson, (c) Microsoft Corporation, Copyright (c) .NET Foundation, Copyright (c) .NET Foundation and Contributors, Copyright (c) .NET Foundation Contributors, Copyright (c) 1980, 1986, 1993 The Regents of the University of California, Copyright (c) 1989 by Hewlett-Packard Company, Palo Alto, Ca. \u0026 Digital Equipment Corporation, Maynard, Mass, Copyright (c) 1990- 1993, 1996 Open Software Foundation, Inc., Copyright (c) 1991-2022 Unicode, Inc., Copyright (c) 1995-2022 Jean-loup Gailly and Mark Adler, Copyright (c) 1998 Microsoft, Copyright (c) 1999 Lucent Technologies, Copyright (c) 2004-2006 Intel Corporation, Copyright (c) 2005-2007, Nick Galbreath, Copyright (c) 2005-2020 Rich Felker, Copyright (c) 2006 Jb Evain (jbevain@gmail.com), Copyright (c) 2007 James Newton-King, Copyright (c) 2008-2016, Wojciech Mula, Copyright (c) 2008-2020 Advanced Micro Devices, Inc., Copyright (c) 2009, 2010, 2013-2016 by the Brotli Authors, Copyright (c) 2011 Novell, Inc (http://www.novell.com), Copyright (c) 2011-2015 Intel Corporation, Copyright (c) 2011-2020 Microsoft Corp, Copyright (c) 2011, Google Inc., Copyright (c) 2012 - present, Victor Zverovich, Copyright (c) 2012-2021 Yann Collet, Copyright (c) 2013-2017, Alfred Klomp, Copyright (c) 2013-2017, Milosz Krajewski, Copyright (c) 2014 Ryan Juckett http://www.ryanjuckett.com, Copyright (c) 2015 The Chromium Authors, Copyright (c) 2015 THL A29 Limited, a Tencent company, and Milo Yip, Copyright (c) 2015 Xamarin, Inc (http://www.xamarin.com), Copyright (c) 2015-2017, Wojciech Mula, Copyright (c) 2016-2017, Matthieu Darbois, Copyright (c) 2017 Yoshifumi Kawai, Copyright (c) 2018 Alexander Chermyanin, Copyright (c) 2019 Microsoft Corporation, Daan Leijen, Copyright (c) 2020 Dan Shechter, Copyright (c) 2020 Mara Bos \u003cm-ou.se@m-ou.se\u003e, Copyright (c) 2021, Copyright (c) 2022, Geoff Langdale, Copyright (c) 2022, Wojciech Mula, Copyright (c) Andrew Arnott, Copyright (c) Microsoft Corporation, Copyright (c) Six Labors, Copyright (c) The Internet Society (2003), Copyright (c) The Internet Society 1997, Copyright (c) YEAR W3C(r) (MIT, ERCIM, Keio, Beihang) Disclaimers, Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018 The Regents of the University of California, Copyright 2012 the V8 project authors, Copyright 2018 Daniel Lemire, Copyright 2019 LLVM Project, Portions (c) International Organization for Standardization 1986", + "externalRefs": [ + { + "referenceCategory": "PACKAGE-MANAGER", + "referenceType": "purl", + "referenceLocator": "pkg:nuget/Microsoft.Extensions.Logging.Abstractions@8.0.3" + } + ] + }, + { + "name": "Microsoft.AspNetCore.Components.Analyzers", + "SPDXID": "SPDXRef-nuget-Microsoft.AspNetCore.Components.Analyzers-8.0.15-75b14f", + "versionInfo": "8.0.15", + "downloadLocation": "NOASSERTION", + "filesAnalyzed": false, + "licenseConcluded": "MIT", + "copyrightText": "(c) Microsoft Corporation, Copyright (c) .NET Foundation Contributors, Copyright (c) 1989, 1993 The Regents of the University of California, Copyright (c) 1990, 1993 The Regents of the University of California, Copyright (c) 1996-1998 John D. Polstra, Copyright (c) 1998 John D. Polstra, Copyright (c) 2000-2013 Julian Seward, Copyright (c) 2007 John Birrell (jb@freebsd.org), Copyright (c) 2011-2021 The Bootstrap Authors, Copyright (c) 2011-2021 Twitter, Inc., Copyright (c) 2013 - 2018 AngleSharp, Copyright (c) 2019-2023 The Bootstrap Authors", + "externalRefs": [ + { + "referenceCategory": "PACKAGE-MANAGER", + "referenceType": "purl", + "referenceLocator": "pkg:nuget/Microsoft.AspNetCore.Components.Analyzers@8.0.15" + } + ] + }, + { + "name": "Microsoft.Extensions.Primitives", + "SPDXID": "SPDXRef-nuget-Microsoft.Extensions.Primitives-8.0.0-973e61", + "versionInfo": "8.0.0", + "downloadLocation": "NOASSERTION", + "filesAnalyzed": false, + "licenseConcluded": "MIT", + "copyrightText": "(c) 1997-2005 Sean Eron Anderson, (c) Microsoft Corporation, Copyright (c) .NET Foundation, Copyright (c) .NET Foundation and Contributors, Copyright (c) .NET Foundation Contributors, Copyright (c) 1980, 1986, 1993 The Regents of the University of California, Copyright (c) 1989 by Hewlett-Packard Company, Palo Alto, Ca. \u0026 Digital Equipment Corporation, Maynard, Mass, Copyright (c) 1990- 1993, 1996 Open Software Foundation, Inc., Copyright (c) 1991-2022 Unicode, Inc., Copyright (c) 1995-2022 Jean-loup Gailly and Mark Adler, Copyright (c) 1998 Microsoft. To, Copyright (c) 1999 Lucent Technologies, Copyright (c) 2004-2006 Intel Corporation, Copyright (c) 2005-2007, Nick Galbreath, Copyright (c) 2005-2020 Rich Felker, Copyright (c) 2006 Jb Evain (jbevain@gmail.com), Copyright (c) 2007 James Newton-King, Copyright (c) 2008-2016, Wojciech Mula, Copyright (c) 2008-2020 Advanced Micro Devices, Inc., Copyright (c) 2009, 2010, 2013-2016 by the Brotli Authors, Copyright (c) 2011 Novell, Inc (http://www.novell.com), Copyright (c) 2011-2015 Intel Corporation, Copyright (c) 2011-2020 Microsoft Corp, Copyright (c) 2011, Google Inc., Copyright (c) 2012 - present, Victor Zverovich, Copyright (c) 2012-2021 Yann Collet, Copyright (c) 2013-2017, Alfred Klomp, Copyright (c) 2013-2017, Milosz Krajewski, Copyright (c) 2014 Ryan Juckett http://www.ryanjuckett.com, Copyright (c) 2015 The Chromium Authors, Copyright (c) 2015 THL A29 Limited, a Tencent company, and Milo Yip, Copyright (c) 2015 Xamarin, Inc (http://www.xamarin.com), Copyright (c) 2015-2017, Wojciech Mula, Copyright (c) 2016-2017, Matthieu Darbois, Copyright (c) 2017 Yoshifumi Kawai, Copyright (c) 2018 Alexander Chermyanin, Copyright (c) 2019 Microsoft Corporation, Daan Leijen, Copyright (c) 2020 Dan Shechter, Copyright (c) 2020 Mara Bos \u003cm-ou.se@m-ou.se\u003e, Copyright (c) 2021 csFastFloat authors, Copyright (c) 2022, Geoff Langdale, Copyright (c) 2022, Wojciech Mula, Copyright (c) Andrew Arnott, Copyright (c) Microsoft Corporation, Copyright (c) Six Labors, Copyright (c) The Internet Society (2003), Copyright (c) The Internet Society 1997, Copyright (c) YEAR W3C(r) (MIT, ERCIM, Keio, Beihang). Disclaimers, Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018 The Regents of the University of California, Copyright 2012 the V8 project authors, Copyright 2018 Daniel Lemire, Copyright 2019 LLVM Project, Portions (c) International Organization", + "externalRefs": [ + { + "referenceCategory": "PACKAGE-MANAGER", + "referenceType": "purl", + "referenceLocator": "pkg:nuget/Microsoft.Extensions.Primitives@8.0.0" + } + ] + }, + { + "name": "Microsoft.AspNetCore.Components.Authorization", + "SPDXID": "SPDXRef-nuget-Microsoft.AspNetCore.Components.Authorization-8.0.15-58c86a", + "versionInfo": "8.0.15", + "downloadLocation": "NOASSERTION", + "filesAnalyzed": false, + "licenseConcluded": "MIT", + "copyrightText": "(c) Microsoft Corporation, Copyright (c) .NET Foundation Contributors, Copyright (c) 1989, 1993 The Regents of the University of California, Copyright (c) 1990, 1993 The Regents of the University of California, Copyright (c) 1996-1998 John D. Polstra, Copyright (c) 1998 John D. Polstra, Copyright (c) 2000-2013 Julian Seward, Copyright (c) 2007 John Birrell (jb@freebsd.org), Copyright (c) 2011-2021 The Bootstrap Authors, Copyright (c) 2011-2021 Twitter, Inc., Copyright (c) 2013 - 2018 AngleSharp, Copyright (c) 2019-2023 The Bootstrap Authors", + "externalRefs": [ + { + "referenceCategory": "PACKAGE-MANAGER", + "referenceType": "purl", + "referenceLocator": "pkg:nuget/Microsoft.AspNetCore.Components.Authorization@8.0.15" + } + ] + }, + { + "name": "Microsoft.AspNetCore.Authorization", + "SPDXID": "SPDXRef-nuget-Microsoft.AspNetCore.Authorization-8.0.15-59a19e", + "versionInfo": "8.0.15", + "downloadLocation": "NOASSERTION", + "filesAnalyzed": false, + "licenseConcluded": "MIT", + "copyrightText": "(c) Microsoft Corporation, Copyright (c) .NET Foundation and Contributors, Copyright (c) .NET Foundation Contributors, Copyright (c) 1989, 1993 The Regents of the University of California, Copyright (c) 1990, 1993 The Regents of the University of California, Copyright (c) 1996-1998 John D. Polstra, Copyright (c) 1998 John D. Polstra, Copyright (c) 2000-2013 Julian Seward, Copyright (c) 2007 James Newton-King, Copyright (c) 2007 John Birrell (jb@freebsd.org), Copyright (c) 2010-2019 Google LLC. http://angular.io/license, Copyright (c) 2011 Alex MacCaw (info@eribium.org), Copyright (c) 2011 Nicolas Gallagher (nicolas@nicolasgallagher.com), Copyright (c) 2011-2021 The Bootstrap Authors, Copyright (c) 2011-2021 Twitter, Inc., Copyright (c) 2013 - 2018 AngleSharp, Copyright (c) 2013-2017, Milosz Krajewski, Copyright (c) 2014-2018 Michael Daines, Copyright (c) 2015, Google Inc., Copyright (c) 2016 Richard Morris, Copyright (c) 2017 Yoshifumi Kawai, Copyright (c) 2019 David Fowler, Copyright (c) 2019-2020 West Wind Technologies, Copyright (c) 2019-2023 The Bootstrap Authors, Copyright (c) Andrew Arnott, Copyright (c) HTML5 Boilerplate, Copyright (c) Microsoft Corporation, Copyright (c) Nicolas Gallagher and Jonathan Neal, Copyright (c) Sindre Sorhus \u003csindresorhus@gmail.com\u003e (https://sindresorhus.com), Copyright 2019 The gRPC Authors, Copyright Jorn Zaefferer, Copyright OpenJS Foundation and other contributors, https://openjsf.org", + "externalRefs": [ + { + "referenceCategory": "PACKAGE-MANAGER", + "referenceType": "purl", + "referenceLocator": "pkg:nuget/Microsoft.AspNetCore.Authorization@8.0.15" + } + ] + }, + { + "name": "Microsoft.AspNetCore.Components", + "SPDXID": "SPDXRef-nuget-Microsoft.AspNetCore.Components-8.0.15-154912", + "versionInfo": "8.0.15", + "downloadLocation": "NOASSERTION", + "filesAnalyzed": false, + "licenseConcluded": "MIT", + "copyrightText": "(c) Microsoft Corporation, Copyright (c) .NET Foundation Contributors, Copyright (c) 1989, 1993 The Regents of the University of California, Copyright (c) 1990, 1993 The Regents of the University of California, Copyright (c) 1996-1998 John D. Polstra, Copyright (c) 1998 John D. Polstra, Copyright (c) 2000-2013 Julian Seward, Copyright (c) 2007 John Birrell (jb@freebsd.org), Copyright (c) 2011-2021 The Bootstrap Authors, Copyright (c) 2011-2021 Twitter, Inc., Copyright (c) 2013 - 2018 AngleSharp, Copyright (c) 2019-2023 The Bootstrap Authors", + "externalRefs": [ + { + "referenceCategory": "PACKAGE-MANAGER", + "referenceType": "purl", + "referenceLocator": "pkg:nuget/Microsoft.AspNetCore.Components@8.0.15" + } + ] + }, + { + "name": "Microsoft.Extensions.Options", + "SPDXID": "SPDXRef-nuget-Microsoft.Extensions.Options-8.0.2-ed918b", + "versionInfo": "8.0.2", + "downloadLocation": "NOASSERTION", + "filesAnalyzed": false, + "licenseConcluded": "MIT", + "copyrightText": "(c) 1997-2005 Sean Eron Anderson, (c) Microsoft Corporation, Copyright (c) .NET Foundation, Copyright (c) .NET Foundation and Contributors, Copyright (c) .NET Foundation Contributors, Copyright (c) 1980, 1986, 1993 The Regents of the University of California, Copyright (c) 1989 by Hewlett-Packard Company, Palo Alto, Ca. \u0026 Digital Equipment Corporation, Maynard, Mass, Copyright (c) 1990- 1993, 1996 Open Software Foundation, Inc., Copyright (c) 1991-2022 Unicode, Inc., Copyright (c) 1995-2022 Jean-loup Gailly and Mark Adler, Copyright (c) 1998 Microsoft. To, Copyright (c) 1999 Lucent Technologies, Copyright (c) 2004-2006 Intel Corporation, Copyright (c) 2005-2007, Nick Galbreath, Copyright (c) 2005-2020 Rich Felker, Copyright (c) 2006 Jb Evain (jbevain@gmail.com), Copyright (c) 2007 James Newton-King, Copyright (c) 2008-2016, Wojciech Mula, Copyright (c) 2008-2020 Advanced Micro Devices, Inc., Copyright (c) 2009, 2010, 2013-2016 by the Brotli Authors, Copyright (c) 2011 Novell, Inc (http://www.novell.com), Copyright (c) 2011-2015 Intel Corporation, Copyright (c) 2011-2020 Microsoft Corp, Copyright (c) 2011, Google Inc., Copyright (c) 2012 - present, Victor Zverovich, Copyright (c) 2012-2021 Yann Collet, Copyright (c) 2013-2017, Alfred Klomp, Copyright (c) 2013-2017, Milosz Krajewski, Copyright (c) 2014 Ryan Juckett http://www.ryanjuckett.com, Copyright (c) 2015 The Chromium Authors, Copyright (c) 2015 THL A29 Limited, a Tencent company, and Milo Yip, Copyright (c) 2015 Xamarin, Inc (http://www.xamarin.com), Copyright (c) 2015-2017, Wojciech Mula, Copyright (c) 2016-2017, Matthieu Darbois, Copyright (c) 2017 Yoshifumi Kawai, Copyright (c) 2018 Alexander Chermyanin, Copyright (c) 2019 Microsoft Corporation, Daan Leijen, Copyright (c) 2020 Dan Shechter, Copyright (c) 2020 Mara Bos \u003cm-ou.se@m-ou.se\u003e, Copyright (c) 2021 csFastFloat authors, Copyright (c) 2022, Geoff Langdale, Copyright (c) 2022, Wojciech Mula, Copyright (c) Andrew Arnott, Copyright (c) Microsoft Corporation, Copyright (c) Six Labors, Copyright (c) The Internet Society (2003), Copyright (c) The Internet Society 1997, Copyright (c) YEAR W3C(r) (MIT, ERCIM, Keio, Beihang). Disclaimers, Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018 The Regents of the University of California, Copyright 2012 the V8 project authors, Copyright 2018 Daniel Lemire, Copyright 2019 LLVM Project, Portions (c) International Organization", + "externalRefs": [ + { + "referenceCategory": "PACKAGE-MANAGER", + "referenceType": "purl", + "referenceLocator": "pkg:nuget/Microsoft.Extensions.Options@8.0.2" + } + ] + }, + { + "name": "Microsoft.Extensions.DependencyInjection.Abstractions", + "SPDXID": "SPDXRef-nuget-Microsoft.Extensions.DependencyInjection.Abstractions-8.0.2-934d86", + "versionInfo": "8.0.2", + "downloadLocation": "NOASSERTION", + "filesAnalyzed": false, + "licenseConcluded": "MIT", + "copyrightText": "(c) 1997-2005 Sean Eron Anderson, (c) Microsoft Corporation, Copyright (c) .NET Foundation, Copyright (c) .NET Foundation and Contributors, Copyright (c) .NET Foundation Contributors, Copyright (c) 1980, 1986, 1993 The Regents of the University of California, Copyright (c) 1989 by Hewlett-Packard Company, Palo Alto, Ca. \u0026 Digital Equipment Corporation, Maynard, Mass, Copyright (c) 1990- 1993, 1996 Open Software Foundation, Inc., Copyright (c) 1991-2022 Unicode, Inc., Copyright (c) 1995-2022 Jean-loup Gailly and Mark Adler, Copyright (c) 1998 Microsoft. To, Copyright (c) 1999 Lucent Technologies, Copyright (c) 2004-2006 Intel Corporation, Copyright (c) 2005-2007, Nick Galbreath, Copyright (c) 2005-2020 Rich Felker, Copyright (c) 2006 Jb Evain (jbevain@gmail.com), Copyright (c) 2007 James Newton-King, Copyright (c) 2008-2016, Wojciech Mula, Copyright (c) 2008-2020 Advanced Micro Devices, Inc., Copyright (c) 2009, 2010, 2013-2016 by the Brotli Authors, Copyright (c) 2011 Novell, Inc (http://www.novell.com), Copyright (c) 2011-2015 Intel Corporation, Copyright (c) 2011-2020 Microsoft Corp, Copyright (c) 2011, Google Inc., Copyright (c) 2012 - present, Victor Zverovich, Copyright (c) 2012-2021 Yann Collet, Copyright (c) 2013-2017, Alfred Klomp, Copyright (c) 2013-2017, Milosz Krajewski, Copyright (c) 2014 Ryan Juckett http://www.ryanjuckett.com, Copyright (c) 2015 The Chromium Authors, Copyright (c) 2015 THL A29 Limited, a Tencent company, and Milo Yip, Copyright (c) 2015 Xamarin, Inc (http://www.xamarin.com), Copyright (c) 2015-2017, Wojciech Mula, Copyright (c) 2016-2017, Matthieu Darbois, Copyright (c) 2017 Yoshifumi Kawai, Copyright (c) 2018 Alexander Chermyanin, Copyright (c) 2019 Microsoft Corporation, Daan Leijen, Copyright (c) 2020 Dan Shechter, Copyright (c) 2020 Mara Bos \u003cm-ou.se@m-ou.se\u003e, Copyright (c) 2021 csFastFloat authors, Copyright (c) 2022, Geoff Langdale, Copyright (c) 2022, Wojciech Mula, Copyright (c) Andrew Arnott, Copyright (c) Microsoft Corporation, Copyright (c) Six Labors, Copyright (c) The Internet Society (2003), Copyright (c) The Internet Society 1997, Copyright (c) YEAR W3C(r) (MIT, ERCIM, Keio, Beihang). Disclaimers, Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018 The Regents of the University of California, Copyright 2012 the V8 project authors, Copyright 2018 Daniel Lemire, Copyright 2019 LLVM Project, Portions (c) International Organization", + "externalRefs": [ + { + "referenceCategory": "PACKAGE-MANAGER", + "referenceType": "purl", + "referenceLocator": "pkg:nuget/Microsoft.Extensions.DependencyInjection.Abstractions@8.0.2" + } + ] + }, + { + "name": "Microsoft.AspNetCore.Metadata", + "SPDXID": "SPDXRef-nuget-Microsoft.AspNetCore.Metadata-8.0.15-f13caf", + "versionInfo": "8.0.15", + "downloadLocation": "NOASSERTION", + "filesAnalyzed": false, + "licenseConcluded": "MIT", + "copyrightText": "(c) Microsoft Corporation, Copyright (c) .NET Foundation and Contributors, Copyright (c) .NET Foundation Contributors, Copyright (c) 1989, 1993 The Regents of the University of California, Copyright (c) 1990, 1993 The Regents of the University of California, Copyright (c) 1996-1998 John D. Polstra, Copyright (c) 1998 John D. Polstra, Copyright (c) 2000-2013 Julian Seward, Copyright (c) 2007 James Newton-King, Copyright (c) 2007 John Birrell (jb@freebsd.org), Copyright (c) 2010-2019 Google LLC. http://angular.io/license, Copyright (c) 2011 Alex MacCaw (info@eribium.org), Copyright (c) 2011 Nicolas Gallagher (nicolas@nicolasgallagher.com), Copyright (c) 2011-2021 The Bootstrap Authors, Copyright (c) 2011-2021 Twitter, Inc., Copyright (c) 2013 - 2018 AngleSharp, Copyright (c) 2013-2017, Milosz Krajewski, Copyright (c) 2014-2018 Michael Daines, Copyright (c) 2015, Google Inc., Copyright (c) 2016 Richard Morris, Copyright (c) 2017 Yoshifumi Kawai, Copyright (c) 2019 David Fowler, Copyright (c) 2019-2020 West Wind Technologies, Copyright (c) 2019-2023 The Bootstrap Authors, Copyright (c) Andrew Arnott, Copyright (c) HTML5 Boilerplate, Copyright (c) Microsoft Corporation, Copyright (c) Nicolas Gallagher and Jonathan Neal, Copyright (c) Sindre Sorhus \u003csindresorhus@gmail.com\u003e (https://sindresorhus.com), Copyright 2019 The gRPC Authors, Copyright Jorn Zaefferer, Copyright OpenJS Foundation and other contributors, https://openjsf.org", + "externalRefs": [ + { + "referenceCategory": "PACKAGE-MANAGER", + "referenceType": "purl", + "referenceLocator": "pkg:nuget/Microsoft.AspNetCore.Metadata@8.0.15" + } + ] + }, + { + "name": "bunit.core", + "SPDXID": "SPDXRef-nuget-bunit.core-1.40.0-44d971", + "versionInfo": "1.40.0", + "downloadLocation": "NOASSERTION", + "filesAnalyzed": false, + "licenseConcluded": "MIT", + "copyrightText": "Copyright (c) .NET Foundation and Contributors", + "externalRefs": [ + { + "referenceCategory": "PACKAGE-MANAGER", + "referenceType": "purl", + "referenceLocator": "pkg:nuget/bunit.core@1.40.0" + } + ] + }, + { + "name": "Microsoft.TestPlatform.ObjectModel", + "SPDXID": "SPDXRef-nuget-Microsoft.TestPlatform.ObjectModel-17.14.1-341464", + "versionInfo": "17.14.1", + "downloadLocation": "NOASSERTION", + "filesAnalyzed": false, + "licenseConcluded": "MIT", + "copyrightText": "(c) Microsoft Corporation", + "externalRefs": [ + { + "referenceCategory": "PACKAGE-MANAGER", + "referenceType": "purl", + "referenceLocator": "pkg:nuget/Microsoft.TestPlatform.ObjectModel@17.14.1" + } + ] + }, + { + "name": "AngleSharp", + "SPDXID": "SPDXRef-nuget-AngleSharp-1.2.0-ec1ca1", + "versionInfo": "1.2.0", + "downloadLocation": "NOASSERTION", + "filesAnalyzed": false, + "licenseConcluded": "LicenseRef-scancode-unknown-license-reference AND MIT", + "copyrightText": "Copyright 2013-2024, AngleSharp, Copyright AngleSharp, 2013-2024", + "externalRefs": [ + { + "referenceCategory": "PACKAGE-MANAGER", + "referenceType": "purl", + "referenceLocator": "pkg:nuget/AngleSharp@1.2.0" + } + ] + }, + { + "name": "Microsoft.AspNetCore.Components.WebAssembly.Authentication", + "SPDXID": "SPDXRef-nuget-Microsoft.AspNetCore.Components.WebAssembly.Authentication-8.0.11-d84320", + "versionInfo": "8.0.11", + "downloadLocation": "NOASSERTION", + "filesAnalyzed": false, + "licenseConcluded": "MIT", + "copyrightText": "(c) Microsoft Corporation, Copyright (c) .NET Foundation Contributors, Copyright (c) 1989, 1993 The Regents of the University of California, Copyright (c) 1990, 1993 The Regents of the University of California, Copyright (c) 1996-1998 John D. Polstra, Copyright (c) 1998 John D. Polstra, Copyright (c) 2000-2013 Julian Seward, Copyright (c) 2007 John Birrell (jb@freebsd.org), Copyright (c) 2011-2021 The Bootstrap Authors, Copyright (c) 2011-2021 Twitter, Inc., Copyright (c) 2013 - 2018 AngleSharp, Copyright (c) 2019-2023 The Bootstrap Authors", + "externalRefs": [ + { + "referenceCategory": "PACKAGE-MANAGER", + "referenceType": "purl", + "referenceLocator": "pkg:nuget/Microsoft.AspNetCore.Components.WebAssembly.Authentication@8.0.11" + } + ] + }, + { + "name": "Microsoft.JSInterop", + "SPDXID": "SPDXRef-nuget-Microsoft.JSInterop-8.0.11-5ea157", + "versionInfo": "8.0.11", + "downloadLocation": "NOASSERTION", + "filesAnalyzed": false, + "licenseConcluded": "MIT", + "copyrightText": "(c) Microsoft Corporation, Copyright (c) .NET Foundation and Contributors, Copyright (c) .NET Foundation Contributors, Copyright (c) 1989, 1993 The Regents of the University of California, Copyright (c) 1990, 1993 The Regents of the University of California, Copyright (c) 1996-1998 John D. Polstra, Copyright (c) 1998 John D. Polstra, Copyright (c) 2000-2013 Julian Seward, Copyright (c) 2007 James Newton-King, Copyright (c) 2007 John Birrell (jb@freebsd.org), Copyright (c) 2010-2019 Google LLC. http://angular.io/license, Copyright (c) 2011 Alex MacCaw (info@eribium.org), Copyright (c) 2011 Nicolas Gallagher (nicolas@nicolasgallagher.com), Copyright (c) 2011-2021 The Bootstrap Authors, Copyright (c) 2011-2021 Twitter, Inc., Copyright (c) 2013 - 2018 AngleSharp, Copyright (c) 2013-2017, Milosz Krajewski, Copyright (c) 2014-2018 Michael Daines, Copyright (c) 2015, Google Inc., Copyright (c) 2016 Richard Morris, Copyright (c) 2017 Yoshifumi Kawai, Copyright (c) 2019 David Fowler, Copyright (c) 2019-2020 West Wind Technologies, Copyright (c) 2019-2023 The Bootstrap Authors, Copyright (c) Andrew Arnott, Copyright (c) HTML5 Boilerplate, Copyright (c) Microsoft Corporation, Copyright (c) Nicolas Gallagher and Jonathan Neal, Copyright (c) Sindre Sorhus \u003csindresorhus@gmail.com\u003e (https://sindresorhus.com), Copyright 2019 The gRPC Authors, Copyright Jorn Zaefferer, Copyright OpenJS Foundation and other contributors, https://openjsf.org", + "externalRefs": [ + { + "referenceCategory": "PACKAGE-MANAGER", + "referenceType": "purl", + "referenceLocator": "pkg:nuget/Microsoft.JSInterop@8.0.11" + } + ] + }, + { + "name": "Microsoft.Extensions.Localization.Abstractions", + "SPDXID": "SPDXRef-nuget-Microsoft.Extensions.Localization.Abstractions-8.0.11-4cb515", + "versionInfo": "8.0.11", + "downloadLocation": "NOASSERTION", + "filesAnalyzed": false, + "licenseConcluded": "MIT", + "copyrightText": "(c) Microsoft Corporation, Copyright (c) .NET Foundation and Contributors, Copyright (c) .NET Foundation Contributors, Copyright (c) 1989, 1993 The Regents of the University of California, Copyright (c) 1990, 1993 The Regents of the University of California, Copyright (c) 1996-1998 John D. Polstra, Copyright (c) 1998 John D. Polstra, Copyright (c) 2000-2013 Julian Seward, Copyright (c) 2007 James Newton-King, Copyright (c) 2007 John Birrell (jb@freebsd.org), Copyright (c) 2010-2019 Google LLC. http://angular.io/license, Copyright (c) 2011 Alex MacCaw (info@eribium.org), Copyright (c) 2011 Nicolas Gallagher (nicolas@nicolasgallagher.com), Copyright (c) 2011-2021 The Bootstrap Authors, Copyright (c) 2011-2021 Twitter, Inc., Copyright (c) 2013 - 2018 AngleSharp, Copyright (c) 2013-2017, Milosz Krajewski, Copyright (c) 2014-2018 Michael Daines, Copyright (c) 2015, Google Inc., Copyright (c) 2016 Richard Morris, Copyright (c) 2017 Yoshifumi Kawai, Copyright (c) 2019 David Fowler, Copyright (c) 2019-2020 West Wind Technologies, Copyright (c) 2019-2023 The Bootstrap Authors, Copyright (c) Andrew Arnott, Copyright (c) HTML5 Boilerplate, Copyright (c) Microsoft Corporation, Copyright (c) Nicolas Gallagher and Jonathan Neal, Copyright (c) Sindre Sorhus \u003csindresorhus@gmail.com\u003e (https://sindresorhus.com), Copyright 2019 The gRPC Authors, Copyright Jorn Zaefferer, Copyright OpenJS Foundation and other contributors, https://openjsf.org", + "externalRefs": [ + { + "referenceCategory": "PACKAGE-MANAGER", + "referenceType": "purl", + "referenceLocator": "pkg:nuget/Microsoft.Extensions.Localization.Abstractions@8.0.11" + } + ] + }, + { + "name": "Microsoft.NET.Test.Sdk", + "SPDXID": "SPDXRef-nuget-Microsoft.NET.Test.Sdk-17.14.1-86ab34", + "versionInfo": "17.14.1", + "downloadLocation": "NOASSERTION", + "filesAnalyzed": false, + "licenseConcluded": "MIT", + "copyrightText": "(c) Microsoft Corporation, Copyright (c) .NET Foundation", + "externalRefs": [ + { + "referenceCategory": "PACKAGE-MANAGER", + "referenceType": "purl", + "referenceLocator": "pkg:nuget/Microsoft.NET.Test.Sdk@17.14.1" + } + ] + }, + { + "name": "System.Text.Json", + "SPDXID": "SPDXRef-nuget-System.Text.Json-8.0.5-74b06c", + "versionInfo": "8.0.5", + "downloadLocation": "NOASSERTION", + "filesAnalyzed": false, + "licenseConcluded": "MIT", + "copyrightText": "(c) 1997-2005 Sean Eron Anderson, (c) Microsoft Corporation, Copyright (c) .NET Foundation, Copyright (c) .NET Foundation and Contributors, Copyright (c) .NET Foundation Contributors, Copyright (c) 1980, 1986, 1993 The Regents of the University of California, Copyright (c) 1989 by Hewlett-Packard Company, Palo Alto, Ca. \u0026 Digital Equipment Corporation, Maynard, Mass, Copyright (c) 1990- 1993, 1996 Open Software Foundation, Inc., Copyright (c) 1991-2022 Unicode, Inc., Copyright (c) 1995-2022 Jean-loup Gailly and Mark Adler, Copyright (c) 1998 Microsoft, Copyright (c) 1998 Microsoft. To, Copyright (c) 1999 Lucent Technologies, Copyright (c) 2004-2006 Intel Corporation, Copyright (c) 2005-2007, Nick Galbreath, Copyright (c) 2005-2020 Rich Felker, Copyright (c) 2006 Jb Evain (jbevain@gmail.com), Copyright (c) 2007 James Newton-King, Copyright (c) 2008-2016, Wojciech Mula, Copyright (c) 2008-2020 Advanced Micro Devices, Inc., Copyright (c) 2009, 2010, 2013-2016 by the Brotli Authors, Copyright (c) 2011 Novell, Inc (http://www.novell.com), Copyright (c) 2011-2015 Intel Corporation, Copyright (c) 2011-2020 Microsoft Corp, Copyright (c) 2011, Google Inc., Copyright (c) 2012 - present, Victor Zverovich, Copyright (c) 2012-2021 Yann Collet, Copyright (c) 2013-2017, Alfred Klomp, Copyright (c) 2013-2017, Milosz Krajewski, Copyright (c) 2014 Ryan Juckett http://www.ryanjuckett.com, Copyright (c) 2015 The Chromium Authors, Copyright (c) 2015 THL A29 Limited, a Tencent company, and Milo Yip, Copyright (c) 2015 Xamarin, Inc (http://www.xamarin.com), Copyright (c) 2015-2017, Wojciech Mula, Copyright (c) 2016-2017, Matthieu Darbois, Copyright (c) 2017 Yoshifumi Kawai, Copyright (c) 2018 Alexander Chermyanin, Copyright (c) 2019 Microsoft Corporation, Daan Leijen, Copyright (c) 2020 Dan Shechter, Copyright (c) 2020 Mara Bos \u003cm-ou.se@m-ou.se\u003e, Copyright (c) 2021, Copyright (c) 2021 csFastFloat authors, Copyright (c) 2022, Geoff Langdale, Copyright (c) 2022, Wojciech Mula, Copyright (c) Andrew Arnott, Copyright (c) Microsoft Corporation, Copyright (c) Six Labors, Copyright (c) The Internet Society (2003), Copyright (c) The Internet Society 1997, Copyright (c) YEAR W3C(r) (MIT, ERCIM, Keio, Beihang) Disclaimers, Copyright (c) YEAR W3C(r) (MIT, ERCIM, Keio, Beihang). Disclaimers, Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018 The Regents of the University of California, Copyright 2012 the V8 project authors, Copyright 2018 Daniel Lemire, Copyright 2019 LLVM Project, Portions (c) International Organization, Portions (c) International Organization for Standardization 1986", + "externalRefs": [ + { + "referenceCategory": "PACKAGE-MANAGER", + "referenceType": "purl", + "referenceLocator": "pkg:nuget/System.Text.Json@8.0.5" + } + ] + }, + { + "name": "Microsoft.AspNetCore.Components.WebAssembly", + "SPDXID": "SPDXRef-nuget-Microsoft.AspNetCore.Components.WebAssembly-8.0.11-b60482", + "versionInfo": "8.0.11", + "downloadLocation": "NOASSERTION", + "filesAnalyzed": false, + "licenseConcluded": "MIT", + "copyrightText": "(c) Microsoft Corporation, Copyright (c) .NET Foundation Contributors, Copyright (c) 1989, 1993 The Regents of the University of California, Copyright (c) 1990, 1993 The Regents of the University of California, Copyright (c) 1996-1998 John D. Polstra, Copyright (c) 1998 John D. Polstra, Copyright (c) 2000-2013 Julian Seward, Copyright (c) 2007 John Birrell (jb@freebsd.org), Copyright (c) 2011-2021 The Bootstrap Authors, Copyright (c) 2011-2021 Twitter, Inc., Copyright (c) 2013 - 2018 AngleSharp, Copyright (c) 2019-2023 The Bootstrap Authors", + "externalRefs": [ + { + "referenceCategory": "PACKAGE-MANAGER", + "referenceType": "purl", + "referenceLocator": "pkg:nuget/Microsoft.AspNetCore.Components.WebAssembly@8.0.11" + } + ] + }, + { + "name": "System.IO.Pipelines", + "SPDXID": "SPDXRef-nuget-System.IO.Pipelines-8.0.0-f9572b", + "versionInfo": "8.0.0", + "downloadLocation": "NOASSERTION", + "filesAnalyzed": false, + "licenseConcluded": "MIT", + "copyrightText": "(c) 1997-2005 Sean Eron Anderson, (c) Microsoft Corporation, Copyright (c) .NET Foundation, Copyright (c) .NET Foundation and Contributors, Copyright (c) .NET Foundation Contributors, Copyright (c) 1980, 1986, 1993 The Regents of the University of California, Copyright (c) 1989 by Hewlett-Packard Company, Palo Alto, Ca. \u0026 Digital Equipment Corporation, Maynard, Mass, Copyright (c) 1990- 1993, 1996 Open Software Foundation, Inc., Copyright (c) 1991-2022 Unicode, Inc., Copyright (c) 1995-2022 Jean-loup Gailly and Mark Adler, Copyright (c) 1998 Microsoft, Copyright (c) 1998 Microsoft. To, Copyright (c) 1999 Lucent Technologies, Copyright (c) 2004-2006 Intel Corporation, Copyright (c) 2005-2007, Nick Galbreath, Copyright (c) 2005-2020 Rich Felker, Copyright (c) 2006 Jb Evain (jbevain@gmail.com), Copyright (c) 2007 James Newton-King, Copyright (c) 2008-2016, Wojciech Mula, Copyright (c) 2008-2020 Advanced Micro Devices, Inc., Copyright (c) 2009, 2010, 2013-2016 by the Brotli Authors, Copyright (c) 2011 Novell, Inc (http://www.novell.com), Copyright (c) 2011-2015 Intel Corporation, Copyright (c) 2011-2020 Microsoft Corp, Copyright (c) 2011, Google Inc., Copyright (c) 2012 - present, Victor Zverovich, Copyright (c) 2012-2021 Yann Collet, Copyright (c) 2013-2017, Alfred Klomp, Copyright (c) 2013-2017, Milosz Krajewski, Copyright (c) 2014 Ryan Juckett http://www.ryanjuckett.com, Copyright (c) 2015 The Chromium Authors, Copyright (c) 2015 THL A29 Limited, a Tencent company, and Milo Yip, Copyright (c) 2015 Xamarin, Inc (http://www.xamarin.com), Copyright (c) 2015-2017, Wojciech Mula, Copyright (c) 2016-2017, Matthieu Darbois, Copyright (c) 2017 Yoshifumi Kawai, Copyright (c) 2018 Alexander Chermyanin, Copyright (c) 2019 Microsoft Corporation, Daan Leijen, Copyright (c) 2020 Dan Shechter, Copyright (c) 2020 Mara Bos \u003cm-ou.se@m-ou.se\u003e, Copyright (c) 2021, Copyright (c) 2021 csFastFloat authors, Copyright (c) 2022, Geoff Langdale, Copyright (c) 2022, Wojciech Mula, Copyright (c) Andrew Arnott, Copyright (c) Microsoft Corporation, Copyright (c) Six Labors, Copyright (c) The Internet Society (2003), Copyright (c) The Internet Society 1997, Copyright (c) YEAR W3C(r) (MIT, ERCIM, Keio, Beihang) Disclaimers, Copyright (c) YEAR W3C(r) (MIT, ERCIM, Keio, Beihang). Disclaimers, Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018 The Regents of the University of California, Copyright 2012 the V8 project authors, Copyright 2018 Daniel Lemire, Copyright 2019 LLVM Project, Portions (c) International Organization, Portions (c) International Organization for Standardization 1986", + "externalRefs": [ + { + "referenceCategory": "PACKAGE-MANAGER", + "referenceType": "purl", + "referenceLocator": "pkg:nuget/System.IO.Pipelines@8.0.0" + } + ] + }, + { + "name": "Microsoft.AspNetCore.Components.Analyzers", + "SPDXID": "SPDXRef-nuget-Microsoft.AspNetCore.Components.Analyzers-8.0.15-67a21b", + "versionInfo": "8.0.15", + "downloadLocation": "NOASSERTION", + "filesAnalyzed": false, + "licenseConcluded": "MIT", + "copyrightText": "(c) Microsoft Corporation, Copyright (c) .NET Foundation Contributors, Copyright (c) 1989, 1993 The Regents of the University of California, Copyright (c) 1990, 1993 The Regents of the University of California, Copyright (c) 1996-1998 John D. Polstra, Copyright (c) 1998 John D. Polstra, Copyright (c) 2000-2013 Julian Seward, Copyright (c) 2007 John Birrell (jb@freebsd.org), Copyright (c) 2011-2021 The Bootstrap Authors, Copyright (c) 2011-2021 Twitter, Inc., Copyright (c) 2013 - 2018 AngleSharp, Copyright (c) 2019-2023 The Bootstrap Authors", + "externalRefs": [ + { + "referenceCategory": "PACKAGE-MANAGER", + "referenceType": "purl", + "referenceLocator": "pkg:nuget/Microsoft.AspNetCore.Components.Analyzers@8.0.15" + } + ] + }, + { + "name": "Microsoft.Extensions.Configuration.Json", + "SPDXID": "SPDXRef-nuget-Microsoft.Extensions.Configuration.Json-8.0.1-bd4bb5", + "versionInfo": "8.0.1", + "downloadLocation": "NOASSERTION", + "filesAnalyzed": false, + "licenseConcluded": "MIT", + "copyrightText": "(c) 1997-2005 Sean Eron Anderson, (c) Microsoft Corporation, Copyright (c) .NET Foundation, Copyright (c) .NET Foundation and Contributors, Copyright (c) .NET Foundation Contributors, Copyright (c) 1980, 1986, 1993 The Regents of the University of California, Copyright (c) 1989 by Hewlett-Packard Company, Palo Alto, Ca. \u0026 Digital Equipment Corporation, Maynard, Mass, Copyright (c) 1990- 1993, 1996 Open Software Foundation, Inc., Copyright (c) 1991-2022 Unicode, Inc., Copyright (c) 1995-2022 Jean-loup Gailly and Mark Adler, Copyright (c) 1998 Microsoft, Copyright (c) 1998 Microsoft. To, Copyright (c) 1999 Lucent Technologies, Copyright (c) 2004-2006 Intel Corporation, Copyright (c) 2005-2007, Nick Galbreath, Copyright (c) 2005-2020 Rich Felker, Copyright (c) 2006 Jb Evain (jbevain@gmail.com), Copyright (c) 2007 James Newton-King, Copyright (c) 2008-2016, Wojciech Mula, Copyright (c) 2008-2020 Advanced Micro Devices, Inc., Copyright (c) 2009, 2010, 2013-2016 by the Brotli Authors, Copyright (c) 2011 Novell, Inc (http://www.novell.com), Copyright (c) 2011-2015 Intel Corporation, Copyright (c) 2011-2020 Microsoft Corp, Copyright (c) 2011, Google Inc., Copyright (c) 2012 - present, Victor Zverovich, Copyright (c) 2012-2021 Yann Collet, Copyright (c) 2013-2017, Alfred Klomp, Copyright (c) 2013-2017, Milosz Krajewski, Copyright (c) 2014 Ryan Juckett http://www.ryanjuckett.com, Copyright (c) 2015 The Chromium Authors, Copyright (c) 2015 THL A29 Limited, a Tencent company, and Milo Yip, Copyright (c) 2015 Xamarin, Inc (http://www.xamarin.com), Copyright (c) 2015-2017, Wojciech Mula, Copyright (c) 2016-2017, Matthieu Darbois, Copyright (c) 2017 Yoshifumi Kawai, Copyright (c) 2018 Alexander Chermyanin, Copyright (c) 2019 Microsoft Corporation, Daan Leijen, Copyright (c) 2020 Dan Shechter, Copyright (c) 2020 Mara Bos \u003cm-ou.se@m-ou.se\u003e, Copyright (c) 2021, Copyright (c) 2021 csFastFloat authors, Copyright (c) 2022, Geoff Langdale, Copyright (c) 2022, Wojciech Mula, Copyright (c) Andrew Arnott, Copyright (c) Microsoft Corporation, Copyright (c) Six Labors, Copyright (c) The Internet Society (2003), Copyright (c) The Internet Society 1997, Copyright (c) YEAR W3C(r) (MIT, ERCIM, Keio, Beihang) Disclaimers, Copyright (c) YEAR W3C(r) (MIT, ERCIM, Keio, Beihang). Disclaimers, Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018 The Regents of the University of California, Copyright 2012 the V8 project authors, Copyright 2018 Daniel Lemire, Copyright 2019 LLVM Project, Portions (c) International Organization, Portions (c) International Organization for Standardization 1986", + "externalRefs": [ + { + "referenceCategory": "PACKAGE-MANAGER", + "referenceType": "purl", + "referenceLocator": "pkg:nuget/Microsoft.Extensions.Configuration.Json@8.0.1" + } + ] + }, + { + "name": "Microsoft.Testing.Platform.MSBuild", + "SPDXID": "SPDXRef-nuget-Microsoft.Testing.Platform.MSBuild-1.7.3-c5050d", + "versionInfo": "1.7.3", + "downloadLocation": "NOASSERTION", + "filesAnalyzed": false, + "licenseConcluded": "MIT", + "copyrightText": "(c) Microsoft Corporation", + "externalRefs": [ + { + "referenceCategory": "PACKAGE-MANAGER", + "referenceType": "purl", + "referenceLocator": "pkg:nuget/Microsoft.Testing.Platform.MSBuild@1.7.3" + } + ] + }, + { + "name": "Microsoft.Extensions.Options", + "SPDXID": "SPDXRef-nuget-Microsoft.Extensions.Options-8.0.2-553265", + "versionInfo": "8.0.2", + "downloadLocation": "NOASSERTION", + "filesAnalyzed": false, + "licenseConcluded": "MIT", + "copyrightText": "(c) 1997-2005 Sean Eron Anderson, (c) Microsoft Corporation, Copyright (c) .NET Foundation, Copyright (c) .NET Foundation and Contributors, Copyright (c) .NET Foundation Contributors, Copyright (c) 1980, 1986, 1993 The Regents of the University of California, Copyright (c) 1989 by Hewlett-Packard Company, Palo Alto, Ca. \u0026 Digital Equipment Corporation, Maynard, Mass, Copyright (c) 1990- 1993, 1996 Open Software Foundation, Inc., Copyright (c) 1991-2022 Unicode, Inc., Copyright (c) 1995-2022 Jean-loup Gailly and Mark Adler, Copyright (c) 1998 Microsoft. To, Copyright (c) 1999 Lucent Technologies, Copyright (c) 2004-2006 Intel Corporation, Copyright (c) 2005-2007, Nick Galbreath, Copyright (c) 2005-2020 Rich Felker, Copyright (c) 2006 Jb Evain (jbevain@gmail.com), Copyright (c) 2007 James Newton-King, Copyright (c) 2008-2016, Wojciech Mula, Copyright (c) 2008-2020 Advanced Micro Devices, Inc., Copyright (c) 2009, 2010, 2013-2016 by the Brotli Authors, Copyright (c) 2011 Novell, Inc (http://www.novell.com), Copyright (c) 2011-2015 Intel Corporation, Copyright (c) 2011-2020 Microsoft Corp, Copyright (c) 2011, Google Inc., Copyright (c) 2012 - present, Victor Zverovich, Copyright (c) 2012-2021 Yann Collet, Copyright (c) 2013-2017, Alfred Klomp, Copyright (c) 2013-2017, Milosz Krajewski, Copyright (c) 2014 Ryan Juckett http://www.ryanjuckett.com, Copyright (c) 2015 The Chromium Authors, Copyright (c) 2015 THL A29 Limited, a Tencent company, and Milo Yip, Copyright (c) 2015 Xamarin, Inc (http://www.xamarin.com), Copyright (c) 2015-2017, Wojciech Mula, Copyright (c) 2016-2017, Matthieu Darbois, Copyright (c) 2017 Yoshifumi Kawai, Copyright (c) 2018 Alexander Chermyanin, Copyright (c) 2019 Microsoft Corporation, Daan Leijen, Copyright (c) 2020 Dan Shechter, Copyright (c) 2020 Mara Bos \u003cm-ou.se@m-ou.se\u003e, Copyright (c) 2021 csFastFloat authors, Copyright (c) 2022, Geoff Langdale, Copyright (c) 2022, Wojciech Mula, Copyright (c) Andrew Arnott, Copyright (c) Microsoft Corporation, Copyright (c) Six Labors, Copyright (c) The Internet Society (2003), Copyright (c) The Internet Society 1997, Copyright (c) YEAR W3C(r) (MIT, ERCIM, Keio, Beihang). Disclaimers, Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018 The Regents of the University of California, Copyright 2012 the V8 project authors, Copyright 2018 Daniel Lemire, Copyright 2019 LLVM Project, Portions (c) International Organization", + "externalRefs": [ + { + "referenceCategory": "PACKAGE-MANAGER", + "referenceType": "purl", + "referenceLocator": "pkg:nuget/Microsoft.Extensions.Options@8.0.2" + } + ] + }, + { + "name": "Microsoft.Extensions.FileSystemGlobbing", + "SPDXID": "SPDXRef-nuget-Microsoft.Extensions.FileSystemGlobbing-8.0.0-df8146", + "versionInfo": "8.0.0", + "downloadLocation": "NOASSERTION", + "filesAnalyzed": false, + "licenseConcluded": "MIT", + "copyrightText": "(c) 1997-2005 Sean Eron Anderson, (c) Microsoft Corporation, Copyright (c) .NET Foundation, Copyright (c) .NET Foundation and Contributors, Copyright (c) .NET Foundation Contributors, Copyright (c) 1980, 1986, 1993 The Regents of the University of California, Copyright (c) 1989 by Hewlett-Packard Company, Palo Alto, Ca. \u0026 Digital Equipment Corporation, Maynard, Mass, Copyright (c) 1990- 1993, 1996 Open Software Foundation, Inc., Copyright (c) 1991-2022 Unicode, Inc., Copyright (c) 1995-2022 Jean-loup Gailly and Mark Adler, Copyright (c) 1998 Microsoft, Copyright (c) 1998 Microsoft. To, Copyright (c) 1999 Lucent Technologies, Copyright (c) 2004-2006 Intel Corporation, Copyright (c) 2005-2007, Nick Galbreath, Copyright (c) 2005-2020 Rich Felker, Copyright (c) 2006 Jb Evain (jbevain@gmail.com), Copyright (c) 2007 James Newton-King, Copyright (c) 2008-2016, Wojciech Mula, Copyright (c) 2008-2020 Advanced Micro Devices, Inc., Copyright (c) 2009, 2010, 2013-2016 by the Brotli Authors, Copyright (c) 2011 Novell, Inc (http://www.novell.com), Copyright (c) 2011-2015 Intel Corporation, Copyright (c) 2011-2020 Microsoft Corp, Copyright (c) 2011, Google Inc., Copyright (c) 2012 - present, Victor Zverovich, Copyright (c) 2012-2021 Yann Collet, Copyright (c) 2013-2017, Alfred Klomp, Copyright (c) 2013-2017, Milosz Krajewski, Copyright (c) 2014 Ryan Juckett http://www.ryanjuckett.com, Copyright (c) 2015 The Chromium Authors, Copyright (c) 2015 THL A29 Limited, a Tencent company, and Milo Yip, Copyright (c) 2015 Xamarin, Inc (http://www.xamarin.com), Copyright (c) 2015-2017, Wojciech Mula, Copyright (c) 2016-2017, Matthieu Darbois, Copyright (c) 2017 Yoshifumi Kawai, Copyright (c) 2018 Alexander Chermyanin, Copyright (c) 2019 Microsoft Corporation, Daan Leijen, Copyright (c) 2020 Dan Shechter, Copyright (c) 2020 Mara Bos \u003cm-ou.se@m-ou.se\u003e, Copyright (c) 2021, Copyright (c) 2021 csFastFloat authors, Copyright (c) 2022, Geoff Langdale, Copyright (c) 2022, Wojciech Mula, Copyright (c) Andrew Arnott, Copyright (c) Microsoft Corporation, Copyright (c) Six Labors, Copyright (c) The Internet Society (2003), Copyright (c) The Internet Society 1997, Copyright (c) YEAR W3C(r) (MIT, ERCIM, Keio, Beihang) Disclaimers, Copyright (c) YEAR W3C(r) (MIT, ERCIM, Keio, Beihang). Disclaimers, Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018 The Regents of the University of California, Copyright 2012 the V8 project authors, Copyright 2018 Daniel Lemire, Copyright 2019 LLVM Project, Portions (c) International Organization, Portions (c) International Organization for Standardization 1986", + "externalRefs": [ + { + "referenceCategory": "PACKAGE-MANAGER", + "referenceType": "purl", + "referenceLocator": "pkg:nuget/Microsoft.Extensions.FileSystemGlobbing@8.0.0" + } + ] + }, + { + "name": "Microsoft.AspNetCore.Components.Forms", + "SPDXID": "SPDXRef-nuget-Microsoft.AspNetCore.Components.Forms-8.0.11-b3ce0c", + "versionInfo": "8.0.11", + "downloadLocation": "NOASSERTION", + "filesAnalyzed": false, + "licenseConcluded": "MIT", + "copyrightText": "(c) Microsoft Corporation, Copyright (c) .NET Foundation Contributors, Copyright (c) 1989, 1993 The Regents of the University of California, Copyright (c) 1990, 1993 The Regents of the University of California, Copyright (c) 1996-1998 John D. Polstra, Copyright (c) 1998 John D. Polstra, Copyright (c) 2000-2013 Julian Seward, Copyright (c) 2007 John Birrell (jb@freebsd.org), Copyright (c) 2011-2021 The Bootstrap Authors, Copyright (c) 2011-2021 Twitter, Inc., Copyright (c) 2013 - 2018 AngleSharp, Copyright (c) 2019-2023 The Bootstrap Authors", + "externalRefs": [ + { + "referenceCategory": "PACKAGE-MANAGER", + "referenceType": "purl", + "referenceLocator": "pkg:nuget/Microsoft.AspNetCore.Components.Forms@8.0.11" + } + ] + }, + { + "name": "Microsoft.AspNetCore.Components", + "SPDXID": "SPDXRef-nuget-Microsoft.AspNetCore.Components-8.0.15-d179a3", + "versionInfo": "8.0.15", + "downloadLocation": "NOASSERTION", + "filesAnalyzed": false, + "licenseConcluded": "MIT", + "copyrightText": "(c) Microsoft Corporation, Copyright (c) .NET Foundation Contributors, Copyright (c) 1989, 1993 The Regents of the University of California, Copyright (c) 1990, 1993 The Regents of the University of California, Copyright (c) 1996-1998 John D. Polstra, Copyright (c) 1998 John D. Polstra, Copyright (c) 2000-2013 Julian Seward, Copyright (c) 2007 John Birrell (jb@freebsd.org), Copyright (c) 2011-2021 The Bootstrap Authors, Copyright (c) 2011-2021 Twitter, Inc., Copyright (c) 2013 - 2018 AngleSharp, Copyright (c) 2019-2023 The Bootstrap Authors", + "externalRefs": [ + { + "referenceCategory": "PACKAGE-MANAGER", + "referenceType": "purl", + "referenceLocator": "pkg:nuget/Microsoft.AspNetCore.Components@8.0.15" + } + ] + }, + { + "name": "Microsoft.JSInterop.WebAssembly", + "SPDXID": "SPDXRef-nuget-Microsoft.JSInterop.WebAssembly-8.0.11-7d7f03", + "versionInfo": "8.0.11", + "downloadLocation": "NOASSERTION", + "filesAnalyzed": false, + "licenseConcluded": "MIT", + "copyrightText": "(c) Microsoft Corporation, Copyright (c) .NET Foundation Contributors, Copyright (c) 1989, 1993 The Regents of the University of California, Copyright (c) 1990, 1993 The Regents of the University of California, Copyright (c) 1996-1998 John D. Polstra, Copyright (c) 1998 John D. Polstra, Copyright (c) 2000-2013 Julian Seward, Copyright (c) 2007 John Birrell (jb@freebsd.org), Copyright (c) 2011-2021 The Bootstrap Authors, Copyright (c) 2011-2021 Twitter, Inc., Copyright (c) 2013 - 2018 AngleSharp, Copyright (c) 2019-2023 The Bootstrap Authors", + "externalRefs": [ + { + "referenceCategory": "PACKAGE-MANAGER", + "referenceType": "purl", + "referenceLocator": "pkg:nuget/Microsoft.JSInterop.WebAssembly@8.0.11" + } + ] + }, + { + "name": "PuppeteerSharp", + "SPDXID": "SPDXRef-nuget-PuppeteerSharp-20.2.2-21f7e5", + "versionInfo": "20.2.2", + "downloadLocation": "NOASSERTION", + "filesAnalyzed": false, + "licenseConcluded": "MIT", + "externalRefs": [ + { + "referenceCategory": "PACKAGE-MANAGER", + "referenceType": "purl", + "referenceLocator": "pkg:nuget/PuppeteerSharp@20.2.2" + } + ] + }, + { + "name": "Microsoft.Extensions.Primitives", + "SPDXID": "SPDXRef-nuget-Microsoft.Extensions.Primitives-8.0.0-7bb3ef", + "versionInfo": "8.0.0", + "downloadLocation": "NOASSERTION", + "filesAnalyzed": false, + "licenseConcluded": "MIT", + "copyrightText": "(c) 1997-2005 Sean Eron Anderson, (c) Microsoft Corporation, Copyright (c) .NET Foundation, Copyright (c) .NET Foundation and Contributors, Copyright (c) .NET Foundation Contributors, Copyright (c) 1980, 1986, 1993 The Regents of the University of California, Copyright (c) 1989 by Hewlett-Packard Company, Palo Alto, Ca. \u0026 Digital Equipment Corporation, Maynard, Mass, Copyright (c) 1990- 1993, 1996 Open Software Foundation, Inc., Copyright (c) 1991-2022 Unicode, Inc., Copyright (c) 1995-2022 Jean-loup Gailly and Mark Adler, Copyright (c) 1998 Microsoft. To, Copyright (c) 1999 Lucent Technologies, Copyright (c) 2004-2006 Intel Corporation, Copyright (c) 2005-2007, Nick Galbreath, Copyright (c) 2005-2020 Rich Felker, Copyright (c) 2006 Jb Evain (jbevain@gmail.com), Copyright (c) 2007 James Newton-King, Copyright (c) 2008-2016, Wojciech Mula, Copyright (c) 2008-2020 Advanced Micro Devices, Inc., Copyright (c) 2009, 2010, 2013-2016 by the Brotli Authors, Copyright (c) 2011 Novell, Inc (http://www.novell.com), Copyright (c) 2011-2015 Intel Corporation, Copyright (c) 2011-2020 Microsoft Corp, Copyright (c) 2011, Google Inc., Copyright (c) 2012 - present, Victor Zverovich, Copyright (c) 2012-2021 Yann Collet, Copyright (c) 2013-2017, Alfred Klomp, Copyright (c) 2013-2017, Milosz Krajewski, Copyright (c) 2014 Ryan Juckett http://www.ryanjuckett.com, Copyright (c) 2015 The Chromium Authors, Copyright (c) 2015 THL A29 Limited, a Tencent company, and Milo Yip, Copyright (c) 2015 Xamarin, Inc (http://www.xamarin.com), Copyright (c) 2015-2017, Wojciech Mula, Copyright (c) 2016-2017, Matthieu Darbois, Copyright (c) 2017 Yoshifumi Kawai, Copyright (c) 2018 Alexander Chermyanin, Copyright (c) 2019 Microsoft Corporation, Daan Leijen, Copyright (c) 2020 Dan Shechter, Copyright (c) 2020 Mara Bos \u003cm-ou.se@m-ou.se\u003e, Copyright (c) 2021 csFastFloat authors, Copyright (c) 2022, Geoff Langdale, Copyright (c) 2022, Wojciech Mula, Copyright (c) Andrew Arnott, Copyright (c) Microsoft Corporation, Copyright (c) Six Labors, Copyright (c) The Internet Society (2003), Copyright (c) The Internet Society 1997, Copyright (c) YEAR W3C(r) (MIT, ERCIM, Keio, Beihang). Disclaimers, Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018 The Regents of the University of California, Copyright 2012 the V8 project authors, Copyright 2018 Daniel Lemire, Copyright 2019 LLVM Project, Portions (c) International Organization", + "externalRefs": [ + { + "referenceCategory": "PACKAGE-MANAGER", + "referenceType": "purl", + "referenceLocator": "pkg:nuget/Microsoft.Extensions.Primitives@8.0.0" + } + ] + }, + { + "name": "Microsoft.ApplicationInsights", + "SPDXID": "SPDXRef-nuget-Microsoft.ApplicationInsights-2.23.0-92127e", + "versionInfo": "2.23.0", + "downloadLocation": "NOASSERTION", + "filesAnalyzed": false, + "licenseConcluded": "MIT", + "copyrightText": "(c) Microsoft Corporation", + "externalRefs": [ + { + "referenceCategory": "PACKAGE-MANAGER", + "referenceType": "purl", + "referenceLocator": "pkg:nuget/Microsoft.ApplicationInsights@2.23.0" + } + ] + }, + { + "name": "Microsoft.TestPlatform.TestHost", + "SPDXID": "SPDXRef-nuget-Microsoft.TestPlatform.TestHost-17.14.1-5a76b2", + "versionInfo": "17.14.1", + "downloadLocation": "NOASSERTION", + "filesAnalyzed": false, + "licenseConcluded": "MIT", + "copyrightText": "(c) Microsoft Corporation, Copyright (c) .NET Foundation and Contributors, Copyright (c) 2007 James Newton-King, Copyright (c) 2008 - 2011 Novell, Inc., Copyright (c) 2008 - 2015 Jb Evain, Copyright 1995-2022 Mark Adler", + "externalRefs": [ + { + "referenceCategory": "PACKAGE-MANAGER", + "referenceType": "purl", + "referenceLocator": "pkg:nuget/Microsoft.TestPlatform.TestHost@17.14.1" + } + ] + }, + { + "name": "System.Collections.Immutable", + "SPDXID": "SPDXRef-nuget-System.Collections.Immutable-8.0.0-00b56b", + "versionInfo": "8.0.0", + "downloadLocation": "NOASSERTION", + "filesAnalyzed": false, + "licenseConcluded": "MIT", + "copyrightText": "(c) 1997-2005 Sean Eron Anderson, (c) Microsoft Corporation, Copyright (c) .NET Foundation, Copyright (c) .NET Foundation and Contributors, Copyright (c) .NET Foundation Contributors, Copyright (c) 1980, 1986, 1993 The Regents of the University of California, Copyright (c) 1989 by Hewlett-Packard Company, Palo Alto, Ca. \u0026 Digital Equipment Corporation, Maynard, Mass, Copyright (c) 1990- 1993, 1996 Open Software Foundation, Inc., Copyright (c) 1991-2022 Unicode, Inc., Copyright (c) 1995-2022 Jean-loup Gailly and Mark Adler, Copyright (c) 1998 Microsoft, Copyright (c) 1998 Microsoft. To, Copyright (c) 1999 Lucent Technologies, Copyright (c) 2004-2006 Intel Corporation, Copyright (c) 2005-2007, Nick Galbreath, Copyright (c) 2005-2020 Rich Felker, Copyright (c) 2006 Jb Evain (jbevain@gmail.com), Copyright (c) 2007 James Newton-King, Copyright (c) 2008-2016, Wojciech Mula, Copyright (c) 2008-2020 Advanced Micro Devices, Inc., Copyright (c) 2009, 2010, 2013-2016 by the Brotli Authors, Copyright (c) 2011 Novell, Inc (http://www.novell.com), Copyright (c) 2011-2015 Intel Corporation, Copyright (c) 2011-2020 Microsoft Corp, Copyright (c) 2011, Google Inc., Copyright (c) 2012 - present, Victor Zverovich, Copyright (c) 2012-2021 Yann Collet, Copyright (c) 2013-2017, Alfred Klomp, Copyright (c) 2013-2017, Milosz Krajewski, Copyright (c) 2014 Ryan Juckett http://www.ryanjuckett.com, Copyright (c) 2015 The Chromium Authors, Copyright (c) 2015 THL A29 Limited, a Tencent company, and Milo Yip, Copyright (c) 2015 Xamarin, Inc (http://www.xamarin.com), Copyright (c) 2015-2017, Wojciech Mula, Copyright (c) 2016-2017, Matthieu Darbois, Copyright (c) 2017 Yoshifumi Kawai, Copyright (c) 2018 Alexander Chermyanin, Copyright (c) 2019 Microsoft Corporation, Daan Leijen, Copyright (c) 2020 Dan Shechter, Copyright (c) 2020 Mara Bos \u003cm-ou.se@m-ou.se\u003e, Copyright (c) 2021, Copyright (c) 2021 csFastFloat authors, Copyright (c) 2022, Geoff Langdale, Copyright (c) 2022, Wojciech Mula, Copyright (c) Andrew Arnott, Copyright (c) Microsoft Corporation, Copyright (c) Six Labors, Copyright (c) The Internet Society (2003), Copyright (c) The Internet Society 1997, Copyright (c) YEAR W3C(r) (MIT, ERCIM, Keio, Beihang) Disclaimers, Copyright (c) YEAR W3C(r) (MIT, ERCIM, Keio, Beihang). Disclaimers, Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018 The Regents of the University of California, Copyright 2012 the V8 project authors, Copyright 2018 Daniel Lemire, Copyright 2019 LLVM Project, Portions (c) International Organization, Portions (c) International Organization for Standardization 1986", + "externalRefs": [ + { + "referenceCategory": "PACKAGE-MANAGER", + "referenceType": "purl", + "referenceLocator": "pkg:nuget/System.Collections.Immutable@8.0.0" + } + ] + }, + { + "name": "Microsoft.Extensions.Configuration.Binder", + "SPDXID": "SPDXRef-nuget-Microsoft.Extensions.Configuration.Binder-8.0.2-bb6751", + "versionInfo": "8.0.2", + "downloadLocation": "NOASSERTION", + "filesAnalyzed": false, + "licenseConcluded": "MIT", + "copyrightText": "(c) 1997-2005 Sean Eron Anderson, (c) Microsoft Corporation, Copyright (c) .NET Foundation, Copyright (c) .NET Foundation and Contributors, Copyright (c) .NET Foundation Contributors, Copyright (c) 1980, 1986, 1993 The Regents of the University of California, Copyright (c) 1989 by Hewlett-Packard Company, Palo Alto, Ca. \u0026 Digital Equipment Corporation, Maynard, Mass, Copyright (c) 1990- 1993, 1996 Open Software Foundation, Inc., Copyright (c) 1991-2022 Unicode, Inc., Copyright (c) 1995-2022 Jean-loup Gailly and Mark Adler, Copyright (c) 1998 Microsoft. To, Copyright (c) 1999 Lucent Technologies, Copyright (c) 2004-2006 Intel Corporation, Copyright (c) 2005-2007, Nick Galbreath, Copyright (c) 2005-2020 Rich Felker, Copyright (c) 2006 Jb Evain (jbevain@gmail.com), Copyright (c) 2007 James Newton-King, Copyright (c) 2008-2016, Wojciech Mula, Copyright (c) 2008-2020 Advanced Micro Devices, Inc., Copyright (c) 2009, 2010, 2013-2016 by the Brotli Authors, Copyright (c) 2011 Novell, Inc (http://www.novell.com), Copyright (c) 2011-2015 Intel Corporation, Copyright (c) 2011-2020 Microsoft Corp, Copyright (c) 2011, Google Inc., Copyright (c) 2012 - present, Victor Zverovich, Copyright (c) 2012-2021 Yann Collet, Copyright (c) 2013-2017, Alfred Klomp, Copyright (c) 2013-2017, Milosz Krajewski, Copyright (c) 2014 Ryan Juckett http://www.ryanjuckett.com, Copyright (c) 2015 The Chromium Authors, Copyright (c) 2015 THL A29 Limited, a Tencent company, and Milo Yip, Copyright (c) 2015 Xamarin, Inc (http://www.xamarin.com), Copyright (c) 2015-2017, Wojciech Mula, Copyright (c) 2016-2017, Matthieu Darbois, Copyright (c) 2017 Yoshifumi Kawai, Copyright (c) 2018 Alexander Chermyanin, Copyright (c) 2019 Microsoft Corporation, Daan Leijen, Copyright (c) 2020 Dan Shechter, Copyright (c) 2020 Mara Bos \u003cm-ou.se@m-ou.se\u003e, Copyright (c) 2021 csFastFloat authors, Copyright (c) 2022, Geoff Langdale, Copyright (c) 2022, Wojciech Mula, Copyright (c) Andrew Arnott, Copyright (c) Microsoft Corporation, Copyright (c) Six Labors, Copyright (c) The Internet Society (2003), Copyright (c) The Internet Society 1997, Copyright (c) YEAR W3C(r) (MIT, ERCIM, Keio, Beihang). Disclaimers, Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018 The Regents of the University of California, Copyright 2012 the V8 project authors, Copyright 2018 Daniel Lemire, Copyright 2019 LLVM Project, Portions (c) International Organization", + "externalRefs": [ + { + "referenceCategory": "PACKAGE-MANAGER", + "referenceType": "purl", + "referenceLocator": "pkg:nuget/Microsoft.Extensions.Configuration.Binder@8.0.2" + } + ] + }, + { + "name": "Microsoft.Extensions.Logging.Abstractions", + "SPDXID": "SPDXRef-nuget-Microsoft.Extensions.Logging.Abstractions-8.0.3-f5387c", + "versionInfo": "8.0.3", + "downloadLocation": "NOASSERTION", + "filesAnalyzed": false, + "licenseConcluded": "MIT", + "copyrightText": "(c) 1997-2005 Sean Eron Anderson, (c) Microsoft Corporation, Copyright (c) .NET Foundation, Copyright (c) .NET Foundation and Contributors, Copyright (c) .NET Foundation Contributors, Copyright (c) 1980, 1986, 1993 The Regents of the University of California, Copyright (c) 1989 by Hewlett-Packard Company, Palo Alto, Ca. \u0026 Digital Equipment Corporation, Maynard, Mass, Copyright (c) 1990- 1993, 1996 Open Software Foundation, Inc., Copyright (c) 1991-2022 Unicode, Inc., Copyright (c) 1995-2022 Jean-loup Gailly and Mark Adler, Copyright (c) 1998 Microsoft, Copyright (c) 1999 Lucent Technologies, Copyright (c) 2004-2006 Intel Corporation, Copyright (c) 2005-2007, Nick Galbreath, Copyright (c) 2005-2020 Rich Felker, Copyright (c) 2006 Jb Evain (jbevain@gmail.com), Copyright (c) 2007 James Newton-King, Copyright (c) 2008-2016, Wojciech Mula, Copyright (c) 2008-2020 Advanced Micro Devices, Inc., Copyright (c) 2009, 2010, 2013-2016 by the Brotli Authors, Copyright (c) 2011 Novell, Inc (http://www.novell.com), Copyright (c) 2011-2015 Intel Corporation, Copyright (c) 2011-2020 Microsoft Corp, Copyright (c) 2011, Google Inc., Copyright (c) 2012 - present, Victor Zverovich, Copyright (c) 2012-2021 Yann Collet, Copyright (c) 2013-2017, Alfred Klomp, Copyright (c) 2013-2017, Milosz Krajewski, Copyright (c) 2014 Ryan Juckett http://www.ryanjuckett.com, Copyright (c) 2015 The Chromium Authors, Copyright (c) 2015 THL A29 Limited, a Tencent company, and Milo Yip, Copyright (c) 2015 Xamarin, Inc (http://www.xamarin.com), Copyright (c) 2015-2017, Wojciech Mula, Copyright (c) 2016-2017, Matthieu Darbois, Copyright (c) 2017 Yoshifumi Kawai, Copyright (c) 2018 Alexander Chermyanin, Copyright (c) 2019 Microsoft Corporation, Daan Leijen, Copyright (c) 2020 Dan Shechter, Copyright (c) 2020 Mara Bos \u003cm-ou.se@m-ou.se\u003e, Copyright (c) 2021, Copyright (c) 2022, Geoff Langdale, Copyright (c) 2022, Wojciech Mula, Copyright (c) Andrew Arnott, Copyright (c) Microsoft Corporation, Copyright (c) Six Labors, Copyright (c) The Internet Society (2003), Copyright (c) The Internet Society 1997, Copyright (c) YEAR W3C(r) (MIT, ERCIM, Keio, Beihang) Disclaimers, Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018 The Regents of the University of California, Copyright 2012 the V8 project authors, Copyright 2018 Daniel Lemire, Copyright 2019 LLVM Project, Portions (c) International Organization for Standardization 1986", + "externalRefs": [ + { + "referenceCategory": "PACKAGE-MANAGER", + "referenceType": "purl", + "referenceLocator": "pkg:nuget/Microsoft.Extensions.Logging.Abstractions@8.0.3" + } + ] + }, + { + "name": "AngleSharp.Diffing", + "SPDXID": "SPDXRef-nuget-AngleSharp.Diffing-1.0.0-08ab89", + "versionInfo": "1.0.0", + "downloadLocation": "NOASSERTION", + "filesAnalyzed": false, + "licenseConcluded": "MIT", + "externalRefs": [ + { + "referenceCategory": "PACKAGE-MANAGER", + "referenceType": "purl", + "referenceLocator": "pkg:nuget/AngleSharp.Diffing@1.0.0" + } + ] + }, + { + "name": "Microsoft.Extensions.FileProviders.Abstractions", + "SPDXID": "SPDXRef-nuget-Microsoft.Extensions.FileProviders.Abstractions-8.0.0-3e71db", + "versionInfo": "8.0.0", + "downloadLocation": "NOASSERTION", + "filesAnalyzed": false, + "licenseConcluded": "MIT", + "copyrightText": "(c) 1997-2005 Sean Eron Anderson, (c) Microsoft Corporation, Copyright (c) .NET Foundation, Copyright (c) .NET Foundation and Contributors, Copyright (c) .NET Foundation Contributors, Copyright (c) 1980, 1986, 1993 The Regents of the University of California, Copyright (c) 1989 by Hewlett-Packard Company, Palo Alto, Ca. \u0026 Digital Equipment Corporation, Maynard, Mass, Copyright (c) 1990- 1993, 1996 Open Software Foundation, Inc., Copyright (c) 1991-2022 Unicode, Inc., Copyright (c) 1995-2022 Jean-loup Gailly and Mark Adler, Copyright (c) 1998 Microsoft, Copyright (c) 1998 Microsoft. To, Copyright (c) 1999 Lucent Technologies, Copyright (c) 2004-2006 Intel Corporation, Copyright (c) 2005-2007, Nick Galbreath, Copyright (c) 2005-2020 Rich Felker, Copyright (c) 2006 Jb Evain (jbevain@gmail.com), Copyright (c) 2007 James Newton-King, Copyright (c) 2008-2016, Wojciech Mula, Copyright (c) 2008-2020 Advanced Micro Devices, Inc., Copyright (c) 2009, 2010, 2013-2016 by the Brotli Authors, Copyright (c) 2011 Novell, Inc (http://www.novell.com), Copyright (c) 2011-2015 Intel Corporation, Copyright (c) 2011-2020 Microsoft Corp, Copyright (c) 2011, Google Inc., Copyright (c) 2012 - present, Victor Zverovich, Copyright (c) 2012-2021 Yann Collet, Copyright (c) 2013-2017, Alfred Klomp, Copyright (c) 2013-2017, Milosz Krajewski, Copyright (c) 2014 Ryan Juckett http://www.ryanjuckett.com, Copyright (c) 2015 The Chromium Authors, Copyright (c) 2015 THL A29 Limited, a Tencent company, and Milo Yip, Copyright (c) 2015 Xamarin, Inc (http://www.xamarin.com), Copyright (c) 2015-2017, Wojciech Mula, Copyright (c) 2016-2017, Matthieu Darbois, Copyright (c) 2017 Yoshifumi Kawai, Copyright (c) 2018 Alexander Chermyanin, Copyright (c) 2019 Microsoft Corporation, Daan Leijen, Copyright (c) 2020 Dan Shechter, Copyright (c) 2020 Mara Bos \u003cm-ou.se@m-ou.se\u003e, Copyright (c) 2021, Copyright (c) 2021 csFastFloat authors, Copyright (c) 2022, Geoff Langdale, Copyright (c) 2022, Wojciech Mula, Copyright (c) Andrew Arnott, Copyright (c) Microsoft Corporation, Copyright (c) Six Labors, Copyright (c) The Internet Society (2003), Copyright (c) The Internet Society 1997, Copyright (c) YEAR W3C(r) (MIT, ERCIM, Keio, Beihang) Disclaimers, Copyright (c) YEAR W3C(r) (MIT, ERCIM, Keio, Beihang). Disclaimers, Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018 The Regents of the University of California, Copyright 2012 the V8 project authors, Copyright 2018 Daniel Lemire, Copyright 2019 LLVM Project, Portions (c) International Organization, Portions (c) International Organization for Standardization 1986", + "externalRefs": [ + { + "referenceCategory": "PACKAGE-MANAGER", + "referenceType": "purl", + "referenceLocator": "pkg:nuget/Microsoft.Extensions.FileProviders.Abstractions@8.0.0" + } + ] + }, + { + "name": "NUnit", + "SPDXID": "SPDXRef-nuget-NUnit-4.4.0-d51504", + "versionInfo": "4.4.0", + "downloadLocation": "NOASSERTION", + "filesAnalyzed": false, + "licenseConcluded": "MIT AND zlib-acknowledgement", + "copyrightText": "Copyright (c) 2000-2002 Philip A. Craig, Copyright (c) 2002-2004 James W. Newkirk, Michael C. Two, Alexei A. Vorontsov, Copyright (c) 2002-2014 Charlie Poole, Copyright (c) 2008 Jonathan Pryor, Novell, Copyright (c) 2024 Charlie Poole, Rob Prouse, Copyright (c) Charlie Poole, Rob Prouse and Contributors, WCopyright (c) Charlie Poole, Rob Prouse and Contributors", + "externalRefs": [ + { + "referenceCategory": "PACKAGE-MANAGER", + "referenceType": "purl", + "referenceLocator": "pkg:nuget/NUnit@4.4.0" + } + ] + }, + { + "name": "Microsoft.Extensions.DependencyInjection.Abstractions", + "SPDXID": "SPDXRef-nuget-Microsoft.Extensions.DependencyInjection.Abstractions-8.0.2-5a630c", + "versionInfo": "8.0.2", + "downloadLocation": "NOASSERTION", + "filesAnalyzed": false, + "licenseConcluded": "MIT", + "copyrightText": "(c) 1997-2005 Sean Eron Anderson, (c) Microsoft Corporation, Copyright (c) .NET Foundation, Copyright (c) .NET Foundation and Contributors, Copyright (c) .NET Foundation Contributors, Copyright (c) 1980, 1986, 1993 The Regents of the University of California, Copyright (c) 1989 by Hewlett-Packard Company, Palo Alto, Ca. \u0026 Digital Equipment Corporation, Maynard, Mass, Copyright (c) 1990- 1993, 1996 Open Software Foundation, Inc., Copyright (c) 1991-2022 Unicode, Inc., Copyright (c) 1995-2022 Jean-loup Gailly and Mark Adler, Copyright (c) 1998 Microsoft. To, Copyright (c) 1999 Lucent Technologies, Copyright (c) 2004-2006 Intel Corporation, Copyright (c) 2005-2007, Nick Galbreath, Copyright (c) 2005-2020 Rich Felker, Copyright (c) 2006 Jb Evain (jbevain@gmail.com), Copyright (c) 2007 James Newton-King, Copyright (c) 2008-2016, Wojciech Mula, Copyright (c) 2008-2020 Advanced Micro Devices, Inc., Copyright (c) 2009, 2010, 2013-2016 by the Brotli Authors, Copyright (c) 2011 Novell, Inc (http://www.novell.com), Copyright (c) 2011-2015 Intel Corporation, Copyright (c) 2011-2020 Microsoft Corp, Copyright (c) 2011, Google Inc., Copyright (c) 2012 - present, Victor Zverovich, Copyright (c) 2012-2021 Yann Collet, Copyright (c) 2013-2017, Alfred Klomp, Copyright (c) 2013-2017, Milosz Krajewski, Copyright (c) 2014 Ryan Juckett http://www.ryanjuckett.com, Copyright (c) 2015 The Chromium Authors, Copyright (c) 2015 THL A29 Limited, a Tencent company, and Milo Yip, Copyright (c) 2015 Xamarin, Inc (http://www.xamarin.com), Copyright (c) 2015-2017, Wojciech Mula, Copyright (c) 2016-2017, Matthieu Darbois, Copyright (c) 2017 Yoshifumi Kawai, Copyright (c) 2018 Alexander Chermyanin, Copyright (c) 2019 Microsoft Corporation, Daan Leijen, Copyright (c) 2020 Dan Shechter, Copyright (c) 2020 Mara Bos \u003cm-ou.se@m-ou.se\u003e, Copyright (c) 2021 csFastFloat authors, Copyright (c) 2022, Geoff Langdale, Copyright (c) 2022, Wojciech Mula, Copyright (c) Andrew Arnott, Copyright (c) Microsoft Corporation, Copyright (c) Six Labors, Copyright (c) The Internet Society (2003), Copyright (c) The Internet Society 1997, Copyright (c) YEAR W3C(r) (MIT, ERCIM, Keio, Beihang). Disclaimers, Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018 The Regents of the University of California, Copyright 2012 the V8 project authors, Copyright 2018 Daniel Lemire, Copyright 2019 LLVM Project, Portions (c) International Organization", + "externalRefs": [ + { + "referenceCategory": "PACKAGE-MANAGER", + "referenceType": "purl", + "referenceLocator": "pkg:nuget/Microsoft.Extensions.DependencyInjection.Abstractions@8.0.2" + } + ] + }, + { + "name": "Microsoft.TestPlatform.AdapterUtilities", + "SPDXID": "SPDXRef-nuget-Microsoft.TestPlatform.AdapterUtilities-17.13.0-22a1b0", + "versionInfo": "17.13.0", + "downloadLocation": "NOASSERTION", + "filesAnalyzed": false, + "licenseConcluded": "MIT", + "copyrightText": "(c) Microsoft Corporation", + "externalRefs": [ + { + "referenceCategory": "PACKAGE-MANAGER", + "referenceType": "purl", + "referenceLocator": "pkg:nuget/Microsoft.TestPlatform.AdapterUtilities@17.13.0" + } + ] + }, + { + "name": "Microsoft.AspNetCore.Authorization", + "SPDXID": "SPDXRef-nuget-Microsoft.AspNetCore.Authorization-8.0.15-457dff", + "versionInfo": "8.0.15", + "downloadLocation": "NOASSERTION", + "filesAnalyzed": false, + "licenseConcluded": "MIT", + "copyrightText": "(c) Microsoft Corporation, Copyright (c) .NET Foundation and Contributors, Copyright (c) .NET Foundation Contributors, Copyright (c) 1989, 1993 The Regents of the University of California, Copyright (c) 1990, 1993 The Regents of the University of California, Copyright (c) 1996-1998 John D. Polstra, Copyright (c) 1998 John D. Polstra, Copyright (c) 2000-2013 Julian Seward, Copyright (c) 2007 James Newton-King, Copyright (c) 2007 John Birrell (jb@freebsd.org), Copyright (c) 2010-2019 Google LLC. http://angular.io/license, Copyright (c) 2011 Alex MacCaw (info@eribium.org), Copyright (c) 2011 Nicolas Gallagher (nicolas@nicolasgallagher.com), Copyright (c) 2011-2021 The Bootstrap Authors, Copyright (c) 2011-2021 Twitter, Inc., Copyright (c) 2013 - 2018 AngleSharp, Copyright (c) 2013-2017, Milosz Krajewski, Copyright (c) 2014-2018 Michael Daines, Copyright (c) 2015, Google Inc., Copyright (c) 2016 Richard Morris, Copyright (c) 2017 Yoshifumi Kawai, Copyright (c) 2019 David Fowler, Copyright (c) 2019-2020 West Wind Technologies, Copyright (c) 2019-2023 The Bootstrap Authors, Copyright (c) Andrew Arnott, Copyright (c) HTML5 Boilerplate, Copyright (c) Microsoft Corporation, Copyright (c) Nicolas Gallagher and Jonathan Neal, Copyright (c) Sindre Sorhus \u003csindresorhus@gmail.com\u003e (https://sindresorhus.com), Copyright 2019 The gRPC Authors, Copyright Jorn Zaefferer, Copyright OpenJS Foundation and other contributors, https://openjsf.org", + "externalRefs": [ + { + "referenceCategory": "PACKAGE-MANAGER", + "referenceType": "purl", + "referenceLocator": "pkg:nuget/Microsoft.AspNetCore.Authorization@8.0.15" + } + ] + }, + { + "name": "Microsoft.Testing.Platform", + "SPDXID": "SPDXRef-nuget-Microsoft.Testing.Platform-1.7.3-984f53", + "versionInfo": "1.7.3", + "downloadLocation": "NOASSERTION", + "filesAnalyzed": false, + "licenseConcluded": "MIT", + "copyrightText": "(c) Microsoft Corporation", + "externalRefs": [ + { + "referenceCategory": "PACKAGE-MANAGER", + "referenceType": "purl", + "referenceLocator": "pkg:nuget/Microsoft.Testing.Platform@1.7.3" + } + ] + }, + { + "name": "Microsoft.IdentityModel.Tokens", + "SPDXID": "SPDXRef-nuget-Microsoft.IdentityModel.Tokens-8.14.0-a883d6", + "versionInfo": "8.14.0", + "downloadLocation": "NOASSERTION", + "filesAnalyzed": false, + "licenseConcluded": "MIT", + "copyrightText": "(c) Microsoft Corporation, Copyright (c) Microsoft Corporation", + "externalRefs": [ + { + "referenceCategory": "PACKAGE-MANAGER", + "referenceType": "purl", + "referenceLocator": "pkg:nuget/Microsoft.IdentityModel.Tokens@8.14.0" + } + ] + }, + { + "name": "AngleSharp.Css", + "SPDXID": "SPDXRef-nuget-AngleSharp.Css-1.0.0-beta.154-30e617", + "versionInfo": "1.0.0-beta.154", + "downloadLocation": "NOASSERTION", + "filesAnalyzed": false, + "licenseConcluded": "LicenseRef-scancode-unknown-license-reference AND MIT", + "copyrightText": "Copyright 2016-2025, AngleSharp, Copyright AngleSharp, 2013-2019", + "externalRefs": [ + { + "referenceCategory": "PACKAGE-MANAGER", + "referenceType": "purl", + "referenceLocator": "pkg:nuget/AngleSharp.Css@1.0.0-beta.154" + } + ] + }, + { + "name": "Microsoft.Extensions.Configuration.FileExtensions", + "SPDXID": "SPDXRef-nuget-Microsoft.Extensions.Configuration.FileExtensions-8.0.1-6b3a2e", + "versionInfo": "8.0.1", + "downloadLocation": "NOASSERTION", + "filesAnalyzed": false, + "licenseConcluded": "MIT", + "copyrightText": "(c) 1997-2005 Sean Eron Anderson, (c) Microsoft Corporation, Copyright (c) .NET Foundation, Copyright (c) .NET Foundation and Contributors, Copyright (c) .NET Foundation Contributors, Copyright (c) 1980, 1986, 1993 The Regents of the University of California, Copyright (c) 1989 by Hewlett-Packard Company, Palo Alto, Ca. \u0026 Digital Equipment Corporation, Maynard, Mass, Copyright (c) 1990- 1993, 1996 Open Software Foundation, Inc., Copyright (c) 1991-2022 Unicode, Inc., Copyright (c) 1995-2022 Jean-loup Gailly and Mark Adler, Copyright (c) 1998 Microsoft. To, Copyright (c) 1999 Lucent Technologies, Copyright (c) 2004-2006 Intel Corporation, Copyright (c) 2005-2007, Nick Galbreath, Copyright (c) 2005-2020 Rich Felker, Copyright (c) 2006 Jb Evain (jbevain@gmail.com), Copyright (c) 2007 James Newton-King, Copyright (c) 2008-2016, Wojciech Mula, Copyright (c) 2008-2020 Advanced Micro Devices, Inc., Copyright (c) 2009, 2010, 2013-2016 by the Brotli Authors, Copyright (c) 2011 Novell, Inc (http://www.novell.com), Copyright (c) 2011-2015 Intel Corporation, Copyright (c) 2011-2020 Microsoft Corp, Copyright (c) 2011, Google Inc., Copyright (c) 2012 - present, Victor Zverovich, Copyright (c) 2012-2021 Yann Collet, Copyright (c) 2013-2017, Alfred Klomp, Copyright (c) 2013-2017, Milosz Krajewski, Copyright (c) 2014 Ryan Juckett http://www.ryanjuckett.com, Copyright (c) 2015 The Chromium Authors, Copyright (c) 2015 THL A29 Limited, a Tencent company, and Milo Yip, Copyright (c) 2015 Xamarin, Inc (http://www.xamarin.com), Copyright (c) 2015-2017, Wojciech Mula, Copyright (c) 2016-2017, Matthieu Darbois, Copyright (c) 2017 Yoshifumi Kawai, Copyright (c) 2018 Alexander Chermyanin, Copyright (c) 2019 Microsoft Corporation, Daan Leijen, Copyright (c) 2020 Dan Shechter, Copyright (c) 2020 Mara Bos \u003cm-ou.se@m-ou.se\u003e, Copyright (c) 2021 csFastFloat authors, Copyright (c) 2022, Geoff Langdale, Copyright (c) 2022, Wojciech Mula, Copyright (c) Andrew Arnott, Copyright (c) Microsoft Corporation, Copyright (c) Six Labors, Copyright (c) The Internet Society (2003), Copyright (c) The Internet Society 1997, Copyright (c) YEAR W3C(r) (MIT, ERCIM, Keio, Beihang). Disclaimers, Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018 The Regents of the University of California, Copyright 2012 the V8 project authors, Copyright 2018 Daniel Lemire, Copyright 2019 LLVM Project, Portions (c) International Organization", + "externalRefs": [ + { + "referenceCategory": "PACKAGE-MANAGER", + "referenceType": "purl", + "referenceLocator": "pkg:nuget/Microsoft.Extensions.Configuration.FileExtensions@8.0.1" + } + ] + }, + { + "name": "Microsoft.Extensions.FileProviders.Physical", + "SPDXID": "SPDXRef-nuget-Microsoft.Extensions.FileProviders.Physical-8.0.0-628894", + "versionInfo": "8.0.0", + "downloadLocation": "NOASSERTION", + "filesAnalyzed": false, + "licenseConcluded": "MIT", + "copyrightText": "(c) 1997-2005 Sean Eron Anderson, (c) Microsoft Corporation, Copyright (c) .NET Foundation, Copyright (c) .NET Foundation and Contributors, Copyright (c) .NET Foundation Contributors, Copyright (c) 1980, 1986, 1993 The Regents of the University of California, Copyright (c) 1989 by Hewlett-Packard Company, Palo Alto, Ca. \u0026 Digital Equipment Corporation, Maynard, Mass, Copyright (c) 1990- 1993, 1996 Open Software Foundation, Inc., Copyright (c) 1991-2022 Unicode, Inc., Copyright (c) 1995-2022 Jean-loup Gailly and Mark Adler, Copyright (c) 1998 Microsoft, Copyright (c) 1998 Microsoft. To, Copyright (c) 1999 Lucent Technologies, Copyright (c) 2004-2006 Intel Corporation, Copyright (c) 2005-2007, Nick Galbreath, Copyright (c) 2005-2020 Rich Felker, Copyright (c) 2006 Jb Evain (jbevain@gmail.com), Copyright (c) 2007 James Newton-King, Copyright (c) 2008-2016, Wojciech Mula, Copyright (c) 2008-2020 Advanced Micro Devices, Inc., Copyright (c) 2009, 2010, 2013-2016 by the Brotli Authors, Copyright (c) 2011 Novell, Inc (http://www.novell.com), Copyright (c) 2011-2015 Intel Corporation, Copyright (c) 2011-2020 Microsoft Corp, Copyright (c) 2011, Google Inc., Copyright (c) 2012 - present, Victor Zverovich, Copyright (c) 2012-2021 Yann Collet, Copyright (c) 2013-2017, Alfred Klomp, Copyright (c) 2013-2017, Milosz Krajewski, Copyright (c) 2014 Ryan Juckett http://www.ryanjuckett.com, Copyright (c) 2015 The Chromium Authors, Copyright (c) 2015 THL A29 Limited, a Tencent company, and Milo Yip, Copyright (c) 2015 Xamarin, Inc (http://www.xamarin.com), Copyright (c) 2015-2017, Wojciech Mula, Copyright (c) 2016-2017, Matthieu Darbois, Copyright (c) 2017 Yoshifumi Kawai, Copyright (c) 2018 Alexander Chermyanin, Copyright (c) 2019 Microsoft Corporation, Daan Leijen, Copyright (c) 2020 Dan Shechter, Copyright (c) 2020 Mara Bos \u003cm-ou.se@m-ou.se\u003e, Copyright (c) 2021, Copyright (c) 2021 csFastFloat authors, Copyright (c) 2022, Geoff Langdale, Copyright (c) 2022, Wojciech Mula, Copyright (c) Andrew Arnott, Copyright (c) Microsoft Corporation, Copyright (c) Six Labors, Copyright (c) The Internet Society (2003), Copyright (c) The Internet Society 1997, Copyright (c) YEAR W3C(r) (MIT, ERCIM, Keio, Beihang) Disclaimers, Copyright (c) YEAR W3C(r) (MIT, ERCIM, Keio, Beihang). Disclaimers, Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018 The Regents of the University of California, Copyright 2012 the V8 project authors, Copyright 2018 Daniel Lemire, Copyright 2019 LLVM Project, Portions (c) International Organization, Portions (c) International Organization for Standardization 1986", + "externalRefs": [ + { + "referenceCategory": "PACKAGE-MANAGER", + "referenceType": "purl", + "referenceLocator": "pkg:nuget/Microsoft.Extensions.FileProviders.Physical@8.0.0" + } + ] + }, + { + "name": "Microsoft.IdentityModel.Abstractions", + "SPDXID": "SPDXRef-nuget-Microsoft.IdentityModel.Abstractions-8.14.0-6e2c7d", + "versionInfo": "8.14.0", + "downloadLocation": "NOASSERTION", + "filesAnalyzed": false, + "licenseConcluded": "MIT", + "copyrightText": "(c) Microsoft Corporation, Copyright (c) Microsoft Corporation", + "externalRefs": [ + { + "referenceCategory": "PACKAGE-MANAGER", + "referenceType": "purl", + "referenceLocator": "pkg:nuget/Microsoft.IdentityModel.Abstractions@8.14.0" + } + ] + }, + { + "name": "Newtonsoft.Json", + "SPDXID": "SPDXRef-nuget-Newtonsoft.Json-13.0.3-7c98bf", + "versionInfo": "13.0.3", + "downloadLocation": "NOASSERTION", + "filesAnalyzed": false, + "licenseConcluded": "MIT", + "copyrightText": "Copyright (c) 2007 James Newton-King, Copyright (c) James Newton-King 2008, Copyright James Newton-King 2008, Copyright James Newton-King 2008 Json.NET", + "externalRefs": [ + { + "referenceCategory": "PACKAGE-MANAGER", + "referenceType": "purl", + "referenceLocator": "pkg:nuget/Newtonsoft.Json@13.0.3" + } + ] + }, + { + "name": "Microsoft.Extensions.DependencyInjection", + "SPDXID": "SPDXRef-nuget-Microsoft.Extensions.DependencyInjection-8.0.1-276050", + "versionInfo": "8.0.1", + "downloadLocation": "NOASSERTION", + "filesAnalyzed": false, + "licenseConcluded": "MIT", + "copyrightText": "(c) 1997-2005 Sean Eron Anderson, (c) Microsoft Corporation, Copyright (c) .NET Foundation, Copyright (c) .NET Foundation and Contributors, Copyright (c) .NET Foundation Contributors, Copyright (c) 1980, 1986, 1993 The Regents of the University of California, Copyright (c) 1989 by Hewlett-Packard Company, Palo Alto, Ca. \u0026 Digital Equipment Corporation, Maynard, Mass, Copyright (c) 1990- 1993, 1996 Open Software Foundation, Inc., Copyright (c) 1991-2022 Unicode, Inc., Copyright (c) 1995-2022 Jean-loup Gailly and Mark Adler, Copyright (c) 1998 Microsoft. To, Copyright (c) 1999 Lucent Technologies, Copyright (c) 2004-2006 Intel Corporation, Copyright (c) 2005-2007, Nick Galbreath, Copyright (c) 2005-2020 Rich Felker, Copyright (c) 2006 Jb Evain (jbevain@gmail.com), Copyright (c) 2007 James Newton-King, Copyright (c) 2008-2016, Wojciech Mula, Copyright (c) 2008-2020 Advanced Micro Devices, Inc., Copyright (c) 2009, 2010, 2013-2016 by the Brotli Authors, Copyright (c) 2011 Novell, Inc (http://www.novell.com), Copyright (c) 2011-2015 Intel Corporation, Copyright (c) 2011-2020 Microsoft Corp, Copyright (c) 2011, Google Inc., Copyright (c) 2012 - present, Victor Zverovich, Copyright (c) 2012-2021 Yann Collet, Copyright (c) 2013-2017, Alfred Klomp, Copyright (c) 2013-2017, Milosz Krajewski, Copyright (c) 2014 Ryan Juckett http://www.ryanjuckett.com, Copyright (c) 2015 The Chromium Authors, Copyright (c) 2015 THL A29 Limited, a Tencent company, and Milo Yip, Copyright (c) 2015 Xamarin, Inc (http://www.xamarin.com), Copyright (c) 2015-2017, Wojciech Mula, Copyright (c) 2016-2017, Matthieu Darbois, Copyright (c) 2017 Yoshifumi Kawai, Copyright (c) 2018 Alexander Chermyanin, Copyright (c) 2019 Microsoft Corporation, Daan Leijen, Copyright (c) 2020 Dan Shechter, Copyright (c) 2020 Mara Bos \u003cm-ou.se@m-ou.se\u003e, Copyright (c) 2021 csFastFloat authors, Copyright (c) 2022, Geoff Langdale, Copyright (c) 2022, Wojciech Mula, Copyright (c) Andrew Arnott, Copyright (c) Microsoft Corporation, Copyright (c) Six Labors, Copyright (c) The Internet Society (2003), Copyright (c) The Internet Society 1997, Copyright (c) YEAR W3C(r) (MIT, ERCIM, Keio, Beihang). Disclaimers, Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018 The Regents of the University of California, Copyright 2012 the V8 project authors, Copyright 2018 Daniel Lemire, Copyright 2019 LLVM Project, Portions (c) International Organization", + "externalRefs": [ + { + "referenceCategory": "PACKAGE-MANAGER", + "referenceType": "purl", + "referenceLocator": "pkg:nuget/Microsoft.Extensions.DependencyInjection@8.0.1" + } + ] + }, + { + "name": "bunit.web", + "SPDXID": "SPDXRef-nuget-bunit.web-1.40.0-b4ac35", + "versionInfo": "1.40.0", + "downloadLocation": "NOASSERTION", + "filesAnalyzed": false, + "licenseConcluded": "MIT", + "copyrightText": "Copyright (c) .NET Foundation and Contributors", + "externalRefs": [ + { + "referenceCategory": "PACKAGE-MANAGER", + "referenceType": "purl", + "referenceLocator": "pkg:nuget/bunit.web@1.40.0" + } + ] + }, + { + "name": "bunit", + "SPDXID": "SPDXRef-nuget-bunit-1.40.0-4dce12", + "versionInfo": "1.40.0", + "downloadLocation": "NOASSERTION", + "filesAnalyzed": false, + "licenseConcluded": "MIT", + "copyrightText": "Copyright (c) .NET Foundation and Contributors", + "externalRefs": [ + { + "referenceCategory": "PACKAGE-MANAGER", + "referenceType": "purl", + "referenceLocator": "pkg:nuget/bunit@1.40.0" + } + ] + }, + { + "name": "Microsoft.Extensions.Configuration", + "SPDXID": "SPDXRef-nuget-Microsoft.Extensions.Configuration-8.0.0-dce331", + "versionInfo": "8.0.0", + "downloadLocation": "NOASSERTION", + "filesAnalyzed": false, + "licenseConcluded": "MIT", + "copyrightText": "(c) 1997-2005 Sean Eron Anderson, (c) Microsoft Corporation, Copyright (c) .NET Foundation, Copyright (c) .NET Foundation and Contributors, Copyright (c) .NET Foundation Contributors, Copyright (c) 1980, 1986, 1993 The Regents of the University of California, Copyright (c) 1989 by Hewlett-Packard Company, Palo Alto, Ca. \u0026 Digital Equipment Corporation, Maynard, Mass, Copyright (c) 1990- 1993, 1996 Open Software Foundation, Inc., Copyright (c) 1991-2022 Unicode, Inc., Copyright (c) 1995-2022 Jean-loup Gailly and Mark Adler, Copyright (c) 1998 Microsoft. To, Copyright (c) 1999 Lucent Technologies, Copyright (c) 2004-2006 Intel Corporation, Copyright (c) 2005-2007, Nick Galbreath, Copyright (c) 2005-2020 Rich Felker, Copyright (c) 2006 Jb Evain (jbevain@gmail.com), Copyright (c) 2007 James Newton-King, Copyright (c) 2008-2016, Wojciech Mula, Copyright (c) 2008-2020 Advanced Micro Devices, Inc., Copyright (c) 2009, 2010, 2013-2016 by the Brotli Authors, Copyright (c) 2011 Novell, Inc (http://www.novell.com), Copyright (c) 2011-2015 Intel Corporation, Copyright (c) 2011-2020 Microsoft Corp, Copyright (c) 2011, Google Inc., Copyright (c) 2012 - present, Victor Zverovich, Copyright (c) 2012-2021 Yann Collet, Copyright (c) 2013-2017, Alfred Klomp, Copyright (c) 2013-2017, Milosz Krajewski, Copyright (c) 2014 Ryan Juckett http://www.ryanjuckett.com, Copyright (c) 2015 The Chromium Authors, Copyright (c) 2015 THL A29 Limited, a Tencent company, and Milo Yip, Copyright (c) 2015 Xamarin, Inc (http://www.xamarin.com), Copyright (c) 2015-2017, Wojciech Mula, Copyright (c) 2016-2017, Matthieu Darbois, Copyright (c) 2017 Yoshifumi Kawai, Copyright (c) 2018 Alexander Chermyanin, Copyright (c) 2019 Microsoft Corporation, Daan Leijen, Copyright (c) 2020 Dan Shechter, Copyright (c) 2020 Mara Bos \u003cm-ou.se@m-ou.se\u003e, Copyright (c) 2021 csFastFloat authors, Copyright (c) 2022, Geoff Langdale, Copyright (c) 2022, Wojciech Mula, Copyright (c) Andrew Arnott, Copyright (c) Microsoft Corporation, Copyright (c) Six Labors, Copyright (c) The Internet Society (2003), Copyright (c) The Internet Society 1997, Copyright (c) YEAR W3C(r) (MIT, ERCIM, Keio, Beihang). Disclaimers, Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018 The Regents of the University of California, Copyright 2012 the V8 project authors, Copyright 2018 Daniel Lemire, Copyright 2019 LLVM Project, Portions (c) International Organization", + "externalRefs": [ + { + "referenceCategory": "PACKAGE-MANAGER", + "referenceType": "purl", + "referenceLocator": "pkg:nuget/Microsoft.Extensions.Configuration@8.0.0" + } + ] + }, + { + "name": "Microsoft.AspNetCore.Components.Authorization", + "SPDXID": "SPDXRef-nuget-Microsoft.AspNetCore.Components.Authorization-8.0.15-c2e5e2", + "versionInfo": "8.0.15", + "downloadLocation": "NOASSERTION", + "filesAnalyzed": false, + "licenseConcluded": "MIT", + "copyrightText": "(c) Microsoft Corporation, Copyright (c) .NET Foundation Contributors, Copyright (c) 1989, 1993 The Regents of the University of California, Copyright (c) 1990, 1993 The Regents of the University of California, Copyright (c) 1996-1998 John D. Polstra, Copyright (c) 1998 John D. Polstra, Copyright (c) 2000-2013 Julian Seward, Copyright (c) 2007 John Birrell (jb@freebsd.org), Copyright (c) 2011-2021 The Bootstrap Authors, Copyright (c) 2011-2021 Twitter, Inc., Copyright (c) 2013 - 2018 AngleSharp, Copyright (c) 2019-2023 The Bootstrap Authors", + "externalRefs": [ + { + "referenceCategory": "PACKAGE-MANAGER", + "referenceType": "purl", + "referenceLocator": "pkg:nuget/Microsoft.AspNetCore.Components.Authorization@8.0.15" + } + ] + }, + { + "name": "Microsoft.AspNetCore.Metadata", + "SPDXID": "SPDXRef-nuget-Microsoft.AspNetCore.Metadata-8.0.15-7088bb", + "versionInfo": "8.0.15", + "downloadLocation": "NOASSERTION", + "filesAnalyzed": false, + "licenseConcluded": "MIT", + "copyrightText": "(c) Microsoft Corporation, Copyright (c) .NET Foundation and Contributors, Copyright (c) .NET Foundation Contributors, Copyright (c) 1989, 1993 The Regents of the University of California, Copyright (c) 1990, 1993 The Regents of the University of California, Copyright (c) 1996-1998 John D. Polstra, Copyright (c) 1998 John D. Polstra, Copyright (c) 2000-2013 Julian Seward, Copyright (c) 2007 James Newton-King, Copyright (c) 2007 John Birrell (jb@freebsd.org), Copyright (c) 2010-2019 Google LLC. http://angular.io/license, Copyright (c) 2011 Alex MacCaw (info@eribium.org), Copyright (c) 2011 Nicolas Gallagher (nicolas@nicolasgallagher.com), Copyright (c) 2011-2021 The Bootstrap Authors, Copyright (c) 2011-2021 Twitter, Inc., Copyright (c) 2013 - 2018 AngleSharp, Copyright (c) 2013-2017, Milosz Krajewski, Copyright (c) 2014-2018 Michael Daines, Copyright (c) 2015, Google Inc., Copyright (c) 2016 Richard Morris, Copyright (c) 2017 Yoshifumi Kawai, Copyright (c) 2019 David Fowler, Copyright (c) 2019-2020 West Wind Technologies, Copyright (c) 2019-2023 The Bootstrap Authors, Copyright (c) Andrew Arnott, Copyright (c) HTML5 Boilerplate, Copyright (c) Microsoft Corporation, Copyright (c) Nicolas Gallagher and Jonathan Neal, Copyright (c) Sindre Sorhus \u003csindresorhus@gmail.com\u003e (https://sindresorhus.com), Copyright 2019 The gRPC Authors, Copyright Jorn Zaefferer, Copyright OpenJS Foundation and other contributors, https://openjsf.org", + "externalRefs": [ + { + "referenceCategory": "PACKAGE-MANAGER", + "referenceType": "purl", + "referenceLocator": "pkg:nuget/Microsoft.AspNetCore.Metadata@8.0.15" + } + ] + }, + { + "name": "Microsoft.Extensions.Caching.Memory", + "SPDXID": "SPDXRef-nuget-Microsoft.Extensions.Caching.Memory-8.0.1-24ebac", + "versionInfo": "8.0.1", + "downloadLocation": "NOASSERTION", + "filesAnalyzed": false, + "licenseConcluded": "MIT", + "copyrightText": "(c) 1997-2005 Sean Eron Anderson, (c) Microsoft Corporation, Copyright (c) .NET Foundation, Copyright (c) .NET Foundation and Contributors, Copyright (c) .NET Foundation Contributors, Copyright (c) 1980, 1986, 1993 The Regents of the University of California, Copyright (c) 1989 by Hewlett-Packard Company, Palo Alto, Ca. \u0026 Digital Equipment Corporation, Maynard, Mass, Copyright (c) 1990- 1993, 1996 Open Software Foundation, Inc., Copyright (c) 1991-2022 Unicode, Inc., Copyright (c) 1995-2022 Jean-loup Gailly and Mark Adler, Copyright (c) 1998 Microsoft, Copyright (c) 1998 Microsoft. To, Copyright (c) 1999 Lucent Technologies, Copyright (c) 2004-2006 Intel Corporation, Copyright (c) 2005-2007, Nick Galbreath, Copyright (c) 2005-2020 Rich Felker, Copyright (c) 2006 Jb Evain (jbevain@gmail.com), Copyright (c) 2007 James Newton-King, Copyright (c) 2008-2016, Wojciech Mula, Copyright (c) 2008-2020 Advanced Micro Devices, Inc., Copyright (c) 2009, 2010, 2013-2016 by the Brotli Authors, Copyright (c) 2011 Novell, Inc (http://www.novell.com), Copyright (c) 2011-2015 Intel Corporation, Copyright (c) 2011-2020 Microsoft Corp, Copyright (c) 2011, Google Inc., Copyright (c) 2012 - present, Victor Zverovich, Copyright (c) 2012-2021 Yann Collet, Copyright (c) 2013-2017, Alfred Klomp, Copyright (c) 2013-2017, Milosz Krajewski, Copyright (c) 2014 Ryan Juckett http://www.ryanjuckett.com, Copyright (c) 2015 The Chromium Authors, Copyright (c) 2015 THL A29 Limited, a Tencent company, and Milo Yip, Copyright (c) 2015 Xamarin, Inc (http://www.xamarin.com), Copyright (c) 2015-2017, Wojciech Mula, Copyright (c) 2016-2017, Matthieu Darbois, Copyright (c) 2017 Yoshifumi Kawai, Copyright (c) 2018 Alexander Chermyanin, Copyright (c) 2019 Microsoft Corporation, Daan Leijen, Copyright (c) 2020 Dan Shechter, Copyright (c) 2020 Mara Bos \u003cm-ou.se@m-ou.se\u003e, Copyright (c) 2021, Copyright (c) 2021 csFastFloat authors, Copyright (c) 2022, Geoff Langdale, Copyright (c) 2022, Wojciech Mula, Copyright (c) Andrew Arnott, Copyright (c) Microsoft Corporation, Copyright (c) Six Labors, Copyright (c) The Internet Society (2003), Copyright (c) The Internet Society 1997, Copyright (c) YEAR W3C(r) (MIT, ERCIM, Keio, Beihang) Disclaimers, Copyright (c) YEAR W3C(r) (MIT, ERCIM, Keio, Beihang). Disclaimers, Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018 The Regents of the University of California, Copyright 2012 the V8 project authors, Copyright 2018 Daniel Lemire, Copyright 2019 LLVM Project, Portions (c) International Organization, Portions (c) International Organization for Standardization 1986", + "externalRefs": [ + { + "referenceCategory": "PACKAGE-MANAGER", + "referenceType": "purl", + "referenceLocator": "pkg:nuget/Microsoft.Extensions.Caching.Memory@8.0.1" + } + ] + }, + { + "name": "Microsoft.IdentityModel.Logging", + "SPDXID": "SPDXRef-nuget-Microsoft.IdentityModel.Logging-8.14.0-44c2b4", + "versionInfo": "8.14.0", + "downloadLocation": "NOASSERTION", + "filesAnalyzed": false, + "licenseConcluded": "MIT", + "copyrightText": "(c) Microsoft Corporation, Copyright (c) Microsoft Corporation", + "externalRefs": [ + { + "referenceCategory": "PACKAGE-MANAGER", + "referenceType": "purl", + "referenceLocator": "pkg:nuget/Microsoft.IdentityModel.Logging@8.14.0" + } + ] + }, + { + "name": "Microsoft.Testing.Extensions.TrxReport.Abstractions", + "SPDXID": "SPDXRef-nuget-Microsoft.Testing.Extensions.TrxReport.Abstractions-1.7.3-14ef65", + "versionInfo": "1.7.3", + "downloadLocation": "NOASSERTION", + "filesAnalyzed": false, + "licenseConcluded": "MIT", + "copyrightText": "(c) Microsoft Corporation", + "externalRefs": [ + { + "referenceCategory": "PACKAGE-MANAGER", + "referenceType": "purl", + "referenceLocator": "pkg:nuget/Microsoft.Testing.Extensions.TrxReport.Abstractions@1.7.3" + } + ] + }, + { + "name": "Microsoft.CodeCoverage", + "SPDXID": "SPDXRef-nuget-Microsoft.CodeCoverage-17.14.1-1dfedf", + "versionInfo": "17.14.1", + "downloadLocation": "NOASSERTION", + "filesAnalyzed": false, + "licenseConcluded": "MIT", + "copyrightText": "(c) Microsoft Corporation, Copyright (c) .NET Foundation, Copyright (c) 2008 - 2011 Novell, Inc., Copyright (c) 2008 - 2015 Jb Evain, Copyright (c) Microsoft, Copyright (c) Microsoft Corporation, Copyright 1995-2022 Mark Adler, Copyright 2008 - 2018 Jb Evain", + "externalRefs": [ + { + "referenceCategory": "PACKAGE-MANAGER", + "referenceType": "purl", + "referenceLocator": "pkg:nuget/Microsoft.CodeCoverage@17.14.1" + } + ] + }, + { + "name": "Microsoft.Extensions.Configuration.Abstractions", + "SPDXID": "SPDXRef-nuget-Microsoft.Extensions.Configuration.Abstractions-8.0.0-639bd0", + "versionInfo": "8.0.0", + "downloadLocation": "NOASSERTION", + "filesAnalyzed": false, + "licenseConcluded": "MIT", + "copyrightText": "(c) 1997-2005 Sean Eron Anderson, (c) Microsoft Corporation, Copyright (c) .NET Foundation, Copyright (c) .NET Foundation and Contributors, Copyright (c) .NET Foundation Contributors, Copyright (c) 1980, 1986, 1993 The Regents of the University of California, Copyright (c) 1989 by Hewlett-Packard Company, Palo Alto, Ca. \u0026 Digital Equipment Corporation, Maynard, Mass, Copyright (c) 1990- 1993, 1996 Open Software Foundation, Inc., Copyright (c) 1991-2022 Unicode, Inc., Copyright (c) 1995-2022 Jean-loup Gailly and Mark Adler, Copyright (c) 1998 Microsoft, Copyright (c) 1998 Microsoft. To, Copyright (c) 1999 Lucent Technologies, Copyright (c) 2004-2006 Intel Corporation, Copyright (c) 2005-2007, Nick Galbreath, Copyright (c) 2005-2020 Rich Felker, Copyright (c) 2006 Jb Evain (jbevain@gmail.com), Copyright (c) 2007 James Newton-King, Copyright (c) 2008-2016, Wojciech Mula, Copyright (c) 2008-2020 Advanced Micro Devices, Inc., Copyright (c) 2009, 2010, 2013-2016 by the Brotli Authors, Copyright (c) 2011 Novell, Inc (http://www.novell.com), Copyright (c) 2011-2015 Intel Corporation, Copyright (c) 2011-2020 Microsoft Corp, Copyright (c) 2011, Google Inc., Copyright (c) 2012 - present, Victor Zverovich, Copyright (c) 2012-2021 Yann Collet, Copyright (c) 2013-2017, Alfred Klomp, Copyright (c) 2013-2017, Milosz Krajewski, Copyright (c) 2014 Ryan Juckett http://www.ryanjuckett.com, Copyright (c) 2015 The Chromium Authors, Copyright (c) 2015 THL A29 Limited, a Tencent company, and Milo Yip, Copyright (c) 2015 Xamarin, Inc (http://www.xamarin.com), Copyright (c) 2015-2017, Wojciech Mula, Copyright (c) 2016-2017, Matthieu Darbois, Copyright (c) 2017 Yoshifumi Kawai, Copyright (c) 2018 Alexander Chermyanin, Copyright (c) 2019 Microsoft Corporation, Daan Leijen, Copyright (c) 2020 Dan Shechter, Copyright (c) 2020 Mara Bos \u003cm-ou.se@m-ou.se\u003e, Copyright (c) 2021, Copyright (c) 2021 csFastFloat authors, Copyright (c) 2022, Geoff Langdale, Copyright (c) 2022, Wojciech Mula, Copyright (c) Andrew Arnott, Copyright (c) Microsoft Corporation, Copyright (c) Six Labors, Copyright (c) The Internet Society (2003), Copyright (c) The Internet Society 1997, Copyright (c) YEAR W3C(r) (MIT, ERCIM, Keio, Beihang) Disclaimers, Copyright (c) YEAR W3C(r) (MIT, ERCIM, Keio, Beihang). Disclaimers, Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018 The Regents of the University of California, Copyright 2012 the V8 project authors, Copyright 2018 Daniel Lemire, Copyright 2019 LLVM Project, Portions (c) International Organization, Portions (c) International Organization for Standardization 1986", + "externalRefs": [ + { + "referenceCategory": "PACKAGE-MANAGER", + "referenceType": "purl", + "referenceLocator": "pkg:nuget/Microsoft.Extensions.Configuration.Abstractions@8.0.0" + } + ] + }, + { + "name": "Microsoft.Extensions.Logging", + "SPDXID": "SPDXRef-nuget-Microsoft.Extensions.Logging-8.0.1-d391ad", + "versionInfo": "8.0.1", + "downloadLocation": "NOASSERTION", + "filesAnalyzed": false, + "licenseConcluded": "MIT", + "copyrightText": "(c) 1997-2005 Sean Eron Anderson, (c) Microsoft Corporation, Copyright (c) .NET Foundation, Copyright (c) .NET Foundation and Contributors, Copyright (c) .NET Foundation Contributors, Copyright (c) 1980, 1986, 1993 The Regents of the University of California, Copyright (c) 1989 by Hewlett-Packard Company, Palo Alto, Ca. \u0026 Digital Equipment Corporation, Maynard, Mass, Copyright (c) 1990- 1993, 1996 Open Software Foundation, Inc., Copyright (c) 1991-2022 Unicode, Inc., Copyright (c) 1995-2022 Jean-loup Gailly and Mark Adler, Copyright (c) 1998 Microsoft, Copyright (c) 1998 Microsoft. To, Copyright (c) 1999 Lucent Technologies, Copyright (c) 2004-2006 Intel Corporation, Copyright (c) 2005-2007, Nick Galbreath, Copyright (c) 2005-2020 Rich Felker, Copyright (c) 2006 Jb Evain (jbevain@gmail.com), Copyright (c) 2007 James Newton-King, Copyright (c) 2008-2016, Wojciech Mula, Copyright (c) 2008-2020 Advanced Micro Devices, Inc., Copyright (c) 2009, 2010, 2013-2016 by the Brotli Authors, Copyright (c) 2011 Novell, Inc (http://www.novell.com), Copyright (c) 2011-2015 Intel Corporation, Copyright (c) 2011-2020 Microsoft Corp, Copyright (c) 2011, Google Inc., Copyright (c) 2012 - present, Victor Zverovich, Copyright (c) 2012-2021 Yann Collet, Copyright (c) 2013-2017, Alfred Klomp, Copyright (c) 2013-2017, Milosz Krajewski, Copyright (c) 2014 Ryan Juckett http://www.ryanjuckett.com, Copyright (c) 2015 The Chromium Authors, Copyright (c) 2015 THL A29 Limited, a Tencent company, and Milo Yip, Copyright (c) 2015 Xamarin, Inc (http://www.xamarin.com), Copyright (c) 2015-2017, Wojciech Mula, Copyright (c) 2016-2017, Matthieu Darbois, Copyright (c) 2017 Yoshifumi Kawai, Copyright (c) 2018 Alexander Chermyanin, Copyright (c) 2019 Microsoft Corporation, Daan Leijen, Copyright (c) 2020 Dan Shechter, Copyright (c) 2020 Mara Bos \u003cm-ou.se@m-ou.se\u003e, Copyright (c) 2021, Copyright (c) 2021 csFastFloat authors, Copyright (c) 2022, Geoff Langdale, Copyright (c) 2022, Wojciech Mula, Copyright (c) Andrew Arnott, Copyright (c) Microsoft Corporation, Copyright (c) Six Labors, Copyright (c) The Internet Society (2003), Copyright (c) The Internet Society 1997, Copyright (c) YEAR W3C(r) (MIT, ERCIM, Keio, Beihang) Disclaimers, Copyright (c) YEAR W3C(r) (MIT, ERCIM, Keio, Beihang). Disclaimers, Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018 The Regents of the University of California, Copyright 2012 the V8 project authors, Copyright 2018 Daniel Lemire, Copyright 2019 LLVM Project, Portions (c) International Organization, Portions (c) International Organization for Standardization 1986", + "externalRefs": [ + { + "referenceCategory": "PACKAGE-MANAGER", + "referenceType": "purl", + "referenceLocator": "pkg:nuget/Microsoft.Extensions.Logging@8.0.1" + } + ] + }, + { + "name": "Microsoft.Testing.Extensions.VSTestBridge", + "SPDXID": "SPDXRef-nuget-Microsoft.Testing.Extensions.VSTestBridge-1.7.3-e3b7da", + "versionInfo": "1.7.3", + "downloadLocation": "NOASSERTION", + "filesAnalyzed": false, + "licenseConcluded": "MIT", + "copyrightText": "(c) Microsoft Corporation", + "externalRefs": [ + { + "referenceCategory": "PACKAGE-MANAGER", + "referenceType": "purl", + "referenceLocator": "pkg:nuget/Microsoft.Testing.Extensions.VSTestBridge@1.7.3" + } + ] + }, + { + "name": "System.Diagnostics.DiagnosticSource", + "SPDXID": "SPDXRef-nuget-System.Diagnostics.DiagnosticSource-5.0.0-31c6d8", + "versionInfo": "5.0.0", + "downloadLocation": "NOASSERTION", + "filesAnalyzed": false, + "licenseConcluded": "MIT", + "copyrightText": "(c) 1997-2005 Sean Eron Anderson., (c) 2008 VeriSign, Inc., (c) Microsoft Corporation., Copyright (c) .NET Foundation and Contributors, Copyright (c) .NET Foundation Contributors, Copyright (c) .NET Foundation., Copyright (c) 1989 by Hewlett-Packard Company, Palo Alto, Ca. \u0026 Digital Equipment Corporation, Maynard, Mass., Copyright (c) 1989 by Hewlett-Packard Company, Palo Alto, Ca. \u0026 Digital Equipment Corporation, Maynard, Mass. To, Copyright (c) 1990- 1993, 1996 Open Software Foundation, Inc., Copyright (c) 1995-2017 Jean-loup Gailly and Mark Adler, Copyright (c) 1998 Microsoft. To, Copyright (c) 2004-2006 Intel Corporation, Copyright (c) 2005-2007, Nick Galbreath, Copyright (c) 2007 James Newton-King, Copyright (c) 2009, 2010, 2013-2016 by the Brotli Authors., Copyright (c) 2011 Novell, Inc (http://www.novell.com), Copyright (c) 2011, Google Inc., Copyright (c) 2012-2014, Yann Collet, Copyright (c) 2013-2017, Alfred Klomp, Copyright (c) 2013-2017, Milosz Krajewski, Copyright (c) 2014 Ryan Juckett http://www.ryanjuckett.com, Copyright (c) 2015 The Chromium Authors., Copyright (c) 2015 THL A29 Limited, a Tencent company, and Milo Yip., Copyright (c) 2015 Xamarin, Inc (http://www.xamarin.com), Copyright (c) 2015-2017, Wojciech Mula, Copyright (c) 2016-2017, Matthieu Darbois, Copyright (c) 2017 Yoshifumi Kawai, Copyright (c) 2018 Alexander Chermyanin, Copyright (c) Andrew Arnott, Copyright (c) Microsoft Corporation, Copyright (c) The Internet Society (2003)., Copyright (c) The Internet Society 1997., Copyright (c) YEAR W3C(r) (MIT, ERCIM, Keio, Beihang). Disclaimers THIS WORK IS PROVIDED AS, Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018 The Regents of the University of California., Copyright 2012 the V8 project, Copyright 2018 Daniel Lemire, Portions (c) International Organization", + "externalRefs": [ + { + "referenceCategory": "PACKAGE-MANAGER", + "referenceType": "purl", + "referenceLocator": "pkg:nuget/System.Diagnostics.DiagnosticSource@5.0.0" + } + ] + }, + { + "name": "Microsoft.Testing.Extensions.Telemetry", + "SPDXID": "SPDXRef-nuget-Microsoft.Testing.Extensions.Telemetry-1.7.3-380d69", + "versionInfo": "1.7.3", + "downloadLocation": "NOASSERTION", + "filesAnalyzed": false, + "licenseConcluded": "MIT", + "copyrightText": "(c) Microsoft Corporation", + "externalRefs": [ + { + "referenceCategory": "PACKAGE-MANAGER", + "referenceType": "purl", + "referenceLocator": "pkg:nuget/Microsoft.Testing.Extensions.Telemetry@1.7.3" + } + ] + }, + { + "name": "System.Reflection.Metadata", + "SPDXID": "SPDXRef-nuget-System.Reflection.Metadata-8.0.0-2fa35d", + "versionInfo": "8.0.0", + "downloadLocation": "NOASSERTION", + "filesAnalyzed": false, + "licenseConcluded": "MIT", + "copyrightText": "(c) 1997-2005 Sean Eron Anderson, (c) Microsoft Corporation, Copyright (c) .NET Foundation, Copyright (c) .NET Foundation and Contributors, Copyright (c) .NET Foundation Contributors, Copyright (c) 1980, 1986, 1993 The Regents of the University of California, Copyright (c) 1989 by Hewlett-Packard Company, Palo Alto, Ca. \u0026 Digital Equipment Corporation, Maynard, Mass, Copyright (c) 1990- 1993, 1996 Open Software Foundation, Inc., Copyright (c) 1991-2022 Unicode, Inc., Copyright (c) 1995-2022 Jean-loup Gailly and Mark Adler, Copyright (c) 1998 Microsoft, Copyright (c) 1998 Microsoft. To, Copyright (c) 1999 Lucent Technologies, Copyright (c) 2004-2006 Intel Corporation, Copyright (c) 2005-2007, Nick Galbreath, Copyright (c) 2005-2020 Rich Felker, Copyright (c) 2006 Jb Evain (jbevain@gmail.com), Copyright (c) 2007 James Newton-King, Copyright (c) 2008-2016, Wojciech Mula, Copyright (c) 2008-2020 Advanced Micro Devices, Inc., Copyright (c) 2009, 2010, 2013-2016 by the Brotli Authors, Copyright (c) 2011 Novell, Inc (http://www.novell.com), Copyright (c) 2011-2015 Intel Corporation, Copyright (c) 2011-2020 Microsoft Corp, Copyright (c) 2011, Google Inc., Copyright (c) 2012 - present, Victor Zverovich, Copyright (c) 2012-2021 Yann Collet, Copyright (c) 2013-2017, Alfred Klomp, Copyright (c) 2013-2017, Milosz Krajewski, Copyright (c) 2014 Ryan Juckett http://www.ryanjuckett.com, Copyright (c) 2015 The Chromium Authors, Copyright (c) 2015 THL A29 Limited, a Tencent company, and Milo Yip, Copyright (c) 2015 Xamarin, Inc (http://www.xamarin.com), Copyright (c) 2015-2017, Wojciech Mula, Copyright (c) 2016-2017, Matthieu Darbois, Copyright (c) 2017 Yoshifumi Kawai, Copyright (c) 2018 Alexander Chermyanin, Copyright (c) 2019 Microsoft Corporation, Daan Leijen, Copyright (c) 2020 Dan Shechter, Copyright (c) 2020 Mara Bos \u003cm-ou.se@m-ou.se\u003e, Copyright (c) 2021, Copyright (c) 2021 csFastFloat authors, Copyright (c) 2022, Geoff Langdale, Copyright (c) 2022, Wojciech Mula, Copyright (c) Andrew Arnott, Copyright (c) Microsoft Corporation, Copyright (c) Six Labors, Copyright (c) The Internet Society (2003), Copyright (c) The Internet Society 1997, Copyright (c) YEAR W3C(r) (MIT, ERCIM, Keio, Beihang) Disclaimers, Copyright (c) YEAR W3C(r) (MIT, ERCIM, Keio, Beihang). Disclaimers, Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018 The Regents of the University of California, Copyright 2012 the V8 project authors, Copyright 2018 Daniel Lemire, Copyright 2019 LLVM Project, Gets the Copyright Table, Portions (c) International Organization, Portions (c) International Organization for Standardization 1986", + "externalRefs": [ + { + "referenceCategory": "PACKAGE-MANAGER", + "referenceType": "purl", + "referenceLocator": "pkg:nuget/System.Reflection.Metadata@8.0.0" + } + ] + }, + { + "name": "NUnit3TestAdapter", + "SPDXID": "SPDXRef-nuget-NUnit3TestAdapter-5.1.0-5f80ff", + "versionInfo": "5.1.0", + "downloadLocation": "NOASSERTION", + "filesAnalyzed": false, + "licenseConcluded": "MIT", + "copyrightText": "(c) 2022 Charlie Poole, Rob Prouse, Copyright (c) 2011-2021 Charlie Poole, 2014-2025 Terje Sandstrom, Copyright (c) 2021 Charlie Poole, Copyright (c) 2021 Charlie Poole Readonly, Copyright (c) 2022 Charlie Poole, Rob Prouse, Copyright 2011-2021 Charlie Poole, 2014-2025 Terje Sandstrom", + "externalRefs": [ + { + "referenceCategory": "PACKAGE-MANAGER", + "referenceType": "purl", + "referenceLocator": "pkg:nuget/NUnit3TestAdapter@5.1.0" + } + ] + }, + { + "name": "Microsoft.AspNetCore.Components.Web", + "SPDXID": "SPDXRef-nuget-Microsoft.AspNetCore.Components.Web-8.0.11-3380f9", + "versionInfo": "8.0.11", + "downloadLocation": "NOASSERTION", + "filesAnalyzed": false, + "licenseConcluded": "MIT", + "copyrightText": "(c) Microsoft Corporation, Copyright (c) .NET Foundation Contributors, Copyright (c) 1989, 1993 The Regents of the University of California, Copyright (c) 1990, 1993 The Regents of the University of California, Copyright (c) 1996-1998 John D. Polstra, Copyright (c) 1998 John D. Polstra, Copyright (c) 2000-2013 Julian Seward, Copyright (c) 2007 John Birrell (jb@freebsd.org), Copyright (c) 2011-2021 The Bootstrap Authors, Copyright (c) 2011-2021 Twitter, Inc., Copyright (c) 2013 - 2018 AngleSharp, Copyright (c) 2019-2023 The Bootstrap Authors", + "externalRefs": [ + { + "referenceCategory": "PACKAGE-MANAGER", + "referenceType": "purl", + "referenceLocator": "pkg:nuget/Microsoft.AspNetCore.Components.Web@8.0.11" + } + ] + }, + { + "name": "Microsoft.Extensions.Caching.Abstractions", + "SPDXID": "SPDXRef-nuget-Microsoft.Extensions.Caching.Abstractions-8.0.0-82b542", + "versionInfo": "8.0.0", + "downloadLocation": "NOASSERTION", + "filesAnalyzed": false, + "licenseConcluded": "MIT", + "copyrightText": "(c) 1997-2005 Sean Eron Anderson, (c) Microsoft Corporation, Copyright (c) .NET Foundation, Copyright (c) .NET Foundation and Contributors, Copyright (c) .NET Foundation Contributors, Copyright (c) 1980, 1986, 1993 The Regents of the University of California, Copyright (c) 1989 by Hewlett-Packard Company, Palo Alto, Ca. \u0026 Digital Equipment Corporation, Maynard, Mass, Copyright (c) 1990- 1993, 1996 Open Software Foundation, Inc., Copyright (c) 1991-2022 Unicode, Inc., Copyright (c) 1995-2022 Jean-loup Gailly and Mark Adler, Copyright (c) 1998 Microsoft, Copyright (c) 1998 Microsoft. To, Copyright (c) 1999 Lucent Technologies, Copyright (c) 2004-2006 Intel Corporation, Copyright (c) 2005-2007, Nick Galbreath, Copyright (c) 2005-2020 Rich Felker, Copyright (c) 2006 Jb Evain (jbevain@gmail.com), Copyright (c) 2007 James Newton-King, Copyright (c) 2008-2016, Wojciech Mula, Copyright (c) 2008-2020 Advanced Micro Devices, Inc., Copyright (c) 2009, 2010, 2013-2016 by the Brotli Authors, Copyright (c) 2011 Novell, Inc (http://www.novell.com), Copyright (c) 2011-2015 Intel Corporation, Copyright (c) 2011-2020 Microsoft Corp, Copyright (c) 2011, Google Inc., Copyright (c) 2012 - present, Victor Zverovich, Copyright (c) 2012-2021 Yann Collet, Copyright (c) 2013-2017, Alfred Klomp, Copyright (c) 2013-2017, Milosz Krajewski, Copyright (c) 2014 Ryan Juckett http://www.ryanjuckett.com, Copyright (c) 2015 The Chromium Authors, Copyright (c) 2015 THL A29 Limited, a Tencent company, and Milo Yip, Copyright (c) 2015 Xamarin, Inc (http://www.xamarin.com), Copyright (c) 2015-2017, Wojciech Mula, Copyright (c) 2016-2017, Matthieu Darbois, Copyright (c) 2017 Yoshifumi Kawai, Copyright (c) 2018 Alexander Chermyanin, Copyright (c) 2019 Microsoft Corporation, Daan Leijen, Copyright (c) 2020 Dan Shechter, Copyright (c) 2020 Mara Bos \u003cm-ou.se@m-ou.se\u003e, Copyright (c) 2021, Copyright (c) 2021 csFastFloat authors, Copyright (c) 2022, Geoff Langdale, Copyright (c) 2022, Wojciech Mula, Copyright (c) Andrew Arnott, Copyright (c) Microsoft Corporation, Copyright (c) Six Labors, Copyright (c) The Internet Society (2003), Copyright (c) The Internet Society 1997, Copyright (c) YEAR W3C(r) (MIT, ERCIM, Keio, Beihang) Disclaimers, Copyright (c) YEAR W3C(r) (MIT, ERCIM, Keio, Beihang). Disclaimers, Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018 The Regents of the University of California, Copyright 2012 the V8 project authors, Copyright 2018 Daniel Lemire, Copyright 2019 LLVM Project, Portions (c) International Organization, Portions (c) International Organization for Standardization 1986", + "externalRefs": [ + { + "referenceCategory": "PACKAGE-MANAGER", + "referenceType": "purl", + "referenceLocator": "pkg:nuget/Microsoft.Extensions.Caching.Abstractions@8.0.0" + } + ] + }, + { + "name": "PuppeteerSharp", + "SPDXID": "SPDXRef-nuget-PuppeteerSharp-20.2.2-d76daa", + "versionInfo": "20.2.2", + "downloadLocation": "NOASSERTION", + "filesAnalyzed": false, + "licenseConcluded": "MIT", + "externalRefs": [ + { + "referenceCategory": "PACKAGE-MANAGER", + "referenceType": "purl", + "referenceLocator": "pkg:nuget/PuppeteerSharp@20.2.2" + } + ] + }, + { + "name": "HtmlAgilityPack", + "SPDXID": "SPDXRef-nuget-HtmlAgilityPack-1.12.2-e4ed5d", + "versionInfo": "1.12.2", + "downloadLocation": "NOASSERTION", + "filesAnalyzed": false, + "licenseConcluded": "MIT", + "copyrightText": "Copyright (c) ZZZ Projects Inc., Copyright ZZZ Projects Inc.", + "externalRefs": [ + { + "referenceCategory": "PACKAGE-MANAGER", + "referenceType": "purl", + "referenceLocator": "pkg:nuget/HtmlAgilityPack@1.12.2" + } + ] + }, + { + "name": "Microsoft.Extensions.DependencyInjection.Abstractions", + "SPDXID": "SPDXRef-nuget-Microsoft.Extensions.DependencyInjection.Abstractions-8.0.2-fa587a", + "versionInfo": "8.0.2", + "downloadLocation": "NOASSERTION", + "filesAnalyzed": false, + "licenseConcluded": "MIT", + "copyrightText": "(c) 1997-2005 Sean Eron Anderson, (c) Microsoft Corporation, Copyright (c) .NET Foundation, Copyright (c) .NET Foundation and Contributors, Copyright (c) .NET Foundation Contributors, Copyright (c) 1980, 1986, 1993 The Regents of the University of California, Copyright (c) 1989 by Hewlett-Packard Company, Palo Alto, Ca. \u0026 Digital Equipment Corporation, Maynard, Mass, Copyright (c) 1990- 1993, 1996 Open Software Foundation, Inc., Copyright (c) 1991-2022 Unicode, Inc., Copyright (c) 1995-2022 Jean-loup Gailly and Mark Adler, Copyright (c) 1998 Microsoft. To, Copyright (c) 1999 Lucent Technologies, Copyright (c) 2004-2006 Intel Corporation, Copyright (c) 2005-2007, Nick Galbreath, Copyright (c) 2005-2020 Rich Felker, Copyright (c) 2006 Jb Evain (jbevain@gmail.com), Copyright (c) 2007 James Newton-King, Copyright (c) 2008-2016, Wojciech Mula, Copyright (c) 2008-2020 Advanced Micro Devices, Inc., Copyright (c) 2009, 2010, 2013-2016 by the Brotli Authors, Copyright (c) 2011 Novell, Inc (http://www.novell.com), Copyright (c) 2011-2015 Intel Corporation, Copyright (c) 2011-2020 Microsoft Corp, Copyright (c) 2011, Google Inc., Copyright (c) 2012 - present, Victor Zverovich, Copyright (c) 2012-2021 Yann Collet, Copyright (c) 2013-2017, Alfred Klomp, Copyright (c) 2013-2017, Milosz Krajewski, Copyright (c) 2014 Ryan Juckett http://www.ryanjuckett.com, Copyright (c) 2015 The Chromium Authors, Copyright (c) 2015 THL A29 Limited, a Tencent company, and Milo Yip, Copyright (c) 2015 Xamarin, Inc (http://www.xamarin.com), Copyright (c) 2015-2017, Wojciech Mula, Copyright (c) 2016-2017, Matthieu Darbois, Copyright (c) 2017 Yoshifumi Kawai, Copyright (c) 2018 Alexander Chermyanin, Copyright (c) 2019 Microsoft Corporation, Daan Leijen, Copyright (c) 2020 Dan Shechter, Copyright (c) 2020 Mara Bos \u003cm-ou.se@m-ou.se\u003e, Copyright (c) 2021 csFastFloat authors, Copyright (c) 2022, Geoff Langdale, Copyright (c) 2022, Wojciech Mula, Copyright (c) Andrew Arnott, Copyright (c) Microsoft Corporation, Copyright (c) Six Labors, Copyright (c) The Internet Society (2003), Copyright (c) The Internet Society 1997, Copyright (c) YEAR W3C(r) (MIT, ERCIM, Keio, Beihang). Disclaimers, Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018 The Regents of the University of California, Copyright 2012 the V8 project authors, Copyright 2018 Daniel Lemire, Copyright 2019 LLVM Project, Portions (c) International Organization", + "externalRefs": [ + { + "referenceCategory": "PACKAGE-MANAGER", + "referenceType": "purl", + "referenceLocator": "pkg:nuget/Microsoft.Extensions.DependencyInjection.Abstractions@8.0.2" + } + ] + }, + { + "name": "Microsoft.Extensions.DependencyInjection", + "SPDXID": "SPDXRef-nuget-Microsoft.Extensions.DependencyInjection-8.0.0-76ea4d", + "versionInfo": "8.0.0", + "downloadLocation": "NOASSERTION", + "filesAnalyzed": false, + "licenseConcluded": "MIT", + "copyrightText": "(c) 1997-2005 Sean Eron Anderson, (c) Microsoft Corporation, Copyright (c) .NET Foundation, Copyright (c) .NET Foundation and Contributors, Copyright (c) .NET Foundation Contributors, Copyright (c) 1980, 1986, 1993 The Regents of the University of California, Copyright (c) 1989 by Hewlett-Packard Company, Palo Alto, Ca. \u0026 Digital Equipment Corporation, Maynard, Mass, Copyright (c) 1990- 1993, 1996 Open Software Foundation, Inc., Copyright (c) 1991-2022 Unicode, Inc., Copyright (c) 1995-2022 Jean-loup Gailly and Mark Adler, Copyright (c) 1998 Microsoft, Copyright (c) 1998 Microsoft. To, Copyright (c) 1999 Lucent Technologies, Copyright (c) 2004-2006 Intel Corporation, Copyright (c) 2005-2007, Nick Galbreath, Copyright (c) 2005-2020 Rich Felker, Copyright (c) 2006 Jb Evain (jbevain@gmail.com), Copyright (c) 2007 James Newton-King, Copyright (c) 2008-2016, Wojciech Mula, Copyright (c) 2008-2020 Advanced Micro Devices, Inc., Copyright (c) 2009, 2010, 2013-2016 by the Brotli Authors, Copyright (c) 2011 Novell, Inc (http://www.novell.com), Copyright (c) 2011-2015 Intel Corporation, Copyright (c) 2011-2020 Microsoft Corp, Copyright (c) 2011, Google Inc., Copyright (c) 2012 - present, Victor Zverovich, Copyright (c) 2012-2021 Yann Collet, Copyright (c) 2013-2017, Alfred Klomp, Copyright (c) 2013-2017, Milosz Krajewski, Copyright (c) 2014 Ryan Juckett http://www.ryanjuckett.com, Copyright (c) 2015 The Chromium Authors, Copyright (c) 2015 THL A29 Limited, a Tencent company, and Milo Yip, Copyright (c) 2015 Xamarin, Inc (http://www.xamarin.com), Copyright (c) 2015-2017, Wojciech Mula, Copyright (c) 2016-2017, Matthieu Darbois, Copyright (c) 2017 Yoshifumi Kawai, Copyright (c) 2018 Alexander Chermyanin, Copyright (c) 2019 Microsoft Corporation, Daan Leijen, Copyright (c) 2020 Dan Shechter, Copyright (c) 2020 Mara Bos \u003cm-ou.se@m-ou.se\u003e, Copyright (c) 2021, Copyright (c) 2021 csFastFloat authors, Copyright (c) 2022, Geoff Langdale, Copyright (c) 2022, Wojciech Mula, Copyright (c) Andrew Arnott, Copyright (c) Microsoft Corporation, Copyright (c) Six Labors, Copyright (c) The Internet Society (2003), Copyright (c) The Internet Society 1997, Copyright (c) YEAR W3C(r) (MIT, ERCIM, Keio, Beihang) Disclaimers, Copyright (c) YEAR W3C(r) (MIT, ERCIM, Keio, Beihang). Disclaimers, Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018 The Regents of the University of California, Copyright 2012 the V8 project authors, Copyright 2018 Daniel Lemire, Copyright 2019 LLVM Project, Portions (c) International Organization, Portions (c) International Organization for Standardization 1986", + "externalRefs": [ + { + "referenceCategory": "PACKAGE-MANAGER", + "referenceType": "purl", + "referenceLocator": "pkg:nuget/Microsoft.Extensions.DependencyInjection@8.0.0" + } + ] + }, + { + "name": "Microsoft.Extensions.Logging.Abstractions", + "SPDXID": "SPDXRef-nuget-Microsoft.Extensions.Logging.Abstractions-8.0.3-c90f02", + "versionInfo": "8.0.3", + "downloadLocation": "NOASSERTION", + "filesAnalyzed": false, + "licenseConcluded": "MIT", + "copyrightText": "(c) 1997-2005 Sean Eron Anderson, (c) Microsoft Corporation, Copyright (c) .NET Foundation, Copyright (c) .NET Foundation and Contributors, Copyright (c) .NET Foundation Contributors, Copyright (c) 1980, 1986, 1993 The Regents of the University of California, Copyright (c) 1989 by Hewlett-Packard Company, Palo Alto, Ca. \u0026 Digital Equipment Corporation, Maynard, Mass, Copyright (c) 1990- 1993, 1996 Open Software Foundation, Inc., Copyright (c) 1991-2022 Unicode, Inc., Copyright (c) 1995-2022 Jean-loup Gailly and Mark Adler, Copyright (c) 1998 Microsoft, Copyright (c) 1999 Lucent Technologies, Copyright (c) 2004-2006 Intel Corporation, Copyright (c) 2005-2007, Nick Galbreath, Copyright (c) 2005-2020 Rich Felker, Copyright (c) 2006 Jb Evain (jbevain@gmail.com), Copyright (c) 2007 James Newton-King, Copyright (c) 2008-2016, Wojciech Mula, Copyright (c) 2008-2020 Advanced Micro Devices, Inc., Copyright (c) 2009, 2010, 2013-2016 by the Brotli Authors, Copyright (c) 2011 Novell, Inc (http://www.novell.com), Copyright (c) 2011-2015 Intel Corporation, Copyright (c) 2011-2020 Microsoft Corp, Copyright (c) 2011, Google Inc., Copyright (c) 2012 - present, Victor Zverovich, Copyright (c) 2012-2021 Yann Collet, Copyright (c) 2013-2017, Alfred Klomp, Copyright (c) 2013-2017, Milosz Krajewski, Copyright (c) 2014 Ryan Juckett http://www.ryanjuckett.com, Copyright (c) 2015 The Chromium Authors, Copyright (c) 2015 THL A29 Limited, a Tencent company, and Milo Yip, Copyright (c) 2015 Xamarin, Inc (http://www.xamarin.com), Copyright (c) 2015-2017, Wojciech Mula, Copyright (c) 2016-2017, Matthieu Darbois, Copyright (c) 2017 Yoshifumi Kawai, Copyright (c) 2018 Alexander Chermyanin, Copyright (c) 2019 Microsoft Corporation, Daan Leijen, Copyright (c) 2020 Dan Shechter, Copyright (c) 2020 Mara Bos \u003cm-ou.se@m-ou.se\u003e, Copyright (c) 2021, Copyright (c) 2022, Geoff Langdale, Copyright (c) 2022, Wojciech Mula, Copyright (c) Andrew Arnott, Copyright (c) Microsoft Corporation, Copyright (c) Six Labors, Copyright (c) The Internet Society (2003), Copyright (c) The Internet Society 1997, Copyright (c) YEAR W3C(r) (MIT, ERCIM, Keio, Beihang) Disclaimers, Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018 The Regents of the University of California, Copyright 2012 the V8 project authors, Copyright 2018 Daniel Lemire, Copyright 2019 LLVM Project, Portions (c) International Organization for Standardization 1986", + "externalRefs": [ + { + "referenceCategory": "PACKAGE-MANAGER", + "referenceType": "purl", + "referenceLocator": "pkg:nuget/Microsoft.Extensions.Logging.Abstractions@8.0.3" + } + ] + }, + { + "name": "Microsoft.Extensions.Logging", + "SPDXID": "SPDXRef-nuget-Microsoft.Extensions.Logging-8.0.0-c71dd9", + "versionInfo": "8.0.0", + "downloadLocation": "NOASSERTION", + "filesAnalyzed": false, + "licenseConcluded": "MIT", + "copyrightText": "(c) 1997-2005 Sean Eron Anderson, (c) Microsoft Corporation, Copyright (c) .NET Foundation, Copyright (c) .NET Foundation and Contributors, Copyright (c) .NET Foundation Contributors, Copyright (c) 1980, 1986, 1993 The Regents of the University of California, Copyright (c) 1989 by Hewlett-Packard Company, Palo Alto, Ca. \u0026 Digital Equipment Corporation, Maynard, Mass, Copyright (c) 1990- 1993, 1996 Open Software Foundation, Inc., Copyright (c) 1991-2022 Unicode, Inc., Copyright (c) 1995-2022 Jean-loup Gailly and Mark Adler, Copyright (c) 1998 Microsoft, Copyright (c) 1998 Microsoft. To, Copyright (c) 1999 Lucent Technologies, Copyright (c) 2004-2006 Intel Corporation, Copyright (c) 2005-2007, Nick Galbreath, Copyright (c) 2005-2020 Rich Felker, Copyright (c) 2006 Jb Evain (jbevain@gmail.com), Copyright (c) 2007 James Newton-King, Copyright (c) 2008-2016, Wojciech Mula, Copyright (c) 2008-2020 Advanced Micro Devices, Inc., Copyright (c) 2009, 2010, 2013-2016 by the Brotli Authors, Copyright (c) 2011 Novell, Inc (http://www.novell.com), Copyright (c) 2011-2015 Intel Corporation, Copyright (c) 2011-2020 Microsoft Corp, Copyright (c) 2011, Google Inc., Copyright (c) 2012 - present, Victor Zverovich, Copyright (c) 2012-2021 Yann Collet, Copyright (c) 2013-2017, Alfred Klomp, Copyright (c) 2013-2017, Milosz Krajewski, Copyright (c) 2014 Ryan Juckett http://www.ryanjuckett.com, Copyright (c) 2015 The Chromium Authors, Copyright (c) 2015 THL A29 Limited, a Tencent company, and Milo Yip, Copyright (c) 2015 Xamarin, Inc (http://www.xamarin.com), Copyright (c) 2015-2017, Wojciech Mula, Copyright (c) 2016-2017, Matthieu Darbois, Copyright (c) 2017 Yoshifumi Kawai, Copyright (c) 2018 Alexander Chermyanin, Copyright (c) 2019 Microsoft Corporation, Daan Leijen, Copyright (c) 2020 Dan Shechter, Copyright (c) 2020 Mara Bos \u003cm-ou.se@m-ou.se\u003e, Copyright (c) 2021, Copyright (c) 2021 csFastFloat authors, Copyright (c) 2022, Geoff Langdale, Copyright (c) 2022, Wojciech Mula, Copyright (c) Andrew Arnott, Copyright (c) Microsoft Corporation, Copyright (c) Six Labors, Copyright (c) The Internet Society (2003), Copyright (c) The Internet Society 1997, Copyright (c) YEAR W3C(r) (MIT, ERCIM, Keio, Beihang) Disclaimers, Copyright (c) YEAR W3C(r) (MIT, ERCIM, Keio, Beihang). Disclaimers, Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018 The Regents of the University of California, Copyright 2012 the V8 project authors, Copyright 2018 Daniel Lemire, Copyright 2019 LLVM Project, Portions (c) International Organization, Portions (c) International Organization for Standardization 1986", + "externalRefs": [ + { + "referenceCategory": "PACKAGE-MANAGER", + "referenceType": "purl", + "referenceLocator": "pkg:nuget/Microsoft.Extensions.Logging@8.0.0" + } + ] + }, + { + "name": "Microsoft.Extensions.Options", + "SPDXID": "SPDXRef-nuget-Microsoft.Extensions.Options-8.0.2-f33fde", + "versionInfo": "8.0.2", + "downloadLocation": "NOASSERTION", + "filesAnalyzed": false, + "licenseConcluded": "MIT", + "copyrightText": "(c) 1997-2005 Sean Eron Anderson, (c) Microsoft Corporation, Copyright (c) .NET Foundation, Copyright (c) .NET Foundation and Contributors, Copyright (c) .NET Foundation Contributors, Copyright (c) 1980, 1986, 1993 The Regents of the University of California, Copyright (c) 1989 by Hewlett-Packard Company, Palo Alto, Ca. \u0026 Digital Equipment Corporation, Maynard, Mass, Copyright (c) 1990- 1993, 1996 Open Software Foundation, Inc., Copyright (c) 1991-2022 Unicode, Inc., Copyright (c) 1995-2022 Jean-loup Gailly and Mark Adler, Copyright (c) 1998 Microsoft. To, Copyright (c) 1999 Lucent Technologies, Copyright (c) 2004-2006 Intel Corporation, Copyright (c) 2005-2007, Nick Galbreath, Copyright (c) 2005-2020 Rich Felker, Copyright (c) 2006 Jb Evain (jbevain@gmail.com), Copyright (c) 2007 James Newton-King, Copyright (c) 2008-2016, Wojciech Mula, Copyright (c) 2008-2020 Advanced Micro Devices, Inc., Copyright (c) 2009, 2010, 2013-2016 by the Brotli Authors, Copyright (c) 2011 Novell, Inc (http://www.novell.com), Copyright (c) 2011-2015 Intel Corporation, Copyright (c) 2011-2020 Microsoft Corp, Copyright (c) 2011, Google Inc., Copyright (c) 2012 - present, Victor Zverovich, Copyright (c) 2012-2021 Yann Collet, Copyright (c) 2013-2017, Alfred Klomp, Copyright (c) 2013-2017, Milosz Krajewski, Copyright (c) 2014 Ryan Juckett http://www.ryanjuckett.com, Copyright (c) 2015 The Chromium Authors, Copyright (c) 2015 THL A29 Limited, a Tencent company, and Milo Yip, Copyright (c) 2015 Xamarin, Inc (http://www.xamarin.com), Copyright (c) 2015-2017, Wojciech Mula, Copyright (c) 2016-2017, Matthieu Darbois, Copyright (c) 2017 Yoshifumi Kawai, Copyright (c) 2018 Alexander Chermyanin, Copyright (c) 2019 Microsoft Corporation, Daan Leijen, Copyright (c) 2020 Dan Shechter, Copyright (c) 2020 Mara Bos \u003cm-ou.se@m-ou.se\u003e, Copyright (c) 2021 csFastFloat authors, Copyright (c) 2022, Geoff Langdale, Copyright (c) 2022, Wojciech Mula, Copyright (c) Andrew Arnott, Copyright (c) Microsoft Corporation, Copyright (c) Six Labors, Copyright (c) The Internet Society (2003), Copyright (c) The Internet Society 1997, Copyright (c) YEAR W3C(r) (MIT, ERCIM, Keio, Beihang). Disclaimers, Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018 The Regents of the University of California, Copyright 2012 the V8 project authors, Copyright 2018 Daniel Lemire, Copyright 2019 LLVM Project, Portions (c) International Organization", + "externalRefs": [ + { + "referenceCategory": "PACKAGE-MANAGER", + "referenceType": "purl", + "referenceLocator": "pkg:nuget/Microsoft.Extensions.Options@8.0.2" + } + ] + }, + { + "name": "Microsoft.Extensions.Primitives", + "SPDXID": "SPDXRef-nuget-Microsoft.Extensions.Primitives-8.0.0-0353ed", + "versionInfo": "8.0.0", + "downloadLocation": "NOASSERTION", + "filesAnalyzed": false, + "licenseConcluded": "MIT", + "copyrightText": "(c) 1997-2005 Sean Eron Anderson, (c) Microsoft Corporation, Copyright (c) .NET Foundation, Copyright (c) .NET Foundation and Contributors, Copyright (c) .NET Foundation Contributors, Copyright (c) 1980, 1986, 1993 The Regents of the University of California, Copyright (c) 1989 by Hewlett-Packard Company, Palo Alto, Ca. \u0026 Digital Equipment Corporation, Maynard, Mass, Copyright (c) 1990- 1993, 1996 Open Software Foundation, Inc., Copyright (c) 1991-2022 Unicode, Inc., Copyright (c) 1995-2022 Jean-loup Gailly and Mark Adler, Copyright (c) 1998 Microsoft. To, Copyright (c) 1999 Lucent Technologies, Copyright (c) 2004-2006 Intel Corporation, Copyright (c) 2005-2007, Nick Galbreath, Copyright (c) 2005-2020 Rich Felker, Copyright (c) 2006 Jb Evain (jbevain@gmail.com), Copyright (c) 2007 James Newton-King, Copyright (c) 2008-2016, Wojciech Mula, Copyright (c) 2008-2020 Advanced Micro Devices, Inc., Copyright (c) 2009, 2010, 2013-2016 by the Brotli Authors, Copyright (c) 2011 Novell, Inc (http://www.novell.com), Copyright (c) 2011-2015 Intel Corporation, Copyright (c) 2011-2020 Microsoft Corp, Copyright (c) 2011, Google Inc., Copyright (c) 2012 - present, Victor Zverovich, Copyright (c) 2012-2021 Yann Collet, Copyright (c) 2013-2017, Alfred Klomp, Copyright (c) 2013-2017, Milosz Krajewski, Copyright (c) 2014 Ryan Juckett http://www.ryanjuckett.com, Copyright (c) 2015 The Chromium Authors, Copyright (c) 2015 THL A29 Limited, a Tencent company, and Milo Yip, Copyright (c) 2015 Xamarin, Inc (http://www.xamarin.com), Copyright (c) 2015-2017, Wojciech Mula, Copyright (c) 2016-2017, Matthieu Darbois, Copyright (c) 2017 Yoshifumi Kawai, Copyright (c) 2018 Alexander Chermyanin, Copyright (c) 2019 Microsoft Corporation, Daan Leijen, Copyright (c) 2020 Dan Shechter, Copyright (c) 2020 Mara Bos \u003cm-ou.se@m-ou.se\u003e, Copyright (c) 2021 csFastFloat authors, Copyright (c) 2022, Geoff Langdale, Copyright (c) 2022, Wojciech Mula, Copyright (c) Andrew Arnott, Copyright (c) Microsoft Corporation, Copyright (c) Six Labors, Copyright (c) The Internet Society (2003), Copyright (c) The Internet Society 1997, Copyright (c) YEAR W3C(r) (MIT, ERCIM, Keio, Beihang). Disclaimers, Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018 The Regents of the University of California, Copyright 2012 the V8 project authors, Copyright 2018 Daniel Lemire, Copyright 2019 LLVM Project, Portions (c) International Organization", + "externalRefs": [ + { + "referenceCategory": "PACKAGE-MANAGER", + "referenceType": "purl", + "referenceLocator": "pkg:nuget/Microsoft.Extensions.Primitives@8.0.0" + } + ] + }, + { + "name": "IPAddressRange", + "SPDXID": "SPDXRef-nuget-IPAddressRange-6.2.0-96c860", + "versionInfo": "6.2.0", + "downloadLocation": "NOASSERTION", + "filesAnalyzed": false, + "licenseConcluded": "MPL-2.0", + "copyrightText": "Copyright (c) 2012-2024 J.Sakamoto, Mozilla, Copyright 2012-2024 J.Sakamoto, Mozilla", + "externalRefs": [ + { + "referenceCategory": "PACKAGE-MANAGER", + "referenceType": "purl", + "referenceLocator": "pkg:nuget/IPAddressRange@6.2.0" + } + ] + }, + { + "name": "Microsoft.IdentityModel.Logging", + "SPDXID": "SPDXRef-nuget-Microsoft.IdentityModel.Logging-8.14.0-b11f58", + "versionInfo": "8.14.0", + "downloadLocation": "NOASSERTION", + "filesAnalyzed": false, + "licenseConcluded": "MIT", + "copyrightText": "(c) Microsoft Corporation, Copyright (c) Microsoft Corporation", + "externalRefs": [ + { + "referenceCategory": "PACKAGE-MANAGER", + "referenceType": "purl", + "referenceLocator": "pkg:nuget/Microsoft.IdentityModel.Logging@8.14.0" + } + ] + }, + { + "name": "Microsoft.IdentityModel.Tokens", + "SPDXID": "SPDXRef-nuget-Microsoft.IdentityModel.Tokens-8.14.0-8284c6", + "versionInfo": "8.14.0", + "downloadLocation": "NOASSERTION", + "filesAnalyzed": false, + "licenseConcluded": "MIT", + "copyrightText": "(c) Microsoft Corporation, Copyright (c) Microsoft Corporation", + "externalRefs": [ + { + "referenceCategory": "PACKAGE-MANAGER", + "referenceType": "purl", + "referenceLocator": "pkg:nuget/Microsoft.IdentityModel.Tokens@8.14.0" + } + ] + }, + { + "name": "System.IdentityModel.Tokens.Jwt", + "SPDXID": "SPDXRef-nuget-System.IdentityModel.Tokens.Jwt-8.14.0-62ac6a", + "versionInfo": "8.14.0", + "downloadLocation": "NOASSERTION", + "filesAnalyzed": false, + "licenseConcluded": "MIT", + "copyrightText": "(c) Microsoft Corporation, Copyright (c) Microsoft Corporation", + "externalRefs": [ + { + "referenceCategory": "PACKAGE-MANAGER", + "referenceType": "purl", + "referenceLocator": "pkg:nuget/System.IdentityModel.Tokens.Jwt@8.14.0" + } + ] + }, + { + "name": "Microsoft.Extensions.DependencyInjection.Abstractions", + "SPDXID": "SPDXRef-nuget-Microsoft.Extensions.DependencyInjection.Abstractions-8.0.0-88c4e5", + "versionInfo": "8.0.0", + "downloadLocation": "NOASSERTION", + "filesAnalyzed": false, + "licenseConcluded": "MIT", + "copyrightText": "(c) 1997-2005 Sean Eron Anderson, (c) Microsoft Corporation, Copyright (c) .NET Foundation, Copyright (c) .NET Foundation and Contributors, Copyright (c) .NET Foundation Contributors, Copyright (c) 1980, 1986, 1993 The Regents of the University of California, Copyright (c) 1989 by Hewlett-Packard Company, Palo Alto, Ca. \u0026 Digital Equipment Corporation, Maynard, Mass, Copyright (c) 1990- 1993, 1996 Open Software Foundation, Inc., Copyright (c) 1991-2022 Unicode, Inc., Copyright (c) 1995-2022 Jean-loup Gailly and Mark Adler, Copyright (c) 1998 Microsoft. To, Copyright (c) 1999 Lucent Technologies, Copyright (c) 2004-2006 Intel Corporation, Copyright (c) 2005-2007, Nick Galbreath, Copyright (c) 2005-2020 Rich Felker, Copyright (c) 2006 Jb Evain (jbevain@gmail.com), Copyright (c) 2007 James Newton-King, Copyright (c) 2008-2016, Wojciech Mula, Copyright (c) 2008-2020 Advanced Micro Devices, Inc., Copyright (c) 2009, 2010, 2013-2016 by the Brotli Authors, Copyright (c) 2011 Novell, Inc (http://www.novell.com), Copyright (c) 2011-2015 Intel Corporation, Copyright (c) 2011-2020 Microsoft Corp, Copyright (c) 2011, Google Inc., Copyright (c) 2012 - present, Victor Zverovich, Copyright (c) 2012-2021 Yann Collet, Copyright (c) 2013-2017, Alfred Klomp, Copyright (c) 2013-2017, Milosz Krajewski, Copyright (c) 2014 Ryan Juckett http://www.ryanjuckett.com, Copyright (c) 2015 The Chromium Authors, Copyright (c) 2015 THL A29 Limited, a Tencent company, and Milo Yip, Copyright (c) 2015 Xamarin, Inc (http://www.xamarin.com), Copyright (c) 2015-2017, Wojciech Mula, Copyright (c) 2016-2017, Matthieu Darbois, Copyright (c) 2017 Yoshifumi Kawai, Copyright (c) 2018 Alexander Chermyanin, Copyright (c) 2019 Microsoft Corporation, Daan Leijen, Copyright (c) 2020 Dan Shechter, Copyright (c) 2020 Mara Bos \u003cm-ou.se@m-ou.se\u003e, Copyright (c) 2021 csFastFloat authors, Copyright (c) 2022, Geoff Langdale, Copyright (c) 2022, Wojciech Mula, Copyright (c) Andrew Arnott, Copyright (c) Microsoft Corporation, Copyright (c) Six Labors, Copyright (c) The Internet Society (2003), Copyright (c) The Internet Society 1997, Copyright (c) YEAR W3C(r) (MIT, ERCIM, Keio, Beihang). Disclaimers, Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018 The Regents of the University of California, Copyright 2012 the V8 project authors, Copyright 2018 Daniel Lemire, Copyright 2019 LLVM Project, Portions (c) International Organization", + "externalRefs": [ + { + "referenceCategory": "PACKAGE-MANAGER", + "referenceType": "purl", + "referenceLocator": "pkg:nuget/Microsoft.Extensions.DependencyInjection.Abstractions@8.0.0" + } + ] + }, + { + "name": "Microsoft.Extensions.Logging.Abstractions", + "SPDXID": "SPDXRef-nuget-Microsoft.Extensions.Logging.Abstractions-8.0.0-145c39", + "versionInfo": "8.0.0", + "downloadLocation": "NOASSERTION", + "filesAnalyzed": false, + "licenseConcluded": "MIT", + "copyrightText": "(c) 1997-2005 Sean Eron Anderson, (c) Microsoft Corporation, Copyright (c) .NET Foundation, Copyright (c) .NET Foundation and Contributors, Copyright (c) .NET Foundation Contributors, Copyright (c) 1980, 1986, 1993 The Regents of the University of California, Copyright (c) 1989 by Hewlett-Packard Company, Palo Alto, Ca. \u0026 Digital Equipment Corporation, Maynard, Mass, Copyright (c) 1990- 1993, 1996 Open Software Foundation, Inc., Copyright (c) 1991-2022 Unicode, Inc., Copyright (c) 1995-2022 Jean-loup Gailly and Mark Adler, Copyright (c) 1998 Microsoft. To, Copyright (c) 1999 Lucent Technologies, Copyright (c) 2004-2006 Intel Corporation, Copyright (c) 2005-2007, Nick Galbreath, Copyright (c) 2005-2020 Rich Felker, Copyright (c) 2006 Jb Evain (jbevain@gmail.com), Copyright (c) 2007 James Newton-King, Copyright (c) 2008-2016, Wojciech Mula, Copyright (c) 2008-2020 Advanced Micro Devices, Inc., Copyright (c) 2009, 2010, 2013-2016 by the Brotli Authors, Copyright (c) 2011 Novell, Inc (http://www.novell.com), Copyright (c) 2011-2015 Intel Corporation, Copyright (c) 2011-2020 Microsoft Corp, Copyright (c) 2011, Google Inc., Copyright (c) 2012 - present, Victor Zverovich, Copyright (c) 2012-2021 Yann Collet, Copyright (c) 2013-2017, Alfred Klomp, Copyright (c) 2013-2017, Milosz Krajewski, Copyright (c) 2014 Ryan Juckett http://www.ryanjuckett.com, Copyright (c) 2015 The Chromium Authors, Copyright (c) 2015 THL A29 Limited, a Tencent company, and Milo Yip, Copyright (c) 2015 Xamarin, Inc (http://www.xamarin.com), Copyright (c) 2015-2017, Wojciech Mula, Copyright (c) 2016-2017, Matthieu Darbois, Copyright (c) 2017 Yoshifumi Kawai, Copyright (c) 2018 Alexander Chermyanin, Copyright (c) 2019 Microsoft Corporation, Daan Leijen, Copyright (c) 2020 Dan Shechter, Copyright (c) 2020 Mara Bos \u003cm-ou.se@m-ou.se\u003e, Copyright (c) 2021 csFastFloat authors, Copyright (c) 2022, Geoff Langdale, Copyright (c) 2022, Wojciech Mula, Copyright (c) Andrew Arnott, Copyright (c) Microsoft Corporation, Copyright (c) Six Labors, Copyright (c) The Internet Society (2003), Copyright (c) The Internet Society 1997, Copyright (c) YEAR W3C(r) (MIT, ERCIM, Keio, Beihang). Disclaimers, Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018 The Regents of the University of California, Copyright 2012 the V8 project authors, Copyright 2018 Daniel Lemire, Copyright 2019 LLVM Project, Portions (c) International Organization", + "externalRefs": [ + { + "referenceCategory": "PACKAGE-MANAGER", + "referenceType": "purl", + "referenceLocator": "pkg:nuget/Microsoft.Extensions.Logging.Abstractions@8.0.0" + } + ] + }, + { + "name": "Microsoft.IdentityModel.Abstractions", + "SPDXID": "SPDXRef-nuget-Microsoft.IdentityModel.Abstractions-8.14.0-dada85", + "versionInfo": "8.14.0", + "downloadLocation": "NOASSERTION", + "filesAnalyzed": false, + "licenseConcluded": "MIT", + "copyrightText": "(c) Microsoft Corporation, Copyright (c) Microsoft Corporation", + "externalRefs": [ + { + "referenceCategory": "PACKAGE-MANAGER", + "referenceType": "purl", + "referenceLocator": "pkg:nuget/Microsoft.IdentityModel.Abstractions@8.14.0" + } + ] + }, + { + "name": "Microsoft.IdentityModel.JsonWebTokens", + "SPDXID": "SPDXRef-nuget-Microsoft.IdentityModel.JsonWebTokens-8.14.0-3e0bac", + "versionInfo": "8.14.0", + "downloadLocation": "NOASSERTION", + "filesAnalyzed": false, + "licenseConcluded": "MIT", + "copyrightText": "(c) Microsoft Corporation, Copyright (c) Microsoft Corporation", + "externalRefs": [ + { + "referenceCategory": "PACKAGE-MANAGER", + "referenceType": "purl", + "referenceLocator": "pkg:nuget/Microsoft.IdentityModel.JsonWebTokens@8.14.0" + } + ] + }, + { + "name": "Microsoft.Extensions.Primitives", + "SPDXID": "SPDXRef-nuget-Microsoft.Extensions.Primitives-8.0.0-07a9d5", + "versionInfo": "8.0.0", + "downloadLocation": "NOASSERTION", + "filesAnalyzed": false, + "licenseConcluded": "MIT", + "copyrightText": "(c) 1997-2005 Sean Eron Anderson, (c) Microsoft Corporation, Copyright (c) .NET Foundation, Copyright (c) .NET Foundation and Contributors, Copyright (c) .NET Foundation Contributors, Copyright (c) 1980, 1986, 1993 The Regents of the University of California, Copyright (c) 1989 by Hewlett-Packard Company, Palo Alto, Ca. \u0026 Digital Equipment Corporation, Maynard, Mass, Copyright (c) 1990- 1993, 1996 Open Software Foundation, Inc., Copyright (c) 1991-2022 Unicode, Inc., Copyright (c) 1995-2022 Jean-loup Gailly and Mark Adler, Copyright (c) 1998 Microsoft. To, Copyright (c) 1999 Lucent Technologies, Copyright (c) 2004-2006 Intel Corporation, Copyright (c) 2005-2007, Nick Galbreath, Copyright (c) 2005-2020 Rich Felker, Copyright (c) 2006 Jb Evain (jbevain@gmail.com), Copyright (c) 2007 James Newton-King, Copyright (c) 2008-2016, Wojciech Mula, Copyright (c) 2008-2020 Advanced Micro Devices, Inc., Copyright (c) 2009, 2010, 2013-2016 by the Brotli Authors, Copyright (c) 2011 Novell, Inc (http://www.novell.com), Copyright (c) 2011-2015 Intel Corporation, Copyright (c) 2011-2020 Microsoft Corp, Copyright (c) 2011, Google Inc., Copyright (c) 2012 - present, Victor Zverovich, Copyright (c) 2012-2021 Yann Collet, Copyright (c) 2013-2017, Alfred Klomp, Copyright (c) 2013-2017, Milosz Krajewski, Copyright (c) 2014 Ryan Juckett http://www.ryanjuckett.com, Copyright (c) 2015 The Chromium Authors, Copyright (c) 2015 THL A29 Limited, a Tencent company, and Milo Yip, Copyright (c) 2015 Xamarin, Inc (http://www.xamarin.com), Copyright (c) 2015-2017, Wojciech Mula, Copyright (c) 2016-2017, Matthieu Darbois, Copyright (c) 2017 Yoshifumi Kawai, Copyright (c) 2018 Alexander Chermyanin, Copyright (c) 2019 Microsoft Corporation, Daan Leijen, Copyright (c) 2020 Dan Shechter, Copyright (c) 2020 Mara Bos \u003cm-ou.se@m-ou.se\u003e, Copyright (c) 2021 csFastFloat authors, Copyright (c) 2022, Geoff Langdale, Copyright (c) 2022, Wojciech Mula, Copyright (c) Andrew Arnott, Copyright (c) Microsoft Corporation, Copyright (c) Six Labors, Copyright (c) The Internet Society (2003), Copyright (c) The Internet Society 1997, Copyright (c) YEAR W3C(r) (MIT, ERCIM, Keio, Beihang). Disclaimers, Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018 The Regents of the University of California, Copyright 2012 the V8 project authors, Copyright 2018 Daniel Lemire, Copyright 2019 LLVM Project, Portions (c) International Organization", + "externalRefs": [ + { + "referenceCategory": "PACKAGE-MANAGER", + "referenceType": "purl", + "referenceLocator": "pkg:nuget/Microsoft.Extensions.Primitives@8.0.0" + } + ] + }, + { + "name": "Microsoft.Rest.ClientRuntime", + "SPDXID": "SPDXRef-nuget-Microsoft.Rest.ClientRuntime-2.3.24-508401", + "versionInfo": "2.3.24", + "downloadLocation": "NOASSERTION", + "filesAnalyzed": false, + "licenseConcluded": "MIT", + "copyrightText": "(c) 2008 VeriSign, Inc., (c) Microsoft Corporation, Copyright (c) 2019 Microsoft, Copyright (c) Microsoft Corporation", + "externalRefs": [ + { + "referenceCategory": "PACKAGE-MANAGER", + "referenceType": "purl", + "referenceLocator": "pkg:nuget/Microsoft.Rest.ClientRuntime@2.3.24" + } + ] + }, + { + "name": "RestSharp.Serializers.NewtonsoftJson", + "SPDXID": "SPDXRef-nuget-RestSharp.Serializers.NewtonsoftJson-112.1.0-1f0a6b", + "versionInfo": "112.1.0", + "downloadLocation": "NOASSERTION", + "filesAnalyzed": false, + "licenseConcluded": "Apache-2.0", + "externalRefs": [ + { + "referenceCategory": "PACKAGE-MANAGER", + "referenceType": "purl", + "referenceLocator": "pkg:nuget/RestSharp.Serializers.NewtonsoftJson@112.1.0" + } + ] + }, + { + "name": "RestSharp", + "SPDXID": "SPDXRef-nuget-RestSharp-112.1.0-839660", + "versionInfo": "112.1.0", + "downloadLocation": "NOASSERTION", + "filesAnalyzed": false, + "licenseConcluded": "Apache-2.0", + "externalRefs": [ + { + "referenceCategory": "PACKAGE-MANAGER", + "referenceType": "purl", + "referenceLocator": "pkg:nuget/RestSharp@112.1.0" + } + ] + }, + { + "name": "GraphQL.Primitives", + "SPDXID": "SPDXRef-nuget-GraphQL.Primitives-6.1.0-8b54bf", + "versionInfo": "6.1.0", + "downloadLocation": "NOASSERTION", + "filesAnalyzed": false, + "licenseConcluded": "MIT", + "copyrightText": "Copyright (c) 2017 graphql-dotnet", + "externalRefs": [ + { + "referenceCategory": "PACKAGE-MANAGER", + "referenceType": "purl", + "referenceLocator": "pkg:nuget/GraphQL.Primitives@6.1.0" + } + ] + }, + { + "name": "GraphQL.Client.Abstractions", + "SPDXID": "SPDXRef-nuget-GraphQL.Client.Abstractions-6.1.0-132a88", + "versionInfo": "6.1.0", + "downloadLocation": "NOASSERTION", + "filesAnalyzed": false, + "licenseConcluded": "MIT", + "copyrightText": "Copyright (c) 2017 graphql-dotnet", + "externalRefs": [ + { + "referenceCategory": "PACKAGE-MANAGER", + "referenceType": "purl", + "referenceLocator": "pkg:nuget/GraphQL.Client.Abstractions@6.1.0" + } + ] + }, + { + "name": "GraphQL.Client", + "SPDXID": "SPDXRef-nuget-GraphQL.Client-6.1.0-7c0c75", + "versionInfo": "6.1.0", + "downloadLocation": "NOASSERTION", + "filesAnalyzed": false, + "licenseConcluded": "MIT", + "copyrightText": "Copyright (c) 2017 graphql-dotnet", + "externalRefs": [ + { + "referenceCategory": "PACKAGE-MANAGER", + "referenceType": "purl", + "referenceLocator": "pkg:nuget/GraphQL.Client@6.1.0" + } + ] + }, + { + "name": "Microsoft.AspNetCore.Components", + "SPDXID": "SPDXRef-nuget-Microsoft.AspNetCore.Components-8.0.15-259cdf", + "versionInfo": "8.0.15", + "downloadLocation": "NOASSERTION", + "filesAnalyzed": false, + "licenseConcluded": "MIT", + "copyrightText": "(c) Microsoft Corporation, Copyright (c) .NET Foundation Contributors, Copyright (c) 1989, 1993 The Regents of the University of California, Copyright (c) 1990, 1993 The Regents of the University of California, Copyright (c) 1996-1998 John D. Polstra, Copyright (c) 1998 John D. Polstra, Copyright (c) 2000-2013 Julian Seward, Copyright (c) 2007 John Birrell (jb@freebsd.org), Copyright (c) 2011-2021 The Bootstrap Authors, Copyright (c) 2011-2021 Twitter, Inc., Copyright (c) 2013 - 2018 AngleSharp, Copyright (c) 2019-2023 The Bootstrap Authors", + "externalRefs": [ + { + "referenceCategory": "PACKAGE-MANAGER", + "referenceType": "purl", + "referenceLocator": "pkg:nuget/Microsoft.AspNetCore.Components@8.0.15" + } + ] + }, + { + "name": "Microsoft.Extensions.DependencyInjection.Abstractions", + "SPDXID": "SPDXRef-nuget-Microsoft.Extensions.DependencyInjection.Abstractions-8.0.2-b43535", + "versionInfo": "8.0.2", + "downloadLocation": "NOASSERTION", + "filesAnalyzed": false, + "licenseConcluded": "MIT", + "copyrightText": "(c) 1997-2005 Sean Eron Anderson, (c) Microsoft Corporation, Copyright (c) .NET Foundation, Copyright (c) .NET Foundation and Contributors, Copyright (c) .NET Foundation Contributors, Copyright (c) 1980, 1986, 1993 The Regents of the University of California, Copyright (c) 1989 by Hewlett-Packard Company, Palo Alto, Ca. \u0026 Digital Equipment Corporation, Maynard, Mass, Copyright (c) 1990- 1993, 1996 Open Software Foundation, Inc., Copyright (c) 1991-2022 Unicode, Inc., Copyright (c) 1995-2022 Jean-loup Gailly and Mark Adler, Copyright (c) 1998 Microsoft. To, Copyright (c) 1999 Lucent Technologies, Copyright (c) 2004-2006 Intel Corporation, Copyright (c) 2005-2007, Nick Galbreath, Copyright (c) 2005-2020 Rich Felker, Copyright (c) 2006 Jb Evain (jbevain@gmail.com), Copyright (c) 2007 James Newton-King, Copyright (c) 2008-2016, Wojciech Mula, Copyright (c) 2008-2020 Advanced Micro Devices, Inc., Copyright (c) 2009, 2010, 2013-2016 by the Brotli Authors, Copyright (c) 2011 Novell, Inc (http://www.novell.com), Copyright (c) 2011-2015 Intel Corporation, Copyright (c) 2011-2020 Microsoft Corp, Copyright (c) 2011, Google Inc., Copyright (c) 2012 - present, Victor Zverovich, Copyright (c) 2012-2021 Yann Collet, Copyright (c) 2013-2017, Alfred Klomp, Copyright (c) 2013-2017, Milosz Krajewski, Copyright (c) 2014 Ryan Juckett http://www.ryanjuckett.com, Copyright (c) 2015 The Chromium Authors, Copyright (c) 2015 THL A29 Limited, a Tencent company, and Milo Yip, Copyright (c) 2015 Xamarin, Inc (http://www.xamarin.com), Copyright (c) 2015-2017, Wojciech Mula, Copyright (c) 2016-2017, Matthieu Darbois, Copyright (c) 2017 Yoshifumi Kawai, Copyright (c) 2018 Alexander Chermyanin, Copyright (c) 2019 Microsoft Corporation, Daan Leijen, Copyright (c) 2020 Dan Shechter, Copyright (c) 2020 Mara Bos \u003cm-ou.se@m-ou.se\u003e, Copyright (c) 2021 csFastFloat authors, Copyright (c) 2022, Geoff Langdale, Copyright (c) 2022, Wojciech Mula, Copyright (c) Andrew Arnott, Copyright (c) Microsoft Corporation, Copyright (c) Six Labors, Copyright (c) The Internet Society (2003), Copyright (c) The Internet Society 1997, Copyright (c) YEAR W3C(r) (MIT, ERCIM, Keio, Beihang). Disclaimers, Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018 The Regents of the University of California, Copyright 2012 the V8 project authors, Copyright 2018 Daniel Lemire, Copyright 2019 LLVM Project, Portions (c) International Organization", + "externalRefs": [ + { + "referenceCategory": "PACKAGE-MANAGER", + "referenceType": "purl", + "referenceLocator": "pkg:nuget/Microsoft.Extensions.DependencyInjection.Abstractions@8.0.2" + } + ] + }, + { + "name": "GraphQL.Client.Abstractions.Websocket", + "SPDXID": "SPDXRef-nuget-GraphQL.Client.Abstractions.Websocket-6.1.0-604e8e", + "versionInfo": "6.1.0", + "downloadLocation": "NOASSERTION", + "filesAnalyzed": false, + "licenseConcluded": "MIT", + "copyrightText": "Copyright (c) 2017 graphql-dotnet", + "externalRefs": [ + { + "referenceCategory": "PACKAGE-MANAGER", + "referenceType": "purl", + "referenceLocator": "pkg:nuget/GraphQL.Client.Abstractions.Websocket@6.1.0" + } + ] + }, + { + "name": "Microsoft.Extensions.Options", + "SPDXID": "SPDXRef-nuget-Microsoft.Extensions.Options-8.0.2-3ddafa", + "versionInfo": "8.0.2", + "downloadLocation": "NOASSERTION", + "filesAnalyzed": false, + "licenseConcluded": "MIT", + "copyrightText": "(c) 1997-2005 Sean Eron Anderson, (c) Microsoft Corporation, Copyright (c) .NET Foundation, Copyright (c) .NET Foundation and Contributors, Copyright (c) .NET Foundation Contributors, Copyright (c) 1980, 1986, 1993 The Regents of the University of California, Copyright (c) 1989 by Hewlett-Packard Company, Palo Alto, Ca. \u0026 Digital Equipment Corporation, Maynard, Mass, Copyright (c) 1990- 1993, 1996 Open Software Foundation, Inc., Copyright (c) 1991-2022 Unicode, Inc., Copyright (c) 1995-2022 Jean-loup Gailly and Mark Adler, Copyright (c) 1998 Microsoft. To, Copyright (c) 1999 Lucent Technologies, Copyright (c) 2004-2006 Intel Corporation, Copyright (c) 2005-2007, Nick Galbreath, Copyright (c) 2005-2020 Rich Felker, Copyright (c) 2006 Jb Evain (jbevain@gmail.com), Copyright (c) 2007 James Newton-King, Copyright (c) 2008-2016, Wojciech Mula, Copyright (c) 2008-2020 Advanced Micro Devices, Inc., Copyright (c) 2009, 2010, 2013-2016 by the Brotli Authors, Copyright (c) 2011 Novell, Inc (http://www.novell.com), Copyright (c) 2011-2015 Intel Corporation, Copyright (c) 2011-2020 Microsoft Corp, Copyright (c) 2011, Google Inc., Copyright (c) 2012 - present, Victor Zverovich, Copyright (c) 2012-2021 Yann Collet, Copyright (c) 2013-2017, Alfred Klomp, Copyright (c) 2013-2017, Milosz Krajewski, Copyright (c) 2014 Ryan Juckett http://www.ryanjuckett.com, Copyright (c) 2015 The Chromium Authors, Copyright (c) 2015 THL A29 Limited, a Tencent company, and Milo Yip, Copyright (c) 2015 Xamarin, Inc (http://www.xamarin.com), Copyright (c) 2015-2017, Wojciech Mula, Copyright (c) 2016-2017, Matthieu Darbois, Copyright (c) 2017 Yoshifumi Kawai, Copyright (c) 2018 Alexander Chermyanin, Copyright (c) 2019 Microsoft Corporation, Daan Leijen, Copyright (c) 2020 Dan Shechter, Copyright (c) 2020 Mara Bos \u003cm-ou.se@m-ou.se\u003e, Copyright (c) 2021 csFastFloat authors, Copyright (c) 2022, Geoff Langdale, Copyright (c) 2022, Wojciech Mula, Copyright (c) Andrew Arnott, Copyright (c) Microsoft Corporation, Copyright (c) Six Labors, Copyright (c) The Internet Society (2003), Copyright (c) The Internet Society 1997, Copyright (c) YEAR W3C(r) (MIT, ERCIM, Keio, Beihang). Disclaimers, Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018 The Regents of the University of California, Copyright 2012 the V8 project authors, Copyright 2018 Daniel Lemire, Copyright 2019 LLVM Project, Portions (c) International Organization", + "externalRefs": [ + { + "referenceCategory": "PACKAGE-MANAGER", + "referenceType": "purl", + "referenceLocator": "pkg:nuget/Microsoft.Extensions.Options@8.0.2" + } + ] + }, + { + "name": "GraphQL.Client.Serializer.Newtonsoft", + "SPDXID": "SPDXRef-nuget-GraphQL.Client.Serializer.Newtonsoft-6.1.0-9b01fa", + "versionInfo": "6.1.0", + "downloadLocation": "NOASSERTION", + "filesAnalyzed": false, + "licenseConcluded": "MIT", + "copyrightText": "Copyright (c) 2017 graphql-dotnet", + "externalRefs": [ + { + "referenceCategory": "PACKAGE-MANAGER", + "referenceType": "purl", + "referenceLocator": "pkg:nuget/GraphQL.Client.Serializer.Newtonsoft@6.1.0" + } + ] + }, + { + "name": "Microsoft.AspNetCore.Authorization", + "SPDXID": "SPDXRef-nuget-Microsoft.AspNetCore.Authorization-8.0.15-6b8922", + "versionInfo": "8.0.15", + "downloadLocation": "NOASSERTION", + "filesAnalyzed": false, + "licenseConcluded": "MIT", + "copyrightText": "(c) Microsoft Corporation, Copyright (c) .NET Foundation and Contributors, Copyright (c) .NET Foundation Contributors, Copyright (c) 1989, 1993 The Regents of the University of California, Copyright (c) 1990, 1993 The Regents of the University of California, Copyright (c) 1996-1998 John D. Polstra, Copyright (c) 1998 John D. Polstra, Copyright (c) 2000-2013 Julian Seward, Copyright (c) 2007 James Newton-King, Copyright (c) 2007 John Birrell (jb@freebsd.org), Copyright (c) 2010-2019 Google LLC. http://angular.io/license, Copyright (c) 2011 Alex MacCaw (info@eribium.org), Copyright (c) 2011 Nicolas Gallagher (nicolas@nicolasgallagher.com), Copyright (c) 2011-2021 The Bootstrap Authors, Copyright (c) 2011-2021 Twitter, Inc., Copyright (c) 2013 - 2018 AngleSharp, Copyright (c) 2013-2017, Milosz Krajewski, Copyright (c) 2014-2018 Michael Daines, Copyright (c) 2015, Google Inc., Copyright (c) 2016 Richard Morris, Copyright (c) 2017 Yoshifumi Kawai, Copyright (c) 2019 David Fowler, Copyright (c) 2019-2020 West Wind Technologies, Copyright (c) 2019-2023 The Bootstrap Authors, Copyright (c) Andrew Arnott, Copyright (c) HTML5 Boilerplate, Copyright (c) Microsoft Corporation, Copyright (c) Nicolas Gallagher and Jonathan Neal, Copyright (c) Sindre Sorhus \u003csindresorhus@gmail.com\u003e (https://sindresorhus.com), Copyright 2019 The gRPC Authors, Copyright Jorn Zaefferer, Copyright OpenJS Foundation and other contributors, https://openjsf.org", + "externalRefs": [ + { + "referenceCategory": "PACKAGE-MANAGER", + "referenceType": "purl", + "referenceLocator": "pkg:nuget/Microsoft.AspNetCore.Authorization@8.0.15" + } + ] + }, + { + "name": "Newtonsoft.Json", + "SPDXID": "SPDXRef-nuget-Newtonsoft.Json-13.0.3-631925", + "versionInfo": "13.0.3", + "downloadLocation": "NOASSERTION", + "filesAnalyzed": false, + "licenseConcluded": "MIT", + "copyrightText": "Copyright (c) 2007 James Newton-King, Copyright (c) James Newton-King 2008, Copyright James Newton-King 2008, Copyright James Newton-King 2008 Json.NET", + "externalRefs": [ + { + "referenceCategory": "PACKAGE-MANAGER", + "referenceType": "purl", + "referenceLocator": "pkg:nuget/Newtonsoft.Json@13.0.3" + } + ] + }, + { + "name": "GraphQL.Client.Serializer.SystemTextJson", + "SPDXID": "SPDXRef-nuget-GraphQL.Client.Serializer.SystemTextJson-6.1.0-c25e33", + "versionInfo": "6.1.0", + "downloadLocation": "NOASSERTION", + "filesAnalyzed": false, + "licenseConcluded": "MIT", + "copyrightText": "Copyright (c) 2017 graphql-dotnet", + "externalRefs": [ + { + "referenceCategory": "PACKAGE-MANAGER", + "referenceType": "purl", + "referenceLocator": "pkg:nuget/GraphQL.Client.Serializer.SystemTextJson@6.1.0" + } + ] + }, + { + "name": "Microsoft.AspNetCore.Components.Analyzers", + "SPDXID": "SPDXRef-nuget-Microsoft.AspNetCore.Components.Analyzers-8.0.15-89dc0e", + "versionInfo": "8.0.15", + "downloadLocation": "NOASSERTION", + "filesAnalyzed": false, + "licenseConcluded": "MIT", + "copyrightText": "(c) Microsoft Corporation, Copyright (c) .NET Foundation Contributors, Copyright (c) 1989, 1993 The Regents of the University of California, Copyright (c) 1990, 1993 The Regents of the University of California, Copyright (c) 1996-1998 John D. Polstra, Copyright (c) 1998 John D. Polstra, Copyright (c) 2000-2013 Julian Seward, Copyright (c) 2007 John Birrell (jb@freebsd.org), Copyright (c) 2011-2021 The Bootstrap Authors, Copyright (c) 2011-2021 Twitter, Inc., Copyright (c) 2013 - 2018 AngleSharp, Copyright (c) 2019-2023 The Bootstrap Authors", + "externalRefs": [ + { + "referenceCategory": "PACKAGE-MANAGER", + "referenceType": "purl", + "referenceLocator": "pkg:nuget/Microsoft.AspNetCore.Components.Analyzers@8.0.15" + } + ] + }, + { + "name": "Microsoft.Extensions.Logging.Abstractions", + "SPDXID": "SPDXRef-nuget-Microsoft.Extensions.Logging.Abstractions-8.0.3-854476", + "versionInfo": "8.0.3", + "downloadLocation": "NOASSERTION", + "filesAnalyzed": false, + "licenseConcluded": "MIT", + "copyrightText": "(c) 1997-2005 Sean Eron Anderson, (c) Microsoft Corporation, Copyright (c) .NET Foundation, Copyright (c) .NET Foundation and Contributors, Copyright (c) .NET Foundation Contributors, Copyright (c) 1980, 1986, 1993 The Regents of the University of California, Copyright (c) 1989 by Hewlett-Packard Company, Palo Alto, Ca. \u0026 Digital Equipment Corporation, Maynard, Mass, Copyright (c) 1990- 1993, 1996 Open Software Foundation, Inc., Copyright (c) 1991-2022 Unicode, Inc., Copyright (c) 1995-2022 Jean-loup Gailly and Mark Adler, Copyright (c) 1998 Microsoft, Copyright (c) 1999 Lucent Technologies, Copyright (c) 2004-2006 Intel Corporation, Copyright (c) 2005-2007, Nick Galbreath, Copyright (c) 2005-2020 Rich Felker, Copyright (c) 2006 Jb Evain (jbevain@gmail.com), Copyright (c) 2007 James Newton-King, Copyright (c) 2008-2016, Wojciech Mula, Copyright (c) 2008-2020 Advanced Micro Devices, Inc., Copyright (c) 2009, 2010, 2013-2016 by the Brotli Authors, Copyright (c) 2011 Novell, Inc (http://www.novell.com), Copyright (c) 2011-2015 Intel Corporation, Copyright (c) 2011-2020 Microsoft Corp, Copyright (c) 2011, Google Inc., Copyright (c) 2012 - present, Victor Zverovich, Copyright (c) 2012-2021 Yann Collet, Copyright (c) 2013-2017, Alfred Klomp, Copyright (c) 2013-2017, Milosz Krajewski, Copyright (c) 2014 Ryan Juckett http://www.ryanjuckett.com, Copyright (c) 2015 The Chromium Authors, Copyright (c) 2015 THL A29 Limited, a Tencent company, and Milo Yip, Copyright (c) 2015 Xamarin, Inc (http://www.xamarin.com), Copyright (c) 2015-2017, Wojciech Mula, Copyright (c) 2016-2017, Matthieu Darbois, Copyright (c) 2017 Yoshifumi Kawai, Copyright (c) 2018 Alexander Chermyanin, Copyright (c) 2019 Microsoft Corporation, Daan Leijen, Copyright (c) 2020 Dan Shechter, Copyright (c) 2020 Mara Bos \u003cm-ou.se@m-ou.se\u003e, Copyright (c) 2021, Copyright (c) 2022, Geoff Langdale, Copyright (c) 2022, Wojciech Mula, Copyright (c) Andrew Arnott, Copyright (c) Microsoft Corporation, Copyright (c) Six Labors, Copyright (c) The Internet Society (2003), Copyright (c) The Internet Society 1997, Copyright (c) YEAR W3C(r) (MIT, ERCIM, Keio, Beihang) Disclaimers, Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018 The Regents of the University of California, Copyright 2012 the V8 project authors, Copyright 2018 Daniel Lemire, Copyright 2019 LLVM Project, Portions (c) International Organization for Standardization 1986", + "externalRefs": [ + { + "referenceCategory": "PACKAGE-MANAGER", + "referenceType": "purl", + "referenceLocator": "pkg:nuget/Microsoft.Extensions.Logging.Abstractions@8.0.3" + } + ] + }, + { + "name": "IPAddressRange", + "SPDXID": "SPDXRef-nuget-IPAddressRange-6.2.0-2c2fd5", + "versionInfo": "6.2.0", + "downloadLocation": "NOASSERTION", + "filesAnalyzed": false, + "licenseConcluded": "MPL-2.0", + "copyrightText": "Copyright (c) 2012-2024 J.Sakamoto, Mozilla, Copyright 2012-2024 J.Sakamoto, Mozilla", + "externalRefs": [ + { + "referenceCategory": "PACKAGE-MANAGER", + "referenceType": "purl", + "referenceLocator": "pkg:nuget/IPAddressRange@6.2.0" + } + ] + }, + { + "name": "System.Reactive", + "SPDXID": "SPDXRef-nuget-System.Reactive-6.0.0-f0ef58", + "versionInfo": "6.0.0", + "downloadLocation": "NOASSERTION", + "filesAnalyzed": false, + "licenseConcluded": "MIT", + "copyrightText": "Copyright (c) .NET Foundation and Contributors, Copyright (c) .NET Foundation and Contributors. Rx Reactive Extensions Observable LINQ Events", + "externalRefs": [ + { + "referenceCategory": "PACKAGE-MANAGER", + "referenceType": "purl", + "referenceLocator": "pkg:nuget/System.Reactive@6.0.0" + } + ] + }, + { + "name": "Microsoft.AspNetCore.Metadata", + "SPDXID": "SPDXRef-nuget-Microsoft.AspNetCore.Metadata-8.0.15-2a8ab9", + "versionInfo": "8.0.15", + "downloadLocation": "NOASSERTION", + "filesAnalyzed": false, + "licenseConcluded": "MIT", + "copyrightText": "(c) Microsoft Corporation, Copyright (c) .NET Foundation and Contributors, Copyright (c) .NET Foundation Contributors, Copyright (c) 1989, 1993 The Regents of the University of California, Copyright (c) 1990, 1993 The Regents of the University of California, Copyright (c) 1996-1998 John D. Polstra, Copyright (c) 1998 John D. Polstra, Copyright (c) 2000-2013 Julian Seward, Copyright (c) 2007 James Newton-King, Copyright (c) 2007 John Birrell (jb@freebsd.org), Copyright (c) 2010-2019 Google LLC. http://angular.io/license, Copyright (c) 2011 Alex MacCaw (info@eribium.org), Copyright (c) 2011 Nicolas Gallagher (nicolas@nicolasgallagher.com), Copyright (c) 2011-2021 The Bootstrap Authors, Copyright (c) 2011-2021 Twitter, Inc., Copyright (c) 2013 - 2018 AngleSharp, Copyright (c) 2013-2017, Milosz Krajewski, Copyright (c) 2014-2018 Michael Daines, Copyright (c) 2015, Google Inc., Copyright (c) 2016 Richard Morris, Copyright (c) 2017 Yoshifumi Kawai, Copyright (c) 2019 David Fowler, Copyright (c) 2019-2020 West Wind Technologies, Copyright (c) 2019-2023 The Bootstrap Authors, Copyright (c) Andrew Arnott, Copyright (c) HTML5 Boilerplate, Copyright (c) Microsoft Corporation, Copyright (c) Nicolas Gallagher and Jonathan Neal, Copyright (c) Sindre Sorhus \u003csindresorhus@gmail.com\u003e (https://sindresorhus.com), Copyright 2019 The gRPC Authors, Copyright Jorn Zaefferer, Copyright OpenJS Foundation and other contributors, https://openjsf.org", + "externalRefs": [ + { + "referenceCategory": "PACKAGE-MANAGER", + "referenceType": "purl", + "referenceLocator": "pkg:nuget/Microsoft.AspNetCore.Metadata@8.0.15" + } + ] + }, + { + "name": "IPAddressRange", + "SPDXID": "SPDXRef-nuget-IPAddressRange-6.2.0-c9d65a", + "versionInfo": "6.2.0", + "downloadLocation": "NOASSERTION", + "filesAnalyzed": false, + "licenseConcluded": "MPL-2.0", + "copyrightText": "Copyright (c) 2012-2024 J.Sakamoto, Mozilla, Copyright 2012-2024 J.Sakamoto, Mozilla", + "externalRefs": [ + { + "referenceCategory": "PACKAGE-MANAGER", + "referenceType": "purl", + "referenceLocator": "pkg:nuget/IPAddressRange@6.2.0" + } + ] + }, + { + "name": "PuppeteerSharp", + "SPDXID": "SPDXRef-nuget-PuppeteerSharp-20.2.2-18c6e7", + "versionInfo": "20.2.2", + "downloadLocation": "NOASSERTION", + "filesAnalyzed": false, + "licenseConcluded": "MIT", + "externalRefs": [ + { + "referenceCategory": "PACKAGE-MANAGER", + "referenceType": "purl", + "referenceLocator": "pkg:nuget/PuppeteerSharp@20.2.2" + } + ] + }, + { + "name": "Microsoft.Extensions.DependencyInjection", + "SPDXID": "SPDXRef-nuget-Microsoft.Extensions.DependencyInjection-8.0.0-03eab0", + "versionInfo": "8.0.0", + "downloadLocation": "NOASSERTION", + "filesAnalyzed": false, + "licenseConcluded": "MIT", + "copyrightText": "(c) 1997-2005 Sean Eron Anderson, (c) Microsoft Corporation, Copyright (c) .NET Foundation, Copyright (c) .NET Foundation and Contributors, Copyright (c) .NET Foundation Contributors, Copyright (c) 1980, 1986, 1993 The Regents of the University of California, Copyright (c) 1989 by Hewlett-Packard Company, Palo Alto, Ca. \u0026 Digital Equipment Corporation, Maynard, Mass, Copyright (c) 1990- 1993, 1996 Open Software Foundation, Inc., Copyright (c) 1991-2022 Unicode, Inc., Copyright (c) 1995-2022 Jean-loup Gailly and Mark Adler, Copyright (c) 1998 Microsoft, Copyright (c) 1998 Microsoft. To, Copyright (c) 1999 Lucent Technologies, Copyright (c) 2004-2006 Intel Corporation, Copyright (c) 2005-2007, Nick Galbreath, Copyright (c) 2005-2020 Rich Felker, Copyright (c) 2006 Jb Evain (jbevain@gmail.com), Copyright (c) 2007 James Newton-King, Copyright (c) 2008-2016, Wojciech Mula, Copyright (c) 2008-2020 Advanced Micro Devices, Inc., Copyright (c) 2009, 2010, 2013-2016 by the Brotli Authors, Copyright (c) 2011 Novell, Inc (http://www.novell.com), Copyright (c) 2011-2015 Intel Corporation, Copyright (c) 2011-2020 Microsoft Corp, Copyright (c) 2011, Google Inc., Copyright (c) 2012 - present, Victor Zverovich, Copyright (c) 2012-2021 Yann Collet, Copyright (c) 2013-2017, Alfred Klomp, Copyright (c) 2013-2017, Milosz Krajewski, Copyright (c) 2014 Ryan Juckett http://www.ryanjuckett.com, Copyright (c) 2015 The Chromium Authors, Copyright (c) 2015 THL A29 Limited, a Tencent company, and Milo Yip, Copyright (c) 2015 Xamarin, Inc (http://www.xamarin.com), Copyright (c) 2015-2017, Wojciech Mula, Copyright (c) 2016-2017, Matthieu Darbois, Copyright (c) 2017 Yoshifumi Kawai, Copyright (c) 2018 Alexander Chermyanin, Copyright (c) 2019 Microsoft Corporation, Daan Leijen, Copyright (c) 2020 Dan Shechter, Copyright (c) 2020 Mara Bos \u003cm-ou.se@m-ou.se\u003e, Copyright (c) 2021, Copyright (c) 2021 csFastFloat authors, Copyright (c) 2022, Geoff Langdale, Copyright (c) 2022, Wojciech Mula, Copyright (c) Andrew Arnott, Copyright (c) Microsoft Corporation, Copyright (c) Six Labors, Copyright (c) The Internet Society (2003), Copyright (c) The Internet Society 1997, Copyright (c) YEAR W3C(r) (MIT, ERCIM, Keio, Beihang) Disclaimers, Copyright (c) YEAR W3C(r) (MIT, ERCIM, Keio, Beihang). Disclaimers, Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018 The Regents of the University of California, Copyright 2012 the V8 project authors, Copyright 2018 Daniel Lemire, Copyright 2019 LLVM Project, Portions (c) International Organization, Portions (c) International Organization for Standardization 1986", + "externalRefs": [ + { + "referenceCategory": "PACKAGE-MANAGER", + "referenceType": "purl", + "referenceLocator": "pkg:nuget/Microsoft.Extensions.DependencyInjection@8.0.0" + } + ] + }, + { + "name": "BlazorTable", + "SPDXID": "SPDXRef-nuget-BlazorTable-1.17.0-647113", + "versionInfo": "1.17.0", + "downloadLocation": "NOASSERTION", + "filesAnalyzed": false, + "licenseConcluded": "MIT", + "copyrightText": "(c) 2008 VeriSign, Inc.", + "externalRefs": [ + { + "referenceCategory": "PACKAGE-MANAGER", + "referenceType": "purl", + "referenceLocator": "pkg:nuget/BlazorTable@1.17.0" + } + ] + }, + { + "name": "Microsoft.AspNetCore.Components.Analyzers", + "SPDXID": "SPDXRef-nuget-Microsoft.AspNetCore.Components.Analyzers-8.0.15-a1b7ad", + "versionInfo": "8.0.15", + "downloadLocation": "NOASSERTION", + "filesAnalyzed": false, + "licenseConcluded": "MIT", + "copyrightText": "(c) Microsoft Corporation, Copyright (c) .NET Foundation Contributors, Copyright (c) 1989, 1993 The Regents of the University of California, Copyright (c) 1990, 1993 The Regents of the University of California, Copyright (c) 1996-1998 John D. Polstra, Copyright (c) 1998 John D. Polstra, Copyright (c) 2000-2013 Julian Seward, Copyright (c) 2007 John Birrell (jb@freebsd.org), Copyright (c) 2011-2021 The Bootstrap Authors, Copyright (c) 2011-2021 Twitter, Inc., Copyright (c) 2013 - 2018 AngleSharp, Copyright (c) 2019-2023 The Bootstrap Authors", + "externalRefs": [ + { + "referenceCategory": "PACKAGE-MANAGER", + "referenceType": "purl", + "referenceLocator": "pkg:nuget/Microsoft.AspNetCore.Components.Analyzers@8.0.15" + } + ] + }, + { + "name": "Microsoft.Extensions.Logging", + "SPDXID": "SPDXRef-nuget-Microsoft.Extensions.Logging-8.0.0-7574df", + "versionInfo": "8.0.0", + "downloadLocation": "NOASSERTION", + "filesAnalyzed": false, + "licenseConcluded": "MIT", + "copyrightText": "(c) 1997-2005 Sean Eron Anderson, (c) Microsoft Corporation, Copyright (c) .NET Foundation, Copyright (c) .NET Foundation and Contributors, Copyright (c) .NET Foundation Contributors, Copyright (c) 1980, 1986, 1993 The Regents of the University of California, Copyright (c) 1989 by Hewlett-Packard Company, Palo Alto, Ca. \u0026 Digital Equipment Corporation, Maynard, Mass, Copyright (c) 1990- 1993, 1996 Open Software Foundation, Inc., Copyright (c) 1991-2022 Unicode, Inc., Copyright (c) 1995-2022 Jean-loup Gailly and Mark Adler, Copyright (c) 1998 Microsoft, Copyright (c) 1998 Microsoft. To, Copyright (c) 1999 Lucent Technologies, Copyright (c) 2004-2006 Intel Corporation, Copyright (c) 2005-2007, Nick Galbreath, Copyright (c) 2005-2020 Rich Felker, Copyright (c) 2006 Jb Evain (jbevain@gmail.com), Copyright (c) 2007 James Newton-King, Copyright (c) 2008-2016, Wojciech Mula, Copyright (c) 2008-2020 Advanced Micro Devices, Inc., Copyright (c) 2009, 2010, 2013-2016 by the Brotli Authors, Copyright (c) 2011 Novell, Inc (http://www.novell.com), Copyright (c) 2011-2015 Intel Corporation, Copyright (c) 2011-2020 Microsoft Corp, Copyright (c) 2011, Google Inc., Copyright (c) 2012 - present, Victor Zverovich, Copyright (c) 2012-2021 Yann Collet, Copyright (c) 2013-2017, Alfred Klomp, Copyright (c) 2013-2017, Milosz Krajewski, Copyright (c) 2014 Ryan Juckett http://www.ryanjuckett.com, Copyright (c) 2015 The Chromium Authors, Copyright (c) 2015 THL A29 Limited, a Tencent company, and Milo Yip, Copyright (c) 2015 Xamarin, Inc (http://www.xamarin.com), Copyright (c) 2015-2017, Wojciech Mula, Copyright (c) 2016-2017, Matthieu Darbois, Copyright (c) 2017 Yoshifumi Kawai, Copyright (c) 2018 Alexander Chermyanin, Copyright (c) 2019 Microsoft Corporation, Daan Leijen, Copyright (c) 2020 Dan Shechter, Copyright (c) 2020 Mara Bos \u003cm-ou.se@m-ou.se\u003e, Copyright (c) 2021, Copyright (c) 2021 csFastFloat authors, Copyright (c) 2022, Geoff Langdale, Copyright (c) 2022, Wojciech Mula, Copyright (c) Andrew Arnott, Copyright (c) Microsoft Corporation, Copyright (c) Six Labors, Copyright (c) The Internet Society (2003), Copyright (c) The Internet Society 1997, Copyright (c) YEAR W3C(r) (MIT, ERCIM, Keio, Beihang) Disclaimers, Copyright (c) YEAR W3C(r) (MIT, ERCIM, Keio, Beihang). Disclaimers, Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018 The Regents of the University of California, Copyright 2012 the V8 project authors, Copyright 2018 Daniel Lemire, Copyright 2019 LLVM Project, Portions (c) International Organization, Portions (c) International Organization for Standardization 1986", + "externalRefs": [ + { + "referenceCategory": "PACKAGE-MANAGER", + "referenceType": "purl", + "referenceLocator": "pkg:nuget/Microsoft.Extensions.Logging@8.0.0" + } + ] + }, + { + "name": "Microsoft.JSInterop", + "SPDXID": "SPDXRef-nuget-Microsoft.JSInterop-3.1.18-ec5757", + "versionInfo": "3.1.18", + "downloadLocation": "NOASSERTION", + "filesAnalyzed": false, + "licenseConcluded": "Apache-2.0", + "externalRefs": [ + { + "referenceCategory": "PACKAGE-MANAGER", + "referenceType": "purl", + "referenceLocator": "pkg:nuget/Microsoft.JSInterop@3.1.18" + } + ] + }, + { + "name": "LinqKit.Core", + "SPDXID": "SPDXRef-nuget-LinqKit.Core-1.1.26-8271d4", + "versionInfo": "1.1.26", + "downloadLocation": "NOASSERTION", + "filesAnalyzed": false, + "licenseConcluded": "MIT", + "externalRefs": [ + { + "referenceCategory": "PACKAGE-MANAGER", + "referenceType": "purl", + "referenceLocator": "pkg:nuget/LinqKit.Core@1.1.26" + } + ] + }, + { + "name": "Microsoft.Extensions.Localization", + "SPDXID": "SPDXRef-nuget-Microsoft.Extensions.Localization-3.1.18-8fe31d", + "versionInfo": "3.1.18", + "downloadLocation": "NOASSERTION", + "filesAnalyzed": false, + "licenseConcluded": "Apache-2.0", + "externalRefs": [ + { + "referenceCategory": "PACKAGE-MANAGER", + "referenceType": "purl", + "referenceLocator": "pkg:nuget/Microsoft.Extensions.Localization@3.1.18" + } + ] + }, + { + "name": "Microsoft.AspNetCore.Components.Forms", + "SPDXID": "SPDXRef-nuget-Microsoft.AspNetCore.Components.Forms-3.1.18-aa28bb", + "versionInfo": "3.1.18", + "downloadLocation": "NOASSERTION", + "filesAnalyzed": false, + "licenseConcluded": "Apache-2.0", + "externalRefs": [ + { + "referenceCategory": "PACKAGE-MANAGER", + "referenceType": "purl", + "referenceLocator": "pkg:nuget/Microsoft.AspNetCore.Components.Forms@3.1.18" + } + ] + }, + { + "name": "IPAddressRange", + "SPDXID": "SPDXRef-nuget-IPAddressRange-6.2.0-3030d8", + "versionInfo": "6.2.0", + "downloadLocation": "NOASSERTION", + "filesAnalyzed": false, + "licenseConcluded": "MPL-2.0", + "copyrightText": "Copyright (c) 2012-2024 J.Sakamoto, Mozilla, Copyright 2012-2024 J.Sakamoto, Mozilla", + "externalRefs": [ + { + "referenceCategory": "PACKAGE-MANAGER", + "referenceType": "purl", + "referenceLocator": "pkg:nuget/IPAddressRange@6.2.0" + } + ] + }, + { + "name": "Microsoft.Extensions.Primitives", + "SPDXID": "SPDXRef-nuget-Microsoft.Extensions.Primitives-8.0.0-fb04bb", + "versionInfo": "8.0.0", + "downloadLocation": "NOASSERTION", + "filesAnalyzed": false, + "licenseConcluded": "MIT", + "copyrightText": "(c) 1997-2005 Sean Eron Anderson, (c) Microsoft Corporation, Copyright (c) .NET Foundation, Copyright (c) .NET Foundation and Contributors, Copyright (c) .NET Foundation Contributors, Copyright (c) 1980, 1986, 1993 The Regents of the University of California, Copyright (c) 1989 by Hewlett-Packard Company, Palo Alto, Ca. \u0026 Digital Equipment Corporation, Maynard, Mass, Copyright (c) 1990- 1993, 1996 Open Software Foundation, Inc., Copyright (c) 1991-2022 Unicode, Inc., Copyright (c) 1995-2022 Jean-loup Gailly and Mark Adler, Copyright (c) 1998 Microsoft. To, Copyright (c) 1999 Lucent Technologies, Copyright (c) 2004-2006 Intel Corporation, Copyright (c) 2005-2007, Nick Galbreath, Copyright (c) 2005-2020 Rich Felker, Copyright (c) 2006 Jb Evain (jbevain@gmail.com), Copyright (c) 2007 James Newton-King, Copyright (c) 2008-2016, Wojciech Mula, Copyright (c) 2008-2020 Advanced Micro Devices, Inc., Copyright (c) 2009, 2010, 2013-2016 by the Brotli Authors, Copyright (c) 2011 Novell, Inc (http://www.novell.com), Copyright (c) 2011-2015 Intel Corporation, Copyright (c) 2011-2020 Microsoft Corp, Copyright (c) 2011, Google Inc., Copyright (c) 2012 - present, Victor Zverovich, Copyright (c) 2012-2021 Yann Collet, Copyright (c) 2013-2017, Alfred Klomp, Copyright (c) 2013-2017, Milosz Krajewski, Copyright (c) 2014 Ryan Juckett http://www.ryanjuckett.com, Copyright (c) 2015 The Chromium Authors, Copyright (c) 2015 THL A29 Limited, a Tencent company, and Milo Yip, Copyright (c) 2015 Xamarin, Inc (http://www.xamarin.com), Copyright (c) 2015-2017, Wojciech Mula, Copyright (c) 2016-2017, Matthieu Darbois, Copyright (c) 2017 Yoshifumi Kawai, Copyright (c) 2018 Alexander Chermyanin, Copyright (c) 2019 Microsoft Corporation, Daan Leijen, Copyright (c) 2020 Dan Shechter, Copyright (c) 2020 Mara Bos \u003cm-ou.se@m-ou.se\u003e, Copyright (c) 2021 csFastFloat authors, Copyright (c) 2022, Geoff Langdale, Copyright (c) 2022, Wojciech Mula, Copyright (c) Andrew Arnott, Copyright (c) Microsoft Corporation, Copyright (c) Six Labors, Copyright (c) The Internet Society (2003), Copyright (c) The Internet Society 1997, Copyright (c) YEAR W3C(r) (MIT, ERCIM, Keio, Beihang). Disclaimers, Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018 The Regents of the University of California, Copyright 2012 the V8 project authors, Copyright 2018 Daniel Lemire, Copyright 2019 LLVM Project, Portions (c) International Organization", + "externalRefs": [ + { + "referenceCategory": "PACKAGE-MANAGER", + "referenceType": "purl", + "referenceLocator": "pkg:nuget/Microsoft.Extensions.Primitives@8.0.0" + } + ] + }, + { + "name": "Microsoft.AspNetCore.Authorization", + "SPDXID": "SPDXRef-nuget-Microsoft.AspNetCore.Authorization-8.0.15-3bb48c", + "versionInfo": "8.0.15", + "downloadLocation": "NOASSERTION", + "filesAnalyzed": false, + "licenseConcluded": "MIT", + "copyrightText": "(c) Microsoft Corporation, Copyright (c) .NET Foundation and Contributors, Copyright (c) .NET Foundation Contributors, Copyright (c) 1989, 1993 The Regents of the University of California, Copyright (c) 1990, 1993 The Regents of the University of California, Copyright (c) 1996-1998 John D. Polstra, Copyright (c) 1998 John D. Polstra, Copyright (c) 2000-2013 Julian Seward, Copyright (c) 2007 James Newton-King, Copyright (c) 2007 John Birrell (jb@freebsd.org), Copyright (c) 2010-2019 Google LLC. http://angular.io/license, Copyright (c) 2011 Alex MacCaw (info@eribium.org), Copyright (c) 2011 Nicolas Gallagher (nicolas@nicolasgallagher.com), Copyright (c) 2011-2021 The Bootstrap Authors, Copyright (c) 2011-2021 Twitter, Inc., Copyright (c) 2013 - 2018 AngleSharp, Copyright (c) 2013-2017, Milosz Krajewski, Copyright (c) 2014-2018 Michael Daines, Copyright (c) 2015, Google Inc., Copyright (c) 2016 Richard Morris, Copyright (c) 2017 Yoshifumi Kawai, Copyright (c) 2019 David Fowler, Copyright (c) 2019-2020 West Wind Technologies, Copyright (c) 2019-2023 The Bootstrap Authors, Copyright (c) Andrew Arnott, Copyright (c) HTML5 Boilerplate, Copyright (c) Microsoft Corporation, Copyright (c) Nicolas Gallagher and Jonathan Neal, Copyright (c) Sindre Sorhus \u003csindresorhus@gmail.com\u003e (https://sindresorhus.com), Copyright 2019 The gRPC Authors, Copyright Jorn Zaefferer, Copyright OpenJS Foundation and other contributors, https://openjsf.org", + "externalRefs": [ + { + "referenceCategory": "PACKAGE-MANAGER", + "referenceType": "purl", + "referenceLocator": "pkg:nuget/Microsoft.AspNetCore.Authorization@8.0.15" + } + ] + }, + { + "name": "Microsoft.Extensions.Logging.Abstractions", + "SPDXID": "SPDXRef-nuget-Microsoft.Extensions.Logging.Abstractions-8.0.3-318844", + "versionInfo": "8.0.3", + "downloadLocation": "NOASSERTION", + "filesAnalyzed": false, + "licenseConcluded": "MIT", + "copyrightText": "(c) 1997-2005 Sean Eron Anderson, (c) Microsoft Corporation, Copyright (c) .NET Foundation, Copyright (c) .NET Foundation and Contributors, Copyright (c) .NET Foundation Contributors, Copyright (c) 1980, 1986, 1993 The Regents of the University of California, Copyright (c) 1989 by Hewlett-Packard Company, Palo Alto, Ca. \u0026 Digital Equipment Corporation, Maynard, Mass, Copyright (c) 1990- 1993, 1996 Open Software Foundation, Inc., Copyright (c) 1991-2022 Unicode, Inc., Copyright (c) 1995-2022 Jean-loup Gailly and Mark Adler, Copyright (c) 1998 Microsoft, Copyright (c) 1999 Lucent Technologies, Copyright (c) 2004-2006 Intel Corporation, Copyright (c) 2005-2007, Nick Galbreath, Copyright (c) 2005-2020 Rich Felker, Copyright (c) 2006 Jb Evain (jbevain@gmail.com), Copyright (c) 2007 James Newton-King, Copyright (c) 2008-2016, Wojciech Mula, Copyright (c) 2008-2020 Advanced Micro Devices, Inc., Copyright (c) 2009, 2010, 2013-2016 by the Brotli Authors, Copyright (c) 2011 Novell, Inc (http://www.novell.com), Copyright (c) 2011-2015 Intel Corporation, Copyright (c) 2011-2020 Microsoft Corp, Copyright (c) 2011, Google Inc., Copyright (c) 2012 - present, Victor Zverovich, Copyright (c) 2012-2021 Yann Collet, Copyright (c) 2013-2017, Alfred Klomp, Copyright (c) 2013-2017, Milosz Krajewski, Copyright (c) 2014 Ryan Juckett http://www.ryanjuckett.com, Copyright (c) 2015 The Chromium Authors, Copyright (c) 2015 THL A29 Limited, a Tencent company, and Milo Yip, Copyright (c) 2015 Xamarin, Inc (http://www.xamarin.com), Copyright (c) 2015-2017, Wojciech Mula, Copyright (c) 2016-2017, Matthieu Darbois, Copyright (c) 2017 Yoshifumi Kawai, Copyright (c) 2018 Alexander Chermyanin, Copyright (c) 2019 Microsoft Corporation, Daan Leijen, Copyright (c) 2020 Dan Shechter, Copyright (c) 2020 Mara Bos \u003cm-ou.se@m-ou.se\u003e, Copyright (c) 2021, Copyright (c) 2022, Geoff Langdale, Copyright (c) 2022, Wojciech Mula, Copyright (c) Andrew Arnott, Copyright (c) Microsoft Corporation, Copyright (c) Six Labors, Copyright (c) The Internet Society (2003), Copyright (c) The Internet Society 1997, Copyright (c) YEAR W3C(r) (MIT, ERCIM, Keio, Beihang) Disclaimers, Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018 The Regents of the University of California, Copyright 2012 the V8 project authors, Copyright 2018 Daniel Lemire, Copyright 2019 LLVM Project, Portions (c) International Organization for Standardization 1986", + "externalRefs": [ + { + "referenceCategory": "PACKAGE-MANAGER", + "referenceType": "purl", + "referenceLocator": "pkg:nuget/Microsoft.Extensions.Logging.Abstractions@8.0.3" + } + ] + }, + { + "name": "Microsoft.AspNetCore.Components", + "SPDXID": "SPDXRef-nuget-Microsoft.AspNetCore.Components-8.0.15-2782e6", + "versionInfo": "8.0.15", + "downloadLocation": "NOASSERTION", + "filesAnalyzed": false, + "licenseConcluded": "MIT", + "copyrightText": "(c) Microsoft Corporation, Copyright (c) .NET Foundation Contributors, Copyright (c) 1989, 1993 The Regents of the University of California, Copyright (c) 1990, 1993 The Regents of the University of California, Copyright (c) 1996-1998 John D. Polstra, Copyright (c) 1998 John D. Polstra, Copyright (c) 2000-2013 Julian Seward, Copyright (c) 2007 John Birrell (jb@freebsd.org), Copyright (c) 2011-2021 The Bootstrap Authors, Copyright (c) 2011-2021 Twitter, Inc., Copyright (c) 2013 - 2018 AngleSharp, Copyright (c) 2019-2023 The Bootstrap Authors", + "externalRefs": [ + { + "referenceCategory": "PACKAGE-MANAGER", + "referenceType": "purl", + "referenceLocator": "pkg:nuget/Microsoft.AspNetCore.Components@8.0.15" + } + ] + }, + { + "name": "Microsoft.AspNetCore.Components.Web", + "SPDXID": "SPDXRef-nuget-Microsoft.AspNetCore.Components.Web-3.1.18-2b319e", + "versionInfo": "3.1.18", + "downloadLocation": "NOASSERTION", + "filesAnalyzed": false, + "licenseConcluded": "Apache-2.0", + "externalRefs": [ + { + "referenceCategory": "PACKAGE-MANAGER", + "referenceType": "purl", + "referenceLocator": "pkg:nuget/Microsoft.AspNetCore.Components.Web@3.1.18" + } + ] + }, + { + "name": "Microsoft.Extensions.Localization.Abstractions", + "SPDXID": "SPDXRef-nuget-Microsoft.Extensions.Localization.Abstractions-3.1.18-552d34", + "versionInfo": "3.1.18", + "downloadLocation": "NOASSERTION", + "filesAnalyzed": false, + "licenseConcluded": "Apache-2.0", + "copyrightText": "(c) 2008 VeriSign, Inc., (c) Microsoft Corporation.", + "externalRefs": [ + { + "referenceCategory": "PACKAGE-MANAGER", + "referenceType": "purl", + "referenceLocator": "pkg:nuget/Microsoft.Extensions.Localization.Abstractions@3.1.18" + } + ] + }, + { + "name": "Microsoft.Extensions.Options", + "SPDXID": "SPDXRef-nuget-Microsoft.Extensions.Options-8.0.2-43de69", + "versionInfo": "8.0.2", + "downloadLocation": "NOASSERTION", + "filesAnalyzed": false, + "licenseConcluded": "MIT", + "copyrightText": "(c) 1997-2005 Sean Eron Anderson, (c) Microsoft Corporation, Copyright (c) .NET Foundation, Copyright (c) .NET Foundation and Contributors, Copyright (c) .NET Foundation Contributors, Copyright (c) 1980, 1986, 1993 The Regents of the University of California, Copyright (c) 1989 by Hewlett-Packard Company, Palo Alto, Ca. \u0026 Digital Equipment Corporation, Maynard, Mass, Copyright (c) 1990- 1993, 1996 Open Software Foundation, Inc., Copyright (c) 1991-2022 Unicode, Inc., Copyright (c) 1995-2022 Jean-loup Gailly and Mark Adler, Copyright (c) 1998 Microsoft. To, Copyright (c) 1999 Lucent Technologies, Copyright (c) 2004-2006 Intel Corporation, Copyright (c) 2005-2007, Nick Galbreath, Copyright (c) 2005-2020 Rich Felker, Copyright (c) 2006 Jb Evain (jbevain@gmail.com), Copyright (c) 2007 James Newton-King, Copyright (c) 2008-2016, Wojciech Mula, Copyright (c) 2008-2020 Advanced Micro Devices, Inc., Copyright (c) 2009, 2010, 2013-2016 by the Brotli Authors, Copyright (c) 2011 Novell, Inc (http://www.novell.com), Copyright (c) 2011-2015 Intel Corporation, Copyright (c) 2011-2020 Microsoft Corp, Copyright (c) 2011, Google Inc., Copyright (c) 2012 - present, Victor Zverovich, Copyright (c) 2012-2021 Yann Collet, Copyright (c) 2013-2017, Alfred Klomp, Copyright (c) 2013-2017, Milosz Krajewski, Copyright (c) 2014 Ryan Juckett http://www.ryanjuckett.com, Copyright (c) 2015 The Chromium Authors, Copyright (c) 2015 THL A29 Limited, a Tencent company, and Milo Yip, Copyright (c) 2015 Xamarin, Inc (http://www.xamarin.com), Copyright (c) 2015-2017, Wojciech Mula, Copyright (c) 2016-2017, Matthieu Darbois, Copyright (c) 2017 Yoshifumi Kawai, Copyright (c) 2018 Alexander Chermyanin, Copyright (c) 2019 Microsoft Corporation, Daan Leijen, Copyright (c) 2020 Dan Shechter, Copyright (c) 2020 Mara Bos \u003cm-ou.se@m-ou.se\u003e, Copyright (c) 2021 csFastFloat authors, Copyright (c) 2022, Geoff Langdale, Copyright (c) 2022, Wojciech Mula, Copyright (c) Andrew Arnott, Copyright (c) Microsoft Corporation, Copyright (c) Six Labors, Copyright (c) The Internet Society (2003), Copyright (c) The Internet Society 1997, Copyright (c) YEAR W3C(r) (MIT, ERCIM, Keio, Beihang). Disclaimers, Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018 The Regents of the University of California, Copyright 2012 the V8 project authors, Copyright 2018 Daniel Lemire, Copyright 2019 LLVM Project, Portions (c) International Organization", + "externalRefs": [ + { + "referenceCategory": "PACKAGE-MANAGER", + "referenceType": "purl", + "referenceLocator": "pkg:nuget/Microsoft.Extensions.Options@8.0.2" + } + ] + }, + { + "name": "Microsoft.AspNetCore.Metadata", + "SPDXID": "SPDXRef-nuget-Microsoft.AspNetCore.Metadata-8.0.15-d16054", + "versionInfo": "8.0.15", + "downloadLocation": "NOASSERTION", + "filesAnalyzed": false, + "licenseConcluded": "MIT", + "copyrightText": "(c) Microsoft Corporation, Copyright (c) .NET Foundation and Contributors, Copyright (c) .NET Foundation Contributors, Copyright (c) 1989, 1993 The Regents of the University of California, Copyright (c) 1990, 1993 The Regents of the University of California, Copyright (c) 1996-1998 John D. Polstra, Copyright (c) 1998 John D. Polstra, Copyright (c) 2000-2013 Julian Seward, Copyright (c) 2007 James Newton-King, Copyright (c) 2007 John Birrell (jb@freebsd.org), Copyright (c) 2010-2019 Google LLC. http://angular.io/license, Copyright (c) 2011 Alex MacCaw (info@eribium.org), Copyright (c) 2011 Nicolas Gallagher (nicolas@nicolasgallagher.com), Copyright (c) 2011-2021 The Bootstrap Authors, Copyright (c) 2011-2021 Twitter, Inc., Copyright (c) 2013 - 2018 AngleSharp, Copyright (c) 2013-2017, Milosz Krajewski, Copyright (c) 2014-2018 Michael Daines, Copyright (c) 2015, Google Inc., Copyright (c) 2016 Richard Morris, Copyright (c) 2017 Yoshifumi Kawai, Copyright (c) 2019 David Fowler, Copyright (c) 2019-2020 West Wind Technologies, Copyright (c) 2019-2023 The Bootstrap Authors, Copyright (c) Andrew Arnott, Copyright (c) HTML5 Boilerplate, Copyright (c) Microsoft Corporation, Copyright (c) Nicolas Gallagher and Jonathan Neal, Copyright (c) Sindre Sorhus \u003csindresorhus@gmail.com\u003e (https://sindresorhus.com), Copyright 2019 The gRPC Authors, Copyright Jorn Zaefferer, Copyright OpenJS Foundation and other contributors, https://openjsf.org", + "externalRefs": [ + { + "referenceCategory": "PACKAGE-MANAGER", + "referenceType": "purl", + "referenceLocator": "pkg:nuget/Microsoft.AspNetCore.Metadata@8.0.15" + } + ] + }, + { + "name": "Microsoft.Extensions.DependencyInjection.Abstractions", + "SPDXID": "SPDXRef-nuget-Microsoft.Extensions.DependencyInjection.Abstractions-8.0.2-f0b5b3", + "versionInfo": "8.0.2", + "downloadLocation": "NOASSERTION", + "filesAnalyzed": false, + "licenseConcluded": "MIT", + "copyrightText": "(c) 1997-2005 Sean Eron Anderson, (c) Microsoft Corporation, Copyright (c) .NET Foundation, Copyright (c) .NET Foundation and Contributors, Copyright (c) .NET Foundation Contributors, Copyright (c) 1980, 1986, 1993 The Regents of the University of California, Copyright (c) 1989 by Hewlett-Packard Company, Palo Alto, Ca. \u0026 Digital Equipment Corporation, Maynard, Mass, Copyright (c) 1990- 1993, 1996 Open Software Foundation, Inc., Copyright (c) 1991-2022 Unicode, Inc., Copyright (c) 1995-2022 Jean-loup Gailly and Mark Adler, Copyright (c) 1998 Microsoft. To, Copyright (c) 1999 Lucent Technologies, Copyright (c) 2004-2006 Intel Corporation, Copyright (c) 2005-2007, Nick Galbreath, Copyright (c) 2005-2020 Rich Felker, Copyright (c) 2006 Jb Evain (jbevain@gmail.com), Copyright (c) 2007 James Newton-King, Copyright (c) 2008-2016, Wojciech Mula, Copyright (c) 2008-2020 Advanced Micro Devices, Inc., Copyright (c) 2009, 2010, 2013-2016 by the Brotli Authors, Copyright (c) 2011 Novell, Inc (http://www.novell.com), Copyright (c) 2011-2015 Intel Corporation, Copyright (c) 2011-2020 Microsoft Corp, Copyright (c) 2011, Google Inc., Copyright (c) 2012 - present, Victor Zverovich, Copyright (c) 2012-2021 Yann Collet, Copyright (c) 2013-2017, Alfred Klomp, Copyright (c) 2013-2017, Milosz Krajewski, Copyright (c) 2014 Ryan Juckett http://www.ryanjuckett.com, Copyright (c) 2015 The Chromium Authors, Copyright (c) 2015 THL A29 Limited, a Tencent company, and Milo Yip, Copyright (c) 2015 Xamarin, Inc (http://www.xamarin.com), Copyright (c) 2015-2017, Wojciech Mula, Copyright (c) 2016-2017, Matthieu Darbois, Copyright (c) 2017 Yoshifumi Kawai, Copyright (c) 2018 Alexander Chermyanin, Copyright (c) 2019 Microsoft Corporation, Daan Leijen, Copyright (c) 2020 Dan Shechter, Copyright (c) 2020 Mara Bos \u003cm-ou.se@m-ou.se\u003e, Copyright (c) 2021 csFastFloat authors, Copyright (c) 2022, Geoff Langdale, Copyright (c) 2022, Wojciech Mula, Copyright (c) Andrew Arnott, Copyright (c) Microsoft Corporation, Copyright (c) Six Labors, Copyright (c) The Internet Society (2003), Copyright (c) The Internet Society 1997, Copyright (c) YEAR W3C(r) (MIT, ERCIM, Keio, Beihang). Disclaimers, Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018 The Regents of the University of California, Copyright 2012 the V8 project authors, Copyright 2018 Daniel Lemire, Copyright 2019 LLVM Project, Portions (c) International Organization", + "externalRefs": [ + { + "referenceCategory": "PACKAGE-MANAGER", + "referenceType": "purl", + "referenceLocator": "pkg:nuget/Microsoft.Extensions.DependencyInjection.Abstractions@8.0.2" + } + ] + }, + { + "name": "GraphQL.Client.Abstractions", + "SPDXID": "SPDXRef-nuget-GraphQL.Client.Abstractions-6.1.0-94d0f3", + "versionInfo": "6.1.0", + "downloadLocation": "NOASSERTION", + "filesAnalyzed": false, + "licenseConcluded": "MIT", + "copyrightText": "Copyright (c) 2017 graphql-dotnet", + "externalRefs": [ + { + "referenceCategory": "PACKAGE-MANAGER", + "referenceType": "purl", + "referenceLocator": "pkg:nuget/GraphQL.Client.Abstractions@6.1.0" + } + ] + }, + { + "name": "GraphQL.Primitives", + "SPDXID": "SPDXRef-nuget-GraphQL.Primitives-6.1.0-0e1997", + "versionInfo": "6.1.0", + "downloadLocation": "NOASSERTION", + "filesAnalyzed": false, + "licenseConcluded": "MIT", + "copyrightText": "Copyright (c) 2017 graphql-dotnet", + "externalRefs": [ + { + "referenceCategory": "PACKAGE-MANAGER", + "referenceType": "purl", + "referenceLocator": "pkg:nuget/GraphQL.Primitives@6.1.0" + } + ] + }, + { + "name": "Microsoft.Extensions.Primitives", + "SPDXID": "SPDXRef-nuget-Microsoft.Extensions.Primitives-8.0.0-f4af79", + "versionInfo": "8.0.0", + "downloadLocation": "NOASSERTION", + "filesAnalyzed": false, + "licenseConcluded": "MIT", + "copyrightText": "(c) 1997-2005 Sean Eron Anderson, (c) Microsoft Corporation, Copyright (c) .NET Foundation, Copyright (c) .NET Foundation and Contributors, Copyright (c) .NET Foundation Contributors, Copyright (c) 1980, 1986, 1993 The Regents of the University of California, Copyright (c) 1989 by Hewlett-Packard Company, Palo Alto, Ca. \u0026 Digital Equipment Corporation, Maynard, Mass, Copyright (c) 1990- 1993, 1996 Open Software Foundation, Inc., Copyright (c) 1991-2022 Unicode, Inc., Copyright (c) 1995-2022 Jean-loup Gailly and Mark Adler, Copyright (c) 1998 Microsoft. To, Copyright (c) 1999 Lucent Technologies, Copyright (c) 2004-2006 Intel Corporation, Copyright (c) 2005-2007, Nick Galbreath, Copyright (c) 2005-2020 Rich Felker, Copyright (c) 2006 Jb Evain (jbevain@gmail.com), Copyright (c) 2007 James Newton-King, Copyright (c) 2008-2016, Wojciech Mula, Copyright (c) 2008-2020 Advanced Micro Devices, Inc., Copyright (c) 2009, 2010, 2013-2016 by the Brotli Authors, Copyright (c) 2011 Novell, Inc (http://www.novell.com), Copyright (c) 2011-2015 Intel Corporation, Copyright (c) 2011-2020 Microsoft Corp, Copyright (c) 2011, Google Inc., Copyright (c) 2012 - present, Victor Zverovich, Copyright (c) 2012-2021 Yann Collet, Copyright (c) 2013-2017, Alfred Klomp, Copyright (c) 2013-2017, Milosz Krajewski, Copyright (c) 2014 Ryan Juckett http://www.ryanjuckett.com, Copyright (c) 2015 The Chromium Authors, Copyright (c) 2015 THL A29 Limited, a Tencent company, and Milo Yip, Copyright (c) 2015 Xamarin, Inc (http://www.xamarin.com), Copyright (c) 2015-2017, Wojciech Mula, Copyright (c) 2016-2017, Matthieu Darbois, Copyright (c) 2017 Yoshifumi Kawai, Copyright (c) 2018 Alexander Chermyanin, Copyright (c) 2019 Microsoft Corporation, Daan Leijen, Copyright (c) 2020 Dan Shechter, Copyright (c) 2020 Mara Bos \u003cm-ou.se@m-ou.se\u003e, Copyright (c) 2021 csFastFloat authors, Copyright (c) 2022, Geoff Langdale, Copyright (c) 2022, Wojciech Mula, Copyright (c) Andrew Arnott, Copyright (c) Microsoft Corporation, Copyright (c) Six Labors, Copyright (c) The Internet Society (2003), Copyright (c) The Internet Society 1997, Copyright (c) YEAR W3C(r) (MIT, ERCIM, Keio, Beihang). Disclaimers, Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018 The Regents of the University of California, Copyright 2012 the V8 project authors, Copyright 2018 Daniel Lemire, Copyright 2019 LLVM Project, Portions (c) International Organization", + "externalRefs": [ + { + "referenceCategory": "PACKAGE-MANAGER", + "referenceType": "purl", + "referenceLocator": "pkg:nuget/Microsoft.Extensions.Primitives@8.0.0" + } + ] + }, + { + "name": "Microsoft.Extensions.DependencyInjection.Abstractions", + "SPDXID": "SPDXRef-nuget-Microsoft.Extensions.DependencyInjection.Abstractions-8.0.2-32a665", + "versionInfo": "8.0.2", + "downloadLocation": "NOASSERTION", + "filesAnalyzed": false, + "licenseConcluded": "MIT", + "copyrightText": "(c) 1997-2005 Sean Eron Anderson, (c) Microsoft Corporation, Copyright (c) .NET Foundation, Copyright (c) .NET Foundation and Contributors, Copyright (c) .NET Foundation Contributors, Copyright (c) 1980, 1986, 1993 The Regents of the University of California, Copyright (c) 1989 by Hewlett-Packard Company, Palo Alto, Ca. \u0026 Digital Equipment Corporation, Maynard, Mass, Copyright (c) 1990- 1993, 1996 Open Software Foundation, Inc., Copyright (c) 1991-2022 Unicode, Inc., Copyright (c) 1995-2022 Jean-loup Gailly and Mark Adler, Copyright (c) 1998 Microsoft. To, Copyright (c) 1999 Lucent Technologies, Copyright (c) 2004-2006 Intel Corporation, Copyright (c) 2005-2007, Nick Galbreath, Copyright (c) 2005-2020 Rich Felker, Copyright (c) 2006 Jb Evain (jbevain@gmail.com), Copyright (c) 2007 James Newton-King, Copyright (c) 2008-2016, Wojciech Mula, Copyright (c) 2008-2020 Advanced Micro Devices, Inc., Copyright (c) 2009, 2010, 2013-2016 by the Brotli Authors, Copyright (c) 2011 Novell, Inc (http://www.novell.com), Copyright (c) 2011-2015 Intel Corporation, Copyright (c) 2011-2020 Microsoft Corp, Copyright (c) 2011, Google Inc., Copyright (c) 2012 - present, Victor Zverovich, Copyright (c) 2012-2021 Yann Collet, Copyright (c) 2013-2017, Alfred Klomp, Copyright (c) 2013-2017, Milosz Krajewski, Copyright (c) 2014 Ryan Juckett http://www.ryanjuckett.com, Copyright (c) 2015 The Chromium Authors, Copyright (c) 2015 THL A29 Limited, a Tencent company, and Milo Yip, Copyright (c) 2015 Xamarin, Inc (http://www.xamarin.com), Copyright (c) 2015-2017, Wojciech Mula, Copyright (c) 2016-2017, Matthieu Darbois, Copyright (c) 2017 Yoshifumi Kawai, Copyright (c) 2018 Alexander Chermyanin, Copyright (c) 2019 Microsoft Corporation, Daan Leijen, Copyright (c) 2020 Dan Shechter, Copyright (c) 2020 Mara Bos \u003cm-ou.se@m-ou.se\u003e, Copyright (c) 2021 csFastFloat authors, Copyright (c) 2022, Geoff Langdale, Copyright (c) 2022, Wojciech Mula, Copyright (c) Andrew Arnott, Copyright (c) Microsoft Corporation, Copyright (c) Six Labors, Copyright (c) The Internet Society (2003), Copyright (c) The Internet Society 1997, Copyright (c) YEAR W3C(r) (MIT, ERCIM, Keio, Beihang). Disclaimers, Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018 The Regents of the University of California, Copyright 2012 the V8 project authors, Copyright 2018 Daniel Lemire, Copyright 2019 LLVM Project, Portions (c) International Organization", + "externalRefs": [ + { + "referenceCategory": "PACKAGE-MANAGER", + "referenceType": "purl", + "referenceLocator": "pkg:nuget/Microsoft.Extensions.DependencyInjection.Abstractions@8.0.2" + } + ] + }, + { + "name": "Microsoft.Extensions.Options", + "SPDXID": "SPDXRef-nuget-Microsoft.Extensions.Options-8.0.2-4cac30", + "versionInfo": "8.0.2", + "downloadLocation": "NOASSERTION", + "filesAnalyzed": false, + "licenseConcluded": "MIT", + "copyrightText": "(c) 1997-2005 Sean Eron Anderson, (c) Microsoft Corporation, Copyright (c) .NET Foundation, Copyright (c) .NET Foundation and Contributors, Copyright (c) .NET Foundation Contributors, Copyright (c) 1980, 1986, 1993 The Regents of the University of California, Copyright (c) 1989 by Hewlett-Packard Company, Palo Alto, Ca. \u0026 Digital Equipment Corporation, Maynard, Mass, Copyright (c) 1990- 1993, 1996 Open Software Foundation, Inc., Copyright (c) 1991-2022 Unicode, Inc., Copyright (c) 1995-2022 Jean-loup Gailly and Mark Adler, Copyright (c) 1998 Microsoft. To, Copyright (c) 1999 Lucent Technologies, Copyright (c) 2004-2006 Intel Corporation, Copyright (c) 2005-2007, Nick Galbreath, Copyright (c) 2005-2020 Rich Felker, Copyright (c) 2006 Jb Evain (jbevain@gmail.com), Copyright (c) 2007 James Newton-King, Copyright (c) 2008-2016, Wojciech Mula, Copyright (c) 2008-2020 Advanced Micro Devices, Inc., Copyright (c) 2009, 2010, 2013-2016 by the Brotli Authors, Copyright (c) 2011 Novell, Inc (http://www.novell.com), Copyright (c) 2011-2015 Intel Corporation, Copyright (c) 2011-2020 Microsoft Corp, Copyright (c) 2011, Google Inc., Copyright (c) 2012 - present, Victor Zverovich, Copyright (c) 2012-2021 Yann Collet, Copyright (c) 2013-2017, Alfred Klomp, Copyright (c) 2013-2017, Milosz Krajewski, Copyright (c) 2014 Ryan Juckett http://www.ryanjuckett.com, Copyright (c) 2015 The Chromium Authors, Copyright (c) 2015 THL A29 Limited, a Tencent company, and Milo Yip, Copyright (c) 2015 Xamarin, Inc (http://www.xamarin.com), Copyright (c) 2015-2017, Wojciech Mula, Copyright (c) 2016-2017, Matthieu Darbois, Copyright (c) 2017 Yoshifumi Kawai, Copyright (c) 2018 Alexander Chermyanin, Copyright (c) 2019 Microsoft Corporation, Daan Leijen, Copyright (c) 2020 Dan Shechter, Copyright (c) 2020 Mara Bos \u003cm-ou.se@m-ou.se\u003e, Copyright (c) 2021 csFastFloat authors, Copyright (c) 2022, Geoff Langdale, Copyright (c) 2022, Wojciech Mula, Copyright (c) Andrew Arnott, Copyright (c) Microsoft Corporation, Copyright (c) Six Labors, Copyright (c) The Internet Society (2003), Copyright (c) The Internet Society 1997, Copyright (c) YEAR W3C(r) (MIT, ERCIM, Keio, Beihang). Disclaimers, Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018 The Regents of the University of California, Copyright 2012 the V8 project authors, Copyright 2018 Daniel Lemire, Copyright 2019 LLVM Project, Portions (c) International Organization", + "externalRefs": [ + { + "referenceCategory": "PACKAGE-MANAGER", + "referenceType": "purl", + "referenceLocator": "pkg:nuget/Microsoft.Extensions.Options@8.0.2" + } + ] + }, + { + "name": "GraphQL.Client.Abstractions.Websocket", + "SPDXID": "SPDXRef-nuget-GraphQL.Client.Abstractions.Websocket-6.1.0-9c814e", + "versionInfo": "6.1.0", + "downloadLocation": "NOASSERTION", + "filesAnalyzed": false, + "licenseConcluded": "MIT", + "copyrightText": "Copyright (c) 2017 graphql-dotnet", + "externalRefs": [ + { + "referenceCategory": "PACKAGE-MANAGER", + "referenceType": "purl", + "referenceLocator": "pkg:nuget/GraphQL.Client.Abstractions.Websocket@6.1.0" + } + ] + }, + { + "name": "GraphQL.Client.Serializer.Newtonsoft", + "SPDXID": "SPDXRef-nuget-GraphQL.Client.Serializer.Newtonsoft-6.1.0-af029d", + "versionInfo": "6.1.0", + "downloadLocation": "NOASSERTION", + "filesAnalyzed": false, + "licenseConcluded": "MIT", + "copyrightText": "Copyright (c) 2017 graphql-dotnet", + "externalRefs": [ + { + "referenceCategory": "PACKAGE-MANAGER", + "referenceType": "purl", + "referenceLocator": "pkg:nuget/GraphQL.Client.Serializer.Newtonsoft@6.1.0" + } + ] + }, + { + "name": "Microsoft.AspNetCore.Components", + "SPDXID": "SPDXRef-nuget-Microsoft.AspNetCore.Components-8.0.15-869df9", + "versionInfo": "8.0.15", + "downloadLocation": "NOASSERTION", + "filesAnalyzed": false, + "licenseConcluded": "MIT", + "copyrightText": "(c) Microsoft Corporation, Copyright (c) .NET Foundation Contributors, Copyright (c) 1989, 1993 The Regents of the University of California, Copyright (c) 1990, 1993 The Regents of the University of California, Copyright (c) 1996-1998 John D. Polstra, Copyright (c) 1998 John D. Polstra, Copyright (c) 2000-2013 Julian Seward, Copyright (c) 2007 John Birrell (jb@freebsd.org), Copyright (c) 2011-2021 The Bootstrap Authors, Copyright (c) 2011-2021 Twitter, Inc., Copyright (c) 2013 - 2018 AngleSharp, Copyright (c) 2019-2023 The Bootstrap Authors", + "externalRefs": [ + { + "referenceCategory": "PACKAGE-MANAGER", + "referenceType": "purl", + "referenceLocator": "pkg:nuget/Microsoft.AspNetCore.Components@8.0.15" + } + ] + }, + { + "name": "Microsoft.Extensions.Logging.Abstractions", + "SPDXID": "SPDXRef-nuget-Microsoft.Extensions.Logging.Abstractions-8.0.3-bc822b", + "versionInfo": "8.0.3", + "downloadLocation": "NOASSERTION", + "filesAnalyzed": false, + "licenseConcluded": "MIT", + "copyrightText": "(c) 1997-2005 Sean Eron Anderson, (c) Microsoft Corporation, Copyright (c) .NET Foundation, Copyright (c) .NET Foundation and Contributors, Copyright (c) .NET Foundation Contributors, Copyright (c) 1980, 1986, 1993 The Regents of the University of California, Copyright (c) 1989 by Hewlett-Packard Company, Palo Alto, Ca. \u0026 Digital Equipment Corporation, Maynard, Mass, Copyright (c) 1990- 1993, 1996 Open Software Foundation, Inc., Copyright (c) 1991-2022 Unicode, Inc., Copyright (c) 1995-2022 Jean-loup Gailly and Mark Adler, Copyright (c) 1998 Microsoft, Copyright (c) 1999 Lucent Technologies, Copyright (c) 2004-2006 Intel Corporation, Copyright (c) 2005-2007, Nick Galbreath, Copyright (c) 2005-2020 Rich Felker, Copyright (c) 2006 Jb Evain (jbevain@gmail.com), Copyright (c) 2007 James Newton-King, Copyright (c) 2008-2016, Wojciech Mula, Copyright (c) 2008-2020 Advanced Micro Devices, Inc., Copyright (c) 2009, 2010, 2013-2016 by the Brotli Authors, Copyright (c) 2011 Novell, Inc (http://www.novell.com), Copyright (c) 2011-2015 Intel Corporation, Copyright (c) 2011-2020 Microsoft Corp, Copyright (c) 2011, Google Inc., Copyright (c) 2012 - present, Victor Zverovich, Copyright (c) 2012-2021 Yann Collet, Copyright (c) 2013-2017, Alfred Klomp, Copyright (c) 2013-2017, Milosz Krajewski, Copyright (c) 2014 Ryan Juckett http://www.ryanjuckett.com, Copyright (c) 2015 The Chromium Authors, Copyright (c) 2015 THL A29 Limited, a Tencent company, and Milo Yip, Copyright (c) 2015 Xamarin, Inc (http://www.xamarin.com), Copyright (c) 2015-2017, Wojciech Mula, Copyright (c) 2016-2017, Matthieu Darbois, Copyright (c) 2017 Yoshifumi Kawai, Copyright (c) 2018 Alexander Chermyanin, Copyright (c) 2019 Microsoft Corporation, Daan Leijen, Copyright (c) 2020 Dan Shechter, Copyright (c) 2020 Mara Bos \u003cm-ou.se@m-ou.se\u003e, Copyright (c) 2021, Copyright (c) 2022, Geoff Langdale, Copyright (c) 2022, Wojciech Mula, Copyright (c) Andrew Arnott, Copyright (c) Microsoft Corporation, Copyright (c) Six Labors, Copyright (c) The Internet Society (2003), Copyright (c) The Internet Society 1997, Copyright (c) YEAR W3C(r) (MIT, ERCIM, Keio, Beihang) Disclaimers, Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018 The Regents of the University of California, Copyright 2012 the V8 project authors, Copyright 2018 Daniel Lemire, Copyright 2019 LLVM Project, Portions (c) International Organization for Standardization 1986", + "externalRefs": [ + { + "referenceCategory": "PACKAGE-MANAGER", + "referenceType": "purl", + "referenceLocator": "pkg:nuget/Microsoft.Extensions.Logging.Abstractions@8.0.3" + } + ] + }, + { + "name": "Newtonsoft.Json", + "SPDXID": "SPDXRef-nuget-Newtonsoft.Json-13.0.3-88677a", + "versionInfo": "13.0.3", + "downloadLocation": "NOASSERTION", + "filesAnalyzed": false, + "licenseConcluded": "MIT", + "copyrightText": "Copyright (c) 2007 James Newton-King, Copyright (c) James Newton-King 2008, Copyright James Newton-King 2008, Copyright James Newton-King 2008 Json.NET", + "externalRefs": [ + { + "referenceCategory": "PACKAGE-MANAGER", + "referenceType": "purl", + "referenceLocator": "pkg:nuget/Newtonsoft.Json@13.0.3" + } + ] + }, + { + "name": "Microsoft.AspNetCore.Components.Analyzers", + "SPDXID": "SPDXRef-nuget-Microsoft.AspNetCore.Components.Analyzers-8.0.15-99d18e", + "versionInfo": "8.0.15", + "downloadLocation": "NOASSERTION", + "filesAnalyzed": false, + "licenseConcluded": "MIT", + "copyrightText": "(c) Microsoft Corporation, Copyright (c) .NET Foundation Contributors, Copyright (c) 1989, 1993 The Regents of the University of California, Copyright (c) 1990, 1993 The Regents of the University of California, Copyright (c) 1996-1998 John D. Polstra, Copyright (c) 1998 John D. Polstra, Copyright (c) 2000-2013 Julian Seward, Copyright (c) 2007 John Birrell (jb@freebsd.org), Copyright (c) 2011-2021 The Bootstrap Authors, Copyright (c) 2011-2021 Twitter, Inc., Copyright (c) 2013 - 2018 AngleSharp, Copyright (c) 2019-2023 The Bootstrap Authors", + "externalRefs": [ + { + "referenceCategory": "PACKAGE-MANAGER", + "referenceType": "purl", + "referenceLocator": "pkg:nuget/Microsoft.AspNetCore.Components.Analyzers@8.0.15" + } + ] + }, + { + "name": "Microsoft.AspNetCore.Metadata", + "SPDXID": "SPDXRef-nuget-Microsoft.AspNetCore.Metadata-8.0.15-38c0cd", + "versionInfo": "8.0.15", + "downloadLocation": "NOASSERTION", + "filesAnalyzed": false, + "licenseConcluded": "MIT", + "copyrightText": "(c) Microsoft Corporation, Copyright (c) .NET Foundation and Contributors, Copyright (c) .NET Foundation Contributors, Copyright (c) 1989, 1993 The Regents of the University of California, Copyright (c) 1990, 1993 The Regents of the University of California, Copyright (c) 1996-1998 John D. Polstra, Copyright (c) 1998 John D. Polstra, Copyright (c) 2000-2013 Julian Seward, Copyright (c) 2007 James Newton-King, Copyright (c) 2007 John Birrell (jb@freebsd.org), Copyright (c) 2010-2019 Google LLC. http://angular.io/license, Copyright (c) 2011 Alex MacCaw (info@eribium.org), Copyright (c) 2011 Nicolas Gallagher (nicolas@nicolasgallagher.com), Copyright (c) 2011-2021 The Bootstrap Authors, Copyright (c) 2011-2021 Twitter, Inc., Copyright (c) 2013 - 2018 AngleSharp, Copyright (c) 2013-2017, Milosz Krajewski, Copyright (c) 2014-2018 Michael Daines, Copyright (c) 2015, Google Inc., Copyright (c) 2016 Richard Morris, Copyright (c) 2017 Yoshifumi Kawai, Copyright (c) 2019 David Fowler, Copyright (c) 2019-2020 West Wind Technologies, Copyright (c) 2019-2023 The Bootstrap Authors, Copyright (c) Andrew Arnott, Copyright (c) HTML5 Boilerplate, Copyright (c) Microsoft Corporation, Copyright (c) Nicolas Gallagher and Jonathan Neal, Copyright (c) Sindre Sorhus \u003csindresorhus@gmail.com\u003e (https://sindresorhus.com), Copyright 2019 The gRPC Authors, Copyright Jorn Zaefferer, Copyright OpenJS Foundation and other contributors, https://openjsf.org", + "externalRefs": [ + { + "referenceCategory": "PACKAGE-MANAGER", + "referenceType": "purl", + "referenceLocator": "pkg:nuget/Microsoft.AspNetCore.Metadata@8.0.15" + } + ] + }, + { + "name": "Microsoft.AspNetCore.Authorization", + "SPDXID": "SPDXRef-nuget-Microsoft.AspNetCore.Authorization-8.0.15-4be166", + "versionInfo": "8.0.15", + "downloadLocation": "NOASSERTION", + "filesAnalyzed": false, + "licenseConcluded": "MIT", + "copyrightText": "(c) Microsoft Corporation, Copyright (c) .NET Foundation and Contributors, Copyright (c) .NET Foundation Contributors, Copyright (c) 1989, 1993 The Regents of the University of California, Copyright (c) 1990, 1993 The Regents of the University of California, Copyright (c) 1996-1998 John D. Polstra, Copyright (c) 1998 John D. Polstra, Copyright (c) 2000-2013 Julian Seward, Copyright (c) 2007 James Newton-King, Copyright (c) 2007 John Birrell (jb@freebsd.org), Copyright (c) 2010-2019 Google LLC. http://angular.io/license, Copyright (c) 2011 Alex MacCaw (info@eribium.org), Copyright (c) 2011 Nicolas Gallagher (nicolas@nicolasgallagher.com), Copyright (c) 2011-2021 The Bootstrap Authors, Copyright (c) 2011-2021 Twitter, Inc., Copyright (c) 2013 - 2018 AngleSharp, Copyright (c) 2013-2017, Milosz Krajewski, Copyright (c) 2014-2018 Michael Daines, Copyright (c) 2015, Google Inc., Copyright (c) 2016 Richard Morris, Copyright (c) 2017 Yoshifumi Kawai, Copyright (c) 2019 David Fowler, Copyright (c) 2019-2020 West Wind Technologies, Copyright (c) 2019-2023 The Bootstrap Authors, Copyright (c) Andrew Arnott, Copyright (c) HTML5 Boilerplate, Copyright (c) Microsoft Corporation, Copyright (c) Nicolas Gallagher and Jonathan Neal, Copyright (c) Sindre Sorhus \u003csindresorhus@gmail.com\u003e (https://sindresorhus.com), Copyright 2019 The gRPC Authors, Copyright Jorn Zaefferer, Copyright OpenJS Foundation and other contributors, https://openjsf.org", + "externalRefs": [ + { + "referenceCategory": "PACKAGE-MANAGER", + "referenceType": "purl", + "referenceLocator": "pkg:nuget/Microsoft.AspNetCore.Authorization@8.0.15" + } + ] + }, + { + "name": "Swashbuckle.AspNetCore", + "SPDXID": "SPDXRef-nuget-Swashbuckle.AspNetCore-8.1.1-96b60e", + "versionInfo": "8.1.1", + "downloadLocation": "NOASSERTION", + "filesAnalyzed": false, + "licenseConcluded": "MIT", + "externalRefs": [ + { + "referenceCategory": "PACKAGE-MANAGER", + "referenceType": "purl", + "referenceLocator": "pkg:nuget/Swashbuckle.AspNetCore@8.1.1" + } + ] + }, + { + "name": "Microsoft.IdentityModel.Logging", + "SPDXID": "SPDXRef-nuget-Microsoft.IdentityModel.Logging-8.14.0-c2340a", + "versionInfo": "8.14.0", + "downloadLocation": "NOASSERTION", + "filesAnalyzed": false, + "licenseConcluded": "MIT", + "copyrightText": "(c) Microsoft Corporation, Copyright (c) Microsoft Corporation", + "externalRefs": [ + { + "referenceCategory": "PACKAGE-MANAGER", + "referenceType": "purl", + "referenceLocator": "pkg:nuget/Microsoft.IdentityModel.Logging@8.14.0" + } + ] + }, + { + "name": "Microsoft.Extensions.DependencyInjection.Abstractions", + "SPDXID": "SPDXRef-nuget-Microsoft.Extensions.DependencyInjection.Abstractions-8.0.2-15e0f0", + "versionInfo": "8.0.2", + "downloadLocation": "NOASSERTION", + "filesAnalyzed": false, + "licenseConcluded": "MIT", + "copyrightText": "(c) 1997-2005 Sean Eron Anderson, (c) Microsoft Corporation, Copyright (c) .NET Foundation, Copyright (c) .NET Foundation and Contributors, Copyright (c) .NET Foundation Contributors, Copyright (c) 1980, 1986, 1993 The Regents of the University of California, Copyright (c) 1989 by Hewlett-Packard Company, Palo Alto, Ca. \u0026 Digital Equipment Corporation, Maynard, Mass, Copyright (c) 1990- 1993, 1996 Open Software Foundation, Inc., Copyright (c) 1991-2022 Unicode, Inc., Copyright (c) 1995-2022 Jean-loup Gailly and Mark Adler, Copyright (c) 1998 Microsoft. To, Copyright (c) 1999 Lucent Technologies, Copyright (c) 2004-2006 Intel Corporation, Copyright (c) 2005-2007, Nick Galbreath, Copyright (c) 2005-2020 Rich Felker, Copyright (c) 2006 Jb Evain (jbevain@gmail.com), Copyright (c) 2007 James Newton-King, Copyright (c) 2008-2016, Wojciech Mula, Copyright (c) 2008-2020 Advanced Micro Devices, Inc., Copyright (c) 2009, 2010, 2013-2016 by the Brotli Authors, Copyright (c) 2011 Novell, Inc (http://www.novell.com), Copyright (c) 2011-2015 Intel Corporation, Copyright (c) 2011-2020 Microsoft Corp, Copyright (c) 2011, Google Inc., Copyright (c) 2012 - present, Victor Zverovich, Copyright (c) 2012-2021 Yann Collet, Copyright (c) 2013-2017, Alfred Klomp, Copyright (c) 2013-2017, Milosz Krajewski, Copyright (c) 2014 Ryan Juckett http://www.ryanjuckett.com, Copyright (c) 2015 The Chromium Authors, Copyright (c) 2015 THL A29 Limited, a Tencent company, and Milo Yip, Copyright (c) 2015 Xamarin, Inc (http://www.xamarin.com), Copyright (c) 2015-2017, Wojciech Mula, Copyright (c) 2016-2017, Matthieu Darbois, Copyright (c) 2017 Yoshifumi Kawai, Copyright (c) 2018 Alexander Chermyanin, Copyright (c) 2019 Microsoft Corporation, Daan Leijen, Copyright (c) 2020 Dan Shechter, Copyright (c) 2020 Mara Bos \u003cm-ou.se@m-ou.se\u003e, Copyright (c) 2021 csFastFloat authors, Copyright (c) 2022, Geoff Langdale, Copyright (c) 2022, Wojciech Mula, Copyright (c) Andrew Arnott, Copyright (c) Microsoft Corporation, Copyright (c) Six Labors, Copyright (c) The Internet Society (2003), Copyright (c) The Internet Society 1997, Copyright (c) YEAR W3C(r) (MIT, ERCIM, Keio, Beihang). Disclaimers, Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018 The Regents of the University of California, Copyright 2012 the V8 project authors, Copyright 2018 Daniel Lemire, Copyright 2019 LLVM Project, Portions (c) International Organization", + "externalRefs": [ + { + "referenceCategory": "PACKAGE-MANAGER", + "referenceType": "purl", + "referenceLocator": "pkg:nuget/Microsoft.Extensions.DependencyInjection.Abstractions@8.0.2" + } + ] + }, + { + "name": "PuppeteerSharp", + "SPDXID": "SPDXRef-nuget-PuppeteerSharp-20.2.2-336c02", + "versionInfo": "20.2.2", + "downloadLocation": "NOASSERTION", + "filesAnalyzed": false, + "licenseConcluded": "MIT", + "externalRefs": [ + { + "referenceCategory": "PACKAGE-MANAGER", + "referenceType": "purl", + "referenceLocator": "pkg:nuget/PuppeteerSharp@20.2.2" + } + ] + }, + { + "name": "Microsoft.Extensions.ApiDescription.Server", + "SPDXID": "SPDXRef-nuget-Microsoft.Extensions.ApiDescription.Server-6.0.5-1864e8", + "versionInfo": "6.0.5", + "downloadLocation": "NOASSERTION", + "filesAnalyzed": false, + "licenseConcluded": "MIT", + "copyrightText": "(c) 2008 VeriSign, Inc., (c) Microsoft Corporation, Copyright James Newton-King 2008, Copyright James Newton-King 2008 Json.NET", + "externalRefs": [ + { + "referenceCategory": "PACKAGE-MANAGER", + "referenceType": "purl", + "referenceLocator": "pkg:nuget/Microsoft.Extensions.ApiDescription.Server@6.0.5" + } + ] + }, + { + "name": "Swashbuckle.AspNetCore.Swagger", + "SPDXID": "SPDXRef-nuget-Swashbuckle.AspNetCore.Swagger-8.1.1-46d10b", + "versionInfo": "8.1.1", + "downloadLocation": "NOASSERTION", + "filesAnalyzed": false, + "licenseConcluded": "MIT", + "copyrightText": "(c) 2016-2025 Richard Morris, Copyright (c) 2016-2025 Richard Morris", + "externalRefs": [ + { + "referenceCategory": "PACKAGE-MANAGER", + "referenceType": "purl", + "referenceLocator": "pkg:nuget/Swashbuckle.AspNetCore.Swagger@8.1.1" + } + ] + }, + { + "name": "Microsoft.IdentityModel.Protocols", + "SPDXID": "SPDXRef-nuget-Microsoft.IdentityModel.Protocols-7.1.2-dacada", + "versionInfo": "7.1.2", + "downloadLocation": "NOASSERTION", + "filesAnalyzed": false, + "licenseConcluded": "MIT", + "copyrightText": "(c) Microsoft Corporation", + "externalRefs": [ + { + "referenceCategory": "PACKAGE-MANAGER", + "referenceType": "purl", + "referenceLocator": "pkg:nuget/Microsoft.IdentityModel.Protocols@7.1.2" + } + ] + }, + { + "name": "System.IdentityModel.Tokens.Jwt", + "SPDXID": "SPDXRef-nuget-System.IdentityModel.Tokens.Jwt-8.14.0-e897cc", + "versionInfo": "8.14.0", + "downloadLocation": "NOASSERTION", + "filesAnalyzed": false, + "licenseConcluded": "MIT", + "copyrightText": "(c) Microsoft Corporation, Copyright (c) Microsoft Corporation", + "externalRefs": [ + { + "referenceCategory": "PACKAGE-MANAGER", + "referenceType": "purl", + "referenceLocator": "pkg:nuget/System.IdentityModel.Tokens.Jwt@8.14.0" + } + ] + }, + { + "name": "Microsoft.IdentityModel.Abstractions", + "SPDXID": "SPDXRef-nuget-Microsoft.IdentityModel.Abstractions-8.14.0-65944f", + "versionInfo": "8.14.0", + "downloadLocation": "NOASSERTION", + "filesAnalyzed": false, + "licenseConcluded": "MIT", + "copyrightText": "(c) Microsoft Corporation, Copyright (c) Microsoft Corporation", + "externalRefs": [ + { + "referenceCategory": "PACKAGE-MANAGER", + "referenceType": "purl", + "referenceLocator": "pkg:nuget/Microsoft.IdentityModel.Abstractions@8.14.0" + } + ] + }, + { + "name": "Microsoft.Extensions.Primitives", + "SPDXID": "SPDXRef-nuget-Microsoft.Extensions.Primitives-8.0.0-8da07a", + "versionInfo": "8.0.0", + "downloadLocation": "NOASSERTION", + "filesAnalyzed": false, + "licenseConcluded": "MIT", + "copyrightText": "(c) 1997-2005 Sean Eron Anderson, (c) Microsoft Corporation, Copyright (c) .NET Foundation, Copyright (c) .NET Foundation and Contributors, Copyright (c) .NET Foundation Contributors, Copyright (c) 1980, 1986, 1993 The Regents of the University of California, Copyright (c) 1989 by Hewlett-Packard Company, Palo Alto, Ca. \u0026 Digital Equipment Corporation, Maynard, Mass, Copyright (c) 1990- 1993, 1996 Open Software Foundation, Inc., Copyright (c) 1991-2022 Unicode, Inc., Copyright (c) 1995-2022 Jean-loup Gailly and Mark Adler, Copyright (c) 1998 Microsoft. To, Copyright (c) 1999 Lucent Technologies, Copyright (c) 2004-2006 Intel Corporation, Copyright (c) 2005-2007, Nick Galbreath, Copyright (c) 2005-2020 Rich Felker, Copyright (c) 2006 Jb Evain (jbevain@gmail.com), Copyright (c) 2007 James Newton-King, Copyright (c) 2008-2016, Wojciech Mula, Copyright (c) 2008-2020 Advanced Micro Devices, Inc., Copyright (c) 2009, 2010, 2013-2016 by the Brotli Authors, Copyright (c) 2011 Novell, Inc (http://www.novell.com), Copyright (c) 2011-2015 Intel Corporation, Copyright (c) 2011-2020 Microsoft Corp, Copyright (c) 2011, Google Inc., Copyright (c) 2012 - present, Victor Zverovich, Copyright (c) 2012-2021 Yann Collet, Copyright (c) 2013-2017, Alfred Klomp, Copyright (c) 2013-2017, Milosz Krajewski, Copyright (c) 2014 Ryan Juckett http://www.ryanjuckett.com, Copyright (c) 2015 The Chromium Authors, Copyright (c) 2015 THL A29 Limited, a Tencent company, and Milo Yip, Copyright (c) 2015 Xamarin, Inc (http://www.xamarin.com), Copyright (c) 2015-2017, Wojciech Mula, Copyright (c) 2016-2017, Matthieu Darbois, Copyright (c) 2017 Yoshifumi Kawai, Copyright (c) 2018 Alexander Chermyanin, Copyright (c) 2019 Microsoft Corporation, Daan Leijen, Copyright (c) 2020 Dan Shechter, Copyright (c) 2020 Mara Bos \u003cm-ou.se@m-ou.se\u003e, Copyright (c) 2021 csFastFloat authors, Copyright (c) 2022, Geoff Langdale, Copyright (c) 2022, Wojciech Mula, Copyright (c) Andrew Arnott, Copyright (c) Microsoft Corporation, Copyright (c) Six Labors, Copyright (c) The Internet Society (2003), Copyright (c) The Internet Society 1997, Copyright (c) YEAR W3C(r) (MIT, ERCIM, Keio, Beihang). Disclaimers, Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018 The Regents of the University of California, Copyright 2012 the V8 project authors, Copyright 2018 Daniel Lemire, Copyright 2019 LLVM Project, Portions (c) International Organization", + "externalRefs": [ + { + "referenceCategory": "PACKAGE-MANAGER", + "referenceType": "purl", + "referenceLocator": "pkg:nuget/Microsoft.Extensions.Primitives@8.0.0" + } + ] + }, + { + "name": "Novell.Directory.Ldap.NETStandard", + "SPDXID": "SPDXRef-nuget-Novell.Directory.Ldap.NETStandard-4.0.0-1ecb72", + "versionInfo": "4.0.0", + "downloadLocation": "NOASSERTION", + "filesAnalyzed": false, + "licenseConcluded": "MIT", + "copyrightText": "(c) 2003 Novell, Inc, 2016, Copyright (c) 2000 - 2017 The Legion of the Bouncy Castle Inc. (http://www.bouncycastle.org)", + "externalRefs": [ + { + "referenceCategory": "PACKAGE-MANAGER", + "referenceType": "purl", + "referenceLocator": "pkg:nuget/Novell.Directory.Ldap.NETStandard@4.0.0" + } + ] + }, + { + "name": "Microsoft.IdentityModel.Tokens", + "SPDXID": "SPDXRef-nuget-Microsoft.IdentityModel.Tokens-8.14.0-7bf14e", + "versionInfo": "8.14.0", + "downloadLocation": "NOASSERTION", + "filesAnalyzed": false, + "licenseConcluded": "MIT", + "copyrightText": "(c) Microsoft Corporation, Copyright (c) Microsoft Corporation", + "externalRefs": [ + { + "referenceCategory": "PACKAGE-MANAGER", + "referenceType": "purl", + "referenceLocator": "pkg:nuget/Microsoft.IdentityModel.Tokens@8.14.0" + } + ] + }, + { + "name": "Swashbuckle.AspNetCore.SwaggerGen", + "SPDXID": "SPDXRef-nuget-Swashbuckle.AspNetCore.SwaggerGen-8.1.1-1e762c", + "versionInfo": "8.1.1", + "downloadLocation": "NOASSERTION", + "filesAnalyzed": false, + "licenseConcluded": "MIT", + "copyrightText": "(c) 2016-2025 Richard Morris, Copyright (c) 2016-2025 Richard Morris", + "externalRefs": [ + { + "referenceCategory": "PACKAGE-MANAGER", + "referenceType": "purl", + "referenceLocator": "pkg:nuget/Swashbuckle.AspNetCore.SwaggerGen@8.1.1" + } + ] + }, + { + "name": "Microsoft.Extensions.DependencyInjection", + "SPDXID": "SPDXRef-nuget-Microsoft.Extensions.DependencyInjection-8.0.0-a9400f", + "versionInfo": "8.0.0", + "downloadLocation": "NOASSERTION", + "filesAnalyzed": false, + "licenseConcluded": "MIT", + "copyrightText": "(c) 1997-2005 Sean Eron Anderson, (c) Microsoft Corporation, Copyright (c) .NET Foundation, Copyright (c) .NET Foundation and Contributors, Copyright (c) .NET Foundation Contributors, Copyright (c) 1980, 1986, 1993 The Regents of the University of California, Copyright (c) 1989 by Hewlett-Packard Company, Palo Alto, Ca. \u0026 Digital Equipment Corporation, Maynard, Mass, Copyright (c) 1990- 1993, 1996 Open Software Foundation, Inc., Copyright (c) 1991-2022 Unicode, Inc., Copyright (c) 1995-2022 Jean-loup Gailly and Mark Adler, Copyright (c) 1998 Microsoft, Copyright (c) 1998 Microsoft. To, Copyright (c) 1999 Lucent Technologies, Copyright (c) 2004-2006 Intel Corporation, Copyright (c) 2005-2007, Nick Galbreath, Copyright (c) 2005-2020 Rich Felker, Copyright (c) 2006 Jb Evain (jbevain@gmail.com), Copyright (c) 2007 James Newton-King, Copyright (c) 2008-2016, Wojciech Mula, Copyright (c) 2008-2020 Advanced Micro Devices, Inc., Copyright (c) 2009, 2010, 2013-2016 by the Brotli Authors, Copyright (c) 2011 Novell, Inc (http://www.novell.com), Copyright (c) 2011-2015 Intel Corporation, Copyright (c) 2011-2020 Microsoft Corp, Copyright (c) 2011, Google Inc., Copyright (c) 2012 - present, Victor Zverovich, Copyright (c) 2012-2021 Yann Collet, Copyright (c) 2013-2017, Alfred Klomp, Copyright (c) 2013-2017, Milosz Krajewski, Copyright (c) 2014 Ryan Juckett http://www.ryanjuckett.com, Copyright (c) 2015 The Chromium Authors, Copyright (c) 2015 THL A29 Limited, a Tencent company, and Milo Yip, Copyright (c) 2015 Xamarin, Inc (http://www.xamarin.com), Copyright (c) 2015-2017, Wojciech Mula, Copyright (c) 2016-2017, Matthieu Darbois, Copyright (c) 2017 Yoshifumi Kawai, Copyright (c) 2018 Alexander Chermyanin, Copyright (c) 2019 Microsoft Corporation, Daan Leijen, Copyright (c) 2020 Dan Shechter, Copyright (c) 2020 Mara Bos \u003cm-ou.se@m-ou.se\u003e, Copyright (c) 2021, Copyright (c) 2021 csFastFloat authors, Copyright (c) 2022, Geoff Langdale, Copyright (c) 2022, Wojciech Mula, Copyright (c) Andrew Arnott, Copyright (c) Microsoft Corporation, Copyright (c) Six Labors, Copyright (c) The Internet Society (2003), Copyright (c) The Internet Society 1997, Copyright (c) YEAR W3C(r) (MIT, ERCIM, Keio, Beihang) Disclaimers, Copyright (c) YEAR W3C(r) (MIT, ERCIM, Keio, Beihang). Disclaimers, Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018 The Regents of the University of California, Copyright 2012 the V8 project authors, Copyright 2018 Daniel Lemire, Copyright 2019 LLVM Project, Portions (c) International Organization, Portions (c) International Organization for Standardization 1986", + "externalRefs": [ + { + "referenceCategory": "PACKAGE-MANAGER", + "referenceType": "purl", + "referenceLocator": "pkg:nuget/Microsoft.Extensions.DependencyInjection@8.0.0" + } + ] + }, + { + "name": "Microsoft.IdentityModel.Protocols.OpenIdConnect", + "SPDXID": "SPDXRef-nuget-Microsoft.IdentityModel.Protocols.OpenIdConnect-7.1.2-99e23d", + "versionInfo": "7.1.2", + "downloadLocation": "NOASSERTION", + "filesAnalyzed": false, + "licenseConcluded": "MIT", + "copyrightText": "(c) Microsoft Corporation", + "externalRefs": [ + { + "referenceCategory": "PACKAGE-MANAGER", + "referenceType": "purl", + "referenceLocator": "pkg:nuget/Microsoft.IdentityModel.Protocols.OpenIdConnect@7.1.2" + } + ] + }, + { + "name": "Microsoft.Extensions.Logging", + "SPDXID": "SPDXRef-nuget-Microsoft.Extensions.Logging-8.0.0-e38db4", + "versionInfo": "8.0.0", + "downloadLocation": "NOASSERTION", + "filesAnalyzed": false, + "licenseConcluded": "MIT", + "copyrightText": "(c) 1997-2005 Sean Eron Anderson, (c) Microsoft Corporation, Copyright (c) .NET Foundation, Copyright (c) .NET Foundation and Contributors, Copyright (c) .NET Foundation Contributors, Copyright (c) 1980, 1986, 1993 The Regents of the University of California, Copyright (c) 1989 by Hewlett-Packard Company, Palo Alto, Ca. \u0026 Digital Equipment Corporation, Maynard, Mass, Copyright (c) 1990- 1993, 1996 Open Software Foundation, Inc., Copyright (c) 1991-2022 Unicode, Inc., Copyright (c) 1995-2022 Jean-loup Gailly and Mark Adler, Copyright (c) 1998 Microsoft, Copyright (c) 1998 Microsoft. To, Copyright (c) 1999 Lucent Technologies, Copyright (c) 2004-2006 Intel Corporation, Copyright (c) 2005-2007, Nick Galbreath, Copyright (c) 2005-2020 Rich Felker, Copyright (c) 2006 Jb Evain (jbevain@gmail.com), Copyright (c) 2007 James Newton-King, Copyright (c) 2008-2016, Wojciech Mula, Copyright (c) 2008-2020 Advanced Micro Devices, Inc., Copyright (c) 2009, 2010, 2013-2016 by the Brotli Authors, Copyright (c) 2011 Novell, Inc (http://www.novell.com), Copyright (c) 2011-2015 Intel Corporation, Copyright (c) 2011-2020 Microsoft Corp, Copyright (c) 2011, Google Inc., Copyright (c) 2012 - present, Victor Zverovich, Copyright (c) 2012-2021 Yann Collet, Copyright (c) 2013-2017, Alfred Klomp, Copyright (c) 2013-2017, Milosz Krajewski, Copyright (c) 2014 Ryan Juckett http://www.ryanjuckett.com, Copyright (c) 2015 The Chromium Authors, Copyright (c) 2015 THL A29 Limited, a Tencent company, and Milo Yip, Copyright (c) 2015 Xamarin, Inc (http://www.xamarin.com), Copyright (c) 2015-2017, Wojciech Mula, Copyright (c) 2016-2017, Matthieu Darbois, Copyright (c) 2017 Yoshifumi Kawai, Copyright (c) 2018 Alexander Chermyanin, Copyright (c) 2019 Microsoft Corporation, Daan Leijen, Copyright (c) 2020 Dan Shechter, Copyright (c) 2020 Mara Bos \u003cm-ou.se@m-ou.se\u003e, Copyright (c) 2021, Copyright (c) 2021 csFastFloat authors, Copyright (c) 2022, Geoff Langdale, Copyright (c) 2022, Wojciech Mula, Copyright (c) Andrew Arnott, Copyright (c) Microsoft Corporation, Copyright (c) Six Labors, Copyright (c) The Internet Society (2003), Copyright (c) The Internet Society 1997, Copyright (c) YEAR W3C(r) (MIT, ERCIM, Keio, Beihang) Disclaimers, Copyright (c) YEAR W3C(r) (MIT, ERCIM, Keio, Beihang). Disclaimers, Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018 The Regents of the University of California, Copyright 2012 the V8 project authors, Copyright 2018 Daniel Lemire, Copyright 2019 LLVM Project, Portions (c) International Organization, Portions (c) International Organization for Standardization 1986", + "externalRefs": [ + { + "referenceCategory": "PACKAGE-MANAGER", + "referenceType": "purl", + "referenceLocator": "pkg:nuget/Microsoft.Extensions.Logging@8.0.0" + } + ] + }, + { + "name": "Microsoft.Extensions.Logging.Abstractions", + "SPDXID": "SPDXRef-nuget-Microsoft.Extensions.Logging.Abstractions-8.0.3-ae48ad", + "versionInfo": "8.0.3", + "downloadLocation": "NOASSERTION", + "filesAnalyzed": false, + "licenseConcluded": "MIT", + "copyrightText": "(c) 1997-2005 Sean Eron Anderson, (c) Microsoft Corporation, Copyright (c) .NET Foundation, Copyright (c) .NET Foundation and Contributors, Copyright (c) .NET Foundation Contributors, Copyright (c) 1980, 1986, 1993 The Regents of the University of California, Copyright (c) 1989 by Hewlett-Packard Company, Palo Alto, Ca. \u0026 Digital Equipment Corporation, Maynard, Mass, Copyright (c) 1990- 1993, 1996 Open Software Foundation, Inc., Copyright (c) 1991-2022 Unicode, Inc., Copyright (c) 1995-2022 Jean-loup Gailly and Mark Adler, Copyright (c) 1998 Microsoft, Copyright (c) 1999 Lucent Technologies, Copyright (c) 2004-2006 Intel Corporation, Copyright (c) 2005-2007, Nick Galbreath, Copyright (c) 2005-2020 Rich Felker, Copyright (c) 2006 Jb Evain (jbevain@gmail.com), Copyright (c) 2007 James Newton-King, Copyright (c) 2008-2016, Wojciech Mula, Copyright (c) 2008-2020 Advanced Micro Devices, Inc., Copyright (c) 2009, 2010, 2013-2016 by the Brotli Authors, Copyright (c) 2011 Novell, Inc (http://www.novell.com), Copyright (c) 2011-2015 Intel Corporation, Copyright (c) 2011-2020 Microsoft Corp, Copyright (c) 2011, Google Inc., Copyright (c) 2012 - present, Victor Zverovich, Copyright (c) 2012-2021 Yann Collet, Copyright (c) 2013-2017, Alfred Klomp, Copyright (c) 2013-2017, Milosz Krajewski, Copyright (c) 2014 Ryan Juckett http://www.ryanjuckett.com, Copyright (c) 2015 The Chromium Authors, Copyright (c) 2015 THL A29 Limited, a Tencent company, and Milo Yip, Copyright (c) 2015 Xamarin, Inc (http://www.xamarin.com), Copyright (c) 2015-2017, Wojciech Mula, Copyright (c) 2016-2017, Matthieu Darbois, Copyright (c) 2017 Yoshifumi Kawai, Copyright (c) 2018 Alexander Chermyanin, Copyright (c) 2019 Microsoft Corporation, Daan Leijen, Copyright (c) 2020 Dan Shechter, Copyright (c) 2020 Mara Bos \u003cm-ou.se@m-ou.se\u003e, Copyright (c) 2021, Copyright (c) 2022, Geoff Langdale, Copyright (c) 2022, Wojciech Mula, Copyright (c) Andrew Arnott, Copyright (c) Microsoft Corporation, Copyright (c) Six Labors, Copyright (c) The Internet Society (2003), Copyright (c) The Internet Society 1997, Copyright (c) YEAR W3C(r) (MIT, ERCIM, Keio, Beihang) Disclaimers, Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018 The Regents of the University of California, Copyright 2012 the V8 project authors, Copyright 2018 Daniel Lemire, Copyright 2019 LLVM Project, Portions (c) International Organization for Standardization 1986", + "externalRefs": [ + { + "referenceCategory": "PACKAGE-MANAGER", + "referenceType": "purl", + "referenceLocator": "pkg:nuget/Microsoft.Extensions.Logging.Abstractions@8.0.3" + } + ] + }, + { + "name": "Microsoft.AspNetCore.Authentication.JwtBearer", + "SPDXID": "SPDXRef-nuget-Microsoft.AspNetCore.Authentication.JwtBearer-8.0.15-6252d7", + "versionInfo": "8.0.15", + "downloadLocation": "NOASSERTION", + "filesAnalyzed": false, + "licenseConcluded": "MIT", + "copyrightText": "(c) Microsoft Corporation, Copyright (c) .NET Foundation and Contributors, Copyright (c) .NET Foundation Contributors, Copyright (c) 1989, 1993 The Regents of the University of California, Copyright (c) 1990, 1993 The Regents of the University of California, Copyright (c) 1996-1998 John D. Polstra, Copyright (c) 1998 John D. Polstra, Copyright (c) 2000-2013 Julian Seward, Copyright (c) 2007 James Newton-King, Copyright (c) 2007 John Birrell (jb@freebsd.org), Copyright (c) 2010-2019 Google LLC. http://angular.io/license, Copyright (c) 2011 Alex MacCaw (info@eribium.org), Copyright (c) 2011 Nicolas Gallagher (nicolas@nicolasgallagher.com), Copyright (c) 2011-2021 The Bootstrap Authors, Copyright (c) 2011-2021 Twitter, Inc., Copyright (c) 2013 - 2018 AngleSharp, Copyright (c) 2013-2017, Milosz Krajewski, Copyright (c) 2014-2018 Michael Daines, Copyright (c) 2015, Google Inc., Copyright (c) 2016 Richard Morris, Copyright (c) 2017 Yoshifumi Kawai, Copyright (c) 2019 David Fowler, Copyright (c) 2019-2020 West Wind Technologies, Copyright (c) 2019-2023 The Bootstrap Authors, Copyright (c) Andrew Arnott, Copyright (c) HTML5 Boilerplate, Copyright (c) Microsoft Corporation, Copyright (c) Nicolas Gallagher and Jonathan Neal, Copyright (c) Sindre Sorhus \u003csindresorhus@gmail.com\u003e (https://sindresorhus.com), Copyright 2019 The gRPC Authors, Copyright Jorn Zaefferer, Copyright OpenJS Foundation and other contributors, https://openjsf.org", + "externalRefs": [ + { + "referenceCategory": "PACKAGE-MANAGER", + "referenceType": "purl", + "referenceLocator": "pkg:nuget/Microsoft.AspNetCore.Authentication.JwtBearer@8.0.15" + } + ] + }, + { + "name": "Microsoft.IdentityModel.JsonWebTokens", + "SPDXID": "SPDXRef-nuget-Microsoft.IdentityModel.JsonWebTokens-8.14.0-1249a1", + "versionInfo": "8.14.0", + "downloadLocation": "NOASSERTION", + "filesAnalyzed": false, + "licenseConcluded": "MIT", + "copyrightText": "(c) Microsoft Corporation, Copyright (c) Microsoft Corporation", + "externalRefs": [ + { + "referenceCategory": "PACKAGE-MANAGER", + "referenceType": "purl", + "referenceLocator": "pkg:nuget/Microsoft.IdentityModel.JsonWebTokens@8.14.0" + } + ] + }, + { + "name": "Swashbuckle.AspNetCore.SwaggerUI", + "SPDXID": "SPDXRef-nuget-Swashbuckle.AspNetCore.SwaggerUI-8.1.1-e01486", + "versionInfo": "8.1.1", + "downloadLocation": "NOASSERTION", + "filesAnalyzed": false, + "licenseConcluded": "MIT", + "copyrightText": "(c) 2016-2025 Richard Morris Middleware, Copyright (c) 2016-2025 Richard Morris, Copyright 2020-2021 SmartBear Software Inc.", + "externalRefs": [ + { + "referenceCategory": "PACKAGE-MANAGER", + "referenceType": "purl", + "referenceLocator": "pkg:nuget/Swashbuckle.AspNetCore.SwaggerUI@8.1.1" + } + ] + }, + { + "name": "Microsoft.OpenApi", + "SPDXID": "SPDXRef-nuget-Microsoft.OpenApi-1.6.23-a09a48", + "versionInfo": "1.6.23", + "downloadLocation": "NOASSERTION", + "filesAnalyzed": false, + "licenseConcluded": "LicenseRef-scancode-generic-cla AND MIT", + "copyrightText": "(c) Microsoft Corporation", + "externalRefs": [ + { + "referenceCategory": "PACKAGE-MANAGER", + "referenceType": "purl", + "referenceLocator": "pkg:nuget/Microsoft.OpenApi@1.6.23" + } + ] + }, + { + "name": "Microsoft.Extensions.Options", + "SPDXID": "SPDXRef-nuget-Microsoft.Extensions.Options-8.0.2-ce1910", + "versionInfo": "8.0.2", + "downloadLocation": "NOASSERTION", + "filesAnalyzed": false, + "licenseConcluded": "MIT", + "copyrightText": "(c) 1997-2005 Sean Eron Anderson, (c) Microsoft Corporation, Copyright (c) .NET Foundation, Copyright (c) .NET Foundation and Contributors, Copyright (c) .NET Foundation Contributors, Copyright (c) 1980, 1986, 1993 The Regents of the University of California, Copyright (c) 1989 by Hewlett-Packard Company, Palo Alto, Ca. \u0026 Digital Equipment Corporation, Maynard, Mass, Copyright (c) 1990- 1993, 1996 Open Software Foundation, Inc., Copyright (c) 1991-2022 Unicode, Inc., Copyright (c) 1995-2022 Jean-loup Gailly and Mark Adler, Copyright (c) 1998 Microsoft. To, Copyright (c) 1999 Lucent Technologies, Copyright (c) 2004-2006 Intel Corporation, Copyright (c) 2005-2007, Nick Galbreath, Copyright (c) 2005-2020 Rich Felker, Copyright (c) 2006 Jb Evain (jbevain@gmail.com), Copyright (c) 2007 James Newton-King, Copyright (c) 2008-2016, Wojciech Mula, Copyright (c) 2008-2020 Advanced Micro Devices, Inc., Copyright (c) 2009, 2010, 2013-2016 by the Brotli Authors, Copyright (c) 2011 Novell, Inc (http://www.novell.com), Copyright (c) 2011-2015 Intel Corporation, Copyright (c) 2011-2020 Microsoft Corp, Copyright (c) 2011, Google Inc., Copyright (c) 2012 - present, Victor Zverovich, Copyright (c) 2012-2021 Yann Collet, Copyright (c) 2013-2017, Alfred Klomp, Copyright (c) 2013-2017, Milosz Krajewski, Copyright (c) 2014 Ryan Juckett http://www.ryanjuckett.com, Copyright (c) 2015 The Chromium Authors, Copyright (c) 2015 THL A29 Limited, a Tencent company, and Milo Yip, Copyright (c) 2015 Xamarin, Inc (http://www.xamarin.com), Copyright (c) 2015-2017, Wojciech Mula, Copyright (c) 2016-2017, Matthieu Darbois, Copyright (c) 2017 Yoshifumi Kawai, Copyright (c) 2018 Alexander Chermyanin, Copyright (c) 2019 Microsoft Corporation, Daan Leijen, Copyright (c) 2020 Dan Shechter, Copyright (c) 2020 Mara Bos \u003cm-ou.se@m-ou.se\u003e, Copyright (c) 2021 csFastFloat authors, Copyright (c) 2022, Geoff Langdale, Copyright (c) 2022, Wojciech Mula, Copyright (c) Andrew Arnott, Copyright (c) Microsoft Corporation, Copyright (c) Six Labors, Copyright (c) The Internet Society (2003), Copyright (c) The Internet Society 1997, Copyright (c) YEAR W3C(r) (MIT, ERCIM, Keio, Beihang). Disclaimers, Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018 The Regents of the University of California, Copyright 2012 the V8 project authors, Copyright 2018 Daniel Lemire, Copyright 2019 LLVM Project, Portions (c) International Organization", + "externalRefs": [ + { + "referenceCategory": "PACKAGE-MANAGER", + "referenceType": "purl", + "referenceLocator": "pkg:nuget/Microsoft.Extensions.Options@8.0.2" + } + ] + }, + { + "name": "Microsoft.Extensions.ObjectPool", + "SPDXID": "SPDXRef-nuget-Microsoft.Extensions.ObjectPool-8.0.11-da583c", + "versionInfo": "8.0.11", + "downloadLocation": "NOASSERTION", + "filesAnalyzed": false, + "licenseConcluded": "MIT", + "copyrightText": "(c) Microsoft Corporation, Copyright (c) .NET Foundation and Contributors, Copyright (c) .NET Foundation Contributors, Copyright (c) 1989, 1993 The Regents of the University of California, Copyright (c) 1990, 1993 The Regents of the University of California, Copyright (c) 1996-1998 John D. Polstra, Copyright (c) 1998 John D. Polstra, Copyright (c) 2000-2013 Julian Seward, Copyright (c) 2007 James Newton-King, Copyright (c) 2007 John Birrell (jb@freebsd.org), Copyright (c) 2010-2019 Google LLC. http://angular.io/license, Copyright (c) 2011 Alex MacCaw (info@eribium.org), Copyright (c) 2011 Nicolas Gallagher (nicolas@nicolasgallagher.com), Copyright (c) 2011-2021 The Bootstrap Authors, Copyright (c) 2011-2021 Twitter, Inc., Copyright (c) 2013 - 2018 AngleSharp, Copyright (c) 2013-2017, Milosz Krajewski, Copyright (c) 2014-2018 Michael Daines, Copyright (c) 2015, Google Inc., Copyright (c) 2016 Richard Morris, Copyright (c) 2017 Yoshifumi Kawai, Copyright (c) 2019 David Fowler, Copyright (c) 2019-2020 West Wind Technologies, Copyright (c) 2019-2023 The Bootstrap Authors, Copyright (c) Andrew Arnott, Copyright (c) HTML5 Boilerplate, Copyright (c) Microsoft Corporation, Copyright (c) Nicolas Gallagher and Jonathan Neal, Copyright (c) Sindre Sorhus \u003csindresorhus@gmail.com\u003e (https://sindresorhus.com), Copyright 2019 The gRPC Authors, Copyright Jorn Zaefferer, Copyright OpenJS Foundation and other contributors, https://openjsf.org", + "externalRefs": [ + { + "referenceCategory": "PACKAGE-MANAGER", + "referenceType": "purl", + "referenceLocator": "pkg:nuget/Microsoft.Extensions.ObjectPool@8.0.11" + } + ] + }, + { + "name": "Microsoft.Net.Http.Headers", + "SPDXID": "SPDXRef-nuget-Microsoft.Net.Http.Headers-2.3.0-6f214b", + "versionInfo": "2.3.0", + "downloadLocation": "NOASSERTION", + "filesAnalyzed": false, + "licenseConcluded": "Apache-2.0 AND LicenseRef-scancode-unknown", + "copyrightText": "(c) Microsoft Corporation, Copyright (c) .NET Foundation and Contributors", + "externalRefs": [ + { + "referenceCategory": "PACKAGE-MANAGER", + "referenceType": "purl", + "referenceLocator": "pkg:nuget/Microsoft.Net.Http.Headers@2.3.0" + } + ] + }, + { + "name": "Microsoft.AspNetCore.WebUtilities", + "SPDXID": "SPDXRef-nuget-Microsoft.AspNetCore.WebUtilities-2.3.0-b47477", + "versionInfo": "2.3.0", + "downloadLocation": "NOASSERTION", + "filesAnalyzed": false, + "licenseConcluded": "Apache-2.0 AND LicenseRef-scancode-unknown", + "copyrightText": "(c) Microsoft Corporation, Copyright (c) .NET Foundation and Contributors", + "externalRefs": [ + { + "referenceCategory": "PACKAGE-MANAGER", + "referenceType": "purl", + "referenceLocator": "pkg:nuget/Microsoft.AspNetCore.WebUtilities@2.3.0" + } + ] + }, + { + "name": "Microsoft.Extensions.Options", + "SPDXID": "SPDXRef-nuget-Microsoft.Extensions.Options-8.0.2-c1e33e", + "versionInfo": "8.0.2", + "downloadLocation": "NOASSERTION", + "filesAnalyzed": false, + "licenseConcluded": "MIT", + "copyrightText": "(c) 1997-2005 Sean Eron Anderson, (c) Microsoft Corporation, Copyright (c) .NET Foundation, Copyright (c) .NET Foundation and Contributors, Copyright (c) .NET Foundation Contributors, Copyright (c) 1980, 1986, 1993 The Regents of the University of California, Copyright (c) 1989 by Hewlett-Packard Company, Palo Alto, Ca. \u0026 Digital Equipment Corporation, Maynard, Mass, Copyright (c) 1990- 1993, 1996 Open Software Foundation, Inc., Copyright (c) 1991-2022 Unicode, Inc., Copyright (c) 1995-2022 Jean-loup Gailly and Mark Adler, Copyright (c) 1998 Microsoft. To, Copyright (c) 1999 Lucent Technologies, Copyright (c) 2004-2006 Intel Corporation, Copyright (c) 2005-2007, Nick Galbreath, Copyright (c) 2005-2020 Rich Felker, Copyright (c) 2006 Jb Evain (jbevain@gmail.com), Copyright (c) 2007 James Newton-King, Copyright (c) 2008-2016, Wojciech Mula, Copyright (c) 2008-2020 Advanced Micro Devices, Inc., Copyright (c) 2009, 2010, 2013-2016 by the Brotli Authors, Copyright (c) 2011 Novell, Inc (http://www.novell.com), Copyright (c) 2011-2015 Intel Corporation, Copyright (c) 2011-2020 Microsoft Corp, Copyright (c) 2011, Google Inc., Copyright (c) 2012 - present, Victor Zverovich, Copyright (c) 2012-2021 Yann Collet, Copyright (c) 2013-2017, Alfred Klomp, Copyright (c) 2013-2017, Milosz Krajewski, Copyright (c) 2014 Ryan Juckett http://www.ryanjuckett.com, Copyright (c) 2015 The Chromium Authors, Copyright (c) 2015 THL A29 Limited, a Tencent company, and Milo Yip, Copyright (c) 2015 Xamarin, Inc (http://www.xamarin.com), Copyright (c) 2015-2017, Wojciech Mula, Copyright (c) 2016-2017, Matthieu Darbois, Copyright (c) 2017 Yoshifumi Kawai, Copyright (c) 2018 Alexander Chermyanin, Copyright (c) 2019 Microsoft Corporation, Daan Leijen, Copyright (c) 2020 Dan Shechter, Copyright (c) 2020 Mara Bos \u003cm-ou.se@m-ou.se\u003e, Copyright (c) 2021 csFastFloat authors, Copyright (c) 2022, Geoff Langdale, Copyright (c) 2022, Wojciech Mula, Copyright (c) Andrew Arnott, Copyright (c) Microsoft Corporation, Copyright (c) Six Labors, Copyright (c) The Internet Society (2003), Copyright (c) The Internet Society 1997, Copyright (c) YEAR W3C(r) (MIT, ERCIM, Keio, Beihang). Disclaimers, Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018 The Regents of the University of California, Copyright 2012 the V8 project authors, Copyright 2018 Daniel Lemire, Copyright 2019 LLVM Project, Portions (c) International Organization", + "externalRefs": [ + { + "referenceCategory": "PACKAGE-MANAGER", + "referenceType": "purl", + "referenceLocator": "pkg:nuget/Microsoft.Extensions.Options@8.0.2" + } + ] + }, + { + "name": "Microsoft.Extensions.Primitives", + "SPDXID": "SPDXRef-nuget-Microsoft.Extensions.Primitives-8.0.0-6087da", + "versionInfo": "8.0.0", + "downloadLocation": "NOASSERTION", + "filesAnalyzed": false, + "licenseConcluded": "MIT", + "copyrightText": "(c) 1997-2005 Sean Eron Anderson, (c) Microsoft Corporation, Copyright (c) .NET Foundation, Copyright (c) .NET Foundation and Contributors, Copyright (c) .NET Foundation Contributors, Copyright (c) 1980, 1986, 1993 The Regents of the University of California, Copyright (c) 1989 by Hewlett-Packard Company, Palo Alto, Ca. \u0026 Digital Equipment Corporation, Maynard, Mass, Copyright (c) 1990- 1993, 1996 Open Software Foundation, Inc., Copyright (c) 1991-2022 Unicode, Inc., Copyright (c) 1995-2022 Jean-loup Gailly and Mark Adler, Copyright (c) 1998 Microsoft. To, Copyright (c) 1999 Lucent Technologies, Copyright (c) 2004-2006 Intel Corporation, Copyright (c) 2005-2007, Nick Galbreath, Copyright (c) 2005-2020 Rich Felker, Copyright (c) 2006 Jb Evain (jbevain@gmail.com), Copyright (c) 2007 James Newton-King, Copyright (c) 2008-2016, Wojciech Mula, Copyright (c) 2008-2020 Advanced Micro Devices, Inc., Copyright (c) 2009, 2010, 2013-2016 by the Brotli Authors, Copyright (c) 2011 Novell, Inc (http://www.novell.com), Copyright (c) 2011-2015 Intel Corporation, Copyright (c) 2011-2020 Microsoft Corp, Copyright (c) 2011, Google Inc., Copyright (c) 2012 - present, Victor Zverovich, Copyright (c) 2012-2021 Yann Collet, Copyright (c) 2013-2017, Alfred Klomp, Copyright (c) 2013-2017, Milosz Krajewski, Copyright (c) 2014 Ryan Juckett http://www.ryanjuckett.com, Copyright (c) 2015 The Chromium Authors, Copyright (c) 2015 THL A29 Limited, a Tencent company, and Milo Yip, Copyright (c) 2015 Xamarin, Inc (http://www.xamarin.com), Copyright (c) 2015-2017, Wojciech Mula, Copyright (c) 2016-2017, Matthieu Darbois, Copyright (c) 2017 Yoshifumi Kawai, Copyright (c) 2018 Alexander Chermyanin, Copyright (c) 2019 Microsoft Corporation, Daan Leijen, Copyright (c) 2020 Dan Shechter, Copyright (c) 2020 Mara Bos \u003cm-ou.se@m-ou.se\u003e, Copyright (c) 2021 csFastFloat authors, Copyright (c) 2022, Geoff Langdale, Copyright (c) 2022, Wojciech Mula, Copyright (c) Andrew Arnott, Copyright (c) Microsoft Corporation, Copyright (c) Six Labors, Copyright (c) The Internet Society (2003), Copyright (c) The Internet Society 1997, Copyright (c) YEAR W3C(r) (MIT, ERCIM, Keio, Beihang). Disclaimers, Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018 The Regents of the University of California, Copyright 2012 the V8 project authors, Copyright 2018 Daniel Lemire, Copyright 2019 LLVM Project, Portions (c) International Organization", + "externalRefs": [ + { + "referenceCategory": "PACKAGE-MANAGER", + "referenceType": "purl", + "referenceLocator": "pkg:nuget/Microsoft.Extensions.Primitives@8.0.0" + } + ] + }, + { + "name": "BouncyCastle.Cryptography", + "SPDXID": "SPDXRef-nuget-BouncyCastle.Cryptography-2.5.1-980798", + "versionInfo": "2.5.1", + "downloadLocation": "NOASSERTION", + "filesAnalyzed": false, + "licenseConcluded": "Apache-2.0 AND LicenseRef-scancode-unknown-license-reference AND MIT", + "copyrightText": "Copyright (c) 2000-2024 The Legion of the Bouncy Castle Inc. (https://www.bouncycastle.org), Copyright (c) Legion of the Bouncy Castle Inc. 2000-2024, Copyright Legion of the Bouncy Castle Inc. 2000-2024", + "externalRefs": [ + { + "referenceCategory": "PACKAGE-MANAGER", + "referenceType": "purl", + "referenceLocator": "pkg:nuget/BouncyCastle.Cryptography@2.5.1" + } + ] + }, + { + "name": "Microsoft.AspNetCore.Http.Abstractions", + "SPDXID": "SPDXRef-nuget-Microsoft.AspNetCore.Http.Abstractions-2.3.0-795f67", + "versionInfo": "2.3.0", + "downloadLocation": "NOASSERTION", + "filesAnalyzed": false, + "licenseConcluded": "Apache-2.0 AND LicenseRef-scancode-unknown", + "copyrightText": "(c) Microsoft Corporation, Copyright (c) .NET Foundation and Contributors", + "externalRefs": [ + { + "referenceCategory": "PACKAGE-MANAGER", + "referenceType": "purl", + "referenceLocator": "pkg:nuget/Microsoft.AspNetCore.Http.Abstractions@2.3.0" + } + ] + }, + { + "name": "System.Security.Cryptography.Pkcs", + "SPDXID": "SPDXRef-nuget-System.Security.Cryptography.Pkcs-8.0.1-0bc701", + "versionInfo": "8.0.1", + "downloadLocation": "NOASSERTION", + "filesAnalyzed": false, + "licenseConcluded": "MIT", + "copyrightText": "(c) 1997-2005 Sean Eron Anderson, (c) Microsoft Corporation, Copyright (c) .NET Foundation, Copyright (c) .NET Foundation and Contributors, Copyright (c) .NET Foundation Contributors, Copyright (c) 1980, 1986, 1993 The Regents of the University of California, Copyright (c) 1989 by Hewlett-Packard Company, Palo Alto, Ca. \u0026 Digital Equipment Corporation, Maynard, Mass, Copyright (c) 1990- 1993, 1996 Open Software Foundation, Inc., Copyright (c) 1991-2022 Unicode, Inc., Copyright (c) 1995-2022 Jean-loup Gailly and Mark Adler, Copyright (c) 1998 Microsoft, Copyright (c) 1998 Microsoft. To, Copyright (c) 1999 Lucent Technologies, Copyright (c) 2004-2006 Intel Corporation, Copyright (c) 2005-2007, Nick Galbreath, Copyright (c) 2005-2020 Rich Felker, Copyright (c) 2006 Jb Evain (jbevain@gmail.com), Copyright (c) 2007 James Newton-King, Copyright (c) 2008-2016, Wojciech Mula, Copyright (c) 2008-2020 Advanced Micro Devices, Inc., Copyright (c) 2009, 2010, 2013-2016 by the Brotli Authors, Copyright (c) 2011 Novell, Inc (http://www.novell.com), Copyright (c) 2011-2015 Intel Corporation, Copyright (c) 2011-2020 Microsoft Corp, Copyright (c) 2011, Google Inc., Copyright (c) 2012 - present, Victor Zverovich, Copyright (c) 2012-2021 Yann Collet, Copyright (c) 2013-2017, Alfred Klomp, Copyright (c) 2013-2017, Milosz Krajewski, Copyright (c) 2014 Ryan Juckett http://www.ryanjuckett.com, Copyright (c) 2015 The Chromium Authors, Copyright (c) 2015 THL A29 Limited, a Tencent company, and Milo Yip, Copyright (c) 2015 Xamarin, Inc (http://www.xamarin.com), Copyright (c) 2015-2017, Wojciech Mula, Copyright (c) 2016-2017, Matthieu Darbois, Copyright (c) 2017 Yoshifumi Kawai, Copyright (c) 2018 Alexander Chermyanin, Copyright (c) 2019 Microsoft Corporation, Daan Leijen, Copyright (c) 2020 Dan Shechter, Copyright (c) 2020 Mara Bos \u003cm-ou.se@m-ou.se\u003e, Copyright (c) 2021, Copyright (c) 2021 csFastFloat authors, Copyright (c) 2022, Geoff Langdale, Copyright (c) 2022, Wojciech Mula, Copyright (c) Andrew Arnott, Copyright (c) Microsoft Corporation, Copyright (c) Six Labors, Copyright (c) The Internet Society (2003), Copyright (c) The Internet Society 1997, Copyright (c) YEAR W3C(r) (MIT, ERCIM, Keio, Beihang) Disclaimers, Copyright (c) YEAR W3C(r) (MIT, ERCIM, Keio, Beihang). Disclaimers, Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018 The Regents of the University of California, Copyright 2012 the V8 project authors, Copyright 2018 Daniel Lemire, Copyright 2019 LLVM Project, Portions (c) International Organization, Portions (c) International Organization for Standardization 1986", + "externalRefs": [ + { + "referenceCategory": "PACKAGE-MANAGER", + "referenceType": "purl", + "referenceLocator": "pkg:nuget/System.Security.Cryptography.Pkcs@8.0.1" + } + ] + }, + { + "name": "MimeKit", + "SPDXID": "SPDXRef-nuget-MimeKit-4.13.0-23ac4f", + "versionInfo": "4.13.0", + "downloadLocation": "NOASSERTION", + "filesAnalyzed": false, + "licenseConcluded": "MIT", + "copyrightText": "Copyright (c) 2012-2025 .NET Foundation and Contributors, Copyright 2013-2025 .NET Foundation and Contributors", + "externalRefs": [ + { + "referenceCategory": "PACKAGE-MANAGER", + "referenceType": "purl", + "referenceLocator": "pkg:nuget/MimeKit@4.13.0" + } + ] + }, + { + "name": "Microsoft.Extensions.DependencyInjection.Abstractions", + "SPDXID": "SPDXRef-nuget-Microsoft.Extensions.DependencyInjection.Abstractions-8.0.0-18c45d", + "versionInfo": "8.0.0", + "downloadLocation": "NOASSERTION", + "filesAnalyzed": false, + "licenseConcluded": "MIT", + "copyrightText": "(c) 1997-2005 Sean Eron Anderson, (c) Microsoft Corporation, Copyright (c) .NET Foundation, Copyright (c) .NET Foundation and Contributors, Copyright (c) .NET Foundation Contributors, Copyright (c) 1980, 1986, 1993 The Regents of the University of California, Copyright (c) 1989 by Hewlett-Packard Company, Palo Alto, Ca. \u0026 Digital Equipment Corporation, Maynard, Mass, Copyright (c) 1990- 1993, 1996 Open Software Foundation, Inc., Copyright (c) 1991-2022 Unicode, Inc., Copyright (c) 1995-2022 Jean-loup Gailly and Mark Adler, Copyright (c) 1998 Microsoft. To, Copyright (c) 1999 Lucent Technologies, Copyright (c) 2004-2006 Intel Corporation, Copyright (c) 2005-2007, Nick Galbreath, Copyright (c) 2005-2020 Rich Felker, Copyright (c) 2006 Jb Evain (jbevain@gmail.com), Copyright (c) 2007 James Newton-King, Copyright (c) 2008-2016, Wojciech Mula, Copyright (c) 2008-2020 Advanced Micro Devices, Inc., Copyright (c) 2009, 2010, 2013-2016 by the Brotli Authors, Copyright (c) 2011 Novell, Inc (http://www.novell.com), Copyright (c) 2011-2015 Intel Corporation, Copyright (c) 2011-2020 Microsoft Corp, Copyright (c) 2011, Google Inc., Copyright (c) 2012 - present, Victor Zverovich, Copyright (c) 2012-2021 Yann Collet, Copyright (c) 2013-2017, Alfred Klomp, Copyright (c) 2013-2017, Milosz Krajewski, Copyright (c) 2014 Ryan Juckett http://www.ryanjuckett.com, Copyright (c) 2015 The Chromium Authors, Copyright (c) 2015 THL A29 Limited, a Tencent company, and Milo Yip, Copyright (c) 2015 Xamarin, Inc (http://www.xamarin.com), Copyright (c) 2015-2017, Wojciech Mula, Copyright (c) 2016-2017, Matthieu Darbois, Copyright (c) 2017 Yoshifumi Kawai, Copyright (c) 2018 Alexander Chermyanin, Copyright (c) 2019 Microsoft Corporation, Daan Leijen, Copyright (c) 2020 Dan Shechter, Copyright (c) 2020 Mara Bos \u003cm-ou.se@m-ou.se\u003e, Copyright (c) 2021 csFastFloat authors, Copyright (c) 2022, Geoff Langdale, Copyright (c) 2022, Wojciech Mula, Copyright (c) Andrew Arnott, Copyright (c) Microsoft Corporation, Copyright (c) Six Labors, Copyright (c) The Internet Society (2003), Copyright (c) The Internet Society 1997, Copyright (c) YEAR W3C(r) (MIT, ERCIM, Keio, Beihang). Disclaimers, Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018 The Regents of the University of California, Copyright 2012 the V8 project authors, Copyright 2018 Daniel Lemire, Copyright 2019 LLVM Project, Portions (c) International Organization", + "externalRefs": [ + { + "referenceCategory": "PACKAGE-MANAGER", + "referenceType": "purl", + "referenceLocator": "pkg:nuget/Microsoft.Extensions.DependencyInjection.Abstractions@8.0.0" + } + ] + }, + { + "name": "MailKit", + "SPDXID": "SPDXRef-nuget-MailKit-4.13.0-b26bfd", + "versionInfo": "4.13.0", + "downloadLocation": "NOASSERTION", + "filesAnalyzed": false, + "licenseConcluded": "MIT", + "copyrightText": "Copyright (c) 2013-2024 .NET Foundation and Contributors, Copyright 2013-2025 .NET Foundation and Contributors", + "externalRefs": [ + { + "referenceCategory": "PACKAGE-MANAGER", + "referenceType": "purl", + "referenceLocator": "pkg:nuget/MailKit@4.13.0" + } + ] + }, + { + "name": "System.Buffers", + "SPDXID": "SPDXRef-nuget-System.Buffers-4.6.0-da25bf", + "versionInfo": "4.6.0", + "downloadLocation": "NOASSERTION", + "filesAnalyzed": false, + "licenseConcluded": "MIT", + "copyrightText": "(c) Microsoft Corporation", + "externalRefs": [ + { + "referenceCategory": "PACKAGE-MANAGER", + "referenceType": "purl", + "referenceLocator": "pkg:nuget/System.Buffers@4.6.0" + } + ] + }, + { + "name": "System.Text.Encodings.Web", + "SPDXID": "SPDXRef-nuget-System.Text.Encodings.Web-9.0.8-7001c6", + "versionInfo": "9.0.8", + "downloadLocation": "NOASSERTION", + "filesAnalyzed": false, + "licenseConcluded": "MIT", + "copyrightText": "(c) 1995-2024 Jean-loup Gailly and Mark Adler, (c) 1997-2005 Sean Eron Anderson, (c) Microsoft Corporation, Copyright (c) .NET Foundation, Copyright (c) .NET Foundation and Contributors, Copyright (c) .NET Foundation Contributors, Copyright (c) 1980, 1986, 1993 The Regents of the University of California, Copyright (c) 1989 by Hewlett-Packard Company, Palo Alto, Ca. \u0026 Digital Equipment Corporation, Maynard, Mass, Copyright (c) 1990- 1993, 1996 Open Software Foundation, Inc., Copyright (c) 1991-2022 Unicode, Inc., Copyright (c) 1998 Microsoft, Copyright (c) 1999 Lucent Technologies, Copyright (c) 2004-2006 Intel Corporation, Copyright (c) 2005-2007, Nick Galbreath, Copyright (c) 2005-2020 Rich Felker, Copyright (c) 2006 Jb Evain (jbevain@gmail.com), Copyright (c) 2007 James Newton-King, Copyright (c) 2008-2016, Wojciech Mula, Copyright (c) 2008-2020 Advanced Micro Devices, Inc., Copyright (c) 2009, 2010, 2013-2016 by the Brotli Authors, Copyright (c) 2011 Novell, Inc (http://www.novell.com), Copyright (c) 2011-2015 Intel Corporation, Copyright (c) 2011-2020 Microsoft Corp, Copyright (c) 2011, Google Inc., Copyright (c) 2012 - present, Victor Zverovich, Copyright (c) 2012-2021 Yann Collet, Copyright (c) 2013-2017, Alfred Klomp, Copyright (c) 2013-2017, Milosz Krajewski, Copyright (c) 2014 Ryan Juckett http://www.ryanjuckett.com, Copyright (c) 2015 Andrew Gallant, Copyright (c) 2015 The Chromium Authors, Copyright (c) 2015 THL A29 Limited, a Tencent company, and Milo Yip, Copyright (c) 2015 Xamarin, Inc (http://www.xamarin.com), Copyright (c) 2015-2017, Wojciech Mula, Copyright (c) 2015-2018, Wojciech Mula, Copyright (c) 2016-2017, Matthieu Darbois, Copyright (c) 2017 Yoshifumi Kawai, Copyright (c) 2018 Alexander Chermyanin, Copyright (c) 2018 Nemanja Mijailovic, Copyright (c) 2019 Microsoft Corporation, Daan Leijen, Copyright (c) 2020 Dan Shechter, Copyright (c) 2020 Mara Bos \u003cm-ou.se@m-ou.se\u003e, Copyright (c) 2021, Copyright (c) 2022 FormatJS, Copyright (c) 2022, Geoff Langdale, Copyright (c) 2022, Wojciech Mula, Copyright (c) Andrew Arnott, Copyright (c) Microsoft Corporation, Copyright (c) Six Labors, Copyright (c) The Internet Society (2003), Copyright (c) The Internet Society 1997, Copyright (c) YEAR W3C(r) (MIT, ERCIM, Keio, Beihang) Disclaimers, Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018 The Regents of the University of California, Copyright 2012 the V8 project authors, Copyright 2018 Daniel Lemire, Copyright 2019 LLVM Project, Portions (c) International Organization for Standardization 1986", + "externalRefs": [ + { + "referenceCategory": "PACKAGE-MANAGER", + "referenceType": "purl", + "referenceLocator": "pkg:nuget/System.Text.Encodings.Web@9.0.8" + } + ] + }, + { + "name": "System.Formats.Asn1", + "SPDXID": "SPDXRef-nuget-System.Formats.Asn1-8.0.1-037f22", + "versionInfo": "8.0.1", + "downloadLocation": "NOASSERTION", + "filesAnalyzed": false, + "licenseConcluded": "MIT", + "copyrightText": "(c) 1997-2005 Sean Eron Anderson, (c) Microsoft Corporation, Copyright (c) .NET Foundation, Copyright (c) .NET Foundation and Contributors, Copyright (c) .NET Foundation Contributors, Copyright (c) 1980, 1986, 1993 The Regents of the University of California, Copyright (c) 1989 by Hewlett-Packard Company, Palo Alto, Ca. \u0026 Digital Equipment Corporation, Maynard, Mass, Copyright (c) 1990- 1993, 1996 Open Software Foundation, Inc., Copyright (c) 1991-2022 Unicode, Inc., Copyright (c) 1995-2022 Jean-loup Gailly and Mark Adler, Copyright (c) 1998 Microsoft. To, Copyright (c) 1999 Lucent Technologies, Copyright (c) 2004-2006 Intel Corporation, Copyright (c) 2005-2007, Nick Galbreath, Copyright (c) 2005-2020 Rich Felker, Copyright (c) 2006 Jb Evain (jbevain@gmail.com), Copyright (c) 2007 James Newton-King, Copyright (c) 2008-2016, Wojciech Mula, Copyright (c) 2008-2020 Advanced Micro Devices, Inc., Copyright (c) 2009, 2010, 2013-2016 by the Brotli Authors, Copyright (c) 2011 Novell, Inc (http://www.novell.com), Copyright (c) 2011-2015 Intel Corporation, Copyright (c) 2011-2020 Microsoft Corp, Copyright (c) 2011, Google Inc., Copyright (c) 2012 - present, Victor Zverovich, Copyright (c) 2012-2021 Yann Collet, Copyright (c) 2013-2017, Alfred Klomp, Copyright (c) 2013-2017, Milosz Krajewski, Copyright (c) 2014 Ryan Juckett http://www.ryanjuckett.com, Copyright (c) 2015 The Chromium Authors, Copyright (c) 2015 THL A29 Limited, a Tencent company, and Milo Yip, Copyright (c) 2015 Xamarin, Inc (http://www.xamarin.com), Copyright (c) 2015-2017, Wojciech Mula, Copyright (c) 2016-2017, Matthieu Darbois, Copyright (c) 2017 Yoshifumi Kawai, Copyright (c) 2018 Alexander Chermyanin, Copyright (c) 2019 Microsoft Corporation, Daan Leijen, Copyright (c) 2020 Dan Shechter, Copyright (c) 2020 Mara Bos \u003cm-ou.se@m-ou.se\u003e, Copyright (c) 2021 csFastFloat authors, Copyright (c) 2022, Geoff Langdale, Copyright (c) 2022, Wojciech Mula, Copyright (c) Andrew Arnott, Copyright (c) Microsoft Corporation, Copyright (c) Six Labors, Copyright (c) The Internet Society (2003), Copyright (c) The Internet Society 1997, Copyright (c) YEAR W3C(r) (MIT, ERCIM, Keio, Beihang). Disclaimers, Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018 The Regents of the University of California, Copyright 2012 the V8 project authors, Copyright 2018 Daniel Lemire, Copyright 2019 LLVM Project, Portions (c) International Organization", + "externalRefs": [ + { + "referenceCategory": "PACKAGE-MANAGER", + "referenceType": "purl", + "referenceLocator": "pkg:nuget/System.Formats.Asn1@8.0.1" + } + ] + }, + { + "name": "Microsoft.AspNetCore.Http", + "SPDXID": "SPDXRef-nuget-Microsoft.AspNetCore.Http-2.3.0-239946", + "versionInfo": "2.3.0", + "downloadLocation": "NOASSERTION", + "filesAnalyzed": false, + "licenseConcluded": "Apache-2.0 AND LicenseRef-scancode-unknown", + "copyrightText": "(c) Microsoft Corporation, Copyright (c) .NET Foundation and Contributors", + "externalRefs": [ + { + "referenceCategory": "PACKAGE-MANAGER", + "referenceType": "purl", + "referenceLocator": "pkg:nuget/Microsoft.AspNetCore.Http@2.3.0" + } + ] + }, + { + "name": "Microsoft.AspNetCore.Http.Features", + "SPDXID": "SPDXRef-nuget-Microsoft.AspNetCore.Http.Features-2.3.0-1fa4f7", + "versionInfo": "2.3.0", + "downloadLocation": "NOASSERTION", + "filesAnalyzed": false, + "licenseConcluded": "Apache-2.0 AND LicenseRef-scancode-unknown", + "copyrightText": "(c) Microsoft Corporation, Copyright (c) .NET Foundation and Contributors", + "externalRefs": [ + { + "referenceCategory": "PACKAGE-MANAGER", + "referenceType": "purl", + "referenceLocator": "pkg:nuget/Microsoft.AspNetCore.Http.Features@2.3.0" + } + ] + }, + { + "name": "actions/checkout", + "SPDXID": "SPDXRef-githubactions-actions-checkout-4..-75c946", + "versionInfo": "4.*.*", + "downloadLocation": "NOASSERTION", + "filesAnalyzed": false, + "externalRefs": [ + { + "referenceCategory": "PACKAGE-MANAGER", + "referenceType": "purl", + "referenceLocator": "pkg:githubactions/actions/checkout@4.%2A.%2A" + } + ] + }, + { + "name": "actions/setup-dotnet", + "SPDXID": "SPDXRef-githubactions-actions-setup-dotnet-4..-75c946", + "versionInfo": "4.*.*", + "downloadLocation": "NOASSERTION", + "filesAnalyzed": false, + "externalRefs": [ + { + "referenceCategory": "PACKAGE-MANAGER", + "referenceType": "purl", + "referenceLocator": "pkg:githubactions/actions/setup-dotnet@4.%2A.%2A" + } + ] + }, + { + "name": "actions/checkout", + "SPDXID": "SPDXRef-githubactions-actions-checkout-3-75c946", + "versionInfo": "3", + "downloadLocation": "NOASSERTION", + "filesAnalyzed": false, + "externalRefs": [ + { + "referenceCategory": "PACKAGE-MANAGER", + "referenceType": "purl", + "referenceLocator": "pkg:githubactions/actions/checkout@3" + } + ] + }, + { + "name": "github/codeql-action/analyze", + "SPDXID": "SPDXRef-githubactions-githubcodeql-action-analyze-2-75c946", + "versionInfo": "2", + "downloadLocation": "NOASSERTION", + "filesAnalyzed": false, + "externalRefs": [ + { + "referenceCategory": "PACKAGE-MANAGER", + "referenceType": "purl", + "referenceLocator": "pkg:githubactions/github/codeql-action/analyze@2" + } + ] + }, + { + "name": "github/codeql-action/autobuild", + "SPDXID": "SPDXRef-githubactions-githubcodeql-action-autobuild-2-75c946", + "versionInfo": "2", + "downloadLocation": "NOASSERTION", + "filesAnalyzed": false, + "externalRefs": [ + { + "referenceCategory": "PACKAGE-MANAGER", + "referenceType": "purl", + "referenceLocator": "pkg:githubactions/github/codeql-action/autobuild@2" + } + ] + }, + { + "name": "github/codeql-action/init", + "SPDXID": "SPDXRef-githubactions-githubcodeql-action-init-2-75c946", + "versionInfo": "2", + "downloadLocation": "NOASSERTION", + "filesAnalyzed": false, + "externalRefs": [ + { + "referenceCategory": "PACKAGE-MANAGER", + "referenceType": "purl", + "referenceLocator": "pkg:githubactions/github/codeql-action/init@2" + } + ] + }, + { + "name": "gitpython", + "SPDXID": "SPDXRef-pypi-gitpython-75c946", + "versionInfo": "\u003e= 3.1.0", + "downloadLocation": "NOASSERTION", + "filesAnalyzed": false, + "externalRefs": [ + { + "referenceCategory": "PACKAGE-MANAGER", + "referenceType": "purl", + "referenceLocator": "pkg:pypi/gitpython" + } + ] + }, + { + "name": "com.github.CactuseSecurity/firewall-orchestrator", + "SPDXID": "SPDXRef-github-CactuseSecurity-firewall-orchestrator-main-0c7c2b", + "versionInfo": "main", + "downloadLocation": "git+https://github.com/CactuseSecurity/firewall-orchestrator", + "filesAnalyzed": false, + "licenseDeclared": "Apache-2.0", + "externalRefs": [ + { + "referenceCategory": "PACKAGE-MANAGER", + "referenceType": "purl", + "referenceLocator": "pkg:github/CactuseSecurity/firewall-orchestrator@main" + } + ] + } + ], + "relationships": [ + { + "spdxElementId": "SPDXRef-nuget-Microsoft.AspNetCore.Components.Authorization-8.0.15-58c86a", + "relatedSpdxElement": "SPDXRef-nuget-Microsoft.Extensions.Primitives-8.0.0-973e61", + "relationshipType": "DEPENDS_ON" + }, + { + "spdxElementId": "SPDXRef-nuget-Microsoft.AspNetCore.Components.Authorization-8.0.15-58c86a", + "relatedSpdxElement": "SPDXRef-nuget-Microsoft.Extensions.Options-8.0.2-ed918b", + "relationshipType": "DEPENDS_ON" + }, + { + "spdxElementId": "SPDXRef-nuget-Microsoft.AspNetCore.Components.Authorization-8.0.15-58c86a", + "relatedSpdxElement": "SPDXRef-nuget-Microsoft.Extensions.DependencyInjection.Abstractions-8.0.2-934d86", + "relationshipType": "DEPENDS_ON" + }, + { + "spdxElementId": "SPDXRef-nuget-Microsoft.AspNetCore.Components.Authorization-8.0.15-58c86a", + "relatedSpdxElement": "SPDXRef-nuget-Microsoft.Extensions.Logging.Abstractions-8.0.3-0d07ba", + "relationshipType": "DEPENDS_ON" + }, + { + "spdxElementId": "SPDXRef-nuget-Microsoft.AspNetCore.Components.Authorization-8.0.15-58c86a", + "relatedSpdxElement": "SPDXRef-nuget-Microsoft.AspNetCore.Authorization-8.0.15-59a19e", + "relationshipType": "DEPENDS_ON" + }, + { + "spdxElementId": "SPDXRef-nuget-Microsoft.AspNetCore.Components.Authorization-8.0.15-58c86a", + "relatedSpdxElement": "SPDXRef-nuget-Microsoft.AspNetCore.Metadata-8.0.15-f13caf", + "relationshipType": "DEPENDS_ON" + }, + { + "spdxElementId": "SPDXRef-nuget-Microsoft.AspNetCore.Components.Authorization-8.0.15-58c86a", + "relatedSpdxElement": "SPDXRef-nuget-Microsoft.AspNetCore.Components-8.0.15-154912", + "relationshipType": "DEPENDS_ON" + }, + { + "spdxElementId": "SPDXRef-nuget-Microsoft.AspNetCore.Components.Authorization-8.0.15-58c86a", + "relatedSpdxElement": "SPDXRef-nuget-Microsoft.AspNetCore.Components.Analyzers-8.0.15-75b14f", + "relationshipType": "DEPENDS_ON" + }, + { + "spdxElementId": "SPDXRef-nuget-Microsoft.AspNetCore.Components-8.0.15-154912", + "relatedSpdxElement": "SPDXRef-nuget-Microsoft.Extensions.Primitives-8.0.0-973e61", + "relationshipType": "DEPENDS_ON" + }, + { + "spdxElementId": "SPDXRef-nuget-Microsoft.AspNetCore.Components-8.0.15-154912", + "relatedSpdxElement": "SPDXRef-nuget-Microsoft.Extensions.Options-8.0.2-ed918b", + "relationshipType": "DEPENDS_ON" + }, + { + "spdxElementId": "SPDXRef-nuget-Microsoft.AspNetCore.Components-8.0.15-154912", + "relatedSpdxElement": "SPDXRef-nuget-Microsoft.Extensions.DependencyInjection.Abstractions-8.0.2-934d86", + "relationshipType": "DEPENDS_ON" + }, + { + "spdxElementId": "SPDXRef-nuget-Microsoft.AspNetCore.Components-8.0.15-154912", + "relatedSpdxElement": "SPDXRef-nuget-Microsoft.Extensions.Logging.Abstractions-8.0.3-0d07ba", + "relationshipType": "DEPENDS_ON" + }, + { + "spdxElementId": "SPDXRef-nuget-Microsoft.AspNetCore.Components-8.0.15-154912", + "relatedSpdxElement": "SPDXRef-nuget-Microsoft.AspNetCore.Authorization-8.0.15-59a19e", + "relationshipType": "DEPENDS_ON" + }, + { + "spdxElementId": "SPDXRef-nuget-Microsoft.AspNetCore.Components-8.0.15-154912", + "relatedSpdxElement": "SPDXRef-nuget-Microsoft.AspNetCore.Metadata-8.0.15-f13caf", + "relationshipType": "DEPENDS_ON" + }, + { + "spdxElementId": "SPDXRef-nuget-Microsoft.AspNetCore.Components-8.0.15-154912", + "relatedSpdxElement": "SPDXRef-nuget-Microsoft.AspNetCore.Components.Analyzers-8.0.15-75b14f", + "relationshipType": "DEPENDS_ON" + }, + { + "spdxElementId": "SPDXRef-nuget-Microsoft.NET.Test.Sdk-17.14.1-86ab34", + "relatedSpdxElement": "SPDXRef-nuget-Newtonsoft.Json-13.0.3-7c98bf", + "relationshipType": "DEPENDS_ON" + }, + { + "spdxElementId": "SPDXRef-nuget-Microsoft.NET.Test.Sdk-17.14.1-86ab34", + "relatedSpdxElement": "SPDXRef-nuget-System.Reflection.Metadata-8.0.0-2fa35d", + "relationshipType": "DEPENDS_ON" + }, + { + "spdxElementId": "SPDXRef-nuget-Microsoft.NET.Test.Sdk-17.14.1-86ab34", + "relatedSpdxElement": "SPDXRef-nuget-System.Collections.Immutable-8.0.0-00b56b", + "relationshipType": "DEPENDS_ON" + }, + { + "spdxElementId": "SPDXRef-nuget-Microsoft.NET.Test.Sdk-17.14.1-86ab34", + "relatedSpdxElement": "SPDXRef-nuget-Microsoft.TestPlatform.ObjectModel-17.14.1-341464", + "relationshipType": "DEPENDS_ON" + }, + { + "spdxElementId": "SPDXRef-nuget-Microsoft.NET.Test.Sdk-17.14.1-86ab34", + "relatedSpdxElement": "SPDXRef-nuget-Microsoft.TestPlatform.TestHost-17.14.1-5a76b2", + "relationshipType": "DEPENDS_ON" + }, + { + "spdxElementId": "SPDXRef-nuget-Microsoft.NET.Test.Sdk-17.14.1-86ab34", + "relatedSpdxElement": "SPDXRef-nuget-Microsoft.CodeCoverage-17.14.1-1dfedf", + "relationshipType": "DEPENDS_ON" + }, + { + "spdxElementId": "SPDXRef-nuget-Microsoft.AspNetCore.Components-8.0.15-d179a3", + "relatedSpdxElement": "SPDXRef-nuget-Microsoft.Extensions.Primitives-8.0.0-7bb3ef", + "relationshipType": "DEPENDS_ON" + }, + { + "spdxElementId": "SPDXRef-nuget-Microsoft.AspNetCore.Components-8.0.15-d179a3", + "relatedSpdxElement": "SPDXRef-nuget-Microsoft.Extensions.Options-8.0.2-553265", + "relationshipType": "DEPENDS_ON" + }, + { + "spdxElementId": "SPDXRef-nuget-Microsoft.AspNetCore.Components-8.0.15-d179a3", + "relatedSpdxElement": "SPDXRef-nuget-Microsoft.Extensions.DependencyInjection.Abstractions-8.0.2-5a630c", + "relationshipType": "DEPENDS_ON" + }, + { + "spdxElementId": "SPDXRef-nuget-Microsoft.AspNetCore.Components-8.0.15-d179a3", + "relatedSpdxElement": "SPDXRef-nuget-Microsoft.Extensions.Logging.Abstractions-8.0.3-f5387c", + "relationshipType": "DEPENDS_ON" + }, + { + "spdxElementId": "SPDXRef-nuget-Microsoft.AspNetCore.Components-8.0.15-d179a3", + "relatedSpdxElement": "SPDXRef-nuget-Microsoft.AspNetCore.Authorization-8.0.15-457dff", + "relationshipType": "DEPENDS_ON" + }, + { + "spdxElementId": "SPDXRef-nuget-Microsoft.AspNetCore.Components-8.0.15-d179a3", + "relatedSpdxElement": "SPDXRef-nuget-Microsoft.AspNetCore.Metadata-8.0.15-7088bb", + "relationshipType": "DEPENDS_ON" + }, + { + "spdxElementId": "SPDXRef-nuget-Microsoft.AspNetCore.Components-8.0.15-d179a3", + "relatedSpdxElement": "SPDXRef-nuget-Microsoft.AspNetCore.Components.Analyzers-8.0.15-67a21b", + "relationshipType": "DEPENDS_ON" + }, + { + "spdxElementId": "SPDXRef-nuget-PuppeteerSharp-20.2.2-21f7e5", + "relatedSpdxElement": "SPDXRef-nuget-Microsoft.Extensions.Primitives-8.0.0-7bb3ef", + "relationshipType": "DEPENDS_ON" + }, + { + "spdxElementId": "SPDXRef-nuget-PuppeteerSharp-20.2.2-21f7e5", + "relatedSpdxElement": "SPDXRef-nuget-Microsoft.Extensions.Options-8.0.2-553265", + "relationshipType": "DEPENDS_ON" + }, + { + "spdxElementId": "SPDXRef-nuget-PuppeteerSharp-20.2.2-21f7e5", + "relatedSpdxElement": "SPDXRef-nuget-Microsoft.Extensions.DependencyInjection.Abstractions-8.0.2-5a630c", + "relationshipType": "DEPENDS_ON" + }, + { + "spdxElementId": "SPDXRef-nuget-PuppeteerSharp-20.2.2-21f7e5", + "relatedSpdxElement": "SPDXRef-nuget-Microsoft.Extensions.Logging.Abstractions-8.0.3-f5387c", + "relationshipType": "DEPENDS_ON" + }, + { + "spdxElementId": "SPDXRef-nuget-PuppeteerSharp-20.2.2-21f7e5", + "relatedSpdxElement": "SPDXRef-nuget-Microsoft.Extensions.Logging-8.0.1-d391ad", + "relationshipType": "DEPENDS_ON" + }, + { + "spdxElementId": "SPDXRef-nuget-PuppeteerSharp-20.2.2-21f7e5", + "relatedSpdxElement": "SPDXRef-nuget-Microsoft.Extensions.DependencyInjection-8.0.1-276050", + "relationshipType": "DEPENDS_ON" + }, + { + "spdxElementId": "SPDXRef-nuget-Microsoft.IdentityModel.Tokens-8.14.0-a883d6", + "relatedSpdxElement": "SPDXRef-nuget-Microsoft.IdentityModel.Abstractions-8.14.0-6e2c7d", + "relationshipType": "DEPENDS_ON" + }, + { + "spdxElementId": "SPDXRef-nuget-Microsoft.IdentityModel.Tokens-8.14.0-a883d6", + "relatedSpdxElement": "SPDXRef-nuget-Microsoft.Extensions.DependencyInjection.Abstractions-8.0.2-5a630c", + "relationshipType": "DEPENDS_ON" + }, + { + "spdxElementId": "SPDXRef-nuget-Microsoft.IdentityModel.Tokens-8.14.0-a883d6", + "relatedSpdxElement": "SPDXRef-nuget-Microsoft.IdentityModel.Logging-8.14.0-44c2b4", + "relationshipType": "DEPENDS_ON" + }, + { + "spdxElementId": "SPDXRef-nuget-Microsoft.IdentityModel.Tokens-8.14.0-a883d6", + "relatedSpdxElement": "SPDXRef-nuget-Microsoft.Extensions.Logging.Abstractions-8.0.3-f5387c", + "relationshipType": "DEPENDS_ON" + }, + { + "spdxElementId": "SPDXRef-nuget-bunit-1.40.0-4dce12", + "relatedSpdxElement": "SPDXRef-nuget-Microsoft.Extensions.Primitives-8.0.0-7bb3ef", + "relationshipType": "DEPENDS_ON" + }, + { + "spdxElementId": "SPDXRef-nuget-bunit-1.40.0-4dce12", + "relatedSpdxElement": "SPDXRef-nuget-Microsoft.Extensions.Options-8.0.2-553265", + "relationshipType": "DEPENDS_ON" + }, + { + "spdxElementId": "SPDXRef-nuget-bunit-1.40.0-4dce12", + "relatedSpdxElement": "SPDXRef-nuget-Microsoft.Extensions.DependencyInjection.Abstractions-8.0.2-5a630c", + "relationshipType": "DEPENDS_ON" + }, + { + "spdxElementId": "SPDXRef-nuget-bunit-1.40.0-4dce12", + "relatedSpdxElement": "SPDXRef-nuget-Microsoft.Extensions.Logging.Abstractions-8.0.3-f5387c", + "relationshipType": "DEPENDS_ON" + }, + { + "spdxElementId": "SPDXRef-nuget-bunit-1.40.0-4dce12", + "relatedSpdxElement": "SPDXRef-nuget-Microsoft.AspNetCore.Authorization-8.0.15-457dff", + "relationshipType": "DEPENDS_ON" + }, + { + "spdxElementId": "SPDXRef-nuget-bunit-1.40.0-4dce12", + "relatedSpdxElement": "SPDXRef-nuget-Microsoft.AspNetCore.Metadata-8.0.15-7088bb", + "relationshipType": "DEPENDS_ON" + }, + { + "spdxElementId": "SPDXRef-nuget-bunit-1.40.0-4dce12", + "relatedSpdxElement": "SPDXRef-nuget-Microsoft.AspNetCore.Components-8.0.15-d179a3", + "relationshipType": "DEPENDS_ON" + }, + { + "spdxElementId": "SPDXRef-nuget-bunit-1.40.0-4dce12", + "relatedSpdxElement": "SPDXRef-nuget-Microsoft.AspNetCore.Components.Analyzers-8.0.15-67a21b", + "relationshipType": "DEPENDS_ON" + }, + { + "spdxElementId": "SPDXRef-nuget-bunit-1.40.0-4dce12", + "relatedSpdxElement": "SPDXRef-nuget-Microsoft.AspNetCore.Components.Authorization-8.0.15-c2e5e2", + "relationshipType": "DEPENDS_ON" + }, + { + "spdxElementId": "SPDXRef-nuget-bunit-1.40.0-4dce12", + "relatedSpdxElement": "SPDXRef-nuget-Microsoft.Extensions.Configuration.Binder-8.0.2-bb6751", + "relationshipType": "DEPENDS_ON" + }, + { + "spdxElementId": "SPDXRef-nuget-bunit-1.40.0-4dce12", + "relatedSpdxElement": "SPDXRef-nuget-Microsoft.Extensions.Configuration-8.0.0-dce331", + "relationshipType": "DEPENDS_ON" + }, + { + "spdxElementId": "SPDXRef-nuget-bunit-1.40.0-4dce12", + "relatedSpdxElement": "SPDXRef-nuget-Microsoft.Extensions.Logging-8.0.1-d391ad", + "relationshipType": "DEPENDS_ON" + }, + { + "spdxElementId": "SPDXRef-nuget-bunit-1.40.0-4dce12", + "relatedSpdxElement": "SPDXRef-nuget-Microsoft.Extensions.FileProviders.Abstractions-8.0.0-3e71db", + "relationshipType": "DEPENDS_ON" + }, + { + "spdxElementId": "SPDXRef-nuget-bunit-1.40.0-4dce12", + "relatedSpdxElement": "SPDXRef-nuget-Microsoft.Extensions.Localization.Abstractions-8.0.11-4cb515", + "relationshipType": "DEPENDS_ON" + }, + { + "spdxElementId": "SPDXRef-nuget-bunit-1.40.0-4dce12", + "relatedSpdxElement": "SPDXRef-nuget-Microsoft.Extensions.DependencyInjection-8.0.1-276050", + "relationshipType": "DEPENDS_ON" + }, + { + "spdxElementId": "SPDXRef-nuget-bunit-1.40.0-4dce12", + "relatedSpdxElement": "SPDXRef-nuget-System.IO.Pipelines-8.0.0-f9572b", + "relationshipType": "DEPENDS_ON" + }, + { + "spdxElementId": "SPDXRef-nuget-bunit-1.40.0-4dce12", + "relatedSpdxElement": "SPDXRef-nuget-Microsoft.JSInterop-8.0.11-5ea157", + "relationshipType": "DEPENDS_ON" + }, + { + "spdxElementId": "SPDXRef-nuget-bunit-1.40.0-4dce12", + "relatedSpdxElement": "SPDXRef-nuget-Microsoft.Extensions.Configuration.FileExtensions-8.0.1-6b3a2e", + "relationshipType": "DEPENDS_ON" + }, + { + "spdxElementId": "SPDXRef-nuget-bunit-1.40.0-4dce12", + "relatedSpdxElement": "SPDXRef-nuget-System.Text.Json-8.0.5-74b06c", + "relationshipType": "DEPENDS_ON" + }, + { + "spdxElementId": "SPDXRef-nuget-bunit-1.40.0-4dce12", + "relatedSpdxElement": "SPDXRef-nuget-Microsoft.Extensions.Caching.Memory-8.0.1-24ebac", + "relationshipType": "DEPENDS_ON" + }, + { + "spdxElementId": "SPDXRef-nuget-bunit-1.40.0-4dce12", + "relatedSpdxElement": "SPDXRef-nuget-Microsoft.AspNetCore.Components.Web-8.0.11-3380f9", + "relationshipType": "DEPENDS_ON" + }, + { + "spdxElementId": "SPDXRef-nuget-bunit-1.40.0-4dce12", + "relatedSpdxElement": "SPDXRef-nuget-bunit.core-1.40.0-44d971", + "relationshipType": "DEPENDS_ON" + }, + { + "spdxElementId": "SPDXRef-nuget-bunit-1.40.0-4dce12", + "relatedSpdxElement": "SPDXRef-nuget-AngleSharp.Diffing-1.0.0-08ab89", + "relationshipType": "DEPENDS_ON" + }, + { + "spdxElementId": "SPDXRef-nuget-bunit-1.40.0-4dce12", + "relatedSpdxElement": "SPDXRef-nuget-Microsoft.Extensions.Configuration.Abstractions-8.0.0-639bd0", + "relationshipType": "DEPENDS_ON" + }, + { + "spdxElementId": "SPDXRef-nuget-bunit-1.40.0-4dce12", + "relatedSpdxElement": "SPDXRef-nuget-Microsoft.AspNetCore.Components.WebAssembly-8.0.11-b60482", + "relationshipType": "DEPENDS_ON" + }, + { + "spdxElementId": "SPDXRef-nuget-bunit-1.40.0-4dce12", + "relatedSpdxElement": "SPDXRef-nuget-Microsoft.Extensions.FileSystemGlobbing-8.0.0-df8146", + "relationshipType": "DEPENDS_ON" + }, + { + "spdxElementId": "SPDXRef-nuget-bunit-1.40.0-4dce12", + "relatedSpdxElement": "SPDXRef-nuget-Microsoft.JSInterop.WebAssembly-8.0.11-7d7f03", + "relationshipType": "DEPENDS_ON" + }, + { + "spdxElementId": "SPDXRef-nuget-bunit-1.40.0-4dce12", + "relatedSpdxElement": "SPDXRef-nuget-Microsoft.Extensions.FileProviders.Physical-8.0.0-628894", + "relationshipType": "DEPENDS_ON" + }, + { + "spdxElementId": "SPDXRef-nuget-bunit-1.40.0-4dce12", + "relatedSpdxElement": "SPDXRef-nuget-Microsoft.Extensions.Configuration.Json-8.0.1-bd4bb5", + "relationshipType": "DEPENDS_ON" + }, + { + "spdxElementId": "SPDXRef-nuget-bunit-1.40.0-4dce12", + "relatedSpdxElement": "SPDXRef-nuget-Microsoft.AspNetCore.Components.WebAssembly.Authentication-8.0.11-d84320", + "relationshipType": "DEPENDS_ON" + }, + { + "spdxElementId": "SPDXRef-nuget-bunit-1.40.0-4dce12", + "relatedSpdxElement": "SPDXRef-nuget-AngleSharp-1.2.0-ec1ca1", + "relationshipType": "DEPENDS_ON" + }, + { + "spdxElementId": "SPDXRef-nuget-bunit-1.40.0-4dce12", + "relatedSpdxElement": "SPDXRef-nuget-AngleSharp.Css-1.0.0-beta.154-30e617", + "relationshipType": "DEPENDS_ON" + }, + { + "spdxElementId": "SPDXRef-nuget-bunit-1.40.0-4dce12", + "relatedSpdxElement": "SPDXRef-nuget-Microsoft.Extensions.Caching.Abstractions-8.0.0-82b542", + "relationshipType": "DEPENDS_ON" + }, + { + "spdxElementId": "SPDXRef-nuget-bunit-1.40.0-4dce12", + "relatedSpdxElement": "SPDXRef-nuget-Microsoft.AspNetCore.Components.Forms-8.0.11-b3ce0c", + "relationshipType": "DEPENDS_ON" + }, + { + "spdxElementId": "SPDXRef-nuget-bunit-1.40.0-4dce12", + "relatedSpdxElement": "SPDXRef-nuget-bunit.web-1.40.0-b4ac35", + "relationshipType": "DEPENDS_ON" + }, + { + "spdxElementId": "SPDXRef-nuget-Microsoft.AspNetCore.Components.Authorization-8.0.15-c2e5e2", + "relatedSpdxElement": "SPDXRef-nuget-Microsoft.Extensions.Primitives-8.0.0-7bb3ef", + "relationshipType": "DEPENDS_ON" + }, + { + "spdxElementId": "SPDXRef-nuget-Microsoft.AspNetCore.Components.Authorization-8.0.15-c2e5e2", + "relatedSpdxElement": "SPDXRef-nuget-Microsoft.Extensions.Options-8.0.2-553265", + "relationshipType": "DEPENDS_ON" + }, + { + "spdxElementId": "SPDXRef-nuget-Microsoft.AspNetCore.Components.Authorization-8.0.15-c2e5e2", + "relatedSpdxElement": "SPDXRef-nuget-Microsoft.Extensions.DependencyInjection.Abstractions-8.0.2-5a630c", + "relationshipType": "DEPENDS_ON" + }, + { + "spdxElementId": "SPDXRef-nuget-Microsoft.AspNetCore.Components.Authorization-8.0.15-c2e5e2", + "relatedSpdxElement": "SPDXRef-nuget-Microsoft.Extensions.Logging.Abstractions-8.0.3-f5387c", + "relationshipType": "DEPENDS_ON" + }, + { + "spdxElementId": "SPDXRef-nuget-Microsoft.AspNetCore.Components.Authorization-8.0.15-c2e5e2", + "relatedSpdxElement": "SPDXRef-nuget-Microsoft.AspNetCore.Authorization-8.0.15-457dff", + "relationshipType": "DEPENDS_ON" + }, + { + "spdxElementId": "SPDXRef-nuget-Microsoft.AspNetCore.Components.Authorization-8.0.15-c2e5e2", + "relatedSpdxElement": "SPDXRef-nuget-Microsoft.AspNetCore.Metadata-8.0.15-7088bb", + "relationshipType": "DEPENDS_ON" + }, + { + "spdxElementId": "SPDXRef-nuget-Microsoft.AspNetCore.Components.Authorization-8.0.15-c2e5e2", + "relatedSpdxElement": "SPDXRef-nuget-Microsoft.AspNetCore.Components-8.0.15-d179a3", + "relationshipType": "DEPENDS_ON" + }, + { + "spdxElementId": "SPDXRef-nuget-Microsoft.AspNetCore.Components.Authorization-8.0.15-c2e5e2", + "relatedSpdxElement": "SPDXRef-nuget-Microsoft.AspNetCore.Components.Analyzers-8.0.15-67a21b", + "relationshipType": "DEPENDS_ON" + }, + { + "spdxElementId": "SPDXRef-nuget-NUnit3TestAdapter-5.1.0-5f80ff", + "relatedSpdxElement": "SPDXRef-nuget-System.Diagnostics.DiagnosticSource-5.0.0-31c6d8", + "relationshipType": "DEPENDS_ON" + }, + { + "spdxElementId": "SPDXRef-nuget-NUnit3TestAdapter-5.1.0-5f80ff", + "relatedSpdxElement": "SPDXRef-nuget-System.Reflection.Metadata-8.0.0-2fa35d", + "relationshipType": "DEPENDS_ON" + }, + { + "spdxElementId": "SPDXRef-nuget-NUnit3TestAdapter-5.1.0-5f80ff", + "relatedSpdxElement": "SPDXRef-nuget-Microsoft.TestPlatform.AdapterUtilities-17.13.0-22a1b0", + "relationshipType": "DEPENDS_ON" + }, + { + "spdxElementId": "SPDXRef-nuget-NUnit3TestAdapter-5.1.0-5f80ff", + "relatedSpdxElement": "SPDXRef-nuget-System.Collections.Immutable-8.0.0-00b56b", + "relationshipType": "DEPENDS_ON" + }, + { + "spdxElementId": "SPDXRef-nuget-NUnit3TestAdapter-5.1.0-5f80ff", + "relatedSpdxElement": "SPDXRef-nuget-Microsoft.Testing.Platform.MSBuild-1.7.3-c5050d", + "relationshipType": "DEPENDS_ON" + }, + { + "spdxElementId": "SPDXRef-nuget-NUnit3TestAdapter-5.1.0-5f80ff", + "relatedSpdxElement": "SPDXRef-nuget-Microsoft.Testing.Extensions.VSTestBridge-1.7.3-e3b7da", + "relationshipType": "DEPENDS_ON" + }, + { + "spdxElementId": "SPDXRef-nuget-NUnit3TestAdapter-5.1.0-5f80ff", + "relatedSpdxElement": "SPDXRef-nuget-Microsoft.Testing.Extensions.TrxReport.Abstractions-1.7.3-14ef65", + "relationshipType": "DEPENDS_ON" + }, + { + "spdxElementId": "SPDXRef-nuget-NUnit3TestAdapter-5.1.0-5f80ff", + "relatedSpdxElement": "SPDXRef-nuget-Microsoft.Testing.Extensions.Telemetry-1.7.3-380d69", + "relationshipType": "DEPENDS_ON" + }, + { + "spdxElementId": "SPDXRef-nuget-NUnit3TestAdapter-5.1.0-5f80ff", + "relatedSpdxElement": "SPDXRef-nuget-Microsoft.TestPlatform.ObjectModel-17.14.1-341464", + "relationshipType": "DEPENDS_ON" + }, + { + "spdxElementId": "SPDXRef-nuget-NUnit3TestAdapter-5.1.0-5f80ff", + "relatedSpdxElement": "SPDXRef-nuget-Microsoft.Testing.Platform-1.7.3-984f53", + "relationshipType": "DEPENDS_ON" + }, + { + "spdxElementId": "SPDXRef-nuget-NUnit3TestAdapter-5.1.0-5f80ff", + "relatedSpdxElement": "SPDXRef-nuget-Microsoft.ApplicationInsights-2.23.0-92127e", + "relationshipType": "DEPENDS_ON" + }, + { + "spdxElementId": "SPDXRef-nuget-PuppeteerSharp-20.2.2-d76daa", + "relatedSpdxElement": "SPDXRef-nuget-Microsoft.Extensions.Primitives-8.0.0-0353ed", + "relationshipType": "DEPENDS_ON" + }, + { + "spdxElementId": "SPDXRef-nuget-PuppeteerSharp-20.2.2-d76daa", + "relatedSpdxElement": "SPDXRef-nuget-Microsoft.Extensions.Options-8.0.2-f33fde", + "relationshipType": "DEPENDS_ON" + }, + { + "spdxElementId": "SPDXRef-nuget-PuppeteerSharp-20.2.2-d76daa", + "relatedSpdxElement": "SPDXRef-nuget-Microsoft.Extensions.DependencyInjection-8.0.0-76ea4d", + "relationshipType": "DEPENDS_ON" + }, + { + "spdxElementId": "SPDXRef-nuget-PuppeteerSharp-20.2.2-d76daa", + "relatedSpdxElement": "SPDXRef-nuget-Microsoft.Extensions.Logging-8.0.0-c71dd9", + "relationshipType": "DEPENDS_ON" + }, + { + "spdxElementId": "SPDXRef-nuget-PuppeteerSharp-20.2.2-d76daa", + "relatedSpdxElement": "SPDXRef-nuget-Microsoft.Extensions.DependencyInjection.Abstractions-8.0.2-fa587a", + "relationshipType": "DEPENDS_ON" + }, + { + "spdxElementId": "SPDXRef-nuget-PuppeteerSharp-20.2.2-d76daa", + "relatedSpdxElement": "SPDXRef-nuget-Microsoft.Extensions.Logging.Abstractions-8.0.3-c90f02", + "relationshipType": "DEPENDS_ON" + }, + { + "spdxElementId": "SPDXRef-nuget-Microsoft.IdentityModel.Tokens-8.14.0-8284c6", + "relatedSpdxElement": "SPDXRef-nuget-Microsoft.IdentityModel.Abstractions-8.14.0-dada85", + "relationshipType": "DEPENDS_ON" + }, + { + "spdxElementId": "SPDXRef-nuget-Microsoft.IdentityModel.Tokens-8.14.0-8284c6", + "relatedSpdxElement": "SPDXRef-nuget-Microsoft.IdentityModel.Logging-8.14.0-b11f58", + "relationshipType": "DEPENDS_ON" + }, + { + "spdxElementId": "SPDXRef-nuget-System.IdentityModel.Tokens.Jwt-8.14.0-62ac6a", + "relatedSpdxElement": "SPDXRef-nuget-Microsoft.IdentityModel.Abstractions-8.14.0-dada85", + "relationshipType": "DEPENDS_ON" + }, + { + "spdxElementId": "SPDXRef-nuget-System.IdentityModel.Tokens.Jwt-8.14.0-62ac6a", + "relatedSpdxElement": "SPDXRef-nuget-Microsoft.IdentityModel.JsonWebTokens-8.14.0-3e0bac", + "relationshipType": "DEPENDS_ON" + }, + { + "spdxElementId": "SPDXRef-nuget-System.IdentityModel.Tokens.Jwt-8.14.0-62ac6a", + "relatedSpdxElement": "SPDXRef-nuget-Microsoft.IdentityModel.Tokens-8.14.0-8284c6", + "relationshipType": "DEPENDS_ON" + }, + { + "spdxElementId": "SPDXRef-nuget-System.IdentityModel.Tokens.Jwt-8.14.0-62ac6a", + "relatedSpdxElement": "SPDXRef-nuget-Microsoft.IdentityModel.Logging-8.14.0-b11f58", + "relationshipType": "DEPENDS_ON" + }, + { + "spdxElementId": "SPDXRef-nuget-System.IdentityModel.Tokens.Jwt-8.14.0-62ac6a", + "relatedSpdxElement": "SPDXRef-nuget-Microsoft.Extensions.DependencyInjection.Abstractions-8.0.0-88c4e5", + "relationshipType": "DEPENDS_ON" + }, + { + "spdxElementId": "SPDXRef-nuget-System.IdentityModel.Tokens.Jwt-8.14.0-62ac6a", + "relatedSpdxElement": "SPDXRef-nuget-Microsoft.Extensions.Logging.Abstractions-8.0.0-145c39", + "relationshipType": "DEPENDS_ON" + }, + { + "spdxElementId": "SPDXRef-nuget-Microsoft.Rest.ClientRuntime-2.3.24-508401", + "relatedSpdxElement": "SPDXRef-nuget-Newtonsoft.Json-13.0.3-631925", + "relationshipType": "DEPENDS_ON" + }, + { + "spdxElementId": "SPDXRef-nuget-RestSharp.Serializers.NewtonsoftJson-112.1.0-1f0a6b", + "relatedSpdxElement": "SPDXRef-nuget-RestSharp-112.1.0-839660", + "relationshipType": "DEPENDS_ON" + }, + { + "spdxElementId": "SPDXRef-nuget-RestSharp.Serializers.NewtonsoftJson-112.1.0-1f0a6b", + "relatedSpdxElement": "SPDXRef-nuget-Newtonsoft.Json-13.0.3-631925", + "relationshipType": "DEPENDS_ON" + }, + { + "spdxElementId": "SPDXRef-nuget-GraphQL.Client-6.1.0-7c0c75", + "relatedSpdxElement": "SPDXRef-nuget-GraphQL.Primitives-6.1.0-8b54bf", + "relationshipType": "DEPENDS_ON" + }, + { + "spdxElementId": "SPDXRef-nuget-GraphQL.Client-6.1.0-7c0c75", + "relatedSpdxElement": "SPDXRef-nuget-System.Reactive-6.0.0-f0ef58", + "relationshipType": "DEPENDS_ON" + }, + { + "spdxElementId": "SPDXRef-nuget-GraphQL.Client-6.1.0-7c0c75", + "relatedSpdxElement": "SPDXRef-nuget-GraphQL.Client.Abstractions-6.1.0-132a88", + "relationshipType": "DEPENDS_ON" + }, + { + "spdxElementId": "SPDXRef-nuget-GraphQL.Client-6.1.0-7c0c75", + "relatedSpdxElement": "SPDXRef-nuget-GraphQL.Client.Abstractions.Websocket-6.1.0-604e8e", + "relationshipType": "DEPENDS_ON" + }, + { + "spdxElementId": "SPDXRef-nuget-Microsoft.AspNetCore.Components-8.0.15-259cdf", + "relatedSpdxElement": "SPDXRef-nuget-Microsoft.Extensions.Primitives-8.0.0-07a9d5", + "relationshipType": "DEPENDS_ON" + }, + { + "spdxElementId": "SPDXRef-nuget-Microsoft.AspNetCore.Components-8.0.15-259cdf", + "relatedSpdxElement": "SPDXRef-nuget-Microsoft.Extensions.Options-8.0.2-3ddafa", + "relationshipType": "DEPENDS_ON" + }, + { + "spdxElementId": "SPDXRef-nuget-Microsoft.AspNetCore.Components-8.0.15-259cdf", + "relatedSpdxElement": "SPDXRef-nuget-Microsoft.Extensions.DependencyInjection.Abstractions-8.0.2-b43535", + "relationshipType": "DEPENDS_ON" + }, + { + "spdxElementId": "SPDXRef-nuget-Microsoft.AspNetCore.Components-8.0.15-259cdf", + "relatedSpdxElement": "SPDXRef-nuget-Microsoft.Extensions.Logging.Abstractions-8.0.3-854476", + "relationshipType": "DEPENDS_ON" + }, + { + "spdxElementId": "SPDXRef-nuget-Microsoft.AspNetCore.Components-8.0.15-259cdf", + "relatedSpdxElement": "SPDXRef-nuget-Microsoft.AspNetCore.Authorization-8.0.15-6b8922", + "relationshipType": "DEPENDS_ON" + }, + { + "spdxElementId": "SPDXRef-nuget-Microsoft.AspNetCore.Components-8.0.15-259cdf", + "relatedSpdxElement": "SPDXRef-nuget-Microsoft.AspNetCore.Metadata-8.0.15-2a8ab9", + "relationshipType": "DEPENDS_ON" + }, + { + "spdxElementId": "SPDXRef-nuget-Microsoft.AspNetCore.Components-8.0.15-259cdf", + "relatedSpdxElement": "SPDXRef-nuget-Microsoft.AspNetCore.Components.Analyzers-8.0.15-89dc0e", + "relationshipType": "DEPENDS_ON" + }, + { + "spdxElementId": "SPDXRef-nuget-GraphQL.Client.Serializer.Newtonsoft-6.1.0-9b01fa", + "relatedSpdxElement": "SPDXRef-nuget-GraphQL.Primitives-6.1.0-8b54bf", + "relationshipType": "DEPENDS_ON" + }, + { + "spdxElementId": "SPDXRef-nuget-GraphQL.Client.Serializer.Newtonsoft-6.1.0-9b01fa", + "relatedSpdxElement": "SPDXRef-nuget-GraphQL.Client.Abstractions-6.1.0-132a88", + "relationshipType": "DEPENDS_ON" + }, + { + "spdxElementId": "SPDXRef-nuget-GraphQL.Client.Serializer.Newtonsoft-6.1.0-9b01fa", + "relatedSpdxElement": "SPDXRef-nuget-GraphQL.Client.Abstractions.Websocket-6.1.0-604e8e", + "relationshipType": "DEPENDS_ON" + }, + { + "spdxElementId": "SPDXRef-nuget-GraphQL.Client.Serializer.Newtonsoft-6.1.0-9b01fa", + "relatedSpdxElement": "SPDXRef-nuget-Newtonsoft.Json-13.0.3-631925", + "relationshipType": "DEPENDS_ON" + }, + { + "spdxElementId": "SPDXRef-nuget-GraphQL.Client.Serializer.SystemTextJson-6.1.0-c25e33", + "relatedSpdxElement": "SPDXRef-nuget-GraphQL.Primitives-6.1.0-8b54bf", + "relationshipType": "DEPENDS_ON" + }, + { + "spdxElementId": "SPDXRef-nuget-GraphQL.Client.Serializer.SystemTextJson-6.1.0-c25e33", + "relatedSpdxElement": "SPDXRef-nuget-GraphQL.Client.Abstractions-6.1.0-132a88", + "relationshipType": "DEPENDS_ON" + }, + { + "spdxElementId": "SPDXRef-nuget-GraphQL.Client.Serializer.SystemTextJson-6.1.0-c25e33", + "relatedSpdxElement": "SPDXRef-nuget-GraphQL.Client.Abstractions.Websocket-6.1.0-604e8e", + "relationshipType": "DEPENDS_ON" + }, + { + "spdxElementId": "SPDXRef-nuget-PuppeteerSharp-20.2.2-18c6e7", + "relatedSpdxElement": "SPDXRef-nuget-Microsoft.Extensions.Primitives-8.0.0-fb04bb", + "relationshipType": "DEPENDS_ON" + }, + { + "spdxElementId": "SPDXRef-nuget-PuppeteerSharp-20.2.2-18c6e7", + "relatedSpdxElement": "SPDXRef-nuget-Microsoft.Extensions.Options-8.0.2-43de69", + "relationshipType": "DEPENDS_ON" + }, + { + "spdxElementId": "SPDXRef-nuget-PuppeteerSharp-20.2.2-18c6e7", + "relatedSpdxElement": "SPDXRef-nuget-Microsoft.Extensions.DependencyInjection-8.0.0-03eab0", + "relationshipType": "DEPENDS_ON" + }, + { + "spdxElementId": "SPDXRef-nuget-PuppeteerSharp-20.2.2-18c6e7", + "relatedSpdxElement": "SPDXRef-nuget-Microsoft.Extensions.Logging-8.0.0-7574df", + "relationshipType": "DEPENDS_ON" + }, + { + "spdxElementId": "SPDXRef-nuget-PuppeteerSharp-20.2.2-18c6e7", + "relatedSpdxElement": "SPDXRef-nuget-Microsoft.Extensions.DependencyInjection.Abstractions-8.0.2-f0b5b3", + "relationshipType": "DEPENDS_ON" + }, + { + "spdxElementId": "SPDXRef-nuget-PuppeteerSharp-20.2.2-18c6e7", + "relatedSpdxElement": "SPDXRef-nuget-Microsoft.Extensions.Logging.Abstractions-8.0.3-318844", + "relationshipType": "DEPENDS_ON" + }, + { + "spdxElementId": "SPDXRef-nuget-BlazorTable-1.17.0-647113", + "relatedSpdxElement": "SPDXRef-nuget-Microsoft.Extensions.Primitives-8.0.0-fb04bb", + "relationshipType": "DEPENDS_ON" + }, + { + "spdxElementId": "SPDXRef-nuget-BlazorTable-1.17.0-647113", + "relatedSpdxElement": "SPDXRef-nuget-Microsoft.Extensions.Options-8.0.2-43de69", + "relationshipType": "DEPENDS_ON" + }, + { + "spdxElementId": "SPDXRef-nuget-BlazorTable-1.17.0-647113", + "relatedSpdxElement": "SPDXRef-nuget-Microsoft.Extensions.DependencyInjection-8.0.0-03eab0", + "relationshipType": "DEPENDS_ON" + }, + { + "spdxElementId": "SPDXRef-nuget-BlazorTable-1.17.0-647113", + "relatedSpdxElement": "SPDXRef-nuget-Microsoft.Extensions.DependencyInjection.Abstractions-8.0.2-f0b5b3", + "relationshipType": "DEPENDS_ON" + }, + { + "spdxElementId": "SPDXRef-nuget-BlazorTable-1.17.0-647113", + "relatedSpdxElement": "SPDXRef-nuget-Microsoft.Extensions.Logging.Abstractions-8.0.3-318844", + "relationshipType": "DEPENDS_ON" + }, + { + "spdxElementId": "SPDXRef-nuget-BlazorTable-1.17.0-647113", + "relatedSpdxElement": "SPDXRef-nuget-Microsoft.AspNetCore.Authorization-8.0.15-3bb48c", + "relationshipType": "DEPENDS_ON" + }, + { + "spdxElementId": "SPDXRef-nuget-BlazorTable-1.17.0-647113", + "relatedSpdxElement": "SPDXRef-nuget-Microsoft.AspNetCore.Metadata-8.0.15-d16054", + "relationshipType": "DEPENDS_ON" + }, + { + "spdxElementId": "SPDXRef-nuget-BlazorTable-1.17.0-647113", + "relatedSpdxElement": "SPDXRef-nuget-Microsoft.AspNetCore.Components-8.0.15-2782e6", + "relationshipType": "DEPENDS_ON" + }, + { + "spdxElementId": "SPDXRef-nuget-BlazorTable-1.17.0-647113", + "relatedSpdxElement": "SPDXRef-nuget-Microsoft.AspNetCore.Components.Analyzers-8.0.15-a1b7ad", + "relationshipType": "DEPENDS_ON" + }, + { + "spdxElementId": "SPDXRef-nuget-BlazorTable-1.17.0-647113", + "relatedSpdxElement": "SPDXRef-nuget-Microsoft.Extensions.Localization.Abstractions-3.1.18-552d34", + "relationshipType": "DEPENDS_ON" + }, + { + "spdxElementId": "SPDXRef-nuget-BlazorTable-1.17.0-647113", + "relatedSpdxElement": "SPDXRef-nuget-Microsoft.Extensions.Localization-3.1.18-8fe31d", + "relationshipType": "DEPENDS_ON" + }, + { + "spdxElementId": "SPDXRef-nuget-BlazorTable-1.17.0-647113", + "relatedSpdxElement": "SPDXRef-nuget-Microsoft.AspNetCore.Components.Web-3.1.18-2b319e", + "relationshipType": "DEPENDS_ON" + }, + { + "spdxElementId": "SPDXRef-nuget-BlazorTable-1.17.0-647113", + "relatedSpdxElement": "SPDXRef-nuget-Microsoft.AspNetCore.Components.Forms-3.1.18-aa28bb", + "relationshipType": "DEPENDS_ON" + }, + { + "spdxElementId": "SPDXRef-nuget-BlazorTable-1.17.0-647113", + "relatedSpdxElement": "SPDXRef-nuget-LinqKit.Core-1.1.26-8271d4", + "relationshipType": "DEPENDS_ON" + }, + { + "spdxElementId": "SPDXRef-nuget-BlazorTable-1.17.0-647113", + "relatedSpdxElement": "SPDXRef-nuget-Microsoft.JSInterop-3.1.18-ec5757", + "relationshipType": "DEPENDS_ON" + }, + { + "spdxElementId": "SPDXRef-nuget-Microsoft.AspNetCore.Components-8.0.15-2782e6", + "relatedSpdxElement": "SPDXRef-nuget-Microsoft.Extensions.Primitives-8.0.0-fb04bb", + "relationshipType": "DEPENDS_ON" + }, + { + "spdxElementId": "SPDXRef-nuget-Microsoft.AspNetCore.Components-8.0.15-2782e6", + "relatedSpdxElement": "SPDXRef-nuget-Microsoft.Extensions.Options-8.0.2-43de69", + "relationshipType": "DEPENDS_ON" + }, + { + "spdxElementId": "SPDXRef-nuget-Microsoft.AspNetCore.Components-8.0.15-2782e6", + "relatedSpdxElement": "SPDXRef-nuget-Microsoft.Extensions.DependencyInjection.Abstractions-8.0.2-f0b5b3", + "relationshipType": "DEPENDS_ON" + }, + { + "spdxElementId": "SPDXRef-nuget-Microsoft.AspNetCore.Components-8.0.15-2782e6", + "relatedSpdxElement": "SPDXRef-nuget-Microsoft.Extensions.Logging.Abstractions-8.0.3-318844", + "relationshipType": "DEPENDS_ON" + }, + { + "spdxElementId": "SPDXRef-nuget-Microsoft.AspNetCore.Components-8.0.15-2782e6", + "relatedSpdxElement": "SPDXRef-nuget-Microsoft.AspNetCore.Authorization-8.0.15-3bb48c", + "relationshipType": "DEPENDS_ON" + }, + { + "spdxElementId": "SPDXRef-nuget-Microsoft.AspNetCore.Components-8.0.15-2782e6", + "relatedSpdxElement": "SPDXRef-nuget-Microsoft.AspNetCore.Metadata-8.0.15-d16054", + "relationshipType": "DEPENDS_ON" + }, + { + "spdxElementId": "SPDXRef-nuget-Microsoft.AspNetCore.Components-8.0.15-2782e6", + "relatedSpdxElement": "SPDXRef-nuget-Microsoft.AspNetCore.Components.Analyzers-8.0.15-a1b7ad", + "relationshipType": "DEPENDS_ON" + }, + { + "spdxElementId": "SPDXRef-nuget-GraphQL.Client.Serializer.Newtonsoft-6.1.0-af029d", + "relatedSpdxElement": "SPDXRef-nuget-GraphQL.Primitives-6.1.0-0e1997", + "relationshipType": "DEPENDS_ON" + }, + { + "spdxElementId": "SPDXRef-nuget-GraphQL.Client.Serializer.Newtonsoft-6.1.0-af029d", + "relatedSpdxElement": "SPDXRef-nuget-GraphQL.Client.Abstractions-6.1.0-94d0f3", + "relationshipType": "DEPENDS_ON" + }, + { + "spdxElementId": "SPDXRef-nuget-GraphQL.Client.Serializer.Newtonsoft-6.1.0-af029d", + "relatedSpdxElement": "SPDXRef-nuget-GraphQL.Client.Abstractions.Websocket-6.1.0-9c814e", + "relationshipType": "DEPENDS_ON" + }, + { + "spdxElementId": "SPDXRef-nuget-GraphQL.Client.Serializer.Newtonsoft-6.1.0-af029d", + "relatedSpdxElement": "SPDXRef-nuget-Newtonsoft.Json-13.0.3-88677a", + "relationshipType": "DEPENDS_ON" + }, + { + "spdxElementId": "SPDXRef-nuget-Microsoft.AspNetCore.Components-8.0.15-869df9", + "relatedSpdxElement": "SPDXRef-nuget-Microsoft.Extensions.Primitives-8.0.0-f4af79", + "relationshipType": "DEPENDS_ON" + }, + { + "spdxElementId": "SPDXRef-nuget-Microsoft.AspNetCore.Components-8.0.15-869df9", + "relatedSpdxElement": "SPDXRef-nuget-Microsoft.Extensions.Options-8.0.2-4cac30", + "relationshipType": "DEPENDS_ON" + }, + { + "spdxElementId": "SPDXRef-nuget-Microsoft.AspNetCore.Components-8.0.15-869df9", + "relatedSpdxElement": "SPDXRef-nuget-Microsoft.Extensions.DependencyInjection.Abstractions-8.0.2-32a665", + "relationshipType": "DEPENDS_ON" + }, + { + "spdxElementId": "SPDXRef-nuget-Microsoft.AspNetCore.Components-8.0.15-869df9", + "relatedSpdxElement": "SPDXRef-nuget-Microsoft.Extensions.Logging.Abstractions-8.0.3-bc822b", + "relationshipType": "DEPENDS_ON" + }, + { + "spdxElementId": "SPDXRef-nuget-Microsoft.AspNetCore.Components-8.0.15-869df9", + "relatedSpdxElement": "SPDXRef-nuget-Microsoft.AspNetCore.Authorization-8.0.15-4be166", + "relationshipType": "DEPENDS_ON" + }, + { + "spdxElementId": "SPDXRef-nuget-Microsoft.AspNetCore.Components-8.0.15-869df9", + "relatedSpdxElement": "SPDXRef-nuget-Microsoft.AspNetCore.Metadata-8.0.15-38c0cd", + "relationshipType": "DEPENDS_ON" + }, + { + "spdxElementId": "SPDXRef-nuget-Microsoft.AspNetCore.Components-8.0.15-869df9", + "relatedSpdxElement": "SPDXRef-nuget-Microsoft.AspNetCore.Components.Analyzers-8.0.15-99d18e", + "relationshipType": "DEPENDS_ON" + }, + { + "spdxElementId": "SPDXRef-nuget-Swashbuckle.AspNetCore-8.1.1-96b60e", + "relatedSpdxElement": "SPDXRef-nuget-Swashbuckle.AspNetCore.Swagger-8.1.1-46d10b", + "relationshipType": "DEPENDS_ON" + }, + { + "spdxElementId": "SPDXRef-nuget-Swashbuckle.AspNetCore-8.1.1-96b60e", + "relatedSpdxElement": "SPDXRef-nuget-Swashbuckle.AspNetCore.SwaggerUI-8.1.1-e01486", + "relationshipType": "DEPENDS_ON" + }, + { + "spdxElementId": "SPDXRef-nuget-Swashbuckle.AspNetCore-8.1.1-96b60e", + "relatedSpdxElement": "SPDXRef-nuget-Microsoft.OpenApi-1.6.23-a09a48", + "relationshipType": "DEPENDS_ON" + }, + { + "spdxElementId": "SPDXRef-nuget-Swashbuckle.AspNetCore-8.1.1-96b60e", + "relatedSpdxElement": "SPDXRef-nuget-Microsoft.Extensions.ApiDescription.Server-6.0.5-1864e8", + "relationshipType": "DEPENDS_ON" + }, + { + "spdxElementId": "SPDXRef-nuget-Swashbuckle.AspNetCore-8.1.1-96b60e", + "relatedSpdxElement": "SPDXRef-nuget-Swashbuckle.AspNetCore.SwaggerGen-8.1.1-1e762c", + "relationshipType": "DEPENDS_ON" + }, + { + "spdxElementId": "SPDXRef-nuget-PuppeteerSharp-20.2.2-336c02", + "relatedSpdxElement": "SPDXRef-nuget-Microsoft.Extensions.Primitives-8.0.0-8da07a", + "relationshipType": "DEPENDS_ON" + }, + { + "spdxElementId": "SPDXRef-nuget-PuppeteerSharp-20.2.2-336c02", + "relatedSpdxElement": "SPDXRef-nuget-Microsoft.Extensions.Options-8.0.2-ce1910", + "relationshipType": "DEPENDS_ON" + }, + { + "spdxElementId": "SPDXRef-nuget-PuppeteerSharp-20.2.2-336c02", + "relatedSpdxElement": "SPDXRef-nuget-Microsoft.Extensions.DependencyInjection-8.0.0-a9400f", + "relationshipType": "DEPENDS_ON" + }, + { + "spdxElementId": "SPDXRef-nuget-PuppeteerSharp-20.2.2-336c02", + "relatedSpdxElement": "SPDXRef-nuget-Microsoft.Extensions.Logging-8.0.0-e38db4", + "relationshipType": "DEPENDS_ON" + }, + { + "spdxElementId": "SPDXRef-nuget-PuppeteerSharp-20.2.2-336c02", + "relatedSpdxElement": "SPDXRef-nuget-Microsoft.Extensions.DependencyInjection.Abstractions-8.0.2-15e0f0", + "relationshipType": "DEPENDS_ON" + }, + { + "spdxElementId": "SPDXRef-nuget-PuppeteerSharp-20.2.2-336c02", + "relatedSpdxElement": "SPDXRef-nuget-Microsoft.Extensions.Logging.Abstractions-8.0.3-ae48ad", + "relationshipType": "DEPENDS_ON" + }, + { + "spdxElementId": "SPDXRef-nuget-System.IdentityModel.Tokens.Jwt-8.14.0-e897cc", + "relatedSpdxElement": "SPDXRef-nuget-Microsoft.IdentityModel.Abstractions-8.14.0-65944f", + "relationshipType": "DEPENDS_ON" + }, + { + "spdxElementId": "SPDXRef-nuget-System.IdentityModel.Tokens.Jwt-8.14.0-e897cc", + "relatedSpdxElement": "SPDXRef-nuget-Microsoft.IdentityModel.JsonWebTokens-8.14.0-1249a1", + "relationshipType": "DEPENDS_ON" + }, + { + "spdxElementId": "SPDXRef-nuget-System.IdentityModel.Tokens.Jwt-8.14.0-e897cc", + "relatedSpdxElement": "SPDXRef-nuget-Microsoft.IdentityModel.Tokens-8.14.0-7bf14e", + "relationshipType": "DEPENDS_ON" + }, + { + "spdxElementId": "SPDXRef-nuget-System.IdentityModel.Tokens.Jwt-8.14.0-e897cc", + "relatedSpdxElement": "SPDXRef-nuget-Microsoft.IdentityModel.Logging-8.14.0-c2340a", + "relationshipType": "DEPENDS_ON" + }, + { + "spdxElementId": "SPDXRef-nuget-Novell.Directory.Ldap.NETStandard-4.0.0-1ecb72", + "relatedSpdxElement": "SPDXRef-nuget-Microsoft.Extensions.DependencyInjection.Abstractions-8.0.2-15e0f0", + "relationshipType": "DEPENDS_ON" + }, + { + "spdxElementId": "SPDXRef-nuget-Novell.Directory.Ldap.NETStandard-4.0.0-1ecb72", + "relatedSpdxElement": "SPDXRef-nuget-Microsoft.Extensions.Logging.Abstractions-8.0.3-ae48ad", + "relationshipType": "DEPENDS_ON" + }, + { + "spdxElementId": "SPDXRef-nuget-Microsoft.IdentityModel.Tokens-8.14.0-7bf14e", + "relatedSpdxElement": "SPDXRef-nuget-Microsoft.IdentityModel.Abstractions-8.14.0-65944f", + "relationshipType": "DEPENDS_ON" + }, + { + "spdxElementId": "SPDXRef-nuget-Microsoft.IdentityModel.Tokens-8.14.0-7bf14e", + "relatedSpdxElement": "SPDXRef-nuget-Microsoft.Extensions.DependencyInjection.Abstractions-8.0.2-15e0f0", + "relationshipType": "DEPENDS_ON" + }, + { + "spdxElementId": "SPDXRef-nuget-Microsoft.IdentityModel.Tokens-8.14.0-7bf14e", + "relatedSpdxElement": "SPDXRef-nuget-Microsoft.IdentityModel.Logging-8.14.0-c2340a", + "relationshipType": "DEPENDS_ON" + }, + { + "spdxElementId": "SPDXRef-nuget-Microsoft.IdentityModel.Tokens-8.14.0-7bf14e", + "relatedSpdxElement": "SPDXRef-nuget-Microsoft.Extensions.Logging.Abstractions-8.0.3-ae48ad", + "relationshipType": "DEPENDS_ON" + }, + { + "spdxElementId": "SPDXRef-nuget-Microsoft.AspNetCore.Authentication.JwtBearer-8.0.15-6252d7", + "relatedSpdxElement": "SPDXRef-nuget-Microsoft.IdentityModel.Abstractions-8.14.0-65944f", + "relationshipType": "DEPENDS_ON" + }, + { + "spdxElementId": "SPDXRef-nuget-Microsoft.AspNetCore.Authentication.JwtBearer-8.0.15-6252d7", + "relatedSpdxElement": "SPDXRef-nuget-Microsoft.IdentityModel.JsonWebTokens-8.14.0-1249a1", + "relationshipType": "DEPENDS_ON" + }, + { + "spdxElementId": "SPDXRef-nuget-Microsoft.AspNetCore.Authentication.JwtBearer-8.0.15-6252d7", + "relatedSpdxElement": "SPDXRef-nuget-System.IdentityModel.Tokens.Jwt-8.14.0-e897cc", + "relationshipType": "DEPENDS_ON" + }, + { + "spdxElementId": "SPDXRef-nuget-Microsoft.AspNetCore.Authentication.JwtBearer-8.0.15-6252d7", + "relatedSpdxElement": "SPDXRef-nuget-Microsoft.IdentityModel.Tokens-8.14.0-7bf14e", + "relationshipType": "DEPENDS_ON" + }, + { + "spdxElementId": "SPDXRef-nuget-Microsoft.AspNetCore.Authentication.JwtBearer-8.0.15-6252d7", + "relatedSpdxElement": "SPDXRef-nuget-Microsoft.IdentityModel.Protocols-7.1.2-dacada", + "relationshipType": "DEPENDS_ON" + }, + { + "spdxElementId": "SPDXRef-nuget-Microsoft.AspNetCore.Authentication.JwtBearer-8.0.15-6252d7", + "relatedSpdxElement": "SPDXRef-nuget-Microsoft.IdentityModel.Protocols.OpenIdConnect-7.1.2-99e23d", + "relationshipType": "DEPENDS_ON" + }, + { + "spdxElementId": "SPDXRef-nuget-Microsoft.AspNetCore.Authentication.JwtBearer-8.0.15-6252d7", + "relatedSpdxElement": "SPDXRef-nuget-Microsoft.Extensions.DependencyInjection.Abstractions-8.0.2-15e0f0", + "relationshipType": "DEPENDS_ON" + }, + { + "spdxElementId": "SPDXRef-nuget-Microsoft.AspNetCore.Authentication.JwtBearer-8.0.15-6252d7", + "relatedSpdxElement": "SPDXRef-nuget-Microsoft.IdentityModel.Logging-8.14.0-c2340a", + "relationshipType": "DEPENDS_ON" + }, + { + "spdxElementId": "SPDXRef-nuget-Microsoft.AspNetCore.Authentication.JwtBearer-8.0.15-6252d7", + "relatedSpdxElement": "SPDXRef-nuget-Microsoft.Extensions.Logging.Abstractions-8.0.3-ae48ad", + "relationshipType": "DEPENDS_ON" + }, + { + "spdxElementId": "SPDXRef-nuget-MimeKit-4.13.0-23ac4f", + "relatedSpdxElement": "SPDXRef-nuget-System.Security.Cryptography.Pkcs-8.0.1-0bc701", + "relationshipType": "DEPENDS_ON" + }, + { + "spdxElementId": "SPDXRef-nuget-MimeKit-4.13.0-23ac4f", + "relatedSpdxElement": "SPDXRef-nuget-BouncyCastle.Cryptography-2.5.1-980798", + "relationshipType": "DEPENDS_ON" + }, + { + "spdxElementId": "SPDXRef-nuget-MailKit-4.13.0-b26bfd", + "relatedSpdxElement": "SPDXRef-nuget-System.Security.Cryptography.Pkcs-8.0.1-0bc701", + "relationshipType": "DEPENDS_ON" + }, + { + "spdxElementId": "SPDXRef-nuget-MailKit-4.13.0-b26bfd", + "relatedSpdxElement": "SPDXRef-nuget-BouncyCastle.Cryptography-2.5.1-980798", + "relationshipType": "DEPENDS_ON" + }, + { + "spdxElementId": "SPDXRef-nuget-MailKit-4.13.0-b26bfd", + "relatedSpdxElement": "SPDXRef-nuget-MimeKit-4.13.0-23ac4f", + "relationshipType": "DEPENDS_ON" + }, + { + "spdxElementId": "SPDXRef-nuget-MailKit-4.13.0-b26bfd", + "relatedSpdxElement": "SPDXRef-nuget-System.Formats.Asn1-8.0.1-037f22", + "relationshipType": "DEPENDS_ON" + }, + { + "spdxElementId": "SPDXRef-nuget-Microsoft.AspNetCore.Http-2.3.0-239946", + "relatedSpdxElement": "SPDXRef-nuget-Microsoft.Extensions.Primitives-8.0.0-6087da", + "relationshipType": "DEPENDS_ON" + }, + { + "spdxElementId": "SPDXRef-nuget-Microsoft.AspNetCore.Http-2.3.0-239946", + "relatedSpdxElement": "SPDXRef-nuget-Microsoft.Extensions.Options-8.0.2-c1e33e", + "relationshipType": "DEPENDS_ON" + }, + { + "spdxElementId": "SPDXRef-nuget-Microsoft.AspNetCore.Http-2.3.0-239946", + "relatedSpdxElement": "SPDXRef-nuget-Microsoft.Extensions.DependencyInjection.Abstractions-8.0.0-18c45d", + "relationshipType": "DEPENDS_ON" + }, + { + "spdxElementId": "SPDXRef-nuget-Microsoft.AspNetCore.Http-2.3.0-239946", + "relatedSpdxElement": "SPDXRef-nuget-Microsoft.AspNetCore.Http.Features-2.3.0-1fa4f7", + "relationshipType": "DEPENDS_ON" + }, + { + "spdxElementId": "SPDXRef-nuget-Microsoft.AspNetCore.Http-2.3.0-239946", + "relatedSpdxElement": "SPDXRef-nuget-Microsoft.Extensions.ObjectPool-8.0.11-da583c", + "relationshipType": "DEPENDS_ON" + }, + { + "spdxElementId": "SPDXRef-nuget-Microsoft.AspNetCore.Http-2.3.0-239946", + "relatedSpdxElement": "SPDXRef-nuget-Microsoft.Net.Http.Headers-2.3.0-6f214b", + "relationshipType": "DEPENDS_ON" + }, + { + "spdxElementId": "SPDXRef-nuget-Microsoft.AspNetCore.Http-2.3.0-239946", + "relatedSpdxElement": "SPDXRef-nuget-System.Buffers-4.6.0-da25bf", + "relationshipType": "DEPENDS_ON" + }, + { + "spdxElementId": "SPDXRef-nuget-Microsoft.AspNetCore.Http-2.3.0-239946", + "relatedSpdxElement": "SPDXRef-nuget-Microsoft.AspNetCore.WebUtilities-2.3.0-b47477", + "relationshipType": "DEPENDS_ON" + }, + { + "spdxElementId": "SPDXRef-nuget-Microsoft.AspNetCore.Http-2.3.0-239946", + "relatedSpdxElement": "SPDXRef-nuget-Microsoft.AspNetCore.Http.Abstractions-2.3.0-795f67", + "relationshipType": "DEPENDS_ON" + }, + { + "spdxElementId": "SPDXRef-nuget-Microsoft.AspNetCore.Http-2.3.0-239946", + "relatedSpdxElement": "SPDXRef-nuget-System.Text.Encodings.Web-9.0.8-7001c6", + "relationshipType": "DEPENDS_ON" + }, + { + "spdxElementId": "SPDXRef-github-CactuseSecurity-firewall-orchestrator-main-0c7c2b", + "relatedSpdxElement": "SPDXRef-nuget-Microsoft.AspNetCore.Components.Authorization-8.0.15-58c86a", + "relationshipType": "DEPENDS_ON" + }, + { + "spdxElementId": "SPDXRef-github-CactuseSecurity-firewall-orchestrator-main-0c7c2b", + "relatedSpdxElement": "SPDXRef-nuget-Microsoft.NET.Test.Sdk-17.14.1-86ab34", + "relationshipType": "DEPENDS_ON" + }, + { + "spdxElementId": "SPDXRef-github-CactuseSecurity-firewall-orchestrator-main-0c7c2b", + "relatedSpdxElement": "SPDXRef-nuget-PuppeteerSharp-20.2.2-21f7e5", + "relationshipType": "DEPENDS_ON" + }, + { + "spdxElementId": "SPDXRef-github-CactuseSecurity-firewall-orchestrator-main-0c7c2b", + "relatedSpdxElement": "SPDXRef-nuget-NUnit-4.4.0-d51504", + "relationshipType": "DEPENDS_ON" + }, + { + "spdxElementId": "SPDXRef-github-CactuseSecurity-firewall-orchestrator-main-0c7c2b", + "relatedSpdxElement": "SPDXRef-nuget-Microsoft.IdentityModel.Tokens-8.14.0-a883d6", + "relationshipType": "DEPENDS_ON" + }, + { + "spdxElementId": "SPDXRef-github-CactuseSecurity-firewall-orchestrator-main-0c7c2b", + "relatedSpdxElement": "SPDXRef-nuget-bunit-1.40.0-4dce12", + "relationshipType": "DEPENDS_ON" + }, + { + "spdxElementId": "SPDXRef-github-CactuseSecurity-firewall-orchestrator-main-0c7c2b", + "relatedSpdxElement": "SPDXRef-nuget-NUnit3TestAdapter-5.1.0-5f80ff", + "relationshipType": "DEPENDS_ON" + }, + { + "spdxElementId": "SPDXRef-github-CactuseSecurity-firewall-orchestrator-main-0c7c2b", + "relatedSpdxElement": "SPDXRef-nuget-PuppeteerSharp-20.2.2-d76daa", + "relationshipType": "DEPENDS_ON" + }, + { + "spdxElementId": "SPDXRef-github-CactuseSecurity-firewall-orchestrator-main-0c7c2b", + "relatedSpdxElement": "SPDXRef-nuget-HtmlAgilityPack-1.12.2-e4ed5d", + "relationshipType": "DEPENDS_ON" + }, + { + "spdxElementId": "SPDXRef-github-CactuseSecurity-firewall-orchestrator-main-0c7c2b", + "relatedSpdxElement": "SPDXRef-nuget-IPAddressRange-6.2.0-96c860", + "relationshipType": "DEPENDS_ON" + }, + { + "spdxElementId": "SPDXRef-github-CactuseSecurity-firewall-orchestrator-main-0c7c2b", + "relatedSpdxElement": "SPDXRef-nuget-System.IdentityModel.Tokens.Jwt-8.14.0-62ac6a", + "relationshipType": "DEPENDS_ON" + }, + { + "spdxElementId": "SPDXRef-github-CactuseSecurity-firewall-orchestrator-main-0c7c2b", + "relatedSpdxElement": "SPDXRef-nuget-Microsoft.Rest.ClientRuntime-2.3.24-508401", + "relationshipType": "DEPENDS_ON" + }, + { + "spdxElementId": "SPDXRef-github-CactuseSecurity-firewall-orchestrator-main-0c7c2b", + "relatedSpdxElement": "SPDXRef-nuget-RestSharp.Serializers.NewtonsoftJson-112.1.0-1f0a6b", + "relationshipType": "DEPENDS_ON" + }, + { + "spdxElementId": "SPDXRef-github-CactuseSecurity-firewall-orchestrator-main-0c7c2b", + "relatedSpdxElement": "SPDXRef-nuget-RestSharp-112.1.0-839660", + "relationshipType": "DEPENDS_ON" + }, + { + "spdxElementId": "SPDXRef-github-CactuseSecurity-firewall-orchestrator-main-0c7c2b", + "relatedSpdxElement": "SPDXRef-nuget-GraphQL.Client-6.1.0-7c0c75", + "relationshipType": "DEPENDS_ON" + }, + { + "spdxElementId": "SPDXRef-github-CactuseSecurity-firewall-orchestrator-main-0c7c2b", + "relatedSpdxElement": "SPDXRef-nuget-Microsoft.AspNetCore.Components-8.0.15-259cdf", + "relationshipType": "DEPENDS_ON" + }, + { + "spdxElementId": "SPDXRef-github-CactuseSecurity-firewall-orchestrator-main-0c7c2b", + "relatedSpdxElement": "SPDXRef-nuget-GraphQL.Client.Serializer.Newtonsoft-6.1.0-9b01fa", + "relationshipType": "DEPENDS_ON" + }, + { + "spdxElementId": "SPDXRef-github-CactuseSecurity-firewall-orchestrator-main-0c7c2b", + "relatedSpdxElement": "SPDXRef-nuget-GraphQL.Client.Serializer.SystemTextJson-6.1.0-c25e33", + "relationshipType": "DEPENDS_ON" + }, + { + "spdxElementId": "SPDXRef-github-CactuseSecurity-firewall-orchestrator-main-0c7c2b", + "relatedSpdxElement": "SPDXRef-nuget-IPAddressRange-6.2.0-2c2fd5", + "relationshipType": "DEPENDS_ON" + }, + { + "spdxElementId": "SPDXRef-github-CactuseSecurity-firewall-orchestrator-main-0c7c2b", + "relatedSpdxElement": "SPDXRef-nuget-IPAddressRange-6.2.0-c9d65a", + "relationshipType": "DEPENDS_ON" + }, + { + "spdxElementId": "SPDXRef-github-CactuseSecurity-firewall-orchestrator-main-0c7c2b", + "relatedSpdxElement": "SPDXRef-nuget-PuppeteerSharp-20.2.2-18c6e7", + "relationshipType": "DEPENDS_ON" + }, + { + "spdxElementId": "SPDXRef-github-CactuseSecurity-firewall-orchestrator-main-0c7c2b", + "relatedSpdxElement": "SPDXRef-nuget-BlazorTable-1.17.0-647113", + "relationshipType": "DEPENDS_ON" + }, + { + "spdxElementId": "SPDXRef-github-CactuseSecurity-firewall-orchestrator-main-0c7c2b", + "relatedSpdxElement": "SPDXRef-nuget-IPAddressRange-6.2.0-3030d8", + "relationshipType": "DEPENDS_ON" + }, + { + "spdxElementId": "SPDXRef-github-CactuseSecurity-firewall-orchestrator-main-0c7c2b", + "relatedSpdxElement": "SPDXRef-nuget-GraphQL.Client.Serializer.Newtonsoft-6.1.0-af029d", + "relationshipType": "DEPENDS_ON" + }, + { + "spdxElementId": "SPDXRef-github-CactuseSecurity-firewall-orchestrator-main-0c7c2b", + "relatedSpdxElement": "SPDXRef-nuget-Microsoft.AspNetCore.Components-8.0.15-869df9", + "relationshipType": "DEPENDS_ON" + }, + { + "spdxElementId": "SPDXRef-github-CactuseSecurity-firewall-orchestrator-main-0c7c2b", + "relatedSpdxElement": "SPDXRef-nuget-Swashbuckle.AspNetCore-8.1.1-96b60e", + "relationshipType": "DEPENDS_ON" + }, + { + "spdxElementId": "SPDXRef-github-CactuseSecurity-firewall-orchestrator-main-0c7c2b", + "relatedSpdxElement": "SPDXRef-nuget-PuppeteerSharp-20.2.2-336c02", + "relationshipType": "DEPENDS_ON" + }, + { + "spdxElementId": "SPDXRef-github-CactuseSecurity-firewall-orchestrator-main-0c7c2b", + "relatedSpdxElement": "SPDXRef-nuget-Novell.Directory.Ldap.NETStandard-4.0.0-1ecb72", + "relationshipType": "DEPENDS_ON" + }, + { + "spdxElementId": "SPDXRef-github-CactuseSecurity-firewall-orchestrator-main-0c7c2b", + "relatedSpdxElement": "SPDXRef-nuget-Microsoft.AspNetCore.Authentication.JwtBearer-8.0.15-6252d7", + "relationshipType": "DEPENDS_ON" + }, + { + "spdxElementId": "SPDXRef-github-CactuseSecurity-firewall-orchestrator-main-0c7c2b", + "relatedSpdxElement": "SPDXRef-nuget-MimeKit-4.13.0-23ac4f", + "relationshipType": "DEPENDS_ON" + }, + { + "spdxElementId": "SPDXRef-github-CactuseSecurity-firewall-orchestrator-main-0c7c2b", + "relatedSpdxElement": "SPDXRef-nuget-MailKit-4.13.0-b26bfd", + "relationshipType": "DEPENDS_ON" + }, + { + "spdxElementId": "SPDXRef-github-CactuseSecurity-firewall-orchestrator-main-0c7c2b", + "relatedSpdxElement": "SPDXRef-nuget-System.Text.Encodings.Web-9.0.8-7001c6", + "relationshipType": "DEPENDS_ON" + }, + { + "spdxElementId": "SPDXRef-github-CactuseSecurity-firewall-orchestrator-main-0c7c2b", + "relatedSpdxElement": "SPDXRef-nuget-Microsoft.AspNetCore.Http-2.3.0-239946", + "relationshipType": "DEPENDS_ON" + }, + { + "spdxElementId": "SPDXRef-github-CactuseSecurity-firewall-orchestrator-main-0c7c2b", + "relatedSpdxElement": "SPDXRef-githubactions-actions-checkout-4..-75c946", + "relationshipType": "DEPENDS_ON" + }, + { + "spdxElementId": "SPDXRef-github-CactuseSecurity-firewall-orchestrator-main-0c7c2b", + "relatedSpdxElement": "SPDXRef-githubactions-actions-setup-dotnet-4..-75c946", + "relationshipType": "DEPENDS_ON" + }, + { + "spdxElementId": "SPDXRef-github-CactuseSecurity-firewall-orchestrator-main-0c7c2b", + "relatedSpdxElement": "SPDXRef-githubactions-actions-checkout-3-75c946", + "relationshipType": "DEPENDS_ON" + }, + { + "spdxElementId": "SPDXRef-github-CactuseSecurity-firewall-orchestrator-main-0c7c2b", + "relatedSpdxElement": "SPDXRef-githubactions-githubcodeql-action-analyze-2-75c946", + "relationshipType": "DEPENDS_ON" + }, + { + "spdxElementId": "SPDXRef-github-CactuseSecurity-firewall-orchestrator-main-0c7c2b", + "relatedSpdxElement": "SPDXRef-githubactions-githubcodeql-action-autobuild-2-75c946", + "relationshipType": "DEPENDS_ON" + }, + { + "spdxElementId": "SPDXRef-github-CactuseSecurity-firewall-orchestrator-main-0c7c2b", + "relatedSpdxElement": "SPDXRef-githubactions-githubcodeql-action-init-2-75c946", + "relationshipType": "DEPENDS_ON" + }, + { + "spdxElementId": "SPDXRef-github-CactuseSecurity-firewall-orchestrator-main-0c7c2b", + "relatedSpdxElement": "SPDXRef-pypi-gitpython-75c946", + "relationshipType": "DEPENDS_ON" + }, + { + "spdxElementId": "SPDXRef-DOCUMENT", + "relatedSpdxElement": "SPDXRef-github-CactuseSecurity-firewall-orchestrator-main-0c7c2b", + "relationshipType": "DESCRIBES" + } + ] +} diff --git a/documentation/SBOM/readme.md b/documentation/SBOM/readme.md new file mode 100644 index 0000000000..2ec48a5c94 --- /dev/null +++ b/documentation/SBOM/readme.md @@ -0,0 +1,910 @@ +# creating SBOM +we are using cycloneDx + +## standard script + wget https://github.com/CycloneDX/cyclonedx-cli/releases/download/v0.27.2/cyclonedx-linux-x64 + sudo mv cyclonedx-linux-x64 /usr/local/bin/cyclonedx + sudo chmod 755 /usr/local/bin/cyclonedx +## script for C# + dotnet tool install --global CycloneDX + cd fwo-cactus + git pull + dotnet-CycloneDX -j roles/FWO.sln + +## list of python packages with venv (importer module) +### Core runtime + pydantic>=2.0,<3.0 + jsonpickle>=3.0 + python-dateutil>=2.8 + netaddr>=1.0 + +### Crypto (AES/CBC via cryptography.hazmat) + cryptography>=40.0 + +### HTTP / GraphQL stack (Note: Requests >=2.32.0 is compatible with urllib3 2.x) + requests>=2.32.0 + urllib3>=2.0 + graphql-core>=3.0 + +### SSH + scrapli>=2025.01.30 + scrapli-community>=2025.01.30 + +### Test + pytest>=7.0 + +### Linting + ruff==0.15.0 + pre-commit>=3.0 + pyright>=1.1.407 + + +## list of deb packages (debian 12) +acl +adduser +adwaita-icon-theme +alsa-topology-conf +alsa-ucm-conf +analog +ansible +ansible-core +apache2 +apache2-bin +apache2-data +apache2-doc +apache2-utils +apparmor +appstream +apt +apt-listchanges +apt-transport-https +apt-utils +aptitude +aptitude-common +aspnetcore-runtime-10.0 +aspnetcore-targeting-pack-10.0 +at-spi2-common +at-spi2-core +augeas-lenses +autoconf +automake +autopoint +autotools-dev +base-files +base-passwd +bash +bash-completion +bc +bind9-dnsutils +bind9-host +bind9-libs:amd64 +binutils +binutils-common:amd64 +binutils-x86-64-linux-gnu +bsd-mailx +bsdextrautils +bsdutils +build-essential +busybox +bzip2 +ca-certificates +certbot +chrony +console-setup +console-setup-linux +containerd.io +coreutils +cpio +cpp +cpp-12 +cron +cron-daemon-common +curl +dash +dbus +dbus-bin +dbus-daemon +dbus-session-bus-common +dbus-system-bus-common +dbus-user-session +dconf-gsettings-backend:amd64 +dconf-service +dctrl-tools +debconf +debconf-i18n +debhelper +debian-archive-keyring +debian-faq +debian-goodies +debianutils +dh-autoreconf +dh-strip-nondeterminism +dictionaries-common +diffutils +dirmngr +discover +discover-data +distro-info-data +dmidecode +dmsetup +doc-debian +docker-buildx-plugin +docker-ce +docker-ce-cli +docker-ce-rootless-extras +docker-compose-plugin +dotnet-apphost-pack-10.0 +dotnet-host +dotnet-hostfxr-10.0 +dotnet-runtime-10.0 +dotnet-runtime-deps-10.0 +dotnet-sdk-10.0 +dotnet-targeting-pack-10.0 +dpkg +dpkg-dev +dwz +e2fsprogs +eject +elfutils +emacsen-common +equivs +ethtool +exim4-base +exim4-config +exim4-daemon-light +fakeroot +fdisk +file +findutils +firmware-linux-free +fontconfig +fontconfig-config +fonts-dejavu-core +fonts-liberation +fuse3 +g++ +g++-12 +gcc +gcc-12 +gcc-12-base:amd64 +gettext +gettext-base +gir1.2-glib-2.0:amd64 +gir1.2-packagekitglib-1.0 +git +git-man +gnupg +gnupg-l10n +gnupg-utils +gnupg2 +gpg +gpg-agent +gpg-wks-client +gpg-wks-server +gpgconf +gpgsm +gpgv +grep +groff-base +grub-common +grub-pc +grub-pc-bin +grub2-common +gsettings-desktop-schemas +gtk-update-icon-cache +gzip +hicolor-icon-theme +hostname +htop +iamerican +ibritish +ieee-data +ienglish-common +ifupdown +inetutils-telnet +init +init-system-helpers +initramfs-tools +initramfs-tools-core +installation-report +intel-microcode +intltool-debian +iproute2 +iptables +iputils-ping +isc-dhcp-client +isc-dhcp-common +iso-codes +ispell +iucode-tool +javascript-common +kbd +keyboard-configuration +klibc-utils +kmod +krb5-locales +laptop-detect +ldap-utils +less +libabsl20220623:amd64 +libacl1:amd64 +libalgorithm-diff-perl +libalgorithm-diff-xs-perl:amd64 +libalgorithm-merge-perl +libaom3:amd64 +libapache2-mod-wsgi-py3 +libapparmor1:amd64 +libappstream4:amd64 +libapr1:amd64 +libaprutil1:amd64 +libaprutil1-dbd-sqlite3:amd64 +libaprutil1-ldap:amd64 +libapt-pkg6.0:amd64 +libarchive-cpio-perl +libarchive-zip-perl +libargon2-1:amd64 +libasan8:amd64 +libasm1:amd64 +libasound2:amd64 +libasound2-data +libassuan0:amd64 +libatk-bridge2.0-0:amd64 +libatk1.0-0:amd64 +libatomic1:amd64 +libatspi2.0-0:amd64 +libattr1:amd64 +libaudit-common +libaudit1:amd64 +libaugeas0:amd64 +libauthen-sasl-perl +libavahi-client3:amd64 +libavahi-common-data:amd64 +libavahi-common3:amd64 +libavif15:amd64 +libayatana-appindicator3-1 +libayatana-ido3-0.4-0:amd64 +libayatana-indicator3-7:amd64 +libbinutils:amd64 +libbit-vector-perl:amd64 +libblkid1:amd64 +libboost-iostreams1.74.0:amd64 +libbpf1:amd64 +libbrotli1:amd64 +libbsd0:amd64 +libbz2-1.0:amd64 +libc-bin +libc-dev-bin +libc-devtools +libc-l10n +libc6:amd64 +libc6-dev:amd64 +libc6-i386 +libcairo-gobject2:amd64 +libcairo2:amd64 +libcap-ng0:amd64 +libcap2:amd64 +libcap2-bin +libcarp-clan-perl +libcbor0.8:amd64 +libcc1-0:amd64 +libcgi-fast-perl +libcgi-pm-perl +libclone-perl:amd64 +libcolord2:amd64 +libcom-err2:amd64 +libcommon-sense-perl:amd64 +libcrypt-dev:amd64 +libcrypt1:amd64 +libcryptsetup12:amd64 +libctf-nobfd0:amd64 +libctf0:amd64 +libcups2:amd64 +libcurl3-gnutls:amd64 +libcurl4:amd64 +libcwidget4:amd64 +libdata-dump-perl +libdate-calc-perl +libdate-calc-xs-perl:amd64 +libdatrie1:amd64 +libdav1d6:amd64 +libdb5.3:amd64 +libdbd-pg-perl +libdbi-perl:amd64 +libdbus-1-3:amd64 +libdbusmenu-glib4:amd64 +libdbusmenu-gtk3-4:amd64 +libdconf1:amd64 +libde265-0:amd64 +libdebconfclient0:amd64 +libdebhelper-perl +libdeflate0:amd64 +libdevmapper1.02.1:amd64 +libdiscover2 +libdpkg-perl +libdrm-amdgpu1:amd64 +libdrm-common +libdrm-intel1:amd64 +libdrm-nouveau2:amd64 +libdrm-radeon1:amd64 +libdrm2:amd64 +libduktape207:amd64 +libdw1:amd64 +libedit2:amd64 +libefiboot1:amd64 +libefivar1:amd64 +libegl-mesa0:amd64 +libegl1:amd64 +libelf1:amd64 +libencode-locale-perl +libepoxy0:amd64 +liberror-perl +libestr0:amd64 +libevent-2.1-7:amd64 +libexif12:amd64 +libexpat1:amd64 +libexpat1-dev:amd64 +libexpect-perl +libext2fs2:amd64 +libfakeroot:amd64 +libfastjson4:amd64 +libfcgi-bin +libfcgi-perl +libfcgi0ldbl:amd64 +libfdisk1:amd64 +libffi8:amd64 +libfido2-1:amd64 +libfile-basedir-perl +libfile-desktopentry-perl +libfile-fcntllock-perl +libfile-listing-perl +libfile-mimeinfo-perl +libfile-slurper-perl +libfile-stripnondeterminism-perl +libfile-which-perl +libfont-afm-perl +libfontconfig1:amd64 +libfontenc1:amd64 +libfreetype6:amd64 +libfribidi0:amd64 +libfstrm0:amd64 +libfuse2:amd64 +libfuse3-3:amd64 +libgav1-1:amd64 +libgbm1:amd64 +libgcc-12-dev:amd64 +libgcc-s1:amd64 +libgcrypt20:amd64 +libgd3:amd64 +libgdbm-compat4:amd64 +libgdbm6:amd64 +libgdiplus +libgdk-pixbuf-2.0-0:amd64 +libgdk-pixbuf2.0-bin +libgdk-pixbuf2.0-common +libgif7:amd64 +libgirepository-1.0-1:amd64 +libgl1:amd64 +libgl1-mesa-dri:amd64 +libglapi-mesa:amd64 +libgles2:amd64 +libglib2.0-0:amd64 +libglib2.0-bin +libglib2.0-data +libglvnd0:amd64 +libglx-mesa0:amd64 +libglx0:amd64 +libgmp10:amd64 +libgnutls-dane0:amd64 +libgnutls30:amd64 +libgomp1:amd64 +libgpg-error0:amd64 +libgprofng0:amd64 +libgraphite2-3:amd64 +libgssapi-krb5-2:amd64 +libgstreamer1.0-0:amd64 +libgtk-3-0:amd64 +libgtk-3-bin +libgtk-3-common +libharfbuzz0b:amd64 +libheif1:amd64 +libhogweed6:amd64 +libhtml-form-perl +libhtml-format-perl +libhtml-parser-perl:amd64 +libhtml-tagset-perl +libhtml-tree-perl +libhttp-cookies-perl +libhttp-daemon-perl +libhttp-date-perl +libhttp-message-perl +libhttp-negotiate-perl +libice6:amd64 +libicu72:amd64 +libidn12:amd64 +libidn2-0:amd64 +libintl-perl +libintl-xs-perl +libio-html-perl +libio-pty-perl +libio-socket-ssl-perl +libio-stringy-perl +libio-stty-perl +libip4tc2:amd64 +libip6tc2:amd64 +libipc-system-simple-perl +libisl23:amd64 +libitm1:amd64 +libjansson4:amd64 +libjbig0:amd64 +libjemalloc2:amd64 +libjpeg62-turbo:amd64 +libjs-jquery +libjs-sphinxdoc +libjs-underscore +libjson-c5:amd64 +libjson-perl +libjson-xs-perl +libk5crypto3:amd64 +libkeyutils1:amd64 +libklibc:amd64 +libkmod2:amd64 +libkrb5-3:amd64 +libkrb5support0:amd64 +libksba8:amd64 +liblcms2-2:amd64 +libldap-2.5-0:amd64 +libldap-common +libldap-dev:amd64 +libldap2-dev +liblerc4:amd64 +libllvm14:amd64 +libllvm15:amd64 +liblmdb0:amd64 +liblocale-gettext-perl +liblockfile-bin +liblockfile1:amd64 +liblognorm5:amd64 +liblsan0:amd64 +libltdl-dev:amd64 +libltdl7:amd64 +liblua5.3-0:amd64 +liblwp-mediatypes-perl +liblwp-protocol-https-perl +liblz4-1:amd64 +liblzma5:amd64 +libmagic-mgc +libmagic1:amd64 +libmail-sendmail-perl +libmailtools-perl +libmaxminddb0:amd64 +libmd0:amd64 +libmnl0:amd64 +libmodbus5:amd64 +libmodule-find-perl +libmount1:amd64 +libmpc3:amd64 +libmpfr6:amd64 +libmspack0:amd64 +libncursesw6:amd64 +libnet-cidr-perl +libnet-dbus-perl +libnet-http-perl +libnet-smtp-ssl-perl +libnet-ssleay-perl:amd64 +libnetfilter-conntrack3:amd64 +libnettle8:amd64 +libnewt0.52:amd64 +libnfnetlink0:amd64 +libnftables1:amd64 +libnftnl11:amd64 +libnghttp2-14:amd64 +libnl-3-200:amd64 +libnl-genl-3-200:amd64 +libnpth0:amd64 +libnsl-dev:amd64 +libnsl2:amd64 +libnspr4:amd64 +libnss-systemd:amd64 +libnss3:amd64 +libnuma1:amd64 +libodbc2:amd64 +libp11-kit0:amd64 +libpackagekit-glib2-18:amd64 +libpam-modules:amd64 +libpam-modules-bin +libpam-runtime +libpam-systemd:amd64 +libpam0g:amd64 +libpango-1.0-0:amd64 +libpangocairo-1.0-0:amd64 +libpangoft2-1.0-0:amd64 +libpcap0.8:amd64 +libpci3:amd64 +libpciaccess0:amd64 +libpcre2-8-0:amd64 +libperl5.36:amd64 +libperlio-utf8-strict-perl +libpipeline1:amd64 +libpixman-1-0:amd64 +libpng16-16:amd64 +libpolkit-agent-1-0:amd64 +libpolkit-gobject-1-0:amd64 +libpopt0:amd64 +libpq-dev +libpq5:amd64 +libproc-processtable-perl:amd64 +libproc2-0:amd64 +libprotobuf-c1:amd64 +libpsl5:amd64 +libpython3-dev:amd64 +libpython3-stdlib:amd64 +libpython3.11:amd64 +libpython3.11-dev:amd64 +libpython3.11-minimal:amd64 +libpython3.11-stdlib:amd64 +libquadmath0:amd64 +librav1e0:amd64 +libreadline8:amd64 +libregexp-ipv6-perl +librsvg2-2:amd64 +librsvg2-common:amd64 +librtmp1:amd64 +libsasl2-2:amd64 +libsasl2-dev +libsasl2-modules:amd64 +libsasl2-modules-db:amd64 +libseccomp2:amd64 +libselinux1:amd64 +libsemanage-common +libsemanage2:amd64 +libsensors-config +libsensors5:amd64 +libsepol2:amd64 +libsigc++-2.0-0v5:amd64 +libslang2:amd64 +libslirp0:amd64 +libsm6:amd64 +libsmartcols1:amd64 +libsnmp-base +libsort-naturally-perl +libsqlite3-0:amd64 +libss2:amd64 +libssh2-1:amd64 +libssl-dev:amd64 +libssl3:amd64 +libstdc++-12-dev:amd64 +libstdc++6:amd64 +libstemmer0d:amd64 +libsub-override-perl +libsvtav1enc1:amd64 +libsys-hostname-long-perl +libsystemd-shared:amd64 +libsystemd0:amd64 +libtasn1-6:amd64 +libterm-readkey-perl +libtext-charwidth-perl:amd64 +libtext-iconv-perl:amd64 +libtext-wrapi18n-perl +libthai-data +libthai0:amd64 +libtie-ixhash-perl +libtiff6:amd64 +libtimedate-perl +libtinfo6:amd64 +libtirpc-common +libtirpc-dev:amd64 +libtirpc3:amd64 +libtool +libtry-tiny-perl +libtsan2:amd64 +libtypes-serialiser-perl +libubsan1:amd64 +libuchardet0:amd64 +libudev1:amd64 +libunbound8:amd64 +libunistring2:amd64 +libunwind8:amd64 +liburi-perl +libusb-1.0-0:amd64 +libuuid1:amd64 +libuv1:amd64 +libwebp7:amd64 +libwrap0:amd64 +libwww-perl +libwww-robotrules-perl +libx265-199:amd64 +libxapian30:amd64 +libxau6:amd64 +libxaw7:amd64 +libxcb-dri2-0:amd64 +libxcb-dri3-0:amd64 +libxcb-glx0:amd64 +libxcb-present0:amd64 +libxcb-randr0:amd64 +libxcb-render0:amd64 +libxcb-shape0:amd64 +libxcb-shm0:amd64 +libxcb-sync1:amd64 +libxcb-xfixes0:amd64 +libxcb1:amd64 +libxcomposite1:amd64 +libxcursor1:amd64 +libxdamage1:amd64 +libxdmcp6:amd64 +libxext6:amd64 +libxfixes3:amd64 +libxft2:amd64 +libxi6:amd64 +libxinerama1:amd64 +libxkbcommon0:amd64 +libxkbfile1:amd64 +libxml-parser-perl +libxml-twig-perl +libxml-xpathengine-perl +libxml2:amd64 +libxmlb2:amd64 +libxmlsec1:amd64 +libxmlsec1-openssl:amd64 +libxmu6:amd64 +libxmuu1:amd64 +libxpm4:amd64 +libxrandr2:amd64 +libxrender1:amd64 +libxshmfence1:amd64 +libxslt1.1:amd64 +libxt6:amd64 +libxtables12:amd64 +libxtst6:amd64 +libxv1:amd64 +libxxf86dga1:amd64 +libxxf86vm1:amd64 +libxxhash0:amd64 +libyaml-0-2:amd64 +libyuv0:amd64 +libz3-4:amd64 +libzstd1:amd64 +linux-base +linux-image-6.1.0-42-amd64 +linux-image-amd64 +linux-libc-dev:amd64 +locales +login +logrotate +logsave +lsb-release +lsof +lynx +lynx-common +m4 +mailcap +make +man-db +manpages +manpages-dev +mawk +media-types +mime-support +mount +nano +ncurses-base +ncurses-bin +ncurses-term +needrestart +net-tools +netbase +netcat-traditional +nftables +open-vm-tools +openssh-client +openssh-server +openssh-sftp-server +openssl +os-prober +packagekit +packagekit-tools +packages-microsoft-prod +passwd +patch +pci.ids +pciutils +perl +perl-base +perl-modules-5.36 +perl-openssl-defaults:amd64 +pigz +pinentry-curses +pkexec +po-debconf +policykit-1 +polkitd +polkitd-pkla +popularity-contest +postgresql +postgresql-15 +postgresql-client +postgresql-client-15 +postgresql-client-common +postgresql-common +procps +psmisc +publicsuffix +python-apt-common +python-babel-localedata +python3 +python3-acme +python3-anyio +python3-apt +python3-argcomplete +python3-asgiref +python3-augeas +python3-babel +python3-blinker +python3-certbot +python3-certbot-apache +python3-certifi +python3-cffi-backend:amd64 +python3-chardet +python3-charset-normalizer +python3-click +python3-colorama +python3-configargparse +python3-configobj +python3-cryptography +python3-dbus +python3-debconf +python3-debian +python3-debianbts +python3-dev +python3-distlib +python3-distro +python3-distutils +python3-dnspython +python3-docker +python3-dotenv +python3-filelock +python3-flask +python3-gi +python3-git +python3-gitdb +python3-gnupg +python3-h11 +python3-h2 +python3-hpack +python3-httpcore +python3-httplib2 +python3-httpx +python3-hyperframe +python3-icu +python3-idna +python3-itsdangerous +python3-jinja2 +python3-jmespath +python3-josepy +python3-jsonpickle +python3-jwt +python3-kerberos +python3-lazr.restfulclient +python3-lazr.uri +python3-ldap +python3-lib2to3 +python3-libcloud +python3-lockfile +python3-markdown-it +python3-markupsafe +python3-mdurl +python3-minimal +python3-netaddr +python3-ntlm-auth +python3-oauthlib +python3-openssl +python3-packaging +python3-parsedatetime +python3-passlib +python3-pip +python3-pip-whl +python3-pkg-resources +python3-platformdirs +python3-psycopg2 +python3-pyasn1 +python3-pyasn1-modules +python3-pycurl +python3-pygments +python3-pyinotify +python3-pyldap +python3-pyparsing +python3-pysimplesoap +python3-reportbug +python3-requests +python3-requests-kerberos +python3-requests-ntlm +python3-requests-toolbelt +python3-resolvelib +python3-rfc3339 +python3-rfc3986 +python3-rich +python3-selinux +python3-setuptools +python3-setuptools-whl +python3-simplejson +python3-six +python3-smmap +python3-sniffio +python3-software-properties +python3-tz +python3-urllib3 +python3-venv +python3-virtualenv +python3-wadllib +python3-websocket +python3-werkzeug +python3-wheel +python3-wheel-whl +python3-winrm +python3-xmltodict +python3-yaml +python3.11 +python3.11-dev +python3.11-minimal +python3.11-venv +readline-common +reportbug +rpcsvc-proto +rsync +rsyslog +runit-helper +sed +sensible-utils +sgml-base +shared-mime-info +slapd +slirp4netns +software-properties-common +ssl-cert +sudo +syslog-ng-core +sysstat +systemd +systemd-sysv +systemd-timesyncd +sysvinit-utils +tar +task-english +task-ssh-server +task-web-server +tasksel +tasksel-data +tcpdump +traceroute +tzdata +ucf +udev +unzip +usbutils +usr-is-merged +util-linux +util-linux-extra +util-linux-locales +vim-common +vim-tiny +wamerican +wget +whiptail +wkhtmltox +x11-common +x11-utils +x11-xserver-utils +xauth +xdg-user-dirs +xdg-utils +xfonts-75dpi +xfonts-base +xfonts-encodings +xfonts-utils +xkb-data +xml-core +xz-utils +zerofree +zlib1g:amd64 +zlib1g-dev:amd64 +zstd +zutty diff --git a/documentation/auth/rbac.md b/documentation/auth/rbac.md index b0d8774693..b09d975ad8 100644 --- a/documentation/auth/rbac.md +++ b/documentation/auth/rbac.md @@ -18,6 +18,7 @@ The following roles are defined in ascending order of permissions: - importer - users can import config changes into the database - dbbackup - users that are able to read data tables for backup purposes - auditor - users that can view all data & settings (in the UI) but cannot make any changes +- modeller - users who can model applications - recertifier - users who can re-certify or de-certify firewall rules - fw-admin - users who can document open changes - requester - users that have the right to create requests diff --git a/documentation/certificates.md b/documentation/certificates.md new file mode 100644 index 0000000000..a5d9a5c5ee --- /dev/null +++ b/documentation/certificates.md @@ -0,0 +1,28 @@ +# Certificates in FWO + +The expected paths for keys and certificates are /etc/apache2/ssl/server.key and /etc/apache2/ssl/server.crt respectivly. If you want to change them, use these names and paths. Make sure server.key has these permissions + +``` +-rw-r----- 1 root root +``` + +After the change restart apache2 + +``` + sudo systemctl restart apache2 +``` + + +## Change Roor Certificate + +Copy root cert to + +``` +/usr/local/share/ca-certificates/ +``` + +and update + +``` +sudo update-ca-certificates +``` diff --git a/documentation/developer-docs/README.MD b/documentation/developer-docs/README.MD index a70d96d657..5d91b26572 100644 --- a/documentation/developer-docs/README.MD +++ b/documentation/developer-docs/README.MD @@ -9,9 +9,6 @@ ## Misc -### UI - -[Open Iconic Icons](https://useiconic.com/open) ### importer diff --git a/documentation/developer-docs/UI/csharp/data-filtering.md b/documentation/developer-docs/UI/csharp/data-filtering.md index 3739195f7d..a2dac0c351 100644 --- a/documentation/developer-docs/UI/csharp/data-filtering.md +++ b/documentation/developer-docs/UI/csharp/data-filtering.md @@ -5,7 +5,7 @@ first version: ```csharp $"{rule.DeviceName} - Rule {rule.Id} {rule.Name}") + NameExtractor=@(rule => $"{rule.RulebaseName} - Rule {rule.Id} {rule.Name}") NetworkObjectExtractor="rule => Array.ConvertAll(rule.Froms.Concat(rule.Tos).GroupBy(x => x.Object?.Id).Select(x => x.FirstOrDefault()).ToArray(), location => location.Object)" NetworkServiceExtractor="rule => Array.ConvertAll(rule.Services, wrapper => wrapper.Content)" NetworkUserExtractor="rule => Array.FindAll(Array.ConvertAll(rule.Froms.Concat(rule.Tos).GroupBy(x => x.User?.Id).Select(x => x.FirstOrDefault()).ToArray(), location => location.User), user => user != null)" /> diff --git a/documentation/developer-docs/UI/icons/README.md b/documentation/developer-docs/UI/icons/README.md new file mode 100644 index 0000000000..252bca8416 --- /dev/null +++ b/documentation/developer-docs/UI/icons/README.md @@ -0,0 +1,10 @@ +### Icons + +The icons used in this project are from [Bootstrap Icons](https://icons.getbootstrap.com) under the [MIT License](https://github.com/twbs/icons/blob/main/LICENSE). We are using version 1.13.1 (as of 29.09.2025). + +##### Updating + +To update the Bootstrap Icons version, follow these steps: +1. Download the latest release from the [Bootstrap Icons GitHub Releases](https://github.com/twbs/icons/releases). +2. Replace the contents of `roles/ui/files/FWO.UI/wwwroot/css/bootstrap-icons` with the new files from the downloaded release (only the fonts folder and the `bootstrap-icons.css` file). +3. Update the version number in this documentation file to reflect the new version. \ No newline at end of file diff --git a/documentation/developer-docs/api/api_handling_documentation.md b/documentation/developer-docs/api/api_handling_documentation.md index 33513a7073..9163d54ba0 100644 --- a/documentation/developer-docs/api/api_handling_documentation.md +++ b/documentation/developer-docs/api/api_handling_documentation.md @@ -42,32 +42,11 @@ tim@fworch-comp:~$ sudo systemctl status fworch-* Tasks: 1 (limit: 4637) Memory: 16.8M CGroup: /system.slice/fworch-importer-api.service - └─341171 /usr/bin/python3 /usr/local/fworch/importer/import-main-loop.py + └─341171 /usr/bin/python3 /usr/local/fworch/importer/import_main_loop.py Dez 09 20:07:18 fworch-comp systemd[1]: Starting fworch importer pure python... Dez 09 20:07:28 fworch-comp systemd[1]: Started fworch importer pure python. -● fworch-importer.service - fworch importer - Loaded: loaded (/lib/systemd/system/fworch-importer.service; enabled; vendor preset: enabled) - Active: active (running) since Thu 2021-12-09 20:08:24 CET; 14h ago - Process: 342644 ExecStartPre=/bin/sleep 10 (code=exited, status=0/SUCCESS) - Main PID: 342651 (fworch-importer) - Tasks: 1 (limit: 4637) - Memory: 13.9M - CGroup: /system.slice/fworch-importer.service - └─342651 /usr/bin/perl -w /usr/local/fworch/importer/fworch-importer-main.pl - -Dez 10 10:45:54 fworch-comp fworch-importer[396236]: version: R5x-R7x, manufacturer: check point, current_import_id=1897 -Dez 10 10:45:55 fworch-comp fworch-import[396236]: Management checkpoint_demo (mgm_id=2), no changes in configuration files (MD5) -Dez 10 10:45:55 fworch-comp fworch-importer[396236]: Management checkpoint_demo (mgm_id=2), no changes in configuration files (MD5) -Dez 10 10:45:55 fworch-comp fworch-import[342651]: Import: looking at fortigate_demo ... -Dez 10 10:45:55 fworch-comp fworch-import[342651]: Import: running on responsible importer fworch-comp ... -Dez 10 10:45:55 fworch-comp fworch-importer[342651]: Import: looking at fortigate_demo ... Import: running on responsible importer fworch-comp ... -Dez 10 10:45:55 fworch-comp fworch-importer[396481]: version: 5.x-6.x, manufacturer: fortinet, current_import_id=1898 -Dez 10 10:45:56 fworch-comp fworch-import[396481]: Management fortigate_demo (mgm_id=1), no changes in configuration files (MD5) -Dez 10 10:45:56 fworch-comp fworch-importer[396481]: Management fortigate_demo (mgm_id=1), no changes in configuration files (MD5) -Dez 10 10:45:56 fworch-comp fworch-import[342651]: -------- Import module: going back to sleep for 40 seconds -------- - ● fworch-middleware.service - FWOrch Middleware Server Loaded: loaded (/lib/systemd/system/fworch-middleware.service; enabled; vendor preset: enabled) Active: active (running) since Fri 2021-12-10 10:45:59 CET; 3s ago @@ -76,11 +55,11 @@ Dez 10 10:45:56 fworch-comp fworch-import[342651]: -------- Import module: going Tasks: 19 (limit: 4637) Memory: 35.2M CGroup: /system.slice/fworch-middleware.service - └─396568 /usr/local/fworch/middleware/files/FWO.Middleware.Server/bin/Release/net6.0/FWO.Middleware.Server + └─396568 /usr/local/fworch/middleware/files/FWO.Middleware.Server/bin/Release/net10.0/FWO.Middleware.Server Dez 10 10:45:59 fworch-comp fworch.middleware-server[396568]: Info - Jwt generation (JwtWriter.cs in line 87): Generated JWT eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1bmlxdWVfbmFtZSI6Im1pZGRsZXdhcmU> Dez 10 10:45:59 fworch-comp fworch.middleware-server[396568]: Info - Found ldap connection to server (Program.cs in line 32): 127.0.0.1:636 Dez 10 10:45:59 fworch-comp fworch.middleware-server[396568]: info: Microsoft.Hosting.Lifetime[14] Dez 10 10:45:59 fworch-comp fworch.middleware-server[396568]: Now listening on: http://127.0.0.1:8880 tim@fworch-comp:~$ -``` \ No newline at end of file +``` diff --git a/documentation/developer-docs/count-lines-of-code.md b/documentation/developer-docs/count-lines-of-code.md deleted file mode 100644 index 8b16375d0a..0000000000 --- a/documentation/developer-docs/count-lines-of-code.md +++ /dev/null @@ -1,93 +0,0 @@ -``` -sudo apt install cloc -cat cloc-fwo.sh - #!/usr/bin/env bash - git clone --depth 1 "$1" temp-linecount-repo && printf "('temp-linecount-repo' will be deleted automatically)\n\n\n" && cloc temp-linecount-repo --exclude-ext=C && rm -rf temp-linecount-repo - -chmod 755 cloc-fwo.sh -date - Wed Dec 9 18:22:59 UTC 2020 - -./cloc-fwo.sh ssh://git@github.com/tpurschke/firewall-orchestrator.git - Cloning into 'temp-linecount-repo'... - remote: Enumerating objects: 872, done. - remote: Counting objects: 100% (872/872), done. - remote: Compressing objects: 100% (785/785), done. - remote: Total 872 (delta 120), reused 381 (delta 42), pack-reused 0 - Receiving objects: 100% (872/872), 2.65 MiB | 1.24 MiB/s, done. - Resolving deltas: 100% (120/120), done. - ('temp-linecount-repo' will be deleted automatically) - - - 630 text files. - 621 unique files. - 112 files ignored. - - github.com/AlDanial/cloc v 1.74 T=1.41 s (371.3 files/s, 61839.1 lines/s) - ------------------------------------------------------------------------------- - Language files blank comment code - ------------------------------------------------------------------------------- - C++ 1 0 0 25894 - PHP 95 615 810 12728 - Perl 15 1054 1927 10315 - SQL 31 530 2286 7445 - YAML 71 584 348 5689 - C# 98 914 460 5026 - Markdown 72 879 0 2665 - Python 16 330 274 2008 - GraphQL 67 66 113 1867 - Bourne Shell 17 66 82 557 - JavaScript 4 71 57 330 - CSS 6 54 30 260 - JSON 9 1 0 193 - MSBuild script 14 49 0 180 - Razor 3 10 0 123 - HTML 1 2 0 29 - ANTLR Grammar 1 0 1 4 - XML 1 0 0 1 - ------------------------------------------------------------------------------- - SUM: 522 5225 6388 75314 - ------------------------------------------------------------------------------- -tim@acantha:~/dev/tmp$ date -Wed 30 Jun 2021 05:11:49 PM CEST -tim@acantha:~/dev/tmp$ cloc-fwo.sh https://github.com/CactuseSecurity/firewall-orchestrator.git -Cloning into 'temp-linecount-repo'... -remote: Enumerating objects: 904, done. -remote: Counting objects: 100% (904/904), done. -remote: Compressing objects: 100% (820/820), done. -remote: Total 904 (delta 125), reused 428 (delta 40), pack-reused 0 -Receiving objects: 100% (904/904), 1.98 MiB | 8.10 MiB/s, done. -Resolving deltas: 100% (125/125), done. -('temp-linecount-repo' will be deleted automatically) - - - 738 text files. - 716 unique files. - 161 files ignored. - -github.com/AlDanial/cloc v 1.82 T=0.28 s (2080.3 files/s, 208752.4 lines/s) -------------------------------------------------------------------------------- -Language files blank comment code -------------------------------------------------------------------------------- -Perl 14 1012 1827 10110 -YAML 82 676 336 8913 -SQL 62 703 2568 8651 -C# 124 1467 757 8255 -Markdown 99 1180 0 3694 -GraphQL 97 74 132 2586 -Python 18 298 211 1752 -Razor 41 58 6 1164 -Bourne Shell 17 63 81 541 -SVG 1 0 3 540 -JSON 8 3 0 252 -CSS 4 27 11 152 -MSBuild script 10 31 0 127 -HTML 1 2 0 29 -ANTLR Grammar 1 0 1 4 -JavaScript 1 0 0 3 -XML 1 0 0 1 -------------------------------------------------------------------------------- -SUM: 581 5594 5933 46774 -------------------------------------------------------------------------------- -tim@acantha:~/dev/tmp$ -``` diff --git a/documentation/developer-docs/csharp/blazor/blazorTable/README.md b/documentation/developer-docs/csharp/blazor/blazorTable/README.md index c1bde0e1ae..53aae6b837 100644 --- a/documentation/developer-docs/csharp/blazor/blazorTable/README.md +++ b/documentation/developer-docs/csharp/blazor/blazorTable/README.md @@ -1,2 +1,8 @@ - [Github Site](https://github.com/IvanJosipovic/BlazorTable) - [Feature Site](https://blazortable.netlify.app/) +- adding a project to the solution + + tim@acantha22:~/dev/firewall-orchestrator/roles$ dotnet sln FWO.sln add lib/files/FWO.Encryption/FWO.Encryption.csproj + Project `lib/files/FWO.Encryption/FWO.Encryption.csproj` added to the solution. + tim@acantha22:~/dev/firewall-orchestrator/roles$ + \ No newline at end of file diff --git a/documentation/developer-docs/csharp/wkhtmltopdf.md b/documentation/developer-docs/csharp/wkhtmltopdf.md deleted file mode 100644 index 6c473b7070..0000000000 --- a/documentation/developer-docs/csharp/wkhtmltopdf.md +++ /dev/null @@ -1,14 +0,0 @@ -To test if you meet all dependencies for this package, follow the following instructions: - -1. Download the approriate deb package for wkhtmltopdf from https://wkhtmltopdf.org/downloads.html -2. Install the package with - - sudo dpkg -i xxx.deb - -3. Have a look at the missing dependencies and add these packages to the respective installation scripts - - roles/lib/tasks/main.yml - - roles/middleware/tasks/main.yml - - roles/ui/tasks/main.yml - -Note that under Ubuntu 22.04 the latest wkhtml package needs to be installed (not the one coming with the OS). - \ No newline at end of file diff --git a/documentation/developer-docs/database/readme.md b/documentation/developer-docs/database/readme.md index bb785e7632..c365ea95b9 100644 --- a/documentation/developer-docs/database/readme.md +++ b/documentation/developer-docs/database/readme.md @@ -78,11 +78,7 @@ All the following tables belong to the "public" schema which is not explicitly l ## Processes involving DB access ### Import -#### Legacy import -There are still some import modules (e.g. for Barracuda, Juniper) written in perl which -connect to the firewall systems via ssh and write the normalized data directly to the database without using the API. -#### API Import The standard way to import data from firewalls is via their respective (REST) API. The FWORCH import module normalizes the data and passes it to the FWORCH (GraphQL) API. diff --git a/documentation/developer-docs/git-howto.md b/documentation/developer-docs/git-howto.md index 1800af57af..fcd4dcd0fb 100644 --- a/documentation/developer-docs/git-howto.md +++ b/documentation/developer-docs/git-howto.md @@ -116,3 +116,117 @@ How to merge fork tpurschke/master into CactuseSecurity/master 5. push new branch to fork git push -u origin auth_frontend + +## Submodules + +### Automatic submodule sync via repo hooks +Enable the repo-managed hooks once (per clone) to keep submodules up to date automatically: +```shell +git config core.hooksPath .githooks +``` +The hooks run after `git pull`, `git checkout`, and `git rebase` and initialize and update the submodules. +Notes: +- The hook is quiet if you do not have access to a submodule repository (no error output). +- The hook checks out the configured submodule branch from `.gitmodules` before updating, to avoid detached HEAD. +- This intentionally moves submodules to the newest commit on their configured branch, even if the superproject has not updated the pointer yet. Expect the submodule to appear "modified" in `git status`, unless you follow the next subsections advice. + +### Avoid Advancing the Submodule Pointer +On the upstream we automatically advance the submodule pointer via automated pull requests. +To prevent merge conflicts and unintended divergence from upstream, **do not commit or push local changes that advance the submodule reference (commit pointer)** in this repository. This might happen if you directly commit or stage all files. It should not happen if you use explicit staging of your files in vscode. + +To automatically ignore local submodule pointer changes, run: +```shell +git config submodule.agents.ignore all +``` + +### Trigger hook +In order to initially trigger the hook which does the initialisation, we need to do any of the operations (git checkout, git merge, git rewrite) + +Here we do a simple checkout of another branch (assuming you are on main branch) + + git checkout develop + +Now you should see the submodule in your IDE. + +### Manual submodule operations (not necessary when using .githooks) +If you like to manually execute the submodule setup, see the sections below. Otherwise, please refer to the sections above. + +#### Initial update (not necessary when using .githooks) +Update submodules to the commits recorded in the superproject (safe, reproducible). Initializes them if necessary. +Execute this command after the initial clone of the fwo repo in the fwo repo root directory: +```shell +git submodule update --init --recursive +``` + +#### Update agents repo manually (not necessary when using .githooks) +This updates the agents repo manually. Update submodules to the latest commit on their configured remote tracking branch. Execute this command to get the newest version of all submodules from their respective repositories. +```shell +git -C .agents checkout main +git submodule update --remote --merge --recursive +``` + +### Check correct file state +```shell +tim@acantha24:~/dev/tim/fwo$ git ls-tree HEAD .agents +160000 commit 73cfbb4efad58dd569c0c0ab4d7ecebc63d23ddd .agents +tim@acantha24:~/dev/tim/fwo$ git ls-tree HEAD AGENTS.md +120000 blob 95e38a6a9ddf012aae10a06a19b6d8c1a65ec8b8 AGENTS.md +tim@acantha24:~/dev/tim/fwo$ +``` +Notes: +- 160000 - sub module +- 120000 - symbolic link +## Troubleshooting: pre-commit Python / Ruff / Pyright + +If `git commit` fails with messages like: + +```text +Warning: No virtual environment found. Assuming python (with ruff and pyright) is available in base environment. +Error: 'python -m ruff' is not available. Please install ruff in the active environment. +``` + +### 1. What was the error? + +The repository-managed pre-commit hook (`.githooks/pre-commit`) failed before creating the commit. +The hook requires `python`, `ruff`, and `pyright` to be available in the active environment. + +### 2. Why does it occur? + +This typically happens when: + +- no local `.venv` is present or active, and no conda env is active, +- `python` points to a different interpreter than expected, +- required tooling is missing from the active interpreter, +- project Python dependencies are not installed yet. + +In this repo, `core.hooksPath` is set to `.githooks`, so these checks run automatically on commit. + +### 3. Suggested changes + +Recommended setup (repo root): + +```powershell +python -m venv .venv +.\.venv\Scripts\Activate.ps1 +python -m pip install -U pip +python -m pip install -r roles\importer\files\importer\requirements.txt -r scripts\customizing\app_data_import\requirements-for-app-data-import.txt +``` + +Optional validation: + +```powershell +python -m ruff --version +python -m pyright --version +``` + +Then retry commit. + +Notes: + +- `ruff` is pinned in this repo (`ruff==0.15.0`). + +Temporary bypass only if absolutely necessary: + +```powershell +git commit --no-verify +``` diff --git a/documentation/developer-docs/importer/FWO-import-api.md b/documentation/developer-docs/importer/FWO-import-api.md deleted file mode 100644 index 31fdf307a1..0000000000 --- a/documentation/developer-docs/importer/FWO-import-api.md +++ /dev/null @@ -1,542 +0,0 @@ -# Importing firewall configs via API - -## JSON structure overview - -### Config in table import_config -```json -{ - "import_id": 1, - "mgm_id": 12, - "config": "config2import" -} -``` -### config2import -```json -{ - "network_objects": [...], - "service_objects": [...], - "user_objects": [...], - "zone_objects": [...], - "rules": [...], - "routing": [], - "interfaces": [] -} -``` - -## Explanations -- In the following, all fields that are null, are optional. -- Note that you need some of them depending on the object type (e.g. group needs members). -- The control_id needs to be present in every single object for technical postgresql reasons. -- group delimiter is the pipe ("|") -- _refs fields contain a string with the uids of the referenced objects separated by "|" -- the order of fields is arbitrary -- _color can be any one listed in roles/database/files/csv/color.csv -- action and track types can be found (and enhanced) in roles/database/files/sql/creation/fworch-fill-stm.sql - -## network_objects - -here we describe a single network object: -```json -{ - "control_id": 1, // bigint: ID of the current import - "obj_ip": "1.5.1.1", // string: ipv4 or v6 address (in CIDR format) - "obj_typ": "host", // string: see types below - "obj_uid": "8a5bc8fb-8a10-4fd2-b4b7-825ee57bd6bd", // string: with unique network object id - "obj_name": "host112", // string: name of network object - "obj_color": null, // string: color of object, see Explanations - "obj_ip_end": "1.5.1.1", // string: last ipv4 or v6 address (for ranges) - "obj_comment": null, // string: comment - "obj_member_names": null, // string: names of the group members separated by "|" - "obj_member_refs": null, // string: uids of the referenced objects separated by "|" - "obj_zone": null // string: name of the object's zone (e.g. for fortinet) -} -``` -- obj_typ can be any of the following (see roles/database/files/sql/creation/fworch-fill-stm.sql): - network, group, host, machines_range, dynamic_net_obj, sofaware_profiles_security_level, gateway, cluster_member, gateway_cluster, domain, group_with_exclusion, ip_range, uas_collection, sofaware_gateway, voip_gk, gsn_handover_group, voip_sip, simple-gateway - - -## service_objects -here we describe a single service object: - -```json -{ - "control_id": 1, // bigint: ID of the current import - "svc_name": "AOL", // string: name of the service - "svc_typ": "simple", // string: type of service (see below) - "svc_uid": "97aeb44f-9aea-11d5-bd16-0090272ccb30", // string: unique service id - "ip_proto": "6", // integer: 0-255 procol number - "svc_port": "5190", // string: 1-65535 (or range) - "svc_timeout": null, // integer: idle timeout in seconds - "svc_port_end": null, // string: to be replaced by range in svc_port - "svc_source_port": null, // string: optional source port restrictions - "svc_source_port_end": null, // string: to be replaced by range in svc_source_port - "svc_color": null, // string: color of object, see Explanations - "svc_comment": null, // string: comment - "svc_member_names": null, // string: names of the group members separated by "|" - "svc_member_refs": null, // string: uids of the referenced service objects separated by "|" - "rpc_nr": null // string: for rpc service the rpc id -}, -``` -- svc_type can be any of the following: simple, group, rpc (see roles/database/files/sql/creation/fworch-fill-stm.sql) - -## user_objects - -here we describe a single user object: - -```json -{ - "control_id": 1, // bigint: ID of the current import - "user_typ": "simple", // string: either "group" or "simple" - "user_uid": "c4d28191-bd44-4d45-8887-df94f594a8ef", // string: unique user id - "user_name": "IA_User1", // string: user name - "user_member_names": null, // string: names of the group members separated by "|" - "user_member_refs": null, // string: uids of the referenced users separated by "|" - "user_color": null, // string: color of object, see Explanations - "user_comment": null, // string: comment - "user_valid_until": null // string: user's "sell-by" date -} -``` - -## zone_objects - -here we describe a single zone object: - -```json -{ - "control_id": 1, // bigint: ID of the current import - "zone_name": "zone1" // string: name of the zone -} -``` - -## rules - -here we describe a single rule: - -```json -{ - "control_id": 1, // bigint: ID of the current import - "rulebase_name": "FirstLayer shared with inline layer", // string: specifies the rulebase name (all rules are contained in a single json struct) - "rule_num": 1, // integer: rule number for ordering - "rule_uid": "acc044f6-2a4f-459b-b78c-9e7afee92621", // string: unique rule id - "rule_src": "user1@obj1|obj2", // string: list of source object names (if it contains user, use "@" as delimiter) - "rule_dst": "Any", // string: list of destination network object names - "rule_svc": "Any", // string: list of service names - "rule_track": "None", // string: logging options, see below - "rule_action": "Inner Layer", // string: rule action options, see below - "rule_implied": false, // boolean: is it an implied (check point) rule derived from settings - "rule_src_neg": false, // boolean: is the source field negated - "rule_dst_neg": false, // boolean: is the destination field negated - "rule_svc_neg": false, // boolean: is the service field negated - "rule_disabled": false, // boolean: is the whole rule disabled - "rule_src_refs": "9aa8e391-f811-4067-86f3-82646bd47d47@9aa8e391-f811-4067-86f3-82646bd47d40|2aa8e391-f811-4067-86f3-82646bd47d41", // string: source references - "rule_dst_refs": "97aeb369-9aea-11d5-bd16-0090272ccb30",// string: destination references - "rule_svc_refs": "97aeb369-9aea-11d5-bd16-0090272ccb30",// string: service references - "rule_time": null, // string: any time restrictions of the rule - "rule_installon": null, // string: list of gateways this rule should be applied to - "parent_rule_uid": null, // string: for layers, the uid of the rule of layer above - "rule_ruleid": null, // string: rule id (unique within gateway, but not globally) - "rule_name": null, // string: optional name of the rule - "rule_comment": null, // string: optional rule comment - "rule_head_text": null, // string: for section headers this is the field to use - "rule_from_zone": null, // string: source zone (if applicable) of the rule - "rule_to_zone": null, // string: destination zone (if applicable) of the rule - "rule_type": "access" // string: type of the nat rule: "access|combined|original|xlate", default "access" -} -``` -- rule_track can be any of log, none, alert, userdefined, mail, account, userdefined 1, userdefined 2, userdefined 3, snmptrap, log count, count, log alert, log alert count, log alert count alarm, log count alarm, count alarm, all, all start, utm, utm start, network log -- rule_action can be any of accept, drop, deny, access, client encrypt, client auth, reject, encrypt, user auth, session auth, permit, permit webauth, redirect, map, permit auth, tunnel l2tp, tunnel vpn-group, tunnel vpn, actionlocalredirect, inner layer - -## Putting it all together 1 - -This is a complete example of a config which may be imported: - -```json -{ - "rules": [ - { - "rulebase_name": "FirstLayer shared with inline layer", - "control_id": 1074, - "rule_num": 0, - "rule_uid": "828b0f42-4b18-4352-8bdf-c9c864d692eb", - "rule_name": null, - "rule_comment": "test comment", - "rule_src": "test-ext-vpn-gw|test-interop-device|BeeW10|wsus", - "rule_dst": "sting-gw", - "rule_svc": "IPSEC", - "rule_time": "Any", - "rule_from_zone": null, - "rule_to_zone": null, - "rule_track": "Log", - "rule_action": "Drop", - "rule_implied": false, - "rule_src_neg": false, - "rule_dst_neg": false, - "rule_svc_neg": false, - "rule_disabled": true, - "rule_src_refs": "a580c5a3-379c-479b-b49d-487faba2442e|98bc04fc-b88b-4283-83ad-7b6899bc1876|2ad18398-e004-4324-af79-634be66941d6|2661ec9f-293f-4c82-8150-4bb6c883ca79", - "rule_dst_refs": "cbdd1e35-b6e9-4ead-b13f-fd6389e34987", - "rule_svc_refs": "97aeb475-9aea-11d5-bd16-0090272ccb30", - "rule_installon": "Policy Targets", - "parent_rule_uid": null, - "rule_ruleid": null, - "rule_type": "access", - "rule_last_change_admin": null - } - ], - "user_objects": [ - { - "user_typ": "simple", - "user_uid": "aae47c39-f416-4b32-801d-af53adfa1939", - "user_name": "test-user1", - "control_id": 1074, - "user_color": "black", - "user_comment": "" - }, - { - "user_typ": "group", - "user_uid": "227d1a80-cc1e-4cd4-9576-4d46f271402f", - "user_name": "test-group", - "control_id": 1074, - "user_color": "black", - "user_comment": "" - } - ], - "network_objects": [ - { - "obj_ip": "22.55.200.192/26", - "obj_typ": "network", - "obj_uid": "5368caf0-d192-457b-9c86-5d5f9e5dc199", - "obj_name": "Net_22.55.200.192-2", - "obj_color": "black", - "control_id": 1074, - "obj_ip_end": "22.55.200.192/26", - "obj_comment": null, - "obj_member_refs": null, - "obj_member_names": null - } - ], - "service_objects": [ - { - "rpc_nr": null, - "svc_typ": "simple", - "svc_uid": "97aeb44f-9aea-11d5-bd16-0090272ccb30", - "ip_proto": "6", - "svc_name": "AOL", - "svc_port": "5190", - "svc_color": "red", - "control_id": 1074, - "svc_comment": "AOL Instant Messenger. Also used by: ICQ & Apple iChat", - "svc_timeout": "3600", - "svc_port_end": "5190", - "svc_member_refs": null, - "svc_member_names": null - } - ], - "zone_objects": [ - { - "zone_name": "test-zone", - "zone_uid": "98aeb44f-9aea-11d5-bd16-0090272ccb30", - "control_id": 1074, - "zone_comment": "just a test" - } - ], - "routing": [ - { - "destination": "10.0.3.38/32", - "distance": 0, - "interface": "port5.1524", - "ip_version": 4, - "metric": 0, - "routing_device": 10, - "source": null, - "static": true, - "target_gateway": "0.0.0.0" - } - ], - "interfaces": [ - { - "ip": "10.0.14.66", - "ip_version": 4, - "name": "port5.1524", - "netmask_bits": 32, - "routing_device": 10, - "state_up": true - } - ] -} -``` - -The following shows an example of how to import nat rules that are combined access/nat rules, here only translating destination (not showing irrelevant fields for brevity's sake): - -```json -{ - "rules": [ - { - "rule_num": 0, - "rule_uid": "828b0f42-4b18-4352-8bdf-c9c864d692eb", - "rule_src": "test-ext-vpn-gw|test-interop-device|BeeW10|wsus", - "rule_dst": "sting-gw", - "rule_svc": "IPSEC", - "rule_src_refs": "a580c5a3-379c-479b-b49d-487faba2442e|98bc04fc-b88b-4283-83ad-7b6899bc1876|2ad18398-e004-4324-af79-634be66941d6|2661ec9f-293f-4c82-8150-4bb6c883ca79", - "rule_dst_refs": "cbdd1e35-b6e9-4ead-b13f-fd6389e34987", - "rule_svc_refs": "97aeb475-9aea-11d5-bd16-0090272ccb30", - "rule_type": "combined", // this rule is both an access and a nat rule - "xlate_rule: "123abcdef-4b18-4352-8bdf-c9c864d692eb" - }, - { - "rule_num": 1, - "rule_uid": "123abcdef-4b18-4352-8bdf-c9c864d692eb", - "rule_src": "test-ext-vpn-gw|test-interop-device|BeeW10|wsus", - "rule_dst": "sting-gw_xlate", - "rule_svc": "IPSEC", - "rule_src_refs": "a580c5a3-379c-479b-b49d-487faba2442e|98bc04fc-b88b-4283-83ad-7b6899bc1876|2ad18398-e004-4324-af79-634be66941d6|2661ec9f-293f-4c82-8150-4bb6c883ca79", - "rule_dst_refs": "123d1e35-b6e9-4ead-b13f-fd6389e34987", - "rule_svc_refs": "97aeb475-9aea-11d5-bd16-0090272ccb30", - "rule_type": "xlate", - } - - ], - ``` - - -## NAT Rules - -here we describe the representation of the rule in the rule table - -- "original" is the keyword for no translation - a special object needs to be created for this -- algorithm for importing NAT rules: - - a NAT rule is stored as two rules, for both of which nat_rule is set to "true" - - the first rule contains the packet match information (original packet) and a pointer (in xlate_rule) to the translation rule - - the translation rule has access_rule==false and xlate_rule==null set and defines how the packet is to be translated - - for check point the NAT rules are pure NAT rules, meaning that access_rule is false - - for other systems a rule can both be an access and an access rule -- rule_action for the xlate_rule can be any of the following (new) values: hide, hide_pool, static_src, static_dst, static_src_and_dst - -- all existing reporting needs to be restricted to access rules (exception receritfication) -- recertification should be possible for both NAT and access rules (should be configurable both per tenant and globally) - -#### final db rule tables - -The following gives an overview of the nat rule presentation as read via FWO API: - -```json -{ - "control_id": 1, // bigint: ID of the current import - "rulebase_name": "FirstLayer shared with inline layer", // string: specifies the rulebase name (all rules are contained in a single json struct) - "rule_num": 1, // integer: rule number for ordering - "rule_uid": "acc044f6-2a4f-459b-b78c-9e7afee92621", // string: unique rule id - "rule_src": "user1@obj1|obj2", // string: list of source object names (if it contains user, use "@" as delimiter) - "rule_dst": "Any", // string: list of destination network object names - "rule_svc": "Any", // string: list of service names - "rule_track": "None", // string: logging options, see below - "rule_action": "Inner Layer", // string: rule action options, see below - "rule_implied": false, // boolean: is it an implied (check point) rule derived from settings - "rule_src_neg": false, // boolean: is the source field negated - "rule_dst_neg": false, // boolean: is the destination field negated - "rule_svc_neg": false, // boolean: is the service field negated - "rule_disabled": false, // boolean: is the whole rule disabled - "rule_src_refs": "9aa8e391-f811-4067-86f3-82646bd47d47@9aa8e391-f811-4067-86f3-82646bd47d40|2aa8e391-f811-4067-86f3-82646bd47d41", // string: source references - "rule_dst_refs": "97aeb369-9aea-11d5-bd16-0090272ccb30",// string: destination references - "rule_svc_refs": "97aeb369-9aea-11d5-bd16-0090272ccb30",// string: service references - "rule_time": null, // string: any time restrictions of the rule - "rule_installon": null, // string: list of gateways this rule should be applied to - "parent_rule_uid": null, // string: for layers, the uid of the rule of layer above - "rule_ruleid": null, // string: rule id (unique within gateway, but not globally) - "rule_name": null, // string: optional name of the rule - "rule_comment": null, // string: optional rule comment - "rule_head_text": null, // string: for section headers this is the field to use - "rule_from_zone": null, // string: source zone (if applicable) of the rule - "rule_to_zone": null, // string: destination zone (if applicable) of the rule - "access_rule": true, - "nat_rule": true, - "xlate_packet": { - "source": "ip_123.1.0.1", - "source_refs": "76aeb369-9aea-11d5-bd16-0090272ccb33", - "destination": "original", - "destination_refs": "original", - "service": "original", - "service_refs": "original" - }, -} -``` - -#### final db rule tables with self ref to xlate rule -```json -{ - "control_id": 1, // bigint: ID of the current import - "rulebase_name": "FirstLayer shared with inline layer", // string: specifies the rulebase name (all rules are contained in a single json struct) - "rule_num": 1, // integer: rule number for ordering - "rule_uid": "acc044f6-2a4f-459b-b78c-9e7afee92621", // string: unique rule id - "rule_src": "user1@obj1|obj2", // string: list of source object names (if it contains user, use "@" as delimiter) - "rule_dst": "Any", // string: list of destination network object names - "rule_svc": "Any", // string: list of service names - "rule_track": "None", // string: logging options, see below - "rule_action": "Inner Layer", // string: rule action options, see below - "rule_implied": false, // boolean: is it an implied (check point) rule derived from settings - "rule_src_neg": false, // boolean: is the source field negated - "rule_dst_neg": false, // boolean: is the destination field negated - "rule_svc_neg": false, // boolean: is the service field negated - "rule_disabled": false, // boolean: is the whole rule disabled - "rule_src_refs": "9aa8e391-f811-4067-86f3-82646bd47d47@9aa8e391-f811-4067-86f3-82646bd47d40|2aa8e391-f811-4067-86f3-82646bd47d41", // string: source references - "rule_dst_refs": "97aeb369-9aea-11d5-bd16-0090272ccb30",// string: destination references - "rule_svc_refs": "97aeb369-9aea-11d5-bd16-0090272ccb30",// string: service references - "rule_time": null, // string: any time restrictions of the rule - "rule_installon": null, // string: list of gateways this rule should be applied to - "parent_rule_uid": null, // string: for layers, the uid of the rule of layer above - "rule_ruleid": null, // string: rule id (unique within gateway, but not globally) - "rule_name": null, // string: optional name of the rule - "rule_comment": null, // string: optional rule comment - "rule_head_text": null, // string: for section headers this is the field to use - "rule_from_zone": null, // string: source zone (if applicable) of the rule - "rule_to_zone": null, // string: destination zone (if applicable) of the rule - "access_rule": true, // string: is this an access rule - "nat_rule": true, // string: is this a NAT rule - "xlate_rule": 1234 // string: for NAT rules this is the link to the xlate rule which contains the translated fileds (src, dst, svc) -} -``` -- additional values for rule_action for xlate rules: hide, hide_pool, static_src, static_dst, static_src_and_dst - -## Envisioned Future Changes -- network_services.ip_proto should be integer instead of string -- network_objects.obj_ip_end can be null for single ip objects instead of repeating the same ip -- The following fields might be dropped in later versions: - - network_objects.obj_sw - - network_objects.obj_location - - network_objects.obj_member_names - could be derived from obj_member_refs - - network_objects.last_change_admin - - network_objects.last_change_time - - network_services.svc_prod_specific - seems to be just a redundant copy of svc_typ - - network_services.last_change_admin - - network_services.last_change_time - - network_services.svc_port_end - range could be entered as string "112-123" - - network_services.svc_source_port_end - range could be entered as string "112-123" - - users.last_change_admin - - rules.rule_last_change_admin - -## 11/2022 target config - -```json -{ - "control_id": 1074, - "mgm_id": 221, - "devices": [ - { - "name": "abc", - "id": 123, - "rulebase_name": "FirstLayer shared with inline layer", - "rules": [ - { - "rulebase_name": "FirstLayer shared with inline layer", - "control_id": 1074, - "rule_num": 0, - "rule_uid": "828b0f42-4b18-4352-8bdf-c9c864d692eb", - "rule_name": null, - "rule_comment": "test comment", - "rule_src": "test-ext-vpn-gw|test-interop-device|BeeW10|wsus", - "rule_dst": "sting-gw", - "rule_svc": "IPSEC", - "rule_time": "Any", - "rule_from_zone": null, - "rule_to_zone": null, - "rule_track": "Log", - "rule_action": "Drop", - "rule_implied": false, - "rule_src_neg": false, - "rule_dst_neg": false, - "rule_svc_neg": false, - "rule_disabled": true, - "rule_src_refs": "a580c5a3-379c-479b-b49d-487faba2442e|98bc04fc-b88b-4283-83ad-7b6899bc1876|2ad18398-e004-4324-af79-634be66941d6|2661ec9f-293f-4c82-8150-4bb6c883ca79", - "rule_dst_refs": "cbdd1e35-b6e9-4ead-b13f-fd6389e34987", - "rule_svc_refs": "97aeb475-9aea-11d5-bd16-0090272ccb30", - "rule_installon": "Policy Targets", - "parent_rule_uid": null, - "rule_ruleid": null, - "rule_type": "access", - "rule_last_change_admin": null - } - ], - "routing": [ - { - "destination": "10.0.3.38/32", - "distance": 0, - "interface": "port5.1524", - "ip_version": 4, - "metric": 0, - "routing_device": 10, - "source": null, - "static": true, - "target_gateway": "0.0.0.0" - } - ], - "interfaces": [ - { - "ip": "10.0.14.66", - "ip_version": 4, - "name": "port5.1524", - "netmask_bits": 32, - "routing_device": 10, - "state_up": true - } - ] - } - ], - "user_objects": [ - { - "user_typ": "simple", - "user_uid": "aae47c39-f416-4b32-801d-af53adfa1939", - "user_name": "test-user1", - "control_id": 1074, - "user_color": "black", - "user_comment": "" - }, - { - "user_typ": "group", - "user_uid": "227d1a80-cc1e-4cd4-9576-4d46f271402f", - "user_name": "test-group", - "control_id": 1074, - "user_color": "black", - "user_comment": "" - } - ], - "network_objects": [ - { - "obj_ip": "22.55.200.192/26", - "obj_typ": "network", - "obj_uid": "5368caf0-d192-457b-9c86-5d5f9e5dc199", - "obj_name": "Net_22.55.200.192-2", - "obj_color": "black", - "control_id": 1074, - "obj_ip_end": "22.55.200.192/26", - "obj_comment": null, - "obj_member_refs": null, - "obj_member_names": null - } - ], - "service_objects": [ - { - "rpc_nr": null, - "svc_typ": "simple", - "svc_uid": "97aeb44f-9aea-11d5-bd16-0090272ccb30", - "ip_proto": "6", - "svc_name": "AOL", - "svc_port": "5190", - "svc_color": "red", - "control_id": 1074, - "svc_comment": "AOL Instant Messenger. Also used by: ICQ & Apple iChat", - "svc_timeout": "3600", - "svc_port_end": "5190", - "svc_member_refs": null, - "svc_member_names": null - } - ], - "zone_objects": [ - { - "zone_name": "test-zone", - "svc_typ": "simple", - "zone_uid": "98aeb44f-9aea-11d5-bd16-0090272ccb30", - "control_id": 1074, - "zone_comment": "just a test" - } - ] -} -``` diff --git a/documentation/developer-docs/importer/firewall-APIs/checkpoint/api-calls-used.md b/documentation/developer-docs/importer/firewall-APIs/checkpoint/api-calls-used.md deleted file mode 100644 index 1b6c523f76..0000000000 --- a/documentation/developer-docs/importer/firewall-APIs/checkpoint/api-calls-used.md +++ /dev/null @@ -1,38 +0,0 @@ -# API feature support - -Firewall Orchestrator uses the following Check Point API calls, which are available from CP API 1.3 - R80.20, -which is the earliest version supported by Firewall Orchestrator. - -See also https://sc1.checkpoint.com/documents/latest/APIs/ - -``` -show-api-versions -show-access-rulebase -show-address-ranges -show-application-site-categories -show-application-sites -show-changes -show-dns-domains -show-gateways-and-servers -show-groups -show-groups-with-exclusion -show-hosts -show-multicast-address-ranges -show-nat-rulebase -show-networks -show-object -show-packages -show-services-tcp -show-services-udp -show-services-dce-rpc -show-services-rpc -show-services-other -show-services-icmp -show-services-icmp6 -show-services-sctp -show-services-gtp -show-service-groups -show-simple-gateways -show-task -show-updatable-objects-repository-content -``` diff --git a/documentation/developer-docs/importer/firewall-APIs/checkpoint/checkpoint-r8x-import-process.png b/documentation/developer-docs/importer/firewall-APIs/checkpoint/checkpoint-r8x-import-process.png deleted file mode 100644 index c9ac36d47a..0000000000 Binary files a/documentation/developer-docs/importer/firewall-APIs/checkpoint/checkpoint-r8x-import-process.png and /dev/null differ diff --git a/documentation/developer-docs/importer/firewall-APIs/checkpoint/hits.md b/documentation/developer-docs/importer/firewall-APIs/checkpoint/hits.md deleted file mode 100644 index b5a36a62e4..0000000000 --- a/documentation/developer-docs/importer/firewall-APIs/checkpoint/hits.md +++ /dev/null @@ -1,43 +0,0 @@ -# The data format of hits -## source - -## command - - show-access-rule - -with header - - { - "name" : "Rule 1", - "layer" : "Network", - "show-hits" : true, - "hits-settings" : {"from-date" : "2014-01-01", "to-date" : "2014-12-31T23:59"} - } - -hits-settings is optional - -## output - - percentage: str "x%" with x in [0-100] - level: str "x" with x in {zero, low, medium, high, very high} - value: int x - first date: obj X with X object that contains posix and iso-8601 dates, only available if at least one hit occured - last date: obj X see first date - -# example - -An example output in json format is - - "hits": { - "percentage": "0%", - "level": "low", - "value": 2, - "first-date": { - "posix": 1602857214000, - "iso-8601": "2020-10-16T07:06-0700" - }, - "last-date": { - "posix": 1602857214000, - "iso-8601": "2020-10-16T07:06-0700" - } - } diff --git a/documentation/developer-docs/importer/firewall-APIs/checkpoint/importer-CP-R8x-Cert-Export.md b/documentation/developer-docs/importer/firewall-APIs/checkpoint/importer-CP-R8x-Cert-Export.md deleted file mode 100644 index 147ecb40b5..0000000000 --- a/documentation/developer-docs/importer/firewall-APIs/checkpoint/importer-CP-R8x-Cert-Export.md +++ /dev/null @@ -1,10 +0,0 @@ -# How to export certificates from Check Point R8x management server - -Necessary for importing into FW-Orch importer to get rid of cert warnings - -Source: https://sc1.checkpoint.com/documents/R81/WebAdminGuides/EN/CP_R81_CLI_ReferenceGuide/Topics-CLIG/MDSG/fwm-printcert.htm?tocpath=Multi-Domain%20Security%20Management%20Commands%7Cfwm%7C_____10 - - -Example: - - fwm printcert -ca internal_ca -x509 out.cert -p >cp.crt \ No newline at end of file diff --git a/documentation/developer-docs/importer/firewall-APIs/checkpoint/install-r8x-test-system.md b/documentation/developer-docs/importer/firewall-APIs/checkpoint/install-r8x-test-system.md deleted file mode 100644 index c54e9490a3..0000000000 --- a/documentation/developer-docs/importer/firewall-APIs/checkpoint/install-r8x-test-system.md +++ /dev/null @@ -1,26 +0,0 @@ -# install R8x test system - -- download r80.40 all-in-one system from -- install on virtual box machine - - bridged fixed ip virtual box using linux 64-bit kernel 2.4/2.6/3/4 - - at least 8 GB RAM - - at least 2 CPUs (Mgmt-Server and API won't run witha single CPU) - - during install dialogue, choose mgmt + gateway install (or later try multi domain mgmt) -- connect to mgmt interface via https and run first time wizard (keep clients can connect from any host), restart -- connect via ssh and set expert password -- also run - - add user fworch userid 1000 homedir /home/fworch - add rba user fworch roles monitorRole - set user fworch password 'secret' - # add allowed-client network ipv4-address 10.8.6.0 mask-length 24 - -## Tell api to listen for all gui clients without GUI client - mgmt_cli -r true --domain MDS set api-settings accepted-api-calls-from "All IP addresses" - api reconf - -## useful commands for later usage - show rba all - show route all - show route static all - diff --git a/documentation/developer-docs/importer/firewall-APIs/checkpoint/r8x-parse-only-testing.md b/documentation/developer-docs/importer/firewall-APIs/checkpoint/r8x-parse-only-testing.md deleted file mode 100644 index 7ae0740a81..0000000000 --- a/documentation/developer-docs/importer/firewall-APIs/checkpoint/r8x-parse-only-testing.md +++ /dev/null @@ -1,16 +0,0 @@ -# how to test with a config file without contact to the original manager - -``` -fworch@ubu18test:~$ python3 importer/checkpointR8x/parse_config.py -f /tmp/isotmp/3/cfg/xxx11.cfg -r 'gMgmt-Cluster_Internet-internal Security' -d 1 -2021-05-04 06:04:07,232 - DEBUG - debug_level: 1 -2021-05-04 06:04:07,418 - DEBUG - parse_config - args -f:/tmp/isotmp/3/cfg/xxx11.cfg -i: 0 -m: -r: gMgmt-Cluster_Internet-internal Security -n: False -s: False -u: False -d: 1 -"0"%"0"%"gMgmt-Cluster_Internet-internal Security"%%"false"%"False"%"Any"%"97aeb369-9aea-11d5-bd16-0090272ccb30"%"False"%"Any"%"97aeb369-9aea-11d5-bd16-0090272ccb30"%"False"%"Any"%"97aeb369-9aea-11d5-bd16-0090272ccb30"%"Accept"%"Log"%"Policy Targets"%"Any"%""%%"24d3149b-7be1-49a3-addb-190e8271baac"%"FW INTERNAL COMMUNICATION"%%% -``` diff --git a/documentation/developer-docs/importer/firewall-APIs/checkpoint/readme.md b/documentation/developer-docs/importer/firewall-APIs/checkpoint/readme.md deleted file mode 100644 index 3a0bed0360..0000000000 --- a/documentation/developer-docs/importer/firewall-APIs/checkpoint/readme.md +++ /dev/null @@ -1,132 +0,0 @@ -# Integrating Check Point R8x via API - -## initial CP API connect -First connect to api should result in the following: -```console -tim@acantha:~$ wget --no-check-certificate https://192.168.100.110/web_api/ -Connecting to 192.168.100.110:443... connected. -WARNING: cannot verify 192.168.100.110's certificate, issued by ‘unstructuredName=An optional company name,emailAddress=Email Address,CN=192.168.100.110,L=Locality Name (eg\\, city)’: - Self-signed certificate encountered. -HTTP request sent, awaiting response... 401 Unauthorized -Username/Password Authentication Failed. -``` - -if you get the following: -```console -tim@acantha:~$ wget --no-check-certificate https://192.168.9.99/web_api/ -HTTP request sent, awaiting response... 403 Forbidden -2020-06-03 12:56:12 ERROR 403: Forbidden. -``` -make sure the api server is up and running and accepting connections from your ip address: -(taken from ) -```console -mgmt_cli -r true --domain MDS set api-settings accepted-api-calls-from "All IP addresses"` -api restart -``` -### create api user profile - -```console -``` - -### Create read-only api user -```console -``` - -### Create full access api user -```console -``` - -## login -```console -curl --insecure --request POST --url https://192.168.100.88/web_api/login --header 'Content-Type: application/json' --data '{"user": "apiuser", "password" : "xxx"}' -``` - -gives the sid (session id) which can then be used to authenticate for further api calls -```json -{ - "sid" : "PhTmI9SD02MTtCWCcTHpc8FsIlX63icc9CvF19PB3qo", - "url" : "https://192.168.100.88:443/web_api", - "session-timeout" : 600, - "last-login-was-at" : { - "posix" : 1631716365111, - "iso-8601" : "2021-09-15T16:32+0200" - }, - "read-only" : true, - "api-server-version" : "1.8", - "user-name" : "apiuser", - "user-uid" : "ba2038a1-437f-45ef-8ea5-c8785cdad9a7" -}``` - -## login to a domain of an MDS -```console -curl --insecure --request POST --url https://192.168.100.88/web_api/login --header 'Content-Type: application/json' --data '{"user": "apiuser", "password" : "xxx", "domain": "yyy"}' -``` - -gives the sid (session id) which can then be used to authenticate for further api calls -```json -{ - "sid" : "PhTmI9SD02MTtCWCcTHpc8FsIlX63icc9CvF19PB3qo", - "url" : "https://192.168.100.88:443/web_api", - "session-timeout" : 600, - "last-login-was-at" : { - "posix" : 1631716365111, - "iso-8601" : "2021-09-15T16:32+0200" - }, - "read-only" : true, - "api-server-version" : "1.8", - "user-name" : "apiuser", - "user-uid" : "ba2038a1-437f-45ef-8ea5-c8785cdad9a7" -} -``` - - -## logout - -```console -``` - -## get a rulebase (part) - -```console -curl --insecure --request POST \ - --url https://192.168.100.88/web_api/show-access-rulebase \ - --header 'Content-Type: application/json' \ - --header 'X-chkp-sid: PhTmI9SD02MTtCWCcTHpc8FsIlX63icc9CvF19PB3qo' \ - --data '{"name": "FirstLayer shared with inline layer"}' -``` - -## get an arbitrary object by UID - -```console -curl --insecure --request POST --url https://192.168.100.88/web_api/show-object --header 'Content-Type: application/json' --header 'X-chkp-sid: KJC5pzFMSRINoVTSByVhUq1xdEE33WD0uy9iXl-cG-4' --data '{"uid": "dd699ecd-1420-41a0-931f-de7f55f799b6", "details-level": "full"}' -``` -results in -```console -{ - "object" : { - "uid" : "d699ecd-1420-41a0-931f-de7f55f799b6", - "type" : "access-section", - "domain" : { - "uid" : "3981ee76-52c3-1744-bf5b-75fe309b1ed9", - "name" : "dom-name1", - "domain-type" : "domain" - }, - "tags" : [ ], - "meta-info" : { - "lock" : "unlocked", - "validation-state" : "ok", - "last-modify-time" : { - "posix" : 1668506934927, - "iso-8601" : "2022-11-15T11:08+0100" - }, - "last-modifier" : "admin-user-1234", - "creation-time" : { - "posix" : 1668506934927, - "iso-8601" : "2022-11-15T11:08+0100" - }, - "creator" : "admin-user-3433" - }, - "read-only" : false - } -} -``` diff --git a/documentation/developer-docs/importer/firewall-APIs/cisco-aci/cisco-aci-api.md b/documentation/developer-docs/importer/firewall-APIs/cisco-aci/cisco-aci-api.md deleted file mode 100644 index 87775e759f..0000000000 --- a/documentation/developer-docs/importer/firewall-APIs/cisco-aci/cisco-aci-api.md +++ /dev/null @@ -1,193 +0,0 @@ -# Integrating Cisco ACI - -- Introduction on ACI reg. firewalling: - - -- API references: - -- ACI Fabric Network Access Security Policy Model (Contracts): - -## online sandbox APIC - -- base (UI) URL: https://sandboxapicdc.cisco.com -- doc URL: https://sandboxapicdc.cisco.com/doc/html -- API URL: https://sandboxapicdc.cisco.com/api/xxx.json -- user: admin -- password: !v3G@!4@Y https://sandboxapicdc.cisco.com - -## user setup - -## login -```console -curl --request POST \ - --url https://sandboxapicdc.cisco.com/api/aaaLogin.json \ - --header 'Content-Type: application/json' \ - --data '{ - "aaaUser" : { - "attributes" : { - "name" : "admin", - "pwd" : "!v3G@!4@Y" - } - } -}' -``` -gives -```json -{ - "totalCount": "1", - "imdata": [ - { - "aaaLogin": { - "attributes": { - "token": "xxx", - "siteFingerprint": "dlcoaz3nzznwlp4f3icvj69l11fp0mys", - "userName": "admin", - "version": "5.2(1g)", - } - } - } - ] -} -``` - -## logout -From the documentation at : - - At this time, the aaaLogout method returns a response but does not end a session. Your session ends after a refresh timeout when you stop sending aaaRefresh messages. - -## get various config parts (classes) - -All of the below classes "CLASS" can be retrieved as follows: -```console -curl --request GET \ - --url https://sandboxapicdc.cisco.com/api/class/CLASS.json \ - --header 'Content-Type: application/json' \ - --cookie APIC-cookie=xxx \ -``` - -### Basic config -- fvBD - bridge domains -- aaaDomain - Domains -- fvEPg - End Point Groups (EPGs) -- fvAEPg - Application endpoint groups -- aaaUser - users -- fvTenant - tenants -- application profiles -- vzGraphCont, vzGraphDef - service graphs -- outside connections - L3Out external EPG (l3extInstP) -- End Point Security Groups (ESGs) - -### Contract information -- vzFilter - filters? -- vzACtrct - contracts -- vzACtrctEpgDef - contracts with EPGs? -- vzBrCP - Binary Contract Profile -- vzABrCP - abstraction of Binary Contract Profile -- vzACollection - ??? -- vzConsDef - Consumer EPg -- vzProvDef - Provider EPg -- vzCtrctEPgCont - Contract EPG Container -- vzCtrctEntityDef - Summary of EPg: Contains All Info to Create ProvDef/ConsDef -- vzRsDenyRule - deny rule (cleanup) -- vzRuleOwner gives an exhaustive list of what looks like fw rules -```json -{ - "totalCount": "55", - "imdata": [ - { - "vzRuleOwner": { - "attributes": { - "action": "permit", - "childAction": "", - "creatorDn": "topology/pod-1/node-101/sys/ctx-[vxlan-16777200]", - "ctrctName": "", - "direction": "uni-dir", - "dn": "topology/pod-1/node-101/sys/actrl/scope-16777200/rule-16777200-s-any-d-any-f-implarp/own-[topology/pod-1/node-101/sys/ctx-[vxlan-16777200]]-tag-vrf", - "intent": "install", - "lcOwn": "local", - "markDscp": "unspecified", - "modTs": "2021-09-20T14:07:18.567+00:00", - "monitorDn": "uni/tn-common/monepg-default", - "name": "", - "nameAlias": "", - "prio": "any_any_filter", - "qosGrp": "unspecified", - "status": "", - "tag": "vrf", - "type": "tenant" - } - } - }, -``` -- vzToEPg -```json -{ - "totalCount": "12", - "imdata": [ - { - "vzToEPg": { - "attributes": { - "bdDefDn": "uni/bd-[uni/tn-Tenant_ISK/BD-BD_ISK]-isSvc-no", - "bdDefStQual": "none", - "bgpDomainId": "10671", - "childAction": "", - "ctxDefDn": "uni/ctx-[uni/tn-Tenant_ISK/ctx-VRF_ISK]", - "ctxDefStQual": "none", - "ctxPcTag": "49153", - "ctxSeg": "2883584", - "descr": "", - "dn": "cdef-[uni/tn-common/brc-app_to_web]/epgCont-[uni/tn-Tenant_ISK/ap-AP_ISK/epg-web]/fr-[uni/tn-common/brc-app_to_web/dirass/prov-[uni/tn-Tenant_ISK/ap-AP_ISK/epg-web]-any-no]/to-[uni/tn-common/brc-app_to_web/dirass/cons-[uni/tn-Tenant_ISK/ap-AP_ISK/epg-app]-any-no]", - "epgDefDn": "uni/tn-common/brc-app_to_web/dirass/cons-[uni/tn-Tenant_ISK/ap-AP_ISK/epg-app]-any-no", - "epgDn": "uni/tn-Tenant_ISK/ap-AP_ISK/epg-app", - "intent": "install", - "isCtxPcTagInUseForRules": "no", - "isGraph": "no", - "l3CtxEncap": "unknown", - "lcOwn": "local", - "modTs": "2021-09-20T14:21:02.498+00:00", - "monPolDn": "", - "name": "", - "nameAlias": "", - "ownerKey": "", - "ownerTag": "", - "pcTag": "16387", - "prefGrMemb": "exclude", - "scopeId": "2883584", - "servicePcTag": "any", - "status": "", - "txId": "17870283321406128551" - } - } - }, -``` - -## get change notifications - -- vzReeval? - -see - -Subscribing to Query Results - can be used to be informated about any changes. This needs a websocket connection. - -## get a list of fw rules - -## get nat rules - - -## Example ansible task to add an EPG - -```ansible - - name: Add static EPG - aci_rest: - host: "{{host}}" - username: "{{username}}" - password: "{{password}}" - method: post - path: /api/node/mo/uni/tn-{{item.tenant}}/ap-{{item.approfile}}/epg-{{item.epgname}}.json - content: "{{ lookup('template', 'templates/epg1.j2') }}" - validate_certs: no - with_items: '{{ ports }}' - ignore_errors: yes - loop_control: - pause: 1 -``` \ No newline at end of file diff --git a/documentation/developer-docs/importer/firewall-APIs/cisco-firepower/readme.md b/documentation/developer-docs/importer/firewall-APIs/cisco-firepower/readme.md deleted file mode 100644 index 880c73fe75..0000000000 --- a/documentation/developer-docs/importer/firewall-APIs/cisco-firepower/readme.md +++ /dev/null @@ -1,18 +0,0 @@ -# Cisco FirePower Documentation - -## Recipe -1. Get devnet access -2. Reserve Environment for 4h -3. Test API Calls using Insomnia or similar -4. Write importer module - -## Resources -### Public -- https://www.cisco.com/c/en/us/support/security/defense-center/products-programming-reference-guides-list.html -- PDF: https://www.cisco.com/c/en/us/td/docs/security/firepower/720/api/REST/secure_firewall_management_center_rest_api_quick_start_guide_720.html -- https://github.com/veeratcisco/postman-fmc/blob/main/collection.zip - -### Devnet -- https://developer.cisco.com/learning/labs/FMC-RESTAPI-02/introduction/ -- https://devnetsandbox.cisco.com/ -- https://fmcrestapisandbox.cisco.com/api/api-explorer/ diff --git a/documentation/developer-docs/importer/firewall-APIs/cisco-sda/cisco-sda-api.md b/documentation/developer-docs/importer/firewall-APIs/cisco-sda/cisco-sda-api.md deleted file mode 100644 index 44df93fb7e..0000000000 --- a/documentation/developer-docs/importer/firewall-APIs/cisco-sda/cisco-sda-api.md +++ /dev/null @@ -1,75 +0,0 @@ -# Integrating Cisco ACI - -## Acronyms -- Cisco Identity Services Engine (ISE) -- Scalable Group Tag (SGT) -- Scalable Group Access Control Entries (SGACE's) - -## intro -Cisco DNA Center uses SSH to establish a trust relationship with ISE. It also uses RestAPI to configure the contracts and policies into ISE. ISE pxGrid information bus is used by Cisco DNA Center to retrieve context information like the SGT's available. - - -## online sandbox APIC - -source: https://devnetsandbox.cisco.com/RM/Diagram/Index/c3c949dc-30af-498b-9d77-4f1c07d835f9?diagramType=Topology - -- SDA policy management: https://community.cisco.com/t5/security-documents/policy-provisioning-and-operation-in-sda/ta-p/3712744 -- base (UI) URL: https://sandboxdnac.cisco.com/ -- doc URL: https://developer.cisco.com/docs/dna-center/api/1-3-3-x/ -- API reference: https://developer.cisco.com/docs/dna-center/#!cisco-dna-2-2-2-api-api-sda-get-sda-fabric-info -- doc API: https://developer.cisco.com/docs/dna-center/#!software-defined-access-sda/software-defined-access-api -- API URL: https://sandboxdnac.cisco.com/dna/intent/api/v1/... -- Community: https://community.cisco.com/t5/networking-blogs/welcome-to-the-dna-center-api-support-community/ba-p/3663632 -- user: devnetuser -- password: Cisco123! - -## user setup - -## login - -base64 encode the credentials: - - tim@acantha:~$ echo devnetuser:Cisco123! | base64 - ZGV2bmV0dXNlcjpDaXNjbzEyMyEK - tim@acantha:~$ - -For some reason the authentication only works when you replace the final K with padding character "=". - -API call: - -```console -curl --request POST \ - --url https://sandboxdnac.cisco.com/dna/system/api/v1/auth/token \ - --header 'Authorization: Basic ZGV2bmV0dXNlcjpDaXNjbzEyMyE=' \ - --header 'Content-Type: application/json' \ -``` -gives - -```json -{ - "Token": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiI2MGVjNGU0ZjRjYTdmOTIyMmM4MmRhNjYiLCJhdXRoU291cmNlIjoiaW50ZXJuYWwiLCJ0ZW5hbnROYW1lIjoiVE5UMCIsInJvbGVzIjpbIjVlOGU4OTZlNGQ0YWRkMDBjYTJiNjQ4ZSJdLCJ0ZW5hbnRJZCI6IjVlOGU4OTZlNGQ0YWRkMDBjYTJiNjQ4NyIsImV4cCI6MTYzMjU2NDU0NSwiaWF0IjoxNjMyNTYwOTQ1LCJqdGkiOiJmMDQyNGIwZi05NTE1LTQxYTctYjVjZC03ODUyNThlZjYzMzYiLCJ1c2VybmFtZSI6ImRldm5ldHVzZXIifQ.ptbCQ4JN6TRyD1ufmI0evKcrNlwthO071YIIISGBOXbxT2VvRTq5x7EPF16gk98N1hYKN80Sx3Q5-XUcwH0TUNoPS7X7kKh7bZmRxWxO59GhKCjtdGgoZmc3sz2jNf1q6CQzsh4gnwQypUUpZq57U6Dwa1RqpY-O7Mtp69akJW7P40_Zz68_vNyS610xkUNiLt4IeVw6ZavblJ2pchyiFJ9tp5rBPMMPpVCl7X63UDSjgWn1echV0Vs3rpq140ZjrWHEsb8DE2LLXG0aWcLcHaXYRkgmueJmbipkAj2KdYE2CsBRPP3naf_-I1JBN6cmFfMkpKH6GWWqT8eYV3BGGA" -} -``` - -## logout - -## get network devices - -```console -curl --request GET \ - --url https://sandboxdnac.cisco.com/dna/intent/api/v1/network-device \ - --header 'Content-Type: application/json' \ - --header 'X-Auth-Token: eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiI2MGVjNGU0ZjRjYTdmOTIyMmM4MmRhNjYiLCJhdXRoU291cmNlIjoiaW50ZXJuYWwiLCJ0ZW5hbnROYW1lIjoiVE5UMCIsInJvbGVzIjpbIjVlOGU4OTZlNGQ0YWRkMDBjYTJiNjQ4ZSJdLCJ0ZW5hbnRJZCI6IjVlOGU4OTZlNGQ0YWRkMDBjYTJiNjQ4NyIsImV4cCI6MTYzMjU2NDU0NSwiaWF0IjoxNjMyNTYwOTQ1LCJqdGkiOiJmMDQyNGIwZi05NTE1LTQxYTctYjVjZC03ODUyNThlZjYzMzYiLCJ1c2VybmFtZSI6ImRldm5ldHVzZXIifQ.ptbCQ4JN6TRyD1ufmI0evKcrNlwthO071YIIISGBOXbxT2VvRTq5x7EPF16gk98N1hYKN80Sx3Q5-XUcwH0TUNoPS7X7kKh7bZmRxWxO59GhKCjtdGgoZmc3sz2jNf1q6CQzsh4gnwQypUUpZq57U6Dwa1RqpY-O7Mtp69akJW7P40_Zz68_vNyS610xkUNiLt4IeVw6ZavblJ2pchyiFJ9tp5rBPMMPpVCl7X63UDSjgWn1echV0Vs3rpq140ZjrWHEsb8DE2LLXG0aWcLcHaXYRkgmueJmbipkAj2KdYE2CsBRPP3naf_-I1JBN6cmFfMkpKH6GWWqT8eYV3BGGA' -``` - -## get sda information - -unfortunately the sandbox does not seam to conain any sda config: - - - -## get a list of fw rules - -## get nat rules - - diff --git a/documentation/developer-docs/importer/firewall-APIs/fortinet/fortiManager-api-howto.md b/documentation/developer-docs/importer/firewall-APIs/fortinet/fortiManager-api-howto.md deleted file mode 100644 index c93c5a908e..0000000000 --- a/documentation/developer-docs/importer/firewall-APIs/fortinet/fortiManager-api-howto.md +++ /dev/null @@ -1,189 +0,0 @@ -# Integrating Fortinet FortiManager 7.x - -## API Docs - -(need account) - -https://fndn.fortinet.net/index.php?/fortiapi/5-fortimanager/&_fromLogin=1 - - - -## user setup - -connect to FM via ssh (admin/empty password) and add the following config - -### make existing admin api ready - -```console -config system admin user - edit admin - set rpc-permit read-write -end -``` - -### create api user profile - -```console -config system admin profile - edit "apiuserprofile" - set super-user-profile enable - next -``` -enter yes here! - -NB: the user will have full rw access via UI but can be restricted to read-only via API as shown below. -Need to find out if there is a more secure way to create an all-read-only api user - -### Create read-only api user -```console -config system admin user - edit "apiuser" - set password xxx - set adom "all_adoms" - set profileid "apiuserprofile" - set rpc-permit read - end -``` - -### Create full access api user -```console -config system admin user - edit "apiuser" - set password xxx - set adom "all_adoms" - set profileid "apiuserprofile" - set rpc-permit read-write -end -``` - -## login -```console -curl --request POST \ - --url https://10.5.1.55/jsonrpc \ - --header 'Content-Type: application/json' \ - --data '{ - "id": 1, - "method": "exec", - "params": [ - { - "data": [ - { - "passwd": "xxx", - "user": "apiuser" - } - ], - "url": "sys/login/user" - } - ] -}' -``` - -gives -```json -{ - "id": 1, - "result": [ - { - "status": { - "code": 0, - "message": "OK" - }, - "url": "sys\/login\/user" - } - ], - "session": "KCOuhqKTFt3ISXKntpIVO2kA5GJ+QcorMoxm8xLGru0HxrwwpgWuTtRcU8P9XCpbIRlDjjSv2+lzTYYIt1bSzw==" -} -``` - -## logout - -```console -curl --request POST \ - --url https://10.5.1.55/jsonrpc \ - --header 'Content-Type: application/json' \ - --data '{ - "id": 1, - "jsonrpc": "1.0", - "method": "exec", - "params": [ - { - "url": "sys/logout" - } - ], - "verbose": 1, - "session": "BJG0kh4qBopxgjJ+DwEyxJSWCl3MzHdeeympX4GJqw50EoLIjXoLH3+7W3e4N9EqtWb5IhGKBJugGKS6HQrDUg==" -}' -``` - -## get a list of all ADOMs - -```console -curl --request POST \ - --url https://10.5.1.55/jsonrpc \ - --header 'Content-Type: application/json' \ - --data '{ - "method": "get", - "params": [ - { - "fields": ["name", "oid", "uuid"], - "url": "/dvmdb/adom" - } - ], - "session": "lieHUJqiA0VldI45nVh8K2o0kP2XRm7NrrayIL1t977BG78\/wukwCgnFnpClbH9A6rAQbCPVjcGVFOw1VwULLQ==" -} -' -``` - -## get a list of fw rules - -```console -curl --request POST \ - --url https://10.5.1.55/jsonrpc \ - --header 'Content-Type: application/json' \ - --data '{ - "method": "get", - "params": [ - { - "url": "/pm/config/adom/my_adom/pkg/mypkg/firewall/policy" - } - ], - "verbose": 1, - "id": 2, - "session": "++7z161rod0cGMaStLUWohDpyUnsyT030tNuLPyVYvIhd0GCLXwp9vCJRKnYV4I0Q\/di1bSL3Wf7o8oNnWu6cw==" -}' -``` - -## get nat rules - -### get snat rules -```console -{ - "method": "get", - "params": [ - { - "url": "/pm/config/adom/my_adom/pkg/mypkg/firewall/central-snat-map" - } - ], - "verbose": 1, - "id": 2, - "session": "++7z161rod0cGMaStLUWohDpyUnsyT030tNuLPyVYvIhd0GCLXwp9vCJRKnYV4I0Q\/di1bSL3Wf7o8oNnWu6cw==" -}' -``` -### get dnat rules - -```console -curl --request POST \ - --url https://10.5.1.55/jsonrpc \ - --header 'Content-Type: application/json' \ - --data '{ - "method": "get", - "params": [ - { - "url": "/pm/config/adom/my_adom/pkg/mypkg/firewall/central/dnat" - } - ], - "verbose": 1, - "id": 2, - "session": "++7z161rod0cGMaStLUWohDpyUnsyT030tNuLPyVYvIhd0GCLXwp9vCJRKnYV4I0Q\/di1bSL3Wf7o8oNnWu6cw==" -}' -``` \ No newline at end of file diff --git a/documentation/developer-docs/importer/firewall-APIs/illumio/0-API.md b/documentation/developer-docs/importer/firewall-APIs/illumio/0-API.md deleted file mode 100644 index cdd2370aee..0000000000 --- a/documentation/developer-docs/importer/firewall-APIs/illumio/0-API.md +++ /dev/null @@ -1,9 +0,0 @@ -# API documentation - -see - - The $KEY and $TOKEN constants in the code examples represent authentication credentials (session and token, API key and token, or username and password as appropriate). - -This is confusing! - -Detailed doc: diff --git a/documentation/developer-docs/importer/firewall-APIs/illumio/1-install-pce.md b/documentation/developer-docs/importer/firewall-APIs/illumio/1-install-pce.md deleted file mode 100644 index 413baebfe7..0000000000 --- a/documentation/developer-docs/importer/firewall-APIs/illumio/1-install-pce.md +++ /dev/null @@ -1,198 +0,0 @@ -# installing on-prem system - -install guide: - -## download software -- login to illumio support portal and navigate to: -- download core & ui rpms and follow instructions on - -```console - /opt/illumio-pce/illumio-pce-env setup --generate-cert - - Illumio PCE Runtime Setup (new configuration) - - # The Fully Qualified Domain Name (FQDN) of this PCE. - # - # For example, pce.mycompany.com - - pce_fqdn: illumio.cactus.de - - # Optional message to display to users on the login page to the PCE web console. - # - # Leave blank if you do not want to configure a login banner. - - login_banner: cactus test system - - # The hostname or IP address of the first node of the PCE cluster. - - service_discovery_fqdn: illumio.cactus.de # auto - - # The public IP addresses associated with the PCE FQDN. - # - # The PCE will automatically program firewall rules with these addresses - # on VENs to allow outbound connections to the PCE. - # - # If cluster load balancing is performed by an L4 load balancer, - # then these addresses will be the VIP(s) of the virtual servers. - - cluster_public_ips: - cluster_fqdn: - - 10.0.2.15 # auto - - # The node type for this PCE node. - # - # Supported values: - # core - # data0 - # data1 - # citus_coordinator - # citus_worker - # snc0 - - node_type: snc0 - - datacenter: dc1 # default - - # The port used for HTTPS connections to the PCE. - # - # If cluster load balancing is performed by an L4 load balancer, - # then the load balancer must be configured to forward this port. - - front_end_https_port: 8443 # default - - # The port used for the PCE web console and API. - # - # If this parameter is not defined (left empty), the PCE will use the - # port defined for the 'front_end_https_port' parameter. - # - # Illumio security best practice is to configure a separate HTTPS - # port for the PCE web console and API. - - front_end_management_https_port: - - # The port used for persistent connections between VENs and the PCE - # event service. - # - # If cluster load balancing is performed by an L4 load balancer, - # then the load balancer must be configured to forward this port - # and its idle connection timeout must be set to 20 minutes. - - front_end_event_service_port: 8444 # default - - # The full path to the RSA private key that matches the public certificate. - # - # The private key must be PEM encoded in PKCS#5 format without a password. - - web_service_private_key: /var/lib/illumio-pce/cert/server.key - - # The full path to a X.509 public certificate used for TLS. - # - # The certificate must match the PCE FQDN. - # The certificate must support both Server and Client authentication. - # The file must contain the server certificate (first) and all - # intermediate CAs needed to establish the chain of trust. - # The certificates must be PEM encoded. - - web_service_certificate: /var/lib/illumio-pce/cert/server.crt - - # The full path to the trusted root certificate bundle. - - trusted_ca_bundle: /etc/ssl/certs/ca-bundle.crt # default - - # The source email address used when sending email from the PCE. - - email_address: illumio@cactus.de - - # The display name used when sending email from the PCE. - - email_display_name: noreply # default - - # A 16 byte key used to encrypt service discovery traffic. - # - # The key must be base64 encoded and must be the same on all nodes in - # the cluster. - - service_discovery_encryption_key: ******** # auto - - # The SMTP relay used by the PCE to send email; for example, to send - # invitations and notifications. - # - # If no port is specified, the default of 587 is used. - - smtp_relay_address: 127.0.0.1:587 # default - - # Specifies the root directory to use for data storage. Defaults to persistent_data_root if not defined. - - - # Specifies the root directory to use for data storage. Defaults to persistent_data_root/traffic_datastore if not defined. - - - # The output format for audit and traffic events written to syslog. - # - # Supported values: - # json - # cef - # leef - - syslog_event_export_format: json # default - - # Allow weaker ciphers, include CBC, for older clients. WARNING: The use of this feature decreases the security of the system, and should only be used with full understanding of the ramifications. - - insecure_tls_weak_ciphers_enabled: true # default - -Wrote configuration /etc/illumio-pce/runtime_env.yml -``` - -Check config -```console -[root@illumio ~]# sudo -u ilo-pce illumio-pce-env check -Checking PCE runtime environment. -Warning: Found 1 warning in PCE runtime environment - 1: Maximum possible log usage (8.42G) could eventually exceed 25% of partition size (5.15G). -OK -[root@illumio ~]# -``` - -setup up aliases: - - alias ctl='sudo -u ilo-pce /opt/illumio-pce/illumio-pce-ctl' - alias ctldb='sudo -u ilo-pce /opt/illumio-pce/illumio-pce-db-management' - alias ctlenv='sudo -u ilo-pce /opt/illumio-pce/illumio-pce-env' - -Start service: - -```console -[tim@illumio ~]$ sudo -u ilo-pce /usr/bin/illumio-pce-ctl start --runlevel 1 -Reading /etc/illumio-pce/runtime_env.yml. -Checking PCE runtime environment. -Warning: Found 1 warning in PCE runtime environment - 1: Maximum possible log usage (8.42G) could eventually exceed 25% of partition size (5.15G). -OK -Starting Illumio Runtime STARTING 6.06s -[tim@illumio ~]$ - - -[tim@illumio ~]$ sudo -u ilo-pce /usr/bin/illumio-pce-ctl status -svw -Checking Illumio Runtime -... -Illumio Runtime System RUNNING [1] 2.33s -[tim@illumio ~]$ -``` -Start master backend and ui - -```console -ctldb setup -ctl set-runlevel 5 -ctl status -svw -ctl cluster-status -``` - -Create UI user: - - ctldb create-domain --user-name tmp@cactus.de --full-name 'tim' --org-name 'Cactus' - -Create API user: - - ctldb create-domain --user-name apiuser@cactus.de --full-name 'api' - - diff --git a/documentation/developer-docs/importer/firewall-APIs/illumio/2-pair-workloads.md b/documentation/developer-docs/importer/firewall-APIs/illumio/2-pair-workloads.md deleted file mode 100644 index 4ea7fa95ca..0000000000 --- a/documentation/developer-docs/importer/firewall-APIs/illumio/2-pair-workloads.md +++ /dev/null @@ -1,8 +0,0 @@ -# Pair workloads - -To use the API, you will need an API key. Which is generated from the PCE’s UI - User - My API keys - Create new key - - Username: api_1fbeb4416acd509bc - Secret: ba9f6db768a875aedd6a6c6bba4fc86c023cd1710698079fb676fe9ffe297221 - -- workload is a tool that uses the API: doc: diff --git a/documentation/developer-docs/importer/firewall-APIs/openstack/openstack.md b/documentation/developer-docs/importer/firewall-APIs/openstack/openstack.md deleted file mode 100644 index 9575537b09..0000000000 --- a/documentation/developer-docs/importer/firewall-APIs/openstack/openstack.md +++ /dev/null @@ -1,239 +0,0 @@ -# OpenStack API - -Start here: - -## online sandbox - -https://www.openstack.org/passport/ - - -## openstack test installation - -on Ubuntu 20.04 (4 GB RAM is not enough, 8 GB seems ok, better 10 GB). - -Make sure simplejson ist not installed: - - sudo apt purge python3-simplejson - -Prepare system: - - sudo useradd -s /bin/bash -d /opt/stack -m stack - echo "stack ALL=(ALL) NOPASSWD: ALL" | sudo tee /etc/sudoers.d/stack - sudo -u stack -i - git clone https://opendev.org/openstack/devstack - cd devstack - -create local.conf file with the following content (choosing a suitable password for XXX): - - [[local|localrc]] - ADMIN_PASSWORD=XXX - DATABASE_PASSWORD=$ADMIN_PASSWORD - RABBIT_PASSWORD=$ADMIN_PASSWORD - SERVICE_PASSWORD=$ADMIN_PASSWORD - - -To avoid error - - Found existing installation: simplejson 3.16.0 - ERROR: Cannot uninstall 'simplejson'. It is a distutils installed project and thus we cannot accurately determine which files belong to it which would lead to only a partial uninstall. - -in inc/python CHANGE FROM - - $cmd_pip $upgrade \ - -TO - - $cmd_pip $upgrade --ignore-installed \ - -Then run the installation - - ./stack.sh - - -## accessing the API - -see - - -### user setup - -### login -```console -curl -i \ - -H "Content-Type: application/json" \ - -d ' -{ "auth": { - "identity": { - "methods": ["password"], - "password": { - "user": { - "name": "admin", - "domain": { "id": "default" }, - "password": "adminpwd" - } - } - } - } -}' \ - "http://localhost:5000/v3/auth/tokens" ; -``` -gives -```json -{ - "totalCount": "1", - "imdata": [ - { - "aaaLogin": { - "attributes": { - "token": "xxx", - "siteFingerprint": "dlcoaz3nzznwlp4f3icvj69l11fp0mys", - "userName": "admin", - "version": "5.2(1g)", - } - } - } - ] -} -``` - -## logout -From the documentation at : - - At this time, the aaaLogout method returns a response but does not end a session. Your session ends after a refresh timeout when you stop sending aaaRefresh messages. - -## get various config parts (classes) - -All of the below classes "CLASS" can be retrieved as follows: -```console -curl --request GET \ - --url https://sandboxapicdc.cisco.com/api/class/CLASS.json \ - --header 'Content-Type: application/json' \ - --cookie APIC-cookie=xxx \ -``` - -### Basic config -- fvBD - bridge domains -- aaaDomain - Domains -- fvEPg - End Point Groups (EPGs) -- fvAEPg - Application endpoint groups -- aaaUser - users -- fvTenant - tenants -- application profiles -- vzGraphCont, vzGraphDef - service graphs -- outside connections - L3Out external EPG (l3extInstP) -- End Point Security Groups (ESGs) - -### Contract information -- vzFilter - filters? -- vzACtrct - contracts -- vzACtrctEpgDef - contracts with EPGs? -- vzBrCP - Binary Contract Profile -- vzABrCP - abstraction of Binary Contract Profile -- vzACollection - ??? -- vzConsDef - Consumer EPg -- vzProvDef - Provider EPg -- vzCtrctEPgCont - Contract EPG Container -- vzCtrctEntityDef - Summary of EPg: Contains All Info to Create ProvDef/ConsDef -- vzRsDenyRule - deny rule (cleanup) -- vzRuleOwner gives an exhaustive list of what looks like fw rules -```json -{ - "totalCount": "55", - "imdata": [ - { - "vzRuleOwner": { - "attributes": { - "action": "permit", - "childAction": "", - "creatorDn": "topology/pod-1/node-101/sys/ctx-[vxlan-16777200]", - "ctrctName": "", - "direction": "uni-dir", - "dn": "topology/pod-1/node-101/sys/actrl/scope-16777200/rule-16777200-s-any-d-any-f-implarp/own-[topology/pod-1/node-101/sys/ctx-[vxlan-16777200]]-tag-vrf", - "intent": "install", - "lcOwn": "local", - "markDscp": "unspecified", - "modTs": "2021-09-20T14:07:18.567+00:00", - "monitorDn": "uni/tn-common/monepg-default", - "name": "", - "nameAlias": "", - "prio": "any_any_filter", - "qosGrp": "unspecified", - "status": "", - "tag": "vrf", - "type": "tenant" - } - } - }, -``` -- vzToEPg -```json -{ - "totalCount": "12", - "imdata": [ - { - "vzToEPg": { - "attributes": { - "bdDefDn": "uni/bd-[uni/tn-Tenant_ISK/BD-BD_ISK]-isSvc-no", - "bdDefStQual": "none", - "bgpDomainId": "10671", - "childAction": "", - "ctxDefDn": "uni/ctx-[uni/tn-Tenant_ISK/ctx-VRF_ISK]", - "ctxDefStQual": "none", - "ctxPcTag": "49153", - "ctxSeg": "2883584", - "descr": "", - "dn": "cdef-[uni/tn-common/brc-app_to_web]/epgCont-[uni/tn-Tenant_ISK/ap-AP_ISK/epg-web]/fr-[uni/tn-common/brc-app_to_web/dirass/prov-[uni/tn-Tenant_ISK/ap-AP_ISK/epg-web]-any-no]/to-[uni/tn-common/brc-app_to_web/dirass/cons-[uni/tn-Tenant_ISK/ap-AP_ISK/epg-app]-any-no]", - "epgDefDn": "uni/tn-common/brc-app_to_web/dirass/cons-[uni/tn-Tenant_ISK/ap-AP_ISK/epg-app]-any-no", - "epgDn": "uni/tn-Tenant_ISK/ap-AP_ISK/epg-app", - "intent": "install", - "isCtxPcTagInUseForRules": "no", - "isGraph": "no", - "l3CtxEncap": "unknown", - "lcOwn": "local", - "modTs": "2021-09-20T14:21:02.498+00:00", - "monPolDn": "", - "name": "", - "nameAlias": "", - "ownerKey": "", - "ownerTag": "", - "pcTag": "16387", - "prefGrMemb": "exclude", - "scopeId": "2883584", - "servicePcTag": "any", - "status": "", - "txId": "17870283321406128551" - } - } - }, -``` - -## get change notifications - -- vzReeval? - -see - -Subscribing to Query Results - can be used to be informated about any changes. This needs a websocket connection. - -## get a list of fw rules - -## get nat rules - - -## Example ansible task to add an EPG - -```ansible - - name: Add static EPG - aci_rest: - host: "{{host}}" - username: "{{username}}" - password: "{{password}}" - method: post - path: /api/node/mo/uni/tn-{{item.tenant}}/ap-{{item.approfile}}/epg-{{item.epgname}}.json - content: "{{ lookup('template', 'templates/epg1.j2') }}" - validate_certs: no - with_items: '{{ ports }}' - ignore_errors: yes - loop_control: - pause: 1 -``` \ No newline at end of file diff --git a/documentation/developer-docs/importer/firewall-APIs/paloAlto/paloAltoApi.md b/documentation/developer-docs/importer/firewall-APIs/paloAlto/paloAltoApi.md deleted file mode 100644 index c257c99faa..0000000000 --- a/documentation/developer-docs/importer/firewall-APIs/paloAlto/paloAltoApi.md +++ /dev/null @@ -1,556 +0,0 @@ -# Integrating Palo Alto firewall - -All examples here are given for PanOS 9.0. PAN-OS has two APIs: XML and REST. There is also an extra REST API for the central management server Panorama. The XML-API can be used to get the whole config in one go. - -## Create api user -see - -## login -```console -curl --insecure --request GET --url 'https://PAN-IP/api/?type=keygen&user=fwo&password=xxx' -``` -gets us a session key in XML format which seems to be valid indefinetly?!: -```xml - - - LUFRPT1Tb2xDZnk0R25WbDJONWJNMmlEMHNpS0Y2d1U9T3ZLZFhydER6SDZKYk9OQit2cmVTVUtEb2MyMVBDUkdBOGY3UzlDS0VrTT0= - - -``` - -More secure: -see , but note: You cannot use basic authentication when you Get Your API Key. - - -## get API version - -`curl -X GET "https:///api/?type=version&key="' - -## Get all network objects -The session key can be used to get objects as follows (for single fw, the name of the vsys seems to be vsys1): -```console -curl --insecure --request GET \ - --url 'https://PAN-IP/restapi/v9.1/Objects/Addresses?location=vsys&vsys=vsys1' \ - --header 'X-PAN-KEY: LUFRPT1JdHF6SnVndXNEU2VxVFIvNnZ1bG1yeFk0S2c9clVWeGhkdnNQNTBRK1BzNXBCeEMvNzdTSks1NWVDdzJLSmZXa1JsUkYzdW9OUnJSb1pDREdseitlVUtNc1VKSw==' -``` -Gives us the network objects in JSON format: - -```json -{ - "@status": "success", - "@code": "19", - "result": { - "@total-count": "45", - "@count": "45", - "entry": [ - { - "@name": "ext-interface-ip-10.9.8.2", - "@location": "vsys", - "@vsys": "vsys1", - "ip-netmask": "10.9.8.2" - }, - { - "@name": "cactus-da", - "@location": "vsys", - "@vsys": "vsys1", - "ip-netmask": "85.182.155.96\/27", - "tag": { - "member": [ - "cactus-DA" - ] - } - }, - { - "@name": "fb_inet_10.9.8.1", - "@location": "vsys", - "@vsys": "vsys1", - "ip-netmask": "10.9.8.1" - }, - { - "@name": "gware.cactus.de_85.182.155.108", - "@location": "vsys", - "@vsys": "vsys1", - "ip-netmask": "85.182.155.108\/32", - "tag": { - "member": [ - "cactus-DA" - ] - } - } - ] - } -} -``` -To get address groups: - -```console -curl --request GET \ - --url 'https://10.8.6.3/restapi/v9.1/Objects/AddressGroups?location=vsys&vsys=vsys1' \ - --header 'X-PAN-KEY: LUFRPT1zUmdXTlZjUFZPaWxmc0R2eHRPa1FvdmtlV009T3ZLZFhydER6SDZKYk9OQit2cmVTZHNYWDJrdHREWDVyN1VnZG01VXNKWT0=' \ -``` - -Retrieves tag-based filters: -```json -{ - "@status": "success", - "@code": "19", - "result": { - "@total-count": "3", - "@count": "3", - "entry": [ - { - "@name": "GRP_tims-ip-adressen", - "@location": "vsys", - "@vsys": "vsys1", - "dynamic": { - "filter": "'tims-clients'" - } - }, - { - "@name": "GRP_guest-ips", - "@location": "vsys", - "@vsys": "vsys1", - "dynamic": { - "filter": "'guests' " - } - }, - { - "@name": "GRP_kids_ips", - "@location": "vsys", - "@vsys": "vsys1", - "dynamic": { - "filter": "'kids-ips'" - } - } - ] - } -} -``` -## get service objects - -first predefined services: - -```console -curl --request GET \ - --url 'https://10.8.6.3/restapi/v9.1/Objects/Services?location=predefined' \ - --header 'X-PAN-KEY: LUFRPT1JdHF6SnVndXNEU2VxVFIvNnZ1bG1yeFk0S2c9clVWeGhkdnNQNTBRK1BzNXBCeEMvNzdTSks1NWVDdzJLSmZXa1JsUkYzdW9OUnJSb1pDREdseitlVUtNc1VKSw==' \ -``` - -yields: - -```json -{ - "@status": "success", - "@code": "19", - "result": { - "@total-count": "2", - "@count": "2", - "entry": [ - { - "@name": "service-http", - "@location": "predefined", - "protocol": { - "tcp": { - "port": "80,8080" - } - } - }, - { - "@name": "service-https", - "@location": "predefined", - "protocol": { - "tcp": { - "port": "443" - } - } - } - ] - } -} -``` - -Then self-defined: - -```console -curl --insecure --request GET \ - --url 'https://PAN-IP/restapi/v9.1/Objects/Services?location=vsys&vsys=vsys1' \ - --header 'X-PAN-KEY: LUFRPT1JdHF6SnVndXNEU2VxVFIvNnZ1bG1yeFk0S2c9clVWeGhkdnNQNTBRK1BzNXBCeEMvNzdTSks1NWVDdzJLSmZXa1JsUkYzdW9OUnJSb1pDREdseitlVUtNc1VKSw==' -``` - -give us: - -```json -{ - "@status": "success", - "@code": "19", - "result": { - "@total-count": "42", - "@count": "42", - "entry": [ - { - "@name": "tcp_64285", - "@location": "vsys", - "@vsys": "vsys1", - "protocol": { - "tcp": { - "port": "64285", - "override": { - "no": [] - } - } - } - }, - { - "@name": "steam_27000-27100", - "@location": "vsys", - "@vsys": "vsys1", - "protocol": { - "udp": { - "port": "27000-27100", - "override": { - "no": [] - } - } - } - }, - { - "@name": "svc_3000_tcp_hbci", - "@location": "vsys", - "@vsys": "vsys1", - "protocol": { - "tcp": { - "port": "3000", - "override": { - "no": [] - } - } - } - }, - { - "@name": "fritzbox_tcp_14013", - "@location": "vsys", - "@vsys": "vsys1", - "protocol": { - "tcp": { - "port": "14013", - "override": { - "no": [] - } - } - } - } - ] - } -} -``` - - -## get (predefined) applications - -in order to get the application names we need API v9.1! - -with version 9.0: -```console -curl --insecure --request GET \ - --url 'https://10.8.6.3/restapi/9.0/Objects/Applications?location=predefined' \ - --header 'X-PAN-KEY: LUFRPT1zUmdXTlZjUFZPaWxmc0R2eHRPa1FvdmtlV009T3ZLZFhydER6SDZKYk9OQit2cmVTZHNYWDJrdHREWDVyN1VnZG01VXNKWT0=' \ -``` -```json -{ - "@status": "success", - "@code": "19", - "result": { - "@total-count": "3566", - "@count": "3566", - "entry": [ - { - "default": { - "port": { - "member": [ - "tcp\/3468,6346,11300" - ] - } - }, - "category": "general-internet", - "subcategory": "file-sharing", - "technology": "peer-to-peer", - "risk": "5", - "evasive-behavior": "yes", - "consume-big-bandwidth": "yes", - "used-by-malware": "yes", - "able-to-transfer-file": "yes", - "has-known-vulnerability": "yes", - "tunnel-other-application": "no", - "prone-to-misuse": "yes", - "pervasive-use": "yes" - } - ] - } -} -``` -With v9.1: - -```console -curl --request GET \ - --url 'https://10.8.6.3/restapi/v9.1/Objects/Applications?location=predefined' \ - --header 'X-PAN-KEY: LUFRPT1zUmdXTlZjUFZPaWxmc0R2eHRPa1FvdmtlV009T3ZLZFhydER6SDZKYk9OQit2cmVTZHNYWDJrdHREWDVyN1VnZG01VXNKWT0=' -``` - -```json -{ - "@status": "success", - "@code": "19", - "result": { - "@total-count": "3566", - "@count": "3566", - "entry": [ - { - "@name": "100bao", - "@location": "predefined", - "default": { - "port": { - "member": [ - "tcp\/3468,6346,11300" - ] - } - }, - "category": "general-internet", - "subcategory": "file-sharing", - "technology": "peer-to-peer", - "risk": "5", - "evasive-behavior": "yes", - "consume-big-bandwidth": "yes", - "used-by-malware": "yes", - "able-to-transfer-file": "yes", - "has-known-vulnerability": "yes", - "tunnel-other-application": "no", - "prone-to-misuse": "yes", - "pervasive-use": "yes" - }, - { - "@name": "open-vpn", - "@location": "predefined", - "default": { - "port": { - "member": [ - "tcp\/1194", - "tcp\/443", - "udp\/1194" - ] - } - }, - "category": "networking", - "subcategory": "encrypted-tunnel", - "technology": "client-server", - "timeout": "3600", - "risk": "3", - "evasive-behavior": "no", - "consume-big-bandwidth": "no", - "used-by-malware": "no", - "able-to-transfer-file": "yes", - "has-known-vulnerability": "yes", - "tunnel-other-application": "yes", - "tunnel-applications": { - "member": [ - "cyberghost-vpn", - "frozenway", - "hotspot-shield", - "ipvanish", - "spotflux" - ] - }, - "prone-to-misuse": "no", - "pervasive-use": "yes" - } - ] - } -} -``` - -## get rules - -```console -curl --insecure --request GET \ - --url 'https://PAN-IP/restapi/v9.1/Policies/SecurityRules?location=vsys&vsys=vsys1' \ - --header 'X-PAN-KEY: LUFRPT1JdHF6SnVndXNEU2VxVFIvNnZ1bG1yeFk0S2c9clVWeGhkdnNQNTBRK1BzNXBCeEMvNzdTSks1NWVDdzJLSmZXa1JsUkYzdW9OUnJSb1pDREdseitlVUtNc1VKSw==' \ -``` - -gives us: - -```json -{ - "@status": "success", - "@code": "19", - "result": { - "@total-count": "85", - "@count": "85", - "entry": [ - { - "@name": "special access tim-1", - "@uuid": "ca58af60-05c3-4806-b7c6-aea7a1ddc70c", - "@location": "vsys", - "@vsys": "vsys1", - "to": { - "member": [ - "untrust" - ] - }, - "from": { - "member": [ - "trust" - ] - }, - "source": { - "member": [ - "GRP_tims-ip-adressen" - ] - }, - "destination": { - "member": [ - "any" - ] - }, - "source-user": { - "member": [ - "any" - ] - }, - "application": { - "member": [ - "open-vpn", - "ssh", - "ssh-tunnel", - "ssl", - "web-browsing" - ] - }, - "service": { - "member": [ - "any" - ] - }, - "hip-profiles": { - "member": [ - "any" - ] - }, - "action": "allow", - "rule-type": "interzone", - "profile-setting": { - "profiles": { - "url-filtering": { - "member": [ - "default" - ] - }, - "file-blocking": { - "member": [ - "strict file blocking" - ] - }, - "virus": { - "member": [ - "test-av-profile" - ] - }, - "spyware": { - "member": [ - "strict" - ] - }, - "vulnerability": { - "member": [ - "default" - ] - }, - "wildfire-analysis": { - "member": [ - "default" - ] - } - } - }, - "tag": { - "member": [ - "tims-clients" - ] - }, - "log-start": "yes", - "category": { - "member": [ - "any" - ] - }, - "disabled": "no", - "log-setting": "forwarder-traffic-log", - "group-tag": "tims-clients" - }, - { - "@name": "DMZ minecraft", - "@uuid": "ac91834b-0ac3-4d9a-abcd-3ad69075bed7", - "@location": "vsys", - "@vsys": "vsys1", - "to": { - "member": [ - "any" - ] - }, - "from": { - "member": [ - "untrust" - ] - }, - "source": { - "member": [ - "any" - ] - }, - "destination": { - "member": [ - "ext-interface-ip-10.9.8.2" - ] - }, - "source-user": { - "member": [ - "any" - ] - }, - "category": { - "member": [ - "any" - ] - }, - "application": { - "member": [ - "any" - ] - }, - "service": { - "member": [ - "tcp_60999" - ] - }, - "hip-profiles": { - "member": [ - "any" - ] - }, - "action": "allow", - "log-start": "yes", - "rule-type": "universal", - "log-setting": "forwarder-traffic-log", - "profile-setting": { - "profiles": { - "vulnerability": { - "member": [ - "strict" - ] - } - } - }, - "disabled": "no" - } - ] - } -} -``` \ No newline at end of file diff --git a/documentation/developer-docs/importer/legacy-importer-csv-interface.md b/documentation/developer-docs/importer/legacy-importer-csv-interface.md deleted file mode 100644 index e81adcc70f..0000000000 --- a/documentation/developer-docs/importer/legacy-importer-csv-interface.md +++ /dev/null @@ -1,139 +0,0 @@ -# CSV interface of importer - -## adjusting parser interface - -All data is currently exchanged via a CSV interface. - -### perl-based (parse-config file) import modules (old) -If a field needs to be added to the CSV interface, for all old perl-based parsers -you need to add the name of the field to the respective _outlist in roles/importer/files/importer/CACTUS/FWORCH/import.pm, e.g. - @rule_outlist =(qw ( rule_id disabled src.op src src.refs dst.op dst dst.refs services.op services services.refs - action track install time comments name UID header_text src.zone dst.zone last_change_admin parent_rule_uid)); - -### python-based (API access) import modules (new) - -For python based importers, you need to adjust the roles/importer/files/importer/checkpointR8x/*_parser.py files, e.g. - csv_dump_svc_obj.py in parse_service.py - -## General - -```console -- boolean fields (negated, disabled) can contain either 0/1 or true/false? -- directory: -- import arrays/fields are defined in CACTUS/FWORCH/import.pm: - our @obj_import_fields - our @svc_import_fields - our @user_import_fields - our @zone_import_fields - our @rule_import_fields - our @auditlog_import_fields -``` - -## import_ tables - -### rule.csv - -```console -name: _rulebase.csv -fields (total=26): - control_id - bigint - id of currently running import (identical for all rules of an import) - rule_num - integer - number of the rule relative to the current import - used for sorting rules within this import - rulebase_name - string - name of the rulebase (used for matching rule to gateway) - rule_ruleid - string - id (unique within gateway, but not globally) - rule_disabled - boolean - is the rule disabled (inactive)? - rule_src_neg - boolean - is the source of the rule negated? - rule_src - string of CSVs with source objects of the rule (including users in format "user[-group]@object") - rule_src_refs - string of CSVs with UIDs of source objects of the rule (including users in format "user[-group]-uid@object-uid") - rule_dst_neg - boolean - is the destination of the rule negated? - rule_dst - string of CSVs with destination objects of the rule - rule_dst_refs - string of CSVs with UIDs of destination objects of the rule - rule_svc_neg - boolean - is the service of the rule negated? - rule_svc - rule_svc_refs - rule_action - rule_track - rule_installon - rule_time - rule_comment - rule_name - rule_uid - rule_head_text - rule_from_zone - rule_to_zone - last_change_admin - string containing name of the last admin having changed this rule (optional, checkpoint only) - parent_rule_uid - string - UID of a rule this rule belongs to (either layer, domain rules or section) -``` - -### network_objects.csv - -```console -name: _netzobjekte.csv -fields (total=15): - control_id - obj_name - obj_typ - obj_member_names - obj_member_refs - obj_sw - obj_ip - obj_ip_end - obj_color - obj_comment - obj_location - obj_zone - obj_uid - last_change_admin - last_change_time -``` - -### services.csv - -```console -name: _services.csv -fields (total=19): - control_id - svc_name - svc_typ - svc_prod_specific --> note: this seems to be just a redundant copy of svc_typ! - svc_member_names - svc_member_refs - svc_color - ip_proto - svc_port - svc_port_end - svc_source_port - svc_source_port_end - svc_comment - rpc_nr - svc_timeout_std - svc_timeout - svc_uid - last_change_admin - last_change_time -``` - -### users.csv - -```console -name: _users.csv -fields (total=10): - control_id - user_name - user_typ - user_member_names - user_member_refs - user_color - user_comment - user_uid - user_valid_until - last_change_admin -``` - -### zones.csv - -```console -name: _zones.csv -fields (total=2): - control_id - zone_name -``` diff --git a/documentation/developer-docs/importer/readme.md b/documentation/developer-docs/importer/readme.md deleted file mode 100644 index 0097a1b9ce..0000000000 --- a/documentation/developer-docs/importer/readme.md +++ /dev/null @@ -1,77 +0,0 @@ -# Importing firewall configs via API - -## Code structure and entry point - -We use the FWO API to write the whole firewall config as JSON into the import_config table. The format is described below. -The main import script is [/roles/importer/import_mgm.py](/roles/importer/import_mgm.py). -It does not need to be changed when adding new import modules. -Within this file we have the following calls which deal with firewall product specific stuff: -```python - # import product-specific importer module: -fw_module = importlib.import_module("." + fw_module_name, pkg_name) - -# get config from FW API and write it into config2import if it has changed: - - config_changed_since_last_import = fw_module.has_config_changed(mgm_details, debug_level=debug_level, ssl_verification=ssl, force=force) - - if config_changed_since_last_import: - get_config_response = fw_module.get_config( - config2import, full_config_json, current_import_id, mgm_details, debug_level=debug_level, - ssl_verification=ssl, limit=limit, force=force, jwt=jwt) - -# now we import config2import via the FWO API: -error_count += fwo_api.import_json_config(fwo_api_base_url, jwt, args.mgm_id, { - "importId": current_import_id, "mgmId": args.mgm_id, "config": config2import}) -``` -The above describes the new 2021 import method. In addition we also have some legacy import modules. -Regarding legacy import modules see [/documentation/developer-docs/importer](/documentation/developer-docs/importer/legacy-importer-csv-interface.md). -For an overview see next section. - -### Import module status -- CPR8x - Currently CPR8x can be importer both via legacy (perl with CSV) and python importer (API2API) -- FortiManager - can be importer using the new API-based method -- FortiGate - can be importer via old legacy method (ssh-based) -- Barracuda - can be importer via old legacy method (ssh-based) -- Juniper JunOS - can be importer via old legacy method (ssh-based) -- Juniper ScreenOS - can be importer via old legacy method (ssh-based) -- Cisco ASA/Pix - can be importer via old legacy method (ssh-based) - work in progress - needs to be tested first. - -## Adding a new import module - -- It is highly recommend to stop the import process before making any changes (don't forget to restart it after successful integration): -```bash - sudo systemctl stop fworch-importer -``` -- create a new firewall type by adding it to table stm_dev_type. To make this change permanent, this has to be added to [/roles/database/files/sql/creation/fworch-fill-stm.sql](/roles/database/files/sql/creation/fworch-fill-stm.sql) as follows: -```sql -insert into stm_dev_typ (dev_typ_name,dev_typ_version,dev_typ_manufacturer) VALUES ('','',''); -``` -- Note that the version should be short and open ended, e.g. "7ff". If there is a major breaking change, a new version, e.g. 10ff will have to be created. -- For a smooth upgrade path for existing installations, a new FWO version needs to be created and sql statement above also needs to be added to the upgrade script. For upgrade information see (documentation/developer-docs/installer/upgrading.md). -- Create a sub-directory beneath /usr/local/fworch/importer/ called "dev_typ_name" + "dev_typ_version" -- Within this directory there has be a module called 'fwcommon.py' containing a function get_config using the parameters above -- The config needs to be returned in the config2import variable as a json dict using the syntax described in [/documentation/developer-docs/importer/FWO-import-api.md](/documentation/developer-docs/importer/FWO-import-api.md) -- For testing the new import module, you need to add a management and a device via the UI (see help section for details on this). - -### Data handling rules -- If there are no (e.g. user or zone) objects of a kind in the config, the respective *_objects arrays can simply be ommited. -- Group delimiter is the pipe (|). -- All non-integer values need to be enclosed in quotes ("). -- All values need to be sanitized, removing quotes (single and double) as well as replacing line breaks with space chars. - -## Testing & Tools - -We recommend using a tool like insomnia for testing API stuff. - -## Debugging python - -importer files end up in different directories during installation process (not the same as in the source/installer code). For debugging use something like: - -```bash -sudo ln -s /home/tim/dev/tpur-fwo-june/firewall-orchestrator/roles/importer/files/importer /usr/local/fworch/importer -``` -or the following in vscode - -```console -sys.path.append(r"/home/tim/dev/tpur-fwo-june/firewall-orchestrator/roles/importer/files/importer") -``` diff --git a/documentation/developer-docs/project-directory-structure.md b/documentation/developer-docs/project-directory-structure.md index c7cbd4a3c6..a21a82cbcf 100644 --- a/documentation/developer-docs/project-directory-structure.md +++ b/documentation/developer-docs/project-directory-structure.md @@ -22,7 +22,6 @@ sample_config_user_home: "/home/{{ sample_config_user }}" - creating {{ fworch_parent_dir }}/fworch - creating user fworch - - adding file iso.conf to {{ fworch_parent_dir }}/fworch/etc - creating logs ## hosts: backends @@ -36,15 +35,15 @@ database_dir: /var/lib/pgsql/data ``` - The roles to be installed on the backend are - - docker + - podman - database - api - auth - openldap-server -- The role docker executes the tasks - - downloads and installs Docker and related packages - - creates local config directory {{ fworch_home }}/.docker and adds config.json +- The role podman executes the tasks + - installs Podman on the API host + - prepares the container runtime used for the Hasura API service - The role database executes the tasks - installs postgresql DBMS diff --git a/documentation/developer-docs/visual-studio/readme.md b/documentation/developer-docs/visual-studio/readme.md index ef73d205f4..9b47d5d607 100644 --- a/documentation/developer-docs/visual-studio/readme.md +++ b/documentation/developer-docs/visual-studio/readme.md @@ -12,15 +12,12 @@ Useful for Blazor/C# testing. Works on Windows, MacOS and Linux. ## Add VS Code Extensions from Marketplace recommended: -- C# +- C# --> make sure to activate OmniSharp Support in settings - Razor+ - Debugger for Firefox - GitHub Pull Requests and Issues, see - GitLens - GraphQL for VSCode -- Perl -- Simple Perl -- Prettier-Code formatter - Python Testing: @@ -107,7 +104,7 @@ or alternatively add the following to csproj file: - netcoreapp3.1 + net10.0 diff --git a/documentation/importer/readme.md b/documentation/importer/readme.md index da60c9873c..93e83cdf22 100644 --- a/documentation/importer/readme.md +++ b/documentation/importer/readme.md @@ -2,30 +2,11 @@ These can be used for testing a specific import on the command line. -## legacy importer fworch-importer-single.pl - -```console --show-only-first-import-error --fullauditlog --clear-all-rules - remove only rules from DB but keep objects --clear-management - remove all rules and objects from the database --no-md5-checks - do not check checksums of config files but import even no changes were made --do-not-copy - do not copy files from management system but use existing local config file(s) --direct-from-csv - neither copy nor parse config but simply import from existing CSV files -need to change import id in all csv-files to next id, e.g.: - sudo find . -name "*.csv" -exec sed -i 's/12192714/12192718/' '{}' \; --use-scp - use scp for copying config for testing ignoring product specific interfaces - (when you do not have a test device handy) --no-cleanup - do not delete temporary files (.config, .csv) after import completed (for debugging purposes) --debug=x - set debug level for import to x --configfile=/path/to/file - import directly from local (R8x) config file, do not copy -``` - ## python importer ```console -user@test:~$ ./import-mgm.py --help -usage: import-mgm.py [-h] -m management_id [-c] [-f] [-d debug_level] [-v] [-s] [-l api_limit] [-i config_file_input] [-n config_file_normalized_input] +user@test:~$ ./import_mgm.py --help +usage: import_mgm.py [-h] -m management_id [-c] [-f] [-d debug_level] [-v] [-s] [-l api_limit] [-i config_file_input] [-n config_file_normalized_input] Read configuration from FW management via API calls @@ -50,3 +31,37 @@ optional arguments: if set, the config will not be fetched from firewall but read from normalized json config file specified here; may also be an url. user@test:~$ ``` + + +### Lint Setup + +ruff and pre-commit are in requirements.txt + +``` +pip install -r .\roles\importer\files\importer\requirements.txt +``` + +``` +pre-commit install +``` + +### Usage + +Ruff lint check + +``` +ruff check +``` + +Ruff lint check and auto fix + +``` +ruff check --fix +``` + + +Ruff format ( only needed for VS, but also run pre-commit) + +``` +ruff format +``` diff --git a/documentation/installer/basic-installation.md b/documentation/installer/basic-installation.md index 9caefdf427..e1a84b2596 100644 --- a/documentation/installer/basic-installation.md +++ b/documentation/installer/basic-installation.md @@ -1,19 +1,29 @@ # Installation instructions server - use latest debian or ubuntu minimal server with ssh service running (need to install and configure sudo for debian) -- recommended platforms are Ubuntu Server 20.04 LTS and Debian 11. See [system requirements](https://fwo.cactus.de/wp-content/uploads/2021/07/fwo-system-requirements-v5.pdf) for supported platforms +- recommended platforms are Ubuntu Server 22.04 LTS and Debian 12. See [system requirements](https://fwo.cactus.de/wp-content/uploads/2021/07/fwo-system-requirements-v5.pdf) for supported platforms - we will install various software components to your system. It is recommended to do so on a dedicated (test) system. 1) prepare your target system (make sure your user has full sudo permissions) ```console su - -apt-get install git ansible sudo +apt-get install git sudo ansible ``` -if not already configured, add your current user to sudo group (make sure to activate this change by starting new shell or even rebooting): +if not already configured, add your current user to sudo group (**_make sure to activate this change by rebooting_**): ```console -usermod -a -G sudo `whoami` +usermod -a -G sudo +``` + +To check if the user is in the sudoers file, you can check with following command: +```console +grep sudo /etc/group +``` + +**_Exit to normal user with:_** +```console +exit ``` Also make sure your packages are up to date before FWORCH installation using e.g. @@ -22,22 +32,27 @@ Also make sure your packages are up to date before FWORCH installation using e.g possibly followed by a reboot. +2) Getting Firewall Orchestrator + +with the following command: -2) get Firewall Orchestrator with the following command (as normal user) ```console git clone https://github.com/CactuseSecurity/firewall-orchestrator.git ``` -3) Ansible Installation - - Ubuntu 18.04, Debian 10 only: install latest ansible before firewall orchestrator installation +3) Ansible installation + +Make sure you have ansible version 2.13 or above installed on your system (check with "ansible --version"). +If this is not the case, install a newer ansible. One possible way is to run the following script: - cd firewall-orchestrator; ansible-playbook scripts/install-latest-ansible.yml -K + cd firewall-orchestrator + source scripts/install-ansible-from-venv.sh - - All platforms: install galaxy collections +Note that if your server is behind a proxy, you will have to set the proxy for pip as follows (to allow for ansible venv download): - ansible-galaxy collection install community.postgresql + pip config set global.proxy http://YOUR-PROXY-NAME:YOUR-PROXY-PORT -4) install (on localhost) +4) Firewall Orchestrator installation ```console cd firewall-orchestrator; ansible-playbook site.yml -K @@ -59,6 +74,11 @@ ok: [install-srv] => { PLAY RECAP ********************************************************************* install-srv : ok=302 changed=171 unreachable=0 failed=0 skipped=127 rescued=0 ignored=0 ``` -Simply navigate to and login with user 'admin' and the UI admin password. +Simply navigate to and login with user 'admin' and the UI admin password displayed by the install script (see above). + +The api hasura admin secret can be used to access the API at . + + +If using the python venv method, you may now exit venv with: -The api hasura admin secret can be used to access the API at . + deactivate diff --git a/documentation/installer/install-advanced.md b/documentation/installer/install-advanced.md index 475701aaf4..4883614360 100644 --- a/documentation/installer/install-advanced.md +++ b/documentation/installer/install-advanced.md @@ -1,34 +1,44 @@ # Advanced installation options -always change into the firewwall-orchestrator directory before starting the installation! +always change into the firewwall-orchestrator directory before starting the installation. ## Install parameters ### Installation mode parameter -The following switch can be used to set the type of installation to perform +installation_mode options: +- new (default) - assumes that no fworch is installed on the target devices - fails if it finds an installation +- uninstall - uninstalls the product including any data (database, ldap, files)! +- upgrade - installs on top of an existing system preserving any existing data in ldap, database, api; removes all files from target and copies latest sources instead + +#### Upgrading #### + +If you have an ansible version less than 2.13 on your machine, before doing an upgrade, switch into the virtual pyhton environment you created during installation before running the upgrade: ```console -ansible-playbook -e "installation_mode=upgrade" site.yml -K +cd ~/firewall-orchestrator +source ansible-venv/bin/activate ``` -If you want to drop the database and re-install from scratch, do the following: +Then for upgrading firewall orchestrator, use the following switch: ```console -ansible-playbook -e "installation_mode=uninstall" site.yml -K -ansible-playbook -e "installation_mode=new" site.yml -K +cd ~/firewall-orchestrator +ansible-playbook -e installation_mode=upgrade site.yml -K ``` -installation_mode options: -- new (default) - assumes that no fworch is installed on the target devices - fails if it finds an installation -- uninstall - uninstalls the product including any data (database, ldap, files)! -- upgrade - installs on top of an existing system preserving any existing data in ldap, database, api; removes all files from target and copies latest sources instead - +#### Uninstall #### +If you want to drop the database and re-install from scratch, do the following: + +```console +ansible-playbook -e installation_mode=uninstall site.yml -K +ansible-playbook site.yml -K +``` ### Installation behind a proxy (no direct Internet connection) By default, during installation or upgrade the proxy settings are read from the OS environment of the installer host. -For example you may have a global system-wide config file /etc/profile.d/proxy.sh with the following content: +For example you may either use /etc/environment or add a global system-wide config file /etc/profile.d/proxy.sh and add the following content: ```console export http_proxy=http://proxy.int:3128 @@ -39,7 +49,7 @@ export no_proxy=127.0.0.1,localhost Also make sure that your proxy is configured in your .gitconfig to be able to do the initial repo cloning. See https://gist.github.com/evantoli/f8c23a37eb3558ab8765. -If instead you need to individually set a proxy before installation/upgrade, use the following comamnds in your terminal: +If instead you need to individually set a proxy before installation/upgrade, use the following commands in your terminal: ```console export http_proxy=http://proxy.int:3128 export https_proxy=http://proxy.int:3128 @@ -51,24 +61,70 @@ Use the following syntax for authenticated proxy access: export http_proxy=http://USERNAME:PASSWORD@proxy.int:8080/ -Note that the following domains must be reachable through the proxy: +If you use Debian you need to additionally specify the proxy for apt in: + + sudo vim.tiny /etc/apt/apt.conf.d/proxy.conf - cactus.de (only for downloading test data, not needed if run with "--skip-tags test") +Add the following lines with your proxy and port: +```console +Acquire::http::Proxy "http://proxy_server:port/"; +Acquire::https::Proxy "http://proxy_server:port/"; +``` + +If you use authentication: + + Acquire::http::Proxy "http://user:password@proxy_server:port/"; + +Note that the following domains (and their sub-domains) must be reachable through the proxy: + + cactus.de (and sub-Domains, only for downloading test data, not needed if run with "--skip-tags test") ubuntu.com canonical.com - github.com + github.com, api.github.com githubusercontent.com - docker.com - docker.io - hasura.io - ansible.com + docker.io (and subdomains) + hasura.io, releases.hasura.io postgresql.org - microsoft.com - nuget.org + microsoft.com + nuget.org, api.nuget.org + googlechromelabs.github.io + storage.googleapis.com + pypi.org + pythonhosted.org (and sub-domains) + snapcraft.io, api.snapcraft.io + snapcraftcontent.com (and sub-domains) + +#### For vscode-debugging only - most are needed for downloading extensions + visualstudio.com (and subdomains) + vsassets.io (and subdomains) + digicert.com (and subdomains) + dot.net (and subdomains) + windows.net (and subdomains) + applicationinsights.azure.com (and subdomains) + exp-tas.com (and subdomains) + +#### Pyhton proxy config + +Remember if your server resides behind a proxy that you will have to set the proxy for pip as follows before installing ansible: + + pip config set global.proxy http://proxy:3128 + -NB: for vscode-debugging, you also need access to +In case of timeout issues (you might be behind a security proxy that does intensive scanning), try to install ansible using the command: - visualstudio.com + pip --default-timeout=3600 install ansible + +##### issues with existing pip config + +In case of errors with existing pip config, do not use the script to create the venv but proceed as follows: + +remove any local pip config and install manually: + + rm -f $HOME/.config/pip/pip.conf + python3 -m venv installer-venv + source installer-venv/bin/activate + pip install -r requirements.txt + pip install ansible ### Parameter "api_no_metadata" to prevent meta data import @@ -83,6 +139,14 @@ ansible-playbook -e "api_no_metadata=yes" site.yml -K ansible-playbook -e "force_install=yes" site.yml -K ``` +### Parameter "docker_network" after the Podman migration + +This legacy parameter is ignored by the current installer because Hasura now runs with Podman host networking instead of a Docker bridge. + +```console +ansible-playbook -e "docker_network=172.26.0.1/16" site.yml -K +``` + ### Parameter "install_syslog" allows disabling of separate syslog installation Default value is install_syslog=yes but if you already have a syslog service running then you can skip syslog installation and configure your existing service manually. @@ -137,13 +201,6 @@ rsyslog config maxsize 4096k missingok copytruncate - sharedscripts - prerotate - systemctl stop {{ product_name }}-importer-legacy.service >/dev/null 2>&1 - endscript - postrotate - systemctl start {{ product_name }}-importer-legacy.service >/dev/null 2>&1 - endscript } ``` @@ -271,18 +328,15 @@ put the hosts into the correct section (`[frontends]`, `[backends]`, `[importers make sure all target hosts meet the requirements for ansible (user with pub key auth & full sudo rights) -modify isohome/etc/iso.conf on frontend(s) - only needed for legacy (perl-based) importers: - enter the address of the database backend server, e.g. ```console fworch database hostname 10.5.10.10 ``` -modify /etc/postgresql/x.y/main/pg_hba.conf to allow secuadmins access from web frontend(s), e.g. +modify /etc/postgresql/x.y/main/pg_hba.conf to allow dbadmin access from web frontend(s), e.g. ```console -host all +secuadmins 127.0.0.1/32 md5 -host all +secuadmins 10.5.5.5/32 md5 + host all dbadmin 10.5.10.10/32 md5 ``` diff --git a/documentation/installer/install-for-testing.md b/documentation/installer/install-for-testing.md index defd370400..7a5720c4c8 100644 --- a/documentation/installer/install-for-testing.md +++ b/documentation/installer/install-for-testing.md @@ -12,7 +12,7 @@ This includes: Note: the relevant secrets are displayed at the very end of the installation. They can also be found in the etc/secrets directory. ```console -ansible-playbook/ site.yml -e "testkeys=yes" -K +ansible-playbook site.yml -e "testkeys=yes" -K ``` A static jwt key helps with debugging c# code in visual studio (code) - you can use a static backend (ldap & api) with these keys. @@ -29,30 +29,37 @@ You need to ## Debugging -Set debug level for extended debugging info during installation. +Set dotnet installation mode to "debug" as follows (default = Release) +### Debugging dotnet applications +```console +ansible-playbook/ site.yml -e "dotnet_mode=Debug" -K +``` +Set debug level for extended debugging info during installation. ```console ansible-playbook site.yml -e "debug_level='2'" -K +``` + +## Running unit tests after installation/upgrade + +To only run unit tests (for an existing installation only to be used in comination with installation_mode=upgrade) use tags as follows: -Set dotnet installation mode to "debug" as follows (default = Release) -### Debugging dotnet applications ```console -ansible-playbook/ site.yml -e "dotnet_mode=Debug" -K +ansible-playbook site.yml --tags unittests -K ``` + ## Running integration tests after installation/upgrade -To only run tests (for an existing installation) use tags as follows: +To only run integration tests (for an existing installation only to be used in comination with installation_mode=upgrade) use tags as follows: ```console -ansible-playbook site.yml --tags test -K +ansible-playbook site.yml --tags integrationtests -K ``` -## Running unit tests only - -To only run tests (for an existing installation, can only be combined with installation_mode=upgrade) use tags as follows: +## Running installation without any tests ```console -ansible-playbook site.yml --tags unittest -e "installation_mode=upgrade" -K +ansible-playbook site.yml -K --skip-tags unittests,integrationtests ``` ## Parameter "api_no_metadata" to prevent meta data import diff --git a/documentation/interface-descriptions-json/firewall-normalized-config-format.md b/documentation/interface-descriptions-json/firewall-normalized-config-format.md new file mode 100644 index 0000000000..1559dee3da --- /dev/null +++ b/documentation/interface-descriptions-json/firewall-normalized-config-format.md @@ -0,0 +1,121 @@ +# Normalized Firewall Config Interface + +Firewall configurations are imported through the normalized JSON format shown +in the two samples inside this directory. Both the single-manager and +multi-manager examples use the same schema, which is described below. + +## Top-Level Envelope + +```json +{ + "ConfigFormat": "NORMALIZED", + "ManagerSet": [ { /* manager */ } ], + "native_config": { } +} +``` + +| Field | Type | Required | Description | +|----------------|----------|----------|-------------| +| `ConfigFormat` | string | yes | Always `NORMALIZED`. | +| `ManagerSet` | object[] | yes | Collection of manager definitions. Each manager contains a batch of configuration objects. | +| `native_config`| object | no | Raw vendor payload (kept empty in the samples). | + +## Manager Definition + +There may be multiple managers in a single import file which belong to the same super-manager (including the super-manager itself). + +| Field | Type | Required | Description | +|-----------------|----------|----------|-------------| +| `ManagerUid` | string | yes | Unique identifier for the manager/adom. | +| `ManagerName` | string | yes | Display name (e.g., `forti-mgr cactus`). | +| `IsSuperManager`| boolean | yes | `true` if the entry aggregates sub-managers. | +| `DomainUid` | string | no | Vendor-specific domain identifier; empty if n/a. | +| `DomainName` | string | no | Human-readable domain name. | +| `SubManagerIds` | string[] | yes | IDs of delegated managers; empty array if none. | +| `Configs` | object[] | yes | Configuration batches imported for the manager. | + +## Config Batch + +There may be multiple configs per manager in the future but at the moment the only supported case is a single config awith action 'INSERT'. + +| Field | Type | Required | Description | +|-----------------|---------|----------|-------------| +| `ConfigFormat` | string | yes | `NORMALIZED` in the sample payloads. | +| `action` | string | yes | CRUD indicator (`INSERT`, `UPDATE`, ...). | +| `network_objects` | object | yes | Map of network objects keyed by UID. | +| `service_objects` | object | yes | Map of service objects keyed by UID. | +| `users` | object | yes | User directory entries keyed by UID (empty in samples). | +| `zone_objects` | object | yes | Map of zone definitions. | +| `rulebases` | array | yes | Rulebase segments assigned to the manager. | +| `gateways` | array | yes | Gateways/firewalls with rulebase links. | + +### `network_objects` entry + +| Field | Type | Description | +|-------------------|--------|-------------| +| `obj_uid` | string | Unique ID (matches the map key). | +| `obj_name` | string | Readable name. | +| `obj_ip` | string | Start IP or CIDR. | +| `obj_ip_end` | string | End IP for ranges. | +| `obj_color` | string | UI color metadata. | +| `obj_typ` | string | Object type (`network`, `host`, etc.). | +| `obj_member_refs` | array/string|null | References to nested objects. | +| `obj_member_names`| array/string|null | Human readable member names. | +| `obj_comment` | string|null | Optional comment. | + +### `service_objects` entry + +| Field | Type | Description | +|-------------------|--------|-------------| +| `svc_uid` | string | Unique ID (map key). | +| `svc_name` | string | Display name. | +| `svc_port` | integer|null | Start port. | +| `svc_port_end` | integer|null | End port (equals start for single ports). | +| `svc_color` | string | UI color metadata. | +| `svc_typ` | string | Service type (`simple`, `group`, ...). | +| `ip_proto` | integer | L4 protocol number. | +| `svc_member_refs` | array/string|null | Child object references. | +| `svc_member_names`| array/string|null | Child names. | +| `svc_comment` | string|null | Optional comment. | +| `svc_timeout` | integer|null | Optional timeout. | +| `rpc_nr` | integer|null | RPC metadata. | + +### Rulebase Segment + +| Field | Type | Description | +|-----------------|---------|-------------| +| `uid` | string | Rulebase identifier (map target for gateway links). | +| `name` | string | Display name. | +| `mgm_uid` | string | Owning manager UID. | +| `is_global` | boolean | Mark global sections. | +| `Rules` | object | Map of rule objects keyed by `rule_uid`. | + +Each rule entry contains metadata such as `rule_src`, `rule_dst`, `rule_svc`, +action, hit counters, zones, and audit fields (`last_change_admin`, etc.), +mirroring the properties shown in the samples. + +### Gateways + +| Field | Type | Description | +|----------------------|----------|-------------| +| `Uid` | string | Firewall identifier. | +| `Name` | string | Friendly name. | +| `Routing` | array | Route table data (empty in samples). | +| `Interfaces` | array | Interface metadata (empty in samples). | +| `RulebaseLinks` | object[] | Links that bind the gateway to rulebases. | +| `GlobalPolicyUid` | string | Optional reference. | +| `EnforcedPolicyUids` | string[] | Enforced access policies. | +| `EnforcedNatPolicyUids` | string[] | Enforced NAT policies. | +| `ImportDisabled` | boolean | Skip flag for UI. | +| `ShowInUI` | boolean | Whether to display the gateway. | + +`RulebaseLinks` specify the relationship between gateways and rulebases: +`to_rulebase_uid` contains the rulebase UID, `link_type` indicates ordering, +and the boolean flags describe whether the link is initial/global/section. + +## Operational Notes + +- Always deliver the full manager dataset; incremental imports are currently not supported. +- UID keys should remain stable so repeated imports update the same records. +- While the samples focus on IPv4 data, any object can contain IPv6 addresses + where the firmware supports them. diff --git a/documentation/interface-descriptions-json/ip-area-data-format.md b/documentation/interface-descriptions-json/ip-area-data-format.md new file mode 100644 index 0000000000..a652f32f26 --- /dev/null +++ b/documentation/interface-descriptions-json/ip-area-data-format.md @@ -0,0 +1,49 @@ +# IP Area Import Interface + +This interface loads network areas and their associated subnets. The payload +is documented by `documentation/interface-descriptions-json/sample-ip-data-normalized.json`. + +## Envelope + +```json +{ + "areas": [ + { /* area */ } + ] +} +``` + +## Area Object + +| Field | Type | Required | Description | +|-------------|----------|----------|-------------| +| `name` | string | yes | Human readable area label (`AREA51`). | +| `id_string` | string | yes | Unique technical identifier used for correlation. | +| `subnets` | object[] | yes | List of subnet records attached to the area. | + +### Subnet Entry + +| Field | Type | Required | Description | +|-------|--------|----------|-------------| +| `ip` | string | yes | Network in CIDR notation (IPv4 or IPv6). | +| `name`| string | yes | Friendly subnet name. | + +Example: + +```json +{ + "name": "AREA51", + "id_string": "NA51", + "subnets": [ + { "ip": "10.10.10.0/24", "name": "Netz01" }, + { "ip": "10.10.34.16/30", "name": "Netz02" } + ] +} +``` + +## Validation Notes + +- Every area requires at least one subnet. +- Subnet CIDR strings must be canonical; overlapping subnets are technically + allowed but should be avoided to keep reporting deterministic. +- Imports replace the full dataset. Incremental subnet updates are not supported. diff --git a/documentation/interface-descriptions-json/owner-data-format.md b/documentation/interface-descriptions-json/owner-data-format.md new file mode 100644 index 0000000000..8fa0ccbce9 --- /dev/null +++ b/documentation/interface-descriptions-json/owner-data-format.md @@ -0,0 +1,90 @@ +# Owner Import Interface + +The owner interface supplies metadata about business applications, their +responsible people, and the server addresses attached to every application. +The data is exchanged as a JSON document that follows the structure shown in +`documentation/interface-descriptions-json/sample-owner-data-normalized.json`. +This document explains the structure so integrators can generate valid input. + +## Top-Level Envelope + +```json +{ + "owners": [ + { /* owner definition */ } + ] +} +``` + +The payload is a single object with one property: + +| Property | Type | Description | +|----------|--------|-------------| +| `owners` | array | All application owner records. The order is not relevant, but every object inside the array must follow the schema described below. | + +## Owner Object + +| Field | Type | Required | Description | +|--------------------|----------|----------|-------------| +| `name` | string | yes | Unique owner identifier inside the import. Usually matches the CMDB application name. | +| `app_id_external` | string | yes | External system identifier (example `APP-4711`). Used to correlate repeated imports. | +| `main_user` | string | yes | Distinguished Name (DN) of the responsible owner. | +| `modellers` | string[] | yes | DNs of groups or users who can modify the application definition. | +| `recert_interval` | integer | yes | Number of days between mandatory recertifications. | +| `import_source` | string | yes | Origin of the record, e.g., `cmdb-export`. Helps auditors trace the data lineage. | +| `app_servers` | object[] | yes | Server definitions that represent the application infrastructure. See below. | + +Example: + +```json +{ + "name": "owner-1", + "app_id_external": "APP-4711", + "main_user": "CN=tiso4711,OU=Benutzer,DC=company,DC=DE", + "modellers": ["CN=app-4711-eigner,OU=Gruppen,DC=company,DC=DE"], + "recert_interval": 180, + "import_source": "cmdb-export", + "app_servers": [ /* … */ ] +} +``` + +## `app_servers` Entries + +`app_servers` is an array that enumerates every IP element (host, network, or +range) assigned to an application owner. Each entry uses the following fields: + +| Field | Type | Required | Description | +|----------|--------|----------|-------------| +| `ip` | string | yes | Starting IP in IPv4 or IPv6 notation. | +| `ip_end` | string | yes | Last IP in the block. Equal to `ip` for single hosts. | +| `type` | string | yes | Defines how the IP range is interpreted. Supported values are listed below. | +| `name` | string | no | Friendly identifier for the block. Mandatory only when the type is `host`. | + +### Supported `type` values + +| Value | Meaning | +|----------|---------| +| `host` | Single IP. `ip` and `ip_end` must be identical. `name` carries the host label (`host_10.12.16.88` in the sample). | +| `network`| Subnet definition. `ip` is the network start and `ip_end` is the broadcast/high address. | +| `range` | Arbitrary inclusive range from `ip` to `ip_end`. | + +Example block: + +```json +{ + "ip": "10.112.5.88", + "ip_end": "10.112.5.99", + "type": "range" +} +``` + +## Validation Checklist + +- Every owner must have at least one `app_servers` entry. +- `ip` and `ip_end` must be valid IPv4 or IPv6 addresses. +- Use consistent casing for DNs to avoid duplicate detection issues. +- Keep the input idempotent: repeatable imports must keep the same + `app_id_external` values. +- Imports must contain the full dataset. Incremental updates are not supported; + each run replaces the previous definition. +- Missing IP objects are not deleted but marked as removed and can be reactivated when contained in a consecutive import. diff --git a/documentation/interface-descriptions-json/sample-firewall-normalized-config-multi-manager.json b/documentation/interface-descriptions-json/sample-firewall-normalized-config-multi-manager.json new file mode 100644 index 0000000000..c03f54a3e3 --- /dev/null +++ b/documentation/interface-descriptions-json/sample-firewall-normalized-config-multi-manager.json @@ -0,0 +1,177 @@ +{ + "ConfigFormat": "NORMALIZED", + "ManagerSet": [ + { + "ManagerUid": "forti-mgr cactus", + "ManagerName": "forti-mgr cactus", + "IsSuperManager": true, + "DomainUid": "", + "DomainName": "", + "SubManagerIds": [], + "Configs": [ + { + "ConfigFormat": "NORMALIZED", + "action": "INSERT", + "network_objects": { + "fb6dc52c-a40e-51f0-58af-1e9bdb08123e": { + "obj_uid": "fb6dc52c-a40e-51f0-58af-1e9bdb08123e", + "obj_name": "gEMS_ALL_UNKNOWN_CLIENTS", + "obj_ip": "0.0.0.0/32", + "obj_ip_end": "255.255.255.255/32", + "obj_color": "black", + "obj_typ": "network", + "obj_member_refs": null, + "obj_member_names": null, + "obj_comment": null + } + }, + "service_objects": { + "gblock-high-risk": { + "svc_uid": "gblock-high-risk", + "svc_name": "gblock-high-risk", + "svc_port": null, + "svc_port_end": null, + "svc_color": "foreground", + "svc_typ": "simple", + "ip_proto": 0, + "svc_member_refs": null, + "svc_member_names": null, + "svc_comment": null, + "svc_timeout": null, + "rpc_nr": null + } + }, + "users": {}, + "zone_objects": { + "any": { + "zone_name": "any" + }, + "dmz": { + "zone_name": "dmz" + } + }, + "rulebases": [], + "gateways": [] + } + ] + }, + { + "ManagerUid": "25952584-ae41-51f0-0c4e-cd435e7407a6", + "ManagerName": "forti-mgr cactus_my_adom", + "IsSuperManager": false, + "DomainUid": "", + "DomainName": "my_adom", + "SubManagerIds": [], + "Configs": [ + { + "ConfigFormat": "NORMALIZED", + "action": "INSERT", + "network_objects": { + "4340e634-add5-51f0-f96e-1a939e4c3326": { + "obj_uid": "4340e634-add5-51f0-f96e-1a939e4c3326", + "obj_name": "gmail.com", + "obj_ip": "0.0.0.0/32", + "obj_ip_end": "255.255.255.255/32", + "obj_color": "black", + "obj_typ": "network", + "obj_member_refs": null, + "obj_member_names": null, + "obj_comment": "IPv4 addresses of Fabric Devices." + } + }, + "service_objects": { + "block-high-risk": { + "svc_uid": "block-high-risk", + "svc_name": "block-high-risk", + "svc_port": 1234, + "svc_port_end": 1234, + "svc_color": "foreground", + "svc_typ": "simple", + "ip_proto": 6, + "svc_member_refs": null, + "svc_member_names": null, + "svc_comment": null, + "svc_timeout": null, + "rpc_nr": null + } + }, + "users": {}, + "zone_objects": { + "1-A1": { + "zone_name": "1-A1" + }, + "dmz": { + "zone_name": "dmz" + } + }, + "rulebases": [ + { + "id": null, + "uid": "rules_adom_v4_mypkg", + "name": "rules_adom_v4_mypkg", + "mgm_uid": "25952584-ae41-51f0-0c4e-cd435e7407a6", + "is_global": false, + "Rules": { + "3fa82664-5717-4562-b3fc-2c963f66afa6": { + "rule_num": 1, + "rule_num_numeric": 0.0, + "rule_disabled": false, + "rule_src_neg": false, + "rule_src": "gmail.com", + "rule_src_refs": "4340e634-add5-51f0-f96e-1a939e4c3326", + "rule_dst_neg": false, + "rule_dst": "gmail.com", + "rule_dst_refs": "4340e634-add5-51f0-f96e-1a939e4c3326", + "rule_svc_neg": false, + "rule_svc": "block-high-risk", + "rule_svc_refs": "block-high-risk", + "rule_action": "accept", + "rule_track": "none", + "rule_installon": "rules_adom_v4_mypkg", + "rule_time": "", + "rule_name": "my combined nat rule", + "rule_uid": "3fa82664-5717-4562-b3fc-2c963f66afa6", + "rule_custom_fields": "{}", + "rule_implied": false, + "rule_type": "access", + "last_change_admin": "tim", + "parent_rule_uid": null, + "last_hit": null, + "rule_comment": null, + "rule_src_zone": "dmz", + "rule_dst_zone": "dmz", + "rule_head_text": null + } + } + } + ], + "gateways": [ + { + "Uid": "fg1_root", + "Name": "fg1_root", + "Routing": [], + "Interfaces": [], + "RulebaseLinks": [ + { + "from_rulebase_uid": null, + "from_rule_uid": null, + "to_rulebase_uid": "rules_adom_v4_mypkg", + "link_type": "ordered", + "is_initial": true, + "is_global": false, + "is_section": false + } + ], + "GlobalPolicyUid": null, + "EnforcedPolicyUids": [], + "EnforcedNatPolicyUids": [], + "ImportDisabled": false, + "ShowInUI": true + } + ] + } + ] + } + ], + "native_config": {} +} diff --git a/documentation/interface-descriptions-json/sample-firewall-normalized-config-single-manager.json b/documentation/interface-descriptions-json/sample-firewall-normalized-config-single-manager.json new file mode 100644 index 0000000000..8f88109d37 --- /dev/null +++ b/documentation/interface-descriptions-json/sample-firewall-normalized-config-single-manager.json @@ -0,0 +1,114 @@ +{ + "ConfigFormat": "NORMALIZED", + "ManagerSet": [ + { + "ManagerUid": "25952584-ae41-51f0-0c4e-cd435e7407a6", + "ManagerName": "cp-single-mgr", + "IsSuperManager": false, + "DomainUid": "", + "DomainName": "", + "SubManagerIds": [], + "Configs": [ + { + "ConfigFormat": "NORMALIZED", + "action": "INSERT", + "network_objects": { + "4340e634-add5-51f0-f96e-1a939e4c3326": { + "obj_uid": "4340e634-add5-51f0-f96e-1a939e4c3326", + "obj_name": "gmail.com", + "obj_ip": "0.0.0.0/32", + "obj_ip_end": "255.255.255.255/32", + "obj_color": "black", + "obj_typ": "network", + "obj_member_refs": null, + "obj_member_names": null, + "obj_comment": "IPv4 addresses of Fabric Devices." + } + }, + "service_objects": { + "block-high-risk": { + "svc_uid": "block-high-risk", + "svc_name": "block-high-risk", + "svc_port": 1234, + "svc_port_end": 1234, + "svc_color": "foreground", + "svc_typ": "simple", + "ip_proto": 6, + "svc_member_refs": null, + "svc_member_names": null, + "svc_comment": null, + "svc_timeout": null, + "rpc_nr": null + } + }, + "users": {}, + "zone_objects": {}, + "rulebases": [ + { + "id": null, + "uid": "section1", + "name": "section1", + "mgm_uid": "25952584-ae41-51f0-0c4e-cd435e7407a6", + "is_global": false, + "Rules": { + "3fa82664-5717-4562-b3fc-2c963f66afa6": { + "rule_num": 1, + "rule_num_numeric": 0.0, + "rule_disabled": false, + "rule_src_neg": false, + "rule_src": "gmail.com", + "rule_src_refs": "4340e634-add5-51f0-f96e-1a939e4c3326", + "rule_dst_neg": false, + "rule_dst": "gmail.com", + "rule_dst_refs": "4340e634-add5-51f0-f96e-1a939e4c3326", + "rule_svc_neg": false, + "rule_svc": "block-high-risk", + "rule_svc_refs": "block-high-risk", + "rule_action": "accept", + "rule_track": "none", + "rule_installon": "rules_adom_v4_mypkg", + "rule_time": "", + "rule_name": "my combined nat rule", + "rule_uid": "3fa82664-5717-4562-b3fc-2c963f66afa6", + "rule_custom_fields": "{}", + "rule_implied": false, + "rule_type": "access", + "last_change_admin": "tim", + "parent_rule_uid": null, + "last_hit": null, + "rule_comment": null, + "rule_head_text": null + } + } + } + ], + "gateways": [ + { + "Uid": "fg1_root", + "Name": "fg1_root", + "Routing": [], + "Interfaces": [], + "RulebaseLinks": [ + { + "from_rulebase_uid": null, + "from_rule_uid": null, + "to_rulebase_uid": "section1", + "link_type": "ordered", + "is_initial": true, + "is_global": false, + "is_section": false + } + ], + "GlobalPolicyUid": null, + "EnforcedPolicyUids": [], + "EnforcedNatPolicyUids": [], + "ImportDisabled": false, + "ShowInUI": true + } + ] + } + ] + } + ], + "native_config": {} +} diff --git a/documentation/interface-descriptions-json/sample-ip-data-normalized.json b/documentation/interface-descriptions-json/sample-ip-data-normalized.json new file mode 100644 index 0000000000..3cbc59b4ab --- /dev/null +++ b/documentation/interface-descriptions-json/sample-ip-data-normalized.json @@ -0,0 +1,32 @@ +{ + "areas": [ + { + "name": "AREA51", + "id_string": "NA51", + "subnets": [ + { + "ip": "10.10.10.0/24", + "name": "Netz01" + }, + { + "ip": "10.10.34.16/30", + "name": "Netz02" + } + ] + }, + { + "name": "AREA52", + "id_string": "NA52", + "subnets": [ + { + "ip": "10.20.10.0/24", + "name": "Netz03" + }, + { + "ip": "10.20.34.128/25", + "name": "Netz04" + } + ] + } + ] +} diff --git a/documentation/interface-descriptions-json/sample-owner-data-normalized.json b/documentation/interface-descriptions-json/sample-owner-data-normalized.json new file mode 100644 index 0000000000..faa1e345ed --- /dev/null +++ b/documentation/interface-descriptions-json/sample-owner-data-normalized.json @@ -0,0 +1,46 @@ +{ + "owners": [ + { + "name": "owner-1", + "app_id_external": "APP-4711", + "main_user": "CN=tiso4711,OU=Benutzer,DC=company,DC=DE", + "modellers": ["CN=app-4711-eigner,OU=Gruppen,DC=company,DC=DE"], + "recert_interval": 180, + "import_source": "cmdb-export", + "app_servers": [ + { + "ip": "10.12.16.88", + "ip_end": "10.12.16.88", + "type": "host", + "name": "host_10.12.16.88" + }, + { + "ip": "10.14.0.128", + "ip_end": "10.14.0.255", + "type": "network" + } + ] + }, + { + "name": "owner-2", + "app_id_external": "APP-4712", + "main_user": "CN=tiso4712,OU=Benutzer,DC=company,DC=DE", + "modellers": ["CN=app-4712-eigner,OU=Gruppen,DC=company,DC=DE"], + "recert_interval": 365, + "import_source": "cmdb-export", + "app_servers": [ + { + "ip": "10.112.16.88", + "ip_end": "10.112.16.88", + "type": "host", + "name": "host_10.112.16.88" + }, + { + "ip": "10.112.5.88", + "ip_end": "10.112.5.99", + "type": "range" + } + ] + } + ] +} diff --git a/documentation/revision-history-develop.md b/documentation/revision-history-develop.md index fb12ae0132..83a81e3e57 100644 --- a/documentation/revision-history-develop.md +++ b/documentation/revision-history-develop.md @@ -78,3 +78,325 @@ In 2020 we decided to re-launch a new ### 6.5.1 24.07.2023 DEVELOP - New report type Unused Rules +### 7.0.1 - 28.07.2023 DEVELOP +- Compliance matrix edit fix +- Logout audit logging fix + +### 7.0.2 - 28.07.2023 DEVELOP +- Default templates for new report types + +### 7.1 - 11.08.2023 DEVELOP +- adding tenant network UI +- adding test import via URI in hostname field +- replacing legacy demo data import with standard imported data, closing #2197 (note: only for new installations, an upgrade will not touch the demo data) +- test imports can now be made from file (integrated in UI) +- improve debugging of imports (no errors for missing object parts) + +### 7.1.1 - 15.08.2023 DEVELOP +- fixes upgrade bug on systems without demo data + +### 7.1.2 - 16.08.2023 DEVELOP +- adding Check Point R8x Inform action + +### 7.2 - 21.08.2023 DEVELOP +mostly version update summarizing latest PRs +- UI/API: adding tenant ip filtering beta version (clean-up and optiomazation necessary) +- API: updating hasura to 2.32.0 +- UI: now not showing super managers in RSB all tab +- UI: bug fixes blazor environment settings + - Use production / development based on the build type instead of always using development. + - Do not show detailed errors in production mode. + - Use the custom error page in the production environment. + - Spelling mistake fix +- UI: bug fix jwt expiry + - jwt expiry timer now works as intended + - after the jwt expired no exception can be triggered anymore + +### 7.2.1 - 11.09.2023 DEVELOP +- new settings option for rule ownership mode +### 7.2.2 - 15.09.2023 DEVELOP +- complete re-work: all ip addresses are now internally represented as ranges, including all networks +### 7.2.3 - 29.09.2023 DEVELOP +bugfix release: +- api - upgrade hasura to 2.33.4 +- installer - fix client/server db sort order mismatch (collate) +- adding simulated changes to fwodemodata (fortiate) +- importer - fix in fortiOS importer action field +- UI + - fix settings owner networks editing and displaying + - recert report (and recert page) IP addresses now also simplified like an other reports + - fix broken links in recert page +### 7.2.4 - 04.10.2023 DEVELOP +- new role modeller +- new mechanism for overwriting texts +# 7.2.5 - 05.10.2023 DEVELOP +- importer + - adding more error debugging in CPR8x importer + - adding new network object type 'external-gateway' (for interoperable-dervice in check point) + - fix fortimanager importer: ignore missing negate fields +- middleware & ui: add check for successful publishing dotnet +- middlware: fix upgrade become issue in middleware ldif files +- database: fix postgresql_query module reference + +# 7.2.6 - 06.10.2023 DEVELOP +- importer Checkpoint: adding network object type support for 'CpmiVsClusterNetobj' (for VSX virtual switches) + +# 7.3 - 22.10.2023 DEVELOP +- cleanup unused database views and functions +- first working tenant ip-based filtering + +# 7.3.1 - 26.10.23 DEVELOP +- introducing unfiltered_managements and devices for tenant filtering +- fixing missing api perms fw-admin (management) +- rename management & device tenat_id fields to unfiltered_tenant_id +- fixing UI device selector crashes + +# 7.3.2 - 09.12.2023 DEVELOP +- Modelling first version + +# 7.3.3 - 08.01.2024 DEVELOP +- Moving to vanilla bootstrap css v5.3.2 +- adding extended tenant to device mapping settings (depending on latest bootstrap version) - closes #2280 +- fix for log locking for import process + +# 7.3.4 - 09.01.2024 DEVELOP +- Scheduled import change notification + +# 7.3.5 - 15.01.2024 DEVELOP +- importer log locking fix (only fixing import stopping so far) +- import change notification: + - DB extensions import_control.security_relevant_changes_counter + - removing python import notification + - writing to change counter after import (inpreparation for notification enhancement) +- importer demo tenant device mapping additions (upgrade) +- installer: introducing venv for newer ansible versions and thereby removing version handling + +# 7.3.6 - 23.01.2024 DEVELOP +- common service handling +- fixes credentials when installing without demo data +- fix error with pdf creation on debian testing + +# 8.0.1 - 20.02.2024 DEVELOP +- iconify modelling +- add missing config values + +# 8.0.2 - 11.03.2024 DEVELOP +- first version of NSX import module + +# 8.0.3 - 08.04.2024 DEVELOP +- add maintenance page during upgrade +- sample customizing py script with sample data, closes Installer customizable config (settings) #2275 +- remove log locking from importer due to stalling importer stops +- credentials encryption, closes encrypt passwords and keys #1508 + - breaking change for developer debugging: add the following local file when using -e testkeys=true: + /etc/fworch/secrets/main_key with content "not4production..not4production.." +- add custom (user-defined) fields to import + - cp only so far, other fw types missing + - user-defined fields are not part of reports yet + +# 8.1.1 - 15.04.2024 DEVELOP +- interface request workflow first version + +# 8.1.2 - 22.04.2024 DEVELOP +- encrypt emailPassword in config +- fix demo managements (change import from deactivated to activated - does not affect test managements) +- upgrade to dotnet 8.0 +- adding all imported modelling users to uiuser + +# 8.2.1 - 03.05.2024 DEVELOP +- fix misleading login error message when authorisation is missing + +# 8.2.2 - 14.05.2024 DEVELOP +- fix email credential decryption +- start of Tufin SecureChange integration + +# 8.2.3 - 26.05.2024 DEVELOP +- remove cascading delete for used interfaces +- new properties field in connections + +# 8.2.4 - 19.06.2024 DEVELOP +- owner-filtering for new report type +- new setting for email recipients + +# 8.3.1 - 08.07.2024 DEVELOP +- workflow: external state handling +- fix config value +- remove uniqueness of owner names + +# 8.3.2 - 09.09.2024 DEVELOP +- Added welcome message and settings + +# 8.4.1 - 15.10.24 DEVELOP +- Add missing FK connection.proposed_app_id #2591 + +# 8.4.2 - 17.10.2024 DEVELOP +- external request + +# 8.4.3 - 05.11.2024 DEVELOP +- extra parameters in modelling connection + +# 8.5.1 - 18.11.2024 DEVELOP +- reporting - fixing PDF generation on various platforms +- modelling - fixing AR editing: strict prevention of all area mixing + +# 8.5.2 - 27.11.2024 DEVELOP +- some check point importer fixes + - 4 new colors + - added Internet object + - added voip one more object + +# 8.5.3 - 27.11.2024 DEVELOP +- owner import - make ldap selectable (internal/external) +- small fixes regarding missing config data for two schedulers (daily, app data import) + +# 8.5.4 - 04.12.2024 DEVELOP +- external request: introduce wait cycles + +# 8.6.1 - 12.12.2024 DEVELOP +- external request: introduce locks + +# 8.6.3 - 20.02.2025 DEVELOP +- dns lookup for app server names + +# 8.7.1 - 05.03.2025 DEVELOP +- ldap writepath for groups + demo data (major versions only) +# 8.7.2 - 20.03.2025 DEVELOP +- new config values +- external request: attempt counter + +# 8.8.2 - 07.05.2025 DEVELOP +- displayed state via variance analysis + +# 8.8.3 - 15.05.2025 DEVELOP +- deactivation of connections + +# 8.8.4 - 02.06.2025 DEVELOP +- hotfix for Check Point importer suppor for DLP actions (ask, inform) + +# 8.8.5 - 17.06.2025 DEVELOP +- new enum values for Request Element Field Types +- hotfix change recognition: separate rule changes and "all changes" to make object version handling work properly + +# 8.8.6 - 08.07.2025 DEVELOP +- hotfix CP importer new stm_track: "extended log" and "detailed log" + +# 8.8.8 - 21.08.2025 DEVELOP +- add read-only db user fwo_ro +- also reducing db listener to localhost and other hardening changes + +# 8.8.9 - 27.08.2025 DEVELOP +- prepare tables + settings for owner recert + first throw recert popup +- notification service +- decommissioning of interfaces +- iconification of modelling and related modules +- fix overwrite of objects with interface + +## 8.8.10 - 07.09.2025 DEVELOP +- new report type owner-recertification + +## 8.9.1 - 02.10.2025 DEVELOP +- owner-recertification + +## 8.9.2 - 17.10.2025 DEVELOP +- add ownerLifeCycleState +- add manageable ownerLifeCycleState menu +- fix two modelling ui glitches + +## 8.9.3 - 05.11.2025 DEVELOP +- hotfix missing permissions for app data import in certain constellations + +## 8.9.4 - 09.12.2025 DEVELOP +- bugfix release: common service connection not editable +- new custom scripts for iiq and cmdb import + +## 8.9.5 - 10.12.2025 DEVELOP +- bugfix release: modelling - change planning showed duplicate NA elements for rule delete requests + +## 8.9.6 - 05.01.2026 DEVELOP +- new parameters for notifications + +# 9.0 - 24.01.2026 DEVELOP +A complete 80K lines rework of FWO, including +- database changes to deduplicate rules (rule to gateway mapping now 1:n by introducing rulebase and rulebase_link tables) +- migrating import module from mixed python/pgsql to pure python + +# 9.0.1 - 07.02.2026 DEVELOP +- generalized owner responsibles with configurable responsible types +- add allow_write_access to responsible types to control modelling and recertification + +# 9.0.2 - 10.02.2026 DEVELOP +- importer: call api chunked where needed + +**Breaking changes** +- Due to introduction of venv for all imports, the following steps have to be taken to manually import a config: + +```shell + sudo -u fworch -i + cd importer + source importer-venv/bin/activate + python3 ./import_mgm.py -m xy -fs -d1 +``` + As we now need support for pip, in installations behind url filter, make sure that all sub-domains of "pythonhosted.org" are also allowed. + +- Limiting database listener to localhost for security reasons + +## 9.0.3 - 12.02.2026 DEVELOP +- introduce interface permissions + +## 9.0.4 - 13.02.2026 DEVELOP +- maintenance release with explicit 9.0.4 upgrade step + +# 9.0.5 - 18.02.2026 DEVELOP +- update rule_owner table for REST api +- update import_control to allow flexible tracking of different import types +- create rule_owner mapping for custom_field via button and service/job +- update import_control to allow flexible tracking of different import types + +# 9.0.6 - 20.02.2026 DEVELOP +- add import of time objects + +# 9.0.7 - 25.02.2026 DEVELOP +- add import of time objects +- create changelog_owner table + +# 9.0.8 - 25.02.2026 DEVELOP +- new config value for removed App Server handling + +# 9.0.10 - 28.02.2026 DEVELOP +- new config value for User synchronization in owner data import + +# 9.0.11 - 04.03.2026 DEVELOP +- new config value for requesting only own objects + +# 9.0.12 - 12.03.2026 DEVELOP +- new config values for rule expiry notification + +# 9.0.13 - 12.03.2026 DEVELOP +- mark lifecycle states as active + +# 9.0.14 - 17.03.2026 DEVELOP +- prepare owner decommission notification + +# 9.0.15 - 19.03.2026 DEVELOP +- rename OwnerSourceCustomFieldKey to CustomFieldOwnerKey in config + +# 9.0.16 - 31.03.2026 DEVELOP +- remove not needed stm_owner_mapping_source +- add Full re-initialize of RuleOwner mapping for IP-based rules +- add matched_objects field in rule_owner table for track matched objects - IpBased + +# 9.0.18 - 03.04.2026 DEVELOP +- add new column automatic_only to workflow states + +# 9.0.19 - 09.04.2026 DEVELOP +- add owner additional_info jsonb field including owner edit UI support + +# 9.0.20 - 11.04.2026 DEVELOP +- extend notification handling + +# 9.0.21 - 21.04.2026 DEVELOP +- fix ldap users with special chars not being processed correctly in role handling +- fix empty mail being sent for orphaned rule report +- update dependencies (notably closing mailkit and pytest vuln) +- fix time zone issues in importer diff --git a/documentation/revision-history-main.md b/documentation/revision-history-main.md index b16e04c6ea..755eaccfeb 100644 --- a/documentation/revision-history-main.md +++ b/documentation/revision-history-main.md @@ -311,3 +311,305 @@ adding report template format fk and permissions - demo data: fix sample group role path - adding demo video in github README.MD - splitting revision history into develop and main + +### 7.3 22.10.2023 MAIN +- new features + - recertification: new rule ownership + - customizable UI texts + - starting target state module with introducing new role "modeller" + - adding tenant ip filtering + - adding tenant simulation (exluding statistical report and recertification) including scheduling +- maintenance / bug-fixing + - complete re-work: all ip addresses are now internally represented as ranges, including all networks + - UI: + - do not show super managers in RSB all tab + - Use production / development based on the build type instead of always using development. + - do not show detailed errors in production mode + use the custom error page in the production environment + - bug fix jwt expiry, jwt expiry timer now works as intended + - unifying IP addresses display method across all parts + - fix filtering for rules with negated source / destination or single negated ip ranges + - Database: + - removing unused materialized view for tenant ip filtering + - Installer + - fix upgrade become issue in middleware ldif files + - fix client/server db sort order mismatch (collate) + - fix postgresql_query module reference + - adding simulated changes to fwodemodata (fortigate) + - add check for successful publishing dotnet (mw, ui) + - Importer + - fortiOS: fix importer action field + - fortimanager: ignore missing negate fields + - Check Point: adding Inform action + - Check Point: adding new network object type 'external-gateway' (for interoperable-dervice) + - Check Point: adding network object type support for 'CpmiVsClusterNetobj' (for VSX virtual switches) + - API: + - upgrade hasura to 2.34.0 +- restrictions + - since tenant filtering is not done in the API but in the UI, the API should not be exposed to the tenants + +### 8.0 19.02.2024 MAIN +- Introducing new Network Modelling module + - allows your organisation to define the target state of all network connection on a per-application basis (or other distributed ownerships) +- Backend + - Introducing Scheduled import change notification including inline or attached change report (replacing simple import notification from import module) + - upgrade hasura graphql API to 2.37.0 +- UI + - New look and feel: Moving to vanilla bootstrap css v5.3.2 (allowing for future up to date css usage) + - ip based tenant filtering: introducing unfiltered_managements and devices and adding extended tenant to device mapping settings +- Installer (breaking change!) + - introducing venv for newer ansible versions and thereby removing annoying ansible version handling in installer (see https://github.com/CactuseSecurity/firewall-orchestrator/blob/main/documentation/installer/basic-installation.md for details) +- bugfixes for + - import log locking + - integration tests with credentials when installing without demo data + - pdf creation on debian testing plattform (trixie) + +# 8.1 - 10.04.2024 MAIN +- UI: iconifying modelling UI buttons (can now use icons instead of text buttons - configurable per user) +- Importer: first version of VMware NSX import module +- API: adding customizing script for bulk configs via API +- Database security: all credentials in the database are now encrypted - breaking change (for developer debugging only): add the following local file when using -e testkeys=true: + /etc/fworch/secrets/main_key with content "not4production..not4production.." +- Importer fix: remove log locking from importer due to stalling importer stops + +# 8.2 - 30.04.2024 MAIN +- new workflow for modelling: interface request + - adding all imported modelling users to local db (uiuser) - to enable email notification +- new features for modelling + - display NAs in Report LSB and Export + - count and display members of areas in selection list +- upgrade to dotnet 8.0 (middleware and UI server) +- encrypt emailPassword in config +- fixes: + - demo managements (change import from deactivated to activated - does not affect test managements) + +# 8.3 - 25.06.2024 MAIN +Maintenance release +- fix misleading login error message when authorisation is missing +- fix email credential decryption +- start of Tufin SecureChange integration +- remove cascading delete for used interfaces +- owner-filtering for new report type +- new setting for email recipients +- owner-import custom script improvements# + +# 8.3.1 - 14.08.24 MAIN +Hotfix: +- in CheckPoint importer: fix missing group members + +# 8.4 - 30.09.24 MAIN +Stability release +- various small bug fixes + - installer (redundant code deleting test user) + - importer (switching from full details to standard, re-adding VSX gateway support, voip domain handling in cp parser) + - reporting (app-rule report containing multiple objects) + - middleware (config subscriptions) + - reporting (temporarily highlight linked to object in rsb) + - modelling (sync connections - not always part of overview table after creation) + - RBA (role picking when user has multiple roles) + - UI various: adding missing pager control + - UI various: spinner clean-up +- features/upgrades + - Added login page welcome message and settings + - Added last hit information in app-rule report + - API - upgrading to 2.43.0 + - various security upgrades dotnet (restsharp, jwt, ...) + +# 8.4.1 - 30.10.24 MAIN +Network Modelling feature update +- import of app server IP addresses via CSV upload +- import of multiple sources for area IP data +- new option email notification: fall-back to main owner if group is empty +Fixes +- corrections in displaying UI messages +- converting owner network ip data to standard format "range" +- importer + - check point - fix import of all VSX instances + - fortinet - add hit counts and install on information + +# 8.5 - 13.11.24 MAIN +Network Modelling feature update +- modelling can be requested as firewall change via external ticketing tool +- includes all approle handling +- simple form of rule change request (always request all connections as rules) +- api hasura upgrade to 2.44.0 +Fixes +- various small UI fixes +- importer (CP: handle None objects) + +# 8.6 - 11.12.2024 MAIN +Features +- Modelling + - Create Application Zones + - Add monitoring for external requests for admins + - Add re-initialization for external requests + - consolidation modelling external requests + - adding optional access requst on behalf of UI user + - adding live update of external task/ticket status + - app server name handling rework (NONAME --> _) + - owner groups can now also be external LDAP groups + +- Reporting + - refining connection report (adding Common service, app role, network area details) +Fixes +- Importer + - adding missing colors in Check Point importer + - new VOIP service object and Internet object + +- UI + - SECURITY: updating System.Text.Encodings.Web v4.5.0 --> v8.0.0 + +# 8.6.1 17.12.2024 MAIN +Fixes network modelling +- lock external requests to avoid multiple external tickets +- fix missing comments +- wait cycles for access request after group changes +- save publish flag at interface creation +- disregard dummyAppRole for status determination +- inherit extra configs from interface +- sanitize extra configs +- sort tasks for connection Id and show already adapted name of new members +- small monitoring adaptations +- some cleanup + removal of compiler warnings +- fix ldap group creation regression +- restrict owner_network uniqness constraint to same import source +- UI interface search pop-up transformed into filterable table + +Upgrade Hasura API to v2.45.1 + +# 8.6.2 03.01.2025 MAIN +Hotfix for network modelling: +- fix: when visiting the library for the second time, app servers were missing due to uninitialized area data. + + +# 8.7 03.03.2025 MAIN +- General UI + - pop-up unification and clean-up + - removing unnecessary scroll-bars +- PDF generation: replacing engine wkhtml with puppeteer +- Modelling + - Edit application role (AR): make objects sortable by IP or name + - adding change requests to history + - adding option to name all application servers by reverse DNS and fall-back to prefix + ip +- API: upgrade Hasura to 2.45.2 +- Workflow: some performance improvements + +# 8.7.1 07.03.2025 MAIN +- fix modelling select existing interfac +- fix modelling settings ldap selection +- fix workflow ticket close spinner + +# 8.8 17.04.2025 MAIN +* fix stm_action by @tpurschke in https://github.com/CactuseSecurity/firewall-orchestrator/pull/2844 +* add missing rulebase_link constraints by @tpurschke in https://github.com/CactuseSecurity/firewall-orchestrator/pull/2845 +* fix rule_metadata creation by @tpurschke in https://github.com/CactuseSecurity/firewall-orchestrator/pull/2865 +* remove dev_id fk constraint from rule_metadata by @tpurschke in https://github.com/CactuseSecurity/firewall-orchestrator/pull/2909 +* fix missing rule_metadata.rulebase_id by @tpurschke in https://github.com/CactuseSecurity/firewall-orchestrator/pull/2911 +* fix warnings and rule normalize bug by @tpurschke in https://github.com/CactuseSecurity/firewall-orchestrator/pull/2912 +* fix missing upgrade scripts from pre 9 by @tpurschke in https://github.com/CactuseSecurity/firewall-orchestrator/pull/2938 +* Cactus develop fix importer main level bug by @tpurschke in https://github.com/CactuseSecurity/firewall-orchestrator/pull/3009 +* Endpoint for getting rules by @abarz722 in https://github.com/CactuseSecurity/firewall-orchestrator/pull/3027 +* ExtRequest - increase logging by @abarz722 in https://github.com/CactuseSecurity/firewall-orchestrator/pull/3029 +* Nuget Updates by @SolidProgramming in https://github.com/CactuseSecurity/firewall-orchestrator/pull/3038 +* Nuget Updates by @SolidProgramming in https://github.com/CactuseSecurity/firewall-orchestrator/pull/3042 +* fix(ui): ip filtering in app report by @Y4nnikH in https://github.com/CactuseSecurity/firewall-orchestrator/pull/3040 +* Preventing use of NA objects in connections by @SolidProgramming in https://github.com/CactuseSecurity/firewall-orchestrator/pull/3043 +* fix(ui rsb): ui crash likely caused by duplicates in query result by @Y4nnikH in https://github.com/CactuseSecurity/firewall-orchestrator/pull/3046 +* LDAP Nuget Update changes by @SolidProgramming in https://github.com/CactuseSecurity/firewall-orchestrator/pull/3056 +* Defer AZ creation until second button click by @SolidProgramming in https://github.com/CactuseSecurity/firewall-orchestrator/pull/2856 +* Removing minor py-re deprecation warnings by @tpurschke in https://github.com/CactuseSecurity/firewall-orchestrator/pull/3053 +* feat(ui): rsb enhancements by @Y4nnikH in https://github.com/CactuseSecurity/firewall-orchestrator/pull/3073 +* User UI glitch by @SolidProgramming in https://github.com/CactuseSecurity/firewall-orchestrator/pull/3089 +* Modelling new AR drop down strange initial value by @SolidProgramming in https://github.com/CactuseSecurity/firewall-orchestrator/pull/3091 +* Verify modelled services for empty groups by @SolidProgramming in https://github.com/CactuseSecurity/firewall-orchestrator/pull/3087 +* adding app servers fails without name by @SolidProgramming in https://github.com/CactuseSecurity/firewall-orchestrator/pull/3088 +* Modelling - no NA should be usable for selected interfaces by @SolidProgramming in https://github.com/CactuseSecurity/firewall-orchestrator/pull/3086 +* new customized app data import script by @tpurschke in https://github.com/CactuseSecurity/firewall-orchestrator/pull/3101 +* adding csv appdata import stats by @tpurschke in https://github.com/CactuseSecurity/firewall-orchestrator/pull/3103 +* reformatting app server ip struct by @tpurschke in https://github.com/CactuseSecurity/firewall-orchestrator/pull/3105 +* css cache changes by @SolidProgramming in https://github.com/CactuseSecurity/firewall-orchestrator/pull/3108 +* show more clearly if everything is (horizontally) displayed by @SolidProgramming in https://github.com/CactuseSecurity/firewall-orchestrator/pull/3096 +* Fixed connection object duplication by @SolidProgramming in https://github.com/CactuseSecurity/firewall-orchestrator/pull/3118 +* Modelling csv import improvements by @SolidProgramming in https://github.com/CactuseSecurity/firewall-orchestrator/pull/3113 +* IP check improvements by @SolidProgramming in https://github.com/CactuseSecurity/firewall-orchestrator/pull/3133 +* Nuget Updates by @SolidProgramming in https://github.com/CactuseSecurity/firewall-orchestrator/pull/3136 +* Some report generation improvements by @SolidProgramming in https://github.com/CactuseSecurity/firewall-orchestrator/pull/3117 +* Config change subscribe add "autoReplaceAppServer" #3138 by @SolidProgramming in https://github.com/CactuseSecurity/firewall-orchestrator/pull/3148 +* Nuget Updates by @SolidProgramming in https://github.com/CactuseSecurity/firewall-orchestrator/pull/3143 +* External ticket timout fix by @NilsPur in https://github.com/CactuseSecurity/firewall-orchestrator/pull/3151 +* feat(ui): ip filter line observes negation in rules by @Y4nnikH in https://github.com/CactuseSecurity/firewall-orchestrator/pull/3164 +* allow for flexible ldap group name templating, fix #3114 by @tpurschke in https://github.com/CactuseSecurity/firewall-orchestrator/pull/3165 +* Variance Report First Throw by @abarz722 in https://github.com/CactuseSecurity/firewall-orchestrator/pull/3080 +* feat(ui rsb): show ip/port of flat members by @Y4nnikH in https://github.com/CactuseSecurity/firewall-orchestrator/pull/3172 +* fix(ui report): ip filter on negated rule to/from by @Y4nnikH in https://github.com/CactuseSecurity/firewall-orchestrator/pull/3173 + +# 8.8.1 - 28.04.2025 MAIN +- fix owner group DN for App Data Import module + +# 8.8.6 - 22.07.2025 MAIN +hotfix release +- CP importer new + - stm_track: "extended log" and "detailed log" + - fixing services-other ip proto import +- improved quality control with stricter automated checks +- various fixes in modelling module + +# 8.8.8 - 23.08.2025 MAIN +- add read-only db user fwo_ro +- hadening changes + - apache config (information leakage) + - listeners (hasura, postgres) + - log santisation +# 8.9.1 - 02.10.2025 MAIN +- owner-recertification + +# 8.9.2 - 17.10.2025 MAIN +- add ownerLifeCycleState +- add manageable ownerLifeCycleState menu + +# 8.9.3 - 05.11.2025 MAIN +- hotfix missing permissions for app data import in certain constellations + +## 8.9.4 - 09.12.2025 MAIN +- bugfix release: common service connection not editable +- new custom scripts for iiq and cmdb import + + +## 8.9.5 - 10.12.2025 MAIN +- bugfix release: modelling - change planning showed duplicate NA elements for rule delete requests + +## 8.9.6 - 05.01.2026 MAIN +- new parameters for notifications + +# 9.0 - 27.01.2026 MAIN +A complete 80K lines rework of FWO, including +- database changes to deduplicate rules (rule to gateway mapping now 1:n by introducing rulebase and rulebase_link tables) +- migrating import module from mixed python/pgsql to pure python + +# 9.0.1 - 07.02.2026 +- update rule_owner table for REST api +- update import_control to allow flexible tracking of different import types +- generalized owner responsibles with configurable responsible types +- add allow_write_access to responsible types to control modelling and recertification + +# 9.0.2 - 10.02.2026 DEVELOP +- fix: chunking for cleanup importer + +# 9.0.4 - 13.02.2026 MAIN +- maintenance release with explicit 9.0.4 upgrade step + +# 9.0.9 - 25.02.2026 DEVELOP +- remove stale v8 code + +# 9.0.16 - 26.03.2026 MAIN +- bug fixing +- moving from docker to podman + +# 9.0.21 - 21.04.2026 MAIN +- bug fixing +- dependency updates (notably closing mailkit and pytest vulnerabilities) + +# 9.0.22 - 26.04.2026 MAIN +- fixes missing source or destination in rule expiry notification report +- fixes time zone issues with checkpoint time objects +- fixes python tests failing on python 3.10 +- fixes owner import from custom file diff --git a/documentation/test-plans/ui-main-test-plan.csv b/documentation/test-plans/ui-main-test-plan.csv new file mode 100644 index 0000000000..e854c353f9 --- /dev/null +++ b/documentation/test-plans/ui-main-test-plan.csv @@ -0,0 +1,85 @@ +"Test ID","Area","Feature/Flow","Preconditions","Steps","Expected Result","Priority","Test Type","Notes/Data" +"UI-001","Authentication","Login with valid credentials","User exists and active","1) Navigate to Login; 2) Enter valid username/password; 3) Submit","User is authenticated and redirected to Start page","P0","Functional","Use a standard non-admin account" +"UI-002","Authentication","Login with invalid credentials","None","1) Navigate to Login; 2) Enter invalid username/password; 3) Submit","Authentication fails with clear error message; no session created","P0","Negative","" +"UI-003","Authentication","Password change flow","User can authenticate; password policy configured","1) Login; 2) Navigate to password change; 3) Enter current password and new valid password; 4) Save","Password updated; user prompted to re-authenticate if required","P1","Functional","Verify policy validation messages" +"UI-004","Authentication","Logout","User is logged in","1) Click Logout; 2) Confirm if prompted","Session cleared; redirected to Login; protected pages no longer accessible","P0","Functional","" +"UI-005","Authentication","Session timeout","User is logged in; short token lifetime configured","1) Remain idle past token expiry; 2) Attempt navigation","User prompted to re-authenticate; no protected data shown","P0","Security","" +"UI-006","Navigation","Main navigation links","User is logged in","1) Open sidebar; 2) Click each primary navigation item","Each link routes to the correct page without errors","P0","Functional","" +"UI-007","Navigation","Role-based navigation visibility","User with limited roles","1) Login as limited user; 2) Inspect navigation","Only permitted sections are visible; restricted entries hidden/disabled","P0","Security","" +"UI-008","Navigation","Breadcrumbs/headers show context","User is logged in","1) Navigate across sections; 2) Observe page headers","Page headers reflect current section and context","P2","UX","" +"UI-009","Localization","Switch language","Multiple languages configured","1) Change UI language; 2) Navigate to several pages","Labels and messages update to selected language","P2","Functional","" +"UI-010","Help","Contextual help links","User is logged in","1) Open a page with help; 2) Click help link","Help opens to the correct topic page","P2","Functional","" +"UI-011","Start","Start page widgets/links","User is logged in","1) Open Start page; 2) Use primary action links","Widgets load data and links route correctly","P1","Functional","" +"UI-012","Reporting","Open report selection","Reporting data available","1) Navigate to Reporting; 2) Choose a report","Report selection UI loads without errors","P0","Functional","" +"UI-013","Reporting","Report time filter","Reporting data available","1) Select time range; 2) Generate report","Report reflects selected time range","P0","Functional","" +"UI-014","Reporting","Device selection filter","Devices exist","1) Choose specific devices; 2) Generate report","Report data is scoped to selected devices","P1","Functional","" +"UI-015","Reporting","Tenant selection filter","Tenants configured","1) Select tenant scope; 2) Generate report","Report data restricted to selected tenants","P1","Functional","" +"UI-016","Reporting","Rules report rendering","Rules data available","1) Generate Rules report; 2) Review table","Rules table loads; sorting and pagination function","P0","Functional","" +"UI-017","Reporting","Changes report rendering","Change history available","1) Generate Changes report; 2) Review table","Changes report loads with correct data","P1","Functional","" +"UI-018","Reporting","Statistics report rendering","Statistics data available","1) Generate Statistics report","Summary metrics display correctly","P2","Functional","" +"UI-019","Reporting","Recertification report rendering","Recert data available","1) Generate Recertification report","Recertification data shown and exportable","P1","Functional","" +"UI-020","Reporting","Variances report rendering","Variance data available","1) Generate Variances report","Variance metrics display correctly","P2","Functional","" +"UI-021","Reporting","Connections report rendering","Connections data available","1) Generate Connections report","Connections report loads; filters apply","P2","Functional","" +"UI-022","Reporting","Report export","Report generated","1) Click Export; 2) Choose format; 3) Download","Export completes; file downloads with expected format","P0","Functional","Validate CSV/XLSX/PDF as configured" +"UI-023","Reporting","Report scheduling","User has permission to schedule","1) Open Schedule; 2) Create schedule; 3) Save","Schedule saved; next run time displayed","P1","Functional","" +"UI-024","Reporting","Report archive access","Archived reports exist","1) Open Archive; 2) Download an entry","Archived file downloads successfully","P1","Functional","" +"UI-025","Reporting","Create ticket from report","External workflow configured","1) Open report; 2) Create ticket; 3) Submit","Ticket is created and linked to report","P1","Integration","" +"UI-026","Monitoring","Monitoring overview loads","Monitoring data available","1) Navigate to Monitoring","Dashboard loads with current status indicators","P0","Functional","" +"UI-027","Monitoring","Open alerts list","Open alerts exist","1) Open Alerts; 2) Inspect list","Alerts show correct severity and metadata","P1","Functional","" +"UI-028","Monitoring","Close/resolve alert","Open alert exists; user has permission","1) Open alert; 2) Resolve; 3) Save","Alert state updates; audit entry created if applicable","P1","Functional","" +"UI-029","Monitoring","Import logs","Import runs exist","1) Open Import Logs; 2) Filter by date","Logs load; filters applied","P2","Functional","" +"UI-030","Monitoring","Import status","Import status data available","1) Open Import Status; 2) Check status badges","Status indicators match backend state","P1","Functional","" +"UI-031","Monitoring","Autodiscovery results","Autodiscovery data available","1) Open Autodiscovery; 2) Review results","Results list loads; details view works","P2","Functional","" +"UI-032","Compliance","Compliance matrix list","Matrices exist","1) Navigate to Compliance Matrix; 2) Select matrix","Matrix list loads; selection opens details","P1","Functional","" +"UI-033","Compliance","Add compliance matrix","User has permission","1) Open Add Matrix; 2) Provide required data; 3) Save","Matrix created and listed","P1","Functional","" +"UI-034","Compliance","Compliance check execution","Compliance targets configured","1) Start compliance check; 2) Wait for completion","Check completes; results visible","P0","Functional","" +"UI-035","Compliance","Compliance results view","Compliance results exist","1) Open results view; 2) Drill into a finding","Results display with details and filters","P1","Functional","" +"UI-036","Workflow","Create change request","Workflow enabled","1) Start new request; 2) Complete required fields; 3) Submit","Request created with initial state","P0","Functional","" +"UI-037","Workflow","Transition workflow state","Request exists; user has permission","1) Open request; 2) Execute action; 3) Confirm","State transitions as configured; history updated","P0","Functional","" +"UI-038","Workflow","External workflow ticket link","External workflow configured","1) Open request; 2) Open external ticket link","External ticket opens in new tab or embedded view","P2","Integration","" +"UI-039","Recertification","Recertification overview","Recert data available","1) Navigate to Recertification; 2) Open overview","Overview loads with counts and links","P1","Functional","" +"UI-040","Recertification","Owner recert list","Owners configured","1) Open owner list; 2) Select owner","Owner recert data loads","P1","Functional","" +"UI-041","Recertification","Recert action completion","Recert task available","1) Open task; 2) Complete action; 3) Save","Task state updates; audit trail updated","P1","Functional","" +"UI-042","Modelling","Applications list","Modelling data available","1) Navigate to Modelling; 2) Open Applications","Applications list loads; search works","P1","Functional","" +"UI-043","Modelling","Create or update application","User has permission","1) Open application editor; 2) Edit fields; 3) Save","Application saved and visible in list","P1","Functional","" +"UI-044","Modelling","Network objects","Network objects exist","1) Open Network Objects; 2) View details","Objects display and edit actions work","P2","Functional","" +"UI-045","Modelling","Connections evaluation","Connections data available","1) Open Connections; 2) Evaluate a connection","Evaluation results displayed with status","P2","Functional","" +"UI-046","Import","Device import upload","Import configured; file prepared","1) Navigate to Import; 2) Upload file; 3) Submit","Import starts; status shown","P0","Functional","" +"UI-047","Import","Import rollback","Import completed","1) Open Import details; 2) Trigger rollback; 3) Confirm","Rollback executes; status updated","P1","Functional","" +"UI-048","Settings","Custom logo upload","User has admin permission","1) Open Settings > Customizing; 2) Upload logo; 3) Save","Logo updated in UI header","P2","Functional","" +"UI-049","Settings","Custom texts","User has admin permission","1) Open Settings > Custom texts; 2) Edit text; 3) Save","Custom text appears in relevant UI locations","P2","Functional","" +"UI-050","Settings","Email settings test","SMTP configured","1) Open Settings > Email; 2) Send test mail","Test email sent successfully; UI shows confirmation","P1","Integration","" +"UI-051","Settings","LDAP connection test","LDAP configured","1) Open Settings > LDAP; 2) Test connection","Connection test succeeds or shows clear error","P0","Integration","" +"UI-052","Settings","User management CRUD","Admin user","1) Create user; 2) Edit user; 3) Disable user","User list reflects changes; validation enforced","P0","Functional","" +"UI-053","Settings","Role management","Admin user","1) Create or edit role; 2) Assign permissions; 3) Save","Role saved; permissions enforced in UI","P0","Functional","" +"UI-054","Settings","Group management","Admin user","1) Create group; 2) Assign users; 3) Save","Group updated; membership visible","P1","Functional","" +"UI-055","Settings","Tenant management","Admin user","1) Create tenant; 2) Assign scope; 3) Save","Tenant saved; visibility rules apply","P1","Functional","" +"UI-056","Settings","Managements CRUD","Admin user; management reachable","1) Add management; 2) Edit settings; 3) Save","Management stored; connection status visible","P1","Functional","" +"UI-057","Settings","Gateways CRUD","Admin user","1) Add gateway; 2) Edit; 3) Save","Gateway stored and listed","P2","Functional","" +"UI-058","Settings","Credentials management","Admin user","1) Add credential; 2) Edit; 3) Save","Credential saved; masked values handled correctly","P0","Security","" +"UI-059","Settings","Import scheduling","Admin user","1) Open Import settings; 2) Set schedule; 3) Save","Schedule saved and next run displayed","P1","Functional","" +"UI-060","Settings","Report templates","Admin user","1) Open Report settings; 2) Create or edit template; 3) Save","Template saved and available in reports","P1","Functional","" +"UI-061","Settings","Compliance settings","Admin user","1) Open Compliance settings; 2) Update thresholds; 3) Save","Settings saved; compliance uses new thresholds","P2","Functional","" +"UI-062","Settings","Workflow states and matrices","Admin user","1) Edit workflow states; 2) Update state matrix; 3) Save","Changes persist; workflows use updated states","P1","Functional","" +"UI-063","Settings","External workflow configuration","Admin user; external system available","1) Open External Workflow settings; 2) Configure endpoint; 3) Save","Settings validated and stored","P1","Integration","" +"UI-064","Settings","Recertification generation settings","Admin user","1) Open Recertification Gen; 2) Update schedule; 3) Save","Schedule saved; next run reflected","P1","Functional","" +"UI-065","Settings","Recertification personalization settings","Admin user","1) Open Recertification Pers; 2) Update per-owner settings; 3) Save","Per-owner settings applied","P2","Functional","" +"UI-066","Settings","Modelling settings","Admin user","1) Open Modelling settings; 2) Update defaults; 3) Save","Defaults saved and used in modelling flows","P2","Functional","" +"UI-067","Settings","Workflow actions","Admin user","1) Open Actions; 2) Add action; 3) Save","Action available in workflow transitions","P2","Functional","" +"UI-068","Settings","Variance options","Admin user","1) Open Variance options; 2) Update parameters; 3) Save","Variance calculations use new parameters","P2","Functional","" +"UI-069","Settings","Owner management","Admin user","1) Add owner; 2) Edit; 3) Save","Owner stored and visible for selection","P1","Functional","" +"UI-070","Settings","Owner app data import","Admin user; app data source ready","1) Open Owner App Data Import; 2) Configure; 3) Save","Import settings stored; next run visible","P2","Functional","" +"UI-071","UI Controls","Pagination controls","List view with many entries","1) Open a list; 2) Change page; 3) Change page size","Pagination updates list correctly","P1","Functional","Use Reporting or Settings lists" +"UI-072","UI Controls","Sorting controls","Sortable table available","1) Click sort header; 2) Toggle sort direction","Sort order changes and indicator updates","P1","Functional","" +"UI-073","UI Controls","Search filters","Searchable list available","1) Enter search term; 2) Apply filters","List narrows to matching entries","P1","Functional","" +"UI-074","UI Controls","Modal confirmations","Destructive action available","1) Trigger delete; 2) Cancel; 3) Trigger again; 4) Confirm","Cancel keeps data; confirm performs delete","P1","Functional","" +"UI-075","UI Controls","File upload validation","Upload field available","1) Upload invalid file type; 2) Upload oversized file","Validation error shown; no upload performed","P1","Negative","" +"UI-076","Resilience","Error page handling","Induced error or invalid route","1) Navigate to invalid route or cause error","Error page displays friendly message and recovery path","P2","Resilience","" +"UI-077","Security","Direct URL access control","Limited user account","1) Enter direct URL to restricted page","Access blocked or redirected with message","P0","Security","" +"UI-078","Accessibility","Keyboard navigation","Any list or form","1) Use Tab/Shift+Tab; 2) Activate buttons with Enter","Focus order logical; actions triggered","P2","Accessibility","" +"UI-079","Accessibility","ARIA labels on key controls","Pages with form controls","1) Inspect key controls; 2) Verify labels","Key inputs have readable labels for screen readers","P3","Accessibility","" +"UI-080","Performance","Initial page load","Normal environment","1) Login; 2) Navigate to Start","Page loads within acceptable time; no blank state","P2","Performance","Define acceptable thresholds" +"UI-081","Performance","Large data report render","Large dataset available","1) Generate large Rules report","Report loads; UI remains responsive","P2","Performance","" +"UI-082","Audit","Audit visibility for actions","Audit feature enabled","1) Perform key action (create request); 2) Check audit view if available","Audit entry recorded and visible to authorized users","P3","Functional","" +"UI-083","Branding","Custom favicon","Admin user","1) Update branding if supported; 2) Refresh UI","Favicon updated across pages","P3","Functional","If supported in Settings" +"UI-084","Help","Help search/navigation","Help pages available","1) Open Help index; 2) Navigate using sidebar","Help navigation works and pages load","P3","Functional","" diff --git a/documentation/test-plans/ui-scheduled-importers-test-plan.csv b/documentation/test-plans/ui-scheduled-importers-test-plan.csv new file mode 100644 index 0000000000..138cd24d3d --- /dev/null +++ b/documentation/test-plans/ui-scheduled-importers-test-plan.csv @@ -0,0 +1,41 @@ +"Test ID","Area","Feature/Flow","Preconditions","Steps","Expected Result","Priority","Test Type","Notes/Data" +"IMP-001","Scheduling","Importer schedule list loads","Importer scheduling enabled","1) Navigate to Settings > Import; 2) Open schedule list","Scheduled importers are listed with next-run times","P0","Functional","" +"IMP-002","Scheduling","Create schedule (daily)","Admin user; importer defined","1) Add new schedule; 2) Select daily; 3) Save","Schedule saved and next run shows daily cadence","P0","Functional","Use default timezone" +"IMP-003","Scheduling","Create schedule (weekly)","Admin user; importer defined","1) Add schedule; 2) Select weekly day; 3) Save","Schedule saved with correct weekday","P1","Functional","" +"IMP-004","Scheduling","Create schedule (cron/advanced)","Admin user; advanced schedule available","1) Add schedule; 2) Enter cron/advanced settings; 3) Save","Schedule validates and saves; next run computed","P1","Functional","If advanced mode exists" +"IMP-005","Scheduling","Edit schedule","Existing schedule","1) Open schedule; 2) Change time; 3) Save","Next run updates to new time","P1","Functional","" +"IMP-006","Scheduling","Disable schedule","Existing schedule","1) Toggle schedule off; 2) Save","Schedule shows disabled; no next run planned","P0","Functional","" +"IMP-007","Scheduling","Delete schedule","Existing schedule","1) Delete schedule; 2) Confirm","Schedule removed from list","P1","Functional","" +"IMP-008","Scheduling","Validation for invalid schedule","None","1) Create schedule with invalid time or missing fields; 2) Save","Validation error shown; schedule not saved","P0","Negative","" +"IMP-009","Scheduling","Timezone handling","Importer schedule with timezone option","1) Set schedule time; 2) Change timezone; 3) Save","Next run time recalculates correctly for timezone","P1","Functional","" +"IMP-010","Scheduling","Overlapping schedules warning","Multiple schedules for same importer","1) Create overlapping schedule; 2) Save","Warning shown or system prevents conflict","P2","Functional","Depending on rules" +"IMP-011","Execution","Scheduled run triggers","Schedule active; system time reaches trigger","1) Wait for scheduled time; 2) Observe status","Run starts automatically; status updates to running","P0","Functional","" +"IMP-012","Execution","Manual run from schedule list","Importer configured","1) Click Run Now; 2) Confirm","Run starts immediately; status shown","P0","Functional","" +"IMP-013","Execution","Concurrent run prevention","Importer currently running","1) Trigger another run; 2) Observe behavior","System blocks or queues new run with message","P1","Functional","" +"IMP-014","Execution","Run history list","Previous runs exist","1) Open import history; 2) Filter by importer","History shows run records with status and timestamps","P1","Functional","" +"IMP-015","Execution","Run duration display","Completed runs exist","1) Open run details","Duration displayed and accurate","P2","Functional","" +"IMP-016","Execution","Status polling updates","Run in progress","1) Open status page; 2) Wait for updates","Status updates without manual refresh if supported","P2","Functional","" +"IMP-017","Execution","Success outcome","Importer configured","1) Run importer; 2) Wait for completion","Status shows success; summary metrics shown","P0","Functional","" +"IMP-018","Execution","Failure outcome","Importer misconfigured or data invalid","1) Run importer; 2) Induce failure","Status shows failure; error message visible","P0","Negative","" +"IMP-019","Execution","Retry after failure","Failure recorded","1) Click Retry; 2) Run again","Retry starts and outcome logged","P1","Functional","" +"IMP-020","Execution","Rollback availability","Run completed; rollback supported","1) Open run details; 2) Trigger rollback","Rollback executes; status updated","P1","Functional","" +"IMP-021","Execution","Rollback disallowed when running","Importer running","1) Attempt rollback","Action blocked with message","P1","Negative","" +"IMP-022","Import Data","Device import from file","Import file prepared","1) Upload file; 2) Map if required; 3) Submit","Import starts; status shown","P0","Functional","" +"IMP-023","Import Data","Management import config","Management exists","1) Open Managements; 2) Set import options; 3) Save","Options stored and used on next run","P2","Functional","" +"IMP-024","Import Data","Credentials validation","Credentials configured","1) Save with invalid credentials; 2) Test connection","Validation error displayed; save blocked if required","P0","Security","" +"IMP-025","Import Data","Scope selection (tenant/device)","Multiple tenants/devices","1) Set scope filters; 2) Save; 3) Run","Import uses selected scope","P1","Functional","" +"IMP-026","Notifications","Email notification on success","Email settings configured","1) Enable notifications; 2) Run importer successfully","Success email sent with summary","P2","Integration","" +"IMP-027","Notifications","Email notification on failure","Email settings configured","1) Enable notifications; 2) Run importer to fail","Failure email sent with error summary","P1","Integration","" +"IMP-028","Notifications","UI alert for failed run","Run failed","1) Open Monitoring/Import Status","Failure alert visible in UI","P1","Functional","" +"IMP-029","Permissions","Role-based access to schedules","Limited user","1) Login as limited user; 2) Open Import settings","Access denied or read-only per role","P0","Security","" +"IMP-030","Permissions","Run/rollback permissions","Limited user","1) Attempt Run Now or Rollback","Actions blocked if not permitted","P0","Security","" +"IMP-031","Resilience","Backend unavailable","Stop importer service or block API","1) Open schedule list; 2) Run importer","Graceful error shown; no UI crash","P1","Resilience","" +"IMP-032","Resilience","Importer service restart during run","Run in progress","1) Restart importer service; 2) Observe UI","Run marked failed or retried per policy; UI updates","P2","Resilience","" +"IMP-033","Performance","Large import execution","Large dataset available","1) Run importer on large data","Run completes; UI responsive; duration logged","P2","Performance","" +"IMP-034","Audit","Audit entry for schedule change","Audit enabled","1) Create/edit schedule; 2) Check audit trail","Audit records change with user and timestamp","P2","Functional","" +"IMP-035","Audit","Audit entry for run trigger","Audit enabled","1) Trigger Run Now; 2) Check audit trail","Audit records run trigger event","P2","Functional","" +"IMP-036","UI Controls","Search/filter schedules","Multiple schedules exist","1) Use search/filter; 2) Apply","List filters correctly","P2","Functional","" +"IMP-037","UI Controls","Pagination in run history","Many run records","1) Change page; 2) Change page size","Pagination works and stays stable","P2","Functional","" +"IMP-038","Security","Direct URL access control","Limited user","1) Enter URL for schedule editor","Access blocked or redirected","P0","Security","" +"IMP-039","Time","Daylight saving time shift","DST change upcoming","1) Set schedule around DST; 2) Observe next run","Next run adjusts correctly for DST rules","P2","Functional","" +"IMP-040","Recovery","Re-enable disabled schedule","Disabled schedule exists","1) Enable schedule; 2) Save","Schedule active; next run set","P1","Functional","" diff --git a/inventory/group_vars/all.yml b/inventory/group_vars/all.yml index 8e349757b5..7194ffc537 100644 --- a/inventory/group_vars/all.yml +++ b/inventory/group_vars/all.yml @@ -1,5 +1,5 @@ ### general settings -product_version: "7.0" +product_version: "9.0.22" ansible_user: "{{ lookup('env', 'USER') }}" ansible_become_method: sudo ansible_python_interpreter: /usr/bin/python3 @@ -22,26 +22,32 @@ sample_hostname: "{{ groups['sampleserver'].0 }}" # upgrade - installs on top of an existing system preserving any existing data in ldap, database, api installation_mode: new install_syslog: true -run_on_github: false add_demo_data: true api_docu: false force_install: false +docker_network: "" ### operating system settings user_id: 60320 fworch_user: "{{ product_name }}" fworch_group: "{{ fworch_user }}" +fworch_subid_range_start_min: 200000 +fworch_subid_range_size: 65536 +postgres_group: "postgres" fworch_parent_dir: "/usr/local" fworch_home: "{{ fworch_parent_dir }}/{{ product_name }}" fworch_conf_dir: "{{ fworch_home }}/etc" fworch_conf_file: "{{ fworch_conf_dir }}/fworch.json" +last_commit_id_file_path: "{{ fworch_conf_dir }}/last_commit_id.txt" fworch_secrets_dir: "{{ fworch_conf_dir }}/secrets" +importer_venv_dir: "{{ fworch_home }}/importer/importer-venv" # setting default proxy (may be overwritten via --extra-vars) http_proxy: "{{ lookup('env','http_proxy') }}" https_proxy: "{{ lookup('env','https_proxy') }}" no_proxy: "{{ lookup('env','no_proxy') }}" proxy_exceptions: "{{ lookup('env','no_proxy') }}" +github_download_timeout: 60 proxy_env: http_proxy: "{{ http_proxy }}" https_proxy: "{{ https_proxy }}" @@ -56,8 +62,10 @@ http_proxy_import_parameter: "" # OS debian_testing_version: "12" + # should actually be 13 but microsoft does not yet provide https://packages.microsoft.com/config/debian/13 debian_testing_release_name: trixie arch: x86_64 +linux_architecture: amd64 redhat_major_version: "8" redhat_arch: "{{ redhat_major_version }}-{{ arch }}" @@ -71,8 +79,12 @@ fworch_db_password_file: "{{ fworch_secrets_dir }}/fworch_db_pwd" ############################################################### ### api -api_service_name: fworch-hasura-docker-api +api_service_name: fworch-hasura-api api_container_name: "{{ product_name }}-api" +api_env_file: "{{ fworch_secrets_dir }}/hasura.env" +api_legacy_service_names: + - fworch-hasura-docker-api + - hasura-docker-api api_local_listening_ip_address: "127.0.0.1" api_network_listening_ip_address: "{{ groups['apiserver'].0 }}" # api_network_listening_ip_address: "{{ hostvars[groups['apiserver'].0].ip_address }}" @@ -92,6 +104,7 @@ ldap_manager_pwd_file: "{{ fworch_secrets_dir }}/ldap_manager_pwd" middleware_hostname: "127.0.0.1" ldif_changetype: add middleware_service_name: "{{ product_name }}-middleware" +openldap_server_enable_ssl: true # middleware web server middleware_web_listener_port: 8888 @@ -103,11 +116,10 @@ middleware_internal_port: 8880 ui_admin_password_file: "{{ fworch_secrets_dir }}/ui_admin_pwd" ui_admin_testonly_password: "fworch.1" importer_password_file: "{{ fworch_secrets_dir }}/importer_pwd" -importer_password_file_on_installer: etc/importer.pwd ### dotnet dotnet_deb_name: "packages-microsoft-prod.deb" -dotnet_version: "6.0" +dotnet_version: "10.0" dotnet_mode: "Release" # dotnet_mode: "Debug" debug_level: "1" @@ -128,12 +140,18 @@ fworch_log_dir: "/var/log/{{ product_name }}" fworch_log_lock_dir: "/var/{{ product_name }}/lock" fworch_mw_lockfile: "{{ fworch_log_lock_dir }}/FWO.Middleware.Server_log.lock" fworch_ui_lockfile: "{{ fworch_log_lock_dir }}/FWO.Ui_log.lock" +fworch_api_importer_lockfile: "{{ fworch_log_lock_dir }}/importer_api_log.lock" ### apache: both package and dir name (needed both on ui and api hosts): webserver_package_name: apache2 http_conf_dir: /etc/{{ webserver_package_name }}/sites-available/ wsgi_package_name: libapache2-mod-wsgi +############# wkhtmltopdf ######################### + +# wkhtmltopdf_version: "0.12.6.1-3" + + ################# testing ######################### fworchtest_user: "{{ product_name }}test" fworchtest_home: "/home/{{ fworchtest_user }}" @@ -154,3 +172,23 @@ csharp_test_start_dir: "{{ fworch_home }}/test/csharp/FWO.Test" # make sure lib role is only run once per host to save time # set initially to false lib_role_has_run: false + +#### apache settings + +apache2_required_modules: + - headers + - rewrite + - proxy + - proxy_http + - ssl + - proxy_wstunnel + +apache_security_headers: + - 'Header always set Strict-Transport-Security "max-age=31536000; includeSubDomains"' + - 'Header always set X-Frame-Options "SAMEORIGIN"' + - 'Header always set X-Content-Type-Options "nosniff"' + +apache_ssl_protocol: "SSLProtocol -all +TLSv1.2 +TLSv1.3" +apache_ssl_cipher_suite: "SSLCipherSuite ECDHE+AESGCM:ECDHE+CHACHA20:DHE+AESGCM:!aNULL:!MD5:!DSS:!SHA1" + +apache_global_settings_file: /etc/apache2/conf-available/security.conf diff --git a/inventory/group_vars/apiserver.yml b/inventory/group_vars/apiserver.yml index 1dae9d01bd..f089f60179 100644 --- a/inventory/group_vars/apiserver.yml +++ b/inventory/group_vars/apiserver.yml @@ -8,7 +8,8 @@ api_hasura_admin_test_password: "not4production" api_user_email: "{{ api_user }}@{{ api_network_listening_ip_address }}" api_home: "{{ fworch_home }}/api" api_hasura_cli_bin: "{{ fworch_home }}/api/bin/hasura" -api_hasura_version: "v2.30.1" +api_hasura_version: "v2.48.13" +api_hasura_image: "docker.io/hasura/graphql-engine:{{ api_hasura_version }}" api_project_name: api api_no_metadata: false api_rollback_is_running: false diff --git a/inventory/group_vars/databaseserver.yml b/inventory/group_vars/databaseserver.yml index 3f57662ae1..3d2dd61797 100644 --- a/inventory/group_vars/databaseserver.yml +++ b/inventory/group_vars/databaseserver.yml @@ -3,44 +3,34 @@ postgresql_package: postgresql postgresql_test_package: pgtap postgresql_c_client_library_header_files: libpq-dev postgresql_dev_package_prefix: postgresql-server-dev -postgresql_query_as_single_query: false database_install_dir: "{{ fworch_home }}/database" +fwo_db_ro_user: fwo_ro # table_space variable can be used to create database in another place where there is enough space # table_space: /var/db/fworch_tablespace # table_space_name: fworch +db_schemata: + - compliance + - modelling + - public + - request + database_users: - dbbackup - fworchimporter database_groups: - - secuadmins - dbbackupusers - configimporters - - reporters - fworchadmins + database_idempotent_files: - - fworch-basic-procs.sql - - fworch-import.sql - - fworch-import-main.sql - - fworch-obj-import.sql - - fworch-obj-refs.sql - - fworch-svc-import.sql - - fworch-svc-refs.sql - - fworch-usr-import.sql - - fworch-usr-refs.sql - - fworch-rule-import.sql - - fworch-rule-refs.sql - - fworch-rule-resolved.sql - - fworch-zone-import.sql - - fworch-report.sql - - fworch-qa.sql - - fworch-report-basics.sql - - fworch-views.sql - fworch-api-funcs.sql - - fworch-grants.sql - - fworch-texts.sql + - fworch-backup-grants.sql + - fworch-encryption.sql - fworch-path-analysis.sql - fworch-rule-recert.sql + - fworch-texts.sql + - fworch-views-changes.sql diff --git a/inventory/group_vars/sampleserver.yml b/inventory/group_vars/sampleserver.yml index fa49d9d531..b576d7df9c 100644 --- a/inventory/group_vars/sampleserver.yml +++ b/inventory/group_vars/sampleserver.yml @@ -1,10 +1,23 @@ sample_config_user: fworchsample -sample_config_user_home: "/home/{{ sample_config_user }}" +# sample_config_user_home: "/home/{{ sample_config_user }}" sample_data_rate: medium sample_role_purpose: demo -sample_fortigate_name: fortigate_demo -sample_checkpoint_name: "dummy only relevant for testing" +sample_fortigate_basename: fortigate +sample_fortigate_name: "{{ sample_fortigate_basename }}_demo" +sample_fortigate_dev_uid: FortiWiFiFirewall +sample_checkpoint_basename: "checkpoint" +sample_checkpoint_name: "{{ sample_checkpoint_basename }}_demo" +sample_checkpoint_uri: "https://fwodemodata.cactus.de/demo17_cpr8x_v{{ product_version.split('.') | first }}.json" +demo_cpr8x_name_without_demo: "CPR81" +demo_cpr8x_name: "{{ demo_cpr8x_name_without_demo}}_demo" +demo_cpr8x_uri: "https://fwodemodata.cactus.de/demo17_cpr8x_v{{ product_version.split('.') | first }}.json" +demo_cpr8x_mgm_uid: "041d28f5-bb5f-4f46-bb1c-217ccf272278" +demo_cpr8x_dev1_uid: "11372f6c-fcda-49b0-8576-910c6804d53c" +demo_cpr8x_dev2_uid: "4d18802a-4dff-4a43-abea-f2bdf9f6ce8f" +demo_fos_name_without_demo: "FortiOS" +demo_fos_name: "{{ demo_fos_name_without_demo }}_demo" +demo_fos_uri: "https://fwodemodata.cactus.de/demo16_fortios_lab.json" sample_postfix: _demo # sample openldap server diff --git a/inventory/hosts.yml b/inventory/hosts.yml index 393c897f40..696ad7c348 100644 --- a/inventory/hosts.yml +++ b/inventory/hosts.yml @@ -1,20 +1,20 @@ +# If you want to use distributed installation, follow the steps on localhost # 1. ssh-keygen -t rsa # Press enter for each line # 2. cat ~/.ssh/id_rsa.pub >> ~/.ssh/authorized_keys # 3. chmod og-wx ~/.ssh/authorized_keys -# 4. change ansible_connection to ssh and ansible_host to your host +# 4. ssh-copy-id @ +# 5. add remote servers below all: hosts: localhost: ip_address: 127.0.0.1 ansible_connection: local - # ansible_connection: local - # ansible_host: localhost # Add servers for distributed installation here. Use these servers in the children dictionary below. # ui-srv: # ansible_connection: ssh -# ansible_host: 192.168.121.2 +# ansible_host: 192.168.2.3 children: frontends: diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 0000000000..81c867b540 --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,139 @@ +[tool.pyright] +include = [ + "roles/importer/files/importer", + "scripts" +] +extraPaths = ["roles/importer/files/importer"] +venv = ".venv" + +exclude = [ + "**/.*", + "**/node_modules", + "**/__pycache__", + ".git", + ".venv", + "venv", + "roles/api/files/scripts", + "scripts/acquire_lock.py", + "scripts/gh-search.py", + "scripts/json_pretty_print.py", + "scripts/release_lock.py" +] + +typeCheckingMode = "strict" +reportMissingImports = false +reportMissingTypeStubs = true + +[tool.ruff] +required-version = "0.15.0" +line-length = 120 +indent-width = 4 +target-version = "py310" +exclude = [ + ".bzr", + ".direnv", + ".eggs", + ".git", + ".git-rewrite", + ".hg", + ".ipynb_checkpoints", + ".mypy_cache", + ".nox", + ".pants.d", + ".pyenv", + ".pytest_cache", + ".pytype", + ".ruff_cache", + ".svn", + ".tox", + ".venv", + ".vscode", + "__pypackages__", + "_build", + "buck-out", + "build", + "dist", + "node_modules", + "site-packages", + "venv", + "__init__.py", + "roles/tests-integration", + "roles/api/files/scripts", + "scripts/acquire_lock.py", + "scripts/gh-search.py", + "scripts/json_pretty_print.py", + "scripts/release_lock.py" +] + +[tool.ruff.lint] +select = ["ALL"] +ignore = [ + "ANN", # flake8-annotations: Type annotation checks + "COM", # flake8-commas: Trailing comma checks + "C90", # mccabe: Complexity checks + "DJ", # flake8-django: Django-specific checks + "EXE", # flake8-executable: Executable file checks + "T10", # flake8-debugger: Debugger import checks + "TID", # flake8-tidy-imports: Import organization checks + "D100", # Missing docstring in public module + "D101", # Missing docstring in public class + "D102", # Missing docstring in public method + "D103", # Missing docstring in public function + "D104", # Missing docstring in public package + "D105", # Missing docstring in magic method + "D106", # Missing docstring in public nested class + "D107", # Missing docstring in __init__ + "D200", # One-line docstring should fit on one line + "D203", # 1 blank line required before class docstring + "D205", # 1 blank line required between summary line and description + "D212", # Multi-line docstring summary should start at the first line + "D400", # First line should end with a period + "D401", # First line should be in imperative mood + "D415", # First line should end with a period, question mark, or exclamation point + "D417", # Missing argument descriptions in the docstring + "E402", # Module level import not at top of file + "E501", # Line too long + "TRY003", # Avoid specifying long messages outside the exception class + "TD002", # Missing author in TODO + "TD003", # Missing issue link on the line following a TODO + "FIX002", # Line contains TODO, consider resolving the issue + "EM101", # Exception must not use a string literal, assign to variable first + "EM102", # Exception must not use an f-string literal, assign to variable first + "PTH100", # os.path.abspath() should be replaced by Path.resolve() + "PTH123", # open() should be replaced by Path.open() + "PLR0913", # Too many arguments in function definition + "PT009", # Use a regular assert instead of unittest-style assertEqual + "PLR0915", # Too many statements + "PLR0912", # Too many branches + "PLR0911", # Too many return statements + "FBT001", # Boolean-typed positional argument in function definition + "FBT002", # Boolean default positional argument in function definition + "BLE001", # Do not catch blind exception: Exception + "DTZ005", # datetime.datetime.now() called without a tz argument + "TRY301", # Abstract raise to an inner function + "TRY300", # Consider moving this statement to an else block + "B904", # Within an except clause, raise exceptions with raise ... from err + "S113", # Probable use of requests call without timeout + "S104", # Possible binding to all interfaces + "S101", # Usage of assert +] +fixable = ["ALL"] +dummy-variable-rgx = "^(_+|(_+[a-zA-Z0-9_]*[a-zA-Z0-9]+?))$" + +[tool.ruff.lint.per-file-ignores] +"roles/importer/files/importer/test/**.py" = ["SLF001", "PLR2004"] + + +[tool.ruff.format] +quote-style = "double" +indent-style = "space" +skip-magic-trailing-comma = false +line-ending = "auto" + + +[tool.pytest.ini_options] +pythonpath = [ + ".", + "roles/importer/files/importer", + "roles/importer/files/importer/test", +] diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000000..0bed96dd66 --- /dev/null +++ b/requirements.txt @@ -0,0 +1,2 @@ +ansible>2.13 +cryptography>=46.0.7 diff --git a/roles/.gitignore b/roles/.gitignore index dfcfd56f44..1b418032e1 100644 --- a/roles/.gitignore +++ b/roles/.gitignore @@ -2,7 +2,9 @@ ## files generated by popular Visual Studio add-ons. ## ## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore - +**/.venv/ +**/__pycache__/ +**/*.pyc # User-specific files *.rsuser *.suo diff --git a/roles/Directory.Build.props b/roles/Directory.Build.props new file mode 100644 index 0000000000..80e9ef7965 --- /dev/null +++ b/roles/Directory.Build.props @@ -0,0 +1,7 @@ + + + true + CS1998 + CS0618 + + \ No newline at end of file diff --git a/roles/FWO.sln b/roles/FWO.sln index 4b78c1b912..28220348ad 100644 --- a/roles/FWO.sln +++ b/roles/FWO.sln @@ -1,20 +1,18 @@  Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio Version 17 -VisualStudioVersion = 17.0.31815.197 +# Visual Studio Version 18 +VisualStudioVersion = 18.1.11312.151 d18.0 MinimumVisualStudioVersion = 10.0.40219.1 Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Lib", "Lib", "{CE55F125-0CD2-4789-A3C1-045DEF33ABA5}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FWO.Middleware.Client", "lib\files\FWO.Middleware.Client\FWO.Middleware.Client.csproj", "{ECB165CE-BE81-4C5C-B27A-D73177D73E28}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FWO.Test", "test\files\FWO.Test\FWO.Test.csproj", "{9C66B86B-FFB2-44A9-A944-54B33D31D413}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FWO.Test", "tests-unit\files\FWO.Test\FWO.Test.csproj", "{9C66B86B-FFB2-44A9-A944-54B33D31D413}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FWO.Report", "lib\files\FWO.Report\FWO.Report.csproj", "{84CA4892-7C35-4F1F-AF25-2A379112DFCA}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FWO.Report.Filter", "lib\files\FWO.Report.Filter\FWO.Report.Filter.csproj", "{A96D97D0-0E81-4723-AE99-841D4975FB67}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FWO.Middleware", "lib\files\FWO.Middleware\FWO.Middleware.csproj", "{C505E035-861A-4E6E-87CA-28583CC48895}" -EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FWO.Logging", "lib\files\FWO.Logging\FWO.Logging.csproj", "{0F0A43A7-66DD-4A7A-BC2E-3FB587838810}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FWO.Api.Client", "lib\files\FWO.Api.Client\FWO.Api.Client.csproj", "{C43BBC19-0147-44A4-AAF5-1CBC136A7A28}" @@ -27,14 +25,29 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FWO.Middleware.Server", "mi EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FWO.Ui", "ui\files\FWO.UI\FWO.Ui.csproj", "{A7ECA205-4916-4B66-8F37-15C656579D60}" EndProject -Project("{888888A0-9F3D-457C-B088-3A5042F75D52}") = "importer", "importer\importer.pyproj", "{1A1B90A0-227D-4041-A62A-F83AF9C9C7CF}" -EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FWO.DeviceAutoDiscovery", "lib\files\FWO.DeviceAutoDiscovery\FWO.DeviceAutoDiscovery.csproj", "{C1D1FE54-4CDD-41C0-AABC-415950AA24D5}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FWO.Mail", "lib\files\FWO.Mail\FWO.Mail.csproj", "{1E7CA417-C64A-4BD9-98D2-5A0A2DD94726}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FWO.Recert", "lib\files\FWO.Recert\FWO.Recert.csproj", "{520779B1-20EB-45D9-8A02-D0C4DFEC9302}" EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FWO.Encryption", "lib\files\FWO.Encryption\FWO.Encryption.csproj", "{6EBEBF57-3399-4008-BA10-0D21F6827244}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FWO.Basics", "lib\files\FWO.Basics\FWO.Basics.csproj", "{0CBD4CC5-3E39-4134-A0E1-4DB8999619F3}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FWO.Services", "lib\files\FWO.Services\FWO.Services.csproj", "{56021BEC-39E5-4EC7-B3DB-80834B57B2F0}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FWO.Data", "lib\files\FWO.Data\FWO.Data.csproj", "{9E80E931-7350-1356-D96D-34F3EDA6ABFB}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{02EA681E-C7D8-13C7-8484-4AC65E1B71E8}" + ProjectSection(SolutionItems) = preProject + .editorconfig = .editorconfig + EndProjectSection +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FWO.Compliance", "lib\files\FWO.Compliance\FWO.Compliance.csproj", "{A22D31CE-BAC6-4708-8B34-BCD46972F2F6}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FWO.ExternalSystems", "lib\files\FWO.ExternalSystems\FWO.ExternalSystems.csproj", "{4AEFC459-C0F3-4091-AA84-FDCE3F03F347}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -57,10 +70,6 @@ Global {A96D97D0-0E81-4723-AE99-841D4975FB67}.Debug|Any CPU.Build.0 = Debug|Any CPU {A96D97D0-0E81-4723-AE99-841D4975FB67}.Release|Any CPU.ActiveCfg = Release|Any CPU {A96D97D0-0E81-4723-AE99-841D4975FB67}.Release|Any CPU.Build.0 = Release|Any CPU - {C505E035-861A-4E6E-87CA-28583CC48895}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {C505E035-861A-4E6E-87CA-28583CC48895}.Debug|Any CPU.Build.0 = Debug|Any CPU - {C505E035-861A-4E6E-87CA-28583CC48895}.Release|Any CPU.ActiveCfg = Release|Any CPU - {C505E035-861A-4E6E-87CA-28583CC48895}.Release|Any CPU.Build.0 = Release|Any CPU {0F0A43A7-66DD-4A7A-BC2E-3FB587838810}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {0F0A43A7-66DD-4A7A-BC2E-3FB587838810}.Debug|Any CPU.Build.0 = Debug|Any CPU {0F0A43A7-66DD-4A7A-BC2E-3FB587838810}.Release|Any CPU.ActiveCfg = Release|Any CPU @@ -85,8 +94,6 @@ Global {A7ECA205-4916-4B66-8F37-15C656579D60}.Debug|Any CPU.Build.0 = Debug|Any CPU {A7ECA205-4916-4B66-8F37-15C656579D60}.Release|Any CPU.ActiveCfg = Release|Any CPU {A7ECA205-4916-4B66-8F37-15C656579D60}.Release|Any CPU.Build.0 = Release|Any CPU - {1A1B90A0-227D-4041-A62A-F83AF9C9C7CF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {1A1B90A0-227D-4041-A62A-F83AF9C9C7CF}.Release|Any CPU.ActiveCfg = Release|Any CPU {C1D1FE54-4CDD-41C0-AABC-415950AA24D5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {C1D1FE54-4CDD-41C0-AABC-415950AA24D5}.Debug|Any CPU.Build.0 = Debug|Any CPU {C1D1FE54-4CDD-41C0-AABC-415950AA24D5}.Release|Any CPU.ActiveCfg = Release|Any CPU @@ -99,6 +106,30 @@ Global {520779B1-20EB-45D9-8A02-D0C4DFEC9302}.Debug|Any CPU.Build.0 = Debug|Any CPU {520779B1-20EB-45D9-8A02-D0C4DFEC9302}.Release|Any CPU.ActiveCfg = Release|Any CPU {520779B1-20EB-45D9-8A02-D0C4DFEC9302}.Release|Any CPU.Build.0 = Release|Any CPU + {6EBEBF57-3399-4008-BA10-0D21F6827244}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {6EBEBF57-3399-4008-BA10-0D21F6827244}.Debug|Any CPU.Build.0 = Debug|Any CPU + {6EBEBF57-3399-4008-BA10-0D21F6827244}.Release|Any CPU.ActiveCfg = Release|Any CPU + {6EBEBF57-3399-4008-BA10-0D21F6827244}.Release|Any CPU.Build.0 = Release|Any CPU + {0CBD4CC5-3E39-4134-A0E1-4DB8999619F3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {0CBD4CC5-3E39-4134-A0E1-4DB8999619F3}.Debug|Any CPU.Build.0 = Debug|Any CPU + {0CBD4CC5-3E39-4134-A0E1-4DB8999619F3}.Release|Any CPU.ActiveCfg = Release|Any CPU + {0CBD4CC5-3E39-4134-A0E1-4DB8999619F3}.Release|Any CPU.Build.0 = Release|Any CPU + {56021BEC-39E5-4EC7-B3DB-80834B57B2F0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {56021BEC-39E5-4EC7-B3DB-80834B57B2F0}.Debug|Any CPU.Build.0 = Debug|Any CPU + {56021BEC-39E5-4EC7-B3DB-80834B57B2F0}.Release|Any CPU.ActiveCfg = Release|Any CPU + {56021BEC-39E5-4EC7-B3DB-80834B57B2F0}.Release|Any CPU.Build.0 = Release|Any CPU + {9E80E931-7350-1356-D96D-34F3EDA6ABFB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {9E80E931-7350-1356-D96D-34F3EDA6ABFB}.Debug|Any CPU.Build.0 = Debug|Any CPU + {9E80E931-7350-1356-D96D-34F3EDA6ABFB}.Release|Any CPU.ActiveCfg = Release|Any CPU + {9E80E931-7350-1356-D96D-34F3EDA6ABFB}.Release|Any CPU.Build.0 = Release|Any CPU + {A22D31CE-BAC6-4708-8B34-BCD46972F2F6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {A22D31CE-BAC6-4708-8B34-BCD46972F2F6}.Debug|Any CPU.Build.0 = Debug|Any CPU + {A22D31CE-BAC6-4708-8B34-BCD46972F2F6}.Release|Any CPU.ActiveCfg = Release|Any CPU + {A22D31CE-BAC6-4708-8B34-BCD46972F2F6}.Release|Any CPU.Build.0 = Release|Any CPU + {4AEFC459-C0F3-4091-AA84-FDCE3F03F347}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {4AEFC459-C0F3-4091-AA84-FDCE3F03F347}.Debug|Any CPU.Build.0 = Debug|Any CPU + {4AEFC459-C0F3-4091-AA84-FDCE3F03F347}.Release|Any CPU.ActiveCfg = Release|Any CPU + {4AEFC459-C0F3-4091-AA84-FDCE3F03F347}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -107,15 +138,14 @@ Global {ECB165CE-BE81-4C5C-B27A-D73177D73E28} = {CE55F125-0CD2-4789-A3C1-045DEF33ABA5} {84CA4892-7C35-4F1F-AF25-2A379112DFCA} = {CE55F125-0CD2-4789-A3C1-045DEF33ABA5} {A96D97D0-0E81-4723-AE99-841D4975FB67} = {CE55F125-0CD2-4789-A3C1-045DEF33ABA5} - {C505E035-861A-4E6E-87CA-28583CC48895} = {CE55F125-0CD2-4789-A3C1-045DEF33ABA5} {0F0A43A7-66DD-4A7A-BC2E-3FB587838810} = {CE55F125-0CD2-4789-A3C1-045DEF33ABA5} {C43BBC19-0147-44A4-AAF5-1CBC136A7A28} = {CE55F125-0CD2-4789-A3C1-045DEF33ABA5} {9225BD37-C13E-4A97-AACD-17E784FA52BB} = {CE55F125-0CD2-4789-A3C1-045DEF33ABA5} {F4972F10-28F8-4AE1-A5F6-C0E5DC1C0B29} = {CE55F125-0CD2-4789-A3C1-045DEF33ABA5} - {1A1B90A0-227D-4041-A62A-F83AF9C9C7CF} = {CE55F125-0CD2-4789-A3C1-045DEF33ABA5} {C1D1FE54-4CDD-41C0-AABC-415950AA24D5} = {CE55F125-0CD2-4789-A3C1-045DEF33ABA5} {1E7CA417-C64A-4BD9-98D2-5A0A2DD94726} = {CE55F125-0CD2-4789-A3C1-045DEF33ABA5} {520779B1-20EB-45D9-8A02-D0C4DFEC9302} = {CE55F125-0CD2-4789-A3C1-045DEF33ABA5} + {4AEFC459-C0F3-4091-AA84-FDCE3F03F347} = {CE55F125-0CD2-4789-A3C1-045DEF33ABA5} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {68364621-1011-4D44-9CF5-518F0DC3F459} diff --git a/roles/api/files/replace_metadata.json b/roles/api/files/replace_metadata.json index 791ca896a3..6ea978bb2f 100644 --- a/roles/api/files/replace_metadata.json +++ b/roles/api/files/replace_metadata.json @@ -11,14 +11,68 @@ "tables": [ { "table": { - "name": "ip_range", + "name": "criterion", "schema": "compliance" }, - "object_relationships": [ + "array_relationships": [ { - "name": "network_zone", + "name": "ip_ranges", "using": { - "foreign_key_constraint_on": "network_zone_id" + "foreign_key_constraint_on": { + "column": "criterion_id", + "table": { + "name": "ip_range", + "schema": "compliance" + } + } + } + }, + { + "name": "network_zone_communications", + "using": { + "foreign_key_constraint_on": { + "column": "criterion_id", + "table": { + "name": "network_zone_communication", + "schema": "compliance" + } + } + } + }, + { + "name": "network_zones", + "using": { + "foreign_key_constraint_on": { + "column": "criterion_id", + "table": { + "name": "network_zone", + "schema": "compliance" + } + } + } + }, + { + "name": "policy_criterions", + "using": { + "foreign_key_constraint_on": { + "column": "criterion_id", + "table": { + "name": "policy_criterion", + "schema": "compliance" + } + } + } + }, + { + "name": "violations", + "using": { + "foreign_key_constraint_on": { + "column": "criterion_id", + "table": { + "name": "violation", + "schema": "compliance" + } + } } } ], @@ -28,175 +82,284 @@ "permission": { "check": {}, "columns": [ - "network_zone_id", - "ip_range_end", - "ip_range_start" - ] - } - }, - { - "role": "importer", - "permission": { - "check": {}, - "columns": [ - "network_zone_id", - "ip_range_end", - "ip_range_start" + "id", + "comment", + "content", + "criterion_type", + "import_source", + "name", + "created", + "removed" ] - } + }, + "comment": "" }, { "role": "middleware-server", "permission": { "check": {}, "columns": [ - "network_zone_id", - "ip_range_end", - "ip_range_start" + "id", + "comment", + "content", + "criterion_type", + "import_source", + "name", + "created", + "removed" ] - } + }, + "comment": "" } ], "select_permissions": [ { - "role": "approver", + "role": "auditor", "permission": { "columns": [ - "network_zone_id", - "ip_range_end", - "ip_range_start" + "id", + "comment", + "content", + "criterion_type", + "import_source", + "name", + "created", + "removed" ], - "filter": {}, - "allow_aggregations": true - } + "filter": {} + }, + "comment": "" }, { - "role": "auditor", + "role": "fw-admin", "permission": { "columns": [ - "network_zone_id", - "ip_range_end", - "ip_range_start" + "id", + "comment", + "content", + "criterion_type", + "import_source", + "name", + "created", + "removed" ], - "filter": {}, - "allow_aggregations": true - } + "filter": {} + }, + "comment": "" }, { - "role": "fw-admin", + "role": "middleware-server", "permission": { "columns": [ - "network_zone_id", - "ip_range_end", - "ip_range_start" + "id", + "comment", + "content", + "criterion_type", + "import_source", + "name", + "created", + "removed" ], - "filter": {}, - "allow_aggregations": true - } + "filter": {} + }, + "comment": "" }, { - "role": "implementer", + "role": "reporter", "permission": { "columns": [ - "network_zone_id", - "ip_range_end", - "ip_range_start" + "id", + "comment", + "content", + "criterion_type", + "import_source", + "name", + "created", + "removed" ], - "filter": {}, - "allow_aggregations": true - } + "filter": {} + }, + "comment": "" }, { - "role": "importer", + "role": "reporter-viewall", "permission": { "columns": [ - "network_zone_id", - "ip_range_end", - "ip_range_start" + "id", + "comment", + "content", + "criterion_type", + "import_source", + "name", + "created", + "removed" + ], + "filter": {} + }, + "comment": "" + } + ], + "update_permissions": [ + { + "role": "fw-admin", + "permission": { + "columns": [ + "id", + "comment", + "content", + "criterion_type", + "import_source", + "name", + "created", + "removed" ], "filter": {}, - "allow_aggregations": true - } + "check": null + }, + "comment": "" }, { "role": "middleware-server", "permission": { "columns": [ - "network_zone_id", - "ip_range_end", - "ip_range_start" + "comment", + "import_source" ], "filter": {}, - "allow_aggregations": true + "check": null + }, + "comment": "" + } + ] + }, + { + "table": { + "name": "ip_range", + "schema": "compliance" + }, + "object_relationships": [ + { + "name": "criterion", + "using": { + "foreign_key_constraint_on": "criterion_id" } }, { - "role": "planner", + "name": "network_zone", + "using": { + "foreign_key_constraint_on": "network_zone_id" + } + } + ], + "insert_permissions": [ + { + "role": "fw-admin", "permission": { + "check": {}, "columns": [ "network_zone_id", "ip_range_end", - "ip_range_start" - ], - "filter": {}, - "allow_aggregations": true - } + "ip_range_start", + "criterion_id", + "name", + "created", + "removed" + ] + }, + "comment": "" }, { - "role": "recertifier", + "role": "middleware-server", + "permission": { + "check": {}, + "columns": [ + "network_zone_id", + "ip_range_end", + "ip_range_start", + "criterion_id", + "name", + "created", + "removed" + ] + } + } + ], + "select_permissions": [ + { + "role": "auditor", "permission": { "columns": [ "network_zone_id", "ip_range_end", - "ip_range_start" + "ip_range_start", + "criterion_id", + "name", + "created", + "removed" ], "filter": {}, "allow_aggregations": true } }, { - "role": "reporter", + "role": "fw-admin", "permission": { "columns": [ "network_zone_id", "ip_range_end", - "ip_range_start" + "ip_range_start", + "criterion_id", + "name", + "created", + "removed" ], "filter": {}, "allow_aggregations": true } }, { - "role": "reporter-viewall", + "role": "middleware-server", "permission": { "columns": [ "network_zone_id", "ip_range_end", - "ip_range_start" + "ip_range_start", + "criterion_id", + "name", + "created", + "removed" ], "filter": {}, "allow_aggregations": true } }, { - "role": "requester", + "role": "reporter", "permission": { "columns": [ "network_zone_id", "ip_range_end", - "ip_range_start" + "ip_range_start", + "criterion_id", + "name", + "created", + "removed" ], - "filter": {}, - "allow_aggregations": true - } + "filter": {} + }, + "comment": "" }, { - "role": "reviewer", + "role": "reporter-viewall", "permission": { "columns": [ "network_zone_id", "ip_range_end", - "ip_range_start" + "ip_range_start", + "criterion_id", + "name", + "created", + "removed" ], "filter": {}, "allow_aggregations": true @@ -210,19 +373,11 @@ "columns": [ "network_zone_id", "ip_range_end", - "ip_range_start" - ], - "filter": {}, - "check": {} - } - }, - { - "role": "importer", - "permission": { - "columns": [ - "network_zone_id", - "ip_range_end", - "ip_range_start" + "ip_range_start", + "criterion_id", + "name", + "created", + "removed" ], "filter": {}, "check": {} @@ -234,32 +389,16 @@ "columns": [ "network_zone_id", "ip_range_end", - "ip_range_start" + "ip_range_start", + "criterion_id", + "name", + "created", + "removed" ], "filter": {}, "check": {} } } - ], - "delete_permissions": [ - { - "role": "fw-admin", - "permission": { - "filter": {} - } - }, - { - "role": "importer", - "permission": { - "filter": {} - } - }, - { - "role": "middleware-server", - "permission": { - "filter": {} - } - } ] }, { @@ -268,6 +407,12 @@ "schema": "compliance" }, "object_relationships": [ + { + "name": "criterion", + "using": { + "foreign_key_constraint_on": "criterion_id" + } + }, { "name": "super_network_zone", "using": { @@ -335,20 +480,11 @@ "owner_id", "super_network_zone_id", "description", - "name" - ] - } - }, - { - "role": "importer", - "permission": { - "check": {}, - "columns": [ - "id", - "owner_id", - "super_network_zone_id", - "description", - "name" + "name", + "criterion_id", + "id_string", + "created", + "removed" ] } }, @@ -357,39 +493,35 @@ "permission": { "check": {}, "columns": [ + "created", + "criterion_id", + "description", "id", + "id_string", + "is_auto_calculated_internet_zone", + "is_auto_calculated_undefined_internal_zone", + "name", "owner_id", - "super_network_zone_id", - "description", - "name" + "removed", + "super_network_zone_id" ] } } ], "select_permissions": [ - { - "role": "approver", - "permission": { - "columns": [ - "id", - "name", - "description", - "super_network_zone_id", - "owner_id" - ], - "filter": {}, - "allow_aggregations": true - } - }, { "role": "auditor", "permission": { "columns": [ "id", - "name", - "description", + "owner_id", "super_network_zone_id", - "owner_id" + "description", + "name", + "criterion_id", + "id_string", + "created", + "removed" ], "filter": {}, "allow_aggregations": true @@ -400,38 +532,14 @@ "permission": { "columns": [ "id", - "name", - "description", + "owner_id", "super_network_zone_id", - "owner_id" - ], - "filter": {}, - "allow_aggregations": true - } - }, - { - "role": "implementer", - "permission": { - "columns": [ - "id", - "name", "description", - "super_network_zone_id", - "owner_id" - ], - "filter": {}, - "allow_aggregations": true - } - }, - { - "role": "importer", - "permission": { - "columns": [ - "id", "name", - "description", - "super_network_zone_id", - "owner_id" + "criterion_id", + "id_string", + "created", + "removed" ], "filter": {}, "allow_aggregations": true @@ -441,39 +549,17 @@ "role": "middleware-server", "permission": { "columns": [ - "id", - "name", - "description", - "super_network_zone_id", - "owner_id" - ], - "filter": {}, - "allow_aggregations": true - } - }, - { - "role": "planner", - "permission": { - "columns": [ - "id", - "name", + "created", + "criterion_id", "description", - "super_network_zone_id", - "owner_id" - ], - "filter": {}, - "allow_aggregations": true - } - }, - { - "role": "recertifier", - "permission": { - "columns": [ "id", + "id_string", + "is_auto_calculated_internet_zone", + "is_auto_calculated_undefined_internal_zone", "name", - "description", - "super_network_zone_id", - "owner_id" + "owner_id", + "removed", + "super_network_zone_id" ], "filter": {}, "allow_aggregations": true @@ -484,10 +570,14 @@ "permission": { "columns": [ "id", - "name", - "description", + "owner_id", "super_network_zone_id", - "owner_id" + "description", + "name", + "criterion_id", + "id_string", + "created", + "removed" ], "filter": {}, "allow_aggregations": true @@ -498,38 +588,14 @@ "permission": { "columns": [ "id", - "name", - "description", + "owner_id", "super_network_zone_id", - "owner_id" - ], - "filter": {}, - "allow_aggregations": true - } - }, - { - "role": "requester", - "permission": { - "columns": [ - "id", - "name", "description", - "super_network_zone_id", - "owner_id" - ], - "filter": {}, - "allow_aggregations": true - } - }, - { - "role": "reviewer", - "permission": { - "columns": [ - "id", "name", - "description", - "super_network_zone_id", - "owner_id" + "criterion_id", + "id_string", + "created", + "removed" ], "filter": {}, "allow_aggregations": true @@ -545,21 +611,11 @@ "owner_id", "super_network_zone_id", "description", - "name" - ], - "filter": {}, - "check": {} - } - }, - { - "role": "importer", - "permission": { - "columns": [ - "id", - "owner_id", - "super_network_zone_id", - "description", - "name" + "name", + "criterion_id", + "id_string", + "created", + "removed" ], "filter": {}, "check": {} @@ -569,36 +625,21 @@ "role": "middleware-server", "permission": { "columns": [ + "created", + "criterion_id", + "description", "id", + "id_string", + "is_auto_calculated_internet_zone", + "name", "owner_id", - "super_network_zone_id", - "description", - "name" + "removed", + "super_network_zone_id" ], "filter": {}, "check": {} } } - ], - "delete_permissions": [ - { - "role": "fw-admin", - "permission": { - "filter": {} - } - }, - { - "role": "importer", - "permission": { - "filter": {} - } - }, - { - "role": "middleware-server", - "permission": { - "filter": {} - } - } ] }, { @@ -607,6 +648,12 @@ "schema": "compliance" }, "object_relationships": [ + { + "name": "criterion", + "using": { + "foreign_key_constraint_on": "criterion_id" + } + }, { "name": "from_network_zone", "using": { @@ -627,17 +674,10 @@ "check": {}, "columns": [ "from_network_zone_id", - "to_network_zone_id" - ] - } - }, - { - "role": "importer", - "permission": { - "check": {}, - "columns": [ - "from_network_zone_id", - "to_network_zone_id" + "to_network_zone_id", + "criterion_id", + "created", + "removed" ] } }, @@ -647,2229 +687,2959 @@ "check": {}, "columns": [ "from_network_zone_id", - "to_network_zone_id" + "to_network_zone_id", + "criterion_id", + "created", + "removed" ] } } ], "select_permissions": [ { - "role": "approver", + "role": "auditor", "permission": { "columns": [ "from_network_zone_id", - "to_network_zone_id" + "to_network_zone_id", + "criterion_id", + "created", + "removed" ], "filter": {}, "allow_aggregations": true } }, { - "role": "auditor", + "role": "fw-admin", "permission": { "columns": [ "from_network_zone_id", - "to_network_zone_id" + "to_network_zone_id", + "criterion_id", + "created", + "removed" ], "filter": {}, "allow_aggregations": true } }, { - "role": "fw-admin", + "role": "middleware-server", "permission": { "columns": [ "from_network_zone_id", - "to_network_zone_id" + "to_network_zone_id", + "criterion_id", + "created", + "removed" ], "filter": {}, "allow_aggregations": true } }, { - "role": "implementer", + "role": "reporter", "permission": { "columns": [ "from_network_zone_id", - "to_network_zone_id" + "to_network_zone_id", + "criterion_id", + "created", + "removed" ], "filter": {}, "allow_aggregations": true } }, { - "role": "importer", + "role": "reporter-viewall", "permission": { "columns": [ "from_network_zone_id", - "to_network_zone_id" + "to_network_zone_id", + "criterion_id", + "created", + "removed" ], "filter": {}, "allow_aggregations": true } - }, + } + ], + "update_permissions": [ { - "role": "middleware-server", + "role": "fw-admin", "permission": { "columns": [ "from_network_zone_id", - "to_network_zone_id" + "to_network_zone_id", + "criterion_id", + "created", + "removed" ], "filter": {}, - "allow_aggregations": true + "check": {} } }, { - "role": "planner", + "role": "middleware-server", "permission": { "columns": [ "from_network_zone_id", - "to_network_zone_id" + "to_network_zone_id", + "criterion_id", + "created", + "removed" ], "filter": {}, - "allow_aggregations": true + "check": {} + } + } + ] + }, + { + "table": { + "name": "policy", + "schema": "compliance" + }, + "array_relationships": [ + { + "name": "policy_criterions", + "using": { + "foreign_key_constraint_on": { + "column": "policy_id", + "table": { + "name": "policy_criterion", + "schema": "compliance" + } + } } }, { - "role": "recertifier", + "name": "violations", + "using": { + "foreign_key_constraint_on": { + "column": "policy_id", + "table": { + "name": "violation", + "schema": "compliance" + } + } + } + } + ], + "select_permissions": [ + { + "role": "auditor", "permission": { "columns": [ - "from_network_zone_id", - "to_network_zone_id" + "disabled", + "id", + "name", + "created_date" ], - "filter": {}, - "allow_aggregations": true - } + "filter": {} + }, + "comment": "" }, { - "role": "reporter", + "role": "fw-admin", "permission": { "columns": [ - "from_network_zone_id", - "to_network_zone_id" + "disabled", + "id", + "name", + "created_date" ], - "filter": {}, - "allow_aggregations": true - } + "filter": {} + }, + "comment": "" }, { - "role": "reporter-viewall", + "role": "middleware-server", "permission": { "columns": [ - "from_network_zone_id", - "to_network_zone_id" + "disabled", + "id", + "name", + "created_date" ], - "filter": {}, - "allow_aggregations": true + "filter": {} + }, + "comment": "" + } + ] + }, + { + "table": { + "name": "policy_criterion", + "schema": "compliance" + }, + "object_relationships": [ + { + "name": "criterion", + "using": { + "foreign_key_constraint_on": "criterion_id" } }, { - "role": "requester", + "name": "policy", + "using": { + "foreign_key_constraint_on": "policy_id" + } + } + ], + "select_permissions": [ + { + "role": "auditor", "permission": { "columns": [ - "from_network_zone_id", - "to_network_zone_id" + "criterion_id", + "policy_id", + "created", + "removed" ], - "filter": {}, - "allow_aggregations": true - } + "filter": {} + }, + "comment": "" }, { - "role": "reviewer", + "role": "fw-admin", "permission": { "columns": [ - "from_network_zone_id", - "to_network_zone_id" + "criterion_id", + "policy_id", + "created", + "removed" ], - "filter": {}, - "allow_aggregations": true + "filter": {} + }, + "comment": "" + }, + { + "role": "middleware-server", + "permission": { + "columns": [ + "criterion_id", + "policy_id", + "created", + "removed" + ], + "filter": {} + }, + "comment": "" + } + ] + }, + { + "table": { + "name": "violation", + "schema": "compliance" + }, + "object_relationships": [ + { + "name": "criterion", + "using": { + "foreign_key_constraint_on": "criterion_id" + } + }, + { + "name": "policy", + "using": { + "foreign_key_constraint_on": "policy_id" + } + }, + { + "name": "rule", + "using": { + "foreign_key_constraint_on": "rule_id" } } ], - "update_permissions": [ + "insert_permissions": [ + { + "role": "middleware-server", + "permission": { + "check": {}, + "columns": [ + "criterion_id", + "details", + "found_date", + "id", + "is_initial", + "mgmt_uid", + "policy_id", + "removed_date", + "risk_score", + "rule_id", + "rule_uid" + ] + }, + "comment": "" + } + ], + "select_permissions": [ + { + "role": "auditor", + "permission": { + "columns": [ + "criterion_id", + "details", + "found_date", + "id", + "is_initial", + "mgmt_uid", + "policy_id", + "removed_date", + "risk_score", + "rule_id", + "rule_uid" + ], + "filter": {} + }, + "comment": "" + }, { "role": "fw-admin", "permission": { "columns": [ - "from_network_zone_id", - "to_network_zone_id" + "criterion_id", + "details", + "found_date", + "id", + "is_initial", + "mgmt_uid", + "policy_id", + "removed_date", + "risk_score", + "rule_id", + "rule_uid" ], - "filter": {}, - "check": {} - } + "filter": {} + }, + "comment": "" }, { - "role": "importer", + "role": "middleware-server", "permission": { "columns": [ - "from_network_zone_id", - "to_network_zone_id" + "criterion_id", + "details", + "found_date", + "id", + "is_initial", + "mgmt_uid", + "policy_id", + "removed_date", + "risk_score", + "rule_id", + "rule_uid" ], "filter": {}, - "check": {} - } - }, + "allow_aggregations": true + }, + "comment": "" + } + ], + "update_permissions": [ { "role": "middleware-server", "permission": { "columns": [ - "from_network_zone_id", - "to_network_zone_id" + "removed_date" ], "filter": {}, - "check": {} + "check": null + }, + "comment": "" + } + ] + }, + { + "table": { + "name": "change_history", + "schema": "modelling" + }, + "object_relationships": [ + { + "name": "owner", + "using": { + "foreign_key_constraint_on": "app_id" } } ], - "delete_permissions": [ + "insert_permissions": [ { - "role": "fw-admin", + "role": "middleware-server", "permission": { - "filter": {} - } + "check": {}, + "columns": [ + "id", + "object_id", + "changer", + "change_text", + "app_id", + "change_type", + "object_type", + "change_time", + "change_source" + ] + }, + "comment": "" }, { - "role": "importer", + "role": "modeller", + "permission": { + "check": {}, + "columns": [ + "id", + "object_id", + "changer", + "change_text", + "app_id", + "change_type", + "object_type", + "change_time", + "change_source" + ] + }, + "comment": "" + } + ], + "select_permissions": [ + { + "role": "auditor", "permission": { + "columns": [ + "id", + "object_id", + "changer", + "change_text", + "app_id", + "change_type", + "object_type", + "change_time", + "change_source" + ], "filter": {} - } + }, + "comment": "" }, { "role": "middleware-server", "permission": { + "columns": [ + "id" + ], "filter": {} - } + }, + "comment": "" + }, + { + "role": "modeller", + "permission": { + "columns": [ + "id", + "object_id", + "changer", + "change_text", + "app_id", + "change_type", + "object_type", + "change_time", + "change_source" + ], + "filter": {} + }, + "comment": "" } ] }, { "table": { - "name": "alert", - "schema": "public" + "name": "connection", + "schema": "modelling" }, "object_relationships": [ { - "name": "device", + "name": "connection", "using": { - "foreign_key_constraint_on": "alert_dev_id" + "foreign_key_constraint_on": "used_interface_id" } }, { - "name": "log_data_issue", + "name": "owner", "using": { - "foreign_key_constraint_on": "ref_log_id" + "foreign_key_constraint_on": "app_id" } }, { - "name": "management", + "name": "ownerByProposedAppId", "using": { - "foreign_key_constraint_on": "alert_mgm_id" + "foreign_key_constraint_on": "proposed_app_id" } - }, + } + ], + "array_relationships": [ { - "name": "uiuser", + "name": "connections", "using": { - "foreign_key_constraint_on": "ack_by" + "foreign_key_constraint_on": { + "column": "used_interface_id", + "table": { + "name": "connection", + "schema": "modelling" + } + } } }, { - "name": "uiuserByUserId", + "name": "nwgroup_connections", "using": { - "foreign_key_constraint_on": "user_id" + "foreign_key_constraint_on": { + "column": "connection_id", + "table": { + "name": "nwgroup_connection", + "schema": "modelling" + } + } } - } - ], - "insert_permissions": [ + }, { - "role": "approver", - "permission": { - "check": {}, - "columns": [ - "ack_by", - "ack_timestamp", - "alert_code", - "alert_dev_id", - "alert_id", - "alert_mgm_id", - "alert_timestamp", - "description", - "json_data", - "ref_alert_id", - "ref_log_id", - "source", - "title", - "user_id" - ] + "name": "nwobject_connections", + "using": { + "foreign_key_constraint_on": { + "column": "connection_id", + "table": { + "name": "nwobject_connection", + "schema": "modelling" + } + } } }, { - "role": "fw-admin", - "permission": { - "check": {}, - "columns": [ - "ack_by", - "ack_timestamp", - "alert_code", - "alert_dev_id", - "alert_id", - "alert_mgm_id", - "alert_timestamp", - "description", - "json_data", - "ref_alert_id", - "ref_log_id", - "source", - "title", - "user_id" - ] + "name": "permitted_owners", + "using": { + "manual_configuration": { + "column_mapping": { + "id": "connection_id" + }, + "insertion_order": null, + "remote_table": { + "name": "permitted_owners", + "schema": "modelling" + } + } } }, { - "role": "implementer", - "permission": { - "check": {}, - "columns": [ - "ack_by", - "ack_timestamp", - "alert_code", - "alert_dev_id", - "alert_id", - "alert_mgm_id", - "alert_timestamp", - "description", - "json_data", - "ref_alert_id", - "ref_log_id", - "source", - "title", - "user_id" - ] + "name": "selected_connections", + "using": { + "foreign_key_constraint_on": { + "column": "connection_id", + "table": { + "name": "selected_connections", + "schema": "modelling" + } + } } }, { - "role": "importer", - "permission": { - "check": {}, - "columns": [ - "ack_by", - "ack_timestamp", - "alert_code", - "alert_dev_id", - "alert_id", - "alert_mgm_id", - "alert_timestamp", - "description", - "json_data", - "ref_alert_id", - "ref_log_id", - "source", - "title", - "user_id" - ] + "name": "service_connections", + "using": { + "foreign_key_constraint_on": { + "column": "connection_id", + "table": { + "name": "service_connection", + "schema": "modelling" + } + } } }, { - "role": "middleware-server", + "name": "service_group_connections", + "using": { + "foreign_key_constraint_on": { + "column": "connection_id", + "table": { + "name": "service_group_connection", + "schema": "modelling" + } + } + } + } + ], + "insert_permissions": [ + { + "role": "modeller", "permission": { - "check": {}, + "check": { + "_or": [ + { + "app_id": { + "_in": "x-hasura-editable-owners" + } + }, + { + "app_id": { + "_is_null": true + } + } + ] + }, "columns": [ - "ack_by", - "ack_timestamp", - "alert_code", - "alert_dev_id", - "alert_id", - "alert_mgm_id", - "alert_timestamp", - "description", - "json_data", - "ref_alert_id", - "ref_log_id", - "source", - "title", - "user_id" + "app_id", + "common_service", + "conn_prop", + "creation_date", + "creator", + "extra_params", + "id", + "interface_permission", + "is_interface", + "is_published", + "is_requested", + "name", + "proposed_app_id", + "reason", + "removal_date", + "removed", + "requested_on_fw", + "ticket_id", + "used_interface_id" ] - } - }, + }, + "comment": "" + } + ], + "select_permissions": [ { - "role": "planner", + "role": "auditor", "permission": { - "check": {}, "columns": [ - "ack_by", - "ack_timestamp", - "alert_code", - "alert_dev_id", - "alert_id", - "alert_mgm_id", - "alert_timestamp", - "description", - "json_data", - "ref_alert_id", - "ref_log_id", - "source", - "title", - "user_id" - ] - } + "ticket_id", + "common_service", + "is_interface", + "is_published", + "is_requested", + "removed", + "requested_on_fw", + "conn_prop", + "creator", + "extra_params", + "interface_permission", + "name", + "app_id", + "id", + "proposed_app_id", + "used_interface_id", + "reason", + "creation_date", + "removal_date" + ], + "filter": {}, + "allow_aggregations": true + }, + "comment": "" }, { - "role": "recertifier", + "role": "middleware-server", "permission": { - "check": {}, "columns": [ - "ack_by", - "ack_timestamp", - "alert_code", - "alert_dev_id", - "alert_id", - "alert_mgm_id", - "alert_timestamp", - "description", - "json_data", - "ref_alert_id", - "ref_log_id", - "source", - "title", - "user_id" - ] - } + "ticket_id", + "common_service", + "is_interface", + "is_published", + "is_requested", + "removed", + "requested_on_fw", + "conn_prop", + "creator", + "extra_params", + "interface_permission", + "name", + "app_id", + "id", + "proposed_app_id", + "used_interface_id", + "reason", + "creation_date", + "removal_date" + ], + "filter": {} + }, + "comment": "" }, { - "role": "reporter", + "role": "modeller", "permission": { - "check": {}, "columns": [ - "ack_by", - "ack_timestamp", - "alert_code", - "alert_dev_id", - "alert_id", - "alert_mgm_id", - "alert_timestamp", - "description", - "json_data", - "ref_alert_id", - "ref_log_id", - "source", - "title", - "user_id" - ] - } - }, + "ticket_id", + "common_service", + "is_interface", + "is_published", + "is_requested", + "removed", + "requested_on_fw", + "conn_prop", + "creator", + "extra_params", + "interface_permission", + "name", + "app_id", + "id", + "proposed_app_id", + "used_interface_id", + "reason", + "creation_date", + "removal_date" + ], + "filter": {}, + "allow_aggregations": true + }, + "comment": "" + } + ], + "update_permissions": [ { - "role": "reporter-viewall", + "role": "implementer", "permission": { - "check": {}, "columns": [ - "ack_by", - "ack_timestamp", - "alert_code", - "alert_dev_id", - "alert_id", - "alert_mgm_id", - "alert_timestamp", - "description", - "json_data", - "ref_alert_id", - "ref_log_id", - "source", - "title", - "user_id" - ] - } + "conn_prop" + ], + "filter": {}, + "check": {} + }, + "comment": "" }, { - "role": "requester", + "role": "middleware-server", "permission": { - "check": {}, "columns": [ - "ack_by", - "ack_timestamp", - "alert_code", - "alert_dev_id", - "alert_id", - "alert_mgm_id", - "alert_timestamp", - "description", - "json_data", - "ref_alert_id", - "ref_log_id", - "source", - "title", - "user_id" - ] - } + "conn_prop" + ], + "filter": {}, + "check": {} + }, + "comment": "" }, { - "role": "reviewer", + "role": "modeller", "permission": { - "check": {}, "columns": [ - "ack_by", - "ack_timestamp", - "alert_code", - "alert_dev_id", - "alert_id", - "alert_mgm_id", - "alert_timestamp", - "description", - "json_data", - "ref_alert_id", - "ref_log_id", - "source", - "title", - "user_id" - ] + "ticket_id", + "common_service", + "is_interface", + "is_published", + "is_requested", + "removed", + "requested_on_fw", + "conn_prop", + "creator", + "extra_params", + "interface_permission", + "name", + "app_id", + "id", + "proposed_app_id", + "used_interface_id", + "reason", + "creation_date", + "removal_date" + ], + "filter": {}, + "check": {} + }, + "comment": "" + } + ], + "delete_permissions": [ + { + "role": "modeller", + "permission": { + "filter": { + "_or": [ + { + "app_id": { + "_in": "x-hasura-editable-owners" + } + }, + { + "app_id": { + "_is_null": true + } + } + ] + } + }, + "comment": "" + } + ] + }, + { + "table": { + "name": "nwgroup", + "schema": "modelling" + }, + "object_relationships": [ + { + "name": "owner", + "using": { + "foreign_key_constraint_on": "app_id" } } ], - "select_permissions": [ + "array_relationships": [ { - "role": "approver", + "name": "nwgroup_connections", + "using": { + "foreign_key_constraint_on": { + "column": "nwgroup_id", + "table": { + "name": "nwgroup_connection", + "schema": "modelling" + } + } + } + }, + { + "name": "nwobject_nwgroups", + "using": { + "foreign_key_constraint_on": { + "column": "nwgroup_id", + "table": { + "name": "nwobject_nwgroup", + "schema": "modelling" + } + } + } + }, + { + "name": "selected_objects", + "using": { + "foreign_key_constraint_on": { + "column": "nwgroup_id", + "table": { + "name": "selected_objects", + "schema": "modelling" + } + } + } + } + ], + "insert_permissions": [ + { + "role": "middleware-server", "permission": { + "check": {}, "columns": [ - "alert_id", - "ref_alert_id", - "ref_log_id", - "description", - "source", - "title", - "ack_by", - "alert_code", - "alert_dev_id", - "alert_mgm_id", - "user_id", - "json_data", - "ack_timestamp", - "alert_timestamp" - ], - "filter": {} - } + "id", + "is_deleted", + "comment", + "creator", + "id_string", + "name", + "app_id", + "group_type", + "creation_date" + ] + }, + "comment": "" }, + { + "role": "modeller", + "permission": { + "check": { + "app_id": { + "_in": "x-hasura-editable-owners" + } + }, + "columns": [ + "id", + "is_deleted", + "comment", + "creator", + "id_string", + "name", + "app_id", + "group_type", + "creation_date" + ] + }, + "comment": "" + } + ], + "select_permissions": [ { "role": "auditor", "permission": { "columns": [ - "ack_by", - "ack_timestamp", - "alert_code", - "alert_dev_id", - "alert_id", - "alert_mgm_id", - "alert_timestamp", - "description", - "json_data", - "ref_alert_id", - "ref_log_id", - "source", - "title", - "user_id" + "id", + "is_deleted", + "comment", + "creator", + "id_string", + "name", + "app_id", + "group_type", + "creation_date" ], "filter": {} - } + }, + "comment": "" }, { - "role": "fw-admin", + "role": "middleware-server", "permission": { "columns": [ - "ack_by", - "ack_timestamp", - "alert_code", - "alert_dev_id", - "alert_id", - "alert_mgm_id", - "alert_timestamp", - "description", - "json_data", - "ref_alert_id", - "ref_log_id", - "source", - "title", - "user_id" + "id", + "is_deleted", + "comment", + "creator", + "id_string", + "name", + "app_id", + "group_type", + "creation_date" ], "filter": {} - } + }, + "comment": "" }, { - "role": "implementer", + "role": "modeller", "permission": { "columns": [ - "alert_id", - "ref_alert_id", - "ref_log_id", - "description", - "source", - "title", - "ack_by", - "alert_code", - "alert_dev_id", - "alert_mgm_id", - "user_id", - "json_data", - "ack_timestamp", - "alert_timestamp" + "id", + "is_deleted", + "comment", + "creator", + "id_string", + "name", + "app_id", + "group_type", + "creation_date" ], "filter": {} - } - }, + }, + "comment": "" + } + ], + "update_permissions": [ { - "role": "importer", + "role": "middleware-server", "permission": { "columns": [ - "alert_id", - "ref_alert_id", - "ref_log_id", - "description", - "source", - "title", - "ack_by", - "alert_code", - "alert_dev_id", - "alert_mgm_id", - "user_id", - "json_data", - "ack_timestamp", - "alert_timestamp" + "is_deleted" ], "filter": {}, - "allow_aggregations": true - } + "check": null + }, + "comment": "" }, { - "role": "middleware-server", + "role": "modeller", "permission": { "columns": [ - "ack_by", - "ack_timestamp", - "alert_code", - "alert_dev_id", - "alert_id", - "alert_mgm_id", - "alert_timestamp", - "description", - "json_data", - "ref_alert_id", - "ref_log_id", - "source", - "title", - "user_id" + "id", + "is_deleted", + "comment", + "creator", + "id_string", + "name", + "app_id", + "group_type", + "creation_date" ], + "filter": { + "app_id": { + "_in": "x-hasura-editable-owners" + } + }, + "check": {} + }, + "comment": "" + } + ], + "delete_permissions": [ + { + "role": "middleware-server", + "permission": { "filter": {} - } + }, + "comment": "" }, { - "role": "planner", + "role": "modeller", "permission": { - "columns": [ - "alert_id", - "ref_alert_id", - "ref_log_id", - "description", - "source", - "title", - "ack_by", - "alert_code", - "alert_dev_id", - "alert_mgm_id", - "user_id", - "json_data", - "ack_timestamp", - "alert_timestamp" - ], - "filter": {} + "filter": { + "app_id": { + "_in": "x-hasura-editable-owners" + } + } + }, + "comment": "" + } + ] + }, + { + "table": { + "name": "nwgroup_connection", + "schema": "modelling" + }, + "object_relationships": [ + { + "name": "connection", + "using": { + "foreign_key_constraint_on": "connection_id" } }, { - "role": "reporter", + "name": "nwgroup", + "using": { + "foreign_key_constraint_on": "nwgroup_id" + } + } + ], + "insert_permissions": [ + { + "role": "modeller", "permission": { + "check": {}, "columns": [ - "alert_id", - "ref_alert_id", - "ref_log_id", - "description", - "source", - "title", - "ack_by", - "alert_code", - "alert_dev_id", - "alert_mgm_id", - "user_id", - "json_data", - "ack_timestamp", - "alert_timestamp" + "nwgroup_id", + "connection_field", + "connection_id" + ] + }, + "comment": "" + } + ], + "select_permissions": [ + { + "role": "auditor", + "permission": { + "columns": [ + "nwgroup_id", + "connection_field", + "connection_id" ], "filter": {} - } + }, + "comment": "" }, { - "role": "requester", + "role": "middleware-server", "permission": { "columns": [ - "alert_id", - "ref_alert_id", - "ref_log_id", - "description", - "source", - "title", - "ack_by", - "alert_code", - "alert_dev_id", - "alert_mgm_id", - "user_id", - "json_data", - "ack_timestamp", - "alert_timestamp" + "nwgroup_id", + "connection_field", + "connection_id" ], "filter": {} - } + }, + "comment": "" }, { - "role": "reviewer", + "role": "modeller", "permission": { "columns": [ - "alert_id", - "ref_alert_id", - "ref_log_id", - "description", - "source", - "title", - "ack_by", - "alert_code", - "alert_dev_id", - "alert_mgm_id", - "user_id", - "json_data", - "ack_timestamp", - "alert_timestamp" + "nwgroup_id", + "connection_field", + "connection_id" ], "filter": {} - } + }, + "comment": "" } ], - "update_permissions": [ + "delete_permissions": [ { - "role": "approver", + "role": "modeller", "permission": { - "columns": [ - "ack_by", - "ack_timestamp" - ], - "filter": {}, - "check": null + "filter": {} + }, + "comment": "" + } + ] + }, + { + "table": { + "name": "nwobject_connection", + "schema": "modelling" + }, + "object_relationships": [ + { + "name": "connection", + "using": { + "foreign_key_constraint_on": "connection_id" } }, { - "role": "fw-admin", - "permission": { - "columns": [ - "ack_by", - "ack_timestamp", - "alert_code", - "alert_dev_id", - "alert_id", - "alert_mgm_id", - "alert_timestamp", - "description", - "json_data", - "ref_alert_id", - "ref_log_id", - "source", - "title", - "user_id" - ], - "filter": {}, - "check": null + "name": "owner_network", + "using": { + "foreign_key_constraint_on": "nwobject_id" } - }, + } + ], + "insert_permissions": [ { - "role": "implementer", + "role": "modeller", "permission": { + "check": {}, "columns": [ - "ack_by", - "ack_timestamp" - ], - "filter": {}, - "check": null - } - }, + "nwobject_id", + "connection_field", + "connection_id" + ] + }, + "comment": "" + } + ], + "select_permissions": [ { - "role": "importer", + "role": "auditor", "permission": { "columns": [ - "alert_id", - "ref_alert_id", - "ref_log_id", - "description", - "source", - "title", - "ack_by", - "alert_code", - "alert_dev_id", - "alert_mgm_id", - "user_id", - "json_data", - "ack_timestamp", - "alert_timestamp" + "nwobject_id", + "connection_field", + "connection_id" ], - "filter": {}, - "check": null - } + "filter": {} + }, + "comment": "" }, { "role": "middleware-server", "permission": { "columns": [ - "ack_by", - "ack_timestamp" + "nwobject_id", + "connection_field", + "connection_id" ], - "filter": {}, - "check": {} - } + "filter": {} + }, + "comment": "" }, { - "role": "planner", + "role": "modeller", "permission": { "columns": [ - "ack_by", - "ack_timestamp" + "nwobject_id", + "connection_field", + "connection_id" ], - "filter": {}, - "check": null + "filter": {} + }, + "comment": "" + } + ], + "delete_permissions": [ + { + "role": "modeller", + "permission": { + "filter": {} + }, + "comment": "" + } + ] + }, + { + "table": { + "name": "nwobject_nwgroup", + "schema": "modelling" + }, + "object_relationships": [ + { + "name": "nwgroup", + "using": { + "foreign_key_constraint_on": "nwgroup_id" } }, { - "role": "recertifier", + "name": "owner_network", + "using": { + "foreign_key_constraint_on": "nwobject_id" + } + } + ], + "insert_permissions": [ + { + "role": "middleware-server", "permission": { + "check": {}, "columns": [ - "ack_by", - "ack_timestamp" - ], - "filter": {}, - "check": null - } + "nwgroup_id", + "nwobject_id" + ] + }, + "comment": "" }, { - "role": "reporter", + "role": "modeller", "permission": { + "check": {}, "columns": [ - "ack_by", - "ack_timestamp" - ], - "filter": {}, - "check": null - } - }, + "nwobject_id", + "nwgroup_id" + ] + }, + "comment": "" + } + ], + "select_permissions": [ { - "role": "reporter-viewall", + "role": "auditor", "permission": { "columns": [ - "ack_by", - "ack_timestamp" + "nwobject_id", + "nwgroup_id" ], - "filter": {}, - "check": null - } + "filter": {} + }, + "comment": "" }, { - "role": "requester", + "role": "middleware-server", "permission": { "columns": [ - "ack_by", - "ack_timestamp" + "nwgroup_id", + "nwobject_id" ], - "filter": {}, - "check": null - } + "filter": {} + }, + "comment": "" }, { - "role": "reviewer", + "role": "modeller", "permission": { "columns": [ - "ack_by", - "ack_timestamp" + "nwobject_id", + "nwgroup_id" ], - "filter": {}, - "check": null - } + "filter": {} + }, + "comment": "" + } + ], + "delete_permissions": [ + { + "role": "middleware-server", + "permission": { + "filter": {} + }, + "comment": "" + }, + { + "role": "modeller", + "permission": { + "filter": {} + }, + "comment": "" } ] }, { "table": { - "name": "changelog_object", - "schema": "public" + "name": "permitted_owners", + "schema": "modelling" }, "object_relationships": [ { - "name": "import_control", + "name": "connection", "using": { - "foreign_key_constraint_on": "control_id" + "manual_configuration": { + "column_mapping": { + "connection_id": "id" + }, + "insertion_order": null, + "remote_table": { + "name": "connection", + "schema": "modelling" + } + } } }, { - "name": "management", + "name": "owner", "using": { - "foreign_key_constraint_on": "mgm_id" + "manual_configuration": { + "column_mapping": { + "app_id": "id" + }, + "insertion_order": null, + "remote_table": { + "name": "owner", + "schema": "public" + } + } } - }, + } + ], + "insert_permissions": [ { - "name": "object", - "using": { - "foreign_key_constraint_on": "new_obj_id" - } - }, + "role": "modeller", + "permission": { + "check": {}, + "columns": [ + "connection_id", + "app_id" + ] + }, + "comment": "" + } + ], + "select_permissions": [ { - "name": "objectByOldObjId", - "using": { - "foreign_key_constraint_on": "old_obj_id" - } + "role": "auditor", + "permission": { + "columns": [ + "connection_id", + "app_id" + ], + "filter": {} + }, + "comment": "" }, { - "name": "stm_change_type", - "using": { - "foreign_key_constraint_on": "change_type_id" - } - }, + "role": "modeller", + "permission": { + "columns": [ + "connection_id", + "app_id" + ], + "filter": {} + }, + "comment": "" + } + ], + "delete_permissions": [ { - "name": "uiuser", + "role": "modeller", + "permission": { + "filter": {} + }, + "comment": "" + } + ] + }, + { + "table": { + "name": "selected_connections", + "schema": "modelling" + }, + "object_relationships": [ + { + "name": "connection", "using": { - "foreign_key_constraint_on": "doku_admin" + "foreign_key_constraint_on": "connection_id" } }, { - "name": "uiuserByImportAdmin", + "name": "owner", "using": { - "foreign_key_constraint_on": "import_admin" + "foreign_key_constraint_on": "app_id" } } ], + "insert_permissions": [ + { + "role": "modeller", + "permission": { + "check": {}, + "columns": [ + "app_id", + "connection_id" + ] + }, + "comment": "" + } + ], "select_permissions": [ { - "role": "importer", + "role": "auditor", "permission": { "columns": [ - "log_obj_id", - "new_obj_id", - "old_obj_id", - "import_admin", - "doku_admin", - "control_id", - "abs_change_id", - "change_action", - "changelog_obj_comment", - "documented", - "docu_time", - "mgm_id", - "change_type_id", - "security_relevant", - "change_request_info", - "change_time", - "unique_name" + "app_id", + "connection_id" ], - "filter": {}, - "allow_aggregations": true - } + "filter": {} + }, + "comment": "" + }, + { + "role": "modeller", + "permission": { + "columns": [ + "app_id", + "connection_id" + ], + "filter": {} + }, + "comment": "" + } + ], + "delete_permissions": [ + { + "role": "modeller", + "permission": { + "filter": {} + }, + "comment": "" } ] }, { "table": { - "name": "changelog_rule", - "schema": "public" + "name": "selected_objects", + "schema": "modelling" }, "object_relationships": [ { - "name": "device", + "name": "nwgroup", "using": { - "foreign_key_constraint_on": "dev_id" + "foreign_key_constraint_on": "nwgroup_id" } }, { - "name": "import_control", + "name": "owner", "using": { - "foreign_key_constraint_on": "control_id" + "foreign_key_constraint_on": "app_id" } + } + ], + "insert_permissions": [ + { + "role": "modeller", + "permission": { + "check": {}, + "columns": [ + "nwgroup_id", + "app_id" + ] + }, + "comment": "" + } + ], + "select_permissions": [ + { + "role": "auditor", + "permission": { + "columns": [ + "nwgroup_id", + "app_id" + ], + "filter": {} + }, + "comment": "" }, { - "name": "management", - "using": { - "foreign_key_constraint_on": "mgm_id" - } + "role": "middleware-server", + "permission": { + "columns": [ + "nwgroup_id" + ], + "filter": {} + }, + "comment": "" }, { - "name": "rule", - "using": { - "foreign_key_constraint_on": "new_rule_id" - } + "role": "modeller", + "permission": { + "columns": [ + "nwgroup_id", + "app_id" + ], + "filter": {} + }, + "comment": "" + } + ], + "delete_permissions": [ + { + "role": "middleware-server", + "permission": { + "filter": {} + }, + "comment": "" }, { - "name": "ruleByOldRuleId", + "role": "modeller", + "permission": { + "filter": {} + }, + "comment": "" + } + ] + }, + { + "table": { + "name": "service", + "schema": "modelling" + }, + "object_relationships": [ + { + "name": "owner", "using": { - "foreign_key_constraint_on": "old_rule_id" + "foreign_key_constraint_on": "app_id" } }, { - "name": "stm_change_type", + "name": "stm_ip_proto", "using": { - "foreign_key_constraint_on": "change_type_id" + "foreign_key_constraint_on": "proto_id" } - }, + } + ], + "array_relationships": [ { - "name": "uiuser", + "name": "service_connections", "using": { - "foreign_key_constraint_on": "doku_admin" + "foreign_key_constraint_on": { + "column": "service_id", + "table": { + "name": "service_connection", + "schema": "modelling" + } + } } }, { - "name": "uiuserByImportAdmin", + "name": "service_service_groups", "using": { - "foreign_key_constraint_on": "import_admin" + "foreign_key_constraint_on": { + "column": "service_id", + "table": { + "name": "service_service_group", + "schema": "modelling" + } + } } } ], + "insert_permissions": [ + { + "role": "modeller", + "permission": { + "check": { + "app_id": { + "_in": "x-hasura-editable-owners" + } + }, + "columns": [ + "is_global", + "name", + "app_id", + "id", + "port", + "port_end", + "proto_id" + ] + }, + "comment": "" + } + ], "select_permissions": [ { "role": "auditor", "permission": { "columns": [ - "log_rule_id", - "doku_admin", - "control_id", - "import_admin", - "new_rule_id", - "old_rule_id", - "implicit_change", - "abs_change_id", - "change_action", - "changelog_rule_comment", - "documented", - "docu_time", - "mgm_id", - "dev_id", - "change_type_id", - "security_relevant", - "change_request_info", - "change_time", - "unique_name" + "is_global", + "name", + "app_id", + "id", + "port", + "port_end", + "proto_id" ], "filter": {} - } + }, + "comment": "" }, { - "role": "fw-admin", + "role": "middleware-server", "permission": { "columns": [ - "abs_change_id", - "control_id", - "log_rule_id", - "new_rule_id", - "old_rule_id", - "documented", - "implicit_change", - "security_relevant", - "change_action", - "change_request_info", - "unique_name", - "change_type_id", - "dev_id", - "doku_admin", - "import_admin", - "mgm_id", - "changelog_rule_comment", - "change_time", - "docu_time" + "is_global", + "name", + "app_id", + "id", + "port", + "port_end", + "proto_id" ], - "filter": {}, - "allow_aggregations": true - } + "filter": {} + }, + "comment": "" }, { - "role": "importer", + "role": "modeller", "permission": { "columns": [ - "log_rule_id", - "doku_admin", - "control_id", - "import_admin", - "new_rule_id", - "old_rule_id", - "implicit_change", - "abs_change_id", - "change_action", - "changelog_rule_comment", - "documented", - "docu_time", - "mgm_id", - "dev_id", - "change_type_id", - "security_relevant", - "change_request_info", - "change_time", - "unique_name" + "is_global", + "name", + "app_id", + "id", + "port", + "port_end", + "proto_id" ], - "filter": {}, - "allow_aggregations": true - } - }, + "filter": {} + }, + "comment": "" + } + ], + "update_permissions": [ { - "role": "recertifier", + "role": "modeller", "permission": { "columns": [ - "log_rule_id", - "doku_admin", - "control_id", - "import_admin", - "new_rule_id", - "old_rule_id", - "implicit_change", - "abs_change_id", - "change_action", - "changelog_rule_comment", - "documented", - "docu_time", - "mgm_id", - "dev_id", - "change_type_id", - "security_relevant", - "change_request_info", - "change_time", - "unique_name" + "is_global", + "name", + "app_id", + "id", + "port", + "port_end", + "proto_id" ], "filter": { - "dev_id": { - "_in": "x-hasura-visible-devices" + "app_id": { + "_in": "x-hasura-editable-owners" } }, - "allow_aggregations": true - } - }, + "check": null + }, + "comment": "" + } + ], + "delete_permissions": [ { - "role": "reporter", + "role": "modeller", "permission": { - "columns": [ - "log_rule_id", - "doku_admin", - "control_id", - "import_admin", - "new_rule_id", - "old_rule_id", - "implicit_change", - "abs_change_id", - "change_action", - "changelog_rule_comment", - "documented", - "docu_time", - "mgm_id", - "dev_id", - "change_type_id", - "security_relevant", - "change_request_info", - "change_time", - "unique_name" - ], "filter": { - "dev_id": { - "_in": "x-hasura-visible-devices" + "app_id": { + "_in": "x-hasura-editable-owners" } - }, - "allow_aggregations": true - } - }, - { - "role": "reporter-viewall", - "permission": { - "columns": [ - "log_rule_id", - "doku_admin", - "control_id", - "import_admin", - "new_rule_id", - "old_rule_id", - "implicit_change", - "abs_change_id", - "change_action", - "changelog_rule_comment", - "documented", - "docu_time", - "mgm_id", - "dev_id", - "change_type_id", - "security_relevant", - "change_request_info", - "change_time", - "unique_name" - ], - "filter": {}, - "allow_aggregations": true - } + } + }, + "comment": "" } ] }, { "table": { - "name": "changelog_service", - "schema": "public" + "name": "service_connection", + "schema": "modelling" }, "object_relationships": [ { - "name": "import_control", - "using": { - "foreign_key_constraint_on": "control_id" - } - }, - { - "name": "management", + "name": "connection", "using": { - "foreign_key_constraint_on": "mgm_id" + "foreign_key_constraint_on": "connection_id" } }, { "name": "service", "using": { - "foreign_key_constraint_on": "new_svc_id" + "foreign_key_constraint_on": "service_id" } - }, + } + ], + "insert_permissions": [ { - "name": "serviceByOldSvcId", - "using": { - "foreign_key_constraint_on": "old_svc_id" - } - }, + "role": "modeller", + "permission": { + "check": {}, + "columns": [ + "connection_id", + "service_id" + ] + }, + "comment": "" + } + ], + "select_permissions": [ { - "name": "stm_change_type", - "using": { - "foreign_key_constraint_on": "change_type_id" - } + "role": "auditor", + "permission": { + "columns": [ + "connection_id", + "service_id" + ], + "filter": {} + }, + "comment": "" }, { - "name": "uiuser", - "using": { - "foreign_key_constraint_on": "doku_admin" - } + "role": "middleware-server", + "permission": { + "columns": [ + "connection_id", + "service_id" + ], + "filter": {} + }, + "comment": "" }, { - "name": "uiuserByImportAdmin", - "using": { - "foreign_key_constraint_on": "import_admin" - } + "role": "modeller", + "permission": { + "columns": [ + "connection_id", + "service_id" + ], + "filter": {} + }, + "comment": "" } ], - "select_permissions": [ + "delete_permissions": [ { - "role": "importer", + "role": "modeller", "permission": { - "columns": [ - "log_svc_id", - "doku_admin", - "control_id", - "import_admin", - "new_svc_id", - "old_svc_id", - "abs_change_id", - "change_action", - "changelog_svc_comment", - "documented", - "docu_time", - "mgm_id", - "change_type_id", - "security_relevant", - "change_request_info", - "change_time", - "unique_name" - ], - "filter": {}, - "allow_aggregations": true - } + "filter": {} + }, + "comment": "" } ] }, { "table": { - "name": "changelog_user", - "schema": "public" + "name": "service_group", + "schema": "modelling" }, "object_relationships": [ { - "name": "import_control", - "using": { - "foreign_key_constraint_on": "control_id" - } - }, - { - "name": "management", - "using": { - "foreign_key_constraint_on": "mgm_id" - } - }, - { - "name": "stm_change_type", - "using": { - "foreign_key_constraint_on": "change_type_id" - } - }, - { - "name": "uiuser", - "using": { - "foreign_key_constraint_on": "doku_admin" - } - }, - { - "name": "uiuserByImportAdmin", + "name": "owner", "using": { - "foreign_key_constraint_on": "import_admin" + "foreign_key_constraint_on": "app_id" } - }, + } + ], + "array_relationships": [ { - "name": "usr", + "name": "service_group_connections", "using": { - "foreign_key_constraint_on": "new_user_id" + "foreign_key_constraint_on": { + "column": "service_group_id", + "table": { + "name": "service_group_connection", + "schema": "modelling" + } + } } }, { - "name": "usrByOldUserId", + "name": "service_service_groups", "using": { - "foreign_key_constraint_on": "old_user_id" + "foreign_key_constraint_on": { + "column": "service_group_id", + "table": { + "name": "service_service_group", + "schema": "modelling" + } + } } } ], - "select_permissions": [ + "insert_permissions": [ { - "role": "importer", + "role": "modeller", "permission": { - "columns": [ - "log_usr_id", - "new_user_id", - "old_user_id", - "import_admin", - "doku_admin", - "control_id", - "abs_change_id", - "change_action", - "changelog_user_comment", - "documented", - "docu_time", - "mgm_id", - "change_type_id", - "security_relevant", - "change_request_info", - "change_time", - "unique_name" + "check": { + "app_id": { + "_in": "x-hasura-editable-owners" + } + }, + "columns": [ + "is_global", + "comment", + "creator", + "name", + "app_id", + "id", + "creation_date" + ] + }, + "comment": "" + } + ], + "select_permissions": [ + { + "role": "auditor", + "permission": { + "columns": [ + "is_global", + "comment", + "creator", + "name", + "app_id", + "id", + "creation_date" ], - "filter": {}, - "allow_aggregations": true - } + "filter": {} + }, + "comment": "" + }, + { + "role": "middleware-server", + "permission": { + "columns": [ + "is_global", + "comment", + "creator", + "name", + "app_id", + "id", + "creation_date" + ], + "filter": {} + }, + "comment": "" + }, + { + "role": "modeller", + "permission": { + "columns": [ + "is_global", + "comment", + "creator", + "name", + "app_id", + "id", + "creation_date" + ], + "filter": {} + }, + "comment": "" + } + ], + "update_permissions": [ + { + "role": "modeller", + "permission": { + "columns": [ + "is_global", + "comment", + "creator", + "name", + "app_id", + "id", + "creation_date" + ], + "filter": { + "app_id": { + "_in": "x-hasura-editable-owners" + } + }, + "check": {} + }, + "comment": "" + } + ], + "delete_permissions": [ + { + "role": "modeller", + "permission": { + "filter": { + "app_id": { + "_in": "x-hasura-editable-owners" + } + } + }, + "comment": "" } ] }, { "table": { - "name": "config", - "schema": "public" + "name": "service_group_connection", + "schema": "modelling" }, "object_relationships": [ { - "name": "uiuser", + "name": "connection", "using": { - "foreign_key_constraint_on": "config_user" + "foreign_key_constraint_on": "connection_id" + } + }, + { + "name": "service_group", + "using": { + "foreign_key_constraint_on": "service_group_id" } } ], "insert_permissions": [ { - "role": "approver", + "role": "modeller", "permission": { - "check": { - "config_user": { - "_eq": "X-Hasura-User-Id" - } - }, + "check": {}, "columns": [ - "config_user", - "config_key", - "config_value" + "connection_id", + "service_group_id" ] - } - }, + }, + "comment": "" + } + ], + "select_permissions": [ { "role": "auditor", "permission": { - "check": { - "config_user": { - "_eq": "X-Hasura-User-Id" - } - }, "columns": [ - "config_key", - "config_value", - "config_user" - ] - } + "connection_id", + "service_group_id" + ], + "filter": {} + }, + "comment": "" }, { - "role": "fw-admin", + "role": "middleware-server", "permission": { - "check": { - "config_user": { - "_eq": "X-Hasura-User-Id" - } - }, "columns": [ - "config_user", - "config_key", - "config_value" - ] - } + "connection_id", + "service_group_id" + ], + "filter": {} + }, + "comment": "" }, { - "role": "implementer", + "role": "modeller", "permission": { - "check": { - "config_user": { - "_eq": "X-Hasura-User-Id" - } - }, "columns": [ - "config_user", - "config_key", - "config_value" - ] - } - }, + "connection_id", + "service_group_id" + ], + "filter": {} + }, + "comment": "" + } + ], + "delete_permissions": [ { - "role": "planner", + "role": "modeller", "permission": { - "check": { - "config_user": { - "_eq": "X-Hasura-User-Id" - } - }, - "columns": [ - "config_user", - "config_key", - "config_value" - ] + "filter": {} + }, + "comment": "" + } + ] + }, + { + "table": { + "name": "service_service_group", + "schema": "modelling" + }, + "object_relationships": [ + { + "name": "service", + "using": { + "foreign_key_constraint_on": "service_id" } }, { - "role": "recertifier", - "permission": { - "check": { - "_or": [ - { - "config_user": { - "_eq": "X-Hasura-User-Id" - } - }, - { - "config_user": { - "_eq": 0 - } - } - ] - }, - "columns": [ - "config_key", - "config_value", - "config_user" - ] + "name": "service_group", + "using": { + "foreign_key_constraint_on": "service_group_id" } - }, + } + ], + "insert_permissions": [ { - "role": "reporter", + "role": "modeller", "permission": { - "check": { - "config_user": { - "_eq": "X-Hasura-User-Id" - } - }, + "check": {}, "columns": [ - "config_user", - "config_key", - "config_value" + "service_group_id", + "service_id" ] - } - }, + }, + "comment": "" + } + ], + "select_permissions": [ { - "role": "reporter-viewall", + "role": "auditor", "permission": { - "check": { - "config_user": { - "_eq": "X-Hasura-User-Id" - } - }, "columns": [ - "config_user", - "config_key", - "config_value" - ] - } + "service_group_id", + "service_id" + ], + "filter": {} + }, + "comment": "" }, { - "role": "requester", + "role": "middleware-server", "permission": { - "check": { - "config_user": { - "_eq": "X-Hasura-User-Id" - } - }, "columns": [ - "config_user", - "config_key", - "config_value" - ] - } + "service_group_id", + "service_id" + ], + "filter": {} + }, + "comment": "" }, { - "role": "reviewer", + "role": "modeller", "permission": { - "check": { - "config_user": { - "_eq": "X-Hasura-User-Id" - } - }, "columns": [ - "config_user", - "config_key", - "config_value" - ] - } + "service_group_id", + "service_id" + ], + "filter": {} + }, + "comment": "" } ], - "select_permissions": [ + "delete_permissions": [ { - "role": "anonymous", + "role": "modeller", "permission": { - "columns": [ - "config_key", - "config_value", - "config_user" - ], - "filter": { - "config_user": { - "_eq": 0 - } - } + "filter": {} + }, + "comment": "" + } + ] + }, + { + "table": { + "name": "alert", + "schema": "public" + }, + "object_relationships": [ + { + "name": "device", + "using": { + "foreign_key_constraint_on": "alert_dev_id" } }, { - "role": "approver", - "permission": { - "columns": [ - "config_key", - "config_value", - "config_user" - ], - "filter": { - "_or": [ - { - "config_user": { - "_eq": "X-Hasura-User-Id" - } - }, - { - "config_user": { - "_eq": 0 - } - } - ] - } + "name": "log_data_issue", + "using": { + "foreign_key_constraint_on": "ref_log_id" } }, { - "role": "auditor", + "name": "management", + "using": { + "foreign_key_constraint_on": "alert_mgm_id" + } + }, + { + "name": "uiuser", + "using": { + "foreign_key_constraint_on": "ack_by" + } + }, + { + "name": "uiuserByUserId", + "using": { + "foreign_key_constraint_on": "user_id" + } + } + ], + "insert_permissions": [ + { + "role": "approver", "permission": { + "check": {}, "columns": [ - "config_user", - "config_key", - "config_value" - ], - "filter": {} + "ack_by", + "ack_timestamp", + "alert_code", + "alert_dev_id", + "alert_id", + "alert_mgm_id", + "alert_timestamp", + "description", + "json_data", + "ref_alert_id", + "ref_log_id", + "source", + "title", + "user_id" + ] } }, { "role": "fw-admin", "permission": { + "check": {}, "columns": [ - "config_user", - "config_key", - "config_value" - ], - "filter": { - "_or": [ - { - "config_user": { - "_eq": "X-Hasura-User-Id" - } - }, - { - "config_user": { - "_eq": 0 - } - } - ] - } + "ack_by", + "ack_timestamp", + "alert_code", + "alert_dev_id", + "alert_id", + "alert_mgm_id", + "alert_timestamp", + "description", + "json_data", + "ref_alert_id", + "ref_log_id", + "source", + "title", + "user_id" + ] } }, { "role": "implementer", "permission": { + "check": {}, "columns": [ - "config_key", - "config_value", - "config_user" - ], - "filter": { - "_or": [ - { - "config_user": { - "_eq": "X-Hasura-User-Id" - } - }, - { - "config_user": { - "_eq": 0 - } - } - ] - } + "ack_by", + "ack_timestamp", + "alert_code", + "alert_dev_id", + "alert_id", + "alert_mgm_id", + "alert_timestamp", + "description", + "json_data", + "ref_alert_id", + "ref_log_id", + "source", + "title", + "user_id" + ] } }, { "role": "importer", "permission": { + "check": {}, "columns": [ - "config_key", - "config_value", - "config_user" - ], - "filter": {}, - "allow_aggregations": true + "ack_by", + "ack_timestamp", + "alert_code", + "alert_dev_id", + "alert_id", + "alert_mgm_id", + "alert_timestamp", + "description", + "json_data", + "ref_alert_id", + "ref_log_id", + "source", + "title", + "user_id" + ] } }, { "role": "middleware-server", "permission": { + "check": {}, "columns": [ - "config_key", - "config_value", - "config_user" - ], - "filter": {} + "ack_by", + "ack_timestamp", + "alert_code", + "alert_dev_id", + "alert_id", + "alert_mgm_id", + "alert_timestamp", + "description", + "json_data", + "ref_alert_id", + "ref_log_id", + "source", + "title", + "user_id" + ] } }, { - "role": "planner", + "role": "modeller", "permission": { + "check": {}, "columns": [ - "config_key", - "config_value", - "config_user" - ], - "filter": { - "_or": [ - { - "config_user": { - "_eq": "X-Hasura-User-Id" - } - }, - { - "config_user": { - "_eq": 0 - } - } - ] - } + "ack_by", + "ack_timestamp", + "alert_code", + "alert_dev_id", + "alert_id", + "alert_mgm_id", + "alert_timestamp", + "description", + "json_data", + "ref_alert_id", + "ref_log_id", + "source", + "title", + "user_id" + ] } }, { - "role": "recertifier", + "role": "planner", "permission": { + "check": {}, "columns": [ - "config_key", - "config_value", - "config_user" - ], - "filter": { - "_or": [ - { - "config_user": { - "_eq": "X-Hasura-User-Id" - } - }, - { - "config_user": { - "_eq": 0 - } - } - ] - } + "ack_by", + "ack_timestamp", + "alert_code", + "alert_dev_id", + "alert_id", + "alert_mgm_id", + "alert_timestamp", + "description", + "json_data", + "ref_alert_id", + "ref_log_id", + "source", + "title", + "user_id" + ] + } + }, + { + "role": "recertifier", + "permission": { + "check": {}, + "columns": [ + "ack_by", + "ack_timestamp", + "alert_code", + "alert_dev_id", + "alert_id", + "alert_mgm_id", + "alert_timestamp", + "description", + "json_data", + "ref_alert_id", + "ref_log_id", + "source", + "title", + "user_id" + ] } }, { "role": "reporter", "permission": { + "check": {}, "columns": [ - "config_key", - "config_value", - "config_user" - ], - "filter": { - "_or": [ - { - "config_user": { - "_eq": "X-Hasura-User-Id" - } - }, - { - "config_user": { - "_eq": 0 - } - } - ] - } + "ack_by", + "ack_timestamp", + "alert_code", + "alert_dev_id", + "alert_id", + "alert_mgm_id", + "alert_timestamp", + "description", + "json_data", + "ref_alert_id", + "ref_log_id", + "source", + "title", + "user_id" + ] } }, { "role": "reporter-viewall", "permission": { + "check": {}, "columns": [ - "config_user", - "config_key", - "config_value" - ], - "filter": { - "_or": [ - { - "config_user": { - "_eq": "X-Hasura-User-Id" - } - }, - { - "config_user": { - "_eq": 0 - } - } - ] - } + "ack_by", + "ack_timestamp", + "alert_code", + "alert_dev_id", + "alert_id", + "alert_mgm_id", + "alert_timestamp", + "description", + "json_data", + "ref_alert_id", + "ref_log_id", + "source", + "title", + "user_id" + ] } }, { "role": "requester", "permission": { + "check": {}, "columns": [ - "config_key", - "config_value", - "config_user" - ], - "filter": { - "_or": [ - { - "config_user": { - "_eq": "X-Hasura-User-Id" - } - }, - { - "config_user": { - "_eq": 0 - } - } - ] - } + "ack_by", + "ack_timestamp", + "alert_code", + "alert_dev_id", + "alert_id", + "alert_mgm_id", + "alert_timestamp", + "description", + "json_data", + "ref_alert_id", + "ref_log_id", + "source", + "title", + "user_id" + ] } }, { "role": "reviewer", "permission": { + "check": {}, "columns": [ - "config_key", - "config_value", - "config_user" - ], - "filter": { - "_or": [ - { - "config_user": { - "_eq": "X-Hasura-User-Id" - } - }, - { - "config_user": { - "_eq": 0 - } - } - ] - } + "ack_by", + "ack_timestamp", + "alert_code", + "alert_dev_id", + "alert_id", + "alert_mgm_id", + "alert_timestamp", + "description", + "json_data", + "ref_alert_id", + "ref_log_id", + "source", + "title", + "user_id" + ] } } ], - "update_permissions": [ + "select_permissions": [ { "role": "approver", "permission": { "columns": [ - "config_value" + "alert_id", + "ref_alert_id", + "ref_log_id", + "description", + "source", + "title", + "ack_by", + "alert_code", + "alert_dev_id", + "alert_mgm_id", + "user_id", + "json_data", + "ack_timestamp", + "alert_timestamp" ], - "filter": { - "config_user": { - "_eq": "X-Hasura-User-Id" - } - }, - "check": null + "filter": {} } }, { "role": "auditor", "permission": { "columns": [ - "config_user", - "config_key", - "config_value" + "ack_by", + "ack_timestamp", + "alert_code", + "alert_dev_id", + "alert_id", + "alert_mgm_id", + "alert_timestamp", + "description", + "json_data", + "ref_alert_id", + "ref_log_id", + "source", + "title", + "user_id" ], - "filter": { - "config_user": { - "_eq": "X-Hasura-User-Id" - } - }, - "check": null + "filter": {} } }, { "role": "fw-admin", "permission": { "columns": [ - "config_value" + "ack_by", + "ack_timestamp", + "alert_code", + "alert_dev_id", + "alert_id", + "alert_mgm_id", + "alert_timestamp", + "description", + "json_data", + "ref_alert_id", + "ref_log_id", + "source", + "title", + "user_id" ], - "filter": { - "config_user": { - "_eq": "X-Hasura-User-Id" - } - }, - "check": null + "filter": {} } }, { "role": "implementer", "permission": { "columns": [ - "config_value" - ], - "filter": { - "config_user": { - "_eq": "X-Hasura-User-Id" - } - }, - "check": null - } + "alert_id", + "ref_alert_id", + "ref_log_id", + "description", + "source", + "title", + "ack_by", + "alert_code", + "alert_dev_id", + "alert_mgm_id", + "user_id", + "json_data", + "ack_timestamp", + "alert_timestamp" + ], + "filter": {} + } }, { - "role": "planner", + "role": "importer", "permission": { "columns": [ - "config_value" + "alert_id", + "ref_alert_id", + "ref_log_id", + "description", + "source", + "title", + "ack_by", + "alert_code", + "alert_dev_id", + "alert_mgm_id", + "user_id", + "json_data", + "ack_timestamp", + "alert_timestamp" ], - "filter": { - "config_user": { - "_eq": "X-Hasura-User-Id" - } - }, - "check": null + "filter": {}, + "allow_aggregations": true } }, { - "role": "recertifier", + "role": "middleware-server", "permission": { "columns": [ - "config_key", - "config_value", - "config_user" + "ack_by", + "ack_timestamp", + "alert_code", + "alert_dev_id", + "alert_id", + "alert_mgm_id", + "alert_timestamp", + "description", + "json_data", + "ref_alert_id", + "ref_log_id", + "source", + "title", + "user_id" ], - "filter": { - "_or": [ - { - "config_user": { - "_eq": "X-Hasura-User-Id" - } - }, - { - "config_user": { - "_eq": 0 - } - } - ] - }, - "check": null + "filter": {} } }, { - "role": "reporter", + "role": "modeller", "permission": { "columns": [ - "config_value" + "alert_id", + "ref_alert_id", + "ref_log_id", + "description", + "source", + "title", + "ack_by", + "alert_code", + "alert_dev_id", + "alert_mgm_id", + "user_id", + "json_data", + "ack_timestamp", + "alert_timestamp" ], - "filter": { - "config_user": { - "_eq": "X-Hasura-User-Id" - } - }, - "check": null + "filter": {} } }, { - "role": "reporter-viewall", + "role": "planner", "permission": { "columns": [ - "config_value" + "alert_id", + "ref_alert_id", + "ref_log_id", + "description", + "source", + "title", + "ack_by", + "alert_code", + "alert_dev_id", + "alert_mgm_id", + "user_id", + "json_data", + "ack_timestamp", + "alert_timestamp" ], - "filter": { - "config_user": { - "_eq": "X-Hasura-User-Id" - } - }, - "check": null + "filter": {} } }, { - "role": "requester", + "role": "recertifier", "permission": { "columns": [ - "config_value" + "alert_id", + "ref_alert_id", + "ref_log_id", + "description", + "source", + "title", + "ack_by", + "alert_code", + "alert_dev_id", + "alert_mgm_id", + "user_id", + "json_data", + "ack_timestamp", + "alert_timestamp" ], - "filter": { - "config_user": { - "_eq": "X-Hasura-User-Id" - } - }, - "check": null - } + "filter": {} + }, + "comment": "" }, { - "role": "reviewer", + "role": "reporter", "permission": { "columns": [ - "config_value" + "alert_id", + "ref_alert_id", + "ref_log_id", + "description", + "source", + "title", + "ack_by", + "alert_code", + "alert_dev_id", + "alert_mgm_id", + "user_id", + "json_data", + "ack_timestamp", + "alert_timestamp" ], - "filter": { - "config_user": { - "_eq": "X-Hasura-User-Id" - } - }, - "check": null - } - } - ] - }, - { - "table": { - "name": "device", - "schema": "public" - }, - "object_relationships": [ - { - "name": "management", - "using": { - "foreign_key_constraint_on": "mgm_id" + "filter": {} } }, { - "name": "stm_dev_typ", - "using": { - "foreign_key_constraint_on": "dev_typ_id" + "role": "requester", + "permission": { + "columns": [ + "alert_id", + "ref_alert_id", + "ref_log_id", + "description", + "source", + "title", + "ack_by", + "alert_code", + "alert_dev_id", + "alert_mgm_id", + "user_id", + "json_data", + "ack_timestamp", + "alert_timestamp" + ], + "filter": {} } }, { - "name": "tenant", - "using": { - "foreign_key_constraint_on": "tenant_id" + "role": "reviewer", + "permission": { + "columns": [ + "alert_id", + "ref_alert_id", + "ref_log_id", + "description", + "source", + "title", + "ack_by", + "alert_code", + "alert_dev_id", + "alert_mgm_id", + "user_id", + "json_data", + "ack_timestamp", + "alert_timestamp" + ], + "filter": {} } } ], - "array_relationships": [ + "update_permissions": [ { - "name": "alerts", - "using": { - "foreign_key_constraint_on": { - "column": "alert_dev_id", - "table": { - "name": "alert", - "schema": "public" - } - } + "role": "approver", + "permission": { + "columns": [ + "ack_by", + "ack_timestamp" + ], + "filter": {}, + "check": null } }, { - "name": "changelog_rules", - "using": { - "foreign_key_constraint_on": { - "column": "dev_id", - "table": { - "name": "changelog_rule", - "schema": "public" - } - } + "role": "fw-admin", + "permission": { + "columns": [ + "ack_by", + "ack_timestamp", + "alert_code", + "alert_dev_id", + "alert_id", + "alert_mgm_id", + "alert_timestamp", + "description", + "json_data", + "ref_alert_id", + "ref_log_id", + "source", + "title", + "user_id" + ], + "filter": {}, + "check": null } }, { - "name": "gw_interfaces", - "using": { - "foreign_key_constraint_on": { - "column": "routing_device", - "table": { - "name": "gw_interface", - "schema": "public" - } - } + "role": "implementer", + "permission": { + "columns": [ + "ack_by", + "ack_timestamp" + ], + "filter": {}, + "check": null } }, { - "name": "gw_routes", - "using": { - "foreign_key_constraint_on": { - "column": "routing_device", - "table": { - "name": "gw_route", - "schema": "public" - } - } + "role": "importer", + "permission": { + "columns": [ + "alert_id", + "ref_alert_id", + "ref_log_id", + "description", + "source", + "title", + "ack_by", + "alert_code", + "alert_dev_id", + "alert_mgm_id", + "user_id", + "json_data", + "ack_timestamp", + "alert_timestamp" + ], + "filter": {}, + "check": null } }, { - "name": "impltasks", + "role": "middleware-server", + "permission": { + "columns": [ + "ack_by", + "ack_timestamp" + ], + "filter": {}, + "check": {} + } + }, + { + "role": "modeller", + "permission": { + "columns": [ + "ack_by", + "ack_timestamp" + ], + "filter": {}, + "check": null + } + }, + { + "role": "planner", + "permission": { + "columns": [ + "ack_by", + "ack_timestamp" + ], + "filter": {}, + "check": null + } + }, + { + "role": "recertifier", + "permission": { + "columns": [ + "ack_by", + "ack_timestamp" + ], + "filter": {}, + "check": null + } + }, + { + "role": "reporter", + "permission": { + "columns": [ + "ack_by", + "ack_timestamp" + ], + "filter": {}, + "check": null + } + }, + { + "role": "reporter-viewall", + "permission": { + "columns": [ + "ack_by", + "ack_timestamp" + ], + "filter": {}, + "check": null + } + }, + { + "role": "requester", + "permission": { + "columns": [ + "ack_by", + "ack_timestamp" + ], + "filter": {}, + "check": null + } + }, + { + "role": "reviewer", + "permission": { + "columns": [ + "ack_by", + "ack_timestamp" + ], + "filter": {}, + "check": null + } + } + ] + }, + { + "table": { + "name": "changelog_object", + "schema": "public" + }, + "object_relationships": [ + { + "name": "import_control", "using": { - "foreign_key_constraint_on": { - "column": "device_id", - "table": { - "name": "impltask", - "schema": "request" - } - } + "foreign_key_constraint_on": "control_id" } }, { - "name": "objects", + "name": "management", "using": { - "foreign_key_constraint_on": { - "column": "obj_nat_install", - "table": { - "name": "object", - "schema": "public" - } - } + "foreign_key_constraint_on": "mgm_id" } }, { - "name": "reqelements", + "name": "object", "using": { - "foreign_key_constraint_on": { - "column": "device_id", - "table": { - "name": "reqelement", - "schema": "request" - } - } + "foreign_key_constraint_on": "new_obj_id" } }, { - "name": "rule_metadata", + "name": "objectByOldObjId", "using": { - "foreign_key_constraint_on": { - "column": "dev_id", - "table": { - "name": "rule_metadata", - "schema": "public" - } - } + "foreign_key_constraint_on": "old_obj_id" } }, { - "name": "rules", + "name": "stm_change_type", "using": { - "foreign_key_constraint_on": { - "column": "dev_id", - "table": { - "name": "rule", - "schema": "public" - } - } + "foreign_key_constraint_on": "change_type_id" } }, { - "name": "rules_with_owner", + "name": "uiuser", "using": { - "manual_configuration": { - "column_mapping": { - "dev_id": "dev_id" - }, - "insertion_order": null, - "remote_table": { - "name": "view_rule_with_owner", - "schema": "public" - } - } + "foreign_key_constraint_on": "doku_admin" } }, { - "name": "tenant_to_devices", + "name": "uiuserByImportAdmin", "using": { - "foreign_key_constraint_on": { - "column": "device_id", - "table": { - "name": "tenant_to_device", - "schema": "public" - } - } + "foreign_key_constraint_on": "import_admin" } } ], "insert_permissions": [ { - "role": "fw-admin", + "role": "importer", "permission": { "check": {}, "columns": [ - "clearing_import_ran", - "dev_active", - "do_not_import", - "force_initial_import", - "hide_in_gui", - "dev_name", - "global_rulebase_name", - "global_rulebase_uid", - "local_rulebase_name", - "local_rulebase_uid", - "package_name", - "package_uid", - "dev_id", - "dev_typ_id", - "mgm_id", - "tenant_id", - "dev_comment", - "dev_create", - "dev_update" - ] - } + "abs_change_id", + "control_id", + "log_obj_id", + "new_obj_id", + "old_obj_id", + "documented", + "security_relevant", + "change_action", + "change_request_info", + "unique_name", + "change_type_id", + "doku_admin", + "import_admin", + "mgm_id", + "changelog_obj_comment", + "change_time", + "docu_time" + ] + }, + "comment": "" } ], "select_permissions": [ { - "role": "approver", + "role": "auditor", "permission": { "columns": [ - "clearing_import_ran", - "dev_active", - "do_not_import", - "force_initial_import", - "hide_in_gui", - "dev_name", - "global_rulebase_name", - "global_rulebase_uid", - "local_rulebase_name", - "local_rulebase_uid", - "package_name", - "package_uid", - "dev_id", - "dev_typ_id", + "abs_change_id", + "control_id", + "log_obj_id", + "new_obj_id", + "old_obj_id", + "documented", + "security_relevant", + "change_action", + "change_request_info", + "unique_name", + "change_type_id", + "doku_admin", + "import_admin", "mgm_id", - "tenant_id", - "dev_comment", - "dev_create", - "dev_update" + "changelog_obj_comment", + "change_time", + "docu_time" ], - "filter": { - "_and": [ - { - "mgm_id": { - "_in": "x-hasura-visible-managements" - } - }, - { - "dev_id": { - "_in": "x-hasura-visible-devices" - } - } - ] - }, - "allow_aggregations": true - } + "filter": {} + }, + "comment": "" }, { - "role": "auditor", + "role": "fw-admin", "permission": { "columns": [ - "dev_id", + "abs_change_id", + "control_id", + "log_obj_id", + "new_obj_id", + "old_obj_id", + "documented", + "security_relevant", + "change_action", + "change_request_info", + "unique_name", + "change_type_id", + "doku_admin", + "import_admin", "mgm_id", - "dev_name", - "dev_typ_id", - "tenant_id", - "dev_active", - "dev_comment", - "dev_create", - "dev_update", - "do_not_import", - "clearing_import_ran", - "force_initial_import", - "hide_in_gui", - "global_rulebase_name", - "global_rulebase_uid", - "package_name", - "package_uid", - "local_rulebase_uid", - "local_rulebase_name" + "changelog_obj_comment", + "change_time", + "docu_time" ], "filter": {}, "allow_aggregations": true - } + }, + "comment": "" }, { - "role": "fw-admin", + "role": "importer", "permission": { "columns": [ - "clearing_import_ran", - "dev_active", - "do_not_import", - "force_initial_import", - "hide_in_gui", - "dev_name", - "global_rulebase_name", - "global_rulebase_uid", - "local_rulebase_name", - "local_rulebase_uid", - "package_name", - "package_uid", - "dev_id", - "dev_typ_id", + "log_obj_id", + "new_obj_id", + "old_obj_id", + "import_admin", + "doku_admin", + "control_id", + "abs_change_id", + "change_action", + "changelog_obj_comment", + "documented", + "docu_time", "mgm_id", - "tenant_id", - "dev_comment", - "dev_create", - "dev_update" + "change_type_id", + "security_relevant", + "change_request_info", + "change_time", + "unique_name" ], "filter": {}, "allow_aggregations": true } }, { - "role": "implementer", + "role": "middleware-server", "permission": { "columns": [ - "clearing_import_ran", - "dev_active", - "do_not_import", - "force_initial_import", - "hide_in_gui", - "dev_name", - "global_rulebase_name", - "global_rulebase_uid", - "local_rulebase_name", - "local_rulebase_uid", - "package_name", - "package_uid", - "dev_id", - "dev_typ_id", + "abs_change_id", + "control_id", + "log_obj_id", + "new_obj_id", + "old_obj_id", + "documented", + "security_relevant", + "change_action", + "change_request_info", + "unique_name", + "change_type_id", + "doku_admin", + "import_admin", "mgm_id", - "tenant_id", - "dev_comment", - "dev_create", - "dev_update" + "changelog_obj_comment", + "change_time", + "docu_time" + ], + "filter": {} + }, + "comment": "" + }, + { + "role": "recertifier", + "permission": { + "columns": [ + "abs_change_id", + "control_id", + "log_obj_id", + "new_obj_id", + "old_obj_id", + "documented", + "security_relevant", + "change_action", + "change_request_info", + "unique_name", + "change_type_id", + "doku_admin", + "import_admin", + "mgm_id", + "changelog_obj_comment", + "change_time", + "docu_time" ], "filter": { "_and": [ @@ -2877,438 +3647,323 @@ "mgm_id": { "_in": "x-hasura-visible-managements" } - }, - { - "dev_id": { - "_in": "x-hasura-visible-devices" - } } ] }, "allow_aggregations": true - } + }, + "comment": "" }, { - "role": "importer", + "role": "reporter", "permission": { "columns": [ - "dev_id", + "abs_change_id", + "control_id", + "log_obj_id", + "new_obj_id", + "old_obj_id", + "documented", + "security_relevant", + "change_action", + "change_request_info", + "unique_name", + "change_type_id", + "doku_admin", + "import_admin", "mgm_id", - "dev_name", - "dev_typ_id", - "tenant_id", - "dev_active", - "dev_comment", - "dev_create", - "dev_update", - "do_not_import", - "clearing_import_ran", - "force_initial_import", - "hide_in_gui", - "global_rulebase_name", - "global_rulebase_uid", - "package_name", - "package_uid", - "local_rulebase_uid", - "local_rulebase_name" + "changelog_obj_comment", + "change_time", + "docu_time" ], - "filter": {}, + "filter": { + "_and": [ + { + "mgm_id": { + "_in": "x-hasura-visible-managements" + } + } + ] + }, "allow_aggregations": true - } + }, + "comment": "" }, { - "role": "middleware-server", + "role": "reporter-viewall", "permission": { "columns": [ - "dev_id", + "abs_change_id", + "control_id", + "log_obj_id", + "new_obj_id", + "old_obj_id", + "documented", + "security_relevant", + "change_action", + "change_request_info", + "unique_name", + "change_type_id", + "doku_admin", + "import_admin", "mgm_id", - "dev_name", - "local_rulebase_name", - "local_rulebase_uid", - "global_rulebase_name", - "global_rulebase_uid", - "package_name", - "package_uid", - "dev_typ_id", - "tenant_id", - "dev_active", - "dev_comment", - "dev_create", - "dev_update", - "do_not_import", - "clearing_import_ran", - "force_initial_import", - "hide_in_gui" + "changelog_obj_comment", + "change_time", + "docu_time" ], - "filter": {} + "filter": {}, + "allow_aggregations": true + }, + "comment": "" + } + ] + }, + { + "table": { + "name": "changelog_owner", + "schema": "public" + }, + "object_relationships": [ + { + "name": "import_control", + "using": { + "foreign_key_constraint_on": "control_id" } }, { - "role": "planner", + "name": "owner", + "using": { + "foreign_key_constraint_on": "new_owner_id" + } + }, + { + "name": "ownerByOldOwnerId", + "using": { + "foreign_key_constraint_on": "old_owner_id" + } + } + ], + "insert_permissions": [ + { + "role": "importer", "permission": { + "check": {}, "columns": [ - "clearing_import_ran", - "dev_active", - "do_not_import", - "force_initial_import", - "hide_in_gui", - "dev_name", - "global_rulebase_name", - "global_rulebase_uid", - "local_rulebase_name", - "local_rulebase_uid", - "package_name", - "package_uid", - "dev_id", - "dev_typ_id", - "mgm_id", - "tenant_id", - "dev_comment", - "dev_create", - "dev_update" + "abs_change_id", + "control_id", + "log_owner_id", + "new_owner_id", + "old_owner_id", + "security_relevant", + "change_action", + "source_id" + ] + }, + "comment": "" + }, + { + "role": "middleware-server", + "permission": { + "check": {}, + "columns": [ + "abs_change_id", + "control_id", + "log_owner_id", + "new_owner_id", + "old_owner_id", + "security_relevant", + "change_action", + "source_id" + ] + }, + "comment": "" + } + ], + "select_permissions": [ + { + "role": "auditor", + "permission": { + "columns": [ + "abs_change_id", + "control_id", + "log_owner_id", + "new_owner_id", + "old_owner_id", + "security_relevant", + "change_action", + "source_id" ], - "filter": { - "_and": [ - { - "mgm_id": { - "_in": "x-hasura-visible-managements" - } - }, - { - "dev_id": { - "_in": "x-hasura-visible-devices" - } - } - ] - }, + "filter": {} + }, + "comment": "" + }, + { + "role": "fw-admin", + "permission": { + "columns": [ + "abs_change_id", + "control_id", + "log_owner_id", + "new_owner_id", + "old_owner_id", + "security_relevant", + "change_action", + "source_id" + ], + "filter": {}, "allow_aggregations": true - } + }, + "comment": "" }, { - "role": "recertifier", + "role": "importer", "permission": { "columns": [ - "clearing_import_ran", - "dev_active", - "do_not_import", - "force_initial_import", - "hide_in_gui", - "dev_name", - "global_rulebase_name", - "global_rulebase_uid", - "local_rulebase_name", - "local_rulebase_uid", - "package_name", - "package_uid", - "dev_id", - "dev_typ_id", - "mgm_id", - "tenant_id", - "dev_comment", - "dev_create", - "dev_update" + "abs_change_id", + "control_id", + "log_owner_id", + "new_owner_id", + "old_owner_id", + "security_relevant", + "change_action", + "source_id" ], - "filter": { - "_and": [ - { - "mgm_id": { - "_in": "x-hasura-visible-managements" - } - }, - { - "dev_id": { - "_in": "x-hasura-visible-devices" - } - } - ] - }, + "filter": {}, "allow_aggregations": true - } + }, + "comment": "" }, { - "role": "reporter", + "role": "middleware-server", "permission": { "columns": [ - "clearing_import_ran", - "dev_active", - "do_not_import", - "force_initial_import", - "hide_in_gui", - "dev_name", - "global_rulebase_name", - "global_rulebase_uid", - "local_rulebase_name", - "local_rulebase_uid", - "package_name", - "package_uid", - "dev_id", - "dev_typ_id", - "mgm_id", - "tenant_id", - "dev_comment", - "dev_create", - "dev_update" + "abs_change_id", + "control_id", + "log_owner_id", + "new_owner_id", + "old_owner_id", + "security_relevant", + "change_action", + "source_id" ], - "filter": { - "_and": [ - { - "mgm_id": { - "_in": "x-hasura-visible-managements" - } - }, - { - "dev_id": { - "_in": "x-hasura-visible-devices" - } - } - ] - }, + "filter": {} + }, + "comment": "" + }, + { + "role": "recertifier", + "permission": { + "columns": [ + "abs_change_id", + "control_id", + "log_owner_id", + "new_owner_id", + "old_owner_id", + "security_relevant", + "change_action", + "source_id" + ], + "filter": {}, "allow_aggregations": true - } + }, + "comment": "" }, { - "role": "reporter-viewall", + "role": "reporter", "permission": { "columns": [ - "dev_id", - "mgm_id", - "dev_name", - "dev_typ_id", - "tenant_id", - "dev_active", - "dev_comment", - "dev_create", - "dev_update", - "do_not_import", - "clearing_import_ran", - "force_initial_import", - "hide_in_gui", - "global_rulebase_name", - "global_rulebase_uid", - "package_name", - "package_uid", - "local_rulebase_uid", - "local_rulebase_name" + "abs_change_id", + "control_id", + "log_owner_id", + "new_owner_id", + "old_owner_id", + "security_relevant", + "change_action", + "source_id" ], "filter": {}, "allow_aggregations": true - } + }, + "comment": "" }, { - "role": "requester", + "role": "reporter-viewall", "permission": { "columns": [ - "clearing_import_ran", - "dev_active", - "do_not_import", - "force_initial_import", - "hide_in_gui", - "dev_name", - "global_rulebase_name", - "global_rulebase_uid", - "local_rulebase_name", - "local_rulebase_uid", - "package_name", - "package_uid", - "dev_id", - "dev_typ_id", - "mgm_id", - "tenant_id", - "dev_comment", - "dev_create", - "dev_update" - ], - "filter": { - "_and": [ - { - "mgm_id": { - "_in": "x-hasura-visible-managements" - } - }, - { - "dev_id": { - "_in": "x-hasura-visible-devices" - } - } - ] - }, - "allow_aggregations": true - } - }, - { - "role": "reviewer", - "permission": { - "columns": [ - "clearing_import_ran", - "dev_active", - "do_not_import", - "force_initial_import", - "hide_in_gui", - "dev_name", - "global_rulebase_name", - "global_rulebase_uid", - "local_rulebase_name", - "local_rulebase_uid", - "package_name", - "package_uid", - "dev_id", - "dev_typ_id", - "mgm_id", - "tenant_id", - "dev_comment", - "dev_create", - "dev_update" - ], - "filter": { - "_and": [ - { - "mgm_id": { - "_in": "x-hasura-visible-managements" - } - }, - { - "dev_id": { - "_in": "x-hasura-visible-devices" - } - } - ] - }, - "allow_aggregations": true - } - } - ], - "update_permissions": [ - { - "role": "fw-admin", - "permission": { - "columns": [ - "clearing_import_ran", - "dev_active", - "do_not_import", - "force_initial_import", - "hide_in_gui", - "dev_name", - "global_rulebase_name", - "global_rulebase_uid", - "local_rulebase_name", - "local_rulebase_uid", - "package_name", - "package_uid", - "dev_id", - "dev_typ_id", - "mgm_id", - "tenant_id", - "dev_comment", - "dev_create", - "dev_update" + "abs_change_id", + "control_id", + "log_owner_id", + "new_owner_id", + "old_owner_id", + "security_relevant", + "change_action", + "source_id" ], "filter": {}, - "check": {} - } + "allow_aggregations": true + }, + "comment": "" } ] }, { "table": { - "name": "device_type", + "name": "changelog_rule", "schema": "public" }, - "insert_permissions": [ + "object_relationships": [ { - "role": "middleware-server", - "permission": { - "check": {}, - "columns": [ - "id", - "name" - ] + "name": "import_control", + "using": { + "foreign_key_constraint_on": "control_id" } - } - ], - "select_permissions": [ + }, { - "role": "auditor", - "permission": { - "columns": [ - "id", - "name" - ], - "filter": {} + "name": "management", + "using": { + "foreign_key_constraint_on": "mgm_id" } }, { - "role": "fw-admin", - "permission": { - "columns": [ - "name", - "id" - ], - "filter": {} + "name": "rule", + "using": { + "foreign_key_constraint_on": "new_rule_id" } }, { - "role": "middleware-server", - "permission": { - "columns": [ - "id", - "name" - ], - "filter": {} + "name": "ruleByOldRuleId", + "using": { + "foreign_key_constraint_on": "old_rule_id" } - } - ], - "update_permissions": [ + }, { - "role": "middleware-server", - "permission": { - "columns": [ - "id", - "name" - ], - "filter": {}, - "check": null + "name": "stm_change_type", + "using": { + "foreign_key_constraint_on": "change_type_id" } - } - ], - "delete_permissions": [ + }, { - "role": "middleware-server", - "permission": { - "filter": {} + "name": "uiuser", + "using": { + "foreign_key_constraint_on": "doku_admin" } - } - ] - }, - { - "table": { - "name": "error", - "schema": "public" - } - }, - { - "table": { - "name": "gw_interface", - "schema": "public" - }, - "object_relationships": [ + }, { - "name": "device", + "name": "uiuserByImportAdmin", "using": { - "foreign_key_constraint_on": "routing_device" + "foreign_key_constraint_on": "import_admin" } } ], - "array_relationships": [ + "computed_fields": [ { - "name": "gw_routes", - "using": { - "foreign_key_constraint_on": { - "column": "interface_id", - "table": { - "name": "gw_route", - "schema": "public" - } - } + "name": "cl_rule_relevant_for_tenant", + "definition": { + "function": { + "name": "cl_rule_relevant_for_tenant", + "schema": "public" + }, + "session_argument": "hasura_session" } } ], @@ -3318,258 +3973,326 @@ "permission": { "check": {}, "columns": [ - "state_up", - "name", - "ip", - "id", - "ip_version", - "netmask_bits", - "routing_device" + "abs_change_id", + "control_id", + "log_rule_id", + "new_rule_id", + "old_rule_id", + "documented", + "implicit_change", + "security_relevant", + "change_action", + "change_request_info", + "unique_name", + "change_type_id", + "dev_id", + "doku_admin", + "import_admin", + "mgm_id", + "changelog_rule_comment", + "change_time", + "docu_time" ] - } + }, + "comment": "" } ], "select_permissions": [ { - "role": "importer", + "role": "auditor", "permission": { "columns": [ - "state_up", - "name", - "ip", - "id", - "ip_version", - "netmask_bits", - "routing_device" - ], - "filter": {}, - "allow_aggregations": true - } - } - ], - "update_permissions": [ - { - "role": "importer", - "permission": { - "columns": [ - "state_up", - "name", - "ip", - "id", - "ip_version", - "netmask_bits", - "routing_device" + "log_rule_id", + "doku_admin", + "control_id", + "import_admin", + "new_rule_id", + "old_rule_id", + "implicit_change", + "abs_change_id", + "change_action", + "changelog_rule_comment", + "documented", + "docu_time", + "mgm_id", + "dev_id", + "change_type_id", + "security_relevant", + "change_request_info", + "change_time", + "unique_name" + ], + "computed_fields": [ + "cl_rule_relevant_for_tenant" ], - "filter": {}, - "check": {} - } - } - ], - "delete_permissions": [ - { - "role": "importer", - "permission": { "filter": {} } - } - ] - }, - { - "table": { - "name": "gw_route", - "schema": "public" - }, - "object_relationships": [ - { - "name": "device", - "using": { - "foreign_key_constraint_on": "routing_device" - } }, { - "name": "gw_interface", - "using": { - "foreign_key_constraint_on": "interface_id" - } - } - ], - "insert_permissions": [ - { - "role": "importer", - "permission": { - "check": {}, - "columns": [ - "static", - "interface", - "destination", - "source", - "target_gateway", - "distance", - "id", - "interface_id", - "ip_version", - "metric", - "routing_device" - ] - } - } - ], - "select_permissions": [ - { - "role": "importer", + "role": "fw-admin", "permission": { "columns": [ - "static", - "interface", - "destination", - "source", - "target_gateway", - "distance", - "id", - "interface_id", - "ip_version", - "metric", - "routing_device" + "abs_change_id", + "control_id", + "log_rule_id", + "new_rule_id", + "old_rule_id", + "documented", + "implicit_change", + "security_relevant", + "change_action", + "change_request_info", + "unique_name", + "change_type_id", + "dev_id", + "doku_admin", + "import_admin", + "mgm_id", + "changelog_rule_comment", + "change_time", + "docu_time" + ], + "computed_fields": [ + "cl_rule_relevant_for_tenant" ], "filter": {}, "allow_aggregations": true } - } - ], - "update_permissions": [ + }, { "role": "importer", "permission": { "columns": [ - "static", - "interface", - "destination", - "source", - "target_gateway", - "distance", - "id", - "interface_id", - "ip_version", - "metric", - "routing_device" + "abs_change_id", + "control_id", + "log_rule_id", + "new_rule_id", + "old_rule_id", + "documented", + "implicit_change", + "security_relevant", + "change_action", + "change_request_info", + "unique_name", + "change_type_id", + "dev_id", + "doku_admin", + "import_admin", + "mgm_id", + "changelog_rule_comment", + "change_time", + "docu_time" + ], + "computed_fields": [ + "cl_rule_relevant_for_tenant" ], "filter": {}, - "check": {} - } - } - ], - "delete_permissions": [ - { - "role": "importer", - "permission": { - "filter": {} - } - } - ] - }, - { - "table": { - "name": "import_changelog", - "schema": "public" - }, - "object_relationships": [ - { - "name": "import_control", - "using": { - "foreign_key_constraint_on": "control_id" - } - } - ] - }, - { - "table": { - "name": "import_config", - "schema": "public" - }, - "object_relationships": [ - { - "name": "import_control", - "using": { - "foreign_key_constraint_on": "import_id" + "allow_aggregations": true } }, { - "name": "management", - "using": { - "foreign_key_constraint_on": "mgm_id" - } - } - ], - "insert_permissions": [ - { - "role": "importer", + "role": "middleware-server", "permission": { - "check": {}, "columns": [ - "import_id", - "debug_mode", - "start_import_flag", - "chunk_number", + "abs_change_id", + "control_id", + "log_rule_id", + "new_rule_id", + "old_rule_id", + "documented", + "implicit_change", + "security_relevant", + "change_action", + "change_request_info", + "unique_name", + "change_type_id", + "dev_id", + "doku_admin", + "import_admin", "mgm_id", - "config" - ] - } - } - ], - "select_permissions": [ + "changelog_rule_comment", + "change_time", + "docu_time" + ], + "computed_fields": [ + "cl_rule_relevant_for_tenant" + ], + "filter": {} + }, + "comment": "" + }, { - "role": "importer", + "role": "recertifier", "permission": { "columns": [ - "import_id", - "debug_mode", - "start_import_flag", - "chunk_number", + "log_rule_id", + "doku_admin", + "control_id", + "import_admin", + "new_rule_id", + "old_rule_id", + "implicit_change", + "abs_change_id", + "change_action", + "changelog_rule_comment", + "documented", + "docu_time", "mgm_id", - "config" - ], - "filter": {}, - "allow_aggregations": true - } - } + "dev_id", + "change_type_id", + "security_relevant", + "change_request_info", + "change_time", + "unique_name" + ], + "computed_fields": [ + "cl_rule_relevant_for_tenant" + ], + "filter": { + "_and": [ + { + "mgm_id": { + "_in": "x-hasura-visible-managements" + } + }, + { + "dev_id": { + "_in": "x-hasura-visible-devices" + } + }, + { + "cl_rule_relevant_for_tenant": { + "_eq": "true" + } + } + ] + }, + "allow_aggregations": true + } + }, + { + "role": "reporter", + "permission": { + "columns": [ + "log_rule_id", + "doku_admin", + "control_id", + "import_admin", + "new_rule_id", + "old_rule_id", + "implicit_change", + "abs_change_id", + "change_action", + "changelog_rule_comment", + "documented", + "docu_time", + "mgm_id", + "dev_id", + "change_type_id", + "security_relevant", + "change_request_info", + "change_time", + "unique_name" + ], + "computed_fields": [ + "cl_rule_relevant_for_tenant" + ], + "filter": { + "_and": [ + { + "mgm_id": { + "_in": "x-hasura-visible-managements" + } + }, + { + "dev_id": { + "_in": "x-hasura-visible-devices" + } + }, + { + "cl_rule_relevant_for_tenant": { + "_eq": "true" + } + } + ] + }, + "allow_aggregations": true + } + }, + { + "role": "reporter-viewall", + "permission": { + "columns": [ + "log_rule_id", + "doku_admin", + "control_id", + "import_admin", + "new_rule_id", + "old_rule_id", + "implicit_change", + "abs_change_id", + "change_action", + "changelog_rule_comment", + "documented", + "docu_time", + "mgm_id", + "dev_id", + "change_type_id", + "security_relevant", + "change_request_info", + "change_time", + "unique_name" + ], + "computed_fields": [ + "cl_rule_relevant_for_tenant" + ], + "filter": {}, + "allow_aggregations": true + } + } ], - "delete_permissions": [ + "update_permissions": [ { "role": "importer", "permission": { - "filter": {} - } + "columns": [ + "abs_change_id", + "control_id", + "log_rule_id", + "new_rule_id", + "old_rule_id", + "documented", + "implicit_change", + "security_relevant", + "change_action", + "change_request_info", + "unique_name", + "change_type_id", + "dev_id", + "doku_admin", + "import_admin", + "mgm_id", + "changelog_rule_comment", + "change_time", + "docu_time" + ], + "filter": {}, + "check": {} + }, + "comment": "" } ] }, { "table": { - "name": "import_control", + "name": "changelog_service", "schema": "public" }, "object_relationships": [ { - "name": "import_config", - "using": { - "foreign_key_constraint_on": { - "column": "import_id", - "table": { - "name": "import_config", - "schema": "public" - } - } - } - }, - { - "name": "import_full_config", + "name": "import_control", "using": { - "foreign_key_constraint_on": { - "column": "import_id", - "table": { - "name": "import_full_config", - "schema": "public" - } - } + "foreign_key_constraint_on": "control_id" } }, { @@ -3577,1460 +4300,2182 @@ "using": { "foreign_key_constraint_on": "mgm_id" } - } - ], - "array_relationships": [ - { - "name": "changelog_objects", - "using": { - "foreign_key_constraint_on": { - "column": "control_id", - "table": { - "name": "changelog_object", - "schema": "public" - } - } - } }, { - "name": "changelog_rules", + "name": "service", "using": { - "foreign_key_constraint_on": { - "column": "control_id", - "table": { - "name": "changelog_rule", - "schema": "public" - } - } + "foreign_key_constraint_on": "new_svc_id" } }, { - "name": "changelog_services", + "name": "serviceByOldSvcId", "using": { - "foreign_key_constraint_on": { - "column": "control_id", - "table": { - "name": "changelog_service", - "schema": "public" - } - } + "foreign_key_constraint_on": "old_svc_id" } }, { - "name": "changelog_users", + "name": "stm_change_type", "using": { - "foreign_key_constraint_on": { - "column": "control_id", - "table": { - "name": "changelog_user", - "schema": "public" - } - } + "foreign_key_constraint_on": "change_type_id" } }, { - "name": "import_changelogs", + "name": "uiuser", "using": { - "foreign_key_constraint_on": { - "column": "control_id", - "table": { - "name": "import_changelog", - "schema": "public" - } - } + "foreign_key_constraint_on": "doku_admin" } }, { - "name": "import_configs", + "name": "uiuserByImportAdmin", "using": { - "foreign_key_constraint_on": { - "column": "import_id", - "table": { - "name": "import_config", - "schema": "public" - } - } + "foreign_key_constraint_on": "import_admin" } - }, + } + ], + "insert_permissions": [ { - "name": "import_objects", - "using": { - "foreign_key_constraint_on": { - "column": "control_id", - "table": { - "name": "import_object", - "schema": "public" - } - } - } - }, + "role": "importer", + "permission": { + "check": {}, + "columns": [ + "abs_change_id", + "control_id", + "log_svc_id", + "new_svc_id", + "old_svc_id", + "documented", + "security_relevant", + "change_action", + "change_request_info", + "unique_name", + "change_type_id", + "doku_admin", + "import_admin", + "mgm_id", + "changelog_svc_comment", + "change_time", + "docu_time" + ] + }, + "comment": "" + } + ], + "select_permissions": [ { - "name": "import_rules", - "using": { - "foreign_key_constraint_on": { - "column": "control_id", - "table": { - "name": "import_rule", - "schema": "public" - } - } + "role": "auditor", + "permission": { + "columns": [ + "abs_change_id", + "control_id", + "log_svc_id", + "new_svc_id", + "old_svc_id", + "documented", + "security_relevant", + "change_action", + "change_request_info", + "unique_name", + "change_type_id", + "doku_admin", + "import_admin", + "mgm_id", + "changelog_svc_comment", + "change_time", + "docu_time" + ], + "filter": {} + }, + "comment": "" + }, + { + "role": "fw-admin", + "permission": { + "columns": [ + "abs_change_id", + "control_id", + "log_svc_id", + "new_svc_id", + "old_svc_id", + "documented", + "security_relevant", + "change_action", + "change_request_info", + "unique_name", + "change_type_id", + "doku_admin", + "import_admin", + "mgm_id", + "changelog_svc_comment", + "change_time", + "docu_time" + ], + "filter": {}, + "allow_aggregations": true + }, + "comment": "" + }, + { + "role": "importer", + "permission": { + "columns": [ + "log_svc_id", + "doku_admin", + "control_id", + "import_admin", + "new_svc_id", + "old_svc_id", + "abs_change_id", + "change_action", + "changelog_svc_comment", + "documented", + "docu_time", + "mgm_id", + "change_type_id", + "security_relevant", + "change_request_info", + "change_time", + "unique_name" + ], + "filter": {}, + "allow_aggregations": true } }, { - "name": "import_services", + "role": "middleware-server", + "permission": { + "columns": [ + "abs_change_id", + "control_id", + "log_svc_id", + "new_svc_id", + "old_svc_id", + "documented", + "security_relevant", + "change_action", + "change_request_info", + "unique_name", + "change_type_id", + "doku_admin", + "import_admin", + "mgm_id", + "changelog_svc_comment", + "change_time", + "docu_time" + ], + "filter": {} + }, + "comment": "" + }, + { + "role": "recertifier", + "permission": { + "columns": [ + "abs_change_id", + "control_id", + "log_svc_id", + "new_svc_id", + "old_svc_id", + "documented", + "security_relevant", + "change_action", + "change_request_info", + "unique_name", + "change_type_id", + "doku_admin", + "import_admin", + "mgm_id", + "changelog_svc_comment", + "change_time", + "docu_time" + ], + "filter": { + "_and": [ + { + "mgm_id": { + "_in": "x-hasura-visible-managements" + } + } + ] + }, + "allow_aggregations": true + }, + "comment": "" + }, + { + "role": "reporter", + "permission": { + "columns": [ + "abs_change_id", + "control_id", + "log_svc_id", + "new_svc_id", + "old_svc_id", + "documented", + "security_relevant", + "change_action", + "change_request_info", + "unique_name", + "change_type_id", + "doku_admin", + "import_admin", + "mgm_id", + "changelog_svc_comment", + "change_time", + "docu_time" + ], + "filter": { + "_and": [ + { + "mgm_id": { + "_in": "x-hasura-visible-managements" + } + } + ] + }, + "allow_aggregations": true + }, + "comment": "" + }, + { + "role": "reporter-viewall", + "permission": { + "columns": [ + "abs_change_id", + "control_id", + "log_svc_id", + "new_svc_id", + "old_svc_id", + "documented", + "security_relevant", + "change_action", + "change_request_info", + "unique_name", + "change_type_id", + "doku_admin", + "import_admin", + "mgm_id", + "changelog_svc_comment", + "change_time", + "docu_time" + ], + "filter": {}, + "allow_aggregations": true + }, + "comment": "" + } + ] + }, + { + "table": { + "name": "changelog_user", + "schema": "public" + }, + "object_relationships": [ + { + "name": "import_control", "using": { - "foreign_key_constraint_on": { - "column": "control_id", - "table": { - "name": "import_service", - "schema": "public" - } - } + "foreign_key_constraint_on": "control_id" } }, { - "name": "import_users", + "name": "management", "using": { - "foreign_key_constraint_on": { - "column": "control_id", - "table": { - "name": "import_user", - "schema": "public" - } - } + "foreign_key_constraint_on": "mgm_id" } }, { - "name": "import_zones", + "name": "stm_change_type", "using": { - "foreign_key_constraint_on": { - "column": "control_id", - "table": { - "name": "import_zone", - "schema": "public" - } - } + "foreign_key_constraint_on": "change_type_id" } }, { - "name": "log_data_issues", + "name": "uiuser", "using": { - "foreign_key_constraint_on": { - "column": "import_id", - "table": { - "name": "log_data_issue", - "schema": "public" - } - } + "foreign_key_constraint_on": "doku_admin" } }, { - "name": "objects", + "name": "uiuserByImportAdmin", "using": { - "foreign_key_constraint_on": { - "column": "obj_create", - "table": { - "name": "object", - "schema": "public" - } - } + "foreign_key_constraint_on": "import_admin" } }, { - "name": "objectsByObjLastSeen", + "name": "usr", "using": { - "foreign_key_constraint_on": { - "column": "obj_last_seen", - "table": { - "name": "object", - "schema": "public" - } - } + "foreign_key_constraint_on": "new_user_id" } }, { - "name": "objgrpFlatsByImportLastSeen", + "name": "usrByOldUserId", "using": { - "foreign_key_constraint_on": { - "column": "import_last_seen", - "table": { - "name": "objgrp_flat", - "schema": "public" - } - } + "foreign_key_constraint_on": "old_user_id" } - }, + } + ], + "insert_permissions": [ { - "name": "objgrp_flats", - "using": { - "foreign_key_constraint_on": { - "column": "import_created", - "table": { - "name": "objgrp_flat", - "schema": "public" - } - } - } + "role": "importer", + "permission": { + "check": {}, + "columns": [ + "abs_change_id", + "control_id", + "log_usr_id", + "new_user_id", + "old_user_id", + "documented", + "security_relevant", + "change_action", + "change_request_info", + "unique_name", + "change_type_id", + "doku_admin", + "import_admin", + "mgm_id", + "changelog_user_comment", + "change_time", + "docu_time" + ] + }, + "comment": "" + } + ], + "select_permissions": [ + { + "role": "auditor", + "permission": { + "columns": [ + "abs_change_id", + "control_id", + "log_usr_id", + "new_user_id", + "old_user_id", + "documented", + "security_relevant", + "change_action", + "change_request_info", + "unique_name", + "change_type_id", + "doku_admin", + "import_admin", + "mgm_id", + "changelog_user_comment", + "change_time", + "docu_time" + ], + "filter": {} + }, + "comment": "" }, { - "name": "objgrps", - "using": { - "foreign_key_constraint_on": { - "column": "import_created", - "table": { - "name": "objgrp", - "schema": "public" - } - } - } + "role": "fw-admin", + "permission": { + "columns": [ + "abs_change_id", + "control_id", + "log_usr_id", + "new_user_id", + "old_user_id", + "documented", + "security_relevant", + "change_action", + "change_request_info", + "unique_name", + "change_type_id", + "doku_admin", + "import_admin", + "mgm_id", + "changelog_user_comment", + "change_time", + "docu_time" + ], + "filter": {}, + "allow_aggregations": true + }, + "comment": "" }, { - "name": "objgrpsByImportLastSeen", - "using": { - "foreign_key_constraint_on": { - "column": "import_last_seen", - "table": { - "name": "objgrp", - "schema": "public" - } - } + "role": "importer", + "permission": { + "columns": [ + "log_usr_id", + "new_user_id", + "old_user_id", + "import_admin", + "doku_admin", + "control_id", + "abs_change_id", + "change_action", + "changelog_user_comment", + "documented", + "docu_time", + "mgm_id", + "change_type_id", + "security_relevant", + "change_request_info", + "change_time", + "unique_name" + ], + "filter": {}, + "allow_aggregations": true } }, { - "name": "ruleFromsByRfLastSeen", - "using": { - "foreign_key_constraint_on": { - "column": "rf_last_seen", - "table": { - "name": "rule_from", - "schema": "public" - } - } - } + "role": "middleware-server", + "permission": { + "columns": [ + "abs_change_id", + "control_id", + "log_usr_id", + "new_user_id", + "old_user_id", + "documented", + "security_relevant", + "change_action", + "change_request_info", + "unique_name", + "change_type_id", + "doku_admin", + "import_admin", + "mgm_id", + "changelog_user_comment", + "change_time", + "docu_time" + ], + "filter": {} + }, + "comment": "" }, { - "name": "ruleNwobjResolvedsByRemoved", - "using": { - "foreign_key_constraint_on": { - "column": "removed", - "table": { - "name": "rule_nwobj_resolved", - "schema": "public" - } - } - } + "role": "recertifier", + "permission": { + "columns": [ + "abs_change_id", + "control_id", + "log_usr_id", + "new_user_id", + "old_user_id", + "documented", + "security_relevant", + "change_action", + "change_request_info", + "unique_name", + "change_type_id", + "doku_admin", + "import_admin", + "mgm_id", + "changelog_user_comment", + "change_time", + "docu_time" + ], + "filter": { + "_and": [ + { + "mgm_id": { + "_in": "x-hasura-visible-managements" + } + } + ] + }, + "allow_aggregations": true + }, + "comment": "" }, { - "name": "ruleServicesByRsLastSeen", - "using": { - "foreign_key_constraint_on": { - "column": "rs_last_seen", - "table": { - "name": "rule_service", - "schema": "public" - } - } - } + "role": "reporter", + "permission": { + "columns": [ + "abs_change_id", + "control_id", + "log_usr_id", + "new_user_id", + "old_user_id", + "documented", + "security_relevant", + "change_action", + "change_request_info", + "unique_name", + "change_type_id", + "doku_admin", + "import_admin", + "mgm_id", + "changelog_user_comment", + "change_time", + "docu_time" + ], + "filter": { + "_and": [ + { + "mgm_id": { + "_in": "x-hasura-visible-managements" + } + } + ] + }, + "allow_aggregations": true + }, + "comment": "" }, { - "name": "ruleSvcResolvedsByRemoved", - "using": { - "foreign_key_constraint_on": { - "column": "removed", - "table": { - "name": "rule_svc_resolved", - "schema": "public" - } - } - } - }, + "role": "reporter-viewall", + "permission": { + "columns": [ + "abs_change_id", + "control_id", + "log_usr_id", + "new_user_id", + "old_user_id", + "documented", + "security_relevant", + "change_action", + "change_request_info", + "unique_name", + "change_type_id", + "doku_admin", + "import_admin", + "mgm_id", + "changelog_user_comment", + "change_time", + "docu_time" + ], + "filter": {}, + "allow_aggregations": true + }, + "comment": "" + } + ] + }, + { + "table": { + "name": "config", + "schema": "public" + }, + "object_relationships": [ { - "name": "ruleTosByRtLastSeen", + "name": "uiuser", "using": { - "foreign_key_constraint_on": { - "column": "rt_last_seen", - "table": { - "name": "rule_to", - "schema": "public" + "foreign_key_constraint_on": "config_user" + } + } + ], + "insert_permissions": [ + { + "role": "approver", + "permission": { + "check": { + "config_user": { + "_eq": "X-Hasura-User-Id" } - } + }, + "columns": [ + "config_user", + "config_key", + "config_value" + ] } }, { - "name": "ruleUserResolvedsByRemoved", - "using": { - "foreign_key_constraint_on": { - "column": "removed", - "table": { - "name": "rule_user_resolved", - "schema": "public" + "role": "auditor", + "permission": { + "check": { + "config_user": { + "_eq": "X-Hasura-User-Id" } - } + }, + "columns": [ + "config_key", + "config_value", + "config_user" + ] } }, { - "name": "rule_froms", - "using": { - "foreign_key_constraint_on": { - "column": "rf_create", - "table": { - "name": "rule_from", - "schema": "public" + "role": "fw-admin", + "permission": { + "check": { + "config_user": { + "_eq": "X-Hasura-User-Id" } - } + }, + "columns": [ + "config_user", + "config_key", + "config_value" + ] } }, { - "name": "rule_nwobj_resolveds", - "using": { - "foreign_key_constraint_on": { - "column": "created", - "table": { - "name": "rule_nwobj_resolved", - "schema": "public" + "role": "implementer", + "permission": { + "check": { + "config_user": { + "_eq": "X-Hasura-User-Id" } - } + }, + "columns": [ + "config_user", + "config_key", + "config_value" + ] } }, { - "name": "rule_services", - "using": { - "foreign_key_constraint_on": { - "column": "rs_create", - "table": { - "name": "rule_service", - "schema": "public" - } - } + "role": "modeller", + "permission": { + "check": { + "_or": [ + { + "config_user": { + "_eq": "X-Hasura-User-Id" + } + }, + { + "config_user": { + "_eq": 0 + } + } + ] + }, + "columns": [ + "config_key", + "config_value", + "config_user" + ] } }, { - "name": "rule_svc_resolveds", - "using": { - "foreign_key_constraint_on": { - "column": "created", - "table": { - "name": "rule_svc_resolved", - "schema": "public" + "role": "planner", + "permission": { + "check": { + "config_user": { + "_eq": "X-Hasura-User-Id" } - } + }, + "columns": [ + "config_user", + "config_key", + "config_value" + ] } }, { - "name": "rule_tos", - "using": { - "foreign_key_constraint_on": { - "column": "rt_create", - "table": { - "name": "rule_to", - "schema": "public" - } - } + "role": "recertifier", + "permission": { + "check": { + "_or": [ + { + "config_user": { + "_eq": "X-Hasura-User-Id" + } + }, + { + "config_user": { + "_eq": 0 + } + } + ] + }, + "columns": [ + "config_key", + "config_value", + "config_user" + ] } }, { - "name": "rule_user_resolveds", - "using": { - "foreign_key_constraint_on": { - "column": "created", - "table": { - "name": "rule_user_resolved", - "schema": "public" + "role": "reporter", + "permission": { + "check": { + "config_user": { + "_eq": "X-Hasura-User-Id" } - } + }, + "columns": [ + "config_user", + "config_key", + "config_value" + ] } }, { - "name": "rules", - "using": { - "foreign_key_constraint_on": { - "column": "rule_create", - "table": { - "name": "rule", - "schema": "public" + "role": "reporter-viewall", + "permission": { + "check": { + "config_user": { + "_eq": "X-Hasura-User-Id" } - } + }, + "columns": [ + "config_user", + "config_key", + "config_value" + ] } }, { - "name": "rulesByRuleLastSeen", - "using": { - "foreign_key_constraint_on": { - "column": "rule_last_seen", - "table": { - "name": "rule", - "schema": "public" + "role": "requester", + "permission": { + "check": { + "config_user": { + "_eq": "X-Hasura-User-Id" } - } + }, + "columns": [ + "config_user", + "config_key", + "config_value" + ] } }, { - "name": "services", - "using": { - "foreign_key_constraint_on": { - "column": "svc_create", - "table": { - "name": "service", - "schema": "public" + "role": "reviewer", + "permission": { + "check": { + "config_user": { + "_eq": "X-Hasura-User-Id" } - } + }, + "columns": [ + "config_user", + "config_key", + "config_value" + ] } - }, + } + ], + "select_permissions": [ { - "name": "servicesBySvcLastSeen", - "using": { - "foreign_key_constraint_on": { - "column": "svc_last_seen", - "table": { - "name": "service", - "schema": "public" + "role": "anonymous", + "permission": { + "columns": [ + "config_key", + "config_value", + "config_user" + ], + "filter": { + "config_user": { + "_eq": 0 } } } }, { - "name": "svcgrpFlatsByImportLastSeen", - "using": { - "foreign_key_constraint_on": { - "column": "import_last_seen", - "table": { - "name": "svcgrp_flat", - "schema": "public" - } + "role": "approver", + "permission": { + "columns": [ + "config_key", + "config_value", + "config_user" + ], + "filter": { + "_or": [ + { + "config_user": { + "_eq": "X-Hasura-User-Id" + } + }, + { + "config_user": { + "_eq": 0 + } + } + ] } } }, { - "name": "svcgrp_flats", - "using": { - "foreign_key_constraint_on": { - "column": "import_created", - "table": { - "name": "svcgrp_flat", - "schema": "public" - } - } + "role": "auditor", + "permission": { + "columns": [ + "config_user", + "config_key", + "config_value" + ], + "filter": {} } }, { - "name": "svcgrps", - "using": { - "foreign_key_constraint_on": { - "column": "import_created", - "table": { - "name": "svcgrp", - "schema": "public" - } + "role": "fw-admin", + "permission": { + "columns": [ + "config_user", + "config_key", + "config_value" + ], + "filter": { + "_or": [ + { + "config_user": { + "_eq": "X-Hasura-User-Id" + } + }, + { + "config_user": { + "_eq": 0 + } + } + ] } } }, { - "name": "svcgrpsByImportLastSeen", - "using": { - "foreign_key_constraint_on": { - "column": "import_last_seen", - "table": { - "name": "svcgrp", - "schema": "public" - } + "role": "implementer", + "permission": { + "columns": [ + "config_key", + "config_value", + "config_user" + ], + "filter": { + "_or": [ + { + "config_user": { + "_eq": "X-Hasura-User-Id" + } + }, + { + "config_user": { + "_eq": 0 + } + } + ] } } }, { - "name": "usergrpFlatsByImportLastSeen", - "using": { - "foreign_key_constraint_on": { - "column": "import_last_seen", - "table": { - "name": "usergrp_flat", - "schema": "public" - } - } + "role": "importer", + "permission": { + "columns": [ + "config_key", + "config_value", + "config_user" + ], + "filter": {}, + "allow_aggregations": true } }, { - "name": "usergrp_flats", - "using": { - "foreign_key_constraint_on": { - "column": "import_created", - "table": { - "name": "usergrp_flat", - "schema": "public" - } + "role": "middleware-server", + "permission": { + "columns": [ + "config_key", + "config_value", + "config_user" + ], + "filter": {} + } + }, + { + "role": "modeller", + "permission": { + "columns": [ + "config_key", + "config_value", + "config_user" + ], + "filter": { + "_or": [ + { + "config_user": { + "_eq": "X-Hasura-User-Id" + } + }, + { + "config_user": { + "_eq": 0 + } + } + ] } } }, { - "name": "usergrps", - "using": { - "foreign_key_constraint_on": { - "column": "import_created", - "table": { - "name": "usergrp", - "schema": "public" - } + "role": "planner", + "permission": { + "columns": [ + "config_key", + "config_value", + "config_user" + ], + "filter": { + "_or": [ + { + "config_user": { + "_eq": "X-Hasura-User-Id" + } + }, + { + "config_user": { + "_eq": 0 + } + } + ] } } }, { - "name": "usergrpsByImportLastSeen", - "using": { - "foreign_key_constraint_on": { - "column": "import_last_seen", - "table": { - "name": "usergrp", - "schema": "public" - } + "role": "recertifier", + "permission": { + "columns": [ + "config_key", + "config_value", + "config_user" + ], + "filter": { + "_or": [ + { + "config_user": { + "_eq": "X-Hasura-User-Id" + } + }, + { + "config_user": { + "_eq": 0 + } + } + ] } } }, { - "name": "usrs", - "using": { - "foreign_key_constraint_on": { - "column": "user_create", - "table": { - "name": "usr", - "schema": "public" - } + "role": "reporter", + "permission": { + "columns": [ + "config_key", + "config_value", + "config_user" + ], + "filter": { + "_or": [ + { + "config_user": { + "_eq": "X-Hasura-User-Id" + } + }, + { + "config_user": { + "_eq": 0 + } + } + ] } } }, { - "name": "usrsByUserLastSeen", - "using": { - "foreign_key_constraint_on": { - "column": "user_last_seen", - "table": { - "name": "usr", - "schema": "public" - } + "role": "reporter-viewall", + "permission": { + "columns": [ + "config_user", + "config_key", + "config_value" + ], + "filter": { + "_or": [ + { + "config_user": { + "_eq": "X-Hasura-User-Id" + } + }, + { + "config_user": { + "_eq": 0 + } + } + ] } } }, { - "name": "zones", - "using": { - "foreign_key_constraint_on": { - "column": "zone_create", - "table": { - "name": "zone", - "schema": "public" - } + "role": "requester", + "permission": { + "columns": [ + "config_key", + "config_value", + "config_user" + ], + "filter": { + "_or": [ + { + "config_user": { + "_eq": "X-Hasura-User-Id" + } + }, + { + "config_user": { + "_eq": 0 + } + } + ] } } }, { - "name": "zonesByZoneLastSeen", - "using": { - "foreign_key_constraint_on": { - "column": "zone_last_seen", - "table": { - "name": "zone", - "schema": "public" - } + "role": "reviewer", + "permission": { + "columns": [ + "config_key", + "config_value", + "config_user" + ], + "filter": { + "_or": [ + { + "config_user": { + "_eq": "X-Hasura-User-Id" + } + }, + { + "config_user": { + "_eq": 0 + } + } + ] } } } ], - "insert_permissions": [ + "update_permissions": [ { - "role": "importer", + "role": "approver", "permission": { - "check": {}, "columns": [ - "control_id", - "start_time", - "stop_time", - "is_initial_import", - "delimiter_group", - "delimiter_zone", - "delimiter_user", - "delimiter_list", - "mgm_id", - "last_change_in_config", - "successful_import", - "changes_found", - "import_errors" - ] + "config_value" + ], + "filter": { + "config_user": { + "_eq": "X-Hasura-User-Id" + } + }, + "check": null } - } - ], - "select_permissions": [ + }, { "role": "auditor", "permission": { "columns": [ - "control_id", - "start_time", - "stop_time", - "is_initial_import", - "delimiter_group", - "delimiter_zone", - "delimiter_user", - "delimiter_list", - "mgm_id", - "last_change_in_config", - "successful_import", - "changes_found", - "import_errors" + "config_user", + "config_key", + "config_value" ], - "filter": {}, - "allow_aggregations": true + "filter": { + "config_user": { + "_eq": "X-Hasura-User-Id" + } + }, + "check": null } }, { "role": "fw-admin", "permission": { "columns": [ - "control_id", - "changes_found", - "is_initial_import", - "successful_import", - "delimiter_group", - "delimiter_list", - "delimiter_user", - "delimiter_zone", - "import_errors", - "mgm_id", - "last_change_in_config", - "start_time", - "stop_time" + "config_value" ], - "filter": {}, - "allow_aggregations": true + "filter": { + "config_user": { + "_eq": "X-Hasura-User-Id" + } + }, + "check": null } }, { - "role": "importer", + "role": "implementer", "permission": { "columns": [ - "control_id", - "changes_found", - "is_initial_import", - "successful_import", - "delimiter_group", - "delimiter_list", - "delimiter_user", - "delimiter_zone", - "import_errors", - "mgm_id", - "last_change_in_config", - "start_time", - "stop_time" + "config_value" ], - "filter": {}, - "allow_aggregations": true + "filter": { + "config_user": { + "_eq": "X-Hasura-User-Id" + } + }, + "check": null } }, { - "role": "middleware-server", + "role": "modeller", "permission": { "columns": [ - "control_id", - "changes_found", - "is_initial_import", - "successful_import", - "delimiter_group", - "delimiter_list", - "delimiter_user", - "delimiter_zone", - "import_errors", - "mgm_id", - "last_change_in_config", - "start_time", - "stop_time" + "config_key", + "config_value", + "config_user" ], - "filter": {} + "filter": { + "_or": [ + { + "config_user": { + "_eq": "X-Hasura-User-Id" + } + }, + { + "config_user": { + "_eq": 0 + } + } + ] + }, + "check": null } }, { - "role": "recertifier", + "role": "planner", "permission": { "columns": [ - "changes_found", - "is_initial_import", - "successful_import", - "mgm_id", - "control_id", - "last_change_in_config", - "start_time", - "stop_time", - "delimiter_group", - "delimiter_list", - "delimiter_user", - "delimiter_zone", - "import_errors" + "config_value" ], "filter": { - "mgm_id": { - "_in": "x-hasura-visible-managements" + "config_user": { + "_eq": "X-Hasura-User-Id" } }, - "allow_aggregations": true + "check": null } }, { - "role": "reporter", + "role": "recertifier", "permission": { "columns": [ - "changes_found", - "is_initial_import", - "successful_import", - "mgm_id", - "control_id", - "last_change_in_config", - "start_time", - "stop_time", - "delimiter_group", - "delimiter_list", - "delimiter_user", - "delimiter_zone", - "import_errors" + "config_key", + "config_value", + "config_user" ], "filter": { - "mgm_id": { - "_in": "x-hasura-visible-managements" - } + "_or": [ + { + "config_user": { + "_eq": "X-Hasura-User-Id" + } + }, + { + "config_user": { + "_eq": 0 + } + } + ] }, - "allow_aggregations": true + "check": null } }, { - "role": "reporter-viewall", + "role": "reporter", "permission": { "columns": [ - "control_id", - "start_time", - "stop_time", - "is_initial_import", - "delimiter_group", - "delimiter_zone", - "delimiter_user", - "delimiter_list", - "mgm_id", - "last_change_in_config", - "successful_import", - "changes_found", - "import_errors" + "config_value" ], - "filter": {}, - "allow_aggregations": true + "filter": { + "config_user": { + "_eq": "X-Hasura-User-Id" + } + }, + "check": null } - } - ], - "update_permissions": [ + }, { - "role": "importer", + "role": "reporter-viewall", "permission": { "columns": [ - "control_id", - "changes_found", - "is_initial_import", - "successful_import", - "delimiter_group", - "delimiter_list", - "delimiter_user", - "delimiter_zone", - "import_errors", - "mgm_id", - "last_change_in_config", - "start_time", - "stop_time" + "config_value" ], - "filter": {}, - "check": {} + "filter": { + "config_user": { + "_eq": "X-Hasura-User-Id" + } + }, + "check": null } - } - ], - "delete_permissions": [ + }, { - "role": "importer", + "role": "requester", "permission": { - "filter": {} + "columns": [ + "config_value" + ], + "filter": { + "config_user": { + "_eq": "X-Hasura-User-Id" + } + }, + "check": null + } + }, + { + "role": "reviewer", + "permission": { + "columns": [ + "config_value" + ], + "filter": { + "config_user": { + "_eq": "X-Hasura-User-Id" + } + }, + "check": null } } ] }, { "table": { - "name": "import_credential", + "name": "customtxt", "schema": "public" }, - "array_relationships": [ + "object_relationships": [ { - "name": "management", + "name": "languageByLanguage", "using": { - "foreign_key_constraint_on": { - "column": "import_credential_id", - "table": { - "name": "management", - "schema": "public" - } - } + "foreign_key_constraint_on": "language" } } ], - "insert_permissions": [ + "select_permissions": [ { - "role": "fw-admin", + "role": "anonymous", "permission": { - "check": {}, "columns": [ - "cloud_client_id", - "cloud_client_secret", - "credential_name", "id", - "is_key_pair", - "public_key", - "secret", - "username" - ] - } - } - ], - "select_permissions": [ + "language", + "txt" + ], + "filter": {} + }, + "comment": "" + }, + { + "role": "approver", + "permission": { + "columns": [ + "id", + "language", + "txt" + ], + "filter": {} + }, + "comment": "" + }, { "role": "auditor", "permission": { "columns": [ - "cloud_client_id", - "credential_name", "id", - "is_key_pair", - "public_key", - "username" + "language", + "txt" ], - "filter": {}, - "allow_aggregations": true - } + "filter": {} + }, + "comment": "" }, { "role": "fw-admin", "permission": { "columns": [ - "cloud_client_id", - "cloud_client_secret", - "credential_name", "id", - "is_key_pair", - "public_key", - "secret", - "username" + "language", + "txt" ], - "filter": {}, - "allow_aggregations": true - } + "filter": {} + }, + "comment": "" }, { - "role": "importer", + "role": "implementer", "permission": { "columns": [ - "is_key_pair", - "cloud_client_id", - "cloud_client_secret", - "credential_name", - "username", "id", - "public_key", - "secret" + "language", + "txt" ], - "filter": {}, - "allow_aggregations": true - } + "filter": {} + }, + "comment": "" }, { "role": "middleware-server", "permission": { "columns": [ - "is_key_pair", - "cloud_client_id", - "cloud_client_secret", - "credential_name", - "username", "id", - "public_key", - "secret" + "language", + "txt" ], - "filter": {}, - "allow_aggregations": true - } - } - ], - "update_permissions": [ + "filter": {} + }, + "comment": "" + }, { - "role": "fw-admin", + "role": "modeller", "permission": { "columns": [ - "cloud_client_id", - "cloud_client_secret", - "credential_name", "id", - "is_key_pair", - "public_key", - "secret", - "username" + "language", + "txt" ], - "filter": {}, - "check": {} - } - } - ], - "delete_permissions": [ + "filter": {} + }, + "comment": "" + }, { - "role": "fw-admin", + "role": "planner", "permission": { + "columns": [ + "id", + "language", + "txt" + ], "filter": {} - } + }, + "comment": "" + }, + { + "role": "recertifier", + "permission": { + "columns": [ + "id", + "language", + "txt" + ], + "filter": {} + }, + "comment": "" + }, + { + "role": "reporter", + "permission": { + "columns": [ + "id", + "language", + "txt" + ], + "filter": {} + }, + "comment": "" + }, + { + "role": "reporter-viewall", + "permission": { + "columns": [ + "id", + "language", + "txt" + ], + "filter": {} + }, + "comment": "" + }, + { + "role": "requester", + "permission": { + "columns": [ + "id", + "language", + "txt" + ], + "filter": {} + }, + "comment": "" + }, + { + "role": "reviewer", + "permission": { + "columns": [ + "id", + "language", + "txt" + ], + "filter": {} + }, + "comment": "" } ] }, { "table": { - "name": "import_full_config", + "name": "device", "schema": "public" }, "object_relationships": [ { - "name": "import_control", + "name": "management", "using": { - "foreign_key_constraint_on": "import_id" + "foreign_key_constraint_on": "mgm_id" } }, { - "name": "management", + "name": "stm_dev_typ", "using": { - "foreign_key_constraint_on": "mgm_id" + "foreign_key_constraint_on": "dev_typ_id" } } ], - "insert_permissions": [ + "array_relationships": [ { - "role": "importer", - "permission": { - "check": {}, - "columns": [ - "config", - "import_id", - "mgm_id" - ] + "name": "alerts", + "using": { + "foreign_key_constraint_on": { + "column": "alert_dev_id", + "table": { + "name": "alert", + "schema": "public" + } + } } - } - ], - "select_permissions": [ + }, { - "role": "importer", - "permission": { - "columns": [ - "import_id", - "mgm_id", - "config" - ], - "filter": {}, - "allow_aggregations": true + "name": "gw_interfaces", + "using": { + "foreign_key_constraint_on": { + "column": "routing_device", + "table": { + "name": "gw_interface", + "schema": "public" + } + } + } + }, + { + "name": "gw_routes", + "using": { + "foreign_key_constraint_on": { + "column": "routing_device", + "table": { + "name": "gw_route", + "schema": "public" + } + } + } + }, + { + "name": "impltasks", + "using": { + "foreign_key_constraint_on": { + "column": "device_id", + "table": { + "name": "impltask", + "schema": "request" + } + } + } + }, + { + "name": "objects", + "using": { + "foreign_key_constraint_on": { + "column": "obj_nat_install", + "table": { + "name": "object", + "schema": "public" + } + } + } + }, + { + "name": "reqelements", + "using": { + "foreign_key_constraint_on": { + "column": "device_id", + "table": { + "name": "reqelement", + "schema": "request" + } + } + } + }, + { + "name": "rule_enforced_on_gateways", + "using": { + "foreign_key_constraint_on": { + "column": "dev_id", + "table": { + "name": "rule_enforced_on_gateway", + "schema": "public" + } + } + } + }, + { + "name": "rulebase_links", + "using": { + "foreign_key_constraint_on": { + "column": "gw_id", + "table": { + "name": "rulebase_link", + "schema": "public" + } + } + } + }, + { + "name": "tenant_to_devices", + "using": { + "foreign_key_constraint_on": { + "column": "device_id", + "table": { + "name": "tenant_to_device", + "schema": "public" + } + } } } ], - "delete_permissions": [ + "computed_fields": [ { - "role": "importer", - "permission": { - "filter": {} + "name": "get_changelog_rules_for_tenant", + "definition": { + "function": { + "name": "get_changelog_rules_for_tenant", + "schema": "public" + }, + "session_argument": "hasura_session" } - } - ] - }, - { - "table": { - "name": "import_object", - "schema": "public" - }, - "object_relationships": [ + }, { - "name": "import_control", - "using": { - "foreign_key_constraint_on": "control_id" + "name": "get_rules_for_owner", + "definition": { + "function": { + "name": "get_rules_for_owner", + "schema": "public" + } + } + }, + { + "name": "get_rules_for_tenant", + "definition": { + "function": { + "name": "get_rules_for_tenant", + "schema": "public" + }, + "session_argument": "hasura_session" } } ], "insert_permissions": [ { - "role": "importer", + "role": "fw-admin", "permission": { "check": {}, "columns": [ - "obj_id", - "obj_zone", - "obj_name", - "obj_typ", - "obj_member_names", - "obj_member_refs", - "obj_member_excludes", - "obj_sw", - "obj_ip", - "obj_ip_end", - "obj_color", - "obj_comment", - "obj_location", - "control_id", - "obj_uid", - "last_change_admin", - "last_change_time", - "obj_scope" + "clearing_import_ran", + "dev_active", + "do_not_import", + "force_initial_import", + "hide_in_gui", + "dev_name", + "dev_uid", + "global_rulebase_name", + "global_rulebase_uid", + "local_rulebase_name", + "local_rulebase_uid", + "package_name", + "package_uid", + "dev_id", + "dev_typ_id", + "mgm_id", + "dev_comment", + "dev_create", + "dev_update" ] } } ], "select_permissions": [ { - "role": "importer", + "role": "approver", "permission": { "columns": [ - "obj_id", - "obj_zone", - "obj_name", - "obj_typ", - "obj_member_names", - "obj_member_refs", - "obj_member_excludes", - "obj_sw", - "obj_ip", - "obj_ip_end", - "obj_color", - "obj_comment", - "obj_location", - "control_id", - "obj_uid", - "last_change_admin", - "last_change_time", - "obj_scope" + "clearing_import_ran", + "dev_active", + "do_not_import", + "force_initial_import", + "hide_in_gui", + "dev_name", + "dev_uid", + "global_rulebase_name", + "global_rulebase_uid", + "local_rulebase_name", + "local_rulebase_uid", + "package_name", + "package_uid", + "dev_id", + "dev_typ_id", + "mgm_id", + "dev_comment", + "dev_create", + "dev_update" + ], + "filter": { + "_and": [ + { + "mgm_id": { + "_in": "x-hasura-visible-managements" + } + }, + { + "dev_id": { + "_in": "x-hasura-visible-devices" + } + } + ] + }, + "allow_aggregations": true + } + }, + { + "role": "auditor", + "permission": { + "columns": [ + "clearing_import_ran", + "dev_active", + "do_not_import", + "force_initial_import", + "hide_in_gui", + "dev_name", + "dev_uid", + "global_rulebase_name", + "global_rulebase_uid", + "local_rulebase_name", + "local_rulebase_uid", + "package_name", + "package_uid", + "dev_id", + "dev_typ_id", + "mgm_id", + "dev_comment", + "dev_create", + "dev_update" ], "filter": {}, "allow_aggregations": true } - } - ], - "update_permissions": [ + }, { - "role": "importer", + "role": "fw-admin", "permission": { "columns": [ - "control_id", - "obj_id", - "last_change_admin", - "obj_name", - "obj_scope", - "obj_sw", - "obj_ip", - "obj_ip_end", - "obj_color", - "obj_comment", - "obj_location", - "obj_member_excludes", - "obj_member_names", - "obj_member_refs", - "obj_typ", - "obj_uid", - "obj_zone", - "last_change_time" + "clearing_import_ran", + "dev_active", + "do_not_import", + "force_initial_import", + "hide_in_gui", + "dev_name", + "global_rulebase_name", + "global_rulebase_uid", + "local_rulebase_name", + "local_rulebase_uid", + "package_name", + "package_uid", + "dev_id", + "dev_typ_id", + "mgm_id", + "dev_comment", + "dev_create", + "dev_update" ], "filter": {}, - "check": null - } - } - ], - "delete_permissions": [ - { - "role": "importer", - "permission": { - "filter": {} - } - } - ] - }, - { - "table": { - "name": "import_rule", - "schema": "public" - }, - "object_relationships": [ - { - "name": "import_control", - "using": { - "foreign_key_constraint_on": "control_id" + "allow_aggregations": true } - } - ], - "insert_permissions": [ + }, { - "role": "importer", + "role": "implementer", "permission": { - "check": {}, "columns": [ - "control_id", - "rule_id", - "rule_disabled", - "rule_dst_neg", - "rule_implied", - "rule_src_neg", - "rule_svc_neg", - "last_change_admin", - "rule_installon", - "rule_name", - "rule_ruleid", - "rule_scope", - "rule_sysid", - "rule_time", - "rule_type", - "rulebase_name", - "rule_num", - "parent_rule_uid", - "rule_action", - "rule_comment", - "rule_dst", - "rule_dst_refs", - "rule_from_zone", - "rule_head_text", - "rule_src", - "rule_src_refs", - "rule_svc", - "rule_svc_refs", - "rule_to_zone", - "rule_track", - "rule_uid", - "last_change_time", - "last_hit" - ] + "clearing_import_ran", + "dev_active", + "do_not_import", + "force_initial_import", + "hide_in_gui", + "dev_name", + "dev_uid", + "global_rulebase_name", + "global_rulebase_uid", + "local_rulebase_name", + "local_rulebase_uid", + "package_name", + "package_uid", + "dev_id", + "dev_typ_id", + "mgm_id", + "dev_comment", + "dev_create", + "dev_update" + ], + "filter": { + "_and": [ + { + "mgm_id": { + "_in": "x-hasura-visible-managements" + } + }, + { + "dev_id": { + "_in": "x-hasura-visible-devices" + } + } + ] + }, + "allow_aggregations": true } - } - ], - "select_permissions": [ + }, { "role": "importer", "permission": { "columns": [ - "control_id" + "clearing_import_ran", + "dev_active", + "do_not_import", + "force_initial_import", + "hide_in_gui", + "dev_name", + "dev_uid", + "global_rulebase_name", + "global_rulebase_uid", + "local_rulebase_name", + "local_rulebase_uid", + "package_name", + "package_uid", + "dev_id", + "dev_typ_id", + "mgm_id", + "dev_comment", + "dev_create", + "dev_update" ], "filter": {}, "allow_aggregations": true } - } - ], - "delete_permissions": [ - { - "role": "importer", - "permission": { - "filter": {} - } - } - ] - }, - { - "table": { - "name": "import_service", - "schema": "public" - }, - "object_relationships": [ - { - "name": "import_control", - "using": { - "foreign_key_constraint_on": "control_id" - } - } - ], - "insert_permissions": [ + }, { - "role": "importer", + "role": "middleware-server", "permission": { - "check": {}, "columns": [ - "svc_id", - "control_id", - "svc_typ", - "svc_name", - "svc_comment", - "svc_color", - "ip_proto", - "svc_prod_specific", - "rpc_nr", - "svc_uid", - "svc_port", - "svc_port_end", - "svc_source_port", - "svc_source_port_end", - "svc_timeout_std", - "svc_timeout", - "svc_member_names", - "svc_member_refs", - "last_change_admin", - "last_change_time", - "svc_scope" - ] + "clearing_import_ran", + "dev_active", + "do_not_import", + "force_initial_import", + "hide_in_gui", + "dev_name", + "dev_uid", + "global_rulebase_name", + "global_rulebase_uid", + "local_rulebase_name", + "local_rulebase_uid", + "package_name", + "package_uid", + "dev_id", + "dev_typ_id", + "mgm_id", + "dev_comment", + "dev_create", + "dev_update" + ], + "filter": {} } - } - ], - "select_permissions": [ + }, { - "role": "importer", + "role": "modeller", "permission": { "columns": [ - "control_id" + "clearing_import_ran", + "dev_active", + "do_not_import", + "force_initial_import", + "hide_in_gui", + "dev_name", + "dev_uid", + "global_rulebase_name", + "global_rulebase_uid", + "local_rulebase_name", + "local_rulebase_uid", + "package_name", + "package_uid", + "dev_id", + "dev_typ_id", + "mgm_id", + "dev_comment", + "dev_create", + "dev_update" ], - "filter": {}, + "filter": { + "_and": [ + { + "mgm_id": { + "_in": "x-hasura-visible-managements" + } + }, + { + "dev_id": { + "_in": "x-hasura-visible-devices" + } + } + ] + }, "allow_aggregations": true } - } - ], - "delete_permissions": [ + }, { - "role": "importer", - "permission": { - "filter": {} - } - } - ] - }, - { - "table": { - "name": "import_user", - "schema": "public" - }, - "object_relationships": [ - { - "name": "import_control", - "using": { - "foreign_key_constraint_on": "control_id" - } - } - ], - "insert_permissions": [ - { - "role": "importer", - "permission": { - "check": {}, - "columns": [ - "user_id", - "control_id", - "user_color", - "user_name", - "user_typ", - "user_comment", - "user_authmethod", - "user_valid_from", - "user_valid_until", - "user_member_names", - "user_member_refs", - "user_uid", - "user_firstname", - "user_lastname", - "src_restrict", - "dst_restrict", - "time_restrict", - "last_change_admin", - "last_change_time", - "user_scope" - ] - } - } - ], - "select_permissions": [ - { - "role": "importer", + "role": "planner", "permission": { "columns": [ - "control_id" + "clearing_import_ran", + "dev_active", + "do_not_import", + "force_initial_import", + "hide_in_gui", + "dev_name", + "dev_uid", + "global_rulebase_name", + "global_rulebase_uid", + "local_rulebase_name", + "local_rulebase_uid", + "package_name", + "package_uid", + "dev_id", + "dev_typ_id", + "mgm_id", + "dev_comment", + "dev_create", + "dev_update" ], - "filter": {}, + "filter": { + "_and": [ + { + "mgm_id": { + "_in": "x-hasura-visible-managements" + } + }, + { + "dev_id": { + "_in": "x-hasura-visible-devices" + } + } + ] + }, "allow_aggregations": true } - } - ], - "delete_permissions": [ - { - "role": "importer", - "permission": { - "filter": {} - } - } - ] - }, - { - "table": { - "name": "import_zone", - "schema": "public" - }, - "object_relationships": [ - { - "name": "import_control", - "using": { - "foreign_key_constraint_on": "control_id" - } - } - ], - "insert_permissions": [ - { - "role": "importer", - "permission": { - "check": {}, - "columns": [ - "control_id", - "zone_name", - "last_change_time" - ] - } - } - ] - }, - { - "table": { - "name": "language", - "schema": "public" - }, - "array_relationships": [ - { - "name": "txts", - "using": { - "foreign_key_constraint_on": { - "column": "language", - "table": { - "name": "txt", - "schema": "public" - } - } - } }, { - "name": "uiusers", - "using": { - "foreign_key_constraint_on": { - "column": "uiuser_language", - "table": { - "name": "uiuser", - "schema": "public" - } - } - } - } - ], - "select_permissions": [ - { - "role": "anonymous", + "role": "recertifier", "permission": { "columns": [ - "name", - "culture_info" + "clearing_import_ran", + "dev_active", + "do_not_import", + "force_initial_import", + "hide_in_gui", + "dev_name", + "dev_uid", + "global_rulebase_name", + "global_rulebase_uid", + "local_rulebase_name", + "local_rulebase_uid", + "package_name", + "package_uid", + "dev_id", + "dev_typ_id", + "mgm_id", + "dev_comment", + "dev_create", + "dev_update" ], - "filter": {}, + "filter": { + "_and": [ + { + "mgm_id": { + "_in": "x-hasura-visible-managements" + } + }, + { + "dev_id": { + "_in": "x-hasura-visible-devices" + } + } + ] + }, "allow_aggregations": true } }, { - "role": "approver", - "permission": { - "columns": [ - "culture_info", - "name" - ], - "filter": {} - } - }, - { - "role": "auditor", + "role": "reporter", "permission": { "columns": [ - "culture_info", - "name" + "clearing_import_ran", + "dev_active", + "do_not_import", + "force_initial_import", + "hide_in_gui", + "dev_name", + "dev_uid", + "global_rulebase_name", + "global_rulebase_uid", + "local_rulebase_name", + "local_rulebase_uid", + "package_name", + "package_uid", + "dev_id", + "dev_typ_id", + "mgm_id", + "dev_comment", + "dev_create", + "dev_update" ], - "filter": {} + "filter": { + "_and": [ + { + "mgm_id": { + "_in": "x-hasura-visible-managements" + } + }, + { + "dev_id": { + "_in": "x-hasura-visible-devices" + } + } + ] + }, + "allow_aggregations": true } }, { - "role": "fw-admin", + "role": "reporter-viewall", "permission": { "columns": [ - "culture_info", - "name" + "clearing_import_ran", + "dev_active", + "do_not_import", + "force_initial_import", + "hide_in_gui", + "dev_name", + "dev_uid", + "global_rulebase_name", + "global_rulebase_uid", + "local_rulebase_name", + "local_rulebase_uid", + "package_name", + "package_uid", + "dev_id", + "dev_typ_id", + "mgm_id", + "dev_comment", + "dev_create", + "dev_update" ], - "filter": {} + "filter": {}, + "allow_aggregations": true } }, { - "role": "implementer", + "role": "requester", "permission": { "columns": [ - "culture_info", - "name" - ], - "filter": {} + "clearing_import_ran", + "dev_active", + "do_not_import", + "force_initial_import", + "hide_in_gui", + "dev_name", + "dev_uid", + "global_rulebase_name", + "global_rulebase_uid", + "local_rulebase_name", + "local_rulebase_uid", + "package_name", + "package_uid", + "dev_id", + "dev_typ_id", + "mgm_id", + "dev_comment", + "dev_create", + "dev_update" + ], + "filter": { + "_and": [ + { + "mgm_id": { + "_in": "x-hasura-visible-managements" + } + }, + { + "dev_id": { + "_in": "x-hasura-visible-devices" + } + } + ] + }, + "allow_aggregations": true } }, + { + "role": "reviewer", + "permission": { + "columns": [ + "clearing_import_ran", + "dev_active", + "do_not_import", + "force_initial_import", + "hide_in_gui", + "dev_name", + "dev_uid", + "global_rulebase_name", + "global_rulebase_uid", + "local_rulebase_name", + "local_rulebase_uid", + "package_name", + "package_uid", + "dev_id", + "dev_typ_id", + "mgm_id", + "dev_comment", + "dev_create", + "dev_update" + ], + "filter": { + "_and": [ + { + "mgm_id": { + "_in": "x-hasura-visible-managements" + } + }, + { + "dev_id": { + "_in": "x-hasura-visible-devices" + } + } + ] + }, + "allow_aggregations": true + } + } + ], + "update_permissions": [ + { + "role": "fw-admin", + "permission": { + "columns": [ + "clearing_import_ran", + "dev_active", + "do_not_import", + "force_initial_import", + "hide_in_gui", + "dev_name", + "dev_uid", + "global_rulebase_name", + "global_rulebase_uid", + "local_rulebase_name", + "local_rulebase_uid", + "package_name", + "package_uid", + "dev_id", + "dev_typ_id", + "mgm_id", + "dev_comment", + "dev_create", + "dev_update" + ], + "filter": {}, + "check": {} + } + } + ] + }, + { + "table": { + "name": "device_type", + "schema": "public" + }, + "insert_permissions": [ { "role": "middleware-server", "permission": { + "check": {}, "columns": [ - "culture_info", + "id", "name" - ], - "filter": {} + ] } - }, + } + ], + "select_permissions": [ { - "role": "planner", + "role": "auditor", "permission": { "columns": [ - "culture_info", + "id", "name" ], "filter": {} } }, { - "role": "recertifier", + "role": "fw-admin", "permission": { "columns": [ - "culture_info", - "name" + "name", + "id" ], "filter": {} } }, { - "role": "reporter", + "role": "middleware-server", "permission": { "columns": [ - "culture_info", + "id", "name" ], "filter": {} } }, { - "role": "reporter-viewall", + "role": "recertifier", "permission": { "columns": [ "name", - "culture_info" + "id" ], "filter": {} - } + }, + "comment": "" }, { - "role": "requester", + "role": "reporter", "permission": { "columns": [ - "culture_info", - "name" + "name", + "id" ], "filter": {} - } + }, + "comment": "" }, { - "role": "reviewer", + "role": "reporter-viewall", "permission": { "columns": [ - "culture_info", + "name", + "id" + ], + "filter": {} + }, + "comment": "" + } + ], + "update_permissions": [ + { + "role": "middleware-server", + "permission": { + "columns": [ + "id", "name" ], + "filter": {}, + "check": null + } + } + ], + "delete_permissions": [ + { + "role": "middleware-server", + "permission": { "filter": {} } } @@ -5038,28 +6483,26 @@ }, { "table": { - "name": "ldap_connection", + "name": "error", + "schema": "public" + } + }, + { + "table": { + "name": "ext_request", "schema": "public" }, "object_relationships": [ { - "name": "tenant", + "name": "owner", "using": { - "foreign_key_constraint_on": "tenant_id" + "foreign_key_constraint_on": "owner_id" } - } - ], - "array_relationships": [ + }, { - "name": "uiusers", + "name": "ticket", "using": { - "foreign_key_constraint_on": { - "column": "ldap_connection_id", - "table": { - "name": "uiuser", - "schema": "public" - } - } + "foreign_key_constraint_on": "ticket_id" } } ], @@ -5069,204 +6512,256 @@ "permission": { "check": {}, "columns": [ - "active", - "ldap_connection_id", - "ldap_global_tenant_name", - "ldap_name", - "ldap_pattern_length", - "ldap_port", - "ldap_search_user", - "ldap_search_user_pwd", - "ldap_searchpath_for_groups", - "ldap_searchpath_for_roles", - "ldap_searchpath_for_users", - "ldap_server", - "ldap_tenant_level", - "ldap_tls", - "ldap_type", - "ldap_write_user", - "ldap_write_user_pwd", - "tenant_id" + "attempts", + "create_date", + "ext_query_variables", + "ext_request_content", + "ext_request_state", + "ext_request_type", + "ext_ticket_id", + "ext_ticket_system", + "finish_date", + "id", + "last_creation_response", + "last_processing_response", + "locked", + "owner_id", + "task_number", + "ticket_id", + "wait_cycles" ] - } + }, + "comment": "" + }, + { + "role": "modeller", + "permission": { + "check": {}, + "columns": [ + "create_date", + "ext_query_variables", + "ext_request_content", + "ext_request_state", + "ext_request_type", + "ext_ticket_system", + "finish_date", + "id", + "locked", + "owner_id", + "task_number", + "ticket_id", + "wait_cycles" + ] + }, + "comment": "" } ], "select_permissions": [ { - "role": "approver", + "role": "auditor", "permission": { "columns": [ - "ldap_connection_id", - "ldap_tenant_level" + "attempts", + "create_date", + "ext_query_variables", + "ext_request_content", + "ext_request_state", + "ext_request_type", + "ext_ticket_id", + "ext_ticket_system", + "finish_date", + "id", + "last_creation_response", + "last_processing_response", + "locked", + "owner_id", + "task_number", + "ticket_id", + "wait_cycles" ], "filter": {} - } + }, + "comment": "" }, { - "role": "auditor", + "role": "middleware-server", "permission": { "columns": [ - "active", - "ldap_connection_id", - "ldap_global_tenant_name", - "ldap_name", - "ldap_pattern_length", - "ldap_port", - "ldap_search_user", - "ldap_search_user_pwd", - "ldap_searchpath_for_groups", - "ldap_searchpath_for_roles", - "ldap_searchpath_for_users", - "ldap_server", - "ldap_tenant_level", - "ldap_tls", - "ldap_type", - "ldap_write_user", - "ldap_write_user_pwd", - "tenant_id" - ], - "filter": {} - } - }, - { - "role": "fw-admin", - "permission": { - "columns": [ - "ldap_connection_id", - "ldap_tenant_level" + "id", + "ticket_id", + "locked", + "ext_query_variables", + "ext_request_content", + "ext_request_state", + "ext_request_type", + "ext_ticket_id", + "ext_ticket_system", + "last_creation_response", + "last_processing_response", + "attempts", + "owner_id", + "task_number", + "wait_cycles", + "create_date", + "finish_date" ], "filter": {} - } + }, + "comment": "" }, { - "role": "implementer", + "role": "modeller", "permission": { "columns": [ - "ldap_connection_id", - "ldap_tenant_level" + "attempts", + "create_date", + "ext_query_variables", + "ext_request_content", + "ext_request_state", + "ext_request_type", + "ext_ticket_id", + "ext_ticket_system", + "finish_date", + "id", + "last_creation_response", + "last_processing_response", + "locked", + "owner_id", + "task_number", + "ticket_id", + "wait_cycles" ], "filter": {} - } - }, + }, + "comment": "" + } + ], + "update_permissions": [ { "role": "middleware-server", "permission": { "columns": [ - "active", - "ldap_connection_id", - "ldap_global_tenant_name", - "ldap_name", - "ldap_pattern_length", - "ldap_port", - "ldap_search_user", - "ldap_search_user_pwd", - "ldap_searchpath_for_groups", - "ldap_searchpath_for_roles", - "ldap_searchpath_for_users", - "ldap_server", - "ldap_tenant_level", - "ldap_tls", - "ldap_type", - "ldap_write_user", - "ldap_write_user_pwd", - "tenant_id" - ], - "filter": {} - } - }, - { - "role": "planner", - "permission": { - "columns": [ - "ldap_connection_id", - "ldap_tenant_level" + "attempts", + "create_date", + "ext_query_variables", + "ext_request_content", + "ext_request_state", + "ext_request_type", + "ext_ticket_id", + "ext_ticket_system", + "finish_date", + "id", + "last_creation_response", + "last_processing_response", + "locked", + "owner_id", + "task_number", + "ticket_id", + "wait_cycles" ], - "filter": {} - } + "filter": {}, + "check": null + }, + "comment": "" }, { - "role": "recertifier", + "role": "modeller", "permission": { "columns": [ - "ldap_connection_id", - "ldap_tenant_level" + "ext_request_state", + "finish_date", + "locked" ], - "filter": {} - } - }, + "filter": {}, + "check": null + }, + "comment": "" + } + ] + }, + { + "table": { + "name": "gw_interface", + "schema": "public" + }, + "object_relationships": [ { - "role": "reporter", - "permission": { - "columns": [ - "ldap_connection_id", - "ldap_tenant_level" - ], - "filter": {} + "name": "device", + "using": { + "foreign_key_constraint_on": "routing_device" } - }, + } + ], + "array_relationships": [ { - "role": "reporter-viewall", - "permission": { - "columns": [ - "ldap_connection_id", - "ldap_tenant_level" - ], - "filter": {} + "name": "gw_routes", + "using": { + "foreign_key_constraint_on": { + "column": "interface_id", + "table": { + "name": "gw_route", + "schema": "public" + } + } } - }, + } + ], + "insert_permissions": [ { - "role": "requester", + "role": "importer", "permission": { + "check": {}, "columns": [ - "ldap_connection_id", - "ldap_tenant_level" - ], - "filter": {} + "state_up", + "name", + "ip", + "id", + "ip_version", + "netmask_bits", + "routing_device" + ] } - }, + } + ], + "select_permissions": [ { - "role": "reviewer", + "role": "importer", "permission": { "columns": [ - "ldap_connection_id", - "ldap_tenant_level" + "state_up", + "name", + "ip", + "id", + "ip_version", + "netmask_bits", + "routing_device" ], - "filter": {} + "filter": {}, + "allow_aggregations": true } } ], "update_permissions": [ { - "role": "middleware-server", + "role": "importer", "permission": { "columns": [ - "active", - "ldap_connection_id", - "ldap_global_tenant_name", - "ldap_name", - "ldap_pattern_length", - "ldap_port", - "ldap_search_user", - "ldap_search_user_pwd", - "ldap_searchpath_for_groups", - "ldap_searchpath_for_roles", - "ldap_searchpath_for_users", - "ldap_server", - "ldap_tenant_level", - "ldap_tls", - "ldap_type", - "ldap_write_user", - "ldap_write_user_pwd", - "tenant_id" + "state_up", + "name", + "ip", + "id", + "ip_version", + "netmask_bits", + "routing_device" ], "filter": {}, - "check": null + "check": {} } } ], "delete_permissions": [ { - "role": "middleware-server", + "role": "importer", "permission": { "filter": {} } @@ -5275,787 +6770,461 @@ }, { "table": { - "name": "log_data_issue", + "name": "gw_route", "schema": "public" }, "object_relationships": [ { - "name": "import_control", + "name": "device", "using": { - "foreign_key_constraint_on": "import_id" + "foreign_key_constraint_on": "routing_device" } }, { - "name": "uiuser", - "using": { - "foreign_key_constraint_on": "user_id" - } - } - ], - "array_relationships": [ - { - "name": "alerts", + "name": "gw_interface", "using": { - "foreign_key_constraint_on": { - "column": "ref_log_id", - "table": { - "name": "alert", - "schema": "public" - } - } + "foreign_key_constraint_on": "interface_id" } } ], "insert_permissions": [ { - "role": "approver", + "role": "importer", "permission": { "check": {}, "columns": [ - "data_issue_id", - "import_id", - "rule_id", - "description", - "object_name", - "object_type", - "object_uid", - "rule_uid", + "static", + "interface", + "destination", "source", - "suspected_cause", - "issue_dev_id", - "issue_mgm_id", - "severity", - "user_id", - "issue_timestamp" + "target_gateway", + "distance", + "id", + "interface_id", + "ip_version", + "metric", + "routing_device" ] } - }, + } + ], + "select_permissions": [ { - "role": "auditor", + "role": "importer", "permission": { - "check": {}, "columns": [ - "data_issue_id", - "import_id", - "rule_id", - "description", - "object_name", - "object_type", - "object_uid", - "rule_uid", + "static", + "interface", + "destination", "source", - "suspected_cause", - "issue_dev_id", - "issue_mgm_id", - "severity", - "user_id", - "issue_timestamp" - ] + "target_gateway", + "distance", + "id", + "interface_id", + "ip_version", + "metric", + "routing_device" + ], + "filter": {}, + "allow_aggregations": true } - }, + } + ], + "update_permissions": [ { - "role": "fw-admin", + "role": "importer", "permission": { - "check": {}, "columns": [ - "data_issue_id", - "import_id", - "rule_id", - "description", - "object_name", - "object_type", - "object_uid", - "rule_uid", + "static", + "interface", + "destination", "source", - "suspected_cause", - "issue_dev_id", - "issue_mgm_id", - "severity", - "user_id", - "issue_timestamp" - ] + "target_gateway", + "distance", + "id", + "interface_id", + "ip_version", + "metric", + "routing_device" + ], + "filter": {}, + "check": {} } - }, + } + ], + "delete_permissions": [ { - "role": "implementer", + "role": "importer", "permission": { - "check": {}, - "columns": [ - "data_issue_id", - "import_id", - "rule_id", - "description", - "object_name", - "object_type", - "object_uid", - "rule_uid", - "source", - "suspected_cause", - "issue_dev_id", - "issue_mgm_id", - "severity", - "user_id", - "issue_timestamp" - ] + "filter": {} + } + } + ] + }, + { + "table": { + "name": "import_changelog", + "schema": "public" + }, + "object_relationships": [ + { + "name": "import_control", + "using": { + "foreign_key_constraint_on": "control_id" + } + } + ] + }, + { + "table": { + "name": "import_config", + "schema": "public" + }, + "object_relationships": [ + { + "name": "import_control", + "using": { + "foreign_key_constraint_on": "import_id" } }, + { + "name": "management", + "using": { + "foreign_key_constraint_on": "mgm_id" + } + } + ], + "insert_permissions": [ { "role": "importer", "permission": { "check": {}, "columns": [ - "data_issue_id", - "description", "import_id", - "issue_dev_id", - "issue_mgm_id", - "issue_timestamp", - "object_name", - "object_type", - "object_uid", - "rule_id", - "rule_uid", - "severity", - "source", - "suspected_cause", - "user_id" + "debug_mode", + "start_import_flag", + "mgm_id", + "config" ] - } - }, + }, + "comment": "" + } + ], + "select_permissions": [ { - "role": "middleware-server", + "role": "importer", "permission": { - "check": {}, "columns": [ - "data_issue_id", - "description", "import_id", - "issue_dev_id", - "issue_mgm_id", - "issue_timestamp", - "object_name", - "object_type", - "object_uid", - "rule_id", - "rule_uid", - "severity", - "source", - "suspected_cause", - "user_id" - ] - } - }, + "debug_mode", + "start_import_flag", + "mgm_id", + "config" + ], + "filter": {}, + "allow_aggregations": true + }, + "comment": "" + } + ], + "delete_permissions": [ { - "role": "planner", + "role": "importer", "permission": { - "check": {}, - "columns": [ - "data_issue_id", - "import_id", - "rule_id", - "description", - "object_name", - "object_type", - "object_uid", - "rule_uid", - "source", - "suspected_cause", - "issue_dev_id", - "issue_mgm_id", - "severity", - "user_id", - "issue_timestamp" - ] + "filter": {} + } + } + ] + }, + { + "table": { + "name": "import_control", + "schema": "public" + }, + "object_relationships": [ + { + "name": "import_config", + "using": { + "foreign_key_constraint_on": { + "column": "import_id", + "table": { + "name": "import_config", + "schema": "public" + } + } } }, { - "role": "recertifier", - "permission": { - "check": {}, - "columns": [ - "data_issue_id", - "import_id", - "rule_id", - "description", - "object_name", - "object_type", - "object_uid", - "rule_uid", - "source", - "suspected_cause", - "issue_dev_id", - "issue_mgm_id", - "severity", - "user_id", - "issue_timestamp" - ] + "name": "import_full_config", + "using": { + "foreign_key_constraint_on": { + "column": "import_id", + "table": { + "name": "import_full_config", + "schema": "public" + } + } } }, { - "role": "reporter", - "permission": { - "check": {}, - "columns": [ - "data_issue_id", - "import_id", - "rule_id", - "description", - "object_name", - "object_type", - "object_uid", - "rule_uid", - "source", - "suspected_cause", - "issue_dev_id", - "issue_mgm_id", - "severity", - "user_id", - "issue_timestamp" - ] + "name": "management", + "using": { + "foreign_key_constraint_on": "mgm_id" } }, { - "role": "reporter-viewall", - "permission": { - "check": {}, - "columns": [ - "data_issue_id", - "import_id", - "rule_id", - "description", - "object_name", - "object_type", - "object_uid", - "rule_uid", - "source", - "suspected_cause", - "issue_dev_id", - "issue_mgm_id", - "severity", - "user_id", - "issue_timestamp" - ] + "name": "stm_import", + "using": { + "foreign_key_constraint_on": "import_type_id" } - }, + } + ], + "array_relationships": [ { - "role": "requester", - "permission": { - "check": {}, - "columns": [ - "data_issue_id", - "import_id", - "rule_id", - "description", - "object_name", - "object_type", - "object_uid", - "rule_uid", - "source", - "suspected_cause", - "issue_dev_id", - "issue_mgm_id", - "severity", - "user_id", - "issue_timestamp" - ] + "name": "changelog_objects", + "using": { + "foreign_key_constraint_on": { + "column": "control_id", + "table": { + "name": "changelog_object", + "schema": "public" + } + } } }, { - "role": "reviewer", - "permission": { - "check": {}, - "columns": [ - "data_issue_id", - "import_id", - "rule_id", - "description", - "object_name", - "object_type", - "object_uid", - "rule_uid", - "source", - "suspected_cause", - "issue_dev_id", - "issue_mgm_id", - "severity", - "user_id", - "issue_timestamp" - ] - } - } - ], - "select_permissions": [ - { - "role": "approver", - "permission": { - "columns": [ - "data_issue_id", - "description", - "import_id", - "issue_dev_id", - "issue_mgm_id", - "issue_timestamp", - "object_name", - "object_type", - "object_uid", - "rule_id", - "rule_uid", - "severity", - "source", - "suspected_cause", - "user_id" - ], - "filter": {}, - "allow_aggregations": true + "name": "changelog_owners", + "using": { + "foreign_key_constraint_on": { + "column": "control_id", + "table": { + "name": "changelog_owner", + "schema": "public" + } + } } }, { - "role": "auditor", - "permission": { - "columns": [ - "data_issue_id", - "description", - "import_id", - "issue_dev_id", - "issue_mgm_id", - "issue_timestamp", - "object_name", - "object_type", - "object_uid", - "rule_id", - "rule_uid", - "severity", - "source", - "suspected_cause", - "user_id" - ], - "filter": {}, - "allow_aggregations": true + "name": "changelog_rules", + "using": { + "foreign_key_constraint_on": { + "column": "control_id", + "table": { + "name": "changelog_rule", + "schema": "public" + } + } } }, { - "role": "fw-admin", - "permission": { - "columns": [ - "data_issue_id", - "description", - "import_id", - "issue_dev_id", - "issue_mgm_id", - "issue_timestamp", - "object_name", - "object_type", - "object_uid", - "rule_id", - "rule_uid", - "severity", - "source", - "suspected_cause", - "user_id" - ], - "filter": {}, - "allow_aggregations": true + "name": "changelog_services", + "using": { + "foreign_key_constraint_on": { + "column": "control_id", + "table": { + "name": "changelog_service", + "schema": "public" + } + } } }, { - "role": "implementer", - "permission": { - "columns": [ - "data_issue_id", - "description", - "import_id", - "issue_dev_id", - "issue_mgm_id", - "issue_timestamp", - "object_name", - "object_type", - "object_uid", - "rule_id", - "rule_uid", - "severity", - "source", - "suspected_cause", - "user_id" - ], - "filter": {}, - "allow_aggregations": true + "name": "changelog_users", + "using": { + "foreign_key_constraint_on": { + "column": "control_id", + "table": { + "name": "changelog_user", + "schema": "public" + } + } } }, { - "role": "importer", - "permission": { - "columns": [ - "data_issue_id", - "description", - "import_id", - "issue_dev_id", - "issue_mgm_id", - "issue_timestamp", - "object_name", - "object_type", - "object_uid", - "rule_id", - "rule_uid", - "severity", - "source", - "suspected_cause", - "user_id" - ], - "filter": {}, - "allow_aggregations": true + "name": "import_changelogs", + "using": { + "foreign_key_constraint_on": { + "column": "control_id", + "table": { + "name": "import_changelog", + "schema": "public" + } + } } }, { - "role": "middleware-server", - "permission": { - "columns": [ - "data_issue_id", - "description", - "import_id", - "issue_dev_id", - "issue_mgm_id", - "issue_timestamp", - "object_name", - "object_type", - "object_uid", - "rule_id", - "rule_uid", - "severity", - "source", - "suspected_cause", - "user_id" - ], - "filter": {}, - "allow_aggregations": true + "name": "import_configs", + "using": { + "foreign_key_constraint_on": { + "column": "import_id", + "table": { + "name": "import_config", + "schema": "public" + } + } } }, { - "role": "planner", - "permission": { - "columns": [ - "data_issue_id", - "description", - "import_id", - "issue_dev_id", - "issue_mgm_id", - "issue_timestamp", - "object_name", - "object_type", - "object_uid", - "rule_id", - "rule_uid", - "severity", - "source", - "suspected_cause", - "user_id" - ], - "filter": {}, - "allow_aggregations": true - } - }, - { - "role": "recertifier", - "permission": { - "columns": [ - "data_issue_id", - "description", - "import_id", - "issue_dev_id", - "issue_mgm_id", - "issue_timestamp", - "object_name", - "object_type", - "object_uid", - "rule_id", - "rule_uid", - "severity", - "source", - "suspected_cause", - "user_id" - ], - "filter": {}, - "allow_aggregations": true - } - }, - { - "role": "reporter", - "permission": { - "columns": [ - "data_issue_id", - "description", - "import_id", - "issue_dev_id", - "issue_mgm_id", - "issue_timestamp", - "object_name", - "object_type", - "object_uid", - "rule_id", - "rule_uid", - "severity", - "source", - "suspected_cause", - "user_id" - ], - "filter": {}, - "allow_aggregations": true - } - }, - { - "role": "reporter-viewall", - "permission": { - "columns": [ - "data_issue_id", - "description", - "import_id", - "issue_dev_id", - "issue_mgm_id", - "issue_timestamp", - "object_name", - "object_type", - "object_uid", - "rule_id", - "rule_uid", - "severity", - "source", - "suspected_cause", - "user_id" - ], - "filter": {}, - "allow_aggregations": true - } - }, - { - "role": "requester", - "permission": { - "columns": [ - "data_issue_id", - "description", - "import_id", - "issue_dev_id", - "issue_mgm_id", - "issue_timestamp", - "object_name", - "object_type", - "object_uid", - "rule_id", - "rule_uid", - "severity", - "source", - "suspected_cause", - "user_id" - ], - "filter": {}, - "allow_aggregations": true - } - }, - { - "role": "reviewer", - "permission": { - "columns": [ - "data_issue_id", - "description", - "import_id", - "issue_dev_id", - "issue_mgm_id", - "issue_timestamp", - "object_name", - "object_type", - "object_uid", - "rule_id", - "rule_uid", - "severity", - "source", - "suspected_cause", - "user_id" - ], - "filter": {}, - "allow_aggregations": true - } - } - ] - }, - { - "table": { - "name": "management", - "schema": "public" - }, - "object_relationships": [ - { - "name": "import_credential", - "using": { - "foreign_key_constraint_on": "import_credential_id" - } - }, - { - "name": "management", - "using": { - "foreign_key_constraint_on": "multi_device_manager_id" - } - }, - { - "name": "stm_dev_typ", + "name": "log_data_issues", "using": { - "foreign_key_constraint_on": "dev_typ_id" + "foreign_key_constraint_on": { + "column": "import_id", + "table": { + "name": "log_data_issue", + "schema": "public" + } + } } }, { - "name": "tenant", - "using": { - "foreign_key_constraint_on": "tenant_id" - } - } - ], - "array_relationships": [ - { - "name": "alerts", + "name": "objects", "using": { "foreign_key_constraint_on": { - "column": "alert_mgm_id", + "column": "obj_create", "table": { - "name": "alert", + "name": "object", "schema": "public" } } } }, { - "name": "changelog_objects", + "name": "objectsByObjLastSeen", "using": { "foreign_key_constraint_on": { - "column": "mgm_id", + "column": "obj_last_seen", "table": { - "name": "changelog_object", + "name": "object", "schema": "public" } } } }, { - "name": "changelog_rules", + "name": "objgrpFlatsByImportLastSeen", "using": { "foreign_key_constraint_on": { - "column": "mgm_id", + "column": "import_last_seen", "table": { - "name": "changelog_rule", + "name": "objgrp_flat", "schema": "public" } } } }, { - "name": "changelog_services", + "name": "objgrp_flats", "using": { "foreign_key_constraint_on": { - "column": "mgm_id", + "column": "import_created", "table": { - "name": "changelog_service", + "name": "objgrp_flat", "schema": "public" } } } }, { - "name": "changelog_users", + "name": "objgrps", "using": { "foreign_key_constraint_on": { - "column": "mgm_id", + "column": "import_created", "table": { - "name": "changelog_user", + "name": "objgrp", "schema": "public" } } } }, { - "name": "devices", + "name": "objgrpsByImportLastSeen", "using": { "foreign_key_constraint_on": { - "column": "mgm_id", + "column": "import_last_seen", "table": { - "name": "device", + "name": "objgrp", "schema": "public" } } } }, { - "name": "import_configs", + "name": "ruleEnforcedOnGatewaysByRemoved", "using": { "foreign_key_constraint_on": { - "column": "mgm_id", + "column": "removed", "table": { - "name": "import_config", + "name": "rule_enforced_on_gateway", "schema": "public" } } } }, { - "name": "import_controls", + "name": "ruleFromsByRfLastSeen", "using": { "foreign_key_constraint_on": { - "column": "mgm_id", + "column": "rf_last_seen", "table": { - "name": "import_control", + "name": "rule_from", "schema": "public" } } } }, { - "name": "import_full_configs", + "name": "ruleMetadataByRemoved", "using": { "foreign_key_constraint_on": { - "column": "mgm_id", + "column": "removed", "table": { - "name": "import_full_config", + "name": "rule_metadata", "schema": "public" } } } }, { - "name": "managementByMultiDeviceManagerId", + "name": "ruleNwobjResolvedsByRemoved", "using": { "foreign_key_constraint_on": { - "column": "multi_device_manager_id", + "column": "removed", "table": { - "name": "management", + "name": "rule_nwobj_resolved", "schema": "public" } } } }, { - "name": "objects", + "name": "ruleOwnersByRemoved", "using": { "foreign_key_constraint_on": { - "column": "mgm_id", + "column": "removed", "table": { - "name": "object", + "name": "rule_owner", "schema": "public" } } } }, { - "name": "rule_nwobj_resolveds", + "name": "ruleServicesByRsLastSeen", "using": { "foreign_key_constraint_on": { - "column": "mgm_id", + "column": "rs_last_seen", "table": { - "name": "rule_nwobj_resolved", + "name": "rule_service", "schema": "public" } } } }, { - "name": "rule_svc_resolveds", + "name": "ruleSvcResolvedsByRemoved", "using": { "foreign_key_constraint_on": { - "column": "mgm_id", + "column": "removed", "table": { "name": "rule_svc_resolved", "schema": "public" @@ -6064,1047 +7233,11261 @@ } }, { - "name": "rule_user_resolveds", + "name": "ruleTimesByRemoved", "using": { "foreign_key_constraint_on": { - "column": "mgm_id", + "column": "removed", "table": { - "name": "rule_user_resolved", + "name": "rule_time", "schema": "public" } } } }, { - "name": "rules", + "name": "ruleTosByRtLastSeen", "using": { "foreign_key_constraint_on": { - "column": "mgm_id", + "column": "rt_last_seen", "table": { - "name": "rule", + "name": "rule_to", "schema": "public" } } } }, { - "name": "services", + "name": "ruleUserResolvedsByRemoved", "using": { "foreign_key_constraint_on": { - "column": "mgm_id", + "column": "removed", "table": { - "name": "service", + "name": "rule_user_resolved", "schema": "public" } } } }, { - "name": "usrs", + "name": "rule_enforced_on_gateways", "using": { "foreign_key_constraint_on": { - "column": "mgm_id", + "column": "created", "table": { - "name": "usr", + "name": "rule_enforced_on_gateway", "schema": "public" } } } }, { - "name": "zones", + "name": "rule_froms", "using": { "foreign_key_constraint_on": { - "column": "mgm_id", + "column": "rf_create", "table": { - "name": "zone", + "name": "rule_from", "schema": "public" } } } - } - ], - "computed_fields": [ + }, { - "name": "filter_rule_nwobj_resolveds", - "definition": { - "function": { - "name": "filter_rule_nwobj_resolveds", - "schema": "public" + "name": "rule_metadata", + "using": { + "foreign_key_constraint_on": { + "column": "rule_created", + "table": { + "name": "rule_metadata", + "schema": "public" + } } } }, { - "name": "filter_rule_svc_resolveds", - "definition": { - "function": { - "name": "filter_rule_svc_resolveds", - "schema": "public" + "name": "rule_nwobj_resolveds", + "using": { + "foreign_key_constraint_on": { + "column": "created", + "table": { + "name": "rule_nwobj_resolved", + "schema": "public" + } } } }, { - "name": "filter_rule_user_resolveds", - "definition": { - "function": { - "name": "filter_rule_user_resolveds", - "schema": "public" + "name": "rule_owners", + "using": { + "foreign_key_constraint_on": { + "column": "created", + "table": { + "name": "rule_owner", + "schema": "public" + } } } - } - ], - "insert_permissions": [ + }, { - "role": "fw-admin", - "permission": { - "check": {}, - "columns": [ - "clearing_import_ran", - "do_not_import", - "force_initial_import", - "hide_in_gui", - "last_import_attempt_successful", - "config_path", - "domain_uid", - "importer_hostname", - "last_import_md5_complete_config", - "mgm_name", - "ssh_hostname", - "debug_level", - "dev_typ_id", - "import_credential_id", - "mgm_id", - "multi_device_manager_id", - "ssh_port", - "tenant_id", - "mgm_comment", - "last_import_attempt", - "mgm_create", - "mgm_update" - ] + "name": "rule_services", + "using": { + "foreign_key_constraint_on": { + "column": "rs_create", + "table": { + "name": "rule_service", + "schema": "public" + } + } } - } - ], - "select_permissions": [ + }, { - "role": "approver", - "permission": { - "columns": [ - "config_path", - "dev_typ_id", - "do_not_import", - "domain_uid", - "hide_in_gui", - "mgm_id", - "mgm_name", - "multi_device_manager_id", - "tenant_id" - ], - "filter": { - "mgm_id": { - "_in": "x-hasura-visible-managements" + "name": "rule_svc_resolveds", + "using": { + "foreign_key_constraint_on": { + "column": "created", + "table": { + "name": "rule_svc_resolved", + "schema": "public" } - }, - "allow_aggregations": true + } } }, { - "role": "auditor", - "permission": { - "columns": [ - "clearing_import_ran", - "do_not_import", - "force_initial_import", - "hide_in_gui", - "last_import_attempt_successful", - "cloud_subscription_id", - "cloud_tenant_id", - "config_path", - "domain_uid", - "importer_hostname", - "last_import_md5_complete_config", - "mgm_name", - "ssh_hostname", - "debug_level", - "dev_typ_id", - "import_credential_id", - "mgm_id", - "multi_device_manager_id", - "ssh_port", - "tenant_id", - "mgm_comment", - "last_import_attempt", - "mgm_create", - "mgm_update" - ], - "filter": {}, - "allow_aggregations": true + "name": "rule_times", + "using": { + "foreign_key_constraint_on": { + "column": "created", + "table": { + "name": "rule_time", + "schema": "public" + } + } } }, { - "role": "fw-admin", - "permission": { - "columns": [ - "clearing_import_ran", - "do_not_import", - "force_initial_import", - "hide_in_gui", - "last_import_attempt_successful", - "cloud_subscription_id", - "cloud_tenant_id", - "config_path", - "domain_uid", - "importer_hostname", - "last_import_md5_complete_config", - "mgm_name", - "ssh_hostname", - "debug_level", - "dev_typ_id", - "import_credential_id", - "mgm_id", - "multi_device_manager_id", - "ssh_port", - "tenant_id", - "mgm_comment", - "last_import_attempt", - "mgm_create", - "mgm_update" - ], - "filter": {}, - "allow_aggregations": true + "name": "rule_tos", + "using": { + "foreign_key_constraint_on": { + "column": "rt_create", + "table": { + "name": "rule_to", + "schema": "public" + } + } } }, { - "role": "implementer", - "permission": { - "columns": [ - "config_path", - "dev_typ_id", - "do_not_import", - "domain_uid", - "hide_in_gui", - "mgm_id", - "mgm_name", - "multi_device_manager_id", - "tenant_id" - ], - "filter": { - "mgm_id": { - "_in": "x-hasura-visible-managements" + "name": "rule_user_resolveds", + "using": { + "foreign_key_constraint_on": { + "column": "created", + "table": { + "name": "rule_user_resolved", + "schema": "public" } - }, - "allow_aggregations": true + } } }, { - "role": "importer", - "permission": { - "columns": [ - "clearing_import_ran", - "do_not_import", - "force_initial_import", - "hide_in_gui", - "last_import_attempt_successful", - "cloud_subscription_id", - "cloud_tenant_id", - "config_path", - "domain_uid", - "importer_hostname", - "last_import_md5_complete_config", - "mgm_name", - "ssh_hostname", - "debug_level", - "dev_typ_id", - "import_credential_id", - "mgm_id", - "multi_device_manager_id", - "ssh_port", - "tenant_id", - "mgm_comment", - "last_import_attempt", - "mgm_create", - "mgm_update" - ], - "filter": {}, - "allow_aggregations": true + "name": "rulebaseLinksByRemoved", + "using": { + "foreign_key_constraint_on": { + "column": "removed", + "table": { + "name": "rulebase_link", + "schema": "public" + } + } } }, { - "role": "middleware-server", - "permission": { - "columns": [ - "clearing_import_ran", - "do_not_import", - "force_initial_import", - "hide_in_gui", - "last_import_attempt_successful", - "cloud_subscription_id", - "cloud_tenant_id", - "config_path", - "domain_uid", - "importer_hostname", - "last_import_md5_complete_config", - "mgm_name", - "ssh_hostname", - "debug_level", - "dev_typ_id", - "import_credential_id", - "mgm_id", - "multi_device_manager_id", - "ssh_port", - "tenant_id", - "mgm_comment", - "last_import_attempt", - "mgm_create", - "mgm_update" - ], - "filter": {} + "name": "rulebase_links", + "using": { + "foreign_key_constraint_on": { + "column": "created", + "table": { + "name": "rulebase_link", + "schema": "public" + } + } } }, { - "role": "planner", - "permission": { - "columns": [ - "config_path", - "dev_typ_id", - "do_not_import", - "domain_uid", - "hide_in_gui", - "mgm_id", - "mgm_name", - "multi_device_manager_id", - "tenant_id" - ], - "filter": { - "mgm_id": { - "_in": "x-hasura-visible-managements" + "name": "rules", + "using": { + "foreign_key_constraint_on": { + "column": "rule_create", + "table": { + "name": "rule", + "schema": "public" } - }, - "allow_aggregations": true + } } }, { - "role": "recertifier", - "permission": { - "columns": [ - "clearing_import_ran", - "do_not_import", - "force_initial_import", - "hide_in_gui", - "last_import_attempt_successful", - "cloud_subscription_id", - "cloud_tenant_id", - "config_path", - "domain_uid", - "importer_hostname", - "last_import_md5_complete_config", - "mgm_name", - "ssh_hostname", - "debug_level", - "dev_typ_id", - "import_credential_id", - "mgm_id", - "multi_device_manager_id", - "ssh_port", - "tenant_id", - "mgm_comment", - "last_import_attempt", - "mgm_create", - "mgm_update" - ], - "filter": { - "mgm_id": { - "_in": "x-hasura-visible-managements" + "name": "rulesByRuleLastSeen", + "using": { + "foreign_key_constraint_on": { + "column": "rule_last_seen", + "table": { + "name": "rule", + "schema": "public" } - }, - "allow_aggregations": true + } } }, { - "role": "reporter", - "permission": { - "columns": [ - "config_path", - "dev_typ_id", - "do_not_import", - "hide_in_gui", - "mgm_id", - "mgm_name", - "multi_device_manager_id", - "tenant_id" - ], - "filter": { - "mgm_id": { - "_in": "x-hasura-visible-managements" + "name": "services", + "using": { + "foreign_key_constraint_on": { + "column": "svc_create", + "table": { + "name": "service", + "schema": "public" } - }, - "allow_aggregations": true + } } }, { - "role": "reporter-viewall", - "permission": { - "columns": [ - "config_path", - "dev_typ_id", - "do_not_import", - "domain_uid", - "hide_in_gui", - "mgm_id", - "mgm_name", - "multi_device_manager_id", - "tenant_id" - ], - "filter": {}, - "allow_aggregations": true + "name": "servicesBySvcLastSeen", + "using": { + "foreign_key_constraint_on": { + "column": "svc_last_seen", + "table": { + "name": "service", + "schema": "public" + } + } } }, { - "role": "requester", - "permission": { - "columns": [ - "config_path", - "dev_typ_id", - "domain_uid", - "hide_in_gui", - "mgm_id", - "mgm_name", - "multi_device_manager_id", - "tenant_id" - ], - "filter": { - "mgm_id": { - "_in": "x-hasura-visible-managements" + "name": "svcgrpFlatsByImportLastSeen", + "using": { + "foreign_key_constraint_on": { + "column": "import_last_seen", + "table": { + "name": "svcgrp_flat", + "schema": "public" } - }, - "allow_aggregations": true + } } }, { - "role": "reviewer", - "permission": { - "columns": [ - "config_path", - "dev_typ_id", - "do_not_import", - "domain_uid", - "hide_in_gui", - "mgm_id", - "mgm_name", - "multi_device_manager_id", - "tenant_id" - ], - "filter": { - "mgm_id": { - "_in": "x-hasura-visible-managements" + "name": "svcgrp_flats", + "using": { + "foreign_key_constraint_on": { + "column": "import_created", + "table": { + "name": "svcgrp_flat", + "schema": "public" } - }, - "allow_aggregations": true - } - } - ], - "update_permissions": [ - { - "role": "fw-admin", - "permission": { - "columns": [ - "clearing_import_ran", - "do_not_import", - "force_initial_import", - "hide_in_gui", - "last_import_attempt_successful", - "config_path", - "domain_uid", - "importer_hostname", - "last_import_md5_complete_config", - "mgm_name", - "ssh_hostname", - "debug_level", - "dev_typ_id", - "import_credential_id", - "mgm_id", - "multi_device_manager_id", - "ssh_port", - "tenant_id", - "mgm_comment", - "last_import_attempt", - "mgm_create", - "mgm_update" - ], - "filter": {}, - "check": {} + } } }, { - "role": "importer", - "permission": { - "columns": [ - "last_import_attempt", - "last_import_attempt_successful" - ], - "filter": {}, - "check": null - } - } - ] - }, - { - "table": { - "name": "nw_object_limits", - "schema": "public" - }, - "select_permissions": [ - { - "role": "auditor", - "permission": { - "columns": [ - "obj_id", - "first_ip", - "last_ip", - "mgm_id" - ], - "filter": {}, - "allow_aggregations": true - } - }, - { - "role": "fw-admin", - "permission": { - "columns": [ - "obj_id", - "first_ip", - "last_ip", - "mgm_id" - ], - "filter": {}, - "allow_aggregations": true - } - }, - { - "role": "recertifier", - "permission": { - "columns": [ - "obj_id", - "first_ip", - "last_ip", - "mgm_id" - ], - "filter": { - "mgm_id": { - "_in": "x-hasura-visible-managements" - } - }, - "allow_aggregations": true - } - }, - { - "role": "reporter", - "permission": { - "columns": [ - "obj_id", - "first_ip", - "last_ip", - "mgm_id" - ], - "filter": { - "mgm_id": { - "_in": "x-hasura-visible-managements" - } - }, - "allow_aggregations": true - } - }, - { - "role": "reporter-viewall", - "permission": { - "columns": [ - "obj_id", - "first_ip", - "last_ip", - "mgm_id" - ], - "filter": {}, - "allow_aggregations": true - } - } - ] - }, - { - "table": { - "name": "object", - "schema": "public" - }, - "object_relationships": [ - { - "name": "device", - "using": { - "foreign_key_constraint_on": "obj_nat_install" - } - }, - { - "name": "importControlByObjLastSeen", - "using": { - "foreign_key_constraint_on": "obj_last_seen" - } - }, - { - "name": "import_control", - "using": { - "foreign_key_constraint_on": "obj_create" - } - }, - { - "name": "management", - "using": { - "foreign_key_constraint_on": "mgm_id" - } - }, - { - "name": "stm_color", - "using": { - "foreign_key_constraint_on": "obj_color_id" - } - }, - { - "name": "stm_obj_typ", + "name": "svcgrps", "using": { - "foreign_key_constraint_on": "obj_typ_id" + "foreign_key_constraint_on": { + "column": "import_created", + "table": { + "name": "svcgrp", + "schema": "public" + } + } } }, { - "name": "uiuser", + "name": "svcgrpsByImportLastSeen", "using": { - "foreign_key_constraint_on": "last_change_admin" + "foreign_key_constraint_on": { + "column": "import_last_seen", + "table": { + "name": "svcgrp", + "schema": "public" + } + } } }, { - "name": "zone", - "using": { - "foreign_key_constraint_on": "zone_id" - } - } - ], - "array_relationships": [ - { - "name": "changelogObjectsByOldObjId", + "name": "timeObjectsByRemoved", "using": { "foreign_key_constraint_on": { - "column": "old_obj_id", + "column": "removed", "table": { - "name": "changelog_object", + "name": "time_object", "schema": "public" } } } }, { - "name": "changelog_objects", + "name": "time_objects", "using": { "foreign_key_constraint_on": { - "column": "new_obj_id", + "column": "created", "table": { - "name": "changelog_object", + "name": "time_object", "schema": "public" } } } }, { - "name": "elements", + "name": "usergrpFlatsByImportLastSeen", "using": { "foreign_key_constraint_on": { - "column": "network_object_id", + "column": "import_last_seen", "table": { - "name": "implelement", - "schema": "request" + "name": "usergrp_flat", + "schema": "public" } } } }, { - "name": "impltasks", + "name": "usergrp_flats", "using": { "foreign_key_constraint_on": { - "column": "nw_obj_grp_id", + "column": "import_created", "table": { - "name": "impltask", - "schema": "request" + "name": "usergrp_flat", + "schema": "public" } } } }, { - "name": "network_object_limits", + "name": "usergrps", "using": { - "manual_configuration": { - "column_mapping": { - "obj_id": "obj_id" - }, - "insertion_order": null, - "remote_table": { - "name": "nw_object_limits", + "foreign_key_constraint_on": { + "column": "import_created", + "table": { + "name": "usergrp", "schema": "public" } } } }, { - "name": "objgrpFlatsByObjgrpFlatMemberId", + "name": "usergrpsByImportLastSeen", "using": { "foreign_key_constraint_on": { - "column": "objgrp_flat_member_id", + "column": "import_last_seen", "table": { - "name": "objgrp_flat", + "name": "usergrp", "schema": "public" } } } }, { - "name": "objgrp_flats", + "name": "usrs", "using": { "foreign_key_constraint_on": { - "column": "objgrp_flat_id", + "column": "user_create", "table": { - "name": "objgrp_flat", + "name": "usr", "schema": "public" } } } }, { - "name": "objgrps", + "name": "usrsByUserLastSeen", "using": { "foreign_key_constraint_on": { - "column": "objgrp_id", + "column": "user_last_seen", "table": { - "name": "objgrp", + "name": "usr", "schema": "public" } } } }, { - "name": "objgrpsByObjgrpMemberId", + "name": "zones", "using": { "foreign_key_constraint_on": { - "column": "objgrp_member_id", + "column": "zone_create", "table": { - "name": "objgrp", + "name": "zone", "schema": "public" } } } }, { - "name": "reqelements", + "name": "zonesByZoneLastSeen", "using": { "foreign_key_constraint_on": { - "column": "network_object_id", + "column": "zone_last_seen", "table": { - "name": "reqelement", - "schema": "request" + "name": "zone", + "schema": "public" } } } + } + ], + "insert_permissions": [ + { + "role": "importer", + "permission": { + "check": {}, + "columns": [ + "changes_found", + "control_id", + "import_errors", + "import_type_id", + "is_initial_import", + "mgm_id", + "notification_done", + "policy_changes_found", + "rule_owner_mapping_done", + "security_relevant_changes_counter", + "start_time", + "stop_time", + "successful_import" + ] + }, + "comment": "" + }, + { + "role": "middleware-server", + "permission": { + "check": {}, + "columns": [ + "changes_found", + "control_id", + "import_errors", + "import_type_id", + "is_initial_import", + "mgm_id", + "notification_done", + "policy_changes_found", + "rule_owner_mapping_done", + "security_relevant_changes_counter", + "start_time", + "stop_time", + "successful_import" + ] + }, + "comment": "" + } + ], + "select_permissions": [ + { + "role": "auditor", + "permission": { + "columns": [ + "changes_found", + "control_id", + "import_errors", + "import_type_id", + "is_initial_import", + "mgm_id", + "notification_done", + "policy_changes_found", + "rule_owner_mapping_done", + "security_relevant_changes_counter", + "start_time", + "stop_time", + "successful_import" + ], + "filter": {}, + "allow_aggregations": true + }, + "comment": "" + }, + { + "role": "fw-admin", + "permission": { + "columns": [ + "changes_found", + "control_id", + "import_errors", + "import_type_id", + "is_initial_import", + "mgm_id", + "notification_done", + "policy_changes_found", + "rule_owner_mapping_done", + "security_relevant_changes_counter", + "start_time", + "stop_time", + "successful_import" + ], + "filter": {}, + "allow_aggregations": true + }, + "comment": "" + }, + { + "role": "importer", + "permission": { + "columns": [ + "changes_found", + "control_id", + "import_errors", + "import_type_id", + "is_initial_import", + "mgm_id", + "notification_done", + "policy_changes_found", + "rule_owner_mapping_done", + "security_relevant_changes_counter", + "start_time", + "stop_time", + "successful_import" + ], + "filter": {}, + "allow_aggregations": true + }, + "comment": "" + }, + { + "role": "middleware-server", + "permission": { + "columns": [ + "changes_found", + "control_id", + "import_errors", + "import_type_id", + "is_initial_import", + "mgm_id", + "notification_done", + "policy_changes_found", + "rule_owner_mapping_done", + "security_relevant_changes_counter", + "start_time", + "stop_time", + "successful_import" + ], + "filter": {}, + "allow_aggregations": true + }, + "comment": "" + }, + { + "role": "modeller", + "permission": { + "columns": [ + "changes_found", + "control_id", + "import_errors", + "import_type_id", + "is_initial_import", + "mgm_id", + "notification_done", + "policy_changes_found", + "rule_owner_mapping_done", + "security_relevant_changes_counter", + "start_time", + "stop_time", + "successful_import" + ], + "filter": { + "mgm_id": { + "_in": "x-hasura-visible-managements" + } + }, + "allow_aggregations": true + }, + "comment": "" + }, + { + "role": "recertifier", + "permission": { + "columns": [ + "changes_found", + "control_id", + "import_errors", + "import_type_id", + "is_initial_import", + "mgm_id", + "notification_done", + "policy_changes_found", + "rule_owner_mapping_done", + "security_relevant_changes_counter", + "start_time", + "stop_time", + "successful_import" + ], + "filter": { + "mgm_id": { + "_in": "x-hasura-visible-managements" + } + }, + "allow_aggregations": true + }, + "comment": "" + }, + { + "role": "reporter", + "permission": { + "columns": [ + "changes_found", + "control_id", + "import_errors", + "import_type_id", + "is_initial_import", + "mgm_id", + "notification_done", + "policy_changes_found", + "rule_owner_mapping_done", + "security_relevant_changes_counter", + "start_time", + "stop_time", + "successful_import" + ], + "filter": { + "mgm_id": { + "_in": "x-hasura-visible-managements" + } + }, + "allow_aggregations": true + }, + "comment": "" + }, + { + "role": "reporter-viewall", + "permission": { + "columns": [ + "changes_found", + "control_id", + "import_errors", + "import_type_id", + "is_initial_import", + "mgm_id", + "notification_done", + "policy_changes_found", + "rule_owner_mapping_done", + "security_relevant_changes_counter", + "start_time", + "stop_time", + "successful_import" + ], + "filter": {}, + "allow_aggregations": true + }, + "comment": "" + } + ], + "update_permissions": [ + { + "role": "importer", + "permission": { + "columns": [ + "changes_found", + "control_id", + "import_errors", + "import_type_id", + "is_initial_import", + "mgm_id", + "notification_done", + "policy_changes_found", + "rule_owner_mapping_done", + "security_relevant_changes_counter", + "start_time", + "stop_time", + "successful_import" + ], + "filter": {}, + "check": {} + }, + "comment": "" + }, + { + "role": "middleware-server", + "permission": { + "columns": [ + "notification_done", + "rule_owner_mapping_done", + "security_relevant_changes_counter", + "stop_time", + "successful_import" + ], + "filter": {}, + "check": {} + } + } + ], + "delete_permissions": [ + { + "role": "importer", + "permission": { + "filter": {} + } + } + ] + }, + { + "table": { + "name": "import_credential", + "schema": "public" + }, + "array_relationships": [ + { + "name": "management", + "using": { + "foreign_key_constraint_on": { + "column": "import_credential_id", + "table": { + "name": "management", + "schema": "public" + } + } + } + } + ], + "insert_permissions": [ + { + "role": "fw-admin", + "permission": { + "check": {}, + "columns": [ + "cloud_client_id", + "cloud_client_secret", + "credential_name", + "id", + "is_key_pair", + "public_key", + "secret", + "username" + ] + } + } + ], + "select_permissions": [ + { + "role": "auditor", + "permission": { + "columns": [ + "cloud_client_id", + "credential_name", + "id", + "is_key_pair", + "public_key", + "username" + ], + "filter": {}, + "allow_aggregations": true + } + }, + { + "role": "fw-admin", + "permission": { + "columns": [ + "cloud_client_id", + "cloud_client_secret", + "credential_name", + "id", + "is_key_pair", + "public_key", + "secret", + "username" + ], + "filter": {}, + "allow_aggregations": true + } + }, + { + "role": "importer", + "permission": { + "columns": [ + "is_key_pair", + "cloud_client_id", + "cloud_client_secret", + "credential_name", + "username", + "id", + "public_key", + "secret" + ], + "filter": {}, + "allow_aggregations": true + } + }, + { + "role": "middleware-server", + "permission": { + "columns": [ + "is_key_pair", + "cloud_client_id", + "cloud_client_secret", + "credential_name", + "username", + "id", + "public_key", + "secret" + ], + "filter": {}, + "allow_aggregations": true + } + } + ], + "update_permissions": [ + { + "role": "fw-admin", + "permission": { + "columns": [ + "cloud_client_id", + "cloud_client_secret", + "credential_name", + "id", + "is_key_pair", + "public_key", + "secret", + "username" + ], + "filter": {}, + "check": {} + } + } + ], + "delete_permissions": [ + { + "role": "fw-admin", + "permission": { + "filter": {} + } + } + ] + }, + { + "table": { + "name": "import_full_config", + "schema": "public" + }, + "object_relationships": [ + { + "name": "import_control", + "using": { + "foreign_key_constraint_on": "import_id" + } + }, + { + "name": "management", + "using": { + "foreign_key_constraint_on": "mgm_id" + } + } + ], + "insert_permissions": [ + { + "role": "importer", + "permission": { + "check": {}, + "columns": [ + "config", + "import_id", + "mgm_id" + ] + } + } + ], + "select_permissions": [ + { + "role": "importer", + "permission": { + "columns": [ + "import_id", + "mgm_id", + "config" + ], + "filter": {}, + "allow_aggregations": true + } + } + ], + "delete_permissions": [ + { + "role": "importer", + "permission": { + "filter": {} + } + } + ] + }, + { + "table": { + "name": "language", + "schema": "public" + }, + "array_relationships": [ + { + "name": "customtxts", + "using": { + "foreign_key_constraint_on": { + "column": "language", + "table": { + "name": "customtxt", + "schema": "public" + } + } + } + }, + { + "name": "txts", + "using": { + "foreign_key_constraint_on": { + "column": "language", + "table": { + "name": "txt", + "schema": "public" + } + } + } + }, + { + "name": "uiusers", + "using": { + "foreign_key_constraint_on": { + "column": "uiuser_language", + "table": { + "name": "uiuser", + "schema": "public" + } + } + } + } + ], + "select_permissions": [ + { + "role": "anonymous", + "permission": { + "columns": [ + "name", + "culture_info" + ], + "filter": {}, + "allow_aggregations": true + } + }, + { + "role": "approver", + "permission": { + "columns": [ + "culture_info", + "name" + ], + "filter": {} + } + }, + { + "role": "auditor", + "permission": { + "columns": [ + "culture_info", + "name" + ], + "filter": {} + } + }, + { + "role": "fw-admin", + "permission": { + "columns": [ + "culture_info", + "name" + ], + "filter": {} + } + }, + { + "role": "implementer", + "permission": { + "columns": [ + "culture_info", + "name" + ], + "filter": {} + } + }, + { + "role": "middleware-server", + "permission": { + "columns": [ + "culture_info", + "name" + ], + "filter": {} + } + }, + { + "role": "modeller", + "permission": { + "columns": [ + "culture_info", + "name" + ], + "filter": {} + }, + "comment": "" + }, + { + "role": "planner", + "permission": { + "columns": [ + "culture_info", + "name" + ], + "filter": {} + } + }, + { + "role": "recertifier", + "permission": { + "columns": [ + "culture_info", + "name" + ], + "filter": {} + } + }, + { + "role": "reporter", + "permission": { + "columns": [ + "culture_info", + "name" + ], + "filter": {} + } + }, + { + "role": "reporter-viewall", + "permission": { + "columns": [ + "name", + "culture_info" + ], + "filter": {} + } + }, + { + "role": "requester", + "permission": { + "columns": [ + "culture_info", + "name" + ], + "filter": {} + } + }, + { + "role": "reviewer", + "permission": { + "columns": [ + "culture_info", + "name" + ], + "filter": {} + } + } + ] + }, + { + "table": { + "name": "latest_config", + "schema": "public" + }, + "insert_permissions": [ + { + "role": "importer", + "permission": { + "check": {}, + "columns": [ + "import_id", + "mgm_id", + "config" + ] + }, + "comment": "" + } + ], + "select_permissions": [ + { + "role": "importer", + "permission": { + "columns": [ + "import_id", + "mgm_id", + "config" + ], + "filter": {}, + "allow_aggregations": true + }, + "comment": "" + } + ], + "delete_permissions": [ + { + "role": "importer", + "permission": { + "filter": {} + }, + "comment": "" + } + ] + }, + { + "table": { + "name": "ldap_connection", + "schema": "public" + }, + "object_relationships": [ + { + "name": "tenant", + "using": { + "foreign_key_constraint_on": "tenant_id" + } + } + ], + "array_relationships": [ + { + "name": "uiusers", + "using": { + "foreign_key_constraint_on": { + "column": "ldap_connection_id", + "table": { + "name": "uiuser", + "schema": "public" + } + } + } + } + ], + "insert_permissions": [ + { + "role": "middleware-server", + "permission": { + "check": {}, + "columns": [ + "active", + "ldap_connection_id", + "ldap_global_tenant_name", + "ldap_name", + "ldap_pattern_length", + "ldap_port", + "ldap_search_user", + "ldap_search_user_pwd", + "ldap_searchpath_for_groups", + "ldap_searchpath_for_roles", + "ldap_searchpath_for_users", + "ldap_server", + "ldap_tenant_level", + "ldap_tls", + "ldap_type", + "ldap_write_user", + "ldap_write_user_pwd", + "ldap_writepath_for_groups", + "tenant_id" + ] + } + } + ], + "select_permissions": [ + { + "role": "approver", + "permission": { + "columns": [ + "ldap_connection_id", + "ldap_tenant_level" + ], + "filter": {} + } + }, + { + "role": "auditor", + "permission": { + "columns": [ + "active", + "ldap_connection_id", + "ldap_global_tenant_name", + "ldap_name", + "ldap_pattern_length", + "ldap_port", + "ldap_search_user", + "ldap_search_user_pwd", + "ldap_searchpath_for_groups", + "ldap_searchpath_for_roles", + "ldap_searchpath_for_users", + "ldap_server", + "ldap_tenant_level", + "ldap_tls", + "ldap_type", + "ldap_write_user", + "ldap_write_user_pwd", + "ldap_writepath_for_groups", + "tenant_id" + ], + "filter": {} + } + }, + { + "role": "fw-admin", + "permission": { + "columns": [ + "ldap_connection_id", + "ldap_name", + "ldap_port", + "ldap_server", + "ldap_tenant_level", + "tenant_id" + ], + "filter": {} + } + }, + { + "role": "implementer", + "permission": { + "columns": [ + "ldap_connection_id", + "ldap_tenant_level" + ], + "filter": {} + } + }, + { + "role": "middleware-server", + "permission": { + "columns": [ + "active", + "ldap_connection_id", + "ldap_global_tenant_name", + "ldap_name", + "ldap_pattern_length", + "ldap_port", + "ldap_search_user", + "ldap_search_user_pwd", + "ldap_searchpath_for_groups", + "ldap_searchpath_for_roles", + "ldap_searchpath_for_users", + "ldap_server", + "ldap_tenant_level", + "ldap_tls", + "ldap_type", + "ldap_write_user", + "ldap_write_user_pwd", + "ldap_writepath_for_groups", + "tenant_id" + ], + "filter": {} + } + }, + { + "role": "modeller", + "permission": { + "columns": [ + "ldap_connection_id", + "ldap_name", + "ldap_port", + "ldap_server", + "ldap_tenant_level", + "tenant_id" + ], + "filter": {} + } + }, + { + "role": "planner", + "permission": { + "columns": [ + "ldap_connection_id", + "ldap_tenant_level" + ], + "filter": {} + } + }, + { + "role": "recertifier", + "permission": { + "columns": [ + "ldap_connection_id", + "ldap_tenant_level" + ], + "filter": {} + } + }, + { + "role": "reporter", + "permission": { + "columns": [ + "ldap_connection_id", + "ldap_tenant_level" + ], + "filter": {} + } + }, + { + "role": "reporter-viewall", + "permission": { + "columns": [ + "ldap_connection_id", + "ldap_tenant_level" + ], + "filter": {} + } + }, + { + "role": "requester", + "permission": { + "columns": [ + "ldap_connection_id", + "ldap_tenant_level" + ], + "filter": {} + } + }, + { + "role": "reviewer", + "permission": { + "columns": [ + "ldap_connection_id", + "ldap_tenant_level" + ], + "filter": {} + } + } + ], + "update_permissions": [ + { + "role": "middleware-server", + "permission": { + "columns": [ + "active", + "ldap_connection_id", + "ldap_global_tenant_name", + "ldap_name", + "ldap_pattern_length", + "ldap_port", + "ldap_search_user", + "ldap_search_user_pwd", + "ldap_searchpath_for_groups", + "ldap_searchpath_for_roles", + "ldap_searchpath_for_users", + "ldap_server", + "ldap_tenant_level", + "ldap_tls", + "ldap_type", + "ldap_write_user", + "ldap_write_user_pwd", + "ldap_writepath_for_groups", + "tenant_id" + ], + "filter": {}, + "check": null + } + } + ], + "delete_permissions": [ + { + "role": "middleware-server", + "permission": { + "filter": {} + } + } + ] + }, + { + "table": { + "name": "log_data_issue", + "schema": "public" + }, + "object_relationships": [ + { + "name": "import_control", + "using": { + "foreign_key_constraint_on": "import_id" + } + }, + { + "name": "uiuser", + "using": { + "foreign_key_constraint_on": "user_id" + } + } + ], + "array_relationships": [ + { + "name": "alerts", + "using": { + "foreign_key_constraint_on": { + "column": "ref_log_id", + "table": { + "name": "alert", + "schema": "public" + } + } + } + } + ], + "insert_permissions": [ + { + "role": "approver", + "permission": { + "check": {}, + "columns": [ + "data_issue_id", + "import_id", + "rule_id", + "description", + "object_name", + "object_type", + "object_uid", + "rule_uid", + "source", + "suspected_cause", + "issue_dev_id", + "issue_mgm_id", + "severity", + "user_id", + "issue_timestamp" + ] + } + }, + { + "role": "auditor", + "permission": { + "check": {}, + "columns": [ + "data_issue_id", + "import_id", + "rule_id", + "description", + "object_name", + "object_type", + "object_uid", + "rule_uid", + "source", + "suspected_cause", + "issue_dev_id", + "issue_mgm_id", + "severity", + "user_id", + "issue_timestamp" + ] + } + }, + { + "role": "fw-admin", + "permission": { + "check": {}, + "columns": [ + "data_issue_id", + "import_id", + "rule_id", + "description", + "object_name", + "object_type", + "object_uid", + "rule_uid", + "source", + "suspected_cause", + "issue_dev_id", + "issue_mgm_id", + "severity", + "user_id", + "issue_timestamp" + ] + } + }, + { + "role": "implementer", + "permission": { + "check": {}, + "columns": [ + "data_issue_id", + "import_id", + "rule_id", + "description", + "object_name", + "object_type", + "object_uid", + "rule_uid", + "source", + "suspected_cause", + "issue_dev_id", + "issue_mgm_id", + "severity", + "user_id", + "issue_timestamp" + ] + } + }, + { + "role": "importer", + "permission": { + "check": {}, + "columns": [ + "data_issue_id", + "description", + "import_id", + "issue_dev_id", + "issue_mgm_id", + "issue_timestamp", + "object_name", + "object_type", + "object_uid", + "rule_id", + "rule_uid", + "severity", + "source", + "suspected_cause", + "user_id" + ] + } + }, + { + "role": "middleware-server", + "permission": { + "check": {}, + "columns": [ + "data_issue_id", + "description", + "import_id", + "issue_dev_id", + "issue_mgm_id", + "issue_timestamp", + "object_name", + "object_type", + "object_uid", + "rule_id", + "rule_uid", + "severity", + "source", + "suspected_cause", + "user_id" + ] + } + }, + { + "role": "modeller", + "permission": { + "check": {}, + "columns": [ + "data_issue_id", + "import_id", + "rule_id", + "description", + "object_name", + "object_type", + "object_uid", + "rule_uid", + "source", + "suspected_cause", + "issue_dev_id", + "issue_mgm_id", + "severity", + "user_id", + "issue_timestamp" + ] + }, + "comment": "" + }, + { + "role": "planner", + "permission": { + "check": {}, + "columns": [ + "data_issue_id", + "import_id", + "rule_id", + "description", + "object_name", + "object_type", + "object_uid", + "rule_uid", + "source", + "suspected_cause", + "issue_dev_id", + "issue_mgm_id", + "severity", + "user_id", + "issue_timestamp" + ] + } + }, + { + "role": "recertifier", + "permission": { + "check": {}, + "columns": [ + "data_issue_id", + "import_id", + "rule_id", + "description", + "object_name", + "object_type", + "object_uid", + "rule_uid", + "source", + "suspected_cause", + "issue_dev_id", + "issue_mgm_id", + "severity", + "user_id", + "issue_timestamp" + ] + } + }, + { + "role": "reporter", + "permission": { + "check": {}, + "columns": [ + "data_issue_id", + "import_id", + "rule_id", + "description", + "object_name", + "object_type", + "object_uid", + "rule_uid", + "source", + "suspected_cause", + "issue_dev_id", + "issue_mgm_id", + "severity", + "user_id", + "issue_timestamp" + ] + } + }, + { + "role": "reporter-viewall", + "permission": { + "check": {}, + "columns": [ + "data_issue_id", + "import_id", + "rule_id", + "description", + "object_name", + "object_type", + "object_uid", + "rule_uid", + "source", + "suspected_cause", + "issue_dev_id", + "issue_mgm_id", + "severity", + "user_id", + "issue_timestamp" + ] + } + }, + { + "role": "requester", + "permission": { + "check": {}, + "columns": [ + "data_issue_id", + "import_id", + "rule_id", + "description", + "object_name", + "object_type", + "object_uid", + "rule_uid", + "source", + "suspected_cause", + "issue_dev_id", + "issue_mgm_id", + "severity", + "user_id", + "issue_timestamp" + ] + } + }, + { + "role": "reviewer", + "permission": { + "check": {}, + "columns": [ + "data_issue_id", + "import_id", + "rule_id", + "description", + "object_name", + "object_type", + "object_uid", + "rule_uid", + "source", + "suspected_cause", + "issue_dev_id", + "issue_mgm_id", + "severity", + "user_id", + "issue_timestamp" + ] + } + } + ], + "select_permissions": [ + { + "role": "approver", + "permission": { + "columns": [ + "data_issue_id", + "description", + "import_id", + "issue_dev_id", + "issue_mgm_id", + "issue_timestamp", + "object_name", + "object_type", + "object_uid", + "rule_id", + "rule_uid", + "severity", + "source", + "suspected_cause", + "user_id" + ], + "filter": {}, + "allow_aggregations": true + } + }, + { + "role": "auditor", + "permission": { + "columns": [ + "data_issue_id", + "description", + "import_id", + "issue_dev_id", + "issue_mgm_id", + "issue_timestamp", + "object_name", + "object_type", + "object_uid", + "rule_id", + "rule_uid", + "severity", + "source", + "suspected_cause", + "user_id" + ], + "filter": {}, + "allow_aggregations": true + } + }, + { + "role": "fw-admin", + "permission": { + "columns": [ + "data_issue_id", + "description", + "import_id", + "issue_dev_id", + "issue_mgm_id", + "issue_timestamp", + "object_name", + "object_type", + "object_uid", + "rule_id", + "rule_uid", + "severity", + "source", + "suspected_cause", + "user_id" + ], + "filter": {}, + "allow_aggregations": true + } + }, + { + "role": "implementer", + "permission": { + "columns": [ + "data_issue_id", + "description", + "import_id", + "issue_dev_id", + "issue_mgm_id", + "issue_timestamp", + "object_name", + "object_type", + "object_uid", + "rule_id", + "rule_uid", + "severity", + "source", + "suspected_cause", + "user_id" + ], + "filter": {}, + "allow_aggregations": true + } + }, + { + "role": "importer", + "permission": { + "columns": [ + "data_issue_id", + "description", + "import_id", + "issue_dev_id", + "issue_mgm_id", + "issue_timestamp", + "object_name", + "object_type", + "object_uid", + "rule_id", + "rule_uid", + "severity", + "source", + "suspected_cause", + "user_id" + ], + "filter": {}, + "allow_aggregations": true + } + }, + { + "role": "middleware-server", + "permission": { + "columns": [ + "data_issue_id", + "description", + "import_id", + "issue_dev_id", + "issue_mgm_id", + "issue_timestamp", + "object_name", + "object_type", + "object_uid", + "rule_id", + "rule_uid", + "severity", + "source", + "suspected_cause", + "user_id" + ], + "filter": {}, + "allow_aggregations": true + } + }, + { + "role": "modeller", + "permission": { + "columns": [ + "data_issue_id", + "import_id", + "rule_id", + "description", + "object_name", + "object_type", + "object_uid", + "rule_uid", + "source", + "suspected_cause", + "issue_dev_id", + "issue_mgm_id", + "severity", + "user_id", + "issue_timestamp" + ], + "filter": {} + }, + "comment": "" + }, + { + "role": "planner", + "permission": { + "columns": [ + "data_issue_id", + "description", + "import_id", + "issue_dev_id", + "issue_mgm_id", + "issue_timestamp", + "object_name", + "object_type", + "object_uid", + "rule_id", + "rule_uid", + "severity", + "source", + "suspected_cause", + "user_id" + ], + "filter": {}, + "allow_aggregations": true + } + }, + { + "role": "recertifier", + "permission": { + "columns": [ + "data_issue_id", + "description", + "import_id", + "issue_dev_id", + "issue_mgm_id", + "issue_timestamp", + "object_name", + "object_type", + "object_uid", + "rule_id", + "rule_uid", + "severity", + "source", + "suspected_cause", + "user_id" + ], + "filter": {}, + "allow_aggregations": true + } + }, + { + "role": "reporter", + "permission": { + "columns": [ + "data_issue_id", + "description", + "import_id", + "issue_dev_id", + "issue_mgm_id", + "issue_timestamp", + "object_name", + "object_type", + "object_uid", + "rule_id", + "rule_uid", + "severity", + "source", + "suspected_cause", + "user_id" + ], + "filter": {}, + "allow_aggregations": true + } + }, + { + "role": "reporter-viewall", + "permission": { + "columns": [ + "data_issue_id", + "description", + "import_id", + "issue_dev_id", + "issue_mgm_id", + "issue_timestamp", + "object_name", + "object_type", + "object_uid", + "rule_id", + "rule_uid", + "severity", + "source", + "suspected_cause", + "user_id" + ], + "filter": {}, + "allow_aggregations": true + } + }, + { + "role": "requester", + "permission": { + "columns": [ + "data_issue_id", + "description", + "import_id", + "issue_dev_id", + "issue_mgm_id", + "issue_timestamp", + "object_name", + "object_type", + "object_uid", + "rule_id", + "rule_uid", + "severity", + "source", + "suspected_cause", + "user_id" + ], + "filter": {}, + "allow_aggregations": true + } + }, + { + "role": "reviewer", + "permission": { + "columns": [ + "data_issue_id", + "description", + "import_id", + "issue_dev_id", + "issue_mgm_id", + "issue_timestamp", + "object_name", + "object_type", + "object_uid", + "rule_id", + "rule_uid", + "severity", + "source", + "suspected_cause", + "user_id" + ], + "filter": {}, + "allow_aggregations": true + } + } + ] + }, + { + "table": { + "name": "management", + "schema": "public" + }, + "object_relationships": [ + { + "name": "import_credential", + "using": { + "foreign_key_constraint_on": "import_credential_id" + } + }, + { + "name": "management", + "using": { + "foreign_key_constraint_on": "multi_device_manager_id" + } + }, + { + "name": "stm_dev_typ", + "using": { + "foreign_key_constraint_on": "dev_typ_id" + } + } + ], + "array_relationships": [ + { + "name": "alerts", + "using": { + "foreign_key_constraint_on": { + "column": "alert_mgm_id", + "table": { + "name": "alert", + "schema": "public" + } + } + } + }, + { + "name": "changelog_objects", + "using": { + "foreign_key_constraint_on": { + "column": "mgm_id", + "table": { + "name": "changelog_object", + "schema": "public" + } + } + } + }, + { + "name": "changelog_rules", + "using": { + "foreign_key_constraint_on": { + "column": "mgm_id", + "table": { + "name": "changelog_rule", + "schema": "public" + } + } + } + }, + { + "name": "changelog_services", + "using": { + "foreign_key_constraint_on": { + "column": "mgm_id", + "table": { + "name": "changelog_service", + "schema": "public" + } + } + } + }, + { + "name": "changelog_users", + "using": { + "foreign_key_constraint_on": { + "column": "mgm_id", + "table": { + "name": "changelog_user", + "schema": "public" + } + } + } + }, + { + "name": "devices", + "using": { + "foreign_key_constraint_on": { + "column": "mgm_id", + "table": { + "name": "device", + "schema": "public" + } + } + } + }, + { + "name": "import_configs", + "using": { + "foreign_key_constraint_on": { + "column": "mgm_id", + "table": { + "name": "import_config", + "schema": "public" + } + } + } + }, + { + "name": "import_controls", + "using": { + "foreign_key_constraint_on": { + "column": "mgm_id", + "table": { + "name": "import_control", + "schema": "public" + } + } + } + }, + { + "name": "import_full_configs", + "using": { + "foreign_key_constraint_on": { + "column": "mgm_id", + "table": { + "name": "import_full_config", + "schema": "public" + } + } + } + }, + { + "name": "managementByMultiDeviceManagerId", + "using": { + "foreign_key_constraint_on": { + "column": "multi_device_manager_id", + "table": { + "name": "management", + "schema": "public" + } + } + } + }, + { + "name": "objects", + "using": { + "foreign_key_constraint_on": { + "column": "mgm_id", + "table": { + "name": "object", + "schema": "public" + } + } + } + }, + { + "name": "reqtasks", + "using": { + "foreign_key_constraint_on": { + "column": "mgm_id", + "table": { + "name": "reqtask", + "schema": "request" + } + } + } + }, + { + "name": "rule_metadata", + "using": { + "foreign_key_constraint_on": { + "column": "mgm_id", + "table": { + "name": "rule_metadata", + "schema": "public" + } + } + } + }, + { + "name": "rule_nwobj_resolveds", + "using": { + "foreign_key_constraint_on": { + "column": "mgm_id", + "table": { + "name": "rule_nwobj_resolved", + "schema": "public" + } + } + } + }, + { + "name": "rule_svc_resolveds", + "using": { + "foreign_key_constraint_on": { + "column": "mgm_id", + "table": { + "name": "rule_svc_resolved", + "schema": "public" + } + } + } + }, + { + "name": "rule_user_resolveds", + "using": { + "foreign_key_constraint_on": { + "column": "mgm_id", + "table": { + "name": "rule_user_resolved", + "schema": "public" + } + } + } + }, + { + "name": "rulebases", + "using": { + "foreign_key_constraint_on": { + "column": "mgm_id", + "table": { + "name": "rulebase", + "schema": "public" + } + } + } + }, + { + "name": "rules", + "using": { + "foreign_key_constraint_on": { + "column": "mgm_id", + "table": { + "name": "rule", + "schema": "public" + } + } + } + }, + { + "name": "services", + "using": { + "foreign_key_constraint_on": { + "column": "mgm_id", + "table": { + "name": "service", + "schema": "public" + } + } + } + }, + { + "name": "tenant_to_managements", + "using": { + "foreign_key_constraint_on": { + "column": "management_id", + "table": { + "name": "tenant_to_management", + "schema": "public" + } + } + } + }, + { + "name": "time_objects", + "using": { + "foreign_key_constraint_on": { + "column": "mgm_id", + "table": { + "name": "time_object", + "schema": "public" + } + } + } + }, + { + "name": "usrs", + "using": { + "foreign_key_constraint_on": { + "column": "mgm_id", + "table": { + "name": "usr", + "schema": "public" + } + } + } + }, + { + "name": "zones", + "using": { + "foreign_key_constraint_on": { + "column": "mgm_id", + "table": { + "name": "zone", + "schema": "public" + } + } + } + } + ], + "computed_fields": [ + { + "name": "filter_rule_nwobj_resolveds", + "definition": { + "function": { + "name": "filter_rule_nwobj_resolveds", + "schema": "public" + } + } + }, + { + "name": "filter_rule_svc_resolveds", + "definition": { + "function": { + "name": "filter_rule_svc_resolveds", + "schema": "public" + } + } + }, + { + "name": "filter_rule_user_resolveds", + "definition": { + "function": { + "name": "filter_rule_user_resolveds", + "schema": "public" + } + } + }, + { + "name": "get_objects_for_tenant", + "definition": { + "function": { + "name": "get_objects_for_tenant", + "schema": "public" + }, + "session_argument": "hasura_session" + } + } + ], + "insert_permissions": [ + { + "role": "fw-admin", + "permission": { + "check": {}, + "columns": [ + "clearing_import_ran", + "cloud_subscription_id", + "cloud_tenant_id", + "config_path", + "debug_level", + "dev_typ_id", + "do_not_import", + "domain_uid", + "ext_mgm_data", + "force_initial_import", + "hide_in_gui", + "import_credential_id", + "importer_hostname", + "last_import_attempt", + "last_import_attempt_successful", + "last_import_md5_complete_config", + "mgm_comment", + "mgm_create", + "mgm_id", + "mgm_name", + "mgm_update", + "multi_device_manager_id", + "ssh_hostname", + "ssh_port" + ] + }, + "comment": "" + } + ], + "select_permissions": [ + { + "role": "approver", + "permission": { + "columns": [ + "config_path", + "dev_typ_id", + "do_not_import", + "domain_uid", + "ext_mgm_data", + "hide_in_gui", + "is_super_manager", + "mgm_id", + "mgm_name", + "mgm_uid", + "multi_device_manager_id" + ], + "filter": { + "mgm_id": { + "_in": "x-hasura-visible-managements" + } + }, + "allow_aggregations": true + } + }, + { + "role": "auditor", + "permission": { + "columns": [ + "clearing_import_ran", + "do_not_import", + "force_initial_import", + "hide_in_gui", + "is_super_manager", + "last_import_attempt_successful", + "cloud_subscription_id", + "cloud_tenant_id", + "config_path", + "domain_uid", + "ext_mgm_data", + "importer_hostname", + "last_import_md5_complete_config", + "mgm_name", + "mgm_uid", + "rulebase_name", + "rulebase_uid", + "ssh_hostname", + "debug_level", + "dev_typ_id", + "import_credential_id", + "mgm_id", + "multi_device_manager_id", + "ssh_port", + "mgm_comment", + "last_import_attempt", + "mgm_create", + "mgm_update" + ], + "filter": {}, + "allow_aggregations": true + } + }, + { + "role": "fw-admin", + "permission": { + "columns": [ + "clearing_import_ran", + "do_not_import", + "force_initial_import", + "hide_in_gui", + "is_super_manager", + "last_import_attempt_successful", + "cloud_subscription_id", + "cloud_tenant_id", + "config_path", + "domain_uid", + "ext_mgm_data", + "importer_hostname", + "last_import_md5_complete_config", + "mgm_name", + "mgm_uid", + "rulebase_name", + "rulebase_uid", + "ssh_hostname", + "debug_level", + "dev_typ_id", + "import_credential_id", + "mgm_id", + "multi_device_manager_id", + "ssh_port", + "mgm_comment", + "last_import_attempt", + "mgm_create", + "mgm_update" + ], + "filter": {}, + "allow_aggregations": true + } + }, + { + "role": "implementer", + "permission": { + "columns": [ + "config_path", + "dev_typ_id", + "do_not_import", + "domain_uid", + "ext_mgm_data", + "hide_in_gui", + "is_super_manager", + "mgm_id", + "mgm_name", + "mgm_uid", + "multi_device_manager_id" + ], + "filter": { + "mgm_id": { + "_in": "x-hasura-visible-managements" + } + }, + "allow_aggregations": true + } + }, + { + "role": "importer", + "permission": { + "columns": [ + "clearing_import_ran", + "do_not_import", + "force_initial_import", + "hide_in_gui", + "is_super_manager", + "last_import_attempt_successful", + "cloud_subscription_id", + "cloud_tenant_id", + "config_path", + "domain_uid", + "ext_mgm_data", + "importer_hostname", + "last_import_md5_complete_config", + "mgm_name", + "mgm_uid", + "rulebase_name", + "rulebase_uid", + "ssh_hostname", + "debug_level", + "dev_typ_id", + "import_credential_id", + "mgm_id", + "multi_device_manager_id", + "ssh_port", + "mgm_comment", + "last_import_attempt", + "mgm_create", + "mgm_update" + ], + "filter": {}, + "allow_aggregations": true + } + }, + { + "role": "middleware-server", + "permission": { + "columns": [ + "clearing_import_ran", + "do_not_import", + "force_initial_import", + "hide_in_gui", + "is_super_manager", + "last_import_attempt_successful", + "cloud_subscription_id", + "cloud_tenant_id", + "config_path", + "domain_uid", + "ext_mgm_data", + "importer_hostname", + "last_import_md5_complete_config", + "mgm_name", + "mgm_uid", + "rulebase_name", + "rulebase_uid", + "ssh_hostname", + "debug_level", + "dev_typ_id", + "import_credential_id", + "mgm_id", + "multi_device_manager_id", + "ssh_port", + "mgm_comment", + "last_import_attempt", + "mgm_create", + "mgm_update" + ], + "filter": {}, + "allow_aggregations": true + } + }, + { + "role": "modeller", + "permission": { + "columns": [ + "config_path", + "dev_typ_id", + "do_not_import", + "domain_uid", + "ext_mgm_data", + "hide_in_gui", + "is_super_manager", + "mgm_id", + "mgm_name", + "mgm_uid", + "multi_device_manager_id" + ], + "filter": { + "mgm_id": { + "_in": "x-hasura-visible-managements" + } + }, + "allow_aggregations": true + } + }, + { + "role": "planner", + "permission": { + "columns": [ + "config_path", + "dev_typ_id", + "do_not_import", + "domain_uid", + "ext_mgm_data", + "hide_in_gui", + "is_super_manager", + "mgm_id", + "mgm_name", + "mgm_uid", + "multi_device_manager_id" + ], + "filter": { + "mgm_id": { + "_in": "x-hasura-visible-managements" + } + }, + "allow_aggregations": true + } + }, + { + "role": "recertifier", + "permission": { + "columns": [ + "clearing_import_ran", + "do_not_import", + "force_initial_import", + "hide_in_gui", + "is_super_manager", + "last_import_attempt_successful", + "cloud_subscription_id", + "cloud_tenant_id", + "config_path", + "domain_uid", + "ext_mgm_data", + "importer_hostname", + "last_import_md5_complete_config", + "mgm_name", + "mgm_uid", + "rulebase_name", + "rulebase_uid", + "ssh_hostname", + "debug_level", + "dev_typ_id", + "import_credential_id", + "mgm_id", + "multi_device_manager_id", + "ssh_port", + "mgm_comment", + "last_import_attempt", + "mgm_create", + "mgm_update" + ], + "filter": { + "mgm_id": { + "_in": "x-hasura-visible-managements" + } + }, + "allow_aggregations": true + } + }, + { + "role": "reporter", + "permission": { + "columns": [ + "config_path", + "dev_typ_id", + "do_not_import", + "ext_mgm_data", + "hide_in_gui", + "is_super_manager", + "mgm_id", + "mgm_name", + "mgm_uid", + "multi_device_manager_id", + "rulebase_name", + "rulebase_uid" + ], + "filter": { + "mgm_id": { + "_in": "x-hasura-visible-managements" + } + }, + "allow_aggregations": true + } + }, + { + "role": "reporter-viewall", + "permission": { + "columns": [ + "config_path", + "dev_typ_id", + "do_not_import", + "domain_uid", + "ext_mgm_data", + "hide_in_gui", + "is_super_manager", + "mgm_id", + "mgm_name", + "mgm_uid", + "multi_device_manager_id" + ], + "filter": {}, + "allow_aggregations": true + } + }, + { + "role": "requester", + "permission": { + "columns": [ + "config_path", + "dev_typ_id", + "domain_uid", + "ext_mgm_data", + "hide_in_gui", + "is_super_manager", + "mgm_id", + "mgm_name", + "mgm_uid", + "multi_device_manager_id" + ], + "filter": { + "mgm_id": { + "_in": "x-hasura-visible-managements" + } + }, + "allow_aggregations": true + } + }, + { + "role": "reviewer", + "permission": { + "columns": [ + "config_path", + "dev_typ_id", + "do_not_import", + "domain_uid", + "ext_mgm_data", + "hide_in_gui", + "is_super_manager", + "mgm_id", + "mgm_name", + "mgm_uid", + "multi_device_manager_id" + ], + "filter": { + "mgm_id": { + "_in": "x-hasura-visible-managements" + } + }, + "allow_aggregations": true + } + } + ], + "update_permissions": [ + { + "role": "fw-admin", + "permission": { + "columns": [ + "clearing_import_ran", + "do_not_import", + "force_initial_import", + "hide_in_gui", + "is_super_manager", + "last_import_attempt_successful", + "cloud_subscription_id", + "cloud_tenant_id", + "config_path", + "domain_uid", + "ext_mgm_data", + "importer_hostname", + "last_import_md5_complete_config", + "mgm_name", + "mgm_uid", + "rulebase_name", + "rulebase_uid", + "ssh_hostname", + "debug_level", + "dev_typ_id", + "import_credential_id", + "mgm_id", + "multi_device_manager_id", + "ssh_port", + "mgm_comment", + "last_import_attempt", + "mgm_create", + "mgm_update" + ], + "filter": {}, + "check": {} + }, + "comment": "" + }, + { + "role": "importer", + "permission": { + "columns": [ + "last_import_attempt", + "last_import_attempt_successful" + ], + "filter": {}, + "check": null + } + } + ] + }, + { + "table": { + "name": "notification", + "schema": "public" + }, + "object_relationships": [ + { + "name": "owner", + "using": { + "foreign_key_constraint_on": "owner_id" + } + }, + { + "name": "report_schedule", + "using": { + "foreign_key_constraint_on": "schedule_id" + } + }, + { + "name": "uiuser", + "using": { + "foreign_key_constraint_on": "user_id" + } + } + ], + "insert_permissions": [ + { + "role": "auditor", + "permission": { + "check": { + "_and": [ + { + "notification_client": { + "_eq": "Report" + } + }, + { + "_or": [ + { + "user_id": { + "_eq": "X-Hasura-User-Id" + } + }, + { + "user_id": { + "_is_null": true + } + } + ] + } + ] + }, + "columns": [ + "bundle_id", + "bundle_type", + "channel", + "deadline", + "email_address_cc", + "email_address_to", + "email_body", + "email_subject", + "layout", + "name", + "notification_client", + "recipient_cc", + "recipient_to", + "id", + "initial_offset_after_deadline", + "interval_before_deadline", + "offset_before_deadline", + "owner_id", + "repeat_interval_after_deadline", + "repeat_offset_after_deadline", + "repetitions_after_deadline", + "schedule_id", + "user_id", + "last_sent" + ] + }, + "comment": "" + }, + { + "role": "fw-admin", + "permission": { + "check": {}, + "columns": [ + "bundle_id", + "bundle_type", + "channel", + "deadline", + "email_address_cc", + "email_address_to", + "email_body", + "email_subject", + "layout", + "name", + "notification_client", + "recipient_cc", + "recipient_to", + "id", + "initial_offset_after_deadline", + "interval_before_deadline", + "offset_before_deadline", + "owner_id", + "repeat_interval_after_deadline", + "repeat_offset_after_deadline", + "repetitions_after_deadline", + "schedule_id", + "user_id", + "last_sent" + ] + }, + "comment": "" + }, + { + "role": "modeller", + "permission": { + "check": {}, + "columns": [ + "bundle_id", + "bundle_type", + "channel", + "deadline", + "email_address_cc", + "email_address_to", + "email_body", + "email_subject", + "layout", + "name", + "notification_client", + "recipient_cc", + "recipient_to", + "id", + "initial_offset_after_deadline", + "interval_before_deadline", + "offset_before_deadline", + "owner_id", + "repeat_interval_after_deadline", + "repeat_offset_after_deadline", + "repetitions_after_deadline", + "schedule_id", + "user_id", + "last_sent" + ] + }, + "comment": "" + }, + { + "role": "recertifier", + "permission": { + "check": {}, + "columns": [ + "bundle_id", + "bundle_type", + "channel", + "deadline", + "email_address_cc", + "email_address_to", + "email_body", + "email_subject", + "layout", + "name", + "notification_client", + "recipient_cc", + "recipient_to", + "id", + "initial_offset_after_deadline", + "interval_before_deadline", + "offset_before_deadline", + "owner_id", + "repeat_interval_after_deadline", + "repeat_offset_after_deadline", + "repetitions_after_deadline", + "schedule_id", + "user_id", + "last_sent" + ] + }, + "comment": "" + }, + { + "role": "reporter", + "permission": { + "check": {}, + "columns": [ + "bundle_id", + "bundle_type", + "channel", + "deadline", + "email_address_cc", + "email_address_to", + "email_body", + "email_subject", + "layout", + "name", + "notification_client", + "recipient_cc", + "recipient_to", + "id", + "initial_offset_after_deadline", + "interval_before_deadline", + "offset_before_deadline", + "owner_id", + "repeat_interval_after_deadline", + "repeat_offset_after_deadline", + "repetitions_after_deadline", + "schedule_id", + "user_id", + "last_sent" + ] + }, + "comment": "" + }, + { + "role": "reporter-viewall", + "permission": { + "check": {}, + "columns": [ + "bundle_id", + "bundle_type", + "channel", + "deadline", + "email_address_cc", + "email_address_to", + "email_body", + "email_subject", + "layout", + "name", + "notification_client", + "recipient_cc", + "recipient_to", + "id", + "initial_offset_after_deadline", + "interval_before_deadline", + "offset_before_deadline", + "owner_id", + "repeat_interval_after_deadline", + "repeat_offset_after_deadline", + "repetitions_after_deadline", + "schedule_id", + "user_id", + "last_sent" + ] + }, + "comment": "" + } + ], + "select_permissions": [ + { + "role": "auditor", + "permission": { + "columns": [ + "bundle_id", + "bundle_type", + "channel", + "deadline", + "email_address_cc", + "email_address_to", + "email_body", + "email_subject", + "layout", + "name", + "notification_client", + "recipient_cc", + "recipient_to", + "id", + "initial_offset_after_deadline", + "interval_before_deadline", + "offset_before_deadline", + "owner_id", + "repeat_interval_after_deadline", + "repeat_offset_after_deadline", + "repetitions_after_deadline", + "schedule_id", + "user_id", + "last_sent" + ], + "filter": {} + }, + "comment": "" + }, + { + "role": "fw-admin", + "permission": { + "columns": [ + "bundle_id", + "bundle_type", + "channel", + "deadline", + "email_address_cc", + "email_address_to", + "email_body", + "email_subject", + "layout", + "name", + "notification_client", + "recipient_cc", + "recipient_to", + "id", + "initial_offset_after_deadline", + "interval_before_deadline", + "offset_before_deadline", + "owner_id", + "repeat_interval_after_deadline", + "repeat_offset_after_deadline", + "repetitions_after_deadline", + "schedule_id", + "user_id", + "last_sent" + ], + "filter": { + "_or": [ + { + "user_id": { + "_eq": "X-Hasura-User-Id" + } + }, + { + "user_id": { + "_is_null": true + } + } + ] + } + }, + "comment": "" + }, + { + "role": "middleware-server", + "permission": { + "columns": [ + "bundle_id", + "bundle_type", + "channel", + "deadline", + "email_address_cc", + "email_address_to", + "email_body", + "email_subject", + "layout", + "name", + "notification_client", + "recipient_cc", + "recipient_to", + "id", + "initial_offset_after_deadline", + "interval_before_deadline", + "offset_before_deadline", + "owner_id", + "repeat_interval_after_deadline", + "repeat_offset_after_deadline", + "repetitions_after_deadline", + "schedule_id", + "user_id", + "last_sent" + ], + "filter": {} + }, + "comment": "" + }, + { + "role": "modeller", + "permission": { + "columns": [ + "bundle_id", + "bundle_type", + "channel", + "deadline", + "email_address_cc", + "email_address_to", + "email_body", + "email_subject", + "layout", + "name", + "notification_client", + "recipient_cc", + "recipient_to", + "id", + "initial_offset_after_deadline", + "interval_before_deadline", + "offset_before_deadline", + "owner_id", + "repeat_interval_after_deadline", + "repeat_offset_after_deadline", + "repetitions_after_deadline", + "schedule_id", + "user_id", + "last_sent" + ], + "filter": { + "_or": [ + { + "user_id": { + "_eq": "X-Hasura-User-Id" + } + }, + { + "user_id": { + "_is_null": true + } + } + ] + } + }, + "comment": "" + }, + { + "role": "recertifier", + "permission": { + "columns": [ + "bundle_id", + "bundle_type", + "channel", + "deadline", + "email_address_cc", + "email_address_to", + "email_body", + "email_subject", + "layout", + "name", + "notification_client", + "recipient_cc", + "recipient_to", + "id", + "initial_offset_after_deadline", + "interval_before_deadline", + "offset_before_deadline", + "owner_id", + "repeat_interval_after_deadline", + "repeat_offset_after_deadline", + "repetitions_after_deadline", + "schedule_id", + "user_id", + "last_sent" + ], + "filter": { + "_or": [ + { + "user_id": { + "_eq": "X-Hasura-User-Id" + } + }, + { + "user_id": { + "_is_null": true + } + } + ] + } + }, + "comment": "" + }, + { + "role": "reporter", + "permission": { + "columns": [ + "bundle_id", + "bundle_type", + "channel", + "deadline", + "email_address_cc", + "email_address_to", + "email_body", + "email_subject", + "layout", + "name", + "notification_client", + "recipient_cc", + "recipient_to", + "id", + "initial_offset_after_deadline", + "interval_before_deadline", + "offset_before_deadline", + "owner_id", + "repeat_interval_after_deadline", + "repeat_offset_after_deadline", + "repetitions_after_deadline", + "schedule_id", + "user_id", + "last_sent" + ], + "filter": { + "_or": [ + { + "user_id": { + "_eq": "X-Hasura-User-Id" + } + }, + { + "user_id": { + "_is_null": true + } + } + ] + } + }, + "comment": "" + }, + { + "role": "reporter-viewall", + "permission": { + "columns": [ + "bundle_id", + "bundle_type", + "channel", + "deadline", + "email_address_cc", + "email_address_to", + "email_body", + "email_subject", + "layout", + "name", + "notification_client", + "recipient_cc", + "recipient_to", + "id", + "initial_offset_after_deadline", + "interval_before_deadline", + "offset_before_deadline", + "owner_id", + "repeat_interval_after_deadline", + "repeat_offset_after_deadline", + "repetitions_after_deadline", + "schedule_id", + "user_id", + "last_sent" + ], + "filter": { + "_or": [ + { + "user_id": { + "_eq": "X-Hasura-User-Id" + } + }, + { + "user_id": { + "_is_null": true + } + } + ] + } + }, + "comment": "" + } + ], + "update_permissions": [ + { + "role": "auditor", + "permission": { + "columns": [ + "bundle_id", + "bundle_type", + "channel", + "deadline", + "email_address_cc", + "email_address_to", + "email_body", + "email_subject", + "layout", + "name", + "notification_client", + "recipient_cc", + "recipient_to", + "id", + "initial_offset_after_deadline", + "interval_before_deadline", + "offset_before_deadline", + "owner_id", + "repeat_interval_after_deadline", + "repeat_offset_after_deadline", + "repetitions_after_deadline", + "schedule_id", + "user_id", + "last_sent" + ], + "filter": { + "_and": [ + { + "notification_client": { + "_eq": "Report" + } + }, + { + "_or": [ + { + "user_id": { + "_eq": "X-Hasura-User-Id" + } + }, + { + "user_id": { + "_is_null": true + } + } + ] + } + ] + }, + "check": { + "_and": [ + { + "notification_client": { + "_eq": "Report" + } + }, + { + "_or": [ + { + "user_id": { + "_eq": "X-Hasura-User-Id" + } + }, + { + "user_id": { + "_is_null": true + } + } + ] + } + ] + } + }, + "comment": "" + }, + { + "role": "fw-admin", + "permission": { + "columns": [ + "bundle_id", + "bundle_type", + "channel", + "deadline", + "email_address_cc", + "email_address_to", + "email_body", + "email_subject", + "layout", + "name", + "notification_client", + "recipient_cc", + "recipient_to", + "id", + "initial_offset_after_deadline", + "interval_before_deadline", + "offset_before_deadline", + "owner_id", + "repeat_interval_after_deadline", + "repeat_offset_after_deadline", + "repetitions_after_deadline", + "schedule_id", + "user_id", + "last_sent" + ], + "filter": { + "_or": [ + { + "user_id": { + "_eq": "X-Hasura-User-Id" + } + }, + { + "user_id": { + "_is_null": true + } + } + ] + }, + "check": { + "_or": [ + { + "user_id": { + "_eq": "X-Hasura-User-Id" + } + }, + { + "user_id": { + "_is_null": true + } + } + ] + } + }, + "comment": "" + }, + { + "role": "middleware-server", + "permission": { + "columns": [ + "last_sent" + ], + "filter": {}, + "check": {} + }, + "comment": "" + }, + { + "role": "modeller", + "permission": { + "columns": [ + "bundle_id", + "bundle_type", + "channel", + "deadline", + "email_address_cc", + "email_address_to", + "email_body", + "email_subject", + "layout", + "name", + "notification_client", + "recipient_cc", + "recipient_to", + "id", + "initial_offset_after_deadline", + "interval_before_deadline", + "offset_before_deadline", + "owner_id", + "repeat_interval_after_deadline", + "repeat_offset_after_deadline", + "repetitions_after_deadline", + "schedule_id", + "user_id", + "last_sent" + ], + "filter": { + "_or": [ + { + "user_id": { + "_eq": "X-Hasura-User-Id" + } + }, + { + "user_id": { + "_is_null": true + } + } + ] + }, + "check": { + "_or": [ + { + "user_id": { + "_eq": "X-Hasura-User-Id" + } + }, + { + "user_id": { + "_is_null": true + } + } + ] + } + }, + "comment": "" + }, + { + "role": "recertifier", + "permission": { + "columns": [ + "bundle_id", + "bundle_type", + "channel", + "deadline", + "email_address_cc", + "email_address_to", + "email_body", + "email_subject", + "layout", + "name", + "notification_client", + "recipient_cc", + "recipient_to", + "id", + "initial_offset_after_deadline", + "interval_before_deadline", + "offset_before_deadline", + "owner_id", + "repeat_interval_after_deadline", + "repeat_offset_after_deadline", + "repetitions_after_deadline", + "schedule_id", + "user_id", + "last_sent" + ], + "filter": { + "_or": [ + { + "user_id": { + "_eq": "X-Hasura-User-Id" + } + }, + { + "user_id": { + "_is_null": true + } + } + ] + }, + "check": { + "_or": [ + { + "user_id": { + "_eq": "X-Hasura-User-Id" + } + }, + { + "user_id": { + "_is_null": true + } + } + ] + } + }, + "comment": "" + }, + { + "role": "reporter", + "permission": { + "columns": [ + "bundle_id", + "bundle_type", + "channel", + "deadline", + "email_address_cc", + "email_address_to", + "email_body", + "email_subject", + "layout", + "name", + "notification_client", + "recipient_cc", + "recipient_to", + "id", + "initial_offset_after_deadline", + "interval_before_deadline", + "offset_before_deadline", + "owner_id", + "repeat_interval_after_deadline", + "repeat_offset_after_deadline", + "repetitions_after_deadline", + "schedule_id", + "user_id", + "last_sent" + ], + "filter": { + "_or": [ + { + "user_id": { + "_eq": "X-Hasura-User-Id" + } + }, + { + "user_id": { + "_is_null": true + } + } + ] + }, + "check": { + "_or": [ + { + "user_id": { + "_eq": "X-Hasura-User-Id" + } + }, + { + "user_id": { + "_is_null": true + } + } + ] + } + }, + "comment": "" + }, + { + "role": "reporter-viewall", + "permission": { + "columns": [ + "bundle_id", + "bundle_type", + "channel", + "deadline", + "email_address_cc", + "email_address_to", + "email_body", + "email_subject", + "layout", + "name", + "notification_client", + "recipient_cc", + "recipient_to", + "id", + "initial_offset_after_deadline", + "interval_before_deadline", + "offset_before_deadline", + "owner_id", + "repeat_interval_after_deadline", + "repeat_offset_after_deadline", + "repetitions_after_deadline", + "schedule_id", + "user_id", + "last_sent" + ], + "filter": { + "_or": [ + { + "user_id": { + "_eq": "X-Hasura-User-Id" + } + }, + { + "user_id": { + "_is_null": true + } + } + ] + }, + "check": { + "_or": [ + { + "user_id": { + "_eq": "X-Hasura-User-Id" + } + }, + { + "user_id": { + "_is_null": true + } + } + ] + } + }, + "comment": "" + } + ], + "delete_permissions": [ + { + "role": "auditor", + "permission": { + "filter": { + "_and": [ + { + "notification_client": { + "_eq": "Report" + } + }, + { + "_or": [ + { + "user_id": { + "_eq": "X-Hasura-User-Id" + } + }, + { + "user_id": { + "_is_null": true + } + } + ] + } + ] + } + }, + "comment": "" + }, + { + "role": "fw-admin", + "permission": { + "filter": { + "_or": [ + { + "user_id": { + "_eq": "X-Hasura-User-Id" + } + }, + { + "user_id": { + "_is_null": true + } + } + ] + } + }, + "comment": "" + }, + { + "role": "modeller", + "permission": { + "filter": { + "_or": [ + { + "user_id": { + "_eq": "X-Hasura-User-Id" + } + }, + { + "user_id": { + "_is_null": true + } + } + ] + } + }, + "comment": "" + }, + { + "role": "recertifier", + "permission": { + "filter": { + "_or": [ + { + "user_id": { + "_eq": "X-Hasura-User-Id" + } + }, + { + "user_id": { + "_is_null": true + } + } + ] + } + }, + "comment": "" + }, + { + "role": "reporter", + "permission": { + "filter": { + "_or": [ + { + "user_id": { + "_eq": "X-Hasura-User-Id" + } + }, + { + "user_id": { + "_is_null": true + } + } + ] + } + }, + "comment": "" + }, + { + "role": "reporter-viewall", + "permission": { + "filter": { + "_or": [ + { + "user_id": { + "_eq": "X-Hasura-User-Id" + } + }, + { + "user_id": { + "_is_null": true + } + } + ] + } + }, + "comment": "" + } + ] + }, + { + "table": { + "name": "object", + "schema": "public" + }, + "object_relationships": [ + { + "name": "device", + "using": { + "foreign_key_constraint_on": "obj_nat_install" + } + }, + { + "name": "importControlByObjLastSeen", + "using": { + "foreign_key_constraint_on": "obj_last_seen" + } + }, + { + "name": "import_control", + "using": { + "foreign_key_constraint_on": "obj_create" + } + }, + { + "name": "management", + "using": { + "foreign_key_constraint_on": "mgm_id" + } + }, + { + "name": "stm_color", + "using": { + "foreign_key_constraint_on": "obj_color_id" + } + }, + { + "name": "stm_obj_typ", + "using": { + "foreign_key_constraint_on": "obj_typ_id" + } + }, + { + "name": "uiuser", + "using": { + "foreign_key_constraint_on": "last_change_admin" + } + }, + { + "name": "zone", + "using": { + "foreign_key_constraint_on": "zone_id" + } + } + ], + "array_relationships": [ + { + "name": "changelogObjectsByOldObjId", + "using": { + "foreign_key_constraint_on": { + "column": "old_obj_id", + "table": { + "name": "changelog_object", + "schema": "public" + } + } + } + }, + { + "name": "changelog_objects", + "using": { + "foreign_key_constraint_on": { + "column": "new_obj_id", + "table": { + "name": "changelog_object", + "schema": "public" + } + } + } + }, + { + "name": "elements", + "using": { + "foreign_key_constraint_on": { + "column": "network_object_id", + "table": { + "name": "implelement", + "schema": "request" + } + } + } + }, + { + "name": "impltasks", + "using": { + "foreign_key_constraint_on": { + "column": "nw_obj_grp_id", + "table": { + "name": "impltask", + "schema": "request" + } + } + } + }, + { + "name": "objgrpFlatsByObjgrpFlatMemberId", + "using": { + "foreign_key_constraint_on": { + "column": "objgrp_flat_member_id", + "table": { + "name": "objgrp_flat", + "schema": "public" + } + } + } + }, + { + "name": "objgrp_flats", + "using": { + "foreign_key_constraint_on": { + "column": "objgrp_flat_id", + "table": { + "name": "objgrp_flat", + "schema": "public" + } + } + } + }, + { + "name": "objgrps", + "using": { + "foreign_key_constraint_on": { + "column": "objgrp_id", + "table": { + "name": "objgrp", + "schema": "public" + } + } + } + }, + { + "name": "objgrpsByObjgrpMemberId", + "using": { + "foreign_key_constraint_on": { + "column": "objgrp_member_id", + "table": { + "name": "objgrp", + "schema": "public" + } + } + } + }, + { + "name": "reqelements", + "using": { + "foreign_key_constraint_on": { + "column": "network_object_id", + "table": { + "name": "reqelement", + "schema": "request" + } + } + } + }, + { + "name": "reqtasks", + "using": { + "foreign_key_constraint_on": { + "column": "nw_obj_grp_id", + "table": { + "name": "reqtask", + "schema": "request" + } + } + } + }, + { + "name": "rule_froms", + "using": { + "foreign_key_constraint_on": { + "column": "obj_id", + "table": { + "name": "rule_from", + "schema": "public" + } + } + } + }, + { + "name": "rule_nwobj_resolveds", + "using": { + "foreign_key_constraint_on": { + "column": "obj_id", + "table": { + "name": "rule_nwobj_resolved", + "schema": "public" + } + } + } + }, + { + "name": "rule_tos", + "using": { + "foreign_key_constraint_on": { + "column": "obj_id", + "table": { + "name": "rule_to", + "schema": "public" + } + } + } + } + ], + "insert_permissions": [ + { + "role": "importer", + "permission": { + "check": {}, + "columns": [ + "obj_create", + "obj_id", + "obj_last_seen", + "removed", + "active", + "initial_config", + "obj_nat", + "obj_comment", + "obj_location", + "obj_name", + "obj_sw", + "obj_sys_contact", + "obj_sys_location", + "obj_sys_name", + "obj_sys_readcom", + "obj_sys_writecom", + "obj_ip", + "obj_ip_end", + "obj_nat_ip", + "obj_nat_ip_end", + "last_change_admin", + "mgm_id", + "nattyp_id", + "obj_color_id", + "obj_nat_install", + "obj_typ_id", + "zone_id", + "obj_member_names", + "obj_member_refs", + "obj_sys_desc", + "obj_uid" + ] + }, + "comment": "" + } + ], + "select_permissions": [ + { + "role": "auditor", + "permission": { + "columns": [ + "obj_id", + "last_change_admin", + "zone_id", + "mgm_id", + "obj_name", + "obj_comment", + "obj_uid", + "obj_typ_id", + "obj_location", + "obj_member_names", + "obj_member_refs", + "initial_config", + "obj_sw", + "obj_ip", + "obj_ip_end", + "obj_nat", + "nattyp_id", + "obj_nat_ip", + "obj_nat_ip_end", + "obj_nat_install", + "obj_color_id", + "obj_sys_name", + "obj_sys_location", + "obj_sys_contact", + "obj_sys_desc", + "obj_sys_readcom", + "obj_sys_writecom", + "active", + "obj_create", + "obj_last_seen", + "removed" + ], + "filter": {}, + "allow_aggregations": true + } + }, + { + "role": "fw-admin", + "permission": { + "columns": [ + "obj_create", + "obj_id", + "obj_last_seen", + "removed", + "active", + "initial_config", + "obj_nat", + "obj_comment", + "obj_location", + "obj_name", + "obj_sw", + "obj_sys_contact", + "obj_sys_location", + "obj_sys_name", + "obj_sys_readcom", + "obj_sys_writecom", + "obj_ip", + "obj_ip_end", + "obj_nat_ip", + "obj_nat_ip_end", + "last_change_admin", + "mgm_id", + "nattyp_id", + "obj_color_id", + "obj_nat_install", + "obj_typ_id", + "zone_id", + "obj_member_names", + "obj_member_refs", + "obj_sys_desc", + "obj_uid" + ], + "filter": {}, + "allow_aggregations": true + } + }, + { + "role": "importer", + "permission": { + "columns": [ + "obj_create", + "obj_id", + "obj_last_seen", + "removed", + "active", + "initial_config", + "obj_nat", + "obj_comment", + "obj_location", + "obj_name", + "obj_sw", + "obj_sys_contact", + "obj_sys_location", + "obj_sys_name", + "obj_sys_readcom", + "obj_sys_writecom", + "obj_ip", + "obj_ip_end", + "obj_nat_ip", + "obj_nat_ip_end", + "last_change_admin", + "mgm_id", + "nattyp_id", + "obj_color_id", + "obj_nat_install", + "obj_typ_id", + "zone_id", + "obj_member_names", + "obj_member_refs", + "obj_sys_desc", + "obj_uid" + ], + "filter": {} + }, + "comment": "" + }, + { + "role": "middleware-server", + "permission": { + "columns": [ + "obj_id", + "last_change_admin", + "zone_id", + "mgm_id", + "obj_name", + "obj_comment", + "obj_uid", + "obj_typ_id", + "obj_location", + "obj_member_names", + "obj_member_refs", + "initial_config", + "obj_sw", + "obj_ip", + "obj_ip_end", + "obj_nat", + "nattyp_id", + "obj_nat_ip", + "obj_nat_ip_end", + "obj_nat_install", + "obj_color_id", + "obj_sys_name", + "obj_sys_location", + "obj_sys_contact", + "obj_sys_desc", + "obj_sys_readcom", + "obj_sys_writecom", + "active", + "obj_create", + "obj_last_seen", + "removed" + ], + "filter": {}, + "allow_aggregations": true + } + }, + { + "role": "modeller", + "permission": { + "columns": [ + "obj_id", + "last_change_admin", + "zone_id", + "mgm_id", + "obj_name", + "obj_comment", + "obj_uid", + "obj_typ_id", + "obj_location", + "obj_member_names", + "obj_member_refs", + "initial_config", + "obj_sw", + "obj_ip", + "obj_ip_end", + "obj_nat", + "nattyp_id", + "obj_nat_ip", + "obj_nat_ip_end", + "obj_nat_install", + "obj_color_id", + "obj_sys_name", + "obj_sys_location", + "obj_sys_contact", + "obj_sys_desc", + "obj_sys_readcom", + "obj_sys_writecom", + "active", + "obj_create", + "obj_last_seen", + "removed" + ], + "filter": { + "mgm_id": { + "_in": "x-hasura-visible-managements" + } + }, + "allow_aggregations": true + } + }, + { + "role": "recertifier", + "permission": { + "columns": [ + "obj_id", + "last_change_admin", + "zone_id", + "mgm_id", + "obj_name", + "obj_comment", + "obj_uid", + "obj_typ_id", + "obj_location", + "obj_member_names", + "obj_member_refs", + "initial_config", + "obj_sw", + "obj_ip", + "obj_ip_end", + "obj_nat", + "nattyp_id", + "obj_nat_ip", + "obj_nat_ip_end", + "obj_nat_install", + "obj_color_id", + "obj_sys_name", + "obj_sys_location", + "obj_sys_contact", + "obj_sys_desc", + "obj_sys_readcom", + "obj_sys_writecom", + "active", + "obj_create", + "obj_last_seen", + "removed" + ], + "filter": { + "mgm_id": { + "_in": "x-hasura-visible-managements" + } + }, + "allow_aggregations": true + } + }, + { + "role": "reporter", + "permission": { + "columns": [ + "obj_id", + "last_change_admin", + "zone_id", + "mgm_id", + "obj_name", + "obj_comment", + "obj_uid", + "obj_typ_id", + "obj_location", + "obj_member_names", + "obj_member_refs", + "initial_config", + "obj_sw", + "obj_ip", + "obj_ip_end", + "obj_nat", + "nattyp_id", + "obj_nat_ip", + "obj_nat_ip_end", + "obj_nat_install", + "obj_color_id", + "obj_sys_name", + "obj_sys_location", + "obj_sys_contact", + "obj_sys_desc", + "obj_sys_readcom", + "obj_sys_writecom", + "active", + "obj_create", + "obj_last_seen", + "removed" + ], + "filter": { + "mgm_id": { + "_in": "x-hasura-visible-managements" + } + }, + "allow_aggregations": true + } + }, + { + "role": "reporter-viewall", + "permission": { + "columns": [ + "obj_id", + "last_change_admin", + "zone_id", + "mgm_id", + "obj_name", + "obj_comment", + "obj_uid", + "obj_typ_id", + "obj_location", + "obj_member_names", + "obj_member_refs", + "initial_config", + "obj_sw", + "obj_ip", + "obj_ip_end", + "obj_nat", + "nattyp_id", + "obj_nat_ip", + "obj_nat_ip_end", + "obj_nat_install", + "obj_color_id", + "obj_sys_name", + "obj_sys_location", + "obj_sys_contact", + "obj_sys_desc", + "obj_sys_readcom", + "obj_sys_writecom", + "active", + "obj_create", + "obj_last_seen", + "removed" + ], + "filter": {}, + "allow_aggregations": true + } + } + ], + "update_permissions": [ + { + "role": "importer", + "permission": { + "columns": [ + "obj_create", + "obj_id", + "obj_last_seen", + "removed", + "active", + "initial_config", + "obj_nat", + "obj_comment", + "obj_location", + "obj_name", + "obj_sw", + "obj_sys_contact", + "obj_sys_location", + "obj_sys_name", + "obj_sys_readcom", + "obj_sys_writecom", + "obj_ip", + "obj_ip_end", + "obj_nat_ip", + "obj_nat_ip_end", + "last_change_admin", + "mgm_id", + "nattyp_id", + "obj_color_id", + "obj_nat_install", + "obj_typ_id", + "zone_id", + "obj_member_names", + "obj_member_refs", + "obj_sys_desc", + "obj_uid" + ], + "filter": {}, + "check": {} + }, + "comment": "" + } + ], + "delete_permissions": [ + { + "role": "importer", + "permission": { + "filter": {} + }, + "comment": "" + } + ] + }, + { + "table": { + "name": "objgrp", + "schema": "public" + }, + "object_relationships": [ + { + "name": "importControlByImportLastSeen", + "using": { + "foreign_key_constraint_on": "import_last_seen" + } + }, + { + "name": "import_control", + "using": { + "foreign_key_constraint_on": "import_created" + } + }, + { + "name": "object", + "using": { + "foreign_key_constraint_on": "objgrp_id" + } + }, + { + "name": "objectByObjgrpMemberId", + "using": { + "foreign_key_constraint_on": "objgrp_member_id" + } + } + ], + "insert_permissions": [ + { + "role": "importer", + "permission": { + "check": {}, + "columns": [ + "import_created", + "import_last_seen", + "objgrp_id", + "objgrp_member_id", + "removed", + "active", + "negated" + ] + }, + "comment": "" + } + ], + "select_permissions": [ + { + "role": "auditor", + "permission": { + "columns": [ + "objgrp_id", + "objgrp_member_id", + "import_created", + "import_last_seen", + "removed", + "active", + "negated" + ], + "filter": {}, + "allow_aggregations": true + } + }, + { + "role": "fw-admin", + "permission": { + "columns": [ + "import_created", + "import_last_seen", + "objgrp_id", + "removed", + "objgrp_member_id", + "active", + "negated" + ], + "filter": {} + } + }, + { + "role": "importer", + "permission": { + "columns": [ + "import_created", + "import_last_seen", + "objgrp_id", + "objgrp_member_id", + "removed", + "active", + "negated" + ], + "filter": {} + }, + "comment": "" + }, + { + "role": "middleware-server", + "permission": { + "columns": [ + "import_created", + "import_last_seen", + "objgrp_id", + "objgrp_member_id", + "removed", + "active", + "negated" + ], + "filter": {} + }, + "comment": "" + }, + { + "role": "modeller", + "permission": { + "columns": [ + "objgrp_id", + "objgrp_member_id", + "import_created", + "import_last_seen", + "removed", + "active", + "negated" + ], + "filter": {}, + "allow_aggregations": true + } + }, + { + "role": "recertifier", + "permission": { + "columns": [ + "objgrp_id", + "objgrp_member_id", + "import_created", + "import_last_seen", + "removed", + "active", + "negated" + ], + "filter": {}, + "allow_aggregations": true + } + }, + { + "role": "reporter", + "permission": { + "columns": [ + "objgrp_id", + "objgrp_member_id", + "import_created", + "import_last_seen", + "removed", + "active", + "negated" + ], + "filter": {}, + "allow_aggregations": true + } + }, + { + "role": "reporter-viewall", + "permission": { + "columns": [ + "objgrp_id", + "objgrp_member_id", + "import_created", + "import_last_seen", + "removed", + "active", + "negated" + ], + "filter": {} + } + } + ], + "update_permissions": [ + { + "role": "importer", + "permission": { + "columns": [ + "import_created", + "import_last_seen", + "objgrp_id", + "objgrp_member_id", + "removed", + "active", + "negated" + ], + "filter": {}, + "check": {} + }, + "comment": "" + } + ], + "delete_permissions": [ + { + "role": "importer", + "permission": { + "filter": {} + }, + "comment": "" + } + ] + }, + { + "table": { + "name": "objgrp_flat", + "schema": "public" + }, + "object_relationships": [ + { + "name": "importControlByImportLastSeen", + "using": { + "foreign_key_constraint_on": "import_last_seen" + } + }, + { + "name": "import_control", + "using": { + "foreign_key_constraint_on": "import_created" + } + }, + { + "name": "object", + "using": { + "foreign_key_constraint_on": "objgrp_flat_id" + } + }, + { + "name": "objectByObjgrpFlatMemberId", + "using": { + "foreign_key_constraint_on": "objgrp_flat_member_id" + } + } + ], + "insert_permissions": [ + { + "role": "importer", + "permission": { + "check": {}, + "columns": [ + "import_created", + "import_last_seen", + "objgrp_flat_id", + "objgrp_flat_member_id", + "removed", + "active", + "negated" + ] + }, + "comment": "" + } + ], + "select_permissions": [ + { + "role": "auditor", + "permission": { + "columns": [ + "objgrp_flat_id", + "objgrp_flat_member_id", + "active", + "import_created", + "import_last_seen", + "removed", + "negated" + ], + "filter": {}, + "allow_aggregations": true + } + }, + { + "role": "fw-admin", + "permission": { + "columns": [ + "import_created", + "import_last_seen", + "removed", + "objgrp_flat_id", + "objgrp_flat_member_id", + "active", + "negated" + ], + "filter": {} + } + }, + { + "role": "importer", + "permission": { + "columns": [ + "import_created", + "import_last_seen", + "objgrp_flat_id", + "objgrp_flat_member_id", + "removed", + "active", + "negated" + ], + "filter": {} + }, + "comment": "" + }, + { + "role": "middleware-server", + "permission": { + "columns": [ + "import_created", + "import_last_seen", + "objgrp_flat_id", + "objgrp_flat_member_id", + "removed", + "active", + "negated" + ], + "filter": {} + }, + "comment": "" + }, + { + "role": "modeller", + "permission": { + "columns": [ + "objgrp_flat_id", + "objgrp_flat_member_id", + "removed", + "active", + "import_created", + "import_last_seen", + "negated" + ], + "filter": {}, + "allow_aggregations": true + } + }, + { + "role": "recertifier", + "permission": { + "columns": [ + "objgrp_flat_id", + "objgrp_flat_member_id", + "removed", + "active", + "import_created", + "import_last_seen", + "negated" + ], + "filter": {}, + "allow_aggregations": true + } + }, + { + "role": "reporter", + "permission": { + "columns": [ + "objgrp_flat_id", + "objgrp_flat_member_id", + "removed", + "active", + "import_created", + "import_last_seen", + "negated" + ], + "filter": {}, + "allow_aggregations": true + } + }, + { + "role": "reporter-viewall", + "permission": { + "columns": [ + "objgrp_flat_id", + "objgrp_flat_member_id", + "removed", + "active", + "import_created", + "import_last_seen", + "negated" + ], + "filter": {} + } + } + ], + "update_permissions": [ + { + "role": "importer", + "permission": { + "columns": [ + "import_created", + "import_last_seen", + "objgrp_flat_id", + "objgrp_flat_member_id", + "removed", + "active", + "negated" + ], + "filter": {}, + "check": {} + }, + "comment": "" + } + ], + "delete_permissions": [ + { + "role": "importer", + "permission": { + "filter": {} + }, + "comment": "" + } + ] + }, + { + "table": { + "name": "owner", + "schema": "public" + }, + "object_relationships": [ + { + "name": "owner_lifecycle_state", + "using": { + "foreign_key_constraint_on": "owner_lifecycle_state_id" + } + }, + { + "name": "tenant", + "using": { + "foreign_key_constraint_on": "tenant_id" + } + }, + { + "name": "uiuser", + "using": { + "foreign_key_constraint_on": "last_recertifier" + } + } + ], + "array_relationships": [ + { + "name": "change_histories", + "using": { + "foreign_key_constraint_on": { + "column": "app_id", + "table": { + "name": "change_history", + "schema": "modelling" + } + } + } + }, + { + "name": "changelogOwnersByOldOwnerId", + "using": { + "foreign_key_constraint_on": { + "column": "old_owner_id", + "table": { + "name": "changelog_owner", + "schema": "public" + } + } + } + }, + { + "name": "changelog_owners", + "using": { + "foreign_key_constraint_on": { + "column": "new_owner_id", + "table": { + "name": "changelog_owner", + "schema": "public" + } + } + } + }, + { + "name": "connections", + "using": { + "foreign_key_constraint_on": { + "column": "app_id", + "table": { + "name": "connection", + "schema": "modelling" + } + } + } + }, + { + "name": "connectionsByProposedAppId", + "using": { + "foreign_key_constraint_on": { + "column": "proposed_app_id", + "table": { + "name": "connection", + "schema": "modelling" + } + } + } + }, + { + "name": "ext_requests", + "using": { + "foreign_key_constraint_on": { + "column": "owner_id", + "table": { + "name": "ext_request", + "schema": "public" + } + } + } + }, + { + "name": "notifications", + "using": { + "foreign_key_constraint_on": { + "column": "owner_id", + "table": { + "name": "notification", + "schema": "public" + } + } + } + }, + { + "name": "nwgroups", + "using": { + "foreign_key_constraint_on": { + "column": "app_id", + "table": { + "name": "nwgroup", + "schema": "modelling" + } + } + } + }, + { + "name": "owner_networks", + "using": { + "foreign_key_constraint_on": { + "column": "owner_id", + "table": { + "name": "owner_network", + "schema": "public" + } + } + } + }, + { + "name": "owner_recertifications", + "using": { + "foreign_key_constraint_on": { + "column": "owner_id", + "table": { + "name": "owner_recertification", + "schema": "public" + } + } + } + }, + { + "name": "owner_responsibles", + "using": { + "foreign_key_constraint_on": { + "column": "owner_id", + "table": { + "name": "owner_responsible", + "schema": "public" + } + } + } + }, + { + "name": "owner_tickets", + "using": { + "foreign_key_constraint_on": { + "column": "owner_id", + "table": { + "name": "owner_ticket", + "schema": "public" + } + } + } + }, + { + "name": "permitted_owners", + "using": { + "manual_configuration": { + "column_mapping": { + "id": "app_id" + }, + "insertion_order": null, + "remote_table": { + "name": "permitted_owners", + "schema": "modelling" + } + } + } + }, + { + "name": "recertifications", + "using": { + "foreign_key_constraint_on": { + "column": "owner_id", + "table": { + "name": "recertification", + "schema": "public" + } + } + } + }, + { + "name": "reports", + "using": { + "foreign_key_constraint_on": { + "column": "owner_id", + "table": { + "name": "report", + "schema": "public" + } + } + } + }, + { + "name": "reqtask_owners", + "using": { + "foreign_key_constraint_on": { + "column": "owner_id", + "table": { + "name": "reqtask_owner", + "schema": "public" + } + } + } + }, + { + "name": "rule_owners", + "using": { + "foreign_key_constraint_on": { + "column": "owner_id", + "table": { + "name": "rule_owner", + "schema": "public" + } + } + } + }, + { + "name": "selected_connections", + "using": { + "foreign_key_constraint_on": { + "column": "app_id", + "table": { + "name": "selected_connections", + "schema": "modelling" + } + } + } + }, + { + "name": "selected_objects", + "using": { + "foreign_key_constraint_on": { + "column": "app_id", + "table": { + "name": "selected_objects", + "schema": "modelling" + } + } + } + }, + { + "name": "service_groups", + "using": { + "foreign_key_constraint_on": { + "column": "app_id", + "table": { + "name": "service_group", + "schema": "modelling" + } + } + } + }, + { + "name": "services", + "using": { + "foreign_key_constraint_on": { + "column": "app_id", + "table": { + "name": "service", + "schema": "modelling" + } + } + } + } + ], + "insert_permissions": [ + { + "role": "middleware-server", + "permission": { + "check": {}, + "columns": [ + "active", + "additional_info", + "app_id_external", + "common_service_possible", + "criticality", + "decomm_date", + "id", + "import_source", + "is_default", + "last_recert_check", + "last_recertified", + "last_recertifier", + "last_recertifier_dn", + "name", + "next_recert_date", + "owner_lifecycle_state_id", + "recert_active", + "recert_check_params", + "recert_interval", + "tenant_id" + ] + }, + "comment": "" + } + ], + "select_permissions": [ + { + "role": "approver", + "permission": { + "columns": [ + "active", + "additional_info", + "app_id_external", + "common_service_possible", + "criticality", + "decomm_date", + "id", + "import_source", + "is_default", + "last_recert_check", + "last_recertified", + "last_recertifier", + "last_recertifier_dn", + "name", + "next_recert_date", + "owner_lifecycle_state_id", + "recert_active", + "recert_check_params", + "recert_interval", + "tenant_id" + ], + "filter": {} + } + }, + { + "role": "auditor", + "permission": { + "columns": [ + "active", + "additional_info", + "app_id_external", + "common_service_possible", + "criticality", + "decomm_date", + "id", + "import_source", + "is_default", + "last_recert_check", + "last_recertified", + "last_recertifier", + "last_recertifier_dn", + "name", + "next_recert_date", + "owner_lifecycle_state_id", + "recert_active", + "recert_check_params", + "recert_interval", + "tenant_id" + ], + "filter": {} + } + }, + { + "role": "fw-admin", + "permission": { + "columns": [ + "active", + "additional_info", + "app_id_external", + "common_service_possible", + "criticality", + "decomm_date", + "id", + "import_source", + "is_default", + "last_recert_check", + "last_recertified", + "last_recertifier", + "last_recertifier_dn", + "name", + "next_recert_date", + "owner_lifecycle_state_id", + "recert_active", + "recert_check_params", + "recert_interval", + "tenant_id" + ], + "filter": {} + } + }, + { + "role": "implementer", + "permission": { + "columns": [ + "active", + "additional_info", + "app_id_external", + "common_service_possible", + "criticality", + "decomm_date", + "id", + "import_source", + "is_default", + "last_recert_check", + "last_recertified", + "last_recertifier", + "last_recertifier_dn", + "name", + "next_recert_date", + "owner_lifecycle_state_id", + "recert_active", + "recert_check_params", + "recert_interval", + "tenant_id" + ], + "filter": {} + } + }, + { + "role": "middleware-server", + "permission": { + "columns": [ + "active", + "additional_info", + "app_id_external", + "common_service_possible", + "criticality", + "decomm_date", + "id", + "import_source", + "is_default", + "last_recert_check", + "last_recertified", + "last_recertifier", + "last_recertifier_dn", + "name", + "next_recert_date", + "owner_lifecycle_state_id", + "recert_active", + "recert_check_params", + "recert_interval", + "tenant_id" + ], + "filter": {} + } + }, + { + "role": "modeller", + "permission": { + "columns": [ + "active", + "additional_info", + "app_id_external", + "common_service_possible", + "criticality", + "decomm_date", + "id", + "import_source", + "is_default", + "last_recert_check", + "last_recertified", + "last_recertifier", + "last_recertifier_dn", + "name", + "next_recert_date", + "owner_lifecycle_state_id", + "recert_active", + "recert_check_params", + "recert_interval", + "tenant_id" + ], + "filter": { + "_and": [ + { + "_or": [ + { + "tenant_id": { + "_is_null": true + } + }, + { + "tenant_id": { + "_eq": "x-hasura-tenant-id" + } + } + ] + } + ] + }, + "allow_aggregations": true + } + }, + { + "role": "planner", + "permission": { + "columns": [ + "active", + "additional_info", + "app_id_external", + "common_service_possible", + "criticality", + "decomm_date", + "id", + "import_source", + "is_default", + "last_recert_check", + "last_recertified", + "last_recertifier", + "last_recertifier_dn", + "name", + "next_recert_date", + "owner_lifecycle_state_id", + "recert_active", + "recert_check_params", + "recert_interval", + "tenant_id" + ], + "filter": {} + } + }, + { + "role": "recertifier", + "permission": { + "columns": [ + "active", + "additional_info", + "app_id_external", + "common_service_possible", + "criticality", + "decomm_date", + "id", + "import_source", + "is_default", + "last_recert_check", + "last_recertified", + "last_recertifier", + "last_recertifier_dn", + "name", + "next_recert_date", + "owner_lifecycle_state_id", + "recert_active", + "recert_check_params", + "recert_interval", + "tenant_id" + ], + "filter": { + "_or": [ + { + "tenant_id": { + "_is_null": true + } + }, + { + "tenant_id": { + "_eq": "x-hasura-tenant-id" + } + } + ] + }, + "allow_aggregations": true + } + }, + { + "role": "reporter", + "permission": { + "columns": [ + "active", + "additional_info", + "app_id_external", + "common_service_possible", + "criticality", + "decomm_date", + "id", + "import_source", + "is_default", + "last_recert_check", + "last_recertified", + "last_recertifier", + "last_recertifier_dn", + "name", + "next_recert_date", + "owner_lifecycle_state_id", + "recert_active", + "recert_check_params", + "recert_interval", + "tenant_id" + ], + "filter": { + "_or": [ + { + "tenant_id": { + "_is_null": true + } + }, + { + "tenant_id": { + "_eq": "x-hasura-tenant-id" + } + } + ] + }, + "allow_aggregations": true + } + }, + { + "role": "reporter-viewall", + "permission": { + "columns": [ + "active", + "additional_info", + "app_id_external", + "common_service_possible", + "criticality", + "decomm_date", + "id", + "import_source", + "is_default", + "last_recert_check", + "last_recertified", + "last_recertifier", + "last_recertifier_dn", + "name", + "next_recert_date", + "owner_lifecycle_state_id", + "recert_active", + "recert_check_params", + "recert_interval", + "tenant_id" + ], + "filter": {}, + "allow_aggregations": true + } + }, + { + "role": "requester", + "permission": { + "columns": [ + "active", + "additional_info", + "app_id_external", + "common_service_possible", + "criticality", + "decomm_date", + "id", + "import_source", + "is_default", + "last_recert_check", + "last_recertified", + "last_recertifier", + "last_recertifier_dn", + "name", + "next_recert_date", + "owner_lifecycle_state_id", + "recert_active", + "recert_check_params", + "recert_interval", + "tenant_id" + ], + "filter": {} + } + }, + { + "role": "reviewer", + "permission": { + "columns": [ + "active", + "additional_info", + "app_id_external", + "common_service_possible", + "criticality", + "decomm_date", + "id", + "import_source", + "is_default", + "last_recert_check", + "last_recertified", + "last_recertifier", + "last_recertifier_dn", + "name", + "next_recert_date", + "owner_lifecycle_state_id", + "recert_active", + "recert_check_params", + "recert_interval", + "tenant_id" + ], + "filter": {} + } + } + ], + "update_permissions": [ + { + "role": "middleware-server", + "permission": { + "columns": [ + "active", + "additional_info", + "app_id_external", + "common_service_possible", + "criticality", + "decomm_date", + "id", + "import_source", + "is_default", + "last_recert_check", + "last_recertified", + "last_recertifier", + "last_recertifier_dn", + "name", + "next_recert_date", + "owner_lifecycle_state_id", + "recert_active", + "recert_check_params", + "recert_interval", + "tenant_id" + ], + "filter": {}, + "check": null + } + }, + { + "role": "modeller", + "permission": { + "columns": [ + "last_recert_check", + "last_recertified", + "last_recertifier", + "last_recertifier_dn", + "next_recert_date", + "recert_active" + ], + "filter": { + "_and": [ + { + "_or": [ + { + "tenant_id": { + "_is_null": true + } + }, + { + "tenant_id": { + "_eq": "x-hasura-tenant-id" + } + } + ] + } + ] + }, + "check": {} + }, + "comment": "" + } + ] + }, + { + "table": { + "name": "owner_lifecycle_state", + "schema": "public" + }, + "array_relationships": [ + { + "name": "owners", + "using": { + "foreign_key_constraint_on": { + "column": "owner_lifecycle_state_id", + "table": { + "name": "owner", + "schema": "public" + } + } + } + } + ], + "select_permissions": [ + { + "role": "auditor", + "permission": { + "columns": [ + "active_state", + "name", + "id" + ], + "filter": {} + }, + "comment": "" + }, + { + "role": "fw-admin", + "permission": { + "columns": [ + "active_state", + "name", + "id" + ], + "filter": {} + }, + "comment": "" + }, + { + "role": "importer", + "permission": { + "columns": [ + "active_state", + "name", + "id" + ], + "filter": {} + }, + "comment": "" + }, + { + "role": "middleware-server", + "permission": { + "columns": [ + "active_state", + "name", + "id" + ], + "filter": {} + }, + "comment": "" + } + ] + }, + { + "table": { + "name": "owner_network", + "schema": "public" + }, + "object_relationships": [ + { + "name": "owner", + "using": { + "foreign_key_constraint_on": "owner_id" + } + }, + { + "name": "stm_ip_proto", + "using": { + "foreign_key_constraint_on": "ip_proto_id" + } + } + ], + "array_relationships": [ + { + "name": "nwobject_connections", + "using": { + "foreign_key_constraint_on": { + "column": "nwobject_id", + "table": { + "name": "nwobject_connection", + "schema": "modelling" + } + } + } + }, + { + "name": "nwobject_nwgroups", + "using": { + "foreign_key_constraint_on": { + "column": "nwobject_id", + "table": { + "name": "nwobject_nwgroup", + "schema": "modelling" + } + } + } + } + ], + "insert_permissions": [ + { + "role": "middleware-server", + "permission": { + "check": {}, + "columns": [ + "custom_type", + "id", + "import_source", + "ip", + "ip_end", + "ip_proto_id", + "is_deleted", + "name", + "nw_type", + "owner_id", + "port" + ] + }, + "comment": "" + } + ], + "select_permissions": [ + { + "role": "auditor", + "permission": { + "columns": [ + "id", + "is_deleted", + "import_source", + "name", + "ip", + "ip_end", + "custom_type", + "ip_proto_id", + "nw_type", + "owner_id", + "port" + ], + "filter": {}, + "allow_aggregations": true + } + }, + { + "role": "middleware-server", + "permission": { + "columns": [ + "custom_type", + "id", + "import_source", + "ip", + "ip_end", + "ip_proto_id", + "is_deleted", + "name", + "nw_type", + "owner_id", + "port" + ], + "filter": {} + }, + "comment": "" + }, + { + "role": "modeller", + "permission": { + "columns": [ + "id", + "is_deleted", + "import_source", + "name", + "ip", + "ip_end", + "custom_type", + "ip_proto_id", + "nw_type", + "owner_id", + "port" + ], + "filter": {} + }, + "comment": "" + } + ], + "update_permissions": [ + { + "role": "middleware-server", + "permission": { + "columns": [ + "custom_type", + "import_source", + "ip", + "ip_end", + "ip_proto_id", + "is_deleted", + "name", + "nw_type", + "owner_id", + "port" + ], + "filter": {}, + "check": null + }, + "comment": "" + } + ], + "delete_permissions": [ + { + "role": "middleware-server", + "permission": { + "filter": {} + }, + "comment": "" + } + ] + }, + { + "table": { + "name": "owner_recertification", + "schema": "public" + }, + "object_relationships": [ + { + "name": "owner", + "using": { + "foreign_key_constraint_on": "owner_id" + } + }, + { + "name": "report", + "using": { + "foreign_key_constraint_on": "report_id" + } + } + ], + "array_relationships": [ + { + "name": "recertifications", + "using": { + "foreign_key_constraint_on": { + "column": "owner_recert_id", + "table": { + "name": "recertification", + "schema": "public" + } + } + } + } + ], + "insert_permissions": [ + { + "role": "modeller", + "permission": { + "check": {}, + "columns": [ + "id", + "report_id", + "recertified", + "comment", + "user_dn", + "owner_id", + "next_recert_date", + "recert_date" + ] + }, + "comment": "" + } + ], + "select_permissions": [ + { + "role": "auditor", + "permission": { + "columns": [ + "id", + "report_id", + "recertified", + "comment", + "user_dn", + "owner_id", + "next_recert_date", + "recert_date" + ], + "filter": {} + }, + "comment": "" + }, + { + "role": "fw-admin", + "permission": { + "columns": [ + "id", + "report_id", + "recertified", + "comment", + "user_dn", + "owner_id", + "next_recert_date", + "recert_date" + ], + "filter": {} + }, + "comment": "" + }, + { + "role": "middleware-server", + "permission": { + "columns": [ + "id", + "report_id", + "recertified", + "comment", + "user_dn", + "owner_id", + "next_recert_date", + "recert_date" + ], + "filter": {} + }, + "comment": "" + }, + { + "role": "modeller", + "permission": { + "columns": [ + "id", + "report_id", + "recertified", + "comment", + "user_dn", + "owner_id", + "next_recert_date", + "recert_date" + ], + "filter": {} + }, + "comment": "" + } + ], + "update_permissions": [ + { + "role": "modeller", + "permission": { + "columns": [ + "report_id" + ], + "filter": {}, + "check": null + }, + "comment": "" + } + ] + }, + { + "table": { + "name": "owner_responsible", + "schema": "public" + }, + "object_relationships": [ + { + "name": "owner", + "using": { + "foreign_key_constraint_on": "owner_id" + } + }, + { + "name": "owner_responsible_type", + "using": { + "foreign_key_constraint_on": "responsible_type" + } + } + ], + "insert_permissions": [ + { + "role": "middleware-server", + "permission": { + "check": {}, + "columns": [ + "dn", + "id", + "owner_id", + "responsible_type" + ] + }, + "comment": "" + }, + { + "role": "modeller", + "permission": { + "check": {}, + "columns": [ + "dn", + "id", + "owner_id", + "responsible_type" + ] + }, + "comment": "" + } + ], + "select_permissions": [ + { + "role": "approver", + "permission": { + "columns": [ + "id", + "owner_id", + "dn", + "responsible_type" + ], + "filter": {} + }, + "comment": "" + }, + { + "role": "auditor", + "permission": { + "columns": [ + "id", + "owner_id", + "dn", + "responsible_type" + ], + "filter": {} + }, + "comment": "" + }, + { + "role": "fw-admin", + "permission": { + "columns": [ + "id", + "owner_id", + "dn", + "responsible_type" + ], + "filter": {} + }, + "comment": "" + }, + { + "role": "implementer", + "permission": { + "columns": [ + "id", + "owner_id", + "dn", + "responsible_type" + ], + "filter": {} + }, + "comment": "" + }, + { + "role": "middleware-server", + "permission": { + "columns": [ + "id", + "owner_id", + "dn", + "responsible_type" + ], + "filter": {} + }, + "comment": "" + }, + { + "role": "modeller", + "permission": { + "columns": [ + "id", + "owner_id", + "dn", + "responsible_type" + ], + "filter": {} + }, + "comment": "" + }, + { + "role": "planner", + "permission": { + "columns": [ + "id", + "owner_id", + "dn", + "responsible_type" + ], + "filter": {} + }, + "comment": "" + }, + { + "role": "recertifier", + "permission": { + "columns": [ + "id", + "owner_id", + "dn", + "responsible_type" + ], + "filter": {} + }, + "comment": "" + }, + { + "role": "reporter", + "permission": { + "columns": [ + "id", + "owner_id", + "dn", + "responsible_type" + ], + "filter": {} + }, + "comment": "" + }, + { + "role": "reporter-viewall", + "permission": { + "columns": [ + "id", + "owner_id", + "dn", + "responsible_type" + ], + "filter": {} + }, + "comment": "" + }, + { + "role": "requester", + "permission": { + "columns": [ + "id", + "owner_id", + "dn", + "responsible_type" + ], + "filter": {} + }, + "comment": "" + }, + { + "role": "reviewer", + "permission": { + "columns": [ + "id", + "owner_id", + "dn", + "responsible_type" + ], + "filter": {} + }, + "comment": "" + } + ], + "delete_permissions": [ + { + "role": "middleware-server", + "permission": { + "filter": {} + }, + "comment": "" + }, + { + "role": "modeller", + "permission": { + "filter": {} + }, + "comment": "" + } + ] + }, + { + "table": { + "name": "owner_responsible_type", + "schema": "public" + }, + "array_relationships": [ + { + "name": "owner_responsibles", + "using": { + "foreign_key_constraint_on": { + "column": "responsible_type", + "table": { + "name": "owner_responsible", + "schema": "public" + } + } + } + } + ], + "insert_permissions": [ + { + "role": "fw-admin", + "permission": { + "check": {}, + "columns": [ + "active", + "allow_modelling", + "allow_recertification", + "id", + "name", + "sort_order" + ] + }, + "comment": "" + }, + { + "role": "middleware-server", + "permission": { + "check": {}, + "columns": [ + "active", + "allow_modelling", + "allow_recertification", + "id", + "name", + "sort_order" + ] + }, + "comment": "" + } + ], + "select_permissions": [ + { + "role": "approver", + "permission": { + "columns": [ + "id", + "name", + "allow_modelling", + "allow_recertification", + "active", + "sort_order" + ], + "filter": {} + }, + "comment": "" + }, + { + "role": "auditor", + "permission": { + "columns": [ + "id", + "name", + "allow_modelling", + "allow_recertification", + "active", + "sort_order" + ], + "filter": {} + }, + "comment": "" + }, + { + "role": "fw-admin", + "permission": { + "columns": [ + "id", + "name", + "allow_modelling", + "allow_recertification", + "active", + "sort_order" + ], + "filter": {} + }, + "comment": "" + }, + { + "role": "implementer", + "permission": { + "columns": [ + "id", + "name", + "allow_modelling", + "allow_recertification", + "active", + "sort_order" + ], + "filter": {} + }, + "comment": "" + }, + { + "role": "middleware-server", + "permission": { + "columns": [ + "id", + "name", + "allow_modelling", + "allow_recertification", + "active", + "sort_order" + ], + "filter": {} + }, + "comment": "" + }, + { + "role": "modeller", + "permission": { + "columns": [ + "id", + "name", + "allow_modelling", + "allow_recertification", + "active", + "sort_order" + ], + "filter": {} + }, + "comment": "" + }, + { + "role": "planner", + "permission": { + "columns": [ + "id", + "name", + "allow_modelling", + "allow_recertification", + "active", + "sort_order" + ], + "filter": {} + }, + "comment": "" + }, + { + "role": "recertifier", + "permission": { + "columns": [ + "id", + "name", + "allow_modelling", + "allow_recertification", + "active", + "sort_order" + ], + "filter": {} + }, + "comment": "" + }, + { + "role": "reporter", + "permission": { + "columns": [ + "id", + "name", + "allow_modelling", + "allow_recertification", + "active", + "sort_order" + ], + "filter": {} + }, + "comment": "" + }, + { + "role": "reporter-viewall", + "permission": { + "columns": [ + "id", + "name", + "allow_modelling", + "allow_recertification", + "active", + "sort_order" + ], + "filter": {} + }, + "comment": "" + }, + { + "role": "requester", + "permission": { + "columns": [ + "id", + "name", + "allow_modelling", + "allow_recertification", + "active", + "sort_order" + ], + "filter": {} + }, + "comment": "" + }, + { + "role": "reviewer", + "permission": { + "columns": [ + "active", + "allow_modelling", + "allow_recertification", + "name", + "id", + "sort_order" + ], + "filter": {} + }, + "comment": "" + } + ], + "update_permissions": [ + { + "role": "fw-admin", + "permission": { + "columns": [ + "active", + "allow_modelling", + "allow_recertification", + "name", + "sort_order" + ], + "filter": {}, + "check": null + }, + "comment": "" + }, + { + "role": "middleware-server", + "permission": { + "columns": [ + "active", + "allow_modelling", + "allow_recertification", + "name", + "sort_order" + ], + "filter": {}, + "check": null + }, + "comment": "" + } + ] + }, + { + "table": { + "name": "owner_ticket", + "schema": "public" + }, + "object_relationships": [ + { + "name": "owner", + "using": { + "foreign_key_constraint_on": "owner_id" + } + }, + { + "name": "ticket", + "using": { + "foreign_key_constraint_on": "ticket_id" + } + } + ], + "insert_permissions": [ + { + "role": "modeller", + "permission": { + "check": {}, + "columns": [ + "ticket_id", + "owner_id" + ] + }, + "comment": "" + } + ], + "select_permissions": [ + { + "role": "approver", + "permission": { + "columns": [ + "ticket_id", + "owner_id" + ], + "filter": {} + }, + "comment": "" + }, + { + "role": "auditor", + "permission": { + "columns": [ + "ticket_id", + "owner_id" + ], + "filter": {} + }, + "comment": "" + }, + { + "role": "fw-admin", + "permission": { + "columns": [ + "ticket_id", + "owner_id" + ], + "filter": {} + }, + "comment": "" + }, + { + "role": "implementer", + "permission": { + "columns": [ + "ticket_id", + "owner_id" + ], + "filter": {} + }, + "comment": "" + }, + { + "role": "modeller", + "permission": { + "columns": [ + "ticket_id", + "owner_id" + ], + "filter": {} + }, + "comment": "" + }, + { + "role": "planner", + "permission": { + "columns": [ + "ticket_id", + "owner_id" + ], + "filter": {} + }, + "comment": "" + }, + { + "role": "requester", + "permission": { + "columns": [ + "ticket_id", + "owner_id" + ], + "filter": {} + }, + "comment": "" + }, + { + "role": "reviewer", + "permission": { + "columns": [ + "ticket_id", + "owner_id" + ], + "filter": {} + }, + "comment": "" + } + ] + }, + { + "table": { + "name": "parent_rule_type", + "schema": "public" + }, + "array_relationships": [ + { + "name": "rules", + "using": { + "foreign_key_constraint_on": { + "column": "parent_rule_type", + "table": { + "name": "rule", + "schema": "public" + } + } + } + } + ], + "select_permissions": [ + { + "role": "auditor", + "permission": { + "columns": [ + "id", + "name" + ], + "filter": {} + } + }, + { + "role": "fw-admin", + "permission": { + "columns": [ + "name", + "id" + ], + "filter": {}, + "allow_aggregations": true + } + }, + { + "role": "importer", + "permission": { + "columns": [ + "id", + "name" + ], + "filter": {} + } + }, + { + "role": "recertifier", + "permission": { + "columns": [ + "id", + "name" + ], + "filter": {}, + "allow_aggregations": true + } + }, + { + "role": "reporter", + "permission": { + "columns": [ + "id", + "name" + ], + "filter": {}, + "allow_aggregations": true + } + }, + { + "role": "reporter-viewall", + "permission": { + "columns": [ + "id", + "name" + ], + "filter": {}, + "allow_aggregations": true + } + } + ] + }, + { + "table": { + "name": "recertification", + "schema": "public" + }, + "object_relationships": [ + { + "name": "owner", + "using": { + "foreign_key_constraint_on": "owner_id" + } + }, + { + "name": "owner_recertification", + "using": { + "foreign_key_constraint_on": "owner_recert_id" + } + }, + { + "name": "rule_metadatum", + "using": { + "foreign_key_constraint_on": "rule_metadata_id" + } + } + ], + "insert_permissions": [ + { + "role": "importer", + "permission": { + "check": {}, + "columns": [ + "comment", + "id", + "ip_match", + "next_recert_date", + "owner_id", + "rule_id", + "rule_metadata_id", + "user_dn" + ] + } + }, + { + "role": "middleware-server", + "permission": { + "check": {}, + "columns": [ + "id", + "owner_recert_id", + "rule_id", + "rule_metadata_id", + "recertified", + "comment", + "ip_match", + "user_dn", + "owner_id", + "next_recert_date", + "recert_date" + ] + } + }, + { + "role": "modeller", + "permission": { + "check": {}, + "columns": [ + "id", + "owner_recert_id", + "rule_id", + "rule_metadata_id", + "recertified", + "comment", + "ip_match", + "user_dn", + "owner_id", + "next_recert_date", + "recert_date" + ] + }, + "comment": "" + }, + { + "role": "recertifier", + "permission": { + "check": {}, + "columns": [ + "id", + "owner_recert_id", + "rule_id", + "rule_metadata_id", + "recertified", + "comment", + "ip_match", + "user_dn", + "owner_id", + "next_recert_date", + "recert_date" + ] + } + } + ], + "select_permissions": [ + { + "role": "auditor", + "permission": { + "columns": [ + "id", + "owner_recert_id", + "rule_id", + "rule_metadata_id", + "recertified", + "comment", + "ip_match", + "user_dn", + "owner_id", + "next_recert_date", + "recert_date" + ], + "filter": {}, + "allow_aggregations": true + } + }, + { + "role": "fw-admin", + "permission": { + "columns": [ + "id", + "owner_recert_id", + "rule_id", + "rule_metadata_id", + "recertified", + "comment", + "ip_match", + "user_dn", + "owner_id", + "next_recert_date", + "recert_date" + ], + "filter": {} + }, + "comment": "" + }, + { + "role": "middleware-server", + "permission": { + "columns": [ + "id", + "owner_recert_id", + "rule_id", + "rule_metadata_id", + "recertified", + "comment", + "ip_match", + "user_dn", + "owner_id", + "next_recert_date", + "recert_date" + ], + "filter": {} + } + }, + { + "role": "modeller", + "permission": { + "columns": [ + "id", + "owner_recert_id", + "rule_id", + "rule_metadata_id", + "recertified", + "comment", + "ip_match", + "user_dn", + "owner_id", + "next_recert_date", + "recert_date" + ], + "filter": {} + }, + "comment": "" + }, + { + "role": "recertifier", + "permission": { + "columns": [ + "id", + "owner_recert_id", + "rule_id", + "rule_metadata_id", + "recertified", + "comment", + "ip_match", + "user_dn", + "owner_id", + "next_recert_date", + "recert_date" + ], + "filter": {}, + "allow_aggregations": true + } + }, + { + "role": "reporter", + "permission": { + "columns": [ + "id", + "owner_recert_id", + "rule_id", + "rule_metadata_id", + "recertified", + "comment", + "ip_match", + "user_dn", + "owner_id", + "next_recert_date", + "recert_date" + ], + "filter": {}, + "allow_aggregations": true + } + }, + { + "role": "reporter-viewall", + "permission": { + "columns": [ + "id", + "owner_recert_id", + "rule_id", + "rule_metadata_id", + "recertified", + "comment", + "ip_match", + "user_dn", + "owner_id", + "next_recert_date", + "recert_date" + ], + "filter": {}, + "allow_aggregations": true + } + } + ], + "update_permissions": [ + { + "role": "modeller", + "permission": { + "columns": [ + "id", + "owner_recert_id", + "rule_id", + "rule_metadata_id", + "recertified", + "comment", + "ip_match", + "user_dn", + "owner_id", + "next_recert_date", + "recert_date" + ], + "filter": {}, + "check": {} + }, + "comment": "" + }, + { + "role": "recertifier", + "permission": { + "columns": [ + "id", + "owner_recert_id", + "rule_id", + "rule_metadata_id", + "recertified", + "comment", + "ip_match", + "user_dn", + "owner_id", + "next_recert_date", + "recert_date" + ], + "filter": {}, + "check": null + } + } + ], + "delete_permissions": [ + { + "role": "middleware-server", + "permission": { + "filter": {} + } + } + ] + }, + { + "table": { + "name": "refresh_log", + "schema": "public" + }, + "select_permissions": [ + { + "role": "middleware-server", + "permission": { + "columns": [ + "id", + "status", + "view_name", + "refreshed_at" + ], + "filter": {}, + "allow_aggregations": true + }, + "comment": "" + } + ] + }, + { + "table": { + "name": "report", + "schema": "public" + }, + "object_relationships": [ + { + "name": "owner", + "using": { + "foreign_key_constraint_on": "owner_id" + } + }, + { + "name": "report_template", + "using": { + "foreign_key_constraint_on": "report_template_id" + } + }, + { + "name": "tenant", + "using": { + "foreign_key_constraint_on": "tenant_wide_visible" + } + }, + { + "name": "uiuser", + "using": { + "foreign_key_constraint_on": "report_owner_id" + } + } + ], + "array_relationships": [ + { + "name": "owner_recertifications", + "using": { + "foreign_key_constraint_on": { + "column": "report_id", + "table": { + "name": "owner_recertification", + "schema": "public" + } + } + } + } + ], + "insert_permissions": [ + { + "role": "auditor", + "permission": { + "check": {}, + "columns": [ + "report_id", + "read_only", + "description", + "report_name", + "owner_id", + "report_owner_id", + "report_template_id", + "report_type", + "tenant_wide_visible", + "report_json", + "report_csv", + "report_html", + "report_pdf", + "report_end_time", + "report_start_time" + ] + } + }, + { + "role": "fw-admin", + "permission": { + "check": {}, + "columns": [ + "report_id", + "read_only", + "description", + "report_name", + "owner_id", + "report_owner_id", + "report_template_id", + "report_type", + "tenant_wide_visible", + "report_json", + "report_csv", + "report_html", + "report_pdf", + "report_end_time", + "report_start_time" + ] + } + }, + { + "role": "middleware-server", + "permission": { + "check": {}, + "columns": [ + "report_id", + "read_only", + "description", + "report_name", + "owner_id", + "report_owner_id", + "report_template_id", + "report_type", + "tenant_wide_visible", + "report_json", + "report_csv", + "report_html", + "report_pdf", + "report_end_time", + "report_start_time" + ] + } + }, + { + "role": "modeller", + "permission": { + "check": {}, + "columns": [ + "report_id", + "read_only", + "description", + "report_name", + "owner_id", + "report_owner_id", + "report_template_id", + "report_type", + "tenant_wide_visible", + "report_json", + "report_csv", + "report_html", + "report_pdf", + "report_end_time", + "report_start_time" + ] + }, + "comment": "" + }, + { + "role": "recertifier", + "permission": { + "check": {}, + "columns": [ + "report_id", + "read_only", + "description", + "report_name", + "owner_id", + "report_owner_id", + "report_template_id", + "report_type", + "tenant_wide_visible", + "report_json", + "report_csv", + "report_html", + "report_pdf", + "report_end_time", + "report_start_time" + ] + } + }, + { + "role": "reporter", + "permission": { + "check": {}, + "columns": [ + "report_id", + "read_only", + "description", + "report_name", + "owner_id", + "report_owner_id", + "report_template_id", + "report_type", + "tenant_wide_visible", + "report_json", + "report_csv", + "report_html", + "report_pdf", + "report_end_time", + "report_start_time" + ] + } + }, + { + "role": "reporter-viewall", + "permission": { + "check": {}, + "columns": [ + "report_id", + "read_only", + "description", + "report_name", + "owner_id", + "report_owner_id", + "report_template_id", + "report_type", + "tenant_wide_visible", + "report_json", + "report_csv", + "report_html", + "report_pdf", + "report_end_time", + "report_start_time" + ] + } + } + ], + "select_permissions": [ + { + "role": "auditor", + "permission": { + "columns": [ + "report_id", + "read_only", + "description", + "report_name", + "owner_id", + "report_owner_id", + "report_template_id", + "report_type", + "tenant_wide_visible", + "report_json", + "report_csv", + "report_html", + "report_pdf", + "report_end_time", + "report_start_time" + ], + "filter": {} + } + }, + { + "role": "fw-admin", + "permission": { + "columns": [ + "description", + "owner_id", + "read_only", + "report_csv", + "report_end_time", + "report_html", + "report_id", + "report_json", + "report_name", + "report_owner_id", + "report_pdf", + "report_start_time", + "report_template_id", + "report_type", + "tenant_wide_visible" + ], + "filter": { + "_or": [ + { + "report_owner_id": { + "_eq": "X-Hasura-User-Id" + } + }, + { + "owner_id": { + "_in": "x-hasura-editable-owners" + } + } + ] + }, + "allow_aggregations": true + } + }, + { + "role": "modeller", + "permission": { + "columns": [ + "description", + "owner_id", + "read_only", + "report_csv", + "report_end_time", + "report_html", + "report_id", + "report_json", + "report_name", + "report_owner_id", + "report_pdf", + "report_start_time", + "report_template_id", + "report_type", + "tenant_wide_visible" + ], + "filter": { + "_or": [ + { + "report_owner_id": { + "_eq": "X-Hasura-User-Id" + } + }, + { + "owner_id": { + "_in": "x-hasura-editable-owners" + } + } + ] + }, + "allow_aggregations": true + } + }, + { + "role": "recertifier", + "permission": { + "columns": [ + "report_id", + "read_only", + "description", + "report_name", + "owner_id", + "report_owner_id", + "report_template_id", + "report_type", + "tenant_wide_visible", + "report_json", + "report_csv", + "report_html", + "report_pdf", + "report_end_time", + "report_start_time" + ], + "filter": { + "_or": [ + { + "report_owner_id": { + "_eq": "X-Hasura-User-Id" + } + }, + { + "owner_id": { + "_in": "x-hasura-editable-owners" + } + } + ] + }, + "allow_aggregations": true + } + }, + { + "role": "reporter", + "permission": { + "columns": [ + "description", + "owner_id", + "read_only", + "report_csv", + "report_end_time", + "report_html", + "report_id", + "report_json", + "report_name", + "report_owner_id", + "report_pdf", + "report_start_time", + "report_template_id", + "report_type", + "tenant_wide_visible" + ], + "filter": { + "_or": [ + { + "report_owner_id": { + "_eq": "X-Hasura-User-Id" + } + }, + { + "owner_id": { + "_in": "x-hasura-editable-owners" + } + } + ] + }, + "allow_aggregations": true + } + }, + { + "role": "reporter-viewall", + "permission": { + "columns": [ + "description", + "owner_id", + "read_only", + "report_csv", + "report_end_time", + "report_html", + "report_id", + "report_json", + "report_name", + "report_owner_id", + "report_pdf", + "report_start_time", + "report_template_id", + "report_type", + "tenant_wide_visible" + ], + "filter": { + "_or": [ + { + "report_owner_id": { + "_eq": "X-Hasura-User-Id" + } + }, + { + "owner_id": { + "_in": "x-hasura-editable-owners" + } + } + ] + }, + "allow_aggregations": true + } + } + ], + "update_permissions": [ + { + "role": "auditor", + "permission": { + "columns": [ + "report_owner_id", + "report_template_id", + "report_type", + "description", + "tenant_wide_visible", + "report_id", + "report_json", + "report_csv", + "report_html", + "report_pdf", + "report_end_time", + "report_start_time", + "report_name" + ], + "filter": { + "report_owner_id": { + "_eq": "X-Hasura-User-Id" + } + }, + "check": null + } + }, + { + "role": "fw-admin", + "permission": { + "columns": [ + "report_pdf", + "report_owner_id", + "report_template_id", + "report_type", + "description", + "tenant_wide_visible", + "report_id", + "report_json", + "report_csv", + "report_html", + "report_end_time", + "report_start_time", + "report_name" + ], + "filter": { + "report_owner_id": { + "_eq": "X-Hasura-User-Id" + } + }, + "check": null + } + }, + { + "role": "modeller", + "permission": { + "columns": [ + "report_pdf", + "report_owner_id", + "report_template_id", + "report_type", + "description", + "tenant_wide_visible", + "report_id", + "report_json", + "report_csv", + "report_html", + "report_end_time", + "report_start_time", + "report_name" + ], + "filter": { + "report_owner_id": { + "_eq": "X-Hasura-User-Id" + } + }, + "check": null + } + }, + { + "role": "recertifier", + "permission": { + "columns": [ + "report_pdf", + "report_owner_id", + "report_template_id", + "report_type", + "description", + "tenant_wide_visible", + "report_id", + "report_json", + "report_csv", + "report_html", + "report_end_time", + "report_start_time", + "report_name" + ], + "filter": { + "report_owner_id": { + "_eq": "X-Hasura-User-Id" + } + }, + "check": null + } + }, + { + "role": "reporter", + "permission": { + "columns": [ + "report_pdf", + "report_owner_id", + "report_template_id", + "report_type", + "description", + "tenant_wide_visible", + "report_id", + "report_json", + "report_csv", + "report_html", + "report_end_time", + "report_start_time", + "report_name" + ], + "filter": { + "report_owner_id": { + "_eq": "X-Hasura-User-Id" + } + }, + "check": null + } + }, + { + "role": "reporter-viewall", + "permission": { + "columns": [ + "report_pdf", + "report_owner_id", + "report_template_id", + "report_type", + "description", + "tenant_wide_visible", + "report_id", + "report_json", + "report_csv", + "report_html", + "report_end_time", + "report_start_time", + "report_name" + ], + "filter": { + "report_owner_id": { + "_eq": "X-Hasura-User-Id" + } + }, + "check": null + } + } + ], + "delete_permissions": [ + { + "role": "auditor", + "permission": { + "filter": { + "report_owner_id": { + "_eq": "X-Hasura-User-Id" + } + } + } + }, + { + "role": "fw-admin", + "permission": { + "filter": { + "report_owner_id": { + "_eq": "X-Hasura-User-Id" + } + } + } + }, + { + "role": "modeller", + "permission": { + "filter": { + "report_owner_id": { + "_eq": "X-Hasura-User-Id" + } + } + } + }, + { + "role": "recertifier", + "permission": { + "filter": { + "report_owner_id": { + "_eq": "X-Hasura-User-Id" + } + } + } + }, + { + "role": "reporter", + "permission": { + "filter": { + "report_owner_id": { + "_eq": "X-Hasura-User-Id" + } + } + } + }, + { + "role": "reporter-viewall", + "permission": { + "filter": { + "report_owner_id": { + "_eq": "X-Hasura-User-Id" + } + } + } + } + ] + }, + { + "table": { + "name": "report_format", + "schema": "public" + }, + "array_relationships": [ + { + "name": "report_schedule_formats", + "using": { + "foreign_key_constraint_on": { + "column": "report_schedule_format_name", + "table": { + "name": "report_schedule_format", + "schema": "public" + } + } + } + } + ], + "select_permissions": [ + { + "role": "auditor", + "permission": { + "columns": [ + "report_format_name" + ], + "filter": {} + } + }, + { + "role": "fw-admin", + "permission": { + "columns": [ + "report_format_name" + ], + "filter": {} + } + }, + { + "role": "middleware-server", + "permission": { + "columns": [ + "report_format_name" + ], + "filter": {} + } + }, + { + "role": "recertifier", + "permission": { + "columns": [ + "report_format_name" + ], + "filter": {} + } + }, + { + "role": "reporter", + "permission": { + "columns": [ + "report_format_name" + ], + "filter": {} + } + }, + { + "role": "reporter-viewall", + "permission": { + "columns": [ + "report_format_name" + ], + "filter": {} + } + } + ] + }, + { + "table": { + "name": "report_schedule", + "schema": "public" + }, + "object_relationships": [ + { + "name": "report_template", + "using": { + "foreign_key_constraint_on": "report_template_id" + } + }, + { + "name": "uiuser", + "using": { + "foreign_key_constraint_on": "report_schedule_owner" + } + } + ], + "array_relationships": [ + { + "name": "notifications", + "using": { + "foreign_key_constraint_on": { + "column": "schedule_id", + "table": { + "name": "notification", + "schema": "public" + } + } + } + }, + { + "name": "report_schedule_formats", + "using": { + "foreign_key_constraint_on": { + "column": "report_schedule_id", + "table": { + "name": "report_schedule_format", + "schema": "public" + } + } + } + } + ], + "insert_permissions": [ + { + "role": "auditor", + "permission": { + "check": {}, + "columns": [ + "archive", + "report_schedule_active", + "report_schedule_every", + "report_schedule_id", + "report_schedule_name", + "report_schedule_owner", + "report_schedule_repeat", + "report_schedule_repetitions", + "report_schedule_start_time", + "report_schedule_counter", + "report_template_id" + ] + } + }, + { + "role": "fw-admin", + "permission": { + "check": {}, + "columns": [ + "archive", + "report_schedule_active", + "report_schedule_every", + "report_schedule_id", + "report_schedule_name", + "report_schedule_owner", + "report_schedule_repeat", + "report_schedule_repetitions", + "report_schedule_start_time", + "report_schedule_counter", + "report_template_id" + ] + } + }, + { + "role": "modeller", + "permission": { + "check": {}, + "columns": [ + "archive", + "report_schedule_id", + "report_schedule_active", + "report_schedule_name", + "report_schedule_counter", + "report_schedule_every", + "report_schedule_owner", + "report_schedule_repeat", + "report_schedule_repetitions", + "report_template_id", + "report_schedule_start_time" + ] + }, + "comment": "" + }, + { + "role": "recertifier", + "permission": { + "check": {}, + "columns": [ + "archive", + "report_schedule_active", + "report_schedule_every", + "report_schedule_id", + "report_schedule_name", + "report_schedule_owner", + "report_schedule_repeat", + "report_schedule_repetitions", + "report_schedule_start_time", + "report_schedule_counter", + "report_template_id" + ] + } + }, + { + "role": "reporter", + "permission": { + "check": {}, + "columns": [ + "archive", + "report_schedule_active", + "report_schedule_every", + "report_schedule_id", + "report_schedule_name", + "report_schedule_owner", + "report_schedule_repeat", + "report_schedule_repetitions", + "report_schedule_start_time", + "report_schedule_counter", + "report_template_id" + ] + } + }, + { + "role": "reporter-viewall", + "permission": { + "check": {}, + "columns": [ + "archive", + "report_schedule_active", + "report_schedule_every", + "report_schedule_id", + "report_schedule_name", + "report_schedule_owner", + "report_schedule_repeat", + "report_schedule_repetitions", + "report_schedule_start_time", + "report_schedule_counter", + "report_template_id" + ] + } + } + ], + "select_permissions": [ + { + "role": "auditor", + "permission": { + "columns": [ + "archive", + "report_schedule_id", + "report_schedule_name", + "report_template_id", + "report_schedule_owner", + "report_schedule_start_time", + "report_schedule_repeat", + "report_schedule_every", + "report_schedule_active", + "report_schedule_counter", + "report_schedule_repetitions" + ], + "filter": {} + } + }, + { + "role": "fw-admin", + "permission": { + "columns": [ + "archive", + "report_schedule_active", + "report_schedule_every", + "report_schedule_id", + "report_schedule_name", + "report_schedule_owner", + "report_schedule_repeat", + "report_schedule_repetitions", + "report_schedule_start_time", + "report_schedule_counter", + "report_template_id" + ], + "filter": { + "_or": [ + { + "report_schedule_owner": { + "_eq": "X-Hasura-User-Id" + } + }, + { + "_exists": { + "_table": { + "name": "report_template_viewable_by_user", + "schema": "public" + }, + "_where": { + "uiuser_id": { + "_eq": "X-Hasura-User-Id" + } + } + } + } + ] + } + } + }, + { + "role": "middleware-server", + "permission": { + "columns": [ + "archive", + "report_schedule_id", + "report_schedule_name", + "report_template_id", + "report_schedule_owner", + "report_schedule_start_time", + "report_schedule_repeat", + "report_schedule_every", + "report_schedule_active", + "report_schedule_counter", + "report_schedule_repetitions" + ], + "filter": {}, + "allow_aggregations": true + } + }, + { + "role": "modeller", + "permission": { + "columns": [ + "archive", + "report_schedule_active", + "report_schedule_every", + "report_schedule_id", + "report_schedule_name", + "report_schedule_owner", + "report_schedule_repeat", + "report_schedule_repetitions", + "report_schedule_start_time", + "report_schedule_counter", + "report_template_id" + ], + "filter": { + "report_schedule_owner": { + "_eq": "X-Hasura-User-Id" + } + } + } + }, + { + "role": "recertifier", + "permission": { + "columns": [ + "archive", + "report_schedule_active", + "report_schedule_every", + "report_schedule_id", + "report_schedule_name", + "report_schedule_owner", + "report_schedule_repeat", + "report_schedule_repetitions", + "report_schedule_start_time", + "report_schedule_counter", + "report_template_id" + ], + "filter": { + "report_schedule_owner": { + "_eq": "X-Hasura-User-Id" + } + } + } + }, + { + "role": "reporter", + "permission": { + "columns": [ + "archive", + "report_schedule_active", + "report_schedule_every", + "report_schedule_id", + "report_schedule_name", + "report_schedule_owner", + "report_schedule_repeat", + "report_schedule_repetitions", + "report_schedule_start_time", + "report_schedule_counter", + "report_template_id" + ], + "filter": { + "report_schedule_owner": { + "_eq": "X-Hasura-User-Id" + } + } + } + }, + { + "role": "reporter-viewall", + "permission": { + "columns": [ + "archive", + "report_schedule_active", + "report_schedule_every", + "report_schedule_id", + "report_schedule_name", + "report_schedule_owner", + "report_schedule_repeat", + "report_schedule_repetitions", + "report_schedule_start_time", + "report_schedule_counter", + "report_template_id" + ], + "filter": { + "_or": [ + { + "report_schedule_owner": { + "_eq": "X-Hasura-User-Id" + } + }, + { + "_exists": { + "_table": { + "name": "report_template_viewable_by_user", + "schema": "public" + }, + "_where": { + "uiuser_id": { + "_eq": "X-Hasura-User-Id" + } + } + } + } + ] + } + } + } + ], + "update_permissions": [ + { + "role": "auditor", + "permission": { + "columns": [ + "archive", + "report_schedule_active", + "report_schedule_every", + "report_schedule_id", + "report_schedule_name", + "report_schedule_owner", + "report_schedule_repeat", + "report_schedule_start_time", + "report_schedule_counter", + "report_template_id" + ], + "filter": { + "report_schedule_owner": { + "_eq": "X-Hasura-User-Id" + } + }, + "check": null + } + }, + { + "role": "fw-admin", + "permission": { + "columns": [ + "archive", + "report_schedule_active", + "report_schedule_every", + "report_schedule_id", + "report_schedule_name", + "report_schedule_owner", + "report_schedule_repeat", + "report_schedule_repetitions", + "report_schedule_start_time", + "report_schedule_counter", + "report_template_id" + ], + "filter": { + "report_schedule_owner": { + "_eq": "X-Hasura-User-Id" + } + }, + "check": null + } + }, + { + "role": "modeller", + "permission": { + "columns": [ + "archive", + "report_schedule_active", + "report_schedule_every", + "report_schedule_id", + "report_schedule_name", + "report_schedule_owner", + "report_schedule_repeat", + "report_schedule_repetitions", + "report_schedule_start_time", + "report_schedule_counter", + "report_template_id" + ], + "filter": { + "report_schedule_owner": { + "_eq": "X-Hasura-User-Id" + } + }, + "check": null + } + }, + { + "role": "recertifier", + "permission": { + "columns": [ + "archive", + "report_schedule_active", + "report_schedule_every", + "report_schedule_id", + "report_schedule_name", + "report_schedule_owner", + "report_schedule_repeat", + "report_schedule_repetitions", + "report_schedule_start_time", + "report_schedule_counter", + "report_template_id" + ], + "filter": { + "report_schedule_owner": { + "_eq": "X-Hasura-User-Id" + } + }, + "check": null + } + }, + { + "role": "reporter", + "permission": { + "columns": [ + "archive", + "report_schedule_active", + "report_schedule_every", + "report_schedule_id", + "report_schedule_name", + "report_schedule_owner", + "report_schedule_repeat", + "report_schedule_repetitions", + "report_schedule_start_time", + "report_schedule_counter", + "report_template_id" + ], + "filter": { + "report_schedule_owner": { + "_eq": "X-Hasura-User-Id" + } + }, + "check": null + } + }, + { + "role": "reporter-viewall", + "permission": { + "columns": [ + "archive", + "report_schedule_active", + "report_schedule_every", + "report_schedule_id", + "report_schedule_name", + "report_schedule_owner", + "report_schedule_repeat", + "report_schedule_repetitions", + "report_schedule_start_time", + "report_schedule_counter", + "report_template_id" + ], + "filter": { + "report_schedule_owner": { + "_eq": "X-Hasura-User-Id" + } + }, + "check": null + } + } + ], + "delete_permissions": [ + { + "role": "auditor", + "permission": { + "filter": { + "report_schedule_owner": { + "_eq": "X-Hasura-User-Id" + } + } + } + }, + { + "role": "fw-admin", + "permission": { + "filter": { + "report_schedule_owner": { + "_eq": "X-Hasura-User-Id" + } + } + } + }, + { + "role": "modeller", + "permission": { + "filter": { + "report_schedule_owner": { + "_eq": "X-Hasura-User-Id" + } + } + } + }, + { + "role": "recertifier", + "permission": { + "filter": { + "report_schedule_owner": { + "_eq": "X-Hasura-User-Id" + } + } + } + }, + { + "role": "reporter", + "permission": { + "filter": { + "report_schedule_owner": { + "_eq": "X-Hasura-User-Id" + } + } + } + }, + { + "role": "reporter-viewall", + "permission": { + "filter": { + "report_schedule_owner": { + "_eq": "X-Hasura-User-Id" + } + } + } + } + ] + }, + { + "table": { + "name": "report_schedule_format", + "schema": "public" + }, + "object_relationships": [ + { + "name": "report_format", + "using": { + "foreign_key_constraint_on": "report_schedule_format_name" + } + }, + { + "name": "report_schedule", + "using": { + "foreign_key_constraint_on": "report_schedule_id" + } + } + ], + "insert_permissions": [ + { + "role": "auditor", + "permission": { + "check": { + "report_schedule": { + "report_schedule_owner": { + "_eq": "X-Hasura-User-Id" + } + } + }, + "columns": [ + "report_schedule_format_name", + "report_schedule_id" + ] + } + }, + { + "role": "fw-admin", + "permission": { + "check": { + "report_schedule": { + "report_schedule_owner": { + "_eq": "X-Hasura-User-Id" + } + } + }, + "columns": [ + "report_schedule_format_name", + "report_schedule_id" + ] + } + }, + { + "role": "modeller", + "permission": { + "check": { + "report_schedule": { + "report_schedule_owner": { + "_eq": "X-Hasura-User-Id" + } + } + }, + "columns": [ + "report_schedule_format_name", + "report_schedule_id" + ] + } + }, + { + "role": "recertifier", + "permission": { + "check": { + "report_schedule": { + "report_schedule_owner": { + "_eq": "X-Hasura-User-Id" + } + } + }, + "columns": [ + "report_schedule_format_name", + "report_schedule_id" + ] + } + }, + { + "role": "reporter", + "permission": { + "check": { + "report_schedule": { + "report_schedule_owner": { + "_eq": "X-Hasura-User-Id" + } + } + }, + "columns": [ + "report_schedule_format_name", + "report_schedule_id" + ] + } + }, + { + "role": "reporter-viewall", + "permission": { + "check": { + "report_schedule": { + "report_schedule_owner": { + "_eq": "X-Hasura-User-Id" + } + } + }, + "columns": [ + "report_schedule_format_name", + "report_schedule_id" + ] + } + } + ], + "select_permissions": [ + { + "role": "auditor", + "permission": { + "columns": [ + "report_schedule_format_name", + "report_schedule_id" + ], + "filter": {} + } + }, + { + "role": "fw-admin", + "permission": { + "columns": [ + "report_schedule_format_name", + "report_schedule_id" + ], + "filter": { + "report_schedule": { + "report_schedule_owner": { + "_eq": "X-Hasura-User-Id" + } + } + } + } + }, + { + "role": "middleware-server", + "permission": { + "columns": [ + "report_schedule_format_name", + "report_schedule_id" + ], + "filter": {} + } + }, + { + "role": "modeller", + "permission": { + "columns": [ + "report_schedule_format_name", + "report_schedule_id" + ], + "filter": { + "report_schedule": { + "report_schedule_owner": { + "_eq": "X-Hasura-User-Id" + } + } + } + } + }, + { + "role": "recertifier", + "permission": { + "columns": [ + "report_schedule_format_name", + "report_schedule_id" + ], + "filter": { + "report_schedule": { + "report_schedule_owner": { + "_eq": "X-Hasura-User-Id" + } + } + } + } + }, + { + "role": "reporter", + "permission": { + "columns": [ + "report_schedule_format_name", + "report_schedule_id" + ], + "filter": { + "report_schedule": { + "report_schedule_owner": { + "_eq": "X-Hasura-User-Id" + } + } + } + } + }, + { + "role": "reporter-viewall", + "permission": { + "columns": [ + "report_schedule_format_name", + "report_schedule_id" + ], + "filter": { + "report_schedule": { + "report_schedule_owner": { + "_eq": "X-Hasura-User-Id" + } + } + } + } + } + ], + "update_permissions": [ + { + "role": "auditor", + "permission": { + "columns": [ + "report_schedule_id", + "report_schedule_format_name" + ], + "filter": { + "report_schedule": { + "report_schedule_owner": { + "_eq": "X-Hasura-User-Id" + } + } + }, + "check": null + } + }, + { + "role": "fw-admin", + "permission": { + "columns": [ + "report_schedule_format_name", + "report_schedule_id" + ], + "filter": { + "report_schedule": { + "report_schedule_owner": { + "_eq": "X-Hasura-User-Id" + } + } + }, + "check": { + "report_schedule": { + "report_schedule_owner": { + "_eq": "X-Hasura-User-Id" + } + } + } + } + }, + { + "role": "modeller", + "permission": { + "columns": [ + "report_schedule_format_name", + "report_schedule_id" + ], + "filter": { + "report_schedule": { + "report_schedule_owner": { + "_eq": "X-Hasura-User-Id" + } + } + }, + "check": { + "report_schedule": { + "report_schedule_owner": { + "_eq": "X-Hasura-User-Id" + } + } + } + } + }, + { + "role": "recertifier", + "permission": { + "columns": [ + "report_schedule_format_name", + "report_schedule_id" + ], + "filter": { + "report_schedule": { + "report_schedule_owner": { + "_eq": "X-Hasura-User-Id" + } + } + }, + "check": { + "report_schedule": { + "report_schedule_owner": { + "_eq": "X-Hasura-User-Id" + } + } + } + } + }, + { + "role": "reporter", + "permission": { + "columns": [ + "report_schedule_format_name", + "report_schedule_id" + ], + "filter": { + "report_schedule": { + "report_schedule_owner": { + "_eq": "X-Hasura-User-Id" + } + } + }, + "check": { + "report_schedule": { + "report_schedule_owner": { + "_eq": "X-Hasura-User-Id" + } + } + } + } + }, + { + "role": "reporter-viewall", + "permission": { + "columns": [ + "report_schedule_format_name", + "report_schedule_id" + ], + "filter": { + "report_schedule": { + "report_schedule_owner": { + "_eq": "X-Hasura-User-Id" + } + } + }, + "check": { + "report_schedule": { + "report_schedule_owner": { + "_eq": "X-Hasura-User-Id" + } + } + } + } + } + ], + "delete_permissions": [ + { + "role": "auditor", + "permission": { + "filter": { + "report_schedule": { + "report_schedule_owner": { + "_eq": "X-Hasura-User-Id" + } + } + } + } + }, + { + "role": "fw-admin", + "permission": { + "filter": { + "report_schedule": { + "report_schedule_owner": { + "_eq": "X-Hasura-User-Id" + } + } + } + } + }, + { + "role": "modeller", + "permission": { + "filter": { + "report_schedule": { + "report_schedule_owner": { + "_eq": "X-Hasura-User-Id" + } + } + } + } + }, + { + "role": "recertifier", + "permission": { + "filter": { + "report_schedule": { + "report_schedule_owner": { + "_eq": "X-Hasura-User-Id" + } + } + } + } + }, + { + "role": "reporter", + "permission": { + "filter": { + "report_schedule": { + "report_schedule_owner": { + "_eq": "X-Hasura-User-Id" + } + } + } + } + }, + { + "role": "reporter-viewall", + "permission": { + "filter": { + "report_schedule": { + "report_schedule_owner": { + "_eq": "X-Hasura-User-Id" + } + } + } + } + } + ] + }, + { + "table": { + "name": "report_template", + "schema": "public" + }, + "object_relationships": [ + { + "name": "uiuser", + "using": { + "foreign_key_constraint_on": "report_template_owner" + } + } + ], + "array_relationships": [ + { + "name": "report_schedules", + "using": { + "foreign_key_constraint_on": { + "column": "report_template_id", + "table": { + "name": "report_schedule", + "schema": "public" + } + } + } + }, + { + "name": "report_template_viewable_by_users", + "using": { + "foreign_key_constraint_on": { + "column": "report_template_id", + "table": { + "name": "report_template_viewable_by_user", + "schema": "public" + } + } + } + }, + { + "name": "reports", + "using": { + "foreign_key_constraint_on": { + "column": "report_template_id", + "table": { + "name": "report", + "schema": "public" + } + } + } + } + ], + "insert_permissions": [ + { + "role": "auditor", + "permission": { + "check": {}, + "columns": [ + "filterline_history", + "report_filter", + "report_parameters", + "report_template_comment", + "report_template_create", + "report_template_id", + "report_template_name", + "report_template_owner" + ] + } + }, + { + "role": "fw-admin", + "permission": { + "check": {}, + "columns": [ + "filterline_history", + "report_filter", + "report_parameters", + "report_template_comment", + "report_template_create", + "report_template_id", + "report_template_name", + "report_template_owner" + ] + } + }, + { + "role": "modeller", + "permission": { + "check": {}, + "columns": [ + "filterline_history", + "report_filter", + "report_template_name", + "report_template_id", + "report_template_owner", + "report_parameters", + "report_template_comment", + "report_template_create" + ] + }, + "comment": "" + }, + { + "role": "recertifier", + "permission": { + "check": {}, + "columns": [ + "filterline_history", + "report_filter", + "report_parameters", + "report_template_comment", + "report_template_create", + "report_template_id", + "report_template_name", + "report_template_owner" + ] + } + }, + { + "role": "reporter", + "permission": { + "check": {}, + "columns": [ + "filterline_history", + "report_filter", + "report_parameters", + "report_template_comment", + "report_template_create", + "report_template_id", + "report_template_name", + "report_template_owner" + ] + } + }, + { + "role": "reporter-viewall", + "permission": { + "check": {}, + "columns": [ + "filterline_history", + "report_filter", + "report_parameters", + "report_template_comment", + "report_template_create", + "report_template_id", + "report_template_name", + "report_template_owner" + ] + } + } + ], + "select_permissions": [ + { + "role": "auditor", + "permission": { + "columns": [ + "filterline_history", + "report_filter", + "report_parameters", + "report_template_comment", + "report_template_create", + "report_template_id", + "report_template_name", + "report_template_owner" + ], + "filter": {} + } + }, + { + "role": "fw-admin", + "permission": { + "columns": [ + "filterline_history", + "report_filter", + "report_parameters", + "report_template_comment", + "report_template_create", + "report_template_id", + "report_template_name", + "report_template_owner" + ], + "filter": { + "_or": [ + { + "report_template_owner": { + "_eq": 0 + } + }, + { + "report_template_owner": { + "_eq": "X-Hasura-User-Id" + } + } + ] + } + } + }, + { + "role": "middleware-server", + "permission": { + "columns": [ + "filterline_history", + "report_filter", + "report_parameters", + "report_template_comment", + "report_template_create", + "report_template_id", + "report_template_name", + "report_template_owner" + ], + "filter": {}, + "allow_aggregations": true + } + }, + { + "role": "modeller", + "permission": { + "columns": [ + "filterline_history", + "report_filter", + "report_parameters", + "report_template_comment", + "report_template_create", + "report_template_id", + "report_template_name", + "report_template_owner" + ], + "filter": { + "_or": [ + { + "report_template_owner": { + "_eq": 0 + } + }, + { + "report_template_owner": { + "_eq": "X-Hasura-User-Id" + } + } + ] + } + } + }, + { + "role": "recertifier", + "permission": { + "columns": [ + "filterline_history", + "report_filter", + "report_parameters", + "report_template_comment", + "report_template_create", + "report_template_id", + "report_template_name", + "report_template_owner" + ], + "filter": { + "_or": [ + { + "report_template_owner": { + "_eq": 0 + } + }, + { + "report_template_owner": { + "_eq": "X-Hasura-User-Id" + } + } + ] + } + } + }, + { + "role": "reporter", + "permission": { + "columns": [ + "filterline_history", + "report_filter", + "report_parameters", + "report_template_comment", + "report_template_create", + "report_template_id", + "report_template_name", + "report_template_owner" + ], + "filter": { + "_or": [ + { + "report_template_owner": { + "_eq": 0 + } + }, + { + "report_template_owner": { + "_eq": "X-Hasura-User-Id" + } + } + ] + } + } + }, + { + "role": "reporter-viewall", + "permission": { + "columns": [ + "filterline_history", + "report_filter", + "report_parameters", + "report_template_comment", + "report_template_create", + "report_template_id", + "report_template_name", + "report_template_owner" + ], + "filter": { + "_or": [ + { + "report_template_owner": { + "_eq": 0 + } + }, + { + "report_template_owner": { + "_eq": "X-Hasura-User-Id" + } + } + ] + } + } + } + ], + "update_permissions": [ + { + "role": "auditor", + "permission": { + "columns": [ + "filterline_history", + "report_filter", + "report_parameters", + "report_template_comment", + "report_template_create", + "report_template_id", + "report_template_name", + "report_template_owner" + ], + "filter": { + "report_template_owner": { + "_eq": "X-Hasura-User-Id" + } + }, + "check": null + } + }, + { + "role": "fw-admin", + "permission": { + "columns": [ + "filterline_history", + "report_filter", + "report_parameters", + "report_template_comment", + "report_template_create", + "report_template_id", + "report_template_name", + "report_template_owner" + ], + "filter": { + "report_template_owner": { + "_eq": "X-Hasura-User-Id" + } + }, + "check": null + } + }, + { + "role": "modeller", + "permission": { + "columns": [ + "filterline_history", + "report_filter", + "report_parameters", + "report_template_comment", + "report_template_create", + "report_template_id", + "report_template_name", + "report_template_owner" + ], + "filter": { + "report_template_owner": { + "_eq": "X-Hasura-User-Id" + } + }, + "check": null + } + }, + { + "role": "recertifier", + "permission": { + "columns": [ + "filterline_history", + "report_filter", + "report_parameters", + "report_template_comment", + "report_template_create", + "report_template_id", + "report_template_name", + "report_template_owner" + ], + "filter": { + "report_template_owner": { + "_eq": "X-Hasura-User-Id" + } + }, + "check": null + } + }, + { + "role": "reporter", + "permission": { + "columns": [ + "filterline_history", + "report_filter", + "report_parameters", + "report_template_comment", + "report_template_create", + "report_template_id", + "report_template_name", + "report_template_owner" + ], + "filter": { + "report_template_owner": { + "_eq": "X-Hasura-User-Id" + } + }, + "check": null + } + }, + { + "role": "reporter-viewall", + "permission": { + "columns": [ + "filterline_history", + "report_filter", + "report_parameters", + "report_template_comment", + "report_template_create", + "report_template_id", + "report_template_name", + "report_template_owner" + ], + "filter": { + "report_template_owner": { + "_eq": "X-Hasura-User-Id" + } + }, + "check": null + } + } + ], + "delete_permissions": [ + { + "role": "auditor", + "permission": { + "filter": { + "report_template_owner": { + "_eq": "X-Hasura-User-Id" + } + } + } + }, + { + "role": "fw-admin", + "permission": { + "filter": { + "report_template_owner": { + "_eq": "X-Hasura-User-Id" + } + } + } + }, + { + "role": "modeller", + "permission": { + "filter": { + "report_template_owner": { + "_eq": "X-Hasura-User-Id" + } + } + } + }, + { + "role": "recertifier", + "permission": { + "filter": { + "report_template_owner": { + "_eq": "X-Hasura-User-Id" + } + } + } + }, + { + "role": "reporter", + "permission": { + "filter": { + "report_template_owner": { + "_eq": "X-Hasura-User-Id" + } + } + } + }, + { + "role": "reporter-viewall", + "permission": { + "filter": { + "report_template_owner": { + "_eq": "X-Hasura-User-Id" + } + } + } + } + ] + }, + { + "table": { + "name": "report_template_viewable_by_user", + "schema": "public" + }, + "object_relationships": [ + { + "name": "report_template", + "using": { + "foreign_key_constraint_on": "report_template_id" + } + }, + { + "name": "uiuser", + "using": { + "foreign_key_constraint_on": "uiuser_id" + } + } + ] + }, + { + "table": { + "name": "reqtask_owner", + "schema": "public" + }, + "object_relationships": [ + { + "name": "owner", + "using": { + "foreign_key_constraint_on": "owner_id" + } + }, + { + "name": "reqtask", + "using": { + "foreign_key_constraint_on": "reqtask_id" + } + } + ], + "insert_permissions": [ + { + "role": "approver", + "permission": { + "check": {}, + "columns": [ + "reqtask_id", + "owner_id" + ] + }, + "comment": "" + }, + { + "role": "implementer", + "permission": { + "check": {}, + "columns": [ + "reqtask_id", + "owner_id" + ] + }, + "comment": "" + }, + { + "role": "modeller", + "permission": { + "check": {}, + "columns": [ + "reqtask_id", + "owner_id" + ] + }, + "comment": "" + }, + { + "role": "planner", + "permission": { + "check": {}, + "columns": [ + "reqtask_id", + "owner_id" + ] + }, + "comment": "" + }, + { + "role": "requester", + "permission": { + "check": {}, + "columns": [ + "reqtask_id", + "owner_id" + ] + }, + "comment": "" + } + ], + "select_permissions": [ + { + "role": "approver", + "permission": { + "columns": [ + "reqtask_id", + "owner_id" + ], + "filter": {} + } + }, + { + "role": "auditor", + "permission": { + "columns": [ + "reqtask_id", + "owner_id" + ], + "filter": {} + } + }, + { + "role": "fw-admin", + "permission": { + "columns": [ + "reqtask_id", + "owner_id" + ], + "filter": {} + } + }, + { + "role": "implementer", + "permission": { + "columns": [ + "reqtask_id", + "owner_id" + ], + "filter": {} + } + }, + { + "role": "middleware-server", + "permission": { + "columns": [ + "reqtask_id", + "owner_id" + ], + "filter": {} + }, + "comment": "" + }, + { + "role": "modeller", + "permission": { + "columns": [ + "reqtask_id", + "owner_id" + ], + "filter": {} + }, + "comment": "" + }, + { + "role": "planner", + "permission": { + "columns": [ + "reqtask_id", + "owner_id" + ], + "filter": {} + } + }, + { + "role": "requester", + "permission": { + "columns": [ + "reqtask_id", + "owner_id" + ], + "filter": {} + } + }, + { + "role": "reviewer", + "permission": { + "columns": [ + "reqtask_id", + "owner_id" + ], + "filter": {} + } + } + ], + "delete_permissions": [ + { + "role": "approver", + "permission": { + "filter": {} + }, + "comment": "" + }, + { + "role": "implementer", + "permission": { + "filter": {} + }, + "comment": "" + }, + { + "role": "planner", + "permission": { + "filter": {} + }, + "comment": "" + }, + { + "role": "requester", + "permission": { + "filter": {} + }, + "comment": "" + } + ] + }, + { + "table": { + "name": "rule", + "schema": "public" + }, + "object_relationships": [ + { + "name": "importControlByRuleLastSeen", + "using": { + "foreign_key_constraint_on": "rule_last_seen" + } + }, + { + "name": "import_control", + "using": { + "foreign_key_constraint_on": "rule_create" + } + }, + { + "name": "management", + "using": { + "foreign_key_constraint_on": "mgm_id" + } + }, + { + "name": "parentRuleTypeByParentRuleType", + "using": { + "foreign_key_constraint_on": "parent_rule_type" + } + }, + { + "name": "rule", + "using": { + "foreign_key_constraint_on": "parent_rule_id" + } + }, + { + "name": "ruleByXlateRule", + "using": { + "foreign_key_constraint_on": "xlate_rule" + } + }, + { + "name": "rule_metadatum", + "using": { + "manual_configuration": { + "column_mapping": { + "mgm_id": "mgm_id", + "rule_uid": "rule_uid" + }, + "insertion_order": null, + "remote_table": { + "name": "rule_metadata", + "schema": "public" + } + } + } + }, + { + "name": "rulebase", + "using": { + "foreign_key_constraint_on": "rulebase_id" + } + }, + { + "name": "stm_action", + "using": { + "foreign_key_constraint_on": "action_id" + } + }, + { + "name": "stm_track", + "using": { + "foreign_key_constraint_on": "track_id" + } + }, + { + "name": "uiuser", + "using": { + "foreign_key_constraint_on": "last_change_admin" + } + }, + { + "name": "zone", + "using": { + "foreign_key_constraint_on": "rule_from_zone" + } + }, + { + "name": "zoneByRuleToZone", + "using": { + "foreign_key_constraint_on": "rule_to_zone" + } + } + ], + "array_relationships": [ + { + "name": "changelogRulesByOldRuleId", + "using": { + "foreign_key_constraint_on": { + "column": "old_rule_id", + "table": { + "name": "changelog_rule", + "schema": "public" + } + } + } + }, + { + "name": "changelog_rules", + "using": { + "foreign_key_constraint_on": { + "column": "new_rule_id", + "table": { + "name": "changelog_rule", + "schema": "public" + } + } + } + }, + { + "name": "compliance_violations", + "using": { + "foreign_key_constraint_on": { + "column": "rule_id", + "table": { + "name": "violation", + "schema": "compliance" + } + } + } + }, + { + "name": "compliance_violations_version_agnostic", + "using": { + "manual_configuration": { + "column_mapping": { + "rule_uid": "rule_uid" + }, + "insertion_order": null, + "remote_table": { + "name": "violation", + "schema": "compliance" + } + } + } + }, + { + "name": "rule_enforced_on_gateways", + "using": { + "foreign_key_constraint_on": { + "column": "rule_id", + "table": { + "name": "rule_enforced_on_gateway", + "schema": "public" + } + } + } + }, + { + "name": "rule_from_zones", + "using": { + "foreign_key_constraint_on": { + "column": "rule_id", + "table": { + "name": "rule_from_zone", + "schema": "public" + } + } + } + }, + { + "name": "rule_froms", + "using": { + "foreign_key_constraint_on": { + "column": "rule_id", + "table": { + "name": "rule_from", + "schema": "public" + } + } + } + }, + { + "name": "rule_nwobj_resolveds", + "using": { + "foreign_key_constraint_on": { + "column": "rule_id", + "table": { + "name": "rule_nwobj_resolved", + "schema": "public" + } + } + } + }, + { + "name": "rule_owners", + "using": { + "foreign_key_constraint_on": { + "column": "rule_id", + "table": { + "name": "rule_owner", + "schema": "public" + } + } + } + }, + { + "name": "rule_services", + "using": { + "foreign_key_constraint_on": { + "column": "rule_id", + "table": { + "name": "rule_service", + "schema": "public" + } + } + } + }, + { + "name": "rule_svc_resolveds", + "using": { + "foreign_key_constraint_on": { + "column": "rule_id", + "table": { + "name": "rule_svc_resolved", + "schema": "public" + } + } + } + }, + { + "name": "rule_times", + "using": { + "foreign_key_constraint_on": { + "column": "rule_id", + "table": { + "name": "rule_time", + "schema": "public" + } + } + } + }, + { + "name": "rule_to_zones", + "using": { + "foreign_key_constraint_on": { + "column": "rule_id", + "table": { + "name": "rule_to_zone", + "schema": "public" + } + } + } + }, + { + "name": "rule_tos", + "using": { + "foreign_key_constraint_on": { + "column": "rule_id", + "table": { + "name": "rule_to", + "schema": "public" + } + } + } + }, + { + "name": "rule_user_resolveds", + "using": { + "foreign_key_constraint_on": { + "column": "rule_id", + "table": { + "name": "rule_user_resolved", + "schema": "public" + } + } + } + }, + { + "name": "rulebase_links", + "using": { + "foreign_key_constraint_on": { + "column": "from_rule_id", + "table": { + "name": "rulebase_link", + "schema": "public" + } + } + } + }, + { + "name": "rules", + "using": { + "foreign_key_constraint_on": { + "column": "parent_rule_id", + "table": { + "name": "rule", + "schema": "public" + } + } + } + }, + { + "name": "rulesByXlateRule", + "using": { + "foreign_key_constraint_on": { + "column": "xlate_rule", + "table": { + "name": "rule", + "schema": "public" + } + } + } + } + ], + "computed_fields": [ + { + "name": "get_rule_froms_for_tenant", + "definition": { + "function": { + "name": "get_rule_froms_for_tenant", + "schema": "public" + }, + "session_argument": "hasura_session" + } + }, + { + "name": "get_rule_tos_for_tenant", + "definition": { + "function": { + "name": "get_rule_tos_for_tenant", + "schema": "public" + }, + "session_argument": "hasura_session" + } + }, + { + "name": "rule_relevant_for_tenant", + "definition": { + "function": { + "name": "rule_relevant_for_tenant", + "schema": "public" + }, + "session_argument": "hasura_session" + } + } + ], + "insert_permissions": [ + { + "role": "importer", + "permission": { + "check": {}, + "columns": [ + "access_rule", + "action_id", + "active", + "dev_id", + "is_global", + "last_change_admin", + "mgm_id", + "nat_rule", + "parent_rule_id", + "parent_rule_type", + "removed", + "rule_action", + "rule_comment", + "rule_create", + "rule_custom_fields", + "rule_disabled", + "rule_dst", + "rule_dst_neg", + "rule_dst_refs", + "rule_from_zone", + "rule_head_text", + "rule_id", + "rule_implied", + "rule_installon", + "rule_last_seen", + "rule_name", + "rule_num", + "rule_num_numeric", + "rule_ruleid", + "rule_src", + "rule_src_neg", + "rule_src_refs", + "rule_svc", + "rule_svc_neg", + "rule_svc_refs", + "rule_time", + "rule_to_zone", + "rule_track", + "rule_uid", + "rulebase_id", + "track_id", + "xlate_rule" + ] + }, + "comment": "" + } + ], + "select_permissions": [ + { + "role": "auditor", + "permission": { + "columns": [ + "parent_rule_id", + "removed", + "rule_create", + "rule_id", + "rule_last_seen", + "xlate_rule", + "access_rule", + "active", + "is_global", + "nat_rule", + "rule_disabled", + "rule_dst_neg", + "rule_implied", + "rule_src_neg", + "rule_svc_neg", + "rule_installon", + "rule_name", + "rule_ruleid", + "rule_time", + "action_id", + "dev_id", + "last_change_admin", + "mgm_id", + "rulebase_id", + "rule_from_zone", + "rule_num", + "rule_to_zone", + "track_id", + "rule_custom_fields", + "rule_num_numeric", + "parent_rule_type", + "rule_action", + "rule_comment", + "rule_dst", + "rule_dst_refs", + "rule_head_text", + "rule_src", + "rule_src_refs", + "rule_svc", + "rule_svc_refs", + "rule_track", + "rule_uid" + ], + "computed_fields": [ + "rule_relevant_for_tenant" + ], + "filter": {}, + "allow_aggregations": true + } + }, + { + "role": "fw-admin", + "permission": { + "columns": [ + "parent_rule_id", + "removed", + "rule_create", + "rule_id", + "rule_last_seen", + "xlate_rule", + "access_rule", + "active", + "is_global", + "nat_rule", + "rule_disabled", + "rule_dst_neg", + "rule_implied", + "rule_src_neg", + "rule_svc_neg", + "rule_installon", + "rule_name", + "rule_ruleid", + "rule_time", + "action_id", + "dev_id", + "last_change_admin", + "mgm_id", + "rulebase_id", + "rule_from_zone", + "rule_num", + "rule_to_zone", + "track_id", + "rule_custom_fields", + "rule_num_numeric", + "parent_rule_type", + "rule_action", + "rule_comment", + "rule_dst", + "rule_dst_refs", + "rule_head_text", + "rule_src", + "rule_src_refs", + "rule_svc", + "rule_svc_refs", + "rule_track", + "rule_uid" + ], + "computed_fields": [ + "rule_relevant_for_tenant" + ], + "filter": {}, + "allow_aggregations": true + } + }, + { + "role": "importer", + "permission": { + "columns": [ + "parent_rule_id", + "removed", + "rule_create", + "rule_id", + "rule_last_seen", + "xlate_rule", + "access_rule", + "active", + "is_global", + "nat_rule", + "rule_disabled", + "rule_dst_neg", + "rule_implied", + "rule_src_neg", + "rule_svc_neg", + "rule_installon", + "rule_name", + "rule_ruleid", + "rule_time", + "action_id", + "dev_id", + "last_change_admin", + "mgm_id", + "rulebase_id", + "rule_from_zone", + "rule_num", + "rule_to_zone", + "track_id", + "rule_custom_fields", + "rule_num_numeric", + "parent_rule_type", + "rule_action", + "rule_comment", + "rule_dst", + "rule_dst_refs", + "rule_head_text", + "rule_src", + "rule_src_refs", + "rule_svc", + "rule_svc_refs", + "rule_track", + "rule_uid" + ], + "computed_fields": [ + "rule_relevant_for_tenant" + ], + "filter": {} + }, + "comment": "" + }, + { + "role": "middleware-server", + "permission": { + "columns": [ + "parent_rule_id", + "removed", + "rule_create", + "rule_id", + "rule_last_seen", + "xlate_rule", + "access_rule", + "active", + "is_global", + "nat_rule", + "rule_disabled", + "rule_dst_neg", + "rule_implied", + "rule_src_neg", + "rule_svc_neg", + "rule_installon", + "rule_name", + "rule_ruleid", + "rule_time", + "action_id", + "dev_id", + "last_change_admin", + "mgm_id", + "rulebase_id", + "rule_from_zone", + "rule_num", + "rule_to_zone", + "track_id", + "rule_custom_fields", + "rule_num_numeric", + "parent_rule_type", + "rule_action", + "rule_comment", + "rule_dst", + "rule_dst_refs", + "rule_head_text", + "rule_src", + "rule_src_refs", + "rule_svc", + "rule_svc_refs", + "rule_track", + "rule_uid" + ], + "computed_fields": [ + "rule_relevant_for_tenant" + ], + "filter": {}, + "allow_aggregations": true + } + }, + { + "role": "modeller", + "permission": { + "columns": [ + "parent_rule_id", + "removed", + "rule_create", + "rule_id", + "rule_last_seen", + "xlate_rule", + "access_rule", + "active", + "is_global", + "nat_rule", + "rule_disabled", + "rule_dst_neg", + "rule_implied", + "rule_src_neg", + "rule_svc_neg", + "rule_installon", + "rule_name", + "rule_ruleid", + "rule_time", + "action_id", + "dev_id", + "last_change_admin", + "mgm_id", + "rulebase_id", + "rule_from_zone", + "rule_num", + "rule_to_zone", + "track_id", + "rule_custom_fields", + "rule_num_numeric", + "parent_rule_type", + "rule_action", + "rule_comment", + "rule_dst", + "rule_dst_refs", + "rule_head_text", + "rule_src", + "rule_src_refs", + "rule_svc", + "rule_svc_refs", + "rule_track", + "rule_uid" + ], + "computed_fields": [ + "rule_relevant_for_tenant" + ], + "filter": {}, + "allow_aggregations": true + } + }, + { + "role": "recertifier", + "permission": { + "columns": [ + "access_rule", + "action_id", + "active", + "dev_id", + "is_global", + "last_change_admin", + "mgm_id", + "nat_rule", + "parent_rule_id", + "parent_rule_type", + "removed", + "rule_action", + "rule_comment", + "rule_create", + "rule_custom_fields", + "rule_disabled", + "rule_dst", + "rule_dst_neg", + "rule_dst_refs", + "rule_from_zone", + "rule_head_text", + "rule_id", + "rule_implied", + "rule_installon", + "rule_last_seen", + "rule_name", + "rule_num", + "rule_num_numeric", + "rule_ruleid", + "rule_src", + "rule_src_neg", + "rule_src_refs", + "rule_svc", + "rule_svc_neg", + "rule_svc_refs", + "rule_time", + "rule_to_zone", + "rule_track", + "rule_uid", + "rulebase_id", + "track_id", + "xlate_rule" + ], + "computed_fields": [ + "rule_relevant_for_tenant" + ], + "filter": { + "_and": [ + { + "mgm_id": { + "_in": "x-hasura-visible-managements" + } + }, + { + "rule_relevant_for_tenant": { + "_eq": "true" + } + } + ] + }, + "allow_aggregations": true + } + }, + { + "role": "reporter", + "permission": { + "columns": [ + "parent_rule_id", + "removed", + "rule_create", + "rule_id", + "rule_last_seen", + "xlate_rule", + "access_rule", + "active", + "is_global", + "nat_rule", + "rule_disabled", + "rule_dst_neg", + "rule_implied", + "rule_src_neg", + "rule_svc_neg", + "rule_installon", + "rule_name", + "rule_ruleid", + "rule_time", + "action_id", + "dev_id", + "last_change_admin", + "mgm_id", + "rulebase_id", + "rule_from_zone", + "rule_num", + "rule_to_zone", + "track_id", + "rule_custom_fields", + "rule_num_numeric", + "parent_rule_type", + "rule_action", + "rule_comment", + "rule_dst", + "rule_dst_refs", + "rule_head_text", + "rule_src", + "rule_src_refs", + "rule_svc", + "rule_svc_refs", + "rule_track", + "rule_uid" + ], + "computed_fields": [ + "rule_relevant_for_tenant" + ], + "filter": { + "_and": [ + { + "mgm_id": { + "_in": "x-hasura-visible-managements" + } + }, + { + "rule_relevant_for_tenant": { + "_eq": "true" + } + } + ] + }, + "allow_aggregations": true + } + }, + { + "role": "reporter-viewall", + "permission": { + "columns": [ + "parent_rule_id", + "removed", + "rule_create", + "rule_id", + "rule_last_seen", + "xlate_rule", + "access_rule", + "active", + "is_global", + "nat_rule", + "rule_disabled", + "rule_dst_neg", + "rule_implied", + "rule_src_neg", + "rule_svc_neg", + "rule_installon", + "rule_name", + "rule_ruleid", + "rule_time", + "action_id", + "dev_id", + "last_change_admin", + "mgm_id", + "rulebase_id", + "rule_from_zone", + "rule_num", + "rule_to_zone", + "track_id", + "rule_custom_fields", + "rule_num_numeric", + "parent_rule_type", + "rule_action", + "rule_comment", + "rule_dst", + "rule_dst_refs", + "rule_head_text", + "rule_src", + "rule_src_refs", + "rule_svc", + "rule_svc_refs", + "rule_track", + "rule_uid" + ], + "computed_fields": [ + "rule_relevant_for_tenant" + ], + "filter": {}, + "allow_aggregations": true + } + }, + { + "role": "requester", + "permission": { + "columns": [ + "access_rule", + "active", + "dev_id", + "rule_id", + "rule_uid" + ], + "filter": {} + }, + "comment": "" + } + ], + "update_permissions": [ + { + "role": "importer", + "permission": { + "columns": [ + "active", + "removed", + "rule_last_seen", + "rule_num_numeric" + ], + "filter": {}, + "check": {} + }, + "comment": "" + } + ], + "delete_permissions": [ + { + "role": "importer", + "permission": { + "filter": {} + }, + "comment": "" + } + ] + }, + { + "table": { + "name": "rule_api", + "schema": "public" + }, + "object_relationships": [ + { + "name": "rule_metadatum", + "using": { + "manual_configuration": { + "column_mapping": { + "rule_uid": "rule_uid" + }, + "insertion_order": null, + "remote_table": { + "name": "rule_metadata", + "schema": "public" + } + } + } + } + ], + "array_relationships": [ + { + "name": "rule_enforced_on_gateways", + "using": { + "manual_configuration": { + "column_mapping": { + "rule_id": "rule_id" + }, + "insertion_order": null, + "remote_table": { + "name": "rule_enforced_on_gateway", + "schema": "public" + } + } + } + }, + { + "name": "rule_from_zones", + "using": { + "manual_configuration": { + "column_mapping": { + "rule_id": "rule_id" + }, + "insertion_order": null, + "remote_table": { + "name": "rule_from_zone", + "schema": "public" + } + } + } + }, + { + "name": "rule_froms", + "using": { + "manual_configuration": { + "column_mapping": { + "rule_id": "rule_id" + }, + "insertion_order": null, + "remote_table": { + "name": "rule_from", + "schema": "public" + } + } + } + }, + { + "name": "rule_services", + "using": { + "manual_configuration": { + "column_mapping": { + "rule_id": "rule_id" + }, + "insertion_order": null, + "remote_table": { + "name": "rule_service", + "schema": "public" + } + } + } + }, + { + "name": "rule_to_zones", + "using": { + "manual_configuration": { + "column_mapping": { + "rule_id": "rule_id" + }, + "insertion_order": null, + "remote_table": { + "name": "rule_to_zone", + "schema": "public" + } + } + } + }, + { + "name": "rule_tos", + "using": { + "manual_configuration": { + "column_mapping": { + "rule_id": "rule_id" + }, + "insertion_order": null, + "remote_table": { + "name": "rule_to", + "schema": "public" + } + } + } + } + ], + "select_permissions": [ + { + "role": "auditor", + "permission": { + "columns": [ + "parent_rule_id", + "removed", + "rule_create", + "rule_id", + "rule_last_seen", + "xlate_rule", + "access_rule", + "active", + "is_global", + "nat_rule", + "rule_disabled", + "rule_dst_neg", + "rule_implied", + "rule_src_neg", + "rule_svc_neg", + "rule_installon", + "rule_name", + "rule_ruleid", + "rule_time", + "action_id", + "dev_id", + "last_change_admin", + "mgm_id", + "rulebase_id", + "rule_from_zone", + "rule_num", + "rule_to_zone", + "track_id", + "rule_custom_fields", + "rule_num_numeric", + "parent_rule_type", + "rule_action", + "rule_comment", + "rule_dst", + "rule_dst_refs", + "rule_head_text", + "rule_src", + "rule_src_refs", + "rule_svc", + "rule_svc_refs", + "rule_track", + "rule_uid" + ], + "filter": {}, + "allow_aggregations": true + } + }, + { + "role": "fw-admin", + "permission": { + "columns": [ + "parent_rule_id", + "removed", + "rule_create", + "rule_id", + "rule_last_seen", + "xlate_rule", + "access_rule", + "active", + "is_global", + "nat_rule", + "rule_disabled", + "rule_dst_neg", + "rule_implied", + "rule_src_neg", + "rule_svc_neg", + "rule_installon", + "rule_name", + "rule_ruleid", + "rule_time", + "action_id", + "dev_id", + "last_change_admin", + "mgm_id", + "rulebase_id", + "rule_from_zone", + "rule_num", + "rule_to_zone", + "track_id", + "rule_custom_fields", + "rule_num_numeric", + "parent_rule_type", + "rule_action", + "rule_comment", + "rule_dst", + "rule_dst_refs", + "rule_head_text", + "rule_src", + "rule_src_refs", + "rule_svc", + "rule_svc_refs", + "rule_track", + "rule_uid" + ], + "filter": {}, + "allow_aggregations": true + } + }, + { + "role": "importer", + "permission": { + "columns": [ + "parent_rule_id", + "removed", + "rule_create", + "rule_id", + "rule_last_seen", + "xlate_rule", + "access_rule", + "active", + "is_global", + "nat_rule", + "rule_disabled", + "rule_dst_neg", + "rule_implied", + "rule_src_neg", + "rule_svc_neg", + "rule_installon", + "rule_name", + "rule_ruleid", + "rule_time", + "action_id", + "dev_id", + "last_change_admin", + "mgm_id", + "rulebase_id", + "rule_from_zone", + "rule_num", + "rule_to_zone", + "track_id", + "rule_custom_fields", + "rule_num_numeric", + "parent_rule_type", + "rule_action", + "rule_comment", + "rule_dst", + "rule_dst_refs", + "rule_head_text", + "rule_src", + "rule_src_refs", + "rule_svc", + "rule_svc_refs", + "rule_track", + "rule_uid" + ], + "filter": {} + }, + "comment": "" + }, + { + "role": "middleware-server", + "permission": { + "columns": [ + "parent_rule_id", + "removed", + "rule_create", + "rule_id", + "rule_last_seen", + "xlate_rule", + "access_rule", + "active", + "is_global", + "nat_rule", + "rule_disabled", + "rule_dst_neg", + "rule_implied", + "rule_src_neg", + "rule_svc_neg", + "rule_installon", + "rule_name", + "rule_ruleid", + "rule_time", + "action_id", + "dev_id", + "last_change_admin", + "mgm_id", + "rulebase_id", + "rule_from_zone", + "rule_num", + "rule_to_zone", + "track_id", + "rule_custom_fields", + "rule_num_numeric", + "parent_rule_type", + "rule_action", + "rule_comment", + "rule_dst", + "rule_dst_refs", + "rule_head_text", + "rule_src", + "rule_src_refs", + "rule_svc", + "rule_svc_refs", + "rule_track", + "rule_uid" + ], + "filter": {}, + "allow_aggregations": true + } + }, + { + "role": "modeller", + "permission": { + "columns": [ + "parent_rule_id", + "removed", + "rule_create", + "rule_id", + "rule_last_seen", + "xlate_rule", + "access_rule", + "active", + "is_global", + "nat_rule", + "rule_disabled", + "rule_dst_neg", + "rule_implied", + "rule_src_neg", + "rule_svc_neg", + "rule_installon", + "rule_name", + "rule_ruleid", + "rule_time", + "action_id", + "dev_id", + "last_change_admin", + "mgm_id", + "rulebase_id", + "rule_from_zone", + "rule_num", + "rule_to_zone", + "track_id", + "rule_custom_fields", + "rule_num_numeric", + "parent_rule_type", + "rule_action", + "rule_comment", + "rule_dst", + "rule_dst_refs", + "rule_head_text", + "rule_src", + "rule_src_refs", + "rule_svc", + "rule_svc_refs", + "rule_track", + "rule_uid" + ], + "filter": { + "_and": [ + { + "mgm_id": { + "_in": "x-hasura-visible-managements" + } + } + ] + }, + "allow_aggregations": true + } + }, + { + "role": "recertifier", + "permission": { + "columns": [ + "parent_rule_id", + "removed", + "rule_create", + "rule_id", + "rule_last_seen", + "xlate_rule", + "access_rule", + "active", + "is_global", + "nat_rule", + "rule_disabled", + "rule_dst_neg", + "rule_implied", + "rule_src_neg", + "rule_svc_neg", + "rule_installon", + "rule_name", + "rule_ruleid", + "rule_time", + "action_id", + "dev_id", + "last_change_admin", + "mgm_id", + "rulebase_id", + "rule_from_zone", + "rule_num", + "rule_to_zone", + "track_id", + "rule_custom_fields", + "rule_num_numeric", + "parent_rule_type", + "rule_action", + "rule_comment", + "rule_dst", + "rule_dst_refs", + "rule_head_text", + "rule_src", + "rule_src_refs", + "rule_svc", + "rule_svc_refs", + "rule_track", + "rule_uid" + ], + "filter": { + "_and": [ + { + "mgm_id": { + "_in": "x-hasura-visible-managements" + } + } + ] + }, + "allow_aggregations": true + } + }, + { + "role": "reporter", + "permission": { + "columns": [ + "parent_rule_id", + "removed", + "rule_create", + "rule_id", + "rule_last_seen", + "xlate_rule", + "access_rule", + "active", + "is_global", + "nat_rule", + "rule_disabled", + "rule_dst_neg", + "rule_implied", + "rule_src_neg", + "rule_svc_neg", + "rule_installon", + "rule_name", + "rule_ruleid", + "rule_time", + "action_id", + "dev_id", + "last_change_admin", + "mgm_id", + "rulebase_id", + "rule_from_zone", + "rule_num", + "rule_to_zone", + "track_id", + "rule_custom_fields", + "rule_num_numeric", + "parent_rule_type", + "rule_action", + "rule_comment", + "rule_dst", + "rule_dst_refs", + "rule_head_text", + "rule_src", + "rule_src_refs", + "rule_svc", + "rule_svc_refs", + "rule_track", + "rule_uid" + ], + "filter": { + "_and": [ + { + "mgm_id": { + "_in": "x-hasura-visible-managements" + } + } + ] + }, + "allow_aggregations": true + } }, { - "name": "reqtasks", + "role": "reporter-viewall", + "permission": { + "columns": [ + "parent_rule_id", + "removed", + "rule_create", + "rule_id", + "rule_last_seen", + "xlate_rule", + "access_rule", + "active", + "is_global", + "nat_rule", + "rule_disabled", + "rule_dst_neg", + "rule_implied", + "rule_src_neg", + "rule_svc_neg", + "rule_installon", + "rule_name", + "rule_ruleid", + "rule_time", + "action_id", + "dev_id", + "last_change_admin", + "mgm_id", + "rulebase_id", + "rule_from_zone", + "rule_num", + "rule_to_zone", + "track_id", + "rule_custom_fields", + "rule_num_numeric", + "parent_rule_type", + "rule_action", + "rule_comment", + "rule_dst", + "rule_dst_refs", + "rule_head_text", + "rule_src", + "rule_src_refs", + "rule_svc", + "rule_svc_refs", + "rule_track", + "rule_uid" + ], + "filter": {}, + "allow_aggregations": true + } + } + ] + }, + { + "table": { + "name": "rule_enforced_on_gateway", + "schema": "public" + }, + "object_relationships": [ + { + "name": "device", "using": { - "foreign_key_constraint_on": { - "column": "nw_obj_grp_id", - "table": { - "name": "reqtask", - "schema": "request" - } - } + "foreign_key_constraint_on": "dev_id" } }, { - "name": "rule_froms", + "name": "importControlByRemoved", "using": { - "foreign_key_constraint_on": { - "column": "obj_id", - "table": { - "name": "rule_from", - "schema": "public" - } - } + "foreign_key_constraint_on": "removed" } }, { - "name": "rule_nwobj_resolveds", + "name": "import_control", "using": { - "foreign_key_constraint_on": { - "column": "obj_id", - "table": { - "name": "rule_nwobj_resolved", - "schema": "public" - } - } + "foreign_key_constraint_on": "created" } }, { - "name": "rule_tos", + "name": "rule", "using": { - "foreign_key_constraint_on": { - "column": "obj_id", - "table": { - "name": "rule_to", - "schema": "public" - } - } + "foreign_key_constraint_on": "rule_id" } } ], + "insert_permissions": [ + { + "role": "importer", + "permission": { + "check": {}, + "columns": [ + "created", + "removed", + "dev_id", + "rule_id" + ] + }, + "comment": "" + } + ], "select_permissions": [ { "role": "auditor", "permission": { "columns": [ - "obj_id", - "last_change_admin", - "zone_id", - "mgm_id", - "obj_name", - "obj_comment", - "obj_uid", - "obj_typ_id", - "obj_location", - "obj_member_names", - "obj_member_refs", - "initial_config", - "obj_sw", - "obj_ip", - "obj_ip_end", - "obj_nat", - "nattyp_id", - "obj_nat_ip", - "obj_nat_ip_end", - "obj_nat_install", - "obj_color_id", - "obj_sys_name", - "obj_sys_location", - "obj_sys_contact", - "obj_sys_desc", - "obj_sys_readcom", - "obj_sys_writecom", - "active", - "obj_create", - "obj_last_seen" + "created", + "removed", + "dev_id", + "rule_id" + ], + "filter": {} + }, + "comment": "" + }, + { + "role": "fw-admin", + "permission": { + "columns": [ + "created", + "removed", + "dev_id", + "rule_id" ], "filter": {}, "allow_aggregations": true - } + }, + "comment": "" }, { - "role": "fw-admin", + "role": "importer", "permission": { "columns": [ - "obj_create", - "obj_id", - "obj_last_seen", - "active", - "initial_config", - "obj_nat", - "obj_comment", - "obj_location", - "obj_name", - "obj_sw", - "obj_sys_contact", - "obj_sys_location", - "obj_sys_name", - "obj_sys_readcom", - "obj_sys_writecom", - "obj_ip", - "obj_ip_end", - "obj_nat_ip", - "obj_nat_ip_end", - "last_change_admin", - "mgm_id", - "nattyp_id", - "obj_color_id", - "obj_nat_install", - "obj_typ_id", - "zone_id", - "obj_member_names", - "obj_member_refs", - "obj_sys_desc", - "obj_uid" + "created", + "removed", + "dev_id", + "rule_id" + ], + "filter": {} + }, + "comment": "" + }, + { + "role": "middleware-server", + "permission": { + "columns": [ + "created", + "removed", + "dev_id", + "rule_id" ], "filter": {}, "allow_aggregations": true - } + }, + "comment": "" + }, + { + "role": "modeller", + "permission": { + "columns": [ + "created", + "removed", + "dev_id", + "rule_id" + ], + "filter": { + "dev_id": { + "_in": "x-hasura-visible-devices" + } + } + }, + "comment": "" }, { "role": "recertifier", "permission": { "columns": [ - "obj_id", - "last_change_admin", - "zone_id", - "mgm_id", - "obj_name", - "obj_comment", - "obj_uid", - "obj_typ_id", - "obj_location", - "obj_member_names", - "obj_member_refs", - "initial_config", - "obj_sw", - "obj_ip", - "obj_ip_end", - "obj_nat", - "nattyp_id", - "obj_nat_ip", - "obj_nat_ip_end", - "obj_nat_install", - "obj_color_id", - "obj_sys_name", - "obj_sys_location", - "obj_sys_contact", - "obj_sys_desc", - "obj_sys_readcom", - "obj_sys_writecom", - "active", - "obj_create", - "obj_last_seen" + "created", + "removed", + "dev_id", + "rule_id" ], "filter": { - "mgm_id": { - "_in": "x-hasura-visible-managements" + "dev_id": { + "_in": "x-hasura-visible-devices" } - }, - "allow_aggregations": true - } + } + }, + "comment": "" }, { "role": "reporter", "permission": { "columns": [ - "obj_id", - "last_change_admin", - "zone_id", - "mgm_id", - "obj_name", - "obj_comment", - "obj_uid", - "obj_typ_id", - "obj_location", - "obj_member_names", - "obj_member_refs", - "initial_config", - "obj_sw", - "obj_ip", - "obj_ip_end", - "obj_nat", - "nattyp_id", - "obj_nat_ip", - "obj_nat_ip_end", - "obj_nat_install", - "obj_color_id", - "obj_sys_name", - "obj_sys_location", - "obj_sys_contact", - "obj_sys_desc", - "obj_sys_readcom", - "obj_sys_writecom", - "active", - "obj_create", - "obj_last_seen" + "created", + "removed", + "dev_id", + "rule_id" ], "filter": { - "mgm_id": { - "_in": "x-hasura-visible-managements" + "dev_id": { + "_in": "x-hasura-visible-devices" } - }, - "allow_aggregations": true - } + } + }, + "comment": "" }, { "role": "reporter-viewall", "permission": { "columns": [ - "obj_id", - "last_change_admin", - "zone_id", - "mgm_id", - "obj_name", - "obj_comment", - "obj_uid", - "obj_typ_id", - "obj_location", - "obj_member_names", - "obj_member_refs", - "initial_config", - "obj_sw", - "obj_ip", - "obj_ip_end", - "obj_nat", - "nattyp_id", - "obj_nat_ip", - "obj_nat_ip_end", - "obj_nat_install", - "obj_color_id", - "obj_sys_name", - "obj_sys_location", - "obj_sys_contact", - "obj_sys_desc", - "obj_sys_readcom", - "obj_sys_writecom", - "active", - "obj_create", - "obj_last_seen" + "created", + "removed", + "dev_id", + "rule_id" ], "filter": {}, "allow_aggregations": true - } + }, + "comment": "" + } + ], + "update_permissions": [ + { + "role": "importer", + "permission": { + "columns": [ + "created", + "removed", + "dev_id", + "rule_id" + ], + "filter": {}, + "check": {} + }, + "comment": "" + } + ], + "delete_permissions": [ + { + "role": "importer", + "permission": { + "filter": {} + }, + "comment": "" } ] }, { "table": { - "name": "objgrp", + "name": "rule_from", "schema": "public" }, "object_relationships": [ { - "name": "importControlByImportLastSeen", + "name": "importControlByRfLastSeen", "using": { - "foreign_key_constraint_on": "import_last_seen" + "foreign_key_constraint_on": "rf_last_seen" } }, { "name": "import_control", "using": { - "foreign_key_constraint_on": "import_created" + "foreign_key_constraint_on": "rf_create" } }, { "name": "object", "using": { - "foreign_key_constraint_on": "objgrp_id" + "foreign_key_constraint_on": "obj_id" } }, { - "name": "objectByObjgrpMemberId", + "name": "rule", "using": { - "foreign_key_constraint_on": "objgrp_member_id" + "foreign_key_constraint_on": "rule_id" + } + }, + { + "name": "usr", + "using": { + "foreign_key_constraint_on": "user_id" + } + } + ], + "computed_fields": [ + { + "name": "rule_from_relevant_for_tenant", + "definition": { + "function": { + "name": "rule_from_relevant_for_tenant", + "schema": "public" + }, + "session_argument": "hasura_session" } } ], + "insert_permissions": [ + { + "role": "importer", + "permission": { + "check": {}, + "columns": [ + "obj_id", + "removed", + "rf_create", + "rf_last_seen", + "rule_from_id", + "rule_id", + "user_id", + "active", + "negated" + ] + }, + "comment": "" + } + ], "select_permissions": [ { "role": "auditor", "permission": { "columns": [ - "objgrp_id", - "objgrp_member_id", - "import_created", - "import_last_seen", "active", - "negated" + "negated", + "obj_id", + "removed", + "rf_create", + "rf_last_seen", + "rule_from_id", + "rule_id", + "user_id" + ], + "computed_fields": [ + "rule_from_relevant_for_tenant" ], "filter": {}, "allow_aggregations": true @@ -7114,513 +18497,446 @@ "role": "fw-admin", "permission": { "columns": [ - "import_created", - "import_last_seen", - "objgrp_id", - "objgrp_member_id", "active", - "negated" + "negated", + "obj_id", + "removed", + "rf_create", + "rf_last_seen", + "removed", + "rule_from_id", + "rule_id", + "user_id" ], - "filter": {} - } - }, - { - "role": "recertifier", - "permission": { - "columns": [ - "objgrp_id", - "objgrp_member_id", - "import_created", - "import_last_seen", - "active", - "negated" + "computed_fields": [ + "rule_from_relevant_for_tenant" ], "filter": {}, "allow_aggregations": true } }, { - "role": "reporter", + "role": "importer", "permission": { "columns": [ - "objgrp_id", - "objgrp_member_id", - "import_created", - "import_last_seen", + "obj_id", + "removed", + "rf_create", + "rf_last_seen", + "rule_from_id", + "rule_id", + "user_id", "active", "negated" ], + "computed_fields": [ + "rule_from_relevant_for_tenant" + ], "filter": {}, "allow_aggregations": true - } + }, + "comment": "" }, { - "role": "reporter-viewall", + "role": "middleware-server", "permission": { "columns": [ - "objgrp_id", - "objgrp_member_id", - "import_created", - "import_last_seen", "active", - "negated" + "negated", + "obj_id", + "removed", + "rf_create", + "rf_last_seen", + "rule_from_id", + "rule_id", + "user_id" + ], + "computed_fields": [ + "rule_from_relevant_for_tenant" ], "filter": {} - } - } - ] - }, - { - "table": { - "name": "objgrp_flat", - "schema": "public" - }, - "object_relationships": [ - { - "name": "importControlByImportLastSeen", - "using": { - "foreign_key_constraint_on": "import_last_seen" - } - }, - { - "name": "import_control", - "using": { - "foreign_key_constraint_on": "import_created" - } - }, - { - "name": "object", - "using": { - "foreign_key_constraint_on": "objgrp_flat_id" - } + }, + "comment": "" }, { - "name": "objectByObjgrpFlatMemberId", - "using": { - "foreign_key_constraint_on": "objgrp_flat_member_id" - } - } - ], - "select_permissions": [ - { - "role": "auditor", + "role": "modeller", "permission": { "columns": [ - "objgrp_flat_id", - "objgrp_flat_member_id", + "obj_id", + "removed", + "rf_create", + "rf_last_seen", + "rule_from_id", + "rule_id", + "user_id", "active", - "import_created", - "import_last_seen", "negated" ], + "computed_fields": [ + "rule_from_relevant_for_tenant" + ], "filter": {}, "allow_aggregations": true } }, { - "role": "fw-admin", + "role": "recertifier", "permission": { "columns": [ - "import_created", - "import_last_seen", - "objgrp_flat_id", - "objgrp_flat_member_id", "active", - "negated" + "negated", + "obj_id", + "removed", + "rf_create", + "rf_last_seen", + "rule_from_id", + "rule_id", + "user_id" ], - "filter": {} + "computed_fields": [ + "rule_from_relevant_for_tenant" + ], + "filter": { + "_and": [ + { + "rule": { + "mgm_id": { + "_in": "x-hasura-visible-managements" + } + } + }, + { + "rule_from_relevant_for_tenant": { + "_eq": "true" + } + } + ] + }, + "allow_aggregations": true } }, { - "role": "recertifier", + "role": "reporter", "permission": { "columns": [ - "objgrp_flat_id", - "objgrp_flat_member_id", + "obj_id", + "removed", + "rf_create", + "rf_last_seen", + "rule_from_id", + "rule_id", + "user_id", "active", - "import_created", - "import_last_seen", "negated" ], - "filter": {}, + "computed_fields": [ + "rule_from_relevant_for_tenant" + ], + "filter": { + "_and": [ + { + "rule": { + "mgm_id": { + "_in": "x-hasura-visible-managements" + } + } + }, + { + "rule_from_relevant_for_tenant": { + "_eq": "true" + } + } + ] + }, "allow_aggregations": true } }, { - "role": "reporter", + "role": "reporter-viewall", "permission": { "columns": [ - "objgrp_flat_id", - "objgrp_flat_member_id", + "obj_id", + "removed", + "rf_create", + "rf_last_seen", + "rule_from_id", + "rule_id", + "user_id", "active", - "import_created", - "import_last_seen", "negated" ], + "computed_fields": [ + "rule_from_relevant_for_tenant" + ], "filter": {}, "allow_aggregations": true } - }, + } + ], + "update_permissions": [ { - "role": "reporter-viewall", + "role": "importer", "permission": { "columns": [ - "objgrp_flat_id", - "objgrp_flat_member_id", + "obj_id", + "removed", + "rf_create", + "rf_last_seen", + "rule_from_id", + "rule_id", + "user_id", "active", - "import_created", - "import_last_seen", "negated" ], + "filter": {}, + "check": {} + }, + "comment": "" + } + ], + "delete_permissions": [ + { + "role": "importer", + "permission": { "filter": {} - } + }, + "comment": "" } ] }, { "table": { - "name": "owner", + "name": "rule_from_zone", "schema": "public" }, "object_relationships": [ { - "name": "tenant", - "using": { - "foreign_key_constraint_on": "tenant_id" - } - } - ], - "array_relationships": [ - { - "name": "owner_networks", - "using": { - "foreign_key_constraint_on": { - "column": "owner_id", - "table": { - "name": "owner_network", - "schema": "public" - } - } - } - }, - { - "name": "recertifications", - "using": { - "foreign_key_constraint_on": { - "column": "owner_id", - "table": { - "name": "recertification", - "schema": "public" - } - } - } - }, - { - "name": "reqtask_owners", + "name": "rule", "using": { - "foreign_key_constraint_on": { - "column": "owner_id", - "table": { - "name": "reqtask_owner", - "schema": "public" - } - } + "foreign_key_constraint_on": "rule_id" } }, { - "name": "rule_owners", + "name": "zone", "using": { - "foreign_key_constraint_on": { - "column": "owner_id", - "table": { - "name": "rule_owner", - "schema": "public" - } - } + "foreign_key_constraint_on": "zone_id" } } ], - "select_permissions": [ + "insert_permissions": [ { - "role": "approver", + "role": "importer", "permission": { + "check": {}, "columns": [ - "is_default", - "app_id_external", - "dn", - "group_dn", - "name", - "recert_check_params", - "id", - "recert_interval", - "tenant_id", - "last_recert_check" - ], - "filter": {} - } - }, + "created", + "removed", + "rule_id", + "zone_id" + ] + }, + "comment": "" + } + ], + "select_permissions": [ { "role": "auditor", "permission": { "columns": [ - "is_default", - "app_id_external", - "dn", - "group_dn", - "name", - "recert_check_params", - "id", - "recert_interval", - "tenant_id", - "last_recert_check" + "created", + "removed", + "rule_id", + "zone_id" ], - "filter": {} - } + "filter": {}, + "allow_aggregations": true + }, + "comment": "" }, { "role": "fw-admin", "permission": { "columns": [ - "is_default", - "app_id_external", - "dn", - "group_dn", - "name", - "recert_check_params", - "id", - "recert_interval", - "tenant_id", - "last_recert_check" - ], - "filter": {} - } - }, - { - "role": "implementer", - "permission": { - "columns": [ - "is_default", - "app_id_external", - "dn", - "group_dn", - "name", - "recert_check_params", - "id", - "recert_interval", - "tenant_id", - "last_recert_check" - ], - "filter": {} - } - }, - { - "role": "middleware-server", - "permission": { - "columns": [ - "id", - "name", - "dn", - "group_dn", - "is_default", - "tenant_id", - "recert_interval", - "app_id_external", - "last_recert_check", - "recert_check_params" + "created", + "removed", + "rule_id", + "zone_id" ], - "filter": {} - } + "filter": {}, + "allow_aggregations": true + }, + "comment": "" }, { - "role": "planner", + "role": "importer", "permission": { - "columns": [ - "is_default", - "app_id_external", - "dn", - "group_dn", - "name", - "recert_check_params", - "id", - "recert_interval", - "tenant_id", - "last_recert_check" + "columns": [ + "created", + "removed", + "rule_id", + "zone_id" ], - "filter": {} - } + "filter": {}, + "allow_aggregations": true + }, + "comment": "" }, { - "role": "recertifier", + "role": "middleware-server", "permission": { "columns": [ - "is_default", - "app_id_external", - "dn", - "group_dn", - "name", - "recert_check_params", - "id", - "recert_interval", - "tenant_id", - "last_recert_check" + "created", + "removed", + "rule_id", + "zone_id" ], - "filter": { - "_or": [ - { - "tenant_id": { - "_is_null": true - } - }, - { - "tenant_id": { - "_eq": "x-hasura-tenant-id" - } - } - ] - }, - "allow_aggregations": true - } + "filter": {} + }, + "comment": "" }, { - "role": "reporter", + "role": "modeller", "permission": { "columns": [ - "is_default", - "app_id_external", - "dn", - "group_dn", - "name", - "recert_check_params", - "id", - "recert_interval", - "tenant_id", - "last_recert_check" + "created", + "removed", + "rule_id", + "zone_id" ], - "filter": { - "tenant_id": { - "_eq": "x-hasura-tenant-id" - } - }, + "filter": {}, "allow_aggregations": true - } + }, + "comment": "" }, { - "role": "reporter-viewall", + "role": "recertifier", "permission": { "columns": [ - "is_default", - "app_id_external", - "dn", - "group_dn", - "name", - "recert_check_params", - "id", - "recert_interval", - "tenant_id", - "last_recert_check" + "created", + "removed", + "rule_id", + "zone_id" ], "filter": {}, "allow_aggregations": true - } + }, + "comment": "" }, { - "role": "requester", + "role": "reporter", "permission": { "columns": [ - "is_default", - "app_id_external", - "dn", - "group_dn", - "name", - "recert_check_params", - "id", - "recert_interval", - "tenant_id", - "last_recert_check" + "created", + "removed", + "rule_id", + "zone_id" ], - "filter": {} - } + "filter": {}, + "allow_aggregations": true + }, + "comment": "" }, { - "role": "reviewer", + "role": "reporter-viewall", "permission": { "columns": [ - "is_default", - "app_id_external", - "dn", - "group_dn", - "name", - "recert_check_params", - "id", - "recert_interval", - "tenant_id", - "last_recert_check" + "created", + "removed", + "rule_id", + "zone_id" ], - "filter": {} - } + "filter": {}, + "allow_aggregations": true + }, + "comment": "" } ], "update_permissions": [ { - "role": "middleware-server", + "role": "importer", "permission": { "columns": [ - "last_recert_check" + "created", + "removed", + "rule_id", + "zone_id" ], "filter": {}, - "check": null - } + "check": {} + }, + "comment": "" + } + ], + "delete_permissions": [ + { + "role": "importer", + "permission": { + "filter": {} + }, + "comment": "" } ] }, { "table": { - "name": "owner_network", + "name": "rule_metadata", "schema": "public" }, "object_relationships": [ { - "name": "owner", + "name": "created_import", "using": { - "foreign_key_constraint_on": "owner_id" + "foreign_key_constraint_on": "rule_created" } }, { - "name": "stm_ip_proto", + "name": "management", "using": { - "foreign_key_constraint_on": "ip_proto_id" + "foreign_key_constraint_on": "mgm_id" } - } - ], - "select_permissions": [ + }, { - "role": "auditor", - "permission": { - "columns": [ - "ip", - "id", - "ip_proto_id", - "owner_id", - "port" - ], - "filter": {}, - "allow_aggregations": true + "name": "removed_import", + "using": { + "foreign_key_constraint_on": "removed" } } - ] - }, - { - "table": { - "name": "parent_rule_type", - "schema": "public" - }, + ], "array_relationships": [ { - "name": "rules", + "name": "recertifications", "using": { "foreign_key_constraint_on": { - "column": "parent_rule_type", + "column": "rule_metadata_id", + "table": { + "name": "recertification", + "schema": "public" + } + } + } + }, + { + "name": "rule_owners", + "using": { + "foreign_key_constraint_on": { + "column": "rule_metadata_id", "table": { + "name": "rule_owner", + "schema": "public" + } + } + } + }, + { + "name": "rules", + "using": { + "manual_configuration": { + "column_mapping": { + "mgm_id": "mgm_id", + "rule_uid": "rule_uid" + }, + "insertion_order": null, + "remote_table": { "name": "rule", "schema": "public" } @@ -7628,44 +18944,122 @@ } } ], + "insert_permissions": [ + { + "role": "importer", + "permission": { + "check": {}, + "columns": [ + "mgm_id", + "removed", + "rule_created", + "rule_first_hit", + "rule_hit_counter", + "rule_last_hit", + "rule_metadata_id", + "rule_uid" + ] + } + } + ], "select_permissions": [ { "role": "auditor", "permission": { "columns": [ - "id", - "name" + "mgm_id", + "removed", + "rule_created", + "rule_first_hit", + "rule_hit_counter", + "rule_last_hit", + "rule_metadata_id", + "rule_uid" ], - "filter": {} + "filter": {}, + "allow_aggregations": true } }, { "role": "fw-admin", "permission": { "columns": [ - "name", - "id" + "mgm_id", + "removed", + "rule_created", + "rule_first_hit", + "rule_hit_counter", + "rule_last_hit", + "rule_metadata_id", + "rule_uid" + ], + "filter": {}, + "allow_aggregations": true + } + }, + { + "role": "importer", + "permission": { + "columns": [ + "mgm_id", + "removed", + "rule_created", + "rule_first_hit", + "rule_hit_counter", + "rule_last_hit", + "rule_metadata_id", + "rule_uid" + ], + "filter": {}, + "allow_aggregations": true + } + }, + { + "role": "middleware-server", + "permission": { + "columns": [ + "mgm_id", + "removed", + "rule_created", + "rule_first_hit", + "rule_hit_counter", + "rule_last_hit", + "rule_metadata_id", + "rule_uid" ], "filter": {}, "allow_aggregations": true } }, { - "role": "importer", + "role": "modeller", "permission": { "columns": [ - "id", - "name" + "mgm_id", + "removed", + "rule_created", + "rule_first_hit", + "rule_hit_counter", + "rule_last_hit", + "rule_metadata_id", + "rule_uid" ], - "filter": {} + "filter": {}, + "allow_aggregations": true } }, { "role": "recertifier", "permission": { "columns": [ - "id", - "name" + "mgm_id", + "removed", + "rule_created", + "rule_first_hit", + "rule_hit_counter", + "rule_last_hit", + "rule_metadata_id", + "rule_uid" ], "filter": {}, "allow_aggregations": true @@ -7675,8 +19069,14 @@ "role": "reporter", "permission": { "columns": [ - "id", - "name" + "mgm_id", + "removed", + "rule_created", + "rule_first_hit", + "rule_hit_counter", + "rule_last_hit", + "rule_metadata_id", + "rule_uid" ], "filter": {}, "allow_aggregations": true @@ -7686,86 +19086,105 @@ "role": "reporter-viewall", "permission": { "columns": [ - "id", - "name" + "mgm_id", + "rule_created", + "rule_first_hit", + "rule_hit_counter", + "rule_last_hit", + "rule_metadata_id", + "rule_uid" ], "filter": {}, "allow_aggregations": true } } + ], + "update_permissions": [ + { + "role": "importer", + "permission": { + "columns": [ + "mgm_id", + "rule_created", + "rule_first_hit", + "rule_hit_counter", + "rule_last_hit", + "rule_metadata_id", + "rule_uid" + ], + "filter": {}, + "check": null + } + }, + { + "role": "recertifier", + "permission": { + "columns": [], + "filter": {}, + "check": {} + } + } + ], + "delete_permissions": [ + { + "role": "importer", + "permission": { + "filter": {} + } + } ] }, { "table": { - "name": "recertification", + "name": "rule_nwobj_resolved", "schema": "public" }, "object_relationships": [ { - "name": "owner", + "name": "importControlByCreated", "using": { - "foreign_key_constraint_on": "owner_id" + "foreign_key_constraint_on": "created" } }, { - "name": "rule_metadatum", + "name": "import_control", "using": { - "foreign_key_constraint_on": "rule_metadata_id" + "foreign_key_constraint_on": "removed" } - } - ], - "insert_permissions": [ + }, { - "role": "importer", - "permission": { - "check": {}, - "columns": [ - "comment", - "id", - "ip_match", - "next_recert_date", - "owner_id", - "rule_id", - "rule_metadata_id", - "user_dn" - ] + "name": "management", + "using": { + "foreign_key_constraint_on": "mgm_id" } }, { - "role": "middleware-server", - "permission": { - "check": {}, - "columns": [ - "id", - "rule_id", - "rule_metadata_id", - "recertified", - "comment", - "ip_match", - "user_dn", - "owner_id", - "next_recert_date", - "recert_date" - ] + "name": "object", + "using": { + "foreign_key_constraint_on": "obj_id" } }, { - "role": "recertifier", + "name": "rule", + "using": { + "foreign_key_constraint_on": "rule_id" + } + } + ], + "insert_permissions": [ + { + "role": "importer", "permission": { "check": {}, "columns": [ - "comment", - "id", - "ip_match", - "next_recert_date", - "owner_id", - "recert_date", - "recertified", + "created", + "obj_id", + "removed", "rule_id", - "rule_metadata_id", - "user_dn" + "mgm_id" ] - } + }, + "comment": "" } ], "select_permissions": [ @@ -7773,74 +19192,78 @@ "role": "auditor", "permission": { "columns": [ - "comment", - "id", - "ip_match", - "next_recert_date", - "owner_id", - "recert_date", - "recertified", - "rule_id", - "rule_metadata_id", - "user_dn" + "created", + "mgm_id", + "obj_id", + "removed", + "rule_id" ], "filter": {}, "allow_aggregations": true } }, { - "role": "middleware-server", + "role": "fw-admin", "permission": { "columns": [ - "id", + "created", + "obj_id", + "removed", "rule_id", - "rule_metadata_id", - "recertified", - "comment", - "ip_match", - "user_dn", - "owner_id", - "next_recert_date", - "recert_date" + "mgm_id" ], - "filter": {} + "filter": {}, + "allow_aggregations": true } }, { - "role": "recertifier", + "role": "importer", "permission": { "columns": [ - "comment", - "id", - "ip_match", - "next_recert_date", - "owner_id", - "recert_date", - "recertified", + "created", + "obj_id", + "removed", "rule_id", - "rule_metadata_id", - "user_dn" + "mgm_id" ], "filter": {}, "allow_aggregations": true + }, + "comment": "" + }, + { + "role": "recertifier", + "permission": { + "columns": [ + "created", + "mgm_id", + "obj_id", + "removed", + "rule_id" + ], + "filter": { + "mgm_id": { + "_in": "x-hasura-visible-managements" + } + }, + "allow_aggregations": true } }, { "role": "reporter", "permission": { "columns": [ - "comment", - "id", - "ip_match", - "next_recert_date", - "owner_id", - "recert_date", - "recertified", - "rule_id", - "rule_metadata_id", - "user_dn" + "created", + "mgm_id", + "obj_id", + "removed", + "rule_id" ], - "filter": {}, + "filter": { + "mgm_id": { + "_in": "X-Hasura-visible-managements" + } + }, "allow_aggregations": true } }, @@ -7848,16 +19271,11 @@ "role": "reporter-viewall", "permission": { "columns": [ - "id", - "rule_id", - "rule_metadata_id", - "recertified", - "comment", - "ip_match", - "user_dn", - "owner_id", - "next_recert_date", - "recert_date" + "created", + "mgm_id", + "obj_id", + "removed", + "rule_id" ], "filter": {}, "allow_aggregations": true @@ -7866,524 +19284,419 @@ ], "update_permissions": [ { - "role": "recertifier", + "role": "importer", "permission": { "columns": [ - "id", + "created", + "obj_id", + "removed", "rule_id", - "rule_metadata_id", - "recertified", - "comment", - "ip_match", - "user_dn", - "owner_id", - "next_recert_date", - "recert_date" + "mgm_id" ], "filter": {}, - "check": null - } + "check": {} + }, + "comment": "" } ], "delete_permissions": [ { - "role": "middleware-server", + "role": "importer", "permission": { "filter": {} - } + }, + "comment": "" } ] }, { "table": { - "name": "report", + "name": "rule_owner", "schema": "public" }, "object_relationships": [ { - "name": "report_template", + "name": "importControlByRemoved", "using": { - "foreign_key_constraint_on": "report_template_id" + "foreign_key_constraint_on": "removed" } }, { - "name": "tenant", + "name": "import_control", "using": { - "foreign_key_constraint_on": "tenant_wide_visible" + "foreign_key_constraint_on": "created" } }, { - "name": "uiuser", + "name": "owner", "using": { - "foreign_key_constraint_on": "report_owner_id" - } - } - ], - "insert_permissions": [ - { - "role": "auditor", - "permission": { - "check": {}, - "columns": [ - "report_id", - "description", - "report_name", - "report_owner_id", - "report_template_id", - "report_type", - "tenant_wide_visible", - "report_json", - "report_csv", - "report_html", - "report_pdf", - "report_end_time", - "report_start_time" - ] - } - }, - { - "role": "fw-admin", - "permission": { - "check": {}, - "columns": [ - "report_id", - "description", - "report_name", - "report_owner_id", - "report_template_id", - "report_type", - "tenant_wide_visible", - "report_json", - "report_csv", - "report_html", - "report_pdf", - "report_end_time", - "report_start_time" - ] + "foreign_key_constraint_on": "owner_id" } }, { - "role": "middleware-server", - "permission": { - "check": {}, - "columns": [ - "report_id", - "description", - "report_name", - "report_owner_id", - "report_template_id", - "report_type", - "tenant_wide_visible", - "report_json", - "report_csv", - "report_html", - "report_pdf", - "report_end_time", - "report_start_time" - ] + "name": "rule", + "using": { + "foreign_key_constraint_on": "rule_id" } }, { - "role": "recertifier", - "permission": { - "check": {}, - "columns": [ - "report_id", - "description", - "report_name", - "report_owner_id", - "report_template_id", - "report_type", - "tenant_wide_visible", - "report_json", - "report_csv", - "report_html", - "report_pdf", - "report_end_time", - "report_start_time" - ] + "name": "rule_metadatum", + "using": { + "foreign_key_constraint_on": "rule_metadata_id" } - }, + } + ], + "insert_permissions": [ { - "role": "reporter", + "role": "importer", "permission": { "check": {}, "columns": [ - "report_id", - "description", - "report_name", - "report_owner_id", - "report_template_id", - "report_type", - "tenant_wide_visible", - "report_json", - "report_csv", - "report_html", - "report_pdf", - "report_end_time", - "report_start_time" + "created", + "matched_objects", + "owner_id", + "owner_mapping_source_id", + "removed", + "rule_id", + "rule_metadata_id" ] - } + }, + "comment": "" }, { - "role": "reporter-viewall", + "role": "middleware-server", "permission": { "check": {}, "columns": [ - "report_id", - "description", - "report_name", - "report_owner_id", - "report_template_id", - "report_type", - "tenant_wide_visible", - "report_json", - "report_csv", - "report_html", - "report_pdf", - "report_end_time", - "report_start_time" + "created", + "matched_objects", + "owner_id", + "owner_mapping_source_id", + "removed", + "rule_id", + "rule_metadata_id" ] - } + }, + "comment": "" } ], "select_permissions": [ { - "role": "auditor", + "role": "approver", "permission": { "columns": [ - "report_id", - "description", - "report_name", - "report_owner_id", - "report_template_id", - "report_type", - "tenant_wide_visible", - "report_json", - "report_csv", - "report_html", - "report_pdf", - "report_end_time", - "report_start_time" + "created", + "matched_objects", + "owner_id", + "owner_mapping_source_id", + "removed", + "rule_id", + "rule_metadata_id" ], "filter": {} - } + }, + "comment": "" }, { - "role": "fw-admin", + "role": "auditor", "permission": { "columns": [ - "report_id", - "description", - "report_name", - "report_owner_id", - "report_template_id", - "report_type", - "tenant_wide_visible", - "report_json", - "report_csv", - "report_html", - "report_pdf", - "report_end_time", - "report_start_time" + "created", + "matched_objects", + "owner_id", + "owner_mapping_source_id", + "removed", + "rule_id", + "rule_metadata_id" ], - "filter": { - "report_owner_id": { - "_eq": "X-Hasura-User-Id" - } - }, + "filter": {}, "allow_aggregations": true } }, { - "role": "recertifier", + "role": "fw-admin", "permission": { "columns": [ - "report_id", - "description", - "report_name", - "report_owner_id", - "report_template_id", - "report_type", - "tenant_wide_visible", - "report_json", - "report_csv", - "report_html", - "report_pdf", - "report_end_time", - "report_start_time" + "created", + "matched_objects", + "owner_id", + "owner_mapping_source_id", + "removed", + "rule_id", + "rule_metadata_id" ], - "filter": { - "report_owner_id": { - "_eq": "X-Hasura-User-Id" - } - }, + "filter": {}, "allow_aggregations": true - } + }, + "comment": "" }, { - "role": "reporter", + "role": "implementer", "permission": { "columns": [ - "report_id", - "description", - "report_name", - "report_owner_id", - "report_template_id", - "report_type", - "tenant_wide_visible", - "report_json", - "report_csv", - "report_html", - "report_pdf", - "report_end_time", - "report_start_time" + "created", + "matched_objects", + "owner_id", + "owner_mapping_source_id", + "removed", + "rule_id", + "rule_metadata_id" + ], + "filter": {} + }, + "comment": "" + }, + { + "role": "importer", + "permission": { + "columns": [ + "created", + "matched_objects", + "owner_id", + "owner_mapping_source_id", + "removed", + "rule_id", + "rule_metadata_id" ], - "filter": { - "report_owner_id": { - "_eq": "X-Hasura-User-Id" - } - }, - "allow_aggregations": true - } + "filter": {} + }, + "comment": "" }, { - "role": "reporter-viewall", + "role": "middleware-server", "permission": { "columns": [ - "report_id", - "description", - "report_name", - "report_owner_id", - "report_template_id", - "report_type", - "tenant_wide_visible", - "report_json", - "report_csv", - "report_html", - "report_pdf", - "report_end_time", - "report_start_time" + "created", + "matched_objects", + "owner_id", + "owner_mapping_source_id", + "removed", + "rule_id", + "rule_metadata_id" ], - "filter": { - "report_owner_id": { - "_eq": "X-Hasura-User-Id" - } - }, + "filter": {}, "allow_aggregations": true - } - } - ], - "update_permissions": [ + }, + "comment": "" + }, { - "role": "auditor", + "role": "modeller", "permission": { "columns": [ - "report_owner_id", - "report_template_id", - "report_type", - "description", - "tenant_wide_visible", - "report_id", - "report_json", - "report_csv", - "report_html", - "report_pdf", - "report_end_time", - "report_start_time", - "report_name" + "created", + "matched_objects", + "owner_id", + "owner_mapping_source_id", + "removed", + "rule_id", + "rule_metadata_id" ], - "filter": { - "report_owner_id": { - "_eq": "X-Hasura-User-Id" - } - }, - "check": null - } + "filter": {}, + "allow_aggregations": true + }, + "comment": "" }, { - "role": "fw-admin", + "role": "planner", "permission": { "columns": [ - "report_pdf", - "report_owner_id", - "report_template_id", - "report_type", - "description", - "tenant_wide_visible", - "report_id", - "report_json", - "report_csv", - "report_html", - "report_end_time", - "report_start_time", - "report_name" + "created", + "matched_objects", + "owner_id", + "owner_mapping_source_id", + "removed", + "rule_id", + "rule_metadata_id" ], - "filter": { - "report_owner_id": { - "_eq": "X-Hasura-User-Id" - } - }, - "check": null - } + "filter": {} + }, + "comment": "" }, { "role": "recertifier", "permission": { "columns": [ - "report_pdf", - "report_owner_id", - "report_template_id", - "report_type", - "description", - "tenant_wide_visible", - "report_id", - "report_json", - "report_csv", - "report_html", - "report_end_time", - "report_start_time", - "report_name" + "created", + "matched_objects", + "owner_id", + "owner_mapping_source_id", + "removed", + "rule_id", + "rule_metadata_id" ], - "filter": { - "report_owner_id": { - "_eq": "X-Hasura-User-Id" - } - }, - "check": null - } + "filter": {}, + "allow_aggregations": true + }, + "comment": "" }, { "role": "reporter", "permission": { "columns": [ - "report_pdf", - "report_owner_id", - "report_template_id", - "report_type", - "description", - "tenant_wide_visible", - "report_id", - "report_json", - "report_csv", - "report_html", - "report_end_time", - "report_start_time", - "report_name" + "created", + "matched_objects", + "owner_id", + "owner_mapping_source_id", + "removed", + "rule_id", + "rule_metadata_id" ], - "filter": { - "report_owner_id": { - "_eq": "X-Hasura-User-Id" - } - }, - "check": null - } + "filter": {}, + "allow_aggregations": true + }, + "comment": "" }, { "role": "reporter-viewall", "permission": { "columns": [ - "report_pdf", - "report_owner_id", - "report_template_id", - "report_type", - "description", - "tenant_wide_visible", - "report_id", - "report_json", - "report_csv", - "report_html", - "report_end_time", - "report_start_time", - "report_name" + "created", + "matched_objects", + "owner_id", + "owner_mapping_source_id", + "removed", + "rule_id", + "rule_metadata_id" ], - "filter": { - "report_owner_id": { - "_eq": "X-Hasura-User-Id" - } - }, - "check": null - } - } - ], - "delete_permissions": [ - { - "role": "auditor", - "permission": { - "filter": { - "report_owner_id": { - "_eq": "X-Hasura-User-Id" - } - } - } + "filter": {}, + "allow_aggregations": true + }, + "comment": "" }, { - "role": "fw-admin", + "role": "requester", "permission": { - "filter": { - "report_owner_id": { - "_eq": "X-Hasura-User-Id" - } - } - } + "columns": [ + "created", + "matched_objects", + "owner_id", + "owner_mapping_source_id", + "removed", + "rule_id", + "rule_metadata_id" + ], + "filter": {} + }, + "comment": "" }, { - "role": "recertifier", + "role": "reviewer", "permission": { - "filter": { - "report_owner_id": { - "_eq": "X-Hasura-User-Id" - } - } - } - }, + "columns": [ + "created", + "matched_objects", + "owner_id", + "owner_mapping_source_id", + "removed", + "rule_id", + "rule_metadata_id" + ], + "filter": {} + }, + "comment": "" + } + ], + "update_permissions": [ { - "role": "reporter", + "role": "importer", "permission": { - "filter": { - "report_owner_id": { - "_eq": "X-Hasura-User-Id" - } - } - } + "columns": [ + "created", + "matched_objects", + "owner_id", + "owner_mapping_source_id", + "removed", + "rule_id", + "rule_metadata_id" + ], + "filter": {}, + "check": {} + }, + "comment": "" }, { - "role": "reporter-viewall", + "role": "middleware-server", "permission": { - "filter": { - "report_owner_id": { - "_eq": "X-Hasura-User-Id" - } - } - } + "columns": [ + "removed" + ], + "filter": {}, + "check": {} + }, + "comment": "" + } + ], + "delete_permissions": [ + { + "role": "importer", + "permission": { + "filter": {} + }, + "comment": "" } ] }, { "table": { - "name": "report_format", + "name": "rule_service", "schema": "public" }, - "array_relationships": [ + "object_relationships": [ { - "name": "report_schedule_formats", + "name": "importControlByRsLastSeen", "using": { - "foreign_key_constraint_on": { - "column": "report_schedule_format_name", - "table": { - "name": "report_schedule_format", - "schema": "public" - } - } + "foreign_key_constraint_on": "rs_last_seen" + } + }, + { + "name": "import_control", + "using": { + "foreign_key_constraint_on": "rs_create" + } + }, + { + "name": "rule", + "using": { + "foreign_key_constraint_on": "rule_id" + } + }, + { + "name": "service", + "using": { + "foreign_key_constraint_on": "svc_id" } } ], + "insert_permissions": [ + { + "role": "importer", + "permission": { + "check": {}, + "columns": [ + "rs_create", + "removed", + "rs_last_seen", + "rule_id", + "svc_id", + "active", + "negated" + ] + }, + "comment": "" + } + ], "select_permissions": [ { "role": "auditor", "permission": { "columns": [ - "report_format_name" + "active", + "negated", + "removed", + "rs_create", + "rs_last_seen", + "rule_id", + "svc_id" ], "filter": {} } @@ -8392,171 +19705,195 @@ "role": "fw-admin", "permission": { "columns": [ - "report_format_name" + "active", + "negated", + "removed", + "rs_create", + "rs_last_seen", + "removed", + "rule_id", + "svc_id" ], "filter": {} } }, + { + "role": "importer", + "permission": { + "columns": [ + "removed", + "rs_create", + "rs_last_seen", + "rule_id", + "svc_id", + "active", + "negated" + ], + "filter": {}, + "allow_aggregations": true + }, + "comment": "" + }, { "role": "middleware-server", "permission": { "columns": [ - "report_format_name" + "active", + "negated", + "removed", + "rs_create", + "rs_last_seen", + "rule_id", + "svc_id" ], "filter": {} + }, + "comment": "" + }, + { + "role": "modeller", + "permission": { + "columns": [ + "active", + "negated", + "removed", + "rs_create", + "rs_last_seen", + "rule_id", + "svc_id" + ], + "filter": {}, + "allow_aggregations": true } }, { "role": "recertifier", "permission": { "columns": [ - "report_format_name" + "active", + "negated", + "removed", + "rs_create", + "rs_last_seen", + "rule_id", + "svc_id" ], - "filter": {} + "filter": {}, + "allow_aggregations": true } }, { "role": "reporter", "permission": { "columns": [ - "report_format_name" + "active", + "negated", + "removed", + "rs_create", + "rs_last_seen", + "rule_id", + "svc_id" ], - "filter": {} + "filter": {}, + "allow_aggregations": true } }, { "role": "reporter-viewall", "permission": { "columns": [ - "report_format_name" + "active", + "negated", + "removed", + "rs_create", + "rs_last_seen", + "rule_id", + "svc_id" ], "filter": {} } } + ], + "update_permissions": [ + { + "role": "importer", + "permission": { + "columns": [ + "removed", + "rs_create", + "rs_last_seen", + "rule_id", + "svc_id", + "active", + "negated" + ], + "filter": {}, + "check": {} + }, + "comment": "" + } + ], + "delete_permissions": [ + { + "role": "importer", + "permission": { + "filter": {} + }, + "comment": "" + } ] }, { "table": { - "name": "report_schedule", + "name": "rule_svc_resolved", "schema": "public" }, "object_relationships": [ { - "name": "report_template", + "name": "importControlByCreated", "using": { - "foreign_key_constraint_on": "report_template_id" + "foreign_key_constraint_on": "created" } }, { - "name": "uiuser", - "using": { - "foreign_key_constraint_on": "report_schedule_owner" - } - } - ], - "array_relationships": [ - { - "name": "report_schedule_formats", + "name": "import_control", "using": { - "foreign_key_constraint_on": { - "column": "report_schedule_id", - "table": { - "name": "report_schedule_format", - "schema": "public" - } - } - } - } - ], - "insert_permissions": [ - { - "role": "auditor", - "permission": { - "check": {}, - "columns": [ - "report_schedule_active", - "report_schedule_every", - "report_schedule_id", - "report_schedule_name", - "report_schedule_owner", - "report_schedule_repeat", - "report_schedule_start_time", - "report_schedule_counter", - "report_template_id" - ] - } - }, - { - "role": "fw-admin", - "permission": { - "check": {}, - "columns": [ - "report_schedule_active", - "report_schedule_every", - "report_schedule_id", - "report_schedule_name", - "report_schedule_owner", - "report_schedule_repeat", - "report_schedule_repetitions", - "report_schedule_start_time", - "report_schedule_counter", - "report_template_id" - ] - } - }, - { - "role": "recertifier", - "permission": { - "check": {}, - "columns": [ - "report_schedule_active", - "report_schedule_every", - "report_schedule_id", - "report_schedule_name", - "report_schedule_owner", - "report_schedule_repeat", - "report_schedule_repetitions", - "report_schedule_start_time", - "report_schedule_counter", - "report_template_id" - ] + "foreign_key_constraint_on": "removed" } }, { - "role": "reporter", - "permission": { - "check": {}, - "columns": [ - "report_schedule_active", - "report_schedule_every", - "report_schedule_id", - "report_schedule_name", - "report_schedule_owner", - "report_schedule_repeat", - "report_schedule_repetitions", - "report_schedule_start_time", - "report_schedule_counter", - "report_template_id" - ] + "name": "management", + "using": { + "foreign_key_constraint_on": "mgm_id" } }, { - "role": "reporter-viewall", + "name": "rule", + "using": { + "foreign_key_constraint_on": "rule_id" + } + }, + { + "name": "service", + "using": { + "foreign_key_constraint_on": "svc_id" + } + } + ], + "insert_permissions": [ + { + "role": "importer", "permission": { "check": {}, "columns": [ - "report_schedule_active", - "report_schedule_every", - "report_schedule_id", - "report_schedule_name", - "report_schedule_owner", - "report_schedule_repeat", - "report_schedule_repetitions", - "report_schedule_start_time", - "report_schedule_counter", - "report_template_id" + "created", + "removed", + "rule_id", + "svc_id", + "mgm_id" ] - } + }, + "comment": "" } ], "select_permissions": [ @@ -8564,430 +19901,397 @@ "role": "auditor", "permission": { "columns": [ - "report_schedule_id", - "report_schedule_name", - "report_template_id", - "report_schedule_owner", - "report_schedule_start_time", - "report_schedule_repeat", - "report_schedule_every", - "report_schedule_active", - "report_schedule_counter", - "report_schedule_repetitions" + "mgm_id", + "created", + "removed", + "rule_id", + "svc_id" ], - "filter": {} + "filter": {}, + "allow_aggregations": true } }, { "role": "fw-admin", "permission": { "columns": [ - "report_schedule_active", - "report_schedule_every", - "report_schedule_id", - "report_schedule_name", - "report_schedule_owner", - "report_schedule_repeat", - "report_schedule_repetitions", - "report_schedule_start_time", - "report_schedule_counter", - "report_template_id" + "created", + "removed", + "rule_id", + "svc_id", + "mgm_id" ], - "filter": { - "_or": [ - { - "report_schedule_owner": { - "_eq": "X-Hasura-User-Id" - } - }, - { - "_exists": { - "_table": { - "name": "report_template_viewable_by_user", - "schema": "public" - }, - "_where": { - "uiuser_id": { - "_eq": "X-Hasura-User-Id" - } - } - } - } - ] - } + "filter": {}, + "allow_aggregations": true } }, { - "role": "middleware-server", + "role": "importer", "permission": { "columns": [ - "report_schedule_id", - "report_schedule_name", - "report_template_id", - "report_schedule_owner", - "report_schedule_start_time", - "report_schedule_repeat", - "report_schedule_every", - "report_schedule_active", - "report_schedule_counter", - "report_schedule_repetitions" + "created", + "removed", + "rule_id", + "svc_id", + "mgm_id" ], "filter": {}, "allow_aggregations": true - } + }, + "comment": "" }, { "role": "recertifier", "permission": { "columns": [ - "report_schedule_active", - "report_schedule_every", - "report_schedule_id", - "report_schedule_name", - "report_schedule_owner", - "report_schedule_repeat", - "report_schedule_repetitions", - "report_schedule_start_time", - "report_schedule_counter", - "report_template_id" + "mgm_id", + "rule_id", + "svc_id", + "created", + "removed" ], "filter": { - "report_schedule_owner": { - "_eq": "X-Hasura-User-Id" + "mgm_id": { + "_in": "x-hasura-visible-managements" } - } + }, + "allow_aggregations": true } }, { "role": "reporter", "permission": { "columns": [ - "report_schedule_active", - "report_schedule_every", - "report_schedule_id", - "report_schedule_name", - "report_schedule_owner", - "report_schedule_repeat", - "report_schedule_repetitions", - "report_schedule_start_time", - "report_schedule_counter", - "report_template_id" + "mgm_id", + "created", + "removed", + "rule_id", + "svc_id" ], "filter": { - "report_schedule_owner": { - "_eq": "X-Hasura-User-Id" + "mgm_id": { + "_in": "X-Hasura-visible-managements" } - } + }, + "allow_aggregations": true } }, { "role": "reporter-viewall", "permission": { "columns": [ - "report_schedule_active", - "report_schedule_every", - "report_schedule_id", - "report_schedule_name", - "report_schedule_owner", - "report_schedule_repeat", - "report_schedule_repetitions", - "report_schedule_start_time", - "report_schedule_counter", - "report_template_id" + "mgm_id", + "created", + "removed", + "rule_id", + "svc_id" ], - "filter": { - "_or": [ - { - "report_schedule_owner": { - "_eq": "X-Hasura-User-Id" - } - }, - { - "_exists": { - "_table": { - "name": "report_template_viewable_by_user", - "schema": "public" - }, - "_where": { - "uiuser_id": { - "_eq": "X-Hasura-User-Id" - } - } - } - } - ] - } + "filter": {}, + "allow_aggregations": true } } ], "update_permissions": [ { - "role": "auditor", + "role": "importer", "permission": { "columns": [ - "report_schedule_active", - "report_schedule_every", - "report_schedule_id", - "report_schedule_name", - "report_schedule_owner", - "report_schedule_repeat", - "report_schedule_start_time", - "report_schedule_counter", - "report_template_id" + "created", + "removed", + "rule_id", + "svc_id", + "mgm_id" ], - "filter": { - "report_schedule_owner": { - "_eq": "X-Hasura-User-Id" - } - }, - "check": null + "filter": {}, + "check": {} + }, + "comment": "" + } + ], + "delete_permissions": [ + { + "role": "importer", + "permission": { + "filter": {} + }, + "comment": "" + } + ] + }, + { + "table": { + "name": "rule_time", + "schema": "public" + }, + "object_relationships": [ + { + "name": "import_control_created", + "using": { + "foreign_key_constraint_on": "created" + } + }, + { + "name": "import_control_removed", + "using": { + "foreign_key_constraint_on": "removed" + } + }, + { + "name": "rule", + "using": { + "foreign_key_constraint_on": "rule_id" } }, { - "role": "fw-admin", + "name": "time_object", + "using": { + "foreign_key_constraint_on": "time_obj_id" + } + } + ], + "insert_permissions": [ + { + "role": "importer", + "permission": { + "check": {}, + "columns": [ + "created", + "removed", + "rule_id", + "rule_time_id", + "time_obj_id" + ] + }, + "comment": "" + } + ], + "select_permissions": [ + { + "role": "auditor", "permission": { "columns": [ - "report_schedule_active", - "report_schedule_every", - "report_schedule_id", - "report_schedule_name", - "report_schedule_owner", - "report_schedule_repeat", - "report_schedule_repetitions", - "report_schedule_start_time", - "report_schedule_counter", - "report_template_id" + "created", + "removed", + "rule_id", + "rule_time_id", + "time_obj_id" ], - "filter": { - "report_schedule_owner": { - "_eq": "X-Hasura-User-Id" - } - }, - "check": null - } + "filter": {} + }, + "comment": "" }, { - "role": "recertifier", + "role": "fw-admin", "permission": { "columns": [ - "report_schedule_active", - "report_schedule_every", - "report_schedule_id", - "report_schedule_name", - "report_schedule_owner", - "report_schedule_repeat", - "report_schedule_repetitions", - "report_schedule_start_time", - "report_schedule_counter", - "report_template_id" + "created", + "removed", + "rule_id", + "rule_time_id", + "time_obj_id" ], - "filter": { - "report_schedule_owner": { - "_eq": "X-Hasura-User-Id" - } - }, - "check": null - } + "filter": {} + }, + "comment": "" }, { - "role": "reporter", + "role": "importer", "permission": { "columns": [ - "report_schedule_active", - "report_schedule_every", - "report_schedule_id", - "report_schedule_name", - "report_schedule_owner", - "report_schedule_repeat", - "report_schedule_repetitions", - "report_schedule_start_time", - "report_schedule_counter", - "report_template_id" + "created", + "removed", + "rule_id", + "rule_time_id", + "time_obj_id" ], - "filter": { - "report_schedule_owner": { - "_eq": "X-Hasura-User-Id" - } - }, - "check": null - } + "filter": {} + }, + "comment": "" }, { - "role": "reporter-viewall", + "role": "middleware-server", "permission": { "columns": [ - "report_schedule_active", - "report_schedule_every", - "report_schedule_id", - "report_schedule_name", - "report_schedule_owner", - "report_schedule_repeat", - "report_schedule_repetitions", - "report_schedule_start_time", - "report_schedule_counter", - "report_template_id" + "created", + "removed", + "rule_id", + "rule_time_id", + "time_obj_id" ], - "filter": { - "report_schedule_owner": { - "_eq": "X-Hasura-User-Id" - } - }, - "check": null - } - } - ], - "delete_permissions": [ - { - "role": "auditor", - "permission": { - "filter": { - "report_schedule_owner": { - "_eq": "X-Hasura-User-Id" - } - } - } + "filter": {} + }, + "comment": "" }, { - "role": "fw-admin", + "role": "modeller", "permission": { + "columns": [ + "created", + "removed", + "rule_id", + "rule_time_id", + "time_obj_id" + ], "filter": { - "report_schedule_owner": { - "_eq": "X-Hasura-User-Id" + "rule": { + "mgm_id": { + "_in": "x-hasura-visible-managements" + } } } - } + }, + "comment": "" }, { "role": "recertifier", "permission": { + "columns": [ + "created", + "removed", + "rule_id", + "rule_time_id", + "time_obj_id" + ], "filter": { - "report_schedule_owner": { - "_eq": "X-Hasura-User-Id" + "rule": { + "mgm_id": { + "_in": "x-hasura-visible-managements" + } } } - } + }, + "comment": "" }, { "role": "reporter", "permission": { + "columns": [ + "created", + "removed", + "rule_id", + "rule_time_id", + "time_obj_id" + ], "filter": { - "report_schedule_owner": { - "_eq": "X-Hasura-User-Id" + "rule": { + "mgm_id": { + "_in": "x-hasura-visible-managements" + } } - } - } + }, + "allow_aggregations": true + }, + "comment": "" }, { "role": "reporter-viewall", "permission": { - "filter": { - "report_schedule_owner": { - "_eq": "X-Hasura-User-Id" - } - } - } + "columns": [ + "created", + "removed", + "rule_id", + "rule_time_id", + "time_obj_id" + ], + "filter": {} + }, + "comment": "" + } + ], + "update_permissions": [ + { + "role": "importer", + "permission": { + "columns": [ + "created", + "removed", + "rule_id", + "rule_time_id", + "time_obj_id" + ], + "filter": {}, + "check": {} + }, + "comment": "" + } + ], + "delete_permissions": [ + { + "role": "importer", + "permission": { + "filter": {} + }, + "comment": "" } ] }, { "table": { - "name": "report_schedule_format", + "name": "rule_to", "schema": "public" }, "object_relationships": [ { - "name": "report_format", + "name": "importControlByRtLastSeen", "using": { - "foreign_key_constraint_on": "report_schedule_format_name" + "foreign_key_constraint_on": "rt_last_seen" } }, { - "name": "report_schedule", + "name": "import_control", "using": { - "foreign_key_constraint_on": "report_schedule_id" + "foreign_key_constraint_on": "rt_create" } - } - ], - "insert_permissions": [ + }, { - "role": "auditor", - "permission": { - "check": { - "report_schedule": { - "report_schedule_owner": { - "_eq": "X-Hasura-User-Id" - } - } - }, - "columns": [ - "report_schedule_format_name", - "report_schedule_id" - ] + "name": "object", + "using": { + "foreign_key_constraint_on": "obj_id" } }, { - "role": "fw-admin", - "permission": { - "check": { - "report_schedule": { - "report_schedule_owner": { - "_eq": "X-Hasura-User-Id" - } - } - }, - "columns": [ - "report_schedule_format_name", - "report_schedule_id" - ] + "name": "rule", + "using": { + "foreign_key_constraint_on": "rule_id" } }, { - "role": "recertifier", - "permission": { - "check": { - "report_schedule": { - "report_schedule_owner": { - "_eq": "X-Hasura-User-Id" - } - } - }, - "columns": [ - "report_schedule_format_name", - "report_schedule_id" - ] + "name": "usr", + "using": { + "foreign_key_constraint_on": "user_id" } - }, + } + ], + "computed_fields": [ { - "role": "reporter", - "permission": { - "check": { - "report_schedule": { - "report_schedule_owner": { - "_eq": "X-Hasura-User-Id" - } - } + "name": "rule_to_relevant_for_tenant", + "definition": { + "function": { + "name": "rule_to_relevant_for_tenant", + "schema": "public" }, - "columns": [ - "report_schedule_format_name", - "report_schedule_id" - ] + "session_argument": "hasura_session" } - }, + } + ], + "insert_permissions": [ { - "role": "reporter-viewall", + "role": "importer", "permission": { - "check": { - "report_schedule": { - "report_schedule_owner": { - "_eq": "X-Hasura-User-Id" - } - } - }, + "check": {}, "columns": [ - "report_schedule_format_name", - "report_schedule_id" + "obj_id", + "removed", + "rt_create", + "rt_last_seen", + "rule_id", + "rule_to_id", + "user_id", + "active", + "negated" ] - } + }, + "comment": "" } ], "select_permissions": [ @@ -8995,8 +20299,18 @@ "role": "auditor", "permission": { "columns": [ - "report_schedule_format_name", - "report_schedule_id" + "active", + "negated", + "obj_id", + "removed", + "rt_create", + "rt_last_seen", + "rule_id", + "rule_to_id", + "user_id" + ], + "computed_fields": [ + "rule_to_relevant_for_tenant" ], "filter": {} } @@ -9005,829 +20319,1037 @@ "role": "fw-admin", "permission": { "columns": [ - "report_schedule_format_name", - "report_schedule_id" + "active", + "negated", + "obj_id", + "removed", + "rt_create", + "rt_last_seen", + "rule_id", + "rule_to_id", + "user_id" ], - "filter": { - "report_schedule": { - "report_schedule_owner": { - "_eq": "X-Hasura-User-Id" - } - } - } - } - }, - { - "role": "middleware-server", - "permission": { - "columns": [ - "report_schedule_format_name", - "report_schedule_id" + "computed_fields": [ + "rule_to_relevant_for_tenant" ], "filter": {} } }, { - "role": "recertifier", + "role": "importer", "permission": { "columns": [ - "report_schedule_format_name", - "report_schedule_id" + "obj_id", + "removed", + "rt_create", + "rt_last_seen", + "rule_id", + "rule_to_id", + "user_id", + "active", + "negated" ], - "filter": { - "report_schedule": { - "report_schedule_owner": { - "_eq": "X-Hasura-User-Id" - } - } - } - } - }, - { - "role": "reporter", - "permission": { - "columns": [ - "report_schedule_format_name", - "report_schedule_id" + "computed_fields": [ + "rule_to_relevant_for_tenant" ], - "filter": { - "report_schedule": { - "report_schedule_owner": { - "_eq": "X-Hasura-User-Id" - } - } - } - } + "filter": {}, + "allow_aggregations": true + }, + "comment": "" }, { - "role": "reporter-viewall", + "role": "middleware-server", "permission": { "columns": [ - "report_schedule_format_name", - "report_schedule_id" + "active", + "negated", + "obj_id", + "removed", + "rt_create", + "rt_last_seen", + "rule_id", + "rule_to_id", + "user_id" ], - "filter": { - "report_schedule": { - "report_schedule_owner": { - "_eq": "X-Hasura-User-Id" - } - } - } - } - } - ], - "update_permissions": [ - { - "role": "auditor", - "permission": { - "columns": [ - "report_schedule_id", - "report_schedule_format_name" + "computed_fields": [ + "rule_to_relevant_for_tenant" ], - "filter": { - "report_schedule": { - "report_schedule_owner": { - "_eq": "X-Hasura-User-Id" - } - } - }, - "check": null + "filter": {} } }, { - "role": "fw-admin", + "role": "modeller", "permission": { "columns": [ - "report_schedule_format_name", - "report_schedule_id" + "active", + "negated", + "obj_id", + "removed", + "rt_create", + "rt_last_seen", + "rule_id", + "rule_to_id", + "user_id" ], - "filter": { - "report_schedule": { - "report_schedule_owner": { - "_eq": "X-Hasura-User-Id" - } - } - }, - "check": { - "report_schedule": { - "report_schedule_owner": { - "_eq": "X-Hasura-User-Id" - } - } - } - } - }, - { - "role": "recertifier", - "permission": { - "columns": [ - "report_schedule_format_name", - "report_schedule_id" + "computed_fields": [ + "rule_to_relevant_for_tenant" ], - "filter": { - "report_schedule": { - "report_schedule_owner": { - "_eq": "X-Hasura-User-Id" - } - } - }, - "check": { - "report_schedule": { - "report_schedule_owner": { - "_eq": "X-Hasura-User-Id" - } - } - } + "filter": {}, + "allow_aggregations": true } }, { - "role": "reporter", + "role": "recertifier", "permission": { "columns": [ - "report_schedule_format_name", - "report_schedule_id" + "active", + "negated", + "obj_id", + "removed", + "rt_create", + "rt_last_seen", + "rule_id", + "rule_to_id", + "user_id" ], - "filter": { - "report_schedule": { - "report_schedule_owner": { - "_eq": "X-Hasura-User-Id" - } - } - }, - "check": { - "report_schedule": { - "report_schedule_owner": { - "_eq": "X-Hasura-User-Id" - } - } - } - } - }, - { - "role": "reporter-viewall", - "permission": { - "columns": [ - "report_schedule_format_name", - "report_schedule_id" + "computed_fields": [ + "rule_to_relevant_for_tenant" ], "filter": { - "report_schedule": { - "report_schedule_owner": { - "_eq": "X-Hasura-User-Id" - } - } - }, - "check": { - "report_schedule": { - "report_schedule_owner": { - "_eq": "X-Hasura-User-Id" - } - } - } - } - } - ], - "delete_permissions": [ - { - "role": "auditor", - "permission": { - "filter": { - "report_schedule": { - "report_schedule_owner": { - "_eq": "X-Hasura-User-Id" + "_and": [ + { + "rule": { + "mgm_id": { + "_in": "x-hasura-visible-managements" + } + } + }, + { + "rule_to_relevant_for_tenant": { + "_eq": "true" + } } - } - } + ] + }, + "allow_aggregations": true } }, { - "role": "fw-admin", + "role": "reporter", "permission": { + "columns": [ + "active", + "negated", + "obj_id", + "removed", + "rt_create", + "rt_last_seen", + "rule_id", + "rule_to_id", + "user_id" + ], + "computed_fields": [ + "rule_to_relevant_for_tenant" + ], "filter": { - "report_schedule": { - "report_schedule_owner": { - "_eq": "X-Hasura-User-Id" + "_and": [ + { + "rule": { + "mgm_id": { + "_in": "x-hasura-visible-managements" + } + } + }, + { + "rule_to_relevant_for_tenant": { + "_eq": "true" + } } - } - } + ] + }, + "allow_aggregations": true } }, { - "role": "recertifier", + "role": "reporter-viewall", "permission": { - "filter": { - "report_schedule": { - "report_schedule_owner": { - "_eq": "X-Hasura-User-Id" - } - } - } + "columns": [ + "active", + "negated", + "obj_id", + "removed", + "rt_create", + "rt_last_seen", + "rule_id", + "rule_to_id", + "user_id" + ], + "computed_fields": [ + "rule_to_relevant_for_tenant" + ], + "filter": {} } - }, + } + ], + "update_permissions": [ { - "role": "reporter", + "role": "importer", "permission": { - "filter": { - "report_schedule": { - "report_schedule_owner": { - "_eq": "X-Hasura-User-Id" - } - } - } - } - }, + "columns": [ + "obj_id", + "removed", + "rt_create", + "rt_last_seen", + "rule_id", + "rule_to_id", + "user_id", + "active", + "negated" + ], + "filter": {}, + "check": {} + }, + "comment": "" + } + ], + "delete_permissions": [ { - "role": "reporter-viewall", + "role": "importer", "permission": { - "filter": { - "report_schedule": { - "report_schedule_owner": { - "_eq": "X-Hasura-User-Id" - } - } - } - } + "filter": {} + }, + "comment": "" } ] }, { "table": { - "name": "report_template", + "name": "rule_to_zone", "schema": "public" }, "object_relationships": [ { - "name": "uiuser", - "using": { - "foreign_key_constraint_on": "report_template_owner" - } - } - ], - "array_relationships": [ - { - "name": "report_schedules", - "using": { - "foreign_key_constraint_on": { - "column": "report_template_id", - "table": { - "name": "report_schedule", - "schema": "public" - } - } - } - }, - { - "name": "report_template_viewable_by_users", + "name": "rule", "using": { - "foreign_key_constraint_on": { - "column": "report_template_id", - "table": { - "name": "report_template_viewable_by_user", - "schema": "public" - } - } + "foreign_key_constraint_on": "rule_id" } }, { - "name": "reports", + "name": "zone", "using": { - "foreign_key_constraint_on": { - "column": "report_template_id", - "table": { - "name": "report", - "schema": "public" - } - } + "foreign_key_constraint_on": "zone_id" } } ], "insert_permissions": [ { - "role": "auditor", + "role": "importer", "permission": { "check": {}, "columns": [ - "filterline_history", - "report_filter", - "report_parameters", - "report_template_comment", - "report_template_create", - "report_template_id", - "report_template_name", - "report_template_owner" + "created", + "removed", + "rule_id", + "zone_id" ] - } + }, + "comment": "" + } + ], + "select_permissions": [ + { + "role": "auditor", + "permission": { + "columns": [ + "created", + "removed", + "rule_id", + "zone_id" + ], + "filter": {}, + "allow_aggregations": true + }, + "comment": "" }, { "role": "fw-admin", "permission": { - "check": {}, "columns": [ - "filterline_history", - "report_filter", - "report_parameters", - "report_template_comment", - "report_template_create", - "report_template_id", - "report_template_name", - "report_template_owner" - ] - } + "created", + "removed", + "rule_id", + "zone_id" + ], + "filter": {}, + "allow_aggregations": true + }, + "comment": "" + }, + { + "role": "importer", + "permission": { + "columns": [ + "created", + "removed", + "rule_id", + "zone_id" + ], + "filter": {}, + "allow_aggregations": true + }, + "comment": "" + }, + { + "role": "middleware-server", + "permission": { + "columns": [ + "created", + "removed", + "rule_id", + "zone_id" + ], + "filter": {} + }, + "comment": "" + }, + { + "role": "modeller", + "permission": { + "columns": [ + "created", + "removed", + "rule_id", + "zone_id" + ], + "filter": {}, + "allow_aggregations": true + }, + "comment": "" }, { "role": "recertifier", "permission": { - "check": {}, "columns": [ - "filterline_history", - "report_filter", - "report_parameters", - "report_template_comment", - "report_template_create", - "report_template_id", - "report_template_name", - "report_template_owner" - ] - } + "created", + "removed", + "rule_id", + "zone_id" + ], + "filter": {}, + "allow_aggregations": true + }, + "comment": "" }, { "role": "reporter", "permission": { - "check": {}, "columns": [ - "filterline_history", - "report_filter", - "report_parameters", - "report_template_comment", - "report_template_create", - "report_template_id", - "report_template_name", - "report_template_owner" - ] - } + "created", + "removed", + "rule_id", + "zone_id" + ], + "filter": {}, + "allow_aggregations": true + }, + "comment": "" }, { "role": "reporter-viewall", "permission": { - "check": {}, "columns": [ - "filterline_history", - "report_filter", - "report_parameters", - "report_template_comment", - "report_template_create", - "report_template_id", - "report_template_name", - "report_template_owner" - ] - } + "created", + "removed", + "rule_id", + "zone_id" + ], + "filter": {}, + "allow_aggregations": true + }, + "comment": "" } ], - "select_permissions": [ + "update_permissions": [ { - "role": "auditor", + "role": "importer", "permission": { "columns": [ - "filterline_history", - "report_filter", - "report_parameters", - "report_template_comment", - "report_template_create", - "report_template_id", - "report_template_name", - "report_template_owner" + "created", + "removed", + "rule_id", + "zone_id" ], + "filter": {}, + "check": {} + }, + "comment": "" + } + ], + "delete_permissions": [ + { + "role": "importer", + "permission": { "filter": {} + }, + "comment": "" + } + ] + }, + { + "table": { + "name": "rule_user_resolved", + "schema": "public" + }, + "object_relationships": [ + { + "name": "importControlByCreated", + "using": { + "foreign_key_constraint_on": "created" } }, { - "role": "fw-admin", - "permission": { - "columns": [ - "filterline_history", - "report_filter", - "report_parameters", - "report_template_comment", - "report_template_create", - "report_template_id", - "report_template_name", - "report_template_owner" - ], - "filter": { - "_or": [ - { - "report_template_owner": { - "_eq": 0 - } - }, - { - "report_template_owner": { - "_eq": "X-Hasura-User-Id" - } - } - ] - } + "name": "import_control", + "using": { + "foreign_key_constraint_on": "removed" } }, { - "role": "middleware-server", - "permission": { - "columns": [ - "filterline_history", - "report_filter", - "report_parameters", - "report_template_comment", - "report_template_create", - "report_template_id", - "report_template_name", - "report_template_owner" - ], - "filter": {}, - "allow_aggregations": true + "name": "management", + "using": { + "foreign_key_constraint_on": "mgm_id" } }, { - "role": "recertifier", - "permission": { - "columns": [ - "filterline_history", - "report_filter", - "report_parameters", - "report_template_comment", - "report_template_create", - "report_template_id", - "report_template_name", - "report_template_owner" - ], - "filter": { - "_or": [ - { - "report_template_owner": { - "_eq": 0 - } - }, - { - "report_template_owner": { - "_eq": "X-Hasura-User-Id" - } - } - ] - } + "name": "rule", + "using": { + "foreign_key_constraint_on": "rule_id" } }, { - "role": "reporter", - "permission": { - "columns": [ - "filterline_history", - "report_filter", - "report_parameters", - "report_template_comment", - "report_template_create", - "report_template_id", - "report_template_name", - "report_template_owner" - ], - "filter": { - "_or": [ - { - "report_template_owner": { - "_eq": 0 - } - }, - { - "report_template_owner": { - "_eq": "X-Hasura-User-Id" - } - } - ] - } + "name": "usr", + "using": { + "foreign_key_constraint_on": "user_id" } - }, + } + ], + "insert_permissions": [ { - "role": "reporter-viewall", + "role": "importer", "permission": { + "check": {}, "columns": [ - "filterline_history", - "report_filter", - "report_parameters", - "report_template_comment", - "report_template_create", - "report_template_id", - "report_template_name", - "report_template_owner" - ], - "filter": { - "_or": [ - { - "report_template_owner": { - "_eq": 0 - } - }, - { - "report_template_owner": { - "_eq": "X-Hasura-User-Id" - } - } - ] - } - } + "created", + "removed", + "rule_id", + "user_id", + "mgm_id" + ] + }, + "comment": "" } ], - "update_permissions": [ + "select_permissions": [ { "role": "auditor", "permission": { "columns": [ - "filterline_history", - "report_filter", - "report_parameters", - "report_template_comment", - "report_template_create", - "report_template_id", - "report_template_name", - "report_template_owner" + "mgm_id", + "rule_id", + "user_id", + "created", + "removed" ], - "filter": { - "report_template_owner": { - "_eq": "X-Hasura-User-Id" - } - }, - "check": null + "filter": {}, + "allow_aggregations": true } }, { "role": "fw-admin", "permission": { "columns": [ - "filterline_history", - "report_filter", - "report_parameters", - "report_template_comment", - "report_template_create", - "report_template_id", - "report_template_name", - "report_template_owner" + "created", + "removed", + "rule_id", + "user_id", + "mgm_id" ], - "filter": { - "report_template_owner": { - "_eq": "X-Hasura-User-Id" - } - }, - "check": null + "filter": {}, + "allow_aggregations": true } }, { - "role": "recertifier", + "role": "importer", "permission": { "columns": [ - "filterline_history", - "report_filter", - "report_parameters", - "report_template_comment", - "report_template_create", - "report_template_id", - "report_template_name", - "report_template_owner" + "created", + "removed", + "rule_id", + "user_id", + "mgm_id" + ], + "filter": {}, + "allow_aggregations": true + }, + "comment": "" + }, + { + "role": "recertifier", + "permission": { + "columns": [ + "mgm_id", + "created", + "removed", + "rule_id", + "user_id" ], "filter": { - "report_template_owner": { - "_eq": "X-Hasura-User-Id" + "mgm_id": { + "_in": "x-hasura-visible-managements" } }, - "check": null + "allow_aggregations": true } }, { "role": "reporter", "permission": { "columns": [ - "filterline_history", - "report_filter", - "report_parameters", - "report_template_comment", - "report_template_create", - "report_template_id", - "report_template_name", - "report_template_owner" + "mgm_id", + "rule_id", + "user_id", + "created", + "removed" ], "filter": { - "report_template_owner": { - "_eq": "X-Hasura-User-Id" + "mgm_id": { + "_in": "X-Hasura-visible-managements" } }, - "check": null + "allow_aggregations": true } }, { "role": "reporter-viewall", "permission": { "columns": [ - "filterline_history", - "report_filter", - "report_parameters", - "report_template_comment", - "report_template_create", - "report_template_id", - "report_template_name", - "report_template_owner" + "mgm_id", + "created", + "removed", + "rule_id", + "user_id" ], - "filter": { - "report_template_owner": { - "_eq": "X-Hasura-User-Id" - } - }, - "check": null + "filter": {}, + "allow_aggregations": true } } ], + "update_permissions": [ + { + "role": "importer", + "permission": { + "columns": [ + "created", + "removed", + "rule_id", + "user_id", + "mgm_id" + ], + "filter": {}, + "check": {} + }, + "comment": "" + } + ], "delete_permissions": [ { - "role": "auditor", + "role": "importer", "permission": { - "filter": { - "report_template_owner": { - "_eq": "X-Hasura-User-Id" + "filter": {} + }, + "comment": "" + } + ] + }, + { + "table": { + "name": "rulebase", + "schema": "public" + }, + "object_relationships": [ + { + "name": "management", + "using": { + "foreign_key_constraint_on": "mgm_id" + } + } + ], + "array_relationships": [ + { + "name": "rulebaseLinksByFromRulebaseId", + "using": { + "foreign_key_constraint_on": { + "column": "from_rulebase_id", + "table": { + "name": "rulebase_link", + "schema": "public" } } } }, { - "role": "fw-admin", - "permission": { - "filter": { - "report_template_owner": { - "_eq": "X-Hasura-User-Id" + "name": "rulebase_links", + "using": { + "foreign_key_constraint_on": { + "column": "to_rulebase_id", + "table": { + "name": "rulebase_link", + "schema": "public" } } } }, { - "role": "recertifier", - "permission": { - "filter": { - "report_template_owner": { - "_eq": "X-Hasura-User-Id" + "name": "rules", + "using": { + "foreign_key_constraint_on": { + "column": "rulebase_id", + "table": { + "name": "rule", + "schema": "public" } } } + } + ], + "computed_fields": [ + { + "name": "get_rules_for_owner", + "definition": { + "function": { + "name": "get_rulebase_for_owner", + "schema": "public" + } + } + } + ], + "insert_permissions": [ + { + "role": "importer", + "permission": { + "check": {}, + "columns": [ + "created", + "removed", + "is_global", + "name", + "uid", + "id", + "mgm_id" + ] + }, + "comment": "" + } + ], + "select_permissions": [ + { + "role": "auditor", + "permission": { + "columns": [ + "created", + "removed", + "is_global", + "name", + "uid", + "id", + "mgm_id" + ], + "filter": {}, + "allow_aggregations": true + }, + "comment": "" + }, + { + "role": "importer", + "permission": { + "columns": [ + "created", + "removed", + "is_global", + "name", + "uid", + "id", + "mgm_id" + ], + "filter": {}, + "allow_aggregations": true + }, + "comment": "" + }, + { + "role": "middleware-server", + "permission": { + "columns": [ + "created", + "removed", + "is_global", + "name", + "uid", + "id", + "mgm_id" + ], + "filter": {} + }, + "comment": "" + }, + { + "role": "modeller", + "permission": { + "columns": [ + "created", + "removed", + "is_global", + "name", + "uid", + "id", + "mgm_id" + ], + "filter": {} + }, + "comment": "" + }, + { + "role": "recertifier", + "permission": { + "columns": [ + "created", + "removed", + "is_global", + "name", + "uid", + "id", + "mgm_id" + ], + "filter": {} + }, + "comment": "" }, { "role": "reporter", "permission": { - "filter": { - "report_template_owner": { - "_eq": "X-Hasura-User-Id" - } - } - } + "columns": [ + "created", + "removed", + "is_global", + "name", + "uid", + "id", + "mgm_id" + ], + "filter": {}, + "allow_aggregations": true + }, + "comment": "" }, { "role": "reporter-viewall", "permission": { - "filter": { - "report_template_owner": { - "_eq": "X-Hasura-User-Id" - } - } - } + "columns": [ + "created", + "removed", + "is_global", + "name", + "uid", + "id", + "mgm_id" + ], + "filter": {}, + "allow_aggregations": true + }, + "comment": "" + } + ], + "update_permissions": [ + { + "role": "importer", + "permission": { + "columns": [ + "created", + "removed", + "is_global", + "name", + "uid", + "id", + "mgm_id" + ], + "filter": {}, + "check": {} + }, + "comment": "" + } + ], + "delete_permissions": [ + { + "role": "importer", + "permission": { + "filter": {} + }, + "comment": "" } ] }, { "table": { - "name": "report_template_viewable_by_user", + "name": "rulebase_link", "schema": "public" }, "object_relationships": [ { - "name": "report_template", + "name": "device", "using": { - "foreign_key_constraint_on": "report_template_id" + "foreign_key_constraint_on": "gw_id" } }, { - "name": "uiuser", + "name": "importControlByRemoved", "using": { - "foreign_key_constraint_on": "uiuser_id" + "foreign_key_constraint_on": "removed" } - } - ] - }, - { - "table": { - "name": "reqtask_owner", - "schema": "public" - }, - "object_relationships": [ + }, { - "name": "owner", + "name": "import_control", "using": { - "foreign_key_constraint_on": "owner_id" + "foreign_key_constraint_on": "created" } }, { - "name": "reqtask", + "name": "rule", "using": { - "foreign_key_constraint_on": "reqtask_id" + "foreign_key_constraint_on": "from_rule_id" + } + }, + { + "name": "rulebase", + "using": { + "foreign_key_constraint_on": "to_rulebase_id" + } + }, + { + "name": "rulebaseByFromRulebaseId", + "using": { + "foreign_key_constraint_on": "from_rulebase_id" + } + }, + { + "name": "stm_link_type", + "using": { + "foreign_key_constraint_on": "link_type" } } ], + "insert_permissions": [ + { + "role": "importer", + "permission": { + "check": {}, + "columns": [ + "created", + "removed", + "is_global", + "is_initial", + "is_section", + "from_rulebase_id", + "from_rule_id", + "gw_id", + "id", + "link_type", + "to_rulebase_id" + ] + }, + "comment": "" + } + ], "select_permissions": [ { - "role": "approver", + "role": "auditor", "permission": { "columns": [ - "reqtask_id", - "owner_id" + "created", + "from_rule_id", + "removed", + "is_global", + "is_initial", + "is_section", + "from_rulebase_id", + "gw_id", + "id", + "link_type", + "to_rulebase_id" ], "filter": {} - } + }, + "comment": "" }, { - "role": "auditor", + "role": "importer", "permission": { "columns": [ - "reqtask_id", - "owner_id" + "created", + "removed", + "is_global", + "is_initial", + "is_section", + "from_rulebase_id", + "from_rule_id", + "gw_id", + "id", + "link_type", + "to_rulebase_id" ], - "filter": {} - } + "filter": {}, + "allow_aggregations": true + }, + "comment": "" }, { - "role": "fw-admin", + "role": "middleware-server", "permission": { "columns": [ - "reqtask_id", - "owner_id" + "created", + "from_rule_id", + "removed", + "is_global", + "is_initial", + "is_section", + "from_rulebase_id", + "gw_id", + "id", + "link_type", + "to_rulebase_id" ], "filter": {} - } + }, + "comment": "" }, { - "role": "implementer", + "role": "modeller", "permission": { "columns": [ - "reqtask_id", - "owner_id" + "created", + "from_rule_id", + "removed", + "is_global", + "is_initial", + "is_section", + "from_rulebase_id", + "gw_id", + "id", + "link_type", + "to_rulebase_id" ], "filter": {} - } + }, + "comment": "" }, { - "role": "planner", + "role": "recertifier", "permission": { "columns": [ - "reqtask_id", - "owner_id" + "created", + "from_rule_id", + "removed", + "is_global", + "is_initial", + "is_section", + "from_rulebase_id", + "gw_id", + "id", + "link_type", + "to_rulebase_id" ], "filter": {} - } + }, + "comment": "" }, { - "role": "requester", + "role": "reporter", "permission": { "columns": [ - "reqtask_id", - "owner_id" + "created", + "from_rule_id", + "removed", + "is_global", + "is_initial", + "is_section", + "from_rulebase_id", + "gw_id", + "id", + "link_type", + "to_rulebase_id" ], "filter": {} - } + }, + "comment": "" }, { - "role": "reviewer", + "role": "reporter-viewall", "permission": { "columns": [ - "reqtask_id", - "owner_id" + "created", + "from_rule_id", + "removed", + "is_global", + "is_initial", + "is_section", + "from_rulebase_id", + "gw_id", + "id", + "link_type", + "to_rulebase_id" ], "filter": {} - } + }, + "comment": "" + } + ], + "update_permissions": [ + { + "role": "importer", + "permission": { + "columns": [ + "removed" + ], + "filter": {}, + "check": {} + }, + "comment": "" + } + ], + "delete_permissions": [ + { + "role": "importer", + "permission": { + "filter": {} + }, + "comment": "" } ] }, { "table": { - "name": "rule", + "name": "service", "schema": "public" }, "object_relationships": [ { - "name": "device", - "using": { - "foreign_key_constraint_on": "dev_id" - } - }, - { - "name": "importControlByRuleLastSeen", + "name": "importControlBySvcLastSeen", "using": { - "foreign_key_constraint_on": "rule_last_seen" + "foreign_key_constraint_on": "svc_last_seen" } }, { "name": "import_control", "using": { - "foreign_key_constraint_on": "rule_create" + "foreign_key_constraint_on": "svc_create" } }, { @@ -9837,49 +21359,21 @@ } }, { - "name": "parentRuleTypeByParentRuleType", - "using": { - "foreign_key_constraint_on": "parent_rule_type" - } - }, - { - "name": "rule", - "using": { - "foreign_key_constraint_on": "parent_rule_id" - } - }, - { - "name": "ruleByXlateRule", - "using": { - "foreign_key_constraint_on": "xlate_rule" - } - }, - { - "name": "rule_metadatum", + "name": "stm_color", "using": { - "manual_configuration": { - "column_mapping": { - "dev_id": "dev_id", - "rule_uid": "rule_uid" - }, - "insertion_order": null, - "remote_table": { - "name": "rule_metadata", - "schema": "public" - } - } + "foreign_key_constraint_on": "svc_color_id" } }, { - "name": "stm_action", + "name": "stm_ip_proto", "using": { - "foreign_key_constraint_on": "action_id" + "foreign_key_constraint_on": "ip_proto_id" } }, { - "name": "stm_track", + "name": "stm_svc_typ", "using": { - "foreign_key_constraint_on": "track_id" + "foreign_key_constraint_on": "svc_typ_id" } }, { @@ -9887,65 +21381,77 @@ "using": { "foreign_key_constraint_on": "last_change_admin" } - }, + } + ], + "array_relationships": [ { - "name": "zone", + "name": "changelogServicesByOldSvcId", "using": { - "foreign_key_constraint_on": "rule_from_zone" + "foreign_key_constraint_on": { + "column": "old_svc_id", + "table": { + "name": "changelog_service", + "schema": "public" + } + } } }, { - "name": "zoneByRuleToZone", + "name": "changelog_services", "using": { - "foreign_key_constraint_on": "rule_to_zone" + "foreign_key_constraint_on": { + "column": "new_svc_id", + "table": { + "name": "changelog_service", + "schema": "public" + } + } } - } - ], - "array_relationships": [ + }, { - "name": "changelogRulesByOldRuleId", + "name": "elements", "using": { "foreign_key_constraint_on": { - "column": "old_rule_id", + "column": "service_id", "table": { - "name": "changelog_rule", - "schema": "public" + "name": "implelement", + "schema": "request" } } } }, { - "name": "changelog_rules", + "name": "impltasks", "using": { "foreign_key_constraint_on": { - "column": "new_rule_id", + "column": "svc_grp_id", "table": { - "name": "changelog_rule", - "schema": "public" + "name": "impltask", + "schema": "request" } } } }, { - "name": "rule_froms", + "name": "reqelements", "using": { "foreign_key_constraint_on": { - "column": "rule_id", + "column": "service_id", "table": { - "name": "rule_from", - "schema": "public" + "name": "reqelement", + "schema": "request" } } } }, { - "name": "rule_nwobj_resolveds", + "name": "reqtasks", "using": { "foreign_key_constraint_on": { - "column": "rule_id", + "column": "svc_grp_id", "table": { - "name": "rule_nwobj_resolved", - "schema": "public" + "name": "reqtask", + "schema": "request" } } } @@ -9954,7 +21460,7 @@ "name": "rule_services", "using": { "foreign_key_constraint_on": { - "column": "rule_id", + "column": "svc_id", "table": { "name": "rule_service", "schema": "public" @@ -9966,7 +21472,7 @@ "name": "rule_svc_resolveds", "using": { "foreign_key_constraint_on": { - "column": "rule_id", + "column": "svc_id", "table": { "name": "rule_svc_resolved", "schema": "public" @@ -9975,489 +21481,539 @@ } }, { - "name": "rule_tos", + "name": "svcgrpFlatsBySvcgrpFlatMemberId", "using": { "foreign_key_constraint_on": { - "column": "rule_id", + "column": "svcgrp_flat_member_id", "table": { - "name": "rule_to", + "name": "svcgrp_flat", "schema": "public" } } } }, { - "name": "rule_user_resolveds", + "name": "svcgrp_flats", "using": { "foreign_key_constraint_on": { - "column": "rule_id", + "column": "svcgrp_flat_id", "table": { - "name": "rule_user_resolved", + "name": "svcgrp_flat", "schema": "public" } } } }, { - "name": "rules", + "name": "svcgrps", "using": { "foreign_key_constraint_on": { - "column": "parent_rule_id", + "column": "svcgrp_id", "table": { - "name": "rule", + "name": "svcgrp", "schema": "public" } } } }, { - "name": "rulesByXlateRule", + "name": "svcgrpsBySvcgrpMemberId", "using": { "foreign_key_constraint_on": { - "column": "xlate_rule", + "column": "svcgrp_member_id", "table": { - "name": "rule", + "name": "svcgrp", "schema": "public" } } } } ], - "select_permissions": [ - { - "role": "auditor", - "permission": { - "columns": [ - "access_rule", - "action_id", - "active", - "dev_id", - "last_change_admin", - "mgm_id", - "nat_rule", - "parent_rule_id", - "parent_rule_type", - "rule_action", - "rule_comment", - "rule_create", - "rule_disabled", - "rule_dst", - "rule_dst_neg", - "rule_dst_refs", - "rule_from_zone", - "rule_head_text", - "rule_id", - "rule_implied", - "rule_installon", - "rule_last_seen", - "rule_name", - "rule_num", - "rule_num_numeric", - "rule_ruleid", - "rule_src", - "rule_src_neg", - "rule_src_refs", - "rule_svc", - "rule_svc_neg", - "rule_svc_refs", - "rule_time", - "rule_to_zone", - "rule_track", - "rule_uid", - "track_id", - "xlate_rule" - ], - "filter": {}, - "allow_aggregations": true - } - }, - { - "role": "fw-admin", - "permission": { - "columns": [ - "parent_rule_id", - "rule_create", - "rule_id", - "rule_last_seen", - "xlate_rule", - "access_rule", - "active", - "nat_rule", - "rule_disabled", - "rule_dst_neg", - "rule_implied", - "rule_src_neg", - "rule_svc_neg", - "rule_installon", - "rule_name", - "rule_ruleid", - "rule_time", - "action_id", - "dev_id", - "last_change_admin", - "mgm_id", - "rule_from_zone", - "rule_num", - "rule_to_zone", - "track_id", - "rule_num_numeric", - "parent_rule_type", - "rule_action", - "rule_comment", - "rule_dst", - "rule_dst_refs", - "rule_head_text", - "rule_src", - "rule_src_refs", - "rule_svc", - "rule_svc_refs", - "rule_track", - "rule_uid" - ], - "filter": {}, - "allow_aggregations": true - } - }, + "insert_permissions": [ { - "role": "recertifier", + "role": "importer", "permission": { + "check": {}, "columns": [ - "parent_rule_id", - "rule_create", - "rule_id", - "rule_last_seen", - "xlate_rule", - "access_rule", + "removed", + "svc_create", + "svc_id", + "svc_last_seen", "active", - "nat_rule", - "rule_disabled", - "rule_dst_neg", - "rule_implied", - "rule_src_neg", - "rule_svc_neg", - "rule_installon", - "rule_name", - "rule_ruleid", - "rule_time", - "action_id", - "dev_id", + "initial_config", + "srv_keeponinstall", + "svc_accept_rep", + "svc_accept_rep_any", + "svc_mfa", + "svc_sync", + "svc_sync_delay", + "svc_tcp_res", + "svc_timeout_std", + "svc_code", + "svc_name", + "svc_rpcnr", + "ip_proto_id", "last_change_admin", "mgm_id", - "rule_from_zone", - "rule_num", - "rule_to_zone", - "track_id", - "rule_num_numeric", - "parent_rule_type", - "rule_action", - "rule_comment", - "rule_dst", - "rule_dst_refs", - "rule_head_text", - "rule_src", - "rule_src_refs", - "rule_svc", - "rule_svc_refs", - "rule_track", - "rule_uid" - ], - "filter": { - "_and": [ - { - "mgm_id": { - "_in": "x-hasura-visible-managements" - } - }, - { - "dev_id": { - "_in": "x-hasura-visible-devices" - } - } - ] - }, - "allow_aggregations": true - } - }, + "svc_color_id", + "svc_port", + "svc_port_end", + "svc_source_port", + "svc_source_port_end", + "svc_sync_delay_start", + "svc_timeout", + "svc_typ_id", + "svc_comment", + "svc_match", + "svc_member_names", + "svc_member_refs", + "svc_prod_specific", + "svc_uid" + ] + }, + "comment": "" + } + ], + "select_permissions": [ { - "role": "reporter", + "role": "auditor", "permission": { "columns": [ - "parent_rule_id", - "rule_create", - "rule_id", - "rule_last_seen", - "xlate_rule", - "access_rule", - "active", - "nat_rule", - "rule_disabled", - "rule_dst_neg", - "rule_implied", - "rule_src_neg", - "rule_svc_neg", - "rule_installon", - "rule_name", - "rule_ruleid", - "rule_time", - "action_id", - "dev_id", - "last_change_admin", + "svc_id", + "svc_uid", + "svc_name", + "svc_typ_id", "mgm_id", - "rule_from_zone", - "rule_num", - "rule_to_zone", - "track_id", - "rule_num_numeric", - "parent_rule_type", - "rule_action", - "rule_comment", - "rule_dst", - "rule_dst_refs", - "rule_head_text", - "rule_src", - "rule_src_refs", - "rule_svc", - "rule_svc_refs", - "rule_track", - "rule_uid" + "svc_comment", + "svc_prod_specific", + "svc_member_names", + "svc_member_refs", + "svc_color_id", + "ip_proto_id", + "svc_port", + "svc_port_end", + "initial_config", + "srv_keeponinstall", + "svc_rpcnr", + "svc_code", + "svc_match", + "svc_source_port", + "svc_source_port_end", + "svc_tcp_res", + "svc_accept_rep", + "svc_accept_rep_any", + "svc_mfa", + "svc_timeout_std", + "svc_timeout", + "svc_sync", + "svc_sync_delay", + "svc_sync_delay_start", + "active", + "last_change_admin", + "svc_create", + "removed", + "svc_last_seen" ], - "filter": { - "_and": [ - { - "mgm_id": { - "_in": "x-hasura-visible-managements" - } - }, - { - "dev_id": { - "_in": "x-hasura-visible-devices" - } - } - ] - }, + "filter": {}, "allow_aggregations": true } }, { - "role": "reporter-viewall", + "role": "fw-admin", "permission": { "columns": [ - "parent_rule_id", - "rule_create", - "rule_id", - "rule_last_seen", - "xlate_rule", - "access_rule", + "svc_create", + "svc_id", + "svc_last_seen", + "removed", "active", - "nat_rule", - "rule_disabled", - "rule_dst_neg", - "rule_implied", - "rule_src_neg", - "rule_svc_neg", - "rule_installon", - "rule_name", - "rule_ruleid", - "rule_time", - "action_id", - "dev_id", + "initial_config", + "srv_keeponinstall", + "svc_accept_rep", + "svc_accept_rep_any", + "svc_mfa", + "svc_sync", + "svc_sync_delay", + "svc_tcp_res", + "svc_timeout_std", + "svc_code", + "svc_name", + "svc_rpcnr", + "ip_proto_id", "last_change_admin", "mgm_id", - "rule_from_zone", - "rule_num", - "rule_to_zone", - "track_id", - "rule_num_numeric", - "parent_rule_type", - "rule_action", - "rule_comment", - "rule_dst", - "rule_dst_refs", - "rule_head_text", - "rule_src", - "rule_src_refs", - "rule_svc", - "rule_svc_refs", - "rule_track", - "rule_uid" + "svc_color_id", + "svc_port", + "svc_port_end", + "svc_source_port", + "svc_source_port_end", + "svc_sync_delay_start", + "svc_timeout", + "svc_typ_id", + "svc_comment", + "svc_match", + "svc_member_names", + "svc_member_refs", + "svc_prod_specific", + "svc_uid" ], "filter": {}, "allow_aggregations": true } - } - ] - }, - { - "table": { - "name": "rule_from", - "schema": "public" - }, - "object_relationships": [ - { - "name": "importControlByRfLastSeen", - "using": { - "foreign_key_constraint_on": "rf_last_seen" - } - }, - { - "name": "import_control", - "using": { - "foreign_key_constraint_on": "rf_create" - } }, { - "name": "object", - "using": { - "foreign_key_constraint_on": "obj_id" - } + "role": "importer", + "permission": { + "columns": [ + "removed", + "svc_create", + "svc_id", + "svc_last_seen", + "active", + "initial_config", + "srv_keeponinstall", + "svc_accept_rep", + "svc_accept_rep_any", + "svc_mfa", + "svc_sync", + "svc_sync_delay", + "svc_tcp_res", + "svc_timeout_std", + "svc_code", + "svc_name", + "svc_rpcnr", + "ip_proto_id", + "last_change_admin", + "mgm_id", + "svc_color_id", + "svc_port", + "svc_port_end", + "svc_source_port", + "svc_source_port_end", + "svc_sync_delay_start", + "svc_timeout", + "svc_typ_id", + "svc_comment", + "svc_match", + "svc_member_names", + "svc_member_refs", + "svc_prod_specific", + "svc_uid" + ], + "filter": {} + }, + "comment": "" }, { - "name": "rule", - "using": { - "foreign_key_constraint_on": "rule_id" - } + "role": "middleware-server", + "permission": { + "columns": [ + "svc_create", + "svc_id", + "svc_last_seen", + "removed", + "active", + "initial_config", + "srv_keeponinstall", + "svc_accept_rep", + "svc_accept_rep_any", + "svc_mfa", + "svc_sync", + "svc_sync_delay", + "svc_tcp_res", + "svc_timeout_std", + "svc_code", + "svc_name", + "svc_rpcnr", + "ip_proto_id", + "last_change_admin", + "mgm_id", + "svc_color_id", + "svc_port", + "svc_port_end", + "svc_source_port", + "svc_source_port_end", + "svc_sync_delay_start", + "svc_timeout", + "svc_typ_id", + "svc_comment", + "svc_match", + "svc_member_names", + "svc_member_refs", + "svc_prod_specific", + "svc_uid" + ], + "filter": {} + }, + "comment": "" }, { - "name": "usr", - "using": { - "foreign_key_constraint_on": "user_id" - } - } - ], - "select_permissions": [ - { - "role": "auditor", + "role": "modeller", "permission": { "columns": [ - "obj_id", - "rf_create", - "rf_last_seen", - "rule_from_id", - "rule_id", - "user_id", + "svc_id", + "svc_uid", + "svc_name", + "svc_typ_id", + "mgm_id", + "svc_comment", + "svc_prod_specific", + "svc_member_names", + "svc_member_refs", + "svc_color_id", + "ip_proto_id", + "svc_port", + "svc_port_end", + "initial_config", + "srv_keeponinstall", + "svc_rpcnr", + "svc_code", + "svc_match", + "svc_source_port", + "svc_source_port_end", + "svc_tcp_res", + "svc_accept_rep", + "svc_accept_rep_any", + "svc_mfa", + "svc_timeout_std", + "svc_timeout", + "svc_sync", + "svc_sync_delay", + "svc_sync_delay_start", "active", - "negated" + "last_change_admin", + "svc_create", + "svc_last_seen", + "removed" ], - "filter": {}, + "filter": { + "mgm_id": { + "_in": "x-hasura-visible-managements" + } + }, "allow_aggregations": true } }, { - "role": "fw-admin", + "role": "recertifier", "permission": { "columns": [ - "obj_id", - "rf_create", - "rf_last_seen", - "rule_from_id", - "rule_id", - "user_id", + "svc_id", + "svc_uid", + "svc_name", + "svc_typ_id", + "mgm_id", + "svc_comment", + "svc_prod_specific", + "svc_member_names", + "svc_member_refs", + "svc_color_id", + "ip_proto_id", + "svc_port", + "svc_port_end", + "initial_config", + "srv_keeponinstall", + "svc_rpcnr", + "svc_code", + "svc_match", + "svc_source_port", + "svc_source_port_end", + "svc_tcp_res", + "svc_accept_rep", + "svc_accept_rep_any", + "svc_mfa", + "svc_timeout_std", + "svc_timeout", + "svc_sync", + "svc_sync_delay", + "svc_sync_delay_start", "active", - "negated" + "last_change_admin", + "svc_create", + "svc_last_seen", + "removed" ], - "filter": {}, + "filter": { + "mgm_id": { + "_in": "x-hasura-visible-managements" + } + }, "allow_aggregations": true } }, { - "role": "recertifier", + "role": "reporter", "permission": { "columns": [ - "obj_id", - "rf_create", - "rf_last_seen", - "rule_from_id", - "rule_id", - "user_id", + "svc_id", + "svc_uid", + "svc_name", + "svc_typ_id", + "mgm_id", + "svc_comment", + "svc_prod_specific", + "svc_member_names", + "svc_member_refs", + "svc_color_id", + "ip_proto_id", + "svc_port", + "svc_port_end", + "initial_config", + "srv_keeponinstall", + "svc_rpcnr", + "svc_code", + "svc_match", + "svc_source_port", + "svc_source_port_end", + "svc_tcp_res", + "svc_accept_rep", + "svc_accept_rep_any", + "svc_mfa", + "svc_timeout_std", + "svc_timeout", + "svc_sync", + "svc_sync_delay", + "svc_sync_delay_start", "active", - "negated" + "last_change_admin", + "svc_create", + "removed", + "svc_last_seen" ], - "filter": {}, + "filter": { + "mgm_id": { + "_in": "x-hasura-visible-managements" + } + }, "allow_aggregations": true } }, { - "role": "reporter", + "role": "reporter-viewall", "permission": { "columns": [ - "obj_id", - "rf_create", - "rf_last_seen", - "rule_from_id", - "rule_id", - "user_id", + "svc_id", + "svc_uid", + "svc_name", + "svc_typ_id", + "mgm_id", + "svc_comment", + "svc_prod_specific", + "svc_member_names", + "svc_member_refs", + "svc_color_id", + "ip_proto_id", + "svc_port", + "svc_port_end", + "initial_config", + "srv_keeponinstall", + "svc_rpcnr", + "svc_code", + "svc_match", + "svc_source_port", + "svc_source_port_end", + "svc_tcp_res", + "svc_accept_rep", + "svc_accept_rep_any", + "svc_mfa", + "svc_timeout_std", + "svc_timeout", + "svc_sync", + "svc_sync_delay", + "svc_sync_delay_start", "active", - "negated" + "last_change_admin", + "removed", + "svc_create", + "svc_last_seen" ], "filter": {}, "allow_aggregations": true } - }, + } + ], + "update_permissions": [ { - "role": "reporter-viewall", + "role": "importer", "permission": { "columns": [ - "obj_id", - "rf_create", - "rf_last_seen", - "rule_from_id", - "rule_id", - "user_id", + "removed", + "svc_create", + "svc_id", + "svc_last_seen", "active", - "negated" + "initial_config", + "srv_keeponinstall", + "svc_accept_rep", + "svc_accept_rep_any", + "svc_mfa", + "svc_sync", + "svc_sync_delay", + "svc_tcp_res", + "svc_timeout_std", + "svc_code", + "svc_name", + "svc_rpcnr", + "ip_proto_id", + "last_change_admin", + "mgm_id", + "svc_color_id", + "svc_port", + "svc_port_end", + "svc_source_port", + "svc_source_port_end", + "svc_sync_delay_start", + "svc_timeout", + "svc_typ_id", + "svc_comment", + "svc_match", + "svc_member_names", + "svc_member_refs", + "svc_prod_specific", + "svc_uid" ], "filter": {}, - "allow_aggregations": true - } + "check": {} + }, + "comment": "" + } + ], + "delete_permissions": [ + { + "role": "importer", + "permission": { + "filter": {} + }, + "comment": "" } ] }, { "table": { - "name": "rule_metadata", + "name": "stm_action", "schema": "public" }, - "object_relationships": [ - { - "name": "device", - "using": { - "foreign_key_constraint_on": "dev_id" - } - }, - { - "name": "uiuser", - "using": { - "foreign_key_constraint_on": "rule_owner" - } - }, - { - "name": "uiuserByRuleLastCertifier", - "using": { - "foreign_key_constraint_on": "rule_last_certifier" - } - } - ], "array_relationships": [ { - "name": "recertifications", + "name": "impltasks", "using": { "foreign_key_constraint_on": { - "column": "rule_metadata_id", + "column": "rule_action", "table": { - "name": "recertification", - "schema": "public" + "name": "impltask", + "schema": "request" } } } }, { - "name": "rule_owners", + "name": "reqtasks", "using": { "foreign_key_constraint_on": { - "column": "rule_metadata_id", + "column": "rule_action", "table": { - "name": "rule_owner", - "schema": "public" + "name": "reqtask", + "schema": "request" } } } @@ -10465,13 +22021,9 @@ { "name": "rules", "using": { - "manual_configuration": { - "column_mapping": { - "dev_id": "dev_id", - "rule_uid": "rule_uid" - }, - "insertion_order": null, - "remote_table": { + "foreign_key_constraint_on": { + "column": "action_id", + "table": { "name": "rule", "schema": "public" } @@ -10479,117 +22031,83 @@ } } ], - "insert_permissions": [ + "select_permissions": [ { - "role": "importer", + "role": "approver", "permission": { - "check": {}, "columns": [ - "rule_to_be_removed", - "dev_id", - "last_change_admin", - "rule_last_certifier", - "rule_owner", - "rule_hit_counter", - "rule_metadata_id", - "rule_uid", - "rule_created", - "rule_decert_date", - "rule_first_hit", - "rule_last_certified", - "rule_last_hit", - "rule_last_modified", - "rule_last_certifier_dn", - "rule_owner_dn", - "rule_recertification_comment" - ] + "action_id", + "action_name", + "allowed" + ], + "filter": {} } - } - ], - "select_permissions": [ + }, { "role": "auditor", "permission": { "columns": [ - "rule_metadata_id", - "dev_id", - "rule_uid", - "rule_created", - "rule_last_modified", - "rule_first_hit", - "rule_last_hit", - "rule_hit_counter", - "rule_last_certified", - "rule_last_certifier", - "rule_last_certifier_dn", - "rule_owner", - "rule_owner_dn", - "rule_to_be_removed", - "last_change_admin", - "rule_decert_date", - "rule_recertification_comment" + "action_id", + "action_name", + "allowed" ], - "filter": {}, - "allow_aggregations": true + "filter": {} } }, { "role": "fw-admin", "permission": { "columns": [ - "rule_hit_counter", - "rule_metadata_id", - "rule_to_be_removed", - "rule_last_certifier_dn", - "rule_owner_dn", - "rule_recertification_comment", - "dev_id", - "last_change_admin", - "rule_last_certifier", - "rule_owner", - "rule_uid", - "rule_created", - "rule_decert_date", - "rule_first_hit", - "rule_last_certified", - "rule_last_hit", - "rule_last_modified" + "allowed", + "action_name", + "action_id" ], "filter": {}, "allow_aggregations": true } }, + { + "role": "implementer", + "permission": { + "columns": [ + "action_id", + "action_name", + "allowed" + ], + "filter": {} + } + }, { "role": "importer", "permission": { "columns": [ - "rule_to_be_removed", - "dev_id", - "last_change_admin", - "rule_last_certifier", - "rule_owner", - "rule_hit_counter", - "rule_metadata_id", - "rule_uid", - "rule_created", - "rule_decert_date", - "rule_first_hit", - "rule_last_certified", - "rule_last_hit", - "rule_last_modified", - "rule_last_certifier_dn", - "rule_owner_dn", - "rule_recertification_comment" + "allowed", + "action_name", + "action_id" ], "filter": {}, "allow_aggregations": true } }, { - "role": "middleware-server", + "role": "modeller", + "permission": { + "columns": [ + "action_id", + "action_name", + "allowed" + ], + "filter": {} + }, + "comment": "" + }, + { + "role": "planner", "permission": { "columns": [ - "dev_id" + "action_id", + "action_name", + "allowed" ], "filter": {} } @@ -10598,132 +22116,55 @@ "role": "recertifier", "permission": { "columns": [ - "rule_to_be_removed", - "dev_id", - "last_change_admin", - "rule_last_certifier", - "rule_owner", - "rule_hit_counter", - "rule_metadata_id", - "rule_uid", - "rule_created", - "rule_decert_date", - "rule_first_hit", - "rule_last_certified", - "rule_last_hit", - "rule_last_modified", - "rule_last_certifier_dn", - "rule_owner_dn", - "rule_recertification_comment" + "action_id", + "action_name", + "allowed" ], - "filter": {}, - "allow_aggregations": true + "filter": {} } }, { "role": "reporter", "permission": { "columns": [ - "rule_metadata_id", - "dev_id", - "rule_uid", - "rule_created", - "rule_last_modified", - "rule_first_hit", - "rule_last_hit", - "rule_hit_counter", - "rule_last_certified", - "rule_last_certifier", - "rule_last_certifier_dn", - "rule_owner", - "rule_owner_dn", - "rule_to_be_removed", - "last_change_admin", - "rule_decert_date", - "rule_recertification_comment" + "action_id", + "action_name", + "allowed" ], - "filter": { - "dev_id": { - "_in": "x-hasura-visible-devices" - } - }, - "allow_aggregations": true + "filter": {} } }, { "role": "reporter-viewall", "permission": { "columns": [ - "rule_to_be_removed", - "dev_id", - "last_change_admin", - "rule_last_certifier", - "rule_owner", - "rule_hit_counter", - "rule_metadata_id", - "rule_uid", - "rule_created", - "rule_decert_date", - "rule_first_hit", - "rule_last_certified", - "rule_last_hit", - "rule_last_modified", - "rule_last_certifier_dn", - "rule_owner_dn", - "rule_recertification_comment" + "action_id", + "action_name", + "allowed" ], "filter": {}, "allow_aggregations": true } - } - ], - "update_permissions": [ + }, { - "role": "importer", + "role": "requester", "permission": { "columns": [ - "rule_to_be_removed", - "dev_id", - "last_change_admin", - "rule_last_certifier", - "rule_owner", - "rule_hit_counter", - "rule_metadata_id", - "rule_uid", - "rule_created", - "rule_decert_date", - "rule_first_hit", - "rule_last_certified", - "rule_last_hit", - "rule_last_modified", - "rule_last_certifier_dn", - "rule_owner_dn", - "rule_recertification_comment" + "action_id", + "action_name", + "allowed" ], - "filter": {}, - "check": null + "filter": {} } }, { - "role": "recertifier", + "role": "reviewer", "permission": { "columns": [ - "rule_decert_date", - "rule_last_certified", - "rule_last_certifier", - "rule_last_certifier_dn", - "rule_recertification_comment", - "rule_to_be_removed" + "action_id", + "action_name", + "allowed" ], - "filter": {}, - "check": {} - } - } - ], - "delete_permissions": [ - { - "role": "importer", - "permission": { "filter": {} } } @@ -10731,38 +22172,56 @@ }, { "table": { - "name": "rule_nwobj_resolved", + "name": "stm_change_type", "schema": "public" }, - "object_relationships": [ - { - "name": "importControlByCreated", - "using": { - "foreign_key_constraint_on": "created" - } - }, + "array_relationships": [ { - "name": "import_control", + "name": "changelog_objects", "using": { - "foreign_key_constraint_on": "removed" + "foreign_key_constraint_on": { + "column": "change_type_id", + "table": { + "name": "changelog_object", + "schema": "public" + } + } } }, { - "name": "management", + "name": "changelog_rules", "using": { - "foreign_key_constraint_on": "mgm_id" + "foreign_key_constraint_on": { + "column": "change_type_id", + "table": { + "name": "changelog_rule", + "schema": "public" + } + } } }, { - "name": "object", + "name": "changelog_services", "using": { - "foreign_key_constraint_on": "obj_id" + "foreign_key_constraint_on": { + "column": "change_type_id", + "table": { + "name": "changelog_service", + "schema": "public" + } + } } }, { - "name": "rule", + "name": "changelog_users", "using": { - "foreign_key_constraint_on": "rule_id" + "foreign_key_constraint_on": { + "column": "change_type_id", + "table": { + "name": "changelog_user", + "schema": "public" + } + } } } ], @@ -10771,25 +22230,18 @@ "role": "auditor", "permission": { "columns": [ - "created", - "mgm_id", - "obj_id", - "removed", - "rule_id" + "change_type_id", + "change_type_name" ], - "filter": {}, - "allow_aggregations": true + "filter": {} } }, { "role": "fw-admin", "permission": { "columns": [ - "created", - "obj_id", - "removed", - "rule_id", - "mgm_id" + "change_type_name", + "change_type_id" ], "filter": {}, "allow_aggregations": true @@ -10799,17 +22251,10 @@ "role": "recertifier", "permission": { "columns": [ - "created", - "mgm_id", - "obj_id", - "removed", - "rule_id" + "change_type_id", + "change_type_name" ], - "filter": { - "mgm_id": { - "_in": "x-hasura-visible-managements" - } - }, + "filter": {}, "allow_aggregations": true } }, @@ -10817,17 +22262,10 @@ "role": "reporter", "permission": { "columns": [ - "created", - "mgm_id", - "obj_id", - "removed", - "rule_id" + "change_type_id", + "change_type_name" ], - "filter": { - "mgm_id": { - "_in": "X-Hasura-visible-managements" - } - }, + "filter": {}, "allow_aggregations": true } }, @@ -10835,66 +22273,55 @@ "role": "reporter-viewall", "permission": { "columns": [ - "created", - "mgm_id", - "obj_id", - "removed", - "rule_id" - ], - "filter": {}, - "allow_aggregations": true - } - } - ] - }, - { - "table": { - "name": "rule_owner", - "schema": "public" - }, - "object_relationships": [ - { - "name": "owner", - "using": { - "foreign_key_constraint_on": "owner_id" - } - }, - { - "name": "rule_metadatum", - "using": { - "foreign_key_constraint_on": "rule_metadata_id" + "change_type_id", + "change_type_name" + ], + "filter": {}, + "allow_aggregations": true } } ] }, { "table": { - "name": "rule_service", + "name": "stm_color", "schema": "public" }, - "object_relationships": [ - { - "name": "importControlByRsLastSeen", - "using": { - "foreign_key_constraint_on": "rs_last_seen" - } - }, + "array_relationships": [ { - "name": "import_control", + "name": "objects", "using": { - "foreign_key_constraint_on": "rs_create" + "foreign_key_constraint_on": { + "column": "obj_color_id", + "table": { + "name": "object", + "schema": "public" + } + } } }, { - "name": "rule", + "name": "services", "using": { - "foreign_key_constraint_on": "rule_id" + "foreign_key_constraint_on": { + "column": "svc_color_id", + "table": { + "name": "service", + "schema": "public" + } + } } }, { - "name": "service", + "name": "usrs", "using": { - "foreign_key_constraint_on": "svc_id" + "foreign_key_constraint_on": { + "column": "user_color_id", + "table": { + "name": "usr", + "schema": "public" + } + } } } ], @@ -10903,12 +22330,10 @@ "role": "auditor", "permission": { "columns": [ - "rule_id", - "svc_id", - "active", - "rs_create", - "rs_last_seen", - "negated" + "color_id", + "color_name", + "color_rgb", + "color_comment" ], "filter": {} } @@ -10917,109 +22342,137 @@ "role": "fw-admin", "permission": { "columns": [ - "rs_create", - "rs_last_seen", - "rule_id", - "svc_id", - "active", - "negated" + "color_rgb", + "color_name", + "color_id", + "color_comment" ], - "filter": {} + "filter": {}, + "allow_aggregations": true } }, { - "role": "recertifier", + "role": "importer", "permission": { "columns": [ - "rule_id", - "svc_id", - "active", - "rs_create", - "rs_last_seen", - "negated" + "color_rgb", + "color_name", + "color_id", + "color_comment" ], "filter": {}, "allow_aggregations": true } }, + { + "role": "recertifier", + "permission": { + "columns": [ + "color_id", + "color_name", + "color_rgb", + "color_comment" + ], + "filter": {} + } + }, { "role": "reporter", "permission": { "columns": [ - "rule_id", - "svc_id", - "active", - "rs_create", - "rs_last_seen", - "negated" + "color_id", + "color_name", + "color_rgb", + "color_comment" ], - "filter": {}, - "allow_aggregations": true + "filter": {} } }, { "role": "reporter-viewall", "permission": { "columns": [ - "rule_id", - "svc_id", - "active", - "rs_create", - "rs_last_seen", - "negated" + "color_id", + "color_name", + "color_rgb", + "color_comment" ], - "filter": {} + "filter": {}, + "allow_aggregations": true } } ] }, { "table": { - "name": "rule_svc_resolved", + "name": "stm_dev_typ", "schema": "public" }, - "object_relationships": [ - { - "name": "importControlByCreated", - "using": { - "foreign_key_constraint_on": "created" - } - }, + "array_relationships": [ { - "name": "import_control", + "name": "devices", "using": { - "foreign_key_constraint_on": "removed" + "foreign_key_constraint_on": { + "column": "dev_typ_id", + "table": { + "name": "device", + "schema": "public" + } + } } }, { "name": "management", "using": { - "foreign_key_constraint_on": "mgm_id" - } - }, - { - "name": "rule", - "using": { - "foreign_key_constraint_on": "rule_id" - } - }, - { - "name": "service", - "using": { - "foreign_key_constraint_on": "svc_id" + "foreign_key_constraint_on": { + "column": "dev_typ_id", + "table": { + "name": "management", + "schema": "public" + } + } } } ], "select_permissions": [ + { + "role": "approver", + "permission": { + "columns": [ + "dev_typ_comment", + "dev_typ_config_file_basic_objects", + "dev_typ_config_file_rules", + "dev_typ_config_file_users", + "dev_typ_id", + "dev_typ_is_mgmt", + "dev_typ_is_multi_mgmt", + "dev_typ_manufacturer", + "dev_typ_name", + "dev_typ_predef_obj", + "dev_typ_predef_svc", + "dev_typ_version", + "is_pure_routing_device" + ], + "filter": {} + } + }, { "role": "auditor", "permission": { "columns": [ - "mgm_id", - "created", - "removed", - "rule_id", - "svc_id" + "dev_typ_is_mgmt", + "dev_typ_is_multi_mgmt", + "is_pure_routing_device", + "dev_typ_config_file_basic_objects", + "dev_typ_config_file_rules", + "dev_typ_config_file_users", + "dev_typ_manufacturer", + "dev_typ_name", + "dev_typ_version", + "dev_typ_id", + "dev_typ_comment", + "dev_typ_predef_obj", + "dev_typ_predef_svc" ], "filter": {}, "allow_aggregations": true @@ -11029,134 +22482,128 @@ "role": "fw-admin", "permission": { "columns": [ - "created", - "removed", - "rule_id", - "svc_id", - "mgm_id" + "dev_typ_is_mgmt", + "dev_typ_is_multi_mgmt", + "is_pure_routing_device", + "dev_typ_config_file_basic_objects", + "dev_typ_config_file_rules", + "dev_typ_config_file_users", + "dev_typ_manufacturer", + "dev_typ_name", + "dev_typ_version", + "dev_typ_id", + "dev_typ_comment", + "dev_typ_predef_obj", + "dev_typ_predef_svc" ], "filter": {}, "allow_aggregations": true } }, { - "role": "recertifier", + "role": "implementer", "permission": { "columns": [ - "mgm_id", - "rule_id", - "svc_id", - "created", - "removed" + "dev_typ_comment", + "dev_typ_config_file_basic_objects", + "dev_typ_config_file_rules", + "dev_typ_config_file_users", + "dev_typ_id", + "dev_typ_is_mgmt", + "dev_typ_is_multi_mgmt", + "dev_typ_manufacturer", + "dev_typ_name", + "dev_typ_predef_obj", + "dev_typ_predef_svc", + "dev_typ_version", + "is_pure_routing_device" ], - "filter": { - "mgm_id": { - "_in": "x-hasura-visible-managements" - } - }, - "allow_aggregations": true + "filter": {} } }, { - "role": "reporter", + "role": "importer", "permission": { "columns": [ - "mgm_id", - "created", - "removed", - "rule_id", - "svc_id" + "dev_typ_is_mgmt", + "dev_typ_is_multi_mgmt", + "is_pure_routing_device", + "dev_typ_config_file_basic_objects", + "dev_typ_config_file_rules", + "dev_typ_config_file_users", + "dev_typ_manufacturer", + "dev_typ_name", + "dev_typ_version", + "dev_typ_id", + "dev_typ_comment", + "dev_typ_predef_obj", + "dev_typ_predef_svc" ], - "filter": { - "mgm_id": { - "_in": "X-Hasura-visible-managements" - } - }, + "filter": {}, "allow_aggregations": true } }, { - "role": "reporter-viewall", + "role": "middleware-server", "permission": { "columns": [ - "mgm_id", - "created", - "removed", - "rule_id", - "svc_id" + "dev_typ_is_mgmt", + "dev_typ_is_multi_mgmt", + "is_pure_routing_device", + "dev_typ_config_file_basic_objects", + "dev_typ_config_file_rules", + "dev_typ_config_file_users", + "dev_typ_manufacturer", + "dev_typ_name", + "dev_typ_version", + "dev_typ_id", + "dev_typ_comment", + "dev_typ_predef_obj", + "dev_typ_predef_svc" ], "filter": {}, "allow_aggregations": true } - } - ] - }, - { - "table": { - "name": "rule_to", - "schema": "public" - }, - "object_relationships": [ - { - "name": "importControlByRtLastSeen", - "using": { - "foreign_key_constraint_on": "rt_last_seen" - } - }, - { - "name": "import_control", - "using": { - "foreign_key_constraint_on": "rt_create" - } - }, - { - "name": "object", - "using": { - "foreign_key_constraint_on": "obj_id" - } }, { - "name": "rule", - "using": { - "foreign_key_constraint_on": "rule_id" - } - }, - { - "name": "usr", - "using": { - "foreign_key_constraint_on": "user_id" - } - } - ], - "select_permissions": [ - { - "role": "auditor", + "role": "modeller", "permission": { "columns": [ - "active", - "negated", - "obj_id", - "rt_create", - "rt_last_seen", - "rule_id", - "rule_to_id", - "user_id" + "dev_typ_is_mgmt", + "dev_typ_is_multi_mgmt", + "is_pure_routing_device", + "dev_typ_config_file_basic_objects", + "dev_typ_config_file_rules", + "dev_typ_config_file_users", + "dev_typ_manufacturer", + "dev_typ_name", + "dev_typ_version", + "dev_typ_id", + "dev_typ_comment", + "dev_typ_predef_obj", + "dev_typ_predef_svc" ], "filter": {} - } + }, + "comment": "" }, { - "role": "fw-admin", + "role": "planner", "permission": { "columns": [ - "active", - "negated", - "obj_id", - "rt_create", - "rt_last_seen", - "rule_id", - "rule_to_id", - "user_id" + "dev_typ_comment", + "dev_typ_config_file_basic_objects", + "dev_typ_config_file_rules", + "dev_typ_config_file_users", + "dev_typ_id", + "dev_typ_is_mgmt", + "dev_typ_is_multi_mgmt", + "dev_typ_manufacturer", + "dev_typ_name", + "dev_typ_predef_obj", + "dev_typ_predef_svc", + "dev_typ_version", + "is_pure_routing_device" ], "filter": {} } @@ -11165,14 +22612,19 @@ "role": "recertifier", "permission": { "columns": [ - "active", - "negated", - "obj_id", - "rt_create", - "rt_last_seen", - "rule_id", - "rule_to_id", - "user_id" + "dev_typ_is_mgmt", + "dev_typ_is_multi_mgmt", + "is_pure_routing_device", + "dev_typ_config_file_basic_objects", + "dev_typ_config_file_rules", + "dev_typ_config_file_users", + "dev_typ_manufacturer", + "dev_typ_name", + "dev_typ_version", + "dev_typ_id", + "dev_typ_comment", + "dev_typ_predef_obj", + "dev_typ_predef_svc" ], "filter": {}, "allow_aggregations": true @@ -11182,14 +22634,19 @@ "role": "reporter", "permission": { "columns": [ - "active", - "negated", - "obj_id", - "rt_create", - "rt_last_seen", - "rule_id", - "rule_to_id", - "user_id" + "dev_typ_is_mgmt", + "dev_typ_is_multi_mgmt", + "is_pure_routing_device", + "dev_typ_config_file_basic_objects", + "dev_typ_config_file_rules", + "dev_typ_config_file_users", + "dev_typ_manufacturer", + "dev_typ_name", + "dev_typ_version", + "dev_typ_id", + "dev_typ_comment", + "dev_typ_predef_obj", + "dev_typ_predef_svc" ], "filter": {}, "allow_aggregations": true @@ -11199,14 +22656,62 @@ "role": "reporter-viewall", "permission": { "columns": [ - "active", - "negated", - "obj_id", - "rt_create", - "rt_last_seen", - "rule_id", - "rule_to_id", - "user_id" + "dev_typ_is_mgmt", + "dev_typ_is_multi_mgmt", + "is_pure_routing_device", + "dev_typ_config_file_basic_objects", + "dev_typ_config_file_rules", + "dev_typ_config_file_users", + "dev_typ_manufacturer", + "dev_typ_name", + "dev_typ_version", + "dev_typ_id", + "dev_typ_comment", + "dev_typ_predef_obj", + "dev_typ_predef_svc" + ], + "filter": {}, + "allow_aggregations": true + } + }, + { + "role": "requester", + "permission": { + "columns": [ + "dev_typ_comment", + "dev_typ_config_file_basic_objects", + "dev_typ_config_file_rules", + "dev_typ_config_file_users", + "dev_typ_id", + "dev_typ_is_mgmt", + "dev_typ_is_multi_mgmt", + "dev_typ_manufacturer", + "dev_typ_name", + "dev_typ_predef_obj", + "dev_typ_predef_svc", + "dev_typ_version", + "is_pure_routing_device" + ], + "filter": {} + } + }, + { + "role": "reviewer", + "permission": { + "columns": [ + "dev_typ_comment", + "dev_typ_config_file_basic_objects", + "dev_typ_config_file_rules", + "dev_typ_config_file_users", + "dev_typ_id", + "dev_typ_is_mgmt", + "dev_typ_is_multi_mgmt", + "dev_typ_manufacturer", + "dev_typ_name", + "dev_typ_predef_obj", + "dev_typ_predef_svc", + "dev_typ_version", + "is_pure_routing_device" ], "filter": {} } @@ -11215,311 +22720,352 @@ }, { "table": { - "name": "rule_user_resolved", + "name": "stm_import", "schema": "public" }, - "object_relationships": [ + "array_relationships": [ { - "name": "importControlByCreated", + "name": "import_controls", "using": { - "foreign_key_constraint_on": "created" + "foreign_key_constraint_on": { + "column": "import_type_id", + "table": { + "name": "import_control", + "schema": "public" + } + } } - }, + } + ], + "select_permissions": [ { - "name": "import_control", - "using": { - "foreign_key_constraint_on": "removed" - } + "role": "auditor", + "permission": { + "columns": [ + "import_type_name", + "import_type_id" + ], + "filter": {} + }, + "comment": "" }, { - "name": "management", - "using": { - "foreign_key_constraint_on": "mgm_id" - } + "role": "fw-admin", + "permission": { + "columns": [ + "import_type_name", + "import_type_id" + ], + "filter": {}, + "allow_aggregations": true + }, + "comment": "" }, { - "name": "rule", - "using": { - "foreign_key_constraint_on": "rule_id" - } + "role": "importer", + "permission": { + "columns": [ + "import_type_name", + "import_type_id" + ], + "filter": {}, + "allow_aggregations": true + }, + "comment": "" }, { - "name": "usr", - "using": { - "foreign_key_constraint_on": "user_id" - } - } - ], - "select_permissions": [ - { - "role": "auditor", + "role": "middleware-server", "permission": { "columns": [ - "mgm_id", - "rule_id", - "user_id", - "created", - "removed" + "import_type_name", + "import_type_id" ], "filter": {}, "allow_aggregations": true - } + }, + "comment": "" }, { - "role": "fw-admin", + "role": "modeller", "permission": { "columns": [ - "created", - "removed", - "rule_id", - "user_id", - "mgm_id" + "import_type_name", + "import_type_id" ], "filter": {}, "allow_aggregations": true - } + }, + "comment": "" }, { "role": "recertifier", "permission": { "columns": [ - "mgm_id", - "created", - "removed", - "rule_id", - "user_id" + "import_type_name", + "import_type_id" ], - "filter": { - "mgm_id": { - "_in": "x-hasura-visible-managements" - } - }, + "filter": {}, "allow_aggregations": true - } + }, + "comment": "" }, { "role": "reporter", "permission": { "columns": [ - "mgm_id", - "rule_id", - "user_id", - "created", - "removed" + "import_type_name", + "import_type_id" ], - "filter": { - "mgm_id": { - "_in": "X-Hasura-visible-managements" - } - }, + "filter": {}, "allow_aggregations": true - } + }, + "comment": "" }, { "role": "reporter-viewall", "permission": { "columns": [ - "mgm_id", - "created", - "removed", - "rule_id", - "user_id" + "import_type_name", + "import_type_id" ], "filter": {}, "allow_aggregations": true - } + }, + "comment": "" } ] }, { "table": { - "name": "service", + "name": "stm_ip_proto", "schema": "public" }, - "object_relationships": [ - { - "name": "importControlBySvcLastSeen", - "using": { - "foreign_key_constraint_on": "svc_last_seen" - } - }, - { - "name": "import_control", - "using": { - "foreign_key_constraint_on": "svc_create" - } - }, - { - "name": "management", - "using": { - "foreign_key_constraint_on": "mgm_id" - } - }, - { - "name": "stm_color", - "using": { - "foreign_key_constraint_on": "svc_color_id" - } - }, - { - "name": "stm_ip_proto", - "using": { - "foreign_key_constraint_on": "ip_proto_id" - } - }, - { - "name": "stm_svc_typ", - "using": { - "foreign_key_constraint_on": "svc_typ_id" - } - }, - { - "name": "uiuser", - "using": { - "foreign_key_constraint_on": "last_change_admin" - } - } - ], "array_relationships": [ { - "name": "changelogServicesByOldSvcId", + "name": "elements", "using": { "foreign_key_constraint_on": { - "column": "old_svc_id", + "column": "ip_proto_id", "table": { - "name": "changelog_service", - "schema": "public" + "name": "implelement", + "schema": "request" } } } }, { - "name": "changelog_services", + "name": "owner_networks", "using": { "foreign_key_constraint_on": { - "column": "new_svc_id", + "column": "ip_proto_id", "table": { - "name": "changelog_service", + "name": "owner_network", "schema": "public" } } } }, { - "name": "elements", + "name": "reqelements", "using": { "foreign_key_constraint_on": { - "column": "service_id", + "column": "ip_proto_id", "table": { - "name": "implelement", + "name": "reqelement", "schema": "request" } } } }, { - "name": "impltasks", + "name": "services", "using": { "foreign_key_constraint_on": { - "column": "svc_grp_id", + "column": "ip_proto_id", "table": { - "name": "impltask", - "schema": "request" + "name": "service", + "schema": "public" } } } }, { - "name": "reqelements", + "name": "servicesByProtoId", "using": { "foreign_key_constraint_on": { - "column": "service_id", + "column": "proto_id", "table": { - "name": "reqelement", - "schema": "request" + "name": "service", + "schema": "modelling" } } } + } + ], + "select_permissions": [ + { + "role": "approver", + "permission": { + "columns": [ + "ip_proto_id", + "ip_proto_name", + "ip_proto_comment" + ], + "filter": {} + } }, { - "name": "reqtasks", - "using": { - "foreign_key_constraint_on": { - "column": "svc_grp_id", - "table": { - "name": "reqtask", - "schema": "request" - } - } + "role": "auditor", + "permission": { + "columns": [ + "ip_proto_id", + "ip_proto_name", + "ip_proto_comment" + ], + "filter": {} } }, { - "name": "rule_services", - "using": { - "foreign_key_constraint_on": { - "column": "svc_id", - "table": { - "name": "rule_service", - "schema": "public" - } - } + "role": "fw-admin", + "permission": { + "columns": [ + "ip_proto_name", + "ip_proto_id", + "ip_proto_comment" + ], + "filter": {}, + "allow_aggregations": true } }, { - "name": "rule_svc_resolveds", - "using": { - "foreign_key_constraint_on": { - "column": "svc_id", - "table": { - "name": "rule_svc_resolved", - "schema": "public" - } - } + "role": "implementer", + "permission": { + "columns": [ + "ip_proto_id", + "ip_proto_name", + "ip_proto_comment" + ], + "filter": {} + } + }, + { + "role": "importer", + "permission": { + "columns": [ + "ip_proto_name", + "ip_proto_id", + "ip_proto_comment" + ], + "filter": {}, + "allow_aggregations": true + } + }, + { + "role": "middleware-server", + "permission": { + "columns": [ + "ip_proto_name", + "ip_proto_id", + "ip_proto_comment" + ], + "filter": {} + }, + "comment": "" + }, + { + "role": "modeller", + "permission": { + "columns": [ + "ip_proto_name", + "ip_proto_id", + "ip_proto_comment" + ], + "filter": {} + }, + "comment": "" + }, + { + "role": "planner", + "permission": { + "columns": [ + "ip_proto_id", + "ip_proto_name", + "ip_proto_comment" + ], + "filter": {} + } + }, + { + "role": "recertifier", + "permission": { + "columns": [ + "ip_proto_id", + "ip_proto_name", + "ip_proto_comment" + ], + "filter": {} } }, { - "name": "svcgrpFlatsBySvcgrpFlatMemberId", - "using": { - "foreign_key_constraint_on": { - "column": "svcgrp_flat_member_id", - "table": { - "name": "svcgrp_flat", - "schema": "public" - } - } + "role": "reporter", + "permission": { + "columns": [ + "ip_proto_id", + "ip_proto_name", + "ip_proto_comment" + ], + "filter": {} } }, { - "name": "svcgrp_flats", - "using": { - "foreign_key_constraint_on": { - "column": "svcgrp_flat_id", - "table": { - "name": "svcgrp_flat", - "schema": "public" - } - } + "role": "reporter-viewall", + "permission": { + "columns": [ + "ip_proto_id", + "ip_proto_name", + "ip_proto_comment" + ], + "filter": {}, + "allow_aggregations": true } }, { - "name": "svcgrps", - "using": { - "foreign_key_constraint_on": { - "column": "svcgrp_id", - "table": { - "name": "svcgrp", - "schema": "public" - } - } + "role": "requester", + "permission": { + "columns": [ + "ip_proto_id", + "ip_proto_name", + "ip_proto_comment" + ], + "filter": {} } }, { - "name": "svcgrpsBySvcgrpMemberId", + "role": "reviewer", + "permission": { + "columns": [ + "ip_proto_id", + "ip_proto_name", + "ip_proto_comment" + ], + "filter": {} + } + } + ] + }, + { + "table": { + "name": "stm_link_type", + "schema": "public" + }, + "array_relationships": [ + { + "name": "rulebase_links", "using": { "foreign_key_constraint_on": { - "column": "svcgrp_member_id", + "column": "link_type", "table": { - "name": "svcgrp", + "name": "rulebase_link", "schema": "public" } } @@ -11531,259 +23077,117 @@ "role": "auditor", "permission": { "columns": [ - "svc_id", - "svc_uid", - "svc_name", - "svc_typ_id", - "mgm_id", - "svc_comment", - "svc_prod_specific", - "svc_member_names", - "svc_member_refs", - "svc_color_id", - "ip_proto_id", - "svc_port", - "svc_port_end", - "initial_config", - "srv_keeponinstall", - "svc_rpcnr", - "svc_code", - "svc_match", - "svc_source_port", - "svc_source_port_end", - "svc_tcp_res", - "svc_accept_rep", - "svc_accept_rep_any", - "svc_mfa", - "svc_timeout_std", - "svc_timeout", - "svc_sync", - "svc_sync_delay", - "svc_sync_delay_start", - "active", - "last_change_admin", - "svc_create", - "svc_last_seen" + "name", + "id" ], - "filter": {}, - "allow_aggregations": true - } + "filter": {} + }, + "comment": "" }, { "role": "fw-admin", "permission": { "columns": [ - "svc_create", - "svc_id", - "svc_last_seen", - "active", - "initial_config", - "srv_keeponinstall", - "svc_accept_rep", - "svc_accept_rep_any", - "svc_mfa", - "svc_sync", - "svc_sync_delay", - "svc_tcp_res", - "svc_timeout_std", - "svc_code", - "svc_name", - "svc_rpcnr", - "ip_proto_id", - "last_change_admin", - "mgm_id", - "svc_color_id", - "svc_port", - "svc_port_end", - "svc_source_port", - "svc_source_port_end", - "svc_sync_delay_start", - "svc_timeout", - "svc_typ_id", - "svc_comment", - "svc_match", - "svc_member_names", - "svc_member_refs", - "svc_prod_specific", - "svc_uid" + "name", + "id" + ], + "filter": {} + }, + "comment": "" + }, + { + "role": "importer", + "permission": { + "columns": [ + "name", + "id" ], "filter": {}, "allow_aggregations": true - } + }, + "comment": "" + }, + { + "role": "middleware-server", + "permission": { + "columns": [ + "name", + "id" + ], + "filter": {} + }, + "comment": "" + }, + { + "role": "modeller", + "permission": { + "columns": [ + "name", + "id" + ], + "filter": {} + }, + "comment": "" }, { "role": "recertifier", "permission": { "columns": [ - "svc_id", - "svc_uid", - "svc_name", - "svc_typ_id", - "mgm_id", - "svc_comment", - "svc_prod_specific", - "svc_member_names", - "svc_member_refs", - "svc_color_id", - "ip_proto_id", - "svc_port", - "svc_port_end", - "initial_config", - "srv_keeponinstall", - "svc_rpcnr", - "svc_code", - "svc_match", - "svc_source_port", - "svc_source_port_end", - "svc_tcp_res", - "svc_accept_rep", - "svc_accept_rep_any", - "svc_mfa", - "svc_timeout_std", - "svc_timeout", - "svc_sync", - "svc_sync_delay", - "svc_sync_delay_start", - "active", - "last_change_admin", - "svc_create", - "svc_last_seen" + "name", + "id" ], - "filter": { - "mgm_id": { - "_in": "x-hasura-visible-managements" - } - }, - "allow_aggregations": true - } + "filter": {} + }, + "comment": "" }, { "role": "reporter", "permission": { - "columns": [ - "svc_id", - "svc_uid", - "svc_name", - "svc_typ_id", - "mgm_id", - "svc_comment", - "svc_prod_specific", - "svc_member_names", - "svc_member_refs", - "svc_color_id", - "ip_proto_id", - "svc_port", - "svc_port_end", - "initial_config", - "srv_keeponinstall", - "svc_rpcnr", - "svc_code", - "svc_match", - "svc_source_port", - "svc_source_port_end", - "svc_tcp_res", - "svc_accept_rep", - "svc_accept_rep_any", - "svc_mfa", - "svc_timeout_std", - "svc_timeout", - "svc_sync", - "svc_sync_delay", - "svc_sync_delay_start", - "active", - "last_change_admin", - "svc_create", - "svc_last_seen" + "columns": [ + "name", + "id" ], - "filter": { - "mgm_id": { - "_in": "x-hasura-visible-managements" - } - }, - "allow_aggregations": true - } + "filter": {} + }, + "comment": "" }, { "role": "reporter-viewall", "permission": { "columns": [ - "svc_id", - "svc_uid", - "svc_name", - "svc_typ_id", - "mgm_id", - "svc_comment", - "svc_prod_specific", - "svc_member_names", - "svc_member_refs", - "svc_color_id", - "ip_proto_id", - "svc_port", - "svc_port_end", - "initial_config", - "srv_keeponinstall", - "svc_rpcnr", - "svc_code", - "svc_match", - "svc_source_port", - "svc_source_port_end", - "svc_tcp_res", - "svc_accept_rep", - "svc_accept_rep_any", - "svc_mfa", - "svc_timeout_std", - "svc_timeout", - "svc_sync", - "svc_sync_delay", - "svc_sync_delay_start", - "active", - "last_change_admin", - "svc_create", - "svc_last_seen" + "name", + "id" ], - "filter": {}, - "allow_aggregations": true - } + "filter": {} + }, + "comment": "" + }, + { + "role": "reviewer", + "permission": { + "columns": [ + "name", + "id" + ], + "filter": {} + }, + "comment": "" } ] }, { "table": { - "name": "stm_action", + "name": "stm_obj_typ", "schema": "public" }, "array_relationships": [ { - "name": "impltasks", - "using": { - "foreign_key_constraint_on": { - "column": "rule_action", - "table": { - "name": "impltask", - "schema": "request" - } - } - } - }, - { - "name": "reqtasks", - "using": { - "foreign_key_constraint_on": { - "column": "rule_action", - "table": { - "name": "reqtask", - "schema": "request" - } - } - } - }, - { - "name": "rules", + "name": "objects", "using": { "foreign_key_constraint_on": { - "column": "action_id", + "column": "obj_typ_id", "table": { - "name": "rule", + "name": "object", "schema": "public" } } @@ -11792,60 +23196,59 @@ ], "select_permissions": [ { - "role": "approver", + "role": "auditor", "permission": { "columns": [ - "action_id", - "action_name" + "obj_typ_id", + "obj_typ_name", + "obj_typ_comment" ], "filter": {} } }, { - "role": "auditor", + "role": "fw-admin", "permission": { "columns": [ - "action_id", - "action_name" + "obj_typ_name", + "obj_typ_id", + "obj_typ_comment" ], - "filter": {} + "filter": {}, + "allow_aggregations": true } }, { - "role": "fw-admin", + "role": "importer", "permission": { "columns": [ - "action_name", - "action_id" + "obj_typ_name", + "obj_typ_id", + "obj_typ_comment" ], "filter": {}, "allow_aggregations": true } }, { - "role": "implementer", + "role": "middleware-server", "permission": { "columns": [ - "action_id", - "action_name" + "obj_typ_id", + "obj_typ_name", + "obj_typ_comment" ], "filter": {} - } - }, - { - "role": "importer", - "permission": { - "columns": [], - "filter": {}, - "allow_aggregations": true - } + }, + "comment": "" }, { - "role": "planner", + "role": "modeller", "permission": { "columns": [ - "action_id", - "action_name" + "obj_typ_id", + "obj_typ_name", + "obj_typ_comment" ], "filter": {} } @@ -11854,8 +23257,9 @@ "role": "recertifier", "permission": { "columns": [ - "action_id", - "action_name" + "obj_typ_id", + "obj_typ_name", + "obj_typ_comment" ], "filter": {} } @@ -11864,8 +23268,9 @@ "role": "reporter", "permission": { "columns": [ - "action_id", - "action_name" + "obj_typ_id", + "obj_typ_name", + "obj_typ_comment" ], "filter": {} } @@ -11874,107 +23279,90 @@ "role": "reporter-viewall", "permission": { "columns": [ - "action_id", - "action_name" + "obj_typ_id", + "obj_typ_name", + "obj_typ_comment" ], "filter": {}, "allow_aggregations": true } - }, - { - "role": "requester", - "permission": { - "columns": [ - "action_id", - "action_name" - ], - "filter": {} - } - }, - { - "role": "reviewer", - "permission": { - "columns": [ - "action_id", - "action_name" - ], - "filter": {} - } } ] }, { "table": { - "name": "stm_change_type", + "name": "stm_svc_typ", "schema": "public" }, "array_relationships": [ { - "name": "changelog_objects", + "name": "services", "using": { "foreign_key_constraint_on": { - "column": "change_type_id", + "column": "svc_typ_id", "table": { - "name": "changelog_object", + "name": "service", "schema": "public" } } } - }, + } + ], + "select_permissions": [ { - "name": "changelog_rules", - "using": { - "foreign_key_constraint_on": { - "column": "change_type_id", - "table": { - "name": "changelog_rule", - "schema": "public" - } - } + "role": "auditor", + "permission": { + "columns": [ + "svc_typ_id", + "svc_typ_name", + "svc_typ_comment" + ], + "filter": {} } }, { - "name": "changelog_services", - "using": { - "foreign_key_constraint_on": { - "column": "change_type_id", - "table": { - "name": "changelog_service", - "schema": "public" - } - } + "role": "fw-admin", + "permission": { + "columns": [ + "svc_typ_name", + "svc_typ_id", + "svc_typ_comment" + ], + "filter": {}, + "allow_aggregations": true } }, { - "name": "changelog_users", - "using": { - "foreign_key_constraint_on": { - "column": "change_type_id", - "table": { - "name": "changelog_user", - "schema": "public" - } - } + "role": "importer", + "permission": { + "columns": [ + "svc_typ_name", + "svc_typ_id", + "svc_typ_comment" + ], + "filter": {}, + "allow_aggregations": true } - } - ], - "select_permissions": [ + }, { - "role": "auditor", + "role": "middleware-server", "permission": { "columns": [ - "change_type_id", - "change_type_name" + "svc_typ_name", + "svc_typ_id", + "svc_typ_comment" ], - "filter": {} + "filter": {}, + "allow_aggregations": true } }, { - "role": "fw-admin", + "role": "modeller", "permission": { "columns": [ - "change_type_name", - "change_type_id" + "svc_typ_id", + "svc_typ_name", + "svc_typ_comment" ], "filter": {}, "allow_aggregations": true @@ -11984,8 +23372,9 @@ "role": "recertifier", "permission": { "columns": [ - "change_type_id", - "change_type_name" + "svc_typ_id", + "svc_typ_name", + "svc_typ_comment" ], "filter": {}, "allow_aggregations": true @@ -11995,8 +23384,9 @@ "role": "reporter", "permission": { "columns": [ - "change_type_id", - "change_type_name" + "svc_typ_id", + "svc_typ_name", + "svc_typ_comment" ], "filter": {}, "allow_aggregations": true @@ -12006,8 +23396,9 @@ "role": "reporter-viewall", "permission": { "columns": [ - "change_type_id", - "change_type_name" + "svc_typ_id", + "svc_typ_name", + "svc_typ_comment" ], "filter": {}, "allow_aggregations": true @@ -12017,41 +23408,41 @@ }, { "table": { - "name": "stm_color", + "name": "stm_track", "schema": "public" }, "array_relationships": [ { - "name": "objects", + "name": "impltasks", "using": { "foreign_key_constraint_on": { - "column": "obj_color_id", + "column": "rule_tracking", "table": { - "name": "object", - "schema": "public" + "name": "impltask", + "schema": "request" } } } }, { - "name": "services", + "name": "reqtasks", "using": { "foreign_key_constraint_on": { - "column": "svc_color_id", + "column": "rule_tracking", "table": { - "name": "service", - "schema": "public" + "name": "reqtask", + "schema": "request" } } } }, { - "name": "usrs", + "name": "rules", "using": { "foreign_key_constraint_on": { - "column": "user_color_id", + "column": "track_id", "table": { - "name": "usr", + "name": "rule", "schema": "public" } } @@ -12060,467 +23451,315 @@ ], "select_permissions": [ { - "role": "auditor", + "role": "approver", "permission": { "columns": [ - "color_id", - "color_name", - "color_rgb", - "color_comment" + "track_id", + "track_name" ], "filter": {} } }, { - "role": "fw-admin", + "role": "auditor", "permission": { "columns": [ - "color_rgb", - "color_name", - "color_id", - "color_comment" + "track_id", + "track_name" ], - "filter": {}, - "allow_aggregations": true + "filter": {} } }, { - "role": "importer", + "role": "fw-admin", "permission": { - "columns": [], + "columns": [ + "track_name", + "track_id" + ], "filter": {}, "allow_aggregations": true } }, { - "role": "recertifier", + "role": "implementer", "permission": { "columns": [ - "color_id", - "color_name", - "color_rgb", - "color_comment" + "track_id", + "track_name" ], "filter": {} } }, { - "role": "reporter", + "role": "importer", "permission": { "columns": [ - "color_id", - "color_name", - "color_rgb", - "color_comment" + "track_name", + "track_id" ], - "filter": {} + "filter": {}, + "allow_aggregations": true } }, { - "role": "reporter-viewall", + "role": "modeller", "permission": { "columns": [ - "color_id", - "color_name", - "color_rgb", - "color_comment" + "track_name", + "track_id" ], - "filter": {}, - "allow_aggregations": true - } - } - ] - }, - { - "table": { - "name": "stm_dev_typ", - "schema": "public" - }, - "array_relationships": [ - { - "name": "devices", - "using": { - "foreign_key_constraint_on": { - "column": "dev_typ_id", - "table": { - "name": "device", - "schema": "public" - } - } - } + "filter": {} + }, + "comment": "" }, { - "name": "management", - "using": { - "foreign_key_constraint_on": { - "column": "dev_typ_id", - "table": { - "name": "management", - "schema": "public" - } - } + "role": "planner", + "permission": { + "columns": [ + "track_id", + "track_name" + ], + "filter": {} } - } - ], - "select_permissions": [ + }, { - "role": "approver", + "role": "recertifier", "permission": { "columns": [ - "dev_typ_comment", - "dev_typ_config_file_basic_objects", - "dev_typ_config_file_rules", - "dev_typ_config_file_users", - "dev_typ_id", - "dev_typ_is_mgmt", - "dev_typ_is_multi_mgmt", - "dev_typ_manufacturer", - "dev_typ_name", - "dev_typ_predef_obj", - "dev_typ_predef_svc", - "dev_typ_version", - "is_pure_routing_device" + "track_id", + "track_name" ], "filter": {} } }, { - "role": "auditor", + "role": "reporter", "permission": { "columns": [ - "dev_typ_is_mgmt", - "dev_typ_is_multi_mgmt", - "is_pure_routing_device", - "dev_typ_config_file_basic_objects", - "dev_typ_config_file_rules", - "dev_typ_config_file_users", - "dev_typ_manufacturer", - "dev_typ_name", - "dev_typ_version", - "dev_typ_id", - "dev_typ_comment", - "dev_typ_predef_obj", - "dev_typ_predef_svc" + "track_id", + "track_name" ], - "filter": {}, - "allow_aggregations": true + "filter": {} } }, { - "role": "fw-admin", + "role": "reporter-viewall", "permission": { "columns": [ - "dev_typ_is_mgmt", - "dev_typ_is_multi_mgmt", - "is_pure_routing_device", - "dev_typ_config_file_basic_objects", - "dev_typ_config_file_rules", - "dev_typ_config_file_users", - "dev_typ_manufacturer", - "dev_typ_name", - "dev_typ_version", - "dev_typ_id", - "dev_typ_comment", - "dev_typ_predef_obj", - "dev_typ_predef_svc" + "track_id", + "track_name" ], "filter": {}, "allow_aggregations": true } }, { - "role": "implementer", + "role": "requester", "permission": { "columns": [ - "dev_typ_comment", - "dev_typ_config_file_basic_objects", - "dev_typ_config_file_rules", - "dev_typ_config_file_users", - "dev_typ_id", - "dev_typ_is_mgmt", - "dev_typ_is_multi_mgmt", - "dev_typ_manufacturer", - "dev_typ_name", - "dev_typ_predef_obj", - "dev_typ_predef_svc", - "dev_typ_version", - "is_pure_routing_device" + "track_id", + "track_name" ], "filter": {} } }, { - "role": "importer", + "role": "reviewer", "permission": { "columns": [ - "dev_typ_is_mgmt", - "dev_typ_is_multi_mgmt", - "is_pure_routing_device", - "dev_typ_config_file_basic_objects", - "dev_typ_config_file_rules", - "dev_typ_config_file_users", - "dev_typ_manufacturer", - "dev_typ_name", - "dev_typ_version", - "dev_typ_id", - "dev_typ_comment", - "dev_typ_predef_obj", - "dev_typ_predef_svc" + "track_id", + "track_name" ], - "filter": {}, - "allow_aggregations": true + "filter": {} } - }, + } + ] + }, + { + "table": { + "name": "stm_usr_typ", + "schema": "public" + }, + "array_relationships": [ { - "role": "middleware-server", - "permission": { - "columns": [ - "dev_typ_is_mgmt", - "dev_typ_is_multi_mgmt", - "is_pure_routing_device", - "dev_typ_config_file_basic_objects", - "dev_typ_config_file_rules", - "dev_typ_config_file_users", - "dev_typ_manufacturer", - "dev_typ_name", - "dev_typ_version", - "dev_typ_id", - "dev_typ_comment", - "dev_typ_predef_obj", - "dev_typ_predef_svc" - ], - "filter": {}, - "allow_aggregations": true + "name": "usrs", + "using": { + "foreign_key_constraint_on": { + "column": "usr_typ_id", + "table": { + "name": "usr", + "schema": "public" + } + } } - }, + } + ], + "select_permissions": [ { - "role": "planner", + "role": "auditor", "permission": { "columns": [ - "dev_typ_comment", - "dev_typ_config_file_basic_objects", - "dev_typ_config_file_rules", - "dev_typ_config_file_users", - "dev_typ_id", - "dev_typ_is_mgmt", - "dev_typ_is_multi_mgmt", - "dev_typ_manufacturer", - "dev_typ_name", - "dev_typ_predef_obj", - "dev_typ_predef_svc", - "dev_typ_version", - "is_pure_routing_device" + "usr_typ_id", + "usr_typ_name" ], "filter": {} } }, { - "role": "recertifier", + "role": "fw-admin", "permission": { "columns": [ - "dev_typ_is_mgmt", - "dev_typ_is_multi_mgmt", - "is_pure_routing_device", - "dev_typ_config_file_basic_objects", - "dev_typ_config_file_rules", - "dev_typ_config_file_users", - "dev_typ_manufacturer", - "dev_typ_name", - "dev_typ_version", - "dev_typ_id", - "dev_typ_comment", - "dev_typ_predef_obj", - "dev_typ_predef_svc" + "usr_typ_name", + "usr_typ_id" ], "filter": {}, "allow_aggregations": true } }, { - "role": "reporter", + "role": "importer", "permission": { "columns": [ - "dev_typ_is_mgmt", - "dev_typ_is_multi_mgmt", - "is_pure_routing_device", - "dev_typ_config_file_basic_objects", - "dev_typ_config_file_rules", - "dev_typ_config_file_users", - "dev_typ_manufacturer", - "dev_typ_name", - "dev_typ_version", - "dev_typ_id", - "dev_typ_comment", - "dev_typ_predef_obj", - "dev_typ_predef_svc" + "usr_typ_name", + "usr_typ_id" ], "filter": {}, "allow_aggregations": true } }, { - "role": "reporter-viewall", + "role": "middleware-server", "permission": { "columns": [ - "dev_typ_is_mgmt", - "dev_typ_is_multi_mgmt", - "is_pure_routing_device", - "dev_typ_config_file_basic_objects", - "dev_typ_config_file_rules", - "dev_typ_config_file_users", - "dev_typ_manufacturer", - "dev_typ_name", - "dev_typ_version", - "dev_typ_id", - "dev_typ_comment", - "dev_typ_predef_obj", - "dev_typ_predef_svc" + "usr_typ_name", + "usr_typ_id" ], - "filter": {}, - "allow_aggregations": true - } + "filter": {} + }, + "comment": "" }, { - "role": "requester", + "role": "modeller", "permission": { "columns": [ - "dev_typ_comment", - "dev_typ_config_file_basic_objects", - "dev_typ_config_file_rules", - "dev_typ_config_file_users", - "dev_typ_id", - "dev_typ_is_mgmt", - "dev_typ_is_multi_mgmt", - "dev_typ_manufacturer", - "dev_typ_name", - "dev_typ_predef_obj", - "dev_typ_predef_svc", - "dev_typ_version", - "is_pure_routing_device" + "usr_typ_name", + "usr_typ_id" + ], + "filter": {} + }, + "comment": "" + }, + { + "role": "recertifier", + "permission": { + "columns": [ + "usr_typ_id", + "usr_typ_name" ], "filter": {} } }, { - "role": "reviewer", + "role": "reporter", "permission": { "columns": [ - "dev_typ_comment", - "dev_typ_config_file_basic_objects", - "dev_typ_config_file_rules", - "dev_typ_config_file_users", - "dev_typ_id", - "dev_typ_is_mgmt", - "dev_typ_is_multi_mgmt", - "dev_typ_manufacturer", - "dev_typ_name", - "dev_typ_predef_obj", - "dev_typ_predef_svc", - "dev_typ_version", - "is_pure_routing_device" + "usr_typ_id", + "usr_typ_name" ], "filter": {} } + }, + { + "role": "reporter-viewall", + "permission": { + "columns": [ + "usr_typ_id", + "usr_typ_name" + ], + "filter": {}, + "allow_aggregations": true + } } ] }, { "table": { - "name": "stm_ip_proto", + "name": "svcgrp", "schema": "public" }, - "array_relationships": [ + "object_relationships": [ { - "name": "elements", + "name": "importControlByImportLastSeen", "using": { - "foreign_key_constraint_on": { - "column": "ip_proto_id", - "table": { - "name": "implelement", - "schema": "request" - } - } + "foreign_key_constraint_on": "import_last_seen" } }, { - "name": "owner_networks", + "name": "import_control", "using": { - "foreign_key_constraint_on": { - "column": "ip_proto_id", - "table": { - "name": "owner_network", - "schema": "public" - } - } + "foreign_key_constraint_on": "import_created" } }, { - "name": "reqelements", + "name": "service", "using": { - "foreign_key_constraint_on": { - "column": "ip_proto_id", - "table": { - "name": "reqelement", - "schema": "request" - } - } + "foreign_key_constraint_on": "svcgrp_id" } }, { - "name": "services", + "name": "serviceBySvcgrpMemberId", "using": { - "foreign_key_constraint_on": { - "column": "ip_proto_id", - "table": { - "name": "service", - "schema": "public" - } - } + "foreign_key_constraint_on": "svcgrp_member_id" } } ], - "select_permissions": [ + "insert_permissions": [ { - "role": "approver", + "role": "importer", "permission": { + "check": {}, "columns": [ - "ip_proto_id", - "ip_proto_name", - "ip_proto_comment" - ], - "filter": {} - } - }, + "import_created", + "import_last_seen", + "removed", + "svcgrp_id", + "svcgrp_member_id", + "active", + "negated" + ] + }, + "comment": "" + } + ], + "select_permissions": [ { "role": "auditor", "permission": { "columns": [ - "ip_proto_id", - "ip_proto_name", - "ip_proto_comment" - ], - "filter": {} - } - }, - { - "role": "fw-admin", - "permission": { - "columns": [ - "ip_proto_name", - "ip_proto_id", - "ip_proto_comment" + "svcgrp_id", + "svcgrp_member_id", + "import_created", + "removed", + "import_last_seen", + "active", + "negated" ], "filter": {}, "allow_aggregations": true } }, { - "role": "implementer", + "role": "fw-admin", "permission": { "columns": [ - "ip_proto_id", - "ip_proto_name", - "ip_proto_comment" + "import_created", + "import_last_seen", + "removed", + "svcgrp_id", + "svcgrp_member_id", + "active", + "negated" ], "filter": {} } @@ -12528,438 +23767,514 @@ { "role": "importer", "permission": { - "columns": [], - "filter": {}, - "allow_aggregations": true - } + "columns": [ + "import_created", + "import_last_seen", + "removed", + "svcgrp_id", + "svcgrp_member_id", + "active", + "negated" + ], + "filter": {} + }, + "comment": "" }, { - "role": "planner", + "role": "middleware-server", "permission": { "columns": [ - "ip_proto_id", - "ip_proto_name", - "ip_proto_comment" + "import_created", + "import_last_seen", + "removed", + "svcgrp_id", + "svcgrp_member_id", + "active", + "negated" ], "filter": {} - } + }, + "comment": "" }, { - "role": "recertifier", + "role": "modeller", "permission": { "columns": [ - "ip_proto_id", - "ip_proto_name", - "ip_proto_comment" + "svcgrp_id", + "svcgrp_member_id", + "import_created", + "import_last_seen", + "removed", + "active", + "negated" ], - "filter": {} + "filter": {}, + "allow_aggregations": true } }, { - "role": "reporter", + "role": "recertifier", "permission": { "columns": [ - "ip_proto_id", - "ip_proto_name", - "ip_proto_comment" + "svcgrp_id", + "svcgrp_member_id", + "import_created", + "import_last_seen", + "removed", + "active", + "negated" ], - "filter": {} + "filter": {}, + "allow_aggregations": true } }, { - "role": "reporter-viewall", + "role": "reporter", "permission": { "columns": [ - "ip_proto_id", - "ip_proto_name", - "ip_proto_comment" + "svcgrp_id", + "svcgrp_member_id", + "import_created", + "import_last_seen", + "removed", + "active", + "negated" ], "filter": {}, "allow_aggregations": true } }, { - "role": "requester", + "role": "reporter-viewall", "permission": { "columns": [ - "ip_proto_id", - "ip_proto_name", - "ip_proto_comment" + "svcgrp_id", + "svcgrp_member_id", + "import_created", + "import_last_seen", + "removed", + "active", + "negated" ], "filter": {} } - }, + } + ], + "update_permissions": [ { - "role": "reviewer", + "role": "importer", "permission": { "columns": [ - "ip_proto_id", - "ip_proto_name", - "ip_proto_comment" + "import_created", + "import_last_seen", + "removed", + "svcgrp_id", + "svcgrp_member_id", + "active", + "negated" ], + "filter": {}, + "check": {} + }, + "comment": "" + } + ], + "delete_permissions": [ + { + "role": "importer", + "permission": { "filter": {} - } + }, + "comment": "" } ] }, { "table": { - "name": "stm_obj_typ", + "name": "svcgrp_flat", "schema": "public" }, - "array_relationships": [ + "object_relationships": [ { - "name": "objects", + "name": "importControlByImportLastSeen", "using": { - "foreign_key_constraint_on": { - "column": "obj_typ_id", - "table": { - "name": "object", - "schema": "public" - } - } + "foreign_key_constraint_on": "import_last_seen" } - } - ], - "select_permissions": [ + }, { - "role": "auditor", - "permission": { - "columns": [ - "obj_typ_id", - "obj_typ_name", - "obj_typ_comment" - ], - "filter": {} + "name": "import_control", + "using": { + "foreign_key_constraint_on": "import_created" } }, { - "role": "fw-admin", - "permission": { - "columns": [ - "obj_typ_name", - "obj_typ_id", - "obj_typ_comment" - ], - "filter": {}, - "allow_aggregations": true + "name": "service", + "using": { + "foreign_key_constraint_on": "svcgrp_flat_id" } }, + { + "name": "serviceBySvcgrpFlatMemberId", + "using": { + "foreign_key_constraint_on": "svcgrp_flat_member_id" + } + } + ], + "insert_permissions": [ { "role": "importer", "permission": { - "columns": [], - "filter": {}, - "allow_aggregations": true - } - }, + "check": {}, + "columns": [ + "removed", + "active", + "negated", + "import_created", + "import_last_seen", + "svcgrp_flat_id", + "svcgrp_flat_member_id" + ] + }, + "comment": "" + } + ], + "select_permissions": [ { - "role": "recertifier", + "role": "auditor", "permission": { "columns": [ - "obj_typ_id", - "obj_typ_name", - "obj_typ_comment" + "svcgrp_flat_id", + "svcgrp_flat_member_id", + "import_created", + "import_last_seen", + "removed", + "active", + "negated" ], - "filter": {} + "filter": {}, + "allow_aggregations": true } }, { - "role": "reporter", + "role": "fw-admin", "permission": { "columns": [ - "obj_typ_id", - "obj_typ_name", - "obj_typ_comment" + "active", + "negated", + "import_created", + "import_last_seen", + "removed", + "svcgrp_flat_id", + "svcgrp_flat_member_id" ], "filter": {} } }, { - "role": "reporter-viewall", + "role": "importer", "permission": { "columns": [ - "obj_typ_id", - "obj_typ_name", - "obj_typ_comment" + "removed", + "active", + "negated", + "import_created", + "import_last_seen", + "removed", + "svcgrp_flat_id", + "svcgrp_flat_member_id" ], - "filter": {}, - "allow_aggregations": true - } - } - ] - }, - { - "table": { - "name": "stm_svc_typ", - "schema": "public" - }, - "array_relationships": [ - { - "name": "services", - "using": { - "foreign_key_constraint_on": { - "column": "svc_typ_id", - "table": { - "name": "service", - "schema": "public" - } - } - } - } - ], - "select_permissions": [ + "filter": {} + }, + "comment": "" + }, { - "role": "auditor", + "role": "middleware-server", "permission": { "columns": [ - "svc_typ_id", - "svc_typ_name", - "svc_typ_comment" + "removed", + "active", + "negated", + "import_created", + "import_last_seen", + "svcgrp_flat_id", + "svcgrp_flat_member_id" ], "filter": {} - } + }, + "comment": "" }, { - "role": "fw-admin", + "role": "modeller", "permission": { "columns": [ - "svc_typ_name", - "svc_typ_id", - "svc_typ_comment" + "svcgrp_flat_id", + "svcgrp_flat_member_id", + "import_created", + "import_last_seen", + "removed", + "active", + "negated" ], "filter": {}, "allow_aggregations": true } }, { - "role": "importer", + "role": "recertifier", "permission": { - "columns": [], + "columns": [ + "svcgrp_flat_id", + "svcgrp_flat_member_id", + "import_created", + "import_last_seen", + "removed", + "active", + "negated" + ], "filter": {}, "allow_aggregations": true } }, { - "role": "recertifier", + "role": "reporter", "permission": { "columns": [ - "svc_typ_id", - "svc_typ_name", - "svc_typ_comment" + "svcgrp_flat_id", + "svcgrp_flat_member_id", + "import_created", + "import_last_seen", + "removed", + "active", + "negated" ], "filter": {}, "allow_aggregations": true } }, { - "role": "reporter", + "role": "reporter-viewall", "permission": { "columns": [ - "svc_typ_id", - "svc_typ_name", - "svc_typ_comment" + "svcgrp_flat_id", + "svcgrp_flat_member_id", + "import_created", + "import_last_seen", + "removed", + "active", + "negated" ], - "filter": {}, - "allow_aggregations": true + "filter": {} } - }, + } + ], + "update_permissions": [ { - "role": "reporter-viewall", + "role": "importer", "permission": { "columns": [ - "svc_typ_id", - "svc_typ_name", - "svc_typ_comment" + "removed", + "active", + "negated", + "import_created", + "import_last_seen", + "svcgrp_flat_id", + "svcgrp_flat_member_id" ], "filter": {}, - "allow_aggregations": true - } + "check": {} + }, + "comment": "" + } + ], + "delete_permissions": [ + { + "role": "importer", + "permission": { + "filter": {} + }, + "comment": "" } ] }, { "table": { - "name": "stm_track", + "name": "tenant", "schema": "public" }, "array_relationships": [ { - "name": "impltasks", + "name": "approvals", "using": { "foreign_key_constraint_on": { - "column": "rule_tracking", + "column": "tenant_id", "table": { - "name": "impltask", + "name": "approval", "schema": "request" } } } }, { - "name": "reqtasks", + "name": "ldap_connections", "using": { "foreign_key_constraint_on": { - "column": "rule_tracking", + "column": "tenant_id", "table": { - "name": "reqtask", - "schema": "request" + "name": "ldap_connection", + "schema": "public" } } } }, { - "name": "rules", + "name": "owners", "using": { "foreign_key_constraint_on": { - "column": "track_id", + "column": "tenant_id", "table": { - "name": "rule", + "name": "owner", "schema": "public" } } } - } - ], - "select_permissions": [ - { - "role": "approver", - "permission": { - "columns": [ - "track_id", - "track_name" - ], - "filter": {} - } }, { - "role": "auditor", - "permission": { - "columns": [ - "track_id", - "track_name" - ], - "filter": {} - } - }, - { - "role": "fw-admin", - "permission": { - "columns": [ - "track_name", - "track_id" - ], - "filter": {}, - "allow_aggregations": true + "name": "reports", + "using": { + "foreign_key_constraint_on": { + "column": "tenant_wide_visible", + "table": { + "name": "report", + "schema": "public" + } + } } }, { - "role": "implementer", - "permission": { - "columns": [ - "track_id", - "track_name" - ], - "filter": {} + "name": "tenant_networks", + "using": { + "foreign_key_constraint_on": { + "column": "tenant_id", + "table": { + "name": "tenant_network", + "schema": "public" + } + } } }, { - "role": "importer", - "permission": { - "columns": [], - "filter": {}, - "allow_aggregations": true + "name": "tenant_to_devices", + "using": { + "foreign_key_constraint_on": { + "column": "tenant_id", + "table": { + "name": "tenant_to_device", + "schema": "public" + } + } } }, { - "role": "planner", - "permission": { - "columns": [ - "track_id", - "track_name" - ], - "filter": {} + "name": "tenant_to_managements", + "using": { + "foreign_key_constraint_on": { + "column": "tenant_id", + "table": { + "name": "tenant_to_management", + "schema": "public" + } + } } }, { - "role": "recertifier", - "permission": { - "columns": [ - "track_id", - "track_name" - ], - "filter": {} + "name": "tickets", + "using": { + "foreign_key_constraint_on": { + "column": "tenant_id", + "table": { + "name": "ticket", + "schema": "request" + } + } } }, { - "role": "reporter", - "permission": { - "columns": [ - "track_id", - "track_name" - ], - "filter": {} + "name": "uiusers", + "using": { + "foreign_key_constraint_on": { + "column": "tenant_id", + "table": { + "name": "uiuser", + "schema": "public" + } + } } }, { - "role": "reporter-viewall", - "permission": { - "columns": [ - "track_id", - "track_name" - ], - "filter": {}, - "allow_aggregations": true + "name": "usrs", + "using": { + "foreign_key_constraint_on": { + "column": "tenant_id", + "table": { + "name": "usr", + "schema": "public" + } + } } - }, + } + ], + "insert_permissions": [ { - "role": "requester", + "role": "middleware-server", "permission": { + "check": {}, "columns": [ - "track_id", - "track_name" - ], - "filter": {} + "tenant_id", + "tenant_name", + "tenant_projekt", + "tenant_comment", + "tenant_report", + "tenant_can_view_all_devices", + "tenant_is_superadmin", + "tenant_create" + ] } - }, + } + ], + "select_permissions": [ { - "role": "reviewer", + "role": "approver", "permission": { "columns": [ - "track_id", - "track_name" - ], - "filter": {} - } - } - ] - }, - { - "table": { - "name": "stm_usr_typ", - "schema": "public" - }, - "array_relationships": [ - { - "name": "usrs", - "using": { - "foreign_key_constraint_on": { - "column": "usr_typ_id", - "table": { - "name": "usr", - "schema": "public" + "tenant_can_view_all_devices", + "tenant_is_superadmin", + "tenant_report", + "tenant_name", + "tenant_projekt", + "tenant_id", + "tenant_comment", + "tenant_create" + ], + "filter": { + "tenant_id": { + "_eq": "x-hasura-tenant-id" } } - } - } - ], - "select_permissions": [ + }, + "comment": "" + }, { "role": "auditor", "permission": { "columns": [ - "usr_typ_id", - "usr_typ_name" + "tenant_id", + "tenant_name", + "tenant_projekt", + "tenant_comment", + "tenant_report", + "tenant_can_view_all_devices", + "tenant_is_superadmin", + "tenant_create" ], "filter": {} } @@ -12968,156 +24283,241 @@ "role": "fw-admin", "permission": { "columns": [ - "usr_typ_name", - "usr_typ_id" + "tenant_can_view_all_devices", + "tenant_is_superadmin", + "tenant_report", + "tenant_name", + "tenant_projekt", + "tenant_id", + "tenant_comment", + "tenant_create" ], - "filter": {}, - "allow_aggregations": true + "filter": {} } }, { - "role": "importer", + "role": "implementer", "permission": { - "columns": [], - "filter": {}, - "allow_aggregations": true - } + "columns": [ + "tenant_can_view_all_devices", + "tenant_is_superadmin", + "tenant_report", + "tenant_name", + "tenant_projekt", + "tenant_id", + "tenant_comment", + "tenant_create" + ], + "filter": { + "tenant_id": { + "_eq": "x-hasura-tenant-id" + } + } + }, + "comment": "" }, { - "role": "recertifier", + "role": "middleware-server", "permission": { "columns": [ - "usr_typ_id", - "usr_typ_name" + "tenant_id", + "tenant_name", + "tenant_projekt", + "tenant_comment", + "tenant_report", + "tenant_can_view_all_devices", + "tenant_is_superadmin", + "tenant_create" ], - "filter": {} + "filter": {}, + "allow_aggregations": true } }, { - "role": "reporter", + "role": "modeller", "permission": { "columns": [ - "usr_typ_id", - "usr_typ_name" + "tenant_can_view_all_devices", + "tenant_is_superadmin", + "tenant_report", + "tenant_name", + "tenant_projekt", + "tenant_id", + "tenant_comment", + "tenant_create" ], - "filter": {} - } + "filter": { + "tenant_id": { + "_eq": "x-hasura-tenant-id" + } + } + }, + "comment": "" }, { - "role": "reporter-viewall", + "role": "planner", "permission": { "columns": [ - "usr_typ_id", - "usr_typ_name" + "tenant_can_view_all_devices", + "tenant_is_superadmin", + "tenant_report", + "tenant_name", + "tenant_projekt", + "tenant_id", + "tenant_comment", + "tenant_create" ], - "filter": {}, - "allow_aggregations": true - } - } - ] - }, - { - "table": { - "name": "svcgrp", - "schema": "public" - }, - "object_relationships": [ - { - "name": "importControlByImportLastSeen", - "using": { - "foreign_key_constraint_on": "import_last_seen" - } + "filter": { + "tenant_id": { + "_eq": "x-hasura-tenant-id" + } + } + }, + "comment": "" }, { - "name": "import_control", - "using": { - "foreign_key_constraint_on": "import_created" - } + "role": "recertifier", + "permission": { + "columns": [ + "tenant_can_view_all_devices", + "tenant_is_superadmin", + "tenant_report", + "tenant_name", + "tenant_projekt", + "tenant_id", + "tenant_comment", + "tenant_create" + ], + "filter": { + "tenant_id": { + "_eq": "x-hasura-tenant-id" + } + } + }, + "comment": "" }, { - "name": "service", - "using": { - "foreign_key_constraint_on": "svcgrp_id" - } + "role": "reporter", + "permission": { + "columns": [ + "tenant_can_view_all_devices", + "tenant_is_superadmin", + "tenant_report", + "tenant_name", + "tenant_projekt", + "tenant_id", + "tenant_comment", + "tenant_create" + ], + "filter": { + "tenant_id": { + "_eq": "x-hasura-tenant-id" + } + } + }, + "comment": "" }, { - "name": "serviceBySvcgrpMemberId", - "using": { - "foreign_key_constraint_on": "svcgrp_member_id" - } - } - ], - "select_permissions": [ - { - "role": "auditor", + "role": "reporter-viewall", "permission": { "columns": [ - "svcgrp_id", - "svcgrp_member_id", - "import_created", - "import_last_seen", - "active", - "negated" + "tenant_can_view_all_devices", + "tenant_is_superadmin", + "tenant_report", + "tenant_name", + "tenant_projekt", + "tenant_id", + "tenant_comment", + "tenant_create" ], "filter": {}, "allow_aggregations": true - } + }, + "comment": "" }, { - "role": "fw-admin", + "role": "requester", "permission": { "columns": [ - "import_created", - "import_last_seen", - "svcgrp_id", - "svcgrp_member_id", - "active", - "negated" + "tenant_can_view_all_devices", + "tenant_is_superadmin", + "tenant_report", + "tenant_name", + "tenant_projekt", + "tenant_id", + "tenant_comment", + "tenant_create" ], - "filter": {} - } + "filter": { + "tenant_id": { + "_eq": "x-hasura-tenant-id" + } + } + }, + "comment": "" }, { - "role": "recertifier", + "role": "reviewer", "permission": { "columns": [ - "svcgrp_id", - "svcgrp_member_id", - "import_created", - "import_last_seen", - "active", - "negated" + "tenant_can_view_all_devices", + "tenant_is_superadmin", + "tenant_report", + "tenant_name", + "tenant_projekt", + "tenant_id", + "tenant_comment", + "tenant_create" ], - "filter": {}, - "allow_aggregations": true - } - }, + "filter": { + "tenant_id": { + "_eq": "x-hasura-tenant-id" + } + } + }, + "comment": "" + } + ], + "update_permissions": [ { - "role": "reporter", + "role": "fw-admin", "permission": { "columns": [ - "svcgrp_id", - "svcgrp_member_id", - "import_created", - "import_last_seen", - "active", - "negated" + "tenant_can_view_all_devices", + "tenant_is_superadmin", + "tenant_report", + "tenant_name", + "tenant_projekt", + "tenant_id", + "tenant_comment", + "tenant_create" ], "filter": {}, - "allow_aggregations": true + "check": {} } }, { - "role": "reporter-viewall", + "role": "middleware-server", "permission": { "columns": [ - "svcgrp_id", - "svcgrp_member_id", - "import_created", - "import_last_seen", - "active", - "negated" + "tenant_can_view_all_devices", + "tenant_is_superadmin", + "tenant_report", + "tenant_name", + "tenant_projekt", + "tenant_id", + "tenant_comment", + "tenant_create" ], + "filter": {}, + "check": {} + } + } + ], + "delete_permissions": [ + { + "role": "middleware-server", + "permission": { "filter": {} } } @@ -13125,32 +24525,31 @@ }, { "table": { - "name": "svcgrp_flat", + "name": "tenant_network", "schema": "public" }, "object_relationships": [ { - "name": "importControlByImportLastSeen", - "using": { - "foreign_key_constraint_on": "import_last_seen" - } - }, - { - "name": "import_control", - "using": { - "foreign_key_constraint_on": "import_created" - } - }, - { - "name": "service", + "name": "tenant", "using": { - "foreign_key_constraint_on": "svcgrp_flat_id" + "foreign_key_constraint_on": "tenant_id" } - }, + } + ], + "insert_permissions": [ { - "name": "serviceBySvcgrpFlatMemberId", - "using": { - "foreign_key_constraint_on": "svcgrp_flat_member_id" + "role": "fw-admin", + "permission": { + "check": {}, + "columns": [ + "tenant_net_id", + "tenant_net_name", + "tenant_net_ip", + "tenant_net_ip_end", + "tenant_id", + "tenant_net_comment", + "tenant_net_create" + ] } } ], @@ -13159,12 +24558,13 @@ "role": "auditor", "permission": { "columns": [ - "svcgrp_flat_id", - "svcgrp_flat_member_id", - "import_created", - "import_last_seen", - "active", - "negated" + "tenant_net_id", + "tenant_net_name", + "tenant_net_ip", + "tenant_net_ip_end", + "tenant_id", + "tenant_net_comment", + "tenant_net_create" ], "filter": {}, "allow_aggregations": true @@ -13174,28 +24574,35 @@ "role": "fw-admin", "permission": { "columns": [ - "active", - "negated", - "import_created", - "import_last_seen", - "svcgrp_flat_id", - "svcgrp_flat_member_id" + "tenant_net_id", + "tenant_net_name", + "tenant_net_ip", + "tenant_net_ip_end", + "tenant_id", + "tenant_net_comment", + "tenant_net_create" ], - "filter": {} + "filter": {}, + "allow_aggregations": true } }, { "role": "recertifier", "permission": { "columns": [ - "svcgrp_flat_id", - "svcgrp_flat_member_id", - "import_created", - "import_last_seen", - "active", - "negated" + "tenant_net_id", + "tenant_net_name", + "tenant_net_ip", + "tenant_net_ip_end", + "tenant_id", + "tenant_net_comment", + "tenant_net_create" ], - "filter": {}, + "filter": { + "tenant_id": { + "_eq": "x-hasura-tenant-id" + } + }, "allow_aggregations": true } }, @@ -13203,14 +24610,19 @@ "role": "reporter", "permission": { "columns": [ - "svcgrp_flat_id", - "svcgrp_flat_member_id", - "import_created", - "import_last_seen", - "active", - "negated" + "tenant_net_id", + "tenant_net_name", + "tenant_net_ip", + "tenant_net_ip_end", + "tenant_id", + "tenant_net_comment", + "tenant_net_create" ], - "filter": {}, + "filter": { + "tenant_id": { + "_eq": "x-hasura-tenant-id" + } + }, "allow_aggregations": true } }, @@ -13218,13 +24630,41 @@ "role": "reporter-viewall", "permission": { "columns": [ - "svcgrp_flat_id", - "svcgrp_flat_member_id", - "import_created", - "import_last_seen", - "active", - "negated" + "tenant_net_id", + "tenant_net_name", + "tenant_net_ip", + "tenant_net_ip_end", + "tenant_id", + "tenant_net_comment", + "tenant_net_create" + ], + "filter": {}, + "allow_aggregations": true + } + } + ], + "update_permissions": [ + { + "role": "fw-admin", + "permission": { + "columns": [ + "tenant_net_id", + "tenant_net_name", + "tenant_net_ip", + "tenant_net_ip_end", + "tenant_id", + "tenant_net_comment", + "tenant_net_create" ], + "filter": {}, + "check": {} + } + } + ], + "delete_permissions": [ + { + "role": "fw-admin", + "permission": { "filter": {} } } @@ -13232,230 +24672,240 @@ }, { "table": { - "name": "tenant", + "name": "tenant_to_device", "schema": "public" }, - "array_relationships": [ + "object_relationships": [ { - "name": "approvals", + "name": "device", "using": { - "foreign_key_constraint_on": { - "column": "tenant_id", - "table": { - "name": "approval", - "schema": "request" - } - } + "foreign_key_constraint_on": "device_id" } }, { - "name": "devices", + "name": "tenant", "using": { - "foreign_key_constraint_on": { - "column": "tenant_id", - "table": { - "name": "device", - "schema": "public" - } - } + "foreign_key_constraint_on": "tenant_id" } - }, + } + ], + "insert_permissions": [ { - "name": "ldap_connections", - "using": { - "foreign_key_constraint_on": { - "column": "tenant_id", - "table": { - "name": "ldap_connection", - "schema": "public" - } - } + "role": "fw-admin", + "permission": { + "check": {}, + "columns": [ + "tenant_id", + "device_id", + "shared" + ] } - }, + } + ], + "select_permissions": [ { - "name": "management", - "using": { - "foreign_key_constraint_on": { - "column": "tenant_id", - "table": { - "name": "management", - "schema": "public" + "role": "approver", + "permission": { + "columns": [ + "tenant_id", + "device_id", + "shared" + ], + "filter": { + "tenant_id": { + "_eq": "x-hasura-tenant-id" } } + }, + "comment": "" + }, + { + "role": "auditor", + "permission": { + "columns": [ + "tenant_id", + "device_id", + "shared" + ], + "filter": {} } }, { - "name": "owners", - "using": { - "foreign_key_constraint_on": { - "column": "tenant_id", - "table": { - "name": "owner", - "schema": "public" - } - } + "role": "fw-admin", + "permission": { + "columns": [ + "tenant_id", + "device_id", + "shared" + ], + "filter": {} } }, { - "name": "reports", - "using": { - "foreign_key_constraint_on": { - "column": "tenant_wide_visible", - "table": { - "name": "report", - "schema": "public" + "role": "implementer", + "permission": { + "columns": [ + "tenant_id", + "device_id", + "shared" + ], + "filter": { + "tenant_id": { + "_eq": "x-hasura-tenant-id" } } - } + }, + "comment": "" }, { - "name": "tenant_networks", - "using": { - "foreign_key_constraint_on": { - "column": "tenant_id", - "table": { - "name": "tenant_network", - "schema": "public" - } - } + "role": "middleware-server", + "permission": { + "columns": [ + "tenant_id", + "device_id", + "shared" + ], + "filter": {} } }, { - "name": "tenant_to_devices", - "using": { - "foreign_key_constraint_on": { - "column": "tenant_id", - "table": { - "name": "tenant_to_device", - "schema": "public" + "role": "modeller", + "permission": { + "columns": [ + "tenant_id", + "device_id", + "shared" + ], + "filter": { + "tenant_id": { + "_eq": "x-hasura-tenant-id" } } - } + }, + "comment": "" }, { - "name": "tickets", - "using": { - "foreign_key_constraint_on": { - "column": "tenant_id", - "table": { - "name": "ticket", - "schema": "request" + "role": "planner", + "permission": { + "columns": [ + "tenant_id", + "device_id", + "shared" + ], + "filter": { + "tenant_id": { + "_eq": "x-hasura-tenant-id" } } - } + }, + "comment": "" }, { - "name": "uiusers", - "using": { - "foreign_key_constraint_on": { - "column": "tenant_id", - "table": { - "name": "uiuser", - "schema": "public" + "role": "recertifier", + "permission": { + "columns": [ + "tenant_id", + "device_id", + "shared" + ], + "filter": { + "tenant_id": { + "_eq": "x-hasura-tenant-id" } } - } + }, + "comment": "" }, { - "name": "usrs", - "using": { - "foreign_key_constraint_on": { - "column": "tenant_id", - "table": { - "name": "usr", - "schema": "public" + "role": "reporter", + "permission": { + "columns": [ + "tenant_id", + "device_id", + "shared" + ], + "filter": { + "tenant_id": { + "_eq": "x-hasura-tenant-id" } } - } - } - ], - "insert_permissions": [ + }, + "comment": "" + }, { - "role": "middleware-server", + "role": "reporter-viewall", "permission": { - "check": {}, "columns": [ "tenant_id", - "tenant_name", - "tenant_projekt", - "tenant_comment", - "tenant_report", - "tenant_can_view_all_devices", - "tenant_is_superadmin", - "tenant_create" - ] - } - } - ], - "select_permissions": [ + "device_id", + "shared" + ], + "filter": {}, + "allow_aggregations": true + }, + "comment": "" + }, { - "role": "auditor", + "role": "requester", "permission": { "columns": [ "tenant_id", - "tenant_name", - "tenant_projekt", - "tenant_comment", - "tenant_report", - "tenant_can_view_all_devices", - "tenant_is_superadmin", - "tenant_create" + "device_id", + "shared" ], - "filter": {} - } + "filter": { + "tenant_id": { + "_eq": "x-hasura-tenant-id" + } + } + }, + "comment": "" }, { - "role": "middleware-server", + "role": "reviewer", "permission": { "columns": [ "tenant_id", - "tenant_name", - "tenant_projekt", - "tenant_comment", - "tenant_report", - "tenant_can_view_all_devices", - "tenant_is_superadmin", - "tenant_create" + "device_id", + "shared" ], - "filter": {}, - "allow_aggregations": true - } + "filter": { + "tenant_id": { + "_eq": "x-hasura-tenant-id" + } + } + }, + "comment": "" } ], "update_permissions": [ { - "role": "middleware-server", + "role": "fw-admin", "permission": { "columns": [ "tenant_id", - "tenant_name", - "tenant_projekt", - "tenant_comment", - "tenant_report", - "tenant_can_view_all_devices", - "tenant_is_superadmin", - "tenant_create" + "device_id", + "shared" ], "filter": {}, - "check": null - } - } - ], - "delete_permissions": [ - { - "role": "middleware-server", - "permission": { - "filter": {} - } + "check": {} + }, + "comment": "" } ] }, { "table": { - "name": "tenant_network", + "name": "tenant_to_management", "schema": "public" }, "object_relationships": [ + { + "name": "management", + "using": { + "foreign_key_constraint_on": "management_id" + } + }, { "name": "tenant", "using": { @@ -13463,169 +24913,241 @@ } } ], - "insert_permissions": [ + "select_permissions": [ { - "role": "fw-admin", + "role": "approver", "permission": { - "check": {}, "columns": [ - "tenant_net_id", - "tenant_net_name", - "tenant_net_ip", - "tenant_net_ip_end", - "tenant_id", - "tenant_net_comment", - "tenant_net_create" - ] - } - } - ], - "select_permissions": [ + "shared", + "management_id", + "tenant_id" + ], + "filter": { + "tenant_id": { + "_eq": "x-hasura-tenant-id" + } + } + }, + "comment": "" + }, { "role": "auditor", "permission": { "columns": [ - "tenant_net_id", - "tenant_net_name", - "tenant_net_ip", - "tenant_net_ip_end", - "tenant_id", - "tenant_net_comment", - "tenant_net_create" + "shared", + "management_id", + "tenant_id" + ], + "filter": {} + }, + "comment": "" + }, + { + "role": "fw-admin", + "permission": { + "columns": [ + "shared", + "management_id", + "tenant_id" + ], + "filter": {} + }, + "comment": "" + }, + { + "role": "implementer", + "permission": { + "columns": [ + "shared", + "management_id", + "tenant_id" + ], + "filter": { + "tenant_id": { + "_eq": "x-hasura-tenant-id" + } + } + }, + "comment": "" + }, + { + "role": "middleware-server", + "permission": { + "columns": [ + "shared", + "management_id", + "tenant_id" + ], + "filter": {} + }, + "comment": "" + }, + { + "role": "modeller", + "permission": { + "columns": [ + "shared", + "management_id", + "tenant_id" ], - "filter": {}, - "allow_aggregations": true - } + "filter": { + "tenant_id": { + "_eq": "x-hasura-tenant-id" + } + } + }, + "comment": "" }, { - "role": "fw-admin", + "role": "planner", "permission": { "columns": [ - "tenant_net_id", - "tenant_net_name", - "tenant_net_ip", - "tenant_net_ip_end", - "tenant_id", - "tenant_net_comment", - "tenant_net_create" + "shared", + "management_id", + "tenant_id" ], - "filter": {}, - "allow_aggregations": true - } + "filter": { + "tenant_id": { + "_eq": "x-hasura-tenant-id" + } + } + }, + "comment": "" }, { "role": "recertifier", "permission": { "columns": [ - "tenant_net_id", - "tenant_net_name", - "tenant_net_ip", - "tenant_net_ip_end", - "tenant_id", - "tenant_net_comment", - "tenant_net_create" + "shared", + "management_id", + "tenant_id" ], "filter": { "tenant_id": { "_eq": "x-hasura-tenant-id" } - }, - "allow_aggregations": true - } + } + }, + "comment": "" }, { "role": "reporter", "permission": { "columns": [ - "tenant_net_id", - "tenant_net_name", - "tenant_net_ip", - "tenant_net_ip_end", - "tenant_id", - "tenant_net_comment", - "tenant_net_create" + "shared", + "management_id", + "tenant_id" ], "filter": { "tenant_id": { "_eq": "x-hasura-tenant-id" } - }, - "allow_aggregations": true - } + } + }, + "comment": "" }, { "role": "reporter-viewall", "permission": { "columns": [ - "tenant_net_id", - "tenant_net_name", - "tenant_net_ip", - "tenant_net_ip_end", - "tenant_id", - "tenant_net_comment", - "tenant_net_create" + "shared", + "management_id", + "tenant_id" ], - "filter": {}, - "allow_aggregations": true - } - } - ], - "update_permissions": [ + "filter": {} + }, + "comment": "" + }, { - "role": "fw-admin", + "role": "requester", "permission": { "columns": [ - "tenant_net_id", - "tenant_net_name", - "tenant_net_ip", - "tenant_net_ip_end", - "tenant_id", - "tenant_net_comment", - "tenant_net_create" + "shared", + "management_id", + "tenant_id" ], - "filter": {}, - "check": {} - } - } - ], - "delete_permissions": [ + "filter": { + "tenant_id": { + "_eq": "x-hasura-tenant-id" + } + } + }, + "comment": "" + }, { - "role": "fw-admin", + "role": "reviewer", "permission": { - "filter": {} - } + "columns": [ + "shared", + "management_id", + "tenant_id" + ], + "filter": { + "tenant_id": { + "_eq": "x-hasura-tenant-id" + } + } + }, + "comment": "" } ] }, { "table": { - "name": "tenant_to_device", + "name": "time_object", "schema": "public" }, "object_relationships": [ { - "name": "device", + "name": "import_control_created", "using": { - "foreign_key_constraint_on": "device_id" + "foreign_key_constraint_on": "created" } }, { - "name": "tenant", + "name": "import_control_removed", "using": { - "foreign_key_constraint_on": "tenant_id" + "foreign_key_constraint_on": "removed" + } + }, + { + "name": "management", + "using": { + "foreign_key_constraint_on": "mgm_id" + } + } + ], + "array_relationships": [ + { + "name": "rule_times", + "using": { + "foreign_key_constraint_on": { + "column": "time_obj_id", + "table": { + "name": "rule_time", + "schema": "public" + } + } } } ], "insert_permissions": [ { - "role": "fw-admin", + "role": "importer", "permission": { "check": {}, "columns": [ - "device_id", - "tenant_id" + "created", + "removed", + "time_obj_id", + "time_obj_name", + "time_obj_uid", + "mgm_id", + "end_time", + "start_time" ] - } + }, + "comment": "" } ], "select_permissions": [ @@ -13633,44 +25155,178 @@ "role": "auditor", "permission": { "columns": [ - "tenant_id", - "device_id" + "created", + "removed", + "time_obj_id", + "time_obj_name", + "time_obj_uid", + "mgm_id", + "end_time", + "start_time" ], "filter": {} - } + }, + "comment": "" }, { "role": "fw-admin", "permission": { "columns": [ - "device_id", - "tenant_id" + "created", + "removed", + "time_obj_id", + "time_obj_name", + "time_obj_uid", + "mgm_id", + "end_time", + "start_time" ], "filter": {} - } + }, + "comment": "" + }, + { + "role": "importer", + "permission": { + "columns": [ + "created", + "removed", + "time_obj_id", + "time_obj_name", + "time_obj_uid", + "mgm_id", + "end_time", + "start_time" + ], + "filter": {} + }, + "comment": "" }, { "role": "middleware-server", "permission": { "columns": [ - "tenant_id", - "device_id" + "created", + "removed", + "time_obj_id", + "time_obj_name", + "time_obj_uid", + "mgm_id", + "end_time", + "start_time" ], "filter": {} - } + }, + "comment": "" + }, + { + "role": "modeller", + "permission": { + "columns": [ + "created", + "removed", + "time_obj_id", + "time_obj_name", + "time_obj_uid", + "mgm_id", + "end_time", + "start_time" + ], + "filter": { + "mgm_id": { + "_in": "x-hasura-visible-managements" + } + } + }, + "comment": "" + }, + { + "role": "recertifier", + "permission": { + "columns": [ + "created", + "removed", + "time_obj_id", + "time_obj_name", + "time_obj_uid", + "mgm_id", + "end_time", + "start_time" + ], + "filter": { + "mgm_id": { + "_in": "x-hasura-visible-managements" + } + } + }, + "comment": "" + }, + { + "role": "reporter", + "permission": { + "columns": [ + "created", + "removed", + "time_obj_id", + "time_obj_name", + "time_obj_uid", + "mgm_id", + "end_time", + "start_time" + ], + "filter": { + "mgm_id": { + "_in": "x-hasura-visible-managements" + } + } + }, + "comment": "" + }, + { + "role": "reporter-viewall", + "permission": { + "columns": [ + "created", + "removed", + "time_obj_id", + "time_obj_name", + "time_obj_uid", + "mgm_id", + "end_time", + "start_time" + ], + "filter": {} + }, + "comment": "" } ], "update_permissions": [ { - "role": "fw-admin", + "role": "importer", "permission": { "columns": [ - "device_id", - "tenant_id" + "created", + "removed", + "time_obj_id", + "time_obj_name", + "time_obj_uid", + "mgm_id", + "end_time", + "start_time" ], "filter": {}, - "check": null - } + "check": {} + }, + "comment": "" + } + ], + "delete_permissions": [ + { + "role": "importer", + "permission": { + "filter": {} + }, + "comment": "" } ] }, @@ -13755,6 +25411,18 @@ "filter": {} } }, + { + "role": "modeller", + "permission": { + "columns": [ + "id", + "language", + "txt" + ], + "filter": {} + }, + "comment": "" + }, { "role": "planner", "permission": { @@ -14041,6 +25709,18 @@ } } }, + { + "name": "notifications", + "using": { + "foreign_key_constraint_on": { + "column": "user_id", + "table": { + "name": "notification", + "schema": "public" + } + } + } + }, { "name": "objects", "using": { @@ -14053,6 +25733,18 @@ } } }, + { + "name": "owners", + "using": { + "foreign_key_constraint_on": { + "column": "last_recertifier", + "table": { + "name": "owner", + "schema": "public" + } + } + } + }, { "name": "report_schedules", "using": { @@ -14113,30 +25805,6 @@ } } }, - { - "name": "ruleMetadataByRuleOwner", - "using": { - "foreign_key_constraint_on": { - "column": "rule_owner", - "table": { - "name": "rule_metadata", - "schema": "public" - } - } - } - }, - { - "name": "rule_metadata", - "using": { - "foreign_key_constraint_on": { - "column": "rule_last_certifier", - "table": { - "name": "rule_metadata", - "schema": "public" - } - } - } - }, { "name": "rules", "using": { @@ -14352,6 +26020,17 @@ "filter": {} } }, + { + "role": "importer", + "permission": { + "columns": [ + "uiuser_id", + "uiuser_username" + ], + "filter": {} + }, + "comment": "" + }, { "role": "middleware-server", "permission": { @@ -14375,6 +26054,29 @@ "filter": {} } }, + { + "role": "modeller", + "permission": { + "columns": [ + "ldap_connection_id", + "tenant_id", + "uiuser_email", + "uiuser_end_date", + "uiuser_first_name", + "uiuser_id", + "uiuser_language", + "uiuser_last_login", + "uiuser_last_name", + "uiuser_last_password_change", + "uiuser_password_must_be_changed", + "uiuser_pwd_history", + "uiuser_start_date", + "uiuser_username", + "uuid" + ], + "filter": {} + } + }, { "role": "planner", "permission": { @@ -14418,11 +26120,7 @@ "uiuser_username", "uuid" ], - "filter": { - "uuid": { - "_eq": "x-hasura-uuid" - } - } + "filter": {} } }, { @@ -14445,11 +26143,7 @@ "uiuser_username", "uuid" ], - "filter": { - "uuid": { - "_eq": "x-hasura-uuid" - } - } + "filter": {} } }, { @@ -14472,11 +26166,7 @@ "uiuser_username", "uuid" ], - "filter": { - "uuid": { - "_eq": "x-hasura-uuid" - } - } + "filter": {} } }, { @@ -14621,6 +26311,20 @@ "check": null } }, + { + "role": "modeller", + "permission": { + "columns": [ + "uiuser_language" + ], + "filter": { + "uuid": { + "_eq": "x-hasura-uuid" + } + }, + "check": null + } + }, { "role": "planner", "permission": { @@ -14746,6 +26450,23 @@ } } ], + "insert_permissions": [ + { + "role": "importer", + "permission": { + "check": {}, + "columns": [ + "import_created", + "import_last_seen", + "removed", + "usergrp_id", + "usergrp_member_id", + "active" + ] + }, + "comment": "" + } + ], "select_permissions": [ { "role": "approver", @@ -14754,6 +26475,7 @@ "usergrp_id", "usergrp_member_id", "import_created", + "removed", "import_last_seen", "active" ], @@ -14769,6 +26491,7 @@ "usergrp_member_id", "import_created", "import_last_seen", + "removed", "active" ], "filter": {}, @@ -14781,6 +26504,7 @@ "columns": [ "import_created", "import_last_seen", + "removed", "usergrp_id", "usergrp_member_id", "active" @@ -14796,6 +26520,55 @@ "usergrp_member_id", "import_created", "import_last_seen", + "removed", + "active" + ], + "filter": {}, + "allow_aggregations": true + } + }, + { + "role": "importer", + "permission": { + "columns": [ + "import_created", + "import_last_seen", + "removed", + "removed", + "usergrp_id", + "usergrp_member_id", + "active" + ], + "filter": {}, + "allow_aggregations": true + }, + "comment": "" + }, + { + "role": "middleware-server", + "permission": { + "columns": [ + "import_created", + "import_last_seen", + "removed", + "usergrp_id", + "usergrp_member_id", + "active" + ], + "filter": {}, + "allow_aggregations": true + }, + "comment": "" + }, + { + "role": "modeller", + "permission": { + "columns": [ + "usergrp_id", + "usergrp_member_id", + "import_created", + "import_last_seen", + "removed", "active" ], "filter": {}, @@ -14810,6 +26583,7 @@ "usergrp_member_id", "import_created", "import_last_seen", + "removed", "active" ], "filter": {}, @@ -14824,6 +26598,7 @@ "usergrp_member_id", "import_created", "import_last_seen", + "removed", "active" ], "filter": {}, @@ -14838,6 +26613,7 @@ "usergrp_member_id", "import_created", "import_last_seen", + "removed", "active" ], "filter": {}, @@ -14852,6 +26628,7 @@ "usergrp_member_id", "import_created", "import_last_seen", + "removed", "active" ], "filter": {} @@ -14865,6 +26642,7 @@ "usergrp_member_id", "import_created", "import_last_seen", + "removed", "active" ], "filter": {}, @@ -14879,12 +26657,40 @@ "usergrp_member_id", "import_created", "import_last_seen", + "removed", "active" ], "filter": {}, "allow_aggregations": true } } + ], + "update_permissions": [ + { + "role": "importer", + "permission": { + "columns": [ + "import_created", + "import_last_seen", + "removed", + "usergrp_id", + "usergrp_member_id", + "active" + ], + "filter": {}, + "check": {} + }, + "comment": "" + } + ], + "delete_permissions": [ + { + "role": "importer", + "permission": { + "filter": {} + }, + "comment": "" + } ] }, { @@ -14918,6 +26724,23 @@ } } ], + "insert_permissions": [ + { + "role": "importer", + "permission": { + "check": {}, + "columns": [ + "import_created", + "import_last_seen", + "removed", + "usergrp_flat_id", + "usergrp_flat_member_id", + "active" + ] + }, + "comment": "" + } + ], "select_permissions": [ { "role": "auditor", @@ -14927,7 +26750,8 @@ "usergrp_flat_id", "usergrp_flat_member_id", "import_created", - "import_last_seen" + "import_last_seen", + "removed" ], "filter": {}, "allow_aggregations": true @@ -14939,6 +26763,7 @@ "columns": [ "import_created", "import_last_seen", + "removed", "usergrp_flat_id", "usergrp_flat_member_id", "active" @@ -14946,6 +26771,53 @@ "filter": {} } }, + { + "role": "importer", + "permission": { + "columns": [ + "import_created", + "import_last_seen", + "removed", + "usergrp_flat_id", + "usergrp_flat_member_id", + "active" + ], + "filter": {}, + "allow_aggregations": true + }, + "comment": "" + }, + { + "role": "middleware-server", + "permission": { + "columns": [ + "import_created", + "import_last_seen", + "removed", + "usergrp_flat_id", + "usergrp_flat_member_id", + "active" + ], + "filter": {}, + "allow_aggregations": true + }, + "comment": "" + }, + { + "role": "modeller", + "permission": { + "columns": [ + "active", + "usergrp_flat_id", + "usergrp_flat_member_id", + "import_created", + "removed", + "import_last_seen" + ], + "filter": {}, + "allow_aggregations": true + } + }, { "role": "recertifier", "permission": { @@ -14954,6 +26826,7 @@ "usergrp_flat_id", "usergrp_flat_member_id", "import_created", + "removed", "import_last_seen" ], "filter": {}, @@ -14968,6 +26841,7 @@ "usergrp_flat_id", "usergrp_flat_member_id", "import_created", + "removed", "import_last_seen" ], "filter": {}, @@ -14982,10 +26856,38 @@ "usergrp_flat_id", "usergrp_flat_member_id", "import_created", + "removed", "import_last_seen" ], "filter": {} - } + } + } + ], + "update_permissions": [ + { + "role": "importer", + "permission": { + "columns": [ + "import_created", + "import_last_seen", + "removed", + "usergrp_flat_id", + "usergrp_flat_member_id", + "active" + ], + "filter": {}, + "check": {} + }, + "comment": "" + } + ], + "delete_permissions": [ + { + "role": "importer", + "permission": { + "filter": {} + }, + "comment": "" } ] }, @@ -15196,6 +27098,40 @@ } } ], + "insert_permissions": [ + { + "role": "importer", + "permission": { + "check": {}, + "columns": [ + "removed", + "user_create", + "user_id", + "user_last_seen", + "active", + "user_authmethod", + "user_firstname", + "user_lastname", + "user_name", + "user_valid_from", + "user_valid_until", + "last_change_admin", + "mgm_id", + "tenant_id", + "user_color_id", + "usr_typ_id", + "dst_restrict", + "src_restrict", + "time_restrict", + "user_comment", + "user_member_names", + "user_member_refs", + "user_uid" + ] + }, + "comment": "" + } + ], "select_permissions": [ { "role": "auditor", @@ -15217,6 +27153,7 @@ "time_restrict", "user_create", "user_last_seen", + "removed", "user_comment", "user_uid", "user_firstname", @@ -15232,6 +27169,39 @@ "role": "fw-admin", "permission": { "columns": [ + "user_create", + "user_id", + "user_last_seen", + "removed", + "active", + "user_authmethod", + "user_firstname", + "user_lastname", + "user_name", + "user_valid_from", + "user_valid_until", + "last_change_admin", + "mgm_id", + "tenant_id", + "user_color_id", + "usr_typ_id", + "dst_restrict", + "src_restrict", + "time_restrict", + "user_comment", + "user_member_names", + "user_member_refs", + "user_uid" + ], + "filter": {}, + "allow_aggregations": true + } + }, + { + "role": "importer", + "permission": { + "columns": [ + "removed", "user_create", "user_id", "user_last_seen", @@ -15257,6 +27227,75 @@ ], "filter": {}, "allow_aggregations": true + }, + "comment": "" + }, + { + "role": "middleware-server", + "permission": { + "columns": [ + "user_create", + "user_id", + "user_last_seen", + "removed", + "active", + "user_authmethod", + "user_firstname", + "user_lastname", + "user_name", + "user_valid_from", + "user_valid_until", + "last_change_admin", + "mgm_id", + "tenant_id", + "user_color_id", + "usr_typ_id", + "dst_restrict", + "src_restrict", + "time_restrict", + "user_comment", + "user_member_names", + "user_member_refs", + "user_uid" + ], + "filter": {} + }, + "comment": "" + }, + { + "role": "modeller", + "permission": { + "columns": [ + "user_id", + "usr_typ_id", + "user_color_id", + "mgm_id", + "user_name", + "active", + "user_member_names", + "user_member_refs", + "user_authmethod", + "user_valid_from", + "user_valid_until", + "src_restrict", + "dst_restrict", + "time_restrict", + "user_create", + "user_last_seen", + "removed", + "user_comment", + "user_uid", + "user_firstname", + "user_lastname", + "last_change_admin", + "tenant_id" + ], + "filter": { + "mgm_id": { + "_in": "x-hasura-visible-managements" + } + }, + "allow_aggregations": true } }, { @@ -15279,6 +27318,7 @@ "time_restrict", "user_create", "user_last_seen", + "removed", "user_comment", "user_uid", "user_firstname", @@ -15314,6 +27354,7 @@ "time_restrict", "user_create", "user_last_seen", + "removed", "user_comment", "user_uid", "user_firstname", @@ -15349,6 +27390,7 @@ "time_restrict", "user_create", "user_last_seen", + "removed", "user_comment", "user_uid", "user_firstname", @@ -15360,6 +27402,50 @@ "allow_aggregations": true } } + ], + "update_permissions": [ + { + "role": "importer", + "permission": { + "columns": [ + "removed", + "user_create", + "user_id", + "user_last_seen", + "active", + "user_authmethod", + "user_firstname", + "user_lastname", + "user_name", + "user_valid_from", + "user_valid_until", + "last_change_admin", + "mgm_id", + "tenant_id", + "user_color_id", + "usr_typ_id", + "dst_restrict", + "src_restrict", + "time_restrict", + "user_comment", + "user_member_names", + "user_member_refs", + "user_uid" + ], + "filter": {}, + "check": {} + }, + "comment": "" + } + ], + "delete_permissions": [ + { + "role": "importer", + "permission": { + "filter": {} + }, + "comment": "" + } ] }, { @@ -15370,67 +27456,55 @@ }, { "table": { - "name": "v_rule_with_dst_owner", - "schema": "public" - } - }, - { - "table": { - "name": "v_rule_with_src_owner", - "schema": "public" - } - }, - { - "table": { - "name": "view_change_counter", + "name": "v_excluded_dst_ips", "schema": "public" } }, { "table": { - "name": "view_changes", + "name": "v_excluded_src_ips", "schema": "public" } }, { "table": { - "name": "view_changes_by_changed_element_id", + "name": "v_rule_ownership_mode", "schema": "public" } }, { "table": { - "name": "view_device_names", + "name": "v_rule_with_dst_owner", "schema": "public" } }, { "table": { - "name": "view_documented_change_counter", + "name": "v_rule_with_ip_owner", "schema": "public" } }, { "table": { - "name": "view_import_status_errors", + "name": "v_rule_with_rule_owner", "schema": "public" } }, { "table": { - "name": "view_import_status_successful", + "name": "v_rule_with_rule_owner_1", "schema": "public" } }, { "table": { - "name": "view_import_status_table", + "name": "v_rule_with_src_owner", "schema": "public" } }, { "table": { - "name": "view_import_status_table_unsorted", + "name": "view_changes", "schema": "public" } }, @@ -15465,394 +27539,113 @@ }, "object_relationships": [ { - "name": "device", - "using": { - "manual_configuration": { - "column_mapping": { - "dev_id": "dev_id" - }, - "insertion_order": null, - "remote_table": { - "name": "device", - "schema": "public" - } - } - } - }, - { - "name": "dst_zone", - "using": { - "manual_configuration": { - "column_mapping": { - "rule_to_zone": "zone_id" - }, - "insertion_order": null, - "remote_table": { - "name": "zone", - "schema": "public" - } - } - } - }, - { - "name": "rule_metadatum", - "using": { - "manual_configuration": { - "column_mapping": { - "dev_id": "dev_id", - "rule_uid": "rule_uid" - }, - "insertion_order": null, - "remote_table": { - "name": "rule_metadata", - "schema": "public" - } - } - } - }, - { - "name": "src_zone", - "using": { - "manual_configuration": { - "column_mapping": { - "rule_from_zone": "zone_id" - }, - "insertion_order": null, - "remote_table": { - "name": "zone", - "schema": "public" - } - } - } - } - ], - "array_relationships": [ - { - "name": "rule_froms", + "name": "dst_zone", "using": { "manual_configuration": { "column_mapping": { - "rule_id": "rule_id" + "rule_to_zone": "zone_id" }, "insertion_order": null, "remote_table": { - "name": "rule_from", + "name": "zone", "schema": "public" } } } }, { - "name": "rule_services", + "name": "src_zone", "using": { "manual_configuration": { "column_mapping": { - "rule_id": "rule_id" + "rule_from_zone": "zone_id" }, "insertion_order": null, "remote_table": { - "name": "rule_service", + "name": "zone", "schema": "public" } } } - }, + } + ], + "array_relationships": [ { - "name": "rule_tos", + "name": "rule_froms", "using": { "manual_configuration": { "column_mapping": { "rule_id": "rule_id" }, "insertion_order": null, - "remote_table": { - "name": "rule_to", - "schema": "public" - } - } - } - } - ], - "select_permissions": [ - { - "role": "auditor", - "permission": { - "columns": [ - "rule_id", - "xlate_rule", - "access_rule", - "nat_rule", - "rule_disabled", - "rule_dst_neg", - "rule_src_neg", - "rule_svc_neg", - "owner_name", - "rule_name", - "action_id", - "dev_id", - "mgm_id", - "owner_id", - "recert_interval", - "rule_from_zone", - "rule_last_certifier", - "rule_to_zone", - "track_id", - "rule_num_numeric", - "matches", - "rule_action", - "rule_comment", - "rule_head_text", - "rule_track", - "rule_uid", - "rule_last_certified" - ], - "filter": { - "dev_id": { - "_in": "x-hasura-visible-devices" - } - }, - "allow_aggregations": true - } - }, - { - "role": "recertifier", - "permission": { - "columns": [ - "rule_id", - "xlate_rule", - "access_rule", - "nat_rule", - "rule_disabled", - "rule_dst_neg", - "rule_src_neg", - "rule_svc_neg", - "owner_name", - "rule_name", - "action_id", - "dev_id", - "mgm_id", - "owner_id", - "recert_interval", - "rule_from_zone", - "rule_last_certifier", - "rule_to_zone", - "track_id", - "rule_num_numeric", - "matches", - "rule_action", - "rule_comment", - "rule_head_text", - "rule_track", - "rule_uid", - "rule_last_certified" - ], - "filter": { - "_and": [ - { - "mgm_id": { - "_in": "x-hasura-visible-managements" - } - }, - { - "dev_id": { - "_in": "x-hasura-visible-devices" - } - } - ] - }, - "allow_aggregations": true - } - }, - { - "role": "reporter", - "permission": { - "columns": [ - "rule_id", - "xlate_rule", - "access_rule", - "nat_rule", - "rule_disabled", - "rule_dst_neg", - "rule_src_neg", - "rule_svc_neg", - "owner_name", - "rule_name", - "action_id", - "dev_id", - "mgm_id", - "owner_id", - "recert_interval", - "rule_from_zone", - "rule_last_certifier", - "rule_to_zone", - "track_id", - "rule_num_numeric", - "matches", - "rule_action", - "rule_comment", - "rule_head_text", - "rule_track", - "rule_uid", - "rule_last_certified" - ], - "filter": { - "_and": [ - { - "mgm_id": { - "_in": "x-hasura-visible-managements" - } - }, - { - "dev_id": { - "_in": "x-hasura-visible-devices" - } - } - ] - }, - "allow_aggregations": true - } - }, - { - "role": "reporter-viewall", - "permission": { - "columns": [ - "rule_id", - "xlate_rule", - "access_rule", - "nat_rule", - "rule_disabled", - "rule_dst_neg", - "rule_src_neg", - "rule_svc_neg", - "owner_name", - "rule_name", - "action_id", - "dev_id", - "mgm_id", - "owner_id", - "recert_interval", - "rule_from_zone", - "rule_last_certifier", - "rule_to_zone", - "track_id", - "rule_num_numeric", - "matches", - "rule_action", - "rule_comment", - "rule_head_text", - "rule_track", - "rule_uid", - "rule_last_certified" - ], - "filter": {}, - "allow_aggregations": true - } - } - ] - }, - { - "table": { - "name": "view_svc_changes", - "schema": "public" - } - }, - { - "table": { - "name": "view_tenant_rules", - "schema": "public" - }, - "select_permissions": [ - { - "role": "auditor", - "permission": { - "columns": [ - "parent_rule_id", - "rule_create", - "rule_id", - "rule_last_seen", - "xlate_rule", - "access_rule", - "active", - "nat_rule", - "rule_disabled", - "rule_dst_neg", - "rule_implied", - "rule_src_neg", - "rule_svc_neg", - "rule_installon", - "rule_name", - "rule_ruleid", - "rule_time", - "action_id", - "dev_id", - "last_change_admin", - "mgm_id", - "rule_from_zone", - "rule_num", - "rule_to_zone", - "tenant_id", - "track_id", - "rule_num_numeric", - "parent_rule_type", - "rule_action", - "rule_comment", - "rule_dst", - "rule_dst_refs", - "rule_head_text", - "rule_src", - "rule_src_refs", - "rule_svc", - "rule_svc_refs", - "rule_track", - "rule_uid" - ], - "filter": {}, - "allow_aggregations": true + "remote_table": { + "name": "rule_from", + "schema": "public" + } + } } }, { - "role": "fw-admin", + "name": "rule_services", + "using": { + "manual_configuration": { + "column_mapping": { + "rule_id": "rule_id" + }, + "insertion_order": null, + "remote_table": { + "name": "rule_service", + "schema": "public" + } + } + } + }, + { + "name": "rule_tos", + "using": { + "manual_configuration": { + "column_mapping": { + "rule_id": "rule_id" + }, + "insertion_order": null, + "remote_table": { + "name": "rule_to", + "schema": "public" + } + } + } + } + ], + "select_permissions": [ + { + "role": "auditor", "permission": { "columns": [ - "parent_rule_id", - "rule_create", "rule_id", - "rule_last_seen", "xlate_rule", "access_rule", - "active", "nat_rule", "rule_disabled", "rule_dst_neg", - "rule_implied", "rule_src_neg", "rule_svc_neg", - "rule_installon", + "owner_name", "rule_name", - "rule_ruleid", - "rule_time", "action_id", - "dev_id", - "last_change_admin", "mgm_id", + "owner_id", + "recert_interval", "rule_from_zone", - "rule_num", "rule_to_zone", - "tenant_id", "track_id", "rule_num_numeric", - "parent_rule_type", + "matches", "rule_action", "rule_comment", - "rule_dst", - "rule_dst_refs", "rule_head_text", - "rule_src", - "rule_src_refs", - "rule_svc", - "rule_svc_refs", "rule_track", - "rule_uid" + "rule_uid", + "rule_last_certified" ], "filter": {}, "allow_aggregations": true @@ -15862,62 +27655,38 @@ "role": "recertifier", "permission": { "columns": [ - "parent_rule_id", - "rule_create", "rule_id", - "rule_last_seen", "xlate_rule", "access_rule", - "active", "nat_rule", "rule_disabled", "rule_dst_neg", - "rule_implied", "rule_src_neg", "rule_svc_neg", - "rule_installon", + "owner_name", "rule_name", - "rule_ruleid", - "rule_time", "action_id", - "dev_id", - "last_change_admin", "mgm_id", + "owner_id", + "recert_interval", "rule_from_zone", - "rule_num", "rule_to_zone", - "tenant_id", "track_id", "rule_num_numeric", - "parent_rule_type", + "matches", "rule_action", "rule_comment", - "rule_dst", - "rule_dst_refs", "rule_head_text", - "rule_src", - "rule_src_refs", - "rule_svc", - "rule_svc_refs", "rule_track", - "rule_uid" + "rule_uid", + "rule_last_certified" ], "filter": { "_and": [ - { - "tenant_id": { - "_eq": "x-hasura-tenant-id" - } - }, { "mgm_id": { "_in": "x-hasura-visible-managements" } - }, - { - "dev_id": { - "_in": "x-hasura-visible-devices" - } } ] }, @@ -15928,62 +27697,38 @@ "role": "reporter", "permission": { "columns": [ - "parent_rule_id", - "rule_create", "rule_id", - "rule_last_seen", "xlate_rule", "access_rule", - "active", "nat_rule", "rule_disabled", "rule_dst_neg", - "rule_implied", "rule_src_neg", "rule_svc_neg", - "rule_installon", + "owner_name", "rule_name", - "rule_ruleid", - "rule_time", "action_id", - "dev_id", - "last_change_admin", "mgm_id", + "owner_id", + "recert_interval", "rule_from_zone", - "rule_num", "rule_to_zone", - "tenant_id", "track_id", "rule_num_numeric", - "parent_rule_type", + "matches", "rule_action", "rule_comment", - "rule_dst", - "rule_dst_refs", "rule_head_text", - "rule_src", - "rule_src_refs", - "rule_svc", - "rule_svc_refs", "rule_track", - "rule_uid" + "rule_uid", + "rule_last_certified" ], "filter": { "_and": [ - { - "tenant_id": { - "_eq": "x-hasura-tenant-id" - } - }, { "mgm_id": { "_in": "x-hasura-visible-managements" } - }, - { - "dev_id": { - "_in": "x-hasura-visible-devices" - } } ] }, @@ -15994,45 +27739,31 @@ "role": "reporter-viewall", "permission": { "columns": [ - "parent_rule_id", - "rule_create", "rule_id", - "rule_last_seen", "xlate_rule", "access_rule", - "active", "nat_rule", "rule_disabled", "rule_dst_neg", - "rule_implied", "rule_src_neg", "rule_svc_neg", - "rule_installon", + "owner_name", "rule_name", - "rule_ruleid", - "rule_time", "action_id", - "dev_id", - "last_change_admin", "mgm_id", + "owner_id", + "recert_interval", "rule_from_zone", - "rule_num", "rule_to_zone", - "tenant_id", "track_id", "rule_num_numeric", - "parent_rule_type", + "matches", "rule_action", "rule_comment", - "rule_dst", - "rule_dst_refs", "rule_head_text", - "rule_src", - "rule_src_refs", - "rule_svc", - "rule_svc_refs", "rule_track", - "rule_uid" + "rule_uid", + "rule_last_certified" ], "filter": {}, "allow_aggregations": true @@ -16042,13 +27773,7 @@ }, { "table": { - "name": "view_undocumented_change_counter", - "schema": "public" - } - }, - { - "table": { - "name": "view_undocumented_changes", + "name": "view_svc_changes", "schema": "public" } }, @@ -16096,6 +27821,30 @@ } } }, + { + "name": "rule_from_zones", + "using": { + "foreign_key_constraint_on": { + "column": "zone_id", + "table": { + "name": "rule_from_zone", + "schema": "public" + } + } + } + }, + { + "name": "rule_to_zones", + "using": { + "foreign_key_constraint_on": { + "column": "zone_id", + "table": { + "name": "rule_to_zone", + "schema": "public" + } + } + } + }, { "name": "rules", "using": { @@ -16121,6 +27870,24 @@ } } ], + "insert_permissions": [ + { + "role": "importer", + "permission": { + "check": {}, + "columns": [ + "removed", + "zone_create", + "zone_last_seen", + "active", + "zone_name", + "mgm_id", + "zone_id" + ] + }, + "comment": "" + } + ], "select_permissions": [ { "role": "auditor", @@ -16129,6 +27896,7 @@ "zone_id", "zone_create", "zone_last_seen", + "removed", "mgm_id", "zone_name", "active" @@ -16141,6 +27909,23 @@ "role": "fw-admin", "permission": { "columns": [ + "zone_create", + "zone_last_seen", + "removed", + "active", + "zone_name", + "mgm_id", + "zone_id" + ], + "filter": {}, + "allow_aggregations": true + } + }, + { + "role": "importer", + "permission": { + "columns": [ + "removed", "zone_create", "zone_last_seen", "active", @@ -16150,6 +27935,43 @@ ], "filter": {}, "allow_aggregations": true + }, + "comment": "" + }, + { + "role": "middleware-server", + "permission": { + "columns": [ + "zone_create", + "zone_last_seen", + "removed", + "active", + "zone_name", + "mgm_id", + "zone_id" + ], + "filter": {} + }, + "comment": "" + }, + { + "role": "modeller", + "permission": { + "columns": [ + "zone_id", + "zone_create", + "zone_last_seen", + "removed", + "mgm_id", + "zone_name", + "active" + ], + "filter": { + "mgm_id": { + "_in": "x-hasura-visible-managements" + } + }, + "allow_aggregations": true } }, { @@ -16159,6 +27981,7 @@ "zone_id", "zone_create", "zone_last_seen", + "removed", "mgm_id", "zone_name", "active" @@ -16178,6 +28001,7 @@ "zone_id", "zone_create", "zone_last_seen", + "removed", "mgm_id", "zone_name", "active" @@ -16198,6 +28022,7 @@ "mgm_id", "zone_create", "zone_last_seen", + "removed", "zone_id", "zone_name" ], @@ -16205,6 +28030,30 @@ "allow_aggregations": true } } + ], + "update_permissions": [ + { + "role": "importer", + "permission": { + "columns": [ + "removed", + "zone_last_seen", + "active" + ], + "filter": {}, + "check": {} + }, + "comment": "" + } + ], + "delete_permissions": [ + { + "role": "importer", + "permission": { + "filter": {} + }, + "comment": "" + } ] }, { @@ -16295,6 +28144,42 @@ "filter": {} } }, + { + "role": "middleware-server", + "permission": { + "columns": [ + "action_type", + "button_text", + "event", + "external_parameters", + "name", + "phase", + "scope", + "task_type", + "id" + ], + "filter": {} + }, + "comment": "" + }, + { + "role": "modeller", + "permission": { + "columns": [ + "action_type", + "button_text", + "event", + "external_parameters", + "name", + "phase", + "scope", + "task_type", + "id" + ], + "filter": {} + }, + "comment": "" + }, { "role": "planner", "permission": { @@ -16312,6 +28197,42 @@ "filter": {} } }, + { + "role": "reporter", + "permission": { + "columns": [ + "action_type", + "button_text", + "event", + "external_parameters", + "name", + "phase", + "scope", + "task_type", + "id" + ], + "filter": {} + }, + "comment": "" + }, + { + "role": "reporter-viewall", + "permission": { + "columns": [ + "action_type", + "button_text", + "event", + "external_parameters", + "name", + "phase", + "scope", + "task_type", + "id" + ], + "filter": {} + }, + "comment": "" + }, { "role": "requester", "permission": { @@ -16442,6 +28363,28 @@ ] } }, + { + "role": "modeller", + "permission": { + "check": {}, + "columns": [ + "id", + "task_id", + "initial_approval", + "approver", + "approver_group", + "assigned_group", + "current_handler", + "recent_handler", + "state_id", + "tenant_id", + "approval_date", + "approval_deadline", + "date_opened" + ] + }, + "comment": "" + }, { "role": "planner", "permission": { @@ -16570,6 +28513,50 @@ "filter": {} } }, + { + "role": "middleware-server", + "permission": { + "columns": [ + "id", + "task_id", + "initial_approval", + "approver", + "approver_group", + "assigned_group", + "current_handler", + "recent_handler", + "state_id", + "tenant_id", + "approval_date", + "approval_deadline", + "date_opened" + ], + "filter": {} + }, + "comment": "" + }, + { + "role": "modeller", + "permission": { + "columns": [ + "id", + "task_id", + "initial_approval", + "approver", + "approver_group", + "assigned_group", + "current_handler", + "recent_handler", + "state_id", + "tenant_id", + "approval_date", + "approval_deadline", + "date_opened" + ], + "filter": {} + }, + "comment": "" + }, { "role": "planner", "permission": { @@ -16591,6 +28578,50 @@ "filter": {} } }, + { + "role": "reporter", + "permission": { + "columns": [ + "id", + "task_id", + "initial_approval", + "approver", + "approver_group", + "assigned_group", + "current_handler", + "recent_handler", + "state_id", + "tenant_id", + "approval_date", + "approval_deadline", + "date_opened" + ], + "filter": {} + }, + "comment": "" + }, + { + "role": "reporter-viewall", + "permission": { + "columns": [ + "id", + "task_id", + "initial_approval", + "approver", + "approver_group", + "assigned_group", + "current_handler", + "recent_handler", + "state_id", + "tenant_id", + "approval_date", + "approval_deadline", + "date_opened" + ], + "filter": {} + }, + "comment": "" + }, { "role": "requester", "permission": { @@ -16719,6 +28750,17 @@ ] } }, + { + "role": "modeller", + "permission": { + "check": {}, + "columns": [ + "approval_id", + "comment_id" + ] + }, + "comment": "" + }, { "role": "planner", "permission": { @@ -16791,6 +28833,28 @@ "filter": {} } }, + { + "role": "middleware-server", + "permission": { + "columns": [ + "approval_id", + "comment_id" + ], + "filter": {} + }, + "comment": "" + }, + { + "role": "modeller", + "permission": { + "columns": [ + "approval_id", + "comment_id" + ], + "filter": {} + }, + "comment": "" + }, { "role": "planner", "permission": { @@ -16801,6 +28865,28 @@ "filter": {} } }, + { + "role": "reporter", + "permission": { + "columns": [ + "approval_id", + "comment_id" + ], + "filter": {} + }, + "comment": "" + }, + { + "role": "reporter-viewall", + "permission": { + "columns": [ + "approval_id", + "comment_id" + ], + "filter": {} + }, + "comment": "" + }, { "role": "requester", "permission": { @@ -16902,11 +28988,39 @@ } } } - } - ], - "insert_permissions": [ + } + ], + "insert_permissions": [ + { + "role": "approver", + "permission": { + "check": {}, + "columns": [ + "id", + "ref_id", + "comment_text", + "scope", + "creator_id", + "creation_date" + ] + } + }, + { + "role": "fw-admin", + "permission": { + "check": {}, + "columns": [ + "id", + "ref_id", + "comment_text", + "scope", + "creator_id", + "creation_date" + ] + } + }, { - "role": "approver", + "role": "implementer", "permission": { "check": {}, "columns": [ @@ -16920,7 +29034,7 @@ } }, { - "role": "fw-admin", + "role": "middleware-server", "permission": { "check": {}, "columns": [ @@ -16931,10 +29045,11 @@ "creator_id", "creation_date" ] - } + }, + "comment": "" }, { - "role": "implementer", + "role": "modeller", "permission": { "check": {}, "columns": [ @@ -16945,7 +29060,8 @@ "creator_id", "creation_date" ] - } + }, + "comment": "" }, { "role": "planner", @@ -17047,6 +29163,36 @@ "filter": {} } }, + { + "role": "middleware-server", + "permission": { + "columns": [ + "id", + "ref_id", + "comment_text", + "scope", + "creator_id", + "creation_date" + ], + "filter": {} + }, + "comment": "" + }, + { + "role": "modeller", + "permission": { + "columns": [ + "id", + "ref_id", + "comment_text", + "scope", + "creator_id", + "creation_date" + ], + "filter": {} + }, + "comment": "" + }, { "role": "planner", "permission": { @@ -17061,6 +29207,36 @@ "filter": {} } }, + { + "role": "reporter", + "permission": { + "columns": [ + "id", + "ref_id", + "comment_text", + "scope", + "creator_id", + "creation_date" + ], + "filter": {} + }, + "comment": "" + }, + { + "role": "reporter-viewall", + "permission": { + "columns": [ + "id", + "ref_id", + "comment_text", + "scope", + "creator_id", + "creation_date" + ], + "filter": {} + }, + "comment": "" + }, { "role": "requester", "permission": { @@ -17091,6 +29267,118 @@ } ] }, + { + "table": { + "name": "ext_state", + "schema": "request" + }, + "object_relationships": [ + { + "name": "state", + "using": { + "foreign_key_constraint_on": "state_id" + } + } + ], + "select_permissions": [ + { + "role": "approver", + "permission": { + "columns": [ + "name", + "id", + "state_id" + ], + "filter": {} + }, + "comment": "" + }, + { + "role": "auditor", + "permission": { + "columns": [ + "name", + "id", + "state_id" + ], + "filter": {} + }, + "comment": "" + }, + { + "role": "implementer", + "permission": { + "columns": [ + "name", + "id", + "state_id" + ], + "filter": {} + }, + "comment": "" + }, + { + "role": "middleware-server", + "permission": { + "columns": [ + "name", + "id", + "state_id" + ], + "filter": {} + }, + "comment": "" + }, + { + "role": "modeller", + "permission": { + "columns": [ + "name", + "id", + "state_id" + ], + "filter": {} + }, + "comment": "" + }, + { + "role": "planner", + "permission": { + "columns": [ + "name", + "id", + "state_id" + ], + "filter": {} + }, + "comment": "" + }, + { + "role": "requester", + "permission": { + "columns": [ + "name", + "id", + "state_id" + ], + "filter": {} + }, + "comment": "" + }, + { + "role": "reviewer", + "permission": { + "columns": [ + "name", + "id", + "state_id" + ], + "filter": {} + }, + "comment": "" + } + ] + }, { "table": { "name": "implelement", @@ -17146,11 +29434,133 @@ } } } - } - ], - "insert_permissions": [ + } + ], + "insert_permissions": [ + { + "role": "approver", + "permission": { + "check": {}, + "columns": [ + "field", + "group_name", + "id", + "implementation_action", + "implementation_task_id", + "ip", + "ip_end", + "ip_proto_id", + "name", + "network_object_id", + "original_nat_id", + "port", + "port_end", + "rule_uid", + "service_id", + "user_id" + ] + } + }, + { + "role": "fw-admin", + "permission": { + "check": {}, + "columns": [ + "field", + "group_name", + "id", + "implementation_action", + "implementation_task_id", + "ip", + "ip_end", + "ip_proto_id", + "name", + "network_object_id", + "original_nat_id", + "port", + "port_end", + "rule_uid", + "service_id", + "user_id" + ] + } + }, + { + "role": "middleware-server", + "permission": { + "check": {}, + "columns": [ + "id", + "implementation_task_id", + "network_object_id", + "original_nat_id", + "service_id", + "user_id", + "group_name", + "name", + "rule_uid", + "ip", + "ip_end", + "ip_proto_id", + "port", + "port_end", + "field", + "implementation_action" + ] + }, + "comment": "" + }, + { + "role": "modeller", + "permission": { + "check": {}, + "columns": [ + "id", + "implementation_task_id", + "network_object_id", + "original_nat_id", + "service_id", + "user_id", + "group_name", + "name", + "rule_uid", + "ip", + "ip_end", + "ip_proto_id", + "port", + "port_end", + "field", + "implementation_action" + ] + }, + "comment": "" + }, + { + "role": "planner", + "permission": { + "check": {}, + "columns": [ + "id", + "implementation_task_id", + "network_object_id", + "original_nat_id", + "service_id", + "user_id", + "group_name", + "name", + "rule_uid", + "ip", + "ip_end", + "ip_proto_id", + "port", + "port_end", + "field", + "implementation_action" + ] + } + }, { - "role": "approver", + "role": "requester", "permission": { "check": {}, "columns": [ @@ -17160,19 +29570,24 @@ "original_nat_id", "service_id", "user_id", + "group_name", + "name", "rule_uid", "ip", + "ip_end", "ip_proto_id", "port", + "port_end", "field", "implementation_action" ] } - }, + } + ], + "select_permissions": [ { - "role": "fw-admin", + "role": "approver", "permission": { - "check": {}, "columns": [ "id", "implementation_task_id", @@ -17180,19 +29595,23 @@ "original_nat_id", "service_id", "user_id", + "group_name", + "name", "rule_uid", "ip", + "ip_end", "ip_proto_id", "port", + "port_end", "field", "implementation_action" - ] + ], + "filter": {} } }, { - "role": "planner", + "role": "auditor", "permission": { - "check": {}, "columns": [ "id", "implementation_task_id", @@ -17200,19 +29619,47 @@ "original_nat_id", "service_id", "user_id", + "group_name", + "name", "rule_uid", "ip", + "ip_end", "ip_proto_id", "port", + "port_end", "field", "implementation_action" - ] + ], + "filter": {} } }, { - "role": "requester", + "role": "fw-admin", + "permission": { + "columns": [ + "field", + "group_name", + "id", + "implementation_action", + "implementation_task_id", + "ip", + "ip_end", + "ip_proto_id", + "name", + "network_object_id", + "original_nat_id", + "port", + "port_end", + "rule_uid", + "service_id", + "user_id" + ], + "filter": {} + } + }, + { + "role": "implementer", "permission": { - "check": {}, "columns": [ "id", "implementation_task_id", @@ -17220,19 +29667,22 @@ "original_nat_id", "service_id", "user_id", + "group_name", + "name", "rule_uid", "ip", + "ip_end", "ip_proto_id", "port", + "port_end", "field", "implementation_action" - ] + ], + "filter": {} } - } - ], - "select_permissions": [ + }, { - "role": "approver", + "role": "middleware-server", "permission": { "columns": [ "id", @@ -17241,18 +29691,23 @@ "original_nat_id", "service_id", "user_id", + "group_name", + "name", "rule_uid", "ip", + "ip_end", "ip_proto_id", "port", + "port_end", "field", "implementation_action" ], "filter": {} - } + }, + "comment": "" }, { - "role": "auditor", + "role": "modeller", "permission": { "columns": [ "id", @@ -17261,18 +29716,23 @@ "original_nat_id", "service_id", "user_id", + "group_name", + "name", "rule_uid", "ip", + "ip_end", "ip_proto_id", "port", + "port_end", "field", "implementation_action" ], "filter": {} - } + }, + "comment": "" }, { - "role": "fw-admin", + "role": "planner", "permission": { "columns": [ "id", @@ -17281,10 +29741,14 @@ "original_nat_id", "service_id", "user_id", + "group_name", + "name", "rule_uid", "ip", + "ip_end", "ip_proto_id", "port", + "port_end", "field", "implementation_action" ], @@ -17292,7 +29756,7 @@ } }, { - "role": "implementer", + "role": "reporter", "permission": { "columns": [ "id", @@ -17301,18 +29765,23 @@ "original_nat_id", "service_id", "user_id", + "group_name", + "name", "rule_uid", "ip", + "ip_end", "ip_proto_id", "port", + "port_end", "field", "implementation_action" ], "filter": {} - } + }, + "comment": "" }, { - "role": "planner", + "role": "reporter-viewall", "permission": { "columns": [ "id", @@ -17321,15 +29790,20 @@ "original_nat_id", "service_id", "user_id", + "group_name", + "name", "rule_uid", "ip", + "ip_end", "ip_proto_id", "port", + "port_end", "field", "implementation_action" ], "filter": {} - } + }, + "comment": "" }, { "role": "requester", @@ -17341,10 +29815,14 @@ "original_nat_id", "service_id", "user_id", + "group_name", + "name", "rule_uid", "ip", + "ip_end", "ip_proto_id", "port", + "port_end", "field", "implementation_action" ], @@ -17361,10 +29839,14 @@ "original_nat_id", "service_id", "user_id", + "group_name", + "name", "rule_uid", "ip", + "ip_end", "ip_proto_id", "port", + "port_end", "field", "implementation_action" ], @@ -17377,18 +29859,22 @@ "role": "fw-admin", "permission": { "columns": [ + "field", + "group_name", "id", + "implementation_action", "implementation_task_id", - "network_object_id", - "original_nat_id", - "service_id", - "user_id", - "rule_uid", "ip", + "ip_end", "ip_proto_id", + "name", + "network_object_id", + "original_nat_id", "port", - "field", - "implementation_action" + "port_end", + "rule_uid", + "service_id", + "user_id" ], "filter": {}, "check": null @@ -17404,10 +29890,14 @@ "original_nat_id", "service_id", "user_id", + "group_name", + "name", "rule_uid", "ip", + "ip_end", "ip_proto_id", "port", + "port_end", "field", "implementation_action" ], @@ -17512,11 +30002,188 @@ } } ], - "insert_permissions": [ + "insert_permissions": [ + { + "role": "approver", + "permission": { + "check": {}, + "columns": [ + "id", + "reqtask_id", + "assigned_group", + "task_type", + "title", + "current_handler", + "device_id", + "nw_obj_grp_id", + "recent_handler", + "rule_action", + "rule_tracking", + "state_id", + "svc_grp_id", + "task_number", + "user_grp_id", + "free_text", + "start", + "stop", + "target_begin_date", + "target_end_date", + "implementation_action" + ] + } + }, + { + "role": "fw-admin", + "permission": { + "check": {}, + "columns": [ + "id", + "reqtask_id", + "assigned_group", + "task_type", + "title", + "current_handler", + "device_id", + "nw_obj_grp_id", + "recent_handler", + "rule_action", + "rule_tracking", + "state_id", + "svc_grp_id", + "task_number", + "user_grp_id", + "free_text", + "start", + "stop", + "target_begin_date", + "target_end_date", + "implementation_action" + ] + } + }, + { + "role": "middleware-server", + "permission": { + "check": {}, + "columns": [ + "id", + "reqtask_id", + "assigned_group", + "task_type", + "title", + "current_handler", + "device_id", + "nw_obj_grp_id", + "recent_handler", + "rule_action", + "rule_tracking", + "state_id", + "svc_grp_id", + "task_number", + "user_grp_id", + "free_text", + "start", + "stop", + "target_begin_date", + "target_end_date", + "implementation_action" + ] + }, + "comment": "" + }, + { + "role": "modeller", + "permission": { + "check": {}, + "columns": [ + "id", + "reqtask_id", + "assigned_group", + "task_type", + "title", + "current_handler", + "device_id", + "nw_obj_grp_id", + "recent_handler", + "rule_action", + "rule_tracking", + "state_id", + "svc_grp_id", + "task_number", + "user_grp_id", + "free_text", + "start", + "stop", + "target_begin_date", + "target_end_date", + "implementation_action" + ] + }, + "comment": "" + }, + { + "role": "planner", + "permission": { + "check": {}, + "columns": [ + "id", + "reqtask_id", + "assigned_group", + "task_type", + "title", + "current_handler", + "device_id", + "nw_obj_grp_id", + "recent_handler", + "rule_action", + "rule_tracking", + "state_id", + "svc_grp_id", + "task_number", + "user_grp_id", + "free_text", + "start", + "stop", + "target_begin_date", + "target_end_date", + "implementation_action" + ] + } + }, + { + "role": "requester", + "permission": { + "check": {}, + "columns": [ + "id", + "reqtask_id", + "assigned_group", + "task_type", + "title", + "current_handler", + "device_id", + "nw_obj_grp_id", + "recent_handler", + "rule_action", + "rule_tracking", + "state_id", + "svc_grp_id", + "task_number", + "user_grp_id", + "free_text", + "start", + "stop", + "target_begin_date", + "target_end_date", + "implementation_action" + ] + } + } + ], + "select_permissions": [ { "role": "approver", "permission": { - "check": {}, "columns": [ "id", "reqtask_id", @@ -17539,13 +30206,13 @@ "target_begin_date", "target_end_date", "implementation_action" - ] + ], + "filter": {} } }, { - "role": "fw-admin", + "role": "auditor", "permission": { - "check": {}, "columns": [ "id", "reqtask_id", @@ -17568,13 +30235,13 @@ "target_begin_date", "target_end_date", "implementation_action" - ] + ], + "filter": {} } }, { - "role": "planner", + "role": "fw-admin", "permission": { - "check": {}, "columns": [ "id", "reqtask_id", @@ -17597,13 +30264,13 @@ "target_begin_date", "target_end_date", "implementation_action" - ] + ], + "filter": {} } }, { - "role": "requester", + "role": "implementer", "permission": { - "check": {}, "columns": [ "id", "reqtask_id", @@ -17626,13 +30293,12 @@ "target_begin_date", "target_end_date", "implementation_action" - ] + ], + "filter": {} } - } - ], - "select_permissions": [ + }, { - "role": "approver", + "role": "middleware-server", "permission": { "columns": [ "id", @@ -17658,10 +30324,11 @@ "implementation_action" ], "filter": {} - } + }, + "comment": "" }, { - "role": "auditor", + "role": "modeller", "permission": { "columns": [ "id", @@ -17687,10 +30354,11 @@ "implementation_action" ], "filter": {} - } + }, + "comment": "" }, { - "role": "fw-admin", + "role": "planner", "permission": { "columns": [ "id", @@ -17719,7 +30387,7 @@ } }, { - "role": "implementer", + "role": "reporter", "permission": { "columns": [ "id", @@ -17745,10 +30413,11 @@ "implementation_action" ], "filter": {} - } + }, + "comment": "" }, { - "role": "planner", + "role": "reporter-viewall", "permission": { "columns": [ "id", @@ -17774,7 +30443,8 @@ "implementation_action" ], "filter": {} - } + }, + "comment": "" }, { "role": "requester", @@ -17896,6 +30566,36 @@ "check": null } }, + { + "role": "middleware-server", + "permission": { + "columns": [ + "assigned_group", + "current_handler", + "recent_handler", + "start", + "state_id", + "stop" + ], + "filter": {}, + "check": null + } + }, + { + "role": "modeller", + "permission": { + "columns": [ + "assigned_group", + "current_handler", + "recent_handler", + "start", + "state_id", + "stop" + ], + "filter": {}, + "check": null + } + }, { "role": "planner", "permission": { @@ -18001,6 +30701,28 @@ ] } }, + { + "role": "middleware-server", + "permission": { + "check": {}, + "columns": [ + "comment_id", + "task_id" + ] + }, + "comment": "" + }, + { + "role": "modeller", + "permission": { + "check": {}, + "columns": [ + "comment_id", + "task_id" + ] + }, + "comment": "" + }, { "role": "planner", "permission": { @@ -18073,6 +30795,28 @@ "filter": {} } }, + { + "role": "middleware-server", + "permission": { + "columns": [ + "comment_id", + "task_id" + ], + "filter": {} + }, + "comment": "" + }, + { + "role": "modeller", + "permission": { + "columns": [ + "comment_id", + "task_id" + ], + "filter": {} + }, + "comment": "" + }, { "role": "planner", "permission": { @@ -18083,6 +30827,28 @@ "filter": {} } }, + { + "role": "reporter", + "permission": { + "columns": [ + "comment_id", + "task_id" + ], + "filter": {} + }, + "comment": "" + }, + { + "role": "reporter-viewall", + "permission": { + "columns": [ + "comment_id", + "task_id" + ], + "filter": {} + }, + "comment": "" + }, { "role": "requester", "permission": { @@ -18152,27 +30918,180 @@ "using": { "foreign_key_constraint_on": "user_id" } - } - ], - "array_relationships": [ + } + ], + "array_relationships": [ + { + "name": "elements", + "using": { + "foreign_key_constraint_on": { + "column": "original_nat_id", + "table": { + "name": "reqelement", + "schema": "request" + } + } + } + } + ], + "insert_permissions": [ + { + "role": "approver", + "permission": { + "check": {}, + "columns": [ + "id", + "network_object_id", + "original_nat_id", + "service_id", + "task_id", + "user_id", + "group_name", + "name", + "rule_uid", + "ip", + "ip_end", + "device_id", + "ip_proto_id", + "port", + "port_end", + "field", + "request_action" + ] + }, + "comment": "" + }, + { + "role": "modeller", + "permission": { + "check": {}, + "columns": [ + "id", + "network_object_id", + "original_nat_id", + "service_id", + "task_id", + "user_id", + "group_name", + "name", + "rule_uid", + "ip", + "ip_end", + "device_id", + "ip_proto_id", + "port", + "port_end", + "field", + "request_action" + ] + }, + "comment": "" + }, + { + "role": "requester", + "permission": { + "check": {}, + "columns": [ + "id", + "network_object_id", + "original_nat_id", + "service_id", + "task_id", + "user_id", + "group_name", + "name", + "rule_uid", + "ip", + "ip_end", + "device_id", + "ip_proto_id", + "port", + "port_end", + "field", + "request_action" + ] + } + } + ], + "select_permissions": [ + { + "role": "approver", + "permission": { + "columns": [ + "id", + "network_object_id", + "original_nat_id", + "service_id", + "task_id", + "user_id", + "group_name", + "name", + "rule_uid", + "ip", + "ip_end", + "device_id", + "ip_proto_id", + "port", + "port_end", + "field", + "request_action" + ], + "filter": {} + } + }, + { + "role": "auditor", + "permission": { + "columns": [ + "id", + "network_object_id", + "original_nat_id", + "service_id", + "task_id", + "user_id", + "group_name", + "name", + "rule_uid", + "ip", + "ip_end", + "device_id", + "ip_proto_id", + "port", + "port_end", + "field", + "request_action" + ], + "filter": {} + } + }, { - "name": "elements", - "using": { - "foreign_key_constraint_on": { - "column": "original_nat_id", - "table": { - "name": "reqelement", - "schema": "request" - } - } + "role": "fw-admin", + "permission": { + "columns": [ + "id", + "network_object_id", + "original_nat_id", + "service_id", + "task_id", + "user_id", + "group_name", + "name", + "rule_uid", + "ip", + "ip_end", + "device_id", + "ip_proto_id", + "port", + "port_end", + "field", + "request_action" + ], + "filter": {} } - } - ], - "insert_permissions": [ + }, { - "role": "requester", + "role": "implementer", "permission": { - "check": {}, "columns": [ "id", "network_object_id", @@ -18180,20 +31099,23 @@ "service_id", "task_id", "user_id", + "group_name", + "name", "rule_uid", "ip", + "ip_end", "device_id", "ip_proto_id", "port", + "port_end", "field", "request_action" - ] + ], + "filter": {} } - } - ], - "select_permissions": [ + }, { - "role": "approver", + "role": "middleware-server", "permission": { "columns": [ "id", @@ -18202,19 +31124,24 @@ "service_id", "task_id", "user_id", + "group_name", + "name", "rule_uid", "ip", + "ip_end", "device_id", "ip_proto_id", "port", + "port_end", "field", "request_action" ], "filter": {} - } + }, + "comment": "" }, { - "role": "auditor", + "role": "modeller", "permission": { "columns": [ "id", @@ -18223,19 +31150,24 @@ "service_id", "task_id", "user_id", + "group_name", + "name", "rule_uid", "ip", + "ip_end", "device_id", "ip_proto_id", "port", + "port_end", "field", "request_action" ], "filter": {} - } + }, + "comment": "" }, { - "role": "fw-admin", + "role": "planner", "permission": { "columns": [ "id", @@ -18244,11 +31176,15 @@ "service_id", "task_id", "user_id", + "group_name", + "name", "rule_uid", "ip", + "ip_end", "device_id", "ip_proto_id", "port", + "port_end", "field", "request_action" ], @@ -18256,7 +31192,7 @@ } }, { - "role": "implementer", + "role": "reporter", "permission": { "columns": [ "id", @@ -18265,19 +31201,24 @@ "service_id", "task_id", "user_id", + "group_name", + "name", "rule_uid", "ip", + "ip_end", "device_id", "ip_proto_id", "port", + "port_end", "field", "request_action" ], "filter": {} - } + }, + "comment": "" }, { - "role": "planner", + "role": "reporter-viewall", "permission": { "columns": [ "id", @@ -18286,16 +31227,21 @@ "service_id", "task_id", "user_id", + "group_name", + "name", "rule_uid", "ip", + "ip_end", "device_id", "ip_proto_id", "port", + "port_end", "field", "request_action" ], "filter": {} - } + }, + "comment": "" }, { "role": "requester", @@ -18307,11 +31253,15 @@ "service_id", "task_id", "user_id", + "group_name", + "name", "rule_uid", "ip", + "ip_end", "device_id", "ip_proto_id", "port", + "port_end", "field", "request_action" ], @@ -18328,11 +31278,15 @@ "service_id", "task_id", "user_id", + "group_name", + "name", "rule_uid", "ip", + "ip_end", "device_id", "ip_proto_id", "port", + "port_end", "field", "request_action" ], @@ -18341,6 +31295,32 @@ } ], "update_permissions": [ + { + "role": "approver", + "permission": { + "columns": [ + "id", + "network_object_id", + "original_nat_id", + "service_id", + "task_id", + "user_id", + "group_name", + "name", + "rule_uid", + "ip", + "ip_end", + "device_id", + "ip_proto_id", + "port", + "port_end", + "field", + "request_action" + ], + "filter": {}, + "check": null + } + }, { "role": "requester", "permission": { @@ -18351,11 +31331,15 @@ "service_id", "task_id", "user_id", + "group_name", + "name", "rule_uid", "ip", + "ip_end", "device_id", "ip_proto_id", "port", + "port_end", "field", "request_action" ], @@ -18365,6 +31349,13 @@ } ], "delete_permissions": [ + { + "role": "approver", + "permission": { + "filter": {} + }, + "comment": "" + }, { "role": "fw-admin", "permission": { @@ -18385,6 +31376,12 @@ "schema": "request" }, "object_relationships": [ + { + "name": "management", + "using": { + "foreign_key_constraint_on": "mgm_id" + } + }, { "name": "object", "using": { @@ -18478,43 +31475,212 @@ } }, { - "name": "reqtask_comments", - "using": { - "foreign_key_constraint_on": { - "column": "task_id", - "table": { - "name": "reqtask_comment", - "schema": "request" - } - } + "name": "reqtask_comments", + "using": { + "foreign_key_constraint_on": { + "column": "task_id", + "table": { + "name": "reqtask_comment", + "schema": "request" + } + } + } + }, + { + "name": "reqtask_owners", + "using": { + "foreign_key_constraint_on": { + "column": "reqtask_id", + "table": { + "name": "reqtask_owner", + "schema": "public" + } + } + } + } + ], + "insert_permissions": [ + { + "role": "modeller", + "permission": { + "check": {}, + "columns": [ + "id", + "ticket_id", + "additional_info", + "assigned_group", + "devices", + "task_type", + "title", + "current_handler", + "mgm_id", + "nw_obj_grp_id", + "recent_handler", + "rule_action", + "rule_tracking", + "state_id", + "svc_grp_id", + "task_number", + "user_grp_id", + "free_text", + "reason", + "last_recert_date", + "start", + "stop", + "target_begin_date", + "target_end_date", + "request_action" + ] + }, + "comment": "" + }, + { + "role": "requester", + "permission": { + "check": {}, + "columns": [ + "id", + "ticket_id", + "additional_info", + "assigned_group", + "devices", + "task_type", + "title", + "current_handler", + "mgm_id", + "nw_obj_grp_id", + "recent_handler", + "rule_action", + "rule_tracking", + "state_id", + "svc_grp_id", + "task_number", + "user_grp_id", + "free_text", + "reason", + "last_recert_date", + "start", + "stop", + "target_begin_date", + "target_end_date", + "request_action" + ] + } + } + ], + "select_permissions": [ + { + "role": "approver", + "permission": { + "columns": [ + "id", + "ticket_id", + "additional_info", + "assigned_group", + "devices", + "task_type", + "title", + "current_handler", + "mgm_id", + "nw_obj_grp_id", + "recent_handler", + "rule_action", + "rule_tracking", + "state_id", + "svc_grp_id", + "task_number", + "user_grp_id", + "free_text", + "reason", + "last_recert_date", + "start", + "stop", + "target_begin_date", + "target_end_date", + "request_action" + ], + "filter": {} + } + }, + { + "role": "auditor", + "permission": { + "columns": [ + "id", + "ticket_id", + "additional_info", + "assigned_group", + "devices", + "task_type", + "title", + "current_handler", + "mgm_id", + "nw_obj_grp_id", + "recent_handler", + "rule_action", + "rule_tracking", + "state_id", + "svc_grp_id", + "task_number", + "user_grp_id", + "free_text", + "reason", + "last_recert_date", + "start", + "stop", + "target_begin_date", + "target_end_date", + "request_action" + ], + "filter": {} + } + }, + { + "role": "fw-admin", + "permission": { + "columns": [ + "id", + "ticket_id", + "additional_info", + "assigned_group", + "devices", + "task_type", + "title", + "current_handler", + "mgm_id", + "nw_obj_grp_id", + "recent_handler", + "rule_action", + "rule_tracking", + "state_id", + "svc_grp_id", + "task_number", + "user_grp_id", + "free_text", + "reason", + "last_recert_date", + "start", + "stop", + "target_begin_date", + "target_end_date", + "request_action" + ], + "filter": {} } }, { - "name": "reqtask_owners", - "using": { - "foreign_key_constraint_on": { - "column": "reqtask_id", - "table": { - "name": "reqtask_owner", - "schema": "public" - } - } - } - } - ], - "insert_permissions": [ - { - "role": "requester", + "role": "implementer", "permission": { - "check": {}, "columns": [ "id", "ticket_id", + "additional_info", "assigned_group", + "devices", "task_type", "title", "current_handler", - "devices", + "mgm_id", "nw_obj_grp_id", "recent_handler", "rule_action", @@ -18531,22 +31697,23 @@ "target_begin_date", "target_end_date", "request_action" - ] + ], + "filter": {} } - } - ], - "select_permissions": [ + }, { - "role": "approver", + "role": "middleware-server", "permission": { "columns": [ "id", "ticket_id", + "additional_info", "assigned_group", + "devices", "task_type", "title", "current_handler", - "devices", + "mgm_id", "nw_obj_grp_id", "recent_handler", "rule_action", @@ -18565,19 +31732,22 @@ "request_action" ], "filter": {} - } + }, + "comment": "" }, { - "role": "auditor", + "role": "modeller", "permission": { "columns": [ "id", "ticket_id", + "additional_info", "assigned_group", "devices", "task_type", "title", "current_handler", + "mgm_id", "nw_obj_grp_id", "recent_handler", "rule_action", @@ -18596,19 +31766,22 @@ "request_action" ], "filter": {} - } + }, + "comment": "" }, { - "role": "fw-admin", + "role": "planner", "permission": { "columns": [ "id", "ticket_id", + "additional_info", "assigned_group", + "devices", "task_type", "title", "current_handler", - "devices", + "mgm_id", "nw_obj_grp_id", "recent_handler", "rule_action", @@ -18630,16 +31803,18 @@ } }, { - "role": "implementer", + "role": "reporter", "permission": { "columns": [ "id", "ticket_id", + "additional_info", "assigned_group", + "devices", "task_type", "title", "current_handler", - "devices", + "mgm_id", "nw_obj_grp_id", "recent_handler", "rule_action", @@ -18658,19 +31833,22 @@ "request_action" ], "filter": {} - } + }, + "comment": "" }, { - "role": "planner", + "role": "reporter-viewall", "permission": { "columns": [ "id", "ticket_id", + "additional_info", "assigned_group", + "devices", "task_type", "title", "current_handler", - "devices", + "mgm_id", "nw_obj_grp_id", "recent_handler", "rule_action", @@ -18689,7 +31867,8 @@ "request_action" ], "filter": {} - } + }, + "comment": "" }, { "role": "requester", @@ -18697,11 +31876,13 @@ "columns": [ "id", "ticket_id", + "additional_info", "assigned_group", + "devices", "task_type", "title", "current_handler", - "devices", + "mgm_id", "nw_obj_grp_id", "recent_handler", "rule_action", @@ -18728,11 +31909,13 @@ "columns": [ "id", "ticket_id", + "additional_info", "assigned_group", + "devices", "task_type", "title", "current_handler", - "devices", + "mgm_id", "nw_obj_grp_id", "recent_handler", "rule_action", @@ -18759,12 +31942,23 @@ "role": "approver", "permission": { "columns": [ + "additional_info", "assigned_group", "current_handler", + "devices", + "free_text", + "mgm_id", + "reason", "recent_handler", + "request_action", + "rule_action", + "rule_tracking", "start", "state_id", - "stop" + "stop", + "target_begin_date", + "target_end_date", + "title" ], "filter": {}, "check": null @@ -18774,6 +31968,7 @@ "role": "fw-admin", "permission": { "columns": [ + "additional_info", "assigned_group", "current_handler", "recent_handler", @@ -18789,6 +31984,40 @@ "role": "implementer", "permission": { "columns": [ + "additional_info", + "assigned_group", + "current_handler", + "recent_handler", + "start", + "state_id", + "stop" + ], + "filter": {}, + "check": null + } + }, + { + "role": "middleware-server", + "permission": { + "columns": [ + "additional_info", + "assigned_group", + "current_handler", + "recent_handler", + "start", + "state_id", + "stop" + ], + "filter": {}, + "check": null + }, + "comment": "" + }, + { + "role": "modeller", + "permission": { + "columns": [ + "additional_info", "assigned_group", "current_handler", "recent_handler", @@ -18804,6 +32033,7 @@ "role": "planner", "permission": { "columns": [ + "additional_info", "assigned_group", "current_handler", "recent_handler", @@ -18821,11 +32051,13 @@ "columns": [ "id", "ticket_id", + "additional_info", "assigned_group", + "devices", "task_type", "title", "current_handler", - "devices", + "mgm_id", "nw_obj_grp_id", "recent_handler", "rule_action", @@ -18851,6 +32083,7 @@ "role": "reviewer", "permission": { "columns": [ + "additional_info", "assigned_group", "current_handler", "recent_handler", @@ -18928,6 +32161,28 @@ ] } }, + { + "role": "middleware-server", + "permission": { + "check": {}, + "columns": [ + "comment_id", + "task_id" + ] + }, + "comment": "" + }, + { + "role": "modeller", + "permission": { + "check": {}, + "columns": [ + "comment_id", + "task_id" + ] + }, + "comment": "" + }, { "role": "planner", "permission": { @@ -19000,6 +32255,28 @@ "filter": {} } }, + { + "role": "middleware-server", + "permission": { + "columns": [ + "comment_id", + "task_id" + ], + "filter": {} + }, + "comment": "" + }, + { + "role": "modeller", + "permission": { + "columns": [ + "comment_id", + "task_id" + ], + "filter": {} + }, + "comment": "" + }, { "role": "planner", "permission": { @@ -19010,6 +32287,28 @@ "filter": {} } }, + { + "role": "reporter", + "permission": { + "columns": [ + "comment_id", + "task_id" + ], + "filter": {} + }, + "comment": "" + }, + { + "role": "reporter-viewall", + "permission": { + "columns": [ + "comment_id", + "task_id" + ], + "filter": {} + }, + "comment": "" + }, { "role": "requester", "permission": { @@ -19050,6 +32349,18 @@ } } }, + { + "name": "ext_states", + "using": { + "foreign_key_constraint_on": { + "column": "state_id", + "table": { + "name": "ext_state", + "schema": "request" + } + } + } + }, { "name": "impltasks", "using": { @@ -19104,6 +32415,7 @@ "role": "approver", "permission": { "columns": [ + "automatic_only", "name", "id" ], @@ -19114,6 +32426,7 @@ "role": "auditor", "permission": { "columns": [ + "automatic_only", "name", "id" ], @@ -19124,6 +32437,7 @@ "role": "fw-admin", "permission": { "columns": [ + "automatic_only", "name", "id" ], @@ -19134,26 +32448,77 @@ "role": "implementer", "permission": { "columns": [ + "automatic_only", "name", "id" ], "filter": {} } }, + { + "role": "middleware-server", + "permission": { + "columns": [ + "automatic_only", + "name", + "id" + ], + "filter": {} + }, + "comment": "" + }, + { + "role": "modeller", + "permission": { + "columns": [ + "automatic_only", + "name", + "id" + ], + "filter": {} + }, + "comment": "" + }, { "role": "planner", "permission": { "columns": [ + "automatic_only", "name", "id" ], "filter": {} } }, + { + "role": "reporter", + "permission": { + "columns": [ + "automatic_only", + "name", + "id" + ], + "filter": {} + }, + "comment": "" + }, + { + "role": "reporter-viewall", + "permission": { + "columns": [ + "automatic_only", + "name", + "id" + ], + "filter": {} + }, + "comment": "" + }, { "role": "requester", "permission": { "columns": [ + "automatic_only", "name", "id" ], @@ -19164,6 +32529,7 @@ "role": "reviewer", "permission": { "columns": [ + "automatic_only", "name", "id" ], @@ -19189,11 +32555,31 @@ "using": { "foreign_key_constraint_on": "state_id" } - } - ], - "select_permissions": [ + } + ], + "select_permissions": [ + { + "role": "approver", + "permission": { + "columns": [ + "action_id", + "state_id" + ], + "filter": {} + } + }, + { + "role": "auditor", + "permission": { + "columns": [ + "action_id", + "state_id" + ], + "filter": {} + } + }, { - "role": "approver", + "role": "fw-admin", "permission": { "columns": [ "action_id", @@ -19203,7 +32589,7 @@ } }, { - "role": "auditor", + "role": "implementer", "permission": { "columns": [ "action_id", @@ -19213,24 +32599,26 @@ } }, { - "role": "fw-admin", + "role": "middleware-server", "permission": { "columns": [ "action_id", "state_id" ], "filter": {} - } + }, + "comment": "" }, { - "role": "implementer", + "role": "modeller", "permission": { "columns": [ "action_id", "state_id" ], "filter": {} - } + }, + "comment": "" }, { "role": "planner", @@ -19242,6 +32630,28 @@ "filter": {} } }, + { + "role": "reporter", + "permission": { + "columns": [ + "action_id", + "state_id" + ], + "filter": {} + }, + "comment": "" + }, + { + "role": "reporter-viewall", + "permission": { + "columns": [ + "action_id", + "state_id" + ], + "filter": {} + }, + "comment": "" + }, { "role": "requester", "permission": { @@ -19302,6 +32712,30 @@ } ], "array_relationships": [ + { + "name": "ext_requests", + "using": { + "foreign_key_constraint_on": { + "column": "ticket_id", + "table": { + "name": "ext_request", + "schema": "public" + } + } + } + }, + { + "name": "owner_tickets", + "using": { + "foreign_key_constraint_on": { + "column": "ticket_id", + "table": { + "name": "owner_ticket", + "schema": "public" + } + } + } + }, { "name": "reqtasks", "using": { @@ -19328,6 +32762,32 @@ } ], "insert_permissions": [ + { + "role": "modeller", + "permission": { + "check": {}, + "columns": [ + "id", + "assigned_group", + "external_ticket_id", + "requester_dn", + "requester_group", + "title", + "current_handler", + "external_ticket_source", + "recent_handler", + "requester_id", + "state_id", + "tenant_id", + "ticket_priority", + "reason", + "date_completed", + "date_created", + "ticket_deadline" + ] + }, + "comment": "" + }, { "role": "requester", "permission": { @@ -19455,6 +32915,58 @@ "filter": {} } }, + { + "role": "middleware-server", + "permission": { + "columns": [ + "id", + "assigned_group", + "external_ticket_id", + "requester_dn", + "requester_group", + "title", + "current_handler", + "external_ticket_source", + "recent_handler", + "requester_id", + "state_id", + "tenant_id", + "ticket_priority", + "reason", + "date_completed", + "date_created", + "ticket_deadline" + ], + "filter": {} + }, + "comment": "" + }, + { + "role": "modeller", + "permission": { + "columns": [ + "id", + "assigned_group", + "external_ticket_id", + "requester_dn", + "requester_group", + "title", + "current_handler", + "external_ticket_source", + "recent_handler", + "requester_id", + "state_id", + "tenant_id", + "ticket_priority", + "reason", + "date_completed", + "date_created", + "ticket_deadline" + ], + "filter": {} + }, + "comment": "" + }, { "role": "planner", "permission": { @@ -19480,6 +32992,58 @@ "filter": {} } }, + { + "role": "reporter", + "permission": { + "columns": [ + "id", + "assigned_group", + "external_ticket_id", + "requester_dn", + "requester_group", + "title", + "current_handler", + "external_ticket_source", + "recent_handler", + "requester_id", + "state_id", + "tenant_id", + "ticket_priority", + "reason", + "date_completed", + "date_created", + "ticket_deadline" + ], + "filter": {} + }, + "comment": "" + }, + { + "role": "reporter-viewall", + "permission": { + "columns": [ + "id", + "assigned_group", + "external_ticket_id", + "requester_dn", + "requester_group", + "title", + "current_handler", + "external_ticket_source", + "recent_handler", + "requester_id", + "state_id", + "tenant_id", + "ticket_priority", + "reason", + "date_completed", + "date_created", + "ticket_deadline" + ], + "filter": {} + }, + "comment": "" + }, { "role": "requester", "permission": { @@ -19539,10 +33103,12 @@ "assigned_group", "current_handler", "date_completed", + "reason", "recent_handler", "state_id", "ticket_deadline", - "ticket_priority" + "ticket_priority", + "title" ], "filter": {}, "check": null @@ -19580,6 +33146,37 @@ "check": null } }, + { + "role": "middleware-server", + "permission": { + "columns": [ + "date_completed", + "external_ticket_id", + "state_id", + "ticket_deadline", + "ticket_priority" + ], + "filter": {}, + "check": null + }, + "comment": "" + }, + { + "role": "modeller", + "permission": { + "columns": [ + "assigned_group", + "current_handler", + "date_completed", + "recent_handler", + "state_id", + "ticket_deadline", + "ticket_priority" + ], + "filter": {}, + "check": null + } + }, { "role": "planner", "permission": { @@ -19690,6 +33287,17 @@ ] } }, + { + "role": "modeller", + "permission": { + "check": {}, + "columns": [ + "comment_id", + "ticket_id" + ] + }, + "comment": "" + }, { "role": "planner", "permission": { @@ -19762,6 +33370,28 @@ "filter": {} } }, + { + "role": "middleware-server", + "permission": { + "columns": [ + "comment_id", + "ticket_id" + ], + "filter": {} + }, + "comment": "" + }, + { + "role": "modeller", + "permission": { + "columns": [ + "comment_id", + "ticket_id" + ], + "filter": {} + }, + "comment": "" + }, { "role": "planner", "permission": { @@ -19772,6 +33402,28 @@ "filter": {} } }, + { + "role": "reporter", + "permission": { + "columns": [ + "comment_id", + "ticket_id" + ], + "filter": {} + }, + "comment": "" + }, + { + "role": "reporter-viewall", + "permission": { + "columns": [ + "comment_id", + "ticket_id" + ], + "filter": {} + }, + "comment": "" + }, { "role": "requester", "permission": { @@ -19802,6 +33454,12 @@ "schema": "public" } }, + { + "function": { + "name": "get_rules_for_owner", + "schema": "public" + } + }, { "function": { "name": "get_visible_devices_per_tenant", @@ -19819,6 +33477,16 @@ "name": "recert_get_one_owner_one_mgm", "schema": "public" } + }, + { + "function": { + "name": "refresh_view_rule_with_owner", + "schema": "public" + }, + "configuration": { + "custom_root_fields": {}, + "exposed_as": "query" + } } ], "configuration": { diff --git a/roles/api/handlers/main.yml b/roles/api/handlers/main.yml index 17ed989bc5..4c12cc9449 100644 --- a/roles/api/handlers/main.yml +++ b/roles/api/handlers/main.yml @@ -21,7 +21,7 @@ listen: "api handler" - name: restore from backup - include_tasks: hasura-install.yml + include_tasks: ../tasks/rollback-restore.yml listen: "api handler" - name: fail message diff --git a/roles/api/tasks/api-apache-install-and-setup.yml b/roles/api/tasks/api-apache-install-and-setup.yml index d7c8d18416..da6a3a0827 100644 --- a/roles/api/tasks/api-apache-install-and-setup.yml +++ b/roles/api/tasks/api-apache-install-and-setup.yml @@ -7,6 +7,10 @@ - "{{ wsgi_package_name }}" environment: "{{ proxy_env }}" + - name: enable apache2 required modules + apache2_module: state=present name={{ item }} + loop: "{{ apache2_required_modules }}" + - set_fact: api_server_name="{{ ansible_hostname }}" # this only works for importer = backend - name: create apache certificates @@ -34,12 +38,7 @@ - name: enable apache modules proxy proxy_http ssl rewrite proxy_wstunnel apache2_module: state=present name={{ item }} - loop: - - rewrite - - proxy - - proxy_http - - ssl - - proxy_wstunnel + loop: "{{ apache2_required_modules }}" - name: copy api httpd config file to api target template: @@ -48,19 +47,14 @@ owner: root group: root - - name: enable {{ product_name }} web site command: "a2ensite {{ product_name }}-api" - # - name: increase apache timeout to {{ apache_timeout }} seconds (while importing we hit the old 15 min limit) - # lineinfile: - # path: /etc/apache2/apache2.conf - # line: "Timeout {{ apache_timeout }}" - - name: add port to apache lineinfile: path: "/etc/apache2/ports.conf" - line: " Listen {{ api_web_port }}" + line: "Listen {{ api_web_port }}" + regexp: '^\s*Listen {{ api_web_port }}\s*$' insertafter: "" - name: restart apache diff --git a/roles/api/tasks/hasura-install.yml b/roles/api/tasks/hasura-install.yml index 36f47d053e..9b66282a1a 100644 --- a/roles/api/tasks/hasura-install.yml +++ b/roles/api/tasks/hasura-install.yml @@ -1,13 +1,12 @@ -# installs docker and the hasura image in a container +# installs Hasura CLI and runs Hasura in a Podman-managed container -- name: Install packages for python pip3 n virtualenv +- name: Install packages for Hasura CLI download package: name: "{{ item }}" state: present loop: - python3-pip - python3-virtualenv - - python3-docker become: true - name: read dbadmin pwd from secrets file @@ -34,198 +33,452 @@ file: path: "{{ fworch_secrets_dir }}" state: directory - mode: "0700" + mode: "0750" owner: "{{ fworch_user }}" - group: "{{ fworch_group }}" + group: "{{ postgres_group }}" + become: true + +- name: check for existing hasura admin secret file + stat: + path: "{{ fworch_secrets_dir }}/hasura_admin_pwd" + register: hasura_admin_secret_file become: true +- name: read existing hasura admin secret during upgrade + slurp: + src: "{{ fworch_secrets_dir }}/hasura_admin_pwd" + register: existing_hasura_admin_secret + become: true + when: + - installation_mode == "upgrade" + - hasura_admin_secret_file.stat.exists + +- name: cache existing hasura admin secret during upgrade + set_fact: + api_existing_hasura_admin_secret: "{{ existing_hasura_admin_secret['content'] | b64decode | trim }}" + when: + - installation_mode == "upgrade" + - hasura_admin_secret_file.stat.exists + +- name: set hasura admin secret from existing file + set_fact: + api_hasura_admin_secret: "{{ api_existing_hasura_admin_secret }}" + when: + - installation_mode == "upgrade" + - api_use_existing_hasura_on_upgrade | default(false) | bool + - api_existing_hasura_admin_secret is defined + - name: set static hasura admin pwd for test purposes only set_fact: api_hasura_admin_secret: "{{ api_hasura_admin_test_password }}" - when: testkeys is defined and testkeys|bool + when: + - api_hasura_admin_secret is not defined + - testkeys is defined + - testkeys | bool - name: set random hasura admin password set_fact: api_hasura_admin_secret: "{{ randomly_generated_pwd }}" - when: testkeys is not defined or not testkeys|bool - -- name: write hasura admin password to secrets directory - copy: - content: "{{ api_hasura_admin_secret }}\n" - dest: "{{ fworch_secrets_dir }}/hasura_admin_pwd" - mode: '0600' - owner: "{{ fworch_user }}" - group: "{{ fworch_group }}" - become: true + when: + - api_hasura_admin_secret is not defined - name: check for existing hasura cli file stat: path: "{{ api_hasura_cli_bin }}" register: api_cli_check -# only download new version of api cli, when not restoring from backup: -- name: download {{ api_hasura_version }} hasura cli binary - get_url: - url: "https://github.com/hasura/graphql-engine/releases/download/{{ api_hasura_version }}/cli-hasura-linux-amd64" - dest: "{{ api_hasura_cli_bin }}" - force: true - mode: "0755" - owner: "{{ fworch_user }}" - group: "{{ fworch_group }}" +- name: detect whether upgrade can reuse installed Hasura + set_fact: + api_hasura_upgrade_reuse_possible: >- + {{ + installation_mode == "upgrade" + and (api_existing_service_name | default('') | length > 0) + and hasura_admin_secret_file.stat.exists + }} + +- name: fail when Hasura upgrade reuse was requested without reusable state + fail: + msg: >- + Hasura upgrade fallback requires both an installed Hasura service unit and the existing + {{ fworch_secrets_dir }}/hasura_admin_pwd secret file. + when: + - installation_mode == "upgrade" + - api_use_existing_hasura_on_upgrade | default(false) | bool + - not api_hasura_upgrade_reuse_possible | bool + +- name: build GitHub auth header + set_fact: + api_github_auth_header: "{{ {'Authorization': 'Bearer ' ~ api_github_token} if api_github_token is defined else {} }}" + +- name: Get Hasura release info from GitHub (authenticated) + uri: + url: "https://api.github.com/repos/hasura/graphql-engine/releases/tags/{{ api_hasura_version }}" + method: GET + headers: "{{ {'Accept': 'application/vnd.github+json'} | combine(api_github_auth_header) }}" + return_content: true + timeout: "{{ github_download_timeout }}" + register: hasura_release environment: "{{ proxy_env }}" - become: true - when: not api_cli_check.stat.exists + failed_when: false + retries: 3 + delay: 5 + until: hasura_release.status | default(-1) == 200 + when: + - not api_cli_check.stat.exists + - not api_use_existing_hasura_on_upgrade | default(false) | bool + +- name: Extract Hasura CLI asset id for {{ linux_architecture }} + set_fact: + hasura_cli_asset_id: >- + {{ + hasura_release.json.assets + | selectattr('name', 'equalto', 'cli-hasura-linux-' ~ linux_architecture) + | map(attribute='id') + | list + | first + }} + when: + - not api_cli_check.stat.exists + - not api_use_existing_hasura_on_upgrade | default(false) | bool + - hasura_release.status | default(-1) == 200 + +- name: download {{ api_hasura_version }} hasura cli binary + block: + - name: download {{ api_hasura_version }} hasura cli binary via authenticated GitHub access + get_url: + url: "https://api.github.com/repos/hasura/graphql-engine/releases/assets/{{ hasura_cli_asset_id }}" + dest: "{{ api_hasura_cli_bin }}" + headers: "{{ {'Accept': 'application/octet-stream'} | combine(api_github_auth_header) }}" + force: true + timeout: "{{ github_download_timeout }}" + mode: "0755" + owner: "{{ fworch_user }}" + group: "{{ fworch_group }}" + environment: "{{ proxy_env }}" + register: api_hasura_cli_download + retries: 3 + delay: 5 + until: api_hasura_cli_download is succeeded + become: true + when: hasura_cli_asset_id is defined + rescue: + - name: download {{ api_hasura_version }} hasura cli binary via direct GitHub download after asset API failure + block: + - name: download {{ api_hasura_version }} hasura cli binary via direct GitHub download after asset API failure + get_url: + url: "https://github.com/hasura/graphql-engine/releases/download/{{ api_hasura_version }}/cli-hasura-linux-{{ linux_architecture }}" + dest: "{{ api_hasura_cli_bin }}" + force: true + timeout: "{{ github_download_timeout }}" + mode: "0755" + owner: "{{ fworch_user }}" + group: "{{ fworch_group }}" + environment: "{{ proxy_env }}" + register: api_hasura_cli_download_fallback + retries: 3 + delay: 5 + until: api_hasura_cli_download_fallback is succeeded + become: true + rescue: + - name: fall back to existing Hasura after CLI download failure during upgrade + set_fact: + api_use_existing_hasura_on_upgrade: true + api_service_name: "{{ api_existing_service_name }}" + api_hasura_admin_secret: "{{ api_existing_hasura_admin_secret }}" + when: api_hasura_upgrade_reuse_possible | bool + + - name: show Hasura CLI upgrade fallback decision + debug: + msg: >- + Hasura CLI download failed during upgrade, reusing the installed Hasura service/container + and continuing with metadata-only upgrade steps. Docker-to-Podman migration is deferred + until a later run can download the required artifacts. + when: api_hasura_upgrade_reuse_possible | bool + + - name: fail when Hasura CLI download fails without upgrade fallback + fail: + msg: >- + Failed to download Hasura CLI and no existing Hasura service is available for upgrade fallback. + when: not api_hasura_upgrade_reuse_possible | bool + when: + - not api_cli_check.stat.exists + - not api_use_existing_hasura_on_upgrade | default(false) | bool + +- name: download {{ api_hasura_version }} hasura cli binary via direct GitHub download when no asset id was found + block: + - name: download {{ api_hasura_version }} hasura cli binary via direct GitHub download when no asset id was found + get_url: + url: "https://github.com/hasura/graphql-engine/releases/download/{{ api_hasura_version }}/cli-hasura-linux-{{ linux_architecture }}" + dest: "{{ api_hasura_cli_bin }}" + force: true + timeout: "{{ github_download_timeout }}" + mode: "0755" + owner: "{{ fworch_user }}" + group: "{{ fworch_group }}" + environment: "{{ proxy_env }}" + register: api_hasura_cli_download_fallback + retries: 3 + delay: 5 + until: api_hasura_cli_download_fallback is succeeded + become: true + rescue: + - name: fall back to existing Hasura after direct CLI download failure during upgrade + set_fact: + api_use_existing_hasura_on_upgrade: true + api_service_name: "{{ api_existing_service_name }}" + api_hasura_admin_secret: "{{ api_existing_hasura_admin_secret }}" + when: api_hasura_upgrade_reuse_possible | bool + + - name: show Hasura direct CLI upgrade fallback decision + debug: + msg: >- + Direct Hasura CLI download failed during upgrade, reusing the installed Hasura service/container + and continuing with metadata-only upgrade steps. Docker-to-Podman migration is deferred + until a later run can download the required artifacts. + when: api_hasura_upgrade_reuse_possible | bool + + - name: fail when direct Hasura CLI download fails without upgrade fallback + fail: + msg: >- + Failed to download Hasura CLI from the release URL and no existing Hasura service is available + for upgrade fallback. + when: not api_hasura_upgrade_reuse_possible | bool + when: + - not api_cli_check.stat.exists + - not api_use_existing_hasura_on_upgrade | default(false) | bool + - hasura_cli_asset_id is not defined - name: initialize hasura cli directory command: "{{ api_hasura_cli_bin }} init {{ product_name }} --skip-update-check --endpoint http://{{ api_local_listening_ip_address }}:{{ api_port }} --admin-secret {{ api_hasura_admin_secret }}" - args: + args: chdir: "{{ api_home }}" become: true become_user: "{{ fworch_user }}" environment: "{{ proxy_env }}" - when: not api_cli_check.stat.exists + when: + - not api_cli_check.stat.exists + - not api_use_existing_hasura_on_upgrade | default(false) | bool + +- name: set Hasura image reuse mode + set_fact: + api_reuse_existing_hasura_image: >- + {{ + installation_mode == "upgrade" + and (api_use_existing_hasura_on_upgrade | default(false) | bool) + and api_hasura_keep_existing_container | default(true) | bool + }} + +- name: set Hasura systemd dependencies + set_fact: + api_hasura_systemd_after: >- + {{ + ['network.target', 'remote-fs.target', 'nss-lookup.target'] + + (['postgresql.service'] if 'databaseserver' in group_names else []) + }} + +- name: ensure Hasura image is present + block: + - name: ensure Hasura image is present + containers.podman.podman_image: + name: "{{ api_hasura_image }}" + state: present + environment: "{{ proxy_env }}" + become: true + rescue: + - name: fall back to existing Hasura image after pull failure during upgrade + set_fact: + api_use_existing_hasura_on_upgrade: true + api_reuse_existing_hasura_image: true + api_service_name: "{{ api_existing_service_name }}" + api_hasura_admin_secret: "{{ api_existing_hasura_admin_secret }}" + when: api_hasura_upgrade_reuse_possible | bool + + - name: show Hasura image upgrade fallback decision + debug: + msg: >- + Hasura image pull failed during upgrade, reusing the installed Hasura service/container + and continuing with metadata-only upgrade steps. Docker-to-Podman migration is deferred + until a later run can download the required artifacts. + when: api_hasura_upgrade_reuse_possible | bool + + - name: fail when Hasura image pull fails without upgrade fallback + fail: + msg: >- + Failed to pull Hasura image {{ api_hasura_image }} and no existing Hasura service is available + for upgrade fallback. + when: not api_hasura_upgrade_reuse_possible | bool + when: + - not api_reuse_existing_hasura_image | bool + - api_rollback_is_running | default(false) | bool == false + +- name: write hasura admin password to secrets directory + copy: + content: "{{ api_hasura_admin_secret }}\n" + dest: "{{ fworch_secrets_dir }}/hasura_admin_pwd" + mode: "0600" + owner: "{{ fworch_user }}" + group: "{{ fworch_group }}" + become: true + when: + - installation_mode != "upgrade" or not (api_use_existing_hasura_on_upgrade | default(false) | bool) or not hasura_admin_secret_file.stat.exists - name: set hasura env variable set_fact: hasura_env: - HASURA_GRAPHQL_DATABASE_URL: "postgres://{{ api_user }}:{{ api_user_password }}@{{ fworch_db_host }}:{{ fworch_db_port }}/{{ fworch_db_name }}" - HASURA_GRAPHQL_ENABLE_CONSOLE: "true" + HASURA_GRAPHQL_DATABASE_URL: "postgres://{{ api_user }}:{{ api_user_password }}@{{ fworch_db_host }}:{{ fworch_db_port }}/{{ fworch_db_name }}" + HASURA_GRAPHQL_ENABLE_CONSOLE: "true" HASURA_GRAPHQL_ENABLE_TELEMETRY: "false" - HASURA_GRAPHQL_ADMIN_SECRET: "{{ api_hasura_admin_secret }}" - HASURA_GRAPHQL_LOG_LEVEL: "{{ api_log_level }}" - HASURA_GRAPHQL_ENABLED_LOG_TYPES: '{{ api_HASURA_GRAPHQL_ENABLED_LOG_TYPES }}' + HASURA_GRAPHQL_ADMIN_SECRET: "{{ api_hasura_admin_secret }}" + HASURA_GRAPHQL_SERVER_HOST: "127.0.0.1" + HASURA_GRAPHQL_SERVER_PORT: "8080" + HASURA_GRAPHQL_LOG_LEVEL: "{{ api_log_level }}" + HASURA_GRAPHQL_ENABLED_LOG_TYPES: "{{ api_HASURA_GRAPHQL_ENABLED_LOG_TYPES }}" HASURA_GRAPHQL_CONSOLE_ASSETS_DIR: "/srv/console-assets" HASURA_GRAPHQL_V1_BOOLEAN_NULL_COLLAPSE: "true" - HASURA_GRAPHQL_CORS_DOMAIN: "*" + HASURA_GRAPHQL_CORS_DOMAIN: "*" HASURA_GRAPHQL_INFER_FUNCTION_PERMISSIONS: "{{ api_HASURA_GRAPHQL_INFER_FUNCTION_PERMISSIONS }}" - HASURA_GRAPHQL_JWT_SECRET: ' - { - "type": "{{ api_hasura_jwt_alg|quote }}", - "key": "{{ api_hasura_jwt_secret | regex_replace(''\n'', ''\\n'') }}", - "claims_namespace_path": "$" - } - ' - HTTP_PROXY: "{{ http_proxy }}" - HTTPS_PROXY: "{{ https_proxy }}" - http_proxy: "{{ http_proxy }}" - https_proxy: "{{ https_proxy }}" - no_proxy: "{{ no_proxy }}" - NO_PROXY: "{{ no_proxy }}" + HASURA_GRAPHQL_JWT_SECRET: "{{ {'type': api_hasura_jwt_alg, 'key': api_hasura_jwt_secret | regex_replace('\n', '\\n'), 'claims_namespace_path': '$'} | to_json }}" + HTTP_PROXY: "{{ http_proxy }}" + HTTPS_PROXY: "{{ https_proxy }}" + http_proxy: "{{ http_proxy }}" + https_proxy: "{{ https_proxy }}" + no_proxy: "{{ no_proxy }}" + NO_PROXY: "{{ no_proxy }}" - name: show hasura env for debugging debug: - var: - hasura_env + var: hasura_env when: debug_level > '1' -- name: start hasura container ansible 2.10 and higher - docker_container: +- name: write Hasura env file for Podman + copy: + dest: "{{ api_env_file }}" + mode: "0640" + owner: "root" + group: "{{ fworch_group }}" + content: | + {% for item in hasura_env | dictsort %} + {{ item.0 }}={{ item.1 }} + {% endfor %} + become: true + +- name: stop Hasura service before container recreation + ansible.builtin.systemd: + name: "{{ api_service_name }}" + state: stopped + become: true + failed_when: false + when: + - not api_reuse_existing_hasura_image | bool + +- name: remove existing Hasura container before recreation + containers.podman.podman_container: name: "{{ api_container_name }}" - image: hasura/graphql-engine:{{ api_hasura_version }} - state: started - network_mode: host - networks_cli_compatible: true - log_driver: syslog - log_options: - syslog-address: "{{ syslog_proto }}://{{ syslog_host }}:{{ syslog_port }}" - syslog-facility: daemon - tag: "{{ api_container_name }}" - recreate: true - exposed_ports: - - "{{ api_port }}:{{ api_port }}" - env: - "{{ hasura_env }}" - container_default_behavior: no_defaults - register: docker_return + state: absent become: true - become_user: "{{ fworch_user }}" - environment: "{{ proxy_env }}" - when: ansible_version.full is version('2.10', '>=') + when: + - not api_reuse_existing_hasura_image | bool + +- name: force remove existing Hasura container before recreation + command: "podman rm -f {{ api_container_name }}" + register: api_force_remove_hasura_container + changed_when: api_force_remove_hasura_container.rc == 0 + failed_when: false + become: true + when: + - not api_reuse_existing_hasura_image | bool -- name: start hasura container pre ansible 2.10 - docker_container: +- name: ensure Hasura container exists + containers.podman.podman_container: name: "{{ api_container_name }}" - image: hasura/graphql-engine:{{ api_hasura_version }} - state: started - network_mode: host - networks_cli_compatible: true - log_driver: syslog - log_options: - syslog-address: "{{ syslog_proto }}://{{ syslog_host }}:{{ syslog_port }}" - syslog-facility: daemon - tag: "{{ api_container_name }}" + image: "{{ api_hasura_image }}" + state: created recreate: true - exposed_ports: - - "{{ api_port }}:{{ api_port }}" - env: - "{{ hasura_env }}" - register: docker_return + rm: true + network: + - host + user: "1001:1001" + env: "{{ hasura_env }}" become: true - become_user: "{{ fworch_user }}" - environment: "{{ proxy_env }}" - when: ansible_version.full is version('2.10', '<') + when: + - not api_reuse_existing_hasura_image | bool -- name: show docker result - debug: - var: - docker_return - when: debug_level > '1' - -- name: Get info on container - docker_container_info: +- name: generate Hasura systemd unit content + containers.podman.podman_generate_systemd: name: "{{ api_container_name }}" - register: result + new: true + no_header: true + restart_policy: on-failure + use_names: true + register: api_hasura_systemd_unit become: true - become_user: "{{ fworch_user }}" + when: + - not api_reuse_existing_hasura_image | bool -- name: Print the status of the container in case of problems only - fail: - msg: "The container status is: {{ result }}" - when: result.exists and result.container['State']['Status'] == 'exited' +- name: install generated Hasura systemd service + copy: + content: >- + {{ + ( + api_hasura_systemd_unit.systemd_units + | dict2items + | first + ).value + | regex_replace( + '\\[Service\\]\\n', + '[Service]\nStandardOutput=journal\nStandardError=journal\nSyslogIdentifier=' ~ product_name ~ '-api\n', + 1 + ) + }} + dest: "/lib/systemd/system/{{ api_service_name }}.service" + backup: true + mode: "0644" + owner: "root" + become: true + when: + - not api_reuse_existing_hasura_image | bool + +- name: remove legacy Docker API service unit + file: + path: "/lib/systemd/system/{{ item }}.service" + state: absent + become: true + loop: "{{ api_legacy_service_names | default([]) }}" + when: + - item != api_service_name -- name: copy hasura systemd service script - template: - src: "{{ api_service_name }}.service.j2" - dest: "/lib/systemd/system/{{ api_service_name }}.service" - backup: true - mode: "0644" - owner: "root" +- name: clear hasura service failed state + command: "systemctl reset-failed {{ api_service_name }}" become: true -- name: make hasura docker container run at host startup +- name: ensure hasura service is running systemd: name: "{{ api_service_name }}" - daemon_reload: true + state: started enabled: true + daemon_reload: true become: true -- name: wait for hasura port to become available +- name: wait for hasura port to become available wait_for: port: "{{ api_port }}" host: "{{ api_local_listening_ip_address }}" connect_timeout: 1 - delay: 10 - timeout: 25 - -- name: check for existing api dir from restore - stat: - path: "{{ api_home }}/{{ product_name }}" - register: api_metadata_check + delay: 3 + timeout: 30 - name: import API metadata via metadata API directly from local file - uri: + uri: url: "http://{{ api_local_listening_ip_address }}:{{ api_port }}/v1/metadata" method: POST return_content: true - body_format: json + body_format: json headers: - Content-Type: application/json + Content-Type: application/json x-hasura-admin-secret: "{{ api_hasura_admin_secret }}" x-hasura-role: "admin" body: "{{ lookup('file','replace_metadata.json') | from_json }}" when: not api_rollback_is_running | bool - # do not install latest metadata in case of rollback environment: http_proxy: "" https_proxy: "" - # do not use http proxy for metadata import diff --git a/roles/api/tasks/main.yml b/roles/api/tasks/main.yml index b9b332e697..926dfec367 100644 --- a/roles/api/tasks/main.yml +++ b/roles/api/tasks/main.yml @@ -8,6 +8,132 @@ - api handler when: installation_mode == "upgrade" +- name: set default hasura upgrade mode for upgrades + set_fact: + api_use_existing_hasura_on_upgrade: "{{ api_keep_existing_hasura_on_upgrade | default(false) | bool }}" + when: installation_mode == "upgrade" + +- name: probe GitHub release access for hasura upgrade + uri: + url: "https://api.github.com/repos/hasura/graphql-engine/releases/tags/{{ api_hasura_version }}" + method: GET + return_content: false + timeout: "{{ github_download_timeout }}" + register: api_hasura_release_access + environment: "{{ proxy_env }}" + failed_when: false + when: + - installation_mode == "upgrade" + - not api_use_existing_hasura_on_upgrade | bool + +- name: fallback to existing hasura when GitHub is not reachable during upgrade + set_fact: + api_use_existing_hasura_on_upgrade: true + when: + - installation_mode == "upgrade" + - not api_use_existing_hasura_on_upgrade | bool + - api_hasura_release_access.status | default(0) != 200 + +- name: show hasura upgrade fallback decision + debug: + msg: >- + GitHub release lookup failed (HTTP {{ api_hasura_release_access.status | default('unknown') }}), + reusing existing Hasura container and upgrading metadata only. + when: + - installation_mode == "upgrade" + - api_use_existing_hasura_on_upgrade | bool + - api_hasura_release_access is defined + - api_hasura_release_access.status | default(0) != 200 + +- name: collect installed Hasura service unit candidates + stat: + path: "/lib/systemd/system/{{ item }}.service" + loop: "{{ [api_service_name] + (api_legacy_service_names | default([])) }}" + register: api_service_unit_candidates + when: installation_mode == "upgrade" + +- name: pick installed Hasura service name for upgrade reuse + set_fact: + api_existing_service_name: >- + {{ + ( + api_service_unit_candidates.results + | selectattr('stat.exists') + | map(attribute='item') + | list + | first + ) | default('') + }} + when: installation_mode == "upgrade" + +- name: reuse installed Hasura service name during upgrade fallback + set_fact: + api_service_name: "{{ api_existing_service_name }}" + when: + - installation_mode == "upgrade" + - api_use_existing_hasura_on_upgrade | default(false) | bool + - api_existing_service_name | length > 0 + +- name: stop MW for upgrading + ansible.builtin.systemd: + name: "{{ product_name }}-middleware" + state: stopped + become: true + when: "'middlewareserver' in group_names and installation_mode == 'upgrade'" + +- name: stop API service for upgrading + ansible.builtin.systemd: + name: "{{ api_service_name }}" + state: stopped + become: true + when: installation_mode == "upgrade" and not (api_use_existing_hasura_on_upgrade | default(false) | bool) + failed_when: false + +- name: stop legacy Hasura services for upgrading + ansible.builtin.systemd: + name: "{{ item }}" + state: stopped + enabled: false + become: true + loop: "{{ api_legacy_service_names | default([]) }}" + when: installation_mode == "upgrade" and not (api_use_existing_hasura_on_upgrade | default(false) | bool) + failed_when: false + +- name: check whether Docker is installed + stat: + path: /usr/bin/docker + register: api_docker_binary + when: installation_mode == "upgrade" + +- name: stop legacy Docker API container for upgrading + command: "/usr/bin/docker stop {{ api_container_name }}" + become: true + register: api_stop_legacy_docker_container + changed_when: api_stop_legacy_docker_container.rc == 0 + failed_when: false + when: + - installation_mode == "upgrade" + - not (api_use_existing_hasura_on_upgrade | default(false) | bool) + - api_docker_binary.stat.exists | default(false) + +- name: remove legacy Docker API container for upgrading + command: "/usr/bin/docker rm {{ api_container_name }}" + become: true + register: api_remove_legacy_docker_container + changed_when: api_remove_legacy_docker_container.rc == 0 + failed_when: false + when: + - installation_mode == "upgrade" + - not (api_use_existing_hasura_on_upgrade | default(false) | bool) + - api_docker_binary.stat.exists | default(false) + +- name: stop UI for upgrading + ansible.builtin.systemd: + name: "{{ product_name }}-ui" + state: stopped + become: true + when: "'frontends' in group_names and installation_mode == 'upgrade'" + - name: check for api dir stat: path: "{{ fworch_home }}/api" @@ -26,6 +152,7 @@ path: "{{ api_home }}" state: absent become: true + when: installation_mode != "upgrade" or not (api_use_existing_hasura_on_upgrade | default(false) | bool) - name: create api home file: @@ -55,15 +182,6 @@ import_tasks: run-upgrades.yml when: "installation_mode == 'upgrade'" -- name: copy fworch config export and import scripts - copy: - src: scripts - dest: "{{ fworch_home }}" - mode: "0755" - owner: "{{ fworch_user}}" - group: "{{ fworch_user}}" - become: true - - name: copy fwo_api.py for scripting from importer copy: src: roles/importer/files/importer/fwo_api.py diff --git a/roles/api/tasks/rollback-restore.yml b/roles/api/tasks/rollback-restore.yml new file mode 100644 index 0000000000..19a9db2bd1 --- /dev/null +++ b/roles/api/tasks/rollback-restore.yml @@ -0,0 +1,33 @@ +- name: collect installed Hasura service unit candidates for rollback + stat: + path: "/lib/systemd/system/{{ item }}.service" + loop: "{{ [api_service_name] + (api_legacy_service_names | default([])) }}" + register: api_restore_service_unit_candidates + become: true + +- name: pick Hasura service name for rollback restore + set_fact: + api_restore_service_name: >- + {{ + ( + api_restore_service_unit_candidates.results + | selectattr('stat.exists') + | map(attribute='item') + | list + | first + ) | default(api_service_name) + }} + +- name: clear Hasura service failed state during rollback + command: "systemctl reset-failed {{ api_restore_service_name }}" + become: true + failed_when: false + +- name: start Hasura service during rollback + ansible.builtin.systemd: + name: "{{ api_restore_service_name }}" + state: started + enabled: true + daemon_reload: true + become: true + failed_when: false diff --git a/roles/api/templates/fworch-hasura-docker-api.service.j2 b/roles/api/templates/fworch-hasura-docker-api.service.j2 index 6c0bc9c941..ae602635b4 100644 --- a/roles/api/templates/fworch-hasura-docker-api.service.j2 +++ b/roles/api/templates/fworch-hasura-docker-api.service.j2 @@ -1,18 +1,32 @@ [Unit] Description={{ product_name }} API +Requires=docker.service {% if 'databaseserver' in group_names -%} -After=network.target remote-fs.target nss-lookup.target postgresql.service +After=network.target remote-fs.target nss-lookup.target postgresql.service docker.service {% else -%} -After=network.target remote-fs.target nss-lookup.target +After=network.target remote-fs.target nss-lookup.target docker.service {%- endif %} [Service] +Restart=on-failure +SuccessExitStatus=0 137 143 WorkingDirectory={{ fworch_home }} -ExecStartPre=/bin/sleep 10 -ExecStart=/usr/bin/docker start {{ api_container_name }} +ExecStart=/bin/bash -c '\ + if /usr/bin/docker inspect -f "{% raw %}{{.State.Running}}{% endraw %}" {{ api_container_name }} 2>/dev/null | grep -q true; then \ + exec /usr/bin/docker attach {{ api_container_name }}; \ + fi; \ + exec /usr/bin/docker start -a {{ api_container_name }} \ +' +ExecStop=/usr/bin/docker stop -t 2 {{ api_container_name }} StandardOutput=journal StandardError=journal SyslogIdentifier={{ product_name }}-api User={{ fworch_user }} -Environment= [Install] -WantedBy=multi-user.target +WantedBy=default.target + +# Explanation of SuccessExitStatus: +# extra exit codes that systemd should treat as “success” instead of failure: +# 0 normal success. +# 137 process exited due to signal 9 (128+9), i.e., killed/SIGKILL (common when a container is stopped forcefully). +# 143 process exited due to signal 15 (128+15), i.e., SIGTERM (the normal stop path). +# Now a clean container stop (SIGTERM) or a forced stop (SIGKILL) does not leave the unit in a failed state. \ No newline at end of file diff --git a/roles/api/templates/httpd.conf.j2 b/roles/api/templates/httpd.conf.j2 index ced5cb94c6..50f4d97def 100644 --- a/roles/api/templates/httpd.conf.j2 +++ b/roles/api/templates/httpd.conf.j2 @@ -4,15 +4,25 @@ # DocumentRoot stays empty, only proxying Timeout {{ apache_fwo_api_timeout }} - ProxyRequests On - Order deny,allow - Allow from all + Require all granted + # + # LimitRequestBody 250M + # + + # set buffer to 128KB + ProxyIOBufferSize 131072 + + Timeout 3600 + ProxyTimeout 3600 + # terminate https incoming calls and proxy to http ProxyPass /api http://{{ api_local_listening_ip_address }}:{{ api_port }}/ - # websocket protocol is needed for subscriptions + ProxyPassReverse /api http://{{ api_local_listening_ip_address }}:{{ api_port }}/ + + # WebSocket support for GraphQL subscriptions RewriteEngine on RewriteCond %{HTTP:Upgrade} websocket [NC] RewriteCond %{HTTP:Connection} upgrade [NC] @@ -21,8 +31,18 @@ ErrorLog /var/log/{{ webserver_package_name }}/error.log TransferLog /var/log/{{ webserver_package_name }}/access.log CustomLog /var/log/{{ webserver_package_name }}/ssl_request_log "%t %h %{SSL_PROTOCOL}x %{SSL_CIPHER}x \"%r\" %b" + SSLEngine on - SSLCipherSuite RSA:!EXP:!NULL:+HIGH:+MEDIUM:-LOW + {{ apache_ssl_protocol }} + {{ apache_ssl_cipher_suite }} SSLCertificateFile /etc/{{ webserver_package_name }}/ssl/server.crt SSLCertificateKeyFile /etc/{{ webserver_package_name }}/ssl/server.key + + # --- Security Headers --- + +{% for header in apache_security_headers %} + {{ header }} +{% endfor %} + + diff --git a/roles/cleanup/tasks/main.yml b/roles/cleanup/tasks/main.yml deleted file mode 100644 index b869b8f8f9..0000000000 --- a/roles/cleanup/tasks/main.yml +++ /dev/null @@ -1,95 +0,0 @@ -# change version to new number in /etc/fworch/fworch.yaml - -- name: check for existing main config file - stat: - path: "{{ fworch_conf_file }}" - register: already_installed - -- set_fact: - already_installed: "{{ already_installed.stat.exists }}" - -- debug: - msg: "installation_mode={{ installation_mode }}, already_installed={{ already_installed }}" - -- name: fail if unknown installation_mode is set - fail: - msg: "Found undefined installation_mode: {{ installation_mode }}, aborting." - when: installation_mode != "new" and installation_mode != "uninstall" and installation_mode != "upgrade" - -- name: fail if not already installed and installation_mode is upgrade - fail: - msg: "Could not find existing installation but running with installation_mode set to {{ installation_mode }}. Try running with installation_mode=new" - when: not already_installed and installation_mode == "upgrade" - -- name: edit central conf file - set new version - lineinfile: - path: "{{ fworch_conf_file }}" - create: true - regexp: "product_version" - line: " \"product_version\": \"{{ product_version }}\"" - when: installation_mode == "upgrade" - become: true - -- name: include upgrade script - import_tasks: run-upgrades.yml - when: "installation_mode == 'upgrade'" - -# Do general cleanup - -- name: delete ldif files - file: - path: "{{ middleware_ldif_dir }}" - state: absent - become: true - when: "'middlewareserver' in group_names" - -- name: restart UI to display new product version - ansible.builtin.systemd: - name: "{{ product_name }}-ui" - state: restarted - become: true - when: "'frontends' in group_names" - -- name: test whether demo data is present - postgresql_query: - db: "{{ fworch_db_name }}" - query: > - SELECT * FROM device WHERE dev_name='{{ sample_fortigate_name }}' - register: demo_data_present - become: true - become_user: postgres - -- name: find cron jobs in case of missing demo data - find: - paths: /etc/cron.d - patterns: "{{ product_name }}_sample_data_*" - register: files_to_delete - when: demo_data_present.query_result == [] - become: true - -- name: delete cron jobs in case of missing demo data - file: - path: "{{ item.path }}" - state: absent - with_items: "{{ files_to_delete.files }}" - when: demo_data_present.query_result == [] - become: true - -- name: remove temp importer_password from install host - file: - path: "{{ importer_password_file_on_installer }}" - state: absent - become: true - delegate_to: localhost - -- name: start importer service - systemd: - name: "{{ item }}" - state: started - daemon_reload: true - enabled: true - become: true - when: "'importers' in group_names" - loop: - - "{{ product_name }}-importer-legacy" - - "{{ product_name }}-importer-api" diff --git a/roles/lib/files/FWO.Api.Client/APIcalls/allObjects/deleteOldObjectsCascading.graphql b/roles/common/files/fwo-api-calls/allObjects/deleteOldObjectsCascading.graphql similarity index 80% rename from roles/lib/files/FWO.Api.Client/APIcalls/allObjects/deleteOldObjectsCascading.graphql rename to roles/common/files/fwo-api-calls/allObjects/deleteOldObjectsCascading.graphql index b4287343ae..3ba03fd594 100644 --- a/roles/lib/files/FWO.Api.Client/APIcalls/allObjects/deleteOldObjectsCascading.graphql +++ b/roles/common/files/fwo-api-calls/allObjects/deleteOldObjectsCascading.graphql @@ -4,6 +4,6 @@ mutation delete_old_objects ($retentionInMonths: Int!) { delete_ldap_connection_by_pk ( ldap_connection_id: $id ) { - DeletedId: ldap_connection_id + deletedId: ldap_connection_id } } diff --git a/roles/common/files/fwo-api-calls/allObjects/fixRefTables.graphql b/roles/common/files/fwo-api-calls/allObjects/fixRefTables.graphql new file mode 100644 index 0000000000..6dc8142620 --- /dev/null +++ b/roles/common/files/fwo-api-calls/allObjects/fixRefTables.graphql @@ -0,0 +1,106 @@ +mutation fixRefTables($importId: bigint!, $mgmId: Int!) { + update_rule_from( + where: { + rule: { mgm_id: { _eq: $mgmId } } + removed: { _is_null: true } + _or: [ + { rule: { removed: { _is_null: false } } } + { object: { removed: { _is_null: false } } } + ] + } + _set: { removed: $importId } + ) { + affected_rows + } + update_rule_to( + where: { + rule: { mgm_id: { _eq: $mgmId } } + removed: { _is_null: true } + _or: [ + { rule: { removed: { _is_null: false } } } + { object: { removed: { _is_null: false } } } + ] + } + _set: { removed: $importId } + ) { + affected_rows + } + update_rule_nwobj_resolved( + where: { + rule: { mgm_id: { _eq: $mgmId } } + removed: { _is_null: true } + _or: [ + { rule: { removed: { _is_null: false } } } + { object: { removed: { _is_null: false } } } + ] + } + _set: { removed: $importId } + ) { + affected_rows + } + update_rule_service( + where: { + rule: { mgm_id: { _eq: $mgmId } } + removed: { _is_null: true } + _or: [ + { rule: { removed: { _is_null: false } } } + { service: { removed: { _is_null: false } } } + ] + } + _set: { removed: $importId } + ) { + affected_rows + } + update_rule_svc_resolved( + where: { + rule: { mgm_id: { _eq: $mgmId } } + removed: { _is_null: true } + _or: [ + { rule: { removed: { _is_null: false } } } + { service: { removed: { _is_null: false } } } + ] + } + _set: { removed: $importId } + ) { + affected_rows + } + update_rule_user_resolved( + where: { + rule: { mgm_id: { _eq: $mgmId } } + removed: { _is_null: true } + _or: [ + { rule: { removed: { _is_null: false } } } + { usr: { removed: { _is_null: false } } } + ] + } + _set: { removed: $importId } + ) { + affected_rows + } + update_rule_from_zone( + where: { + rule: { mgm_id: { _eq: $mgmId } } + removed: { _is_null: true } + _or: [ + { rule: { removed: { _is_null: false } } } + { zone: { removed: { _is_null: false } } } + ] + } + _set: { removed: $importId } + ) { + affected_rows + } + update_rule_to_zone( + where: { + rule: { mgm_id: { _eq: $mgmId } } + removed: { _is_null: true } + _or: [ + { rule: { removed: { _is_null: false } } } + { zone: { removed: { _is_null: false } } } + ] + } + _set: { removed: $importId } + ) { + affected_rows + } +} diff --git a/roles/common/files/fwo-api-calls/allObjects/getAllObjectDetails.graphql b/roles/common/files/fwo-api-calls/allObjects/getAllObjectDetails.graphql new file mode 100644 index 0000000000..07e2250e4f --- /dev/null +++ b/roles/common/files/fwo-api-calls/allObjects/getAllObjectDetails.graphql @@ -0,0 +1,80 @@ +query getAllObjectDetails ( + $management_id: [Int!] + $type: [String!] + $uid: [String!] + $active: Boolean + $import_id_start: bigint + $import_id_end: bigint + $obj_name: [String!] + $limit: Int + $offset: Int +) { + management( + where: { + mgm_id: { _in: $management_id } + hide_in_gui: { _eq: false } + stm_dev_typ:{ + dev_typ_is_multi_mgmt: { _eq: false } + is_pure_routing_device:{_eq:false} + } + } + order_by: { mgm_name: asc } + ) { + id: mgm_id + name: mgm_name + networkObjects: objects ( + limit: $limit + offset: $offset + where: { + stm_obj_typ: { obj_typ_name: { _in: $type } } + active: { _eq: $active } + _or: [ + { removed: { _is_null: true } }, + { removed: { _gte: $import_id_start } } + ] + obj_create: { _lte: $import_id_end } + obj_name: { _in: $obj_name } + obj_uid: { _in: $uid } + } + order_by: { obj_name: asc } + ) { + ...networkObjectDetails + } + serviceObjects: services ( + limit: $limit + offset: $offset + where: { + stm_svc_typ: { svc_typ_name: { _in: $type } } + active: { _eq: $active } + _or: [ + { removed: { _is_null: true } }, + { removed: { _gte: $import_id_start } } + ] + svc_create: { _lte: $import_id_end } + svc_name: { _in: $obj_name } + svc_uid: { _in: $uid } + } + order_by: { svc_name: asc } + ) { + ...networkServiceDetails + } + userObjects: usrs ( + limit: $limit + offset: $offset + where: { + stm_usr_typ: { usr_typ_name: { _in: $type } } + active: { _eq: $active } + _or: [ + { removed: { _is_null: true } }, + { removed: { _gte: $import_id_start } } + ] + user_create: { _lte: $import_id_end } + user_name: { _in: $obj_name } + user_uid: { _in: $uid } + } + order_by: { user_name: asc } + ) { + ...userDetails + } + } +} diff --git a/roles/common/files/fwo-api-calls/allObjects/upsertObjects.graphql b/roles/common/files/fwo-api-calls/allObjects/upsertObjects.graphql new file mode 100644 index 0000000000..4994630b0d --- /dev/null +++ b/roles/common/files/fwo-api-calls/allObjects/upsertObjects.graphql @@ -0,0 +1,99 @@ +mutation upsertObjects( + $mgmId: Int! + $importId: bigint! + $removedNwObjectUids: [String!]! + $removedSvcObjectUids: [String!]! + $removedUserUids: [String!]! + $removedZoneUids: [String!]! + $newNwObjects: [object_insert_input!]! + $newSvcObjects: [service_insert_input!]! + $newUsers: [usr_insert_input!]! + $newZones: [zone_insert_input!]! +) { + update_object( + where: { + mgm_id: { _eq: $mgmId } + obj_uid: { _in: $removedNwObjectUids } + removed: { _is_null: true } + } + _set: { removed: $importId, active: false } + ) { + affected_rows + returning { + obj_id + obj_uid + obj_typ_id + } + } + update_service( + where: { + mgm_id: { _eq: $mgmId } + svc_uid: { _in: $removedSvcObjectUids } + removed: { _is_null: true } + } + _set: { removed: $importId, active: false } + ) { + affected_rows + returning { + svc_id + svc_uid + } + } + update_usr( + where: { + mgm_id: { _eq: $mgmId } + user_uid: { _in: $removedUserUids } + removed: { _is_null: true } + } + _set: { removed: $importId, active: false } + ) { + affected_rows + returning { + user_id + user_uid + } + } + update_zone( + where: { + mgm_id: { _eq: $mgmId } + zone_name: { _in: $removedZoneUids } + removed: { _is_null: true } + } + _set: { removed: $importId, active: false } + ) { + affected_rows + returning { + zone_id + zone_name + } + } + insert_object(objects: $newNwObjects) { + affected_rows + returning { + obj_id + obj_uid + obj_typ_id + } + } + insert_service(objects: $newSvcObjects) { + affected_rows + returning { + svc_id + svc_uid + } + } + insert_usr(objects: $newUsers) { + affected_rows + returning { + user_id + user_uid + } + } + insert_zone(objects: $newZones) { + affected_rows + returning { + zone_id + zone_name + } + } +} diff --git a/roles/lib/files/FWO.Api.Client/APIcalls/auth/addDeviceToTenant.graphql b/roles/common/files/fwo-api-calls/auth/addDeviceToTenant.graphql similarity index 87% rename from roles/lib/files/FWO.Api.Client/APIcalls/auth/addDeviceToTenant.graphql rename to roles/common/files/fwo-api-calls/auth/addDeviceToTenant.graphql index 0e3a2b3c08..62639ab886 100644 --- a/roles/lib/files/FWO.Api.Client/APIcalls/auth/addDeviceToTenant.graphql +++ b/roles/common/files/fwo-api-calls/auth/addDeviceToTenant.graphql @@ -9,7 +9,7 @@ mutation addDeviceToTenant( } ) { returning { - newId: device_id + insertedId: device_id } } } diff --git a/roles/lib/files/FWO.Api.Client/APIcalls/auth/addTenant.graphql b/roles/common/files/fwo-api-calls/auth/addTenant.graphql similarity index 80% rename from roles/lib/files/FWO.Api.Client/APIcalls/auth/addTenant.graphql rename to roles/common/files/fwo-api-calls/auth/addTenant.graphql index a0cf44b835..40dd1cb3c7 100644 --- a/roles/lib/files/FWO.Api.Client/APIcalls/auth/addTenant.graphql +++ b/roles/common/files/fwo-api-calls/auth/addTenant.graphql @@ -3,7 +3,6 @@ mutation addTenant( $project: String $comment: String $viewAllDevices: Boolean -# $superAdmin: Boolean $create: timestamp ) { insert_tenant( @@ -12,12 +11,11 @@ mutation addTenant( tenant_projekt: $project tenant_comment: $comment tenant_can_view_all_devices: $viewAllDevices -# tenant_is_superadmin: $superAdmin tenant_create: $create } ) { returning { - newId: tenant_id + newId: tenant_id } } } diff --git a/roles/common/files/fwo-api-calls/auth/addTenantNetwork.graphql b/roles/common/files/fwo-api-calls/auth/addTenantNetwork.graphql new file mode 100644 index 0000000000..2a77812bdb --- /dev/null +++ b/roles/common/files/fwo-api-calls/auth/addTenantNetwork.graphql @@ -0,0 +1,19 @@ +mutation addTenantNetwork( + $tenantId: Int! + $ip: cidr + $ipEnd: cidr + $name: String + $comment: String + ) { + insert_tenant_network(objects: { + tenant_id: $tenantId + tenant_net_ip: $ip + tenant_net_ip_end: $ipEnd + tenant_net_name: $name + tenant_net_comment: $comment + }) { + returning { + newIdLong: tenant_net_id + } + } +} diff --git a/roles/common/files/fwo-api-calls/auth/addTenantToGateway.graphql b/roles/common/files/fwo-api-calls/auth/addTenantToGateway.graphql new file mode 100644 index 0000000000..e39efba105 --- /dev/null +++ b/roles/common/files/fwo-api-calls/auth/addTenantToGateway.graphql @@ -0,0 +1,6 @@ +mutation addTenantToGateway($tenantId: Int!, $gwId: Int!, $shared: Boolean) { + insert_tenant_to_device(objects: {device_id: $gwId, shared: $shared, tenant_id: $tenantId}) + { + affected_rows + } +} diff --git a/roles/common/files/fwo-api-calls/auth/addTenantToManagement.graphql b/roles/common/files/fwo-api-calls/auth/addTenantToManagement.graphql new file mode 100644 index 0000000000..23ea252256 --- /dev/null +++ b/roles/common/files/fwo-api-calls/auth/addTenantToManagement.graphql @@ -0,0 +1,7 @@ + +mutation addTenantToManagement($tenantId: Int!, $mgmId: Int!, $shared: Boolean) { + insert_tenant_to_management(objects: {management_id: $mgmId, shared: $shared, tenant_id: $tenantId}) + { + affected_rows + } +} \ No newline at end of file diff --git a/roles/lib/files/FWO.Api.Client/APIcalls/auth/assertUserExists.graphql b/roles/common/files/fwo-api-calls/auth/assertUserExists.graphql similarity index 100% rename from roles/lib/files/FWO.Api.Client/APIcalls/auth/assertUserExists.graphql rename to roles/common/files/fwo-api-calls/auth/assertUserExists.graphql diff --git a/roles/common/files/fwo-api-calls/auth/deleteAllGatewaysOfTenant.graphql b/roles/common/files/fwo-api-calls/auth/deleteAllGatewaysOfTenant.graphql new file mode 100644 index 0000000000..bc8bf4a759 --- /dev/null +++ b/roles/common/files/fwo-api-calls/auth/deleteAllGatewaysOfTenant.graphql @@ -0,0 +1,7 @@ +mutation deleteAllGatewaysOfTenant($tenantId: Int!) { + delete_tenant_to_device(where: {tenant_id:{_eq:$tenantId}}) + { + affected_rows + } +} + diff --git a/roles/common/files/fwo-api-calls/auth/deleteAllManagementsOfTenant.graphql b/roles/common/files/fwo-api-calls/auth/deleteAllManagementsOfTenant.graphql new file mode 100644 index 0000000000..9f39ba746b --- /dev/null +++ b/roles/common/files/fwo-api-calls/auth/deleteAllManagementsOfTenant.graphql @@ -0,0 +1,7 @@ + +mutation deleteAllManagementsOfTenant($tenantId: Int!) { + delete_tenant_to_management(where: {tenant_id:{_eq:$tenantId}}) + { + affected_rows + } +} \ No newline at end of file diff --git a/roles/lib/files/FWO.Api.Client/APIcalls/auth/deleteLdapConnection.graphql b/roles/common/files/fwo-api-calls/auth/deleteLdapConnection.graphql similarity index 79% rename from roles/lib/files/FWO.Api.Client/APIcalls/auth/deleteLdapConnection.graphql rename to roles/common/files/fwo-api-calls/auth/deleteLdapConnection.graphql index ade2dea965..d7d5d29034 100644 --- a/roles/lib/files/FWO.Api.Client/APIcalls/auth/deleteLdapConnection.graphql +++ b/roles/common/files/fwo-api-calls/auth/deleteLdapConnection.graphql @@ -2,6 +2,6 @@ mutation delete_ldap_connection_by_pk ($id: bigint!) { delete_ldap_connection_by_pk ( ldap_connection_id: $id ) { - DeletedId: ldap_connection_id + deletedId: ldap_connection_id } } diff --git a/roles/lib/files/FWO.Api.Client/APIcalls/auth/deleteTenant.graphql b/roles/common/files/fwo-api-calls/auth/deleteTenant.graphql similarity index 79% rename from roles/lib/files/FWO.Api.Client/APIcalls/auth/deleteTenant.graphql rename to roles/common/files/fwo-api-calls/auth/deleteTenant.graphql index 95cff55d7b..7ce498035e 100644 --- a/roles/lib/files/FWO.Api.Client/APIcalls/auth/deleteTenant.graphql +++ b/roles/common/files/fwo-api-calls/auth/deleteTenant.graphql @@ -2,6 +2,6 @@ mutation delete_tenant_by_pk ($id: Int!) { delete_tenant_by_pk ( tenant_id: $id ) { - DeletedId: tenant_id + deletedId: tenant_id } } diff --git a/roles/common/files/fwo-api-calls/auth/deleteTenantNetwork.graphql b/roles/common/files/fwo-api-calls/auth/deleteTenantNetwork.graphql new file mode 100644 index 0000000000..67e022a17c --- /dev/null +++ b/roles/common/files/fwo-api-calls/auth/deleteTenantNetwork.graphql @@ -0,0 +1,8 @@ +mutation deleteTenantNetwork( + $tenantId: Int! + $tenNetId: bigint! + ) { + delete_tenant_network(where: {tenant_id: {_eq: $tenantId}, tenant_net_id: {_eq: $tenNetId}}) { + affected_rows + } +} diff --git a/roles/lib/files/FWO.Api.Client/APIcalls/auth/deleteUser.graphql b/roles/common/files/fwo-api-calls/auth/deleteUser.graphql similarity index 79% rename from roles/lib/files/FWO.Api.Client/APIcalls/auth/deleteUser.graphql rename to roles/common/files/fwo-api-calls/auth/deleteUser.graphql index bb1ae8d421..57374f351c 100644 --- a/roles/lib/files/FWO.Api.Client/APIcalls/auth/deleteUser.graphql +++ b/roles/common/files/fwo-api-calls/auth/deleteUser.graphql @@ -2,6 +2,6 @@ mutation delete_user_by_pk ($id: Int!) { delete_uiuser_by_pk ( uiuser_id: $id ) { - DeletedId: uiuser_id + deletedId: uiuser_id } } diff --git a/roles/lib/files/FWO.Api.Client/APIcalls/auth/getAllLdapConnections.graphql b/roles/common/files/fwo-api-calls/auth/getAllLdapConnections.graphql similarity index 95% rename from roles/lib/files/FWO.Api.Client/APIcalls/auth/getAllLdapConnections.graphql rename to roles/common/files/fwo-api-calls/auth/getAllLdapConnections.graphql index 0ad68acd34..4880b00d3b 100644 --- a/roles/lib/files/FWO.Api.Client/APIcalls/auth/getAllLdapConnections.graphql +++ b/roles/common/files/fwo-api-calls/auth/getAllLdapConnections.graphql @@ -16,6 +16,7 @@ query getAllLdapConnections { ldap_searchpath_for_users ldap_searchpath_for_roles ldap_searchpath_for_groups + ldap_writepath_for_groups ldap_write_user ldap_write_user_pwd tenant_id diff --git a/roles/common/files/fwo-api-calls/auth/getLdapConnectionForUserSearchById.graphql b/roles/common/files/fwo-api-calls/auth/getLdapConnectionForUserSearchById.graphql new file mode 100644 index 0000000000..4b7e0ec1ac --- /dev/null +++ b/roles/common/files/fwo-api-calls/auth/getLdapConnectionForUserSearchById.graphql @@ -0,0 +1,10 @@ +query getLdapConnectionForUserSearchById ($id: bigint!){ + ldap_connection_by_pk(ldap_connection_id: $id) { + ldap_server + ldap_port + ldap_tls + ldap_search_user + ldap_search_user_pwd + ldap_searchpath_for_users + } +} diff --git a/roles/common/files/fwo-api-calls/auth/getLdapConnections.graphql b/roles/common/files/fwo-api-calls/auth/getLdapConnections.graphql new file mode 100644 index 0000000000..b88dcce7b6 --- /dev/null +++ b/roles/common/files/fwo-api-calls/auth/getLdapConnections.graphql @@ -0,0 +1,28 @@ +# returns a list of all active ldap connections +# the field ldap_searchpath_for_roles is not null only for the internal ldap + +query getLdapConnections { + ldap_connection( + where: { active: { _eq: true } } + order_by: { ldap_connection_id: desc } + ) { + ldap_name + ldap_server + ldap_port + ldap_type + ldap_pattern_length + ldap_search_user + ldap_tls + ldap_tenant_level + ldap_connection_id + ldap_search_user_pwd + ldap_searchpath_for_users + ldap_searchpath_for_roles + ldap_searchpath_for_groups + ldap_writepath_for_groups + ldap_write_user + ldap_write_user_pwd + tenant_id + ldap_global_tenant_name + } +} diff --git a/roles/lib/files/FWO.Api.Client/APIcalls/auth/getLdapConnectionsSubscription.graphql b/roles/common/files/fwo-api-calls/auth/getLdapConnectionsSubscription.graphql similarity index 93% rename from roles/lib/files/FWO.Api.Client/APIcalls/auth/getLdapConnectionsSubscription.graphql rename to roles/common/files/fwo-api-calls/auth/getLdapConnectionsSubscription.graphql index 4187db8527..3d62cefeee 100644 --- a/roles/lib/files/FWO.Api.Client/APIcalls/auth/getLdapConnectionsSubscription.graphql +++ b/roles/common/files/fwo-api-calls/auth/getLdapConnectionsSubscription.graphql @@ -13,6 +13,7 @@ ldap_searchpath_for_users ldap_searchpath_for_roles ldap_searchpath_for_groups + ldap_writepath_for_groups ldap_write_user ldap_write_user_pwd tenant_id diff --git a/roles/lib/files/FWO.Api.Client/APIcalls/auth/getTenantId.graphql b/roles/common/files/fwo-api-calls/auth/getTenantId.graphql similarity index 100% rename from roles/lib/files/FWO.Api.Client/APIcalls/auth/getTenantId.graphql rename to roles/common/files/fwo-api-calls/auth/getTenantId.graphql diff --git a/roles/common/files/fwo-api-calls/auth/getTenantNetworks.graphql b/roles/common/files/fwo-api-calls/auth/getTenantNetworks.graphql new file mode 100644 index 0000000000..1bed9d2e43 --- /dev/null +++ b/roles/common/files/fwo-api-calls/auth/getTenantNetworks.graphql @@ -0,0 +1,10 @@ + +query getTenantNetworks ($tenantId: Int!) { + tenant_network (where: {tenant_id: {_eq: $tenantId}} order_by: { tenant_net_id: asc }){ + id: tenant_net_id + ip: tenant_net_ip + ip_end: tenant_net_ip_end + name: tenant_net_name + comment: tenant_net_comment + } +} diff --git a/roles/lib/files/FWO.Api.Client/APIcalls/auth/getVisibleDeviceIdsPerTenant.graphql b/roles/common/files/fwo-api-calls/auth/getTenantVisibleDeviceIds.graphql similarity index 100% rename from roles/lib/files/FWO.Api.Client/APIcalls/auth/getVisibleDeviceIdsPerTenant.graphql rename to roles/common/files/fwo-api-calls/auth/getTenantVisibleDeviceIds.graphql diff --git a/roles/common/files/fwo-api-calls/auth/getTenantVisibleManagementIds.graphql b/roles/common/files/fwo-api-calls/auth/getTenantVisibleManagementIds.graphql new file mode 100644 index 0000000000..02eb7836e9 --- /dev/null +++ b/roles/common/files/fwo-api-calls/auth/getTenantVisibleManagementIds.graphql @@ -0,0 +1,2 @@ +query getVisibleManagementIdsPerTenant($tenantId: Int!) { + visibleManagements: get_visible_managements_per_tenant(args: {arg_1: $tenantId}) { id } } \ No newline at end of file diff --git a/roles/common/files/fwo-api-calls/auth/getTenants.graphql b/roles/common/files/fwo-api-calls/auth/getTenants.graphql new file mode 100644 index 0000000000..f2ba721ee4 --- /dev/null +++ b/roles/common/files/fwo-api-calls/auth/getTenants.graphql @@ -0,0 +1,29 @@ +query getTenants($tenant_id: Int) { + tenant(where:{tenant_id:{_eq: $tenant_id}}) { + tenant_id + tenant_name + tenant_comment + tenant_projekt + tenant_can_view_all_devices + tenant_is_superadmin + + tenant_to_devices { + shared + device { + id: dev_id + name: dev_name + } + } + tenant_to_managements { + shared + management { + id: mgm_id + name: mgm_name + devices { + id: dev_id + name: dev_name + } + } + } + } +} diff --git a/roles/lib/files/FWO.Api.Client/APIcalls/auth/getUserByDbId.graphql b/roles/common/files/fwo-api-calls/auth/getUserByDbId.graphql similarity index 85% rename from roles/lib/files/FWO.Api.Client/APIcalls/auth/getUserByDbId.graphql rename to roles/common/files/fwo-api-calls/auth/getUserByDbId.graphql index 29670ef2ac..103382e821 100644 --- a/roles/lib/files/FWO.Api.Client/APIcalls/auth/getUserByDbId.graphql +++ b/roles/common/files/fwo-api-calls/auth/getUserByDbId.graphql @@ -6,6 +6,8 @@ query getUserByDbId($userId: Int!) { uiuser_language uiuser_password_must_be_changed uiuser_email + uiuser_first_name + uiuser_last_name uiuser_last_login uiuser_last_password_change } diff --git a/roles/lib/files/FWO.Api.Client/APIcalls/auth/getUserByDn.graphql b/roles/common/files/fwo-api-calls/auth/getUserByDn.graphql similarity index 82% rename from roles/lib/files/FWO.Api.Client/APIcalls/auth/getUserByDn.graphql rename to roles/common/files/fwo-api-calls/auth/getUserByDn.graphql index 82415550a0..1ef2bc795f 100644 --- a/roles/lib/files/FWO.Api.Client/APIcalls/auth/getUserByDn.graphql +++ b/roles/common/files/fwo-api-calls/auth/getUserByDn.graphql @@ -4,6 +4,8 @@ query getUserByDn($dn: String!) { uuid uiuser_username uiuser_email + uiuser_first_name + uiuser_last_name uiuser_language uiuser_password_must_be_changed } diff --git a/roles/common/files/fwo-api-calls/auth/getUserEmails.graphql b/roles/common/files/fwo-api-calls/auth/getUserEmails.graphql new file mode 100644 index 0000000000..f4e3e760bc --- /dev/null +++ b/roles/common/files/fwo-api-calls/auth/getUserEmails.graphql @@ -0,0 +1,10 @@ +query getUserEmails ($uuid: String){ + uiuser(where:{uuid:{_eq:$uuid}}) { + uiuser_id + uuid + uiuser_username + uiuser_email + uiuser_first_name + uiuser_last_name + } +} diff --git a/roles/lib/files/FWO.Api.Client/APIcalls/auth/getUsers.graphql b/roles/common/files/fwo-api-calls/auth/getUsers.graphql similarity index 90% rename from roles/lib/files/FWO.Api.Client/APIcalls/auth/getUsers.graphql rename to roles/common/files/fwo-api-calls/auth/getUsers.graphql index 030b1ffb7a..da4a81b847 100644 --- a/roles/lib/files/FWO.Api.Client/APIcalls/auth/getUsers.graphql +++ b/roles/common/files/fwo-api-calls/auth/getUsers.graphql @@ -4,6 +4,8 @@ query getUsers{ uuid uiuser_username uiuser_email + uiuser_first_name + uiuser_last_name tenant{ tenant_id tenant_name diff --git a/roles/lib/files/FWO.Api.Client/APIcalls/auth/getVisibleManagementIdsPerTenant.graphql b/roles/common/files/fwo-api-calls/auth/getVisibleManagementIdsPerTenant.graphql similarity index 100% rename from roles/lib/files/FWO.Api.Client/APIcalls/auth/getVisibleManagementIdsPerTenant.graphql rename to roles/common/files/fwo-api-calls/auth/getVisibleManagementIdsPerTenant.graphql diff --git a/roles/lib/files/FWO.Api.Client/APIcalls/auth/newLdapConnection.graphql b/roles/common/files/fwo-api-calls/auth/newLdapConnection.graphql similarity index 93% rename from roles/lib/files/FWO.Api.Client/APIcalls/auth/newLdapConnection.graphql rename to roles/common/files/fwo-api-calls/auth/newLdapConnection.graphql index 830b7e3124..ddb25563c4 100644 --- a/roles/lib/files/FWO.Api.Client/APIcalls/auth/newLdapConnection.graphql +++ b/roles/common/files/fwo-api-calls/auth/newLdapConnection.graphql @@ -11,6 +11,7 @@ mutation newLdapConnection( $searchpathForUsers: String! $searchpathForRoles: String $searchpathForGroups: String + $writepathForGroups: String $writeUser: String $writeUserPwd: String $tenantId: Int @@ -31,6 +32,7 @@ mutation newLdapConnection( ldap_searchpath_for_users: $searchpathForUsers ldap_searchpath_for_roles: $searchpathForRoles ldap_searchpath_for_groups: $searchpathForGroups + ldap_writepath_for_groups: $writepathForGroups ldap_write_user: $writeUser ldap_write_user_pwd: $writeUserPwd tenant_id: $tenantId diff --git a/roles/lib/files/FWO.Api.Client/APIcalls/auth/updateLdapConnection.graphql b/roles/common/files/fwo-api-calls/auth/updateLdapConnection.graphql similarity index 91% rename from roles/lib/files/FWO.Api.Client/APIcalls/auth/updateLdapConnection.graphql rename to roles/common/files/fwo-api-calls/auth/updateLdapConnection.graphql index cbfe56cf5a..a673a61a2d 100644 --- a/roles/lib/files/FWO.Api.Client/APIcalls/auth/updateLdapConnection.graphql +++ b/roles/common/files/fwo-api-calls/auth/updateLdapConnection.graphql @@ -12,6 +12,7 @@ mutation updateLdapConnection( $searchpathForUsers: String! $searchpathForRoles: String $searchpathForGroups: String + $writepathForGroups: String $writeUser: String $writeUserPwd: String $tenantId: Int @@ -33,6 +34,7 @@ mutation updateLdapConnection( ldap_searchpath_for_users: $searchpathForUsers ldap_searchpath_for_roles: $searchpathForRoles ldap_searchpath_for_groups: $searchpathForGroups + ldap_writepath_for_groups: $writepathForGroups ldap_write_user: $writeUser ldap_write_user_pwd: $writeUserPwd tenant_id: $tenantId @@ -40,7 +42,7 @@ mutation updateLdapConnection( active: $active } ) { - UpdatedId: ldap_connection_id + updatedId: ldap_connection_id } } diff --git a/roles/lib/files/FWO.Api.Client/APIcalls/auth/updateTenant.graphql b/roles/common/files/fwo-api-calls/auth/updateTenant.graphql similarity index 92% rename from roles/lib/files/FWO.Api.Client/APIcalls/auth/updateTenant.graphql rename to roles/common/files/fwo-api-calls/auth/updateTenant.graphql index 1069f0dc45..5bc33dacba 100644 --- a/roles/lib/files/FWO.Api.Client/APIcalls/auth/updateTenant.graphql +++ b/roles/common/files/fwo-api-calls/auth/updateTenant.graphql @@ -12,6 +12,6 @@ mutation updateTenant( tenant_can_view_all_devices: $viewAllDevices } ) { - UpdatedId: tenant_id + updatedId: tenant_id } } diff --git a/roles/lib/files/FWO.Api.Client/APIcalls/auth/updateUserEmail.graphql b/roles/common/files/fwo-api-calls/auth/updateUserEmail.graphql similarity index 87% rename from roles/lib/files/FWO.Api.Client/APIcalls/auth/updateUserEmail.graphql rename to roles/common/files/fwo-api-calls/auth/updateUserEmail.graphql index 8d51fc32f4..6738e6fb53 100644 --- a/roles/lib/files/FWO.Api.Client/APIcalls/auth/updateUserEmail.graphql +++ b/roles/common/files/fwo-api-calls/auth/updateUserEmail.graphql @@ -8,6 +8,6 @@ mutation updateUserEmail( uiuser_email: $email } ) { - UpdatedId: uiuser_id + updatedId: uiuser_id } } diff --git a/roles/lib/files/FWO.Api.Client/APIcalls/auth/updateUserLanguage.graphql b/roles/common/files/fwo-api-calls/auth/updateUserLanguage.graphql similarity index 88% rename from roles/lib/files/FWO.Api.Client/APIcalls/auth/updateUserLanguage.graphql rename to roles/common/files/fwo-api-calls/auth/updateUserLanguage.graphql index 3a1e4bf917..913744e830 100644 --- a/roles/lib/files/FWO.Api.Client/APIcalls/auth/updateUserLanguage.graphql +++ b/roles/common/files/fwo-api-calls/auth/updateUserLanguage.graphql @@ -8,6 +8,6 @@ mutation updateUserLanguage( uiuser_language: $language } ) { - UpdatedId: uiuser_id + updatedId: uiuser_id } } diff --git a/roles/lib/files/FWO.Api.Client/APIcalls/auth/updateUserLastLogin.graphql b/roles/common/files/fwo-api-calls/auth/updateUserLastLogin.graphql similarity index 100% rename from roles/lib/files/FWO.Api.Client/APIcalls/auth/updateUserLastLogin.graphql rename to roles/common/files/fwo-api-calls/auth/updateUserLastLogin.graphql diff --git a/roles/lib/files/FWO.Api.Client/APIcalls/auth/updateUserPasswordChange.graphql b/roles/common/files/fwo-api-calls/auth/updateUserPasswordChange.graphql similarity index 100% rename from roles/lib/files/FWO.Api.Client/APIcalls/auth/updateUserPasswordChange.graphql rename to roles/common/files/fwo-api-calls/auth/updateUserPasswordChange.graphql diff --git a/roles/common/files/fwo-api-calls/auth/upsertUiUser.graphql b/roles/common/files/fwo-api-calls/auth/upsertUiUser.graphql new file mode 100644 index 0000000000..82307bb7ef --- /dev/null +++ b/roles/common/files/fwo-api-calls/auth/upsertUiUser.graphql @@ -0,0 +1,41 @@ +mutation upsertUiUser( + $uiuser_username: String! + $uuid: String! + $email: String + $uiuser_first_name: String + $uiuser_last_name: String + $tenant: Int + $loginTime: timestamptz + $passwordMustBeChanged: Boolean + $ldapConnectionId: bigint +) { + insert_uiuser( + objects: { + uiuser_username: $uiuser_username + uuid: $uuid + uiuser_email: $email + uiuser_first_name: $uiuser_first_name + uiuser_last_name: $uiuser_last_name + tenant_id: $tenant + uiuser_last_login: $loginTime + uiuser_password_must_be_changed: $passwordMustBeChanged + ldap_connection_id: $ldapConnectionId + } + on_conflict: { + constraint: uiuser_uuid_key + update_columns: [ + uiuser_email + uiuser_first_name + uiuser_last_name + tenant_id + uiuser_last_login + uiuser_password_must_be_changed + ldap_connection_id + ] + } + ) { + returning { + newId: uiuser_id + } + } +} diff --git a/roles/common/files/fwo-api-calls/compliance/addCritToPolicy.graphql b/roles/common/files/fwo-api-calls/compliance/addCritToPolicy.graphql new file mode 100644 index 0000000000..eb463cc01a --- /dev/null +++ b/roles/common/files/fwo-api-calls/compliance/addCritToPolicy.graphql @@ -0,0 +1,13 @@ +mutation addCritToPolicy( + $policyId: Int! + $criterionId: Int! + ) { + insert_compliance_policy_criterion(objects: { + policy_id: $policyId + criterion_id: $criterionId + }) { + returning { + insertedId: criterion_id + } + } +} diff --git a/roles/common/files/fwo-api-calls/compliance/addCriterion.graphql b/roles/common/files/fwo-api-calls/compliance/addCriterion.graphql new file mode 100644 index 0000000000..e931cadc8f --- /dev/null +++ b/roles/common/files/fwo-api-calls/compliance/addCriterion.graphql @@ -0,0 +1,19 @@ +mutation addCriterion( + $name: String! + $criterionType: String! + $content: String + $comment: String + $importSource: String + ) { + insert_compliance_criterion(objects: { + name: $name + criterion_type: $criterionType + content: $content + comment: $comment + import_source: $importSource + }) { + returning { + insertedId: id + } + } +} diff --git a/roles/common/files/fwo-api-calls/compliance/addNetworkZone.graphql b/roles/common/files/fwo-api-calls/compliance/addNetworkZone.graphql new file mode 100644 index 0000000000..19b5497253 --- /dev/null +++ b/roles/common/files/fwo-api-calls/compliance/addNetworkZone.graphql @@ -0,0 +1,39 @@ +mutation addNetworkZone ( + $name: String! + $description: String! + $idString: String! + $ipRanges: [compliance_ip_range_insert_input!]! + $superNetworkZoneId: bigint + $communicationSources: [compliance_network_zone_communication_insert_input!]! + $communicationDestinations: [compliance_network_zone_communication_insert_input!]! + $subNetworkZones: [compliance_network_zone_insert_input!]! + $criterionId: Int + $isAutoCalculatedInternetZone: Boolean + $isAutoCalculatedUndefinedInternalZone: Boolean +) { + insert_compliance_network_zone_one ( + object: { + super_network_zone_id: $superNetworkZoneId, + name: $name, + id_string: $idString, + description: $description, + ip_ranges: { + data: $ipRanges + }, + network_zone_communication_destinations: { + data: $communicationDestinations + }, + network_zone_communication_sources: { + data: $communicationSources + }, + sub_network_zones: { + data: $subNetworkZones + }, + criterion_id: $criterionId, + is_auto_calculated_internet_zone: $isAutoCalculatedInternetZone, + is_auto_calculated_undefined_internal_zone: $isAutoCalculatedUndefinedInternalZone + } + ) { + id + } +} \ No newline at end of file diff --git a/roles/common/files/fwo-api-calls/compliance/addPolicy.graphql b/roles/common/files/fwo-api-calls/compliance/addPolicy.graphql new file mode 100644 index 0000000000..15050a9796 --- /dev/null +++ b/roles/common/files/fwo-api-calls/compliance/addPolicy.graphql @@ -0,0 +1,12 @@ +mutation addPolicy( + $name: String! + ) { + insert_compliance_policy(objects: { + name: $name + disabled: false + }) { + returning { + insertedId: id + } + } +} diff --git a/roles/common/files/fwo-api-calls/compliance/addViolations.graphql b/roles/common/files/fwo-api-calls/compliance/addViolations.graphql new file mode 100644 index 0000000000..b1ef39eb49 --- /dev/null +++ b/roles/common/files/fwo-api-calls/compliance/addViolations.graphql @@ -0,0 +1,10 @@ +mutation addViolations($violations: [compliance_violation_insert_input!]!) { + insert_compliance_violation( + objects: $violations + ) { + affected_rows + returning { id } + + } +} + diff --git a/roles/common/files/fwo-api-calls/compliance/deleteAllViolations.graphql b/roles/common/files/fwo-api-calls/compliance/deleteAllViolations.graphql new file mode 100644 index 0000000000..fa152961de --- /dev/null +++ b/roles/common/files/fwo-api-calls/compliance/deleteAllViolations.graphql @@ -0,0 +1,7 @@ +mutation deleteAllViolations { + delete_compliance_violation( + where: { } + ) { + affected_rows + } +} \ No newline at end of file diff --git a/roles/common/files/fwo-api-calls/compliance/disablePolicy.graphql b/roles/common/files/fwo-api-calls/compliance/disablePolicy.graphql new file mode 100644 index 0000000000..42bf67dd6d --- /dev/null +++ b/roles/common/files/fwo-api-calls/compliance/disablePolicy.graphql @@ -0,0 +1,11 @@ +mutation disablePolicy( + $id: Int! +) { + update_compliance_policy_by_pk( + pk_columns: { id: $id } + _set: { + disabled: true + }) { + updatedId: id + } +} diff --git a/roles/common/files/fwo-api-calls/compliance/getCriteria.graphql b/roles/common/files/fwo-api-calls/compliance/getCriteria.graphql new file mode 100644 index 0000000000..aca9380197 --- /dev/null +++ b/roles/common/files/fwo-api-calls/compliance/getCriteria.graphql @@ -0,0 +1,9 @@ +query getCriteria { + compliance_criterion (where: { removed: {_is_null: true} }){ + id + name + criterion_type + content + comment + } +} diff --git a/roles/common/files/fwo-api-calls/compliance/getMatrices.graphql b/roles/common/files/fwo-api-calls/compliance/getMatrices.graphql new file mode 100644 index 0000000000..d51218d040 --- /dev/null +++ b/roles/common/files/fwo-api-calls/compliance/getMatrices.graphql @@ -0,0 +1,7 @@ +query getMatrices { + compliance_criterion (where: { criterion_type: {_eq: "Matrix"}, removed: {_is_null: true} }){ + id + name + import_source + } +} diff --git a/roles/common/files/fwo-api-calls/compliance/getMatrixByName.graphql b/roles/common/files/fwo-api-calls/compliance/getMatrixByName.graphql new file mode 100644 index 0000000000..44cad88176 --- /dev/null +++ b/roles/common/files/fwo-api-calls/compliance/getMatrixByName.graphql @@ -0,0 +1,8 @@ +query getMatrixByName ($name: String!){ + compliance_criterion (where: { criterion_type: {_eq: "Matrix"}, name: {_eq: $name}, removed: {_is_null: true} }){ + id + name + comment + import_source + } +} diff --git a/roles/common/files/fwo-api-calls/compliance/getNetworkZonesForMatrix.graphql b/roles/common/files/fwo-api-calls/compliance/getNetworkZonesForMatrix.graphql new file mode 100644 index 0000000000..83966c94ce --- /dev/null +++ b/roles/common/files/fwo-api-calls/compliance/getNetworkZonesForMatrix.graphql @@ -0,0 +1,35 @@ +query getNetworkZonesForMatrix ($criterionId: Int!){ + compliance_network_zone (where: { criterion_id: {_eq: $criterionId}, removed: {_is_null: true} } order_by: {name: asc}) { + id + name + description + criterion_id + id_string + ip_ranges (where: { removed: {_is_null: true} }){ + ip_range_start + ip_range_end + } + super_network_zone { + id + name + } + sub_network_zones (where: { removed: {_is_null: true} }){ + id + name + } + network_zone_communication_destinations (where: { criterion_id: {_eq: $criterionId}, removed: {_is_null: true} }){ + to_network_zone { + id + name + } + } + network_zone_communication_sources (where: { criterion_id: {_eq: $criterionId}, removed: {_is_null: true} }){ + from_network_zone { + id + name + } + } + is_auto_calculated_internet_zone + is_auto_calculated_undefined_internal_zone + } +} diff --git a/roles/common/files/fwo-api-calls/compliance/getPolicies.graphql b/roles/common/files/fwo-api-calls/compliance/getPolicies.graphql new file mode 100644 index 0000000000..eaefb6911a --- /dev/null +++ b/roles/common/files/fwo-api-calls/compliance/getPolicies.graphql @@ -0,0 +1,17 @@ +query getPolicies { + compliance_policy(where: {disabled: {_eq: false}}) { + id + name + created_date + disabled + criteria: policy_criterions (where: {removed: {_is_null: true}}) { + criterion: criterion { + content + criterion_type + id + name + } + } + } +} + diff --git a/roles/common/files/fwo-api-calls/compliance/getPolicyById.graphql b/roles/common/files/fwo-api-calls/compliance/getPolicyById.graphql new file mode 100644 index 0000000000..e5b2c51d4b --- /dev/null +++ b/roles/common/files/fwo-api-calls/compliance/getPolicyById.graphql @@ -0,0 +1,16 @@ +query getPolicyById($id: Int!) { + compliance_policy_by_pk(id: $id) { + id + name + created_date + disabled + criteria: policy_criterions(where: { removed: { _is_null: true } }) { + criterion: criterion { + content + criterion_type + id + name + } + } + } +} diff --git a/roles/common/files/fwo-api-calls/compliance/getPolicyIdsForCrit.graphql b/roles/common/files/fwo-api-calls/compliance/getPolicyIdsForCrit.graphql new file mode 100644 index 0000000000..a8fc52e861 --- /dev/null +++ b/roles/common/files/fwo-api-calls/compliance/getPolicyIdsForCrit.graphql @@ -0,0 +1,10 @@ +query getPolicyIdsForCrit ($critId: Int!){ + compliance_policy_criterion(where: { + removed: {_is_null: true} + criterion_id: { _eq: $critId } + }) { + criterion_id + policy_id + } +} + \ No newline at end of file diff --git a/roles/common/files/fwo-api-calls/compliance/getViolationCount.graphql b/roles/common/files/fwo-api-calls/compliance/getViolationCount.graphql new file mode 100644 index 0000000000..a3c0797993 --- /dev/null +++ b/roles/common/files/fwo-api-calls/compliance/getViolationCount.graphql @@ -0,0 +1,7 @@ +query getViolationsCount { + compliance_violation_aggregate { + aggregate { + count + } + } +} diff --git a/roles/common/files/fwo-api-calls/compliance/getViolations.graphql b/roles/common/files/fwo-api-calls/compliance/getViolations.graphql new file mode 100644 index 0000000000..a321e27702 --- /dev/null +++ b/roles/common/files/fwo-api-calls/compliance/getViolations.graphql @@ -0,0 +1,14 @@ +query getViolations { + compliance_violation { + id + criterion_id + details + found_date + policy_id + removed_date + risk_score + rule_id + rule_uid + mgmt_uid + } +} diff --git a/roles/common/files/fwo-api-calls/compliance/getViolationsByRuleID.graphql b/roles/common/files/fwo-api-calls/compliance/getViolationsByRuleID.graphql new file mode 100644 index 0000000000..4e4b9b9a4d --- /dev/null +++ b/roles/common/files/fwo-api-calls/compliance/getViolationsByRuleID.graphql @@ -0,0 +1,12 @@ +query getViolationsByRuleID($ruleId: bigint) { + compliance_violation(where: { rule_id: { _eq: $ruleId } }) { + id + criterion_id + details + found_date + policy_id + removed_date + risk_score + rule_id + } +} diff --git a/roles/common/files/fwo-api-calls/compliance/getViolationsByRuleUid.graphql b/roles/common/files/fwo-api-calls/compliance/getViolationsByRuleUid.graphql new file mode 100644 index 0000000000..71dc7bad3e --- /dev/null +++ b/roles/common/files/fwo-api-calls/compliance/getViolationsByRuleUid.graphql @@ -0,0 +1,14 @@ +query getViolationsByRuleID($ruleUid: String, $mgmtUid: String) { + compliance_violation(where: {rule_uid: {_eq: $ruleUid} mgmt_uid: {_eq: $mgmtUid}}) { + id + criterion_id + details + found_date + policy_id + removed_date + risk_score + rule_id + rule_uid + mgmt_uid + } +} diff --git a/roles/common/files/fwo-api-calls/compliance/getViolationsChunk.graphql b/roles/common/files/fwo-api-calls/compliance/getViolationsChunk.graphql new file mode 100644 index 0000000000..eae15ac5aa --- /dev/null +++ b/roles/common/files/fwo-api-calls/compliance/getViolationsChunk.graphql @@ -0,0 +1,12 @@ +query getViolationsChunk($limit: Int, $offset: Int, $active: Boolean) { + compliance_violation(limit: $limit, offset: $offset, order_by: { id: asc }) { + id + criterion_id + details + found_date + policy_id + removed_date + risk_score + rule_id + } +} \ No newline at end of file diff --git a/roles/common/files/fwo-api-calls/compliance/removeCritFromPolicy.graphql b/roles/common/files/fwo-api-calls/compliance/removeCritFromPolicy.graphql new file mode 100644 index 0000000000..b93806eff3 --- /dev/null +++ b/roles/common/files/fwo-api-calls/compliance/removeCritFromPolicy.graphql @@ -0,0 +1,17 @@ +mutation removeCritFromPolicy( + $policyId: Int! + $criterionId: Int! + $removed: timestamptz +) { + update_compliance_policy_criterion( + where: { + policy_id: {_eq: $policyId} + criterion_id: {_eq: $criterionId} + removed: {_is_null: true} + } + _set: { + removed: $removed + }) { + affected_rows + } +} diff --git a/roles/common/files/fwo-api-calls/compliance/removeCriterion.graphql b/roles/common/files/fwo-api-calls/compliance/removeCriterion.graphql new file mode 100644 index 0000000000..d172e7ecd3 --- /dev/null +++ b/roles/common/files/fwo-api-calls/compliance/removeCriterion.graphql @@ -0,0 +1,12 @@ +mutation removeCriterion( + $id: Int! + $removed: timestamptz +) { + update_compliance_criterion_by_pk( + pk_columns: { id: $id } + _set: { + removed: $removed + }) { + updatedId: id + } +} diff --git a/roles/common/files/fwo-api-calls/compliance/removeNetworkZone.graphql b/roles/common/files/fwo-api-calls/compliance/removeNetworkZone.graphql new file mode 100644 index 0000000000..cbd00d8167 --- /dev/null +++ b/roles/common/files/fwo-api-calls/compliance/removeNetworkZone.graphql @@ -0,0 +1,39 @@ +mutation removeNetworkZone ( + $id: bigint! + $removed: timestamptz + $deleteIpRangesExp: [compliance_ip_range_bool_exp!]! + $deleteZoneCommunicationExp: [compliance_network_zone_communication_bool_exp!]! +) { + update_compliance_network_zone_by_pk ( + pk_columns: { id: $id } + _set: { + removed: $removed + }) { + updatedId: id + } + + update_compliance_ip_range ( + where: { + network_zone_id: {_eq: $id}, + _or: $deleteIpRangesExp + removed: {_is_null: true} + } + _set: { + removed: $removed + } + ) { + affected_rows + } + + update_compliance_network_zone_communication ( + where: { + _or: $deleteZoneCommunicationExp + removed: {_is_null: true} + }, + _set: { + removed: $removed + } + ) { + affected_rows + } +} diff --git a/roles/common/files/fwo-api-calls/compliance/removeViolations.graphql b/roles/common/files/fwo-api-calls/compliance/removeViolations.graphql new file mode 100644 index 0000000000..13672a27bd --- /dev/null +++ b/roles/common/files/fwo-api-calls/compliance/removeViolations.graphql @@ -0,0 +1,8 @@ +mutation removeViolations($ids: [bigint!]!, $removedAt: timestamptz!) { + update_compliance_violation( + where: { id: { _in: $ids } }, + _set: { removed_date: $removedAt } + ) { + affected_rows + } +} diff --git a/roles/common/files/fwo-api-calls/compliance/updateCriterionMetadata.graphql b/roles/common/files/fwo-api-calls/compliance/updateCriterionMetadata.graphql new file mode 100644 index 0000000000..4b39d6935c --- /dev/null +++ b/roles/common/files/fwo-api-calls/compliance/updateCriterionMetadata.graphql @@ -0,0 +1,15 @@ +mutation updateCriterionMetadata( + $id: Int! + $importSource: String + $comment: String + ) { + update_compliance_criterion_by_pk( + pk_columns: { id: $id }, + _set: { + comment: $comment + import_source: $importSource + } + ) { + id + } +} diff --git a/roles/common/files/fwo-api-calls/compliance/updateNetworkZone.graphql b/roles/common/files/fwo-api-calls/compliance/updateNetworkZone.graphql new file mode 100644 index 0000000000..1cbc0d8e0d --- /dev/null +++ b/roles/common/files/fwo-api-calls/compliance/updateNetworkZone.graphql @@ -0,0 +1,87 @@ +mutation updateNetworkZone ( + $networkZoneId: bigint! + $name: String! + $description: String! + $superNetworkZoneId: bigint + $addIpRanges: [compliance_ip_range_insert_input!]! + $deleteIpRangesExp: [compliance_ip_range_bool_exp!]! + $addZoneCommunication: [compliance_network_zone_communication_insert_input!]! + $deleteZoneCommunicationExp: [compliance_network_zone_communication_bool_exp!]! + $addSubZonesExp: [compliance_network_zone_bool_exp!]! + $deleteSubZonesExp: [compliance_network_zone_bool_exp!]! + $removed: timestamptz + $isAutoCalculatedInternetZone: Boolean) +{ + update_compliance_network_zone ( + where: {id: {_eq: $networkZoneId}} + _set: { + name: $name, + description: $description, + super_network_zone_id: $superNetworkZoneId, + is_auto_calculated_internet_zone: $isAutoCalculatedInternetZone + } + ) { + affected_rows + } + + update_compliance_ip_range ( + where: { + network_zone_id: {_eq: $networkZoneId}, + _or: $deleteIpRangesExp + removed: {_is_null: true} + } + _set: { + removed: $removed + } + ) { + affected_rows + } + + insert_compliance_ip_range ( + objects: $addIpRanges + ) { + affected_rows + } + + update_compliance_network_zone_communication ( + where: { + _or: $deleteZoneCommunicationExp + removed: {_is_null: true} + }, + _set: { + removed: $removed + } + ) { + affected_rows + } + + insert_compliance_network_zone_communication ( + objects: $addZoneCommunication + ) { + affected_rows + } + + update_compliance_network_zone_many ( + updates: [ + { + where: { + _or: $deleteSubZonesExp + removed: {_is_null: true} + } + _set: { + super_network_zone_id: null + } + }, + { + where: { + _or: $addSubZonesExp + } + _set: { + super_network_zone_id: $networkZoneId + } + } + ] + ) { + affected_rows + } +} \ No newline at end of file diff --git a/roles/common/files/fwo-api-calls/compliance/updateNetworkZoneCommunication.graphql b/roles/common/files/fwo-api-calls/compliance/updateNetworkZoneCommunication.graphql new file mode 100644 index 0000000000..4d550b9a6c --- /dev/null +++ b/roles/common/files/fwo-api-calls/compliance/updateNetworkZoneCommunication.graphql @@ -0,0 +1,24 @@ +mutation updateNetworkZoneCommunication( + $deleteZoneCommunicationExp: [compliance_network_zone_communication_bool_exp!]! + $addZoneCommunication: [compliance_network_zone_communication_insert_input!]! + $removed: timestamptz +) +{ + update_compliance_network_zone_communication ( + where: { + _or: $deleteZoneCommunicationExp + removed: {_is_null: true} + }, + _set: { + removed: $removed + } + ) { + affected_rows + } + + insert_compliance_network_zone_communication ( + objects: $addZoneCommunication + ) { + affected_rows + } +} diff --git a/roles/common/files/fwo-api-calls/compliance/updateViolationById.graphql b/roles/common/files/fwo-api-calls/compliance/updateViolationById.graphql new file mode 100644 index 0000000000..28d4fe9f0a --- /dev/null +++ b/roles/common/files/fwo-api-calls/compliance/updateViolationById.graphql @@ -0,0 +1,8 @@ +mutation updateViolation($id: bigint!, $changes: compliance_violation_set_input!) { + update_compliance_violation_by_pk( + pk_columns: { id: $id }, + _set: $changes + ) { + id + } +} diff --git a/roles/lib/files/FWO.Api.Client/APIcalls/config/addConfigItem.graphql b/roles/common/files/fwo-api-calls/config/addConfigItem.graphql similarity index 89% rename from roles/lib/files/FWO.Api.Client/APIcalls/config/addConfigItem.graphql rename to roles/common/files/fwo-api-calls/config/addConfigItem.graphql index f7e4752e82..a1835b7bd4 100644 --- a/roles/lib/files/FWO.Api.Client/APIcalls/config/addConfigItem.graphql +++ b/roles/common/files/fwo-api-calls/config/addConfigItem.graphql @@ -11,7 +11,7 @@ mutation addConfigItem( } ) { returning { - newId: config_key + newId: config_key } } } diff --git a/roles/common/files/fwo-api-calls/config/deleteCustomText.graphql b/roles/common/files/fwo-api-calls/config/deleteCustomText.graphql new file mode 100644 index 0000000000..cf54d22d83 --- /dev/null +++ b/roles/common/files/fwo-api-calls/config/deleteCustomText.graphql @@ -0,0 +1,8 @@ +mutation delete_customtxt_by_pk ($id: String!, $lang: String!) { + delete_customtxt_by_pk ( + id: $id + language: $lang + ) { + deletedId: id + } +} diff --git a/roles/lib/files/FWO.Api.Client/APIcalls/config/getConfigItemByKey.graphql b/roles/common/files/fwo-api-calls/config/getConfigItemByKey.graphql similarity index 100% rename from roles/lib/files/FWO.Api.Client/APIcalls/config/getConfigItemByKey.graphql rename to roles/common/files/fwo-api-calls/config/getConfigItemByKey.graphql diff --git a/roles/lib/files/FWO.Api.Client/APIcalls/config/getConfigItemsByUser.graphql b/roles/common/files/fwo-api-calls/config/getConfigItemsByUser.graphql similarity index 98% rename from roles/lib/files/FWO.Api.Client/APIcalls/config/getConfigItemsByUser.graphql rename to roles/common/files/fwo-api-calls/config/getConfigItemsByUser.graphql index 0c1f475864..4ce351abbe 100644 --- a/roles/lib/files/FWO.Api.Client/APIcalls/config/getConfigItemsByUser.graphql +++ b/roles/common/files/fwo-api-calls/config/getConfigItemsByUser.graphql @@ -3,4 +3,4 @@ query getConfigItemsByUser($user: Int) { config_key config_value } -} \ No newline at end of file +} diff --git a/roles/common/files/fwo-api-calls/config/getConfigValue.graphql b/roles/common/files/fwo-api-calls/config/getConfigValue.graphql new file mode 100644 index 0000000000..ea6a4126f4 --- /dev/null +++ b/roles/common/files/fwo-api-calls/config/getConfigValue.graphql @@ -0,0 +1,5 @@ +query getConfigValue($key: String) { + config(where: {config_key: {_eq: $key}}) { + config_value + } +} diff --git a/roles/common/files/fwo-api-calls/config/getConfigValuesByKeyFilter.graphql b/roles/common/files/fwo-api-calls/config/getConfigValuesByKeyFilter.graphql new file mode 100644 index 0000000000..dc95fae647 --- /dev/null +++ b/roles/common/files/fwo-api-calls/config/getConfigValuesByKeyFilter.graphql @@ -0,0 +1,5 @@ +query getConfigValuesByKeyFilter($keyFilter: String) { + config(where: {config_key: {_ilike: $keyFilter}}) { + config_key config_value + } +} diff --git a/roles/common/files/fwo-api-calls/config/getCustomTextsPerLanguage.graphql b/roles/common/files/fwo-api-calls/config/getCustomTextsPerLanguage.graphql new file mode 100644 index 0000000000..097052d02b --- /dev/null +++ b/roles/common/files/fwo-api-calls/config/getCustomTextsPerLanguage.graphql @@ -0,0 +1,8 @@ + +query getCustomTextsPerLanguage($language: String!) { + customtxt(where: {language: {_eq: $language}}) { + id + language + txt + } +} diff --git a/roles/common/files/fwo-api-calls/config/getDataRetention.graphql b/roles/common/files/fwo-api-calls/config/getDataRetention.graphql new file mode 100644 index 0000000000..8c754a2216 --- /dev/null +++ b/roles/common/files/fwo-api-calls/config/getDataRetention.graphql @@ -0,0 +1,5 @@ +query getDataRetention { + config(where: {config_key: {_eq: "dataRetentionTime"}, config_user: {_eq: 0}}) { + retentionInDays: config_value + } +} diff --git a/roles/lib/files/FWO.Api.Client/APIcalls/config/getLanguages.graphql b/roles/common/files/fwo-api-calls/config/getLanguages.graphql similarity index 100% rename from roles/lib/files/FWO.Api.Client/APIcalls/config/getLanguages.graphql rename to roles/common/files/fwo-api-calls/config/getLanguages.graphql diff --git a/roles/lib/files/FWO.Api.Client/APIcalls/config/getTexts.graphql b/roles/common/files/fwo-api-calls/config/getTexts.graphql similarity index 100% rename from roles/lib/files/FWO.Api.Client/APIcalls/config/getTexts.graphql rename to roles/common/files/fwo-api-calls/config/getTexts.graphql diff --git a/roles/lib/files/FWO.Api.Client/APIcalls/config/getTextsPerLanguage.graphql b/roles/common/files/fwo-api-calls/config/getTextsPerLanguage.graphql similarity index 100% rename from roles/lib/files/FWO.Api.Client/APIcalls/config/getTextsPerLanguage.graphql rename to roles/common/files/fwo-api-calls/config/getTextsPerLanguage.graphql diff --git a/roles/lib/files/FWO.Api.Client/APIcalls/config/subscribeAutodiscoveryConfigChanges.graphql b/roles/common/files/fwo-api-calls/config/subscribeAutodiscoveryConfigChanges.graphql similarity index 100% rename from roles/lib/files/FWO.Api.Client/APIcalls/config/subscribeAutodiscoveryConfigChanges.graphql rename to roles/common/files/fwo-api-calls/config/subscribeAutodiscoveryConfigChanges.graphql diff --git a/roles/common/files/fwo-api-calls/config/subscribeComplianceCheckConfigChanges.graphql b/roles/common/files/fwo-api-calls/config/subscribeComplianceCheckConfigChanges.graphql new file mode 100644 index 0000000000..7d455f3534 --- /dev/null +++ b/roles/common/files/fwo-api-calls/config/subscribeComplianceCheckConfigChanges.graphql @@ -0,0 +1,48 @@ +subscription subscribeComplianceCheckConfigChanges { + config( + where: { + _or: [ + { config_key: { _eq: "importCheckCertificates" } } + { config_key: { _eq: "importSuppressCertificateWarnings" } } + { config_key: { _eq: "complianceCheckInternetZoneObject" } } + { config_key: { _eq: "complianceCheckMailBody" } } + { config_key: { _eq: "complianceCheckMailRecipients" } } + { config_key: { _eq: "complianceCheckMailSubject" } } + { config_key: { _eq: "complianceCheckMaxPrintedViolations" } } + { config_key: { _eq: "complianceCheckPolicy" } } + { config_key: { _eq: "complianceCheckRelevantManagements" } } + { config_key: { _eq: "complianceCheckScheduledDiffReports" } } + { config_key: { _eq: "complianceCheckSleepTime" } } + { config_key: { _eq: "complianceCheckStartAt" } } + { config_key: { _eq: "autoCalculateInternetZone" } } + { config_key: { _eq: "autoCalculateUndefinedInternalZone" } } + { config_key: { _eq: "internalZoneRange_10_0_0_0_8" } } + { config_key: { _eq: "internalZoneRange_172_16_0_0_12" } } + { config_key: { _eq: "internalZoneRange_192_168_0_0_16" } } + { config_key: { _eq: "internalZoneRange_0_0_0_0_8" } } + { config_key: { _eq: "internalZoneRange_127_0_0_0_8" } } + { config_key: { _eq: "internalZoneRange_169_254_0_0_16" } } + { config_key: { _eq: "internalZoneRange_224_0_0_0_4" } } + { config_key: { _eq: "internalZoneRange_240_0_0_0_4" } } + { config_key: { _eq: "internalZoneRange_255_255_255_255_32" } } + { config_key: { _eq: "internalZoneRange_192_0_2_0_24" } } + { config_key: { _eq: "internalZoneRange_198_51_100_0_24" } } + { config_key: { _eq: "internalZoneRange_203_0_113_0_24" } } + { config_key: { _eq: "internalZoneRange_100_64_0_0_10" } } + { config_key: { _eq: "internalZoneRange_192_0_0_0_24" } } + { config_key: { _eq: "internalZoneRange_192_88_99_0_24" } } + { config_key: { _eq: "internalZoneRange_198_18_0_0_15" } } + { config_key: { _eq: "autoCalculatedZonesAtTheEnd" } } + { config_key: { _eq: "treatDynamicAndDomainObjectsAsInternet" } } + { config_key: { _eq: "showShortColumnsInComplianceReports" } } + { config_key: { _eq: "complianceCheckElementsPerFetch" } } + { config_key: { _eq: "complianceCheckAvailableProcessors" } } + + ] + } + limit: 35 + ) { + config_key + config_value + } +} diff --git a/roles/common/files/fwo-api-calls/config/subscribeConfigChangesByUser.graphql b/roles/common/files/fwo-api-calls/config/subscribeConfigChangesByUser.graphql new file mode 100644 index 0000000000..b695902043 --- /dev/null +++ b/roles/common/files/fwo-api-calls/config/subscribeConfigChangesByUser.graphql @@ -0,0 +1,6 @@ +subscription subscribeConfigChangesByUser($userId: Int, $ignoreKeys: [String]) { + config(where: {_and: [{config_user: {_eq: $userId}}, {config_key: {_nin: $ignoreKeys}} ]}) { + config_key + config_value + } +} diff --git a/roles/common/files/fwo-api-calls/config/subscribeDailyCheckConfigChanges.graphql b/roles/common/files/fwo-api-calls/config/subscribeDailyCheckConfigChanges.graphql new file mode 100644 index 0000000000..b8e780be8c --- /dev/null +++ b/roles/common/files/fwo-api-calls/config/subscribeDailyCheckConfigChanges.graphql @@ -0,0 +1,34 @@ +subscription subscribeDailyCheckConfigChanges { + config (where: { _or: [ + {config_key: {_eq: "dailyCheckStartAt"}}, + {config_key: {_eq: "dailyCheckModules"}}, + {config_key: {_eq: "recRefreshDaily"}}, + {config_key: {_eq: "recertificationMode"}}, + {config_key: {_eq: "recCheckActive"}}, + {config_key: {_eq: "recCheckEmailSubject"}}, + {config_key: {_eq: "recCheckEmailUpcomingText"}}, + {config_key: {_eq: "recCheckEmailOverdueText"}}, + {config_key: {_eq: "recCheckParams"}}, + {config_key: {_eq: "recertificationPeriod"}}, + {config_key: {_eq: "initialRecertificationPeriod"}}, + {config_key: {_eq: "initialRecertifier"}}, + {config_key: {_eq: "recertificationDisplayPeriod"}}, + {config_key: {_eq: "useDummyEmailAddress"}}, + {config_key: {_eq: "emailUser"}}, + {config_key: {_eq: "emailTls"}}, + {config_key: {_eq: "emailPort"}}, + {config_key: {_eq: "emailServerAddress"}}, + {config_key: {_eq: "emailSenderAddress"}}, + {config_key: {_eq: "emailPassword"}}, + {config_key: {_eq: "notificationLanguage"}}, + {config_key: {_eq: "maxImportDuration"}}, + {config_key: {_eq: "maxImportInterval"}}, + {config_key: {_eq: "modUnansweredReqEmailBody"}}, + {config_key: {_eq: "ruleExpiryEmailBody"}}, + {config_key: {_eq: "ownerActiveRuleEmailBody"}}, + {config_key: {_eq: "ruleExpiryInitiatorKeys"}} + ]}){ + config_key + config_value + } +} diff --git a/roles/common/files/fwo-api-calls/config/subscribeExternalRequestConfigChanges.graphql b/roles/common/files/fwo-api-calls/config/subscribeExternalRequestConfigChanges.graphql new file mode 100644 index 0000000000..dd1be443a9 --- /dev/null +++ b/roles/common/files/fwo-api-calls/config/subscribeExternalRequestConfigChanges.graphql @@ -0,0 +1,13 @@ +subscription subscribeExternalRequestConfigChanges { + config (where: { _or: [ + {config_key: {_eq: "externalRequestSleepTime"}}, + {config_key: {_eq: "externalRequestStartAt"}}, + {config_key: {_eq: "modRolloutBundleTasks"}}, + {config_key: {_eq: "externalRequestWaitCycles"}}, + {config_key: {_eq: "extTicketSystems"}}, + {config_key: {_eq: "modNamingConvention"}} + ]}){ + config_key + config_value + } +} diff --git a/roles/common/files/fwo-api-calls/config/subscribeImportAppDataConfigChanges.graphql b/roles/common/files/fwo-api-calls/config/subscribeImportAppDataConfigChanges.graphql new file mode 100644 index 0000000000..95ad0af40b --- /dev/null +++ b/roles/common/files/fwo-api-calls/config/subscribeImportAppDataConfigChanges.graphql @@ -0,0 +1,18 @@ +subscription subscribeImportAppDataConfigChanges { + config (where: { _or: [ + {config_key: {_eq: "importAppDataSleepTime"}}, + {config_key: {_eq: "importAppDataStartAt"}}, + {config_key: {_eq: "importAppDataPath"}}, + {config_key: {_eq: "importAppDataScriptArgs"}}, + {config_key: {_eq: "ownerLdapGroupNames"}}, + {config_key: {_eq: "rolesWithAppDataImport"}}, + {config_key: {_eq: "modNamingConvention"}}, + {config_key: {_eq: "dnsLookup"}}, + {config_key: {_eq: "overwriteExistingNames"}}, + {config_key: {_eq: "autoReplaceAppServer"}} + ]}){ + config_key + config_value + } +} + diff --git a/roles/common/files/fwo-api-calls/config/subscribeImportNotifyConfigChanges.graphql b/roles/common/files/fwo-api-calls/config/subscribeImportNotifyConfigChanges.graphql new file mode 100644 index 0000000000..9f19f5ea44 --- /dev/null +++ b/roles/common/files/fwo-api-calls/config/subscribeImportNotifyConfigChanges.graphql @@ -0,0 +1,24 @@ +subscription subscribeImportNotifyConfigChanges { + config(where: {_or: [ + {config_key: {_eq: "importSleepTime"}}, + {config_key: {_eq: "importCheckCertificates"}}, + {config_key: {_eq: "importSuppressCertificateWarnings"}}, + {config_key: {_eq: "impChangeNotifySleepTime"}}, + {config_key: {_eq: "impChangeNotifyStartAt"}}, + {config_key: {_eq: "impChangeNotifyRecipients"}}, + {config_key: {_eq: "impChangeNotifySubject"}}, + {config_key: {_eq: "impChangeNotifyActive"}}, + {config_key: {_eq: "impChangeIncludeObjectChanges"}}, + {config_key: {_eq: "impChangeNotifyType"}}, + {config_key: {_eq: "impChangeNotifyBody"}}, + {config_key: {_eq: "useDummyEmailAddress"}}, + {config_key: {_eq: "emailServerAddress"}}, + {config_key: {_eq: "emailPort"}}, + {config_key: {_eq: "emailTls"}}, + {config_key: {_eq: "emailUser"}}, + {config_key: {_eq: "emailPassword"}} + ]}, limit: 15) { + config_key + config_value + } +} diff --git a/roles/common/files/fwo-api-calls/config/subscribeImportSubnetDataConfigChanges.graphql b/roles/common/files/fwo-api-calls/config/subscribeImportSubnetDataConfigChanges.graphql new file mode 100644 index 0000000000..c0d9dc8a9f --- /dev/null +++ b/roles/common/files/fwo-api-calls/config/subscribeImportSubnetDataConfigChanges.graphql @@ -0,0 +1,6 @@ +subscription subscribeImportSubnetDataConfigChanges { + config (where: { _or: [{config_key: {_eq: "importSubnetDataSleepTime"}}, {config_key: {_eq: "importSubnetDataStartAt"}}, {config_key: {_eq: "importSubnetDataPath"}} ]}, limit: 3){ + config_key + config_value + } +} diff --git a/roles/common/files/fwo-api-calls/config/subscribeUpdateRuleOwnerMappingConfigChanges.graphql b/roles/common/files/fwo-api-calls/config/subscribeUpdateRuleOwnerMappingConfigChanges.graphql new file mode 100644 index 0000000000..1b1f62a5a6 --- /dev/null +++ b/roles/common/files/fwo-api-calls/config/subscribeUpdateRuleOwnerMappingConfigChanges.graphql @@ -0,0 +1,11 @@ +subscription subscribeUpdateRuleOwnerMappingConfigChanges { + config(where: {_or: [ + {config_key: {_eq: "UpdateRuleOwnerMappingSleepTime"}}, + {config_key: {_eq: "updateRuleOwnerMappingStartAt"}}, + {config_key: {_eq: "updateRuleOwnerMappingActive"}}, + ]} + ){ + config_key + config_value + } +} diff --git a/roles/common/files/fwo-api-calls/config/subscribeVarianceAnalysisConfigChanges.graphql b/roles/common/files/fwo-api-calls/config/subscribeVarianceAnalysisConfigChanges.graphql new file mode 100644 index 0000000000..580d7aa074 --- /dev/null +++ b/roles/common/files/fwo-api-calls/config/subscribeVarianceAnalysisConfigChanges.graphql @@ -0,0 +1,14 @@ +subscription subscribeVarianceAnalysisConfigChanges { + config (where: { _or: [ + {config_key: {_eq: "varianceAnalysisSleepTime"}}, + {config_key: {_eq: "varianceAnalysisStartAt"}}, + {config_key: {_eq: "ModModelledMarkerLocation"}}, + {config_key: {_eq: "ModModelledMarker"}}, + {config_key: {_eq: "RuleRecognitionOption"}}, + {config_key: {_eq: "modNamingConvention"}} + ]}){ + config_key + config_value + } +} + \ No newline at end of file diff --git a/roles/lib/files/FWO.Api.Client/APIcalls/config/updateConfigItem.graphql b/roles/common/files/fwo-api-calls/config/updateConfigItem.graphql similarity index 89% rename from roles/lib/files/FWO.Api.Client/APIcalls/config/updateConfigItem.graphql rename to roles/common/files/fwo-api-calls/config/updateConfigItem.graphql index 1a02fd061e..5a45b751c5 100644 --- a/roles/lib/files/FWO.Api.Client/APIcalls/config/updateConfigItem.graphql +++ b/roles/common/files/fwo-api-calls/config/updateConfigItem.graphql @@ -9,6 +9,6 @@ mutation updateConfigItem( config_value: $value } ) { - UpdatedId: config_key + updatedId: config_key } } diff --git a/roles/lib/files/FWO.Api.Client/APIcalls/config/upsertConfig.graphql b/roles/common/files/fwo-api-calls/config/upsertConfig.graphql similarity index 100% rename from roles/lib/files/FWO.Api.Client/APIcalls/config/upsertConfig.graphql rename to roles/common/files/fwo-api-calls/config/upsertConfig.graphql diff --git a/roles/lib/files/FWO.Api.Client/APIcalls/config/upsertConfigItem.graphql b/roles/common/files/fwo-api-calls/config/upsertConfigItem.graphql similarity index 100% rename from roles/lib/files/FWO.Api.Client/APIcalls/config/upsertConfigItem.graphql rename to roles/common/files/fwo-api-calls/config/upsertConfigItem.graphql diff --git a/roles/common/files/fwo-api-calls/config/upsertConfigItems.graphql b/roles/common/files/fwo-api-calls/config/upsertConfigItems.graphql new file mode 100644 index 0000000000..2cf474533d --- /dev/null +++ b/roles/common/files/fwo-api-calls/config/upsertConfigItems.graphql @@ -0,0 +1,13 @@ +mutation upsertConfigItems($config_items: [config_insert_input!]!) { + insert_config( + objects: $config_items, + on_conflict: { + constraint: config_pkey, + update_columns: [config_value] + } + ) { + returning { + id: config_key + } + } +} \ No newline at end of file diff --git a/roles/common/files/fwo-api-calls/config/upsertCustomText.graphql b/roles/common/files/fwo-api-calls/config/upsertCustomText.graphql new file mode 100644 index 0000000000..a4b7fcdc7a --- /dev/null +++ b/roles/common/files/fwo-api-calls/config/upsertCustomText.graphql @@ -0,0 +1,17 @@ +mutation upsertCustomText($id: String!, $lang: String!, $text: String!) { + insert_customtxt( + objects: { + id: $id + language: $lang + txt: $text + }, + on_conflict: { + constraint: customtxt_pkey , + update_columns: [txt] + } + ) { + returning { + id: id + } + } +} diff --git a/roles/lib/files/FWO.Api.Client/APIcalls/device/changeDeviceState.graphql b/roles/common/files/fwo-api-calls/device/changeDeviceState.graphql similarity index 89% rename from roles/lib/files/FWO.Api.Client/APIcalls/device/changeDeviceState.graphql rename to roles/common/files/fwo-api-calls/device/changeDeviceState.graphql index c299ca34fe..1f533142db 100644 --- a/roles/lib/files/FWO.Api.Client/APIcalls/device/changeDeviceState.graphql +++ b/roles/common/files/fwo-api-calls/device/changeDeviceState.graphql @@ -8,6 +8,6 @@ mutation changeDeviceState( do_not_import: $importDisabled } ) { - UpdatedId: dev_id + updatedId: dev_id } } diff --git a/roles/lib/files/FWO.Api.Client/APIcalls/device/changeManagementState.graphql b/roles/common/files/fwo-api-calls/device/changeManagementState.graphql similarity index 90% rename from roles/lib/files/FWO.Api.Client/APIcalls/device/changeManagementState.graphql rename to roles/common/files/fwo-api-calls/device/changeManagementState.graphql index a314feed00..5554e6e4b2 100644 --- a/roles/lib/files/FWO.Api.Client/APIcalls/device/changeManagementState.graphql +++ b/roles/common/files/fwo-api-calls/device/changeManagementState.graphql @@ -8,6 +8,6 @@ mutation changeManagementState( do_not_import: $importDisabled } ) { - UpdatedId: mgm_id + updatedId: mgm_id } } diff --git a/roles/lib/files/FWO.Api.Client/APIcalls/device/deleteCredential.graphql b/roles/common/files/fwo-api-calls/device/deleteCredential.graphql similarity index 86% rename from roles/lib/files/FWO.Api.Client/APIcalls/device/deleteCredential.graphql rename to roles/common/files/fwo-api-calls/device/deleteCredential.graphql index f33e089064..599f16fc65 100644 --- a/roles/lib/files/FWO.Api.Client/APIcalls/device/deleteCredential.graphql +++ b/roles/common/files/fwo-api-calls/device/deleteCredential.graphql @@ -2,6 +2,6 @@ mutation delete_import_credential_by_pk ($id: Int!) { delete_import_credential_by_pk ( id: $id ) { - DeletedId: id + deletedId: id } } diff --git a/roles/lib/files/FWO.Api.Client/APIcalls/device/deleteDevice.graphql b/roles/common/files/fwo-api-calls/device/deleteDevice.graphql similarity index 81% rename from roles/lib/files/FWO.Api.Client/APIcalls/device/deleteDevice.graphql rename to roles/common/files/fwo-api-calls/device/deleteDevice.graphql index 1a015e6f75..0511ecc941 100644 --- a/roles/lib/files/FWO.Api.Client/APIcalls/device/deleteDevice.graphql +++ b/roles/common/files/fwo-api-calls/device/deleteDevice.graphql @@ -2,6 +2,6 @@ mutation delete_device_by_pk ($id: Int!) { delete_device_by_pk ( dev_id: $id ) { - DeletedId: dev_id + deletedId: dev_id } } diff --git a/roles/lib/files/FWO.Api.Client/APIcalls/device/deleteManagement.graphql b/roles/common/files/fwo-api-calls/device/deleteManagement.graphql similarity index 82% rename from roles/lib/files/FWO.Api.Client/APIcalls/device/deleteManagement.graphql rename to roles/common/files/fwo-api-calls/device/deleteManagement.graphql index cfe2bb8b34..67a727f295 100644 --- a/roles/lib/files/FWO.Api.Client/APIcalls/device/deleteManagement.graphql +++ b/roles/common/files/fwo-api-calls/device/deleteManagement.graphql @@ -2,6 +2,6 @@ mutation delete_management_by_pk ($id: Int!) { delete_management_by_pk ( mgm_id: $id ) { - DeletedId: mgm_id + deletedId: mgm_id } } diff --git a/roles/lib/files/FWO.Api.Client/APIcalls/device/fragments/deviceDetails.graphql b/roles/common/files/fwo-api-calls/device/fragments/deviceDetails.graphql similarity index 96% rename from roles/lib/files/FWO.Api.Client/APIcalls/device/fragments/deviceDetails.graphql rename to roles/common/files/fwo-api-calls/device/fragments/deviceDetails.graphql index 9c7767d604..0b1ffef4ee 100644 --- a/roles/lib/files/FWO.Api.Client/APIcalls/device/fragments/deviceDetails.graphql +++ b/roles/common/files/fwo-api-calls/device/fragments/deviceDetails.graphql @@ -3,6 +3,7 @@ fragment deviceDetails on device { id: dev_id name: dev_name + uid: dev_uid deviceType: stm_dev_typ { ...deviceTypeDetails } management { id: mgm_id diff --git a/roles/lib/files/FWO.Api.Client/APIcalls/device/fragments/deviceTypeDetails.graphql b/roles/common/files/fwo-api-calls/device/fragments/deviceTypeDetails.graphql similarity index 100% rename from roles/lib/files/FWO.Api.Client/APIcalls/device/fragments/deviceTypeDetails.graphql rename to roles/common/files/fwo-api-calls/device/fragments/deviceTypeDetails.graphql diff --git a/roles/lib/files/FWO.Api.Client/APIcalls/device/fragments/importCredentials.graphql b/roles/common/files/fwo-api-calls/device/fragments/importCredentials.graphql similarity index 100% rename from roles/lib/files/FWO.Api.Client/APIcalls/device/fragments/importCredentials.graphql rename to roles/common/files/fwo-api-calls/device/fragments/importCredentials.graphql diff --git a/roles/lib/files/FWO.Api.Client/APIcalls/device/fragments/importCredentialsWithoutSecrets.graphql b/roles/common/files/fwo-api-calls/device/fragments/importCredentialsWithoutSecrets.graphql similarity index 100% rename from roles/lib/files/FWO.Api.Client/APIcalls/device/fragments/importCredentialsWithoutSecrets.graphql rename to roles/common/files/fwo-api-calls/device/fragments/importCredentialsWithoutSecrets.graphql diff --git a/roles/lib/files/FWO.Api.Client/APIcalls/device/fragments/managementDetails.graphql b/roles/common/files/fwo-api-calls/device/fragments/managementDetails.graphql similarity index 79% rename from roles/lib/files/FWO.Api.Client/APIcalls/device/fragments/managementDetails.graphql rename to roles/common/files/fwo-api-calls/device/fragments/managementDetails.graphql index a819833ee0..c1d3121468 100644 --- a/roles/lib/files/FWO.Api.Client/APIcalls/device/fragments/managementDetails.graphql +++ b/roles/common/files/fwo-api-calls/device/fragments/managementDetails.graphql @@ -1,11 +1,12 @@ fragment ManagementDetails on management { id: mgm_id name: mgm_name + uid: mgm_uid hostname: ssh_hostname port: ssh_port import_credential_id import_credential { ...ImportCredentialDetails } - deviceType: stm_dev_typ { ...deviceTypeDetails } superManager: multi_device_manager_id + deviceType: stm_dev_typ { ...deviceTypeDetails } configPath: config_path domainUid: domain_uid cloudSubscriptionId: cloud_subscription_id @@ -16,13 +17,18 @@ fragment ManagementDetails on management { importerHostname: importer_hostname comment: mgm_comment debugLevel: debug_level + extMgtData: ext_mgm_data creationDate: mgm_create updateDate: mgm_update lastConfigHash: last_import_md5_complete_config devices { id: dev_id name: dev_name + uid: dev_uid importDisabled: do_not_import local_rulebase_name: local_rulebase_name } + isSuperManager: is_super_manager + multi_device_manager_id + ...subManagements } diff --git a/roles/lib/files/FWO.Api.Client/APIcalls/device/fragments/managementDetailsWithoutSecrets.graphql b/roles/common/files/fwo-api-calls/device/fragments/managementDetailsWithoutSecrets.graphql similarity index 84% rename from roles/lib/files/FWO.Api.Client/APIcalls/device/fragments/managementDetailsWithoutSecrets.graphql rename to roles/common/files/fwo-api-calls/device/fragments/managementDetailsWithoutSecrets.graphql index ada6dc95c5..70a0caeec8 100644 --- a/roles/lib/files/FWO.Api.Client/APIcalls/device/fragments/managementDetailsWithoutSecrets.graphql +++ b/roles/common/files/fwo-api-calls/device/fragments/managementDetailsWithoutSecrets.graphql @@ -1,11 +1,13 @@ fragment ManagementDetailsWithoutSecrets on management { id: mgm_id name: mgm_name + uid: mgm_uid hostname: ssh_hostname port: ssh_port import_credential_id import_credential { ...ImportCredentialDetailsWithoutSecrets } - deviceType: stm_dev_typ { ...deviceTypeDetails } superManager: multi_device_manager_id + deviceType: stm_dev_typ { ...deviceTypeDetails } + multi_device_manager_id configPath: config_path domainUid: domain_uid cloudSubscriptionId: cloud_subscription_id @@ -16,12 +18,14 @@ fragment ManagementDetailsWithoutSecrets on management { importerHostname: importer_hostname comment: mgm_comment debugLevel: debug_level + extMgtData: ext_mgm_data creationDate: mgm_create updateDate: mgm_update lastConfigHash: last_import_md5_complete_config devices { id: dev_id name: dev_name + uid: dev_uid importDisabled: do_not_import local_rulebase_name: local_rulebase_name } diff --git a/roles/common/files/fwo-api-calls/device/fragments/subManagements.graphql b/roles/common/files/fwo-api-calls/device/fragments/subManagements.graphql new file mode 100644 index 0000000000..c47a42e2eb --- /dev/null +++ b/roles/common/files/fwo-api-calls/device/fragments/subManagements.graphql @@ -0,0 +1,34 @@ +fragment subManagements on management { + subManagers: managementByMultiDeviceManagerId { + id: mgm_id + name: mgm_name + uid: mgm_uid + hostname: ssh_hostname + port: ssh_port + deviceType: stm_dev_typ { + ...deviceTypeDetails + } + configPath: config_path + domainUid: domain_uid + importDisabled: do_not_import + hideInUi: hide_in_gui + extMgtData: ext_mgm_data + creationDate: mgm_create + updateDate: mgm_update + devices { + id: dev_id + name: dev_name + uid: dev_uid + importDisabled: do_not_import + local_rulebase_name: local_rulebase_name + } + importerHostname: importer_hostname + import_credential { + ...ImportCredentialDetails + } + isSuperManager: is_super_manager + subManagers: managementByMultiDeviceManagerId { + mgm_id + } + } +} diff --git a/roles/lib/files/FWO.Api.Client/APIcalls/device/getCredentials.graphql b/roles/common/files/fwo-api-calls/device/getCredentials.graphql similarity index 100% rename from roles/lib/files/FWO.Api.Client/APIcalls/device/getCredentials.graphql rename to roles/common/files/fwo-api-calls/device/getCredentials.graphql diff --git a/roles/lib/files/FWO.Api.Client/APIcalls/device/getCredentialsWithoutSecrets.graphql b/roles/common/files/fwo-api-calls/device/getCredentialsWithoutSecrets.graphql similarity index 100% rename from roles/lib/files/FWO.Api.Client/APIcalls/device/getCredentialsWithoutSecrets.graphql rename to roles/common/files/fwo-api-calls/device/getCredentialsWithoutSecrets.graphql diff --git a/roles/lib/files/FWO.Api.Client/APIcalls/device/getDeviceDetails.graphql b/roles/common/files/fwo-api-calls/device/getDeviceDetails.graphql similarity index 100% rename from roles/lib/files/FWO.Api.Client/APIcalls/device/getDeviceDetails.graphql rename to roles/common/files/fwo-api-calls/device/getDeviceDetails.graphql diff --git a/roles/lib/files/FWO.Api.Client/APIcalls/device/getDeviceTypeDetails.graphql b/roles/common/files/fwo-api-calls/device/getDeviceTypeDetails.graphql similarity index 100% rename from roles/lib/files/FWO.Api.Client/APIcalls/device/getDeviceTypeDetails.graphql rename to roles/common/files/fwo-api-calls/device/getDeviceTypeDetails.graphql diff --git a/roles/lib/files/FWO.Api.Client/APIcalls/device/getDevicesByManagement.graphql b/roles/common/files/fwo-api-calls/device/getDevicesByManagement.graphql similarity index 76% rename from roles/lib/files/FWO.Api.Client/APIcalls/device/getDevicesByManagement.graphql rename to roles/common/files/fwo-api-calls/device/getDevicesByManagement.graphql index 9e2c79759b..d519310e92 100644 --- a/roles/lib/files/FWO.Api.Client/APIcalls/device/getDevicesByManagement.graphql +++ b/roles/common/files/fwo-api-calls/device/getDevicesByManagement.graphql @@ -1,6 +1,7 @@ -query getDevicesByManagement { +query getDevicesByManagement($devIds:[Int!]) { management( where: { + devices:{dev_id:{_in:$devIds}} hide_in_gui: { _eq: false } stm_dev_typ: { dev_typ_is_multi_mgmt: { _eq: false } @@ -11,8 +12,10 @@ query getDevicesByManagement { ) { id: mgm_id name: mgm_name + uid: mgm_uid devices( where: { + dev_id:{_in:$devIds} hide_in_gui: { _eq: false } stm_dev_typ: { is_pure_routing_device: { _eq: false } } } @@ -20,6 +23,7 @@ query getDevicesByManagement { ) { id: dev_id name: dev_name + uid: dev_uid } } } diff --git a/roles/common/files/fwo-api-calls/device/getDevicesWithRulebaseLinks.graphql b/roles/common/files/fwo-api-calls/device/getDevicesWithRulebaseLinks.graphql new file mode 100644 index 0000000000..05a6073f2d --- /dev/null +++ b/roles/common/files/fwo-api-calls/device/getDevicesWithRulebaseLinks.graphql @@ -0,0 +1,14 @@ +query getDevicesWithRulebaseLinks($mgmId: Int!) +{ + device (where: { + mgm_id: { _eq:$mgmId } + hide_in_gui: { _eq: false } + stm_dev_typ: { is_pure_routing_device: { _eq: false } } + }) + { + id: dev_id + rulebase_links (where: {removed:{_is_null:true} }) { + from_rule_id + } + } +} diff --git a/roles/common/files/fwo-api-calls/device/getGatewayId.graphql b/roles/common/files/fwo-api-calls/device/getGatewayId.graphql new file mode 100644 index 0000000000..7510a3a014 --- /dev/null +++ b/roles/common/files/fwo-api-calls/device/getGatewayId.graphql @@ -0,0 +1,10 @@ +query getGatewayId($gwName:String!, $mgmUid: String!) { + device( + where: { + dev_name:{_eq:$gwName} + management: { mgm_uid: { _eq: $mgmUid } } + } + ) { + id: dev_id + } +} diff --git a/roles/lib/files/FWO.Api.Client/APIcalls/device/getManagementDetailsWithoutSecrets.graphql b/roles/common/files/fwo-api-calls/device/getManagementDetailsWithoutSecrets.graphql similarity index 100% rename from roles/lib/files/FWO.Api.Client/APIcalls/device/getManagementDetailsWithoutSecrets.graphql rename to roles/common/files/fwo-api-calls/device/getManagementDetailsWithoutSecrets.graphql diff --git a/roles/common/files/fwo-api-calls/device/getManagementNames.graphql b/roles/common/files/fwo-api-calls/device/getManagementNames.graphql new file mode 100644 index 0000000000..b81b78b02a --- /dev/null +++ b/roles/common/files/fwo-api-calls/device/getManagementNames.graphql @@ -0,0 +1,14 @@ +query getManagementNames +{ + management(order_by: {mgm_name:asc}){ + id: mgm_id + name: mgm_name + uid: mgm_uid + extMgtData: ext_mgm_data + devices { + id: dev_id + name: dev_name + uid: dev_uid + } + } +} diff --git a/roles/common/files/fwo-api-calls/device/getManagementWithSubs.graphql b/roles/common/files/fwo-api-calls/device/getManagementWithSubs.graphql new file mode 100644 index 0000000000..04cc70de53 --- /dev/null +++ b/roles/common/files/fwo-api-calls/device/getManagementWithSubs.graphql @@ -0,0 +1,13 @@ +query getManagementWithSubs { + management( + where: { + _not: {management: {}} + do_not_import: { _eq: false } + } + ) { + id: mgm_id + subManager: managementByMultiDeviceManagerId { + mgm_id + } + } +} \ No newline at end of file diff --git a/roles/lib/files/FWO.Api.Client/APIcalls/device/getManagementsDetails.graphql b/roles/common/files/fwo-api-calls/device/getManagementsDetails.graphql similarity index 100% rename from roles/lib/files/FWO.Api.Client/APIcalls/device/getManagementsDetails.graphql rename to roles/common/files/fwo-api-calls/device/getManagementsDetails.graphql diff --git a/roles/common/files/fwo-api-calls/device/getManagementsWithRulebases.graphql b/roles/common/files/fwo-api-calls/device/getManagementsWithRulebases.graphql new file mode 100644 index 0000000000..b0b58d35cd --- /dev/null +++ b/roles/common/files/fwo-api-calls/device/getManagementsWithRulebases.graphql @@ -0,0 +1,14 @@ +query getManagementsWithRulebases +{ + management(order_by: {mgm_name:asc}){ + id: mgm_id + name: mgm_name + uid: mgm_uid + extMgtData: ext_mgm_data + rulebases { + id + name + uid + } + } +} diff --git a/roles/lib/files/FWO.Api.Client/APIcalls/device/getMgmtNumberUsingCred.graphql b/roles/common/files/fwo-api-calls/device/getMgmtNumberUsingCred.graphql similarity index 100% rename from roles/lib/files/FWO.Api.Client/APIcalls/device/getMgmtNumberUsingCred.graphql rename to roles/common/files/fwo-api-calls/device/getMgmtNumberUsingCred.graphql diff --git a/roles/common/files/fwo-api-calls/device/getSingleManagementDetails.graphql b/roles/common/files/fwo-api-calls/device/getSingleManagementDetails.graphql new file mode 100644 index 0000000000..f42ffc366b --- /dev/null +++ b/roles/common/files/fwo-api-calls/device/getSingleManagementDetails.graphql @@ -0,0 +1,6 @@ +query getManagementDetails($mgmId: Int!) +{ + management(where: {mgm_id: {_eq: $mgmId}}){ + ...ManagementDetails + } +} diff --git a/roles/common/files/fwo-api-calls/device/getSubManagerUids.graphql b/roles/common/files/fwo-api-calls/device/getSubManagerUids.graphql new file mode 100644 index 0000000000..6d1c6b874c --- /dev/null +++ b/roles/common/files/fwo-api-calls/device/getSubManagerUids.graphql @@ -0,0 +1,7 @@ +query getSubManagerUids($mgmId: Int!) +{ + management(where: {multi_device_manager_id: {_eq: $mgmId}}) { + mgm_id + mgm_uid + } +} diff --git a/roles/common/files/fwo-api-calls/device/markGatewaysRemoved.graphql b/roles/common/files/fwo-api-calls/device/markGatewaysRemoved.graphql new file mode 100644 index 0000000000..6949d6edc1 --- /dev/null +++ b/roles/common/files/fwo-api-calls/device/markGatewaysRemoved.graphql @@ -0,0 +1,14 @@ +mutation markGatewaysRemoved($gwIds: [Int!], $importId: bigint!) { + update_rulebase_link( + where: { gw_id: { _in: $gwIds }, removed: { _is_null: true } } + _set: { removed: $importId } + ) { + affected_rows + } + update_rule_enforced_on_gateway( + where: { dev_id: { _in: $gwIds }, removed: { _is_null: true } } + _set: { removed: $importId } + ) { + affected_rows + } +} diff --git a/roles/common/files/fwo-api-calls/device/markManagersRemoved.graphql b/roles/common/files/fwo-api-calls/device/markManagersRemoved.graphql new file mode 100644 index 0000000000..0dae04f01b --- /dev/null +++ b/roles/common/files/fwo-api-calls/device/markManagersRemoved.graphql @@ -0,0 +1,24 @@ +mutation markManagersRemoved($mgmIds: [Int!], $importId: bigint!) { + update_rule(where: {mgm_id: {_in: $mgmIds}, removed: {_is_null: true}}, _set: {removed: $importId}) { affected_rows } + update_rulebase(where: {mgm_id: {_in: $mgmIds}, removed: {_is_null: true}}, _set: {removed: $importId}) { affected_rows } + update_rulebase_link(where: {device: {mgm_id: {_in: $mgmIds}}, removed: {_is_null: true}}, _set: {removed: $importId}) { affected_rows } + update_object(where: {mgm_id: {_in: $mgmIds}, removed: {_is_null: true}}, _set: {removed: $importId}) { affected_rows } + update_service(where: {mgm_id: {_in: $mgmIds}, removed: {_is_null: true}}, _set: {removed: $importId}) { affected_rows } + update_usr(where: {mgm_id: {_in: $mgmIds}, removed: {_is_null: true}}, _set: {removed: $importId}) { affected_rows } + update_zone(where: {mgm_id: {_in: $mgmIds}, removed: {_is_null: true}}, _set: {removed: $importId}) { affected_rows } + update_objgrp(where: {object: {mgm_id: {_in: $mgmIds}}, removed: {_is_null: true}}, _set: {removed: $importId}) { affected_rows } + update_svcgrp(where: {service: {mgm_id: {_in: $mgmIds}}, removed: {_is_null: true}}, _set: {removed: $importId}) { affected_rows } + update_usergrp(where: {usr: {mgm_id: {_in: $mgmIds}}, removed: {_is_null: true}}, _set: {removed: $importId}) { affected_rows } + update_objgrp_flat(where: {object: {mgm_id: {_in: $mgmIds}}, removed: {_is_null: true}}, _set: {removed: $importId}) { affected_rows } + update_svcgrp_flat(where: {service: {mgm_id: {_in: $mgmIds}}, removed: {_is_null: true}}, _set: {removed: $importId}) { affected_rows } + update_usergrp_flat(where: {usr: {mgm_id: {_in: $mgmIds}}, removed: {_is_null: true}}, _set: {removed: $importId}) { affected_rows } + update_rule_to(where: {rule: {mgm_id: {_in: $mgmIds}}, removed: {_is_null: true}}, _set: {removed: $importId}) { affected_rows } + update_rule_from(where: {rule: {mgm_id: {_in: $mgmIds}}, removed: {_is_null: true}}, _set: {removed: $importId}) { affected_rows } + update_rule_service(where: {rule: {mgm_id: {_in: $mgmIds}}, removed: {_is_null: true}}, _set: {removed: $importId}) { affected_rows } + update_rule_nwobj_resolved(where: {rule: {mgm_id: {_in: $mgmIds}}, removed: {_is_null: true}}, _set: {removed: $importId}) { affected_rows } + update_rule_svc_resolved(where: {rule: {mgm_id: {_in: $mgmIds}}, removed: {_is_null: true}}, _set: {removed: $importId}) { affected_rows } + update_rule_user_resolved(where: {rule: {mgm_id: {_in: $mgmIds}}, removed: {_is_null: true}}, _set: {removed: $importId}) { affected_rows } + update_rule_from_zone(where: {rule: {mgm_id: {_in: $mgmIds}}, removed: {_is_null: true}}, _set: {removed: $importId}) { affected_rows } + update_rule_to_zone(where: {rule: {mgm_id: {_in: $mgmIds}}, removed: {_is_null: true}}, _set: {removed: $importId}) { affected_rows } + update_rule_enforced_on_gateway(where: {rule: {mgm_id: {_in: $mgmIds}}, removed: {_is_null: true}}, _set: {removed: $importId}) { affected_rows } +} \ No newline at end of file diff --git a/roles/lib/files/FWO.Api.Client/APIcalls/device/newCredential.graphql b/roles/common/files/fwo-api-calls/device/newCredential.graphql similarity index 100% rename from roles/lib/files/FWO.Api.Client/APIcalls/device/newCredential.graphql rename to roles/common/files/fwo-api-calls/device/newCredential.graphql diff --git a/roles/lib/files/FWO.Api.Client/APIcalls/device/newDevice.graphql b/roles/common/files/fwo-api-calls/device/newDevice.graphql similarity index 90% rename from roles/lib/files/FWO.Api.Client/APIcalls/device/newDevice.graphql rename to roles/common/files/fwo-api-calls/device/newDevice.graphql index 740bc1c55b..d9599b6a62 100644 --- a/roles/lib/files/FWO.Api.Client/APIcalls/device/newDevice.graphql +++ b/roles/common/files/fwo-api-calls/device/newDevice.graphql @@ -1,8 +1,9 @@ mutation newDevice( $name: String! + $uid: String! $devTypeId: Int! $managementId: Int! - $localRulebase: String! + $localRulebase: String $globalRulebase: String $package: String $importDisabled: Boolean! @@ -12,6 +13,7 @@ mutation newDevice( insert_device( objects: { dev_name: $name + dev_uid: $uid dev_typ_id: $devTypeId mgm_id: $managementId local_rulebase_name: $localRulebase @@ -31,6 +33,7 @@ mutation newDevice( # example variables (at least the following) # { # "name": "huhu", +# "uid": "huhu", # "devTypeId": 10, # "managementId": 2, # "rulebase": "layer1", diff --git a/roles/lib/files/FWO.Api.Client/APIcalls/device/newManagement.graphql b/roles/common/files/fwo-api-calls/device/newManagement.graphql similarity index 87% rename from roles/lib/files/FWO.Api.Client/APIcalls/device/newManagement.graphql rename to roles/common/files/fwo-api-calls/device/newManagement.graphql index 9744235602..412e51d587 100644 --- a/roles/lib/files/FWO.Api.Client/APIcalls/device/newManagement.graphql +++ b/roles/common/files/fwo-api-calls/device/newManagement.graphql @@ -1,5 +1,6 @@ mutation newManagementWithExistingCredentials( $name: String! + $uid: String $devTypeId: Int! $importCredentialId: Int! $hostname: String! @@ -13,13 +14,15 @@ mutation newManagementWithExistingCredentials( $cloudSubscriptionId: String $importerHostname: String $comment: String - $tenantId: Int $debugLevel: Int $superManager: Int + $extMgtData: String + $isSuperManager: Boolean ) { insert_management( objects: { mgm_name: $name + mgm_uid: $uid dev_typ_id: $devTypeId ssh_hostname: $hostname import_credential_id: $importCredentialId @@ -33,9 +36,10 @@ mutation newManagementWithExistingCredentials( force_initial_import: $forceInitialImport hide_in_gui: $hideInUi mgm_comment: $comment - tenant_id: $tenantId debug_level: $debugLevel multi_device_manager_id: $superManager + ext_mgm_data: $extMgtData + is_super_manager: $isSuperManager } ) { returning { diff --git a/roles/lib/files/FWO.Api.Client/APIcalls/device/updateCredential.graphql b/roles/common/files/fwo-api-calls/device/updateCredential.graphql similarity index 92% rename from roles/lib/files/FWO.Api.Client/APIcalls/device/updateCredential.graphql rename to roles/common/files/fwo-api-calls/device/updateCredential.graphql index bfe99e1780..a69651518f 100644 --- a/roles/lib/files/FWO.Api.Client/APIcalls/device/updateCredential.graphql +++ b/roles/common/files/fwo-api-calls/device/updateCredential.graphql @@ -2,7 +2,7 @@ mutation updateCredential( $id: Int! $username: String! $secret: String! - $sshPublicKey: String! + $sshPublicKey: String $credential_name: String! $isKeyPair: Boolean $cloudClientId: String @@ -20,6 +20,6 @@ mutation updateCredential( cloud_client_secret: $cloudClientSecret } ) { - UpdatedId: id + updatedId: id } } diff --git a/roles/lib/files/FWO.Api.Client/APIcalls/device/updateDevice.graphql b/roles/common/files/fwo-api-calls/device/updateDevice.graphql similarity index 88% rename from roles/lib/files/FWO.Api.Client/APIcalls/device/updateDevice.graphql rename to roles/common/files/fwo-api-calls/device/updateDevice.graphql index 67d6f756a5..6946d94b8e 100644 --- a/roles/lib/files/FWO.Api.Client/APIcalls/device/updateDevice.graphql +++ b/roles/common/files/fwo-api-calls/device/updateDevice.graphql @@ -1,11 +1,12 @@ mutation updateDevice( $id: Int! + $uid: String $name: String! $managementId: Int! $devTypeId: Int! $importDisabled: Boolean! $hideInUi: Boolean! - $localRulebase: String! + $localRulebase: String $globalRulebase: String $package: String $comment: String @@ -14,6 +15,7 @@ mutation updateDevice( pk_columns: { dev_id: $id } _set: { dev_name: $name + dev_uid: $uid dev_typ_id: $devTypeId mgm_id: $managementId local_rulebase_name: $localRulebase @@ -24,7 +26,7 @@ mutation updateDevice( dev_comment: $comment } ) { - UpdatedId: dev_id + updatedId: dev_id } } @@ -32,6 +34,7 @@ mutation updateDevice( # { # "id": 17, # "name": "huhu", +# "uid": "huhu", # "devTypeId": 10, # "managementId": 2, # "rulebase": "layer1", diff --git a/roles/common/files/fwo-api-calls/device/updateGatewayUid.graphql b/roles/common/files/fwo-api-calls/device/updateGatewayUid.graphql new file mode 100644 index 0000000000..191ca50d33 --- /dev/null +++ b/roles/common/files/fwo-api-calls/device/updateGatewayUid.graphql @@ -0,0 +1,13 @@ +mutation updateDevice( + $id: Int! + $uid: String! +) { + update_device_by_pk( + pk_columns: { dev_id: $id } + _set: { + dev_uid: $uid + } + ) { + UpdatedId: dev_id + } +} diff --git a/roles/lib/files/FWO.Api.Client/APIcalls/device/updateManagement.graphql b/roles/common/files/fwo-api-calls/device/updateManagement.graphql similarity index 85% rename from roles/lib/files/FWO.Api.Client/APIcalls/device/updateManagement.graphql rename to roles/common/files/fwo-api-calls/device/updateManagement.graphql index 95c62afd04..4f6920c5bb 100644 --- a/roles/lib/files/FWO.Api.Client/APIcalls/device/updateManagement.graphql +++ b/roles/common/files/fwo-api-calls/device/updateManagement.graphql @@ -1,6 +1,7 @@ mutation updateManagement( $id: Int! $name: String! + $uid: String $devTypeId: Int! $importCredentialId: Int! $hostname: String! @@ -14,14 +15,16 @@ mutation updateManagement( $cloudSubscriptionId: String $importerHostname: String $comment: String - $tenantId: Int $debugLevel: Int $superManager: Int + $extMgtData: String + $isSuperManager: Boolean ) { update_management_by_pk( pk_columns: { mgm_id: $id } _set: { mgm_name: $name + mgm_uid: $uid dev_typ_id: $devTypeId ssh_hostname: $hostname import_credential_id: $importCredentialId @@ -35,11 +38,12 @@ mutation updateManagement( force_initial_import: $forceInitialImport hide_in_gui: $hideInUi mgm_comment: $comment - tenant_id: $tenantId debug_level: $debugLevel multi_device_manager_id: $superManager + ext_mgm_data: $extMgtData + is_super_manager: $isSuperManager } ) { - UpdatedId: mgm_id + updatedId: mgm_id } } diff --git a/roles/common/files/fwo-api-calls/device/updateManagementUid.graphql b/roles/common/files/fwo-api-calls/device/updateManagementUid.graphql new file mode 100644 index 0000000000..10a633228f --- /dev/null +++ b/roles/common/files/fwo-api-calls/device/updateManagementUid.graphql @@ -0,0 +1,13 @@ +mutation updateManagementUid( + $id: Int! + $uid: String +) { + update_management_by_pk( + pk_columns: { mgm_id: $id } + _set: { + mgm_uid: $uid + } + ) { + UpdatedId: mgm_id + } +} diff --git a/roles/common/files/fwo-api-calls/device/updateManagementUids.graphql b/roles/common/files/fwo-api-calls/device/updateManagementUids.graphql new file mode 100644 index 0000000000..103ca3a50c --- /dev/null +++ b/roles/common/files/fwo-api-calls/device/updateManagementUids.graphql @@ -0,0 +1,15 @@ +mutation updateManagementUids( + $id: Int! + $uid: String + $domainUid: String +) { + update_management_by_pk( + pk_columns: { mgm_id: $id } + _set: { + mgm_uid: $uid + domain_uid: $domainUid + } + ) { + UpdatedId: mgm_id + } +} diff --git a/roles/common/files/fwo-api-calls/extRequest/addExtRequest.graphql b/roles/common/files/fwo-api-calls/extRequest/addExtRequest.graphql new file mode 100644 index 0000000000..65fecece8d --- /dev/null +++ b/roles/common/files/fwo-api-calls/extRequest/addExtRequest.graphql @@ -0,0 +1,27 @@ +mutation addExtRequest( + $ownerId: Int! + $ticketId: bigint! + $taskNumber: Int! + $extTicketSystem: String! + $extTaskType: String! + $extTaskContent: String! + $extQueryVariables: String + $extRequestState: String! + $waitCycles: Int + ) { + insert_ext_request(objects: { + owner_id: $ownerId + ticket_id: $ticketId + task_number: $taskNumber + ext_ticket_system: $extTicketSystem + ext_request_type: $extTaskType + ext_request_content: $extTaskContent + ext_query_variables: $extQueryVariables + ext_request_state: $extRequestState + wait_cycles: $waitCycles + }) { + returning { + newIdLong: id + } + } +} diff --git a/roles/common/files/fwo-api-calls/extRequest/addTicketId.graphql b/roles/common/files/fwo-api-calls/extRequest/addTicketId.graphql new file mode 100644 index 0000000000..35d6254cd6 --- /dev/null +++ b/roles/common/files/fwo-api-calls/extRequest/addTicketId.graphql @@ -0,0 +1,13 @@ +mutation addTicketId( + $ownerId: Int! + $ticketId: bigint! + ) { + insert_owner_ticket(objects: { + owner_id: $ownerId + ticket_id: $ticketId + }) { + returning { + insertedIdLong: ticket_id + } + } +} diff --git a/roles/common/files/fwo-api-calls/extRequest/fragments/extRequestDetails.graphql b/roles/common/files/fwo-api-calls/extRequest/fragments/extRequestDetails.graphql new file mode 100644 index 0000000000..083c565bfe --- /dev/null +++ b/roles/common/files/fwo-api-calls/extRequest/fragments/extRequestDetails.graphql @@ -0,0 +1,21 @@ + +fragment extRequestDetails on ext_request +{ + id + owner_id + ticket_id + ext_ticket_system + ext_query_variables + ext_request_content + task_number + ext_request_type + ext_request_state + ext_ticket_id + last_creation_response + last_processing_response + create_date + finish_date + wait_cycles + attempts + locked +} diff --git a/roles/common/files/fwo-api-calls/extRequest/getAndLockOpenRequests.graphql b/roles/common/files/fwo-api-calls/extRequest/getAndLockOpenRequests.graphql new file mode 100644 index 0000000000..77f2c616a6 --- /dev/null +++ b/roles/common/files/fwo-api-calls/extRequest/getAndLockOpenRequests.graphql @@ -0,0 +1,12 @@ + +mutation getAndLockOpenRequests ($states: [String!] ){ + update_ext_request (where: { ext_request_state: { _in: $states }, locked: { _eq: false } }, + _set: { + locked: true + } + ){ + returning { + ...extRequestDetails + } + } +} diff --git a/roles/common/files/fwo-api-calls/extRequest/getLastRequest.graphql b/roles/common/files/fwo-api-calls/extRequest/getLastRequest.graphql new file mode 100644 index 0000000000..23529719a8 --- /dev/null +++ b/roles/common/files/fwo-api-calls/extRequest/getLastRequest.graphql @@ -0,0 +1,6 @@ + +query getLastRequest ($ticketId: bigint! ){ + ext_request (where: { ticket_id: {_eq: $ticketId} } order_by: { id: desc }, limit: 1){ + ...extRequestDetails + } +} diff --git a/roles/common/files/fwo-api-calls/extRequest/getLatestTicketId.graphql b/roles/common/files/fwo-api-calls/extRequest/getLatestTicketId.graphql new file mode 100644 index 0000000000..9302592b0d --- /dev/null +++ b/roles/common/files/fwo-api-calls/extRequest/getLatestTicketId.graphql @@ -0,0 +1,6 @@ + +query getLatestTicketId ($ownerId: Int!) { + owner_ticket (where: {owner_id: {_eq: $ownerId}} order_by: { ticket_id: desc }, limit: 1){ + ticket_id + } +} diff --git a/roles/common/files/fwo-api-calls/extRequest/getLatestTicketIds.graphql b/roles/common/files/fwo-api-calls/extRequest/getLatestTicketIds.graphql new file mode 100644 index 0000000000..34c6838eb3 --- /dev/null +++ b/roles/common/files/fwo-api-calls/extRequest/getLatestTicketIds.graphql @@ -0,0 +1,6 @@ + +query getLatestTicketIds ($ownerId: Int!) { + owner_ticket (where: {owner_id: {_eq: $ownerId}} order_by: { ticket_id: desc }){ + ticket_id + } +} diff --git a/roles/common/files/fwo-api-calls/extRequest/getOpenRequests.graphql b/roles/common/files/fwo-api-calls/extRequest/getOpenRequests.graphql new file mode 100644 index 0000000000..a77ed1a362 --- /dev/null +++ b/roles/common/files/fwo-api-calls/extRequest/getOpenRequests.graphql @@ -0,0 +1,12 @@ + +query getOpenRequests ($states: [String!] ){ + ext_request (where: { ext_request_state: {_in: $states} } order_by: { id: asc }){ + ...extRequestDetails + owner: owner { + id + name + app_id_external + common_service_possible + } + } +} diff --git a/roles/common/files/fwo-api-calls/extRequest/subscribeExtRequestStateUpdate.graphql b/roles/common/files/fwo-api-calls/extRequest/subscribeExtRequestStateUpdate.graphql new file mode 100644 index 0000000000..a9de551181 --- /dev/null +++ b/roles/common/files/fwo-api-calls/extRequest/subscribeExtRequestStateUpdate.graphql @@ -0,0 +1,9 @@ +subscription subscribeExtRequestStateUpdate ($id: bigint!){ + ext_request(where: { id: {_eq: $id} }, limit: 1) { + id + owner_id + ticket_id + task_number + ext_request_state + } +} diff --git a/roles/common/files/fwo-api-calls/extRequest/updateExtRequestCreation.graphql b/roles/common/files/fwo-api-calls/extRequest/updateExtRequestCreation.graphql new file mode 100644 index 0000000000..ddd201bb63 --- /dev/null +++ b/roles/common/files/fwo-api-calls/extRequest/updateExtRequestCreation.graphql @@ -0,0 +1,20 @@ +mutation updateExtRequestCreation( + $id: bigint! + $extRequestState: String! + $extTicketId: String + $creationResponse: String + $waitCycles: Int! + $attempts: Int! + ) { + update_ext_request_by_pk( + pk_columns: { id: $id } + _set: { + ext_request_state: $extRequestState + ext_ticket_id: $extTicketId + last_creation_response: $creationResponse + wait_cycles: $waitCycles + attempts: $attempts + }) { + updatedIdLong: id + } +} diff --git a/roles/common/files/fwo-api-calls/extRequest/updateExtRequestFinal.graphql b/roles/common/files/fwo-api-calls/extRequest/updateExtRequestFinal.graphql new file mode 100644 index 0000000000..3377434914 --- /dev/null +++ b/roles/common/files/fwo-api-calls/extRequest/updateExtRequestFinal.graphql @@ -0,0 +1,14 @@ +mutation updateExtRequestFinal( + $id: bigint! + $extRequestState: String! + $finishDate: timestamp + ) { + update_ext_request_by_pk( + pk_columns: { id: $id } + _set: { + ext_request_state: $extRequestState + finish_date: $finishDate + }) { + updatedIdLong: id + } +} diff --git a/roles/common/files/fwo-api-calls/extRequest/updateExtRequestProcess.graphql b/roles/common/files/fwo-api-calls/extRequest/updateExtRequestProcess.graphql new file mode 100644 index 0000000000..abb4ff0038 --- /dev/null +++ b/roles/common/files/fwo-api-calls/extRequest/updateExtRequestProcess.graphql @@ -0,0 +1,14 @@ +mutation updateExtRequestProcess( + $id: bigint! + $extRequestState: String! + $processingResponse: String + ) { + update_ext_request_by_pk( + pk_columns: { id: $id } + _set: { + ext_request_state: $extRequestState + last_processing_response: $processingResponse + }) { + updatedIdLong: id + } +} diff --git a/roles/common/files/fwo-api-calls/extRequest/updateExternalRequestLock.graphql b/roles/common/files/fwo-api-calls/extRequest/updateExternalRequestLock.graphql new file mode 100644 index 0000000000..39817bac8b --- /dev/null +++ b/roles/common/files/fwo-api-calls/extRequest/updateExternalRequestLock.graphql @@ -0,0 +1,12 @@ +mutation updateExternalRequestLock( + $id: bigint! + $locked: Boolean! + ) { + update_ext_request_by_pk( + pk_columns: { id: $id } + _set: { + locked: $locked + }) { + updatedIdLong: id + } +} diff --git a/roles/common/files/fwo-api-calls/extRequest/updateExternalRequestWaitCycles.graphql b/roles/common/files/fwo-api-calls/extRequest/updateExternalRequestWaitCycles.graphql new file mode 100644 index 0000000000..cf1a988dc8 --- /dev/null +++ b/roles/common/files/fwo-api-calls/extRequest/updateExternalRequestWaitCycles.graphql @@ -0,0 +1,12 @@ +mutation updateExternalRequestWaitCycles( + $id: bigint! + $waitCycles: Int! + ) { + update_ext_request_by_pk( + pk_columns: { id: $id } + _set: { + wait_cycles: $waitCycles + }) { + updatedIdLong: id + } +} diff --git a/roles/common/files/fwo-api-calls/import/addImportConfig.grahpql b/roles/common/files/fwo-api-calls/import/addImportConfig.grahpql new file mode 100644 index 0000000000..58ed3c1360 --- /dev/null +++ b/roles/common/files/fwo-api-calls/import/addImportConfig.grahpql @@ -0,0 +1,5 @@ +mutation addImportConfig($importId: bigint!, $mgmId: Int!, $config: jsonb!, $start_import_flag: Boolean!, $debug_mode: Boolean!) { + insert_import_config(objects: {start_import_flag: $start_import_flag, import_id: $importId, mgm_id: $mgmId, config: $config, debug_mode: $debug_mode}) { + affected_rows + } +} \ No newline at end of file diff --git a/roles/common/files/fwo-api-calls/import/addImportForMgm.graphql b/roles/common/files/fwo-api-calls/import/addImportForMgm.graphql new file mode 100644 index 0000000000..3e49ff512b --- /dev/null +++ b/roles/common/files/fwo-api-calls/import/addImportForMgm.graphql @@ -0,0 +1,17 @@ +mutation addImportForMgm( + $mgmId: Int! + $isInitialImport: Boolean! + $importTypeId: Int! +) { + insert_import_control( + objects: { + mgm_id: $mgmId + is_initial_import: $isInitialImport + import_type_id: $importTypeId + } + ) { + returning { + control_id + } + } +} diff --git a/roles/common/files/fwo-api-calls/import/addImportForOwner.graphql b/roles/common/files/fwo-api-calls/import/addImportForOwner.graphql new file mode 100644 index 0000000000..035a56eacb --- /dev/null +++ b/roles/common/files/fwo-api-calls/import/addImportForOwner.graphql @@ -0,0 +1,9 @@ +mutation addImportForOwner($importTypeId: Int!) { + insert_import_control( + objects: { import_type_id: $importTypeId, changes_found: true } + ) { + returning { + control_id + } + } +} diff --git a/roles/common/files/fwo-api-calls/import/addImportForRuleOwner.graphql b/roles/common/files/fwo-api-calls/import/addImportForRuleOwner.graphql new file mode 100644 index 0000000000..1fa70cfba3 --- /dev/null +++ b/roles/common/files/fwo-api-calls/import/addImportForRuleOwner.graphql @@ -0,0 +1,7 @@ +mutation addImportForRuleOwner($importTypeId: Int!) { + insert_import_control(objects: { import_type_id: $importTypeId }) { + returning { + control_id + } + } +} diff --git a/roles/lib/files/FWO.Api.Client/APIcalls/device/deleteImport.graphql b/roles/common/files/fwo-api-calls/import/deleteImport.graphql similarity index 76% rename from roles/lib/files/FWO.Api.Client/APIcalls/device/deleteImport.graphql rename to roles/common/files/fwo-api-calls/import/deleteImport.graphql index fc5de78230..6f601dbce9 100644 --- a/roles/lib/files/FWO.Api.Client/APIcalls/device/deleteImport.graphql +++ b/roles/common/files/fwo-api-calls/import/deleteImport.graphql @@ -1,4 +1,4 @@ -mutation delete_import($mgmId: Int!) { +deletemutation delete_import($mgmId: Int!) { delete_import_control(where: {mgm_id: {_eq: $mgmId}, successful_import: {_eq: false}, stop_time: {_is_null: true}}) { affected_rows } diff --git a/roles/common/files/fwo-api-calls/import/deleteImportConfig.graphql b/roles/common/files/fwo-api-calls/import/deleteImportConfig.graphql new file mode 100644 index 0000000000..0e0433d3af --- /dev/null +++ b/roles/common/files/fwo-api-calls/import/deleteImportConfig.graphql @@ -0,0 +1,3 @@ +mutation deleteImportConfig($importId: bigint!) { + delete_import_config(where: {import_id: {_eq: $importId}}) { affected_rows } +} diff --git a/roles/common/files/fwo-api-calls/import/deleteLatestConfigOfManagement.graphql b/roles/common/files/fwo-api-calls/import/deleteLatestConfigOfManagement.graphql new file mode 100644 index 0000000000..927fcbf0d5 --- /dev/null +++ b/roles/common/files/fwo-api-calls/import/deleteLatestConfigOfManagement.graphql @@ -0,0 +1,5 @@ +mutation deleteLatestConfigOfManagement($mgmId: Int!) { + delete_latest_config(where: { mgm_id: { _eq: $mgmId } }) { + affected_rows + } +} diff --git a/roles/common/files/fwo-api-calls/import/deleteOldImports.graphql b/roles/common/files/fwo-api-calls/import/deleteOldImports.graphql new file mode 100644 index 0000000000..7686f348ed --- /dev/null +++ b/roles/common/files/fwo-api-calls/import/deleteOldImports.graphql @@ -0,0 +1,7 @@ +mutation deleteOldImports($mgmId: Int!, $lastImportToKeep: bigint!) { + delete_import_control(where: {mgm_id: {_eq: $mgmId}, control_id: {_lt: $lastImportToKeep}}) { + returning { + control_id + } + } +} \ No newline at end of file diff --git a/roles/common/files/fwo-api-calls/import/getChangesPerImport.graphql b/roles/common/files/fwo-api-calls/import/getChangesPerImport.graphql new file mode 100644 index 0000000000..b37d7f3980 --- /dev/null +++ b/roles/common/files/fwo-api-calls/import/getChangesPerImport.graphql @@ -0,0 +1,6 @@ +query getChangesPerImport($importId: bigint!) { + changelog_object_aggregate(where: {control_id: {_eq: $importId}}) { aggregate { count } } + changelog_service_aggregate(where: {control_id: {_eq: $importId}}) { aggregate { count } } + changelog_user_aggregate(where: {control_id: {_eq: $importId}}) { aggregate { count } } + changelog_rule_aggregate(where: {control_id: {_eq: $importId}}) { aggregate { count } } +} diff --git a/roles/common/files/fwo-api-calls/import/getLastCompleteImport.graphql b/roles/common/files/fwo-api-calls/import/getLastCompleteImport.graphql new file mode 100644 index 0000000000..67f41c5299 --- /dev/null +++ b/roles/common/files/fwo-api-calls/import/getLastCompleteImport.graphql @@ -0,0 +1,11 @@ +query getLastCompleteImport($mgmId: Int!) { + import_control( + order_by: { control_id: desc } + limit: 1 + where: { mgm_id: { _eq: $mgmId }, stop_time: {_is_null: false} } + ) { + start_time + control_id + } +} + diff --git a/roles/common/files/fwo-api-calls/import/getLastImport.graphql b/roles/common/files/fwo-api-calls/import/getLastImport.graphql new file mode 100644 index 0000000000..e92afe7c09 --- /dev/null +++ b/roles/common/files/fwo-api-calls/import/getLastImport.graphql @@ -0,0 +1,11 @@ +query getLastImport($mgmId: Int!) { + import_control( + order_by: { control_id: desc } + limit: 1 + where: { mgm_id: { _eq: $mgmId }} + ) { + start_time + control_id + } +} + diff --git a/roles/common/files/fwo-api-calls/import/getLastSuccessImport.graphql b/roles/common/files/fwo-api-calls/import/getLastSuccessImport.graphql new file mode 100644 index 0000000000..74fbdc3c29 --- /dev/null +++ b/roles/common/files/fwo-api-calls/import/getLastSuccessImport.graphql @@ -0,0 +1,11 @@ +query getLastSuccessImport($mgmId: Int!) { + import_control( + order_by: { control_id: desc } + limit: 1 + where: { mgm_id: { _eq: $mgmId }, successful_import: { _eq: true } } + ) { + start_time + control_id + } +} + diff --git a/roles/common/files/fwo-api-calls/import/getLatestConfig.graphql b/roles/common/files/fwo-api-calls/import/getLatestConfig.graphql new file mode 100644 index 0000000000..bc692d5ac1 --- /dev/null +++ b/roles/common/files/fwo-api-calls/import/getLatestConfig.graphql @@ -0,0 +1,6 @@ +query getLatestConfig($mgmId: Int!) { + latest_config(where: { mgm_id: { _eq: $mgmId } }) { + import_id + config + } +} diff --git a/roles/common/files/fwo-api-calls/import/getMaxImportId.graphql b/roles/common/files/fwo-api-calls/import/getMaxImportId.graphql new file mode 100644 index 0000000000..70fb2072a5 --- /dev/null +++ b/roles/common/files/fwo-api-calls/import/getMaxImportId.graphql @@ -0,0 +1,9 @@ +query getMaxImportId { + import_control_aggregate { + aggregate { + max { + id: control_id + } + } + } +} diff --git a/roles/common/files/fwo-api-calls/import/getPendingRuleOwnerImports.graphql b/roles/common/files/fwo-api-calls/import/getPendingRuleOwnerImports.graphql new file mode 100644 index 0000000000..0007463207 --- /dev/null +++ b/roles/common/files/fwo-api-calls/import/getPendingRuleOwnerImports.graphql @@ -0,0 +1,11 @@ +query getPendingRuleOwnerImports { + import_control(where: { + is_initial_import: {_eq: false} + successful_import: {_eq: true} + changes_found: {_eq: true} + rule_owner_mapping_done: {_eq: false} + } order_by: {control_id: asc}) { + control_id + import_type_id + } +} diff --git a/roles/common/files/fwo-api-calls/import/getRuleChangesPerImport.graphql b/roles/common/files/fwo-api-calls/import/getRuleChangesPerImport.graphql new file mode 100644 index 0000000000..4d96b63126 --- /dev/null +++ b/roles/common/files/fwo-api-calls/import/getRuleChangesPerImport.graphql @@ -0,0 +1,5 @@ +query getRuleChangesPerImport($importId: bigint!) { + changelog_rule_aggregate(where: {control_id: {_eq: $importId}}) { + aggregate { count } + } +} diff --git a/roles/common/files/fwo-api-calls/import/rollbackImport.graphql b/roles/common/files/fwo-api-calls/import/rollbackImport.graphql new file mode 100644 index 0000000000..8038303e44 --- /dev/null +++ b/roles/common/files/fwo-api-calls/import/rollbackImport.graphql @@ -0,0 +1,52 @@ +mutation rollbackImport($importId: bigint!) { + delete_objgrp(where: {import_created: {_eq: $importId}}) { affected_rows } + delete_svcgrp(where: {import_created: {_eq: $importId}}) { affected_rows } + delete_usergrp(where: {import_created: {_eq: $importId}}) { affected_rows } + delete_objgrp_flat(where: {import_created: {_eq: $importId}}) { affected_rows } + delete_svcgrp_flat(where: {import_created: {_eq: $importId}}) { affected_rows } + delete_usergrp_flat(where: {import_created: {_eq: $importId}}) { affected_rows } + delete_rule_to(where: {rt_create: {_eq: $importId}}) { affected_rows } + delete_rule_from(where: {rf_create: {_eq: $importId}}) { affected_rows } + delete_rule_service(where: {rs_create: {_eq: $importId}}) { affected_rows } + delete_rule_nwobj_resolved(where: {created: {_eq: $importId}}) { affected_rows } + delete_rule_svc_resolved(where: {created: {_eq: $importId}}) { affected_rows } + delete_rule_user_resolved(where: {created: {_eq: $importId}}) { affected_rows } + delete_rule_from_zone(where: {created: {_eq: $importId}}) { affected_rows } + delete_rule_to_zone(where: {created: {_eq: $importId}}) { affected_rows } + delete_rule_time(where: {created: {_eq: $importId}}) { affected_rows } + delete_rule_enforced_on_gateway(where: {created: {_eq: $importId}}) { affected_rows } + delete_object(where: {obj_create: {_eq: $importId}}) { affected_rows } + delete_service(where: {svc_create: {_eq: $importId}}) { affected_rows } + delete_usr(where: {user_create: {_eq: $importId}}) { affected_rows } + delete_zone(where: {zone_create: {_eq: $importId}}) { affected_rows } + delete_time_object(where: {created: {_eq: $importId}}) { affected_rows } + delete_rule_metadata(where: {rule_created: {_eq: $importId}}) { affected_rows } + delete_rule(where: {rule_create: {_eq: $importId}}) { affected_rows } + delete_rulebase_link(where: {created: {_eq: $importId}}) { affected_rows } + delete_rulebase(where: {created: {_eq: $importId}}) { affected_rows } + update_rule(where: {removed: {_eq: $importId}}, _set: {removed: null}) { affected_rows } + update_rulebase(where: {removed: {_eq: $importId}}, _set: {removed: null}) { affected_rows } + update_rulebase_link(where: {removed: {_eq: $importId}}, _set: {removed: null}) { affected_rows } + update_object(where: {removed: {_eq: $importId}}, _set: {removed: null}) { affected_rows } + update_service(where: {removed: {_eq: $importId}}, _set: {removed: null}) { affected_rows } + update_usr(where: {removed: {_eq: $importId}}, _set: {removed: null}) { affected_rows } + update_zone(where: {removed: {_eq: $importId}}, _set: {removed: null}) { affected_rows } + update_time_object(where: {removed: {_eq: $importId}}, _set: {removed: null}) { affected_rows } + update_objgrp(where: {removed: {_eq: $importId}}, _set: {removed: null}) { affected_rows } + update_svcgrp(where: {removed: {_eq: $importId}}, _set: {removed: null}) { affected_rows } + update_usergrp(where: {removed: {_eq: $importId}}, _set: {removed: null}) { affected_rows } + update_objgrp_flat(where: {removed: {_eq: $importId}}, _set: {removed: null}) { affected_rows } + update_svcgrp_flat(where: {removed: {_eq: $importId}}, _set: {removed: null}) { affected_rows } + update_usergrp_flat(where: {removed: {_eq: $importId}}, _set: {removed: null}) { affected_rows } + update_rule_to(where: {removed: {_eq: $importId}}, _set: {removed: null}) { affected_rows } + update_rule_from(where: {removed: {_eq: $importId}}, _set: {removed: null}) { affected_rows } + update_rule_service(where: {removed: {_eq: $importId}}, _set: {removed: null}) { affected_rows } + update_rule_nwobj_resolved(where: {removed: {_eq: $importId}}, _set: {removed: null}) { affected_rows } + update_rule_svc_resolved(where: {removed: {_eq: $importId}}, _set: {removed: null}) { affected_rows } + update_rule_user_resolved(where: {removed: {_eq: $importId}}, _set: {removed: null}) { affected_rows } + update_rule_from_zone(where: {removed: {_eq: $importId}}, _set: {removed: null}) { affected_rows } + update_rule_to_zone(where: {removed: {_eq: $importId}}, _set: {removed: null}) { affected_rows } + update_rule_time(where: {removed: {_eq: $importId}}, _set: {removed: null}) { affected_rows } + update_rule_enforced_on_gateway(where: {removed: {_eq: $importId}}, _set: {removed: null}) { affected_rows } + delete_import_control(where: {control_id: {_eq: $importId}}) { affected_rows } +} diff --git a/roles/common/files/fwo-api-calls/import/storeLatestConfig.graphql b/roles/common/files/fwo-api-calls/import/storeLatestConfig.graphql new file mode 100644 index 0000000000..bbde916cbe --- /dev/null +++ b/roles/common/files/fwo-api-calls/import/storeLatestConfig.graphql @@ -0,0 +1,5 @@ +mutation storeLatestConfig($importId: bigint!, $mgmId: Int!, $config: jsonb!) { + insert_latest_config(objects: {import_id: $importId, mgm_id: $mgmId, config: $config}) { + affected_rows + } +} diff --git a/roles/common/files/fwo-api-calls/import/updateImportControlForRuleOwnerFull.graphql b/roles/common/files/fwo-api-calls/import/updateImportControlForRuleOwnerFull.graphql new file mode 100644 index 0000000000..9d3b5e5c3f --- /dev/null +++ b/roles/common/files/fwo-api-calls/import/updateImportControlForRuleOwnerFull.graphql @@ -0,0 +1,18 @@ +mutation updateImportControlForRuleOwnerFull($controlId: bigint!, $stopTime: timestamp, $successful: Boolean, $rule_owner_mapping_done: Boolean!) { + update_import_control( + where: { control_id: { _eq: $controlId } }, + _set: { + stop_time: $stopTime, + successful_import: $successful, + rule_owner_mapping_done: $rule_owner_mapping_done + } + ) { + affected_rows + returning { + control_id + stop_time + successful_import + rule_owner_mapping_done + } + } +} \ No newline at end of file diff --git a/roles/common/files/fwo-api-calls/import/updateImportControlForRuleOwnerInc.graphql b/roles/common/files/fwo-api-calls/import/updateImportControlForRuleOwnerInc.graphql new file mode 100644 index 0000000000..38aa7f404f --- /dev/null +++ b/roles/common/files/fwo-api-calls/import/updateImportControlForRuleOwnerInc.graphql @@ -0,0 +1,14 @@ +mutation updateImportControlForRuleOwnerInc($controlId: bigint!, $rule_owner_mapping_done: Boolean!) { + update_import_control( + where: { control_id: { _eq: $controlId } }, + _set: { + rule_owner_mapping_done: $rule_owner_mapping_done + } + ) { + affected_rows + returning { + control_id + rule_owner_mapping_done + } + } +} \ No newline at end of file diff --git a/roles/common/files/fwo-api-calls/import/updateImportStopTime.graphql b/roles/common/files/fwo-api-calls/import/updateImportStopTime.graphql new file mode 100644 index 0000000000..68c2fc91e4 --- /dev/null +++ b/roles/common/files/fwo-api-calls/import/updateImportStopTime.graphql @@ -0,0 +1,6 @@ + +mutation updateImportStopTime($importId: bigint!, $stopTime: timestamp!, $success: Boolean, $policyChangesFound: Boolean!, $changesFound: Boolean!, $changeNumber: Int!) { + update_import_control(where: {control_id: {_eq: $importId}}, _set: {stop_time: $stopTime, successful_import: $success, policy_changes_found: $policyChangesFound, changes_found: $changesFound, security_relevant_changes_counter: $changeNumber}) { + affected_rows + } +} \ No newline at end of file diff --git a/roles/common/files/fwo-api-calls/import/updateManagementLastImportAttempt.graphql b/roles/common/files/fwo-api-calls/import/updateManagementLastImportAttempt.graphql new file mode 100644 index 0000000000..af2b6a95f2 --- /dev/null +++ b/roles/common/files/fwo-api-calls/import/updateManagementLastImportAttempt.graphql @@ -0,0 +1,3 @@ +mutation updateManagementLastImportAttempt($mgmId: Int!, $timeStamp: timestamp!, $success: Boolean) { + update_management(where: {mgm_id: {_eq: $mgmId}}, _set: {last_import_attempt: $timeStamp, last_import_attempt_successful: $success } ) { affected_rows } +} diff --git a/roles/common/files/fwo-api-calls/modelling/addAppServerToConnection.graphql b/roles/common/files/fwo-api-calls/modelling/addAppServerToConnection.graphql new file mode 100644 index 0000000000..b287516851 --- /dev/null +++ b/roles/common/files/fwo-api-calls/modelling/addAppServerToConnection.graphql @@ -0,0 +1,15 @@ +mutation addAppServerToConnection( + $nwObjectId: bigint! + $connectionId: Int! + $connectionField: Int! + ) { + insert_modelling_nwobject_connection(objects: { + nwobject_id: $nwObjectId + connection_id: $connectionId + connection_field: $connectionField + }) { + returning { + insertedIdLong: nwobject_id + } + } +} diff --git a/roles/common/files/fwo-api-calls/modelling/addHistoryEntry.graphql b/roles/common/files/fwo-api-calls/modelling/addHistoryEntry.graphql new file mode 100644 index 0000000000..edd73fd2db --- /dev/null +++ b/roles/common/files/fwo-api-calls/modelling/addHistoryEntry.graphql @@ -0,0 +1,25 @@ +mutation addHistoryEntry( + $appId: Int + $changeType: Int! + $objectType: Int! + $objectId: bigint! + $changeText: String + $changer: String! + $changeSource: String +) { + insert_modelling_change_history( + objects: { + app_id: $appId + change_type: $changeType + object_type: $objectType + object_id: $objectId + change_text: $changeText + changer: $changer + change_source: $changeSource + } + ) { + returning { + newIdLong: id + } + } +} diff --git a/roles/common/files/fwo-api-calls/modelling/addNwAppZone.graphql b/roles/common/files/fwo-api-calls/modelling/addNwAppZone.graphql new file mode 100644 index 0000000000..db2e98b66e --- /dev/null +++ b/roles/common/files/fwo-api-calls/modelling/addNwAppZone.graphql @@ -0,0 +1,18 @@ +mutation newAppZone( + $appId: Int! + $name: String + $idString: String + $creator: String + ) { + insert_modelling_nwgroup(objects: { + app_id: $appId + name: $name + id_string: $idString + creator: $creator + group_type: 21 + }) { + returning { + newIdLong: id + } + } +} diff --git a/roles/common/files/fwo-api-calls/modelling/addNwGroupToConnection.graphql b/roles/common/files/fwo-api-calls/modelling/addNwGroupToConnection.graphql new file mode 100644 index 0000000000..bddfdc0e49 --- /dev/null +++ b/roles/common/files/fwo-api-calls/modelling/addNwGroupToConnection.graphql @@ -0,0 +1,15 @@ +mutation addNwGroupToConnection( + $nwGroupId: bigint! + $connectionId: Int! + $connectionField: Int! + ) { + insert_modelling_nwgroup_connection(objects: { + nwgroup_id: $nwGroupId + connection_id: $connectionId + connection_field: $connectionField + }) { + returning { + insertedIdLong: nwgroup_id + } + } +} diff --git a/roles/common/files/fwo-api-calls/modelling/addNwObjectToNwGroup.graphql b/roles/common/files/fwo-api-calls/modelling/addNwObjectToNwGroup.graphql new file mode 100644 index 0000000000..4a6222cf83 --- /dev/null +++ b/roles/common/files/fwo-api-calls/modelling/addNwObjectToNwGroup.graphql @@ -0,0 +1,13 @@ +mutation addNwObjectToNwGroup( + $nwObjectId: bigint! + $nwGroupId: bigint! + ) { + insert_modelling_nwobject_nwgroup(objects: { + nwobject_id: $nwObjectId + nwgroup_id: $nwGroupId + }) { + returning { + insertedIdLong: nwobject_id + } + } +} diff --git a/roles/common/files/fwo-api-calls/modelling/addPermittedOwner.graphql b/roles/common/files/fwo-api-calls/modelling/addPermittedOwner.graphql new file mode 100644 index 0000000000..876bbbd101 --- /dev/null +++ b/roles/common/files/fwo-api-calls/modelling/addPermittedOwner.graphql @@ -0,0 +1,14 @@ +mutation addPermittedOwner( + $connectionId: Int! + $appId: Int! + ) { + insert_modelling_permitted_owners(objects: { + connection_id: $connectionId + app_id: $appId + }) { + returning { + insertedConnectionId: connection_id + insertedAppId: app_id + } + } +} diff --git a/roles/common/files/fwo-api-calls/modelling/addSelectedConnection.graphql b/roles/common/files/fwo-api-calls/modelling/addSelectedConnection.graphql new file mode 100644 index 0000000000..a137d7b71f --- /dev/null +++ b/roles/common/files/fwo-api-calls/modelling/addSelectedConnection.graphql @@ -0,0 +1,13 @@ +mutation addSelectedConnection( + $appId: Int! + $connectionId: Int! + ) { + insert_modelling_selected_connections(objects: { + app_id: $appId + connection_id: $connectionId + }) { + returning { + insertedId: connection_id + } + } +} diff --git a/roles/common/files/fwo-api-calls/modelling/addSelectedNwGroupObject.graphql b/roles/common/files/fwo-api-calls/modelling/addSelectedNwGroupObject.graphql new file mode 100644 index 0000000000..33eacff859 --- /dev/null +++ b/roles/common/files/fwo-api-calls/modelling/addSelectedNwGroupObject.graphql @@ -0,0 +1,13 @@ +mutation addSelectedNwGroupObject( + $appId: Int! + $nwGroupId: bigint! + ) { + insert_modelling_selected_objects(objects: { + app_id: $appId + nwgroup_id: $nwGroupId + }) { + returning { + insertedIdLong: nwgroup_id + } + } +} diff --git a/roles/common/files/fwo-api-calls/modelling/addServiceGroupToConnection.graphql b/roles/common/files/fwo-api-calls/modelling/addServiceGroupToConnection.graphql new file mode 100644 index 0000000000..e60777c30a --- /dev/null +++ b/roles/common/files/fwo-api-calls/modelling/addServiceGroupToConnection.graphql @@ -0,0 +1,13 @@ +mutation addServiceGroupToConnection( + $serviceGroupId: Int! + $connectionId: Int! + ) { + insert_modelling_service_group_connection(objects: { + service_group_id: $serviceGroupId + connection_id: $connectionId + }) { + returning { + insertedId: service_group_id + } + } +} diff --git a/roles/common/files/fwo-api-calls/modelling/addServiceToConnection.graphql b/roles/common/files/fwo-api-calls/modelling/addServiceToConnection.graphql new file mode 100644 index 0000000000..2fa004d856 --- /dev/null +++ b/roles/common/files/fwo-api-calls/modelling/addServiceToConnection.graphql @@ -0,0 +1,13 @@ +mutation addServiceToConnection( + $serviceId: Int! + $connectionId: Int! + ) { + insert_modelling_service_connection(objects: { + service_id: $serviceId + connection_id: $connectionId + }) { + returning { + insertedId: service_id + } + } +} diff --git a/roles/common/files/fwo-api-calls/modelling/addServiceToServiceGroup.graphql b/roles/common/files/fwo-api-calls/modelling/addServiceToServiceGroup.graphql new file mode 100644 index 0000000000..e6d7c83549 --- /dev/null +++ b/roles/common/files/fwo-api-calls/modelling/addServiceToServiceGroup.graphql @@ -0,0 +1,13 @@ +mutation addServiceToServiceGroup( + $serviceId: Int! + $serviceGroupId: Int! + ) { + insert_modelling_service_service_group(objects: { + service_id: $serviceId + service_group_id: $serviceGroupId + }) { + returning { + insertedId: service_id + } + } +} diff --git a/roles/common/files/fwo-api-calls/modelling/deleteAppServer.graphql b/roles/common/files/fwo-api-calls/modelling/deleteAppServer.graphql new file mode 100644 index 0000000000..4d4a5bf0c7 --- /dev/null +++ b/roles/common/files/fwo-api-calls/modelling/deleteAppServer.graphql @@ -0,0 +1,5 @@ +mutation deleteAppServer($id: bigint!) { + delete_owner_network(where: {id: {_eq: $id}}) { + affected_rows + } +} diff --git a/roles/common/files/fwo-api-calls/modelling/deleteConnection.graphql b/roles/common/files/fwo-api-calls/modelling/deleteConnection.graphql new file mode 100644 index 0000000000..7939a151fa --- /dev/null +++ b/roles/common/files/fwo-api-calls/modelling/deleteConnection.graphql @@ -0,0 +1,5 @@ +mutation deleteConnection($id: Int!) { + delete_modelling_connection_by_pk(id: $id) { + deletedId: id + } +} diff --git a/roles/common/files/fwo-api-calls/modelling/deleteNwGroup.graphql b/roles/common/files/fwo-api-calls/modelling/deleteNwGroup.graphql new file mode 100644 index 0000000000..c692b5bd8a --- /dev/null +++ b/roles/common/files/fwo-api-calls/modelling/deleteNwGroup.graphql @@ -0,0 +1,5 @@ +mutation deleteNwGroup($id: bigint!) { + delete_modelling_nwgroup(where: {id: {_eq: $id}}) { + affected_rows + } +} diff --git a/roles/common/files/fwo-api-calls/modelling/deletePermittedOwner.graphql b/roles/common/files/fwo-api-calls/modelling/deletePermittedOwner.graphql new file mode 100644 index 0000000000..6ef94330da --- /dev/null +++ b/roles/common/files/fwo-api-calls/modelling/deletePermittedOwner.graphql @@ -0,0 +1,12 @@ +mutation deletePermittedOwner( + $connectionId: Int! + $appId: Int! + ) { + delete_modelling_permitted_owners_by_pk( + connection_id: $connectionId, + app_id: $appId + ) { + connection_id + app_id + } +} diff --git a/roles/common/files/fwo-api-calls/modelling/deleteService.graphql b/roles/common/files/fwo-api-calls/modelling/deleteService.graphql new file mode 100644 index 0000000000..5cde10ff40 --- /dev/null +++ b/roles/common/files/fwo-api-calls/modelling/deleteService.graphql @@ -0,0 +1,5 @@ +mutation deleteService($id: Int!) { + delete_modelling_service(where: {id: {_eq: $id}}) { + affected_rows + } +} diff --git a/roles/common/files/fwo-api-calls/modelling/deleteServiceGroup.graphql b/roles/common/files/fwo-api-calls/modelling/deleteServiceGroup.graphql new file mode 100644 index 0000000000..cd2dec375f --- /dev/null +++ b/roles/common/files/fwo-api-calls/modelling/deleteServiceGroup.graphql @@ -0,0 +1,5 @@ +mutation deleteServiceGroup($id: Int!) { + delete_modelling_service_group(where: {id: {_eq: $id}}) { + affected_rows + } +} diff --git a/roles/common/files/fwo-api-calls/modelling/fragments/appRoleDetails.graphql b/roles/common/files/fwo-api-calls/modelling/fragments/appRoleDetails.graphql new file mode 100644 index 0000000000..cb41fdd175 --- /dev/null +++ b/roles/common/files/fwo-api-calls/modelling/fragments/appRoleDetails.graphql @@ -0,0 +1,16 @@ +fragment appRoleDetails on modelling_nwgroup { + id + app_id + id_string + group_type + name + comment + is_deleted + creator + creation_date + nwobjects: nwobject_nwgroups{ + owner_network{ + ...appServerDetails + } + } +} diff --git a/roles/common/files/fwo-api-calls/modelling/fragments/appServerDetails.graphql b/roles/common/files/fwo-api-calls/modelling/fragments/appServerDetails.graphql new file mode 100644 index 0000000000..49e41864f4 --- /dev/null +++ b/roles/common/files/fwo-api-calls/modelling/fragments/appServerDetails.graphql @@ -0,0 +1,10 @@ +fragment appServerDetails on owner_network { + id + name + ip + ip_end + import_source + is_deleted + custom_type + app_id: owner_id +} diff --git a/roles/common/files/fwo-api-calls/modelling/fragments/areaDetails.graphql b/roles/common/files/fwo-api-calls/modelling/fragments/areaDetails.graphql new file mode 100644 index 0000000000..69049506c3 --- /dev/null +++ b/roles/common/files/fwo-api-calls/modelling/fragments/areaDetails.graphql @@ -0,0 +1,14 @@ +fragment areaDetails on modelling_nwgroup { + id + name + id_string + is_deleted + ip_data: nwobject_nwgroups{ + owner_network{ + id + name + ip + ip_end + } + } +} diff --git a/roles/common/files/fwo-api-calls/modelling/fragments/connectionDetails.graphql b/roles/common/files/fwo-api-calls/modelling/fragments/connectionDetails.graphql new file mode 100644 index 0000000000..fca881f713 --- /dev/null +++ b/roles/common/files/fwo-api-calls/modelling/fragments/connectionDetails.graphql @@ -0,0 +1,63 @@ +fragment connectionDetails on modelling_connection { + id + app_id + proposed_app_id + name + reason + is_interface + used_interface_id + is_requested + is_published + ticket_id + common_service + creator + creation_date + conn_prop + extra_params + requested_on_fw + removed + removal_date + interface_permission + owner { + id + name + app_id_external + } + permitted_owners { + owner { + id + name + app_id_external + } + } + source_nwobjects: nwobject_connections (where: { connection_field: { _eq: 1 } }){ + owner_network{ + ...appServerDetails + } + } + source_approles: nwgroup_connections (where: { connection_field: { _eq: 1 } }){ + nwgroup{ + ...appRoleDetails + } + } + destination_nwobjects: nwobject_connections (where: { connection_field: { _eq: 2 } }){ + owner_network{ + ...appServerDetails + } + } + destination_approles: nwgroup_connections (where: { connection_field: { _eq: 2 } }){ + nwgroup{ + ...appRoleDetails + } + } + service_groups: service_group_connections{ + service_group{ + ...serviceGroupDetails + } + } + services: service_connections{ + service{ + ...serviceDetails + } + } +} diff --git a/roles/common/files/fwo-api-calls/modelling/fragments/connectionResolvedDetails.graphql b/roles/common/files/fwo-api-calls/modelling/fragments/connectionResolvedDetails.graphql new file mode 100644 index 0000000000..9e73dd3bce --- /dev/null +++ b/roles/common/files/fwo-api-calls/modelling/fragments/connectionResolvedDetails.graphql @@ -0,0 +1,83 @@ +fragment connectionResolvedDetails on modelling_connection { + id + app_id + proposed_app_id + owner: owner { + id + name + app_id_external + } + name + reason + is_interface + used_interface_id + is_requested + is_published + ticket_id + common_service + creator + creation_date + conn_prop + extra_params + requested_on_fw + removed + removal_date + interface_permission + permitted_owners { + owner { + id + name + app_id_external + } + } + source_nwobjects: nwobject_connections (where: { connection_field: { _eq: 1 } }){ + owner_network{ + ...appServerDetails + } + } + source_approles: nwgroup_connections (where: { connection_field: { _eq: 1 }, nwgroup: { group_type: { _eq: 20 } } }){ + nwgroup { + ...appRoleDetails + } + } + source_areas: nwgroup_connections (where: { connection_field: { _eq: 1 }, nwgroup: { group_type: { _eq: 23 } } }){ + nwgroup { + ...areaDetails + } + } + source_other_groups: nwgroup_connections (where: { connection_field: { _eq: 1 }, nwgroup: { group_type: { _nin: [20, 23] } } }){ + nwgroup { + ...appRoleDetails + } + } + destination_nwobjects: nwobject_connections (where: { connection_field: { _eq: 2 } }){ + owner_network{ + ...appServerDetails + } + } + destination_approles: nwgroup_connections (where: { connection_field: { _eq: 2 }, nwgroup: { group_type: { _eq: 20 } } } ){ + nwgroup{ + ...appRoleDetails + } + } + destination_areas: nwgroup_connections (where: { connection_field: { _eq: 2 }, nwgroup: { group_type: { _eq: 23 } } }){ + nwgroup{ + ...areaDetails + } + } + destination_other_groups: nwgroup_connections (where: { connection_field: { _eq: 2 }, nwgroup: { group_type: { _nin: [20, 23] } } }){ + nwgroup { + ...appRoleDetails + } + } + service_groups: service_group_connections{ + service_group{ + ...serviceGroupDetails + } + } + services: service_connections{ + service{ + ...serviceDetails + } + } +} diff --git a/roles/common/files/fwo-api-calls/modelling/fragments/serviceDetails.graphql b/roles/common/files/fwo-api-calls/modelling/fragments/serviceDetails.graphql new file mode 100644 index 0000000000..49a5975717 --- /dev/null +++ b/roles/common/files/fwo-api-calls/modelling/fragments/serviceDetails.graphql @@ -0,0 +1,12 @@ +fragment serviceDetails on modelling_service { + id + name + is_global + port + port_end + proto_id + protocol: stm_ip_proto { + id: ip_proto_id + name: ip_proto_name + } +} diff --git a/roles/common/files/fwo-api-calls/modelling/fragments/serviceGroupDetails.graphql b/roles/common/files/fwo-api-calls/modelling/fragments/serviceGroupDetails.graphql new file mode 100644 index 0000000000..1508cfaaf0 --- /dev/null +++ b/roles/common/files/fwo-api-calls/modelling/fragments/serviceGroupDetails.graphql @@ -0,0 +1,14 @@ +fragment serviceGroupDetails on modelling_service_group { + id + app_id + name + is_global + comment + creator + creation_date + services: service_service_groups{ + service{ + ...serviceDetails + } + } +} diff --git a/roles/common/files/fwo-api-calls/modelling/getAllAppServers.graphql b/roles/common/files/fwo-api-calls/modelling/getAllAppServers.graphql new file mode 100644 index 0000000000..56f224a423 --- /dev/null +++ b/roles/common/files/fwo-api-calls/modelling/getAllAppServers.graphql @@ -0,0 +1,5 @@ +query getAllAppServers { + owner_network (where: { nw_type: { _eq: 10 } } order_by: { name: asc }){ + ...appServerDetails + } +} diff --git a/roles/common/files/fwo-api-calls/modelling/getAppRoles.graphql b/roles/common/files/fwo-api-calls/modelling/getAppRoles.graphql new file mode 100644 index 0000000000..0f87568f9a --- /dev/null +++ b/roles/common/files/fwo-api-calls/modelling/getAppRoles.graphql @@ -0,0 +1,10 @@ +query getAppRoles ($appId: Int!){ + modelling_nwgroup (where: { app_id: { _eq: $appId }, group_type: { _eq: 20 }, is_deleted: { _eq: false } } order_by: { name: asc }){ + ...appRoleDetails + nwobjects: nwobject_nwgroups{ + owner_network{ + ...appServerDetails + } + } + } +} diff --git a/roles/common/files/fwo-api-calls/modelling/getAppRolesForAppServer.graphql b/roles/common/files/fwo-api-calls/modelling/getAppRolesForAppServer.graphql new file mode 100644 index 0000000000..19e4ed8f9d --- /dev/null +++ b/roles/common/files/fwo-api-calls/modelling/getAppRolesForAppServer.graphql @@ -0,0 +1,5 @@ +query getAppRolesForAppServer ($id: bigint!){ + modelling_nwobject_nwgroup (where: { nwobject_id: { _eq: $id }, nwgroup: { group_type: { _eq: 20 } } }){ + id: nwgroup_id + } +} diff --git a/roles/common/files/fwo-api-calls/modelling/getAppServersByIp.graphql b/roles/common/files/fwo-api-calls/modelling/getAppServersByIp.graphql new file mode 100644 index 0000000000..fcbba45261 --- /dev/null +++ b/roles/common/files/fwo-api-calls/modelling/getAppServersByIp.graphql @@ -0,0 +1,9 @@ +query getAppServersByIp ( + $appId: Int! + $ip: cidr! + $ipEnd: cidr! + ){ + owner_network (where: { owner_id: { _eq: $appId }, nw_type: { _eq: 10 }, ip: { _eq: $ip }, ip_end: { _eq: $ipEnd } } order_by: { name: asc }){ + ...appServerDetails + } +} diff --git a/roles/common/files/fwo-api-calls/modelling/getAppServersByName.graphql b/roles/common/files/fwo-api-calls/modelling/getAppServersByName.graphql new file mode 100644 index 0000000000..ab06e0b1f8 --- /dev/null +++ b/roles/common/files/fwo-api-calls/modelling/getAppServersByName.graphql @@ -0,0 +1,8 @@ +query getAppServersByName ( + $appId: Int! + $name: String! + ){ + owner_network (where: { owner_id: { _eq: $appId }, nw_type: { _eq: 10 }, name: { _eq: $name } } order_by: { name: asc }){ + ...appServerDetails + } +} diff --git a/roles/common/files/fwo-api-calls/modelling/getAppServersBySource.graphql b/roles/common/files/fwo-api-calls/modelling/getAppServersBySource.graphql new file mode 100644 index 0000000000..9d1ee194f8 --- /dev/null +++ b/roles/common/files/fwo-api-calls/modelling/getAppServersBySource.graphql @@ -0,0 +1,5 @@ +query getAppServersBySource ($importSource: String!, $appId: Int){ + owner_network (where: { import_source: { _ilike: $importSource }, nw_type: { _eq: 10 }, owner_id: { _eq: $appId } }){ + ...appServerDetails + } +} diff --git a/roles/common/files/fwo-api-calls/modelling/getAppServersForOwner.graphql b/roles/common/files/fwo-api-calls/modelling/getAppServersForOwner.graphql new file mode 100644 index 0000000000..3170f7e6be --- /dev/null +++ b/roles/common/files/fwo-api-calls/modelling/getAppServersForOwner.graphql @@ -0,0 +1,5 @@ +query getAppServersForOwner ($appId: Int!){ + owner_network (where: { owner_id: { _eq: $appId }, nw_type: { _eq: 10 } } order_by: { name: asc }){ + ...appServerDetails + } +} diff --git a/roles/common/files/fwo-api-calls/modelling/getAppZonesByAppId.graphql b/roles/common/files/fwo-api-calls/modelling/getAppZonesByAppId.graphql new file mode 100644 index 0000000000..f1c3b94636 --- /dev/null +++ b/roles/common/files/fwo-api-calls/modelling/getAppZonesByAppId.graphql @@ -0,0 +1,14 @@ +query getAppZonesByAppId($appId: Int!) { + modelling_nwgroup (where: { group_type: { _eq: 21 }, app_id: { _eq: $appId} } order_by: { name: asc }){ + id + app_id + name + id_string + is_deleted + nwobjects: nwobject_nwgroups{ + owner_network{ + ...appServerDetails + } + } + } +} diff --git a/roles/common/files/fwo-api-calls/modelling/getAreas.graphql b/roles/common/files/fwo-api-calls/modelling/getAreas.graphql new file mode 100644 index 0000000000..0657947450 --- /dev/null +++ b/roles/common/files/fwo-api-calls/modelling/getAreas.graphql @@ -0,0 +1,5 @@ +query getAreas { + modelling_nwgroup (where: { group_type: { _eq: 23 } } order_by: { name: asc }){ + ...areaDetails + } +} diff --git a/roles/common/files/fwo-api-calls/modelling/getCommonServices.graphql b/roles/common/files/fwo-api-calls/modelling/getCommonServices.graphql new file mode 100644 index 0000000000..bd8b68c355 --- /dev/null +++ b/roles/common/files/fwo-api-calls/modelling/getCommonServices.graphql @@ -0,0 +1,9 @@ +query getCommonServices{ + modelling_connection (where: { common_service: { _eq: true }, removed: { _eq: false } } order_by: { name: asc }){ + ...connectionDetails + owner{ + name + app_id_external + } + } +} diff --git a/roles/common/files/fwo-api-calls/modelling/getConnectionById.graphql b/roles/common/files/fwo-api-calls/modelling/getConnectionById.graphql new file mode 100644 index 0000000000..0a9b837207 --- /dev/null +++ b/roles/common/files/fwo-api-calls/modelling/getConnectionById.graphql @@ -0,0 +1,5 @@ +query getConnectionById($id: Int!){ + modelling_connection (where: { id: { _eq: $id } }){ + ...connectionDetails + } +} diff --git a/roles/common/files/fwo-api-calls/modelling/getConnectionIdsForAppServer.graphql b/roles/common/files/fwo-api-calls/modelling/getConnectionIdsForAppServer.graphql new file mode 100644 index 0000000000..8175e50618 --- /dev/null +++ b/roles/common/files/fwo-api-calls/modelling/getConnectionIdsForAppServer.graphql @@ -0,0 +1,5 @@ +query getConnectionIdsForAppServer ($id: bigint!){ + modelling_nwobject_connection (where: { nwobject_id: { _eq: $id } }){ + connection_id + } +} diff --git a/roles/common/files/fwo-api-calls/modelling/getConnectionIdsForNwGroup.graphql b/roles/common/files/fwo-api-calls/modelling/getConnectionIdsForNwGroup.graphql new file mode 100644 index 0000000000..d0e0c0f2d6 --- /dev/null +++ b/roles/common/files/fwo-api-calls/modelling/getConnectionIdsForNwGroup.graphql @@ -0,0 +1,8 @@ +query getConnectionIdsForNwGroup ($id: bigint!){ + modelling_nwgroup_connection (where: { nwgroup_id: { _eq: $id } }){ + connection { + id + removed + } + } +} diff --git a/roles/common/files/fwo-api-calls/modelling/getConnectionIdsForService.graphql b/roles/common/files/fwo-api-calls/modelling/getConnectionIdsForService.graphql new file mode 100644 index 0000000000..362dc7db48 --- /dev/null +++ b/roles/common/files/fwo-api-calls/modelling/getConnectionIdsForService.graphql @@ -0,0 +1,5 @@ +query getConnectionIdsForService ($serviceId: Int!){ + modelling_service_connection (where: { service_id: { _eq: $serviceId } }){ + connection_id + } +} diff --git a/roles/common/files/fwo-api-calls/modelling/getConnectionIdsForServiceGroup.graphql b/roles/common/files/fwo-api-calls/modelling/getConnectionIdsForServiceGroup.graphql new file mode 100644 index 0000000000..16b3329d33 --- /dev/null +++ b/roles/common/files/fwo-api-calls/modelling/getConnectionIdsForServiceGroup.graphql @@ -0,0 +1,5 @@ +query getConnectionIdsForServiceGroup ($serviceGroupId: Int!){ + modelling_service_group_connection (where: { service_group_id: { _eq: $serviceGroupId } }){ + connection_id + } +} diff --git a/roles/common/files/fwo-api-calls/modelling/getConnections.graphql b/roles/common/files/fwo-api-calls/modelling/getConnections.graphql new file mode 100644 index 0000000000..906b2453e0 --- /dev/null +++ b/roles/common/files/fwo-api-calls/modelling/getConnections.graphql @@ -0,0 +1,5 @@ +query getConnections ($appId: Int!){ + modelling_connection (where: { _or: [{app_id: { _eq: $appId }}, {proposed_app_id: { _eq: $appId }}], removed: { _eq: false } } order_by: { is_interface: desc, common_service: desc, name: asc }){ + ...connectionDetails + } +} diff --git a/roles/common/files/fwo-api-calls/modelling/getConnectionsByTicketId.graphql b/roles/common/files/fwo-api-calls/modelling/getConnectionsByTicketId.graphql new file mode 100644 index 0000000000..818bff7d07 --- /dev/null +++ b/roles/common/files/fwo-api-calls/modelling/getConnectionsByTicketId.graphql @@ -0,0 +1,5 @@ +query getConnectionsByTicketId ($ticketId: bigint){ + modelling_connection (where: { ticket_id: { _eq: $ticketId }, removed: { _eq: false } } order_by: { is_interface: desc, common_service: desc, name: asc }){ + ...connectionDetails + } +} diff --git a/roles/common/files/fwo-api-calls/modelling/getConnectionsForNwGroup.graphql b/roles/common/files/fwo-api-calls/modelling/getConnectionsForNwGroup.graphql new file mode 100644 index 0000000000..fa7cf52ef5 --- /dev/null +++ b/roles/common/files/fwo-api-calls/modelling/getConnectionsForNwGroup.graphql @@ -0,0 +1,12 @@ +query getConnectionsForNwGroup ($id: bigint!){ + modelling_nwgroup_connection (where: { nwgroup_id: { _eq: $id } }){ + connection { + ...connectionDetails + owner { + id + name + app_id_external + } + } + } +} diff --git a/roles/common/files/fwo-api-calls/modelling/getConnectionsResolved.graphql b/roles/common/files/fwo-api-calls/modelling/getConnectionsResolved.graphql new file mode 100644 index 0000000000..e42aafece0 --- /dev/null +++ b/roles/common/files/fwo-api-calls/modelling/getConnectionsResolved.graphql @@ -0,0 +1,5 @@ +query getConnectionsResolved ($appId: Int!){ + modelling_connection (where: { _or: [{app_id: { _eq: $appId }}, {proposed_app_id: { _eq: $appId }}], removed: { _eq: false } } order_by: { is_interface: desc, common_service: desc, name: asc }){ + ...connectionResolvedDetails + } +} diff --git a/roles/common/files/fwo-api-calls/modelling/getDeletedConnections.graphql b/roles/common/files/fwo-api-calls/modelling/getDeletedConnections.graphql new file mode 100644 index 0000000000..468e5a95c5 --- /dev/null +++ b/roles/common/files/fwo-api-calls/modelling/getDeletedConnections.graphql @@ -0,0 +1,5 @@ +query getDeletedConnections ($appId: Int!){ + modelling_connection (where: { app_id: { _eq: $appId }, removed: { _eq: true } } order_by: { id: asc }){ + ...connectionDetails + } +} diff --git a/roles/common/files/fwo-api-calls/modelling/getDummyAppRole.graphql b/roles/common/files/fwo-api-calls/modelling/getDummyAppRole.graphql new file mode 100644 index 0000000000..7c8400ca5e --- /dev/null +++ b/roles/common/files/fwo-api-calls/modelling/getDummyAppRole.graphql @@ -0,0 +1,5 @@ +query getDummyAppRole { + modelling_nwgroup (where: { app_id: { _is_null: true }, group_type: { _eq: 20 } }){ + ...appRoleDetails + } +} diff --git a/roles/common/files/fwo-api-calls/modelling/getGlobalServiceGroups.graphql b/roles/common/files/fwo-api-calls/modelling/getGlobalServiceGroups.graphql new file mode 100644 index 0000000000..9e48af6c0b --- /dev/null +++ b/roles/common/files/fwo-api-calls/modelling/getGlobalServiceGroups.graphql @@ -0,0 +1,10 @@ +query getGlobalServiceGroups{ + modelling_service_group (where: { is_global: { _eq: true } } order_by: { name: asc }){ + ...serviceGroupDetails + services: service_service_groups{ + service{ + ...serviceDetails + } + } + } +} diff --git a/roles/common/files/fwo-api-calls/modelling/getGlobalServices.graphql b/roles/common/files/fwo-api-calls/modelling/getGlobalServices.graphql new file mode 100644 index 0000000000..a561415f73 --- /dev/null +++ b/roles/common/files/fwo-api-calls/modelling/getGlobalServices.graphql @@ -0,0 +1,5 @@ +query getGlobalServices{ + modelling_service (where: { is_global: { _eq: true } } order_by: { name: asc }){ + ...serviceDetails + } +} diff --git a/roles/common/files/fwo-api-calls/modelling/getHistory.graphql b/roles/common/files/fwo-api-calls/modelling/getHistory.graphql new file mode 100644 index 0000000000..0701ac1203 --- /dev/null +++ b/roles/common/files/fwo-api-calls/modelling/getHistory.graphql @@ -0,0 +1,20 @@ +query getHistory ( + $limit: Int + $offset: Int +){ + modelling_change_history ( + limit: $limit + offset: $offset + order_by: { change_time: desc } + ){ + id + app_id + change_type + object_type + object_id + change_text + changer + change_time + change_source + } +} diff --git a/roles/common/files/fwo-api-calls/modelling/getHistoryForApp.graphql b/roles/common/files/fwo-api-calls/modelling/getHistoryForApp.graphql new file mode 100644 index 0000000000..50d0c1d42c --- /dev/null +++ b/roles/common/files/fwo-api-calls/modelling/getHistoryForApp.graphql @@ -0,0 +1,13 @@ +query getHistoryForApp ($appId: Int!){ + modelling_change_history (where: {app_id: {_eq: $appId}} order_by: { change_time: desc }){ + id + app_id + change_type + object_type + object_id + change_text + changer + change_time + change_source + } +} diff --git a/roles/common/files/fwo-api-calls/modelling/getInterfaceUsers.graphql b/roles/common/files/fwo-api-calls/modelling/getInterfaceUsers.graphql new file mode 100644 index 0000000000..62add82e77 --- /dev/null +++ b/roles/common/files/fwo-api-calls/modelling/getInterfaceUsers.graphql @@ -0,0 +1,13 @@ +query getInterfaceUsers ($id: Int){ + modelling_connection (where: { used_interface_id: { _eq: $id }, removed: { _eq: false } } ){ + id + conn_prop + name + app_id + owner{ + id + name + app_id_external + } + } +} diff --git a/roles/common/files/fwo-api-calls/modelling/getNewestAppRoles.graphql b/roles/common/files/fwo-api-calls/modelling/getNewestAppRoles.graphql new file mode 100644 index 0000000000..e11806818e --- /dev/null +++ b/roles/common/files/fwo-api-calls/modelling/getNewestAppRoles.graphql @@ -0,0 +1,6 @@ +query getNewestAppRoles ($pattern: String!){ + modelling_nwgroup (where: { id_string: { _ilike: $pattern }, group_type: { _eq: 20 } } order_by: { id: desc }){ + id + id_string + } +} diff --git a/roles/common/files/fwo-api-calls/modelling/getNwGroupObjects.graphql b/roles/common/files/fwo-api-calls/modelling/getNwGroupObjects.graphql new file mode 100644 index 0000000000..451915d7cc --- /dev/null +++ b/roles/common/files/fwo-api-calls/modelling/getNwGroupObjects.graphql @@ -0,0 +1,9 @@ +query getNwGroupObjects ($grpType: Int!){ + modelling_nwgroup (where: { group_type: { _eq: $grpType }, is_deleted: { _eq: false } } order_by: { name: asc }){ + id + name + id_string + app_id + group_type + } +} diff --git a/roles/common/files/fwo-api-calls/modelling/getPermittedOwnersForConnection.graphql b/roles/common/files/fwo-api-calls/modelling/getPermittedOwnersForConnection.graphql new file mode 100644 index 0000000000..ed741a74a5 --- /dev/null +++ b/roles/common/files/fwo-api-calls/modelling/getPermittedOwnersForConnection.graphql @@ -0,0 +1,7 @@ +query getPermittedOwnersForConnection($connectionId: Int!) { + owner(where: { permitted_owners: { connection_id: { _eq: $connectionId } } }) { + id + name + app_id_external + } +} diff --git a/roles/common/files/fwo-api-calls/modelling/getPublishedInterfaces.graphql b/roles/common/files/fwo-api-calls/modelling/getPublishedInterfaces.graphql new file mode 100644 index 0000000000..ce1eb9c5f9 --- /dev/null +++ b/roles/common/files/fwo-api-calls/modelling/getPublishedInterfaces.graphql @@ -0,0 +1,10 @@ +query getPublishedInterfaces{ + modelling_connection (where: { is_interface: { _eq: true }, is_published: { _eq: true }, is_requested: { _eq: false }, removed: { _eq: false }} order_by: { name: asc }){ + ...connectionDetails + owner{ + id + name + app_id_external + } + } +} diff --git a/roles/common/files/fwo-api-calls/modelling/getRequestedInterfaces.graphql b/roles/common/files/fwo-api-calls/modelling/getRequestedInterfaces.graphql new file mode 100644 index 0000000000..afd7dd7cf7 --- /dev/null +++ b/roles/common/files/fwo-api-calls/modelling/getRequestedInterfaces.graphql @@ -0,0 +1,12 @@ +query getRequestedInterfaces($showRemoved: Boolean!){ + modelling_connection ( + where: { + is_interface: { _eq: true }, + is_requested: { _eq: true }, + removed: { _eq: $showRemoved } + }, + order_by: { name: asc } + ){ + ...connectionDetails + } +} diff --git a/roles/common/files/fwo-api-calls/modelling/getSelectedConnections.graphql b/roles/common/files/fwo-api-calls/modelling/getSelectedConnections.graphql new file mode 100644 index 0000000000..8b5e481bfd --- /dev/null +++ b/roles/common/files/fwo-api-calls/modelling/getSelectedConnections.graphql @@ -0,0 +1,7 @@ +query getSelectedConnections ($appId: Int!){ + modelling_selected_connections (where: { app_id: { _eq: $appId } }){ + connection { + ...connectionDetails + } + } +} diff --git a/roles/common/files/fwo-api-calls/modelling/getSelectedNwGroupObjects.graphql b/roles/common/files/fwo-api-calls/modelling/getSelectedNwGroupObjects.graphql new file mode 100644 index 0000000000..d02bc13224 --- /dev/null +++ b/roles/common/files/fwo-api-calls/modelling/getSelectedNwGroupObjects.graphql @@ -0,0 +1,10 @@ +query getSelectedNwGroupObjects ($appId: Int!){ + modelling_selected_objects (where: { app_id: { _eq: $appId } }){ + nwgroup { + id + id_string + name + group_type + } + } +} diff --git a/roles/common/files/fwo-api-calls/modelling/getServiceGroupById.graphql b/roles/common/files/fwo-api-calls/modelling/getServiceGroupById.graphql new file mode 100644 index 0000000000..b8fd8ba87d --- /dev/null +++ b/roles/common/files/fwo-api-calls/modelling/getServiceGroupById.graphql @@ -0,0 +1,10 @@ +query getServiceGroupById ($id: Int!){ + modelling_service_group_by_pk(id: $id){ + ...serviceGroupDetails + services: service_service_groups{ + service{ + ...serviceDetails + } + } + } +} diff --git a/roles/common/files/fwo-api-calls/modelling/getServiceGroupIdsForService.graphql b/roles/common/files/fwo-api-calls/modelling/getServiceGroupIdsForService.graphql new file mode 100644 index 0000000000..b64963863d --- /dev/null +++ b/roles/common/files/fwo-api-calls/modelling/getServiceGroupIdsForService.graphql @@ -0,0 +1,5 @@ +query getServiceGroupIdsForService ($serviceId: Int!){ + modelling_service_service_group (where: { service_id: { _eq: $serviceId } }){ + service_group_id + } +} diff --git a/roles/common/files/fwo-api-calls/modelling/getServiceGroupsForApp.graphql b/roles/common/files/fwo-api-calls/modelling/getServiceGroupsForApp.graphql new file mode 100644 index 0000000000..87663e9acb --- /dev/null +++ b/roles/common/files/fwo-api-calls/modelling/getServiceGroupsForApp.graphql @@ -0,0 +1,10 @@ +query getServiceGroupsForApp ($appId: Int!){ + modelling_service_group (where: { app_id: { _eq: $appId } } order_by: { name: asc }){ + ...serviceGroupDetails + services: service_service_groups{ + service{ + ...serviceDetails + } + } + } +} diff --git a/roles/common/files/fwo-api-calls/modelling/getServicesForApp.graphql b/roles/common/files/fwo-api-calls/modelling/getServicesForApp.graphql new file mode 100644 index 0000000000..bd9c984c02 --- /dev/null +++ b/roles/common/files/fwo-api-calls/modelling/getServicesForApp.graphql @@ -0,0 +1,5 @@ +query getServicesForApp ($appId: Int!){ + modelling_service (where: { app_id: { _eq: $appId } } order_by: { name: asc }){ + ...serviceDetails + } +} diff --git a/roles/common/files/fwo-api-calls/modelling/newAppRole.graphql b/roles/common/files/fwo-api-calls/modelling/newAppRole.graphql new file mode 100644 index 0000000000..eacd1ba911 --- /dev/null +++ b/roles/common/files/fwo-api-calls/modelling/newAppRole.graphql @@ -0,0 +1,20 @@ +mutation newAppRole( + $name: String + $idString: String + $appId: Int + $comment: String + $creator: String + ) { + insert_modelling_nwgroup(objects: { + name: $name + id_string: $idString + app_id: $appId + comment: $comment + creator: $creator + group_type: 20 + }) { + returning { + newIdLong: id + } + } +} diff --git a/roles/common/files/fwo-api-calls/modelling/newAppServer.graphql b/roles/common/files/fwo-api-calls/modelling/newAppServer.graphql new file mode 100644 index 0000000000..62e465c4d6 --- /dev/null +++ b/roles/common/files/fwo-api-calls/modelling/newAppServer.graphql @@ -0,0 +1,24 @@ +mutation newAppServer( + $name: String + $appId: Int + $ip: cidr + $ipEnd: cidr + $importSource: String + $customType: Int + ) { + insert_owner_network(objects: { + name: $name + owner_id: $appId + ip: $ip + ip_end: $ipEnd + import_source: $importSource + is_deleted: false + nw_type: 10 + custom_type: $customType + } + ) { + returning { + newIdLong: id + } + } +} diff --git a/roles/common/files/fwo-api-calls/modelling/newArea.graphql b/roles/common/files/fwo-api-calls/modelling/newArea.graphql new file mode 100644 index 0000000000..b3f8e71943 --- /dev/null +++ b/roles/common/files/fwo-api-calls/modelling/newArea.graphql @@ -0,0 +1,16 @@ +mutation newArea( + $name: String + $idString: String + $creator: String + ) { + insert_modelling_nwgroup(objects: { + name: $name + id_string: $idString + creator: $creator + group_type: 23 + }) { + returning { + newIdLong: id + } + } +} diff --git a/roles/common/files/fwo-api-calls/modelling/newAreaIpData.graphql b/roles/common/files/fwo-api-calls/modelling/newAreaIpData.graphql new file mode 100644 index 0000000000..8790d56edf --- /dev/null +++ b/roles/common/files/fwo-api-calls/modelling/newAreaIpData.graphql @@ -0,0 +1,19 @@ +mutation newAreaIpData( + $name: String + $ip: cidr + $ipEnd: cidr + $importSource: String + ) { + insert_owner_network(objects: { + name: $name + ip: $ip + ip_end: $ipEnd + import_source: $importSource + is_deleted: false + nw_type: 11 + }) { + returning { + newIdLong: id + } + } +} diff --git a/roles/common/files/fwo-api-calls/modelling/newConnection.graphql b/roles/common/files/fwo-api-calls/modelling/newConnection.graphql new file mode 100644 index 0000000000..337eec3251 --- /dev/null +++ b/roles/common/files/fwo-api-calls/modelling/newConnection.graphql @@ -0,0 +1,37 @@ +mutation newConnection( + $name: String + $appId: Int + $proposedAppId: Int + $reason: String + $isInterface: Boolean + $usedInterfaceId: Int + $isRequested: Boolean + $isPublished: Boolean + $ticketId: bigint + $creator: String + $commonSvc: Boolean + $connProp: String + $extraParams: String + $interfacePermission: String + ) { + insert_modelling_connection(objects: { + name: $name + app_id: $appId + proposed_app_id: $proposedAppId + reason: $reason + is_interface: $isInterface + used_interface_id: $usedInterfaceId + is_requested: $isRequested + is_published: $isPublished + ticket_id: $ticketId + creator: $creator + common_service: $commonSvc + conn_prop: $connProp + extra_params: $extraParams + interface_permission: $interfacePermission + }) { + returning { + newId: id + } + } +} diff --git a/roles/common/files/fwo-api-calls/modelling/newService.graphql b/roles/common/files/fwo-api-calls/modelling/newService.graphql new file mode 100644 index 0000000000..db214df193 --- /dev/null +++ b/roles/common/files/fwo-api-calls/modelling/newService.graphql @@ -0,0 +1,21 @@ +mutation newService( + $name: String + $appId: Int + $isGlobal: Boolean + $port: Int + $portEnd: Int + $protoId: Int + ) { + insert_modelling_service(objects: { + name: $name + app_id: $appId + is_global: $isGlobal + port: $port + port_end: $portEnd + proto_id: $protoId + }) { + returning { + newId: id + } + } +} diff --git a/roles/common/files/fwo-api-calls/modelling/newServiceGroup.graphql b/roles/common/files/fwo-api-calls/modelling/newServiceGroup.graphql new file mode 100644 index 0000000000..f2fb1c949c --- /dev/null +++ b/roles/common/files/fwo-api-calls/modelling/newServiceGroup.graphql @@ -0,0 +1,19 @@ +mutation newServiceGroup( + $name: String + $appId: Int + $isGlobal: Boolean + $comment: String + $creator: String + ) { + insert_modelling_service_group(objects: { + name: $name + app_id: $appId + is_global: $isGlobal + comment: $comment + creator: $creator + }) { + returning { + newId: id + } + } +} diff --git a/roles/common/files/fwo-api-calls/modelling/removeAllAppServersFromConnection.graphql b/roles/common/files/fwo-api-calls/modelling/removeAllAppServersFromConnection.graphql new file mode 100644 index 0000000000..91335a9664 --- /dev/null +++ b/roles/common/files/fwo-api-calls/modelling/removeAllAppServersFromConnection.graphql @@ -0,0 +1,7 @@ +mutation removeAllAppServersFromConnection( + $id: Int! + ) { + delete_modelling_nwobject_connection(where: {connection_id: {_eq: $id}}) { + affected_rows + } +} diff --git a/roles/common/files/fwo-api-calls/modelling/removeAllNwGroupsFromConnection.graphql b/roles/common/files/fwo-api-calls/modelling/removeAllNwGroupsFromConnection.graphql new file mode 100644 index 0000000000..dc838d9e9a --- /dev/null +++ b/roles/common/files/fwo-api-calls/modelling/removeAllNwGroupsFromConnection.graphql @@ -0,0 +1,7 @@ +mutation removeAllNwGroupsFromConnection( + $id: Int! + ) { + delete_modelling_nwgroup_connection(where: { connection_id: {_eq: $id}}) { + affected_rows + } +} diff --git a/roles/common/files/fwo-api-calls/modelling/removeAllServiceGroupsFromConnection.graphql b/roles/common/files/fwo-api-calls/modelling/removeAllServiceGroupsFromConnection.graphql new file mode 100644 index 0000000000..bc8343be89 --- /dev/null +++ b/roles/common/files/fwo-api-calls/modelling/removeAllServiceGroupsFromConnection.graphql @@ -0,0 +1,7 @@ +mutation removeAllServiceGroupsFromConnection( + $id: Int! + ) { + delete_modelling_service_group_connection(where: {connection_id: {_eq: $id}}) { + affected_rows + } +} diff --git a/roles/common/files/fwo-api-calls/modelling/removeAllServicesFromConnection.graphql b/roles/common/files/fwo-api-calls/modelling/removeAllServicesFromConnection.graphql new file mode 100644 index 0000000000..48ed22e047 --- /dev/null +++ b/roles/common/files/fwo-api-calls/modelling/removeAllServicesFromConnection.graphql @@ -0,0 +1,7 @@ +mutation removeAllServicesFromConnection( + $id: Int! + ) { + delete_modelling_service_connection(where: {connection_id: {_eq: $id}}) { + affected_rows + } +} diff --git a/roles/common/files/fwo-api-calls/modelling/removeAppServerFromConnection.graphql b/roles/common/files/fwo-api-calls/modelling/removeAppServerFromConnection.graphql new file mode 100644 index 0000000000..8cf0f556ce --- /dev/null +++ b/roles/common/files/fwo-api-calls/modelling/removeAppServerFromConnection.graphql @@ -0,0 +1,9 @@ +mutation removeAppServerFromConnection( + $nwObjectId: bigint! + $connectionId: Int! + $connectionField: Int! + ) { + delete_modelling_nwobject_connection(where: {nwobject_id: {_eq: $nwObjectId}, connection_id: {_eq: $connectionId}, connection_field: {_eq: $connectionField}}) { + affected_rows + } +} diff --git a/roles/common/files/fwo-api-calls/modelling/removeNwGroupFromConnection.graphql b/roles/common/files/fwo-api-calls/modelling/removeNwGroupFromConnection.graphql new file mode 100644 index 0000000000..00478589d1 --- /dev/null +++ b/roles/common/files/fwo-api-calls/modelling/removeNwGroupFromConnection.graphql @@ -0,0 +1,9 @@ +mutation removeNwGroupFromConnection( + $nwGroupId: bigint! + $connectionId: Int! + $connectionField: Int! + ) { + delete_modelling_nwgroup_connection(where: {nwgroup_id: {_eq: $nwGroupId}, connection_id: {_eq: $connectionId}, connection_field: {_eq: $connectionField}}) { + affected_rows + } +} diff --git a/roles/common/files/fwo-api-calls/modelling/removeNwObjectFromNwGroup.graphql b/roles/common/files/fwo-api-calls/modelling/removeNwObjectFromNwGroup.graphql new file mode 100644 index 0000000000..ec7e946c89 --- /dev/null +++ b/roles/common/files/fwo-api-calls/modelling/removeNwObjectFromNwGroup.graphql @@ -0,0 +1,8 @@ +mutation removeNwObjectFromNwGroup( + $nwObjectId: bigint! + $nwGroupId: bigint! + ) { + delete_modelling_nwobject_nwgroup(where: {nwobject_id: {_eq: $nwObjectId}, nwgroup_id: {_eq: $nwGroupId}}) { + affected_rows + } +} diff --git a/roles/common/files/fwo-api-calls/modelling/removeSelectedConnection.graphql b/roles/common/files/fwo-api-calls/modelling/removeSelectedConnection.graphql new file mode 100644 index 0000000000..6538d9cfcc --- /dev/null +++ b/roles/common/files/fwo-api-calls/modelling/removeSelectedConnection.graphql @@ -0,0 +1,7 @@ +mutation removeSelectedConnection( + $connectionId: Int! + ) { + delete_modelling_selected_connections(where: {connection_id: {_eq: $connectionId}}) { + affected_rows + } +} diff --git a/roles/common/files/fwo-api-calls/modelling/removeSelectedConnectionFromApp.graphql b/roles/common/files/fwo-api-calls/modelling/removeSelectedConnectionFromApp.graphql new file mode 100644 index 0000000000..02bcbe6226 --- /dev/null +++ b/roles/common/files/fwo-api-calls/modelling/removeSelectedConnectionFromApp.graphql @@ -0,0 +1,8 @@ +mutation removeSelectedConnectionFromApp( + $appId: Int! + $connectionId: Int! + ) { + delete_modelling_selected_connections(where: {app_id: {_eq: $appId}, connection_id: {_eq: $connectionId}}) { + affected_rows + } +} diff --git a/roles/common/files/fwo-api-calls/modelling/removeSelectedNwGroupObject.graphql b/roles/common/files/fwo-api-calls/modelling/removeSelectedNwGroupObject.graphql new file mode 100644 index 0000000000..f154242939 --- /dev/null +++ b/roles/common/files/fwo-api-calls/modelling/removeSelectedNwGroupObject.graphql @@ -0,0 +1,8 @@ +mutation removeSelectedNwGroupObject( + $appId: Int! + $nwGroupId: bigint! + ) { + delete_modelling_selected_objects(where: {app_id: {_eq: $appId}, nwgroup_id: {_eq: $nwGroupId}}) { + affected_rows + } +} diff --git a/roles/common/files/fwo-api-calls/modelling/removeSelectedNwGroupObjectFromAllApps.graphql b/roles/common/files/fwo-api-calls/modelling/removeSelectedNwGroupObjectFromAllApps.graphql new file mode 100644 index 0000000000..5ff91909af --- /dev/null +++ b/roles/common/files/fwo-api-calls/modelling/removeSelectedNwGroupObjectFromAllApps.graphql @@ -0,0 +1,7 @@ +mutation removeSelectedNwGroupObjectFromAllApps( + $nwGroupId: bigint! + ) { + delete_modelling_selected_objects(where: {nwgroup_id: {_eq: $nwGroupId}}) { + affected_rows + } +} diff --git a/roles/common/files/fwo-api-calls/modelling/removeServiceFromConnection.graphql b/roles/common/files/fwo-api-calls/modelling/removeServiceFromConnection.graphql new file mode 100644 index 0000000000..33b23c0e7e --- /dev/null +++ b/roles/common/files/fwo-api-calls/modelling/removeServiceFromConnection.graphql @@ -0,0 +1,8 @@ +mutation removeServiceFromConnection( + $serviceId: Int! + $connectionId: Int! + ) { + delete_modelling_service_connection(where: {service_id: {_eq: $serviceId}, connection_id: {_eq: $connectionId}}) { + affected_rows + } +} diff --git a/roles/common/files/fwo-api-calls/modelling/removeServiceFromServiceGroup.graphql b/roles/common/files/fwo-api-calls/modelling/removeServiceFromServiceGroup.graphql new file mode 100644 index 0000000000..4f5cfa8158 --- /dev/null +++ b/roles/common/files/fwo-api-calls/modelling/removeServiceFromServiceGroup.graphql @@ -0,0 +1,8 @@ +mutation removeServiceFromServiceGroup( + $serviceId: Int! + $serviceGroupId: Int! + ) { + delete_modelling_service_service_group(where: {service_id: {_eq: $serviceId}, service_group_id: {_eq: $serviceGroupId}}) { + affected_rows + } +} diff --git a/roles/common/files/fwo-api-calls/modelling/removeServiceGroupFromConnection.graphql b/roles/common/files/fwo-api-calls/modelling/removeServiceGroupFromConnection.graphql new file mode 100644 index 0000000000..6ce9f37ae6 --- /dev/null +++ b/roles/common/files/fwo-api-calls/modelling/removeServiceGroupFromConnection.graphql @@ -0,0 +1,8 @@ +mutation removeServiceGroupFromConnection( + $serviceGroupId: Int! + $connectionId: Int! + ) { + delete_modelling_service_group_connection(where: {service_group_id: {_eq: $serviceGroupId}, connection_id: {_eq: $connectionId}}) { + affected_rows + } +} diff --git a/roles/common/files/fwo-api-calls/modelling/replaceUsedInterface.graphql b/roles/common/files/fwo-api-calls/modelling/replaceUsedInterface.graphql new file mode 100644 index 0000000000..5515194627 --- /dev/null +++ b/roles/common/files/fwo-api-calls/modelling/replaceUsedInterface.graphql @@ -0,0 +1,11 @@ +mutation replaceUsedInterface( + $usedInterfaceIdOld: Int! + $usedInterfaceIdNew: Int! + ) { + update_modelling_connection(where: {used_interface_id: {_eq: $usedInterfaceIdOld}} + _set: { + used_interface_id: $usedInterfaceIdNew + }) { + affected_rows + } +} diff --git a/roles/common/files/fwo-api-calls/modelling/setAppServerDeletedState.graphql b/roles/common/files/fwo-api-calls/modelling/setAppServerDeletedState.graphql new file mode 100644 index 0000000000..d04abb789a --- /dev/null +++ b/roles/common/files/fwo-api-calls/modelling/setAppServerDeletedState.graphql @@ -0,0 +1,12 @@ +mutation setAppServerDeletedState( + $id: bigint! + $deleted: Boolean! + ) { + update_owner_network_by_pk( + pk_columns: { id: $id } + _set: { + is_deleted: $deleted + }) { + UpdatedIdLong: id + } +} diff --git a/roles/common/files/fwo-api-calls/modelling/setAppServerName.graphql b/roles/common/files/fwo-api-calls/modelling/setAppServerName.graphql new file mode 100644 index 0000000000..973519b02e --- /dev/null +++ b/roles/common/files/fwo-api-calls/modelling/setAppServerName.graphql @@ -0,0 +1,12 @@ +mutation setAppServerName( + $id: bigint! + $newName: String! + ) { + update_owner_network_by_pk( + pk_columns: { id: $id } + _set: { + name: $newName + }) { + UpdatedIdLong: id + } +} diff --git a/roles/common/files/fwo-api-calls/modelling/setAppServerType.graphql b/roles/common/files/fwo-api-calls/modelling/setAppServerType.graphql new file mode 100644 index 0000000000..dd214958fa --- /dev/null +++ b/roles/common/files/fwo-api-calls/modelling/setAppServerType.graphql @@ -0,0 +1,12 @@ +mutation setAppServerType( + $id: bigint! + $customType: Int + ) { + update_owner_network_by_pk( + pk_columns: { id: $id } + _set: { + custom_type: $customType + }) { + UpdatedIdLong: id + } +} diff --git a/roles/common/files/fwo-api-calls/modelling/setNwGroupDeletedState.graphql b/roles/common/files/fwo-api-calls/modelling/setNwGroupDeletedState.graphql new file mode 100644 index 0000000000..0789239fe5 --- /dev/null +++ b/roles/common/files/fwo-api-calls/modelling/setNwGroupDeletedState.graphql @@ -0,0 +1,12 @@ +mutation setNwGroupDeletedState( + $id: bigint! + $deleted: Boolean! + ) { + update_modelling_nwgroup_by_pk( + pk_columns: { id: $id } + _set: { + is_deleted: $deleted + }) { + UpdatedIdLong: id + } +} diff --git a/roles/common/files/fwo-api-calls/modelling/updateAppRole.graphql b/roles/common/files/fwo-api-calls/modelling/updateAppRole.graphql new file mode 100644 index 0000000000..782e6e7a2e --- /dev/null +++ b/roles/common/files/fwo-api-calls/modelling/updateAppRole.graphql @@ -0,0 +1,18 @@ +mutation updateAppRole( + $id: bigint! + $name: String + $idString: String + $appId: Int + $comment: String + ) { + update_modelling_nwgroup_by_pk( + pk_columns: { id: $id } + _set: { + name: $name + id_string: $idString + app_id: $appId + comment: $comment + }) { + UpdatedIdLong: id + } +} diff --git a/roles/common/files/fwo-api-calls/modelling/updateAppServer.graphql b/roles/common/files/fwo-api-calls/modelling/updateAppServer.graphql new file mode 100644 index 0000000000..cdd5d2a6cf --- /dev/null +++ b/roles/common/files/fwo-api-calls/modelling/updateAppServer.graphql @@ -0,0 +1,23 @@ +mutation updateAppServer( + $id: bigint! + $name: String + $appId: Int + $ip: cidr + $ipEnd: cidr + $importSource: String + $customType: Int + ) { + update_owner_network_by_pk( + pk_columns: { id: $id } + _set: { + name: $name + owner_id: $appId + ip: $ip + ip_end: $ipEnd + import_source: $importSource + is_deleted: false + custom_type: $customType + }) { + updatedIdLong: id + } +} diff --git a/roles/common/files/fwo-api-calls/modelling/updateConnection.graphql b/roles/common/files/fwo-api-calls/modelling/updateConnection.graphql new file mode 100644 index 0000000000..81e34f0c1b --- /dev/null +++ b/roles/common/files/fwo-api-calls/modelling/updateConnection.graphql @@ -0,0 +1,34 @@ +mutation updateConnection( + $id: Int! + $name: String + $appId: Int + $proposedAppId: Int + $reason: String + $isInterface: Boolean + $usedInterfaceId: Int + $isRequested: Boolean + $isPublished: Boolean + $commonSvc: Boolean + $connProp: String + $extraParams: String + $interfacePermission: String + ) { + update_modelling_connection_by_pk( + pk_columns: { id: $id } + _set: { + name: $name + app_id: $appId + proposed_app_id: $proposedAppId + reason: $reason + is_interface: $isInterface + used_interface_id: $usedInterfaceId + is_requested: $isRequested + is_published: $isPublished + common_service: $commonSvc + conn_prop: $connProp + extra_params: $extraParams + interface_permission: $interfacePermission + }) { + updatedId: id + } +} diff --git a/roles/common/files/fwo-api-calls/modelling/updateConnectionDecommission.graphql b/roles/common/files/fwo-api-calls/modelling/updateConnectionDecommission.graphql new file mode 100644 index 0000000000..3c789591ee --- /dev/null +++ b/roles/common/files/fwo-api-calls/modelling/updateConnectionDecommission.graphql @@ -0,0 +1,17 @@ +mutation updateConnectionDecommission( + $id: Int! + $removalDate: timestamp + $connProp: String + $reason: String + ) { + update_modelling_connection_by_pk( + pk_columns: { id: $id } + _set: { + removed: true + removal_date: $removalDate + conn_prop: $connProp + reason: $reason + }) { + updatedId: id + } +} diff --git a/roles/common/files/fwo-api-calls/modelling/updateConnectionFwRequested.graphql b/roles/common/files/fwo-api-calls/modelling/updateConnectionFwRequested.graphql new file mode 100644 index 0000000000..f030886c9a --- /dev/null +++ b/roles/common/files/fwo-api-calls/modelling/updateConnectionFwRequested.graphql @@ -0,0 +1,11 @@ +mutation updateConnectionFwRequested( + $id: Int! + ) { + update_modelling_connection_by_pk( + pk_columns: { id: $id } + _set: { + requested_on_fw: true + }) { + updatedId: id + } +} diff --git a/roles/common/files/fwo-api-calls/modelling/updateConnectionProperties.graphql b/roles/common/files/fwo-api-calls/modelling/updateConnectionProperties.graphql new file mode 100644 index 0000000000..2e6a2b3f47 --- /dev/null +++ b/roles/common/files/fwo-api-calls/modelling/updateConnectionProperties.graphql @@ -0,0 +1,12 @@ +mutation updateConnectionProperties( + $id: Int! + $connProp: String + ) { + update_modelling_connection_by_pk( + pk_columns: { id: $id } + _set: { + conn_prop: $connProp + }) { + updatedId: id + } +} diff --git a/roles/common/files/fwo-api-calls/modelling/updateConnectionPublish.graphql b/roles/common/files/fwo-api-calls/modelling/updateConnectionPublish.graphql new file mode 100644 index 0000000000..eb74ce0b90 --- /dev/null +++ b/roles/common/files/fwo-api-calls/modelling/updateConnectionPublish.graphql @@ -0,0 +1,18 @@ +mutation updateConnectionPublish( + $id: Int! + $isPublished: Boolean + $isRequested: Boolean + $appId: Int + $proposedAppId: Int + ) { + update_modelling_connection_by_pk( + pk_columns: { id: $id } + _set: { + is_requested: $isRequested + is_published: $isPublished + app_id: $appId + proposed_app_id: $proposedAppId + }) { + updatedId: id + } +} diff --git a/roles/common/files/fwo-api-calls/modelling/updateConnectionRemove.graphql b/roles/common/files/fwo-api-calls/modelling/updateConnectionRemove.graphql new file mode 100644 index 0000000000..21e6536717 --- /dev/null +++ b/roles/common/files/fwo-api-calls/modelling/updateConnectionRemove.graphql @@ -0,0 +1,13 @@ +mutation updateConnectionRemove( + $id: Int! + $removalDate: timestamp + ) { + update_modelling_connection_by_pk( + pk_columns: { id: $id } + _set: { + removed: true + removal_date: $removalDate + }) { + updatedId: id + } +} diff --git a/roles/common/files/fwo-api-calls/modelling/updateNwObjectInConnection.graphql b/roles/common/files/fwo-api-calls/modelling/updateNwObjectInConnection.graphql new file mode 100644 index 0000000000..212c27f6a7 --- /dev/null +++ b/roles/common/files/fwo-api-calls/modelling/updateNwObjectInConnection.graphql @@ -0,0 +1,5 @@ +mutation updateNwObjectInConnection($oldObjectId: bigint!, $newObjectId: bigint!) { + update_modelling_nwobject_connection(where: {nwobject_id: {_eq: $oldObjectId}}, _set: {nwobject_id: $newObjectId}) { + affected_rows + } +} diff --git a/roles/common/files/fwo-api-calls/modelling/updateNwObjectInNwGroup.graphql b/roles/common/files/fwo-api-calls/modelling/updateNwObjectInNwGroup.graphql new file mode 100644 index 0000000000..bb5238caba --- /dev/null +++ b/roles/common/files/fwo-api-calls/modelling/updateNwObjectInNwGroup.graphql @@ -0,0 +1,5 @@ +mutation updateNwObjectInNwGroup($oldObjectId: bigint!, $newObjectId: bigint!) { + update_modelling_nwobject_nwgroup(where: {nwobject_id: {_eq: $oldObjectId}}, _set: {nwobject_id: $newObjectId}) { + affected_rows + } +} diff --git a/roles/common/files/fwo-api-calls/modelling/updateProposedConnectionOwner.graphql b/roles/common/files/fwo-api-calls/modelling/updateProposedConnectionOwner.graphql new file mode 100644 index 0000000000..985e2cc4be --- /dev/null +++ b/roles/common/files/fwo-api-calls/modelling/updateProposedConnectionOwner.graphql @@ -0,0 +1,12 @@ +mutation updateProposedConnectionOwner( + $id: Int! + $propAppId: Int + ) { + update_modelling_connection_by_pk( + pk_columns: { id: $id } + _set: { + proposed_app_id: $propAppId + }) { + updatedId: id + } +} diff --git a/roles/common/files/fwo-api-calls/modelling/updateService.graphql b/roles/common/files/fwo-api-calls/modelling/updateService.graphql new file mode 100644 index 0000000000..2a6cadaa13 --- /dev/null +++ b/roles/common/files/fwo-api-calls/modelling/updateService.graphql @@ -0,0 +1,18 @@ +mutation updateService( + $id: Int! + $name: String + $port: Int + $portEnd: Int + $protoId: Int + ) { + update_modelling_service_by_pk( + pk_columns: { id: $id } + _set: { + name: $name + port: $port + port_end: $portEnd + proto_id: $protoId + }) { + updatedId: id + } +} diff --git a/roles/common/files/fwo-api-calls/modelling/updateServiceGroup.graphql b/roles/common/files/fwo-api-calls/modelling/updateServiceGroup.graphql new file mode 100644 index 0000000000..56d944c5d5 --- /dev/null +++ b/roles/common/files/fwo-api-calls/modelling/updateServiceGroup.graphql @@ -0,0 +1,14 @@ +mutation updateServiceGroup( + $id: Int! + $name: String + $comment: String + ) { + update_modelling_service_group_by_pk( + pk_columns: { id: $id } + _set: { + name: $name + comment: $comment + }) { + updatedId: id + } +} diff --git a/roles/common/files/fwo-api-calls/modelling/upsertAppServer.graphql b/roles/common/files/fwo-api-calls/modelling/upsertAppServer.graphql new file mode 100644 index 0000000000..22d4e15208 --- /dev/null +++ b/roles/common/files/fwo-api-calls/modelling/upsertAppServer.graphql @@ -0,0 +1,38 @@ +mutation upsertAppServer( + $name: String + $appId: Int + $ip: cidr + $ipEnd: cidr + $importSource: String + $customType: Int + ) { + insert_owner_network(objects: { + name: $name + owner_id: $appId + ip: $ip + ip_end: $ipEnd + import_source: $importSource + is_deleted: false + nw_type: 10 + custom_type: $customType + } + on_conflict: { + constraint: owner_network_ip_unique + update_columns: + [ + name + owner_id + ip + ip_end + import_source + is_deleted + nw_type + custom_type + ] + } + ) { + returning { + newIdLong: id + } + } +} diff --git a/roles/lib/files/FWO.Api.Client/APIcalls/monitor/acknowledgeAlert.graphql b/roles/common/files/fwo-api-calls/monitor/acknowledgeAlert.graphql similarity index 88% rename from roles/lib/files/FWO.Api.Client/APIcalls/monitor/acknowledgeAlert.graphql rename to roles/common/files/fwo-api-calls/monitor/acknowledgeAlert.graphql index 762241eb26..cc0eadb272 100644 --- a/roles/lib/files/FWO.Api.Client/APIcalls/monitor/acknowledgeAlert.graphql +++ b/roles/common/files/fwo-api-calls/monitor/acknowledgeAlert.graphql @@ -10,6 +10,6 @@ mutation acknowledgeAlert( ack_timestamp: $ackTime } ) { - UpdatedId: alert_id + updatedIdLong: alert_id } } diff --git a/roles/common/files/fwo-api-calls/monitor/acknowledgeAllOpenAlerts.graphql b/roles/common/files/fwo-api-calls/monitor/acknowledgeAllOpenAlerts.graphql new file mode 100644 index 0000000000..43d9444b8e --- /dev/null +++ b/roles/common/files/fwo-api-calls/monitor/acknowledgeAllOpenAlerts.graphql @@ -0,0 +1,14 @@ +mutation acknowledgeAllOpenAlerts( + $ackUser: Int! + $ackTime: timestamp! +) { + update_alert( + where: { ack_by: {_is_null: true} } + _set: { + ack_by: $ackUser + ack_timestamp: $ackTime + } + ) { + affected_rows + } +} diff --git a/roles/lib/files/FWO.Api.Client/APIcalls/monitor/addAlert.graphql b/roles/common/files/fwo-api-calls/monitor/addAlert.graphql similarity index 94% rename from roles/lib/files/FWO.Api.Client/APIcalls/monitor/addAlert.graphql rename to roles/common/files/fwo-api-calls/monitor/addAlert.graphql index b3cb95faac..988aaeb478 100644 --- a/roles/lib/files/FWO.Api.Client/APIcalls/monitor/addAlert.graphql +++ b/roles/common/files/fwo-api-calls/monitor/addAlert.graphql @@ -23,7 +23,7 @@ mutation addAlert( } ) { returning { - newId: alert_id + newIdLong: alert_id } } } diff --git a/roles/lib/files/FWO.Api.Client/APIcalls/monitor/addAutodiscoveryLogEntry.graphql b/roles/common/files/fwo-api-calls/monitor/addAutodiscoveryLogEntry.graphql similarity index 86% rename from roles/lib/files/FWO.Api.Client/APIcalls/monitor/addAutodiscoveryLogEntry.graphql rename to roles/common/files/fwo-api-calls/monitor/addAutodiscoveryLogEntry.graphql index 16ba524fd1..6d5349f0c0 100644 --- a/roles/lib/files/FWO.Api.Client/APIcalls/monitor/addAutodiscoveryLogEntry.graphql +++ b/roles/common/files/fwo-api-calls/monitor/addAutodiscoveryLogEntry.graphql @@ -1,4 +1,4 @@ -mutation addAutodiscoveryLog( +mutation addAutodiscoveryLogEntry( $discoverUser: Int! $severity: Int! $suspectedCause: String @@ -18,7 +18,7 @@ mutation addAutodiscoveryLog( } ) { returning { - newId: data_issue_id + newIdLong: data_issue_id } } } diff --git a/roles/common/files/fwo-api-calls/monitor/addDataImportLogEntry.graphql b/roles/common/files/fwo-api-calls/monitor/addDataImportLogEntry.graphql new file mode 100644 index 0000000000..4bd76d4cfc --- /dev/null +++ b/roles/common/files/fwo-api-calls/monitor/addDataImportLogEntry.graphql @@ -0,0 +1,21 @@ +mutation addDataImportLogEntry( + $user: Int! + $source: String! + $severity: Int! + $suspectedCause: String + $description: String +) { + insert_log_data_issue( + objects: { + source: $source + user_id: $user + severity: $severity + suspected_cause: $suspectedCause + description: $description + } + ) { + returning { + newIdLong: data_issue_id + } + } +} diff --git a/roles/lib/files/FWO.Api.Client/APIcalls/monitor/addLogEntry.graphql b/roles/common/files/fwo-api-calls/monitor/addLogEntry.graphql similarity index 93% rename from roles/lib/files/FWO.Api.Client/APIcalls/monitor/addLogEntry.graphql rename to roles/common/files/fwo-api-calls/monitor/addLogEntry.graphql index 6ea0cb4bb2..b9156ab197 100644 --- a/roles/lib/files/FWO.Api.Client/APIcalls/monitor/addLogEntry.graphql +++ b/roles/common/files/fwo-api-calls/monitor/addLogEntry.graphql @@ -1,6 +1,6 @@ mutation addLogEntry( $source: String! - $discoverUser: Int! + $discoverUser: Int $severity: Int! $suspectedCause: String $description: String @@ -31,7 +31,7 @@ mutation addLogEntry( } ) { returning { - newId: data_issue_id + newIdLong: data_issue_id } } } diff --git a/roles/lib/files/FWO.Api.Client/APIcalls/monitor/addUiLogEntry.graphql b/roles/common/files/fwo-api-calls/monitor/addUiLogEntry.graphql similarity index 84% rename from roles/lib/files/FWO.Api.Client/APIcalls/monitor/addUiLogEntry.graphql rename to roles/common/files/fwo-api-calls/monitor/addUiLogEntry.graphql index 81fbd5c2f0..5fbd3885ce 100644 --- a/roles/lib/files/FWO.Api.Client/APIcalls/monitor/addUiLogEntry.graphql +++ b/roles/common/files/fwo-api-calls/monitor/addUiLogEntry.graphql @@ -1,4 +1,4 @@ -mutation addUiLog( +mutation addUiLogEntry( $user: Int! $severity: Int! $suspectedCause: String @@ -14,7 +14,7 @@ mutation addUiLog( } ) { returning { - newId: data_issue_id + newIdLong: data_issue_id } } } diff --git a/roles/lib/files/FWO.Api.Client/APIcalls/monitor/getAlertById.graphql b/roles/common/files/fwo-api-calls/monitor/getAlertById.graphql similarity index 100% rename from roles/lib/files/FWO.Api.Client/APIcalls/monitor/getAlertById.graphql rename to roles/common/files/fwo-api-calls/monitor/getAlertById.graphql diff --git a/roles/common/files/fwo-api-calls/monitor/getAlertByManagement.graphql b/roles/common/files/fwo-api-calls/monitor/getAlertByManagement.graphql new file mode 100644 index 0000000000..8ba50982f1 --- /dev/null +++ b/roles/common/files/fwo-api-calls/monitor/getAlertByManagement.graphql @@ -0,0 +1,9 @@ +query getAlertByManagement($mgmId: Int!, $alertCode: Int!, $currentAlertId: bigint!) { + alert(where: { + alert_mgm_id: {_eq: $mgmId}, alert_code: {_eq: $alertCode} + ack_timestamp: {_is_null: true} + alert_id: {_neq: $currentAlertId}}) + { + alert_id + } +} diff --git a/roles/lib/files/FWO.Api.Client/APIcalls/monitor/getAlerts.graphql b/roles/common/files/fwo-api-calls/monitor/getAlerts.graphql similarity index 100% rename from roles/lib/files/FWO.Api.Client/APIcalls/monitor/getAlerts.graphql rename to roles/common/files/fwo-api-calls/monitor/getAlerts.graphql diff --git a/roles/lib/files/FWO.Api.Client/APIcalls/monitor/getAllUiLogEntrys.graphql b/roles/common/files/fwo-api-calls/monitor/getAllUiLogEntrys.graphql similarity index 100% rename from roles/lib/files/FWO.Api.Client/APIcalls/monitor/getAllUiLogEntrys.graphql rename to roles/common/files/fwo-api-calls/monitor/getAllUiLogEntrys.graphql diff --git a/roles/lib/files/FWO.Api.Client/APIcalls/monitor/getAutodiscoveryLogEntrys.graphql b/roles/common/files/fwo-api-calls/monitor/getAutodiscoveryLogEntrys.graphql similarity index 100% rename from roles/lib/files/FWO.Api.Client/APIcalls/monitor/getAutodiscoveryLogEntrys.graphql rename to roles/common/files/fwo-api-calls/monitor/getAutodiscoveryLogEntrys.graphql diff --git a/roles/lib/files/FWO.Api.Client/APIcalls/monitor/getDailyCheckLogEntrys.graphql b/roles/common/files/fwo-api-calls/monitor/getDailyCheckLogEntrys.graphql similarity index 100% rename from roles/lib/files/FWO.Api.Client/APIcalls/monitor/getDailyCheckLogEntrys.graphql rename to roles/common/files/fwo-api-calls/monitor/getDailyCheckLogEntrys.graphql diff --git a/roles/common/files/fwo-api-calls/monitor/getDataImportLogEntrys.graphql b/roles/common/files/fwo-api-calls/monitor/getDataImportLogEntrys.graphql new file mode 100644 index 0000000000..85ddaea1ed --- /dev/null +++ b/roles/common/files/fwo-api-calls/monitor/getDataImportLogEntrys.graphql @@ -0,0 +1,9 @@ +query getDataImportLogEntrys ($source: String!){ + log_data_issue (where: {source: {_eq: $source}} order_by: { data_issue_id: desc }){ + data_issue_id + severity + issue_timestamp + suspected_cause + description + } +} diff --git a/roles/lib/files/FWO.Api.Client/APIcalls/monitor/getImportLogEntrys.graphql b/roles/common/files/fwo-api-calls/monitor/getImportLogEntrys.graphql similarity index 100% rename from roles/lib/files/FWO.Api.Client/APIcalls/monitor/getImportLogEntrys.graphql rename to roles/common/files/fwo-api-calls/monitor/getImportLogEntrys.graphql diff --git a/roles/common/files/fwo-api-calls/monitor/getImportStatus.graphql b/roles/common/files/fwo-api-calls/monitor/getImportStatus.graphql new file mode 100644 index 0000000000..1494097018 --- /dev/null +++ b/roles/common/files/fwo-api-calls/monitor/getImportStatus.graphql @@ -0,0 +1,48 @@ +query getImportStatus { + management(where: {_or: [{multi_device_manager_id: {_is_null: true}}, {is_super_manager: {_eq: true}}]}, order_by: {mgm_name: asc}) { + mgm_id + mgm_name + importDisabled: do_not_import + last_import_attempt + last_import_attempt_successful + deviceType: stm_dev_typ { + id: dev_typ_id + name: dev_typ_name + version: dev_typ_version + manufacturer: dev_typ_manufacturer + isPureRoutingDevice: is_pure_routing_device + } + last_import: import_controls(order_by: {control_id: desc}, limit: 1) { + control_id + start_time + stop_time + successful_import + import_errors + } + last_successful_import: import_controls(where: {successful_import: {_eq: true}}, order_by: {control_id: desc}, limit: 1) { + control_id + start_time + stop_time + successful_import + import_errors + } + last_incomplete_import: import_controls(where: {successful_import: {_eq: false}, stop_time: {_is_null: true}}, order_by: {control_id: desc}, limit: 1) { + control_id + start_time + stop_time + successful_import + import_errors + } + first_import: import_controls(order_by: {control_id: asc}, limit: 1) { + control_id + start_time + stop_time + successful_import + import_errors + } + erroneous_imports: import_controls(where: {successful_import: {_eq: false}}, order_by: {control_id: desc}) { + control_id + import_errors + } + } +} diff --git a/roles/lib/files/FWO.Api.Client/APIcalls/monitor/getLogEntrys.graphql b/roles/common/files/fwo-api-calls/monitor/getLogEntrys.graphql similarity index 100% rename from roles/lib/files/FWO.Api.Client/APIcalls/monitor/getLogEntrys.graphql rename to roles/common/files/fwo-api-calls/monitor/getLogEntrys.graphql diff --git a/roles/lib/files/FWO.Api.Client/APIcalls/monitor/getOpenAlerts.graphql b/roles/common/files/fwo-api-calls/monitor/getOpenAlerts.graphql similarity index 100% rename from roles/lib/files/FWO.Api.Client/APIcalls/monitor/getOpenAlerts.graphql rename to roles/common/files/fwo-api-calls/monitor/getOpenAlerts.graphql diff --git a/roles/common/files/fwo-api-calls/monitor/getOwnerTicketIds.graphql b/roles/common/files/fwo-api-calls/monitor/getOwnerTicketIds.graphql new file mode 100644 index 0000000000..cdc8823866 --- /dev/null +++ b/roles/common/files/fwo-api-calls/monitor/getOwnerTicketIds.graphql @@ -0,0 +1,6 @@ + +query getOwnerTicketIds ($ownerIds: [Int!]) { + owner_ticket (where: {owner_id: {_in: $ownerIds}} order_by: { ticket_id: desc }){ + ticket_id + } +} diff --git a/roles/common/files/fwo-api-calls/monitor/getOwnerTickets.graphql b/roles/common/files/fwo-api-calls/monitor/getOwnerTickets.graphql new file mode 100644 index 0000000000..be7e37f5e1 --- /dev/null +++ b/roles/common/files/fwo-api-calls/monitor/getOwnerTickets.graphql @@ -0,0 +1,14 @@ + +query getOwnerTickets ($ownerId: Int!) { + owner_ticket (where: {owner_id: {_eq: $ownerId}} order_by: { ticket_id: desc }){ + owner: owner { + id + name + app_id_external + common_service_possible + } + ticket: ticket { + ...ticketOverview + } + } +} diff --git a/roles/lib/files/FWO.Api.Client/APIcalls/monitor/getUiLogEntrys.graphql b/roles/common/files/fwo-api-calls/monitor/getUiLogEntrys.graphql similarity index 100% rename from roles/lib/files/FWO.Api.Client/APIcalls/monitor/getUiLogEntrys.graphql rename to roles/common/files/fwo-api-calls/monitor/getUiLogEntrys.graphql diff --git a/roles/lib/files/FWO.Api.Client/APIcalls/monitor/subscribeAlertChanges.graphql b/roles/common/files/fwo-api-calls/monitor/subscribeAlertChanges.graphql similarity index 100% rename from roles/lib/files/FWO.Api.Client/APIcalls/monitor/subscribeAlertChanges.graphql rename to roles/common/files/fwo-api-calls/monitor/subscribeAlertChanges.graphql diff --git a/roles/common/files/fwo-api-calls/monitor/updateAlert.graphql b/roles/common/files/fwo-api-calls/monitor/updateAlert.graphql new file mode 100644 index 0000000000..b107bd4d1c --- /dev/null +++ b/roles/common/files/fwo-api-calls/monitor/updateAlert.graphql @@ -0,0 +1,5 @@ +mutation updateAlert($userId: Int, $alertId: bigint, $ackTimeStamp: timestamp) { + update_alert(where: {alert_id: {_eq: $alertId}}, _set: {ack_by: $userId, ack_timestamp: $ackTimeStamp}) { + affected_rows + } +} diff --git a/roles/common/files/fwo-api-calls/networkObject/fragments/networkObjectDetails.graphql b/roles/common/files/fwo-api-calls/networkObject/fragments/networkObjectDetails.graphql new file mode 100644 index 0000000000..d59ef7bb29 --- /dev/null +++ b/roles/common/files/fwo-api-calls/networkObject/fragments/networkObjectDetails.graphql @@ -0,0 +1,67 @@ +fragment networkObjectDetails on object { + obj_id + obj_name + obj_ip + obj_ip_end + obj_uid + zone { + zone_id + zone_name + } + active + obj_create + obj_create_time: import_control { + time: start_time + } + obj_last_seen + type: stm_obj_typ { + name: obj_typ_name + } + obj_comment + obj_member_names + obj_member_refs + objgrps( + where: { + active: { _eq: $active } + import_created: { _lte: $import_id_end } + _or: [ + { removed: { _is_null: true } } + { removed: { _gt: $import_id_start } } + ] + } + order_by: { objgrp_member_id: asc } + ) { + id: objgrp_member_id + byId: objectByObjgrpMemberId { + obj_id + obj_name + type: stm_obj_typ { + id: obj_typ_id + name: obj_typ_name + } + } + } + objgrp_flats( + where: { + active: { _eq: $active } + import_created: { _lte: $import_id_end } + _or: [ + { removed: { _is_null: true } } + { removed: { _gt: $import_id_start } } + ] + } + order_by: { objgrp_flat_member_id: asc } + ) { + id_flat: objgrp_flat_id + byFlatId: objectByObjgrpFlatMemberId { + obj_id + obj_name + obj_ip + obj_ip_end + obj_member_refs + type: stm_obj_typ { + name: obj_typ_name + } + } + } +} diff --git a/roles/common/files/fwo-api-calls/networkObject/fragments/networkObjectDetailsChangesNew.graphql b/roles/common/files/fwo-api-calls/networkObject/fragments/networkObjectDetailsChangesNew.graphql new file mode 100644 index 0000000000..9c14d3bb9b --- /dev/null +++ b/roles/common/files/fwo-api-calls/networkObject/fragments/networkObjectDetailsChangesNew.graphql @@ -0,0 +1,67 @@ +fragment networkObjectDetailsChangesNew on object { + obj_id + obj_name + obj_ip + obj_ip_end + obj_uid + zone { + zone_id + zone_name + } + active + obj_create + obj_create_time: import_control { + time: start_time + } + obj_last_seen + type: stm_obj_typ { + name: obj_typ_name + } + obj_comment + obj_member_names + obj_member_refs + objgrps( + where: { + active: { _eq: $active } + import_created: { _lte: $import_id_new } + _or: [ + {removed: {_is_null: true}} + {removed: {_gt: $import_id_new}} + ] + } + order_by: {objgrp_member_id: asc}) + { + id: objgrp_member_id + byId: objectByObjgrpMemberId { + obj_id + obj_name + type: stm_obj_typ { + id: obj_typ_id + name: obj_typ_name + } + } + } + objgrp_flats( + where: { + active: { _eq: $active } + import_created: { _lte: $import_id_new } + _or: [ + {removed: {_is_null: true}} + {removed: {_gt: $import_id_new}} + ] + } + order_by: {objgrp_flat_member_id: asc}) + { + id_flat: objgrp_flat_id + byFlatId: objectByObjgrpFlatMemberId { + obj_id + obj_name + obj_ip + obj_ip_end + type: stm_obj_typ { + id: obj_typ_id + name: obj_typ_name + } + } + } +} diff --git a/roles/common/files/fwo-api-calls/networkObject/fragments/networkObjectDetailsChangesOld.graphql b/roles/common/files/fwo-api-calls/networkObject/fragments/networkObjectDetailsChangesOld.graphql new file mode 100644 index 0000000000..e168bc0e14 --- /dev/null +++ b/roles/common/files/fwo-api-calls/networkObject/fragments/networkObjectDetailsChangesOld.graphql @@ -0,0 +1,67 @@ +fragment networkObjectDetailsChangesOld on object { + obj_id + obj_name + obj_ip + obj_ip_end + obj_uid + zone { + zone_id + zone_name + } + active + obj_create + obj_create_time: import_control { + time: start_time + } + obj_last_seen + type: stm_obj_typ { + name: obj_typ_name + } + obj_comment + obj_member_names + obj_member_refs + objgrps( + where: { + active: { _eq: $active } + import_created: { _lte: $import_id_old } + _or: [ + {removed: {_is_null: true}} + {removed: {_gt: $import_id_old}} + ] + } + order_by: {objgrp_member_id: asc}) + { + id: objgrp_member_id + byId: objectByObjgrpMemberId { + obj_id + obj_name + type: stm_obj_typ { + id: obj_typ_id + name: obj_typ_name + } + } + } + objgrp_flats( + where: { + active: { _eq: $active } + import_created: { _lte: $import_id_old } + _or: [ + {removed: {_is_null: true}} + {removed: {_gt: $import_id_old}} + ] + } + order_by: {objgrp_flat_member_id: asc}) + { + id_flat: objgrp_flat_id + byFlatId: objectByObjgrpFlatMemberId { + obj_id + obj_name + obj_ip + obj_ip_end + type: stm_obj_typ { + id: obj_typ_id + name: obj_typ_name + } + } + } +} diff --git a/roles/common/files/fwo-api-calls/networkObject/fragments/networkObjectDetailsForAppRules.graphql b/roles/common/files/fwo-api-calls/networkObject/fragments/networkObjectDetailsForAppRules.graphql new file mode 100644 index 0000000000..0c9a378f01 --- /dev/null +++ b/roles/common/files/fwo-api-calls/networkObject/fragments/networkObjectDetailsForAppRules.graphql @@ -0,0 +1,35 @@ +fragment networkObjectDetailsForAppRules on object { + obj_id + obj_name + obj_ip + obj_ip_end + obj_uid + zone { + zone_id + zone_name + } + active + type: stm_obj_typ { + name: obj_typ_name + } + objgrp_flats( + where: { + active: { _eq: $active } + import_created: { _lte: $import_id_end } + _or: [ + { removed: { _is_null: true } } + { removed: { _gt: $import_id_start } } + ] + } + order_by: { objgrp_flat_member_id: asc } + ) { + id_flat: objgrp_flat_id + byFlatId: objectByObjgrpFlatMemberId { + obj_id + obj_name + obj_ip + obj_ip_end + obj_member_refs + } + } +} diff --git a/roles/common/files/fwo-api-calls/networkObject/fragments/networkObjectDetailsForVariance.graphql b/roles/common/files/fwo-api-calls/networkObject/fragments/networkObjectDetailsForVariance.graphql new file mode 100644 index 0000000000..e5c0511bef --- /dev/null +++ b/roles/common/files/fwo-api-calls/networkObject/fragments/networkObjectDetailsForVariance.graphql @@ -0,0 +1,22 @@ +fragment networkObjectDetailsForVariance on object { + obj_id + obj_name + obj_ip + obj_ip_end + objgrp_flats(where: { + active: { _eq: $active } + _or: [ + {removed: {_is_null: true}} + {removed: {_gt: $import_id_start}} + ] + import_created: { _lte: $import_id_end } + } order_by: {objgrp_flat_member_id: asc}) { + id_flat: objgrp_flat_id + byFlatId: objectByObjgrpFlatMemberId { + obj_id + obj_name + obj_ip + obj_ip_end + } + } +} diff --git a/roles/lib/files/FWO.Api.Client/APIcalls/networkObject/fragments/networkObjectOverview.graphql b/roles/common/files/fwo-api-calls/networkObject/fragments/networkObjectOverview.graphql similarity index 94% rename from roles/lib/files/FWO.Api.Client/APIcalls/networkObject/fragments/networkObjectOverview.graphql rename to roles/common/files/fwo-api-calls/networkObject/fragments/networkObjectOverview.graphql index 35ce2218dd..508cb89c2f 100644 --- a/roles/lib/files/FWO.Api.Client/APIcalls/networkObject/fragments/networkObjectOverview.graphql +++ b/roles/common/files/fwo-api-calls/networkObject/fragments/networkObjectOverview.graphql @@ -3,6 +3,7 @@ fragment networkObjectOverview on object { obj_ip_end obj_name obj_id + obj_uid type: stm_obj_typ { id: obj_typ_id name: obj_typ_name diff --git a/roles/common/files/fwo-api-calls/networkObject/getMapOfUid2Id.graphql b/roles/common/files/fwo-api-calls/networkObject/getMapOfUid2Id.graphql new file mode 100644 index 0000000000..e5568dd1fc --- /dev/null +++ b/roles/common/files/fwo-api-calls/networkObject/getMapOfUid2Id.graphql @@ -0,0 +1,13 @@ +query getMapOfUid2Id($uids: [String!], $mgmId: Int!) { + object(where: { + obj_uid: {_in: $uids}, + _or: [ + {mgm_id: {_eq: $mgmId}}, + {management: {multi_device_manager_id: {_eq: $mgmId}}} + ], + removed: {_is_null: true} + }) { + obj_id + obj_uid + } +} diff --git a/roles/common/files/fwo-api-calls/networkObject/getNetworkObjectDetails.graphql b/roles/common/files/fwo-api-calls/networkObject/getNetworkObjectDetails.graphql new file mode 100644 index 0000000000..8767e1249b --- /dev/null +++ b/roles/common/files/fwo-api-calls/networkObject/getNetworkObjectDetails.graphql @@ -0,0 +1,36 @@ +query getNetworkObjectDetails( + $management_id: [Int!] + $nwObjTyp: [String!] + $nwObjUid: [String!] + $active: Boolean + $import_id_start: bigint + $import_id_end: bigint + $obj_name: [String!] + $obj_ip: [cidr!] + $limit: Int + $offset: Int +) { + management(where: { mgm_id: { _in: $management_id }, stm_dev_typ:{dev_typ_is_multi_mgmt:{_eq:false}} }) { + id: mgm_id + name: mgm_name + networkObjects: objects( + limit: $limit + offset: $offset + where: { + stm_obj_typ: { obj_typ_name: { _in: $nwObjTyp } } + active: { _eq: $active } + _or: [ + { removed: { _is_null: true } } + { removed: { _gte: $import_id_start } } + ] + obj_create: { _lte: $import_id_end } + obj_name: { _in: $obj_name } + obj_ip: { _in: $obj_ip } + obj_uid: { _in: $nwObjUid } + } + order_by: [{ obj_name: asc }, { obj_id: asc }] + ) { + ...networkObjectDetails + } + } +} diff --git a/roles/common/files/fwo-api-calls/networkObject/getNetworkObjectsForManagement.graphql b/roles/common/files/fwo-api-calls/networkObject/getNetworkObjectsForManagement.graphql new file mode 100644 index 0000000000..515a9d166a --- /dev/null +++ b/roles/common/files/fwo-api-calls/networkObject/getNetworkObjectsForManagement.graphql @@ -0,0 +1,20 @@ +query getNetworkObjectsForManagement ( + $mgmId: Int + $objTypeIds: [Int!] + $active: Boolean + $import_id_start: bigint + $import_id_end: bigint +){ + object(where: { + mgm_id: { _eq: $mgmId } + active: {_eq: true} + obj_typ_id: {_in: $objTypeIds} + obj_create: {_lte: $import_id_end} + _or: [ + {removed: {_is_null: true}} + {removed: {_gt: $import_id_start}} + ] + }) { + ...networkObjectDetailsForVariance + } +} diff --git a/roles/common/files/fwo-api-calls/networkService/fragments/networkServiceDetails.graphql b/roles/common/files/fwo-api-calls/networkService/fragments/networkServiceDetails.graphql new file mode 100644 index 0000000000..8443db31c1 --- /dev/null +++ b/roles/common/files/fwo-api-calls/networkService/fragments/networkServiceDetails.graphql @@ -0,0 +1,71 @@ +fragment networkServiceDetails on service { + svc_id + svc_name + svc_uid + svc_port + svc_port_end + svc_source_port + svc_source_port_end + svc_code + svc_timeout + svc_typ_id + active + svc_create + svc_create_time: import_control { + time: start_time + } + svc_last_seen + service_type: stm_svc_typ { + name: svc_typ_name + } + svc_comment + svc_color_id + ip_proto_id + protocol_name: stm_ip_proto { + id: ip_proto_id + name: ip_proto_name + } + svc_member_names + svc_member_refs + svcgrps(where: { + active: { _eq: $active } + import_created: { _lte: $import_id_end } + _or: [ + {removed: {_is_null: true}} + {removed: {_gt: $import_id_start}} + ] + } order_by: { svcgrp_member_id: asc }) { + id: svcgrp_member_id + byId: serviceBySvcgrpMemberId { + svc_id + svc_name + service_type: stm_svc_typ { + name: svc_typ_name + } + } + } + svcgrp_flats(where: { + active: { _eq: $active } + import_created: { _lte: $import_id_end } + _or: [ + {removed: {_is_null: true}} + {removed: {_gt: $import_id_start}} + ] + } order_by: { svcgrp_flat_member_id: asc }) { + flat_id: svcgrp_flat_id + byFlatId: serviceBySvcgrpFlatMemberId { + svc_id + svc_name + svc_port + svc_port_end + ip_proto_id + protocol_name: stm_ip_proto { + id: ip_proto_id + name: ip_proto_name + } + service_type: stm_svc_typ { + name: svc_typ_name + } + } + } +} diff --git a/roles/common/files/fwo-api-calls/networkService/fragments/networkServiceDetailsChangesNew.graphql b/roles/common/files/fwo-api-calls/networkService/fragments/networkServiceDetailsChangesNew.graphql new file mode 100644 index 0000000000..f07c1815af --- /dev/null +++ b/roles/common/files/fwo-api-calls/networkService/fragments/networkServiceDetailsChangesNew.graphql @@ -0,0 +1,71 @@ +fragment networkServiceDetailsChangesNew on service { + svc_id + svc_name + svc_uid + svc_port + svc_port_end + svc_source_port + svc_source_port_end + svc_code + svc_timeout + svc_typ_id + active + svc_create + svc_create_time: import_control { + time: start_time + } + svc_last_seen + service_type: stm_svc_typ { + name: svc_typ_name + } + svc_comment + svc_color_id + ip_proto_id + protocol_name: stm_ip_proto { + id: ip_proto_id + name: ip_proto_name + } + svc_member_names + svc_member_refs + svcgrps(where: { + active: { _eq: $active } + import_created: { _lte: $import_id_new } + _or: [ + {removed: {_is_null: true}} + {removed: {_gt: $import_id_new}} + ] + } order_by: { svcgrp_member_id: asc }) { + id: svcgrp_member_id + byId: serviceBySvcgrpMemberId { + svc_id + svc_name + service_type: stm_svc_typ { + name: svc_typ_name + } + } + } + svcgrp_flats(where: { + active: { _eq: $active } + import_created: { _lte: $import_id_new } + _or: [ + {removed: {_is_null: true}} + {removed: {_gt: $import_id_new}} + ] + } order_by: { svcgrp_flat_member_id: asc }) { + flat_id: svcgrp_flat_id + byFlatId: serviceBySvcgrpFlatMemberId { + svc_id + svc_name + svc_port + svc_port_end + ip_proto_id + protocol_name: stm_ip_proto { + id: ip_proto_id + name: ip_proto_name + } + service_type: stm_svc_typ { + name: svc_typ_name + } + } + } +} diff --git a/roles/common/files/fwo-api-calls/networkService/fragments/networkServiceDetailsChangesOld.graphql b/roles/common/files/fwo-api-calls/networkService/fragments/networkServiceDetailsChangesOld.graphql new file mode 100644 index 0000000000..267fb14897 --- /dev/null +++ b/roles/common/files/fwo-api-calls/networkService/fragments/networkServiceDetailsChangesOld.graphql @@ -0,0 +1,71 @@ +fragment networkServiceDetailsChangesOld on service { + svc_id + svc_name + svc_uid + svc_port + svc_port_end + svc_source_port + svc_source_port_end + svc_code + svc_timeout + svc_typ_id + active + svc_create + svc_create_time: import_control { + time: start_time + } + svc_last_seen + service_type: stm_svc_typ { + name: svc_typ_name + } + svc_comment + svc_color_id + ip_proto_id + protocol_name: stm_ip_proto { + id: ip_proto_id + name: ip_proto_name + } + svc_member_names + svc_member_refs + svcgrps(where: { + active: { _eq: $active } + import_created: { _lte: $import_id_old } + _or: [ + {removed: {_is_null: true}} + {removed: {_gt: $import_id_old}} + ] + } order_by: { svcgrp_member_id: asc }) { + id: svcgrp_member_id + byId: serviceBySvcgrpMemberId { + svc_id + svc_name + service_type: stm_svc_typ { + name: svc_typ_name + } + } + } + svcgrp_flats(where: { + active: { _eq: $active } + import_created: { _lte: $import_id_old } + _or: [ + {removed: {_is_null: true}} + {removed: {_gt: $import_id_old}} + ] + } order_by: { svcgrp_flat_member_id: asc }) { + flat_id: svcgrp_flat_id + byFlatId: serviceBySvcgrpFlatMemberId { + svc_id + svc_name + svc_port + svc_port_end + ip_proto_id + protocol_name: stm_ip_proto { + id: ip_proto_id + name: ip_proto_name + } + service_type: stm_svc_typ { + name: svc_typ_name + } + } + } +} diff --git a/roles/lib/files/FWO.Api.Client/APIcalls/networkService/fragments/networkServiceOverview.graphql b/roles/common/files/fwo-api-calls/networkService/fragments/networkServiceOverview.graphql similarity index 95% rename from roles/lib/files/FWO.Api.Client/APIcalls/networkService/fragments/networkServiceOverview.graphql rename to roles/common/files/fwo-api-calls/networkService/fragments/networkServiceOverview.graphql index 0ff9de9071..f84462c91f 100644 --- a/roles/lib/files/FWO.Api.Client/APIcalls/networkService/fragments/networkServiceOverview.graphql +++ b/roles/common/files/fwo-api-calls/networkService/fragments/networkServiceOverview.graphql @@ -9,6 +9,7 @@ fragment networkServiceOverview on service { name: svc_typ_name } svc_color_id + ip_proto_id protocol_name: stm_ip_proto { id: ip_proto_id name: ip_proto_name diff --git a/roles/common/files/fwo-api-calls/networkService/getMapOfUid2Id.graphql b/roles/common/files/fwo-api-calls/networkService/getMapOfUid2Id.graphql new file mode 100644 index 0000000000..48a62fadba --- /dev/null +++ b/roles/common/files/fwo-api-calls/networkService/getMapOfUid2Id.graphql @@ -0,0 +1,13 @@ +query getMapOfUid2Id($uids: [String!], $mgmId: Int!) { + service(where: { + svc_uid: {_in: $uids}, + _or: [ + {mgm_id: {_eq: $mgmId}}, + {management: {multi_device_manager_id: {_eq: $mgmId}}} + ], + removed: {_is_null: true} + }) { + svc_id + svc_uid + } +} diff --git a/roles/common/files/fwo-api-calls/networkService/getNetworkServiceDetails.graphql b/roles/common/files/fwo-api-calls/networkService/getNetworkServiceDetails.graphql new file mode 100644 index 0000000000..36d7b23c9e --- /dev/null +++ b/roles/common/files/fwo-api-calls/networkService/getNetworkServiceDetails.graphql @@ -0,0 +1,32 @@ +query getNetworkServiceDetails( + $management_id: [Int!] + $active: Boolean + $import_id_start: bigint + $import_id_end: bigint + $svc_name: [String!] + $svc_port: [Int!] + $limit: Int + $offset: Int +) { + management(where: { mgm_id: { _in: $management_id }, stm_dev_typ:{dev_typ_is_multi_mgmt:{_eq:false}} }) { + id: mgm_id + name: mgm_name + serviceObjects : services( + limit: $limit + offset: $offset + where: { + _or: [ + { removed: { _is_null: true } }, + { removed: { _gte: $import_id_start } } + ] + active: { _eq: $active } + svc_create: { _lte: $import_id_end } + svc_name: { _in: $svc_name } + svc_port: { _in: $svc_port } + } + order_by: [{ svc_name: asc }, { svc_id: asc }] + ) { + ...networkServiceDetails + } + } +} diff --git a/roles/lib/files/FWO.Api.Client/APIcalls/networking/analyzePath.graphql b/roles/common/files/fwo-api-calls/networking/analyzePath.graphql similarity index 100% rename from roles/lib/files/FWO.Api.Client/APIcalls/networking/analyzePath.graphql rename to roles/common/files/fwo-api-calls/networking/analyzePath.graphql diff --git a/roles/lib/files/FWO.Api.Client/APIcalls/networking/getAllNetworkInfosPerDevice.graphql b/roles/common/files/fwo-api-calls/networking/getAllNetworkInfosPerDevice.graphql similarity index 100% rename from roles/lib/files/FWO.Api.Client/APIcalls/networking/getAllNetworkInfosPerDevice.graphql rename to roles/common/files/fwo-api-calls/networking/getAllNetworkInfosPerDevice.graphql diff --git a/roles/lib/files/FWO.Api.Client/APIcalls/networking/getAllNetworkInfosTable.graphql b/roles/common/files/fwo-api-calls/networking/getAllNetworkInfosTable.graphql similarity index 100% rename from roles/lib/files/FWO.Api.Client/APIcalls/networking/getAllNetworkInfosTable.graphql rename to roles/common/files/fwo-api-calls/networking/getAllNetworkInfosTable.graphql diff --git a/roles/common/files/fwo-api-calls/notification/addNotification.graphql b/roles/common/files/fwo-api-calls/notification/addNotification.graphql new file mode 100644 index 0000000000..895540f386 --- /dev/null +++ b/roles/common/files/fwo-api-calls/notification/addNotification.graphql @@ -0,0 +1,51 @@ +mutation addNotification( + $client: String! + $userId: Int + $channel: String! + $name: String + $recipientTo: String + $emailAddressTo: String + $recipientCc: String + $emailAddressCc: String + $subject: String + $emailBody: String + $scheduleId: Int + $bundleType: String + $bundleId: String + $layout: String! + $deadline: String + $intervalBeforeDeadline: Int + $offsetBeforeDeadline: Int + $intervalAfterDeadline: Int + $initialOffsetAfterDeadline: Int + $offsetAfterDeadline: Int + $repetitionsAfterDeadline: Int + ) { + insert_notification(objects: { + notification_client: $client + user_id: $userId + channel: $channel + name: $name + recipient_to: $recipientTo + email_address_to: $emailAddressTo + recipient_cc: $recipientCc + email_address_cc: $emailAddressCc + email_subject: $subject + email_body: $emailBody + schedule_id: $scheduleId + bundle_type: $bundleType + bundle_id: $bundleId + layout: $layout + deadline: $deadline + interval_before_deadline: $intervalBeforeDeadline + offset_before_deadline: $offsetBeforeDeadline + repeat_interval_after_deadline: $intervalAfterDeadline + initial_offset_after_deadline: $initialOffsetAfterDeadline + repeat_offset_after_deadline: $offsetAfterDeadline + repetitions_after_deadline: $repetitionsAfterDeadline + }) { + returning { + newId: id + } + } +} diff --git a/roles/common/files/fwo-api-calls/notification/deleteNotification.graphql b/roles/common/files/fwo-api-calls/notification/deleteNotification.graphql new file mode 100644 index 0000000000..b8379c134d --- /dev/null +++ b/roles/common/files/fwo-api-calls/notification/deleteNotification.graphql @@ -0,0 +1,5 @@ +mutation deleteNotification($id: Int!) { + delete_notification(where: {id: {_eq: $id}}) { + affected_rows + } +} diff --git a/roles/common/files/fwo-api-calls/notification/getNotifications.graphql b/roles/common/files/fwo-api-calls/notification/getNotifications.graphql new file mode 100644 index 0000000000..b7f1c919ac --- /dev/null +++ b/roles/common/files/fwo-api-calls/notification/getNotifications.graphql @@ -0,0 +1,29 @@ + +query getNotifications ($client: String! ){ + notification (where: { notification_client: {_eq: $client} } order_by: { id: asc }){ + id + notification_client + user_id + name + owner_id + channel + recipient_to + email_address_to + recipient_cc + email_address_cc + email_subject + email_body + schedule_id + bundle_type + bundle_id + layout + deadline + interval_before_deadline + offset_before_deadline + repeat_interval_after_deadline + initial_offset_after_deadline + repeat_offset_after_deadline + repetitions_after_deadline + last_sent + } +} diff --git a/roles/common/files/fwo-api-calls/notification/updateNotification.graphql b/roles/common/files/fwo-api-calls/notification/updateNotification.graphql new file mode 100644 index 0000000000..f5641ccfe4 --- /dev/null +++ b/roles/common/files/fwo-api-calls/notification/updateNotification.graphql @@ -0,0 +1,50 @@ +mutation updateNotification( + $id: Int! + $userId: Int + $channel: String! + $name: String + $recipientTo: String + $emailAddressTo: String + $recipientCc: String + $emailAddressCc: String + $subject: String + $emailBody: String + $scheduleId: Int + $bundleType: String + $bundleId: String + $layout: String! + $deadline: String + $intervalBeforeDeadline: Int + $offsetBeforeDeadline: Int + $intervalAfterDeadline: Int + $initialOffsetAfterDeadline: Int + $offsetAfterDeadline: Int + $repetitionsAfterDeadline: Int + ) { + update_notification_by_pk( + pk_columns: { id: $id } + _set: { + user_id: $userId + channel: $channel + name: $name + recipient_to: $recipientTo + email_address_to: $emailAddressTo + recipient_cc: $recipientCc + email_address_cc: $emailAddressCc + email_subject: $subject + email_body: $emailBody + schedule_id: $scheduleId + bundle_type: $bundleType + bundle_id: $bundleId + layout: $layout + deadline: $deadline + interval_before_deadline: $intervalBeforeDeadline + offset_before_deadline: $offsetBeforeDeadline + repeat_interval_after_deadline: $intervalAfterDeadline + initial_offset_after_deadline: $initialOffsetAfterDeadline + repeat_offset_after_deadline: $offsetAfterDeadline + repetitions_after_deadline: $repetitionsAfterDeadline + }) { + updatedId: id + } +} diff --git a/roles/common/files/fwo-api-calls/notification/updateNotificationsLastSent.graphql b/roles/common/files/fwo-api-calls/notification/updateNotificationsLastSent.graphql new file mode 100644 index 0000000000..be974cd571 --- /dev/null +++ b/roles/common/files/fwo-api-calls/notification/updateNotificationsLastSent.graphql @@ -0,0 +1,12 @@ +mutation updateNotificationsLastSent( + $ids: [Int!] + $lastSent: timestamp + ) { + update_notification( + where: { id: {_in: $ids} } + _set: { + last_sent: $lastSent + }) { + affected_rows + } +} diff --git a/roles/common/files/fwo-api-calls/owner/deactivateOwner.graphql b/roles/common/files/fwo-api-calls/owner/deactivateOwner.graphql new file mode 100644 index 0000000000..d952a96ec9 --- /dev/null +++ b/roles/common/files/fwo-api-calls/owner/deactivateOwner.graphql @@ -0,0 +1,11 @@ +mutation deactivateOwner( + $id: Int! + ) { + update_owner_by_pk( + pk_columns: { id: $id } + _set: { + active: false + }) { + updatedId: id + } +} diff --git a/roles/common/files/fwo-api-calls/owner/deleteAreaIpData.graphql b/roles/common/files/fwo-api-calls/owner/deleteAreaIpData.graphql new file mode 100644 index 0000000000..0db1b11475 --- /dev/null +++ b/roles/common/files/fwo-api-calls/owner/deleteAreaIpData.graphql @@ -0,0 +1,7 @@ +mutation deleteAreaIpData( + $id: bigint! + ) { + delete_owner_network(where: {owner_id: {_is_null: true}, id: {_eq: $id}}) { + affected_rows + } +} diff --git a/roles/common/files/fwo-api-calls/owner/deleteNetworkOwnership.graphql b/roles/common/files/fwo-api-calls/owner/deleteNetworkOwnership.graphql new file mode 100644 index 0000000000..785be7863b --- /dev/null +++ b/roles/common/files/fwo-api-calls/owner/deleteNetworkOwnership.graphql @@ -0,0 +1,8 @@ +mutation deleteNetworkOwnership( + $ownerId: Int! + $id: bigint! + ) { + delete_owner_network(where: {owner_id: {_eq: $ownerId}, id: {_eq: $id}}) { + affected_rows + } +} diff --git a/roles/lib/files/FWO.Api.Client/APIcalls/owner/deleteOwner.graphql b/roles/common/files/fwo-api-calls/owner/deleteOwner.graphql similarity index 100% rename from roles/lib/files/FWO.Api.Client/APIcalls/owner/deleteOwner.graphql rename to roles/common/files/fwo-api-calls/owner/deleteOwner.graphql diff --git a/roles/common/files/fwo-api-calls/owner/deleteOwnerLifeCycle.graphql b/roles/common/files/fwo-api-calls/owner/deleteOwnerLifeCycle.graphql new file mode 100644 index 0000000000..bf43de262d --- /dev/null +++ b/roles/common/files/fwo-api-calls/owner/deleteOwnerLifeCycle.graphql @@ -0,0 +1,5 @@ +mutation deleteOwnerLifeCycle($id: Int!) { + delete_owner_lifecycle_state(where: {id: {_eq: $id}}) { + affected_rows + } +} diff --git a/roles/common/files/fwo-api-calls/owner/deleteOwnerResponsibleType.graphql b/roles/common/files/fwo-api-calls/owner/deleteOwnerResponsibleType.graphql new file mode 100644 index 0000000000..02f0f8f304 --- /dev/null +++ b/roles/common/files/fwo-api-calls/owner/deleteOwnerResponsibleType.graphql @@ -0,0 +1,7 @@ +mutation deleteOwnerResponsibleType($id: Int!) { + delete_owner_responsible_type(where: {id: {_eq: $id}}) { + returning { + deletedId: id + } + } +} diff --git a/roles/common/files/fwo-api-calls/owner/deleteOwnerResponsibles.graphql b/roles/common/files/fwo-api-calls/owner/deleteOwnerResponsibles.graphql new file mode 100644 index 0000000000..42f70d7f2a --- /dev/null +++ b/roles/common/files/fwo-api-calls/owner/deleteOwnerResponsibles.graphql @@ -0,0 +1,5 @@ +mutation deleteOwnerResponsibles($ownerId: Int!) { + delete_owner_responsible(where: {owner_id: {_eq: $ownerId}}) { + affected_rows + } +} diff --git a/roles/common/files/fwo-api-calls/owner/deleteRuleOwnership.graphql b/roles/common/files/fwo-api-calls/owner/deleteRuleOwnership.graphql new file mode 100644 index 0000000000..89c4fd2a55 --- /dev/null +++ b/roles/common/files/fwo-api-calls/owner/deleteRuleOwnership.graphql @@ -0,0 +1,8 @@ +mutation deleteRuleOwnership( + $ownerId: Int! + $ruleMetadataId: bigint! + ) { + delete_rule_owner(where: {owner_id: {_eq: $ownerId}, rule_metadata_id: {_eq: $ruleMetadataId}}) { + affected_rows + } +} diff --git a/roles/common/files/fwo-api-calls/owner/deleteSpecificOwnerResponsibles.graphql b/roles/common/files/fwo-api-calls/owner/deleteSpecificOwnerResponsibles.graphql new file mode 100644 index 0000000000..53cd03a4ff --- /dev/null +++ b/roles/common/files/fwo-api-calls/owner/deleteSpecificOwnerResponsibles.graphql @@ -0,0 +1,13 @@ +mutation deleteSpecificOwnerResponsibles( + $ownerId: Int!, + $objects: [owner_responsible_bool_exp!]! +) { + delete_owner_responsible( + where: { + owner_id: { _eq: $ownerId }, + _or: $objects + } + ) { + affected_rows + } +} diff --git a/roles/common/files/fwo-api-calls/owner/fragments/ownerDetails.graphql b/roles/common/files/fwo-api-calls/owner/fragments/ownerDetails.graphql new file mode 100644 index 0000000000..f17218b695 --- /dev/null +++ b/roles/common/files/fwo-api-calls/owner/fragments/ownerDetails.graphql @@ -0,0 +1,26 @@ +fragment ownerDetails on owner { + id + name + owner_responsibles { + dn + responsible_type + } + is_default + tenant_id + recert_interval + app_id_external + recert_check_params + last_recert_check + additional_info + criticality + owner_lifecycle_state_id + active + import_source + common_service_possible + last_recertified + last_recertifier + last_recertifier_dn + next_recert_date + decomm_date + recert_active +} diff --git a/roles/common/files/fwo-api-calls/owner/getChangedOwnersForRuleOwnerMappingCustomField.graphql b/roles/common/files/fwo-api-calls/owner/getChangedOwnersForRuleOwnerMappingCustomField.graphql new file mode 100644 index 0000000000..6749370847 --- /dev/null +++ b/roles/common/files/fwo-api-calls/owner/getChangedOwnersForRuleOwnerMappingCustomField.graphql @@ -0,0 +1,23 @@ + +query getChangedOwnersForRuleOwnerMappingCustomField($controlId: bigint!) { + changelog_owner(where: { control_id: { _eq: $controlId } }) { + import: import_control { + control_id + } + change_action + old: ownerByOldOwnerId { + id + name + app_id_external + active + import_source + } + new: owner { + id + name + app_id_external + active + import_source + } + } +} diff --git a/roles/common/files/fwo-api-calls/owner/getChangedOwnersForRuleOwnerMappingIpBased.graphql b/roles/common/files/fwo-api-calls/owner/getChangedOwnersForRuleOwnerMappingIpBased.graphql new file mode 100644 index 0000000000..d2cd8c83bd --- /dev/null +++ b/roles/common/files/fwo-api-calls/owner/getChangedOwnersForRuleOwnerMappingIpBased.graphql @@ -0,0 +1,34 @@ +query getChangedOwnersForRuleOwnerMappingIpBased($controlId: bigint!) { + changelog_owner(where: { control_id: { _eq: $controlId } }) { + import: import_control { + control_id + } + change_action + old: ownerByOldOwnerId { + id + name + app_id_external + active + import_source + owner_networks(where: { is_deleted: { _eq: false } }) { + id + ip + ip_end + name + } + } + new: owner { + id + name + app_id_external + active + import_source + owner_networks(where: { is_deleted: { _eq: false } }) { + id + ip + ip_end + name + } + } + } +} diff --git a/roles/common/files/fwo-api-calls/owner/getEditableOwners.graphql b/roles/common/files/fwo-api-calls/owner/getEditableOwners.graphql new file mode 100644 index 0000000000..99124d554e --- /dev/null +++ b/roles/common/files/fwo-api-calls/owner/getEditableOwners.graphql @@ -0,0 +1,6 @@ + +query getEditableOwners ($appIds: [Int!]){ + owner_list: owner (where: {id: {_in: $appIds}} order_by: { name: asc }){ + ...ownerDetails + } +} diff --git a/roles/common/files/fwo-api-calls/owner/getEditableOwnersWithConn.graphql b/roles/common/files/fwo-api-calls/owner/getEditableOwnersWithConn.graphql new file mode 100644 index 0000000000..a64bc12672 --- /dev/null +++ b/roles/common/files/fwo-api-calls/owner/getEditableOwnersWithConn.graphql @@ -0,0 +1,9 @@ + +query getEditableOwnersWithConn ($appIds: [Int!]){ + owner_list: owner (where: {id: {_in: $appIds}} order_by: { name: asc }){ + ...ownerDetails + connections_aggregate { + aggregate { count } + } + } +} diff --git a/roles/lib/files/FWO.Api.Client/APIcalls/owner/getNetworkOwnerships.graphql b/roles/common/files/fwo-api-calls/owner/getNetworkOwnerships.graphql similarity index 92% rename from roles/lib/files/FWO.Api.Client/APIcalls/owner/getNetworkOwnerships.graphql rename to roles/common/files/fwo-api-calls/owner/getNetworkOwnerships.graphql index ca6680ed7e..06c74f24a9 100644 --- a/roles/lib/files/FWO.Api.Client/APIcalls/owner/getNetworkOwnerships.graphql +++ b/roles/common/files/fwo-api-calls/owner/getNetworkOwnerships.graphql @@ -3,5 +3,6 @@ query getNetworkOwnerships ($ownerId: Int!) { owner_network (where: {owner_id: {_eq: $ownerId}} order_by: { id: asc }){ id ip + ip_end } } diff --git a/roles/common/files/fwo-api-calls/owner/getOwnerById.graphql b/roles/common/files/fwo-api-calls/owner/getOwnerById.graphql new file mode 100644 index 0000000000..d64c57f7c6 --- /dev/null +++ b/roles/common/files/fwo-api-calls/owner/getOwnerById.graphql @@ -0,0 +1,8 @@ +query getOwnerById ($id: Int!){ + owner_by_pk (id: $id){ + id + name + app_id_external + additional_info + } +} diff --git a/roles/common/files/fwo-api-calls/owner/getOwnerId.graphql b/roles/common/files/fwo-api-calls/owner/getOwnerId.graphql new file mode 100644 index 0000000000..2341e0faf9 --- /dev/null +++ b/roles/common/files/fwo-api-calls/owner/getOwnerId.graphql @@ -0,0 +1,5 @@ +query getOwnerId($externalAppId: String) { + owner_list: owner (where: {app_id_external:{_eq: $externalAppId}}){ + id + } +} diff --git a/roles/common/files/fwo-api-calls/owner/getOwnerLifeCycleStates.graphql b/roles/common/files/fwo-api-calls/owner/getOwnerLifeCycleStates.graphql new file mode 100644 index 0000000000..c463cfb352 --- /dev/null +++ b/roles/common/files/fwo-api-calls/owner/getOwnerLifeCycleStates.graphql @@ -0,0 +1,7 @@ +query getOwnerLifeCycleStates { + owner_lifecycle_state (order_by: { name: asc }){ + id + name + active_state + } +} diff --git a/roles/common/files/fwo-api-calls/owner/getOwnerResponsibleTypes.graphql b/roles/common/files/fwo-api-calls/owner/getOwnerResponsibleTypes.graphql new file mode 100644 index 0000000000..cac0c862c3 --- /dev/null +++ b/roles/common/files/fwo-api-calls/owner/getOwnerResponsibleTypes.graphql @@ -0,0 +1,10 @@ +query getOwnerResponsibleTypes { + owner_responsible_type(order_by: { sort_order: asc, name: asc }) { + id + name + active + allow_modelling + allow_recertification + sort_order + } +} diff --git a/roles/lib/files/FWO.Api.Client/APIcalls/owner/getOwners.graphql b/roles/common/files/fwo-api-calls/owner/getOwners.graphql similarity index 100% rename from roles/lib/files/FWO.Api.Client/APIcalls/owner/getOwners.graphql rename to roles/common/files/fwo-api-calls/owner/getOwners.graphql diff --git a/roles/common/files/fwo-api-calls/owner/getOwnersForDns.graphql b/roles/common/files/fwo-api-calls/owner/getOwnersForDns.graphql new file mode 100644 index 0000000000..0a81108329 --- /dev/null +++ b/roles/common/files/fwo-api-calls/owner/getOwnersForDns.graphql @@ -0,0 +1,15 @@ +query getOwnersForDns ($dns: [String!]!) { + owner_list: owner ( + where: { + owner_responsibles: { + dn: {_in: $dns}, + owner_responsible_type: { + active: {_eq: true} + } + } + }, + order_by: { name: asc } + ) { + ...ownerDetails + } +} diff --git a/roles/common/files/fwo-api-calls/owner/getOwnersForDnsWithConn.graphql b/roles/common/files/fwo-api-calls/owner/getOwnersForDnsWithConn.graphql new file mode 100644 index 0000000000..b9834ac131 --- /dev/null +++ b/roles/common/files/fwo-api-calls/owner/getOwnersForDnsWithConn.graphql @@ -0,0 +1,18 @@ +query getOwnersForDnsWithConn ($dns: [String!]!) { + owner_list: owner ( + where: { + owner_responsibles: { + dn: {_in: $dns}, + owner_responsible_type: { + active: {_eq: true} + } + } + }, + order_by: { name: asc } + ) { + ...ownerDetails + connections_aggregate { + aggregate { count } + } + } +} diff --git a/roles/common/files/fwo-api-calls/owner/getOwnersForDnsWithModellingWithConn.graphql b/roles/common/files/fwo-api-calls/owner/getOwnersForDnsWithModellingWithConn.graphql new file mode 100644 index 0000000000..46ea98abd2 --- /dev/null +++ b/roles/common/files/fwo-api-calls/owner/getOwnersForDnsWithModellingWithConn.graphql @@ -0,0 +1,19 @@ +query getOwnersForDnsWithModellingWithConn ($dns: [String!]!) { + owner_list: owner ( + where: { + owner_responsibles: { + dn: {_in: $dns}, + owner_responsible_type: { + active: {_eq: true}, + allow_modelling: {_eq: true} + } + } + }, + order_by: { name: asc } + ) { + ...ownerDetails + connections_aggregate { + aggregate { count } + } + } +} diff --git a/roles/common/files/fwo-api-calls/owner/getOwnersForDnsWithRecertification.graphql b/roles/common/files/fwo-api-calls/owner/getOwnersForDnsWithRecertification.graphql new file mode 100644 index 0000000000..6b7b49958b --- /dev/null +++ b/roles/common/files/fwo-api-calls/owner/getOwnersForDnsWithRecertification.graphql @@ -0,0 +1,16 @@ +query getOwnersForDnsWithRecertification ($dns: [String!]!) { + owner ( + where: { + owner_responsibles: { + dn: {_in: $dns}, + owner_responsible_type: { + active: {_eq: true}, + allow_recertification: {_eq: true} + } + } + }, + order_by: { id: asc } + ) { + ...ownerDetails + } +} diff --git a/roles/common/files/fwo-api-calls/owner/getOwnersForResponsibleType.graphql b/roles/common/files/fwo-api-calls/owner/getOwnersForResponsibleType.graphql new file mode 100644 index 0000000000..7746c17bc6 --- /dev/null +++ b/roles/common/files/fwo-api-calls/owner/getOwnersForResponsibleType.graphql @@ -0,0 +1,5 @@ +query getOwnersForResponsibleType($responsibleTypeId: Int!) { + owner(where: {owner_responsibles: {responsible_type: {_eq: $responsibleTypeId}}}, limit: 1) { + id + } +} diff --git a/roles/common/files/fwo-api-calls/owner/getOwnersForRuleOwnerCustomField.graphql b/roles/common/files/fwo-api-calls/owner/getOwnersForRuleOwnerCustomField.graphql new file mode 100644 index 0000000000..25a1c31d54 --- /dev/null +++ b/roles/common/files/fwo-api-calls/owner/getOwnersForRuleOwnerCustomField.graphql @@ -0,0 +1,9 @@ + +query getOwnersForRuleOwnerCustomField { + owner (where: { active: { _eq: true } }) + { + id + name + app_id_external + } +} diff --git a/roles/common/files/fwo-api-calls/owner/getOwnersForRuleOwnerIpBased.graphql b/roles/common/files/fwo-api-calls/owner/getOwnersForRuleOwnerIpBased.graphql new file mode 100644 index 0000000000..d4316d7f24 --- /dev/null +++ b/roles/common/files/fwo-api-calls/owner/getOwnersForRuleOwnerIpBased.graphql @@ -0,0 +1,13 @@ +query getOwnersForRuleOwnerIpBased { + owner(where: { active: { _eq: true } }) { + id + name + app_id_external + owner_networks(where: { is_deleted: { _eq: false } }) { + id + ip + ip_end + name + } + } +} diff --git a/roles/common/files/fwo-api-calls/owner/getOwnersForUser.graphql b/roles/common/files/fwo-api-calls/owner/getOwnersForUser.graphql new file mode 100644 index 0000000000..12feee378e --- /dev/null +++ b/roles/common/files/fwo-api-calls/owner/getOwnersForUser.graphql @@ -0,0 +1,8 @@ + +query getOwnersForUser ($userDns: [String!]!) { + owner (where: {owner_responsibles: {dn: {_in: $userDns}, owner_responsible_type: {active: {_eq: true}}}} order_by: { id: asc }){ + id + recert_interval + name + } +} diff --git a/roles/common/files/fwo-api-calls/owner/getOwnersFromGroups.graphql b/roles/common/files/fwo-api-calls/owner/getOwnersFromGroups.graphql new file mode 100644 index 0000000000..0a094dc684 --- /dev/null +++ b/roles/common/files/fwo-api-calls/owner/getOwnersFromGroups.graphql @@ -0,0 +1,8 @@ + +query getOwnersFromGroups ($groupDns: [String!]!) { + owner (where: {owner_responsibles: {dn: {_in: $groupDns}, owner_responsible_type: {active: {_eq: true}}}} order_by: { id: asc }){ + id + recert_interval + name + } +} diff --git a/roles/common/files/fwo-api-calls/owner/getOwnersWithConn.graphql b/roles/common/files/fwo-api-calls/owner/getOwnersWithConn.graphql new file mode 100644 index 0000000000..b75792541f --- /dev/null +++ b/roles/common/files/fwo-api-calls/owner/getOwnersWithConn.graphql @@ -0,0 +1,9 @@ + +query getOwnersWithConn { + owner_list: owner (where: {id: { _gt: 0 }} order_by: { name: asc }){ + ...ownerDetails + connections_aggregate { + aggregate { count } + } + } +} diff --git a/roles/common/files/fwo-api-calls/owner/getOwnersWithNetworks.graphql b/roles/common/files/fwo-api-calls/owner/getOwnersWithNetworks.graphql new file mode 100644 index 0000000000..685e98806a --- /dev/null +++ b/roles/common/files/fwo-api-calls/owner/getOwnersWithNetworks.graphql @@ -0,0 +1,11 @@ +query getOwnersWithNetworks { + owner_list: owner(order_by: { name: asc }) { + ...ownerDetails + owner_networks(where: { is_deleted: { _eq: false } }) { + id + ip + ip_end + name + } + } +} \ No newline at end of file diff --git a/roles/common/files/fwo-api-calls/owner/getRuleOwnerToRemoveByOwner.graphql b/roles/common/files/fwo-api-calls/owner/getRuleOwnerToRemoveByOwner.graphql new file mode 100644 index 0000000000..c3f194e5a0 --- /dev/null +++ b/roles/common/files/fwo-api-calls/owner/getRuleOwnerToRemoveByOwner.graphql @@ -0,0 +1,12 @@ +query getRuleOwnerToRemoveByOwner($ownerIds: [Int!]!) { + rule_owner( + where: { + owner_id: { _in: $ownerIds }, + removed: { _is_null: true } + } + ) { + rule_id + owner_id + created + } +} diff --git a/roles/common/files/fwo-api-calls/owner/getRuleOwnerToRemoveByRule.graphql b/roles/common/files/fwo-api-calls/owner/getRuleOwnerToRemoveByRule.graphql new file mode 100644 index 0000000000..34d67c370a --- /dev/null +++ b/roles/common/files/fwo-api-calls/owner/getRuleOwnerToRemoveByRule.graphql @@ -0,0 +1,12 @@ +query getRuleOwnerToRemoveByRule($ruleIds: [bigint!]!) { + rule_owner( + where: { + rule_id: { _in: $ruleIds }, + removed: { _is_null: true } + } + ) { + rule_id + owner_id + created + } +} diff --git a/roles/common/files/fwo-api-calls/owner/getRuleOwnerships.graphql b/roles/common/files/fwo-api-calls/owner/getRuleOwnerships.graphql new file mode 100644 index 0000000000..8a48b948cc --- /dev/null +++ b/roles/common/files/fwo-api-calls/owner/getRuleOwnerships.graphql @@ -0,0 +1,10 @@ +query getRuleOwnerships ($ownerId: Int!) { + v_rule_with_rule_owner_1(where: {owner_id: {_eq: $ownerId}} order_by: { mgm_id: asc, rulebase_id: asc }) { + rule_id + rule_name + rule_uid + mgm_id + rulebase_id + rule_metadata_id + } +} diff --git a/roles/common/files/fwo-api-calls/owner/insertRuleOwners.graphql b/roles/common/files/fwo-api-calls/owner/insertRuleOwners.graphql new file mode 100644 index 0000000000..b2d88f42ff --- /dev/null +++ b/roles/common/files/fwo-api-calls/owner/insertRuleOwners.graphql @@ -0,0 +1,13 @@ +mutation insertRuleOwners($objects: [rule_owner_insert_input!]!) { + insert_rule_owner(objects: $objects) { + affected_rows + returning { + rule_id + owner_id + removed + created + rule_metadata_id + owner_mapping_source_id + } + } +} \ No newline at end of file diff --git a/roles/common/files/fwo-api-calls/owner/newNetworkOwnership.graphql b/roles/common/files/fwo-api-calls/owner/newNetworkOwnership.graphql new file mode 100644 index 0000000000..79de1101a0 --- /dev/null +++ b/roles/common/files/fwo-api-calls/owner/newNetworkOwnership.graphql @@ -0,0 +1,17 @@ +mutation newNetworkOwnership( + $ownerId: Int! + $ip: cidr + $ip_end: cidr + ) { + insert_owner_network(objects: { + owner_id: $ownerId + ip: $ip + ip_end: $ip_end + is_deleted: false + nw_type: 10 + }) { + returning { + newIdLong: id + } + } +} diff --git a/roles/common/files/fwo-api-calls/owner/newOwner.graphql b/roles/common/files/fwo-api-calls/owner/newOwner.graphql new file mode 100644 index 0000000000..d7726cbc66 --- /dev/null +++ b/roles/common/files/fwo-api-calls/owner/newOwner.graphql @@ -0,0 +1,33 @@ +mutation newOwner( + $name: String! + $tenantId: Int + $recertInterval: Int + $appIdExternal: String + $recertCheckParams: String + $additionalInfo: jsonb + $ownerLifeCycleStateId: Int + $criticality: String + $importSource: String + $commSvcPossible: Boolean + $recertActive: Boolean + $decommDate: timestamp + ) { + insert_owner(objects: { + name: $name + tenant_id: $tenantId + recert_interval: $recertInterval + app_id_external: $appIdExternal + recert_check_params: $recertCheckParams + additional_info: $additionalInfo + owner_lifecycle_state_id: $ownerLifeCycleStateId + criticality: $criticality + import_source: $importSource + common_service_possible: $commSvcPossible + recert_active: $recertActive + decomm_date: $decommDate + }) { + returning { + newId: id + } + } +} diff --git a/roles/common/files/fwo-api-calls/owner/newOwnerLifeCycle.graphql b/roles/common/files/fwo-api-calls/owner/newOwnerLifeCycle.graphql new file mode 100644 index 0000000000..560afb776e --- /dev/null +++ b/roles/common/files/fwo-api-calls/owner/newOwnerLifeCycle.graphql @@ -0,0 +1,13 @@ +mutation newOwnerLifeCycle( + $name: String! + $activeState: Boolean! + ) { + insert_owner_lifecycle_state(objects: { + name: $name + active_state: $activeState + }) { + returning { + newId: id + } + } +} diff --git a/roles/common/files/fwo-api-calls/owner/newOwnerResponsibleType.graphql b/roles/common/files/fwo-api-calls/owner/newOwnerResponsibleType.graphql new file mode 100644 index 0000000000..477a3a76f6 --- /dev/null +++ b/roles/common/files/fwo-api-calls/owner/newOwnerResponsibleType.graphql @@ -0,0 +1,7 @@ +mutation newOwnerResponsibleType($name: String!, $active: Boolean!, $sort_order: Int!, $allow_modelling: Boolean!, $allow_recertification: Boolean!) { + insert_owner_responsible_type(objects: { name: $name, active: $active, sort_order: $sort_order, allow_modelling: $allow_modelling, allow_recertification: $allow_recertification }) { + returning { + newId: id + } + } +} diff --git a/roles/common/files/fwo-api-calls/owner/newOwnerResponsibles.graphql b/roles/common/files/fwo-api-calls/owner/newOwnerResponsibles.graphql new file mode 100644 index 0000000000..d4468a0bda --- /dev/null +++ b/roles/common/files/fwo-api-calls/owner/newOwnerResponsibles.graphql @@ -0,0 +1,5 @@ +mutation newOwnerResponsibles($responsibles: [owner_responsible_insert_input!]!) { + insert_owner_responsible(objects: $responsibles) { + affected_rows + } +} diff --git a/roles/common/files/fwo-api-calls/owner/newRuleOwnership.graphql b/roles/common/files/fwo-api-calls/owner/newRuleOwnership.graphql new file mode 100644 index 0000000000..103f9c4fc2 --- /dev/null +++ b/roles/common/files/fwo-api-calls/owner/newRuleOwnership.graphql @@ -0,0 +1,13 @@ +mutation newRuleOwnership( + $ownerId: Int! + $ruleMetadataId: bigint! + ) { + insert_rule_owner(objects: { + owner_id: $ownerId + rule_metadata_id: $ruleMetadataId + }) { + returning { + insertedIdLong: rule_metadata_id + } + } +} diff --git a/roles/common/files/fwo-api-calls/owner/setAffectedRuleOwnersRemoved.graphql b/roles/common/files/fwo-api-calls/owner/setAffectedRuleOwnersRemoved.graphql new file mode 100644 index 0000000000..aa0ad7d28f --- /dev/null +++ b/roles/common/files/fwo-api-calls/owner/setAffectedRuleOwnersRemoved.graphql @@ -0,0 +1,15 @@ +mutation setAffectedRuleOwnersRemoved( + $objects: [rule_owner_bool_exp!]!, + $removed: bigint! +) { + update_rule_owner( + where: { + _or: $objects + } + _set: { + removed: $removed + } + ) { + affected_rows + } +} diff --git a/roles/common/files/fwo-api-calls/owner/setAllActiveRuleOwnersRemoved.graphql b/roles/common/files/fwo-api-calls/owner/setAllActiveRuleOwnersRemoved.graphql new file mode 100644 index 0000000000..b5fd4b0df5 --- /dev/null +++ b/roles/common/files/fwo-api-calls/owner/setAllActiveRuleOwnersRemoved.graphql @@ -0,0 +1,8 @@ +mutation setAllActiveRuleOwnersRemoved($controlId: bigint!) { + update_rule_owner( + where: { removed: { _is_null: true } }, + _set: { removed: $controlId } + ) { + affected_rows + } +} \ No newline at end of file diff --git a/roles/lib/files/FWO.Api.Client/APIcalls/owner/setDefaultOwner.graphql b/roles/common/files/fwo-api-calls/owner/setDefaultOwner.graphql similarity index 90% rename from roles/lib/files/FWO.Api.Client/APIcalls/owner/setDefaultOwner.graphql rename to roles/common/files/fwo-api-calls/owner/setDefaultOwner.graphql index 9010b96e28..97c88fe625 100644 --- a/roles/lib/files/FWO.Api.Client/APIcalls/owner/setDefaultOwner.graphql +++ b/roles/common/files/fwo-api-calls/owner/setDefaultOwner.graphql @@ -7,6 +7,6 @@ mutation setDefaultOwner( _set: { is_default: $isDefault }) { - UpdatedId: id + updatedId: id } } diff --git a/roles/lib/files/FWO.Api.Client/APIcalls/owner/setOwnerLastCheck.graphql b/roles/common/files/fwo-api-calls/owner/setOwnerLastCheck.graphql similarity index 91% rename from roles/lib/files/FWO.Api.Client/APIcalls/owner/setOwnerLastCheck.graphql rename to roles/common/files/fwo-api-calls/owner/setOwnerLastCheck.graphql index 66579f941f..fa613f8623 100644 --- a/roles/lib/files/FWO.Api.Client/APIcalls/owner/setOwnerLastCheck.graphql +++ b/roles/common/files/fwo-api-calls/owner/setOwnerLastCheck.graphql @@ -7,6 +7,6 @@ mutation setOwnerLastCheck( _set: { last_recert_check: $lastRecertCheck }) { - UpdatedId: id + updatedId: id } } diff --git a/roles/common/files/fwo-api-calls/owner/setOwnerLastRecert.graphql b/roles/common/files/fwo-api-calls/owner/setOwnerLastRecert.graphql new file mode 100644 index 0000000000..f0716a86ff --- /dev/null +++ b/roles/common/files/fwo-api-calls/owner/setOwnerLastRecert.graphql @@ -0,0 +1,18 @@ +mutation setOwnerLastRecert( + $id: Int! + $lastRecert: timestamp + $lastRecertifierId: Int + $lastRecertifierDn: String + $nextRecertDate: timestamp + ) { + update_owner_by_pk( + pk_columns: { id: $id } + _set: { + last_recertified: $lastRecert + last_recertifier: $lastRecertifierId + last_recertifier_dn: $lastRecertifierDn + next_recert_date: $nextRecertDate + }) { + updatedId: id + } +} diff --git a/roles/common/files/fwo-api-calls/owner/updateChangelogOwner.graphql b/roles/common/files/fwo-api-calls/owner/updateChangelogOwner.graphql new file mode 100644 index 0000000000..89d8b5c30f --- /dev/null +++ b/roles/common/files/fwo-api-calls/owner/updateChangelogOwner.graphql @@ -0,0 +1,19 @@ +mutation updateChangelogOwner( + $control_id: bigint, + $old_owner_id: bigint, + $new_owner_id: bigint, + $change_action: bpchar, + $source_id: String +) { + insert_changelog_owner_one( + object: { + control_id: $control_id + old_owner_id: $old_owner_id + new_owner_id: $new_owner_id + change_action: $change_action + source_id: $source_id + } + ) { + log_owner_id + } +} \ No newline at end of file diff --git a/roles/common/files/fwo-api-calls/owner/updateOwner.graphql b/roles/common/files/fwo-api-calls/owner/updateOwner.graphql new file mode 100644 index 0000000000..4a4f29822e --- /dev/null +++ b/roles/common/files/fwo-api-calls/owner/updateOwner.graphql @@ -0,0 +1,33 @@ +mutation updateOwner( + $id: Int! + $name: String! + $tenantId: Int + $recertInterval: Int + $appIdExternal: String + $recertCheckParams: String + $additionalInfo: jsonb + $ownerLifeCycleStateId: Int + $criticality: String + $commSvcPossible: Boolean + $recertActive: Boolean + $decommDate: timestamp + ) { + update_owner_by_pk( + pk_columns: { id: $id } + _set: { + name: $name + tenant_id: $tenantId + recert_interval: $recertInterval + app_id_external: $appIdExternal + recert_check_params: $recertCheckParams + additional_info: $additionalInfo + owner_lifecycle_state_id: $ownerLifeCycleStateId + criticality: $criticality + common_service_possible: $commSvcPossible + active: true + recert_active: $recertActive + decomm_date: $decommDate + }) { + updatedId: id + } +} diff --git a/roles/common/files/fwo-api-calls/owner/updateOwnerLifeCycle.graphql b/roles/common/files/fwo-api-calls/owner/updateOwnerLifeCycle.graphql new file mode 100644 index 0000000000..febc794024 --- /dev/null +++ b/roles/common/files/fwo-api-calls/owner/updateOwnerLifeCycle.graphql @@ -0,0 +1,14 @@ +mutation updateOwnerLifeCycle( + $id: Int! + $name: String! + $activeState: Boolean! + ) { + update_owner_lifecycle_state_by_pk( + pk_columns: { id: $id } + _set: { + name: $name + active_state: $activeState + }) { + updatedId: id + } +} diff --git a/roles/common/files/fwo-api-calls/owner/updateOwnerResponsibleType.graphql b/roles/common/files/fwo-api-calls/owner/updateOwnerResponsibleType.graphql new file mode 100644 index 0000000000..e462e0ee79 --- /dev/null +++ b/roles/common/files/fwo-api-calls/owner/updateOwnerResponsibleType.graphql @@ -0,0 +1,8 @@ +mutation updateOwnerResponsibleType($id: Int!, $name: String!, $active: Boolean!, $sort_order: Int!, $allow_modelling: Boolean!, $allow_recertification: Boolean!) { + update_owner_responsible_type_by_pk( + pk_columns: { id: $id } + _set: { name: $name, active: $active, sort_order: $sort_order, allow_modelling: $allow_modelling, allow_recertification: $allow_recertification } + ) { + updatedId: id + } +} diff --git a/roles/common/files/fwo-api-calls/recertification/addRecertEntries.graphql b/roles/common/files/fwo-api-calls/recertification/addRecertEntries.graphql new file mode 100644 index 0000000000..c41a1343cc --- /dev/null +++ b/roles/common/files/fwo-api-calls/recertification/addRecertEntries.graphql @@ -0,0 +1,9 @@ +mutation addRecertEntries($recerts:[recertification_insert_input!]!) { + insert_recertification( + objects: $recerts + ) { + returning { + newIdLong: id + } + } +} diff --git a/roles/common/files/fwo-api-calls/recertification/clearOpenRecerts.graphql b/roles/common/files/fwo-api-calls/recertification/clearOpenRecerts.graphql new file mode 100644 index 0000000000..d882321e4a --- /dev/null +++ b/roles/common/files/fwo-api-calls/recertification/clearOpenRecerts.graphql @@ -0,0 +1,12 @@ +mutation clearOpenRecerts($ownerId: Int) { + delete_recertification( + where: { + owner_id: { _eq: $ownerId } + recert_date: { _is_null: true } + } + ) { + returning { + deletedIdLong: id + } + } +} diff --git a/roles/common/files/fwo-api-calls/recertification/fragments/ruleOpenCertOverview.graphql b/roles/common/files/fwo-api-calls/recertification/fragments/ruleOpenCertOverview.graphql new file mode 100644 index 0000000000..6d039c77fa --- /dev/null +++ b/roles/common/files/fwo-api-calls/recertification/fragments/ruleOpenCertOverview.graphql @@ -0,0 +1,115 @@ +fragment ruleOpenCertOverview on rule { + rule_id + rule_uid + rule_action + section_header: rule_head_text + rule_comment + rule_track + rule_disabled +rule_from_zones { + zone { + zone_name + zone_id + } + } + rule_metadatum { + rule_metadata_id + rule_created + rule_first_hit + rule_last_hit + created_import { + start_time + } + recertification: recertifications( + where: { + owner: $ownerWhere + recert_date: { _is_null: true } + next_recert_date: { _lte: $refdate1 } + } + order_by: { owner: { name: asc } } + ) { + recert_date + recertified + ip_match + next_recert_date + owner { + id + name + } + } + recert_history: recertifications( + where: { owner: $ownerWhere, recert_date: { _is_null: false } } + order_by: { recert_date: desc } + ) { + recert_date + recertified + user_dn + comment + owner { + name + } + } + } + rule_src_neg + rule_dst_neg + rule_svc_neg + rule_num_numeric + rule_name + access_rule + nat_rule + xlate_rule + rule_froms( + where: { + rf_create: { _lte: $import_id_end } + _or: [ + { removed: { _is_null: true } } + { removed: { _gt: $import_id_start } } + ] + } + order_by: { object: { obj_name: asc } } + ) { + usr { + ...userOverview + } + object { + ...networkObjectOverview + } + } + rule_to_zones { + zone { + zone_name + zone_id + } + } + rule_tos( + where: { + rt_create: { _lte: $import_id_end } + _or: [ + { removed: { _is_null: true } } + { removed: { _gt: $import_id_start } } + ] + } + order_by: { object: { obj_name: asc } } + ) { + usr { + ...userOverview + } + object { + ...networkObjectOverview + } + } + rule_services( + where: { + rs_create: { _lte: $import_id_end } + _or: [ + { removed: { _is_null: true } } + { removed: { _gt: $import_id_start } } + ] + } + order_by: { service: { svc_name: asc } } + ) { + service { + ...networkServiceOverview + } + } +} diff --git a/roles/common/files/fwo-api-calls/recertification/getInitialOwnerRecert.graphql b/roles/common/files/fwo-api-calls/recertification/getInitialOwnerRecert.graphql new file mode 100644 index 0000000000..6d553c36e5 --- /dev/null +++ b/roles/common/files/fwo-api-calls/recertification/getInitialOwnerRecert.graphql @@ -0,0 +1,12 @@ +query getInitialOwnerRecert ($ownerId: Int!) { + owner_recertification (where: {owner_id: {_eq: $ownerId}, recertified: {_eq: false}}){ + id + owner_id + user_dn + recertified + recert_date + comment + next_recert_date + report_id + } +} diff --git a/roles/common/files/fwo-api-calls/recertification/getOpenRecertsForOwners.graphql b/roles/common/files/fwo-api-calls/recertification/getOpenRecertsForOwners.graphql new file mode 100644 index 0000000000..019d4710bf --- /dev/null +++ b/roles/common/files/fwo-api-calls/recertification/getOpenRecertsForOwners.graphql @@ -0,0 +1,18 @@ +query getOpenRecertsForOwners($ownerId: Int!, $mgmId: Int!) { + recert_get_one_owner_one_mgm( + where: { recert_date: { _is_null: true } } + args: { i_mgm_id: $mgmId, i_owner_id: $ownerId } + ) { + id + rule_metadata_id + rule_id + ip_match + owner_id + user_dn + recertified + next_recert_date + recert_date + comment + owner_recert_id + } +} diff --git a/roles/lib/files/FWO.Api.Client/APIcalls/recertification/getOpenRecertsForRule.graphql b/roles/common/files/fwo-api-calls/recertification/getOpenRecertsForRule.graphql similarity index 100% rename from roles/lib/files/FWO.Api.Client/APIcalls/recertification/getOpenRecertsForRule.graphql rename to roles/common/files/fwo-api-calls/recertification/getOpenRecertsForRule.graphql diff --git a/roles/common/files/fwo-api-calls/recertification/getOwnerRecerts.graphql b/roles/common/files/fwo-api-calls/recertification/getOwnerRecerts.graphql new file mode 100644 index 0000000000..7762780fbf --- /dev/null +++ b/roles/common/files/fwo-api-calls/recertification/getOwnerRecerts.graphql @@ -0,0 +1,12 @@ +query getOwnerRecerts ($ownerId: Int!) { + owner_recertification (where: {owner_id: {_eq: $ownerId}, recertified: {_eq: true}} order_by: { recert_date: desc }){ + id + owner_id + user_dn + recertified + recert_date + comment + next_recert_date + report_id + } +} diff --git a/roles/lib/files/FWO.Api.Client/APIcalls/recertification/prepareNextRecertification.graphql b/roles/common/files/fwo-api-calls/recertification/prepareNextRecertification.graphql similarity index 94% rename from roles/lib/files/FWO.Api.Client/APIcalls/recertification/prepareNextRecertification.graphql rename to roles/common/files/fwo-api-calls/recertification/prepareNextRecertification.graphql index 4092e1cee2..672a3bd4b2 100644 --- a/roles/lib/files/FWO.Api.Client/APIcalls/recertification/prepareNextRecertification.graphql +++ b/roles/common/files/fwo-api-calls/recertification/prepareNextRecertification.graphql @@ -13,7 +13,7 @@ mutation prepareNextRecertification( next_recert_date: $nextRecertDate }) { returning { - newId: id + newIdLong: id } } } diff --git a/roles/lib/files/FWO.Api.Client/APIcalls/recertification/recertify.graphql b/roles/common/files/fwo-api-calls/recertification/recertify.graphql similarity index 87% rename from roles/lib/files/FWO.Api.Client/APIcalls/recertification/recertify.graphql rename to roles/common/files/fwo-api-calls/recertification/recertify.graphql index e23baf0d6f..f5c4459c1b 100644 --- a/roles/lib/files/FWO.Api.Client/APIcalls/recertification/recertify.graphql +++ b/roles/common/files/fwo-api-calls/recertification/recertify.graphql @@ -5,6 +5,7 @@ mutation recertify( $recertified: Boolean $recertDate: timestamp $comment: String + $ownerRecertId: bigint ) { update_recertification( where: {_and: [{rule_id: {_eq: $ruleId}}, {owner_id: {_eq: $ownerId}}, {recert_date: {_is_null: true}}]}, @@ -13,8 +14,9 @@ mutation recertify( recertified: $recertified recert_date: $recertDate comment: $comment + owner_recert_id: $ownerRecertId } ) { affected_rows } - } +} diff --git a/roles/common/files/fwo-api-calls/recertification/recertifyOwner.graphql b/roles/common/files/fwo-api-calls/recertification/recertifyOwner.graphql new file mode 100644 index 0000000000..245f6ac9f9 --- /dev/null +++ b/roles/common/files/fwo-api-calls/recertification/recertifyOwner.graphql @@ -0,0 +1,23 @@ +mutation recertifyOwner( + $ownerId: Int! + $userDn: String + $recertified: Boolean + $recertDate: timestamp + $nextRecertDate: timestamp + $comment: String +) { + insert_owner_recertification( + objects: { + owner_id: $ownerId + user_dn: $userDn + recertified: $recertified + recert_date: $recertDate + next_recert_date: $nextRecertDate + comment: $comment + } + ) { + returning { + newIdLong: id + } + } +} diff --git a/roles/common/files/fwo-api-calls/recertification/recertifyRuleDirectly.graphql b/roles/common/files/fwo-api-calls/recertification/recertifyRuleDirectly.graphql new file mode 100644 index 0000000000..733c41a6a0 --- /dev/null +++ b/roles/common/files/fwo-api-calls/recertification/recertifyRuleDirectly.graphql @@ -0,0 +1,27 @@ +mutation recertifyRuleDirectly( + $ruleMetadataId: bigint! + $ruleId: bigint! + $ownerId: Int! + $nextRecertDate: timestamp + $userDn: String + $recertified: Boolean + $recertDate: timestamp + $comment: String + $ownerRecertId: bigint + ) { + insert_recertification(objects: { + rule_metadata_id: $ruleMetadataId + rule_id: $ruleId + owner_id: $ownerId + next_recert_date: $nextRecertDate + user_dn: $userDn + recertified: $recertified + recert_date: $recertDate + comment: $comment + owner_recert_id: $ownerRecertId + }) { + returning { + newIdLong: id + } + } +} diff --git a/roles/common/files/fwo-api-calls/recertification/refreshViewRuleWithOwner.graphql b/roles/common/files/fwo-api-calls/recertification/refreshViewRuleWithOwner.graphql new file mode 100644 index 0000000000..1746143359 --- /dev/null +++ b/roles/common/files/fwo-api-calls/recertification/refreshViewRuleWithOwner.graphql @@ -0,0 +1,8 @@ +query { + refresh_view_rule_with_owner { + id + view_name + refreshed_at + status + } +} diff --git a/roles/common/files/fwo-api-calls/recertification/updateRecertReportId.graphql b/roles/common/files/fwo-api-calls/recertification/updateRecertReportId.graphql new file mode 100644 index 0000000000..a264e31495 --- /dev/null +++ b/roles/common/files/fwo-api-calls/recertification/updateRecertReportId.graphql @@ -0,0 +1,12 @@ +mutation updateRecertReportId( + $id: bigint! + $reportId: bigint + ) { + update_owner_recertification_by_pk( + pk_columns: { id: $id } + _set: { + report_id: $reportId + }) { + updatedId: id + } +} diff --git a/roles/lib/files/FWO.Api.Client/APIcalls/report/addGeneratedReport.graphql b/roles/common/files/fwo-api-calls/report/addGeneratedReport.graphql similarity index 76% rename from roles/lib/files/FWO.Api.Client/APIcalls/report/addGeneratedReport.graphql rename to roles/common/files/fwo-api-calls/report/addGeneratedReport.graphql index 9f43e8de2d..d550660297 100644 --- a/roles/lib/files/FWO.Api.Client/APIcalls/report/addGeneratedReport.graphql +++ b/roles/common/files/fwo-api-calls/report/addGeneratedReport.graphql @@ -10,24 +10,28 @@ $report_template_id: Int $report_type: Int $description: String + $read_only: Boolean + $owner_id: Int ) { insert_report( objects: { report_name: $report_name report_start_time: $report_start_time report_end_time: $report_end_time - report_owner_id : $report_owner_id + report_owner_id: $report_owner_id report_csv: $report_csv report_pdf: $report_pdf report_html: $report_html report_json: $report_json - report_template_id : $report_template_id + report_template_id: $report_template_id report_type: $report_type description: $description + read_only: $read_only + owner_id: $owner_id } ) { returning { - report_id + newIdLong: report_id } } } diff --git a/roles/lib/files/FWO.Api.Client/APIcalls/report/addReportSchedule.graphql b/roles/common/files/fwo-api-calls/report/addReportSchedule.graphql similarity index 92% rename from roles/lib/files/FWO.Api.Client/APIcalls/report/addReportSchedule.graphql rename to roles/common/files/fwo-api-calls/report/addReportSchedule.graphql index e395316958..3a1b5e9a52 100644 --- a/roles/lib/files/FWO.Api.Client/APIcalls/report/addReportSchedule.graphql +++ b/roles/common/files/fwo-api-calls/report/addReportSchedule.graphql @@ -6,6 +6,7 @@ mutation addReportSchedule( $report_schedule_repeat: Int! # 0 do not repeat, 1 daily, 2 weekly, 3 monthly, 4 yearly $report_schedule_every: Int! # every x days/weeks/months/years $report_schedule_active: Boolean! + $archive: Boolean! $report_schedule_formats: report_schedule_format_arr_rel_insert_input! # array of foreign key to output formats ) { insert_report_schedule( @@ -17,11 +18,12 @@ mutation addReportSchedule( report_schedule_every: $report_schedule_every report_template_id: $report_schedule_template_id report_schedule_active: $report_schedule_active + archive: $archive report_schedule_formats: $report_schedule_formats } ) { returning { - report_schedule_id + newId: report_schedule_id } } } diff --git a/roles/lib/files/FWO.Api.Client/APIcalls/report/addReportScheduleFileFormats.graphql b/roles/common/files/fwo-api-calls/report/addReportScheduleFileFormats.graphql similarity index 100% rename from roles/lib/files/FWO.Api.Client/APIcalls/report/addReportScheduleFileFormats.graphql rename to roles/common/files/fwo-api-calls/report/addReportScheduleFileFormats.graphql diff --git a/roles/lib/files/FWO.Api.Client/APIcalls/report/addReportTemplate.graphql b/roles/common/files/fwo-api-calls/report/addReportTemplate.graphql similarity index 100% rename from roles/lib/files/FWO.Api.Client/APIcalls/report/addReportTemplate.graphql rename to roles/common/files/fwo-api-calls/report/addReportTemplate.graphql diff --git a/roles/lib/files/FWO.Api.Client/APIcalls/report/addReportTemplatePermission.graphql b/roles/common/files/fwo-api-calls/report/addReportTemplatePermission.graphql similarity index 100% rename from roles/lib/files/FWO.Api.Client/APIcalls/report/addReportTemplatePermission.graphql rename to roles/common/files/fwo-api-calls/report/addReportTemplatePermission.graphql diff --git a/roles/lib/files/FWO.Api.Client/APIcalls/report/countReportSchedule.graphql b/roles/common/files/fwo-api-calls/report/countReportSchedule.graphql similarity index 100% rename from roles/lib/files/FWO.Api.Client/APIcalls/report/countReportSchedule.graphql rename to roles/common/files/fwo-api-calls/report/countReportSchedule.graphql diff --git a/roles/common/files/fwo-api-calls/report/deleteGeneratedReport.graphql b/roles/common/files/fwo-api-calls/report/deleteGeneratedReport.graphql new file mode 100644 index 0000000000..ada44d7037 --- /dev/null +++ b/roles/common/files/fwo-api-calls/report/deleteGeneratedReport.graphql @@ -0,0 +1,7 @@ +mutation deleteGeneratedReport ($report_id : bigint!) { + delete_report( + where: {report_id: {_eq: $report_id}, read_only: {_eq: false}} + ) { + affected_rows + } +} \ No newline at end of file diff --git a/roles/lib/files/FWO.Api.Client/APIcalls/report/deleteReportSchedule.graphql b/roles/common/files/fwo-api-calls/report/deleteReportSchedule.graphql similarity index 100% rename from roles/lib/files/FWO.Api.Client/APIcalls/report/deleteReportSchedule.graphql rename to roles/common/files/fwo-api-calls/report/deleteReportSchedule.graphql diff --git a/roles/lib/files/FWO.Api.Client/APIcalls/report/deleteReportTemplate.graphql b/roles/common/files/fwo-api-calls/report/deleteReportTemplate.graphql similarity index 100% rename from roles/lib/files/FWO.Api.Client/APIcalls/report/deleteReportTemplate.graphql rename to roles/common/files/fwo-api-calls/report/deleteReportTemplate.graphql diff --git a/roles/lib/files/FWO.Api.Client/APIcalls/report/editReportSchedule.graphql b/roles/common/files/fwo-api-calls/report/editReportSchedule.graphql similarity index 92% rename from roles/lib/files/FWO.Api.Client/APIcalls/report/editReportSchedule.graphql rename to roles/common/files/fwo-api-calls/report/editReportSchedule.graphql index 90131d6cdb..6c803fce74 100644 --- a/roles/lib/files/FWO.Api.Client/APIcalls/report/editReportSchedule.graphql +++ b/roles/common/files/fwo-api-calls/report/editReportSchedule.graphql @@ -1,7 +1,8 @@ mutation editReportSchedule($report_schedule_id: bigint!, $report_schedule_name: String!, $report_schedule_owner_id: Int!, $report_schedule_template_id: Int!, $report_schedule_start_time : timestamp!, $report_schedule_repeat : Int!, - $report_schedule_every : Int!, $report_schedule_active : Boolean! + $report_schedule_every : Int!, $report_schedule_active : Boolean!, + $archive: Boolean!, $report_schedule_format_names : [String!]!, $report_schedule_format_rel: [report_schedule_format_insert_input!]!) { update_report_schedule( @@ -13,7 +14,8 @@ report_schedule_active: $report_schedule_active, report_schedule_every: $report_schedule_every, report_schedule_repeat: $report_schedule_repeat, - report_template_id: $report_schedule_template_id + report_template_id: $report_schedule_template_id, + archive: $archive } ) { affected_rows @@ -40,4 +42,4 @@ report_schedule_id }, } -} \ No newline at end of file +} diff --git a/roles/common/files/fwo-api-calls/report/getAllObjectDetailsInReport.graphql b/roles/common/files/fwo-api-calls/report/getAllObjectDetailsInReport.graphql new file mode 100644 index 0000000000..004dda42d7 --- /dev/null +++ b/roles/common/files/fwo-api-calls/report/getAllObjectDetailsInReport.graphql @@ -0,0 +1,35 @@ +query getReportFilteredObjectDetails ( + $mgmIds: [Int!] + $ruleIds: _int8 + $active: Boolean + $import_id_start: bigint + $import_id_end: bigint + $limit: Int + $offset: Int +) { + management(where: { mgm_id: { _in: $mgmIds }, stm_dev_typ:{dev_typ_is_multi_mgmt:{_eq:false}} }) { + name: mgm_name + id: mgm_id + reportNetworkObjects: filter_rule_nwobj_resolveds ( + args: {rule_ids: $ruleIds, import_id: $import_id_start} + limit: $limit + offset: $offset + ) { + ...networkObjectDetails + } + reportServiceObjects: filter_rule_svc_resolveds ( + args: {rule_ids: $ruleIds, import_id: $import_id_start} + limit: $limit + offset: $offset + ) { + ...networkServiceDetails + } + reportUserObjects: filter_rule_user_resolveds ( + args: {rule_ids: $ruleIds, import_id: $import_id_start} + limit: $limit + offset: $offset + ) { + ...userDetails + } + } +} diff --git a/roles/lib/files/FWO.Api.Client/APIcalls/report/getGeneratedReport.graphql b/roles/common/files/fwo-api-calls/report/getGeneratedReport.graphql similarity index 100% rename from roles/lib/files/FWO.Api.Client/APIcalls/report/getGeneratedReport.graphql rename to roles/common/files/fwo-api-calls/report/getGeneratedReport.graphql diff --git a/roles/common/files/fwo-api-calls/report/getGeneratedReports.graphql b/roles/common/files/fwo-api-calls/report/getGeneratedReports.graphql new file mode 100644 index 0000000000..ff5160ef0f --- /dev/null +++ b/roles/common/files/fwo-api-calls/report/getGeneratedReports.graphql @@ -0,0 +1,23 @@ +query getGeneratedReports { + report(order_by:{report_id:desc}) { + report_id + report_name + report_start_time + report_end_time + report_type + report_owner_id + description + read_only + owner { + id + name + app_id_external + } + uiuser { + uiuser_username + } + report_template { + report_template_name + } + } +} diff --git a/roles/common/files/fwo-api-calls/report/getImportsToNotify.graphql b/roles/common/files/fwo-api-calls/report/getImportsToNotify.graphql new file mode 100644 index 0000000000..5019d7942c --- /dev/null +++ b/roles/common/files/fwo-api-calls/report/getImportsToNotify.graphql @@ -0,0 +1,15 @@ +query getImportsToNotify { + import_control(where: { + successful_import: {_eq: true} + policy_changes_found: {_eq: true} + notification_done: {_eq: false} + } order_by: {stop_time: asc}) { + control_id + stop_time + mgm_id + management{ + mgm_name + } + security_relevant_changes_counter + } +} diff --git a/roles/common/files/fwo-api-calls/report/getImportsToNotifyForAnyChanges.graphql b/roles/common/files/fwo-api-calls/report/getImportsToNotifyForAnyChanges.graphql new file mode 100644 index 0000000000..d89392f002 --- /dev/null +++ b/roles/common/files/fwo-api-calls/report/getImportsToNotifyForAnyChanges.graphql @@ -0,0 +1,16 @@ +query getImportsToNotifyForAnyChanges { + import_control(where: { + is_initial_import: {_eq: false} + successful_import: {_eq: true} + changes_found: {_eq: true} + notification_done: {_eq: false} + } order_by: {stop_time: asc}) { + control_id + stop_time + mgm_id + management{ + mgm_name + } + security_relevant_changes_counter + } +} diff --git a/roles/common/files/fwo-api-calls/report/getImportsToNotifyForRuleChanges.graphql b/roles/common/files/fwo-api-calls/report/getImportsToNotifyForRuleChanges.graphql new file mode 100644 index 0000000000..d219b7b2d3 --- /dev/null +++ b/roles/common/files/fwo-api-calls/report/getImportsToNotifyForRuleChanges.graphql @@ -0,0 +1,16 @@ +query getImportsToNotifyForRuleChanges { + import_control(where: { + is_initial_import: {_eq: false} + successful_import: {_eq: true} + policy_changes_found: {_eq: true} + notification_done: {_eq: false} + } order_by: {stop_time: asc}) { + control_id + stop_time + mgm_id + management{ + mgm_name + } + security_relevant_changes_counter + } +} diff --git a/roles/common/files/fwo-api-calls/report/getManagementForLatestNormalizedConfig.graphql b/roles/common/files/fwo-api-calls/report/getManagementForLatestNormalizedConfig.graphql new file mode 100644 index 0000000000..0bd6e15001 --- /dev/null +++ b/roles/common/files/fwo-api-calls/report/getManagementForLatestNormalizedConfig.graphql @@ -0,0 +1,180 @@ +query getManagementForLatestNormalizedConfig( + $mgm_ids: [Int!]! +) { + management(where: { mgm_id: { _in: $mgm_ids } }) { + id: mgm_id + uid: mgm_uid + name: mgm_name + networkObjects: objects(where: { removed: { _is_null: true } }) { + ...networkObjectFragment + } + serviceObjects: services(where: { removed: { _is_null: true } }) { + ...serviceObjectFragment + } + userObjects: usrs(where: { removed: { _is_null: true } }) { + ...userObjectFragment + } + zoneObjects: zones(where: { removed: { _is_null: true } }) { + zone_name + } + timeObjects: time_objects(where: { removed: { _is_null: true } }) { + ...timeObjectFragment + } + rulebases(where: { removed: { _is_null: true } }) { + ...rulebaseFragment + } + devices { + ...deviceFragment + } + } +} + +fragment networkObjectFragment on object { + obj_id + obj_uid + obj_name + obj_ip + obj_ip_end + type: stm_obj_typ { + name: obj_typ_name + } + obj_color: stm_color { + color_name + } + obj_member_refs + obj_member_names + obj_comment +} + +fragment serviceObjectFragment on service { + svc_id + svc_uid + svc_name + svc_port + svc_port_end + svc_timeout + service_type: stm_svc_typ { + name: svc_typ_name + } + stm_color { + color_name + } + ip_proto_id + svc_member_refs + svc_member_names + svc_comment + svc_rpcnr +} + +fragment userObjectFragment on usr { + user_id + user_uid + user_name + user_lastname + user_firstname + type: stm_usr_typ { + usr_typ_name + } + user_member_names + user_member_refs + user_comment +} + +fragment timeObjectFragment on time_object { + time_obj_id + time_obj_uid + time_obj_name + start_time + end_time +} + +fragment rulebaseFragment on rulebase { + id + name + uid + is_global + rules(where: { removed: { _is_null: true } } order_by: { rule_num_numeric: asc }) { + ...ruleFragment + } +} + +fragment ruleFragment on rule { + rule_id + rule_uid + rule_name + rule_num + rule_num_numeric + rule_disabled + rule_src_neg + rule_src + rule_src_refs + rule_dst_neg + rule_dst + rule_dst_refs + rule_svc_neg + rule_svc + rule_svc_refs + rule_action + rule_track + rule_installon + rule_time + rule_custom_fields + rule_implied + nat_rule + uiuser { + uiuser_username + } + rule { + rule_uid + } + rule_metadatum { + rule_last_hit + } + rule_comment + rule_from_zones { + zone { + zone_name + } + } + rule_to_zones { + zone { + zone_name + } + } + section_header: rule_head_text +} + +fragment deviceFragment on device { + id: dev_id + uid: dev_uid + name: dev_name + #TODO: routing + #TODO: interfaces + rulebase_links(where: { removed: { _is_null: true } }) { + ...ruleBaseLinkFragment + } + global_rulebase_uid + #TODO: EnforcedPolicyUids + #TODO: EnforcedNatPolicyUids + importDisabled: do_not_import + hideInUi: hide_in_gui +} + +fragment ruleBaseLinkFragment on rulebase_link { + gw_id + rule { + rule_uid + } + rulebaseByFromRulebaseId { + uid + } + rulebase { + uid + } + stm_link_type { + name + } + is_initial + is_global + is_section +} diff --git a/roles/common/files/fwo-api-calls/report/getManagementForNormalizedConfig.graphql b/roles/common/files/fwo-api-calls/report/getManagementForNormalizedConfig.graphql new file mode 100644 index 0000000000..33a55fe52d --- /dev/null +++ b/roles/common/files/fwo-api-calls/report/getManagementForNormalizedConfig.graphql @@ -0,0 +1,235 @@ +query getManagementForNormalizedConfig( + $mgm_id: Int! + $import_id: Int! +) { + management(where: { mgm_id: { _eq: $mgm_id } }) { + id: mgm_id + uid: mgm_uid + name: mgm_name + networkObjects: objects( + where: { + obj_create: { _lte: $import_id } + _or: [ + { removed: { _is_null: true } } + { removed: { _gte: $import_id } } + ] + } + ) { + ...networkObjectFragment + } + serviceObjects: services( + where: { + svc_create: { _lte: $import_id } + _or: [ + { removed: { _is_null: true } } + { removed: { _gte: $import_id } } + ] + } + ) { + ...serviceObjectFragment + } + userObjects: usrs( + where: { + user_create: { _lte: $import_id_end } + _or: [ + { removed: { _is_null: true } } + { removed: { _gte: $import_id_start } } + ] + } + ) { + ...userObjectFragment + } + zoneObjects: zones( + where: { + zone_create: { _lte: $import_id } + _or: [ + { removed: { _is_null: true } } + { removed: { _gte: $import_id } } + ] + } + ) { + zone_name + } + timeObjects: time_objects( + where: { + created: { _lte: $import_id } + _or: [ + { removed: { _is_null: true } } + { removed: { _gte: $import_id } } + ] + } + ) { + ...timeObjectFragment + } + rulebases( + where: { + created: { _lte: $import_id } + _or: [ + { removed: { _is_null: true } } + { removed: { _gte: $import_id } } + ] + } + ) { + ...rulebaseFragment + } + devices { + ...deviceFragment + } + } +} + +fragment networkObjectFragment on object { + obj_id + obj_uid + obj_name + obj_ip + obj_ip_end + type: stm_obj_typ { + name: obj_typ_name + } + obj_color: stm_color { + color_name + } + obj_member_refs + obj_member_names + obj_comment +} + +fragment serviceObjectFragment on service { + svc_id + svc_uid + svc_name + svc_port + svc_port_end + svc_timeout + service_type: stm_svc_typ { + name: svc_typ_name + } + stm_color { + color_name + } + ip_proto_id + svc_member_refs + svc_member_names + svc_comment + svc_rpcnr +} + +fragment userObjectFragment on usr { + user_id + user_uid + user_name + user_lastname + user_firstname + type: stm_usr_typ { + usr_typ_name + } + user_member_names + user_member_refs + user_comment +} + +fragment timeObjectFragment on time_object { + time_obj_id + time_obj_uid + time_obj_name + start_time + end_time +} + +fragment rulebaseFragment on rulebase { + id + name + uid + is_global + rules(where: { + rule_create: { _lte: $import_id } + _or: [ + { removed: { _is_null: true } } + { removed: { _gte: $import_id } } + ] + }) { + ...ruleFragment + } +} + +fragment ruleFragment on rule { + rule_id + rule_uid + rule_name + rule_num + rule_num_numeric + rule_disabled + rule_src_neg + rule_src + rule_src_refs + rule_dst_neg + rule_dst + rule_dst_refs + rule_svc_neg + rule_svc + rule_svc_refs + rule_action + rule_track + rule_installon + rule_time + rule_custom_fields + rule_implied + nat_rule + uiuser { + uiuser_username + } + rule { + rule_uid + } + rule_metadatum { + rule_last_hit + } + rule_comment + rule_from_zones { + zone { + zone_name + } + } + rule_to_zones { + zone { + zone_name + } + } + section_header: rule_head_text +} + +fragment deviceFragment on device { + id: dev_id + uid: dev_uid + name: dev_name + #TODO: routing + #TODO: interfaces + rulebase_links(where: { removed: { _is_null: true } }) { + ...ruleBaseLinkFragment + } + global_rulebase_uid + #TODO: EnforcedPolicyUids + #TODO: EnforcedNatPolicyUids + importDisabled: do_not_import + hideInUi: hide_in_gui +} + +fragment ruleBaseLinkFragment on rulebase_link { + gw_id + rule { + rule_uid + } + rulebaseByFromRulebaseId { + uid + } + rulebase { + uid + } + stm_link_type { + name + } + is_initial + is_global + is_section +} diff --git a/roles/common/files/fwo-api-calls/report/getModelledRulesByManagementComment.graphql b/roles/common/files/fwo-api-calls/report/getModelledRulesByManagementComment.graphql new file mode 100644 index 0000000000..ce2daf0ffe --- /dev/null +++ b/roles/common/files/fwo-api-calls/report/getModelledRulesByManagementComment.graphql @@ -0,0 +1,22 @@ +query getModelledRulesByManagementComment ( + $mgmId: Int! + $active: Boolean + $import_id_start: bigint + $import_id_end: bigint + $marker: String +) { + rule ( + where: { + mgm_id: { _eq: $mgmId } + active: { _eq: true } + access_rule: { _eq: true } + rule_head_text: { _is_null: true } + rule_disabled: { _eq: false } + action_id: { _nin: [2,3,7] } + import_control: {control_id: {_lte: $import_id_end}}, _or: [{removed: {_is_null: true}}, {removed: {_gt: $import_id_start}}] + rule_comment: { _ilike: $marker } + } + order_by: { rule_num_numeric: asc }){ + ...ruleDetailsForReport + } +} diff --git a/roles/common/files/fwo-api-calls/report/getModelledRulesByManagementName.graphql b/roles/common/files/fwo-api-calls/report/getModelledRulesByManagementName.graphql new file mode 100644 index 0000000000..b60db65e46 --- /dev/null +++ b/roles/common/files/fwo-api-calls/report/getModelledRulesByManagementName.graphql @@ -0,0 +1,22 @@ +query getModelledRulesByManagementName ( + $mgmId: Int! + $active: Boolean + $import_id_start: bigint + $import_id_end: bigint + $marker: String +) { + rule ( + where: { + mgm_id: { _eq: $mgmId } + active: { _eq: true } + access_rule: { _eq: true } + rule_head_text: { _is_null: true } + rule_disabled: { _eq: false } + action_id: { _nin: [2,3,7] } + import_control: {control_id: {_lte: $import_id_end}}, _or: [{removed: {_is_null: true}}, {removed: {_gt: $import_id_start}}] + rule_name: { _ilike: $marker } + } + order_by: { rule_num_numeric: asc }){ + ...ruleDetailsForReport + } +} diff --git a/roles/common/files/fwo-api-calls/report/getRelevantImportIdsAtTime.graphql b/roles/common/files/fwo-api-calls/report/getRelevantImportIdsAtTime.graphql new file mode 100644 index 0000000000..a882e66c92 --- /dev/null +++ b/roles/common/files/fwo-api-calls/report/getRelevantImportIdsAtTime.graphql @@ -0,0 +1,33 @@ +query getRelevantImportIdsAtTime( + $time: timestamp! + $mgmIds: [Int!] + $ruleChangesFound: Boolean +) { + management(where: { + _or: [ + { mgm_id: {_in: $mgmIds}} + {_and: { + is_super_manager: {_eq: true} + managementByMultiDeviceManagerId: { mgm_id: {_in: $mgmIds}} + }} + ] + hide_in_gui: {_eq: false} + } order_by: {mgm_name: asc}) { + name: mgm_name + id: mgm_id + is_super_manager + multi_device_manager_id + import: import_controls_aggregate(where: { + stop_time: {_lte: $time} + successful_import: {_eq: true} + changes_found: {_eq: true} + policy_changes_found: {_eq: $ruleChangesFound} + }) { + aggregate { + max { + id: control_id + } + } + } + } +} diff --git a/roles/common/files/fwo-api-calls/report/getRelevantImportIdsInTimeRange.graphql b/roles/common/files/fwo-api-calls/report/getRelevantImportIdsInTimeRange.graphql new file mode 100644 index 0000000000..8bf7b95b63 --- /dev/null +++ b/roles/common/files/fwo-api-calls/report/getRelevantImportIdsInTimeRange.graphql @@ -0,0 +1,36 @@ +query getRelevantImportIdsInTimeRange( + $start_time: timestamp! + $end_time: timestamp! + $mgmIds: [Int!]! + $ruleChangesFound: Boolean +) { + management(where: { + _or: [ + { mgm_id: {_in: $mgmIds}} + {_and: { + is_super_manager: {_eq: true} + managementByMultiDeviceManagerId: { mgm_id: {_in: $mgmIds}} + }} + ] + hide_in_gui: {_eq: false} + } order_by: {mgm_name: asc}) { + id: mgm_id + managementByMultiDeviceManagerId { + id: mgm_id + } + import_controls( + where: { + _and: [ + { stop_time: { _gte: $start_time } } + { stop_time: { _lte: $end_time } } + ] + successful_import: { _eq: true } + changes_found: { _eq: true } + policy_changes_found: { _eq: $ruleChangesFound } + } + order_by: { stop_time: asc } + ) { + control_id + } + } +} diff --git a/roles/lib/files/FWO.Api.Client/APIcalls/report/getReportById.graphql b/roles/common/files/fwo-api-calls/report/getReportById.graphql similarity index 100% rename from roles/lib/files/FWO.Api.Client/APIcalls/report/getReportById.graphql rename to roles/common/files/fwo-api-calls/report/getReportById.graphql diff --git a/roles/common/files/fwo-api-calls/report/getReportFilteredNetworkObjectDetails.graphql b/roles/common/files/fwo-api-calls/report/getReportFilteredNetworkObjectDetails.graphql new file mode 100644 index 0000000000..f6bc1dbb42 --- /dev/null +++ b/roles/common/files/fwo-api-calls/report/getReportFilteredNetworkObjectDetails.graphql @@ -0,0 +1,21 @@ +query getReportFilteredNetworkObjectDetails ( + $mgmIds: [Int!] + $active: Boolean + $import_id_start: bigint + $import_id_end: bigint + $ruleIds: _int8 + $limit: Int + $offset: Int +) { + management(where: { mgm_id: { _in: $mgmIds }, stm_dev_typ:{dev_typ_is_multi_mgmt:{_eq:false}} }) { + name: mgm_name + id: mgm_id + reportNetworkObjects: filter_rule_nwobj_resolveds ( + args: {rule_ids: $ruleIds, import_id: $import_id_start} + limit: $limit + offset: $offset + ) { + ...networkObjectDetails + } + } +} diff --git a/roles/common/files/fwo-api-calls/report/getReportFilteredNetworkServiceDetails.graphql b/roles/common/files/fwo-api-calls/report/getReportFilteredNetworkServiceDetails.graphql new file mode 100644 index 0000000000..f3e4a62f40 --- /dev/null +++ b/roles/common/files/fwo-api-calls/report/getReportFilteredNetworkServiceDetails.graphql @@ -0,0 +1,21 @@ +query getReportFilteredNetworkServiceDetails ( + $mgmIds: [Int!] + $ruleIds: _int8 + $active: Boolean + $import_id_start: bigint + $import_id_end: bigint + $limit: Int + $offset: Int +) { + management(where: { mgm_id: { _in: $mgmIds }, stm_dev_typ:{dev_typ_is_multi_mgmt:{_eq:false}} }) { + name: mgm_name + id: mgm_id + reportServiceObjects: filter_rule_svc_resolveds ( + args: {rule_ids: $ruleIds, import_id: $import_id_start} + limit: $limit + offset: $offset + ) { + ...networkServiceDetails + } + } +} diff --git a/roles/common/files/fwo-api-calls/report/getReportFilteredObjectDetails.graphql b/roles/common/files/fwo-api-calls/report/getReportFilteredObjectDetails.graphql new file mode 100644 index 0000000000..004dda42d7 --- /dev/null +++ b/roles/common/files/fwo-api-calls/report/getReportFilteredObjectDetails.graphql @@ -0,0 +1,35 @@ +query getReportFilteredObjectDetails ( + $mgmIds: [Int!] + $ruleIds: _int8 + $active: Boolean + $import_id_start: bigint + $import_id_end: bigint + $limit: Int + $offset: Int +) { + management(where: { mgm_id: { _in: $mgmIds }, stm_dev_typ:{dev_typ_is_multi_mgmt:{_eq:false}} }) { + name: mgm_name + id: mgm_id + reportNetworkObjects: filter_rule_nwobj_resolveds ( + args: {rule_ids: $ruleIds, import_id: $import_id_start} + limit: $limit + offset: $offset + ) { + ...networkObjectDetails + } + reportServiceObjects: filter_rule_svc_resolveds ( + args: {rule_ids: $ruleIds, import_id: $import_id_start} + limit: $limit + offset: $offset + ) { + ...networkServiceDetails + } + reportUserObjects: filter_rule_user_resolveds ( + args: {rule_ids: $ruleIds, import_id: $import_id_start} + limit: $limit + offset: $offset + ) { + ...userDetails + } + } +} diff --git a/roles/common/files/fwo-api-calls/report/getReportFilteredUserDetails.graphql b/roles/common/files/fwo-api-calls/report/getReportFilteredUserDetails.graphql new file mode 100644 index 0000000000..2e9556f0d8 --- /dev/null +++ b/roles/common/files/fwo-api-calls/report/getReportFilteredUserDetails.graphql @@ -0,0 +1,21 @@ +query getReportFilteredUserDetails ( + $mgmIds: [Int!] + $active: Boolean + $import_id_start: bigint + $import_id_end: bigint + $ruleIds: _int8 + $limit: Int + $offset: Int +) { + management(where: { mgm_id: { _in: $mgmIds }, stm_dev_typ:{dev_typ_is_multi_mgmt:{_eq:false}} }) { + name: mgm_name + id: mgm_id + reportUserObjects: filter_rule_user_resolveds ( + args: {rule_ids: $ruleIds, import_id: $import_id_start} + limit: $limit + offset: $offset + ) { + ...userDetails + } + } +} \ No newline at end of file diff --git a/roles/common/files/fwo-api-calls/report/getReportSchedules.graphql b/roles/common/files/fwo-api-calls/report/getReportSchedules.graphql new file mode 100644 index 0000000000..78163c60c2 --- /dev/null +++ b/roles/common/files/fwo-api-calls/report/getReportSchedules.graphql @@ -0,0 +1,45 @@ +query getReportSchedules { + report_schedule(order_by: {report_schedule_id: desc}) { + report_schedule_id + report_schedule_name + report_schedule_every + report_schedule_repeat + report_schedule_start_time + archive + report_schedule_owner_user: uiuser { + uiuser_id + uiuser_username + ldap_connection: ldap_connection { + ldap_connection_id + } + } + report_schedule_active + report_schedule_template: report_template { + report_template_id + report_template_name + report_filter + report_parameters + } + report_schedule_formats { + report_schedule_format_name + } + notifications(where: {notification_client: {_eq: "Report"}}) { + id + notification_client + channel + recipient_to + email_address_to + recipient_cc + email_address_cc + email_subject + email_body + layout + deadline + schedule_id + bundle_type + bundle_id + last_sent + } + report_schedule_counter + } +} diff --git a/roles/lib/files/FWO.Api.Client/APIcalls/report/getReportTemplates.graphql b/roles/common/files/fwo-api-calls/report/getReportTemplates.graphql similarity index 100% rename from roles/lib/files/FWO.Api.Client/APIcalls/report/getReportTemplates.graphql rename to roles/common/files/fwo-api-calls/report/getReportTemplates.graphql diff --git a/roles/lib/files/FWO.Api.Client/APIcalls/report/getReportsOverview.graphql b/roles/common/files/fwo-api-calls/report/getReportsOverview.graphql similarity index 100% rename from roles/lib/files/FWO.Api.Client/APIcalls/report/getReportsOverview.graphql rename to roles/common/files/fwo-api-calls/report/getReportsOverview.graphql diff --git a/roles/common/files/fwo-api-calls/report/getUsageDataCount.graphql b/roles/common/files/fwo-api-calls/report/getUsageDataCount.graphql new file mode 100644 index 0000000000..3fdd082b9c --- /dev/null +++ b/roles/common/files/fwo-api-calls/report/getUsageDataCount.graphql @@ -0,0 +1,13 @@ +query getUsageDataCount($devId: Int!) { + device(where: {dev_id: {_eq: $devId}}) { + rulebase_on_gateways { + rulebase { + rulesWithHits: rule_metadata_aggregate(where: {rule_last_hit: {_is_null: false}}) { + aggregate { + count + } + } + } + } + } +} diff --git a/roles/common/files/fwo-api-calls/report/setImportsNotified.graphql b/roles/common/files/fwo-api-calls/report/setImportsNotified.graphql new file mode 100644 index 0000000000..720e5ff685 --- /dev/null +++ b/roles/common/files/fwo-api-calls/report/setImportsNotified.graphql @@ -0,0 +1,9 @@ +mutation setImportsNotified($ids: [bigint!]) { + update_import_control( + where: { control_id: {_in: $ids} } + _set: { + notification_done: true + }) { + affected_rows + } +} diff --git a/roles/lib/files/FWO.Api.Client/APIcalls/report/statisticsCurrent.graphql b/roles/common/files/fwo-api-calls/report/statisticsCurrent.graphql similarity index 100% rename from roles/lib/files/FWO.Api.Client/APIcalls/report/statisticsCurrent.graphql rename to roles/common/files/fwo-api-calls/report/statisticsCurrent.graphql diff --git a/roles/lib/files/FWO.Api.Client/APIcalls/report/statisticsCurrentOverall.graphql b/roles/common/files/fwo-api-calls/report/statisticsCurrentOverall.graphql similarity index 100% rename from roles/lib/files/FWO.Api.Client/APIcalls/report/statisticsCurrentOverall.graphql rename to roles/common/files/fwo-api-calls/report/statisticsCurrentOverall.graphql diff --git a/roles/lib/files/FWO.Api.Client/APIcalls/report/subscribeGeneratedReportsChanges.graphql b/roles/common/files/fwo-api-calls/report/subscribeGeneratedReportsChanges.graphql similarity index 75% rename from roles/lib/files/FWO.Api.Client/APIcalls/report/subscribeGeneratedReportsChanges.graphql rename to roles/common/files/fwo-api-calls/report/subscribeGeneratedReportsChanges.graphql index 14057b001c..bcc3574dba 100644 --- a/roles/lib/files/FWO.Api.Client/APIcalls/report/subscribeGeneratedReportsChanges.graphql +++ b/roles/common/files/fwo-api-calls/report/subscribeGeneratedReportsChanges.graphql @@ -5,7 +5,14 @@ subscription subscribeGeneratedReportsChanges { report_start_time report_end_time report_type + report_owner_id description + read_only + owner { + id + name + app_id_external + } uiuser { uiuser_username } diff --git a/roles/common/files/fwo-api-calls/report/subscribeReportScheduleChanges.graphql b/roles/common/files/fwo-api-calls/report/subscribeReportScheduleChanges.graphql new file mode 100644 index 0000000000..50a8d08e6a --- /dev/null +++ b/roles/common/files/fwo-api-calls/report/subscribeReportScheduleChanges.graphql @@ -0,0 +1,45 @@ +subscription subscribeReportScheduleChanges { + report_schedule(order_by: {report_schedule_id: desc}) { + report_schedule_id + report_schedule_name + report_schedule_every + report_schedule_repeat + report_schedule_start_time + archive + report_schedule_owner_user: uiuser { + uiuser_id + uiuser_username + ldap_connection: ldap_connection { + ldap_connection_id + } + } + report_schedule_active + report_schedule_template: report_template { + report_template_id + report_template_name + report_filter + report_parameters + } + report_schedule_formats { + report_schedule_format_name + } + notifications(where: {notification_client: {_eq: "Report"}}) { + id + notification_client + channel + recipient_to + email_address_to + recipient_cc + email_address_cc + email_subject + email_body + layout + deadline + schedule_id + bundle_type + bundle_id + last_sent + } + report_schedule_counter + } +} diff --git a/roles/common/files/fwo-api-calls/report/updateReportTemplate.graphql b/roles/common/files/fwo-api-calls/report/updateReportTemplate.graphql new file mode 100644 index 0000000000..e320c0866e --- /dev/null +++ b/roles/common/files/fwo-api-calls/report/updateReportTemplate.graphql @@ -0,0 +1,23 @@ +mutation updateReportTemplate( + $reportTemplateId: Int + $reportTemplateName: String + $reportTemplateCreate: timestamp + $reportTemplateComment: String + $reportFilterLine: String + $reportTemplateOwner: Int + $reportParameters: json +) { + update_report_template( + where: { report_template_id: { _eq: $reportTemplateId } } + _set: { + report_template_name: $reportTemplateName + report_template_create: $reportTemplateCreate + report_template_comment: $reportTemplateComment + report_filter: $reportFilterLine + report_template_owner: $reportTemplateOwner + report_parameters: $reportParameters + } + ) { + affected_rows + } +} diff --git a/roles/lib/files/FWO.Api.Client/APIcalls/request/addCommentToApproval.graphql b/roles/common/files/fwo-api-calls/request/addCommentToApproval.graphql similarity index 86% rename from roles/lib/files/FWO.Api.Client/APIcalls/request/addCommentToApproval.graphql rename to roles/common/files/fwo-api-calls/request/addCommentToApproval.graphql index 5732f18019..e8fc60cf2d 100644 --- a/roles/lib/files/FWO.Api.Client/APIcalls/request/addCommentToApproval.graphql +++ b/roles/common/files/fwo-api-calls/request/addCommentToApproval.graphql @@ -7,7 +7,7 @@ mutation addCommentToApproval( comment_id: $commentId }) { returning { - newId: approval_id + insertedIdLong: approval_id } } } diff --git a/roles/lib/files/FWO.Api.Client/APIcalls/request/addCommentToImplTask.graphql b/roles/common/files/fwo-api-calls/request/addCommentToImplTask.graphql similarity index 87% rename from roles/lib/files/FWO.Api.Client/APIcalls/request/addCommentToImplTask.graphql rename to roles/common/files/fwo-api-calls/request/addCommentToImplTask.graphql index 3bc24b7c80..b50b7cd65f 100644 --- a/roles/lib/files/FWO.Api.Client/APIcalls/request/addCommentToImplTask.graphql +++ b/roles/common/files/fwo-api-calls/request/addCommentToImplTask.graphql @@ -7,7 +7,7 @@ mutation addCommentToImplTask( comment_id: $commentId }) { returning { - newId: task_id + insertedIdLong: task_id } } } diff --git a/roles/lib/files/FWO.Api.Client/APIcalls/request/addCommentToReqTask.graphql b/roles/common/files/fwo-api-calls/request/addCommentToReqTask.graphql similarity index 87% rename from roles/lib/files/FWO.Api.Client/APIcalls/request/addCommentToReqTask.graphql rename to roles/common/files/fwo-api-calls/request/addCommentToReqTask.graphql index e54e8d3921..9e0cf706c1 100644 --- a/roles/lib/files/FWO.Api.Client/APIcalls/request/addCommentToReqTask.graphql +++ b/roles/common/files/fwo-api-calls/request/addCommentToReqTask.graphql @@ -7,7 +7,7 @@ mutation addCommentToReqTask( comment_id: $commentId }) { returning { - newId: task_id + insertedIdLong: task_id } } } diff --git a/roles/lib/files/FWO.Api.Client/APIcalls/request/addCommentToTicket.graphql b/roles/common/files/fwo-api-calls/request/addCommentToTicket.graphql similarity index 86% rename from roles/lib/files/FWO.Api.Client/APIcalls/request/addCommentToTicket.graphql rename to roles/common/files/fwo-api-calls/request/addCommentToTicket.graphql index d0eb1f1f44..9a891055f1 100644 --- a/roles/lib/files/FWO.Api.Client/APIcalls/request/addCommentToTicket.graphql +++ b/roles/common/files/fwo-api-calls/request/addCommentToTicket.graphql @@ -7,7 +7,7 @@ mutation addCommentToTicket( comment_id: $commentId }) { returning { - newId: ticket_id + insertedIdLong: ticket_id } } } diff --git a/roles/common/files/fwo-api-calls/request/addExtState.graphql b/roles/common/files/fwo-api-calls/request/addExtState.graphql new file mode 100644 index 0000000000..d08dcf7471 --- /dev/null +++ b/roles/common/files/fwo-api-calls/request/addExtState.graphql @@ -0,0 +1,13 @@ +mutation addExtState( + $name: String! + $stateId: Int! + ) { + insert_request_ext_state(objects: { + name: $name + state_id: $stateId + }) { + returning { + newId: id + } + } +} diff --git a/roles/common/files/fwo-api-calls/request/addOwnerToReqTask.graphql b/roles/common/files/fwo-api-calls/request/addOwnerToReqTask.graphql new file mode 100644 index 0000000000..2f2b06346f --- /dev/null +++ b/roles/common/files/fwo-api-calls/request/addOwnerToReqTask.graphql @@ -0,0 +1,13 @@ +mutation addOwnerToReqTask( + $reqTaskId: bigint + $ownerId: Int! + ) { + insert_reqtask_owner(objects: { + reqtask_id: $reqTaskId + owner_id: $ownerId + }) { + returning { + newId: owner_id + } + } +} diff --git a/roles/lib/files/FWO.Api.Client/APIcalls/request/addStateAction.graphql b/roles/common/files/fwo-api-calls/request/addStateAction.graphql similarity index 100% rename from roles/lib/files/FWO.Api.Client/APIcalls/request/addStateAction.graphql rename to roles/common/files/fwo-api-calls/request/addStateAction.graphql diff --git a/roles/lib/files/FWO.Api.Client/APIcalls/request/deleteAction.graphql b/roles/common/files/fwo-api-calls/request/deleteAction.graphql similarity index 100% rename from roles/lib/files/FWO.Api.Client/APIcalls/request/deleteAction.graphql rename to roles/common/files/fwo-api-calls/request/deleteAction.graphql diff --git a/roles/lib/files/FWO.Api.Client/APIcalls/request/deleteImplementationElement.graphql b/roles/common/files/fwo-api-calls/request/deleteImplementationElement.graphql similarity index 83% rename from roles/lib/files/FWO.Api.Client/APIcalls/request/deleteImplementationElement.graphql rename to roles/common/files/fwo-api-calls/request/deleteImplementationElement.graphql index bced1d8b6e..305635f8a1 100644 --- a/roles/lib/files/FWO.Api.Client/APIcalls/request/deleteImplementationElement.graphql +++ b/roles/common/files/fwo-api-calls/request/deleteImplementationElement.graphql @@ -2,6 +2,6 @@ mutation deleteImplementationElement ($id: bigint!) { delete_request_implelement_by_pk ( id: $id ) { - DeletedId: id + deletedIdLong: id } } diff --git a/roles/lib/files/FWO.Api.Client/APIcalls/request/deleteImplementationTask.graphql b/roles/common/files/fwo-api-calls/request/deleteImplementationTask.graphql similarity index 83% rename from roles/lib/files/FWO.Api.Client/APIcalls/request/deleteImplementationTask.graphql rename to roles/common/files/fwo-api-calls/request/deleteImplementationTask.graphql index eb660551cc..53d76b7171 100644 --- a/roles/lib/files/FWO.Api.Client/APIcalls/request/deleteImplementationTask.graphql +++ b/roles/common/files/fwo-api-calls/request/deleteImplementationTask.graphql @@ -2,6 +2,6 @@ mutation deleteImplementationTask ($id: bigint!) { delete_request_impltask_by_pk ( id: $id ) { - DeletedId: id + deletedIdLong: id } } diff --git a/roles/lib/files/FWO.Api.Client/APIcalls/request/deleteRequestElement.graphql b/roles/common/files/fwo-api-calls/request/deleteRequestElement.graphql similarity index 82% rename from roles/lib/files/FWO.Api.Client/APIcalls/request/deleteRequestElement.graphql rename to roles/common/files/fwo-api-calls/request/deleteRequestElement.graphql index 709d736029..9118788624 100644 --- a/roles/lib/files/FWO.Api.Client/APIcalls/request/deleteRequestElement.graphql +++ b/roles/common/files/fwo-api-calls/request/deleteRequestElement.graphql @@ -2,6 +2,6 @@ mutation deleteRequestElement ($id: bigint!) { delete_request_reqelement_by_pk ( id: $id ) { - DeletedId: id + deletedIdLong: id } } diff --git a/roles/lib/files/FWO.Api.Client/APIcalls/request/deleteRequestTask.graphql b/roles/common/files/fwo-api-calls/request/deleteRequestTask.graphql similarity index 82% rename from roles/lib/files/FWO.Api.Client/APIcalls/request/deleteRequestTask.graphql rename to roles/common/files/fwo-api-calls/request/deleteRequestTask.graphql index 68d625929d..c4dbe534c2 100644 --- a/roles/lib/files/FWO.Api.Client/APIcalls/request/deleteRequestTask.graphql +++ b/roles/common/files/fwo-api-calls/request/deleteRequestTask.graphql @@ -2,6 +2,6 @@ mutation deleteRequestTask ($id: bigint!) { delete_request_reqtask_by_pk ( id: $id ) { - DeletedId: id + deletedIdLong: id } } diff --git a/roles/lib/files/FWO.Api.Client/APIcalls/request/deleteState.graphql b/roles/common/files/fwo-api-calls/request/deleteState.graphql similarity index 100% rename from roles/lib/files/FWO.Api.Client/APIcalls/request/deleteState.graphql rename to roles/common/files/fwo-api-calls/request/deleteState.graphql diff --git a/roles/lib/files/FWO.Api.Client/APIcalls/request/fragments/commentDetails.graphql b/roles/common/files/fwo-api-calls/request/fragments/commentDetails.graphql similarity index 100% rename from roles/lib/files/FWO.Api.Client/APIcalls/request/fragments/commentDetails.graphql rename to roles/common/files/fwo-api-calls/request/fragments/commentDetails.graphql diff --git a/roles/lib/files/FWO.Api.Client/APIcalls/request/fragments/implTaskDetails.graphql b/roles/common/files/fwo-api-calls/request/fragments/implTaskDetails.graphql similarity index 94% rename from roles/lib/files/FWO.Api.Client/APIcalls/request/fragments/implTaskDetails.graphql rename to roles/common/files/fwo-api-calls/request/fragments/implTaskDetails.graphql index 15ebe2b958..96e8c34b9f 100644 --- a/roles/lib/files/FWO.Api.Client/APIcalls/request/fragments/implTaskDetails.graphql +++ b/roles/common/files/fwo-api-calls/request/fragments/implTaskDetails.graphql @@ -33,7 +33,9 @@ fragment implTaskDetails on request_impltask { implementation_task_id implementation_action ip + ip_end port + port_end ip_proto_id network_object_id service_id @@ -41,6 +43,8 @@ fragment implTaskDetails on request_impltask { user_id original_nat_id rule_uid + group_name + name } comments: impltask_comments { comment: comment { diff --git a/roles/common/files/fwo-api-calls/request/fragments/reqElementDetails.graphql b/roles/common/files/fwo-api-calls/request/fragments/reqElementDetails.graphql new file mode 100644 index 0000000000..469e64308c --- /dev/null +++ b/roles/common/files/fwo-api-calls/request/fragments/reqElementDetails.graphql @@ -0,0 +1,19 @@ +fragment reqElementDetails on request_reqelement { + id + task_id + request_action + ip + ip_end + port + port_end + ip_proto_id + network_object_id + service_id + field + user_id + original_nat_id + device_id + rule_uid + group_name + name +} diff --git a/roles/lib/files/FWO.Api.Client/APIcalls/request/fragments/reqTaskDetails.graphql b/roles/common/files/fwo-api-calls/request/fragments/reqTaskDetails.graphql similarity index 85% rename from roles/lib/files/FWO.Api.Client/APIcalls/request/fragments/reqTaskDetails.graphql rename to roles/common/files/fwo-api-calls/request/fragments/reqTaskDetails.graphql index 28bf792708..a649d6e2fd 100644 --- a/roles/lib/files/FWO.Api.Client/APIcalls/request/fragments/reqTaskDetails.graphql +++ b/roles/common/files/fwo-api-calls/request/fragments/reqTaskDetails.graphql @@ -14,8 +14,10 @@ fragment reqTaskDetails on request_reqtask { nw_obj_grp_id user_grp_id reason + additional_info free_text last_recert_date + mgm_id current_handler: uiuser { uiuser_id uuid @@ -30,20 +32,13 @@ fragment reqTaskDetails on request_reqtask { target_begin_date target_end_date devices + on_management: management { + id: mgm_id + name: mgm_name + extMgtData: ext_mgm_data + } elements: elements { - id - task_id - request_action - ip - port - ip_proto_id - network_object_id - service_id - field - user_id - original_nat_id - device_id - rule_uid + ...reqElementDetails } implementation_tasks: impltasks { ...implTaskDetails diff --git a/roles/common/files/fwo-api-calls/request/fragments/reqTaskOverview.graphql b/roles/common/files/fwo-api-calls/request/fragments/reqTaskOverview.graphql new file mode 100644 index 0000000000..f55b9a59e7 --- /dev/null +++ b/roles/common/files/fwo-api-calls/request/fragments/reqTaskOverview.graphql @@ -0,0 +1,39 @@ +fragment reqTaskOverview on request_reqtask { + id + ticket_id + title + task_number + state_id + task_type + request_action + rule_action + rule_tracking + start + stop + reason + additional_info + on_management: management { + id: mgm_id + name: mgm_name + } + implementation_tasks: impltasks { + id + title + task_number + state_id + start + stop + } + request_approvals: approvals { + id + task_id + state_id + date_opened + approval_date + } + comments: reqtask_comments { + comment: comment { + comment_text + } + } +} diff --git a/roles/lib/files/FWO.Api.Client/APIcalls/request/fragments/ticketDetails.graphql b/roles/common/files/fwo-api-calls/request/fragments/ticketDetails.graphql similarity index 83% rename from roles/lib/files/FWO.Api.Client/APIcalls/request/fragments/ticketDetails.graphql rename to roles/common/files/fwo-api-calls/request/fragments/ticketDetails.graphql index ed7d0e85c7..246e7306d3 100644 --- a/roles/lib/files/FWO.Api.Client/APIcalls/request/fragments/ticketDetails.graphql +++ b/roles/common/files/fwo-api-calls/request/fragments/ticketDetails.graphql @@ -7,6 +7,8 @@ fragment ticketDetails on request_ticket { requester: uiuser { uiuser_id uiuser_username + uuid + uiuser_email } requester_dn requester_group @@ -16,7 +18,7 @@ fragment ticketDetails on request_ticket { external_ticket_source ticket_deadline ticket_priority - reqtasks: reqtasks { + reqtasks: reqtasks (order_by: { task_number: asc }){ ...reqTaskDetails } comments: ticket_comments { diff --git a/roles/common/files/fwo-api-calls/request/fragments/ticketDetailsReqTaskOverview.graphql b/roles/common/files/fwo-api-calls/request/fragments/ticketDetailsReqTaskOverview.graphql new file mode 100644 index 0000000000..1e59ef2f06 --- /dev/null +++ b/roles/common/files/fwo-api-calls/request/fragments/ticketDetailsReqTaskOverview.graphql @@ -0,0 +1,29 @@ +fragment ticketDetailsReqTaskOverview on request_ticket { + id + title + date_created + date_completed + state_id + requester: uiuser { + uiuser_id + uiuser_username + uuid + uiuser_email + } + requester_dn + requester_group + tenant_id + reason + external_ticket_id + external_ticket_source + ticket_deadline + ticket_priority + reqtasks: reqtasks { + ...reqTaskOverview + } + comments: ticket_comments { + comment: comment { + ...commentDetails + } + } +} diff --git a/roles/common/files/fwo-api-calls/request/fragments/ticketOverview.graphql b/roles/common/files/fwo-api-calls/request/fragments/ticketOverview.graphql new file mode 100644 index 0000000000..6b2d8f876d --- /dev/null +++ b/roles/common/files/fwo-api-calls/request/fragments/ticketOverview.graphql @@ -0,0 +1,18 @@ +fragment ticketOverview on request_ticket { + id + title + date_created + date_completed + state_id + requester: uiuser { + uiuser_username + } + reason + external_ticket_id + external_ticket_source + ticket_deadline + ticket_priority + reqtasks: reqtasks { + ...reqTaskOverview + } +} diff --git a/roles/lib/files/FWO.Api.Client/APIcalls/request/getActions.graphql b/roles/common/files/fwo-api-calls/request/getActions.graphql similarity index 100% rename from roles/lib/files/FWO.Api.Client/APIcalls/request/getActions.graphql rename to roles/common/files/fwo-api-calls/request/getActions.graphql diff --git a/roles/common/files/fwo-api-calls/request/getExtStates.graphql b/roles/common/files/fwo-api-calls/request/getExtStates.graphql new file mode 100644 index 0000000000..8d458d5181 --- /dev/null +++ b/roles/common/files/fwo-api-calls/request/getExtStates.graphql @@ -0,0 +1,8 @@ + +query getExtStates { + request_ext_state (order_by: { id: asc }){ + id + name + state_id + } +} diff --git a/roles/common/files/fwo-api-calls/request/getFullTickets.graphql b/roles/common/files/fwo-api-calls/request/getFullTickets.graphql new file mode 100644 index 0000000000..cbd9a97082 --- /dev/null +++ b/roles/common/files/fwo-api-calls/request/getFullTickets.graphql @@ -0,0 +1,5 @@ +query getFullTickets($fromState: Int!, $toState: Int!) { + request_ticket(where: {_or: [{_and: [{state_id: {_gte: $fromState}}, {state_id: {_lt: $toState}}]}, {reqtasks: {_and: [{state_id: {_gte: $fromState}}, {state_id: {_lt: $toState}}]}}]}, order_by: {id: desc}) { + ...ticketDetails + } +} diff --git a/roles/common/files/fwo-api-calls/request/getRequestTasksByIds.graphql b/roles/common/files/fwo-api-calls/request/getRequestTasksByIds.graphql new file mode 100644 index 0000000000..e878763902 --- /dev/null +++ b/roles/common/files/fwo-api-calls/request/getRequestTasksByIds.graphql @@ -0,0 +1,5 @@ +query getRequestTasksByIds($task_ids: [bigint!]) { + request_tasks(where: { id: { _in: $task_ids } }, order_by: { id: asc }) { + ...reqTaskDetails + } +} diff --git a/roles/lib/files/FWO.Api.Client/APIcalls/request/getStates.graphql b/roles/common/files/fwo-api-calls/request/getStates.graphql similarity index 94% rename from roles/lib/files/FWO.Api.Client/APIcalls/request/getStates.graphql rename to roles/common/files/fwo-api-calls/request/getStates.graphql index a4e32f6dbf..6ec5ed61d6 100644 --- a/roles/lib/files/FWO.Api.Client/APIcalls/request/getStates.graphql +++ b/roles/common/files/fwo-api-calls/request/getStates.graphql @@ -3,6 +3,7 @@ query getStates { state_list: request_state (order_by: { id: asc }){ id name + automatic_only actions: state_actions { action: action { id diff --git a/roles/lib/files/FWO.Api.Client/APIcalls/request/getTicketById.graphql b/roles/common/files/fwo-api-calls/request/getTicketById.graphql similarity index 100% rename from roles/lib/files/FWO.Api.Client/APIcalls/request/getTicketById.graphql rename to roles/common/files/fwo-api-calls/request/getTicketById.graphql diff --git a/roles/common/files/fwo-api-calls/request/getTickets.graphql b/roles/common/files/fwo-api-calls/request/getTickets.graphql new file mode 100644 index 0000000000..ce6bc2c7bc --- /dev/null +++ b/roles/common/files/fwo-api-calls/request/getTickets.graphql @@ -0,0 +1,5 @@ +query getTickets($fromState: Int!, $toState: Int!) { + request_ticket(where: {_or: [{_and: [{state_id: {_gte: $fromState}}, {state_id: {_lt: $toState}}]}, {reqtasks: {_and: [{state_id: {_gte: $fromState}}, {state_id: {_lt: $toState}}]}}]}, order_by: {id: desc}) { + ...ticketDetailsReqTaskOverview + } +} diff --git a/roles/common/files/fwo-api-calls/request/getTicketsByParameters.graphql b/roles/common/files/fwo-api-calls/request/getTicketsByParameters.graphql new file mode 100644 index 0000000000..908f94b18a --- /dev/null +++ b/roles/common/files/fwo-api-calls/request/getTicketsByParameters.graphql @@ -0,0 +1,44 @@ +query getTicketsByParameters($cutOffDate: timestamp, $taskType: String, $fromState: Int!, $toState: Int!) { + request_ticket(where: { + _and: [ + { + date_created: { _lte: $cutOffDate } + }, + { + reqtasks: { + _and: [ + {task_type: {_eq: $taskType}} + {state_id: {_gte: $fromState}}, + {state_id: {_lt: $toState}} + ] + } + } + ] + }, order_by: {id: desc}) { + id + title + date_created + state_id + requester: uiuser { + uiuser_id + uiuser_username + uuid + uiuser_email + } + reqtasks: reqtasks { + id + task_number + state_id + title + task_type + additional_info + owners: reqtask_owners { + owner: owner { + id + name + app_id_external + } + } + } + } +} diff --git a/roles/lib/files/FWO.Api.Client/APIcalls/request/newAction.graphql b/roles/common/files/fwo-api-calls/request/newAction.graphql similarity index 100% rename from roles/lib/files/FWO.Api.Client/APIcalls/request/newAction.graphql rename to roles/common/files/fwo-api-calls/request/newAction.graphql diff --git a/roles/lib/files/FWO.Api.Client/APIcalls/request/newApproval.graphql b/roles/common/files/fwo-api-calls/request/newApproval.graphql similarity index 95% rename from roles/lib/files/FWO.Api.Client/APIcalls/request/newApproval.graphql rename to roles/common/files/fwo-api-calls/request/newApproval.graphql index 4702d33164..8ecce62c9d 100644 --- a/roles/lib/files/FWO.Api.Client/APIcalls/request/newApproval.graphql +++ b/roles/common/files/fwo-api-calls/request/newApproval.graphql @@ -15,7 +15,7 @@ mutation newApproval( initial_approval: $initialApproval }) { returning { - newId: id + newIdLong: id } } } diff --git a/roles/lib/files/FWO.Api.Client/APIcalls/request/newComment.graphql b/roles/common/files/fwo-api-calls/request/newComment.graphql similarity index 93% rename from roles/lib/files/FWO.Api.Client/APIcalls/request/newComment.graphql rename to roles/common/files/fwo-api-calls/request/newComment.graphql index 7b8ef00f74..162e85093e 100644 --- a/roles/lib/files/FWO.Api.Client/APIcalls/request/newComment.graphql +++ b/roles/common/files/fwo-api-calls/request/newComment.graphql @@ -13,7 +13,7 @@ mutation newComment( comment_text: $text }) { returning { - newId: id + newIdLong: id } } } diff --git a/roles/lib/files/FWO.Api.Client/APIcalls/request/newImplementationElement.graphql b/roles/common/files/fwo-api-calls/request/newImplementationElement.graphql similarity index 79% rename from roles/lib/files/FWO.Api.Client/APIcalls/request/newImplementationElement.graphql rename to roles/common/files/fwo-api-calls/request/newImplementationElement.graphql index 84e42014f1..1f1674dfff 100644 --- a/roles/lib/files/FWO.Api.Client/APIcalls/request/newImplementationElement.graphql +++ b/roles/common/files/fwo-api-calls/request/newImplementationElement.graphql @@ -2,7 +2,9 @@ mutation newImplementationElement( $implementationAction: action_enum $implTaskId: bigint! $ip: cidr + $ipEnd: cidr $port: Int + $portEnd: Int $proto: Int $networkObjId: bigint $serviceId: bigint @@ -10,12 +12,16 @@ mutation newImplementationElement( $userId: bigint $originalNatId: bigint $ruleUid: String + $groupName: String + $name: String ) { insert_request_implelement(objects: { implementation_action: $implementationAction implementation_task_id: $implTaskId ip: $ip + ip_end: $ipEnd port: $port + port_end: $portEnd ip_proto_id: $proto network_object_id: $networkObjId service_id: $serviceId @@ -23,9 +29,11 @@ mutation newImplementationElement( user_id: $userId original_nat_id: $originalNatId rule_uid: $ruleUid + group_name: $groupName + name: $name }) { returning { - newId: id + newIdLong: id } } } diff --git a/roles/lib/files/FWO.Api.Client/APIcalls/request/newImplementationTask.graphql b/roles/common/files/fwo-api-calls/request/newImplementationTask.graphql similarity index 97% rename from roles/lib/files/FWO.Api.Client/APIcalls/request/newImplementationTask.graphql rename to roles/common/files/fwo-api-calls/request/newImplementationTask.graphql index 256e882dfd..995acd26a3 100644 --- a/roles/lib/files/FWO.Api.Client/APIcalls/request/newImplementationTask.graphql +++ b/roles/common/files/fwo-api-calls/request/newImplementationTask.graphql @@ -29,7 +29,7 @@ mutation newImplementationTask( free_text: $freeText }) { returning { - newId: id + newIdLong: id } } } diff --git a/roles/lib/files/FWO.Api.Client/APIcalls/request/newRequestElement.graphql b/roles/common/files/fwo-api-calls/request/newRequestElement.graphql similarity index 78% rename from roles/lib/files/FWO.Api.Client/APIcalls/request/newRequestElement.graphql rename to roles/common/files/fwo-api-calls/request/newRequestElement.graphql index 73f48e3ef6..760d8b9e44 100644 --- a/roles/lib/files/FWO.Api.Client/APIcalls/request/newRequestElement.graphql +++ b/roles/common/files/fwo-api-calls/request/newRequestElement.graphql @@ -2,7 +2,9 @@ mutation newRequestElement( $requestAction: action_enum $taskId: bigint! $ip: cidr + $ipEnd: cidr $port: Int + $portEnd: Int $proto: Int $networkObjId: bigint $serviceId: bigint @@ -11,12 +13,16 @@ mutation newRequestElement( $originalNatId: bigint $deviceId: Int $ruleUid: String + $groupName: String + $name: String ) { insert_request_reqelement(objects: { request_action: $requestAction task_id: $taskId ip: $ip + ip_end: $ipEnd port: $port + port_end: $portEnd ip_proto_id: $proto network_object_id: $networkObjId service_id: $serviceId @@ -25,9 +31,11 @@ mutation newRequestElement( original_nat_id: $originalNatId device_id: $deviceId rule_uid: $ruleUid + group_name: $groupName + name: $name }) { returning { - newId: id + newIdLong: id } } } diff --git a/roles/lib/files/FWO.Api.Client/APIcalls/request/newRequestTask.graphql b/roles/common/files/fwo-api-calls/request/newRequestTask.graphql similarity index 83% rename from roles/lib/files/FWO.Api.Client/APIcalls/request/newRequestTask.graphql rename to roles/common/files/fwo-api-calls/request/newRequestTask.graphql index 1b7f2990bb..a5fb879424 100644 --- a/roles/lib/files/FWO.Api.Client/APIcalls/request/newRequestTask.graphql +++ b/roles/common/files/fwo-api-calls/request/newRequestTask.graphql @@ -10,7 +10,9 @@ mutation newRequestTask( $validFrom: timestamp $validTo: timestamp $reason: String + $additionalInfo: String $freeText: String + $managementId: Int ) { insert_request_reqtask(objects: { title: $title @@ -24,10 +26,12 @@ mutation newRequestTask( target_begin_date: $validFrom target_end_date: $validTo reason: $reason + additional_info: $additionalInfo free_text: $freeText + mgm_id: $managementId }) { returning { - newId: id + newIdLong: id } } } diff --git a/roles/lib/files/FWO.Api.Client/APIcalls/request/newTicket.graphql b/roles/common/files/fwo-api-calls/request/newTicket.graphql similarity index 95% rename from roles/lib/files/FWO.Api.Client/APIcalls/request/newTicket.graphql rename to roles/common/files/fwo-api-calls/request/newTicket.graphql index b581347186..1d4f9468b0 100644 --- a/roles/lib/files/FWO.Api.Client/APIcalls/request/newTicket.graphql +++ b/roles/common/files/fwo-api-calls/request/newTicket.graphql @@ -17,7 +17,7 @@ mutation newTicket( reqtasks: $requestTasks }) { returning { - newId: id + newIdLong: id } } } \ No newline at end of file diff --git a/roles/common/files/fwo-api-calls/request/removeExtState.graphql b/roles/common/files/fwo-api-calls/request/removeExtState.graphql new file mode 100644 index 0000000000..2744540d75 --- /dev/null +++ b/roles/common/files/fwo-api-calls/request/removeExtState.graphql @@ -0,0 +1,7 @@ +mutation removeExtState($id: Int!) { + delete_request_ext_state_by_pk ( + id: $id + ) { + deletedId: id + } +} diff --git a/roles/common/files/fwo-api-calls/request/removeOwnerFromReqTask.graphql b/roles/common/files/fwo-api-calls/request/removeOwnerFromReqTask.graphql new file mode 100644 index 0000000000..2043a191dd --- /dev/null +++ b/roles/common/files/fwo-api-calls/request/removeOwnerFromReqTask.graphql @@ -0,0 +1,8 @@ +mutation removeOwnerFromReqTask( + $reqTaskId: bigint + $ownerId: Int! + ) { + delete_reqtask_owner(where: {owner_id: {_eq: $ownerId}, reqtask_id: {_eq: $reqTaskId}}) { + affected_rows + } +} diff --git a/roles/lib/files/FWO.Api.Client/APIcalls/request/removeStateAction.graphql b/roles/common/files/fwo-api-calls/request/removeStateAction.graphql similarity index 100% rename from roles/lib/files/FWO.Api.Client/APIcalls/request/removeStateAction.graphql rename to roles/common/files/fwo-api-calls/request/removeStateAction.graphql diff --git a/roles/common/files/fwo-api-calls/request/subscribeTaskChanges.graphql b/roles/common/files/fwo-api-calls/request/subscribeTaskChanges.graphql new file mode 100644 index 0000000000..3ba20fbe82 --- /dev/null +++ b/roles/common/files/fwo-api-calls/request/subscribeTaskChanges.graphql @@ -0,0 +1,22 @@ +subscription subscribeTaskChanges ($id: bigint!){ + request_reqtask(where: { id: {_eq: $id} }, limit:1) { + id + title + task_number + state_id + task_type + additional_info + on_management: management { + id: mgm_id + name: mgm_name + } + elements: elements { + ...reqElementDetails + } + comments: reqtask_comments { + comment: comment { + comment_text + } + } + } +} diff --git a/roles/common/files/fwo-api-calls/request/subscribeTicketStateChanges.graphql b/roles/common/files/fwo-api-calls/request/subscribeTicketStateChanges.graphql new file mode 100644 index 0000000000..a34b54a73e --- /dev/null +++ b/roles/common/files/fwo-api-calls/request/subscribeTicketStateChanges.graphql @@ -0,0 +1,12 @@ +subscription subscribeTicketStateChanges ($id: bigint!){ + request_ticket(where: { id: {_eq: $id} }, limit:1) { + id + date_created + date_completed + state_id + requester: uiuser { + uiuser_id + uiuser_username + } + } +} diff --git a/roles/lib/files/FWO.Api.Client/APIcalls/request/updateAction.graphql b/roles/common/files/fwo-api-calls/request/updateAction.graphql similarity index 96% rename from roles/lib/files/FWO.Api.Client/APIcalls/request/updateAction.graphql rename to roles/common/files/fwo-api-calls/request/updateAction.graphql index 68a2176f4a..06d5b76396 100644 --- a/roles/lib/files/FWO.Api.Client/APIcalls/request/updateAction.graphql +++ b/roles/common/files/fwo-api-calls/request/updateAction.graphql @@ -21,6 +21,6 @@ mutation updateAction( button_text: $buttonText external_parameters: $externalParameters }) { - UpdatedId: id + updatedId: id } } diff --git a/roles/lib/files/FWO.Api.Client/APIcalls/request/updateApproval.graphql b/roles/common/files/fwo-api-calls/request/updateApproval.graphql similarity index 93% rename from roles/lib/files/FWO.Api.Client/APIcalls/request/updateApproval.graphql rename to roles/common/files/fwo-api-calls/request/updateApproval.graphql index 384e76b743..a8ede02703 100644 --- a/roles/lib/files/FWO.Api.Client/APIcalls/request/updateApproval.graphql +++ b/roles/common/files/fwo-api-calls/request/updateApproval.graphql @@ -13,6 +13,6 @@ mutation updateApproval( approver: $approver assigned_group: $assignedGroup }) { - UpdatedId: id + UpdatedIdLong: id } } diff --git a/roles/lib/files/FWO.Api.Client/APIcalls/request/updateImplementationElement.graphql b/roles/common/files/fwo-api-calls/request/updateImplementationElement.graphql similarity index 79% rename from roles/lib/files/FWO.Api.Client/APIcalls/request/updateImplementationElement.graphql rename to roles/common/files/fwo-api-calls/request/updateImplementationElement.graphql index 1dc947bcce..fc2f71d5a8 100644 --- a/roles/lib/files/FWO.Api.Client/APIcalls/request/updateImplementationElement.graphql +++ b/roles/common/files/fwo-api-calls/request/updateImplementationElement.graphql @@ -3,7 +3,9 @@ mutation updateImplementationElement( $implementationAction: action_enum $implTaskId: bigint! $ip: cidr + $ipEnd: cidr $port: Int + $portEnd: Int $proto: Int $networkObjId: bigint $serviceId: bigint @@ -11,6 +13,8 @@ mutation updateImplementationElement( $userId: bigint $originalNatId: bigint $ruleUid: String + $groupName: String + $name: String ) { update_request_implelement_by_pk( pk_columns: { id: $id } @@ -18,7 +22,9 @@ mutation updateImplementationElement( implementation_action: $implementationAction implementation_task_id: $implTaskId ip: $ip + ip_end: $ipEnd port: $port + port_end: $portEnd ip_proto_id: $proto network_object_id: $networkObjId service_id: $serviceId @@ -26,7 +32,9 @@ mutation updateImplementationElement( user_id: $userId original_nat_id: $originalNatId rule_uid: $ruleUid + group_name: $groupName + name: $name }) { - UpdatedId: id + UpdatedIdLong: id } } diff --git a/roles/lib/files/FWO.Api.Client/APIcalls/request/updateImplementationTask.graphql b/roles/common/files/fwo-api-calls/request/updateImplementationTask.graphql similarity index 91% rename from roles/lib/files/FWO.Api.Client/APIcalls/request/updateImplementationTask.graphql rename to roles/common/files/fwo-api-calls/request/updateImplementationTask.graphql index 2d5aef6568..c3a565a41e 100644 --- a/roles/lib/files/FWO.Api.Client/APIcalls/request/updateImplementationTask.graphql +++ b/roles/common/files/fwo-api-calls/request/updateImplementationTask.graphql @@ -4,7 +4,6 @@ mutation updateImplementationTask( $reqTaskId: bigint! $implIaskNumber: Int $state: Int - $taskType: String! $device: Int $implAction: action_enum $ruleAction: Int @@ -21,7 +20,6 @@ mutation updateImplementationTask( reqtask_id: $reqTaskId task_number: $implIaskNumber state_id: $state - task_type: $taskType device_id: $device implementation_action: $implAction rule_action: $ruleAction @@ -31,6 +29,6 @@ mutation updateImplementationTask( target_end_date: $validTo free_text: $freeText }) { - UpdatedId: id + UpdatedIdLong: id } } diff --git a/roles/lib/files/FWO.Api.Client/APIcalls/request/updateImplementationTaskState.graphql b/roles/common/files/fwo-api-calls/request/updateImplementationTaskState.graphql similarity index 95% rename from roles/lib/files/FWO.Api.Client/APIcalls/request/updateImplementationTaskState.graphql rename to roles/common/files/fwo-api-calls/request/updateImplementationTaskState.graphql index ecba2a0c67..0bc7180b75 100644 --- a/roles/lib/files/FWO.Api.Client/APIcalls/request/updateImplementationTaskState.graphql +++ b/roles/common/files/fwo-api-calls/request/updateImplementationTaskState.graphql @@ -17,6 +17,6 @@ mutation updateImplementationTaskState( recent_handler: $recentHandler assigned_group: $assignedGroup }) { - UpdatedId: id + UpdatedIdLong: id } } diff --git a/roles/lib/files/FWO.Api.Client/APIcalls/request/updateRequestElement.graphql b/roles/common/files/fwo-api-calls/request/updateRequestElement.graphql similarity index 79% rename from roles/lib/files/FWO.Api.Client/APIcalls/request/updateRequestElement.graphql rename to roles/common/files/fwo-api-calls/request/updateRequestElement.graphql index b268d975df..697409980e 100644 --- a/roles/lib/files/FWO.Api.Client/APIcalls/request/updateRequestElement.graphql +++ b/roles/common/files/fwo-api-calls/request/updateRequestElement.graphql @@ -3,7 +3,9 @@ mutation updateRequestElement( $requestAction: action_enum $taskId: bigint! $ip: cidr + $ipEnd: cidr $port: Int + $portEnd: Int $proto: Int $networkObjId: bigint $serviceId: bigint @@ -12,6 +14,8 @@ mutation updateRequestElement( $originalNatId: bigint $deviceId: Int $ruleUid: String + $groupName: String + $name: String ) { update_request_reqelement_by_pk( pk_columns: { id: $id } @@ -19,7 +23,9 @@ mutation updateRequestElement( request_action: $requestAction task_id: $taskId ip: $ip + ip_end: $ipEnd port: $port + port_end: $portEnd ip_proto_id: $proto network_object_id: $networkObjId service_id: $serviceId @@ -28,7 +34,9 @@ mutation updateRequestElement( original_nat_id: $originalNatId device_id: $deviceId rule_uid: $ruleUid + group_name: $groupName + name: $name }) { - UpdatedId: id + UpdatedIdLong: id } } diff --git a/roles/lib/files/FWO.Api.Client/APIcalls/request/updateRequestTask.graphql b/roles/common/files/fwo-api-calls/request/updateRequestTask.graphql similarity index 83% rename from roles/lib/files/FWO.Api.Client/APIcalls/request/updateRequestTask.graphql rename to roles/common/files/fwo-api-calls/request/updateRequestTask.graphql index dc0a11d707..9f647f9400 100644 --- a/roles/lib/files/FWO.Api.Client/APIcalls/request/updateRequestTask.graphql +++ b/roles/common/files/fwo-api-calls/request/updateRequestTask.graphql @@ -3,15 +3,16 @@ mutation updateRequestTask( $title: String! $taskNumber: Int $state: Int - $taskType: String! $requestAction: action_enum $ruleAction: Int $tracking: Int $validFrom: timestamp $validTo: timestamp $reason: String + $additionalInfo: String $freeText: String $devices: String + $managementId: Int ) { update_request_reqtask_by_pk( pk_columns: { id: $id } @@ -19,16 +20,17 @@ mutation updateRequestTask( title: $title task_number: $taskNumber state_id: $state - task_type: $taskType request_action: $requestAction rule_action: $ruleAction rule_tracking: $tracking target_begin_date: $validFrom target_end_date: $validTo reason: $reason + additional_info: $additionalInfo free_text: $freeText devices: $devices + mgm_id: $managementId }) { - UpdatedId: id + UpdatedIdLong: id } } diff --git a/roles/common/files/fwo-api-calls/request/updateRequestTaskAdditionalInfo.graphql b/roles/common/files/fwo-api-calls/request/updateRequestTaskAdditionalInfo.graphql new file mode 100644 index 0000000000..cee76c4cdc --- /dev/null +++ b/roles/common/files/fwo-api-calls/request/updateRequestTaskAdditionalInfo.graphql @@ -0,0 +1,12 @@ +mutation updateRequestTaskAdditionalInfo( + $id: bigint! + $additionalInfo: String + ) { + update_request_reqtask_by_pk( + pk_columns: { id: $id } + _set: { + additional_info: $additionalInfo + }) { + UpdatedIdLong: id + } +} diff --git a/roles/lib/files/FWO.Api.Client/APIcalls/request/updateRequestTaskState.graphql b/roles/common/files/fwo-api-calls/request/updateRequestTaskState.graphql similarity index 94% rename from roles/lib/files/FWO.Api.Client/APIcalls/request/updateRequestTaskState.graphql rename to roles/common/files/fwo-api-calls/request/updateRequestTaskState.graphql index f0e2d6cd9a..152e94100b 100644 --- a/roles/lib/files/FWO.Api.Client/APIcalls/request/updateRequestTaskState.graphql +++ b/roles/common/files/fwo-api-calls/request/updateRequestTaskState.graphql @@ -17,6 +17,6 @@ mutation updateRequestTaskState( recent_handler: $recentHandler assigned_group: $assignedGroup }) { - UpdatedId: id + UpdatedIdLong: id } } diff --git a/roles/lib/files/FWO.Api.Client/APIcalls/request/updateTicket.graphql b/roles/common/files/fwo-api-calls/request/updateTicket.graphql similarity index 93% rename from roles/lib/files/FWO.Api.Client/APIcalls/request/updateTicket.graphql rename to roles/common/files/fwo-api-calls/request/updateTicket.graphql index 6e12fdfd72..725141482d 100644 --- a/roles/lib/files/FWO.Api.Client/APIcalls/request/updateTicket.graphql +++ b/roles/common/files/fwo-api-calls/request/updateTicket.graphql @@ -15,6 +15,6 @@ mutation updateTicket( ticket_deadline: $deadline ticket_priority: $priority }) { - UpdatedId: id + UpdatedIdLong: id } } diff --git a/roles/lib/files/FWO.Api.Client/APIcalls/request/updateTicketState.graphql b/roles/common/files/fwo-api-calls/request/updateTicketState.graphql similarity index 93% rename from roles/lib/files/FWO.Api.Client/APIcalls/request/updateTicketState.graphql rename to roles/common/files/fwo-api-calls/request/updateTicketState.graphql index 0fdbf94e7c..0a6b8dfc61 100644 --- a/roles/lib/files/FWO.Api.Client/APIcalls/request/updateTicketState.graphql +++ b/roles/common/files/fwo-api-calls/request/updateTicketState.graphql @@ -13,6 +13,6 @@ mutation updateTicketState( ticket_deadline: $deadline ticket_priority: $priority }) { - UpdatedId: id + UpdatedIdLong: id } } diff --git a/roles/common/files/fwo-api-calls/request/upsertState.graphql b/roles/common/files/fwo-api-calls/request/upsertState.graphql new file mode 100644 index 0000000000..2fa4a11c83 --- /dev/null +++ b/roles/common/files/fwo-api-calls/request/upsertState.graphql @@ -0,0 +1,17 @@ +mutation upsertState($id: Int!, $name: String!, $automaticOnly: Boolean!) { + insert_request_state( + objects: { + id: $id + name: $name + automatic_only: $automaticOnly + }, + on_conflict: { + constraint: state_pkey , + update_columns: [name, automatic_only] + } + ) { + returning { + id: id + } + } +} diff --git a/roles/common/files/fwo-api-calls/rule/countActiveRules.graphql b/roles/common/files/fwo-api-calls/rule/countActiveRules.graphql new file mode 100644 index 0000000000..230bb14cdb --- /dev/null +++ b/roles/common/files/fwo-api-calls/rule/countActiveRules.graphql @@ -0,0 +1,7 @@ +query countActiveRules($mgm_ids: [Int!]) { + rule_aggregate(where: { mgm_id: { _in: $mgm_ids } removed: { _is_null: true } }) { + aggregate { + count + } + } +} diff --git a/roles/common/files/fwo-api-calls/rule/countRules.graphql b/roles/common/files/fwo-api-calls/rule/countRules.graphql new file mode 100644 index 0000000000..48a62b7758 --- /dev/null +++ b/roles/common/files/fwo-api-calls/rule/countRules.graphql @@ -0,0 +1,5 @@ + query countRules($mgm_ids: [Int!]) { + rule_aggregate(where: { mgm_id: { _in: $mgm_ids } }) { + aggregate { count } + } + } diff --git a/roles/common/files/fwo-api-calls/rule/fragments/natRuleDetails.graphql b/roles/common/files/fwo-api-calls/rule/fragments/natRuleDetails.graphql new file mode 100644 index 0000000000..8528583d77 --- /dev/null +++ b/roles/common/files/fwo-api-calls/rule/fragments/natRuleDetails.graphql @@ -0,0 +1,53 @@ +fragment natRuleDetails on rule { + ...ruleDetails + translate: ruleByXlateRule { + rule_src + rule_src_refs + rule_src_neg + rule_dst + rule_dst_refs + rule_dst_neg + rule_svc + rule_svc_refs + rule_svc_neg + rule_froms(where: { + rf_create: { _lte: $import_id_end } + _or: [ + { removed: { _is_null: true } } + { removed: { _gt: $import_id_start } } + ] + }, order_by: { object: { obj_name: asc } }) { + usr { + ...userDetails + } + object { + ...networkObjectDetails + } + } + rule_tos(where: { + rt_create: { _lte: $import_id_end } + _or: [ + { removed: { _is_null: true } } + { removed: { _gt: $import_id_start } } + ] + }, order_by: { object: { obj_name: asc } }) { + usr { + ...userDetails + } + object { + ...networkObjectDetails + } + } + rule_services(where: { + rs_create: { _lte: $import_id_end } + _or: [ + { removed: { _is_null: true } } + { removed: { _gt: $import_id_start } } + ] + }, order_by: { service: { svc_name: asc } }) { + service { + ...networkServiceDetails + } + } + } +} \ No newline at end of file diff --git a/roles/common/files/fwo-api-calls/rule/fragments/natRuleDetailsForReport.graphql b/roles/common/files/fwo-api-calls/rule/fragments/natRuleDetailsForReport.graphql new file mode 100644 index 0000000000..bf4c99cdc6 --- /dev/null +++ b/roles/common/files/fwo-api-calls/rule/fragments/natRuleDetailsForReport.graphql @@ -0,0 +1,53 @@ +fragment natRuleDetails on rule { + ...ruleDetails + translate: ruleByXlateRule { + rule_src + rule_src_refs + rule_src_neg + rule_dst + rule_dst_refs + rule_dst_neg + rule_svc + rule_svc_refs + rule_svc_neg + rule_froms(where: { + rf_create: { _lte: $import_id_end } + _or: [ + { removed: { _is_null: true } } + { removed: { _gt: $import_id_start } } + ] + }, order_by: { object: { obj_name: asc } }) { + usr { + ...userDetails + } + object { + ...networkObjectDetails + } + } + rule_tos(where: { + rt_create: { _lte: $import_id_end } + _or: [ + { removed: { _is_null: true } } + { removed: { _gt: $import_id_start } } + ] + }, order_by: { object: { obj_name: asc } }) { + usr { + ...userDetails + } + object { + ...networkObjectDetails + } + } + rule_services(where: { + rs_create: { _lte: $import_id_end } + _or: [ + { removed: { _is_null: true } } + { removed: { _gt: $import_id_start } } + ] + }, order_by: { service: { svc_name: asc } }) { + service { + ...networkServiceDetails + } + } + } +} diff --git a/roles/common/files/fwo-api-calls/rule/fragments/natRuleOverview.graphql b/roles/common/files/fwo-api-calls/rule/fragments/natRuleOverview.graphql new file mode 100644 index 0000000000..248d93a1d4 --- /dev/null +++ b/roles/common/files/fwo-api-calls/rule/fragments/natRuleOverview.graphql @@ -0,0 +1,53 @@ +fragment natRuleOverview on rule { + ...ruleOverview + translate: ruleByXlateRule { + rule_src + rule_src_refs + rule_src_neg + rule_dst + rule_dst_refs + rule_dst_neg + rule_svc + rule_svc_refs + rule_svc_neg + rule_froms(where: { + rf_create: { _lte: $import_id_end } + _or: [ + { removed: { _is_null: true } } + { removed: { _gt: $import_id_start } } + ] + }, order_by: { object: { obj_name: asc } }) { + usr { + ...userOverview + } + object { + ...networkObjectOverview + } + } + rule_tos(where: { + rt_create: { _lte: $import_id_end } + _or: [ + { removed: { _is_null: true } } + { removed: { _gt: $import_id_start } } + ] + }, order_by: { object: { obj_name: asc } }) { + usr { + ...userOverview + } + object { + ...networkObjectOverview + } + } + rule_services(where: { + rs_create: { _lte: $import_id_end } + _or: [ + { removed: { _is_null: true } } + { removed: { _gt: $import_id_start } } + ] + }, order_by: { service: { svc_name: asc } }) { + service { + ...networkServiceOverview + } + } + } +} diff --git a/roles/common/files/fwo-api-calls/rule/fragments/ruleDetails.graphql b/roles/common/files/fwo-api-calls/rule/fragments/ruleDetails.graphql new file mode 100644 index 0000000000..383099fadd --- /dev/null +++ b/roles/common/files/fwo-api-calls/rule/fragments/ruleDetails.graphql @@ -0,0 +1,106 @@ +fragment ruleDetails on rule { + rule_id + rule_uid + mgm_id + dev_id + rule_action + rulebase_id + section_header: rule_head_text + rule_comment + rule_track + rule_disabled + rule_from_zones { + zone { + zone_name + zone_id + } + } + active + rule_create + rule_last_seen + importControlByRuleLastSeen { + control_id + start_time + } + rule_src_neg + rule_dst_neg + rule_svc_neg + rule_num_numeric + rule_name + rule_installon + rule_custom_fields + rule_time + rule_times(where: { + created: { _lte: $import_id_end } + _or: [ + { removed: { _is_null: true } } + { removed: { _gt: $import_id_start } } + ] + }, order_by:{ time_object: { time_obj_name: asc } }) { + rule_time_id + rule_id + time_obj_id + created + removed + time_object { + time_obj_id + time_obj_name + time_obj_uid + start_time + end_time + created + } + } + access_rule + nat_rule + xlate_rule + rule_froms(where: { + active: { _eq: $active } + rf_create: { _lte: $import_id_end } + _or: [ + { removed: { _is_null: true } } + { removed: { _gt: $import_id_start } } + ] + }, order_by:{ object: { obj_name: asc } }) { + usr { + ...userDetails + } + object { + ...networkObjectDetails + } + } + rule_to_zones { + zone { + zone_name + zone_id + } + } + rule_tos(where: { + active: { _eq: $active } + rt_create: { _lte: $import_id_end } + _or: [ + { removed: { _is_null: true } } + { removed: { _gt: $import_id_start } } + ] + }, order_by:{ object: { obj_name: asc } }) { + usr { + ...userDetails + } + object { + ...networkObjectDetails + } + } + rule_svc + rule_services(where: { + active: { _eq: $active } + rs_create: { _lte: $import_id_end } + _or: [ + { removed: { _is_null: true } } + { removed: { _gt: $import_id_start } } + ] + }, order_by:{ service: { svc_name: asc } }) { + service { + ...networkServiceDetails + } + } +} diff --git a/roles/common/files/fwo-api-calls/rule/fragments/ruleDetailsChangesNew.graphql b/roles/common/files/fwo-api-calls/rule/fragments/ruleDetailsChangesNew.graphql new file mode 100644 index 0000000000..72c507ef6b --- /dev/null +++ b/roles/common/files/fwo-api-calls/rule/fragments/ruleDetailsChangesNew.graphql @@ -0,0 +1,88 @@ +fragment ruleDetailsChangesNew on rule { + rule_id + rule_uid + dev_id + rule_action + section_header: rule_head_text + rule_comment + rule_track + rule_disabled + rule_from_zones { + zone { + zone_name + zone_id + } + } + rule_metadatum { + rule_metadata_id + rule_created + rule_first_hit + rule_last_hit + created_import { start_time } + } + active + rule_create + rule_last_seen + rule_src_neg + rule_dst_neg + rule_svc_neg + rule_num_numeric + rule_name + access_rule + nat_rule + xlate_rule + rule_froms(where: { + active: { _eq: $active } + rf_create: { _lte: $import_id_new } + _or: [ + { removed: { _is_null: true } } + { removed: { _gt:$import_id_new } } + ] + }, order_by: { object: { obj_name: asc } }) { + usr { + ...userDetailsChangesNew + } + object { + ...networkObjectDetailsChangesNew + } + } + rule_to_zones { + zone { + zone_name + zone_id + } + } + rule_tos(where: { + active: { _eq: $active } + rt_create: { _lte: $import_id_new } + _or: [ + { removed: { _is_null: true } } + { removed: { _gt:$import_id_new } } + ] + }, order_by: { object: { obj_name: asc } }) { + usr { + ...userDetailsChangesNew + } + object { + ...networkObjectDetailsChangesNew + } + } + rule_services(where: { + active: { _eq: $active } + rs_create: { _lte: $import_id_new } + _or: [ + { removed: { _is_null: true } } + { removed: { _gt:$import_id_new } } + ] + }, order_by: { service: { svc_name: asc } }) { + service { + ...networkServiceDetailsChangesNew + } + } + rule_enforced_on_gateways(order_by:{ device: { dev_name: asc } }) { + device { + id: dev_id + name: dev_name + } + } +} diff --git a/roles/common/files/fwo-api-calls/rule/fragments/ruleDetailsChangesOld.graphql b/roles/common/files/fwo-api-calls/rule/fragments/ruleDetailsChangesOld.graphql new file mode 100644 index 0000000000..a562b0b36d --- /dev/null +++ b/roles/common/files/fwo-api-calls/rule/fragments/ruleDetailsChangesOld.graphql @@ -0,0 +1,88 @@ +fragment ruleDetailsChangesOld on rule { + rule_id + rule_uid + dev_id + rule_action + section_header: rule_head_text + rule_comment + rule_track + rule_disabled + rule_from_zones { + zone { + zone_name + zone_id + } + } + rule_metadatum { + rule_metadata_id + rule_created + rule_first_hit + rule_last_hit + created_import { start_time } + } + active + rule_create + rule_last_seen + rule_src_neg + rule_dst_neg + rule_svc_neg + rule_num_numeric + rule_name + access_rule + nat_rule + xlate_rule + rule_froms(where: { + active: { _eq: $active } + rf_create: { _lte: $import_id_old } + _or: [ + { removed: { _is_null: true } } + { removed: { _gt:$import_id_old } } + ] + }, order_by: { object: { obj_name: asc } }) { + usr { + ...userDetailsChangesOld + } + object { + ...networkObjectDetailsChangesOld + } + } + rule_to_zones { + zone { + zone_name + zone_id + } + } + rule_tos(where: { + active: { _eq: $active } + rt_create: { _lte: $import_id_old } + _or: [ + { removed: { _is_null: true } } + { removed: { _gt:$import_id_old } } + ] + }, order_by: { object: { obj_name: asc } }) { + usr { + ...userDetailsChangesOld + } + object { + ...networkObjectDetailsChangesOld + } + } + rule_services(where: { + active: { _eq: $active } + rs_create: { _lte: $import_id_old } + _or: [ + { removed: { _is_null: true } } + { removed: { _gt:$import_id_old } } + ] + }, order_by: { service: { svc_name: asc } }) { + service { + ...networkServiceDetailsChangesOld + } + } + rule_enforced_on_gateways(order_by:{ device: { dev_name: asc } }) { + device { + id: dev_id + name: dev_name + } + } +} diff --git a/roles/common/files/fwo-api-calls/rule/fragments/ruleDetailsForAppRuleReport.graphql b/roles/common/files/fwo-api-calls/rule/fragments/ruleDetailsForAppRuleReport.graphql new file mode 100644 index 0000000000..369a264bdb --- /dev/null +++ b/roles/common/files/fwo-api-calls/rule/fragments/ruleDetailsForAppRuleReport.graphql @@ -0,0 +1,71 @@ +fragment ruleDetailsForAppRuleReport on rule_api { + rule_id + rule_uid + mgm_id + dev_id + rule_action + section_header: rule_head_text + rule_comment + rule_track + rule_disabled + rule_from_zones { + zone { + zone_name + zone_id + } + } + active + rule_src_neg + rule_dst_neg + rule_svc_neg + rule_num_numeric + rule_name + rule_installon + rule_custom_fields + access_rule + rule_froms(where: { + rf_create: { _lte: $import_id_end } + _or: [ + { removed: { _is_null: true } } + { removed: { _gt: $import_id_start } } + ] + }, order_by: { object: { obj_name: asc } }) { + usr { + ...userOverview + } + object { + ...networkObjectDetailsForAppRules + } + } + rule_to_zones { + zone { + zone_name + zone_id + } + } + rule_tos(where: { + rt_create: { _lte: $import_id_end } + _or: [ + { removed: { _is_null: true } } + { removed: { _gt: $import_id_start } } + ] + }, order_by: { object: { obj_name: asc } }) { + usr { + ...userOverview + } + object { + ...networkObjectDetailsForAppRules + } + } + rule_services(where: { + rs_create: { _lte: $import_id_end } + _or: [ + { removed: { _is_null: true } } + { removed: { _gt: $import_id_start } } + ] + }, order_by: { service: { svc_name: asc } }) { + service { + ...networkServiceOverview + } + } +} diff --git a/roles/common/files/fwo-api-calls/rule/fragments/ruleDetailsForReport.graphql b/roles/common/files/fwo-api-calls/rule/fragments/ruleDetailsForReport.graphql new file mode 100644 index 0000000000..ffbb1318b6 --- /dev/null +++ b/roles/common/files/fwo-api-calls/rule/fragments/ruleDetailsForReport.graphql @@ -0,0 +1,108 @@ +fragment ruleDetailsForReport on rule { + rule_id + rule_uid + mgm_id + dev_id + rule_action + section_header: rule_head_text + rule_comment + rule_track + rule_disabled + rule_from_zones { + zone { + zone_name + zone_id + } + } + rule_metadatum { + rule_metadata_id + rule_created + rule_first_hit + rule_last_hit + created_import { start_time } + } + active + rule_create + rule_last_seen + importControlByRuleLastSeen { + control_id + start_time + } + rule_src_neg + rule_dst_neg + rule_svc_neg + rule_num_numeric + rule_name + rule_installon + rule_custom_fields + rule_time + rule_times { + rule_time_id + rule_id + time_obj_id + created + removed + time_object { + time_obj_id + time_obj_name + time_obj_uid + start_time + end_time + created + } + } + access_rule + nat_rule + xlate_rule + rule_froms(where: { + rf_create: { _lte: $import_id_end } + _or: [ + { removed: { _is_null: true } } + { removed: { _gt: $import_id_start } } + ] + }, order_by: { object: { obj_name: asc } }) { + usr { + ...userDetails + } + object { + ...networkObjectDetails + } + } + rule_to_zones { + zone { + zone_name + zone_id + } + } + rule_tos(where: { + rt_create: { _lte: $import_id_end } + _or: [ + { removed: { _is_null: true } } + { removed: { _gt: $import_id_start } } + ] + }, order_by: { object: { obj_name: asc } }) { + usr { + ...userDetails + } + object { + ...networkObjectDetails + } + } + rule_services(where: { + rs_create: { _lte: $import_id_end } + _or: [ + { removed: { _is_null: true } } + { removed: { _gt: $import_id_start } } + ] + }, order_by: { service: { svc_name: asc } }) { + service { + ...networkServiceDetails + } + } + rule_enforced_on_gateways(order_by:{ device: { dev_name: asc } }) { + device { + id: dev_id + name: dev_name + } + } +} diff --git a/roles/common/files/fwo-api-calls/rule/fragments/ruleOverview.graphql b/roles/common/files/fwo-api-calls/rule/fragments/ruleOverview.graphql new file mode 100644 index 0000000000..531235c8da --- /dev/null +++ b/roles/common/files/fwo-api-calls/rule/fragments/ruleOverview.graphql @@ -0,0 +1,105 @@ +fragment ruleOverview on rule { + rule_id + rule_uid + dev_id + rule_action + rulebase_id + section_header: rule_head_text + rule_comment + rule_track + rule_disabled + rule_from_zones { + zone { + zone_name + zone_id + } + } + rule_metadatum { + rule_metadata_id + rule_created + rule_first_hit + rule_last_hit + created_import { start_time } + } + rule_src_neg + rule_dst_neg + rule_svc_neg + rule_src + rule_dst + rule_svc + rule_num_numeric + rule_num + rule_name + rule_custom_fields + rule_installon + rule_time + rule_times { + rule_time_id + rule_id + time_obj_id + created + removed + time_object { + time_obj_id + time_obj_name + time_obj_uid + start_time + end_time + created + } + } + access_rule + nat_rule + xlate_rule + rule_froms(where: { + rf_create: { _lte: $import_id_end } + _or: [ + { removed: { _is_null: true } } + { removed: { _gt: $import_id_start } } + ] + }, order_by:{ object: { obj_name: asc } }) { + usr { + ...userOverview + } + object { + ...networkObjectOverview + } + } + rule_to_zones { + zone { + zone_name + zone_id + } + } + rule_tos(where: { + rt_create: { _lte: $import_id_end } + _or: [ + { removed: { _is_null: true } } + { removed: { _gt: $import_id_start } } + ] + }, order_by:{ object: { obj_name: asc } }) { + usr { + ...userOverview + } + object { + ...networkObjectOverview + } + } + rule_services(where: { + rs_create: { _lte: $import_id_end } + _or: [ + { removed: { _is_null: true } } + { removed: { _gt: $import_id_start } } + ] + }, order_by:{ service: { svc_name: asc } }) { + service { + ...networkServiceOverview + } + } + rule_enforced_on_gateways(order_by:{ device: { dev_name: asc } }) { + device { + id: dev_id + name: dev_name + } + } +} diff --git a/roles/common/files/fwo-api-calls/rule/fragments/ruleOverviewChangesNew.graphql b/roles/common/files/fwo-api-calls/rule/fragments/ruleOverviewChangesNew.graphql new file mode 100644 index 0000000000..0e989f1320 --- /dev/null +++ b/roles/common/files/fwo-api-calls/rule/fragments/ruleOverviewChangesNew.graphql @@ -0,0 +1,85 @@ +fragment ruleOverviewChangesNew on rule { + rule_id + rule_uid + dev_id + rule_action + section_header: rule_head_text + rule_comment + rule_track + rule_disabled + rule_from_zones { + zone { + zone_name + zone_id + } + } + rule_metadatum { + rule_metadata_id + rule_created + rule_first_hit + rule_last_hit + created_import { start_time } + } + rule_src_neg + rule_dst_neg + rule_svc_neg + rule_num_numeric + rule_name + access_rule + nat_rule + xlate_rule + rule_froms(where: { + active: { _eq: $active } + rf_create: { _lte: $import_id_new } + _or: [ + { removed: { _is_null: true } } + { removed: { _gt: $import_id_new } } + ] + }, order_by: { object: { obj_name: asc } }) { + usr { + ...userOverview + } + object { + ...networkObjectOverview + } + } + rule_to_zones { + zone { + zone_name + zone_id + } + } + rule_tos(where: { + active: { _eq: $active } + rt_create: { _lte: $import_id_new } + _or: [ + { removed: { _is_null: true } } + { removed: { _gt: $import_id_new } } + ] + }, order_by: { object: { obj_name: asc } }) { + usr { + ...userOverview + } + object { + ...networkObjectOverview + } + } + rule_services(where: { + active: { _eq: $active } + rs_create: { _lte: $import_id_new } + _or: [ + { removed: { _is_null: true } } + { removed: { _gt: $import_id_new } } + ] + }, order_by: { service: { svc_name: asc } }) { + service { + ...networkServiceOverview + } + } + rule_enforced_on_gateways(order_by:{ device: { dev_name: asc } }) { + device { + id: dev_id + name: dev_name + } + } +} diff --git a/roles/common/files/fwo-api-calls/rule/fragments/ruleOverviewChangesOld.graphql b/roles/common/files/fwo-api-calls/rule/fragments/ruleOverviewChangesOld.graphql new file mode 100644 index 0000000000..7f28c23e72 --- /dev/null +++ b/roles/common/files/fwo-api-calls/rule/fragments/ruleOverviewChangesOld.graphql @@ -0,0 +1,85 @@ +fragment ruleOverviewChangesOld on rule { + rule_id + rule_uid + dev_id + rule_action + section_header: rule_head_text + rule_comment + rule_track + rule_disabled + rule_from_zones { + zone { + zone_name + zone_id + } + } + rule_metadatum { + rule_metadata_id + rule_created + rule_first_hit + rule_last_hit + created_import { start_time } + } + rule_src_neg + rule_dst_neg + rule_svc_neg + rule_num_numeric + rule_name + access_rule + nat_rule + xlate_rule + rule_froms(where: { + active: { _eq: $active } + rf_create: { _lte: $import_id_old } + _or: [ + { removed: { _is_null: true } } + { removed: { _gt: $import_id_old } } + ] + }, order_by: { object: { obj_name: asc } }) { + usr { + ...userOverview + } + object { + ...networkObjectOverview + } + } + rule_to_zones { + zone { + zone_name + zone_id + } + } + rule_tos(where: { + active: { _eq: $active } + rt_create: { _lte: $import_id_old } + _or: [ + { removed: { _is_null: true } } + { removed: { _gt:$import_id_old } } + ] + }, order_by: { object: { obj_name: asc } }) { + usr { + ...userOverview + } + object { + ...networkObjectOverview + } + } + rule_services(where: { + active: { _eq: $active } + rs_create: { _lte: $import_id_old } + _or: [ + { removed: { _is_null: true } } + { removed: { _gt:$import_id_old } } + ] + }, order_by: { service: { svc_name: asc } }) { + service { + ...networkServiceOverview + } + } + rule_enforced_on_gateways(order_by:{ device: { dev_name: asc } }) { + device { + id: dev_id + name: dev_name + } + } +} diff --git a/roles/common/files/fwo-api-calls/rule/fragments/rulebaseOverview.graphql b/roles/common/files/fwo-api-calls/rule/fragments/rulebaseOverview.graphql new file mode 100644 index 0000000000..931f395e2f --- /dev/null +++ b/roles/common/files/fwo-api-calls/rule/fragments/rulebaseOverview.graphql @@ -0,0 +1,5 @@ +fragment rulebaseOverview on rulebase { + id + uid + name +} diff --git a/roles/common/files/fwo-api-calls/rule/getActiveRulesByOwner.graphql b/roles/common/files/fwo-api-calls/rule/getActiveRulesByOwner.graphql new file mode 100644 index 0000000000..771c43b5da --- /dev/null +++ b/roles/common/files/fwo-api-calls/rule/getActiveRulesByOwner.graphql @@ -0,0 +1,80 @@ +query getActiveRulesByOwner($ownerId: Int!) { + rule( + where: { + removed: {_is_null: true}, + rule_owners: { + owner_id: {_eq: $ownerId}, + removed: {_is_null: true} + } + } + ) { + rule_uid + rule_id + mgm_id + rule_froms(order_by:{ object: {obj_id: asc}}){ + object{ + obj_name + obj_ip + obj_ip_end + objgrp_flats( + where: { + active: { _eq: true } + removed: { _is_null: true } + } + ) { + id_flat: objgrp_flat_id + byFlatId: objectByObjgrpFlatMemberId { + obj_id + obj_name + obj_ip + obj_ip_end + obj_member_refs + type: stm_obj_typ { + name: obj_typ_name + } + } + } + } + } + rule_tos(order_by: { object: { obj_name: asc } }) { + object { + obj_name + obj_ip + obj_ip_end + objgrp_flats( + where: { + active: { _eq: true } + removed: { _is_null: true } + } + ) { + id_flat: objgrp_flat_id + byFlatId: objectByObjgrpFlatMemberId { + obj_id + obj_name + obj_ip + obj_ip_end + obj_member_refs + type: stm_obj_typ { + name: obj_typ_name + } + } + } + } + } + rule_services(order_by: { service: { svc_name: asc } }) { + service { + svc_name + ip_proto_id + protocol_name: stm_ip_proto { + name: ip_proto_name + } + svc_port + } + } + rule_custom_fields + rule_name + rule_metadatum { + rule_last_hit + } + } +} diff --git a/roles/common/files/fwo-api-calls/rule/getChangedRulesForRuleOwnerMappingCustomField.graphql b/roles/common/files/fwo-api-calls/rule/getChangedRulesForRuleOwnerMappingCustomField.graphql new file mode 100644 index 0000000000..540ce6f474 --- /dev/null +++ b/roles/common/files/fwo-api-calls/rule/getChangedRulesForRuleOwnerMappingCustomField.graphql @@ -0,0 +1,26 @@ + +query getChangedRulesForRuleOwnerMappingCustomField($controlId: bigint!) { + changelog_rule(where: { control_id: { _eq: $controlId } }) { + import: import_control { + control_id + import_type_id + } + change_action + old: ruleByOldRuleId { + rule_id + rule_name + rule_metadatum { + rule_metadata_id + } + rule_custom_fields + } + new: rule { + rule_id + rule_name + rule_metadatum { + rule_metadata_id + } + rule_custom_fields + } + } +} diff --git a/roles/common/files/fwo-api-calls/rule/getChangedRulesForRuleOwnerMappingIpBased.graphql b/roles/common/files/fwo-api-calls/rule/getChangedRulesForRuleOwnerMappingIpBased.graphql new file mode 100644 index 0000000000..da4dfc4d31 --- /dev/null +++ b/roles/common/files/fwo-api-calls/rule/getChangedRulesForRuleOwnerMappingIpBased.graphql @@ -0,0 +1,68 @@ +query getChangedRulesForRuleOwnerMappingIpBased($controlId: bigint!) { + changelog_rule(where: { control_id: { _eq: $controlId } }) { + import: import_control { + control_id + import_type_id + } + + change_action + + old: ruleByOldRuleId { + rule_id + rule_name + + rule_metadatum { + rule_metadata_id + } + + rule_tos(where: { removed: { _is_null: true } }) { + object { + obj_id + obj_ip + obj_ip_end + obj_name + removed + } + } + + rule_froms(where: { removed: { _is_null: true } }) { + object { + obj_id + obj_ip + obj_ip_end + obj_name + removed + } + } + } + + new: rule { + rule_id + rule_name + + rule_metadatum { + rule_metadata_id + } + + rule_tos(where: { removed: { _is_null: true } }) { + object { + obj_id + obj_ip + obj_ip_end + obj_name + removed + } + } + + rule_froms(where: { removed: { _is_null: true } }) { + object { + obj_id + obj_ip + obj_ip_end + obj_name + removed + } + } + } + } +} diff --git a/roles/common/files/fwo-api-calls/rule/getChangelogRulesCForMgm.graphql b/roles/common/files/fwo-api-calls/rule/getChangelogRulesCForMgm.graphql new file mode 100644 index 0000000000..b2f5f1f151 --- /dev/null +++ b/roles/common/files/fwo-api-calls/rule/getChangelogRulesCForMgm.graphql @@ -0,0 +1,12 @@ +query getChangelogRulesCForMgm($mgmId: Int!) { + changelog_rule( + where: { mgm_id: { _eq: $mgmId }, change_action: { _eq: "C" } } + ) { + log_rule_id + new_rule_id + old_rule_id + rule { + rule_uid + } + } +} diff --git a/roles/common/files/fwo-api-calls/rule/getMapOfUid2Id.graphql b/roles/common/files/fwo-api-calls/rule/getMapOfUid2Id.graphql new file mode 100644 index 0000000000..63ebaeb9e8 --- /dev/null +++ b/roles/common/files/fwo-api-calls/rule/getMapOfUid2Id.graphql @@ -0,0 +1,13 @@ +query getMapOfUid2Id($uids: [String!], $mgmId: Int!) { + rule(where: { + rule_uid: {_in: $uids}, + _or: [ + {mgm_id: {_eq: $mgmId}}, + {management: {multi_device_manager_id: {_eq: $mgmId}}} + ], + removed: {_is_null: true} + }) { + rule_id + rule_uid + } +} diff --git a/roles/common/files/fwo-api-calls/rule/getNatRuleDetails.graphql b/roles/common/files/fwo-api-calls/rule/getNatRuleDetails.graphql new file mode 100644 index 0000000000..58bc784892 --- /dev/null +++ b/roles/common/files/fwo-api-calls/rule/getNatRuleDetails.graphql @@ -0,0 +1,25 @@ +query getNatRuleDetails( + $rule_id: [bigint!] + $rule_uid: [String!] + $ruleSrcName: [String!] + $ruleSrcIp: [cidr!] + $limit: Int + $offset: Int +) { + rule( + limit: $limit + offset: $offset + where: { + rule_id: { _in: $rule_id } + rule_uid: { _in: $rule_uid } + active: { _eq: true } + rule_src: { _in: $ruleSrcName } + rule_froms: { object: { obj_ip: { _in: $ruleSrcIp } } } + nat_rule: { _eq: true } + } + order_by: { rule_num_numeric: asc } + ) { + mgm_id: mgm_id + ...natRuleDetails + } +} diff --git a/roles/lib/files/FWO.Api.Client/APIcalls/rule/getNatRuleOverview.graphql b/roles/common/files/fwo-api-calls/rule/getNatRuleOverview.graphql similarity index 100% rename from roles/lib/files/FWO.Api.Client/APIcalls/rule/getNatRuleOverview.graphql rename to roles/common/files/fwo-api-calls/rule/getNatRuleOverview.graphql diff --git a/roles/lib/files/FWO.Api.Client/APIcalls/rule/getRuleByUid.graphql b/roles/common/files/fwo-api-calls/rule/getRuleByUid.graphql similarity index 100% rename from roles/lib/files/FWO.Api.Client/APIcalls/rule/getRuleByUid.graphql rename to roles/common/files/fwo-api-calls/rule/getRuleByUid.graphql diff --git a/roles/common/files/fwo-api-calls/rule/getRuleDetailByID.graphql b/roles/common/files/fwo-api-calls/rule/getRuleDetailByID.graphql new file mode 100644 index 0000000000..b6b5fce096 --- /dev/null +++ b/roles/common/files/fwo-api-calls/rule/getRuleDetailByID.graphql @@ -0,0 +1,101 @@ +query RuleDetailById( + $rule_ids: [bigint!] + $rule_action: String +) { + rule( + where:{ + rule_id: {_in: $rule_ids} + rule_action: { _eq: $rule_action} + removed: { _is_null: true } + } + ) { + rule_uid + rule_id + mgm_id + rule_froms(order_by:{ object: {obj_id: asc}}){ + object{ + obj_name + obj_ip + obj_ip_end + objgrp_flats( + where: { + active: { _eq: true } + removed: { _is_null: true } + } + ) { + id_flat: objgrp_flat_id + byFlatId: objectByObjgrpFlatMemberId { + obj_id + obj_name + obj_ip + obj_ip_end + obj_member_refs + type: stm_obj_typ { + name: obj_typ_name + } + } + } + } + } + rule_tos(order_by: { object: { obj_name: asc } }) { + object { + obj_name + obj_ip + obj_ip_end + objgrp_flats( + where: { + active: { _eq: true } + removed: { _is_null: true } + } + ) { + id_flat: objgrp_flat_id + byFlatId: objectByObjgrpFlatMemberId { + obj_id + obj_name + obj_ip + obj_ip_end + obj_member_refs + type: stm_obj_typ { + name: obj_typ_name + } + } + } + } + } + rule_services(order_by: { service: { svc_name: asc } }) { + service { + svc_name + ip_proto_id + protocol_name: stm_ip_proto { + name: ip_proto_name + } + svc_port + } + } + rule_times( + where: { + removed: { _is_null: true } + } + ) { + time_obj_id + time_object { + time_obj_name + } + } + rule_custom_fields + rule_name + rule_last_seen + rule_action + rule_comment + createdImport: import_control { + start_time + } + rule_metadatum { + rule_last_hit + } + rule_owners + { + owner_id + } + } +} diff --git a/roles/common/files/fwo-api-calls/rule/getRuleDetails.graphql b/roles/common/files/fwo-api-calls/rule/getRuleDetails.graphql new file mode 100644 index 0000000000..4c51d53c90 --- /dev/null +++ b/roles/common/files/fwo-api-calls/rule/getRuleDetails.graphql @@ -0,0 +1,33 @@ +query getRuleDetails( + $rule_id: [bigint!] + $rule_uid: [String!] + $ruleSrcName: [String!] + $ruleSrcIp: [cidr!] + $active: Boolean + $import_id: bigint + $import_id_start: bigint + $import_id_end: bigint + $limit: Int + $offset: Int +) { + rule( + limit: $limit + offset: $offset + where: { + rule_id: { _in: $rule_id } + rule_uid: { _in: $rule_uid } + rule_create: { _lte: $import_id } + _or: [ + { removed: { _is_null: true } } + { removed: { _gt: $import_id_start } } + ] + rule_src: { _in: $ruleSrcName } + rule_froms: { object: { obj_ip: { _in: $ruleSrcIp } } } + access_rule: { _eq: true } + } + order_by: { rule_num_numeric: asc } + ) { + mgm_id: mgm_id + ...ruleDetails + } +} diff --git a/roles/common/files/fwo-api-calls/rule/getRuleIdsByRuleOwner.graphql b/roles/common/files/fwo-api-calls/rule/getRuleIdsByRuleOwner.graphql new file mode 100644 index 0000000000..7b75d44c98 --- /dev/null +++ b/roles/common/files/fwo-api-calls/rule/getRuleIdsByRuleOwner.graphql @@ -0,0 +1,10 @@ +query GetRuleIdsByRuleOwner($ownerId: Int!, $owner_mapping_source: smallint!) { + rule_owner( + where: { + owner_mapping_source_id: { _eq: $owner_mapping_source } + owner_id: { _eq: $ownerId } + } + ) { + rule_id + } +} diff --git a/roles/common/files/fwo-api-calls/rule/getRuleIdsOfImport.graphql b/roles/common/files/fwo-api-calls/rule/getRuleIdsOfImport.graphql new file mode 100644 index 0000000000..25330e6189 --- /dev/null +++ b/roles/common/files/fwo-api-calls/rule/getRuleIdsOfImport.graphql @@ -0,0 +1,18 @@ +query getRuleIdsOfImport( + $import_id_start: bigint + $import_id_end: bigint + $devIds: [Int!] +) { + rule( + where: { + rule_create: { _lte: $import_id_end } + _or: [ + { removed: { _is_null: true } } + { removed: { _gt: $import_id_start } } + ] + dev_id: { _in: $devIds } + } + ) { + rule_id + } +} diff --git a/roles/lib/files/FWO.Api.Client/APIcalls/rule/getRuleOverview.graphql b/roles/common/files/fwo-api-calls/rule/getRuleOverview.graphql similarity index 100% rename from roles/lib/files/FWO.Api.Client/APIcalls/rule/getRuleOverview.graphql rename to roles/common/files/fwo-api-calls/rule/getRuleOverview.graphql diff --git a/roles/common/files/fwo-api-calls/rule/getRuleUidsOfDevice.graphql b/roles/common/files/fwo-api-calls/rule/getRuleUidsOfDevice.graphql new file mode 100644 index 0000000000..fa980684b5 --- /dev/null +++ b/roles/common/files/fwo-api-calls/rule/getRuleUidsOfDevice.graphql @@ -0,0 +1,25 @@ +# unused query, kept for reference - delete when not needed +# query getRuleUidsOfDevice ( +# $devId: Int! +# $import_id_start: bigint +# $import_id_end: bigint +# ) { +# rule ( +# where: { +# dev_id: { _eq: $devId } +# active: { _eq: true } +# access_rule: { _eq: true } +# rule_head_text: { _is_null: true } +# rule_disabled: { _eq: false } +# action_id: { _nin: [2,3,7] } +# import_control: {control_id: {_lte: $import_id_end}}, _or: [{removed: {_is_null: true}}, {removed: {_gt: $import_id_start}}] +# } +# order_by: { rule_num_numeric: asc }){ +# rule_uid +# rule_metadatum{ +# rule_metadata_id +# rule_uid +# dev_id +# } +# } +# } diff --git a/roles/common/files/fwo-api-calls/rule/getRuleUidsOfRulebase.graphql b/roles/common/files/fwo-api-calls/rule/getRuleUidsOfRulebase.graphql new file mode 100644 index 0000000000..edffafe455 --- /dev/null +++ b/roles/common/files/fwo-api-calls/rule/getRuleUidsOfRulebase.graphql @@ -0,0 +1,25 @@ +query getRuleUidsOfRulebase ( + $rulebaseId: Int! + $import_id_start: bigint + $import_id_end: bigint +) { + rule ( + where: { + rulebase_id: { _eq: $rulebaseId } + active: { _eq: true } + access_rule: { _eq: true } + rule_head_text: { _is_null: true } + rule_disabled: { _eq: false } + action_id: { _nin: [2,3,7] } + import_control: {control_id: {_lte: $import_id_end}}, _or: [{removed: {_is_null: true}}, {removed: {_gt: $import_id_start}}] + } + order_by: { rule_num_numeric: asc }){ + rule_uid + rule_name + mgm_id + rulebase_id + rule_metadatum{ + rule_metadata_id + } + } +} diff --git a/roles/common/files/fwo-api-calls/rule/getRulebaseLinks.graphql b/roles/common/files/fwo-api-calls/rule/getRulebaseLinks.graphql new file mode 100644 index 0000000000..a105a08fd8 --- /dev/null +++ b/roles/common/files/fwo-api-calls/rule/getRulebaseLinks.graphql @@ -0,0 +1,15 @@ +query getRulebaseLinks($gwIds: [Int!]) { + rulebase_link (where: {removed:{_is_null:true}, gw_id: {_in: $gwIds } }) { + id + gw_id + from_rule_id + from_rulebase_id + to_rulebase_id + link_type + is_initial + is_global + is_section + created + removed + } +} diff --git a/roles/common/files/fwo-api-calls/rule/getRulesByIdWithRefUids.graphql b/roles/common/files/fwo-api-calls/rule/getRulesByIdWithRefUids.graphql new file mode 100644 index 0000000000..b8de9a0d89 --- /dev/null +++ b/roles/common/files/fwo-api-calls/rule/getRulesByIdWithRefUids.graphql @@ -0,0 +1,15 @@ +query getRulesByIdWithRefUids ($ruleIds:[bigint!]!) { + rule (where:{rule_id:{_in:$ruleIds}}) { + rule_id + rule_src_refs + rule_dst_refs + rule_svc_refs + rule_to_zone + rule_from_zone + rule_src_neg + rule_dst_neg + rule_svc_neg + rulebase_id + rule_installon + } +} diff --git a/roles/common/files/fwo-api-calls/rule/getRulesByManagement.graphql b/roles/common/files/fwo-api-calls/rule/getRulesByManagement.graphql new file mode 100644 index 0000000000..68811064f8 --- /dev/null +++ b/roles/common/files/fwo-api-calls/rule/getRulesByManagement.graphql @@ -0,0 +1,20 @@ +query getRulesByManagement ( + $mgmId: Int! + $active: Boolean + $import_id_start: bigint + $import_id_end: bigint +) { + rule ( + where: { + mgm_id: { _eq: $mgmId } + active: { _eq: true } + access_rule: { _eq: true } + rule_head_text: { _is_null: true } + rule_disabled: { _eq: false } + action_id: { _nin: [2,3,7] } + import_control: {control_id: {_lte: $import_id_end}}, _or: [{removed: {_is_null: true}}, {removed: {_gt: $import_id_start}}] + } + order_by: { rule_num_numeric: asc }){ + ...ruleDetails + } +} diff --git a/roles/common/files/fwo-api-calls/rule/getRulesByUidsForMgm.graphql b/roles/common/files/fwo-api-calls/rule/getRulesByUidsForMgm.graphql new file mode 100644 index 0000000000..adaa0a06c9 --- /dev/null +++ b/roles/common/files/fwo-api-calls/rule/getRulesByUidsForMgm.graphql @@ -0,0 +1,6 @@ +query getRulesByUidsForMgm($mgmId: Int!, $ruleUids: [String!]) { + rule(where: { mgm_id: { _eq: $mgmId }, rule_uid: { _in: $ruleUids } }) { + rule_id + rule_uid + } +} diff --git a/roles/common/files/fwo-api-calls/rule/getRulesByUidsWithCreate.graphql b/roles/common/files/fwo-api-calls/rule/getRulesByUidsWithCreate.graphql new file mode 100644 index 0000000000..4c58985b51 --- /dev/null +++ b/roles/common/files/fwo-api-calls/rule/getRulesByUidsWithCreate.graphql @@ -0,0 +1,16 @@ +query getRulesByUidsWithCreate($uids: [String!], $mgmId: Int!) { + rule( + where: { + rule_uid: { _in: $uids } + _or: [ + { mgm_id: { _eq: $mgmId } } + { management: { multi_device_manager_id: { _eq: $mgmId } } } + ] + removed: { _is_null: true } + } + ) { + rule_id + rule_uid + rule_create + } +} diff --git a/roles/common/files/fwo-api-calls/rule/getRulesEnforcedOnGateways.graphql b/roles/common/files/fwo-api-calls/rule/getRulesEnforcedOnGateways.graphql new file mode 100644 index 0000000000..99c6807994 --- /dev/null +++ b/roles/common/files/fwo-api-calls/rule/getRulesEnforcedOnGateways.graphql @@ -0,0 +1,15 @@ +query getRulesEnforcedOnGateways($gwIds: [Int!]!) { + rule_enforced_on_gateway( + where: { dev_id: { _in: $gwIds }, removed: { _is_null: true } } + ) { + rule { + rule_id + rule_uid + removed + } + device { + dev_id + dev_uid + } + } +} diff --git a/roles/common/files/fwo-api-calls/rule/getRulesForOwnerMappingCustomField.graphql b/roles/common/files/fwo-api-calls/rule/getRulesForOwnerMappingCustomField.graphql new file mode 100644 index 0000000000..c0a1aa6767 --- /dev/null +++ b/roles/common/files/fwo-api-calls/rule/getRulesForOwnerMappingCustomField.graphql @@ -0,0 +1,16 @@ +query getRulesForOwnerMappingCustomField { + rule( + where: { + removed: { _is_null: true } + rule_custom_fields: { _is_null: false } + } + ) { + rule_id + rule_name + rule_uid + rule_metadatum { + rule_metadata_id + } + rule_custom_fields + } +} diff --git a/roles/common/files/fwo-api-calls/rule/getRulesForOwnerMappingIpBased.graphql b/roles/common/files/fwo-api-calls/rule/getRulesForOwnerMappingIpBased.graphql new file mode 100644 index 0000000000..473a2cc861 --- /dev/null +++ b/roles/common/files/fwo-api-calls/rule/getRulesForOwnerMappingIpBased.graphql @@ -0,0 +1,28 @@ +query getRulesForOwnerMappingIpBased { + rule(where: { removed: { _is_null: true } }) { + rule_name + rule_id + rule_uid + rule_metadatum { + rule_metadata_id + } + rule_tos(where: { removed: { _is_null: true } }) { + object { + obj_id + obj_ip + obj_ip_end + obj_name + removed + } + } + rule_froms(where: { removed: { _is_null: true } }) { + object { + obj_id + obj_ip + obj_ip_end + obj_name + removed + } + } + } +} diff --git a/roles/common/files/fwo-api-calls/rule/getRulesForRuleOwnerByOwnerToUpdateCustomField.graphql b/roles/common/files/fwo-api-calls/rule/getRulesForRuleOwnerByOwnerToUpdateCustomField.graphql new file mode 100644 index 0000000000..75faaacad8 --- /dev/null +++ b/roles/common/files/fwo-api-calls/rule/getRulesForRuleOwnerByOwnerToUpdateCustomField.graphql @@ -0,0 +1,19 @@ +query getRulesForRuleOwnerByOwnerToUpdateCustomField($ownerIds: [Int!]!) { + rule( + where: { + rule_owners: { + owner_id: { _in: $ownerIds } + removed: { _is_null: false } + } + } + ) { + rule_id + rule_name + removed + rule_uid + rule_metadatum { + rule_metadata_id + } + rule_custom_fields + } +} diff --git a/roles/common/files/fwo-api-calls/rule/getRulesForRuleOwnerCustomField.graphql b/roles/common/files/fwo-api-calls/rule/getRulesForRuleOwnerCustomField.graphql new file mode 100644 index 0000000000..7c7e888612 --- /dev/null +++ b/roles/common/files/fwo-api-calls/rule/getRulesForRuleOwnerCustomField.graphql @@ -0,0 +1,12 @@ +query getRulesForRuleOwnerCustomField { + rule(where: { removed: { _eq: null } }) { + rule_id + rule_name + removed + rule_uid + rule_metadatum { + rule_metadata_id + } + rule_custom_fields + } +} diff --git a/roles/common/files/fwo-api-calls/rule/getRulesForRuleOwnerIpBased.graphql b/roles/common/files/fwo-api-calls/rule/getRulesForRuleOwnerIpBased.graphql new file mode 100644 index 0000000000..4deb0ce479 --- /dev/null +++ b/roles/common/files/fwo-api-calls/rule/getRulesForRuleOwnerIpBased.graphql @@ -0,0 +1,29 @@ +query getRulesForRuleOwnerIpBased { + rule(where: { removed: { _eq: null } }) { + rule_id + rule_name + removed + rule_uid + rule_metadatum { + rule_metadata_id + } + rule_tos(where: { removed: { _is_null: true } }) { + object { + obj_id + obj_ip + obj_ip_end + obj_name + removed + } + } + rule_froms(where: { removed: { _is_null: true } }) { + object { + obj_id + obj_ip + obj_ip_end + obj_name + removed + } + } + } +} diff --git a/roles/common/files/fwo-api-calls/rule/getRulesForSelectedManagements.graphql b/roles/common/files/fwo-api-calls/rule/getRulesForSelectedManagements.graphql new file mode 100644 index 0000000000..53953ce8e6 --- /dev/null +++ b/roles/common/files/fwo-api-calls/rule/getRulesForSelectedManagements.graphql @@ -0,0 +1,38 @@ +query getRulesForSelectedManagementsByChunk( + $limit: Int + $offset: Int + $active: Boolean + $import_id_start: bigint + $import_id_end: bigint + $from_date: timestamptz + $to_date: timestamptz + $mgm_ids: [Int!] +) { + rule( + limit: $limit + offset: $offset + order_by: { rule_uid: asc } + where: { mgm_id: { _in: $mgm_ids } removed: { _is_null: true } } + ){ + rule_src + rule_dst + ...ruleDetails + violations: compliance_violations_version_agnostic( where: { removed_date: { _is_null: true } }) { + id + rule_id + rule_uid + mgmt_uid + found_date + removed_date + details + risk_score + policy_id + criterion_id + criterion: criterion{ + id + name + criterion_type + } + } + } +} diff --git a/roles/common/files/fwo-api-calls/rule/getRulesWithCurrentViolationsByChunk.graphql b/roles/common/files/fwo-api-calls/rule/getRulesWithCurrentViolationsByChunk.graphql new file mode 100644 index 0000000000..6d89bff222 --- /dev/null +++ b/roles/common/files/fwo-api-calls/rule/getRulesWithCurrentViolationsByChunk.graphql @@ -0,0 +1,28 @@ +query getRulesWithCurrentViolationsByChunk($limit: Int, $offset: Int, $active: Boolean, $import_id_start: bigint, $import_id_end: bigint, $mgm_ids: [Int!]) { + rule(limit: $limit, offset: $offset, order_by: { rule_uid: asc }, where: { mgm_id: { _in: $mgm_ids } removed: { _is_null: true } }) { + rule_src + rule_dst + ...ruleDetails + violations: compliance_violations_version_agnostic( where: { removed_date: { _is_null: true } }) { + id + rule_id + rule_uid + mgmt_uid + found_date + removed_date + details + risk_score + policy_id + criterion_id + criterion: criterion{ + id + name + criterion_type + } + } + rulebase: rulebase { + id + name + } + } +} diff --git a/roles/common/files/fwo-api-calls/rule/getRulesWithViolationsInTimespanByChunk.graphql b/roles/common/files/fwo-api-calls/rule/getRulesWithViolationsInTimespanByChunk.graphql new file mode 100644 index 0000000000..c1a590b2c0 --- /dev/null +++ b/roles/common/files/fwo-api-calls/rule/getRulesWithViolationsInTimespanByChunk.graphql @@ -0,0 +1,45 @@ +query getRulesWithViolationsInTimespanByChunk( + $limit: Int + $offset: Int + $active: Boolean + $import_id_start: bigint + $import_id_end: bigint + $mgm_ids: [Int!] + $violations_where: compliance_violation_bool_exp! +) { + rule( + limit: $limit + offset: $offset + order_by: { rule_uid: asc } + where: { mgm_id: { _in: $mgm_ids } removed: { _is_null: true } } + ) { + rule_src + rule_dst + ...ruleDetails + + violations: compliance_violations_version_agnostic( + where: $violations_where + ) { + id + rule_id + rule_uid + mgmt_uid + found_date + removed_date + details + risk_score + policy_id + criterion_id + criterion: criterion{ + id + name + criterion_type + } + } + + rulebase: rulebase { + id + name + } + } +} diff --git a/roles/common/files/fwo-api-calls/rule/getTimeBasedRulesByOwner.graphql b/roles/common/files/fwo-api-calls/rule/getTimeBasedRulesByOwner.graphql new file mode 100644 index 0000000000..a886e93980 --- /dev/null +++ b/roles/common/files/fwo-api-calls/rule/getTimeBasedRulesByOwner.graphql @@ -0,0 +1,193 @@ +query getTimeBasedRulesByOwner { + rule_owner( + where: { + removed: { _is_null: true } + owner: { active: { _eq: true } } + rule: { + removed: { _is_null: true } + rule_times: { + removed: { _is_null: true } + time_object: { removed: { _is_null: true }, end_time: { _is_null: false } } + } + } + } + ) { + owner { + id + name + app_id_external + } + rule { + rule_id + rule_uid + rule_name + mgm_id + rule_num + rule_src_neg + rule_dst_neg + rule_svc_neg + rule_src + rule_dst + rule_svc + rule_custom_fields + rule_metadatum { + rule_last_hit + } + rulebase { + name + } + rule_froms( + where: { + removed: { _is_null: true } + object: { removed: { _is_null: true } } + } + order_by: { object: { obj_name: asc } } + ) { + usr { + user_id + user_uid + user_name + } + object { + obj_id + obj_uid + obj_name + obj_ip + obj_ip_end + obj_member_refs + type: stm_obj_typ { + id: obj_typ_id + name: obj_typ_name + } + objgrp_flats( + where: { + active: { _eq: true } + removed: { _is_null: true } + } + order_by: { objgrp_flat_member_id: asc } + ) { + flat_id: objgrp_flat_id + byFlatId: objectByObjgrpFlatMemberId { + obj_id + obj_uid + obj_name + obj_ip + obj_ip_end + obj_member_refs + type: stm_obj_typ { + name: obj_typ_name + } + } + } + } + } + rule_tos( + where: { + removed: { _is_null: true } + object: { removed: { _is_null: true } } + } + order_by: { object: { obj_name: asc } } + ) { + usr { + user_id + user_uid + user_name + } + object { + obj_id + obj_uid + obj_name + obj_ip + obj_ip_end + obj_member_refs + type: stm_obj_typ { + id: obj_typ_id + name: obj_typ_name + } + objgrp_flats( + where: { + active: { _eq: true } + removed: { _is_null: true } + } + order_by: { objgrp_flat_member_id: asc } + ) { + flat_id: objgrp_flat_id + byFlatId: objectByObjgrpFlatMemberId { + obj_id + obj_uid + obj_name + obj_ip + obj_ip_end + obj_member_refs + type: stm_obj_typ { + name: obj_typ_name + } + } + } + } + } + rule_services( + where: { + removed: { _is_null: true } + service: { removed: { _is_null: true } } + } + order_by: { service: { svc_name: asc } } + ) { + service { + svc_id + svc_uid + svc_name + svc_port + svc_port_end + svc_member_refs + service_type: stm_svc_typ { + name: svc_typ_name + } + ip_proto_id + protocol_name: stm_ip_proto { + id: ip_proto_id + name: ip_proto_name + } + svcgrp_flats( + where: { + active: { _eq: true } + removed: { _is_null: true } + } + order_by: { svcgrp_flat_member_id: asc } + ) { + flat_id: svcgrp_flat_id + byFlatId: serviceBySvcgrpFlatMemberId { + svc_id + svc_uid + svc_name + svc_port + svc_port_end + svc_member_refs + ip_proto_id + protocol_name: stm_ip_proto { + id: ip_proto_id + name: ip_proto_name + } + service_type: stm_svc_typ { + name: svc_typ_name + } + } + } + } + } + rule_times( + where: { + removed: { _is_null: true } + time_object: { removed: { _is_null: true }, end_time: { _is_null: false } } + } + ) { + time_obj_id + time_object { + time_obj_id + time_obj_name + end_time + } + } + } + } +} diff --git a/roles/common/files/fwo-api-calls/rule/insertRuleEnforcedOnGateway.graphql b/roles/common/files/fwo-api-calls/rule/insertRuleEnforcedOnGateway.graphql new file mode 100644 index 0000000000..ed78cc2f10 --- /dev/null +++ b/roles/common/files/fwo-api-calls/rule/insertRuleEnforcedOnGateway.graphql @@ -0,0 +1,7 @@ +mutation insertRuleEnforcedOnGateway ( + $rulesEnforcedOnGateway: [rule_enforced_on_gateway_insert_input!]! +) { + insert_rule_enforced_on_gateway(objects: $rulesEnforcedOnGateway) { + affected_rows + } +} diff --git a/roles/common/files/fwo-api-calls/rule/insertRuleRefs.graphql b/roles/common/files/fwo-api-calls/rule/insertRuleRefs.graphql new file mode 100644 index 0000000000..76da659f9f --- /dev/null +++ b/roles/common/files/fwo-api-calls/rule/insertRuleRefs.graphql @@ -0,0 +1,39 @@ +mutation insertRuleRefs( + $ruleFroms: [rule_from_insert_input!]! + $ruleTos: [rule_to_insert_input!]! + $ruleServices: [rule_service_insert_input!]! + $ruleNwObjResolveds: [rule_nwobj_resolved_insert_input!]! + $ruleSvcResolveds: [rule_svc_resolved_insert_input!]! + $ruleUserResolveds: [rule_user_resolved_insert_input!]! + $ruleFromZones: [rule_from_zone_insert_input!]! + $ruleToZones: [rule_to_zone_insert_input!]! + $ruleTimes: [rule_time_insert_input!]! +) { + insert_rule_from(objects: $ruleFroms) { + affected_rows + } + insert_rule_to(objects: $ruleTos) { + affected_rows + } + insert_rule_service(objects: $ruleServices) { + affected_rows + } + insert_rule_nwobj_resolved(objects: $ruleNwObjResolveds) { + affected_rows + } + insert_rule_svc_resolved(objects: $ruleSvcResolveds) { + affected_rows + } + insert_rule_user_resolved(objects: $ruleUserResolveds) { + affected_rows + } + insert_rule_from_zone(objects: $ruleFromZones) { + affected_rows + } + insert_rule_to_zone(objects: $ruleToZones) { + affected_rows + } + insert_rule_time(objects: $ruleTimes) { + affected_rows + } +} \ No newline at end of file diff --git a/roles/common/files/fwo-api-calls/rule/insertRulebaseLinks.graphql b/roles/common/files/fwo-api-calls/rule/insertRulebaseLinks.graphql new file mode 100644 index 0000000000..ce3e6d60ee --- /dev/null +++ b/roles/common/files/fwo-api-calls/rule/insertRulebaseLinks.graphql @@ -0,0 +1,11 @@ +mutation importInsertRulebaseOnGateway($rulebaseLinks: [rulebase_link_insert_input!]!) { + insert_rulebase_link( + objects: $rulebaseLinks + on_conflict: { + constraint: unique_rulebase_link + update_columns: [] + } + ) { + affected_rows + } +} \ No newline at end of file diff --git a/roles/common/files/fwo-api-calls/rule/removeInconsistentEnforcedOnGateways.graphql b/roles/common/files/fwo-api-calls/rule/removeInconsistentEnforcedOnGateways.graphql new file mode 100644 index 0000000000..de85fec0e1 --- /dev/null +++ b/roles/common/files/fwo-api-calls/rule/removeInconsistentEnforcedOnGateways.graphql @@ -0,0 +1,15 @@ +mutation removeInconsistentEnforcedOnGateways( + $gwIds: [Int!]! + $importId: bigint! +) { + update_rule_enforced_on_gateway( + where: { + dev_id: { _in: $gwIds } + removed: { _is_null: true } + rule: { removed: { _is_null: false } } + } + _set: { removed: $importId } + ) { + affected_rows + } +} diff --git a/roles/common/files/fwo-api-calls/rule/removeInconsistentRulebaseLinks.graphql b/roles/common/files/fwo-api-calls/rule/removeInconsistentRulebaseLinks.graphql new file mode 100644 index 0000000000..8920c318a1 --- /dev/null +++ b/roles/common/files/fwo-api-calls/rule/removeInconsistentRulebaseLinks.graphql @@ -0,0 +1,16 @@ +mutation removeInconsistentRulebaseLinks($importId: bigint!, $mgmId: Int!) { + update_rulebase_link( + where: { + device: { management: { mgm_id: { _eq: $mgmId } } } + removed: { _is_null: true } + _or: [ + { rulebase: { removed: { _is_null: false } } } + { rulebaseByFromRulebaseId: { removed: { _is_null: false } } } + { rule: { removed: { _is_null: false } } } + ] + } + _set: { removed: $importId } + ) { + affected_rows + } +} diff --git a/roles/common/files/fwo-api-calls/rule/removeRulebaseLinks.graphql b/roles/common/files/fwo-api-calls/rule/removeRulebaseLinks.graphql new file mode 100644 index 0000000000..d26039a1f6 --- /dev/null +++ b/roles/common/files/fwo-api-calls/rule/removeRulebaseLinks.graphql @@ -0,0 +1,18 @@ +mutation removeRulebaseLinks( + $importId: bigint! + $removedRulebaseLinks: [Int!]! +) { + update_rulebase_link( + where: { + id: { _in: $removedRulebaseLinks } + removed: { _is_null: true } + } + _set: { removed: $importId } + ) { + affected_rows + returning { + gw_id + id + } + } +} \ No newline at end of file diff --git a/roles/common/files/fwo-api-calls/rule/updateChangelogRuleEntries.graphql b/roles/common/files/fwo-api-calls/rule/updateChangelogRuleEntries.graphql new file mode 100644 index 0000000000..133e74188b --- /dev/null +++ b/roles/common/files/fwo-api-calls/rule/updateChangelogRuleEntries.graphql @@ -0,0 +1,5 @@ +mutation updateChangelogRuleEntries($updates: [changelog_rule_updates!]!) { + update_changelog_rule_many(updates: $updates) { + affected_rows + } +} diff --git a/roles/common/files/fwo-api-calls/rule/updateChanglogRules.graphql b/roles/common/files/fwo-api-calls/rule/updateChanglogRules.graphql new file mode 100644 index 0000000000..23932a596a --- /dev/null +++ b/roles/common/files/fwo-api-calls/rule/updateChanglogRules.graphql @@ -0,0 +1,5 @@ +mutation updateChanglogRules($rule_changes: [changelog_rule_insert_input!]!) { + insert_changelog_rule(objects: $rule_changes) { + affected_rows + } +} \ No newline at end of file diff --git a/roles/common/files/fwo-api-calls/rule/updateRuleEnforcedOnGateway.graphql b/roles/common/files/fwo-api-calls/rule/updateRuleEnforcedOnGateway.graphql new file mode 100644 index 0000000000..5b3a1c5bee --- /dev/null +++ b/roles/common/files/fwo-api-calls/rule/updateRuleEnforcedOnGateway.graphql @@ -0,0 +1,13 @@ +mutation updateRuleEnforcedOnGateway( + $importId: bigint! + $rulesEnforcedOnGateway: [rule_enforced_on_gateway_bool_exp!]! +) { + update_rule_enforced_on_gateway(where: { + _or: $rulesEnforcedOnGateway + removed: {_is_null: true} + }, _set: { + removed: $importId + }) { + affected_rows + } +} \ No newline at end of file diff --git a/roles/common/files/fwo-api-calls/rule/updateRuleRefs.graphql b/roles/common/files/fwo-api-calls/rule/updateRuleRefs.graphql new file mode 100644 index 0000000000..1a5d99372e --- /dev/null +++ b/roles/common/files/fwo-api-calls/rule/updateRuleRefs.graphql @@ -0,0 +1,88 @@ +mutation updateRuleRefs( + $importId: bigint! + $ruleFroms: [rule_from_bool_exp!]! + $ruleTos: [rule_to_bool_exp!]! + $ruleServices: [rule_service_bool_exp!]! + $ruleNwObjResolveds: [rule_nwobj_resolved_bool_exp!] + $ruleSvcResolveds: [rule_svc_resolved_bool_exp!]! + $ruleUserResolveds: [rule_user_resolved_bool_exp!]! + $ruleFromZones: [rule_from_zone_bool_exp!] + $ruleToZones: [rule_to_zone_bool_exp!] + $ruleTimes: [rule_time_bool_exp!] +) { + update_rule_from(where: { + _or: $ruleFroms + removed: {_is_null: true} + }, _set: { + removed: $importId + active: false + }) { + affected_rows + } + update_rule_to(where: { + _or: $ruleTos + removed: {_is_null: true} + }, _set: { + removed: $importId + active: false + }) { + affected_rows + } + update_rule_service(where: { + _or: $ruleServices + removed: {_is_null: true} + }, _set: { + removed: $importId + active: false + }) { + affected_rows + } + update_rule_nwobj_resolved(where: { + _or: $ruleNwObjResolveds + removed: {_is_null: true} + }, _set: { + removed: $importId + }) { + affected_rows + } + update_rule_svc_resolved(where: { + _or: $ruleSvcResolveds + removed: {_is_null: true} + }, _set: { + removed: $importId + }) { + affected_rows + } + update_rule_user_resolved(where: { + _or: $ruleUserResolveds + removed: {_is_null: true} + }, _set: { + removed: $importId + }) { + affected_rows + } + update_rule_from_zone(where: { + _or: $ruleFromZones + removed: {_is_null: true} + }, _set: { + removed: $importId + }) { + affected_rows + } + update_rule_to_zone(where: { + _or: $ruleToZones + removed: {_is_null: true} + }, _set: { + removed: $importId + }) { + affected_rows + } + update_rule_time(where: { + _or: $ruleTimes + removed: {_is_null: true} + }, _set: { + removed: $importId + }) { + affected_rows + } +} \ No newline at end of file diff --git a/roles/common/files/fwo-api-calls/rule_metadata/updateLastHits.graphql b/roles/common/files/fwo-api-calls/rule_metadata/updateLastHits.graphql new file mode 100644 index 0000000000..6b788c7847 --- /dev/null +++ b/roles/common/files/fwo-api-calls/rule_metadata/updateLastHits.graphql @@ -0,0 +1,6 @@ +mutation updateLasthits($hit_info: [rule_metadata_updates!]!) { + update_rule_metadata_many(updates: $hit_info) { + affected_rows + returning { rule_uid } + } +} diff --git a/roles/common/files/fwo-api-calls/rulebase/getMapOfUid2Id.graphql b/roles/common/files/fwo-api-calls/rulebase/getMapOfUid2Id.graphql new file mode 100644 index 0000000000..7fa72c95a8 --- /dev/null +++ b/roles/common/files/fwo-api-calls/rulebase/getMapOfUid2Id.graphql @@ -0,0 +1,13 @@ +query getMapOfUid2Id($uids: [String!], $mgmId: Int!) { + rulebase(where: { + uid: {_in: $uids}, + _or: [ + {mgm_id: {_eq: $mgmId}}, + {management: {multi_device_manager_id: {_eq: $mgmId}}} + ], + removed: {_is_null: true} + }) { + id + uid + } +} diff --git a/roles/common/files/fwo-api-calls/stmTables/getColors.graphql b/roles/common/files/fwo-api-calls/stmTables/getColors.graphql new file mode 100644 index 0000000000..567c03bd5d --- /dev/null +++ b/roles/common/files/fwo-api-calls/stmTables/getColors.graphql @@ -0,0 +1,7 @@ + +query getColors { + stm_color { + color_id + color_name + } +} diff --git a/roles/lib/files/FWO.Api.Client/APIcalls/stmTables/getIpProtocols.graphql b/roles/common/files/fwo-api-calls/stmTables/getIpProtocols.graphql similarity index 100% rename from roles/lib/files/FWO.Api.Client/APIcalls/stmTables/getIpProtocols.graphql rename to roles/common/files/fwo-api-calls/stmTables/getIpProtocols.graphql diff --git a/roles/lib/files/FWO.Api.Client/APIcalls/stmTables/getRuleActions.graphql b/roles/common/files/fwo-api-calls/stmTables/getRuleActions.graphql similarity index 100% rename from roles/lib/files/FWO.Api.Client/APIcalls/stmTables/getRuleActions.graphql rename to roles/common/files/fwo-api-calls/stmTables/getRuleActions.graphql diff --git a/roles/lib/files/FWO.Api.Client/APIcalls/stmTables/getTracking.graphql b/roles/common/files/fwo-api-calls/stmTables/getTracking.graphql similarity index 100% rename from roles/lib/files/FWO.Api.Client/APIcalls/stmTables/getTracking.graphql rename to roles/common/files/fwo-api-calls/stmTables/getTracking.graphql diff --git a/roles/common/files/fwo-api-calls/time/getMapOfUid2Id.graphql b/roles/common/files/fwo-api-calls/time/getMapOfUid2Id.graphql new file mode 100644 index 0000000000..f755bbbfac --- /dev/null +++ b/roles/common/files/fwo-api-calls/time/getMapOfUid2Id.graphql @@ -0,0 +1,15 @@ +query getMapOfUid2Id($uids: [String!], $mgmId: Int!) { + time_object( + where: { + time_obj_uid: { _in: $uids } + _or: [ + { mgm_id: { _eq: $mgmId } } + { management: { multi_device_manager_id: { _eq: $mgmId } } } + ] + removed: { _is_null: true } + } + ) { + time_obj_id + time_obj_uid + } +} diff --git a/roles/common/files/fwo-api-calls/time/upsertTimeObjects.graphql b/roles/common/files/fwo-api-calls/time/upsertTimeObjects.graphql new file mode 100644 index 0000000000..bbe0aebf21 --- /dev/null +++ b/roles/common/files/fwo-api-calls/time/upsertTimeObjects.graphql @@ -0,0 +1,24 @@ +mutation upsertTimeObjects( + $mgmId: Int! + $importId: bigint! + $removedTimeObjectIds: [bigint!]! + $newTimeObjects: [time_object_insert_input!]! +) { + update_time_object( + where: { + mgm_id: { _eq: $mgmId } + time_obj_id: { _in: $removedTimeObjectIds } + removed: { _is_null: true } + } + _set: { removed: $importId } + ) { + affected_rows + } + insert_time_object(objects: $newTimeObjects) { + affected_rows + returning { + time_obj_id + time_obj_uid + } + } +} diff --git a/roles/common/files/fwo-api-calls/user/fragments/userDetails.graphql b/roles/common/files/fwo-api-calls/user/fragments/userDetails.graphql new file mode 100644 index 0000000000..06f83fb9d9 --- /dev/null +++ b/roles/common/files/fwo-api-calls/user/fragments/userDetails.graphql @@ -0,0 +1,46 @@ +fragment userDetails on usr { + user_id + user_uid + user_create + user_create_time: import_control { + time: start_time + } + user_last_seen + user_name + user_comment + user_lastname + user_firstname + usr_typ_id + type: stm_usr_typ { + usr_typ_name + } + user_member_names + user_member_refs + usergrps(order_by: { usergrp_member_id: asc }) { + id: usergrp_id + byId: usrByUsergrpMemberId { + user_id + user_name + type: stm_usr_typ { + usr_typ_name + } + } + } + usergrp_flats(where: { + active: { _eq: $active } + import_created: { _lte: $import_id_end } + _or: [ + { removed: { _is_null: true } } + { removed: { _gt:$import_id_start } } + ] + } order_by: { usergrp_flat_member_id: asc }) { + flat_id: usergrp_flat_id + byFlatId: usrByUsergrpFlatMemberId { + user_id + user_name + type: stm_usr_typ { + usr_typ_name + } + } + } +} diff --git a/roles/common/files/fwo-api-calls/user/fragments/userDetailsChangesNew.graphql b/roles/common/files/fwo-api-calls/user/fragments/userDetailsChangesNew.graphql new file mode 100644 index 0000000000..5897fe1704 --- /dev/null +++ b/roles/common/files/fwo-api-calls/user/fragments/userDetailsChangesNew.graphql @@ -0,0 +1,53 @@ +fragment userDetailsChangesNew on usr { + user_id + user_uid + user_create + user_create_time: import_control { + time: start_time + } + user_last_seen + user_name + user_comment + user_lastname + user_firstname + usr_typ_id + type: stm_usr_typ { + usr_typ_name + } + user_member_names + user_member_refs + usergrps(where: { + active: { _eq: $active } + import_created: { _lte: $import_id_new } + _or: [ + { removed: { _is_null: true } } + { removed: { _gt: $import_id_new } } + ] + } order_by: { usergrp_member_id: asc }) { + id: usergrp_id + byId: usrByUsergrpMemberId { + user_id + user_name + type: stm_usr_typ { + usr_typ_name + } + } + } + usergrp_flats(where: { + active: { _eq: $active } + import_created: { _lte: $import_id_new } + _or: [ + { removed: { _is_null: true } } + { removed: { _gt: $import_id_new } } + ] + } order_by: { usergrp_flat_member_id: asc }) { + flat_id: usergrp_flat_id + byFlatId: usrByUsergrpFlatMemberId { + user_id + user_name + type: stm_usr_typ { + usr_typ_name + } + } + } +} diff --git a/roles/common/files/fwo-api-calls/user/fragments/userDetailsChangesOld.graphql b/roles/common/files/fwo-api-calls/user/fragments/userDetailsChangesOld.graphql new file mode 100644 index 0000000000..3cbac357cd --- /dev/null +++ b/roles/common/files/fwo-api-calls/user/fragments/userDetailsChangesOld.graphql @@ -0,0 +1,53 @@ +fragment userDetailsChangesOld on usr { + user_id + user_uid + user_create + user_create_time: import_control { + time: start_time + } + user_last_seen + user_name + user_comment + user_lastname + user_firstname + usr_typ_id + type: stm_usr_typ { + usr_typ_name + } + user_member_names + user_member_refs + usergrps(where: { + active: { _eq: $active } + import_created: { _lte: $import_id_old } + _or: [ + { removed: { _is_null: true } } + { removed: { _gt: $import_id_old } } + ] + } order_by: { usergrp_member_id: asc }) { + id: usergrp_id + byId: usrByUsergrpMemberId { + user_id + user_name + type: stm_usr_typ { + usr_typ_name + } + } + } + usergrp_flats(where: { + active: { _eq: $active } + import_created: { _lte: $import_id_old } + _or: [ + { removed: { _is_null: true } } + { removed: { _gt: $import_id_old } } + ] + } order_by: { usergrp_flat_member_id: asc }) { + flat_id: usergrp_flat_id + byFlatId: usrByUsergrpFlatMemberId { + user_id + user_name + type: stm_usr_typ { + usr_typ_name + } + } + } +} diff --git a/roles/lib/files/FWO.Api.Client/APIcalls/user/fragments/userOverview.graphql b/roles/common/files/fwo-api-calls/user/fragments/userOverview.graphql similarity index 100% rename from roles/lib/files/FWO.Api.Client/APIcalls/user/fragments/userOverview.graphql rename to roles/common/files/fwo-api-calls/user/fragments/userOverview.graphql diff --git a/roles/common/files/fwo-api-calls/user/getMapOfUid2Id.graphql b/roles/common/files/fwo-api-calls/user/getMapOfUid2Id.graphql new file mode 100644 index 0000000000..29b394d835 --- /dev/null +++ b/roles/common/files/fwo-api-calls/user/getMapOfUid2Id.graphql @@ -0,0 +1,13 @@ +query getMapOfUid2Id($uids: [String!], $mgmId: Int!) { + usr(where: { + user_uid: {_in: $uids}, + _or: [ + {mgm_id: {_eq: $mgmId}}, + {management: {multi_device_manager_id: {_eq: $mgmId}}} + ], + removed: {_is_null: true} + }) { + user_id + user_uid + } +} diff --git a/roles/common/files/fwo-api-calls/user/getUserDetails.graphql b/roles/common/files/fwo-api-calls/user/getUserDetails.graphql new file mode 100644 index 0000000000..acdda0f284 --- /dev/null +++ b/roles/common/files/fwo-api-calls/user/getUserDetails.graphql @@ -0,0 +1,30 @@ +query getUserDetails( + $management_id: [Int!] + $active: Boolean + $import_id_start: bigint + $import_id_end: bigint + $user_name: [String!] + $limit: Int + $offset: Int +) { + management(where: { mgm_id: { _in: $management_id }, stm_dev_typ:{dev_typ_is_multi_mgmt:{_eq:false}} }) { + id: mgm_id + name: mgm_name + userObjects: usrs( + limit: $limit + offset: $offset + where: { + _or: [ + { removed: { _is_null: true } } + { removed: { _gte: $import_id_start } } + ] + active: { _eq: $active } + user_create: { _lte: $import_id_end } + user_name: { _in: $user_name } + } + order_by: [{ user_name: asc }, { user_id: asc }] + ) { + ...userDetails + } + } +} diff --git a/roles/common/files/fwo-api-calls/zone/getMapOfName2Id.graphql b/roles/common/files/fwo-api-calls/zone/getMapOfName2Id.graphql new file mode 100644 index 0000000000..bc7f268a6b --- /dev/null +++ b/roles/common/files/fwo-api-calls/zone/getMapOfName2Id.graphql @@ -0,0 +1,13 @@ +query getMapOfName2Id($names: [String!], $mgmId: Int!) { + zone(where: { + zone_name: {_in: $names}, + _or: [ + {mgm_id: {_eq: $mgmId}}, + {management: {multi_device_manager_id: {_eq: $mgmId}}} + ], + removed: {_is_null: true} + }) { + zone_id + zone_name + } +} diff --git a/roles/common/files/maintenance-info.html b/roles/common/files/maintenance-info.html new file mode 100644 index 0000000000..f31b9ebf93 --- /dev/null +++ b/roles/common/files/maintenance-info.html @@ -0,0 +1,39 @@ + + + + + + Under Maintenance + + + +
+

Firewall Orchestrator is under maintenance

+

Sorry for the inconvenience. Please try again in 10 minutes.

+ Maintenance Image +
+ + diff --git a/roles/common/files/men-at-work.png b/roles/common/files/men-at-work.png new file mode 100644 index 0000000000..4885360cba Binary files /dev/null and b/roles/common/files/men-at-work.png differ diff --git a/roles/common/tasks/conf_file_creator.yml b/roles/common/tasks/conf_file_creator.yml index 0032108159..634250ccb7 100644 --- a/roles/common/tasks/conf_file_creator.yml +++ b/roles/common/tasks/conf_file_creator.yml @@ -1,18 +1,5 @@ - block: - - name: fetch remote config file - fetch: - src: "{{ fworch_conf_file }}" - dest: "temp_remote_config_file.json" - flat: true - when: already_installed and installation_mode == "upgrade" - - - name: read config file of currently installed product - include_vars: - file: "temp_remote_config_file.json" - name: config - when: already_installed and installation_mode == "upgrade" - - name: remove local copy of remote config file file: state: absent @@ -24,11 +11,6 @@ dest: "/etc/{{ product_name }}" state: link - - name: get version of currently installed product - set_fact: - old_version: "{{ config.product_version }}" - when: already_installed and installation_mode == "upgrade" - - name: set config values set_fact: config_json: @@ -39,6 +21,7 @@ api_hasura_jwt_alg: "{{ api_hasura_jwt_alg }}" middleware_native_uri: "http://{{ middleware_hostname }}:{{ middleware_internal_port }}/" middleware_uri: "{{ middleware_uri }}" + remote_addresses: [] - name: create central conf file by dumping varibale as json file copy: diff --git a/roles/common/tasks/global-apache2-config.yml b/roles/common/tasks/global-apache2-config.yml new file mode 100644 index 0000000000..b95d55b9f2 --- /dev/null +++ b/roles/common/tasks/global-apache2-config.yml @@ -0,0 +1,55 @@ +- name: install apache and make all global configs (non-server dependent) + block: + - name: Install apache2 and wsgi module + package: + name: "{{ item }}" + state: present + update_cache: yes + loop: + - "{{ webserver_package_name }}" + - "{{ wsgi_package_name }}" + + - name: edit conf file for global security settings - ServerTokens + lineinfile: + path: "{{ apache_global_settings_file }}" + line: ServerTokens Prod + regexp: '^\s*ServerTokens' + create: true + mode: "0644" + + - name: edit conf file for global security settings - ServerSignature + lineinfile: + path: "{{ apache_global_settings_file }}" + line: ServerSignature Off + regexp: '^\s*ServerSignature' + create: true + mode: "0644" + + - name: edit conf file for global security settings - TraceEnable + lineinfile: + path: "{{ apache_global_settings_file }}" + line: TraceEnable Off + regexp: '^\s*TraceEnable' + create: true + mode: "0644" + + - name: enable global security settings + command: "a2enconf security" + + - name: remove duplicate FWO custom apache listener lines during upgrade + lineinfile: + path: /etc/apache2/ports.conf + regexp: '^\s*Listen {{ item }}\s*$' + state: absent + loop: + - "{{ middleware_web_listener_port }}" + - "{{ api_web_port }}" + when: installation_mode == "upgrade" + + - name: restart apache + service: + name: "{{ webserver_package_name }}" + state: restarted + when: installation_mode != "upgrade" + + become: true diff --git a/roles/common/tasks/install-api-calls.yml b/roles/common/tasks/install-api-calls.yml new file mode 100644 index 0000000000..8551acb515 --- /dev/null +++ b/roles/common/tasks/install-api-calls.yml @@ -0,0 +1,19 @@ + +# this coppies all graphql queries and mutations to the server +# for use with UI, MW and importer +- name: ensure the fwo api calls destination directory is owned by fworch + file: + path: "{{ fworch_home }}/fwo-api-calls" + state: directory + owner: "{{ fworch_user }}" + group: "{{ fworch_group }}" + mode: "0755" + become: true + +- name: install the fwo api calls + synchronize: + src: "fwo-api-calls" + dest: "{{ fworch_home }}" + rsync_opts: + - "--chown={{ fworch_user }}:{{ fworch_group }}" + become: true diff --git a/roles/common/tasks/install_syslog.yml b/roles/common/tasks/install_syslog.yml index 4606ea5a93..da850574d0 100644 --- a/roles/common/tasks/install_syslog.yml +++ b/roles/common/tasks/install_syslog.yml @@ -75,11 +75,11 @@ if $programname == '{{ ui_syslog_id }}' then action(type="omfile" file="{{ fworch_log_dir }}/ui.log" template="fworch") if $programname == '{{ ldap_syslog_id }}' then action(type="omfile" file="{{ fworch_log_dir }}/ldap.log" template="fworch") if $programname == '{{ product_name }}-api' then action(type="omfile" file="{{ fworch_log_dir }}/api.log" template="fworch") - if $programname startswith '{{ product_name }}-importer-legacy' then action(type="omfile" file="{{ fworch_log_dir }}/importer-legacy.log" template="fworch") if $programname startswith '{{ product_name }}-importer-api' then action(type="omfile" file="{{ fworch_log_dir }}/importer-api.log" template="fworch") if $programname startswith '{{ product_name }}' and $msg contains "Audit" then action(type="omfile" file="{{ fworch_log_dir }}/audit.log" template="fworch") if $programname startswith '{{ product_name }}' and $msg contains "FWORCHAlert" then action(type="omfile" file="{{ fworch_log_dir }}/alert.log" template="fworch") if $programname == '{{ product_name }}-webhook' then action(type="omfile" file="{{ fworch_log_dir }}/webhook.log" template="fworch") + if $programname == 'import-fworch-app-data' then action(type="omfile" file="{{ fworch_log_dir }}/import-fworch-app-data.log" template="fworch") become: true - name: edit logrotate @@ -119,7 +119,10 @@ endscript } - {{ fworch_log_dir }}/importer-legacy.log { + {{ fworch_log_dir }}/database.log + {{ fworch_log_dir }}/ldap.log + {{ fworch_log_dir }}/api.log + {{ fworch_log_dir }}/importer-api.log { compress maxage 7 rotate 99 @@ -128,17 +131,12 @@ copytruncate sharedscripts prerotate - systemctl stop {{ product_name }}-importer-legacy.service >/dev/null 2>&1 + {{ fworch_home }}/scripts/acquire_lock.py {{ fworch_api_importer_lockfile }} >/dev/null 2>&1 endscript postrotate - systemctl start {{ product_name }}-importer-legacy.service >/dev/null 2>&1 + {{ fworch_home }}/scripts/release_lock.py {{ fworch_api_importer_lockfile }} >/dev/null 2>&1 endscript } - - {{ fworch_log_dir }}/database.log - {{ fworch_log_dir }}/ldap.log - {{ fworch_log_dir }}/api.log - {{ fworch_log_dir }}/importer-api.log {{ fworch_log_dir }}/audit.log {{ fworch_log_dir }}/alert.log {{ fworch_log_dir }}/webhook.log diff --git a/roles/common/tasks/last_commit_id_file_creator.yml b/roles/common/tasks/last_commit_id_file_creator.yml new file mode 100644 index 0000000000..22cee7131b --- /dev/null +++ b/roles/common/tasks/last_commit_id_file_creator.yml @@ -0,0 +1,23 @@ +- block: + - name: remove local copy of remote config file + file: + state: absent + name: "temp_remote_config_file.json" + + - name: get last commit id + command: git rev-parse HEAD + register: final_commit_id + failed_when: false + changed_when: false + + # also handle case where we are not inside a git repo + - name: determine commit id content + set_fact: + final_commit_id_value: "{{ final_commit_id.stdout if final_commit_id.rc == 0 else 'unknown' }}" + + - name: write commit id to last_commit_id.txt file + copy: + content: "{{ final_commit_id_value }}" + dest: "{{ last_commit_id_file_path }}" + + become: true diff --git a/roles/common/tasks/main.yml b/roles/common/tasks/main.yml index 7af3c09960..68f4b8135d 100644 --- a/roles/common/tasks/main.yml +++ b/roles/common/tasks/main.yml @@ -1,53 +1,14 @@ - - block: +- name: uninstall product + include_tasks: uninstall.yml + when: "installation_mode == 'uninstall'" - - name: assert ansible version +# only when not uninstalling ... +- block: + # check installation mode + - name: assert ansible version gt 2.12 fail: - msg: Ansible 2.8 or above is required - when: ansible_version.full is version('2.8', '<') - - - name: update operating system package cache .deb based - apt: - update_cache: true - when: ansible_facts['distribution'] == "Ubuntu" or ansible_facts['distribution'] == "Debian" - - - name: check for existing upgradable packages - command: apt list --upgradable - register: upgradable_packages - when: ansible_facts['distribution'] == "Ubuntu" or ansible_facts['distribution'] == "Debian" - - - block: - - debug: - msg: "current number of upgradable packages: {{ upgradable_packages.stdout_lines|length-1 }}" - - - name: assert there are no upgradable packages. upgrades must be run interactively outside the FWORCH installer - fail: - msg: - - There are upgradable OS packages available, please run OS upgrade before running FWORCH installer. - - Use "-e force_install=true" to overwrite this check and install anyway at your own risk. - when: | - (ansible_facts['distribution'] == "Ubuntu" or ansible_facts['distribution'] == "Debian") - and upgradable_packages.stdout_lines|length > 1 - - when: not force_install|bool and not run_on_github|bool - - - name: update operating system packages .deb based (for github actions or enforced run) - apt: - upgrade: dist - update_cache: true - when: ansible_facts['distribution'] == "Ubuntu" or ansible_facts['distribution'] == "Debian" and run_on_github|bool - - - name: update operating system packages .rpm based (untested) - yum: - upgrade: dist - when: ansible_facts['distribution'] == "Red Hat" or ansible_facts['distribution'] == "CentOS" - - - name: install packages rsync, acl (for non-root user in ansible) - package: - name: "{{ item }}" - state: present - loop: - - rsync - - acl + msg: Ansible 2.13 or above is required + when: ansible_version.full is version('2.13', '<') - name: check for existing main config file {{ fworch_conf_file }} stat: @@ -56,10 +17,19 @@ - set_fact: already_installed: "{{ already_installed.stat.exists }}" - + + - set_fact: + wsgi_package_name: "{{ wsgi_package_name }}-py3" + when: | + (ansible_facts['distribution_release']|lower == debian_testing_release_name) + or + (ansible_facts['distribution']|lower == 'debian' and ansible_facts['distribution_major_version']|int is version('10', '>')) + or + (ansible_facts['distribution']|lower == 'ubuntu' and ansible_facts['distribution_major_version']|int is version('20', '>')) + - debug: msg: "installation_mode={{ installation_mode }}, already_installed={{ already_installed }}" - + - name: fail if unknown installation_mode is set fail: msg: "Found undefined installation_mode: {{ installation_mode }}, aborting." @@ -75,12 +45,33 @@ msg: "Could not find existing installation but running with installation_mode set to {{ installation_mode }}. Try running with installation_mode=new" when: not already_installed and installation_mode == "upgrade" + # when upgrading check if we are not attempting a downgrade + - block: + - name: fetch remote config file + fetch: + src: "{{ fworch_conf_file }}" + dest: "temp_remote_config_file.json" + flat: true + + - name: read config file of currently installed product + include_vars: + file: "temp_remote_config_file.json" + name: config + + - name: get version of currently installed product + set_fact: + old_version: "{{ config.product_version }}" + product_version_changed: "{{ config.product_version != product_version }}" + + when: already_installed and installation_mode == "upgrade" + - name: create group {{ fworch_group }} group: name: "{{ fworch_user }}" gid: "{{ user_id }}" state: present - + become: true + - name: add user {{ fworch_user }} user: name: "{{ fworch_user }}" @@ -92,10 +83,256 @@ generate_ssh_key: true ssh_key_bits: 4096 ssh_key_file: .ssh/id_rsa + become: true - - name: include redhat install basics - include_tasks: redhat_preps.yml - when: installation_mode == "new" and ansible_os_family == "RedHat" + - name: ensure subordinate id files exist + copy: + content: "" + dest: "{{ item }}" + force: false + mode: "0644" + loop: + - /etc/subuid + - /etc/subgid + become: true + + - name: check existing subordinate uid entry for {{ fworch_user }} + command: + argv: + - grep + - -E + - "^{{ fworch_user }}:[0-9]+:[0-9]+$" + - /etc/subuid + register: fworch_subuid_entry + changed_when: false + failed_when: false + become: true + + - name: check existing subordinate gid entry for {{ fworch_user }} + command: + argv: + - grep + - -E + - "^{{ fworch_user }}:[0-9]+:[0-9]+$" + - /etc/subgid + register: fworch_subgid_entry + changed_when: false + failed_when: false + become: true + + - name: fail if subordinate uid lookup failed unexpectedly + fail: + msg: "Failed to read existing subordinate uid entry for {{ fworch_user }} from /etc/subuid." + when: + - fworch_subuid_entry.rc not in [0, 1] + + - name: fail if subordinate gid lookup failed unexpectedly + fail: + msg: "Failed to read existing subordinate gid entry for {{ fworch_user }} from /etc/subgid." + when: + - fworch_subgid_entry.rc not in [0, 1] + + - name: fail if multiple subordinate uid entries exist for {{ fworch_user }} + fail: + msg: >- + Found multiple subordinate uid entries for {{ fworch_user }} in /etc/subuid: + {{ fworch_subuid_entry.stdout_lines | join(', ') }}. + Please remove duplicate entries before running the installer again. + when: + - fworch_subuid_entry.rc == 0 + - fworch_subuid_entry.stdout_lines | length > 1 + + - name: fail if multiple subordinate gid entries exist for {{ fworch_user }} + fail: + msg: >- + Found multiple subordinate gid entries for {{ fworch_user }} in /etc/subgid: + {{ fworch_subgid_entry.stdout_lines | join(', ') }}. + Please remove duplicate entries before running the installer again. + when: + - fworch_subgid_entry.rc == 0 + - fworch_subgid_entry.stdout_lines | length > 1 + + - name: determine next free subordinate uid range start + command: + argv: + - awk + - "-F:" + - -v + - min_start={{ fworch_subid_range_start_min }} + - | + BEGIN { max_end = min_start } + NF >= 3 { + start = $2 + 0 + count = $3 + 0 + end = start + count + if (end > max_end) max_end = end + } + END { print max_end } + - /etc/subuid + register: fworch_next_subuid_start + changed_when: false + become: true + when: + - fworch_subuid_entry.rc != 0 + + - name: determine next free subordinate gid range start + command: + argv: + - awk + - "-F:" + - -v + - min_start={{ fworch_subid_range_start_min }} + - | + BEGIN { max_end = min_start } + NF >= 3 { + start = $2 + 0 + count = $3 + 0 + end = start + count + if (end > max_end) max_end = end + } + END { print max_end } + - /etc/subgid + register: fworch_next_subgid_start + changed_when: false + become: true + when: + - fworch_subgid_entry.rc != 0 + + - name: define subordinate id entries for {{ fworch_user }} + set_fact: + fworch_subuid_line: >- + {{ + fworch_subuid_entry.stdout_lines[0] + if fworch_subuid_entry.rc == 0 else + fworch_user ~ ':' ~ fworch_next_subuid_start.stdout ~ ':' ~ fworch_subid_range_size + }} + fworch_subgid_line: >- + {{ + fworch_subgid_entry.stdout_lines[0] + if fworch_subgid_entry.rc == 0 else + fworch_user ~ ':' ~ fworch_next_subgid_start.stdout ~ ':' ~ fworch_subid_range_size + }} + + - name: add subordinate uid entry for {{ fworch_user }} + lineinfile: + path: /etc/subuid + regexp: "^{{ fworch_user }}:" + line: "{{ fworch_subuid_line }}" + create: true + become: true + + - name: add subordinate gid entry for {{ fworch_user }} + lineinfile: + path: /etc/subgid + regexp: "^{{ fworch_user }}:" + line: "{{ fworch_subgid_line }}" + create: true + become: true + + - name: check whether loginctl is available + stat: + path: /usr/bin/loginctl + register: loginctl_binary + become: true + + - name: enable lingering for {{ fworch_user }} + command: + argv: + - loginctl + - enable-linger + - "{{ fworch_user }}" + creates: "/var/lib/systemd/linger/{{ fworch_user }}" + register: fworch_enable_linger + changed_when: fworch_enable_linger.rc == 0 + failed_when: false + become: true + when: + - ansible_service_mgr == "systemd" + - loginctl_binary.stat.exists + + - name: global apache config + include_tasks: global-apache2-config.yml + # vars: + # apache2_required_modules: "{{ apache2_required_modules | default([]) }}" + # webserver_package_name: "{{ webserver_package_name | default('apache2') }}" + # http_conf_dir: "{{ http_conf_dir | default('/etc/apache2/sites-available') }}" + # product_name: "{{ product_name }}" + # product_version: "{{ product_version }}" + # api_web_port: "{{ api_web_port | default(8080) }}" + # server_admin: "{{ server_admin | default('webmaster@localhost') }}" + # apache_global_settings_file: "{{ apache_global_settings_file | default('/etc/apache2/conf-available/security.conf') }}" + when: "inventory_hostname in groups['frontends'] or inventory_hostname in groups['middlewareserver'] or inventory_hostname in groups['apiserver']" + + - name: replace fwo web sites with maintenance site + include_tasks: maintenance-site.yml + when: "installation_mode == 'upgrade' and inventory_hostname in groups['frontends']" + + - name: stop fw importer service before making any changes + systemd: + name: "{{ product_name }}-importer-api" + state: stopped + become: true + when: "inventory_hostname in groups['importers'] and installation_mode == 'upgrade'" + + - name: stop importer service before making any changes + systemd: + name: "{{ product_name }}-importer-api" + state: stopped + become: true + ignore_errors: true # might not have been installed yet in case of early fail installs + when: "inventory_hostname in groups['importers'] and installation_mode == 'uninstall'" + + - name: update operating system package cache .deb based + apt: + update_cache: true + when: ansible_facts['distribution'] == "Ubuntu" or ansible_facts['distribution'] == "Debian" + + - name: check for existing upgradable packages + command: apt list --upgradable + register: upgradable_packages + when: ansible_facts['distribution'] == "Ubuntu" or ansible_facts['distribution'] == "Debian" + + - block: + - debug: + msg: "current number of upgradable packages: {{ upgradable_packages.stdout_lines|length-1 }}" + + - block: + - name: disable apache2 maintenance web site + command: "a2dissite {{ product_name }}-maintenance" + ignore_errors: true + + - name: enable {{ product_name }} web site + command: "a2ensite {{ product_name }}-ui" + ignore_errors: true + + - name: restart apache without maintenance site + service: + name: "{{ webserver_package_name }}" + state: restarted + when: installation_mode == "upgrade" + + - name: assert there are no upgradable packages. upgrades must be run interactively outside the FWORCH installer + fail: + msg: + - There are upgradable OS packages available, please run OS upgrade before running FWORCH installer. + - Use "-e force_install=true" to overwrite this check and install anyway at your own risk. + when: | + not force_install|bool and + (ansible_facts['distribution'] == "Ubuntu" or ansible_facts['distribution'] == "Debian") and + upgradable_packages.stdout_lines|length > 1 + + - name: update operating system packages .rpm based (untested) + yum: + upgrade: dist + when: ansible_facts['distribution'] == "Red Hat" or ansible_facts['distribution'] == "CentOS" + + - name: install packages rsync, acl (for non-root user in ansible) + package: + name: "{{ item }}" + state: present + loop: + - rsync + - acl - name: create var lock directory file: @@ -105,25 +342,6 @@ group: "{{ fworch_group }}" mode: "0775" - - name: create scripts directory - file: - path: "{{ fworch_home }}/scripts" - state: directory - owner: "{{ fworch_user }}" - group: "{{ fworch_group }}" - mode: "0775" - - - name: copy log lock scripts - copy: - src: "{{ item }}" - dest: "{{ fworch_home }}/scripts/" - mode: "0755" - owner: "{{ fworch_user}}" - group: "{{ fworch_user}}" - loop: - - acquire_lock.py - - release_lock.py - - name: install rsyslog import_tasks: install_syslog.yml when: "install_syslog | bool" @@ -136,6 +354,32 @@ group: "{{ fworch_group }}" mode: "0775" + - name: copy fworch scripts directory + synchronize: + src: scripts + dest: "{{ fworch_home }}" + rsync_opts: + - "--chown={{ fworch_user }}:{{ fworch_group }}" + become: true + + - name: check existence of scripts that need to be executable + stat: + path: "{{ fworch_home }}/scripts/{{ item }}" + loop: + - customizing/app_data_import/get_owner_data3_from_normalized_csvs.py + - customizing/area_ip_data_import/convertNwObjDataFromGit.py + - customizing/iiq_request_missing_roles/iiq_request_missing_fwmgt_roles.py + - acquire_lock.py + - release_lock.py + register: fworch_script_stats + + - name: set scripts to executable where needed + file: + path: "{{ fworch_home }}/scripts/{{ item.item }}" + mode: "0755" + loop: "{{ fworch_script_stats.results }}" + when: item.stat.exists + - name: add proxy setting to fworch users .profile and .bashrc blockinfile: path: "{{ fworch_home }}/{{ item }}" @@ -156,38 +400,82 @@ state: directory owner: "{{ fworch_user }}" group: "{{ fworch_group }}" - mode: '0755' + mode: "0755" - name: create dir for passwords file: path: "{{ fworch_home }}/etc/secrets" state: directory owner: "{{ fworch_user }}" + group: "{{ fworch_user }}" + # group: "{{ postgres_group }}" # group does not exist yet during install, created in role database + mode: "0750" + when: "installation_mode == 'new'" + + - name: check importer password file exists + stat: + path: "{{ importer_password_file }}" + register: importer_pwd_stat + when: "installation_mode == 'new' and inventory_hostname in groups['middlewareserver']" + + - name: set importer password for secrets file + set_fact: + importer_password: "{{ randomly_generated_pwd }}" + when: "installation_mode == 'new' and inventory_hostname in groups['middlewareserver'] and not importer_pwd_stat.stat.exists" + + - name: write importer password to secrets directory + copy: + content: "{{ importer_password }}\n" + dest: "{{ importer_password_file }}" + mode: "0600" + owner: "{{ fworch_user }}" group: "{{ fworch_group }}" - mode: '0700' + become: true + when: "installation_mode == 'new' and inventory_hostname in groups['middlewareserver'] and not importer_pwd_stat.stat.exists" - - set_fact: - wsgi_package_name: "{{ wsgi_package_name }}-py3" - when: | - (ansible_facts['distribution_release']|lower == debian_testing_release_name) - or - (ansible_facts['distribution']|lower == 'debian' and ansible_facts['distribution_major_version']|int is version('10', '>')) - or - (ansible_facts['distribution']|lower == 'ubuntu' and ansible_facts['distribution_major_version']|int is version('20', '>')) + - name: generate main key + set_fact: + main_key: "{{ randomly_generated_pwd }}" # 32 bytes + main_key_file: "{{ fworch_secrets_dir }}/main_key" + when: testkeys is not defined or testkeys|bool is false + + - name: set static main key for test purposes only + set_fact: + main_key: "{{ api_hasura_admin_test_password }}..{{ api_hasura_admin_test_password }}.." # to have 32 bytes + main_key_file: "{{ fworch_secrets_dir }}/main_key" + when: testkeys is defined and testkeys|bool - - name: copy iso.conf to target - template: - src: iso.conf.j2 - dest: "{{ fworch_home }}/etc/iso.conf" + - name: Check if main key file exists + stat: + path: "{{ main_key_file }}" + register: stat_result + + - name: write main key to secrets directory + copy: + content: "{{ main_key }}\n" + dest: "{{ main_key_file }}" + mode: "0640" owner: "{{ fworch_user }}" group: "{{ fworch_group }}" + become: true + when: not stat_result.stat.exists + + - name: include fwo api call installer + import_tasks: install-api-calls.yml + + - name: include upgrade script + import_tasks: run-upgrades.yml + when: "installation_mode == 'upgrade'" - name: include fworch.yaml config file creator import_tasks: conf_file_creator.yml + - name: include last_commit_id.txt file creator + import_tasks: last_commit_id_file_creator.yml + - name: include upgrade script import_tasks: run-upgrades.yml when: "installation_mode == 'upgrade'" - become: true - \ No newline at end of file + become: true + when: "installation_mode != 'uninstall'" diff --git a/roles/common/tasks/maintenance-site.yml b/roles/common/tasks/maintenance-site.yml new file mode 100644 index 0000000000..f94dc47d29 --- /dev/null +++ b/roles/common/tasks/maintenance-site.yml @@ -0,0 +1,52 @@ +- block: + + - name: create maint website dir + file: + path: "/var/www/html/" + state: directory + mode: "0755" + owner: "{{ fworch_user }}" + group: "{{ fworch_group }}" + + - name: copy maintenance web site index + copy: + src: maintenance-info.html + dest: "/var/www/html/index.html" + mode: "0644" + + - name: copy maintenance web site image + copy: + src: men-at-work.png + dest: "/var/www/html/men-at-work.png" + mode: "0644" + + - name: disable existing FWO apache sites before maintenance switch + command: "a2dissite {{ item }}" + loop: + - "{{ product_name }}-ui" + - "{{ product_name }}-api" + - "{{ product_name }}-mw" + - "{{ product_name }}-maintenance" + ignore_errors: true + + - name: enable apache2 required modules + apache2_module: state=present name={{ item }} + loop: "{{ apache2_required_modules }}" + + - name: copy httpd maintenance config file to ui target + template: + src: "httpd-maintenance.conf" + dest: "{{ http_conf_dir }}/{{ product_name }}-maintenance.conf" + owner: root + group: root + + - name: enable apache2 maintenance web site + command: "a2ensite {{ product_name }}-maintenance" + ignore_errors: true + + - name: restart apache with maintenance site + service: + name: "{{ webserver_package_name }}" + state: restarted + + become: true diff --git a/roles/common/tasks/uninstall.yml b/roles/common/tasks/uninstall.yml new file mode 100644 index 0000000000..91d28fef42 --- /dev/null +++ b/roles/common/tasks/uninstall.yml @@ -0,0 +1,220 @@ +--- +# this script will uninstall all fworch components from all hosts in the chosen inventory +# call with: +# sudo ansible-playbook/ scripts/uninstall-fworch.yml -K [-e "wipe_packages=yes"] +# parameters: +# wipe_packages=yes removes all packages potentially installed during fworch installation +# NB: this might break other applications running on the same system +# +# caveat: run this script with "wipe_packages" switch only if you are on an fworch-exclusive system + +- name: stop Podman container + command: podman stop fworch-api + ignore_errors: true + +- name: remove Podman container + command: podman rm fworch-api + ignore_errors: true + +- name: stop legacy Docker container + command: docker stop fworch-api + ignore_errors: true + +- name: remove legacy Docker container + command: docker rm fworch-api + ignore_errors: true + +- name: restart postgres to make sure no connections are blocking the database removal + service: + name: postgresql + state: restarted + when: ansible_facts['distribution']|lower == 'debian' or ansible_facts['distribution']|lower == 'ubuntu' + ignore_errors: true + +- name: find out installed postgres version + script: "scripts/get_pg_version.sh" + register: pg_version_result + changed_when: false + +- name: set fact pg_version + set_fact: + pg_version: "{{ pg_version_result.stdout }}" + ignore_errors: true + +- set_fact: + postgresql_dev_package: "{{ postgresql_dev_package_prefix }}-{{ pg_version }}" + ignore_errors: true + +# postgres operations with postgres user and ignoring errors +- block: + - name: remove database pre pg_version 13 + postgresql_db: + name: fworchdb + state: absent + register: drop_db + when: pg_version|int < 13 + + - name: remove database for pg_version starting from 13 + command: psql -c 'drop database if exists fworchdb with ( force )' + register: drop_db + when: pg_version|int >= 13 + + - name: check if db still exists + postgresql_query: + db: "{{ fworch_db_name }}" + query: "select exists(SELECT datname FROM pg_catalog.pg_database WHERE lower(datname) = lower('fworchdb'))" + register: db_exists + + - name: fail when db still exists + fail: + msg: database could not be dropped {{ drop_db.msg }}. Try to stop all sessions connected to the database before running uninstall again. + when: db_exists|bool + + - name: remove db groups + postgresql_user: + name: "{{ item }}" + state: absent + loop: "{{ database_groups }}" + + - name: remove db users + postgresql_user: + name: "{{ item }}" + state: absent + loop: "{{ database_users }}" + + become: true + become_user: postgres + ignore_errors: true + +- name: stop and disable slapd + service: + name: slapd + state: stopped + enabled: no + when: ansible_facts['distribution']|lower == 'debian' or ansible_facts['distribution']|lower == 'ubuntu' + ignore_errors: true + +- name: stop and disable {{ product_name }}-ui + service: + name: "{{ product_name }}-ui" + state: stopped + enabled: no + ignore_errors: true + +- name: stop and disable {{ product_name }}-middleware + service: + name: "{{ product_name }}-middleware" + state: stopped + enabled: no + ignore_errors: true + +- name: stop and disable current Hasura API service + service: + name: "{{ api_service_name }}" + state: stopped + enabled: no + ignore_errors: true + +- name: stop and disable legacy Hasura API services + service: + name: "{{ item }}" + state: stopped + enabled: no + loop: "{{ api_legacy_service_names | default([]) }}" + ignore_errors: true + +- block: + - name: disable apache sites + command: a2dissite {{ product_name }}-ui + ignore_errors: true + + - name: disable apache modules (due to a bug with php mod not properly getting purged) + apache2_module: state=absent name={{ item }} + loop: "{{ apache2_required_modules }}" + ignore_errors: true + + - name: uninstall all packages for {{ product_name }}, keeping git and ansible + package: + state: absent + name: "{{ item }}" + purge: yes + loop: + - rsyslog + - apache2 + - gnupg2 + - apt-transport-https + - software-properties-common + - npm + - python3-pip + - python3-virtualenv + - python3-psycopg2 + - libpq-dev + - "{{ postgresql_package }}" + - libpq-dev + - postgresql-client + - ldap-utils + - libldap-common + - libldap + - podman + - dotnet-sdk-3.1 + - make + - "{{ postgresql_dev_package }}" + - "{{ postgresql_test_package }}" + - apache2 + when: wipe_packages is defined and wipe_packages|bool + + - name: uninstall openldap + package: + state: absent + name: slapd + purge: yes + + - name: remove {{ product_name }} dirs and files + file: + name: "{{ item }}" + state: absent + loop: + - "{{ fworch_home }}" + - /etc/{{ product_name }} + - /etc/apache2/sites-available/{{ product_name }}-ui.conf + - /etc/apache2/sites-available/{{ product_name }}-api.conf + - /etc/apache2/sites-available/{{ product_name }}-mw.conf + - /etc/apache2/sites-available/{{ product_name }}-maintenance.conf + - /etc/apache2/sites-enabled/{{ product_name }}-ui.conf + - /etc/apache2/sites-enabled/{{ product_name }}-api.conf + - /etc/apache2/sites-enabled/{{ product_name }}-mw.conf + - /etc/apache2/sites-enabled/{{ product_name }}-maintenance.conf + - /lib/systemd/system/{{ api_service_name }}.service + - /lib/systemd/system/fworch-hasura-docker-api.service + - /var/lib/ldap/{{ product_name }}.internal + - /var/lib/ldap/example.com + - /var/lib/pgsql/data + - "{{ api_hasura_cli_bin }}" + - "{{ api_env_file }}" + - /var/{{ product_name }} + - /var/log/{{ product_name }} + ignore_errors: true + + - name: remove OS users and delete home directories + user: + name: "{{ item }}" + force: yes + remove: yes + state: absent + loop: + - "{{ fworch_user }}" + - "fworchsample" + + - name: remove OS group + group: + name: "{{ fworch_group }}" + state: absent + + # ssh-keygen -f "/usr/local/fworch/.ssh/known_hosts" -R "localhost" + - name: remove known host key + known_hosts: + name: "localhost" + path: "{{ fworch_home }}/.ssh/known_hosts" + state: absent + + become: yes diff --git a/roles/common/tasks/upgrade/7.2.3.yml b/roles/common/tasks/upgrade/7.2.3.yml new file mode 100644 index 0000000000..477ea85917 --- /dev/null +++ b/roles/common/tasks/upgrade/7.2.3.yml @@ -0,0 +1,24 @@ +- name: Read config file + slurp: + path: "{{ fworch_conf_file }}" + register: config_file + +- name: Parse JSON content + set_fact: + json_data: "{{ config_file.content | b64decode | from_json }}" + +- name: Modify config file if remote_addresses property is not present + block: + - name: Add remote_addresses property + set_fact: + modified_json_data: "{{ json_data | combine({'remote_addresses': []}) }}" + + - name: Save updated config to file + copy: + content: "{{ modified_json_data | to_nice_json }}" + dest: "{{ fworch_conf_file }}" + owner: "{{ fworch_user }}" + group: "{{ fworch_group }}" + + when: "'remote_addresses' not in json_data" + \ No newline at end of file diff --git a/roles/common/templates/httpd-maintenance.conf b/roles/common/templates/httpd-maintenance.conf new file mode 100644 index 0000000000..7478fa4363 --- /dev/null +++ b/roles/common/templates/httpd-maintenance.conf @@ -0,0 +1,47 @@ + + ServerName {{ ui_server_name }}:80 + ServerAdmin {{ server_admin }} + ServerAlias {{ ui_server_alias }} + Timeout {{ apache_ui_timeout }} + + RewriteEngine On + RewriteCond %{HTTP_HOST} ^(.*)$ + RewriteCond %{REQUEST_URI} !^/$ + RewriteCond %{REQUEST_URI} !^/men-at-work.png$ + RewriteRule ^(.*)$ / [R=301,L] + + ErrorLog /var/log/{{ webserver_package_name }}/error.log + TransferLog /var/log/{{ webserver_package_name }}/access.log + + +# https vhost: + + ServerName {{ ui_server_name }}:{{ ui_web_port }} + ServerAdmin {{ server_admin }} + ServerAlias {{ ui_server_alias }} + Timeout {{ apache_ui_timeout }} + DocumentRoot /var/www/html + + ErrorLog /var/log/{{ webserver_package_name }}/maint_error.log + TransferLog /var/log/{{ webserver_package_name }}/maint_access.log + CustomLog /var/log/{{ webserver_package_name }}/maint_ssl_request_log "%t %h %{SSL_PROTOCOL}x %{SSL_CIPHER}x \"%r\" %b" + SSLEngine on + {{ apache_ssl_protocol }} + {{ apache_ssl_cipher_suite }} + SSLCertificateFile /etc/{{ webserver_package_name }}/ssl/server.crt + SSLCertificateKeyFile /etc/{{ webserver_package_name }}/ssl/server.key + + RewriteEngine On + RewriteCond %{HTTP_HOST} ^(.*)$ + RewriteCond %{REQUEST_URI} !^/$ + RewriteCond %{REQUEST_URI} !^/men-at-work.png$ + RewriteRule ^(.*)$ / [R=301,L] + + # --- Security Headers --- + +{% for header in apache_security_headers %} + {{ header }} +{% endfor %} + + + diff --git a/roles/common/templates/iso.conf.j2 b/roles/common/templates/iso.conf.j2 deleted file mode 100644 index 241fdfcec0..0000000000 --- a/roles/common/templates/iso.conf.j2 +++ /dev/null @@ -1,22 +0,0 @@ -# zentrales Config-File - -TopDir {{ fworch_home }} # Installationsverzeichnis - -###################### database connection ############################## -fworch database hostname {{ fworch_db_host }} -fworch database type DBX_PGSQL -fworch database name {{ fworch_db_name }} -fworch database port {{ fworch_db_port }} - -###################### logging options ################################## -set loglevel 7 -set logtarget syslog -syslog_local 6 -syslog_type unix -syslog_ident fworch-importer-legacy -syslog_facility local6 - -###################### misc ############################################# -rule_header_offset 99000 # used for creating netscreen header_rules (containing zone-info) - # (used in import and web-gui) - # must at least be higher than max expected rule number diff --git a/roles/database/files/csv/color.csv b/roles/database/files/csv/color.csv index 35a8b64cd6..ffab95bad5 100644 --- a/roles/database/files/csv/color.csv +++ b/roles/database/files/csv/color.csv @@ -753,3 +753,7 @@ "yellow3";"cdcd00" "yellow4";"8b8b00" "yellowgreen";"9acd32" +"crete blue";"485cd4" +"state blue";"a186ed" +"olive";"617d28" +"dark gold";"cdad00" diff --git a/roles/database/files/get_pg_version.sh b/roles/database/files/get_pg_version.sh index 092d037a5e..784a574ae3 100644 --- a/roles/database/files/get_pg_version.sh +++ b/roles/database/files/get_pg_version.sh @@ -3,7 +3,7 @@ ver=$(psql --version | cut -d " " -f 3) major_ver=$(echo "$ver" | cut -d "." -f 1) minor_ver=$(echo "$ver" | cut -d "." -f 2) # return only major version from pg 10 onwards -if [ $((major_ver * 1)) -gt 9 ] +if [[ $((major_ver * 1)) -gt 9 ]] then ver=$major_ver fi diff --git a/roles/database/files/remove_all_containers.sh b/roles/database/files/remove_all_containers.sh index 41156840cf..567f6c36a9 100644 --- a/roles/database/files/remove_all_containers.sh +++ b/roles/database/files/remove_all_containers.sh @@ -1,8 +1,8 @@ #!/bin/bash -if [ -e /usr/bin/docker ] +if [[ -e /usr/bin/docker ]] then - if [ "$(docker ps -a -q)" != "" ] + if [[ "$(docker ps -a -q)" != "" ]] then # TODO: find out why the following does not work on debian (using backtick notation for the time being): # docker stop "$(docker ps -a -q)" diff --git a/roles/database/files/sql/creation/fworch-create-constraints.sql b/roles/database/files/sql/creation/fworch-create-constraints.sql index 6e6246b587..6d7ab48d45 100755 --- a/roles/database/files/sql/creation/fworch-create-constraints.sql +++ b/roles/database/files/sql/creation/fworch-create-constraints.sql @@ -1,31 +1,76 @@ -Alter Table "changelog_object" add Constraint "alt_key_changelog_object" UNIQUE ("abs_change_id"); -Alter Table "changelog_rule" add Constraint "alt_key_changelog_rule" UNIQUE ("abs_change_id"); -Alter Table "changelog_service" add Constraint "alt_key_changelog_service" UNIQUE ("abs_change_id"); -Alter Table "changelog_user" add Constraint "alt_key_changelog_user" UNIQUE ("abs_change_id"); -Alter Table "import_changelog" add Constraint "Alter_Key14" UNIQUE ("import_changelog_nr","control_id"); -Alter Table "import_control" add Constraint "control_id_stop_time_unique" UNIQUE ("stop_time","control_id"); -Alter Table "object" add Constraint "obj_altkey" UNIQUE ("mgm_id","zone_id","obj_uid","obj_create"); -ALTER TABLE owner ADD CONSTRAINT owner_name_unique_in_tenant UNIQUE ("name","tenant_id"); -ALTER TABLE owner_network ADD CONSTRAINT port_in_valid_range CHECK (port > 0 and port <= 65535); -ALTER TABLE owner_network ADD CONSTRAINT owner_network_ip_unique UNIQUE (owner_id, ip); -ALTER TABLE request.reqelement ADD CONSTRAINT port_in_valid_range CHECK (port > 0 and port <= 65535); -ALTER TABLE request.implelement ADD CONSTRAINT port_in_valid_range CHECK (port > 0 and port <= 65535); -Alter Table "rule" add Constraint "rule_altkey" UNIQUE ("dev_id","rule_uid","rule_create",xlate_rule); -Alter Table "rule_metadata" add Constraint "rule_metadata_alt_key" UNIQUE ("rule_uid","dev_id"); -Alter Table "service" add Constraint "svc_altkey" UNIQUE ("mgm_id","svc_uid","svc_create"); -Alter Table "stm_dev_typ" add Constraint "Alter_Key1" UNIQUE ("dev_typ_name","dev_typ_version"); -Alter Table "usr" add Constraint "usr_altkey" UNIQUE ("mgm_id","user_name","user_create"); -Alter Table "zone" add Constraint "Alter_Key10" UNIQUE ("mgm_id","zone_name"); --- TODO: Alter Table "tenant" add Constraint "tenant_name_unique" UNIQUE("tenant_name") - -create unique index if not exists only_one_future_recert_per_owner_per_rule on recertification(owner_id,rule_metadata_id,recert_date) -where recert_date IS NULL; - ---- compliance -CREATE EXTENSION IF NOT EXISTS btree_gist; -ALTER TABLE compliance.ip_range ADD CONSTRAINT "exclude_overlapping_ip_ranges" -EXCLUDE USING gist ( - network_zone_id WITH =, - numrange(ip_range_start - '0.0.0.0'::inet, ip_range_end - '0.0.0.0'::inet, '[]') WITH && -); - +CREATE OR REPLACE FUNCTION is_single_ip (ip CIDR) + RETURNS BOOLEAN + LANGUAGE 'plpgsql' IMMUTABLE COST 1 + AS +$BODY$ + BEGIN + RETURN masklen(ip)=32 AND family(ip)=4 OR masklen(ip)=128 AND family(ip)=6; + END; +$BODY$; + +Alter Table "changelog_object" add Constraint "alt_key_changelog_object" UNIQUE ("abs_change_id"); +Alter Table "changelog_rule" add Constraint "alt_key_changelog_rule" UNIQUE ("abs_change_id"); +Alter Table "changelog_service" add Constraint "alt_key_changelog_service" UNIQUE ("abs_change_id"); +Alter Table "changelog_user" add Constraint "alt_key_changelog_user" UNIQUE ("abs_change_id"); +Alter Table "import_changelog" add Constraint "Alter_Key14" UNIQUE ("import_changelog_nr","control_id"); +Alter Table "import_control" add Constraint "control_id_stop_time_unique" UNIQUE ("stop_time","control_id"); +Alter Table "object" add Constraint "obj_altkey" UNIQUE ("mgm_id","zone_id","obj_uid","obj_create"); +ALTER TABLE object ADD CONSTRAINT object_obj_ip_is_host CHECK (is_single_ip(obj_ip)); +ALTER TABLE object ADD CONSTRAINT object_obj_ip_end_is_host CHECK (is_single_ip(obj_ip_end)); +-- magic numbers here: 1 = host object, 3 = network object, 4 = range object +ALTER TABLE "object" ADD CONSTRAINT object_obj_ip_not_null CHECK (NOT (obj_ip IS NULL AND obj_typ_id IN (1, 3, 4))); +ALTER TABLE "object" ADD CONSTRAINT object_obj_ip_end_not_null CHECK (NOT (obj_ip_end IS NULL AND obj_typ_id IN (1, 3, 4))); +ALTER TABLE owner ADD CONSTRAINT owner_name_unique_in_tenant UNIQUE ("name","tenant_id"); +ALTER TABLE owner_network ADD CONSTRAINT port_in_valid_range CHECK (port > 0 and port <= 65535); +ALTER TABLE owner_network ADD CONSTRAINT owner_network_ip_is_host CHECK (is_single_ip(ip)); +ALTER TABLE owner_network ADD CONSTRAINT owner_network_ip_end_is_host CHECK (is_single_ip(ip_end)); +ALTER TABLE owner_network ADD CONSTRAINT owner_network_ip_unique UNIQUE (owner_id, ip, ip_end, import_source); +ALTER TABLE request.reqelement ADD CONSTRAINT port_in_valid_range CHECK (port > 0 and port <= 65535); +ALTER TABLE request.implelement ADD CONSTRAINT port_in_valid_range CHECK (port > 0 and port <= 65535); +-- Alter Table "rule" add Constraint "rule_altkey" UNIQUE ("dev_id","rule_uid","rule_create",xlate_rule); +Alter Table "rule" ADD Constraint "rule_unique_mgm_id_rule_uid_rule_create_xlate_rule" UNIQUE ("mgm_id", "rule_uid","rule_create","xlate_rule"); +ALTER TABLE rule_metadata ADD CONSTRAINT rule_metadata_mgm_id_rule_uid_unique UNIQUE (mgm_id, rule_uid); +Alter table "rulebase" add CONSTRAINT rulebase_uid_mgm_id_removed_key UNIQUE ("mgm_id", "uid", "removed"); +Alter table "rulebase_link" add CONSTRAINT unique_rulebase_link + UNIQUE ( + "gw_id", + "from_rulebase_id", + "from_rule_id", + "to_rulebase_id", + "created" + ); +Alter Table "service" add Constraint "svc_altkey" UNIQUE ("mgm_id","svc_uid","svc_create"); +Alter Table "stm_dev_typ" add Constraint "Alter_Key1" UNIQUE ("dev_typ_name","dev_typ_version"); +Alter Table "usr" add Constraint "usr_altkey" UNIQUE ("mgm_id","user_name","user_create"); + +CREATE UNIQUE INDEX if not exists "zone_mgm_id_zone_name_removed_is_null_unique" ON zone (mgm_id, zone_name) WHERE removed IS NULL; + +create unique index if not exists only_one_future_recert_per_owner_per_rule on recertification(owner_id,rule_metadata_id,recert_date) + where recert_date IS NULL; + +--- compliance + +CREATE EXTENSION IF NOT EXISTS btree_gist; +ALTER TABLE compliance.ip_range ADD CONSTRAINT "exclude_overlapping_ip_ranges" +EXCLUDE USING gist ( + network_zone_id WITH =, + numrange(ip_range_start - '0.0.0.0'::inet, ip_range_end - '0.0.0.0'::inet, '[]') WITH && +) +WHERE (removed IS NULL); + +--- report template + +ALTER TABLE report_template +ADD CONSTRAINT unique_report_template_name UNIQUE (report_template_name); + +-- import_control +ALTER TABLE import_control +ADD CONSTRAINT import_control_mgm_id_required_for_import_type_1 +CHECK ( + import_type_id <> 1 + OR mgm_id IS NOT NULL +); + +-- rule_owner +ALTER TABLE rule_owner ADD CONSTRAINT rule_owner_matched_objects_for_ip_based +CHECK ( owner_mapping_source_id != 1 OR matched_objects IS NOT NULL ); \ No newline at end of file diff --git a/roles/database/files/sql/creation/fworch-create-foreign-keys.sql b/roles/database/files/sql/creation/fworch-create-foreign-keys.sql index 2d23664944..4d02540d8a 100755 --- a/roles/database/files/sql/creation/fworch-create-foreign-keys.sql +++ b/roles/database/files/sql/creation/fworch-create-foreign-keys.sql @@ -14,12 +14,14 @@ Alter table "changelog_object" add foreign key ("new_obj_id") references "objec Alter table "changelog_object" add foreign key ("old_obj_id") references "object" ("obj_id") on update restrict on delete cascade; Alter table "changelog_rule" add foreign key ("change_type_id") references "stm_change_type" ("change_type_id") on update restrict on delete cascade; Alter table "changelog_rule" add foreign key ("control_id") references "import_control" ("control_id") on update restrict on delete cascade; -Alter table "changelog_rule" add foreign key ("dev_id") references "device" ("dev_id") on update restrict on delete cascade; Alter table "changelog_rule" add foreign key ("doku_admin") references "uiuser" ("uiuser_id") on update restrict on delete cascade; Alter table "changelog_rule" add foreign key ("import_admin") references "uiuser" ("uiuser_id") on update restrict on delete cascade; Alter table "changelog_rule" add foreign key ("mgm_id") references "management" ("mgm_id") on update restrict on delete cascade; Alter table "changelog_rule" add foreign key ("new_rule_id") references "rule" ("rule_id") on update restrict on delete cascade; Alter table "changelog_rule" add foreign key ("old_rule_id") references "rule" ("rule_id") on update restrict on delete cascade; +ALTER TABLE "changelog_owner"ADD CONSTRAINT changelog_owner_control_id_import_control_foreign_key FOREIGN KEY ("control_id") REFERENCES "import_control" ("control_id") ON UPDATE RESTRICT ON DELETE CASCADE; +ALTER TABLE "changelog_owner" ADD CONSTRAINT changelog_owner_new_owner_id_owner_id_foreign_key FOREIGN KEY ("new_owner_id") REFERENCES "owner" ("id") ON UPDATE RESTRICT ON DELETE CASCADE; +ALTER TABLE "changelog_owner" ADD CONSTRAINT changelog_owner_old_owner_id_owner_id_foreign_key FOREIGN KEY ("old_owner_id") REFERENCES "owner" ("id") ON UPDATE RESTRICT ON DELETE CASCADE; Alter table "changelog_service" add foreign key ("change_type_id") references "stm_change_type" ("change_type_id") on update restrict on delete cascade; Alter table "changelog_service" add foreign key ("control_id") references "import_control" ("control_id") on update restrict on delete cascade; Alter table "changelog_service" add foreign key ("doku_admin") references "uiuser" ("uiuser_id") on update restrict on delete cascade; @@ -37,25 +39,19 @@ Alter table "changelog_user" add foreign key ("old_user_id") references "usr" ( Alter table "config" add foreign key ("config_user") references "uiuser" ("uiuser_id") on update restrict on delete cascade; Alter table "device" add foreign key ("dev_typ_id") references "stm_dev_typ" ("dev_typ_id") on update restrict on delete cascade; Alter table "device" add foreign key ("mgm_id") references "management" ("mgm_id") on update restrict on delete cascade; -Alter table "device" add foreign key ("tenant_id") references "tenant" ("tenant_id") on update restrict on delete cascade; ALTER TABLE gw_route ADD CONSTRAINT gw_route_routing_device_foreign_key FOREIGN KEY (routing_device) REFERENCES device(dev_id) ON UPDATE RESTRICT ON DELETE CASCADE; ALTER TABLE gw_route ADD CONSTRAINT gw_route_interface_foreign_key FOREIGN KEY (interface_id) REFERENCES gw_interface(id) ON UPDATE RESTRICT ON DELETE CASCADE; ALTER TABLE gw_interface ADD CONSTRAINT gw_interface_routing_device_foreign_key FOREIGN KEY (routing_device) REFERENCES device(dev_id) ON UPDATE RESTRICT ON DELETE CASCADE; Alter table "import_changelog" add foreign key ("control_id") references "import_control" ("control_id") on update restrict on delete cascade; Alter table "import_config" add constraint "import_config_import_id_f_key" foreign key ("import_id") references "import_control" ("control_id") on update restrict on delete cascade; Alter table "import_config" add constraint "import_config_mgm_id_f_key" foreign key ("mgm_id") references "management" ("mgm_id") on update restrict on delete cascade; +Alter table "import_control" add foreign key ("import_type_id") references "stm_import" ("import_type_id") on update restrict on delete cascade; Alter table "import_control" add foreign key ("mgm_id") references "management" ("mgm_id") on update restrict on delete cascade; Alter table "import_full_config" add constraint "import_full_config_import_id_f_key" foreign key ("import_id") references "import_control" ("control_id") on update restrict on delete cascade; Alter table "import_full_config" add constraint "import_full_config_mgm_id_f_key" foreign key ("mgm_id") references "management" ("mgm_id") on update restrict on delete cascade; -Alter table "import_object" add foreign key ("control_id") references "import_control" ("control_id") on update restrict on delete cascade; -Alter table "import_rule" add foreign key ("control_id") references "import_control" ("control_id") on update restrict on delete cascade; -Alter table "import_service" add foreign key ("control_id") references "import_control" ("control_id") on update restrict on delete cascade; -Alter table "import_user" add foreign key ("control_id") references "import_control" ("control_id") on update restrict on delete cascade; -Alter table "import_zone" add foreign key ("control_id") references "import_control" ("control_id") on update restrict on delete cascade; Alter table "ldap_connection" add foreign key ("tenant_id") references "tenant" ("tenant_id") on update restrict on delete cascade; Alter table "management" add foreign key ("dev_typ_id") references "stm_dev_typ" ("dev_typ_id") on update restrict on delete cascade; -Alter table "management" add foreign key ("tenant_id") references "tenant" ("tenant_id") on update restrict on delete cascade; -ALTER TABLE "management" ADD CONSTRAINT management_multi_device_manager_id_fkey FOREIGN KEY ("multi_device_manager_id") REFERENCES "management" ("mgm_id") ON UPDATE RESTRICT; --ON DELETE CASCADE; +ALTER TABLE "management" ADD CONSTRAINT management_multi_device_manager_id_fkey FOREIGN KEY ("multi_device_manager_id") REFERENCES "management" ("mgm_id") ON UPDATE RESTRICT; ALTER TABLE "management" ADD CONSTRAINT management_import_credential_id_foreign_key FOREIGN KEY (import_credential_id) REFERENCES import_credential(id) ON UPDATE RESTRICT ON DELETE CASCADE; Alter table "object" add foreign key ("last_change_admin") references "uiuser" ("uiuser_id") on update restrict on delete cascade; Alter table "object" add foreign key ("mgm_id") references "management" ("mgm_id") on update restrict on delete cascade; @@ -76,6 +72,7 @@ Alter table "objgrp_flat" add foreign key ("objgrp_flat_member_id") references Alter table "report" add foreign key ("report_template_id") references "report_template" ("report_template_id") on update restrict on delete cascade; Alter table "report" add foreign key ("report_owner_id") references "uiuser" ("uiuser_id") on update restrict on delete cascade; Alter table "report" add foreign key ("tenant_wide_visible") references "tenant" ("tenant_id") on update restrict on delete cascade; +ALTER TABLE report ADD CONSTRAINT report_owner_foreign_key FOREIGN KEY (owner_id) REFERENCES owner(id) ON UPDATE RESTRICT ON DELETE CASCADE; Alter table "report_schedule" add foreign key ("report_template_id") references "report_template" ("report_template_id") on update restrict on delete cascade; Alter table "report_schedule" add foreign key ("report_schedule_owner") references "uiuser" ("uiuser_id") on update restrict on delete cascade; Alter table "report_schedule_format" add foreign key ("report_schedule_id") references "report_schedule" ("report_schedule_id") on update restrict on delete cascade; @@ -84,7 +81,6 @@ Alter table "report_template" add foreign key ("report_template_owner") referenc Alter table "report_template_viewable_by_user" add foreign key ("report_template_id") references "report_template" ("report_template_id") on update restrict on delete cascade; Alter table "report_template_viewable_by_user" add foreign key ("uiuser_id") references "uiuser" ("uiuser_id") on update restrict on delete cascade; Alter table "rule" add foreign key ("action_id") references "stm_action" ("action_id") on update restrict on delete cascade; -Alter table "rule" add foreign key ("dev_id") references "device" ("dev_id") on update restrict on delete cascade; Alter table "rule" add foreign key ("last_change_admin") references "uiuser" ("uiuser_id") on update restrict on delete cascade; Alter table "rule" add foreign key ("mgm_id") references "management" ("mgm_id") on update restrict on delete cascade; Alter table "rule" add foreign key ("rule_create") references "import_control" ("control_id") on update restrict on delete cascade; @@ -98,21 +94,40 @@ ALTER TABLE "rule" ADD CONSTRAINT rule_rule_parent_rule_id_fkey FOREIGN KEY ("parent_rule_id") REFERENCES "rule" ("rule_id") ON UPDATE RESTRICT ON DELETE CASCADE; ALTER TABLE "rule" ADD CONSTRAINT rule_parent_rule_type_id_fkey FOREIGN KEY ("parent_rule_type") REFERENCES "parent_rule_type" ("id") ON UPDATE RESTRICT ON DELETE CASCADE; -Alter table "rule" add constraint "rule_metadata_dev_id_rule_uid_f_key" - foreign key ("dev_id", "rule_uid") references "rule_metadata" ("dev_id", "rule_uid") on update restrict on delete cascade; +Alter table "rule" add constraint "fk_rule_rulebase_id" foreign key ("rulebase_id") references "rulebase" ("id") on update restrict on delete cascade; +Alter table "rule" add constraint "rule_rule_metadata_mgm_id_rule_uid_f_key" + foreign key ("mgm_id", "rule_uid") references "rule_metadata" ("mgm_id", "rule_uid") on update restrict on delete cascade; + +Alter table "rulebase" add CONSTRAINT fk_rulebase_mgm_id foreign key ("mgm_id") references "management" ("mgm_id") on update restrict on delete cascade; +Alter table "rulebase_link" add constraint "fk_rulebase_link_from_rulebase_id" foreign key ("from_rulebase_id") references "rulebase" ("id") on update restrict on delete cascade; +Alter table "rulebase_link" add constraint "fk_rulebase_link_to_rulebase_id" foreign key ("to_rulebase_id") references "rulebase" ("id") on update restrict on delete cascade; +Alter table "rulebase_link" add constraint "fk_rulebase_link_from_rule_id" foreign key ("from_rule_id") references "rule" ("rule_id") on update restrict on delete cascade; +Alter table "rulebase_link" add constraint "fk_rulebase_link_link_type" foreign key ("link_type") references "stm_link_type" ("id") on update restrict on delete cascade; +Alter table "rulebase_link" add constraint "fk_rulebase_link_gw_id" foreign key ("gw_id") references "device" ("dev_id") on update restrict on delete cascade; +Alter table "rulebase_link" add CONSTRAINT fk_rulebase_link_created_import_control_control_id + foreign key ("created") references "import_control" ("control_id") on update restrict on delete cascade; +Alter table "rulebase_link" add CONSTRAINT fk_rulebase_link_removed_import_control_control_id + foreign key ("removed") references "import_control" ("control_id") on update restrict on delete cascade; -Alter table "rule_from" add foreign key ("obj_id") references "object" ("obj_id") on update restrict on delete cascade; -Alter table "rule_from" add foreign key ("rf_create") references "import_control" ("control_id") on update restrict on delete cascade; -Alter table "rule_from" add foreign key ("rf_last_seen") references "import_control" ("control_id") on update restrict on delete cascade; -Alter table "rule_from" add foreign key ("rule_id") references "rule" ("rule_id") on update restrict on delete cascade; -Alter table "rule_from" add foreign key ("user_id") references "usr" ("user_id") on update restrict on delete cascade; +ALTER TABLE "rule_from_zone" ADD CONSTRAINT fk_rule_from_zone_rule_id_rule_rule_id FOREIGN KEY ("rule_id") REFERENCES "rule" ("rule_id") on update restrict on delete cascade; +ALTER TABLE "rule_from_zone" ADD CONSTRAINT fk_rule_from_zone_zone_id_zone_zone_id FOREIGN KEY ("zone_id") REFERENCES "zone" ("zone_id") on update restrict on delete cascade; -Alter table "rule_metadata" add constraint "rule_metadata_device_dev_id_f_key" - foreign key ("dev_id") references "device" ("dev_id") on update restrict on delete cascade; -Alter table "rule_metadata" add constraint "rule_metadata_rule_last_certifier_uiuser_uiuser_id_f_key" - foreign key ("rule_last_certifier") references "uiuser" ("uiuser_id") on update restrict on delete cascade; -Alter table "rule_metadata" add constraint "rule_metadata_rule_owner_uiuser_uiuser_id_f_key" - foreign key ("rule_owner") references "uiuser" ("uiuser_id") on update restrict on delete cascade; +Alter table "rule_from" add foreign key ("obj_id") references "object" ("obj_id") on update restrict on delete cascade; +Alter table "rule_from" add foreign key ("rf_create") references "import_control" ("control_id") on update restrict on delete cascade; +Alter table "rule_from" add foreign key ("rf_last_seen") references "import_control" ("control_id") on update restrict on delete cascade; +Alter table "rule_from" add foreign key ("rule_id") references "rule" ("rule_id") on update restrict on delete cascade; +Alter table "rule_from" add foreign key ("user_id") references "usr" ("user_id") on update restrict on delete cascade; +Alter table "rule_metadata" add constraint "rule_metadata_rule_created_import_control_control_id_f_key" + foreign key ("rule_created") references "import_control" ("control_id") on update restrict on delete restrict; +Alter table "rule_metadata" add constraint "rule_metadata_removed_import_control_control_id_f_key" + foreign key ("removed") references "import_control" ("control_id") on update restrict on delete restrict; +ALTER TABLE rule_metadata ADD CONSTRAINT rule_metadata_mgm_id_management_id_fk FOREIGN KEY (mgm_id) REFERENCES management(mgm_id) +ON update restrict on delete cascade; + +Alter table "rule_enforced_on_gateway" add CONSTRAINT fk_rule_enforced_on_gateway_rule_rule_id foreign key ("rule_id") references "rule" ("rule_id") on update restrict on delete cascade; +Alter table "rule_enforced_on_gateway" add CONSTRAINT fk_rule_enforced_on_gateway_device_dev_id foreign key ("dev_id") references "device" ("dev_id") on update restrict on delete cascade; +Alter table "rule_enforced_on_gateway" add CONSTRAINT fk_rule_enforced_on_gateway_created_import_control_control_id foreign key ("created") references "import_control" ("control_id") on update restrict on delete cascade; +Alter table "rule_enforced_on_gateway" add CONSTRAINT fk_rule_enforced_on_gateway_removed_import_control_control_id foreign key ("removed") references "import_control" ("control_id") on update restrict on delete cascade; Alter table "rule_nwobj_resolved" add foreign key ("obj_id") references "object" ("obj_id") on update restrict on delete cascade; Alter table "rule_nwobj_resolved" add foreign key ("rule_id") references "rule" ("rule_id") on update restrict on delete cascade; @@ -137,6 +152,9 @@ Alter table "rule_to" add foreign key ("rt_last_seen") references "import_contr Alter table "rule_to" add foreign key ("rule_id") references "rule" ("rule_id") on update restrict on delete cascade; Alter table "rule_to" add constraint rule_to_user_id_usr_user_id FOREIGN KEY ("user_id") references "usr" ("user_id") on update restrict on delete cascade; +ALTER TABLE "rule_to_zone" ADD CONSTRAINT fk_rule_to_zone_rule_id_rule_rule_id FOREIGN KEY ("rule_id") REFERENCES "rule" ("rule_id") on update restrict on delete cascade; +ALTER TABLE "rule_to_zone" ADD CONSTRAINT fk_rule_to_zone_zone_id_zone_zone_id FOREIGN KEY ("zone_id") REFERENCES "zone" ("zone_id") on update restrict on delete cascade; + Alter table "rule_user_resolved" add foreign key ("user_id") references "usr" ("user_id") on update restrict on delete cascade; Alter table "rule_user_resolved" add foreign key ("rule_id") references "rule" ("rule_id") on update restrict on delete cascade; Alter table "rule_user_resolved" add foreign key ("mgm_id") references "management" ("mgm_id") on update restrict on delete cascade; @@ -158,13 +176,13 @@ Alter table "svcgrp_flat" add foreign key ("import_created") references "import Alter table "svcgrp_flat" add foreign key ("import_last_seen") references "import_control" ("control_id") on update restrict on delete cascade; Alter table "svcgrp_flat" add foreign key ("svcgrp_flat_id") references "service" ("svc_id") on update restrict on delete cascade; Alter table "svcgrp_flat" add foreign key ("svcgrp_flat_member_id") references "service" ("svc_id") on update restrict on delete cascade; --- Alter table "temp_filtered_rule_ids" add foreign key ("rule_id") references "rule" ("rule_id") on update restrict on delete cascade; --- Alter table "temp_mgmid_importid_at_report_time" add foreign key ("control_id") references "import_control" ("control_id") on update restrict on delete cascade; --- Alter table "temp_mgmid_importid_at_report_time" add foreign key ("mgm_id") references "management" ("mgm_id") on update restrict on delete cascade; Alter table "tenant_network" add foreign key ("tenant_id") references "tenant" ("tenant_id") on update restrict on delete cascade; Alter table "tenant_to_device" add foreign key ("device_id") references "device" ("dev_id") on update restrict on delete cascade; Alter table "tenant_to_device" add foreign key ("tenant_id") references "tenant" ("tenant_id") on update restrict on delete cascade; +Alter table "tenant_to_management" add foreign key ("management_id") references "management" ("mgm_id") on update restrict on delete cascade; +Alter table "tenant_to_management" add foreign key ("tenant_id") references "tenant" ("tenant_id") on update restrict on delete cascade; Alter table "txt" add foreign key ("language") references "language" ("name") on update restrict on delete cascade; +Alter table "customtxt" add foreign key ("language") references "language" ("name") on update restrict on delete cascade; Alter table "uiuser" add foreign key ("tenant_id") references "tenant" ("tenant_id") on update restrict on delete cascade; Alter table "uiuser" add foreign key ("uiuser_language") references "language" ("name") on update restrict on delete cascade; Alter table "uiuser" add foreign key ("ldap_connection_id") references "ldap_connection" ("ldap_connection_id") on update restrict on delete cascade; @@ -189,6 +207,22 @@ Alter table "zone" add foreign key ("mgm_id") references "management" ("mgm_id" Alter table "zone" add foreign key ("zone_create") references "import_control" ("control_id") on update restrict on delete cascade; Alter table "zone" add foreign key ("zone_last_seen") references "import_control" ("control_id") on update restrict on delete cascade; +Alter table "owner" add constraint owner_last_recertifier_uiuser_uiuser_id_f_key foreign key (last_recertifier) references uiuser (uiuser_id) on update restrict; + +ALTER TABLE owner_ticket ADD CONSTRAINT owner_ticket_owner_id_foreign_key FOREIGN KEY (owner_id) REFERENCES owner(id) ON UPDATE RESTRICT ON DELETE CASCADE; +ALTER TABLE owner_ticket ADD CONSTRAINT owner_ticket_ticket_id_foreign_key FOREIGN KEY (ticket_id) REFERENCES request.ticket(id) ON UPDATE RESTRICT ON DELETE CASCADE; +ALTER TABLE ext_request ADD CONSTRAINT ext_request_owner_id_foreign_key FOREIGN KEY (owner_id) REFERENCES owner(id) ON UPDATE RESTRICT ON DELETE CASCADE; +ALTER TABLE ext_request ADD CONSTRAINT ext_request_ticket_id_foreign_key FOREIGN KEY (ticket_id) REFERENCES request.ticket(id) ON UPDATE RESTRICT ON DELETE CASCADE; + +Alter table "time_object" add foreign key ("mgm_id") references "management" ("mgm_id") on update restrict on delete cascade; +Alter table "time_object" add foreign key ("created") references "import_control" ("control_id") on update restrict on delete cascade; +Alter table "time_object" add foreign key ("removed") references "import_control" ("control_id") on update restrict on delete cascade; + +Alter table "rule_time" add foreign key ("rule_id") references "rule" ("rule_id") on update restrict on delete cascade; +Alter table "rule_time" add foreign key ("time_obj_id") references "time_object" ("time_obj_id") on update restrict on delete cascade; +Alter table "rule_time" add foreign key ("created") references "import_control" ("control_id") on update restrict on delete cascade; +Alter table "rule_time" add foreign key ("removed") references "import_control" ("control_id") on update restrict on delete cascade; + --- request.reqtask --- ALTER TABLE request.reqtask ADD CONSTRAINT request_reqtask_request_ticket_foreign_key FOREIGN KEY (ticket_id) REFERENCES request.ticket(id) ON UPDATE RESTRICT ON DELETE CASCADE; ALTER TABLE request.reqtask ADD CONSTRAINT request_reqtask_request_state_foreign_key FOREIGN KEY (state_id) REFERENCES request.state(id) ON UPDATE RESTRICT ON DELETE CASCADE; @@ -199,6 +233,7 @@ ALTER TABLE request.reqtask ADD CONSTRAINT request_reqtask_object_foreign_key FO ALTER TABLE request.reqtask ADD CONSTRAINT request_reqtask_usergrp_foreign_key FOREIGN KEY (user_grp_id) REFERENCES usr(user_id) ON UPDATE RESTRICT ON DELETE CASCADE; ALTER TABLE request.reqtask ADD CONSTRAINT request_reqtask_current_handler_foreign_key FOREIGN KEY (current_handler) REFERENCES uiuser(uiuser_id) ON UPDATE RESTRICT ON DELETE CASCADE; ALTER TABLE request.reqtask ADD CONSTRAINT request_reqtask_recent_handler_foreign_key FOREIGN KEY (recent_handler) REFERENCES uiuser(uiuser_id) ON UPDATE RESTRICT ON DELETE CASCADE; +ALTER TABLE request.reqtask ADD CONSTRAINT request_reqtask_management_foreign_key FOREIGN KEY (mgm_id) REFERENCES management(mgm_id) ON UPDATE RESTRICT ON DELETE CASCADE; --- request.reqelement --- ALTER TABLE request.reqelement ADD CONSTRAINT request_reqelement_request_reqtask_foreign_key FOREIGN KEY (task_id) REFERENCES request.reqtask(id) ON UPDATE RESTRICT ON DELETE CASCADE; ALTER TABLE request.reqelement ADD CONSTRAINT request_reqelement_proto_foreign_key FOREIGN KEY (ip_proto_id) REFERENCES stm_ip_proto(ip_proto_id) ON UPDATE RESTRICT ON DELETE CASCADE; @@ -221,6 +256,9 @@ ALTER TABLE request.ticket ADD CONSTRAINT request_ticket_current_handler_foreign ALTER TABLE request.ticket ADD CONSTRAINT request_ticket_recent_handler_foreign_key FOREIGN KEY (recent_handler) REFERENCES uiuser(uiuser_id) ON UPDATE RESTRICT ON DELETE CASCADE; --- owner --- ALTER TABLE owner ADD CONSTRAINT owner_tenant_foreign_key FOREIGN KEY (tenant_id) REFERENCES tenant(tenant_id) ON UPDATE RESTRICT ON DELETE CASCADE; +ALTER TABLE owner ADD CONSTRAINT owner_owner_lifecycle_state_foreign_key FOREIGN KEY (owner_lifecycle_state_id) REFERENCES owner_lifecycle_state(id) ON DELETE SET NULL; +ALTER TABLE owner_responsible ADD CONSTRAINT owner_responsible_owner_foreign_key FOREIGN KEY (owner_id) REFERENCES owner(id) ON UPDATE RESTRICT ON DELETE CASCADE; +ALTER TABLE owner_responsible ADD CONSTRAINT owner_responsible_type_foreign_key FOREIGN KEY (responsible_type) REFERENCES owner_responsible_type(id) ON UPDATE RESTRICT ON DELETE RESTRICT; --- comment --- ALTER TABLE request.comment ADD CONSTRAINT request_comment_uiuser_foreign_key FOREIGN KEY (creator_id) REFERENCES uiuser(uiuser_id) ON UPDATE RESTRICT ON DELETE CASCADE; ALTER TABLE request.comment ADD CONSTRAINT request_comment_request_comment_foreign_key FOREIGN KEY (ref_id) REFERENCES request.comment(id) ON UPDATE RESTRICT ON DELETE CASCADE; @@ -230,6 +268,9 @@ ALTER TABLE owner_network ADD CONSTRAINT owner_network_owner_foreign_key FOREIGN --- rule_owner --- ALTER TABLE rule_owner ADD CONSTRAINT rule_owner_rule_metadata_foreign_key FOREIGN KEY (rule_metadata_id) REFERENCES rule_metadata(rule_metadata_id) ON UPDATE RESTRICT ON DELETE CASCADE; ALTER TABLE rule_owner ADD CONSTRAINT rule_owner_owner_foreign_key FOREIGN KEY (owner_id) REFERENCES owner(id) ON UPDATE RESTRICT ON DELETE CASCADE; +ALTER TABLE rule_owner ADD CONSTRAINT rule_owner_rule_foreign_key FOREIGN KEY (rule_id) REFERENCES rule(rule_id) ON UPDATE RESTRICT ON DELETE CASCADE; +ALTER TABLE rule_owner ADD CONSTRAINT rule_owner_created_import_control_foreign_key FOREIGN KEY (created) REFERENCES import_control(control_id) ON UPDATE RESTRICT ON DELETE CASCADE; +ALTER TABLE rule_owner ADD CONSTRAINT rule_owner_removed_import_control_foreign_key FOREIGN KEY (removed) REFERENCES import_control(control_id) ON UPDATE RESTRICT ON DELETE CASCADE; --- reqtask_owner --- ALTER TABLE reqtask_owner ADD CONSTRAINT reqtask_owner_request_reqtask_foreign_key FOREIGN KEY (reqtask_id) REFERENCES request.reqtask(id) ON UPDATE RESTRICT ON DELETE CASCADE; ALTER TABLE reqtask_owner ADD CONSTRAINT reqtask_owner_owner_foreign_key FOREIGN KEY (owner_id) REFERENCES owner(id) ON UPDATE RESTRICT ON DELETE CASCADE; @@ -248,6 +289,8 @@ ALTER TABLE request.impltask_comment ADD CONSTRAINT request_impltask_comment_com --- state_action --- ALTER TABLE request.state_action ADD CONSTRAINT request_state_action_state_foreign_key FOREIGN KEY (state_id) REFERENCES request.state(id) ON UPDATE RESTRICT ON DELETE CASCADE; ALTER TABLE request.state_action ADD CONSTRAINT request_state_action_action_foreign_key FOREIGN KEY (action_id) REFERENCES request.action(id) ON UPDATE RESTRICT ON DELETE CASCADE; +--- ext_state --- +ALTER TABLE request.ext_state ADD CONSTRAINT request_ext_state_state_foreign_key FOREIGN KEY (state_id) REFERENCES request.state(id) ON UPDATE RESTRICT ON DELETE CASCADE; --- request.implelement --- ALTER TABLE request.implelement ADD CONSTRAINT request_implelement_request_implelement_foreign_key FOREIGN KEY (original_nat_id) REFERENCES request.implelement(id) ON UPDATE RESTRICT ON DELETE CASCADE; ALTER TABLE request.implelement ADD CONSTRAINT request_implelement_service_foreign_key FOREIGN KEY (service_id) REFERENCES service(svc_id) ON UPDATE RESTRICT ON DELETE CASCADE; @@ -266,16 +309,65 @@ ALTER TABLE request.impltask ADD CONSTRAINT request_impltask_object_foreign_key ALTER TABLE request.impltask ADD CONSTRAINT request_impltask_usergrp_foreign_key FOREIGN KEY (user_grp_id) REFERENCES usr(user_id) ON UPDATE RESTRICT ON DELETE CASCADE; ALTER TABLE request.impltask ADD CONSTRAINT request_impltask_current_handler_foreign_key FOREIGN KEY (current_handler) REFERENCES uiuser(uiuser_id) ON UPDATE RESTRICT ON DELETE CASCADE; ALTER TABLE request.impltask ADD CONSTRAINT request_impltask_recent_handler_foreign_key FOREIGN KEY (recent_handler) REFERENCES uiuser(uiuser_id) ON UPDATE RESTRICT ON DELETE CASCADE; + --- recertification --- ALTER TABLE recertification ADD CONSTRAINT recertification_rule_metadata_foreign_key FOREIGN KEY (rule_metadata_id) REFERENCES rule_metadata(rule_metadata_id) ON UPDATE RESTRICT ON DELETE CASCADE; ALTER TABLE recertification ADD CONSTRAINT recertification_owner_foreign_key FOREIGN KEY (owner_id) REFERENCES owner(id) ON UPDATE RESTRICT ON DELETE CASCADE; +ALTER TABLE recertification ADD CONSTRAINT recertification_owner_recertification_foreign_key FOREIGN KEY (owner_recert_id) REFERENCES owner_recertification(id) ON UPDATE RESTRICT ON DELETE CASCADE; +ALTER TABLE owner_recertification ADD CONSTRAINT owner_recertification_owner_foreign_key FOREIGN KEY (owner_id) REFERENCES owner(id) ON UPDATE RESTRICT ON DELETE CASCADE; +ALTER TABLE owner_recertification ADD CONSTRAINT owner_recertification_report_foreign_key FOREIGN KEY (report_id) REFERENCES report(report_id) ON UPDATE RESTRICT ON DELETE CASCADE; --- compliance.ip_range --- ALTER TABLE compliance.ip_range ADD CONSTRAINT compliance_ip_range_network_zone_foreign_key FOREIGN KEY (network_zone_id) REFERENCES compliance.network_zone(id) ON UPDATE RESTRICT ON DELETE CASCADE; +ALTER TABLE compliance.ip_range ADD CONSTRAINT compliance_criterion_ip_range_foreign_key FOREIGN KEY (criterion_id) REFERENCES compliance.criterion(id) ON UPDATE RESTRICT ON DELETE CASCADE; --- compliance.network_zone --- ALTER TABLE compliance.network_zone ADD CONSTRAINT compliance_super_zone_foreign_key FOREIGN KEY (super_network_zone_id) REFERENCES compliance.network_zone(id) ON UPDATE RESTRICT ON DELETE CASCADE; +ALTER TABLE compliance.network_zone ADD CONSTRAINT compliance_criterion_network_zone_foreign_key FOREIGN KEY (criterion_id) REFERENCES compliance.criterion(id) ON UPDATE RESTRICT ON DELETE CASCADE; --- compliance.network_zone_communication --- ALTER TABLE compliance.network_zone_communication ADD CONSTRAINT compliance_from_network_zone_communication_foreign_key FOREIGN KEY (from_network_zone_id) REFERENCES compliance.network_zone(id) ON UPDATE RESTRICT ON DELETE CASCADE; ALTER TABLE compliance.network_zone_communication ADD CONSTRAINT compliance_to_network_zone_communication_foreign_key FOREIGN KEY (to_network_zone_id) REFERENCES compliance.network_zone(id) ON UPDATE RESTRICT ON DELETE CASCADE; +ALTER TABLE compliance.network_zone_communication ADD CONSTRAINT compliance_criterion_network_zone_communication_foreign_key FOREIGN KEY (criterion_id) REFERENCES compliance.criterion(id) ON UPDATE RESTRICT ON DELETE CASCADE; + +--- compliance.policy_criterion --- +ALTER TABLE compliance.policy_criterion ADD CONSTRAINT compliance_policy_policy_criterion_foreign_key FOREIGN KEY (policy_id) REFERENCES compliance.policy(id) ON UPDATE RESTRICT ON DELETE CASCADE; +ALTER TABLE compliance.policy_criterion ADD CONSTRAINT compliance_criterion_policy_criterion_foreign_key FOREIGN KEY (criterion_id) REFERENCES compliance.criterion(id) ON UPDATE RESTRICT ON DELETE CASCADE; + +--- compliance.violation --- +ALTER TABLE compliance.violation ADD CONSTRAINT compliance_policy_violation_foreign_key FOREIGN KEY (policy_id) REFERENCES compliance.policy(id) ON UPDATE RESTRICT ON DELETE CASCADE; +ALTER TABLE compliance.violation ADD CONSTRAINT compliance_criterion_violation_foreign_key FOREIGN KEY (criterion_id) REFERENCES compliance.criterion(id) ON UPDATE RESTRICT ON DELETE CASCADE; +ALTER TABLE compliance.violation ADD CONSTRAINT compliance_rule_violation_foreign_key FOREIGN KEY (rule_id) REFERENCES public.rule(rule_id) ON UPDATE RESTRICT ON DELETE CASCADE; + +-- modelling +ALTER TABLE modelling.nwgroup ADD CONSTRAINT modelling_nwgroup_owner_foreign_key FOREIGN KEY (app_id) REFERENCES owner(id) ON UPDATE RESTRICT ON DELETE CASCADE; +ALTER TABLE modelling.connection ADD CONSTRAINT modelling_connection_owner_foreign_key FOREIGN KEY (app_id) REFERENCES owner(id) ON UPDATE RESTRICT ON DELETE CASCADE; +ALTER TABLE modelling.connection ADD CONSTRAINT modelling_connection_used_interface_foreign_key FOREIGN KEY (used_interface_id) REFERENCES modelling.connection(id) ON UPDATE RESTRICT; +ALTER TABLE modelling.connection ADD CONSTRAINT modelling_connection_proposed_app_id_foreign_key FOREIGN KEY (proposed_app_id) REFERENCES owner(id) ON UPDATE RESTRICT ON DELETE CASCADE; +ALTER TABLE modelling.nwobject_nwgroup ADD CONSTRAINT modelling_nwobject_nwgroup_nwobject_foreign_key FOREIGN KEY (nwobject_id) REFERENCES owner_network(id) ON UPDATE RESTRICT ON DELETE CASCADE; +ALTER TABLE modelling.nwobject_nwgroup ADD CONSTRAINT modelling_nwobject_nwgroup_nwgroup_foreign_key FOREIGN KEY (nwgroup_id) REFERENCES modelling.nwgroup(id) ON UPDATE RESTRICT ON DELETE CASCADE; +ALTER TABLE modelling.nwgroup_connection ADD CONSTRAINT modelling_nwgroup_connection_nwgroup_foreign_key FOREIGN KEY (nwgroup_id) REFERENCES modelling.nwgroup(id) ON UPDATE RESTRICT ON DELETE CASCADE; +ALTER TABLE modelling.nwgroup_connection ADD CONSTRAINT modelling_nwgroup_connection_connection_foreign_key FOREIGN KEY (connection_id) REFERENCES modelling.connection(id) ON UPDATE RESTRICT ON DELETE CASCADE; +ALTER TABLE modelling.nwobject_connection ADD CONSTRAINT modelling_nwobject_connection_nwobject_foreign_key FOREIGN KEY (nwobject_id) REFERENCES owner_network(id) ON UPDATE RESTRICT ON DELETE CASCADE; +ALTER TABLE modelling.nwobject_connection ADD CONSTRAINT modelling_nwobject_connection_connection_foreign_key FOREIGN KEY (connection_id) REFERENCES modelling.connection(id) ON UPDATE RESTRICT ON DELETE CASCADE; +ALTER TABLE modelling.permitted_owners ADD CONSTRAINT modelling_permitted_owners_connection_foreign_key FOREIGN KEY (connection_id) REFERENCES modelling.connection(id) ON UPDATE RESTRICT ON DELETE CASCADE; +ALTER TABLE modelling.permitted_owners ADD CONSTRAINT modelling_permitted_owners_owner_foreign_key FOREIGN KEY (app_id) REFERENCES owner(id) ON UPDATE RESTRICT ON DELETE CASCADE; +ALTER TABLE modelling.service ADD CONSTRAINT modelling_service_owner_foreign_key FOREIGN KEY (app_id) REFERENCES owner(id) ON UPDATE RESTRICT ON DELETE CASCADE; +ALTER TABLE modelling.service ADD CONSTRAINT modelling_service_protocol_foreign_key FOREIGN KEY (proto_id) REFERENCES stm_ip_proto(ip_proto_id) ON UPDATE RESTRICT ON DELETE CASCADE; +ALTER TABLE modelling.service_group ADD CONSTRAINT modelling_service_group_owner_foreign_key FOREIGN KEY (app_id) REFERENCES owner(id) ON UPDATE RESTRICT ON DELETE CASCADE; +ALTER TABLE modelling.service_service_group ADD CONSTRAINT modelling_service_service_group_service_foreign_key FOREIGN KEY (service_id) REFERENCES modelling.service(id) ON UPDATE RESTRICT ON DELETE CASCADE; +ALTER TABLE modelling.service_service_group ADD CONSTRAINT modelling_service_service_group_service_group_foreign_key FOREIGN KEY (service_group_id) REFERENCES modelling.service_group(id) ON UPDATE RESTRICT ON DELETE CASCADE; +ALTER TABLE modelling.service_group_connection ADD CONSTRAINT modelling_service_group_connection_service_group_foreign_key FOREIGN KEY (service_group_id) REFERENCES modelling.service_group(id) ON UPDATE RESTRICT ON DELETE CASCADE; +ALTER TABLE modelling.service_group_connection ADD CONSTRAINT modelling_service_group_connection_connection_foreign_key FOREIGN KEY (connection_id) REFERENCES modelling.connection(id) ON UPDATE RESTRICT ON DELETE CASCADE; +ALTER TABLE modelling.service_connection ADD CONSTRAINT modelling_service_connection_service_foreign_key FOREIGN KEY (service_id) REFERENCES modelling.service(id) ON UPDATE RESTRICT ON DELETE CASCADE; +ALTER TABLE modelling.service_connection ADD CONSTRAINT modelling_service_connection_connection_foreign_key FOREIGN KEY (connection_id) REFERENCES modelling.connection(id) ON UPDATE RESTRICT ON DELETE CASCADE; +ALTER TABLE modelling.change_history ADD CONSTRAINT modelling_change_history_owner_foreign_key FOREIGN KEY (app_id) REFERENCES owner(id) ON UPDATE RESTRICT ON DELETE CASCADE; +ALTER TABLE modelling.selected_objects ADD CONSTRAINT modelling_selected_objects_owner_foreign_key FOREIGN KEY (app_id) REFERENCES owner(id) ON UPDATE RESTRICT ON DELETE CASCADE; +ALTER TABLE modelling.selected_objects ADD CONSTRAINT modelling_selected_objects_nwgroup_foreign_key FOREIGN KEY (nwgroup_id) REFERENCES modelling.nwgroup(id) ON UPDATE RESTRICT ON DELETE CASCADE; +ALTER TABLE modelling.selected_connections ADD CONSTRAINT modelling_selected_connections_owner_foreign_key FOREIGN KEY (app_id) REFERENCES owner(id) ON UPDATE RESTRICT ON DELETE CASCADE; +ALTER TABLE modelling.selected_connections ADD CONSTRAINT modelling_selected_connections_connection_foreign_key FOREIGN KEY (connection_id) REFERENCES modelling.connection(id) ON UPDATE RESTRICT ON DELETE CASCADE; + +-- notification +ALTER TABLE notification ADD CONSTRAINT notification_owner_foreign_key FOREIGN KEY (owner_id) REFERENCES owner(id) ON UPDATE RESTRICT ON DELETE CASCADE; +ALTER TABLE notification ADD CONSTRAINT notification_user_foreign_key FOREIGN KEY (user_id) REFERENCES uiuser(uiuser_id) ON UPDATE RESTRICT ON DELETE CASCADE; +ALTER TABLE notification ADD CONSTRAINT notification_report_schedule_foreign_key FOREIGN KEY (schedule_id) REFERENCES report_schedule(report_schedule_id) ON UPDATE RESTRICT ON DELETE CASCADE; diff --git a/roles/database/files/sql/creation/fworch-create-indices.sql b/roles/database/files/sql/creation/fworch-create-indices.sql index 96917ff511..f1fc609146 100755 --- a/roles/database/files/sql/creation/fworch-create-indices.sql +++ b/roles/database/files/sql/creation/fworch-create-indices.sql @@ -1,123 +1,120 @@ -Create index IF NOT EXISTS idx_changelog_object01 on changelog_object (change_type_id); -Create index IF NOT EXISTS idx_changelog_object02 on changelog_object (mgm_id); -Create index IF NOT EXISTS idx_changelog_rule01 on changelog_rule (change_type_id); -Create index IF NOT EXISTS idx_changelog_rule02 on changelog_rule (mgm_id); -Create index IF NOT EXISTS idx_changelog_rule03 on changelog_rule (dev_id); -Create index IF NOT EXISTS idx_changelog_service01 on changelog_service (change_type_id); -Create index IF NOT EXISTS idx_changelog_service02 on changelog_service (mgm_id); -Create index IF NOT EXISTS idx_changelog_user01 on changelog_user (change_type_id); -Create index IF NOT EXISTS idx_changelog_user02 on changelog_user (mgm_id); -Create index IF NOT EXISTS idx_import_control01 on import_control (control_id); -Create index IF NOT EXISTS idx_import_object01 on import_object (control_id); -Create index IF NOT EXISTS idx_import_object02 on import_object (obj_id); -Create index IF NOT EXISTS idx_import_rule01 on import_rule (rule_id); -Create index IF NOT EXISTS idx_object01 on object (mgm_id); -Create index IF NOT EXISTS idx_object02 on object (obj_name,mgm_id,zone_id,active); -Create index IF NOT EXISTS idx_object03 on object (obj_uid,mgm_id,zone_id,active); -Create index IF NOT EXISTS idx_object04 on object (obj_ip); -Create index IF NOT EXISTS idx_objgrp_flat01 on objgrp_flat (objgrp_flat_id); -Create index IF NOT EXISTS idx_objgrp_flat02 on objgrp_flat (objgrp_flat_member_id); -Create index IF NOT EXISTS idx_rule01 on rule (rule_uid,mgm_id,dev_id,active,nat_rule,xlate_rule); -Create index IF NOT EXISTS idx_rule02 on rule (mgm_id,rule_id,rule_uid,dev_id); -Create index IF NOT EXISTS idx_rule03 on rule (dev_id); -Create index IF NOT EXISTS idx_rule04 on rule (action_id); -Create index IF NOT EXISTS idx_rule_from01 on rule_from (rule_id); -Create index IF NOT EXISTS idx_rule_service01 on rule_service (rule_id); -Create index IF NOT EXISTS idx_rule_service02 on rule_service (svc_id); -Create index IF NOT EXISTS idx_rule_to01 on rule_to (rule_id); -Create index IF NOT EXISTS idx_service01 on service (mgm_id); -Create index IF NOT EXISTS idx_service02 on service (svc_color_id); -Create index IF NOT EXISTS idx_svcgrp_flat01 on svcgrp_flat (svcgrp_flat_id); -Create index IF NOT EXISTS idx_svcgrp_flat02 on svcgrp_flat (svcgrp_flat_member_id); -Create index IF NOT EXISTS idx_usr01 on usr (mgm_id); -Create index IF NOT EXISTS idx_usergrp_flat01 on usergrp_flat (usergrp_flat_id); -Create index IF NOT EXISTS idx_usergrp_flat02 on usergrp_flat (usergrp_flat_member_id); -Create index IF NOT EXISTS idx_zone01 on zone (zone_name,mgm_id); -Create index IF NOT EXISTS idx_zone02 on zone (mgm_id); -- needed as mgm_id is not first column on above composite index - --- make sure a maximum of one stop_time=null entry exists per mgm_id (only one running import per mgm): -CREATE UNIQUE INDEX uidx_import_control_only_one_null_stop_time_per_mgm_when_null ON import_control (mgm_id) WHERE stop_time IS NULL; - -CREATE UNIQUE index if not exists only_one_default_owner on owner(is_default) where is_default = true; - --- probably useful: -Create index "IX_Relationship59" on "import_service" ("control_id"); -Create index "IX_Relationship61" on "import_rule" ("control_id"); -Create index "IX_Relationship62" on "import_user" ("control_id"); -Create index "IX_Relationship132" on "import_zone" ("control_id"); - -Create index "IX_Relationship68" on "changelog_object" ("control_id"); -Create index "IX_Relationship76" on "changelog_service" ("control_id"); -Create index "IX_Relationship77" on "changelog_user" ("control_id"); -Create index "IX_Relationship78" on "changelog_rule" ("control_id"); - --- tbd -Create unique index "kundennetze_akey" on "tenant_network" using btree ("tenant_net_id","tenant_id"); -Create unique index "rule_from_unique_index" on "rule_from" using btree ("rule_id","obj_id","user_id"); -Create index "import_control_start_time_idx" on "import_control" using btree ("start_time"); - - -Create index "IX_relationship23" on "rule" ("action_id"); -Create index "IX_relationship9" on "object" ("obj_typ_id"); -Create index "IX_relationship24" on "rule" ("track_id"); -Create index "IX_Relationship33" on "service" ("ip_proto_id"); -Create index "IX_Relationship36" on "service" ("svc_typ_id"); -Create index "IX_Relationship37" on "object" ("zone_id"); -Create index "IX_Relationship90" on "rule" ("rule_from_zone"); -Create index "IX_Relationship95" on "rule_from" ("user_id"); -Create index "IX_relationship26" on "rule_from" ("obj_id"); -Create index "IX_relationship28" on "rule_to" ("obj_id"); -Create index "IX_Relationship91" on "rule" ("rule_to_zone"); - -Create index "IX_Relationship65" on "changelog_object" ("old_obj_id"); -Create index "IX_Relationship66" on "changelog_object" ("new_obj_id"); -Create index "IX_Relationship72" on "changelog_rule" ("new_rule_id"); -Create index "IX_Relationship73" on "changelog_rule" ("old_rule_id"); -Create index "IX_Relationship74" on "changelog_service" ("new_svc_id"); -Create index "IX_Relationship75" on "changelog_service" ("old_svc_id"); -Create index "IX_Relationship79" on "changelog_user" ("new_user_id"); -Create index "IX_Relationship80" on "changelog_user" ("old_user_id"); - - -Create index "IX_Relationship120" on "objgrp" ("import_created"); -Create index "IX_Relationship121" on "objgrp" ("import_last_seen"); -Create index "IX_Relationship122" on "svcgrp" ("import_created"); -Create index "IX_Relationship123" on "svcgrp" ("import_last_seen"); -Create index "IX_Relationship50" on "usergrp" ("usergrp_id"); -Create index "IX_Relationship51" on "usergrp" ("usergrp_member_id"); -Create index "IX_Relationship153" on "usergrp" ("import_created"); -Create index "IX_Relationship154" on "usergrp" ("import_last_seen"); - - -Create index "IX_relationship20" on "svcgrp" ("svcgrp_member_id"); -Create index "IX_relationship14" on "objgrp" ("objgrp_member_id"); - -Create index "IX_Relationship107" on "objgrp_flat" ("import_created"); -Create index "IX_Relationship108" on "objgrp_flat" ("import_last_seen"); -Create index "IX_Relationship124" on "svcgrp_flat" ("import_created"); -Create index "IX_Relationship125" on "svcgrp_flat" ("import_last_seen"); -Create index "IX_Relationship151" on "usergrp_flat" ("import_created"); -Create index "IX_Relationship152" on "usergrp_flat" ("import_last_seen"); - -Create index "IX_Relationship166" on "rule" ("rule_create"); -Create index "IX_Relationship167" on "rule" ("rule_last_seen"); -Create index "IX_Relationship168" on "rule_from" ("rf_create"); -Create index "IX_Relationship169" on "rule_from" ("rf_last_seen"); -Create index "IX_Relationship170" on "rule_to" ("rt_create"); -Create index "IX_Relationship171" on "rule_to" ("rt_last_seen"); -Create index "IX_Relationship172" on "rule_service" ("rs_create"); -Create index "IX_Relationship173" on "rule_service" ("rs_last_seen"); -Create index "IX_Relationship174" on "object" ("obj_create"); -Create index "IX_Relationship175" on "object" ("obj_last_seen"); -Create index "IX_Relationship176" on "service" ("svc_create"); -Create index "IX_Relationship177" on "service" ("svc_last_seen"); -Create index "IX_Relationship178" on "zone" ("zone_create"); -Create index "IX_Relationship179" on "zone" ("zone_last_seen"); - -create unique index if not exists only_one_default_owner on owner(is_default) -where is_default = true; - --- compliance -Create index IF NOT EXISTS idx_fkey_network_zone_id on compliance.ip_range USING HASH (network_zone_id); -Create index IF NOT EXISTS idx_fkey_network_zone_from on compliance.network_zone_communication USING HASH (from_network_zone_id); -Create index IF NOT EXISTS idx_fkey_network_zone_to on compliance.network_zone_communication USING HASH (to_network_zone_id); +Create index IF NOT EXISTS idx_changelog_object01 on changelog_object (change_type_id); +Create index IF NOT EXISTS idx_changelog_object02 on changelog_object (mgm_id); +Create index IF NOT EXISTS idx_changelog_rule01 on changelog_rule (change_type_id); +Create index IF NOT EXISTS idx_changelog_rule02 on changelog_rule (mgm_id); +Create index IF NOT EXISTS idx_changelog_rule03 on changelog_rule (dev_id); +Create index IF NOT EXISTS idx_changelog_service01 on changelog_service (change_type_id); +Create index IF NOT EXISTS idx_changelog_service02 on changelog_service (mgm_id); +Create index IF NOT EXISTS idx_changelog_user01 on changelog_user (change_type_id); +Create index IF NOT EXISTS idx_changelog_user02 on changelog_user (mgm_id); +Create index IF NOT EXISTS idx_import_control01 on import_control (control_id); +Create index IF NOT EXISTS idx_object01 on object (mgm_id); +Create index IF NOT EXISTS idx_object02 on object (obj_name,mgm_id,zone_id,active); +Create index IF NOT EXISTS idx_object03 on object (obj_uid,mgm_id,zone_id,active); +Create index IF NOT EXISTS idx_object04 on object (obj_ip); +Create index IF NOT EXISTS idx_objgrp_flat01 on objgrp_flat (objgrp_flat_id); +Create index IF NOT EXISTS idx_objgrp_flat02 on objgrp_flat (objgrp_flat_member_id); +Create index IF NOT EXISTS idx_rule01 on rule (rule_uid,mgm_id,dev_id,active,nat_rule,xlate_rule); +Create index IF NOT EXISTS idx_rule02 on rule (mgm_id,rule_id,rule_uid,dev_id); +Create index IF NOT EXISTS idx_rule03 on rule (dev_id); +Create index IF NOT EXISTS idx_rule04 on rule (action_id); +Create index IF NOT EXISTS idx_rule_from01 on rule_from (rule_id); +Create index IF NOT EXISTS idx_rule_service01 on rule_service (rule_id); +Create index IF NOT EXISTS idx_rule_service02 on rule_service (svc_id); +Create index IF NOT EXISTS idx_rule_to01 on rule_to (rule_id); +Create index IF NOT EXISTS idx_service01 on service (mgm_id); +Create index IF NOT EXISTS idx_service02 on service (svc_color_id); +Create index IF NOT EXISTS idx_svcgrp_flat01 on svcgrp_flat (svcgrp_flat_id); +Create index IF NOT EXISTS idx_svcgrp_flat02 on svcgrp_flat (svcgrp_flat_member_id); +Create index IF NOT EXISTS idx_usr01 on usr (mgm_id); +Create index IF NOT EXISTS idx_usergrp_flat01 on usergrp_flat (usergrp_flat_id); +Create index IF NOT EXISTS idx_usergrp_flat02 on usergrp_flat (usergrp_flat_member_id); +Create index IF NOT EXISTS idx_zone01 on zone (zone_name,mgm_id); +Create index IF NOT EXISTS idx_zone02 on zone (mgm_id); -- needed as mgm_id is not first column on above composite index + +-- make sure a maximum of one stop_time=null entry exists per mgm_id (only one running import per mgm): +CREATE UNIQUE INDEX uidx_import_control_only_one_null_stop_time_per_mgm_when_null ON import_control (mgm_id) WHERE stop_time IS NULL; + +CREATE UNIQUE index if not exists only_one_default_owner on owner(is_default) where is_default = true; +CREATE UNIQUE index if not exists owner_responsible_owner_dn_type_unique on owner_responsible(owner_id, dn, responsible_type); +CREATE index if not exists owner_responsible_dn_idx on owner_responsible(dn); +CREATE UNIQUE index if not exists owner_responsible_type_name_unique on owner_responsible_type(name); + +Create index "IX_Relationship68" on "changelog_object" ("control_id"); +Create index "IX_Relationship76" on "changelog_service" ("control_id"); +Create index "IX_Relationship77" on "changelog_user" ("control_id"); +Create index "IX_Relationship78" on "changelog_rule" ("control_id"); + +-- tbd +Create unique index "kundennetze_akey" on "tenant_network" using btree ("tenant_net_id","tenant_id"); +Create unique index "rule_from_unique_index" on "rule_from" using btree ("rule_id","obj_id","user_id"); +Create index "import_control_start_time_idx" on "import_control" using btree ("start_time"); + + +Create index "IX_relationship23" on "rule" ("action_id"); +Create index "IX_relationship9" on "object" ("obj_typ_id"); +Create index "IX_relationship24" on "rule" ("track_id"); +Create index "IX_Relationship33" on "service" ("ip_proto_id"); +Create index "IX_Relationship36" on "service" ("svc_typ_id"); +Create index "IX_Relationship37" on "object" ("zone_id"); +Create index "IX_Relationship90" on "rule" ("rule_from_zone"); +Create index "IX_Relationship95" on "rule_from" ("user_id"); +Create index "IX_relationship26" on "rule_from" ("obj_id"); +Create index "IX_relationship28" on "rule_to" ("obj_id"); +Create index "IX_Relationship91" on "rule" ("rule_to_zone"); + +Create index "IX_Relationship65" on "changelog_object" ("old_obj_id"); +Create index "IX_Relationship66" on "changelog_object" ("new_obj_id"); +Create index "IX_Relationship72" on "changelog_rule" ("new_rule_id"); +Create index "IX_Relationship73" on "changelog_rule" ("old_rule_id"); +Create index "IX_Relationship74" on "changelog_service" ("new_svc_id"); +Create index "IX_Relationship75" on "changelog_service" ("old_svc_id"); +Create index "IX_Relationship79" on "changelog_user" ("new_user_id"); +Create index "IX_Relationship80" on "changelog_user" ("old_user_id"); + + +Create index "IX_Relationship120" on "objgrp" ("import_created"); +Create index "IX_Relationship121" on "objgrp" ("import_last_seen"); +Create index "IX_Relationship122" on "svcgrp" ("import_created"); +Create index "IX_Relationship123" on "svcgrp" ("import_last_seen"); +Create index "IX_Relationship50" on "usergrp" ("usergrp_id"); +Create index "IX_Relationship51" on "usergrp" ("usergrp_member_id"); +Create index "IX_Relationship153" on "usergrp" ("import_created"); +Create index "IX_Relationship154" on "usergrp" ("import_last_seen"); + + +Create index "IX_relationship20" on "svcgrp" ("svcgrp_member_id"); +Create index "IX_relationship14" on "objgrp" ("objgrp_member_id"); + +Create index "IX_Relationship107" on "objgrp_flat" ("import_created"); +Create index "IX_Relationship108" on "objgrp_flat" ("import_last_seen"); +Create index "IX_Relationship124" on "svcgrp_flat" ("import_created"); +Create index "IX_Relationship125" on "svcgrp_flat" ("import_last_seen"); +Create index "IX_Relationship151" on "usergrp_flat" ("import_created"); +Create index "IX_Relationship152" on "usergrp_flat" ("import_last_seen"); + +Create index "IX_Relationship166" on "rule" ("rule_create"); +Create index "IX_Relationship167" on "rule" ("rule_last_seen"); +Create index "IX_Relationship168" on "rule_from" ("rf_create"); +Create index "IX_Relationship169" on "rule_from" ("rf_last_seen"); +Create index "IX_Relationship170" on "rule_to" ("rt_create"); +Create index "IX_Relationship171" on "rule_to" ("rt_last_seen"); +Create index "IX_Relationship172" on "rule_service" ("rs_create"); +Create index "IX_Relationship173" on "rule_service" ("rs_last_seen"); +Create index "IX_Relationship174" on "object" ("obj_create"); +Create index "IX_Relationship175" on "object" ("obj_last_seen"); +Create index "IX_Relationship176" on "service" ("svc_create"); +Create index "IX_Relationship177" on "service" ("svc_last_seen"); +Create index "IX_Relationship178" on "zone" ("zone_create"); +Create index "IX_Relationship179" on "zone" ("zone_last_seen"); + +create unique index if not exists only_one_default_owner on owner(is_default) +where is_default = true; + +-- compliance +Create index IF NOT EXISTS idx_fkey_network_zone_id on compliance.ip_range USING HASH (network_zone_id); +Create index IF NOT EXISTS idx_fkey_network_zone_from on compliance.network_zone_communication USING HASH (from_network_zone_id); +Create index IF NOT EXISTS idx_fkey_network_zone_to on compliance.network_zone_communication USING HASH (to_network_zone_id); + +-- rule_owner +CREATE UNIQUE INDEX IF NOT EXISTS idx_rule_owner_removed_is_null_unique ON rule_owner (rule_id, owner_id) WHERE removed IS NULL; \ No newline at end of file diff --git a/roles/database/files/sql/creation/fworch-create-tables-base.sql b/roles/database/files/sql/creation/fworch-create-tables-base.sql new file mode 100755 index 0000000000..2dfc99f8d0 --- /dev/null +++ b/roles/database/files/sql/creation/fworch-create-tables-base.sql @@ -0,0 +1,525 @@ +-- the abs_hange_id is needed as it is incremented across 4 different tables +Create sequence "public"."abs_change_id_seq" +Increment 1 +Minvalue 1 +Maxvalue 9223372036854775807 +Cache 1; + +-- the device_type table is only needed for the API +-- it allows for the pre-auth functions to work with hasura +Create table "device_type" +( + "id" int, + "name" VARCHAR +); + +-- fundamental firewall data ------------------------------------- + +Create table "device" -- contains an entry for each firewall gateway +( + "dev_id" SERIAL, + "mgm_id" Integer NOT NULL, + "dev_name" Varchar, + "dev_uid" Varchar, + "local_rulebase_name" Varchar, + "local_rulebase_uid" Varchar, + "global_rulebase_name" Varchar, + "global_rulebase_uid" Varchar, + "package_name" Varchar, + "package_uid" Varchar, + "dev_typ_id" Integer NOT NULL, + "dev_active" Boolean NOT NULL Default true, + "dev_comment" Text, + "dev_create" Timestamp NOT NULL Default now(), + "dev_update" Timestamp NOT NULL Default now(), + "do_not_import" Boolean NOT NULL Default FALSE, + "clearing_import_ran" Boolean NOT NULL Default FALSE, + "force_initial_import" Boolean NOT NULL Default FALSE, + "hide_in_gui" Boolean NOT NULL Default false, + primary key ("dev_id") +); + +Create table "management" -- contains an entry for each firewall management system +( + "mgm_id" SERIAL, + "dev_typ_id" Integer NOT NULL, + "mgm_name" Varchar NOT NULL, + "mgm_comment" Text, + "cloud_tenant_id" VARCHAR, + "cloud_subscription_id" VARCHAR, + "mgm_create" Timestamp NOT NULL Default now(), + "mgm_update" Timestamp NOT NULL Default now(), + "import_credential_id" Integer NOT NULL, + "ssh_hostname" Varchar NOT NULL, + "ssh_port" Integer NOT NULL Default 22, + "last_import_md5_complete_config" Varchar Default 0, + "last_import_attempt" Timestamp, + "last_import_attempt_successful" Boolean NOT NULL Default false, + "do_not_import" Boolean NOT NULL Default FALSE, + "clearing_import_ran" Boolean NOT NULL Default false, + "force_initial_import" Boolean NOT NULL Default FALSE, + "config_path" Varchar, + "domain_uid" Varchar, + "hide_in_gui" Boolean NOT NULL Default false, + "importer_hostname" Varchar, + "debug_level" Integer, + "multi_device_manager_id" integer, -- if this manager belongs to another multi_device_manager, then this id points to it + "is_super_manager" BOOLEAN DEFAULT FALSE, + "ext_mgm_data" Varchar, + "mgm_uid" Varchar NOT NULL DEFAULT '', + "rulebase_name" Varchar NOT NULL DEFAULT '', + "rulebase_uid" Varchar NOT NULL DEFAULT '', + primary key ("mgm_id") +); + + +create table import_credential +( + id SERIAL PRIMARY KEY, + credential_name varchar NOT NULL, + is_key_pair BOOLEAN default FALSE, + username varchar NOT NULL, + secret text NOT NULL, + public_key Text, + cloud_client_id VARCHAR, + cloud_client_secret VARCHAR +); + +Create table "object" +( + "obj_id" BIGSERIAL, + "last_change_admin" Integer, + "zone_id" Integer, + "mgm_id" Integer NOT NULL, + "obj_name" Varchar, + "obj_comment" Varchar, + "obj_uid" Text, + "obj_typ_id" Integer NOT NULL, + "obj_location" Varchar, + "obj_member_names" Text, + "obj_member_refs" Text, + "initial_config" Boolean NOT NULL Default FALSE, + "obj_sw" Varchar, + "obj_ip" Cidr, + "obj_ip_end" Cidr, + "obj_nat" Boolean Default false, + "nattyp_id" Integer, + "obj_nat_ip" Cidr, + "obj_nat_ip_end" Cidr, + "obj_nat_install" Integer, + "obj_color_id" Integer Default 1, + "obj_sys_name" Varchar, + "obj_sys_location" Varchar, + "obj_sys_contact" Varchar, + "obj_sys_desc" Text, + "obj_sys_readcom" Varchar, + "obj_sys_writecom" Varchar, + "active" Boolean NOT NULL Default TRUE, + "obj_create" BIGINT NOT NULL, + "obj_last_seen" BIGINT NOT NULL, + "removed" BIGINT, + primary key ("obj_id") +); + +Create table "objgrp" +( + "objgrp_id" BIGINT NOT NULL, + "objgrp_member_id" BIGINT NOT NULL, + "import_created" BIGINT NOT NULL, + "import_last_seen" BIGINT NOT NULL, + "active" Boolean NOT NULL Default TRUE, + "negated" Boolean NOT NULL Default FALSE, + "removed" BIGINT, + primary key ("objgrp_id","objgrp_member_id") +); + +Create table "service" +( + "svc_id" BIGSERIAL, + "svc_uid" Text, + "svc_name" Varchar, + "svc_typ_id" Integer NOT NULL, + "mgm_id" Integer, + "svc_comment" Text, + "svc_prod_specific" Text, + "svc_member_names" Text, + "svc_member_refs" Text, + "svc_color_id" Integer Default 1, + "ip_proto_id" Integer, + "svc_port" Integer Check (svc_port is NULL OR (svc_port>=0 and svc_port<=65535)), + "svc_port_end" Integer Check (svc_port_end IS NULL OR (svc_port_end>=0 and svc_port_end<=65535)), + "initial_config" Boolean NOT NULL Default FALSE, + "srv_keeponinstall" Boolean Default false, + "svc_rpcnr" Varchar, + "svc_code" Varchar, + "svc_match" Text, + "svc_source_port" Integer Check (svc_source_port is NULL OR (svc_source_port>=0 and svc_source_port<=65535)), + "svc_source_port_end" Integer Check (svc_source_port_end is NULL OR (svc_source_port_end>=0 and svc_source_port_end<=65535)), + "svc_tcp_res" Boolean Default false, + "svc_accept_rep" Boolean Default false, + "svc_accept_rep_any" Boolean Default false, + "svc_mfa" Boolean Default false, + "svc_timeout_std" Boolean Default false, + "svc_timeout" Integer, + "svc_sync" Boolean Default false, + "svc_sync_delay" Boolean Default false, + "svc_sync_delay_start" Integer, + "active" Boolean NOT NULL Default TRUE, + "last_change_admin" Integer, + "svc_create" BIGINT NOT NULL, + "svc_last_seen" BIGINT NOT NULL, + "removed" BIGINT, + primary key ("svc_id") +); + +Create table "svcgrp" +( + "svcgrp_id" BIGINT NOT NULL, + "svcgrp_member_id" BIGINT NOT NULL, + "import_created" BIGINT NOT NULL, + "import_last_seen" BIGINT NOT NULL, + "active" Boolean NOT NULL Default TRUE, + "negated" Boolean NOT NULL Default FALSE, + "removed" BIGINT, + primary key ("svcgrp_id","svcgrp_member_id") +); + +Create table "zone" +( + "zone_id" SERIAL, + "zone_create" BIGINT NOT NULL, + "zone_last_seen" BIGINT NOT NULL, + "mgm_id" Integer NOT NULL, + "zone_name" Varchar NOT NULL, + "active" Boolean NOT NULL Default TRUE, + "removed" BIGINT, + primary key ("zone_id") +); + +Create table "usr" +( + "user_id" BIGSERIAL PRIMARY KEY, + "usr_typ_id" Integer NOT NULL, + "user_color_id" Integer Default 1, + "mgm_id" Integer NOT NULL, + "user_name" Varchar NOT NULL, + "active" Boolean NOT NULL Default TRUE, + "user_member_names" Text, + "user_member_refs" Text, + "user_authmethod" Varchar, + "user_valid_from" Date Default '1900-01-01', + "user_valid_until" Date Default '9999-12-31', + "src_restrict" Text, + "dst_restrict" Text, + "time_restrict" Text, + "user_create" BIGINT NOT NULL, + "user_last_seen" BIGINT NOT NULL, + "user_comment" Text, + "user_uid" Text, + "user_firstname" Varchar, + "user_lastname" Varchar, + "last_change_admin" Integer, + "tenant_id" Integer, + "removed" BIGINT +); + +Create table "usergrp" +( + "usergrp_id" BIGINT, + "usergrp_member_id" BIGINT, + "import_created" BIGINT NOT NULL, + "import_last_seen" BIGINT NOT NULL, + "active" Boolean NOT NULL Default TRUE, + "removed" BIGINT, + primary key ("usergrp_id","usergrp_member_id") +); + + +-- uiuser - change metadata ------------------------------------- + +Create table "uiuser" +( + "uiuser_id" SERIAL NOT NULL, + "uiuser_username" Varchar, + "uuid" Varchar NOT NULL UNIQUE, + "uiuser_first_name" Varchar, + "uiuser_last_name" Varchar, + "uiuser_start_date" Date Default now(), + "uiuser_end_date" Date, + "uiuser_email" Varchar, + "tenant_id" Integer, + "uiuser_language" Varchar, + "uiuser_password_must_be_changed" Boolean NOT NULL Default TRUE, + "uiuser_last_login" Timestamp with time zone, + "uiuser_last_password_change" Timestamp with time zone, + "uiuser_pwd_history" Text, + "ldap_connection_id" BIGINT, + primary key ("uiuser_id") +); + +-- text tables ---------------------------------------- + +Create table "language" +( + "name" Varchar NOT NULL UNIQUE, + "culture_info" Varchar NOT NULL, + primary key ("name") +); + +Create table "txt" +( + "id" Varchar NOT NULL, + "language" Varchar NOT NULL, + "txt" Varchar NOT NULL, + primary key ("id", "language") +); + +Create table "customtxt" +( + "id" Varchar NOT NULL, + "language" Varchar NOT NULL, + "txt" Varchar NOT NULL, + primary key ("id", "language") +); + +Create table "error" +( + "error_id" Varchar NOT NULL UNIQUE, + "error_lvl" Integer NOT NULL, + "error_txt_ger" Text NOT NULL, + "error_txt_eng" Text NOT NULL, + primary key ("error_id") +); + +-- tenant ------------------------------------- +Create table "tenant" +( + "tenant_id" SERIAL, + "tenant_name" Varchar NOT NULL UNIQUE, + "tenant_projekt" Varchar, + "tenant_comment" Text, + "tenant_report" Boolean Default true, + "tenant_can_view_all_devices" Boolean NOT NULL Default false, + "tenant_is_superadmin" Boolean NOT NULL default false, + "tenant_create" Timestamp NOT NULL Default now(), + primary key ("tenant_id") +); + +Create table tenant_to_management +( + tenant_id Integer NOT NULL, + management_id Integer NOT NULL, + shared BOOLEAN NOT NULL DEFAULT TRUE, + primary key ("tenant_id", "management_id") +); + +Create table "tenant_to_device" +( + "tenant_id" Integer NOT NULL, + "device_id" Integer NOT NULL, + shared Boolean NOT NULL DEFAULT TRUE, + primary key ("tenant_id", "device_id") +); + +Create table "tenant_network" +( + "tenant_net_id" BIGSERIAL, + "tenant_id" Integer NOT NULL, + "tenant_net_name" Varchar, + "tenant_net_comment" Text, + "tenant_net_ip" Cidr NOT NULL, + "tenant_net_ip_end" Cidr NOT NULL, + "tenant_net_create" Timestamp NOT NULL Default now(), + primary key ("tenant_net_id") +); + +-- basic static data ------------------------------------- + +Create table "import_control" +( + "control_id" BIGSERIAL, + "start_time" Timestamp NOT NULL Default now(), + "stop_time" Timestamp, + "import_type_id" INTEGER NOT NULL, + "is_initial_import" Boolean NOT NULL Default FALSE, + "mgm_id" Integer, + "successful_import" Boolean NOT NULL Default FALSE, + "policy_changes_found" Boolean NOT NULL Default FALSE, -- old_field: rule_changes_found + "changes_found" Boolean NOT NULL Default FALSE, -- old_field: any_changes_found + "import_errors" Varchar, + "notification_done" Boolean NOT NULL Default FALSE, + "rule_owner_mapping_done" Boolean NOT NULL Default FALSE, + "security_relevant_changes_counter" INTEGER NOT NULL Default 0, + primary key ("control_id") +); + +-- temporary table for storing the fw-relevant config during import +CREATE table "import_config" ( + "import_id" bigint NOT NULL, + "mgm_id" integer NOT NULL, + "config" jsonb NOT NULL, + "start_import_flag" Boolean NOT NULL Default FALSE, + "debug_mode" Boolean Default FALSE +); + +-- todo: move this to git instead +-- permanent table for storing the full config as an archive +CREATE TABLE "import_full_config" ( + "import_id" bigint NOT NULL, + "mgm_id" integer NOT NULL, + "config" jsonb NOT NULL, + PRIMARY KEY ("import_id") +); + +CREATE TABLE "latest_config" ( + "mgm_id" integer NOT NULL, + "import_id" bigint NOT NULL, + "config" jsonb NOT NULL, + PRIMARY KEY ("mgm_id") +); + +--------------------------------------------------------------------------------------- +-- adding interfaces and routing for path analysis +-- drop table if exists gw_route; +-- drop table if exists gw_interface; + +create table gw_interface +( + id SERIAL PRIMARY KEY, + routing_device INTEGER NOT NULL, + name VARCHAR NOT NULL, + ip CIDR, + state_up BOOLEAN DEFAULT TRUE, + ip_version INTEGER NOT NULL DEFAULT 4, + netmask_bits INTEGER NOT NULL +); + +create table gw_route +( + id SERIAL PRIMARY KEY, + routing_device INT NOT NULL, + target_gateway CIDR NOT NULL, + destination CIDR NOT NULL, + source CIDR, + interface_id INT, + interface VARCHAR, + static BOOLEAN DEFAULT TRUE, + metric INT, + distance INT, + ip_version INTEGER NOT NULL DEFAULT 4 +); + +-- (change)log tables ------------------------------------- + +Create table "log_data_issue" +( + "data_issue_id" BIGSERIAL, + "import_id" BIGINT, + "object_name" Varchar, + "object_uid" Varchar, + "rule_uid" Varchar, -- if a rule ref is broken + "rule_id" BIGINT, -- if a rule ref is broken + "object_type" Varchar, + "suspected_cause" VARCHAR, + "description" VARCHAR, + "issue_mgm_id" INTEGER, + "issue_dev_id" INTEGER, + "severity" INTEGER NOT NULL DEFAULT 1, + "source" VARCHAR NOT NULL DEFAULT 'import', + "issue_timestamp" TIMESTAMP DEFAULT NOW(), + "user_id" INTEGER DEFAULT 0, + primary key ("data_issue_id") +); + +Create table "alert" +( + "alert_id" BIGSERIAL, + "ref_log_id" BIGINT, + "ref_alert_id" BIGINT, + "source" VARCHAR NOT NULL, + "title" VARCHAR, + "description" VARCHAR, + "alert_mgm_id" INTEGER, + "alert_dev_id" INTEGER, + "alert_timestamp" TIMESTAMP DEFAULT NOW(), + "user_id" INTEGER DEFAULT 0, + "ack_by" INTEGER, + "ack_timestamp" TIMESTAMP, + "json_data" json, + "alert_code" INTEGER, + primary key ("alert_id") +); + +create table notification +( + id SERIAL PRIMARY KEY, + notification_client Varchar, + name Varchar, + user_id int, + owner_id int, + channel Varchar, + recipient_to Varchar, + email_address_to Varchar, + recipient_cc Varchar, + email_address_cc Varchar, + email_subject Varchar, + layout Varchar, + deadline Varchar, + interval_before_deadline int, + offset_before_deadline int, + repeat_interval_after_deadline int, + initial_offset_after_deadline int, + repeat_offset_after_deadline int, + repetitions_after_deadline int, + last_sent Timestamp, + email_body Varchar, + schedule_id Integer, + bundle_type Varchar, + bundle_id Varchar + ); + +-- configuration + +Create table "ldap_connection" +( + "ldap_connection_id" BIGSERIAL, + "ldap_server" Varchar NOT NULL, + "ldap_port" Integer NOT NULL Default 636, + "ldap_tls" Boolean NOT NULL Default TRUE, + "ldap_searchpath_for_users" Varchar NOT NULL, + "ldap_searchpath_for_roles" Varchar, + "ldap_tenant_level" Integer NOT NULL Default 1, + "ldap_search_user" Varchar NOT NULL, + "ldap_search_user_pwd" Varchar NOT NULL, + "ldap_write_user" Varchar, + "tenant_id" Integer, + "ldap_write_user_pwd" Varchar, + "ldap_searchpath_for_groups" Varchar, + "ldap_writepath_for_groups" Varchar, + "ldap_type" Integer NOT NULL Default 0, + "ldap_pattern_length" Integer NOT NULL Default 0, + "ldap_name" Varchar, + "ldap_global_tenant_name" Varchar, + "active" Boolean NOT NULL Default TRUE, + primary key ("ldap_connection_id") +); + +Create table "config" +( + "config_key" VARCHAR NOT NULL, + "config_value" VARCHAR, + "config_user" Integer, + primary key ("config_key","config_user") +); + +create table time_object +( + time_obj_id BIGSERIAL PRIMARY KEY, + mgm_id Integer NOT NULL, + time_obj_uid Varchar, + time_obj_name Varchar, + start_time TIMESTAMP WITH TIME ZONE, + end_time TIMESTAMP WITH TIME ZONE, + created BIGINT, + removed BIGINT +); diff --git a/roles/database/files/sql/creation/fworch-create-tables-changelog.sql b/roles/database/files/sql/creation/fworch-create-tables-changelog.sql new file mode 100644 index 0000000000..1b0faa0d52 --- /dev/null +++ b/roles/database/files/sql/creation/fworch-create-tables-changelog.sql @@ -0,0 +1,125 @@ + +Create table "import_changelog" +( + "change_time" Timestamp, + "management_name" Varchar, + "changed_object_name" Varchar, + "changed_object_uid" Varchar, + "changed_object_type" Varchar, + "change_action" Varchar NOT NULL, + "change_admin" Varchar, + "control_id" BIGINT NOT NULL, + "import_changelog_nr" BIGINT, + "import_changelog_id" BIGSERIAL, + primary key ("import_changelog_id") +); + +Create table "changelog_object" +( + "log_obj_id" BIGSERIAL, + "new_obj_id" BIGINT Constraint "changelog_object_new_obj_id_constraint" Check ((change_action='D' AND new_obj_id IS NULL) OR NOT new_obj_id IS NULL), + "old_obj_id" BIGINT Constraint "changelog_object_old_obj_id_constraint" Check ((change_action='I' AND old_obj_id IS NULL) OR NOT old_obj_id IS NULL), + "import_admin" Integer, + "doku_admin" Integer, + "control_id" BIGINT NOT NULL, + "abs_change_id" BIGINT NOT NULL Default nextval('public.abs_change_id_seq'::text) UNIQUE, + "change_action" Char(1) NOT NULL, + "changelog_obj_comment" Text, + "documented" Boolean NOT NULL Default FALSE, + "docu_time" Timestamp, + "mgm_id" Integer NOT NULL, + "change_type_id" Integer NOT NULL Default 3, + "security_relevant" Boolean NOT NULL Default TRUE, + "change_request_info" Varchar, + "change_time" Timestamp, + "unique_name" Varchar, + primary key ("log_obj_id") +); + +Create table "changelog_service" +( + "log_svc_id" BIGSERIAL, + "doku_admin" Integer, + "control_id" BIGINT NOT NULL, + "import_admin" Integer, + "new_svc_id" BIGINT Constraint "changelog_service_new_svc_id_constraint" Check ((change_action='D' AND new_svc_id IS NULL) OR NOT new_svc_id IS NULL), + "old_svc_id" BIGINT Constraint "changelog_service_old_svc_id_constraint" Check ((change_action='I' AND old_svc_id IS NULL) OR NOT old_svc_id IS NULL), + "abs_change_id" BIGINT NOT NULL Default nextval('public.abs_change_id_seq'::text) UNIQUE, + "change_action" Char(1) NOT NULL, + "changelog_svc_comment" Text, + "documented" Boolean NOT NULL Default FALSE, + "docu_time" Timestamp, + "mgm_id" Integer NOT NULL, + "change_type_id" Integer NOT NULL Default 3, + "security_relevant" Boolean NOT NULL Default TRUE, + "change_request_info" Varchar, + "change_time" Timestamp, + "unique_name" Varchar, + primary key ("log_svc_id") +); + +Create table "changelog_user" +( + "log_usr_id" BIGSERIAL, + "new_user_id" BIGINT Constraint "changelog_user_new_user_id_constraint" Check ((change_action='D' AND new_user_id IS NULL) OR NOT new_user_id IS NULL), + "old_user_id" BIGINT Constraint "changelog_user_old_user_id_contraint" Check ((change_action='I' AND old_user_id IS NULL) OR NOT old_user_id IS NULL), + "import_admin" Integer, + "doku_admin" Integer, + "control_id" BIGINT NOT NULL, + "abs_change_id" BIGINT NOT NULL Default nextval('public.abs_change_id_seq'::text) UNIQUE, + "change_action" Char(1) NOT NULL, + "changelog_user_comment" Text, + "documented" Boolean NOT NULL Default FALSE, + "docu_time" Timestamp, + "mgm_id" Integer NOT NULL, + "change_type_id" Integer NOT NULL Default 3, + "security_relevant" Boolean NOT NULL Default TRUE, + "change_request_info" Varchar, + "change_time" Timestamp, + "unique_name" Varchar, + primary key ("log_usr_id") +); + +Create table "changelog_rule" +( + "log_rule_id" BIGSERIAL, + "doku_admin" Integer, + "control_id" BIGINT NOT NULL, + "import_admin" Integer, + "new_rule_id" BIGINT Constraint "changelog_rule_new_rule_id_constraint" Check ((change_action='D' AND new_rule_id IS NULL) OR NOT new_rule_id IS NULL), + "old_rule_id" BIGINT Constraint "changelog_rule_old_rule_id_constraint" Check ((change_action='I' AND old_rule_id IS NULL) OR NOT old_rule_id IS NULL), + "implicit_change" Boolean NOT NULL Default FALSE, + "abs_change_id" BIGINT NOT NULL Default nextval('public.abs_change_id_seq'::text) UNIQUE, + "change_action" Char(1) NOT NULL, + "changelog_rule_comment" Text, + "documented" Boolean NOT NULL Default FALSE, + "docu_time" Timestamp, + "mgm_id" Integer NOT NULL, + "dev_id" Integer, + "change_type_id" Integer NOT NULL Default 3, + "security_relevant" Boolean NOT NULL Default TRUE, + "change_request_info" Varchar, + "change_time" Timestamp, + "unique_name" Varchar, + primary key ("log_rule_id") +); + +Create table "changelog_owner" +( + "log_owner_id" BIGSERIAL, + "control_id" BIGINT NOT NULL, + "new_owner_id" BIGINT Constraint "changelog_owner_new_rule_id_constraint" Check ((change_action='D' AND new_owner_id IS NULL) OR NOT new_owner_id IS NULL), + "old_owner_id" BIGINT Constraint "changelog_owner_old_rule_id_constraint" Check ((change_action='I' AND old_owner_id IS NULL) OR NOT old_owner_id IS NULL), + "abs_change_id" BIGINT NOT NULL Default nextval('public.abs_change_id_seq'::text) UNIQUE, + "change_action" Char(1) NOT NULL, + "source_id" Varchar, + "security_relevant" Boolean NOT NULL Default TRUE, + primary key ("log_owner_id") +); + +Create table "stm_change_type" +( + "change_type_id" Integer, + "change_type_name" Varchar, + primary key ("change_type_id") +); diff --git a/roles/database/files/sql/creation/fworch-create-tables-compliance.sql b/roles/database/files/sql/creation/fworch-create-tables-compliance.sql new file mode 100644 index 0000000000..0fbad2fd8f --- /dev/null +++ b/roles/database/files/sql/creation/fworch-create-tables-compliance.sql @@ -0,0 +1,96 @@ + +--- Compliance --- +create schema compliance; + +create table compliance.network_zone +( + id BIGSERIAL PRIMARY KEY, + name VARCHAR NOT NULL, + description VARCHAR NOT NULL, + super_network_zone_id bigint, + owner_id bigint, + removed timestamp with time zone, + created timestamp with time zone default now(), + criterion_id INT, + id_string TEXT, + is_auto_calculated_internet_zone BOOLEAN DEFAULT FALSE, + is_auto_calculated_undefined_internal_zone BOOLEAN DEFAULT FALSE +); + +create table compliance.network_zone_communication +( + criterion_id INT, + from_network_zone_id bigint NOT NULL, + to_network_zone_id bigint NOT NULL, + removed timestamp with time zone, + created timestamp with time zone default now() +); + +create table compliance.ip_range +( + network_zone_id bigint NOT NULL, + ip_range_start inet NOT NULL, + ip_range_end inet NOT NULL, + PRIMARY KEY(network_zone_id, ip_range_start, ip_range_end, created), + removed timestamp with time zone, + created timestamp with time zone default now(), + criterion_id INT, + name TEXT +); + +create table compliance.policy +( + id SERIAL PRIMARY KEY, + name TEXT, + created_date timestamp default now(), + disabled bool +); + +create table compliance.policy_criterion +( + policy_id INT NOT NULL, + criterion_id INT NOT NULL, + removed timestamp with time zone, + created timestamp with time zone default now() +); + +create table compliance.criterion +( + id SERIAL PRIMARY KEY, + name TEXT, + comment TEXT, + criterion_type TEXT, + content TEXT, + removed timestamp with time zone, + created timestamp with time zone default now(), + import_source TEXT +); + +create table compliance.violation +( + id BIGSERIAL PRIMARY KEY, + rule_id bigint NOT NULL, + rule_uid TEXT, + mgmt_uid TEXT, + found_date timestamp with time zone default now(), + removed_date timestamp with time zone, + details TEXT, + risk_score real, + policy_id INT NOT NULL, + criterion_id INT NOT NULL, + is_initial BOOLEAN NOT NULL +); + +-- create table compliance.assessability_issue +-- ( +-- violation_id BIGINT NOT NULL, +-- type_id INT NOT NULL, +-- PRIMARY KEY(violation_id, type_id) +-- ); + +-- create table compliance.assessability_issue_type +-- ( +-- type_id INT PRIMARY KEY, +-- type_name VARCHAR(50) NOT NULL +-- ); + diff --git a/roles/database/files/sql/creation/fworch-create-tables-flats.sql b/roles/database/files/sql/creation/fworch-create-tables-flats.sql new file mode 100644 index 0000000000..2541699ba6 --- /dev/null +++ b/roles/database/files/sql/creation/fworch-create-tables-flats.sql @@ -0,0 +1,36 @@ +-- these tables contain redundant data that is imported from the main tables and flattened for easier querying in the UI. +-- They are updated during the import process and are not used for any other purpose. +-- They are not normalized and may contain duplicate data, but this is acceptable for their intended use case. + +Create table "usergrp_flat" +( + "active" Boolean NOT NULL Default TRUE, + "usergrp_flat_id" BIGINT NOT NULL, + "usergrp_flat_member_id" BIGINT NOT NULL, + "import_created" BIGINT NOT NULL, + "import_last_seen" BIGINT NOT NULL, + "removed" BIGINT, + primary key ("usergrp_flat_id","usergrp_flat_member_id") +); + +Create table "objgrp_flat" +( + "objgrp_flat_id" BIGINT NOT NULL, + "objgrp_flat_member_id" BIGINT NOT NULL, + "active" Boolean NOT NULL Default TRUE, + "import_created" BIGINT NOT NULL, + "import_last_seen" BIGINT NOT NULL, + "negated" Boolean NOT NULL Default FALSE, + "removed" BIGINT +); + +Create table "svcgrp_flat" +( + "svcgrp_flat_id" BIGINT NOT NULL, + "svcgrp_flat_member_id" BIGINT NOT NULL, + "import_created" BIGINT NOT NULL, + "import_last_seen" BIGINT NOT NULL, + "active" Boolean NOT NULL Default TRUE, + "negated" Boolean NOT NULL Default FALSE, + "removed" BIGINT +); diff --git a/roles/database/files/sql/creation/fworch-create-tables-modelling.sql b/roles/database/files/sql/creation/fworch-create-tables-modelling.sql new file mode 100644 index 0000000000..abfb734c83 --- /dev/null +++ b/roles/database/files/sql/creation/fworch-create-tables-modelling.sql @@ -0,0 +1,139 @@ + +--- Network modelling --- +create schema modelling; + +create table modelling.nwgroup +( + id BIGSERIAL PRIMARY KEY, + app_id int, + id_string Varchar, + name Varchar, + comment Varchar, + group_type int, + is_deleted boolean default false, + creator Varchar, + creation_date timestamp default now() +); + +create table modelling.connection +( + id SERIAL PRIMARY KEY, + app_id int, + proposed_app_id int, + name Varchar, + reason Text, + is_interface boolean default false, + used_interface_id int, + is_requested boolean default false, + ticket_id bigint, + common_service boolean default false, + is_published boolean default false, + creator Varchar, + creation_date timestamp default now(), + conn_prop Varchar, + extra_params Varchar, + requested_on_fw boolean default false, + removed boolean default false, + removal_date timestamp, + interface_permission Varchar +); + +create table modelling.permitted_owners +( + connection_id int, + app_id int, + primary key (connection_id, app_id) +); + +create table modelling.selected_objects +( + app_id int, + nwgroup_id bigint, + primary key (app_id, nwgroup_id) +); + +create table modelling.selected_connections +( + app_id int, + connection_id int, + primary key (app_id, connection_id) +); + +create table modelling.nwobject_nwgroup +( + nwobject_id bigint, + nwgroup_id bigint, + primary key (nwobject_id, nwgroup_id) +); + +create table modelling.nwgroup_connection +( + nwgroup_id bigint, + connection_id int, + connection_field int, -- enum src=1, dest=2, ... + primary key (nwgroup_id, connection_id, connection_field) +); + +create table modelling.nwobject_connection -- (used only if settings flag is set) +( + nwobject_id bigint, + connection_id int, + connection_field int, -- enum src=1, dest=2, ... + primary key (nwobject_id, connection_id, connection_field) +); + +create table modelling.service +( + id SERIAL PRIMARY KEY, + app_id int, + name Varchar, + is_global boolean default false, + port int, + port_end int, + proto_id int +); + +create table modelling.service_group +( + id SERIAL PRIMARY KEY, + app_id int, + name Varchar, + is_global boolean default false, + comment Varchar, + creator Varchar, + creation_date timestamp default now() +); + +create table modelling.service_service_group +( + service_id int, + service_group_id int, + primary key (service_id, service_group_id) +); + +create table modelling.service_group_connection +( + service_group_id int, + connection_id int, + primary key (service_group_id, connection_id) +); + +create table modelling.service_connection -- (used only if settings flag is set) +( + service_id int, + connection_id int, + primary key (service_id, connection_id) +); + +create table modelling.change_history +( + id BIGSERIAL PRIMARY KEY, + app_id int, + change_type int, + object_type int, + object_id bigint, + change_text Varchar, + changer Varchar, + change_time Timestamp default now(), + change_source Varchar default 'manual' +); diff --git a/roles/database/files/sql/creation/fworch-create-tables-owner.sql b/roles/database/files/sql/creation/fworch-create-tables-owner.sql new file mode 100644 index 0000000000..2d2b231736 --- /dev/null +++ b/roles/database/files/sql/creation/fworch-create-tables-owner.sql @@ -0,0 +1,138 @@ + +-- owner ------------------------------------------------------- + +create table owner +( + id SERIAL PRIMARY KEY, + name Varchar NOT NULL, + -- responsibles stored in owner_responsible table + is_default boolean default false, + tenant_id int, + recert_interval int, + app_id_external varchar UNIQUE, + last_recert_check Timestamp, + recert_check_params Varchar, + criticality Varchar, + owner_lifecycle_state_id int, + active boolean default true, + import_source Varchar, + common_service_possible boolean default false, + last_recertified Timestamp, + last_recertifier int, + last_recertifier_dn Varchar, + next_recert_date Timestamp, + recert_active boolean default false, + decomm_date Timestamp, + additional_info jsonb +); + +create table owner_responsible +( + id SERIAL PRIMARY KEY, + owner_id int NOT NULL, + dn Varchar NOT NULL, + responsible_type int NOT NULL +); + +create table owner_responsible_type +( + id SERIAL PRIMARY KEY, + name Varchar NOT NULL, + active boolean default true, + sort_order int default 0, + allow_modelling boolean default false, + allow_recertification boolean default false +); + +CREATE TABLE owner_lifecycle_state ( + id SERIAL PRIMARY KEY, + name Varchar NOT NULL, + active_state boolean NOT NULL default true +); + +create table owner_network +( + id BIGSERIAL PRIMARY KEY, + owner_id int, + name Varchar, + ip cidr NOT NULL, + ip_end cidr NOT NULL, + port int, + ip_proto_id int, + nw_type int, + import_source Varchar default 'manual', + is_deleted boolean default false, + custom_type int +); + +create table reqtask_owner +( + reqtask_id bigint, + owner_id int +); + +create table rule_owner +( + owner_id int, + rule_metadata_id bigint, + rule_id bigint NOT NULL, + created bigint NOT NULL, + removed bigint, + matched_objects jsonb, + owner_mapping_source_id smallint NOT NULL, + primary key (rule_id, owner_id, created) +); + +create table recertification +( + id BIGSERIAL PRIMARY KEY, + rule_metadata_id bigint NOT NULL, + rule_id bigint NOT NULL, + ip_match varchar, + owner_id int, + user_dn varchar, + recertified boolean default false, + recert_date Timestamp, + comment varchar, + next_recert_date Timestamp, + owner_recert_id bigint +); + +create table owner_recertification +( + id BIGSERIAL PRIMARY KEY, + owner_id int NOT NULL, + user_dn varchar, + recertified boolean default false, + recert_date Timestamp, + comment varchar, + next_recert_date Timestamp, + report_id bigint +); + +create table owner_ticket +( + owner_id int, + ticket_id bigint +); + +create table ext_request +( + id BIGSERIAL PRIMARY KEY, + owner_id int, + ticket_id bigint, + task_number int, + ext_ticket_system varchar, + ext_request_type varchar, + ext_request_content varchar, + ext_query_variables varchar, + ext_request_state varchar, + ext_ticket_id varchar, + last_creation_response varchar, + last_processing_response varchar, + create_date Timestamp default now(), + finish_date Timestamp, + wait_cycles int default 0, + attempts int default 0, + locked boolean default false +); diff --git a/roles/database/files/sql/creation/fworch-create-tables-report.sql b/roles/database/files/sql/creation/fworch-create-tables-report.sql new file mode 100644 index 0000000000..511b3a2ad9 --- /dev/null +++ b/roles/database/files/sql/creation/fworch-create-tables-report.sql @@ -0,0 +1,70 @@ +-- reporting ------------------------------------------------------- + +Create table "report_template" +( + "report_template_id" SERIAL, + "report_filter" Varchar, + "report_template_name" Varchar, -- NOT NULL Default "Report_"|"report_id"::VARCHAR, -- user given name of a report + "report_template_comment" TEXT, + "report_template_create" Timestamp DEFAULT now(), + "report_template_owner" Integer, --FK + "filterline_history" Boolean Default TRUE, -- every time a filterline is sent, we save it for future usage (auto-deleted every 90 days) + "report_parameters" json, + primary key ("report_template_id") +); + +Create table "report_format" +( + "report_format_name" varchar not null, + primary key ("report_format_name") +); + +Create table "report_schedule_format" +( + "report_schedule_format_name" VARCHAR not null, + "report_schedule_id" BIGSERIAL, + primary key ("report_schedule_format_name","report_schedule_id") +); + +Create table "report" +( + "report_id" BIGSERIAL, + "report_template_id" Integer, + "report_start_time" Timestamp, + "report_end_time" Timestamp, + "report_json" json NOT NULL, + "report_pdf" text, + "report_csv" text, + "report_html" text, + "report_name" varchar NOT NULL, + "report_owner_id" Integer NOT NULL, --FK to uiuser + "tenant_wide_visible" Integer, + "report_type" Integer, + "description" varchar, + "read_only" Boolean default FALSE, + "owner_id" Integer, + primary key ("report_id") +); + +Create table "report_schedule" +( + "report_schedule_id" BIGSERIAL, + "report_schedule_name" Varchar, -- NOT NULL Default "Report_"|"report_id"::VARCHAR, -- user given name of a report + "report_template_id" Integer, --FK + "report_schedule_owner" Integer NOT NULL, --FK + "report_schedule_start_time" Timestamp NOT NULL, -- if day is bigger than 28, simply use the 1st of the next month, 00:00 am + "report_schedule_repeat" Integer Not NULL Default 0, -- 0 do not repeat, 1 daily, 2 weekly, 3 monthly, 4 yearly + "report_schedule_every" Integer Not NULL Default 1, -- x - every x days/weeks/months/years + "report_schedule_active" Boolean Default TRUE, + "report_schedule_repetitions" Integer, + "report_schedule_counter" Integer Not NULL Default 0, + "archive" Boolean Not NULL Default FALSE, + primary key ("report_schedule_id") +); + +Create table "report_template_viewable_by_user" +( + "report_template_id" Integer NOT NULL, + "uiuser_id" Integer NOT NULL, + primary key ("uiuser_id","report_template_id") +); diff --git a/roles/database/files/sql/creation/fworch-create-tables-request.sql b/roles/database/files/sql/creation/fworch-create-tables-request.sql new file mode 100644 index 0000000000..0d22b543df --- /dev/null +++ b/roles/database/files/sql/creation/fworch-create-tables-request.sql @@ -0,0 +1,209 @@ + +-- workflow ------------------------------------------------------- + +-- create schema +create schema request; + +CREATE TYPE rule_field_enum AS ENUM ('source', 'destination', 'service', 'rule', 'modelled_source', 'modelled_destination'); +CREATE TYPE action_enum AS ENUM ('create', 'delete', 'modify', 'unchanged', 'addAfterCreation'); + +-- create tables +create table request.reqtask +( + id BIGSERIAL PRIMARY KEY, + title VARCHAR, + ticket_id bigint, + task_number int, + state_id int NOT NULL, + task_type VARCHAR NOT NULL, + request_action action_enum NOT NULL, + rule_action int, + rule_tracking int, + start Timestamp, + stop Timestamp, + svc_grp_id int, + nw_obj_grp_id int, + user_grp_id int, + free_text text, + reason text, + last_recert_date Timestamp, + current_handler int, + recent_handler int, + assigned_group varchar, + target_begin_date Timestamp, + target_end_date Timestamp, + devices varchar, + additional_info varchar, + mgm_id int +); + +create table request.reqelement +( + id BIGSERIAL PRIMARY KEY, + request_action action_enum NOT NULL default 'create', + task_id bigint, + ip cidr, + ip_end cidr, + port int, + port_end int, + ip_proto_id int, + network_object_id bigint, + service_id bigint, + field rule_field_enum NOT NULL, + user_id bigint, + original_nat_id bigint, + device_id int, + rule_uid varchar, + group_name varchar, + name varchar +); + +create table request.approval +( + id BIGSERIAL PRIMARY KEY, + task_id bigint, + date_opened Timestamp NOT NULL default CURRENT_TIMESTAMP, + approver_group Varchar, + approval_date Timestamp, + approver Varchar, + current_handler int, + recent_handler int, + assigned_group varchar, + tenant_id int, + initial_approval boolean not null default true, + approval_deadline Timestamp, + state_id int NOT NULL +); + +create table request.ticket +( + id BIGSERIAL PRIMARY KEY, + title VARCHAR NOT NULL, + date_created Timestamp NOT NULL default CURRENT_TIMESTAMP, + date_completed Timestamp, + state_id int NOT NULL, + requester_id int, + requester_dn Varchar, + requester_group Varchar, + current_handler int, + recent_handler int, + assigned_group varchar, + tenant_id int, + reason text, + external_ticket_id varchar, + external_ticket_source int, + ticket_deadline Timestamp, + ticket_priority int +); + +create table request.comment +( + id BIGSERIAL PRIMARY KEY, + ref_id bigint, + scope varchar, + creation_date Timestamp, + creator_id int, + comment_text varchar +); + +create table request.ticket_comment +( + ticket_id bigint, + comment_id bigint +); + +create table request.reqtask_comment +( + task_id bigint, + comment_id bigint +); + +create table request.approval_comment +( + approval_id bigint, + comment_id bigint +); + +create table request.impltask_comment +( + task_id bigint, + comment_id bigint +); + +create table request.state +( + id Integer NOT NULL UNIQUE PRIMARY KEY, + name Varchar NOT NULL, + automatic_only boolean NOT NULL DEFAULT FALSE +); + +create table request.ext_state +( + id SERIAL PRIMARY KEY, + name Varchar NOT NULL, + state_id Integer +); + +create table request.action +( + id SERIAL PRIMARY KEY, + name Varchar NOT NULL, + action_type Varchar NOT NULL, + scope Varchar, + task_type Varchar, + phase Varchar, + event Varchar, + button_text Varchar, + external_parameters Varchar +); + +create table request.state_action +( + state_id int, + action_id int +); + +create table request.implelement +( + id BIGSERIAL PRIMARY KEY, + implementation_action action_enum NOT NULL default 'create', + implementation_task_id bigint, + ip cidr, + ip_end cidr, + port int, + port_end int, + ip_proto_id int, + network_object_id bigint, + service_id bigint, + field rule_field_enum NOT NULL, + user_id bigint, + original_nat_id bigint, + rule_uid varchar, + group_name varchar, + name varchar +); + +create table request.impltask +( + id BIGSERIAL PRIMARY KEY, + title VARCHAR, + reqtask_id bigint, + task_number int, + state_id int NOT NULL, + task_type VARCHAR NOT NULL, + device_id int, + implementation_action action_enum NOT NULL, + rule_action int, + rule_tracking int, + start timestamp, + stop timestamp, + svc_grp_id int, + nw_obj_grp_id int, + user_grp_id int, + free_text text, + current_handler int, + recent_handler int, + assigned_group varchar, + target_begin_date Timestamp, + target_end_date Timestamp +); diff --git a/roles/database/files/sql/creation/fworch-create-tables-rule-related.sql b/roles/database/files/sql/creation/fworch-create-tables-rule-related.sql new file mode 100755 index 0000000000..55c56cd4f1 --- /dev/null +++ b/roles/database/files/sql/creation/fworch-create-tables-rule-related.sql @@ -0,0 +1,202 @@ + +Create table "rule" +( + "rule_id" BIGSERIAL, + "last_change_admin" Integer, + "rule_name" Varchar, + "mgm_id" Integer NOT NULL, + "parent_rule_id" BIGINT, + "parent_rule_type" smallint, + "active" Boolean NOT NULL Default TRUE, + "rule_num" Integer NOT NULL, + "rule_num_numeric" NUMERIC(16, 8), + "rule_ruleid" Varchar, + "rule_uid" Text, + "rule_disabled" Boolean NOT NULL Default false, + "rule_src_neg" Boolean NOT NULL Default false, + "rule_dst_neg" Boolean NOT NULL Default false, + "rule_svc_neg" Boolean NOT NULL Default false, + "action_id" Integer NOT NULL, + "track_id" Integer NOT NULL, + "rule_src" Text NOT NULL, + "rule_dst" Text NOT NULL, + "rule_svc" Text NOT NULL, + "rule_src_refs" Text, + "rule_dst_refs" Text, + "rule_svc_refs" Text, + "rule_from_zone" Integer, + "rule_to_zone" Integer, + "rule_action" Text NOT NULL, + "rule_track" Text NOT NULL, + "rule_installon" Varchar, + "rule_time" Varchar, + "rule_comment" Text, + "rule_head_text" Text, + "rule_implied" Boolean NOT NULL Default FALSE, + "rule_create" BIGINT NOT NULL, + "rule_last_seen" BIGINT NOT NULL, + "dev_id" Integer, + "rule_custom_fields" jsonb, + "access_rule" BOOLEAN Default TRUE, + "nat_rule" BOOLEAN Default FALSE, + "xlate_rule" BIGINT, + "is_global" BOOLEAN DEFAULT FALSE NOT NULL, + "rulebase_id" Integer NOT NULL, + "removed" BIGINT, + primary key ("rule_id") +); + +-- rule_metadata contains rule related data that does not change when the rule itself is changed +Create table "rule_metadata" +( + "rule_metadata_id" BIGSERIAL, + "rule_uid" Text NOT NULL, + "mgm_id" Integer NOT NULL, + "rule_created" BIGINT NOT NULL, + "rule_first_hit" Timestamp, + "rule_last_hit" Timestamp, + "rule_hit_counter" BIGINT, + "removed" BIGINT, + primary key ("rule_metadata_id") +); + +Create table "parent_rule_type" +( + "id" smallint NOT NULL, + "name" Varchar NOT NULL, + primary key ("id") +); + +-- adding direct link tables rule_[svc|nwobj|user]_resolved to make report object export easier +Create table "rule_svc_resolved" +( + "mgm_id" INT, + "rule_id" BIGINT NOT NULL, + "svc_id" BIGINT NOT NULL, + "created" BIGINT NOT NULL, + "removed" BIGINT, + primary key ("mgm_id","rule_id","svc_id","created") +); + +Create table "rule_nwobj_resolved" +( + "mgm_id" INT, + "rule_id" BIGINT NOT NULL, + "obj_id" BIGINT NOT NULL, + "created" BIGINT NOT NULL, + "removed" BIGINT, + primary key ("mgm_id","rule_id","obj_id","created") +); + +Create table "rule_user_resolved" +( + "mgm_id" INT, + "rule_id" BIGINT NOT NULL, + "user_id" BIGINT NOT NULL, + "created" BIGINT NOT NULL, + "removed" BIGINT, + primary key ("mgm_id","rule_id","user_id","created") +); + +Create table "rule_from" +-- needs separate primary key as user_id can be null +( + "rule_from_id" BIGSERIAL PRIMARY KEY, + "rule_id" BIGINT NOT NULL, + "obj_id" BIGINT NOT NULL, + "user_id" BIGINT, + "active" Boolean NOT NULL Default TRUE, + "negated" Boolean NOT NULL Default FALSE, + "rf_create" BIGINT NOT NULL, + "rf_last_seen" BIGINT NOT NULL, + "removed" BIGINT +); + +Create table "rule_service" +( + "rule_id" BIGINT NOT NULL, + "svc_id" BIGINT NOT NULL, + "active" Boolean NOT NULL Default TRUE, + "rs_create" BIGINT NOT NULL, + "rs_last_seen" BIGINT NOT NULL, + "negated" Boolean NOT NULL Default FALSE, + "removed" BIGINT, + primary key ("rule_id","svc_id") +); + +Create table "rule_to" +-- needs separate primary key as user_id can be null +( + "rule_to_id" BIGSERIAL PRIMARY KEY, + "rule_id" BIGINT NOT NULL, + "obj_id" BIGINT NOT NULL, + "user_id" BIGINT, + "rt_create" BIGINT NOT NULL, + "rt_last_seen" BIGINT NOT NULL, + "active" Boolean NOT NULL Default TRUE, + "negated" Boolean NOT NULL Default FALSE, + "removed" BIGINT +); + +Create table "rulebase" +( + "id" SERIAL primary key, + "name" Varchar NOT NULL, + "uid" Varchar NOT NULL, + "mgm_id" Integer NOT NULL, + "is_global" BOOLEAN DEFAULT FALSE NOT NULL, + "created" BIGINT, + "removed" BIGINT +); + +Create table "rulebase_link" +( + "id" SERIAL primary key, + "gw_id" Integer, + "from_rulebase_id" Integer, -- either from_rulebase_id or from_rule_id must be SET or the is_initial flag + "from_rule_id" BIGINT, + "to_rulebase_id" Integer NOT NULL, + "link_type" Integer, + "is_initial" BOOLEAN DEFAULT FALSE, + "is_global" BOOLEAN DEFAULT FALSE, + "is_section" BOOLEAN DEFAULT TRUE, + "created" BIGINT, + "removed" BIGINT +); + +Create Table "rule_enforced_on_gateway" +( + "rule_id" Integer NOT NULL, + "dev_id" Integer, -- NULL if rule is available for all gateways of its management + "created" BIGINT, + "removed" BIGINT +); + +--crosstabulation rule zone for source +Create table "rule_from_zone" +( + "rule_id" BIGINT NOT NULL, + "zone_id" Integer NOT NULL, + "created" BIGINT NOT NULL, + "removed" BIGINT, + primary key (rule_id, zone_id, created) +); + +--crosstabulation rule zone for destination +Create table "rule_to_zone" +( + "rule_id" BIGINT NOT NULL, + "zone_id" Integer NOT NULL, + "created" BIGINT NOT NULL, + "removed" BIGINT, + primary key (rule_id, zone_id, created) +); + +create table rule_time +( + rule_time_id BIGSERIAL PRIMARY KEY, + rule_id BIGINT, + time_obj_id BIGINT, + created BIGINT, + removed BIGINT +); diff --git a/roles/database/files/sql/creation/fworch-create-tables-stm.sql b/roles/database/files/sql/creation/fworch-create-tables-stm.sql new file mode 100644 index 0000000000..143f383ec0 --- /dev/null +++ b/roles/database/files/sql/creation/fworch-create-tables-stm.sql @@ -0,0 +1,85 @@ + +Create table "stm_link_type" +( + "id" Integer primary key, + "name" Varchar NOT NULL +); + +Create table "stm_action" +( + "action_id" Integer, + "action_name" Varchar NOT NULL, + "allowed" BOOLEAN NOT NULL DEFAULT TRUE, + primary key ("action_id") +); + +Create table "stm_color" +( + "color_id" SERIAL, + "color_name" Varchar NOT NULL, + "color_rgb" Char(7) NOT NULL, + "color_comment" Text, + primary key ("color_id") +); + +Create table "stm_dev_typ" +( + "dev_typ_id" Integer, + "dev_typ_manufacturer" Varchar, + "dev_typ_name" Varchar NOT NULL, + "dev_typ_version" Varchar NOT NULL, + "dev_typ_comment" Text, + "dev_typ_predef_svc" Text, + "dev_typ_predef_obj" Text, + "dev_typ_is_mgmt" Boolean, + "dev_typ_config_file_rules" Varchar, + "dev_typ_config_file_basic_objects" Varchar, + "dev_typ_config_file_users" Varchar, + "dev_typ_is_multi_mgmt" Boolean Default FALSE, + "is_pure_routing_device" Boolean Default FALSE, + primary key ("dev_typ_id") +); + +Create table "stm_obj_typ" +( + "obj_typ_id" Integer, + "obj_typ_name" Varchar NOT NULL, + "obj_typ_comment" Text, + primary key ("obj_typ_id") +); + +Create table "stm_track" +( + "track_id" Integer, + "track_name" Varchar NOT NULL, + primary key ("track_id") +); + +CREATE TABLE "stm_import" +( + "import_type_id" Integer PRIMARY KEY, + "import_type_name" Varchar NOT NULL +); + +Create table "stm_ip_proto" +( + "ip_proto_id" Integer NOT NULL, + "ip_proto_name" Varchar, + "ip_proto_comment" Text, + primary key ("ip_proto_id") +); + +Create table "stm_svc_typ" +( + "svc_typ_id" Integer NOT NULL UNIQUE, + "svc_typ_name" Varchar, + "svc_typ_comment" Text, + primary key ("svc_typ_id") +); + +Create table "stm_usr_typ" +( + "usr_typ_id" Integer NOT NULL UNIQUE, + "usr_typ_name" Varchar, + primary key ("usr_typ_id") +); diff --git a/roles/database/files/sql/creation/fworch-create-tables.sql b/roles/database/files/sql/creation/fworch-create-tables.sql deleted file mode 100755 index b0c05ac96b..0000000000 --- a/roles/database/files/sql/creation/fworch-create-tables.sql +++ /dev/null @@ -1,1279 +0,0 @@ -/* -Created 29.04.2005 -Last modified 14.07.2023 -Project Firewall Orchestrator -Contact https://cactus.de/fworch -Database PostgreSQL 9-13 -*/ - -/* Create Sequence - -the abs_hange_id is needed as it is incremented across 4 different tables - -*/ - -Create sequence "public"."abs_change_id_seq" -Increment 1 -Minvalue 1 -Maxvalue 9223372036854775807 -Cache 1; - --- the device_type table is only needed for the API --- it allows for the pre-auth functions to work with hasura -Create table "device_type" -( - "id" int, - "name" VARCHAR -); - --- fundamental firewall data ------------------------------------- - -Create table "device" -- contains an entry for each firewall gateway -( - "dev_id" SERIAL, - "mgm_id" Integer NOT NULL, - "dev_name" Varchar, - "local_rulebase_name" Varchar, - "local_rulebase_uid" Varchar, - "global_rulebase_name" Varchar, - "global_rulebase_uid" Varchar, - "package_name" Varchar, - "package_uid" Varchar, - "dev_typ_id" Integer NOT NULL, - "tenant_id" Integer, - "dev_active" Boolean NOT NULL Default true, - "dev_comment" Text, - "dev_create" Timestamp NOT NULL Default now(), - "dev_update" Timestamp NOT NULL Default now(), - "do_not_import" Boolean NOT NULL Default FALSE, - "clearing_import_ran" Boolean NOT NULL Default FALSE, - "force_initial_import" Boolean NOT NULL Default FALSE, - "hide_in_gui" Boolean NOT NULL Default false, - primary key ("dev_id") -); - -Create table "management" -- contains an entry for each firewall management system -( - "mgm_id" SERIAL, - "dev_typ_id" Integer NOT NULL, - "mgm_name" Varchar NOT NULL, - "mgm_comment" Text, - "tenant_id" Integer, - "cloud_tenant_id" VARCHAR, - "cloud_subscription_id" VARCHAR, - "mgm_create" Timestamp NOT NULL Default now(), - "mgm_update" Timestamp NOT NULL Default now(), - "import_credential_id" Integer NOT NULL, - "ssh_hostname" Varchar NOT NULL, - "ssh_port" Integer NOT NULL Default 22, - "last_import_md5_complete_config" Varchar Default 0, - "last_import_attempt" Timestamp, - "last_import_attempt_successful" Boolean NOT NULL Default false, - "do_not_import" Boolean NOT NULL Default FALSE, - "clearing_import_ran" Boolean NOT NULL Default false, - "force_initial_import" Boolean NOT NULL Default FALSE, - "config_path" Varchar, - "domain_uid" Varchar, - "hide_in_gui" Boolean NOT NULL Default false, - "importer_hostname" Varchar, - "debug_level" Integer, - "multi_device_manager_id" integer, -- if this manager belongs to another multi_device_manager, then this id points to it - primary key ("mgm_id") -); - -create table import_credential -( - id SERIAL PRIMARY KEY, - credential_name varchar NOT NULL, - is_key_pair BOOLEAN default FALSE, - username varchar NOT NULL, - secret text NOT NULL, - public_key Text, - cloud_client_id VARCHAR, - cloud_client_secret VARCHAR -); - -Create table "object" -( - "obj_id" BIGSERIAL, - "last_change_admin" Integer, - "zone_id" Integer, - "mgm_id" Integer NOT NULL, - "obj_name" Varchar, - "obj_comment" Varchar, - "obj_uid" Text, - "obj_typ_id" Integer NOT NULL, - "obj_location" Varchar, - "obj_member_names" Text, - "obj_member_refs" Text, - "initial_config" Boolean NOT NULL Default FALSE, - "obj_sw" Varchar, - "obj_ip" Cidr, - "obj_ip_end" Cidr, - "obj_nat" Boolean Default false, - "nattyp_id" Integer, - "obj_nat_ip" Cidr, - "obj_nat_ip_end" Cidr, - "obj_nat_install" Integer, - "obj_color_id" Integer Default 1, - "obj_sys_name" Varchar, - "obj_sys_location" Varchar, - "obj_sys_contact" Varchar, - "obj_sys_desc" Text, - "obj_sys_readcom" Varchar, - "obj_sys_writecom" Varchar, - "active" Boolean NOT NULL Default TRUE, - "obj_create" BIGINT NOT NULL, - "obj_last_seen" BIGINT NOT NULL, - primary key ("obj_id") -); - -Create table "objgrp" -( - "objgrp_id" BIGINT NOT NULL, - "objgrp_member_id" BIGINT NOT NULL, - "import_created" BIGINT NOT NULL, - "import_last_seen" BIGINT NOT NULL, - "active" Boolean NOT NULL Default TRUE, - "negated" Boolean NOT NULL Default FALSE, - primary key ("objgrp_id","objgrp_member_id") -); - -Create table "rule" -( - "rule_id" BIGSERIAL, - "last_change_admin" Integer, - "rule_name" Varchar, - "mgm_id" Integer NOT NULL, - "parent_rule_id" BIGINT, - "parent_rule_type" smallint, - "active" Boolean NOT NULL Default TRUE, - "rule_num" Integer NOT NULL, - "rule_num_numeric" NUMERIC(16, 8), - "rule_ruleid" Varchar, - "rule_uid" Text, - "rule_disabled" Boolean NOT NULL Default false, - "rule_src_neg" Boolean NOT NULL Default false, - "rule_dst_neg" Boolean NOT NULL Default false, - "rule_svc_neg" Boolean NOT NULL Default false, - "action_id" Integer NOT NULL, - "track_id" Integer NOT NULL, - "rule_src" Text NOT NULL, - "rule_dst" Text NOT NULL, - "rule_svc" Text NOT NULL, - "rule_src_refs" Text, - "rule_dst_refs" Text, - "rule_svc_refs" Text, - "rule_from_zone" Integer, - "rule_to_zone" Integer, - "rule_action" Text NOT NULL, - "rule_track" Text NOT NULL, - "rule_installon" Varchar, - "rule_time" Varchar, - "rule_comment" Text, - "rule_head_text" Text, - "rule_implied" Boolean NOT NULL Default FALSE, - "rule_create" BIGINT NOT NULL, - "rule_last_seen" BIGINT NOT NULL, - "dev_id" Integer, - "access_rule" BOOLEAN Default TRUE, - "nat_rule" BOOLEAN Default FALSE, - "xlate_rule" BIGINT, - primary key ("rule_id") -); - --- rule_metadata contains rule related data that does not change when the rule itself is changed -Create table "rule_metadata" -( - "rule_metadata_id" BIGSERIAL, - "dev_id" Integer NOT NULL, - "rule_uid" Text NOT NULL, - "rule_created" Timestamp NOT NULL Default now(), - "rule_last_modified" Timestamp NOT NULL Default now(), - "rule_first_hit" Timestamp, - "rule_last_hit" Timestamp, - "rule_hit_counter" BIGINT, - "rule_last_certified" Timestamp, - "rule_last_certifier" Integer, - "rule_last_certifier_dn" VARCHAR, - "rule_owner" Integer, - "rule_owner_dn" Varchar, -- distinguished name pointing to ldap group, path or user - "rule_to_be_removed" Boolean NOT NULL Default FALSE, - "last_change_admin" Integer, - "rule_decert_date" Timestamp, - "rule_recertification_comment" Varchar, - primary key ("rule_metadata_id") -); - --- adding direct link tables rule_[svc|nwobj|user]_resolved to make report object export easier -Create table "rule_svc_resolved" -( - "mgm_id" INT, - "rule_id" BIGINT NOT NULL, - "svc_id" BIGINT NOT NULL, - "created" BIGINT NOT NULL, - "removed" BIGINT, - primary key ("mgm_id","rule_id","svc_id") -); - -Create table "rule_nwobj_resolved" -( - "mgm_id" INT, - "rule_id" BIGINT NOT NULL, - "obj_id" BIGINT NOT NULL, - "created" BIGINT NOT NULL, - "removed" BIGINT, - primary key ("mgm_id","rule_id","obj_id") -); - -Create table "rule_user_resolved" -( - "mgm_id" INT, - "rule_id" BIGINT NOT NULL, - "user_id" BIGINT NOT NULL, - "created" BIGINT NOT NULL, - "removed" BIGINT, - primary key ("mgm_id","rule_id","user_id") -); - -Create table "rule_from" --- needs separate primary key as user_id can be null -( - "rule_from_id" BIGSERIAL PRIMARY KEY, - "rule_id" BIGINT NOT NULL, - "obj_id" BIGINT NOT NULL, - "user_id" BIGINT, - "active" Boolean NOT NULL Default TRUE, - "negated" Boolean NOT NULL Default FALSE, - "rf_create" BIGINT NOT NULL, - "rf_last_seen" BIGINT NOT NULL -); - -Create table "rule_service" -( - "rule_id" BIGINT NOT NULL, - "svc_id" BIGINT NOT NULL, - "active" Boolean NOT NULL Default TRUE, - "rs_create" BIGINT NOT NULL, - "rs_last_seen" BIGINT NOT NULL, - "negated" Boolean NOT NULL Default FALSE, - primary key ("rule_id","svc_id") -); - -Create table "rule_to" --- needs separate primary key as user_id can be null -( - "rule_to_id" BIGSERIAL PRIMARY KEY, - "rule_id" BIGINT NOT NULL, - "obj_id" BIGINT NOT NULL, - "user_id" BIGINT, - "rt_create" BIGINT NOT NULL, - "rt_last_seen" BIGINT NOT NULL, - "active" Boolean NOT NULL Default TRUE, - "negated" Boolean NOT NULL Default FALSE -); - -Create table "service" -( - "svc_id" BIGSERIAL, - "svc_uid" Text, - "svc_name" Varchar, - "svc_typ_id" Integer NOT NULL, - "mgm_id" Integer, - "svc_comment" Text, - "svc_prod_specific" Text, - "svc_member_names" Text, - "svc_member_refs" Text, - "svc_color_id" Integer Default 1, - "ip_proto_id" Integer, - "svc_port" Integer Check (svc_port is NULL OR (svc_port>=0 and svc_port<=65535)), - "svc_port_end" Integer Check (svc_port_end IS NULL OR (svc_port_end>=0 and svc_port_end<=65535)), - "initial_config" Boolean NOT NULL Default FALSE, - "srv_keeponinstall" Boolean Default false, - "svc_rpcnr" Varchar, - "svc_code" Varchar, - "svc_match" Text, - "svc_source_port" Integer Check (svc_source_port is NULL OR (svc_source_port>=0 and svc_source_port<=65535)), - "svc_source_port_end" Integer Check (svc_source_port_end is NULL OR (svc_source_port_end>=0 and svc_source_port_end<=65535)), - "svc_tcp_res" Boolean Default false, - "svc_accept_rep" Boolean Default false, - "svc_accept_rep_any" Boolean Default false, - "svc_mfa" Boolean Default false, - "svc_timeout_std" Boolean Default false, - "svc_timeout" Integer, - "svc_sync" Boolean Default false, - "svc_sync_delay" Boolean Default false, - "svc_sync_delay_start" Integer, - "active" Boolean NOT NULL Default TRUE, - "last_change_admin" Integer, - "svc_create" BIGINT NOT NULL, - "svc_last_seen" BIGINT NOT NULL, - primary key ("svc_id") -); - -Create table "svcgrp" -( - "svcgrp_id" BIGINT NOT NULL, - "svcgrp_member_id" BIGINT NOT NULL, - "import_created" BIGINT NOT NULL, - "import_last_seen" BIGINT NOT NULL, - "active" Boolean NOT NULL Default TRUE, - "negated" Boolean NOT NULL Default FALSE, - primary key ("svcgrp_id","svcgrp_member_id") -); - -Create table "zone" -( - "zone_id" SERIAL, - "zone_create" BIGINT NOT NULL, - "zone_last_seen" BIGINT NOT NULL, - "mgm_id" Integer NOT NULL, - "zone_name" Varchar NOT NULL, - "active" Boolean NOT NULL Default TRUE, - primary key ("zone_id") -); - -Create table "usr" -( - "user_id" BIGSERIAL PRIMARY KEY, - "usr_typ_id" Integer NOT NULL, - "user_color_id" Integer Default 1, - "mgm_id" Integer NOT NULL, - "user_name" Varchar NOT NULL, - "active" Boolean NOT NULL Default TRUE, - "user_member_names" Text, - "user_member_refs" Text, - "user_authmethod" Varchar, - "user_valid_from" Date Default '1900-01-01', - "user_valid_until" Date Default '9999-12-31', - "src_restrict" Text, - "dst_restrict" Text, - "time_restrict" Text, - "user_create" BIGINT NOT NULL, - "user_last_seen" BIGINT NOT NULL, - "user_comment" Text, - "user_uid" Text, - "user_firstname" Varchar, - "user_lastname" Varchar, - "last_change_admin" Integer, - "tenant_id" Integer -); - -Create table "usergrp" -( - "usergrp_id" BIGINT, - "usergrp_member_id" BIGINT, - "import_created" BIGINT NOT NULL, - "import_last_seen" BIGINT NOT NULL, - "active" Boolean NOT NULL Default TRUE, - primary key ("usergrp_id","usergrp_member_id") -); - -Create table "usergrp_flat" -( - "active" Boolean NOT NULL Default TRUE, - "usergrp_flat_id" BIGINT NOT NULL, - "usergrp_flat_member_id" BIGINT NOT NULL, - "import_created" BIGINT NOT NULL, - "import_last_seen" BIGINT NOT NULL, - primary key ("usergrp_flat_id","usergrp_flat_member_id") -); - -Create table "objgrp_flat" -( - "objgrp_flat_id" BIGINT NOT NULL, - "objgrp_flat_member_id" BIGINT NOT NULL, - "active" Boolean NOT NULL Default TRUE, - "import_created" BIGINT NOT NULL, - "import_last_seen" BIGINT NOT NULL, - "negated" Boolean NOT NULL Default FALSE -); - -Create table "svcgrp_flat" -( - "svcgrp_flat_id" Integer NOT NULL, - "svcgrp_flat_member_id" Integer NOT NULL, - "import_created" Integer NOT NULL, - "import_last_seen" Integer NOT NULL, - "active" Boolean NOT NULL Default TRUE, - "negated" Boolean NOT NULL Default FALSE -); - --- uiuser - change metadata ------------------------------------- - -Create table "uiuser" -( - "uiuser_id" SERIAL NOT NULL, - "uiuser_username" Varchar, - "uuid" Varchar NOT NULL UNIQUE, - "uiuser_first_name" Varchar, - "uiuser_last_name" Varchar, - "uiuser_start_date" Date Default now(), - "uiuser_end_date" Date, - "uiuser_email" Varchar, - "tenant_id" Integer, - "uiuser_language" Varchar, - "uiuser_password_must_be_changed" Boolean NOT NULL Default TRUE, - "uiuser_last_login" Timestamp with time zone, - "uiuser_last_password_change" Timestamp with time zone, - "uiuser_pwd_history" Text, - "ldap_connection_id" BIGINT, - primary key ("uiuser_id") -); - --- text tables ---------------------------------------- - -Create table "language" -( - "name" Varchar NOT NULL UNIQUE, - "culture_info" Varchar NOT NULL, - primary key ("name") -); - -Create table "txt" -( - "id" Varchar NOT NULL, - "language" Varchar NOT NULL, - "txt" Varchar NOT NULL, - primary key ("id", "language") -); - -Create table "error" -( - "error_id" Varchar NOT NULL UNIQUE, - "error_lvl" Integer NOT NULL, - "error_txt_ger" Text NOT NULL, - "error_txt_eng" Text NOT NULL, - primary key ("error_id") -); - --- tenant ------------------------------------- -Create table "tenant" -( - "tenant_id" SERIAL, - "tenant_name" Varchar NOT NULL, - "tenant_projekt" Varchar, - "tenant_comment" Text, - "tenant_report" Boolean Default true, - "tenant_can_view_all_devices" Boolean NOT NULL Default false, - "tenant_is_superadmin" Boolean NOT NULL default false, - "tenant_create" Timestamp NOT NULL Default now(), - primary key ("tenant_id") -); - -Create table "tenant_to_device" -( - "tenant_id" Integer NOT NULL, - "device_id" Integer NOT NULL, - primary key ("tenant_id", "device_id") -); - -Create table "tenant_network" -( - "tenant_net_id" BIGSERIAL, - "tenant_id" Integer NOT NULL, - "tenant_net_name" Varchar, - "tenant_net_comment" Text, - "tenant_net_ip" Cidr, - "tenant_net_ip_end" Cidr, - "tenant_net_create" Timestamp NOT NULL Default now(), - primary key ("tenant_net_id") -); - --- basic static data ------------------------------------- - -Create table "parent_rule_type" -( - "id" smallserial NOT NULL, - "name" Varchar NOT NULL, - primary key ("id") -); - -Create table "stm_action" -( - "action_id" SERIAL, - "action_name" Varchar NOT NULL, - primary key ("action_id") -); - -Create table "stm_color" -( - "color_id" SERIAL, - "color_name" Varchar NOT NULL, - "color_rgb" Char(7) NOT NULL, - "color_comment" Text, - primary key ("color_id") -); - -Create table "stm_dev_typ" -( - "dev_typ_id" SERIAL, - "dev_typ_manufacturer" Varchar, - "dev_typ_name" Varchar NOT NULL, - "dev_typ_version" Varchar NOT NULL, - "dev_typ_comment" Text, - "dev_typ_predef_svc" Text, - "dev_typ_predef_obj" Text, - "dev_typ_is_mgmt" Boolean, - "dev_typ_config_file_rules" Varchar, - "dev_typ_config_file_basic_objects" Varchar, - "dev_typ_config_file_users" Varchar, - "dev_typ_is_multi_mgmt" Boolean Default FALSE, - "is_pure_routing_device" Boolean Default FALSE, - primary key ("dev_typ_id") -); - -Create table "stm_obj_typ" -( - "obj_typ_id" SERIAL, - "obj_typ_name" Varchar NOT NULL, - "obj_typ_comment" Text, - primary key ("obj_typ_id") -); - -Create table "stm_track" -( - "track_id" SERIAL, - "track_name" Varchar NOT NULL, - primary key ("track_id") -); - -Create table "stm_ip_proto" -( - "ip_proto_id" Integer NOT NULL, - "ip_proto_name" Varchar, - "ip_proto_comment" Text, - primary key ("ip_proto_id") -); - -Create table "stm_svc_typ" -( - "svc_typ_id" Integer NOT NULL UNIQUE, - "svc_typ_name" Varchar, - "svc_typ_comment" Text, - primary key ("svc_typ_id") -); - -Create table "stm_usr_typ" -( - "usr_typ_id" Integer NOT NULL UNIQUE, - "usr_typ_name" Varchar, - primary key ("usr_typ_id") -); - --- only permanent import table ----------------------------------------------- --- these tables are only filled during an import run and the import data --- is immediately removed afterwards - -Create table "import_control" -( - "control_id" BIGSERIAL, - "start_time" Timestamp NOT NULL Default now(), - "stop_time" Timestamp, - "is_initial_import" Boolean NOT NULL Default FALSE, - "delimiter_group" Varchar(3) NOT NULL Default '|', - "delimiter_zone" Varchar(3) Default '%', - "delimiter_user" Varchar(3) Default '@', - "delimiter_list" Varchar(3) Default '|', - "mgm_id" Integer NOT NULL, - "last_change_in_config" Timestamp, - "successful_import" Boolean NOT NULL Default FALSE, - "changes_found" Boolean NOT NULL Default FALSE, - "import_errors" Varchar, - primary key ("control_id") -); - --- temporary table for storing the fw-relevant config during import -CREATE table "import_config" ( - "import_id" bigint NOT NULL, - "mgm_id" integer NOT NULL, - "chunk_number" integer, - "config" jsonb NOT NULL, - "start_import_flag" Boolean NOT NULL Default FALSE, - "debug_mode" Boolean Default FALSE -); - --- todo: move this to git instead --- permanent table for storing the full config as an archive -CREATE TABLE "import_full_config" ( - "import_id" bigint NOT NULL, - "mgm_id" integer NOT NULL, - "config" jsonb NOT NULL, - PRIMARY KEY ("import_id") -); - --- temporary import tables ------------------------------------- - -Create table "import_service" -( - "svc_id" BIGSERIAL, - "control_id" BIGINT NOT NULL, - "svc_typ" Text NOT NULL, - "svc_name" Varchar, - "svc_comment" Text, - "svc_color" Text Default 'black', - "ip_proto" Text, - "svc_prod_specific" Text, - "rpc_nr" Varchar, - "svc_uid" Text, - "svc_port" Integer, - "svc_port_end" Integer, - "svc_source_port" Integer, - "svc_source_port_end" Integer, - "svc_timeout_std" Boolean Default false, - "svc_timeout" Integer, - "svc_member_names" Text, - "svc_member_refs" Text, - "last_change_admin" Varchar, - "last_change_time" Timestamp, - "svc_scope" Varchar, - primary key ("svc_id","control_id") -); - -Create table "import_object" -( - "obj_id" BIGSERIAL, - "obj_zone" Text, - "obj_name" Varchar, - "obj_typ" Text NOT NULL, - "obj_member_names" Text, - "obj_member_refs" Text, - "obj_member_excludes" Text, - "obj_sw" Varchar, - "obj_ip" Cidr, - "obj_ip_end" Cidr, - "obj_color" Text Default 'black', - "obj_comment" Text, - "obj_location" Text, - "control_id" BIGINT NOT NULL, - "obj_uid" Text, - "last_change_admin" Varchar, - "last_change_time" Timestamp, - "obj_scope" Varchar, - primary key ("obj_id","control_id") -); - -Create table "import_user" -( - "user_id" BIGSERIAL, - "control_id" BIGINT NOT NULL, - "user_color" Text Default 'black', - "user_name" Varchar NOT NULL, - "user_typ" Text, - "user_comment" Text, - "user_authmethod" Varchar, - "user_valid_from" Text, - "user_valid_until" Text, - "user_member_names" Text, - "user_member_refs" Text, - "user_uid" Text, - "user_firstname" Text, - "user_lastname" Text, - "src_restrict" Text, - "dst_restrict" Text, - "time_restrict" Text, - "last_change_admin" Varchar, - "last_change_time" Timestamp, - "user_scope" Varchar, - primary key ("user_id","control_id") -); - -Create table "import_rule" -( - "control_id" BIGINT NOT NULL, - "rule_id" BIGSERIAL, - "rulebase_name" Varchar NOT NULL, - "rule_num" Integer NOT NULL, - "rule_uid" Text NOT NULL, - "rule_ruleid" Varchar, - "rule_name" Varchar, - "rule_sysid" Varchar, - "rule_disabled" Boolean Default false, - "rule_src_neg" Boolean Default false, - "rule_dst_neg" Boolean Default false, - "rule_svc_neg" Boolean Default false, - "rule_implied" Boolean Default FALSE, - "rule_src" Text NOT NULL, - "rule_dst" Text NOT NULL, - "rule_from_zone" Text, - "rule_to_zone" Text, - "rule_svc" Text, - "rule_action" Text NOT NULL, - "rule_track" Text NOT NULL, - "rule_installon" Varchar, - "rule_time" Varchar, - "rule_comment" Text, - "rule_head_text" Text, - "last_change_admin" Varchar, - "last_change_time" Timestamp, - "rule_scope" Varchar, - "rule_src_refs" Text, - "rule_dst_refs" Text, - "rule_svc_refs" Text, - "parent_rule_uid" Text, - "rule_type" Varchar Default 'access', - "last_hit" Timestamp, - primary key ("control_id","rule_id") -); - -Create table "import_zone" -( - "control_id" BIGINT NOT NULL, - "zone_name" Text NOT NULL, - "last_change_time" Timestamp -); - ---------------------------------------------------------------------------------------- --- adding interfaces and routing for path analysis --- drop table if exists gw_route; --- drop table if exists gw_interface; - -create table gw_interface -( - id SERIAL PRIMARY KEY, - routing_device INTEGER NOT NULL, - name VARCHAR NOT NULL, - ip CIDR, - state_up BOOLEAN DEFAULT TRUE, - ip_version INTEGER NOT NULL DEFAULT 4, - netmask_bits INTEGER NOT NULL -); - -create table gw_route -( - id SERIAL PRIMARY KEY, - routing_device INT NOT NULL, - target_gateway CIDR NOT NULL, - destination CIDR NOT NULL, - source CIDR, - interface_id INT, - interface VARCHAR, - static BOOLEAN DEFAULT TRUE, - metric INT, - distance INT, - ip_version INTEGER NOT NULL DEFAULT 4 -); - --- (change)log tables ------------------------------------- - -Create table "log_data_issue" -( - "data_issue_id" BIGSERIAL, - "import_id" BIGINT, - "object_name" Varchar, - "object_uid" Varchar, - "rule_uid" Varchar, -- if a rule ref is broken - "rule_id" BIGINT, -- if a rule ref is broken - "object_type" Varchar, - "suspected_cause" VARCHAR, - "description" VARCHAR, - "issue_mgm_id" INTEGER, - "issue_dev_id" INTEGER, - "severity" INTEGER NOT NULL DEFAULT 1, - "source" VARCHAR NOT NULL DEFAULT 'import', - "issue_timestamp" TIMESTAMP DEFAULT NOW(), - "user_id" INTEGER DEFAULT 0, - primary key ("data_issue_id") -); - -Create table "alert" -( - "alert_id" BIGSERIAL, - "ref_log_id" BIGINT, - "ref_alert_id" BIGINT, - "source" VARCHAR NOT NULL, - "title" VARCHAR, - "description" VARCHAR, - "alert_mgm_id" INTEGER, - "alert_dev_id" INTEGER, - "alert_timestamp" TIMESTAMP DEFAULT NOW(), - "user_id" INTEGER DEFAULT 0, - "ack_by" INTEGER, - "ack_timestamp" TIMESTAMP, - "json_data" json, - "alert_code" INTEGER, - primary key ("alert_id") -); - -Create table "import_changelog" -( - "change_time" Timestamp, - "management_name" Varchar, - "changed_object_name" Varchar, - "changed_object_uid" Varchar, - "changed_object_type" Varchar, - "change_action" Varchar NOT NULL, - "change_admin" Varchar, - "control_id" BIGINT NOT NULL, - "import_changelog_nr" BIGINT, - "import_changelog_id" BIGSERIAL, - primary key ("import_changelog_id") -); - -Create table "changelog_object" -( - "log_obj_id" BIGSERIAL, - "new_obj_id" BIGINT Constraint "changelog_object_new_obj_id_constraint" Check ((change_action='D' AND new_obj_id IS NULL) OR NOT new_obj_id IS NULL), - "old_obj_id" BIGINT Constraint "changelog_object_old_obj_id_constraint" Check ((change_action='I' AND old_obj_id IS NULL) OR NOT old_obj_id IS NULL), - "import_admin" Integer, - "doku_admin" Integer, - "control_id" BIGINT NOT NULL, - "abs_change_id" BIGINT NOT NULL Default nextval('public.abs_change_id_seq'::text) UNIQUE, - "change_action" Char(1) NOT NULL, - "changelog_obj_comment" Text, - "documented" Boolean NOT NULL Default FALSE, - "docu_time" Timestamp, - "mgm_id" Integer NOT NULL, - "change_type_id" Integer NOT NULL Default 3, - "security_relevant" Boolean NOT NULL Default TRUE, - "change_request_info" Varchar, - "change_time" Timestamp, - "unique_name" Varchar, - primary key ("log_obj_id") -); - -Create table "changelog_service" -( - "log_svc_id" BIGSERIAL, - "doku_admin" Integer, - "control_id" BIGINT NOT NULL, - "import_admin" Integer, - "new_svc_id" BIGINT Constraint "changelog_service_new_svc_id_constraint" Check ((change_action='D' AND new_svc_id IS NULL) OR NOT new_svc_id IS NULL), - "old_svc_id" BIGINT Constraint "changelog_service_old_svc_id_constraint" Check ((change_action='I' AND old_svc_id IS NULL) OR NOT old_svc_id IS NULL), - "abs_change_id" BIGINT NOT NULL Default nextval('public.abs_change_id_seq'::text) UNIQUE, - "change_action" Char(1) NOT NULL, - "changelog_svc_comment" Text, - "documented" Boolean NOT NULL Default FALSE, - "docu_time" Timestamp, - "mgm_id" Integer NOT NULL, - "change_type_id" Integer NOT NULL Default 3, - "security_relevant" Boolean NOT NULL Default TRUE, - "change_request_info" Varchar, - "change_time" Timestamp, - "unique_name" Varchar, - primary key ("log_svc_id") -); - -Create table "changelog_user" -( - "log_usr_id" BIGSERIAL, - "new_user_id" BIGINT Constraint "changelog_user_new_user_id_constraint" Check ((change_action='D' AND new_user_id IS NULL) OR NOT new_user_id IS NULL), - "old_user_id" BIGINT Constraint "changelog_user_old_user_id_contraint" Check ((change_action='I' AND old_user_id IS NULL) OR NOT old_user_id IS NULL), - "import_admin" Integer, - "doku_admin" Integer, - "control_id" BIGINT NOT NULL, - "abs_change_id" BIGINT NOT NULL Default nextval('public.abs_change_id_seq'::text) UNIQUE, - "change_action" Char(1) NOT NULL, - "changelog_user_comment" Text, - "documented" Boolean NOT NULL Default FALSE, - "docu_time" Timestamp, - "mgm_id" Integer NOT NULL, - "change_type_id" Integer NOT NULL Default 3, - "security_relevant" Boolean NOT NULL Default TRUE, - "change_request_info" Varchar, - "change_time" Timestamp, - "unique_name" Varchar, - primary key ("log_usr_id") -); - -Create table "changelog_rule" -( - "log_rule_id" BIGSERIAL, - "doku_admin" Integer, - "control_id" BIGINT NOT NULL, - "import_admin" Integer, - "new_rule_id" BIGINT Constraint "changelog_rule_new_rule_id_constraint" Check ((change_action='D' AND new_rule_id IS NULL) OR NOT new_rule_id IS NULL), - "old_rule_id" BIGINT Constraint "changelog_rule_old_rule_id_constraint" Check ((change_action='I' AND old_rule_id IS NULL) OR NOT old_rule_id IS NULL), - "implicit_change" Boolean NOT NULL Default FALSE, - "abs_change_id" BIGINT NOT NULL Default nextval('public.abs_change_id_seq'::text) UNIQUE, - "change_action" Char(1) NOT NULL, - "changelog_rule_comment" Text, - "documented" Boolean NOT NULL Default FALSE, - "docu_time" Timestamp, - "mgm_id" Integer NOT NULL, - "dev_id" Integer NOT NULL, - "change_type_id" Integer NOT NULL Default 3, - "security_relevant" Boolean NOT NULL Default TRUE, - "change_request_info" Varchar, - "change_time" Timestamp, - "unique_name" Varchar, - primary key ("log_rule_id") -); - -Create table "stm_change_type" -( - "change_type_id" SERIAL, - "change_type_name" Varchar, - primary key ("change_type_id") -); - --- reporting ------------------------------------------------------- - -Create table "report_template" -( - "report_template_id" SERIAL, - "report_filter" Varchar, - "report_template_name" Varchar, -- NOT NULL Default "Report_"|"report_id"::VARCHAR, -- user given name of a report - "report_template_comment" TEXT, - "report_template_create" Timestamp DEFAULT now(), - "report_template_owner" Integer, --FK - "filterline_history" Boolean Default TRUE, -- every time a filterline is sent, we save it for future usage (auto-deleted every 90 days) - "report_parameters" json, - primary key ("report_template_id") -); - -Create table "report_format" -( - "report_format_name" varchar not null, - primary key ("report_format_name") -); - -Create table "report_schedule_format" -( - "report_schedule_format_name" VARCHAR not null, - "report_schedule_id" BIGSERIAL, - primary key ("report_schedule_format_name","report_schedule_id") -); - -Create table "report" -( - "report_id" BIGSERIAL, - "report_template_id" Integer, - "report_start_time" Timestamp, - "report_end_time" Timestamp, - "report_json" json NOT NULL, - "report_pdf" text, - "report_csv" text, - "report_html" text, - "report_name" varchar NOT NULL, - "report_owner_id" Integer NOT NULL, --FK to uiuser - "tenant_wide_visible" Integer, - "report_type" Integer, - "description" varchar, - primary key ("report_id") -); - -Create table "report_schedule" -( - "report_schedule_id" BIGSERIAL, - "report_schedule_name" Varchar, -- NOT NULL Default "Report_"|"report_id"::VARCHAR, -- user given name of a report - "report_template_id" Integer, --FK - "report_schedule_owner" Integer NOT NULL, --FK - "report_schedule_start_time" Timestamp NOT NULL, -- if day is bigger than 28, simply use the 1st of the next month, 00:00 am - "report_schedule_repeat" Integer Not NULL Default 0, -- 0 do not repeat, 1 daily, 2 weekly, 3 monthly, 4 yearly - "report_schedule_every" Integer Not NULL Default 1, -- x - every x days/weeks/months/years - "report_schedule_active" Boolean Default TRUE, - "report_schedule_repetitions" Integer, - "report_schedule_counter" Integer Not NULL Default 0, - primary key ("report_schedule_id") -); - -Create table "report_template_viewable_by_user" -( - "report_template_id" Integer NOT NULL, - "uiuser_id" Integer NOT NULL, - primary key ("uiuser_id","report_template_id") -); - --- configuration - -Create table "ldap_connection" -( - "ldap_connection_id" BIGSERIAL, - "ldap_server" Varchar NOT NULL, - "ldap_port" Integer NOT NULL Default 636, - "ldap_tls" Boolean NOT NULL Default TRUE, - "ldap_searchpath_for_users" Varchar NOT NULL, - "ldap_searchpath_for_roles" Varchar, - "ldap_tenant_level" Integer NOT NULL Default 1, - "ldap_search_user" Varchar NOT NULL, - "ldap_search_user_pwd" Varchar NOT NULL, - "ldap_write_user" Varchar, - "tenant_id" Integer, - "ldap_write_user_pwd" Varchar, - "ldap_searchpath_for_groups" Varchar, - "ldap_type" Integer NOT NULL Default 0, - "ldap_pattern_length" Integer NOT NULL Default 0, - "ldap_name" Varchar, - "ldap_global_tenant_name" Varchar, - "active" Boolean NOT NULL Default TRUE, - primary key ("ldap_connection_id") -); - -Create table "config" -( - "config_key" VARCHAR NOT NULL, - "config_value" VARCHAR, - "config_user" Integer, - primary key ("config_key","config_user") -); - --- owner ------------------------------------------------------- - -create table owner -( - id SERIAL PRIMARY KEY, - name Varchar UNIQUE NOT NULL, - dn Varchar NOT NULL, - group_dn Varchar NOT NULL, - is_default boolean default false, - tenant_id int, - recert_interval int, - app_id_external varchar UNIQUE, - last_recert_check Timestamp, - recert_check_params Varchar -); - -create table owner_network -( - id SERIAL PRIMARY KEY, - owner_id int, - ip cidr NOT NULL, - port int, - ip_proto_id int -); - -create table reqtask_owner -( - reqtask_id bigint, - owner_id int -); - -create table rule_owner -( - owner_id int, - rule_metadata_id bigint -); - -create table recertification -( - id BIGSERIAL PRIMARY KEY, - rule_metadata_id bigint NOT NULL, - rule_id bigint NOT NULL, - ip_match varchar, - owner_id int, - user_dn varchar, - recertified boolean default false, - recert_date Timestamp, - comment varchar, - next_recert_date Timestamp -); - --- workflow ------------------------------------------------------- - --- create schema -create schema request; - -CREATE TYPE rule_field_enum AS ENUM ('source', 'destination', 'service', 'rule'); -CREATE TYPE action_enum AS ENUM ('create', 'delete', 'modify'); - --- create tables -create table request.reqtask -( - id BIGSERIAL PRIMARY KEY, - title VARCHAR, - ticket_id bigint, - task_number int, - state_id int NOT NULL, - task_type VARCHAR NOT NULL, - request_action action_enum NOT NULL, - rule_action int, - rule_tracking int, - start Timestamp, - stop Timestamp, - svc_grp_id int, - nw_obj_grp_id int, - user_grp_id int, - free_text text, - reason text, - last_recert_date Timestamp, - current_handler int, - recent_handler int, - assigned_group varchar, - target_begin_date Timestamp, - target_end_date Timestamp, - devices varchar -); - -create table request.reqelement -( - id BIGSERIAL PRIMARY KEY, - request_action action_enum NOT NULL default 'create', - task_id bigint, - ip cidr, - port int, - ip_proto_id int, - network_object_id bigint, - service_id bigint, - field rule_field_enum NOT NULL, - user_id bigint, - original_nat_id bigint, - device_id int, - rule_uid varchar -); - -create table request.approval -( - id BIGSERIAL PRIMARY KEY, - task_id bigint, - date_opened Timestamp NOT NULL default CURRENT_TIMESTAMP, - approver_group Varchar, - approval_date Timestamp, - approver Varchar, - current_handler int, - recent_handler int, - assigned_group varchar, - tenant_id int, - initial_approval boolean not null default true, - approval_deadline Timestamp, - state_id int NOT NULL -); - -create table request.ticket -( - id BIGSERIAL PRIMARY KEY, - title VARCHAR NOT NULL, - date_created Timestamp NOT NULL default CURRENT_TIMESTAMP, - date_completed Timestamp, - state_id int NOT NULL, - requester_id int, - requester_dn Varchar, - requester_group Varchar, - current_handler int, - recent_handler int, - assigned_group varchar, - tenant_id int, - reason text, - external_ticket_id varchar, - external_ticket_source int, - ticket_deadline Timestamp, - ticket_priority int -); - -create table request.comment -( - id BIGSERIAL PRIMARY KEY, - ref_id bigint, - scope varchar, - creation_date Timestamp, - creator_id int, - comment_text varchar -); - -create table request.ticket_comment -( - ticket_id bigint, - comment_id bigint -); - -create table request.reqtask_comment -( - task_id bigint, - comment_id bigint -); - -create table request.approval_comment -( - approval_id bigint, - comment_id bigint -); - -create table request.impltask_comment -( - task_id bigint, - comment_id bigint -); - -create table request.state -( - id Integer NOT NULL UNIQUE PRIMARY KEY, - name Varchar NOT NULL -); - -create table request.action -( - id SERIAL PRIMARY KEY, - name Varchar NOT NULL, - action_type Varchar NOT NULL, - scope Varchar, - task_type Varchar, - phase Varchar, - event Varchar, - button_text Varchar, - external_parameters Varchar -); - -create table request.state_action -( - state_id int, - action_id int -); - -create table request.implelement -( - id BIGSERIAL PRIMARY KEY, - implementation_action action_enum NOT NULL default 'create', - implementation_task_id bigint, - ip cidr, - port int, - ip_proto_id int, - network_object_id bigint, - service_id bigint, - field rule_field_enum NOT NULL, - user_id bigint, - original_nat_id bigint, - rule_uid varchar -); - -create table request.impltask -( - id BIGSERIAL PRIMARY KEY, - title VARCHAR, - reqtask_id bigint, - task_number int, - state_id int NOT NULL, - task_type VARCHAR NOT NULL, - device_id int, - implementation_action action_enum NOT NULL, - rule_action int, - rule_tracking int, - start timestamp, - stop timestamp, - svc_grp_id int, - nw_obj_grp_id int, - user_grp_id int, - free_text text, - current_handler int, - recent_handler int, - assigned_group varchar, - target_begin_date Timestamp, - target_end_date Timestamp -); - - ---- Compliance --- -create schema compliance; - -create table compliance.network_zone -( - id BIGSERIAL PRIMARY KEY, - name VARCHAR NOT NULL, - description VARCHAR NOT NULL, - super_network_zone_id bigint, - owner_id bigint -); - -create table compliance.network_zone_communication -( - from_network_zone_id bigint NOT NULL, - to_network_zone_id bigint NOT NULL -); - -create table compliance.ip_range -( - network_zone_id bigint NOT NULL, - ip_range_start inet NOT NULL, - ip_range_end inet NOT NULL, - PRIMARY KEY(network_zone_id, ip_range_start, ip_range_end) -); - diff --git a/roles/database/files/sql/creation/fworch-create-triggers.sql b/roles/database/files/sql/creation/fworch-create-triggers.sql index cc0a4ee2be..2a6b18b56e 100644 --- a/roles/database/files/sql/creation/fworch-create-triggers.sql +++ b/roles/database/files/sql/creation/fworch-create-triggers.sql @@ -1,48 +1,4 @@ -------------------- --- the following triggers create the bigserial obj_id as it does not seem to be set automatically, --- when insert via json function and specifying no obj_id - -CREATE OR REPLACE FUNCTION import_object_obj_id_seq() RETURNS TRIGGER AS $$ -BEGIN - NEW.obj_id = coalesce(NEW.obj_id, nextval('import_object_obj_id_seq')); - RETURN NEW; -END; -$$ LANGUAGE plpgsql; - -DROP TRIGGER IF EXISTS import_object_obj_id_seq ON import_object CASCADE; -CREATE TRIGGER import_object_obj_id_seq BEFORE INSERT ON import_object FOR EACH ROW EXECUTE PROCEDURE import_object_obj_id_seq(); - -CREATE OR REPLACE FUNCTION import_service_svc_id_seq() RETURNS TRIGGER AS $$ -BEGIN - NEW.svc_id = coalesce(NEW.svc_id, nextval('import_service_svc_id_seq')); - RETURN NEW; -END; -$$ LANGUAGE plpgsql; - -DROP TRIGGER IF EXISTS import_service_svc_id_seq ON import_service CASCADE; -CREATE TRIGGER import_service_svc_id_seq BEFORE INSERT ON import_service FOR EACH ROW EXECUTE PROCEDURE import_service_svc_id_seq(); - -CREATE OR REPLACE FUNCTION import_user_user_id_seq() RETURNS TRIGGER AS $$ -BEGIN - NEW.user_id = coalesce(NEW.user_id, nextval('import_user_user_id_seq')); - RETURN NEW; -END; -$$ LANGUAGE plpgsql; - -DROP TRIGGER IF EXISTS import_user_user_id_seq ON import_user CASCADE; -CREATE TRIGGER import_user_user_id_seq BEFORE INSERT ON import_user FOR EACH ROW EXECUTE PROCEDURE import_user_user_id_seq(); - -CREATE OR REPLACE FUNCTION import_rule_rule_id_seq() RETURNS TRIGGER AS $$ -BEGIN - NEW.rule_id = coalesce(NEW.rule_id, nextval('import_rule_rule_id_seq')); - RETURN NEW; -END; -$$ LANGUAGE plpgsql; - -DROP TRIGGER IF EXISTS import_rule_rule_id_seq ON import_rule CASCADE; -CREATE TRIGGER import_rule_rule_id_seq BEFORE INSERT ON import_rule FOR EACH ROW EXECUTE PROCEDURE import_rule_rule_id_seq(); - CREATE OR REPLACE FUNCTION gw_interface_id_seq() RETURNS TRIGGER AS $$ BEGIN NEW.id = coalesce(NEW.id, nextval('gw_interface_id_seq')); @@ -65,167 +21,22 @@ $$ LANGUAGE plpgsql; DROP TRIGGER IF EXISTS gw_route_add ON gw_route CASCADE; CREATE TRIGGER gw_route_add BEFORE INSERT ON gw_route FOR EACH ROW EXECUTE PROCEDURE gw_route_add(); -------------------- - -CREATE OR REPLACE FUNCTION import_config_from_json () - RETURNS TRIGGER - AS $BODY$ +-- -- function used during import of owner data +CREATE OR REPLACE FUNCTION recert_refresh_per_owner(i_owner_id INTEGER) RETURNS VOID AS $$ DECLARE - i_mgm_id INTEGER; + r_mgm RECORD; BEGIN - -- networking - IF NEW.chunk_number=0 THEN -- delete all networking data only when starting import, not for each chunk - SELECT INTO i_mgm_id mgm_id FROM import_control WHERE control_id=NEW.import_id; - -- before importing, delete all old interfaces and routes belonging to the current management: - DELETE FROM gw_route WHERE routing_device IN - (SELECT dev_id FROM device LEFT JOIN management ON (device.mgm_id=management.mgm_id) WHERE management.mgm_id=i_mgm_id); - DELETE FROM gw_interface WHERE routing_device IN - (SELECT dev_id FROM device LEFT JOIN management ON (device.mgm_id=management.mgm_id) WHERE management.mgm_id=i_mgm_id); - END IF; - - -- now re-insert the currently found interfaces: - INSERT INTO gw_interface SELECT * FROM jsonb_populate_recordset(NULL::gw_interface, NEW.config -> 'interfaces'); - -- now re-insert the currently found routes: - INSERT INTO gw_route SELECT * FROM jsonb_populate_recordset(NULL::gw_route, NEW.config -> 'routing'); - - -- firewall objects and rules - - INSERT INTO import_object - SELECT - * - FROM - jsonb_populate_recordset(NULL::import_object, NEW.config -> 'network_objects'); - - INSERT INTO import_service - SELECT - * - FROM - jsonb_populate_recordset(NULL::import_service, NEW.config -> 'service_objects'); - - INSERT INTO import_user - SELECT - * - FROM - jsonb_populate_recordset(NULL::import_user, NEW.config -> 'user_objects'); - - INSERT INTO import_zone - SELECT - * - FROM - jsonb_populate_recordset(NULL::import_zone, NEW.config -> 'zone_objects'); - - INSERT INTO import_rule - SELECT - * - FROM - jsonb_populate_recordset(NULL::import_rule, NEW.config -> 'rules'); - - IF NEW.start_import_flag THEN - -- finally start the stored procedure import - PERFORM import_all_main(NEW.import_id, NEW.debug_mode); - END IF; - RETURN NEW; + BEGIN + FOR r_mgm IN + SELECT mgm_id, mgm_name FROM management + LOOP + PERFORM recert_refresh_one_owner_one_mgm (i_owner_id, r_mgm.mgm_id, NULL::TIMESTAMP); + END LOOP; + + EXCEPTION WHEN OTHERS THEN + RAISE EXCEPTION 'Exception caught in recert_refresh_per_owner while handling management %', r_mgm.mgm_name; + END; + RETURN; END; -$BODY$ -LANGUAGE plpgsql -VOLATILE -COST 100; -ALTER FUNCTION public.import_config_from_json () OWNER TO fworch; - - -DROP TRIGGER IF EXISTS import_config_insert ON import_config CASCADE; - -CREATE TRIGGER import_config_insert - BEFORE INSERT ON import_config - FOR EACH ROW - EXECUTE PROCEDURE import_config_from_json (); - - - -------------------------- --- recert refresh trigger - -create or replace function refresh_view_rule_with_owner() -returns trigger language plpgsql -as $$ -begin - refresh materialized view view_rule_with_owner; - return null; -end $$; - -drop trigger IF exists refresh_view_rule_with_owner_delete_trigger ON recertification CASCADE; - -create trigger refresh_view_rule_with_owner_delete_trigger -after delete on recertification for each statement -execute procedure refresh_view_rule_with_owner(); - --- -- function used during import of owner data --- CREATE OR REPLACE FUNCTION recert_refresh_per_owner(i_owner_id INTEGER) RETURNS VOID AS $$ --- DECLARE --- r_mgm RECORD; --- BEGIN --- BEGIN --- FOR r_mgm IN --- SELECT mgm_id, mgm_name FROM management --- LOOP --- PERFORM recert_refresh_one_owner_one_mgm (i_owner_id, r_mgm.mgm_id, NULL::TIMESTAMP); --- END LOOP; - --- EXCEPTION WHEN OTHERS THEN --- RAISE EXCEPTION 'Exception caught in recert_refresh_per_owner while handling management %', r_mgm.mgm_name; --- END; --- RETURN; --- END; --- $$ LANGUAGE plpgsql; - - --- CREATE OR REPLACE FUNCTION owner_change_triggered () --- RETURNS TRIGGER --- AS $BODY$ --- BEGIN --- IF NOT NEW.id IS NULL THEN --- PERFORM recert_refresh_per_owner(NEW.id); --- END IF; --- RETURN NEW; --- END; --- $BODY$ --- LANGUAGE plpgsql --- VOLATILE --- COST 100; --- ALTER FUNCTION public.owner_change_triggered () OWNER TO fworch; - - --- DROP TRIGGER IF EXISTS owner_change ON owner CASCADE; - --- CREATE TRIGGER owner_change --- AFTER INSERT OR UPDATE OR DELETE ON owner --- FOR EACH ROW --- EXECUTE PROCEDURE owner_change_triggered (); - - --- CREATE OR REPLACE FUNCTION owner_network_change_triggered () --- RETURNS TRIGGER --- AS $BODY$ --- BEGIN --- IF NOT NEW.owner_id IS NULL THEN --- PERFORM recert_refresh_per_owner(NEW.owner_id); --- END IF; --- RETURN NEW; --- END; --- $BODY$ --- LANGUAGE plpgsql --- VOLATILE --- COST 100; --- ALTER FUNCTION public.owner_network_change_triggered () OWNER TO fworch; - --- DROP TRIGGER IF EXISTS owner_network_change ON owner_network CASCADE; - --- CREATE TRIGGER owner_network_change --- AFTER INSERT OR UPDATE OR DELETE ON owner_network --- FOR EACH ROW --- EXECUTE PROCEDURE owner_network_change_triggered (); - --- -- LargeOwnerChange: uncomment to disable triggers (e.g. for large installations without recert needs) --- -- ALTER TABLE owner DISABLE TRIGGER owner_change; --- -- ALTER TABLE owner_network DISABLE TRIGGER owner_network_change; +$$ LANGUAGE plpgsql; diff --git a/roles/database/files/sql/creation/fworch-fill-stm.sql b/roles/database/files/sql/creation/fworch-fill-stm.sql index e8447690b2..43b71ed780 100644 --- a/roles/database/files/sql/creation/fworch-fill-stm.sql +++ b/roles/database/files/sql/creation/fworch-fill-stm.sql @@ -7,6 +7,7 @@ insert into uiuser (uiuser_id, uiuser_username, uuid) VALUES (0,'default', 'defa insert into config (config_key, config_value, config_user) VALUES ('DefaultLanguage', 'English', 0); insert into config (config_key, config_value, config_user) VALUES ('sessionTimeout', '720', 0); insert into config (config_key, config_value, config_user) VALUES ('sessionTimeoutNoticePeriod', '60', 0); -- in minutes before expiry +insert into config (config_key, config_value, config_user) VALUES ('uiHostName', 'http://localhost:5000', 0); -- insert into config (config_key, config_value, config_user) VALUES ('maxMessages', '3', 0); insert into config (config_key, config_value, config_user) VALUES ('elementsPerFetch', '100', 0); insert into config (config_key, config_value, config_user) VALUES ('maxInitialFetchesRightSidebar', '10', 0); @@ -32,10 +33,15 @@ insert into config (config_key, config_value, config_user) VALUES ('recCheckActi insert into config (config_key, config_value, config_user) VALUES ('recCheckEmailSubject', 'Upcoming rule recertifications', 0); insert into config (config_key, config_value, config_user) VALUES ('recCheckEmailUpcomingText', 'The following rules are upcoming to be recertified:', 0); insert into config (config_key, config_value, config_user) VALUES ('recCheckEmailOverdueText', 'The following rules are overdue to be recertified:', 0); +insert into config (config_key, config_value, config_user) VALUES ('recCheckParams', '{"check_interval":2,"check_offset":1,"check_weekday":null,"check_dayofmonth":null}', 0); insert into config (config_key, config_value, config_user) VALUES ('recRefreshStartup', 'False', 0); insert into config (config_key, config_value, config_user) VALUES ('recRefreshDaily', 'False', 0); +insert into config (config_key, config_value, config_user) VALUES ('ruleExpiryEmailBody', '', 0); +insert into config (config_key, config_value, config_user) VALUES ('ownerActiveRuleEmailBody', '', 0); +insert into config (config_key, config_value, config_user) VALUES ('ruleExpiryInitiatorKeys', '{}', 0); insert into config (config_key, config_value, config_user) VALUES ('messageViewTime', '7', 0); insert into config (config_key, config_value, config_user) VALUES ('dailyCheckStartAt', '00:00:00', 0); +insert into config (config_key, config_value, config_user) VALUES ('dailyCheckModules', '[1,2,3,4,5,6,7]', 0); insert into config (config_key, config_value, config_user) VALUES ('autoDiscoverStartAt', '00:00:00', 0); insert into config (config_key, config_value, config_user) VALUES ('autoDiscoverSleepTime', '24', 0); insert into config (config_key, config_value, config_user) VALUES ('minCollapseAllDevices', '15', 0); @@ -54,6 +60,7 @@ insert into config (config_key, config_value, config_user) VALUES ('reqRulModSta insert into config (config_key, config_value, config_user) VALUES ('reqGrpCreStateMatrix', '{"config_value":{"request":{"matrix":{"0":[0,49,620],"49":[49,620],"620":[620]},"derived_states":{"0":0,"49":49,"620":620},"lowest_input_state":0,"lowest_start_state":49,"lowest_end_state":49,"active":true},"approval":{"matrix":{"49":[60],"60":[60,99,610],"99":[99],"610":[610]},"derived_states":{"49":49,"60":60,"99":99,"610":610},"lowest_input_state":49,"lowest_start_state":60,"lowest_end_state":99,"active":true},"planning":{"matrix":{"99":[110],"110":[110,120,130,149],"120":[120,110,130,149],"130":[130,110,120,149,610],"149":[149],"610":[610]},"derived_states":{"99":99,"110":110,"120":110,"130":110,"149":149,"610":610},"lowest_input_state":99,"lowest_start_state":110,"lowest_end_state":149,"active":false},"verification":{"matrix":{"149":[160],"160":[160,199,610],"199":[199],"610":[610]},"derived_states":{"149":149,"160":160,"199":199,"610":610},"lowest_input_state":149,"lowest_start_state":160,"lowest_end_state":199,"active":false},"implementation":{"matrix":{"99":[210],"210":[210,220,249],"220":[220,210,249,610],"249":[249],"610":[610]},"derived_states":{"99":99,"210":210,"220":210,"249":249,"610":610},"lowest_input_state":99,"lowest_start_state":210,"lowest_end_state":249,"active":true},"review":{"matrix":{"249":[260],"260":[260,270,299],"270":[210,270,260,299,610],"299":[299],"610":[610]},"derived_states":{"249":249,"260":260,"270":260,"299":299,"610":610},"lowest_input_state":249,"lowest_start_state":260,"lowest_end_state":299,"active":false},"recertification":{"matrix":{"299":[310],"310":[310,349,400],"349":[349],"400":[400]},"derived_states":{"299":299,"310":310,"349":349,"400":400},"lowest_input_state":299,"lowest_start_state":310,"lowest_end_state":349,"active":false}}}', 0); insert into config (config_key, config_value, config_user) VALUES ('reqGrpModStateMatrix', '{"config_value":{"request":{"matrix":{"0":[0,49,620],"49":[49,620],"620":[620]},"derived_states":{"0":0,"49":49,"620":620},"lowest_input_state":0,"lowest_start_state":49,"lowest_end_state":49,"active":true},"approval":{"matrix":{"49":[60],"60":[60,99,610],"99":[99],"610":[610]},"derived_states":{"49":49,"60":60,"99":99,"610":610},"lowest_input_state":49,"lowest_start_state":60,"lowest_end_state":99,"active":true},"planning":{"matrix":{"99":[110],"110":[110,120,130,149],"120":[120,110,130,149],"130":[130,110,120,149,610],"149":[149],"610":[610]},"derived_states":{"99":99,"110":110,"120":110,"130":110,"149":149,"610":610},"lowest_input_state":99,"lowest_start_state":110,"lowest_end_state":149,"active":false},"verification":{"matrix":{"149":[160],"160":[160,199,610],"199":[199],"610":[610]},"derived_states":{"149":149,"160":160,"199":199,"610":610},"lowest_input_state":149,"lowest_start_state":160,"lowest_end_state":199,"active":false},"implementation":{"matrix":{"99":[210],"210":[210,220,249],"220":[220,210,249,610],"249":[249],"610":[610]},"derived_states":{"99":99,"210":210,"220":210,"249":249,"610":610},"lowest_input_state":99,"lowest_start_state":210,"lowest_end_state":249,"active":true},"review":{"matrix":{"249":[260],"260":[260,270,299],"270":[210,270,260,299,610],"299":[299],"610":[610]},"derived_states":{"249":249,"260":260,"270":260,"299":299,"610":610},"lowest_input_state":249,"lowest_start_state":260,"lowest_end_state":299,"active":false},"recertification":{"matrix":{"299":[310],"310":[310,349,400],"349":[349],"400":[400]},"derived_states":{"299":299,"310":310,"349":349,"400":400},"lowest_input_state":299,"lowest_start_state":310,"lowest_end_state":349,"active":false}}}', 0); insert into config (config_key, config_value, config_user) VALUES ('reqGrpDelStateMatrix', '{"config_value":{"request":{"matrix":{"0":[0,49,620],"49":[49,620],"620":[620]},"derived_states":{"0":0,"49":49,"620":620},"lowest_input_state":0,"lowest_start_state":49,"lowest_end_state":49,"active":true},"approval":{"matrix":{"49":[60],"60":[60,99,610],"99":[99],"610":[610]},"derived_states":{"49":49,"60":60,"99":99,"610":610},"lowest_input_state":49,"lowest_start_state":60,"lowest_end_state":99,"active":true},"planning":{"matrix":{"99":[110],"110":[110,120,130,149],"120":[120,110,130,149],"130":[130,110,120,149,610],"149":[149],"610":[610]},"derived_states":{"99":99,"110":110,"120":110,"130":110,"149":149,"610":610},"lowest_input_state":99,"lowest_start_state":110,"lowest_end_state":149,"active":false},"verification":{"matrix":{"149":[160],"160":[160,199,610],"199":[199],"610":[610]},"derived_states":{"149":149,"160":160,"199":199,"610":610},"lowest_input_state":149,"lowest_start_state":160,"lowest_end_state":199,"active":false},"implementation":{"matrix":{"99":[210],"210":[210,220,249],"220":[220,210,249,610],"249":[249],"610":[610]},"derived_states":{"99":99,"210":210,"220":210,"249":249,"610":610},"lowest_input_state":99,"lowest_start_state":210,"lowest_end_state":249,"active":true},"review":{"matrix":{"249":[260],"260":[260,270,299],"270":[210,270,260,299,610],"299":[299],"610":[610]},"derived_states":{"249":249,"260":260,"270":260,"299":299,"610":610},"lowest_input_state":249,"lowest_start_state":260,"lowest_end_state":299,"active":false},"recertification":{"matrix":{"299":[310],"310":[310,349,400],"349":[349],"400":[400]},"derived_states":{"299":299,"310":310,"349":349,"400":400},"lowest_input_state":299,"lowest_start_state":310,"lowest_end_state":349,"active":false}}}', 0); +insert into config (config_key, config_value, config_user) VALUES ('reqNewIntStateMatrix', '{"config_value":{"request":{"matrix":{"0":[0,49,620]},"derived_states":{"0":0},"lowest_input_state":0,"lowest_start_state":0,"lowest_end_state":49,"active":true},"approval":{"matrix":{"0":[0]},"derived_states":{"0":0},"lowest_input_state":0,"lowest_start_state":0,"lowest_end_state":0,"active":false},"planning":{"matrix":{"0":[0]},"derived_states":{"0":0},"lowest_input_state":0,"lowest_start_state":0,"lowest_end_state":0,"active":false},"verification":{"matrix":{"0":[0]},"derived_states":{"0":0},"lowest_input_state":0,"lowest_start_state":0,"lowest_end_state":0,"active":false},"implementation":{"matrix":{"205":[205,249],"49":[210],"210":[610,210,249]},"derived_states":{"205":205,"49":49,"210":210},"lowest_input_state":49,"lowest_start_state":205,"lowest_end_state":249,"active":true},"review":{"matrix":{"249":[249,205,299]},"derived_states":{"249":249},"lowest_input_state":249,"lowest_start_state":249,"lowest_end_state":299,"active":true},"recertification":{"matrix":{"0":[0]},"derived_states":{"0":0},"lowest_input_state":0,"lowest_start_state":0,"lowest_end_state":0,"active":false}}}', 0); insert into config (config_key, config_value, config_user) VALUES ('reqMasterStateMatrixDefault', '{"config_value":{"request":{"matrix":{"0":[0,49,620],"49":[49,620],"620":[620]},"derived_states":{"0":0,"49":49,"620":620},"lowest_input_state":0,"lowest_start_state":49,"lowest_end_state":49,"active":true},"approval":{"matrix":{"49":[60],"60":[60,99,610],"99":[99],"610":[610]},"derived_states":{"49":49,"60":60,"99":99,"610":610},"lowest_input_state":49,"lowest_start_state":60,"lowest_end_state":99,"active":true},"planning":{"matrix":{"99":[110],"110":[110,120,130,149],"120":[120,110,130,149],"130":[130,110,120,149,610],"149":[149],"610":[610]},"derived_states":{"99":99,"110":110,"120":110,"130":110,"149":149,"610":610},"lowest_input_state":99,"lowest_start_state":110,"lowest_end_state":149,"active":false},"verification":{"matrix":{"149":[160],"160":[160,199,610],"199":[199],"610":[610]},"derived_states":{"149":149,"160":160,"199":199,"610":610},"lowest_input_state":149,"lowest_start_state":160,"lowest_end_state":199,"active":false},"implementation":{"matrix":{"99":[210],"210":[210,220,249],"220":[220,210,249,610],"249":[249],"610":[610]},"derived_states":{"99":99,"210":210,"220":210,"249":249,"610":610},"lowest_input_state":99,"lowest_start_state":210,"lowest_end_state":249,"active":true},"review":{"matrix":{"249":[260],"260":[260,270,299],"270":[210,270,260,299,610],"299":[299],"610":[610]},"derived_states":{"249":249,"260":260,"270":260,"299":299,"610":610},"lowest_input_state":249,"lowest_start_state":260,"lowest_end_state":299,"active":false},"recertification":{"matrix":{"299":[310],"310":[310,349,400],"349":[349],"400":[400]},"derived_states":{"299":299,"310":310,"349":349,"400":400},"lowest_input_state":299,"lowest_start_state":310,"lowest_end_state":349,"active":false}}}', 0); insert into config (config_key, config_value, config_user) VALUES ('reqGenStateMatrixDefault', '{"config_value":{"request":{"matrix":{"0":[0,49,620],"49":[49,620],"620":[620]},"derived_states":{"0":0,"49":49,"620":620},"lowest_input_state":0,"lowest_start_state":49,"lowest_end_state":49,"active":true},"approval":{"matrix":{"49":[60],"60":[60,99,610],"99":[99],"610":[610]},"derived_states":{"49":49,"60":60,"99":99,"610":610},"lowest_input_state":49,"lowest_start_state":60,"lowest_end_state":99,"active":true},"planning":{"matrix":{"99":[110],"110":[110,120,130,149],"120":[120,110,130,149],"130":[130,110,120,149,610],"149":[149],"610":[610]},"derived_states":{"99":99,"110":110,"120":110,"130":110,"149":149,"610":610},"lowest_input_state":99,"lowest_start_state":110,"lowest_end_state":149,"active":false},"verification":{"matrix":{"149":[160],"160":[160,199,610],"199":[199],"610":[610]},"derived_states":{"149":149,"160":160,"199":199,"610":610},"lowest_input_state":149,"lowest_start_state":160,"lowest_end_state":199,"active":false},"implementation":{"matrix":{"99":[210],"210":[210,220,249],"220":[220,210,249,610],"249":[249],"610":[610]},"derived_states":{"99":99,"210":210,"220":210,"249":249,"610":610},"lowest_input_state":99,"lowest_start_state":210,"lowest_end_state":249,"active":true},"review":{"matrix":{"249":[260],"260":[260,270,299],"270":[210,270,260,299,610],"299":[299],"610":[610]},"derived_states":{"249":249,"260":260,"270":260,"299":299,"610":610},"lowest_input_state":249,"lowest_start_state":260,"lowest_end_state":299,"active":false},"recertification":{"matrix":{"299":[310],"310":[310,349,400],"349":[349],"400":[400]},"derived_states":{"299":299,"310":310,"349":349,"400":400},"lowest_input_state":299,"lowest_start_state":310,"lowest_end_state":349,"active":false}}}', 0); insert into config (config_key, config_value, config_user) VALUES ('reqAccStateMatrixDefault', '{"config_value":{"request":{"matrix":{"0":[0,49,620],"49":[49,620],"620":[620]},"derived_states":{"0":0,"49":49,"620":620},"lowest_input_state":0,"lowest_start_state":49,"lowest_end_state":49,"active":true},"approval":{"matrix":{"49":[60],"60":[60,99,610],"99":[99],"610":[610]},"derived_states":{"49":49,"60":60,"99":99,"610":610},"lowest_input_state":49,"lowest_start_state":60,"lowest_end_state":99,"active":true},"planning":{"matrix":{"99":[110],"110":[110,120,130,149],"120":[120,110,130,149],"130":[130,110,120,149,610],"149":[149],"610":[610]},"derived_states":{"99":99,"110":110,"120":110,"130":110,"149":149,"610":610},"lowest_input_state":99,"lowest_start_state":110,"lowest_end_state":149,"active":false},"verification":{"matrix":{"149":[160],"160":[160,199,610],"199":[199],"610":[610]},"derived_states":{"149":149,"160":160,"199":199,"610":610},"lowest_input_state":149,"lowest_start_state":160,"lowest_end_state":199,"active":false},"implementation":{"matrix":{"99":[210],"210":[210,220,249],"220":[220,210,249,610],"249":[249],"610":[610]},"derived_states":{"99":99,"210":210,"220":210,"249":249,"610":610},"lowest_input_state":99,"lowest_start_state":210,"lowest_end_state":249,"active":true},"review":{"matrix":{"249":[260],"260":[260,270,299],"270":[210,270,260,299,610],"299":[299],"610":[610]},"derived_states":{"249":249,"260":260,"270":260,"299":299,"610":610},"lowest_input_state":249,"lowest_start_state":260,"lowest_end_state":299,"active":false},"recertification":{"matrix":{"299":[310],"310":[310,349,400],"349":[349],"400":[400]},"derived_states":{"299":299,"310":310,"349":349,"400":400},"lowest_input_state":299,"lowest_start_state":310,"lowest_end_state":349,"active":false}}}', 0); @@ -62,14 +69,121 @@ insert into config (config_key, config_value, config_user) VALUES ('reqRulModSta insert into config (config_key, config_value, config_user) VALUES ('reqGrpCreStateMatrixDefault', '{"config_value":{"request":{"matrix":{"0":[0,49,620],"49":[49,620],"620":[620]},"derived_states":{"0":0,"49":49,"620":620},"lowest_input_state":0,"lowest_start_state":49,"lowest_end_state":49,"active":true},"approval":{"matrix":{"49":[60],"60":[60,99,610],"99":[99],"610":[610]},"derived_states":{"49":49,"60":60,"99":99,"610":610},"lowest_input_state":49,"lowest_start_state":60,"lowest_end_state":99,"active":true},"planning":{"matrix":{"99":[110],"110":[110,120,130,149],"120":[120,110,130,149],"130":[130,110,120,149,610],"149":[149],"610":[610]},"derived_states":{"99":99,"110":110,"120":110,"130":110,"149":149,"610":610},"lowest_input_state":99,"lowest_start_state":110,"lowest_end_state":149,"active":false},"verification":{"matrix":{"149":[160],"160":[160,199,610],"199":[199],"610":[610]},"derived_states":{"149":149,"160":160,"199":199,"610":610},"lowest_input_state":149,"lowest_start_state":160,"lowest_end_state":199,"active":false},"implementation":{"matrix":{"99":[210],"210":[210,220,249],"220":[220,210,249,610],"249":[249],"610":[610]},"derived_states":{"99":99,"210":210,"220":210,"249":249,"610":610},"lowest_input_state":99,"lowest_start_state":210,"lowest_end_state":249,"active":true},"review":{"matrix":{"249":[260],"260":[260,270,299],"270":[210,270,260,299,610],"299":[299],"610":[610]},"derived_states":{"249":249,"260":260,"270":260,"299":299,"610":610},"lowest_input_state":249,"lowest_start_state":260,"lowest_end_state":299,"active":false},"recertification":{"matrix":{"299":[310],"310":[310,349,400],"349":[349],"400":[400]},"derived_states":{"299":299,"310":310,"349":349,"400":400},"lowest_input_state":299,"lowest_start_state":310,"lowest_end_state":349,"active":false}}}', 0); insert into config (config_key, config_value, config_user) VALUES ('reqGrpModStateMatrixDefault', '{"config_value":{"request":{"matrix":{"0":[0,49,620],"49":[49,620],"620":[620]},"derived_states":{"0":0,"49":49,"620":620},"lowest_input_state":0,"lowest_start_state":49,"lowest_end_state":49,"active":true},"approval":{"matrix":{"49":[60],"60":[60,99,610],"99":[99],"610":[610]},"derived_states":{"49":49,"60":60,"99":99,"610":610},"lowest_input_state":49,"lowest_start_state":60,"lowest_end_state":99,"active":true},"planning":{"matrix":{"99":[110],"110":[110,120,130,149],"120":[120,110,130,149],"130":[130,110,120,149,610],"149":[149],"610":[610]},"derived_states":{"99":99,"110":110,"120":110,"130":110,"149":149,"610":610},"lowest_input_state":99,"lowest_start_state":110,"lowest_end_state":149,"active":false},"verification":{"matrix":{"149":[160],"160":[160,199,610],"199":[199],"610":[610]},"derived_states":{"149":149,"160":160,"199":199,"610":610},"lowest_input_state":149,"lowest_start_state":160,"lowest_end_state":199,"active":false},"implementation":{"matrix":{"99":[210],"210":[210,220,249],"220":[220,210,249,610],"249":[249],"610":[610]},"derived_states":{"99":99,"210":210,"220":210,"249":249,"610":610},"lowest_input_state":99,"lowest_start_state":210,"lowest_end_state":249,"active":true},"review":{"matrix":{"249":[260],"260":[260,270,299],"270":[210,270,260,299,610],"299":[299],"610":[610]},"derived_states":{"249":249,"260":260,"270":260,"299":299,"610":610},"lowest_input_state":249,"lowest_start_state":260,"lowest_end_state":299,"active":false},"recertification":{"matrix":{"299":[310],"310":[310,349,400],"349":[349],"400":[400]},"derived_states":{"299":299,"310":310,"349":349,"400":400},"lowest_input_state":299,"lowest_start_state":310,"lowest_end_state":349,"active":false}}}', 0); insert into config (config_key, config_value, config_user) VALUES ('reqGrpDelStateMatrixDefault', '{"config_value":{"request":{"matrix":{"0":[0,49,620],"49":[49,620],"620":[620]},"derived_states":{"0":0,"49":49,"620":620},"lowest_input_state":0,"lowest_start_state":49,"lowest_end_state":49,"active":true},"approval":{"matrix":{"49":[60],"60":[60,99,610],"99":[99],"610":[610]},"derived_states":{"49":49,"60":60,"99":99,"610":610},"lowest_input_state":49,"lowest_start_state":60,"lowest_end_state":99,"active":true},"planning":{"matrix":{"99":[110],"110":[110,120,130,149],"120":[120,110,130,149],"130":[130,110,120,149,610],"149":[149],"610":[610]},"derived_states":{"99":99,"110":110,"120":110,"130":110,"149":149,"610":610},"lowest_input_state":99,"lowest_start_state":110,"lowest_end_state":149,"active":false},"verification":{"matrix":{"149":[160],"160":[160,199,610],"199":[199],"610":[610]},"derived_states":{"149":149,"160":160,"199":199,"610":610},"lowest_input_state":149,"lowest_start_state":160,"lowest_end_state":199,"active":false},"implementation":{"matrix":{"99":[210],"210":[210,220,249],"220":[220,210,249,610],"249":[249],"610":[610]},"derived_states":{"99":99,"210":210,"220":210,"249":249,"610":610},"lowest_input_state":99,"lowest_start_state":210,"lowest_end_state":249,"active":true},"review":{"matrix":{"249":[260],"260":[260,270,299],"270":[210,270,260,299,610],"299":[299],"610":[610]},"derived_states":{"249":249,"260":260,"270":260,"299":299,"610":610},"lowest_input_state":249,"lowest_start_state":260,"lowest_end_state":299,"active":false},"recertification":{"matrix":{"299":[310],"310":[310,349,400],"349":[349],"400":[400]},"derived_states":{"299":299,"310":310,"349":349,"400":400},"lowest_input_state":299,"lowest_start_state":310,"lowest_end_state":349,"active":false}}}', 0); +insert into config (config_key, config_value, config_user) VALUES ('reqNewIntStateMatrixDefault', '{"config_value":{"request":{"matrix":{"0":[0,49,620]},"derived_states":{"0":0},"lowest_input_state":0,"lowest_start_state":0,"lowest_end_state":49,"active":true},"approval":{"matrix":{"0":[0]},"derived_states":{"0":0},"lowest_input_state":0,"lowest_start_state":0,"lowest_end_state":0,"active":false},"planning":{"matrix":{"0":[0]},"derived_states":{"0":0},"lowest_input_state":0,"lowest_start_state":0,"lowest_end_state":0,"active":false},"verification":{"matrix":{"0":[0]},"derived_states":{"0":0},"lowest_input_state":0,"lowest_start_state":0,"lowest_end_state":0,"active":false},"implementation":{"matrix":{"205":[205,249],"49":[210],"210":[610,210,249]},"derived_states":{"205":205,"49":49,"210":210},"lowest_input_state":49,"lowest_start_state":205,"lowest_end_state":249,"active":true},"review":{"matrix":{"249":[249,205,299]},"derived_states":{"249":249},"lowest_input_state":249,"lowest_start_state":249,"lowest_end_state":299,"active":true},"recertification":{"matrix":{"0":[0]},"derived_states":{"0":0},"lowest_input_state":0,"lowest_start_state":0,"lowest_end_state":0,"active":false}}}', 0); insert into config (config_key, config_value, config_user) VALUES ('reqAvailableTaskTypes', '[0,1,2,3]', 0); insert into config (config_key, config_value, config_user) VALUES ('reqPriorities', '[{"numeric_prio":1,"name":"Highest","ticket_deadline":1,"approval_deadline":1},{"numeric_prio":2,"name":"High","ticket_deadline":3,"approval_deadline":2},{"numeric_prio":3,"name":"Medium","ticket_deadline":7,"approval_deadline":3},{"numeric_prio":4,"name":"Low","ticket_deadline":14,"approval_deadline":7},{"numeric_prio":5,"name":"Lowest","ticket_deadline":30,"approval_deadline":14}]', 0); insert into config (config_key, config_value, config_user) VALUES ('reqAutoCreateImplTasks', 'enterInReqTask', 0); +insert into config (config_key, config_value, config_user) VALUES ('reqOwnerBased', 'False', 0); insert into config (config_key, config_value, config_user) VALUES ('reqAllowObjectSearch', 'False', 0); insert into config (config_key, config_value, config_user) VALUES ('reqAllowManualOwnerAdmin', 'False', 0); insert into config (config_key, config_value, config_user) VALUES ('reqActivatePathAnalysis', 'True', 0); +insert into config (config_key, config_value, config_user) VALUES ('reqShowCompliance', 'False', 0); insert into config (config_key, config_value, config_user) VALUES ('unusedTolerance', '400', 0); insert into config (config_key, config_value, config_user) VALUES ('creationTolerance', '90', 0); +insert into config (config_key, config_value, config_user) VALUES ('ruleOwnershipMode', 'mixed', 0); +insert into config (config_key, config_value, config_user) VALUES ('allowServerInConn', 'True', 0); +insert into config (config_key, config_value, config_user) VALUES ('allowServiceInConn', 'True', 0); +insert into config (config_key, config_value, config_user) VALUES ('importAppDataStartAt', '00:00:00', 0); +insert into config (config_key, config_value, config_user) VALUES ('importAppDataSleepTime', '0', 0); +insert into config (config_key, config_value, config_user) VALUES ('importSubnetDataStartAt', '00:00:00', 0); +insert into config (config_key, config_value, config_user) VALUES ('importSubnetDataSleepTime', '0', 0); +insert into config (config_key, config_value, config_user) VALUES ('importAppDataPath', '[]', 0); +insert into config (config_key, config_value, config_user) VALUES ('importSubnetDataPath', '[]', 0); +insert into config (config_key, config_value, config_user) VALUES ('modNamingConvention', '{"networkAreaRequired":false,"useAppPart":false,"fixedPartLength":0,"freePartLength":0,"networkAreaPattern":"","appRolePattern":""}', 0); +insert into config (config_key, config_value, config_user) VALUES ('modCommonAreas', '[]', 0); +insert into config (config_key, config_value, config_user) VALUES ('modAppServerTypes', '[{"Id":0,"Name":"Default"}]', 0); +insert into config (config_key, config_value, config_user) VALUES ('modReqInterfaceName', '', 0); +insert into config (config_key, config_value, config_user) VALUES ('modReqEmailReceiver', 'OwnerGroupOnly', 0); +insert into config (config_key, config_value, config_user) VALUES ('modReqEmailRequesterInCc', 'true', 0); +insert into config (config_key, config_value, config_user) VALUES ('modReqEmailOtherAddresses', '', 0); +insert into config (config_key, config_value, config_user) VALUES ('modReqEmailSubject', '', 0); +insert into config (config_key, config_value, config_user) VALUES ('modReqEmailBody', '', 0); +insert into config (config_key, config_value, config_user) VALUES ('modReqTicketTitle', '', 0); +insert into config (config_key, config_value, config_user) VALUES ('modReqTaskTitle', '', 0); +insert into config (config_key, config_value, config_user) VALUES ('modDecommEmailReceiver', 'None', 0); +insert into config (config_key, config_value, config_user) VALUES ('modDecommEmailOtherAddresses', '', 0); +insert into config (config_key, config_value, config_user) VALUES ('modDecommEmailSubject', '', 0); +insert into config (config_key, config_value, config_user) VALUES ('modDecommEmailBody', '', 0); +insert into config (config_key, config_value, config_user) VALUES ('modRolloutActive', 'true', 0); +insert into config (config_key, config_value, config_user) VALUES ('modRolloutResolveServiceGroups', 'true', 0); +insert into config (config_key, config_value, config_user) VALUES ('modRolloutBundleTasks', 'false', 0); +insert into config (config_key, config_value, config_user) VALUES ('modRolloutNatHeuristic', 'false', 0); +insert into config (config_key, config_value, config_user) VALUES ('modRolloutRemovedAppServers', 'false', 0); +insert into config (config_key, config_value, config_user) VALUES ('modRequestOnlyOwnObjects', 'false', 0); +insert into config (config_key, config_value, config_user) VALUES ('modRolloutErrorText', 'Error during external request', 0); +insert into config (config_key, config_value, config_user) VALUES ('modRecertActive', 'false', 0); +insert into config (config_key, config_value, config_user) VALUES ('modRecertExpectAllModelled', 'false', 0); +insert into config (config_key, config_value, config_user) VALUES ('modRecertText', '', 0); +insert into config (config_key, config_value, config_user) VALUES ('modIconify', 'True', 0); +insert into config (config_key, config_value, config_user) VALUES ('reducedProtocolSet', 'True', 0); +insert into config (config_key, config_value, config_user) VALUES ('overviewDisplayLines', '3', 0); +insert into config (config_key, config_value, config_user) VALUES ('emailServerAddress', '', 0); +insert into config (config_key, config_value, config_user) VALUES ('emailPort', '0', 0); +insert into config (config_key, config_value, config_user) VALUES ('emailTls', 'None', 0); +insert into config (config_key, config_value, config_user) VALUES ('emailUser', '', 0); +insert into config (config_key, config_value, config_user) VALUES ('emailPassword', '', 0); +insert into config (config_key, config_value, config_user) VALUES ('emailSenderAddress', '', 0); +insert into config (config_key, config_value, config_user) VALUES ('impChangeNotifyRecipients', '', 0); +insert into config (config_key, config_value, config_user) VALUES ('impChangeNotifySubject', '', 0); +insert into config (config_key, config_value, config_user) VALUES ('impChangeNotifyBody', '', 0); +insert into config (config_key, config_value, config_user) VALUES ('impChangeNotifyActive', 'False', 0); +insert into config (config_key, config_value, config_user) VALUES ('impChangeNotifyType', '0', 0); +insert into config (config_key, config_value, config_user) VALUES ('impChangeNotifySleepTime', '0', 0); +insert into config (config_key, config_value, config_user) VALUES ('impChangeNotifyStartAt', '00:00:00', 0); +insert into config (config_key, config_value, config_user) VALUES ('externalRequestSleepTime', '0', 0); +insert into config (config_key, config_value, config_user) VALUES ('externalRequestStartAt', '00:00:00', 0); +insert into config (config_key, config_value, config_user) VALUES ('externalRequestWaitCycles', '0', 0); +insert into config (config_key, config_value, config_user) VALUES ('modExtraConfigs', '[]', 0); +insert into config (config_key, config_value, config_user) VALUES ('modSpecUserAreas', '[]', 0); +insert into config (config_key, config_value, config_user) VALUES ('modUpdatableObjAreas', '[]', 0); +insert into config (config_key, config_value, config_user) VALUES ('extTicketSystems', '[{"Url":"","TicketTemplate":"{\"ticket\":{\"subject\":\"@@TICKET_SUBJECT@@\",\"priority\":\"@@PRIORITY@@\",\"requester\":\"@@ONBEHALF@@\",\"domain_name\":\"\",\"workflow\":{\"name\":\"@@WORKFLOW_NAME@@\"},\"steps\":{\"step\":[{\"name\":\"Erfassung des Antrags\",\"tasks\":{\"task\":{\"fields\":{\"field\":[@@TASKS@@]}}}}]}}}","TasksTemplate":"{\"@xsi.type\":\"multi_access_request\",\"name\":\"GewünschterZugang\",\"read_only\":false,\"access_request\":{\"order\":\"AR1\",\"verifier_result\":{\"status\":\"notrun\"},\"use_topology\":true,\"targets\":{\"target\":{\"@type\":\"ANY\"}},\"users\":{\"user\":@@USERS@@},\"sources\":{\"source\":@@SOURCES@@},\"destinations\":{\"destination\":@@DESTINATIONS@@},\"services\":{\"service\":@@SERVICES@@},\"action\":\"@@ACTION@@\",\"labels\":\"\"}},{\"@xsi.type\":\"text_area\",\"name\":\"Grund für den Antrag\",\"read_only\":false,\"text\":\"@@REASON@@\"},{\"@xsi.type\":\"drop_down_list\",\"name\":\"Regel Log aktivieren?\",\"selection\":\"@@LOGGING@@\"},{\"@xsi.type\":\"date\",\"name\":\"Regel befristen bis:\"},{\"@xsi.type\":\"text_field\",\"name\":\"Anwendungs-ID\",\"text\":\"@@APPID@@\"},{\"@xsi.type\":\"checkbox\",\"name\":\"Die benötigte Kommunikationsverbindung ist im Kommunikationsprofil nach IT-Sicherheitsstandard hinterlegt\",\"value\":@@COM_DOCUMENTED@@},{\"@xsi.type\":\"drop_down_list\",\"name\":\"Expertenmodus: Exakt wie beantragt implementieren (Designervorschlag ignorieren)\",\"selection\":\"Nein\"}"}]', 0); +insert into config (config_key, config_value, config_user) VALUES ('welcomeMessage', '', 0); +insert into config (config_key, config_value, config_user) VALUES ('dnsLookup', 'False', 0); +insert into config (config_key, config_value, config_user) VALUES ('overwriteExistingNames', 'False', 0); +insert into config (config_key, config_value, config_user) VALUES ('autoReplaceAppServer', 'False', 0); +insert into config (config_key, config_value, config_user) VALUES ('ownerLdapGroupNames', 'ModellerGroup_@@ExternalAppId@@', 0); +insert into config (config_key, config_value, config_user) VALUES ('ownerDataImportSyncUsers', 'true', 0); +insert into config (config_key, config_value, config_user) VALUES ('modModelledMarker', 'FWOC', 0); +insert into config (config_key, config_value, config_user) VALUES ('modModelledMarkerLocation', 'rulename', 0); +insert into config (config_key, config_value, config_user) VALUES ('ruleRecognitionOption', '{"nwRegardIp":true,"nwRegardName":false,"nwRegardGroupName":false,"nwResolveGroup":false,"svcRegardPortAndProt":true,"svcRegardName":false,"svcRegardGroupName":false,"svcResolveGroup":true,"svcSplitPortRanges":false}', 0); +insert into config (config_key, config_value, config_user) VALUES ('availableReportTypes', '[1,2,3,4,5,6,7,8,9,10,21,22,31,32]', 0); +insert into config (config_key, config_value, config_user) VALUES ('varianceAnalysisSleepTime', '0', 0); +insert into config (config_key, config_value, config_user) VALUES ('varianceAnalysisStartAt', '00:00:00', 0); +insert into config (config_key, config_value, config_user) VALUES ('varianceAnalysisSync', 'false', 0); +insert into config (config_key, config_value, config_user) VALUES ('varianceAnalysisRefresh', 'false', 0); +insert into config (config_key, config_value, config_user) VALUES ('resolveNetworkAreas', 'False', 0); +insert into config (config_key, config_value, config_user) VALUES ('complianceCheckSleepTime', '0', 0); +insert into config (config_key, config_value, config_user) VALUES ('complianceCheckStartAt', '00:00:00', 0); +insert into config (config_key, config_value, config_user) VALUES ('complianceCheckPolicy', '0', 0); +insert into config (config_key, config_value, config_user) VALUES ('complianceCheckMaxPrintedViolations', '0', 0); +insert into config (config_key, config_value, config_user) VALUES ('complianceCheckSortMatrixByID', 'false', 0); +insert into config (config_key, config_value, config_user) VALUES ('availableModules', '[1,2,3,4,5,6]', 0); +insert into config (config_key, config_value, config_user) VALUES ('debugConfig', '{"debugLevel":8, "extendedLogComplianceCheck":true, "extendedLogReportGeneration":true, "extendedLogScheduler":true}', 0); +insert into config (config_key, config_value, config_user) VALUES ('reportSchedulerConfig', '', 0); +insert into config (config_key, config_value, config_user) VALUES ('autoCalculateInternetZone', 'true', 0); +insert into config (config_key, config_value, config_user) VALUES ('autoCalculateUndefinedInternalZone', 'true', 0); +insert into config (config_key, config_value, config_user) VALUES ('internalZoneRange_10_0_0_0_8', 'true', 0); +insert into config (config_key, config_value, config_user) VALUES ('internalZoneRange_172_16_0_0_12', 'true', 0); +insert into config (config_key, config_value, config_user) VALUES ('internalZoneRange_192_168_0_0_16', 'true', 0); +insert into config (config_key, config_value, config_user) VALUES ('internalZoneRange_0_0_0_0_8', 'true', 0); +insert into config (config_key, config_value, config_user) VALUES ('internalZoneRange_127_0_0_0_8', 'true', 0); +insert into config (config_key, config_value, config_user) VALUES ('internalZoneRange_169_254_0_0_16', 'true', 0); +insert into config (config_key, config_value, config_user) VALUES ('internalZoneRange_224_0_0_0_4', 'true', 0); +insert into config (config_key, config_value, config_user) VALUES ('internalZoneRange_240_0_0_0_4', 'true', 0); +insert into config (config_key, config_value, config_user) VALUES ('internalZoneRange_255_255_255_255_32', 'true', 0); +insert into config (config_key, config_value, config_user) VALUES ('internalZoneRange_192_0_2_0_24', 'true', 0); +insert into config (config_key, config_value, config_user) VALUES ('internalZoneRange_198_51_100_0_24', 'true', 0); +insert into config (config_key, config_value, config_user) VALUES ('internalZoneRange_203_0_113_0_24', 'true', 0); +insert into config (config_key, config_value, config_user) VALUES ('internalZoneRange_100_64_0_0_10', 'true', 0); +insert into config (config_key, config_value, config_user) VALUES ('internalZoneRange_192_0_0_0_24', 'true', 0); +insert into config (config_key, config_value, config_user) VALUES ('internalZoneRange_192_88_99_0_24', 'true', 0); +insert into config (config_key, config_value, config_user) VALUES ('internalZoneRange_198_18_0_0_15', 'true', 0); +insert into config (config_key, config_value, config_user) VALUES ('autoCalculatedZonesAtTheEnd', 'true', 0); +insert into config (config_key, config_value, config_user) VALUES ('treatDynamicAndDomainObjectsAsInternet', 'true', 0); +insert into config (config_key, config_value, config_user) VALUES ('showShortColumnsInComplianceReports', 'true', 0); +insert into config (config_key, config_value, config_user) VALUES ('importedMatrixReadOnly', 'true', 0); +insert into config (config_key, config_value, config_user) VALUES ('complianceCheckElementsPerFetch', '500', 0); +insert into config (config_key, config_value, config_user) VALUES ('complianceCheckAvailableProcessors', '4', 0); INSERT INTO "report_format" ("report_format_name") VALUES ('json'); INSERT INTO "report_format" ("report_format_name") VALUES ('pdf'); @@ -153,6 +267,81 @@ INSERT INTO "report_template" ("report_filter","report_template_name","report_te "end_time": "2022-01-01T00:00:00.0000000+01:00", "open_start": false, "open_end": false}}'); +INSERT INTO "report_template" ("report_filter","report_template_name","report_template_comment","report_template_owner", "report_parameters") + VALUES ('','Last year''s Unused Rules','T0106', 0, + '{"report_type":10,"device_filter":{"management":[]}, + "time_filter": { + "is_shortcut": true, + "shortcut": "now", + "report_time": "2022-01-01T00:00:00.0000000+01:00", + "timerange_type": "SHORTCUT", + "shortcut_range": "this year", + "offset": 0, + "interval": "DAYS", + "start_time": "2022-01-01T00:00:00.0000000+01:00", + "end_time": "2022-01-01T00:00:00.0000000+01:00", + "open_start": false, + "open_end": false}, + "unused_filter": { + "creationTolerance": 0, + "unusedForDays": 365}}'); +INSERT INTO "report_template" ("report_filter","report_template_name","report_template_comment","report_template_owner", "report_parameters") + VALUES ('','Next Month''s Recertifications','T0107', 0, + '{"report_type":7,"device_filter":{"management":[]}, + "time_filter": { + "is_shortcut": true, + "shortcut": "now", + "report_time": "2022-01-01T00:00:00.0000000+01:00", + "timerange_type": "SHORTCUT", + "shortcut_range": "this year", + "offset": 0, + "interval": "DAYS", + "start_time": "2022-01-01T00:00:00.0000000+01:00", + "end_time": "2022-01-01T00:00:00.0000000+01:00", + "open_start": false, + "open_end": false}, + "recert_filter": { + "recertOwnerList": [], + "recertShowAnyMatch": true, + "recertificationDisplayPeriod": 30}}'); +INSERT INTO "report_template" ("report_filter","report_template_name","report_template_comment","report_template_owner", "report_parameters") + VALUES ('action=accept', + 'Compliance: Unresolved violations','T0108', 0, + '{"report_type":31,"device_filter":{"management":[]}, + "time_filter": { + "is_shortcut": true, + "shortcut": "now", + "report_time": "2022-01-01T00:00:00.0000000+01:00", + "timerange_type": "SHORTCUT", + "shortcut_range": "this year", + "offset": 0, + "interval": "DAYS", + "start_time": "2022-01-01T00:00:00.0000000+01:00", + "end_time": "2022-01-01T00:00:00.0000000+01:00", + "open_start": false, + "open_end": false}, + "compliance_filter": { + "diff_reference_in_days": 0, + "show_non_impact_rules": true}}'); +INSERT INTO "report_template" ("report_filter","report_template_name","report_template_comment","report_template_owner", "report_parameters") + VALUES ('action=accept', + 'Compliance: Diffs','T0109', 0, + '{"report_type":32,"device_filter":{"management":[]}, + "time_filter": { + "is_shortcut": true, + "shortcut": "now", + "report_time": "2022-01-01T00:00:00.0000000+01:00", + "timerange_type": "SHORTCUT", + "shortcut_range": "this year", + "offset": 0, + "interval": "DAYS", + "start_time": "2022-01-01T00:00:00.0000000+01:00", + "end_time": "2022-01-01T00:00:00.0000000+01:00", + "open_start": false, + "open_end": false}, + "compliance_filter": { + "diff_reference_in_days": 7, + "show_non_impact_rules": false}}'); insert into parent_rule_type (id, name) VALUES (1, 'section'); -- do not restart numbering insert into parent_rule_type (id, name) VALUES (2, 'guarded-layer'); -- restart numbering, rule restrictions are ANDed to all rules below it, layer is not entered if guard does not apply @@ -187,14 +376,17 @@ insert into stm_obj_typ (obj_typ_id,obj_typ_name) VALUES (15,'voip_gk'); insert into stm_obj_typ (obj_typ_id,obj_typ_name) VALUES (16,'gsn_handover_group'); insert into stm_obj_typ (obj_typ_id,obj_typ_name) VALUES (17,'voip_sip'); insert into stm_obj_typ (obj_typ_id,obj_typ_name) VALUES (18,'simple-gateway'); +insert into stm_obj_typ (obj_typ_id,obj_typ_name) VALUES (19,'external-gateway'); +insert into stm_obj_typ (obj_typ_id,obj_typ_name) VALUES (20,'voip'); -- general voip object replacing old specific ones and including CpmiVoipSipDomain +insert into stm_obj_typ (obj_typ_id,obj_typ_name) VALUES (21,'access-role'); insert into stm_action (action_id,action_name) VALUES (1,'accept'); -- cp, fortinet -insert into stm_action (action_id,action_name) VALUES (2,'drop'); -- cp -insert into stm_action (action_id,action_name) VALUES (3,'deny'); -- netscreen, fortinet +insert into stm_action (action_id,action_name, allowed) VALUES (2,'drop', FALSE); -- cp +insert into stm_action (action_id,action_name, allowed) VALUES (3,'deny', FALSE); -- netscreen, fortinet insert into stm_action (action_id,action_name) VALUES (4,'access'); -- netscreen insert into stm_action (action_id,action_name) VALUES (5,'client encrypt'); -- cp insert into stm_action (action_id,action_name) VALUES (6,'client auth'); -- cp -insert into stm_action (action_id,action_name) VALUES (7,'reject'); -- cp +insert into stm_action (action_id,action_name, allowed) VALUES (7,'reject', FALSE); -- cp insert into stm_action (action_id,action_name) VALUES (8,'encrypt'); -- cp insert into stm_action (action_id,action_name) VALUES (9,'user auth'); -- cp insert into stm_action (action_id,action_name) VALUES (10,'session auth'); -- cp @@ -217,7 +409,10 @@ insert into stm_action (action_id,action_name) VALUES (25,'NAT dst, svc') ON CON insert into stm_action (action_id,action_name) VALUES (26,'NAT svc') ON CONFLICT DO NOTHING; -- port nat insert into stm_action (action_id,action_name) VALUES (27,'NAT src, svc') ON CONFLICT DO NOTHING; -- source ip nat plus port nat insert into stm_action (action_id,action_name) VALUES (28,'NAT') ON CONFLICT DO NOTHING; -- generic NAT +insert into stm_action (action_id,action_name) VALUES (29,'inform'); -- cp DLP +insert into stm_action (action_id,action_name) VALUES (30,'ask'); -- cp DLP +-- checkpoint old: insert into stm_track (track_id,track_name) VALUES (1,'log'); insert into stm_track (track_id,track_name) VALUES (2,'none'); insert into stm_track (track_id,track_name) VALUES (3,'alert'); @@ -240,19 +435,22 @@ insert into stm_track (track_id,track_name) VALUES (17,'count alarm'); insert into stm_track (track_id,track_name) VALUES (18,'all'); insert into stm_track (track_id,track_name) VALUES (19,'all start'); insert into stm_track (track_id,track_name) VALUES (20,'utm'); -insert into stm_track (track_id,track_name) VALUES (22,'utm start'); -insert into stm_track (track_id,track_name) VALUES (21,'network log'); -- check point R8x: +-- mixed (continuous): +insert into stm_track (track_id,track_name) VALUES (21,'network log'); -- check point R8x +insert into stm_track (track_id,track_name) VALUES (22,'utm start'); -- fortinet +insert into stm_track (track_id,track_name) VALUES (23,'detailed log'); -- check point R8x +insert into stm_track (track_id,track_name) VALUES (24,'extended log'); -- check point R8x -insert into stm_dev_typ (dev_typ_id,dev_typ_name,dev_typ_version,dev_typ_manufacturer,dev_typ_predef_svc,dev_typ_is_mgmt,is_pure_routing_device) - VALUES (2,'Netscreen','5.x-6.x','Netscreen', '', true,false); -insert into stm_dev_typ (dev_typ_id,dev_typ_name,dev_typ_version,dev_typ_manufacturer,dev_typ_predef_svc,dev_typ_is_mgmt,is_pure_routing_device) - VALUES (4,'FortiGateStandalone','5ff','Fortinet','', true,false); +-- insert into stm_dev_typ (dev_typ_id,dev_typ_name,dev_typ_version,dev_typ_manufacturer,dev_typ_predef_svc,dev_typ_is_mgmt,is_pure_routing_device) +-- VALUES (2,'Netscreen','5.x-6.x','Netscreen', '', true,false); +-- insert into stm_dev_typ (dev_typ_id,dev_typ_name,dev_typ_version,dev_typ_manufacturer,dev_typ_predef_svc,dev_typ_is_mgmt,is_pure_routing_device) +-- VALUES (4,'FortiGateStandalone','5ff','Fortinet','', true,false); insert into stm_dev_typ (dev_typ_id,dev_typ_name,dev_typ_version,dev_typ_manufacturer,dev_typ_predef_svc,dev_typ_is_mgmt,is_pure_routing_device) VALUES (5,'Barracuda Firewall Control Center','Vx','phion','',true,false); insert into stm_dev_typ (dev_typ_id,dev_typ_name,dev_typ_version,dev_typ_manufacturer,dev_typ_predef_svc,dev_typ_is_mgmt,is_pure_routing_device) VALUES (6,'phion netfence','3.x','phion','', false,false); -insert into stm_dev_typ (dev_typ_id,dev_typ_name,dev_typ_version,dev_typ_manufacturer,dev_typ_predef_svc,dev_typ_is_mgmt,is_pure_routing_device) - VALUES (7,'Check Point','R5x-R7x','Check Point','', true,false); +-- insert into stm_dev_typ (dev_typ_id,dev_typ_name,dev_typ_version,dev_typ_manufacturer,dev_typ_predef_svc,dev_typ_is_mgmt,is_pure_routing_device) +-- VALUES (7,'Check Point','R5x-R7x','Check Point','', true,false); insert into stm_dev_typ (dev_typ_id,dev_typ_name,dev_typ_version,dev_typ_manufacturer,dev_typ_predef_svc,dev_typ_is_mgmt,is_pure_routing_device) VALUES (8,'JUNOS','10-21','Juniper','any;0;0;65535;;junos-predefined-service;simple;', true,false); insert into stm_dev_typ (dev_typ_id,dev_typ_name,dev_typ_version,dev_typ_manufacturer,dev_typ_predef_svc,dev_typ_is_mgmt,is_pure_routing_device) @@ -289,175 +487,14 @@ insert into stm_dev_typ (dev_typ_id,dev_typ_name,dev_typ_version,dev_typ_manufac VALUES (24,'FortiOS Management','REST','Fortinet','',false,true,false) ON CONFLICT DO NOTHING; insert into stm_dev_typ (dev_typ_id,dev_typ_name,dev_typ_version,dev_typ_manufacturer,dev_typ_predef_svc,dev_typ_is_multi_mgmt,dev_typ_is_mgmt,is_pure_routing_device) VALUES (25,'Fortinet FortiOS Gateway','REST','Fortinet','',false,false,false) ON CONFLICT DO NOTHING; - -update stm_dev_typ set dev_typ_predef_svc= -'ANY;0;0;65535;1;other;simple -AOL;6;5190;5194;30;remote;simple -APPLE-ICHAT-SNATMAP;17;5678;5678;1;other;simple -BGP;6;179;179;30;other;simple -CHARGEN;17;19;19;1;other;simple -DHCP-Relay;17;67;67;1;info seeking;simple -DISCARD;17;9;9;1;other;simple -DNS;17;53;53;1;info seeking;simple -ECHO;17;7;7;1;other;simple -FINGER;6;79;79;30;info seeking;simple -FTP;6;21;21;30;remote;simple -FTP-Get;6;21;21;30;remote;simple -FTP-Put;6;21;21;30;remote;simple -GNUTELLA;17;6346;6347;1;remote;simple -GOPHER;6;70;70;30;info seeking;simple -GRE;47;0;65535;60;remote;simple -GTP;6;3386;3386;30;remote;simple -H.323;6;1720;1720;30;remote;simple -HTTP;6;80;80;5;info seeking;simple -HTTP-EXT;6;8000;8001;5;info seeking;simple -HTTPS;6;443;443;30;security;simple -ICMP Address Mask;1;0;65535;1;other;simple -ICMP Dest Unreachable;1;0;65535;1;other;simple -ICMP Fragment Needed;1;0;65535;1;other;simple -ICMP Fragment Reassembly;1;0;65535;1;other;simple -ICMP Host Unreachable;1;0;65535;1;other;simple -ICMP Parameter Problem;1;0;65535;1;other;simple -ICMP Port Unreachable;1;0;65535;1;other;simple -ICMP Protocol Unreach;1;0;65535;1;other;simple -ICMP Redirect;1;0;65535;1;other;simple -ICMP Redirect Host;1;0;65535;1;other;simple -ICMP Redirect TOS & Host;1;0;65535;1;other;simple -ICMP Redirect TOS & Net;1;0;65535;1;other;simple -ICMP Source Quench;1;0;65535;1;other;simple -ICMP Source Route Fail;1;0;65535;1;other;simple -ICMP Time Exceeded;1;0;65535;1;other;simple -ICMP-ANY;1;0;65535;1;other;simple -ICMP-INFO;1;0;65535;1;other;simple -ICMP-TIMESTAMP;1;0;65535;1;other;simple -ICMP6 Dst Unreach addr;58;0;65535;30;other;simple -ICMP6 Dst Unreach admin;58;0;65535;30;other;simple -ICMP6 Dst Unreach beyond;58;0;65535;30;other;simple -ICMP6 Dst Unreach port;58;0;65535;30;other;simple -ICMP6 Dst Unreach route;58;0;65535;30;other;simple -ICMP6 Echo Reply;58;0;65535;30;other;simple -ICMP6 Echo Request;58;0;65535;30;other;simple -ICMP6 HAAD Reply;58;0;65535;30;other;simple -ICMP6 HAAD Request;58;0;65535;30;other;simple -ICMP6 MP Advertisement;58;0;65535;30;other;simple -ICMP6 MP Solicitation;58;0;65535;30;other;simple -ICMP6 Packet Too Big;58;0;65535;30;other;simple -ICMP6 Param Prob header;58;0;65535;30;other;simple -ICMP6 Param Prob nexthdr;58;0;65535;30;other;simple -ICMP6 Param Prob option;58;0;65535;30;other;simple -ICMP6 Time Exceed reasse;58;0;65535;30;other;simple -ICMP6 Time Exceed transi;58;0;65535;30;other;simple -ICMP6-ANY;58;0;65535;30;other;simple -IDENT;6;113;113;30;other;simple -IKE;17;500;500;1;security;simple -IKE-NAT;17;500;500;3;security;simple -IMAP;6;143;143;30;email;simple -Internet Locator Service;6;389;389;30;info seeking;simple -IRC;6;6660;6669;30;remote;simple -L2TP;17;1701;1701;1;remote;simple -LDAP;6;389;389;30;info seeking;simple -LPR;6;515;515;30;other;simple -MAIL;6;25;25;30;email;simple -MGCP-CA;17;2727;2727;120;other;simple -MGCP-UA;17;2427;2427;120;other;simple -MS-AD-BR;;;;1;other;rpc -MS-AD-DRSUAPI;;;;1;other;rpc -MS-AD-DSROLE;;;;1;other;rpc -MS-AD-DSSETUP;;;;1;other;rpc -MS-DTC;;;;1;other;rpc -MS-EXCHANGE-DATABASE;;;;30;other;rpc -MS-EXCHANGE-DIRECTORY;;;;30;other;rpc -MS-EXCHANGE-INFO-STORE;;;;30;other;rpc -MS-EXCHANGE-MTA;;;;30;other;rpc -MS-EXCHANGE-STORE;;;;30;other;rpc -MS-EXCHANGE-SYSATD;;;;30;other;rpc -MS-FRS;;;;1;other;rpc -MS-IIS-COM;;;;30;other;rpc -MS-IIS-IMAP4;;;;1;other;rpc -MS-IIS-INETINFO;;;;1;other;rpc -MS-IIS-NNTP;;;;1;other;rpc -MS-IIS-POP3;;;;1;other;rpc -MS-IIS-SMTP;;;;1;other;rpc -MS-ISMSERV;;;;1;other;rpc -MS-MESSENGER;;;;30;other;rpc -MS-MQQM;;;;1;other;rpc -MS-NETLOGON;;;;1;other;rpc -MS-RPC-ANY;;;;1;other;rpc -MS-RPC-EPM;17;135;135;30;remote;simple -MS-SCHEDULER;;;;1;other;rpc -MS-SQL;6;1433;1433;30;other;simple -MS-WIN-DNS;;;;1;other;rpc -MS-WINS;;;;1;other;rpc -MS-WMIC;;;;30;other;rpc -MSN;6;1863;1863;30;remote;simple -NBDS;17;138;138;1;remote;simple -NBNAME;17;137;137;1;remote;simple -NetMeeting;6;1720;1720;30;remote;simple -NFS;17;111;111;40;remote;simple -NNTP;6;119;119;30;info seeking;simple -NS Global;6;15397;15397;30;remote;simple -NS Global PRO;6;15397;15397;30;remote;simple -NSM;17;69;69;1;other;simple -NTP;17;123;123;1;other;simple -OSPF;89;0;65535;1;other;simple -PC-Anywhere;17;5632;5632;1;remote;simple -PING;1;0;65535;1;other;simple -PINGv6;58;0;65535;30;other;simple -POP3;6;110;110;30;email;simple -PPTP;6;1723;1723;30;security;simple -RADIUS;17;1812;1813;1;other;simple -Real Media;6;7070;7070;30;info seeking;simple -REXEC;6;512;512;30;remote;simple -RIP;17;520;520;1;other;simple -RLOGIN;6;513;513;30;remote;simple -RSH;6;514;514;30;remote;simple -RTSP;6;554;554;30;info seeking;simple -SCCP;6;2000;2000;30;other;simple -SCTP-ANY;132;0;65535;1;other;simple -SIP;17;5060;5060;1;other;simple -SMB;6;139;139;30;remote;simple -SMTP;6;25;25;30;email;simple -SNMP;17;161;161;1;other;simple -SQL Monitor;17;1434;1434;1;other;simple -SQL*Net V1;6;1525;1525;30;other;simple -SQL*Net V2;6;1521;1521;30;other;simple -SSH;6;22;22;30;security;simple -SUN-RPC;;;;1;other;rpc -SUN-RPC-ANY;;;;1;other;rpc -SUN-RPC-MOUNTD;;;;30;other;rpc -SUN-RPC-NFS;;;;40;other;rpc -SUN-RPC-NLOCKMGR;;;;1;other;rpc -SUN-RPC-PORTMAPPER;17;111;111;40;remote;simple -SUN-RPC-RQUOTAD;;;;30;other;rpc -SUN-RPC-RSTATD;;;;30;other;rpc -SUN-RPC-RUSERD;;;;30;other;rpc -SUN-RPC-SADMIND;;;;30;other;rpc -SUN-RPC-SPRAYD;;;;30;other;rpc -SUN-RPC-STATUS;;;;30;other;rpc -SUN-RPC-WALLD;;;;30;other;rpc -SUN-RPC-YPBIND;;;;30;other;rpc -SYSLOG;17;514;514;1;other;simple -TALK;17;517;518;1;other;simple -TCP-ANY;6;0;65535;30;other;simple -TELNET;6;23;23;30;remote;simple -TFTP;17;69;69;1;remote;simple -TRACEROUTE;1;0;65535;1;other;simple -UDP-ANY;17;0;65535;1;other;simple -UUCP;17;540;540;1;remote;simple -VDO Live;6;7000;7010;30;info seeking;simple -VNC;6;5800;5800;30;other;simple -WAIS;6;210;210;30;info seeking;simple -WHOIS;6;43;43;30;info seeking;simple -WINFRAME;6;1494;1494;30;remote;simple -X-WINDOWS;6;6000;6063;30;remote;simple -YMSG;6;5050;5050;30;remote;simple -APPLE-ICHAT;;;;;Apple iChat Services Group;group;AOL|APPLE-ICHAT-SNATMAP|DNS|HTTP|HTTPS|SIP -MGCP;;;;;Media Gateway Control Protoc;group;MGCP-CA|MGCP-UA -MS-AD;;;;;Microsoft Active Directory;group;MS-AD-BR|MS-AD-DRSUAPI|MS-AD-DSROLE|MS-AD-DSSETUP -MS-EXCHANGE;;;;;Microsoft Exchange;group;MS-EXCHANGE-DIRECTORY|MS-EXCHANGE-INFO-STORE|MS-EXCHANGE-MTA|MS-EXCHANGE-STORE|MS-EXCHANGE-SYSATD -MS-IIS;;;;;Microsoft IIS Server;group;MS-IIS-COM|MS-IIS-IMAP4|MS-IIS-INETINFO|MS-IIS-NNTP|MS-IIS-POP3|MS-IIS-SMTP -VOIP;;;;;VOIP Service Group;group;H.323|MGCP-CA|MGCP-UA|SCCP|SIP' -where dev_typ_id=2; +insert into stm_dev_typ (dev_typ_id,dev_typ_name,dev_typ_version,dev_typ_manufacturer,dev_typ_predef_svc,dev_typ_is_multi_mgmt,dev_typ_is_mgmt,is_pure_routing_device) + VALUES (26,'NSX','REST','VMWare','',false,true,false) ON CONFLICT DO NOTHING; +insert into stm_dev_typ (dev_typ_id,dev_typ_name,dev_typ_version,dev_typ_manufacturer,dev_typ_predef_svc,dev_typ_is_multi_mgmt,dev_typ_is_mgmt,is_pure_routing_device) + VALUES (27,'NSX DFW Gateway','REST','VMWare','',false,false,false) ON CONFLICT DO NOTHING; +insert into stm_dev_typ (dev_typ_id,dev_typ_name,dev_typ_version,dev_typ_manufacturer,dev_typ_predef_svc,dev_typ_is_multi_mgmt,dev_typ_is_mgmt,is_pure_routing_device) + VALUES (28,'Cisco Asa','9','Cisco','',false,true,false); +insert into stm_dev_typ (dev_typ_id,dev_typ_name,dev_typ_version,dev_typ_manufacturer,dev_typ_predef_svc,dev_typ_is_multi_mgmt,dev_typ_is_mgmt,is_pure_routing_device) + VALUES (29,'Cisco Asa on FirePower','9','Cisco','',false,true,false); -- SET statement_timeout = 0; -- SET client_encoding = 'UTF8'; @@ -484,6 +521,7 @@ insert into request.state (id,name) VALUES (160,'Plan In Verification'); insert into request.state (id,name) VALUES (199,'Plan Verified'); insert into request.state (id,name) VALUES (200,'To Implement'); +insert into request.state (id,name) VALUES (205,'Rework'); insert into request.state (id,name) VALUES (210,'In Implementation'); insert into request.state (id,name) VALUES (220,'Implementation Trouble'); insert into request.state (id,name) VALUES (249,'Implemented'); @@ -504,6 +542,30 @@ insert into request.state (id,name) VALUES (600,'Done'); insert into request.state (id,name) VALUES (610,'Rejected'); insert into request.state (id,name) VALUES (620,'Discarded'); -INSERT INTO owner (id, name, dn, group_dn, is_default, recert_interval, app_id_external) -VALUES (0, 'super-owner', 'uid=admin,ou=tenant0,ou=operator,ou=user,dc=fworch,dc=internal', 'group-dn-for-super-owner', true, 365, 'NONE') -ON CONFLICT DO NOTHING; +INSERT INTO owner (id, name, is_default, recert_interval, app_id_external) +VALUES (0, 'super-owner', true, 365, 'NONE'); +INSERT INTO owner_responsible_type (id, name, active, sort_order, allow_modelling, allow_recertification) +VALUES + (1, 'Main responsible', true, 10, true, true), + (2, 'Supporting responsible', true, 20, true, true), + (3, 'Optional escalation responsible', true, 30, false, false) +ON CONFLICT DO NOTHING; +INSERT INTO owner_responsible (owner_id, dn, responsible_type) +VALUES + (0, 'uid=admin,ou=tenant0,ou=operator,ou=user,dc=fworch,dc=internal', 1), + (0, 'group-dn-for-super-owner', 2) +ON CONFLICT DO NOTHING; + +insert into stm_link_type (id, name) VALUES (2, 'ordered'); +insert into stm_link_type (id, name) VALUES (3, 'inline'); +insert into stm_link_type (id, name) VALUES (4, 'concatenated'); +insert into stm_link_type (id, name) VALUES (5, 'domain'); + +-- insert into compliance.assessability_issue_type (type_id, type_name) VALUES (1, 'empty group'); +-- insert into compliance.assessability_issue_type (type_id, type_name) VALUES (2, 'broadcast address'); +-- insert into compliance.assessability_issue_type (type_id, type_name) VALUES (3, 'DHCP IP undefined address'); +-- insert into compliance.assessability_issue_type (type_id, type_name) VALUES (4, 'dynamic internet address'); + +INSERT INTO stm_import (import_type_id, import_type_name) VALUES (1, 'rule'); +INSERT INTO stm_import (import_type_id, import_type_name) VALUES (2, 'owner'); +INSERT INTO stm_import (import_type_id, import_type_name) VALUES (3, 'admin via reinitialize button'); diff --git a/roles/database/files/sql/creation/fworch-views-materialized.sql b/roles/database/files/sql/creation/fworch-views-materialized.sql new file mode 100644 index 0000000000..614c27e734 --- /dev/null +++ b/roles/database/files/sql/creation/fworch-views-materialized.sql @@ -0,0 +1,222 @@ +/* + logic for checking overlap of ip ranges: + not (end_ip1 < start_ip2 or start_ip1 > end_ip2) + = + end_ip1 >= start_ip2 and start_ip1 <= end_ip2 + + ip1 = owner_network.ip + ip2 = object.ip + + --> + owner_network.ip_end >= object.ip and owner_network.ip <= object.ip_end + + here: + --> + owner_network.ip_end >= o.obj_ip and owner_network.ip <= o.obj_ip_end + +*/ + +DROP VIEW IF EXISTS v_rule_with_src_owner CASCADE; +DROP VIEW IF EXISTS v_rule_with_dst_owner CASCADE; +DROP VIEW IF EXISTS v_rule_with_ip_owner CASCADE; + +CREATE OR REPLACE VIEW v_active_access_allow_rules AS + SELECT rule_id, + rule_src, rule_dst, rule_svc, + rule_svc_neg, rule_src_neg, rule_dst_neg, + mgm_id, rule_uid, + rule_num_numeric, rule_disabled, + rule_src_refs, rule_dst_refs, rule_svc_refs, + rule_from_zone, rule_to_zone, + rule_action, rule_track, track_id, action_id, + rule_installon, rule_comment, rule_name, rule_implied, rule_custom_fields, + rule_create, removed, + is_global, + rulebase_id + FROM rule r + WHERE r.active AND -- only show current (not historical) rules + r.access_rule AND -- only show access rules (no NAT) + r.rule_head_text IS NULL AND -- do not show header rules + NOT r.rule_disabled AND -- do not show disabled rules + NOT r.action_id IN (2,3,7); -- do not deal with deny rules + +CREATE OR REPLACE VIEW v_rule_ownership_mode AS + SELECT c.config_value as mode FROM config c + WHERE c.config_key = 'ruleOwnershipMode'; + +CREATE OR REPLACE VIEW v_rule_with_rule_owner AS + SELECT r.rule_id, ow.id as owner_id, ow.name as owner_name, 'rule' AS matches, + ow.recert_interval, max(rec.recert_date) AS rule_last_certified + FROM v_active_access_allow_rules r + LEFT JOIN rule_metadata met ON (r.rule_uid=met.rule_uid) + LEFT JOIN rule_owner ro ON (ro.rule_metadata_id=met.rule_metadata_id) + LEFT JOIN owner ow ON (ro.owner_id=ow.id) + LEFT JOIN recertification rec ON (rec.rule_metadata_id = met.rule_metadata_id AND rec.owner_id = ow.id AND rec.recertified IS TRUE) + WHERE NOT ow.id IS NULL + GROUP BY r.rule_id, ow.id, ow.name, ow.recert_interval; + +CREATE OR REPLACE VIEW v_rule_with_rule_owner_1 AS + SELECT DISTINCT r.rule_id, r.rule_uid, r.rule_name, r.mgm_id, r.rulebase_id, ow.id AS owner_id, met.rule_metadata_id + FROM v_active_access_allow_rules r + JOIN rule_metadata met ON r.rule_uid = met.rule_uid + JOIN rule_owner ro ON ro.rule_metadata_id = met.rule_metadata_id + JOIN owner ow ON ro.owner_id = ow.id; + +CREATE OR REPLACE VIEW v_excluded_src_ips AS + SELECT distinct o.obj_ip + FROM v_rule_with_rule_owner r + LEFT JOIN rule_from rf ON (r.rule_id=rf.rule_id) + LEFT JOIN objgrp_flat of ON (rf.obj_id=of.objgrp_flat_id) + LEFT JOIN object o ON (of.objgrp_flat_member_id=o.obj_id) + WHERE NOT o.obj_ip='0.0.0.0/0'; + +CREATE OR REPLACE VIEW v_excluded_dst_ips AS + SELECT distinct o.obj_ip + FROM v_rule_with_rule_owner r + LEFT JOIN rule_to rt ON (r.rule_id=rt.rule_id) + LEFT JOIN objgrp_flat of ON (rt.obj_id=of.objgrp_flat_id) + LEFT JOIN object o ON (of.objgrp_flat_member_id=o.obj_id) + WHERE NOT o.obj_ip='0.0.0.0/0'; + + -- if start_ip1 <= end_ip2 and start_ip2 <= end_ip1: + -- overlap_start = max(start_ip1, start_ip2) + -- overlap_end = min(end_ip1, end_ip2) + -- return (overlap_start, overlap_end) + -- else: + -- return None # No overlap + +CREATE OR REPLACE VIEW v_rule_with_src_owner AS + SELECT + r.rule_id, ow.id as owner_id, ow.name as owner_name, + CASE + WHEN onw.ip = onw.ip_end + THEN SPLIT_PART(CAST(onw.ip AS VARCHAR), '/', 1) -- Single IP overlap, removing netmask + ELSE + CASE WHEN -- range is a single network + host(broadcast(inet_merge(onw.ip, onw.ip_end))) = host (onw.ip_end) AND + host(inet_merge(onw.ip, onw.ip_end)) = host (onw.ip) + THEN + text(inet_merge(onw.ip, onw.ip_end)) + ELSE + CONCAT(SPLIT_PART(onw.ip::VARCHAR,'/', 1), '-', SPLIT_PART(onw.ip_end::VARCHAR, '/', 1)) + END + END AS matching_ip, + 'source' AS match_in, + ow.recert_interval, max(rec.recert_date) AS rule_last_certified + FROM v_active_access_allow_rules r + LEFT JOIN rule_from ON (r.rule_id=rule_from.rule_id) + LEFT JOIN objgrp_flat of ON (rule_from.obj_id=of.objgrp_flat_id) + LEFT JOIN object o ON (of.objgrp_flat_member_id=o.obj_id) + LEFT JOIN owner_network onw ON (onw.ip_end >= o.obj_ip AND onw.ip <= o.obj_ip_end) + LEFT JOIN owner ow ON (onw.owner_id=ow.id) + LEFT JOIN rule_metadata met ON (r.rule_uid=met.rule_uid) + LEFT JOIN recertification rec ON (rec.rule_metadata_id = met.rule_metadata_id AND rec.owner_id = ow.id AND rec.recertified IS TRUE) + WHERE r.rule_id NOT IN (SELECT distinct rwo.rule_id FROM v_rule_with_rule_owner rwo) AND + CASE + when (select mode from v_rule_ownership_mode) = 'exclusive' then (NOT o.obj_ip IS NULL) AND o.obj_ip NOT IN (select * from v_excluded_src_ips) + else NOT o.obj_ip IS NULL + END + GROUP BY r.rule_id, o.obj_ip, o.obj_ip_end, onw.ip, onw.ip_end, ow.id, ow.name, ow.recert_interval; + +CREATE OR REPLACE VIEW v_rule_with_dst_owner AS + SELECT + r.rule_id, ow.id as owner_id, ow.name as owner_name, + CASE + WHEN onw.ip = onw.ip_end + THEN SPLIT_PART(CAST(onw.ip AS VARCHAR), '/', 1) -- Single IP overlap, removing netmask + ELSE + CASE WHEN -- range is a single network + host(broadcast(inet_merge(onw.ip, onw.ip_end))) = host (onw.ip_end) AND + host(inet_merge(onw.ip, onw.ip_end)) = host (onw.ip) + THEN + text(inet_merge(onw.ip, onw.ip_end)) + ELSE + CONCAT(SPLIT_PART(onw.ip::VARCHAR,'/', 1), '-', SPLIT_PART(onw.ip_end::VARCHAR, '/', 1)) + END + END AS matching_ip, + 'destination' AS match_in, + ow.recert_interval, max(rec.recert_date) AS rule_last_certified + FROM v_active_access_allow_rules r + LEFT JOIN rule_to rt ON (r.rule_id=rt.rule_id) + LEFT JOIN objgrp_flat of ON (rt.obj_id=of.objgrp_flat_id) + LEFT JOIN object o ON (of.objgrp_flat_member_id=o.obj_id) + LEFT JOIN owner_network onw ON (onw.ip_end >= o.obj_ip AND onw.ip <= o.obj_ip_end) + LEFT JOIN owner ow ON (onw.owner_id=ow.id) + LEFT JOIN rule_metadata met ON (r.rule_uid=met.rule_uid) + LEFT JOIN recertification rec ON (rec.rule_metadata_id = met.rule_metadata_id AND rec.owner_id = ow.id AND rec.recertified IS TRUE) + WHERE r.rule_id NOT IN (SELECT distinct rwo.rule_id FROM v_rule_with_rule_owner rwo) AND + CASE + when (select mode from v_rule_ownership_mode) = 'exclusive' then (NOT o.obj_ip IS NULL) AND o.obj_ip NOT IN (select * from v_excluded_dst_ips) + else NOT o.obj_ip IS NULL + END + GROUP BY r.rule_id, o.obj_ip, o.obj_ip_end, onw.ip, onw.ip_end, ow.id, ow.name, ow.recert_interval; + +CREATE OR REPLACE VIEW v_rule_with_ip_owner AS + SELECT DISTINCT uno.rule_id, uno.owner_id, uno.owner_name, + string_agg(DISTINCT match_in || ':' || matching_ip::VARCHAR, '; ' order by match_in || ':' || matching_ip::VARCHAR desc) as matches, + uno.recert_interval, uno.rule_last_certified + FROM ( SELECT DISTINCT * FROM v_rule_with_src_owner AS src UNION SELECT DISTINCT * FROM v_rule_with_dst_owner AS dst) AS uno + GROUP BY uno.rule_id, uno.owner_id, uno.owner_name, uno.recert_interval, uno.rule_last_certified; + +CREATE OR REPLACE FUNCTION purge_view_rule_with_owner () RETURNS VOID AS $$ +DECLARE + r_temp_record RECORD; +BEGIN + select INTO r_temp_record schemaname, viewname from pg_catalog.pg_views + where schemaname NOT IN ('pg_catalog', 'information_schema') and viewname='view_rule_with_owner' + order by schemaname, viewname; + IF FOUND THEN + DROP VIEW IF EXISTS view_rule_with_owner CASCADE; + END IF; + DROP MATERIALIZED VIEW IF EXISTS view_rule_with_owner CASCADE; + RETURN; +END; +$$ LANGUAGE plpgsql; + +SELECT * FROM purge_view_rule_with_owner (); +DROP FUNCTION purge_view_rule_with_owner(); + +-- LargeOwnerChange: remove MATERIALIZED for small installations +-- SmallOwnerChange: add MATERIALIZED for large installations +CREATE MATERIALIZED VIEW view_rule_with_owner AS + SELECT DISTINCT ar.rule_id, ar.owner_id, ar.owner_name, ar.matches, ar.recert_interval, ar.rule_last_certified, + r.rule_num_numeric, r.track_id, r.action_id, r.rule_from_zone, r.rule_to_zone, r.mgm_id, r.rule_uid, + r.rule_action, r.rule_name, r.rule_comment, r.rule_track, r.rule_src_neg, r.rule_dst_neg, r.rule_svc_neg, + r.rule_head_text, r.rule_disabled, r.access_rule, r.xlate_rule, r.nat_rule + FROM ( SELECT * FROM v_rule_with_rule_owner AS rul UNION SELECT * FROM v_rule_with_ip_owner AS ips) AS ar + LEFT JOIN rule AS r USING (rule_id); + +CREATE TABLE IF NOT EXISTS refresh_log ( + id SERIAL PRIMARY KEY, + view_name TEXT NOT NULL, + refreshed_at TIMESTAMPTZ DEFAULT now(), + status TEXT +); + +CREATE OR REPLACE FUNCTION refresh_view_rule_with_owner() +RETURNS SETOF refresh_log AS $$ +DECLARE + status_message TEXT; +BEGIN + -- Attempt to refresh the materialized view + BEGIN + REFRESH MATERIALIZED VIEW view_rule_with_owner; + status_message := 'Materialized view refreshed successfully'; + EXCEPTION + WHEN OTHERS THEN + status_message := format('Failed to refresh view: %s', SQLERRM); + END; + + -- Log the operation + INSERT INTO refresh_log (view_name, status) + VALUES ('view_rule_with_owner', status_message); + + -- Return the log entry + RETURN QUERY SELECT * FROM refresh_log WHERE view_name = 'view_rule_with_owner' ORDER BY refreshed_at DESC LIMIT 1; +END; +$$ LANGUAGE plpgsql VOLATILE; + + +-- Create indexes on the materialized view +CREATE INDEX IF NOT EXISTS idx_view_rule_with_owner_rule_id ON view_rule_with_owner (rule_id); +CREATE INDEX IF NOT EXISTS idx_view_rule_with_owner_owner_id ON view_rule_with_owner (owner_id); diff --git a/roles/database/files/sql/idempotent/fworch-api-funcs.sql b/roles/database/files/sql/idempotent/fworch-api-funcs.sql index 5f6de591ca..bd1f25c5d9 100644 --- a/roles/database/files/sql/idempotent/fworch-api-funcs.sql +++ b/roles/database/files/sql/idempotent/fworch-api-funcs.sql @@ -3,15 +3,13 @@ CREATE OR REPLACE FUNCTION public.get_visible_devices_per_tenant(integer) RETURNS SETOF device_type LANGUAGE 'plpgsql' - COST 100 STABLE - ROWS 1000 AS $BODY$ DECLARE - i_tenant_id ALIAS FOR $1; - i_dev_id integer; + i_tenant_id ALIAS FOR $1; + i_dev_id integer; v_dev_name VARCHAR; - b_can_view_all_devices boolean; + b_can_view_all_devices boolean; BEGIN SELECT INTO b_can_view_all_devices tenant_can_view_all_devices FROM tenant WHERE tenant_id=i_tenant_id; IF b_can_view_all_devices THEN @@ -20,10 +18,20 @@ BEGIN RETURN NEXT ROW (i_dev_id, v_dev_name); END LOOP; ELSE - FOR i_dev_id, v_dev_name IN SELECT device_id, dev_name FROM tenant JOIN tenant_to_device USING (tenant_id) LEFT JOIN device ON (tenant_to_device.device_id=device.dev_id) WHERE tenant.tenant_id=i_tenant_id + FOR i_dev_id, v_dev_name IN + SELECT device_id, dev_name FROM tenant + RIGHT JOIN tenant_to_device USING (tenant_id) + LEFT JOIN device ON (tenant_to_device.device_id=device.dev_id) + WHERE tenant.tenant_id=i_tenant_id + UNION + SELECT dev_id, dev_name FROM tenant + RIGHT JOIN tenant_to_management USING (tenant_id) + LEFT JOIN device ON (NOT tenant_to_management.shared AND tenant_to_management.management_id=device.mgm_id) + WHERE tenant.tenant_id=i_tenant_id and dev_id is not null LOOP RETURN NEXT ROW (i_dev_id, v_dev_name); END LOOP; + -- also add devices that belong to unfiltered managements END IF; RETURN; END; @@ -32,16 +40,13 @@ $BODY$; CREATE OR REPLACE FUNCTION public.get_visible_managements_per_tenant(integer) RETURNS SETOF device_type LANGUAGE 'plpgsql' - COST 100 STABLE - ROWS 1000 AS $BODY$ DECLARE - i_tenant_id ALIAS FOR $1; - i_mgm_id integer; + i_tenant_id ALIAS FOR $1; + i_mgm_id integer; v_mgm_name VARCHAR; - b_can_view_all_devices boolean; - i_dev_id integer; + b_can_view_all_devices boolean; BEGIN SELECT INTO b_can_view_all_devices tenant_can_view_all_devices FROM tenant WHERE tenant_id=i_tenant_id; IF b_can_view_all_devices THEN @@ -50,13 +55,16 @@ BEGIN RETURN NEXT ROW (i_mgm_id, v_mgm_name); END LOOP; ELSE - -- return all managements belonging to devices the tenant can view - derive it from get_visible_devices_per_tenant: - FOR i_mgm_id, v_mgm_name IN SELECT DISTINCT mgm_id, mgm_name FROM management WHERE mgm_id IN (SELECT mgm_id FROM device WHERE dev_id IN (SELECT id FROM get_visible_devices_per_tenant(i_tenant_id))) + FOR i_mgm_id, v_mgm_name IN + SELECT mgm_id, mgm_name FROM tenant + RIGHT JOIN tenant_to_management USING (tenant_id) + LEFT JOIN management ON (management_id=mgm_id) + WHERE tenant.tenant_id=i_tenant_id and mgm_id is not null LOOP RETURN NEXT ROW (i_mgm_id, v_mgm_name); END LOOP; END IF; - RETURN; + RETURN; END; $BODY$; @@ -67,7 +75,7 @@ CREATE OR REPLACE FUNCTION public.filter_rule_nwobj_resolveds(management_row man AS $function$ SELECT o.* FROM rule_nwobj_resolved r JOIN object o ON (r.obj_id=o.obj_id) - WHERE r.mgm_id = management_row.mgm_id AND rule_id = any (rule_ids) AND r.created <= import_id AND (r.removed IS NULL OR r.removed >= import_id) + WHERE r.mgm_id = management_row.mgm_id AND rule_id = any (rule_ids) AND r.created <= import_id AND (r.removed IS NULL OR r.removed > import_id) GROUP BY o.obj_id ORDER BY MAX(obj_name), o.obj_id $function$; @@ -79,7 +87,7 @@ CREATE OR REPLACE FUNCTION public.filter_rule_svc_resolveds(management_row manag AS $function$ SELECT s.* FROM rule_svc_resolved r JOIN service s ON (r.svc_id=s.svc_id) - WHERE r.mgm_id = management_row.mgm_id AND rule_id = any (rule_ids) AND r.created <= import_id AND (r.removed IS NULL OR r.removed >= import_id) + WHERE r.mgm_id = management_row.mgm_id AND rule_id = any (rule_ids) AND r.created <= import_id AND (r.removed IS NULL OR r.removed > import_id) GROUP BY s.svc_id ORDER BY MAX(svc_name), s.svc_id $function$; @@ -91,7 +99,568 @@ CREATE OR REPLACE FUNCTION public.filter_rule_user_resolveds(management_row mana AS $function$ SELECT u.* FROM rule_user_resolved r JOIN usr u ON (r.user_id=u.user_id) - WHERE r.mgm_id = management_row.mgm_id AND rule_id = any (rule_ids) AND r.created <= import_id AND (r.removed IS NULL OR r.removed >= import_id) + WHERE r.mgm_id = management_row.mgm_id AND rule_id = any (rule_ids) AND r.created <= import_id AND (r.removed IS NULL OR r.removed > import_id) GROUP BY u.user_id ORDER BY MAX(user_name), u.user_id -$function$; \ No newline at end of file +$function$; + + +CREATE OR REPLACE FUNCTION ip_ranges_overlap(ip1_start cidr, ip1_end cidr, ip2_start cidr, ip2_end cidr, inverted boolean DEFAULT FALSE) + RETURNS boolean AS $$ + BEGIN + IF ip1_start IS NULL OR ip1_end IS NULL OR ip2_start IS NULL OR ip2_end IS NULL THEN + RETURN FALSE; + END IF; + + IF inverted THEN -- []: cidr1 ~> invert (): cidr2 + IF ip1_start <= ip2_start AND ip2_end <= ip1_end THEN --[-*(--)-*]-- ~> --]-*(--)-*[-- + RETURN FALSE; + ELSE + RETURN TRUE; + END IF; + END IF; + + RETURN ip1_start <= ip2_end AND ip2_start <= ip1_end; + END; +$$ LANGUAGE 'plpgsql' STABLE; + + +CREATE OR REPLACE FUNCTION has_relevant_change(cl_rule changelog_rule, tenant integer) +RETURNS boolean AS $$ + DECLARE show boolean DEFAULT false; + + BEGIN + IF tenant IS NULL THEN + RAISE EXCEPTION 'Given tenant is NULL'; + ELSIF tenant = 1 THEN + show := true; + ELSE + IF EXISTS ( + SELECT diff.obj_id, diff.negated FROM ( -- set of difference between rule_from of old and new rule + SELECT obj_id, negated FROM rule_from WHERE rule_id = cl_rule.old_rule_id EXCEPT SELECT obj_id, negated FROM rule_from WHERE rule_id = cl_rule.new_rule_id + UNION + (SELECT obj_id, negated FROM rule_from WHERE rule_id = cl_rule.new_rule_id EXCEPT SELECT obj_id, negated FROM rule_from WHERE rule_id = cl_rule.old_rule_id) + ) AS diff + JOIN objgrp_flat ON (obj_id=objgrp_flat_id) + JOIN object ON (objgrp_flat_member_id=object.obj_id) + JOIN tenant_network ON + (ip_ranges_overlap(obj_ip, obj_ip_end, tenant_net_ip, tenant_net_ip_end, diff.negated)) + WHERE tenant_id = tenant + ) THEN + show := true; + END IF; + + IF EXISTS ( + SELECT diff.obj_id, diff.negated FROM ( -- set of difference between rule_to of old and new rule + SELECT obj_id, negated FROM rule_to WHERE rule_id = cl_rule.old_rule_id EXCEPT SELECT obj_id, negated FROM rule_to WHERE rule_id = cl_rule.new_rule_id + UNION + (SELECT obj_id, negated FROM rule_to WHERE rule_id = cl_rule.new_rule_id EXCEPT SELECT obj_id, negated FROM rule_to WHERE rule_id = cl_rule.old_rule_id) + ) AS diff + JOIN objgrp_flat ON (obj_id=objgrp_flat_id) + JOIN object ON (objgrp_flat_member_id=object.obj_id) + JOIN tenant_network ON + (ip_ranges_overlap(obj_ip, obj_ip_end, tenant_net_ip, tenant_net_ip_end, diff.negated)) + WHERE tenant_id = tenant + ) THEN + show := true; + END IF; + + END IF; + + RETURN show; + END; +$$ LANGUAGE 'plpgsql' STABLE; + + +CREATE OR REPLACE FUNCTION cl_rule_relevant_for_tenant(cl_rule changelog_rule, hasura_session json) +RETURNS boolean AS $$ + DECLARE t_id integer; + show boolean DEFAULT false; + + BEGIN + t_id := (hasura_session ->> 'x-hasura-tenant-id')::integer; + + IF t_id IS NULL THEN + RAISE EXCEPTION 'No tenant id found in hasura session'; --> only happens when using auth via x-hasura-admin-secret (no tenant id is set) + ELSIF t_id = 1 THEN + show := true; + ELSE + show := has_relevant_change(cl_rule, t_id); + END IF; + + RETURN show; + END; +$$ LANGUAGE 'plpgsql' STABLE; + + + +CREATE OR REPLACE FUNCTION rule_from_relevant_for_tenant(rule_from rule_from, hasura_session json) +RETURNS boolean AS $$ + DECLARE + t_id integer; + show boolean DEFAULT false; + rule_to_obj RECORD; + i_dev_id integer; + BEGIN + t_id := (hasura_session ->> 'x-hasura-tenant-id')::integer; + SELECT INTO i_dev_id dev_id FROM rule_from LEFT JOIN rule USING (rule_id); + IF t_id IS NULL THEN + RAISE EXCEPTION 'No tenant id found in hasura session'; --> only happens when using auth via x-hasura-admin-secret (no tenant id is set) + ELSIF t_id = 1 THEN + show := true; + ELSE + IF rulebase_fully_visible_to_tenant(i_dev_id, t_id) THEN + show := true; + ELSE + IF EXISTS ( -- ip of rule_from object is in tenant_network of tenant + SELECT rf.obj_id FROM rule_from rf + LEFT JOIN rule r ON (rf.rule_id=r.rule_id) + LEFT JOIN objgrp_flat ON (rf.obj_id=objgrp_flat.objgrp_flat_id) + LEFT JOIN object ON (objgrp_flat.objgrp_flat_member_id=object.obj_id) + LEFT JOIN tenant_network ON + (ip_ranges_overlap(obj_ip, obj_ip_end, tenant_net_ip, tenant_net_ip_end, rf.negated != r.rule_src_neg)) + WHERE rule_from_id = rule_from.rule_from_id AND tenant_id = t_id + ) THEN + show := true; + ELSE -- check if all rule_from objects visible since relevant rule_to exists + FOR rule_to_obj IN + SELECT rt.*, tenant_network.tenant_id + FROM rule_to rt + LEFT JOIN rule r ON (rt.rule_id=r.rule_id) + LEFT JOIN objgrp_flat ON (rt.obj_id=objgrp_flat_id) + LEFT JOIN object ON (objgrp_flat_member_id=object.obj_id) + LEFT JOIN tenant_network ON + (ip_ranges_overlap(obj_ip, obj_ip_end, tenant_net_ip, tenant_net_ip_end, rt.negated != r.rule_dst_neg)) + WHERE rt.rule_id = rule_from.rule_id + LOOP + IF rule_to_obj.tenant_id = t_id THEN + show := true; + EXIT; + END IF; + END LOOP; + END IF; + END IF; + END IF; + + RETURN show; + END; +$$ LANGUAGE 'plpgsql' STABLE; + + + +CREATE OR REPLACE FUNCTION rule_to_relevant_for_tenant(rule_to rule_to, hasura_session json) +RETURNS boolean AS $$ + DECLARE + t_id integer; + show boolean DEFAULT false; + rule_from_obj RECORD; + i_dev_id integer; + BEGIN + t_id := (hasura_session ->> 'x-hasura-tenant-id')::integer; + SELECT INTO i_dev_id dev_id FROM rule_to LEFT JOIN rule USING (rule_id); + + IF t_id IS NULL THEN + RAISE EXCEPTION 'No tenant id found in hasura session'; --> only happens when using auth via x-hasura-admin-secret (no tenant id is set) + ELSIF t_id = 1 THEN + show := true; + ELSE + IF rulebase_fully_visible_to_tenant(i_dev_id, t_id) THEN + show := true; + ELSE + IF EXISTS ( -- ip of rule_to object is in tenant_network of tenant + SELECT rt.obj_id FROM rule_to rt + LEFT JOIN rule r ON (rt.rule_id=r.rule_id) + LEFT JOIN objgrp_flat ON (rt.obj_id=objgrp_flat.objgrp_flat_id) + LEFT JOIN object ON (objgrp_flat.objgrp_flat_member_id=object.obj_id) + LEFT JOIN tenant_network ON + (ip_ranges_overlap(obj_ip, obj_ip_end, tenant_net_ip, tenant_net_ip_end, rt.negated != r.rule_dst_neg)) + WHERE rule_to_id = rule_to.rule_to_id AND tenant_id = t_id + ) THEN + show := true; + ELSE -- check if all rule_to objects visible since relevant rule_from exists + FOR rule_from_obj IN + SELECT rf.*, tenant_network.tenant_id + FROM rule_from rf + LEFT JOIN rule r ON (rf.rule_id=r.rule_id) + LEFT JOIN objgrp_flat ON (rf.obj_id=objgrp_flat_id) + LEFT JOIN object ON (objgrp_flat.objgrp_flat_member_id=object.obj_id) + LEFT JOIN tenant_network ON + (ip_ranges_overlap(obj_ip, obj_ip_end, tenant_net_ip, tenant_net_ip_end, rf.negated != r.rule_src_neg)) + WHERE rf.rule_id = rule_to.rule_id + LOOP + IF rule_from_obj.tenant_id = t_id THEN + show := true; + EXIT; + END IF; + END LOOP; + END IF; + END IF; + END IF; + + RETURN show; + END; +$$ LANGUAGE 'plpgsql' STABLE; + +CREATE OR REPLACE FUNCTION get_changelog_rules_for_tenant(device_row device, tenant integer, hasura_session json) +RETURNS SETOF changelog_rule AS $$ + DECLARE t_id integer; + + BEGIN + t_id := (hasura_session ->> 'x-hasura-tenant-id')::integer; + + IF t_id IS NULL THEN + RAISE EXCEPTION 'No tenant id found in hasura session'; + -- ELSIF t_id != 1 THEN + -- RAISE EXCEPTION 'Tenant id in hasura session is not 1 (admin). Tenant simulation not allowed.'; + ELSIF tenant = 1 THEN + RAISE EXCEPTION 'Tenant 1 (admin) cannot be simulated.'; + ELSE + RETURN QUERY + SELECT cl_rule.* FROM changelog_rule cl_rule + WHERE cl_rule.dev_id = device_row.dev_id AND has_relevant_change(cl_rule, tenant) = true; + END IF; + END; +$$ LANGUAGE 'plpgsql' STABLE; + +CREATE OR REPLACE FUNCTION get_objects_for_tenant(management_row management, tenant integer, hasura_session json) +RETURNS SETOF object AS $$ + DECLARE t_id integer; + + BEGIN + t_id := (hasura_session ->> 'x-hasura-tenant-id')::integer; + + IF t_id IS NULL THEN + RAISE EXCEPTION 'No tenant id found in hasura session'; --> only happens when using auth via x-hasura-admin-secret (no tenant id is set) + -- ELSIF t_id != 1 THEN + -- RAISE EXCEPTION 'Tenant id in hasura session is not 1 (admin). Tenant simulation not allowed.'; + ELSIF tenant = 1 THEN + RAISE EXCEPTION 'Tenant 1 (admin) cannot be simulated.'; + ELSE + RETURN QUERY + SELECT o.* FROM ( + SELECT o.* FROM object o + LEFT JOIN rule_from rf ON (o.obj_id=rf.obj_id) + LEFT JOIN rule r ON (rf.rule_id=r.rule_id) + LEFT JOIN rule_to rt ON (r.rule_id=rt.rule_id) + LEFT JOIN objgrp_flat rt_of ON (rt.obj_id=rt_of.objgrp_flat_id) + LEFT JOIN object rt_o ON (rt_of.objgrp_flat_member_id=rt_o.obj_id) + LEFT JOIN tenant_network ON + (ip_ranges_overlap(o.obj_ip, o.obj_ip_end, tenant_net_ip, tenant_net_ip_end, rf.negated != r.rule_src_neg) + OR ip_ranges_overlap(rt_o.obj_ip, rt_o.obj_ip_end, tenant_net_ip, tenant_net_ip_end, rt.negated != r.rule_dst_neg)) + WHERE o.mgm_id = management_row.mgm_id AND tenant_id = tenant AND r.rule_head_text is NULL + UNION + SELECT o.* FROM object o + LEFT JOIN rule_to rt ON (o.obj_id=rt.obj_id) + LEFT JOIN rule r ON (rt.rule_id=r.rule_id) + LEFT JOIN rule_from rf ON (r.rule_id=rf.rule_id) + LEFT JOIN objgrp_flat rf_of ON (rf.obj_id=rf_of.objgrp_flat_id) + LEFT JOIN object rf_o ON (rf_of.objgrp_flat_member_id=rf_o.obj_id) + LEFT JOIN tenant_network ON + (ip_ranges_overlap(o.obj_ip, o.obj_ip_end, tenant_net_ip, tenant_net_ip_end, rt.negated != r.rule_dst_neg) + OR ip_ranges_overlap(rf_o.obj_ip, rf_o.obj_ip_end, tenant_net_ip, tenant_net_ip_end, rf.negated != r.rule_src_neg)) + WHERE o.mgm_id = management_row.mgm_id AND tenant_id = tenant AND r.rule_head_text is NULL + ) AS o + ORDER BY obj_name; + END IF; + END; +$$ LANGUAGE 'plpgsql' STABLE; + + +------------------------------------------------------------------------------------------------------------------------ +-- rule_relevant complexity: O(rf + rt) +-- rule_from_relevant complexity: O(rt) +-- rule_to_relevant complexity: O(rf) +-- total for single rule: O(rf + rt + 2*rf*rt) +-- theoretical min needed complexity: O(2(rf+rt)) +-- obj_relevant complexity: O(r * rf * rt) +-- with material view: all O(1) but additional O(ten * r * (rf + rt)) for each import / tenant change + +CREATE OR REPLACE FUNCTION rulebase_fully_visible_to_tenant(i_dev_id INTEGER, i_tenant_id INTEGER) + RETURNS boolean AS $$ + DECLARE + i_mgm_id INTEGER; + i_temp_id INTEGER; + b_mgm_is_unfiltered boolean := FALSE; + b_dev_is_unfiltered boolean := FALSE; + BEGIN + SELECT INTO i_mgm_id + mgm_id + FROM device LEFT JOIN management USING (mgm_id) + WHERE dev_id=i_dev_id; + + SELECT INTO i_temp_id + management_id + FROM tenant_to_management + WHERE management_id=i_mgm_id AND tenant_id=i_tenant_id AND NOT shared; + + IF FOUND THEN + b_mgm_is_unfiltered := TRUE; + END IF; + + SELECT INTO i_temp_id + device_id + FROM tenant_to_device + WHERE device_id=i_dev_id AND tenant_id=i_tenant_id AND NOT shared; + + IF FOUND THEN + b_dev_is_unfiltered := TRUE; + END IF; + + RETURN b_mgm_is_unfiltered OR b_dev_is_unfiltered; + + END; +$$ LANGUAGE 'plpgsql' STABLE; + + +CREATE OR REPLACE FUNCTION rule_relevant_for_tenant(rule rule, hasura_session json) +RETURNS boolean AS $$ + DECLARE + t_id integer; + show boolean DEFAULT false; + mgm_unfiltered_tenant_id integer; + gw_unfiltered_tenant_id integer; + + BEGIN + t_id := (hasura_session ->> 'x-hasura-tenant-id')::integer; + + IF t_id IS NULL THEN + RAISE EXCEPTION 'No tenant id found in hasura session'; --> only happens when using auth via x-hasura-admin-secret (no tenant id is set) + ELSIF t_id = 1 THEN + show := true; + ELSE + IF rulebase_fully_visible_to_tenant(rule.dev_id, t_id) THEN + show := true; + ELSE + IF EXISTS ( + SELECT rf.obj_id FROM rule_from rf + LEFT JOIN rule r ON (rf.rule_id=r.rule_id) + LEFT JOIN objgrp_flat ON (rf.obj_id=objgrp_flat.objgrp_flat_id) + LEFT JOIN object ON (objgrp_flat.objgrp_flat_member_id=object.obj_id) + LEFT JOIN tenant_network ON + (ip_ranges_overlap(obj_ip, obj_ip_end, tenant_net_ip, tenant_net_ip_end, rf.negated != r.rule_src_neg)) + WHERE rf.rule_id = rule.rule_id AND tenant_id = t_id + ) THEN + show := true; + ELSIF EXISTS ( + SELECT rt.obj_id FROM rule_to rt + LEFT JOIN rule r ON (rt.rule_id=r.rule_id) + LEFT JOIN objgrp_flat ON (rt.obj_id=objgrp_flat.objgrp_flat_id) + LEFT JOIN object ON (objgrp_flat.objgrp_flat_member_id=object.obj_id) + LEFT JOIN tenant_network ON + (ip_ranges_overlap(obj_ip, obj_ip_end, tenant_net_ip, tenant_net_ip_end, rt.negated != r.rule_dst_neg)) + WHERE rt.rule_id = rule.rule_id AND tenant_id = t_id + ) THEN + show := true; + END IF; + END IF; + END IF; + + RETURN show; + END; +$$ LANGUAGE 'plpgsql' STABLE; + +CREATE OR REPLACE FUNCTION get_rules_for_tenant(device_row device, tenant integer, hasura_session json) +RETURNS SETOF rule AS $$ + DECLARE + t_id integer; + BEGIN + t_id := (hasura_session ->> 'x-hasura-tenant-id')::integer; +-- SELECT INTO i_dev_id dev_id FROM device; + IF t_id IS NULL THEN + RAISE EXCEPTION 'No tenant id found in hasura session'; --> only happens when using auth via x-hasura-admin-secret (no tenant id is set) + ELSIF t_id != 1 AND t_id != tenant THEN + RAISE EXCEPTION 'A non-tenant-0 user was trying to generate a report for another tenant.'; + ELSIF tenant = 1 THEN + RAISE EXCEPTION 'Tenant0 cannot be simulated.'; + ELSE + IF rulebase_fully_visible_to_tenant(device_row.dev_id, tenant) + THEN + RETURN QUERY SELECT * FROM rule WHERE dev_id=device_row.dev_id; + ELSE + RETURN QUERY + SELECT r.* FROM rule r + LEFT JOIN rule_from rf ON (r.rule_id=rf.rule_id) + LEFT JOIN objgrp_flat rf_of ON (rf.obj_id=rf_of.objgrp_flat_id) + LEFT JOIN object rf_o ON (rf_of.objgrp_flat_member_id=rf_o.obj_id) + LEFT JOIN tenant_network ON + (ip_ranges_overlap(rf_o.obj_ip, rf_o.obj_ip_end, tenant_net_ip, tenant_net_ip_end, rf.negated != r.rule_src_neg)) + WHERE r.dev_id = device_row.dev_id AND tenant_id = tenant AND rule_head_text IS NULL + UNION + SELECT r.* FROM rule r + LEFT JOIN rule_to rt ON (r.rule_id=rt.rule_id) + LEFT JOIN objgrp_flat rt_of ON (rt.obj_id=rt_of.objgrp_flat_id) + LEFT JOIN object rt_o ON (rt_of.objgrp_flat_member_id=rt_o.obj_id) + LEFT JOIN tenant_network ON + (ip_ranges_overlap(rt_o.obj_ip, rt_o.obj_ip_end, tenant_net_ip, tenant_net_ip_end, rt.negated != r.rule_dst_neg)) + WHERE r.dev_id = device_row.dev_id AND tenant_id = tenant AND rule_head_text IS NULL + ORDER BY rule_name; + END IF; + END IF; + END; +$$ LANGUAGE 'plpgsql' STABLE; + +CREATE OR REPLACE FUNCTION get_rule_froms_for_tenant(rule rule, tenant integer, hasura_session json) +RETURNS SETOF rule_from AS $$ + DECLARE + t_id integer; + BEGIN + t_id := (hasura_session ->> 'x-hasura-tenant-id')::integer; + + IF t_id IS NULL THEN + RAISE EXCEPTION 'No tenant id found in hasura session'; --> only happens when using auth via x-hasura-admin-secret (no tenant id is set) + ELSIF t_id != 1 AND t_id != tenant THEN + RAISE EXCEPTION 'A non-tenant-0 user was trying to generate a report for another tenant.'; + ELSIF tenant = 1 THEN + RAISE EXCEPTION 'Tenant0 cannot be simulated.'; + ELSE + IF rulebase_fully_visible_to_tenant(rule.dev_id, tenant) + THEN + RETURN QUERY SELECT rf.* FROM rule_from rf WHERE rule_id = rule.rule_id; + ELSIF EXISTS ( + SELECT rt.obj_id FROM rule_to rt + LEFT JOIN objgrp_flat ON (rt.obj_id=objgrp_flat.objgrp_flat_id) + LEFT JOIN object ON (objgrp_flat.objgrp_flat_member_id=object.obj_id) + LEFT JOIN tenant_network ON + (ip_ranges_overlap(obj_ip, obj_ip_end, tenant_net_ip, tenant_net_ip_end, rt.negated != rule.rule_dst_neg)) + WHERE rt.rule_id = rule.rule_id AND tenant_id = tenant + ) THEN + RETURN QUERY + SELECT rf.* FROM rule_from rf WHERE rule_id = rule.rule_id; + ELSE + RETURN QUERY + SELECT DISTINCT rf.* FROM rule_from rf + LEFT JOIN objgrp_flat ON (rf.obj_id=objgrp_flat.objgrp_flat_id) + LEFT JOIN object ON (objgrp_flat.objgrp_flat_member_id=object.obj_id) + LEFT JOIN tenant_network ON + (ip_ranges_overlap(obj_ip, obj_ip_end, tenant_net_ip, tenant_net_ip_end, rf.negated != rule.rule_src_neg)) + WHERE rule_id = rule.rule_id AND tenant_id = tenant; + END IF; + END IF; + END; +$$ LANGUAGE 'plpgsql' STABLE; + +CREATE OR REPLACE FUNCTION public.get_rule_tos_for_tenant(rule rule, tenant integer, hasura_session json) + RETURNS SETOF rule_to + LANGUAGE plpgsql + STABLE +AS $function$ + DECLARE + t_id integer; + BEGIN + t_id := (hasura_session ->> 'x-hasura-tenant-id')::integer; + + IF t_id IS NULL THEN + RAISE EXCEPTION 'No tenant id found in hasura session'; --> only happens when using auth via x-hasura-admin-secret (no tenant id is set) + ELSIF t_id != 1 AND t_id != tenant THEN + RAISE EXCEPTION 'A non-tenant-0 user was trying to generate a report for another tenant.'; + ELSIF tenant = 1 THEN + RAISE EXCEPTION 'Tenant0 cannot be simulated.'; + ELSE + IF rulebase_fully_visible_to_tenant(rule.dev_id, tenant) + THEN + RETURN QUERY SELECT rt.* FROM rule_to rt WHERE rule_id = rule.rule_id; + ELSIF EXISTS ( + SELECT rf.obj_id FROM rule_from rf + LEFT JOIN objgrp_flat ON (rf.obj_id=objgrp_flat.objgrp_flat_id) + LEFT JOIN object ON (objgrp_flat.objgrp_flat_member_id=object.obj_id) + LEFT JOIN tenant_network ON + (ip_ranges_overlap(obj_ip, obj_ip_end, tenant_net_ip, tenant_net_ip_end, rf.negated != rule.rule_src_neg)) + WHERE rf.rule_id = rule.rule_id AND tenant_id = tenant + ) THEN + RETURN QUERY + SELECT rt.* FROM rule_to rt WHERE rule_id = rule.rule_id; + ELSE + RETURN QUERY + SELECT DISTINCT rt.* FROM rule_to rt + LEFT JOIN objgrp_flat ON (rt.obj_id=objgrp_flat.objgrp_flat_id) + LEFT JOIN object ON (objgrp_flat.objgrp_flat_member_id=object.obj_id) + LEFT JOIN tenant_network ON + (ip_ranges_overlap(obj_ip, obj_ip_end, tenant_net_ip, tenant_net_ip_end, rt.negated != rule.rule_dst_neg)) + WHERE rule_id = rule.rule_id AND tenant_id = tenant; + END IF; + END IF; + END; +$function$; + + +CREATE OR REPLACE FUNCTION get_rules_for_owner(device_row device, ownerid integer) +RETURNS SETOF rule AS $$ + BEGIN + RETURN QUERY + SELECT r.* FROM rule r + LEFT JOIN rule_from rf ON (r.rule_id=rf.rule_id) + LEFT JOIN objgrp_flat rf_of ON (rf.obj_id=rf_of.objgrp_flat_id) + LEFT JOIN object rf_o ON (rf_of.objgrp_flat_member_id=rf_o.obj_id) + LEFT JOIN owner_network ON + (ip_ranges_overlap(rf_o.obj_ip, rf_o.obj_ip_end, ip, ip_end, rf.negated != r.rule_src_neg)) + WHERE r.dev_id = device_row.dev_id AND owner_id = ownerid AND rule_head_text IS NULL + UNION + SELECT r.* FROM rule r + LEFT JOIN rule_to rt ON (r.rule_id=rt.rule_id) + LEFT JOIN objgrp_flat rt_of ON (rt.obj_id=rt_of.objgrp_flat_id) + LEFT JOIN object rt_o ON (rt_of.objgrp_flat_member_id=rt_o.obj_id) + LEFT JOIN owner_network ON + (ip_ranges_overlap(rt_o.obj_ip, rt_o.obj_ip_end, ip, ip_end, rt.negated != r.rule_dst_neg)) + WHERE r.dev_id = device_row.dev_id AND owner_id = ownerid AND rule_head_text IS NULL + ORDER BY rule_name; + END; +$$ LANGUAGE 'plpgsql' STABLE; + +DROP FUNCTION IF EXISTS public.get_rulebase_for_owner; +DROP VIEW IF EXISTS public.rule_api; +CREATE OR REPLACE VIEW public.rule_api AS + SELECT + rule_id, last_change_admin, rule_name, mgm_id, parent_rule_id, parent_rule_type, active, rule_num, rule_num_numeric, + rule_ruleid, rule_uid, rule_disabled, rule_src_neg, rule_dst_neg, rule_svc_neg, action_id, track_id, + rule_src, rule_dst, rule_svc, rule_src_refs, rule_dst_refs, rule_svc_refs, rule_from_zone, rule_to_zone, + rule_action, rule_track, rule_installon, rule_time, rule_comment, rule_head_text, rule_implied, rule_create, rule_last_seen, + dev_id, rule_custom_fields, access_rule, nat_rule, xlate_rule, is_global, rulebase_id, removed + FROM rule; + +CREATE OR REPLACE FUNCTION public.get_rulebase_for_owner( + rulebase_row rulebase, + ownerid integer +) +RETURNS SETOF rule_api +LANGUAGE plpgsql +STABLE +AS $function$ +BEGIN + RETURN QUERY + SELECT * + FROM ( + WITH src_rules AS ( + SELECT r.rule_id, r.rule_src_neg, r.rulebase_id, rf_o.obj_ip, rf_o.obj_ip_end, rf.negated + FROM rule_api r + LEFT JOIN rule_from rf ON r.rule_id = rf.rule_id + LEFT JOIN objgrp_flat rf_of ON rf.obj_id = rf_of.objgrp_flat_id + LEFT JOIN object rf_o ON rf_of.objgrp_flat_member_id = rf_o.obj_id + WHERE r.rulebase_id = rulebase_row.id + AND r.active = true + AND rule_head_text IS NULL + ), + dst_rules AS ( + SELECT r.rule_id, r.rule_dst_neg, r.rulebase_id, rt_o.obj_ip, rt_o.obj_ip_end, rt.negated + FROM rule_api r + LEFT JOIN rule_to rt ON r.rule_id = rt.rule_id + LEFT JOIN objgrp_flat rt_of ON rt.obj_id = rt_of.objgrp_flat_id + LEFT JOIN object rt_o ON rt_of.objgrp_flat_member_id = rt_o.obj_id + WHERE r.rulebase_id = rulebase_row.id + AND r.active = true + AND rule_head_text IS NULL + ) + SELECT r.* + FROM src_rules s + LEFT JOIN owner_network onw ON ip_ranges_overlap(s.obj_ip, s.obj_ip_end, ip, ip_end, s.negated != s.rule_src_neg) + JOIN rule_api r ON r.rule_id = s.rule_id + WHERE onw.owner_id = ownerid + UNION + SELECT r.* + FROM dst_rules d + LEFT JOIN owner_network onw ON ip_ranges_overlap(d.obj_ip, d.obj_ip_end, ip, ip_end, d.negated != d.rule_dst_neg) + JOIN rule_api r ON r.rule_id = d.rule_id + WHERE onw.owner_id = ownerid + ) AS combined + ORDER BY rule_name ASC; +END; +$function$; diff --git a/roles/database/files/sql/idempotent/fworch-backup-grants.sql b/roles/database/files/sql/idempotent/fworch-backup-grants.sql new file mode 100644 index 0000000000..bff8cddaf4 --- /dev/null +++ b/roles/database/files/sql/idempotent/fworch-backup-grants.sql @@ -0,0 +1,16 @@ + +-- settings backup permissions +DO $$ +DECLARE + SchemaName text; +BEGIN + FOREACH SchemaName IN ARRAY ARRAY['public', 'request', 'compliance', 'modelling'] + LOOP + EXECUTE format('GRANT USAGE ON SCHEMA %I TO "dbbackupusers";', SchemaName); + EXECUTE format('GRANT SELECT ON ALL SEQUENCES IN SCHEMA %I TO "dbbackupusers";', SchemaName); + EXECUTE format('GRANT SELECT ON ALL TABLES IN SCHEMA %I TO "dbbackupusers";', SchemaName); + EXECUTE format('ALTER DEFAULT PRIVILEGES IN SCHEMA %I GRANT SELECT ON SEQUENCES TO "dbbackupusers";', SchemaName); + EXECUTE format('ALTER DEFAULT PRIVILEGES IN SCHEMA %I GRANT SELECT ON TABLES TO "dbbackupusers";', SchemaName); + END LOOP; +END +$$; \ No newline at end of file diff --git a/roles/database/files/sql/idempotent/fworch-basic-procs.sql b/roles/database/files/sql/idempotent/fworch-basic-procs.sql deleted file mode 100644 index 14408209a7..0000000000 --- a/roles/database/files/sql/idempotent/fworch-basic-procs.sql +++ /dev/null @@ -1,572 +0,0 @@ --------------------------------------------------------------------------------------- --- BASIC FUNCTIONS ----------------------------------------------------- --- FUNCTION: is_numeric --- Zweck: ist ein String eine reine Zahl? --- Parameter: VARCHAR --- RETURNS: BOOLEAN --- -CREATE OR REPLACE FUNCTION is_numeric (varchar) - RETURNS boolean - AS $$ -DECLARE - input ALIAS FOR $1; -BEGIN - RETURN (input ~ '[0-9]'); -END; -$$ -LANGUAGE plpgsql; - ----------------------------------------------------- --- FUNCTION: are_equal --- Zweck: sind zwei Werte gleich (oder beide NULL)? --- Parameter: 2x Boolean oder 2x varchar oder ... --- RETURNS: BOOLEAN --- -CREATE OR REPLACE FUNCTION are_equal (boolean, boolean) - RETURNS boolean - AS $$ -BEGIN - IF (($1 IS NULL AND $2 IS NULL) OR $1 = $2) THEN - RETURN TRUE; - ELSE - RETURN FALSE; - END IF; -END; -$$ -LANGUAGE plpgsql; - -CREATE OR REPLACE FUNCTION are_equal (varchar, varchar) - RETURNS boolean - AS $$ -DECLARE - v_str varchar; -BEGIN - IF (($1 IS NULL AND $2 IS NULL) OR $1 = $2) THEN - RETURN TRUE; - ELSE - RETURN FALSE; - END IF; -END; -$$ -LANGUAGE plpgsql; - -CREATE OR REPLACE FUNCTION are_equal (text, text) - RETURNS boolean - AS $$ -DECLARE - v_str varchar; -BEGIN - IF (($1 IS NULL AND $2 IS NULL) OR $1 = $2) THEN - RETURN TRUE; - ELSE - RETURN FALSE; - END IF; -END; -$$ -LANGUAGE plpgsql; - -CREATE OR REPLACE FUNCTION are_equal (cidr, cidr) - RETURNS boolean - AS $$ -DECLARE - v_str varchar; -BEGIN - IF (($1 IS NULL AND $2 IS NULL) OR $1 = $2) THEN - RETURN TRUE; - ELSE - RETURN FALSE; - END IF; -END; -$$ -LANGUAGE plpgsql; - -CREATE OR REPLACE FUNCTION are_equal (integer, integer) - RETURNS boolean - AS $$ -BEGIN - IF (($1 IS NULL AND $2 IS NULL) OR $1 = $2) THEN - RETURN TRUE; - ELSE - RETURN FALSE; - END IF; -END; -$$ -LANGUAGE plpgsql; - -CREATE OR REPLACE FUNCTION are_equal (bigint, bigint) - RETURNS boolean - AS $$ -BEGIN - IF (($1 IS NULL AND $2 IS NULL) OR ((NOT $1 IS NULL AND NOT $2 IS NULL) AND $1 = $2)) THEN - RETURN TRUE; - ELSE - RETURN FALSE; - END IF; -END; -$$ -LANGUAGE plpgsql; - -CREATE OR REPLACE FUNCTION are_equal (smallint, smallint) - RETURNS boolean - AS $$ -BEGIN - -- RAISE DEBUG 'are_equal_smallint 1, p1=%, p2=%', $1, $1; - IF (($1 IS NULL AND $2 IS NULL) OR ((NOT $1 IS NULL AND NOT $2 IS NULL) AND $1 = $2)) THEN - RETURN TRUE; - ELSE - RETURN FALSE; - END IF; -END; -$$ -LANGUAGE plpgsql; - ----------------------------------------------------- --- FUNCTION: is_svc_group --- Zweck: liefert TRUE, wenn service eine Gruppe ist --- Parameter1: svc_id --- RETURNS: BOOLEAN --- -CREATE OR REPLACE FUNCTION is_svc_group (bigint) - RETURNS boolean - AS $$ -DECLARE - i_svc_id ALIAS FOR $1; - r_svc RECORD; - -- zu pruefendes Objekt -BEGIN - SELECT - INTO r_svc svc_typ_name - FROM - service - LEFT JOIN stm_svc_typ ON service.svc_typ_id = stm_svc_typ.svc_typ_id -WHERE - service.svc_id = i_svc_id; - IF r_svc.svc_typ_name = 'group' THEN - -- Gruppe - RETURN TRUE; - ELSE - -- keine Gruppe - RETURN FALSE; - END IF; -END; -$$ -LANGUAGE plpgsql; - ----------------------------------------------------- --- FUNCTION: is_obj_group --- Zweck: liefert TRUE, wenn objekt eine Gruppe ist --- Parameter1: obj_id --- RETURNS: BOOLEAN --- -CREATE OR REPLACE FUNCTION is_obj_group (bigint) - RETURNS boolean - AS $$ -DECLARE - i_obj_id ALIAS FOR $1; - r_obj RECORD; - -- zu pruefendes Objekt -BEGIN - SELECT - INTO r_obj obj_typ_name - FROM - object - LEFT JOIN stm_obj_typ ON object.obj_typ_id = stm_obj_typ.obj_typ_id -WHERE - object.obj_id = i_obj_id; - IF r_obj.obj_typ_name = 'group' THEN - -- Gruppe - RETURN TRUE; - ELSE - -- keine Gruppe - RETURN FALSE; - END IF; -END; -$$ -LANGUAGE plpgsql; - ----------------------------------------------------- --- FUNCTION: is_user_group --- Zweck: liefert TRUE, wenn user eine Gruppe ist --- Parameter1: user_id --- RETURNS: BOOLEAN --- -CREATE OR REPLACE FUNCTION is_user_group (bigint) - RETURNS boolean - AS $$ -DECLARE - i_user_id ALIAS FOR $1; - r_user RECORD; - -- zu pruefendes Objekt -BEGIN - SELECT - INTO r_user usr_typ_name - FROM - usr - LEFT JOIN stm_usr_typ ON usr.usr_typ_id = stm_usr_typ.usr_typ_id -WHERE - usr.user_id = i_user_id; - IF r_user.usr_typ_name = 'group' THEN - -- Gruppe - RETURN TRUE; - ELSE - -- keine Gruppe - RETURN FALSE; - END IF; -END; -$$ -LANGUAGE plpgsql; - ----------------------------------------------------- --- FUNCTION: get_admin_id_from_name --- Zweck: liefert zu einem admin-namen die zugehoerige uiuser_id zurueck --- Parameter: name des admins --- RETURNS: INTEGER uiuser_id --- -CREATE OR REPLACE FUNCTION get_admin_id_from_name (varchar) - RETURNS integer - AS $$ -DECLARE - v_admin_name ALIAS FOR $1; - r_admin RECORD; -BEGIN - IF v_admin_name IS NULL OR v_admin_name = '' THEN - RETURN NULL; - END IF; - SELECT - INTO r_admin * - FROM - uiuser - WHERE - uiuser_username = v_admin_name; - IF NOT FOUND THEN - IF v_admin_name <> 'CheckPoint' AND v_admin_name <> 'Upgrade Process' AND v_admin_name <> 'Check Point SmartCenter Server Update Process' THEN - PERFORM - error_handling ('INFO_ADMIN_NOT_FOUND', v_admin_name); - END IF; - RETURN NULL; - END IF; - RETURN r_admin.uiuser_id; -END; -$$ -LANGUAGE plpgsql; - ----------------------------------------------------- --- FUNCTION: get_dev_typ_id --- Zweck: liefert die dev_typ_id zu einem device-name zurueck --- Parameter: device-name VARCHAR --- RETURNS: INTEGER dev_typ_id des uebergebenen devices --- -CREATE OR REPLACE FUNCTION get_dev_typ_id (varchar) - RETURNS integer - AS $$ -DECLARE - devicename ALIAS FOR $1; - dev RECORD; -BEGIN - SELECT - INTO dev dev_typ_id - FROM - device - WHERE - dev_name = devicename; - IF NOT FOUND THEN - -- TODO: Fehlerbehandlung - PERFORM - error_handling ('ERR_DEV_NOT_FOUND', devicename); - END IF; - RETURN dev.dev_typ_id; -END; -$$ -LANGUAGE plpgsql; - ----------------------------------------------------- --- FUNCTION: error_handling (einmal mit und einmal ohne variablen Anteil) --- Zweck: gibt Fehlermeldung aus --- Parameter: error-string (id), [wert einer variablen] --- RETURNS: error string --- -CREATE OR REPLACE FUNCTION error_handling (varchar) - RETURNS varchar - AS $$ -DECLARE - errid ALIAS FOR $1; -BEGIN - RETURN error_handling (errid, ''); -END; -$$ -LANGUAGE plpgsql; - -CREATE OR REPLACE FUNCTION error_handling (varchar, varchar) - RETURNS varchar - AS $$ -DECLARE - errid ALIAS FOR $1; - var_output_string ALIAS FOR $2; - err RECORD; - lang RECORD; - err_txt text; - err_prefix varchar; -BEGIN - err_txt := ''; - SELECT - INTO err * - FROM - error - WHERE - error_id = errid; - IF NOT FOUND THEN - RAISE EXCEPTION 'errorid not found %', errid; - END IF; - SELECT - INTO lang config_value - FROM - config - WHERE - config_key = 'DefaultLanguage'; - IF NOT FOUND THEN - RAISE EXCEPTION 'config not found, %', errid; - END IF; - IF lang.config_value = 'German' THEN - err_txt := err.error_txt_ger; - IF err.error_lvl = 1 THEN - err_prefix := 'FEHLER: '; - ELSIF err.error_lvl = 2 THEN - err_prefix := 'WARNUNG: '; - ELSIF err.error_lvl = 3 THEN - err_prefix := 'WARNUNG: '; - ELSIF err.error_lvl = 4 THEN - err_prefix := 'INFO: '; - ELSE - RAISE EXCEPTION 'Unbekannte Fehlerstufe %', err.error_lvl; - END IF; - ELSE - err_txt := err.error_txt_eng; - IF err.error_lvl = 1 THEN - err_prefix := 'ERROR: '; - ELSIF err.error_lvl = 2 THEN - err_prefix := 'WARNING: '; - ELSIF err.error_lvl = 3 THEN - err_prefix := 'WARNING: '; - ELSIF err.error_lvl = 4 THEN - err_prefix := 'INFO: '; - ELSE - RAISE EXCEPTION 'Unbekannte Fehlerstufe %', err.error_lvl; - END IF; - END IF; - err_prefix := err_prefix || errid || ': '; - IF var_output_string <> '' THEN - err_txt := err_txt || ': ' || var_output_string; - END IF; - err_txt := err_prefix || err_txt; - -- INSERT INTO error_log (error_id, error_txt) - -- VALUES (errid, err_txt); - IF err.error_lvl = 1 THEN - RAISE DEBUG 'sorry, encountered fatal error: %', err_txt; - RAISE EXCEPTION '%', err_txt; - ELSIF err.error_lvl = 2 THEN - RAISE NOTICE '%', err_txt; - ELSIF err.error_lvl = 3 THEN - RAISE NOTICE '%', err_txt; - ELSIF err.error_lvl = 4 THEN - RAISE DEBUG '%', err_txt; - -- NULL; - ELSE - RAISE EXCEPTION 'unknown errorlevel %', err.error_lvl; - END IF; - RETURN err_txt; -END; -$$ -LANGUAGE plpgsql; - ---------------------------------------------------------------------------------------- --- entfernt alle Whitespaces vom Anfang u. Ende eine Strings -CREATE OR REPLACE FUNCTION remove_spaces (varchar) - RETURNS varchar - AS $$ -DECLARE - s ALIAS FOR $1; - -- res VARCHAR; - -- test VARCHAR; - -- left VARCHAR; - -- right VARCHAR; - -- pos integer; -BEGIN - -- res := s; - -- test := substring(s, '^.*?([' || E'\t' || ' ]).*?$'); - -- if test IS NOT NULL AND char_length(test)>0 THEN - -- left := substring(s, '^(.*?)[ ' || E'\t' || '].*?$'); - -- right := substring(s, '^.*?[ ' || E'\t' || '](.*?)$'); - -- res := left || remove_spaces(right); - -- END IF; - RETURN btrim(s); -END; -$$ -LANGUAGE plpgsql; - ---------------------------------------------------------------------------------------- --- Entfernt Tabs und Leerzeichen am Anfang und Ende des Strings -CREATE OR REPLACE FUNCTION del_surrounding_spaces (varchar) - RETURNS varchar - AS $$ -DECLARE - s ALIAS FOR $1; -BEGIN - -- return substring(s, '[ \t]*(.*?)[ \t]*'); - RETURN substring(s, '[ ' || E'\t' || ']*(.*?)[ ' || E'\t' || ']*'); -END; -$$ -LANGUAGE plpgsql; - ---------------------------------------------------------------------------------------- --- instr functions that mimic Oracle's counterpart --- Syntax: instr(string1, string2, [n], [m]) where [] denotes optional parameters. --- --- Searches string1 beginning at the nth character for the mth occurrence --- of string2. If n is negative, search backwards. If m is not passed, --- assume 1 (search starts at first character). --- -CREATE OR REPLACE FUNCTION instr (varchar, varchar) - RETURNS integer - AS $$ -DECLARE - pos integer; -BEGIN - pos := instr ($1, $2, 1); - RETURN pos; -END; -$$ -LANGUAGE plpgsql; - -CREATE OR REPLACE FUNCTION instr (varchar, varchar, integer) - RETURNS integer - AS $$ -DECLARE - string ALIAS FOR $1; - string_to_search ALIAS FOR $2; - beg_index ALIAS FOR $3; - pos integer NOT NULL DEFAULT 0; - temp_str varchar; - beg integer; - length integer; - ss_length integer; -BEGIN - IF beg_index > 0 THEN - temp_str := substring(string FROM beg_index); - pos := position(string_to_search IN temp_str); - IF pos = 0 THEN - RETURN 0; - ELSE - RETURN pos + beg_index - 1; - END IF; - ELSE - ss_length := char_length(string_to_search); - length := char_length(string); - beg := length + beg_index - ss_length + 2; - WHILE beg > 0 LOOP - temp_str := substring(string FROM beg FOR ss_length); - pos := position(string_to_search IN temp_str); - IF pos > 0 THEN - RETURN beg; - END IF; - beg := beg - 1; - END LOOP; - RETURN 0; - END IF; -END; -$$ -LANGUAGE plpgsql; - -CREATE OR REPLACE FUNCTION instr (varchar, varchar, integer, integer) - RETURNS integer - AS $$ -DECLARE - string ALIAS FOR $1; - string_to_search ALIAS FOR $2; - beg_index ALIAS FOR $3; - occur_index ALIAS FOR $4; - pos integer NOT NULL DEFAULT 0; - occur_number integer NOT NULL DEFAULT 0; - temp_str varchar; - beg integer; - i integer; - length integer; - ss_length integer; -BEGIN - IF beg_index > 0 THEN - beg := beg_index; - temp_str := substring(string FROM beg_index); - FOR i IN 1..occur_index LOOP - pos := position(string_to_search IN temp_str); - IF i = 1 THEN - beg := beg + pos - 1; - ELSE - beg := beg + pos; - END IF; - temp_str := substring(string FROM beg + 1); - END LOOP; - IF pos = 0 THEN - RETURN 0; - ELSE - RETURN beg; - END IF; - ELSE - ss_length := char_length(string_to_search); - length := char_length(string); - beg := length + beg_index - ss_length + 2; - WHILE beg > 0 LOOP - temp_str := substring(string FROM beg FOR ss_length); - pos := position(string_to_search IN temp_str); - IF pos > 0 THEN - occur_number := occur_number + 1; - IF occur_number = occur_index THEN - RETURN beg; - END IF; - END IF; - beg := beg - 1; - END LOOP; - RETURN 0; - END IF; -END; -$$ -LANGUAGE plpgsql; - - --- CREATE OR REPLACE FUNCTION add_data_issue(varchar,int,timestamp,BIGINT,varchar,varchar,varchar,bigint,int,int,varchar,varchar,varchar) RETURNS VOID AS $$ --- DECLARE --- v_source ALIAS FOR $1; --- i_severity ALIAS FOR $2; --- t_timestamp ALIAS FOR $3; --- i_current_import_id ALIAS FOR $4; --- v_obj_name ALIAS FOR $5; --- v_obj_uid ALIAS FOR $6; --- v_rule_uid ALIAS FOR $7; --- i_rule_id ALIAS FOR $8; --- i_mgm_id ALIAS FOR $9; --- i_dev_id ALIAS FOR $10; --- v_obj_type ALIAS FOR $11; --- v_suspected_cause ALIAS FOR $12; --- v_description ALIAS FOR $13; --- v_log_string VARCHAR; --- BEGIN --- INSERT INTO log_data_issue ( --- source, severity, issue_timestamp, import_id, object_name, object_uid, rule_uid, --- rule_id, issue_mgm_id, issue_dev_id, object_type, suspected_cause, description ) --- VALUES ( --- v_source, i_severity, t_timestamp, i_current_import_id, v_obj_name, v_obj_uid, v_rule_uid, --- i_rule_id, i_mgm_id, i_dev_id, v_obj_type, v_suspected_cause, v_description); --- RETURN; --- v_log_string := 'src=' || v_source || ', sev=' || v_severity; --- IF t_timestamp IS NOT NULL THEN --- v_log_string := v_log_string || ', time=' || t_timestamp; --- END IF; --- IF i_current_import_id IS NOT NULL THEN --- v_log_string := v_log_string || ', import_id=' || CAST(i_current_import_id AS VARCHAR); --- END IF; --- IF v_obj_name IS NOT NULL THEN --- v_log_string := v_log_string || ', object_name=' || v_obj_name; --- END IF; --- -- todo: add more issue information --- RAISE INFO '%', v_log_string; -- send the log to syslog as well --- END; --- $$ LANGUAGE plpgsql; diff --git a/roles/database/files/sql/idempotent/fworch-encryption.sql b/roles/database/files/sql/idempotent/fworch-encryption.sql new file mode 100644 index 0000000000..cd1e82d88f --- /dev/null +++ b/roles/database/files/sql/idempotent/fworch-encryption.sql @@ -0,0 +1,163 @@ +------------------------------------- +-- credentials/secrets encryption +-- the following functions are needed for the upgrade and during installation (to encrypt the ldap passwords in ldap_connection table) +-- for existing installations all encrytion/decryption is done in the UI or in the MW server (for ldap binding) + +CREATE EXTENSION IF NOT EXISTS pgcrypto; + +CREATE OR REPLACE FUNCTION custom_aes_cbc_encrypt_base64(plaintext TEXT, key TEXT) RETURNS TEXT AS $$ +DECLARE + iv BYTEA; + encrypted_text BYTEA; +BEGIN + -- Generate a random IV (Initialization Vector) + iv := gen_random_bytes(16); -- IV size for AES is typically 16 bytes + + -- Perform AES CBC encryption + encrypted_text := encrypt_iv(plaintext::BYTEA, key::BYTEA, iv, 'aes-cbc/pad:pkcs'); + + -- Combine IV and encrypted text and encode them to base64 + RETURN encode(iv || encrypted_text, 'base64'); +END; +$$ LANGUAGE plpgsql; + +CREATE OR REPLACE FUNCTION custom_aes_cbc_decrypt_base64(ciphertext TEXT, key TEXT) RETURNS TEXT AS $$ +DECLARE + iv BYTEA; + encrypted_text BYTEA; + decrypted_text BYTEA; +BEGIN + -- Decode the base64 string into IV and encrypted text + encrypted_text := decode(ciphertext, 'base64'); + + -- Extract IV from the encrypted text + iv := substring(encrypted_text from 1 for 16); + + -- Extract encrypted text without IV + encrypted_text := substring(encrypted_text from 17); + + -- Perform AES CBC decryption + decrypted_text := decrypt_iv(encrypted_text, key::BYTEA, iv, 'aes-cbc/pad:pkcs'); + + -- Return the decrypted text + RETURN convert_from(decrypted_text, 'UTF8'); +END; +$$ LANGUAGE plpgsql; + +CREATE OR REPLACE FUNCTION encryptText (plaintext_in text, key_in text) RETURNS text AS $$ +DECLARE + t_cyphertext TEXT; + t_plaintext TEXT; + t_crypt_algo TEXT := 'cipher-algo=aes256'; + t_coding_algo TEXT := 'base64'; + -- ba_iv bytea; +BEGIN + -- check if plaintext is actually ciphertext + BEGIN + SELECT into t_plaintext custom_aes_cbc_decrypt_base64(plaintext_in, key_in); + -- if we get here without error, the plaintext passed in was actually already encrypted + RETURN plaintext_in; + EXCEPTION WHEN OTHERS THEN + RETURN custom_aes_cbc_encrypt_base64(plaintext_in, key_in); + END; +END; +$$ LANGUAGE plpgsql VOLATILE; + +CREATE OR REPLACE FUNCTION decryptText (cyphertext_in text, key text) RETURNS text AS $$ +DECLARE + t_plaintext TEXT; + t_crypt_algo TEXT := 'cipher-algo=aes-256-cbc/pad:pkcs'; + t_coding_algo TEXT := 'base64'; +BEGIN + BEGIN + SELECT INTO t_plaintext custom_aes_cbc_decrypt_base64(cyphertext_in, key); + RETURN t_plaintext; + EXCEPTION WHEN OTHERS THEN + -- decryption did not work out, so assuming that text was not encrypted + RAISE EXCEPTION 'decryption with the given key failed!'; + END; + +END; +$$ LANGUAGE plpgsql VOLATILE; + +CREATE OR REPLACE FUNCTION encryptPasswords (key text) RETURNS VOID AS $$ +DECLARE + r_cred RECORD; + t_encrypted TEXT; +BEGIN + -- encrypt pwds in import_credential table + FOR r_cred IN + SELECT id, secret FROM import_credential + LOOP + SELECT INTO t_encrypted * FROM encryptText(r_cred.secret, key); + UPDATE import_credential SET secret=t_encrypted WHERE id=r_cred.id; + END LOOP; + + --encrypt pwds in ldap_connection table + FOR r_cred IN + SELECT ldap_search_user_pwd, ldap_write_user_pwd, ldap_connection_id FROM ldap_connection + LOOP + SELECT INTO t_encrypted * FROM encryptText(r_cred.ldap_search_user_pwd, key); + UPDATE ldap_connection SET ldap_search_user_pwd=t_encrypted WHERE ldap_connection_id=r_cred.ldap_connection_id; + SELECT INTO t_encrypted * FROM encryptText(r_cred.ldap_write_user_pwd, key); + UPDATE ldap_connection SET ldap_write_user_pwd=t_encrypted WHERE ldap_connection_id=r_cred.ldap_connection_id; + END LOOP; + + -- encrypt smtp email user pwds in config table + SELECT INTO r_cred config_value FROM config WHERE config_key='emailPassword'; + SELECT INTO t_encrypted * FROM encryptText(r_cred.config_value, key); + UPDATE config SET config_value=t_encrypted WHERE config_key='emailPassword'; + + RETURN; +END; +$$ LANGUAGE plpgsql; + +-- get encryption key from filesystem +CREATE OR REPLACE FUNCTION getMainKey() RETURNS TEXT AS $$ +DECLARE + t_key TEXT; +BEGIN + CREATE TEMPORARY TABLE temp_main_key (key text); + COPY temp_main_key FROM '/etc/fworch/secrets/main_key' CSV DELIMITER ','; + SELECT INTO t_key * FROM temp_main_key; + -- RAISE NOTICE 'main key: "%"', t_key; + DROP TABLE temp_main_key; + RETURN t_key; +END; +$$ LANGUAGE plpgsql; + +-- finally do the encryption in the db tables +SELECT * FROM encryptPasswords (getMainKey()); + +-- function for adding local ldap data with encrypted pwds into ldap_connection +CREATE OR REPLACE FUNCTION insertLocalLdapWithEncryptedPasswords( + serverName TEXT, + port INTEGER, + userSearchPath TEXT, + roleSearchPath TEXT, + groupSearchPath TEXT, + groupWritePath TEXT, + tenantLevel INTEGER, + searchUser TEXT, + searchUserPwd TEXT, + writeUser TEXT, + writeUserPwd TEXT, + ldapType INTEGER +) RETURNS VOID AS $$ +DECLARE + t_key TEXT; + t_encryptedReadPwd TEXT; + t_encryptedWritePwd TEXT; +BEGIN + IF NOT EXISTS (SELECT * FROM ldap_connection WHERE ldap_server = serverName) + THEN + SELECT INTO t_key * FROM getMainKey(); + SELECT INTO t_encryptedReadPwd * FROM encryptText(searchUserPwd, t_key); + SELECT INTO t_encryptedWritePwd * FROM encryptText(writeUserPwd, t_key); + INSERT INTO ldap_connection + (ldap_server, ldap_port, ldap_searchpath_for_users, ldap_searchpath_for_roles, ldap_searchpath_for_groups, ldap_writepath_for_groups, + ldap_tenant_level, ldap_search_user, ldap_search_user_pwd, ldap_write_user, ldap_write_user_pwd, ldap_type) + VALUES (serverName, port, userSearchPath, roleSearchPath, groupSearchPath, groupWritePath, tenantLevel, searchUser, t_encryptedReadPwd, writeUser, t_encryptedWritePwd, ldapType); + END IF; +END; +$$ LANGUAGE plpgsql; diff --git a/roles/database/files/sql/idempotent/fworch-grants.sql b/roles/database/files/sql/idempotent/fworch-grants.sql deleted file mode 100644 index bb003757e7..0000000000 --- a/roles/database/files/sql/idempotent/fworch-grants.sql +++ /dev/null @@ -1,97 +0,0 @@ - --- settings backup permissions -GRANT USAGE ON SCHEMA public TO dbbackupusers; -GRANT SELECT ON ALL SEQUENCES IN SCHEMA public TO group "dbbackupusers"; -Grant select on ALL TABLES in SCHEMA public to group dbbackupusers; -ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT SELECT ON SEQUENCES TO group "dbbackupusers"; -ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT SELECT ON TABLES TO group dbbackupusers; - -GRANT USAGE ON SCHEMA request TO dbbackupusers; -GRANT SELECT ON ALL SEQUENCES IN SCHEMA request TO group "dbbackupusers"; -Grant select on ALL TABLES in SCHEMA request to group dbbackupusers; -ALTER DEFAULT PRIVILEGES IN SCHEMA request GRANT SELECT ON SEQUENCES TO group "dbbackupusers"; -ALTER DEFAULT PRIVILEGES IN SCHEMA request GRANT SELECT ON TABLES TO group dbbackupusers; - -GRANT USAGE ON SCHEMA compliance TO dbbackupusers; -GRANT SELECT ON ALL SEQUENCES IN SCHEMA compliance TO group "dbbackupusers"; -Grant select on ALL TABLES in SCHEMA compliance to group dbbackupusers; -ALTER DEFAULT PRIVILEGES IN SCHEMA compliance GRANT SELECT ON SEQUENCES TO group "dbbackupusers"; -ALTER DEFAULT PRIVILEGES IN SCHEMA compliance GRANT SELECT ON TABLES TO group dbbackupusers; - --- grants for all (implicit) sequences -GRANT USAGE, SELECT ON ALL SEQUENCES IN SCHEMA public TO group "secuadmins"; -ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT USAGE, SELECT ON SEQUENCES TO group "secuadmins"; - -GRANT USAGE, SELECT ON ALL SEQUENCES IN SCHEMA public TO group "configimporters"; -ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT USAGE, SELECT ON SEQUENCES TO group "configimporters"; - -GRANT USAGE, SELECT ON ALL SEQUENCES IN SCHEMA public TO group "reporters"; -ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT USAGE, SELECT ON SEQUENCES TO group "reporters"; - -GRANT USAGE, SELECT ON ALL SEQUENCES IN SCHEMA public TO group "fworchadmins"; -ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT USAGE, SELECT ON SEQUENCES TO group "fworchadmins"; - --- Group permissions on tables - --- general grants: -Grant ALL on ALL tables in SCHEMA public to group fworchadmins; -- todo: could be reduced -ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT ALL ON TABLES TO group fworchadmins; - -Grant select on ALL TABLES in SCHEMA public to group configimporters; -ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT SELECT ON TABLES TO group configimporters; - -Grant select on ALL TABLES in SCHEMA public to group reporters; -ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT SELECT ON TABLES TO group reporters; - -Grant select on ALL TABLES in SCHEMA public to group secuadmins; -ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT SELECT ON TABLES TO group secuadmins; - --- config importers: -Grant ALL on "import_service" to group "configimporters"; -Grant ALL on "import_object" to group "configimporters"; -Grant ALL on "import_user" to group "configimporters"; -Grant ALL on "import_rule" to group "configimporters"; -Grant ALL on "import_control" to group "configimporters"; -Grant ALL on "import_zone" to group "configimporters"; -Grant ALL on "import_changelog" to group "configimporters"; -Grant ALL on "import_credential" to group "configimporters"; - -Grant update on "device" to group "configimporters"; -Grant update on "management" to group "configimporters"; -Grant update,insert on "object" to group "configimporters"; -Grant update,insert on "objgrp" to group "configimporters"; -Grant update,insert on "rule" to group "configimporters"; -Grant update,insert on "rule_metadata" to group "configimporters"; -Grant update,insert on "rule_from" to group "configimporters"; -Grant update,insert on "rule_service" to group "configimporters"; -Grant update,insert on "rule_to" to group "configimporters"; -Grant update,insert on "service" to group "configimporters"; -Grant update,insert on "svcgrp" to group "configimporters"; -Grant update,insert on "usr" to group "configimporters"; -Grant update,insert on "zone" to group "configimporters"; -Grant update,insert on "usergrp" to group "configimporters"; -Grant update,insert on "usergrp_flat" to group "configimporters"; -Grant update,insert on "objgrp_flat" to group "configimporters"; -Grant update,insert on "svcgrp_flat" to group "configimporters"; -Grant insert on "changelog_object" to group "configimporters"; -Grant insert on "changelog_service" to group "configimporters"; -Grant insert on "changelog_user" to group "configimporters"; -Grant insert on "changelog_rule" to group "configimporters"; -Grant insert,update on "rule_nwobj_resolved" to group "configimporters"; -Grant insert,update on "rule_svc_resolved" to group "configimporters"; -Grant insert,update on "rule_user_resolved" to group "configimporters"; -Grant ALL on "recertification" to group "configimporters"; -Grant ALL on "recertification" to group "fworchadmins"; - --- secuadmins: -Grant update on "uiuser" to group "secuadmins"; -Grant update,insert on "changelog_object" to group "secuadmins"; -Grant update,insert on "changelog_service" to group "secuadmins"; -Grant update,insert on "changelog_user" to group "secuadmins"; -Grant update,insert on "changelog_rule" to group "secuadmins"; -Grant insert on "report" to group "secuadmins"; - --- reporters: -Grant update on "uiuser" to group "reporters"; -Grant insert on "report" to group "reporters"; -Grant insert on "report_template" to group "reporters"; diff --git a/roles/database/files/sql/idempotent/fworch-import-main.sql b/roles/database/files/sql/idempotent/fworch-import-main.sql deleted file mode 100644 index 06453b057d..0000000000 --- a/roles/database/files/sql/idempotent/fworch-import-main.sql +++ /dev/null @@ -1,362 +0,0 @@ -/* - data structure: - rule__resolved table for each object contained in a rule - used for quick reporting of objects used in a reported ruleset - - rule table: - rule.rule_from/to/svc/usr - textual overview of rule elements - filled directly from import_xxx tables without ref integrity checking - - import_changelog table only used for audit log entries - currently not used at all - can be deleted or maybe used for recording ref integrity issues? - - changelog_rule/svc/nwobj tables - record all changes - should also contain unreferenced changes?! then we can use these tables for reporting ref issues - - new: log_data_issue for storing broken references etc. but not rolling back the import - - - (error handling) structure: - - import_all_main(mgm_id) RETURNS boolean --> string with errors instead? - { - TRY: - all VOID returns: import_zone_main, import_nwobj_main, import_svc_main, import_usr_main - FOR all devices: - IF import_rules() - import_rules_set_rule_num_numeric - - if import_global_refhandler_main THEN raise returned exception error_string - -- here exception handling needs to be fixed - else - if get_active_rules_with_broken_refs_per_mgm() <>'' THEN raise returned exception error_string - -- here exception handling already seems to be working - - import_changelog_sync (mainly logging hitherto unnoticed deletes in import_change- tables) - CATCH: - enrich import_control.import_errors with errors from above - - --------- creating foreign key references for each element of a rule (and also object groups) - the _flat tables in addition contain all resolved group members (redundant information to speed up reporting) - - import_global_refhandler_main: (exception handling not working) - import_nwobj_refhandler_main - import_nwobj_refhandler_insert - import_nwobj_refhandler_objgrp_add_group - import_nwobj_refhandler_change - import_nwobj_refhandler_change_objgrp_member_refs - import_nwobj_refhandler_objgrp_add_group - import_nwobj_refhandler_insert_flat - import_nwobj_refhandler_objgrp_flat_add_group - import_nwobj_refhandler_change_flat - import_nwobj_refhandler_change_objgrp_flat_member_refs - import_nwobj_refhandler_change_rule_from_refs - import_nwobj_refhandler_change_rule_to_refs - - import_svc_refhandler_main (same sub functions as nwobj above) - ... - import_usr_refhandler_main (same sub functions as nwobj above) - ... - - for each device: - import_rule_refhandler_main: - for each rule: - resolve_rule_list(rule_from): - for each rule-from element: - f_add_single_rule_from_element - import_rule_resolved_nwobj - resolve_rule_list(rule_to) - for each rule-to element: - f_add_single_rule_to_element - import_rule_resolved_nwobj - resolve_rule_list(rule_service) - for each rule-service element: - f_add_single_rule_svc_element - import_rule_resolved_svc - - --------- Q&A the following code just checks for broken references and reports them - broken refs can occur if the element is not the only element in a field? - - get_active_rules_with_broken_refs_per_mgm: (exception handling working) - for each device: - get_active_rules_with_broken_refs_per_dev := - get_active_rules_with_broken_src_refs_per_dev (v_delimiter, b_heal, i_dev_id) || - get_active_rules_with_broken_dst_refs_per_dev (v_delimiter, b_heal, i_dev_id) || - get_active_rules_with_broken_svc_refs_per_dev - - the above functions check all refs - if "healing mode" is set (not used during import), the missing refs are inserted into rule_from/rule_to/rule_svc - all broken refs are returned as a string - } */ - -DROP FUNCTION IF EXISTS public.import_all_main(BIGINT); -DROP FUNCTION IF EXISTS public.import_all_main(BIGINT, BOOLEAN); -CREATE OR REPLACE FUNCTION public.import_all_main(BIGINT, BOOLEAN) - RETURNS VARCHAR AS -$BODY$ -DECLARE - i_current_import_id ALIAS FOR $1; -- ID of the current import - b_debug_mode ALIAS FOR $2; -- should we output debug info? - i_mgm_id INTEGER; - r_dev RECORD; - b_force_initial_import BOOLEAN; - b_is_initial_import BOOLEAN; - b_do_not_import BOOLEAN; - v_err_pos VARCHAR; - v_err_str VARCHAR; - v_err_str_refs VARCHAR; - b_result BOOLEAN; - r_obj RECORD; - v_exception_message VARCHAR; - v_exception_details VARCHAR; - v_exception_hint VARCHAR; - v_exception VARCHAR; - t_import_start TIMESTAMP; - t_last_measured_timestamp TIMESTAMP; -BEGIN - BEGIN -- catch exception block - t_import_start := now(); - v_err_pos := 'start'; - SELECT INTO i_mgm_id mgm_id FROM import_control WHERE control_id=i_current_import_id; - SELECT INTO b_is_initial_import is_initial_import FROM import_control WHERE control_id=i_current_import_id; - IF NOT b_is_initial_import THEN -- pruefen, ob force_flag des Mangements gesetzt ist - SELECT INTO b_force_initial_import force_initial_import FROM management WHERE mgm_id=i_mgm_id; - IF b_force_initial_import THEN b_is_initial_import := TRUE; END IF; - END IF; - - -- import base objects - v_err_pos := 'import_zone_main'; - PERFORM import_zone_main (i_current_import_id, b_is_initial_import); - v_err_pos := 'import_nwobj_main'; - PERFORM import_nwobj_main (i_current_import_id, b_is_initial_import); - v_err_pos := 'import_svc_main'; - PERFORM import_svc_main (i_current_import_id, b_is_initial_import); - v_err_pos := 'import_usr_main'; - PERFORM import_usr_main (i_current_import_id, b_is_initial_import); - RAISE DEBUG 'after usr_import'; - v_err_pos := 'rulebase_import_start'; - - t_last_measured_timestamp := debug_show_time('import of base objects', t_import_start); - -- import rulebases - FOR r_dev IN - SELECT * FROM device WHERE mgm_id=i_mgm_id AND NOT do_not_import - LOOP - SELECT INTO b_do_not_import do_not_import FROM device WHERE dev_id=r_dev.dev_id; - IF NOT b_do_not_import THEN -- RAISE NOTICE 'importing %', r_dev.dev_name; - v_err_pos := 'import_rules of device ' || r_dev.dev_name || ' (Management: ' || CAST (i_mgm_id AS VARCHAR) || ')'; - IF (import_rules(r_dev.dev_id, i_current_import_id)) THEN -- returns true if rule order needs to be changed - -- currently always returns true as each import needs a rule reordering - v_err_pos := 'import_rules_set_rule_num_numeric of device ' || r_dev.dev_name || ' (Management: ' || CAST (i_mgm_id AS VARCHAR) || ')'; - -- in case of any changes - adjust rule_num values in rulebase - PERFORM import_rules_set_rule_num_numeric (i_current_import_id,r_dev.dev_id); - END IF; - END IF; - END LOOP; - - t_last_measured_timestamp := debug_show_time('import of rules', t_last_measured_timestamp); - - v_err_pos := 'ImpGlobRef'; - SELECT INTO b_result * FROM import_global_refhandler_main(i_current_import_id); - IF NOT b_result THEN -- alle Referenzen aendern (basiert nur auf Eintraegen in changelog_xxx - SELECT INTO v_err_str_refs import_errors FROM import_control WHERE control_id=i_current_import_id; - RAISE NOTICE 'notice. error in import_global_refhandler_main'; - RAISE EXCEPTION 'error in import_global_refhandler_main'; - ELSE -- no error so far - v_err_pos := 'get_active_rules_with_broken_refs_per_mgm'; - SELECT INTO v_err_str_refs * FROM get_active_rules_with_broken_refs_per_mgm ('|', FALSE, i_mgm_id); - IF NOT are_equal(v_err_str_refs, '') THEN - RAISE EXCEPTION 'error in get_active_rules_with_broken_refs_per_mgm: %', v_err_str_refs; --- RAISE NOTICE 'found broken references in get_active_rules_with_broken_refs_per_mgm: %', v_err_str_refs; - END IF; - END IF; - IF b_force_initial_import THEN UPDATE management SET force_initial_import=FALSE WHERE mgm_id=i_mgm_id; END IF; -- evtl. gesetztes management.force_initial_import-Flag loeschen - v_err_pos := 'import_changelog_sync'; - PERFORM import_changelog_sync (i_current_import_id, i_mgm_id); -- Abgleich zwischen import_changelog und changelog_xxx - v_err_pos := 'recert_refresh_per_management'; - -- LargeOwnerChange: comment out the following line - -- PERFORM recert_refresh_per_management (i_mgm_id); - EXCEPTION - WHEN OTHERS THEN -- read error from import_control and rollback - GET STACKED DIAGNOSTICS v_exception_message = MESSAGE_TEXT, - v_exception_details = PG_EXCEPTION_DETAIL, - v_exception_hint = PG_EXCEPTION_HINT; - v_exception := v_exception_message || v_exception_details || v_exception_hint; - v_err_pos := 'ERR-ImpMain@' || v_err_pos; - RAISE DEBUG 'import_all_main - Exception block entered with v_err_pos=%', v_err_pos; - SELECT INTO v_err_str import_errors FROM import_control WHERE control_id=i_current_import_id; - IF v_err_str IS NULL THEN - UPDATE import_control SET import_errors = v_err_pos || v_exception WHERE control_id=i_current_import_id; - ELSE - UPDATE import_control SET import_errors = v_err_str || v_err_pos || v_exception WHERE control_id=i_current_import_id; - END IF; - IF NOT v_err_str_refs IS NULL THEN - SELECT INTO v_err_str import_errors FROM import_control WHERE control_id=i_current_import_id; - UPDATE import_control SET import_errors = v_err_str || ';' || v_err_str_refs WHERE control_id=i_current_import_id; - END IF; - RAISE NOTICE 'ERROR: import_all_main failed'; - RETURN v_err_str; - -- RETURN FALSE; - END; - RETURN ''; -END; -$BODY$ - LANGUAGE plpgsql VOLATILE - COST 100; -ALTER FUNCTION public.import_all_main(BIGINT, BOOLEAN) OWNER TO fworch; - - -CREATE OR REPLACE FUNCTION debug_show_time (VARCHAR, TIMESTAMP) - RETURNS TIMESTAMP - AS $BODY$ -DECLARE - v_event ALIAS FOR $1; -- description of the processed time - t_import_start ALIAS FOR $2; -- start time of the import -BEGIN - - RAISE NOTICE '% duration: %s', v_event, CAST(now()- t_import_start AS VARCHAR); --- RAISE NOTICE 'duration of last step: %s', CAST(now()- t_import_start AS VARCHAR); - RETURN now(); -END; -$BODY$ -LANGUAGE plpgsql -VOLATILE -COST 100; - ----------------------------------------------------- --- FUNCTION: import_global_refhandler_main --- Zweck: ueberall dort, wo Elemente veraendert (changed,inserted,deleted) wurden, --- Zweck: muessen die Referenzen entweder: --- Zweck: - vom alten auf das neue Element umgebogen werden --- Zweck: - fuer das Element geloescht werden --- Zweck: - fuer das Element hinzugefuegt werden --- Parameter: current_import_id --- RETURNS: VOID --- -CREATE OR REPLACE FUNCTION import_global_refhandler_main (BIGINT) RETURNS BOOLEAN AS $$ -DECLARE - i_current_import_id ALIAS FOR $1; -- ID des laufenden Imports - i_mgm_id INTEGER; - r_device RECORD; - b_do_not_import BOOLEAN; - v_err_pos VARCHAR; - v_err_str VARCHAR; -BEGIN - -- BEGIN -- exception block - -- adjust references for objects for current management - v_err_pos := 'import_nwobj_refhandler_main'; - PERFORM import_nwobj_refhandler_main(i_current_import_id); - v_err_pos := 'import_svc_refhandler_main'; - PERFORM import_svc_refhandler_main(i_current_import_id); - v_err_pos := 'import_usr_refhandler_main'; - PERFORM import_usr_refhandler_main(i_current_import_id); - - -- adjust rule references or all devices of the current management - SELECT INTO i_mgm_id mgm_id FROM import_control WHERE control_id=i_current_import_id; - FOR r_device IN - SELECT * FROM device WHERE mgm_id=i_mgm_id - LOOP - SELECT INTO b_do_not_import do_not_import FROM device WHERE dev_id=r_device.dev_id; - IF NOT b_do_not_import THEN - v_err_pos := 'import_rule_refhandler_main of device ' || r_device.dev_name || ' (Management: ' || CAST (i_mgm_id AS VARCHAR) || ')'; - PERFORM import_rule_refhandler_main(i_current_import_id, r_device.dev_id); - END IF; - END LOOP; - -- EXCEPTION - -- WHEN OTHERS THEN - -- v_err_pos := 'ERR-ImpGlobRef@' || v_err_pos; - -- RAISE NOTICE 'referr %', v_err_pos; - -- -- SELECT INTO v_err_str import_errors FROM import_control WHERE control_id=i_current_import_id; - -- -- IF v_err_str IS NULL THEN - -- -- UPDATE import_control SET import_errors = v_err_pos WHERE control_id=i_current_import_id; - -- -- ELSE - -- -- UPDATE import_control SET import_errors = v_err_str || v_err_pos WHERE control_id=i_current_import_id; - -- -- END IF; - -- -- RETURN FALSE; - -- END; - RETURN TRUE; -END; -$$ LANGUAGE plpgsql; - ----------------------------------------------------- --- FUNCTION: import_changelog_sync --- Zweck: Abgleich zwischen Auditlog Eintraegen (import_changelog) und --- Zweck: den generierten Eintraegen in changelog_xxx --- Parameter: current_import_id --- Parameter: mgmg_id --- RETURNS: VOID --- -/* -Example import_changelog entries: - -fworchdb=# select * from import_changelog where control_id=14; - change_time | management_name | changed_object_name | changed_object_uid | changed_object_type | change_action | change_admin | control_id | import_changelog_nr | import_changelog_id ----------------------+-----------------+---------------------+--------------------------------------+---------------------+---------------+--------------+------------+---------------------+--------------------- - 2007-09-25 11:08:02 | fw1 | Standard | 4C6B3F06-B6B0-4287-AF4B-A7B553925F02 | rule | C | tim | 14 | 8 | 311 - 2007-09-25 11:08:02 | fw1 | abc | B4BD0D06-43F7-4FA4-AAE0-5567D45E313C | network_object | I | tim | 14 | 7 | 310 - 2007-09-25 11:01:27 | fw1 | | | | Log In | tim | 14 | 1 | 304 - 2007-09-25 11:00:33 | fw1 | | | | Log In | localhost | 14 | 0 | 303 -(10 Zeilen) - - -fworchdb=# select * from view_changes; - abs_change_id | local_change_id | change_request_info | change_element | change_element_order | old_id | new_id | change_documented | change_type_id | change_type | change_comment | obj_comment | change_time | mgm_name | mgm_id | dev_name | dev_id | change_admin | change_admin_id | doku_admin | doku_admin_id | security_relevant | unique_name | change_diffs | change_new_element ----------------+-----------------+---------------------+----------------+----------------------+--------+--------+-------------------+----------------+-------------+----------------+-------------+----------------------------+----------+--------+----------+--------+--------------+-----------------+------------+---------------+-------------------+-------------------------------------------------------------------------+--------------+-------------------- - 460 | 9 | | rule | rule_element | 4 | 8 | f | 3 | C | | | 2007-09-25 11:04:41.951275 | fw1 | 444 | fw1 | 444 | Tim Purschke | 4 | | | t | Standard__uid__26E762E9-4DF2-406C-B3D4-F57C2C19F7A9, Rulebase: Standard | | - 457 | 8 | | rule | rule_element | 7 | | f | 3 | D | | | 2007-09-25 11:42:45.101601 | fw1 | 444 | fw1 | 444 | | | | | t | Standard__uid__8ED0AE3D-F6E5-485A-81D8-C22D21410491, Rulebase: Standard | | - 458 | 13 | | object | basic_element | 2 | | f | 3 | D | | | 2007-09-25 11:45:45.972244 | fw1 | 444 | | | | | | | t | test1-inserted | | -(9 Zeilen) -*/ - -CREATE OR REPLACE FUNCTION import_changelog_sync (BIGINT, INTEGER) RETURNS VOID AS $$ -DECLARE - i_current_import_id ALIAS FOR $1; -- ID des laufenden Imports - i_mgm_id ALIAS FOR $2; -- mgm_id - r_auditlog RECORD; - r_changelog RECORD; - i_admin_id INTEGER; - r_user_id RECORD; - i_delete_import_id BIGINT; - i_last_seen_import_id BIGINT; -BEGIN - FOR r_auditlog IN - SELECT * FROM import_changelog WHERE control_id=i_current_import_id - LOOP - RAISE NOTICE 'change: %', r_auditlog.change_action; - IF r_auditlog.change_action = 'C' OR r_auditlog.change_action = 'I' OR r_auditlog.change_action = 'D' THEN -- real changes, no log-ins/outs - SELECT uiuser_id INTO i_admin_id FROM uiuser WHERE uiuser_username=r_auditlog.change_admin; -- change_admin ID holen - RAISE NOTICE ' object change, name=%', r_auditlog.changed_object_name || ', type=' || r_auditlog.changed_object_type || ', action=' || r_auditlog.change_action || '.'; - -- now processing unnoticed user deletes (which exist for checkpoint firewalls) - IF r_auditlog.changed_object_type='user' AND r_auditlog.change_action='D' THEN - RAISE NOTICE ' user delete change found: %', r_auditlog.changed_object_name; - SELECT view_changes.*, uiuser_username INTO r_changelog FROM view_changes LEFT JOIN uiuser ON (change_admin_id=uiuser_id) - WHERE unique_name=r_auditlog.changed_object_name AND change_type='D'; - IF NOT FOUND THEN --- RAISE NOTICE ' found unnoticed user delete: %', r_auditlog.changed_object_name; - SELECT user_id INTO r_user_id FROM usr WHERE user_name=r_auditlog.changed_object_name AND active; - IF FOUND THEN - SELECT MAX(control_id) INTO i_last_seen_import_id FROM import_control WHERE mgm_id=i_mgm_id AND start_timei_last_seen_import_id; - IF FOUND THEN - INSERT INTO changelog_user (control_id, old_user_id, change_action, mgm_id, change_type_id, change_time, import_admin, unique_name) - VALUES (i_current_import_id, r_user_id.user_id, 'D', i_mgm_id, 3, r_auditlog.change_time, i_admin_id, r_auditlog.changed_object_uid); - UPDATE usr SET active=FALSE, user_last_seen=i_last_seen_import_id WHERE active AND usr.user_id=r_user_id.user_id; - ELSE - RAISE WARNING 'ERROR: no previous import for deleted user % found', r_auditlog.changed_object_name; - END IF; - ELSE -- der user wurde vor dem ersten Import des Managements geloescht --> also wenn moeglich nicht in die DB aufnehmen - RAISE NOTICE 'User % already deleted before initial import', r_auditlog.changed_object_name; - DELETE FROM changelog_user WHERE new_user_id=r_user_id.user_id; - -- catch errors - DELETE FROM usr WHERE user_id=r_user_id.user_id; - -- catch errors - END IF; - ELSE - RAISE EXCEPTION 'ERROR: deleted user % not found', r_auditlog.changed_object_name; - END IF; - ELSE - RAISE NOTICE ' found noticed user delete: %', r_auditlog.changed_object_name; - END IF; - END IF; - END IF; - END LOOP; - RETURN; -END; -$$ LANGUAGE plpgsql; diff --git a/roles/database/files/sql/idempotent/fworch-import.sql b/roles/database/files/sql/idempotent/fworch-import.sql deleted file mode 100644 index 2b62df0376..0000000000 --- a/roles/database/files/sql/idempotent/fworch-import.sql +++ /dev/null @@ -1,421 +0,0 @@ --- $Id: iso-import.sql,v 1.1.2.3 2011-05-07 08:46:47 tim Exp $ --- $Source: /home/cvs/iso/package/install/database/Attic/iso-import.sql,v $ - ----------------------------------------------------- --- FUNCTION: undocumented_rule_changes_exist --- Zweck: pruefen, ob noch nicht dokumentierte Aenderungen existieren --- Parameter: KEINE --- RETURNS: INTEGER (Anzahl der undok. Aenderungen) --- -CREATE OR REPLACE FUNCTION undocumented_rule_changes_exist() RETURNS INTEGER AS $$ -DECLARE - i_anz_rule_ch INTEGER; -BEGIN - SELECT INTO i_anz_rule_ch COUNT(*) FROM changelog_rule WHERE NOT documented; - RETURN (i_anz_rule_ch); -END; -$$ LANGUAGE plpgsql; - ----------------------------------------------------- --- FUNCTION: undocumented_svc_changes_exist --- Zweck: pruefen, ob noch nicht dokumentierte Aenderungen existieren --- Parameter: KEINE --- RETURNS: INTEGER --- -CREATE OR REPLACE FUNCTION undocumented_svc_changes_exist() RETURNS INTEGER AS $$ -DECLARE - i_anz_svc_ch INTEGER; -BEGIN - SELECT INTO i_anz_svc_ch COUNT(*) FROM changelog_service WHERE NOT documented; - RETURN (i_anz_svc_ch); -END; -$$ LANGUAGE plpgsql; - ----------------------------------------------------- --- FUNCTION: undocumented_usr_changes_exist --- Zweck: pruefen, ob noch nicht dokumentierte Aenderungen existieren --- Parameter: KEINE --- RETURNS: INTEGER --- -CREATE OR REPLACE FUNCTION undocumented_usr_changes_exist() RETURNS INTEGER AS $$ -DECLARE - i_anz_usr_ch INTEGER; -BEGIN - SELECT INTO i_anz_usr_ch COUNT(*) FROM changelog_user WHERE NOT documented; - RETURN (i_anz_usr_ch); -END; -$$ LANGUAGE plpgsql; - ----------------------------------------------------- --- FUNCTION: undocumented_obj_changes_exist --- Zweck: pruefen, ob noch nicht dokumentierte Aenderungen existieren --- Parameter: KEINE --- RETURNS: INTEGER --- -CREATE OR REPLACE FUNCTION undocumented_obj_changes_exist() RETURNS INTEGER AS $$ -DECLARE - i_anz_obj_ch INTEGER; -BEGIN - SELECT INTO i_anz_obj_ch COUNT(*) FROM changelog_object WHERE NOT documented; - RETURN (i_anz_obj_ch); -END; -$$ LANGUAGE plpgsql; - ----------------------------------------------------- --- FUNCTION: undocumented_changes_exist --- Zweck: pruefen, ob noch nicht dokumentierte Aenderungen existieren --- Parameter: KEINE --- RETURNS: INTEGER --- -CREATE OR REPLACE FUNCTION undocumented_changes_exist() RETURNS INTEGER AS $$ -DECLARE - i_anz_obj_ch INTEGER; - i_anz_usr_ch INTEGER; - i_anz_svc_ch INTEGER; - i_anz_rule_ch INTEGER; -BEGIN - SELECT INTO i_anz_obj_ch COUNT(*) FROM changelog_object WHERE NOT documented; - SELECT INTO i_anz_usr_ch COUNT(*) FROM changelog_user WHERE NOT documented; - SELECT INTO i_anz_svc_ch COUNT(*) FROM changelog_service WHERE NOT documented; - SELECT INTO i_anz_rule_ch COUNT(*) FROM changelog_rule WHERE NOT documented; - RETURN (i_anz_obj_ch + i_anz_usr_ch + i_anz_svc_ch + i_anz_rule_ch); -END; -$$ LANGUAGE plpgsql; - ----------------------------------------------------- --- FUNCTION: is_import_running --- Zweck: pruefen, ob gerade anderer Import aktiv laeuft --- Parameter: KEINE --- RETURNS: BOOLEAN (TRUE: import aktiv, FALSE: kein Import aktiv) --- -CREATE OR REPLACE FUNCTION is_import_running() RETURNS BOOLEAN AS $$ -DECLARE - last_import_time RECORD; - last_control_id RECORD; -BEGIN - SELECT INTO last_import_time MAX(start_time) AS last_import FROM import_control WHERE successful_import; - SELECT INTO last_control_id control_id FROM import_control WHERE stop_time IS NULL AND successful_import AND start_time = last_import_time.last_import; - IF NOT FOUND THEN -- OK, kein Import aktiv - RETURN FALSE; - ELSE - RETURN TRUE; - END IF; -END; -$$ LANGUAGE plpgsql; - ----------------------------------------------------- --- FUNCTION: is_import_running --- Zweck: pruefen, ob gerade anderer Import des Managements aktiv laeuft --- Parameter: Management-System --- RETURNS: BOOLEAN (TRUE: import aktiv, FALSE: kein Import aktiv) --- -CREATE OR REPLACE FUNCTION is_import_running(INTEGER) RETURNS BOOLEAN AS $$ -DECLARE - i_mgm_id ALIAS FOR $1; - last_control_id RECORD; -BEGIN - SELECT INTO last_control_id control_id FROM import_control - WHERE stop_time IS NULL AND mgm_id=i_mgm_id; - IF NOT FOUND THEN -- OK, kein Import aktiv - RETURN FALSE; - ELSE - RETURN TRUE; - END IF; -END; -$$ LANGUAGE plpgsql; - ----------------------------------------------------- --- FUNCTION: get_previous_import_id_for_mgmt --- Zweck: liefert die ID des direkt vor $2 liegenden Imports des Managements $1 zurueck --- Parameter1: Management-ID --- Parameter2: Bezugspunkt (normalerweise = current_import_id) --- RETURNS: BIGINT Import-ID --- -CREATE OR REPLACE FUNCTION get_previous_import_id_for_mgmt (INTEGER,BIGINT) RETURNS BIGINT AS $$ -DECLARE - i_mgm_id ALIAS FOR $1; -- ID des Managements - i_import_id ALIAS FOR $2; -- ID des Imports - i_prev_import_id BIGINT; -- temp. Record -BEGIN - IF i_import_id IS NULL THEN - RETURN NULL; - ELSE - SELECT INTO i_prev_import_id MAX(control_id) FROM import_control WHERE mgm_id=i_mgm_id AND control_id0) THEN - v_changed := v_changed || E'\n' || error_handling('MSG_NUMBER_CHANGES_OBJ_INS', CAST (r_change.anzahl AS VARCHAR)); - END IF; - SELECT INTO r_change COUNT(*) AS anzahl FROM changelog_object WHERE control_id = ctrl_id AND change_action = 'C'; - IF (r_change.anzahl>0) THEN - v_changed := v_changed || E'\n' || error_handling('MSG_NUMBER_CHANGES_OBJ_CHG', CAST (r_change.anzahl AS VARCHAR)); - END IF; - SELECT INTO r_change COUNT(*) AS anzahl FROM changelog_object WHERE control_id = ctrl_id AND change_action = 'D'; - IF (r_change.anzahl>0) THEN - v_changed := v_changed || E'\n' || error_handling('MSG_NUMBER_CHANGES_OBJ_DEL', CAST (r_change.anzahl AS VARCHAR)); - END IF; ----------------------------- - SELECT INTO r_change COUNT(*) AS anzahl FROM changelog_user WHERE control_id = ctrl_id AND change_action = 'I'; - IF (r_change.anzahl>0) THEN - v_changed := v_changed || E'\n' || error_handling('MSG_NUMBER_CHANGES_USR_INS', CAST (r_change.anzahl AS VARCHAR)); - END IF; - SELECT INTO r_change COUNT(*) AS anzahl FROM changelog_user WHERE control_id = ctrl_id AND change_action = 'C'; - IF (r_change.anzahl>0) THEN - v_changed := v_changed || E'\n' || error_handling('MSG_NUMBER_CHANGES_USR_CHG', CAST (r_change.anzahl AS VARCHAR)); - END IF; - SELECT INTO r_change COUNT(*) AS anzahl FROM changelog_user WHERE control_id = ctrl_id AND change_action = 'D'; - IF (r_change.anzahl>0) THEN - v_changed := v_changed || E'\n' || error_handling('MSG_NUMBER_CHANGES_USR_DEL', CAST (r_change.anzahl AS VARCHAR)); - END IF; ----------------------------- - SELECT INTO r_change COUNT(*) AS anzahl FROM changelog_service WHERE control_id = ctrl_id AND change_action = 'I'; - IF (r_change.anzahl>0) THEN - v_changed := v_changed || E'\n' || error_handling('MSG_NUMBER_CHANGES_SVC_INS', CAST (r_change.anzahl AS VARCHAR)); - END IF; - SELECT INTO r_change COUNT(*) AS anzahl FROM changelog_service WHERE control_id = ctrl_id AND change_action = 'C'; - IF (r_change.anzahl>0) THEN - v_changed := v_changed || E'\n' || error_handling('MSG_NUMBER_CHANGES_SVC_CHG', CAST (r_change.anzahl AS VARCHAR)); - END IF; - SELECT INTO r_change COUNT(*) AS anzahl FROM changelog_service WHERE control_id = ctrl_id AND change_action = 'D'; - IF (r_change.anzahl>0) THEN - v_changed := v_changed || E'\n' || error_handling('MSG_NUMBER_CHANGES_SVC_DEL', CAST (r_change.anzahl AS VARCHAR)); - END IF; ----------------------------- - SELECT INTO r_change COUNT(*) AS anzahl FROM changelog_rule WHERE control_id = ctrl_id AND change_action = 'I'; - IF (r_change.anzahl>0) THEN - v_changed := v_changed || E'\n' || error_handling('MSG_NUMBER_CHANGES_RULE_INS', CAST (r_change.anzahl AS VARCHAR)); - END IF; - SELECT INTO r_change COUNT(*) AS anzahl FROM changelog_rule WHERE control_id = ctrl_id AND change_action = 'C'; - IF (r_change.anzahl>0) THEN - v_changed := v_changed || E'\n' || error_handling('MSG_NUMBER_CHANGES_RULE_CHG', CAST (r_change.anzahl AS VARCHAR)); - END IF; - SELECT INTO r_change COUNT(*) AS anzahl FROM changelog_rule WHERE control_id = ctrl_id AND change_action = 'D'; - IF (r_change.anzahl>0) THEN - v_changed := v_changed || E'\n' || error_handling('MSG_NUMBER_CHANGES_RULE_DEL', CAST (r_change.anzahl AS VARCHAR)); - END IF; ----------------------------- - RETURN v_changed; -END; -$$ LANGUAGE plpgsql; - -CREATE OR REPLACE FUNCTION found_changes_in_import(BIGINT) RETURNS VARCHAR AS $$ -BEGIN - RETURN (select show_change_summary($1)<>''); -END; -$$ LANGUAGE plpgsql; - -CREATE OR REPLACE FUNCTION clean_up_tables (BIGINT) RETURNS VOID AS $$ -DECLARE - i_current_import_id ALIAS FOR $1; -BEGIN - DELETE FROM import_object WHERE control_id=i_current_import_id; - VACUUM ANALYZE import_object; - DELETE FROM import_service WHERE control_id=i_current_import_id; - VACUUM ANALYZE import_service; - DELETE FROM import_user WHERE control_id=i_current_import_id; - VACUUM ANALYZE import_user; - DELETE FROM import_rule WHERE control_id=i_current_import_id; - VACUUM ANALYZE import_rule; - DELETE FROM import_zone WHERE control_id=i_current_import_id; - VACUUM ANALYZE import_zone; - - VACUUM ANALYZE object; -- neuordnen der Tabellen - VACUUM ANALYZE objgrp_flat; -- neuordnen der Tabellen - VACUUM ANALYZE rule_from; -- neuordnen der Tabellen - VACUUM ANALYZE rule_to; -- neuordnen der Tabellen - VACUUM ANALYZE service; -- neuordnen der Tabellen - VACUUM ANALYZE rule; -- neuordnen der Tabellen - VACUUM ANALYZE usr; -- neuordnen der Tabellen - RETURN; -END; -$$ LANGUAGE plpgsql; diff --git a/roles/database/files/sql/idempotent/fworch-networking-import.sql b/roles/database/files/sql/idempotent/fworch-networking-import.sql deleted file mode 100644 index 35e7a7be32..0000000000 --- a/roles/database/files/sql/idempotent/fworch-networking-import.sql +++ /dev/null @@ -1,63 +0,0 @@ - -CREATE OR REPLACE FUNCTION import_networking_main (BIGINT, BOOLEAN) RETURNS VOID AS $$ -DECLARE - i_current_import_id ALIAS FOR $1; - b_is_initial_import ALIAS FOR $2; - i_mgm_id INTEGER; - r_interface RECORD; - r_route RECORD; -BEGIN - SELECT INTO i_mgm_id mgm_id FROM import_control WHERE control_id=i_current_import_id; - - -- first delete all old interfaces belonging to the current management: - DELETE FROM gw_interface WHERE routing_device IN (SELECT dev_id FROM device LEFT JOIN management USING (mgm_id) WHERE device.mgm_id=i_mgm_id); - - -- first delete all old routes belonging to the current management: - -- DELETE FROM gw_route WHERE routing_device IN (SELECT dev_id FROM device LEFT JOIN management USING (mgm_id) WHERE device.mgm_id=i_mgm_id); - - -- now re-insert the currently found interfaces: - INSERT INTO gw_interface SELECT * FROM jsonb_populate_recordset(NULL::gw_interface, NEW.config -> 'interfaces'); - -- now re-insert the currently found routes: - -- INSERT INTO gw_route SELECT * FROM jsonb_populate_recordset(NULL::gw_route, NEW.config -> 'routes'); - - RETURN; -END; -$$ LANGUAGE plpgsql; - -CREATE OR REPLACE FUNCTION import_zone_single(BIGINT,INTEGER,VARCHAR,BIGINT) RETURNS VOID AS $$ -DECLARE - control_id ALIAS FOR $1; - i_mgm_id ALIAS FOR $2; - v_zone_name ALIAS FOR $3; - i_current_import_id ALIAS FOR $4; - r_existing_zone RECORD; -BEGIN - RAISE DEBUG 'start import_zone_single for zone %', v_zone_name; - -- zones need update of zone_last_seen - SELECT INTO r_existing_zone zone_name FROM zone WHERE mgm_id=i_mgm_id AND zone_name=v_zone_name; - IF FOUND THEN - UPDATE zone set zone_last_seen=i_current_import_id, active=TRUE where mgm_id=i_mgm_id AND zone_name=v_zone_name; - ELSE - INSERT INTO zone (mgm_id,zone_name,zone_create,zone_last_seen) - VALUES (i_mgm_id,v_zone_name,i_current_import_id,i_current_import_id); - END IF; - RAISE DEBUG 'end import_zone_single for zone %', v_zone_name; - RETURN; -END; -$$ LANGUAGE plpgsql; - - -CREATE OR REPLACE FUNCTION import_zone_mark_deleted(BIGINT,INTEGER) RETURNS VOID AS $$ -DECLARE - i_current_import_id ALIAS FOR $1; - i_mgm_id ALIAS FOR $2; - i_import_admin_id BIGINT; - i_previous_import_id BIGINT; -- zum Holen der import_ID des vorherigen Imports fuer das Mgmt -BEGIN - i_previous_import_id := get_previous_import_id_for_mgmt(i_mgm_id,i_current_import_id); - IF NOT i_previous_import_id IS NULL THEN -- wenn das Management nicht zum ersten Mal importiert wurde - UPDATE zone SET active='FALSE' WHERE mgm_id=i_mgm_id AND active AND zone_last_seen nix zu tun - -- abschliessend bei allen nicht auf non-active gesetzten Relationen die last_seen_id aktualisieren - UPDATE rule_from SET rf_last_seen=i_current_import_id WHERE rule_id IN - (SELECT rule_id FROM rule WHERE mgm_id=i_mgm_id AND active) AND active; - RAISE DEBUG 'import_nwobj_refhandler_main - after second rule_from UPDATE'; - UPDATE rule_to SET rt_last_seen=i_current_import_id WHERE rule_id IN - (SELECT rule_id FROM rule WHERE mgm_id=i_mgm_id AND active) AND active; - RAISE DEBUG 'import_nwobj_refhandler_main - after second rule_to UPDATE'; - UPDATE objgrp SET import_last_seen=i_current_import_id WHERE objgrp_id IN - (SELECT obj_id FROM object WHERE mgm_id=i_mgm_id AND active) AND active; - RAISE DEBUG 'import_nwobj_refhandler_main - after objgrp UPDATE'; - UPDATE objgrp_flat SET import_last_seen=i_current_import_id WHERE objgrp_flat_id IN - (SELECT obj_id FROM object WHERE mgm_id=i_mgm_id AND active) AND active; - RAISE DEBUG 'import_nwobj_refhandler_main - after objgrp_flat UPDATE finished import_nwobj_refhandler_main'; - - FOR r_obj IN -- loop for rule_nwobj_resolved - SELECT old_obj_id,new_obj_id,change_action FROM changelog_object WHERE control_id=i_current_import_id -- AND (change_action = 'C' OR change_action = 'D') - LOOP - -- RAISE NOTICE 'import_nwobj_refhandler_main - rule_nwobj_resolved loop'; - PERFORM import_rule_resolved_nwobj (i_mgm_id, NULL, r_obj.old_obj_id, r_obj.new_obj_id, i_current_import_id, r_obj.change_action, 'N'); - END LOOP; - EXCEPTION - WHEN others THEN - raise notice 'import_nwobj_refhandler_main - uncommittable state. Rolling back'; - raise EXCEPTION '% %', SQLERRM, SQLSTATE; - END; - RETURN; -END; -$BODY$ - LANGUAGE 'plpgsql' VOLATILE - COST 100; - ----------------------------------------------------- --- FUNCTION: import_nwobj_refhandler_change --- Zweck: ueberall dort, wo ein object geaendert wurde, --- Zweck: muessen die Referenzen vom alten auf das neue Objekt umgebogen werden --- Parameter: old_obj_id, new_obj_id, current_import_id --- RETURNS: VOID --- an allen Stellen, an denen das alte Objekt in einem aktiven Datensatz referenziert wird, --- muss es durch das neue ersetzt werden - -CREATE OR REPLACE FUNCTION import_nwobj_refhandler_change(BIGINT, BIGINT, BIGINT) RETURNS VOID AS $$ -DECLARE - i_old_id ALIAS FOR $1; -- id des bestehenden Datensatzes aus object - i_new_id ALIAS FOR $2; -- id des neuen Datensatzes aus object - i_current_import_id ALIAS FOR $3; -- zum Heraussuchen des group_delimiters - r_obj_info RECORD; -- Record zum Sammeln diverser object-Infos (mgm_id, obj_member) - r_import_info RECORD; -- Record zum Sammeln von import-Infos (group_del) -BEGIN - IF are_equal(i_old_id,i_new_id) THEN - RAISE EXCEPTION 'old and new obj id are identical!'; - END IF; - PERFORM import_nwobj_refhandler_change_objgrp_member_refs (i_old_id, i_new_id, i_current_import_id); - -- jetzt noch die Aufloesung der Gruppen - IF is_obj_group(i_old_id) THEN -- wenn Gruppe, dann werden die Beziehungen der moeglicherweise neuen Mitglieder komplett neu eingetragen - -- Daten zum Beschicken der Funktion insert_nwobj_group_relations sammeln - SELECT INTO r_import_info delimiter_group FROM import_control WHERE control_id=i_current_import_id; - SELECT INTO r_obj_info mgm_id,obj_member_refs FROM object WHERE obj_id=i_new_id; - -- neue Member-Beziehungen von i_new_id eintragen - PERFORM import_nwobj_refhandler_objgrp_add_group - (i_new_id,r_obj_info.obj_member_refs,r_import_info.delimiter_group,r_obj_info.mgm_id,i_current_import_id); - END IF; - RETURN; -END; -$$ language plpgsql; - ----------------------------------------------------- --- FUNCTION: import_nwobj_refhandler_insert --- Zweck: pruefen ob Gruppe, wenn ja Gruppenzugehoerigkeiten der Gruppe aufloesen --- Zweck: und in objgrp eintragen --- Parameter: $1: obj_id des neuen Objekts --- Parameter: $2: Trennzeichen zwischen Gruppenmitgliedern --- verwendete --- Funktionen: add_references_for_inserted_group_obj --- RETURNS: VOID --- -CREATE OR REPLACE FUNCTION import_nwobj_refhandler_insert (BIGINT,varchar,BIGINT) RETURNS VOID AS $$ -DECLARE - i_new_id ALIAS FOR $1; - v_delimiter ALIAS FOR $2; - i_current_import_id ALIAS FOR $3; - r_obj_info RECORD; -BEGIN - -- Aufloesung der Gruppen - RAISE DEBUG 'import_nwobj_refhandler_insert - starting'; - IF is_obj_group(i_new_id) THEN -- wenn Gruppe, dann werden die Beziehungen zwischen Gruppe und - RAISE DEBUG 'import_nwobj_refhandler_insert - is_obj_group = TRUE'; - -- Mitgliedern eingetragen - SELECT INTO r_obj_info mgm_id,obj_member_refs FROM object WHERE obj_id=i_new_id; - -- neue Member-Beziehungen von i_new_id eintragen - RAISE DEBUG 'import_nwobj_refhandler_insert - calling import_nwobj_refhandler_objgrp_add_group'; - PERFORM import_nwobj_refhandler_objgrp_add_group (i_new_id,r_obj_info.obj_member_refs,v_delimiter,r_obj_info.mgm_id,i_current_import_id); - END IF; - RAISE DEBUG 'import_nwobj_refhandler_insert - exiting normally'; - RETURN; -END; -$$ LANGUAGE plpgsql; - - -CREATE OR REPLACE FUNCTION import_nwobj_refhandler_change_flat (BIGINT, BIGINT, BIGINT) RETURNS VOID AS $$ -DECLARE - i_old_id ALIAS FOR $1; -- id des bestehenden Datensatzes aus object - i_new_id ALIAS FOR $2; -- id des neuen Datensatzes aus object - i_current_import_id ALIAS FOR $3; -- zum Heraussuchen des group_delimiters - r_obj_info RECORD; -- Record zum Sammeln diverser object-Infos (mgm_id, obj_member) - r_import_info RECORD; -- Record zum Sammeln von import-Infos (group_del) -BEGIN - IF are_equal(i_old_id,i_new_id) THEN - RAISE EXCEPTION 'old and new obj id are identical!'; - END IF; - PERFORM import_nwobj_refhandler_change_objgrp_flat_member_refs (i_old_id, i_new_id, i_current_import_id); - PERFORM import_nwobj_refhandler_change_rule_from_refs (i_old_id, i_new_id, i_current_import_id); - PERFORM import_nwobj_refhandler_change_rule_to_refs (i_old_id, i_new_id, i_current_import_id); - -- jetzt noch die Aufloesung der Gruppen - IF is_obj_group(i_old_id) THEN -- wenn Gruppe, dann werden die Beziehungen der moeglicherweise neuen Mitglieder komplett neu eingetragen - -- Daten zum Beschicken der Funktion insert_nwobj_group_relations sammeln - SELECT INTO r_import_info delimiter_group FROM import_control WHERE control_id=i_current_import_id; - SELECT INTO r_obj_info mgm_id,obj_member_refs FROM object WHERE obj_id=i_new_id; - -- neue Member-Beziehungen von i_new_id eintragen - PERFORM import_nwobj_refhandler_objgrp_flat_add_group (i_new_id,i_new_id,0,i_current_import_id); - END IF; - PERFORM import_nwobj_refhandler_objgrp_flat_add_self(i_new_id, i_current_import_id); - RETURN; -END; -$$ language plpgsql; - ----------------------------------------------------- --- FUNCTION: import_nwobj_refhandler_insert_flat --- Zweck: pruefen ob Gruppe, wenn ja Gruppenzugehoerigkeiten der Gruppe aufloesen --- Zweck: und in objgrp_flat eintragen --- Parameter: $1: obj_id des neuen Objekts --- Parameter: $2: Trennzeichen zwischen Gruppenmitgliedern --- verwendete --- Funktionen: add_references_for_inserted_group_obj --- RETURNS: VOID --- -CREATE OR REPLACE FUNCTION import_nwobj_refhandler_insert_flat (BIGINT,varchar,BIGINT) RETURNS VOID AS $$ -DECLARE - i_new_id ALIAS FOR $1; - v_delimiter ALIAS FOR $2; - i_current_import_id ALIAS FOR $3; - r_obj_info RECORD; -BEGIN - -- Aufloesung der Gruppen - IF is_obj_group(i_new_id) THEN -- wenn Gruppe, dann werden die Beziehungen zwischen Gruppe und Mitgliedern eingetragen - SELECT INTO r_obj_info mgm_id,obj_member_refs FROM object WHERE obj_id=i_new_id; - -- neue Member-Beziehungen von i_new_id eintragen - PERFORM import_nwobj_refhandler_objgrp_flat_add_group (i_new_id,i_new_id,0,i_current_import_id); - END IF; - PERFORM import_nwobj_refhandler_objgrp_flat_add_self(i_new_id,i_current_import_id); - RETURN; -END; -$$ LANGUAGE plpgsql; - ----------------------------------------------------- --- FUNCTION: import_nwobj_refhandler_objgrp_add_group --- Zweck: die Gruppenzugehoerigkeiten der Gruppe $1 aufloesen --- Zweck: und in objgrp eintragen --- Parameter: $1: obj_id der Gruppe --- Parameter: $2: String mit Gruppenmitgliedern --- Parameter: $3: Trennzeichen zwischen den Gruppenmitgliedern in $1 --- Parameter: $4: Management-ID --- verwendete --- Funktionen: f_add_single_group_member_object, insert_nwobj_group_relations (rekursiv) --- RETURNS: VOID -CREATE OR REPLACE FUNCTION import_nwobj_refhandler_objgrp_add_group (BIGINT,varchar,varchar,integer,BIGINT) RETURNS VOID AS $$ -DECLARE - i_group_id ALIAS FOR $1; - v_member_string ALIAS FOR $2; - v_delimiter ALIAS FOR $3; - i_mgm_id ALIAS FOR $4; - i_current_import_id ALIAS FOR $5; - v_current_member varchar; -BEGIN - RAISE DEBUG 'import_nwobj_refhandler_objgrp_add_group - 1 starting, v_member_string=%', v_member_string; - IF v_member_string IS NULL OR v_member_string='' THEN RETURN; END IF; - FOR v_current_member IN SELECT member FROM regexp_split_to_table(v_member_string, E'\\' || v_delimiter) AS member LOOP - RAISE DEBUG 'import_nwobj_refhandler_objgrp_add_group - 2 adding group member ref for %', v_current_member; - PERFORM import_nwobj_refhandler_objgrp_add_single_groupmember(v_current_member, i_group_id, i_mgm_id, i_current_import_id); - END LOOP; - RETURN; -END; -$$ LANGUAGE plpgsql; - ----------------------------------------------------- --- FUNCTION: import_nwobj_refhandler_objgrp_add_single_groupmember --- Zweck: die Gruppenzugehoerigkeiten der Gruppe $2 aufloesen --- Zweck: und in objgrp eintragen --- Parameter: $1: Name eines einzelnen Gruppenmitglieds --- Parameter: $2: obj_id der Gruppe --- Parameter: $3: Management-ID --- verwendete --- Funktionen: KEINE --- RETURNS: VOID --- -CREATE OR REPLACE FUNCTION import_nwobj_refhandler_objgrp_add_single_groupmember(varchar,BIGINT,INTEGER,BIGINT) - RETURNS VOID AS $$ -DECLARE - v_member_name ALIAS FOR $1; - i_group_id ALIAS FOR $2; - i_mgm_id ALIAS FOR $3; - i_current_import_id ALIAS FOR $4; - i_obj_id integer; - r_group RECORD; - v_error_str VARCHAR; - r_debug RECORD; -BEGIN --- RAISE DEBUG 'import_nwobj_refhandler_objgrp_add_single_groupmember - starting'; - SELECT INTO i_obj_id obj_id FROM object WHERE mgm_id=i_mgm_id AND obj_uid = v_member_name AND active; --- RAISE DEBUG 'import_nwobj_refhandler_objgrp_add_single_groupmember - after first select into'; - -- hier sollte ev. noch die Zonenzugehoerigkeit beruecksichtigt werden - IF NOT FOUND THEN --- RAISE DEBUG 'import_nwobj_refhandler_objgrp_add_single_groupmember - obj_uid not found: normal case, no dups'; - SELECT INTO r_group obj_name,obj_uid FROM object WHERE obj_id = i_group_id; --- RAISE DEBUG 'import_nwobj_refhandler_objgrp_add_single_groupmember - after second select into (group)'; - v_error_str := ''; - IF NOT r_group.obj_name IS NULL THEN - v_error_str := 'group: ' || r_group.obj_name || ' (uid: ' || r_group.obj_uid || '), '; - ELSE - v_error_str := 'unknown group, '; - END IF; - IF NOT v_member_name IS NULL THEN - v_error_str := v_error_str || 'member: ' || v_member_name; - ELSE - v_error_str := v_error_str || 'unknown member'; - END IF; - PERFORM error_handling('ERR_GRP_MISS_OBJ', v_error_str); - -- PERFORM add_data_issue(i_current_import_id, r_group.obj_name, r_group.obj_uid, NULL, NULL, 'nw obj group member', - -- 'non-existant nw obj ' || v_member_name || ' referenced in network object group ' || r_group.obj_name, NULL); - ELSE - RAISE DEBUG 'import_nwobj_refhandler_objgrp_add_single_groupmember - obj_uid already exists: duplicate'; - -- debugging for duplicate members - SELECT INTO r_debug objgrp_id,objgrp_member_id FROM objgrp - WHERE objgrp_id=i_group_id AND objgrp_member_id=i_obj_id AND active; - IF FOUND THEN - SELECT INTO r_group obj_name,obj_uid FROM object WHERE obj_id = i_group_id; - v_error_str := ''; - IF NOT r_group.obj_name IS NULL THEN - v_error_str := 'group: ' || r_group.obj_name || ' (uid: ' || r_group.obj_uid || '), '; - ELSE - v_error_str := 'unknown group, '; - END IF; - IF NOT v_member_name IS NULL THEN - v_error_str := v_error_str || 'member: ' || v_member_name; - ELSE - v_error_str := v_error_str || 'unknown member'; - END IF; - -- PERFORM add_data_issue(i_current_import_id, r_group.obj_name, r_group.obj_uid, NULL, NULL, 'nw obj group member', - -- 'duplicate nw obj in group', 'nw obj ' || v_member_name || ' referenced more than once in network object group ' || r_group.obj_name); - PERFORM error_handling('ERR_GRP_DBL_OBJ', v_error_str); - ELSE - INSERT INTO objgrp (objgrp_id,objgrp_member_id,import_created,import_last_seen) - VALUES (i_group_id,i_obj_id,i_current_import_id,i_current_import_id); - END IF; - END IF; --- RAISE DEBUG 'import_nwobj_refhandler_objgrp_add_single_groupmember - exiting normally'; - RETURN; -END; -$$ LANGUAGE plpgsql; - - ------------------ ab hier kommen die flat-Funktionen ----------------------- - ----------------------------------------------------- --- FUNCTION: import_nwobj_refhandler_objgrp_flat_add_group --- Zweck: die Gruppenzugehoerigkeiten der Gruppe $2 aufloesen --- Zweck: und in objgrp_flat als Teil von $1 eintragen --- Parameter: $1: obj_id der Top-Level-Gruppe --- Parameter: $2: obj_id der Unter-Gruppe --- Parameter: $3: Rekursionsebene - fuer Abbruch nach 20 Rekursionen --- verwendete --- Funktionen: insert_nwobj_group_relations_flat (rekursiv) --- RETURNS: VOID --- -CREATE OR REPLACE FUNCTION import_nwobj_refhandler_objgrp_flat_add_group (BIGINT,BIGINT,INTEGER,BIGINT) RETURNS VOID AS $$ -DECLARE - i_top_group_id ALIAS FOR $1; - i_group_id ALIAS FOR $2; - i_rec_level ALIAS FOR $3; - i_current_import_id ALIAS FOR $4; - r_member RECORD; - r_obj RECORD; - r_member_exists RECORD; -BEGIN --- RAISE DEBUG '%', 'objgrp_flat_add_group start with top lvl ' || i_top_group_id || ' and current group to add ' || i_group_id || ', rec_level=' || i_rec_level; - IF i_rec_level>20 THEN - RAISE DEBUG '%', 'exceeded rec-level (' || i_rec_level || ') check, top-lvl-group ' || i_top_group_id || ', current group to add ' || i_group_id; - PERFORM error_handling('ERR_OBJ_GROUP_REC_LVL_EXCEEDED'); - END IF; - FOR r_member IN SELECT objgrp_member_id FROM objgrp WHERE objgrp_id=i_group_id - LOOP --- RAISE DEBUG '%', 'in loop with current member to add: ' || r_member.objgrp_member_id; - SELECT INTO r_member_exists * FROM objgrp_flat WHERE objgrp_flat_id=i_top_group_id AND objgrp_flat_member_id=r_member.objgrp_member_id; - IF NOT FOUND THEN --- RAISE DEBUG '%', 'adding ' || r_member.objgrp_member_id || ' from group ' || i_group_id || ' to top lvl group ' || i_top_group_id; - INSERT INTO objgrp_flat (objgrp_flat_id,objgrp_flat_member_id,import_created,import_last_seen) - VALUES (i_top_group_id,r_member.objgrp_member_id,i_current_import_id,i_current_import_id); - IF is_obj_group(r_member.objgrp_member_id) THEN --- RAISE DEBUG'%', 'found a nested group ' || r_member.objgrp_member_id || ' in group ' || i_group_id || ' (in top lvl group ' || i_top_group_id || ')'; - PERFORM import_nwobj_refhandler_objgrp_flat_add_group (i_top_group_id, r_member.objgrp_member_id, i_rec_level+1, i_current_import_id); - END IF; - ELSE --- RAISE DEBUG '%', 'member ' || r_member.objgrp_member_id || ' already (FOUND) in group ' || i_group_id || ' (top lvl group ' || i_top_group_id || ') - skipping'; - END IF; - END LOOP; --- RAISE DEBUG '%', 'objgrp_flat_add_group stop top lvl=' || i_top_group_id || ', current group to add=' || i_group_id || ', rec_level=' || i_rec_level; - RETURN; -END; -$$ LANGUAGE plpgsql; - ----------------------------------------------------- --- FUNCTION: import_nwobj_refhandler_objgrp_flat_add_self --- Zweck: das Objekt $1 (ob Gruppe oder simple-Object) wird als sein eigenes objgrp_flat-Mitglied eingetragen --- Parameter: $1: obj_id eines NW-Objekts --- RETURNS: VOID --- -CREATE OR REPLACE FUNCTION import_nwobj_refhandler_objgrp_flat_add_self (BIGINT,BIGINT) RETURNS VOID AS $$ -DECLARE - i_obj_id ALIAS FOR $1; - i_current_import_id ALIAS FOR $2; -BEGIN - INSERT INTO objgrp_flat (objgrp_flat_id,objgrp_flat_member_id,import_created,import_last_seen) - VALUES (i_obj_id,i_obj_id,i_current_import_id,i_current_import_id); - RETURN; -END; -$$ LANGUAGE plpgsql; - ----------------------------------------------------- --- FUNCTION: import_nwobj_refhandler_change_objgrp_member_refs --- Zweck: ueberall dort, wo das alte (geaenderte) Objekt in objgrp als member auftaucht --- Zweck: muessen die Referenzen vom alten auf das neue Objekt umgebogen werden --- Parameter: old_obj_id, new_obj_id --- RETURNS: VOID -CREATE OR REPLACE FUNCTION import_nwobj_refhandler_change_objgrp_member_refs(BIGINT, BIGINT, BIGINT) RETURNS VOID AS $$ -DECLARE - i_old_id ALIAS FOR $1; -- id des bestehenden Datensatzes aus object - i_new_id ALIAS FOR $2; -- id des neuen Datensatzes aus object - i_current_import_id ALIAS FOR $3; - r_objgrp objgrp%ROWTYPE; -BEGIN - FOR r_objgrp IN - SELECT * FROM objgrp WHERE objgrp_member_id=i_old_id AND active - LOOP -- die neue Beziehung wird eingefuegt - INSERT INTO objgrp (objgrp_id,objgrp_member_id,import_created,import_last_seen) - VALUES (r_objgrp.objgrp_id, i_new_id,i_current_import_id,i_current_import_id); - END LOOP; - RETURN; -END; -$$ language plpgsql; - ----------------------------------------------------- --- FUNCTION: import_nwobj_refhandler_change_objgrp_flat_member_refs --- Zweck: ueberall dort, wo das alte (geaenderte) Objekt in objgrp_flat als member auftaucht --- Zweck: muessen die Referenzen vom alten auf das neue Objekt umgebogen werden --- Parameter: old_obj_id, new_obj_id --- RETURNS: VOID -CREATE OR REPLACE FUNCTION import_nwobj_refhandler_change_objgrp_flat_member_refs(BIGINT, BIGINT, BIGINT) RETURNS VOID AS $$ -DECLARE - i_old_id ALIAS FOR $1; -- id des bestehenden Datensatzes aus object - i_new_id ALIAS FOR $2; -- id des neuen Datensatzes aus object - i_current_import_id ALIAS FOR $3; - r_objgrp_flat objgrp_flat%ROWTYPE; - r_member_exists objgrp_flat%ROWTYPE; -BEGIN - FOR r_objgrp_flat IN - SELECT * FROM objgrp_flat WHERE objgrp_flat_member_id=i_old_id AND active - LOOP -- die neue Beziehung wird eingefuegt - SELECT INTO r_member_exists * FROM objgrp_flat WHERE - objgrp_flat_id=r_objgrp_flat.objgrp_flat_id AND objgrp_flat_member_id=i_new_id; - IF NOT FOUND THEN -- wenn das Mitglied noch nicht in der Gruppe ist: eintragen - verhindert doppelte EIntraege - INSERT INTO objgrp_flat (objgrp_flat_id,objgrp_flat_member_id,import_created,import_last_seen) - VALUES (r_objgrp_flat.objgrp_flat_id, i_new_id, i_current_import_id, i_current_import_id); - ELSE - RAISE NOTICE 'found double flat_group_member in group %', r_objgrp_flat.objgrp_flat_id; - END IF; - END LOOP; - RETURN; -END; -$$ language plpgsql; - ----------------------------------------------------- --- FUNCTION: import_nwobj_refhandler_change_rule_from_refs --- Zweck: ueberall dort, wo das alte (geaenderte) Objekt in rule_from als Quelle auftaucht --- Zweck: muessen die Referenzen vom alten auf das neue Objekt umgebogen werden --- Parameter: old_obj_id, new_obj_id --- RETURNS: VOID -CREATE OR REPLACE FUNCTION import_nwobj_refhandler_change_rule_from_refs (BIGINT, BIGINT, BIGINT) RETURNS VOID AS $$ -DECLARE - i_old_id ALIAS FOR $1; -- id des bestehenden Datensatzes aus object - i_new_id ALIAS FOR $2; -- id des neuen Datensatzes aus object - i_import_id ALIAS FOR $3; -- id des imports - r_from rule_from%ROWTYPE; -BEGIN - FOR r_from IN - SELECT * FROM rule_from WHERE obj_id=i_old_id AND active - LOOP -- die neue Beziehung wird eingefuegt - INSERT INTO rule_from (rule_id,obj_id,user_id,rf_create,rf_last_seen) - VALUES (r_from.rule_id, i_new_id, r_from.user_id, i_import_id, i_import_id); - END LOOP; - RETURN; -END; -$$ language plpgsql; - ----------------------------------------------------- --- FUNCTION: import_nwobj_refhandler_change_rule_to_refs --- Zweck: ueberall dort, wo das alte (geaenderte) Objekt in rule_to als Ziel auftaucht --- Zweck: muessen die Referenzen vom alten auf das neue Objekt umgebogen werden --- Parameter: old_obj_id, new_obj_id --- RETURNS: VOID -CREATE OR REPLACE FUNCTION import_nwobj_refhandler_change_rule_to_refs (BIGINT, BIGINT, BIGINT) RETURNS VOID AS $$ -DECLARE - i_old_id ALIAS FOR $1; -- id des bestehenden Datensatzes aus object - i_new_id ALIAS FOR $2; -- id des neuen Datensatzes aus object - i_import_id ALIAS FOR $3; -- id des imports - r_to rule_to%ROWTYPE; -BEGIN - FOR r_to IN - SELECT * FROM rule_to WHERE obj_id=i_old_id AND active - LOOP -- alte Zeiger auf rule_to-objekte mit i_old_id werden auf not active gesetzt - -- zusaetzlich wird die neue Beziehung eingefuegt - INSERT INTO rule_to (rule_id,obj_id, rt_create, rt_last_seen) - VALUES (r_to.rule_id, i_new_id, i_import_id, i_import_id); - END LOOP; - RETURN; -END; -$$ language plpgsql; diff --git a/roles/database/files/sql/idempotent/fworch-path-analysis.sql b/roles/database/files/sql/idempotent/fworch-path-analysis.sql index 0f8f3954e0..1e258f2e42 100644 --- a/roles/database/files/sql/idempotent/fworch-path-analysis.sql +++ b/roles/database/files/sql/idempotent/fworch-path-analysis.sql @@ -2,8 +2,7 @@ DROP FUNCTION IF EXISTS devices_in_path (cidr, cidr); CREATE OR REPLACE FUNCTION public.routing_interface (c_network_object cidr, i_dev_id integer, i_ip_version integer) RETURNS integer - LANGUAGE 'plpgsql' - COST 100 STABLE + LANGUAGE 'plpgsql' STABLE AS $BODY$ BEGIN RETURN ( @@ -24,8 +23,7 @@ $BODY$; CREATE OR REPLACE FUNCTION public.devices_in_path (c_source cidr, c_destination cidr) RETURNS SETOF device - LANGUAGE 'plpgsql' - COST 100 STABLE ROWS 1000 + LANGUAGE 'plpgsql' STABLE ROWS 20 AS $BODY$ DECLARE dev device; diff --git a/roles/database/files/sql/idempotent/fworch-qa.sql b/roles/database/files/sql/idempotent/fworch-qa.sql deleted file mode 100644 index 6a1c086055..0000000000 --- a/roles/database/files/sql/idempotent/fworch-qa.sql +++ /dev/null @@ -1,394 +0,0 @@ - -CREATE OR REPLACE FUNCTION fix_broken_refs () RETURNS VARCHAR AS $$ -DECLARE - r_mgm RECORD; - v_result VARCHAR; -BEGIN - v_result := ''; - FOR r_mgm IN SELECT mgm_id FROM management WHERE NOT management.do_not_import LOOP - v_result := v_result || get_active_rules_with_broken_refs_per_mgm('|', TRUE, r_mgm.mgm_id); - END LOOP; - RETURN v_result; -END; -$$ LANGUAGE plpgsql; - - -CREATE OR REPLACE FUNCTION check_broken_refs (VARCHAR, BOOLEAN) RETURNS VARCHAR AS $$ -DECLARE - v_delimiter ALIAS FOR $1; - b_heal ALIAS FOR $2; - r_mgm RECORD; - v_result VARCHAR; -BEGIN - v_result := ''; - FOR r_mgm IN SELECT mgm_id FROM management WHERE NOT management.do_not_import LOOP --- RAISE NOTICE 'checking device %', CAST(r_dev.dev_id AS VARCHAR); - v_result := v_result || get_active_rules_with_broken_refs_per_mgm(v_delimiter, b_heal, r_mgm.mgm_id); - END LOOP; - RETURN v_result; -END; -$$ LANGUAGE plpgsql; - -CREATE OR REPLACE FUNCTION get_active_rules_with_broken_refs_per_mgm (VARCHAR, BOOLEAN, INTEGER) RETURNS VARCHAR AS $$ -DECLARE - v_delimiter ALIAS FOR $1; - b_heal ALIAS FOR $2; - i_mgm_id ALIAS FOR $3; - r_dev RECORD; - v_result VARCHAR; -BEGIN - v_result := ''; - FOR r_dev IN SELECT dev_id FROM device LEFT JOIN management using (mgm_id) WHERE management.mgm_id=i_mgm_id AND - NOT management.do_not_import AND NOT device.do_not_import LOOP --- RAISE NOTICE 'checking device %', CAST(r_dev.dev_id AS VARCHAR); - v_result := v_result || get_active_rules_with_broken_refs_per_dev(v_delimiter, b_heal, r_dev.dev_id); - END LOOP; - RETURN v_result; -END; -$$ LANGUAGE plpgsql; - - ----------------------------------------------------- --- FUNCTION: get_active_rules_with_broken_refs_per_dev (VARCHAR, BOOLEAN, INTEGER) --- Zweck: get rule_ids of all rules that are active and belong to a device that is imported --- Zweck: where rule references are broken (rule_to, rule_from, rule_service) --- Parameter1: delimiter (varchar) default = |, delimiter between objects of a rule --- Parameter2: heal (boolean), if set to true, the reference is added to the respective table --- Parameter3: device id of device to check --- RETURNS: a set of all affected rules --- Example: a) SELECT mgm_id,dev_id,rule_id, rule_create, rule_last_seen, rule_src_refs, rule_dst_refs, rule_svc_refs FROM rule WHERE --- rule_id in (select * from get_active_rules_with_broken_refs ('|', false)) order by rule_create; --- Example: b) select * from get_active_rules_with_broken_refs ('|', true); -- repair all broken refs --- Example: c) select * from get_active_rules_with_broken_refs ('|', false); -- just display NOTICES about broken refs - -CREATE OR REPLACE FUNCTION get_active_rules_with_broken_refs_per_dev (VARCHAR, BOOLEAN, INTEGER) RETURNS VARCHAR AS $$ -DECLARE - v_delimiter ALIAS FOR $1; - b_heal ALIAS FOR $2; - i_dev_id ALIAS FOR $3; -BEGIN - RETURN - get_active_rules_with_broken_src_refs_per_dev (v_delimiter, b_heal, i_dev_id) || - get_active_rules_with_broken_dst_refs_per_dev (v_delimiter, b_heal, i_dev_id) || - get_active_rules_with_broken_svc_refs_per_dev (v_delimiter, b_heal, i_dev_id); -END; -$$ LANGUAGE plpgsql; - - -CREATE OR REPLACE FUNCTION get_active_rules_with_broken_src_refs_per_dev (VARCHAR, BOOLEAN, INTEGER) RETURNS VARCHAR AS $$ -DECLARE - v_delimiter ALIAS FOR $1; - b_heal ALIAS FOR $2; - i_dev_id ALIAS FOR $3; - i_mgm_id INTEGER; - i_zone_id INTEGER; - i_rule_created BIGINT; - i_rule_last_seen BIGINT; - i_count INTEGER; - i_rule_count INTEGER; - i_ref_count INTEGER; - r_obj RECORD; - r_rule RECORD; - r_dev RECORD; - r_debug RECORD; - r_debug2 RECORD; - v_current_obj VARCHAR; - v_user_group VARCHAR; - i_user_id BIGINT; - v_result VARCHAR; - v_result_single VARCHAR; -BEGIN - -- BEGIN - v_result := ''; - FOR r_rule IN SELECT rule_id,rule_uid,rule_src, rule_dst, rule_svc, rule_src_refs, rule_dst_refs, rule_svc_refs, - rule_from_zone, rule_to_zone, rule_create, rule_last_seen - FROM rule WHERE dev_id=i_dev_id and active LOOP - SELECT INTO i_mgm_id mgm_id FROM rule WHERE rule_id=r_rule.rule_id; - SELECT INTO i_rule_created rule_create FROM rule WHERE rule_id=r_rule.rule_id; - SELECT INTO i_rule_last_seen rule_last_seen FROM rule WHERE rule_id=r_rule.rule_id; - - -- checking rule source references - FOR v_current_obj IN SELECT obj FROM regexp_split_to_table(r_rule.rule_src_refs, E'\\' || v_delimiter) AS obj LOOP - IF NOT (v_current_obj IS NULL OR v_current_obj='') THEN - SELECT INTO i_count count(*) FROM regexp_split_to_table(v_current_obj, '@'); - v_user_group := ''; - IF i_count=2 THEN -- AT in string - SELECT INTO v_user_group regexp_replace(v_current_obj, '@.*$', ''); - SELECT INTO v_current_obj regexp_replace(v_current_obj, '^.+@', ''); - SELECT INTO i_user_id user_id FROM usr WHERE user_uid=v_user_group AND mgm_id=i_mgm_id AND active; - -- checking user refs - SELECT INTO r_obj user_id FROM usr WHERE user_uid=v_user_group AND mgm_id=i_mgm_id AND active; - IF NOT FOUND THEN - v_result_single := 'mgmt ' || CAST(i_mgm_id AS VARCHAR) || ', dev ' || CAST(i_dev_id AS VARCHAR) || ', fail 1 (src user_id not found at all): ' || v_user_group; - v_result := v_result || v_result_single || '; '; - -- -- 1 2 3 4 5 6 7 - -- PERFORM add_data_issue(i_rule_last_seen, v_user_group, NULL, r_rule.rule_uid, r_rule.rule_id, i_dev_id, 'user in rule', - -- 'non-existant user obj "' || v_user_group || '" referenced in rule with UID ' || r_rule.rule_uid, NULL); - RAISE NOTICE '%', v_result_single; - ELSE -- check if exactly one object is returned - IF (NOT COUNT(r_obj)=1) THEN - v_result_single := 'mgmt ' || CAST(i_mgm_id AS VARCHAR) || ', dev ' || CAST(i_dev_id AS VARCHAR) || ', fail 2 (not exactly one src obj found): ' || CAST(r_obj.user_id AS VARCHAR) || ', COUNT=' || CAST(count(r_obj) AS VARCHAR); - v_result := v_result || v_result_single || '; '; - RAISE NOTICE '%', v_result_single; - -- -- 1 2 3 4 5 6 7 - -- PERFORM add_data_issue(i_rule_last_seen, v_user_group, NULL, r_rule.rule_uid, r_rule.rule_id, i_dev_id, 'user in rule', - -- 'more than one matching user obj "' || v_user_group || '" found in rule with UID ' || r_rule.rule_uid, NULL); - ELSE - SELECT INTO r_debug rule_id,user_id FROM rule_from WHERE rule_id=r_rule.rule_id AND user_id=r_obj.user_id AND active; - IF NOT FOUND THEN - v_result_single := 'mgmt ' || CAST(i_mgm_id AS VARCHAR) || ', dev ' || CAST(i_dev_id AS VARCHAR) || ', fail 3 (src user not found in rule_from), id=' || CAST(r_obj.user_id AS VARCHAR) || ', uid=' || v_current_obj; - v_result := v_result || v_result_single || '; '; - RAISE NOTICE '%', v_result_single; - -- -- 1 2 3 4 5 6 7 - -- PERFORM add_data_issue(i_rule_last_seen, v_user_group, NULL, r_rule.rule_uid, r_rule.rule_id, i_dev_id, 'user in rule', - -- 'user in rule undefined', 'user "' || v_user_group || '" found in rule with UID ' || r_rule.rule_uid || ' could not be found'); - END IF; - END IF; - END IF; - -- end of user checks, no fixes here because they are done below - END IF; - IF r_rule.rule_from_zone IS NULL THEN - SELECT INTO r_obj obj_id FROM object WHERE obj_uid=v_current_obj AND mgm_id=i_mgm_id AND active; - ELSE - SELECT INTO r_obj obj_id FROM object WHERE obj_uid=v_current_obj AND (zone_id=r_rule.rule_from_zone) - AND mgm_id=i_mgm_id AND active; - IF NOT FOUND THEN -- last chance: global zone for juniper devices - SELECT INTO i_zone_id zone_id FROM zone WHERE (zone_name='global') AND zone.mgm_id=i_mgm_id; - IF FOUND THEN - SELECT INTO r_obj obj_id FROM object WHERE obj_uid=v_current_obj AND zone_id=i_zone_id AND - object.mgm_id=i_mgm_id AND object.active; - ELSE -- zone_id is null - pick any object with same name disregarding the zone - SELECT INTO r_obj obj_id FROM object WHERE obj_uid=v_current_obj AND object.mgm_id=i_mgm_id AND object.active; - END IF; - END IF; - END IF; - IF NOT FOUND THEN - v_result_single := 'mgmt ' || CAST(i_mgm_id AS VARCHAR) || ', dev ' || CAST(i_dev_id AS VARCHAR) || ', fail 4 (src obj_id not found at all): ' || v_current_obj; - v_result := v_result || v_result_single || '; '; - RAISE NOTICE '%', v_result_single; - -- -- 1 2 3 4 5 6 7 - -- PERFORM add_data_issue(i_rule_last_seen, v_current_obj, v_current_obj, r_rule.rule_uid, r_rule.rule_id, i_dev_id, 'source network object in rule', - -- 'non-existant source network object "' || v_current_obj || '" referenced in rule with UID ' || r_rule.rule_uid, NULL); - ELSE -- check if exactly one object is returned - IF (NOT COUNT(r_obj)=1) THEN - v_result_single := 'mgmt ' || CAST(i_mgm_id AS VARCHAR) || ', dev ' || CAST(i_dev_id AS VARCHAR) || ', fail 5 (not exactly one src obj found): ' || CAST(r_obj.obj_id AS VARCHAR) || ', COUNT=' || CAST(count(r_obj) AS VARCHAR); - v_result := v_result || v_result_single || '; '; - RAISE NOTICE '%', v_result_single; - ELSE - SELECT INTO r_debug rule_id,obj_id FROM rule_from WHERE rule_id=r_rule.rule_id AND obj_id=r_obj.obj_id AND active; - IF NOT FOUND THEN - v_result_single := 'mgmt ' || CAST(i_mgm_id AS VARCHAR) || ', dev ' || CAST(i_dev_id AS VARCHAR) || ', fail 6 (src obj not found in rule_from), id=' || CAST(r_obj.obj_id AS VARCHAR) || ', uid=' || v_current_obj; - v_result := v_result || v_result_single || '; '; - RAISE NOTICE '%', v_result_single; - -- -- 1 2 3 4 5 6 7 - -- PERFORM add_data_issue(i_rule_last_seen, v_user_group, NULL, r_rule.rule_uid, r_rule.rule_id, i_dev_id, 'user in rule', - -- 'no matching source network obj "' || r_obj.obj_uid || '" found in rule with UID ' || r_rule.rule_uid, NULL); - IF b_heal THEN -- healing: - IF v_user_group='' THEN -- no auth rule with user group - INSERT INTO rule_from (rule_id, obj_id, rf_create, rf_last_seen) - VALUES (r_rule.rule_id, r_obj.obj_id, r_rule.rule_create, r_rule.rule_last_seen); - ELSE -- auth rule with user group - INSERT INTO rule_from (rule_id, user_id, obj_id, rf_create, rf_last_seen) - VALUES (r_rule.rule_id, i_user_id, r_obj.obj_id, r_rule.rule_create, r_rule.rule_last_seen); - END IF; - END IF; - END IF; - END IF; - END IF; - END IF; - END LOOP; - END LOOP; - -- EXCEPTION WHEN OTHERS THEN - -- -- 1 2 3 4 5 6 7 - -- PERFORM add_data_issue(i_rule_last_seen, r_rule.rule_uid, r_rule.rule_uid, r_rule.rule_uid, r_rule.rule_id, i_dev_id, 'rule ref error', - -- 'exception raised while importing rule with UID "' || r_rule.rule_uid || '"', 'Unknown exception in get_active_rules_with_broken_src_refs_per_dev'); - -- RAISE EXCEPTION 'Unknown exception in get_active_rules_with_broken_src_refs_per_dev'; - -- END; - RETURN v_result; -END; -$$ LANGUAGE plpgsql; - -CREATE OR REPLACE FUNCTION get_active_rules_with_broken_dst_refs_per_dev (VARCHAR, BOOLEAN, INTEGER) RETURNS VARCHAR AS $$ -DECLARE - v_delimiter ALIAS FOR $1; - b_heal ALIAS FOR $2; - i_dev_id ALIAS FOR $3; - i_mgm_id INTEGER; - i_zone_id INTEGER; - i_rule_created BIGINT; - i_count INTEGER; - i_rule_last_seen BIGINT; - r_obj RECORD; - r_rule RECORD; - r_debug RECORD; - r_debug2 RECORD; - v_current_obj VARCHAR; - v_result VARCHAR; - v_result_single VARCHAR; - v_user_group VARCHAR; - i_user_id BIGINT; -BEGIN - v_result := ''; - FOR r_rule IN SELECT rule_id,rule_src, rule_dst, rule_svc, rule_src_refs, rule_dst_refs, rule_svc_refs, - rule_from_zone, rule_to_zone, rule_create, rule_last_seen - FROM rule WHERE dev_id=i_dev_id and active - LOOP - SELECT INTO i_mgm_id mgm_id FROM rule WHERE rule_id=r_rule.rule_id; - SELECT INTO i_rule_created rule_create FROM rule WHERE rule_id=r_rule.rule_id; - SELECT INTO i_rule_last_seen rule_last_seen FROM rule WHERE rule_id=r_rule.rule_id; - SELECT INTO i_zone_id rule_to_zone FROM rule WHERE rule_id=r_rule.rule_id; - - FOR v_current_obj IN SELECT obj FROM regexp_split_to_table(r_rule.rule_dst_refs, E'\\' || v_delimiter) AS obj - LOOP - SELECT INTO i_count count(*) FROM regexp_split_to_table(v_current_obj, '@'); - v_user_group := ''; - IF i_count=2 THEN -- AT in string - SELECT INTO v_user_group regexp_replace(v_current_obj, '@.*$', ''); - SELECT INTO v_current_obj regexp_replace(v_current_obj, '^.+@', ''); - SELECT INTO i_user_id user_id FROM usr WHERE user_uid=v_user_group AND mgm_id=i_mgm_id AND active; --- checking user refs - SELECT INTO r_obj user_id FROM usr WHERE user_uid=v_user_group AND mgm_id=i_mgm_id AND active; - IF NOT FOUND THEN - v_result_single := 'mgmt ' || CAST(i_mgm_id AS VARCHAR) || ', dev ' || CAST(i_dev_id AS VARCHAR) || ', fail 1 (dst user_id not found at all): ' || v_user_group; - v_result := v_result || v_result_single || '; '; - -- -- 1 2 3 4 5 6 7 - -- PERFORM add_data_issue(i_rule_last_seen, v_user_group, NULL, r_rule.rule_uid, r_rule.rule_id, i_dev_id, 'user in rule', - -- 'non-existant user obj "' || v_user_group || '" referenced in rule dst with UID ' || r_rule.rule_uid, NULL); - RAISE NOTICE '%', v_result_single; - ELSE -- check if exactly one object is returned - IF (NOT COUNT(r_obj)=1) THEN - v_result_single := 'mgmt ' || CAST(i_mgm_id AS VARCHAR) || ', dev ' || CAST(i_dev_id AS VARCHAR) || ', fail 2 (not exactly one dst obj found): ' || CAST(r_obj.user_id AS VARCHAR) || ', COUNT=' || CAST(count(r_obj) AS VARCHAR); - v_result := v_result || v_result_single || '; '; - RAISE NOTICE '%', v_result_single; - -- -- 1 2 3 4 5 6 7 - -- PERFORM add_data_issue(i_rule_last_seen, v_user_group, NULL, r_rule.rule_uid, r_rule.rule_id, i_dev_id, 'user in rule', - -- 'more than one matching user obj "' || v_user_group || '" found in rule dst with UID ' || r_rule.rule_uid, NULL); - ELSE - SELECT INTO r_debug rule_id,user_id FROM rule_to WHERE rule_id=r_rule.rule_id AND user_id=r_obj.user_id AND active; - IF NOT FOUND THEN - v_result_single := 'mgmt ' || CAST(i_mgm_id AS VARCHAR) || ', dev ' || CAST(i_dev_id AS VARCHAR) || ', fail 3 (dst user not found in rule_to), id=' || CAST(r_obj.user_id AS VARCHAR) || ', uid=' || v_current_obj; - v_result := v_result || v_result_single || '; '; - RAISE NOTICE '%', v_result_single; - -- -- 1 2 3 4 5 6 7 - -- PERFORM add_data_issue(i_rule_last_seen, v_user_group, NULL, r_rule.rule_uid, r_rule.rule_id, i_dev_id, 'user in rule', - -- 'user in rule undefined', 'user "' || v_user_group || '" found in rule with UID ' || r_rule.rule_uid || ' could not be found'); - END IF; - END IF; - END IF; - -- end of user checks, no fixes here because they are done below - END IF; - IF NOT (v_current_obj IS NULL OR v_current_obj='') THEN - IF r_rule.rule_to_zone IS NULL THEN - SELECT INTO r_obj obj_id FROM object WHERE obj_uid=v_current_obj AND mgm_id=i_mgm_id AND active; - ELSE - SELECT INTO r_obj obj_id FROM object WHERE obj_uid=v_current_obj AND (zone_id=r_rule.rule_to_zone) AND mgm_id=i_mgm_id AND active; - IF NOT FOUND THEN -- last chance: global zone - SELECT INTO i_zone_id zone_id FROM zone WHERE (zone_name='global') AND zone.mgm_id=i_mgm_id; - IF FOUND THEN - SELECT INTO r_obj obj_id FROM object WHERE obj_uid=v_current_obj AND zone_id=i_zone_id AND - object.mgm_id=i_mgm_id AND object.active; - ELSE -- zone_id is null - pick any object with same name disregarding the zone - SELECT INTO r_obj obj_id FROM object WHERE obj_uid=v_current_obj AND object.mgm_id=i_mgm_id AND object.active; - END IF; - END IF; - END IF; - IF NOT FOUND THEN -- dst object not found at all (in object table) - v_result_single := 'mgmt ' || CAST(i_mgm_id AS VARCHAR) || ', dev ' || CAST(i_dev_id AS VARCHAR) || ', fail 7 (dst object not found in object table): ' || v_current_obj; - v_result := v_result || v_result_single || '; '; - RAISE NOTICE '%', v_result_single; - ELSE -- check if exactly one object is returned - IF (NOT COUNT(r_obj)=1) THEN - v_result_single := 'mgmt ' || CAST(i_mgm_id AS VARCHAR) || ', dev ' || CAST(i_dev_id AS VARCHAR) || ', fail 8 (not exactly one dst obj found): ' || CAST(r_obj.obj_id AS VARCHAR) || ', COUNT=' || CAST(count(r_obj) AS VARCHAR); - v_result := v_result || v_result_single || '; '; - RAISE NOTICE '%', v_result_single; - ELSE - -- SELECT INTO r_debug rule_id,obj_id FROM rule_to WHERE rule_id=r_rule.rule_id AND obj_id=r_obj.obj_id AND active; - SELECT INTO r_debug rule_id,obj_id,rule_uid FROM rule_to LEFT JOIN rule USING (rule_id) WHERE rule_id=r_rule.rule_id AND obj_id=r_obj.obj_id AND rule.active AND rule_to.active; - IF NOT FOUND THEN - SELECT INTO r_debug2 obj_name FROM object WHERE obj_id=r_obj.obj_id; - v_result_single := 'mgmt ' || CAST(i_mgm_id AS VARCHAR) || ', dev ' || CAST(i_dev_id AS VARCHAR) || - ', fail 9 (dst object not found in rule_to table): object: ' || CAST(r_debug2.obj_name AS VARCHAR) || ', id=' || CAST(r_obj.obj_id AS VARCHAR) || ', rule_uid=' || CAST(r_debug.rule_uid AS VARCHAR); - v_result := v_result || v_result_single || '; '; - RAISE NOTICE '%', v_result_single; - IF b_heal THEN -- healing: - - IF v_user_group='' THEN -- no auth rule with user group - INSERT INTO rule_to (rule_id, obj_id, rt_create, rt_last_seen) - VALUES (r_rule.rule_id, r_obj.obj_id, r_rule.rule_create, r_rule.rule_last_seen); - ELSE -- auth rule with user group - INSERT INTO rule_from (rule_id, user_id, obj_id, rt_create, rt_last_seen) - VALUES (r_rule.rule_id, i_user_id, r_obj.obj_id, r_rule.rule_create, r_rule.rule_last_seen); - END IF; - END IF; - END IF; - END IF; - END IF; - END IF; - END LOOP; - END LOOP; - RETURN v_result; -END; -$$ LANGUAGE plpgsql; - -CREATE OR REPLACE FUNCTION get_active_rules_with_broken_svc_refs_per_dev (VARCHAR, BOOLEAN, INTEGER) RETURNS VARCHAR AS $$ -DECLARE - v_delimiter ALIAS FOR $1; - b_heal ALIAS FOR $2; - i_dev_id ALIAS FOR $3; - i_mgm_id INTEGER; - i_zone_id INTEGER; - i_rule_created BIGINT; - i_rule_last_seen BIGINT; - i_count INTEGER; - i_rule_count INTEGER; - i_ref_count INTEGER; - r_obj RECORD; - r_rule RECORD; - r_dev RECORD; - r_debug RECORD; - r_debug2 RECORD; - v_current_obj VARCHAR; - v_user_group VARCHAR; - i_user_id BIGINT; - v_result VARCHAR; - v_result_single VARCHAR; -BEGIN - v_result := ''; - FOR r_rule IN SELECT rule_id,rule_src, rule_dst, rule_svc, rule_src_refs, rule_dst_refs, rule_svc_refs, - rule_from_zone, rule_to_zone, rule_create, rule_last_seen - FROM rule WHERE dev_id=i_dev_id and active LOOP - SELECT INTO i_mgm_id mgm_id FROM rule WHERE rule_id=r_rule.rule_id; - SELECT INTO i_rule_created rule_create FROM rule WHERE rule_id=r_rule.rule_id; - SELECT INTO i_rule_last_seen rule_last_seen FROM rule WHERE rule_id=r_rule.rule_id; - - FOR v_current_obj IN SELECT obj FROM regexp_split_to_table(r_rule.rule_svc_refs, E'\\' || v_delimiter) AS obj LOOP - IF NOT (v_current_obj IS NULL OR v_current_obj='') THEN - SELECT INTO r_obj svc_id FROM service WHERE svc_uid=v_current_obj AND mgm_id=i_mgm_id AND active; - IF NOT FOUND THEN - v_result_single := 'mgmt ' || CAST(i_mgm_id AS VARCHAR) || ', dev ' || CAST(i_dev_id AS VARCHAR) || ', fail 10 (svc_id not found at all): ' || v_current_obj; - v_result := v_result || v_result_single || '; '; - RAISE NOTICE '%', v_result_single; - ELSE -- check if exactly one object is returned - IF (NOT COUNT(r_obj)=1) THEN - v_result_single := 'mgmt ' || CAST(i_mgm_id AS VARCHAR) || ', dev ' || CAST(i_dev_id AS VARCHAR) || ', fail 11 (not exactly one svc found): ' || CAST(r_obj.obj_id AS VARCHAR) || ', COUNT=' || CAST(count(r_obj) AS VARCHAR); - v_result := v_result || v_result_single || '; '; - RAISE NOTICE '%', v_result_single; - ELSE - SELECT INTO r_debug rule_id,svc_id FROM rule_service WHERE rule_id=r_rule.rule_id AND svc_id=r_obj.svc_id AND active; - IF NOT FOUND THEN - v_result_single := 'mgmt ' || CAST(i_mgm_id AS VARCHAR) || ', dev ' || CAST(i_dev_id AS VARCHAR) || ', fail 12 "svc not found": id=' || CAST(r_obj.svc_id AS VARCHAR) || ', uid=' || v_current_obj; - v_result := v_result || v_result_single || '; '; - RAISE NOTICE '%', v_result_single; - IF b_heal THEN -- healing: - INSERT INTO rule_service (rule_id, svc_id, rs_create, rs_last_seen) - VALUES (r_rule.rule_id, r_obj.svc_id, r_rule.rule_create, r_rule.rule_last_seen); - END IF; - END IF; - END IF; - END IF; - END IF; - END LOOP; - END LOOP; - RETURN v_result; -END; -$$ LANGUAGE plpgsql; diff --git a/roles/database/files/sql/idempotent/fworch-report-basics.sql b/roles/database/files/sql/idempotent/fworch-report-basics.sql deleted file mode 100644 index 4da7ea2e2f..0000000000 --- a/roles/database/files/sql/idempotent/fworch-report-basics.sql +++ /dev/null @@ -1,532 +0,0 @@ ----------------------------------------------------- --- generate report functions ----------------------------------------------------- -------- basics ------------ --- is_obj_group (obj_id) RETURNS BOOLEAN --- is_rule_src_negated (rule_id) RETURNS BOOLEAN --- is_rule_dst_negated (rule_id) RETURNS BOOLEAN --- explode_objgrp (obj_id,import_id) RETURNS SETOF INTEGER --- explode_objgrp (obj_id) RETURNS SETOF INTEGER --- get_previous_import_id (dev_id, time) --- get_previous_import_ids (time) --- get_matching_import_id(device_id, zeitpunkt) RETURNS INTEGER --- get_exploded_src_of_rule(rule_id,import_id) RETURNS SETOF INTEGER --- get_exploded_dst_of_rule(rule_id,import_id) RETURNS SETOF INTEGER --- get_mgmt_dev_list(name-of-REFCURSOR) RETURNS REFCURSOR - -------- advanced div ------------ --- get_rule_action (rule_id) RETURNS RECORD (action_id, action_name) --- DROP FUNCTION get_request_str(VARCHAR,BIGINT); -CREATE OR REPLACE FUNCTION get_request_str(VARCHAR,BIGINT) RETURNS VARCHAR AS $$ -DECLARE - v_table ALIAS FOR $1; - i_id ALIAS FOR $2; - r_request RECORD; - v_tbl VARCHAR; - v_result VARCHAR; - v_id_name VARCHAR; - v_sql_statement VARCHAR; -BEGIN - v_result := ''; - -- IF v_table='object' THEN v_tbl := 'obj'; END IF; - -- IF v_table='service' THEN v_tbl := 'svc'; END IF; - -- IF v_table='user' THEN v_tbl := 'usr'; END IF; - -- IF v_table='rule' THEN v_tbl := 'rule'; END IF; - -- v_id_name := 'log_' || v_tbl || '_id'; - -- v_sql_statement := 'SELECT request_number, tenant_name, request_type_name FROM request_' || - -- v_table || '_change LEFT JOIN request USING (request_id) LEFT JOIN tenant USING (tenant_id) ' || - -- ' LEFT JOIN request_type using (request_type_id) ' || - -- ' WHERE ' || v_id_name || '=' || CAST(i_id AS VARCHAR); - -- FOR r_request IN EXECUTE v_sql_statement - -- LOOP - -- IF v_result<>'' THEN v_result := v_result || '
'; END IF; - -- IF NOT r_request.tenant_name IS NULL THEN - -- v_result := v_result || r_request.tenant_name || ': '; - -- END IF; - -- IF NOT r_request.request_type_name IS NULL THEN - -- v_result := v_result || r_request.request_type_name || '-'; - -- END IF; - -- v_result := v_result || r_request.request_number; - - -- END LOOP; - RETURN v_result; -END; -$$ LANGUAGE plpgsql; - ----------------------------------------------------- --- FUNCTION: get_last_change_admin_of_rulebase_change(import_id, dev_id) --- Zweck: liefert den change_admin fuer einen Zeitpunkt und ein Device zurueck (fuer rule_deletes --- benoetigt fuer rule_deletes --- Annahme: ein Admin hat alle Rule-Changes an einer Rulebase zu einem Zeitpunkt gemacht --- Parameter1: import id --- Parameter2: device id --- RETURNS: id des change_admins --- - --- DROP FUNCTION get_last_change_admin_of_rulebase_change (BIGINT, INTEGER); -CREATE OR REPLACE FUNCTION get_last_change_admin_of_rulebase_change (BIGINT, INTEGER) RETURNS INTEGER AS -$BODY$ -DECLARE - i_import_id ALIAS FOR $1; - i_dev_id ALIAS FOR $2; - r_rule RECORD; - i_admin_counter INTEGER; -BEGIN - - SELECT INTO i_admin_counter COUNT(distinct import_admin) FROM changelog_rule - WHERE control_id=i_import_id AND dev_id=i_dev_id AND NOT import_admin IS NULL GROUP BY import_admin; - IF (i_admin_counter=1) THEN - SELECT INTO r_rule import_admin FROM changelog_rule - WHERE control_id=i_import_id AND dev_id=i_dev_id AND NOT import_admin IS NULL GROUP BY import_admin; --- RAISE NOTICE 'Found last_change_admin %', r_rule.import_admin; - IF FOUND THEN - RETURN r_rule.import_admin; - ELSE - RETURN NULL; - END IF; - ELSE - RETURN NULL; - END IF; -END; -$BODY$ - LANGUAGE 'plpgsql' VOLATILE; - ----------------------------------------------------- --- FUNCTION: get_last_change_admin_of_obj_delete(import_id, mgm_id) --- Zweck: liefert den change_admin fuer einen Import zurueck (fuer svc- nwobj u. usr_deletes --- benoetigt fuer obj / svc / usr _deletes --- Annahme: ein Admin hat alle Changes an einem Management zu einem Zeitpunkt gemacht --- wenn nicht, dann wird NULL zurueckgeliefert --- Parameter1: import id --- RETURNS: id des change_admins --- - --- DROP FUNCTION get_last_change_admin_of_obj_delete (BIGINT); -CREATE OR REPLACE FUNCTION get_last_change_admin_of_obj_delete (BIGINT) RETURNS INTEGER AS -$BODY$ -DECLARE - i_import_id ALIAS FOR $1; - r_obj RECORD; - i_admin_counter INTEGER; - i_admin_id INTEGER; -BEGIN - i_admin_counter := 0; - FOR r_obj IN - SELECT import_admin FROM changelog_object WHERE control_id=i_import_id AND NOT import_admin IS NULL - UNION - SELECT import_admin FROM changelog_service WHERE control_id=i_import_id AND NOT import_admin IS NULL - UNION - SELECT import_admin FROM changelog_user WHERE control_id=i_import_id AND NOT import_admin IS NULL - LOOP - i_admin_counter := i_admin_counter + 1; - i_admin_id := r_obj.import_admin; - END LOOP; - IF (i_admin_counter=1) THEN - RETURN i_admin_id; - ELSE - RETURN NULL; - END IF; -END; -$BODY$ -LANGUAGE 'plpgsql' VOLATILE; - ----------------------------------------------------- --- FUNCTION: get_mgmt_dev_list(name-of-refcursor) --- Zweck: liefert Cursor mit allen Managements und Devices zurueck (Name u. ID) --- Parameter1: Name des zurueckzuliefernden Pointers --- RETURNS: Cursor mit Tabelle (mgmt_id,mgmt_name,dev_id,dev_name,manufacturer) --- ---DROP FUNCTION get_mgmt_dev_list(REFCURSOR); -CREATE OR REPLACE FUNCTION get_mgmt_dev_list(REFCURSOR) RETURNS REFCURSOR AS $$ -DECLARE -BEGIN - OPEN $1 FOR - SELECT management.mgm_id,management.mgm_name,device.dev_id,device.dev_name,stm_dev_typ.dev_typ_manufacturer - FROM management, device, stm_dev_typ - WHERE management.mgm_id=device.mgm_id AND stm_dev_typ.dev_typ_id=device.dev_typ_id - ORDER BY dev_typ_manufacturer,mgm_name,dev_name; - RETURN $1; -END; -$$ LANGUAGE plpgsql; - ----------------------------------------------------- --- FUNCTION: get_mgmt_list(name-of-refcursor) --- Zweck: liefert Cursor mit allen Managements zurueck (Name u. ID) --- Parameter1: Name des zurueckzuliefernden Pointers --- RETURNS: Cursor mit Tabelle (mgmt_id,mgmt_name,manufacturer) --- - --- DROP FUNCTION get_mgmt_list(REFCURSOR); -CREATE OR REPLACE FUNCTION get_mgmt_list(REFCURSOR) RETURNS REFCURSOR AS $$ -DECLARE -BEGIN - OPEN $1 FOR - SELECT management.mgm_id,management.mgm_name,stm_dev_typ.dev_typ_manufacturer - FROM management, stm_dev_typ - WHERE management.dev_typ_id=stm_dev_typ.dev_typ_id - ORDER BY dev_typ_manufacturer,mgm_name; - RETURN $1; -END; -$$ LANGUAGE plpgsql; - ----------------------------------------------------- --- FUNCTION: get_dev_list(name-of-refcursor,mgm_id) --- Zweck: liefert Cursor mit allen Device-Ids der zum Management gehoerigen Devices zurueck (ID) --- Parameter1: Name des zurueckzuliefernden Pointers --- RETURNS: Cursor mit Tabelle (dev_id) --- --- DROP FUNCTION get_dev_list(REFCURSOR,INTEGER); -CREATE OR REPLACE FUNCTION get_dev_list(REFCURSOR,INTEGER) RETURNS REFCURSOR AS $$ -DECLARE - i_mgm_id ALIAS FOR $2; -BEGIN - OPEN $1 FOR - SELECT dev_id - FROM device - WHERE mgm_id=i_mgm_id; - RETURN $1; -END; -$$ LANGUAGE plpgsql; - ----------------------------------------------------- --- FUNCTION: get_report_typ_list(name-of-refcursor) --- Zweck: liefert Cursor mit allen Reporttypen zurueck (Name u. ID) --- Parameter1: Name des zurueckzuliefernden Pointers --- RETURNS: Cursor mit Tabelle (report_typ_id,report_typ_name) --- --- DROP FUNCTION get_report_typ_list(REFCURSOR); --- CREATE OR REPLACE FUNCTION get_report_typ_list(REFCURSOR) RETURNS REFCURSOR AS $$ --- DECLARE --- r_config RECORD; --- BEGIN --- SELECT INTO r_config * FROM config; --- IF r_config.language='german' THEN --- OPEN $1 FOR --- SELECT report_typ_id, report_typ_name --- FROM stm_report_typ --- ORDER BY report_typ_id; --- -- ORDER BY report_typ_name; --- ELSE --- OPEN $1 FOR --- SELECT report_typ_id, report_typ_name --- FROM stm_report_typ --- ORDER BY report_typ_id; --- -- ORDER BY report_typ_name; --- END IF; --- RETURN $1; --- END; --- $$ LANGUAGE plpgsql; - --- CREATE OR REPLACE FUNCTION get_report_typ_list(REFCURSOR) RETURNS REFCURSOR AS $$ --- DECLARE --- r_config RECORD; --- BEGIN --- SELECT INTO r_config * FROM config; --- OPEN $1 FOR --- SELECT report_typ_id,report_typ_name as report_typ_name --- FROM stm_report_typ --- ORDER BY report_typ_id; --- RETURN $1; --- END; --- $$ LANGUAGE plpgsql; - ----------------------------------------------------- --- FUNCTION: get_tenant_list(name-of-refcursor) --- Zweck: liefert Cursor mit allen tenants zurueck (Name u. ID) --- Parameter1: Name des zurueckzuliefernden Pointers --- Parameter2: tenant-Id fuer spaetere Anzeige direkt fuer tenant --- RETURNS: Cursor mit Tabelle (tenant_id,tenant_name) --- -CREATE OR REPLACE FUNCTION get_tenant_list(REFCURSOR) RETURNS REFCURSOR AS $$ -DECLARE -BEGIN - OPEN $1 FOR SELECT tenant_id,tenant_name FROM tenant ORDER BY tenant_name; - RETURN $1; -END; -$$ LANGUAGE plpgsql; - ----------------------------------------------------- --- FUNCTION: get_exploded_src_of_rule(rule_id) --- Zweck: liefert alle in den Quellen enthalten object IDs zurueck --- Zweck: auch fuer alle Gruppen rekursiv --- Parameter1: rule_id der Regel --- Parameter2: relevante import_id --- RETURNS: alle obj_ids als Tabelle --- -CREATE OR REPLACE FUNCTION get_exploded_src_of_rule(BIGINT) RETURNS SETOF BIGINT AS $$ -DECLARE - i_rule_id ALIAS FOR $1; --- i_import_id ALIAS FOR $2; - r_obj RECORD; - r_obj2 RECORD; -BEGIN - FOR r_obj IN - SELECT obj_id FROM rule_from WHERE rule_id=i_rule_id -- AND rf_create<=i_import_id AND rf_last_seen>=i_import_id - LOOP - FOR r_obj2 IN --- SELECT explode_objgrp AS obj_id FROM explode_objgrp(r_obj.obj_id,i_import_id) - SELECT explode_objgrp AS obj_id FROM explode_objgrp(r_obj.obj_id) - LOOP - RETURN NEXT r_obj2.obj_id; - END LOOP; - END LOOP; - RETURN; -END; -$$ LANGUAGE plpgsql; - ----------------------------------------------------- --- FUNCTION: get_exploded_dst_of_rule(rule_id,import_id) --- Zweck: liefert alle in den Zielen enthalten objeckt IDs zurueck --- Zweck: auch fuer alle Gruppen rekursiv --- Parameter1: rule_id der Regel --- Parameter1: relevante import_id --- RETURNS: alle obj_ids als Tabelle --- -CREATE OR REPLACE FUNCTION get_exploded_dst_of_rule(BIGINT) RETURNS SETOF BIGINT AS $$ -DECLARE - i_rule_id ALIAS FOR $1; --- i_import_id ALIAS FOR $2; - r_obj RECORD; - r_obj2 RECORD; -BEGIN - FOR r_obj IN - SELECT obj_id FROM rule_to WHERE rule_id=i_rule_id -- AND rt_create<=i_import_id AND rt_last_seen>=i_import_id - LOOP - FOR r_obj2 IN --- SELECT explode_objgrp AS obj_id FROM explode_objgrp(r_obj.obj_id,i_import_id) - SELECT explode_objgrp AS obj_id FROM explode_objgrp(r_obj.obj_id) - LOOP - RETURN NEXT r_obj2.obj_id; - END LOOP; - END LOOP; - RETURN; -END; -$$ LANGUAGE plpgsql; --- version ohne import_id ----------------------------------------------------- --- FUNCTION: get_exploded_dst_of_rule(rule_id) --- Zweck: liefert alle in den Zielen enthalten objeckt IDs zurueck --- Zweck: auch fuer alle Gruppen rekursiv --- Parameter1: rule_id der Regel --- RETURNS: alle obj_ids als Tabelle --- -CREATE OR REPLACE FUNCTION get_exploded_dst_of_rule(BIGINT) RETURNS SETOF BIGINT AS $$ -DECLARE - i_rule_id ALIAS FOR $1; - r_obj RECORD; - r_obj2 RECORD; -BEGIN - FOR r_obj IN - SELECT obj_id FROM rule_to WHERE rule_id=i_rule_id -- AND rt_create<=i_import_id AND rt_last_seen>=i_import_id - LOOP - FOR r_obj2 IN --- SELECT explode_objgrp AS obj_id FROM explode_objgrp(r_obj.obj_id,i_import_id) - SELECT explode_objgrp AS obj_id FROM explode_objgrp(r_obj.obj_id) - LOOP - RETURN NEXT r_obj2.obj_id; - END LOOP; - END LOOP; - RETURN; -END; -$$ LANGUAGE plpgsql; - ----------------------------------------------------- --- FUNCTION: get_previous_import_id(devid, zeitpunkt) --- Zweck: liefert zu einem Device + Zeitpunkt die Import ID des vorherigen Imports --- Parameter1: Device_id (INTEGER) --- Parameter2: Time (timestamp) --- RETURNS: ID des vorherigen Imports --- -CREATE OR REPLACE FUNCTION get_previous_import_id(INTEGER,TIMESTAMP) RETURNS BIGINT AS $$ -DECLARE - i_device_id ALIAS FOR $1; - t_report_time_in ALIAS FOR $2; - t_report_time TIMESTAMP; - i_mgm_id INTEGER; - i_prev_import_id BIGINT; -BEGIN - IF t_report_time_in IS NULL THEN - t_report_time := now(); - ELSE - t_report_time := t_report_time_in; - END IF; - SELECT INTO i_mgm_id mgm_id FROM device WHERE dev_id=i_device_id; - SELECT INTO i_prev_import_id max(control_id) FROM import_control WHERE mgm_id=i_mgm_id AND - start_time<=t_report_time AND NOT stop_time IS NULL AND successful_import; - IF NOT FOUND THEN - RETURN NULL; - ELSE --- RAISE NOTICE 'found get_previous_import_id: %', i_prev_import_id; - RETURN i_prev_import_id; - END IF; -END; -$$ LANGUAGE plpgsql; - ----------------------------------------------------- --- FUNCTION: get_previous_import_ids(time) --- Zweck: liefert zu einem Zeitpunkt die Import ID aller Systeme des vorherigen Imports --- Parameter1: Time (timestamp) --- RETURNS: string mit Import-Ids, eg.: (1, 2, 5, 7) --- -CREATE OR REPLACE FUNCTION get_previous_import_ids(TIMESTAMP) RETURNS VARCHAR AS $$ -DECLARE - t_report_time_in ALIAS FOR $1; - t_report_time TIMESTAMP; - i_mgm_id INTEGER; - r_dev RECORD; - v_id_string VARCHAR; - i_prev_import_id BIGINT; -BEGIN - IF t_report_time_in IS NULL THEN - t_report_time := now(); - ELSE - t_report_time := t_report_time_in; - END IF; - v_id_string := ' ('; - FOR r_dev IN - SELECT dev_id FROM device - LOOP - i_prev_import_id := get_previous_import_id(r_dev.dev_id, t_report_time); - IF NOT i_prev_import_id IS NULL THEN - IF NOT v_id_string=' (' THEN - v_id_string := v_id_string || ', '; - END IF; - v_id_string := v_id_string || CAST(i_prev_import_id AS VARCHAR); - END IF; - END LOOP; - v_id_string := v_id_string || ') '; - RETURN v_id_string; -END; -$$ LANGUAGE plpgsql; - ----------------------------------------------------- --- FUNCTION: get_next_import_id($devid) --- Zweck: liefert zu einem Device + Zeitpunkt die Import ID des naechst folgenden Imports --- Parameter1: Device_id (INTEGER) --- Parameter2: Time (timestamp) --- RETURNS: ID des naechsten Imports --- -CREATE OR REPLACE FUNCTION get_next_import_id(INTEGER,TIMESTAMP) RETURNS BIGINT AS $$ -DECLARE - i_device_id ALIAS FOR $1; - t_report_time_in ALIAS FOR $2; - t_report_time TIMESTAMP; - i_mgm_id INTEGER; - i_next_import_id BIGINT; -BEGIN - IF t_report_time_in IS NULL THEN - t_report_time := now(); - ELSE - t_report_time := t_report_time_in; - END IF; - SELECT INTO i_mgm_id mgm_id FROM device WHERE dev_id=i_device_id; - SELECT INTO i_next_import_id min(control_id) FROM import_control WHERE mgm_id=i_mgm_id - AND start_time>=t_report_time AND NOT stop_time IS NULL AND successful_import; - RETURN i_next_import_id; -END; -$$ LANGUAGE plpgsql; - ----------------------------------------------------- --- FUNCTION: get_matching_import_id --- Zweck: liefert zu einem Zeitpunkt die ID des unmittelbar davor --- Zweck: stattgefunden habenden Imports fuer das Device zurueck --- Parameter1: Device_id (INTEGER) --- Parameter2: Zeitpunkt (TIMESTAMP) --- RETURNS: ID des Imports --- -CREATE OR REPLACE FUNCTION get_matching_import_id(INTEGER, TIMESTAMP) RETURNS BIGINT AS $$ -DECLARE - i_device_id ALIAS FOR $1; - t_report_time_in ALIAS FOR $2; - i_import_id BIGINT; - i_mgm_id INTEGER; - t_report_time TIMESTAMP; -BEGIN - IF t_report_time_in IS NULL THEN - t_report_time := now(); - ELSE t_report_time := t_report_time_in; - END IF; - SELECT INTO i_mgm_id mgm_id FROM device WHERE dev_id=i_device_id; - SELECT INTO i_import_id control_id FROM import_control - WHERE mgm_id=i_mgm_id AND start_time<=t_report_time AND NOT stop_time IS NULL AND successful_import -- get only completed imports - ORDER BY control_id desc - LIMIT 1; --- RAISE EXCEPTION 'device_id: %, time: %, import_id: %', i_device_id, t_report_time, i_import_id; - RETURN i_import_id; -END; -$$ LANGUAGE plpgsql; - ----------------------------------------------------- --- FUNCTION: explode_objgrp --- Zweck: liefert alle obj_ids die in der Gruppe (auch rekursiv) enthalten sind, zurueck --- Zweck: wenn keine Gruppe, dann nur das object selbst --- Parameter1: obj_id --- RETURNS: wahr, wenn das Komplement von object zum tenant mit tenant_id gehoert --- -CREATE OR REPLACE FUNCTION explode_objgrp (BIGINT) RETURNS SETOF BIGINT AS $$ -DECLARE - i_obj_id ALIAS FOR $1; - r_obj RECORD; -- zu pruefendes Objekt -BEGIN - IF is_obj_group(i_obj_id) THEN -- keine Gruppe - FOR r_obj IN - SELECT objgrp_flat_member_id FROM object LEFT JOIN objgrp_flat ON objgrp_flat_id=object.obj_id - WHERE object.obj_id=i_obj_id - LOOP - RETURN NEXT r_obj.objgrp_flat_member_id; - END LOOP; - ELSE -- Gruppe - RETURN NEXT i_obj_id; - END IF; - RETURN; -END; -$$ LANGUAGE plpgsql; - ----------------------------------------------------- --- FUNCTION: is_rule_src_negated --- Zweck: liefert TRUE, wenn die Quelle der Regel negiert ist --- Parameter1: rule_id --- RETURNS: BOOLEAN --- -CREATE OR REPLACE FUNCTION is_rule_src_negated (BIGINT) RETURNS BOOLEAN AS $$ -DECLARE - i_rule_id ALIAS FOR $1; - r_rule_src_neg BOOLEAN; -- result -BEGIN - SELECT INTO r_rule_src_neg rule_src_neg FROM rule WHERE rule_id=i_rule_id; - RETURN r_rule_src_neg; -END; -$$ LANGUAGE plpgsql; - ----------------------------------------------------- --- FUNCTION: is_rule_dst_negated --- Zweck: liefert TRUE, wenn das Ziel der Regel negiert ist --- Parameter1: rule_id --- RETURNS: BOOLEAN --- -CREATE OR REPLACE FUNCTION is_rule_dst_negated (BIGINT) RETURNS BOOLEAN AS $$ -DECLARE - i_rule_id ALIAS FOR $1; - r_rule_dst_neg BOOLEAN; -- result -BEGIN - SELECT INTO r_rule_dst_neg rule_dst_neg FROM rule WHERE rule_id=i_rule_id; - RETURN r_rule_dst_neg; -END; -$$ LANGUAGE plpgsql; - ----------------------------------------------------- --- FUNCTION: get_rule_action --- Zweck: liefert die Aktion der Regel zur Anzeige (als ID und als String) --- Parameter1: rule_id --- RETURNS: action_id und string der Aktion --- -CREATE OR REPLACE FUNCTION get_rule_action (BIGINT) RETURNS RECORD AS $$ -DECLARE - i_rule_id ALIAS FOR $1; - r_rule RECORD; -- record to be returned -BEGIN - SELECT INTO r_rule rule.action_id,action_name FROM rule,stm_action - WHERE rule.action_id=stm_action.action_id AND rule_id=i_rule_id; - RETURN r_rule; -END; -$$ LANGUAGE plpgsql; \ No newline at end of file diff --git a/roles/database/files/sql/idempotent/fworch-report.sql b/roles/database/files/sql/idempotent/fworch-report.sql deleted file mode 100644 index c8d18034c6..0000000000 --- a/roles/database/files/sql/idempotent/fworch-report.sql +++ /dev/null @@ -1,1095 +0,0 @@ --- $Id: iso-report.sql,v 1.1.2.7 2012-05-28 10:32:56 tim Exp $ --- $Source: /home/cvs/iso/package/install/database/Attic/iso-report.sql,v $ - ----------------------------------------------------- --- Filterfunktionen zum Generieren von Reports ----------------------------------------------------- --- get_tenant_ip_filter(tenant_id) RETURNS VARCHAR --- get_negated_tenant_ip_filter(tenant_id) RETURNS VARCHAR - --- get_obj_ids_of_filtered_ruleset(INTEGER[]) RETURNS SETOF INTEGER - --- get_rule_ids(device_id, zeitpunkt, tenant_id) RETURNS SETOF INTEGER --- get_rule_ids(device_id, zeitpunkt, tenant_id, src_ip, dst_ip, any_ip, proto, port) RETURNS SETOF INTEGER --> for rulesearch - --- rule_src_contains_tenant_obj (rule_id, tenant_id) RETURNS BOOLEAN --- rule_dst_contains_tenant_obj (rule_id, tenant_id) RETURNS BOOLEAN --- obj_belongs_to_tenant (obj_id, tenant_id) RETURNS BOOLEAN --- obj_neg_belongs_to_tenant (obj_id, tenant_id) RETURNS BOOLEAN - --- get_rule_src (rule_id, tenant_id) RETURNS SETOF INTEGER --- get_rule_dst (rule_id, tenant_id) RETURNS SETOF INTEGER - --- get_tenant_relevant_changes(tenant-ID, management-id, device-id, startzeit, stopzeit) --- unterfunktionen von get_tenant_relevant_changes: - -- get_svc_ids_of_tenant(tenant, array_of_rule_ids) RETURNS SETOF INTEGER - -- get_user_ids_of_tenant(tenant, array_of_rule_ids) RETURNS SETOF INTEGER - -- get_obj_ids_of_tenant(tenant, array_of_rule_ids) RETURNS SETOF INTEGER - ----------------------------------------------------- --- FUNCTION: get_tenant_relevant_changes --- Zweck: liefert zu einem tenant alle Changes zurueck, die in fuer ihn relevanten sind --- Parameter1: tenant-ID des zu betrachtenden tenants --- Parameter2: managment-id --- Parameter3: device-id --- Parameter4: startzeit --- Parameter5: stopzeit - --- RETURNS: Menge der relevanten Changes (abs_change_id : set of integer) --- --- CREATE OR REPLACE FUNCTION get_tenant_relevant_changes(INTEGER, INTEGER, INTEGER, TIMESTAMP, TIMESTAMP) RETURNS SETOF BIGINT AS $$ --- DECLARE --- i_tenant_id ALIAS FOR $1; --- i_mgm_id ALIAS FOR $2; --- i_dev_id ALIAS FOR $3; --- t_start ALIAS FOR $4; --- t_end ALIAS FOR $5; --- r_change RECORD; --- v_sql VARCHAR; --- BEGIN --- -- delete content of temp table anf fill it again with all rule_ids of the requested tenant --- DELETE FROM temp_table_for_tenant_filtered_rule_ids; --- INSERT INTO temp_table_for_tenant_filtered_rule_ids SELECT rule_id FROM view_tenant_rules WHERE tenant_id=i_tenant_id; --- v_sql := 'SELECT abs_change_id FROM view_changes_by_changed_element_id WHERE TRUE'; --- -- apply filter criteria if set --- IF NOT i_mgm_id=NULL THEN v_sql := v_sql || ' AND mgm_id=' || i_mgm_id; END IF; --- IF NOT i_dev_id=NULL THEN v_sql := v_sql || ' AND dev_id=' || i_dev_id; END IF; --- IF NOT t_start=NULL THEN v_sql := v_sql || ' AND change_time>=' || t_start; END IF; --- IF NOT t_end=NULL THEN v_sql := v_sql || ' AND change_time<=' || t_end; END IF; --- -- now the various individual change elements --- v_sql := v_sql || ' AND ((change_element=''service'' and element_id in (select * from get_svc_ids_for_tenant())) ' || --- 'OR (change_element=''user'' and element_id in (select * from get_user_ids_for_tenant())) ' || --- 'OR (change_element=''object'' and element_id in (select * from get_obj_ids_for_tenant())) ' || --- 'OR (change_element=''rule'' and element_id in (select * from temp_table_for_tenant_filtered_rule_ids))' || --- ') GROUP BY abs_change_id'; --- FOR r_change IN EXECUTE v_sql --- LOOP --- RETURN NEXT r_change.abs_change_id; --- END LOOP; --- RETURN; --- END; --- $$ LANGUAGE plpgsql; - ----------------------------------------------------- --- FUNCTION: get_svc_ids_of_tenant --- Zweck: liefert zu einem tenant alle dienste zurueck, die in fuer ihn relevanten regeln vorkommen --- Annahme: die Menge der Regeln steht in temp_table_for_tenant_filtered_rule_ids --- RETURNS: Menge der Dienst-IDs (svc_id) --- --- CREATE OR REPLACE FUNCTION get_svc_ids_for_tenant() RETURNS SETOF BIGINT AS $$ --- DECLARE --- r_svc RECORD; --- BEGIN --- FOR r_svc IN --- SELECT service.svc_id FROM rule --- LEFT JOIN rule_service USING (rule_id) --- LEFT JOIN svcgrp_flat ON (rule_service.svc_id=svcgrp_flat_id) --- LEFT JOIN service ON (svcgrp_flat_member_id=service.svc_id) --- WHERE rule.rule_id IN (SELECT rule_id FROM temp_table_for_tenant_filtered_rule_ids) --- GROUP BY service.svc_id --- LOOP --- RETURN NEXT r_svc.svc_id; --- END LOOP; --- RETURN; --- END; --- $$ LANGUAGE plpgsql; - ----------------------------------------------------- --- FUNCTION: get_user_ids_of_tenant --- Zweck: liefert zu einem tenant alle User zurueck, die in fuer ihn relevanten regeln vorkommen --- Annahme: die Menge der Regeln steht in temp_table_for_tenant_filtered_rule_ids --- RETURNS: Menge der User-IDs (user_id) --- -- --- CREATE OR REPLACE FUNCTION get_user_ids_for_tenant() RETURNS SETOF BIGINT AS $$ --- DECLARE --- r_user RECORD; --- BEGIN --- FOR r_user IN --- SELECT usr.user_id FROM rule --- LEFT JOIN rule_from USING (rule_id) --- LEFT JOIN usergrp_flat ON (rule_user.user_id=usergrp_flat_id) --- LEFT JOIN usr ON (usergrp_flat_member_id=usr.user_id) --- WHERE rule.rule_id IN (SELECT rule_id FROM temp_table_for_tenant_filtered_rule_ids) --- GROUP BY usr.user_id --- LOOP --- RETURN NEXT r_user.user_id; --- END LOOP; --- RETURN; --- END; --- $$ LANGUAGE plpgsql; - ----------------------------------------------------- --- FUNCTION: get_obj_ids_of_tenant --- Zweck: liefert zu einem tenant alle NW-Objekte zurueck, die in fuer ihn relevanten regeln vorkommen --- Annahme: die Menge der Regeln steht in temp_table_for_tenant_filtered_rule_ids --- RETURNS: Menge der object-IDs (obj_id) --- --- CREATE OR REPLACE FUNCTION get_obj_ids_for_tenant() RETURNS SETOF BIGINT AS $$ --- DECLARE --- r_obj RECORD; --- BEGIN --- FOR r_obj IN --- SELECT object.obj_id FROM rule --- LEFT JOIN rule_from USING (rule_id) --- LEFT JOIN objgrp_flat ON (rule_from.obj_id=objgrp_flat_id) --- LEFT JOIN object ON (objgrp_flat_member_id=object.obj_id) --- WHERE rule.rule_id IN (SELECT rule_id FROM temp_table_for_tenant_filtered_rule_ids) --- UNION --- SELECT object.obj_id FROM rule --- LEFT JOIN rule_to USING (rule_id) --- LEFT JOIN objgrp_flat ON (rule_to.obj_id=objgrp_flat_id) --- LEFT JOIN object ON (objgrp_flat_member_id=object.obj_id) --- WHERE rule.rule_id IN (SELECT rule_id FROM temp_table_for_tenant_filtered_rule_ids) --- GROUP BY object.obj_id --- LOOP --- RETURN NEXT r_obj.obj_id; --- END LOOP; --- RETURN; --- END; --- $$ LANGUAGE plpgsql; - ----------------------------------------------------- --- FUNCTION: get_tenant_ip_filter --- Zweck: liefert zu einem tenant einen Filter-String --- Parameter1: tenant-ID des zu betrachtenden tenants --- RETURNS: String mit booleschem Ausdruck fuer SQL-Where-Clause --- -CREATE OR REPLACE FUNCTION get_tenant_ip_filter(INTEGER) RETURNS VARCHAR AS $$ -DECLARE - i_tenant_id ALIAS FOR $1; - v_filter VARCHAR; - r_tenant_net RECORD; -BEGIN - IF i_tenant_id IS NULL THEN - RETURN 'TRUE'; - ELSE - v_filter := '('; - FOR r_tenant_net IN - SELECT tenant_net_ip FROM tenant_network WHERE tenant_id=i_tenant_id - LOOP - v_filter := v_filter || ' obj_ip<<=' || E'\'' || - CAST (r_tenant_net.tenant_net_ip AS VARCHAR) || E'\'' || ' OR ' || E'\'' || - CAST (r_tenant_net.tenant_net_ip AS VARCHAR) || E'\'' || '<<=obj_ip OR'; - END LOOP; - v_filter := v_filter || ' FALSE)'; --- RAISE INFO 'tenant-filter: %', v_filter; - RETURN v_filter; - END IF; -END; -$$ LANGUAGE plpgsql; - - ----------------------------------------------------- --- FUNCTION: get_ip_filter --- Zweck: liefert zu einer IP-Adresse einen Filter-String --- Parameter1: IP-Adresse (auch Netzbereich) --- RETURNS: String mit booleschem Ausdruck fuer SQL-Where-Clause --- -CREATE OR REPLACE FUNCTION get_ip_filter(CIDR) RETURNS VARCHAR AS $$ -DECLARE - c_ip_filter ALIAS FOR $1; - v_filter VARCHAR; -BEGIN - IF c_ip_filter IS NULL THEN - RETURN ' TRUE '; - ELSE - v_filter := ' ( obj_ip<<=' || E'\'' || - CAST (c_ip_filter AS VARCHAR) || E'\'' || ' OR ' || E'\'' || - CAST (c_ip_filter AS VARCHAR) || E'\'' || '<<=obj_ip ) '; --- RAISE INFO 'ip-filter: %', v_filter; - RETURN v_filter; - END IF; -END; -$$ LANGUAGE plpgsql; ----------------------------------------------------- --- FUNCTION: get_negated_tenant_ip_filter --- Zweck: liefert zu einem tenant einen Filter-String --- Zweck: fuer ngegierte Regelteile (Quelle oder Ziel) --- Parameter1: tenant-ID des zu betrachtenden tenants --- RETURNS: String mit booleschem Ausdruck fuer SQL-Where-Clause --- -CREATE OR REPLACE FUNCTION get_negated_tenant_ip_filter(INTEGER) RETURNS VARCHAR AS $$ -DECLARE - i_tenant_id ALIAS FOR $1; - v_filter VARCHAR; - r_tenant_net RECORD; -BEGIN - IF i_tenant_id IS NULL THEN - RETURN 'TRUE'; - ELSE - v_filter := '('; - FOR r_tenant_net IN - SELECT tenant_net_ip FROM tenant_network WHERE tenant_id=i_tenant_id - LOOP - v_filter := v_filter || 'NOT(obj_ip<<=' || E'\'' || - CAST (r_tenant_net.tenant_net_ip AS VARCHAR) || E'\'' || ') AND NOT(' || E'\'' || - CAST (r_tenant_net.tenant_net_ip AS VARCHAR) || E'\'' || '<<=obj_ip) AND '; - END LOOP; - v_filter := v_filter || ' TRUE)'; --- RAISE INFO 'tenant-filter: %', v_filter; - RETURN v_filter; - END IF; -END; -$$ LANGUAGE plpgsql; - - ----------------------------------------------------- --- FUNCTION: get_obj_ids_of_filtered_ruleset --- Zweck: liefert Tabelle mit allen Object-IDs zurueck, --- Zweck: die in den Zielen oder Quellen der Regeln vorkommen --- Parameter1: Array mit allen Rule_IDs --- Parameter2: import_id --- Parameter3: tenant-ID des Kunden, fuer den der Report generiert werden soll --- Parameter3: wenn NULL: keine Kunden-Filterung: liefere alle Regeln --- RETURNS: Tabelle mit einer Spalte (obj_id) --- --- CREATE OR REPLACE FUNCTION get_obj_ids_of_filtered_ruleset(BIGINT[], INTEGER, TIMESTAMP) RETURNS SETOF BIGINT AS $$ --- DECLARE --- ar_rule_ids ALIAS FOR $1; --- i_tenant ALIAS FOR $2; --- t_time ALIAS FOR $3; --- r_rule RECORD; --- r_obj RECORD; --- BEGIN --- FOR r_rule IN --- SELECT rule_id FROM rule WHERE rule_id = ANY (ar_rule_ids) --- LOOP --- FOR r_obj IN --- ( --- ( --- -- SELECT get_rule_src AS obj_id FROM get_rule_src(r_rule.rule_id,i_import_id,i_tenant) --- SELECT get_rule_src AS obj_id FROM get_rule_src(r_rule.rule_id,i_tenant,t_time) --- ) --- UNION --- ( --- -- SELECT get_rule_dst AS obj_id FROM get_rule_dst(r_rule.rule_id,i_import_id,i_tenant) --- SELECT get_rule_dst AS obj_id FROM get_rule_dst(r_rule.rule_id,i_tenant,t_time) --- ) --- ) -- GROUP BY obj_id ORDER BY obj_id --- LOOP --- RETURN NEXT r_obj.obj_id; --- END LOOP; --- END LOOP; --- RETURN; --- END; --- $$ LANGUAGE plpgsql; - ----------------------------------------------------- --- FUNCTION: get_obj_ids_of_filtered_ruleset_flat --- Zweck: liefert Tabelle mit allen Object-IDs zurueck, --- Zweck: die in den Zielen oder Quellen der Regeln vorkommen --- Zweck: plus alle Objekte, die in den Gruppen dort stecken --- Parameter1: Array mit allen Rule_IDs --- Parameter2: import_id --- Parameter3: tenant-ID des Kunden, fuer den der Report generiert werden soll --- Parameter3: wenn NULL: keine Kunden-Filterung: liefere alle Regeln --- RETURNS: Tabelle mit einer Spalte (obj_id) --- --- CREATE OR REPLACE FUNCTION get_obj_ids_of_filtered_ruleset_flat(INTEGER[], INTEGER, TIMESTAMP) RETURNS SETOF INTEGER AS $$ --- DECLARE --- ar_rule_ids ALIAS FOR $1; --- i_tenant ALIAS FOR $2; --- t_time ALIAS FOR $3; --- r_rule RECORD; --- r_obj RECORD; --- BEGIN --- FOR r_rule IN --- SELECT rule_id FROM rule WHERE rule_id = ANY (ar_rule_ids) --- LOOP --- FOR r_obj IN --- ( --- SELECT get_rule_src_flat AS obj_id FROM get_rule_src_flat(r_rule.rule_id,i_tenant,t_time) --- UNION --- SELECT get_rule_dst_flat AS obj_id FROM get_rule_dst_flat(r_rule.rule_id,i_tenant,t_time) --- ) --- LOOP --- RETURN NEXT r_obj.obj_id; --- END LOOP; --- END LOOP; --- RETURN; --- END; --- $$ LANGUAGE plpgsql; - ----------------------------------------------------- --- FUNCTION: get_obj_ids_of_filtered_management --- Zweck: liefert Tabelle mit allen Object-IDs des Managements zurueck, --- Zweck: die in den Filterkriterien (tenant und Zeitpunkt) gen�gen --- Parameter1: ID des Managements --- Parameter2: import_id --- Parameter3: tenant-ID des Kunden, fuer den der Report generiert werden soll --- Parameter3: wenn NULL: keine Kunden-Filterung: liefere alle Regeln --- RETURNS: Tabelle mit einer Spalte (obj_id) --- -CREATE OR REPLACE FUNCTION get_obj_ids_of_filtered_management(INTEGER, BIGINT, INTEGER) RETURNS SETOF BIGINT AS $$ -DECLARE - i_mgm_id ALIAS FOR $1; - i_import_id ALIAS FOR $2; - i_tenant ALIAS FOR $3; - r_obj RECORD; - v_sql_code VARCHAR; - v_filter VARCHAR; -BEGIN - IF NOT i_tenant IS NULL THEN - v_filter := get_tenant_ip_filter(i_tenant); - v_sql_code := 'SELECT obj_id FROM object WHERE mgm_id=' || i_mgm_id || ' AND obj_create<=' || i_import_id || - ' AND obj_last_seen>=' || i_import_id || ' AND ' || v_filter; --- RAISE NOTICE 'sql_code: %', v_sql_code; - FOR r_obj IN EXECUTE v_sql_code - LOOP - RETURN NEXT r_obj.obj_id; - END LOOP; - ELSE - FOR r_obj IN - SELECT obj_id FROM object WHERE mgm_id=i_mgm_id AND obj_create<=i_import_id AND obj_last_seen>=i_import_id - LOOP - RETURN NEXT r_obj.obj_id; - END LOOP; - END IF; - RETURN; -END; -$$ LANGUAGE plpgsql; - - --- CREATE OR REPLACE FUNCTION get_rule_ids_no_tenant_filter(int4, "timestamp", cidr, cidr, cidr, int4, int4, VARCHAR) --- RETURNS SETOF int4 AS --- $BODY$ --- DECLARE --- i_device_id ALIAS FOR $1; --- t_in_report_time ALIAS FOR $2; --- -- i_tenant_id ALIAS FOR $3; --- c_ip_src ALIAS FOR $3; --- c_ip_dst ALIAS FOR $4; --- c_ip_anywhere ALIAS FOR $5; --- i_proto ALIAS FOR $6; --- i_port ALIAS FOR $7; --- v_admin_view_filter ALIAS FOR $8; --- i_relevant_import_id BIGINT; -- ID des Imports, direkt vor dem Report-Zeitpunkt --- v_tenant_filter_ip_list VARCHAR; -- Filter-Liste mit allen IP-Bereichen des tenants --- v_tenant_filter_ip_list_negated VARCHAR; -- Filter-Liste mit allen IP-Bereichen des tenants fuer negierte Faelle --- r_rule RECORD; -- temp. Variable fuer Rule-ID --- t_report_time TIMESTAMP; -- Zeitpunkt des Reports (jetzt, wenn t_in_report_time IS NULL) --- v_sql_get_rules_with_tenant_src_ips VARCHAR; -- SQL-Code zum Holen der Rule-IDs mit Quellen im tenant-Bereich --- v_sql_get_rules_with_tenant_dst_ips VARCHAR; -- SQL-Code zum Holen der Rule-IDs mit Zielen im tenant-Bereich --- v_error_str VARCHAR; --- v_dev_filter VARCHAR; -- filter for devices (true for all devices) --- v_import_filter VARCHAR; -- filter for imports --- v_select_statement VARCHAR; --- v_order_statement VARCHAR; --- v_src_ip_filter VARCHAR; -- Filter fuer source ip match --- v_dst_ip_filter VARCHAR; -- Filter fuer destination ip match --- BEGIN --- v_order_statement := ''; --- IF t_in_report_time IS NULL THEN t_report_time := now(); -- no report time given, assuming now() --- ELSE t_report_time := t_in_report_time; END IF; --- -- set filter: a) import filter, b) device filter --- IF i_device_id IS NULL THEN -- ueber alle Devices --- v_import_filter := get_previous_import_ids(t_report_time); --- IF v_import_filter = ' () ' THEN v_import_filter := ' FALSE '; --- ELSE v_import_filter := 'rule_order.control_id IN ' || get_previous_import_ids(t_report_time); END IF; --- v_dev_filter := ' TRUE '; --- ELSE --- i_relevant_import_id := get_previous_import_id(i_device_id, t_report_time); --- IF i_relevant_import_id IS NULL THEN --- v_error_str := 'device_id: ' || CAST(i_device_id AS VARCHAR) || ', time: ' || CAST(t_report_time AS VARCHAR); --- PERFORM error_handling('WARN_NO_IMP_ID_FOUND', v_error_str); --- v_import_filter := ' FALSE '; --- ELSE --- v_import_filter := 'rule_order.control_id = ' || CAST(i_relevant_import_id AS VARCHAR); --- END IF; --- v_dev_filter := 'rule_order.dev_id = ' || CAST(i_device_id AS VARCHAR); --- END IF; --- IF c_ip_src IS NULL THEN v_src_ip_filter := ' TRUE '; --- ELSE v_src_ip_filter := ' (object.obj_ip <<= ' || E'\'' || CAST(c_ip_src AS VARCHAR) || E'\'' || ' OR object.obj_ip >>= ' || E'\'' || CAST(c_ip_src AS VARCHAR) || E'\'' || ') '; END IF; --- IF c_ip_dst IS NULL THEN v_dst_ip_filter := ' TRUE '; --- ELSE v_dst_ip_filter := ' (object.obj_ip <<= ' || E'\'' || CAST(c_ip_dst AS VARCHAR) || E'\'' || ' OR object.obj_ip >>= ' || E'\'' || CAST(c_ip_dst AS VARCHAR) || E'\'' || ') '; END IF; --- v_select_statement := --- ' (SELECT rule_id FROM rule_order LEFT JOIN rule USING (rule_id) LEFT JOIN rule_from USING (rule_id) LEFT JOIN objgrp_flat ON (rule_from.obj_id=objgrp_flat_member_id) ' || --- ' LEFT JOIN object ON (objgrp_flat_member_id=object.obj_id) WHERE ' || v_import_filter || ' AND ' || v_dev_filter || --- ' AND ' || v_src_ip_filter || ' AND ' || v_admin_view_filter || ' AND rule.rule_head_text IS NULL AND NOT rule_disabled AND rule_action<>' || --- E'\'' || 'drop' || E'\'' || ' AND rule_action<>' || --- E'\'' || 'reject' || E'\'' || ' AND rule_action<>' || E'\'' || 'deny' || E'\'' || ')' || --- ' INTERSECT ' || --- ' (SELECT rule_id FROM rule_order LEFT JOIN rule USING (rule_id) LEFT JOIN rule_to USING (rule_id) LEFT JOIN objgrp_flat ON (rule_to.obj_id=objgrp_flat_member_id) ' || --- ' LEFT JOIN object ON (objgrp_flat_member_id=object.obj_id) WHERE ' || v_import_filter || ' AND ' || v_dev_filter || --- ' AND ' || v_dst_ip_filter || ' AND ' || v_admin_view_filter || ' AND rule.rule_head_text IS NULL AND NOT rule_disabled AND rule_action<>' || --- E'\'' || 'drop' || E'\'' || ' AND rule_action<>' || --- E'\'' || 'reject' || E'\'' || ' AND rule_action<>' || E'\'' || 'deny' || E'\'' --- -- || ' GROUP BY rule_id' --- || ')'; --- FOR r_rule IN EXECUTE v_select_statement --- LOOP --- RETURN NEXT r_rule.rule_id; --- END LOOP; --- RETURN; --- END; --- $BODY$ LANGUAGE plpgsql; ----------------------------------------------------- --- FUNCTION: get_rule_ids --- Zweck: liefert Tabelle mit Regel-IDs zurueck, die den Filterkriterien entsprechen --- Used for: Account (Usage) Report --- Parameter1: Device-ID dessen Regelsatz untersucht wird (erforderlich) --- Parameter2: Zeitpunkt zu dem das Regelwerk angezeigt werden soll --- Parameter2: wenn NULL: Zeitpunkt = jetzt (also hoechste vorhandene Import-ID, des Devices) --- Parameter3: tenant-ID des Kunden, fuer den der Report generiert werden soll --- Parameter3: wenn NULL: keine Kunden-Filterung: liefere alle Regeln --- Parameter4: Filter resultierend aus Einschraenkungen des angemeldeten Benutzers (SQL as Text) --- RETURNS: Tabelle mit einer Spalte (rule_id) - --- CREATE OR REPLACE FUNCTION get_rule_ids(int4, "timestamp", int4, VARCHAR) RETURNS SETOF BIGINT AS --- $BODY$ --- DECLARE --- i_device_id ALIAS FOR $1; --- t_in_report_time ALIAS FOR $2; --- i_tenant_id ALIAS FOR $3; --- v_admin_view_filter ALIAS FOR $4; --- i_relevant_import_id BIGINT; -- ID des Imports, direkt vor dem Report-Zeitpunkt --- v_tenant_filter_ip_list VARCHAR; -- Filter-Liste mit allen IP-Bereichen des tenants --- v_tenant_filter_ip_list_negated VARCHAR; -- Filter-Liste mit allen IP-Bereichen des tenants fuer negierte Faelle --- r_rule RECORD; -- temp. Variable fuer Rule-ID --- t_report_time TIMESTAMP; -- Zeitpunkt des Reports (jetzt, wenn t_in_report_time IS NULL) --- v_sql_get_rules_with_tenant_src_ips VARCHAR; -- SQL-Code zum Holen der Rule-IDs mit Quellen im tenant-Bereich --- v_sql_get_rules_with_tenant_dst_ips VARCHAR; -- SQL-Code zum Holen der Rule-IDs mit Zielen im tenant-Bereich --- v_error_str VARCHAR; --- v_dev_filter VARCHAR; -- filter for devices (true for all devices) --- v_import_filter VARCHAR; -- filter for imports --- v_select_statement VARCHAR; --- v_order_statement VARCHAR; --- BEGIN --- -- RAISE NOTICE 'get_rule_ids parameter device_id: %', i_device_id; --- -- RAISE NOTICE 'get_rule_ids parameter in_report_time: %', t_in_report_time; --- -- v_order_statement := ' ORDER BY dev_id, rule_number '; --- v_order_statement := ''; --- IF t_in_report_time IS NULL THEN -- no report time given, assuming now() --- t_report_time := now(); --- ELSE --- t_report_time := t_in_report_time; --- END IF; --- -- set filter: a) import filter, b) device filter --- IF i_device_id IS NULL THEN -- ueber alle Devices --- v_import_filter := get_previous_import_ids(t_report_time); --- IF v_import_filter = ' () ' THEN --- v_import_filter := ' FALSE '; --- ELSE --- v_import_filter := 'rule_order.control_id IN ' || get_previous_import_ids(t_report_time); --- END IF; --- v_dev_filter := ' TRUE '; --- ELSE --- i_relevant_import_id := get_previous_import_id(i_device_id, t_report_time); --- IF i_relevant_import_id IS NULL THEN --- v_error_str := 'device_id: ' || CAST(i_device_id AS VARCHAR) || ', time: ' || CAST(t_report_time AS VARCHAR); --- PERFORM error_handling('WARN_NO_IMP_ID_FOUND', v_error_str); --- v_import_filter := ' FALSE '; --- ELSE --- v_import_filter := 'rule_order.control_id = ' || CAST(i_relevant_import_id AS VARCHAR); --- END IF; --- v_dev_filter := 'rule_order.dev_id = ' || CAST(i_device_id AS VARCHAR); --- END IF; --- IF i_tenant_id IS NULL THEN -- einfacher Fall ohne tenant-Filter --- v_select_statement := 'SELECT rule_id FROM rule_order INNER JOIN device USING (dev_id) INNER JOIN management USING (mgm_id) WHERE ' || v_import_filter --- || ' AND ' || v_dev_filter || ' AND ' || v_admin_view_filter || v_order_statement; --- ELSE -- tenant-Filter --- v_tenant_filter_ip_list := get_tenant_ip_filter(i_tenant_id); --- v_tenant_filter_ip_list_negated := get_negated_tenant_ip_filter(i_tenant_id); --- v_sql_get_rules_with_tenant_src_ips := --- '(SELECT rule.rule_id FROM rule, rule_order, object,rule_from --- WHERE rule.rule_id = rule_from.rule_id --- AND ' || v_import_filter || ' AND ' || v_dev_filter || --- ' AND rule_order.rule_id=rule.rule_id --- AND (((' || v_tenant_filter_ip_list || ') AND NOT rule.rule_src_neg) OR ((' || --- v_tenant_filter_ip_list_negated || ') AND rule.rule_src_neg))' || --- ' AND (rule.rule_id,object.obj_id) IN --- ( --- SELECT rule.rule_id,object.obj_id FROM rule_order,rule,rule_from,object --- LEFT JOIN objgrp_flat ON objgrp_flat_id=object.obj_id --- WHERE rule.rule_id = rule_from.rule_id --- AND ' || v_import_filter || ' AND ' || v_dev_filter || --- ' AND rule_order.rule_id=rule.rule_id AND object.obj_id=rule_from.obj_id --- UNION --- SELECT rule.rule_id,objgrp_flat.objgrp_flat_member_id FROM rule_order,rule,rule_from,object --- LEFT JOIN objgrp_flat ON objgrp_flat_id=object.obj_id --- WHERE rule.rule_id = rule_from.rule_id --- AND ' || v_import_filter || ' AND ' || v_dev_filter || --- ' AND rule_order.rule_id=rule.rule_id AND object.obj_id=rule_from.obj_id --- ) --- )'; --- v_sql_get_rules_with_tenant_dst_ips := --- '(SELECT rule.rule_id FROM rule,rule_order,object,rule_to WHERE rule.rule_id = rule_to.rule_id --- AND ' || v_import_filter || ' AND ' || v_dev_filter || ' AND rule_order.rule_id=rule.rule_id --- AND (((' || v_tenant_filter_ip_list || ') AND NOT rule.rule_dst_neg) OR ((' || --- v_tenant_filter_ip_list_negated || ') AND rule.rule_dst_neg))' || --- ' AND (rule.rule_id,object.obj_id) in --- ( --- SELECT rule.rule_id,object.obj_id FROM rule_order,rule,rule_to,object --- LEFT JOIN objgrp_flat ON objgrp_flat_id=object.obj_id --- WHERE rule.rule_id = rule_to.rule_id --- AND ' || v_import_filter || ' AND ' || v_dev_filter || --- ' AND rule_order.rule_id=rule.rule_id AND object.obj_id=rule_to.obj_id --- UNION --- SELECT rule.rule_id,objgrp_flat.objgrp_flat_member_id FROM rule_order,rule,rule_to,object --- LEFT JOIN objgrp_flat ON objgrp_flat_id=object.obj_id --- WHERE rule.rule_id = rule_to.rule_id --- AND ' || v_import_filter || ' AND ' || v_dev_filter || --- ' AND rule_order.rule_id=rule.rule_id AND object.obj_id=rule_to.obj_id --- ) --- )'; --- v_select_statement := 'SELECT rule_id FROM rule_order LEFT JOIN device USING (dev_id) LEFT JOIN management USING (mgm_id) WHERE rule_id IN (' || v_sql_get_rules_with_tenant_src_ips --- || ' UNION ' || v_sql_get_rules_with_tenant_dst_ips || ')' || ' AND ' || v_admin_view_filter || v_order_statement --- || ' GROUP BY rule_order.rule_id '; --- END IF; -- tenant_filter set - --- -- RAISE NOTICE 'get_rule_ids select: %', v_select_statement; --- FOR r_rule IN EXECUTE v_select_statement --- LOOP --- RETURN NEXT r_rule.rule_id; --- END LOOP; --- RETURN; --- END; --- $BODY$ --- LANGUAGE 'plpgsql' VOLATILE; - - --- CREATE OR REPLACE FUNCTION get_rule_ids_no_tenant_filter(int4, "timestamp", VARCHAR) RETURNS SETOF BIGINT AS --- $BODY$ --- DECLARE --- i_device_id ALIAS FOR $1; --- t_in_report_time ALIAS FOR $2; --- v_admin_view_filter ALIAS FOR $3; --- i_relevant_import_id BIGINT; -- ID des Imports, direkt vor dem Report-Zeitpunkt --- r_rule RECORD; -- temp. Variable fuer Rule-ID --- t_report_time TIMESTAMP; -- Zeitpunkt des Reports (jetzt, wenn t_in_report_time IS NULL) --- v_error_str VARCHAR; --- v_dev_filter VARCHAR; -- filter for devices (true for all devices) --- v_import_filter VARCHAR; -- filter for imports --- v_select_statement VARCHAR; --- v_order_statement VARCHAR; --- BEGIN --- v_order_statement := ''; --- IF t_in_report_time IS NULL THEN -- no report time given, assuming now() --- t_report_time := now(); --- ELSE --- t_report_time := t_in_report_time; --- END IF; --- -- set filter: a) import filter, b) device filter --- IF i_device_id IS NULL THEN -- ueber alle Devices --- v_import_filter := get_previous_import_ids(t_report_time); --- IF v_import_filter = ' () ' THEN --- v_import_filter := ' FALSE '; --- ELSE --- v_import_filter := 'rule_order.control_id IN ' || get_previous_import_ids(t_report_time); --- END IF; --- v_dev_filter := ' TRUE '; --- ELSE --- i_relevant_import_id := get_previous_import_id(i_device_id, t_report_time); --- IF i_relevant_import_id IS NULL THEN --- v_error_str := 'device_id: ' || CAST(i_device_id AS VARCHAR) || ', time: ' || CAST(t_report_time AS VARCHAR); --- PERFORM error_handling('WARN_NO_IMP_ID_FOUND', v_error_str); --- v_import_filter := ' FALSE '; --- ELSE --- v_import_filter := 'rule_order.control_id = ' || CAST(i_relevant_import_id AS VARCHAR); --- END IF; --- v_dev_filter := 'rule_order.dev_id = ' || CAST(i_device_id AS VARCHAR); --- END IF; --- v_select_statement := 'SELECT rule_id FROM rule_order INNER JOIN device USING (dev_id) INNER JOIN management USING (mgm_id) WHERE ' || v_import_filter --- || ' AND ' || v_dev_filter || ' AND ' || v_admin_view_filter || v_order_statement; --- FOR r_rule IN EXECUTE v_select_statement --- LOOP --- RETURN NEXT r_rule.rule_id; --- END LOOP; --- RETURN; --- END; --- $BODY$ --- LANGUAGE 'plpgsql' VOLATILE; - -CREATE OR REPLACE FUNCTION get_import_ids_for_time (TIMESTAMP) RETURNS SETOF BIGINT AS $$ -DECLARE - t_import_time ALIAS FOR $1; - r_mgm RECORD; - i_ctrl_id BIGINT; -BEGIN - FOR r_mgm IN - SELECT mgm_id FROM management - LOOP - SELECT INTO i_ctrl_id MAX(control_id) FROM import_control WHERE mgm_id=r_mgm.mgm_id - AND start_time<=t_import_time AND NOT stop_time IS NULL AND successful_import; - IF FOUND AND NOT i_ctrl_id IS NULL THEN --- RAISE NOTICE 'ctrl_id found: %', i_ctrl_id; - RETURN NEXT i_ctrl_id; - END IF; - END LOOP; - RETURN; -END; -$$ LANGUAGE plpgsql; - ----------------------------------------------------- --- FUNCTION: rule_src_contains_tenant_obj --- Zweck: prueft, ob in den Quellen ein Objekt enthalten ist, das zum Kunden-Dunstkreis gehoert --- Parameter1: rule_id --- Parameter2: id des relevanten Imports --- Parameter3: tenant_id fuer Filterung innerhalb der Regel --- RETURNS: wahr, wenn in den Quellen der Regeln ein tenant-relevantes Objekt enthalten ist --- -CREATE OR REPLACE FUNCTION rule_src_contains_tenant_obj (BIGINT, INTEGER) RETURNS BOOLEAN AS $$ -DECLARE - i_rule_id ALIAS FOR $1; - i_tenant_id ALIAS FOR $2; - r_obj RECORD; -- object - v_tenant_ip_filter VARCHAR; -BEGIN - IF is_rule_src_negated(i_rule_id) THEN - v_tenant_ip_filter := get_negated_tenant_ip_filter(i_tenant_id); - ELSE - v_tenant_ip_filter := get_tenant_ip_filter(i_tenant_id); - END IF; - FOR r_obj IN EXECUTE - 'SELECT obj_id FROM object WHERE (obj_id IN (SELECT * FROM get_exploded_src_of_rule(' || - CAST(i_rule_id AS VARCHAR) || '))) AND (' || v_tenant_ip_filter || ')' - LOOP - RETURN TRUE; - END LOOP; - RETURN FALSE; -END; -$$ LANGUAGE plpgsql; - ----------------------------------------------------- --- version ohne import_id --- FUNCTION: rule_dst_contains_tenant_obj --- Zweck: prueft, ob in den Zielen ein Objekt enthalten ist, das zum Kunden-Dunstkreis gehoert --- Parameter1: rule_id --- Parameter2: tenant_id fuer Filterung innerhalb der Regel --- RETURNS: wahr, wenn in den Zielen der Regeln ein tenant-relevantes Objekt enthalten ist --- -CREATE OR REPLACE FUNCTION rule_dst_contains_tenant_obj (BIGINT, INTEGER) RETURNS BOOLEAN AS $$ -DECLARE - i_rule_id ALIAS FOR $1; - i_tenant_id ALIAS FOR $2; - r_rule RECORD; -- rule to be returned - v_tenant_ip_filter VARCHAR; -BEGIN - IF is_rule_dst_negated(i_rule_id) THEN - v_tenant_ip_filter := get_negated_tenant_ip_filter(i_tenant_id); - ELSE - v_tenant_ip_filter := get_tenant_ip_filter(i_tenant_id); - END IF; - FOR r_rule IN EXECUTE - 'SELECT obj_id FROM object WHERE (obj_id IN (SELECT * FROM get_exploded_dst_of_rule(' || - CAST(i_rule_id AS VARCHAR) || '))) AND (' || v_tenant_ip_filter || ')' - LOOP - RETURN TRUE; - END LOOP; - RETURN FALSE; -END; -$$ LANGUAGE plpgsql; - ----------------------------------------------------- --- FUNCTION: obj_belongs_to_tenant --- Zweck: prueft, ob das NW-Objekt zum tenant-Bereich gehoert --- Parameter1: obj_id --- Parameter2: tenant_id --- RETURNS: wahr, wenn object zum tenant mit tenant_id gehoert --- -CREATE OR REPLACE FUNCTION obj_belongs_to_tenant (BIGINT, INTEGER) RETURNS BOOLEAN AS $$ -DECLARE - i_obj_id ALIAS FOR $1; - i_tenant_id ALIAS FOR $2; - r_obj RECORD; -- zu pruefendes Objekt - v_tenant_filter_ip_list VARCHAR; -BEGIN - v_tenant_filter_ip_list := get_tenant_ip_filter(i_tenant_id); --- RAISE INFO 'tenant: %', i_tenant_id; --- RAISE INFO 'tenant_filter: %', v_tenant_filter_ip_list; - FOR r_obj IN EXECUTE - 'SELECT obj_id FROM object WHERE (obj_id IN (SELECT * FROM explode_objgrp(' || i_obj_id || - '))) AND ('|| v_tenant_filter_ip_list || ')' - LOOP --- RAISE INFO 'obj: %', r_obj.obj_id; - RETURN TRUE; - END LOOP; - RETURN FALSE; -END; -$$ LANGUAGE plpgsql; - ----------------------------------------------------- --- FUNCTION: obj_neg_belongs_to_tenant --- Zweck: prueft, ob die Negation des NW-Objekts zum tenant-Bereich gehoert --- Parameter1: obj_id --- Parameter2: tenant_id --- RETURNS: wahr, wenn das Komplement von object zum tenant mit tenant_id gehoert --- -CREATE OR REPLACE FUNCTION obj_neg_belongs_to_tenant (BIGINT, INTEGER) RETURNS BOOLEAN AS $$ -DECLARE - i_obj_id ALIAS FOR $1; - i_tenant_id ALIAS FOR $2; - r_obj RECORD; -- zu pruefendes Objekt - v_tenant_filter_ip_list_neg VARCHAR; -BEGIN - v_tenant_filter_ip_list_neg := get_negated_tenant_ip_filter(i_tenant_id); - FOR r_obj IN EXECUTE - 'SELECT obj_id FROM object WHERE (obj_id IN (SELECT * FROM explode_objgrp(' || i_obj_id || - '))) AND ('|| v_tenant_filter_ip_list_neg || ')' - LOOP - RETURN TRUE; - END LOOP; - RETURN FALSE; -END; -$$ LANGUAGE plpgsql; - ----------------------------------------------------- --- FUNCTION: flatten_obj_list --- Zweck: gibt zu einer Liste von Objek-IDs die aufgeloeste Liste zurueck --- Zweck: die auch alle Mitglieder enthaelt --- Parameter1: Array of Object-IDs --- RETURNS: Array of Object-IDs --- -CREATE OR REPLACE FUNCTION flatten_obj_list (BIGINT[]) RETURNS BIGINT[] AS $$ -DECLARE - ar_obj_ids ALIAS FOR $1; - r_obj RECORD; - ar_obj_ids_result BIGINT[]; - i BIGINT; - i_array_size BIGINT; -BEGIN - ar_obj_ids_result := '{}'; - i_array_size := array_upper(ar_obj_ids,1); - FOR i IN 0..i_array_size-1 LOOP - ar_obj_ids_result := array_append(ar_obj_ids_result, ar_obj_ids[i]); - FOR r_obj IN - SELECT objgrp_flat_member_id FROM objgrp_flat WHERE objgrp_flat_id=ar_obj_ids[i] - LOOP - ar_obj_ids_result := array_append(ar_obj_ids_result, r_obj.objgrp_flat_member_id); - END LOOP; - END LOOP; - RETURN ar_obj_ids_result; -END; -$$ LANGUAGE plpgsql; - - ----------------------------------------------------- --- FUNCTION: get_rule_src --- Zweck: liefert alle Quellen der Regel als setof zurueck --- Parameter1: rule_id --- Parameter2: tenant_id fuer Filterung innerhalb der Regel --- Parameter3: Zeitpunkt --- RETURNS: Tabelle mit allen src-obj_ids der Regel fuer Report --- --- CREATE OR REPLACE FUNCTION get_rule_src (BIGINT, INTEGER, TIMESTAMP) RETURNS SETOF BIGINT AS $$ --- DECLARE --- i_rule_id ALIAS FOR $1; --- i_tenant_id ALIAS FOR $2; --- t_time ALIAS FOR $3; --- r_obj RECORD; -- temp. object --- i_import_id BIGINT; --- i_mgm_id INTEGER; --- BEGIN --- SELECT INTO i_mgm_id device.mgm_id FROM rule_order LEFT JOIN device USING (dev_id) WHERE rule_id=i_rule_id LIMIT 1; --- i_import_id := get_import_id_for_mgmt_at_time(i_mgm_id,t_time); --- IF i_tenant_id IS NULL THEN --- -- RAISE NOTICE 'import: %', i_import_id; --- FOR r_obj IN --- SELECT obj_id FROM rule,rule_from WHERE rf_last_seen>=i_import_id AND rf_create<=i_import_id AND --- rule.rule_id=rule_from.rule_id AND rule.rule_id=i_rule_id --- LOOP --- RETURN NEXT r_obj.obj_id; --- END LOOP; --- ELSE --- -- do the filtering --- IF rule_dst_contains_tenant_obj(i_rule_id, i_tenant_id) THEN -- alle Quellen anzeigen --- FOR r_obj IN --- SELECT obj_id FROM rule,rule_from WHERE rf_last_seen>=i_import_id AND rf_create<=i_import_id AND --- rule.rule_id=rule_from.rule_id AND rule.rule_id=i_rule_id --- LOOP --- RETURN NEXT r_obj.obj_id; --- END LOOP; --- ELSE -- filtern - nur tenant-Objekte anzeigen --- IF is_rule_src_negated(i_rule_id) THEN --- FOR r_obj IN --- SELECT obj_id FROM rule,rule_from WHERE rf_last_seen>=i_import_id AND rf_create<=i_import_id AND --- rule.rule_id=rule_from.rule_id AND rule.rule_id=i_rule_id --- LOOP --- IF obj_neg_belongs_to_tenant(r_obj.obj_id, i_tenant_id) THEN --- RETURN NEXT r_obj.obj_id; --- END IF; --- END LOOP; --- ELSE --- FOR r_obj IN --- SELECT obj_id FROM rule,rule_from WHERE rf_last_seen>=i_import_id AND rf_create<=i_import_id AND --- rule.rule_id=rule_from.rule_id AND rule.rule_id=i_rule_id --- LOOP --- IF obj_belongs_to_tenant(r_obj.obj_id, i_tenant_id) THEN --- RETURN NEXT r_obj.obj_id; --- END IF; --- END LOOP; --- END IF; --- END IF; --- END IF; --- RETURN; --- END; --- $$ LANGUAGE plpgsql; - --- ---------------------------------------------------- --- -- FUNCTION: get_rule_dst --- -- Zweck: liefert alle Ziele der Regel als setof zurueck --- -- Parameter1: rule_id --- -- Parameter2: relevante import id --- -- Parameter3: tenant_id fuer Filterung innerhalb der Regel --- -- RETURNS: Tabele mit allen dst-obj_ids der Regel fuer Report --- -- --- -- CREATE OR REPLACE FUNCTION get_rule_dst (BIGINT, INTEGER, TIMESTAMP) RETURNS SETOF BIGINT AS $$ --- CREATE OR REPLACE FUNCTION get_rule_dst (BIGINT, INTEGER, TIMESTAMP) RETURNS SETOF BIGINT AS $$ --- DECLARE --- i_rule_id ALIAS FOR $1; --- i_tenant_id ALIAS FOR $2; --- t_time ALIAS FOR $3; --- i_import_id BIGINT; --- r_obj RECORD; -- rule to be returned --- i_mgm_id INTEGER; --- BEGIN --- SELECT INTO i_mgm_id device.mgm_id FROM rule_order LEFT JOIN device USING (dev_id) WHERE rule_id=i_rule_id LIMIT 1; --- i_import_id := get_import_id_for_mgmt_at_time(i_mgm_id,t_time); --- IF i_tenant_id IS NULL THEN --- FOR r_obj IN --- SELECT obj_id FROM rule,rule_to WHERE rt_last_seen>=i_import_id AND rt_create<=i_import_id AND --- rule.rule_id=rule_to.rule_id AND rule.rule_id=i_rule_id --- LOOP --- RETURN NEXT r_obj.obj_id; --- END LOOP; --- ELSE -- do the filtering --- IF rule_src_contains_tenant_obj(i_rule_id, i_tenant_id) THEN -- alle Quellen anzeigen --- FOR r_obj IN --- SELECT obj_id FROM rule,rule_to WHERE rt_last_seen>=i_import_id AND rt_create<=i_import_id AND --- rule.rule_id=rule_to.rule_id AND rule.rule_id=i_rule_id --- LOOP --- RETURN NEXT r_obj.obj_id; --- END LOOP; --- ELSE -- filtern - nur tenant-Objekte anzeigen --- IF is_rule_dst_negated(i_rule_id) THEN --- FOR r_obj IN --- SELECT obj_id FROM rule,rule_to WHERE rt_last_seen>=i_import_id AND rt_create<=i_import_id AND --- rule.rule_id=rule_to.rule_id AND rule.rule_id=i_rule_id --- LOOP --- IF obj_neg_belongs_to_tenant(r_obj.obj_id, i_tenant_id) THEN --- RETURN NEXT r_obj.obj_id; --- END IF; --- END LOOP; --- ELSE --- FOR r_obj IN --- SELECT obj_id FROM rule,rule_to WHERE rt_last_seen>=i_import_id AND rt_create<=i_import_id AND --- rule.rule_id=rule_to.rule_id AND rule.rule_id=i_rule_id --- LOOP --- IF obj_belongs_to_tenant(r_obj.obj_id, i_tenant_id) THEN --- RETURN NEXT r_obj.obj_id; --- END IF; --- END LOOP; --- END IF; --- END IF; --- END IF; --- RETURN; --- END; --- $$ LANGUAGE plpgsql; - - - ----------------------------------------------------- --- FUNCTION: get_rule_src_flat --- Zweck: liefert alle Quellen (und deren Gruppen-Mitglieder) der Regel als setof zurueck --- Parameter1: rule_id --- Parameter2: tenant_id fuer Filterung innerhalb der Regel --- Parameter3: Zeitpunkt --- RETURNS: Tabelle mit allen src-obj_ids der Regel fuer Report --- --- Function: get_rule_src(integer, integer, timestamp without time zone) - --- DROP FUNCTION get_rule_src(integer, integer, timestamp without time zone); - --- CREATE OR REPLACE FUNCTION get_rule_src_flat (BIGINT, integer, timestamp without time zone) --- RETURNS SETOF BIGINT AS --- $BODY$ --- DECLARE --- i_rule_id ALIAS FOR $1; --- i_tenant_id ALIAS FOR $2; --- t_time ALIAS FOR $3; --- r_obj RECORD; -- temp. object --- i_import_id BIGINT; --- i_mgm_id INTEGER; --- BEGIN --- SELECT INTO i_mgm_id device.mgm_id FROM rule_order LEFT JOIN device USING (dev_id) WHERE rule_id=i_rule_id LIMIT 1; --- i_import_id := get_import_id_for_mgmt_at_time(i_mgm_id,t_time); --- IF i_tenant_id IS NULL OR rule_dst_contains_tenant_obj(i_rule_id, i_tenant_id) THEN --- -- RAISE NOTICE 'import: %', i_import_id; --- FOR r_obj IN --- SELECT objgrp_flat_member_id FROM rule LEFT JOIN rule_from USING (rule_id) --- LEFT JOIN objgrp_flat ON (rule_from.obj_id=objgrp_flat.objgrp_flat_id) --- WHERE rf_last_seen>=i_import_id AND rf_create<=i_import_id AND rule.rule_id=i_rule_id --- LOOP --- RETURN NEXT r_obj.objgrp_flat_member_id; --- END LOOP; --- ELSE -- filtern - nur tenant-Objekte anzeigen --- IF is_rule_src_negated(i_rule_id) THEN --- FOR r_obj IN --- SELECT objgrp_flat_member_id FROM rule LEFT JOIN rule_from USING (rule_id) --- LEFT JOIN objgrp_flat ON (rule_from.obj_id=objgrp_flat.objgrp_flat_id) --- WHERE rf_last_seen>=i_import_id AND rf_create<=i_import_id AND rule.rule_id=i_rule_id --- LOOP --- IF obj_neg_belongs_to_tenant(r_obj.objgrp_flat_member_id, i_tenant_id) THEN --- RETURN NEXT r_obj.objgrp_flat_member_id; --- END IF; --- END LOOP; --- ELSE --- FOR r_obj IN --- SELECT objgrp_flat_member_id FROM rule LEFT JOIN rule_from USING (rule_id) --- LEFT JOIN objgrp_flat ON (rule_from.obj_id=objgrp_flat.objgrp_flat_id) --- WHERE rf_last_seen>=i_import_id AND rf_create<=i_import_id AND rule.rule_id=i_rule_id --- LOOP --- IF obj_belongs_to_tenant(r_obj.objgrp_flat_member_id, i_tenant_id) THEN --- RETURN NEXT r_obj.objgrp_flat_member_id; --- END IF; --- END LOOP; --- END IF; --- END IF; --- RETURN; --- END; --- $BODY$ --- LANGUAGE 'plpgsql' VOLATILE --- COST 100 --- ROWS 1000; - ----------------------------------------------------- --- FUNCTION: get_rule_dst_flat --- Zweck: liefert alle Ziele der Regel (und alle Gruppenmitglieder davon) als setof zurueck --- Parameter1: rule_id --- Parameter2: relevante import id --- Parameter3: tenant_id fuer Filterung innerhalb der Regel --- RETURNS: Tabele mit allen dst-obj_ids der Regel fuer Report --- --- CREATE OR REPLACE FUNCTION get_rule_dst_flat (BIGINT, INTEGER, timestamp) RETURNS SETOF INTEGER AS $$ --- Function: get_rule_src(integer, integer, timestamp without time zone) - --- DROP FUNCTION get_rule_src(BIGINT, integer, timestamp without time zone); - --- CREATE OR REPLACE FUNCTION get_rule_dst_flat (BIGINT, integer, timestamp without time zone) --- RETURNS SETOF BIGINT AS --- $BODY$ --- DECLARE --- i_rule_id ALIAS FOR $1; --- i_tenant_id ALIAS FOR $2; --- t_time ALIAS FOR $3; --- r_obj RECORD; -- temp. object --- i_import_id BIGINT; --- i_mgm_id INTEGER; --- BEGIN --- SELECT INTO i_mgm_id device.mgm_id FROM rule_order LEFT JOIN device USING (dev_id) WHERE rule_id=i_rule_id LIMIT 1; --- i_import_id := get_import_id_for_mgmt_at_time(i_mgm_id,t_time); --- IF i_tenant_id IS NULL OR rule_src_contains_tenant_obj(i_rule_id, i_tenant_id) THEN --- -- RAISE NOTICE 'import: %', i_import_id; --- FOR r_obj IN --- SELECT objgrp_flat_member_id FROM rule LEFT JOIN rule_to USING (rule_id) --- LEFT JOIN objgrp_flat ON (rule_to.obj_id=objgrp_flat.objgrp_flat_id) --- WHERE rt_last_seen>=i_import_id AND rt_create<=i_import_id AND rule.rule_id=i_rule_id --- LOOP --- RETURN NEXT r_obj.objgrp_flat_member_id; --- END LOOP; --- ELSE -- filtern - nur tenant-Objekte anzeigen --- IF is_rule_dst_negated(i_rule_id) THEN --- FOR r_obj IN --- SELECT objgrp_flat_member_id FROM rule LEFT JOIN rule_to USING (rule_id) --- LEFT JOIN objgrp_flat ON (rule_to.obj_id=objgrp_flat.objgrp_flat_id) --- WHERE rt_last_seen>=i_import_id AND rt_create<=i_import_id AND rule.rule_id=i_rule_id --- LOOP --- IF obj_neg_belongs_to_tenant(r_obj.objgrp_flat_member_id, i_tenant_id) THEN --- RETURN NEXT r_obj.objgrp_flat_member_id; --- END IF; --- END LOOP; --- ELSE --- FOR r_obj IN --- SELECT objgrp_flat_member_id FROM rule LEFT JOIN rule_to USING (rule_id) --- LEFT JOIN objgrp_flat ON (rule_to.obj_id=objgrp_flat.objgrp_flat_id) --- WHERE rt_last_seen>=i_import_id AND rt_create<=i_import_id AND rule.rule_id=i_rule_id --- LOOP --- IF obj_belongs_to_tenant(r_obj.objgrp_flat_member_id, i_tenant_id) THEN --- RETURN NEXT r_obj.objgrp_flat_member_id; --- END IF; --- END LOOP; --- END IF; --- END IF; --- RETURN; --- END; --- $BODY$ --- LANGUAGE 'plpgsql' VOLATILE --- COST 100 --- ROWS 1000; - --- Function: get_changed_newrules(refcursor, _int4) - --- DROP FUNCTION get_changed_newrules(refcursor, _int4); - -CREATE OR REPLACE FUNCTION get_changed_newrules(refcursor, _int4) - RETURNS refcursor AS -$BODY$ -DECLARE - cursor_result ALIAS FOR $1; - log_rule_ids ALIAS FOR $2; - BEGIN - OPEN cursor_result FOR - SELECT changelog_rule.*, rule.rule_num,rule.rule_id,action_name,track_name,from_zone.zone_name,to_zone.zone_name,rule.* - FROM changelog_rule,stm_track,stm_action,rule - LEFT JOIN zone as from_zone ON rule.rule_from_zone=from_zone.zone_id - LEFT JOIN zone as to_zone ON rule.rule_to_zone=to_zone.zone_id - WHERE rule.action_id=stm_action.action_id - AND rule.track_id=stm_track.track_id - AND rule.rule_id = changelog_rule.new_rule_id - AND changelog_rule.log_rule_id = ANY (log_rule_ids) - ORDER BY changelog_rule.log_rule_id; - RETURN cursor_result; -END; -$BODY$ - LANGUAGE 'plpgsql' VOLATILE; - --- Function: get_changed_oldrules(refcursor, _int4) - --- DROP FUNCTION get_changed_oldrules(refcursor, _int4); - -CREATE OR REPLACE FUNCTION get_changed_oldrules(refcursor, _int4) - RETURNS refcursor AS -$BODY$ -DECLARE - cursor_result ALIAS FOR $1; - log_rule_ids ALIAS FOR $2; - BEGIN - OPEN cursor_result FOR - SELECT changelog_rule.*, rule.rule_num,rule.rule_id,action_name,track_name,from_zone.zone_name,to_zone.zone_name,rule.* - FROM changelog_rule,stm_track,stm_action,rule - LEFT JOIN zone as from_zone ON rule.rule_from_zone=from_zone.zone_id - LEFT JOIN zone as to_zone ON rule.rule_to_zone=to_zone.zone_id - WHERE rule.action_id=stm_action.action_id - AND rule.track_id=stm_track.track_id - AND rule.rule_id = changelog_rule.old_rule_id - AND changelog_rule.log_rule_id = ANY (log_rule_ids) - ORDER BY changelog_rule.log_rule_id; - RETURN cursor_result; -END; -$BODY$ - LANGUAGE 'plpgsql' VOLATILE; - ----------------------------------------------------- --- FUNCTION: get_undocumented_changelog_entries --- Zweck: liefert eine Tabelle mit allen Feldern von changelog_$1 zurueck, die 'undocumented' sind --- Parameter1: table_name (object,service,user,rule) --- RETURNS: Tabelle mit allen Feldern der Eintraege von changelog_$1 zurueck, die 'undocumented' sind --- -CREATE OR REPLACE FUNCTION get_undocumented_changelog_entries(VARCHAR) RETURNS SETOF RECORD AS $$ -DECLARE - v_table ALIAS FOR $1; - r_chlog RECORD; - v_sql VARCHAR; -BEGIN --- RAISE NOTICE 'sql'; - v_sql := 'SELECT * FROM changelog_' || v_table || ' WHERE NOT documented ORDER BY change_action'; --- RAISE NOTICE 'sql: %', v_sql; - FOR r_chlog IN EXECUTE - v_sql - LOOP - RETURN NEXT r_chlog; - END LOOP; - RETURN; -END; -$$ LANGUAGE plpgsql; - diff --git a/roles/database/files/sql/idempotent/fworch-rule-import.sql b/roles/database/files/sql/idempotent/fworch-rule-import.sql deleted file mode 100644 index bbc252455a..0000000000 --- a/roles/database/files/sql/idempotent/fworch-rule-import.sql +++ /dev/null @@ -1,558 +0,0 @@ ----------------------------------------------------- --- FUNCTION: import_rules (device_id) --- Purpose: adds all changed rules of the current import to the rule table --- Purpose: using function insert_single_rule --- Parameter: device_id --- Parameter2: import_id --- RETURNS: has anything been changed? --- -CREATE OR REPLACE FUNCTION import_rules (INTEGER,BIGINT) RETURNS BOOLEAN AS $$ -DECLARE - i_dev_id ALIAS FOR $1; -- device id - i_current_import_id ALIAS FOR $2; - i_mgm_id INTEGER; -- for fetching the mgm_ID of the device - r_rule RECORD; -- record with single rule_id from the import_rule table - v_rulebase_name VARCHAR; -- namve of the rulebase of the current device - b_is_initial_import BOOLEAN; - v_rule_head_text VARCHAR; - b_rule_order_to_be_written BOOLEAN; - i_change_admin INTEGER; - v_uid VARCHAR; - i_added_rule_id BIGINT; - i_xlate_rule_id BIGINT; -BEGIN - b_rule_order_to_be_written := FALSE; - SELECT INTO i_mgm_id mgm_id FROM import_control WHERE control_id=i_current_import_id; - SELECT INTO v_rulebase_name local_rulebase_name FROM device WHERE dev_id=i_dev_id; - SELECT INTO r_rule rule_id FROM rule WHERE dev_id=i_dev_id LIMIT 1; - IF FOUND THEN - b_is_initial_import := FALSE; - SELECT INTO r_rule force_initial_import FROM management WHERE mgm_id=i_mgm_id; - IF r_rule.force_initial_import THEN - b_is_initial_import := TRUE; - b_rule_order_to_be_written := TRUE; - END IF; - SELECT INTO r_rule force_initial_import FROM device WHERE dev_id=i_dev_id; - IF r_rule.force_initial_import THEN - b_is_initial_import := TRUE; - UPDATE device SET force_initial_import=FALSE WHERE dev_id=i_dev_id; -- reset force_initial_import flag - END IF; - ELSE - b_is_initial_import := TRUE; - b_rule_order_to_be_written := TRUE; - END IF; - -- RAISE DEBUG 'import_rules - importing rulebase: %', v_rulebase_name; - - b_rule_order_to_be_written := import_rules_xlate(i_mgm_id, i_dev_id, i_current_import_id, v_rulebase_name, b_is_initial_import, b_rule_order_to_be_written) OR b_rule_order_to_be_written; - b_rule_order_to_be_written := import_rules_access(i_mgm_id, i_dev_id, i_current_import_id, v_rulebase_name, b_is_initial_import, b_rule_order_to_be_written) OR b_rule_order_to_be_written; - b_rule_order_to_be_written := import_rules_combined(i_mgm_id, i_dev_id, i_current_import_id, v_rulebase_name, b_is_initial_import, b_rule_order_to_be_written, v_uid) OR b_rule_order_to_be_written; - - -- RAISE DEBUG 'import_rules - after insert loop'; - IF NOT b_is_initial_import THEN -- set active=false for the old version of rules that have been changed - i_change_admin := get_last_change_admin_of_rulebase_change(i_current_import_id,i_dev_id); - FOR r_rule IN -- every deleted Regel is inserted in changelog_rule - SELECT rule_id, rule_name, (rule_head_text is NULL) as is_security_relevant FROM rule - WHERE active AND dev_id=i_dev_id AND mgm_id=i_mgm_id AND rule_last_seeni_prev_numeric_value ORDER BY rule_num_numeric LIMIT 1; - RAISE DEBUG 'import_rules_set_rule_num_numeric next rule %', CAST(i_next_numeric_value AS VARCHAR); - IF i_prev_numeric_value IS NULL AND i_next_numeric_value IS NULL THEN - i_numeric_value := 0; - ELSIF i_next_numeric_value IS NULL THEN - i_numeric_value := i_prev_numeric_value + 1000; - ELSIF i_prev_numeric_value IS NULL THEN - i_numeric_value := i_next_numeric_value - 1000; - ELSE - i_numeric_value := (i_prev_numeric_value + i_next_numeric_value) / 2; - END IF; - RAISE DEBUG 'import_rules_set_rule_num_numeric determined rule_num_numeric %', CAST(i_numeric_value AS VARCHAR); - UPDATE rule SET rule_num_numeric = i_numeric_value WHERE rule.rule_id=r_rule.rule_id; - r_rule.rule_num_numeric := i_numeric_value; - END IF; - i_prev_numeric_value := r_rule.rule_num_numeric; - END LOOP; - RAISE DEBUG 'import_rules_set_rule_num_numeric - end'; - RETURN; -END; -$$ LANGUAGE plpgsql; - -/* - -only works for postgres>10 - -CREATE OR REPLACE FUNCTION security_relevant_change(record, record, INT, INT, INT, INT) RETURNS BOOLEAN AS $$ -DECLARE - r_existing ALIAS FOR $1; - r_to_import ALIAS FOR $2; - i_fromzone ALIAS FOR $3; - i_tozone ALIAS FOR $4; - i_action_id ALIAS FOR $5; - i_track_id ALIAS FOR $6; -BEGIN - RETURN NOT ( - are_equal(r_existing.rule_uid, r_to_import.rule_uid) AND - are_equal(r_existing.rule_ruleid,r_to_import.rule_ruleid) AND - are_equal(r_existing.rule_from_zone, i_fromzone) AND - are_equal(r_existing.rule_to_zone, i_tozone) AND - are_equal(r_existing.rule_disabled, r_to_import.rule_disabled) AND - are_equal(r_existing.rule_src, r_to_import.rule_src) AND - are_equal(r_existing.rule_dst, r_to_import.rule_dst) AND - are_equal(r_existing.rule_svc, r_to_import.rule_svc) AND - are_equal(r_existing.rule_src_refs, r_to_import.rule_src_refs) AND - are_equal(r_existing.rule_dst_refs, r_to_import.rule_dst_refs) AND - are_equal(r_existing.rule_svc_refs, r_to_import.rule_svc_refs) AND - are_equal(r_existing.rule_src_neg, r_to_import.rule_src_neg) AND - are_equal(r_existing.rule_dst_neg, r_to_import.rule_dst_neg) AND - are_equal(r_existing.rule_svc_neg, r_to_import.rule_svc_neg) AND - are_equal(r_existing.action_id, i_action_id) AND - are_equal(r_existing.track_id, i_track_id) AND - are_equal(r_existing.rule_installon, r_to_import.rule_installon) AND - -- are_equal(r_existing.access_rule, r_to_import.access_rule) AND - -- cannot compare the following two as they are not part of import_rule: --- are_equal(r_existing.parent_rule_id, r_to_import.parent_rule_id) AND --- are_equal(r_existing.parent_rule_type, r_to_import.parent_rule_type) AND - are_equal(r_existing.rule_time, r_to_import.rule_time) - ); -END; -$$ LANGUAGE plpgsql; - -CREATE OR REPLACE FUNCTION non_security_relevant_change(record, record) RETURNS BOOLEAN AS $$ -DECLARE - r_existing ALIAS FOR $1; - r_to_import ALIAS FOR $2; -BEGIN - RETURN NOT ( - are_equal(r_existing.rule_name,r_to_import.rule_name) AND - are_equal(r_existing.rule_head_text, r_to_import.rule_head_text) AND - -- are_equal(r_existing.nat_rule, r_to_import.nat_rule) AND - are_equal(r_existing.rule_comment, r_to_import.rule_comment) - ); -END; -$$ LANGUAGE plpgsql; -*/ - ----------------------------------------------------- --- FUNCTION: insert_single_rule --- Purpose adds a single rule of the current import into the rule table --- Parameter1: import_rule.rule_id - ID of the rule to import --- Parameter2: dev_id --- Parameter3: mgm_id --- Parameter4: control_id --- Parameter5: b_is_initial_import --- RETURNS: new rule id - --- dropping first due to change of return type in v5.5.1: -DROP FUNCTION IF EXISTS insert_single_rule(bigint,integer,integer,bigint,boolean); - -CREATE OR REPLACE FUNCTION insert_single_rule(BIGINT,INTEGER,INTEGER,BIGINT,BOOLEAN) RETURNS BIGINT AS $$ -DECLARE - id ALIAS FOR $1; - i_dev_id ALIAS FOR $2; - i_mgm_id ALIAS FOR $3; - i_control_id ALIAS FOR $4; - b_is_initial_import ALIAS FOR $5; - r_to_import RECORD; -- the record to import from import_rule - r_meta RECORD; -- rule meta data record - i_rule_num INTEGER; -- the rule number - s_track VARCHAR; -- track-string - i_action_id INTEGER; -- action_id - i_track_id INTEGER; -- Record for tracking action - i_fromzone INTEGER; -- Record for source zone - i_tozone INTEGER; -- Record for destination zone - i_admin_id INTEGER; -- ID of last_change_admin - b_implied BOOLEAN; -- rule is implicit? - r_existing RECORD; -- formerly existing rule (for changes) - b_insert BOOLEAN; -- new rule - b_change BOOLEAN; -- was the rule changed? - b_change_sr BOOLEAN; -- non-security-relevant change - v_change_id VARCHAR; -- type of change - i_new_rule_id BIGINT; -- id of rule just about to be inserted - i_old_rule_id BIGINT; -- id of exisiting rule - b_is_documented BOOLEAN; - t_outtext TEXT; - i_change_type INTEGER; - v_change_action VARCHAR; - i_parent_rule_id BIGINT; - i_parent_rule_type SMALLINT; - r_parent_rule RECORD; - b_access_rule BOOLEAN; - b_nat_rule BOOLEAN; -BEGIN - b_insert := FALSE; b_change := FALSE; b_change_sr := FALSE; - SELECT INTO r_to_import * FROM import_rule WHERE rule_id = id; -- get rule record from import_rule --- fetch zone id ------------------------------------------------------------------------------------------ - IF (r_to_import.rule_from_zone IS NULL) THEN i_fromzone := NULL; - ELSE SELECT INTO i_fromzone zone_id FROM zone WHERE zone_name = r_to_import.rule_from_zone AND zone.mgm_id = i_mgm_id; -- AND active; - END IF; - IF (r_to_import.rule_to_zone IS NULL) THEN i_tozone := NULL; - ELSE SELECT INTO i_tozone zone_id FROM zone WHERE zone_name = r_to_import.rule_to_zone AND zone.mgm_id = i_mgm_id; -- AND active; - END IF; --- fetch track ID ------------------------------------------------------------------------------------------ - IF char_length(cast(r_to_import.rule_track as varchar))=0 THEN s_track := 'none'; - ELSE s_track := lower(r_to_import.rule_track); - END IF; - SELECT INTO i_track_id track_id FROM stm_track WHERE track_name = s_track; -- Track-ID holen - IF NOT FOUND THEN PERFORM error_handling('ERR_NO_TRACK', s_track); END IF; --- fetch action id ------------------------------------------------------------------------------------------ - SELECT INTO i_action_id action_id FROM stm_action WHERE action_name = lower(r_to_import.rule_action); -- Action-ID holen - IF NOT FOUND THEN PERFORM error_handling('ERR_NO_ACTION', r_to_import.rule_action); END IF; --- fetch rule_num ------------------------------------------------------------------------------------------ - IF (r_to_import.rule_num IS NULL OR CAST(r_to_import.rule_num AS VARCHAR) = '') THEN -- if there is no rule number - i_rule_num := 0; -- we use 0 - ELSE - i_rule_num := CAST(r_to_import.rule_num AS INTEGER); -- cast text into integer (todo: add error handling) - END IF; --- which rule was changed? ----------------------------------------------------------------- - IF (r_to_import.rule_uid IS NULL) THEN -- removed char_length-check due to utf-8 problems - PERFORM error_handling('ERR_RULE_NOT_IDENTIFYABLE'); - END IF; - - -- setting rule type vars - IF r_to_import.rule_type = 'access' OR r_to_import.rule_type = 'combined' OR r_to_import.rule_type IS NULL THEN - b_access_rule := TRUE; - ELSE - b_access_rule := FALSE; - END IF; - IF NOT (r_to_import.rule_type = 'access' OR r_to_import.rule_type IS NULL) THEN - b_nat_rule := TRUE; - ELSE - b_nat_rule := FALSE; - END IF; - - IF r_to_import.rule_type = 'original' THEN - SELECT INTO r_existing * FROM rule WHERE - rule_uid=r_to_import.rule_uid AND rule.mgm_id=i_mgm_id AND rule.dev_id=i_dev_id AND rule.active AND rule.nat_rule AND NOT rule.xlate_rule IS NULL; - ELSE - IF r_to_import.rule_type = 'xlate' THEN - SELECT INTO r_existing * FROM rule WHERE - rule_uid=r_to_import.rule_uid AND rule.mgm_id=i_mgm_id AND rule.dev_id=i_dev_id AND rule.active AND rule.nat_rule AND rule.xlate_rule IS NULL; - ELSE -- standard access rule or combined original rule - SELECT INTO r_existing * FROM rule WHERE - rule_uid=r_to_import.rule_uid AND rule.mgm_id=i_mgm_id AND rule.dev_id=i_dev_id AND rule.active AND rule.access_rule AND - ((rule.nat_rule AND rule.xlate_rule IS NOT NULL) OR NOT rule.nat_rule AND rule.xlate_rule IS NULL); - END IF; - END IF; - - IF FOUND THEN -- rule already exists - -- IF security_relevant_change(r_existing, r_to_import, i_fromzone, i_tozone, i_action_id, i_track_id) THEN - IF ( NOT ( - are_equal(r_existing.rule_uid, r_to_import.rule_uid) AND - are_equal(r_existing.rule_ruleid,r_to_import.rule_ruleid) AND - are_equal(r_existing.rule_from_zone,i_fromzone) AND - are_equal(r_existing.rule_to_zone,i_tozone) AND - are_equal(r_existing.rule_disabled, r_to_import.rule_disabled) AND - are_equal(r_existing.rule_src, r_to_import.rule_src) AND - are_equal(r_existing.rule_dst, r_to_import.rule_dst) AND - are_equal(r_existing.rule_svc, r_to_import.rule_svc) AND - are_equal(r_existing.rule_src_refs,r_to_import.rule_src_refs) AND - are_equal(r_existing.rule_dst_refs, r_to_import.rule_dst_refs) AND - are_equal(r_existing.rule_svc_refs, r_to_import.rule_svc_refs) AND - are_equal(r_existing.rule_src_neg, r_to_import.rule_src_neg) AND - are_equal(r_existing.rule_dst_neg, r_to_import.rule_dst_neg) AND - are_equal(r_existing.rule_svc_neg, r_to_import.rule_svc_neg) AND - are_equal(r_existing.action_id, i_action_id) AND - are_equal(r_existing.track_id, i_track_id) AND - are_equal(r_existing.rule_installon, r_to_import.rule_installon) AND - are_equal(r_existing.rule_time, r_to_import.rule_time) )) - THEN - b_change := TRUE; - b_change_sr := TRUE; - END IF; - -- IF non_security_relevant_change(r_existing, r_to_import) THEN - IF ( NOT ( -- from here: non-security-relevant changes - are_equal(r_existing.rule_name,r_to_import.rule_name) AND - are_equal(r_existing.rule_head_text, r_to_import.rule_head_text) AND - are_equal(r_existing.rule_comment, r_to_import.rule_comment) )) - THEN - b_change := TRUE; - END IF; - IF (b_change) - THEN - v_change_id := 'INFO_RULE_CHANGED'; - ELSE - UPDATE rule SET rule_last_seen = i_control_id WHERE rule_id = r_existing.rule_id; - END IF; - ELSE -- rule was changed - b_insert := TRUE; - v_change_id := 'INFO_RULE_INSERTED'; - END IF; - IF (b_change OR b_insert) THEN - PERFORM error_handling(v_change_id, r_to_import.rule_uid); - i_admin_id := get_admin_id_from_name(r_to_import.last_change_admin); - -- execute INSERT statement - IF r_to_import.rule_svc IS NULL OR r_to_import.rule_src IS NULL OR r_to_import.rule_dst IS NULL THEN - RAISE NOTICE 'rule_change with svc, dst or svc = NULL: %', r_to_import.rule_uid; - ELSE - SELECT INTO r_meta rule_metadata_id FROM rule_metadata WHERE dev_id=i_dev_id AND rule_uid=r_to_import.rule_uid; - IF FOUND THEN - UPDATE rule_metadata SET rule_last_modified=now() WHERE dev_id=i_dev_id AND rule_uid=CAST(r_to_import.rule_uid AS TEXT); - ELSE - INSERT INTO rule_metadata (rule_uid, dev_id) VALUES(r_to_import.rule_uid, i_dev_id); - END IF; - i_parent_rule_id := NULL; - i_parent_rule_type := NULL; - IF NOT r_to_import.parent_rule_uid IS NULL THEN - SELECT INTO r_parent_rule rule_id, rule_head_text, action_name FROM rule LEFT JOIN stm_action USING (action_id) WHERE rule_uid=r_to_import.parent_rule_uid AND rule_last_seen=i_control_id; - IF NOT FOUND THEN - RAISE WARNING 'rule_change found reference to parent rule with uid (%) that cannot be found in import. Importing without parent reference.', - r_to_import.parent_rule_uid; - i_parent_rule_id := NULL; - ELSE - i_parent_rule_id := r_parent_rule.rule_id; - IF r_parent_rule.action_name = 'inline-layer' THEN - i_parent_rule_type := 2; -- layer guard - ELSIF NOT r_parent_rule.rule_head_text IS NULL AND NOT r_parent_rule.rule_head_text='Placeholder for domain rules' THEN - i_parent_rule_type := 1; -- standard section - ELSIF NOT r_parent_rule.rule_head_text IS NULL AND r_parent_rule.rule_head_text='Placeholder for domain rules' THEN - i_parent_rule_type := 3; -- domain rule section - END IF; - END IF; - END IF; - BEGIN -- catch insert rule exception block - INSERT INTO rule - (mgm_id,rule_name,rule_num,rule_ruleid,rule_uid,rule_disabled,rule_src_neg,rule_dst_neg,rule_svc_neg, - action_id,track_id,rule_src,rule_dst,rule_svc,rule_src_refs,rule_dst_refs,rule_svc_refs,rule_action,rule_track,rule_installon,rule_time, - rule_from_zone,rule_to_zone,rule_comment,rule_implied,rule_head_text,last_change_admin, - rule_create,rule_last_seen, dev_id, parent_rule_id, parent_rule_type, access_rule, nat_rule) - VALUES (i_mgm_id,r_to_import.rule_name,i_rule_num,r_to_import.rule_ruleid,r_to_import.rule_uid, - r_to_import.rule_disabled,r_to_import.rule_src_neg,r_to_import.rule_dst_neg,r_to_import.rule_svc_neg, - i_action_id,i_track_id,r_to_import.rule_src,r_to_import.rule_dst,r_to_import.rule_svc, - r_to_import.rule_src_refs,r_to_import.rule_dst_refs,r_to_import.rule_svc_refs, - lower(r_to_import.rule_action),r_to_import.rule_track,r_to_import.rule_installon,r_to_import.rule_time, - i_fromzone,i_tozone, r_to_import.rule_comment,r_to_import.rule_implied,r_to_import.rule_head_text,i_admin_id, - i_control_id,i_control_id, i_dev_id, i_parent_rule_id, i_parent_rule_type, b_access_rule, b_nat_rule) - RETURNING rule_id INTO i_new_rule_id; - EXCEPTION WHEN OTHERS THEN - RAISE EXCEPTION 'rule_change_change exception while inserting rule: - mgm_id=% - rule_name=% - rule_num=% - rule_ruleid=% - rule_uid=% - rule_disabled=% - rule_src_neg=% - rule_dst_neg=% - rule_svc_neg=% - action_id=% - track_id=% - rule_src=% - rule_dst=% - rule_svc=% - rule_src_refs=% - rule_dst_refs=% - rule_svc_refs=% - rule_action=% - rule_track=% - rule_installon=% - rule_time=% - rule_from_zone=% - rule_to_zone=% - rule_comment=% - rule_implied=% - rule_head_text=% - last_change_admin=% - rule_create=% - rule_last_seen=% - dev_id=% - parent_rule_id=% - parent_rule_type=% - access_rule=% - nat_rule=%', - i_mgm_id,r_to_import.rule_name,i_rule_num,r_to_import.rule_ruleid,r_to_import.rule_uid, - r_to_import.rule_disabled,r_to_import.rule_src_neg,r_to_import.rule_dst_neg,r_to_import.rule_svc_neg, - i_action_id,i_track_id,r_to_import.rule_src,r_to_import.rule_dst,r_to_import.rule_svc, - r_to_import.rule_src_refs,r_to_import.rule_dst_refs,r_to_import.rule_svc_refs, - lower(r_to_import.rule_action),r_to_import.rule_track,r_to_import.rule_installon,r_to_import.rule_time, - i_fromzone,i_tozone, r_to_import.rule_comment,r_to_import.rule_implied,r_to_import.rule_head_text,i_admin_id, - i_control_id,i_control_id, i_dev_id, i_parent_rule_id, i_parent_rule_type, b_access_rule, b_nat_rule; - END; - - -- make changelog entry - IF (b_insert) THEN -- rule was inserted and is no header rule - IF b_is_initial_import - THEN b_is_documented := TRUE; i_change_type := 2; - ELSE b_is_documented := FALSE; t_outtext := NULL; i_change_type := 3; - END IF; - v_change_action := 'I'; - i_old_rule_id := NULL; - IF r_to_import.rule_head_text IS NULL THEN - b_change_sr := TRUE; - t_outtext := NULL; - b_is_documented := FALSE; - ELSE - t_outtext := 'not sec relevant'; - b_is_documented := TRUE; - b_change_sr := FALSE; - END IF; - ELSE -- change - i_change_type := 3; - IF (b_change_sr) THEN - t_outtext := NULL; - b_is_documented := FALSE; - ELSE - t_outtext := 'NON_SECURITY_RELEVANT_CHANGE'; - b_is_documented := TRUE; - END IF; - -- todo: add test if it is only a rename, then we would not add a changelog_rule entry in the future - v_change_action := 'C'; - i_old_rule_id := r_existing.rule_id; - UPDATE rule SET active = FALSE WHERE rule_id = i_old_rule_id; -- change old rule version to non-active - PERFORM import_rule_resolved_nwobj(i_mgm_id, i_old_rule_id, NULL, NULL, i_control_id, v_change_action, 'R'); - END IF; - INSERT INTO changelog_rule - (control_id,new_rule_id,old_rule_id,change_action,import_admin,documented,changelog_rule_comment, - mgm_id,dev_id,change_type_id,security_relevant) - VALUES - (i_control_id,i_new_rule_id,i_old_rule_id,v_change_action,i_admin_id,b_is_documented, - t_outtext,i_mgm_id,i_dev_id,i_change_type,b_change_sr); - END IF; - END IF; - RETURN i_new_rule_id; -END; -$$ LANGUAGE plpgsql; diff --git a/roles/database/files/sql/idempotent/fworch-rule-recert.sql b/roles/database/files/sql/idempotent/fworch-rule-recert.sql index 53e1b16c59..fc20f6919e 100644 --- a/roles/database/files/sql/idempotent/fworch-rule-recert.sql +++ b/roles/database/files/sql/idempotent/fworch-rule-recert.sql @@ -7,8 +7,6 @@ -- (once per statement, not per row) - - -- fundamental function to check owner <--> rule mapping using the existing view -- "view_rule_with_owner" CREATE OR REPLACE FUNCTION recert_owner_responsible_for_rule (i_owner_id INTEGER, i_rule_id BIGINT) RETURNS BOOLEAN AS $$ @@ -106,7 +104,7 @@ BEGIN b_never_recertified := TRUE; SELECT INTO t_rule_created rule_metadata.rule_created FROM rule - LEFT JOIN rule_metadata ON (rule.rule_uid=rule_metadata.rule_uid AND rule.dev_id=rule_metadata.dev_id) + LEFT JOIN rule_metadata ON (rule.rule_uid=rule_metadata.rule_uid AND rule.mgm_id = rule_metadata.mgm_id) WHERE rule_id=r_rule.rule_id; END IF; @@ -132,39 +130,25 @@ BEGIN DELETE FROM recertification WHERE owner_id=i_owner_id AND rule_id=r_rule.rule_id AND recert_date IS NULL; -- add new recert entry: - IF b_super_owner THEN -- special case for super owner (convert NULL to ID) - INSERT INTO recertification (rule_metadata_id, next_recert_date, rule_id, ip_match, owner_id) - SELECT rule_metadata_id, - t_next_recert_date AS next_recert_date, - rule_id, - matches as ip_match, - i_owner_id AS owner_id - FROM view_rule_with_owner - LEFT JOIN rule USING (rule_id) - LEFT JOIN rule_metadata ON (rule.rule_uid=rule_metadata.rule_uid AND rule.dev_id=rule_metadata.dev_id) - WHERE view_rule_with_owner.rule_id=r_rule.rule_id AND view_rule_with_owner.owner_id IS NULL; - ELSE - INSERT INTO recertification (rule_metadata_id, next_recert_date, rule_id, ip_match, owner_id) - SELECT rule_metadata_id, - t_next_recert_date AS next_recert_date, - rule_id, - matches as ip_match, - i_owner_id AS owner_id - FROM view_rule_with_owner - LEFT JOIN rule USING (rule_id) - LEFT JOIN rule_metadata ON (rule.rule_uid=rule_metadata.rule_uid AND rule.dev_id=rule_metadata.dev_id) - WHERE view_rule_with_owner.rule_id=r_rule.rule_id AND view_rule_with_owner.owner_id=i_owner_id; - END IF; + INSERT INTO recertification (rule_metadata_id, next_recert_date, rule_id, ip_match, owner_id) + SELECT rule_metadata_id, + t_next_recert_date AS next_recert_date, + rule_id, + matches AS ip_match, + i_owner_id AS owner_id + FROM view_rule_with_owner + LEFT JOIN rule USING (rule_id) + LEFT JOIN rule_metadata ON (rule.rule_uid=rule_metadata.rule_uid AND rule.mgm_id = rule_metadata.mgm_id) + WHERE view_rule_with_owner.rule_id=r_rule.rule_id + AND ( + (b_super_owner AND view_rule_with_owner.owner_id IS NULL) + OR (NOT b_super_owner AND view_rule_with_owner.owner_id=i_owner_id) + ); ELSE -- delete old outdated recert entry if owner is not responsible any more DELETE FROM recertification WHERE owner_id=i_owner_id AND rule_id=r_rule.rule_id AND recert_date IS NULL; END IF; END LOOP; - - -- -- finally, when not super user - recalculate super user recert entries - since these might change with each owner change - -- IF NOT b_super_owner AND b_super_owner_exists THEN - -- PERFORM recert_refresh_one_owner_one_mgm (i_super_owner_id, i_mgm_id, t_requested_next_recert_date); - -- END IF; END IF; END; $$ LANGUAGE plpgsql; @@ -188,81 +172,66 @@ BEGIN END; $$ LANGUAGE plpgsql; +-- select * from recert_get_one_owner_one_mgm(4,1) --- this function returns a table of future recert entries +-- This function returns a table of future recert entries -- but does not write them into the recertification table -CREATE OR REPLACE FUNCTION recert_get_one_owner_one_mgm - (i_owner_id INTEGER, i_mgm_id INTEGER) - RETURNS SETOF recertification AS +CREATE OR REPLACE FUNCTION recert_get_one_owner_one_mgm( + i_owner_id INTEGER, + i_mgm_id INTEGER +) +RETURNS SETOF recertification AS $$ DECLARE - b_super_owner BOOLEAN := FALSE; - i_recert_entry_id INTEGER; - i_super_owner_interval INTEGER; + b_super_owner BOOLEAN := FALSE; + i_recert_entry_id INTEGER; + i_recert_interval INTEGER; BEGIN - SELECT INTO i_recert_entry_id id FROM owner WHERE id=i_owner_id AND is_default; - IF FOUND THEN - b_super_owner := TRUE; - END IF; - - -- ignore rule_id/owner_id combinations with existing decertification entries - -- owner_id=0 and not recertified and NOT recert_date is null - IF b_super_owner THEN - SELECT INTO i_super_owner_interval recert_interval FROM OWNER WHERE is_default; - - RETURN QUERY - SELECT DISTINCT - NULL::bigint AS id, - M.rule_metadata_id, - R.rule_id, - V.matches::VARCHAR as ip_match, - 0::int as owner_id, - NULL::VARCHAR AS user_dn, - FALSE::BOOLEAN AS recertified, - NULL::TIMESTAMP AS recert_date, - NULL::VARCHAR AS comment, - MAX((SELECT MAX(value)::TIMESTAMP AS next_recert_date - FROM ( - SELECT I.start_time::timestamp + make_interval (days => o.recert_interval) AS value - UNION - SELECT C.recert_date + make_interval (days => o.recert_interval) AS value - ) AS temp_table)) - FROM - view_rule_with_owner V - LEFT JOIN rule R USING (rule_id) - LEFT JOIN rule_metadata M ON (R.rule_uid=M.rule_uid AND R.dev_id=M.dev_id) - LEFT JOIN owner O ON (O.id=0) - LEFT JOIN import_control I ON (R.rule_create=I.control_id) - LEFT JOIN recertification C ON (M.rule_metadata_id=C.rule_metadata_id) - WHERE V.owner_id IS NULL AND R.mgm_id=i_mgm_id AND R.active AND (recert_date IS NULL OR (NOT recert_date IS NULL AND recertified)) - GROUP BY M.rule_metadata_id, R.rule_id, V.matches; - ELSE - RETURN QUERY - SELECT - NULL::bigint AS id, - M.rule_metadata_id, - R.rule_id, - V.matches::VARCHAR as ip_match, - i_owner_id, - NULL::VARCHAR AS user_dn, - FALSE::BOOLEAN AS recertified, - NULL::TIMESTAMP AS recert_date, - NULL::VARCHAR AS comment, - MAX((SELECT MAX(value)::TIMESTAMP AS next_recert_date - FROM ( - SELECT I.start_time::timestamp + make_interval (days => o.recert_interval) AS value - UNION - SELECT C.recert_date + make_interval (days => o.recert_interval) AS value - ) AS temp_table)) - FROM - view_rule_with_owner V - LEFT JOIN rule R USING (rule_id) - LEFT JOIN rule_metadata M ON (R.rule_uid=M.rule_uid AND R.dev_id=M.dev_id) - LEFT JOIN owner O ON (V.owner_id=O.id) - LEFT JOIN import_control I ON (R.rule_create=I.control_id) - LEFT JOIN recertification C ON (M.rule_metadata_id=C.rule_metadata_id) - WHERE V.owner_id=i_owner_id AND R.mgm_id=i_mgm_id AND R.active AND (recert_date IS NULL OR (NOT recert_date IS NULL AND recertified)) - GROUP BY M.rule_metadata_id, R.rule_id, V.matches; - END IF; + SELECT INTO i_recert_entry_id id FROM owner WHERE id=i_owner_id AND is_default; + IF FOUND THEN + b_super_owner := TRUE; + END IF; + + SELECT INTO i_recert_interval recert_interval FROM owner WHERE id=i_owner_id; + + -- ignore rule_id/owner_id combinations with existing decertification entries + -- owner_id=0 and not recertified and NOT recert_date is null + RETURN QUERY + SELECT + NULL::bigint AS id, + M.rule_metadata_id, + R.rule_id, + V.matches::VARCHAR AS ip_match, + CASE + WHEN b_super_owner THEN 0::int + ELSE i_owner_id + END AS owner_id, + NULL::VARCHAR AS user_dn, + FALSE::BOOLEAN AS recertified, + NULL::TIMESTAMP AS recert_date, + NULL::VARCHAR AS comment, + MAX(( + SELECT MAX(value)::TIMESTAMP AS next_recert_date + FROM ( + SELECT I.start_time::timestamp + make_interval (days => i_recert_interval) AS value + UNION + SELECT C.recert_date + make_interval (days => i_recert_interval) AS value + ) AS temp_table + )), + NULL::bigint AS owner_recert_id + FROM + view_rule_with_owner V + LEFT JOIN rule R USING (rule_id) + LEFT JOIN rule_metadata M ON (R.rule_uid=M.rule_uid AND R.mgm_id = M.mgm_id) + LEFT JOIN import_control I ON (R.rule_create=I.control_id) + LEFT JOIN recertification C ON (M.rule_metadata_id=C.rule_metadata_id) + WHERE R.mgm_id=i_mgm_id + AND R.active + AND (recert_date IS NULL OR (NOT recert_date IS NULL AND recertified)) + AND ( + (b_super_owner AND V.owner_id IS NULL) + OR (NOT b_super_owner AND V.owner_id=i_owner_id) + ) + GROUP BY M.rule_metadata_id, R.rule_id, V.matches; END; $$ LANGUAGE plpgsql STABLE; diff --git a/roles/database/files/sql/idempotent/fworch-rule-refs.sql b/roles/database/files/sql/idempotent/fworch-rule-refs.sql deleted file mode 100644 index beddbb1bb5..0000000000 --- a/roles/database/files/sql/idempotent/fworch-rule-refs.sql +++ /dev/null @@ -1,373 +0,0 @@ --- $Id: iso-rule-refs.sql,v 1.1.2.9 2011-09-28 21:33:17 tim Exp $ --- $Source: /home/cvs/iso/package/install/database/Attic/iso-rule-refs.sql,v $ - ----------------------------------------------------- --- FUNCTION: resolve_all_rule_lists --- Zweck: Generiert die Beziehungen in rule_from, rule_to, rule_svc --- Zweck: fuer alle aktuell importierten, geaenderten Regelteile des Device mit dev-id --- Zweck: orientiert sich dabei an den aktuellen changelog-Eintraegen --- Parameter1: import_id --- Parameter2: device_id --- verwendete --- Funktionen: resolve_rule_list_obj, resolve_rule_list_svc, resolve_rule_list_user --- RETURNS: nix --- -CREATE OR REPLACE FUNCTION import_rule_refhandler_main(BIGINT,INTEGER) RETURNS VOID AS $$ -DECLARE - i_current_import_id ALIAS FOR $1; -- Import-ID - i_dev_id ALIAS FOR $2; -- Device ID - r_liste RECORD; -- Record fuer Liste - r_control RECORD; -- Record fuer import control (Trennzeichen, Mangement) -BEGIN - BEGIN - SELECT INTO r_control mgm_id,delimiter_group,delimiter_user,delimiter_zone,delimiter_list FROM import_control - WHERE control_id=i_current_import_id; - -- fuer alle neuen Regeln - FOR r_liste IN - SELECT rule.rule_uid, rule.rule_from_zone,rule.rule_to_zone,rule.rule_id,rule.rule_src,rule.rule_dst,rule.rule_svc, - rule.rule_src_refs,rule.rule_dst_refs,rule.rule_svc_refs - FROM changelog_rule,rule WHERE - changelog_rule.dev_id = i_dev_id AND - changelog_rule.new_rule_id = rule.rule_id AND - changelog_rule.control_id = i_current_import_id AND - changelog_rule.change_action <> 'D' -- create new entries in rule_XXX for inserted or changed rules - LOOP - RAISE DEBUG '%', 'processing rule no. ' || r_liste.rule_uid || ': ' || r_liste.rule_src || ' --> ' || r_liste.rule_dst || ' with services: ' || r_liste.rule_svc; - -- PERFORM error_handling('DEBUG_GENERAL_INFO', CAST(r_liste.rule_id AS VARCHAR)); - PERFORM resolve_rule_list (r_liste.rule_id, 'rule_from',r_liste.rule_src_refs, r_control.mgm_id, - r_liste.rule_from_zone, r_control.delimiter_list,i_current_import_id); - PERFORM resolve_rule_list (r_liste.rule_id, 'rule_to', r_liste.rule_dst_refs, r_control.mgm_id, - r_liste.rule_to_zone, r_control.delimiter_list,i_current_import_id); - PERFORM resolve_rule_list (r_liste.rule_id, 'rule_service', r_liste.rule_svc_refs, r_control.mgm_id, - 0, r_control.delimiter_list, i_current_import_id); - END LOOP; - EXCEPTION WHEN OTHERS THEN - -- the following log entry gets rolled-back as we have to raise another exception to avoid a half-finished import state for this rulebase - -- alternatively we need to avoid the error where it occurs and not raise any exceptions, just add the log_data_issue and leave out the single object that is broken - -- -- 1 2 3 4 5 6 7 8 9 10 11 12 - -- PERFORM add_data_issue('import', 3, NULL, i_current_import_id, NULL, NULL, r_liste.rule_uid, r_liste.rule_id, NULL, i_dev_id, NULL, - -- 'broken ref in rule', 'non-existant object referenced in rule with UID ' || r_liste.rule_uid); - RAISE EXCEPTION 'Exception caught in import_rule_refhandler_main while handling rule %', r_liste.rule_uid; - END; - RETURN; -END; -$$ LANGUAGE plpgsql; - ----------------------------------------------------- --- FUNCTION: resolve_rule_list --- Zweck: die Liste $3 aufloesen --- Zweck: und in rule_from,rule_to,rule_svc eintragen --- Parameter: $1: rule_id --- Parameter: $2: Zieltabelle (rule_from|rule_to|rule_svc) --- Parameter: $3: Liste von Elementen in Stringform --- Parameter: $4: mgm_id des aktuellen imports --- Parameter: $5: zone_id der aktuellen Regel (entweder from oder to, bei svc dummy=0) --- Parameter: $6: Trennzeichen zwischen den Listenmitgliedern in $3 --- Parameter: $7: current import id --- verwendete --- Funktionen: f_add_single_list_element, resolve_rule_list (rekursiv) --- RETURNS: VOID --- - -CREATE OR REPLACE FUNCTION resolve_rule_list (BIGINT,varchar,varchar,integer,BIGINT,varchar,BIGINT) RETURNS VOID AS $$ -DECLARE - i_rule_id ALIAS FOR $1; - v_dst_table ALIAS FOR $2; - v_member_string ALIAS FOR $3; - i_mgm_id ALIAS FOR $4; - i_zone_id ALIAS FOR $5; - v_delimiter ALIAS FOR $6; - i_current_import_id ALIAS FOR $7; - v_current_member varchar; -BEGIN - RAISE DEBUG 'resolve_rule_list - 1 starting, v_member_string=%', v_member_string; - RAISE DEBUG 'resolve_rule_list - 2 dst_table=%', v_dst_table; - IF v_member_string IS NULL OR v_member_string='' THEN RETURN; END IF; - FOR v_current_member IN SELECT member FROM regexp_split_to_table(v_member_string, E'\\' || v_delimiter) AS member LOOP - IF NOT (v_current_member IS NULL OR v_current_member='') THEN - RAISE DEBUG 'resolve_rule_list - 3 adding list refs for %.', v_current_member; - IF v_dst_table = 'rule_from' THEN - PERFORM f_add_single_rule_from_element(i_rule_id, v_current_member, i_mgm_id, i_zone_id, i_current_import_id); - ELSIF v_dst_table = 'rule_to' THEN - PERFORM f_add_single_rule_to_element(i_rule_id, v_current_member, i_mgm_id, i_zone_id, i_current_import_id); - ELSIF v_dst_table = 'rule_service' THEN - PERFORM f_add_single_rule_svc_element(i_rule_id, v_current_member, i_mgm_id, i_current_import_id); - END IF; - END IF; - END LOOP; - RETURN; -END; -$$ LANGUAGE plpgsql; - ----------------------------------------------------- --- FUNCTION: f_add_single_rule_from_element --- Zweck: die Elemente der Liste $2 aufloesen --- Zweck: und in rule_from eintragen --- Parameter: $1: rule_id --- Parameter: $2: einzelnes Listenelement --- Parameter: $3: Management-ID --- Parameter: $4: Zone-ID (netscreen only) --- Parameter: $5: current import id --- verwendete --- Funktionen: KEINE --- RETURNS: VOID --- -CREATE OR REPLACE FUNCTION f_add_single_rule_from_element(BIGINT,varchar,integer,BIGINT,BIGINT) RETURNS VOID AS $$ -DECLARE - i_rule_id ALIAS FOR $1; - v_element ALIAS FOR $2; - i_mgm_id ALIAS FOR $3; - i_zone_id ALIAS FOR $4; - i_current_import_id ALIAS FOR $5; - i_obj BIGINT; - i_usr BIGINT; - i_at_sign_pos INTEGER; - v_usergroup_name VARCHAR; - v_src_obj VARCHAR; - r_debug RECORD; - v_error_str VARCHAR; -BEGIN - RAISE DEBUG 'f_add_single_rule_from_element - 1 starting for %', v_element; - i_at_sign_pos := instr(v_element,'@'); - IF i_at_sign_pos > 0 THEN -- User-Gruppen enthalten - v_usergroup_name := substr(v_element,0,i_at_sign_pos); - v_src_obj := substr(v_element,i_at_sign_pos+1); - SELECT INTO i_usr user_id FROM usr WHERE user_uid=v_usergroup_name AND mgm_id=i_mgm_id AND active; - IF NOT FOUND THEN - PERFORM error_handling('ERR_LST_EL_MISS', 'User: ' || v_usergroup_name); - END IF; - ELSE - v_src_obj := v_element; - i_usr := NULL; -- auf 'nouser' gesetzt - END IF; - - IF i_zone_id IS NULL THEN -- wenn zoneID leer: ignoriere das Feld - SELECT INTO i_obj obj_id FROM object WHERE obj_uid=v_src_obj AND mgm_id=i_mgm_id AND active; - ELSE - SELECT INTO i_obj obj_id FROM object WHERE obj_uid=v_src_obj AND zone_id=i_zone_id AND mgm_id=i_mgm_id AND active; - IF NOT FOUND THEN -- trying without zone (assuming global zone for junos) - SELECT INTO i_obj obj_id FROM object WHERE obj_uid=v_src_obj AND mgm_id=i_mgm_id AND active; - END IF; - END IF; - IF NOT FOUND THEN - PERFORM error_handling('ERR_LST_EL_MISS', 'Obj: ' || v_src_obj); - END IF; - IF i_usr IS NULL THEN - SELECT INTO r_debug rule_id,obj_id,user_id FROM rule_from - WHERE rule_id=i_rule_id AND obj_id=i_obj AND rf_create=i_current_import_id AND rf_last_seen=i_current_import_id; - ELSE - SELECT INTO r_debug rule_id,obj_id,user_id FROM rule_from - WHERE rule_id=i_rule_id AND obj_id=i_obj AND user_id=i_usr AND rf_create=i_current_import_id AND rf_last_seen=i_current_import_id; - END IF; - - IF FOUND THEN -- debug duplicate objects - SELECT INTO r_debug obj_name,obj_uid FROM object WHERE obj_id = r_debug.obj_id; - v_error_str := ''; - IF NOT r_debug.obj_name IS NULL THEN - v_error_str := 'object: ' || r_debug.obj_name || '(uid: ' || r_debug.obj_uid || '), '; - ELSE - v_error_str := 'unknown object, '; - END IF; - SELECT INTO r_debug rule_uid FROM rule WHERE rule_id = i_rule_id; - IF NOT r_debug.rule_uid IS NULL THEN - v_error_str := 'rule: ' || r_debug.rule_uid; - ELSE - v_error_str := 'unknown rule'; - END IF; - PERFORM error_handling('ERR_RULE_DBL_OBJ', v_error_str); - ELSE - RAISE DEBUG 'f_add_single_rule_from_element - 3 before inserting'; - IF (NOT i_obj IS NULL) THEN - IF i_usr IS NULL THEN - INSERT INTO rule_from (rule_id,obj_id,rf_create,rf_last_seen) - VALUES (i_rule_id,i_obj,i_current_import_id,i_current_import_id); - ELSE - INSERT INTO rule_from (rule_id,obj_id,user_id,rf_create,rf_last_seen) - VALUES (i_rule_id,i_obj,i_usr,i_current_import_id,i_current_import_id); - BEGIN - PERFORM import_rule_resolved_usr(i_mgm_id, i_rule_id, NULL, i_usr, i_current_import_id, 'I', 'R'); - EXCEPTION - WHEN others THEN - raise notice 'f_add_single_rule_from_element - rule_from with user import_rule_resolved_usr - uncommittable state. Rolling back'; - raise notice '% %', SQLERRM, SQLSTATE; - END; - - END IF; - BEGIN - PERFORM import_rule_resolved_nwobj(i_mgm_id, i_rule_id, NULL, i_obj, i_current_import_id, 'I', 'R'); - EXCEPTION - WHEN others THEN - raise notice 'f_add_single_rule_from_element - rule_from import_rule_resolved_nwobj - uncommittable state. Rolling back'; - raise EXCEPTION '% %', SQLERRM, SQLSTATE; - END; - - END IF; - END IF; - RETURN; -END; -$$ LANGUAGE plpgsql; - ----------------------------------------------------- --- FUNCTION: f_add_single_rule_to_element --- Zweck: die Elemente der Liste $2 aufloesen --- Zweck: und in rule_to eintragen --- Parameter: $1: rule_id --- Parameter: $2: einzelnes Listenelement --- Parameter: $3: Management-ID --- Parameter: $4: Zone-ID (netscreen only) --- Parameter: $5: current import id - --- verwendete --- Funktionen: KEINE --- RETURNS: VOID --- -CREATE OR REPLACE FUNCTION f_add_single_rule_to_element(BIGINT,varchar,integer,BIGINT,BIGINT) RETURNS VOID AS $$ -DECLARE - i_rule_id ALIAS FOR $1; - v_element ALIAS FOR $2; - i_mgm_id ALIAS FOR $3; - i_zone_id ALIAS FOR $4; - i_current_import_id ALIAS FOR $5; - r_obj RECORD; - v_error_str VARCHAR; - i_usr BIGINT; - i_at_sign_pos INTEGER; - v_usergroup_name VARCHAR; - v_dst_obj VARCHAR; - r_debug RECORD; -BEGIN - - i_at_sign_pos := instr(v_element,'@'); - IF i_at_sign_pos > 0 THEN -- User-Gruppen enthalten - v_usergroup_name := substr(v_element,0,i_at_sign_pos); - v_dst_obj := substr(v_element,i_at_sign_pos+1); - SELECT INTO i_usr user_id FROM usr WHERE user_uid=v_usergroup_name AND mgm_id=i_mgm_id AND active; - IF NOT FOUND THEN - PERFORM error_handling('ERR_LST_EL_MISS', 'User: ' || v_usergroup_name); - END IF; - ELSE - v_dst_obj := v_element; - i_usr := NULL; -- auf 'nouser' gesetzt - END IF; - - IF i_zone_id IS NULL THEN - SELECT INTO r_obj obj_id FROM object WHERE obj_uid=v_dst_obj AND mgm_id=i_mgm_id AND active; - ELSE - SELECT INTO r_obj obj_id FROM object WHERE obj_uid=v_dst_obj AND zone_id=i_zone_id AND mgm_id=i_mgm_id AND active; - IF NOT FOUND THEN - SELECT INTO r_obj obj_id FROM object WHERE obj_uid=v_dst_obj AND mgm_id=i_mgm_id AND active; - END IF; - END IF; - IF NOT FOUND THEN - PERFORM error_handling('ERR_LST_EL_MISS', v_dst_obj); - ELSE --- TODO: check if exactly one hit found - END IF; - IF i_usr IS NULL THEN - SELECT INTO r_debug rule_id,obj_id,user_id FROM rule_to - WHERE rule_id=i_rule_id AND obj_id=r_obj.obj_id AND rt_create=i_current_import_id AND rt_last_seen=i_current_import_id; - ELSE - SELECT INTO r_debug rule_id,obj_id,user_id FROM rule_to - WHERE rule_id=i_rule_id AND obj_id=r_obj.obj_id AND user_id=i_usr AND rt_create=i_current_import_id AND rt_last_seen=i_current_import_id; - END IF; - - IF FOUND THEN -- debug duplicate objects - SELECT INTO r_debug obj_name,obj_uid FROM object WHERE obj_id = r_debug.obj_id; - v_error_str := ''; - IF NOT r_debug.obj_name IS NULL THEN - v_error_str := 'object: ' || r_debug.obj_name || '(uid: ' || r_debug.obj_uid || '), '; - ELSE - v_error_str := 'unknown object, '; - END IF; - SELECT INTO r_debug rule_uid FROM rule WHERE rule_id = i_rule_id; - IF NOT r_debug.rule_uid IS NULL THEN - v_error_str := 'rule: ' || r_debug.rule_uid; - ELSE - v_error_str := 'unknown rule'; - END IF; - PERFORM error_handling('ERR_RULE_DBL_OBJ', v_error_str); - ELSE - IF (NOT r_obj.obj_id IS NULL) THEN - IF i_usr IS NULL THEN - INSERT INTO rule_to (rule_id,obj_id,rt_create,rt_last_seen) - VALUES (i_rule_id,r_obj.obj_id,i_current_import_id,i_current_import_id); - ELSE - INSERT INTO rule_to (rule_id,obj_id,user_id,rt_create,rt_last_seen) - VALUES (i_rule_id,r_obj.obj_id,i_usr,i_current_import_id,i_current_import_id); - BEGIN - PERFORM import_rule_resolved_usr(i_mgm_id, i_rule_id, NULL, i_usr, i_current_import_id, 'I', 'R'); - EXCEPTION - WHEN others THEN - raise notice 'f_add_single_rule_to_element - rule_to with user import_rule_resolved_usr - uncommittable state. Rolling back'; - raise notice '% %', SQLERRM, SQLSTATE; - END; - - END IF; - BEGIN - PERFORM import_rule_resolved_nwobj(i_mgm_id, i_rule_id, NULL, r_obj.obj_id, i_current_import_id, 'I', 'R'); - EXCEPTION - WHEN others THEN - raise notice 'f_add_single_rule_to_element - rule_to import_rule_resolved_nwobj - uncommittable state. Rolling back'; - raise EXCEPTION '% %', SQLERRM, SQLSTATE; - END; - - END IF; - END IF; - RETURN; -END; -$$ LANGUAGE plpgsql; - ----------------------------------------------------- --- FUNCTION: f_add_single_rule_svc_element --- Zweck: die Elemente der Liste $2 aufloesen --- Zweck: und in rule_svc eintragen --- Parameter: $1: rule_id --- Parameter: $2: einzelnes Listenelement --- Parameter: $3: Management-ID --- Parameter: $4: current import id --- verwendete --- Funktionen: KEINE --- RETURNS: VOID --- -CREATE OR REPLACE FUNCTION f_add_single_rule_svc_element(BIGINT,varchar,integer,BIGINT) RETURNS VOID AS $$ -DECLARE - i_rule_id ALIAS FOR $1; - v_element ALIAS FOR $2; - i_mgm_id ALIAS FOR $3; - i_current_import_id ALIAS FOR $4; - r_svc RECORD; - v_error_str VARCHAR; - r_debug RECORD; -BEGIN - SELECT INTO r_svc svc_id FROM service WHERE svc_uid=v_element AND mgm_id=i_mgm_id AND active; - IF NOT FOUND THEN - PERFORM error_handling('ERR_LST_EL_MISS', v_element); - END IF; - - SELECT INTO r_debug * FROM rule_service WHERE rule_id=i_rule_id AND - svc_id=r_svc.svc_id AND rs_create=i_current_import_id AND - rs_last_seen=i_current_import_id; - IF FOUND THEN --- RAISE NOTICE 'Error: found duplicate service in rule: %', v_element; - SELECT INTO r_debug svc_name,svc_uid FROM service WHERE svc_id = r_debug.svc_id; - v_error_str := ''; - IF NOT r_debug.svc_name IS NULL THEN - v_error_str := 'service: ' || r_debug.svc_name || '(uid: ' || r_debug.svc_uid || '), '; - ELSE - v_error_str := 'unknown service, '; - END IF; - SELECT INTO r_debug rule_uid FROM rule WHERE rule_id = i_rule_id; - IF NOT r_debug.rule_uid IS NULL THEN - v_error_str := 'rule: ' || r_debug.rule_uid; - ELSE - v_error_str := 'unknown rule'; - END IF; - PERFORM error_handling('ERR_RULE_DBL_OBJ', v_error_str); - ELSE - INSERT INTO rule_service (rule_id,svc_id,rs_create,rs_last_seen) - VALUES (i_rule_id,r_svc.svc_id,i_current_import_id,i_current_import_id); - PERFORM import_rule_resolved_svc(i_mgm_id, i_rule_id, NULL, r_svc.svc_id, i_current_import_id, 'I', 'R'); - END IF; - RETURN; -END; -$$ LANGUAGE plpgsql; diff --git a/roles/database/files/sql/idempotent/fworch-rule-resolved.sql b/roles/database/files/sql/idempotent/fworch-rule-resolved.sql deleted file mode 100644 index ee433e5e1b..0000000000 --- a/roles/database/files/sql/idempotent/fworch-rule-resolved.sql +++ /dev/null @@ -1,381 +0,0 @@ - --- all functions around the rule__resolved tables introduced with version 5.1.16 in May 2021 --- these functions add an entry to the respective rule__resolved table for each object contained in a rule --- used for quick reporting of objects used in a reported ruleset - -CREATE OR REPLACE FUNCTION import_rule_resolved_nwobj (INT,BIGINT,BIGINT,BIGINT,BIGINT,CHAR,CHAR) RETURNS VOID AS $$ -DECLARE - i_mgm_id ALIAS FOR $1; - i_rule_id ALIAS FOR $2; - i_old_obj_id ALIAS FOR $3; - i_new_obj_id ALIAS FOR $4; - i_current_import_id ALIAS FOR $5; - c_action ALIAS FOR $6; - c_changelog_table ALIAS FOR $7; - r_null RECORD; - i_member BIGINT; - i_matching_rule_id BIGINT; - i_matching_obj_id BIGINT; - r_search RECORD; -BEGIN - BEGIN -- catch - RAISE DEBUG 'import_rule_resolved_nwobj 0 enter - i_mgm_id=%, i_rule_id=%, i_old_obj_id=%, i_new_obj_id=%, i_current_import_id=%, c_action=%, c_changelog_table=%', - i_mgm_id, i_rule_id, i_old_obj_id, i_new_obj_id, i_current_import_id, c_action, c_changelog_table; - - -- rule has been deleted resp. changed, marking all existing rule/obj refs as removed - IF i_old_obj_id IS NULL AND i_new_obj_id IS NULL AND NOT i_rule_id IS NULL AND NOT c_action='I' THEN - -- handle ocurrences in all rules, if rule_id is NULL - RAISE DEBUG 'import_rule_resolved_nwobj 0a all obj of a rule - i_mgm_id=%, i_rule_id=%, i_old_obj_id=%, i_new_obj_id=%, i_current_import_id=%, c_action=%, c_changelog_table=%', - i_mgm_id, i_rule_id, i_old_obj_id, i_new_obj_id, i_current_import_id, c_action, c_changelog_table; - FOR i_matching_obj_id IN - SELECT obj_id FROM rule_nwobj_resolved WHERE mgm_id=i_mgm_id AND rule_id=i_rule_id AND removed IS NULL - LOOP - RAISE DEBUG 'import_rule_resolved_nwobj 0b obj loop - i_mgm_id=%, i_rule_id=%, i_old_obj_id=%, i_new_obj_id=%, i_current_import_id=%, c_action=%, c_changelog_table=%', - i_mgm_id, i_rule_id, i_matching_obj_id, NULL, i_current_import_id, c_action, c_changelog_table; - PERFORM import_rule_resolved_nwobj(i_mgm_id, i_rule_id, i_matching_obj_id, NULL, i_current_import_id, 'D', c_changelog_table); - END LOOP; - - -- handle ocurrences in all rules, if rule_id is NULL (caused by object change) - ELSIF i_rule_id IS NULL THEN - RAISE DEBUG 'import_rule_resolved_nwobj 0c no rule - i_mgm_id=%, i_rule_id=%, i_old_obj_id=%, i_new_obj_id=%, i_current_import_id=%, c_action=%, c_changelog_table=%', - i_mgm_id, i_rule_id, i_old_obj_id, i_new_obj_id, i_current_import_id, c_action, c_changelog_table; - IF NOT c_action='I' THEN -- no valid case, cannot insert everywhere, using C to replace old with new obj ref - FOR i_matching_rule_id IN - SELECT rule_id FROM rule_nwobj_resolved WHERE mgm_id=i_mgm_id AND obj_id=i_old_obj_id AND removed IS NULL - LOOP - RAISE DEBUG 'import_rule_resolved_nwobj 0d rule loop - i_mgm_id=%, i_rule_id=%, i_old_obj_id=%, i_new_obj_id=%, i_current_import_id=%, c_action=%, c_changelog_table=%', - i_mgm_id, i_rule_id, i_old_obj_id, i_new_obj_id, i_current_import_id, c_action, c_changelog_table; - PERFORM import_rule_resolved_nwobj(i_mgm_id, i_matching_rule_id, i_old_obj_id, i_new_obj_id, i_current_import_id, c_action, c_changelog_table); - END LOOP; - END IF; - - -- standard case: both one obj_id and rule_id are given: - ELSE - RAISE DEBUG 'import_rule_resolved_nwobj 1 ELSE enter - i_mgm_id=%, i_rule_id=%, i_old_obj_id=%, i_new_obj_id=%, i_current_import_id=%, c_action=%, c_changelog_table=%', - i_mgm_id, i_rule_id, i_old_obj_id, i_new_obj_id, i_current_import_id, c_action, c_changelog_table; - IF c_action = 'I' THEN - SELECT INTO r_null * FROM rule_nwobj_resolved WHERE mgm_id=i_mgm_id AND rule_id=i_rule_id AND obj_id=i_new_obj_id AND created=i_current_import_id; - RAISE DEBUG 'import_rule_resolved_nwobj 1 insert - i_mgm_id=%, i_rule_id=%, i_old_obj_id=%, i_new_obj_id=%, i_current_import_id=%, c_action=%, c_changelog_table=%', - i_mgm_id, i_rule_id, i_old_obj_id, i_new_obj_id, i_current_import_id, c_action, c_changelog_table; - IF NOT FOUND THEN - RAISE DEBUG 'import_rule_resolved_nwobj 1a insert - i_mgm_id=%, i_rule_id=%, i_old_obj_id=%, i_new_obj_id=%, i_current_import_id=%, c_action=%, c_changelog_table=%', - i_mgm_id, i_rule_id, i_old_obj_id, i_new_obj_id, i_current_import_id, c_action, c_changelog_table; - INSERT INTO rule_nwobj_resolved (mgm_id, rule_id, obj_id, created) VALUES (i_mgm_id, i_rule_id, i_new_obj_id, i_current_import_id); - END IF; - ELSIF c_action = 'D' THEN - RAISE DEBUG 'import_rule_resolved_nwobj 2 delete - i_mgm_id=%, i_rule_id=%, i_old_obj_id=%, i_new_obj_id=%, i_current_import_id=%, c_action=%, c_changelog_table=%', - i_mgm_id, i_rule_id, i_old_obj_id, i_new_obj_id, i_current_import_id, c_action, c_changelog_table; - UPDATE rule_nwobj_resolved SET removed=i_current_import_id WHERE rule_id=i_rule_id AND obj_id=i_old_obj_id AND removed IS NULL; - ELSIF c_action = 'C' THEN - RAISE DEBUG 'import_rule_resolved_nwobj 3 change - i_mgm_id=%, i_rule_id=%, i_old_obj_id=%, i_new_obj_id=%, i_current_import_id=%, c_action=%, c_changelog_table=%', - i_mgm_id, i_rule_id, i_old_obj_id, i_new_obj_id, i_current_import_id, c_action, c_changelog_table; - IF NOT i_old_obj_id IS NULL THEN - UPDATE rule_nwobj_resolved SET removed=i_current_import_id WHERE rule_id=i_rule_id AND obj_id=i_old_obj_id AND removed IS NULL; - END IF; - SELECT INTO r_null * FROM rule_nwobj_resolved WHERE mgm_id=i_mgm_id AND rule_id=i_rule_id AND obj_id=i_new_obj_id; -- AND created=i_current_import_id; - IF NOT FOUND THEN - RAISE DEBUG 'import_rule_resolved_nwobj 3a change - insert - i_mgm_id=%, i_rule_id=%, i_old_obj_id=%, i_new_obj_id=%, i_current_import_id=%, c_action=%, c_changelog_table=%', - i_mgm_id, i_rule_id, i_old_obj_id, i_new_obj_id, i_current_import_id, c_action, c_changelog_table; - IF NOT i_new_obj_id IS NULL THEN - INSERT INTO rule_nwobj_resolved (mgm_id, rule_id, obj_id, created) VALUES (i_mgm_id, i_rule_id, i_new_obj_id, i_current_import_id); - END IF; - END IF; - END IF; - - -- if the (new) object is a group, deal with all group members recursively - -- cannot use _flat group as this would leave out any intermediate groups - IF is_obj_group(i_new_obj_id) THEN -- treat all group members as well - RAISE DEBUG 'import_rule_resolved_nwobj 4 group - i_mgm_id=%, i_rule_id=%, i_old_obj_id=%, i_new_obj_id=%, i_current_import_id=%, c_action=%, c_changelog_table=%', - i_mgm_id, i_rule_id, i_old_obj_id, i_new_obj_id, i_current_import_id, c_action, c_changelog_table; - - -- make sure all new active members are in resolved table: - FOR i_member IN SELECT objgrp_member_id FROM objgrp WHERE active AND objgrp_id=i_new_obj_id AND - NOT objgrp_member_id in (SELECT objgrp_member_id FROM objgrp WHERE objgrp_id=i_old_obj_id) - -- do not add objects that were already in the old group - LOOP - RAISE DEBUG 'import_rule_resolved_nwobj 4a group loop - i_mgm_id=%, i_rule_id=%, i_old_obj_id=%, i_new_obj_id=%, i_current_import_id=%, c_action=%, c_changelog_table=%', - i_mgm_id, i_rule_id, i_old_obj_id, i_new_obj_id, i_current_import_id, c_action, c_changelog_table; - IF i_new_obj_id <> i_member THEN - RAISE DEBUG 'import_rule_resolved_nwobj 4b recurse new obj - i_mgm_id=%, i_rule_id=%, i_old_obj_id=%, i_new_obj_id=%, i_current_import_id=%, c_action=%, c_changelog_table=%', - i_mgm_id, i_rule_id, i_old_obj_id, i_new_obj_id, i_current_import_id, c_action, c_changelog_table; - PERFORM import_rule_resolved_nwobj(i_mgm_id, i_rule_id, NULL, i_member, i_current_import_id, c_action, c_changelog_table); - END IF; - END LOOP; - - FOR i_member IN - SELECT objgrp_member_id FROM objgrp - WHERE objgrp_id=i_old_obj_id AND - import_last_seen IN (SELECT MAX(control_id) FROM import_control WHERE mgm_id=i_mgm_id AND control_id i_member THEN - RAISE DEBUG 'import_rule_resolved_nwobj 5b recurse old obj - i_mgm_id=%, i_rule_id=%, i_old_obj_id=%, i_new_obj_id=%, i_current_import_id=%, c_action=%, c_changelog_table=%', - i_mgm_id, i_rule_id, i_old_obj_id, i_new_obj_id, i_current_import_id, c_action, c_changelog_table; - PERFORM import_rule_resolved_nwobj(i_mgm_id, i_rule_id, i_member, NULL, i_current_import_id, c_action, c_changelog_table); - END IF; - END LOOP; - END IF; - END IF; - EXCEPTION - WHEN others THEN - RAISE DEBUG 'import_rule_resolved_nwobj uncommittable state. ERROR %: %', SQLSTATE, SQLERRM; - raise EXCEPTION 'import_rule_resolved_nwobj uncommittable state. ERROR %: %', SQLSTATE, SQLERRM; - END; - RETURN; -END; -$$ LANGUAGE plpgsql; - - -CREATE OR REPLACE FUNCTION import_rule_resolved_svc (INT,BIGINT,BIGINT,BIGINT,BIGINT,CHAR,CHAR) RETURNS VOID AS $$ -DECLARE - i_mgm_id ALIAS FOR $1; - i_rule_id ALIAS FOR $2; - i_old_obj_id ALIAS FOR $3; - i_new_obj_id ALIAS FOR $4; - i_current_import_id ALIAS FOR $5; - c_action ALIAS FOR $6; - c_changelog_table ALIAS FOR $7; - r_null RECORD; - i_member BIGINT; - i_matching_rule_id BIGINT; - i_matching_obj_id BIGINT; - r_search RECORD; -BEGIN - BEGIN -- catch - RAISE DEBUG 'import_rule_resolved_svc 0 enter - i_mgm_id=%, i_rule_id=%, i_old_obj_id=%, i_new_obj_id=%, i_current_import_id=%, c_action=%, c_changelog_table=%', - i_mgm_id, i_rule_id, i_old_obj_id, i_new_obj_id, i_current_import_id, c_action, c_changelog_table; - - -- rule has been deleted resp. changed, marking all existing rule/obj refs as removed - IF i_old_obj_id IS NULL AND i_new_obj_id IS NULL AND NOT i_rule_id IS NULL AND NOT c_action='I' THEN - -- handle ocurrences in all rules, if rule_id is NULL - RAISE DEBUG 'import_rule_resolved_svc 0a all obj of a rule - i_mgm_id=%, i_rule_id=%, i_old_obj_id=%, i_new_obj_id=%, i_current_import_id=%, c_action=%, c_changelog_table=%', - i_mgm_id, i_rule_id, i_old_obj_id, i_new_obj_id, i_current_import_id, c_action, c_changelog_table; - FOR i_matching_obj_id IN - SELECT svc_id FROM rule_svc_resolved WHERE mgm_id=i_mgm_id AND rule_id=i_rule_id AND removed IS NULL - LOOP - RAISE DEBUG 'import_rule_resolved_svc 0b obj loop - i_mgm_id=%, i_rule_id=%, i_old_obj_id=%, i_new_obj_id=%, i_current_import_id=%, c_action=%, c_changelog_table=%', - i_mgm_id, i_rule_id, i_matching_obj_id, NULL, i_current_import_id, c_action, c_changelog_table; - PERFORM import_rule_resolved_svc(i_mgm_id, i_rule_id, i_matching_obj_id, NULL, i_current_import_id, 'D', c_changelog_table); - END LOOP; - - -- handle ocurrences in all rules, if rule_id is NULL - ELSIF i_rule_id IS NULL THEN - RAISE DEBUG 'import_rule_resolved_svc 0c no rule - i_mgm_id=%, i_rule_id=%, i_old_obj_id=%, i_new_obj_id=%, i_current_import_id=%, c_action=%, c_changelog_table=%', - i_mgm_id, i_rule_id, i_old_obj_id, i_new_obj_id, i_current_import_id, c_action, c_changelog_table; - IF NOT c_action='I' THEN -- no valid case, cannot insert everywhere, using C to replace old with new obj ref - FOR i_matching_rule_id IN - SELECT rule_id FROM rule_svc_resolved WHERE mgm_id=i_mgm_id AND svc_id=i_old_obj_id AND removed IS NULL - LOOP - RAISE DEBUG 'import_rule_resolved_svc 0d rule loop - i_mgm_id=%, i_rule_id=%, i_old_obj_id=%, i_new_obj_id=%, i_current_import_id=%, c_action=%, c_changelog_table=%', - i_mgm_id, i_rule_id, i_old_obj_id, i_new_obj_id, i_current_import_id, c_action, c_changelog_table; - PERFORM import_rule_resolved_svc(i_mgm_id, i_matching_rule_id, i_old_obj_id, i_new_obj_id, i_current_import_id, c_action, c_changelog_table); - END LOOP; - END IF; - - -- standard case: both one obj_id and rule_id are given: - ELSE - RAISE DEBUG 'import_rule_resolved_svc 1 ELSE enter - i_mgm_id=%, i_rule_id=%, i_old_obj_id=%, i_new_obj_id=%, i_current_import_id=%, c_action=%, c_changelog_table=%', - i_mgm_id, i_rule_id, i_old_obj_id, i_new_obj_id, i_current_import_id, c_action, c_changelog_table; - IF c_action = 'I' THEN - SELECT INTO r_null * FROM rule_svc_resolved WHERE mgm_id=i_mgm_id AND rule_id=i_rule_id AND svc_id=i_new_obj_id AND created=i_current_import_id; - RAISE DEBUG 'import_rule_resolved_svc 1 insert - i_mgm_id=%, i_rule_id=%, i_old_obj_id=%, i_new_obj_id=%, i_current_import_id=%, c_action=%, c_changelog_table=%', - i_mgm_id, i_rule_id, i_old_obj_id, i_new_obj_id, i_current_import_id, c_action, c_changelog_table; - IF NOT FOUND THEN - RAISE DEBUG 'import_rule_resolved_svc 1a insert - i_mgm_id=%, i_rule_id=%, i_old_obj_id=%, i_new_obj_id=%, i_current_import_id=%, c_action=%, c_changelog_table=%', - i_mgm_id, i_rule_id, i_old_obj_id, i_new_obj_id, i_current_import_id, c_action, c_changelog_table; - INSERT INTO rule_svc_resolved (mgm_id, rule_id, svc_id, created) VALUES (i_mgm_id, i_rule_id, i_new_obj_id, i_current_import_id); - END IF; - ELSIF c_action = 'D' THEN - RAISE DEBUG 'import_rule_resolved_svc 2 delete - i_mgm_id=%, i_rule_id=%, i_old_obj_id=%, i_new_obj_id=%, i_current_import_id=%, c_action=%, c_changelog_table=%', - i_mgm_id, i_rule_id, i_old_obj_id, i_new_obj_id, i_current_import_id, c_action, c_changelog_table; - UPDATE rule_svc_resolved SET removed=i_current_import_id WHERE rule_id=i_rule_id AND svc_id=i_old_obj_id AND removed IS NULL; - ELSIF c_action = 'C' THEN - RAISE DEBUG 'import_rule_resolved_svc 3 change - i_mgm_id=%, i_rule_id=%, i_old_obj_id=%, i_new_obj_id=%, i_current_import_id=%, c_action=%, c_changelog_table=%', - i_mgm_id, i_rule_id, i_old_obj_id, i_new_obj_id, i_current_import_id, c_action, c_changelog_table; - IF NOT i_old_obj_id IS NULL THEN - UPDATE rule_svc_resolved SET removed=i_current_import_id WHERE rule_id=i_rule_id AND svc_id=i_old_obj_id AND removed IS NULL; - END IF; - SELECT INTO r_null * FROM rule_svc_resolved WHERE mgm_id=i_mgm_id AND rule_id=i_rule_id AND svc_id=i_new_obj_id; -- AND created=i_current_import_id; - IF NOT FOUND THEN - RAISE DEBUG 'import_rule_resolved_svc 3a change - insert - i_mgm_id=%, i_rule_id=%, i_old_obj_id=%, i_new_obj_id=%, i_current_import_id=%, c_action=%, c_changelog_table=%', - i_mgm_id, i_rule_id, i_old_obj_id, i_new_obj_id, i_current_import_id, c_action, c_changelog_table; - IF NOT i_new_obj_id IS NULL THEN - INSERT INTO rule_svc_resolved (mgm_id, rule_id, svc_id, created) VALUES (i_mgm_id, i_rule_id, i_new_obj_id, i_current_import_id); - END IF; - END IF; - END IF; - - - -- if the (new) object is a group, deal with all group members recursively - -- cannot use _flat group as this would leave out any intermediate groups - IF is_svc_group(i_new_obj_id) THEN -- treat all group members as well - RAISE DEBUG 'import_rule_resolved_svc 4 group - i_mgm_id=%, i_rule_id=%, i_old_obj_id=%, i_new_obj_id=%, i_current_import_id=%, c_action=%, c_changelog_table=%', - i_mgm_id, i_rule_id, i_old_obj_id, i_new_obj_id, i_current_import_id, c_action, c_changelog_table; - - -- make sure all new active members are in resolved table: - FOR i_member IN SELECT svcgrp_member_id FROM svcgrp WHERE active AND svcgrp_id=i_new_obj_id AND - NOT svcgrp_member_id in (SELECT svcgrp_member_id FROM svcgrp WHERE svcgrp_id=i_old_obj_id) - -- do not add objects that were already in the old group - LOOP - RAISE DEBUG 'import_rule_resolved_svc 4a group loop - i_mgm_id=%, i_rule_id=%, i_old_obj_id=%, i_new_obj_id=%, i_current_import_id=%, c_action=%, c_changelog_table=%', - i_mgm_id, i_rule_id, i_old_obj_id, i_new_obj_id, i_current_import_id, c_action, c_changelog_table; - IF i_new_obj_id <> i_member THEN - RAISE DEBUG 'import_rule_resolved_svc 4b recurse new obj - i_mgm_id=%, i_rule_id=%, i_old_obj_id=%, i_new_obj_id=%, i_current_import_id=%, c_action=%, c_changelog_table=%', - i_mgm_id, i_rule_id, i_old_obj_id, i_new_obj_id, i_current_import_id, c_action, c_changelog_table; - PERFORM import_rule_resolved_svc(i_mgm_id, i_rule_id, NULL, i_member, i_current_import_id, c_action, c_changelog_table); - END IF; - END LOOP; - - FOR i_member IN - SELECT svcgrp_member_id FROM svcgrp - WHERE svcgrp_id=i_old_obj_id AND - import_last_seen IN (SELECT MAX(control_id) FROM import_control WHERE mgm_id=i_mgm_id AND control_id i_member THEN - RAISE DEBUG 'import_rule_resolved_svc 5b recurse old obj - i_mgm_id=%, i_rule_id=%, i_old_obj_id=%, i_new_obj_id=%, i_current_import_id=%, c_action=%, c_changelog_table=%', - i_mgm_id, i_rule_id, i_old_obj_id, i_new_obj_id, i_current_import_id, c_action, c_changelog_table; - PERFORM import_rule_resolved_svc(i_mgm_id, i_rule_id, i_member, NULL, i_current_import_id, c_action, c_changelog_table); - END IF; - END LOOP; - END IF; - END IF; - EXCEPTION - WHEN others THEN - raise EXCEPTION 'import_rule_resolved_svc uncommittable state. ERROR %: %', SQLSTATE, SQLERRM; - END; - RETURN; -END; -$$ LANGUAGE plpgsql; - - -CREATE OR REPLACE FUNCTION import_rule_resolved_usr (INT,BIGINT,BIGINT,BIGINT,BIGINT,CHAR,CHAR) RETURNS VOID AS $$ -DECLARE - i_mgm_id ALIAS FOR $1; - i_rule_id ALIAS FOR $2; - i_old_obj_id ALIAS FOR $3; - i_new_obj_id ALIAS FOR $4; - i_current_import_id ALIAS FOR $5; - c_action ALIAS FOR $6; - c_changelog_table ALIAS FOR $7; - r_null RECORD; - i_member BIGINT; - i_matching_rule_id BIGINT; - i_matching_obj_id BIGINT; - r_search RECORD; -BEGIN - BEGIN -- catch - RAISE DEBUG 'import_rule_resolved_usr 0 enter - i_mgm_id=%, i_rule_id=%, i_old_obj_id=%, i_new_obj_id=%, i_current_import_id=%, c_action=%, c_changelog_table=%', - i_mgm_id, i_rule_id, i_old_obj_id, i_new_obj_id, i_current_import_id, c_action, c_changelog_table; - - -- rule has been deleted resp. changed, marking all existing rule/obj refs as removed - IF i_old_obj_id IS NULL AND i_new_obj_id IS NULL AND NOT i_rule_id IS NULL AND NOT c_action='I' THEN - -- handle ocurrences in all rules, if rule_id is NULL - RAISE DEBUG 'import_rule_resolved_usr 0a all obj of a rule - i_mgm_id=%, i_rule_id=%, i_old_obj_id=%, i_new_obj_id=%, i_current_import_id=%, c_action=%, c_changelog_table=%', - i_mgm_id, i_rule_id, i_old_obj_id, i_new_obj_id, i_current_import_id, c_action, c_changelog_table; - FOR i_matching_obj_id IN - SELECT user_id FROM rule_user_resolved WHERE mgm_id=i_mgm_id AND rule_id=i_rule_id AND removed IS NULL - LOOP - RAISE DEBUG 'import_rule_resolved_usr 0b obj loop - i_mgm_id=%, i_rule_id=%, i_old_obj_id=%, i_new_obj_id=%, i_current_import_id=%, c_action=%, c_changelog_table=%', - i_mgm_id, i_rule_id, i_matching_obj_id, NULL, i_current_import_id, c_action, c_changelog_table; - PERFORM import_rule_resolved_usr(i_mgm_id, i_rule_id, i_matching_obj_id, NULL, i_current_import_id, 'D', c_changelog_table); - END LOOP; - - -- handle ocurrences in all rules, if rule_id is NULL - ELSIF i_rule_id IS NULL THEN - RAISE DEBUG 'import_rule_resolved_usr 0c no rule - i_mgm_id=%, i_rule_id=%, i_old_obj_id=%, i_new_obj_id=%, i_current_import_id=%, c_action=%, c_changelog_table=%', - i_mgm_id, i_rule_id, i_old_obj_id, i_new_obj_id, i_current_import_id, c_action, c_changelog_table; - IF NOT c_action='I' THEN -- no valid case, cannot insert everywhere, using C to replace old with new obj ref - FOR i_matching_rule_id IN - SELECT rule_id FROM rule_user_resolved WHERE mgm_id=i_mgm_id AND user_id=i_old_obj_id AND removed IS NULL - LOOP - RAISE DEBUG 'import_rule_resolved_usr 0d rule loop - i_mgm_id=%, i_rule_id=%, i_old_obj_id=%, i_new_obj_id=%, i_current_import_id=%, c_action=%, c_changelog_table=%', - i_mgm_id, i_rule_id, i_old_obj_id, i_new_obj_id, i_current_import_id, c_action, c_changelog_table; - PERFORM import_rule_resolved_usr(i_mgm_id, i_matching_rule_id, i_old_obj_id, i_new_obj_id, i_current_import_id, c_action, c_changelog_table); - END LOOP; - END IF; - - -- standard case: both one obj_id and rule_id are given: - ELSE - RAISE DEBUG 'import_rule_resolved_usr 1 ELSE enter - i_mgm_id=%, i_rule_id=%, i_old_obj_id=%, i_new_obj_id=%, i_current_import_id=%, c_action=%, c_changelog_table=%', - i_mgm_id, i_rule_id, i_old_obj_id, i_new_obj_id, i_current_import_id, c_action, c_changelog_table; - IF c_action = 'I' THEN - SELECT INTO r_null * FROM rule_user_resolved WHERE mgm_id=i_mgm_id AND rule_id=i_rule_id AND user_id=i_new_obj_id AND created=i_current_import_id; - RAISE DEBUG 'import_rule_resolved_usr 1 insert - i_mgm_id=%, i_rule_id=%, i_old_obj_id=%, i_new_obj_id=%, i_current_import_id=%, c_action=%, c_changelog_table=%', - i_mgm_id, i_rule_id, i_old_obj_id, i_new_obj_id, i_current_import_id, c_action, c_changelog_table; - IF NOT FOUND THEN - RAISE DEBUG 'import_rule_resolved_usr 1a insert - i_mgm_id=%, i_rule_id=%, i_old_obj_id=%, i_new_obj_id=%, i_current_import_id=%, c_action=%, c_changelog_table=%', - i_mgm_id, i_rule_id, i_old_obj_id, i_new_obj_id, i_current_import_id, c_action, c_changelog_table; - INSERT INTO rule_user_resolved (mgm_id, rule_id, user_id, created) VALUES (i_mgm_id, i_rule_id, i_new_obj_id, i_current_import_id); - END IF; - ELSIF c_action = 'D' THEN - RAISE DEBUG 'import_rule_resolved_usr 2 delete - i_mgm_id=%, i_rule_id=%, i_old_obj_id=%, i_new_obj_id=%, i_current_import_id=%, c_action=%, c_changelog_table=%', - i_mgm_id, i_rule_id, i_old_obj_id, i_new_obj_id, i_current_import_id, c_action, c_changelog_table; - UPDATE rule_user_resolved SET removed=i_current_import_id WHERE rule_id=i_rule_id AND user_id=i_old_obj_id AND removed IS NULL; - ELSIF c_action = 'C' THEN - RAISE DEBUG 'import_rule_resolved_usr 3 change - i_mgm_id=%, i_rule_id=%, i_old_obj_id=%, i_new_obj_id=%, i_current_import_id=%, c_action=%, c_changelog_table=%', - i_mgm_id, i_rule_id, i_old_obj_id, i_new_obj_id, i_current_import_id, c_action, c_changelog_table; - IF NOT i_old_obj_id IS NULL THEN - UPDATE rule_user_resolved SET removed=i_current_import_id WHERE rule_id=i_rule_id AND user_id=i_old_obj_id AND removed IS NULL; - END IF; - SELECT INTO r_null * FROM rule_user_resolved WHERE mgm_id=i_mgm_id AND rule_id=i_rule_id AND user_id=i_new_obj_id; -- AND created=i_current_import_id; - IF NOT FOUND THEN - RAISE DEBUG 'import_rule_resolved_usr 3a change - insert - i_mgm_id=%, i_rule_id=%, i_old_obj_id=%, i_new_obj_id=%, i_current_import_id=%, c_action=%, c_changelog_table=%', - i_mgm_id, i_rule_id, i_old_obj_id, i_new_obj_id, i_current_import_id, c_action, c_changelog_table; - IF NOT i_new_obj_id IS NULL THEN - INSERT INTO rule_user_resolved (mgm_id, rule_id, user_id, created) VALUES (i_mgm_id, i_rule_id, i_new_obj_id, i_current_import_id); - END IF; - END IF; - END IF; - - -- if the (new) object is a group, deal with all group members recursively - -- cannot use _flat group as this would leave out any intermediate groups - IF is_user_group(i_new_obj_id) THEN -- treat all group members as well - RAISE DEBUG 'import_rule_resolved_usr 4 group - i_mgm_id=%, i_rule_id=%, i_old_obj_id=%, i_new_obj_id=%, i_current_import_id=%, c_action=%, c_changelog_table=%', - i_mgm_id, i_rule_id, i_old_obj_id, i_new_obj_id, i_current_import_id, c_action, c_changelog_table; - - -- make sure all new active members are in resolved table: - FOR i_member IN SELECT usergrp_member_id FROM usergrp WHERE active AND usergrp_id=i_new_obj_id AND - NOT usergrp_member_id in (SELECT usergrp_member_id FROM usergrp WHERE usergrp_id=i_old_obj_id) - -- do not add objects that were already in the old group - LOOP - RAISE DEBUG 'import_rule_resolved_usr 4a group loop - i_mgm_id=%, i_rule_id=%, i_old_obj_id=%, i_new_obj_id=%, i_current_import_id=%, c_action=%, c_changelog_table=%', - i_mgm_id, i_rule_id, i_old_obj_id, i_new_obj_id, i_current_import_id, c_action, c_changelog_table; - IF i_new_obj_id <> i_member THEN - RAISE DEBUG 'import_rule_resolved_usr 4b recurse new obj - i_mgm_id=%, i_rule_id=%, i_old_obj_id=%, i_new_obj_id=%, i_current_import_id=%, c_action=%, c_changelog_table=%', - i_mgm_id, i_rule_id, i_old_obj_id, i_new_obj_id, i_current_import_id, c_action, c_changelog_table; - PERFORM import_rule_resolved_usrj(i_mgm_id, i_rule_id, NULL, i_member, i_current_import_id, c_action, c_changelog_table); - END IF; - END LOOP; - - FOR i_member IN - SELECT usergrp_member_id FROM usergrp - WHERE usergrp_id=i_old_obj_id AND - import_last_seen IN (SELECT MAX(control_id) FROM import_control WHERE mgm_id=i_mgm_id AND control_id i_member THEN - RAISE DEBUG 'import_rule_resolved_usr 5b recurse old obj - i_mgm_id=%, i_rule_id=%, i_old_obj_id=%, i_new_obj_id=%, i_current_import_id=%, c_action=%, c_changelog_table=%', - i_mgm_id, i_rule_id, i_old_obj_id, i_new_obj_id, i_current_import_id, c_action, c_changelog_table; - PERFORM import_rule_resolved_usr(i_mgm_id, i_rule_id, i_member, NULL, i_current_import_id, c_action, c_changelog_table); - END IF; - END LOOP; - END IF; - - END IF; - EXCEPTION - WHEN others THEN - raise EXCEPTION 'import_rule_resolved_usr uncommittable state. ERROR %: %', SQLSTATE, SQLERRM; - END; - RETURN; -END; -$$ LANGUAGE plpgsql; diff --git a/roles/database/files/sql/idempotent/fworch-svc-import.sql b/roles/database/files/sql/idempotent/fworch-svc-import.sql deleted file mode 100644 index ef453374ce..0000000000 --- a/roles/database/files/sql/idempotent/fworch-svc-import.sql +++ /dev/null @@ -1,348 +0,0 @@ --- $Id: iso-svc-import.sql,v 1.1.2.5 2011-09-16 15:01:11 tim Exp $ --- $Source: /home/cvs/iso/package/install/database/Attic/iso-svc-import.sql,v $ - ----------------------------------------------------- --- FUNCTION: import_svc_main --- Zweck: fuegt alle Services des aktuellen Imports in die service-Tabelle --- Zweck: verwendet die Funktion insert_single_svc zum Einfuegen der Einzelelemente --- Zweck: bzw. import_svc_mark_deleted und import_svc_refhandler_main zum Aufloesen der Referenzen --- Parameter: control-id --- RETURNS: VOID --- --- Function: public.import_svc_main(BIGINT, boolean) - --- DROP FUNCTION public.import_svc_main(BIGINT, boolean); - -CREATE OR REPLACE FUNCTION public.import_svc_main( - BIGINT, - boolean) - RETURNS void AS -$BODY$ -DECLARE - i_current_import_id ALIAS FOR $1; -- ID des aktiven Imports - b_is_initial_import ALIAS FOR $2; -- flag, ob initialer Import - r_ctrl RECORD; -- zum Holen der start_time fuer Loeschen von Elementen - i_mgm_id INTEGER; -- zum Holen der mgm_ID fuer Loeschen von Elementen - r_svc RECORD; -- Datensatz mit einzelner svc_id aus import_service-Tabelle des zu importierenden Services - v_group_del VARCHAR; -- Trennzeichen fuer Gruppenmitglieder - i_dev_typ_id INTEGER; -- Datensatz fuer Device-Typ - r_devtyp RECORD; -- Datensatz fuer Device-Typ - is_netscreen BOOLEAN; -- netscreen (wg. timeout in minuten statt sekunden) - i_timeout_factor INTEGER; - t_last_change_time TIMESTAMP; - r_last_times RECORD; -BEGIN - SELECT INTO r_ctrl mgm_id FROM import_control WHERE control_id=i_current_import_id; - i_mgm_id := r_ctrl.mgm_id; - SELECT INTO i_dev_typ_id dev_typ_id FROM management WHERE mgm_id = i_mgm_id; -- Hersteller-String holen - SELECT INTO r_devtyp dev_typ_manufacturer AS hersteller FROM stm_dev_typ WHERE dev_typ_id = i_dev_typ_id; -- Hersteller-String holen - is_netscreen := (lower(r_devtyp.hersteller) = 'netscreen'); - IF (is_netscreen) THEN i_timeout_factor := 60; - ELSE i_timeout_factor := 1; END IF; - -/* - IF NOT b_is_initial_import THEN - -- Objekte ausklammern, die vor dem vorherigen Import-Zeitpunkt geaendert wurden, Tuning-Masznahme - SELECT INTO r_last_times MAX(start_time) AS last_import_time, MAX(last_change_in_config) AS last_change_time - FROM import_control WHERE mgm_id=i_mgm_id AND NOT control_id=i_current_import_id AND successful_import; - IF (r_last_times.last_change_time IS NULL) THEN t_last_change_time := r_last_times.last_import_time; - ELSE - IF (r_last_times.last_import_time65535) THEN -- Port ungueltig? - err_txt := 'Service: ' || to_import.svc_name || ', port: ' || to_import.svc_source_port_end; - PERFORM error_handling('ERR_PORT_INVALID', err_txt); - IF (port<0) THEN port := 0; - ELSE port := 65535; - END IF; - END IF; - END IF; - IF (to_import.svc_port_end IS NULL) THEN -- wenn kein Port enthalten - port_end := port; -- Port nur ein Port gemeint - ELSE - port_end := CAST(to_import.svc_port_end AS INTEGER); -- TEXT in INTEGER umwandeln, TODO: Fehlerbehandlung - IF (port_end<0 OR port_end>65535) THEN -- Port ungueltig? - err_txt := 'Service: ' || to_import.svc_name || ', port-end: ' || to_import.svc_source_port_end; - PERFORM error_handling('ERR_PORT_INVALID', err_txt); - IF (port_end<0) THEN port_end := 0; - ELSE port_end := 65535; - END IF; - END IF; - END IF; - IF (to_import.svc_source_port IS NULL) THEN -- wenn kein Port enthalten - srcport := NULL; -- Port auf 0 setzen - ELSE - srcport := CAST(to_import.svc_source_port AS INTEGER); -- TEXT in INTEGER umwandeln, TODO: Fehlerbehandlung - IF (srcport<0 OR srcport>65535) THEN -- Port ungueltig? - err_txt := 'Service: ' || to_import.svc_name || ', src-port: ' || to_import.svc_source_port; - PERFORM error_handling('ERR_PORT_INVALID', err_txt); - IF (srcport<0) THEN srcport := 0; - ELSE srcport := 65535; - END IF; - END IF; - END IF; - IF (to_import.svc_source_port_end IS NULL) THEN -- wenn kein Port enthalten - srcport_end := srcport; -- nur ein Port gemeint - ELSE - srcport_end := CAST(to_import.svc_source_port_end AS INTEGER); -- TEXT in INTEGER umwandeln, TODO: Fehlerbehandlung - IF (srcport_end<0 OR srcport_end>65535) THEN -- Port ungueltig? - err_txt := 'Service: ' || to_import.svc_name || ', src-port-end: ' || to_import.svc_source_port_end; - PERFORM error_handling('ERR_PORT_INVALID', err_txt); - IF (srcport_end<0) THEN srcport_end := 0; - ELSE srcport_end := 65535; - END IF; - END IF; - END IF; - IF (to_import.svc_timeout IS NULL) THEN -- wenn kein Timeout enthalten - timeout := NULL; -- Timeout auf 0 setzen - std_timeout := TRUE; -- hier greift der Standard-Timeout - ELSE - timeout := CAST(to_import.svc_timeout AS INTEGER); -- TEXT in INTEGER umwandeln, TODO: Fehlerbehandlung - timeout := timeout * i_timeout_factor; - END IF; - SELECT INTO i_typ svc_typ_id FROM stm_svc_typ WHERE svc_typ_name = to_import.svc_typ; -- svc_typ_id holen (simple,group,rpc,...) - IF NOT FOUND THEN -- TODO: das muss noch automatisiert werden: Neuanlegen eines svc_typ - PERFORM error_handling('ERR_SVCTYP_MISS', to_import.svc_typ); - END IF; - -- color_id holen (normalisiert ohne SPACES und in Kleinbuchstaben) - SELECT INTO i_farbe color_id FROM stm_color WHERE color_name = LOWER(remove_spaces(to_import.svc_color)); - IF NOT FOUND THEN -- TODO: Fehlerbehandlung bzw. automat. Neuanlegen einer Farbe? - i_farbe := NULL; --- PERFORM error_handling('ERR_COLOR_MISS', to_import.svc_color); - END IF; - --- neu (Integration der alten Triggerfunktionen) - IF (to_import.svc_uid IS NULL OR char_length(cast (to_import.svc_uid as varchar)) = 0) THEN -- nur der Weg ueber den Namen als ID geht - SELECT INTO existing_svc * FROM service WHERE svc_name=to_import.svc_name AND mgm_id=i_mgm_id AND active; - ELSE -- svc_uid ist nicht leer: nehme dieses Feld als ID-Anteil anstatt Namen: erschlaegt Umbenennungen - SELECT INTO existing_svc * FROM service WHERE svc_uid=to_import.svc_uid AND mgm_id=i_mgm_id AND active; - END IF; - IF FOUND THEN -- service existiert bereits - IF (NOT ( - are_equal(existing_svc.svc_typ_id, i_typ) AND - are_equal(existing_svc.svc_member_names, to_import.svc_member_names) AND - are_equal(existing_svc.svc_member_refs, to_import.svc_member_refs) AND - are_equal(existing_svc.ip_proto_id, protoID) AND - are_equal(existing_svc.svc_port, port) AND - are_equal(existing_svc.svc_port_end, port_end) AND - are_equal(existing_svc.svc_rpcnr, to_import.rpc_nr) AND - are_equal(existing_svc.svc_source_port, srcport) AND - are_equal(existing_svc.svc_source_port_end, srcport_end) AND - are_equal(existing_svc.svc_timeout, timeout) AND - are_equal(existing_svc.svc_uid, to_import.svc_uid) AND - are_equal(existing_svc.svc_name, to_import.svc_name) AND - are_equal(existing_svc.svc_prod_specific, to_import.svc_prod_specific) - )) - THEN - b_change := TRUE; - b_change_security_relevant := TRUE; - END IF; - IF (NOT( -- ab hier die nicht sicherheitsrelevanten Aenderungen - are_equal(existing_svc.svc_comment, to_import.svc_comment) AND - are_equal(existing_svc.svc_color_id, i_farbe) - )) - THEN -- object unveraendert - b_change := TRUE; - END IF; - IF (b_change) THEN - v_change_id := 'INFO_SVC_CHANGED'; - ELSE - UPDATE service SET svc_last_seen = i_control_id WHERE svc_id = existing_svc.svc_id; - END IF; - ELSE - b_insert := TRUE; - v_change_id := 'INFO_SVC_INSERTED'; - END IF; - IF (b_change OR b_insert) THEN - PERFORM error_handling(v_change_id, to_import.svc_name); - i_admin_id := get_admin_id_from_name(to_import.last_change_admin); - RAISE DEBUG 'inserting service with uid %', to_import.svc_uid; - INSERT INTO service ( - mgm_id,svc_name,svc_timeout,ip_proto_id,svc_port,svc_port_end, - svc_source_port,svc_source_port_end,svc_typ_id,svc_comment,svc_member_names,svc_member_refs, - svc_color_id,svc_rpcnr,svc_prod_specific,svc_uid,last_change_admin, - svc_last_seen,svc_create - ) - VALUES ( - i_mgm_id,to_import.svc_name,timeout,protoID,port,port_end,srcport,srcport_end,i_typ, - to_import.svc_comment,to_import.svc_member_names,to_import.svc_member_refs,i_farbe,to_import.rpc_nr,to_import.svc_prod_specific, - to_import.svc_uid,i_admin_id,i_control_id,i_control_id - ); - - -- changelog-Eintrag - SELECT INTO i_new_svc_id MAX(svc_id) FROM service WHERE mgm_id=i_mgm_id; -- ein bisschen fragwuerdig - IF (b_insert) THEN -- der service wurde neu angelegt - IF b_is_initial_import THEN - b_is_documented := TRUE; t_outtext := 'INITIAL_IMPORT'; i_change_type := 2; - ELSE - b_is_documented := FALSE; t_outtext := NULL; i_change_type := 3; - END IF; - -- fest verdrahtete Werte: weniger gut - INSERT INTO changelog_service - (control_id,new_svc_id,old_svc_id,change_action,import_admin,documented,changelog_svc_comment,mgm_id,change_type_id) - VALUES (i_control_id,i_new_svc_id,NULL,'I',i_admin_id,b_is_documented,t_outtext,i_mgm_id,i_change_type); - ELSE -- change - IF (b_change_security_relevant) THEN - v_comment := NULL; - b_is_documented := FALSE; - ELSE - v_comment := 'NON_SECURITY_RELEVANT_CHANGE'; - b_is_documented := TRUE; - END IF; - INSERT INTO changelog_service - (control_id,new_svc_id,old_svc_id,change_action,import_admin,documented,mgm_id, - security_relevant,changelog_svc_comment) - VALUES (i_control_id,i_new_svc_id,existing_svc.svc_id,'C',i_admin_id,b_is_documented, - i_mgm_id,b_change_security_relevant,v_comment); - -- erst jetzt kann active beim alten Dienst auf FALSE gesetzt werden - UPDATE service SET active = FALSE WHERE svc_id = existing_svc.svc_id; -- alten Dienst auf not active setzen - END IF; - END IF; - RETURN; -END; -$BODY$ - LANGUAGE plpgsql VOLATILE - COST 100; -ALTER FUNCTION public.import_svc_single(BIGINT, integer, BIGINT, integer, boolean) OWNER TO fworch; - diff --git a/roles/database/files/sql/idempotent/fworch-svc-refs.sql b/roles/database/files/sql/idempotent/fworch-svc-refs.sql deleted file mode 100644 index 4f3401ccaa..0000000000 --- a/roles/database/files/sql/idempotent/fworch-svc-refs.sql +++ /dev/null @@ -1,430 +0,0 @@ - ----------------------------------------------------- --- FUNCTION: import_svc_refhandler_main --- Zweck: ueberall dort, wo ein service veraendert (changed,inserted,deleted) wurde, --- Zweck: muessen die Referenzen entweder: --- Zweck: - vom alten auf das neue Objekt umgebogen werden --- Zweck: - fuer das Objekt geloescht werden --- Zweck: - fuer das Objekt hinzugefuegt werden --- Parameter: current_import_id --- RETURNS: VOID --- -CREATE OR REPLACE FUNCTION import_svc_refhandler_main (BIGINT) RETURNS VOID AS $$ -DECLARE - i_current_import_id ALIAS FOR $1; -- ID des laufenden Imports - r_svc RECORD; -- temp service - r_ctrl RECORD; -- zum Holen des group-delimiters - v_debug VARCHAR; --debug-output - i_previous_import_id BIGINT; - i_mgm_id INTEGER; -BEGIN - BEGIN - RAISE DEBUG 'import_svc_refhandler_main - 1 start'; - SELECT INTO i_mgm_id mgm_id FROM import_control WHERE control_id=i_current_import_id; - RAISE DEBUG 'import_svc_refhandler_main - 2'; - i_previous_import_id := get_previous_import_id_for_mgmt (i_mgm_id, i_current_import_id); - RAISE DEBUG 'import_svc_refhandler_main - 3'; - SELECT INTO r_ctrl delimiter_group FROM import_control WHERE control_id=i_current_import_id; - RAISE DEBUG 'import_svc_refhandler_main - 4'; - -- neue Member-Beziehungen von i_new_id eintragen - FOR r_svc IN -- jedes geloeschte Objekt wird in changelog_service eingetragen (standard groups) - SELECT old_svc_id,new_svc_id,change_action FROM changelog_service WHERE control_id=i_current_import_id AND NOT change_action='D' - LOOP - RAISE DEBUG 'import_svc_refhandler_main - first loop'; - IF r_svc.change_action = 'I' THEN - PERFORM import_svc_refhandler_insert(r_svc.new_svc_id,r_ctrl.delimiter_group,i_current_import_id); - ELSIF r_svc.change_action = 'C' THEN - PERFORM import_svc_refhandler_change(r_svc.old_svc_id,r_svc.new_svc_id,i_current_import_id); - END IF; - END LOOP; - RAISE DEBUG 'import_svc_refhandler_main - 5'; - FOR r_svc IN -- jedes geloeschte Objekt wird in changelog_service eingetragen (flattened groups) - SELECT old_svc_id,new_svc_id,change_action FROM changelog_service WHERE control_id=i_current_import_id AND NOT change_action='D' - LOOP - RAISE DEBUG 'import_svc_refhandler_main - second loop (flat grps)'; - IF r_svc.change_action = 'I' THEN - PERFORM import_svc_refhandler_insert_flat(r_svc.new_svc_id,r_ctrl.delimiter_group,i_current_import_id); - ELSIF r_svc.change_action = 'C' THEN - PERFORM import_svc_refhandler_change_flat(r_svc.old_svc_id,r_svc.new_svc_id,i_current_import_id); - END IF; - END LOOP; - RAISE DEBUG 'import_svc_refhandler_main - 6'; - ---------------------------------------------------------------------------------------------- - -- die alten (nicht mehr gueltigen) Objekte auf non-active setzen - UPDATE svcgrp SET active=FALSE WHERE svcgrp_id IN - (SELECT old_svc_id FROM changelog_service WHERE control_id=i_current_import_id GROUP BY old_svc_id); - UPDATE svcgrp_flat SET active=FALSE WHERE svcgrp_flat_id IN - (SELECT old_svc_id FROM changelog_service WHERE control_id=i_current_import_id GROUP BY old_svc_id); - UPDATE svcgrp SET active=FALSE WHERE svcgrp_member_id IN - (SELECT old_svc_id FROM changelog_service WHERE control_id=i_current_import_id GROUP BY old_svc_id); - UPDATE svcgrp_flat SET active=FALSE WHERE svcgrp_flat_member_id IN - (SELECT old_svc_id FROM changelog_service WHERE control_id=i_current_import_id GROUP BY old_svc_id); - UPDATE rule_service SET active=FALSE WHERE svc_id IN - (SELECT old_svc_id FROM changelog_service WHERE control_id=i_current_import_id AND NOT old_svc_id IS NULL); - UPDATE rule_service SET rs_last_seen=i_current_import_id WHERE rule_id IN - (SELECT rule_id FROM rule WHERE mgm_id=i_mgm_id AND active) AND active; - UPDATE svcgrp SET import_last_seen=i_current_import_id WHERE svcgrp_id IN - (SELECT svc_id FROM service WHERE mgm_id=i_mgm_id AND active) AND active; - UPDATE svcgrp_flat SET import_last_seen=i_current_import_id WHERE svcgrp_flat_id IN - (SELECT svc_id FROM service WHERE service.mgm_id=i_mgm_id AND active) AND active; - RAISE DEBUG 'import_svc_refhandler_main - 7 - end'; - - FOR r_svc IN -- loop for rule_svc_resolved - SELECT old_svc_id,new_svc_id,change_action FROM changelog_service WHERE control_id=i_current_import_id -- AND (change_action = 'C' OR change_action = 'D') - LOOP - PERFORM import_rule_resolved_svc (i_mgm_id, NULL, r_svc.old_svc_id, r_svc.new_svc_id, i_current_import_id, r_svc.change_action, 'S'); - END LOOP; - EXCEPTION - WHEN others THEN - raise notice 'import_svc_refhandler_main - uncommittable state. Rolling back'; - raise EXCEPTION '% %', SQLERRM, SQLSTATE; - END; - RETURN; -END; -$$ LANGUAGE plpgsql; - ----------------------------------------------------- --- FUNCTION: import_svc_refhandler_change --- Zweck: ueberall dort, wo ein service geaendert wurde, --- Zweck: muessen die Referenzen vom alten auf das neue Objekt umgebogen werden --- Parameter: old_svc_id, new_svc_id, current_import_id --- RETURNS: VOID --- an allen Stellen, an denen das alte Objekt in einem aktiven Datensatz referenziert wird, --- muss es durch das neue ersetzt werden -CREATE OR REPLACE FUNCTION import_svc_refhandler_change(BIGINT, BIGINT, BIGINT) RETURNS VOID AS $$ -DECLARE - i_old_id ALIAS FOR $1; -- id des bestehenden Datensatzes aus service - i_new_id ALIAS FOR $2; -- id des neuen Datensatzes aus service - i_current_import_id ALIAS FOR $3; -- zum Heraussuchen des group_delimiters - r_svc_info RECORD; -- Record zum Sammeln diverser service-Infos (mgm_id, svc_member) - r_import_info RECORD; -- Record zum Sammeln von import-Infos (group_del) -BEGIN - IF are_equal(i_old_id,i_new_id) THEN - RAISE EXCEPTION 'old and new svc id are identical!'; - END IF; - PERFORM import_svc_refhandler_change_svcgrp_member_refs (i_old_id, i_new_id, i_current_import_id); - PERFORM import_svc_refhandler_change_rule_service_refs (i_old_id, i_new_id, i_current_import_id); - -- jetzt noch die Aufloesung der Gruppen - IF is_svc_group(i_old_id) THEN -- wenn Gruppe, dann werden die Beziehungen der moeglicherweise - -- neuen Mitglieder komplett neu eingetragen und die alten Beziehungen auf inaktiv gesetzt --- IF NOT is_svc_group(i_new_id) THEN --- RAISE EXCEPTION 'trying to replace group with non-group service'; --- END IF; - -- Daten zum Beschicken der Funktion insert_svc_group_relations sammeln - SELECT INTO r_import_info delimiter_group FROM import_control WHERE control_id=i_current_import_id; - SELECT INTO r_svc_info mgm_id,svc_member_refs FROM service WHERE svc_id=i_new_id; - -- neue Member-Beziehungen von i_new_id eintragen - PERFORM import_svc_refhandler_svcgrp_add_group - (i_new_id,r_svc_info.svc_member_refs,r_import_info.delimiter_group,r_svc_info.mgm_id,i_current_import_id); - END IF; - RETURN; -END; -$$ language plpgsql; - ----------------------------------------------------- --- FUNCTION: import_svc_refhandler_insert --- Zweck: pruefen ob Gruppe, wenn ja Gruppenzugehoerigkeiten der Gruppe aufloesen --- Zweck: und in svcgrp eintragen --- Parameter: $1: svc_id des neuen Objekts --- Parameter: $2: Trennzeichen zwischen Gruppenmitgliedern --- verwendete --- Funktionen: add_references_for_inserted_group_svc --- RETURNS: VOID --- -CREATE OR REPLACE FUNCTION import_svc_refhandler_insert (BIGINT,varchar,BIGINT) RETURNS VOID AS $$ -DECLARE - i_new_id ALIAS FOR $1; - v_delimiter ALIAS FOR $2; - i_current_import_id ALIAS FOR $3; - r_svc_info RECORD; -BEGIN - -- Aufloesung der Gruppen - IF is_svc_group(i_new_id) THEN -- wenn Gruppe, dann werden die Beziehungen zwischen Gruppe und - -- Mitgliedern eingetragen - SELECT INTO r_svc_info mgm_id,svc_member_refs FROM service WHERE svc_id=i_new_id; - -- neue Member-Beziehungen von i_new_id eintragen - PERFORM import_svc_refhandler_svcgrp_add_group - (i_new_id,r_svc_info.svc_member_refs,v_delimiter,r_svc_info.mgm_id,i_current_import_id); - END IF; - RETURN; -END; -$$ LANGUAGE plpgsql; - ----------------------------------------------------- --- FUNCTION: import_svc_refhandler_change_flat --- Zweck: flat group relations neu setzen --- Parameter: old_svc_id, new_svc_id, current_import_id --- RETURNS: VOID --- an allen Stellen, an denen das alte Objekt in einem aktiven Datensatz referenziert wird, --- muss es durch das neue ersetzt werden -CREATE OR REPLACE FUNCTION import_svc_refhandler_change_flat(BIGINT, BIGINT, BIGINT) RETURNS VOID AS $$ -DECLARE - i_old_id ALIAS FOR $1; -- id des bestehenden Datensatzes aus service - i_new_id ALIAS FOR $2; -- id des neuen Datensatzes aus service - i_current_import_id ALIAS FOR $3; -- zum Heraussuchen des group_delimiters - r_svc_info RECORD; -- Record zum Sammeln diverser service-Infos (mgm_id, svc_member) - r_import_info RECORD; -- Record zum Sammeln von import-Infos (group_del) -BEGIN - IF are_equal(i_old_id,i_new_id) THEN - RAISE EXCEPTION 'old and new svc id are identical!'; - END IF; - PERFORM import_svc_refhandler_change_svcgrp_flat_member_refs (i_old_id, i_new_id, i_current_import_id); - IF is_svc_group(i_old_id) THEN -- wenn Gruppe, dann werden die Beziehungen der moeglicherweise - SELECT INTO r_import_info delimiter_group FROM import_control WHERE control_id=i_current_import_id; - SELECT INTO r_svc_info mgm_id,svc_member_refs FROM service WHERE svc_id=i_new_id; - PERFORM import_svc_refhandler_svcgrp_flat_add_group - (i_new_id,i_new_id,0,i_current_import_id); - END IF; - PERFORM import_svc_refhandler_svcgrp_flat_add_self(i_new_id, i_current_import_id); - RETURN; -END; -$$ language plpgsql; - ----------------------------------------------------- --- FUNCTION: import_svc_refhandler_insert_flat --- Zweck: pruefen ob Gruppe, wenn ja Gruppenzugehoerigkeiten der Gruppe aufloesen --- Zweck: und in svcgrp_flat eintragen --- Parameter: $1: svc_id des neuen Objekts --- Parameter: $2: Trennzeichen zwischen Gruppenmitgliedern --- verwendete --- Funktionen: add_references_for_inserted_group_svc --- RETURNS: VOID --- -CREATE OR REPLACE FUNCTION import_svc_refhandler_insert_flat (BIGINT,varchar,BIGINT) RETURNS VOID AS $$ -DECLARE - i_new_id ALIAS FOR $1; - v_delimiter ALIAS FOR $2; - i_current_import_id ALIAS FOR $3; - r_svc_info RECORD; -BEGIN - -- Aufloesung der Gruppen - IF is_svc_group(i_new_id) THEN -- wenn Gruppe, dann werden die Beziehungen zwischen Gruppe und - SELECT INTO r_svc_info mgm_id,svc_member_refs FROM service WHERE svc_id=i_new_id; - PERFORM import_svc_refhandler_svcgrp_flat_add_group (i_new_id,i_new_id,0,i_current_import_id); - END IF; - PERFORM import_svc_refhandler_svcgrp_flat_add_self(i_new_id, i_current_import_id); - RETURN; -END; -$$ LANGUAGE plpgsql; - ----------------------------------------------------- --- FUNCTION: import_svc_refhandler_svcgrp_add_group --- Zweck: die Gruppenzugehoerigkeiten der Gruppe $1 aufloesen --- Zweck: und in svcgrp eintragen --- Parameter: $1: svc_id der Gruppe --- Parameter: $2: String mit Gruppenmitgliedern --- Parameter: $3: Trennzeichen zwischen den Gruppenmitgliedern in $1 --- Parameter: $4: Management-ID --- verwendete --- Funktionen: f_add_single_group_member_service, insert_svc_group_relations (rekursiv) --- RETURNS: VOID --- -CREATE OR REPLACE FUNCTION import_svc_refhandler_svcgrp_add_group (BIGINT,varchar,varchar,integer,BIGINT) RETURNS VOID AS $$ -DECLARE - i_group_id ALIAS FOR $1; - v_member_string ALIAS FOR $2; - v_delimiter ALIAS FOR $3; - i_mgm_id ALIAS FOR $4; - i_current_import_id ALIAS FOR $5; - v_current_member varchar; -BEGIN - RAISE DEBUG 'import_svc_refhandler_svcgrp_add_group - 1 starting, v_member_string=%', v_member_string; - IF v_member_string IS NULL OR v_member_string='' THEN RETURN; END IF; - FOR v_current_member IN SELECT member FROM regexp_split_to_table(v_member_string, E'\\' || v_delimiter) AS member LOOP - RAISE DEBUG 'import_svc_refhandler_svcgrp_add_group - 2 adding group member ref for %', v_current_member; - PERFORM import_svc_refhandler_svcgrp_add_single_groupmember(v_current_member, i_group_id, i_mgm_id, i_current_import_id); - END LOOP; - RETURN; -END; -$$ LANGUAGE plpgsql; - ----------------------------------------------------- --- FUNCTION: import_svc_refhandler_svcgrp_flat_add_self --- Zweck: der Dienst$1 (ob Gruppe oder simple-Object) wird als sein eigenes svcgrp_flat-Mitglied eingetragen --- Dient dazu, einfacher nach geschachtelten Diensten zu suchen --- Parameter: $1: svc_id eines Dienstes --- RETURNS: VOID --- -CREATE OR REPLACE FUNCTION import_svc_refhandler_svcgrp_flat_add_self (BIGINT, BIGINT) RETURNS VOID AS $$ -DECLARE - i_svc_id ALIAS FOR $1; - i_current_import_id ALIAS FOR $2; -BEGIN - INSERT INTO svcgrp_flat (svcgrp_flat_id,svcgrp_flat_member_id,import_created,import_last_seen) - VALUES (i_svc_id,i_svc_id,i_current_import_id,i_current_import_id); - RETURN; -END; -$$ LANGUAGE plpgsql; - - ----------------------------------------------------- --- FUNCTION: import_svc_refhandler_svcgrp_add_single_groupmember --- Zweck: die Gruppenzugehoerigkeiten der Gruppe $2 aufloesen --- Zweck: und in svcgrp eintragen --- Parameter: $1: Name eines einzelnen Gruppenmitglieds --- Parameter: $2: svc_id der Gruppe --- Parameter: $3: Management-ID --- verwendete --- Funktionen: KEINE --- RETURNS: VOID --- -CREATE OR REPLACE FUNCTION import_svc_refhandler_svcgrp_add_single_groupmember(VARCHAR,BIGINT,INTEGER,BIGINT) RETURNS VOID AS $$ -DECLARE - v_member_name ALIAS FOR $1; - i_group_id ALIAS FOR $2; - i_mgm_id ALIAS FOR $3; - i_current_import_id ALIAS FOR $4; - i_svc_id BIGINT; - r_group RECORD; - v_error_str VARCHAR; - r_debug RECORD; -BEGIN - SELECT INTO i_svc_id svc_id FROM service WHERE mgm_id=i_mgm_id AND svc_uid = v_member_name AND active; - IF NOT FOUND THEN - SELECT INTO r_group svc_name,svc_uid FROM service WHERE svc_id = i_group_id; - PERFORM error_handling - ('ERR_GRP_MISS_SVC', r_group.svc_name || ' (uid of group: ' || r_group.svc_uid || '), ' || v_member_name); - ELSE -- debugging for duplicate members - SELECT INTO r_debug svcgrp_id,svcgrp_member_id FROM svcgrp - WHERE svcgrp_id=i_group_id AND svcgrp_member_id=i_svc_id AND active; - IF FOUND THEN - SELECT INTO r_debug svc_name,svc_uid FROM service WHERE svc_id = i_group_id; - v_error_str := ''; - IF NOT r_debug.svc_name IS NULL THEN - v_error_str := 'group: ' || r_debug.svc_name || ' (group-uid: ' || r_debug.svc_uid || '), ' || ', '; - ELSE - v_error_str := 'unknown group, '; - END IF; - IF NOT v_member_name IS NULL THEN - v_error_str := v_error_str || 'member_uid: ' || v_member_name; - ELSE - v_error_str := v_error_str || 'unknown member'; - END IF; - PERFORM error_handling('ERR_GRP_DBL_SVC', v_error_str); - ELSE - INSERT INTO svcgrp (svcgrp_id,svcgrp_member_id,import_created,import_last_seen) - VALUES (i_group_id,i_svc_id,i_current_import_id,i_current_import_id); - END IF; - END IF; - RETURN; -END; -$$ LANGUAGE plpgsql; - - ------------------ ab hier kommen die flat-Funktionen ----------------------- - ----------------------------------------------------- --- FUNCTION: import_svc_refhandler_svcgrp_flat_add_group --- Zweck: die Gruppenzugehoerigkeiten der Gruppe $2 aufloesen --- Zweck: und in svcgrp_flat als Teil von $1 eintragen --- Parameter: $1: svc_id der Top-Level-Gruppe --- Parameter: $2: svc_id der Unter-Gruppe --- Parameter: $3: Rekursionsebene - fuer Abbruch nach 20 Rekursionen --- verwendete --- Funktionen: insert_svc_group_relations_flat (rekursiv) --- RETURNS: VOID --- -CREATE OR REPLACE FUNCTION import_svc_refhandler_svcgrp_flat_add_group (BIGINT,BIGINT,INTEGER,BIGINT) RETURNS VOID AS $$ -DECLARE - i_top_group_id ALIAS FOR $1; - i_group_id ALIAS FOR $2; - i_rec_level ALIAS FOR $3; - i_current_import_id ALIAS FOR $4; - r_member RECORD; - r_svc RECORD; - r_member_exists RECORD; -BEGIN - IF i_rec_level>20 THEN - PERFORM error_handling('ERR_SVC_GROUP_REC_LVL_EXCEEDED'); - END IF; - FOR r_member IN - SELECT svcgrp_member_id FROM svcgrp WHERE svcgrp_id=i_group_id - LOOP - SELECT INTO r_member_exists * FROM svcgrp_flat WHERE - svcgrp_flat_id=i_top_group_id AND svcgrp_flat_member_id=r_member.svcgrp_member_id; - IF NOT FOUND THEN - INSERT INTO svcgrp_flat (svcgrp_flat_id,svcgrp_flat_member_id,import_created,import_last_seen) - VALUES (i_top_group_id,r_member.svcgrp_member_id,i_current_import_id,i_current_import_id); - END IF; - IF is_svc_group(r_member.svcgrp_member_id) THEN - PERFORM import_svc_refhandler_svcgrp_flat_add_group - (i_top_group_id, r_member.svcgrp_member_id, i_rec_level+1, i_current_import_id); - END IF; - END LOOP; - RETURN; -END; -$$ LANGUAGE plpgsql; - ----------------------------------------------------- --- FUNCTION: import_svc_refhandler_change_svcgrp_member_refs --- Zweck: ueberall dort, wo das alte (geaenderte) Objekt in svcgrp als member auftaucht --- Zweck: muessen die Referenzen vom alten auf das neue Objekt umgebogen werden --- Parameter: old_svc_id, new_svc_id --- RETURNS: VOID -CREATE OR REPLACE FUNCTION import_svc_refhandler_change_svcgrp_member_refs(BIGINT, BIGINT, BIGINT) RETURNS VOID AS $$ -DECLARE - i_old_id ALIAS FOR $1; -- id des bestehenden Datensatzes aus service - i_new_id ALIAS FOR $2; -- id des neuen Datensatzes aus service - i_current_import_id ALIAS FOR $3; - r_svcgrp svcgrp%ROWTYPE; -BEGIN - FOR r_svcgrp IN - SELECT * FROM svcgrp WHERE svcgrp_member_id=i_old_id AND active - LOOP -- die neue Beziehung wird eingefuegt - INSERT INTO svcgrp (svcgrp_id, svcgrp_member_id, import_created, import_last_seen) - VALUES (r_svcgrp.svcgrp_id, i_new_id, i_current_import_id, i_current_import_id); - END LOOP; - RETURN; -END; -$$ language plpgsql; - ----------------------------------------------------- --- FUNCTION: import_svc_refhandler_change_svcgrp_flat_member_refs --- Zweck: ueberall dort, wo das alte (geaenderte) Objekt in svcgrp_flat als member auftaucht --- Zweck: muessen die Referenzen vom alten auf das neue Objekt umgebogen werden --- Parameter: old_svc_id, new_svc_id --- RETURNS: VOID -CREATE OR REPLACE FUNCTION import_svc_refhandler_change_svcgrp_flat_member_refs(BIGINT, BIGINT, BIGINT) RETURNS VOID AS $$ -DECLARE - i_old_id ALIAS FOR $1; -- id des bestehenden Datensatzes aus service - i_new_id ALIAS FOR $2; -- id des neuen Datensatzes aus service - i_current_import_id ALIAS FOR $3; - r_svcgrp_flat svcgrp_flat%ROWTYPE; - r_member_exists svcgrp_flat%ROWTYPE; -BEGIN - FOR r_svcgrp_flat IN - SELECT * FROM svcgrp_flat WHERE svcgrp_flat_member_id=i_old_id AND active - LOOP -- es wird die neue Beziehung eingefuegt - SELECT INTO r_member_exists * FROM svcgrp_flat WHERE - svcgrp_flat_id=r_svcgrp_flat.svcgrp_flat_id AND svcgrp_flat_member_id=i_new_id; - IF NOT FOUND THEN -- wenn das Mitglied noch nicht in der Gruppe ist: eintragen - verhindert doppelte Eintraege - INSERT INTO svcgrp_flat (svcgrp_flat_id,svcgrp_flat_member_id,import_created,import_last_seen) - VALUES (r_svcgrp_flat.svcgrp_flat_id, i_new_id, i_current_import_id, i_current_import_id); - END IF; - END LOOP; - RETURN; -END; -$$ language plpgsql; - ----------------------------------------------------- --- FUNCTION: import_svc_refhandler_change_rule_service_refs --- Zweck: ueberall dort, wo das alte (geaenderte) Objekt in rule_service auftaucht --- Zweck: muessen die Referenzen vom alten auf das neue Objekt umgebogen werden --- Parameter: old_svc_id, new_svc_id --- RETURNS: VOID -CREATE OR REPLACE FUNCTION import_svc_refhandler_change_rule_service_refs (BIGINT, BIGINT, BIGINT) RETURNS VOID AS $$ -DECLARE - i_old_id ALIAS FOR $1; -- id des bestehenden Datensatzes aus service - i_new_id ALIAS FOR $2; -- id des neuen Datensatzes aus service - i_import_id ALIAS FOR $3; -- id des aktuellen Imports - r_service rule_service%ROWTYPE; -BEGIN - FOR r_service IN - SELECT * FROM rule_service WHERE svc_id=i_old_id AND active - LOOP -- die neue Beziehung wird eingefuegt - INSERT INTO rule_service (rule_id,svc_id,rs_create,rs_last_seen) - VALUES (r_service.rule_id, i_new_id, i_import_id, i_import_id); - END LOOP; - RETURN; -END; -$$ language plpgsql; diff --git a/roles/database/files/sql/idempotent/fworch-texts.sql b/roles/database/files/sql/idempotent/fworch-texts.sql index 7d1ecdc4ce..d32547c8fc 100644 --- a/roles/database/files/sql/idempotent/fworch-texts.sql +++ b/roles/database/files/sql/idempotent/fworch-texts.sql @@ -1,3 +1,27 @@ +-- text codes (roughly) categorized: +-- U: user texts (explanation or confirmation texts) +-- E: error texts +-- A: Api errors +-- T: texts from external sources (Ldap, other database tables) +-- C: Contextual Info (Tooltips) +-- H: help pages +-- 0000-0999: General +-- 1000-1999: Reporting +-- 2000-2999: Scheduling +-- 3000-3999: Archive +-- 4000-4999: Recertification +-- 5000-5999: Settings +-- 5000-5099: general +-- 5100-5199: devices +-- 5200-5299: authorization +-- 5300-5399: defaults +-- 5400-5499: personal settings +-- 5500-5599: workflow module +-- 5600-5699: modelling +-- 6000-6999: API +-- 7000-7999: Monitoring +-- 8000-8999: Workflow +-- 9000-9999: Modelling -- cleanup DELETE FROM txt; @@ -12,6 +36,300 @@ INSERT INTO txt VALUES ('English', 'English', 'English'); INSERT INTO txt VALUES ('German', 'German', 'Deutsch'); INSERT INTO txt VALUES ('German', 'English', 'German'); +-- enum values +INSERT INTO txt VALUES ('master', 'German', 'Master'); +INSERT INTO txt VALUES ('master', 'English', 'Master'); +INSERT INTO txt VALUES ('access', 'German', 'Zugriff'); +INSERT INTO txt VALUES ('access', 'English', 'Access'); +INSERT INTO txt VALUES ('generic', 'German', 'Generisch'); +INSERT INTO txt VALUES ('generic', 'English', 'Generic'); +INSERT INTO txt VALUES ('rule_modify', 'German', 'Regel ändern'); +INSERT INTO txt VALUES ('rule_modify', 'English', 'Modify Rule'); +INSERT INTO txt VALUES ('rule_delete', 'German', 'Regel löschen'); +INSERT INTO txt VALUES ('rule_delete', 'English', 'Delete Rule'); +INSERT INTO txt VALUES ('group_create', 'German', 'Gruppe anlegen'); +INSERT INTO txt VALUES ('group_create', 'English', 'Create Group'); +INSERT INTO txt VALUES ('group_modify', 'German', 'Gruppe ändern'); +INSERT INTO txt VALUES ('group_modify', 'English', 'Modify Group'); +INSERT INTO txt VALUES ('group_delete', 'German', 'Gruppe löschen'); +INSERT INTO txt VALUES ('group_delete', 'English', 'Delete Group'); +INSERT INTO txt VALUES ('new_interface', 'German', 'Neue Schnittstelle'); +INSERT INTO txt VALUES ('new_interface', 'English', 'New Interface'); +INSERT INTO txt VALUES ('TicketCreation', 'German', 'Ticket-Erstellung'); +INSERT INTO txt VALUES ('TicketCreation', 'English', 'Ticket Creation'); +INSERT INTO txt VALUES ('TicketClosure', 'German', 'Ticket-Abschluss'); +INSERT INTO txt VALUES ('TicketClosure', 'English', 'Ticket Closure'); +INSERT INTO txt VALUES ('ApprovalOpened', 'German', 'Freigabe geöffnet'); +INSERT INTO txt VALUES ('ApprovalOpened', 'English', 'Approval Opened'); +INSERT INTO txt VALUES ('Approved', 'German', 'Genehmigt'); +INSERT INTO txt VALUES ('Approved', 'English', 'Approved'); +INSERT INTO txt VALUES ('TaskStart', 'German', 'Aufgabenstart'); +INSERT INTO txt VALUES ('TaskStart', 'English', 'Task Start'); +INSERT INTO txt VALUES ('TaskEnd', 'German', 'Aufgabenende'); +INSERT INTO txt VALUES ('TaskEnd', 'English', 'Task End'); +INSERT INTO txt VALUES ('ImplementationStart', 'German', 'Implementierungsstart'); +INSERT INTO txt VALUES ('ImplementationStart', 'English', 'Implementation Start'); +INSERT INTO txt VALUES ('ImplementationEnd', 'German', 'Implementierungsende'); +INSERT INTO txt VALUES ('ImplementationEnd', 'English', 'Implementation End'); +INSERT INTO txt VALUES ('AnyActivity', 'German', 'Beliebige Aktivität'); +INSERT INTO txt VALUES ('AnyActivity', 'English', 'Any Activity'); +INSERT INTO txt VALUES ('None', 'German', 'Keine(r/s)'); +INSERT INTO txt VALUES ('None', 'English', 'None'); +INSERT INTO txt VALUES ('OnSet', 'German', 'Beim Erreichen'); +INSERT INTO txt VALUES ('OnSet', 'English', 'On set'); +INSERT INTO txt VALUES ('OnLeave', 'German', 'Beim Verlassen'); +INSERT INTO txt VALUES ('OnLeave', 'English', 'On leave'); +INSERT INTO txt VALUES ('OfferButton', 'German', 'Schaltfläche anbieten'); +INSERT INTO txt VALUES ('OfferButton', 'English', 'Offer button'); +INSERT INTO txt VALUES ('OwnerChange', 'German', 'Eigentümerwechsel'); +INSERT INTO txt VALUES ('OwnerChange', 'English', 'Owner Change'); +INSERT INTO txt VALUES ('OnAssignment', 'German', 'Bei Zuweisung'); +INSERT INTO txt VALUES ('OnAssignment', 'English', 'On Assignment'); +INSERT INTO txt VALUES ('DoNothing', 'German', 'Keine Aktion'); +INSERT INTO txt VALUES ('DoNothing', 'English', 'Do Nothing'); +INSERT INTO txt VALUES ('AutoPromote', 'German', 'Autom. Weiterleitung'); +INSERT INTO txt VALUES ('AutoPromote', 'English', 'Auto-forward'); +INSERT INTO txt VALUES ('AddApproval', 'German', 'Genehmigung hinzufügen'); +INSERT INTO txt VALUES ('AddApproval', 'English', 'Add approval'); +INSERT INTO txt VALUES ('SetAlert', 'German', 'Alarm auslösen'); +INSERT INTO txt VALUES ('SetAlert', 'English', 'Set alert'); +INSERT INTO txt VALUES ('TrafficPathAnalysis', 'German', 'Pfadanalyse'); +INSERT INTO txt VALUES ('TrafficPathAnalysis', 'English', 'Path Analysis'); +INSERT INTO txt VALUES ('ExternalCall', 'German', 'Externer Aufruf'); +INSERT INTO txt VALUES ('ExternalCall', 'English', 'External call'); +INSERT INTO txt VALUES ('SendEmail', 'German', 'Email verschicken'); +INSERT INTO txt VALUES ('SendEmail', 'English', 'Send email'); +INSERT INTO txt VALUES ('UpdateConnectionOwner','German', 'Verbindungseigentümer ändern'); +INSERT INTO txt VALUES ('UpdateConnectionOwner','English', 'Update Connection Owner'); +INSERT INTO txt VALUES ('UpdateConnectionRelease','German', 'Verbindung veröffentlichen'); +INSERT INTO txt VALUES ('UpdateConnectionRelease','English','Publish Connection'); +INSERT INTO txt VALUES ('UpdateConnectionReject','German', 'Schnittstelle ablehnen'); +INSERT INTO txt VALUES ('UpdateConnectionReject','English', 'Reject Interface'); +INSERT INTO txt VALUES ('DisplayConnection', 'German', 'Verbindung darstellen'); +INSERT INTO txt VALUES ('DisplayConnection', 'English', 'Display Connection'); +INSERT INTO txt VALUES ('Ticket', 'German', 'Ticket'); +INSERT INTO txt VALUES ('Ticket', 'English', 'Ticket'); +INSERT INTO txt VALUES ('RequestTask', 'German', 'fachlicher Auftrag'); +INSERT INTO txt VALUES ('RequestTask', 'English', 'Request Task'); +INSERT INTO txt VALUES ('ImplementationTask', 'German', 'Implementierungs-Auftrag'); +INSERT INTO txt VALUES ('ImplementationTask', 'English', 'Implementation Task'); +INSERT INTO txt VALUES ('Approval', 'German', 'Genehmigung'); +INSERT INTO txt VALUES ('Approval', 'English', 'Approval'); +INSERT INTO txt VALUES ('never', 'German', 'Niemals'); +INSERT INTO txt VALUES ('never', 'English', 'Never'); +INSERT INTO txt VALUES ('onlyForOneDevice', 'German', 'Nur eines wenn Gerät vorhanden'); +INSERT INTO txt VALUES ('onlyForOneDevice', 'English', 'Only one if device available'); +INSERT INTO txt VALUES ('forEachDevice', 'German', 'Für jedes Gerät'); +INSERT INTO txt VALUES ('forEachDevice', 'English', 'For each device'); +INSERT INTO txt VALUES ('enterInReqTask', 'German', 'Gerät im Antrag eingeben'); +INSERT INTO txt VALUES ('enterInReqTask', 'English', 'Enter device in request'); +INSERT INTO txt VALUES ('oneTaskForAllDevices', 'German', 'Ein Auftrag für alle Geräte'); +INSERT INTO txt VALUES ('oneTaskForAllDevices', 'English', 'One task for all devices'); +INSERT INTO txt VALUES ('afterPathAnalysis', 'German', 'Nach Pfadanalyse'); +INSERT INTO txt VALUES ('afterPathAnalysis', 'English', 'After path analysis'); +INSERT INTO txt VALUES ('WriteToDeviceList', 'German', 'In Geräteliste eintragen'); +INSERT INTO txt VALUES ('WriteToDeviceList', 'English', 'Write to device list'); +INSERT INTO txt VALUES ('DisplayFoundDevices', 'German', 'Gefundene Geräte darstellen'); +INSERT INTO txt VALUES ('DisplayFoundDevices', 'English', 'Display found devices'); +INSERT INTO txt VALUES ('Sunday', 'German', 'Sonntag'); +INSERT INTO txt VALUES ('Sunday', 'English', 'Sunday'); +INSERT INTO txt VALUES ('Monday', 'German', 'Montag'); +INSERT INTO txt VALUES ('Monday', 'English', 'Monday'); +INSERT INTO txt VALUES ('Tuesday', 'German', 'Dienstag'); +INSERT INTO txt VALUES ('Tuesday', 'English', 'Tuesday'); +INSERT INTO txt VALUES ('Wednesday', 'German', 'Mittwoch'); +INSERT INTO txt VALUES ('Wednesday', 'English', 'Wednesday'); +INSERT INTO txt VALUES ('Thursday', 'German', 'Donnerstag'); +INSERT INTO txt VALUES ('Thursday', 'English', 'Thursday'); +INSERT INTO txt VALUES ('Friday', 'German', 'Freitag'); +INSERT INTO txt VALUES ('Friday', 'English', 'Friday'); +INSERT INTO txt VALUES ('Saturday', 'German', 'Samstag'); +INSERT INTO txt VALUES ('Saturday', 'English', 'Saturday'); +INSERT INTO txt VALUES ('All', 'German', 'Alle'); +INSERT INTO txt VALUES ('All', 'English', 'All'); +INSERT INTO txt VALUES ('Undefined', 'German', 'Undefiniert'); +INSERT INTO txt VALUES ('Undefined', 'English', 'Undefined'); +INSERT INTO txt VALUES ('Rules', 'German', 'Regeln: Standard'); +INSERT INTO txt VALUES ('Rules', 'English', 'Rules: Standard'); +INSERT INTO txt VALUES ('Changes', 'German', 'Changes: Standard'); +INSERT INTO txt VALUES ('Changes', 'English', 'Changes: Standard'); +INSERT INTO txt VALUES ('Statistics', 'German', 'Statistik'); +INSERT INTO txt VALUES ('Statistics', 'English', 'Statistics'); +INSERT INTO txt VALUES ('NatRules', 'German', 'Regeln: NAT'); +INSERT INTO txt VALUES ('NatRules', 'English', 'Rules: NAT'); +INSERT INTO txt VALUES ('ResolvedRules', 'German', 'Regeln: Aufgelöst'); +INSERT INTO txt VALUES ('ResolvedRules', 'English', 'Rules: Resolved'); +INSERT INTO txt VALUES ('ResolvedRulesTech', 'German', 'Regeln: Technisch'); +INSERT INTO txt VALUES ('ResolvedRulesTech', 'English', 'Rules: Technical'); +INSERT INTO txt VALUES ('Recertification', 'German', 'Zert: Regel-Übersicht'); +INSERT INTO txt VALUES ('Recertification', 'English', 'Cert: Rule Overview'); +INSERT INTO txt VALUES ('ResolvedChanges', 'German', 'Changes: Aufgelöst'); +INSERT INTO txt VALUES ('ResolvedChanges', 'English', 'Changes: Resolved'); +INSERT INTO txt VALUES ('ResolvedChangesTech', 'German', 'Changes: Technisch'); +INSERT INTO txt VALUES ('ResolvedChangesTech', 'English', 'Changes: Technical'); +INSERT INTO txt VALUES ('UnusedRules', 'German', 'Regeln: Unbenutzt'); +INSERT INTO txt VALUES ('UnusedRules', 'English', 'Rules: Unused'); +INSERT INTO txt VALUES ('Connections', 'German', 'Modell: Verbindungen'); +INSERT INTO txt VALUES ('Connections', 'English', 'Model: Connections'); +INSERT INTO txt VALUES ('AppRules', 'German', 'Modell: App-Regeln'); +INSERT INTO txt VALUES ('AppRules', 'English', 'Model: App Rules'); +INSERT INTO txt VALUES ('VarianceAnalysis', 'German', 'Modell: Soll-Ist'); +INSERT INTO txt VALUES ('VarianceAnalysis', 'English', 'Model: Variances'); +INSERT INTO txt VALUES ('OwnerRecertification', 'German', 'Zert: Eigentümer-Übersicht'); +INSERT INTO txt VALUES ('OwnerRecertification', 'English', 'Cert: Owner Overview'); +INSERT INTO txt VALUES ('Owners', 'German', 'Eigentümer'); +INSERT INTO txt VALUES ('Owners', 'English', 'Owners'); +INSERT INTO txt VALUES ('RecertificationEvent', 'German', 'Zert: Zertifikat'); +INSERT INTO txt VALUES ('RecertificationEvent', 'English', 'Cert: Certificate'); +INSERT INTO txt VALUES ('RecertEventReport', 'German', 'Zert: Zert-Regel-Details'); +INSERT INTO txt VALUES ('RecertEventReport', 'English', 'Cert: Cert Rule Details'); +INSERT INTO txt VALUES ('ComplianceReport', 'German', 'Compliance Report'); +INSERT INTO txt VALUES ('ComplianceReport', 'English', 'Compliance Report'); +INSERT INTO txt VALUES ('ComplianceDiffReport', 'German', 'Compliance Diff Report'); +INSERT INTO txt VALUES ('ComplianceDiffReport', 'English', 'Compliance Diff Report'); +INSERT INTO txt VALUES ('TicketReport', 'German', 'Workflow: Tickets'); +INSERT INTO txt VALUES ('TicketReport', 'English', 'Workflow: Tickets'); +INSERT INTO txt VALUES ('TicketChangeReport', 'German', 'Workflow: Ticket-Änderungen'); +INSERT INTO txt VALUES ('TicketChangeReport', 'English', 'Workflow: Ticket Changes'); +INSERT INTO txt VALUES ('mixed', 'German', 'Gemischt'); +INSERT INTO txt VALUES ('mixed', 'English', 'Mixed'); +INSERT INTO txt VALUES ('exclusive', 'German', 'Exklusiv'); +INSERT INTO txt VALUES ('exclusive', 'English', 'Exclusive'); +INSERT INTO txt VALUES ('AppRole', 'German', 'App Rolle'); +INSERT INTO txt VALUES ('AppRole', 'English', 'App Role'); +INSERT INTO txt VALUES ('AppZone', 'German', 'Anwendungszone'); +INSERT INTO txt VALUES ('AppZone', 'English', 'App Zone'); +INSERT INTO txt VALUES ('NetworkZone', 'German', 'Netzwerkzone'); +INSERT INTO txt VALUES ('NetworkZone', 'English', 'Network Zone'); +INSERT INTO txt VALUES ('NetworkArea', 'German', 'Netzwerkarea'); +INSERT INTO txt VALUES ('NetworkArea', 'English', 'Network Area'); +INSERT INTO txt VALUES ('CommunicationProfile', 'German', 'Kommunikationsprofil'); +INSERT INTO txt VALUES ('CommunicationProfile', 'English', 'Communication Profile'); +INSERT INTO txt VALUES ('Connection', 'German', 'Verbindung'); +INSERT INTO txt VALUES ('Connection', 'English', 'Connection'); +INSERT INTO txt VALUES ('AppServer', 'German', 'App Server'); +INSERT INTO txt VALUES ('AppServer', 'English', 'App Server'); +INSERT INTO txt VALUES ('ServiceGroup', 'German', 'Dienstgruppe'); +INSERT INTO txt VALUES ('ServiceGroup', 'English', 'Service Group'); +INSERT INTO txt VALUES ('Service', 'German', 'Dienst'); +INSERT INTO txt VALUES ('Service', 'English', 'Service'); +INSERT INTO txt VALUES ('Insert', 'German', 'Einfügen'); +INSERT INTO txt VALUES ('Insert', 'English', 'Insert'); +INSERT INTO txt VALUES ('Update', 'German', 'Ändern'); +INSERT INTO txt VALUES ('Update', 'English', 'Update'); +INSERT INTO txt VALUES ('Delete', 'German', 'Löschen'); +INSERT INTO txt VALUES ('Delete', 'English', 'Delete'); +INSERT INTO txt VALUES ('Assign', 'German', 'Zuweisen'); +INSERT INTO txt VALUES ('Assign', 'English', 'Assign'); +INSERT INTO txt VALUES ('Unassign', 'German', 'Zuweisung aufheben'); +INSERT INTO txt VALUES ('Unassign', 'English', 'Unassign'); +INSERT INTO txt VALUES ('MarkDeleted', 'German', 'Als gelöscht markieren'); +INSERT INTO txt VALUES ('MarkDeleted', 'English', 'Mark Deleted'); +INSERT INTO txt VALUES ('Reactivate', 'German', 'Reaktivieren'); +INSERT INTO txt VALUES ('Reactivate', 'English', 'Reactivate'); +INSERT INTO txt VALUES ('InitRequests', 'German', 'Beantragung starten'); +INSERT INTO txt VALUES ('InitRequests', 'English', 'Init Request'); +INSERT INTO txt VALUES ('Request', 'German', 'Beantragen'); +INSERT INTO txt VALUES ('Request', 'English', 'Request'); +INSERT INTO txt VALUES ('Implement', 'German', 'Implementieren'); +INSERT INTO txt VALUES ('Implement', 'English', 'Implement'); +INSERT INTO txt VALUES ('Reject', 'German', 'Ablehnen'); +INSERT INTO txt VALUES ('Reject', 'English', 'Reject'); +INSERT INTO txt VALUES ('Decommission', 'German', 'Stilllegen'); +INSERT INTO txt VALUES ('Decommission', 'English', 'Decommission'); +INSERT INTO txt VALUES ('Recertify', 'German', 'Rezertifizieren'); +INSERT INTO txt VALUES ('Recertify', 'English', 'Recertify'); +INSERT INTO txt VALUES ('SimpleText', 'German', 'Einfacher Text (kein Report)'); +INSERT INTO txt VALUES ('SimpleText', 'English', 'Simple Text (no Report)'); +INSERT INTO txt VALUES ('HtmlInBody', 'German', 'Html in Email'); +INSERT INTO txt VALUES ('HtmlInBody', 'English', 'Html in email body'); +INSERT INTO txt VALUES ('PdfAsAttachment', 'German', 'Pdf als Anhang'); +INSERT INTO txt VALUES ('PdfAsAttachment', 'English', 'Pdf as Attachment'); +INSERT INTO txt VALUES ('HtmlAsAttachment', 'German', 'Html als Anhang'); +INSERT INTO txt VALUES ('HtmlAsAttachment', 'English', 'Html as Attachment'); +INSERT INTO txt VALUES ('CsvAsAttachment', 'German', 'Csv als Anhang'); +INSERT INTO txt VALUES ('CsvAsAttachment', 'English', 'Csv as Attachment'); +INSERT INTO txt VALUES ('JsonAsAttachment', 'German', 'Json als Anhang'); +INSERT INTO txt VALUES ('JsonAsAttachment', 'English', 'Json as Attachment'); +INSERT INTO txt VALUES ('CurrentHandler', 'German', 'Aktueller Bearbeiter'); +INSERT INTO txt VALUES ('CurrentHandler', 'English', 'Current handler'); +INSERT INTO txt VALUES ('RecentHandler', 'German', 'Vorheriger Bearbeiter'); +INSERT INTO txt VALUES ('RecentHandler', 'English', 'Recent handler'); +INSERT INTO txt VALUES ('AssignedGroup', 'German', 'Zugewiesene Gruppe'); +INSERT INTO txt VALUES ('AssignedGroup', 'English', 'Assigned Group'); +INSERT INTO txt VALUES ('OwnerMainResponsible', 'German', 'Eigentümer Hauptverantwortlicher'); +INSERT INTO txt VALUES ('OwnerMainResponsible', 'English', 'Owner Main Responsible'); +INSERT INTO txt VALUES ('AllOwnerResponsibles', 'German', 'Eigentümer alle Verantwortlichen'); +INSERT INTO txt VALUES ('AllOwnerResponsibles', 'English', 'Owner all responsibles'); +INSERT INTO txt VALUES ('OwnerGroupOnly', 'German', 'nur Eigentümergruppe'); +INSERT INTO txt VALUES ('OwnerGroupOnly', 'English', 'Owner Group only'); +INSERT INTO txt VALUES ('FallbackToMainResponsibleIfOwnerGroupEmpty', 'German', 'Hauptverantworlicher wenn Eigentümergruppe nicht spezifiziert oder leer'); +INSERT INTO txt VALUES ('FallbackToMainResponsibleIfOwnerGroupEmpty', 'English','Owner Main Responsible if Owner Group not specified or empty'); +INSERT INTO txt VALUES ('Requester', 'German', 'Antragsteller'); +INSERT INTO txt VALUES ('Requester', 'English', 'Requester'); +INSERT INTO txt VALUES ('Approver', 'German', 'Genehmiger'); +INSERT INTO txt VALUES ('Approver', 'English', 'Approver'); +INSERT INTO txt VALUES ('LastCommenter', 'German', 'Letzter Kommentierender'); +INSERT INTO txt VALUES ('LastCommenter', 'English', 'Last commenter'); +INSERT INTO txt VALUES ('AllCommenters', 'German', 'Alle Kommentierenden'); +INSERT INTO txt VALUES ('AllCommenters', 'English', 'All commenters'); +INSERT INTO txt VALUES ('OtherAddresses', 'German', 'Andere Adressen'); +INSERT INTO txt VALUES ('OtherAddresses', 'English', 'Other Addresses'); +INSERT INTO txt VALUES ('Standard', 'German', 'Normal'); +INSERT INTO txt VALUES ('Standard', 'English', 'Standard'); +INSERT INTO txt VALUES ('InterfaceRequested', 'German', 'Schnittstelle beantragt'); +INSERT INTO txt VALUES ('InterfaceRequested', 'English', 'Interface requested'); +INSERT INTO txt VALUES ('InterfaceRejected', 'German', 'Schnittstelle abgelehnt'); +INSERT INTO txt VALUES ('InterfaceRejected', 'English', 'Interface rejected'); +INSERT INTO txt VALUES ('Published', 'German', 'Veröffentlicht'); +INSERT INTO txt VALUES ('Published', 'English', 'Published'); +INSERT INTO txt VALUES ('Requested', 'German', 'Beantragt'); +INSERT INTO txt VALUES ('Requested', 'English', 'Requested'); +INSERT INTO txt VALUES ('Rejected', 'German', 'Abgelehnt'); +INSERT INTO txt VALUES ('Rejected', 'English', 'Rejected'); +INSERT INTO txt VALUES ('Internal', 'German', 'Intern'); +INSERT INTO txt VALUES ('Internal', 'English', 'Internal'); +INSERT INTO txt VALUES ('RuleByRule', 'German', 'Regel für Regel'); +INSERT INTO txt VALUES ('RuleByRule', 'English', 'Rule by Rule'); +INSERT INTO txt VALUES ('OwnersAndRules', 'German', 'Eigentümer und Regeln'); +INSERT INTO txt VALUES ('OwnersAndRules', 'English', 'Owners And Rules'); +INSERT INTO txt VALUES ('RecertDate', 'German', 'Rezertifizierungsdatum'); +INSERT INTO txt VALUES ('RecertDate', 'English', 'Recertification Date'); +INSERT INTO txt VALUES ('RequestDate', 'German', 'Antragsdatum'); +INSERT INTO txt VALUES ('RequestDate', 'English', 'Request Date'); +INSERT INTO txt VALUES ('RuleExpiry', 'German', 'Ablaufdatum'); +INSERT INTO txt VALUES ('RuleExpiry', 'English', 'Expiry Date'); +INSERT INTO txt VALUES ('DecommissionDate', 'German', 'Stilllegungsdatum'); +INSERT INTO txt VALUES ('DecommissionDate', 'English', 'Decommission Date'); +INSERT INTO txt VALUES ('Public', 'German', 'Öffentlich'); +INSERT INTO txt VALUES ('Public', 'English', 'Public'); +INSERT INTO txt VALUES ('Restricted', 'German', 'Beschränkt'); +INSERT INTO txt VALUES ('Restricted', 'English', 'Restricted'); +INSERT INTO txt VALUES ('Private', 'German', 'Privat'); +INSERT INTO txt VALUES ('Private', 'English', 'Private'); +INSERT INTO txt VALUES ('IpBased', 'German', 'IP-basiert'); +INSERT INTO txt VALUES ('IpBased', 'English', 'IP based'); +INSERT INTO txt VALUES ('CustomField', 'German', 'Custom-Feld'); +INSERT INTO txt VALUES ('CustomField', 'English', 'Custom field'); +INSERT INTO txt VALUES ('NameField', 'German', 'Namensfeld'); +INSERT INTO txt VALUES ('NameField', 'English', 'Name field'); +INSERT INTO txt VALUES ('Manual', 'German', 'Manuell'); +INSERT INTO txt VALUES ('Manual', 'English', 'Manual'); +INSERT INTO txt VALUES ('DemoData', 'German', 'Demo-Daten'); +INSERT INTO txt VALUES ('DemoData', 'English', 'Demo data'); +INSERT INTO txt VALUES ('Imports', 'German', 'Importe'); +INSERT INTO txt VALUES ('Imports', 'English', 'Imports'); +INSERT INTO txt VALUES ('RecertRefresh', 'German', 'Zertifizierungs-Aktualisierung'); +INSERT INTO txt VALUES ('RecertRefresh', 'English', 'Recertification refresh'); +INSERT INTO txt VALUES ('RecertCheck', 'German', 'Zertifizierungs-Check'); +INSERT INTO txt VALUES ('RecertCheck', 'English', 'Recertification check'); +INSERT INTO txt VALUES ('UnansweredInterfaceRequests','German','Unbeantwortete Interface-Anfragen'); +INSERT INTO txt VALUES ('UnansweredInterfaceRequests','English','Unanswered interface requests'); +INSERT INTO txt VALUES ('RuleExpiryCheck', 'German', 'Ablaufdatum-Check'); +INSERT INTO txt VALUES ('RuleExpiryCheck', 'English', 'Rule expiry check'); +INSERT INTO txt VALUES ('OwnerActiveRules', 'German', 'Aktive Regeln von deaktivierten Eigentümern'); +INSERT INTO txt VALUES ('OwnerActiveRules', 'English', 'Active rules of decommissioned owners'); + -- general INSERT INTO txt VALUES ('cancel', 'German', 'Abbrechen'); INSERT INTO txt VALUES ('cancel', 'English', 'Cancel'); @@ -59,16 +377,32 @@ INSERT INTO txt VALUES ('added', 'German', 'hinzugefügt'); INSERT INTO txt VALUES ('added', 'English', 'added'); INSERT INTO txt VALUES ('deleted', 'German', 'gelöscht'); INSERT INTO txt VALUES ('deleted', 'English', 'deleted'); +INSERT INTO txt VALUES ('surplus', 'German', 'zuviel'); +INSERT INTO txt VALUES ('surplus', 'English', 'surplus'); +INSERT INTO txt VALUES ('missing', 'German', 'fehlend'); +INSERT INTO txt VALUES ('missing', 'English', 'missing'); INSERT INTO txt VALUES ('modified', 'German', 'geändert'); INSERT INTO txt VALUES ('modified', 'English', 'modified'); INSERT INTO txt VALUES ('id', 'German', 'Id'); INSERT INTO txt VALUES ('id', 'English', 'Id'); INSERT INTO txt VALUES ('coming_soon', 'German', '(demnächst)'); INSERT INTO txt VALUES ('coming_soon', 'English', '(coming soon)'); -INSERT INTO txt VALUES ('in_progress', 'German', 'in Arbeit'); -INSERT INTO txt VALUES ('in_progress', 'English', 'in progress'); +INSERT INTO txt VALUES ('in_progress', 'German', 'In Arbeit - Bitte warten'); +INSERT INTO txt VALUES ('in_progress', 'English', 'In Progress - Please wait'); INSERT INTO txt VALUES ('select', 'German', 'Auswählen'); INSERT INTO txt VALUES ('select', 'English', 'Select'); +INSERT INTO txt VALUES ('loading', 'German', 'Laden...'); +INSERT INTO txt VALUES ('loading', 'English', 'Loading...'); +INSERT INTO txt VALUES ('exporting', 'German', 'Exportieren...'); +INSERT INTO txt VALUES ('exporting', 'English', 'Exporting...'); +INSERT INTO txt VALUES ('PagerPagesize', 'German', 'Seitengrösse'); +INSERT INTO txt VALUES ('PagerPagesize', 'English', 'Page size'); +INSERT INTO txt VALUES ('PagerSubmit', 'German', 'Speichern'); +INSERT INTO txt VALUES ('PagerSubmit', 'English', 'Save'); +INSERT INTO txt VALUES ('order_by', 'German', 'Sortieren nach'); +INSERT INTO txt VALUES ('order_by', 'English', 'Order by'); +INSERT INTO txt VALUES ('sort_order', 'German', 'Sortierreihenfolge'); +INSERT INTO txt VALUES ('sort_order', 'English', 'Sort order'); -- (re)login INSERT INTO txt VALUES ('login', 'German', 'Anmelden'); @@ -87,16 +421,18 @@ INSERT INTO txt VALUES ('jwt_expiry_title', 'German', 'JWT läuft bald INSERT INTO txt VALUES ('jwt_expiry_title', 'English', 'JWT about to expire'); INSERT INTO txt VALUES ('jwt_expiry_text', 'German', 'Ihr Jwt (Session Token) ist kurz davor abzulaufen. Bitte geben Sie ihr Passwort ein, um einen neuen Jwt zu erzeugen.'); INSERT INTO txt VALUES ('jwt_expiry_text', 'English', 'Your jwt (session token) is about to expire. Please enter your password to generate a new jwt.'); -INSERT INTO txt VALUES ('jwt_expired_title', 'German', 'JWT abgelaufen'); -INSERT INTO txt VALUES ('jwt_expired_title', 'English', 'JWT expired'); +INSERT INTO txt VALUES ('jwt_expired_title', 'German', 'JWT abgelaufen'); +INSERT INTO txt VALUES ('jwt_expired_title', 'English', 'JWT expired'); INSERT INTO txt VALUES ('jwt_expired_text', 'German', 'Ihr Jwt (Session Token) ist abgelaufen, wodurch es zu einem Fehler kam. Bitte geben Sie ihr Passwort ein, um einen neuen Jwt zu erzeugen.'); INSERT INTO txt VALUES ('jwt_expired_text', 'English', 'Your jwt (session token) is expired. This lead to an error. Please enter your password to create a new jwt.'); -INSERT INTO txt VALUES ('permissions_title', 'German', 'Berechtigungen'); -INSERT INTO txt VALUES ('permissions_title', 'English', 'Permissions'); +INSERT INTO txt VALUES ('permissions', 'German', 'Berechtigungen'); +INSERT INTO txt VALUES ('permissions', 'English', 'Permissions'); INSERT INTO txt VALUES ('permissions_text', 'German', 'Ihre Berechtigungen wurden geändert. Bitte geben Sie Ihr Passwort ein, um Ihre Berechtigungen zu aktualisieren!'); INSERT INTO txt VALUES ('permissions_text', 'English', 'Your permissions have been changed. Re-login to update your permissions.'); INSERT INTO txt VALUES ('login_importer_error', 'German', 'Nutzer mit der Rolle "Importer" dürfen sich nicht an der Benutzeroberfläche anmelden. Diese Rolle dient einzig dem Importieren von eingebundenen Geräten.'); INSERT INTO txt VALUES ('login_importer_error', 'English', 'Users with role "importer" are not allowed to log into the user interface. The only purpose of this role is to import included devices.'); +INSERT INTO txt VALUES ('not_authorized', 'German', 'Authentisierung OK, aber keine Berechtigung/Authorisierung vorhanden.'); +INSERT INTO txt VALUES ('not_authorized', 'English', 'Authentication succeeded, but not authorized.'); -- navigation INSERT INTO txt VALUES ('reporting', 'German', 'Reporting'); @@ -109,6 +445,8 @@ INSERT INTO txt VALUES ('fworch_long', 'German', 'Firewall Orchestrator') INSERT INTO txt VALUES ('fworch_long', 'English', 'Firewall Orchestrator'); INSERT INTO txt VALUES ('help', 'German', 'Hilfe'); INSERT INTO txt VALUES ('help', 'English', 'Help'); +INSERT INTO txt VALUES ('online_help_fworch', 'German', 'Online-Hilfe FWORCH'); +INSERT INTO txt VALUES ('online_help_fworch', 'English', 'Online Help FWORCH'); INSERT INTO txt VALUES ('logout', 'German', 'Abmelden'); INSERT INTO txt VALUES ('logout', 'English', 'Logout'); INSERT INTO txt VALUES ('documentation', 'German', 'Dokumentation'); @@ -135,10 +473,14 @@ INSERT INTO txt VALUES ('api', 'German', 'API'); INSERT INTO txt VALUES ('api', 'English', 'API'); INSERT INTO txt VALUES ('workflow', 'German', 'Workflow'); INSERT INTO txt VALUES ('workflow', 'English', 'Workflow'); +INSERT INTO txt VALUES ('modules', 'German', 'Module'); +INSERT INTO txt VALUES ('modules', 'English', 'Modules'); INSERT INTO txt VALUES ('planning', 'German', 'Planung'); INSERT INTO txt VALUES ('planning', 'English', 'Planning'); INSERT INTO txt VALUES ('implementation', 'German', 'Implementierung'); INSERT INTO txt VALUES ('implementation', 'English', 'Implementation'); +INSERT INTO txt VALUES ('rollout', 'German', 'Einführung'); +INSERT INTO txt VALUES ('rollout', 'English', 'Rollout'); -- start INSERT INTO txt VALUES ('welcome_to', 'German', 'Willkommen zu Firewall Orchestrator'); @@ -147,26 +489,18 @@ INSERT INTO txt VALUES ('whats_new_in_version', 'German', 'Was ist neu in Firew INSERT INTO txt VALUES ('whats_new_in_version', 'English', 'Release notes Firewall Orchestrator version'); INSERT INTO txt VALUES ('whats_new_facts', 'German', ' '); INSERT INTO txt VALUES ('whats_new_facts', 'English', ' '); @@ -174,16 +508,17 @@ INSERT INTO txt VALUES ('getting_started', 'German', 'Einstiegshilfe'); INSERT INTO txt VALUES ('getting_started', 'English', 'Quick start'); INSERT INTO txt VALUES ('getting_started_facts', 'German', ' Die folgenden Hauptmenüpunkte stehen (je nach Rollenzugehörigkeit) zur Verfügung:
    -
  • Reporting: Erlaubt das einmalige Generieren verschiedener Reports sowie eine regelmäß Generierung
  • +
  • Reporting: Erlaubt das einmalige Generieren verschiedener Reports sowie eine regelmäßige Generierung
  • Workflow: Ticketsystem zur Beantragung von Änderungen
  • Rezertifizierung: Workflow zur Bereinigung des Regelwerks um nicht mehr benötigte Regeln
  • +
  • Modellierung: Erlaubt die verteilte Modellierung von Kommunikationsverbindungen (Soll-Zustand)
  • Netzanalyse: Pfadanalyse - welche Firewalls liegen zwischen zwei IP-Adressen?
  • -
  • Compliance: Definition von Zonenmatrix und Zugriffs-Compliance
  • +
  • Compliance: Definition von Zonenmatrix und Zugriffs-Compliance
  • Monitoring: Alarmierung, Log-Files, Import-Status, ...
  • Hilfeseiten: Benutzerhandbuch
  • Einstellungen: Alle Einstellungen wie z.B. Sprache der Benutzeroberfläche oder das Einbinden Ihrer eigenen Firewall-Systeme.
    - N.B. Stellen Sie sicher, dass Sie alle Demo-Daten (insbesondere die Demo-User) löschen (mit Hilfe der "Beispieldaten löschen" Option in den Einstellungen), + N.B. Stellen Sie sicher, dass Sie alle Demo-Daten (insbesondere die Demo-User) löschen (mit Hilfe der "Beispieldaten löschen" Option in den Einstellungen), bevor Sie in den produktiven Betrieb übergehen, da andernfalls ggf. Ihre Daten mit Default-Logins angezeigt werden könnten.
  • Abmelden: Firewall Orchestrator verlassen
@@ -194,13 +529,14 @@ The following top-level menu items are available (depending on role memberships)
  • Reporting: Ad-hoc generation and scheduling of reports
  • Workflow: Ticketing system for requesting and processing firewall changes
  • Recertification: Rulebase sanitization by continuously cleaning up existing rules
  • +
  • Modelling: Allows for distributed modelling of network connections (target state)
  • Network Analysis: Path analysis - which firewall is crossed when routing between two IP addresses?
  • -
  • Compliance: Defining zone matrix and access compliance
  • +
  • Compliance: Defining zone matrix and access compliance
  • Monitoring: Alarms, log files, import status, ...
  • Help: Manual pages
  • -
  • Settings: All settings like e.g. language of the user interface or +
  • Settings: All settings like e.g. language of the user interface or integration of your own firewalls.
    - N.B. Please make sure to delete all demo data (using the "Remove sample data" option under settings) + N.B. Please make sure to delete all demo data (using the "Remove sample data" option under settings) before using Firewall Orchestrator with production data. Otherwise you might expose your data by providing default accounts.
  • Logout: Leave Firewall Orchestrator
  • @@ -242,10 +578,14 @@ Choose from the following contact options: '); -- reporting +INSERT INTO txt VALUES ('report', 'German', 'Report'); +INSERT INTO txt VALUES ('report', 'English', 'Report'); INSERT INTO txt VALUES ('report_type', 'German', 'Report-Typ'); INSERT INTO txt VALUES ('report_type', 'English', 'Report Type'); INSERT INTO txt VALUES ('report_time', 'German', 'Report-Zeit'); INSERT INTO txt VALUES ('report_time', 'English', 'Report Time'); +INSERT INTO txt VALUES ('tenant_view', 'German', 'Mandantenansicht'); +INSERT INTO txt VALUES ('tenant_view', 'English', 'Tenant View'); INSERT INTO txt VALUES ('unused_days', 'German', 'Unbenutzt seit (in Tagen)'); INSERT INTO txt VALUES ('unused_days', 'English', 'Unused since (in days)'); INSERT INTO txt VALUES ('generation', 'German', 'Generierung'); @@ -288,6 +628,18 @@ INSERT INTO txt VALUES ('check_times', 'German', 'Prüfung Datumswerte'); INSERT INTO txt VALUES ('check_times', 'English', 'Check time values'); INSERT INTO txt VALUES ('select_device', 'German', 'Device(s) auswählen'); INSERT INTO txt VALUES ('select_device', 'English', 'Select device(s)'); +INSERT INTO txt VALUES ('select_management', 'German', 'Management(s) auswählen'); +INSERT INTO txt VALUES ('select_management', 'English', 'Select management(s)'); +INSERT INTO txt VALUES ('tenant_vis_devices', 'German', 'Mandanten-Firewalls'); +INSERT INTO txt VALUES ('tenant_vis_devices', 'English', 'Tenant firewalls'); +INSERT INTO txt VALUES ('edit_vis_devices', 'German', 'Devices für Mandant'); +INSERT INTO txt VALUES ('edit_vis_devices', 'English', 'Devices for tenant'); +INSERT INTO txt VALUES ('hide', 'German', 'versteckt'); +INSERT INTO txt VALUES ('hide', 'English', 'hidden'); +INSERT INTO txt VALUES ('shared', 'German', 'geteilt'); +INSERT INTO txt VALUES ('shared', 'English', 'shared'); +INSERT INTO txt VALUES ('unfiltered', 'German', 'ungefiltert'); +INSERT INTO txt VALUES ('unfiltered', 'English', 'unfiltered'); INSERT INTO txt VALUES ('select_all', 'German', 'Alle auswählen'); INSERT INTO txt VALUES ('select_all', 'English', 'Select all'); INSERT INTO txt VALUES ('clear_all', 'German', 'Auswahl leeren'); @@ -334,10 +686,24 @@ INSERT INTO txt VALUES ('number', 'German', 'Nr.'); INSERT INTO txt VALUES ('number', 'English', 'No.'); INSERT INTO txt VALUES ('name', 'German', 'Name'); INSERT INTO txt VALUES ('name', 'English', 'Name'); +INSERT INTO txt VALUES ('label', 'German', 'Label'); +INSERT INTO txt VALUES ('label', 'English', 'Label'); +INSERT INTO txt VALUES ('user_deleted', 'German', 'Nutzer gelöscht'); +INSERT INTO txt VALUES ('user_deleted', 'English', 'User deleted'); +INSERT INTO txt VALUES ('user_added', 'German', 'Nutzer hinzugefügt'); +INSERT INTO txt VALUES ('user_added', 'English', 'User added'); +INSERT INTO txt VALUES ('user_modified', 'German', 'Nutzer modifiziert'); +INSERT INTO txt VALUES ('user_modified', 'English', 'User modified'); INSERT INTO txt VALUES ('source', 'German', 'Quelle'); INSERT INTO txt VALUES ('source', 'English', 'Source'); INSERT INTO txt VALUES ('destination', 'German', 'Ziel'); INSERT INTO txt VALUES ('destination', 'English', 'Destination'); +INSERT INTO txt VALUES ('service_deleted', 'German', 'Dienst gelöscht'); +INSERT INTO txt VALUES ('service_deleted', 'English', 'Service deleted'); +INSERT INTO txt VALUES ('service_added', 'German', 'Dienst hinzugefügt'); +INSERT INTO txt VALUES ('service_added', 'English', 'Service added'); +INSERT INTO txt VALUES ('service_modified', 'German', 'Dienst modifiziert'); +INSERT INTO txt VALUES ('service_modified', 'English', 'Service modified'); INSERT INTO txt VALUES ('services', 'German', 'Dienste'); INSERT INTO txt VALUES ('services', 'English', 'Services'); INSERT INTO txt VALUES ('trans_source', 'German', 'Umgesetzte Quelle'); @@ -376,6 +742,14 @@ INSERT INTO txt VALUES ('no_rules_gtw', 'German', 'Anzahl Regeln pro Gatew INSERT INTO txt VALUES ('no_rules_gtw', 'English', 'Number of Rules per Gateway'); INSERT INTO txt VALUES ('negated', 'German', 'nicht'); INSERT INTO txt VALUES ('negated', 'English', 'not'); +INSERT INTO txt VALUES ('network_object_deleted','German', 'Netzwerkobjekt gelöscht'); +INSERT INTO txt VALUES ('network_object_deleted','English', 'Network Object deleted'); +INSERT INTO txt VALUES ('network_object_added', 'German', 'Netzwerkobjekt hinzugefügt'); +INSERT INTO txt VALUES ('network_object_added', 'English', 'Network Object added'); +INSERT INTO txt VALUES ('network_object_modified','German', 'Netzwerkobjekt modifiziert'); +INSERT INTO txt VALUES ('network_object_modified','English','Network Object modified'); +INSERT INTO txt VALUES ('network_object', 'German', 'Netzwerkobjekt'); +INSERT INTO txt VALUES ('network_object', 'English', 'Network Object'); INSERT INTO txt VALUES ('network_objects', 'German', 'Netzwerkobjekte'); INSERT INTO txt VALUES ('network_objects', 'English', 'Network Objects'); INSERT INTO txt VALUES ('network_services', 'German', 'Netzwerkdienste'); @@ -386,8 +760,16 @@ INSERT INTO txt VALUES ('user_objects', 'German', 'Nutzerobjekte'); INSERT INTO txt VALUES ('user_objects', 'English', 'User objects'); INSERT INTO txt VALUES ('rules', 'German', 'Regeln'); INSERT INTO txt VALUES ('rules', 'English', 'Rules'); +INSERT INTO txt VALUES ('unused_rules', 'German', 'Unbenutze Regeln'); +INSERT INTO txt VALUES ('unused_rules', 'English', 'Unused Rules'); INSERT INTO txt VALUES ('changes', 'German', 'Änderungen'); INSERT INTO txt VALUES ('changes', 'English', 'Changes'); +INSERT INTO txt VALUES ('used_objects', 'German', 'Benutzte Objekte'); +INSERT INTO txt VALUES ('used_objects', 'English', 'Used Objects'); +INSERT INTO txt VALUES ('unused_objects', 'German', 'Unbenutzte Objekte'); +INSERT INTO txt VALUES ('unused_objects', 'English', 'Unused Objects'); +INSERT INTO txt VALUES ('modelled_objects', 'German', 'Modellierte Objekte'); +INSERT INTO txt VALUES ('modelled_objects', 'English', 'Modelled Objects'); INSERT INTO txt VALUES ('rule_deleted', 'German', 'Regel gelöscht'); INSERT INTO txt VALUES ('rule_deleted', 'English', 'Rule deleted'); INSERT INTO txt VALUES ('rule_added', 'German', 'Regel hinzugefügt'); @@ -406,12 +788,16 @@ INSERT INTO txt VALUES ('expand_all', 'German', 'Alles ausklappen'); INSERT INTO txt VALUES ('expand_all', 'English', 'Expand all'); INSERT INTO txt VALUES ('all', 'German', 'Alle'); INSERT INTO txt VALUES ('all', 'English', 'All'); +INSERT INTO txt VALUES ('all_open', 'German', 'Alle offenen'); +INSERT INTO txt VALUES ('all_open', 'English', 'All open'); INSERT INTO txt VALUES ('rule', 'German', 'Regel'); INSERT INTO txt VALUES ('rule', 'English', 'Rule'); INSERT INTO txt VALUES ('objects', 'German', 'Objekte'); INSERT INTO txt VALUES ('objects', 'English', 'Objects'); INSERT INTO txt VALUES ('report_duration', 'German', 'Report-Generierung in'); INSERT INTO txt VALUES ('report_duration', 'English', 'Report generation took'); +INSERT INTO txt VALUES ('report_elements', 'German', 'Ausgewertete Elemente'); +INSERT INTO txt VALUES ('report_elements', 'English', 'Evaluated elements'); INSERT INTO txt VALUES ('seconds', 'German', 'Sekunden'); INSERT INTO txt VALUES ('seconds', 'English', 'seconds'); INSERT INTO txt VALUES ('minutes', 'German', 'Minuten'); @@ -426,8 +812,12 @@ INSERT INTO txt VALUES ('destination_zone', 'German', 'Zielzone'); INSERT INTO txt VALUES ('destination_zone', 'English', 'Destination Zone'); INSERT INTO txt VALUES ('enabled', 'German', 'Aktiviert'); INSERT INTO txt VALUES ('enabled', 'English', 'Enabled'); +INSERT INTO txt VALUES ('install_on', 'German', 'Installiere auf'); +INSERT INTO txt VALUES ('install_on', 'English', 'Install On'); INSERT INTO txt VALUES ('uid', 'German', 'UID'); INSERT INTO txt VALUES ('uid', 'English', 'UID'); +INSERT INTO txt VALUES ('change_id', 'German', 'Änderungs-ID'); +INSERT INTO txt VALUES ('change_id', 'English', 'Change-ID'); INSERT INTO txt VALUES ('created', 'German', 'Angelegt'); INSERT INTO txt VALUES ('created', 'English', 'Created'); INSERT INTO txt VALUES ('last_modified', 'German', 'Zuletzt geändert'); @@ -484,6 +874,52 @@ INSERT INTO txt VALUES ('delete_unused_rule', 'German', 'Unbenutzte Regel l&oum INSERT INTO txt VALUES ('delete_unused_rule', 'English', 'Delete unused rule'); INSERT INTO txt VALUES ('delete_unused_rules', 'German', 'Unbenutzte Regeln löschen'); INSERT INTO txt VALUES ('delete_unused_rules', 'English', 'Delete unused rules'); +INSERT INTO txt VALUES ('network', 'German', 'Netzwerk'); +INSERT INTO txt VALUES ('network', 'English', 'network'); +INSERT INTO txt VALUES ('ip_range', 'German', 'Ip-Bereich'); +INSERT INTO txt VALUES ('ip_range', 'English', 'Ip Range'); +INSERT INTO txt VALUES ('simple', 'German', 'Einfach'); +INSERT INTO txt VALUES ('simple', 'English', 'Simple'); +INSERT INTO txt VALUES ('rpc', 'German', 'Rpc'); +INSERT INTO txt VALUES ('rpc', 'English', 'Rpc'); +INSERT INTO txt VALUES ('more', 'German', 'weitere'); +INSERT INTO txt VALUES ('more', 'English', 'more'); +INSERT INTO txt VALUES ('connections_not_implemented','German', 'Nicht implementierte Verbindungen'); +INSERT INTO txt VALUES ('connections_not_implemented','English','Connections not implemented'); +INSERT INTO txt VALUES ('connections_with_diffs','German', 'Verbindungen mit Abweichungen'); +INSERT INTO txt VALUES ('connections_with_diffs','English', 'Connections with differences'); +INSERT INTO txt VALUES ('rules_not_modelled', 'German', 'Nicht modellierte Regeln'); +INSERT INTO txt VALUES ('rules_not_modelled', 'English', 'Rules not modelled'); +INSERT INTO txt VALUES ('app_roles_not_implemented','German','Nicht implementierte App Rollen'); +INSERT INTO txt VALUES ('app_roles_not_implemented','English','App Roles not implemented'); +INSERT INTO txt VALUES ('app_roles_with_diffs', 'German', 'App Rollen mit Abweichungen'); +INSERT INTO txt VALUES ('app_roles_with_diffs', 'English', 'App Roles with difference'); +INSERT INTO txt VALUES ('remaining_rules', 'German', 'Verbleibende Regeln'); +INSERT INTO txt VALUES ('remaining_rules', 'English', 'Remaining rules'); +INSERT INTO txt VALUES ('implemented', 'German', 'Implementiert'); +INSERT INTO txt VALUES ('implemented', 'English', 'Implemented'); +INSERT INTO txt VALUES ('not_implemented', 'German', 'Nicht Implementiert'); +INSERT INTO txt VALUES ('not_implemented', 'English', 'Not Implemented'); +INSERT INTO txt VALUES ('with_diffs', 'German', 'Mit Abweichungen'); +INSERT INTO txt VALUES ('with_diffs', 'English', 'With Differences'); +INSERT INTO txt VALUES ('missing_app_servers', 'German', 'Fehlende App Server auf Device'); +INSERT INTO txt VALUES ('missing_app_servers', 'English', 'Missing App Servers on Device'); +INSERT INTO txt VALUES ('surplus_app_servers', 'German', 'Überschüssige App Server auf Device'); +INSERT INTO txt VALUES ('surplus_app_servers', 'English', 'Surplus App Servers on Device'); +INSERT INTO txt VALUES ('missing_objects', 'German', 'Fehlende Objekte auf Device'); +INSERT INTO txt VALUES ('missing_objects', 'English', 'Missing Objects on Device'); +INSERT INTO txt VALUES ('fully_modelled', 'German', 'Vollständig Modelliert'); +INSERT INTO txt VALUES ('fully_modelled', 'English', 'Fully Modelled'); +INSERT INTO txt VALUES ('show_all_owners', 'German', 'Alle Eigentümer mit aktiver Rezertifizierung'); +INSERT INTO txt VALUES ('show_all_owners', 'English', 'All owners with active recertification'); +INSERT INTO txt VALUES ('show_inactive_recert_owners', 'German', 'Eigentümer ohne aktive Rezertifizierung'); +INSERT INTO txt VALUES ('show_inactive_recert_owners', 'English', 'Owners with inactive recertification'); +INSERT INTO txt VALUES ('recert_activated', 'German', 'Rezertifizierung aktiviert'); +INSERT INTO txt VALUES ('recert_activated', 'English', 'Recertification activated'); +INSERT INTO txt VALUES ('no_recerts', 'German', 'keine Rezertifizierung vorhanden'); +INSERT INTO txt VALUES ('no_recerts', 'English', 'No recertification available'); +INSERT INTO txt VALUES ('diff_interval', 'German', 'Differenz-Intervall'); +INSERT INTO txt VALUES ('diff_interval', 'English', 'Diff interval'); -- schedule INSERT INTO txt VALUES ('schedule', 'German', 'Terminplan'); @@ -494,10 +930,12 @@ INSERT INTO txt VALUES ('repeat_interval', 'German', 'Wiederholungsintervall') INSERT INTO txt VALUES ('repeat_interval', 'English', 'Repeat Interval'); INSERT INTO txt VALUES ('template', 'German', 'Vorlage'); INSERT INTO txt VALUES ('template', 'English', 'Template'); -INSERT INTO txt VALUES ('owner', 'German', 'Eigentümer'); -INSERT INTO txt VALUES ('owner', 'English', 'Owner'); +INSERT INTO txt VALUES ('schedule_owner', 'German', 'Eigentümer'); +INSERT INTO txt VALUES ('schedule_owner', 'English', 'Owner'); INSERT INTO txt VALUES ('active', 'German', 'Aktiv'); INSERT INTO txt VALUES ('active', 'English', 'Active'); +INSERT INTO txt VALUES ('inactive', 'German', 'Inaktiv'); +INSERT INTO txt VALUES ('inactive', 'English', 'Inactive'); INSERT INTO txt VALUES ('count', 'German', 'Zähler'); INSERT INTO txt VALUES ('count', 'English', 'Count'); INSERT INTO txt VALUES ('output_format', 'German', 'Ausgabeformat'); @@ -566,6 +1004,8 @@ INSERT INTO txt VALUES ('all_readonly', 'German', 'Alle Anträge (nur INSERT INTO txt VALUES ('all_readonly', 'English', 'All tickets (read only)'); INSERT INTO txt VALUES ('task', 'German', 'Aufgabe'); INSERT INTO txt VALUES ('task', 'English', 'Task'); +INSERT INTO txt VALUES ('task_number', 'German', 'Aufgabennummer'); +INSERT INTO txt VALUES ('task_number', 'English', 'Task Number'); INSERT INTO txt VALUES ('element', 'German', 'Element'); INSERT INTO txt VALUES ('element', 'English', 'Element'); INSERT INTO txt VALUES ('reason', 'German', 'Grund'); @@ -618,6 +1058,8 @@ INSERT INTO txt VALUES ('delete_element', 'German', 'Element löschen INSERT INTO txt VALUES ('delete_element', 'English', 'Delete element'); INSERT INTO txt VALUES ('requester', 'German', 'Antragsteller'); INSERT INTO txt VALUES ('requester', 'English', 'Requester'); +INSERT INTO txt VALUES ('save_promote', 'German', 'Speichern + Status ändern'); +INSERT INTO txt VALUES ('save_promote', 'English', 'Save + Promote'); INSERT INTO txt VALUES ('promote', 'German', 'Status ändern'); INSERT INTO txt VALUES ('promote', 'English', 'Promote'); INSERT INTO txt VALUES ('promote_to', 'German', 'Status ändern'); @@ -696,6 +1138,8 @@ INSERT INTO txt VALUES ('assign_to', 'German', 'Weiterleiten an'); INSERT INTO txt VALUES ('assign_to', 'English', 'Assign to'); INSERT INTO txt VALUES ('assign_group', 'German', 'Gruppe zuweisen'); INSERT INTO txt VALUES ('assign_group', 'English', 'Assign group'); +INSERT INTO txt VALUES ('assign_owner', 'German', 'Eigentümer zuweisen'); +INSERT INTO txt VALUES ('assign_owner', 'English', 'Assign Owner'); INSERT INTO txt VALUES ('assigned', 'German', 'Zugewiesen'); INSERT INTO txt VALUES ('assigned', 'English', 'Assigned'); INSERT INTO txt VALUES ('back_to', 'German', 'Zurück zu'); @@ -716,6 +1160,8 @@ INSERT INTO txt VALUES ('all_gateways', 'German', 'Alle Gateways'); INSERT INTO txt VALUES ('all_gateways', 'English', 'All Gateways'); INSERT INTO txt VALUES ('insert_ip', 'German', 'IP einfügen'); INSERT INTO txt VALUES ('insert_ip', 'English', 'Insert IP'); +INSERT INTO txt VALUES ('insert_port', 'German', 'Port einfügen'); +INSERT INTO txt VALUES ('insert_port', 'English', 'Insert port'); INSERT INTO txt VALUES ('state_actions', 'German', 'Statusaktionen'); INSERT INTO txt VALUES ('state_actions', 'English', 'State Actions'); INSERT INTO txt VALUES ('add_action', 'German', 'Aktion hinzufügen'); @@ -732,8 +1178,16 @@ INSERT INTO txt VALUES ('event', 'German', 'Ereignis'); INSERT INTO txt VALUES ('event', 'English', 'Event'); INSERT INTO txt VALUES ('phase', 'German', 'Phase'); INSERT INTO txt VALUES ('phase', 'English', 'Phase'); +INSERT INTO txt VALUES ('reference_date', 'German', 'Bezugsdatum'); +INSERT INTO txt VALUES ('reference_date', 'English', 'Reference date'); INSERT INTO txt VALUES ('task_type', 'German', 'Tasktyp'); INSERT INTO txt VALUES ('task_type', 'English', 'Task type'); +INSERT INTO txt VALUES ('not_existing', 'German', 'Nicht vorhanden'); +INSERT INTO txt VALUES ('not_existing', 'English', 'Not existing'); +INSERT INTO txt VALUES ('existing', 'German', 'Vorhanden'); +INSERT INTO txt VALUES ('existing', 'English', 'Existing'); +INSERT INTO txt VALUES ('value', 'German', 'Wert'); +INSERT INTO txt VALUES ('value', 'English', 'Value'); INSERT INTO txt VALUES ('action_type', 'German', 'Aktionstyp'); INSERT INTO txt VALUES ('action_type', 'English', 'Action type'); INSERT INTO txt VALUES ('external_params', 'German', 'Externe Parameter'); @@ -744,6 +1198,18 @@ INSERT INTO txt VALUES ('to_state', 'German', 'Zielstatus'); INSERT INTO txt VALUES ('to_state', 'English', 'to State'); INSERT INTO txt VALUES ('automatic', 'German', 'Automatisch'); INSERT INTO txt VALUES ('automatic', 'English', 'Automatic'); +INSERT INTO txt VALUES ('Conditional', 'German', 'Bedingt'); +INSERT INTO txt VALUES ('Conditional', 'English', 'Conditional'); +INSERT INTO txt VALUES ('to_be_called', 'German', 'Aufzurufen'); +INSERT INTO txt VALUES ('to_be_called', 'English', 'To be called'); +INSERT INTO txt VALUES ('ifCompliantState', 'German', 'Falls konform Status'); +INSERT INTO txt VALUES ('ifCompliantState', 'English', 'If compliant state'); +INSERT INTO txt VALUES ('ifNotCompliantState', 'German', 'Falls nicht konform Status'); +INSERT INTO txt VALUES ('ifNotCompliantState', 'English', 'If not compliant state'); +INSERT INTO txt VALUES ('checkResultLabel', 'German', 'Prüfergebnis-Label'); +INSERT INTO txt VALUES ('checkResultLabel', 'English', 'Check result label'); +INSERT INTO txt VALUES ('PolicyCheck', 'German', 'Policy-Prüfung'); +INSERT INTO txt VALUES ('PolicyCheck', 'English', 'Policy Check'); INSERT INTO txt VALUES ('free_text', 'German', 'Freitext'); INSERT INTO txt VALUES ('free_text', 'English', 'Free Text'); INSERT INTO txt VALUES ('back_to_ticket', 'German', 'Zurück zum Ticket'); @@ -758,100 +1224,22 @@ INSERT INTO txt VALUES ('button_text', 'German', 'Schaltertext'); INSERT INTO txt VALUES ('button_text', 'English', 'Button Text'); INSERT INTO txt VALUES ('path_analysis', 'German', 'Pfadanalyse'); INSERT INTO txt VALUES ('path_analysis', 'English', 'Path analysis'); - --- enum values -INSERT INTO txt VALUES ('master', 'German', 'Master'); -INSERT INTO txt VALUES ('master', 'English', 'Master'); -INSERT INTO txt VALUES ('access', 'German', 'Zugriff'); -INSERT INTO txt VALUES ('access', 'English', 'Access'); -INSERT INTO txt VALUES ('generic', 'German', 'Generisch'); -INSERT INTO txt VALUES ('generic', 'English', 'Generic'); -INSERT INTO txt VALUES ('rule_modify', 'German', 'Regel ändern'); -INSERT INTO txt VALUES ('rule_modify', 'English', 'Modify Rule'); -INSERT INTO txt VALUES ('rule_delete', 'German', 'Regel löschen'); -INSERT INTO txt VALUES ('rule_delete', 'English', 'Delete Rule'); -INSERT INTO txt VALUES ('group_create', 'German', 'Gruppe anlegen'); -INSERT INTO txt VALUES ('group_create', 'English', 'Create Group'); -INSERT INTO txt VALUES ('group_modify', 'German', 'Gruppe ändern'); -INSERT INTO txt VALUES ('group_modify', 'English', 'Modify Group'); -INSERT INTO txt VALUES ('group_delete', 'German', 'Gruppe löschen'); -INSERT INTO txt VALUES ('group_delete', 'English', 'Delete Group'); -INSERT INTO txt VALUES ('None', 'German', 'Keine(r/s)'); -INSERT INTO txt VALUES ('None', 'English', 'None'); -INSERT INTO txt VALUES ('OnSet', 'German', 'Beim Erreichen'); -INSERT INTO txt VALUES ('OnSet', 'English', 'On set'); -INSERT INTO txt VALUES ('OnLeave', 'German', 'Beim Verlassen'); -INSERT INTO txt VALUES ('OnLeave', 'English', 'On leave'); -INSERT INTO txt VALUES ('OfferButton', 'German', 'Schaltfläche anbieten'); -INSERT INTO txt VALUES ('OfferButton', 'English', 'Offer button'); -INSERT INTO txt VALUES ('DoNothing', 'German', 'Keine Aktion'); -INSERT INTO txt VALUES ('DoNothing', 'English', 'Do Nothing'); -INSERT INTO txt VALUES ('AutoPromote', 'German', 'Autom. Weiterleitung'); -INSERT INTO txt VALUES ('AutoPromote', 'English', 'Auto-forward'); -INSERT INTO txt VALUES ('AddApproval', 'German', 'Genehmigung hinzufügen'); -INSERT INTO txt VALUES ('AddApproval', 'English', 'Add approval'); -INSERT INTO txt VALUES ('SetAlert', 'German', 'Alarm auslösen'); -INSERT INTO txt VALUES ('SetAlert', 'English', 'Set alert'); -INSERT INTO txt VALUES ('TrafficPathAnalysis', 'German', 'Pfadanalyse'); -INSERT INTO txt VALUES ('TrafficPathAnalysis', 'English', 'Path Analysis'); -INSERT INTO txt VALUES ('ExternalCall', 'German', 'Externer Aufruf'); -INSERT INTO txt VALUES ('ExternalCall', 'English', 'External call'); -INSERT INTO txt VALUES ('Ticket', 'German', 'Ticket'); -INSERT INTO txt VALUES ('Ticket', 'English', 'Ticket'); -INSERT INTO txt VALUES ('RequestTask', 'German', 'fachlicher Auftrag'); -INSERT INTO txt VALUES ('RequestTask', 'English', 'Request Task'); -INSERT INTO txt VALUES ('ImplementationTask', 'German', 'Implementierungs-Auftrag'); -INSERT INTO txt VALUES ('ImplementationTask', 'English', 'Implementation Task'); -INSERT INTO txt VALUES ('Approval', 'German', 'Genehmigung'); -INSERT INTO txt VALUES ('Approval', 'English', 'Approval'); -INSERT INTO txt VALUES ('never', 'German', 'Niemals'); -INSERT INTO txt VALUES ('never', 'English', 'Never'); -INSERT INTO txt VALUES ('onlyForOneDevice', 'German', 'Nur eines wenn Gerät vorhanden'); -INSERT INTO txt VALUES ('onlyForOneDevice', 'English', 'Only one if device available'); -INSERT INTO txt VALUES ('forEachDevice', 'German', 'Für jedes Gerät'); -INSERT INTO txt VALUES ('forEachDevice', 'English', 'For each device'); -INSERT INTO txt VALUES ('enterInReqTask', 'German', 'Gerät im Antrag eingeben'); -INSERT INTO txt VALUES ('enterInReqTask', 'English', 'Enter device in request'); -INSERT INTO txt VALUES ('afterPathAnalysis', 'German', 'Nach Pfadanalyse'); -INSERT INTO txt VALUES ('afterPathAnalysis', 'English', 'After path analysis'); -INSERT INTO txt VALUES ('WriteToDeviceList', 'German', 'In Geräteliste eintragen'); -INSERT INTO txt VALUES ('WriteToDeviceList', 'English', 'Write to device list'); -INSERT INTO txt VALUES ('DisplayFoundDevices', 'German', 'Gefundene Geräte darstellen'); -INSERT INTO txt VALUES ('DisplayFoundDevices', 'English', 'Display found devices'); -INSERT INTO txt VALUES ('Sunday', 'German', 'Sonntag'); -INSERT INTO txt VALUES ('Sunday', 'English', 'Sunday'); -INSERT INTO txt VALUES ('Monday', 'German', 'Montag'); -INSERT INTO txt VALUES ('Monday', 'English', 'Monday'); -INSERT INTO txt VALUES ('Tuesday', 'German', 'Dienstag'); -INSERT INTO txt VALUES ('Tuesday', 'English', 'Tuesday'); -INSERT INTO txt VALUES ('Wednesday', 'German', 'Mittwoch'); -INSERT INTO txt VALUES ('Wednesday', 'English', 'Wednesday'); -INSERT INTO txt VALUES ('Thursday', 'German', 'Donnerstag'); -INSERT INTO txt VALUES ('Thursday', 'English', 'Thursday'); -INSERT INTO txt VALUES ('Friday', 'German', 'Freitag'); -INSERT INTO txt VALUES ('Friday', 'English', 'Friday'); -INSERT INTO txt VALUES ('Saturday', 'German', 'Samstag'); -INSERT INTO txt VALUES ('Saturday', 'English', 'Saturday'); -INSERT INTO txt VALUES ('Rules', 'German', 'Regel-Report'); -INSERT INTO txt VALUES ('Rules', 'English', 'Rules Report'); -INSERT INTO txt VALUES ('Changes', 'German', 'Changes-Report'); -INSERT INTO txt VALUES ('Changes', 'English', 'Changes Report'); -INSERT INTO txt VALUES ('Statistics', 'German', 'Statistik-Report'); -INSERT INTO txt VALUES ('Statistics', 'English', 'Statistics Report'); -INSERT INTO txt VALUES ('NatRules', 'German', 'NAT-Regel-Report'); -INSERT INTO txt VALUES ('NatRules', 'English', 'NAT Rules Report'); -INSERT INTO txt VALUES ('ResolvedRules', 'German', 'Regel-Report (aufgelöst)'); -INSERT INTO txt VALUES ('ResolvedRules', 'English', 'Rules Report (resolved)'); -INSERT INTO txt VALUES ('ResolvedRulesTech', 'German', 'Regel-Report (technisch)'); -INSERT INTO txt VALUES ('ResolvedRulesTech', 'English', 'Rules Report (technical)'); -INSERT INTO txt VALUES ('Recertification', 'German', 'Rezertifizierungs-Report'); -INSERT INTO txt VALUES ('Recertification', 'English', 'Recertification Report'); -INSERT INTO txt VALUES ('ResolvedChanges', 'German', 'Changes-Report (aufgelöst)'); -INSERT INTO txt VALUES ('ResolvedChanges', 'English', 'Changes Report (resolved)'); -INSERT INTO txt VALUES ('ResolvedChangesTech', 'German', 'Changes-Report (technisch)'); -INSERT INTO txt VALUES ('ResolvedChangesTech', 'English', 'Changes Report (technical)'); -INSERT INTO txt VALUES ('UnusedRules', 'German', 'Unbenutzte-Regel-Report'); -INSERT INTO txt VALUES ('UnusedRules', 'English', 'Unused Rules Report'); +INSERT INTO txt VALUES ('all_my_owners', 'German', 'Alle meine Eigentümer'); +INSERT INTO txt VALUES ('all_my_owners', 'English', 'All my owners'); +INSERT INTO txt VALUES ('assigned_to_me', 'German', 'Mir zugeordnet'); +INSERT INTO txt VALUES ('assigned_to_me', 'English', 'Assigned to me'); +INSERT INTO txt VALUES ('select_owner', 'German', 'Eigentümer auswählen'); +INSERT INTO txt VALUES ('select_owner', 'English', 'Select Owner'); +INSERT INTO txt VALUES ('ticket_id', 'German', 'Ticket-Id'); +INSERT INTO txt VALUES ('ticket_id', 'English', 'Ticket Id'); +INSERT INTO txt VALUES ('requesting_owner', 'German', 'Beantragender Eigentümer'); +INSERT INTO txt VALUES ('requesting_owner', 'English', 'Requesting Owner'); +INSERT INTO txt VALUES ('port_range', 'German', 'Port(bereich)'); +INSERT INTO txt VALUES ('port_range', 'English', 'Port (range)'); +INSERT INTO txt VALUES ('network_group', 'German', 'Netzwerkgruppe'); +INSERT INTO txt VALUES ('network_group', 'English', 'Network Group'); +INSERT INTO txt VALUES ('service_group', 'German', 'Servicegruppe'); +INSERT INTO txt VALUES ('service_group', 'English', 'Service Group'); -- network analysis INSERT INTO txt VALUES ('network_analysis', 'German', 'Netzanalyse'); @@ -882,12 +1270,20 @@ INSERT INTO txt VALUES ('load_rules', 'German', 'Regeln anzeigen'); INSERT INTO txt VALUES ('load_rules', 'English', 'Show Rules'); INSERT INTO txt VALUES ('execute_selected', 'German', 'Ausgewählte Aktionen ausführen'); INSERT INTO txt VALUES ('execute_selected', 'English', 'Execute Selected Actions'); +INSERT INTO txt VALUES ('no_recertifiable_owners_assigned', 'German', 'Keine rezertifizierbaren Eigentümer zugewiesen.'); +INSERT INTO txt VALUES ('no_recertifiable_owners_assigned', 'English', 'No recertifiable owners assigned.'); +INSERT INTO txt VALUES ('recert_action_unavailable_hint', 'German', 'Wenn Regeln sichtbar sind, aber keine Rezertifizierungs-Aktion angezeigt wird, sind dem Benutzer aktuell keine rezertifizierbaren Eigentümer zugewiesen.'); +INSERT INTO txt VALUES ('recert_action_unavailable_hint', 'English', 'If rules are visible but no recertification action is shown, no recertifiable owners are currently assigned to the user.'); INSERT INTO txt VALUES ('missing_owner_id', 'German', 'Fehlende Eigentümer ID'); INSERT INTO txt VALUES ('missing_owner_id', 'English', 'missing owner id'); -INSERT INTO txt VALUES ('next_recert', 'German', 'Datum nächste Rezertifizierung'); -INSERT INTO txt VALUES ('next_recert', 'English', 'Next Recertification Date'); +INSERT INTO txt VALUES ('next_recert_date', 'German', 'Datum nächste Rezertifizierung'); +INSERT INTO txt VALUES ('next_recert_date', 'English', 'Next Recertification Date'); INSERT INTO txt VALUES ('last_recertifier', 'German', 'Letzter Rezertifizierer'); -INSERT INTO txt VALUES ('last_recertifier', 'English', 'Last Recertifier Name'); +INSERT INTO txt VALUES ('last_recertifier', 'English', 'Last Recertifier'); +INSERT INTO txt VALUES ('last_recertified', 'German', 'Letzte Rezertifizierung'); +INSERT INTO txt VALUES ('last_recertified', 'English', 'Last Recertification'); +INSERT INTO txt VALUES ('next_recertification', 'German', 'Nächste Rezertifizierung'); +INSERT INTO txt VALUES ('next_recertification', 'English', 'Next Recertification'); INSERT INTO txt VALUES ('unknown', 'German', '(unbekannt)'); INSERT INTO txt VALUES ('unknown', 'English', '(unknown)'); INSERT INTO txt VALUES ('recerts_executed', 'German', 'Durchgeführte Rezertifizierungen: '); @@ -904,6 +1300,8 @@ INSERT INTO txt VALUES ('recert_history', 'German', 'Rezertifizierungshi INSERT INTO txt VALUES ('recert_history', 'English', 'Recertification history'); INSERT INTO txt VALUES ('recertified_by', 'German', 'rezertifiziert von'); INSERT INTO txt VALUES ('recertified_by', 'English', 'recertified by'); +INSERT INTO txt VALUES ('by', 'German', 'durch'); +INSERT INTO txt VALUES ('by', 'English', 'by'); INSERT INTO txt VALUES ('decertified_by', 'German', 'dezertifiziert von'); INSERT INTO txt VALUES ('decertified_by', 'English', 'decertified by'); INSERT INTO txt VALUES ('as_owner', 'German', 'als Eigentümer'); @@ -932,6 +1330,697 @@ INSERT INTO txt VALUES ('at_startup', 'German', 'Beim Hochfahren'); INSERT INTO txt VALUES ('at_startup', 'English', 'At startup'); INSERT INTO txt VALUES ('daily', 'German', 'Täglich'); INSERT INTO txt VALUES ('daily', 'English', 'Daily'); +INSERT INTO txt VALUES ('recertificationMode', 'German', 'Rezertifizierungsmodus'); +INSERT INTO txt VALUES ('recertificationMode', 'English', 'Recertification Mode'); +INSERT INTO txt VALUES ('email_address', 'German', 'Email-Adresse'); +INSERT INTO txt VALUES ('email_address', 'English', 'Email address'); +INSERT INTO txt VALUES ('channel', 'German', 'Kanal'); +INSERT INTO txt VALUES ('channel', 'English', 'Channel'); +INSERT INTO txt VALUES ('layout', 'German', 'Layout'); +INSERT INTO txt VALUES ('layout', 'English', 'Layout'); +INSERT INTO txt VALUES ('notif_before_deadline','German', 'Benachrichtigungen vor Termin'); +INSERT INTO txt VALUES ('notif_before_deadline','English', 'Notifications before Deadline'); +INSERT INTO txt VALUES ('notif_after_deadline', 'German', 'Benachrichtigungen nach Termin'); +INSERT INTO txt VALUES ('notif_after_deadline', 'English', 'Notifications after Deadline'); +INSERT INTO txt VALUES ('initial_offset', 'German', 'Initialer Offset'); +INSERT INTO txt VALUES ('initial_offset', 'English', 'Initial Offset'); +INSERT INTO txt VALUES ('max_number', 'German', 'Maximale Anzahl'); +INSERT INTO txt VALUES ('max_number', 'English', 'Max Number'); +INSERT INTO txt VALUES ('recipient_to', 'German', 'Empfänger (To)'); +INSERT INTO txt VALUES ('recipient_to', 'English', 'Recipient (To)'); +INSERT INTO txt VALUES ('recipient_cc', 'German', 'Empfänger (Cc)'); +INSERT INTO txt VALUES ('recipient_cc', 'English', 'Recipient (Cc)'); +INSERT INTO txt VALUES ('recertification_ok', 'German', 'Rezertifizierung Ok'); +INSERT INTO txt VALUES ('recertification_ok', 'English', 'Recertification Ok'); +INSERT INTO txt VALUES ('recertification_error','German', 'Rezertifizierungsfehler'); +INSERT INTO txt VALUES ('recertification_error','English', 'Recertification Error'); +INSERT INTO txt VALUES ('recertified_rules', 'German', 'Rezertifizierte Regeln'); +INSERT INTO txt VALUES ('recertified_rules', 'English', 'Recertified rules'); + +-- network modelling +INSERT INTO txt VALUES ('network_modelling', 'German', 'Netzwerkmodellierung'); +INSERT INTO txt VALUES ('network_modelling', 'English', 'Network Modelling'); +INSERT INTO txt VALUES ('modelling', 'German', 'Modellierung'); +INSERT INTO txt VALUES ('modelling', 'English', 'Modelling'); +INSERT INTO txt VALUES ('application', 'German', 'Applikation'); +INSERT INTO txt VALUES ('application', 'English', 'Application'); +INSERT INTO txt VALUES ('applications', 'German', 'Applikationen'); +INSERT INTO txt VALUES ('applications', 'English', 'Applications'); +INSERT INTO txt VALUES ('library', 'German', 'Bibliothek'); +INSERT INTO txt VALUES ('library', 'English', 'Library'); +INSERT INTO txt VALUES ('app_server', 'German', 'App Server'); +INSERT INTO txt VALUES ('app_server', 'English', 'App Server'); +INSERT INTO txt VALUES ('app_servers', 'German', 'App Server'); +INSERT INTO txt VALUES ('app_servers', 'English', 'App Servers'); +INSERT INTO txt VALUES ('app_role', 'German', 'App Rolle'); +INSERT INTO txt VALUES ('app_role', 'English', 'App Role'); +INSERT INTO txt VALUES ('app_roles', 'German', 'App Rollen'); +INSERT INTO txt VALUES ('app_roles', 'English', 'App Roles'); +INSERT INTO txt VALUES ('preview', 'German', 'Vorschau'); +INSERT INTO txt VALUES ('preview', 'English', 'Preview'); +INSERT INTO txt VALUES ('comm_profile', 'German', 'Kommunikationsprofil'); +INSERT INTO txt VALUES ('comm_profile', 'English', 'Communication Profile'); +INSERT INTO txt VALUES ('connection', 'German', 'Verbindung'); +INSERT INTO txt VALUES ('connection', 'English', 'Connection'); +INSERT INTO txt VALUES ('connections', 'German', 'Verbindungen'); +INSERT INTO txt VALUES ('connections', 'English', 'Connections'); +INSERT INTO txt VALUES ('add_connection', 'German', 'Verbindung hinzufügen'); +INSERT INTO txt VALUES ('add_connection', 'English', 'Add Connection'); +INSERT INTO txt VALUES ('edit_connection', 'German', 'Verbindung bearbeiten'); +INSERT INTO txt VALUES ('edit_connection', 'English', 'Edit Connection'); +INSERT INTO txt VALUES ('save_connection', 'German', 'Verbindung speichern'); +INSERT INTO txt VALUES ('save_connection', 'English', 'Save Connection'); +INSERT INTO txt VALUES ('delete_connection', 'German', 'Verbindung löschen'); +INSERT INTO txt VALUES ('delete_connection', 'English', 'Delete Connection'); +INSERT INTO txt VALUES ('remove_connection', 'German', 'Verbindung entfernen'); +INSERT INTO txt VALUES ('remove_connection', 'English', 'Remove Connection'); +INSERT INTO txt VALUES ('displayRejected', 'German', 'Abgelehnte anzeigen'); +INSERT INTO txt VALUES ('displayRejected', 'English', 'Display rejected'); +INSERT INTO txt VALUES ('add_interface', 'German', 'Schnittstelle hinzufügen'); +INSERT INTO txt VALUES ('add_interface', 'English', 'Add Interface'); +INSERT INTO txt VALUES ('edit_interface', 'German', 'Schnittstelle bearbeiten'); +INSERT INTO txt VALUES ('edit_interface', 'English', 'Edit Interface'); +INSERT INTO txt VALUES ('delete_interface', 'German', 'Schnittstelle löschen'); +INSERT INTO txt VALUES ('delete_interface', 'English', 'Delete Interface'); +INSERT INTO txt VALUES ('propose_alternative', 'German', 'Alternative vorschlagen'); +INSERT INTO txt VALUES ('propose_alternative', 'English', 'Propose alternative'); +INSERT INTO txt VALUES ('insert_forbidden', 'German', 'Einfügen verboten'); +INSERT INTO txt VALUES ('insert_forbidden', 'English', 'Insert forbidden'); +INSERT INTO txt VALUES ('func_reason', 'German', 'Fachliche Begründung'); +INSERT INTO txt VALUES ('func_reason', 'English', 'Functional Reason'); +INSERT INTO txt VALUES ('to_source', 'German', 'Zu Quelle'); +INSERT INTO txt VALUES ('to_source', 'English', 'To Source'); +INSERT INTO txt VALUES ('to_dest', 'German', 'Zu Ziel'); +INSERT INTO txt VALUES ('to_dest', 'English', 'To Destination'); +INSERT INTO txt VALUES ('to_service', 'German', 'Zu Dienst'); +INSERT INTO txt VALUES ('to_service', 'English', 'To Service'); +INSERT INTO txt VALUES ('data_inconsistent', 'German', 'Daten inkonsistent'); +INSERT INTO txt VALUES ('data_inconsistent', 'English', 'Data inconsistent'); +INSERT INTO txt VALUES ('add_app_role', 'German', 'Neue App Rolle'); +INSERT INTO txt VALUES ('add_app_role', 'English', 'New App Role'); +INSERT INTO txt VALUES ('edit_app_role', 'German', 'App Rolle bearbeiten'); +INSERT INTO txt VALUES ('edit_app_role', 'English', 'Edit App Role'); +INSERT INTO txt VALUES ('save_app_role', 'German', 'App Rolle speichern'); +INSERT INTO txt VALUES ('save_app_role', 'English', 'Save App Role'); +INSERT INTO txt VALUES ('delete_app_role', 'German', 'App Rolle löschen'); +INSERT INTO txt VALUES ('delete_app_role', 'English', 'Delete App Role'); +INSERT INTO txt VALUES ('display_app_role', 'German', 'App Rolle darstellen'); +INSERT INTO txt VALUES ('display_app_role', 'English', 'Display App Role'); +INSERT INTO txt VALUES ('to_app_role', 'German', 'Zu App Rolle'); +INSERT INTO txt VALUES ('to_app_role', 'English', 'To App Role'); +INSERT INTO txt VALUES ('display_app_server', 'German', 'App Server darstellen'); +INSERT INTO txt VALUES ('display_app_server', 'English', 'Display App Server'); +INSERT INTO txt VALUES ('add_service', 'German', 'Dienst hinzufügen'); +INSERT INTO txt VALUES ('add_service', 'English', 'Add Service'); +INSERT INTO txt VALUES ('edit_service', 'German', 'Dienst bearbeiten'); +INSERT INTO txt VALUES ('edit_service', 'English', 'Edit Service'); +INSERT INTO txt VALUES ('save_service', 'German', 'Dienst speichern'); +INSERT INTO txt VALUES ('save_service', 'English', 'Save Service'); +INSERT INTO txt VALUES ('delete_service', 'German', 'Dienst löschen'); +INSERT INTO txt VALUES ('delete_service', 'English', 'Delete Service'); +INSERT INTO txt VALUES ('ext_ticket_system_type','German', 'Typ des externen Ticketing Systems'); +INSERT INTO txt VALUES ('ext_ticket_system_type','English', 'Type of external ticketing system'); +INSERT INTO txt VALUES ('ext_ticket_url', 'German', 'URL des externen Ticketing Systems'); +INSERT INTO txt VALUES ('ext_ticket_url', 'English', 'URL of external ticketing system'); +INSERT INTO txt VALUES ('response_timeout', 'German', 'Antwort Timeout (Sekunden)'); +INSERT INTO txt VALUES ('response_timeout', 'English', 'Response Timeout (Seconds)'); +INSERT INTO txt VALUES ('max_attempts', 'German', 'Max Versuche'); +INSERT INTO txt VALUES ('max_attempts', 'English', 'Max Attempts'); +INSERT INTO txt VALUES ('cycles_between', 'German', 'Zyklen zwischen Versuchen'); +INSERT INTO txt VALUES ('cycles_between', 'English', 'Cycles between attempts'); +INSERT INTO txt VALUES ('ext_ticket_template', 'German', 'Template Ticket-Text'); +INSERT INTO txt VALUES ('ext_ticket_template', 'English', 'Template ticket text'); +INSERT INTO txt VALUES ('ext_task_template', 'German', 'Template Aufgabentext'); +INSERT INTO txt VALUES ('ext_task_template', 'English', 'Template task text'); +INSERT INTO txt VALUES ('ext_obj_template', 'German', 'Template Objekt (neu)'); +INSERT INTO txt VALUES ('ext_obj_template', 'English', 'Template object (new)'); +INSERT INTO txt VALUES ('ext_obj_short_template','German', 'Template Objekt kurz (Änderung)'); +INSERT INTO txt VALUES ('ext_obj_short_template','English', 'Template object short (modification)'); +INSERT INTO txt VALUES ('ext_ip_template', 'German', 'Template IP Adresse'); +INSERT INTO txt VALUES ('ext_ip_template', 'English', 'Template IP address'); +INSERT INTO txt VALUES ('ext_nwgroup_template', 'German', 'Template Netzwerkgruppe'); +INSERT INTO txt VALUES ('ext_nwgroup_template', 'English', 'Template network group'); +INSERT INTO txt VALUES ('ext_service_template', 'German', 'Template Dienst'); +INSERT INTO txt VALUES ('ext_service_template', 'English', 'Template service'); +INSERT INTO txt VALUES ('ext_icmp_template', 'German', 'Template ICMP'); +INSERT INTO txt VALUES ('ext_icmp_template', 'English', 'Template ICMP'); +INSERT INTO txt VALUES ('ext_ip_protocol_template','German','Template Ip-Protokoll'); +INSERT INTO txt VALUES ('ext_ip_protocol_template','English','Template Ip Protocol'); +INSERT INTO txt VALUES ('ext_ticket_template_ph','German', 'Ticket Template im JSON-Format, Bspw. für Tufin Secure Change: +{ + "ticket": { + "subject": "@@TICKET_SUBJECT@@", + "priority": "@@PRIORITY@@", + "requester": "@@ONBEHALF@@", + "domain_name": "", + "workflow": { + "name": "@@WORKFLOW_NAME@@" + }, + "steps": { + "step": [ + { + "name": "Erfassung des Antrags", + "tasks": { + "task": { + "fields": { + "field": [ + @@TASKS@@ + ] + } + } + } + } + ] + } + } +} +'); +INSERT INTO txt VALUES ('ext_ticket_template_ph','English', 'Ticket Template in JSON format, e. g. for Tufin Secure Change: +{ + "ticket": { + "subject": "@@TICKET_SUBJECT@@", + "priority": "@@PRIORITY@@", + "requester": "@@ONBEHALF@@", + "domain_name": "", + "workflow": { + "name": "@@WORKFLOW_NAME@@" + }, + "steps": { + "step": [ + { + "name": "Request creation", + "tasks": { + "task": { + "fields": { + "field": [ + @@TASKS@@ + ] + } + } + } + } + ] + } + } +}'); +INSERT INTO txt VALUES ('ext_task_template_ph', 'German', 'Template Text je Verbindung, für Tufin Secure Change etwa: + { + "@xsi.type": "multi_access_request", + "name": "Gewünschter Zugang", + "read_only": false, + "access_request": { + "order": "AR1", + "verifier_result": { + "status": "not run" + }, + "use_topology": true, + "targets": { + "target": { + "@type": "ANY" + } + }, + "users": { + "user": @@USERS@@ + }, + "sources": { + "source": @@SOURCES@@ + }, + "destinations": { + "destination": @@DESTINATIONS@@ + }, + "services": { + "service": @@SERVICES@@ + }, + "action": "@@ACTION@@", + "labels": "" + } + }, + { + "@xsi.type": "text_area", + "name": "Grund für den Antrag", + "read_only": false, + "text": "@@REASON@@" + }, + { + "@xsi.type": "drop_down_list", + "name": "Regel Log aktivieren?", + "selection": "@@LOGGING@@" + }, + { + "@xsi.type": "date", + "name": "Regel befristen bis:" + }, + { + "@xsi.type": "text_field", + "name": "Anwendungs-ID", + "text": "@@APPID@@" + }, + { + "@xsi.type": "checkbox", + "name": "Die benötigte Kommunikationsverbindung ist im Kommunikationsprofil nach IT-Sicherheitsstandard hinterlegt", + "value": @@COM_DOCUMENTED@@ + }, + { + "@xsi.type": "drop_down_list", + "name": "Expertenmodus: Exakt wie beantragt implementieren (Designervorschlag ignorieren)", + "selection": "Nein" + }'); +INSERT INTO txt VALUES ('ext_task_template_ph', 'English', 'Template text for each connection; e.g. for Tufin Secure Change: + { + "@xsi.type": "multi_access_request", + "name": "Required access", + "read_only": false, + "access_request": { + "order": "AR1", + "verifier_result": { + "status": "not run" + }, + "use_topology": true, + "targets": { + "target": { + "@type": "ANY" + } + }, + "users": { + "user": @@USERS@@ + }, + "sources": { + "source": @@SOURCES@@ + }, + "destinations": { + "destination": @@DESTINATIONS@@ + }, + "services": { + "service": @@SERVICES@@ + }, + "action": "@@ACTION@@", + "labels": "" + } + }, + { + "@xsi.type": "text_area", + "name": "Reason for the connection request", + "read_only": false, + "text": "@@REASON@@" + }, + { + "@xsi.type": "drop_down_list", + "name": "Activate logging?", + "selection": "@@LOGGING@@" + }, + { + "@xsi.type": "date", + "name": "Rule termination date:" + }, + { + "@xsi.type": "text_field", + "name": "Application ID", + "text": "@@APPID@@" + }, + { + "@xsi.type": "checkbox", + "name": "Connection defined in application security documentation", + "value": @@COM_DOCUMENTED@@ + }, + { + "@xsi.type": "drop_down_list", + "name": "Expert mode?", + "selection": "Nein" + }'); + +INSERT INTO txt VALUES ('area', 'German', 'Area'); +INSERT INTO txt VALUES ('area', 'English', 'Area'); +INSERT INTO txt VALUES ('interface', 'German', 'Schnittstelle'); +INSERT INTO txt VALUES ('interface', 'English', 'Interface'); +INSERT INTO txt VALUES ('interfaces', 'German', 'Schnittstellen'); +INSERT INTO txt VALUES ('interfaces', 'English', 'Interfaces'); +INSERT INTO txt VALUES ('provided_interfaces', 'German', 'Bereitgestellte Schnittstellen'); +INSERT INTO txt VALUES ('provided_interfaces', 'English', 'Provided Interfaces'); +INSERT INTO txt VALUES ('remove_interface', 'German', 'Schnittstelle entfernen'); +INSERT INTO txt VALUES ('remove_interface', 'English', 'Remove Interface'); +INSERT INTO txt VALUES ('display_interface', 'German', 'Schnittstelle darstellen'); +INSERT INTO txt VALUES ('display_interface', 'English', 'Display Interface'); +INSERT INTO txt VALUES ('interface_permission', 'German', 'Berechtigung'); +INSERT INTO txt VALUES ('interface_permission', 'English', 'Permission'); +INSERT INTO txt VALUES ('request_interface', 'German', 'Schnittstelle anfordern'); +INSERT INTO txt VALUES ('request_interface', 'English', 'Request Interface'); +INSERT INTO txt VALUES ('requested_interface', 'German', 'Angeforderte Schnittstelle'); +INSERT INTO txt VALUES ('requested_interface', 'English', 'Requested Interface'); +INSERT INTO txt VALUES ('requested_interfaces', 'German', 'Angeforderte Schnittstellen'); +INSERT INTO txt VALUES ('requested_interfaces', 'English', 'Requested Interfaces'); +INSERT INTO txt VALUES ('requested_app', 'German', 'Angeforderte Anwendung'); +INSERT INTO txt VALUES ('requested_app', 'English', 'Requested App'); +INSERT INTO txt VALUES ('requesting_app', 'German', 'Anfordernde Anwendung'); +INSERT INTO txt VALUES ('requesting_app', 'English', 'Requesting App'); +INSERT INTO txt VALUES ('interface_requested', 'German', 'Schnittstelle angefordert'); +INSERT INTO txt VALUES ('interface_requested', 'English', 'Interface requested'); +INSERT INTO txt VALUES ('update_interf_user', 'German', 'Schnittstellen-Nutzer aktualisieren'); +INSERT INTO txt VALUES ('update_interf_user', 'English', 'Update interface user'); +INSERT INTO txt VALUES ('own_interfaces', 'German', 'Eigene Schnittstellen'); +INSERT INTO txt VALUES ('own_interfaces', 'English', 'Own Interfaces'); +INSERT INTO txt VALUES ('use', 'German', 'Benutzen'); +INSERT INTO txt VALUES ('use', 'English', 'Use'); +INSERT INTO txt VALUES ('services_group', 'German', 'Dienstgruppe'); +INSERT INTO txt VALUES ('services_group', 'English', 'Service Group'); +INSERT INTO txt VALUES ('services_groups', 'German', 'Dienstgruppen'); +INSERT INTO txt VALUES ('services_groups', 'English', 'Service Groups'); +INSERT INTO txt VALUES ('to_services_group', 'German', 'Zu Dienstgruppe'); +INSERT INTO txt VALUES ('to_services_group', 'English', 'To Service Group'); +INSERT INTO txt VALUES ('add_service_group', 'German', 'Dienstgruppe hinzufügen'); +INSERT INTO txt VALUES ('add_service_group', 'English', 'Add Service Group'); +INSERT INTO txt VALUES ('edit_service_group', 'German', 'Dienstgruppe bearbeiten'); +INSERT INTO txt VALUES ('edit_service_group', 'English', 'Edit Service Group'); +INSERT INTO txt VALUES ('save_service_group', 'German', 'Dienstgruppe speichern'); +INSERT INTO txt VALUES ('save_service_group', 'English', 'Save Service Group'); +INSERT INTO txt VALUES ('delete_service_group', 'German', 'Dienstgruppe löschen'); +INSERT INTO txt VALUES ('delete_service_group', 'English', 'Delete Service Group'); +INSERT INTO txt VALUES ('display_service_group','German', 'Dienstgruppe darstellen'); +INSERT INTO txt VALUES ('display_service_group','English', 'Display Service Group'); +INSERT INTO txt VALUES ('add_app_server', 'German', 'Neuer App Server'); +INSERT INTO txt VALUES ('add_app_server', 'English', 'New App Server'); +INSERT INTO txt VALUES ('edit_app_server', 'German', 'App Server bearbeiten'); +INSERT INTO txt VALUES ('edit_app_server', 'English', 'Edit App Server'); +INSERT INTO txt VALUES ('save_app_server', 'German', 'App Server speichern'); +INSERT INTO txt VALUES ('save_app_server', 'English', 'Save App Server'); +INSERT INTO txt VALUES ('delete_app_server', 'German', 'App Server löschen'); +INSERT INTO txt VALUES ('delete_app_server', 'English', 'Delete App Server'); +INSERT INTO txt VALUES ('created_by', 'German', 'Erstellt von'); +INSERT INTO txt VALUES ('created_by', 'English', 'Created by'); +INSERT INTO txt VALUES ('requested_by', 'German', 'Beantragt von'); +INSERT INTO txt VALUES ('requested_by', 'English', 'Requested by'); +INSERT INTO txt VALUES ('for', 'German', 'für'); +INSERT INTO txt VALUES ('for', 'English', 'for'); +INSERT INTO txt VALUES ('log_change', 'German', 'Änderung loggen'); +INSERT INTO txt VALUES ('log_change', 'English', 'Log Change'); +INSERT INTO txt VALUES ('show_history', 'German', 'Änderungshistorie'); +INSERT INTO txt VALUES ('show_history', 'English', 'Show History'); +INSERT INTO txt VALUES ('request_fw_change', 'German', 'Firewall-Änderungen beantragen'); +INSERT INTO txt VALUES ('request_fw_change', 'English', 'Request firewall changes'); +INSERT INTO txt VALUES ('ext_ticket_auth', 'German', 'Authorization-Header-String'); +INSERT INTO txt VALUES ('ext_ticket_auth', 'English', 'Authorization header string'); +INSERT INTO txt VALUES ('ext_ticket_lookup_id', 'German', 'Externe Nutzer Id ermitteln'); +INSERT INTO txt VALUES ('ext_ticket_lookup_id', 'English', 'Lookup external user Id'); +INSERT INTO txt VALUES ('ext_ticket_number', 'German', 'Externe Ticket-Nummer'); +INSERT INTO txt VALUES ('ext_ticket_number', 'English', 'External ticket number'); +INSERT INTO txt VALUES ('changed_by', 'German', 'Geändert von'); +INSERT INTO txt VALUES ('changed_by', 'English', 'Changed by'); +INSERT INTO txt VALUES ('object_id', 'German', 'Objekt-Id'); +INSERT INTO txt VALUES ('object_id', 'English', 'Object Id'); +INSERT INTO txt VALUES ('predef_services', 'German', 'Vordefinierte Dienste'); +INSERT INTO txt VALUES ('predef_services', 'English', 'Predefined Services'); +INSERT INTO txt VALUES ('common_areas', 'German', 'Gemeinsame Netzwerkareas'); +INSERT INTO txt VALUES ('common_areas', 'English', 'Common Network Areas'); +INSERT INTO txt VALUES ('special_user_areas', 'German', 'Netzwerkareas für Nutzer'); +INSERT INTO txt VALUES ('special_user_areas', 'English', 'Network Areas for Users'); +INSERT INTO txt VALUES ('updatable_obj_areas', 'German', 'Netzwerkareas für Updatable Objects'); +INSERT INTO txt VALUES ('updatable_obj_areas', 'English', 'Network Areas for Updatable Objects'); +INSERT INTO txt VALUES ('search_interface', 'German', 'Schnittstelle suchen'); +INSERT INTO txt VALUES ('search_interface', 'English', 'Search Interface'); +INSERT INTO txt VALUES ('used_interface', 'German', 'Genutzte Schnittstelle'); +INSERT INTO txt VALUES ('used_interface', 'English', 'Used Interface'); +INSERT INTO txt VALUES ('reactivate', 'German', 'Reaktivieren'); +INSERT INTO txt VALUES ('reactivate', 'English', 'Reactivate'); +INSERT INTO txt VALUES ('search_nw_object', 'German', 'Netzwerkobjekt suchen'); +INSERT INTO txt VALUES ('search_nw_object', 'English', 'Search Network Object'); +INSERT INTO txt VALUES ('remove_nw_object', 'German', 'Netzwerkobjekt entfernen'); +INSERT INTO txt VALUES ('remove_nw_object', 'English', 'Remove Network Object'); +INSERT INTO txt VALUES ('is_in_use', 'German', 'Wird benutzt'); +INSERT INTO txt VALUES ('is_in_use', 'English', 'Is in use'); +INSERT INTO txt VALUES ('deactivate', 'German', 'Deaktivieren'); +INSERT INTO txt VALUES ('deactivate', 'English', 'Deactivate'); +INSERT INTO txt VALUES ('common_service', 'German', 'Common Service'); +INSERT INTO txt VALUES ('common_service', 'English', 'Common Service'); +INSERT INTO txt VALUES ('common_services', 'German', 'Common Services'); +INSERT INTO txt VALUES ('common_services', 'English', 'Common Services'); +INSERT INTO txt VALUES ('own_common_services', 'German', 'Eigene Common Services'); +INSERT INTO txt VALUES ('own_common_services', 'English', 'Own Common Services'); +INSERT INTO txt VALUES ('global_common_services','German', 'Globale Common Services'); +INSERT INTO txt VALUES ('global_common_services','English', 'Global Common Services'); +INSERT INTO txt VALUES ('add_common_service', 'German', 'Common Service hinzufügen'); +INSERT INTO txt VALUES ('add_common_service', 'English', 'Add Common Service'); +INSERT INTO txt VALUES ('regular_connection', 'German', 'Standard-Verbindung'); +INSERT INTO txt VALUES ('regular_connection', 'English', 'Regular Connection'); +INSERT INTO txt VALUES ('regular_connections', 'German', 'Standard-Verbindungen'); +INSERT INTO txt VALUES ('regular_connections', 'English', 'Regular Connections'); +INSERT INTO txt VALUES ('using_connections', 'German', 'Nutzende Verbindungen von '); +INSERT INTO txt VALUES ('using_connections', 'English', 'Using Connections of '); +INSERT INTO txt VALUES ('where_used', 'German', 'Wo genutzt?'); +INSERT INTO txt VALUES ('where_used', 'English', 'Where used?'); +INSERT INTO txt VALUES ('show_all', 'German', 'Alle darstellen'); +INSERT INTO txt VALUES ('show_all', 'English', 'Show all'); +INSERT INTO txt VALUES ('fetch_limit', 'German', 'Limit'); +INSERT INTO txt VALUES ('fetch_limit', 'English', 'limit'); +INSERT INTO txt VALUES ('as_source', 'German', 'Als Quelle'); +INSERT INTO txt VALUES ('as_source', 'English', 'As Source'); +INSERT INTO txt VALUES ('send_email', 'German', 'Email senden'); +INSERT INTO txt VALUES ('send_email', 'English', 'Send email'); +INSERT INTO txt VALUES ('from_ticket', 'German', 'Von Ticket'); +INSERT INTO txt VALUES ('from_ticket', 'English', 'From Ticket'); +INSERT INTO txt VALUES ('display_ticket', 'German', 'Antrag darstellen'); +INSERT INTO txt VALUES ('display_ticket', 'English', 'Display Ticket'); +INSERT INTO txt VALUES ('edit_ticket', 'German', 'Antrag bearbeiten'); +INSERT INTO txt VALUES ('edit_ticket', 'English', 'Edit Ticket'); +INSERT INTO txt VALUES ('publish', 'German', 'Veröffentlichen'); +INSERT INTO txt VALUES ('publish', 'English', 'Publish'); +INSERT INTO txt VALUES ('published', 'German', 'Veröffentlicht'); +INSERT INTO txt VALUES ('published', 'English', 'Published'); +INSERT INTO txt VALUES ('interface_description','German', 'Schnittstellenbeschreibung'); +INSERT INTO txt VALUES ('interface_description','English', 'Interface description'); +INSERT INTO txt VALUES ('owner', 'German', 'Eigentümer'); +INSERT INTO txt VALUES ('owner', 'English', 'Owner'); +INSERT INTO txt VALUES ('app_server_types', 'German', 'App-Server-Typen'); +INSERT INTO txt VALUES ('app_server_types', 'English', 'App Server Types'); +INSERT INTO txt VALUES ('default_app_server_type','German', 'Standardtyp'); +INSERT INTO txt VALUES ('default_app_server_type','English','Default Type'); +INSERT INTO txt VALUES ('replace', 'German', 'Ersetzen'); +INSERT INTO txt VALUES ('replace', 'English', 'Replace'); +INSERT INTO txt VALUES ('share_link', 'German', 'Link teilen'); +INSERT INTO txt VALUES ('share_link', 'English', 'Share Link'); +INSERT INTO txt VALUES ('copy_to_clipboard', 'German', 'in Zwischenablage kopieren'); +INSERT INTO txt VALUES ('copy_to_clipboard', 'English', 'Copy to clipboard'); +INSERT INTO txt VALUES ('workflow_filters', 'German', 'Workflow-Filter'); +INSERT INTO txt VALUES ('workflow_filters', 'English', 'Workflow Filters'); +INSERT INTO txt VALUES ('rule_filters', 'German', 'Regel-Filter'); +INSERT INTO txt VALUES ('rule_filters', 'English', 'Rule Filters'); +INSERT INTO txt VALUES ('variance_filters', 'German', 'Soll-Ist-Filter'); +INSERT INTO txt VALUES ('variance_filters', 'English', 'Variance Filters'); +INSERT INTO txt VALUES ('match_source', 'German', 'in Quelle'); +INSERT INTO txt VALUES ('match_source', 'English', 'in Source'); +INSERT INTO txt VALUES ('match_destination', 'German', 'in Ziel'); +INSERT INTO txt VALUES ('match_destination', 'English', 'in Destination'); +INSERT INTO txt VALUES ('match_either', 'German', 'in Quelle oder Ziel'); +INSERT INTO txt VALUES ('match_either', 'English', 'in Source or Destination'); +INSERT INTO txt VALUES ('match_any', 'German', 'in Any-Regeln'); +INSERT INTO txt VALUES ('match_any', 'English', 'in Any Rules'); +INSERT INTO txt VALUES ('match_drop_rules', 'German', 'in Drop-Regeln'); +INSERT INTO txt VALUES ('match_drop_rules', 'English', 'in Drop rules'); +INSERT INTO txt VALUES ('show_full_rules', 'German', 'vollständige Regeln anzeigen'); +INSERT INTO txt VALUES ('show_full_rules', 'English', 'show full rules'); +INSERT INTO txt VALUES ('show_full_ticket', 'German', 'vollständiges Ticket anzeigen'); +INSERT INTO txt VALUES ('show_full_ticket', 'English', 'show full ticket'); +INSERT INTO txt VALUES ('detailed_view', 'German', 'Detaillierte Ansicht'); +INSERT INTO txt VALUES ('detailed_view', 'English', 'Detailed View'); +INSERT INTO txt VALUES ('analyse_remaining_rules','German', 'Verbleibende Regeln analysieren'); +INSERT INTO txt VALUES ('analyse_remaining_rules','English','Analyse remaining rules'); +INSERT INTO txt VALUES ('rules_for_deleted_conns','German', 'Regeln von gelöschten Verbindungen'); +INSERT INTO txt VALUES ('rules_for_deleted_conns','English','Rules from deleted connections'); +INSERT INTO txt VALUES ('reject', 'German', 'Ablehnen'); +INSERT INTO txt VALUES ('reject', 'English', 'Reject'); +INSERT INTO txt VALUES ('reject_interface', 'German', 'Schnittstelle ablehnen'); +INSERT INTO txt VALUES ('reject_interface', 'English', 'Reject interface'); +INSERT INTO txt VALUES ('decommission', 'German', 'Stilllegen'); +INSERT INTO txt VALUES ('decommission', 'English', 'Decommission'); +INSERT INTO txt VALUES ('decomm_interface', 'German', 'Schnittstelle stilllegen'); +INSERT INTO txt VALUES ('decomm_interface', 'English', 'Decommission interface'); +INSERT INTO txt VALUES ('on', 'German', ' auf '); +INSERT INTO txt VALUES ('on', 'English', ' on '); +INSERT INTO txt VALUES ('create_rule', 'German', 'Regeln anlegen'); +INSERT INTO txt VALUES ('create_rule', 'English', 'Create Rules'); +INSERT INTO txt VALUES ('modify_rule', 'German', 'Regeln ändern'); +INSERT INTO txt VALUES ('modify_rule', 'English', 'Modify Rules'); +INSERT INTO txt VALUES ('remove_rule', 'German', 'Regeln löschen'); +INSERT INTO txt VALUES ('remove_rule', 'English', 'Remove Rules'); +INSERT INTO txt VALUES ('create_group', 'German', 'Gruppe anlegen'); +INSERT INTO txt VALUES ('create_group', 'English', 'Create Group'); +INSERT INTO txt VALUES ('modify_group', 'German', 'Gruppe ändern'); +INSERT INTO txt VALUES ('modify_group', 'English', 'Modify Group'); +INSERT INTO txt VALUES ('new_connection', 'German', 'Neue Verbindung'); +INSERT INTO txt VALUES ('new_connection', 'English', 'New Connection'); +INSERT INTO txt VALUES ('new_common_service', 'German', 'Neuer Common Service'); +INSERT INTO txt VALUES ('new_common_service', 'English', 'New Common Service'); +INSERT INTO txt VALUES ('edit_common_service', 'German', 'Common Service bearbeiten'); +INSERT INTO txt VALUES ('edit_common_service', 'English', 'Edit Common Service'); +INSERT INTO txt VALUES ('new_app_role', 'German', 'Neue AppRolle: '); +INSERT INTO txt VALUES ('new_app_role', 'English', 'New AppRole: '); +INSERT INTO txt VALUES ('update_app_role', 'German', 'Geänderte AppRolle: '); +INSERT INTO txt VALUES ('update_app_role', 'English', 'Update AppRole: '); +INSERT INTO txt VALUES ('new_svc_grp', 'German', 'Neue Servicegruppe: '); +INSERT INTO txt VALUES ('new_svc_grp', 'English', 'New Servicegroup: '); +INSERT INTO txt VALUES ('add_members', 'German', ': Mitglieder hinzufügen'); +INSERT INTO txt VALUES ('add_members', 'English', ': Add Members'); +INSERT INTO txt VALUES ('remove_members', 'German', ': Mitglieder entfernen'); +INSERT INTO txt VALUES ('remove_members', 'English', ': Remove Members'); +INSERT INTO txt VALUES ('delete_app_zone', 'German', 'App Zone löschen'); +INSERT INTO txt VALUES ('delete_app_zone', 'English', 'Delete App Zone'); +INSERT INTO txt VALUES ('extra_params', 'German', 'Sonderkonfigurationen'); +INSERT INTO txt VALUES ('extra_params', 'English', 'Extra configurations'); +INSERT INTO txt VALUES ('add_extra_config', 'German', 'Sonderkonfiguration hinzufügen'); +INSERT INTO txt VALUES ('add_extra_config', 'English', 'Add extra configuration'); +INSERT INTO txt VALUES ('delete_extra_config', 'German', 'Sonderkonfiguration entfernen'); +INSERT INTO txt VALUES ('delete_extra_config', 'English', 'Delete extra configurations'); +INSERT INTO txt VALUES ('impl_instructions', 'German', 'Implementationsanweisungen'); +INSERT INTO txt VALUES ('impl_instructions', 'English', 'Implementation instructions'); +INSERT INTO txt VALUES ('never_requested', 'German', 'Wurde noch nicht beantragt'); +INSERT INTO txt VALUES ('never_requested', 'English', 'Never requested'); +INSERT INTO txt VALUES ('never_succ_req', 'German', 'Wurde noch nicht erfolgreich beantragt'); +INSERT INTO txt VALUES ('never_succ_req', 'English', 'Never successfully requested'); +INSERT INTO txt VALUES ('in_process', 'German', 'Antrag in Bearbeitung'); +INSERT INTO txt VALUES ('in_process', 'English', 'Request in process'); +INSERT INTO txt VALUES ('temp_error', 'German', 'Temporärer Fehler'); +INSERT INTO txt VALUES ('temp_error', 'English', 'Temporary error'); +INSERT INTO txt VALUES ('temp_error_extended', 'German', 'Temporärer Fehler bei der Beantragung (es wird weiter versucht)'); +INSERT INTO txt VALUES ('temp_error_extended', 'English', 'Temporary error at requesting (will be further attempted)'); +INSERT INTO txt VALUES ('last_successful', 'German', 'Zuletzt erfolgreich beantragt: '); +INSERT INTO txt VALUES ('last_successful', 'English', 'Last successfully requested: '); +INSERT INTO txt VALUES ('implementation_error', 'German', 'Fehler bei der Umsetzung'); +INSERT INTO txt VALUES ('implementation_error', 'English', 'Implementation error'); +INSERT INTO txt VALUES ('update_subscription_error','German','Fehler beim Aktualisieren'); +INSERT INTO txt VALUES ('update_subscription_error','English','Update subscription error'); +INSERT INTO txt VALUES ('new_app_zone', 'German', 'Neue AppZone: '); +INSERT INTO txt VALUES ('new_app_zone', 'English', 'New AppZone: '); +INSERT INTO txt VALUES ('update_app_zone', 'German', 'Geänderte AppZone: '); +INSERT INTO txt VALUES ('update_app_zone', 'English', 'Update AppZone: '); +INSERT INTO txt VALUES ('nwareachange_clear_app_servers', 'German', 'Sind Sie sicher, dass Sie die Netzwerk Area wechseln wollen?

    Es werden alle hinzugefügten App Server entfernt!'); +INSERT INTO txt VALUES ('nwareachange_clear_app_servers', 'English', 'Are you sure you want to change the network area?

    All added app servers will be removed!'); +INSERT INTO txt VALUES ('lookup', 'German', 'Nachschlagen'); +INSERT INTO txt VALUES ('lookup', 'English', 'Look-up'); +INSERT INTO txt VALUES ('generate_name', 'German', 'Name generieren'); +INSERT INTO txt VALUES ('generate_name', 'English', 'Generate Name'); +INSERT INTO txt VALUES ('change_source', 'German', 'Änderungsquelle'); +INSERT INTO txt VALUES ('change_source', 'English', 'Change Source'); +INSERT INTO txt VALUES ('tableofcontent', 'German', 'Inhaltsverzeichnis'); +INSERT INTO txt VALUES ('tableofcontent', 'English', 'Table of content'); +INSERT INTO txt VALUES ('entrydata', 'German', 'Dateneintrag'); +INSERT INTO txt VALUES ('entrydata', 'English', 'Data entry'); +INSERT INTO txt VALUES ('error_message', 'German', 'Fehlermeldung'); +INSERT INTO txt VALUES ('error_message', 'English', 'Error message'); +INSERT INTO txt VALUES ('variance_analysis', 'German', 'Soll-Ist-Abgleich'); +INSERT INTO txt VALUES ('variance_analysis', 'English', 'Variance Analysis'); +INSERT INTO txt VALUES ('app_zone', 'German', 'App Zone'); +INSERT INTO txt VALUES ('app_zone', 'English', 'App Zone'); +INSERT INTO txt VALUES ('az_differing_on', 'German', 'Implementierte App Zone differiert auf'); +INSERT INTO txt VALUES ('az_differing_on', 'English', 'Implemented App Zone differing on'); +INSERT INTO txt VALUES ('no_modelled_az', 'German', 'Keine App Zone modelliert'); +INSERT INTO txt VALUES ('no_modelled_az', 'English', 'No App Zone modelled'); +INSERT INTO txt VALUES ('mod_state', 'German', 'Mod Status'); +INSERT INTO txt VALUES ('mod_state', 'English', 'Mod State'); +INSERT INTO txt VALUES ('impl_state', 'German', 'Impl Status'); +INSERT INTO txt VALUES ('impl_state', 'English', 'Impl State'); +INSERT INTO txt VALUES ('refresh_state', 'German', 'Status aktualisieren'); +INSERT INTO txt VALUES ('refresh_state', 'English', 'Refresh State'); +INSERT INTO txt VALUES ('delete_rule', 'German', 'Regel löschen'); +INSERT INTO txt VALUES ('delete_rule', 'English', 'Delete Rule'); +INSERT INTO txt VALUES ('change_rule', 'German', 'Regel ändern'); +INSERT INTO txt VALUES ('change_rule', 'English', 'Change Rule'); +INSERT INTO txt VALUES ('update_ticket', 'German', 'Ticket aktualisieren'); +INSERT INTO txt VALUES ('update_ticket', 'English', 'Update ticket'); +INSERT INTO txt VALUES ('modelled_source', 'German', 'Modellierte Quelle'); +INSERT INTO txt VALUES ('modelled_source', 'English', 'Modelled Source'); +INSERT INTO txt VALUES ('modelled_destination', 'German', 'Modelliertes Ziel'); +INSERT INTO txt VALUES ('modelled_destination', 'English', 'Modelled Destination'); +INSERT INTO txt VALUES ('last_requested', 'German', 'Letzte Beantragung'); +INSERT INTO txt VALUES ('last_requested', 'English', 'Last Requested'); +INSERT INTO txt VALUES ('permitted_owners', 'German', 'Berechtigte Applikationen'); +INSERT INTO txt VALUES ('permitted_owners', 'English', 'Permitted Applications'); + +-- compliance +INSERT INTO txt VALUES ('compliance', 'German', 'Compliance'); +INSERT INTO txt VALUES ('compliance', 'English', 'Compliance'); +INSERT INTO txt VALUES ('network_zones', 'German', 'Netzwerkzonen'); +INSERT INTO txt VALUES ('network_zones', 'English', 'Network zones'); +INSERT INTO txt VALUES ('matrix', 'German', 'Zonen-Matrix'); +INSERT INTO txt VALUES ('matrix', 'English', 'Zones Matrix'); +INSERT INTO txt VALUES ('checks', 'German', 'Überprüfung'); +INSERT INTO txt VALUES ('checks', 'English', 'Checks'); +INSERT INTO txt VALUES ('check', 'German', 'Überprüfen'); +INSERT INTO txt VALUES ('check', 'English', 'Check'); +INSERT INTO txt VALUES ('zone_comm_matrix', 'German', 'Netzwerkzonen-Kommunikationsmatrix'); +INSERT INTO txt VALUES ('zone_comm_matrix', 'English', 'Network zone communication matrix'); +INSERT INTO txt VALUES ('network_zone_config', 'German', 'Netzwerkzonen-Konfiguration'); +INSERT INTO txt VALUES ('network_zone_config', 'English', 'Network zone configuration'); +INSERT INTO txt VALUES ('network_zone_check', 'German', 'Netzwerkzonen-Complianceprüfung'); +INSERT INTO txt VALUES ('network_zone_check', 'English', 'Network zone compliance check'); +INSERT INTO txt VALUES ('allowed_communication','German', 'Erlaubte Kommunikation'); +INSERT INTO txt VALUES ('allowed_communication','English', 'Allowed communication'); +INSERT INTO txt VALUES ('subzones', 'German', 'Subzonen'); +INSERT INTO txt VALUES ('subzones', 'English', 'Subzones'); +INSERT INTO txt VALUES ('superzone', 'German', 'Superzone'); +INSERT INTO txt VALUES ('superzone', 'English', 'Superzone'); +INSERT INTO txt VALUES ('edit_zone_title', 'German', 'Netzwerkzone editieren'); +INSERT INTO txt VALUES ('edit_zone_title', 'English', 'Edit network zone'); +INSERT INTO txt VALUES ('add_ip_addresses', 'German', 'IP Adresse(n) hinzufügen'); +INSERT INTO txt VALUES ('add_ip_addresses', 'English', 'Add IP Addresses'); +INSERT INTO txt VALUES ('delete_zone_title', 'German', 'Netzwerkzone löschen'); +INSERT INTO txt VALUES ('delete_zone_title', 'English', 'Delete network zone'); +INSERT INTO txt VALUES ('delete_zone_text', 'German', 'Sind Sie sich sicher, dass sie die Netzwerkzone % löschen wollen?'); +INSERT INTO txt VALUES ('delete_zone_text', 'English', 'Are you sure you want to delete the network zone %?'); +INSERT INTO txt VALUES ('to', 'German', 'Nach'); +INSERT INTO txt VALUES ('to', 'English', 'To'); +INSERT INTO txt VALUES ('allowed_comm_dests', 'German', 'Erlaubte Kommunikation (Nach)'); +INSERT INTO txt VALUES ('allowed_comm_dests', 'English', 'Allowed communication (to)'); +INSERT INTO txt VALUES ('allowed_comm_srcs', 'German', 'Erlaubte Kommunikation (Von)'); +INSERT INTO txt VALUES ('allowed_comm_srcs', 'English', 'Allowed communication (from)'); +INSERT INTO txt VALUES ('relogin', 'German', 'Erneut anmelden'); +INSERT INTO txt VALUES ('relogin', 'English', 'Re-Login'); +INSERT INTO txt VALUES ('relogin_error', 'German', 'Fehler bei der erneuten Anmeldung'); +INSERT INTO txt VALUES ('relogin_error', 'English', 'Re-Login error'); +INSERT INTO txt VALUES ('internet_local_zone', 'German', 'Internet / Lokal'); +INSERT INTO txt VALUES ('internet_local_zone', 'English', 'Internet / Local'); +INSERT INTO txt VALUES ('rule_conform', 'German', 'Regelkonform'); +INSERT INTO txt VALUES ('rule_conform', 'English', 'In accordance with the rules'); +INSERT INTO txt VALUES ('rule_violations', 'German', 'Regelverletzungen'); +INSERT INTO txt VALUES ('rule_violations', 'English', 'Rule violations'); +INSERT INTO txt VALUES ('no_network_zones', 'German', 'Es existieren bisher keine Netzwerkzonen. Bitte legen Sie diese im Abschnitt "Konfiguration" an.'); +INSERT INTO txt VALUES ('no_network_zones', 'English', 'No network zones exist yet. Please create them in the "Configuration" section.'); +INSERT INTO txt VALUES ('owner_appserver_notfound','German', 'Owner für App-Server nicht gefunden.'); +INSERT INTO txt VALUES ('owner_appserver_notfound','English', 'Owner for App server not found.'); +INSERT INTO txt VALUES ('owner_appservertype_notfound','German', 'App-Server Typ für App-Server nicht gefunden.'); +INSERT INTO txt VALUES ('owner_appservertype_notfound','English', 'App server type for App server not found.'); +INSERT INTO txt VALUES ('import_finished_witherrors','German', 'Import wurde mit Fehlern abgeschlossen'); +INSERT INTO txt VALUES ('import_finished_witherrors','English', 'Import succeeded with errors'); +INSERT INTO txt VALUES ('file_upload_failed', 'German', 'Datei hochladen ist fehlgeschlagen.'); +INSERT INTO txt VALUES ('file_upload_failed', 'English', 'File upload failed.'); +INSERT INTO txt VALUES ('wrong_input_data', 'German', 'Falsche Eingabedaten'); +INSERT INTO txt VALUES ('wrong_input_data', 'English', 'Wrong input data'); +INSERT INTO txt VALUES ('add_matrix', 'German', 'Matrix hinzufügen'); +INSERT INTO txt VALUES ('add_matrix', 'English', 'Add Matrix'); +INSERT INTO txt VALUES ('delete_matrix', 'German', 'Matrix löschen'); +INSERT INTO txt VALUES ('delete_matrix', 'English', 'Delete Matrix'); +INSERT INTO txt VALUES ('policy', 'German', 'Policy'); +INSERT INTO txt VALUES ('policy', 'English', 'Policy'); +INSERT INTO txt VALUES ('policies', 'German', 'Policies'); +INSERT INTO txt VALUES ('policies', 'English', 'Policies'); +INSERT INTO txt VALUES ('edit_policy', 'German', 'Policy bearbeiten'); +INSERT INTO txt VALUES ('edit_policy', 'English', 'Edit Policy'); +INSERT INTO txt VALUES ('delete_policy', 'German', 'Policy löschen'); +INSERT INTO txt VALUES ('delete_policy', 'English', 'Delete Policy'); +INSERT INTO txt VALUES ('fix_criteria', 'German', 'Feste Kriterien'); +INSERT INTO txt VALUES ('fix_criteria', 'English', 'Fixed Criteria'); +INSERT INTO txt VALUES ('edit_fix_crit', 'German', 'Festes Kriteriium bearbeiten'); +INSERT INTO txt VALUES ('edit_fix_crit', 'English', 'Edit Fixed Criterion'); +INSERT INTO txt VALUES ('criteria', 'German', 'Kriterien'); +INSERT INTO txt VALUES ('criteria', 'English', 'Criteria'); +INSERT INTO txt VALUES ('show_non_impact_rules','German', 'Zeige Regeln ohne Auswirkungen'); +INSERT INTO txt VALUES ('show_non_impact_rules','English', 'Show non-impact rules'); +INSERT INTO txt VALUES ('assess_ip_null', 'German', 'Netzwerkobjekte in Quelle oder Ziel ohne IP-Adresse'); +INSERT INTO txt VALUES ('assess_ip_null', 'English', 'Network objects in source or destination without IP'); +INSERT INTO txt VALUES ('assess_all_ips', 'German', 'Netzwerkobjekte in Quelle oder Ziel mit 0.0.0.0/0 oder ::/0'); +INSERT INTO txt VALUES ('assess_all_ips', 'English', 'Network objects in source or destination with 0.0.0.0/0 or ::/0'); +INSERT INTO txt VALUES ('assess_host_address', 'German', 'Netzwerkobjekte in Quelle oder Ziel mit 0.0.0.0/32'); +INSERT INTO txt VALUES ('assess_host_address', 'English', 'Network objects in source or destination with 0.0.0.0/32'); +INSERT INTO txt VALUES ('assess_broadcast', 'German', 'Netzwerkobjekte in Quelle oder Ziel mit 255.255.255.255/32'); +INSERT INTO txt VALUES ('assess_broadcast', 'English', 'Network objects in source or destination with 255.255.255.255/32'); + -- settings INSERT INTO txt VALUES ('devices', 'German', 'Geräte'); INSERT INTO txt VALUES ('devices', 'English', 'Devices'); @@ -959,8 +2048,20 @@ INSERT INTO txt VALUES ('password_policy', 'German', 'Passworteinstellunge INSERT INTO txt VALUES ('password_policy', 'English', 'Password Policy'); INSERT INTO txt VALUES ('email_settings', 'German', 'Email-Einstellungen'); INSERT INTO txt VALUES ('email_settings', 'English', 'Email settings'); -INSERT INTO txt VALUES ('importer_settings', 'German', 'Importer-Einstellungen'); -INSERT INTO txt VALUES ('importer_settings', 'English', 'Importer settings'); +INSERT INTO txt VALUES ('importer_settings', 'German', 'FW-Importer-Einstellungen'); +INSERT INTO txt VALUES ('importer_settings', 'English', 'FW Importer Settings'); +INSERT INTO txt VALUES ('change_trigger', 'German', 'FW-Änderungstrigger-Einstellungen'); +INSERT INTO txt VALUES ('change_trigger', 'English', 'FW Change Trigger Settings'); +INSERT INTO txt VALUES ('change_notification_sub','German', 'Einstellungen für Trigger von Änderungsbenachrichtigungen'); +INSERT INTO txt VALUES ('change_notification_sub','English','Change Notification Event Trigger Settings'); +INSERT INTO txt VALUES ('owner_mapping', 'German', 'Eigentümerzuordnung'); +INSERT INTO txt VALUES ('owner_mapping', 'English', 'Owner Mapping'); +INSERT INTO txt VALUES ('custom_field_Owner_key', 'German', 'Custom-Feld-Eigentümer-Schlüssel'); +INSERT INTO txt VALUES ('custom_field_Owner_key', 'English', 'Custom Field Owner key'); +INSERT INTO txt VALUES ('custom_field_ChangeID_key', 'German', 'Custom-Feld-&Äuml;nderungsID-Schlüssel'); +INSERT INTO txt VALUES ('custom_field_ChangeID_key', 'English', 'Custom Field ChangeID key'); +INSERT INTO txt VALUES ('custom_field_import_Settings', 'German', 'Custom-Feld-Einstellungen'); +INSERT INTO txt VALUES ('custom_field_import_Settings', 'English', 'Custom Field Settings'); INSERT INTO txt VALUES ('edit_email', 'German', 'Email-Einstellungen editieren'); INSERT INTO txt VALUES ('edit_email', 'English', 'Edit email settings'); INSERT INTO txt VALUES ('email_sender', 'German', 'Email-Absendeadresse'); @@ -971,6 +2072,10 @@ INSERT INTO txt VALUES ('email_auth_pwd', 'German', 'Email-Nutzer Passwor INSERT INTO txt VALUES ('email_auth_pwd', 'English', 'Email user password'); INSERT INTO txt VALUES ('email_enc_method', 'German', 'Email-Verschlüsselung'); INSERT INTO txt VALUES ('email_enc_method', 'English', 'Email encryption'); +INSERT INTO txt VALUES ('use_dummy_email_address','German', 'Dummy-Email-Addresse nutzen'); +INSERT INTO txt VALUES ('use_dummy_email_address','English','Use dummy email address'); +INSERT INTO txt VALUES ('dummy_email_address', 'German', 'Dummy-Email-Addresse'); +INSERT INTO txt VALUES ('dummy_email_address', 'English', 'Dummy email address'); INSERT INTO txt VALUES ('state_definitions', 'German', 'Statusdefinitionen'); INSERT INTO txt VALUES ('state_definitions', 'English', 'State Definitions'); INSERT INTO txt VALUES ('state_matrix', 'German', 'Statusmatrix'); @@ -1043,6 +2148,8 @@ INSERT INTO txt VALUES ('edit_gateway', 'German', 'Gateway bearbeiten') INSERT INTO txt VALUES ('edit_gateway', 'English', 'Edit Gateway'); INSERT INTO txt VALUES ('management', 'German', 'Management'); INSERT INTO txt VALUES ('management', 'English', 'Management'); +INSERT INTO txt VALUES ('ext_mgt_data', 'German', 'Externe Management Daten'); +INSERT INTO txt VALUES ('ext_mgt_data', 'English', 'External Management Data'); INSERT INTO txt VALUES ('local_rulebase', 'German', 'Lokale Rulebase'); INSERT INTO txt VALUES ('local_rulebase', 'English', 'Local Rulebase'); INSERT INTO txt VALUES ('global_rulebase', 'German', 'Globale Rulebase'); @@ -1061,6 +2168,10 @@ INSERT INTO txt VALUES ('last_incomplete', 'German', 'Letzter Unvollendete INSERT INTO txt VALUES ('last_incomplete', 'English', 'Last Incomplete'); INSERT INTO txt VALUES ('rollback', 'German', 'Zurücksetzen'); INSERT INTO txt VALUES ('rollback', 'English', 'Rollback'); +INSERT INTO txt VALUES ('full_rollback', 'German', 'Komplett zurücksetzen'); +INSERT INTO txt VALUES ('full_rollback', 'English', 'Full rollback'); +INSERT INTO txt VALUES ('not_imported_yet', 'German', 'Kein Import für dieses Management vorhanden'); +INSERT INTO txt VALUES ('not_imported_yet', 'English', 'No existing Import for this management'); INSERT INTO txt VALUES ('last_success', 'German', 'Letzter Erfolg'); INSERT INTO txt VALUES ('last_success', 'English', 'Last Success'); INSERT INTO txt VALUES ('last_import', 'German', 'Letzter Import'); @@ -1117,7 +2228,7 @@ INSERT INTO txt VALUES ('remove_user', 'German', 'Nutzer entfernen'); INSERT INTO txt VALUES ('remove_user', 'English', 'Remove user'); INSERT INTO txt VALUES ('get_user_from_ldap', 'German', 'Nutzer von LDAP holen'); INSERT INTO txt VALUES ('get_user_from_ldap', 'English', 'Get user from LDAP'); -INSERT INTO txt VALUES ('select_from_ldap', 'German', 'von LDAP auswählen'); +INSERT INTO txt VALUES ('select_from_ldap', 'German', 'Von LDAP auswählen'); INSERT INTO txt VALUES ('select_from_ldap', 'English', 'Select from LDAP'); INSERT INTO txt VALUES ('synchronize', 'German', 'Mit LDAP Synchronisieren'); INSERT INTO txt VALUES ('synchronize', 'English', 'Synchronize to LDAP'); @@ -1130,11 +2241,11 @@ INSERT INTO txt VALUES ('user', 'English', 'User'); INSERT INTO txt VALUES ('group', 'German', 'Gruppe'); INSERT INTO txt VALUES ('group', 'English', 'Group'); INSERT INTO txt VALUES ('owner_group', 'German', 'Eigentümergruppe'); -INSERT INTO txt VALUES ('owner_group', 'English', 'Owner group'); +INSERT INTO txt VALUES ('owner_group', 'English', 'Owner Group'); INSERT INTO txt VALUES ('into_ldap', 'German', 'in LDAP'); INSERT INTO txt VALUES ('into_ldap', 'English', 'into LDAP'); -INSERT INTO txt VALUES ('from_ldap', 'German', 'von LDAP'); -INSERT INTO txt VALUES ('from_ldap', 'English', 'from LDAP'); +INSERT INTO txt VALUES ('from_ldap', 'German', 'Von LDAP'); +INSERT INTO txt VALUES ('from_ldap', 'English', 'From LDAP'); INSERT INTO txt VALUES ('search_pattern', 'German', 'Suchmuster'); INSERT INTO txt VALUES ('search_pattern', 'English', 'Search Pattern'); INSERT INTO txt VALUES ('internal_group', 'German', 'Interne Gruppe'); @@ -1151,6 +2262,8 @@ INSERT INTO txt VALUES ('add_new_ldap', 'German', 'Neue LDAP-Verbindung INSERT INTO txt VALUES ('add_new_ldap', 'English', 'Add new LDAP connection'); INSERT INTO txt VALUES ('edit_ldap', 'German', 'LDAP-Verbindung bearbeiten'); INSERT INTO txt VALUES ('edit_ldap', 'English', 'Edit LDAP connection'); +INSERT INTO txt VALUES ('edit_ldap_message', 'German', 'Diese Einstellungen müssen normalerweise nicht angepasst werden. Ändern Sie diese Einstellungen nur wenn Sie wirklich wissen was Sie tun.'); +INSERT INTO txt VALUES ('edit_ldap_message', 'English', 'These settings do not normally need to be adjusted. Only change these settings if you really know what you are doing.'); INSERT INTO txt VALUES ('test_connection', 'German', 'Verbindung testen'); INSERT INTO txt VALUES ('test_connection', 'English', 'Test connection'); INSERT INTO txt VALUES ('test_email_connection','German', 'Email-Verbindung testen'); @@ -1169,6 +2282,8 @@ INSERT INTO txt VALUES ('role_search_path', 'German', 'Suchpfad Rollen'); INSERT INTO txt VALUES ('role_search_path', 'English', 'Role Search Path'); INSERT INTO txt VALUES ('group_search_path', 'German', 'Suchpfad Gruppen'); INSERT INTO txt VALUES ('group_search_path', 'English', 'Group Search Path'); +INSERT INTO txt VALUES ('group_write_path', 'German', 'Schreibpfad Gruppen'); +INSERT INTO txt VALUES ('group_write_path', 'English', 'Group Write Path'); INSERT INTO txt VALUES ('search_user', 'German', 'Nutzer für Suche'); INSERT INTO txt VALUES ('search_user', 'English', 'Search User'); INSERT INTO txt VALUES ('search_user_pwd', 'German', 'Passwort Nutzer für Suche'); @@ -1179,6 +2294,8 @@ INSERT INTO txt VALUES ('write_user_pwd', 'German', 'Passwort Schreibende INSERT INTO txt VALUES ('write_user_pwd', 'English', 'Write User Password'); INSERT INTO txt VALUES ('tenant', 'German', 'Mandant'); INSERT INTO txt VALUES ('tenant', 'English', 'Tenant'); +INSERT INTO txt VALUES ('owner_lc_state', 'German', 'Produktionsstatus'); +INSERT INTO txt VALUES ('owner_lc_state', 'English', 'Production state'); INSERT INTO txt VALUES ('global_tenant_name', 'German', 'Globaler Mandantenname'); INSERT INTO txt VALUES ('global_tenant_name', 'English', 'Global Tenant Name'); INSERT INTO txt VALUES ('pwMinLength', 'German', 'Mindestlänge'); @@ -1205,6 +2322,10 @@ INSERT INTO txt VALUES ('sessionTimeout', 'German', 'Sitzungs-Timeout (in INSERT INTO txt VALUES ('sessionTimeout', 'English', 'Session timeout (in minutes)'); INSERT INTO txt VALUES ('sessionTimeoutNoticePeriod', 'German','Benachrichtigung vor Sitzungs-Timeout (in Minuten)'); INSERT INTO txt VALUES ('sessionTimeoutNoticePeriod', 'English','Warning before session timeout (in minutes)'); +INSERT INTO txt VALUES ('uiHostName', 'German', 'Hostname der UI'); +INSERT INTO txt VALUES ('uiHostName', 'English', 'UI Hostname'); +INSERT INTO txt VALUES ('welcomeMessage', 'German', 'Willkommensnachricht'); +INSERT INTO txt VALUES ('welcomeMessage', 'English', 'Welcome Message'); INSERT INTO txt VALUES ('maxMessages', 'German', 'Max Anzahl Nachrichten'); INSERT INTO txt VALUES ('maxMessages', 'English', 'Max number of messages'); INSERT INTO txt VALUES ('messageViewTime', 'German', 'Nachrichten-Anzeigedauer (in Sekunden)'); @@ -1217,6 +2338,8 @@ INSERT INTO txt VALUES ('dataRetentionTime', 'German', 'Datenaufbewahrungsze INSERT INTO txt VALUES ('dataRetentionTime', 'English', 'Data retention time (in days)'); INSERT INTO txt VALUES ('dailyCheckStartAt', 'German', 'Startzeit täglicher Check'); INSERT INTO txt VALUES ('dailyCheckStartAt', 'English', 'Daily check start at'); +INSERT INTO txt VALUES ('dailyCheckModules', 'German', 'Module täglicher Check'); +INSERT INTO txt VALUES ('dailyCheckModules', 'English', 'Daily check modules'); INSERT INTO txt VALUES ('maxImportDuration', 'German', 'Max erlaubte Importdauer (in Stunden)'); INSERT INTO txt VALUES ('maxImportDuration', 'English', 'Max allowed import duration (in hours)'); INSERT INTO txt VALUES ('maxImportInterval', 'German', 'Max erlaubtes Importintervall (in Stunden)'); @@ -1237,12 +2360,34 @@ INSERT INTO txt VALUES ('impChangeNotifyBody', 'German', 'Text der Än INSERT INTO txt VALUES ('impChangeNotifyBody', 'English', 'Body of change notification emails'); INSERT INTO txt VALUES ('impChangeNotifyActive', 'German', 'Änderungsbenachrichtigung aktiv?'); INSERT INTO txt VALUES ('impChangeNotifyActive', 'English', 'Change notification active?'); +INSERT INTO txt VALUES ('impChangeNotifyType', 'German', 'Änderungsbenachrichtigungstyp'); +INSERT INTO txt VALUES ('impChangeNotifyType', 'English', 'Change notification type'); +INSERT INTO txt VALUES ('impChangeNotifySleepTime','German','Änderungsbenachrichtigungs-Intervall (in Sekunden)'); +INSERT INTO txt VALUES ('impChangeNotifySleepTime','English','Change notification sleep time (in seconds)'); +INSERT INTO txt VALUES ('impChangeNotifyStartAt', 'German','Änderungsbenachrichtigungs-Start'); +INSERT INTO txt VALUES ('impChangeNotifyStartAt', 'English','Change notification start at'); +INSERT INTO txt VALUES ('updateRuleOwnerMappingActive','German', 'Regel-Eigentümer-Zuordnungs-Aktualisierung aktiv?'); +INSERT INTO txt VALUES ('updateRuleOwnerMappingActive','English', 'Update Rule Owner Mapping active?'); +INSERT INTO txt VALUES ('updateRuleOwnerMappingSleepTime','German','Regel-Eigentümer-Zuordnungs-Aktualisierungs-Intervall (in Sekunden)'); +INSERT INTO txt VALUES ('updateRuleOwnerMappingSleepTime','English','Update Rule Owner Mapping sleep time (in seconds)'); +INSERT INTO txt VALUES ('updateRuleOwnerMappingStartAt', 'German','Regel-Eigentümer-Zuordnungs-Aktualisierungs-Start'); +INSERT INTO txt VALUES ('updateRuleOwnerMappingStartAt', 'English','Update Rule Owner Mapping start at'); +INSERT INTO txt VALUES ('externalRequestSleepTime','German','Externes Auftrags-Intervall (in Sekunden)'); +INSERT INTO txt VALUES ('externalRequestSleepTime','English','External Request sleep time (in seconds)'); +INSERT INTO txt VALUES ('externalRequestStartAt', 'German','Externer Auftrags-Start'); +INSERT INTO txt VALUES ('externalRequestStartAt', 'English','External Request start at'); +INSERT INTO txt VALUES ('externalRequestWaitCycles','German','Anzahl Wartezyklen'); +INSERT INTO txt VALUES ('externalRequestWaitCycles','English','Number wait cycles'); INSERT INTO txt VALUES ('autoDiscoverSleepTime','German', 'Autodiscover-Intervall (in Stunden)'); INSERT INTO txt VALUES ('autoDiscoverSleepTime','English', 'Auto-discovery sleep time (in hours)'); INSERT INTO txt VALUES ('autoDiscoverStartAt', 'German', 'Autodiscover-Start'); INSERT INTO txt VALUES ('autoDiscoverStartAt', 'English', 'Auto-discovery start at'); INSERT INTO txt VALUES ('recertificationPeriod','German', 'Rezertifizierungsintervall (in Tagen)'); INSERT INTO txt VALUES ('recertificationPeriod','English', 'Recertification Period (in days)'); +INSERT INTO txt VALUES ('initialRecertificationPeriod','German','Initiales Rezertifizierungsintervall (in Tagen)'); +INSERT INTO txt VALUES ('initialRecertificationPeriod','English','Initial Recertification Period (in days)'); +INSERT INTO txt VALUES ('initialRecertifier','German', 'Initialer Rezertifizierer'); +INSERT INTO txt VALUES ('initialRecertifier','English', 'Initial Recertifier'); INSERT INTO txt VALUES ('recertificationNoticePeriod','German','Rezertifizierungserinnerungsintervall (in Tagen)'); INSERT INTO txt VALUES ('recertificationNoticePeriod','English','Recertification Notice Period (in days)'); INSERT INTO txt VALUES ('recertificationDisplayPeriod','German','Rezertifizierungsanzeigeintervall (in Tagen)'); @@ -1265,10 +2410,28 @@ INSERT INTO txt VALUES ('recDeleteRuleTicketPriority','German','Priorität f INSERT INTO txt VALUES ('recDeleteRuleTicketPriority','English','Priority for delete rule ticket'); INSERT INTO txt VALUES ('recDeleteRuleInitState','German', 'Initialer Status für Löschantrag'); INSERT INTO txt VALUES ('recDeleteRuleInitState','English', 'Initial state for delete rule ticket'); -INSERT INTO txt VALUES ('recCheckActive', 'German','Rezert Check - aktiv'); -INSERT INTO txt VALUES ('recCheckActive', 'English','Recert Check - active'); -INSERT INTO txt VALUES ('recCheckEmailSubject', 'German','Rezert Check - Email Betreff'); -INSERT INTO txt VALUES ('recCheckEmailSubject', 'English','Recert Check - Email subject'); +INSERT INTO txt VALUES ('recCheckActive', 'German', 'Rezert Check - aktiv'); +INSERT INTO txt VALUES ('recCheckActive', 'English', 'Recert Check - active'); +INSERT INTO txt VALUES ('recCheckNotifications','German', 'Rezert Check - Benachrichtigungen'); +INSERT INTO txt VALUES ('recCheckNotifications','English', 'Recert Check - Notifications'); +INSERT INTO txt VALUES ('ruleExpiryNotifications','German', 'Regelablauf - Benachrichtigungen'); +INSERT INTO txt VALUES ('ruleExpiryNotifications','English','Rule Expiry - Notifications'); +INSERT INTO txt VALUES ('notificationLanguage', 'German', 'Sprache für Benachrichtigungen'); +INSERT INTO txt VALUES ('notificationLanguage', 'English','Notification language'); +INSERT INTO txt VALUES ('useGlobalDefault', 'German', 'Globale Standardsprache verwenden'); +INSERT INTO txt VALUES ('useGlobalDefault', 'English','Use global default'); +INSERT INTO txt VALUES ('ruleExpiryEmailBody', 'German', 'Regelablauf - Email-Text'); +INSERT INTO txt VALUES ('ruleExpiryEmailBody', 'English', 'Rule Expiry - Email body'); +INSERT INTO txt VALUES ('ownerActiveRuleNotifications','German', 'Aktive Regeln - Benachrichtigungen'); +INSERT INTO txt VALUES ('ownerActiveRuleNotifications','English', 'Active Rules - Notifications'); +INSERT INTO txt VALUES ('ownerActiveRuleEmailBody', 'German', 'Aktive Regeln - Email-Text'); +INSERT INTO txt VALUES ('ownerActiveRuleEmailBody', 'English', 'Active Rules - Email body'); +INSERT INTO txt VALUES ('ruleExpiryInitiatorKeys','German', 'Regelablauf - Initiator-Texte'); +INSERT INTO txt VALUES ('ruleExpiryInitiatorKeys','English', 'Rule Expiry - Initiator texts'); +INSERT INTO txt VALUES ('ruleExpiryInitiator', 'German', 'Initiator des Ablaufs'); +INSERT INTO txt VALUES ('ruleExpiryInitiator', 'English', 'Expiry initiator'); +INSERT INTO txt VALUES ('recCheckEmailSubject', 'German', 'Rezert Check - Email Betreff'); +INSERT INTO txt VALUES ('recCheckEmailSubject', 'English', 'Recert Check - Email subject'); INSERT INTO txt VALUES ('recCheckEmailUpcomingText','German','Rezert Check - Text anstehend'); INSERT INTO txt VALUES ('recCheckEmailUpcomingText','English','Recert Check - text upcoming'); INSERT INTO txt VALUES ('recCheckEmailOverdueText','German','Rezert Check - Text überfällig'); @@ -1281,16 +2444,30 @@ INSERT INTO txt VALUES ('undefined', 'German', 'nicht definiert'); INSERT INTO txt VALUES ('undefined', 'English', 'undefined'); INSERT INTO txt VALUES ('reqAvailableTaskTypes','German', 'Verfügbare Auftragstypen'); INSERT INTO txt VALUES ('reqAvailableTaskTypes','English', 'Available Task Types'); +INSERT INTO txt VALUES ('reqOwnerBased', 'German', 'Eigentümerbasiert'); +INSERT INTO txt VALUES ('reqOwnerBased', 'English', 'Owner based'); +INSERT INTO txt VALUES ('reqReducedView', 'German', 'Eingeschränkte Darstellung'); +INSERT INTO txt VALUES ('reqReducedView', 'English', 'Reduced view'); INSERT INTO txt VALUES ('reqAllowObjectSearch', 'German', 'Objektsuche erlauben'); INSERT INTO txt VALUES ('reqAllowObjectSearch', 'English', 'Allow object search'); INSERT INTO txt VALUES ('reqAllowManualOwnerAdmin','German', 'Manuelle Eigentümerverwaltung erlauben'); INSERT INTO txt VALUES ('reqAllowManualOwnerAdmin','English','Allow manual owner administration'); +INSERT INTO txt VALUES ('ruleOwnershipMode', 'German', 'Regel-Eigentümerschaftsmodus'); +INSERT INTO txt VALUES ('ruleOwnershipMode', 'English', 'Rule Ownership Mode'); INSERT INTO txt VALUES ('reqPriorities', 'German', 'Prioritäten'); INSERT INTO txt VALUES ('reqPriorities', 'English', 'Priorities'); INSERT INTO txt VALUES ('reqAutoCreateImplTasks','German', 'Autom. Erzeugen von Implementierungs-Aufträgen'); INSERT INTO txt VALUES ('reqAutoCreateImplTasks','English', 'Auto-create implementation tasks'); INSERT INTO txt VALUES ('reqActivatePathAnalysis','German', 'Pfadanalyse aktivieren'); INSERT INTO txt VALUES ('reqActivatePathAnalysis','English','Activate Path Analysis'); +INSERT INTO txt VALUES ('reqShowCompliance', 'German', 'Compliance-Modul anzeigen'); +INSERT INTO txt VALUES ('reqShowCompliance', 'English', 'Show Compliance Module'); +INSERT INTO txt VALUES ('reqAllowedChangesByApprover','German', 'Erlaubte Änderungen durch Genehmiger'); +INSERT INTO txt VALUES ('reqAllowedChangesByApprover','English','Allowed changes by approver'); +INSERT INTO txt VALUES ('ticket_fields', 'German', 'Ticket-Felder'); +INSERT INTO txt VALUES ('ticket_fields', 'English', 'Ticket fields'); +INSERT INTO txt VALUES ('task_fields', 'German', 'Auftragsfelder'); +INSERT INTO txt VALUES ('task_fields', 'English', 'Task fields'); INSERT INTO txt VALUES ('numeric_prio', 'German', 'Numerische Priorität'); INSERT INTO txt VALUES ('numeric_prio', 'English', 'Numeric Priority'); INSERT INTO txt VALUES ('ticket_deadline', 'German', 'Ticket-Deadline (in Tagen)'); @@ -1313,6 +2490,10 @@ INSERT INTO txt VALUES ('group_action', 'German', 'Gruppenaktion'); INSERT INTO txt VALUES ('group_action', 'English', 'Group Action'); INSERT INTO txt VALUES ('email', 'German', 'Email'); INSERT INTO txt VALUES ('email', 'English', 'Email'); +INSERT INTO txt VALUES ('firstname', 'German', 'Vorname'); +INSERT INTO txt VALUES ('firstname', 'English', 'First name'); +INSERT INTO txt VALUES ('lastname', 'German', 'Nachname'); +INSERT INTO txt VALUES ('lastname', 'English', 'Last name'); INSERT INTO txt VALUES ('last_login', 'German', 'Letzte Anmeldung'); INSERT INTO txt VALUES ('last_login', 'English', 'Last Login'); INSERT INTO txt VALUES ('last_pw_change', 'German', 'Letzte Passwortänderung'); @@ -1409,13 +2590,19 @@ INSERT INTO txt VALUES ('rollback_import', 'German', 'Import zurückse INSERT INTO txt VALUES ('rollback_import', 'English', 'Rollback Import'); INSERT INTO txt VALUES ('report_settings', 'German', 'Reporteinstellungen'); INSERT INTO txt VALUES ('report_settings', 'English', 'Report Settings'); +INSERT INTO txt VALUES ('migrate_scheduler_config', 'German', 'Scheduler-Konfiguration migrieren'); +INSERT INTO txt VALUES ('migrate_scheduler_config', 'English', 'Migrate scheduler config'); +INSERT INTO txt VALUES ('confirm_migrate_scheduler_config', 'German', 'Alte Scheduler-Konfiguration jetzt in Benachrichtigungen migrieren?'); +INSERT INTO txt VALUES ('confirm_migrate_scheduler_config', 'English', 'Migrate the legacy scheduler configuration to notifications now?'); +INSERT INTO txt VALUES ('scheduler_config_migrated', 'German', 'Scheduler-Konfiguration migriert.'); +INSERT INTO txt VALUES ('scheduler_config_migrated', 'English', 'Scheduler configuration migrated.'); INSERT INTO txt VALUES ('change_language', 'German', 'Ändern der Passworteinstellungen'); INSERT INTO txt VALUES ('change_language', 'English', 'Change Language'); INSERT INTO txt VALUES ('recert_settings', 'German', 'Rezertifizierungseinstellungen'); INSERT INTO txt VALUES ('recert_settings', 'English', 'Recertification Settings'); INSERT INTO txt VALUES ('save_settings', 'German', 'Einstellungen speichern'); INSERT INTO txt VALUES ('save_settings', 'English', 'Save settings'); -INSERT INTO txt VALUES ('available_states', 'German', 'Verfügbare Stati'); +INSERT INTO txt VALUES ('available_states', 'German', 'Verfügbare Status'); INSERT INTO txt VALUES ('available_states', 'English', 'Available states'); INSERT INTO txt VALUES ('add_state', 'German', 'Status hinzufügen'); INSERT INTO txt VALUES ('add_state', 'English', 'Add state'); @@ -1427,11 +2614,11 @@ INSERT INTO txt VALUES ('delete_state', 'German', 'Status löschen INSERT INTO txt VALUES ('delete_state', 'English', 'Delete state'); INSERT INTO txt VALUES ('from_state', 'German', 'Von Status'); INSERT INTO txt VALUES ('from_state', 'English', 'From state'); -INSERT INTO txt VALUES ('to_states', 'German', 'Nach Stati'); +INSERT INTO txt VALUES ('to_states', 'German', 'Nach Status'); INSERT INTO txt VALUES ('to_states', 'English', 'To states'); -INSERT INTO txt VALUES ('allowed_transitions', 'German', 'erlaubte Übergänge'); +INSERT INTO txt VALUES ('allowed_transitions', 'German', 'Erlaubte Übergänge'); INSERT INTO txt VALUES ('allowed_transitions', 'English', 'Allowed transitions'); -INSERT INTO txt VALUES ('special_states', 'German', 'Spezielle Stati'); +INSERT INTO txt VALUES ('special_states', 'German', 'Spezielle Status'); INSERT INTO txt VALUES ('special_states', 'English', 'Special states'); INSERT INTO txt VALUES ('lowest_input_state', 'German', 'Niedrigster Eingangsstatus'); INSERT INTO txt VALUES ('lowest_input_state', 'English', 'Lowest input state'); @@ -1441,8 +2628,28 @@ INSERT INTO txt VALUES ('lowest_end_state', 'German', 'Niedrigster Ausgang INSERT INTO txt VALUES ('lowest_end_state', 'English', 'Lowest exit state'); INSERT INTO txt VALUES ('derived_state', 'German', 'Abgeleiteter Status'); INSERT INTO txt VALUES ('derived_state', 'English', 'Derived state'); +INSERT INTO txt VALUES ('ext_states', 'German', 'Externe Status'); +INSERT INTO txt VALUES ('ext_states', 'English', 'External states'); +INSERT INTO txt VALUES ('save_ext_states', 'German', 'Externe Status speichern'); +INSERT INTO txt VALUES ('save_ext_states', 'English', 'Save external states'); +INSERT INTO txt VALUES ('internal_state_name', 'German', 'Interner Status-Name'); +INSERT INTO txt VALUES ('internal_state_name', 'English', 'Internal State Name'); +INSERT INTO txt VALUES ('external_state_name', 'German', 'Externer Status-Name'); +INSERT INTO txt VALUES ('external_state_name', 'English', 'External State Name'); +INSERT INTO txt VALUES ('assign_state_to', 'German', 'Status zuordnen zu: '); +INSERT INTO txt VALUES ('assign_state_to', 'English', 'Assign state to: '); INSERT INTO txt VALUES ('select_action', 'German', 'Aktion auswählen'); INSERT INTO txt VALUES ('select_action', 'English', 'Select action'); +INSERT INTO txt VALUES ('lifecycle_states', 'German', 'Lifecycle-Status'); +INSERT INTO txt VALUES ('lifecycle_states', 'English', 'Lifecycle States'); +INSERT INTO txt VALUES ('owner_lifecycle_states','German', 'Eigentümer-Lifecycle-Status'); +INSERT INTO txt VALUES ('owner_lifecycle_states','English', 'Owner Lifecycle States'); +INSERT INTO txt VALUES ('add_owner_lc_state', 'German', 'Lifecycle Status hinzufügen'); +INSERT INTO txt VALUES ('add_owner_lc_state', 'English', 'Add Owner Lifecycle State'); +INSERT INTO txt VALUES ('edit_owner_lc_state', 'German', 'Lifecycle Status bearbeiten'); +INSERT INTO txt VALUES ('edit_owner_lc_state', 'English', 'Edit Owner Lifecycle State'); +INSERT INTO txt VALUES ('delete_owner_lc_state','German', 'Lifecycle Status löschen'); +INSERT INTO txt VALUES ('delete_owner_lc_state','English', 'Delete Owner Lifecycle State'); INSERT INTO txt VALUES ('owners', 'German', 'Eigentümer'); INSERT INTO txt VALUES ('owners', 'English', 'Owners'); INSERT INTO txt VALUES ('add_owner', 'German', 'Eigentümer hinzufügen'); @@ -1451,18 +2658,283 @@ INSERT INTO txt VALUES ('edit_owner', 'German', 'Eigentümer bea INSERT INTO txt VALUES ('edit_owner', 'English', 'Edit owner'); INSERT INTO txt VALUES ('delete_owner', 'German', 'Eigentümer löschen'); INSERT INTO txt VALUES ('delete_owner', 'English', 'Delete owner'); +INSERT INTO txt VALUES ('add_rule', 'German', 'Regel hinzufügen'); +INSERT INTO txt VALUES ('add_rule', 'English', 'Add rule'); INSERT INTO txt VALUES ('recert_interval', 'German', 'Rezertintervall (in Tagen)'); INSERT INTO txt VALUES ('recert_interval', 'English', 'Recert Interval (in days)'); INSERT INTO txt VALUES ('ext_app_id', 'German', 'Externe Anwendungs-Id'); INSERT INTO txt VALUES ('ext_app_id', 'English', 'External Application Id'); +INSERT INTO txt VALUES ('requested_ext_app_id', 'German', 'Angeforderte externe Anwendungs-Id'); +INSERT INTO txt VALUES ('requested_ext_app_id', 'English', 'Requested External Application Id'); +INSERT INTO txt VALUES ('requesting_ext_app_id','German', 'Anfordernde externe Anwendungs-Id'); +INSERT INTO txt VALUES ('requesting_ext_app_id','English', 'Requesting External Application Id'); +INSERT INTO txt VALUES ('used_in_connection_ids','German', 'Genutzt in Verbindungs-ID(s)'); +INSERT INTO txt VALUES ('used_in_connection_ids','English', 'Used In Connection ID(s)'); +INSERT INTO txt VALUES ('show_removed_requested_interfaces','German', 'Gelöschte angeforderte Schnittstellen anzeigen'); +INSERT INTO txt VALUES ('show_removed_requested_interfaces','English', 'Show removed requested interfaces'); +INSERT INTO txt VALUES ('criticality', 'German', 'Kritikalität'); +INSERT INTO txt VALUES ('criticality', 'English', 'Criticality'); +INSERT INTO txt VALUES ('comm_svc_possible', 'German', 'Common Service zugelassen'); +INSERT INTO txt VALUES ('comm_svc_possible', 'English', 'Common Service Possible'); +INSERT INTO txt VALUES ('additional_info', 'German', 'Zusätzliche Informationen'); +INSERT INTO txt VALUES ('additional_info', 'English', 'Additional Information'); INSERT INTO txt VALUES ('dn', 'German', 'Vollständiger Name'); INSERT INTO txt VALUES ('dn', 'English', 'Distinguished Name'); +INSERT INTO txt VALUES ('main_responsible', 'German', 'Hauptverantwortlicher (DN)'); +INSERT INTO txt VALUES ('main_responsible', 'English', 'Main responsible person (DN)'); +INSERT INTO txt VALUES ('responsibles', 'German', 'Verantwortliche'); +INSERT INTO txt VALUES ('responsibles', 'English', 'Responsibles'); +INSERT INTO txt VALUES ('allow_modelling', 'German', 'Modelling erlauben'); +INSERT INTO txt VALUES ('allow_modelling', 'English', 'Allow modelling'); +INSERT INTO txt VALUES ('allow_recertification','German', 'Rezertifizierung erlauben'); +INSERT INTO txt VALUES ('allow_recertification','English', 'Allow recertification'); +INSERT INTO txt VALUES ('add_responsible_type', 'German', 'Verantwortlichkeitsstufe hinzufügen'); +INSERT INTO txt VALUES ('add_responsible_type', 'English', 'Add responsible type'); +INSERT INTO txt VALUES ('edit_responsible_type','German', 'Verantwortlichkeitsstufe bearbeiten'); +INSERT INTO txt VALUES ('edit_responsible_type','English', 'Edit responsible type'); +INSERT INTO txt VALUES ('owner_responsible3', 'German', 'Weitere Verantwortliche (DN)'); +INSERT INTO txt VALUES ('owner_responsible3', 'English', 'Additional responsible persons (DN)'); INSERT INTO txt VALUES ('set_default', 'German', 'als Vorgabewert setzen'); INSERT INTO txt VALUES ('set_default', 'English', 'Set as Default'); -INSERT INTO txt VALUES ('reset_to_default', 'German', 'auf Vorgabewerte zurücksetzen'); +INSERT INTO txt VALUES ('reset_to_default', 'German', 'Auf Vorgabewerte zurücksetzen'); INSERT INTO txt VALUES ('reset_to_default', 'English', 'Reset to Default'); INSERT INTO txt VALUES ('option', 'German', 'Option'); INSERT INTO txt VALUES ('option', 'English', 'Option'); +INSERT INTO txt VALUES ('customize_texts', 'German', 'Texte anpassen'); +INSERT INTO txt VALUES ('customize_texts', 'English', 'Customize Texts'); +INSERT INTO txt VALUES ('ignore_helptexts', 'German', 'Hilfetexte ignorieren'); +INSERT INTO txt VALUES ('ignore_helptexts', 'English', 'Ignore help texts'); +INSERT INTO txt VALUES ('case_sensitive', 'German', 'Schreibungsabhängig'); +INSERT INTO txt VALUES ('case_sensitive', 'English', 'Case Sensitive'); +INSERT INTO txt VALUES ('key', 'German', 'Schlüssel'); +INSERT INTO txt VALUES ('key', 'English', 'Key'); +INSERT INTO txt VALUES ('text', 'German', 'Text'); +INSERT INTO txt VALUES ('text', 'English', 'Text'); +INSERT INTO txt VALUES ('custom_text', 'German', 'Angepasster Text'); +INSERT INTO txt VALUES ('custom_text', 'English', 'Custom Text'); +INSERT INTO txt VALUES ('allowServerInConn', 'German', 'Server in Verbindung erlauben'); +INSERT INTO txt VALUES ('allowServerInConn', 'English', 'Allow Servers in Connection'); +INSERT INTO txt VALUES ('allowServiceInConn', 'German', 'Einfache Dienste in Verbindung erlauben'); +INSERT INTO txt VALUES ('allowServiceInConn', 'English', 'Allow Simple Services in Connection'); +INSERT INTO txt VALUES ('overviewDisplayLines', 'German', 'Max. Anzahl Zeilen in Übersicht'); +INSERT INTO txt VALUES ('overviewDisplayLines', 'English', 'Max. Number of Rows in Overview'); +INSERT INTO txt VALUES ('reducedProtocolSet', 'German', 'Reduzierten Protokollset darstellen'); +INSERT INTO txt VALUES ('reducedProtocolSet', 'English', 'Display reduced Protocol set'); +INSERT INTO txt VALUES ('importAppDataPath', 'German', 'Pfad und Name von Appdaten-Import (ohne Endung)'); +INSERT INTO txt VALUES ('importAppDataPath', 'English', 'Path and Name of App data import (without ending)'); +INSERT INTO txt VALUES ('importAppDataScriptArgs', 'German', 'Skriptparameter (optional)'); +INSERT INTO txt VALUES ('importAppDataScriptArgs', 'English', 'Script parameters (optional)'); +INSERT INTO txt VALUES ('importAppDataSleepTime','German', 'Import Appdaten-Intervall (in Stunden)'); +INSERT INTO txt VALUES ('importAppDataSleepTime','English', 'Import App data sleep time (in hours)'); +INSERT INTO txt VALUES ('ownerDataImportSyncUsers', 'German', 'App-Verantwortliche synchronisieren'); +INSERT INTO txt VALUES ('ownerDataImportSyncUsers', 'English', 'Sync owner responsibles'); +INSERT INTO txt VALUES ('importAppDataStartAt', 'German', 'Import Appdaten-Start'); +INSERT INTO txt VALUES ('importAppDataStartAt', 'English', 'Import App data start at'); +INSERT INTO txt VALUES ('importSubnetDataPath', 'German', 'Pfad und Name von Subnetzdaten-Import (ohne Endung)'); +INSERT INTO txt VALUES ('importSubnetDataPath', 'English', 'Path and Name of subnet data import (without ending)'); +INSERT INTO txt VALUES ('importSubnetDataSleepTime','German','Import Subnetzdaten-Intervall (in Stunden)'); +INSERT INTO txt VALUES ('importSubnetDataSleepTime','English','Import Subnet data sleep time (in hours)'); +INSERT INTO txt VALUES ('importSubnetDataStartAt','German', 'Import Subnetzdaten-Start'); +INSERT INTO txt VALUES ('importSubnetDataStartAt','English','Import Subnet data start at'); +INSERT INTO txt VALUES ('importAppServerDataSuccess', 'German', 'Import von App-Server Daten erfolgreich'); +INSERT INTO txt VALUES ('importAppServerDataSuccess', 'English', 'Import of App-Server Data successfull'); +INSERT INTO txt VALUES ('networkAreaRequired', 'German', 'Netzwerkarea vorgeschrieben'); +INSERT INTO txt VALUES ('networkAreaRequired', 'English', 'Network Area Required'); +INSERT INTO txt VALUES ('modReqInterfaceName', 'German', 'Name der beantragten Schnittstelle'); +INSERT INTO txt VALUES ('modReqInterfaceName', 'English', 'Name of requested interface'); +INSERT INTO txt VALUES ('modReqEmailReceiver', 'German', 'Empfänger der Antragsbenachrichtigung'); +INSERT INTO txt VALUES ('modReqEmailReceiver', 'English', 'Receiver of request email'); +INSERT INTO txt VALUES ('modReqEmailRequesterInCc','German','Antragssteller in CC'); +INSERT INTO txt VALUES ('modReqEmailRequesterInCc','English','Requester in CC'); +INSERT INTO txt VALUES ('modReqEmailOtherAddresses','German','Weitere Email-Adressen'); +INSERT INTO txt VALUES ('modReqEmailOtherAddresses','English','Additional email addresses'); +INSERT INTO txt VALUES ('modEnsureAtLeastOneEmailNotification','German','Mindestens eine Email-Benachrichtigung sicherstellen'); +INSERT INTO txt VALUES ('modEnsureAtLeastOneEmailNotification','English','Ensure at least one email notification can be sent'); +INSERT INTO txt VALUES ('modReqEmailSubject', 'German', 'Titel der Antragsbenachrichtigung'); +INSERT INTO txt VALUES ('modReqEmailSubject', 'English', 'Subject of request emails'); +INSERT INTO txt VALUES ('modReqEmailBody', 'German', 'Text der Antragsbenachrichtigung'); +INSERT INTO txt VALUES ('modReqEmailBody', 'English', 'Body of request emails'); +INSERT INTO txt VALUES ('modUnansweredReqEmailBody','German','Text der Erinnerungsbenachrichtigung'); +INSERT INTO txt VALUES ('modUnansweredReqEmailBody','English','Body of unanswered request emails'); +INSERT INTO txt VALUES ('modReqTicketTitle', 'German', 'Titel des Schnittstellentickets'); +INSERT INTO txt VALUES ('modReqTicketTitle', 'English', 'Title of interface request ticket'); +INSERT INTO txt VALUES ('modReqTaskTitle', 'German', 'Titel des Schnittstellenauftrags'); +INSERT INTO txt VALUES ('modReqTaskTitle', 'English', 'Title of interface request task'); +INSERT INTO txt VALUES ('modDecommEmailReceiver','German', 'Empfänger der Stilllegungsbenachrichtigung'); +INSERT INTO txt VALUES ('modDecommEmailReceiver','English', 'Receiver of decommission email'); +INSERT INTO txt VALUES ('modDecommEmailOtherAddresses','German','Weitere Email-Adressen'); +INSERT INTO txt VALUES ('modDecommEmailOtherAddresses','English','Additional email addresses'); +INSERT INTO txt VALUES ('modDecommEmailSubject','German', 'Titel der Stilllegungsbenachrichtigung'); +INSERT INTO txt VALUES ('modDecommEmailSubject','English', 'Subject of decommission emails'); +INSERT INTO txt VALUES ('modDecommEmailBody', 'German', 'Text der Stilllegungsbenachrichtigung'); +INSERT INTO txt VALUES ('modDecommEmailBody', 'English', 'Body of decommission emails'); +INSERT INTO txt VALUES ('modRolloutActive', 'German', 'Automatische Firewallbeantragung aktivieren'); +INSERT INTO txt VALUES ('modRolloutActive', 'English', 'Activate automatic Firewall request'); +INSERT INTO txt VALUES ('modRolloutResolveServiceGroups','German','Servicegruppen auflösen'); +INSERT INTO txt VALUES ('modRolloutResolveServiceGroups','English','Resolve service groups'); +INSERT INTO txt VALUES ('modRolloutBundleTasks','German', 'Tasks zusammenfassen'); +INSERT INTO txt VALUES ('modRolloutBundleTasks','English', 'Bundle tasks'); +INSERT INTO txt VALUES ('modRolloutNatHeuristic','German', 'NAT Heuristik'); +INSERT INTO txt VALUES ('modRolloutNatHeuristic','English', 'NAT Heuristic'); +INSERT INTO txt VALUES ('modRolloutRemovedAppServers','German','Gelöschte App Server ausrollen'); +INSERT INTO txt VALUES ('modRolloutRemovedAppServers','English','Rollout removed App Servers'); +INSERT INTO txt VALUES ('modRequestOnlyOwnObjects','German','Nur eigene Objekte beantragen'); +INSERT INTO txt VALUES ('modRequestOnlyOwnObjects','English','Request only own objects'); +INSERT INTO txt VALUES ('modRolloutErrorText', 'German', 'Fehlertext'); +INSERT INTO txt VALUES ('modRolloutErrorText', 'English', 'Error text'); +INSERT INTO txt VALUES ('modelledMarker', 'German', 'Markierung Modelliert'); +INSERT INTO txt VALUES ('modelledMarker', 'English', 'Modelled marker'); +INSERT INTO txt VALUES ('modelledMarkerLocation','German', 'Ort Markierung'); +INSERT INTO txt VALUES ('modelledMarkerLocation','English', 'Marker Location'); +INSERT INTO txt VALUES ('modRecertActive', 'German', 'Integrierte Rezertifizierung aktivieren'); +INSERT INTO txt VALUES ('modRecertActive', 'English', 'Activate Integrated Recertification'); +INSERT INTO txt VALUES ('modRecertExpectAllModelled','German','Alle Regeln modelliert erwarten'); +INSERT INTO txt VALUES ('modRecertExpectAllModelled','English','Expect all rules as modelled'); +INSERT INTO txt VALUES ('modRecertText', 'German', 'Rezertifizierungstext'); +INSERT INTO txt VALUES ('modRecertText', 'English', 'Recertification Text'); +INSERT INTO txt VALUES ('fixedPartLength', 'German', 'Länge fixer Teil'); +INSERT INTO txt VALUES ('fixedPartLength', 'English', 'Fixed Part Length'); +INSERT INTO txt VALUES ('freePartLength', 'German', 'Länge freier Teil'); +INSERT INTO txt VALUES ('freePartLength', 'English', 'Free Part Length'); +INSERT INTO txt VALUES ('useAppPart', 'German', 'Eigentümernamen verwenden'); +INSERT INTO txt VALUES ('useAppPart', 'English', 'Use Owner Name'); +INSERT INTO txt VALUES ('networkAreaPattern', 'German', 'Muster Netzwerkarea'); +INSERT INTO txt VALUES ('networkAreaPattern', 'English', 'Network Area Pattern'); +INSERT INTO txt VALUES ('appRolePattern', 'German', 'Muster App Rolle'); +INSERT INTO txt VALUES ('appRolePattern', 'English', 'App Role Pattern'); +INSERT INTO txt VALUES ('appServerPrefix', 'German', 'App Server Namenspräfix'); +INSERT INTO txt VALUES ('appServerPrefix', 'English', 'App Server Name Prefix'); +INSERT INTO txt VALUES ('networkPrefix', 'German', 'Namenspräfix IP-Netzwerk'); +INSERT INTO txt VALUES ('networkPrefix', 'English', 'Network Name Prefix'); +INSERT INTO txt VALUES ('ipRangePrefix', 'German', 'Namenspräfix IP-Bereich'); +INSERT INTO txt VALUES ('ipRangePrefix', 'English', 'IP Range Name Prefix'); +INSERT INTO txt VALUES ('dns_lookup', 'German', 'DNS-Suche'); +INSERT INTO txt VALUES ('dns_lookup', 'English', 'DNS Look-up'); +INSERT INTO txt VALUES ('overwrite_exiting_names','German', 'Existierende Namen überschreiben'); +INSERT INTO txt VALUES ('overwrite_exiting_names','English','Overwrite Existing Names'); +INSERT INTO txt VALUES ('auto_replace_app_server','German', 'App Server umhängen'); +INSERT INTO txt VALUES ('auto_replace_app_server','English','Replace App Servers'); +INSERT INTO txt VALUES ('import_source', 'German', 'Importquelle'); +INSERT INTO txt VALUES ('import_source', 'English', 'Import Source'); +INSERT INTO txt VALUES ('modelling_settings', 'German', 'Modellierungseinstellungen'); +INSERT INTO txt VALUES ('modelling_settings', 'English', 'Modelling Settings'); +INSERT INTO txt VALUES ('rule_recognition_options','German','Regelerkennungs-Optionen'); +INSERT INTO txt VALUES ('rule_recognition_options','English','Rule Recognition Options'); +INSERT INTO txt VALUES ('port_protocol', 'German', 'Port und Protokoll'); +INSERT INTO txt VALUES ('port_protocol', 'English', 'Port and Protocol'); +INSERT INTO txt VALUES ('group_name', 'German', 'Gruppenname'); +INSERT INTO txt VALUES ('group_name', 'English', 'Group Name'); +INSERT INTO txt VALUES ('resolve_group', 'German', 'Gruppen auflösen'); +INSERT INTO txt VALUES ('resolve_group', 'English', 'Resolve Groups'); +INSERT INTO txt VALUES ('separate_analysis', 'German', 'Gruppenanalyse trennen'); +INSERT INTO txt VALUES ('separate_analysis', 'English', 'Separate Group analysis'); +INSERT INTO txt VALUES ('split_port_ranges', 'German', 'Portbereiche auflösen'); +INSERT INTO txt VALUES ('split_port_ranges', 'English', 'Split Port Ranges'); +INSERT INTO txt VALUES ('ext_ticketing', 'German', 'Externes Ticket-System'); +INSERT INTO txt VALUES ('ext_ticketing', 'English', 'External ticket tool'); +INSERT INTO txt VALUES ('ext_ticket_settings', 'German', 'Einstellungen externes Ticket-System'); +INSERT INTO txt VALUES ('ext_ticket_settings', 'English', 'Settings external ticket tool'); +INSERT INTO txt VALUES ('modIconify', 'German', 'Nutzung von Piktogrammen'); +INSERT INTO txt VALUES ('modIconify', 'English', 'Prefer use of Icons'); +INSERT INTO txt VALUES ('use_in_src', 'German', 'in Quelle'); +INSERT INTO txt VALUES ('use_in_src', 'English', 'in Source'); +INSERT INTO txt VALUES ('use_in_dst', 'German', 'in Ziel'); +INSERT INTO txt VALUES ('use_in_dst', 'English', 'in Destination'); +INSERT INTO txt VALUES ('email_subject', 'German', 'Email-Betreff'); +INSERT INTO txt VALUES ('email_subject', 'English', 'Email subject'); +INSERT INTO txt VALUES ('email_body', 'German', 'Email-Inhalt'); +INSERT INTO txt VALUES ('email_body', 'English', 'Email body'); +INSERT INTO txt VALUES ('email_to', 'German', 'An'); +INSERT INTO txt VALUES ('email_to', 'English', 'To'); +INSERT INTO txt VALUES ('email_cc', 'German', 'CC'); +INSERT INTO txt VALUES ('email_cc', 'English', 'CC'); +INSERT INTO txt VALUES ('app_zone_pattern', 'German', 'Muster App Zone'); +INSERT INTO txt VALUES ('app_zone_pattern', 'English', 'App Zone Pattern'); +INSERT INTO txt VALUES ('app_zone_creation', 'German', 'App Zonen Objekte erstellen'); +INSERT INTO txt VALUES ('app_zone_creation', 'English', 'Create App Zone Objects'); +INSERT INTO txt VALUES ('appserver_import', 'German', 'App server import'); +INSERT INTO txt VALUES ('appserver_import', 'English', 'App server import'); +INSERT INTO txt VALUES ('select_file', 'German', 'Datei auswählen'); +INSERT INTO txt VALUES ('select_file', 'English', 'Select file'); +INSERT INTO txt VALUES ('availableReportTypes', 'German', 'Verfügbare Reporttypen'); +INSERT INTO txt VALUES ('availableReportTypes', 'English', 'Available Report Types'); +INSERT INTO txt VALUES ('varianceAnalysisSync', 'German', 'Synchroner Soll-Ist-Abgleich'); +INSERT INTO txt VALUES ('varianceAnalysisSync', 'English', 'Synchroneous Variance Analysis'); +INSERT INTO txt VALUES ('varianceAnalysisRefresh','German', 'Soll-Ist-Abgleich auf Schaltfläche'); +INSERT INTO txt VALUES ('varianceAnalysisRefresh','English','Variance Analysis Refresh Button'); +INSERT INTO txt VALUES ('varianceAnalysisSleepTime','German','Soll-Ist-Abgleich-Intervall (in Minuten)'); +INSERT INTO txt VALUES ('varianceAnalysisSleepTime','English','Variance Analysis sleep time (in minutes)'); +INSERT INTO txt VALUES ('varianceAnalysisStartAt','German', 'Soll-Ist-Abgleich-Start'); +INSERT INTO txt VALUES ('varianceAnalysisStartAt','English','Variance Analysis start at'); +INSERT INTO txt VALUES ('resolveNetworkAreas', 'German', 'Netzbereiche auflösen'); +INSERT INTO txt VALUES ('resolveNetworkAreas', 'English', 'Resolve Network Areas'); +INSERT INTO txt VALUES ('complianceCheckSleepTime','German','Compliance-Check-Intervall (in Minuten)'); +INSERT INTO txt VALUES ('complianceCheckSleepTime','English','Compliance Check sleep time (in minutes)'); +INSERT INTO txt VALUES ('complianceCheckStartAt','German', 'Compliance-Check-Start'); +INSERT INTO txt VALUES ('complianceCheckStartAt','English',' Compliance Check start at'); +INSERT INTO txt VALUES ('complianceCheckMailRecipients','German','Empfänger-Email-Adressen für Benachrichtigungen'); +INSERT INTO txt VALUES ('complianceCheckMailRecipients','English','Recipient email addresses for notifications'); +INSERT INTO txt VALUES ('complianceCheckMailSubject','German','Titel der Benachrichtigung'); +INSERT INTO txt VALUES ('complianceCheckMailSubject','English','Subject of notification emails'); +INSERT INTO txt VALUES ('complianceCheckMailBody','German', 'Text der Benachrichtigung'); +INSERT INTO txt VALUES ('complianceCheckMailBody','English','Body of notification emails'); +INSERT INTO txt VALUES ('complianceMatrixAllowNetworkZones','German', 'Netzwerkzonenverschachtelung erlauben'); +INSERT INTO txt VALUES ('complianceMatrixAllowNetworkZones','English','Nested Network Zones allowed'); +INSERT INTO txt VALUES ('complianceCheckInternetZoneObject','German', 'Internetzone'); +INSERT INTO txt VALUES ('complianceCheckInternetZoneObject','English','Internet zone'); +INSERT INTO txt VALUES ('complianceCheckMaxPrintedViolations','German', 'Maximale Anzahl gedruckter Verstöße pro Regel'); +INSERT INTO txt VALUES ('complianceCheckMaxPrintedViolations','English','Maximum number of printed violations per rule'); +INSERT INTO txt VALUES ('complianceCheckSortMatrixByID', 'German', 'Matrixsortierung nach Zonen-ID'); +INSERT INTO txt VALUES ('complianceCheckSortMatrixByID', 'English', 'Matrix sorting by zone ID'); +INSERT INTO txt VALUES ('complianceCheckRelevantManagements','German', 'Relevante Managements'); +INSERT INTO txt VALUES ('complianceCheckRelevantManagements','English','Relevant managements'); +INSERT INTO txt VALUES ('complianceCheckAutoCalcInternetZone','German', 'Internetzone automatisch berechnen'); +INSERT INTO txt VALUES ('complianceCheckAutoCalcInternetZone','English','Auto-calculate internet zone'); +INSERT INTO txt VALUES ('complianceCheckAutoCalcUndefinedInternalZone','German', 'Undefiniert-intern Zone automatisch berechnen'); +INSERT INTO txt VALUES ('complianceCheckAutoCalcUndefinedInternalZone','English','Auto-calculate undefined-internal zone'); +INSERT INTO txt VALUES ('complianceCheckExcludeFromInternetZone','German', 'Von Internetzonenberechnung ausschließen'); +INSERT INTO txt VALUES ('complianceCheckExcludeFromInternetZone','English','Exclude from internet zone calculation'); +INSERT INTO txt VALUES ('complianceCheckPrivateAdressSpace','German', 'Privater Adressbereich'); +INSERT INTO txt VALUES ('complianceCheckPrivateAdressSpace','English','Private address space'); +INSERT INTO txt VALUES ('complianceCheckLoopbackLocal','German', 'Loopback / local'); +INSERT INTO txt VALUES ('complianceCheckLoopbackLocal','English','Loopback / lokal'); +INSERT INTO txt VALUES ('complianceCheckMulticastBroadcast','German', 'Multicast / Broadcast'); +INSERT INTO txt VALUES ('complianceCheckMulticastBroadcast','English','Multicast / broadcast'); +INSERT INTO txt VALUES ('complianceCheckDocumentationSamples','German', 'Dokumentation / Beispiele'); +INSERT INTO txt VALUES ('complianceCheckDocumentationSamples','English','Documentation / samples'); +INSERT INTO txt VALUES ('complianceCheckDiv','German', 'Div (Benchmarking, Spezialzweck usw.)'); +INSERT INTO txt VALUES ('complianceCheckDiv','English','Div (benchmarking, special purpose, etc)'); +INSERT INTO txt VALUES ('complianceCheckAutoCalculatedZonesAtTheEnd','German', 'Auto-kalkulierte Zonen nach anderen Zonen anordnen'); +INSERT INTO txt VALUES ('complianceCheckAutoCalculatedZonesAtTheEnd','English','Arrange auto-calculated zones according to other zones'); +INSERT INTO txt VALUES ('complianceCheckTreatDynamicAndDomainObjectsAsInternet','German', 'Behandel dynamische und Domain-Objekte als Internet'); +INSERT INTO txt VALUES ('complianceCheckTreatDynamicAndDomainObjectsAsInternet','English','Treat dynamic and domain objects as internet'); +INSERT INTO txt VALUES ('complianceCheckShowShortColumsInComplianceReports','German', 'Spalten mit Kurzform für Sources, Destinations und Services anzeigen'); +INSERT INTO txt VALUES ('complianceCheckShowShortColumsInComplianceReports','English','Show columns with short forms for sources, destinations and services'); +INSERT INTO txt VALUES ('importedMatrixReadOnly','German', 'Importierte Matrizen schreibgeschützt'); +INSERT INTO txt VALUES ('importedMatrixReadOnly','English','Imported matrices read-only'); +INSERT INTO txt VALUES ('filterOutInitialViolations','German', 'Filtere initiale Violations raus'); +INSERT INTO txt VALUES ('filterOutInitialViolations','English','Filter out initial violations'); + +INSERT INTO txt VALUES ('availableModules', 'German', 'Verfügbare Module'); +INSERT INTO txt VALUES ('availableModules', 'English', 'Available Modules'); +INSERT INTO txt VALUES ('notification', 'German', 'Benachrichtigung'); +INSERT INTO txt VALUES ('notification', 'English', 'Notification'); +INSERT INTO txt VALUES ('notifications', 'German', 'Benachrichtigungen'); +INSERT INTO txt VALUES ('notifications', 'English', 'Notifications'); +INSERT INTO txt VALUES ('reminders', 'German', 'Erinnerungsbenachrichtigungen'); +INSERT INTO txt VALUES ('reminders', 'English', 'Reminders'); +INSERT INTO txt VALUES ('edit_notification', 'German', 'Benachrichtigung bearbeiten'); +INSERT INTO txt VALUES ('edit_notification', 'English', 'Edit Notification'); +INSERT INTO txt VALUES ('delete_notification', 'German', 'Benachrichtigung löschen'); +INSERT INTO txt VALUES ('delete_notification', 'English', 'Delete Notification'); +INSERT INTO txt VALUES ('last_sent', 'German', 'Zuletzt gesendet'); +INSERT INTO txt VALUES ('last_sent', 'English', 'Last sent'); +INSERT INTO txt VALUES ('reset_notification', 'German', 'Zurücksetzen'); +INSERT INTO txt VALUES ('reset_notification', 'English', 'Reset'); +INSERT INTO txt VALUES ('set_roles_with_import','German', 'Beim Import zu setzende Rollen'); +INSERT INTO txt VALUES ('set_roles_with_import','English', 'Set Roles with import'); +INSERT INTO txt VALUES ('no_owners', 'German', 'Keine Eigentümer zur Auswahl'); +INSERT INTO txt VALUES ('no_owners', 'English', 'No owners to be selected'); -- monitoring INSERT INTO txt VALUES ('open_alerts', 'German', 'Offene Alarme'); @@ -1483,6 +2955,8 @@ INSERT INTO txt VALUES ('suspected_cause', 'German', 'Vermutliche Ursache' INSERT INTO txt VALUES ('suspected_cause', 'English', 'Suspected Cause'); INSERT INTO txt VALUES ('device', 'German', 'Gerät'); INSERT INTO txt VALUES ('device', 'English', 'Device'); +INSERT INTO txt VALUES ('enforcing_devices', 'German', 'Filter-Devices'); +INSERT INTO txt VALUES ('enforcing_devices', 'English', 'Enforcing Devices'); INSERT INTO txt VALUES ('object_type', 'German', 'Objekt-Typ'); INSERT INTO txt VALUES ('object_type', 'English', 'Object Type'); INSERT INTO txt VALUES ('object_name', 'German', 'Objektname'); @@ -1497,6 +2971,10 @@ INSERT INTO txt VALUES ('import', 'German', 'Import'); INSERT INTO txt VALUES ('import', 'English', 'Import'); INSERT INTO txt VALUES ('import_logs', 'German', 'Import-Logs'); INSERT INTO txt VALUES ('import_logs', 'English', 'Import Logs'); +INSERT INTO txt VALUES ('app_data_import_logs', 'German', 'Eigentümer-Daten Import-Logs'); +INSERT INTO txt VALUES ('app_data_import_logs', 'English', 'Owner Data Import Logs'); +INSERT INTO txt VALUES ('area_ip_data_import_logs','German','Subnetzdaten Import-Logs'); +INSERT INTO txt VALUES ('area_ip_data_import_logs','English','Subnet Data Import Logs'); INSERT INTO txt VALUES ('import_status', 'German', 'Import-Status'); INSERT INTO txt VALUES ('import_status', 'English', 'Import Status'); INSERT INTO txt VALUES ('ui_messages', 'German', 'UI-Nachrichten'); @@ -1521,6 +2999,10 @@ INSERT INTO txt VALUES ('acknowledge_alert', 'German', 'Alarm bestätige INSERT INTO txt VALUES ('acknowledge_alert', 'English', 'Acknowledge alert'); INSERT INTO txt VALUES ('acknowledge_action', 'German', 'Aktion bestätigen'); INSERT INTO txt VALUES ('acknowledge_action', 'English', 'Acknowledge action'); +INSERT INTO txt VALUES ('acknowledge_all', 'German', 'Alle bestätigen'); +INSERT INTO txt VALUES ('acknowledge_all', 'English', 'Acknowledge all'); +INSERT INTO txt VALUES ('alerts_acknowledged', 'German', 'Alarme bestätigt'); +INSERT INTO txt VALUES ('alerts_acknowledged', 'English', 'alerts acknowledged'); INSERT INTO txt VALUES ('confirm', 'German', 'Bestätigen'); INSERT INTO txt VALUES ('confirm', 'English', 'Confirm'); INSERT INTO txt VALUES ('found_by', 'German', 'Gefunden von'); @@ -1579,7 +3061,100 @@ INSERT INTO txt VALUES ('changes_found', 'German', ' Änderungen gef INSERT INTO txt VALUES ('changes_found', 'English', ' changes found'); INSERT INTO txt VALUES ('found_no_changes', 'German', 'keine Änderungen gefunden'); INSERT INTO txt VALUES ('found_no_changes', 'English', 'no changes found'); - +INSERT INTO txt VALUES ('scheduled_app_import', 'German', 'Termingesteuerter App-Import'); +INSERT INTO txt VALUES ('scheduled_app_import', 'English', 'Scheduled App Import'); +INSERT INTO txt VALUES ('adjust_app_server_name','German', 'Termingesteuerte AppServer-Namensanpassung'); +INSERT INTO txt VALUES ('adjust_app_server_name','English', 'Scheduled AppServer Name adjustment'); +INSERT INTO txt VALUES ('scheduled_subnet_import','German', 'Termingesteuerter Subnetz-Import'); +INSERT INTO txt VALUES ('scheduled_subnet_import','English','Scheduled Subnet Import'); +INSERT INTO txt VALUES ('imp_change_notification','German', 'Änderungsbenachrichtigung'); +INSERT INTO txt VALUES ('imp_change_notification','English','Import Change Notification'); +INSERT INTO txt VALUES ('scheduled_var_analysis','German', 'Termingesteuerter Soll-Ist-Abgleich'); +INSERT INTO txt VALUES ('scheduled_var_analysis','English', 'Scheduled Variance Analysis'); +INSERT INTO txt VALUES ('credentials', 'German', 'Login-Daten'); +INSERT INTO txt VALUES ('credentials', 'English', 'Credentials'); +INSERT INTO txt VALUES ('external_request', 'German', 'Externer Auftrag'); +INSERT INTO txt VALUES ('external_request', 'English', 'External Request'); +INSERT INTO txt VALUES ('external_requests', 'German', 'Externe Aufträge'); +INSERT INTO txt VALUES ('external_requests', 'English', 'External Requests'); +INSERT INTO txt VALUES ('request_content', 'German', 'Auftragsinhalt'); +INSERT INTO txt VALUES ('request_content', 'English', 'Request content'); +INSERT INTO txt VALUES ('bundled_tasks', 'German', 'Gebündelte Aufträge'); +INSERT INTO txt VALUES ('bundled_tasks', 'English', 'Bundled tasks'); +INSERT INTO txt VALUES ('last_creation_response','German', 'Letzte Erzeugungsnachricht'); +INSERT INTO txt VALUES ('last_creation_response','English', 'Last creation response'); +INSERT INTO txt VALUES ('last_process_response','German', 'Letzte Abwicklungsnachricht'); +INSERT INTO txt VALUES ('last_process_response','English', 'Last processing response'); +INSERT INTO txt VALUES ('ext_ticket_system', 'German', 'Externes Ticketing System'); +INSERT INTO txt VALUES ('ext_ticket_system', 'English', 'External ticketing system'); +INSERT INTO txt VALUES ('ext_request_tickets', 'German', 'Interne Tickets für Ext. Auftr.'); +INSERT INTO txt VALUES ('ext_request_tickets', 'English', 'Internal Tickets for Ext. Req.'); +INSERT INTO txt VALUES ('reinit_ext_request', 'German', 'Externe Aufträge neu anstossen'); +INSERT INTO txt VALUES ('reinit_ext_request', 'English', 'Reinit External Requests'); +INSERT INTO txt VALUES ('reject_ticket', 'German', 'Auftrag als abgelehnt schliessen'); +INSERT INTO txt VALUES ('reject_ticket', 'English', 'Close Ticket as rejected'); +INSERT INTO txt VALUES ('reject_tickets', 'German', 'Aufträge als abgelehnt schliessen'); +INSERT INTO txt VALUES ('reject_tickets', 'English', 'Close Tickets as rejected'); +INSERT INTO txt VALUES ('orphaned_requested_interface_tickets', 'German', 'Offene Tickets zu gelöschten angeforderten Schnittstellen'); +INSERT INTO txt VALUES ('orphaned_requested_interface_tickets', 'English', 'Open tickets for deleted requested interfaces'); +INSERT INTO txt VALUES ('orphaned_requested_interface_tickets_empty', 'German', 'Es wurden keine offenen Tickets zu gelöschten angeforderten Schnittstellen gefunden.'); +INSERT INTO txt VALUES ('orphaned_requested_interface_tickets_empty', 'English', 'No open tickets for deleted requested interfaces were found.'); +INSERT INTO txt VALUES ('wait_cycles', 'German', 'Wartezyklen'); +INSERT INTO txt VALUES ('wait_cycles', 'English', 'Wait cycles'); +INSERT INTO txt VALUES ('attempts', 'German', 'Versuche'); +INSERT INTO txt VALUES ('attempts', 'English', 'Attempts'); +INSERT INTO txt VALUES ('locked', 'German', 'Gesperrt'); +INSERT INTO txt VALUES ('locked', 'English', 'Locked'); +INSERT INTO txt VALUES ('unlock', 'German', 'Entsperren'); +INSERT INTO txt VALUES ('unlock', 'English', 'Unlock'); +INSERT INTO txt VALUES ('useCustomLogo', 'German', 'Benutzerdefiniertes Logo'); +INSERT INTO txt VALUES ('useCustomLogo', 'English', 'Custom logo'); +INSERT INTO txt VALUES ('object_users', 'German', 'Nutzer von Objekten'); +INSERT INTO txt VALUES ('object_users', 'English', 'Object Users'); +INSERT INTO txt VALUES ('scheduler_jobs_title', 'German', 'Scheduler-Jobs'); +INSERT INTO txt VALUES ('scheduler_jobs_title', 'English', 'Scheduler Jobs'); +INSERT INTO txt VALUES ('scheduler_jobs_description', 'German', 'Admin-Benutzer können Scheduler-Jobs sofort ausführen.'); +INSERT INTO txt VALUES ('scheduler_jobs_description', 'English', 'Admin users can run scheduler jobs immediately.'); +INSERT INTO txt VALUES ('scheduler_interval', 'German', 'Intervall'); +INSERT INTO txt VALUES ('scheduler_interval', 'English', 'Interval'); +INSERT INTO txt VALUES ('scheduler_last_run', 'German', 'Letzte Ausführung'); +INSERT INTO txt VALUES ('scheduler_last_run', 'English', 'Last run'); +INSERT INTO txt VALUES ('scheduler_next_run', 'German', 'Nächste Ausführung'); +INSERT INTO txt VALUES ('scheduler_next_run', 'English', 'Next run'); +INSERT INTO txt VALUES ('scheduler_status', 'German', 'Status'); +INSERT INTO txt VALUES ('scheduler_status', 'English', 'Status'); +INSERT INTO txt VALUES ('scheduler_action', 'German', 'Aktion'); +INSERT INTO txt VALUES ('scheduler_action', 'English', 'Action'); +INSERT INTO txt VALUES ('scheduler_no_jobs', 'German', 'Keine Scheduler-Jobs verfügbar.'); +INSERT INTO txt VALUES ('scheduler_no_jobs', 'English', 'No scheduler jobs available.'); +INSERT INTO txt VALUES ('scheduler_starting', 'German', 'Startet bald…'); +INSERT INTO txt VALUES ('scheduler_starting', 'English', 'Starting soon…'); +INSERT INTO txt VALUES ('scheduler_start_now', 'German', 'Jetzt starten'); +INSERT INTO txt VALUES ('scheduler_start_now', 'English', 'Start now'); +INSERT INTO txt VALUES ('scheduler_now', 'German', 'Jetzt'); +INSERT INTO txt VALUES ('scheduler_now', 'English', 'Now'); +INSERT INTO txt VALUES ('scheduler_interval_description', 'German', 'Alle'); +INSERT INTO txt VALUES ('scheduler_interval_description', 'English', 'Every'); +INSERT INTO txt VALUES ('orphaned_app_roles', 'German', 'Verwaiste App Regeln'); +INSERT INTO txt VALUES ('orphaned_app_roles', 'English', 'Orphaned App Roles'); +INSERT INTO txt VALUES ('orphaned_app_servers', 'German', 'Verwaiste App Server'); +INSERT INTO txt VALUES ('orphaned_app_servers', 'English', 'Orphaned App Servers'); +INSERT INTO txt VALUES ('orphaned_network_areas','German', 'Verwaiste Netzwerk-Areas'); +INSERT INTO txt VALUES ('orphaned_network_areas','English', 'Orphaned Network Areas'); +INSERT INTO txt VALUES ('orphaned_view', 'German', 'Nur Verwaiste anzeigen'); +INSERT INTO txt VALUES ('orphaned_view', 'English', 'Show orphaned only'); +INSERT INTO txt VALUES ('remove_all_orphans', 'German', 'Alle Verwaisten entfernen'); +INSERT INTO txt VALUES ('remove_all_orphans', 'English', 'Remove all orphans'); +INSERT INTO txt VALUES ('orphaned_services', 'German', 'Verwaiste Dienste'); +INSERT INTO txt VALUES ('orphaned_services', 'English', 'Orphaned Services'); +INSERT INTO txt VALUES ('orphaned_service_groups', 'German', 'Verwaiste Servicegruppen'); +INSERT INTO txt VALUES ('orphaned_service_groups','English','Orphaned Service Groups'); +INSERT INTO txt VALUES ('orphaned_entries_removed', 'German', 'Verwaiste Einträge entfernt'); +INSERT INTO txt VALUES ('orphaned_entries_removed', 'English', 'Orphaned entries removed'); +INSERT INTO txt VALUES ('network_area', 'German', 'Netzwerk-Area'); +INSERT INTO txt VALUES ('network_area', 'English', 'Network Area'); +INSERT INTO txt VALUES ('network_areas', 'German', 'Netzwerk-Areas'); +INSERT INTO txt VALUES ('network_areas', 'English', 'Network Areas'); -- help pages INSERT INTO txt VALUES ('report_types', 'German', 'Report-Typen'); @@ -1622,141 +3197,88 @@ INSERT INTO txt VALUES ('sample_mutation', 'German', 'Beispiel-Mutation'); INSERT INTO txt VALUES ('sample_mutation', 'English', 'Sample Mutation'); INSERT INTO txt VALUES ('admin_access', 'German', 'Admin-Zugang'); INSERT INTO txt VALUES ('admin_access', 'English', 'Admin Access'); -INSERT INTO txt VALUES ('keywords', 'German', 'Schlüsselwörter (alternative Schreibweisen in Klammern)'); -INSERT INTO txt VALUES ('keywords', 'English', 'Keywords (alternative spellings in brackets)'); -INSERT INTO txt VALUES ('operators', 'German', 'Operatoren'); -INSERT INTO txt VALUES ('operators', 'English', 'Operators'); -INSERT INTO txt VALUES ('examples', 'German', 'Beispiele'); -INSERT INTO txt VALUES ('examples', 'English', 'Examples'); -INSERT INTO txt VALUES ('jwt_corr_login', 'German', 'JWT nach korrekter Anmeldung'); -INSERT INTO txt VALUES ('jwt_corr_login', 'English', 'Get JWT with correct login'); -INSERT INTO txt VALUES ('err_incorr_login', 'German', 'Fehler nach inkorrekter Anmeldung'); -INSERT INTO txt VALUES ('err_incorr_login', 'English', 'Error with incorrect login'); -INSERT INTO txt VALUES ('get_with_admin', 'German', 'Holen der Namen aller Firewall-Managements mit Admin-Zugang'); -INSERT INTO txt VALUES ('get_with_admin', 'English', 'Get the names of all firewall managements using admin access'); -INSERT INTO txt VALUES ('get_with_jwt', 'German', 'Holen der Namen aller Firewall-Managements mit Standard-JWT-Zugang'); -INSERT INTO txt VALUES ('get_with_jwt', 'English', 'Get the names of all firewall managements using standard JWT access'); -INSERT INTO txt VALUES ('get_with_jwt_role', 'German', 'Holen der Namen aller Firewall-Managements mit Standard-JWT-Zugang und spezifischer Rolle'); -INSERT INTO txt VALUES ('get_with_jwt_role', 'English', 'Get the names of all firewall managements using standard JWT access and specifying a certain role'); -INSERT INTO txt VALUES ('get_single_dev_rules', 'German', 'Alle aktuellen Regeln von Gateway mit ID 1 holen'); -INSERT INTO txt VALUES ('get_single_dev_rules', 'English', 'Get all current rules of gateway with ID 1'); -INSERT INTO txt VALUES ('parameters', 'German', 'Parameter'); -INSERT INTO txt VALUES ('parameters', 'English', 'Parameters'); -INSERT INTO txt VALUES ('introduction', 'German', 'Einführung'); -INSERT INTO txt VALUES ('introduction', 'English', 'Introduction'); -INSERT INTO txt VALUES ('architecture', 'German', 'Die Firewall Orchestrator Architektur'); -INSERT INTO txt VALUES ('architecture', 'English', 'Firewall Orchestrator Architecture'); -INSERT INTO txt VALUES ('phases_roles', 'German', 'Phasen und Rollen'); -INSERT INTO txt VALUES ('phases_roles', 'English', 'Phases and Roles'); -INSERT INTO txt VALUES ('task_types', 'German', 'Auftragstypen'); -INSERT INTO txt VALUES ('task_types', 'English', 'Task Types'); -INSERT INTO txt VALUES ('state_handling', 'German', 'Status-Verwaltung'); -INSERT INTO txt VALUES ('state_handling', 'English', 'State Handling'); -INSERT INTO txt VALUES ('checklist', 'German', 'Checkliste'); -INSERT INTO txt VALUES ('checklist', 'English', 'Checklist'); -INSERT INTO txt VALUES ('requirements', 'German', 'Voraussetzungen'); -INSERT INTO txt VALUES ('requirements', 'English', 'Requirements'); -INSERT INTO txt VALUES ('recert_logic', 'German', 'Logik und Konfiguration'); -INSERT INTO txt VALUES ('recert_logic', 'English', 'Logic and Configuration'); -INSERT INTO txt VALUES ('configuration', 'German', 'Konfiguration'); -INSERT INTO txt VALUES ('configuration', 'English', 'Configuration'); -INSERT INTO txt VALUES ('owner_import', 'German', 'Eigentümer-Import'); -INSERT INTO txt VALUES ('owner_import', 'English', 'Owner Import'); --- compliance -INSERT INTO txt VALUES ('compliance', 'German', 'Compliance'); -INSERT INTO txt VALUES ('compliance', 'English', 'Compliance'); -INSERT INTO txt VALUES ('network_zones', 'German', 'Netzwerkzonen'); -INSERT INTO txt VALUES ('network_zones', 'English', 'Network zones'); -INSERT INTO txt VALUES ('matrix', 'German', 'Matrix'); -INSERT INTO txt VALUES ('matrix', 'English', 'Matrix'); -INSERT INTO txt VALUES ('checks', 'German', 'Überprüfung'); -INSERT INTO txt VALUES ('checks', 'English', 'Checks'); -INSERT INTO txt VALUES ('check', 'German', 'Überprüfen'); -INSERT INTO txt VALUES ('check', 'English', 'Check'); -INSERT INTO txt VALUES ('zone_comm_matrix', 'German', 'Netzwerkzonen-Kommunikationsmatrix'); -INSERT INTO txt VALUES ('zone_comm_matrix', 'English', 'Network zone communication matrix'); -INSERT INTO txt VALUES ('network_zone_config', 'German', 'Netzwerkzonen-Konfiguration'); -INSERT INTO txt VALUES ('network_zone_config', 'English', 'Network zone configuration'); -INSERT INTO txt VALUES ('network_zone_check', 'German', 'Netzwerkzonen-Complianceprüfung'); -INSERT INTO txt VALUES ('network_zone_check', 'English', 'Network zone compliance check'); -INSERT INTO txt VALUES ('allowed_communication','German', 'Erlaubte Kommunikation'); -INSERT INTO txt VALUES ('allowed_communication','English', 'Allowed communication'); -INSERT INTO txt VALUES ('subzones', 'German', 'Subzonen'); -INSERT INTO txt VALUES ('subzones', 'English', 'Subzones'); -INSERT INTO txt VALUES ('superzone', 'German', 'Superzone'); -INSERT INTO txt VALUES ('superzone', 'English', 'Superzone'); -INSERT INTO txt VALUES ('edit_zone_title', 'German', 'Netzwerkzone editieren'); -INSERT INTO txt VALUES ('edit_zone_title', 'English', 'Edit network zone'); -INSERT INTO txt VALUES ('add_ip_addresses', 'German', 'IP Adresse(n) hinzufügen'); -INSERT INTO txt VALUES ('add_ip_addresses', 'English', 'Add IP Addresses'); -INSERT INTO txt VALUES ('delete_zone_title', 'German', 'Netzwerkzone löschen'); -INSERT INTO txt VALUES ('delete_zone_title', 'English', 'Delete network zone'); -INSERT INTO txt VALUES ('delete_zone_text', 'German', 'Sind Sie sich sicher, dass sie die Netzwerkzone % löschen wollen?'); -INSERT INTO txt VALUES ('delete_zone_text', 'English', 'Are you sure you want to delete the network zone %?'); -INSERT INTO txt VALUES ('to', 'German', 'Nach'); -INSERT INTO txt VALUES ('to', 'English', 'To'); -INSERT INTO txt VALUES ('allowed_comm_dests', 'German', 'Erlaubte Kommunikation (Nach)'); -INSERT INTO txt VALUES ('allowed_comm_dests', 'English', 'Allowed communication (to)'); -INSERT INTO txt VALUES ('allowed_comm_srcs', 'German', 'Erlaubte Kommunikation (Von)'); -INSERT INTO txt VALUES ('allowed_comm_srcs', 'English', 'Allowed communication (from)'); -INSERT INTO txt VALUES ('relogin', 'German', 'Erneut anmelden'); -INSERT INTO txt VALUES ('relogin', 'English', 'Re-Login'); -INSERT INTO txt VALUES ('relogin_error', 'German', 'Fehler bei der erneuten Anmeldung'); -INSERT INTO txt VALUES ('relogin_error', 'English', 'Re-Login error'); -INSERT INTO txt VALUES ('internet_local_zone', 'German', 'Internet / Lokal'); -INSERT INTO txt VALUES ('internet_local_zone', 'English', 'Internet / Local'); -INSERT INTO txt VALUES ('rule_conform', 'German', 'Regelkonform'); -INSERT INTO txt VALUES ('rule_conform', 'English', 'In accordance with the rules'); -INSERT INTO txt VALUES ('rule_violations', 'German', 'Regelverletzungen'); -INSERT INTO txt VALUES ('rule_violations', 'English', 'Rule violations'); -INSERT INTO txt VALUES ('no_network_zones', 'German', 'Es existieren bisher keine Netzwerkzonen. Bitte legen Sie diese im Abschnitt "Konfiguration" an.'); -INSERT INTO txt VALUES ('no_network_zones', 'English', 'No network zones exist yet. Please create them in the "Configuration" section.'); - - --- text codes (roughly) categorized: --- U: user texts (explanation or confirmation texts) --- E: error texts --- A: Api errors --- T: texts from external sources (Ldap, other database tables) --- H: help pages --- 0000-0999: General --- 1000-1999: Reporting --- 2000-2999: Scheduling --- 3000-3999: Archive --- 4000-4999: Recertification --- 5000-5999: Settings --- 5000-5099: general --- 5100-5199: devices --- 5200-5299: authorization --- 5300-5399: defaults --- 5400-5499: personal settings --- 5500-5599: workflow module --- 6000-6999: API --- 7000-7999: Monitoring --- 8000-8999: Workflow - --- generic success messages -INSERT INTO txt VALUES ('S_add_title', 'German', 'Erstellen erfolgreich'); -INSERT INTO txt VALUES ('S_add_title', 'English', 'Creation successful'); -INSERT INTO txt VALUES ('S_add_message', 'German', 'Das Erstellen des Elements wurde erfolgreich abgeschlossen.'); -INSERT INTO txt VALUES ('S_add_message', 'English', 'The creation of the element has been completed successfully.'); - -INSERT INTO txt VALUES ('S_modify_title', 'German', 'Modifizieren erfolgreich'); -INSERT INTO txt VALUES ('S_modify_title', 'English', 'Modification successful'); -INSERT INTO txt VALUES ('S_modify_message', 'German', 'Das Modifizieren des Elements wurde erfolgreich abgeschlossen.'); -INSERT INTO txt VALUES ('S_modify_message', 'English', 'The modification of the element has been completed successfully.'); - -INSERT INTO txt VALUES ('S_delete_title', 'German', 'Löschen erfolgreich'); -INSERT INTO txt VALUES ('S_delete_title', 'English', 'Deletion successful'); -INSERT INTO txt VALUES ('S_delete_message', 'German', 'Das Löschen des Elements wurde erfolgreich abgeschlossen.'); -INSERT INTO txt VALUES ('S_delete_message', 'English', 'The deletion of the element has been completed successfully.'); +INSERT INTO txt VALUES ('keywords', 'German', 'Schlüsselwörter (alternative Schreibweisen in Klammern)'); +INSERT INTO txt VALUES ('keywords', 'English', 'Keywords (alternative spellings in brackets)'); +INSERT INTO txt VALUES ('operators', 'German', 'Operatoren'); +INSERT INTO txt VALUES ('operators', 'English', 'Operators'); +INSERT INTO txt VALUES ('examples', 'German', 'Beispiele'); +INSERT INTO txt VALUES ('examples', 'English', 'Examples'); +INSERT INTO txt VALUES ('jwt_corr_login', 'German', 'JWT nach korrekter Anmeldung'); +INSERT INTO txt VALUES ('jwt_corr_login', 'English', 'Get JWT with correct login'); +INSERT INTO txt VALUES ('err_incorr_login', 'German', 'Fehler nach inkorrekter Anmeldung'); +INSERT INTO txt VALUES ('err_incorr_login', 'English', 'Error with incorrect login'); +INSERT INTO txt VALUES ('get_with_admin', 'German', 'Holen der Namen aller Firewall-Managements mit Admin-Zugang'); +INSERT INTO txt VALUES ('get_with_admin', 'English', 'Get the names of all firewall managements using admin access'); +INSERT INTO txt VALUES ('get_with_jwt', 'German', 'Holen der Namen aller Firewall-Managements mit Standard-JWT-Zugang'); +INSERT INTO txt VALUES ('get_with_jwt', 'English', 'Get the names of all firewall managements using standard JWT access'); +INSERT INTO txt VALUES ('get_with_jwt_role', 'German', 'Holen der Namen aller Firewall-Managements mit Standard-JWT-Zugang und spezifischer Rolle'); +INSERT INTO txt VALUES ('get_with_jwt_role', 'English', 'Get the names of all firewall managements using standard JWT access and specifying a certain role'); +INSERT INTO txt VALUES ('get_single_dev_rules', 'German', 'Alle aktuellen Regeln von Gateway mit ID 1 holen'); +INSERT INTO txt VALUES ('get_single_dev_rules', 'English', 'Get all current rules of gateway with ID 1'); +INSERT INTO txt VALUES ('parameters', 'German', 'Parameter'); +INSERT INTO txt VALUES ('parameters', 'English', 'Parameters'); +INSERT INTO txt VALUES ('introduction', 'German', 'Einführung'); +INSERT INTO txt VALUES ('introduction', 'English', 'Introduction'); +INSERT INTO txt VALUES ('architecture', 'German', 'Die Firewall Orchestrator Architektur'); +INSERT INTO txt VALUES ('architecture', 'English', 'Firewall Orchestrator Architecture'); +INSERT INTO txt VALUES ('phases_roles', 'German', 'Phasen und Rollen'); +INSERT INTO txt VALUES ('phases_roles', 'English', 'Phases and Roles'); +INSERT INTO txt VALUES ('task_types', 'German', 'Auftragstypen'); +INSERT INTO txt VALUES ('task_types', 'English', 'Task Types'); +INSERT INTO txt VALUES ('state_handling', 'German', 'Status-Verwaltung'); +INSERT INTO txt VALUES ('state_handling', 'English', 'State Handling'); +INSERT INTO txt VALUES ('checklist', 'German', 'Checkliste'); +INSERT INTO txt VALUES ('checklist', 'English', 'Checklist'); +INSERT INTO txt VALUES ('requirements', 'German', 'Voraussetzungen'); +INSERT INTO txt VALUES ('requirements', 'English', 'Requirements'); +INSERT INTO txt VALUES ('recert_logic', 'German', 'Logik und Konfiguration'); +INSERT INTO txt VALUES ('recert_logic', 'English', 'Logic and Configuration'); +INSERT INTO txt VALUES ('configuration', 'German', 'Konfiguration'); +INSERT INTO txt VALUES ('configuration', 'English', 'Configuration'); +INSERT INTO txt VALUES ('owner_import', 'German', 'Eigentümer-Import'); +INSERT INTO txt VALUES ('owner_import', 'English', 'Owner Import'); +INSERT INTO txt VALUES ('import_interfaces', 'German', 'Import-Schnittstellen'); +INSERT INTO txt VALUES ('import_interfaces', 'English', 'Import Interfaces'); +INSERT INTO txt VALUES ('import_app_data', 'German', 'Eigentümer-Daten-Import'); +INSERT INTO txt VALUES ('import_app_data', 'English', 'Owner Data Import'); +INSERT INTO txt VALUES ('import_subnet_data', 'German', 'Subnetzdaten-Import'); +INSERT INTO txt VALUES ('import_subnet_data', 'English', 'Subnet Data Import'); +INSERT INTO txt VALUES ('general', 'German', 'Allgemein'); +INSERT INTO txt VALUES ('general', 'English', 'General'); +INSERT INTO txt VALUES ('naming_convention', 'German', 'Namenskonvention'); +INSERT INTO txt VALUES ('naming_convention', 'English', 'Naming Convention'); +INSERT INTO txt VALUES ('import_app_server', 'German', 'App Server importieren'); +INSERT INTO txt VALUES ('import_app_server', 'English', 'Import app servers'); +INSERT INTO txt VALUES ('import_matrix', 'German', 'Matrix-Import'); +INSERT INTO txt VALUES ('import_matrix', 'English', 'Matrix Import'); -- user messages INSERT INTO txt VALUES ('U0001', 'German', 'Eingabetext wurde um nicht erlaubte Zeichen gekürzt'); INSERT INTO txt VALUES ('U0001', 'English', 'Input text has been shortened by not allowed characters'); +INSERT INTO txt VALUES ('U0010', 'German', 'Erstellen erfolgreich'); +INSERT INTO txt VALUES ('U0010', 'English', 'Creation successful'); +INSERT INTO txt VALUES ('U0011', 'German', 'Das Erstellen des Elements wurde erfolgreich abgeschlossen.'); +INSERT INTO txt VALUES ('U0011', 'English', 'The creation of the element has been completed successfully.'); +INSERT INTO txt VALUES ('U0012', 'German', 'Modifizieren erfolgreich'); +INSERT INTO txt VALUES ('U0012', 'English', 'Modification successful'); +INSERT INTO txt VALUES ('U0013', 'German', 'Das Modifizieren des Elements wurde erfolgreich abgeschlossen.'); +INSERT INTO txt VALUES ('U0013', 'English', 'The modification of the element has been completed successfully.'); +INSERT INTO txt VALUES ('U0014', 'German', 'Löschen erfolgreich'); +INSERT INTO txt VALUES ('U0014', 'English', 'Deletion successful'); +INSERT INTO txt VALUES ('U0015', 'German', 'Das Löschen des Elements wurde erfolgreich abgeschlossen.'); +INSERT INTO txt VALUES ('U0015', 'English', 'The deletion of the element has been completed successfully.'); +INSERT INTO txt VALUES ('U0016', 'German', 'Das Fenster kann geschlossen werden.'); +INSERT INTO txt VALUES ('U0016', 'English', 'Window can be closed.'); +INSERT INTO txt VALUES ('U1001', 'German', 'Filter (nur Verbindungen)'); +INSERT INTO txt VALUES ('U1001', 'English', 'Filter (connections only)'); INSERT INTO txt VALUES ('U1002', 'German', 'Sind sie sicher, dass sie folgende Reportvorlage löschen wollen: '); INSERT INTO txt VALUES ('U1002', 'English', 'Do you really want to delete report template'); +INSERT INTO txt VALUES ('U1003', 'German', 'In diesem Report werden nur vollständig modellierte Verbindungen berücksichtigt.'); +INSERT INTO txt VALUES ('U1003', 'English', 'In this report only completely modelled connections are regarded.'); +INSERT INTO txt VALUES ('U1004', 'German', 'Objektänderungen anzeigen'); +INSERT INTO txt VALUES ('U1004', 'English', 'Include object changes'); + INSERT INTO txt VALUES ('U2002', 'German', 'Sind sie sicher, dass sie folgenden Reporttermin löschen wollen: '); INSERT INTO txt VALUES ('U2002', 'English', 'Do you really want to delete report schedule '); @@ -1764,6 +3286,35 @@ INSERT INTO txt VALUES ('U2002', 'English', 'Do you really want to delete report INSERT INTO txt VALUES ('U3002', 'German', 'Sind sie sicher, dass sie folgenden Report löschen wollen: '); INSERT INTO txt VALUES ('U3002', 'English', 'Do you really want to delete generated report '); +INSERT INTO txt VALUES ('U4001', 'German', 'Sind sie sicher, dass sie folgende Benachrichtigung löschen wollen: '); +INSERT INTO txt VALUES ('U4001', 'English', 'Do you really want to delete notification '); +INSERT INTO txt VALUES ('U4002', 'German', 'Die App @@APPNAME@@ mit @@CONN_NUMBER@@ Verbindungen/ @@RULE_NUMBER@@ Regeln wurde erfolgreich rezertifiziert.'); +INSERT INTO txt VALUES ('U4002', 'English', 'Recertified @@APPNAME@@ with @@CONN_NUMBER@@ connections/ @@RULE_NUMBER@@ rules successfully.'); +INSERT INTO txt VALUES ('U4003', 'German', 'Rezertifizierung überfällig'); +INSERT INTO txt VALUES ('U4003', 'English', 'Overdue to be recertified'); +INSERT INTO txt VALUES ('U4004', 'German', 'Es wurden keine überfälligen Apps gefunden.'); +INSERT INTO txt VALUES ('U4004', 'English', 'No overdue apps found.'); +INSERT INTO txt VALUES ('U4005', 'German', 'Anstehende Rezertifizierungen in den nächsten @@DAYS@@ Tagen'); +INSERT INTO txt VALUES ('U4005', 'English', 'Upcoming recertifications in the next @@DAYS@@ days'); +INSERT INTO txt VALUES ('U4006', 'German', 'Es wurden keine anstehenden Rezertifizierungen in den nächsten @@DAYS@@ Tagen gefunden.'); +INSERT INTO txt VALUES ('U4006', 'English', 'No upcoming recertifications found in the next @@DAYS@@ days.'); +INSERT INTO txt VALUES ('U4007', 'German', 'Weitere rezertifizierte Apps'); +INSERT INTO txt VALUES ('U4007', 'English', 'Further recertified apps'); +INSERT INTO txt VALUES ('U4008', 'German', 'Weitere Apps'); +INSERT INTO txt VALUES ('U4008', 'English', 'Further apps'); +INSERT INTO txt VALUES ('U4009', 'German', 'Apps ohne aktive Rezertifizierung'); +INSERT INTO txt VALUES ('U4009', 'English', 'Apps without active recertification'); +INSERT INTO txt VALUES ('U4501', 'German', 'Sind sie sicher, dass sie folgende Policy löschen wollen: '); +INSERT INTO txt VALUES ('U4501', 'English', 'Are you sure you want to delete policy: '); +INSERT INTO txt VALUES ('U4502', 'German', 'Sind sie sicher, dass sie folgendes Fixes Kriterium löschen wollen: '); +INSERT INTO txt VALUES ('U4502', 'English', 'Are you sure you want to delete fix criterion: '); +INSERT INTO txt VALUES ('U4503', 'German', 'Sind sie sicher, dass sie folgende Matrix löschen wollen: '); +INSERT INTO txt VALUES ('U4503', 'English', 'Are you sure you want to delete matrix: '); +INSERT INTO txt VALUES ('U4504', 'German', 'Die Matrix kann nicht gelöscht werden, da sie in mindestens einer aktiven Policy verwendet wird.'); +INSERT INTO txt VALUES ('U4504', 'English', 'Matrix cannot be deleted as it is used in at least one active Policy.'); +INSERT INTO txt VALUES ('U4505', 'German', 'Die Matrix kann nicht gelöscht werden, da sie von einer anderen Quelle importiert wurde.'); +INSERT INTO txt VALUES ('U4505', 'English', 'Matrix cannot be deleted as it is imported from another source.'); + INSERT INTO txt VALUES ('U5001', 'German', 'Setup und Verwaltung des Firewall Orchestrator. Bitte eine Einstellung in der linken Randleiste auswählen.'); INSERT INTO txt VALUES ('U5001', 'English', 'Setup and administration of Firewall Orchestrator. Please choose a setting in the left sidebar.'); INSERT INTO txt VALUES ('U5011', 'German', 'Verwaltung der technischen Komponenten (nur für Admin)'); @@ -1776,7 +3327,10 @@ INSERT INTO txt VALUES ('U5014', 'German', 'Persönliche Nutzereinstellunge INSERT INTO txt VALUES ('U5014', 'English', 'Personal settings for the individual user'); INSERT INTO txt VALUES ('U5015', 'German', 'Verwaltung der Workflow-Voreinstellungen (nur für Admin)'); INSERT INTO txt VALUES ('U5015', 'English', 'Administration of workflow settings (only by admin)'); - +INSERT INTO txt VALUES ('U5016', 'German', 'Verwaltung der externen Aufträge (nur für Admin)'); +INSERT INTO txt VALUES ('U5016', 'English', 'Administration of external requests (only by admin)'); +INSERT INTO txt VALUES ('U5017', 'German', 'Verwaltung der Modul-Einstellungen (nur für Admin)'); +INSERT INTO txt VALUES ('U5017', 'English', 'Administration of module settings (only by admin)'); INSERT INTO txt VALUES ('U5101', 'German', 'Sind sie sicher, dass sie folgendes Management löschen wollen: '); INSERT INTO txt VALUES ('U5101', 'English', 'Are you sure you want to delete management: '); INSERT INTO txt VALUES ('U5102', 'German', 'Löscht alle Beispielmanagements (auf "_demo" endend) und alle zugeordneten Gateways'); @@ -1807,6 +3361,12 @@ INSERT INTO txt VALUES ('U5116', 'German', 'Verwaltung der Login-Daten der eing INSERT INTO txt VALUES ('U5116', 'English', 'Manage credentials for login to connected firewall management systems'); INSERT INTO txt VALUES ('U5117', 'German', 'Sind sie sicher, dass sie folgende Login-Daten löschen wollen: '); INSERT INTO txt VALUES ('U5117', 'English', 'Are you sure you want to delete credentials: '); +INSERT INTO txt VALUES ('U5118', 'German', 'Statusanzeige aller externen Aufträge. Möglichkeit zur Statusänderung, wenn nötig.'); +INSERT INTO txt VALUES ('U5118', 'English', 'Show the status of all external requests. Possibility to patch state if necessary.'); +INSERT INTO txt VALUES ('U5119', 'German', 'Statusanzeige aller Tickets für externe Aufträge. Möglichkeit zum Wiederanstossen, wenn nötig.'); +INSERT INTO txt VALUES ('U5119', 'English', 'Show the status of all tickets for external requests. Possibility to reinit if necessary.'); +INSERT INTO txt VALUES ('U5120', 'German', 'Informationen zu Modellierungsobjekten.'); +INSERT INTO txt VALUES ('U5120', 'English', 'Some Details for modelling objects.'); INSERT INTO txt VALUES ('U5201', 'German', 'Sind sie sicher, dass sie folgenden Nutzer löschen wollen: '); INSERT INTO txt VALUES ('U5201', 'English', 'Are you sure you want to delete user: '); @@ -1844,6 +3404,8 @@ INSERT INTO txt VALUES ('U5217', 'German', 'Sind sie sicher, dass sie folgenden INSERT INTO txt VALUES ('U5217', 'English', 'Are you sure you want to delete owner: '); INSERT INTO txt VALUES ('U5218', 'German', 'Löscht alle Beispiel-Eigentümer (auf "_demo" endend)'); INSERT INTO txt VALUES ('U5218', 'English', 'Deletes all sample owners (ending with "_demo")'); +INSERT INTO txt VALUES ('U5219', 'German', 'Sind sie sicher, dass sie folgenden Lifecycle Status löschen wollen: '); +INSERT INTO txt VALUES ('U5219', 'English', 'Are you sure you want to delete Owner Lifecycle State: '); INSERT INTO txt VALUES ('U5301', 'German', 'Einstellungen geändert.'); INSERT INTO txt VALUES ('U5301', 'English', 'Settings changed.'); @@ -1873,6 +3435,20 @@ INSERT INTO txt VALUES ('U5319', 'German', 'Server für ausgehende Emails z INSERT INTO txt VALUES ('U5319', 'English', 'Manage email server for outgoing user notifications.'); INSERT INTO txt VALUES ('U5320', 'German', 'Mehrere Email-Adressen mit Komma trennen'); INSERT INTO txt VALUES ('U5320', 'English', 'Multiple email addresses can be separated by using commas'); +INSERT INTO txt VALUES ('U5321', 'German', 'Anzeige und Überschreiben aller dargestellten Texte'); +INSERT INTO txt VALUES ('U5321', 'English', 'Show and overwrite all shown texts'); +INSERT INTO txt VALUES ('U5322', 'German', 'Verwaltung der Voreinstellungen für die Netzwerk-Modellierung'); +INSERT INTO txt VALUES ('U5322', 'English', 'Administration of default settings for network modelling'); +INSERT INTO txt VALUES ('U5323', 'German', 'Verwaltung der Voreinstellungen für das Reporting'); +INSERT INTO txt VALUES ('U5323', 'English', 'Administration of default settings for reporting'); +INSERT INTO txt VALUES ('U5324', 'German', 'Verwaltung der Compliance-Voreinstellungen für alle Nutzer'); +INSERT INTO txt VALUES ('U5324', 'English', 'Administration of compliance settings for all users'); +INSERT INTO txt VALUES ('U5325', 'German', 'Mehrere Service-Uids mit Komma trennen'); +INSERT INTO txt VALUES ('U5325', 'English', 'Multiple service uids can be separated by using commas'); +INSERT INTO txt VALUES ('U5326', 'German', 'Verwaltung aller durch FW-Änderungen ausgelösten Events'); +INSERT INTO txt VALUES ('U5326', 'English', 'Set the settings for all events triggerd by FW changes'); +INSERT INTO txt VALUES ('U5327', 'German', 'Verwaltung der Benachrichtigungs-Einstellungen für Regelablauf und aktive Regeln.'); +INSERT INTO txt VALUES ('U5327', 'English', 'Administration of notification settings for rule expiry and active rules.'); INSERT INTO txt VALUES ('U5401', 'German', 'Passwort geändert.'); INSERT INTO txt VALUES ('U5401', 'English', 'Password changed.'); @@ -1886,11 +3462,18 @@ INSERT INTO txt VALUES ('U5413', 'German', 'Anpassung der persönlichen Rep INSERT INTO txt VALUES ('U5413', 'English', 'Adapt your personal reporting settings'); INSERT INTO txt VALUES ('U5414', 'German', 'Anpassung der persönlichen Rezertifizierungseinstellungen'); INSERT INTO txt VALUES ('U5414', 'English', 'Adapt your personal recertification settings'); +INSERT INTO txt VALUES ('U5415', 'German', 'Anpassung der persönlichen Modellierungseinstellungen'); +INSERT INTO txt VALUES ('U5415', 'English', 'Adapt your personal modelling settings'); INSERT INTO txt VALUES ('U5501', 'German', 'Sind sie sicher, dass sie folgenden Status löschen wollen: '); INSERT INTO txt VALUES ('U5501', 'English', 'Are you sure you want to delete state: '); INSERT INTO txt VALUES ('U5502', 'German', 'Sind sie sicher, dass sie folgende Aktion löschen wollen: '); INSERT INTO txt VALUES ('U5502', 'English', 'Are you sure you want to delete action: '); +INSERT INTO txt VALUES ('U5503', 'German', 'Import erfolgreich.'); +INSERT INTO txt VALUES ('U5503', 'English', 'Import successful.'); + +INSERT INTO txt VALUES ('U5601', 'German', 'Sind sie sicher, dass sie das letzte Senden für folgende Benachrichtigung zurücksetzen wollen: '); +INSERT INTO txt VALUES ('U5601', 'English', 'Are you sure you want to reset the last sending for following notification: '); INSERT INTO txt VALUES ('U7001', 'German', 'Überblick der Ereignisse im Firewall Orchestrator'); INSERT INTO txt VALUES ('U7001', 'English', 'Alerts and events inside Firewall Orchestrator'); @@ -1900,6 +3483,10 @@ INSERT INTO txt VALUES ('U7003', 'German', 'Löscht alle Beispieldaten (auf INSERT INTO txt VALUES ('U7003', 'English', 'Deletes all sample data (ending with "_demo"): managements, credentials, gateways, users, tenants, groups, owners'); INSERT INTO txt VALUES ('U7101', 'German', 'Archiv der Alarme mit Bestätigungen'); INSERT INTO txt VALUES ('U7101', 'English', 'View the past alerts with acknowledgements'); +INSERT INTO txt VALUES ('U7102', 'German', 'Sind sie sicher, dass sie alle offenen Alarme bestätigen wollen?'); +INSERT INTO txt VALUES ('U7102', 'English', 'Are you sure you want to acknowledge all open alerts?'); +INSERT INTO txt VALUES ('U7103', 'German', 'Sind Sie sicher, dass Sie alle verwaisten Einträge aller Owner entfernen wollen?'); +INSERT INTO txt VALUES ('U7103', 'English', 'Are you sure you want to remove all orphaned entries for all owners?'); INSERT INTO txt VALUES ('U7201', 'German', 'Archiv der Importer-Nachrichten'); INSERT INTO txt VALUES ('U7201', 'English', 'View the past importer messages'); INSERT INTO txt VALUES ('U7301', 'German', 'Archiv der eigenen Nutzernachrichten'); @@ -1915,29 +3502,77 @@ INSERT INTO txt VALUES ('U8002', 'German', 'Neue Genehmigung zum Auftrag hinzug INSERT INTO txt VALUES ('U8002', 'English', 'New approval added to task.'); INSERT INTO txt VALUES ('U8003', 'German', 'Sind sie sicher, dass sie abbrechen wollen? Bereits erzeugte Aufträge gehen verloren.'); INSERT INTO txt VALUES ('U8003', 'English', 'Are you sure you want to cancel? Already Created tasks will be lost.'); +INSERT INTO txt VALUES ('U8004', 'German', 'Sind sie sicher, dass sie einen neuen Eigentümer zuweisen wollen? Zuständigkeiten können sich ändern.'); +INSERT INTO txt VALUES ('U8004', 'English', 'Are you sure you want to change owner? Responsibilities can be changed.'); - --- generic error messages -- -INSERT INTO txt VALUES ('E_load_title', 'German', 'Fehler beim Laden'); -INSERT INTO txt VALUES ('E_load_title', 'English', 'Loading error'); -INSERT INTO txt VALUES ('E_load_message', 'German', 'Beim Laden der Elemente ist ein unerwarteter Fehler aufgetreten. Bitte melden Sie den Fehler, wenn er nicht erklärbar ist.'); -INSERT INTO txt VALUES ('E_load_message', 'English', 'An unexpected error occurred while loading the items. Please report the error if it cannot be resolved.'); - -INSERT INTO txt VALUES ('E_add_title', 'German', 'Fehler beim Erstellen'); -INSERT INTO txt VALUES ('E_add_title', 'English', 'Creation error'); -INSERT INTO txt VALUES ('E_add_message', 'German', 'Bei der Erstellung des Elements ist ein unerwarteter Fehler aufgetreten. Bitte melden Sie den Fehler, wenn er nicht erklärbar ist.'); -INSERT INTO txt VALUES ('E_add_message', 'English', 'An unexpected error occurred while creating the item. Please report the error if it cannot be resolved.'); - -INSERT INTO txt VALUES ('E_modify_title', 'German', 'Fehler beim Modifizieren'); -INSERT INTO txt VALUES ('E_modify_title', 'English', 'Modification error'); -INSERT INTO txt VALUES ('E_modify_message', 'German', 'Bei der Modifizierung des Elements ist ein unerwarteter Fehler aufgetreten. Bitte melden Sie den Fehler, wenn er nicht erklärbar ist.'); -INSERT INTO txt VALUES ('E_modify_message', 'English', 'An unexpected error occurred while modifying the item. Please report the error if it cannot be resolved.'); - -INSERT INTO txt VALUES ('E_delete_title', 'German', 'Fehler beim Löschen'); -INSERT INTO txt VALUES ('E_delete_title', 'English', 'Deletion error'); -INSERT INTO txt VALUES ('E_delete_message', 'German', 'Bei der Löschung des Elements ist ein unerwarteter Fehler aufgetreten. Bitte melden Sie den Fehler, wenn er nicht erklärbar ist.'); -INSERT INTO txt VALUES ('E_delete_message', 'English', 'An unexpected error occurred while deleting the item. Please report the error if it cannot be resolved.'); - +INSERT INTO txt VALUES ('U9001', 'German', 'Sind sie sicher, dass sie folgende Verbindung löschen wollen: '); +INSERT INTO txt VALUES ('U9001', 'English', 'Are you sure you want to delete connection: '); +INSERT INTO txt VALUES ('U9002', 'German', 'Sind sie sicher, dass sie folgende App Rolle löschen wollen: '); +INSERT INTO txt VALUES ('U9002', 'English', 'Are you sure you want to delete App Role: '); +INSERT INTO txt VALUES ('U9003', 'German', 'Sind sie sicher, dass sie folgenden Dienst löschen wollen: '); +INSERT INTO txt VALUES ('U9003', 'English', 'Are you sure you want to delete service: '); +INSERT INTO txt VALUES ('U9004', 'German', 'Sind sie sicher, dass sie folgende Dienstgruppe löschen wollen: '); +INSERT INTO txt VALUES ('U9004', 'English', 'Are you sure you want to delete service group: '); +INSERT INTO txt VALUES ('U9005', 'German', 'Sind sie sicher, dass sie folgende App Server reaktivieren wollen: '); +INSERT INTO txt VALUES ('U9005', 'English', 'Are you sure you want to reactivate App Server: '); +INSERT INTO txt VALUES ('U9006', 'German', 'Sind sie sicher, dass sie folgendes Objekt aus der Auswahlliste löschen wollen: '); +INSERT INTO txt VALUES ('U9006', 'English', 'Are you sure you want to delete following object from selection list: '); +INSERT INTO txt VALUES ('U9007', 'German', 'Der folgende App Server wird verwendet. Sind sie sicher, dass sie ihn deaktivieren wollen: '); +INSERT INTO txt VALUES ('U9007', 'English', 'Following App Server is in use. Are you sure you want to deactivate it: '); +INSERT INTO txt VALUES ('U9008', 'German', 'Sind sie sicher, dass sie folgenden App Server löschen wollen: '); +INSERT INTO txt VALUES ('U9008', 'English', 'Are you sure you want to delete App Server: '); +INSERT INTO txt VALUES ('U9011', 'German', 'Benachrichtigung an App-Verantwortliche gesendet.'); +INSERT INTO txt VALUES ('U9011', 'English', 'Email sent to App responsibles.'); +INSERT INTO txt VALUES ('U9012', 'German', 'Bitte durch eigenen Text ersetzen'); +INSERT INTO txt VALUES ('U9012', 'English', 'Please replace by your own text'); +INSERT INTO txt VALUES ('U9013', 'German', 'Antrag-Status wurde geändert:'); +INSERT INTO txt VALUES ('U9013', 'English', 'Ticket promoted'); +INSERT INTO txt VALUES ('U9014', 'German', 'Sind sie sicher, dass sie folgende Schnittstelle löschen wollen: '); +INSERT INTO txt VALUES ('U9014', 'English', 'Are you sure you want to delete interface: '); +INSERT INTO txt VALUES ('U9015', 'German', 'Beantragte Schnittstelle mit dieser ersetzen?'); +INSERT INTO txt VALUES ('U9015', 'English', 'Replace requested interface by this?'); +INSERT INTO txt VALUES ('U9016', 'German', 'Beantragte Schnittstelle ersetzt durch'); +INSERT INTO txt VALUES ('U9016', 'English', 'Requested interface replaced by'); +INSERT INTO txt VALUES ('U9017', 'German', 'Sind sie sicher, dass sie folgende beantragte Schnittstelle ablehnen wollen: '); +INSERT INTO txt VALUES ('U9017', 'English', 'Are you sure you want to reject following requested interface: '); +INSERT INTO txt VALUES ('U9018', 'German', 'Antrag abgelehnt.'); +INSERT INTO txt VALUES ('U9018', 'English', 'Ticket rejected.'); +INSERT INTO txt VALUES ('U9019', 'German', 'Sind sie sicher, dass sie die Externen Aufträge für folgendes Ticket wiederanstossen wollen: '); +INSERT INTO txt VALUES ('U9019', 'English', 'Are you sure you want to reinit the external requests for following ticket: '); +INSERT INTO txt VALUES ('U9020', 'German', 'Die externe Beantragung wurde gestartet.'); +INSERT INTO txt VALUES ('U9020', 'English', 'External Request initialized.'); +INSERT INTO txt VALUES ('U9021', 'German', 'Schnittstellen dürfen keine Netzbereiche enthalten.'); +INSERT INTO txt VALUES ('U9021', 'English', 'Interfaces must not contain network areas.'); +INSERT INTO txt VALUES ('U9022', 'German', 'Quelle und Ziel dürfen nicht gleichzeitig einen Netzbereich enthalten.'); +INSERT INTO txt VALUES ('U9022', 'English', 'Source and destination must not contain a network area at the same time.'); +INSERT INTO txt VALUES ('U9023', 'German', 'Dieser Netzbereich kann nur in der Registerkarte Common Services verwendet werden.'); +INSERT INTO txt VALUES ('U9023', 'English', 'This network area can only be used in common services tab.'); +INSERT INTO txt VALUES ('U9024', 'German', 'Netzbereiche können nicht zusammen mit Schnittstellen anderer Apps genutzt werden.'); +INSERT INTO txt VALUES ('U9024', 'English', 'Network areas cannot be used together with interfaces from foreign apps.'); +INSERT INTO txt VALUES ('U9025', 'German', 'Sind sie sicher, dass sie folgendes Ticket als abgelehnt schliessen wollen: '); +INSERT INTO txt VALUES ('U9025', 'English', 'Are you sure you want to close the following ticket as rejected: '); +INSERT INTO txt VALUES ('U9026', 'German', 'Nichts zu beantragen!'); +INSERT INTO txt VALUES ('U9026', 'English', 'Nothing to request!'); +INSERT INTO txt VALUES ('U9027', 'German', 'Keine Verbindungen zu rezertifizieren!'); +INSERT INTO txt VALUES ('U9027', 'English', 'No connections to recertify!'); +INSERT INTO txt VALUES ('U9028', 'German', 'Folgende Verbindungen sind noch nicht korrekt modelliert und verhindern die Rezertifizierung:'); +INSERT INTO txt VALUES ('U9028', 'English', 'Following connections are not properly modelled and impede recertification: '); +INSERT INTO txt VALUES ('U9029', 'German', 'Bei folgenden Verbindungen stimmt der Produktionsstand nicht mit dem modellierten überein und verhindern die Rezertifizierung:'); +INSERT INTO txt VALUES ('U9029', 'English', 'For following connections production state does not fit modelled state and impede recertification: '); +INSERT INTO txt VALUES ('U9030', 'German', 'Ein gemeinsamer Dienst muss mindestens einen nicht gemeinsam genutzten Netzwerkbereich enthalten.'); +INSERT INTO txt VALUES ('U9030', 'English', 'A common service must contain at least one non-shared network area.'); +INSERT INTO txt VALUES ('U9031', 'German', 'Gemeinsame Dienste dürfen nur Netzwerkbereichsobjekte in einer Richtung enthalten.'); +INSERT INTO txt VALUES ('U9031', 'English', 'Common services must contain only network area objects in direction.'); +INSERT INTO txt VALUES ('U9032', 'German', 'Sie wird von folgenden verbindungen genutzt: '); +INSERT INTO txt VALUES ('U9032', 'English', 'It is used by following connections: '); +INSERT INTO txt VALUES ('U9033', 'German', '@@OK_NUMBER@@ Benachrichtigungen an App-Verantwortliche gesendet.'); +INSERT INTO txt VALUES ('U9033', 'English', '@@OK_NUMBER@@ emails sent to App responsibles.'); +INSERT INTO txt VALUES ('U9034', 'German', 'Es ist noch ein Firewall-Änderungsantrag in Bearbeitung!'); +INSERT INTO txt VALUES ('U9034', 'English', 'A Firewall Change request is running!'); +INSERT INTO txt VALUES ('U9035', 'German', 'Sind sie sicher, dass sie folgende Schnittstelle stillegen wollen: '); +INSERT INTO txt VALUES ('U9035', 'English', 'Are you sure you want to decommission following interface: '); +INSERT INTO txt VALUES ('U9036', 'German', 'Zurückgewiesen durch Admin'); +INSERT INTO txt VALUES ('U9036', 'English', 'Rejected by Admin'); -- error messages INSERT INTO txt VALUES ('E0001', 'German', 'Nicht klassifizierter Fehler: '); @@ -1954,6 +3589,22 @@ INSERT INTO txt VALUES ('E0012', 'German', 'Möglicherweise ist das Backend INSERT INTO txt VALUES ('E0012', 'English', 'Maybe backend (API or database) is unreachable. Please contact administrator'); INSERT INTO txt VALUES ('E0021', 'German', 'Bitte überprüfen Sie ihre Einstellungen'); INSERT INTO txt VALUES ('E0021', 'English', 'Please check your settings'); +INSERT INTO txt VALUES ('E0030', 'German', 'Fehler beim Laden'); +INSERT INTO txt VALUES ('E0030', 'English', 'Loading error'); +INSERT INTO txt VALUES ('E0031', 'German', 'Beim Laden der Elemente ist ein unerwarteter Fehler aufgetreten. Bitte melden Sie den Fehler, wenn er nicht erklärbar ist.'); +INSERT INTO txt VALUES ('E0031', 'English', 'An unexpected error occurred while loading the items. Please report the error if it cannot be resolved.'); +INSERT INTO txt VALUES ('E0032', 'German', 'Fehler beim Erstellen'); +INSERT INTO txt VALUES ('E0032', 'English', 'Creation error'); +INSERT INTO txt VALUES ('E0033', 'German', 'Bei der Erstellung des Elements ist ein unerwarteter Fehler aufgetreten. Bitte melden Sie den Fehler, wenn er nicht erklärbar ist.'); +INSERT INTO txt VALUES ('E0033', 'English', 'An unexpected error occurred while creating the item. Please report the error if it cannot be resolved.'); +INSERT INTO txt VALUES ('E0034', 'German', 'Fehler beim Modifizieren'); +INSERT INTO txt VALUES ('E0034', 'English', 'Modification error'); +INSERT INTO txt VALUES ('E0035', 'German', 'Bei der Modifizierung des Elements ist ein unerwarteter Fehler aufgetreten. Bitte melden Sie den Fehler, wenn er nicht erklärbar ist.'); +INSERT INTO txt VALUES ('E0035', 'English', 'An unexpected error occurred while modifying the item. Please report the error if it cannot be resolved.'); +INSERT INTO txt VALUES ('E0036', 'German', 'Fehler beim Löschen'); +INSERT INTO txt VALUES ('E0036', 'English', 'Deletion error'); +INSERT INTO txt VALUES ('E0037', 'German', 'Bei der Löschung des Elements ist ein unerwarteter Fehler aufgetreten. Bitte melden Sie den Fehler, wenn er nicht erklärbar ist.'); +INSERT INTO txt VALUES ('E0037', 'English', 'An unexpected error occurred while deleting the item. Please report the error if it cannot be resolved.'); INSERT INTO txt VALUES ('E1001', 'German', 'Vor dem Generieren des Reports bitte mindestens ein Device auf der linken Seite auswählen'); INSERT INTO txt VALUES ('E1001', 'English', 'Please select at least one device in the left side-bar before generating a report'); @@ -1972,6 +3623,8 @@ INSERT INTO txt VALUES ('E1011', 'English', 'End time is before start time'); INSERT INTO txt VALUES ('E2001', 'German', 'Bitte eine Vorlage auswählen'); INSERT INTO txt VALUES ('E2001', 'English', 'Please select a template'); +INSERT INTO txt VALUES ('E2002', 'German', 'Reporttermin gespeichert, aber die Benachrichtigungs-Einstellungen konnten nicht aktualisiert werden.'); +INSERT INTO txt VALUES ('E2002', 'English', 'Report schedule saved, but notification settings could not be updated.'); INSERT INTO txt VALUES ('E4001', 'German', 'Bitte Kommentar hinzufügen'); INSERT INTO txt VALUES ('E4001', 'English', 'Please insert a comment'); @@ -1981,6 +3634,14 @@ INSERT INTO txt VALUES ('E4003', 'German', 'Keine Änderungen für die INSERT INTO txt VALUES ('E4003', 'English', 'No changes found for given criteria'); INSERT INTO txt VALUES ('E4004', 'German', 'Nutzungsdaten nicht unterstützt für: '); INSERT INTO txt VALUES ('E4004', 'English', 'Usage data not supported for: '); +INSERT INTO txt VALUES ('E4010', 'German', 'Betreff fehlt'); +INSERT INTO txt VALUES ('E4010', 'English', 'Subject missing'); +INSERT INTO txt VALUES ('E4011', 'German', 'Email-Adressen nicht konsistent'); +INSERT INTO txt VALUES ('E4011', 'English', 'Email addresses not consistent'); +INSERT INTO txt VALUES ('E4012', 'German', 'Mindestens ein Offset vor oder nach dem Termin muss gefüllt sein'); +INSERT INTO txt VALUES ('E4012', 'English', 'At least one offset before or after deadline has to be filled'); +INSERT INTO txt VALUES ('E4013', 'German', 'Daten für Benachrichtigung nach Termin nicht konsistent'); +INSERT INTO txt VALUES ('E4013', 'English', 'Data for Notifications after Deadline not consistent'); INSERT INTO txt VALUES ('E5101', 'German', 'Löschen des Managements nicht erlaubt, da noch Gateways zugeordnet sind. Diese zuerst löschen wenn möglich'); INSERT INTO txt VALUES ('E5101', 'English', 'Deletion of management not allowed as there are related Gateways. Delete them first if possible'); @@ -2000,12 +3661,16 @@ INSERT INTO txt VALUES ('E5108', 'German', 'Email-Adresse muss "@"-Zeichen enth INSERT INTO txt VALUES ('E5108', 'English', 'Email address must contain "@"-sign.'); INSERT INTO txt VALUES ('E5109', 'German', 'Bitte keine Leerzeichen im Namen verwenden.'); INSERT INTO txt VALUES ('E5109', 'English', 'Please do not use spaces in the name.'); +INSERT INTO txt VALUES ('E5110', 'German', 'UID für Check Point Managements muss gesetzt sein.'); +INSERT INTO txt VALUES ('E5110', 'English', 'UID for Check Point managements has to be set.'); INSERT INTO txt VALUES ('E5111', 'German', 'Es gibt bereits ein Gateway mit derselben Konfiguration und Import aktiviert'); INSERT INTO txt VALUES ('E5111', 'English', 'There is already a gateway in the same configuration with import enabled'); INSERT INTO txt VALUES ('E5112', 'German', 'Gateway konnte nicht angelegt werden'); INSERT INTO txt VALUES ('E5112', 'English', 'Gateway could not be created'); INSERT INTO txt VALUES ('E5117', 'German', 'Löschen der Login-Daten nicht möglich, da diese von einem Management verwendet werden. Dort zuerst andere Login-Daten auswählen'); INSERT INTO txt VALUES ('E5117', 'English', 'Deletion of credentials not allowed as they are in use by one or more management devices. Change the management credentials before deleting them.'); +INSERT INTO txt VALUES ('E5118', 'German', 'Die obere Grenze muss grösser als die untere Grenze des Portbereichs sein.'); +INSERT INTO txt VALUES ('E5118', 'English', 'Upper limit has to be greater than lower limit in Port range.'); INSERT INTO txt VALUES ('E5201', 'German', 'LDAP-Verbindung konnte nicht angelegt werden'); INSERT INTO txt VALUES ('E5201', 'English', 'LDAP connection could not be created'); @@ -2127,11 +3792,17 @@ INSERT INTO txt VALUES ('E5291', 'German', 'Eigentümer konnte nicht gespei INSERT INTO txt VALUES ('E5291', 'English', 'Owner could not be saved'); INSERT INTO txt VALUES ('E5292', 'German', 'Dn oder Gruppe muss gefüllt sein'); INSERT INTO txt VALUES ('E5292', 'English', 'Dn or group has to be filled'); +INSERT INTO txt VALUES ('E5293', 'German', 'Lifecycle Status konnte nicht gespeichert werden'); +INSERT INTO txt VALUES ('E5293', 'English', 'Owner Lifecycle State could not be saved'); +INSERT INTO txt VALUES ('E5294', 'German', 'Fehler beim Einloggen in'); +INSERT INTO txt VALUES ('E5294', 'English', 'error while logging in to'); +INSERT INTO txt VALUES ('E5295', 'German', 'Authentifizierungsfehler'); +INSERT INTO txt VALUES ('E5295', 'English', 'Authentication Error'); +INSERT INTO txt VALUES ('E5296', 'German', 'Zusätzliche Informationen müssen ein gültiges JSON Objekt sein'); +INSERT INTO txt VALUES ('E5296', 'English', 'Additional information must be a valid JSON object'); -INSERT INTO txt VALUES ('E5301', 'German', 'Konfiguration für Standardsprache konnte nicht gelesen werden: Wert auf Englisch gesetzt'); -INSERT INTO txt VALUES ('E5301', 'English', 'Error reading Config for default language: taking default English'); -INSERT INTO txt VALUES ('E5302', 'German', 'Konfiguration konnte nicht gelesen werden, Standardwert gesetzt: '); -INSERT INTO txt VALUES ('E5302', 'English', 'Error reading Config, taking default: '); +INSERT INTO txt VALUES ('E5301', 'German', 'Konfiguration konnte nicht gelesen oder verarbeitet werden.'); +INSERT INTO txt VALUES ('E5301', 'English', 'Error reading or processing Config.'); INSERT INTO txt VALUES ('E5401', 'German', 'Bitte das alte Passwort eintragen'); INSERT INTO txt VALUES ('E5401', 'English', 'Please insert the old password'); @@ -2153,6 +3824,25 @@ INSERT INTO txt VALUES ('E5415', 'German', 'Passwort muss mindestens ein Sonder INSERT INTO txt VALUES ('E5415', 'English', 'Password must contain at least one special character (!?(){}=~$%&#*-+.,_)'); INSERT INTO txt VALUES ('E5421', 'German', 'Schlüssel nicht gefunden oder Wert nicht konvertierbar: Wert wird gesetzt auf: '); INSERT INTO txt VALUES ('E5421', 'English', 'Key not found or could not convert value to int: taking value: '); +INSERT INTO txt VALUES ('E5422', 'German', 'Eintrag enthält nicht alle erforderlichen Spalten'); +INSERT INTO txt VALUES ('E5422', 'English', 'Entry does not contain all required columns'); +INSERT INTO txt VALUES ('E5423', 'German', 'IP-Adresse/IP-Bereich ist fehlerhaft'); +INSERT INTO txt VALUES ('E5423', 'English', 'IP Address/IP Range malformed'); +INSERT INTO txt VALUES ('E5430', 'German', 'Hochgeladener Dateityp ist nicht erlaubt'); +INSERT INTO txt VALUES ('E5430', 'English', 'Uploaded Filetype is not allowed'); +INSERT INTO txt VALUES ('E5431', 'German', 'Hochgeladene Datei überschreitet Maximum'); +INSERT INTO txt VALUES ('E5431', 'English', 'Uploaded File exceeds the allowed maximum'); + +INSERT INTO txt VALUES ('E5501', 'German', 'Die Regel kann nicht doppelt zugewiesen werden.'); +INSERT INTO txt VALUES ('E5501', 'English', 'Rule cannot be assigned twice.'); +INSERT INTO txt VALUES ('E5502', 'German', 'Keine Regeln/Eigentümer gefunden oder falsches Schlüsselfeld.'); +INSERT INTO txt VALUES ('E5502', 'English', 'No Rules/Owner or wrong Key-Field.'); +INSERT INTO txt VALUES ('E5503', 'German', 'Fehler beim Import.'); +INSERT INTO txt VALUES ('E5503', 'English', 'Import error.'); +INSERT INTO txt VALUES ('E5504', 'German', 'Bitte eine Eigentümerzuordnungsquelle auswählen.'); +INSERT INTO txt VALUES ('E5504', 'English', 'Please select an owner mapping source.'); +INSERT INTO txt VALUES ('E5505', 'German', 'Bitte den benutzerdefinierten Feldschlüssel ausfüllen.'); +INSERT INTO txt VALUES ('E5505', 'English', 'Please fill the custom field key.'); INSERT INTO txt VALUES ('E6001', 'German', 'Der Re-Login war nicht erfolgreich. Haben Sie ein falsches Passwort eingegeben? Schauen Sie für Details bitte in die Logs.'); INSERT INTO txt VALUES ('E6001', 'English', 'Re-login failed. Did you enter a wrong password? See log for details.'); @@ -2169,6 +3859,10 @@ INSERT INTO txt VALUES ('E7012', 'German', 'Kein Import für aktives Manage INSERT INTO txt VALUES ('E7012', 'English', 'No Import for active management'); INSERT INTO txt VALUES ('E7013', 'German', 'Letzter erfolgreicher Import zu lange her'); INSERT INTO txt VALUES ('E7013', 'English', 'Last successful import too long ago'); +INSERT INTO txt VALUES ('E7014', 'German', 'Es sind nur CSV Dateien erlaubt.'); +INSERT INTO txt VALUES ('E7014', 'English', 'Only CSV Files allowed.'); +INSERT INTO txt VALUES ('E7015', 'German', 'Fehler beim Bestätigen aller offenen Alarme.'); +INSERT INTO txt VALUES ('E7015', 'English', 'Error acknowledging all open alerts.'); INSERT INTO txt VALUES ('E8001', 'German', 'Antrag konnte nicht angelegt werden'); INSERT INTO txt VALUES ('E8001', 'English', 'Request could not be created'); @@ -2198,12 +3892,85 @@ INSERT INTO txt VALUES ('E8013', 'German', 'Regel-Uid ist auf diesem Gerät INSERT INTO txt VALUES ('E8013', 'English', 'Rule Uid does not exist on this device: '); INSERT INTO txt VALUES ('E8014', 'German', 'Die Verarbeitung dieses Auftragstyps ist nicht aktiviert. Bitte Administrator kontaktieren.'); INSERT INTO txt VALUES ('E8014', 'English', 'The handling of this Task Type is not activated. Please contact administrator.'); +INSERT INTO txt VALUES ('E8015', 'German', 'Eigentümer konnte nicht zugeordnet werden'); +INSERT INTO txt VALUES ('E8015', 'English', 'Owner could not be assigned'); +INSERT INTO txt VALUES ('E8016', 'German', 'Eigentümer konnte nicht entfernt werden'); +INSERT INTO txt VALUES ('E8016', 'English', 'Owner could not be removed'); INSERT INTO txt VALUES ('E8101', 'German', 'Email-Versand kann nicht getestet werden, da der aktuell angemeldete Nutzer keine Email-Adresse hinterlegt hat.'); INSERT INTO txt VALUES ('E8101', 'English', 'Sending of emails cannot be tested because the logged-in user does not have an email address.'); +INSERT INTO txt VALUES ('E9001', 'German', 'Sie haben Modellier-Rechte für keine Applikation.'); +INSERT INTO txt VALUES ('E9001', 'English', 'You have no modeller rights for any application.'); +INSERT INTO txt VALUES ('E9002', 'German', 'Keine Area verfügbar.'); +INSERT INTO txt VALUES ('E9002', 'English', 'No areas available.'); +INSERT INTO txt VALUES ('E9003', 'German', 'Id schon vergeben. Bitte eine andere auswählen.'); +INSERT INTO txt VALUES ('E9003', 'English', 'Id already used. Please choose another.'); +INSERT INTO txt VALUES ('E9004', 'German', 'Dienst und Quelle oder Ziel müssen ausgefüllt sein.'); +INSERT INTO txt VALUES ('E9004', 'English', 'Service and source or Destination have to be filled.'); +INSERT INTO txt VALUES ('E9005', 'German', 'Der Schnittstellentyp kann nicht zwischen Quelle und Ziel geändert werden.'); +INSERT INTO txt VALUES ('E9005', 'English', 'The Interface type cannot be changed between Source and Destination.'); +INSERT INTO txt VALUES ('E9006', 'German', 'Quelle, Dienst und Ziel müssen gefüllt sein.'); +INSERT INTO txt VALUES ('E9006', 'English', 'Source, Service and Destination have to be filled.'); +INSERT INTO txt VALUES ('E9007', 'German', 'Dienst kann nicht gelöscht werden, da er in Benutzung ist: '); +INSERT INTO txt VALUES ('E9007', 'English', 'Service cannot be deleted because it is in use: '); +INSERT INTO txt VALUES ('E9008', 'German', 'Dienstgruppe kann nicht gelöscht werden, da sie in Benutzung ist: '); +INSERT INTO txt VALUES ('E9008', 'English', 'Service Group cannot be deleted because it is in use: '); +INSERT INTO txt VALUES ('E9009', 'German', 'App Rolle kann nicht gelöscht werden, da sie in Benutzung ist: '); +INSERT INTO txt VALUES ('E9009', 'English', 'App Role cannot be deleted because it is in use: '); +INSERT INTO txt VALUES ('E9010', 'German', 'IP-Adresse wurde schon verwendet.'); +INSERT INTO txt VALUES ('E9010', 'English', 'IP address is already used.'); +INSERT INTO txt VALUES ('E9011', 'German', 'Benachrichtigung an App-Verantwortliche konnte nicht gesendet werden.'); +INSERT INTO txt VALUES ('E9011', 'English', 'Email could not be sent to App responsibles.'); +INSERT INTO txt VALUES ('E9012', 'German', 'Die Schnittstelle sollte nicht in der eigenen App beantragt werden.'); +INSERT INTO txt VALUES ('E9012', 'English', 'Interface should not be requested in own App.'); +INSERT INTO txt VALUES ('E9013', 'German', 'Schnittstelle kann nicht gelöscht werden, da sie in Benutzung ist: '); +INSERT INTO txt VALUES ('E9013', 'English', 'Interface cannot be deleted because it is in use: '); +INSERT INTO txt VALUES ('E9014', 'German', 'Bitte zuerst die gemachten Änderungen speichern.'); +INSERT INTO txt VALUES ('E9014', 'English', 'Please save changes first.'); +INSERT INTO txt VALUES ('E9015', 'German', 'Dieses NA-Objekt darf an dieser Stelle nicht verwendet werden (administrativ verboten).'); +INSERT INTO txt VALUES ('E9015', 'English', 'This NA object must not be used in this position (administratively forbidden).'); +INSERT INTO txt VALUES ('E9016', 'German', 'Beantragte Schnittstelle kann nicht gelöscht werden.'); +INSERT INTO txt VALUES ('E9016', 'English', 'Requested interface cannot be deleted.'); +INSERT INTO txt VALUES ('E9017', 'German', 'Schnittstelle kann die angeforderte nicht ersetzen: Die Richtungen der Schnittstellen stimmen nicht überein (eine ist eine Quellschnittstelle, die andere eine Zielschnittstelle).'); +INSERT INTO txt VALUES ('E9017', 'English', 'Interface cannot replace requested one: the directions of the interfaces do not match (one is a source interface, the other a destination interface).'); +INSERT INTO txt VALUES ('E9018', 'German', 'Name schon vergeben. Bitte einen anderen wählen.'); +INSERT INTO txt VALUES ('E9018', 'English', 'Name already used. Please choose another.'); +INSERT INTO txt VALUES ('E9019', 'German', 'Benachrichtigungen an @@FAIL_NUMBER@@ App-Verantwortliche konnte nicht gesendet werden.'); +INSERT INTO txt VALUES ('E9019', 'English', 'Email could not be sent to @@FAIL_NUMBER@@ App responsibles.'); +INSERT INTO txt VALUES ('E9020', 'German', 'Schnittstelle kann nicht auf Privat gesetzt werden, da sie von anderen Applikationen verwendet wird.'); +INSERT INTO txt VALUES ('E9020', 'English', 'Interface cannot be set to Private because it is used by other applications.'); +INSERT INTO txt VALUES ('E9021', 'German', 'Schnittstellenberechtigung erforderlich.'); +INSERT INTO txt VALUES ('E9021', 'English', 'Interface permission required.'); +INSERT INTO txt VALUES ('E9101', 'German', 'Fehler bei externer Auftragserzeugung.'); +INSERT INTO txt VALUES ('E9101', 'English', 'Error at external ticket creation.'); +INSERT INTO txt VALUES ('E9102', 'German', 'Fehler beim Ändern des externen Auftragsstatus.'); +INSERT INTO txt VALUES ('E9102', 'English', 'Error at changing the external ticket state.'); +INSERT INTO txt VALUES ('E9103', 'German', 'Fehler beim Schliessen des Tickets.'); +INSERT INTO txt VALUES ('E9103', 'English', 'Error closing ticket.'); +INSERT INTO txt VALUES ('E9104', 'German', 'Sie haben nicht die benötigte Rolle.'); +INSERT INTO txt VALUES ('E9104', 'English', 'You do not have the necessary role.'); +INSERT INTO txt VALUES ('E9201', 'German', 'Fehler beim Löschen der existierenden App Zonen Objekte'); +INSERT INTO txt VALUES ('E9201', 'English', 'Error deleting existing app zone objects'); +INSERT INTO txt VALUES ('E9202', 'German', 'Fehler beim Erzeugen der App Zonen Objekte'); +INSERT INTO txt VALUES ('E9202', 'English', 'Error creating app zone objects'); +INSERT INTO txt VALUES ('E9203', 'German', 'Fehler beim Abrufen der existierenden App Zonen Objekte'); +INSERT INTO txt VALUES ('E9203', 'English', 'Error retrieving the existing app zone objects'); +INSERT INTO txt VALUES ('E9204', 'German', 'Fehler beim Hinzufügen des App Servers zum App Zonen Objekt'); +INSERT INTO txt VALUES ('E9204', 'English', 'Error adding the App Server to the App Zone object'); +INSERT INTO txt VALUES ('E9301', 'German', 'Template Datei nicht gefunden!'); +INSERT INTO txt VALUES ('E9301', 'English', 'Template File not found!'); +INSERT INTO txt VALUES ('E9302', 'German', 'HTML ist nicht valide!'); +INSERT INTO txt VALUES ('E9302', 'English', 'HTML is invalid!'); + +INSERT INTO txt VALUES ('E9400', 'German', 'Leere Datei hochgeladen/keine Änderungen wurden vorgenommen'); +INSERT INTO txt VALUES ('E9400', 'English', 'Empty file provided/no changes where applied'); +INSERT INTO txt VALUES ('E9401', 'German', 'Matrix erfolgreich importiert'); +INSERT INTO txt VALUES ('E9401', 'English', 'Matrix imported successfully'); +INSERT INTO txt VALUES ('E9402', 'German', 'Fehlr beim Import der Matrix'); +INSERT INTO txt VALUES ('E9402', 'English', 'Error importing matrix'); -- errors from Api INSERT INTO txt VALUES ('A0001', 'German', 'Ungültige Anmeldedaten. Nutzername darf nicht leer sein'); @@ -2236,7 +4003,7 @@ INSERT INTO txt VALUES ('T0011', 'German', 'Nutzer mit vollem Zugriff auf den F INSERT INTO txt VALUES ('T0011', 'English', 'users with full access rights to firewall orchestrator'); INSERT INTO txt VALUES ('T0012', 'German', 'Nutzer mit Berechtigung zum Rezertifizieren von Regeln'); INSERT INTO txt VALUES ('T0012', 'English', 'users that have the right to recertify rules'); -INSERT INTO txt VALUES ('T0013', 'German', 'NNutzer mit Berechtigung zum Anlegen von Anträgen'); +INSERT INTO txt VALUES ('T0013', 'German', 'Nutzer mit Berechtigung zum Anlegen von Anträgen'); INSERT INTO txt VALUES ('T0013', 'English', 'users that have the right to create requests'); INSERT INTO txt VALUES ('T0014', 'German', 'Nutzer mit Berechtigung zum Genehmigen von Anträgen'); INSERT INTO txt VALUES ('T0014', 'English', 'users that have the right to approve requests'); @@ -2246,6 +4013,8 @@ INSERT INTO txt VALUES ('T0016', 'German', 'Nutzer mit Berechtigung zum Impleme INSERT INTO txt VALUES ('T0016', 'English', 'users that have the right to implement requests'); INSERT INTO txt VALUES ('T0017', 'German', 'Nutzer mit Berechtigung zum Review von Aufträgen'); INSERT INTO txt VALUES ('T0017', 'English', 'users that have the right to review requests'); +INSERT INTO txt VALUES ('T0018', 'German', 'Nutzer mit Berechtigung zum Modellieren von Applikationen'); +INSERT INTO txt VALUES ('T0018', 'English', 'users that have the right to model applications'); -- template comments INSERT INTO txt VALUES ('T0101', 'German', 'Aktuell aktive Regeln aller Gateways'); @@ -2258,6 +4027,96 @@ INSERT INTO txt VALUES ('T0104', 'German', 'Alle Regeln, die offene Quellen, Zi INSERT INTO txt VALUES ('T0104', 'English', 'All pass rules that contain any as source, destination or service'); INSERT INTO txt VALUES ('T0105', 'German', 'Aktuell aktive NAT-Regeln aller Gateways'); INSERT INTO txt VALUES ('T0105', 'English', 'Currently active NAT rules of all gateways'); +INSERT INTO txt VALUES ('T0106', 'German', 'Aktuell aktive unbenutzte Regeln aller Gateways'); +INSERT INTO txt VALUES ('T0106', 'English', 'Currently active unused rules of all gateways'); +INSERT INTO txt VALUES ('T0107', 'German', 'Aktuell aktive Regeln, die zur Rezertifizierung anstehen'); +INSERT INTO txt VALUES ('T0107', 'English', 'Currently active rules with upcoming recertification'); +INSERT INTO txt VALUES ('T0108', 'German', 'Alle nicht gelösten Compliance-Verletzungen'); +INSERT INTO txt VALUES ('T0108', 'English', 'All unresolved compliance violations'); +INSERT INTO txt VALUES ('T0109', 'German', 'Veränderungen der Compliance-Verletzungen in Zeitraum x'); +INSERT INTO txt VALUES ('T0109', 'English', 'Changes in compliance violations in period x'); + +-- Contextual Info (Tooltips) +INSERT INTO txt VALUES ('C1000', 'German', 'Zeige alle Eigentümer mit aktiver Rezertifizierung, unabhängig vom nächsten Rezertifizierungsdatum.'); +INSERT INTO txt VALUES ('C1000', 'English', 'Show all owners with active recertification, regardless of the next recertification date.'); +INSERT INTO txt VALUES ('C1001', 'German', 'Zeige alle Eigentüer, fü welche die Rezertifizierung aktiviert ist.'); +INSERT INTO txt VALUES ('C1001', 'English', 'Show all owners with recertification activated.'); +INSERT INTO txt VALUES ('C1002', 'German', 'Zeige Eigentümer, für die keine aktive Rezertifizierung konfiguriert ist, in einem separaten Kapitel.'); +INSERT INTO txt VALUES ('C1002', 'English', 'Show owners without active recertification in a separate chapter.'); +INSERT INTO txt VALUES ('C9000', 'German', 'Dieses Objekt wurde deaktiviert und sollte von der App Rolle entfernt werden.'); +INSERT INTO txt VALUES ('C9000', 'English', 'This object was deactivated and should be removed from App Role.'); +INSERT INTO txt VALUES ('C9001', 'German', 'Dieses Objekt wurde deaktiviert und sollte von der Verbindung entfernt werden.'); +INSERT INTO txt VALUES ('C9001', 'English', 'This object was deactivated and should be removed from Connection.'); +INSERT INTO txt VALUES ('C9002', 'German', 'Dieser App Server wurde noch in keiner App Rolle oder Verbindung verwendet.'); +INSERT INTO txt VALUES ('C9002', 'English', 'This App Server was not used in any App Role or Connection.'); +INSERT INTO txt VALUES ('C9003', 'German', 'Diese App wurde deaktiviert.'); +INSERT INTO txt VALUES ('C9003', 'English', 'This app was deactivated.'); +INSERT INTO txt VALUES ('C9004', 'German', 'In dieser App wurden noch keine Verbindungen angelegt.'); +INSERT INTO txt VALUES ('C9004', 'English', 'In this app no connections have been created.'); +INSERT INTO txt VALUES ('C9005', 'German', 'Wählen Sie die App, in der die Schnittstelle voraussichtlich angelegt werden soll. Diese kann im Workflow ggf. noch geändert werden'); +INSERT INTO txt VALUES ('C9005', 'English', 'Select app where the interface presumably should be created. This may be changed within the workflow if necessary.'); +INSERT INTO txt VALUES ('C9006', 'German', 'Diese Schnittstelle als Quelle anlegen.'); +INSERT INTO txt VALUES ('C9006', 'English', 'Create this interface as source.'); +INSERT INTO txt VALUES ('C9007', 'German', 'Angefrage Schnittstelle - noch auf der Gegenseite zu modellieren!'); +INSERT INTO txt VALUES ('C9007', 'English', 'Requested interface - to be modelled in the counterpart!'); +INSERT INTO txt VALUES ('C9008', 'German', 'Angefrage Schnittstelle - bitte modellieren!'); +INSERT INTO txt VALUES ('C9008', 'English', 'Requested interface - please model!'); +INSERT INTO txt VALUES ('C9009', 'German', 'Mit der Veröffentlichung wird die Schnittstelle für andere Modellierer sicht- und nutzbar. + Bei Rücknahme der Veröffentlichung ändert sich lediglich die Sichtbarkeit bei der Suche - für bereits vorhandene nutzende Verbindungen ändert sich nichts. +'); +INSERT INTO txt VALUES ('C9009', 'English', 'By publishing the interface is visible and usable for other modellers. + When reverting the publication, only the visibility in searches is changed - already using connections remain unchanged. +'); +INSERT INTO txt VALUES ('C9010', 'German', 'Angefrage Schnittstelle durch bereits vorhandene ersetzen.'); +INSERT INTO txt VALUES ('C9010', 'English', 'Replace requested by already existing interface.'); +INSERT INTO txt VALUES ('C9011', 'German', 'Angefrage Schnittstelle wurde abgelehnt.'); +INSERT INTO txt VALUES ('C9011', 'English', 'Requested interface was rejected.'); +INSERT INTO txt VALUES ('C9012', 'German', 'Sie haben keine der Rollen: requester, implementer, admin, auditor.'); +INSERT INTO txt VALUES ('C9012', 'English', 'You do not have one of the following roles: requester, implementer, admin, auditor.'); +INSERT INTO txt VALUES ('C9013', 'German', 'Leere App Rolle enthalten. Diese Verbindung wird nicht beantragt.'); +INSERT INTO txt VALUES ('C9013', 'English', 'Contains empty App Role. This connection will not be requested.'); +INSERT INTO txt VALUES ('C9014', 'German', 'Gelöschtes Objekt enthalten. Diese Verbindung wird nicht beantragt.'); +INSERT INTO txt VALUES ('C9014', 'English', 'Contains deleted object. This connection will not be requested.'); +INSERT INTO txt VALUES ('C9015', 'German', 'Leere App Rolle enthalten. Nutzende Verbindungen dieser Schnittstelle werden nicht beantragt.'); +INSERT INTO txt VALUES ('C9015', 'English', 'Contains empty App Role. Connections using this interface will not be requested.'); +INSERT INTO txt VALUES ('C9016', 'German', 'Gelöschtes Objekt enthalten. Nutzende Verbindungen dieser Schnittstelle werden nicht beantragt.'); +INSERT INTO txt VALUES ('C9016', 'English', 'Contains deleted object. Connections using this interface will not be requested.'); +INSERT INTO txt VALUES ('C9017', 'German', 'Hier kann der Name des App-Servers, der beim Speichern ohnehin automatisch erzeugt wird, im voraus zur Ansicht generiert werden. + Dabei wird der Name zur IP-Adresse im DNS nachgeschlagen. Wenn keiner gefunden wird, so wird er entsprechend der Namenskonvention konstruiert. +'); +INSERT INTO txt VALUES ('C9017', 'English', 'Here the name of the App Server, which is created on saving anyway, can be generated for display in advance. + The name is searched in the DNS. If not found, it is constructed according to the naming convention. +'); +INSERT INTO txt VALUES ('C9018', 'German', 'Leere Service Gruppe(n) enthalten. Diese Verbindung wird nicht beantragt.'); +INSERT INTO txt VALUES ('C9018', 'English', 'Contains empty Service Groups(s). This connection will not be requested.'); +INSERT INTO txt VALUES ('C9019', 'German', 'Leere Service Gruppe(n) enthalten. Nutzende Verbindungen dieser Schnittstelle werden nicht beantragt.'); +INSERT INTO txt VALUES ('C9019', 'English', 'Contains empty Service Groups(s). Connections using this interface will not be requested.'); +INSERT INTO txt VALUES ('C9020', 'German', 'Nur zu Dokumentation. Diese Verbindung wird nicht beantragt.'); +INSERT INTO txt VALUES ('C9020', 'English', 'Only for documentation. This connection will not be requested.'); +INSERT INTO txt VALUES ('C9021', 'German', 'Soll-Ist-Differenz: Die Verbindung wurde auf Produktionsdevices nicht gefunden.'); +INSERT INTO txt VALUES ('C9021', 'English', 'Variance: Connection not found on production devices.'); +INSERT INTO txt VALUES ('C9022', 'German', 'Soll-Ist-Differenz: Der Produktionsstand entspricht nicht der modellierten Verbindung.'); +INSERT INTO txt VALUES ('C9022', 'English', 'Variance: Production state does not fit to the modelled connection.'); +INSERT INTO txt VALUES ('C9023', 'German', 'Die modellierte Verbindung ist Ok.'); +INSERT INTO txt VALUES ('C9023', 'English', 'Modelled connection is Ok.'); +INSERT INTO txt VALUES ('C9024', 'German', 'Der Produktionsstand entspricht der modellierten Verbindung.'); +INSERT INTO txt VALUES ('C9024', 'English', 'Production state fits to modelled connection.'); +INSERT INTO txt VALUES ('C9025', 'German', 'Asynchroner Soll-Ist-Abgleich wurde noch nicht durchgeführt.'); +INSERT INTO txt VALUES ('C9025', 'English', 'Asynchroneous Variance Analysis not performed yet.'); +INSERT INTO txt VALUES ('C9026', 'German', 'Schnittstelle wurde stillgelegt.'); +INSERT INTO txt VALUES ('C9026', 'English', 'Interface was decommissioned.'); +INSERT INTO txt VALUES ('C9027', 'German', 'Nicht Berechtigt. Bitte Anbieter kontaktieren.'); +INSERT INTO txt VALUES ('C9027', 'English', 'Not authorized. Please contact the provider.'); +INSERT INTO txt VALUES ('C9028', 'German', 'Nutzung der Schnittstelle nicht (mehr) erlaubt.'); +INSERT INTO txt VALUES ('C9028', 'English', 'Usage of interface not allowed (any more).'); +INSERT INTO txt VALUES ('C9029', 'German', 'Zeigt nur verwaiste Einträge des gewählten Owners und blendet die Auswahlfelder aus. + Als verwaist gelten Objekte, die in Verbindungen angelegt aber durch eine genutzte Schnittstelle nicht mehr sichtbar sind. Diese Konstellation sollte mit neueren Versionen nicht mehr erzeugt werden können. +'); +INSERT INTO txt VALUES ('C9029', 'English', 'Shows only orphaned entries for the selected owner and hides the selection fields. + Orphaned are objects that are appended to connections but not visible any more due to the use of an interface. The creation of this constellation should be suppressed in newer versions. +'); +INSERT INTO txt VALUES ('C9030', 'German', 'Nutzung der Schnittstelle enthält Gruppenobjekte anderer Eigentümer, die in Produktion nicht gefunden wurden. Beantragung unterdrückt.'); +INSERT INTO txt VALUES ('C9030', 'English', 'Used interface contains group objects of other owners that were not found in production. Request suppressed.'); -- help pages INSERT INTO txt VALUES ('H0001', 'German', 'Firewall Orchestrator ist eine Anwendung zum Erzeugen und Verwalten von verschiedenen Reports aus Konfigurationsdaten verteilter Firewallsysteme. @@ -2281,7 +4140,7 @@ INSERT INTO txt VALUES ('H1001', 'German', 'Die erste Eingabezeile ist die Filt Mit Hilfe der Tabs am oberen Bildschirmrand kann zwischen der Report-Generierung, dem Report-Scheduling und dem Report-Archiv umgeschaltet werden. '); INSERT INTO txt VALUES ('H1001', 'English', 'The first input line is the filter line, where the parameters for the report creation are defined. - It is subject to a special Filter Syntax. + It is subject to a special Filter Syntax. It can be filled completely manually or supported by Templates, which can be chosen below. In the Left Sidebar the available report types and devices as well as the reporting time are displayed.
    After selecting the "Generate Report" button the Report Data is shown in the lower part of the window. @@ -2295,10 +4154,12 @@ INSERT INTO txt VALUES ('H1101', 'German', '
  • Alle Filter sind schreibungsun
  • Alle Filterausdrücke müssen logisch mit den Operatoren: and, or, not miteinander kombiniert werden.
  • Klammern können genutzt werden, um die Filterausdrücke zu strukturieren.
  • Anführungszeichen (") können optional für Wertdefinitionen genutzt werden. Wenn Leerzeichen im Wert vorkommen (z.B. für Datum/Zeit-Werte), müssen sie genutzt werden.
  • -
  • Ein Gateway muss ausgewählt werden. Dies kann manuell oder über die linke Randleiste, von wo die Auswahl automatisch in den Filter integriert wird, erfolgen.
  • +
  • Muss ein Gateway ausgewählt werden, kann dies manuell oder über die linke Randleiste, von wo die Auswahl automatisch in den Filter integriert wird, erfolgen.
  • +
  • Workflow-Ticket-Reports unterstützen zusätzlich die Filterleisten-Schlüsselwörter tasktype, state/states und phase; Workflow-Ticketänderungen zusätzlich reference_date.
  • Zeitfilterung funktioniert zur Zeit nur für Zeitpunkte vor dem letzten Import, der einen Config Change gefunden hat.
  • Regeln werden immer in voller Tiefe durchsucht, d.h. alle Gruppen in Quell-, Ziel- und Dienstfeldern werden aufgelöst. Zur Zeit gibt es noch keine Möglichkeit, nur auf der obersten Regelebene zu suchen.
  • +
  • Auch Verbindungen können mit den entsprechenden Schlüsselwörtern für Quelle, Dienst und Ziel durchsucht werden.
  • '); INSERT INTO txt VALUES ('H1101', 'English', '
  • All filtering is case insensitive.
  • There are multiple variants for most keywords, e.g. DestinationPort filters can be written as: @@ -2306,42 +4167,21 @@ INSERT INTO txt VALUES ('H1101', 'English', '
  • All filtering is case insensit
  • All filter statements must be logically combined using either: and, or, not.
  • Brackets can be used for structuring the filter statement.
  • Quotation marks (") can be used optionally for the value definition. If there are white spaces in the value (e.g. for date/time values) the quotation marks have to be used.
  • -
  • A gateway has to be selected. This can be done manually or via the left sidebar, from where the selection is automatically integrated to the filter.
  • +
  • If a gateway has to be selected, this can be done manually or via the left sidebar, from where the selection is automatically integrated to the filter.
  • +
  • Workflow ticket reports additionally support the filter-line keywords tasktype, state/states and phase; workflow ticket change reports additionally support reference_date.
  • Time filtering currently only works for points in time before the last import that found a config change.
  • Rules are always deep-searched, meaning all groups in source, destination and service fields are resolved. There is currently no option to only search at the rule top-level.
  • -'); -INSERT INTO txt VALUES ('H1102', 'German', 'Folgende Report-Typen stehen zur Auswahl: -
      -
    • Regeln - Anzeige von Zugriffsregeln; Default-Report-Zeitpunkt: jetzt
    • -
    • Regeln (aufgelöst) - Anzeige von Zugriffsregeln, wobei sämtliche Gruppen in Quelle, Ziel und Dienst aufgelöst werden. - Dies ermöglicht einen Export in einer einzigen Tabelle ohne Hilfstabellen, in denen die Objekt-Definitionen stehen. Default-Report-Zeitpunkt: jetzt
    • -
    • Regeln (technisch) - wie der aufgelöste Regel-Report, nur dass Objektnamen nicht angezeigt werden. Default-Report-Zeitpunkt: jetzt
    • -
    • Unbenutzte Regeln - Anzeige aller Regeln die das letztemal vor einem vorgegebenen Zeitpunkt benutzt wurden. Geräte, die keine Nutzungsinformation liefern, werden ignoriert. - Falls der Reporter auch die Rolle "requester" hat, wird bei Selektion ausgegebener Regeln eine Schaltfläche zur Erzeugung eines Löschantrags angeboten.
    • -
    • NAT-Regeln - Anzeige der NAT-Regeln und nicht der Zugriffsregeln. Default-Report-Zeitpunkt: jetzt
    • -
    • Rezertifizierung - Anzeige aller Regeln mit anstehenden Rezertifizierungen. Der Default-Report-Zeitraum kann in den Einstellungen gesetzt werden
    • -
    • Änderungen - Anzeige von Änderungen in einem bestimmten Zeitraum. Default-Report-Zeitraum: dieses Jahr
    • -
    • Änderungen (aufgelöst) - Anzeige von Änderungen in einem bestimmten Zeitraum, wobei sämtliche Gruppen in Quelle, Ziel und Dienst aufgelöst werden. Default-Report-Zeitraum: dieses Jahr
    • -
    • Änderungen (technisch)- wie der aufgelöste Änderungs-Report, nur dass Objektnamen nicht angezeigt werden. Default-Report-Zeitraum: dieses Jahr
    • -
    • Statistik - Anzeige von Statistikdaten über Anzahl von Objekten und Regeln. Default-Report-Zeitpunkt: jetzt
    • -
    -'); -INSERT INTO txt VALUES ('H1102', 'English', 'Choose from the following report types: -
      -
    • Rules - display access rules; default report time: now
    • -
    • Rules (resolved) - display access rules but not showing any group structure but only resolved group content. Default report time: now
    • -
    • Rules (technical) - display access rules, resolving groups and not showing object names. Default report time: now<
    • -
    • Unused Rules - display all rules where the rule last hit lies before a given time. Devices delivering no usage information are disregarded. - If the reporter has also a requester role, a button to create a delete rule request is offered after selecting reported rules.
    • -
    • NAT Rules - display NAT rules instead of access rules. Default report time: now
    • -
    • Recertification - display all rules where recertifications are upcoming. Default report interval can be defined in settings
    • -
    • Changes - display all changes in a defined time interval. Default report interval: this year
    • -
    • Changes (resolved) - display all changes in a defined time interval but not showing any group structure but only resolved group content. Default report interval: this year
    • -
    • Changes (technical) - display all changes in a defined time interval resolving groups and not showing object names. Default report interval: this year
    • -
    • Statistics - display statistical data on the number of objects and rules. Default report time: now
    • -
    -'); +
  • Also connections can be filtered with the respective keywords for source, service and destination.
  • +'); +INSERT INTO txt VALUES ('H1102', 'German', 'Folgende Report-Typen stehen zur Auswahl:'); +INSERT INTO txt VALUES ('H1102', 'English', 'Choose from the following report types:'); +INSERT INTO txt VALUES ('H1103', 'German', 'Fehlende Report-Typen müssen möglicherweise zuerst in den Reporting-Einstellungen unter "Verfügbare Reporttypen" aktiviert werden. Zusätzlich kann die Liste je nach Rolle weiter eingeschränkt sein.'); +INSERT INTO txt VALUES ('H1103', 'English', 'Missing report types may first need to be enabled in Report Settings under "Available Report Types". In addition, the list can be further restricted depending on the user role.'); +INSERT INTO txt VALUES ('H1104', 'German', 'Zert: Certificate ist ein archivierter Spezial-Report und steht nicht als regulärer auswählbarer Report-Typ zur Verfügung. Er ist nur im Archiv verfügbar.'); +INSERT INTO txt VALUES ('H1104', 'English', 'Cert: Certificate is a special archived report and is not available as a regular selectable report type. It is only available in the Archive.'); +INSERT INTO txt VALUES ('H1112', 'German', 'Definiert den Zeitraum für die Vorausschau (in Tagen) für die nächste Rezertifizierung. Der Wert 0 bedeutet, dass nur bereits fällige Einträge berücksichtigt werden; im Eigentümer-Report wird dann kein Abschnitt für bald fällige Einträge angezeigt.'); +INSERT INTO txt VALUES ('H1112', 'English', 'Defines the lookahead period (in days) for the next recertification. A value of 0 means that only already due entries are considered; in the owner report no upcoming section is shown in that case.'); INSERT INTO txt VALUES ('H1111', 'German', '
  • gateway (gw, firewall, fw, device, dev): Zusätzlich zu der in der Linken Randleiste zu tätigenden Auswahl spezifischer Devices kann hier noch die Auswahl weiter nach Namen eingeschränkt werden.
  • management (mgmt, manager, mgm, mgr)
  • @@ -2353,10 +4193,16 @@ INSERT INTO txt VALUES ('H1111', 'German', '
  • gateway (gw, firewall, fw, devi
  • destinationport (port, dport, dst_port, dst-port, dest-port, destination-port, dest_port, destination_port)
  • action (act, enforce)
  • remove: Mögliche Werte: true/false. Wenn "true", werden nur dezertifizierte Regeln gesucht
  • -
  • recertdisplay (recertdisp): Definiert den Zeitraum für die Vorausschau (in Tagen) für die nächste Rezertifizierung. Nur Regeln in diesem Zeitfenster werden gesucht.
  • +
  • recertdisplay (recertdisp): Definiert den Zeitraum für die Vorausschau (in Tagen) für die nächste Rezertifizierung. Der Wert 0 bedeutet, dass nur bereits fällige Einträge berücksichtigt werden; im Eigentümer-Report wird dann kein Abschnitt für bald fällige Einträge angezeigt.
  • lasthit (last-hit, last-used, last-usage, last-use): Filtern nach Regel-Nutzung - aktuell unterstützt für FortiManager und Check Point >=R80.
  • not-used-for-days (unused, unused-days, not-used): nicht genutzt seit der vorgegebenen Anzahl von Tagen oder gar nicht
  • fulltext (full, fulltextsearch, fts, text, textsearch)
  • +
  • ownerstate (owner-state, owner_state, owner_lc_state, owner-lc-state): Eigentümer-Report nach Lifecycle-Status-ID oder Lifecycle-Status-Name filtern
  • +
  • criticality: Eigentümer-Report nach Kritikalität filtern
  • +
  • tasktype (task-type, task_type): Workflow-Ticket-Reports nach Request-Tasktypen filtern
  • +
  • state/states (state_ids, state-ids): Workflow-Ticket-Reports nach Ticket-Status filtern
  • +
  • phase: Workflow-Ticket-Reports auf den Statusbereich einer aktiven Workflow-Phase einschränken
  • +
  • reference_date (reference-date, referencedate): Workflow-Ticketänderungen auf ein bestimmtes Bezugsdatum oder Ereignis beziehen
  • '); INSERT INTO txt VALUES ('H1111', 'English', '
  • gateway (gw, firewall, fw, device, dev): Additionally to the specific device selection in the left sidebar the selected devices can be further restricted here by device names.
  • @@ -2369,10 +4215,16 @@ INSERT INTO txt VALUES ('H1111', 'English', '
  • gateway (gw, firewall, fw, devi
  • destinationport (port, dport, dst_port, dst-port, dest-port, destination-port, dest_port, destination_port)
  • action (act, enforce)
  • remove: Possible Values: true/false. If "true", only decertified rules are searched
  • -
  • recertdisplay (recertdisp): Defines the lookahead period (in days) for next recertification. Only rules in this time range are searched.
  • +
  • recertdisplay (recertdisp): Defines the lookahead period (in days) for the next recertification. A value of 0 means that only already due entries are considered; in the owner report no upcoming section is shown in that case.
  • lasthit (last-hit, last-used, last-usage, last-use): filter by rule usage - supported for FortiManager and Check Point >=R80 only.
  • not-used-for-days (unused, unused-days, not-used): not used for the given number of days or never
  • fulltext (full, fulltextsearch, fts, text, textsearch)
  • +
  • ownerstate (owner-state, owner_state, owner_lc_state, owner-lc-state): filter Owners report by lifecycle state id or lifecycle state name
  • +
  • criticality: filter Owners report by criticality
  • +
  • tasktype (task-type, task_type): filter workflow ticket reports by request task types
  • +
  • state/states (state_ids, state-ids): filter workflow ticket reports by ticket states
  • +
  • phase: restrict workflow ticket reports to the state range of an active workflow phase
  • +
  • reference_date (reference-date, referencedate): use a specific reference date or event for workflow ticket change reports
  • '); INSERT INTO txt VALUES ('H1131', 'German', '
  • and (&)
  • or (|)
  • not (!)
  • eq (=, :)
  • neq
  • (
  • )
  • '); INSERT INTO txt VALUES ('H1131', 'English', '
  • and (&)
  • or (|)
  • not (!)
  • eq (=, :)
  • neq
  • (
  • )
  • '); @@ -2404,6 +4256,82 @@ INSERT INTO txt VALUES ('H1145', 'English', '
  • filter for last hit of ruleslasthit<2023-01-01 - only shows rules with hits before the year 2023 including those rules which have no hits at all
  • lasthit>2022-12-31 - only shows rules which have hits in 2023 (or later). Rules without any hits are not shown.
  • '); +INSERT INTO txt VALUES ('H1146', 'German', '
  • Workflow-Ticket-Reports unterstützen in der Filterleiste tasktype, state/states und phase, z.B. tasktype=access,new_interface and state=49 and phase=implementation. + Für state/states werden in der Filterleiste numerische Status-IDs erwartet.
  • Workflow-Ticketänderungen unterstützen zusätzlich reference_date, z.B. reference_date=ImplementationStart.
  • +'); +INSERT INTO txt VALUES ('H1146', 'English', '
  • Workflow ticket reports support tasktype, state/states and phase in the filter line, for example tasktype=access,new_interface and state=49 and phase=implementation. + The filter-line variants state/states expect numeric state ids.
  • Workflow ticket change reports additionally support reference_date, for example reference_date=ImplementationStart.
  • +'); +INSERT INTO txt VALUES ('H1151', 'German', 'Regeln: Standard - Anzeige von Zugriffsregeln; Default-Report-Zeitpunkt: jetzt'); +INSERT INTO txt VALUES ('H1151', 'English', 'Rules: Standard - display access rules; default report time: now'); +INSERT INTO txt VALUES ('H1152', 'German', 'Regeln: Aufgelöst - Anzeige von Zugriffsregeln, wobei sämtliche Gruppen in Quelle, Ziel und Dienst aufgelöst werden. + Dies ermöglicht einen Export in einer einzigen Tabelle ohne Hilfstabellen, in denen die Objekt-Definitionen stehen. Default-Report-Zeitpunkt: jetzt +'); +INSERT INTO txt VALUES ('H1152', 'English', 'Rules: Resolved - display access rules but not showing any group structure, only resolved group content. + This allows export in a single table without helper tables for object definitions. Default report time: now +'); +INSERT INTO txt VALUES ('H1153', 'German', 'Regeln: Technisch - wie der aufgelöste Regel-Report, nur dass Objektnamen nicht angezeigt werden. Default-Report-Zeitpunkt: jetzt'); +INSERT INTO txt VALUES ('H1153', 'English', 'Rules: Technical - like the resolved rule report, but object names are not shown. Default report time: now'); +INSERT INTO txt VALUES ('H1154', 'German', 'Regeln: Unbenutzt - Anzeige aller Regeln, die das letzte Mal vor einem vorgegebenen Zeitpunkt benutzt wurden. + Geräte, die keine Nutzungsinformation liefern, werden ignoriert. Falls der Reporter auch die Rolle "requester" hat, wird bei Selektion ausgegebener Regeln eine Schaltfläche zur Erzeugung eines Löschantrags angeboten. +'); +INSERT INTO txt VALUES ('H1154', 'English', 'Rules: Unused - display all rules where the last hit lies before a given time. + Devices delivering no usage information are disregarded. If the reporter also has the requester role, a button to create a delete rule request is offered after selecting reported rules. +'); +INSERT INTO txt VALUES ('H1155', 'German', 'Regeln: NAT - Anzeige der NAT-Regeln und nicht der Zugriffsregeln. Default-Report-Zeitpunkt: jetzt'); +INSERT INTO txt VALUES ('H1155', 'English', 'Rules: NAT - display NAT rules instead of access rules. Default report time: now'); +INSERT INTO txt VALUES ('H1156', 'German', 'Changes: Standard - Anzeige von Änderungen in einem bestimmten Zeitraum. Default-Report-Zeitraum: dieses Jahr'); +INSERT INTO txt VALUES ('H1156', 'English', 'Changes: Standard - display all changes in a defined time interval. Default report interval: this year'); +INSERT INTO txt VALUES ('H1157', 'German', 'Changes: Aufgelöst - Anzeige von Änderungen in einem bestimmten Zeitraum, wobei sämtliche Gruppen in Quelle, Ziel und Dienst aufgelöst werden. Default-Report-Zeitraum: dieses Jahr'); +INSERT INTO txt VALUES ('H1157', 'English', 'Changes: Resolved - display all changes in a defined time interval with groups in source, destination and service resolved. Default report interval: this year'); +INSERT INTO txt VALUES ('H1158', 'German', 'Changes: Technisch - wie der aufgelöste Changes-Report, nur dass Objektnamen nicht angezeigt werden. Default-Report-Zeitraum: dieses Jahr'); +INSERT INTO txt VALUES ('H1158', 'English', 'Changes: Technical - like the resolved changes report, but object names are not shown. Default report interval: this year'); +INSERT INTO txt VALUES ('H1159', 'German', 'Statistik - Anzeige von Statistikdaten über Anzahl von Objekten und Regeln. Default-Report-Zeitpunkt: jetzt'); +INSERT INTO txt VALUES ('H1159', 'English', 'Statistics - display statistical data about the number of objects and rules. Default report time: now'); +INSERT INTO txt VALUES ('H1160', 'German', 'Compliance - Anzeige von Compliance-bezogenen Regeln. Die Tabelle enthält zusätzlich eine Spalte "ExpirationTime", die die erste verfügbare Rule-Time-Ablaufzeit anzeigt.'); +INSERT INTO txt VALUES ('H1160', 'English', 'Compliance - display compliance-related rules. The table additionally contains an "ExpirationTime" column that shows the first available rule-time expiration.'); +INSERT INTO txt VALUES ('H1160a','German', 'Compliance: Differenzen - Darstellung der Unterschiede zwischen zwei Compliance-Ständen in einem gewählten Zeitraum.'); +INSERT INTO txt VALUES ('H1160a','English', 'Compliance: Differences - display the differences between two compliance states in a selected time range.'); +INSERT INTO txt VALUES ('H1161', 'German', 'Modell: Verbindungen - Anzeige aller in einer Applikation modellierten Verbindungen, Schnittstellen und eigener Common Services + mit zusätzlicher Auflistung aller hierin verwendeten Netzwerk- und Serviceobjekte. Hinzu kommt eine Liste aller globalen Common Services. +'); +INSERT INTO txt VALUES ('H1161', 'English', 'Model: Connections - display all connections, interfaces and own Common Services modelled in an application, plus lists of all network and service objects used there. + Additionally a list of all global Common Services is shown. +'); +INSERT INTO txt VALUES ('H1162', 'German', 'Modell: App-Regeln - Darstellung aller Regeln, in welchen Objekte eines vorgegebenen Eigentümers verwendet werden. Diese werden farblich hervorgehoben. + Es kann weiter spezifiziert werden, ob nur Quelle, Ziel oder beides sowie ob "Any"-Objekte berücksichtigt werden sollen. +'); +INSERT INTO txt VALUES ('H1162', 'English', 'Model: App Rules - display all rules where objects of the selected owner are used. + These objects are highlighted. It can be specified whether source, destination or both, and whether "any" objects, should be considered. +'); +INSERT INTO txt VALUES ('H1163', 'German', 'Modell: Soll-Ist - Darstellung aller Abweichungen zwischen den modellierten Verbindungen und den auf den Firewalls gefundenen Objekten und Regeln. + Optional können zusätzlich die noch nicht modellierten Regeln in Form des App-Regel-Reports aufgelistet werden. +'); +INSERT INTO txt VALUES ('H1163', 'English', 'Model: Variances - display all differences between modelled connections and the objects and rules found on the firewalls. + Optionally, not yet modelled rules can also be listed in the form of the App Rules report. +'); +INSERT INTO txt VALUES ('H1164', 'German', 'Zert: Regel-Übersicht - Anzeige aller Regeln mit anstehenden Rezertifizierungen. Der Default-Report-Zeitraum kann in den Einstellungen gesetzt werden.'); +INSERT INTO txt VALUES ('H1164', 'English', 'Cert: Rule Overview - display all rules with upcoming recertifications. The default report interval can be configured in settings.'); +INSERT INTO txt VALUES ('H1165', 'German', 'Zert: Eigentümer-Übersicht - Darstellung aller Eigentümer nach ihrem Rezertifizierungsstatus. In den regulären Kapiteln werden nur Eigentümer mit aktiver Rezertifizierung dargestellt. + "Alle Eigentümer zeigen" erweitert diese Sicht auf alle aktiven Eigentümer, unabhängig vom nächsten Rezertifizierungsdatum. + Mit der zusätzlichen Option für inaktive Rezertifizierung werden Eigentümer ohne aktive Rezertifizierung in einem separaten Kapitel dargestellt. +'); +INSERT INTO txt VALUES ('H1165', 'English', 'Cert: Owner Overview - display all owners by their recertification status. The regular chapters only show owners with active recertification. + "Show all owners" expands this to all active owners, regardless of the next recertification date. + With the additional option for inactive recertification, owners without active recertification are shown in a separate chapter. +'); +INSERT INTO txt VALUES ('H1166', 'German', 'Zert: Zert-Regel-Details - Darstellung einer Eigentümer-Rezertifizierung mitsamt der mitrezertifizierten Regeln.'); +INSERT INTO txt VALUES ('H1166', 'English', 'Cert: Cert Rule Details - display an owner recertification together with the related rule recertifications.'); +INSERT INTO txt VALUES ('H1167', 'German', 'Workflow: Ticket-Änderungen - Darstellung von Workflow-Tickets innerhalb eines gewählten Zeitraums bezogen auf ein auswählbares Referenzdatum. + Zusätzlich kann nach Tasktypen und Ticket-Status gefiltert sowie die Detailtiefe der Ausgabe gesteuert werden. +'); +INSERT INTO txt VALUES ('H1167', 'English', 'Workflow: Ticket Changes - display workflow tickets in a selected time range based on a selectable reference date. + Additional filters are available for task types, ticket states and the amount of detail shown in the output. +'); +INSERT INTO txt VALUES ('H1167a', 'German', 'Workflow: Tickets - Darstellung von Workflow-Tickets mit ihrem aktuellen Stand und den zugehörigen Aufgaben.'); +INSERT INTO txt VALUES ('H1167a', 'English', 'Workflow: Tickets - display workflow tickets with their current state and related tasks.'); +INSERT INTO txt VALUES ('H1168', 'German', 'Eigentümer - Darstellung aller Eigentümer mit Kritikalität, Lebenszyklusstatus und zusätzlichen Informationen.'); +INSERT INTO txt VALUES ('H1168', 'English', 'Owners - display all owners with criticality, lifecycle status and additional information.'); INSERT INTO txt VALUES ('H1201', 'German', 'Vorlagen können genutzt werden, um wiederkehrende Reports zu definieren. Diese werden für das Scheduling benötigt. Jeder Nutzer kann seine eigenen Vorlagen definieren und sie mit anderen teilen.
    Beim Anlegen einer neuen Vorlage über die Schaltfläche "Als Vorlage speichern" wird ein Pop-Up-Fenster geöffnet, in dem Name und ein Kommentar vergeben werden können. @@ -2424,20 +4352,24 @@ INSERT INTO txt VALUES ('H1202', 'German', 'Um sie direkt in der UI zu nutzen, INSERT INTO txt VALUES ('H1202', 'English', 'For using them directly on the UI, devices have to be selected additionally. Used in scheduling, all devices are regarded as selected. These templates can be used as basis for the creation of own self-defined templates. '); -INSERT INTO txt VALUES ('H1211', 'German', 'Einfache Statistik: Etwas Statistik über Netzwerk-, Dienst- und Nutzerobjekte aller Devices.'); +INSERT INTO txt VALUES ('H1211', 'German', 'Basic Statistics: Etwas Statistik über Netzwerk-, Dienst- und Nutzerobjekte aller Devices.'); INSERT INTO txt VALUES ('H1211', 'English', 'Basic Statistics: Some statistics about network, service and user objects and rules of all devices.'); -INSERT INTO txt VALUES ('H1212', 'German', 'Compliance: Durchlassregeln mit "any": Alle Durchlassregeln, die "any" als Quelle, Ziel oder Dienst enthalten.'); +INSERT INTO txt VALUES ('H1212', 'German', 'Compliance: Pass rules with "any": Alle Durchlassregeln, die "any" als Quelle, Ziel oder Dienst enthalten.'); INSERT INTO txt VALUES ('H1212', 'English', 'Compliance: Pass rules with "any": All pass rules that contain "any" as source, destination or service.'); -INSERT INTO txt VALUES ('H1213', 'German', 'Aktuelle Regeln: Aktuell aktive Regeln aller ausgewählten Devices.'); +INSERT INTO txt VALUES ('H1213', 'German', 'Current Rules: Aktuell aktive Regeln aller ausgewählten Devices.'); INSERT INTO txt VALUES ('H1213', 'English', 'Current Rules: Currently active rules of all selected devices.'); -INSERT INTO txt VALUES ('H1214', 'German', 'Regeländerungen des aktuellen Jahres: Alle im aktuellen Jahr geänderten Regeln in den ausgewählten Devices.'); +INSERT INTO txt VALUES ('H1214', 'German', 'This year's Rule Changes: Alle im aktuellen Jahr geänderten Regeln in den ausgewählten Devices.'); INSERT INTO txt VALUES ('H1214', 'English', 'This year's Rule Changes: All rule change performed in the current year in the selected devices.'); -INSERT INTO txt VALUES ('H1215', 'German', 'Aktuelle NAT Regeln: Aktuell aktive NAT-Regeln aller ausgewählten Devices.'); +INSERT INTO txt VALUES ('H1215', 'German', 'Current NAT Rules: Aktuell aktive NAT-Regeln aller ausgewählten Devices.'); INSERT INTO txt VALUES ('H1215', 'English', 'Current NAT Rules: Currently active NAT rules of all selected devices.'); +INSERT INTO txt VALUES ('H1216', 'German', 'Last year's Unused Rules: Aktuell aktive und seit mindestens einem Jahr unbenutzte Regeln aller Gateways.'); +INSERT INTO txt VALUES ('H1216', 'English', 'Last year's Unused Rules: Currently active and for at least one year unused rules of all gateways.'); +INSERT INTO txt VALUES ('H1217', 'German', 'Next Month's Recertifications: Aktuell aktive Regeln, die im nächsten Monat zur Rezertifizierung anstehen.'); +INSERT INTO txt VALUES ('H1217', 'English', 'Next Month's Recertifications: Currently active rules with upcoming recertification next month.'); INSERT INTO txt VALUES ('H1301', 'German', 'Direkt nach der Erzeugung oder vom Archiv aus können Reports in verschiedenen Ausgabeformaten exportiert werden:'); INSERT INTO txt VALUES ('H1301', 'English', 'Directly after creation or from the archive reports can be exported to different output formats:'); -INSERT INTO txt VALUES ('H1302', 'German', '
  • pdf
  • html
  • csv (aktuell nur für die aufgelösten und technischen Report-Typen unterstützt)
  • json
  • '); -INSERT INTO txt VALUES ('H1302', 'English', '
  • pdf
  • html
  • csv (currently only supported for resolved and technical report types)
  • json
  • '); +INSERT INTO txt VALUES ('H1302', 'German', '
  • pdf
  • html
  • csv (für aufgelöste, Compliance-, Eigentümer- und Workflow-Report-Typen verfügbar; bei Workflow-Reports nur ohne Detailansicht)
  • json
  • '); +INSERT INTO txt VALUES ('H1302', 'English', '
  • pdf
  • html
  • csv (available for resolved, compliance, owners, and workflow report types; for workflow reports only without detailed view)
  • json
  • '); INSERT INTO txt VALUES ('H1303', 'German', 'Nach betätigen des "Report exportieren"-Auswahlfeldes kann eines oder mehrere dieser Formate ausgewählt werden. Bei Aktivierung der pdf-Ausgabe wird desweiteren das Seitenformat zur Auswahl angeboten.
    Auch kann der Report mit einem Namen versehen und archiviert werden. @@ -2446,38 +4378,76 @@ INSERT INTO txt VALUES ('H1303', 'German', 'Nach betätigen des "Report exp INSERT INTO txt VALUES ('H1303', 'English', 'After clicking the "Export Report" button one or more of them can be selected. When selecting the pdf export, the page format is offered for selection.
    Also the possibility to name and save the report in the archive is given. - Another Popup allows then to download the selected output files separately. + Another Popup allows then to download the selected output files separately. '); INSERT INTO txt VALUES ('H1401', 'German', 'Im unteren Teil der Hauptseite werden die Ausgabedaten des generierten Reports dargestellt. Unerwünschte Spalten können mit der jeweiligen "-" Schaltfläche ausgeblendet werden. Wenn dargestellt, können die Spalten auch zum Sortieren oder Filtern genutzt werden.
    - Die zur Verfügung stehenden Datenspalten sind: + Die in regelbasierten Reports zur Verfügung stehenden Datenspalten sind: '); INSERT INTO txt VALUES ('H1401', 'English', 'In the lower part of the main page the output data of the generated report is displayed. - Unwanted columns can be removed by clicking on the respective "-" button. + Unwanted columns can be removed by clicking on the respective "-" button. If diplayed the columns can be used for sorting or filtering.
    - The available data columns are: -'); -INSERT INTO txt VALUES ('H1402', 'German', '
  • Nummer
  • Name
  • Quellzone
  • Quelle
  • Zielzone
  • -
  • Ziel
  • Dienste
  • Aktion
  • Logging
  • Aktiviert
  • UID
  • Kommentar
  • + The available data columns in rule based reports are: +'); +INSERT INTO txt VALUES ('H1402', 'German', '
  • Nummer: Laufende Regel- oder Eintragsnummer innerhalb des Reports.
  • +
  • Name: Anzeigename der Regel oder des dargestellten Objekts.
  • +
  • Quellzone: Firewall-Zone oder Bereich der Quellobjekte.
  • +
  • Quelle: Quellnetz, Host, Gruppe oder Objektliste.
  • +
  • Zielzone: Firewall-Zone oder Bereich der Zielobjekte.
  • +
  • Ziel: Zielnetz, Host, Gruppe oder Objektliste.
  • +
  • Dienste: Zugeordnete Dienste bzw. Service-Gruppen.
  • +
  • Aktion: Regelaktion wie erlauben, blockieren oder ähnliche technische Aktionen.
  • +
  • Logging: Gibt an, ob und wie Zugriffe zu diesem Eintrag protokolliert werden.
  • +
  • Aktiviert: Kennzeichnet, ob die Regel oder der Eintrag aktuell aktiv ist.
  • +
  • LastModified: Importdatum der letzten Änderung des Regeleintrags.
  • +
  • UID: Technische eindeutige Kennung des Eintrags im importierten Datenbestand.
  • +
  • Kommentar: Freitext-Kommentar oder technische Zusatzinformation aus der Quelldatenbasis.
  • +'); +INSERT INTO txt VALUES ('H1402', 'English', '
  • Number: Sequential rule or entry number within the report.
  • +
  • Name: Display name of the rule or shown object.
  • +
  • Source Zone: Firewall zone or area of the source objects.
  • +
  • Source: Source network, host, group or object list.
  • +
  • Destination Zone: Firewall zone or area of the destination objects.
  • +
  • Destination: Destination network, host, group or object list.
  • +
  • Services: Assigned services or service groups.
  • +
  • Action: Rule action such as allow, deny or similar technical actions.
  • +
  • Logging: Indicates whether and how access for this entry is logged.
  • +
  • Enabled: Marks whether the rule or entry is currently active.
  • +
  • LastModified: Import date of the last change to the rule entry.
  • +
  • UID: Technical unique identifier of the entry in the imported data set.
  • +
  • Comment: Free-text comment or technical additional information from the source data.
  • +'); +INSERT INTO txt VALUES ('H1403', 'German', 'Zusätzlich werden in regelbasierten Reporttypen weitere Spalten dargestellt: +
      +
    • Changes: Änderungszeit, Änderungstyp (Regelnummerierung entfällt dafür)
    • +
    • Regeln: Unbenutzt: Letzter Treffer
    • +
    • Regeln: NAT: Umgesetzte Quelle, Umgesetztes Ziel, Umgesetzte Dienste
    • +
    '); -INSERT INTO txt VALUES ('H1402', 'English', '
  • Number
  • Name
  • Source Zone
  • Source
  • Destination Zone
  • -
  • Destination
  • Services
  • Action
  • Logging
  • Enabled
  • UID
  • Comment
  • +INSERT INTO txt VALUES ('H1403', 'English', 'Additionally, rule-based report types can show further columns: +
      +
    • Changes: Change Time, Change Type (but no rule numbering)
    • +
    • Rules: Unused: Last Hit
    • +
    • Rules: NAT: Translated Source, Translated Destination, Translated Services
    • +
    '); -INSERT INTO txt VALUES ('H1403', 'German', 'Zusätzlich werden in einzelnen Reporttypen weitere Spalten dargestellt: +INSERT INTO txt VALUES ('H1404', 'German', 'Nicht regelbasierte Reports verwenden eigene Ausgabespalten, zum Beispiel:
      -
    • Changes report: Änderungszeit, Änderungstyp (Regelnummerierung entfällt dafür)
    • -
    • Unbenutzte-Regel-Report: Letzter Treffer
    • -
    • NAT-Regel-Report: Umgesetzte Quelle, Umgesetztes Ziel, Umgesetzte Dienste
    • -
    • Rezertifizierungs-Report: Datum nächste Rezertifizierung, Eigentümer, IP-Adress-Übereinstimmung, Letzter Treffer
    • +
    • Compliance: zusätzliche Compliance- und Ablaufinformationen, z.B. ExpirationTime
    • +
    • Eigentümer: Kritikalität, Lifecycle-Status sowie weitere Eigentümer-Informationen
    • +
    • Workflow: Ticket-, Task-, Status- und Referenzdatumsinformationen je nach Reporttyp und Detailansicht
    • +
    • Zert: Regel-Übersicht und Zert: Zert-Regel-Details: nächste Rezertifizierung, Eigentümer, IP-Adress-Übereinstimmung, Letzter Treffer
    • +
    • Modell: Verbindungen: Nummer, Name, fachliche Begründung, Quelle, Dienst und Ziel
    '); -INSERT INTO txt VALUES ('H1403', 'English', 'Additionally in the different Report Types further columns are displayed: +INSERT INTO txt VALUES ('H1404', 'English', 'Non-rule-based reports use their own output columns, for example:
      -
    • Changes report: Change Time, Change Type (but no rule numbering)
    • -
    • Unused Rules Report: Last Hit
    • -
    • NAT Rules Report: Translated Source, Translated Destination, Translated Services
    • -
    • Recertification Report: Next Recertification Date, Owner, IP address match, Last Hit
    • +
    • Compliance: additional compliance and expiration information, e.g. ExpirationTime
    • +
    • Owners: criticality, lifecycle state and further owner information
    • +
    • Workflow: ticket, task, state and reference-date information depending on report type and detailed view
    • +
    • Cert: Rule Overview and Cert: Cert Rule Details: next recertification, owner, IP address match, last hit
    • +
    • Model: Connections: number, name, functional reason, source, service and destination
    '); @@ -2510,11 +4480,11 @@ INSERT INTO txt VALUES ('H1504', 'English', 'Display of the selected report time INSERT INTO txt VALUES ('H1505', 'German', 'Für Report-Typen, welche die Angabe eines Zeitpunktes erfordern, gibt es zwei Optionen: Auswahl eines bestimmten Zeitpunktes mit dem Date-Picker oder die Nutzung des Vorgabewertes "jetzt". '); -INSERT INTO txt VALUES ('H1505', 'English', 'For report types requiring a report time there are two options: +INSERT INTO txt VALUES ('H1505', 'English', 'For report types requiring a report time there are two options: Selecting a particular time with the date/time picker or using the default value "now". '); -INSERT INTO txt VALUES ('H1506', 'German', 'Für Report-Typen, die Zeitintervalle benötigen (nicht Unbenutzte-Regel- und Rezertifizierungs-Report), kann gewählt werden zwischen:'); -INSERT INTO txt VALUES ('H1506', 'English', 'For report types requiring a time range (not Unused Rule or Recertification Report) a selection can be done between:'); +INSERT INTO txt VALUES ('H1506', 'German', 'Für Report-Typen, die Zeitintervalle benötigen (nicht Regeln: Unbenutzt und Zert: Zert-Regel-Details), kann gewählt werden zwischen:'); +INSERT INTO txt VALUES ('H1506', 'English', 'For report types requiring a time range (not Rules: Unused or Cert: Cert Rule Details) a selection can be done between:'); INSERT INTO txt VALUES ('H1507', 'German', 'Vordefinierte Abkürzungen "dieses Jahr", "letztes Jahr", "dieser Monat", "letzter Monat", "diese Woche", "letzte Woche", "heute" oder "gestern"'); INSERT INTO txt VALUES ('H1507', 'English', 'Predefined shortcuts "this year", "last year", "this month", "last month", "this week", "last week", "today" or "yesterday"'); INSERT INTO txt VALUES ('H1508', 'German', 'Zeitintervalle in Tagen, Wochen, Monaten oder Jahren relativ zum aktuellen Zeitpunkt'); @@ -2523,38 +4493,83 @@ INSERT INTO txt VALUES ('H1509', 'German', 'Absolute Start- und Endezeiten. Bei INSERT INTO txt VALUES ('H1509', 'English', 'Absolute start and end times. Both limits can be separately omitted by setting the "open" checkbox.'); INSERT INTO txt VALUES ('H1510', 'German', 'Nur beim Unbenutzte-Regel-Report: Unbenutzt seit: Hier wird die Anzahl von Tagen eingegeben, seitdem die anzuzeigenden Regeln nicht mehr benutzt wurden. Regeln, die noch keine letzte Nutzung protokolliert haben, werden ebenfalls dargestellt, falls sie älter als eine in den Reporting-Einstellungen definierte Toleranzzeit sind. - Dort kann auch der Default-Wert für den Zeitraum der Nichtbenutzung gesetzt werden. + Dort kann auch der Default-Wert für den Zeitraum der Nichtbenutzung gesetzt werden. '); INSERT INTO txt VALUES ('H1510', 'English', 'Only for Unused Rules Report: Unused since: Here the number of days is given, where the rules to be displayed have not be used. Rules never used are also displayed if their creation date is older than a tolerance interval defined in the Report Settings. There also the default value for the unused interval can be defined. '); -INSERT INTO txt VALUES ('H1511', 'German', 'Nur beim Rezertifizierungs-Report: Rezertifizierungsparameter -
  • Fällig in: Hier wird festgelegt, wie weit die Suche nach zu rezertifizierenden Regeln gehen soll (in Tagen). +INSERT INTO txt VALUES ('H1511', 'German', 'Nur beim Zert-Regel-Details: Rezertifizierungsparameter +
    • Fällig in: Hier wird festgelegt, wie weit die Suche nach zu rezertifizierenden Regeln gehen soll (in Tagen). Der Default-Wert kann sowohl vom Administrator in den Allgemeinen als auch vom jeweiligen Nutzer in den Persönlichen Rezertifizierungseinstellungen festgelegt werden.
    • Eigentümer: Hier kann aus den dem Nutzer zugeordneten Eigentümerschaften ausgewählt werden.
    • Any-Regeln anzeigen: Wenn das Häkchen gesetzt ist, werden auch Regeln mit Ip 0.0.0.0 in Quelle oder Ziel dargestellt. - Beim deselektieren wird ein exkludierender Ausdruck zur Filterzeile hinzugefügt.
    • + Beim deselektieren wird ein exkludierender Ausdruck zur Filterzeile hinzugefügt.
    '); -INSERT INTO txt VALUES ('H1511', 'English', 'Only for Recertification Report: Recertification Parameters -
  • Due within: Select how far ahead should be searched for rules to be recertified (in days). +INSERT INTO txt VALUES ('H1511', 'English', 'Only for Cert Rule Details: Recertification Parameters +
    • Due within: Select how far ahead should be searched for rules to be recertified (in days). The default value can be set by the administrator in the General - as well as in the Personal Recertification Settings by the user
    • . + as well as in the Personal Recertification Settings by the user.
    • Owner: Select the certifying owner out of the ownerships related to the user.
    • Show any rules: If flag is set, rules with Ip 0.0.0.0 in source or destination are shown. - When deselecting an excluding statement is added to the filter line.
    • -'); -INSERT INTO txt VALUES ('H1601', 'German', 'Die rechte Randleiste hat zwei Reiter: Unter "Alle" werden alle aktuell abgeholten Objekte dargestellt, - während unter "Regel" nur die in der Reportausgabe ausgewählten Regeln gezeigt werden.
      - Folgende Daten werden dargestellt, gruppiert nach den ausgewählten Devices: -'); -INSERT INTO txt VALUES ('H1601', 'English', 'There are two Tabs shown in the right sidebar: The "All" tab displays all currently fetched objects, - while in the "Rule" tab only the objects of rules selected in the report output are shown.
      - The following data are displayed grouped by the selected devices: + When deselecting an excluding statement is added to the filter line.
    +'); +INSERT INTO txt VALUES ('H1512', 'German', 'Nur bei Modell: Verbindungen und App-Regeln: Eigentümer: Hier kann aus den dem Nutzer zur Modellierung zugeordneten Eigentümerschaften ausgewählt werden. '); +INSERT INTO txt VALUES ('H1512', 'English', 'Only for Model: Connections and App Rules: Owner: Select the modelling owner out of the ownerships related to the user.'); +INSERT INTO txt VALUES ('H1513', 'German', 'Nur beim Modell: App-Regeln: Weitere Parameter zur Einschränkung der Treffermenge: Berücksichtigung von Quelle und/oder Ziel, Any- oder Drop-Regeln. + Desweiteren, ob nicht relevante Teile der Regel dargestellt werden sollen oder nicht. +'); +INSERT INTO txt VALUES ('H1513', 'English', 'Only for Model: App Rules: Further parameters to reduce the selected rules: Regard Source and/or Destination, Any or Drop rules. + Furtheron, if not relevant parts of the rules shall be displayed or not. +'); +INSERT INTO txt VALUES ('H1514', 'German', 'Nur beim Modell: Soll-Ist: Verbleibende Regeln analysieren: Die dem Eigentümer zugeordneten nicht modellierten Regeln werden in Form eines App-Regel-Reports an den report angehängt.'); +INSERT INTO txt VALUES ('H1514', 'English', 'Only for Model: Variances: Analyse remaining rules: Not modelled rules associated to the owner are appended to the report as App Rules Report.'); +INSERT INTO txt VALUES ('H1515', 'German', 'Nur bei Workflow: Ticket-Änderungen: Workflow-spezifische Parameter zur Eingrenzung der angezeigten Tickets und ihrer Details.'); +INSERT INTO txt VALUES ('H1515', 'English', 'Only for Workflow: Ticket Changes: workflow-specific parameters to restrict the displayed tickets and their details.'); +INSERT INTO txt VALUES ('H1516', 'German', 'Für Workflow: Ticket-Änderungen stehen folgende Parameter zur Verfügung:'); +INSERT INTO txt VALUES ('H1516', 'English', 'For Workflow: Ticket Changes the following parameters are available:'); +INSERT INTO txt VALUES ('H1517', 'German', 'Referenzdatum: Legt fest, auf welches Datum oder Ereignis der gewählte Zeitraum angewendet wird, z.B. Ticket-Erstellung, Ticket-Abschluss, Aufgabenstart, Aufgabenende, Freigaben oder beliebige Aktivität. Bei Workflow-Ticketänderungen kann derselbe Filter auch in der Filterleiste mit reference_date=... gesetzt werden.'); +INSERT INTO txt VALUES ('H1517', 'English', 'Reference date: Defines which date or event the selected time range is applied to, e.g. ticket creation, ticket closure, task start, task end, approvals or any activity. For workflow ticket change reports the same filter can also be set in the filter line with reference_date=....'); +INSERT INTO txt VALUES ('H1518', 'German', 'Tasktyp: Mehrfachauswahl der zu berücksichtigenden Request-Tasktypen. Die Option "alle" ist vorbelegt und wählt alle verfügbaren Typen aus. Derselbe Filter kann auch in der Filterleiste mit tasktype=... gesetzt werden.'); +INSERT INTO txt VALUES ('H1518', 'English', 'Task type: Multiselect of request task types to be considered. The option "all" is selected by default and represents all available types. The same filter can also be set in the filter line with tasktype=....'); +INSERT INTO txt VALUES ('H1519', 'German', 'Status: Mehrfachauswahl der Ticket-Statuswerte. Ohne explizite Auswahl werden Tickets aller Status berücksichtigt. Derselbe Filter kann auch in der Filterleiste mit state=... oder states=... gesetzt werden; dort werden numerische Status-IDs erwartet.'); +INSERT INTO txt VALUES ('H1519', 'English', 'State: Multiselect of ticket states. Without an explicit selection, tickets of all states are considered. The same filter can also be set in the filter line with state=... or states=...; there the values must be numeric state ids.'); +INSERT INTO txt VALUES ('H1520', 'German', 'Vollständiges Ticket anzeigen: Ist diese Option aktiviert, werden zu jedem gefundenen Ticket alle enthaltenen Request Tasks, Implementierungs-Tasks und Freigaben angezeigt. Ist sie deaktiviert, werden in den Details nur Objekte angezeigt, deren Referenzdatum im gewählten Zeitraum liegt.'); +INSERT INTO txt VALUES ('H1520', 'English', 'Show full ticket: If this option is enabled, every matching ticket shows all contained request tasks, implementation tasks and approvals. If it is disabled, the details only show objects whose reference date lies within the selected time range.'); +INSERT INTO txt VALUES ('H1521', 'German', 'Phase: Beschränkt die Ticketauswahl auf den Statusbereich der gewählten aktiven Workflow-Phase. In der Statusauswahl werden dann nur Status angeboten, die in dieser Phase verwendet werden. Derselbe Filter kann auch in der Filterleiste mit phase=... gesetzt werden.'); +INSERT INTO txt VALUES ('H1521', 'English', 'Phase: Restricts the ticket selection to the status range of the selected active workflow phase. The state dropdown then only offers states that are used in this phase. The same filter can also be set in the filter line with phase=....'); +INSERT INTO txt VALUES ('H1522', 'German', 'Label: Filtert Workflow-Tickets über ein zusätzliches Info-Feld in den Request Tasks. Der Dialog erlaubt Name und erwarteten Zustand oder Wert des Labels zu definieren.'); +INSERT INTO txt VALUES ('H1522', 'English', 'Label: Filters workflow tickets by an additional info field on the request tasks. The dialog allows defining the label name and the expected label state or value.'); +INSERT INTO txt VALUES ('H1523', 'German', 'Name: Referenziert einen Schlüssel im AdditionalInfo-Feld des Request Tasks, z.B. ein Label, das zuvor durch eine Action gesetzt wurde.'); +INSERT INTO txt VALUES ('H1523', 'English', 'Name: References a key in the request task additional info field, for example a label that was set earlier by an action.'); +INSERT INTO txt VALUES ('H1524', 'German', 'Detaillierte Ansicht: Ist diese Option aktiviert, werden Request Tasks und deren Details im Bericht angezeigt. Der CSV-Export steht nur zur Verfügung, wenn diese Option deaktiviert ist.'); +INSERT INTO txt VALUES ('H1524', 'English', 'Detailed view: If this option is enabled, request tasks and their details are shown in the report. CSV export is only available when this option is disabled.'); +INSERT INTO txt VALUES ('H1525', 'German', 'Nur beim Report Eigentümer: Status und Kritikalität: Diese Felder schränken die angezeigten Eigentümer auf den ausgewählten Lifecycle-Status bzw. die ausgewählte Kritikalität ein. Die Voreinstellung "alle" lässt den jeweiligen Filter inaktiv.'); +INSERT INTO txt VALUES ('H1525', 'English', 'Only for Owners report: State and Criticality: These fields restrict the displayed owners to the selected lifecycle state and selected criticality. The default value "all" leaves the respective filter inactive.'); + +INSERT INTO txt VALUES ('H1601', 'German', 'Die rechte Randleiste hat mehrere Reiter, die je nach Report eingeblendet werden: Für regelbasierte Reports werden unter "Alle" sämtliche aktuell abgeholten Objekte dargestellt, + während unter "Report" nur die Objekte der im Report vorkommenden Regeln gezeigt werden. + Im Reiter "Regel" sind dann nur die Objekte der in der Reportausgabe ausgewählten Regeln dargestellt.
    + ("Alle"- und "Regel"-Reiter werden mit derselben Funktionalität auch im Rezertifizierungsdialog angeboten).
    + In eigentümerbasierten Reports erscheint der Reiter "Benutzte Objekte", in dem alle in den Verbindungen verwendeten Objekte aufgelistet werden.
    + Folgende Daten werden soweit verfügbar dargestellt, gruppiert nach den ausgewählten Devices: +'); +INSERT INTO txt VALUES ('H1601', 'English', 'There are several tabs shown in the right sidebar, depending on the report type: In rule based reports the "All" tab displays all currently fetched objects, + whereas in the "Report" tab only the objects of the rules of the report are shown. + In the "Rule" tab only objects of rules selected in the report output are dispalyed.
    + ("All" and "Rule" tab are also offered in the Recertification dialogue with the same functionality).
    + In owner based reports the Tab "Used Objects" is displayed, where all objects used in the connections are listed.
    + The following data are displayed if available, grouped by the selected devices: +'); +INSERT INTO txt VALUES ('H1602', 'German', '
  • Netzwerkobjekte: Name, Typ, IP, Zone, ggf. Gruppenmitglieder, zuletzt geändert, Kommentar
  • +
  • Dienste: Name, Typ, UID, Quellport, Zielport, Protokoll, Timeout, ggf. Gruppenmitglieder, zuletzt geändert, Kommentar
  • +
  • Nutzer: Name, Typ, UID, realer Name, ggf. Gruppenmitglieder, zuletzt geändert, Kommentar
  • +'); +INSERT INTO txt VALUES ('H1602', 'English', '
  • Network objects: Name, type, IP, zone, group members if applicable, last changed, comment
  • +
  • Services: Name, type, UID, source port, destination port, protocol, timeout, group members if applicable, last changed, comment
  • +
  • Users: Name, type, UID, real name, group members if applicable, last changed, comment
  • '); -INSERT INTO txt VALUES ('H1602', 'German', '
  • Netzwerkobjekte
  • Dienste
  • Nutzer
  • '); -INSERT INTO txt VALUES ('H1602', 'English', '
  • Network objects
  • Services
  • Users
  • '); INSERT INTO txt VALUES ('H2001', 'German', 'Es können Reports für einen bestimmten Termin oder als wiederkehrende Aufträge festgelegt werden. Jeder Nutzer kann seine eigenen Terminpläne verwalten. @@ -2562,18 +4577,20 @@ INSERT INTO txt VALUES ('H2001', 'German', 'Es können Reports für ein INSERT INTO txt VALUES ('H2001', 'English', 'Reports can be scheduled for a given time or as recurring tasks. Every user can administrate his own report schedules. '); +INSERT INTO txt VALUES ('H2001a', 'German', 'Der Inhalt geplanter Reports wird in der Sprache des Schedule-Owners erzeugt.'); +INSERT INTO txt VALUES ('H2001a', 'English','Scheduled report content is generated in the language of the schedule owner.'); INSERT INTO txt VALUES ('H2011', 'German', 'Name: Der Reportname, der im Archiv wiederzufinden ist.'); INSERT INTO txt VALUES ('H2011', 'English', 'Name: The report name to be found in the Archive.'); INSERT INTO txt VALUES ('H2012', 'German', 'Startdatum und -zeit: Erste Ausführung des Terminauftrags. - Bitte einige Minuten im voraus wählen, wenn die Ausführung noch heute erfolgen soll, da es einen Zeitverzug von einigen Minuten durch den Timer geben kann. + Bitte einige Minuten im voraus wählen, wenn die Ausführung noch heute erfolgen soll, da es einen Zeitverzug von einigen Minuten durch den Timer geben kann. '); -INSERT INTO txt VALUES ('H2012', 'English', 'Start date and time: First execution of the schedule. +INSERT INTO txt VALUES ('H2012', 'English', 'Start date and time: First execution of the schedule. Be aware of selecting some minutes ahead if execution should start by today, as there may be a timer delay of some minutes. '); INSERT INTO txt VALUES ('H2013', 'German', 'Wiederholungsintervall: Es können Abstände in Tagen, Wochen, Monaten oder Jahren ausgewählt werden. - Wenn "Niemals" gewählt wird, wird der Auftrag nur einmal ausgeführt. + Wenn "Niemals" gewählt wird, wird der Auftrag nur einmal ausgeführt. '); -INSERT INTO txt VALUES ('H2013', 'English', 'Repetition interval: Intervals in days, weeks, months or years can be selected. +INSERT INTO txt VALUES ('H2013', 'English', 'Repetition interval: Intervals in days, weeks, months or years can be selected. If "Never" is selected, only one execution is scheduled. '); INSERT INTO txt VALUES ('H2014', 'German', 'Vorlagen: Hier muss eine der vorbereiteten Vorlagen ausgewählt werden.'); @@ -2585,7 +4602,7 @@ INSERT INTO txt VALUES ('H2015', 'English', 'Output formats: One or more of the If nothing is selected, a json output is prepared. '); INSERT INTO txt VALUES ('H2016', 'German', 'Aktiv-Kennzeichen: Nur als aktiv gekennzeichnete Aufträge werden ausgeführt. - So können Aufträge für die Zukunft vorbereitet werden, bzw. vorübergehend nicht benötigte Aufträge müssen nicht gelöscht werden. + So können Aufträge für die Zukunft vorbereitet werden, bzw. vorübergehend nicht benötigte Aufträge müssen nicht gelöscht werden. '); INSERT INTO txt VALUES ('H2016', 'English', 'Active Flag: Only schedules with this flag set will be executed. So report schedules for future use can be prepared, resp. schedules currently not needed do not have to be deleted. @@ -2594,36 +4611,44 @@ INSERT INTO txt VALUES ('H2017', 'German', 'Eigentümer: Ersteller dieses T INSERT INTO txt VALUES ('H2017', 'English', 'Owner: Creator of this schedule.'); INSERT INTO txt VALUES ('H2018', 'German', 'Zähler: Zählt, wie viele Reports mit diesem Terminauftrag bereits erstellt wurden.'); INSERT INTO txt VALUES ('H2018', 'English', 'Count: Counts how many reports have already been created with this schedule.'); +INSERT INTO txt VALUES ('H2019', 'German', 'Empfänger-Email-Adressen für Benachrichtigungen: Komma-separierte Liste von Email-Adressen, an die die durch diesen Termin erzeugten Reports versendet werden. Default-Wert = "leer".'); +INSERT INTO txt VALUES ('H2019', 'English', 'Recipient email addresses for notification emails: A comma-separated list of email addresses to which the reports generated by this schedule will be sent. Default value = "empty".'); +INSERT INTO txt VALUES ('H2020', 'German', 'Titel der Benachrichtigung: Betreffzeile der Benachrichtigungs-Email für die durch diesen Termin erzeugten Reports. Default-Wert = "leer".'); +INSERT INTO txt VALUES ('H2020', 'English', 'Subject of notification emails: Subject line of the notification email for the reports generated by this schedule. Default value = "empty".'); +INSERT INTO txt VALUES ('H2021', 'German', 'Text der Benachrichtigung: Email-Text für die Benachrichtigung. Der Email werden die durch diesen Termin erzeugten Reports angehängt. Default-Wert = "leer".'); +INSERT INTO txt VALUES ('H2021', 'English', 'Body of notification emails: Email text for the notification. The reports generated by this schedule will be attached to the email. Default value = "empty".'); -INSERT INTO txt VALUES ('H3001', 'German', 'Hier sind die archivierten Reports mit Name sowie Informationen zu Erzeugungsdatum, Typ, Vorlage (nur bei termingesteuerten Reports), +INSERT INTO txt VALUES ('H3001', 'German', 'Hier sind die archivierten Reports mit Name sowie Informationen zu Erzeugungsdatum, Typ, Vorlage (nur bei termingesteuerten Reports), Eigentümer sowie eine kurze Beschreibung des Inhalts zu finden. Sie können zum einen durch Export manuell erzeugter Reports durch Setzen des "Archiv"-Kennzeichens in Export Report erzeugt werden. - Zum anderen finden sich hier auch die durch das Scheduling erzeugten Reports. - Die archivierten Reports können von hier heruntergeladen oder gelöscht werden. + Zum anderen finden sich hier auch die durch das Scheduling und beim Rezertifizieren erzeugten Reports. + Die archivierten Reports können von hier heruntergeladen oder (bis auf die Rezertifizierungen) gelöscht werden. + In der linken Spalte kann die Anzeige der aufgelisteten Reports auf einzelne Reporttypen eingeschränkt werden. '); INSERT INTO txt VALUES ('H3001', 'English', 'Here the archived reports can be found with name and information about creation date, type, template (only at scheduled reports), - owner and a short description about the content. + owner and a short description about the content. They may be created on the one hand by exporting manually created reports with setting the flag "Archive" in Export Report. - On the other hand here also the reports created by the Scheduling can be found. - It is possible to download or delete these archived reports. + On the other hand here also the reports created by the Scheduling or in the recertification process can be found. + It is possible to download or delete (except recertifications) these archived reports. + In the left sidebar the report display can be restricted to the particular report types. '); INSERT INTO txt VALUES ('H4011', 'German', 'Im ersten Schritt muss ein Report mit den demnächst zu rezertifizierenden Regeln geladen werden. Der Zeitraum für die Vorausschau kann im Feld "Fällig in" gewählt werden. - Diese wird im "Rezertifizierungsanzeigeintervall" in den persönlichen bzw. + Diese wird im "Rezertifizierungsanzeigeintervall" in den persönlichen bzw. in den allgemeinen Rezertifizierungseinstellungen initialisiert. Desweiteren müssen die zu betrachtenden Geräte in der linken Randleiste ausgewählt werden. '); -INSERT INTO txt VALUES ('H4011', 'English', 'In the first step a report of upcoming rules to be certified has to be loaded. - The lookahead period for this can be chosen in the "Due within" field. - It is initialized by the settings value "Recertification Display Period" in the +INSERT INTO txt VALUES ('H4011', 'English', 'In the first step a report of upcoming rules to be certified has to be loaded. + The lookahead period for this can be chosen in the "Due within" field. + It is initialized by the settings value "Recertification Display Period" in the personal resp. general Recertification Settings. Also the regarded devices have to be chosen in the left sidebar. '); INSERT INTO txt VALUES ('H4012', 'German', 'Der Report zeigt nun alle Regeln, die im gewählten Zeitraum zertifiziert werden müssen. Das Rezertifizierungsdatum wird errechnet aus dem letzten Rezertifizierungsdatum (falls unbekannt, wird das Erzeugungsdatum der Regel genommen) und dem Rezertifizierungsintervall, welches in den Rezertifizierungseinstellungen definiert wurde. - Rezertifizierungen, die in den nächsten Tagen (definiert im Rezertifizierungserinnerungsintervall in den Standardeinstellungen) fällig sind, + Rezertifizierungen, die in den nächsten Tagen (definiert im Rezertifizierungserinnerungsintervall in den Standardeinstellungen) fällig sind, werden in gelb, überfällige Rezertifizierungen in rot unterlegt. Zusätzlich wird der letzte Rezertifizierer dargestellt ("unbekannt" zeigt an, dass noch keine Rezertifizierung stattgefunden hat). '); @@ -2640,9 +4665,9 @@ INSERT INTO txt VALUES ('H4013', 'German', 'Der Rezertifizierer hat nun die M&o Danach werden nur noch die verbleibenden anstehenden Rezertifizierungen angezeigt. '); INSERT INTO txt VALUES ('H4013', 'English', 'The recertifier has now the possibility to mark each of the displayed rules for recertification or decertification. - After clicking the "Execute Selected Actions" button a comment is requested. + After clicking the "Execute Selected Actions" button a comment is requested. This has to be filled, if the setting "Comment Required" in Recertification Settings is activated. - When confirmed all selected re- and decertifications are executed in on step. + When confirmed all selected re- and decertifications are executed in on step. After that only the remaining open certifications are displayed. '); INSERT INTO txt VALUES ('H4014', 'German', 'Dezertifizierte Regel können im Abschnitt Reporting mit dem Filterparameter "remove=true" dargestellt werden.'); @@ -2651,44 +4676,41 @@ INSERT INTO txt VALUES ('H4021', 'German', 'Dieses Rezertifizierungsszenario is INSERT INTO txt VALUES ('H4021', 'English', 'This recertification scenario is intended to be a base for further customized workflows.'); INSERT INTO txt VALUES ('H4031', 'German', 'In diesem Modul können Nutzer Firewall-Regeln re- oder dezertifizieren. -Dafür wird die Rolle "recertifier" benötigt. Auditor- und Admin-Nutzer können hier nur lesend auf die anstehenden Rezertifizierungen zugreifen. -
    -Aktuell gibt es zwei verschiedene Optionen: -
      -
    1. In der einfachen Variante kann ein Nutzer mit recertifier Rolle jede beliebige Regel rezertifizieren. - Diese Option eignet sich üblicherweise nur für kleine Installationen mit wenigen Firewall-Regeln. -
    2. -
    3. In größeren Umgebungen ist es sinnvoll, die Rezertifizierung dezentral zu organisieren. - Dafür wird eine Eigentümerstruktur unterstützt, die einer Liste von Eigentümern die Verantwortlichkeit für jeweils einen Teil des Netzwerks in Form von IP-Adressen bzw. IP-Subnetzen zuweist. - Dies kann z.B. eine Aufteilung auf Applikationsbasis sein, es ist aber genauso auch eine Unterteilung nach Subnetzen auf Basis von Betriebseinheiten denkbar. - Je nach Quelle und Ziel sind alle Eigentümer, die für einen Teil der Regel in Form von IP-Adressen verantwortlich sind, auch für die Rezertifizierung der Regel verantwortlich. - Es ist also im Allgemeinen eine Gruppe von Eigentümern für die Rezertifizierung einer Regel verantwortlich. -
    4. -
    -Eine Regel gilt erst dann als vollständig rezertifiziert, wenn alle Eigentümer die Regel rezertifiziert haben. -
    -Im Reporting-Modul steht außerdem ein Rezertifizierungs-Report zur Verfügung. + Dafür wird die Rolle "recertifier" benötigt. Auditor- und Admin-Nutzer können hier nur lesend auf die anstehenden Rezertifizierungen zugreifen.
    + Aktuell gibt es zwei verschiedene Optionen: +
      +
    1. In der einfachen Variante kann ein Nutzer mit recertifier Rolle jede beliebige Regel rezertifizieren. + Diese Option eignet sich üblicherweise nur für kleine Installationen mit wenigen Firewall-Regeln. +
    2. +
    3. In größeren Umgebungen ist es sinnvoll, die Rezertifizierung dezentral zu organisieren. + Dafür wird eine Eigentümerstruktur unterstützt, die einer Liste von Eigentümern die Verantwortlichkeit für jeweils einen Teil des Netzwerks in Form von IP-Adressen bzw. IP-Subnetzen zuweist. + Dies kann z.B. eine Aufteilung auf Applikationsbasis sein, es ist aber genauso auch eine Unterteilung nach Subnetzen auf Basis von Betriebseinheiten denkbar. + Je nach Quelle und Ziel sind alle Eigentümer, die für einen Teil der Regel in Form von IP-Adressen verantwortlich sind, auch für die Rezertifizierung der Regel verantwortlich. + Es ist also im Allgemeinen eine Gruppe von Eigentümern für die Rezertifizierung einer Regel verantwortlich. +
    4. +
    + Eine Regel gilt erst dann als vollständig rezertifiziert, wenn alle Eigentümer die Regel rezertifiziert haben.
    + Im Reporting-Modul steht außerdem ein Zert-Regel-Details-Report zur Verfügung. + Desweiteren kann in den Einstellungen konfiguriert werden, dass bei Dezertifizierung durch alle Eigentümer automatisch ein Löschauftrag erzeugt wird. '); INSERT INTO txt VALUES ('H4031', 'English', ' -In this module, users can recertify or decertify firewall rules. - -The "recertifier" role is required for this. Auditor and admin users have read-only access to the pending recertifications here. -
    -Currently there are two different options: -
      -
    1. In the simple variant, a user with recertifier role can recertify any rule. - This option is usually suitable only for small installations with few firewall rules. -
    2. -
    3. In larger environments, it makes sense to organize recertification in a decentralized manner. - For this purpose, an ownership structure is supported that assigns responsibility for a part of the network in the form of IP addresses or IP subnets to a list of owners. - This can, for example, be a division on an application basis, but a subdivision by subnets based on operating units is just as conceivable. - Depending on the source and destination, all owners who are responsible for a part of the rule in the form of IP addresses are also responsible for recertifying the rule. - Thus, in general, a group of owners is responsible for the recertification of a rule. -
    4. -
    -A rule is not considered fully recertified until all owners have recertified the rule. -
    -A recertification report is also available in the reporting module. + In this module, users can recertify or decertify firewall rules. + The "recertifier" role is required for this. Auditor and admin users have read-only access to the pending recertifications here.
    + Currently there are two different options: +
      +
    1. In the simple variant, a user with recertifier role can recertify any rule. + This option is usually suitable only for small installations with few firewall rules. +
    2. +
    3. In larger environments, it makes sense to organize recertification in a decentralized manner. + For this purpose, an ownership structure is supported that assigns responsibility for a part of the network in the form of IP addresses or IP subnets to a list of owners. + This can, for example, be a division on an application basis, but a subdivision by subnets based on operating units is just as conceivable. + Depending on the source and destination, all owners who are responsible for a part of the rule in the form of IP addresses are also responsible for recertifying the rule. + Thus, in general, a group of owners is responsible for the recertification of a rule. +
    4. +
    + A rule is not considered fully recertified until all owners have recertified the rule.
    + A Cert Rule Details report is also available in the reporting module. + Furtheron it can be configured in the settings that after decertification by all owners a delete request is created automatically. '); INSERT INTO txt VALUES ('H4032', 'German', ' @@ -2697,24 +4719,24 @@ Für das ordnungsgemäße Funktionieren des Rezertifzierungsprozess

    Berechtigungen

    • Angemeldete Nutzer müssen die Rolle "Recertifier" besitzen
    • -
    • Angemeldete Nutzer müssen Mitglied eines Eigentümers sein (entweder direkt unter "Vollständiger Name*:" oder als Mitglieder einer Eigentümergruppe)
    • +
    • Angemeldete Nutzer müssen Mitglied eines Eigentümers sein (entweder direkt unter "Hauptverantwortlicher (DN)" oder als Mitglieder einer Eigentümergruppe)

    Konfiguration der Eigentümer

    Möchte man keine Verteilung der Zuständigkeit auf mehrere Eigentümer vornehmen, so ist es ausreichend, dem Eigentümer "Super-Owner" eine Gruppe von Rezertifizierern zuzuordnen, die für die Rezertifizierung aller Firewall-Regeln verantwortlich sind. - Um den Super-Owner editieren zu können, + Um den Super-Owner editieren zu können, ist im Menü "Einstellungen" - "Weitere Einstellungen" - "Standardeinstellungen" die Option "Manuelle Eigentümerverwaltung erlauben" zu aktivieren.

    - Soll hingegen eine dezentrale Struktur aufgebaut werden, so können die Eigentümer entweder im Firewall Orchestrator selbst definiert werden (nicht empfohlen) + Soll hingegen eine dezentrale Struktur aufgebaut werden, so können die Eigentümer entweder im Firewall Orchestrator selbst definiert werden (nicht empfohlen) oder aber man importiert eine im Unternehmen vorhandene Eigentümerliste, wodurch der Pflegeaufwand zum Aktuell-Halten dieser Zuordnung nicht dem Betreiber der Firewall-Infrastruktur zufällt.
    Es wird hierbei empfohlen, im Menü "Einstellungen" - "Weitere Einstellungen" - "Standardeinstellungen" die Option "Manuelle Eigentümerverwaltung erlauben" zu deaktivieren, um sicherzustellen, dass keine lokalen Änderungen vorgenommen werden, sondern die Eigentümer-Pflege ausschließlich im externen Tool stattfindet.
    - Für die Verwaltung in einem externen System ist der Import der Eigentümer und deren IP-Adressen via + Für die Verwaltung in einem externen System ist der Import der Eigentümer und deren IP-Adressen via Firewall Orchestrator API vorzunehmen.

    - Die Definition der Eigentümer im Firewall Orchestrator selbst ist recht simpel. + Die Definition der Eigentümer im Firewall Orchestrator selbst ist recht simpel. Hierzu muss lediglich im Menü "Einstellungen" - "Weitere Einstellungen" - "Standardeinstellungen" die Option "Manuelle Eigentümerverwaltung erlauben" aktiviert werden.
    Anschließend ist es im Menü "Einstellungen" - "Eigentümer" möglich, Eigentümer manuell hinzuzufügen, zu bearbeiten oder zu löschen. @@ -2731,10 +4753,10 @@ For the proper functioning of the recertification process, the following configu

    Owner configuration

    If one does not want to distribute responsibility among several owners, it is sufficient to assign a group of recertifiers to the "Super-Owner" owner, who are responsible for the recertification of all firewall rules. - To be able to edit the super-owner + To be able to edit the super-owner the "Allow manual owner management" option must be enabled in the "Settings" - "Additional settings" - "Default settings" menu.

    - If, on the other hand, a decentralized structure is to be set up, the owners can either be defined in the Firewall Orchestrator itself (not recommended) + If, on the other hand, a decentralized structure is to be set up, the owners can either be defined in the Firewall Orchestrator itself (not recommended) or you can import an existing list of owners in the company, which means that the maintenance effort for keeping this assignment up to date does not fall to the operator of the firewall infrastructure.
    In this case, it is recommended to deactivate the "Allow manual owner administration" option in the "Settings" - "Additional settings" - "Default settings" menu, @@ -2743,7 +4765,7 @@ For the proper functioning of the recertification process, the following configu For management in an external system, importing owners and their IP addresses should be done via the Firewall Orchestrator API.

    - Defining the owners in Firewall Orchestrator itself is quite simple. + Defining the owners in Firewall Orchestrator itself is quite simple. All that is required is to activate the "Allow manual owner administration" option in the "Settings" - "Additional settings" - "Default settings" menu.
    After that, in the "Settings" - "Owners" menu it is possible to add, edit or delete owners manually. @@ -2759,23 +4781,23 @@ Login erfolgt mit user1_demo (Passwort cactus1) oder user2_demo (Passwort cactus

    1. - Im ersten Schritt kann in der linken Randleiste eine Filterung vorgenommen werden (Fälligkeit der Rezertifizierung, Eigentümer, Firewall-Geräte) + Im ersten Schritt kann in der linken Randleiste eine Filterung vorgenommen werden (Fälligkeit der Rezertifizierung, Eigentümer, Firewall-Geräte) und anschließend mit der Schaltfläche "Regeln anzeigen" eine Liste der zu rezertifizierenden Regeln generiert werden.
    2. -
    3. - Der Zeitraum für die Vorausschau kann im Feld "Fällig in" gewählt werden. - Der Default-Wert kann über Verändern des "Rezertifizierungsanzeigeintervalls" in den persönlichen bzw. in den allgemeinen Rezertifizierungseinstellungen gesetzt werden. +
    4. + Der Zeitraum für die Vorausschau kann im Feld "Fällig in" gewählt werden. + Der Default-Wert kann über Verändern des "Rezertifizierungsanzeigeintervalls" in den persönlichen bzw. in den allgemeinen Rezertifizierungseinstellungen gesetzt werden.
    5. Bei Rezertifizierungen, die überfällig sind, wird das Datum in rot angezeigt.
      Der Rezertifizierer hat nun die Möglichkeit, beliebige zu re- oder dezertifizierenden Regeln zu markieren.
      - Durch klicken der "Ausgewählte Aktionen ausführen"-Schaltfläche wird zunächst ein (optionaler - konfigurierbar) Kommentar abgefragt, und + Durch klicken der "Ausgewählte Aktionen ausführen"-Schaltfläche wird zunächst ein (optionaler - konfigurierbar) Kommentar abgefragt, und nach Bestätigung werden alle markierten Re- und Dezertifizierungen in einem Schritt ausgeführt.
      Anschließend werden nur noch die verbliebenen anstehenden Rezertifizierungen angezeigt.
    6. - Sollte die Option zum Re- bzw. Dezertifizierung nicht angezeigt werden, - sollten die Berechtigungen überprüft werden bzw. wenn der Nutzer Mitglied mehrerer Eigentümergruppen ist, + Sollte die Option zum Re- bzw. Dezertifizierung nicht angezeigt werden, + sollten die Berechtigungen überprüft werden bzw. wenn der Nutzer Mitglied mehrerer Eigentümergruppen ist, muss zunächst einer der Eigentümer ausgewählt werden, um speziell für diesen rezertifizieren zu können.
      In diesem Fall empfiehlt es sich für einen Eigentümer nach dem anderen zu rezertifizieren.
    7. @@ -2790,22 +4812,22 @@ Login with user1_demo (password cactus1) or user2_demo (password cactus2)

      1. - In the first step, a filtering can be made in the left sidebar (recertification due date, owner, firewall devices). + In the first step, a filtering can be made in the left sidebar (recertification due date, owner, firewall devices). and then a list of rules to be recertified can be generated using the "Show rules" button.
      2. -
      3. - The period for the preview can be selected in the "Due within" field. - The default value can be set by changing the "Recertification display interval" in the personal or in the general recertification settings. +
      4. + The period for the preview can be selected in the "Due within" field. + The default value can be set by changing the "Recertification display interval" in the personal or in the general recertification settings.
      5. For recertifications that are overdue, the date is displayed in red.
        The recertifier now has the option to mark any rules to be re- or decertified.
        - By clicking the "Execute selected actions" button, a (optional - configurable) comment will be requested first, and + By clicking the "Execute selected actions" button, a (optional - configurable) comment will be requested first, and after confirmation all marked recertifications and decertifications are executed in one step.
        Afterwards, only the remaining pending recertifications are displayed.
      6. - If the option to recertify or decertify is not displayed, the permissions should be checked or if the user is a member of several owner groups, + If the option to recertify or decertify is not displayed, the permissions should be checked or if the user is a member of several owner groups, one of the owners must be selected first in order to be able to recertify specifically for this owner.
        In this case, it is recommended for one owner at a time to recertify.
      7. @@ -2814,12 +4836,12 @@ Login with user1_demo (password cactus1) or user2_demo (password cactus2) INSERT INTO txt VALUES ('H4034', 'German', '

        IP-Adress-Matching

        - Jede Regel (Quelle und Ziel) wird mit den für einen Eigentümer definierten IP-Adressen auf Überlappung geprüft.
        - Bei einer Überlappung ist der Eigentümer für die Rezertifizierung der Regel verantwortlich und ein entsprechender Eintrag wird - abhängig vom Rezertifizierungsintervall des Eigentümers erzeugt. -

        - Alle Regeln, die Netzwerkobjekte enthalten, die keinem Eigentümer zugeordnet werden können, sind automatisch dem Super-Owner zugewiesen. -
        + Jede Regel (Quelle und Ziel) wird mit den für einen Eigentümer definierten IP-Adressen auf Überlappung geprüft.
        + Bei einer Überlappung ist der Eigentümer für die Rezertifizierung der Regel verantwortlich und ein entsprechender Eintrag wird + abhängig vom Rezertifizierungsintervall des Eigentümers erzeugt. +

        + Alle Regeln, die Netzwerkobjekte enthalten, die keinem Eigentümer zugeordnet werden können, sind automatisch dem Super-Owner zugewiesen. +
        Dieser ist somit für deren Rezertifzierung verantwortlich.

        Fälligkeitsdatum

        @@ -2828,31 +4850,31 @@ INSERT INTO txt VALUES ('H4034', 'German', '

        Konfiguration

        Siehe auch Rezertifizierungseinstellungen. -

        - Es ist möglich, die einmal nächtliche laufende Neuberechnung der anstehenden Rezertifizierungen manuell anzustoßen. +

        + Es ist möglich, die einmal nächtliche laufende Neuberechnung der anstehenden Rezertifizierungen manuell anzustoßen.
        - Hierzu dient die Schaltfläche Einstellungen - Weitere Einstellungen - Rezertifizierung - "Neuberechnung offene Rezertifizierungen". + Hierzu dient die Schaltfläche Einstellungen - Weitere Einstellungen - Rezertifizierung - "Neuberechnung offene Rezertifizierungen". '); INSERT INTO txt VALUES ('H4034', 'English', '

        IP Adress Matching

        - Each rule (source and destination) is checked for overlap with the IP addresses defined for an owner.
        - In case of an overlap, the owner is responsible for the recertification of the rule and a corresponding entry will be - generated depending on the recertification interval of the owner. -

        + Each rule (source and destination) is checked for overlap with the IP addresses defined for an owner.
        + In case of an overlap, the owner is responsible for the recertification of the rule and a corresponding entry will be + generated depending on the recertification interval of the owner. +

        All rules that contain network objects that cannot be assigned to an owner are automatically assigned to the super-owner. -
        +
        The latter is thus responsible for their recertification.

        Due Date

        The recertification date is calculated from the last recertification date (if unknown, the creation date of the rule is taken) - and the recertification interval defined for the respective owner. + and the recertification interval defined for the respective owner.

        Also see Recertification Settings. -

        - It is possible to manually trigger the once-a-night running recalculation of pending recertifications. +

        + It is possible to manually trigger the once-a-night running recalculation of pending recertifications.
        - The button Settings - Further settings - Recertification - "Recalculation of open recertifications" is used for this purpose. + The button Settings - Further settings - Recertification - "Recalculation of open recertifications" is used for this purpose. '); INSERT INTO txt VALUES ('H4035', 'German', ' @@ -2878,26 +4900,23 @@ Variablen { "name": "5", "recert_interval": 365, - "dn":"x", - "group_dn":"x", + "owner_responsibles":[{"dn":"x","responsible_type":1},{"dn":"x","responsible_type":2}], "app_id_external": "app-5", - "owner_networks": {"data": [{"ip": "10.5.0.0/16"},{"ip": "10.9.0.0/16"}]} + "owner_networks": {"data": [{"ip": "10.5.0.0/32", "ip_end": "10.5.255.255/32"},{"ip": "10.9.0.0/32", "ip": "10.9.255.255/32"}]} }, { "name": "6", "recert_interval": 30, - "dn":"x", - "group_dn":"x", + "owner_responsibles":[{"dn":"x","responsible_type":1},{"dn":"x","responsible_type":2}], "app_id_external": "app-6", - "owner_networks": {"data": [{"ip": "10.6.0.0/16"}]} + "owner_networks": {"data": [{"ip": "10.6.0.0/32", "ip_end": "10.6.255.255/32"}]} }, { "name": "7", "recert_interval": 90, - "dn":"x", - "group_dn":"x", + "owner_responsibles":[{"dn":"x","responsible_type":1},{"dn":"x","responsible_type":2}], "app_id_external": "app-7", - "owner_networks": {"data": [{"ip": "10.7.0.0/16"}]} + "owner_networks": {"data": [{"ip": "10.7.0.0/32", /"ip_end": "10.7.255.21655/32"}]} } ] } @@ -2913,11 +4932,12 @@ mutation addSingleOwner { { name: "sechs" recert_interval: 222 - dn: "a" - group_dn: "b" + owner_responsibles: { + data: [{ dn: "a", responsible_type: 1 }, { dn: "b", responsible_type: 2 }] + } app_id_external: "app-sechs" owner_networks: { - data: [{ ip: "10.69.0.0/16" }, { ip: "10.9.0.0/16" }] + data: [{ ip: "10.69.0.0/32", ip_end: "10.69.255.255/32" }, { ip: "10.9.0.0/32", ip_end: "10.9.255.255/32" }] on_conflict: { constraint: owner_network_ip_unique update_columns: [ip] @@ -2927,7 +4947,7 @@ mutation addSingleOwner { ] on_conflict: { constraint: owner_name_unique - update_columns: [recert_interval, dn, group_dn] + update_columns: [recert_interval] } ) { returning { @@ -2960,26 +4980,23 @@ Variables { "name": "5", "recert_interval": 365, - "dn":"x", - "group_dn":"x", + "owner_responsibles":[{"dn":"x","responsible_type":1},{"dn":"x","responsible_type":2}], "app_id_external": "app-5", - "owner_networks": {"data": [{"ip": "10.5.0.0/16"},{"ip": "10.9.0.0/16"}]} + "owner_networks": {"data": [{"ip": "10.5.0.0/32", "ip_end": "10.5.255.255/32"},{"ip": "10.9.0.0/32", "ip": "10.9.255.255/32"}]} }, { "name": "6", "recert_interval": 30, - "dn":"x", - "group_dn":"x", + "owner_responsibles":[{"dn":"x","responsible_type":1},{"dn":"x","responsible_type":2}], "app_id_external": "app-6", - "owner_networks": {"data": [{"ip": "10.6.0.0/16"}]} + "owner_networks": {"data": [{"ip": "10.6.0.0/32", "ip_end": "10.6.255.255/32"}]} }, { "name": "7", "recert_interval": 90, - "dn":"x", - "group_dn":"x", + "owner_responsibles":[{"dn":"x","responsible_type":1},{"dn":"x","responsible_type":2}], "app_id_external": "app-7", - "owner_networks": {"data": [{"ip": "10.7.0.0/16"}]} + "owner_networks": {"data": [{"ip": "10.7.0.0/32", /"ip_end": "10.7.255.21655/32"}]} } ] } @@ -2995,11 +5012,12 @@ mutation addSingleOwner { { name: "sechs" recert_interval: 222 - dn: "a" - group_dn: "b" + owner_responsibles: { + data: [{ dn: "a", responsible_type: 1 }, { dn: "b", responsible_type: 2 }] + } app_id_external: "app-sechs" owner_networks: { - data: [{ ip: "10.69.0.0/16" }, { ip: "10.9.0.0/16" }] + data: [{ ip: "10.69.0.0/32", ip_end: "10.69.255.255/32" }, { ip: "10.9.0.0/32", ip_end: "10.9.255.255/32" }] on_conflict: { constraint: owner_network_ip_unique update_columns: [ip] @@ -3009,7 +5027,7 @@ mutation addSingleOwner { ] on_conflict: { constraint: owner_name_unique - update_columns: [recert_interval, dn, group_dn] + update_columns: [recert_interval] } ) { returning { @@ -3020,6 +5038,29 @@ mutation addSingleOwner { '); +INSERT INTO txt VALUES ('H4101', 'German', 'Kanal: Legt fest, auf welchem Weg die Nachrichten geschickt werden (z.Zt. nur Email).'); +INSERT INTO txt VALUES ('H4101', 'English', 'Channel: Defines on which way the notificastions are delivered (currently onl email).'); +INSERT INTO txt VALUES ('H4102', 'German', 'Layout: Legt fest in welchem Format die Nachrichten erzeugt werden sollen (z.B. als PDF-Attachment).'); +INSERT INTO txt VALUES ('H4102', 'English', 'Layout: Defines in which format the notifications are created (e.g. as PDF attachment).'); +INSERT INTO txt VALUES ('H4103', 'German', 'Deadline: Referenzdatum, relativ zu dem Nachrichten verschickt werden sollen.'); +INSERT INTO txt VALUES ('H4103', 'English', 'Deadline: Reference date for the submission of notifications.'); +INSERT INTO txt VALUES ('H4104', 'German', 'Benachrichtigungen vor Termin: Definiert das Zeitintervall vor dem Referenzdatum, in dem eine Benachrichtigung stattfinden soll.'); +INSERT INTO txt VALUES ('H4104', 'English', 'Notifications before Deadline: Defines the time interval relative to the reference date, where one notification is to be sent.'); +INSERT INTO txt VALUES ('H4105', 'German', 'Benachrichtigungen nach Termin: Definiert ein Zeitintervall für wiederkehrende Benachrichtigungen nach Ablauf des Referenzdatums mit einer maximalen Anzahl von Wiederholungen. + Der initiale Offset wird nur zum ersten Zeitintervall hinzuaddiert (auch negative Zahlen möglich). +'); +INSERT INTO txt VALUES ('H4105', 'English', 'Notifications after Deadline: Defines a time interval for recurring notifications after reaching the reference date with a maximum number of repetitions. + The initial offset is added only to the first interval (also negative numbers possible). +'); +INSERT INTO txt VALUES ('H4106', 'German', 'Email-Betreff: Betreff der Benachrichtigung. Verfügbare Platzhalter: @@APPNAME@@, @@APPID@@.'); +INSERT INTO txt VALUES ('H4106', 'English', 'Email subject: Subject line of the notification. Available placeholders: @@APPNAME@@, @@APPID@@.'); +INSERT INTO txt VALUES ('H4107', 'German', 'Empfänger (To): Es werden verschiedene Rollen (je nach Kontext) als Empfänger angeboten, zu denen dann automatisch die entsprechenden Adressen ermittelt werden. Bei "Andere Adressen" können manuell Adressen eingegeben werden.'); +INSERT INTO txt VALUES ('H4107', 'English', 'Recipient (To): Different roles are offered as recipients (depending on context), for which the addresses are determined automatically. With "Other Addresses" addreesses can be inserted manually.'); +INSERT INTO txt VALUES ('H4108', 'German', 'Empfänger (Cc). Wie "Empfänger (To)" für Empfänger im CC.'); +INSERT INTO txt VALUES ('H4108', 'English', 'Recipient (Cc). As "Recipient (To)" for recipient in CC.'); +INSERT INTO txt VALUES ('H4109', 'German', 'Name: Name der Benachrichtigung, nur für Darstellungszwecke.'); +INSERT INTO txt VALUES ('H4109', 'English', 'Name: Name of notification, only for display purposes.'); + INSERT INTO txt VALUES ('H5001', 'German', 'In diesem Abschnitt werden die Setup- und Verwaltungseinstellungen behandelt. Die meisten Einstellungen können nur von Nutzern mit der Administrator-Rolle gesehen und geändert werden. Der Auditor kann zwar die Einstellungen sehen, da er aber keine Schreibrechte hat, sind alle Schaltflächen, die zu Änderungen führen würden, deaktiviert. @@ -3028,11 +5069,13 @@ INSERT INTO txt VALUES ('H5001', 'English', 'In the settings section the setup a Most settings can only be seen and done by users with administrator role. The auditor is able to see the settings, but as he has no write permissions all buttons leading to changes are disabled. '); -INSERT INTO txt VALUES ('H5011', 'German', 'Im ersten Kapitel "Geräte" wird das Setup der Datenquellen behandelt: +INSERT INTO txt VALUES ('H5011', 'German', 'Im ersten Kapitel "Geräte" wird das Setup der Datenquellen behandelt: Die Abschnitte Managements und Gateways dienen der Definition der verbundenen Hardware. + Hinzu kommt die Verwaltung der Import-Zugangsdaten. '); INSERT INTO txt VALUES ('H5011', 'English', 'In the first chapter "Devices" the setup of the report data sources is done: The sections Managements and Gateways are for the definition of the connected hardware. + Additionally there is the administration of the Import Credentials. '); INSERT INTO txt VALUES ('H5012', 'German', 'Das Kapitel "Berechtigungen" bietet die Funktionalität für die Nutzerverwaltung: In LDAP-Verbindungen können externe Verbindungen zusätzlich zum internen LDAP definiert werden. @@ -3048,25 +5091,29 @@ INSERT INTO txt VALUES ('H5012', 'English', 'The chapter "Authorization" offers '); INSERT INTO txt VALUES ('H5013', 'German', 'Im Kapitel "Voreinstellungen" kann der Administrator Standardeinstellungen vornehmen, die für alle Nutzer gelten, sowie die Email-, Importer- und - Passworteinstellungen definieren. + Passworteinstellungen definieren. Hinzu kommen die modulspezifischen + Allgemeinen Rezertifizierungs- und Modellierungseinstellungen. '); INSERT INTO txt VALUES ('H5013', 'English', 'In the "Defaults" chapter the administrator can define Default Values applicable to all users - and define email-, importer- and Password Policy settings. + and define email-, importer- and Password Policy settings. + Additionally there are the module specific General Recertification and Modelling Settings. '); INSERT INTO txt VALUES ('H5014', 'German', 'Das Kapitel "Persönlich" ist für alle Nutzer zugänglich. Hier können das individuelle Password, die bevorzugte Sprache und Reporting-Einstellungen gesetzt werden. Nutzer mit Rezertifizierer-Rolle können auch ihre Rezertifizierungseinstellungen anpassen. + Das gleiche gilt für Modellierer in den Modellierungseinstellungen. '); INSERT INTO txt VALUES ('H5014', 'English', 'The "Personal" chapter is accessible by all users, where they can set their individual Password, - Language and Reporting preferences. + Language and Reporting preferences. Users with recertifier role have also the possibility to adjust their Recertification Setting. + Same for modellers in the Modelling Settings. '); INSERT INTO txt VALUES ('H5015', 'German', 'Das Kapitel "Workflow" dient dem Administrator, einen Workflow aufzusetzen. Dazu gehört die Definition der angebotenen Aktionen, - der verwendeten Stati und den Statusübergängen in den zentralen Status-Matrizen. + der verwendeten Status und den Statusübergängen in den zentralen Status-Matrizen. In den Einstellungen können allgemeine Voreinstellungen zu den Workflows vorgenommen werden. '); INSERT INTO txt VALUES ('H5015', 'English', 'The "Workflow" chapter helps the administrator to set up a workflow. This includes the definition of the offered actions, - the used states, and the state transitions in the central state matrices. + the used states, and the state transitions in the central state matrices. In customizing general workflow settings can be done. '); @@ -3089,7 +5136,7 @@ INSERT INTO txt VALUES ('H5102', 'German', 'Folgende Firewallprodukte könn
      8. JUNOS 10 - 17 - Firewallgateway
      9. Netscreen 5.x/6.x - Firewallgateway
      10. - +
      11. API Zugriff via https
        • Check Point R8x - SmartCenter
        • @@ -3100,7 +5147,7 @@ INSERT INTO txt VALUES ('H5102', 'German', 'Folgende Firewallprodukte könn
        • Azure Firewall
        • Cisco FirePower Management Center
        -
      12. + '); INSERT INTO txt VALUES ('H5102', 'English', 'The following firewall products can be integrated:
          @@ -3114,51 +5161,54 @@ INSERT INTO txt VALUES ('H5102', 'English', 'The following firewall products can
        • JUNOS 10 - 17 - firewall gateway
        • Netscreen 5.x/6.x - firewall gateway
        - +
      13. API access via https
        • Check Point R8x - SmartCenter
        • Check Point R8x - MDS (Multi Domain Server)
        • -
        • FortiGate StandAlone (via REST API)
        • +
        • FortiGate StandAlone (via REST API)
        • FortiManager 5ff - FortiManager - for this management type the complete infrastructure (ADOM, FortiGateway devices) can be auto discovered.
        • Palo Alto Firewalls (not Panorama)
        • Azure Firewall
        • Cisco FirePower Management Center
        -
      14. + '); INSERT INTO txt VALUES ('H5103', 'German', 'Für Firewallgateways ohne separates Management oder im Falle, dass das zentrale Management nicht in den Firewall Orchestrator eingebunden werden kann, werden die Details des Gateways als Management und gleichzeitig auch als Gateway eingetragen.
        Im Falle Fortigate Legacy (via ssh): Um einen vollständigen Datenimport zu gewährleisten, bitte in der Fortigate config den Seitenumbruch deaktivieren, damit beim Kommando "show full-configuration" die komplette Config ausgegeben wird. '); -INSERT INTO txt VALUES ('H5103', 'English', 'For firewall gateways without a separate management or in case the central management cannot be integrated into Firewall Orchestrator +INSERT INTO txt VALUES ('H5103', 'English', 'For firewall gateways without a separate management or in case the central management cannot be integrated into Firewall Orchestrator you may enter the details of the gateway here as a management system as well and then add it again as a gateway.
        In the case of legacy Fortigate (via ssh): To get the entire data imported, disable pagination in the Fortigate config to allow get command "show full-configuration" to retrieve the complete config. '); INSERT INTO txt VALUES ('H5104', 'German', 'Wenn Beispieldaten (definiert durch die Endung "_demo" vom Namen) existieren, wird eine Schaltfläche angezeigt, um diese und alle verknüpften Gateways zu löschen.'); INSERT INTO txt VALUES ('H5104', 'English', 'If there are sample data (defined by the ending "_demo" of the name), a button is displayed to delete them and all related gateways.'); +INSERT INTO txt VALUES ('H5110', 'German', 'Uid: Eindeutige ID des Managements.'); +INSERT INTO txt VALUES ('H5110', 'English', 'Uid: Unique id of the mangement.'); INSERT INTO txt VALUES ('H5111', 'German', 'Name*: Name des Managements.
        Für die meisten Firewalls ist dies ein willkürlicher Name. Ausnahmen sind direkt verbundene Gateways von Fortigate, Netscreen und Juniper. Hier muss der Name des Firewallgateways eingetragen werden.
        - Da es zu Problemen mit dem perl-Importer kommen kann, sollten Leerzeichen im Namen von Legacy-Systemen nicht verwendet werden. Ein Management dessen Name mit "_demo" endet, wird beim Betätigen der "Beispieldaten löschen"-Schaltfläche gelöscht. '); INSERT INTO txt VALUES ('H5111', 'English', 'Name*: Name of the mangement.
        For most firewalls this is an arbitrary name. Exceptions are Fortigate, Netscreen and Juniper directly connected gateways. Here the name give needs to be the name of the firewall gateway.
        - Do not use spaces in the management name of legacy systems as perl importer cannot cope with spaces here. A management whose name ends with "_demo" will be deleted when using the "Remove Sample Data" button. '); INSERT INTO txt VALUES ('H5112', 'German', 'Kommentar: Optionale Beschreibung des Managements.'); INSERT INTO txt VALUES ('H5112', 'English', 'Comment: Optional description of this management.'); INSERT INTO txt VALUES ('H5113', 'German', 'Gerätetyp*: bitte das korrekte Produkt von der Liste auswählen (siehe oben)'); INSERT INTO txt VALUES ('H5113', 'English', 'Device Type*: Select correct product from a list of available types, see above.'); -INSERT INTO txt VALUES ('H5114', 'German', 'Hostname*: Adresse des Hosts (entweder IP-Addresse oder auflösbarer Name). +INSERT INTO txt VALUES ('H5114', 'German', 'Hostname*: Adresse des Hosts (entweder IP-Addresse oder auflösbarer Name).
        + Wenn die native Konfiguration eines Firewall-Systems als JSON-Datei zu Testzwecken eingelesen werden soll, ist hier die URI in einem der folgenden Formate anzugeben:
        + https://..., http://..., file://...
        Für Check Point R8x MDS Installationen die Addresse des MDS-Servers für alle Domains benutzen.
        Für alle Firewall-Plattformen, die kein separates Management-System besitzen, muss die IP oder der auflösbare Name des Firewallgateways spezifiziert werden. '); -INSERT INTO txt VALUES ('H5114', 'English', 'Hostname*: Address of the host (either IP address or resolvable name). +INSERT INTO txt VALUES ('H5114', 'English', 'Hostname*: Address of the host (either IP address or resolvable name).
        + For reading the native firewall config from a JSON file (for testing purposes), enter the URI of the file (https://..., http://..., file://...)
        For Check Point R8x MDS installations use the address of the MDS server for all domains.
        For all firewall platforms which do not possess a separate management, use the IP address or the resolvable name of the firewall gateway. '); @@ -3185,7 +5235,7 @@ INSERT INTO txt VALUES ('H5119', 'English', 'Domain: Firewall Domain Name
        INSERT INTO txt VALUES ('H5120', 'German', 'Importer Hostname: Der Name des Servers, auf dem der Importprozess laufen soll. Muss individuell konfiguriert werden, wenn mehrere verteilte Importmodule laufen sollen, so dass nicht jeder Importer alle Managements importiert. '); -INSERT INTO txt VALUES ('H5120', 'English', 'Importer Hostname: This must be the name of the server, the import process should run on. +INSERT INTO txt VALUES ('H5120', 'English', 'Importer Hostname: This must be the name of the server, the import process should run on. Needs to be individually configured if you want to have multiple distributed import modules, so that not every importer imports all managements. '); INSERT INTO txt VALUES ('H5121', 'German', 'Debug Stufe (0-9): Erlaubt individuelle Debug-Granularität pro Management.'); @@ -3194,12 +5244,14 @@ INSERT INTO txt VALUES ('H5122', 'German', 'Import Deaktiviert: Schalter um den INSERT INTO txt VALUES ('H5122', 'English', 'Import Disabled: Flag if the data import needs to be disabled.'); INSERT INTO txt VALUES ('H5123', 'German', 'Nicht sichtbar: Wenn gesetzt ist dieses Management nicht mit Standard-Reporter-Rolle sichtbar.'); INSERT INTO txt VALUES ('H5123', 'English', 'Hide in UI: If set, this management is not visible to the standard reporter role.'); +INSERT INTO txt VALUES ('H5124', 'German', 'Externe Management Daten: Daten die das Management in externen Systemen kennzeichnen.'); +INSERT INTO txt VALUES ('H5124', 'English', 'External Management Data: Data specifying the management in external systems.'); INSERT INTO txt VALUES ('H5130', 'German', 'Hier werden die Zugangsdaten für den Import der Firewall-Konfigurationen verwaltet. Diese können auch für den Zugriff auf mehrere Firewall-Managements verwendet werden. Ein Löschen ist erst möglich, wenn die Zugangsdaten nirgends mehr verwendet werden.
        - Für den FortiGate Stand-Alone Import via REST API: + Für den FortiGate Stand-Alone Import via REST API:
        1. Im FortiGate Web Interface: Erstelle ein Read Only Admin Profile z.B. "ro_admin"
        2. Im FortiGate Web Interface: Erstelle einen "REST API Admin" e.g. "fworch" mit "ro_admin" Profil und kopiere den API Schlüssel
        3. @@ -3225,7 +5277,7 @@ INSERT INTO txt VALUES ('H5132', 'German', 'Import Nutzer*: Der Nutzer, der zum Er muss vorher auf dem Firewallsystem angelegt sein und vollen Lesezugriff auf das System besitzen.
          Auf Check Point R8x wird empfohlen, das vordefinierte "Read Only All"-Profil (sowohl globales als auch Domainmanagement) zu verwenden. '); -INSERT INTO txt VALUES ('H5132', 'English', 'Username*: The user used to login to the firewall management. +INSERT INTO txt VALUES ('H5132', 'English', 'Username*: The user used to login to the firewall management. This user needs to be created on the firewall system in advance and needs full read access to the system.
          On Check Point R8x we recommend using the predefined "Read Only All" profile (both global and domain management) for the user. '); @@ -3260,6 +5312,8 @@ INSERT INTO txt VALUES ('H5141', 'English', 'Admins can create and administrate The clone button helps defining new gateways by copying the data from existing ones. Before saving at least one of the parameters Device Type, Management or Rulebase has to be different from the existing gateways if the Import Disabled flag is not set. '); +INSERT INTO txt VALUES ('H5150', 'German', 'UID*: Eindeutige ID des Gateways.'); +INSERT INTO txt VALUES ('H5150', 'English', 'UID*: Unique ID of the Gateway.'); INSERT INTO txt VALUES ('H5151', 'German', 'Name*: Name des Gateways. Für Legacy Fortinet (ssh) muss dies der reale Name des Firewallgateways sein wie in der Config definiert.'); INSERT INTO txt VALUES ('H5151', 'English', 'Name*: Name of the Gateway. For legacy Fortinet (ssh) this must be the real name of the firewall gateway as defined in the config.'); INSERT INTO txt VALUES ('H5152', 'German', 'Kommentar: Optionaler Kommentar zu diesem Gateway.'); @@ -3267,7 +5321,7 @@ INSERT INTO txt VALUES ('H5152', 'English', 'Comment: Optional comment regarding INSERT INTO txt VALUES ('H5153', 'German', 'Gerätetyp*: Auswahlliste der verfügbaren Typen. Für die verfügbaren Typen siehe Managementeinstellungen. '); -INSERT INTO txt VALUES ('H5153', 'English', 'Device Type*: Out of a list of available types. For a list of available device types see +INSERT INTO txt VALUES ('H5153', 'English', 'Device Type*: Out of a list of available types. For a list of available device types see management settings. '); INSERT INTO txt VALUES ('H5154', 'German', 'Management*: Wählen Sie das Management, welches dieses Gateway kontrolliert. Wenn zu einem Beispielmanagement zugeordnet, wird es mitgelöscht, wenn die "Beispieldaten löschen"-Schaltfläche bei den Managementeinstellungen betätigt wird.'); @@ -3281,7 +5335,7 @@ INSERT INTO txt VALUES ('H5155', 'German', 'Lokale Rulebase* / Lokales Package*
        4. Im Falle von FortiGate Stand-Alone (Import via REST API) wird dieses Feld automatisch ausgefüllt.
        5. '); -INSERT INTO txt VALUES ('H5155', 'English', 'Local Rulebase* / Local Package*: Enter the name of the rulebase here. +INSERT INTO txt VALUES ('H5155', 'English', 'Local Rulebase* / Local Package*: Enter the name of the rulebase here.
          • For Check Point R8x the top level access layer name goes here (default is "Network").
          • For Check Point R8x MDS enter the name of the global policy layer followed by the name of the domain policy separated by "/", e.g. "global-policy-layer-name/domain-policy-layer-name".
          • @@ -3308,10 +5362,10 @@ INSERT INTO txt VALUES ('H5171', 'English', 'The status of the import jobs for t '); INSERT INTO txt VALUES ('H5181', 'German', 'Aktualisieren: Aktualisiert die dargestellten Daten.'); INSERT INTO txt VALUES ('H5181', 'English', 'Refresh: Updates the displayed data.'); -INSERT INTO txt VALUES ('H5182', 'German', 'Details: Für das ausgewählte Management wird hier eine genauere Übersicht über die Import-Ids, Start/Stop-Zeiten, +INSERT INTO txt VALUES ('H5182', 'German', 'Details: Für das ausgewählte Management wird hier eine genauere Übersicht über die Import-Ids, Start/Stop-Zeiten, Dauer und Fehler des ersten, letzten erfolgreichen und letzten Imports gegeben, sowie die Anzahl der Fehler seit dem letzten erfolgreichen Import. '); -INSERT INTO txt VALUES ('H5182', 'English', 'Details: For the selected management a detailed view on import ids, start/stop times, +INSERT INTO txt VALUES ('H5182', 'English', 'Details: For the selected management a detailed view on import ids, start/stop times, duration and errors of the first, last successful and last import, as well as the number of errors since the last successful import. '); INSERT INTO txt VALUES ('H5183', 'German', 'Letzter Unvollendeter: Die Startzeit eines aktuell laufenden Imports falls vorhanden. @@ -3353,10 +5407,10 @@ INSERT INTO txt VALUES ('H5212', 'German', 'Port*: Portnummer des verbundenen L INSERT INTO txt VALUES ('H5212', 'English', 'Port*: Port number of the connected Ldap.'); INSERT INTO txt VALUES ('H5213', 'German', 'Tls: Zeigt an, ob TLS in der Kommunikation verwendet wird.'); INSERT INTO txt VALUES ('H5213', 'English', 'Tls: Flag if TLS is used for communication.'); -INSERT INTO txt VALUES ('H5214', 'German', 'Mandantenebene: Wenn Mandanten Teil des Distinguished Name (Dn) des Nutzers sind, definiert diese Zahl die Pfadtiefe, wo dieser zu finden ist. +INSERT INTO txt VALUES ('H5214', 'German', 'Mandantenebene: Wenn Mandanten Teil des Distinguished Name (Dn) des Nutzers sind, definiert diese Zahl die Pfadtiefe, wo dieser zu finden ist. Das beginnt mit 1 für das erste Element von rechts. Wenn keine Mandanten genutzt werden, auf 0 setzen. '); -INSERT INTO txt VALUES ('H5214', 'English', 'Tenant Level: If tenants are part of the distinguished names (Dn) of the user, this number defines the level in the path, where they are found. +INSERT INTO txt VALUES ('H5214', 'English', 'Tenant Level: If tenants are part of the distinguished name (Dn) of the user, this number defines the level in the path, where they are found. Starting with 1 for the first Dn element from the right. Set to 0 if no tenants are used. '); INSERT INTO txt VALUES ('H5215', 'German', 'Typ*: Implementierungstyp des Ldap, welcher die Syntax des Zugangs festlegt. Zur Zeit werden "OpenLdap" und "ActiveDirectory" unterstützt. @@ -3397,6 +5451,8 @@ INSERT INTO txt VALUES ('H5225', 'English', 'Global Tenant Name: If the Ldap is '); INSERT INTO txt VALUES ('H5226', 'German', 'Aktiv: Wenn das Ldap nicht auf aktiv gesetzt ist, wird es für andere Aktionen (Autorisierungen, Rollenzuweisung etc.) nicht berücksichtigt.'); INSERT INTO txt VALUES ('H5226', 'English', 'Active: If not set to active, the Ldap is not involved in other actions (authorization, role assignment etc.).'); +INSERT INTO txt VALUES ('H5227', 'German', 'Schreibpfad Gruppen: Der Distinguished name (Dn) des Wurzelverzeichnisses des Gruppensbaums. Dieser Parameter kann vom Suchpfad abweichen (was er im internen Ldap nicht tut).'); +INSERT INTO txt VALUES ('H5227', 'English', 'Group Write Path: The distinguished name (Dn) of the root of the group writ tree. This parameter may differ from the search path (in the internal Ldap it does not).'); INSERT INTO txt VALUES ('H5231', 'German', 'Die verfügbaren Mandanten werden hier mit den zugeordneten Gateways dargestellt.
            Es ist möglich, Mandanten im lokalen Ldap sowie Verknüpfungen zu den vorhandenen Gateways anzulegen oder zu löschen. Wenn Beispieldaten (definiert durch die Endung "_demo" vom Mandantennamen) existieren, wird eine Schaltfläche angezeigt, um diese zu löschen. @@ -3421,13 +5477,15 @@ INSERT INTO txt VALUES ('H5247', 'German', 'Superadmin: Zeigt an, dass es sich INSERT INTO txt VALUES ('H5247', 'English', 'Superadmin: Flag indicating the superadmin.'); INSERT INTO txt VALUES ('H5248', 'German', 'Gateways: Alle mit diesem Mandanten verknüpften Gateways.'); INSERT INTO txt VALUES ('H5248', 'English', 'Gateways: All gateways related to this tenant.'); +INSERT INTO txt VALUES ('H5249', 'German', 'IP-Adressen: Im Editiermodus können einem Mandanten (ausser dem Globalen Mandanten) zwecks Filterung IP-Adressen zugeordnet werden.'); +INSERT INTO txt VALUES ('H5249', 'English', 'IP Addresses: In the edit mode IP addresses can be assigned to the tenant (except global tenant) for the purpose of filtering.'); INSERT INTO txt VALUES ('H5261', 'German', 'Hier werden alle dem System bekannten Nutzer dargestellt. Das sind alle im internen Ldap angelegten Nutzer, sowie Nutzer von externen Ldaps, die sich schon mindestens einmal angemeldet haben.
            Der Administrator kann Nutzer anlegen, ändern oder löschen. Beim Anlegen besteht auch die Möglichkeit, sofort Gruppen- und Rollenzugehörigkeiten festzulegen. Weitere Gruppen- und Rollenzuordnungen können dann in den Abschnitten Gruppen bzw. Rollen erfolgen.
            Wenn Beispieldaten (definiert durch die Endung "_demo" vom Nutzernamen) existieren, wird eine Schaltfläche angezeigt, um diese zu löschen. '); -INSERT INTO txt VALUES ('H5261', 'English', 'Here all users known to the system are displayed. +INSERT INTO txt VALUES ('H5261', 'English', 'Here all users known to the system are displayed. These are all users defined in the internal Ldap and users from external Ldaps who have already logged in at least once.
            The administrator can add, change or delete users. When adding there is the possibility to assign group or role memberships. Further memberships can be administrated in the groups resp. roles sections.
            @@ -3436,7 +5494,7 @@ INSERT INTO txt VALUES ('H5261', 'English', 'Here all users known to the system INSERT INTO txt VALUES ('H5271', 'German', 'Aktionen: Nutzer können geklont, geändert oder gelöscht werden. Ausserdem kann der Administrator das Passwort der Nutzer zurücksetzen und ein neues setzen, welches den Vorgaben der Passworteinstellungen genügen muss. '); -INSERT INTO txt VALUES ('H5271', 'English', 'Actions: Users can be cloned, edited or deleted. +INSERT INTO txt VALUES ('H5271', 'English', 'Actions: Users can be cloned, edited or deleted. Additionally the administrator has the possibility to reset the password of the users and set a new password which has to comply with the Password Policy. '); INSERT INTO txt VALUES ('H5272', 'German', 'Name: Nutzername.'); @@ -3458,27 +5516,39 @@ INSERT INTO txt VALUES ('H5278', 'German', 'PW Änd. erf.: Zeigt an, dass d '); INSERT INTO txt VALUES ('H5278', 'English', 'Pwd Chg Req: Flag that the user has to change his password at next login. The user is then forced to change the password in a separate popup window before he can proceed to the application. - The flag is set when a new user is added or when the admin has reset the password, + The flag is set when a new user is added or when the admin has reset the password, except for users with auditor role, because that role is not allowed to make any changes in the system. '); +INSERT INTO txt VALUES ('H5279', 'German', 'Von LDAP: Ldap, in dem der Nutzer angelegt ist. Dies kann sowohl das interne, als auch ein in den Ldap-Einstellungen definiertes externes Ldap sein.'); +INSERT INTO txt VALUES ('H5279', 'English', 'From LDAP: Ldap, where the user is registered. This can be the internal as well as an external Ldap as defined in the Ldap Settings.'); +INSERT INTO txt VALUES ('H5280', 'German', 'In LDAP: Ldap, in dem der Nutzer angelegt werden soll. Angeboten werden sowohl das interne, als auch alle in den Ldap-Einstellungen definierten externen Ldaps, in denen Schreibrechte bestehen.'); +INSERT INTO txt VALUES ('H5280', 'English', 'Into LDAP: Ldap, where the user should be registered. Offered are the internal as well as all external Ldaps as defined in the Ldap Settings, where write permissions are given.'); +INSERT INTO txt VALUES ('H5281', 'German', 'Vorname: Vorname des Benutzers.'); +INSERT INTO txt VALUES ('H5281', 'English', 'First name: The user''s given name.'); +INSERT INTO txt VALUES ('H5282', 'German', 'Nachname: Nachname des Benutzers.'); +INSERT INTO txt VALUES ('H5282', 'English', 'Surname: The user''s surname.'); INSERT INTO txt VALUES ('H5301', 'German', 'Der Admin kann Nutzergruppen im internen Ldap definieren. Dabei besteht die Möglichkeit, sie gleich einer Rolle zuzuordnen. Weitere Rollenzuordnungen können dann unter Rollen erfolgen.
            - Wenn Beispieldaten (definiert durch die Endung "_demo" vom Gruppennamen) existieren, wird eine Schaltfläche angezeigt, um diese zu löschen. - Die Löschung ist nicht möglich, wenn Nutzer, die nicht als Beispielnutzer gekennzeichnet sind (Name endet nicht auf "_demo"), der Gruppe zugeordnet sind. '); INSERT INTO txt VALUES ('H5301', 'English', 'Groups of users can be defined by the admin in the internal Ldap. When adding there is the possibility to assign a role membership. Further memberships can be administrated in the roles section.
            - If there are sample data (defined by the ending "_demo" of the group name), a button is displayed to delete them. +'); +INSERT INTO txt VALUES ('H5302', 'German', 'Wenn Beispieldaten (definiert durch die Endung "_demo" vom Gruppennamen) existieren, wird eine Schaltfläche angezeigt, um diese zu löschen. + Die Löschung ist nicht möglich, wenn Nutzer, die nicht als Beispielnutzer gekennzeichnet sind (Name endet nicht auf "_demo"), der Gruppe zugeordnet sind. +'); +INSERT INTO txt VALUES ('H5302', 'English', 'If there are sample data (defined by the ending "_demo" of the group name), a button is displayed to delete them. The deletion is only possible, if there are no non-sample users (user name not ending with "_demo") assigned to the group. '); INSERT INTO txt VALUES ('H5311', 'German', 'Gruppenaktionen: Hier können selbstdefinierte Gruppen geändert (zur Zeit nur umbenannt) oder gelöscht werden.'); INSERT INTO txt VALUES ('H5311', 'English', 'Group actions: Here is the possibility to edit (currently only rename) or delete self defined user groups.'); -INSERT INTO txt VALUES ('H5312', 'German', 'Nutzeraktionen: Hier können dem System bekannte Nutzer (siehe Nutzereinstellungen) der Gruppe zugeordnet oder von dieser entfernt werden.'); -INSERT INTO txt VALUES ('H5312', 'English', 'User actions: Here users known to the system (see User settings) can be assigned to or removed from the user groups.'); +INSERT INTO txt VALUES ('H5312', 'German', 'Nutzeraktionen: Hier können dem System bekannte Nutzer (siehe Nutzereinstellungen) oder aus einem zu durchsuchenden Ldap der Gruppe zugeordnet bzw. von dieser entfernt werden.'); +INSERT INTO txt VALUES ('H5312', 'English', 'User actions: Here users known to the system (see User settings) or searched from an Ldap can be assigned to resp. removed from the user groups.'); INSERT INTO txt VALUES ('H5313', 'German', 'Name: Name der Nutzergruppe.'); INSERT INTO txt VALUES ('H5313', 'English', 'Name: Name of the user group.'); INSERT INTO txt VALUES ('H5314', 'German', 'Nutzer: Liste der der Gruppe zugeordneten Nutzer.'); INSERT INTO txt VALUES ('H5314', 'English', 'Users: List of assigned users to the group.'); +INSERT INTO txt VALUES ('H5315', 'German', 'Eigentümergruppe: Kann für die Eigentümerverwaltung beim Rezertifizieren oder Modellieren verwendet werden.'); +INSERT INTO txt VALUES ('H5315', 'English', 'Owner Group: Can be used for owner administration in recertification or modelling modules.'); INSERT INTO txt VALUES ('H5331', 'German', 'Alle definierten Rollen werden mit einer kurzen Erklärung dargestellt.
            Der Admin kann Nutzer oder Nutzergruppen den Rollen zuweisen bzw. von diesen entfernen. '); @@ -3491,7 +5561,7 @@ INSERT INTO txt VALUES ('H5341', 'German', 'Aktionen: Der Admin hat die Mö ausser für "anonymous" oder "middleware-server", welche nur intern genutzt werden kann. Das Hinzufügen der Nutzer kann auf drei Arten erfolgen: '); -INSERT INTO txt VALUES ('H5341', 'English', 'Actions: The admin can add or delete users from the roles, +INSERT INTO txt VALUES ('H5341', 'English', 'Actions: The admin can add or delete users from the roles, except for "anonymous" or "middleware-server" which can only be used internally. For adding users there are three possibilities: '); @@ -3506,15 +5576,15 @@ INSERT INTO txt VALUES ('H5351', 'German', 'Suche in einem der connected Ldaps. - A search string may be necessary with the minimal length defined in the Ldap connection. + A search string may be necessary with the minimal length defined in the Ldap connection. For that the syntax is the same as searching directly in the connected Ldap. '); INSERT INTO txt VALUES ('H5352', 'German', 'Auswahl aus der Liste der bekannten Nutzer, wie sie in den Nutzereinstellungen dargestellt wird.'); INSERT INTO txt VALUES ('H5352', 'English', 'Select from the list of known users also displayed in the users settings.'); INSERT INTO txt VALUES ('H5353', 'German', 'Auswahl aus der Liste der internen Gruppen, wie sie in den Gruppeneinstellungen dargestellt wird.'); INSERT INTO txt VALUES ('H5353', 'English', 'Select from the list of internal groups also displayed in the groups settings.'); -INSERT INTO txt VALUES ('H5361', 'German', 'Reporting und Rezertifizierung (regelbasiert): reporter, reporter-viewall, recertifier'); -INSERT INTO txt VALUES ('H5361', 'English', 'Reporting and recertification (rule based): reporter, reporter-viewall, recertifier'); +INSERT INTO txt VALUES ('H5361', 'German', 'Reporting, Modellierung und Rezertifizierung (regelbasiert): reporter, reporter-viewall, modeller, recertifier'); +INSERT INTO txt VALUES ('H5361', 'English', 'Reporting, modelling and recertification (rule based): reporter, reporter-viewall, modeller, recertifier'); INSERT INTO txt VALUES ('H5362', 'German', 'Workflow: requester, approver, planner, implementer, reviewer'); INSERT INTO txt VALUES ('H5362', 'English', 'Workflow: requester, approver, planner, implementer, reviewer'); INSERT INTO txt VALUES ('H5363', 'German', 'Übergeordnete Rollen: admin, fw-admin, auditor, (anonymous)'); @@ -3530,7 +5600,7 @@ INSERT INTO txt VALUES ('H5401', 'English', 'The admin can define several defaul INSERT INTO txt VALUES ('H5411', 'German', 'Standardsprache: Die Sprache, die neuen Nutzern beim ersten Anmelden zugewiesen wird. Nach dem Anmelden kann jeder Nutzer seine eigene bevorzugte Sprache definieren. '); -INSERT INTO txt VALUES ('H5411', 'English', 'Default Language: The language which every user gets at first login. +INSERT INTO txt VALUES ('H5411', 'English', 'Default Language: The language which every user gets at first login. After login each user can define its own preferred language. '); INSERT INTO txt VALUES ('H5412', 'German', 'UI - Pro Abruf geholte Elemente: Definiert die (maximale) Anzahl der Objekte, die bei der Reporterzeugung und beim Aufbau der rechten Randleiste in einem Schritt geholt werden. @@ -3553,51 +5623,22 @@ INSERT INTO txt VALUES ('H5414', 'English', 'Completely auto-fill right sidebar: '); INSERT INTO txt VALUES ('H5415', 'German', 'Datenaufbewahrungszeit (in Tagen): Legt fest, wie lange die Daten in der Datenbank gehalten werden (wird noch nicht unterstützt).'); INSERT INTO txt VALUES ('H5415', 'English', 'Data retention time (in days): Defines how long the data is kept in the database (currently not supported).'); -INSERT INTO txt VALUES ('H5416', 'German', ' -
              -
            • Importintervall (in Sekunden): Zeitintervall zwischen zwei Import-Läfen. Default-Wert = 40.
            • -
            • Zertifikate beim Import prüfen: Sollen bei den API-Calls in Richtung der Firewalls nur gültige Zertifikate akzeptiert werden?. - Sollte nur auf "aktiv" gesetzt werden, wenn alle Firewalls offiziell signierte Zertifikate besitzen, - andernfalls ist ein Import nicht möglich. Default-Wert = "inaktiv".
            • -
            • Zertifikatswarnungen unterdrücken: Sollen im Log Warnungen bei selbstsignierten oder ungültigen Zertifkaten auf zu importierenden - Firewalls ausgegeben werden? Default-Wert = "inaktiv".
            • -
            • FW API - Pro Abruf geholte Elemente: Wie viele Objekte sollen beim Import per Firewall-API Call auf einmal geholt werden? Default-Wert = 150.
            • -
            • Änderungsbenachrichtigung via Email -
                -
              • Änderungsbenachrichtigung aktiv: Sollen Emails bei festgestellten Änderungen versendet werden, ist diese - Einstellung zu aktivieren. Default-Wert = "inaktiv".
              • -
              • Empfänger-Email-Adressen für Änderungen: Komma-separierte Liste von Email-Adressen, die bei festgestellter - sicherheitsrelevanter Änderung auf einem importierten Management benachrichtigt werden. Default-Wert = "leer".
              • -
              • Titel der Änderungsbenachrichtigung: Betreffzeile der Benachrichtigungs-Email. Default-Wert = "leer".
              • -
              • Text der Änderungsbenachrichtigung: Start des Email-Textes. Die Email enthält stets den Namen und die ID des - geänderten Managements sowie die Anzahl der festgestellten Änderungen. Default-Wert = "leer".
              • -
              -
            • -
            -'); -INSERT INTO txt VALUES ('H5416', 'English', ' -
              -
            • Import sleep time (in seconds): Time between import loops; default value=40.
            • -
            • Check certificates during import: During API calls towards Firewalls shall only valid certificates be accepted?. - This should only be set to "active" if all firewall API certificates are valid, otherwise an import will not be possible. - Default value = "inactive".
            • -
            • Suppress certificate warnings: Shall warnings about invalid certificates be written to import log? Default value = "inactive".
            • -
            • FW API - Elements per fetch: How many objects/rules shall be fetched per API call from a firewall management? Default value = 150.
            • -
            • Change notification via email: -
                -
              • Change notification active?: When an import finds security relevant changes, should an email be sent out? - Default value = "inactive".
              • -
              • Recipient email addresses for change notifications: A comma-separated list of email addresses, which will get information in the case of - security relevant changes found during import of a firewall management. Default value = "empty".
              • -
              • Subject of change notification emails: Subject line for notification emails. Default value = "empty".
              • -
              • Body of change notification emails: Start of the email text. The email will always contain name and ID of the changed - firewall management as well as the number of changes. Default value = "empty".
              • -
              -
            • -
            -'); -INSERT INTO txt VALUES ('H5417', 'German', 'Rezertifizierungsintervall (in Tagen): Maximale Zeit, nach der eine Regel rezertifiziert werden soll.'); -INSERT INTO txt VALUES ('H5417', 'English', 'Recertification Period (in days): Maximum time, after when a rule should be recertified.'); +INSERT INTO txt VALUES ('H5416', 'German', 'Einstellungen für Änderungsbenachrichtigungen via E-Mail:'); +INSERT INTO txt VALUES ('H5416', 'English', 'Change Notification Email Settings:'); +INSERT INTO txt VALUES ('H5416a', 'German', 'Trigger-Einstellungen für Änderungsbenachrichtigungen:'); +INSERT INTO txt VALUES ('H5416a', 'English', 'Change Notification Trigger Settings:'); +INSERT INTO txt VALUES ('H5416b', 'German', 'Trigger-Einstellungen für Regelverantwortlungs-Aktualisierung:'); +INSERT INTO txt VALUES ('H5416b', 'English', 'Update Rule Owner Mapping Trigger Settings:'); +INSERT INTO txt VALUES ('H5417', 'German', 'Rezertifizierungsintervall (in Tagen): Maximale Zeit, nach der ein Eigentümer bzw. eine Regel rezertifiziert werden soll. + Bei Rezertifizierungsmodus "Eigentümer und Regeln": Default-Wert für alle Eigentümer, für die kein Wert gesetzt ist. +'); +INSERT INTO txt VALUES ('H5417', 'English', 'Recertification Period (in days): Maximum time, after when an owner resp. a rule should be recertified. + In case of Recertification Mode "Owners And Rules": Default period for all owners where no value set. +'); +INSERT INTO txt VALUES ('H5417a', 'German', 'Initiales Rezertifizierungsintervall (in Tagen): Maximale Zeit, nach der ein Eigentümer bzw. eine Regel das erste Mal rezertifiziert werden muss.'); +INSERT INTO txt VALUES ('H5417a', 'English', 'Initial Recertification Period (in days): Maximum time, after when an owner resp. a rule has to be recertified the first time.'); +INSERT INTO txt VALUES ('H5417b', 'German', 'Initialer Rezertifizierer: Name, der als Rezertifizierer bei der automatischen initialen Rezertifizierung eingetragen werden soll.'); +INSERT INTO txt VALUES ('H5417b', 'English', 'Initial Recertifier: Name displayed as recertifier on automatic initial recertification.'); INSERT INTO txt VALUES ('H5418', 'German', 'Rezertifizierungserinnerungsintervall (in Tagen): Zeit vor dem Fälligkeitsdatum, ab der eine Regel als fällig hervorgehoben werden soll.'); INSERT INTO txt VALUES ('H5418', 'English', 'Recertification Notice Period (in days): Time before the due date when the rule should be marked as upcoming recertification.'); INSERT INTO txt VALUES ('H5419', 'German', 'Rezertifizierungsanzeigeintervall (in Tagen): Vorausschauintervall für fällige Rezertifizierungen.'); @@ -3610,23 +5651,33 @@ INSERT INTO txt VALUES ('H5422', 'German', 'Devices zu Beginn eingeklappt ab: L INSERT INTO txt VALUES ('H5422', 'English', 'Devices collapsed at beginning from: defines from which number of devices (managements + gateways) they are displayed collapsed in the left sidebar at beginning.'); INSERT INTO txt VALUES ('H5423', 'German', 'Nachrichten-Anzeigedauer (in Sekunden): legt fest, wie lange Erfolgs-Nachrichten dargestellt werden, bis sie automatisch ausgeblendet werden. Fehler-Nachrichten erscheinen dreimal so lange. Beim Wert 0 werden die Nachrichten nicht automatisch ausgeblendet. - Die Nutzer-Meldungen können auch danach noch unter UI-Nachrichten eingesehen werden. + Die Nutzer-Meldungen können auch danach noch im Monitoring unter UI-Nachrichten eingesehen werden. '); INSERT INTO txt VALUES ('H5423', 'English', 'Message view time (in seconds): defines how long success messages are displayed, until they fade out automatically. Error messages are displayed 3 times as long. Value 0 means that the messages do not fade out. - All user messages can still be reviewed at UI Messages. + All user messages can still be reviewed in the monitoring tab at UI Messages. '); INSERT INTO txt VALUES ('H5424', 'German', 'Startzeit täglicher Check: legt die Zeit fest, wann der tägliche Check durchgeführt werden soll.'); INSERT INTO txt VALUES ('H5424', 'English', 'Daily check start at: defines the time when the daily check should happen.'); +INSERT INTO txt VALUES ('H5424a', 'German', 'Module täglicher Check: legt fest, welche Teile des täglichen Checks ausgeführt werden sollen.'); +INSERT INTO txt VALUES ('H5424a', 'English', 'Daily check modules: defines which parts of the daily check should be executed.'); +INSERT INTO txt VALUES ('H5425', 'German', 'Hostname der UI: URL der UI, wird z. B. für Links in Email-Benachrichtigungen benötigt.'); +INSERT INTO txt VALUES ('H5425', 'English', 'UI Hostname: URL of the UI, needed e.g. for links in email notifications.'); INSERT INTO txt VALUES ('H5426', 'German', 'Autodiscover-Intervall (in Stunden): legt das Intervall fest, in dem die Autodiscovery durchgeführt werden soll.'); INSERT INTO txt VALUES ('H5426', 'English', 'Auto-discovery sleep time (in hours): defines the interval in which the autodiscovery should be performed.'); +INSERT INTO txt VALUES ('H5426a', 'German', 'Externes Auftrags-Intervall (in Sekunden): legt das Intervall fest, in dem die externen Aufträge durchgeführt werden sollen.'); +INSERT INTO txt VALUES ('H5426a', 'English', 'External Request sleep time (in seconds): defines the interval in which the external requests should be performed.'); +INSERT INTO txt VALUES ('H5426b', 'German', 'Anzahl Wartezyklen: legt fest, wie viele Zyklen des Auftrags-Intervalls bei bestimmten Aufträgen gewartet werden soll (z.B. nach Neuanlegen von Netzwerkobjekten).'); +INSERT INTO txt VALUES ('H5426b', 'English', 'Number wait cycles: defines how many cycles of the external request interval are to be waited in case of some requests (e.g. after creation of new network objects).'); INSERT INTO txt VALUES ('H5427', 'German', 'Autodiscover-Start: legt eine Bezugszeit fest, ab dem die Intervalle für die Autodiscovery gerechnet werden.'); INSERT INTO txt VALUES ('H5427', 'English', 'Auto-discovery start at: defines a referential time from which the autodiscovery intervals are calculated.'); +INSERT INTO txt VALUES ('H5427a', 'German', 'Externer Auftrags-Start: legt eine Bezugszeit fest, ab dem die Intervalle für die externen Aufträge gerechnet werden.'); +INSERT INTO txt VALUES ('H5427a', 'English', 'External Request start at: defines a referential time from which the external request intervals are calculated.'); INSERT INTO txt VALUES ('H5428', 'German', 'Rezert Check - aktiv: aktviere bzw. deaktiviere regelmäßige Prüfungen zur Versendung von Benachrichtigungs- oder Eskalations-Emails an die Eigentümer.'); INSERT INTO txt VALUES ('H5428', 'English', 'Recert Check - active: enable or disable recurring recertification checks to send out notification or escalation emails to owners.'); INSERT INTO txt VALUES ('H5429', 'German', 'Rezert Check alle: Abstand der Prüfungen für den Versand von Benachrichtigungs- oder Eskalations-Emails an die Eigentümer.'); INSERT INTO txt VALUES ('H5429', 'English', 'Recert Check every: Interval between checks for recertification notifications.'); -INSERT INTO txt VALUES ('H5430', 'German', 'Rezert Check - Email Titel: Titel der Benachrichtigungs-Email.'); +INSERT INTO txt VALUES ('H5430', 'German', 'Rezert Check - Email Betreff: Betreff der Benachrichtigungs-Email.'); INSERT INTO txt VALUES ('H5430', 'English', 'Recert Check - Email subject: Subject line of the notification email.'); INSERT INTO txt VALUES ('H5431', 'German', 'Der Administrator kann Vorgaben für Passwörter definieren, gegen die alle neuen Passwörter aller (internen) Nutzer geprüft werden.'); INSERT INTO txt VALUES ('H5431', 'English', 'The admin user can define a password policy, against which all new passwords of all (internal) users are checked.'); @@ -3637,9 +5688,9 @@ INSERT INTO txt VALUES ('H5433', 'German', 'Autom. Anlegen Löschantrag: So INSERT INTO txt VALUES ('H5433', 'English', 'Autocreate delete rule ticket: When a rule has been fully de-certified, should a delete ticket be automatically generated?'); INSERT INTO txt VALUES ('H5434', 'German', 'Titel für Löschantrag: Titel des zu erzeugenden Lösch-Tickets.'); INSERT INTO txt VALUES ('H5434', 'English', 'Title delete ticket: Subject line of the delete ticket to be generated.'); -INSERT INTO txt VALUES ('H5435', 'German', 'Grund für Lösch-Antrag: Text für den Grund des zu erzeugenden Lösch-Tickets.'); +INSERT INTO txt VALUES ('H5435', 'German', 'Grund für Löschantrag: Text für den Grund des zu erzeugenden Lösch-Tickets.'); INSERT INTO txt VALUES ('H5435', 'English', 'Reason delete ticket: Text for the reason of the delete ticket to be generated.'); -INSERT INTO txt VALUES ('H5436', 'German', 'Titel für Lösch Auftrag: Titel der zu erzeugenden Löschaufgabe.'); +INSERT INTO txt VALUES ('H5436', 'German', 'Titel für Löschauftrag: Titel der zu erzeugenden Löschaufgabe.'); INSERT INTO txt VALUES ('H5436', 'English', 'Title delete rule task: Title of the delete task to be generated.'); INSERT INTO txt VALUES ('H5437', 'German', 'Grund für Löschauftrag: Begründungstext für die zu erzeugende Löschaufgabe.'); INSERT INTO txt VALUES ('H5437', 'English', 'Reason for delete rule task: Text for the reason of the delete task to be generated.'); @@ -3682,7 +5733,18 @@ INSERT INTO txt VALUES ('H5452', 'German', 'Max erlaubte Importdauer (in Stunde INSERT INTO txt VALUES ('H5452', 'English', 'Max allowed import duration (in hours): Upper limit for the accepted import duration in the daily check.'); INSERT INTO txt VALUES ('H5453', 'German', 'Max erlaubtes Importintervall (in Stunden): Obergrenze, welcher Abstand zwischen zwei Imports im täglichen Check noch akzeptiert wird.'); INSERT INTO txt VALUES ('H5453', 'English', 'Max import interval (in hours): Upper limit for the accepted interval between two imports in the daily check.'); - +INSERT INTO txt VALUES ('H5454', 'German', 'Regel-Eigentümerschaftsmodus: (Gemischt/Exklusiv) Wird z. Zt. nicht genutzt.'); +INSERT INTO txt VALUES ('H5454', 'English', 'Rule Ownership Mode: (Mixed/Exclusive) Currently not in use.'); +INSERT INTO txt VALUES ('H5455', 'German', 'Verfügbare Reporttypen: Es kann ausgewählt werden, welche der technisch vorhandenen Reporttypen zur Verwendung in der Oberfläche angeboten werden sollen. Die Liste der angebotenen Reporttypen beim Nutzer kann je nach Rolle weiter verkürzt sein.'); +INSERT INTO txt VALUES ('H5455', 'English', 'Available Report Types: It can be selected, which of the technically available report types should be offered for use in the UI. The List of offered report types to the user can be shorter depending on the respective role.'); +INSERT INTO txt VALUES ('H5456', 'German', 'Netzbereiche auflösen: Darstellung aller Elemente eines Netzbereichs in Verbindungs-orientierten Reports'); +INSERT INTO txt VALUES ('H5456', 'English', 'Resolve Network Areas: Display of all elements of a network area in connection related reports.'); +INSERT INTO txt VALUES ('H5457', 'German', 'Verfügbare Module: Es kann ausgewählt werden, welche der technisch vorhandenen Module zur Verwendung in der Oberfläche angeboten werden sollen. Die Anzahl der angebotenen Module beim Nutzer kann je nach Rolle geringer sein.'); +INSERT INTO txt VALUES ('H5457', 'English', 'Available Modules: It can be selected, which of the technically available modules should be offered for use in the UI. The number of offered modules to the user can be smaller depending on the respective role.'); +INSERT INTO txt VALUES ('H5458', 'German', 'Rezertifizierungsmodus: Methode der Rezertifizierung.'); +INSERT INTO txt VALUES ('H5458', 'English', 'Recertification Mode: Type of recertification.'); +INSERT INTO txt VALUES ('H5459', 'German', 'Rezert Check - Benachrichtigungen: Legt fest, wer in welchem Zeitintervall vor dem Rezert-Termin benachrichtigt wird.'); +INSERT INTO txt VALUES ('H5459', 'English', 'Recert Check - Notifications: Defines who will be notified in which time interval before the recert deadline.'); INSERT INTO txt VALUES ('H5461', 'German', 'Jeder Nutzer kann seine eigene bevorzugte Sprache für die Anwendung einstellen.
            Alle Texte werden in dieser Sprache dargestellt, soweit verfügbar. Wenn nicht, wird die Standardsprache verwendet. Wenn der Text auch dort nicht verfügbar ist, wird Englisch genutzt. Die Standardsprache beim ersten Anmelden kann vom Admin für alle Nutzer in den Standardeinstellungen definiert werden.

            @@ -3693,6 +5755,8 @@ INSERT INTO txt VALUES ('H5461', 'English', 'Every user can set his own preferre The default language at first login can be defined by the admin for all users in the Default Settings.

            Currently available: '); +INSERT INTO txt VALUES ('H5466', 'German', 'Nachricht die auf der Anmeldeseite angezeigt werden soll.'); +INSERT INTO txt VALUES ('H5466', 'English', 'Message that is displayed on Login Page.'); INSERT INTO txt VALUES ('H5471', 'German', 'Jeder Nutzer kann einige persönliche Voreinstellungen für die Reporteinstellungen überschreiben. Ausgangswert ist der vom Admin in den Standardeinstellungen gesetzte Wert. '); @@ -3702,31 +5766,102 @@ INSERT INTO txt VALUES ('H5471', 'English', 'Every user can overwrite some perso INSERT INTO txt VALUES ('H5481', 'German', 'Ein Rezertifizierer kann einige persönliche Voreinstellungen für den Rezertifizierungsreport überschreiben. Ausgangswert ist der vom Admin in den Standardeinstellungen gesetzte Wert. '); -INSERT INTO txt VALUES ('H5481', 'English', 'A recertifier can overwrite some personal settings for the recertification report. +INSERT INTO txt VALUES ('H5481', 'English', 'A recertifier can overwrite some personal settings for the recertification report. The default value is set by the admin in the Default Settings. '); -INSERT INTO txt VALUES ('H5491', 'German', 'Firewall Orchestrator kann Benachrichtigungen versenden, z.B. für anstehende Rezertifizierungen oder wenn beim Import - Änderungen festgestellt wurden. +INSERT INTO txt VALUES ('H5482', 'German', 'Die folgenden Einstellungen gelten für Ereignis-Trigger bei FW-Änderungen und Aktualisierungen'); +INSERT INTO txt VALUES ('H5482', 'English', 'The following settings apply to event triggers for FW changes and updates'); +INSERT INTO txt VALUES ('H5483', 'German', 'Änderungsbenachrichtigung aktiv: Sollen Emails bei festgestellten Änderungen versendet werden, ist diese + Einstellung zu aktivieren. Default-Wert = "inaktiv". +'); +INSERT INTO txt VALUES ('H5483', 'English', 'Change notification active?: When an import finds security relevant changes, should an email be sent out? + Default value = "inactive". +'); +INSERT INTO txt VALUES ('H5483a', 'German', 'Regel-Eigentümer-Zuordnungs-Aktualisierung aktiv: Wenn sich ein Eigentümer oder eine Regel ändert, wird die Zuordnung automatisch überprüft und ggf. eine neue Zuordnung erstellt. + Default-Wert = "inaktiv". +'); +INSERT INTO txt VALUES ('H5483a', 'English', 'Update Rule Owner Mapping active?: When an owner or a rule changes, the mapping is automatically checked and a new mapping is created if needed. + Default value = "inactive". +'); +INSERT INTO txt VALUES ('H5484', 'German', 'Änderungsbenachrichtigungstyp: Art und Umfang, in dem die Änderungsbenachrichtigung gesendet werden soll:
              -
            • Der Name oder die IP-Adresse des SMTP-Servers für ausgehende Emails wird im Feld "Adresse" eingetragen.
            • -
            • Der TCP-Port des SMTP-Servers (meist 25, 587 oder 465, abhängig von der verwendeten Verschlüsselung) wird im "Port"-Feld eingetragen.
            • -
            • Anschließend wird die gewünschte Art der Verschlüsselung eingestellt (None=unverschlüsselt / StartTls / Tls)
            • -
            • Verlangt der SMTP-Server eine Authentisierung, so sind Email-Nutzer und Email-Nutzer-Passwort in den beiden folgenden Feldern einzutragen. Anderfalls können diese Felder leer gelassen werden.
            • -
            • Schließkann nach eine individuelle Absendeadresse im Feld "Email-Absendeadresse" konfiguriert werden.
            • +
            • Einfacher Text (kein Änderungsreport): Es wird nur der hier definierte Text der Änderungsbenachrichtigung gesendet.
            • +
            • Html in Email: Ein Changes Report wird zu den im Import gefundenen Änderungen erstellt und in der email als Html versendet.
            • +
            • Pdf als Anhang: Ein Changes Report wird erstellt und der email als Pdf-Datei angehängt.
            • +
            • Html als Anhang: Ein Changes Report wird erstellt und der email als Html-Datei angehängt.
            • +
            • Json als Anhang: Ein Changes Report wird erstellt und der email als Json-Datei angehängt.
            '); -INSERT INTO txt VALUES ('H5491', 'English', 'Firewall Orchestrator is able to send out notifications, e.g. for upcoming recertifications or when an import found changes in the firewall configuration.
            +INSERT INTO txt VALUES ('H5484', 'English', 'Change notification type: Defines how and with which content the notification should be sent:
              -
            • Enter the name of IP address of your outgoing SMTP server in the field Feld "Adress".
            • -
            • The TCP port of the SMTP server (usually 25, 587 or 465, depending on the encryption method used) is entered in the "Port" field.
            • -
            • Choose the desired encryption type (None=clear-text / StartTls / Tls)
            • -
            • If the SMTP server requires authentication, enter Email User name and password in the following two fields. Otherwise leave empty.
            • -
            • Finally an individual sender address can be configured using the field "Email sender address".
            • +
            • Simple Text (no Change Report): Only the body of change notification emails as defined below is sent.
            • +
            • Html in email body: A Changes Report is created and sent as Html in the email body
            • +
            • Pdf as Attachment: A Changes Report is created and attached to the email as Pdf file.
            • +
            • Html as Attachment: A Changes Report is created and attached to the email as Html file.
            • +
            • Json as Attachment: A Changes Report is created and attached to the email as Json file.
            '); +INSERT INTO txt VALUES ('H5485', 'German', 'Änderungsbenachrichtigungs-Intervall (in Sekunden): Zeit zwischen den Checks auf importierte Änderungen.'); +INSERT INTO txt VALUES ('H5485', 'English', 'Change notification sleep time (in seconds): Time between the checks for imported changes.'); +INSERT INTO txt VALUES ('H5485a', 'German', 'Regel-Eigentümer-Zuordnungs-Aktualisierungs-Intervall (in Sekunden): Zeit zwischen den Checks auf importierte Änderungen.'); +INSERT INTO txt VALUES ('H5485a', 'English','Update Rule Owner Mapping sleep time (in seconds): Time between the checks for imported changes.'); +INSERT INTO txt VALUES ('H5486', 'German', 'Änderungsbenachrichtigungs-Start: Startzeit für die Checks auf importierte Änderungen.'); +INSERT INTO txt VALUES ('H5486', 'English', 'Change notification start at: Start time for the import change checks.'); +INSERT INTO txt VALUES ('H5486a', 'German', 'Regel-Eigentümer-Zuordnungs-Aktualisierungs-Start: Startzeit für die Checks auf importierte Änderungen.'); +INSERT INTO txt VALUES ('H5486a', 'English','Update Rule Owner Mapping start at: Start time for the import change checks.'); +INSERT INTO txt VALUES ('H5486b','German', 'Einstellungen für Trigger zur Aktualisierung der Regelverantwortung'); +INSERT INTO txt VALUES ('H5486b','English', 'Rule Owner Mapping Update Event Trigger Settings'); +INSERT INTO txt VALUES ('H5487', 'German', 'Empfänger-Email-Adressen für Änderungen: Komma-separierte Liste von Email-Adressen, die bei festgestellter + sicherheitsrelevanter Änderung auf einem importierten Management benachrichtigt werden. Default-Wert = "leer". +'); +INSERT INTO txt VALUES ('H5487', 'English', 'Recipient email addresses for change notifications: A comma-separated list of email addresses, which will get information in the case of + security relevant changes found during import of a firewall management. Default value = "empty". +'); +INSERT INTO txt VALUES ('H5488', 'German', 'Titel der Änderungsbenachrichtigung: Betreffzeile der Benachrichtigungs-Email. Default-Wert = "leer".'); +INSERT INTO txt VALUES ('H5488', 'English', 'Subject of change notification emails: Subject line for notification emails. Default value = "empty".'); +INSERT INTO txt VALUES ('H5489', 'German', 'Text der Änderungsbenachrichtigung: Start des Email-Textes für alle Änderungsbenachrichtigungstypen. Die Email enthält danach stets + eine Liste der Namen und IDs der geänderten Managements sowie die Anzahl der festgestellten Änderungen. Default-Wert = "leer". +'); +INSERT INTO txt VALUES ('H5489', 'English', 'Body of change notification emails: Start of the email text for all change notification types. The email will subsequently always contain + a list of names and IDs of the changed firewall management as well as the number of changes. Default value = "empty". +'); +INSERT INTO txt VALUES ('H5491', 'German', 'Firewall Orchestrator kann Benachrichtigungen versenden, z.B. für anstehende Rezertifizierungen oder wenn beim Import Änderungen festgestellt wurden.'); +INSERT INTO txt VALUES ('H5491', 'English', 'Firewall Orchestrator is able to send out notifications, e.g. for upcoming recertifications or when an import found changes in the firewall configuration.
            '); +INSERT INTO txt VALUES ('H5491a','German', 'Der Name oder die IP-Adresse des SMTP-Servers für ausgehende Emails wird im Feld "Adresse" eingetragen.'); +INSERT INTO txt VALUES ('H5491a','English', 'Enter the name of IP address of your outgoing SMTP server in the field Feld "Adress".'); +INSERT INTO txt VALUES ('H5491b','German', 'Der TCP-Port des SMTP-Servers (meist 25, 587 oder 465, abhängig von der verwendeten Verschlüsselung) wird im "Port"-Feld eingetragen.'); +INSERT INTO txt VALUES ('H5491b','English', 'The TCP port of the SMTP server (usually 25, 587 or 465, depending on the encryption method used) is entered in the "Port" field.'); +INSERT INTO txt VALUES ('H5491c','German', 'Anschließend wird die gewünschte Art der Verschlüsselung eingestellt (None=unverschlüsselt / StartTls / Tls)'); +INSERT INTO txt VALUES ('H5491c','English', 'Choose the desired encryption type (None=clear-text / StartTls / Tls)'); +INSERT INTO txt VALUES ('H5491d','German', 'Verlangt der SMTP-Server eine Authentisierung, so sind Email-Nutzer und Email-Nutzer-Passwort in den beiden Feldern einzutragen. Anderfalls können diese Felder leer gelassen werden.'); +INSERT INTO txt VALUES ('H5491d','English', 'If the SMTP server requires authentication, enter Email User name and password in the two fields. Otherwise leave empty.'); +INSERT INTO txt VALUES ('H5491e','German', 'Schließlich kann auch eine individuelle Absendeadresse im Feld "Email-Absendeadresse" konfiguriert werden.'); +INSERT INTO txt VALUES ('H5491e','English', 'Finally an individual sender address can be configured using the field "Email sender address".'); +INSERT INTO txt VALUES ('H5491f','German', 'Dummy-Email-Addresse nutzen: Zu Testzwecken werden alle ausgehenden emails (ausser der Test-Email) auf eine Emailaddresse umgeleitet.'); +INSERT INTO txt VALUES ('H5491f','English', 'Use dummy email address: For testing purpose all sent emails (except the test email) are redirected to a dummy email address.'); +INSERT INTO txt VALUES ('H5491g','German', 'Dummy-Email-Addresse: Addresse auf welche die Emails umgeleitet werden, wenn Umleitung aktiviert.'); +INSERT INTO txt VALUES ('H5491g','English', 'Dummy email address: Address where emails are directed, if redirection is activated.'); +INSERT INTO txt VALUES ('H5492','German', 'Verbindung testen: Es wird eine Test-email an die oben eingerichtete email-Adresse versandt.'); +INSERT INTO txt VALUES ('H5492','English', 'Test connection: A test email is sent to the above defined email address.'); INSERT INTO txt VALUES ('H5495', 'German', 'Die folgenden Einstellungen wirken sich auf das Import-Modul (python) aus.'); INSERT INTO txt VALUES ('H5495', 'English', 'The following settings apply to the Import Module (python)'); -INSERT INTO txt VALUES ('H5501', 'German', 'Aktionen müssen zuerst in den Einstellungen definiert werden und können dann den jeweiligen Stati zugeordnet werden. +INSERT INTO txt VALUES ('H5496', 'German', 'Importintervall (in Sekunden): Zeitintervall zwischen zwei Import-Läufen. Default-Wert = 40.'); +INSERT INTO txt VALUES ('H5496', 'English', 'Import sleep time (in seconds): Time between import loops; default value=40.'); +INSERT INTO txt VALUES ('H5497', 'German', 'Zertifikate beim Import prüfen: Sollen bei den API-Calls in Richtung der Firewalls nur gültige Zertifikate akzeptiert werden?. + Sollte nur auf "aktiv" gesetzt werden, wenn alle Firewalls offiziell signierte Zertifikate besitzen, + andernfalls ist ein Import nicht möglich. Default-Wert = "inaktiv". +'); +INSERT INTO txt VALUES ('H5497', 'English', 'Check certificates during import: During API calls towards Firewalls shall only valid certificates be accepted?. + This should only be set to "active" if all firewall API certificates are valid, otherwise an import will not be possible. + Default value = "inactive". +'); +INSERT INTO txt VALUES ('H5498', 'German', 'Zertifikatswarnungen unterdrücken: Sollen im Log Warnungen bei selbstsignierten oder ungültigen Zertifkaten auf zu importierenden + Firewalls ausgegeben werden? Default-Wert = "inaktiv". +'); +INSERT INTO txt VALUES ('H5498', 'English', 'Suppress certificate warnings: Shall warnings about invalid certificates be written to import log? Default value = "inactive".'); +INSERT INTO txt VALUES ('H5499', 'German', 'FW API - Pro Abruf geholte Elemente: Wie viele Objekte sollen beim Import per Firewall-API Call auf einmal geholt werden? Default-Wert = 150.'); +INSERT INTO txt VALUES ('H5499', 'English', 'FW API - Elements per fetch: How many objects/rules shall be fetched per API call from a firewall management? Default value = 150.'); +INSERT INTO txt VALUES ('H5501', 'German', 'Aktionen müssen zuerst in den Einstellungen definiert werden und können dann den jeweiligen Status zugeordnet werden. Die Aktion wird dann bei Eintreffen der hier definierten Bedingungen angeboten bzw. ausgeführt. '); INSERT INTO txt VALUES ('H5501', 'English', 'Actions have to be defined first in the customizing settings before they can be assigned to the desired states. @@ -3734,7 +5869,7 @@ INSERT INTO txt VALUES ('H5501', 'English', 'Actions have to be defined first in '); INSERT INTO txt VALUES ('H5511', 'German', 'Allgemeine Parameter für alle Aktionstypen: Hier wird definiert, unter welchen Bedingungen eine Aktion ausgelöst werden soll.'); INSERT INTO txt VALUES ('H5511', 'English', 'General parameters for all action types: Here it can be defined, under which conditions an action should be performed.'); -INSERT INTO txt VALUES ('H5512', 'German', 'Name: Der Name, unter dem die Aktion den Stati zugeordnet wird (da intern eine Id verarbeitet wird, sind auch doppelt vergebene Namen möglich).'); +INSERT INTO txt VALUES ('H5512', 'German', 'Name: Der Name, unter dem die Aktion den Status zugeordnet wird (da intern eine Id verarbeitet wird, sind auch doppelt vergebene Namen möglich).'); INSERT INTO txt VALUES ('H5512', 'English', 'Name: The name to be found in the state assignment (as internally the Id is processed, duplicate names are possible).'); INSERT INTO txt VALUES ('H5513', 'German', 'Ereignis: Es wird zwischen drei Ereignistypen unterschieden: Bei "Beim Erreichen" wird die Aktion beim Erreichen, bei "Beim Verlassen" beim Verlassen des zugeordneten Status ausgelöst. Bei "Schaltfläche anbieten" wird eine Schaltfläche zur manuellen Ausführung in dem ausgewählten Objekttyp eingeblendet, solange der zugeordnete Status besteht. In diesem Fall ist auch der auf der Schaltfläche erscheinende Text auszufüllen. @@ -3746,7 +5881,7 @@ INSERT INTO txt VALUES ('H5513', 'English', 'Event: It has to be distinguished b '); INSERT INTO txt VALUES ('H5514', 'German', 'Phase: Hier kann die Aktion für alle Phasen zugelassen oder auf eine auszuwählende Phase beschränkt werden.'); INSERT INTO txt VALUES ('H5514', 'English', 'Phase: Here the action can be permitted for all phases or restricted on a selected phase.'); -INSERT INTO txt VALUES ('H5515', 'German', 'Geltungsbereich: Hier wird festgelegt, auf welchen Objekttyp (Ticket, fachlicher Auftrag, Implementierungs-Auftrag, Genehmigung) sich die Aktion bezieht. +INSERT INTO txt VALUES ('H5515', 'German', 'Geltungsbereich: Hier wird festgelegt, auf welchen Objekttyp (Ticket, fachlicher Auftrag, Implementierungs-Auftrag, Genehmigung) sich die Aktion bezieht. Für Request Task oder Implementation Task kann in einer weiteren Auswahl der zu berücksichtigende Tasktyp eingeschränkt werden. '); INSERT INTO txt VALUES ('H5515', 'English', 'Scope: Here it can be defined, to which object type (Ticket, Request Task, Implementation Task, Approval) the action should reference. @@ -3772,21 +5907,39 @@ INSERT INTO txt VALUES ('H5526', 'German', 'Pfadanalyse: Hier kann zwischen den INSERT INTO txt VALUES ('H5526', 'English', 'Path analysis: Here the options "Write to device list" or "Display found devices" can be selected. In the first case the list of devices in the request task is replaced by the devices found in the path analysis, in the second the result of the path analysis is only displayed in a separate window. '); -INSERT INTO txt VALUES ('H5531', 'German', 'Es könne beliebig viele neue Stati angelegt bzw. vorhandene Stati umbenannt, ggf. auch gelöscht werden. Die Namen und Nummern der Stati sind weitgehend frei wählbar. +INSERT INTO txt VALUES ('H5527', 'German', 'Email verschicken: Es kann zwischen verschieden Optionen für den/die direkten Empfänger und Optional für die weiteren Empfänger im CC gewählt werden. + Ausserdem müssen Betreff und Text der Email-Benachrichtigung hier festgelegt werden. +'); +INSERT INTO txt VALUES ('H5527', 'English', 'Send Email: There are different options for the direct recipients and optionally for the recipients in Cc to be chosen. + Furtheron subject and body of the email message have to be defined here. +'); +INSERT INTO txt VALUES ('H5528', 'German', 'Bedingt: Wählt einen Prüfaufruf aus. Fuer "Policy-Prüfung" wird eine Mehrfachauswahl der verfuegbaren Policies angeboten. + Optional kann ein Label gesetzt werden; dann wird dieses mit dem Prüfergebnis "true" oder "false" in den AdditionalInfo der geprüften Request Tasks gespeichert. + Geprüft werden nur die in den Request Tasks des aufrufenden Tickets angeforderten Regeln. Der Status "Falls konform" wird nur verwendet, wenn alle ausgewählten Policies ohne Verstoss prüfen. + Andernfalls wird "Falls nicht konform" verwendet. +'); +INSERT INTO txt VALUES ('H5528', 'English', 'Conditional: Select a check to execute. For "Policy Check", a multiselect of the available policies is shown. + You can optionally set a label; if set, that label is stored with the check result "true" or "false" in the AdditionalInfo of the checked request tasks. + Only the rules requested in the request tasks of the calling ticket are checked. The "If compliant state" target is used only if all selected policies pass without violations. + Otherwise, the "If not compliant state" target is used. +'); +INSERT INTO txt VALUES ('H5531', 'German', 'Es können beliebig viele neue Status angelegt bzw. vorhandene Status umbenannt, ggf. auch gelöscht werden. Die Namen und Nummern der Status sind weitgehend frei wählbar. Zu beachten ist dabei, dass die Nummern zu den in den Status-Matrizen definierten Bereichen (Eingang, Bearbeitung, Ausgang) der jeweiligen Phasen passen. Da intern ausschliesslich die Nummern verarbeitet werden, sind auch doppelt vergebene Status-Namen (technisch) möglich. - Es werden nur Stati zum Löschen angeboten, die in keiner Status-Matrix verwendet werden (auch nicht in deaktivierten Phasen oder Aktionen). + Es werden nur Status zum Löschen angeboten, die in keiner Status-Matrix verwendet werden (auch nicht in deaktivierten Phasen oder Aktionen). '); INSERT INTO txt VALUES ('H5531', 'English', 'An arbitrary number of states can be created, renamed or deleted where appropriate. Names and numbers of the states can be selected freely. But it has to be considered, that the numbers fit into the ranges (Input, Started, Exit) of the phases defined in the state matrices. As internally solely the numbers are processed, duplicates in state names are (technically) possible. Only states are offered for deletion, who are not used in any state matrix (even in deactivated phases or in actions). '); -INSERT INTO txt VALUES ('H5541', 'German', 'In der Status-Matrix werden die verarbeitbaren Stati pro Phase und Tasktyp festgelegt. +INSERT INTO txt VALUES ('H5532', 'German', 'Externe Status: Um interne Status über Aktionen ansprechen zu können, müssen sie vordefinierten, nach aussen sichtbaren Status zugeordnet werden.'); +INSERT INTO txt VALUES ('H5532', 'English', 'External States: To be used by actions, internal states have to be assigned to predefined externally visible states.'); +INSERT INTO txt VALUES ('H5541', 'German', 'In der Status-Matrix werden die verarbeitbaren Status pro Phase und Tasktyp festgelegt. Es gibt eine Master-Matrix, welche die Eigenschaften auf Ticket-Ebene beschreibt, sowie und für jeden Tasktyp separate Matrizen. In der Installation sind diese Matrizen bereits vorbelegt, sie können aber nahezu beliebig überschrieben werden. - Zu beachten ist, dass das Speichern der geänderten Matrizen jeweils als Ganzes durch tätigen der "Speichern"-Schaltfläche erfolgt, einzelne Änderungen der Stati also bei Abbruch verloren gehen. - Jede einzelne Matrix kann auch als Ganzes durch Betätigen der entsprechenden Schaltfläche auf die Initialeinstellungen zurückgesetzt werden. + Zu beachten ist, dass das Speichern der geänderten Matrizen jeweils als Ganzes durch tätigen der "Speichern"-Schaltfläche erfolgt, einzelne Änderungen der Status also bei Abbruch verloren gehen. + Jede einzelne Matrix kann auch als Ganzes durch Betätigen der entsprechenden Schaltfläche auf die Initialeinstellungen zurückgesetzt werden. Während die bereits vorhandenen Matrizen bei Software-Upgrades nicht berührt werden, kann es vorkommen, dass die Initialeinstellungen aktualisiert werden. '); INSERT INTO txt VALUES ('H5541', 'English', 'In the state matrix the usable states per phase and task type are defined. @@ -3796,17 +5949,17 @@ INSERT INTO txt VALUES ('H5541', 'English', 'In the state matrix the usable stat Each matrix can also be reset to the default settings as a whole by using the respective button. As already existing matrices are not touched with software upgrades, it may happen, that the default settings are updated. '); -INSERT INTO txt VALUES ('H5542', 'German', 'Phasen: Die für die Tickets bzw. den jeweiligen Tasktyp vorgesehenen Bearbeitungsphasen können durch setzen der entsprechenden Häkchen in der Status-Matrix festgelegt werden (die Tabelle der Stati klappt dann automatisch ein oder aus). +INSERT INTO txt VALUES ('H5542', 'German', 'Phasen: Die für die Tickets bzw. den jeweiligen Tasktyp vorgesehenen Bearbeitungsphasen können durch setzen der entsprechenden Häkchen in der Status-Matrix festgelegt werden (die Tabelle der Status klappt dann automatisch ein oder aus). Die Phasen Verifizieren und Rezertifizieren sind noch nicht implementiert, so dass eine Aktivierung hier folgenlos bleibt. '); INSERT INTO txt VALUES ('H5542', 'English', 'Phases: The workflow phases provided for the tickets resp. each task type can be defined by setting the check mark in the respective state matrix (the table of used states then appears or disappears automatically). The phases Verify and Recertify are not implemented yet, an activation would have no effect. '); -INSERT INTO txt VALUES ('H5543', 'German', 'Statusübergänge: Für jeden in einer Phase vorkommenden Status muss hier festgelegt werden, in welche Stati von dort beim Speichern gewechselt werden kann. +INSERT INTO txt VALUES ('H5543', 'German', 'Statusübergänge: Für jeden in einer Phase vorkommenden Status muss hier festgelegt werden, in welche Status von dort beim Speichern gewechselt werden kann. Diese werden dann bei den jeweiligen Aktionen in einer Liste angeboten. Ist nur der Übergang zu genau einem Status möglich, so wird dieser Übergang automatisch ohne Rückfrage ausgeführt. (z.B. ist in der Standardkonfiguration nur der Übergang "Requested" -&gt; "In Approval" eingetragen, so dass beim betätigen von "Genehmigung beginnen" automatisch letzterer Status gesetzt wird.) Soll eine Aktion, die ein Speichern bewirkt, auch ohne Statuswechsel stattfinden können, so ist der Ausgangszustand auch in der Liste der Zielzustände aufzunehmen. - Es ist darauf zu achten, dass alle vorkommenden Zielstati der Übergangsmatrizen auch in den Ausgangsstati zu finden sind. + Es ist darauf zu achten, dass alle vorkommenden Zielstatus der Übergangsmatrizen auch in den Ausgangsstatus zu finden sind. '); INSERT INTO txt VALUES ('H5543', 'English', 'State transitions: For each state appearing in a phase it has to be defined, to which states transitions are possible on saving. These states are displayed in a list in the particular actions. If there is only the transition to exactly one state possible, this transition is performed automatically without further dialogue. @@ -3814,12 +5967,12 @@ INSERT INTO txt VALUES ('H5543', 'English', 'State transitions: For each state a If an action leading to a storage should also have the possibility to be performed without state change, the source state has to be added also to the target state list. Make sure that all used target states in all transition matrices also appear in the source states. '); -INSERT INTO txt VALUES ('H5544', 'German', 'Abgeleitete Stati: Bei der Behandlung der abgeleiteten Stati wird unterschieden zwischen der Antragstellung und den anschliessenden Phasen: +INSERT INTO txt VALUES ('H5544', 'German', 'Abgeleitete Status: Bei der Behandlung der abgeleiteten Status wird unterschieden zwischen der Antragstellung und den anschliessenden Phasen: Bei der Antragstellung wird zuerst der Status des Tickets gesetzt. - Die Stati der zugeordneten Aufträgen bekommen zunächst denselben Status wie das Ticket, sofern sie nicht schon in einem höheren Status waren (möglich durch Rückzuweisungen des Tickets z.B. vom Genehmiger). - Die Tasktyp-spezifischen Status-Matrizen legen nun anschliessend aus den abgeleiteten Stati fest, welcher Status dem jeweiligen spezifischen Auftrag zugewiesen wird. Dabei können z.B. auch Phasen übersprungen werden. - In den weiteren Phasen werden die abgeleiteten Stati dann umgekehrt interpretiert: Aus den Stati der Genehmigungen und Implementierungs-Aufträge wird mittels der Tasktyp-spezifischen Status-Matrizen der Status des fachlichen Auftrags ermittelt. - Aus den Stati der fachlichen Aufträge wird dann mittels der Master-Matrix der Status für das Ticket abgeleitet. + Die Status der zugeordneten Aufträgen bekommen zunächst denselben Status wie das Ticket, sofern sie nicht schon in einem höheren Status waren (möglich durch Rückzuweisungen des Tickets z.B. vom Genehmiger). + Die Tasktyp-spezifischen Status-Matrizen legen nun anschliessend aus den abgeleiteten Status fest, welcher Status dem jeweiligen spezifischen Auftrag zugewiesen wird. Dabei können z.B. auch Phasen übersprungen werden. + In den weiteren Phasen werden die abgeleiteten Status dann umgekehrt interpretiert: Aus den Status der Genehmigungen und Implementierungs-Aufträge wird mittels der Tasktyp-spezifischen Status-Matrizen der Status des fachlichen Auftrags ermittelt. + Aus den Status der fachlichen Aufträge wird dann mittels der Master-Matrix der Status für das Ticket abgeleitet. '); INSERT INTO txt VALUES ('H5544', 'English', 'Derived states: Regarding the handling of the derived states, it has to be distinguished between ticket creation and the subsequent phases: On ticket creation, first the state of the ticket is set. @@ -3828,7 +5981,7 @@ INSERT INTO txt VALUES ('H5544', 'English', 'Derived states: Regarding the handl In further phases, the derived states are interpreted the other way round: From the states of approval and implementation tasks the state of the request task is computed via the task type specific state matrix. From the states of the request tasks now the state of the ticket is derived via the master state matrix. '); -INSERT INTO txt VALUES ('H5545', 'German', 'Spezielle Stati: Für jede Phase werden drei Bereiche unterschieden: Eingang, Bearbeitung, Ausgang. Sie werden durch die speziellen Stati markiert:'); +INSERT INTO txt VALUES ('H5545', 'German', 'Spezielle Status: Für jede Phase werden drei Bereiche unterschieden: Eingang, Bearbeitung, Ausgang. Sie werden durch die speziellen Status markiert:'); INSERT INTO txt VALUES ('H5545', 'English', 'Special states: For each phase there are three different ranges to be distinguished: Input, started, exit. They are indicated by special states:'); INSERT INTO txt VALUES ('H5551', 'German', '"Niedrigster Eingangsstatus": Ab diesem Status wird der Auftrag für den Bearbeiter dieser Phase sichtbar.'); INSERT INTO txt VALUES ('H5551', 'English', '"Lowest input state": From this state on the ticket is visible for the actor in the current phase'); @@ -3841,8 +5994,8 @@ INSERT INTO txt VALUES ('H5561', 'English', 'In this chapter general settings fo INSERT INTO txt VALUES ('H5562', 'German', 'Verfügbare Auftragstypen: Es kann ausgewählt werden, welche der technisch vorhandenen Auftragstypen zur Verwendung in den Workflows angeboten werden sollen.'); INSERT INTO txt VALUES ('H5562', 'English', 'Available Task Types: It can be selected, which of the technically available task types should be offered for use in the workflows.'); INSERT INTO txt VALUES ('H5563', 'German', 'Prioritäten und Deadlines: Die vorbelegten 5 Prioritätsstufen für Tickets können hier entsprechend den eigenen Konventionen (um-)benannt werden. - Zu jeder Priorität kann ein eigenes Intervall (in Tagen) für die Ticket- bzw. Genehmigungs-Deadline gesetzt werden, welches dann bei der automatischen Deadline-Erzeugung genutzt wird. - Der Wert 0 bedeutet hierbei, dass keine Deadline gesetzt wird. + Zu jeder Priorität kann ein eigenes Intervall (in Tagen) für die Ticket- bzw. Genehmigungs-Deadline gesetzt werden, welches dann bei der automatischen Deadline-Erzeugung genutzt wird. + Der Wert 0 bedeutet hierbei, dass keine Deadline gesetzt wird. '); INSERT INTO txt VALUES ('H5563', 'English', 'Priorities and Deadlines: The 5 initialized priority levels for tickets can be (re)named according to the own conventions. For each priority an own interval (in days) for ticket and approval deadlines can be set, which is used by the automatic computation of the deadlines. @@ -3853,44 +6006,565 @@ INSERT INTO txt VALUES ('H5564', 'English', 'Allow object search: During definit INSERT INTO txt VALUES ('H5565', 'German', 'Manuelle Eigentümerverwaltung erlauben: Es wird das manuelle Anlegen und Verwalten von Eigentümern durch den Administrator gestattet.'); INSERT INTO txt VALUES ('H5565', 'English', 'Allow manual owner administration: The manual creation and administration of owners can be permitted.'); INSERT INTO txt VALUES ('H5566', 'German', 'Autom. Erzeugen von Implementierungs-Aufträgen: Ist die Planungs-Phase nicht aktiviert, so müssen aus den vorhandenen fachlichen Aufträgen automatisch jeweils ein oder mehrere Implementierungs-Aufträge erzeugt werden. - Dafür kann zwischen folgenden Optionen gewählt werden: + Dafür kann zwischen folgenden Optionen gewählt werden (gilt nur für Auftragstyp "Zugriff"): '); INSERT INTO txt VALUES ('H5566', 'English', 'Auto-create implementation tasks: If the planning phase is not activated, one or more implementation tasks have to be created automatically from the request task. - Therefore the following options can be selected: + Therefore the following options can be selected (only valid for Task Type "access"): '); INSERT INTO txt VALUES ('H5567', 'German', 'Pfadanalyse aktivieren: Dem Planer werden Werkzeuge zur automatischen Pfadanalyse (Prüfung, Erzeugen von Implementierungsaufträgen, Bereinigung) zur Verfügung gestellt.'); INSERT INTO txt VALUES ('H5567', 'English', 'Activate Path Analysis: The planner gets access to tools for automatic path analysis (check, creation of implementation tasks, cleanup).'); +INSERT INTO txt VALUES ('H5568', 'German', 'Eigentümerbasiert: Darstellung der Anträge erfolgt nach Eigentümern. Diese können gegenseitig zugewiesen werden.'); +INSERT INTO txt VALUES ('H5568', 'English', 'Owner based: Display of tickets by owner. They can be assigned to each other.'); +INSERT INTO txt VALUES ('H5569', 'German', 'Compliance-Modul anzeigen: Das Compliance-Modul wird auch für Nutzer in den Workflow-Rollen (requester, approver, planner, implementer, reviewer) dargestellt.'); +INSERT INTO txt VALUES ('H5569', 'English', 'Show Compliance Module: The Compliance module is also displayed for users in the workflow roles (requester, approver, planner, implementer, reviewer).'); +INSERT INTO txt VALUES ('H5570', 'German', 'Eingeschränkte Darstellung: Die Auswahlmöglichkeiten werden für den Nutzer auf ein Minimum reduziert (z.B. keine Ticketdarstellung in der Implementierungsphase).'); +INSERT INTO txt VALUES ('H5570', 'English', 'Reduced view: Selection possibilities for users are reuduced to minimum (e.g. no ticket display in Implementation Phase).'); INSERT INTO txt VALUES ('H5571', 'German', 'Niemals: Es wird kein Implementierungs-Auftrag erzeugt (nur sinnvoll, falls Implementierung und folgende Phasen nicht benötigt werden).'); INSERT INTO txt VALUES ('H5571', 'English', 'Never: No implementation task is created (only reasonable, if implementation and following phases are not needed).'); INSERT INTO txt VALUES ('H5572', 'German', 'Nur eines wenn Gerät vorhanden: Bei mindestens einem vorhandenen Gerät wird das erste der Liste eingetragen - (kann z.B. verwendet werden, wenn es nicht auf das Gerät ankommt, bzw. wenn dies erst später festgelegt werden soll). + (kann z.B. verwendet werden, wenn es nicht auf das Gerät ankommt, bzw. wenn dies erst später festgelegt werden soll). '); INSERT INTO txt VALUES ('H5572', 'English', 'Only one if device available: The first device from the list is taken, if there is any at all (can e.g. be used, if the device choice is not important at this stage or can only be determined later). '); INSERT INTO txt VALUES ('H5573', 'German', 'Für jedes Gerät: Für jedes der bekannten Geräte wird ein eigener Implementierungs-Auftrag angelegt (Vorsicht bei grosser Anzahl angeschlossener Geräte).'); INSERT INTO txt VALUES ('H5573', 'English', 'For each device: For each of the known devices an own implementation task is created (Take care in case of a big number of connected devices).'); -INSERT INTO txt VALUES ('H5574', 'German', 'Gerät im Antrag eingeben: Standardmässig eingestellt: Bereits bei Antragstellung wird ein Pflichtfeld zur Auswahl der betroffenen Geräte eingeblendet, - falls vom Tasktypen benötigt (hier wird also schon dem Antragsteller technisches Wissen abverlangt). +INSERT INTO txt VALUES ('H5574', 'German', 'Gerät im Antrag eingeben: Bereits bei Antragstellung wird ein Pflichtfeld zur Auswahl der betroffenen Geräte eingeblendet, + falls vom Tasktypen benötigt (hier wird also schon dem Antragsteller technisches Wissen abverlangt). Für jedes ausgewählte Gerät wird ein eigener Implementierungs-Auftrag angelegt; bei Auswahl von Alle also für jedes vorhandene Gerät. '); -INSERT INTO txt VALUES ('H5574', 'English', 'Enter device in request: Default value: A mandatory field to select devices is already displayed during request task creation, - if needed in the task type (in this case some technical know-how is presumed from the requester). +INSERT INTO txt VALUES ('H5574', 'English', 'Enter device in request: A mandatory field to select the affected devices is already displayed during request task creation, + if needed in the task type (in this case some technical know-how is presumed from the requester). One implementation task is created for each selected device; if all is selected, one task is created for every existing device. '); INSERT INTO txt VALUES ('H5575', 'German', 'Nach Pfadanalyse: Für jedes bei der automatischen Pfadanalyse gefundene Gerät wird ein eigener Implementierungs-Auftrag angelegt.'); INSERT INTO txt VALUES ('H5575', 'English', 'After path analysis: For each device found in the automatic path analysis an own implementation task is created.'); -INSERT INTO txt VALUES ('H5581', 'German', 'In diesem Abschnitt können die vorhandenen Eigentümer eingesehen und administriert (falls in den Einstellungen aktiviert) werden. +INSERT INTO txt VALUES ('H5576', 'German', 'Erlaubte Änderungen durch Genehmiger: Hier wird festgelegt, welche Ticket- und Auftragsfelder ein Genehmiger in der Genehmigungsphase bearbeiten darf. Felder, die bereits in Implementierungsaufträge kopiert wurden, können danach nicht mehr geändert werden.'); +INSERT INTO txt VALUES ('H5576', 'English', 'Allowed changes by approver: Defines which ticket and task fields an approver may edit during the approval phase. Fields already copied to implementation tasks can no longer be changed afterwards.'); +INSERT INTO txt VALUES ('H5577', 'German', 'Ein Auftrag für alle Geräte: Wie bei Gerät im Antrag eingeben wird die Geräteauswahl bereits im Antrag gepflegt. Der Unterschied ist nur: Falls dort Alle gewählt ist, wird genau ein Implementierungs-Auftrag angelegt statt eines pro vorhandenem Gerät.'); +INSERT INTO txt VALUES ('H5577', 'English', 'One task for all devices: As with Enter device in request, the device selection is already maintained in the request. The only difference is this: if all is selected there, exactly one implementation task is created instead of one per existing device.'); +INSERT INTO txt VALUES ('H5581', 'German', 'In diesem Abschnitt können die vorhandenen Eigentümer eingesehen und administriert (falls in den Einstellungen aktiviert) werden. + Die Eigentümerschaft muss Nutzern entweder direkt oder über Eigentümergruppen zugeordnet werden. Es ist geplant, die Eigentümerschaft mit der Zuständigkeit bei der Antragsstellung zu verknüpfen. '); INSERT INTO txt VALUES ('H5581', 'English', 'In this chapter the existing owners can be displayed and administrated (if activated in the Customizing Settings). + Ownership has to be assigned to users directly or via owner groups. It is planned to connect the ownership with responsiblity on request creation. '); +INSERT INTO txt VALUES ('H5581b', 'German', 'Die Berechtigungen des aktuellen Benutzers für einen Eigentümer werden aus den zugeordneten Verantwortlichen (User-DN oder Gruppen-DN) abgeleitet.'); +INSERT INTO txt VALUES ('H5581b', 'English', 'Owner permissions are derived from the assigned responsible entries of the current user (user DN or group DN) for the selected owner.'); +INSERT INTO txt VALUES ('H5581c', 'German', 'Modellierung erlaubt: Schreibaktionen in der Modellierung (z.B. Anlegen, Bearbeiten, Löschen) sind nur aktiv, wenn mindestens eine passende Verantwortlichkeitsstufe die Modellierung erlaubt und der Benutzer die Modelling-Rolle besitzt.'); +INSERT INTO txt VALUES ('H5581c', 'English', 'Allow modelling: write actions in modelling (e.g. add, edit, delete) are only enabled if at least one matching responsible type allows modelling and the user holds the modelling role.'); +INSERT INTO txt VALUES ('H5581d', 'German', 'Rezertifizierung erlaubt: Die Ausführung der Rezertifizierung ist nur aktiv, wenn mindestens eine passende Verantwortlichkeitsstufe die Rezertifizierung erlaubt und der Benutzer die Rezertifizierungsrolle besitzt.'); +INSERT INTO txt VALUES ('H5581d', 'English', 'Allow recertification: recertification execution is only enabled if at least one matching responsible type allows recertification and the user holds the recertification role.'); +INSERT INTO txt VALUES ('H5581e', 'German', 'Benutzer ohne Schreibberechtigung behalten Lesezugriff auf Eigentümer, Modellierungsansichten und Rezertifizierungsberichte.'); +INSERT INTO txt VALUES ('H5581e', 'English', 'Users without write permission still keep read access to owners, modelling views and recertification reports.'); +INSERT INTO txt VALUES ('H5582', 'German', 'Name: Name der Eigentümers'); +INSERT INTO txt VALUES ('H5582', 'English', 'Name: Owner name'); +INSERT INTO txt VALUES ('H5583', 'German', 'Hauptverantwortlicher (DN): Name und Ldap-Pfad des zugeordneten Nutzers. + Mindestens eines der Felder "Hauptverantwortlicher (DN)" oder "Gruppe" muss gefüllt sein. +'); +INSERT INTO txt VALUES ('H5583', 'English', 'Main responsible person (DN): Name and Ldap path of the associated user. + At least one of the fields "Main responsible person (DN)" or "Group" has to be filled. +'); +INSERT INTO txt VALUES ('H5584', 'German', 'Gruppe: Name und Ldap-Pfad der zugeordneten Nutzergruppe. + Die referenzierte Gruppe muss in den Gruppen-Einstellungen als Eigentümergruppe markiert sein. + Mindestens eines der Felder "Hauptverantwortlicher (DN)" oder "Gruppe" muss gefüllt sein. +'); +INSERT INTO txt VALUES ('H5584', 'English', 'Group: Name and Ldap path of the associated user group. + The referenced group has to be marked as owner group in the Group settings. + At least one of the fields "Main responsible person (DN)" or "Group" has to be filled. +'); +INSERT INTO txt VALUES ('H5585', 'German', 'Mandant: Der Mandant, dem der Eigentümer zugeordnet ist.'); +INSERT INTO txt VALUES ('H5585', 'English', 'Tenant: Tenant to which the owner is assigned to.'); +INSERT INTO txt VALUES ('H5586', 'German', 'Externe Anwendungs-Id: Id eines externen Eigentümers, vorgesehen für importierte Eigentümerschaften.'); +INSERT INTO txt VALUES ('H5586', 'English', 'External Application Id: Id of an external owner, which may be used for imported ownerships.'); +INSERT INTO txt VALUES ('H5587', 'German', 'Rezertintervall (in Tagen): Hier kann das in den Allgemeinen Rezertifizierungseinstellungen gesetzte Rezertifizierungsintervall für den aktuellen Eigentümer überschrieben werden.'); +INSERT INTO txt VALUES ('H5587', 'English', 'Recert Interval (in days): Here the recert interval set in the global recertification settings can be overwritten for the specific owner.'); +INSERT INTO txt VALUES ('H5588', 'German', 'Rezert Check alle: Hier kann das in den Allgemeinen Rezertifizierungseinstellungen gesetzte Rezert-Check-Intervall für den aktuellen Eigentümer überschrieben werden.'); +INSERT INTO txt VALUES ('H5588', 'English', 'Recert Check every: Here the recert check interval set in the global recertification settings can be overwritten for the specific owner.'); +INSERT INTO txt VALUES ('H5589', 'German', 'Regeln: Dem Eigentümer können hier einzelne Regeln, definiert durch Management, Rulebase und Regel-Uid, zugeordnet werden.'); +INSERT INTO txt VALUES ('H5589', 'English', 'Rules: specific rules, defined by management, rulebase and rule Uid, can be assigned to the owner.'); +INSERT INTO txt VALUES ('H5590', 'German', 'IP-Adressen: Dem Eigentümer können hier einzelne IP-Adressen zugeordnet werden.'); +INSERT INTO txt VALUES ('H5590', 'English', 'IP Addresses: IP addresses can be assigned to the owner.'); +INSERT INTO txt VALUES ('H5591', 'German', 'Common Service zugelassen: Modellierern wird erlaubt, hier Common Services anzulegen.'); +INSERT INTO txt VALUES ('H5591', 'English', 'Common Service Possible: Allows modellers to create common services inside.'); +INSERT INTO txt VALUES ('H5591a', 'German', 'Rezertifizierung aktiviert: Der Eigentüer wird über den Firewall Orchestrator rezertifiziert.'); +INSERT INTO txt VALUES ('H5591a', 'English', 'Recertification activated: This owner is to be recertified via Firewall Orchestrator.'); +INSERT INTO txt VALUES ('H5592', 'German', 'Importquelle: Falls importiert das dort vergebene Label (sh. Modellierungseinstellungen).'); +INSERT INTO txt VALUES ('H5592', 'English', 'Import Source: If imported the label given there (see Modelling Settings).'); +INSERT INTO txt VALUES ('H5593', 'German', 'URL des externen Ticketing Systems: Exakte Adresse inklusive Pfad, unter der die API das externen Ticket Systems erreicht werden kann.'); +INSERT INTO txt VALUES ('H5593', 'English', 'URL of external ticketing system: Exact address and path under which the external ticket system''s API can be reached.'); +INSERT INTO txt VALUES ('H5593a', 'German', 'Antwort Timeout (Sekunden): Gibt an in Sekunden, wie lange maximal auf eine Antwort des externen Systems gewartet wird.'); +INSERT INTO txt VALUES ('H5593a', 'English','Response Timeout (Seconds): Defines in seconds, how long should be waited for a response of the external system.'); +INSERT INTO txt VALUES ('H5593b', 'German', 'Max Versuche: Maximale Anzahl der Versuche, bevor das Ticket zurückgewiesen wird.'); +INSERT INTO txt VALUES ('H5593b', 'English','Max Attempts: Maximal attempts until the ticket is rejected.'); +INSERT INTO txt VALUES ('H5593c', 'German', 'Zyklen zwischen Versuchen: Zyklen zwischen zwei Sendeversuchen. Wird mit der Anzahl der Versuche multipliziert, um den Abstand mit der Zeit zu vergrössern.'); +INSERT INTO txt VALUES ('H5593c', 'English','Cycles between attempts: Cycles between two sending attempts. Will be multiplied with attempt count to enlarge interval with time.'); +INSERT INTO txt VALUES ('H5594', 'German', 'Authorization-Header-String: Beispielsweise Base64-kodierter String von "Username:Password" mit führendem "Basic" zur Bezeichnung der Basic Authentication'); +INSERT INTO txt VALUES ('H5594', 'English', 'Authorization header string: E.g. base64 encoded string of "Username:Password" lead by "Basic" to indicate basic authentication'); +INSERT INTO txt VALUES ('H5595', 'German', 'Template Ticket-Text: Vorlagentext mit verschiedenen Platzhaltern, die durch @@PLACEHOLDER@@ gekennzeichnet sind und für jede Anfrage durch die eigentlichen Anfragedaten ersetzt werden. + Verfügbare Platzhalter: @@TICKET_SUBJECT@@, @@PRIORITY@@, @@ONBEHALF@@, @@TASKS@@, @@REASON@@, @@APPID@@. +'); +INSERT INTO txt VALUES ('H5595', 'English', 'Template ticket text: template text containing various placeholders indicated by @@PLACEHOLDER@@ which will be substituted for each ticket with the actual ticket data. + Available placeholders: @@TICKET_SUBJECT@@, @@PRIORITY@@, @@ONBEHALF@@, @@TASKS@@, @@REASON@@, @@APPID@@. +'); +INSERT INTO txt VALUES ('H5596', 'German', 'Template Aufgabentext: Template pro Aufgabe (Verbindung/Netzwerkobjekt). Verfügbare Platzhalter: + Verbindung: @@ORDERNAME@@, @@SOURCES@@, @@SERVICES@@, @@DESTINATIONS@@, @@TASKCOMMENT@@, @@ACTION@@. + Netzwerkobjekt: @@GROUPNAME@@, @@MANAGEMENT_ID@@, @@MANAGEMENT_NAME@@, @@CHANGEACTION@@, @@MEMBERS@@. +'); +INSERT INTO txt VALUES ('H5596', 'English', 'Template task text: Template for each task (connection/network object). Available placeholders: + Connection: @@ORDERNAME@@, @@SOURCES@@, @@SERVICES@@, @@DESTINATIONS@@, @@TASKCOMMENT@@, @@ACTION@@. + Network object: @@GROUPNAME@@, @@MANAGEMENT_ID@@, @@MANAGEMENT_NAME@@, @@CHANGEACTION@@, @@MEMBERS@@. +'); +INSERT INTO txt VALUES ('H5596a', 'German', 'Template Objekt (neu): Template pro neu anzulegendem Objekt. Verfügbare Platzhalter: @@TYPE@@, @@OBJECTNAME@@, @@OBJECT_TYPE@@, @@OBJECT_DETAILS@@, @@COMMENT@@, @@STATUS@@, @@OBJUPDSTATUS@@, @@MANAGEMENT_ID@@.'); +INSERT INTO txt VALUES ('H5596a', 'English','Template object (new): Template for new created object. Available placeholders: @@TYPE@@, @@OBJECTNAME@@, @@OBJECT_TYPE@@, @@OBJECT_DETAILS@@, @@COMMENT@@, @@STATUS@@, @@OBJUPDSTATUS@@, @@MANAGEMENT_ID@@.'); +INSERT INTO txt VALUES ('H5596b', 'German', 'Template Objekt kurz (Änderung): Template pro zu änderndem Object. Verfügbare Platzhalter: @@OBJECTNAME@@, @@STATUS@@, @@OBJUPDSTATUS@@, @@MANAGEMENT_ID@@.'); +INSERT INTO txt VALUES ('H5596b', 'English','Template object short (modification): Template for object to be modified. Available placeholders: @@OBJECTNAME@@, @@STATUS@@, @@OBJUPDSTATUS@@, @@MANAGEMENT_ID@@.'); +INSERT INTO txt VALUES ('H5596c', 'German', 'Template IP Adresse: Template pro IP-Adress-Objekt. Verfügbare Platzhalter: @@IP@@.'); +INSERT INTO txt VALUES ('H5596c', 'English','Template IP address: Template for IP address object. Available placeholders: @@IP@@.'); +INSERT INTO txt VALUES ('H5596d', 'German', 'Template Netzwerkgruppe: Template pro Netzwerkgruppe. Verfügbare Platzhalter: @@GROUPNAME@@, @@MANAGEMENT_ID@@, @@MANAGEMENT_NAME@@.'); +INSERT INTO txt VALUES ('H5596d', 'English','Template network group: Template for network group. Available placeholders: @@GROUPNAME@@, @@MANAGEMENT_ID@@, @@MANAGEMENT_NAME@@.'); +INSERT INTO txt VALUES ('H5596e', 'German', 'Template Dienst: Template pro Dienst. Verfügbare Platzhalter: @@PROTOCOLNAME@@, @@PORT@@, @@SERVICENAME@@.'); +INSERT INTO txt VALUES ('H5596e', 'English','Template service: Template for service. Available placeholders: @@PROTOCOLNAME@@, @@PORT@@, @@SERVICENAME@@.'); +INSERT INTO txt VALUES ('H5596f', 'German', 'Template ICMP: spezielles Template für den Protokolltyp ICMP. Verfügbare Platzhalter: @@SERVICENAME@@.'); +INSERT INTO txt VALUES ('H5596f', 'English','Template ICMP: Special template for protocol type ICMP. Available placeholders: @@SERVICENAME@@.'); +INSERT INTO txt VALUES ('H5596g', 'German', 'Template Ip-Protokoll: Template für alle Protokolltypen ausser TCP, UDP, ICMP, z.B. ESP. Verfügbare Platzhalter: @@PROTOCOLNAME@@, @@PROTOCOLID@@, @@SERVICENAME@@.'); +INSERT INTO txt VALUES ('H5596g', 'English','Template Ip-Protokoll: Template for protocol types not TCP, UDP, ICMP, e.g. ESP. Available placeholders: @@PROTOCOLNAME@@, @@PROTOCOLID@@, @@SERVICENAME@@.'); +INSERT INTO txt VALUES ('H5597', 'German', 'Typ des externen Ticketing Systems: Aktuell wird nur TufinSecureChange unterstützt.'); +INSERT INTO txt VALUES ('H5597', 'English', 'Type of external ticketing system: Currently only TufinSecureChange is supported.'); +INSERT INTO txt VALUES ('H5598', 'German', 'Hier werden die Einstellungen für die Anbindung an externe Ticket-Systeme verwaltet.'); +INSERT INTO txt VALUES ('H5598', 'English', 'On this page the settings for the connection to external ticket systems are administrated.'); +INSERT INTO txt VALUES ('H5599', 'German', 'Tasktyp: Typ des Tasks im externen Auftragssystem.'); +INSERT INTO txt VALUES ('H5599', 'English', 'Task Type: Type of the task in the external ticket system.'); + +INSERT INTO txt VALUES ('H5601', 'German', 'Hier werden die Einstellungen für die Netzwerk-Modellierung verwaltet. + Dies betrifft Vordefinierte Dienste, Darstellung verschiedener Elemente, Definition von Namenskonventionen sowie Scheduling-Einstellungen für die zu importierenden Objekte: +'); +INSERT INTO txt VALUES ('H5601', 'English', 'On this page all types of modelling settings are administrated. + This includes Predefined Services, Display options of different elements, definition of naming conventions as well as scheduling settings for the objects to be imported: +'); +INSERT INTO txt VALUES ('H5602', 'German', 'Vordefinierte Dienste: Hier wird dem Administrator ein Menü angeboten, um Dienste und Gruppierungen von Diensten vorzudefinieren, + zu bearbeiten oder zu löschen. Diese stehen dann allen Applikationen zur Verfügung. +'); +INSERT INTO txt VALUES ('H5602', 'English', 'Predefined Services: Offers a menu to the administrator to define, change or delete predefined services or service groups. + These services are available for all applications. +'); +INSERT INTO txt VALUES ('H5603', 'German', 'Server in Verbindung erlauben: Steuert, ob in der Bibliothek neben den App Rollen auch App Server zur direkten Verwendung in den Verbindungen angeboten werden.'); +INSERT INTO txt VALUES ('H5603', 'English', 'Allow Servers in Connection: Controls, if App Servers are offered in the Library besides the App Roles for direct use in the connections.'); +INSERT INTO txt VALUES ('H5604', 'German', 'Einfache Dienste in Verbindung erlauben: Steuert, ob in der Bibliothek neben den Servicegruppen auch einfache Services zur direkten Verwendung in den Verbindungen angeboten werden.'); +INSERT INTO txt VALUES ('H5604', 'English', 'Allow Simple Services in Connection: Controls, if simple Services are offered in the Library besides the Service Groups for direct use in the connections.'); +INSERT INTO txt VALUES ('H5605', 'German', 'Max. Anzahl Zeilen in Übersicht: Definiert die Zeilenzahl innerhalb eines Eintrags in der Übersichtstabelle der Verbindungen, ab der die Elemente eingeklappt dargestellt werden. + Wird vom Administrator allgemein vorausgewählt, kann aber vom Nutzer in den persönlichen Einstellungen überschrieben werden. +'); +INSERT INTO txt VALUES ('H5605', 'English', 'Max. Number of Rows in Overview: Defines the number of rows inside an entry of the connections overview table, from which the elements are displayed retracted. + Generally set by the administrator but can be overwritten in the personal settings of the user. +'); +INSERT INTO txt VALUES ('H5606', 'German', 'Netzwerkarea vorgeschrieben: Wenn dieses Flag gesetzt ist, müssen die auszuwählenden App Server einer festen Area zugeordnet sein. + Es werden dann beim Zusammenstellen einer App Rolle in der Bibliothek nur die der aktuell ausgewählten Area zugehörigen App Server angeboten. + Für die Namensgebung der App Rolle wird dann die in den folgenden Punkten definierte Namenskonvention angewendet. +'); +INSERT INTO txt VALUES ('H5606', 'English', 'Network Area Required: If this flag is set, the App Servers used have to be associated to a fixed area. + When defining an App Role, only the App Servers belonging to the selected area are displayed in the library. + Naming of the App Role is then restricted to the naming convention defined in the following settings. +'); +INSERT INTO txt VALUES ('H5607', 'German', 'Länge fixer Teil: Länge des vorgebenen Teils des Namensmusters einer App Rolle (ohne den ggf. vorhandenen Eigentümerteil variabler Länge).'); +INSERT INTO txt VALUES ('H5607', 'English', 'Fixed Part Length: Length of the predefined part of the name pattern of an App Role (without the owner part of variable length if activated).'); +INSERT INTO txt VALUES ('H5608', 'German', 'Länge freier Teil: Länge des frei zu vergebenden Teils des Namens einer App Rolle (nur für den Namensvorschlag beim Neuanlegen relevant).'); +INSERT INTO txt VALUES ('H5608', 'English', 'Free Part Length: Length of the free part of the name pattern of an App Role (only relevant for name proposal during creation).'); +INSERT INTO txt VALUES ('H5609', 'German', 'Muster Netzwerkarea: Definiert, wie der Name einer Netzwerkarea beginnt (z.B "NA").'); +INSERT INTO txt VALUES ('H5609', 'English', 'Network Area Pattern: Defines the beginning of a network area name (e.g. "NA").'); +INSERT INTO txt VALUES ('H5610', 'German', 'Muster App Rolle: Definiert, wie der Name einer App Rolle beginnt (z.B. "AR"). + Zu einer Netzwerkarea (z.B. "NAxx") wird dann ein Name der App Rolle (z.B. "ARxx") mit der oben definierten Länge des fixen Teils vorgegeben. + Ist die Länge des Musters grösser als die Länge des fixen Teils, wird der überschüssige Teil nicht berücksichtigt. +'); +INSERT INTO txt VALUES ('H5610', 'English', 'App Role Pattern: Defines the beginning of an App Role name (e.g. "AR"). + According to an network area name (e.g. "NAxx"), an App Role name (e.g. "ARxx") is preset in the length of the fixed part defined above. + If the length of the pattern is greater than the fixed part length, the surplus part is ignored. +'); +INSERT INTO txt VALUES ('H5611', 'German', 'Pfad und Name von Appdaten-Import (ohne Endung): Hier werden die vollständigen Pfade für eventuell vorhandene Importskripte und -dateien eingegeben. + Der Importprozess prüft für jede der eingegebenen Datenquellen zunächst, ob ein Skript dieses Namens mit der Endung .py vorhanden ist, und führt dieses ggf. aus. + Anschliessend wird eine Datei desselben Namens mit der Endung .json gesucht und ggf. importiert. + Es gibt für den Import pro Datenquelle also sowohl die Möglichkeit, eine direkt zu importierende Datei zur Verfügung zu stellen, als auch ein Skript zur Datenabholung, + welches die benötigte Import-Datei erst erzeugt. Die Struktur der Importdatei wird unter Import-Schnittstellen beschrieben. +'); +INSERT INTO txt VALUES ('H5611', 'English', 'Path and Name of App data import (without ending): Here the full paths of provided import scripts and files are inserted. + The import process checks for each data source, if a script of this name with ending .py exists and executes it. + Then a file of this name with ending .json is searched and imported if found. + Thus there is the possibility for each data source to provide a file for direct import or a script to catch the import data and create the app data import file. + The structure of the import file is described at Import Interfaces. +'); +INSERT INTO txt VALUES ('H5611a', 'German', 'Skriptparameter (optional): Zusätzliche Parameter, die an das Appdaten-Importskript übergeben werden, z.B. "-f foldername".'); +INSERT INTO txt VALUES ('H5611a', 'English', 'Script parameters (optional): Additional parameters passed to the app data import script, e.g. "-f foldername".'); +INSERT INTO txt VALUES ('H5612', 'German', 'Import Appdaten-Intervall (in Stunden): Zeitintervall zwischen zwei Appdaten-Import-Läufen. + Ein Wert 0 bedeutet, dass der Appdaten-Import deaktiviert ist. Default-Wert = 0. +'); +INSERT INTO txt VALUES ('H5612', 'English', 'Import App data sleep time (in hours): Time between App data import loops. + A value 0 means, that the App data import is deactivated. Default value = 0. +'); +INSERT INTO txt VALUES ('H5613', 'German', 'Import Appdaten-Start: Legt eine Bezugszeit fest, ab dem die Intervalle für die Appdaten-Importe gerechnet werden.'); +INSERT INTO txt VALUES ('H5613', 'English', 'Import App data start at: Defines a referential time from which the App data import intervals are calculated.'); +INSERT INTO txt VALUES ('H5614', 'German', 'Pfad und Name von Subnetzdaten-Import (ohne Endung): Hier wird der vollständige Pfad für ein eventuell vorhandenes Importskript oder einer Import-Datei eingegeben. + Der Importprozess prüft zunächst, ob ein Skript dieses Namens mit der Endung .py vorhanden ist, und führt dieses ggf. aus. Anschliessend wird eine Datei desselben Namens mit der Endung .json + gesucht und ggf. importiert. Es gibt für den Import also sowohl die Möglichkeit, eine direkt zu importierende Datei zur Verfügung zu stellen, als auch ein Skript zur Datenabholung, + welches die benötigte Import-Datei erst erzeugt. Die Struktur der Importdatei wird unter Import-Schnittstellen beschrieben. +'); +INSERT INTO txt VALUES ('H5614', 'English', 'Path and Name of subnet data import (without ending): Here the full path of a provided import script or file is inserted. + The import process checks, if a script of this name with ending .py exists and executes it. + Then a file of this name with ending .json is searched and imported if found. + Thus there is the possibility to provide a file for direct import or a script to catch the import data and create the subnet data import file. + The structure of the import file is described at Import Interfaces. +'); +INSERT INTO txt VALUES ('H5615', 'German', 'Import Subnetzdaten-Intervall (in Stunden): Zeitintervall zwischen zwei Subnetzdaten-Import-Läufen. + Ein Wert 0 bedeutet, dass der Subnetzdaten-Import deaktiviert ist. Default-Wert = 0. +'); +INSERT INTO txt VALUES ('H5615', 'English', 'Import Subnet data sleep time (in hours): Time between Subnet data import loops. + A value 0 means, that the Subnet data import is deactivated. Default value = 0. +'); +INSERT INTO txt VALUES ('H5616', 'German', 'Import Subnetzdaten-Start: Legt eine Bezugszeit fest, ab dem die Intervalle für die Subnetzdaten-Importe gerechnet werden.'); +INSERT INTO txt VALUES ('H5616', 'English', 'Import Subnet data start at: Import App data start at: Defines a referential time from which the Subnet data import intervals are calculated.'); +INSERT INTO txt VALUES ('H5617', 'German', 'Reduzierten Protokollset darstellen: Nur eine begrenzte Zahl von Protokollen wird zur Auswahl angeboten (TCP, UDP, ICMP).'); +INSERT INTO txt VALUES ('H5617', 'English', 'Display reduced Protocol set: Offer only a reduced number of protocols for selection (TCP, UDP, ICMP).'); +INSERT INTO txt VALUES ('H5618', 'German', 'Nutzung von Piktogrammen: Vorzugsweise Nutzung von Piktogrammen wo sinnvoll. Wird vom Administrator allgemein vorausgewählt, kann aber vom Nutzer in den persönlichen Einstellungen überschrieben werden.'); +INSERT INTO txt VALUES ('H5618', 'English', 'Prefer use of Icons: Use icons where reasonnable. Generally set by the administrator but can be overwritten in the personal settings of the user.'); +INSERT INTO txt VALUES ('H5619', 'German', 'Eigentümernamen verwenden: Der Name des Eigentümers fliesst in den mittleren Teil der Namenskonvention für App-Rollen ein.'); +INSERT INTO txt VALUES ('H5619', 'English', 'Use Owner Name: The name of the owner is used in the middle part of the naming convention for App Roles.'); +INSERT INTO txt VALUES ('H5620', 'German', 'Gemeinsame Netzwerkareas: Vom Administrator vorgegebene Netzwerkareas, welche von allen Verbindungen genutzt werden dürfen. + Sie sind in der Bibliothek immer sichtbar und stehen dann nicht mehr in der Liste der auszuwählenden Areas für Common Services. + Die beiden Auswahlfelder "in Quelle" und "in Ziel" legen fest, wo die Netzwerkarea genutzt werden darf. +'); +INSERT INTO txt VALUES ('H5620', 'English', 'Common Network Areas: Network areas defined by the administrator, which are permitted to be used by all connections. + They are visible in the object library and are not offered in the list of available areas for Common Services. + The flags "in Source" and "in Destination" determine, where the Common Network Areas are allowed to be used. +'); +INSERT INTO txt VALUES ('H5621', 'German', 'Ein Modellierer kann einige persönliche Voreinstellungen für die Darstellung der Modellierung überschreiben. + Ausgangswert ist der vom Admin in den Modellierungseinstellungen gesetzte Wert. +'); +INSERT INTO txt VALUES ('H5621', 'English', 'A modeller can overwrite some personal settings for the modelling layout. + The default value is set by the admin in the Modelling Settings. +'); +INSERT INTO txt VALUES ('H5622', 'German', 'Name der beantragten Schnittstelle: Namensvorschlag bei der Beantragung einer Schnittstelle. Kann vom Antragsteller noch geändert werden.'); +INSERT INTO txt VALUES ('H5622', 'English', 'Name of requested interface: Proposed name of the requested interface. Can be changed by the requester.'); +INSERT INTO txt VALUES ('H5623', 'German', 'Titel der Antragsbenachrichtigung: Betreff der Email-Benachrichtigung an die Beauftragten.'); +INSERT INTO txt VALUES ('H5623', 'English', 'Subject of request emails: Subject of the email to the addressed owners.'); +INSERT INTO txt VALUES ('H5624', 'German', 'Text der Antragsbenachrichtigung: Text der Email-Benachrichtigung an die Beauftragten. Wird noch durch Antragsteller (zu Beginn) und Beauftragtem (am Ende) ergänzt. + Hinzu kommt noch jeweils ein Link auf den Auftrag im Workflowmodul und auf die beauftragte Schnittstelle im Modellierungsmodul. +'); +INSERT INTO txt VALUES ('H5624', 'English', 'Body of request emails: Text of the email notification to the addressed owners. Will be appended by the requester (at the beginning) and the addressed owner (at the end). + Additionally links to the request in the Workflow module and the requested interface in the Modelling module are added. +'); +INSERT INTO txt VALUES ('H5624a', 'German', 'Text der Erinnerungsbenachrichtigung: Text der Email-Benachrichtigung an die Beauftragten. Verfügbare Platzhalter: + @@APPNAME@@, @@APPID@@, @@REQUESTER@@, @@REQUESTDATE@@, @@REQUESTING_APPNAME@@, @@REQUESTING_APPID@@, @@INTERFACE_LINK@@. +'); +INSERT INTO txt VALUES ('H5624a', 'English', 'Body of unanswered request emails: Text of the email notification to the addressed owners. Available placeholders: + @@APPNAME@@, @@APPID@@, @@REQUESTER@@, @@REQUESTDATE@@, @@REQUESTING_APPNAME@@, @@REQUESTING_APPID@@, @@INTERFACE_LINK@@. +'); +INSERT INTO txt VALUES ('H5625', 'German', 'Titel des Schnittstellentickets: Titel, mit dem ein neues Ticket zur Beantragung einer Schnittstelle angelegt wird.'); +INSERT INTO txt VALUES ('H5625', 'English', 'Title of interface request ticket: Title used for the new interface request ticket.'); +INSERT INTO txt VALUES ('H5626', 'German', 'Titel des Schnittstellenauftrags: Titel, mit dem ein neuer Auftrag im Ticket zur Beantragung einer Schnittstelle angelegt wird.'); +INSERT INTO txt VALUES ('H5626', 'English', 'Title of interface request ticket: Title used for the Task in the new interface request ticket.'); +INSERT INTO txt VALUES ('H5627', 'German', 'App-Server-Typen: Hier können beliebige App-Server-Typen mit Namen und Id definiert werden. Bitte jeweils neue Id vergeben. Vorsicht beim Löschen bereits verwendeter Typen! + Der Standard-typ ist immer vorhanden und wird beim Datenimport verwendet. Hier kann nur der dargestellte Name gesetzt werden. Zur manuellen Zuweisung zu einem App-Server kann er nicht verwendet werden. +'); +INSERT INTO txt VALUES ('H5627', 'English', 'App Server Types: Here any App Server Types can be defined with name and Id. Please use different Ids. Be careful when deleting types already in use! + The default type should always exist and is used during data import. Here only the displayed name can be chosen. It is not available for manual assignment to an App Server. +'); +INSERT INTO txt VALUES ('H5628', 'German', 'Vordefinierte Dienste: Hier wird dem Administrator ein Menü angeboten, um Dienste und Gruppierungen von Diensten vorzudefinieren, + zu bearbeiten oder zu löschen. Diese stehen dann allen Applikationen zur Verfügung. +'); +INSERT INTO txt VALUES ('H5628', 'English', 'Predefined Services: Offers a menu to the administrator to define, change or delete predefined services or service groups. + These services are available for all applications. +'); +INSERT INTO txt VALUES ('H5629', 'German', 'Erinnerungsbenachrichtigungen: Legt fest, wer wie oft in welchem Zeitintervall über offene Schnittstellenanträge benachrichtigt wird.'); +INSERT INTO txt VALUES ('H5629', 'English', 'Reminders: Defines who will be notified how often and in which time interval about open interface requests.'); +INSERT INTO txt VALUES ('H5630', 'German', 'Empfänger der Antragsbenachrichtigung: Mehrfachauswahl, an wen die Email geschickt werden soll. + Verfügbare Optionen sind Keine, Andere Adressen, die Option "Mindestens eine Email-Benachrichtigung sicherstellen" und alle aktiven Verantwortlichkeitsstufen. + Ist "Keine" gesetzt, sind alle anderen Optionen deaktiviert. Wenn "Mindestens eine Email-Benachrichtigung sicherstellen" aktiv ist, werden zuerst die ausgewählten Optionen verwendet. Nur falls daraus keine Empfänger entstehen, werden nicht ausgewählte Verantwortlichkeitsstufen von hoher zu niedriger Sortierreihenfolge durchsucht, bis eine Stufe mit Empfängern gefunden wird. + Zusätzlich kann festgelegt werden, ob der Antragsteller die Nachricht im Cc bekommen soll (Default: ja). +'); +INSERT INTO txt VALUES ('H5630', 'English', 'Receiver of request emails: Multi-select list defining who receives the request notification email. + Available options are None, Other addresses, the option "Ensure at least one email notification can be sent", and all active responsible levels. + If "None" is selected, all other options are disabled. If "Ensure at least one email notification can be sent" is active, selected options are used first. Only if they yield no recipients, non-selected responsible levels are checked from highest to lowest sort order until a level with recipients is found. + It can also be configured whether the requester receives the email in Cc (default: yes). +'); +INSERT INTO txt VALUES ('H5631', 'German', 'Servicegruppen auflösen: Ersetze beim Erzeugen eines externen Auftrags die Servicegruppen durch die einzelnen Mitglieder.'); +INSERT INTO txt VALUES ('H5631', 'English', 'Resolve service groups: Replace service groups by its members when creating an external request.'); +INSERT INTO txt VALUES ('H5632', 'German', 'Tasks zusammenfassen: Fasse gleichartige Tasks in einem externen Auftrag zusammen.'); +INSERT INTO txt VALUES ('H5632', 'English', 'Bundle tasks: Bundle tasks of same type in one external request.'); +INSERT INTO txt VALUES ('H5633', 'German', 'App Server Namenspräfix: Falls der Name nicht schon anderweitig vorbelegt ist, wird er aus Namenspräfix + Ip-Adresse zusammengesetzt.'); +INSERT INTO txt VALUES ('H5633', 'English', 'App Server Name Prefix: If not already filled, the App Server Name will be constructed by Name Prefix + Ip address.'); +INSERT INTO txt VALUES ('H5634', 'German', 'Automatische Firewallbeantragung aktivieren: Aktiviert den Button zum Workflow zur automatischen Firewallbeantragung.'); +INSERT INTO txt VALUES ('H5634', 'English', 'Activate automatic Firewall request: Activates the button to the workflow for automatic firewall requests.'); +INSERT INTO txt VALUES ('H5635', 'German', 'Muster App Zone: Definiert, wie der Name einer App Zone beginnt (z.B. "AZ").'); +INSERT INTO txt VALUES ('H5635', 'English', 'App zone pattern: Defines how the name of an app zone begins (e.g. "AZ").'); +INSERT INTO txt VALUES ('H5636', 'German', 'App Zonen erstellen: Wenn dieses Flag gesetzt wird, werden App Zonen erstellt.'); +INSERT INTO txt VALUES ('H5636', 'English', 'Create app zones: If this flag is set, app zones are created.'); +INSERT INTO txt VALUES ('H5637', 'German', 'Hier werden die möglichen Werte für Sonderkonfigurationstypen gesetzt, z.B. NAT. Ein Präfix "Doku_" (welches in der Benutzeroberfläche nicht dargestellt wird) bewirkt die Markierung einer Verbindung als nur zu Dokumentationszwecken. + Sie wird dann bei der Beantragung und dem Soll-Ist-Abgleich nicht berücksichtigt. Endet der Feldinhalt mit dem String "_user" oder "-user" (Case-insensitiv), so wird in den Produktionsdaten mindestens ein Objekt mit dem im zugehörigen Text angegebenen Namen erwartet. + Diesem werden dann alle (mindestens eines) nicht anderweitig zuzuordnenden modellierten Objekte aus der Spezielle-Nutzer-Liste als enthalten angenommen. +'); +INSERT INTO txt VALUES ('H5637', 'English', 'Set here the possible values for extra configuration types, e.g. NAT. A prefix "Doku_" (which is then not displayed in the UI) leads to marking the connection as for documentation only. + It will not be regarded in the requesting process and Variance Analysis. If the field content ends with "_user" or "-user"(case insensitive), an object with the name given in the extra configuration text is expected to be found in the production data. + This object is assumed to contain all modelled objects (at least one) from the special user list, which could not be matched so far. +'); +INSERT INTO txt VALUES ('H5638', 'German', 'Hier wird der Anweisungstext für Sonderkonfigurationen eingetragen.'); +INSERT INTO txt VALUES ('H5638', 'English', 'Insert text for extra configurations.'); +INSERT INTO txt VALUES ('H5639', 'German', 'Hier wird der Meldungstext für Fehler im externen Beantragungsprozess eingetragen.'); +INSERT INTO txt VALUES ('H5639', 'English', 'Insert customized text for errors in requests to external ticket system.'); +INSERT INTO txt VALUES ('H5643', 'German', 'DNS-Suche: Wenn gesetzt, werden App-Server-Namen aus dem DNS ergänzt und sind nicht manuell editierbar. Falls kein Name aufgelöst werden kann, wird er aus Präfix und IP-Adresse konstruiert.'); +INSERT INTO txt VALUES ('H5643', 'English', 'DNS Look-up: When set, App Server names are resolved from DNS and are not manually editable. If no name can be resolved, it is constructed from prefix and IP address.'); +INSERT INTO txt VALUES ('H5644', 'German', 'Existierende Namen überschreiben: Wenn gesetzt, werden bereits existierende Namen auch überschrieben, wenn sie nicht im DNS aufgelöst werden können.'); +INSERT INTO txt VALUES ('H5644', 'English', 'Overwrite Existing Names: When set, existing App Server names are overwritten, even if they cannot be resolved from DNS.'); +INSERT INTO txt VALUES ('H5645', 'German', 'Namenspräfix IP-Netzwerk: Der Name der IP-Netzwerke wird aus diesem Namenspräfix + Ip-Netzwerkadresse zusammengesetzt.'); +INSERT INTO txt VALUES ('H5645', 'English', 'Network Name Prefix: The name of IP networks will be constructed by this prefix + network address.'); +INSERT INTO txt VALUES ('H5646', 'German', 'Namenspräfix IP-Bereich: Der Name der IP-Bereiche wird aus diesem Namenspräfix + Ip-Bereich zusammengesetzt.'); +INSERT INTO txt VALUES ('H5646', 'English', 'IP Range Name Prefix: The name of IP ranges will be constructed by this prefix + Ip address range.'); +INSERT INTO txt VALUES ('H5647', 'German', 'App Server umhängen: Neu angelegte oder reaktivierte App Server ersetzen vorher vorhandene gleichen Namens auch in App Rollen und Verbindungen/Schnittstellen.'); +INSERT INTO txt VALUES ('H5647', 'English', 'Replace App Servers: New or reactivated App Servers replace existing ones of same name also in App Roles and Connections/Interfaces.'); +INSERT INTO txt VALUES ('H5648', 'German', 'Markierung Modelliert: Gibt eine Zeichenfolge an, nach der in einer Regel der Verweis auf die modellierte Verbindung gesetzt wird (default:"FWOC", z.B. "FWOC123" verweist auf Verbindung 123).'); +INSERT INTO txt VALUES ('H5648', 'English', 'Modelled marker: Defines a pattern mark a to reference to the modelled connection (default:"FWOC", e.g. "FWOC123" references to connection 123).'); +INSERT INTO txt VALUES ('H5649', 'German', 'Ort Markierung: Gibt an, in welchem Feld der Regel die Markierung erfolgen soll (rulename/comment/customfields, default:"rulename").'); +INSERT INTO txt VALUES ('H5649', 'English', 'Marker Location: Defines the data field in the rule, where this reference should be placed (rulename/comment/customfields, default:"rulename").'); +INSERT INTO txt VALUES ('H5650', 'German', 'Regelerkennungs-Optionen: Legt fest, wann implementierte Regeln als identisch zu den modellierten Verbindungen angesehen werden. + Mögliche Kriterien sind - jeweils für Netzwerkobjekte und Dienste - Name, IP-Adresse bzw Port/Protokoll, Gruppennname. + Ausserdem muss festgelegt werden, ob Gruppen aufgelöst werden sollen; dann werden die einzelnen Objekte unabhängig von der Gruppenzugehörigkeit erkannt. +'); +INSERT INTO txt VALUES ('H5650', 'English', 'Rule Recognition Options: Defines, when implemented rules are regarded as identical to the modelled connections. + Possible criteria are - separated for network objects and services - Name, IP address resp. Port/Protocol, Group Name. + Additionally it has to be defined, if groups are resolved; then single objects are identified independently from their group membership. +'); +INSERT INTO txt VALUES ('H5651', 'German', 'Synchroner Soll-Ist-Abgleich: Wenn aktiviert, werden die Status der Verbindungen sofort bei Initialisierung der Seite berechnet. + Da dies bei grösseren Systemen zu erheblichem Rechenaufwand führt, kann dies zu einer verzögerten Darstellung führen. + In diesem Fall wird die Nutzung des asynchronen Soll-Ist-Abgleichs empfohlen. +'); +INSERT INTO txt VALUES ('H5651', 'English', 'Synchroneous Variance Analysis: If activated all states of the connections are calculated on page initialization. + As this implies a considerable calculation effort, this may lead to a delayed display for bigger systems. + In this case the usage of the asynchroneous Variance Analysis is recommended. +'); +INSERT INTO txt VALUES ('H5652', 'German', 'Soll-Ist-Abgleich-Intervall (in Minuten): Zeitintervall zwischen zwei Soll-Ist-Abgleich-Läufen. + Dort werden asynchron die Status zur Darstellung in der Oberfläche berechnet. + Ein Wert 0 bedeutet, dass der asynchrone Soll-Ist-Abgleich deaktiviert ist. Default-Wert = 0. +'); +INSERT INTO txt VALUES ('H5652', 'English', 'Variance Analysis sleep time (in minutes): Time between two Variance Analysis loops. + There the states to display in the UI are calculated asynchroneously. + A value 0 means, that the Variance Analysis is deactivated. Default value = 0. +'); +INSERT INTO txt VALUES ('H5653', 'German', 'Soll-Ist-Abgleich-Start: Legt eine Bezugszeit fest, ab dem die Intervalle für die Soll-Ist-Abgleiche gerechnet werden.'); +INSERT INTO txt VALUES ('H5653', 'English', 'Variance Analysis start at: Defines a referential time from which the Variance Analysis intervals are calculated.'); +INSERT INTO txt VALUES ('H5654', 'German', 'Soll-Ist-Abgleich auf Schaltfläche: Es wird eine Schaltfläche angeboten, um den Status der Verbindungen mittels Soll-Ist-Abgleich synchron zu ermitteln.'); +INSERT INTO txt VALUES ('H5654', 'English', 'Variance Analysis Refresh Button: A button is offered to calculate the state of the connections synchroneously via Variance Analysis.'); +INSERT INTO txt VALUES ('H5655', 'German', 'Netzwerkareas für Nutzer: Vom Administrator vorgegebene Netzwerkareas, welche für die Zuordnung über die Sonderkonfiguration genutzt werden dürfen. Die beiden Auswahlfelder "in Quelle" und "in Ziel" legen fest, wo die Netzwerkarea genutzt werden darf.'); +INSERT INTO txt VALUES ('H5655', 'English', 'Network Areas for Users: Network areas defined by the administrator, which are permitted to be used for assignment via the Extra Configurations. The flags "in Source" and "in Destination" determine, where the Network Areas are allowed to be used.'); +INSERT INTO txt VALUES ('H5656', 'German', 'NAT Heuristik: Wenn die Sonderkonfiguration NAT gesetzt ist, wird, sobald mindestens eine zur Modellierung passend umgesetzte Regel gefunden wird, davon ausgegangen, dass die anderen Regeln mit NAT transformierte Regeln sind und nur auf die Objektzahl geprüft.'); +INSERT INTO txt VALUES ('H5656', 'English', 'NAT Heuristic: When extra config NAT is set, if at least one rule is found fitting to the modelling: the other rules are assumed to be NAT translated and are only checked for object numbers.'); +INSERT INTO txt VALUES ('H5657', 'German', 'Integrierte Rezertifizierung aktivieren: Ermöglicht die Rezertifizierung der Regeln direkt aus der Modellierung.'); +INSERT INTO txt VALUES ('H5657', 'English', 'Activate Integrated Recertification: Enables the recertification directly from Modelling.'); +INSERT INTO txt VALUES ('H5658', 'German', 'Rezertifizierungstext: Text, der zur Bestätigung der Rezertifizierung angezeigt werden soll. Enthält der Text einen Platzhalter "@@APPNAME@@", so wird dieser durch den App-Namen ersetzt.'); +INSERT INTO txt VALUES ('H5658', 'English', 'Recertification Text: Text to be shown to confirm recertification. If the text contains a placeholder "@@APPNAME@@", it is replaced by the app name.'); +INSERT INTO txt VALUES ('H5659', 'German', 'Netzwerkareas für Updatable Objects: Vom Administrator vorgegebene Netzwerkareas, welche für die Zuordnung über die Sonderkonfiguration "Updatable Objects" genutzt werden dürfen. Die beiden Auswahlfelder "in Quelle" und "in Ziel" legen fest, wo die Netzwerkarea genutzt werden darf.'); +INSERT INTO txt VALUES ('H5659', 'English', 'Network Areas for Updatable Objects: Network areas defined by the administrator, which are permitted to be used for assignment via the Extra Configurations "Updatable Objects". The flags "in Source" and "in Destination" determine, where the Network Areas are allowed to be used.'); +INSERT INTO txt VALUES ('H5660', 'German', 'Empfänger der Stilllegungsbenachrichtigung: Mehrfachauswahl, an wen die Email geschickt werden soll. + Verfügbare Optionen sind Keine, Andere Adressen, die Option "Mindestens eine Email-Benachrichtigung sicherstellen" und alle aktiven Verantwortlichkeitsstufen. + Ist "Keine" gesetzt, sind alle anderen Optionen deaktiviert. Wenn "Mindestens eine Email-Benachrichtigung sicherstellen" aktiv ist, werden zuerst die ausgewählten Optionen verwendet. Nur falls daraus keine Empfänger entstehen, werden nicht ausgewählte Verantwortlichkeitsstufen von hoher zu niedriger Sortierreihenfolge durchsucht, bis eine Stufe mit Empfängern gefunden wird.'); +INSERT INTO txt VALUES ('H5660', 'English', 'Receiver of decommission emails: Multi-select list defining who receives the decommission notification email. + Available options are None, Other addresses, the option "Ensure at least one email notification can be sent", and all active responsible levels. + If "None" is selected, all other options are disabled. If "Ensure at least one email notification can be sent" is active, selected options are used first. Only if they yield no recipients, non-selected responsible levels are checked from highest to lowest sort order until a level with recipients is found.'); +INSERT INTO txt VALUES ('H5661', 'German', 'Titel der Stilllegungsbenachrichtigung: Betreff der Email-Benachrichtigung an die betroffenen Eigentümer. Platzhalter @@INTERFACE_NAME@@ werden mit dem Namen der zu löschenden Schnittstelle ersetzt.'); +INSERT INTO txt VALUES ('H5661', 'English', 'Subject of decommission emails: Subject of the email to the addressed owners. Placeholders @@INTERFACE_NAME@@ will be replaced by the name of the interface to be decommissioned.'); +INSERT INTO txt VALUES ('H5662', 'German', 'Text der Stilllegungsbenachrichtigung: Text der Email-Benachrichtigung an die Nutzer der Schnittstelle, gefolgt von der Liste der betroffenen Verbindungen. Es können folgende Platzhalter genutzt werden: + @@INTERFACE_NAME@@ wird durch den Namen der stillzulegenden Schnittstelle ersetzt, @@NEW_INTERFACE_NAME@@ mit dem Namen der vorgeschlagenen Ersatzschnittstelle, @@NEW_INTERFACE_LINK@@ mit einem Link auf diese, + @@REASON@@ mit dem Begründungstext, der im Stillegungsformular eingegeben wurde, @@USER_NAME@@ mit dem Nutzer, der die Stillegung veranlasst hat. +'); +INSERT INTO txt VALUES ('H5662', 'English', 'Body of decommission emails: Text of the email notification to the addressed owners, followed by a list of the affected connections. Some placeholders can be used: + @@INTERFACE_NAME@@ will be replaced by the name of the interface to be decommissioned, @@NEW_INTERFACE_NAME@@ by the name of the proposed new interface, @@NEW_INTERFACE_LINK@@ by a link to this interface, + @@REASON@@ by the reason text filled in the decommission form, @@USER_NAME@@ by the user initiating the decommissioning. +'); +INSERT INTO txt VALUES ('H5663', 'German', 'Alle Regeln modelliert erwarten: Alle dem Eigentümer zugeordneten Regeln müssen modelliert sein.'); +INSERT INTO txt VALUES ('H5663', 'English', 'Expect all rules as modelled: All rules associated to the owner have to be modelled.'); +INSERT INTO txt VALUES ('H5664', 'German', 'Produktionsstatus: Gibt an, in welchem Lifecycle Status sich der Eigentümer befindet.'); +INSERT INTO txt VALUES ('H5664', 'English', 'Production state: The Owner Lifecycle State assigned to the owner.'); +INSERT INTO txt VALUES ('H5665', 'German', 'Name: Name des Produktionsstatus. Dieser wird beim Datenimport als möglicher Wert ausgewertet.'); +INSERT INTO txt VALUES ('H5665', 'English', 'Name: Owner Lifecycle State name. This is regarded as possible value during data import'); +INSERT INTO txt VALUES ('H5666', 'German', 'In diesem Kapitel können die Werte des Produktions-Status von Eigentümern eingesehen, erstellt, bearbeitet und gelöscht werden. + Der Produktions-Status definiert den aktuellen Zustand eines Eigentümers (z. B. Geplant, Im Betrieb, Auslaufend). Sie werden beim Eigentümer-Daten-Import ausgewertet. +'); +INSERT INTO txt VALUES ('H5666', 'English', 'In this chapter, Production Lifecycle States of owners can be viewed, created, edited, and deleted. + Production Lifecycle States define the current status of an owner (e.g., Planned, In Production, End of Life). They are evaluated during Owner Data Import. +'); +INSERT INTO txt VALUES ('H5667', 'German', 'Gelöschte App Server ausrollen: App Server, die nicht mehr im Datenimport geliefert wurden, werden dennoch weiter ausgerollt. + Dies kann z.B. zur Stabilisierung der Prozesse bei instabilem Datenimport dienen. Zur Rezertifizierung müssen die betroffenen Verbindungen aber bereinigt sein. +'); +INSERT INTO txt VALUES ('H5667', 'English', 'Rollout removed App Servers: App servers not delivered anymore in data import are further rolled out. + This may e.g. stabilize processes on instable data import. Before recertification the affected connections have to be adjusted. +'); +INSERT INTO txt VALUES ('H5668', 'German', 'Nur eigene Objekte beantragen: In Beantragungen werden nur eigene Gruppenobjekte aus genutzten Schnittstellen berücksichtigt. Falls Gruppenobjekte anderer Eigentümer enthalten sind, die in Produktion nicht gefunden wurden, wird die Beantragung der Verbindung unterdrückt.'); +INSERT INTO txt VALUES ('H5668', 'English', 'Request only own objects: Requests include only own group objects from used interfaces. If group objects of other owners are included that are not found in production, the request for that connection is suppressed.'); +INSERT INTO txt VALUES ('H5669', 'German', 'Aktiv: Steuert, ob der Träger des Lifecycle-Status als aktiv gewertet wird.'); +INSERT INTO txt VALUES ('H5669', 'English', 'Active: Controls whether the holder of the lifecycle state is considered as active.'); +INSERT INTO txt VALUES ('H5670', 'German', 'Diese Seite konfiguriert die Importplanung für Eigentümer/App-Daten und Subnetze, die Quellpfade sowie die LDAP-Gruppenverwaltung.'); +INSERT INTO txt VALUES ('H5670', 'English', 'This page configures the owner/app data import and subnet import schedules, source paths, and LDAP group handling.'); +INSERT INTO txt VALUES ('H5671', 'German', 'Konfigurieren Sie Importpfade, Startzeiten und Warteintervalle für App-Daten und Subnetzdaten.'); +INSERT INTO txt VALUES ('H5671', 'English', 'Configure import paths, start times and sleep intervals for app data and subnet data.'); +INSERT INTO txt VALUES ('H5672', 'German', 'Zusätzliche Informationen: Bearbeitbares JSON Objekt für zusätzliche Eigentümer-Metadaten, z. B. aus dem App-Daten-Import.'); +INSERT INTO txt VALUES ('H5672', 'English', 'Additional Information: Editable JSON object for extra owner metadata, for example from app data import.'); +INSERT INTO txt VALUES ('H5673', 'German', 'Legen Sie Rollen pro Verantwortlichkeitsstufe fest, um zu steuern, welche Rollen beim Import gesetzt werden.'); +INSERT INTO txt VALUES ('H5673', 'English', 'Use role assignment per responsible type to control which roles are set during import.'); +INSERT INTO txt VALUES ('H5674', 'German', 'Verantwortlichkeitsstufen ohne die erforderliche Berechtigungs-Flagge können die zugehörigen Rollen nicht zuweisen.'); +INSERT INTO txt VALUES ('H5674', 'English', 'Responsible types without the required permission flag cannot assign related roles.'); +INSERT INTO txt VALUES ('H5675', 'German', 'Nur Administratoren können Änderungen speichern.'); +INSERT INTO txt VALUES ('H5675', 'English', 'Only administrators can save changes.'); +INSERT INTO txt VALUES ('H5676', 'German', 'Wenn aktiviert, werden Benutzer aus Eigentümergruppen entfernt, die nicht im Import enthalten sind. Andernfalls werden nur neue Benutzer hinzugefügt.'); +INSERT INTO txt VALUES ('H5676', 'English', 'If enabled, users not listed in the import are removed from owner groups. Otherwise only new users are added.'); +INSERT INTO txt VALUES ('H5677', 'German', 'Trage hier die Schlüssel ein, die das Feld für den Owner repräsentieren. Du kannst mehrere Keys hinzufügen, indem du auf das + Symbol klickst. +'); +INSERT INTO txt VALUES ('H5677', 'English', 'Enter the keys that represent the Owner field. You can add multiple keys by clicking the + button. +'); +INSERT INTO txt VALUES ('H5678', 'German', 'Trage hier die Schlüssel ein, die das Feld für die ÄnderungsId repräsentieren. Du kannst mehrere Keys hinzufügen, indem du auf das + Symbol klickst. +'); +INSERT INTO txt VALUES ('H5678', 'English', 'Enter the keys that represent the ChangeId field. You can add multiple keys by clicking the + button. +'); +INSERT INTO txt VALUES ('H5701', 'German', 'Die in der Datenbank hinterlegten sprachabhängigen Texte können individuell überschrieben werden. + Dabei werden die vom System vorgegebenen Texte nicht geändert, sondern nur durch die hier definierten Texte - falls vorhanden - überblendet. + Die hier gemachten Änderungen werden in der UI beim nächsten Login sichtbar, bei Hilfetexten erst nach dem nächsten Restart. +'); +INSERT INTO txt VALUES ('H5701', 'English', 'The language dependent texts stored in the database can be overwritten individually. + In doing so, system texts are not changed but crossfaded by the texts defined here. The changes made here become visible in the UI with the next login, + help texts only after the next restart. +'); +INSERT INTO txt VALUES ('H5702', 'German', 'Im ersten Schritt muss die betroffene Sprache ausgewählt werden. Dann erscheint die Zeile zur eigentlichen Textsuche.'); +INSERT INTO txt VALUES ('H5702', 'English', 'In the first step the language to be handled has to be selected. Then the row for the text search appears.'); +INSERT INTO txt VALUES ('H5703', 'German', 'Bei Eingabe eines Suchstrings erscheinen alle hinterlegten Texte, welche diesen beinhalten. + Wird das Feld leer gelassen, erscheinen alle verfügbaren Texte der gewählten Sprache. Die Suche kann wahlweise auch schreibungsabhängig durchgeführt werden. + Durch das Setzen des "Hilfetexte ignorieren"-Flags werden die Hilfetexte (Schlüssel beginnend mit "H"), bei der Suche nicht berücksichtigt. +'); +INSERT INTO txt VALUES ('H5703', 'English', 'When entering a search string, all texts containing this are displayed. If left empty, all texts of the selected language are displayed. + Optionally the search can be case-sensitive. By setting the "Ignore Help Texts" flag all Help texts (Key beginning with "H") are disregarded. +'); +INSERT INTO txt VALUES ('H5704', 'German', 'In der Tabelle der Suchergebnisse können pro Schlüssel neue Texte definiert, + bereits vorhandene durch Setzen des "Löschen"-Flags zum Löschen vorgemerkt werden. Wird nur der Text entfernt, wird der Systemtext mit Leertext überschrieben! + Die Änderungen werden erst durch das Betätigen des "Speichern"-Knopfes wirksam. +'); +INSERT INTO txt VALUES ('H5704', 'English', 'In the table of search results new texts can be defined per key, existing texts can be marked for deletion by setting the "Delete" flag. + If only a text is removed, the system text will be overwritten by an empty text! All changes get effective only by pressing the "Save" button. +'); +INSERT INTO txt VALUES ('H5720', 'German', 'Diese Seite beschreibt die Einstellungen für Regelablauf-Benachrichtigungen. Konfiguriert werden Versandintervalle, Mail-Textvorlage und die Zuordnung von Initiator-Schlüsseln zu Anzeigetexten.'); +INSERT INTO txt VALUES ('H5720', 'English', 'This page describes the settings for rule expiry notifications. You can configure sending intervals, email body template and the mapping of initiator keys to display texts.'); +INSERT INTO txt VALUES ('H5720a', 'German', 'Der Inhalt geplanter Reports wird in der Sprache des Schedule-Owners erzeugt. Sprachabhängige Benachrichtigungs-Platzhalter wie @@TIME_INTERVAL@@ und @@RULE_TABLE@@ verwenden die konfigurierte Benachrichtigungssprache; falls keine gesetzt ist, wird die globale Standardsprache verwendet.'); +INSERT INTO txt VALUES ('H5720a', 'English','Scheduled report content is generated in the language of the schedule owner. Language-dependent notification placeholders such as @@TIME_INTERVAL@@ and @@RULE_TABLE@@ use the configured notification language; if none is set, the global default language is used.'); +INSERT INTO txt VALUES ('H5721', 'German', 'Regelablauf - Benachrichtigungen: Konfiguration der Versandintervalle und Empfänger für RuleTimer-Benachrichtigungen.'); +INSERT INTO txt VALUES ('H5721', 'English', 'Rule expiry notifications: Configure intervals and recipients for RuleTimer notifications.'); +INSERT INTO txt VALUES ('H5721a', 'German', 'Sprache für Benachrichtigungen: Legt fest, in welcher Sprache sprachabhängige Platzhalter wie @@TIME_INTERVAL@@ und @@RULE_TABLE@@ erzeugt werden. Standard ist die globale Standardsprache.'); +INSERT INTO txt VALUES ('H5721a', 'English','Notification language: Defines the language used for language-dependent placeholders like @@TIME_INTERVAL@@ and @@RULE_TABLE@@. The default is the global default language.'); +INSERT INTO txt VALUES ('H5722', 'German', 'Regelablauf - Email-Text: Vorlage für den Mail-Text. Platzhalter wie @@APPNAME@@, @@APPID@@, @@TIME_INTERVAL@@ und @@RULE_TABLE@@ werden ersetzt. @@RULE_TABLE@@ definiert die Einfügeposition der Regeltabelle.'); +INSERT INTO txt VALUES ('H5722', 'English', 'Rule expiry email body: Template for the mail body. Placeholders like @@APPNAME@@, @@APPID@@, @@TIME_INTERVAL@@ and @@RULE_TABLE@@ are replaced. @@RULE_TABLE@@ defines where the rule table is inserted.'); +INSERT INTO txt VALUES ('H5723', 'German', 'Regelablauf - Initiator-Texte: Zuordnung von Suffix-Schlüsseln aus dem Time-Objektnamen zu Anzeige-Texten im Report.'); +INSERT INTO txt VALUES ('H5723', 'English', 'Rule expiry initiator texts: Mapping of suffix keys from time-object names to display texts in the report.'); +INSERT INTO txt VALUES ('H5724', 'German', 'Neuen Initiator-Eintrag hinzufügen: Schlüssel und Text erfassen und mit Plus übernehmen.'); +INSERT INTO txt VALUES ('H5724', 'English', 'Add a new initiator entry: Enter key and text and confirm with the plus button.'); +INSERT INTO txt VALUES ('H5725', 'German', 'Aktive Regeln - Benachrichtigungen: Konfiguration der Empfänger für Benachrichtigungen, wenn ein Owner noch aktive Regeln besitzt.'); +INSERT INTO txt VALUES ('H5725', 'English', 'Active rules notifications: Configure recipients for notifications when an owner still has active rules.'); +INSERT INTO txt VALUES ('H5726', 'German', 'Aktive Regeln - Email-Text: Vorlage für den Mail-Text. Platzhalter wie @@APPNAME@@, @@APPID@@ und @@RULE_TABLE@@ werden ersetzt. @@RULE_TABLE@@ definiert die Einfügeposition der Regeltabelle.'); +INSERT INTO txt VALUES ('H5726', 'English', 'Active rules email body: Template for the mail body. Placeholders like @@APPNAME@@, @@APPID@@ and @@RULE_TABLE@@ are replaced. @@RULE_TABLE@@ defines where the rule table is inserted.'); +INSERT INTO txt VALUES ('H5801', 'German', 'Compliance-Check-Intervall (in Minuten): legt das Intervall fest, in dem der Compliance-Check durchgeführt werden soll.'); +INSERT INTO txt VALUES ('H5801', 'English', 'Compliance Check sleep time (in minutes): defines the interval in which the compliance check should be performed.'); +INSERT INTO txt VALUES ('H5802', 'German', 'Compliance-Check-Start: legt eine Bezugszeit fest, ab dem die Intervalle für den Compliance-Check gerechnet werden.'); +INSERT INTO txt VALUES ('H5802', 'English', 'Compliance Check start at: defines a referential time from which the Compliance Check intervals are calculated.'); +INSERT INTO txt VALUES ('H5803', 'German', 'Hier werden alle Einstellungen rund um den Compliance-Check verwaltet.'); +INSERT INTO txt VALUES ('H5803', 'English', 'Here all settings around the Compliance Check are administrated.'); +INSERT INTO txt VALUES ('H5807', 'German', 'Wenn aktiviert, werden die durch die Compliance-Prüfung erzeugten Daten in der Datenbank gespeichert.'); +INSERT INTO txt VALUES ('H5807', 'English', 'If checked, the data that is generated by the compliance check will be persisted in the database.'); +INSERT INTO txt VALUES ('H5808', 'German', 'Hier werden die Dienste definiert, die bei der Compliance-Prüfung berücksichtigt werden sollen. Wenn dieses Feld leer ist, werden keine Dienste eingeschränkt.'); +INSERT INTO txt VALUES ('H5808', 'English', 'Sets up services that should be checked for during compliance check. If this field is empty, no service will be restricted.'); +INSERT INTO txt VALUES ('H5809', 'German', 'Wenn aktiviert, wird beim Erstellen der Compliance-Matrix eine Schachtelung der Netzwerk-Zonen ermöglicht.'); +INSERT INTO txt VALUES ('H5809', 'English', 'If checked, the use of nested network zones for compliance matrices is enabled.'); +INSERT INTO txt VALUES ('H5810', 'German', 'Die Policy, die für den termingesteuerten Compliance Check genutzt wird.'); +INSERT INTO txt VALUES ('H5810', 'English', 'Policy used for the scheduled compliance check.'); +INSERT INTO txt VALUES ('H5811', 'German', 'Das Netzwerkobjekt, dass die Netzwerkzone "Internet" darstellt.'); +INSERT INTO txt VALUES ('H5811', 'English', 'The network object that is taken for the network zone "Internet".'); +INSERT INTO txt VALUES ('H5812', 'German', 'Importieren einer Matrix via JSON Datei. '); +INSERT INTO txt VALUES ('H5812', 'English', 'Import of a matrix via JSON file. '); +INSERT INTO txt VALUES ('H5813', 'German', 'Definition vom Kriterien mit fixem Inhalt'); +INSERT INTO txt VALUES ('H5813', 'English', 'Definition of Criteria with fixed content. '); +INSERT INTO txt VALUES ('H5814', 'German', 'Maximal Anzahl von Violations die im Compliance Report pro Rule angezeigt werden. Bei 0 keine Beschränkung.'); +INSERT INTO txt VALUES ('H5814', 'English', 'Maximum number of violations shown in the compliance report per rule. If set to 0, no limitation is applied.'); +INSERT INTO txt VALUES ('H5815', 'German', 'Wenn aktiviert, werden Netzwerkzonenmatrizen nach Zonen-ID sortiert (Default: Sortierung nach Name).'); +INSERT INTO txt VALUES ('H5815', 'English', 'When enabled, network zone matrices are sorted by zone ID (default: sorted by name).'); +INSERT INTO txt VALUES ('H5816', 'German', 'Durch Komma getrennte Liste von relevanten Management IDs.'); +INSERT INTO txt VALUES ('H5816', 'English', 'Comma-separated list of relevant management IDs.'); +INSERT INTO txt VALUES ('H5817', 'German', 'Wenn aktiviert, wird bei Änderungen in Compliance-Matrizen automatisch eine "Internetzone" hinzugefügt, die alle Adressbereiche beinhaltet, die nicht in anderen Zonen definiert sind.'); +INSERT INTO txt VALUES ('H5817', 'English', 'If enabled, changes to compliance matrices will automatically add an "Internetzone" that includes all address ranges not defined in other zones.'); +INSERT INTO txt VALUES ('H5818', 'German', 'Adressbereiche, die aus der Berechnung der Internetzone ausgeschlossen werden sollen.'); +INSERT INTO txt VALUES ('H5818', 'English', 'Address ranges that should be excluded from the Internet zone calculation.'); +INSERT INTO txt VALUES ('H5819', 'German', 'Wenn aktiviert, wird bei Änderungen in Compliance-Matrizen automatisch eine "Undefiniert-Intern-Zone" hinzugefügt, die alle Adressbereiche beinhaltet, die nicht in anderen Zonen definiert sind und von der Internetzone ausgeschlossen wurden.'); +INSERT INTO txt VALUES ('H5819', 'English', 'When enabled, changes to compliance matrices automatically add an "Undefined Internal Zone" that includes all address ranges not defined in other zones and excluded from the Internet zone.'); +INSERT INTO txt VALUES ('H5820', 'German', 'Teilbereich des privaten Adressbereichs gemäß RFC 1918'); +INSERT INTO txt VALUES ('H5820', 'English', 'Part of the private address range according to RFC 1918'); +INSERT INTO txt VALUES ('H5821', 'German', 'Spezialbereich für „diese“ Netzwerke, Quelle unbekannt (unspezifische Adresse).'); +INSERT INTO txt VALUES ('H5821', 'English', 'Special range for “this” network, used as an unspecified address.'); +INSERT INTO txt VALUES ('H5822', 'German', 'Loopback-Adressbereich zur internen Kommunikation eines Hosts.'); +INSERT INTO txt VALUES ('H5822', 'English', 'Loopback address range for internal host communication.'); +INSERT INTO txt VALUES ('H5823', 'German', 'Link-Local-Adressbereich für automatische Adressvergabe ohne DHCP.'); +INSERT INTO txt VALUES ('H5823', 'English', 'Link-local address range for automatic addressing without DHCP.'); +INSERT INTO txt VALUES ('H5824', 'German', 'Multicast-Adressbereich für die Zustellung an mehrere Empfänger.'); +INSERT INTO txt VALUES ('H5824', 'English', 'Multicast address range for delivery to multiple recipients.'); +INSERT INTO txt VALUES ('H5825', 'German', 'Reservierter Bereich für zukünftige oder experimentelle Nutzung.'); +INSERT INTO txt VALUES ('H5825', 'English', 'Reserved range for future or experimental use.'); +INSERT INTO txt VALUES ('H5826', 'German', 'Broadcast-Adresse für die Ansprache aller Hosts im lokalen Netzwerk.'); +INSERT INTO txt VALUES ('H5826', 'English', 'Broadcast address for addressing all hosts in the local network.'); +INSERT INTO txt VALUES ('H5827', 'German', 'Dokumentationsnetz für Beispiele in Handbüchern und Tutorials.'); +INSERT INTO txt VALUES ('H5827', 'English', 'Documentation network for examples in manuals and tutorials.'); +INSERT INTO txt VALUES ('H5828', 'German', 'Zweites Dokumentationsnetz für Lehr- und Beispielzwecke.'); +INSERT INTO txt VALUES ('H5828', 'English', 'Second documentation network for educational and example purposes.'); +INSERT INTO txt VALUES ('H5829', 'German', 'Drittes Dokumentationsnetz für Lehr- und Beispielzwecke.'); +INSERT INTO txt VALUES ('H5829', 'English', 'Third documentation network for educational and example purposes.'); +INSERT INTO txt VALUES ('H5830', 'German', 'Carrier-Grade NAT-Bereich für Provider-interne Adressierung.'); +INSERT INTO txt VALUES ('H5830', 'English', 'Carrier-grade NAT range for provider-internal addressing.'); +INSERT INTO txt VALUES ('H5831', 'German', 'Reservierter Adressbereich für spezielle Zwecke (IANA).'); +INSERT INTO txt VALUES ('H5831', 'English', 'Reserved address block for special purposes (IANA).'); +INSERT INTO txt VALUES ('H5832', 'German', 'Adressbereich für Netzwerkleistungs- und Benchmark-Tests.'); +INSERT INTO txt VALUES ('H5832', 'English', 'Address range for network performance and benchmark testing.'); +INSERT INTO txt VALUES ('H5833', 'German', 'Ehemaliger IPv6-Übergangsbereich (6to4-Relay), heute obsolet.'); +INSERT INTO txt VALUES ('H5833', 'English', 'Former IPv6 transition range (6to4 relay), now obsolete.'); +INSERT INTO txt VALUES ('H5834', 'German', 'Wenn aktiviert, werden die auto-kalkulierten Zonen am Ende der Matrix-Achsen eingeordnet. Default: am Anfang.'); +INSERT INTO txt VALUES ('H5834', 'English', 'When activated, the auto-calculated zones are placed at the end of the matrix axes. Default: at the beginning.'); +INSERT INTO txt VALUES ('H5835', 'German', 'Wenn aktiviert, werden dynamische und Domain-Objekte in der Compliance-Auswertung als Teil der Internetzone angenommen. Default: Objekte werden gleich behandelt wie andere Netzwerkobjekte.'); +INSERT INTO txt VALUES ('H5835', 'English', 'When enabled, dynamic and domain objects are considered part of the Internet zone in the compliance evaluation. Default: Objects are treated the same as other network objects.'); +INSERT INTO txt VALUES ('H5836', 'German', 'Wenn aktiviert, werden in compliance reports zusätzlich zu den aufgelösten Spalten für Sources, Destinations und Services Spalten mit der Kurzform angezeigt.'); +INSERT INTO txt VALUES ('H5836', 'English', 'When enabled, compliance reports will display columns with the short form in addition to the resolved columns for sources, destinations and services.'); +INSERT INTO txt VALUES ('H5837', 'German', 'Editieren der Compliance-Matrix. Rot: Erlaubte Kommunikation. Grün: Verbotene Kommunikation.'); +INSERT INTO txt VALUES ('H5837', 'English', 'Editing the compliance matrix. Red: allowed communication. Green: restricted communication.'); +INSERT INTO txt VALUES ('H5838', 'German', 'Editieren von importierten Matrizen nicht möglich.'); +INSERT INTO txt VALUES ('H5838', 'English', 'Editing imported matrices not possible.'); +INSERT INTO txt VALUES ('H5839', 'German', 'Matrixverletzung'); +INSERT INTO txt VALUES ('H5839', 'English', 'Matrix violation'); +INSERT INTO txt VALUES ('H5840', 'German', 'Verbotener Service'); +INSERT INTO txt VALUES ('H5840', 'English', 'Restricted Service'); +INSERT INTO txt VALUES ('H5841', 'German', 'Auswertbarkeitsproblem'); +INSERT INTO txt VALUES ('H5841', 'English', 'Assessability issue'); +INSERT INTO txt VALUES ('H5842', 'German', 'Wenn aktiviert, können importierte Matrizen weder gelöscht noch editiert werden.'); +INSERT INTO txt VALUES ('H5842', 'English', 'When enabled, imported matrices cannot be deleted or edited.'); +INSERT INTO txt VALUES ('H5843', 'German', 'Anzahl der Elemente die pro Anfrage geladen werden sollen.'); +INSERT INTO txt VALUES ('H5843', 'English', 'Amount of elements that should be retrieved with each fetch operation.'); +INSERT INTO txt VALUES ('H5844', 'German', 'Anzahl der Prozessoren die für Parallelisierungsoperationen zur Verfügung stehen.'); +INSERT INTO txt VALUES ('H5844', 'English', 'Amount of processors that should be used for parallelized operations.'); +INSERT INTO txt VALUES ('H5845', 'German', 'Löscht vorhandene Violations.'); +INSERT INTO txt VALUES ('H5845', 'English', 'Deletes all existing violations .'); +INSERT INTO txt VALUES ('H5846', 'German', 'Lösche alle Violations'); +INSERT INTO txt VALUES ('H5846', 'English', 'Delete all violations'); +INSERT INTO txt VALUES ('H5848', 'German', 'Initiert einen vollständigen Compliance Check, welcher gefundene Violations als "Initial" markiert.'); +INSERT INTO txt VALUES ('H5848', 'English', 'Initializes a complete compliance check, marking found violations as "initial".'); +INSERT INTO txt VALUES ('H5849', 'German', 'Initialen Check durchführen'); +INSERT INTO txt VALUES ('H5849', 'English', 'Run initial check'); +INSERT INTO txt VALUES ('H5850', 'German', 'Check starten'); +INSERT INTO txt VALUES ('H5850', 'English', 'Run Check'); +INSERT INTO txt VALUES ('H5851', 'German', 'Sollen festgestellte Objektänderungen im Änderungsreport angezeigt werden, ist diese Einstellung zu aktivieren. Default-Wert = "inaktiv".'); +INSERT INTO txt VALUES ('H5851', 'English', 'Include object changes: When the import detects object changes, they will be included in the change report. Default value = "inactive".'); + INSERT INTO txt VALUES ('H6001', 'German', 'Firewall Orchestrator verfügt über zwei APIs:
            • Die Haupt- (oder FWO) API, die den Zugriff auf die Firewall-Nutzdaten erlaubt.
            • Die User Management API, mit deren Hilfe der die Firewall Orchestrator Nutzer ausgelesen oder geändert werden können.
            - Die FWO API ist eine GraphQl API, welche auf Hasura basiert. + Die FWO API ist eine GraphQl API, welche auf Hasura basiert. Diese erlaubt es, flexibel den Zugang zu allen Daten der Datenbank und die Granularität der zurückgegebenen Daten zu steuern.

            @@ -3904,16 +6578,16 @@ INSERT INTO txt VALUES ('H6001', 'English', 'Firewall Orchestrator features two
          • The User Management API which can be used to handle Firewall Orchestrator users
          - The FWO API is a GraphQl API which is based on Hasura. + The FWO API is a GraphQl API which is based on Hasura. This allows us to flexibly provide access to all data in the database and also define the level of granularity the data is returned in.

          - The User Management API allows user authentication as well as user manipulation such as listing, adding, deleting, changing users and + The User Management API allows user authentication as well as user manipulation such as listing, adding, deleting, changing users and their access permissions (roles and tenant memberships).

          Note that when API testing without a valid certificate installed for your API, consider using the "--insecure" parameter for your curl test calls. '); INSERT INTO txt VALUES ('H6101', 'German', 'GraphQL nutzt einen leicht anderen Ansatz als REST, indem es keine fixen Entry points zur API definiert. - Stattdessen hat man die Freiheit, eine exakt auf die gewünschte Detailtiefe angepasste Query zu nutzen. + Stattdessen hat man die Freiheit, eine exakt auf die gewünschte Detailtiefe angepasste Query zu nutzen. '); INSERT INTO txt VALUES ('H6101', 'English', 'GraphQL uses a slightly different approach as REST, not defining fixed entry points to the API. Instead you are free to use a custom query specifying exactly which level of detail you want to return each time. @@ -3976,6 +6650,76 @@ INSERT INTO txt VALUES ('H6906', 'German', 'Anmelden zur Generierung eines g&uu INSERT INTO txt VALUES ('H6906', 'English', 'Login to get a JWT for the steps further below'); INSERT INTO txt VALUES ('H6907', 'German', 'Auflisten bereits vorhandener Reports im Archiv (hier der letzte generierte zum Schedule)'); INSERT INTO txt VALUES ('H6907', 'English', 'List generated reports in archive (here we get the last one generated for the respective schedule)'); +INSERT INTO txt VALUES ('H6921', 'German', 'Der Import von Applikationsdaten wird aus einer oder mehreren .json-Dateien mit den in den Modellierungseinstellungen definierten Pfaden und Namen gespeist. + Dort kann auch jeweils ein gleichnamiges Python-Skript (mit der Endung .py) zur Erzeugung eben dieser Dateien hinterlegt werden. Die .json-Datei hat die folgende Struktur: +'); +INSERT INTO txt VALUES ('H6921', 'English', 'The import of application data is fed from one or several .json files with paths and names defined in the Modelling Settings. + There also python scripts with the same names can be provided to create these files. The structure of the .json file is as following: +'); +INSERT INTO txt VALUES ('H6922', 'German', 'Die einzelnen Felder haben folgende Bedeutung: +
            +
          • app_id_external: Eindeutige Kennzeichnung der Applikation. Dies ist ggf. über verschiedene Importquellen hinweg sicherzustellen.
          • +
          • name: Dargestellter Name der Applikation.
          • +
          • main_user: Die DN der hauptverantwortlichen Person. Mindestens eines der Felder main_user, modellers oder modeller_groups sollte gefüllt sein, damit ein Zugriff + auf diese Applikation möglich ist. (Ansonsten muss dieses in den Eigentümer-Einstellungen manuell nachgeholt werden.)
          • +
          • modellers: Hier werden die DNs von allen zur Bearbeitung dieser Applikation Berechtigten angegeben.
          • +
          • modeller_groups: Hier können die DNs von Gruppen angegeben werden. Zur Zeit werden diese genauso wie die Einträge unter "modellers" behandelt.
          • +
          • criticality: Hier kann optional ein String zur Kennzeichnung der Kritikalität der Applikation definiert werden.
          • +
          • import_source: String zur Kennzeichnung der Importquelle. Dient zur Unterscheidung bei mehreren Quellen.
          • +
          • app_servers: Liste aller zur Applikation zugeordneten Host-Adressen. +
              +
            • name: Optionaler Name zur Darstellung
            • +
            • ip: IP-Adresse
            • +
            +
          • +
          +'); +INSERT INTO txt VALUES ('H6922', 'English', 'These fields have the following meaning: +
            +
          • app_id_external: Unique identification string of the application. This has to be ensured over several import sources.
          • +
          • name: Displayed name of the application.
          • +
          • main_user: DN of the main responsible person. At least one of the fields main_user, modellers or modeller_groups should be filled to ensure access + to the application. (Else this has to be ensured manually in the Owner Settings afterwards.)
          • +
          • modellers: Here the DNs of all persons authorized to work on this application have to be delivered.
          • +
          • modeller_groups: Here DNs of user groups can be delivered. Currently they are handled the same way as the entries in "modellers".
          • +
          • criticality: An optional string to mark the criticality of the application can be defined here.
          • +
          • import_source: String to identify the import source. Necessary to distinguish between several sources.
          • +
          • app_servers: List of all host addresses assigned to the application: +
              +
            • name: Optional name for display
            • +
            • ip: IP address
            • +
            +
          • +
          +'); +INSERT INTO txt VALUES ('H6931', 'German', 'Der Import von IP-Daten wird aus einer .json-Datei mit dem in den Modellierungseinstellungen definierten Pfad und Namen gespeist. + Dort kann auch ein gleichnamiges Python-Skript (mit der Endung .py) zur Erzeugung eben dieser Datei hinterlegt werden. Die .json-Datei hat die folgende Struktur: +'); +INSERT INTO txt VALUES ('H6931', 'English', 'The import of IP data is fed from a .json file with path and name defined in the Modelling Settings. + There also a python script with the same name can be provided to create this file. the structure of the .json file is as following: +'); +INSERT INTO txt VALUES ('H6932', 'German', 'Die einzelnen Felder haben folgende Bedeutung: +
            +
          • name: Dargestellter Name der Area.
          • +
          • id_string: Eindeutige Kennzeichnung der Area.
          • +
          • subnets: Liste alle Subnetze der Area: +
          • name: Optionaler Name zur Darstellung.
          • +
          • ip: IP-Adresse oder Start-IP-Addresse, falls Bereiche definiert werden sollen.
          • +
          • ip_end: Ende-IP-Addresse, falls Bereiche definiert werden sollen. Sonst leer lassen oder denselben Wert wie in "ip" liefern.
          • + +
          +'); +INSERT INTO txt VALUES ('H6932', 'English', 'These fields have the following meaning: +
            +
          • name: Displayed name of the area
          • +
          • id_string: Unique identification string of the area.
          • +
          • subnets: List of all subnets of the area: +
          • name: Optional name for display.
          • +
          • ip: IP address or start IP address, if ranges are to be defined.
          • +
          • ip_end: end IP address, if ranges are to be defined. Else leave empty or fill with the same value as "ip".
          • + +
          +'); INSERT INTO txt VALUES ('H7001', 'German', 'Im diesem Reiter werden die Monitoringwerkzeuge zur Verfügung gestellt. Die meisten Abschnitte können nur von Nutzern mit den verschiedenen Administrator-Rollen gesehen und genutzt werden. @@ -3985,8 +6729,8 @@ INSERT INTO txt VALUES ('H7001', 'English', 'In this tab monitoring tools are pr Most sections can only be seen and used by users with the different administrator roles. The auditor is able to see the monitoring tools, but as he has no write permissions all buttons leading to changes are disabled. '); -INSERT INTO txt VALUES ('H7011', 'German', 'Im ersten Kapitel "Alarme" werden alle Ereignisse behandelt, die eine Überprüfung oder ein Eingreifen eines Administrators erfordern: - Der Abschnitt Offene Alarme dient als Übersicht über alle noch zu behandelnden Ereignisse, während in Alle Alarme +INSERT INTO txt VALUES ('H7011', 'German', 'Im ersten Kapitel "Alarme" werden alle Ereignisse behandelt, die eine Überprüfung oder ein Eingreifen eines Administrators erfordern: + Der Abschnitt Offene Alarme dient als Übersicht über alle noch zu behandelnden Ereignisse, während in Alle Alarme auch die bereits bearbeiteten Alarme mitsamt dem jeweiligen Bearbeiter eingesehen werden können. '); INSERT INTO txt VALUES ('H7011', 'English', 'In the first chapter "Alerts" all events that need a check or intervention by an administrator are handled: @@ -4002,22 +6746,28 @@ INSERT INTO txt VALUES ('H7012', 'English', 'The chapter "Background Checks" dis Daily Checks inspect other system conditions, especially the import status of the different managements. '); INSERT INTO txt VALUES ('H7013', 'German', 'Im Kapitel "Import" wird der Datenimport überwacht: - Import-Status erlaubt einen Überblick über einige Parameter der verschiedenen importierenden systeme, - während Import-Logs die wichtigen Ausgaben der Datenimporte festhält. + Import-Status erlaubt einen Überblick über einige Parameter der verschiedenen importierenden Systeme, + während "Import-Logs", "Applikationsdaten Import-Logs" und "Subnetzdaten Import-Logs" die wichtigen Ausgaben der jeweiligen Datenimporte festhält. '); -INSERT INTO txt VALUES ('H7013', 'English', 'In the "Import" chapter the data import is monitored: - Import Status allows a view on several parameters of the different importing systems, - whereas Import Logs records noteworthy outcomes of the data imports. +INSERT INTO txt VALUES ('H7013', 'English', 'In the "Import" chapter the data import is monitored: + Import Status allows a view on several parameters of the different importing systems, + whereas "Import Logs", "Owner Data Import Logs", and "Subnet Data Import Logs" record noteworthy outcomes of the respective data imports. '); -INSERT INTO txt VALUES ('H7014', 'German', 'Das Kapitel "Persönlich" ist für alle Nutzer zugänglich. +INSERT INTO txt VALUES ('H7014', 'German', 'Das Kapitel "Persönlich" ist für alle Nutzer zugänglich. Unter UI-Nachrichten werden alle Fehler- und Erfolgsmeldungen des jeweiligen Nutzers festgehalten. '); INSERT INTO txt VALUES ('H7014', 'English', 'The "Personal" chapter is accessible by all users. Ui Messages records all error and success messages of the actual user. '); +INSERT INTO txt VALUES ('H7015', 'German', 'Das Kapitel "Modellierung" zeigt die App Rollen, App Server, Netzwerkbereiche, Service Gruppen und Services pro Owner + und bietet die Möglichkeit, verwaiste Einträge aus Verbindungen zu entfernen. +'); +INSERT INTO txt VALUES ('H7015', 'English', 'The "Modelling" chapter shows app roles, app servers, network areas, service groups and services per owner + and allows removing orphaned entries from connections. +'); INSERT INTO txt VALUES ('H7101', 'German', 'Verschiedene Komponenten des Firewall Orchestrator können Alarme auslösen, wenn eine Überprüfung oder ein Eingreifen durch einen Administrator erforderich ist. Je nach Alarmtyp werden unter "Details" weitere Informationen oder Handlungsoptionen angeboten. Durch Auswahl der "Bestätigen"-Schaltfläche verschwindet der Alarm aus der Übersicht, der Bestätigende wird mit Zeitstempel im Alarm protokolliert. - Der Alarm kann dann weiterhin unter "Alle Alarme" eingesehen werden, die Details sind dann aber nicht mehr verfügbar. Wird ein Alarm wiederholt ausgelöst (z.B. bei der Autodiscovery + Der Alarm kann dann weiterhin unter "Alle Alarme" eingesehen werden, die Details sind dann aber nicht mehr verfügbar. Wird ein Alarm wiederholt ausgelöst (z.B. bei der Autodiscovery oder beim Täglichen Check), so wird der bereits existierende, soweit zuzuordnen, automatisch bestätigt. '); INSERT INTO txt VALUES ('H7101', 'English', 'Several components of Firewall Orchestrator can raise alerts, if a check or intervention by an administrator is necessary. @@ -4035,17 +6785,17 @@ INSERT INTO txt VALUES ('H7102', 'English', 'If sample data is found by the Täglichen Check beim Import einzelner Managements Unregelmässigkeiten festgestellt (langlaufende, überfällige oder ganz ausgebliebene Importe), +INSERT INTO txt VALUES ('H7104', 'German', 'Werden beim Täglichen Check beim Import einzelner Managements Unregelmässigkeiten festgestellt (langlaufende, überfällige oder ganz ausgebliebene Importe), wird im Alarm eine detailliertere Übersicht über den Import-Status bzw. die Möglichkeit des Rollbacks (im Falle eines langlaufenden Imports) des jeweiligen Managements angeboten. '); INSERT INTO txt VALUES ('H7104', 'English', 'When the Daily Check finds irregularities in the import of a management (long-running, overdue or completely missing imports), a detailled overview of the import status, resp. an option to rollback the import (in case of a long-running import) is offered in the alert. '); INSERT INTO txt VALUES ('H7105', 'German', 'Wenn der automatische Lauf der Autodiscovery Änderungen in der Device-Konfiguration feststellt (hinzugekommene oder verschwundene Geräte), - wird für jede einzelne Änderung ein Alarm ausgelöst. Unter "Details" wird dann die jeweilige Aktion zur Anpassung im Firewall Orchestrator zur Ausführung angeboten. - Dabei ist zu berücksichtigen, dass Managements zuerst angelegt werden müssen, bevor Gateways zugeordnet werden können, + wird für jede einzelne Änderung ein Alarm ausgelöst. Unter "Details" wird dann die jeweilige Aktion zur Anpassung im Firewall Orchestrator zur Ausführung angeboten. + Dabei ist zu berücksichtigen, dass Managements zuerst angelegt werden müssen, bevor Gateways zugeordnet werden können, bzw. dass Gateways gelöscht oder deaktiviert sein müssen bevor die entsprechende Aktion mit dem übergeordneten Management erfolgen kann. - Deshalb können vorgeschlagene Aktionen deaktiviert sein, dann bitte zuerst die vorausgesetzten Aktionen durchführen. + Deshalb können vorgeschlagene Aktionen deaktiviert sein, dann bitte zuerst die vorausgesetzten Aktionen durchführen. Beim Anlegen eines Managements oder Gateways wird automatisch geprüft, ob dieses schon vorhanden ist, und dann nur reaktiviert zu werden braucht. Bei nicht mehr vorhandenen Managements oder Gateways werden die Alternativen Deaktivieren oder vollständiges Löschen angeboten (bei letzterem werden auch alle importierten Daten entfernt!). '); @@ -4057,7 +6807,7 @@ INSERT INTO txt VALUES ('H7105', 'English', 'Whenever an Default settings (by the administrator). '); INSERT INTO txt VALUES ('H7252', 'German', 'Beispieldaten (erkennbar an den Endungen auf "_demo") sollten nur in einer initialen Kennenlernphase des Firewall Orchestrator-Systems genutzt werden. - In Produktivumgebung sollten sie nicht mehr vorkommen. Deshalb wird das System darauf geprüft und gegebenenfalls ein Alarm ausgelöst. Im Protokoll wird aufgeführt, in welchen Datenbereichen + In Produktivumgebung sollten sie nicht mehr vorkommen. Deshalb wird das System darauf geprüft und gegebenenfalls ein Alarm ausgelöst. Im Protokoll wird aufgeführt, in welchen Datenbereichen (Managements, Mandanten, Nutzer oder Gruppen) Beispieldaten gefunden wurden. '); INSERT INTO txt VALUES ('H7252', 'English', 'Sample data (defined by the ending "_demo") should only be used in an initial learning phase of the Firewall Orchestrator system. @@ -4147,6 +6897,49 @@ INSERT INTO txt VALUES ('H7401', 'German', 'Hier werden alle Nachrichten, die al INSERT INTO txt VALUES ('H7401', 'English', 'All messages are listed here, which have been displayed for the respective user. The messages can be seen only by the user itself, except system errors which have raised an alert to be handled by the administrators. '); +INSERT INTO txt VALUES ('H7411', 'German', 'Diese Seite zeigt Verbindungen pro Owner und deren App Rollen, App Server, Netzwerkbereiche, Service Gruppen und Services. + Wählen Sie zuerst einen Owner, um die zugehörigen Einträge anzuzeigen. +'); +INSERT INTO txt VALUES ('H7411', 'English', 'This page shows connections per owner and their app roles, app servers, network areas, service groups and services. + Select an owner first to display the related entries. +'); +INSERT INTO txt VALUES ('H7412', 'German', 'Mit "Nur Verwaiste anzeigen" werden alle verwaisten Einträge des Owners angezeigt. + Die Auswahlfelder werden ausgeblendet und nur die betroffene Seite (Quelle oder Ziel) bleibt gefüllt. + Als verwaist gelten Objekte, die in Verbindungen angelegt aber durch eine genutzte Schnittstelle nicht mehr sichtbar sind. Diese Konstellation sollte mit neueren Versionen nicht mehr erzeugt werden können. +'); +INSERT INTO txt VALUES ('H7412', 'English', 'With "Show orphaned only" all orphaned entries of the owner are listed. + The selection fields are hidden and only the affected side (source or destination) remains filled. + Orphaned are objects that are appended to connections but not visible any more due to the use of an interface. The creation of this constellation should be suppressed in newer versions. +'); +INSERT INTO txt VALUES ('H7413', 'German', 'Die Tabellen sind in Abschnitte gegliedert. Über die Aktionsspalte können verwaiste Einträge aus der Verbindung entfernt werden. +'); +INSERT INTO txt VALUES ('H7413', 'English', 'The tables are grouped in sections. Use the action column to remove orphaned entries from the connection. +'); + +INSERT INTO txt VALUES ('H7421', 'German', 'Diese Seite zeigt alle angeforderten Schnittstellen mit beantragender und angefragter Applikation, Ticket, Status und Erstellungsdatum. + Zusätzlich zeigt die Spalte "Verwendet in Verbindungs-IDs", in welchen bestehenden Verbindungen die Schnittstelle bereits referenziert wird. + Über die Aktionsspalte können Schnittstellendetails und das zugehörige Ticket angezeigt werden. + Bei offenen Vorgängen erscheint auch eine Schaltfläche zur regulären Ablehnung des Antrags als Admin mit dem üblichen Fenster. +'); +INSERT INTO txt VALUES ('H7421', 'English', 'This page shows all requested interfaces together with requesting and requested application, ticket, state and creation date. + In addition, the column "Used In Connection Ids" shows in which existing connections the interface is already referenced. + The action column can be used to display interface details and the corresponding ticket. + For open items, a button is also shown for the regular rejection of the request by an admin using the usual popup. +'); +INSERT INTO txt VALUES ('H7422', 'German', 'Mit dem Statusfilter kann die Liste auf einen konkreten Ticketzustand oder auf alle offenen Vorgänge eingeschränkt werden. + Die Option "Gelöschte angeforderte Schnittstellen anzeigen" blendet stattdessen gelöschte Schnittstellen ein, damit deren ursprüngliche Anfragen nachvollzogen und bereinigt werden können. +'); +INSERT INTO txt VALUES ('H7422', 'English', 'The state filter can be used to restrict the list to one concrete ticket state or to all open items. + The option "Show removed requested interfaces" shows deleted interfaces instead, so their original requests can still be reviewed and cleaned up. +'); +INSERT INTO txt VALUES ('H7423', 'German', 'Wenn entfernte angeforderte Schnittstellen noch offene Tickets besitzen, kann der Administrator diese gesammelt als abgelehnt schliessen.'); +INSERT INTO txt VALUES ('H7423', 'English', 'If deleted requested interfaces still have open tickets, the administrator can close those tickets together as rejected.'); +INSERT INTO txt VALUES ('H7424', 'German', 'Die Schaltfläche "Offene Tickets zu gelöschten angeforderten Schnittstellen" öffnet eine separate Liste aller noch offenen New-Interface-Tickets, deren angeforderte Schnittstelle nicht mehr existiert. + Die Prüfung erfolgt erst beim Öffnen des Fensters und ist damit unabhängig von der aktuell angezeigten Tabellenfilterung. +'); +INSERT INTO txt VALUES ('H7424', 'English', 'The button "Open tickets for deleted requested interfaces" opens a separate list of all still open new-interface tickets whose requested interface does not exist anymore. + The check is performed only when opening the popup, so it is independent from the current table filter. +'); INSERT INTO txt VALUES ('H8001', 'German', 'Das Workflow-Modul soll die Zusammenarbeit mehrerer beteiligter Akteure bei Arbeitsabläufen im Umfeld der Netzwerkadministration unterstützen. Um eine möglichst grosse Vielzahl von Workflows abbilden zu können, werden diverse Konfigurationsmöglichkeiten angeboten. @@ -4164,26 +6957,26 @@ INSERT INTO txt VALUES ('H8011', 'English', 'Ob Based on the request tasks, one or more implementation tasks can be generated automatically or manually, which reflect the technical realization of the request. To each of these 4 object types there is a state assigned. '); -INSERT INTO txt VALUES ('H8012', 'German', 'Phasen und Rollen: Die Bearbeitung der Aufträge ist in Phasen unterteilt, welche an Rollen gebunden sind. +INSERT INTO txt VALUES ('H8012', 'German', 'Phasen und Rollen: Die Bearbeitung der Aufträge ist in Phasen unterteilt, welche an Rollen gebunden sind. Bei der Konfiguration des Workflows wird festgelegt, welche Phasen für die jeweiligen Tasktypen überhaupt verwendet werden. '); INSERT INTO txt VALUES ('H8012', 'English', 'Phases and Roles: Processing of the requests is divided into several phases, which are bound to roles. During configuration it has to be defined, which of the phases are used for the respective task types. '); -INSERT INTO txt VALUES ('H8013', 'German', 'Stati: Bei der Konfiguration des Workflows können Stati frei definiert und benannt werden. - Durch geeignete Wahl der Nummernkreise werden diese in den verschiedenen Phasen sichtbar bzw. bearbeitbar. +INSERT INTO txt VALUES ('H8013', 'German', 'Status: Bei der Konfiguration des Workflows können Werte für; den Status frei definiert und benannt werden. + Durch geeignete Wahl der Nummernkreise werden diese in den verschiedenen Phasen sichtbar bzw. bearbeitbar. '); INSERT INTO txt VALUES ('H8013', 'English', 'States: During configuration of the workflow, states can be defined and named freely. They become visible and processable in the different phases by choosing the appropriate number ranges. '); -INSERT INTO txt VALUES ('H8014', 'German', 'Aktionen: Um die Bearbeitung der Aufträge zu unterstützen, können Aktionen verschiedener Typen definiert werden. +INSERT INTO txt VALUES ('H8014', 'German', 'Aktionen: Um die Bearbeitung der Aufträge zu unterstützen, können Aktionen verschiedener Typen definiert werden. Dazu gehören automatische Status-Weiterleitungen oder das Anfordern weiterer Genehmigungen. Auch die Konfiguration für Aufrufe externer Komponenten ist vorgesehen. '); INSERT INTO txt VALUES ('H8014', 'English', 'Actions: To support processing of the requests, different kinds of actions can be defined. This includes automatic state forwarding or the request of further approvals. Also configuration of calls to external components is in preparation. '); INSERT INTO txt VALUES ('H8101', 'German', 'Das Workflow-Modul operiert mit 4 verschiedenen Objekttypen, welche der Statusbehandlung unterliegen. - Entsprechend der Objekthierarchie sind die Stati voneinander abhängig. + Entsprechend der Objekthierarchie sind die Status voneinander abhängig. '); INSERT INTO txt VALUES ('H8101', 'English', 'The workflow module operates on 4 different object types which are subject to state handling. According to the object hierarchy their states are interdependent. @@ -4192,7 +6985,7 @@ INSERT INTO txt VALUES ('H8111', 'German', 'Ticket: Bildet die Klammer für INSERT INTO txt VALUES ('H8111', 'English', 'Ticket: Serves as a clamp around one or more functional (request) tasks. Fields are:'); INSERT INTO txt VALUES ('H8112', 'German', 'Titel: Pflichtfeld zur Kennzeichnung des Antrags.'); INSERT INTO txt VALUES ('H8112', 'English', 'Title: Mandatory field to identify the request'); -INSERT INTO txt VALUES ('H8113', 'German', 'Status: Der Ticket-Status wird in der ersten Phase vom Antragssteller gesetzt, in späteren Phasen aus den Stati der fachlicher Aufträge ermittelt.'); +INSERT INTO txt VALUES ('H8113', 'German', 'Status: Der Ticket-Status wird in der ersten Phase vom Antragssteller gesetzt, in späteren Phasen aus den Status der fachlicher Aufträge ermittelt.'); INSERT INTO txt VALUES ('H8113', 'English', 'State: The ticket state is set in the first phase by the requester, in later phases it is computed from the states of the request tasks.'); INSERT INTO txt VALUES ('H8114', 'German', 'Antragsteller: Wird automatisch beim Anlegen des Tickets auf den erzeugenden Nutzer gesetzt.'); INSERT INTO txt VALUES ('H8114', 'English', 'Requester: Is automatically set to the requesting user at ticket creation time.'); @@ -4225,7 +7018,7 @@ INSERT INTO txt VALUES ('H8137', 'English', 'Reason: Serves for a more detailled INSERT INTO txt VALUES ('H8138', 'German', 'Kommentare: In den Phasen Genehmigung und Planung können Kommentare zu dem fachlichen Auftrag hinzugefügt werden. Sie werden mit Datum und Autor aufgelistet und können nicht gelöscht werden.'); INSERT INTO txt VALUES ('H8138', 'English', 'Comments: In the approval and planning phase comments can be added to the request task. They are listed with date and author an can not be deleted.'); INSERT INTO txt VALUES ('H8139', 'German', 'Start: Hier wird automatisch ein Zeitstempel eingetragen, sobald der Auftrag das erste mal nach der Genehmigung angefasst wird. - Falls aktiviert, kann dies den Beginn der Planungsphase markieren, ansonsten wird hier der Beginn der ersten Implementierung widergespiegelt. + Falls aktiviert, kann dies den Beginn der Planungsphase markieren, ansonsten wird hier der Beginn der ersten Implementierung widergespiegelt. '); INSERT INTO txt VALUES ('H8139', 'English', 'Start: Here the timestamp of the first change after approval is set. If activated, this can mark the beginning of the planning phase, else the start of the first implementation is indicated. @@ -4253,19 +7046,19 @@ INSERT INTO txt VALUES ('H8158', 'English', 'Start: Here the timestamp of the fi INSERT INTO txt VALUES ('H8159', 'German', 'Stop: Wird bei Bearbeitung in der Implementierungsphase ein Status im Ausgangsbereich erreicht, wird hier der aktuelle Zeitstempel gesetzt. '); INSERT INTO txt VALUES ('H8159', 'English', 'Stop: When reaching a state in the exit range, the actual timestamp is set.'); INSERT INTO txt VALUES ('H8171', 'German', 'Genehmigungen werden als eigenständige Objekte dem fachlichen Auftrag zugeordnet. Ein Auftrag gilt dann als genehmigt, wenn alle zugeordneten Einzelgenehmigungen den entsprechenden Status aufweisen. - Eine Genehmigung enthält folgende Felder: + Eine Genehmigung enthält folgende Felder: '); INSERT INTO txt VALUES ('H8171', 'English', 'Approvals are associated to the functional (request) task as separate objects. A request task is regarded as approved, if all related single approvals have the approprioate state. An approval contains the following fields: '); INSERT INTO txt VALUES ('H8172', 'German', 'Geöffnet: Zeitstempel des Anlegens der Genehmigung.'); INSERT INTO txt VALUES ('H8172', 'English', 'Opened: Timestamp of the approval creation.'); -INSERT INTO txt VALUES ('H8173', 'German', 'Deadline: Beim Anlegen der Genehmigung wird automatisch eine Deadline gesetzt. +INSERT INTO txt VALUES ('H8173', 'German', 'Deadline: Beim Anlegen der Genehmigung wird automatisch eine Deadline gesetzt. Diese wird beim Anlegen des Auftrags aus der Priorität des Tickets (Einstellungen) ermittelt. - Beim Anfordern weiterer Genehmigungen über Aktionen kann in dessen Parametern ebenfalls eine Deadline gesetzt werden. - Der Wert 0 hat dabei zur Folge, dass keine Deadline gesetzt wird. + Beim Anfordern weiterer Genehmigungen über Aktionen kann in dessen Parametern ebenfalls eine Deadline gesetzt werden. + Der Wert 0 hat dabei zur Folge, dass keine Deadline gesetzt wird. '); -INSERT INTO txt VALUES ('H8173', 'English', 'Deadline: During approval creation a deadline is set automatically. +INSERT INTO txt VALUES ('H8173', 'English', 'Deadline: During approval creation a deadline is set automatically. It is computed from the ticket priority at task creation time (Customizing). The requesting of new approvals via Actions also allows setting of a deadline in the parameters. The value 0 results in setting no deadline. @@ -4279,14 +7072,14 @@ INSERT INTO txt VALUES ('H8176', 'English', 'Approver: The user setting the stat INSERT INTO txt VALUES ('H8177', 'German', 'Status: Status der Genehmigung.'); INSERT INTO txt VALUES ('H8177', 'English', 'State: State of the approval.'); INSERT INTO txt VALUES ('H8178', 'German', 'Kommentare: Nach dem Anlegen einer Genehmigung bis zur erfolgten Genehmigung können Kommentare hinzugefügt werden. - Dies ist über eine Schaltfläche in der Genehmigungsübersicht oder beim Statusübergang (z.B. Ablehnung) selbst möglich. - Die Kommentare werden mit Datum und Autor aufgelistet und können nicht gelöscht werden. + Dies ist über eine Schaltfläche in der Genehmigungsübersicht oder beim Statusübergang (z.B. Ablehnung) selbst möglich. + Die Kommentare werden mit Datum und Autor aufgelistet und können nicht gelöscht werden. '); INSERT INTO txt VALUES ('H8178', 'English', 'Comments: After creation of an approval until it is committed comments can be added. This can be done via a button in the approval overview or during state transition (e.g. reject). Comments are listed with date and author an can not be deleted. '); -INSERT INTO txt VALUES ('H8201', 'German', 'Je nach Art der beantragten Aufgaben können verschiedene Workflow-Varianten erforderlich sein. +INSERT INTO txt VALUES ('H8201', 'German', 'Je nach Art der beantragten Aufgaben können verschiedene Workflow-Varianten erforderlich sein. Dies wird in den Tasktypen abgebildet, welche separat die jeweils nötigen Felder anbieten und in verschiedenen Workflows konfiguriert werden können. Die für die Nutzer verfügbaren Tasktypen werden in den Einstellungen freigeschaltet. '); @@ -4296,7 +7089,7 @@ INSERT INTO txt VALUES ('H8201', 'English', 'Depending on the kind of the reques '); INSERT INTO txt VALUES ('H8211', 'German', 'Generisch: Eine einfache Variante, in der die beauftragte Tätigkeit in einem Freitextfeld beschrieben wird.'); INSERT INTO txt VALUES ('H8211', 'English', 'Generic: A basic variant, where the requested activity is described in a free text field.'); -INSERT INTO txt VALUES ('H8212', 'German', 'Zugriff: Es wird eine Reihe von Feldern angeboten, die für einen Antrag auf Netzwerkzugriff nötig sind. +INSERT INTO txt VALUES ('H8212', 'German', 'Zugriff: Es wird eine Reihe von Feldern angeboten, die für einen Antrag auf Netzwerkzugriff nötig sind. Dazu gehören zwingend Angaben zu Quelle, Ziel und Dienst, Aktion, Regel-Aktion, Logging. Bei entsprechender Konfiguration (keine Planungsphase, "Gerät im Antrag eingeben" in Einstellungen) müssen auch die betroffenen Gateways selektiert werden. Hinzu kommen optionale Angaben wie Gültigkeitszeitraum und Grund. @@ -4306,8 +7099,24 @@ INSERT INTO txt VALUES ('H8212', 'English', 'Access: Several fields are offered, In case of the respective configuration (no planning phase, "Enter device in request" in Customizing) also the affected devices have to be selected. Additionally there are optional specifications like validity range and reason. '); -INSERT INTO txt VALUES ('H8213', 'German', 'Die weiteren vorgesehenen Tasktypen "Gruppe anlegen", "Gruppe ändern" und "Gruppe löschen" können zwar aktiviert und genutzt werden, sind aber noch nicht mit spezifischen Feldern versehen.'); -INSERT INTO txt VALUES ('H8213', 'English', 'Further task types "create group", "modify group" and "delete group" can be activated and used, but are not equipped with specific fields yet.'); +INSERT INTO txt VALUES ('H8213', 'German', 'Die weiteren vorgesehenen Tasktypen "Gruppe ändern" und "Gruppe löschen" können zwar aktiviert und genutzt werden, sind aber noch nicht mit spezifischen Feldern versehen.'); +INSERT INTO txt VALUES ('H8213', 'English', 'Further task types "modify group" and "delete group" can be activated and used, but are not equipped with specific fields yet.'); +INSERT INTO txt VALUES ('H8214', 'German', 'Regel löschen: Hier muss zwingend das Gateway und die Uid der zu löschenden Regel eingegeben werden. + Diese wird gegen die tatsächlich auf dem Gateway vorhandenen Uids geprüft.
          + Dieser Auftragstyp wird auch bei der automatischen Erzeugung aus dem Unbenutzte-Regel-Report bzw. bei der Dezertifizierung verwendet. +'); +INSERT INTO txt VALUES ('H8214', 'English', 'Delete Rule: Mandatory input fields are the gateway and the Uid of the rule to be deleted. + The Uid is checked against the rules actually existing on the gateway.
          + This Task Type is also used for the automatic creation of delete requests in the Unused Rules Report resp. in the decertification workflow. +'); +INSERT INTO txt VALUES ('H8215', 'German', 'Neue Schnittstelle: Dieser Tasktyp wird v.a. aus dem Modellierungsmodul heraus genutzt, um eine Schnittstelle von einem anderen Eigentämer zu beantragen. + Hier ist der beauftragte Eigentämer aus einer Liste auszuwählen. Die weiteren Details der Schnittstelle werden im Modellierungsmodul gehalten. +'); +INSERT INTO txt VALUES ('H8215', 'English', 'New Interface: This task type is primarily used by the Modelling module to order a new interface from another owner. + Here the appointed owener has to be selected from a list. Further details of the interface are handled in the Modelling module. +'); +INSERT INTO txt VALUES ('H8216', 'German', 'Gruppe anlegen: Um Netzwerkgruppen zu beantragen, mässen der Gruppenname und eine Liste der zugehärigen IP-Adressen bzw. IP-Adress-Bereichen angegeben werden.'); +INSERT INTO txt VALUES ('H8216', 'English', 'Create group: To order network groups, the group name and a list of associated IP addresses resp. IP ranges have to be inserted.'); INSERT INTO txt VALUES ('H8301', 'German', 'Jeder Verarbeitungsschritt kann nur von Nutzern mit entsprechenden Rollen getätigt werden. Dabei können einzelnen Nutzern auch mehrere Rollen zufallen. Die Rollen können individuell oder über Gruppenzugehörigkeit zugewiesen werden. Hinzu kommt die Rolle des admin, welche einen Komplettzugriff erlaubt. Je nach Rolle des Bearbeiters sind nur die für ihn relevanten Teile der folgenden Rubriken sichtbar. @@ -4316,15 +7125,15 @@ INSERT INTO txt VALUES ('H8301', 'English', 'Each processing step can only be do Although, single users can be in possession of several roles. Roles can be assigned individually or via group membership. Additionally there is the role of the admin, who has always full access. Depending on the roles of the user, only the relevant parts of the following chapters are visible. '); -INSERT INTO txt VALUES ('H8311', 'German', 'Ticket-Liste (Rolle: requester, fw-admin): +INSERT INTO txt VALUES ('H8311', 'German', 'Ticket-Liste (Rolle: requester, fw-admin): Dem Antragsteller steht eine Übersicht über alle von ihm selbst angelegten Tickets aller Bearbeitungsstufen zur Verfügung. Der fw-admin kann hier alle Tickets sehen. Änderungen an den Tickets sind in dieser Ansicht nicht möglich. '); INSERT INTO txt VALUES ('H8311', 'English', 'Ticket List (Role: requester, fw-admin): The requester gets an overview of all tickets in all processing states created by himself. The fw-admin has view on all tickets. - Changes on the tickets are not possible in this view. + Changes on the tickets are not possible in this view. '); -INSERT INTO txt VALUES ('H8312', 'German', 'Antrag stellen (Rolle: requester), voreingestellt: +INSERT INTO txt VALUES ('H8312', 'German', 'Antrag stellen (Rolle: requester), voreingestellt: Anträge können nur von Nutzern mit entsprechenden Rechten gestellt werden, definiert durch die Rolle (weitere Einschränkungen auf die Eigentümerschaft ist in späteren Versionen vorgesehen). Solange noch kein Status des Ausgangsbereichs erreicht wurde, können Tickets beliebig geändert und fachliche Aufträge angehängt, geändert oder gelöscht werden. Um Inkonsistenzen zu vermeiden, werden angelegte Aufträge erst beim ersten Speichern des Tickets mit erzeugt. Vorher sind sie nur lokal vorhanden und gehen beim Abbruch der Antragstellung verloren. @@ -4336,9 +7145,9 @@ INSERT INTO txt VALUES ('H8312', 'English', 'Create ticket (Role: requester), pr To avoid inconsistencies, already built request tasks are created with the first saving of the ticket. Before, they exist only locally and get lost on cancellation of ticket creation. In later phases no changes of the ticket and request tasks contents are possible, only changes on metadata like state, start and stop, as well as adding comments can be done. '); -INSERT INTO txt VALUES ('H8313', 'German', 'Genehmigungen (Rolle: approver), voreingestellt: +INSERT INTO txt VALUES ('H8313', 'German', 'Genehmigungen (Rolle: approver), voreingestellt: Der Workflow kann einen verpflichtenden Genehmigungsschritt vorsehen, bevor der Antrag weiter bearbeitet werden kann (Status-Matrix). - Beim erstmaligen Speichern des Antrags wird automatisch pro Auftrag ein Genehmigungsobjekt angelegt. + Beim erstmaligen Speichern des Antrags wird automatisch pro Auftrag ein Genehmigungsobjekt angelegt. Konfigurierbar über Aktionen können in beliebigen Phasen weitere Genehmigungen angefordert werden. Der Genehmiger kann das Ticket und die Aufträge nicht mehr inhaltlich verändern, lediglich einen neuen Status setzen und Kommentare hinzufügen. Hinzu kommen gegebenenfalls weitere vorkonfigurierte eingeblendete Aktionen. @@ -4352,7 +7161,7 @@ INSERT INTO txt VALUES ('H8313', 'English', 'Approvals (Role: approver), presele Additionally there may be further preconfigured shown actions. A request task counts as approved, if all single approvals have reached the appropriate state. Henceforward the approver can not perform changes anymore. '); -INSERT INTO txt VALUES ('H8314', 'German', 'Planungen (Rolle: planner, fw-admin), optional: +INSERT INTO txt VALUES ('H8314', 'German', 'Planungen (Rolle: planner, fw-admin), optional: Im Workflow kann vorgesehen werden, dass die Implementierungs-Aufträge aus den fachlichen Aufträgen manuell von einem Planer erzeugt werden. Ist diese Phase aktiviert, greift die automatische Erzeugung der Implementierungs-Aufträge nicht (Einstellungen). Stattdessen kann der Planer beliebige Implementierungs-Aufträge erzeugen, editieren und löschen. @@ -4361,7 +7170,7 @@ INSERT INTO txt VALUES ('H8314', 'German', 'Planungen (Rolle: planner, fw-admin Zum Überprüfen, für welche der bei der Pfadanalyse gefundenen Geräte bereits Implementierungs-Aufträge angelegt sind, zum automatischen Anlegen von Implementierungs-Aufträgen für alle der bei der Pfadanalyse gefundenen Geräte (soweit noch nicht vorhanden), sowie zum Löschen aller vorhandenen Implementierungs-Aufträge. - Die fachlichen Aufträge können in dieser Phase auch anderen Nutzern oder Gruppen zugewiesen werden. + Die fachlichen Aufträge können in dieser Phase auch anderen Nutzern oder Gruppen zugewiesen werden. Bei Betätigen der entsprechenden Schaltfläche erscheint eine Auswahlliste aller Nutzer und internen Gruppen, welche den notwendigen Rollen für diese Planungsphase besitzen. Wurde einem selbst auf diese Weise der Auftrag zugewiesen, wird auch eine Option zum direkten Zurückzuweisen angeboten. '); @@ -4373,15 +7182,15 @@ INSERT INTO txt VALUES ('H8314', 'English', 'Plannings (Role: planner, fw-admin) For the handling of access requests further path analysis functions are offered (if activated in Customizing): To check, for which of the found devices of the path analysis there are already implementation tasks existing, to create automatically implemntation tasks for all devices found in path analysis (if not already existing), - as well as to delete all existing implementation tasks. + as well as to delete all existing implementation tasks. The request tasks can also be assigned to other users or groups in this phase. After pushing the respective button a selection list appears with all users and groups, which own the necessary roles for the planning phase. If the task had been assigned to oneself this way, an option for direct assigning back is shown. '); -INSERT INTO txt VALUES ('H8315', 'German', 'Implementierungen (Rolle: implementer, fw-admin), voreingestellt: +INSERT INTO txt VALUES ('H8315', 'German', 'Implementierungen (Rolle: implementer, fw-admin), voreingestellt: Hier wird die technische Umsetzung der einzelnen Aufträge unterstützt und dokumentiert. Die fachlichen Aufträge sind im Ticket nicht sichtbar, lediglich die Implementierungs-Aufträge. In der Übersicht können für den Nutzer auch statt der Tickets direkt alle Implementierungs-Aufträge oder nur die Implementierungs-Aufträge für ein Gerät dargestellt werden. - Die Implementierungs-Aufträge können in dieser Phase auch anderen Nutzern oder Gruppen zugewiesen werden. + Die Implementierungs-Aufträge können in dieser Phase auch anderen Nutzern oder Gruppen zugewiesen werden. Bei Betätigen der entsprechenden Schaltfläche erscheint eine Auswahlliste aller Nutzer und internen Gruppen, welche den notwendigen Rollen für Implementierungsphase besitzen. Wurde einem selbst auf diese Weise der Auftrag zugewiesen, wird auch eine Option zum direkten Zurückzuweisen angeboten. '); @@ -4392,20 +7201,20 @@ INSERT INTO txt VALUES ('H8315', 'English', 'Implementations (Role: implementer, After pushing the respective button a selection list appears with all users and groups, which own the necessary roles for the implementation phase. If the task had been assigned to oneself this way, an option for direct assigning back is shown. '); -INSERT INTO txt VALUES ('H8316', 'German', 'Reviews (Rolle: reviewer), optional: +INSERT INTO txt VALUES ('H8316', 'German', 'Reviews (Rolle: reviewer), optional: Abschliessend kann der Workflow einen Review-Schritt vorsehen, um die Umsetzung des Antrags zu überprüfen. Dazu werden die Tickets mitsamt der Implementierungs-Aufträge dargestellt. '); -INSERT INTO txt VALUES ('H8316', 'English', 'Reviews (Role: reviewer), optional: +INSERT INTO txt VALUES ('H8316', 'English', 'Reviews (Role: reviewer), optional: Finally the workflow can contain a review phase to check the implementation of the request. Therefore the tickets are displayed with their implementation tasks. '); INSERT INTO txt VALUES ('H8317', 'German', 'Weitere Phasen zum Verifizieren und Rezertifizieren sind vorbereitet, aber noch nicht implementiert.'); INSERT INTO txt VALUES ('H8317', 'English', 'Further phases for verification and recertification are prepared but not implemented yet.'); -INSERT INTO txt VALUES ('H8401', 'German', 'Stati und deren Übergänge bilden die Basis der Workflows. Bei der Konfiguration können sie frei definiert und benannt werden (Statusdefinitionen). - Durch geeignete Wahl der Nummernkreise werden die Stati dann in den verschiedenen Phasen sichtbar bzw. benutzbar, was in den Status-Matrizen definiert wird. - In einer Status-Matrix werden pro Phase alle vorkommenden Stati mitsamt den möglichen Statusübergängen festgelegt. +INSERT INTO txt VALUES ('H8401', 'German', 'Status und deren Übergänge bilden die Basis der Workflows. Bei der Konfiguration können sie frei definiert und benannt werden (Statusdefinitionen). + Durch geeignete Wahl der Nummernkreise werden die Status dann in den verschiedenen Phasen sichtbar bzw. benutzbar, was in den Status-Matrizen definiert wird. + In einer Status-Matrix werden pro Phase alle vorkommenden Status mitsamt den möglichen Statusübergängen festgelegt. Ausserdem werden drei Bereiche bestimmt: Eingangs-, Bearbeitungs- und Ausgangsbereich, welche für die Bearbeitbarkeit in der jeweiligen Phase entscheidend sind. Für das Ticket und jeden einzelnen Tasktypen werden separate Status-Matrizen angelegt, so dass sich deren Workflows unterscheiden können. - Auch müssen hier die Beziehungen der Stati der verschiedenen Objekttypen zueinander festgelegt werden. + Auch müssen hier die Beziehungen der Status der verschiedenen Objekttypen zueinander festgelegt werden. '); INSERT INTO txt VALUES ('H8401', 'English', 'States and their transitions are the basis of the workflows. During configuration they can be defined and named freely (State Definitions). Appropriate selection of number ranges make the states visible and usable in the different phases, which is defined in State Matrices. @@ -4416,7 +7225,7 @@ INSERT INTO txt VALUES ('H8401', 'English', 'States and their transitions are th '); INSERT INTO txt VALUES ('H8501', 'German', 'Die Aktionen der verschiedenen Typen dienen der Unterstützung und Automatisierung der Bearbeitung der Aufträge. Dazu gehören automatische Status-Weiterleitungen, das Anfordern weiterer Genehmigungen oder das Auslösen eines Alarms. Auch die Konfiguration für Aufrufe externer Komponenten ist vorgesehen. - Aktionen sind an Bedingungen gebunden und werden bestimmten Stati zugewiesen (Aktionen anlegen). + Aktionen sind an Bedingungen gebunden und werden bestimmten Status zugewiesen (Aktionen anlegen). Sie bewirken bei Eintreffen der Bedingungen entweder eine automatische Ausführung oder das Aufblenden einer Schaltfläche zur manuellen Ausführung. Bislang stehen folgende Aktionen zur Auswahl: '); @@ -4427,14 +7236,14 @@ INSERT INTO txt VALUES ('H8501', 'English', 'Actions of different types provide Currently following actions can be selected: '); INSERT INTO txt VALUES ('H8511', 'German', 'Autom. Weiterleitung: Obwohl die Statusweiterleitung mit dem Mechanismus der Status-Matrix weitgehend abgebildet werden kann, erweitert diese Aktion die Möglichkeiten. - So kann die Weiterleitung stärker auf bestimmte Objekttypen eingeschränkt werden (die Status-Matrix gilt für alle Objekte eines Tasktyps). - Auch ein Aufblenden einer speziellen Weiterleitung als "Shortcut" kann erwünscht sein. + So kann die Weiterleitung stärker auf bestimmte Objekttypen eingeschränkt werden (die Status-Matrix gilt für alle Objekte eines Tasktyps). + Auch ein Aufblenden einer speziellen Weiterleitung als "Shortcut" kann erwünscht sein. '); INSERT INTO txt VALUES ('H8511', 'English', 'Auto-forward: Although state forwarding can widely be realized by the state matrix mechanism, this action enlarges the options. The forwarding can be more restricted to dedicated object types (the state matrix is valid for all object types within a task type). Additionally the display of a special state transition as "Shortcut" may be desired. '); -INSERT INTO txt VALUES ('H8512', 'German', 'Genehmigung hinzufügen: Wenn im Verlauf des Workflows (z.B. vom Planer) festgestellt wird, dass weitere Genehmigungen eingeholt werden müssen, +INSERT INTO txt VALUES ('H8512', 'German', 'Genehmigung hinzufügen: Wenn im Verlauf des Workflows (z.B. vom Planer) festgestellt wird, dass weitere Genehmigungen eingeholt werden müssen, kann man mit dieser Aktion weitere Genehmigungsobjekte erzeugen und zuweisen. '); INSERT INTO txt VALUES ('H8512', 'English', 'Add approval: If in the course of the workflow it is realized (e.g. by the planner) that further approvals are necessary, @@ -4443,21 +7252,33 @@ INSERT INTO txt VALUES ('H8512', 'English', 'Add approval: If in the course of t INSERT INTO txt VALUES ('H8513', 'German', 'Alarm auslösen: Unter Umständen kann eine gezielte Alarmierung in einem Workflow nützlich sein (z.B. durch den Reviewer nach einer festgestellten Fehlimplementierung).'); INSERT INTO txt VALUES ('H8513', 'English', 'Set alert: Possibly a specific alerting within a workflow may be useful (e.g. by the reviewer in case of a wrong or dangerous implementaion).'); INSERT INTO txt VALUES ('H8514', 'German', 'Externer Aufruf: Aufrufe externer Komponenenten bieten ein weites Spektrum von Erweiterungs- und Integrationsmöglichkeiten, die stark vom Systemumfeld abhängen. - Hier sind für kommende Releases die Anknüpfungspunkte für Erweiterungen vorgesehen. + Hier sind für kommende Releases die Anknüpfungspunkte für Erweiterungen vorgesehen. '); INSERT INTO txt VALUES ('H8514', 'English', 'External call: Calls to external components provide a wide range of extension or integration possibilities, which strongly depend on the system environment. Here connecting factors for extensions future releases are planned. '); INSERT INTO txt VALUES ('H8515', 'German', 'Pfadanalyse: Die in der automatischen Pfadanalyse gefundenen Geräte werden als Liste der Geräte eines Zugriffs-Auftrags übernommen oder in einem eigenen Fenster dargestellt.'); INSERT INTO txt VALUES ('H8515', 'English', 'Path Analysis: The devices found in the automatic path analysis are transferred to the list of devices of a request task or displayed in an own window.'); +INSERT INTO txt VALUES ('H8516', 'German', 'Email verschicken: Es können Emails mit vorgegebenen Betreff und Inhalt an alle im Workflow bekannten Akteure (Antragsteller, Genehmiger, letzter Kommentator...) geschickt werden.'); +INSERT INTO txt VALUES ('H8516', 'English', 'Send Email: Emails with self defined subject an body can be sent to all known actors in the workflow (requester, approver, last commenter...).'); +INSERT INTO txt VALUES ('H8517', 'German', 'Verbindung anlegen: TBD.'); +INSERT INTO txt VALUES ('H8517', 'English', 'Create Connection: TBD.'); +INSERT INTO txt VALUES ('H8518', 'German', 'Verbindungseigentümer ändern: Der Eigentümer einer Verbindung im Modellierungsmodul kann angepasst werden.'); +INSERT INTO txt VALUES ('H8518', 'English', 'Update Connection Owner: To adapt the owner of a connection in the Modelling module.'); +INSERT INTO txt VALUES ('H8519', 'German', 'Verbindung veröffentlichen: Dient der Veröffentlichung einer Verbindung (bzw. Schnittstelle) im Modellierungsmodul.'); +INSERT INTO txt VALUES ('H8519', 'English', 'Publish Connection: To publish a connection (resp. interface) in the Modelling module.'); +INSERT INTO txt VALUES ('H8520', 'German', 'Verbindung darstellen: Darstellen einer Verbindung/Schnittstelle aus dem Modellierungsmodul im Workflow-Kontext (nur lesend).'); +INSERT INTO txt VALUES ('H8520', 'English', 'Display Connection: Display a connection/interface of the Modelling module in workflow context (read only).'); +INSERT INTO txt VALUES ('H8521', 'German', 'Schnittstelle ablehnen: Ablehnen einer beantragten Schnittstelle im Modellierungsmodul.'); +INSERT INTO txt VALUES ('H8521', 'English', 'Reject Interface: Reject a requested interface of the Modelling module.'); INSERT INTO txt VALUES ('H8601', 'German', 'Zum Aufsetzen eines Workflows empfiehlt es sich, in folgenden Schritten vorzugehen: '); INSERT INTO txt VALUES ('H8701', 'German', 'Die folgenden Beispiele sollen ein Schlaglicht auf die verschiedenen Konfigurationsmöglichkeiten des Workflowmoduls werfen. - Sie können gleichzeitig oder voneinander unabhängig ausprobiert werden (mit Ausnahme von Beispiel 5, welches auf den in Beispiel 4 definierten Stati aufsetzt). - Es wurden hier englische Namen für Stati oder Aktionen gewählt (wie sie ja auch vorinstalliert sind), + Sie können gleichzeitig oder voneinander unabhängig ausprobiert werden (mit Ausnahme von Beispiel 5, welches auf den in Beispiel 4 definierten Status aufsetzt). + Es wurden hier englische Namen für Status oder Aktionen gewählt (wie sie ja auch vorinstalliert sind), eine beliebige Umbenennung (z. B. Übersetzung ins Deutsche) ist natürlich jederzeit und einfach möglich. '); INSERT INTO txt VALUES ('H8701', 'English', 'Following examples are intended to give an idea about the different configuration options of the workflow module. @@ -4490,12 +7311,12 @@ INSERT INTO txt VALUES ('H8701', 'English', 'Following examples are intended to INSERT INTO txt VALUES ('H8711', 'German', '

          1) Einfügen eines neuen Status in die Genehmigungsphase

          Dient zum Markieren von "geparkten" offenen Genehmigungen (nur zu erreichen von "In Approval" und zurück)
            -
          • Einstellungen -&gt; Statusdefinitionen -&gt; Status hinzufügen -&gt; Eingabe Id: 61 +
          • Einstellungen -&gt; Statusdefinitionen -&gt; Status hinzufügen -&gt; Eingabe Id: 61 (Nummer im Bereich zwischen niedrigstem Bearbeitungs- und niedrigstem Ausgangsstatus der Genehmigungsphase), Name: "Approval on Hold" -&gt; Speichern
          • Einstellungen -&gt; Statusmatrix -&gt; Typ auswählen: Master
            • Genehmigung: Erlaubte Übergänge: Status hinzufügen -&gt; "Approval on Hold" auswählen
            • -
            • Genehmigung: Erlaubte Übergänge: "Approval on Hold" bearbeiten -&gt; Status hinzufügen +
            • Genehmigung: Erlaubte Übergänge: "Approval on Hold" bearbeiten -&gt; Status hinzufügen -&gt; "Approval on Hold" auswählen -&gt; Status hinzufügen -&gt; "In Approval" auswählen -&gt; Ok
            • Genehmigung: Erlaubte Übergänge: "In Approval" bearbeiten -&gt; Status hinzufügen -&gt; "Approval on Hold" auswählen -&gt; Ok
            @@ -4504,7 +7325,7 @@ INSERT INTO txt VALUES ('H8711', 'German', '

            1) Einfügen eines neuen St
          • Einstellungen -&gt; Statusmatrix -&gt; Typ auswählen: Zugriff
            • Genehmigung: Erlaubte Übergänge: Status hinzufügen -&gt; "Approval on Hold" auswählen
            • -
            • Genehmigung: Erlaubte Übergänge: "Approval on Hold" bearbeiten -&gt; Status hinzufügen -&gt; "Approval on Hold" auswählen +
            • Genehmigung: Erlaubte Übergänge: "Approval on Hold" bearbeiten -&gt; Status hinzufügen -&gt; "Approval on Hold" auswählen -&gt; Status hinzufügen -&gt; "In Approval" auswählen -&gt; Ok
            • Genehmigung: Erlaubte Übergänge: "In Approval" bearbeiten -&gt; Status hinzufügen -&gt; "Approval on Hold" auswählen -&gt; Ok
            @@ -4515,7 +7336,7 @@ INSERT INTO txt VALUES ('H8711', 'German', '

            1) Einfügen eines neuen St INSERT INTO txt VALUES ('H8711', 'English', '

            1) Insert new state to approval phase

            Serves for marking of "parked" open approvals (only reachable from "In Approval" and back)
              -
            • Settings -&gt; State Definitions -&gt; Add State -&gt; Insert Id: 61 +
            • Settings -&gt; State Definitions -&gt; Add State -&gt; Insert Id: 61 (Id has to be in the range between lowest started state and lowest exit state of approval phase), Name: "Approval on Hold" -&gt; Save
            • Settings -&gt; State Matrix -&gt; Select Type: Master
                @@ -4536,30 +7357,30 @@ INSERT INTO txt VALUES ('H8711', 'English', '

                1) Insert new state to approval

              '); INSERT INTO txt VALUES ('H8712', 'German', '

              2) Rücksprung in vorherige Phase

              - Soll beispielsweise dem Genehmiger erlaubt werden, den Antrag an den Antragsteller zurückzuschicken, + Soll beispielsweise dem Genehmiger erlaubt werden, den Antrag an den Antragsteller zurückzuschicken, kann einfach in der Status-Matrix ein Übergang zu einem Status im Eingangsbeerich der Antragsphase eingetragen werden. Dann wird dieser Status beim Genehmigen automatisch als möglicher Zielstatus angezeigt. Zur leichteren Erkennung für den Antragsteller wird in diesem Beispiel in der anzuspringenden Phase ein weiterer Status definiert und in der Status-Matrix mit den erwünschten Statusübergängen versehen:
                -
              • Einstellungen -&gt; Statusdefinitionen -&gt; Status hinzufügen -&gt; Eingabe Id: 1, Name: "Back To Requester" -&gt; Speichern +
              • Einstellungen -&gt; Statusdefinitionen -&gt; Status hinzufügen -&gt; Eingabe Id: 1, Name: "Back To Requester" -&gt; Speichern (Nummer im Bereich zwischen niedrigstem Eingangs- und niedrigstem Bearbeitungsstatus der Request-Phase)
              • Einstellungen -&gt; Statusmatrix -&gt; Typ auswählen: Master
                • Antrag: Erlaubte Übergänge: Status hinzufügen -&gt; "Back To Requester" auswählen
                • -
                • Antrag: Erlaubte Übergänge: "Back To Requester" bearbeiten -&gt; Status hinzufügen -&gt; "Back To Requester" auswählen +
                • Antrag: Erlaubte Übergänge: "Back To Requester" bearbeiten -&gt; Status hinzufügen -&gt; "Back To Requester" auswählen -&gt; Status hinzufügene -&gt; "Requested" auswählen -&gt; Status hinzufügen -&gt; "Discarded" auswählen -&gt; Ok
                • Genehmigung: Erlaubte Übergänge: Status hinzufügen -&gt; "Back To Requester" auswählen
                -&gt; Statusmatrix: Speichern
              • -
              • Einstellungen -&gt; Statusmatrix -&gt; Typ auswählen: Zugriff +
              • Einstellungen -&gt; Statusmatrix -&gt; Typ auswählen: Zugriff
                • Antrag: Erlaubte Übergänge: Status hinzufügen -&gt; "Back To Requester" auswählen
                • -
                • Antrag: Erlaubte Übergänge: "Back To Requester" bearbeiten -&gt; Status hinzufügen -&gt; "Back To Requester" auswählen +
                • Antrag: Erlaubte Übergänge: "Back To Requester" bearbeiten -&gt; Status hinzufügen -&gt; "Back To Requester" auswählen -&gt; Status hinzufügen -&gt; "Requested" auswählen -&gt; Status hinzufügen -&gt; "Discarded" auswählen -&gt; Ok
                • Genehmigung: Erlaubte Übergänge: "In Approval" bearbeiten -&gt; Status hinzufügen -&gt; "Back To Requester" auswählen -&gt; Ok
                • Genehmigung: Erlaubte Übergänge: Status hinzufügen -&gt; "Back To Requester" auswählen
                • -
                • Genehmigung: Erlaubte Übergänge: "Back To Requester" bearbeiten -&gt; Status hinzufügen -&gt; "In Approval" auswählen -&gt; Status hinzufügen +
                • Genehmigung: Erlaubte Übergänge: "Back To Requester" bearbeiten -&gt; Status hinzufügen -&gt; "In Approval" auswählen -&gt; Status hinzufügen -&gt; "Approved" auswählen -&gt; Status hinzufügen -&gt; "Rejected" auswählen -&gt; Status hinzufügen -&gt; "Back To Requester" auswählen -&gt; Ok
                -&gt; Statusmatrix: Speichern @@ -4571,25 +7392,25 @@ INSERT INTO txt VALUES ('H8712', 'English', '

                2) Jump back to previous phase< This state is then offered automatically as target state for the approver. For easier identification for the requester, in this example a new state is defined and equipped with the necessary transitions in the state matrix:
                  -
                • Settings -&gt; State Definitions -&gt; Add State -&gt; Insert Id: 1, Name: "Back To Requester" -&gt; Save +
                • Settings -&gt; State Definitions -&gt; Add State -&gt; Insert Id: 1, Name: "Back To Requester" -&gt; Save (Id in the range between lowest imput and lowest started state of Request phase)
                • Settings -&gt; State Matrix -&gt; Select Type: Master
                  • Request: Allowed transitions: Add State -&gt; Select "Back To Requester"
                  • -
                  • Request: Allowed transitions: Edit "Back To Requester" -&gt; Add State -&gt; Select "Back To Requester" +
                  • Request: Allowed transitions: Edit "Back To Requester" -&gt; Add State -&gt; Select "Back To Requester" -&gt; Add State -&gt; Select "Requested" -&gt; Add State -&gt; Select "Discarded" -&gt; Ok
                  • Approval: Allowed transitions: Add State -&gt; Select "Back To Requester"
                  -&gt; State Matrix: Save
                • -
                • Settings -&gt; State Matrix -&gt; Select Type: Access +
                • Settings -&gt; State Matrix -&gt; Select Type: Access
                  • Request: Allowed transitions: Add State -&gt; Select "Back To Requester"
                  • -
                  • Request: Allowed transitions: Edit "Back To Requester" -&gt; Add State -&gt; Select "Back To Requester" +
                  • Request: Allowed transitions: Edit "Back To Requester" -&gt; Add State -&gt; Select "Back To Requester" -&gt; Add State -&gt; Select "Requested" -&gt; Add State -&gt; Select "Discarded" -&gt; Ok
                  • Approval: Allowed transitions: Edit "In Approval" -&gt; Add State -&gt; Select "Back To Requester" -&gt; Ok
                  • Approval: Allowed transitions: Add State -&gt; Select "Back To Requester"
                  • -
                  • Approval: Allowed transitions: Edit "Back To Requester" -&gt; Add State -&gt; Select "In Approval" -&gt; Add State -&gt; Select "Approved" +
                  • Approval: Allowed transitions: Edit "Back To Requester" -&gt; Add State -&gt; Select "In Approval" -&gt; Add State -&gt; Select "Approved" -&gt; Add State -&gt; Select "Rejected" -&gt; Add State -&gt; Select "Back To Requester" -&gt; Ok
                  -&gt; State Matrix: Save @@ -4606,14 +7427,14 @@ INSERT INTO txt VALUES ('H8713', 'German', '

                  3) Auslassen von Phasen fü
                • Implementierung: Erlaubte Übergänge: Status hinzufügen -&gt; "To Implement" auswählen
                • Implementierung: Erlaubte Übergänge: "To Implement" bearbeiten -&gt; Status hinzufügen -&gt; "In Implementation" auswählen -&gt; Ok
                • Implementierung: Erlaubte Übergänge: "Approved" löschen (wird nicht mehr benötigt)
                • -
                • Implementierung: Spezielle Stati: Niedrigster Eingangsstatus: "To Implement" auswählen
                • +
                • Implementierung: Spezielle Status: Niedrigster Eingangsstatus: "To Implement" auswählen
                -&gt; Statusmatrix: Speichern

              '); INSERT INTO txt VALUES ('H8713', 'English', '

              3) Skip phase for specific Task Type

              - In this example the approval phase for generic task is skipped: + In this example the approval phase for generic task is skipped:
              • Settings -&gt; State Matrix -&gt; Select Type: Generic
                  @@ -4631,16 +7452,16 @@ INSERT INTO txt VALUES ('H8713', 'English', '

                  3) Skip phase for specific Task INSERT INTO txt VALUES ('H8714', 'German', '

                  4) Aktion Autom. Weiterleitung

                  Als weitere Option ist es auch möglich, eine Aktion vom Typ Autom. Weiterleitung zu nutzen. In diesem Beispiel wird beim Reject durch den Implementer (nur zu erreichen nach vorherigem Status "Implementation Trouble") das Ticket automatisch wieder dem Requester zur Bestätigung vorgelegt - (der Einfachheit halber werden die vorhandenen Stati soweit möglich weiterverwendet, eine Definition weiterer Stati wie "Acknowledge Reject" und "Try again" würde sich aber anbieten): + (der Einfachheit halber werden die vorhandenen Status soweit möglich weiterverwendet, eine Definition weiterer Status wie "Acknowledge Reject" und "Try again" würde sich aber anbieten):
                  • Einstellungen -&gt; Statusdefinitionen -&gt; Status hinzufügen -&gt; Eingabe Id: 2, Name "Rejected By Implementer" -&gt; Speichern
                  • -
                  • Einstellungen -&gt; Statusaktionen -&gt; Aktion hinzufügen -&gt; Name: "Acknowledge Reject", Aktionstyp: "Autom. Weiterleitung", Ereignis: "Beim Erreichen", Phase: "Implementierung", +
                  • Einstellungen -&gt; Statusaktionen -&gt; Aktion hinzufügen -&gt; Name: "Acknowledge Reject", Aktionstyp: "Autom. Weiterleitung", Ereignis: "Beim Erreichen", Phase: "Implementierung", Geltungsbereich: "Implementierungs-Auftrag", Tasktyp: "All", Zielstatus: "Rejected By Implementer" -&gt; Speichern
                  • Einstellungen -&gt; Statusdefinitionen -&gt; "Rejected" bearbeiten -&gt; Aktion hinzufügen -&gt; "Acknowledge Reject" auswählen -&gt; Speichern
                  • Einstellungen -&gt; Statusmatrix -&gt; Typ auswählen: Master
                    • Antrag: Erlaubte Übergänge: Status hinzufügen -&gt; "Rejected By Implementer" auswählen
                    • -
                    • Antrag: Erlaubte Übergänge: "Rejected By Implementer" bearbeiten -&gt; Status hinzufügen -&gt; "Discarded" auswählen +
                    • Antrag: Erlaubte Übergänge: "Rejected By Implementer" bearbeiten -&gt; Status hinzufügen -&gt; "Discarded" auswählen -&gt; Status hinzufügen -&gt; "Requested" auswählen -&gt; Ok
                    • Implementierung: Erlaubte Übergänge: Status hinzufügen -&gt; "Rejected By Implementer" auswählen
                    @@ -4666,7 +7487,7 @@ INSERT INTO txt VALUES ('H8714', 'English', '

                    4) Action Auto-forward

                    (for simplicity the existing states are reused if possible, a definition of further states as "Acknowledge Reject" and "Try again" would be appropriate):
                    • Settings -&gt; State Definitions -&gt; Add State -&gt; Insert Id: 2, Name "Rejected By Implementer" -&gt; Save
                    • -
                    • Settings -&gt; State Actions -&gt; Add Action -&gt; Name: "Acknowledge Reject", Action Type: "Auto-forward", Event: "On Set", Phase: "Implementation", +
                    • Settings -&gt; State Actions -&gt; Add Action -&gt; Name: "Acknowledge Reject", Action Type: "Auto-forward", Event: "On Set", Phase: "Implementation", Scope: "Implementation Task", Task Type: "All", To State: "Rejected By Implementer" -&gt; Save
                    • Settings -&gt; State Definitions -&gt; Edit "Rejected" -&gt; Add Action -&gt; Select "Acknowledge Reject" -&gt; Save
                    • Settings -&gt; State Matrix -&gt; Select Type: Master @@ -4696,7 +7517,7 @@ INSERT INTO txt VALUES ('H8715', 'German', '

                      5) Automatische Aktion Genehmig Dafür wird der noch unbenutzte Status "To approve" nach "Requested again" umbenannt (natürlich könnte stattdessen auch ein neuer Status definiert werden):
                      • Einstellungen -&gt; Statusdefinitionen -&gt; Status "50: To Approve" bearbeiten -&gt; Name ändern in "Requested again" -&gt; Speichern
                      • -
                      • Einstellungen -&gt; Statusaktionen -&gt; Aktion hinzufügen -&gt; Name: "Reapprove", Aktionstyp: "Genehmigung hinzufügen", Ereignis: "Beim Erreichen", +
                      • Einstellungen -&gt; Statusaktionen -&gt; Aktion hinzufügen -&gt; Name: "Reapprove", Aktionstyp: "Genehmigung hinzufügen", Ereignis: "Beim Erreichen", Phase: "Antrag", Geltungsbereich: "fachlicher Auftrag", Tasktyp: "Zugriff", Zielstatus: "Requested again" -&gt; Speichern
                      • Einstellungen -&gt; Statusdefinitionen -&gt; "Requested again" bearbeiten -&gt; Aktion hinzufügen -&gt; "Reapprove" auswählen -&gt; Speichern
                      • Einstellungen -&gt; Statusmatrix -&gt; Typ auswählen: Master @@ -4730,7 +7551,7 @@ INSERT INTO txt VALUES ('H8715', 'English', '

                        5) Automatic action Add Approva Therefore the currently unused state "To approve" is renamed to "Requested again" (of course instead a new state could be defined):
                        • Settings -&gt; State Definitions -&gt; Edit State "50: To Approve" -&gt; Change Name to "Requested again" -&gt; Save
                        • -
                        • Settings -&gt; State Actions -&gt; Add Action -&gt; Name: "Reapprove", Action Type: "Add approval", Event: "On Set", +
                        • Settings -&gt; State Actions -&gt; Add Action -&gt; Name: "Reapprove", Action Type: "Add approval", Event: "On Set", Phase: "Request", Scope: "Request Task", Task Type: "Access", To State: "Requested again" -&gt; Save
                        • Settings -&gt; State Definitions -&gt; Edit "Requested again" -&gt; Add Action -&gt; Select "Reapprove" -&gt; Save
                        • Settings -&gt; State Matrix -&gt; Select Type: Master @@ -4763,7 +7584,7 @@ INSERT INTO txt VALUES ('H8716', 'German', '

                          6) Aktion Genehmigung hinzuf&uu Der Genehmiger soll die Möglichkeit bekommen, bei Bedarf ein weiteres Approval zu erzeugen (um es z.B. jemand anderem zuzuweisen). Dafür soll eine Schaltfläche mit dem Text "weitere Genehmigung erforderlich" angeboten werden, die beim Bearbeiten des Auftrags im Status "In approval" erscheint:
                            -
                          • Einstellungen -&gt; Statusaktionen -&gt; Aktion hinzufügen -&gt; Name: "FurtherApproval", Aktionstyp: "Genehmigung hinzufügen", Ereignis: "Schaltfläche anbieten", +
                          • Einstellungen -&gt; Statusaktionen -&gt; Aktion hinzufügen -&gt; Name: "FurtherApproval", Aktionstyp: "Genehmigung hinzufügen", Ereignis: "Schaltfläche anbieten", Schaltertext: "weitere Genehmigung erforderlich", Phase: "Genehmigung", Geltungsbereich: "fachlicher Auftrag", Tasktyp: "Zugriff", Zielstatus: "Requested" -&gt; Speichern
                          • Einstellungen -&gt; Statusdefinitionen -&gt; "In approval" bearbeiten -&gt; Aktion hinzufügen -&gt; "FurtherApproval" auswählen -&gt; Speichern
                          @@ -4772,13 +7593,13 @@ INSERT INTO txt VALUES ('H8716', 'English', '

                          6) Action Add Approval as butto The approver should get the possibility to create a further approval (e.g. to assign it to someone else). To achieve this, a button with the text "Further approval needed" is offered, which appears when working on the task with the state "In approval":
                            -
                          • Settings -&gt; State Actions -&gt; Add Action -&gt; Name: "FurtherApproval", Action Type: "Add approval", Event: "Offer Button", +
                          • Settings -&gt; State Actions -&gt; Add Action -&gt; Name: "FurtherApproval", Action Type: "Add approval", Event: "Offer Button", Button Text: "Further approval needed", Phase: "Approval", Scope: "Request Task", Task Type: "Access", To State: "Requested" -&gt; Save
                          • Settings -&gt; State Definitions -&gt; Edit "In approval" -&gt; Add Action -&gt; Select "FurtherApproval" -&gt; Save
                          '); INSERT INTO txt VALUES ('H8717', 'German', '

                          7) Aktivieren Planungsphase

                          - Für Zugriffsaufträge soll die Planungsphase wie vorinstalliert aktiviert werden + Für Zugriffsaufträge soll die Planungsphase wie vorinstalliert aktiviert werden (Implementierungsaufträge werden dann nicht mehr automatisch erzeugt, sondern müssen vom Planer erstellt werden):
                          • Einstellungen -&gt; Statusmatrix -&gt; Typ auswählen: Master @@ -4786,7 +7607,7 @@ INSERT INTO txt VALUES ('H8717', 'German', '

                            7) Aktivieren Planungsphase

                            Planung: Phase auswählen (die Übergangsmatrix wird eingeblendet)
                          • Implementierung: Erlaubte Übergänge: Status hinzufügen -&gt; "Planned" auswählen
                          • Implementierung: Erlaubte Übergänge: "Planned" bearbeiten -&gt; Status hinzufügen -&gt; "In Implementation" auswählen -&gt; Ok
                          • -
                          • Implementierung: Spezielle Stati: Niedrigster Eingangsstatus: "Planned" auswählen
                          • +
                          • Implementierung: Spezielle Status: Niedrigster Eingangsstatus: "Planned" auswählen
                          -&gt; Statusmatrix: Speichern
                        • @@ -4795,14 +7616,14 @@ INSERT INTO txt VALUES ('H8717', 'German', '

                          7) Aktivieren Planungsphase

                          Planung: Phase auswählen (die Übergangsmatrix wird eingeblendet)
                        • Implementierung: Erlaubte Übergänge: Status hinzufügen -&gt; "Planned" auswählen
                        • Implementierung: Erlaubte Übergänge: "Planned" bearbeiten -&gt; Status hinzufügen -&gt; "In Implementation" auswählen -&gt; Ok
                        • -
                        • Implementierung: Spezielle Stati: Niedrigster Eingangsstatus: "Planned" auswählen
                        • +
                        • Implementierung: Spezielle Status: Niedrigster Eingangsstatus: "Planned" auswählen
                        -&gt; Statusmatrix: Speichern

                      '); INSERT INTO txt VALUES ('H8717', 'English', '

                      7) Activate Planning phase

                      - For access tasks the Planning phase will be activated as preinstalled + For access tasks the Planning phase will be activated as preinstalled (Implementation tasks will not be created automatically but have to be defined by the planner):
                      • Settings -&gt; State Matrix -&gt; Select Type: Master @@ -4825,3 +7646,333 @@ INSERT INTO txt VALUES ('H8717', 'English', '

                        7) Activate Planning phase

                      '); + +INSERT INTO txt VALUES ('H9001', 'German', 'Insbesondere in grösseren Netzwerken besteht der Bedarf, die vielfältigen Verbindungen zwischen den Teilnehmern zu modellieren, + um sie so einer weitergehenden Verwaltung zugänglich zu machen. Dieses Modul stellt die Hilfsmittel, bereits vorhandene Applikationen von anderen Systemen zu importieren + und ihre Elemente nach vorgegebenen Kriterien zu verknüpfen. Dadurch wird ein Kommunikationsprofil erzeugt, bestehend aus einem Satz von Verbindungen und Schnittstellen.

                      + Zur Definition der Schnittstellen und Verbindungen wird auf der linken Seite eine Bibliothek bereitgestellt, in der zunächst die zur Applikation zugeordneten + (in der Regel aus Fremdsystemen importierten) Host-Adressen (App-Server) angeboten werden. Diese können im ersten Schritt zu App-Rollen gebündelt werden (sh. Netzwerkobjekte). + Die App-Rollen (und je nach Modellierungseinstellungen auch die App-Server selbst) können dann als Quelle oder Ziel in die zu erstellende Verbindung übertragen werden. + Hinzu können noch weitere Objekte (z. B. Netzwerke) kommen, und es können (interne und externe) Schnittstellen eingebunden werden.
                      + Desweiteren werden in der Bibliothek vordefinierte (vom Administrator eingestellte) Dienste angeboten. Diese können durch selbst definierte Dienste ergänzt, + als Dienstgruppen gebündelt und dann in den zu definierenden Verbindungen verwendet werden.

                      + Für das erstellte Kommunikationsprofil kann per Knopfdruck automatisch ein Verbindungs-Report erstellt werden. Er wird dann in dem Report-Modul dargestellt. + Dort stehen dann die vom Report-Modul bereitgestellten Funktionalitäten zur weiteren Eingrenzung mittels zusätzlicher Filter, Erzeugung von Vorlagen und Terminen, sowie der Archivierung zur Verfügung.

                      + Bei entsprechender Konfiguration kann die Ausrollung der fertiggestellten Verbindungen automatisch in einem externen Ticketsystem beantragt werden (Einführung). +'); +INSERT INTO txt VALUES ('H9001', 'English', 'Especially in greater networks there is the demand to model the connections between the participants, + with the aim of further administration. This module provides tools to import already existing applications from other systems + and to connect their elements by predefined criteria. By doing this a communication profile is created, composed by a set of connections and interfaces.

                      + To define interfaces and connections a library is provided on the left side, where at the beginning the host addresses (App Server) associated to the application + (which usually are imported from external systems) are offered. They can in a first step be bundled to App Roles (see Network Objects). + These App Roles (and depending on the Modelling Settings also the App Servers themselves) can be used as source or destination in the connections to be created. + Additionally further objects (e.g. networks) and (internal or external) interfaces can be integrated.
                      + Furthermore the library offers predefined Services (inserted by the administrator). They can be complemented by self defined services, bundled as Service Groups, + and used in the connections.

                      + For the communication profile a Connections Report can be created automatically. It is displayed in the Report module. + Here the reporting functionalities for further filtering, creation of templates and schedules, as well as archiving can be used.

                      + When configured the rollout of the finalized connections can be requested automatically on an external ticket system (Rollout). +'); +INSERT INTO txt VALUES ('H9011', 'German', 'Eine Applikation ist aus Sicht des Firewall Orchestrators ein Behälter, in dem aus zugeordneten Host-Adressen ein Kommunikationsprofil erstellt wird. + Sie wird in der Regel extern aus den Anforderungen und Gegebenheiten der jeweiligen Unternehmung definiert und kann über eine Importschnittstelle in den Firewall Orchestrator importiert + (oder auch manuell angelegt) werden. + Das Kommunikationsprofil besteht aus einem Satz von Schnittstellen und Verbindungen welche die Kommunikation sowohl intern als auch mit anderen Applikationen definieren.
                      + Jeder Modellierer bekommt die ihm zugänglichen Applikationen dargestellt. D.h. +
                        +
                      • Der Nutzer muss die Rolle "Modellierer" besitzen (Voraussetzung, dass diese Seite überhaupt dargestellt wird). + Die Rollen können vom Administrator in den Rollen-Einstellungen gesetzt werden.
                      • +
                      • Die Applikationen wurden mit den entsprechenden Skripten importiert (Modelling-Einstellungen) + oder vom Administrator manuell angelegt (Eigentümer-Einstellungen).
                      • +
                      • Der Nutzer ist entweder in den Gruppen-Einstellungen der entsprechenden "ModellerGroup" der Applikation + (wird beim Import automatisch angelegt) oder in den Eigentümer-Einstellungen direkt zugeordnet.
                      • +
                      + Eine Applikation kann durch den Administrator in den Eigentümer-Einstellungen als "Common Service zugelassen" markiert werden. + Nur dann können auch Common Services angelegt werden. +'); +INSERT INTO txt VALUES ('H9011', 'English', 'An application is - from the perspective of the Firewall Orchestrator - a container, where a communication profile is defined on basis of associated host addresses. + Generally the application is defined externally by the requests and conditions of the enterprise and can be imported to the Firewall Orchestrator via import interface (or created manually). + The communication profile consists of a set of interfaces and connections, which define the communication both internally and to other applications.
                      + For each modeller his accessible applications are displayed. That means +
                        +
                      • The user has to have the role "modeller" (precondition that this page is displayed at all). + Roles are set by the administrator in Role Settings.
                      • +
                      • Applications have been imported by respective scripts (Modelling Settings) + or manually created by the administrator (Owner Settings).
                      • +
                      • The user is assigned to the application via the appropriate "ModellerGroup" (automatically created by the import) + in the Group Settings or directly in the Owner Settings.
                      • +
                      + An application can be marked by the administrator as "Common Service Possible" in the Owner Settings. + Only in this case Common Services can be created in this application. +'); +INSERT INTO txt VALUES ('H9021', 'German', 'Verbindungen sind die Hauptbestandteile des Kommunikationsprofils. Es wird zwischen verschiedenen Arten von Verbindungen unterschieden:'); +INSERT INTO txt VALUES ('H9021', 'English', 'Connections are the main components of the communication profile. There are different types of connections:'); +INSERT INTO txt VALUES ('H9022', 'German', 'Schnittstellen: Sie dienen in erster Linie der Modellierung von (aus Sicht der Applikation) externen Verbindungen oder der Bündelung interner Objekte. + Es müssen in der Applikation neben dem Dienst entweder Quelle oder Ziel definiert werden. Die Schnittstellen können durch Setzen des entsprechendenn Häkchens veröffentlicht und dadurch in den anderen Applikationen + zur Auswahl angeboten werden. Sie können dann dort in der Definition von eigenen Verbindungen verwendet werden. +'); +INSERT INTO txt VALUES ('H9022', 'English', 'Interfaces: They serve primarily the modelling of (relative to the application) external connections or the bundling of internal objects. + Besides the service either source or destination have to be defined in the application. The interfaces can be published by setting the respective flag and are then offered to other applications to use + them in the definition of own connections. +'); +INSERT INTO txt VALUES ('H9023', 'German', 'Standard: Zentrale Objekte zur Modellierung der Kommunikationsverbindungen. Dabei müssen Quelle, Dienst und Ziel aus den in der Bibliothek + angebotenen Ntzwerkobjekten bzw. Services gewählt werden. Es können auch eigene oder externe Schnittstellen eingebunden werden. Dann müssen nur noch die "offenen Enden" + (je nach Schnittstelle Quelle oder Ziel) aus der Bibliothek hinzugefügt werden. +'); +INSERT INTO txt VALUES ('H9023', 'English', 'Connections: Essential objects for modelling the communication. Source, Service and Destination have to be selected from the network resp. service objects + offered in the library. Additionally own or external interfaces can be integrated. In this case only the "open ends" (source or destination, depending on the inetrface type) + have to be added from the library. +'); +INSERT INTO txt VALUES ('H9024', 'German', 'Common Services: Können nur definiert werden, wenn die Applikation durch den Administrator in den Eigentümer-Einstellungen + dafür freigegeben wurde. Sie sind formal wie normale Verbindungen aufgebaut, dürfen aber keine Schnittstellen verwenden. +'); +INSERT INTO txt VALUES ('H9024', 'English', 'Common Services: Can only be defined, if the application is marked as permitted in the Owner Settings by the administrator. + Formally they are structured as regular connections but are not allowed to use interfaces. +'); +INSERT INTO txt VALUES ('H9031', 'German', 'Netzwerkobjekte werden zur Definition von Quelle und Ziel der Verbindungen benötigt. Es wird zwischen verschiedenen Arten von Netzwerkobjekten unterschieden:'); +INSERT INTO txt VALUES ('H9031', 'English', 'Network objects are used to define source and destination of the connections. There are different types of network objects:'); +INSERT INTO txt VALUES ('H9032', 'German', 'App-Server: Die elementaren Bausteine (Host-Adressen, Netzwerke, IP-Bereiche), die der Applikation zugeordnet sind. Sie werden in der Regel mit den Applikationen importiert + (Import-Einstellungen, Import-Schnittstelle), können aber auch manuell oder per CSV-Import vom Administrator angelegt werden. + Je nach Einstellung (abhängig von den jeweiligen Vorgaben des Unternehmens) können die App-Server direkt in die Verbindungen übernommen werden oder müssen zuerst in App-Rollen gebündelt werden. +'); +INSERT INTO txt VALUES ('H9032', 'English', 'App Server: Elementary components (host addresses, networks, IP ranges) associated to the application. Usually they are imported with the applications + (Import Settings, Import Interface), but can also be created manually or imported via CSV by the administrator. + Depending on the settings (according to company requirements) App Servers can be used directly in the connections or have to be bundled in App Roles first. +'); +INSERT INTO txt VALUES ('H9033', 'German', 'App-Rollen: Dienen der Bündelung von App-Servern. Falls in den Modellierungseinstellungen so vorgesehen, + müssen sie einer Netzwerkarea zugehören. Beim Erstellen der App-Rolle muss dann zunächst eine Area ausgewählt werden, nur von dieser werden dann die App-Server in der Bibliothek angeboten. + Die Namen der App-Rollen müssen dann einer ebenfalls in den Einstellungen vorgegebenen Namenskonvention folgen. +'); +INSERT INTO txt VALUES ('H9033', 'English', 'App Roles: Used for bundling of App Servers. If required in the Modelling Settings, + they have to belong to a network area. When creating an App Role, first a network area has to be selected, only App Servers belonging to this are are displayed then in the library. + Names of the App Roles have to comply to a naming convention, defined in the Modelling Settings. +'); +INSERT INTO txt VALUES ('H9034', 'German', 'Netzwerkareas: Werden über die Subnetzdaten-Importschnittstelle (Import-Einstellungen, Import-Schnittstelle) importiert. + Sie können aus der Bibliothek heraus gesucht, selektiert und anschliessend in Quelle oder Ziel der Verbindungen übernommen werden. +'); +INSERT INTO txt VALUES ('H9034', 'English', 'Network Areas: Are imported via the Subnet Data Import Interface (Import Settings, Import Interface). + They can be searched an selected from the library and then used for source and destination of the connections. +'); +INSERT INTO txt VALUES ('H9041', 'German', 'Es wird zwischen einfachen Diensten und Dienstgruppen unterschieden. In den Modellierungseinstellungen + kann festgelegt werden, dass nur Dienstgruppen in der Definition von Verbindungen genutzt werden können, ansonsten sind auch einfache Dienste zugelassen. +'); +INSERT INTO txt VALUES ('H9041', 'English', 'There is a differentiation between simple services and Service Groups. It can be defined in the Modelling Settings, + that only Service Groups are allowed to be used in the definition of connections, else also simple services are permitted. +'); +INSERT INTO txt VALUES ('H9042', 'German', 'Dienste: Einfache Dienste werden durch Port (einfach oder Intervall) und Protokoll definiert und können einen Namen zugewiesen bekommen. + Die Definition kann durch den Modellierer selbst vorgenommen werden, es können aber auch - falls vorhanden - vom Administrator vordefinierte Dienste verwendet werden. +'); +INSERT INTO txt VALUES ('H9042', 'English', 'Services: Simple services are defined by port (single or range) and protocol and can have a name assigned. + Definition can be done by the modeller, but also - if available - predefined services by the administrator can be used. +'); +INSERT INTO txt VALUES ('H9043', 'German', 'Dienstgruppen: In Dienstgruppen können die einfachen Dienste zusammengefasst werden. Hier muss ein Name vergeben werden, es können auch Kommentare hinzugefügt werden. + Auch hier kann die Definition durch den Modellierer selbst erfolgen oder auch vom Administrator vordefinierte Dienstgruppen verwendet werden. +'); +INSERT INTO txt VALUES ('H9043', 'English', 'Service Groups: Simple services can be bundled in Service Groups. A name has to be given to them, comments can be added. + Again definition can be done by the modeller, but also Service Groups predefined by the administrator can be used. +'); +INSERT INTO txt VALUES ('H9051', 'German', 'Beantragung neuer Schnittstellen: Wenn externe Schnittstellen von anderen Applikationen benötigt werden, können diese über die entsprechende Schaltfläche in der Bibliothek beantragt werden. +
                        +
                      • Es erscheint ein Dialog, in dem die externe Applikation ausgewählt und eine Begründung eingetragen werden müssen, sowie das Häkchen, ob die Schnittstelle als Quelle oder Ziel genutzt werden soll.
                      • +
                      • Beim Abschicken der Anforderung wird +
                          +
                        • bei der externen Applikation automatisch eine Dummy-Schnittstelle angelegt, die dann in der eigenen Schnittstellen-Auswahl erscheint und direkt zur Erstellung eigener Verbindungen genutzt werden kann. + Sie wird in der Liste der eigenen Verbindungen mit Einträgen "Schnittstelle angefordert" in Quelle/Ziel und Dienst als solche gekennzeichnet.
                        • +
                        • der oder die für die externe Applikation Verantwortlichen per Email über den Antrag informiert.
                        • +
                        • im Workflow-Modul ein Ticket mit dem Antrag erstellt. Je nach Konfiguration des Workflows kann hier der Auftrag abgelehnt, an andere Applikationen weitergeleitet, einzelnen Bearbeitern zugewiesen oder mit Kommentaren versehen werden.
                        • +
                        +
                      • +
                      • Wird die Schnittstelle auf der Gegenseite modelliert und veröffentlicht, wandelt sich auch die eigene nutzende Verbindung automatisch in eine "normale" Verbindung um, eine weiteres Eingreifen des Antragstellers ist nicht mehr notwendig.
                      • +
                      +'); +INSERT INTO txt VALUES ('H9051', 'English', 'Request new interface: If external interfaces from other applications are needed, they can be requested via a button in the library. +
                        +
                      • A dialogue is displayed to select the external Application. A reason field has to be filled as well as the checkbox, if the interface should be used as source or destination.
                      • +
                      • If the request is submitted +
                          +
                        • a dummy interface is created automatically at the target application, which then appears in the own interface selection in the library and can be used for the definition of the own connection. + It is marked as such by the text "Interface requested" in Source/Destination and Service in the list of own the connections.
                        • +
                        • the responsible(s) of the external Application is informed about the request by email.
                        • +
                        • a ticket in the Workflow module is created. Depending on the configuration of the workflow, the request can be rejected, forwarded to other applications, assigned to aperson in charge or commented.
                        • +
                        +
                      • +
                      • When the requested interface is modelled and published on the other side, the own using connection is changed to a "regular" connection automatically, further action is not necessary.
                      • +
                      +'); +INSERT INTO txt VALUES ('H9052', 'German', 'Der beauftragte Modellierer kann die angefragte Schnittstelle durch eine bereits vorhandene ersetzen: +
                        +
                      • Beim Editieren der beantragten Schnittstelle wird in der Bibliothek unten eine Liste der eigenen Schnittstellen angeboten, von der eine per Schaltfläche oder Drag&Drop ausgewählt werden kann.
                      • +
                      • Entspricht die ausgewählte Schnittstelle dem Typ (Quelle oder Ziel) der beantragten, wird sie in einem neuen Fenster dargestellt.
                      • +
                      • Beim Speichern werden +
                          +
                        • zuerst alle nutzenden Verbindungen der beantragten auf die ausgewählte Schnittstelle umgestellt,
                        • +
                        • danach die beantragte Schnittstelle gelöscht,
                        • +
                        • zum Abschluss wird der Implementierungsauftrag des Tickets mit einem entsprechenden Kommentar versehen und geschlossen. Je nach Konfiguration kann eine Email an den Antragsteller gesendet werden.
                        • +
                        +
                      • +
                      • Aus Sicht des Antragstellers besteht kein Unterschied, ob die Schnittstelle neu modelliert oder durch eine bereits vorhandene ersetzt wurde.
                      • +
                      +'); +INSERT INTO txt VALUES ('H9052', 'English', 'The assigned modeller can replace the requested interface by an already existing: +
                        +
                      • When editing the requested interface a list of the own interfaces is displayed in the lower part of the library to be selected via button or drag&drop.
                      • +
                      • If the type (source or destination) of the selected interface fits to the requested it is displayed then in a pop up window.
                      • +
                      • When saving +
                          +
                        • first all using connections are converted from the requested to the already existing,
                        • +
                        • then the requested interface is deleted,
                        • +
                        • finally the implementation task of the request ticket is closed with a respective comment. Depending on the configuration, an email to the requester may be sent.
                        • +
                        +
                      • +
                      • From the view of the requester there is no difference, whether the interface was newly modelled or replaced by an alredy existing.
                      • +
                      +'); +INSERT INTO txt VALUES ('H9053', 'German', 'Der beauftragte Modellierer kann die angefragte Schnittstelle ablehnen: +
                        +
                      • Beim Editieren der beantragten Schnittstelle wird eine Schaltfläche "Ablehnen" angeboten.
                      • +
                      • Es erscheint ein Fenster, in dem eine Begründung eingetragen werden kann (dieser wird in das Kommentarfeld des entsprechenden Implementierungsauftrags übernommen).
                      • +
                      • Beim Speichern wird die Schnittstelle auf abgelehnt gesetzt und der zugehörige Antrag auf den entsprechenden Status gesetzt.
                      • +
                      • Bei entsprechender Konfiguration durch den Administrator (Aktionen) kann die Schnittstelle auch aus dem Workflow-Antrag heraus abgelehnt werden.
                      • +
                      +'); +INSERT INTO txt VALUES ('H9053', 'English', 'The assigned modeller can reject the requested interface: +
                        +
                      • When editing the requested interface a button "Reject" is displayed.
                      • +
                      • A pop up window is shown where the reason for the reject can be inserted (which is added to the comments of the respective implementation task).
                      • +
                      • When saving the interface is set to rejected and the respective workflow request is set to the according state.
                      • +
                      • If configured by the administrator (Actions), the interface can also be rejected inside the workflow request.
                      • +
                      +'); +INSERT INTO txt VALUES ('H9055', 'German', 'Importieren von App Servern via CSV Datei. Die CSV muss folgende Daten enthalten: +
                        +
                      • App Server Name
                      • +
                      • Externe App-ID
                      • +
                      • App Server Typ
                      • +
                      • App IP Address Range
                      • +
                      +
                      + Die CSV darf eine Überschrift enthalten und muss wie folgt formatiert/benannt sein: App-Server-Name;External-App-ID;App-Server-Typ;App-IP-Address-Range. +'); +INSERT INTO txt VALUES ('H9055', 'English', 'Import from app servers via CSV file. The CSV must contain the following data: +
                        +
                      • App server name
                      • +
                      • External app ID
                      • +
                      • App server type
                      • +
                      • App IP address range
                      • +
                      +
                      + The CSV may contain a header and must be formatted/named as follows: App-Server-Name;External-App-ID;App-Server-Typ;App-IP-Address-Range. +'); +INSERT INTO txt VALUES ('H9060', 'German', 'Hier werden alle Tickets dargestellt, die für den ausgewählten Eigentümer für Externe Aufträge angelegt wurden. + Wenn ein Ticket noch nicht abgeschlossen ist, aber keine offenen Externen Aufträge dafür existieren, wird dem Administrator die Möglichkeit zum Wiederaufsetzen angeboten. + Dabei wird dann die erste noch nicht abgeschlossene Aufgabe aus dem Ticket beantragt. +'); +INSERT INTO txt VALUES ('H9060', 'English', 'All tickets are displayed, which have been created for the selected owner for external requests. + If a ticket is not finished but no open external requests are existing, a button to reinit is offered to the administrator. + When selected, the first not finished request task of the ticket is requested. +'); +INSERT INTO txt VALUES ('H9070', 'German', 'Hier werden alle in der Auftragstabelle eingetragenen Externen Aufträge dargestellt, + deren Status noch nicht einen der Endzustände "ExtReqAcknowledged" oder "ExtReqAckRejected" erreicht hat.
                      +'); +INSERT INTO txt VALUES ('H9070', 'English', 'All external requests from the external request table are displayed, + which have not reached one of the final states "ExtReqAcknowledged" or "ExtReqAckRejected".
                      +'); +INSERT INTO txt VALUES ('H9071', 'German', 'Für den Administrator wird die Möglichkeit angeboten, den Zustand zu ändern. Je nach Ausgangszustand gibt es dabei verschiedene erreichbare Endzustände: +
                        +
                      • Von den Initialzuständen "ExtReqInitialized" und "ExtReqFailed" kann nach "ExtReqRejected", "ExtReqAckRejected" und "ExtReqDiscarded" gewechselt werden.
                      • +
                      • Von Zuständen "ExtReqRequested" und "ExtReqInProgress", die bereits eine externe Bearbeitung anzeigen, ist der Übergang nach + "ExtReqRejected", "ExtReqDone", "ExtReqAckRejected" und "ExtReqAcknowledged" möglich.
                      • +
                      • Die Zustände "ExtReqDone" und "ExtReqRejected", die eine abgeschlossene externe Bearbeitung anzeigen, können nur noch mit dem Übergang nach + "ExtReqAcknowledged" bzw. "ExtReqAckRejected" geschlossen werden.
                      • +
                      + Zu beachten ist: +
                        +
                      • Der Zustand "ExtReqDiscarded" kann nur durch den aktiven Eingriff des Administrators erreicht werden. + Der Externe Auftrag wird bei der weiteren Bearbeitung nicht mehr berücksichtigt. + Somit steht z.B. die Möglichkeit offen, durch Neuanstossen des internen Tickets einen neuen Auftrag für denselben Requesttask zu erzeugen.
                      • +
                      • Wird als Endzustand "ExtReqRejected" oder "ExtReqDone" gewählt, wird auch automatisch die entsprechende Weiterverarbeitung angestossen. + D.h. das interne Ticket wird aktualisiert und ggf. Folgeaufträge angestossen oder abgebrochen.
                      • +
                      • Beim Wählen von "ExtReqAcknowledged" bzw. "ExtReqAckRejected" wird nur der Status im Externen Auftrag gesetzt.
                      • +
                      +'); +INSERT INTO txt VALUES ('H9071', 'English', 'For the administrator the possibility is given to patch the state. Depending on the actual state different final states can be reached: +
                        +
                      • From the initial states "ExtReqInitialized" and "ExtReqFailed" the final states "ExtReqRejected", "ExtReqAckRejected" and "ExtReqDiscarded" can be selected.
                      • +
                      • The states "ExtReqRequested" und "ExtReqInProgress", who indicate that the external processing has already started, allow the transition to + "ExtReqRejected", "ExtReqDone", "ExtReqAckRejected" and "ExtReqAcknowledged".
                      • +
                      • The states "ExtReqDone" und "ExtReqRejected", who indicate finalized external processing, can only be closed by transition to + "ExtReqAcknowledged" resp. "ExtReqAckRejected".
                      • +
                      + Please note: +
                        +
                      • The state "ExtReqDiscarded" can only be reached by the intervention of the administrator. + The External Request will not be regarded any more in further processing. + This opens the possibility to create a new external request for the same request task by reactivating the resp. internal ticket.
                      • +
                      • If "ExtReqRejected" or "ExtReqDone" are chosen, the further processing is activated automatically. + The internal ticket is updated and further tasks may be initialized resp. rejected.
                      • +
                      • Chosing "ExtReqAcknowledged" resp. "ExtReqAckRejected" sets only the state in the external request table.
                      • +
                      +'); +INSERT INTO txt VALUES ('H9080', 'German', 'Für das Kommunikationsprofil kann per Knopfdruck die Ausrollung auf den Firewalls über ein externes Ticketsystem angefordert werden. + Berücksichtigt werden alle Verbindungen und Common Services, die folgende Voraussetzungen erfüllen: +
                        +
                      • Es sind keine beantragten und noch nicht freigegebenen Schnittstellen enthalten.
                      • +
                      • Es wurde keine leere App Rolle verwendet.
                      • +
                      • Es sind keine gelöschten Netzwerkobjekte enthalten.
                      • +
                      + Im ersten Schritt werden anhand der Produktionsdaten alle zu beauftragenden Einzelposten ermittelt und in der erforderlichen Reihenfolge aufgelistet: +
                        +
                      • Zu erweiternde Netzwerkgruppen
                      • +
                      • Neu einzurichtende Netzwerkgruppen
                      • +
                      • Alle relevanten Access Requests (zur Zeit werden alle relevanten Verbindungen beantragt, da die genaue Netzwerktopologie nicht bekannt ist)
                      • +
                      • Zu reduzierende Netzwerkgruppen
                      • +
                      + Bei Bestätigung wird ein interner Auftrag angelegt und hieraus die einzelnen Aufgaben automatisch nacheinander beauftragt. + Dabei können bei entsprechender Konfiguration mehrere Aufgaben (zur Zeit nur Access Requests) in einem externen Ticket gebündelt werden. + Der aktuelle Status der Verarbeitung kann über erneutes Darstellen der Auftragsliste abgefragt werden. Im Fehlerfall erscheint eine entsprechende Nachricht in der Oberfläche. + Je nach Konfiguration wird nach Beendigung des Auftrags eine Email an den Antragsteller verschickt. + Solange die Verarbeitung nicht abgeschlossen ist, kann keine weitere Ausrollung für diese Applikation beantragt werden. +'); +INSERT INTO txt VALUES ('H9080', 'English', 'For the Communication Profile the rollout on the firewalls can be requested via an external ticket system. + Included are all Connections or Common Services satisfying the following conditions: +
                        +
                      • They contain no requested but unpublished interfaces.
                      • +
                      • They do not use any empty App Role.
                      • +
                      • They do not contain any deleted network object.
                      • +
                      + In the first step all tasks to request are calculated by comparing to production data and listed in the necessary order: +
                        +
                      • Network groups to be expanded
                      • +
                      • Network groups to be created
                      • +
                      • All relevant Access Requests (currently all connections are requested, as the exact network topology is unknown)
                      • +
                      • Network groups to be reduced
                      • +
                      + If submitted, an internal ticket is created, from where the tasks are processed automatically step by step. + Several tasks can be bundled in one single external ticket, if configured (currently only Access Requests). + The actual state of the processing can be determined by redisplaying the request list. In case of an error a respective message is displayed in the Ui. + After finishing all tasks an email is sent to the requester, if configured. + As long as the processing is not finished, no further rollout can be requested for this application. +'); +INSERT INTO txt VALUES ('H9081', 'German', 'Sonderkonfigurationen sind spezielle Anweisungen zur Implementierung, z.B. NAT. Die möglichen Typen werden vom Administrator vorgegeben.'); +INSERT INTO txt VALUES ('H9081', 'English', 'Extra configurations are special recommendations for implementation, e.g. NAT. Possible types are defined by the administrator.'); +INSERT INTO txt VALUES ('H9082', 'German', 'Berechtigung: Bestimmt die Sicht- und Nutzbarkeit für andere Applikationen: Öffentlich - für alle ohne Rückfrage nutzbar, Beschränkt - nur mit Zustimmung des Eigentümers nutzbar, Privat - ausschliesslich innerhalb des eigenen Kommunikationsprofils nutzbar.'); +INSERT INTO txt VALUES ('H9082', 'English', 'Permission: Defines visability and usability for other applications: Public - usable for all without further query, Restricted - usable only with permission of the owner, Private - usable only inside the own Communication Profile.'); +INSERT INTO txt VALUES ('H9083', 'German', 'Berechtigte Applikationen: Bestimmt, welche anderen Applikationen diese Schnittstelle nutzen dürfen.'); +INSERT INTO txt VALUES ('H9083', 'English', 'Permitted Applications: Defines which other applications are permitted to use this interface.'); +INSERT INTO txt VALUES ('H5901', 'German', 'Verantwortlichkeitsstufen für Eigentümer verwalten. Sie können Stufen anlegen, bearbeiten, reaktivieren und löschen. Beim Löschen prüft FWOrch, ob die Stufe noch verwendet wird.'); +INSERT INTO txt VALUES ('H5901', 'English', 'Manage responsible levels for owners. You can create, edit, reactivate and delete levels. On delete, FWOrch checks whether the level is still in use.'); +INSERT INTO txt VALUES ('H5902', 'German', 'Diese Einstellungen vergeben keine Rollen. Sie steuern nur die UI-Zugriffs- und Aktionsmöglichkeiten für verantwortliche Benutzer/Gruppen.'); +INSERT INTO txt VALUES ('H5902', 'English', 'These settings do not assign roles. They only control UI access and available actions for responsible users/groups.'); +INSERT INTO txt VALUES ('H5903', 'German', 'Modellierungs- und Rezertifizierungsaktionen sind nur aktiv, wenn der Benutzer die entsprechende Rolle besitzt und eine passende Verantwortlichkeitsstufe die Aktion erlaubt.'); +INSERT INTO txt VALUES ('H5903', 'English', 'Modelling and recertification actions are only enabled when the user has the corresponding role and a matching responsible type allows the action.'); +INSERT INTO txt VALUES ('H5908', 'German', 'Wenn eine Verantwortlichkeitsstufe noch zu Eigentümern zugeordnet ist, wird sie beim Löschvorgang nicht entfernt, sondern automatisch deaktiviert.'); +INSERT INTO txt VALUES ('H5908', 'English', 'If a responsible type is still assigned to owners, delete will not remove it but automatically deactivate it.'); +INSERT INTO txt VALUES ('H5909', 'German', 'Inaktive Stufen können über den Reaktivieren-Button wieder aktiviert werden. Rollen werden hier nicht konfiguriert.'); +INSERT INTO txt VALUES ('H5909', 'English', 'Inactive levels can be enabled again via the reactivate button. Roles are not configured in this chapter.'); +INSERT INTO txt VALUES ('H5910', 'German', 'In diesem Kapitel wird die automatische Eigentümerzuordnung für Regeln konfiguriert und bei Bedarf angestossen.'); +INSERT INTO txt VALUES ('H5910', 'English', 'This chapter configures automatic owner mapping for rules and allows triggering a recalculation when needed.'); +INSERT INTO txt VALUES ('H5911', 'German', 'Quelle auswählen: Legt fest, aus welchem Regelmerkmal die Eigentümerzuordnung abgeleitet wird (z.B. IP-basiert, Namensfeld oder Custom Field).'); +INSERT INTO txt VALUES ('H5911', 'English', 'Select source: Defines which rule attribute is used to derive owner mapping (e.g. IP-based, name field, or custom field).'); +INSERT INTO txt VALUES ('H5912', 'German', 'Custom-Field-Schlüssel: Nur erforderlich bei Quelle "Custom Field". Ohne Schlüssel kann die Konfiguration nicht gespeichert werden.'); +INSERT INTO txt VALUES ('H5912', 'English', 'Custom field key: Required only when source is "Custom Field". Configuration cannot be saved without this key.'); +INSERT INTO txt VALUES ('H5913', 'German', 'Neu berechnen: Startet die Aktualisierung der Eigentümerzuordnung für bestehende Regeln auf Basis der aktuellen Konfiguration.'); +INSERT INTO txt VALUES ('H5913', 'English', 'Recalculate: Starts updating owner mappings for existing rules based on the current configuration.'); diff --git a/roles/database/files/sql/idempotent/fworch-usr-import.sql b/roles/database/files/sql/idempotent/fworch-usr-import.sql deleted file mode 100644 index e2c641ca95..0000000000 --- a/roles/database/files/sql/idempotent/fworch-usr-import.sql +++ /dev/null @@ -1,246 +0,0 @@ --- $Id: iso-usr-import.sql,v 1.1.2.6 2011-05-12 12:11:52 tim Exp $ --- $Source: /home/cvs/iso/package/install/database/Attic/iso-usr-import.sql,v $ - ----------------------------------------------------- --- FUNCTION: import_users --- Zweck: fuegt alle Benutzer des aktuellen Imports in die usr-Tabelle --- Zweck: verwendet dazu die Funktionen insert_single_user und resolve_user_groups --- Parameter: KEINE --- RETURNS: VOID --- -CREATE OR REPLACE FUNCTION import_usr_main (BIGINT,BOOLEAN) RETURNS VOID AS $$ -DECLARE - i_current_import_id ALIAS FOR $1; -- ID des aktiven Imports - b_is_initial_import ALIAS FOR $2; -- ID des aktiven Imports - i_mgm_id INTEGER; -- zum Holen der mgm_ID fuer Loeschen von Elementen - r_usr RECORD; -- Datensatz mit einzelner svc_id aus import_service-Tabelle des zu importierenden Services - v_group_del VARCHAR; -- Trennzeichen fuer Gruppenmitglieder - t_last_change_time TIMESTAMP; - r_last_times RECORD; -BEGIN - SELECT INTO i_mgm_id mgm_id FROM import_control WHERE control_id=i_current_import_id; - -/* - IF NOT b_is_initial_import THEN -- Objekte ausklammern, die vor dem vorherigen Import-Zeitpunkt geaendert wurden, Tuning-Masznahme - SELECT INTO r_last_times MAX(start_time) AS last_import_time, MAX(last_change_in_config) AS last_change_time - FROM import_control WHERE mgm_id=i_mgm_id AND NOT control_id=i_current_import_id AND successful_import; - IF (r_last_times.last_change_time IS NULL) THEN t_last_change_time := r_last_times.last_import_time; - ELSE - IF (r_last_times.last_import_time=i_current_import_id - SELECT * FROM usergrp WHERE usergrp_member_id=i_old_id AND active - LOOP -- die neue Beziehung wird eingefuegt - IF NOT i_new_id IS NULL THEN - INSERT INTO usergrp (usergrp_id,usergrp_member_id,import_created,import_last_seen) - VALUES (r_usergrp.usergrp_id, i_new_id,i_current_import_id,i_current_import_id); - END IF; - END LOOP; - RETURN; -END; -$$ language plpgsql; - - ------------------ ab hier kommen die flat-Funktionen ----------------------- - - ----------------------------------------------------- --- FUNCTION: import_usr_refhandler_usergrp_flat_add_self --- Zweck: der simple User $1 (keine Gruppe) wird als sein eigenes usergrp_flat-Mitglied eingetragen --- Dient dazu, einfacher nach geschachtelten Benutzern zu suchen --- Parameter: $1: user_id des Benutzers --- RETURNS: VOID --- -CREATE OR REPLACE FUNCTION import_usr_refhandler_usergrp_flat_add_self (BIGINT,BIGINT) RETURNS VOID AS $$ -DECLARE - i_user_id ALIAS FOR $1; - i_current_import_id ALIAS FOR $2; - --- v_temp VARCHAR; -BEGIN --- SELECT INTO v_temp user_name FROM usr WHERE user_id=i_user_id; --- v_temp := v_temp || ', id: ' || CAST(i_user_id AS VARCHAR); --- RAISE NOTICE 'adding usergrp_flat_self: %', v_temp; - IF NOT i_user_id IS NULL THEN - INSERT INTO usergrp_flat (usergrp_flat_id,usergrp_flat_member_id,import_created,import_last_seen) - VALUES (i_user_id,i_user_id,i_current_import_id,i_current_import_id); - END IF; - RETURN; -END; -$$ LANGUAGE plpgsql; - ----------------------------------------------------- --- FUNCTION: import_usr_refhandler_usergrp_flat_add_group --- Zweck: die Gruppenzugehoerigkeiten der Gruppe $2 aufloesen --- Zweck: und in usergrp_flat als Teil von $1 eintragen --- Parameter: $1: user_id der Top-Level-Gruppe --- Parameter: $2: user_id der Unter-Gruppe --- Parameter: $3: Rekursionsebene - fuer Abbruch nach 20 Rekursionen --- verwendete --- Funktionen: insert_user_group_relations_flat (rekursiv) --- RETURNS: VOID --- -CREATE OR REPLACE FUNCTION import_usr_refhandler_usergrp_flat_add_group (BIGINT,BIGINT,INTEGER,BIGINT) RETURNS VOID AS $$ -DECLARE - i_top_group_id ALIAS FOR $1; - i_group_id ALIAS FOR $2; - i_rec_level ALIAS FOR $3; - i_current_import_id ALIAS FOR $4; - r_member RECORD; - r_user RECORD; - r_member_exists usergrp_flat%ROWTYPE; -BEGIN - IF i_rec_level>20 THEN - SELECT INTO r_member * FROM usr WHERE user_id = i_top_group_id; --- RAISE NOTICE 'user group recursion reached its limit for top group %:', r_member.user_name; - SELECT INTO r_member * FROM usr WHERE user_id = i_group_id; --- RAISE NOTICE 'user group recursion reached its limit for member group %:', r_member.user_name; - PERFORM error_handling('ERR_OBJ_GROUP_REC_LVL_EXCEEDED'); - END IF; - FOR r_member IN - SELECT usergrp_member_id FROM usergrp WHERE usergrp_id=i_group_id - LOOP - SELECT INTO r_member_exists * FROM usergrp_flat WHERE - usergrp_flat_id=i_top_group_id AND usergrp_flat_member_id=r_member.usergrp_member_id; - IF NOT FOUND AND NOT r_member.usergrp_member_id IS NULL THEN - INSERT INTO usergrp_flat (usergrp_flat_id,usergrp_flat_member_id,import_created,import_last_seen) - VALUES (i_top_group_id,r_member.usergrp_member_id,i_current_import_id,i_current_import_id); - END IF; - IF is_user_group(r_member.usergrp_member_id) THEN - PERFORM import_usr_refhandler_usergrp_flat_add_group - (i_top_group_id, r_member.usergrp_member_id, i_rec_level+1, i_current_import_id); - END IF; - END LOOP; - RETURN; -END; -$$ LANGUAGE plpgsql; - ----------------------------------------------------- --- FUNCTION: import_usr_refhandler_change_usergrp_flat_member_refs --- Zweck: ueberall dort, wo das alte (geaenderte) Objekt in usergrp_flat als member auftaucht --- Zweck: muessen die Referenzen vom alten auf das neue Objekt umgebogen werden --- Parameter: old_user_id, new_user_id --- RETURNS: VOID -CREATE OR REPLACE FUNCTION import_usr_refhandler_change_usergrp_flat_member_refs(BIGINT, BIGINT, BIGINT) RETURNS VOID AS $$ -DECLARE - i_old_id ALIAS FOR $1; -- id des bestehenden Datensatzes aus usr - i_new_id ALIAS FOR $2; -- id des neuen Datensatzes aus usr - i_current_import_id ALIAS FOR $3; - r_usergrp_flat usergrp_flat%ROWTYPE; - r_member_exists usergrp_flat%ROWTYPE; --- v_temp VARCHAR; --- v_temp1 VARCHAR; -BEGIN - FOR r_usergrp_flat IN - SELECT * FROM usergrp_flat WHERE usergrp_flat_member_id=i_old_id AND active - LOOP -- es wird die neue Beziehung eingefuegt, wenn sie noch nicht existiert - SELECT INTO r_member_exists * FROM usergrp_flat WHERE - usergrp_flat.usergrp_flat_id=r_usergrp_flat.usergrp_flat_id AND usergrp_flat_member_id=i_new_id; - IF NOT FOUND AND NOT i_new_id IS NULL THEN - INSERT INTO usergrp_flat (usergrp_flat_id,usergrp_flat_member_id,import_created,import_last_seen) - VALUES (r_usergrp_flat.usergrp_flat_id, i_new_id, i_current_import_id, i_current_import_id); - END IF; - END LOOP; - RETURN; -END; -$$ language plpgsql; - ----------------------------------------------------- --- FUNCTION: import_usr_refhandler_change_rule_usr_refs --- Zweck: ueberall dort, wo das alte (geaenderte) Objekt in rule_from auftaucht --- Zweck: muessen die Referenzen vom alten auf das neue Objekt umgebogen werden --- Parameter: old_user_id, new_user_id, import_id --- RETURNS: VOID -CREATE OR REPLACE FUNCTION import_usr_refhandler_change_rule_usr_refs (BIGINT, BIGINT, BIGINT) RETURNS VOID AS $$ -DECLARE - i_old_id ALIAS FOR $1; -- id des bestehenden Datensatzes aus usr - i_new_id ALIAS FOR $2; -- id des neuen Datensatzes aus usr - i_current_import_id ALIAS FOR $3; - r_usr rule_from%ROWTYPE; -BEGIN - FOR r_usr IN - SELECT * FROM rule_from WHERE user_id=i_old_id AND active - LOOP -- zusaetzlich wird die neue Beziehung eingefuegt - INSERT INTO rule_from (rule_id,obj_id,user_id,rf_create,rf_last_seen) - VALUES (r_usr.rule_id, r_usr.obj_id, i_new_id, i_current_import_id, i_current_import_id); - END LOOP; - RETURN; -END; -$$ language plpgsql; diff --git a/roles/database/files/sql/idempotent/fworch-views-changes.sql b/roles/database/files/sql/idempotent/fworch-views-changes.sql new file mode 100644 index 0000000000..d2e4e320c5 --- /dev/null +++ b/roles/database/files/sql/idempotent/fworch-views-changes.sql @@ -0,0 +1,332 @@ + +--------------------------------------------------------------------------------------------- +-- object views +--------------------------------------------------------------------------------------------- +CREATE OR REPLACE VIEW view_obj_changes AS + SELECT + abs_change_id, + log_obj_id AS local_change_id, + ''::VARCHAR as change_request_info, + CAST('object' AS VARCHAR) as change_element, + CAST('basic_element' AS VARCHAR) as change_element_order, + changelog_object.old_obj_id AS old_id, + changelog_object.new_obj_id AS new_id, + changelog_object.documented as change_documented, + changelog_object.change_type_id as change_type_id, + change_action as change_type, + changelog_obj_comment as change_comment, + obj_comment, + import_control.start_time AS change_time, + management.mgm_name AS mgm_name, + management.mgm_id AS mgm_id, + CAST(NULL AS VARCHAR) as dev_name, + CAST(NULL AS INTEGER) as dev_id, + t_change_admin.uiuser_first_name || ' ' || t_change_admin.uiuser_last_name AS change_admin, + t_change_admin.uiuser_id AS change_admin_id, + t_doku_admin.uiuser_first_name || ' ' || t_doku_admin.uiuser_last_name AS doku_admin, + t_doku_admin.uiuser_id AS doku_admin_id, + security_relevant, + object.obj_name AS unique_name, + CAST (NULL AS VARCHAR) AS change_diffs, + CAST (NULL AS VARCHAR) AS change_new_element + FROM + changelog_object + LEFT JOIN (import_control LEFT JOIN management using (mgm_id)) using (control_id) + LEFT JOIN object ON (old_obj_id=obj_id) + LEFT JOIN uiuser AS t_change_admin ON (changelog_object.import_admin=t_change_admin.uiuser_id) + LEFT JOIN uiuser AS t_doku_admin ON (changelog_object.doku_admin=t_doku_admin.uiuser_id) + WHERE change_type_id = 3 AND security_relevant AND change_action='D' AND successful_import + + UNION + + SELECT + abs_change_id, + log_obj_id AS local_change_id, + ''::VARCHAR as change_request_info, + CAST('object' AS VARCHAR) as change_element, + CAST('basic_element' AS VARCHAR) as change_element_order, + changelog_object.old_obj_id AS old_id, + changelog_object.new_obj_id AS new_id, + changelog_object.documented as change_documented, + changelog_object.change_type_id as change_type_id, + change_action as change_type, + changelog_obj_comment as change_comment, + obj_comment, + import_control.start_time AS change_time, + management.mgm_name AS mgm_name, + management.mgm_id AS mgm_id, + CAST(NULL AS VARCHAR) as dev_name, + CAST(NULL AS INTEGER) as dev_id, + t_change_admin.uiuser_first_name || ' ' || t_change_admin.uiuser_last_name AS change_admin, + t_change_admin.uiuser_id AS change_admin_id, + t_doku_admin.uiuser_first_name || ' ' || t_doku_admin.uiuser_last_name AS doku_admin, + t_doku_admin.uiuser_id AS doku_admin_id, + security_relevant, + object.obj_name AS unique_name, + CAST (NULL AS VARCHAR) AS change_diffs, + CAST (NULL AS VARCHAR) AS change_new_element + FROM + changelog_object + LEFT JOIN (import_control LEFT JOIN management using (mgm_id)) using (control_id) + LEFT JOIN object ON (new_obj_id=obj_id) + LEFT JOIN uiuser AS t_change_admin ON (changelog_object.import_admin=t_change_admin.uiuser_id) + LEFT JOIN uiuser AS t_doku_admin ON (changelog_object.doku_admin=t_doku_admin.uiuser_id) + WHERE change_type_id = 3 AND security_relevant AND change_action<>'D' AND successful_import; + + +--------------------------------------------------------------------------------------------- +-- user views +--------------------------------------------------------------------------------------------- + +CREATE OR REPLACE VIEW view_user_changes AS + SELECT + abs_change_id, + log_usr_id AS local_change_id, + change_request_info, + CAST('usr' AS VARCHAR) as change_element, + CAST('basic_element' AS VARCHAR) as change_element_order, + changelog_user.old_user_id AS old_id, + changelog_user.new_user_id AS new_id, + changelog_user.documented as change_documented, + changelog_user.change_type_id as change_type_id, + change_action as change_type, + changelog_user_comment as change_comment, + user_comment as obj_comment, + import_control.start_time AS change_time, + management.mgm_name AS mgm_name, + management.mgm_id AS mgm_id, + CAST(NULL AS VARCHAR) as dev_name, + CAST(NULL AS INTEGER) as dev_id, + t_change_admin.uiuser_first_name || ' ' || t_change_admin.uiuser_last_name AS change_admin, + t_change_admin.uiuser_id AS change_admin_id, + t_doku_admin.uiuser_first_name || ' ' || t_doku_admin.uiuser_last_name AS doku_admin, + t_doku_admin.uiuser_id AS doku_admin_id, + security_relevant, + usr.user_name AS unique_name, + CAST (NULL AS VARCHAR) AS change_diffs, + CAST (NULL AS VARCHAR) AS change_new_element + FROM + changelog_user + LEFT JOIN (import_control LEFT JOIN management using (mgm_id)) using (control_id) + LEFT JOIN usr ON (old_user_id=user_id) + LEFT JOIN uiuser AS t_change_admin ON (changelog_user.import_admin=t_change_admin.uiuser_id) + LEFT JOIN uiuser AS t_doku_admin ON (changelog_user.doku_admin=t_doku_admin.uiuser_id) + WHERE change_type_id = 3 AND security_relevant AND change_action='D' AND successful_import + UNION + SELECT + abs_change_id, + log_usr_id AS local_change_id, + change_request_info, + CAST('usr' AS VARCHAR) as change_element, + CAST('basic_element' AS VARCHAR) as change_element_order, + changelog_user.old_user_id AS old_id, + changelog_user.new_user_id AS new_id, + changelog_user.documented as change_documented, + changelog_user.change_type_id as change_type_id, + change_action as change_type, + changelog_user_comment as change_comment, + user_comment as obj_comment, + import_control.start_time AS change_time, + management.mgm_name AS mgm_name, + management.mgm_id AS mgm_id, + CAST(NULL AS VARCHAR) as dev_name, + CAST(NULL AS INTEGER) as dev_id, + t_change_admin.uiuser_first_name || ' ' || t_change_admin.uiuser_last_name AS change_admin, + t_change_admin.uiuser_id AS change_admin_id, + t_doku_admin.uiuser_first_name || ' ' || t_doku_admin.uiuser_last_name AS doku_admin, + t_doku_admin.uiuser_id AS doku_admin_id, + security_relevant, + usr.user_name AS unique_name, + CAST (NULL AS VARCHAR) AS change_diffs, + CAST (NULL AS VARCHAR) AS change_new_element + FROM + changelog_user + LEFT JOIN (import_control LEFT JOIN management using (mgm_id)) using (control_id) + LEFT JOIN usr ON (new_user_id=user_id) + LEFT JOIN uiuser AS t_change_admin ON (changelog_user.import_admin=t_change_admin.uiuser_id) + LEFT JOIN uiuser AS t_doku_admin ON (changelog_user.doku_admin=t_doku_admin.uiuser_id) + WHERE change_type_id = 3 AND security_relevant AND change_action<>'D' AND successful_import; + +--------------------------------------------------------------------------------------------- +-- service views +--------------------------------------------------------------------------------------------- + +CREATE OR REPLACE VIEW view_svc_changes AS + SELECT + abs_change_id, + log_svc_id AS local_change_id, + change_request_info, + CAST('service' AS VARCHAR) as change_element, + CAST('basic_element' AS VARCHAR) as change_element_order, + changelog_service.old_svc_id AS old_id, + changelog_service.new_svc_id AS new_id, + changelog_service.documented as change_documented, + changelog_service.change_type_id as change_type_id, + change_action as change_type, + changelog_svc_comment as change_comment, + svc_comment as obj_comment, + import_control.start_time AS change_time, + management.mgm_name AS mgm_name, + management.mgm_id AS mgm_id, + CAST(NULL AS VARCHAR) as dev_name, + CAST(NULL AS INTEGER) as dev_id, + t_change_admin.uiuser_first_name || ' ' || t_change_admin.uiuser_last_name AS change_admin, + t_change_admin.uiuser_id AS change_admin_id, + t_doku_admin.uiuser_first_name || ' ' || t_doku_admin.uiuser_last_name AS doku_admin, + t_doku_admin.uiuser_id AS doku_admin_id, + security_relevant, + service.svc_name AS unique_name, + CAST (NULL AS VARCHAR) AS change_diffs, + CAST (NULL AS VARCHAR) AS change_new_element + FROM + changelog_service + LEFT JOIN (import_control LEFT JOIN management using (mgm_id)) using (control_id) + LEFT JOIN service ON (old_svc_id=svc_id) + LEFT JOIN uiuser AS t_change_admin ON (changelog_service.import_admin=t_change_admin.uiuser_id) + LEFT JOIN uiuser AS t_doku_admin ON (changelog_service.doku_admin=t_doku_admin.uiuser_id) + WHERE change_type_id = 3 AND security_relevant AND change_action='D' AND successful_import + UNION + SELECT + abs_change_id, + log_svc_id AS local_change_id, + change_request_info, + CAST('service' AS VARCHAR) as change_element, + CAST('basic_element' AS VARCHAR) as change_element_order, + changelog_service.old_svc_id AS old_id, + changelog_service.new_svc_id AS new_id, + changelog_service.documented as change_documented, + changelog_service.change_type_id as change_type_id, + change_action as change_type, + changelog_svc_comment as change_comment, + svc_comment as obj_comment, + import_control.start_time AS change_time, + management.mgm_name AS mgm_name, + management.mgm_id AS mgm_id, + CAST(NULL AS VARCHAR) as dev_name, + CAST(NULL AS INTEGER) as dev_id, + t_change_admin.uiuser_first_name || ' ' || t_change_admin.uiuser_last_name AS change_admin, + t_change_admin.uiuser_id AS change_admin_id, + t_doku_admin.uiuser_first_name || ' ' || t_doku_admin.uiuser_last_name AS doku_admin, + t_doku_admin.uiuser_id AS doku_admin_id, + security_relevant, + service.svc_name AS unique_name, + CAST (NULL AS VARCHAR) AS change_diffs, + CAST (NULL AS VARCHAR) AS change_new_element + FROM + changelog_service + LEFT JOIN (import_control LEFT JOIN management using (mgm_id)) using (control_id) + LEFT JOIN service ON (new_svc_id=svc_id) + LEFT JOIN uiuser AS t_change_admin ON (changelog_service.import_admin=t_change_admin.uiuser_id) + LEFT JOIN uiuser AS t_doku_admin ON (changelog_service.doku_admin=t_doku_admin.uiuser_id) + WHERE change_type_id = 3 AND security_relevant AND change_action<>'D' AND successful_import; + +--------------------------------------------------------------------------------------------- +-- rule views +--------------------------------------------------------------------------------------------- + + +CREATE OR REPLACE VIEW view_rule_changes AS + SELECT -- first select for deleted rules (join over old_rule_id) + abs_change_id, + log_rule_id AS local_change_id, + change_request_info, + CAST('rule' AS VARCHAR) as change_element, + CAST('rule_element' AS VARCHAR) as change_element_order, + changelog_rule.old_rule_id AS old_id, + changelog_rule.new_rule_id AS new_id, + changelog_rule.documented as change_documented, + changelog_rule.change_type_id as change_type_id, + change_action as change_type, + changelog_rule_comment as change_comment, + rule_comment as obj_comment, + import_control.start_time AS change_time, + management.mgm_name AS mgm_name, + management.mgm_id AS mgm_id, + device.dev_name, + device.dev_id, + CAST(t_change_admin.uiuser_first_name || ' ' || t_change_admin.uiuser_last_name AS VARCHAR) AS change_admin, + t_change_admin.uiuser_id AS change_admin_id, + CAST (t_doku_admin.uiuser_first_name || ' ' || t_doku_admin.uiuser_last_name AS VARCHAR) AS doku_admin, + t_doku_admin.uiuser_id AS doku_admin_id, + security_relevant, + CAST((COALESCE (rule.rule_ruleid, rule.rule_uid) || ', Rulebase: ' || device.local_rulebase_name) AS VARCHAR) AS unique_name, + CAST (NULL AS VARCHAR) AS change_diffs, + CAST (NULL AS VARCHAR) AS change_new_element + FROM + changelog_rule + LEFT JOIN (import_control LEFT JOIN management using (mgm_id)) using (control_id) + LEFT JOIN rule ON (old_rule_id=rule_id) + LEFT JOIN device ON (changelog_rule.dev_id=device.dev_id) + LEFT JOIN uiuser AS t_change_admin ON (t_change_admin.uiuser_id=changelog_rule.import_admin) + LEFT JOIN uiuser AS t_doku_admin ON (changelog_rule.doku_admin=t_doku_admin.uiuser_id) + WHERE changelog_rule.change_action='D' AND change_type_id = 3 AND security_relevant AND successful_import + + UNION + + SELECT -- second select for changed or inserted rules (join over new_rule_id) + abs_change_id, + log_rule_id AS local_change_id, + change_request_info, + CAST('rule' AS VARCHAR) as change_element, + CAST('rule_element' AS VARCHAR) as change_element_order, + changelog_rule.old_rule_id AS old_id, + changelog_rule.new_rule_id AS new_id, + changelog_rule.documented as change_documented, + changelog_rule.change_type_id as change_type_id, + change_action as change_type, + changelog_rule_comment as change_comment, + rule_comment as obj_comment, + import_control.start_time AS change_time, + management.mgm_name AS mgm_name, + management.mgm_id AS mgm_id, + device.dev_name, + device.dev_id, + CAST(t_change_admin.uiuser_first_name || ' ' || t_change_admin.uiuser_last_name AS VARCHAR) AS change_admin, + t_change_admin.uiuser_id AS change_admin_id, + CAST (t_doku_admin.uiuser_first_name || ' ' || t_doku_admin.uiuser_last_name AS VARCHAR) AS doku_admin, + t_doku_admin.uiuser_id AS doku_admin_id, + security_relevant, + CAST((COALESCE (rule.rule_ruleid, rule.rule_uid) || ', Rulebase: ' || device.local_rulebase_name) AS VARCHAR) AS unique_name, + CAST (NULL AS VARCHAR) AS change_diffs, + CAST (NULL AS VARCHAR) AS change_new_element + FROM + changelog_rule + LEFT JOIN (import_control LEFT JOIN management using (mgm_id)) using (control_id) + LEFT JOIN rule ON (new_rule_id=rule_id) + LEFT JOIN device ON (changelog_rule.dev_id=device.dev_id) + LEFT JOIN uiuser AS t_change_admin ON (t_change_admin.uiuser_id=changelog_rule.import_admin) + LEFT JOIN uiuser AS t_doku_admin ON (changelog_rule.doku_admin=t_doku_admin.uiuser_id) + WHERE changelog_rule.change_action<>'D' AND change_type_id = 3 AND security_relevant AND successful_import; + +--------------------------------------------------------------------------------------------- +-- top level views +--------------------------------------------------------------------------------------------- + + +--- changes --------------------------------------------------------------------------------- + +CREATE OR REPLACE VIEW view_changes AS + (SELECT * FROM view_obj_changes) UNION + (SELECT * FROM view_rule_changes) UNION + (SELECT * FROM view_svc_changes) UNION + (SELECT * FROM view_user_changes) + ORDER BY change_time,mgm_name,change_admin,change_element_order; + +CREATE OR REPLACE VIEW view_reportable_changes AS + SELECT * FROM view_changes +-- WHERE change_type_id = 3 AND security_relevant + ORDER BY change_time,mgm_name,change_admin,change_element_order; + +-- einheitliche View auf source und destination aller regeln - Verwendung in ChangeList bei tenant-Filterung +CREATE OR REPLACE VIEW view_rule_source_or_destination AS + SELECT rule.rule_id, rule.rule_dst_neg AS rule_neg, objgrp_flat.objgrp_flat_member_id AS obj_id + FROM rule + LEFT JOIN rule_to USING (rule_id) + LEFT JOIN objgrp_flat ON rule_to.obj_id = objgrp_flat.objgrp_flat_id + LEFT JOIN object ON objgrp_flat.objgrp_flat_member_id = object.obj_id +UNION + SELECT rule.rule_id, rule.rule_src_neg AS rule_neg, objgrp_flat.objgrp_flat_member_id AS obj_id + FROM rule + LEFT JOIN rule_from USING (rule_id) + LEFT JOIN objgrp_flat ON rule_from.obj_id = objgrp_flat.objgrp_flat_id + LEFT JOIN object ON objgrp_flat.objgrp_flat_member_id = object.obj_id; diff --git a/roles/database/files/sql/idempotent/fworch-views.sql b/roles/database/files/sql/idempotent/fworch-views.sql deleted file mode 100644 index 5a7fd8d02a..0000000000 --- a/roles/database/files/sql/idempotent/fworch-views.sql +++ /dev/null @@ -1,676 +0,0 @@ - ---------------------------------------------------------------------------------------------- --- object views ---------------------------------------------------------------------------------------------- -CREATE OR REPLACE VIEW view_obj_changes AS - SELECT - abs_change_id, - log_obj_id AS local_change_id, - get_request_str(CAST('object' as VARCHAR), changelog_object.log_obj_id) as change_request_info, - CAST('object' AS VARCHAR) as change_element, - CAST('basic_element' AS VARCHAR) as change_element_order, - changelog_object.old_obj_id AS old_id, - changelog_object.new_obj_id AS new_id, - changelog_object.documented as change_documented, - changelog_object.change_type_id as change_type_id, - change_action as change_type, - changelog_obj_comment as change_comment, - obj_comment, - import_control.start_time AS change_time, - management.mgm_name AS mgm_name, - management.mgm_id AS mgm_id, - CAST(NULL AS VARCHAR) as dev_name, - CAST(NULL AS INTEGER) as dev_id, - t_change_admin.uiuser_first_name || ' ' || t_change_admin.uiuser_last_name AS change_admin, - t_change_admin.uiuser_id AS change_admin_id, - t_doku_admin.uiuser_first_name || ' ' || t_doku_admin.uiuser_last_name AS doku_admin, - t_doku_admin.uiuser_id AS doku_admin_id, - security_relevant, - object.obj_name AS unique_name, - CAST (NULL AS VARCHAR) AS change_diffs, - CAST (NULL AS VARCHAR) AS change_new_element - FROM - changelog_object - LEFT JOIN (import_control LEFT JOIN management using (mgm_id)) using (control_id) - LEFT JOIN object ON (old_obj_id=obj_id) - LEFT JOIN uiuser AS t_change_admin ON (changelog_object.import_admin=t_change_admin.uiuser_id) - LEFT JOIN uiuser AS t_doku_admin ON (changelog_object.doku_admin=t_doku_admin.uiuser_id) - WHERE change_type_id = 3 AND security_relevant AND change_action='D' AND successful_import - - UNION - - SELECT - abs_change_id, - log_obj_id AS local_change_id, - get_request_str('object', changelog_object.log_obj_id) as change_request_info, - CAST('object' AS VARCHAR) as change_element, - CAST('basic_element' AS VARCHAR) as change_element_order, - changelog_object.old_obj_id AS old_id, - changelog_object.new_obj_id AS new_id, - changelog_object.documented as change_documented, - changelog_object.change_type_id as change_type_id, - change_action as change_type, - changelog_obj_comment as change_comment, - obj_comment, - import_control.start_time AS change_time, - management.mgm_name AS mgm_name, - management.mgm_id AS mgm_id, - CAST(NULL AS VARCHAR) as dev_name, - CAST(NULL AS INTEGER) as dev_id, - t_change_admin.uiuser_first_name || ' ' || t_change_admin.uiuser_last_name AS change_admin, - t_change_admin.uiuser_id AS change_admin_id, - t_doku_admin.uiuser_first_name || ' ' || t_doku_admin.uiuser_last_name AS doku_admin, - t_doku_admin.uiuser_id AS doku_admin_id, - security_relevant, - object.obj_name AS unique_name, - CAST (NULL AS VARCHAR) AS change_diffs, - CAST (NULL AS VARCHAR) AS change_new_element - FROM - changelog_object - LEFT JOIN (import_control LEFT JOIN management using (mgm_id)) using (control_id) - LEFT JOIN object ON (new_obj_id=obj_id) - LEFT JOIN uiuser AS t_change_admin ON (changelog_object.import_admin=t_change_admin.uiuser_id) - LEFT JOIN uiuser AS t_doku_admin ON (changelog_object.doku_admin=t_doku_admin.uiuser_id) - WHERE change_type_id = 3 AND security_relevant AND change_action<>'D' AND successful_import; - - ---------------------------------------------------------------------------------------------- --- user views ---------------------------------------------------------------------------------------------- - -CREATE OR REPLACE VIEW view_user_changes AS - SELECT - abs_change_id, - log_usr_id AS local_change_id, - change_request_info, - CAST('usr' AS VARCHAR) as change_element, - CAST('basic_element' AS VARCHAR) as change_element_order, - changelog_user.old_user_id AS old_id, - changelog_user.new_user_id AS new_id, - changelog_user.documented as change_documented, - changelog_user.change_type_id as change_type_id, - change_action as change_type, - changelog_user_comment as change_comment, - user_comment as obj_comment, - import_control.start_time AS change_time, - management.mgm_name AS mgm_name, - management.mgm_id AS mgm_id, - CAST(NULL AS VARCHAR) as dev_name, - CAST(NULL AS INTEGER) as dev_id, - t_change_admin.uiuser_first_name || ' ' || t_change_admin.uiuser_last_name AS change_admin, - t_change_admin.uiuser_id AS change_admin_id, - t_doku_admin.uiuser_first_name || ' ' || t_doku_admin.uiuser_last_name AS doku_admin, - t_doku_admin.uiuser_id AS doku_admin_id, - security_relevant, - usr.user_name AS unique_name, - CAST (NULL AS VARCHAR) AS change_diffs, - CAST (NULL AS VARCHAR) AS change_new_element - FROM - changelog_user - LEFT JOIN (import_control LEFT JOIN management using (mgm_id)) using (control_id) - LEFT JOIN usr ON (old_user_id=user_id) - LEFT JOIN uiuser AS t_change_admin ON (changelog_user.import_admin=t_change_admin.uiuser_id) - LEFT JOIN uiuser AS t_doku_admin ON (changelog_user.doku_admin=t_doku_admin.uiuser_id) - WHERE change_type_id = 3 AND security_relevant AND change_action='D' AND successful_import - UNION - SELECT - abs_change_id, - log_usr_id AS local_change_id, - change_request_info, - CAST('usr' AS VARCHAR) as change_element, - CAST('basic_element' AS VARCHAR) as change_element_order, - changelog_user.old_user_id AS old_id, - changelog_user.new_user_id AS new_id, - changelog_user.documented as change_documented, - changelog_user.change_type_id as change_type_id, - change_action as change_type, - changelog_user_comment as change_comment, - user_comment as obj_comment, - import_control.start_time AS change_time, - management.mgm_name AS mgm_name, - management.mgm_id AS mgm_id, - CAST(NULL AS VARCHAR) as dev_name, - CAST(NULL AS INTEGER) as dev_id, - t_change_admin.uiuser_first_name || ' ' || t_change_admin.uiuser_last_name AS change_admin, - t_change_admin.uiuser_id AS change_admin_id, - t_doku_admin.uiuser_first_name || ' ' || t_doku_admin.uiuser_last_name AS doku_admin, - t_doku_admin.uiuser_id AS doku_admin_id, - security_relevant, - usr.user_name AS unique_name, - CAST (NULL AS VARCHAR) AS change_diffs, - CAST (NULL AS VARCHAR) AS change_new_element - FROM - changelog_user - LEFT JOIN (import_control LEFT JOIN management using (mgm_id)) using (control_id) - LEFT JOIN usr ON (new_user_id=user_id) - LEFT JOIN uiuser AS t_change_admin ON (changelog_user.import_admin=t_change_admin.uiuser_id) - LEFT JOIN uiuser AS t_doku_admin ON (changelog_user.doku_admin=t_doku_admin.uiuser_id) - WHERE change_type_id = 3 AND security_relevant AND change_action<>'D' AND successful_import; - ---------------------------------------------------------------------------------------------- --- service views ---------------------------------------------------------------------------------------------- - -CREATE OR REPLACE VIEW view_svc_changes AS - SELECT - abs_change_id, - log_svc_id AS local_change_id, - change_request_info, - CAST('service' AS VARCHAR) as change_element, - CAST('basic_element' AS VARCHAR) as change_element_order, - changelog_service.old_svc_id AS old_id, - changelog_service.new_svc_id AS new_id, - changelog_service.documented as change_documented, - changelog_service.change_type_id as change_type_id, - change_action as change_type, - changelog_svc_comment as change_comment, - svc_comment as obj_comment, - import_control.start_time AS change_time, - management.mgm_name AS mgm_name, - management.mgm_id AS mgm_id, - CAST(NULL AS VARCHAR) as dev_name, - CAST(NULL AS INTEGER) as dev_id, - t_change_admin.uiuser_first_name || ' ' || t_change_admin.uiuser_last_name AS change_admin, - t_change_admin.uiuser_id AS change_admin_id, - t_doku_admin.uiuser_first_name || ' ' || t_doku_admin.uiuser_last_name AS doku_admin, - t_doku_admin.uiuser_id AS doku_admin_id, - security_relevant, - service.svc_name AS unique_name, - CAST (NULL AS VARCHAR) AS change_diffs, - CAST (NULL AS VARCHAR) AS change_new_element - FROM - changelog_service - LEFT JOIN (import_control LEFT JOIN management using (mgm_id)) using (control_id) - LEFT JOIN service ON (old_svc_id=svc_id) - LEFT JOIN uiuser AS t_change_admin ON (changelog_service.import_admin=t_change_admin.uiuser_id) - LEFT JOIN uiuser AS t_doku_admin ON (changelog_service.doku_admin=t_doku_admin.uiuser_id) - WHERE change_type_id = 3 AND security_relevant AND change_action='D' AND successful_import - UNION - SELECT - abs_change_id, - log_svc_id AS local_change_id, - change_request_info, - CAST('service' AS VARCHAR) as change_element, - CAST('basic_element' AS VARCHAR) as change_element_order, - changelog_service.old_svc_id AS old_id, - changelog_service.new_svc_id AS new_id, - changelog_service.documented as change_documented, - changelog_service.change_type_id as change_type_id, - change_action as change_type, - changelog_svc_comment as change_comment, - svc_comment as obj_comment, - import_control.start_time AS change_time, - management.mgm_name AS mgm_name, - management.mgm_id AS mgm_id, - CAST(NULL AS VARCHAR) as dev_name, - CAST(NULL AS INTEGER) as dev_id, - t_change_admin.uiuser_first_name || ' ' || t_change_admin.uiuser_last_name AS change_admin, - t_change_admin.uiuser_id AS change_admin_id, - t_doku_admin.uiuser_first_name || ' ' || t_doku_admin.uiuser_last_name AS doku_admin, - t_doku_admin.uiuser_id AS doku_admin_id, - security_relevant, - service.svc_name AS unique_name, - CAST (NULL AS VARCHAR) AS change_diffs, - CAST (NULL AS VARCHAR) AS change_new_element - FROM - changelog_service - LEFT JOIN (import_control LEFT JOIN management using (mgm_id)) using (control_id) - LEFT JOIN service ON (new_svc_id=svc_id) - LEFT JOIN uiuser AS t_change_admin ON (changelog_service.import_admin=t_change_admin.uiuser_id) - LEFT JOIN uiuser AS t_doku_admin ON (changelog_service.doku_admin=t_doku_admin.uiuser_id) - WHERE change_type_id = 3 AND security_relevant AND change_action<>'D' AND successful_import; - ---------------------------------------------------------------------------------------------- --- rule views ---------------------------------------------------------------------------------------------- - - -CREATE OR REPLACE VIEW view_rule_changes AS - SELECT -- first select for deleted rules (join over old_rule_id) - abs_change_id, - log_rule_id AS local_change_id, - change_request_info, - CAST('rule' AS VARCHAR) as change_element, - CAST('rule_element' AS VARCHAR) as change_element_order, - changelog_rule.old_rule_id AS old_id, - changelog_rule.new_rule_id AS new_id, - changelog_rule.documented as change_documented, - changelog_rule.change_type_id as change_type_id, - change_action as change_type, - changelog_rule_comment as change_comment, - rule_comment as obj_comment, - import_control.start_time AS change_time, - management.mgm_name AS mgm_name, - management.mgm_id AS mgm_id, - device.dev_name, - device.dev_id, - CAST(t_change_admin.uiuser_first_name || ' ' || t_change_admin.uiuser_last_name AS VARCHAR) AS change_admin, - t_change_admin.uiuser_id AS change_admin_id, - CAST (t_doku_admin.uiuser_first_name || ' ' || t_doku_admin.uiuser_last_name AS VARCHAR) AS doku_admin, - t_doku_admin.uiuser_id AS doku_admin_id, - security_relevant, - CAST((COALESCE (rule.rule_ruleid, rule.rule_uid) || ', Rulebase: ' || device.local_rulebase_name) AS VARCHAR) AS unique_name, - CAST (NULL AS VARCHAR) AS change_diffs, - CAST (NULL AS VARCHAR) AS change_new_element - FROM - changelog_rule - LEFT JOIN (import_control LEFT JOIN management using (mgm_id)) using (control_id) - LEFT JOIN rule ON (old_rule_id=rule_id) - LEFT JOIN device ON (changelog_rule.dev_id=device.dev_id) - LEFT JOIN uiuser AS t_change_admin ON (t_change_admin.uiuser_id=changelog_rule.import_admin) - LEFT JOIN uiuser AS t_doku_admin ON (changelog_rule.doku_admin=t_doku_admin.uiuser_id) - WHERE changelog_rule.change_action='D' AND change_type_id = 3 AND security_relevant AND successful_import - - UNION - - SELECT -- second select for changed or inserted rules (join over new_rule_id) - abs_change_id, - log_rule_id AS local_change_id, - change_request_info, - CAST('rule' AS VARCHAR) as change_element, - CAST('rule_element' AS VARCHAR) as change_element_order, - changelog_rule.old_rule_id AS old_id, - changelog_rule.new_rule_id AS new_id, - changelog_rule.documented as change_documented, - changelog_rule.change_type_id as change_type_id, - change_action as change_type, - changelog_rule_comment as change_comment, - rule_comment as obj_comment, - import_control.start_time AS change_time, - management.mgm_name AS mgm_name, - management.mgm_id AS mgm_id, - device.dev_name, - device.dev_id, - CAST(t_change_admin.uiuser_first_name || ' ' || t_change_admin.uiuser_last_name AS VARCHAR) AS change_admin, - t_change_admin.uiuser_id AS change_admin_id, - CAST (t_doku_admin.uiuser_first_name || ' ' || t_doku_admin.uiuser_last_name AS VARCHAR) AS doku_admin, - t_doku_admin.uiuser_id AS doku_admin_id, - security_relevant, - CAST((COALESCE (rule.rule_ruleid, rule.rule_uid) || ', Rulebase: ' || device.local_rulebase_name) AS VARCHAR) AS unique_name, - CAST (NULL AS VARCHAR) AS change_diffs, - CAST (NULL AS VARCHAR) AS change_new_element - FROM - changelog_rule - LEFT JOIN (import_control LEFT JOIN management using (mgm_id)) using (control_id) - LEFT JOIN rule ON (new_rule_id=rule_id) - LEFT JOIN device ON (changelog_rule.dev_id=device.dev_id) - LEFT JOIN uiuser AS t_change_admin ON (t_change_admin.uiuser_id=changelog_rule.import_admin) - LEFT JOIN uiuser AS t_doku_admin ON (changelog_rule.doku_admin=t_doku_admin.uiuser_id) - WHERE changelog_rule.change_action<>'D' AND change_type_id = 3 AND security_relevant AND successful_import; - ---------------------------------------------------------------------------------------------- --- top level views ---------------------------------------------------------------------------------------------- - - ---- changes --------------------------------------------------------------------------------- - -CREATE OR REPLACE VIEW view_changes AS - (SELECT * FROM view_obj_changes) UNION - (SELECT * FROM view_rule_changes) UNION - (SELECT * FROM view_svc_changes) UNION - (SELECT * FROM view_user_changes) - ORDER BY change_time,mgm_name,change_admin,change_element_order; - -CREATE OR REPLACE VIEW view_undocumented_changes AS - SELECT * FROM view_changes - WHERE --- change_type_id = 3 AND security_relevant AND - NOT change_documented - ORDER BY change_time,mgm_name,change_admin,change_element_order; - -CREATE OR REPLACE VIEW view_reportable_changes AS - SELECT * FROM view_changes --- WHERE change_type_id = 3 AND security_relevant - ORDER BY change_time,mgm_name,change_admin,change_element_order; - --- Zusammenfassung aller geaenderten Element-IDs (erzeugt #(change_type='C') mehr Eintr�ge) --- erzeugt keine Dubletten unter der Praemisse, dass stets old_id<>new_id -CREATE OR REPLACE VIEW view_changes_by_changed_element_id AS - SELECT old_id as element_id, * FROM view_reportable_changes WHERE NOT old_id IS NULL - UNION - SELECT new_id as element_id, * FROM view_reportable_changes WHERE NOT new_id IS NULL; - --- slim view for counting number of changes - -CREATE OR REPLACE VIEW view_change_counter AS - (SELECT mgm_id,CAST(NULL AS INTEGER) as dev_id,import_admin,abs_change_id,documented FROM changelog_user WHERE change_type_id=3 AND security_relevant) - UNION - (SELECT mgm_id,CAST(NULL AS INTEGER) as dev_id,import_admin,abs_change_id,documented FROM changelog_object WHERE change_type_id=3 AND security_relevant) - UNION - (SELECT mgm_id,CAST(NULL AS INTEGER) as dev_id,import_admin,abs_change_id,documented FROM changelog_service WHERE change_type_id=3 AND security_relevant) - UNION - (SELECT mgm_id,dev_id,import_admin,abs_change_id,documented FROM changelog_rule WHERE change_type_id=3 AND security_relevant); - -CREATE OR REPLACE VIEW view_undocumented_change_counter AS - SELECT * FROM view_change_counter WHERE NOT documented; - -CREATE OR REPLACE VIEW view_documented_change_counter AS - SELECT * FROM view_change_counter WHERE documented; - --- einheitliche View auf source und destination aller regeln - Verwendung in ChangeList bei tenant-Filterung -CREATE OR REPLACE VIEW view_rule_source_or_destination AS - SELECT rule.rule_id, rule.rule_dst_neg AS rule_neg, objgrp_flat.objgrp_flat_member_id AS obj_id - FROM rule - LEFT JOIN rule_to USING (rule_id) - LEFT JOIN objgrp_flat ON rule_to.obj_id = objgrp_flat.objgrp_flat_id - LEFT JOIN object ON objgrp_flat.objgrp_flat_member_id = object.obj_id -UNION - SELECT rule.rule_id, rule.rule_src_neg AS rule_neg, objgrp_flat.objgrp_flat_member_id AS obj_id - FROM rule - LEFT JOIN rule_from USING (rule_id) - LEFT JOIN objgrp_flat ON rule_from.obj_id = objgrp_flat.objgrp_flat_id - LEFT JOIN object ON objgrp_flat.objgrp_flat_member_id = object.obj_id; - ---- import status ----------------------------------------------------------------------------- - -CREATE OR REPLACE VIEW view_import_status_successful AS - SELECT mgm_id, mgm_name, dev_typ_name, do_not_import, MAX(last_import) AS last_import, MAX(import_count_24hours) AS import_count_24hours FROM ( - SELECT management.mgm_id, mgm_name, dev_typ_name, do_not_import, successful_import, MAX(start_time) AS last_import, - COUNT(import_control.control_id) AS import_count_24hours - FROM management LEFT JOIN import_control ON (management.mgm_id=import_control.mgm_id) - LEFT JOIN stm_dev_typ USING (dev_typ_id) - WHERE start_time>(now() - interval '24 hours') AND successful_import AND NOT stop_time IS NULL - GROUP BY management.mgm_id, mgm_name, successful_import, do_not_import, dev_typ_name - UNION - SELECT management.mgm_id, mgm_name, dev_typ_name, do_not_import, successful_import, MAX(start_time) AS last_import, - 0 AS import_count_24hours - FROM management LEFT JOIN import_control ON (management.mgm_id=import_control.mgm_id) - LEFT JOIN stm_dev_typ USING (dev_typ_id) - WHERE start_time<=(now() - interval '24 hours') AND successful_import AND NOT stop_time IS NULL - GROUP BY management.mgm_id, mgm_name, successful_import, do_not_import, dev_typ_name - UNION - SELECT management.mgm_id, mgm_name, dev_typ_name, do_not_import, successful_import, NULL AS last_import, - 0 AS import_count_24hours - FROM management LEFT JOIN import_control USING (mgm_id) - LEFT JOIN stm_dev_typ USING (dev_typ_id) - WHERE successful_import IS NULL - GROUP BY management.mgm_id, mgm_name, successful_import, do_not_import, dev_typ_name - ) AS foo GROUP BY mgm_id, mgm_name, successful_import, do_not_import, dev_typ_name ORDER BY dev_typ_name, mgm_name; - -CREATE OR REPLACE VIEW view_import_status_errors AS - SELECT mgm_id, mgm_name, dev_typ_name, do_not_import, MAX(last_import) AS last_import, MAX(import_count_24hours) AS import_count_24hours, import_errors FROM ( - SELECT management.mgm_id, mgm_name, dev_typ_name, do_not_import, successful_import, MAX(start_time) AS last_import, - COUNT(import_control.control_id) AS import_count_24hours, import_control.import_errors - FROM management LEFT JOIN import_control ON (management.mgm_id=import_control.mgm_id) - LEFT JOIN stm_dev_typ USING (dev_typ_id) - WHERE start_time>(now() - interval '24 hours') AND NOT successful_import AND NOT stop_time IS NULL - GROUP BY management.mgm_id, mgm_name, successful_import, do_not_import, dev_typ_name, import_errors --- UNION ALL --- SELECT management.mgm_id, mgm_name, dev_typ_name, do_not_import, successful_import, MAX(start_time) AS last_import, --- 0 AS import_count_24hours, NULL AS import_errors --- FROM management LEFT JOIN import_control ON (management.mgm_id=import_control.mgm_id) --- LEFT JOIN stm_dev_typ USING (dev_typ_id) --- WHERE start_time<=(now() - interval '24 hours') AND NOT successful_import --- GROUP BY management.mgm_id, mgm_name, successful_import, do_not_import, dev_typ_name, import_errors - UNION - SELECT management.mgm_id, mgm_name, dev_typ_name, do_not_import, successful_import, NULL AS last_import, - 0 AS import_count_24hours, NULL AS import_errors - FROM management LEFT JOIN import_control USING (mgm_id) - LEFT JOIN stm_dev_typ USING (dev_typ_id) - WHERE successful_import IS NULL AND NOT stop_time IS NULL - GROUP BY management.mgm_id, mgm_name, successful_import, do_not_import, dev_typ_name, import_errors - ) AS foo --- WHERE NOT import_errors IS NULL - GROUP BY mgm_id, mgm_name, successful_import, do_not_import, dev_typ_name, import_errors ORDER BY dev_typ_name, mgm_name; - -CREATE OR REPLACE VIEW view_import_status_table_unsorted AS - SELECT *, - CASE - WHEN import_is_active AND import_count_successful=0 AND import_count_errors>=5 THEN VARCHAR 'red' - WHEN (NOT import_is_active AND last_successful_import IS NULL AND last_import_with_errors IS NULL) - OR (last_successful_import>last_import_with_errors) THEN VARCHAR 'green' - WHEN (last_successful_import IS NULL AND last_import_with_errors IS NULL) - OR (last_successful_import>tenant_net_ip OR obj_ip=tenant_net_ip)) - OR (rule_dst_neg AND (NOT obj_ip<>tenant_net_ip AND NOT obj_ip=tenant_net_ip)) - ) - WHERE rule_head_text IS NULL - UNION - SELECT rule.rule_id, rule.rule_create, rule.rule_last_seen, tenant_network.tenant_id, rule.mgm_id, rule_order.dev_id - FROM rule - LEFT JOIN rule_order ON (rule.rule_id=rule_order.rule_id) - LEFT JOIN rule_from ON (rule.rule_id=rule_from.rule_id) - LEFT JOIN objgrp_flat ON (rule_from.obj_id=objgrp_flat.objgrp_flat_id) - LEFT JOIN object ON (objgrp_flat.objgrp_flat_member_id=object.obj_id) - LEFT JOIN tenant_network ON - ( - (NOT rule_src_neg AND (obj_ip<>tenant_net_ip OR obj_ip=tenant_net_ip)) - OR (rule_src_neg AND (NOT obj_ip<>tenant_net_ip AND NOT obj_ip=tenant_net_ip)) - ) - WHERE rule_head_text IS NULL - ) AS x; -- GROUP BY rule_id,tenant_id,mgm_id,rule_create, rule_last_seen - --- examples for tenant filtering: --- select rule_id from view_tenant_rules where tenant_network.tenant_id=1 and rule.mgm_id=4 --- select rule_id,rule_create from view_tenant_rules where mgm_id=4 group by rule_id,rule_create -*/ - - -CREATE OR REPLACE VIEW view_device_names AS - SELECT 'Management: ' || mgm_name || ', Device: ' || dev_name AS dev_string, dev_id, mgm_id, dev_name, mgm_name FROM device LEFT JOIN management USING (mgm_id); - --- view for ip address filtering -DROP MATERIALIZED VIEW IF EXISTS nw_object_limits; -CREATE MATERIALIZED VIEW nw_object_limits AS - select obj_id, mgm_id, - host ( object.obj_ip )::cidr as first_ip, - CASE - WHEN object.obj_ip_end IS NULL - THEN host(broadcast(object.obj_ip))::cidr - ELSE host(broadcast(object.obj_ip_end))::cidr - END last_ip - from object; - --- adding indexes for view -Create index IF NOT EXISTS idx_nw_object_limits_obj_id on nw_object_limits (obj_id); -Create index IF NOT EXISTS idx_nw_object_limits_mgm_id on nw_object_limits (mgm_id); - -DROP MATERIALIZED VIEW IF EXISTS view_tenant_rules; -CREATE MATERIALIZED VIEW IF NOT EXISTS view_tenant_rules AS - select tenant_rules.* from ( - SELECT rule.*, tenant_network.tenant_id - FROM rule - LEFT JOIN rule_to ON (rule.rule_id=rule_to.rule_id) - LEFT JOIN objgrp_flat ON (rule_to.obj_id=objgrp_flat_id) - LEFT JOIN object ON (objgrp_flat_member_id=object.obj_id) - LEFT JOIN tenant_network ON - ( NOT rule_dst_neg AND (obj_ip>>=tenant_net_ip OR obj_ip<<=tenant_net_ip)) - WHERE rule_head_text IS NULL - UNION - SELECT rule.*, tenant_network.tenant_id - FROM rule - LEFT JOIN rule_from ON (rule.rule_id=rule_from.rule_id) - LEFT JOIN objgrp_flat ON (rule_from.obj_id=objgrp_flat.objgrp_flat_id) - LEFT JOIN object ON (objgrp_flat.objgrp_flat_member_id=object.obj_id) - LEFT JOIN tenant_network ON - ( NOT rule_src_neg AND (obj_ip>>=tenant_net_ip OR obj_ip<<=tenant_net_ip) ) - WHERE rule_head_text IS NULL - ) AS tenant_rules; - --- adding indexes for view -Create index IF NOT EXISTS idx_view_tenant_rules_tenant_id on view_tenant_rules(tenant_id); -Create index IF NOT EXISTS idx_view_tenant_rules_mgm_id on view_tenant_rules(mgm_id); - -REFRESH MATERIALIZED VIEW view_tenant_rules; -GRANT SELECT ON TABLE view_tenant_rules TO GROUP secuadmins, reporters; -/* - - query filterRulesByTenant($importId: bigint) { - view_tenant_rules(where: {access_rule: {_eq: true}, rule_last_seen: {_gte: $importId}, rule_create: {_lte: $importId}}) { - rule_id - rule_src - rule_dst - rule_create - rule_last_seen - tenant_id - } - } - -*/ - --- example tenant_network data: --- insert into tenant_network (tenant_id, tenant_net_ip) values (123, '10.9.8.0/24'); - --- test query: --- select dev_id, rule_num_numeric, view_tenant_rules.rule_id, rule_src,rule_dst --- from view_tenant_rules --- where access_rule, tenant_id=123 and mgm_id=8 and rule_last_seen>=28520 --- order by dev_id asc, rule_num_numeric asc - - ----------------- --- recert views - -CREATE OR REPLACE VIEW v_active_access_allow_rules AS - SELECT * FROM rule r - WHERE r.active AND -- only show current (not historical) rules - r.access_rule AND -- only show access rules (no NAT) - r.rule_head_text IS NULL AND -- do not show header rules - NOT r.rule_disabled AND -- do not show disabled rules - NOT r.action_id IN (2,3,7); -- do not deal with deny rules - -CREATE OR REPLACE VIEW v_rule_with_src_owner AS - SELECT r.rule_id, owner.id as owner_id, owner_network.ip as matching_ip, 'source' AS match_in, owner.name as owner_name, - recert_interval, rule_metadata.rule_last_certified, rule_last_certifier - FROM v_active_access_allow_rules r - LEFT JOIN rule_from ON (r.rule_id=rule_from.rule_id) - LEFT JOIN objgrp_flat of ON (rule_from.obj_id=of.objgrp_flat_id) - LEFT JOIN object o ON (of.objgrp_flat_member_id=o.obj_id) - LEFT JOIN owner_network ON (o.obj_ip>>=owner_network.ip OR o.obj_ip<<=owner_network.ip) - LEFT JOIN owner ON (owner_network.owner_id=owner.id) - LEFT JOIN rule_metadata ON (r.rule_uid=rule_metadata.rule_uid AND r.dev_id=rule_metadata.dev_id) - WHERE NOT o.obj_ip IS NULL - GROUP BY r.rule_id, matching_ip, owner.id, owner.name, rule_metadata.rule_last_certified, rule_last_certifier; - -CREATE OR REPLACE VIEW v_rule_with_dst_owner AS - SELECT r.rule_id, owner.id as owner_id, owner_network.ip as matching_ip, 'destination' AS match_in, owner.name as owner_name, - recert_interval, rule_metadata.rule_last_certified, rule_last_certifier - FROM v_active_access_allow_rules r - LEFT JOIN rule_to ON (r.rule_id=rule_to.rule_id) - LEFT JOIN objgrp_flat of ON (rule_to.obj_id=of.objgrp_flat_id) - LEFT JOIN object o ON (of.objgrp_flat_member_id=o.obj_id) - LEFT JOIN owner_network ON (o.obj_ip>>=owner_network.ip OR o.obj_ip<<=owner_network.ip) - LEFT JOIN owner ON (owner_network.owner_id=owner.id) - LEFT JOIN rule_metadata ON (r.rule_uid=rule_metadata.rule_uid AND r.dev_id=rule_metadata.dev_id) - WHERE NOT o.obj_ip IS NULL - GROUP BY r.rule_id, matching_ip, owner.id, owner.name, rule_metadata.rule_last_certified, rule_last_certifier; - - -CREATE OR REPLACE FUNCTION purge_view_rule_with_owner () RETURNS VOID AS $$ -DECLARE - r_temp_record RECORD; -BEGIN - select INTO r_temp_record schemaname, viewname from pg_catalog.pg_views - where schemaname NOT IN ('pg_catalog', 'information_schema') and viewname='view_rule_with_owner' - order by schemaname, viewname; - IF FOUND THEN - DROP VIEW IF EXISTS view_rule_with_owner CASCADE; - END IF; - DROP MATERIALIZED VIEW IF EXISTS view_rule_with_owner CASCADE; - RETURN; -END; -$$ LANGUAGE plpgsql; - -SELECT * FROM purge_view_rule_with_owner (); -DROP FUNCTION purge_view_rule_with_owner(); - --- LargeOwnerChange: remove MATERIALIZED for small installations -CREATE MATERIALIZED VIEW view_rule_with_owner AS - SELECT DISTINCT r.rule_num_numeric, r.track_id, r.action_id, r.rule_from_zone, r.rule_to_zone, r.dev_id, r.mgm_id, r.rule_uid, uno.rule_id, uno.owner_id, uno.owner_name, uno.rule_last_certified, uno.rule_last_certifier, - rule_action, rule_name, rule_comment, rule_track, rule_src_neg, rule_dst_neg, rule_svc_neg, - rule_head_text, rule_disabled, access_rule, xlate_rule, nat_rule, - string_agg(DISTINCT match_in || ':' || matching_ip::VARCHAR, '; ' order by match_in || ':' || matching_ip::VARCHAR desc) as matches, - recert_interval - FROM ( SELECT DISTINCT * FROM v_rule_with_src_owner UNION SELECT DISTINCT * FROM v_rule_with_dst_owner ) AS uno - LEFT JOIN rule AS r USING (rule_id) - GROUP BY rule_id, owner_id, owner_name, rule_last_certified, rule_last_certifier, r.rule_from_zone, r.rule_to_zone, recert_interval, - r.dev_id, r.mgm_id, r.rule_uid, rule_num_numeric, track_id, action_id, rule_action, rule_name, rule_comment, rule_track, rule_src_neg, rule_dst_neg, rule_svc_neg, - rule_head_text, rule_disabled, access_rule, xlate_rule, nat_rule; - -------------------------- --- recert refresh trigger - -create or replace function refresh_view_rule_with_owner() -returns trigger language plpgsql -as $$ -begin - refresh materialized view view_rule_with_owner; - return null; -end $$; - -drop trigger IF exists refresh_view_rule_with_owner_delete_trigger ON recertification CASCADE; - -create trigger refresh_view_rule_with_owner_delete_trigger -after delete on recertification for each statement -execute procedure refresh_view_rule_with_owner(); - - ---------------------------------------------------------------------------------------------- --- GRANTS on exportable Views ---------------------------------------------------------------------------------------------- - -GRANT SELECT ON TABLE view_rule_with_owner TO GROUP secuadmins, reporters, configimporters; - --- views for secuadmins -GRANT SELECT ON TABLE view_change_counter TO GROUP secuadmins; -GRANT SELECT ON TABLE view_undocumented_change_counter TO GROUP secuadmins; -GRANT SELECT ON TABLE view_documented_change_counter TO GROUP secuadmins; -GRANT SELECT ON TABLE view_undocumented_changes TO GROUP secuadmins; - --- views used for reporters, too -GRANT SELECT ON TABLE view_reportable_changes TO GROUP secuadmins, reporters; -GRANT SELECT ON TABLE view_changes TO GROUP secuadmins, reporters; --- GRANT SELECT ON TABLE view_tenant_rules TO GROUP secuadmins, reporters; -GRANT SELECT ON TABLE view_changes_by_changed_element_id TO GROUP secuadmins, reporters; -GRANT SELECT ON TABLE view_device_names TO GROUP secuadmins, reporters; -GRANT SELECT ON TABLE view_rule_source_or_destination TO GROUP secuadmins, reporters; - --- view for import status -GRANT SELECT ON TABLE view_import_status_table TO fworch; -- {{fworch_home}}/bin/write_import_status_file.sh is run as fworch as it will also be invoked via cli -GRANT SELECT ON TABLE view_import_status_table TO GROUP secuadmins, reporters; -- not really neccessary diff --git a/roles/database/files/sql/idempotent/fworch-zone-import.sql b/roles/database/files/sql/idempotent/fworch-zone-import.sql deleted file mode 100644 index d94ee325c9..0000000000 --- a/roles/database/files/sql/idempotent/fworch-zone-import.sql +++ /dev/null @@ -1,59 +0,0 @@ - -CREATE OR REPLACE FUNCTION import_zone_main (BIGINT, BOOLEAN) RETURNS VOID AS $$ -DECLARE - i_current_import_id ALIAS FOR $1; -- ID des aktiven Imports - b_is_initial_import ALIAS FOR $2; -- ID des aktiven Imports - i_mgm_id INTEGER; -- zum Holen der mgm_ID fuer Loeschen von Objekten - r_zone RECORD; -- Datensatz mit einzelner obj_id aus import_object-Tabelle des zu importierenden Objekts -BEGIN - RAISE DEBUG 'import_zone_main 1 - start'; - SELECT INTO i_mgm_id mgm_id FROM import_control WHERE control_id=i_current_import_id; - RAISE DEBUG 'import_zone_main 2'; - FOR r_zone IN -- jedes Objekt wird mittels insert_single_nwobj eingefuegt - SELECT zone_name FROM import_zone WHERE control_id = i_current_import_id - LOOP - RAISE DEBUG 'importing zone %', r_zone.zone_name; - PERFORM import_zone_single(i_current_import_id,i_mgm_id,r_zone.zone_name,i_current_import_id); - END LOOP; - PERFORM import_zone_mark_deleted (i_current_import_id, i_mgm_id); - RETURN; -END; -$$ LANGUAGE plpgsql; - -CREATE OR REPLACE FUNCTION import_zone_single(BIGINT,INTEGER,VARCHAR,BIGINT) RETURNS VOID AS $$ -DECLARE - control_id ALIAS FOR $1; - i_mgm_id ALIAS FOR $2; - v_zone_name ALIAS FOR $3; - i_current_import_id ALIAS FOR $4; - r_existing_zone RECORD; -BEGIN - RAISE DEBUG 'start import_zone_single for zone %', v_zone_name; - -- zones need update of zone_last_seen - SELECT INTO r_existing_zone zone_name FROM zone WHERE mgm_id=i_mgm_id AND zone_name=v_zone_name; - IF FOUND THEN - UPDATE zone set zone_last_seen=i_current_import_id, active=TRUE where mgm_id=i_mgm_id AND zone_name=v_zone_name; - ELSE - INSERT INTO zone (mgm_id,zone_name,zone_create,zone_last_seen) - VALUES (i_mgm_id,v_zone_name,i_current_import_id,i_current_import_id); - END IF; - RAISE DEBUG 'end import_zone_single for zone %', v_zone_name; - RETURN; -END; -$$ LANGUAGE plpgsql; - - -CREATE OR REPLACE FUNCTION import_zone_mark_deleted(BIGINT,INTEGER) RETURNS VOID AS $$ -DECLARE - i_current_import_id ALIAS FOR $1; - i_mgm_id ALIAS FOR $2; - i_import_admin_id BIGINT; - i_previous_import_id BIGINT; -- zum Holen der import_ID des vorherigen Imports fuer das Mgmt -BEGIN - i_previous_import_id := get_previous_import_id_for_mgmt(i_mgm_id,i_current_import_id); - IF NOT i_previous_import_id IS NULL THEN -- wenn das Management nicht zum ersten Mal importiert wurde - UPDATE zone SET active='FALSE' WHERE mgm_id=i_mgm_id AND active AND zone_last_seen '' + GROUP BY + r.mgm_id, + btrim(ref.time_obj_uid) +) +INSERT INTO time_object ( + mgm_id, + time_obj_uid, + time_obj_name, + created +) +SELECT + referenced_time_objects.mgm_id, + referenced_time_objects.time_obj_uid, + referenced_time_objects.time_obj_uid, + referenced_time_objects.created +FROM referenced_time_objects +WHERE NOT EXISTS ( + SELECT 1 + FROM time_object AS t + WHERE t.mgm_id = referenced_time_objects.mgm_id + AND t.time_obj_uid = referenced_time_objects.time_obj_uid +); + +WITH rule_time_refs AS ( + SELECT DISTINCT + r.rule_id, + r.mgm_id, + r.rule_create AS created, + r.removed, + btrim(ref.time_obj_uid) AS time_obj_uid + FROM rule AS r + CROSS JOIN LATERAL unnest(string_to_array(COALESCE(r.rule_time, ''), '|')) AS ref(time_obj_uid) + WHERE btrim(ref.time_obj_uid) <> '' +) +INSERT INTO rule_time ( + rule_id, + time_obj_id, + created, + removed +) +SELECT + rtr.rule_id, + matched_time_object.time_obj_id, + rtr.created, + rtr.removed +FROM rule_time_refs AS rtr +JOIN LATERAL ( + SELECT t.time_obj_id + FROM time_object AS t + WHERE t.mgm_id = rtr.mgm_id + AND t.time_obj_uid = rtr.time_obj_uid + AND COALESCE(t.created, rtr.created) <= rtr.created + AND (t.removed IS NULL OR t.removed >= rtr.created) + ORDER BY t.created DESC NULLS LAST, t.time_obj_id DESC + LIMIT 1 +) AS matched_time_object ON TRUE +WHERE NOT EXISTS ( + SELECT 1 + FROM rule_time AS rt + WHERE rt.rule_id = rtr.rule_id + AND rt.time_obj_id = matched_time_object.time_obj_id + AND rt.created = rtr.created +); diff --git a/roles/database/files/sql/test/hasura-test.sql b/roles/database/files/sql/test/hasura-test.sql deleted file mode 100644 index bf6599c549..0000000000 --- a/roles/database/files/sql/test/hasura-test.sql +++ /dev/null @@ -1,31 +0,0 @@ - --- cannot test hasura before API was installed, so can only run this on upgrade - -BEGIN; - -CREATE EXTENSION IF NOT EXISTS pgtap; - --- CREATE OR REPLACE FUNCTION hdb_catalog.test_1_hdb_catalog_schema() --- RETURNS SETOF TEXT LANGUAGE plpgsql AS $$ --- BEGIN --- RETURN NEXT has_table( 'hdb_catalog.hdb_action_log' ); --- RETURN NEXT has_table( 'hdb_catalog.hdb_metadata' ); --- RETURN NEXT has_table( 'hdb_catalog.hdb_version' ); --- END; --- $$; - -CREATE OR REPLACE FUNCTION hdb_catalog.test_2_hdb_catalog_data() -RETURNS SETOF TEXT LANGUAGE plpgsql AS $$ -BEGIN - RETURN NEXT results_eq('SELECT cast((select COUNT(*) FROM hdb_catalog.hdb_metadata) as integer)', 'SELECT cast (1 as integer)', 'there should be exactly one metadata entry'); -END; -$$; - -CREATE OR REPLACE FUNCTION hdb_catalog.shutdown_1() RETURNS VOID LANGUAGE plpgsql AS $$ -BEGIN - drop function if exists hdb_catalog.test_1_hdb_catalog_schema(); - drop function if exists hdb_catalog.test_2_hdb_catalog_data(); -END; -$$; - -SELECT * FROM runtests('hdb_catalog'::name); diff --git a/roles/database/files/sql/test/unit-test-cleanup.sql b/roles/database/files/sql/test/unit-test-cleanup.sql deleted file mode 100644 index 340756871c..0000000000 --- a/roles/database/files/sql/test/unit-test-cleanup.sql +++ /dev/null @@ -1,3 +0,0 @@ -drop extension if exists pgtap; --- drop function if exists test_1_schema(); --- drop function if exists test_2_functions(); \ No newline at end of file diff --git a/roles/database/files/sql/test/unit-tests.sql b/roles/database/files/sql/test/unit-tests.sql deleted file mode 100644 index 2e18df85f8..0000000000 --- a/roles/database/files/sql/test/unit-tests.sql +++ /dev/null @@ -1,33 +0,0 @@ - -BEGIN; -CREATE EXTENSION IF NOT EXISTS pgtap; - -CREATE OR REPLACE FUNCTION public.test_1_schema() -RETURNS SETOF TEXT LANGUAGE plpgsql AS $$ -BEGIN - RETURN NEXT has_table( 'object' ); - RETURN NEXT has_table( 'rule' ); - RETURN NEXT has_table( 'service' ); - RETURN NEXT has_table( 'usr' ); - RETURN NEXT hasnt_table( 'rule_order' ); -END; -$$; - -CREATE OR REPLACE FUNCTION public.test_2_functions() -RETURNS SETOF TEXT LANGUAGE plpgsql AS $$ -BEGIN - RETURN NEXT results_eq('SELECT * FROM are_equal(CAST(''1.2.3.4'' AS CIDR),CAST(''1.2.3.4/32'' AS CIDR))', 'SELECT TRUE', 'cidr 1.2.3.4==1.2.3.4/32 are_equal should return true'); - RETURN NEXT results_eq('SELECT * FROM are_equal(''1.2.3.4'',''1.2.3.4/32'')', 'SELECT FALSE', 'string 1.2.3.4==1.2.3.4/32 are_equal should return false'); - RETURN NEXT results_eq('SELECT * FROM are_equal(7*0, 0)', 'SELECT TRUE', 'int are_equal should return true'); - RETURN NEXT results_eq('SELECT * FROM remove_spaces('' abc '')', 'SELECT CAST(''abc'' AS VARCHAR)', 'remove_spaces should return abc'); -END; -$$; - -CREATE OR REPLACE FUNCTION public.shutdown_1() RETURNS VOID LANGUAGE plpgsql AS $$ -BEGIN - drop function if exists test_1_schema(); - drop function if exists test_2_functions(); -END; -$$; - -SELECT * FROM runtests('public'::name); diff --git a/roles/database/files/upgrade/5.0.1.sql b/roles/database/files/upgrade/5.0.1.sql index 35f24b958a..8b3528eba5 100644 --- a/roles/database/files/upgrade/5.0.1.sql +++ b/roles/database/files/upgrade/5.0.1.sql @@ -12,5 +12,18 @@ Create table if not exists "report_schedule" primary key ("report_schedule_id") ); -Alter table if exists "report_schedule" add foreign key ("report_template_id") references "report_template" ("report_template_id") on update restrict on delete cascade; -Alter table if exists "report_schedule" if not exists add foreign key ("report_schedule_owner") references "uiuser" ("uiuser_id") on update restrict on delete cascade; +DO $$ +BEGIN + IF NOT EXISTS(select constraint_name + from information_schema.referential_constraints + where constraint_name = 'report_schedule_report_template_id_fkey') + THEN + Alter table if exists "report_schedule" add foreign key ("report_template_id") references "report_template" ("report_template_id") on update restrict on delete cascade; + END IF; + IF NOT EXISTS(select constraint_name + from information_schema.referential_constraints + where constraint_name = 'report_schedule_report_schedule_owner_fkey') + THEN + Alter table if exists "report_schedule" if not exists add foreign key ("report_schedule_owner") references "uiuser" ("uiuser_id") on update restrict on delete cascade; + END IF; +END $$; diff --git a/roles/database/files/upgrade/5.0.3.sql b/roles/database/files/upgrade/5.0.3.sql index c6e52e12c7..a602614362 100644 --- a/roles/database/files/upgrade/5.0.3.sql +++ b/roles/database/files/upgrade/5.0.3.sql @@ -1,4 +1,13 @@ Alter table "config" add column if not exists "config_user" Integer; Alter table "config" drop constraint if exists "config_pkey"; Alter table "config" add primary key ("config_key","config_user"); -Alter table "config" add foreign key ("config_user") references "uiuser" ("uiuser_id") on update restrict on delete cascade; + +DO $$ +BEGIN + IF NOT EXISTS(select constraint_name + from information_schema.referential_constraints + where constraint_name = 'config_config_user_fkey') + THEN + Alter table "config" add foreign key ("config_user") references "uiuser" ("uiuser_id") on update restrict on delete cascade; + END IF; +END $$; diff --git a/roles/database/files/upgrade/5.0.4.sql b/roles/database/files/upgrade/5.0.4.sql index 9ccfddd6a2..b2556f2f7e 100644 --- a/roles/database/files/upgrade/5.0.4.sql +++ b/roles/database/files/upgrade/5.0.4.sql @@ -1,4 +1,13 @@ -- adding report owner (do not allow for sharing of generated reports yet) Alter table "report" add column "report_owner_id" Integer Not Null; -Alter table "report" add foreign key ("report_owner_id") references "uiuser" ("uiuser_id") on update restrict on delete cascade; + +DO $$ +BEGIN + IF NOT EXISTS(select constraint_name + from information_schema.referential_constraints + where constraint_name = 'report_report_owner_id_fkey') + THEN + Alter table "report" add foreign key ("report_owner_id") references "uiuser" ("uiuser_id") on update restrict on delete cascade; + END IF; +END $$; diff --git a/roles/database/files/upgrade/5.0.5.sql b/roles/database/files/upgrade/5.0.5.sql index 4e3882e3e4..5f7fcef5f0 100644 --- a/roles/database/files/upgrade/5.0.5.sql +++ b/roles/database/files/upgrade/5.0.5.sql @@ -114,5 +114,18 @@ Alter table "request_user_change" ALTER COLUMN "log_usr_id" TYPE BIGINT; -- add some missing foreign keys -Alter table "usr" add foreign key ("user_create") references "import_control" ("control_id") on update restrict on delete cascade; -Alter table "usr" add foreign key ("user_last_seen") references "import_control" ("control_id") on update restrict on delete cascade; +DO $$ +BEGIN + IF NOT EXISTS(select constraint_name + from information_schema.referential_constraints + where constraint_name = 'usr_user_create_fkey') + THEN + Alter table "usr" add foreign key ("user_create") references "import_control" ("control_id") on update restrict on delete cascade; + END IF; + IF NOT EXISTS(select constraint_name + from information_schema.referential_constraints + where constraint_name = 'usr_user_last_seen_fkey') + THEN + Alter table "usr" add foreign key ("user_last_seen") references "import_control" ("control_id") on update restrict on delete cascade; + END IF; +END $$; diff --git a/roles/database/files/upgrade/5.0.6.sql b/roles/database/files/upgrade/5.0.6.sql index 788298b76f..40b33d597d 100644 --- a/roles/database/files/upgrade/5.0.6.sql +++ b/roles/database/files/upgrade/5.0.6.sql @@ -1,3 +1,11 @@ Alter table "ldap_connection" ADD COLUMN "tenant_id" INTEGER; -- add foreign key ldap_connection --> tenant -Alter table "ldap_connection" add foreign key ("tenant_id") references "tenant" ("tenant_id") on update restrict on delete cascade; +DO $$ +BEGIN + IF NOT EXISTS(select constraint_name + from information_schema.referential_constraints + where constraint_name = 'ldap_connection_tenant_id_fkey') + THEN + Alter table "ldap_connection" add foreign key ("tenant_id") references "tenant" ("tenant_id") on update restrict on delete cascade; + END IF; +END $$; diff --git a/roles/database/files/upgrade/5.1.03.sql b/roles/database/files/upgrade/5.1.03.sql index 113a350533..80e42753f7 100644 --- a/roles/database/files/upgrade/5.1.03.sql +++ b/roles/database/files/upgrade/5.1.03.sql @@ -16,10 +16,28 @@ Create table IF NOT EXISTS "report_schedule_format" "report_schedule_id" BIGSERIAL, primary key ("report_schedule_format_name","report_schedule_id") ); -Alter table "report_schedule_format" add foreign key ("report_schedule_format_name") references "report_format" ("report_format_name") on update restrict on delete cascade; + +DO $$ +BEGIN + IF NOT EXISTS(select constraint_name + from information_schema.referential_constraints + where constraint_name = 'report_schedule_format_report_schedule_format_name_fkey') + THEN + Alter table "report_schedule_format" add foreign key ("report_schedule_format_name") references "report_format" ("report_format_name") on update restrict on delete cascade; + END IF; +END $$; + Alter table "report_template" ADD COLUMN IF NOT EXISTS "report_template_owner" Integer; -Alter table "report_template" add foreign key ("report_template_owner") references "uiuser" ("uiuser_id") on update restrict on delete cascade; +DO $$ +BEGIN + IF NOT EXISTS(select constraint_name + from information_schema.referential_constraints + where constraint_name = 'report_template_report_template_owner_fkey') + THEN + Alter table "report_template" add foreign key ("report_template_owner") references "uiuser" ("uiuser_id") on update restrict on delete cascade; + END IF; +END $$; Alter table "report_schedule" ADD COLUMN IF NOT EXISTS "report_schedule_active" Boolean Default TRUE; @@ -30,5 +48,13 @@ Alter table "report" ADD COLUMN IF NOT EXISTS "report_csv" text; Alter table "report" ADD COLUMN IF NOT EXISTS "report_html" text; Alter table "report" ALTER COLUMN "report_filetype" DROP NOT NULL; Alter table "report" ADD COLUMN IF NOT EXISTS "tenant_wide_visible" Integer; -Alter table "report" add foreign key ("tenant_wide_visible") references "tenant" ("tenant_id") on update restrict on delete cascade; +DO $$ +BEGIN + IF NOT EXISTS(select constraint_name + from information_schema.referential_constraints + where constraint_name = 'report_tenant_wide_visible_fkey') + THEN + Alter table "report" add foreign key ("tenant_wide_visible") references "tenant" ("tenant_id") on update restrict on delete cascade; + END IF; +END $$; diff --git a/roles/database/files/upgrade/5.1.16.sql b/roles/database/files/upgrade/5.1.16.sql index 3ebe9ae47a..c03a6499ff 100644 --- a/roles/database/files/upgrade/5.1.16.sql +++ b/roles/database/files/upgrade/5.1.16.sql @@ -26,17 +26,65 @@ Create table if not exists "rule_user_resolved" primary key ("mgm_id","rule_id","user_id") ); -Alter table "rule_nwobj_resolved" add foreign key ("obj_id") references "object" ("obj_id") on update restrict on delete cascade; -Alter table "rule_nwobj_resolved" add foreign key ("rule_id") references "rule" ("rule_id") on update restrict on delete cascade; -Alter table "rule_nwobj_resolved" add foreign key ("mgm_id") references "management" ("mgm_id") on update restrict on delete cascade; - -Alter table "rule_svc_resolved" add foreign key ("svc_id") references "service" ("svc_id") on update restrict on delete cascade; -Alter table "rule_svc_resolved" add foreign key ("rule_id") references "rule" ("rule_id") on update restrict on delete cascade; -Alter table "rule_svc_resolved" add foreign key ("mgm_id") references "management" ("mgm_id") on update restrict on delete cascade; - -Alter table "rule_user_resolved" add foreign key ("user_id") references "usr" ("user_id") on update restrict on delete cascade; -Alter table "rule_user_resolved" add foreign key ("rule_id") references "rule" ("rule_id") on update restrict on delete cascade; -Alter table "rule_user_resolved" add foreign key ("mgm_id") references "management" ("mgm_id") on update restrict on delete cascade; +DO $$ +BEGIN + IF NOT EXISTS(select constraint_name + from information_schema.referential_constraints + where constraint_name = 'rule_nwobj_resolved_obj_id_fkey') + THEN + Alter table "rule_nwobj_resolved" add foreign key ("obj_id") references "object" ("obj_id") on update restrict on delete cascade; + END IF; + IF NOT EXISTS(select constraint_name + from information_schema.referential_constraints + where constraint_name = 'rule_nwobj_resolved_rule_id_fkey') + THEN + Alter table "rule_nwobj_resolved" add foreign key ("rule_id") references "rule" ("rule_id") on update restrict on delete cascade; + END IF; + IF NOT EXISTS(select constraint_name + from information_schema.referential_constraints + where constraint_name = 'rule_nwobj_resolved_mgm_id_fkey') + THEN + Alter table "rule_nwobj_resolved" add foreign key ("mgm_id") references "management" ("mgm_id") on update restrict on delete cascade; + END IF; + + IF NOT EXISTS(select constraint_name + from information_schema.referential_constraints + where constraint_name = 'rule_svc_resolved_svc_id_fkey') + THEN + Alter table "rule_svc_resolved" add foreign key ("svc_id") references "service" ("svc_id") on update restrict on delete cascade; + END IF; + IF NOT EXISTS(select constraint_name + from information_schema.referential_constraints + where constraint_name = 'rule_svc_resolved_rule_id_fkey') + THEN + Alter table "rule_svc_resolved" add foreign key ("rule_id") references "rule" ("rule_id") on update restrict on delete cascade; + END IF; + IF NOT EXISTS(select constraint_name + from information_schema.referential_constraints + where constraint_name = 'rule_svc_resolved_mgm_id_fkey') + THEN + Alter table "rule_svc_resolved" add foreign key ("mgm_id") references "management" ("mgm_id") on update restrict on delete cascade; + END IF; + + IF NOT EXISTS(select constraint_name + from information_schema.referential_constraints + where constraint_name = 'rule_user_resolved_user_id_fkey') + THEN + Alter table "rule_user_resolved" add foreign key ("user_id") references "usr" ("user_id") on update restrict on delete cascade; + END IF; + IF NOT EXISTS(select constraint_name + from information_schema.referential_constraints + where constraint_name = 'rule_user_resolved_rule_id_fkey') + THEN + Alter table "rule_user_resolved" add foreign key ("rule_id") references "rule" ("rule_id") on update restrict on delete cascade; + END IF; + IF NOT EXISTS(select constraint_name + from information_schema.referential_constraints + where constraint_name = 'rule_user_resolved_mgm_id_fkey') + THEN + Alter table "rule_user_resolved" add foreign key ("mgm_id") references "management" ("mgm_id") on update restrict on delete cascade; + END IF; +END $$; Grant insert on "rule_nwobj_resolved" to group "configimporters"; Grant insert on "rule_svc_resolved" to group "configimporters"; diff --git a/roles/database/files/upgrade/5.3.3.sql b/roles/database/files/upgrade/5.3.3.sql index c6b0e7bea2..958e6ceb9e 100644 --- a/roles/database/files/upgrade/5.3.3.sql +++ b/roles/database/files/upgrade/5.3.3.sql @@ -1,3 +1,13 @@ Alter table "ldap_connection" ADD COLUMN IF NOT EXISTS "ldap_name" Varchar; Alter table "uiuser" ADD COLUMN IF NOT EXISTS "ldap_connection_id" BIGINT; -Alter table "uiuser" add foreign key ("ldap_connection_id") references "ldap_connection" ("ldap_connection_id") on update restrict on delete cascade; + +DO $$ +BEGIN + IF NOT EXISTS(select constraint_name + from information_schema.referential_constraints + where constraint_name = 'uiuser_ldap_connection_id_fkey') + THEN + Alter table "uiuser" add foreign key ("ldap_connection_id") references "ldap_connection" ("ldap_connection_id") on update restrict on delete cascade; + END IF; +END $$; + diff --git a/roles/database/files/upgrade/5.4.1.sql b/roles/database/files/upgrade/5.4.1.sql index 848b0ebb44..291e2f9a75 100644 --- a/roles/database/files/upgrade/5.4.1.sql +++ b/roles/database/files/upgrade/5.4.1.sql @@ -91,6 +91,7 @@ CREATE TRIGGER import_rule_rule_id_seq BEFORE INSERT ON import_rule FOR EACH ROW CREATE OR REPLACE FUNCTION import_config_from_jsonb () RETURNS TRIGGER + LANGUAGE plpgsql AS $BODY$ DECLARE import_id BIGINT; @@ -132,10 +133,7 @@ BEGIN RETURN NEW; END; -$BODY$ -LANGUAGE plpgsql -VOLATILE -COST 100; +$BODY$; ALTER FUNCTION public.import_config_from_jsonb () OWNER TO fworch; diff --git a/roles/database/files/upgrade/5.6.3.sql b/roles/database/files/upgrade/5.6.3.sql index e0ba0bf226..ac3ccba366 100644 --- a/roles/database/files/upgrade/5.6.3.sql +++ b/roles/database/files/upgrade/5.6.3.sql @@ -12,6 +12,7 @@ DROP FUNCTION IF EXISTS import_config_from_jsonb (); CREATE OR REPLACE FUNCTION import_config_from_json () RETURNS TRIGGER + LANGUAGE plpgsql AS $BODY$ DECLARE import_id BIGINT; @@ -53,10 +54,7 @@ BEGIN RETURN NEW; END; -$BODY$ -LANGUAGE plpgsql -VOLATILE -COST 100; +$BODY$; ALTER FUNCTION public.import_config_from_json () OWNER TO fworch; diff --git a/roles/database/files/upgrade/5.6.5.sql b/roles/database/files/upgrade/5.6.5.sql index 3043209477..4cd0621ee8 100644 --- a/roles/database/files/upgrade/5.6.5.sql +++ b/roles/database/files/upgrade/5.6.5.sql @@ -24,6 +24,7 @@ DROP TRIGGER IF EXISTS import_config_insert ON import_config CASCADE; CREATE OR REPLACE FUNCTION import_config_from_json () RETURNS TRIGGER + LANGUAGE plpgsql AS $BODY$ DECLARE import_id BIGINT; @@ -65,10 +66,7 @@ BEGIN END IF; RETURN NEW; END; -$BODY$ -LANGUAGE plpgsql -VOLATILE -COST 100; +$BODY$; ALTER FUNCTION public.import_config_from_json () OWNER TO fworch; diff --git a/roles/database/files/upgrade/5.6.7.sql b/roles/database/files/upgrade/5.6.7.sql index a07fd834c3..0c4992d082 100644 --- a/roles/database/files/upgrade/5.6.7.sql +++ b/roles/database/files/upgrade/5.6.7.sql @@ -11,6 +11,7 @@ ALTER TABLE import_config ADD COLUMN IF NOT EXISTS "debug_mode" Boolean Default CREATE OR REPLACE FUNCTION import_config_from_json () RETURNS TRIGGER + LANGUAGE plpgsql AS $BODY$ DECLARE import_id BIGINT; @@ -52,14 +53,12 @@ BEGIN END IF; RETURN NEW; END; -$BODY$ -LANGUAGE plpgsql -VOLATILE -COST 100; +$BODY$; CREATE OR REPLACE FUNCTION debug_show_time (VARCHAR, TIMESTAMP) RETURNS TIMESTAMP + LANGUAGE plpgsql AS $BODY$ DECLARE v_event ALIAS FOR $1; -- description of the processed time @@ -67,19 +66,15 @@ DECLARE BEGIN RAISE NOTICE '% duration: %s', v_event, now()- t_import_start; --- RAISE NOTICE '% duration: %s', v_event, CAST((now()- t_import_start) AS VARCHAR); --- RAISE NOTICE 'duration of last step: %s', CAST(now()- t_import_start AS VARCHAR); RETURN now(); END; -$BODY$ -LANGUAGE plpgsql -VOLATILE -COST 100; +$BODY$; DROP FUNCTION IF EXISTS public.import_all_main(BIGINT); DROP FUNCTION IF EXISTS public.import_all_main(BIGINT, BOOLEAN); CREATE OR REPLACE FUNCTION public.import_all_main(BIGINT, BOOLEAN) - RETURNS VARCHAR AS + LANGUAGE plpgsql + RETURNS VARCHAR AS $BODY$ DECLARE i_current_import_id ALIAS FOR $1; -- ID of the current import @@ -130,10 +125,10 @@ BEGIN LOOP SELECT INTO b_do_not_import do_not_import FROM device WHERE dev_id=r_dev.dev_id; IF NOT b_do_not_import THEN -- RAISE NOTICE 'importing %', r_dev.dev_name; - v_err_pos := 'import_rules of device ' || r_dev.dev_name || ' (Management: ' || CAST (i_mgm_id AS VARCHAR) || ')'; + v_err_pos := 'import_rules of device ' || r_dev.dev_name || ' (Management: ' || CAST (i_mgm_id AS VARCHAR) || ') '; IF (import_rules(r_dev.dev_id, i_current_import_id)) THEN -- returns true if rule order needs to be changed -- currently always returns true as each import needs a rule reordering - v_err_pos := 'import_rules_set_rule_num_numeric of device ' || r_dev.dev_name || ' (Management: ' || CAST (i_mgm_id AS VARCHAR) || ')'; + v_err_pos := 'import_rules_set_rule_num_numeric of device ' || r_dev.dev_name || ' (Management: ' || CAST (i_mgm_id AS VARCHAR) || ') '; -- in case of any changes - adjust rule_num values in rulebase PERFORM import_rules_set_rule_num_numeric (i_current_import_id,r_dev.dev_id); END IF; @@ -183,9 +178,7 @@ BEGIN END; RETURN ''; END; -$BODY$ - LANGUAGE plpgsql VOLATILE - COST 100; +$BODY$; ALTER FUNCTION public.import_all_main(BIGINT, BOOLEAN) OWNER TO fworch; DO $$ @@ -370,7 +363,6 @@ DROP table if exists "tenant_object"; DROP table if exists "report_template_viewable_by_tenant"; --- Alter table "error_log" add foreign key ("error_id") references "error" ("error_id") on update restrict on delete cascade; drop table if exists "error_log"; -- index optimization diff --git a/roles/database/files/upgrade/5.7.2.sql b/roles/database/files/upgrade/5.7.2.sql index 27e776aa18..12c49ec93e 100644 --- a/roles/database/files/upgrade/5.7.2.sql +++ b/roles/database/files/upgrade/5.7.2.sql @@ -66,6 +66,7 @@ CREATE TRIGGER gw_route_add BEFORE INSERT ON gw_route FOR EACH ROW EXECUTE PROCE CREATE OR REPLACE FUNCTION import_config_from_json () RETURNS TRIGGER + LANGUAGE plpgsql AS $BODY$ DECLARE i_mgm_id INTEGER; @@ -123,10 +124,7 @@ BEGIN END IF; RETURN NEW; END; -$BODY$ -LANGUAGE plpgsql -VOLATILE -COST 100; +$BODY$; ALTER FUNCTION public.import_config_from_json () OWNER TO fworch; DROP TRIGGER IF EXISTS import_config_insert ON import_config CASCADE; diff --git a/roles/database/files/upgrade/6.1.3.sql b/roles/database/files/upgrade/6.1.3.sql index 9fb22ba2f7..3b58dd00ad 100644 --- a/roles/database/files/upgrade/6.1.3.sql +++ b/roles/database/files/upgrade/6.1.3.sql @@ -4,15 +4,13 @@ ALTER TABLE recertification ADD COLUMN IF NOT EXISTS next_recert_date Timestamp; CREATE OR REPLACE FUNCTION owner_change_triggered () RETURNS TRIGGER + LANGUAGE plpgsql AS $BODY$ BEGIN PERFORM recert_refresh_per_owner(NEW.id); RETURN NEW; END; -$BODY$ -LANGUAGE plpgsql -VOLATILE -COST 100; +$BODY$; ALTER FUNCTION public.owner_change_triggered () OWNER TO fworch; @@ -25,15 +23,13 @@ CREATE TRIGGER owner_change CREATE OR REPLACE FUNCTION owner_network_change_triggered () RETURNS TRIGGER + LANGUAGE plpgsql AS $BODY$ BEGIN PERFORM recert_refresh_per_owner(NEW.id); RETURN NEW; END; -$BODY$ -LANGUAGE plpgsql -VOLATILE -COST 100; +$BODY$; ALTER FUNCTION public.owner_network_change_triggered () OWNER TO fworch; DROP TRIGGER IF EXISTS owner_network_change ON owner_network CASCADE; diff --git a/roles/database/files/upgrade/7.0.2.sql b/roles/database/files/upgrade/7.0.2.sql new file mode 100644 index 0000000000..012701264a --- /dev/null +++ b/roles/database/files/upgrade/7.0.2.sql @@ -0,0 +1,41 @@ +INSERT INTO "report_template" ("report_filter","report_template_name","report_template_comment","report_template_owner", "report_parameters") +SELECT '','Last year''s Unused Rules','T0106', 0, + '{"report_type":10,"device_filter":{"management":[]}, + "time_filter": { + "is_shortcut": true, + "shortcut": "now", + "report_time": "2022-01-01T00:00:00.0000000+01:00", + "timerange_type": "SHORTCUT", + "shortcut_range": "this year", + "offset": 0, + "interval": "DAYS", + "start_time": "2022-01-01T00:00:00.0000000+01:00", + "end_time": "2022-01-01T00:00:00.0000000+01:00", + "open_start": false, + "open_end": false}, + "unused_filter": { + "creationTolerance": 0, + "unusedForDays": 365}}' +WHERE NOT EXISTS (SELECT * FROM report_template WHERE report_template_owner = 0 AND report_template_comment = 'T0106'); + +INSERT INTO "report_template" ("report_filter","report_template_name","report_template_comment","report_template_owner", "report_parameters") +SELECT '','Next Month''s Recertifications','T0107', 0, + '{"report_type":7,"device_filter":{"management":[]}, + "time_filter": { + "is_shortcut": true, + "shortcut": "now", + "report_time": "2022-01-01T00:00:00.0000000+01:00", + "timerange_type": "SHORTCUT", + "shortcut_range": "this year", + "offset": 0, + "interval": "DAYS", + "start_time": "2022-01-01T00:00:00.0000000+01:00", + "end_time": "2022-01-01T00:00:00.0000000+01:00", + "open_start": false, + "open_end": false}, + "recert_filter": { + "recertOwnerList": [], + "recertShowAnyMatch": true, + "recertificationDisplayPeriod": 30}}' +WHERE NOT EXISTS (SELECT * FROM report_template WHERE report_template_owner = 0 AND report_template_comment = 'T0107'); + diff --git a/roles/database/files/upgrade/7.1.2.sql b/roles/database/files/upgrade/7.1.2.sql new file mode 100644 index 0000000000..0f80318064 --- /dev/null +++ b/roles/database/files/upgrade/7.1.2.sql @@ -0,0 +1 @@ +insert into stm_action (action_id,action_name) VALUES (29,'inform') ON CONFLICT DO NOTHING; -- cp diff --git a/roles/database/files/upgrade/7.2.1.sql b/roles/database/files/upgrade/7.2.1.sql new file mode 100644 index 0000000000..5a55d8785a --- /dev/null +++ b/roles/database/files/upgrade/7.2.1.sql @@ -0,0 +1,2 @@ + +insert into config (config_key, config_value, config_user) VALUES ('ruleOwnershipMode', 'mixed', 0) ON CONFLICT DO NOTHING; diff --git a/roles/database/files/upgrade/7.2.2.sql b/roles/database/files/upgrade/7.2.2.sql new file mode 100644 index 0000000000..747a16f8ef --- /dev/null +++ b/roles/database/files/upgrade/7.2.2.sql @@ -0,0 +1,111 @@ +-- turning all CIDR objects into ranges +-- see https://github.com/CactuseSecurity/firewall-orchestrator/issues/2238 + +-- defining helper functions: +CREATE OR REPLACE FUNCTION get_first_ip_of_cidr (ip CIDR) + RETURNS CIDR + LANGUAGE 'plpgsql' IMMUTABLE COST 1 + AS +$BODY$ + BEGIN + IF is_single_ip(ip) THEN + RETURN ip; + ELSE + RETURN host(abbrev(ip)::cidr); + END IF; + END; +$BODY$; + +CREATE OR REPLACE FUNCTION get_last_ip_of_cidr (ip CIDR) + RETURNS CIDR + LANGUAGE 'plpgsql' IMMUTABLE COST 1 + AS +$BODY$ + BEGIN + IF is_single_ip(ip) THEN + RETURN ip; + ELSE + RETURN inet(host(broadcast(ip))); + END IF; + END; +$BODY$; + +CREATE OR REPLACE FUNCTION is_single_ip (ip CIDR) + RETURNS BOOLEAN + LANGUAGE 'plpgsql' IMMUTABLE COST 1 + AS +$BODY$ + BEGIN + RETURN masklen(ip)=32 AND family(ip)=4 OR masklen(ip)=128 AND family(ip)=6; + END; +$BODY$; + +CREATE OR REPLACE FUNCTION turn_all_cidr_objects_into_ranges () RETURNS VOID AS $$ +DECLARE + i_obj_id BIGINT; + r_obj RECORD; +BEGIN + +-- handling table object + FOR r_obj IN SELECT obj_id, obj_ip, obj_ip_end FROM object + LOOP + IF NOT is_single_ip(r_obj.obj_ip) OR r_obj.obj_ip_end IS NULL THEN + + UPDATE object SET obj_ip_end = get_last_ip_of_cidr(r_obj.obj_ip) WHERE obj_id=r_obj.obj_id; + UPDATE object SET obj_ip = get_first_ip_of_cidr(r_obj.obj_ip) WHERE obj_id=r_obj.obj_id; + END IF; + END LOOP; + + -- all network objects but groups must have ip addresses: + ALTER TABLE object DROP CONSTRAINT IF EXISTS object_obj_ip_not_null; + ALTER TABLE object DROP CONSTRAINT IF EXISTS object_obj_ip_end_not_null; + ALTER TABLE object ADD CONSTRAINT object_obj_ip_not_null CHECK (obj_ip IS NOT NULL OR obj_typ_id=2); + ALTER TABLE object ADD CONSTRAINT object_obj_ip_end_not_null CHECK (obj_ip_end IS NOT NULL OR obj_typ_id=2); + + ALTER TABLE object DROP CONSTRAINT IF EXISTS object_obj_ip_is_host; + ALTER TABLE object DROP CONSTRAINT IF EXISTS object_obj_ip_end_is_host; + ALTER TABLE object ADD CONSTRAINT object_obj_ip_is_host CHECK (is_single_ip(obj_ip)); + ALTER TABLE object ADD CONSTRAINT object_obj_ip_end_is_host CHECK (is_single_ip(obj_ip_end)); + +-- handling table owner_network + ALTER TABLE owner_network ADD COLUMN IF NOT EXISTS ip_end CIDR; + + FOR r_obj IN SELECT id, ip, ip_end FROM owner_network + LOOP + IF NOT is_single_ip(r_obj.ip) OR r_obj.ip_end IS NULL THEN + UPDATE owner_network SET ip_end = get_last_ip_of_cidr(r_obj.ip) WHERE id=r_obj.id; + UPDATE owner_network SET ip = get_first_ip_of_cidr(r_obj.ip) WHERE id=r_obj.id; + END IF; + END LOOP; + + ALTER TABLE owner_network DROP CONSTRAINT IF EXISTS owner_network_ip_end_not_null; + ALTER TABLE owner_network ADD CONSTRAINT owner_network_ip_end_not_null CHECK (ip_end IS NOT NULL); + +-- handling table tenant_network + FOR r_obj IN SELECT tenant_net_id, tenant_net_ip, tenant_net_ip_end FROM tenant_network + LOOP + IF is_single_ip(r_obj.tenant_net_ip) OR r_obj.tenant_net_ip_end IS NULL THEN + UPDATE tenant_network SET tenant_net_ip_end = inet(host(broadcast(r_obj.tenant_net_ip))) WHERE tenant_net_id=r_obj.tenant_net_id; + UPDATE tenant_network SET tenant_net_ip = inet(abbrev(r_obj.tenant_net_ip)) WHERE tenant_net_id=r_obj.tenant_net_id; + END IF; + END LOOP; + + ALTER TABLE tenant_network DROP CONSTRAINT IF EXISTS tenant_network_tenant_net_ip_end_not_null; + ALTER TABLE tenant_network ADD CONSTRAINT tenant_network_tenant_net_ip_end_not_null CHECK (tenant_net_ip_end IS NOT NULL); + + Alter Table tenant DROP Constraint IF EXISTS tenant_tenant_name_key; + Alter Table tenant ADD Constraint tenant_tenant_name_key UNIQUE(tenant_name); + + RETURN; +END; +$$ LANGUAGE plpgsql; + +SELECT * FROM turn_all_cidr_objects_into_ranges(); +DROP FUNCTION turn_all_cidr_objects_into_ranges(); + +-- removing unused import_status views: +DROP VIEW IF EXISTS view_import_status_table_unsorted CASCADE; +DROP VIEW IF EXISTS view_import_status_table CASCADE; +DROP VIEW IF EXISTS view_import_status_errors CASCADE; +DROP VIEW IF EXISTS view_import_status_successful CASCADE; + diff --git a/roles/database/files/upgrade/7.2.4.sql b/roles/database/files/upgrade/7.2.4.sql new file mode 100644 index 0000000000..68ab2835ab --- /dev/null +++ b/roles/database/files/upgrade/7.2.4.sql @@ -0,0 +1,18 @@ + +Create table if not exists "customtxt" +( + "id" Varchar NOT NULL, + "language" Varchar NOT NULL, + "txt" Varchar NOT NULL, + primary key ("id", "language") +); + +DO $$ +BEGIN + IF NOT EXISTS(select constraint_name + from information_schema.referential_constraints + where constraint_name = 'customtxt_language_fkey') + THEN + Alter table "customtxt" add foreign key ("language") references "language" ("name") on update restrict on delete cascade; + END IF; +END $$; diff --git a/roles/database/files/upgrade/7.2.5.sql b/roles/database/files/upgrade/7.2.5.sql new file mode 100644 index 0000000000..f0f52ecfc6 --- /dev/null +++ b/roles/database/files/upgrade/7.2.5.sql @@ -0,0 +1 @@ +insert into stm_obj_typ (obj_typ_id,obj_typ_name) VALUES (19,'external-gateway') ON CONFLICT DO NOTHING; diff --git a/roles/database/files/upgrade/7.3.1.sql b/roles/database/files/upgrade/7.3.1.sql new file mode 100644 index 0000000000..49d13f2faa --- /dev/null +++ b/roles/database/files/upgrade/7.3.1.sql @@ -0,0 +1,208 @@ +--------------------- make sure dedicated managements and devices are not tenant filtered ------------------------ + +-- tename existing tenant_id columns +DO $$ +BEGIN + IF EXISTS(SELECT * + FROM information_schema.columns + WHERE table_name='device' and column_name='tenant_id') + THEN + ALTER TABLE "public"."device" RENAME COLUMN "tenant_id" TO "unfiltered_tenant_id"; + END IF; + IF EXISTS(SELECT * + FROM information_schema.columns + WHERE table_name='management' and column_name='tenant_id') + THEN + ALTER TABLE "public"."management" RENAME COLUMN "tenant_id" TO "unfiltered_tenant_id"; + END IF; +END $$; + + +-- TODO: provide UI (settings) for editing unfiltered_tenant for both managements and gateways + +CREATE OR REPLACE FUNCTION rule_relevant_for_tenant(rule rule, hasura_session json) +RETURNS boolean AS $$ + DECLARE + t_id integer; + show boolean DEFAULT false; + mgm_unfiltered_tenant_id integer; + gw_unfiltered_tenant_id integer; + + BEGIN + t_id := (hasura_session ->> 'x-hasura-tenant-id')::integer; + + IF t_id IS NULL THEN + RAISE EXCEPTION 'No tenant id found in hasura session'; --> only happens when using auth via x-hasura-admin-secret (no tenant id is set) + ELSIF t_id = 1 THEN + show := true; + ELSE + SELECT INTO mgm_unfiltered_tenant_id unfiltered_tenant_id FROM rule LEFT JOIN management USING (mgm_id); + SELECT INTO gw_unfiltered_tenant_id unfiltered_tenant_id FROM rule LEFT JOIN device USING (dev_id); + IF mgm_unfiltered_tenant_id IS NOT NULL AND mgm_unfiltered_tenant_id=t_id OR gw_unfiltered_tenant_id IS NOT NULL AND gw_unfiltered_tenant_id=t_id THEN + show := true; + ELSE + IF EXISTS ( + SELECT rf.obj_id FROM rule_from rf + LEFT JOIN rule r ON (rf.rule_id=r.rule_id) + LEFT JOIN objgrp_flat ON (rf.obj_id=objgrp_flat.objgrp_flat_id) + LEFT JOIN object ON (objgrp_flat.objgrp_flat_member_id=object.obj_id) + LEFT JOIN tenant_network ON + (ip_ranges_overlap(obj_ip, obj_ip_end, tenant_net_ip, tenant_net_ip_end, rf.negated != r.rule_src_neg)) + WHERE rf.rule_id = rule.rule_id AND tenant_id = t_id + ) THEN + show := true; + ELSIF EXISTS ( + SELECT rt.obj_id FROM rule_to rt + LEFT JOIN rule r ON (rt.rule_id=r.rule_id) + LEFT JOIN objgrp_flat ON (rt.obj_id=objgrp_flat.objgrp_flat_id) + LEFT JOIN object ON (objgrp_flat.objgrp_flat_member_id=object.obj_id) + LEFT JOIN tenant_network ON + (ip_ranges_overlap(obj_ip, obj_ip_end, tenant_net_ip, tenant_net_ip_end, rt.negated != r.rule_dst_neg)) + WHERE rt.rule_id = rule.rule_id AND tenant_id = t_id + ) THEN + show := true; + END IF; + END IF; + END IF; + + RETURN show; + END; +$$ LANGUAGE 'plpgsql' STABLE; + +CREATE OR REPLACE FUNCTION get_rules_for_tenant(device_row device, tenant integer, hasura_session json) +RETURNS SETOF rule AS $$ + DECLARE + t_id integer; + mgm_unfiltered_tenant_id integer; + gw_unfiltered_tenant_id integer; + BEGIN + t_id := (hasura_session ->> 'x-hasura-tenant-id')::integer; + IF t_id IS NULL THEN + RAISE EXCEPTION 'No tenant id found in hasura session'; --> only happens when using auth via x-hasura-admin-secret (no tenant id is set) + ELSIF t_id != 1 AND t_id != tenant THEN + RAISE EXCEPTION 'A non-tenant-0 user was trying to generate a report for another tenant.'; + ELSIF tenant = 1 THEN + RAISE EXCEPTION 'Tenant0 cannot be simulated.'; + ELSE + SELECT INTO mgm_unfiltered_tenant_id management.unfiltered_tenant_id FROM device LEFT JOIN management USING (mgm_id) WHERE device.dev_id=device_row.dev_id; + SELECT INTO gw_unfiltered_tenant_id device.unfiltered_tenant_id FROM device WHERE dev_id=device_row.dev_id; + + IF mgm_unfiltered_tenant_id IS NOT NULL AND mgm_unfiltered_tenant_id=tenant OR + gw_unfiltered_tenant_id IS NOT NULL AND gw_unfiltered_tenant_id=tenant + THEN + RETURN QUERY SELECT * FROM rule WHERE dev_id=device_row.dev_id; + ELSE + RETURN QUERY + SELECT r.* FROM rule r + LEFT JOIN rule_from rf ON (r.rule_id=rf.rule_id) + LEFT JOIN objgrp_flat rf_of ON (rf.obj_id=rf_of.objgrp_flat_id) + LEFT JOIN object rf_o ON (rf_of.objgrp_flat_member_id=rf_o.obj_id) + LEFT JOIN tenant_network ON + (ip_ranges_overlap(rf_o.obj_ip, rf_o.obj_ip_end, tenant_net_ip, tenant_net_ip_end, rf.negated != r.rule_src_neg)) + WHERE r.dev_id = device_row.dev_id AND tenant_id = tenant AND rule_head_text IS NULL + UNION + SELECT r.* FROM rule r + LEFT JOIN rule_to rt ON (r.rule_id=rt.rule_id) + LEFT JOIN objgrp_flat rt_of ON (rt.obj_id=rt_of.objgrp_flat_id) + LEFT JOIN object rt_o ON (rt_of.objgrp_flat_member_id=rt_o.obj_id) + LEFT JOIN tenant_network ON + (ip_ranges_overlap(rt_o.obj_ip, rt_o.obj_ip_end, tenant_net_ip, tenant_net_ip_end, rt.negated != r.rule_dst_neg)) + WHERE r.dev_id = device_row.dev_id AND tenant_id = tenant AND rule_head_text IS NULL + ORDER BY rule_name; + END IF; + END IF; + END; +$$ LANGUAGE 'plpgsql' STABLE; + +CREATE OR REPLACE FUNCTION get_rule_froms_for_tenant(rule rule, tenant integer, hasura_session json) +RETURNS SETOF rule_from AS $$ + DECLARE + t_id integer; + mgm_unfiltered_tenant_id integer; + gw_unfiltered_tenant_id integer; + BEGIN + t_id := (hasura_session ->> 'x-hasura-tenant-id')::integer; + + IF t_id IS NULL THEN + RAISE EXCEPTION 'No tenant id found in hasura session'; --> only happens when using auth via x-hasura-admin-secret (no tenant id is set) + ELSIF t_id != 1 AND t_id != tenant THEN + RAISE EXCEPTION 'A non-tenant-0 user was trying to generate a report for another tenant.'; + ELSIF tenant = 1 THEN + RAISE EXCEPTION 'Tenant0 cannot be simulated.'; + ELSE + SELECT INTO mgm_unfiltered_tenant_id management.unfiltered_tenant_id FROM device LEFT JOIN management USING (mgm_id) WHERE device.dev_id=rule.dev_id; + SELECT INTO gw_unfiltered_tenant_id device.unfiltered_tenant_id FROM device WHERE dev_id=rule.dev_id; + + IF mgm_unfiltered_tenant_id IS NOT NULL AND mgm_unfiltered_tenant_id=tenant OR + gw_unfiltered_tenant_id IS NOT NULL AND gw_unfiltered_tenant_id=tenant + THEN + RETURN QUERY SELECT rf.* FROM rule_from rf WHERE rule_id = rule.rule_id; + ELSIF EXISTS ( + SELECT rt.obj_id FROM rule_to rt + LEFT JOIN objgrp_flat ON (rt.obj_id=objgrp_flat.objgrp_flat_id) + LEFT JOIN object ON (objgrp_flat.objgrp_flat_member_id=object.obj_id) + LEFT JOIN tenant_network ON + (ip_ranges_overlap(obj_ip, obj_ip_end, tenant_net_ip, tenant_net_ip_end, rt.negated != rule.rule_dst_neg)) + WHERE rt.rule_id = rule.rule_id AND tenant_id = tenant + ) THEN + RETURN QUERY + SELECT rf.* FROM rule_from rf WHERE rule_id = rule.rule_id; + ELSE + RETURN QUERY + SELECT DISTINCT rf.* FROM rule_from rf + LEFT JOIN objgrp_flat ON (rf.obj_id=objgrp_flat.objgrp_flat_id) + LEFT JOIN object ON (objgrp_flat.objgrp_flat_member_id=object.obj_id) + LEFT JOIN tenant_network ON + (ip_ranges_overlap(obj_ip, obj_ip_end, tenant_net_ip, tenant_net_ip_end, rf.negated != rule.rule_src_neg)) + WHERE rule_id = rule.rule_id AND tenant_id = tenant; + END IF; + END IF; + END; +$$ LANGUAGE 'plpgsql' STABLE; + + +CREATE OR REPLACE FUNCTION get_rule_tos_for_tenant(rule rule, tenant integer, hasura_session json) +RETURNS SETOF rule_to AS $$ + DECLARE + t_id integer; + mgm_unfiltered_tenant_id integer; + gw_unfiltered_tenant_id integer; + BEGIN + t_id := (hasura_session ->> 'x-hasura-tenant-id')::integer; + + IF t_id IS NULL THEN + RAISE EXCEPTION 'No tenant id found in hasura session'; --> only happens when using auth via x-hasura-admin-secret (no tenant id is set) + ELSIF t_id != 1 AND t_id != tenant THEN + RAISE EXCEPTION 'A non-tenant-0 user was trying to generate a report for another tenant.'; + ELSIF tenant = 1 THEN + RAISE EXCEPTION 'Tenant0 cannot be simulated.'; + ELSE + SELECT INTO mgm_unfiltered_tenant_id management.unfiltered_tenant_id FROM device LEFT JOIN management USING (mgm_id) WHERE device.dev_id=rule.dev_id; + SELECT INTO gw_unfiltered_tenant_id device.unfiltered_tenant_id FROM device WHERE dev_id=rule.dev_id; + + IF mgm_unfiltered_tenant_id IS NOT NULL AND mgm_unfiltered_tenant_id=tenant OR + gw_unfiltered_tenant_id IS NOT NULL AND gw_unfiltered_tenant_id=tenant + THEN + RETURN QUERY SELECT rt.* FROM rule_to rt WHERE rule_id = rule.rule_id; + ELSIF EXISTS ( + SELECT rf.obj_id FROM rule_from rf + LEFT JOIN objgrp_flat ON (rf.obj_id=objgrp_flat.objgrp_flat_id) + LEFT JOIN object ON (objgrp_flat.objgrp_flat_member_id=object.obj_id) + LEFT JOIN tenant_network ON + (ip_ranges_overlap(obj_ip, obj_ip_end, tenant_net_ip, tenant_net_ip_end, rf.negated != rule.rule_src_neg)) + WHERE rf.rule_id = rule.rule_id AND tenant_id = tenant + ) THEN + RETURN QUERY + SELECT rt.* FROM rule_to rt WHERE rule_id = rule.rule_id; + ELSE + RETURN QUERY + SELECT DISTINCT rt.* FROM rule_to rt + LEFT JOIN objgrp_flat ON (rt.obj_id=objgrp_flat.objgrp_flat_id) + LEFT JOIN object ON (objgrp_flat.objgrp_flat_member_id=object.obj_id) + LEFT JOIN tenant_network ON + (ip_ranges_overlap(obj_ip, obj_ip_end, tenant_net_ip, tenant_net_ip_end, rt.negated != rule.rule_dst_neg)) + WHERE rule_id = rule.rule_id AND tenant_id = tenant; + END IF; + END IF; + END; +$$ LANGUAGE 'plpgsql' STABLE; diff --git a/roles/database/files/upgrade/7.3.2.sql b/roles/database/files/upgrade/7.3.2.sql new file mode 100644 index 0000000000..b19fa699d1 --- /dev/null +++ b/roles/database/files/upgrade/7.3.2.sql @@ -0,0 +1,194 @@ +insert into config (config_key, config_value, config_user) VALUES ('allowServerInConn', 'True', 0) ON CONFLICT DO NOTHING; +insert into config (config_key, config_value, config_user) VALUES ('allowServiceInConn', 'True', 0) ON CONFLICT DO NOTHING; +insert into config (config_key, config_value, config_user) VALUES ('importAppDataStartAt', '00:00:00', 0) ON CONFLICT DO NOTHING; +insert into config (config_key, config_value, config_user) VALUES ('importAppDataSleepTime', '0', 0) ON CONFLICT DO NOTHING; +insert into config (config_key, config_value, config_user) VALUES ('importSubnetDataStartAt', '00:00:00', 0) ON CONFLICT DO NOTHING; +insert into config (config_key, config_value, config_user) VALUES ('importSubnetDataSleepTime', '0', 0) ON CONFLICT DO NOTHING; +insert into config (config_key, config_value, config_user) VALUES ('importAppDataPath', '[]', 0) ON CONFLICT DO NOTHING; +insert into config (config_key, config_value, config_user) VALUES ('importSubnetDataPath', '', 0) ON CONFLICT DO NOTHING; +insert into config (config_key, config_value, config_user) VALUES ('modNamingConvention', '{"networkAreaRequired":false,"fixedPartLength":0,"freePartLength":0,"networkAreaPattern":"","appRolePattern":""}', 0) ON CONFLICT DO NOTHING; + +alter table owner add column if not exists criticality Varchar; +alter table owner add column if not exists active boolean default true; +alter table owner add column if not exists import_source Varchar; + +alter table owner_network alter column id type bigint; +alter table owner_network add column if not exists name Varchar; +alter table owner_network add column if not exists nw_type int; +alter table owner_network add column if not exists import_source Varchar default 'manual'; +alter table owner_network add column if not exists is_deleted boolean default false; + +-- temp +-- ALTER TABLE modelling.nwobject DROP CONSTRAINT IF EXISTS modelling_nwobject_owner_foreign_key; +-- drop table if exists modelling.nwobject; + + +create schema if not exists modelling; + +create table if not exists modelling.nwgroup +( + id BIGSERIAL PRIMARY KEY, + app_id int, + id_string Varchar, + name Varchar, + comment Varchar, + group_type int, + is_deleted boolean default false, + creator Varchar, + creation_date timestamp default now() +); + +create table if not exists modelling.connection +( + id SERIAL PRIMARY KEY, + app_id int, + name Varchar, + reason Text, + is_interface boolean default false, + used_interface_id int, + common_service boolean default false, + creator Varchar, + creation_date timestamp default now() +); + +create table if not exists modelling.selected_objects +( + app_id int, + nwgroup_id bigint, + primary key (app_id, nwgroup_id) +); + +create table if not exists modelling.selected_connections +( + app_id int, + connection_id int, + primary key (app_id, connection_id) +); + +create table if not exists modelling.nwobject_nwgroup +( + nwobject_id bigint, + nwgroup_id bigint, + primary key (nwobject_id, nwgroup_id) +); + +create table if not exists modelling.nwgroup_connection +( + nwgroup_id bigint, + connection_id int, + connection_field int, -- enum src=1, dest=2, ... + primary key (nwgroup_id, connection_id, connection_field) +); + +create table if not exists modelling.nwobject_connection -- (used only if settings flag is set) +( + nwobject_id bigint, + connection_id int, + connection_field int, -- enum src=1, dest=2, ... + primary key (nwobject_id, connection_id, connection_field) +); + +create table if not exists modelling.service +( + id SERIAL PRIMARY KEY, + app_id int, + name Varchar, + is_global boolean default false, + port int, + port_end int, + proto_id int +); + +create table if not exists modelling.service_group +( + id SERIAL PRIMARY KEY, + app_id int, + name Varchar, + is_global boolean default false, + comment Varchar, + creator Varchar, + creation_date timestamp default now() +); + +create table if not exists modelling.service_service_group +( + service_id int, + service_group_id int, + primary key (service_id, service_group_id) +); + +create table if not exists modelling.service_group_connection +( + service_group_id int, + connection_id int, + primary key (service_group_id, connection_id) +); + +create table if not exists modelling.service_connection -- (used only if settings flag is set) +( + service_id int, + connection_id int, + primary key (service_id, connection_id) +); + +create table if not exists modelling.change_history +( + id BIGSERIAL PRIMARY KEY, + app_id int, + change_type int, + object_type int, + object_id bigint, + change_text Varchar, + changer Varchar, + change_time Timestamp default now() +); + + +ALTER TABLE modelling.nwgroup DROP CONSTRAINT IF EXISTS modelling_nwgroup_owner_foreign_key; +ALTER TABLE modelling.connection DROP CONSTRAINT IF EXISTS modelling_connection_owner_foreign_key; +ALTER TABLE modelling.connection DROP CONSTRAINT IF EXISTS modelling_connection_used_interface_foreign_key; +ALTER TABLE modelling.nwobject_nwgroup DROP CONSTRAINT IF EXISTS modelling_nwobject_nwgroup_nwobject_foreign_key; +ALTER TABLE modelling.nwobject_nwgroup DROP CONSTRAINT IF EXISTS modelling_nwobject_nwgroup_nwgroup_foreign_key; +ALTER TABLE modelling.nwgroup_connection DROP CONSTRAINT IF EXISTS modelling_nwgroup_connection_nwgroup_foreign_key; +ALTER TABLE modelling.nwgroup_connection DROP CONSTRAINT IF EXISTS modelling_nwgroup_connection_connection_foreign_key; +ALTER TABLE modelling.nwobject_connection DROP CONSTRAINT IF EXISTS modelling_nwobject_connection_nwobject_foreign_key; +ALTER TABLE modelling.nwobject_connection DROP CONSTRAINT IF EXISTS modelling_nwobject_connection_connection_foreign_key; +ALTER TABLE modelling.service DROP CONSTRAINT IF EXISTS modelling_service_owner_foreign_key; +ALTER TABLE modelling.service DROP CONSTRAINT IF EXISTS modelling_service_protocol_foreign_key; +ALTER TABLE modelling.service_group DROP CONSTRAINT IF EXISTS modelling_service_group_owner_foreign_key; +ALTER TABLE modelling.service_service_group DROP CONSTRAINT IF EXISTS modelling_service_service_group_service_foreign_key; +ALTER TABLE modelling.service_service_group DROP CONSTRAINT IF EXISTS modelling_service_service_group_service_group_foreign_key; +ALTER TABLE modelling.service_group_connection DROP CONSTRAINT IF EXISTS modelling_service_group_connection_service_group_foreign_key; +ALTER TABLE modelling.service_group_connection DROP CONSTRAINT IF EXISTS modelling_service_group_connection_connection_foreign_key; +ALTER TABLE modelling.service_connection DROP CONSTRAINT IF EXISTS modelling_service_connection_service_foreign_key; +ALTER TABLE modelling.service_connection DROP CONSTRAINT IF EXISTS modelling_service_connection_connection_foreign_key; +ALTER TABLE modelling.change_history DROP CONSTRAINT IF EXISTS modelling_change_history_owner_foreign_key; +ALTER TABLE modelling.selected_objects DROP CONSTRAINT IF EXISTS modelling_selected_objects_owner_foreign_key; +ALTER TABLE modelling.selected_objects DROP CONSTRAINT IF EXISTS modelling_selected_objects_nwgroup_foreign_key; +ALTER TABLE modelling.selected_connections DROP CONSTRAINT IF EXISTS modelling_selected_connections_owner_foreign_key; +ALTER TABLE modelling.selected_connections DROP CONSTRAINT IF EXISTS modelling_selected_connections_connection_foreign_key; + +ALTER TABLE modelling.nwgroup ADD CONSTRAINT modelling_nwgroup_owner_foreign_key FOREIGN KEY (app_id) REFERENCES owner(id) ON UPDATE RESTRICT ON DELETE CASCADE; +ALTER TABLE modelling.connection ADD CONSTRAINT modelling_connection_owner_foreign_key FOREIGN KEY (app_id) REFERENCES owner(id) ON UPDATE RESTRICT ON DELETE CASCADE; +ALTER TABLE modelling.connection ADD CONSTRAINT modelling_connection_used_interface_foreign_key FOREIGN KEY (used_interface_id) REFERENCES modelling.connection(id) ON UPDATE RESTRICT ON DELETE CASCADE; +ALTER TABLE modelling.nwobject_nwgroup ADD CONSTRAINT modelling_nwobject_nwgroup_nwobject_foreign_key FOREIGN KEY (nwobject_id) REFERENCES owner_network(id) ON UPDATE RESTRICT ON DELETE CASCADE; +ALTER TABLE modelling.nwobject_nwgroup ADD CONSTRAINT modelling_nwobject_nwgroup_nwgroup_foreign_key FOREIGN KEY (nwgroup_id) REFERENCES modelling.nwgroup(id) ON UPDATE RESTRICT ON DELETE CASCADE; +ALTER TABLE modelling.nwgroup_connection ADD CONSTRAINT modelling_nwgroup_connection_nwgroup_foreign_key FOREIGN KEY (nwgroup_id) REFERENCES modelling.nwgroup(id) ON UPDATE RESTRICT ON DELETE CASCADE; +ALTER TABLE modelling.nwgroup_connection ADD CONSTRAINT modelling_nwgroup_connection_connection_foreign_key FOREIGN KEY (connection_id) REFERENCES modelling.connection(id) ON UPDATE RESTRICT ON DELETE CASCADE; +ALTER TABLE modelling.nwobject_connection ADD CONSTRAINT modelling_nwobject_connection_nwobject_foreign_key FOREIGN KEY (nwobject_id) REFERENCES owner_network(id) ON UPDATE RESTRICT ON DELETE CASCADE; +ALTER TABLE modelling.nwobject_connection ADD CONSTRAINT modelling_nwobject_connection_connection_foreign_key FOREIGN KEY (connection_id) REFERENCES modelling.connection(id) ON UPDATE RESTRICT ON DELETE CASCADE; +ALTER TABLE modelling.service ADD CONSTRAINT modelling_service_owner_foreign_key FOREIGN KEY (app_id) REFERENCES owner(id) ON UPDATE RESTRICT ON DELETE CASCADE; +ALTER TABLE modelling.service ADD CONSTRAINT modelling_service_protocol_foreign_key FOREIGN KEY (proto_id) REFERENCES stm_ip_proto(ip_proto_id) ON UPDATE RESTRICT ON DELETE CASCADE; +ALTER TABLE modelling.service_group ADD CONSTRAINT modelling_service_group_owner_foreign_key FOREIGN KEY (app_id) REFERENCES owner(id) ON UPDATE RESTRICT ON DELETE CASCADE; +ALTER TABLE modelling.service_service_group ADD CONSTRAINT modelling_service_service_group_service_foreign_key FOREIGN KEY (service_id) REFERENCES modelling.service(id) ON UPDATE RESTRICT ON DELETE CASCADE; +ALTER TABLE modelling.service_service_group ADD CONSTRAINT modelling_service_service_group_service_group_foreign_key FOREIGN KEY (service_group_id) REFERENCES modelling.service_group(id) ON UPDATE RESTRICT ON DELETE CASCADE; +ALTER TABLE modelling.service_group_connection ADD CONSTRAINT modelling_service_group_connection_service_group_foreign_key FOREIGN KEY (service_group_id) REFERENCES modelling.service_group(id) ON UPDATE RESTRICT ON DELETE CASCADE; +ALTER TABLE modelling.service_group_connection ADD CONSTRAINT modelling_service_group_connection_connection_foreign_key FOREIGN KEY (connection_id) REFERENCES modelling.connection(id) ON UPDATE RESTRICT ON DELETE CASCADE; +ALTER TABLE modelling.service_connection ADD CONSTRAINT modelling_service_connection_service_foreign_key FOREIGN KEY (service_id) REFERENCES modelling.service(id) ON UPDATE RESTRICT ON DELETE CASCADE; +ALTER TABLE modelling.service_connection ADD CONSTRAINT modelling_service_connection_connection_foreign_key FOREIGN KEY (connection_id) REFERENCES modelling.connection(id) ON UPDATE RESTRICT ON DELETE CASCADE; +ALTER TABLE modelling.change_history ADD CONSTRAINT modelling_change_history_owner_foreign_key FOREIGN KEY (app_id) REFERENCES owner(id) ON UPDATE RESTRICT ON DELETE CASCADE; +ALTER TABLE modelling.selected_objects ADD CONSTRAINT modelling_selected_objects_owner_foreign_key FOREIGN KEY (app_id) REFERENCES owner(id) ON UPDATE RESTRICT ON DELETE CASCADE; +ALTER TABLE modelling.selected_objects ADD CONSTRAINT modelling_selected_objects_nwgroup_foreign_key FOREIGN KEY (nwgroup_id) REFERENCES modelling.nwgroup(id) ON UPDATE RESTRICT ON DELETE CASCADE; +ALTER TABLE modelling.selected_connections ADD CONSTRAINT modelling_selected_connections_owner_foreign_key FOREIGN KEY (app_id) REFERENCES owner(id) ON UPDATE RESTRICT ON DELETE CASCADE; +ALTER TABLE modelling.selected_connections ADD CONSTRAINT modelling_selected_connections_connection_foreign_key FOREIGN KEY (connection_id) REFERENCES modelling.connection(id) ON UPDATE RESTRICT ON DELETE CASCADE; + diff --git a/roles/database/files/upgrade/7.3.3.sql b/roles/database/files/upgrade/7.3.3.sql new file mode 100644 index 0000000000..168ac93144 --- /dev/null +++ b/roles/database/files/upgrade/7.3.3.sql @@ -0,0 +1,102 @@ +-- contains all managements visible to a tenant + +Create table if not exists tenant_to_management + ( + tenant_id Integer NOT NULL, + management_id Integer NOT NULL, + shared BOOLEAN NOT NULL DEFAULT TRUE, + primary key ("tenant_id", "management_id") + ); + + +-- Alter table tenant_to_management +-- drop column if exists shared; + + +-- Alter table tenant_to_device +-- drop column if exists shared; + + +Alter table tenant_to_management add column if not exists shared BOOLEAN NOT NULL DEFAULT TRUE; + +Alter table tenant_to_device add column if not exists shared BOOLEAN NOT NULL DEFAULT TRUE; + +Alter table management DROP column if exists unfiltered_tenant_id; + + +Alter table device +DROP column if exists unfiltered_tenant_id; + +DO $$ +BEGIN + IF NOT EXISTS(select constraint_name + from information_schema.referential_constraints + where constraint_name = 'tenant_to_management_management_id_fkey') + THEN + Alter table "tenant_to_management" add foreign key ("management_id") references "management" ("mgm_id") on update restrict on delete cascade; + END IF; + + IF NOT EXISTS(select constraint_name + from information_schema.referential_constraints + where constraint_name = 'tenant_to_management_tenant_id_fkey') + THEN + Alter table "tenant_to_management" add foreign key ("tenant_id") references "tenant" ("tenant_id") on update restrict on delete cascade; + END IF; +END $$; + +/* + +Documentation of RBAC for tenant filtering + +- tenant to device mapping is stored in tenant_to_device and tenant_to_management tables +- we need to make sure that the mapping is complete (e.g. no devices are visible if the management is not visible) + - this also means we need a mechanism to set new gateways to fully visible if the management is fully visible! + this is done in the settings after selecting the exact three-way visibility + - new gateways and managements start with "not shared" if the management's visibility is "not shared" (only when added via UI) + - new gateways start as "invisible" if the management's visibility is "shared" + - new managements start with no visibility for a tenant + - invisible means not visible for a tenant user (e.g. reporter) but needs to be visible for the admin in the tenant settings! + + alternatively it would be possible to just set management as fully visible to result in all (future) gateways of the management to be fully visible as well + but then the API filtering would become much more complex +- use the same mechanisms for tenant simulation as reporter_view_all and admin as for restricted reporter: + - not all filters can be applied in API (especially not for object vie in RSB) due to performance issues + - this works as long as reports are generated and stored in the archive and the reporter has no direct accesss to the API +- API access is restricted via tenant_filter as follows: + - device table: + {"_and":[{"mgm_id":{"_in":"x-hasura-visible-managements"}},{"dev_id":{"_in":"x-hasura-visible-devices"}}]} + - management table: + {"mgm_id":{"_in":"x-hasura-visible-managements"}} + - rule table: + {"_and":[{"mgm_id":{"_in":"x-hasura-visible-managements"}},{"dev_id":{"_in":"x-hasura-visible-devices"}},{"rule_relevant_for_tenant":{"_eq":"true"}}]} + - rule_to table: + {"_and":[{"rule":{"mgm_id":{"_in":"x-hasura-visible-managements"}}},{"rule":{"dev_id":{"_in":"x-hasura-visible-devices"}}},{"rule_to_relevant_for_tenant":{"_eq":"true"}}]} + - rule_from table: + {"_and":[{"rule":{"mgm_id":{"_in":"x-hasura-visible-managements"}}},{"rule":{"dev_id":{"_in":"x-hasura-visible-devices"}}},{"rule_from_relevant_for_tenant":{"_eq":"true"}}]} + - object: (no restrictions on objgrp, ...) + {"mgm_id":{"_in":"x-hasura-visible-managements"}} + +- rules and rule_from/to are fetched using the computed fields defined by functions + - rule_relevant_for_tenant + - get_rule_froms_for_tenant + - get_rule_tos_for_tenant + +- Question: do we actually need to include the computed fields get_rule_froms_for_tenant, ... in the queries or can all of this be steered by API permissions and we just use the normal fields (rules, rule_tos, rule_froms)? + Anser: for the simulation of tenants (by admin/reporter-viewall role) we need these functions as we do not have API restrictions + - the function get_rules_for_tenant is needed to be able to simulate getting rules for a specific tenant + +- we are introducing a new quality of visibility (visible, shared visible, fully visible (not shared)) for gateways and managements + - these visibilities are inherited from management to gateway: when a management is fully visible then all the gateways are also fully visible + +- we do not add more information to the JWT, just whether the device is visible or not: + x-hasura-visible-devices: { 1,4 } --> shared and not shared gateways + x-hasura-visible-managements: { 3,6 } --> shared and not shared managements + + NOT implemented: + x-hasura-fully-visible-devices: { 1 } + x-hasura-fully-visible-devices: { 6 } + + then depending on the grade of visibility we either return a rule(base) unfiltered or filtered + {"_and":["_or":[{"mgm_id":{"_in":"x-hasura-visible-managements"}},{"dev_id":{"_in":"x-hasura-visible-devices"}}]} + +*/ diff --git a/roles/database/files/upgrade/7.3.4.sql b/roles/database/files/upgrade/7.3.4.sql new file mode 100644 index 0000000000..280de3924d --- /dev/null +++ b/roles/database/files/upgrade/7.3.4.sql @@ -0,0 +1 @@ +alter table import_control add column if not exists notification_done Boolean NOT NULL Default FALSE; diff --git a/roles/database/files/upgrade/7.3.5.sql b/roles/database/files/upgrade/7.3.5.sql new file mode 100644 index 0000000000..3e2a447757 --- /dev/null +++ b/roles/database/files/upgrade/7.3.5.sql @@ -0,0 +1,30 @@ +alter table import_control add column if not exists security_relevant_changes_counter INTEGER NOT NULL Default 0; + +-- add missing tenant to management mappings for demo data +DO $do$ BEGIN + IF EXISTS (SELECT * FROM tenant WHERE tenant_name='tenant1_demo') AND + EXISTS (select mgm_id FROM management where management.mgm_name='fortigate_demo') + THEN + IF NOT EXISTS (SELECT * FROM tenant_to_management LEFT JOIN tenant USING (tenant_id) WHERE tenant_name='tenant1_demo') THEN + INSERT INTO tenant_to_management (tenant_id, management_id, shared) + SELECT + tenant_id, + (select mgm_id FROM management where management.mgm_name='fortigate_demo'), + TRUE + FROM tenant WHERE tenant.tenant_name='tenant1_demo'; + END IF; + END IF; + + IF EXISTS (SELECT * FROM tenant WHERE tenant_name='tenant2_demo') AND + EXISTS (select mgm_id FROM management where management.mgm_name='fortigate_demo') + THEN + IF NOT EXISTS (SELECT * FROM tenant_to_management LEFT JOIN tenant USING (tenant_id) WHERE tenant_name='tenant2_demo') THEN + INSERT INTO tenant_to_management (tenant_id, management_id, shared) + SELECT + tenant_id, + (select mgm_id FROM management where management.mgm_name='fortigate_demo'), + FALSE + FROM tenant WHERE tenant.tenant_name='tenant2_demo'; + END IF; + END IF; +END $do$ diff --git a/roles/database/files/upgrade/7.3.6.sql b/roles/database/files/upgrade/7.3.6.sql new file mode 100644 index 0000000000..ef14bd984e --- /dev/null +++ b/roles/database/files/upgrade/7.3.6.sql @@ -0,0 +1 @@ +alter table owner add column if not exists common_service_possible boolean default false; diff --git a/roles/database/files/upgrade/7.3.sql b/roles/database/files/upgrade/7.3.sql new file mode 100644 index 0000000000..2fc1bd6709 --- /dev/null +++ b/roles/database/files/upgrade/7.3.sql @@ -0,0 +1,123 @@ +-- clean up database functions and views + +DROP FUNCTION IF EXISTS get_tenant_list(REFCURSOR); +DROP FUNCTION IF EXISTS get_dev_list(REFCURSOR,INTEGER); +DROP FUNCTION IF EXISTS get_mgmt_list(REFCURSOR); +DROP FUNCTION IF EXISTS get_mgmt_dev_list(REFCURSOR); +DROP FUNCTION IF EXISTS get_obj_ids_of_filtered_management(INTEGER, INTEGER, INTEGER); +DROP FUNCTION IF EXISTS rule_src_contains_tenant_obj (BIGINT, INTEGER); +DROP FUNCTION IF EXISTS rule_dst_contains_tenant_obj (BIGINT, INTEGER); +DROP FUNCTION IF EXISTS obj_belongs_to_tenant (BIGINT, INTEGER); +DROP FUNCTION IF EXISTS obj_neg_belongs_to_tenant (BIGINT, INTEGER); +DROP FUNCTION IF EXISTS flatten_obj_list (BIGINT[]); +DROP FUNCTION IF EXISTS get_changed_newrules(refcursor, _int4); +DROP FUNCTION IF EXISTS get_changed_oldrules(refcursor, _int4); +DROP FUNCTION IF EXISTS get_undocumented_changelog_entries(VARCHAR); +DROP FUNCTION IF EXISTS get_import_ids_for_time (TIMESTAMP); +DROP FUNCTION IF EXISTS get_negated_tenant_ip_filter(INTEGER); +DROP FUNCTION IF EXISTS get_ip_filter(CIDR); +DROP FUNCTION IF EXISTS get_tenant_ip_filter(INTEGER); +DROP FUNCTION IF EXISTS get_exploded_src_of_rule(BIGINT); +DROP FUNCTION IF EXISTS get_exploded_dst_of_rule(BIGINT); +DROP FUNCTION IF EXISTS get_rule_action (BIGINT); +DROP FUNCTION IF EXISTS is_rule_src_negated (BIGINT); +DROP FUNCTION IF EXISTS is_rule_dst_negated (BIGINT); +DROP FUNCTION IF EXISTS explode_objgrp (BIGINT); +DROP FUNCTION IF EXISTS get_matching_import_id(INTEGER, TIMESTAMP); +DROP FUNCTION IF EXISTS get_next_import_id(INTEGER,TIMESTAMP); +DROP FUNCTION IF EXISTS get_previous_import_ids(TIMESTAMP); +DROP FUNCTION IF EXISTS instr (varchar, varchar, integer, integer); +DROP FUNCTION IF EXISTS instr (varchar, varchar, integer); +DROP FUNCTION IF EXISTS instr (varchar, varchar); +DROP FUNCTION IF EXISTS get_dev_typ_id (varchar); +DROP FUNCTION IF EXISTS object_relevant_for_tenant(object object, hasura_session json); + +CREATE OR REPLACE VIEW view_obj_changes AS + SELECT + abs_change_id, + log_obj_id AS local_change_id, + ''::VARCHAR as change_request_info, + CAST('object' AS VARCHAR) as change_element, + CAST('basic_element' AS VARCHAR) as change_element_order, + changelog_object.old_obj_id AS old_id, + changelog_object.new_obj_id AS new_id, + changelog_object.documented as change_documented, + changelog_object.change_type_id as change_type_id, + change_action as change_type, + changelog_obj_comment as change_comment, + obj_comment, + import_control.start_time AS change_time, + management.mgm_name AS mgm_name, + management.mgm_id AS mgm_id, + CAST(NULL AS VARCHAR) as dev_name, + CAST(NULL AS INTEGER) as dev_id, + t_change_admin.uiuser_first_name || ' ' || t_change_admin.uiuser_last_name AS change_admin, + t_change_admin.uiuser_id AS change_admin_id, + t_doku_admin.uiuser_first_name || ' ' || t_doku_admin.uiuser_last_name AS doku_admin, + t_doku_admin.uiuser_id AS doku_admin_id, + security_relevant, + object.obj_name AS unique_name, + CAST (NULL AS VARCHAR) AS change_diffs, + CAST (NULL AS VARCHAR) AS change_new_element + FROM + changelog_object + LEFT JOIN (import_control LEFT JOIN management using (mgm_id)) using (control_id) + LEFT JOIN object ON (old_obj_id=obj_id) + LEFT JOIN uiuser AS t_change_admin ON (changelog_object.import_admin=t_change_admin.uiuser_id) + LEFT JOIN uiuser AS t_doku_admin ON (changelog_object.doku_admin=t_doku_admin.uiuser_id) + WHERE change_type_id = 3 AND security_relevant AND change_action='D' AND successful_import + + UNION + + SELECT + abs_change_id, + log_obj_id AS local_change_id, + ''::VARCHAR as change_request_info, + CAST('object' AS VARCHAR) as change_element, + CAST('basic_element' AS VARCHAR) as change_element_order, + changelog_object.old_obj_id AS old_id, + changelog_object.new_obj_id AS new_id, + changelog_object.documented as change_documented, + changelog_object.change_type_id as change_type_id, + change_action as change_type, + changelog_obj_comment as change_comment, + obj_comment, + import_control.start_time AS change_time, + management.mgm_name AS mgm_name, + management.mgm_id AS mgm_id, + CAST(NULL AS VARCHAR) as dev_name, + CAST(NULL AS INTEGER) as dev_id, + t_change_admin.uiuser_first_name || ' ' || t_change_admin.uiuser_last_name AS change_admin, + t_change_admin.uiuser_id AS change_admin_id, + t_doku_admin.uiuser_first_name || ' ' || t_doku_admin.uiuser_last_name AS doku_admin, + t_doku_admin.uiuser_id AS doku_admin_id, + security_relevant, + object.obj_name AS unique_name, + CAST (NULL AS VARCHAR) AS change_diffs, + CAST (NULL AS VARCHAR) AS change_new_element + FROM + changelog_object + LEFT JOIN (import_control LEFT JOIN management using (mgm_id)) using (control_id) + LEFT JOIN object ON (new_obj_id=obj_id) + LEFT JOIN uiuser AS t_change_admin ON (changelog_object.import_admin=t_change_admin.uiuser_id) + LEFT JOIN uiuser AS t_doku_admin ON (changelog_object.doku_admin=t_doku_admin.uiuser_id) + WHERE change_type_id = 3 AND security_relevant AND change_action<>'D' AND successful_import; + +DROP FUNCTION IF EXISTS get_request_str(VARCHAR,BIGINT); + + + +DROP VIEW IF EXISTS view_undocumented_changes CASCADE; +DROP VIEW IF EXISTS view_changes_by_changed_element_id CASCADE; +DROP VIEW IF EXISTS view_change_counter CASCADE; +DROP VIEW IF EXISTS view_undocumented_change_counter CASCADE; +DROP VIEW IF EXISTS view_documented_change_counter CASCADE; + +--- +-- DROP VIEW IF EXISTS view_obj_changes CASCADE; +-- DROP VIEW IF EXISTS view_change_counter CASCADE; +-- DROP VIEW IF EXISTS view_svc_changes CASCADE; +-- DROP VIEW IF EXISTS view_user_changes CASCADE; +-- DROP VIEW IF EXISTS view_rule_changes CASCADE; +-- DROP VIEW IF EXISTS view_rule_source_or_destination CASCADE; + diff --git a/roles/database/files/upgrade/8.0.1.sql b/roles/database/files/upgrade/8.0.1.sql new file mode 100644 index 0000000000..d21147e47e --- /dev/null +++ b/roles/database/files/upgrade/8.0.1.sql @@ -0,0 +1,17 @@ +insert into config (config_key, config_value, config_user) VALUES ('modIconify', 'True', 0) ON CONFLICT DO NOTHING; +insert into config (config_key, config_value, config_user) VALUES ('reducedProtocolSet', 'True', 0) ON CONFLICT DO NOTHING; +insert into config (config_key, config_value, config_user) VALUES ('overviewDisplayLines', '3', 0) ON CONFLICT DO NOTHING; +insert into config (config_key, config_value, config_user) VALUES ('emailServerAddress', '', 0) ON CONFLICT DO NOTHING; +insert into config (config_key, config_value, config_user) VALUES ('emailPort', '0', 0) ON CONFLICT DO NOTHING; +insert into config (config_key, config_value, config_user) VALUES ('emailTls', 'None', 0) ON CONFLICT DO NOTHING; +insert into config (config_key, config_value, config_user) VALUES ('emailUser', '', 0) ON CONFLICT DO NOTHING; +insert into config (config_key, config_value, config_user) VALUES ('emailPassword', '', 0) ON CONFLICT DO NOTHING; +insert into config (config_key, config_value, config_user) VALUES ('emailSenderAddress', '', 0) ON CONFLICT DO NOTHING; +insert into config (config_key, config_value, config_user) VALUES ('impChangeNotifyRecipients', '', 0) ON CONFLICT DO NOTHING; +insert into config (config_key, config_value, config_user) VALUES ('impChangeNotifySubject', '', 0) ON CONFLICT DO NOTHING; +insert into config (config_key, config_value, config_user) VALUES ('impChangeNotifyBody', '', 0) ON CONFLICT DO NOTHING; +insert into config (config_key, config_value, config_user) VALUES ('impChangeNotifyActive', 'False', 0) ON CONFLICT DO NOTHING; +insert into config (config_key, config_value, config_user) VALUES ('impChangeNotifyType', '0', 0) ON CONFLICT DO NOTHING; +insert into config (config_key, config_value, config_user) VALUES ('impChangeNotifySleepTime', '0', 0) ON CONFLICT DO NOTHING; +insert into config (config_key, config_value, config_user) VALUES ('impChangeNotifyStartAt', '00:00:00', 0) ON CONFLICT DO NOTHING; +insert into config (config_key, config_value, config_user) VALUES ('recCheckParams', '{"check_interval":2,"check_offset":1,"check_weekday":null,"check_dayofmonth":null}', 0) ON CONFLICT DO NOTHING; diff --git a/roles/database/files/upgrade/8.0.2.sql b/roles/database/files/upgrade/8.0.2.sql new file mode 100644 index 0000000000..d85bfaac2b --- /dev/null +++ b/roles/database/files/upgrade/8.0.2.sql @@ -0,0 +1,4 @@ +insert into stm_dev_typ (dev_typ_id,dev_typ_name,dev_typ_version,dev_typ_manufacturer,dev_typ_predef_svc,dev_typ_is_multi_mgmt,dev_typ_is_mgmt,is_pure_routing_device) + VALUES (26,'NSX','4ff','VMWare','',false,true,false) ON CONFLICT DO NOTHING; +insert into stm_dev_typ (dev_typ_id,dev_typ_name,dev_typ_version,dev_typ_manufacturer,dev_typ_predef_svc,dev_typ_is_multi_mgmt,dev_typ_is_mgmt,is_pure_routing_device) + VALUES (27,'NSX DFW Gateway','4ff','VMWare','',false,false,false) ON CONFLICT DO NOTHING; diff --git a/roles/database/files/upgrade/8.0.3.sql b/roles/database/files/upgrade/8.0.3.sql new file mode 100644 index 0000000000..3936741322 --- /dev/null +++ b/roles/database/files/upgrade/8.0.3.sql @@ -0,0 +1,183 @@ +-- add default config value to avoid warnings +insert into config (config_key, config_value, config_user) VALUES ('modCommonAreas', '', 0) ON CONFLICT DO NOTHING; + +-- add custom fields as jsonb +Alter table rule add column if not exists rule_custom_fields JSONB; +Alter table import_rule add column if not exists rule_custom_fields JSONB; + + +-- adding imported custom rule fields +-- replaced CREATE OR REPLACE FUNCTION insert_single_rule(BIGINT,INTEGER,INTEGER,BIGINT,BOOLEAN) RETURNS BIGINT AS $$ +-- new compare function for jsonb necessary for custom rule fields +CREATE OR REPLACE FUNCTION are_equal (jsonb, jsonb) + RETURNS boolean + AS $$ +BEGIN + IF (($1 IS NULL AND $2 IS NULL) OR $1 = $2) THEN + RETURN TRUE; + ELSE + RETURN FALSE; + END IF; +END; +$$ +LANGUAGE plpgsql; + +------------------------------------- +-- credentials/secrets encryption +-- the following functions are needed for the upgrade and during installation (to encrypt the ldap passwords in ldap_connection table) +-- for existing installations all encrytion/decryption is done in the UI or in the MW server (for ldap binding) + +CREATE EXTENSION IF NOT EXISTS pgcrypto; + +CREATE OR REPLACE FUNCTION custom_aes_cbc_encrypt_base64(plaintext TEXT, key TEXT) RETURNS TEXT AS $$ +DECLARE + iv BYTEA; + encrypted_text BYTEA; +BEGIN + -- Generate a random IV (Initialization Vector) + iv := gen_random_bytes(16); -- IV size for AES is typically 16 bytes + + -- Perform AES CBC encryption + encrypted_text := encrypt_iv(plaintext::BYTEA, key::BYTEA, iv, 'aes-cbc/pad:pkcs'); + + -- Combine IV and encrypted text and encode them to base64 + RETURN encode(iv || encrypted_text, 'base64'); +END; +$$ LANGUAGE plpgsql; + +CREATE OR REPLACE FUNCTION custom_aes_cbc_decrypt_base64(ciphertext TEXT, key TEXT) RETURNS TEXT AS $$ +DECLARE + iv BYTEA; + encrypted_text BYTEA; + decrypted_text BYTEA; +BEGIN + -- Decode the base64 string into IV and encrypted text + encrypted_text := decode(ciphertext, 'base64'); + + -- Extract IV from the encrypted text + iv := substring(encrypted_text from 1 for 16); + + -- Extract encrypted text without IV + encrypted_text := substring(encrypted_text from 17); + + -- Perform AES CBC decryption + decrypted_text := decrypt_iv(encrypted_text, key::BYTEA, iv, 'aes-cbc/pad:pkcs'); + + -- Return the decrypted text + RETURN convert_from(decrypted_text, 'UTF8'); +END; +$$ LANGUAGE plpgsql; + +CREATE OR REPLACE FUNCTION encryptText (plaintext_in text, key_in text) RETURNS text AS $$ +DECLARE + t_cyphertext TEXT; + t_plaintext TEXT; + t_crypt_algo TEXT := 'cipher-algo=aes256'; + t_coding_algo TEXT := 'base64'; + -- ba_iv bytea; +BEGIN + -- check if plaintext is actually ciphertext + BEGIN + SELECT into t_plaintext custom_aes_cbc_decrypt_base64(plaintext_in, key_in); + -- if we get here without error, the plaintext passed in was actually already encrypted + RETURN plaintext_in; + EXCEPTION WHEN OTHERS THEN + RETURN custom_aes_cbc_encrypt_base64(plaintext_in, key_in); + END; +END; +$$ LANGUAGE plpgsql VOLATILE; + +CREATE OR REPLACE FUNCTION decryptText (cyphertext_in text, key text) RETURNS text AS $$ +DECLARE + t_plaintext TEXT; + t_crypt_algo TEXT := 'cipher-algo=aes-256-cbc/pad:pkcs'; + t_coding_algo TEXT := 'base64'; +BEGIN + BEGIN + SELECT INTO t_plaintext custom_aes_cbc_decrypt_base64(cyphertext_in, key); + RETURN t_plaintext; + EXCEPTION WHEN OTHERS THEN + -- decryption did not work out, so assuming that text was not encrypted + RAISE EXCEPTION 'decryption with the given key failed!'; + END; + +END; +$$ LANGUAGE plpgsql VOLATILE; + +CREATE OR REPLACE FUNCTION encryptPasswords (key text) RETURNS VOID AS $$ +DECLARE + r_cred RECORD; + t_encrypted TEXT; +BEGIN + -- encrypt pwds in import_credential table + FOR r_cred IN + SELECT id, secret FROM import_credential + LOOP + SELECT INTO t_encrypted * FROM encryptText(r_cred.secret, key); + UPDATE import_credential SET secret=t_encrypted WHERE id=r_cred.id; + END LOOP; + + --encrypt pwds in ldap_connection table + FOR r_cred IN + SELECT ldap_search_user_pwd, ldap_write_user_pwd, ldap_connection_id FROM ldap_connection + LOOP + SELECT INTO t_encrypted * FROM encryptText(r_cred.ldap_search_user_pwd, key); + UPDATE ldap_connection SET ldap_search_user_pwd=t_encrypted WHERE ldap_connection_id=r_cred.ldap_connection_id; + SELECT INTO t_encrypted * FROM encryptText(r_cred.ldap_write_user_pwd, key); + UPDATE ldap_connection SET ldap_write_user_pwd=t_encrypted WHERE ldap_connection_id=r_cred.ldap_connection_id; + END LOOP; + + RETURN; +END; +$$ LANGUAGE plpgsql; + +-- get encryption key from filesystem +CREATE OR REPLACE FUNCTION getMainKey() RETURNS TEXT AS $$ +DECLARE + t_key TEXT; +BEGIN + CREATE TEMPORARY TABLE temp_main_key (key text); + COPY temp_main_key FROM '/etc/fworch/secrets/main_key' CSV DELIMITER ','; + SELECT INTO t_key * FROM temp_main_key; + -- RAISE NOTICE 'main key: "%"', t_key; + DROP TABLE temp_main_key; + RETURN t_key; +END; +$$ LANGUAGE plpgsql; + +-- finally do the encryption in the db tables +SELECT * FROM encryptPasswords (getMainKey()); +-- test using: SELECT * FROM custom_aes_cbc_decrypt_base64(custom_aes_cbc_encrypt_base64('xxx', 'xxx'), 'xxx'); + +-- function for adding local ldap data with encrypted pwds into ldap_connection +CREATE OR REPLACE FUNCTION insertLocalLdapWithEncryptedPasswords( + serverName TEXT, + port INTEGER, + userSearchPath TEXT, + roleSearchPath TEXT, + groupSearchPath TEXT, + tenantLevel INTEGER, + searchUser TEXT, + searchUserPwd TEXT, + writeUser TEXT, + writeUserPwd TEXT, + ldapType INTEGER +) RETURNS VOID AS $$ +DECLARE + t_key TEXT; + t_encryptedReadPwd TEXT; + t_encryptedWritePwd TEXT; +BEGIN + IF NOT EXISTS (SELECT * FROM ldap_connection WHERE ldap_server = serverName) + THEN + SELECT INTO t_key * FROM getMainKey(); + SELECT INTO t_encryptedReadPwd * FROM encryptText(searchUserPwd, t_key); + SELECT INTO t_encryptedWritePwd * FROM encryptText(writeUserPwd, t_key); + INSERT INTO ldap_connection + (ldap_server, ldap_port, ldap_searchpath_for_users, ldap_searchpath_for_roles, ldap_searchpath_for_groups, + ldap_tenant_level, ldap_search_user, ldap_search_user_pwd, ldap_write_user, ldap_write_user_pwd, ldap_type) + VALUES (serverName, port, userSearchPath, roleSearchPath, groupSearchPath, tenantLevel, searchUser, t_encryptedReadPwd, writeUser, t_encryptedWritePwd, ldapType); + END IF; +END; +$$ LANGUAGE plpgsql; +-- test using: SELECT * FROM insertLocalLdapWithEncryptedPasswords('127.0.0.3', 636, 'ou=operator,ou=user,dc=fworch,dc=internal','ou=role,dc=fworch,dc=internal','ou=group,dc=fworch,dc=internal',5,'inspector','xxx','ldapwriter','xxx',2); diff --git a/roles/database/files/upgrade/8.1.1.sql b/roles/database/files/upgrade/8.1.1.sql new file mode 100644 index 0000000000..c2a1aa48cb --- /dev/null +++ b/roles/database/files/upgrade/8.1.1.sql @@ -0,0 +1,21 @@ +alter table modelling.connection add column if not exists is_requested boolean default false; +alter table modelling.connection add column if not exists ticket_id bigint; +alter table modelling.connection add column if not exists is_published boolean default false; +alter table modelling.connection add column if not exists proposed_app_id int; +alter table owner_network add column if not exists custom_type int; +alter table request.reqtask add column if not exists additional_info varchar; + + +insert into request.state (id,name) VALUES (205,'Rework') ON CONFLICT DO NOTHING; +insert into config (config_key, config_value, config_user) VALUES ('reqNewIntStateMatrix', '{"config_value":{"request":{"matrix":{"0":[0,49,620]},"derived_states":{"0":0},"lowest_input_state":0,"lowest_start_state":0,"lowest_end_state":49,"active":true},"approval":{"matrix":{"0":[0]},"derived_states":{"0":0},"lowest_input_state":0,"lowest_start_state":0,"lowest_end_state":0,"active":false},"planning":{"matrix":{"0":[0]},"derived_states":{"0":0},"lowest_input_state":0,"lowest_start_state":0,"lowest_end_state":0,"active":false},"verification":{"matrix":{"0":[0]},"derived_states":{"0":0},"lowest_input_state":0,"lowest_start_state":0,"lowest_end_state":0,"active":false},"implementation":{"matrix":{"205":[205,249],"49":[210],"210":[610,210,249]},"derived_states":{"205":205,"49":49,"210":210},"lowest_input_state":49,"lowest_start_state":205,"lowest_end_state":249,"active":true},"review":{"matrix":{"249":[249,205,299]},"derived_states":{"249":249},"lowest_input_state":249,"lowest_start_state":249,"lowest_end_state":299,"active":true},"recertification":{"matrix":{"0":[0]},"derived_states":{"0":0},"lowest_input_state":0,"lowest_start_state":0,"lowest_end_state":0,"active":false}}}', 0) ON CONFLICT DO NOTHING; +insert into config (config_key, config_value, config_user) VALUES ('reqNewIntStateMatrixDefault', '{"config_value":{"request":{"matrix":{"0":[0,49,620]},"derived_states":{"0":0},"lowest_input_state":0,"lowest_start_state":0,"lowest_end_state":49,"active":true},"approval":{"matrix":{"0":[0]},"derived_states":{"0":0},"lowest_input_state":0,"lowest_start_state":0,"lowest_end_state":0,"active":false},"planning":{"matrix":{"0":[0]},"derived_states":{"0":0},"lowest_input_state":0,"lowest_start_state":0,"lowest_end_state":0,"active":false},"verification":{"matrix":{"0":[0]},"derived_states":{"0":0},"lowest_input_state":0,"lowest_start_state":0,"lowest_end_state":0,"active":false},"implementation":{"matrix":{"205":[205,249],"49":[210],"210":[610,210,249]},"derived_states":{"205":205,"49":49,"210":210},"lowest_input_state":49,"lowest_start_state":205,"lowest_end_state":249,"active":true},"review":{"matrix":{"249":[249,205,299]},"derived_states":{"249":249},"lowest_input_state":249,"lowest_start_state":249,"lowest_end_state":299,"active":true},"recertification":{"matrix":{"0":[0]},"derived_states":{"0":0},"lowest_input_state":0,"lowest_start_state":0,"lowest_end_state":0,"active":false}}}', 0) ON CONFLICT DO NOTHING; + +insert into config (config_key, config_value, config_user) VALUES ('modReqInterfaceName', '', 0) ON CONFLICT DO NOTHING; +insert into config (config_key, config_value, config_user) VALUES ('modReqEmailSubject', '', 0) ON CONFLICT DO NOTHING; +insert into config (config_key, config_value, config_user) VALUES ('modReqEmailBody', '', 0) ON CONFLICT DO NOTHING; +insert into config (config_key, config_value, config_user) VALUES ('modReqTicketTitle', '', 0) ON CONFLICT DO NOTHING; +insert into config (config_key, config_value, config_user) VALUES ('modReqTaskTitle', '', 0) ON CONFLICT DO NOTHING; +insert into config (config_key, config_value, config_user) VALUES ('reqOwnerBased', 'False', 0) ON CONFLICT DO NOTHING; +insert into config (config_key, config_value, config_user) VALUES ('reqShowCompliance', 'False', 0) ON CONFLICT DO NOTHING; +insert into config (config_key, config_value, config_user) VALUES ('uiHostName', 'http://localhost:5000', 0) ON CONFLICT DO NOTHING; +insert into config (config_key, config_value, config_user) VALUES ('ModAppServerTypes', '[{"Id":0,"Name":"Default"}]', 0) ON CONFLICT DO NOTHING; diff --git a/roles/database/files/upgrade/8.1.2.sql b/roles/database/files/upgrade/8.1.2.sql new file mode 100644 index 0000000000..00c0b7d0b5 --- /dev/null +++ b/roles/database/files/upgrade/8.1.2.sql @@ -0,0 +1,33 @@ +CREATE OR REPLACE FUNCTION encryptPasswords (key text) RETURNS VOID AS $$ +DECLARE + r_cred RECORD; + t_encrypted TEXT; +BEGIN + -- encrypt pwds in import_credential table + FOR r_cred IN + SELECT id, secret FROM import_credential + LOOP + SELECT INTO t_encrypted * FROM encryptText(r_cred.secret, key); + UPDATE import_credential SET secret=t_encrypted WHERE id=r_cred.id; + END LOOP; + + --encrypt pwds in ldap_connection table + FOR r_cred IN + SELECT ldap_search_user_pwd, ldap_write_user_pwd, ldap_connection_id FROM ldap_connection + LOOP + SELECT INTO t_encrypted * FROM encryptText(r_cred.ldap_search_user_pwd, key); + UPDATE ldap_connection SET ldap_search_user_pwd=t_encrypted WHERE ldap_connection_id=r_cred.ldap_connection_id; + SELECT INTO t_encrypted * FROM encryptText(r_cred.ldap_write_user_pwd, key); + UPDATE ldap_connection SET ldap_write_user_pwd=t_encrypted WHERE ldap_connection_id=r_cred.ldap_connection_id; + END LOOP; + + -- encrypt smtp email user pwds in config table + SELECT INTO r_cred config_value FROM config WHERE config_key='emailPassword'; + SELECT INTO t_encrypted * FROM encryptText(r_cred.config_value, key); + UPDATE config SET config_value=t_encrypted WHERE config_key='emailPassword'; + + RETURN; +END; +$$ LANGUAGE plpgsql; + +SELECT * FROM encryptPasswords (getMainKey()); diff --git a/roles/database/files/upgrade/8.2.2.sql b/roles/database/files/upgrade/8.2.2.sql new file mode 100644 index 0000000000..894127859f --- /dev/null +++ b/roles/database/files/upgrade/8.2.2.sql @@ -0,0 +1,37 @@ +/* + + plan "Tufin SecureChange Request Module" - TUREM + + User Interface + - modeller user can choose to request the current state of modelling for one app/owner + - a button can be used within the modeller top level menu to do so + - modelling which has already been requested and that which has not need to be displayed in NeMo so that each can be easily identified + + Automatic steps: + - TUREM needs to store the last modelling state that was requested in order to be able to request the differences + - database structure needs to be defined - if possible find a simple model which does not look like the current FWO change tracking + (work with a flag - modelled/requested) + - TUREM needs to request the creation of objects (network, service) as well as access requests based on these objects + - TUREM will not take the rulebase of the actual firewalls into account - this will be done by SC + - specifically will changes between two TUREM requests (not requested via TUREM) not be taken into account + + Open decisions/tests + - do we also need to get feedback on the implementation state of the SC ticket? If so, what to do with it? + - at least we should store the tufin ticket numbers in NeMo for reference + - can we always just create a single SC ticket or do we need multiple tickets? + - probably SC cannot deal with order of tasks so that in the first task objects are requested which are then Nused in the same ticket within an AR + - if we need multiple SC tickets, we need to be prepared to store multiple ticket numbers in NeMo for a single TUREM request + - for non-initial requests: do we have to create change requests or do we simply request the whole modelled rulebase? + - same question for changes to (modelled) objects + - what about changes to basic objects like NAs - do we requests these of just assume that they already have been implemented? + - where to draw the line? + + Preparations + - get a technical user with SC create ticket rights on Tufin STEST system + + Not customer related: + - develop in parallel: internal request module which requests the changes within the FWO request module + +*/ + +insert into config (config_key, config_value, config_user) VALUES ('extTicketSystems', '[{"Url":"","TicketTemplate":"{\"ticket\":{\"subject\":\"@@TICKET_SUBJECT@@\",\"priority\":\"@@PRIORITY@@\",\"requester\":\"@@ONBEHALF@@\",\"domain_name\":\"\",\"workflow\":{\"name\":\"@@WORKFLOW_NAME@@\"},\"steps\":{\"step\":[{\"name\":\"Erfassung des Antrags\",\"tasks\":{\"task\":{\"fields\":{\"field\":[@@TASKS@@]}}}}]}}}","TasksTemplate":"{\"@xsi.type\":\"multi_access_request\",\"name\":\"GewuenschterZugang\",\"read_only\":false,\"access_request\":{\"order\":\"AR1\",\"verifier_result\":{\"status\":\"notrun\"},\"use_topology\":true,\"targets\":{\"target\":{\"@type\":\"ANY\"}},\"users\":{\"user\":@@USERS@@},\"sources\":{\"source\":@@SOURCES@@},\"destinations\":{\"destination\":@@DESTINATIONS@@},\"services\":{\"service\":@@SERVICES@@},\"action\":\"@@ACTION@@\",\"labels\":\"\"}},{\"@xsi.type\":\"text_area\",\"name\":\"Grund fuer den Antrag\",\"read_only\":false,\"text\":\"@@REASON@@\"},{\"@xsi.type\":\"drop_down_list\",\"name\":\"Regel Log aktivieren?\",\"selection\":\"@@LOGGING@@\"},{\"@xsi.type\":\"date\",\"name\":\"Regel befristen bis:\"},{\"@xsi.type\":\"text_field\",\"name\":\"Anwendungs-ID\",\"text\":\"@@APPID@@\"},{\"@xsi.type\":\"checkbox\",\"name\":\"Die benoetigte Kommunikationsverbindung ist im Kommunikationsprofil nach IT-Sicherheitsstandard hinterlegt\",\"value\":@@COM_DOCUMENTED@@},{\"@xsi.type\":\"drop_down_list\",\"name\":\"Expertenmodus: Exakt wie beantragt implementieren (Designervorschlag ignorieren)\",\"selection\":\"Nein\"}"}]', 0) ON CONFLICT DO NOTHING; diff --git a/roles/database/files/upgrade/8.2.3.sql b/roles/database/files/upgrade/8.2.3.sql new file mode 100644 index 0000000000..bab8ded000 --- /dev/null +++ b/roles/database/files/upgrade/8.2.3.sql @@ -0,0 +1,4 @@ +ALTER TABLE modelling.connection DROP CONSTRAINT IF EXISTS modelling_connection_used_interface_foreign_key; +ALTER TABLE modelling.connection ADD CONSTRAINT modelling_connection_used_interface_foreign_key FOREIGN KEY (used_interface_id) REFERENCES modelling.connection(id) ON UPDATE RESTRICT; + +alter table modelling.connection add column if not exists conn_prop Varchar; diff --git a/roles/database/files/upgrade/8.2.4.sql b/roles/database/files/upgrade/8.2.4.sql new file mode 100644 index 0000000000..92d7666b41 --- /dev/null +++ b/roles/database/files/upgrade/8.2.4.sql @@ -0,0 +1,25 @@ +CREATE OR REPLACE FUNCTION get_rules_for_owner(device_row device, ownerid integer) +RETURNS SETOF rule AS $$ + BEGIN + RETURN QUERY + SELECT r.* FROM rule r + LEFT JOIN rule_from rf ON (r.rule_id=rf.rule_id) + LEFT JOIN objgrp_flat rf_of ON (rf.obj_id=rf_of.objgrp_flat_id) + LEFT JOIN object rf_o ON (rf_of.objgrp_flat_member_id=rf_o.obj_id) + LEFT JOIN owner_network ON + (ip_ranges_overlap(rf_o.obj_ip, rf_o.obj_ip_end, ip, ip_end, rf.negated != r.rule_src_neg)) + WHERE r.dev_id = device_row.dev_id AND owner_id = ownerid AND rule_head_text IS NULL + UNION + SELECT r.* FROM rule r + LEFT JOIN rule_to rt ON (r.rule_id=rt.rule_id) + LEFT JOIN objgrp_flat rt_of ON (rt.obj_id=rt_of.objgrp_flat_id) + LEFT JOIN object rt_o ON (rt_of.objgrp_flat_member_id=rt_o.obj_id) + LEFT JOIN owner_network ON + (ip_ranges_overlap(rt_o.obj_ip, rt_o.obj_ip_end, ip, ip_end, rt.negated != r.rule_dst_neg)) + WHERE r.dev_id = device_row.dev_id AND owner_id = ownerid AND rule_head_text IS NULL + ORDER BY rule_name; + END; +$$ LANGUAGE 'plpgsql' STABLE; + +insert into config (config_key, config_value, config_user) VALUES ('modReqEmailReceiver', 'OwnerGroupOnly', 0) ON CONFLICT DO NOTHING; +insert into config (config_key, config_value, config_user) VALUES ('modReqEmailRequesterInCc', 'true', 0) ON CONFLICT DO NOTHING; diff --git a/roles/database/files/upgrade/8.3.1.sql b/roles/database/files/upgrade/8.3.1.sql new file mode 100644 index 0000000000..d797b5cdd0 --- /dev/null +++ b/roles/database/files/upgrade/8.3.1.sql @@ -0,0 +1,15 @@ + +delete from config where config_key='ModAppServerTypes'; +insert into config (config_key, config_value, config_user) VALUES ('modAppServerTypes', '[{"Id":0,"Name":"Default"}]', 0) ON CONFLICT DO NOTHING; + +create table if not exists request.ext_state +( + id SERIAL PRIMARY KEY, + name Varchar NOT NULL, + state_id Integer +); + +ALTER TABLE request.ext_state DROP CONSTRAINT IF EXISTS request_ext_state_state_foreign_key; +ALTER TABLE request.ext_state ADD CONSTRAINT request_ext_state_state_foreign_key FOREIGN KEY (state_id) REFERENCES request.state(id) ON UPDATE RESTRICT ON DELETE CASCADE; + +ALTER TABLE owner DROP CONSTRAINT IF EXISTS owner_name_key; diff --git a/roles/database/files/upgrade/8.3.2.sql b/roles/database/files/upgrade/8.3.2.sql new file mode 100644 index 0000000000..e6bc4349ce --- /dev/null +++ b/roles/database/files/upgrade/8.3.2.sql @@ -0,0 +1 @@ +insert into config (config_key, config_value, config_user) VALUES ('welcomeMessage', '', 0) ON CONFLICT DO NOTHING; \ No newline at end of file diff --git a/roles/database/files/upgrade/8.4.1.sql b/roles/database/files/upgrade/8.4.1.sql new file mode 100644 index 0000000000..3eca8abd17 --- /dev/null +++ b/roles/database/files/upgrade/8.4.1.sql @@ -0,0 +1,75 @@ +ALTER TABLE modelling.connection DROP CONSTRAINT IF EXISTS modelling_connection_proposed_app_id_foreign_key; +ALTER TABLE modelling.connection ADD CONSTRAINT modelling_connection_proposed_app_id_foreign_key FOREIGN KEY (proposed_app_id) REFERENCES owner(id) ON UPDATE RESTRICT ON DELETE CASCADE; + +-- turning all CIDR objects into ranges +-- see https://github.com/CactuseSecurity/firewall-orchestrator/issues/2238 +-- defining helper functions: + +CREATE OR REPLACE FUNCTION get_first_ip_of_cidr (ip CIDR) + RETURNS CIDR + LANGUAGE 'plpgsql' IMMUTABLE COST 1 + AS +$BODY$ + BEGIN + IF is_single_ip(ip) THEN + RETURN ip; + ELSE + RETURN host(abbrev(ip)::cidr); + END IF; + END; +$BODY$; + +CREATE OR REPLACE FUNCTION get_last_ip_of_cidr (ip CIDR) + RETURNS CIDR + LANGUAGE 'plpgsql' IMMUTABLE COST 1 + AS +$BODY$ + BEGIN + IF is_single_ip(ip) THEN + RETURN ip; + ELSE + RETURN inet(host(broadcast(ip))); + END IF; + END; +$BODY$; + +CREATE OR REPLACE FUNCTION is_single_ip (ip CIDR) + RETURNS BOOLEAN + LANGUAGE 'plpgsql' IMMUTABLE COST 1 + AS +$BODY$ + BEGIN + RETURN masklen(ip)=32 AND family(ip)=4 OR masklen(ip)=128 AND family(ip)=6; + END; +$BODY$; + +CREATE OR REPLACE FUNCTION turn_all_cidr_objects_into_ranges () RETURNS VOID AS $$ +DECLARE + i_obj_id BIGINT; + r_obj RECORD; +BEGIN +-- handling table owner_network + ALTER TABLE owner_network ADD COLUMN IF NOT EXISTS ip_end CIDR; + + FOR r_obj IN SELECT id, ip, ip_end FROM owner_network + LOOP + IF NOT is_single_ip(r_obj.ip) OR r_obj.ip_end IS NULL THEN + UPDATE owner_network SET ip_end = get_last_ip_of_cidr(r_obj.ip) WHERE id=r_obj.id; + UPDATE owner_network SET ip = get_first_ip_of_cidr(r_obj.ip) WHERE id=r_obj.id; + END IF; + END LOOP; + + ALTER TABLE owner_network DROP CONSTRAINT IF EXISTS owner_network_ip_end_not_null; + ALTER TABLE owner_network ADD CONSTRAINT owner_network_ip_end_not_null CHECK (ip_end IS NOT NULL); + + RETURN; +END; +$$ LANGUAGE plpgsql; + +SELECT * FROM turn_all_cidr_objects_into_ranges(); +DROP FUNCTION turn_all_cidr_objects_into_ranges(); + +ALTER TABLE owner_network DROP CONSTRAINT IF EXISTS owner_network_ip_is_host; +ALTER TABLE owner_network DROP CONSTRAINT IF EXISTS owner_network_ip_end_is_host; +ALTER TABLE owner_network ADD CONSTRAINT owner_network_ip_is_host CHECK (is_single_ip(ip)); +ALTER TABLE owner_network ADD CONSTRAINT owner_network_ip_end_is_host CHECK (is_single_ip(ip_end)); diff --git a/roles/database/files/upgrade/8.4.2.sql b/roles/database/files/upgrade/8.4.2.sql new file mode 100644 index 0000000000..7b4a01b69c --- /dev/null +++ b/roles/database/files/upgrade/8.4.2.sql @@ -0,0 +1,58 @@ + +create table if not exists owner_ticket +( + owner_id int, + ticket_id bigint +); + +create table if not exists ext_request +( + id BIGSERIAL PRIMARY KEY, + owner_id int, + ticket_id bigint, + task_number int, + ext_ticket_system varchar, + ext_request_type varchar, + ext_request_content varchar, + ext_query_variables varchar, + ext_request_state varchar, + ext_ticket_id varchar, + last_creation_response varchar, + last_processing_response varchar, + create_date Timestamp default now(), + finish_date Timestamp +); + +ALTER TABLE owner_ticket DROP CONSTRAINT IF EXISTS owner_ticket_owner_id_foreign_key; +ALTER TABLE owner_ticket DROP CONSTRAINT IF EXISTS owner_ticket_ticket_id_foreign_key; +ALTER TABLE owner_ticket ADD CONSTRAINT owner_ticket_owner_id_foreign_key FOREIGN KEY (owner_id) REFERENCES owner(id) ON UPDATE RESTRICT ON DELETE CASCADE; +ALTER TABLE owner_ticket ADD CONSTRAINT owner_ticket_ticket_id_foreign_key FOREIGN KEY (ticket_id) REFERENCES request.ticket(id) ON UPDATE RESTRICT ON DELETE CASCADE; + +ALTER TABLE ext_request DROP CONSTRAINT IF EXISTS ext_request_owner_id_foreign_key; +ALTER TABLE ext_request DROP CONSTRAINT IF EXISTS ext_request_ticket_id_foreign_key; +ALTER TABLE ext_request ADD CONSTRAINT ext_request_owner_id_foreign_key FOREIGN KEY (owner_id) REFERENCES owner(id) ON UPDATE RESTRICT ON DELETE CASCADE; +ALTER TABLE ext_request ADD CONSTRAINT ext_request_ticket_id_foreign_key FOREIGN KEY (ticket_id) REFERENCES request.ticket(id) ON UPDATE RESTRICT ON DELETE CASCADE; + +ALTER TABLE management ADD COLUMN IF NOT EXISTS ext_mgm_data varchar; + +ALTER TABLE request.reqelement ADD COLUMN IF NOT EXISTS group_name varchar; +ALTER TABLE request.reqelement ADD COLUMN IF NOT EXISTS ip_end cidr; +ALTER TABLE request.reqelement ADD COLUMN IF NOT EXISTS port_end int; +ALTER TABLE request.reqelement ADD COLUMN IF NOT EXISTS name varchar; +ALTER TABLE request.implelement ADD COLUMN IF NOT EXISTS group_name varchar; +ALTER TABLE request.implelement ADD COLUMN IF NOT EXISTS ip_end cidr; +ALTER TABLE request.implelement ADD COLUMN IF NOT EXISTS port_end int; +ALTER TABLE request.implelement ADD COLUMN IF NOT EXISTS name varchar; +ALTER TABLE request.reqtask ADD COLUMN IF NOT EXISTS mgm_id int; + +ALTER TABLE request.reqtask DROP CONSTRAINT IF EXISTS request_reqtask_management_foreign_key; +ALTER TABLE request.reqtask ADD CONSTRAINT request_reqtask_management_foreign_key FOREIGN KEY (mgm_id) REFERENCES management(mgm_id) ON UPDATE RESTRICT ON DELETE CASCADE; + +insert into config (config_key, config_value, config_user) VALUES ('externalRequestSleepTime', '0', 0) ON CONFLICT DO NOTHING; +insert into config (config_key, config_value, config_user) VALUES ('externalRequestStartAt', '00:00:00', 0) ON CONFLICT DO NOTHING; +insert into config (config_key, config_value, config_user) VALUES ('modRolloutActive', 'true', 0) ON CONFLICT DO NOTHING; +insert into config (config_key, config_value, config_user) VALUES ('modRolloutResolveServiceGroups', 'true', 0) ON CONFLICT DO NOTHING; +insert into config (config_key, config_value, config_user) VALUES ('modRolloutBundleTasks', 'false', 0) ON CONFLICT DO NOTHING; + +ALTER TYPE action_enum ADD VALUE IF NOT EXISTS 'unchanged'; + diff --git a/roles/database/files/upgrade/8.4.3.sql b/roles/database/files/upgrade/8.4.3.sql new file mode 100644 index 0000000000..ff093ed9ee --- /dev/null +++ b/roles/database/files/upgrade/8.4.3.sql @@ -0,0 +1,9 @@ + +alter table modelling.connection add column if not exists extra_params Varchar; + +insert into config (config_key, config_value, config_user) VALUES ('modExtraConfigs', '[]', 0) ON CONFLICT DO NOTHING; +insert into config (config_key, config_value, config_user) VALUES ('modRolloutErrorText', 'Error during external request', 0) ON CONFLICT DO NOTHING; + +ALTER TYPE action_enum ADD VALUE IF NOT EXISTS 'addAfterCreation'; + +delete from config where config_key='[]'; diff --git a/roles/database/files/upgrade/8.5.2.sql b/roles/database/files/upgrade/8.5.2.sql new file mode 100644 index 0000000000..c5372e9cee --- /dev/null +++ b/roles/database/files/upgrade/8.5.2.sql @@ -0,0 +1,14 @@ +DO $do$ BEGIN + IF NOT EXISTS (SELECT color_name FROM stm_color WHERE color_name='crete blue') THEN + INSERT INTO stm_color (color_name, color_rgb) VALUES ('crete blue', '485cd4'); + END IF; + IF NOT EXISTS (SELECT color_name FROM stm_color WHERE color_name='state blue') THEN + INSERT INTO stm_color (color_name, color_rgb) VALUES ('state blue', 'a186ed'); + END IF; + IF NOT EXISTS (SELECT color_name FROM stm_color WHERE color_name='olive') THEN + INSERT INTO stm_color (color_name, color_rgb) VALUES ('olive', '617d28'); + END IF; + IF NOT EXISTS (SELECT color_name FROM stm_color WHERE color_name='dark gold') THEN + INSERT INTO stm_color (color_name, color_rgb) VALUES ('dark gold', 'cdad00'); + END IF; +END $do$; diff --git a/roles/database/files/upgrade/8.5.3.sql b/roles/database/files/upgrade/8.5.3.sql new file mode 100644 index 0000000000..29db8e954b --- /dev/null +++ b/roles/database/files/upgrade/8.5.3.sql @@ -0,0 +1,6 @@ +-- dropping trigger for materialized view view_rule_with_owner +drop trigger IF exists refresh_view_rule_with_owner_delete_trigger ON recertification CASCADE; + +insert into config (config_key, config_value, config_user) VALUES ('ownerLdapId', '1', 0) ON CONFLICT DO NOTHING; +insert into config (config_key, config_value, config_user) VALUES ('ownerLdapGroupNames', 'cn=ModellerGroup_@@ExternalAppId@@,ou=group,dc=fworch,dc=internal', 0) ON CONFLICT DO NOTHING; +insert into config (config_key, config_value, config_user) VALUES ('manageOwnerLdapGroups', 'true', 0) ON CONFLICT DO NOTHING; diff --git a/roles/database/files/upgrade/8.5.4.sql b/roles/database/files/upgrade/8.5.4.sql new file mode 100644 index 0000000000..c3c69c04cf --- /dev/null +++ b/roles/database/files/upgrade/8.5.4.sql @@ -0,0 +1,3 @@ +ALTER TABLE ext_request ADD COLUMN IF NOT EXISTS wait_cycles int DEFAULT 0; + +insert into config (config_key, config_value, config_user) VALUES ('externalRequestWaitCycles', '0', 0) ON CONFLICT DO NOTHING; diff --git a/roles/database/files/upgrade/8.6.1.sql b/roles/database/files/upgrade/8.6.1.sql new file mode 100644 index 0000000000..02133a11ea --- /dev/null +++ b/roles/database/files/upgrade/8.6.1.sql @@ -0,0 +1,107 @@ +ALTER TABLE owner_network DROP CONSTRAINT IF EXISTS owner_network_ip_unique; +ALTER TABLE owner_network ADD CONSTRAINT owner_network_ip_unique UNIQUE (owner_id, ip, ip_end, import_source); +ALTER TABLE ext_request ADD COLUMN IF NOT EXISTS locked boolean default false; + +-- Create indexes on the materialized view +CREATE INDEX IF NOT EXISTS idx_view_rule_with_owner_rule_id ON view_rule_with_owner (rule_id); +CREATE INDEX IF NOT EXISTS idx_view_rule_with_owner_owner_id ON view_rule_with_owner (owner_id); + +-- -- function used during import of owner data +CREATE OR REPLACE FUNCTION recert_refresh_per_owner(i_owner_id INTEGER) RETURNS VOID AS $$ +DECLARE + r_mgm RECORD; +BEGIN + BEGIN + FOR r_mgm IN + SELECT mgm_id, mgm_name FROM management + LOOP + PERFORM recert_refresh_one_owner_one_mgm (i_owner_id, r_mgm.mgm_id, NULL::TIMESTAMP); + END LOOP; + + EXCEPTION WHEN OTHERS THEN + RAISE EXCEPTION 'Exception caught in recert_refresh_per_owner while handling management %', r_mgm.mgm_name; + END; + RETURN; +END; +$$ LANGUAGE plpgsql; + + +-- CREATE OR REPLACE FUNCTION owner_change_triggered () +-- RETURNS TRIGGER +-- AS $BODY$ +-- BEGIN +-- IF NOT NEW.id IS NULL THEN +-- PERFORM recert_refresh_per_owner(NEW.id); +-- END IF; +-- RETURN NEW; +-- END; +-- $BODY$ +-- LANGUAGE plpgsql +-- VOLATILE; +-- ALTER FUNCTION public.owner_change_triggered () OWNER TO fworch; + + +-- DROP TRIGGER IF EXISTS owner_change ON owner CASCADE; + +-- CREATE TRIGGER owner_change +-- AFTER INSERT OR UPDATE OR DELETE ON owner +-- FOR EACH ROW +-- EXECUTE PROCEDURE owner_change_triggered (); + +-- CREATE OR REPLACE FUNCTION owner_network_change_triggered () +-- RETURNS TRIGGER +-- AS $BODY$ +-- BEGIN +-- IF NOT NEW.owner_id IS NULL THEN +-- PERFORM recert_refresh_per_owner(NEW.owner_id); +-- END IF; +-- RETURN NEW; +-- END; +-- $BODY$ +-- LANGUAGE plpgsql +-- VOLATILE; +-- ALTER FUNCTION public.owner_network_change_triggered () OWNER TO fworch; + +-- DROP TRIGGER IF EXISTS owner_network_change ON owner_network CASCADE; + +-- CREATE TRIGGER owner_network_change +-- AFTER INSERT OR UPDATE OR DELETE ON owner_network +-- FOR EACH ROW +-- EXECUTE PROCEDURE owner_network_change_triggered (); + +DROP FUNCTION IF EXISTS recert_refresh_per_owner(INTEGER); +DROP FUNCTION IF EXISTS refresh_view_rule_with_owner(); +DROP TRIGGER IF EXISTS owner_network_change ON owner_network CASCADE; +DROP FUNCTION IF EXISTS owner_network_change_triggered (); +DROP TRIGGER IF EXISTS owner_change ON owner CASCADE; +DROP FUNCTION IF EXISTS owner_change_triggered (); + +CREATE TABLE IF NOT EXISTS refresh_log ( + id SERIAL PRIMARY KEY, + view_name TEXT NOT NULL, + refreshed_at TIMESTAMPTZ DEFAULT now(), + status TEXT +); + +CREATE OR REPLACE FUNCTION refresh_view_rule_with_owner() +RETURNS SETOF refresh_log AS $$ +DECLARE + status_message TEXT; +BEGIN + -- Attempt to refresh the materialized view + BEGIN + REFRESH MATERIALIZED VIEW view_rule_with_owner; + status_message := 'Materialized view refreshed successfully'; + EXCEPTION + WHEN OTHERS THEN + status_message := format('Failed to refresh view: %s', SQLERRM); + END; + + -- Log the operation + INSERT INTO refresh_log (view_name, status) + VALUES ('view_rule_with_owner', status_message); + + -- Return the log entry + RETURN QUERY SELECT * FROM refresh_log WHERE view_name = 'view_rule_with_owner' ORDER BY refreshed_at DESC LIMIT 1; +END; +$$ LANGUAGE plpgsql VOLATILE; diff --git a/roles/database/files/upgrade/8.6.3.sql b/roles/database/files/upgrade/8.6.3.sql new file mode 100644 index 0000000000..5876c53a41 --- /dev/null +++ b/roles/database/files/upgrade/8.6.3.sql @@ -0,0 +1,37 @@ +insert into config (config_key, config_value, config_user) VALUES ('dnsLookup', 'False', 0) ON CONFLICT DO NOTHING; +insert into config (config_key, config_value, config_user) VALUES ('overwriteExistingNames', 'False', 0) ON CONFLICT DO NOTHING; +insert into config (config_key, config_value, config_user) VALUES ('autoReplaceAppServer', 'False', 0) ON CONFLICT DO NOTHING; + +ALTER TABLE modelling.change_history ADD COLUMN IF NOT EXISTS change_source Varchar default 'manual'; + + +CREATE TABLE IF NOT EXISTS refresh_log ( + id SERIAL PRIMARY KEY, + view_name TEXT NOT NULL, + refreshed_at TIMESTAMPTZ DEFAULT now(), + status TEXT +); + +DROP FUNCTION IF EXISTS refresh_view_rule_with_owner(); +CREATE OR REPLACE FUNCTION refresh_view_rule_with_owner() +RETURNS SETOF refresh_log AS $$ +DECLARE + status_message TEXT; +BEGIN + -- Attempt to refresh the materialized view + BEGIN + REFRESH MATERIALIZED VIEW view_rule_with_owner; + status_message := 'Materialized view refreshed successfully'; + EXCEPTION + WHEN OTHERS THEN + status_message := format('Failed to refresh view: %s', SQLERRM); + END; + + -- Log the operation + INSERT INTO refresh_log (view_name, status) + VALUES ('view_rule_with_owner', status_message); + + -- Return the log entry + RETURN QUERY SELECT * FROM refresh_log WHERE view_name = 'view_rule_with_owner' ORDER BY refreshed_at DESC LIMIT 1; +END; +$$ LANGUAGE plpgsql VOLATILE; diff --git a/roles/database/files/upgrade/8.7.1.sql b/roles/database/files/upgrade/8.7.1.sql new file mode 100644 index 0000000000..3dae3c8770 --- /dev/null +++ b/roles/database/files/upgrade/8.7.1.sql @@ -0,0 +1,244 @@ +Alter table "ldap_connection" ADD COLUMN IF NOT EXISTS "ldap_writepath_for_groups" Varchar; + +CREATE OR REPLACE FUNCTION insertLocalLdapWithEncryptedPasswords( + serverName TEXT, + port INTEGER, + userSearchPath TEXT, + roleSearchPath TEXT, + groupSearchPath TEXT, + groupWritePath TEXT, + tenantLevel INTEGER, + searchUser TEXT, + searchUserPwd TEXT, + writeUser TEXT, + writeUserPwd TEXT, + ldapType INTEGER +) RETURNS VOID AS $$ +DECLARE + t_key TEXT; + t_encryptedReadPwd TEXT; + t_encryptedWritePwd TEXT; +BEGIN + IF NOT EXISTS (SELECT * FROM ldap_connection WHERE ldap_server = serverName) + THEN + SELECT INTO t_key * FROM getMainKey(); + SELECT INTO t_encryptedReadPwd * FROM encryptText(searchUserPwd, t_key); + SELECT INTO t_encryptedWritePwd * FROM encryptText(writeUserPwd, t_key); + INSERT INTO ldap_connection + (ldap_server, ldap_port, ldap_searchpath_for_users, ldap_searchpath_for_roles, ldap_searchpath_for_groups, ldap_writepath_for_groups, + ldap_tenant_level, ldap_search_user, ldap_search_user_pwd, ldap_write_user, ldap_write_user_pwd, ldap_type) + VALUES (serverName, port, userSearchPath, roleSearchPath, groupSearchPath, groupWritePath, tenantLevel, searchUser, t_encryptedReadPwd, writeUser, t_encryptedWritePwd, ldapType); + END IF; +END; +$$ LANGUAGE plpgsql; + +-- in preparation for performance optimization in march 2025 + +-- all indices have been tested with ~660 tickets and ~2000 tasks +-- but did not really improve performance +-- so we will not use them for now + +-- DROP INDEX IF EXISTS IF EXISTS idx_owner01; +-- DROP INDEX IF EXISTS idx_owner_network01; +-- DROP INDEX IF EXISTS idx_owner_network02; +-- DROP INDEX IF EXISTS request.idx_reqtask_owner01; +-- DROP INDEX IF EXISTS request.idx_reqtask_owner02; +-- DROP INDEX IF EXISTS request.idx_request_ticket01; +-- DROP INDEX IF EXISTS request.idx_request_ticket02; +-- DROP INDEX IF EXISTS request.idx_request_ticket03; +-- DROP INDEX IF EXISTS request.idx_request_ticket04; +-- DROP INDEX IF EXISTS request.idx_request_ticket05; +-- DROP INDEX IF EXISTS request.idx_request_reqtask01; +-- DROP INDEX IF EXISTS request.idx_request_reqtask02; +-- DROP INDEX IF EXISTS request.idx_request_reqtask03; +-- DROP INDEX IF EXISTS request.idx_request_reqtask04; +-- DROP INDEX IF EXISTS request.idx_request_reqtask05; +-- DROP INDEX IF EXISTS request.idx_request_reqtask06; +-- DROP INDEX IF EXISTS request.idx_request_reqtask07; +-- DROP INDEX IF EXISTS request.idx_request_reqtask08; +-- DROP INDEX IF EXISTS request.idx_request_reqtask09; +-- DROP INDEX IF EXISTS request.idx_request_reqtask10; +-- DROP INDEX IF EXISTS request.idx_request_reqelement01; +-- DROP INDEX IF EXISTS request.idx_request_reqelement02; +-- DROP INDEX IF EXISTS request.idx_request_reqelement03; +-- DROP INDEX IF EXISTS request.idx_request_reqelement04; +-- DROP INDEX IF EXISTS request.idx_request_reqelement05; +-- DROP INDEX IF EXISTS request.idx_request_reqelement06; +-- DROP INDEX IF EXISTS request.idx_request_reqelement07; +-- DROP INDEX IF EXISTS request.idx_request_approval01; +-- DROP INDEX IF EXISTS request.idx_request_approval02; +-- DROP INDEX IF EXISTS request.idx_request_approval03; +-- DROP INDEX IF EXISTS request.idx_request_approval04; +-- DROP INDEX IF EXISTS request.idx_request_approval05; +-- DROP INDEX IF EXISTS request.idx_request_comment01; +-- DROP INDEX IF EXISTS request.idx_request_comment02; +-- DROP INDEX IF EXISTS request.idx_request_ticket_comment01; +-- DROP INDEX IF EXISTS request.idx_request_ticket_comment02; +-- DROP INDEX IF EXISTS request.idx_request_reqtask_comment01; +-- DROP INDEX IF EXISTS request.idx_request_reqtask_comment02; +-- DROP INDEX IF EXISTS request.idx_request_approval_comment01; +-- DROP INDEX IF EXISTS request.idx_request_approval_comment02; +-- DROP INDEX IF EXISTS request.idx_request_impltask_comment01; +-- DROP INDEX IF EXISTS request.idx_request_impltask_comment02; +-- DROP INDEX IF EXISTS request.idx_request_implelement01; +-- DROP INDEX IF EXISTS request.idx_request_implelement02; +-- DROP INDEX IF EXISTS request.idx_request_implelement03; +-- DROP INDEX IF EXISTS request.idx_request_implelement04; +-- DROP INDEX IF EXISTS request.idx_request_implelement05; +-- DROP INDEX IF EXISTS request.idx_request_implelement06; +-- DROP INDEX IF EXISTS request.idx_request_impltask01; +-- DROP INDEX IF EXISTS request.idx_request_impltask02; +-- DROP INDEX IF EXISTS request.idx_request_impltask03; +-- DROP INDEX IF EXISTS request.idx_request_impltask04; +-- DROP INDEX IF EXISTS request.idx_request_impltask05; +-- DROP INDEX IF EXISTS request.idx_request_impltask06; +-- DROP INDEX IF EXISTS request.idx_request_impltask07; +-- DROP INDEX IF EXISTS request.idx_request_impltask08; +-- DROP INDEX IF EXISTS request.idx_request_impltask09; +-- DROP INDEX IF EXISTS modelling.idx_modelling_nwgroup01; +-- DROP INDEX IF EXISTS modelling.idx_modelling_connection01; +-- DROP INDEX IF EXISTS modelling.idx_modelling_connection02; +-- DROP INDEX IF EXISTS modelling.idx_modelling_connection03; +-- DROP INDEX IF EXISTS modelling.idx_modelling_nwobject_nwgroup01; +-- DROP INDEX IF EXISTS modelling.idx_modelling_nwobject_nwgroup02; +-- DROP INDEX IF EXISTS modelling.idx_modelling_nwgroup_connection01; +-- DROP INDEX IF EXISTS modelling.idx_modelling_nwgroup_connection02; +-- DROP INDEX IF EXISTS modelling.idx_modelling_nwobject_connection01; +-- DROP INDEX IF EXISTS modelling.idx_modelling_nwobject_connection02; +-- DROP INDEX IF EXISTS modelling.idx_modelling_service01; +-- DROP INDEX IF EXISTS modelling.idx_modelling_service02; +-- DROP INDEX IF EXISTS modelling.idx_modelling_service_group01; +-- DROP INDEX IF EXISTS modelling.idx_modelling_service_service_group01; +-- DROP INDEX IF EXISTS modelling.idx_modelling_service_service_group02; +-- DROP INDEX IF EXISTS modelling.idx_modelling_service_group_connection01; +-- DROP INDEX IF EXISTS modelling.idx_modelling_service_group_connection02; +-- DROP INDEX IF EXISTS modelling.idx_modelling_service_connection01; +-- DROP INDEX IF EXISTS modelling.idx_modelling_service_connection02; +-- DROP INDEX IF EXISTS modelling.idx_modelling_change_history01; +-- DROP INDEX IF EXISTS modelling.idx_modelling_selected_objects01; +-- DROP INDEX IF EXISTS modelling.idx_modelling_selected_objects02; +-- DROP INDEX IF EXISTS modelling.idx_modelling_selected_connections01; +-- DROP INDEX IF EXISTS modelling.idx_modelling_selected_connections02; + +--- create indices for owner & reqtask_owner --- +-- CREATE index if not exists idx_owner01 on owner (tenant_id); + +-- CREATE index if not exists idx_reqtask_owner01 on reqtask_owner (reqtask_id); +-- CREATE index if not exists idx_reqtask_owner02 on reqtask_owner (owner_id); + +-- -- adding indices for workflow (request schema) +-- CREATE index if not exists idx_request_ticket01 on request.ticket(state_id); +-- CREATE index if not exists idx_request_ticket02 on request.ticket(tenant_id); +-- CREATE index if not exists idx_request_ticket03 on request.ticket(requester_id); +-- CREATE index if not exists idx_request_ticket04 on request.ticket(current_handler); +-- CREATE index if not exists idx_request_ticket05 on request.ticket(recent_handler); + +-- CREATE index if not exists idx_request_reqtask01 on request.reqtask (ticket_id); +-- CREATE index if not exists idx_request_reqtask02 on request.reqtask (state_id); +-- CREATE index if not exists idx_request_reqtask03 on request.reqtask (rule_action); +-- CREATE index if not exists idx_request_reqtask04 on request.reqtask (rule_tracking); +-- CREATE index if not exists idx_request_reqtask05 on request.reqtask (svc_grp_id); +-- CREATE index if not exists idx_request_reqtask06 on request.reqtask (nw_obj_grp_id); +-- CREATE index if not exists idx_request_reqtask07 on request.reqtask (user_grp_id); +-- CREATE index if not exists idx_request_reqtask08 on request.reqtask (current_handler); +-- CREATE index if not exists idx_request_reqtask09 on request.reqtask (recent_handler); +-- CREATE index if not exists idx_request_reqtask10 on request.reqtask (mgm_id); + +-- CREATE index if not exists idx_request_reqelement01 on request.reqelement (task_id); +-- CREATE index if not exists idx_request_reqelement02 on request.reqelement (ip_proto_id); +-- CREATE index if not exists idx_request_reqelement03 on request.reqelement (service_id); +-- CREATE index if not exists idx_request_reqelement04 on request.reqelement (network_object_id); +-- CREATE index if not exists idx_request_reqelement05 on request.reqelement (original_nat_id); +-- CREATE index if not exists idx_request_reqelement06 on request.reqelement (user_id); +-- CREATE index if not exists idx_request_reqelement07 on request.reqelement (device_id); + +-- CREATE index if not exists idx_request_approval01 on request.approval (task_id); +-- CREATE index if not exists idx_request_approval02 on request.approval (tenant_id); +-- CREATE index if not exists idx_request_approval03 on request.approval (state_id); +-- CREATE index if not exists idx_request_approval04 on request.approval (current_handler); +-- CREATE index if not exists idx_request_approval05 on request.approval (recent_handler); + +-- CREATE index if not exists idx_request_comment01 on request.comment (creator_id); +-- CREATE index if not exists idx_request_comment02 on request.comment (ref_id); + +-- CREATE index if not exists idx_owner_network01 on owner_network (ip_proto_id); +-- CREATE index if not exists idx_owner_network02 on owner_network (owner_id); + +-- CREATE index if not exists idx_request_ticket_comment01 on request.ticket_comment (ticket_id); +-- CREATE index if not exists idx_request_ticket_comment02 on request.ticket_comment (comment_id); + +-- CREATE index if not exists idx_request_reqtask_comment01 on request.reqtask_comment (comment_id); +-- CREATE index if not exists idx_request_reqtask_comment02 on request.reqtask_comment (task_id); + +-- CREATE index if not exists idx_request_approval_comment01 on request.approval_comment (comment_id); +-- CREATE index if not exists idx_request_approval_comment02 on request.approval_comment (approval_id); + +-- CREATE index if not exists idx_request_impltask_comment01 on request.impltask_comment (comment_id); +-- CREATE index if not exists idx_request_impltask_comment02 on request.impltask_comment (task_id); + +-- CREATE index if not exists idx_request_implelement01 on request.implelement (original_nat_id); +-- CREATE index if not exists idx_request_implelement02 on request.implelement (service_id); +-- CREATE index if not exists idx_request_implelement03 on request.implelement (network_object_id); +-- CREATE index if not exists idx_request_implelement04 on request.implelement (ip_proto_id); +-- CREATE index if not exists idx_request_implelement05 on request.implelement (implementation_task_id); +-- CREATE index if not exists idx_request_implelement06 on request.implelement (user_id); + +-- CREATE index if not exists idx_request_impltask01 on request.impltask (reqtask_id); +-- CREATE index if not exists idx_request_impltask02 on request.impltask (state_id); +-- CREATE index if not exists idx_request_impltask03 on request.impltask (device_id); +-- CREATE index if not exists idx_request_impltask04 on request.impltask (rule_action); +-- CREATE index if not exists idx_request_impltask05 on request.impltask (rule_tracking); +-- CREATE index if not exists idx_request_impltask06 on request.impltask (svc_grp_id); +-- CREATE index if not exists idx_request_impltask07 on request.impltask (user_grp_id); +-- CREATE index if not exists idx_request_impltask08 on request.impltask (current_handler); +-- CREATE index if not exists idx_request_impltask09 on request.impltask (recent_handler); + +-- -- Create indices for modelling schema foreign keys +-- CREATE index if not exists idx_modelling_nwgroup01 on modelling.nwgroup (app_id); + +-- CREATE INDEX IF NOT EXISTS idx_modelling_connection01 ON modelling.connection (app_id); +-- CREATE INDEX IF NOT EXISTS idx_modelling_connection02 ON modelling.connection (used_interface_id); +-- CREATE INDEX IF NOT EXISTS idx_modelling_connection03 ON modelling.connection (proposed_app_id); + +-- CREATE INDEX IF NOT EXISTS idx_modelling_nwobject_nwgroup01 ON modelling.nwobject_nwgroup (nwobject_id); +-- CREATE INDEX IF NOT EXISTS idx_modelling_nwobject_nwgroup02 ON modelling.nwobject_nwgroup (nwgroup_id); + +-- CREATE INDEX IF NOT EXISTS idx_modelling_nwgroup_connection01 ON modelling.nwgroup_connection (nwgroup_id); +-- CREATE INDEX IF NOT EXISTS idx_modelling_nwgroup_connection02 ON modelling.nwgroup_connection (connection_id); + +-- CREATE INDEX IF NOT EXISTS idx_modelling_nwobject_connection01 ON modelling.nwobject_connection (nwobject_id); +-- CREATE INDEX IF NOT EXISTS idx_modelling_nwobject_connection02 ON modelling.nwobject_connection (connection_id); + +-- CREATE INDEX IF NOT EXISTS idx_modelling_service01 ON modelling.service (app_id); +-- CREATE INDEX IF NOT EXISTS idx_modelling_service02 ON modelling.service (proto_id); + +-- CREATE INDEX IF NOT EXISTS idx_modelling_service_group01 ON modelling.service_group (app_id); + +-- CREATE INDEX IF NOT EXISTS idx_modelling_service_service_group01 ON modelling.service_service_group (service_id); +-- CREATE INDEX IF NOT EXISTS idx_modelling_service_service_group02 ON modelling.service_service_group (service_group_id); + +-- CREATE INDEX IF NOT EXISTS idx_modelling_service_group_connection01 ON modelling.service_group_connection (service_group_id); +-- CREATE INDEX IF NOT EXISTS idx_modelling_service_group_connection02 ON modelling.service_group_connection (connection_id); + +-- CREATE INDEX IF NOT EXISTS idx_modelling_service_connection01 ON modelling.service_connection (service_id); +-- CREATE INDEX IF NOT EXISTS idx_modelling_service_connection02 ON modelling.service_connection (connection_id); + +-- CREATE INDEX IF NOT EXISTS idx_modelling_change_history01 ON modelling.change_history (app_id); + +-- CREATE INDEX IF NOT EXISTS idx_modelling_selected_objects01 ON modelling.selected_objects (app_id); +-- CREATE INDEX IF NOT EXISTS idx_modelling_selected_objects02 ON modelling.selected_objects (nwgroup_id); + +-- CREATE INDEX IF NOT EXISTS idx_modelling_selected_connections01 ON modelling.selected_connections (app_id); +-- CREATE INDEX IF NOT EXISTS idx_modelling_selected_connections02 ON modelling.selected_connections (connection_id); + + -- some other candidates: + + -- --- rule_owner --- + -- ALTER TABLE rule_owner ADD CONSTRAINT rule_owner_rule_metadata_foreign_key FOREIGN KEY (rule_metadata_id) REFERENCES rule_metadata(rule_metadata_id) ON UPDATE RESTRICT ON DELETE CASCADE; + -- ALTER TABLE rule_owner ADD CONSTRAINT rule_owner_owner_foreign_key FOREIGN KEY (owner_id) REFERENCES owner(id) ON UPDATE RESTRICT ON DELETE CASCADE; + + -- --- state_action --- + -- ALTER TABLE request.state_action ADD CONSTRAINT request_state_action_state_foreign_key FOREIGN KEY (state_id) REFERENCES request.state(id) ON UPDATE RESTRICT ON DELETE CASCADE; + -- ALTER TABLE request.state_action ADD CONSTRAINT request_state_action_action_foreign_key FOREIGN KEY (action_id) REFERENCES request.action(id) ON UPDATE RESTRICT ON DELETE CASCADE; + -- --- ext_state --- + -- ALTER TABLE request.ext_state ADD CONSTRAINT request_ext_state_state_foreign_key FOREIGN KEY (state_id) REFERENCES request.state(id) ON UPDATE RESTRICT ON DELETE CASCADE; diff --git a/roles/database/files/upgrade/8.7.2.sql b/roles/database/files/upgrade/8.7.2.sql new file mode 100644 index 0000000000..84ee02df68 --- /dev/null +++ b/roles/database/files/upgrade/8.7.2.sql @@ -0,0 +1,7 @@ + +ALTER TABLE ext_request ADD COLUMN IF NOT EXISTS attempts int DEFAULT 0; + +insert into config (config_key, config_value, config_user) VALUES ('modModelledMarker', 'FWOC', 0) ON CONFLICT DO NOTHING; +insert into config (config_key, config_value, config_user) VALUES ('modModelledMarkerLocation', 'rulename', 0) ON CONFLICT DO NOTHING; +insert into config (config_key, config_value, config_user) VALUES ('ruleRecognitionOption', '{"nwRegardIp":true,"nwRegardName":false,"nwRegardGroupName":false,"nwResolveGroup":false,"svcRegardPortAndProt":true,"svcRegardName":false,"svcRegardGroupName":false,"svcResolveGroup":true}', 0) ON CONFLICT DO NOTHING; +insert into config (config_key, config_value, config_user) VALUES ('availableReportTypes', '[1,2,3,4,5,6,7,8,9,10,21,22]', 0) ON CONFLICT DO NOTHING; diff --git a/roles/database/files/upgrade/8.8.10.sql b/roles/database/files/upgrade/8.8.10.sql new file mode 100644 index 0000000000..96144af975 --- /dev/null +++ b/roles/database/files/upgrade/8.8.10.sql @@ -0,0 +1,4 @@ +alter table report add column if not exists read_only Boolean default FALSE; + +alter table owner_recertification drop constraint if exists owner_recertification_owner_foreign_key; +ALTER TABLE owner_recertification ADD CONSTRAINT owner_recertification_owner_foreign_key FOREIGN KEY (owner_id) REFERENCES owner(id) ON UPDATE RESTRICT ON DELETE CASCADE; diff --git a/roles/database/files/upgrade/8.8.2.sql b/roles/database/files/upgrade/8.8.2.sql new file mode 100644 index 0000000000..b217fc61a3 --- /dev/null +++ b/roles/database/files/upgrade/8.8.2.sql @@ -0,0 +1,5 @@ +insert into config (config_key, config_value, config_user) VALUES ('varianceAnalysisSleepTime', '0', 0) ON CONFLICT DO NOTHING; +insert into config (config_key, config_value, config_user) VALUES ('varianceAnalysisStartAt', '00:00:00', 0) ON CONFLICT DO NOTHING; +insert into config (config_key, config_value, config_user) VALUES ('varianceAnalysisSync', 'false', 0) ON CONFLICT DO NOTHING; +insert into config (config_key, config_value, config_user) VALUES ('varianceAnalysisRefresh', 'false', 0) ON CONFLICT DO NOTHING; +insert into config (config_key, config_value, config_user) VALUES ('resolveNetworkAreas', 'false', 0) ON CONFLICT DO NOTHING; diff --git a/roles/database/files/upgrade/8.8.3.sql b/roles/database/files/upgrade/8.8.3.sql new file mode 100644 index 0000000000..4f665a0ac3 --- /dev/null +++ b/roles/database/files/upgrade/8.8.3.sql @@ -0,0 +1,5 @@ +ALTER TABLE modelling.connection ADD COLUMN IF NOT EXISTS requested_on_fw boolean default false; +ALTER TABLE modelling.connection ADD COLUMN IF NOT EXISTS removed boolean default false; +ALTER TABLE modelling.connection ADD COLUMN IF NOT EXISTS removal_date timestamp; + +UPDATE modelling.connection SET requested_on_fw=true WHERE requested_on_fw=false; diff --git a/roles/database/files/upgrade/8.8.4.sql b/roles/database/files/upgrade/8.8.4.sql new file mode 100644 index 0000000000..0577e59728 --- /dev/null +++ b/roles/database/files/upgrade/8.8.4.sql @@ -0,0 +1,3 @@ +insert into config (config_key, config_value, config_user) VALUES ('useCustomLogo', 'False', 0) ON CONFLICT DO NOTHING; +insert into config (config_key, config_value, config_user) VALUES ('customLogoData', '', 0) ON CONFLICT DO NOTHING; +insert into stm_action (action_id,action_name) VALUES (30,'ask') ON CONFLICT DO NOTHING; -- cp diff --git a/roles/database/files/upgrade/8.8.5.sql b/roles/database/files/upgrade/8.8.5.sql new file mode 100644 index 0000000000..d80832bbc1 --- /dev/null +++ b/roles/database/files/upgrade/8.8.5.sql @@ -0,0 +1,58 @@ +ALTER TYPE rule_field_enum ADD VALUE IF NOT EXISTS 'modelled_source'; +ALTER TYPE rule_field_enum ADD VALUE IF NOT EXISTS 'modelled_destination'; + +-- rename changes_found column to rule_changes_found in import_control table +DO $$ +BEGIN + IF EXISTS ( + SELECT 1 + FROM information_schema.columns + WHERE table_name = 'import_control' + AND column_name = 'changes_found' + ) THEN + EXECUTE 'ALTER TABLE import_control RENAME COLUMN changes_found TO rule_changes_found'; + END IF; +END +$$; + +-- add any_changes_found column to import_control table +ALTER table "import_control" + ADD COLUMN IF NOT EXISTS "any_changes_found" Boolean Default FALSE; + + +-- now set the any_changes_found column to true for all imports that have security relevant changes + +DROP VIEW IF EXISTS view_imports_with_security_relevant_changes; + +CREATE OR REPLACE VIEW view_imports_with_security_relevant_changes AS + SELECT clr.control_id AS import_id, clr.mgm_id + FROM changelog_rule clr + WHERE clr.security_relevant + + UNION + + SELECT clo.control_id AS import_id, clo.mgm_id + FROM changelog_object clo + WHERE clo.security_relevant + + UNION + + SELECT cls.control_id AS import_id, cls.mgm_id + FROM changelog_service cls + WHERE cls.security_relevant + + UNION + + SELECT clu.control_id AS import_id, clu.mgm_id + FROM changelog_user clu + WHERE clu.security_relevant; + + +UPDATE import_control +SET any_changes_found = true +WHERE control_id IN ( + SELECT import_id + FROM view_imports_with_security_relevant_changes +); + +DROP VIEW IF EXISTS view_imports_with_security_relevant_changes; diff --git a/roles/database/files/upgrade/8.8.6.sql b/roles/database/files/upgrade/8.8.6.sql new file mode 100644 index 0000000000..199fd73e89 --- /dev/null +++ b/roles/database/files/upgrade/8.8.6.sql @@ -0,0 +1,2 @@ +insert into stm_track (track_id,track_name) VALUES (23,'detailed log') ON CONFLICT DO NOTHING; -- check point R8x: +insert into stm_track (track_id,track_name) VALUES (24,'extended log') ON CONFLICT DO NOTHING; -- check point R8x: diff --git a/roles/database/files/upgrade/8.8.8.sql b/roles/database/files/upgrade/8.8.8.sql new file mode 100644 index 0000000000..e1d0b8a60b --- /dev/null +++ b/roles/database/files/upgrade/8.8.8.sql @@ -0,0 +1,34 @@ +DO $$ +BEGIN + IF NOT EXISTS (SELECT FROM pg_roles WHERE rolname = 'fwo_ro') THEN + CREATE ROLE fwo_ro WITH LOGIN NOSUPERUSER INHERIT NOCREATEDB NOCREATEROLE; + END IF; +END +$$; + + +GRANT CONNECT ON DATABASE fworchdb TO fwo_ro; + +GRANT USAGE ON SCHEMA compliance TO fwo_ro; +GRANT SELECT ON ALL TABLES IN SCHEMA compliance TO fwo_ro; +GRANT USAGE, SELECT ON ALL SEQUENCES IN SCHEMA compliance TO fwo_ro; +ALTER DEFAULT PRIVILEGES IN SCHEMA compliance GRANT SELECT ON TABLES TO fwo_ro; +ALTER DEFAULT PRIVILEGES IN SCHEMA compliance GRANT USAGE, SELECT ON SEQUENCES TO fwo_ro; + +GRANT USAGE ON SCHEMA modelling TO fwo_ro; +GRANT SELECT ON ALL TABLES IN SCHEMA modelling TO fwo_ro; +GRANT USAGE, SELECT ON ALL SEQUENCES IN SCHEMA modelling TO fwo_ro; +ALTER DEFAULT PRIVILEGES IN SCHEMA modelling GRANT SELECT ON TABLES TO fwo_ro; +ALTER DEFAULT PRIVILEGES IN SCHEMA modelling GRANT USAGE, SELECT ON SEQUENCES TO fwo_ro; + +GRANT USAGE ON SCHEMA public TO fwo_ro; +GRANT SELECT ON ALL TABLES IN SCHEMA public TO fwo_ro; +GRANT USAGE, SELECT ON ALL SEQUENCES IN SCHEMA public TO fwo_ro; +ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT SELECT ON TABLES TO fwo_ro; +ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT USAGE, SELECT ON SEQUENCES TO fwo_ro; + +GRANT USAGE ON SCHEMA request TO fwo_ro; +GRANT SELECT ON ALL TABLES IN SCHEMA request TO fwo_ro; +GRANT USAGE, SELECT ON ALL SEQUENCES IN SCHEMA request TO fwo_ro; +ALTER DEFAULT PRIVILEGES IN SCHEMA request GRANT SELECT ON TABLES TO fwo_ro; +ALTER DEFAULT PRIVILEGES IN SCHEMA request GRANT USAGE, SELECT ON SEQUENCES TO fwo_ro; diff --git a/roles/database/files/upgrade/8.8.9.sql b/roles/database/files/upgrade/8.8.9.sql new file mode 100644 index 0000000000..95b7402a26 --- /dev/null +++ b/roles/database/files/upgrade/8.8.9.sql @@ -0,0 +1,109 @@ +create table if not exists owner_recertification +( + id BIGSERIAL PRIMARY KEY, + owner_id int NOT NULL, + user_dn varchar, + recertified boolean default false, + recert_date Timestamp, + comment varchar, + next_recert_date Timestamp +); + +create table if not exists notification +( + id SERIAL PRIMARY KEY, + notification_client Varchar, + user_id int, + owner_id int, + channel Varchar, + recipient_to Varchar, + email_address_to Varchar, + recipient_cc Varchar, + email_address_cc Varchar, + email_subject Varchar, + layout Varchar, + deadline Varchar, + interval_before_deadline int, + offset_before_deadline int, + repeat_interval_after_deadline int, + repeat_offset_after_deadline int, + repetitions_after_deadline int, + last_sent Timestamp +); + +alter table notification drop constraint if exists notification_owner_foreign_key; +ALTER TABLE notification ADD CONSTRAINT notification_owner_foreign_key FOREIGN KEY (owner_id) REFERENCES owner(id) ON UPDATE RESTRICT ON DELETE CASCADE; +alter table notification drop constraint if exists notification_user_foreign_key; +ALTER TABLE notification ADD CONSTRAINT notification_user_foreign_key FOREIGN KEY (user_id) REFERENCES uiuser(uiuser_id) ON UPDATE RESTRICT ON DELETE CASCADE; + +alter table owner add column if not exists last_recertified Timestamp; +alter table owner add column if not exists last_recertifier int; +alter table owner add column if not exists last_recertifier_dn Varchar; +alter table owner add column if not exists next_recert_date Timestamp; + +alter table owner drop constraint if exists owner_last_recertifier_uiuser_uiuser_id_f_key; +alter table owner add constraint owner_last_recertifier_uiuser_uiuser_id_f_key foreign key (last_recertifier) references uiuser (uiuser_id) on update restrict; + + +DO $$ +BEGIN + -- recertification.owner_recert_id → owner_recertification(id) + IF NOT EXISTS ( + SELECT 1 + FROM pg_constraint c + JOIN pg_class t ON t.oid = c.conrelid + JOIN pg_namespace n ON n.oid = t.relnamespace + WHERE c.conname = 'recertification_owner_recertification_foreign_key' + AND t.relname = 'recertification' + AND n.nspname = current_schema() + ) THEN + ALTER TABLE recertification + ADD CONSTRAINT recertification_owner_recertification_foreign_key + FOREIGN KEY (owner_recert_id) + REFERENCES owner_recertification(id) + ON UPDATE RESTRICT + ON DELETE CASCADE; + END IF; + + -- owner_recertification.owner_id → owner(id) + IF NOT EXISTS ( + SELECT 1 + FROM pg_constraint c + JOIN pg_class t ON t.oid = c.conrelid + JOIN pg_namespace n ON n.oid = t.relnamespace + WHERE c.conname = 'owner_recertification_owner_foreign_key' + AND t.relname = 'owner_recertification' + AND n.nspname = current_schema() + ) THEN + ALTER TABLE owner_recertification + ADD CONSTRAINT owner_recertification_owner_foreign_key + FOREIGN KEY (owner_id) + REFERENCES owner(id) + ON UPDATE RESTRICT + ON DELETE CASCADE; + END IF; + + -- owner_recertification.report_id → report(report_id) + IF NOT EXISTS ( + SELECT 1 + FROM pg_constraint c + JOIN pg_class t ON t.oid = c.conrelid + JOIN pg_namespace n ON n.oid = t.relnamespace + WHERE c.conname = 'owner_recertification_report_foreign_key' + AND t.relname = 'owner_recertification' + AND n.nspname = current_schema() + ) THEN + ALTER TABLE owner_recertification + ADD CONSTRAINT owner_recertification_report_foreign_key + FOREIGN KEY (report_id) + REFERENCES report(report_id) + ON UPDATE RESTRICT + ON DELETE CASCADE; + END IF; +END +$$; + + +insert into config (config_key, config_value, config_user) VALUES ('modDecommEmailReceiver', 'None', 0) ON CONFLICT DO NOTHING; +insert into config (config_key, config_value, config_user) VALUES ('modDecommEmailSubject', '', 0) ON CONFLICT DO NOTHING; +insert into config (config_key, config_value, config_user) VALUES ('modDecommEmailBody', '', 0) ON CONFLICT DO NOTHING; diff --git a/roles/database/files/upgrade/8.9.1.sql b/roles/database/files/upgrade/8.9.1.sql new file mode 100644 index 0000000000..614c54d9f0 --- /dev/null +++ b/roles/database/files/upgrade/8.9.1.sql @@ -0,0 +1,15 @@ +alter table report add column if not exists owner_id Integer; + +alter table report drop constraint if exists report_owner_foreign_key; +ALTER TABLE report ADD CONSTRAINT report_owner_foreign_key FOREIGN KEY (owner_id) REFERENCES owner(id) ON UPDATE RESTRICT ON DELETE CASCADE; + +alter table owner_recertification add column if not exists report_id bigint; +alter table owner_recertification drop constraint if exists owner_recertification_report_foreign_key; +ALTER TABLE owner_recertification ADD CONSTRAINT owner_recertification_report_foreign_key FOREIGN KEY (report_id) REFERENCES report(report_id) ON UPDATE RESTRICT ON DELETE CASCADE; + +alter table owner add column if not exists recert_active boolean default false; + +alter table recertification add column if not exists owner_recert_id bigint; + +alter table recertification drop constraint if exists recertification_owner_recertification_foreign_key; +ALTER TABLE recertification ADD CONSTRAINT recertification_owner_recertification_foreign_key FOREIGN KEY (owner_recert_id) REFERENCES owner_recertification(id) ON UPDATE RESTRICT ON DELETE CASCADE; diff --git a/roles/database/files/upgrade/8.9.2.sql b/roles/database/files/upgrade/8.9.2.sql new file mode 100644 index 0000000000..388edcc983 --- /dev/null +++ b/roles/database/files/upgrade/8.9.2.sql @@ -0,0 +1,9 @@ +CREATE TABLE if not exists owner_lifecycle_state ( + id SERIAL PRIMARY KEY, + name Varchar NOT NULL +); + +alter table owner add column if not exists owner_lifecycle_state_id int; + +alter table owner drop constraint if exists owner_owner_lifecycle_state_foreign_key; +ALTER TABLE owner ADD CONSTRAINT owner_owner_lifecycle_state_foreign_key FOREIGN KEY (owner_lifecycle_state_id)REFERENCES owner_lifecycle_state(id) ON DELETE SET NULL; \ No newline at end of file diff --git a/roles/database/files/upgrade/8.9.6.sql b/roles/database/files/upgrade/8.9.6.sql new file mode 100644 index 0000000000..5be58869e9 --- /dev/null +++ b/roles/database/files/upgrade/8.9.6.sql @@ -0,0 +1,2 @@ +alter table notification add column if not exists initial_offset_after_deadline int; +alter table notification add column if not exists name Varchar; diff --git a/roles/database/files/upgrade/9.0.1.sql b/roles/database/files/upgrade/9.0.1.sql new file mode 100644 index 0000000000..86e80fa7ec --- /dev/null +++ b/roles/database/files/upgrade/9.0.1.sql @@ -0,0 +1,58 @@ +-- add owner_responsible_type lookup table +CREATE TABLE IF NOT EXISTS owner_responsible_type +( + id SERIAL PRIMARY KEY, + name Varchar NOT NULL, + active boolean default true, + sort_order int default 0, + allow_modelling boolean NOT NULL DEFAULT false, + allow_recertification boolean NOT NULL DEFAULT false +); + +INSERT INTO owner_responsible_type (id, name, active, sort_order) +VALUES + (1, 'Main responsible', true, 10), + (2, 'Supporting responsible', true, 20), + (3, 'Optional escalation responsible', true, 30) +ON CONFLICT DO NOTHING; + +CREATE UNIQUE INDEX IF NOT EXISTS owner_responsible_type_name_unique ON owner_responsible_type(name); + +UPDATE owner_responsible_type +SET allow_modelling = true, + allow_recertification = true +WHERE id IN (1, 2); + +DO $$ +DECLARE + seq_name text; + max_id bigint; +BEGIN + seq_name := pg_get_serial_sequence('owner_responsible_type', 'id'); + IF seq_name IS NOT NULL THEN + SELECT COALESCE(MAX(id), 0) INTO max_id FROM owner_responsible_type; + PERFORM setval(seq_name, max_id, true); + END IF; +END +$$; + +DO $$ +BEGIN + IF NOT EXISTS ( + SELECT 1 + FROM pg_constraint c + JOIN pg_class t ON t.oid = c.conrelid + JOIN pg_namespace n ON n.oid = t.relnamespace + WHERE c.conname = 'owner_responsible_type_foreign_key' + AND t.relname = 'owner_responsible' + AND n.nspname = current_schema() + ) THEN + ALTER TABLE owner_responsible + ADD CONSTRAINT owner_responsible_type_foreign_key + FOREIGN KEY (responsible_type) + REFERENCES owner_responsible_type(id) + ON UPDATE RESTRICT + ON DELETE RESTRICT; + END IF; +END +$$; \ No newline at end of file diff --git a/roles/database/files/upgrade/9.0.10.sql b/roles/database/files/upgrade/9.0.10.sql new file mode 100644 index 0000000000..a875d9aa57 --- /dev/null +++ b/roles/database/files/upgrade/9.0.10.sql @@ -0,0 +1 @@ +insert into config (config_key, config_value, config_user) VALUES ('ownerDataImportSyncUsers', 'true', 0) ON CONFLICT DO NOTHING; diff --git a/roles/database/files/upgrade/9.0.11.sql b/roles/database/files/upgrade/9.0.11.sql new file mode 100644 index 0000000000..0bcbfffac1 --- /dev/null +++ b/roles/database/files/upgrade/9.0.11.sql @@ -0,0 +1 @@ +insert into config (config_key, config_value, config_user) VALUES ('modRequestOnlyOwnObjects', 'false', 0) ON CONFLICT DO NOTHING; diff --git a/roles/database/files/upgrade/9.0.12.sql b/roles/database/files/upgrade/9.0.12.sql new file mode 100644 index 0000000000..16cf3bf3e4 --- /dev/null +++ b/roles/database/files/upgrade/9.0.12.sql @@ -0,0 +1,2 @@ +insert into config (config_key, config_value, config_user) VALUES ('ruleExpiryEmailBody', '', 0) ON CONFLICT DO NOTHING; +insert into config (config_key, config_value, config_user) VALUES ('ruleExpiryInitiatorKeys', '{}', 0) ON CONFLICT DO NOTHING; diff --git a/roles/database/files/upgrade/9.0.13.sql b/roles/database/files/upgrade/9.0.13.sql new file mode 100644 index 0000000000..5efe9b9bfb --- /dev/null +++ b/roles/database/files/upgrade/9.0.13.sql @@ -0,0 +1,2 @@ +alter table if exists owner_lifecycle_state + add column if not exists active_state boolean not null default true; diff --git a/roles/database/files/upgrade/9.0.14.sql b/roles/database/files/upgrade/9.0.14.sql new file mode 100644 index 0000000000..63c02c2a8c --- /dev/null +++ b/roles/database/files/upgrade/9.0.14.sql @@ -0,0 +1,3 @@ +insert into config (config_key, config_value, config_user) VALUES ('ownerActiveRuleEmailBody', '', 0) ON CONFLICT DO NOTHING; +insert into config (config_key, config_value, config_user) VALUES ('dailyCheckModules', '[1,2,3,4,5,6,7]', 0) ON CONFLICT DO NOTHING; +ALTER TABLE owner ADD COLUMN IF NOT EXISTS decomm_date Timestamp; diff --git a/roles/database/files/upgrade/9.0.15.sql b/roles/database/files/upgrade/9.0.15.sql new file mode 100644 index 0000000000..2f8bcc1b3c --- /dev/null +++ b/roles/database/files/upgrade/9.0.15.sql @@ -0,0 +1,28 @@ +UPDATE config +SET config_key = 'CustomFieldOwnerKey' +WHERE config_key = 'OwnerSourceCustomFieldKey'; + +-- Fix inconsistent mgm_id in changelog tables +UPDATE changelog_rule AS c +SET mgm_id = r.mgm_id +FROM rule AS r +WHERE COALESCE(c.new_rule_id, c.old_rule_id) = r.rule_id + AND c.mgm_id <> r.mgm_id; + +UPDATE changelog_object AS c +SET mgm_id = o.mgm_id +FROM object AS o +WHERE COALESCE(c.new_obj_id, c.old_obj_id) = o.obj_id + AND c.mgm_id <> o.mgm_id; + +UPDATE changelog_service AS c +SET mgm_id = s.mgm_id +FROM service AS s +WHERE COALESCE(c.new_svc_id, c.old_svc_id) = s.svc_id + AND c.mgm_id <> s.mgm_id; + +UPDATE changelog_user AS c +SET mgm_id = u.mgm_id +FROM usr AS u +WHERE COALESCE(c.new_user_id, c.old_user_id) = u.user_id + AND c.mgm_id <> u.mgm_id; diff --git a/roles/database/files/upgrade/9.0.16.sql b/roles/database/files/upgrade/9.0.16.sql new file mode 100644 index 0000000000..889860f863 --- /dev/null +++ b/roles/database/files/upgrade/9.0.16.sql @@ -0,0 +1,16 @@ +--remove stm_owner_mapping_source + +ALTER TABLE rule_owner +DROP CONSTRAINT IF EXISTS rule_owner_owner_mapping_source_id_stm_owner_mapping_source_for; + +DROP TABLE IF EXISTS stm_owner_mapping_source; + +-- add column to rule_owner +ALTER TABLE rule_owner +ADD COLUMN IF NOT EXISTS matched_objects jsonb; + +ALTER TABLE rule_owner +DROP CONSTRAINT IF EXISTS rule_owner_matched_objects_for_ip_based; + +ALTER TABLE rule_owner ADD CONSTRAINT rule_owner_matched_objects_for_ip_based +CHECK ( owner_mapping_source_id != 1 OR matched_objects IS NOT NULL ); \ No newline at end of file diff --git a/roles/database/files/upgrade/9.0.18.sql b/roles/database/files/upgrade/9.0.18.sql new file mode 100644 index 0000000000..94f293c4fe --- /dev/null +++ b/roles/database/files/upgrade/9.0.18.sql @@ -0,0 +1,2 @@ +ALTER TABLE IF EXISTS request.state + ADD COLUMN IF NOT EXISTS automatic_only BOOLEAN NOT NULL DEFAULT FALSE; diff --git a/roles/database/files/upgrade/9.0.19.sql b/roles/database/files/upgrade/9.0.19.sql new file mode 100644 index 0000000000..2298fe0859 --- /dev/null +++ b/roles/database/files/upgrade/9.0.19.sql @@ -0,0 +1,2 @@ +ALTER TABLE IF EXISTS public.owner + ADD COLUMN IF NOT EXISTS additional_info JSONB; diff --git a/roles/database/files/upgrade/9.0.20.sql b/roles/database/files/upgrade/9.0.20.sql new file mode 100644 index 0000000000..c37a58dc7a --- /dev/null +++ b/roles/database/files/upgrade/9.0.20.sql @@ -0,0 +1,9 @@ +alter table notification add column if not exists email_body Varchar; +alter table notification add column if not exists schedule_id Integer; +alter table notification add column if not exists bundle_type Varchar; +alter table notification add column if not exists bundle_id Varchar; +alter table report_schedule add column if not exists archive Boolean NOT NULL Default FALSE; + +alter table notification drop constraint if exists notification_report_schedule_foreign_key; +alter table notification add constraint notification_report_schedule_foreign_key + foreign key (schedule_id) references report_schedule(report_schedule_id) on update restrict on delete cascade; diff --git a/roles/database/files/upgrade/9.0.3.sql b/roles/database/files/upgrade/9.0.3.sql new file mode 100644 index 0000000000..f7bee54bea --- /dev/null +++ b/roles/database/files/upgrade/9.0.3.sql @@ -0,0 +1,16 @@ +CREATE TABLE IF NOT EXISTS modelling.permitted_owners +( + connection_id int, + app_id int, + primary key (connection_id, app_id) +); + +ALTER TABLE modelling.permitted_owners DROP CONSTRAINT IF EXISTS modelling_permitted_owners_connection_foreign_key; +ALTER TABLE modelling.permitted_owners ADD CONSTRAINT modelling_permitted_owners_connection_foreign_key + FOREIGN KEY (connection_id) REFERENCES modelling.connection(id) ON UPDATE RESTRICT ON DELETE CASCADE; + +ALTER TABLE modelling.permitted_owners DROP CONSTRAINT IF EXISTS modelling_permitted_owners_owner_foreign_key; +ALTER TABLE modelling.permitted_owners ADD CONSTRAINT modelling_permitted_owners_owner_foreign_key + FOREIGN KEY (app_id) REFERENCES owner(id) ON UPDATE RESTRICT ON DELETE CASCADE; + +ALTER TABLE modelling.connection ADD COLUMN IF NOT EXISTS interface_permission Varchar; diff --git a/roles/database/files/upgrade/9.0.4.sql b/roles/database/files/upgrade/9.0.4.sql new file mode 100644 index 0000000000..1701b57097 --- /dev/null +++ b/roles/database/files/upgrade/9.0.4.sql @@ -0,0 +1,37 @@ +-- 9.0.4 +-- migrate modelling mail recipients to multi-select JSON representation +INSERT INTO config (config_key, config_value, config_user) VALUES ('modReqEmailOtherAddresses', '', 0) ON CONFLICT DO NOTHING; +INSERT INTO config (config_key, config_value, config_user) VALUES ('modDecommEmailOtherAddresses', '', 0) ON CONFLICT DO NOTHING; + +UPDATE config +SET config_value = '{"none":false,"other_addresses":false,"owner_responsible_type_ids":[2]}' +WHERE config_key IN ('modReqEmailReceiver', 'modDecommEmailReceiver') + AND config_value = 'OwnerGroupOnly'; + +UPDATE config +SET config_value = '{"none":false,"other_addresses":false,"owner_responsible_type_ids":[1]}' +WHERE config_key IN ('modReqEmailReceiver', 'modDecommEmailReceiver') + AND config_value = 'OwnerMainResponsible'; + +UPDATE config +SET config_value = '{"none":false,"other_addresses":false,"ensure_at_least_one_notification":true,"owner_responsible_type_ids":[2,1]}' +WHERE config_key IN ('modReqEmailReceiver', 'modDecommEmailReceiver') + AND config_value = 'FallbackToMainResponsibleIfOwnerGroupEmpty'; + +UPDATE config +SET config_value = '{"none":false,"other_addresses":true,"owner_responsible_type_ids":[]}' +WHERE config_key IN ('modReqEmailReceiver', 'modDecommEmailReceiver') + AND config_value = 'OtherAddresses'; + +UPDATE config +SET config_value = ( + SELECT json_build_object( + 'none', false, + 'other_addresses', false, + 'owner_responsible_type_ids', COALESCE(json_agg(id ORDER BY sort_order DESC), '[]'::json) + )::text + FROM owner_responsible_type + WHERE active = true +) +WHERE config_key IN ('modReqEmailReceiver', 'modDecommEmailReceiver') + AND config_value = 'AllOwnerResponsibles'; diff --git a/roles/database/files/upgrade/9.0.5.sql b/roles/database/files/upgrade/9.0.5.sql new file mode 100644 index 0000000000..ea7584a34e --- /dev/null +++ b/roles/database/files/upgrade/9.0.5.sql @@ -0,0 +1,286 @@ +-- rule_owner table +ALTER TABLE rule_owner +ADD COLUMN IF NOT EXISTS rule_id bigint, +ADD COLUMN IF NOT EXISTS created bigint, +ADD COLUMN IF NOT EXISTS removed bigint, +ADD COLUMN IF NOT EXISTS owner_mapping_source_id smallint; -- stm_ for source (ip_based, custom_field, name_field, manual) todo + +-- backfill new columns for existing rows +DO $$ +DECLARE + latest_import_id bigint; +BEGIN + SELECT MAX(control_id) INTO latest_import_id FROM import_control; + + IF EXISTS ( + SELECT 1 FROM information_schema.columns + WHERE table_name = 'rule_owner' + AND column_name = 'rule_id' + ) THEN + UPDATE rule_owner ro + SET rule_id = r.rule_id + FROM rule_metadata met + JOIN rule r ON r.rule_uid = met.rule_uid AND r.mgm_id = met.mgm_id + WHERE ro.rule_metadata_id = met.rule_metadata_id + AND ro.rule_id IS NULL; + END IF; + + IF latest_import_id IS NOT NULL THEN + UPDATE rule_owner + SET created = latest_import_id + WHERE created IS NULL; + END IF; + + UPDATE rule_owner + SET owner_mapping_source_id = 4 + WHERE owner_mapping_source_id IS NULL; +END $$; + + +-- set not null if not done +DO $$ +BEGIN + IF EXISTS ( + SELECT 1 FROM information_schema.columns + WHERE table_name = 'rule_owner' + AND column_name = 'rule_id' + AND is_nullable = 'YES' + ) THEN + ALTER TABLE rule_owner ALTER COLUMN rule_id SET NOT NULL; + END IF; + + IF EXISTS ( + SELECT 1 FROM information_schema.columns + WHERE table_name = 'rule_owner' + AND column_name = 'created' + AND is_nullable = 'YES' + ) THEN + ALTER TABLE rule_owner ALTER COLUMN created SET NOT NULL; + END IF; + + IF EXISTS ( + SELECT 1 FROM information_schema.columns + WHERE table_name = 'rule_owner' + AND column_name = 'owner_id' + AND is_nullable = 'YES' + ) THEN + ALTER TABLE rule_owner ALTER COLUMN owner_id SET NOT NULL; + END IF; + + IF EXISTS ( + SELECT 1 FROM information_schema.columns + WHERE table_name = 'rule_owner' + AND column_name = 'owner_mapping_source_id' + AND is_nullable = 'YES' + ) THEN + ALTER TABLE rule_owner ALTER COLUMN owner_mapping_source_id SET NOT NULL; + END IF; +END $$; + +-- set primary key +DO $$ +BEGIN + DELETE FROM rule_owner ro + USING ( + SELECT rule_id, owner_id, created, MIN(ctid) AS keep_ctid + FROM rule_owner + GROUP BY rule_id, owner_id, created + HAVING COUNT(*) > 1 + ) dups + WHERE ro.rule_id = dups.rule_id + AND ro.owner_id = dups.owner_id + AND ro.created = dups.created + AND ro.ctid <> dups.keep_ctid; + + IF NOT EXISTS ( + SELECT 1 + FROM information_schema.table_constraints + WHERE table_name = 'rule_owner' + AND constraint_type = 'PRIMARY KEY' + ) AND NOT EXISTS ( + SELECT 1 FROM rule_owner + WHERE rule_id IS NULL OR owner_id IS NULL OR created IS NULL + ) THEN + ALTER TABLE rule_owner + ADD CONSTRAINT pk_rule_owner + PRIMARY KEY (rule_id, owner_id, created); + END IF; +END $$; + +-- owner source table +CREATE TABLE if not EXISTS stm_owner_mapping_source +( + "owner_mapping_source_type_id" BIGINT PRIMARY KEY, + "owner_mapping_source_type_name" Varchar NOT NULL +); +-- add owner source +INSERT INTO stm_owner_mapping_source (owner_mapping_source_type_id, owner_mapping_source_type_name) +VALUES + (1, 'ip_based'), + (2, 'custom_field'), + (3, 'name_field'), + (4, 'manual') +ON CONFLICT (owner_mapping_source_type_id) DO NOTHING; + +-- just one "active" (rule_id, owner_id) + performance +CREATE UNIQUE INDEX IF NOT EXISTS idx_rule_owner_removed_is_null_unique ON rule_owner (rule_id, owner_id) WHERE removed IS NULL; + +-- create fks +ALTER TABLE rule_owner DROP CONSTRAINT IF EXISTS rule_owner_rule_foreign_key; +ALTER TABLE rule_owner ADD CONSTRAINT rule_owner_rule_foreign_key FOREIGN KEY (rule_id) REFERENCES rule(rule_id) ON UPDATE RESTRICT ON DELETE CASCADE; + +ALTER TABLE rule_owner DROP CONSTRAINT IF EXISTS rule_owner_created_import_control_foreign_key; +ALTER TABLE rule_owner ADD CONSTRAINT rule_owner_created_import_control_foreign_key FOREIGN KEY (created) REFERENCES import_control(control_id) ON UPDATE RESTRICT ON DELETE CASCADE; + +ALTER TABLE rule_owner DROP CONSTRAINT IF EXISTS rule_owner_removed_import_control_foreign_key; +ALTER TABLE rule_owner ADD CONSTRAINT rule_owner_removed_import_control_foreign_key FOREIGN KEY (removed) REFERENCES import_control(control_id) ON UPDATE RESTRICT ON DELETE CASCADE; + +ALTER TABLE rule_owner DROP CONSTRAINT IF EXISTS rule_owner_owner_mapping_source_id_stm_owner_mapping_source_foreign_key; +ALTER TABLE rule_owner ADD CONSTRAINT rule_owner_owner_mapping_source_id_stm_owner_mapping_source_foreign_key FOREIGN KEY (owner_mapping_source_id) +REFERENCES stm_owner_mapping_source(owner_mapping_source_type_id) ON UPDATE RESTRICT ON DELETE CASCADE; + +-- shrink owner_mapping_source_id to smallint if it was created as bigint +DO $$ +BEGIN + IF EXISTS ( + SELECT 1 FROM information_schema.columns + WHERE table_name = 'rule_owner' + AND column_name = 'owner_mapping_source_id' + AND data_type = 'bigint' + ) THEN + ALTER TABLE rule_owner + ALTER COLUMN owner_mapping_source_id TYPE smallint + USING owner_mapping_source_id::smallint; + END IF; +END $$; + + +-- import_control +-- alter import_control delete unused/exported columns +-- owner source table +CREATE TABLE if not EXISTS stm_import +( + "import_type_id" Integer PRIMARY KEY, + "import_type_name" Varchar NOT NULL +); + +INSERT INTO stm_import (import_type_id, import_type_name) +VALUES + (1, 'rule'), + (2, 'owner'), + (3, 'admin via reinitialize button') +ON CONFLICT (import_type_id) DO NOTHING; + +-- Set all imports to rule import - if import_type_id null +DO $$ +BEGIN + IF NOT EXISTS ( + SELECT 1 + FROM information_schema.columns + WHERE table_name='import_control' + AND column_name='import_type_id' + ) THEN + ALTER TABLE import_control + ADD COLUMN import_type_id INTEGER; + + UPDATE import_control + SET import_type_id = 1 + WHERE import_type_id IS NULL; + + ALTER TABLE import_control + ALTER COLUMN import_type_id SET NOT NULL; + END IF; +END +$$; + +-- change name of fields +DO $$ +BEGIN + IF EXISTS ( + SELECT 1 + FROM information_schema.columns + WHERE table_name='import_control' + AND column_name='rule_changes_found' + ) THEN + ALTER TABLE import_control RENAME COLUMN rule_changes_found TO changes_found; + END IF; + + IF EXISTS ( + SELECT 1 + FROM information_schema.columns + WHERE table_name='import_control' + AND column_name='any_changes_found' + ) THEN + ALTER TABLE import_control RENAME COLUMN any_changes_found TO policy_changes_found; + END IF; + + IF NOT EXISTS ( + SELECT 1 + FROM information_schema.columns + WHERE table_name = 'import_control' + AND column_name = 'rule_owner_mapping_done' + ) THEN + ALTER TABLE import_control + ADD COLUMN rule_owner_mapping_done BOOLEAN NOT NULL DEFAULT FALSE; + END IF; +END$$; + +-- mgm_id now nullable +DO $$ +BEGIN + IF EXISTS ( + SELECT 1 + FROM information_schema.columns + WHERE table_name = 'import_control' + AND column_name = 'mgm_id' + AND is_nullable = 'NO' + ) THEN + ALTER TABLE import_control + ALTER COLUMN mgm_id DROP NOT NULL; + END IF; +END +$$; + +-- constraint mgm_id not null, if import_type_id = 1 +DO $$ +BEGIN + IF NOT EXISTS ( + SELECT 1 + FROM pg_constraint + WHERE conname = 'import_control_mgm_id_required_for_import_type_1' + ) THEN + ALTER TABLE import_control + ADD CONSTRAINT import_control_mgm_id_required_for_import_type_1 + CHECK ( + import_type_id <> 1 + OR mgm_id IS NOT NULL + ); + END IF; +END +$$; + +-- runs without problems in pgadmin - drops "old / unused" fields +DO $$ +DECLARE + col RECORD; +BEGIN + FOR col IN + SELECT column_name + FROM information_schema.columns + WHERE table_name = 'import_control' + AND column_name IN ( + 'delimiter_group', + 'delimiter_zone', + 'delimiter_user', + 'delimiter_list', + 'last_change_in_config', + 'is_full_import' + ) + LOOP + EXECUTE format( + 'ALTER TABLE import_control DROP COLUMN IF EXISTS %I', + col.column_name + ); + END LOOP; +END +$$; \ No newline at end of file diff --git a/roles/database/files/upgrade/9.0.6.sql b/roles/database/files/upgrade/9.0.6.sql new file mode 100644 index 0000000000..74a067d750 --- /dev/null +++ b/roles/database/files/upgrade/9.0.6.sql @@ -0,0 +1,38 @@ +create table if not EXISTS time_object +( + time_obj_id BIGSERIAL PRIMARY KEY, + mgm_id Integer NOT NULL, + time_obj_uid Varchar, + time_obj_name Varchar, + start_time TIMESTAMP WITH TIME ZONE, + end_time TIMESTAMP WITH TIME ZONE, + created BIGINT, + removed BIGINT +); + +create table if not EXISTS rule_time +( + rule_time_id BIGSERIAL PRIMARY KEY, + rule_id BIGINT, + time_obj_id BIGINT, + created BIGINT, + removed BIGINT +); + + +-- create fks +ALTER TABLE time_object DROP CONSTRAINT IF EXISTS time_object_mgm_id_fkey; +ALTER TABLE time_object ADD CONSTRAINT time_object_mgm_id_fkey FOREIGN KEY (mgm_id) REFERENCES management (mgm_id) ON UPDATE RESTRICT ON DELETE CASCADE; +ALTER TABLE time_object DROP CONSTRAINT IF EXISTS time_object_created_fkey; +ALTER TABLE time_object ADD CONSTRAINT time_object_created_fkey FOREIGN KEY (created) REFERENCES import_control (control_id) ON UPDATE RESTRICT ON DELETE CASCADE; +ALTER TABLE time_object DROP CONSTRAINT IF EXISTS time_object_removed_fkey; +ALTER TABLE time_object ADD CONSTRAINT time_object_removed_fkey FOREIGN KEY (removed) REFERENCES import_control (control_id) ON UPDATE RESTRICT ON DELETE CASCADE; + +ALTER TABLE rule_time DROP CONSTRAINT IF EXISTS rule_time_rule_id_fkey; +ALTER TABLE rule_time ADD CONSTRAINT rule_time_rule_id_fkey FOREIGN KEY (rule_id) REFERENCES rule (rule_id) ON UPDATE RESTRICT ON DELETE CASCADE; +ALTER TABLE rule_time DROP CONSTRAINT IF EXISTS rule_time_time_obj_id_fkey; +ALTER TABLE rule_time ADD CONSTRAINT rule_time_time_obj_id_fkey FOREIGN KEY (time_obj_id) REFERENCES time_object (time_obj_id) ON UPDATE RESTRICT ON DELETE CASCADE; +ALTER TABLE rule_time DROP CONSTRAINT IF EXISTS rule_time_created_fkey; +ALTER TABLE rule_time ADD CONSTRAINT rule_time_created_fkey FOREIGN KEY (created) REFERENCES import_control (control_id) ON UPDATE RESTRICT ON DELETE CASCADE; +ALTER TABLE rule_time DROP CONSTRAINT IF EXISTS rule_time_removed_fkey; +ALTER TABLE rule_time ADD CONSTRAINT rule_time_removed_fkey FOREIGN KEY (removed) REFERENCES import_control (control_id) ON UPDATE RESTRICT ON DELETE CASCADE; diff --git a/roles/database/files/upgrade/9.0.7.sql b/roles/database/files/upgrade/9.0.7.sql new file mode 100644 index 0000000000..b9dc230435 --- /dev/null +++ b/roles/database/files/upgrade/9.0.7.sql @@ -0,0 +1,80 @@ +-- create changelog_owner +DO $$ +BEGIN + IF NOT EXISTS ( + SELECT 1 + FROM information_schema.tables + WHERE table_schema = 'public' + AND table_name = 'changelog_owner' + ) THEN + CREATE TABLE "changelog_owner" + ( + "log_owner_id" BIGSERIAL, + "control_id" BIGINT NOT NULL, + "new_owner_id" BIGINT + CONSTRAINT "changelog_owner_new_rule_id_constraint" + CHECK ((change_action='D' AND new_owner_id IS NULL) OR NOT new_owner_id IS NULL), + "old_owner_id" BIGINT + CONSTRAINT "changelog_owner_old_rule_id_constraint" + CHECK ((change_action='I' AND old_owner_id IS NULL) OR NOT old_owner_id IS NULL), + "abs_change_id" BIGINT NOT NULL + DEFAULT nextval('public.abs_change_id_seq'::text) + UNIQUE, + "change_action" CHAR(1) NOT NULL, + "source_id" VARCHAR, + "security_relevant" BOOLEAN NOT NULL DEFAULT TRUE, + PRIMARY KEY ("log_owner_id") + ); + END IF; +END $$; + +-- control_id +DO $$ +BEGIN + IF NOT EXISTS ( + SELECT 1 + FROM pg_constraint + WHERE conname = 'changelog_owner_control_id_import_control_foreign_key' + ) THEN + ALTER TABLE "changelog_owner" + ADD CONSTRAINT changelog_owner_control_id_import_control_foreign_key + FOREIGN KEY ("control_id") + REFERENCES "import_control" ("control_id") + ON UPDATE RESTRICT + ON DELETE CASCADE; + END IF; +END $$; + +-- new_owner_id +DO $$ +BEGIN + IF NOT EXISTS ( + SELECT 1 + FROM pg_constraint + WHERE conname = 'changelog_owner_new_owner_id_owner_id_foreign_key' + ) THEN + ALTER TABLE "changelog_owner" + ADD CONSTRAINT changelog_owner_new_owner_id_owner_id_foreign_key + FOREIGN KEY ("new_owner_id") + REFERENCES "owner" ("id") + ON UPDATE RESTRICT + ON DELETE CASCADE; + END IF; +END $$; + +-- old_owner_id +DO $$ +BEGIN + IF NOT EXISTS ( + SELECT 1 + FROM pg_constraint + WHERE conname = 'changelog_owner_old_owner_id_owner_id_foreign_key' + ) THEN + ALTER TABLE "changelog_owner" + ADD CONSTRAINT changelog_owner_old_owner_id_owner_id_foreign_key + FOREIGN KEY ("old_owner_id") + REFERENCES "owner" ("id") + ON UPDATE RESTRICT + ON DELETE CASCADE; + END IF; +END $$; \ No newline at end of file diff --git a/roles/database/files/upgrade/9.0.8.sql b/roles/database/files/upgrade/9.0.8.sql new file mode 100644 index 0000000000..e5d8dbf8a4 --- /dev/null +++ b/roles/database/files/upgrade/9.0.8.sql @@ -0,0 +1,23 @@ +insert into config (config_key, config_value, config_user) VALUES ('modRolloutRemovedAppServers', 'false', 0) ON CONFLICT DO NOTHING; + +-- import_control -> stm_import FK for hasura relations +DO $$ +BEGIN + IF NOT EXISTS ( + SELECT 1 + FROM information_schema.table_constraints tc + JOIN information_schema.key_column_usage kcu + ON tc.constraint_name = kcu.constraint_name + AND tc.table_schema = kcu.table_schema + WHERE tc.table_name = 'import_control' + AND tc.constraint_type = 'FOREIGN KEY' + AND kcu.column_name = 'import_type_id' + ) THEN + ALTER TABLE import_control + ADD CONSTRAINT import_control_import_type_id_stm_import_foreign_key + FOREIGN KEY (import_type_id) + REFERENCES stm_import(import_type_id) + ON UPDATE RESTRICT ON DELETE RESTRICT; + END IF; +END +$$; diff --git a/roles/database/files/upgrade/9.0.9.sql b/roles/database/files/upgrade/9.0.9.sql new file mode 100644 index 0000000000..d6d60d72fc --- /dev/null +++ b/roles/database/files/upgrade/9.0.9.sql @@ -0,0 +1,126 @@ +-- cleanup objects removed in branch clean/remove-stale-v8-code vs develop + +-- remove explicit table grants that existed for legacy import staging tables +DO $$ +DECLARE + target_table TEXT; +BEGIN + IF EXISTS (SELECT 1 FROM pg_roles WHERE rolname = 'configimporters') THEN + FOREACH target_table IN ARRAY ARRAY[ + 'import_service', + 'import_object', + 'import_user', + 'import_rule', + 'import_zone' + ] + LOOP + IF to_regclass('public.' || target_table) IS NOT NULL THEN + EXECUTE format( + 'REVOKE ALL ON TABLE public.%I FROM %I;', + target_table, + 'configimporters' + ); + END IF; + END LOOP; + END IF; +END +$$; + +-- remove foreign keys for removed import staging tables +ALTER TABLE IF EXISTS import_object DROP CONSTRAINT IF EXISTS import_object_control_id_fkey; +ALTER TABLE IF EXISTS import_rule DROP CONSTRAINT IF EXISTS import_rule_control_id_fkey; +ALTER TABLE IF EXISTS import_service DROP CONSTRAINT IF EXISTS import_service_control_id_fkey; +ALTER TABLE IF EXISTS import_user DROP CONSTRAINT IF EXISTS import_user_control_id_fkey; +ALTER TABLE IF EXISTS import_zone DROP CONSTRAINT IF EXISTS import_zone_control_id_fkey; + +-- remove explicit indexes for removed import staging tables +DROP INDEX IF EXISTS idx_import_object01; +DROP INDEX IF EXISTS idx_import_object02; +DROP INDEX IF EXISTS idx_import_rule01; +DROP INDEX IF EXISTS "IX_Relationship59"; +DROP INDEX IF EXISTS "IX_Relationship61"; +DROP INDEX IF EXISTS "IX_Relationship62"; +DROP INDEX IF EXISTS "IX_Relationship132"; + +-- remove legacy import staging tables +DROP TABLE IF EXISTS import_service; +DROP TABLE IF EXISTS import_object; +DROP TABLE IF EXISTS import_user; +DROP TABLE IF EXISTS import_rule; +DROP TABLE IF EXISTS import_zone; + +-- remove routines of the legacy SQL-based import pipeline +DO $$ +DECLARE + current_routine RECORD; +BEGIN + FOR current_routine IN + SELECT + proc_namespace.nspname AS schema_name, + proc_definition.proname AS routine_name, + pg_get_function_identity_arguments(proc_definition.oid) AS routine_arguments, + proc_definition.prokind AS routine_kind + FROM pg_proc proc_definition + JOIN pg_namespace proc_namespace + ON proc_namespace.oid = proc_definition.pronamespace + WHERE proc_namespace.nspname = 'public' + AND proc_definition.proname = ANY (ARRAY[ + 'import_all_main', + 'debug_show_time', + 'import_global_refhandler_main', + 'import_changelog_sync', + 'undocumented_rule_changes_exist', + 'undocumented_svc_changes_exist', + 'undocumented_usr_changes_exist', + 'undocumented_obj_changes_exist', + 'undocumented_changes_exist', + 'is_import_running', + 'get_previous_import_id_for_mgmt', + 'get_last_import_id_for_mgmt', + 'get_previous_import_id', + 'get_import_id_for_dev_at_time', + 'get_import_id_for_mgmt_at_time', + 'rollback_current_import', + 'rollback_import_of_mgm', + 'remove_import_lock', + 'show_change_summary', + 'found_changes_in_import', + 'clean_up_tables', + 'import_networking_main', + 'import_zone_main', + 'import_zone_single', + 'import_zone_mark_deleted', + 'import_nwobj_main', + 'import_nwobj_mark_deleted', + 'import_nwobj_single', + 'get_first_ip_of_cidr', + 'get_last_ip_of_cidr', + 'import_rules', + 'import_rules_xlate', + 'import_rules_access', + 'import_rules_combined', + 'import_rules_set_rule_num_numeric', + 'security_relevant_change', + 'non_security_relevant_change', + 'insert_single_rule', + 'import_svc_main', + 'import_svc_mark_deleted', + 'import_svc_single', + 'import_usr_main', + 'import_usr_mark_deleted', + 'import_usr_single' + ]) + LOOP + EXECUTE format( + 'DROP %s IF EXISTS %I.%I(%s);', + CASE + WHEN current_routine.routine_kind = 'p' THEN 'PROCEDURE' + ELSE 'FUNCTION' + END, + current_routine.schema_name, + current_routine.routine_name, + current_routine.routine_arguments + ); + END LOOP; +END +$$; diff --git a/roles/database/files/upgrade/9.0.sql b/roles/database/files/upgrade/9.0.sql new file mode 100644 index 0000000000..d3d165a8f6 --- /dev/null +++ b/roles/database/files/upgrade/9.0.sql @@ -0,0 +1,2105 @@ +-- pre 9.0 upgrade scripts + +--- 8.6.3 + +insert into config (config_key, config_value, config_user) VALUES ('dnsLookup', 'False', 0) ON CONFLICT DO NOTHING; +insert into config (config_key, config_value, config_user) VALUES ('overwriteExistingNames', 'False', 0) ON CONFLICT DO NOTHING; +insert into config (config_key, config_value, config_user) VALUES ('autoReplaceAppServer', 'False', 0) ON CONFLICT DO NOTHING; + +ALTER TABLE modelling.change_history ADD COLUMN IF NOT EXISTS change_source Varchar default 'manual'; + + +CREATE TABLE IF NOT EXISTS refresh_log ( + id SERIAL PRIMARY KEY, + view_name TEXT NOT NULL, + refreshed_at TIMESTAMPTZ DEFAULT now(), + status TEXT +); + +CREATE OR REPLACE FUNCTION refresh_view_rule_with_owner() +RETURNS SETOF refresh_log AS $$ +DECLARE + status_message TEXT; +BEGIN + -- Attempt to refresh the materialized view + BEGIN + REFRESH MATERIALIZED VIEW view_rule_with_owner; + status_message := 'Materialized view refreshed successfully'; + EXCEPTION + WHEN OTHERS THEN + status_message := format('Failed to refresh view: %s', SQLERRM); + END; + + -- Log the operation + INSERT INTO refresh_log (view_name, status) + VALUES ('view_rule_with_owner', status_message); + + -- Return the log entry + RETURN QUERY SELECT * FROM refresh_log WHERE view_name = 'view_rule_with_owner' ORDER BY refreshed_at DESC LIMIT 1; +END; +$$ LANGUAGE plpgsql VOLATILE; + +--- +--- 8.7.1 + +Alter table "ldap_connection" ADD COLUMN IF NOT EXISTS "ldap_writepath_for_groups" Varchar; + +CREATE OR REPLACE FUNCTION insertLocalLdapWithEncryptedPasswords( + serverName TEXT, + port INTEGER, + userSearchPath TEXT, + roleSearchPath TEXT, + groupSearchPath TEXT, + groupWritePath TEXT, + tenantLevel INTEGER, + searchUser TEXT, + searchUserPwd TEXT, + writeUser TEXT, + writeUserPwd TEXT, + ldapType INTEGER +) RETURNS VOID AS $$ +DECLARE + t_key TEXT; + t_encryptedReadPwd TEXT; + t_encryptedWritePwd TEXT; +BEGIN + IF (SELECT 1 FROM ldap_connection WHERE ldap_server = serverName LIMIT 1) IS NULL + THEN + SELECT INTO t_key * FROM getMainKey(); + SELECT INTO t_encryptedReadPwd * FROM encryptText(searchUserPwd, t_key); + SELECT INTO t_encryptedWritePwd * FROM encryptText(writeUserPwd, t_key); + INSERT INTO ldap_connection + (ldap_server, ldap_port, ldap_searchpath_for_users, ldap_searchpath_for_roles, ldap_searchpath_for_groups, ldap_writepath_for_groups, + ldap_tenant_level, ldap_search_user, ldap_search_user_pwd, ldap_write_user, ldap_write_user_pwd, ldap_type) + VALUES (serverName, port, userSearchPath, roleSearchPath, groupSearchPath, groupWritePath, tenantLevel, searchUser, t_encryptedReadPwd, writeUser, t_encryptedWritePwd, ldapType); + END IF; +END; +$$ LANGUAGE plpgsql; + + +-- 8.7.2 +ALTER TABLE ext_request ADD COLUMN IF NOT EXISTS attempts int DEFAULT 0; +insert into config (config_key, config_value, config_user) VALUES ('modModelledMarker', 'FWOC', 0) ON CONFLICT DO NOTHING; +insert into config (config_key, config_value, config_user) VALUES ('modModelledMarkerLocation', 'rulename', 0) ON CONFLICT DO NOTHING; +insert into config (config_key, config_value, config_user) VALUES ('ruleRecognitionOption', '{"nwRegardIp":true,"nwRegardName":false,"nwRegardGroupName":false,"nwResolveGroup":false,"svcRegardPortAndProt":true,"svcRegardName":false,"svcRegardGroupName":false,"svcResolveGroup":true}', 0) ON CONFLICT DO NOTHING; +insert into config (config_key, config_value, config_user) VALUES ('availableReportTypes', '[1,2,3,4,5,6,7,8,9,10,21,22]', 0) ON CONFLICT DO NOTHING; + +-- 8.8.2 +insert into config (config_key, config_value, config_user) VALUES ('varianceAnalysisSleepTime', '0', 0) ON CONFLICT DO NOTHING; +insert into config (config_key, config_value, config_user) VALUES ('varianceAnalysisStartAt', '00:00:00', 0) ON CONFLICT DO NOTHING; +insert into config (config_key, config_value, config_user) VALUES ('varianceAnalysisSync', 'false', 0) ON CONFLICT DO NOTHING; +insert into config (config_key, config_value, config_user) VALUES ('varianceAnalysisRefresh', 'false', 0) ON CONFLICT DO NOTHING; +insert into config (config_key, config_value, config_user) VALUES ('resolveNetworkAreas', 'false', 0) ON CONFLICT DO NOTHING; + +-- 8.8.3 +ALTER TABLE modelling.connection ADD COLUMN IF NOT EXISTS requested_on_fw boolean default false; +ALTER TABLE modelling.connection ADD COLUMN IF NOT EXISTS removed boolean default false; +ALTER TABLE modelling.connection ADD COLUMN IF NOT EXISTS removal_date timestamp; +UPDATE modelling.connection SET requested_on_fw=true WHERE NOT requested_on_fw; + +-- 8.8.4 +insert into stm_action (action_id,action_name) VALUES (30,'ask') ON CONFLICT DO NOTHING; -- cp + +-- 8.8.5 +ALTER TYPE rule_field_enum ADD VALUE IF NOT EXISTS 'modelled_source'; +ALTER TYPE rule_field_enum ADD VALUE IF NOT EXISTS 'modelled_destination'; + +-- 8.8.6 +insert into stm_track (track_id,track_name) VALUES (23,'detailed log') ON CONFLICT DO NOTHING; -- check point R8x +insert into stm_track (track_id,track_name) VALUES (24,'extended log') ON CONFLICT DO NOTHING; -- check point R8x + +-- 8.8.8 +DO $$ +BEGIN + IF NOT EXISTS (SELECT FROM pg_roles WHERE rolname = 'fwo_ro') THEN + CREATE ROLE fwo_ro WITH LOGIN NOSUPERUSER INHERIT NOCREATEDB NOCREATEROLE; + END IF; +END +$$; + + +GRANT CONNECT ON DATABASE fworchdb TO fwo_ro; + +GRANT USAGE ON SCHEMA compliance TO fwo_ro; +GRANT SELECT ON ALL TABLES IN SCHEMA compliance TO fwo_ro; +GRANT USAGE, SELECT ON ALL SEQUENCES IN SCHEMA compliance TO fwo_ro; +ALTER DEFAULT PRIVILEGES IN SCHEMA compliance GRANT SELECT ON TABLES TO fwo_ro; +ALTER DEFAULT PRIVILEGES IN SCHEMA compliance GRANT USAGE, SELECT ON SEQUENCES TO fwo_ro; + +GRANT USAGE ON SCHEMA modelling TO fwo_ro; +GRANT SELECT ON ALL TABLES IN SCHEMA modelling TO fwo_ro; +GRANT USAGE, SELECT ON ALL SEQUENCES IN SCHEMA modelling TO fwo_ro; +ALTER DEFAULT PRIVILEGES IN SCHEMA modelling GRANT SELECT ON TABLES TO fwo_ro; +ALTER DEFAULT PRIVILEGES IN SCHEMA modelling GRANT USAGE, SELECT ON SEQUENCES TO fwo_ro; + +GRANT USAGE ON SCHEMA public TO fwo_ro; +GRANT SELECT ON ALL TABLES IN SCHEMA public TO fwo_ro; +GRANT USAGE, SELECT ON ALL SEQUENCES IN SCHEMA public TO fwo_ro; +ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT SELECT ON TABLES TO fwo_ro; +ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT USAGE, SELECT ON SEQUENCES TO fwo_ro; + +GRANT USAGE ON SCHEMA request TO fwo_ro; +GRANT SELECT ON ALL TABLES IN SCHEMA request TO fwo_ro; +GRANT USAGE, SELECT ON ALL SEQUENCES IN SCHEMA request TO fwo_ro; +ALTER DEFAULT PRIVILEGES IN SCHEMA request GRANT SELECT ON TABLES TO fwo_ro; +ALTER DEFAULT PRIVILEGES IN SCHEMA request GRANT USAGE, SELECT ON SEQUENCES TO fwo_ro; + +-- 8.8.9 + +ALTER TABLE recertification ADD column IF NOT EXISTS owner_recert_id BIGINT; + +create table if not exists owner_recertification +( + id BIGSERIAL PRIMARY KEY, + owner_id int NOT NULL, + user_dn varchar, + recertified boolean default false, + recert_date Timestamp, + comment varchar, + next_recert_date Timestamp +); + +create table if not exists notification +( + id SERIAL PRIMARY KEY, + notification_client Varchar, + user_id int, + owner_id int, + channel Varchar, + recipient_to Varchar, + email_address_to Varchar, + recipient_cc Varchar, + email_address_cc Varchar, + email_subject Varchar, + layout Varchar, + deadline Varchar, + interval_before_deadline int, + offset_before_deadline int, + repeat_interval_after_deadline int, + repeat_offset_after_deadline int, + repetitions_after_deadline int, + last_sent Timestamp +); + +alter table notification drop constraint if exists notification_owner_foreign_key; +ALTER TABLE notification ADD CONSTRAINT notification_owner_foreign_key FOREIGN KEY (owner_id) REFERENCES owner(id) ON UPDATE RESTRICT ON DELETE CASCADE; +alter table notification drop constraint if exists notification_user_foreign_key; +ALTER TABLE notification ADD CONSTRAINT notification_user_foreign_key FOREIGN KEY (user_id) REFERENCES uiuser(uiuser_id) ON UPDATE RESTRICT ON DELETE CASCADE; + +alter table owner add column if not exists last_recertified Timestamp; +alter table owner add column if not exists last_recertifier int; +alter table owner add column if not exists last_recertifier_dn Varchar; +alter table owner add column if not exists next_recert_date Timestamp; + +alter table owner drop constraint if exists owner_last_recertifier_uiuser_uiuser_id_f_key; +alter table owner add constraint owner_last_recertifier_uiuser_uiuser_id_f_key foreign key (last_recertifier) references uiuser (uiuser_id) on update restrict; + +insert into config (config_key, config_value, config_user) VALUES ('modDecommEmailReceiver', 'None', 0) ON CONFLICT DO NOTHING; +insert into config (config_key, config_value, config_user) VALUES ('modDecommEmailSubject', '', 0) ON CONFLICT DO NOTHING; +insert into config (config_key, config_value, config_user) VALUES ('modDecommEmailBody', '', 0) ON CONFLICT DO NOTHING; + +alter table report add column if not exists read_only Boolean default FALSE; + +DO $$ +BEGIN + -- recertification.owner_recert_id → owner_recertification(id) + IF NOT EXISTS ( + SELECT 1 + FROM pg_constraint c + JOIN pg_class t ON t.oid = c.conrelid + JOIN pg_namespace n ON n.oid = t.relnamespace + WHERE c.conname = 'recertification_owner_recertification_foreign_key' + AND t.relname = 'recertification' + AND n.nspname = current_schema() + ) THEN + ALTER TABLE recertification + ADD CONSTRAINT recertification_owner_recertification_foreign_key + FOREIGN KEY (owner_recert_id) + REFERENCES owner_recertification(id) + ON UPDATE RESTRICT + ON DELETE CASCADE; + END IF; + + -- owner_recertification.owner_id → owner(id) + IF NOT EXISTS ( + SELECT 1 + FROM pg_constraint c + JOIN pg_class t ON t.oid = c.conrelid + JOIN pg_namespace n ON n.oid = t.relnamespace + WHERE c.conname = 'owner_recertification_owner_foreign_key' + AND t.relname = 'owner_recertification' + AND n.nspname = current_schema() + ) THEN + ALTER TABLE owner_recertification + ADD CONSTRAINT owner_recertification_owner_foreign_key + FOREIGN KEY (owner_id) + REFERENCES owner(id) + ON UPDATE RESTRICT + ON DELETE CASCADE; + END IF; +END +$$; + +-- 8.9.1 + +alter table report add column if not exists owner_id Integer; + +alter table report drop constraint if exists report_owner_foreign_key; +ALTER TABLE report ADD CONSTRAINT report_owner_foreign_key FOREIGN KEY (owner_id) REFERENCES owner(id) ON UPDATE RESTRICT ON DELETE CASCADE; + +alter table owner_recertification add column if not exists report_id bigint; +alter table owner_recertification drop constraint if exists owner_recertification_report_foreign_key; +ALTER TABLE owner_recertification ADD CONSTRAINT owner_recertification_report_foreign_key FOREIGN KEY (report_id) REFERENCES report(report_id) ON UPDATE RESTRICT ON DELETE CASCADE; + +alter table owner add column if not exists recert_active boolean default false; + +alter table recertification add column if not exists owner_recert_id bigint; + +alter table recertification drop constraint if exists recertification_owner_recertification_foreign_key; +ALTER TABLE recertification ADD CONSTRAINT recertification_owner_recertification_foreign_key FOREIGN KEY (owner_recert_id) REFERENCES owner_recertification(id) ON UPDATE RESTRICT ON DELETE CASCADE; + +-- 8.9.2 +CREATE TABLE if not exists owner_lifecycle_state ( + id SERIAL PRIMARY KEY, + name Varchar NOT NULL +); + +alter table owner add column if not exists owner_lifecycle_state_id int; + +alter table owner drop constraint if exists owner_owner_lifecycle_state_foreign_key; +ALTER TABLE owner ADD CONSTRAINT owner_owner_lifecycle_state_foreign_key FOREIGN KEY (owner_lifecycle_state_id)REFERENCES owner_lifecycle_state(id) ON DELETE SET NULL; + +-- changes to nw obj ip constraints +ALTER TABLE "object" DROP CONSTRAINT IF EXISTS "object_obj_ip_not_null" CASCADE; +ALTER TABLE "object" DROP CONSTRAINT IF EXISTS "object_obj_ip_end_not_null" CASCADE; + +-- magic numbers here: 1 = host object, 3 = network object, 4 = range object +ALTER TABLE "object" ADD CONSTRAINT object_obj_ip_not_null CHECK (NOT (obj_ip IS NULL AND obj_typ_id IN (1, 3, 4))); +ALTER TABLE "object" ADD CONSTRAINT object_obj_ip_end_not_null CHECK (NOT (obj_ip_end IS NULL AND obj_typ_id IN (1, 3, 4))); + +-- 8.9.2 +CREATE TABLE if not exists owner_lifecycle_state ( + id SERIAL PRIMARY KEY, + name Varchar NOT NULL +); + +alter table owner add column if not exists owner_lifecycle_state_id int; + +alter table owner drop constraint if exists owner_owner_lifecycle_state_foreign_key; +ALTER TABLE owner ADD CONSTRAINT owner_owner_lifecycle_state_foreign_key FOREIGN KEY (owner_lifecycle_state_id)REFERENCES owner_lifecycle_state(id) ON DELETE SET NULL; + +-- v8.9.6 + +alter table notification add column if not exists initial_offset_after_deadline int; +alter table notification add column if not exists name Varchar; + +------------------------------------------------------------------------------------ + +-- rename changes_found column to rule_changes_found in import_control table +DO $$ +BEGIN + IF EXISTS ( + SELECT 1 + FROM information_schema.columns + WHERE table_name = 'import_control' + AND column_name = 'changes_found' + ) THEN + EXECUTE 'ALTER TABLE import_control RENAME COLUMN changes_found TO rule_changes_found'; + END IF; +END +$$; + +-- add any_changes_found column to import_control table +ALTER table "import_control" + ADD COLUMN IF NOT EXISTS "any_changes_found" Boolean Default FALSE; + + +-- now set the any_changes_found column to true for all imports that have security relevant changes + +DROP VIEW IF EXISTS view_imports_with_security_relevant_changes; + +CREATE OR REPLACE VIEW view_imports_with_security_relevant_changes AS + SELECT clr.control_id AS import_id, clr.mgm_id + FROM changelog_rule clr + WHERE clr.security_relevant + + UNION + + SELECT clo.control_id AS import_id, clo.mgm_id + FROM changelog_object clo + WHERE clo.security_relevant + + UNION + + SELECT cls.control_id AS import_id, cls.mgm_id + FROM changelog_service cls + WHERE cls.security_relevant + + UNION + + SELECT clu.control_id AS import_id, clu.mgm_id + FROM changelog_user clu + WHERE clu.security_relevant; + + +UPDATE import_control +SET any_changes_found = true +WHERE control_id IN ( + SELECT import_id + FROM view_imports_with_security_relevant_changes +); + +DROP VIEW IF EXISTS view_imports_with_security_relevant_changes; + +--- pre 9.0 changes (old import) + +DELETE FROM stm_dev_typ WHERE dev_typ_id IN (2,4,5,6,7); + +DROP TRIGGER IF EXISTS gw_route_add ON gw_route CASCADE; +CREATE TRIGGER gw_route_add BEFORE INSERT ON gw_route FOR EACH ROW EXECUTE PROCEDURE gw_route_add(); + +CREATE OR REPLACE FUNCTION import_config_from_json () + RETURNS TRIGGER + AS $BODY$ +DECLARE + i_mgm_id INTEGER; + i_count INTEGER; +BEGIN + -- networking + SELECT INTO i_mgm_id mgm_id FROM import_control WHERE control_id=NEW.import_id; + -- before importing, delete all old interfaces and routes belonging to the current management: + + -- now re-insert the currently found interfaces: + SELECT INTO i_count COUNT(*) FROM jsonb_populate_recordset(NULL::gw_interface, NEW.config -> 'interfaces'); + IF i_count>0 THEN + DELETE FROM gw_interface WHERE routing_device IN + (SELECT dev_id FROM device LEFT JOIN management ON (device.mgm_id=management.mgm_id) WHERE management.mgm_id=i_mgm_id); + INSERT INTO gw_interface SELECT * FROM jsonb_populate_recordset(NULL::gw_interface, NEW.config -> 'interfaces'); + END IF; + + SELECT INTO i_count COUNT(*) FROM jsonb_populate_recordset(NULL::gw_route, NEW.config -> 'routing'); + IF i_count>0 THEN + DELETE FROM gw_route WHERE routing_device IN + (SELECT dev_id FROM device LEFT JOIN management ON (device.mgm_id=management.mgm_id) WHERE management.mgm_id=i_mgm_id); + -- now re-insert the currently found routes: + INSERT INTO gw_route SELECT * FROM jsonb_populate_recordset(NULL::gw_route, NEW.config -> 'routing'); + END IF; + + -- firewall objects and rules + + INSERT INTO import_object + SELECT + * + FROM + jsonb_populate_recordset(NULL::import_object, NEW.config -> 'network_objects'); + + INSERT INTO import_service + SELECT + * + FROM + jsonb_populate_recordset(NULL::import_service, NEW.config -> 'service_objects'); + + INSERT INTO import_user + SELECT + * + FROM + jsonb_populate_recordset(NULL::import_user, NEW.config -> 'user_objects'); + + INSERT INTO import_zone + SELECT + * + FROM + jsonb_populate_recordset(NULL::import_zone, NEW.config -> 'zone_objects'); + + INSERT INTO import_rule + SELECT + * + FROM + jsonb_populate_recordset(NULL::import_rule, NEW.config -> 'rules'); + + IF NEW.start_import_flag THEN + -- finally start the stored procedure import + PERFORM import_all_main(NEW.import_id, NEW.debug_mode); + END IF; + RETURN NEW; +END; +$BODY$ +LANGUAGE plpgsql +VOLATILE; +ALTER FUNCTION public.import_config_from_json () OWNER TO fworch; + +DROP TRIGGER IF EXISTS import_config_insert ON import_config CASCADE; + +CREATE TRIGGER import_config_insert + BEFORE INSERT ON import_config + FOR EACH ROW + EXECUTE PROCEDURE import_config_from_json (); + +--------------------------------------------------------------------------------------------- +-- new import + +ALTER TABLE management ADD COLUMN IF NOT EXISTS "mgm_uid" Varchar NOT NULL DEFAULT ''; +ALTER TABLE management ADD COLUMN IF NOT EXISTS "rulebase_name" Varchar NOT NULL DEFAULT ''; +ALTER TABLE management ADD COLUMN IF NOT EXISTS "rulebase_uid" Varchar NOT NULL DEFAULT ''; +-- Alter table rule_metadata add column if not exists rulebase_id integer; -- not null; + +ALTER TABLE device ADD COLUMN IF NOT EXISTS "dev_uid" Varchar NOT NULL DEFAULT ''; + +Alter table stm_action add column if not exists allowed BOOLEAN NOT NULL DEFAULT TRUE; +UPDATE stm_action SET allowed = FALSE WHERE action_name = 'deny' OR action_name = 'drop' OR action_name = 'reject'; + +Create table IF NOT EXISTS "rulebase" +( + "id" SERIAL primary key, + "name" Varchar NOT NULL, + "uid" Varchar NOT NULL, + "mgm_id" Integer NOT NULL, + "is_global" BOOLEAN DEFAULT FALSE NOT NULL, + "created" BIGINT, + "removed" BIGINT +); + +ALTER table "rulebase" ADD COLUMN IF NOT EXISTS "uid" Varchar NOT NULL; +ALTER table "rulebase" ADD COLUMN IF NOT EXISTS "removed" BIGINT; + + +ALTER TABLE "rulebase" DROP CONSTRAINT IF EXISTS "fk_rulebase_mgm_id" CASCADE; +Alter table "rulebase" add CONSTRAINT fk_rulebase_mgm_id foreign key ("mgm_id") references "management" ("mgm_id") on update restrict on delete cascade; + +ALTER TABLE "rulebase" DROP CONSTRAINT IF EXISTS "unique_rulebase_mgm_id_name" CASCADE; +ALTER TABLE "rulebase" DROP CONSTRAINT IF EXISTS "unique_rulebase_mgm_id_uid" CASCADE; +ALTER TABLE "rulebase" DROP CONSTRAINT IF EXISTS "unique_rulebase_mgm_id_uid_removed" CASCADE; +ALTER TABLE "rulebase" DROP CONSTRAINT IF EXISTS "rulebase_uid_mgm_id_removed_key" CASCADE; +Alter table "rulebase" add CONSTRAINT rulebase_uid_mgm_id_removed_key UNIQUE ("mgm_id", "uid", "removed"); +----------------------------------------------- + +ALTER TABLE "management" ADD COLUMN IF NOT EXISTS "is_super_manager" BOOLEAN DEFAULT FALSE; +ALTER TABLE "rule" ADD COLUMN IF NOT EXISTS "is_global" BOOLEAN DEFAULT FALSE NOT NULL; +ALTER TABLE "rule" ADD COLUMN IF NOT EXISTS "rulebase_id" INTEGER; + +-- permanent table for storing latest config to calc diffs +CREATE TABLE IF NOT EXISTS "latest_config" ( + "mgm_id" integer NOT NULL, + "import_id" bigint NOT NULL, + "config" jsonb NOT NULL, + PRIMARY KEY ("mgm_id") +); + + +-- Drop old primary key if it exists +DO $$ +BEGIN + IF EXISTS ( + SELECT 1 + FROM pg_constraint + WHERE conrelid = 'latest_config'::regclass + AND contype = 'p' + ) THEN + ALTER TABLE latest_config DROP CONSTRAINT latest_config_pkey; + END IF; +END $$; + +-- Add new primary key on mgm_id if not already set +DO $$ +BEGIN + IF NOT EXISTS ( + SELECT 1 + FROM pg_constraint + WHERE conrelid = 'latest_config'::regclass + AND contype = 'p' + AND conkey = ARRAY[ + (SELECT attnum FROM pg_attribute + WHERE attrelid = 'latest_config'::regclass + AND attname = 'mgm_id') + ] + ) THEN + ALTER TABLE latest_config ADD CONSTRAINT latest_config_pkey PRIMARY KEY (mgm_id); + END IF; +END $$; + + +ALTER table "import_control" ADD COLUMN IF NOT EXISTS "is_full_import" BOOLEAN DEFAULT FALSE; + +----------------------------------------------- + +Create Table IF NOT EXISTS "rule_enforced_on_gateway" +( + "rule_id" Integer NOT NULL, + "dev_id" Integer, -- NULL if rule is available for all gateways of its management + "created" BIGINT, + "removed" BIGINT +); + + ALTER table "rule_enforced_on_gateway" ADD COLUMN IF NOT EXISTS "removed" BIGINT; + +ALTER TABLE "rule_enforced_on_gateway" + DROP CONSTRAINT IF EXISTS "fk_rule_enforced_on_gateway_rule_rule_id" CASCADE; +Alter table "rule_enforced_on_gateway" add CONSTRAINT fk_rule_enforced_on_gateway_rule_rule_id foreign key ("rule_id") references "rule" ("rule_id") on update restrict on delete cascade; + +ALTER TABLE "rule_enforced_on_gateway" + DROP CONSTRAINT IF EXISTS "fk_rule_enforced_on_gateway_device_dev_id" CASCADE; +Alter table "rule_enforced_on_gateway" add CONSTRAINT fk_rule_enforced_on_gateway_device_dev_id foreign key ("dev_id") references "device" ("dev_id") on update restrict on delete cascade; + +ALTER TABLE "rule_enforced_on_gateway" + DROP CONSTRAINT IF EXISTS "fk_rule_enforced_on_gateway_created_import_control_control_id" CASCADE; +Alter table "rule_enforced_on_gateway" add CONSTRAINT fk_rule_enforced_on_gateway_created_import_control_control_id + foreign key ("created") references "import_control" ("control_id") on update restrict on delete cascade; + +ALTER TABLE "rule_enforced_on_gateway" + DROP CONSTRAINT IF EXISTS "fk_rule_enforced_on_gateway_removed_import_control_control_id" CASCADE; + +-- just temp for migration purposes - will be removed later +ALTER TABLE "rule_enforced_on_gateway" + DROP CONSTRAINT IF EXISTS "fk_rule_enforced_on_gateway_deleted_import_control_control_id" CASCADE; + +Alter table "rule_enforced_on_gateway" add CONSTRAINT fk_rule_enforced_on_gateway_removed_import_control_control_id + foreign key ("removed") references "import_control" ("control_id") on update restrict on delete cascade; + +----------------------------------------------- + +CREATE OR REPLACE FUNCTION get_next_rule_number_after_uid(mgmId int, current_rule_uid text) +RETURNS NUMERIC AS $$ + SELECT r.rule_num_numeric as ruleNumber + FROM rule r + WHERE r.mgm_id = mgmId and active + AND r.rule_num_numeric > ( + SELECT rule_num_numeric + FROM rule r2 + WHERE rule_uid = current_rule_uid AND r2.mgm_id = mgmId AND active + LIMIT 1 + ) + ORDER BY r.rule_num_numeric ASC + LIMIT 1; +$$ LANGUAGE sql; + +ALTER table "svcgrp_flat" ALTER COLUMN "svcgrp_flat_id" TYPE BIGINT; +ALTER table "svcgrp_flat" ALTER COLUMN "svcgrp_flat_member_id" TYPE BIGINT; +ALTER table "svcgrp_flat" ALTER COLUMN "import_created" TYPE BIGINT; +ALTER table "svcgrp_flat" ALTER COLUMN "import_last_seen" TYPE BIGINT; + +ALTER TABLE "rule" DROP CONSTRAINT IF EXISTS "fk_rule_rulebase_id" CASCADE; +ALTER TABLE "rule" ADD CONSTRAINT fk_rule_rulebase_id FOREIGN KEY ("rulebase_id") REFERENCES "rulebase" ("id") ON UPDATE RESTRICT ON DELETE CASCADE; + +-- removed logic for rule +ALTER TABLE "rule" ADD COLUMN IF NOT EXISTS "removed" BIGINT; + +----------------------------------------------- +-- METADATA part +-- we are removing dev_id and rulebase_id from rule_metadata +-- even CP API does not provide this information regarding hits (the target parameter is ignored, so hits are returned per rule not per rule per gw) + +Alter table "rule" drop constraint IF EXISTS "rule_metadata_dev_id_rule_uid_f_key"; +Alter Table "rule_metadata" drop Constraint IF EXISTS "rule_metadata_alt_key"; + +ALTER TABLE rule_metadata DROP Constraint IF EXISTS "rule_metadata_rule_uid_unique" CASCADE; +Alter table "rule" DROP constraint IF EXISTS "rule_rule_metadata_rule_uid_f_key"; + +-- composite fk is added after rule_metadata.mgm_id is populated + + +-- rule_metadata add mgm_id + fk, drop constraint +ALTER TABLE rule_metadata ADD COLUMN IF NOT EXISTS mgm_id Integer; + +DO $$ +BEGIN + IF NOT EXISTS ( + SELECT 1 + FROM pg_constraint + WHERE conname = 'rule_metadata_mgm_id_management_id_fk' + ) THEN + ALTER TABLE rule_metadata + ADD CONSTRAINT rule_metadata_mgm_id_management_id_fk + FOREIGN KEY (mgm_id) REFERENCES management(mgm_id) + ON UPDATE RESTRICT ON DELETE CASCADE; + END IF; +END$$; + +DO $$ +DECLARE + rec RECORD; + v_do_not_import_true_count INT; + v_do_not_import_false_count INT; + missing_uids TEXT; + too_many_mgm_ids_on_uid_and_no_resolve TEXT; + all_errors_with_no_resolve TEXT := ''; + rm_columns TEXT; + rm_columns_select TEXT; + +BEGIN +--Check rule_metadata has entries in rule + SELECT string_agg(rm.rule_uid::text, ', ') + INTO missing_uids + FROM rule_metadata rm + LEFT JOIN rule r ON rm.rule_uid = r.rule_uid + WHERE r.rule_uid IS NULL + AND rm.mgm_id IS NULL; + + IF missing_uids IS NOT NULL THEN + RAISE NOTICE 'Missing rule(s): %', missing_uids; + DELETE FROM rule_metadata + WHERE rule_uid IN ( + SELECT rm.rule_uid + FROM rule_metadata rm + LEFT JOIN rule r ON rm.rule_uid = r.rule_uid + WHERE r.rule_uid IS NULL + AND rm.mgm_id IS NULL + ) + AND mgm_id IS NULL; + END IF; + + -- drop constraints + ALTER TABLE rule DROP CONSTRAINT IF EXISTS rule_metadatum; + ALTER TABLE rule DROP CONSTRAINT IF EXISTS rule_rule_metadata_rule_uid_f_key; + ALTER TABLE rule_metadata DROP CONSTRAINT IF EXISTS rule_metadata_rule_uid_unique; + +-- Start loop for rule_uid und mgm_id import/transfer + FOR rec IN + SELECT + rm.rule_uid, + COUNT(DISTINCT r.mgm_id) AS mgm_count + FROM rule_metadata rm + JOIN rule r ON rm.rule_uid = r.rule_uid + WHERE rm.mgm_id IS NULL + GROUP BY rm.rule_uid + HAVING COUNT(DISTINCT r.mgm_id) >= 1 + LOOP + -- Case 1: exactly one mgm_id gefunden + IF rec.mgm_count = 1 THEN + -- + UPDATE rule_metadata rm + SET mgm_id = r.mgm_id + FROM rule r + WHERE rm.rule_uid = r.rule_uid + AND rm.mgm_id IS NULL + AND rm.rule_uid = rec.rule_uid; + + -- Case 2: found more then two mgm_id found + ELSIF rec.mgm_count >= 2 THEN + -- Count flag "do_not_import" for rule_uid + SELECT + COUNT(*) FILTER (WHERE m.do_not_import IS TRUE), + COUNT(*) FILTER (WHERE m.do_not_import IS FALSE) + INTO v_do_not_import_true_count, v_do_not_import_false_count + FROM rule r + JOIN management m ON r.mgm_id = m.mgm_id + WHERE r.rule_uid = rec.rule_uid; + + -- check if there is just 1 "do_not_import" = false + IF v_do_not_import_false_count = 1 THEN + UPDATE rule_metadata rm + SET mgm_id = r.mgm_id + FROM rule r + JOIN management m ON r.mgm_id = m.mgm_id + WHERE rm.rule_uid = r.rule_uid + AND m.do_not_import IS FALSE + AND rm.rule_uid = rec.rule_uid + AND rm.mgm_id IS NULL; + + -- Warning: Not used mgm_ids where do_not_import=true + RAISE NOTICE 'rule_uid % has % additional mgm_id(s) marked do_not_import=true: %', + rec.rule_uid, v_do_not_import_true_count, + (SELECT string_agg(format('mgm_id=%s', r.mgm_id), ', ') + FROM rule r + JOIN management m ON r.mgm_id = m.mgm_id + WHERE r.rule_uid = rec.rule_uid + AND m.do_not_import IS TRUE); + + ELSE + -- No resolve + SELECT string_agg( + format('rule_uid=%s → mgm_id=%s (do_not_import=%s)', + r.rule_uid, r.mgm_id, m.do_not_import), + E'\n' + ) + INTO too_many_mgm_ids_on_uid_and_no_resolve + FROM rule r + JOIN management m ON r.mgm_id = m.mgm_id + WHERE r.rule_uid = rec.rule_uid; + + all_errors_with_no_resolve := all_errors_with_no_resolve || format( + E'\n\nrule_uid %s has ambiguous mgm_id assignments:\n%s', + rec.rule_uid, + too_many_mgm_ids_on_uid_and_no_resolve + ); + + END IF; + END IF; + END LOOP; + + IF all_errors_with_no_resolve <> '' THEN + RAISE EXCEPTION 'Ambiguous mgm_id assignments detected:%s', all_errors_with_no_resolve; + END IF; + + -- update NAT rule UIDs to make implicit NAT rules unique per device/xlate rule + CREATE TEMP TABLE tmp_nat_rule_uid AS + SELECT r.rule_id, + r.mgm_id, + r.rule_uid AS old_uid, + r.rule_uid || '_' || COALESCE(r.dev_id::text, 'NULL') || '_' || COALESCE(r.xlate_rule::text, 'NULL') AS new_uid + FROM rule r + WHERE r.nat_rule IS TRUE + AND r.rule_uid IS NOT NULL + AND r.rule_uid NOT LIKE '%' || '_' || COALESCE(r.dev_id::text, 'NULL') || '_' || COALESCE(r.xlate_rule::text, 'NULL'); + + -- collapse any existing rule_metadata duplicates for the affected old_uids + CREATE TEMP TABLE tmp_rule_metadata_dups_old AS + SELECT rm.rule_metadata_id AS duplicate_id, + MIN(rm.rule_metadata_id) OVER (PARTITION BY rm.mgm_id, rm.rule_uid) AS keep_id + FROM rule_metadata rm + JOIN ( + SELECT DISTINCT mgm_id, old_uid + FROM tmp_nat_rule_uid + ) t ON t.mgm_id = rm.mgm_id AND t.old_uid = rm.rule_uid; + + UPDATE rule_owner ro + SET rule_metadata_id = d.keep_id + FROM tmp_rule_metadata_dups_old d + WHERE ro.rule_metadata_id = d.duplicate_id + AND d.duplicate_id <> d.keep_id; + + UPDATE recertification rct + SET rule_metadata_id = d.keep_id + FROM tmp_rule_metadata_dups_old d + WHERE rct.rule_metadata_id = d.duplicate_id + AND d.duplicate_id <> d.keep_id; + + DELETE FROM rule_metadata rm + USING tmp_rule_metadata_dups_old d + WHERE rm.rule_metadata_id = d.duplicate_id + AND d.duplicate_id <> d.keep_id; + + DROP TABLE tmp_rule_metadata_dups_old; + + SELECT string_agg(quote_ident(column_name), ', ') + INTO rm_columns + FROM information_schema.columns + WHERE table_schema = 'public' + AND table_name = 'rule_metadata' + AND column_name NOT IN ('rule_metadata_id', 'rule_uid'); + + SELECT string_agg('rm.' || quote_ident(column_name), ', ') + INTO rm_columns_select + FROM information_schema.columns + WHERE table_schema = 'public' + AND table_name = 'rule_metadata' + AND column_name NOT IN ('rule_metadata_id', 'rule_uid'); + + WITH primary_uid AS ( + SELECT mgm_id, old_uid, MIN(new_uid) AS new_uid + FROM tmp_nat_rule_uid + GROUP BY mgm_id, old_uid + ) + UPDATE rule_metadata rm + SET rule_uid = p.new_uid + FROM primary_uid p + WHERE rm.mgm_id = p.mgm_id + AND rm.rule_uid = p.old_uid; + + IF rm_columns IS NULL THEN + EXECUTE + 'INSERT INTO rule_metadata (rule_uid) + SELECT m.new_uid + FROM tmp_nat_rule_uid m + JOIN ( + SELECT mgm_id, old_uid, MIN(new_uid) AS primary_uid + FROM tmp_nat_rule_uid + GROUP BY mgm_id, old_uid + ) p ON p.mgm_id = m.mgm_id AND p.old_uid = m.old_uid + WHERE m.new_uid <> p.primary_uid + AND NOT EXISTS ( + SELECT 1 FROM rule_metadata rm2 + WHERE rm2.mgm_id = m.mgm_id AND rm2.rule_uid = m.new_uid + )'; + ELSE + EXECUTE format( + 'INSERT INTO rule_metadata (rule_uid, %s) + SELECT m.new_uid, %s + FROM tmp_nat_rule_uid m + JOIN ( + SELECT mgm_id, old_uid, MIN(new_uid) AS primary_uid + FROM tmp_nat_rule_uid + GROUP BY mgm_id, old_uid + ) p ON p.mgm_id = m.mgm_id AND p.old_uid = m.old_uid + JOIN rule_metadata rm ON rm.mgm_id = p.mgm_id AND rm.rule_uid = p.primary_uid + WHERE m.new_uid <> p.primary_uid + AND NOT EXISTS ( + SELECT 1 FROM rule_metadata rm2 + WHERE rm2.mgm_id = m.mgm_id AND rm2.rule_uid = m.new_uid + )', + rm_columns, + rm_columns_select + ); + END IF; + + UPDATE rule r + SET rule_uid = t.new_uid + FROM tmp_nat_rule_uid t + WHERE r.rule_id = t.rule_id; + + DROP TABLE tmp_nat_rule_uid; + + -- redo constraints + ALTER TABLE rule_metadata ALTER COLUMN mgm_id SET NOT NULL; + ALTER TABLE rule_metadata DROP CONSTRAINT IF EXISTS rule_metadata_rule_uid_unique; + IF NOT EXISTS ( + SELECT 1 + FROM pg_constraint + WHERE conname = 'rule_metadata_mgm_id_rule_uid_unique' + ) THEN + ALTER TABLE rule_metadata ADD CONSTRAINT rule_metadata_mgm_id_rule_uid_unique UNIQUE (mgm_id, rule_uid); + END IF; + ALTER TABLE rule DROP CONSTRAINT IF EXISTS rule_rule_metadata_rule_uid_f_key; + ALTER TABLE rule DROP CONSTRAINT IF EXISTS rule_rule_metadata_mgm_id_rule_uid_f_key; + ALTER TABLE rule ADD CONSTRAINT rule_rule_metadata_mgm_id_rule_uid_f_key + FOREIGN KEY (mgm_id, rule_uid) REFERENCES rule_metadata (mgm_id, rule_uid) + ON UPDATE RESTRICT ON DELETE CASCADE; +END$$; + +-- rework rule_metadata timestamps to reference import_control and drop unused columns +ALTER TABLE IF EXISTS rule_metadata DROP CONSTRAINT IF EXISTS rule_metadata_rule_last_certifier_uiuser_uiuser_id_f_key CASCADE; +ALTER TABLE IF EXISTS rule_metadata DROP CONSTRAINT IF EXISTS rule_metadata_rule_owner_uiuser_uiuser_id_f_key CASCADE; + +ALTER TABLE IF EXISTS rule_metadata ADD COLUMN IF NOT EXISTS rule_created_new BIGINT; +ALTER TABLE IF EXISTS rule_metadata ADD COLUMN IF NOT EXISTS rule_last_modified_new BIGINT; + +-- delete all stale rule_metadata entries +DELETE FROM rule_metadata +WHERE rule_uid IN ( + SELECT rm.rule_uid + FROM rule_metadata rm + LEFT JOIN rule r ON r.rule_uid = rm.rule_uid + WHERE r.rule_uid IS NULL +); + +UPDATE rule_metadata m SET + rule_created_new = r.rule_create, + rule_last_modified_new = r.rule_last_seen +FROM rule r +WHERE r.rule_uid = m.rule_uid; + +UPDATE rule_metadata SET rule_last_modified_new = COALESCE(rule_last_modified_new, rule_created_new) WHERE TRUE; + +ALTER TABLE IF EXISTS rule_metadata DROP COLUMN IF EXISTS rule_created; +ALTER TABLE IF EXISTS rule_metadata DROP COLUMN IF EXISTS rule_last_modified; + +ALTER TABLE IF EXISTS rule_metadata RENAME COLUMN rule_created_new TO rule_created; +ALTER TABLE IF EXISTS rule_metadata RENAME COLUMN rule_last_modified_new TO rule_last_modified; + +ALTER TABLE IF EXISTS rule_metadata + ALTER COLUMN rule_created SET NOT NULL, + ALTER COLUMN rule_last_modified SET NOT NULL; + +-- rebuild recertification related views/materialized view +DROP MATERIALIZED VIEW IF EXISTS view_rule_with_owner CASCADE; +DROP VIEW IF EXISTS v_rule_with_ip_owner CASCADE; +DROP VIEW IF EXISTS v_rule_with_dst_owner CASCADE; +DROP VIEW IF EXISTS v_rule_with_src_owner CASCADE; +DROP VIEW IF EXISTS v_rule_with_rule_owner CASCADE; +DROP VIEW IF EXISTS v_rule_ownership_mode CASCADE; +DROP VIEW IF EXISTS v_active_access_allow_rules CASCADE; +DROP VIEW IF EXISTS v_excluded_src_ips CASCADE; +DROP VIEW IF EXISTS v_excluded_dst_ips CASCADE; + +ALTER TABLE IF EXISTS rule_metadata + DROP COLUMN IF EXISTS rule_last_certified, + DROP COLUMN IF EXISTS rule_last_certifier, + DROP COLUMN IF EXISTS rule_last_certifier_dn, + DROP COLUMN IF EXISTS rule_owner, + DROP COLUMN IF EXISTS rule_owner_dn, + DROP COLUMN IF EXISTS rule_to_be_removed, + DROP COLUMN IF EXISTS last_change_admin, + DROP COLUMN IF EXISTS rule_decert_date, + DROP COLUMN IF EXISTS rule_recertification_comment; + +ALTER TABLE IF EXISTS rule_metadata DROP CONSTRAINT IF EXISTS rule_metadata_rule_created_import_control_control_id_f_key CASCADE; +ALTER TABLE IF EXISTS rule_metadata DROP CONSTRAINT IF EXISTS rule_metadata_rule_last_modified_import_control_control_id_f_key CASCADE; +ALTER TABLE IF EXISTS rule_metadata ADD CONSTRAINT rule_metadata_rule_created_import_control_control_id_f_key + FOREIGN KEY (rule_created) REFERENCES import_control(control_id) ON UPDATE RESTRICT ON DELETE RESTRICT; +ALTER TABLE IF EXISTS rule_metadata ADD CONSTRAINT rule_metadata_rule_last_modified_import_control_control_id_f_key + FOREIGN KEY (rule_last_modified) REFERENCES import_control(control_id) ON UPDATE RESTRICT ON DELETE RESTRICT; + +CREATE OR REPLACE VIEW v_active_access_allow_rules AS + SELECT rule_id, + rule_src, rule_dst, rule_svc, + rule_svc_neg, rule_src_neg, rule_dst_neg, + mgm_id, rule_uid, + rule_num_numeric, rule_disabled, + rule_src_refs, rule_dst_refs, rule_svc_refs, + rule_from_zone, rule_to_zone, + rule_action, rule_track, track_id, action_id, + rule_installon, rule_comment, rule_name, rule_implied, rule_custom_fields, + rule_create, removed, + is_global, + rulebase_id + FROM rule r + WHERE r.active + AND r.access_rule + AND r.rule_head_text IS NULL + AND NOT r.rule_disabled + AND NOT r.action_id IN (2,3,7); + +CREATE OR REPLACE VIEW v_rule_ownership_mode AS + SELECT c.config_value as mode FROM config c + WHERE c.config_key = 'ruleOwnershipMode'; + +CREATE OR REPLACE VIEW v_rule_with_rule_owner AS + SELECT r.rule_id, ow.id as owner_id, ow.name as owner_name, 'rule' AS matches, + ow.recert_interval, max(rec.recert_date) AS rule_last_certified + FROM v_active_access_allow_rules r + LEFT JOIN rule_metadata met ON (r.rule_uid=met.rule_uid) + LEFT JOIN rule_owner ro ON (ro.rule_metadata_id=met.rule_metadata_id) + LEFT JOIN owner ow ON (ro.owner_id=ow.id) + LEFT JOIN recertification rec ON (rec.rule_metadata_id = met.rule_metadata_id AND rec.owner_id = ow.id AND rec.recertified IS TRUE) + WHERE NOT ow.id IS NULL + GROUP BY r.rule_id, ow.id, ow.name, ow.recert_interval; + +CREATE OR REPLACE VIEW v_excluded_src_ips AS + SELECT distinct o.obj_ip + FROM v_rule_with_rule_owner r + LEFT JOIN rule_from rf ON (r.rule_id=rf.rule_id) + LEFT JOIN objgrp_flat of ON (rf.obj_id=of.objgrp_flat_id) + LEFT JOIN object o ON (of.objgrp_flat_member_id=o.obj_id) + WHERE NOT o.obj_ip='0.0.0.0/0'; + +CREATE OR REPLACE VIEW v_excluded_dst_ips AS + SELECT distinct o.obj_ip + FROM v_rule_with_rule_owner r + LEFT JOIN rule_to rt ON (r.rule_id=rt.rule_id) + LEFT JOIN objgrp_flat of ON (rt.obj_id=of.objgrp_flat_id) + LEFT JOIN object o ON (of.objgrp_flat_member_id=o.obj_id) + WHERE NOT o.obj_ip='0.0.0.0/0'; + +drop VIEW if exists v_rule_with_rule_owner_1; +CREATE OR REPLACE VIEW v_rule_with_rule_owner_1 AS + SELECT DISTINCT r.rule_id, r.rule_uid, r.rule_name, r.mgm_id, r.rulebase_id, ow.id AS owner_id, met.rule_metadata_id + FROM v_active_access_allow_rules r + JOIN rule_metadata met ON r.rule_uid = met.rule_uid + JOIN rule_owner ro ON ro.rule_metadata_id = met.rule_metadata_id + JOIN owner ow ON ro.owner_id = ow.id; + +CREATE OR REPLACE VIEW v_rule_with_src_owner AS + SELECT + r.rule_id, ow.id as owner_id, ow.name as owner_name, + CASE + WHEN onw.ip = onw.ip_end + THEN SPLIT_PART(CAST(onw.ip AS VARCHAR), '/', 1) + ELSE + CASE WHEN + host(broadcast(inet_merge(onw.ip, onw.ip_end))) = host (onw.ip_end) AND + host(inet_merge(onw.ip, onw.ip_end)) = host (onw.ip) + THEN + text(inet_merge(onw.ip, onw.ip_end)) + ELSE + CONCAT(SPLIT_PART(onw.ip::VARCHAR,'/', 1), '-', SPLIT_PART(onw.ip_end::VARCHAR, '/', 1)) + END + END AS matching_ip, + 'source' AS match_in, + ow.recert_interval, max(rec.recert_date) AS rule_last_certified + FROM v_active_access_allow_rules r + LEFT JOIN rule_from ON (r.rule_id=rule_from.rule_id) + LEFT JOIN objgrp_flat of ON (rule_from.obj_id=of.objgrp_flat_id) + LEFT JOIN object o ON (of.objgrp_flat_member_id=o.obj_id) + LEFT JOIN owner_network onw ON (onw.ip_end >= o.obj_ip AND onw.ip <= o.obj_ip_end) + LEFT JOIN owner ow ON (onw.owner_id=ow.id) + LEFT JOIN rule_metadata met ON (r.rule_uid=met.rule_uid) + LEFT JOIN recertification rec ON (rec.rule_metadata_id = met.rule_metadata_id AND rec.owner_id = ow.id AND rec.recertified IS TRUE) + WHERE r.rule_id NOT IN (SELECT distinct rwo.rule_id FROM v_rule_with_rule_owner rwo) AND + CASE + when (select mode from v_rule_ownership_mode) = 'exclusive' then (NOT o.obj_ip IS NULL) AND o.obj_ip NOT IN (select * from v_excluded_src_ips) + else NOT o.obj_ip IS NULL + END + GROUP BY r.rule_id, o.obj_ip, o.obj_ip_end, onw.ip, onw.ip_end, ow.id, ow.name, ow.recert_interval; + +CREATE OR REPLACE VIEW v_rule_with_dst_owner AS + SELECT + r.rule_id, ow.id as owner_id, ow.name as owner_name, + CASE + WHEN onw.ip = onw.ip_end + THEN SPLIT_PART(CAST(onw.ip AS VARCHAR), '/', 1) + ELSE + CASE WHEN + host(broadcast(inet_merge(onw.ip, onw.ip_end))) = host (onw.ip_end) AND + host(inet_merge(onw.ip, onw.ip_end)) = host (onw.ip) + THEN + text(inet_merge(onw.ip, onw.ip_end)) + ELSE + CONCAT(SPLIT_PART(onw.ip::VARCHAR,'/', 1), '-', SPLIT_PART(onw.ip_end::VARCHAR, '/', 1)) + END + END AS matching_ip, + 'destination' AS match_in, + ow.recert_interval, max(rec.recert_date) AS rule_last_certified + FROM v_active_access_allow_rules r + LEFT JOIN rule_to rt ON (r.rule_id=rt.rule_id) + LEFT JOIN objgrp_flat of ON (rt.obj_id=of.objgrp_flat_id) + LEFT JOIN object o ON (of.objgrp_flat_member_id=o.obj_id) + LEFT JOIN owner_network onw ON (onw.ip_end >= o.obj_ip AND onw.ip <= o.obj_ip_end) + LEFT JOIN owner ow ON (onw.owner_id=ow.id) + LEFT JOIN rule_metadata met ON (r.rule_uid=met.rule_uid) + LEFT JOIN recertification rec ON (rec.rule_metadata_id = met.rule_metadata_id AND rec.owner_id = ow.id AND rec.recertified IS TRUE) + WHERE r.rule_id NOT IN (SELECT distinct rwo.rule_id FROM v_rule_with_rule_owner rwo) AND + CASE + when (select mode from v_rule_ownership_mode) = 'exclusive' then (NOT o.obj_ip IS NULL) AND o.obj_ip NOT IN (select * from v_excluded_dst_ips) + else NOT o.obj_ip IS NULL + END + GROUP BY r.rule_id, o.obj_ip, o.obj_ip_end, onw.ip, onw.ip_end, ow.id, ow.name, ow.recert_interval; + +CREATE OR REPLACE VIEW v_rule_with_ip_owner AS + SELECT DISTINCT uno.rule_id, uno.owner_id, uno.owner_name, + string_agg(DISTINCT match_in || ':' || matching_ip::VARCHAR, '; ' order by match_in || ':' || matching_ip::VARCHAR desc) as matches, + uno.recert_interval, uno.rule_last_certified + FROM ( SELECT DISTINCT * FROM v_rule_with_src_owner AS src UNION SELECT DISTINCT * FROM v_rule_with_dst_owner AS dst) AS uno + GROUP BY uno.rule_id, uno.owner_id, uno.owner_name, uno.recert_interval, uno.rule_last_certified; + +CREATE MATERIALIZED VIEW view_rule_with_owner AS + SELECT DISTINCT ar.rule_id, ar.owner_id, ar.owner_name, ar.matches, ar.recert_interval, ar.rule_last_certified, + r.rule_num_numeric, r.track_id, r.action_id, r.rule_from_zone, r.rule_to_zone, r.mgm_id, r.rule_uid, + r.rule_action, r.rule_name, r.rule_comment, r.rule_track, r.rule_src_neg, r.rule_dst_neg, r.rule_svc_neg, + r.rule_head_text, r.rule_disabled, r.access_rule, r.xlate_rule, r.nat_rule + FROM ( SELECT * FROM v_rule_with_rule_owner AS rul UNION SELECT * FROM v_rule_with_ip_owner AS ips) AS ar + LEFT JOIN rule AS r USING (rule_id); + +GRANT SELECT ON TABLE view_rule_with_owner TO GROUP secuadmins, reporters, configimporters; + +ALTER TABLE rule_metadata DROP COLUMN IF EXISTS "rulebase_id"; +ALTER TABLE rule_metadata DROP COLUMN IF EXISTS "dev_id"; +-- Remove rule_metadata.rule_last_modified and its constraint +ALTER TABLE IF EXISTS rule_metadata + DROP CONSTRAINT IF EXISTS rule_metadata_rule_last_modified_import_control_control_id_f_key CASCADE; + +ALTER TABLE IF EXISTS rule_metadata + DROP COLUMN IF EXISTS rule_last_modified; + + + +----------------------------------------------- +-- bulid rule-rulebase graph +-- rules may spawn rulebase children with new link table rulebase_link + +Create table IF NOT EXISTS "stm_link_type" +( + "id" SERIAL primary key, + "name" Varchar NOT NULL +); + +Create table IF NOT EXISTS "rulebase_link" +( + "id" SERIAL primary key, + "gw_id" Integer, + "from_rulebase_id" Integer, -- either from_rulebase_id or from_rule_id must be SET or the is_initial flag + "from_rule_id" BIGINT, + "to_rulebase_id" Integer NOT NULL, + "link_type" Integer, + "is_initial" BOOLEAN DEFAULT FALSE, + "is_global" BOOLEAN DEFAULT FALSE, + "is_section" BOOLEAN DEFAULT TRUE, + "created" BIGINT, + "removed" BIGINT +); + +-- only for developers who already have on old 9.0 database: +Alter table "rulebase_link" add column IF NOT EXISTS "is_initial" BOOLEAN; +Alter table "rulebase_link" add column IF NOT EXISTS "is_global" BOOLEAN; +Alter table "rulebase_link" add column IF NOT EXISTS "from_rulebase_id" Integer; +Alter table "rulebase_link" add column IF NOT EXISTS "is_section" BOOLEAN DEFAULT TRUE; + +DO $$ +BEGIN + IF EXISTS ( + SELECT 1 + FROM information_schema.columns + WHERE table_name = 'rulebase_link' + AND column_name = 'from_rule_id' + AND data_type = 'integer' + ) THEN + Alter table "rulebase_link" alter column "from_rule_id" TYPE bigint; + END IF; +END +$$; +--- + +Alter table "rulebase_link" drop constraint IF EXISTS "fk_rulebase_link_from_rulebase_id"; +Alter table "rulebase_link" add constraint "fk_rulebase_link_from_rulebase_id" foreign key ("from_rulebase_id") references "rulebase" ("id") on update restrict on delete cascade; +Alter table "rulebase_link" drop constraint IF EXISTS "fk_rulebase_link_to_rulebase_id"; +Alter table "rulebase_link" add constraint "fk_rulebase_link_to_rulebase_id" foreign key ("to_rulebase_id") references "rulebase" ("id") on update restrict on delete cascade; +Alter table "rulebase_link" drop constraint IF EXISTS "fk_rulebase_link_from_rule_id"; +Alter table "rulebase_link" add constraint "fk_rulebase_link_from_rule_id" foreign key ("from_rule_id") references "rule" ("rule_id") on update restrict on delete cascade; +Alter table "rulebase_link" drop constraint IF EXISTS "fk_rulebase_link_link_type"; +Alter table "rulebase_link" add constraint "fk_rulebase_link_link_type" foreign key ("link_type") references "stm_link_type" ("id") on update restrict on delete cascade; +Alter table "rulebase_link" drop constraint IF EXISTS "fk_rulebase_link_gw_id"; +Alter table "rulebase_link" add constraint "fk_rulebase_link_gw_id" foreign key ("gw_id") references "device" ("dev_id") on update restrict on delete cascade; +Alter table "rulebase_link" drop constraint IF EXISTS "unique_rulebase_link"; +Alter table "rulebase_link" add CONSTRAINT unique_rulebase_link + UNIQUE ( + "gw_id", + "from_rulebase_id", + "from_rule_id", + "to_rulebase_id", + "created" + ); + +ALTER TABLE "rulebase_link" + DROP CONSTRAINT IF EXISTS "fk_rulebase_link_created_import_control_control_id" CASCADE; +Alter table "rulebase_link" add CONSTRAINT fk_rulebase_link_created_import_control_control_id + foreign key ("created") references "import_control" ("control_id") on update restrict on delete cascade; +ALTER TABLE "rulebase_link" + DROP CONSTRAINT IF EXISTS "fk_rulebase_link_removed_import_control_control_id" CASCADE; +Alter table "rulebase_link" add CONSTRAINT fk_rulebase_link_removed_import_control_control_id + foreign key ("removed") references "import_control" ("control_id") on update restrict on delete cascade; + +insert into stm_link_type (id, name) VALUES (2, 'ordered') ON CONFLICT DO NOTHING; +insert into stm_link_type (id, name) VALUES (3, 'inline') ON CONFLICT DO NOTHING; +insert into stm_link_type (id, name) VALUES (4, 'concatenated') ON CONFLICT DO NOTHING; +insert into stm_link_type (id, name) VALUES (5, 'domain') ON CONFLICT DO NOTHING; +delete from stm_link_type where name in ('initial','global','local','section'); -- initial and global/local are additional flags now + +CREATE OR REPLACE FUNCTION deleteDuplicateRulebases() RETURNS VOID + LANGUAGE plpgsql + VOLATILE +AS $function$ + BEGIN + -- TODO: make sure that we have at least one rulebase for each device + DELETE FROM rule WHERE rulebase_id IS NULL; + END; +$function$; + +-- TODO: needs to be rewritten to rulebase_link + +CREATE OR REPLACE FUNCTION get_last_import_id_for_mgmt (INTEGER) RETURNS BIGINT AS $$ +DECLARE + i_mgm_id ALIAS FOR $1; -- ID des Managements + i_prev_import_id BIGINT; -- temp. Record +BEGIN + SELECT INTO i_prev_import_id MAX(control_id) FROM import_control WHERE mgm_id=i_mgm_id AND successful_import; + IF NOT FOUND THEN + RETURN NULL; + END IF; + RETURN i_prev_import_id; +END; +$$ LANGUAGE plpgsql; + +CREATE OR REPLACE FUNCTION addRuleEnforcedOnGatewayEntries() RETURNS VOID + LANGUAGE plpgsql + VOLATILE +AS $function$ + DECLARE + r_rulebase RECORD; + r_rule RECORD; + r_dev_null RECORD; + i_dev_id INTEGER; + a_all_dev_ids_of_rulebase INTEGER[]; + a_target_gateways VARCHAR[]; + v_gw_name VARCHAR; + BEGIN + FOR r_rulebase IN + SELECT * FROM rulebase + LOOP + -- collect all device ids for this rulebase + SELECT ARRAY( + SELECT gw_id FROM rulebase_link + WHERE to_rulebase_id=r_rulebase.id + ) INTO a_all_dev_ids_of_rulebase; + + FOR r_rule IN + SELECT rule_installon, rule_id FROM rule + LOOP + -- depending on install_on field: + -- add enry for all gateways of the management + -- or just add specific gateway entries + IF r_rule.rule_installon='Policy Targets' THEN + -- need to find out other platforms equivivalent keywords + FOREACH i_dev_id IN ARRAY a_all_dev_ids_of_rulebase + LOOP + INSERT INTO rule_enforced_on_gateway (rule_id, dev_id, created) + VALUES (r_rule.rule_id, i_dev_id, (SELECT * FROM get_last_import_id_for_mgmt(r_rulebase.mgm_id))); + END LOOP; + ELSE + -- need to deal with entries separately - split rule_installon field by '|' + IF r_rule.rule_installon IS NULL OR btrim(r_rule.rule_installon) = '' THEN + r_rule.rule_installon := 'Policy Targets'; + END IF; + SELECT ARRAY( + SELECT string_to_array(r_rule.rule_installon, '|') + ) INTO a_target_gateways; + FOREACH v_gw_name IN ARRAY a_target_gateways + LOOP + -- get dev_id for gw_name + SELECT INTO i_dev_id dev_id FROM device WHERE dev_name=v_gw_name; + IF FOUND THEN + INSERT INTO rule_enforced_on_gateway (rule_id, dev_id, created) + VALUES (r_rule.rule_id, i_dev_id, (SELECT * FROM get_last_import_id_for_mgmt(r_rulebase.mgm_id))); + ELSE + -- decide what to do with misses + END IF; + END LOOP; + END IF; + END LOOP; + END LOOP; + END; +$function$; + +CREATE OR REPLACE FUNCTION addMetadataRulebaseEntries() RETURNS VOID + LANGUAGE plpgsql + VOLATILE +AS $function$ + BEGIN + IF NOT EXISTS ( + SELECT 1 + FROM information_schema.columns + WHERE table_name = 'rule_metadata' + AND column_name = 'rulebase_id' + ) THEN + RETURN; + END IF; + + WITH rulebase_per_rule AS ( + SELECT rule_uid, mgm_id, MIN(rulebase_id) AS rulebase_id + FROM rule + WHERE rulebase_id IS NOT NULL + GROUP BY rule_uid, mgm_id + ) + UPDATE rule_metadata rm + SET rulebase_id = rbr.rulebase_id + FROM rulebase_per_rule rbr + WHERE rm.rule_uid = rbr.rule_uid + AND rm.mgm_id = rbr.mgm_id + AND rm.rulebase_id IS NULL; + -- now we can add the "not null" constraint for rule_metadata.rulebase_id + IF EXISTS ( + SELECT 1 + FROM information_schema.columns + WHERE table_name = 'rule_metadata' + AND column_name = 'rulebase_id' + AND is_nullable = 'YES' + ) THEN + ALTER TABLE rule_metadata + ALTER COLUMN rulebase_id SET NOT NULL; + END IF; + END; +$function$; + +CREATE OR REPLACE FUNCTION addRulebaseLinkEntries() RETURNS VOID + LANGUAGE plpgsql + VOLATILE +AS $function$ + DECLARE + r_dev RECORD; + r_dev_null RECORD; + i_rulebase_id INTEGER; + i_initial_rulebase_id INTEGER; + BEGIN + FOR r_dev IN + SELECT * FROM device + LOOP + -- find the id of the matching rulebase + SELECT INTO i_rulebase_id id FROM rulebase WHERE name=r_dev.local_rulebase_name AND mgm_id=r_dev.mgm_id; + -- check if rulebase_link already exists + IF i_rulebase_id IS NOT NULL THEN + SELECT INTO r_dev_null * FROM rulebase_link WHERE to_rulebase_id=i_rulebase_id AND gw_id=r_dev.dev_id AND removed IS NULL; + IF NOT FOUND THEN + INSERT INTO rulebase_link (gw_id, from_rule_id, to_rulebase_id, created, link_type, is_initial) + VALUES (r_dev.dev_id, NULL, i_rulebase_id, (SELECT * FROM get_last_import_id_for_mgmt(r_dev.mgm_id)), 2, True) + RETURNING id INTO i_initial_rulebase_id; -- when migrating, there cannot be more than one (the initial) rb per device + END IF; + END IF; + + -- global rulebase: + -- find the id of the matching rulebase + IF r_dev.global_rulebase_name IS NOT NULL THEN + SELECT INTO i_rulebase_id id FROM rulebase WHERE name=r_dev.global_rulebase_name AND mgm_id=r_dev.mgm_id; + -- check if rulebase_link already exists + IF i_rulebase_id IS NOT NULL THEN + SELECT INTO r_dev_null * FROM rulebase_link WHERE to_rulebase_id=i_rulebase_id AND gw_id=r_dev.dev_id; + IF NOT FOUND THEN + INSERT INTO rulebase_link (gw_id, from_rule_id, to_rulebase_id, created, link_type, is_initial) + VALUES (r_dev.dev_id, NULL, i_rulebase_id, (SELECT * FROM get_last_import_id_for_mgmt(r_dev.mgm_id)), 2, TRUE); + END IF; + END IF; + END IF; + END LOOP; + END; +$function$; + +CREATE OR REPLACE FUNCTION addRulebaseEntriesAndItsRuleRefs() RETURNS VOID + LANGUAGE plpgsql + VOLATILE +AS $function$ + DECLARE + r_dev RECORD; + r_rule RECORD; + r_dev_null RECORD; + i_new_rulebase_id INTEGER; + BEGIN + + FOR r_dev IN + SELECT * FROM device + LOOP + -- if rulebase does not exist yet: insert it + SELECT INTO r_dev_null * FROM rulebase WHERE name=r_dev.local_rulebase_name; + IF NOT FOUND AND r_dev.local_rulebase_name IS NOT NULL THEN + -- first create rulebase entries + INSERT INTO rulebase (name, uid, mgm_id, is_global, created) + VALUES (r_dev.local_rulebase_name, r_dev.local_rulebase_name, r_dev.mgm_id, FALSE, 1) + RETURNING id INTO i_new_rulebase_id; + -- now update references in all rules to the newly created rulebase + UPDATE rule SET rulebase_id=i_new_rulebase_id WHERE dev_id=r_dev.dev_id; + END IF; + + SELECT INTO r_dev_null * FROM rulebase WHERE name=r_dev.global_rulebase_name; + IF NOT FOUND AND r_dev.global_rulebase_name IS NOT NULL THEN + INSERT INTO rulebase (name, uid, mgm_id, is_global, created) + VALUES (r_dev.global_rulebase_name, r_dev.global_rulebase_name, r_dev.mgm_id, TRUE, 1) + RETURNING id INTO i_new_rulebase_id; + -- now update references in all rules to the newly created rulebase + UPDATE rule SET rulebase_id=i_new_rulebase_id WHERE dev_id=r_dev.dev_id; + -- add entries in rule_enforced_on_gateway + END IF; + END LOOP; + + -- now check for remaining rules without rulebase_id + -- TODO: decide how to deal with this - ONLY DUMMY SOLUTION FOR NOW + FOR r_rule IN + SELECT * FROM rule WHERE rulebase_id IS NULL + -- how do we deal with this? we simply pick the smallest rulebase id for now + LOOP + SELECT INTO i_new_rulebase_id id FROM rulebase ORDER BY id LIMIT 1; + UPDATE rule SET rulebase_id=i_new_rulebase_id WHERE rule_id=r_rule.rule_id; + END LOOP; + + -- now we can add the "not null" constraint for rule.rulebase_id + IF EXISTS ( + SELECT 1 + FROM information_schema.columns + WHERE table_name = 'rule' + AND column_name = 'rulebase_id' + AND is_nullable = 'YES' + ) THEN + ALTER TABLE rule + ALTER COLUMN rulebase_id SET NOT NULL; + END IF; + END; +$function$; + +-- in this migration, in scenarios where a rulebase is used on more than one gateway, +-- only the rules of the first gw get a rulebase_id, the others (copies) will be deleted +CREATE OR REPLACE FUNCTION migrateToRulebases() RETURNS VOID + LANGUAGE plpgsql + VOLATILE +AS $function$ + BEGIN + + PERFORM addRulebaseEntriesAndItsRuleRefs(); + PERFORM addRulebaseLinkEntries(); + -- danger zone: delete all rules that have no rulebase_id + -- the deletion might take some time + PERFORM deleteDuplicateRulebases(); + PERFORM addMetadataRulebaseEntries(); + -- add entries in rule_enforced_on_gateway + PERFORM addRuleEnforcedOnGatewayEntries(); + END; +$function$; + +-- end of rule_metadata migration + +ALTER TABLE IF EXISTS rule_metadata + ADD COLUMN IF NOT EXISTS removed BIGINT; + +ALTER TABLE IF EXISTS rule_metadata + DROP CONSTRAINT IF EXISTS rule_metadata_removed_import_control_control_id_f_key; + +ALTER TABLE IF EXISTS rule_metadata + ADD CONSTRAINT rule_metadata_removed_import_control_control_id_f_key + FOREIGN KEY (removed) REFERENCES import_control (control_id) + ON UPDATE RESTRICT ON DELETE RESTRICT; + +DO $$ +BEGIN + IF NOT EXISTS ( + SELECT 1 FROM rulebase_link LIMIT 1 + ) THEN + PERFORM migrateToRulebases(); + END IF; +END +$$; + +-- now we can set the new constraint on rule_uid: +Alter Table "rule" DROP Constraint IF EXISTS "rule_altkey"; +Alter Table "rule" DROP Constraint IF EXISTS "rule_unique_mgm_id_rule_uid_rule_create_xlate_rule"; +Alter Table "rule" ADD Constraint "rule_unique_mgm_id_rule_uid_rule_create_xlate_rule" UNIQUE ("mgm_id", "rule_uid","rule_create","xlate_rule"); + + +-- drop only after migration + +ALTER TABLE rule DROP CONSTRAINT IF EXISTS rule_dev_id_fkey; + +ALTER TABLE "rule_metadata" DROP CONSTRAINT IF EXISTS "rule_metadata_rulebase_id_f_key" CASCADE; +ALTER TABLE "rule_metadata" DROP CONSTRAINT IF EXISTS "unique_rule_metadata_rule_uid_mgm_id"; +ALTER TABLE "rule_metadata" ADD CONSTRAINT "unique_rule_metadata_rule_uid_mgm_id" UNIQUE ("rule_uid","mgm_id"); + +-- reverse last_seen / removed logic for objects +ALTER TABLE "object" ADD COLUMN IF NOT EXISTS "removed" BIGINT; +ALTER TABLE "objgrp" ADD COLUMN IF NOT EXISTS "removed" BIGINT; +ALTER TABLE "objgrp_flat" ADD COLUMN IF NOT EXISTS "removed" BIGINT; +ALTER TABLE "service" ADD COLUMN IF NOT EXISTS "removed" BIGINT; +ALTER TABLE "svcgrp" ADD COLUMN IF NOT EXISTS "removed" BIGINT; +ALTER TABLE "svcgrp_flat" ADD COLUMN IF NOT EXISTS "removed" BIGINT; +ALTER TABLE "zone" ADD COLUMN IF NOT EXISTS "removed" BIGINT; +ALTER TABLE "usr" ADD COLUMN IF NOT EXISTS "removed" BIGINT; +ALTER TABLE "usergrp" ADD COLUMN IF NOT EXISTS "removed" BIGINT; +ALTER TABLE "usergrp_flat" ADD COLUMN IF NOT EXISTS "removed" BIGINT; +ALTER TABLE "rule_from" ADD COLUMN IF NOT EXISTS "removed" BIGINT; +ALTER TABLE "rule_to" ADD COLUMN IF NOT EXISTS "removed" BIGINT; +ALTER TABLE "rule_service" ADD COLUMN IF NOT EXISTS "removed" BIGINT; +ALTER TABLE "rule_enforced_on_gateway" ADD COLUMN IF NOT EXISTS "removed" BIGINT; +ALTER TABLE "rulebase" ADD COLUMN IF NOT EXISTS "removed" BIGINT; +ALTER TABLE "rulebase_link" ADD COLUMN IF NOT EXISTS "removed" BIGINT; + +-- add obj type access-role for cp import +INSERT INTO stm_obj_typ (obj_typ_id,obj_typ_name) VALUES (21,'access-role') ON CONFLICT DO NOTHING; + +-- remove dev_id fk and set nullable if column exists +ALTER TABLE changelog_rule DROP CONSTRAINT IF EXISTS changelog_rule_dev_id_fkey; + +DO $$ +BEGIN + IF EXISTS ( + SELECT 1 + FROM information_schema.columns + WHERE table_name = 'changelog_rule' + AND column_name = 'dev_id' + ) THEN + ALTER TABLE changelog_rule ALTER COLUMN dev_id DROP NOT NULL; + END IF; +END +$$; + +-- add new compliance tables + +CREATE TABLE IF NOT EXISTS compliance.policy +( + id SERIAL PRIMARY KEY, + name TEXT, + created_date timestamp default now(), + disabled bool +); + +CREATE TABLE IF NOT EXISTS compliance.policy_criterion +( + policy_id INT NOT NULL, + criterion_id INT NOT NULL, + removed timestamp with time zone, + created timestamp with time zone default now() +); + +CREATE TABLE IF NOT EXISTS compliance.criterion +( + id SERIAL PRIMARY KEY, + name TEXT, + comment TEXT, + criterion_type TEXT, + content TEXT, + removed timestamp with time zone, + created timestamp with time zone default now(), + import_source TEXT +); + +CREATE TABLE IF NOT EXISTS compliance.violation +( + id BIGSERIAL PRIMARY KEY, + rule_id bigint NOT NULL, + found_date timestamp with time zone default now(), + removed_date timestamp with time zone, + details TEXT, + risk_score real, + policy_id INT NOT NULL, + criterion_id INT NOT NULL +); + +-- add columns in existing compliance tables + +ALTER TABLE compliance.network_zone ADD COLUMN IF NOT EXISTS "created" TIMESTAMP WITH TIME ZONE DEFAULT NOW(); +ALTER TABLE compliance.network_zone ADD COLUMN IF NOT EXISTS "removed" TIMESTAMP WITH TIME ZONE; +ALTER TABLE compliance.network_zone ADD COLUMN IF NOT EXISTS "criterion_id" INT; +ALTER TABLE compliance.network_zone ADD COLUMN IF NOT EXISTS "id_string" TEXT; +ALTER TABLE compliance.network_zone_communication ADD COLUMN IF NOT EXISTS "created" TIMESTAMP WITH TIME ZONE DEFAULT NOW(); +ALTER TABLE compliance.network_zone_communication ADD COLUMN IF NOT EXISTS "removed" TIMESTAMP WITH TIME ZONE; +ALTER TABLE compliance.network_zone_communication ADD COLUMN IF NOT EXISTS "criterion_id" INT; +ALTER TABLE compliance.ip_range ADD COLUMN IF NOT EXISTS "created" TIMESTAMP WITH TIME ZONE DEFAULT NOW(); +ALTER TABLE compliance.ip_range ADD COLUMN IF NOT EXISTS "removed" TIMESTAMP WITH TIME ZONE; +ALTER TABLE compliance.ip_range ADD COLUMN IF NOT EXISTS "criterion_id" INT; +ALTER TABLE compliance.ip_range ADD COLUMN IF NOT EXISTS "name" TEXT; + +-- tables altered inside this version + +ALTER TABLE compliance.criterion ADD COLUMN IF NOT EXISTS "created" TIMESTAMP WITH TIME ZONE DEFAULT NOW(); +ALTER TABLE compliance.criterion ADD COLUMN IF NOT EXISTS "removed" TIMESTAMP WITH TIME ZONE; +ALTER TABLE compliance.criterion ADD COLUMN IF NOT EXISTS "import_source" TEXT; +ALTER TABLE compliance.criterion ADD COLUMN IF NOT EXISTS "comment" TEXT; +ALTER TABLE compliance.network_zone ALTER COLUMN "removed" DROP DEFAULT; +ALTER TABLE compliance.network_zone ADD COLUMN IF NOT EXISTS "is_auto_calculated_internet_zone" BOOLEAN DEFAULT FALSE; +ALTER TABLE compliance.network_zone ADD COLUMN IF NOT EXISTS "is_auto_calculated_undefined_internal_zone" BOOLEAN DEFAULT FALSE; +ALTER TABLE compliance.network_zone_communication ALTER COLUMN "removed" DROP DEFAULT; +ALTER TABLE compliance.ip_range ALTER COLUMN "removed" DROP DEFAULT; +ALTER TABLE compliance.policy_criterion ALTER COLUMN "removed" DROP DEFAULT; +ALTER TABLE compliance.violation ALTER COLUMN "removed_date" DROP DEFAULT; +ALTER TABLE compliance.violation ALTER COLUMN "found_date" TYPE TIMESTAMP WITH TIME ZONE; -- takes local timezone. can be set wxplicitly by "USING found_date AT TIME ZONE 'UTC'"; + +-- alter ip_range's PK + +ALTER TABLE compliance.ip_range DROP CONSTRAINT IF EXISTS ip_range_pkey; +ALTER TABLE compliance.ip_range +ADD CONSTRAINT ip_range_pkey +PRIMARY KEY (network_zone_id, ip_range_start, ip_range_end, created); + +-- add FKs + +ALTER TABLE compliance.network_zone +DROP CONSTRAINT IF EXISTS compliance_criterion_network_zone_foreign_key; +ALTER TABLE compliance.network_zone +ADD CONSTRAINT compliance_criterion_network_zone_foreign_key +FOREIGN KEY (criterion_id) REFERENCES compliance.criterion(id) +ON UPDATE RESTRICT ON DELETE CASCADE; + +ALTER TABLE compliance.ip_range +DROP CONSTRAINT IF EXISTS compliance_criterion_ip_range_foreign_key; +ALTER TABLE compliance.ip_range +ADD CONSTRAINT compliance_criterion_ip_range_foreign_key +FOREIGN KEY (criterion_id) REFERENCES compliance.criterion(id) +ON UPDATE RESTRICT ON DELETE CASCADE; + +ALTER TABLE compliance.network_zone_communication +DROP CONSTRAINT IF EXISTS compliance_criterion_network_zone_communication_foreign_key; +ALTER TABLE compliance.network_zone_communication +ADD CONSTRAINT compliance_criterion_network_zone_communication_foreign_key +FOREIGN KEY (criterion_id) REFERENCES compliance.criterion(id) +ON UPDATE RESTRICT ON DELETE CASCADE; + +ALTER TABLE compliance.policy_criterion +DROP CONSTRAINT IF EXISTS compliance_policy_policy_criterion_foreign_key; +ALTER TABLE compliance.policy_criterion +ADD CONSTRAINT compliance_policy_policy_criterion_foreign_key +FOREIGN KEY (policy_id) REFERENCES compliance.policy(id) +ON UPDATE RESTRICT ON DELETE CASCADE; + +ALTER TABLE compliance.policy_criterion +DROP CONSTRAINT IF EXISTS compliance_criterion_policy_criterion_foreign_key; +ALTER TABLE compliance.policy_criterion +ADD CONSTRAINT compliance_criterion_policy_criterion_foreign_key +FOREIGN KEY (criterion_id) REFERENCES compliance.criterion(id) +ON UPDATE RESTRICT ON DELETE CASCADE; + +ALTER TABLE compliance.violation +DROP CONSTRAINT IF EXISTS compliance_policy_violation_foreign_key; +ALTER TABLE compliance.violation +ADD CONSTRAINT compliance_policy_violation_foreign_key +FOREIGN KEY (policy_id) REFERENCES compliance.policy(id) +ON UPDATE RESTRICT ON DELETE CASCADE; + +ALTER TABLE compliance.violation +DROP CONSTRAINT IF EXISTS compliance_criterion_violation_foreign_key; +ALTER TABLE compliance.violation +ADD CONSTRAINT compliance_criterion_violation_foreign_key +FOREIGN KEY (criterion_id) REFERENCES compliance.criterion(id) +ON UPDATE RESTRICT ON DELETE CASCADE; + +ALTER TABLE compliance.violation +DROP CONSTRAINT IF EXISTS compliance_rule_violation_foreign_key; +ALTER TABLE compliance.violation +ADD CONSTRAINT compliance_rule_violation_foreign_key +FOREIGN KEY (rule_id) REFERENCES public.rule(rule_id) +ON UPDATE RESTRICT ON DELETE CASCADE; + +-- add report type Compliance + +UPDATE config SET config_value = '[1,2,3,4,5,6,7,8,9,10,21,22,31,32]' WHERE config_key = 'availableReportTypes'; + +--- prevent overlapping active ip address ranges in the same zone +ALTER TABLE compliance.ip_range DROP CONSTRAINT IF EXISTS exclude_overlapping_ip_ranges; +ALTER TABLE compliance.ip_range ADD CONSTRAINT exclude_overlapping_ip_ranges +EXCLUDE USING gist ( + network_zone_id WITH =, + numrange(ip_range_start - '0.0.0.0'::inet, ip_range_end - '0.0.0.0'::inet, '[]') WITH && +) +WHERE (removed IS NULL); + +-- add config parameter debugConfig if not exists + +INSERT INTO config (config_key, config_value, config_user) +VALUES ('debugConfig', '{"debugLevel":8, "extendedLogComplianceCheck":true, "extendedLogReportGeneration":true, "extendedLogScheduler":true}', 0) +ON CONFLICT (config_key, config_user) DO NOTHING; + +-- add config parameter complianceCheckPolicy if not exists + +INSERT INTO config (config_key, config_value, config_user) +VALUES ('complianceCheckPolicy', '0', 0) +ON CONFLICT (config_key, config_user) DO NOTHING; + +-- add management and rule uids to table violation + +ALTER TABLE compliance.violation ADD COLUMN IF NOT EXISTS rule_uid TEXT; +ALTER TABLE compliance.violation ADD COLUMN IF NOT EXISTS mgmt_uid TEXT; +ALTER TABLE compliance.violation ADD COLUMN IF NOT EXISTS is_initial BOOLEAN; + +-- add unique constraint for report_template_name + +DO $$ +BEGIN + IF NOT EXISTS ( + SELECT 1 + FROM pg_constraint + WHERE conname = 'unique_report_template_name' + ) THEN + ALTER TABLE report_template + ADD CONSTRAINT unique_report_template_name UNIQUE (report_template_name); + END IF; +END$$; + +-- add new report template for compliance: unresolved violations + +INSERT INTO "report_template" ("report_filter","report_template_name","report_template_comment","report_template_owner", "report_parameters") + VALUES ('action=accept', + 'Compliance: Unresolved violations','T0108', 0, + '{"report_type":31,"device_filter":{"management":[]}, + "time_filter": { + "is_shortcut": true, + "shortcut": "now", + "report_time": "2022-01-01T00:00:00.0000000+01:00", + "timerange_type": "SHORTCUT", + "shortcut_range": "this year", + "offset": 0, + "interval": "DAYS", + "start_time": "2022-01-01T00:00:00.0000000+01:00", + "end_time": "2022-01-01T00:00:00.0000000+01:00", + "open_start": false, + "open_end": false}, + "compliance_filter": { + "diff_reference_in_days": 0, + "show_non_impact_rules": true}}') +ON CONFLICT (report_template_name) DO NOTHING; + +-- add new report template for compliance: diffs + +INSERT INTO "report_template" ("report_filter","report_template_name","report_template_comment","report_template_owner", "report_parameters") + VALUES ('action=accept', + 'Compliance: Diffs','T0109', 0, + '{"report_type":32,"device_filter":{"management":[]}, + "time_filter": { + "is_shortcut": true, + "shortcut": "now", + "report_time": "2022-01-01T00:00:00.0000000+01:00", + "timerange_type": "SHORTCUT", + "shortcut_range": "this year", + "offset": 0, + "interval": "DAYS", + "start_time": "2022-01-01T00:00:00.0000000+01:00", + "end_time": "2022-01-01T00:00:00.0000000+01:00", + "open_start": false, + "open_end": false}, + "compliance_filter": { + "diff_reference_in_days": 7, + "show_non_impact_rules": false}}') +ON CONFLICT (report_template_name) DO NOTHING; + +-- add parameter to limit number of printed violations in compliance report to config + +INSERT INTO config (config_key, config_value, config_user) +VALUES ('complianceCheckMaxPrintedViolations', '0', 0) +ON CONFLICT (config_key, config_user) DO NOTHING; + +-- add parameter to persist report scheduler configs to config + +INSERT INTO config (config_key, config_value, config_user) +VALUES ('reportSchedulerConfig', '', 0) +ON CONFLICT (config_key, config_user) DO NOTHING; + +-- add parameter to choose order by column of network matrix between name and id + +INSERT INTO config (config_key, config_value, config_user) +VALUES ('complianceCheckSortMatrixByID', 'false', 0) +ON CONFLICT (config_key, config_user) DO NOTHING; + +-- internal zone parameters + +INSERT INTO config (config_key, config_value, config_user) VALUES ('internalZoneRange_10_0_0_0_8', 'true', 0) ON CONFLICT (config_key, config_user) DO NOTHING; +INSERT INTO config (config_key, config_value, config_user) VALUES ('internalZoneRange_172_16_0_0_12', 'true', 0) ON CONFLICT (config_key, config_user) DO NOTHING; +INSERT INTO config (config_key, config_value, config_user) VALUES ('internalZoneRange_192_168_0_0_16', 'true', 0) ON CONFLICT (config_key, config_user) DO NOTHING; +INSERT INTO config (config_key, config_value, config_user) VALUES ('internalZoneRange_0_0_0_0_8', 'true', 0) ON CONFLICT (config_key, config_user) DO NOTHING; +INSERT INTO config (config_key, config_value, config_user) VALUES ('internalZoneRange_127_0_0_0_8', 'true', 0) ON CONFLICT (config_key, config_user) DO NOTHING; +INSERT INTO config (config_key, config_value, config_user) VALUES ('internalZoneRange_169_254_0_0_16', 'true', 0) ON CONFLICT (config_key, config_user) DO NOTHING; +INSERT INTO config (config_key, config_value, config_user) VALUES ('internalZoneRange_224_0_0_0_4', 'true', 0) ON CONFLICT (config_key, config_user) DO NOTHING; +INSERT INTO config (config_key, config_value, config_user) VALUES ('internalZoneRange_240_0_0_0_4', 'true', 0) ON CONFLICT (config_key, config_user) DO NOTHING; +INSERT INTO config (config_key, config_value, config_user) VALUES ('internalZoneRange_255_255_255_255_32', 'true', 0) ON CONFLICT (config_key, config_user) DO NOTHING; +INSERT INTO config (config_key, config_value, config_user) VALUES ('internalZoneRange_192_0_2_0_24', 'true', 0) ON CONFLICT (config_key, config_user) DO NOTHING; +INSERT INTO config (config_key, config_value, config_user) VALUES ('internalZoneRange_198_51_100_0_24', 'true', 0) ON CONFLICT (config_key, config_user) DO NOTHING; +INSERT INTO config (config_key, config_value, config_user) VALUES ('internalZoneRange_203_0_113_0_24', 'true', 0) ON CONFLICT (config_key, config_user) DO NOTHING; +INSERT INTO config (config_key, config_value, config_user) VALUES ('internalZoneRange_100_64_0_0_10', 'true', 0) ON CONFLICT (config_key, config_user) DO NOTHING; +INSERT INTO config (config_key, config_value, config_user) VALUES ('internalZoneRange_192_0_0_0_24', 'true', 0) ON CONFLICT (config_key, config_user) DO NOTHING; +INSERT INTO config (config_key, config_value, config_user) VALUES ('internalZoneRange_192_88_99_0_24', 'true', 0) ON CONFLICT (config_key, config_user) DO NOTHING; +INSERT INTO config (config_key, config_value, config_user) VALUES ('internalZoneRange_198_18_0_0_15', 'true', 0) ON CONFLICT (config_key, config_user) DO NOTHING; + +-- auto calculate special zone parameters + +INSERT INTO config (config_key, config_value, config_user) +VALUES ('autoCalculateInternetZone', 'true', 0) +ON CONFLICT (config_key, config_user) DO NOTHING; + +INSERT INTO config (config_key, config_value, config_user) +VALUES ('autoCalculateUndefinedInternalZone', 'true', 0) +ON CONFLICT (config_key, config_user) DO NOTHING; + +INSERT INTO config (config_key, config_value, config_user) +VALUES ('autoCalculatedZonesAtTheEnd', 'true', 0) +ON CONFLICT (config_key, config_user) DO NOTHING; + +INSERT INTO config (config_key, config_value, config_user) +VALUES ('treatDynamicAndDomainObjectsAsInternet', 'true', 0) +ON CONFLICT (config_key, config_user) DO NOTHING; + +INSERT INTO config (config_key, config_value, config_user) +VALUES ('showShortColumnsInComplianceReports', 'true', 0) +ON CONFLICT (config_key, config_user) DO NOTHING; + +INSERT INTO config (config_key, config_value, config_user) +VALUES ('autoCalculatedZonesAtTheEnd', 'true', 0) +ON CONFLICT (config_key, config_user) DO NOTHING; + +INSERT INTO config (config_key, config_value, config_user) +VALUES ('treatDynamicAndDomainObjectsAsInternet', 'true', 0) +ON CONFLICT (config_key, config_user) DO NOTHING; + +INSERT INTO config (config_key, config_value, config_user) +VALUES ('showShortColumnsInComplianceReports', 'true', 0) +ON CONFLICT (config_key, config_user) DO NOTHING; + +-- set deprecated field rule_num to 0 for all rules to avoid inconsistencies +UPDATE rule SET rule_num = 0 WHERE rule_num <> 0;; + +-- add config value to make imported matrices editable + +INSERT INTO config (config_key, config_value, config_user) +VALUES ('importedMatrixReadOnly', 'true', 0) +ON CONFLICT (config_key, config_user) DO NOTHING; + +-- add config values to make parallelization in compliance check configurable + +INSERT INTO config (config_key, config_value, config_user) +VALUES ('complianceCheckElementsPerFetch', '500', 0) +ON CONFLICT (config_key, config_user) DO NOTHING; + +INSERT INTO config (config_key, config_value, config_user) +VALUES ('complianceCheckAvailableProcessors', '4', 0) +ON CONFLICT (config_key, config_user) DO NOTHING; + +-- add crosstabulations rules with zone for source and destination + +--crosstabulation rule zone for source +Create table IF NOT EXISTS "rule_from_zone" +( + "rule_id" BIGINT NOT NULL, + "zone_id" Integer NOT NULL, + "created" BIGINT NOT NULL, + "removed" BIGINT, + primary key (rule_id, zone_id, created) +); + +--crosstabulation rule zone for destination +Create table IF NOT EXISTS "rule_to_zone" +( + "rule_id" BIGINT NOT NULL, + "zone_id" Integer NOT NULL, + "created" BIGINT NOT NULL, + "removed" BIGINT, + primary key (rule_id, zone_id, created) +); + +--crosstabulation rule zone for destination FKs +ALTER TABLE "rule_to_zone" +DROP CONSTRAINT IF EXISTS fk_rule_to_zone_rule_id_rule_rule_id; +ALTER TABLE "rule_to_zone" +DROP CONSTRAINT IF EXISTS fk_rule_to_zone_zone_id_zone_zone_id; + +ALTER TABLE "rule_to_zone" +ADD CONSTRAINT fk_rule_to_zone_rule_id_rule_rule_id FOREIGN KEY ("rule_id") REFERENCES "rule" ("rule_id") ON UPDATE RESTRICT ON DELETE CASCADE; +ALTER TABLE "rule_to_zone" +ADD CONSTRAINT fk_rule_to_zone_zone_id_zone_zone_id FOREIGN KEY ("zone_id") REFERENCES "zone" ("zone_id") ON UPDATE RESTRICT ON DELETE CASCADE; + +--crosstabulation rule zone for source FKs +ALTER TABLE "rule_from_zone" +DROP CONSTRAINT IF EXISTS fk_rule_from_zone_rule_id_rule_rule_id; +ALTER TABLE "rule_from_zone" +DROP CONSTRAINT IF EXISTS fk_rule_from_zone_zone_id_zone_zone_id; + +ALTER TABLE "rule_from_zone" +ADD CONSTRAINT fk_rule_from_zone_rule_id_rule_rule_id FOREIGN KEY ("rule_id") REFERENCES "rule" ("rule_id") ON UPDATE RESTRICT ON DELETE CASCADE; +ALTER TABLE "rule_from_zone" +ADD CONSTRAINT fk_rule_from_zone_zone_id_zone_zone_id FOREIGN KEY ("zone_id") REFERENCES "zone" ("zone_id") ON UPDATE RESTRICT ON DELETE CASCADE; + + +-- initial fill script for rule_from_zones and rule_to_zones +DO $$ +DECLARE + inserted_source INT := 0; + inserted_destination INT := 0; + remaining_source INT:= 0; + remaining_destination INT:= 0; + col_exists_source BOOLEAN; + col_exists_destination BOOLEAN; + count_from_zone_in_rule_after_update INT:= 0; + count_to_zone_in_rule_after_update INT:= 0; + +BEGIN + -- Check column rule_from_zone exists + SELECT EXISTS ( + SELECT 1 + FROM information_schema.columns + WHERE table_name='rule' + AND column_name='rule_from_zone' + ) INTO col_exists_source; + + -- Check column rule_to_zone exists + SELECT EXISTS ( + SELECT 1 + FROM information_schema.columns + WHERE table_name='rule' + AND column_name='rule_to_zone' + ) INTO col_exists_destination; + + IF col_exists_source AND NOT EXISTS (SELECT 1 FROM rule_from_zone) THEN + INSERT INTO rule_from_zone (rule_id, zone_id, created, removed) + SELECT rule_id, rule_from_zone, rule_create, removed + FROM rule + WHERE rule_from_zone IS NOT NULL; + GET DIAGNOSTICS inserted_source = ROW_COUNT; + + -- Count the existing rule_from_zone and rule_to_zone + SELECT COUNT(*) INTO remaining_source + FROM rule + WHERE rule_from_zone IS NOT NULL; + + ELSE + -- RAISE NOTICE 'Table does not exist or is not empty'; + END IF; + + IF col_exists_destination AND NOT EXISTS (SELECT 1 FROM rule_to_zone) THEN + INSERT INTO rule_to_zone (rule_id, zone_id, created, removed) + SELECT rule_id, rule_to_zone, rule_create, removed + FROM rule + WHERE rule_to_zone IS NOT NULL; + GET DIAGNOSTICS inserted_destination = ROW_COUNT; + + -- Count the existing rule_from_zone and rule_to_zone + SELECT COUNT(*) INTO remaining_destination + FROM rule + WHERE rule_to_zone IS NOT NULL; + + ELSE + -- RAISE NOTICE 'Table does not exist or is not empty'; + END IF; + + IF (col_exists_source OR col_exists_destination) AND + (remaining_source + remaining_destination = inserted_source + inserted_destination) Then + UPDATE rule + SET rule_from_zone = NULL, + rule_to_zone = NULL + WHERE rule_from_zone IS NOT NULL + OR rule_to_zone IS NOT NULL; + END IF; + + IF (col_exists_source OR col_exists_destination) Then + SELECT COUNT(*) INTO count_from_zone_in_rule_after_update FROM rule WHERE rule_from_zone IS NOT NULL; + SELECT COUNT(*) INTO count_to_zone_in_rule_after_update FROM rule WHERE rule_to_zone IS NOT NULL; + + IF count_from_zone_in_rule_after_update > 0 OR count_to_zone_in_rule_after_update > 0 THEN + RAISE EXCEPTION 'Cannot drop columns: non-null values remain (from_zone: %, to_zone: %)', count_from_zone_in_rule_after_update, count_to_zone_in_rule_after_update; + END IF; + + END IF; +END +$$; + + +insert into stm_dev_typ (dev_typ_id,dev_typ_name,dev_typ_version,dev_typ_manufacturer,dev_typ_predef_svc,dev_typ_is_multi_mgmt,dev_typ_is_mgmt,is_pure_routing_device) + VALUES (28,'Cisco Asa','9','Cisco','',false,true,false) + ON CONFLICT (dev_typ_id) DO NOTHING; + +insert into stm_dev_typ (dev_typ_id,dev_typ_name,dev_typ_version,dev_typ_manufacturer,dev_typ_predef_svc,dev_typ_is_multi_mgmt,dev_typ_is_mgmt,is_pure_routing_device) + VALUES (29,'Cisco Asa on FirePower','9','Cisco','',false,true,false) + ON CONFLICT (dev_typ_id) DO NOTHING; + +-- Set stm* tables hardcoded only - no Serial - stm_color filled via csv +ALTER TABLE stm_link_type ALTER COLUMN id DROP DEFAULT; +ALTER TABLE stm_track ALTER COLUMN track_id DROP DEFAULT; +ALTER TABLE stm_obj_typ ALTER COLUMN obj_typ_id DROP DEFAULT; +ALTER TABLE stm_change_type ALTER COLUMN change_type_id DROP DEFAULT; +ALTER TABLE stm_action ALTER COLUMN action_id DROP DEFAULT; +ALTER TABLE stm_dev_typ ALTER COLUMN dev_typ_id DROP DEFAULT; +ALTER TABLE parent_rule_type ALTER COLUMN id DROP DEFAULT; + +-- Drop Sequence +DROP SEQUENCE IF EXISTS public.stm_link_type_id_seq; +DROP SEQUENCE IF EXISTS public.stm_track_track_id_seq; +DROP SEQUENCE IF EXISTS public.stm_obj_typ_obj_typ_id_seq; +DROP SEQUENCE IF EXISTS public.stm_change_type_change_type_id_seq; +DROP SEQUENCE IF EXISTS public.stm_action_action_id_seq; +DROP SEQUENCE IF EXISTS public.stm_dev_typ_dev_typ_id_seq; +DROP SEQUENCE IF EXISTS public.parent_rule_type_id_seq; + +-- drop old mgm_id, zone_name constraint +ALTER TABLE zone DROP CONSTRAINT IF EXISTS "Alter_Key10"; + +-- add new mgm_id, zone_name constraint where just one with removed is null allowed +CREATE UNIQUE INDEX if not exists "zone_mgm_id_zone_name_removed_is_null_unique" ON zone (mgm_id, zone_name) WHERE removed IS NULL; + +-- normalize owner responsibles into separate table and enhance it +CREATE TABLE IF NOT EXISTS owner_responsible +( + id SERIAL PRIMARY KEY, + owner_id int NOT NULL, + dn Varchar NOT NULL, + responsible_type int NOT NULL +); + +-- revert older first throw +ALTER TABLE owner_responsible DROP COLUMN IF EXISTS roles; + +DO $$ +BEGIN + IF ( + SELECT COUNT(*) + FROM information_schema.columns + WHERE table_name='owner' AND column_name='owner_responsible1' + ) > 0 THEN + INSERT INTO owner_responsible (owner_id, dn, responsible_type) + SELECT owner.id, dn, 1 + FROM owner, unnest(owner_responsible1) AS dn + LEFT JOIN owner_responsible r + ON r.owner_id = owner.id AND r.dn = dn AND r.responsible_type = 1 + WHERE NULLIF(dn, '') IS NOT NULL + AND r.owner_id IS NULL; + ALTER TABLE owner DROP COLUMN owner_responsible1; + END IF; + + IF ( + SELECT COUNT(*) + FROM information_schema.columns + WHERE table_name='owner' AND column_name='owner_responsible2' + ) > 0 THEN + INSERT INTO owner_responsible (owner_id, dn, responsible_type) + SELECT owner.id, dn, 2 + FROM owner, unnest(owner_responsible2) AS dn + LEFT JOIN owner_responsible r + ON r.owner_id = owner.id AND r.dn = dn AND r.responsible_type = 2 + WHERE NULLIF(dn, '') IS NOT NULL + AND r.owner_id IS NULL; + ALTER TABLE owner DROP COLUMN owner_responsible2; + END IF; + + IF ( + SELECT COUNT(*) + FROM information_schema.columns + WHERE table_name='owner' AND column_name='owner_responsible3' + ) > 0 THEN + INSERT INTO owner_responsible (owner_id, dn, responsible_type) + SELECT owner.id, dn, 3 + FROM owner, unnest(owner_responsible3) AS dn + LEFT JOIN owner_responsible r + ON r.owner_id = owner.id AND r.dn = dn AND r.responsible_type = 3 + WHERE NULLIF(dn, '') IS NOT NULL + AND r.owner_id IS NULL; + ALTER TABLE owner DROP COLUMN owner_responsible3; + END IF; + + IF ( + SELECT COUNT(*) + FROM information_schema.columns + WHERE table_name='owner' AND column_name='dn' + ) > 0 THEN + INSERT INTO owner_responsible (owner_id, dn, responsible_type) + SELECT owner.id, owner.dn, 1 + FROM owner + LEFT JOIN owner_responsible r + ON r.owner_id = owner.id AND r.dn = owner.dn AND r.responsible_type = 1 + WHERE NULLIF(owner.dn, '') IS NOT NULL + AND r.owner_id IS NULL; + ALTER TABLE owner DROP COLUMN dn; + END IF; + + IF ( + SELECT COUNT(*) + FROM information_schema.columns + WHERE table_name='owner' AND column_name='group_dn' + ) > 0 THEN + INSERT INTO owner_responsible (owner_id, dn, responsible_type) + SELECT owner.id, owner.group_dn, 2 + FROM owner + LEFT JOIN owner_responsible r + ON r.owner_id = owner.id AND r.dn = owner.group_dn AND r.responsible_type = 2 + WHERE NULLIF(owner.group_dn, '') IS NOT NULL + AND r.owner_id IS NULL; + ALTER TABLE owner DROP COLUMN group_dn; + END IF; +END$$; + +DO $$ +BEGIN + IF ( + SELECT COUNT(*) + FROM pg_constraint + WHERE conname = 'owner_responsible_owner_foreign_key' + ) = 0 THEN + ALTER TABLE owner_responsible + ADD CONSTRAINT owner_responsible_owner_foreign_key + FOREIGN KEY (owner_id) REFERENCES owner(id) ON UPDATE RESTRICT ON DELETE CASCADE; + END IF; +END$$; + +CREATE UNIQUE INDEX IF NOT EXISTS owner_responsible_owner_dn_type_unique ON owner_responsible(owner_id, dn, responsible_type); +CREATE INDEX IF NOT EXISTS owner_responsible_dn_idx ON owner_responsible(dn); + +-- Changing primary key of *_resolved tables to include created timestamp +-- This is necessary to store multiple resolutions for the same object/rule over time +ALTER TABLE "rule_nwobj_resolved" DROP CONSTRAINT IF EXISTS "rule_nwobj_resolved_pkey"; +ALTER TABLE "rule_nwobj_resolved" ADD PRIMARY KEY ("mgm_id", "rule_id", "obj_id", "created"); +ALTER TABLE "rule_svc_resolved" DROP CONSTRAINT IF EXISTS "rule_svc_resolved_pkey"; +ALTER TABLE "rule_svc_resolved" ADD PRIMARY KEY ("mgm_id", "rule_id", "svc_id", "created"); +ALTER TABLE "rule_user_resolved" DROP CONSTRAINT IF EXISTS "rule_user_resolved_pkey"; +ALTER TABLE "rule_user_resolved" ADD PRIMARY KEY ("mgm_id", "rule_id", "user_id", "created"); + +-- rule_to_zone +ALTER TABLE "rule_to_zone" +DROP CONSTRAINT IF EXISTS fk_rule_to_zone_rule_id_rule_rule_id; + +ALTER TABLE "rule_to_zone" +ADD CONSTRAINT fk_rule_to_zone_rule_id_rule_rule_id +FOREIGN KEY ("rule_id") REFERENCES "rule" ("rule_id") +ON UPDATE RESTRICT +ON DELETE CASCADE; + +ALTER TABLE "rule_to_zone" +DROP CONSTRAINT IF EXISTS fk_rule_to_zone_zone_id_zone_zone_id; + +ALTER TABLE "rule_to_zone" +ADD CONSTRAINT fk_rule_to_zone_zone_id_zone_zone_id +FOREIGN KEY ("zone_id") REFERENCES "zone" ("zone_id") +ON UPDATE RESTRICT +ON DELETE CASCADE; + +-- rule_from_zone +ALTER TABLE "rule_from_zone" +DROP CONSTRAINT IF EXISTS fk_rule_from_zone_rule_id_rule_rule_id; + +ALTER TABLE "rule_from_zone" +ADD CONSTRAINT fk_rule_from_zone_rule_id_rule_rule_id +FOREIGN KEY ("rule_id") REFERENCES "rule" ("rule_id") +ON UPDATE RESTRICT +ON DELETE CASCADE; + +ALTER TABLE "rule_from_zone" +DROP CONSTRAINT IF EXISTS fk_rule_from_zone_zone_id_zone_zone_id; + +ALTER TABLE "rule_from_zone" +ADD CONSTRAINT fk_rule_from_zone_zone_id_zone_zone_id +FOREIGN KEY ("zone_id") REFERENCES "zone" ("zone_id") +ON UPDATE RESTRICT +ON DELETE CASCADE; + +DROP FUNCTION IF EXISTS get_last_import_id_for_mgmt(INTEGER); diff --git a/roles/database/tasks/create-ro-user.yml b/roles/database/tasks/create-ro-user.yml new file mode 100644 index 0000000000..d971636257 --- /dev/null +++ b/roles/database/tasks/create-ro-user.yml @@ -0,0 +1,27 @@ +# add db ro user and assign privileges + +- block: + + - name: create {{ fwo_db_ro_user }} + postgresql_user: + name: "{{ fwo_db_ro_user }}" + role_attr_flags: LOGIN,NOSUPERUSER,INHERIT,NOCREATEDB,NOCREATEROLE + + - name: GRANT ro user + postgresql_query: + db: "{{ fworch_db_name }}" + query: GRANT CONNECT ON DATABASE {{ fworch_db_name }} TO {{ fwo_db_ro_user }} + + - name: GRANT ro user all access to schemata + postgresql_query: + db: "{{ fworch_db_name }}" + query: | + GRANT USAGE ON SCHEMA {{ item }} TO {{ fwo_db_ro_user }}; + GRANT SELECT ON ALL TABLES IN SCHEMA {{ item }} TO {{ fwo_db_ro_user }}; + GRANT USAGE, SELECT ON ALL SEQUENCES IN SCHEMA {{ item }} TO {{ fwo_db_ro_user }}; + ALTER DEFAULT PRIVILEGES IN SCHEMA {{ item }} GRANT SELECT ON TABLES TO {{ fwo_db_ro_user }}; + ALTER DEFAULT PRIVILEGES IN SCHEMA {{ item }} GRANT USAGE, SELECT ON SEQUENCES TO {{ fwo_db_ro_user }}; + loop: "{{ db_schemata }}" + + become: true + become_user: postgres diff --git a/roles/database/tasks/create-users.yml b/roles/database/tasks/create-users.yml index 8572edff8a..7a484da4f6 100755 --- a/roles/database/tasks/create-users.yml +++ b/roles/database/tasks/create-users.yml @@ -1,32 +1,27 @@ -# add db users and assign groups - -- block: - - - name: create db groups - postgresql_user: - name: "{{ item }}" - loop: "{{ database_groups }}" - - - name: create db users - postgresql_user: - name: "{{ item }}" - role_attr_flags: LOGIN,NOSUPERUSER,INHERIT,NOCREATEDB,NOCREATEROLE - loop: "{{ database_users }}" - - - name: add user dbbackup to group dbbackupusers - postgresql_query: - db: "{{ fworch_db_name }}" - query: GRANT dbbackupusers TO dbbackup - - - name: add user fworchimporter to group configimporters - postgresql_query: - db: "{{ fworch_db_name }}" - query: GRANT configimporters TO fworchimporter - - - name: add user fworch to group fworchadmins - postgresql_query: - db: "{{ fworch_db_name }}" - query: GRANT fworchadmins TO fworch - - become: true - become_user: postgres +# add db users and assign groups + +- block: + + - name: create db groups + postgresql_user: + name: "{{ item }}" + loop: "{{ database_groups }}" + + - name: create db users + postgresql_user: + name: "{{ item }}" + role_attr_flags: LOGIN,NOSUPERUSER,INHERIT,NOCREATEDB,NOCREATEROLE + loop: "{{ database_users }}" + + - name: add user dbbackup to group dbbackupusers + postgresql_query: + db: "{{ fworch_db_name }}" + query: GRANT dbbackupusers TO dbbackup + + - name: add user fworch to group fworchadmins + postgresql_query: + db: "{{ fworch_db_name }}" + query: GRANT fworchadmins TO fworch + + become: true + become_user: postgres diff --git a/roles/database/tasks/install-database.yml b/roles/database/tasks/install-database.yml index 54feb32d43..6a71f8c6f3 100644 --- a/roles/database/tasks/install-database.yml +++ b/roles/database/tasks/install-database.yml @@ -1,12 +1,3 @@ -- name: make sure {{ fworch_home }}/etc/secrets exists - file: - path: "{{ fworch_home }}/etc/secrets" - state: directory - owner: "{{ fworch_user }}" - group: "{{ fworch_group }}" - mode: "0700" - become: true - - name: set dbadmin password from parameter set_fact: dbadmin_password: "{{ dbadmin_initial_password }}" @@ -17,7 +8,7 @@ dbadmin_password: "{{ randomly_generated_pwd }}" when: dbadmin_initial_password is not defined -- name: write dbadmin_password password to secret directory +- name: write dbadmin_password password to secrets directory copy: content: "{{ dbadmin_password }}\n" dest: "{{ dbadmin_password_file }}" @@ -62,6 +53,13 @@ # include add-tablespace.yml here + - name: make sure sorting order of psql client and postgresql server match for databases to be created + postgresql_query: + login_user: postgres + db: postgres + query: "ALTER DATABASE template1 REFRESH COLLATION VERSION" + when: pg_version|int >= 15 + - name: create database {{ fworch_db_name }} postgresql_db: name: "{{ fworch_db_name }}" @@ -78,18 +76,33 @@ debug: msg: "test_query result: {{ test_query }}" - - name: include table creation with ansible 2.10 and beyond - include_tasks: install-db-base-ansible-2.10.yml - when: ansible_version.full is version('2.10', '>=') - - - name: include table creation pre ansible 2.10 - include_tasks: install-db-base-ansible-pre2.10.yml - when: ansible_version.full is version('2.10', '<') - - name: create db users with group memberships import_tasks: create-users.yml when: installation_mode == "new" + - name: creating {{ fworch_db_name }}-db-model + community.postgresql.postgresql_script: + db: "{{ fworch_db_name }}" + path: "{{ database_install_dir }}/sql/creation/{{ item }}" + loop: + - fworch-create-tables-base.sql + - fworch-create-tables-rule-related.sql + - fworch-create-tables-stm.sql + - fworch-create-tables-flats.sql + - fworch-create-tables-changelog.sql + - fworch-create-tables-owner.sql + - fworch-create-tables-report.sql + - fworch-create-tables-modelling.sql + - fworch-create-tables-request.sql + - fworch-create-tables-compliance.sql + - fworch-create-constraints.sql + - fworch-create-foreign-keys.sql + - fworch-create-indices.sql + - fworch-create-triggers.sql + - fworch-fill-stm.sql + - fworch-views-materialized.sql + when: installation_mode == "new" + - name: add colors to the database postgresql_copy: db: "{{ fworch_db_name }}" @@ -134,3 +147,9 @@ become: true become_user: postgres + + +- name: create ro db user {{ fwo_db_ro_user }} + import_tasks: create-ro-user.yml + when: installation_mode == "new" + \ No newline at end of file diff --git a/roles/database/tasks/install-db-base-ansible-2.10.yml b/roles/database/tasks/install-db-base-ansible-2.10.yml deleted file mode 100644 index 315f0426a3..0000000000 --- a/roles/database/tasks/install-db-base-ansible-2.10.yml +++ /dev/null @@ -1,19 +0,0 @@ - -- block: - - - name: creating {{ fworch_db_name }}-db-model - community.postgresql.postgresql_query: - db: "{{ fworch_db_name }}" - path_to_script: "{{ database_install_dir }}/sql/creation/{{ item }}" - as_single_query: "{{ postgresql_query_as_single_query }}" - loop: - - fworch-create-tables.sql - - fworch-create-constraints.sql - - fworch-create-foreign-keys.sql - - fworch-create-indices.sql - - fworch-create-triggers.sql - - fworch-fill-stm.sql - when: installation_mode == "new" - - become: true - become_user: postgres diff --git a/roles/database/tasks/install-db-base-ansible-pre2.10.yml b/roles/database/tasks/install-db-base-ansible-pre2.10.yml deleted file mode 100644 index f4ba2ceb86..0000000000 --- a/roles/database/tasks/install-db-base-ansible-pre2.10.yml +++ /dev/null @@ -1,18 +0,0 @@ - -- block: - - - name: creating {{ fworch_db_name }}-db-model - postgresql_query: - db: "{{ fworch_db_name }}" - path_to_script: "{{ database_install_dir }}/sql/creation/{{ item }}" - loop: - - fworch-create-tables.sql - - fworch-create-constraints.sql - - fworch-create-foreign-keys.sql - - fworch-create-indices.sql - - fworch-create-triggers.sql - - fworch-fill-stm.sql - when: installation_mode == "new" - - become: true - become_user: postgres diff --git a/roles/database/tasks/main.yml b/roles/database/tasks/main.yml index 34af401080..eeb65c671b 100644 --- a/roles/database/tasks/main.yml +++ b/roles/database/tasks/main.yml @@ -27,6 +27,7 @@ - postgresql - python3-psycopg2 - libpq-dev + - postgresql-client when: ansible_os_family == "Debian" - name: initdb as extra step for redhat @@ -42,11 +43,6 @@ - name: set fact pg_version set_fact: pg_version={{ pg_version_result.stdout | float }} - - name: activate as_single_query if ansible_version is sufficient - set_fact: - postgresql_query_as_single_query: true - when: ansible_version.full is version('2.10', '>=') - - name: pg_version to int when possible set_fact: pg_version={{ pg_version | int }} when: pg_version|int >= 10 @@ -63,62 +59,32 @@ postgresql_hba_file: /var/lib/pgsql/data/pg_hba.conf when: ansible_os_family == 'RedHat' - - name: edit postgresql.conf log_destination - lineinfile: - path: "{{ postgresql_config_file }}" - line: log_destination = 'syslog' - regexp: '\s*log_destination' - backup: true - - - name: edit postgresql.conf client_min_messages - lineinfile: - path: "{{ postgresql_config_file }}" - line: client_min_messages = WARNING - regexp: '\s*client_min_messages' - backup: true - - - name: edit postgresql.conf log_min_messages - lineinfile: - path: "{{ postgresql_config_file }}" - line: log_min_messages = WARNING - regexp: '\s*log_min_messages' - backup: true - - - name: edit postgresql.conf application_name - lineinfile: - path: "{{ postgresql_config_file }}" - line: application_name = {{ product_name }}-database - regexp: '\s*application_name' - backup: true - - - name: edit postgresql.conf log_error_verbosity - lineinfile: - path: "{{ postgresql_config_file }}" - line: log_error_verbosity = DEFAULT - regexp: '\s*log_error_verbosity' - backup: true - - - name: edit postgresql.conf log_min_error_statement + - name: edit {{ postgresql_config_file }} settings lineinfile: path: "{{ postgresql_config_file }}" - line: log_min_error_statement = ERROR - regexp: '\s*log_min_error_statement' - backup: true - - - name: edit postgresql.conf log_line_prefix - lineinfile: - path: "{{ postgresql_config_file }}" - line: log_line_prefix = '%d ' - regexp: '\s*log_line_prefix' - backup: true - - - name: edit postgresql.conf listening IPs - lineinfile: - path: "{{ postgresql_config_file }}" - line: "listen_addresses = '0.0.0.0'" - #line: "listen_addresses = '{{ api_network_listening_ip_address }},127.0.0.1'" - regexp: listen_addresses + line: "{{ item.line }}" + regexp: "{{ item.regexp }}" backup: true + loop: + - line: "log_destination = 'syslog'" + regexp: '\s*log_destination' + - line: "client_min_messages = WARNING" + regexp: '\s*client_min_messages' + - line: "log_min_messages = WARNING" + regexp: '\s*log_min_messages' + - line: "application_name = {{ product_name }}-database" + regexp: '\s*application_name' + - line: "log_error_verbosity = DEFAULT" + regexp: '\s*log_error_verbosity' + - line: "log_min_error_statement = ERROR" + regexp: '\s*log_min_error_statement' + - line: "log_line_prefix = '%d '" + regexp: '\s*log_line_prefix' + - line: "listen_addresses = '{{ api_network_listening_ip_address }},127.0.0.1'" + regexp: listen_addresses + - line: "client_encoding = 'UTF8'" + regexp: client_encoding + register: postgres_config_updates - name: edit pg_hba.conf blockinfile: @@ -126,27 +92,25 @@ backup: true insertbefore: '# IPv4 local connections:' block: | - #host all dbadmin 127.0.0.0/8 md5 - #host all dbadmin api_network_listening_ip_address/32 md5 - host all dbadmin 0.0.0.0/0 md5 - host all {{ fworch_user }} 127.0.0.0/8 trust - host all +dbbackupusers 127.0.0.0/8 trust - host all confexporter 127.0.0.0/8 trust - host all +configimporters 127.0.0.0/8 trust - #host all +configimporters api_network_listening_ip_address/32 trust - # TODO: we need a solution here to add the IP of a remote importer instead of the name: - #host all +configimporters importer_server_ip/32 trust + host all dbadmin 127.0.0.0/8 md5 + host all {{ fwo_db_ro_user }} 127.0.0.0/8 trust + host all {{ fworch_user }} 127.0.0.0/8 trust + host all +dbbackupusers 127.0.0.0/8 trust + host all confexporter 127.0.0.0/8 trust + register: postgres_hba_update - name: reload postgres service service: name: "{{ postgresql_package }}" state: restarted + when: postgres_config_updates.changed or postgres_hba_update.changed - name: copy database files to backend target - copy: src="{{ item }}" dest="{{ database_install_dir }}" owner="{{ fworch_user }}" group="{{ fworch_user }}" - loop: - - csv - - sql + synchronize: + src: "./" + dest: "{{ database_install_dir }}" + rsync_opts: + - "--chown={{ fworch_user }}:{{ fworch_group }}" tags: [ 'test' ] - name: create tablespace directory @@ -168,6 +132,23 @@ become: true become_user: postgres +- name: make sure {{ fworch_home }}/etc/secrets exists + file: + path: "{{ fworch_home }}/etc/secrets" + state: directory + owner: "{{ fworch_user }}" + group: "{{ postgres_group }}" + mode: "0750" + become: true + +# now that postgresq user group exists ... +- name: set the correct permissions for main key file + file: + dest: "{{ main_key_file }}" + mode: '0640' + group: "{{ postgres_group }}" + become: true + - name: create new database import_tasks: install-database.yml when: installation_mode == "new" @@ -176,13 +157,13 @@ import_tasks: upgrade-database.yml when: installation_mode == "upgrade" -- name: (re)define functions and views - include_tasks: recreate-functions-and-views-ansible-pre2.10.yml - when: ansible_version.full is version('2.10', '<') - -- name: (re)define functions and views - include_tasks: recreate-functions-and-views-ansible-2.10.yml - when: ansible_version.full is version('2.10', '>=') +- name: (re)defines functions and views (idempotent) + community.postgresql.postgresql_script: + db: "{{ fworch_db_name }}" + path: "{{ database_install_dir }}/sql/idempotent/{{ item }}" + become: true + become_user: postgres + loop: "{{ database_idempotent_files }}" - name: install pg test packages package: @@ -192,11 +173,6 @@ tags: [ 'never', 'unittest' ] become: true -- name: run unit tests - include_tasks: run-unit-tests.yml - when: not installation_mode == "uninstall" - tags: [ 'never', 'unittest' ] - - name: remove database dir file: state: absent diff --git a/roles/database/tasks/recreate-functions-and-views-ansible-2.10.yml b/roles/database/tasks/recreate-functions-and-views-ansible-2.10.yml deleted file mode 100644 index b587ed81d8..0000000000 --- a/roles/database/tasks/recreate-functions-and-views-ansible-2.10.yml +++ /dev/null @@ -1,9 +0,0 @@ - -- name: (re)defines functions and views (idempotent) from ansible 2.10 - community.postgresql.postgresql_query: - db: "{{ fworch_db_name }}" - path_to_script: "{{ database_install_dir }}/sql/idempotent/{{ item }}" - as_single_query: "{{ postgresql_query_as_single_query }}" - become: true - become_user: postgres - loop: "{{ database_idempotent_files }}" diff --git a/roles/database/tasks/recreate-functions-and-views-ansible-pre2.10.yml b/roles/database/tasks/recreate-functions-and-views-ansible-pre2.10.yml deleted file mode 100644 index 8b361f9c4d..0000000000 --- a/roles/database/tasks/recreate-functions-and-views-ansible-pre2.10.yml +++ /dev/null @@ -1,8 +0,0 @@ - -- name: (re)defines functions and views (idempotent) prior to ansible 2.10 - postgresql_query: - db: "{{ fworch_db_name }}" - path_to_script: "{{ database_install_dir }}/sql/idempotent/{{ item }}" - become: true - become_user: postgres - loop: "{{ database_idempotent_files }}" diff --git a/roles/database/tasks/run-unit-tests.yml b/roles/database/tasks/run-unit-tests.yml deleted file mode 100644 index 215ccc5b44..0000000000 --- a/roles/database/tasks/run-unit-tests.yml +++ /dev/null @@ -1,28 +0,0 @@ - -- name: copy database test files to backend target - copy: src="sql/test" dest="{{ database_install_dir }}/sql" owner="{{ fworch_user }}" group="{{ fworch_user }}" - become: true - -- set_fact: - unit_test_scripts: - - unit-tests.sql - - hasura-test.sql - - unit-test-cleanup.sql - -- debug: - msg: "unit_test_scripts: {{ unit_test_scripts | to_nice_json }}" - -- name: run db unit tests - postgresql_query: - db: "{{ fworch_db_name }}" - path_to_script: "{{ database_install_dir }}/sql/test/{{ item }}" - become: true - become_user: "postgres" - register: testresults - loop: "{{ unit_test_scripts }}" - tags: - - unittest - -- name: Print db test results - debug: - msg: "test results: {{ testresults | to_nice_json }}" diff --git a/roles/database/tasks/run-upgrade-file.yml b/roles/database/tasks/run-upgrade-file.yml new file mode 100644 index 0000000000..7dd74c9533 --- /dev/null +++ b/roles/database/tasks/run-upgrade-file.yml @@ -0,0 +1,6 @@ +- name: install upgrade {{ upgrade_file }}.sql + community.postgresql.postgresql_script: + db: "{{ fworch_db_name }}" + path: "{{ database_install_dir }}/upgrade/{{ upgrade_file }}.sql" + become: true + become_user: postgres diff --git a/roles/database/tasks/unused-add-tablespace.yml b/roles/database/tasks/unused-add-tablespace.yml deleted file mode 100644 index 1e465bb0a3..0000000000 --- a/roles/database/tasks/unused-add-tablespace.yml +++ /dev/null @@ -1,27 +0,0 @@ -# Note: In the example below, if database foo exists and has another tablespace -# the tablespace will be changed to foo. Access to the database will be locked -# until the copying of database files is finished. -# - name: Create a new database called foo in tablespace bar -# postgresql_db: -# name: foo -# tablespace: bar - - - -# leave out tablespace creation for now as this cannot be done within a pgsql function (might use dblink later on) -# - name: create tablespace {{ fworch_user }} -# shell: 'psql -c "DO \$do\$ BEGIN IF NOT EXISTS (SELECT 1 FROM pg_tablespace WHERE spcname = ''{{ table_space_name }}'') THEN CREATE TABLESPACE {{ table_space_name }} OWNER dbadmin LOCATION ''{{ table_space }}''; END IF; END \$do\$"' -# when: table_space is defined -# -# also move temp tablespace to large disk: -# postgres=# create tablespace temp_tbs location '/var/db/tmp_tablespace'; -# grep temp_tablespaces /etc/postgresql/9.5/main/postgresql.conf -# temp_tablespaces = 'temp_tbs' # a list of tablespace names, '' uses -# postgres=# select pg_reload_conf(); - -# - name: check if database already exists -# shell: 'psql -At -c "SELECT count(*) FROM pg_database WHERE datname=''{{ fworch_db_name }}''"' -# register: db_exists - -# - debug: -# var: db_exists.stdout diff --git a/roles/database/tasks/upgrade-database.yml b/roles/database/tasks/upgrade-database.yml index e75d396cf9..b2a03e034f 100644 --- a/roles/database/tasks/upgrade-database.yml +++ b/roles/database/tasks/upgrade-database.yml @@ -1,50 +1,47 @@ - - # install all upgrades between running version and version currently being installed +# install all upgrades between running version and version currently being installed - name: guard - stop when trying anything but an upgrade with existing database fail: - msg: "Error: You chose upgrade on a system without existing database {{ fworch_db_name }}" + msg: "Error: You chose upgrade on a system without existing database {{ fworch_db_name }}" when: db_exists.query_result.0.count == 0 - name: create upgrade dir file: - path: "{{ database_install_dir }}/upgrade" - state: directory + path: "{{ database_install_dir }}/upgrade" + state: directory become: true - -- set_fact: - installed_version: "{{ old_version }}" - current_version: "{{ product_version }}" - all_upgrades_available: "{{ lookup('fileglob', 'upgrade/*.sql') }}" - upgrade_files: [] + +- set_fact: + installed_version: "{{ old_version }}" + current_version: "{{ product_version }}" + all_upgrades_available: "{{ lookup('fileglob', 'upgrade/*.sql') }}" + upgrade_files: [] - name: set list of relevant upgrade files (without extension) set_fact: - upgrade_files: "{{ upgrade_files + [ item | basename | splitext | first | regex_replace('([\\d\\.]+)\\.sql', '\\1') ] }}" + upgrade_files: "{{ upgrade_files + [ item | basename | splitext | first | regex_replace('([\\d\\.]+)\\.sql', '\\1') ] }}" when: | - item | basename | splitext | first | regex_replace('([\\d\\.]+)\\.sql', '\\1') is version(installed_version, '>=') - and - item | basename | splitext | first | regex_replace('([\\d\\.]+)\\.sql', '\\1') is version(current_version, '<=') + item | basename | splitext | first | regex_replace('([\\d\\.]+)\\.sql', '\\1') is version(installed_version, '>=') + and + item | basename | splitext | first | regex_replace('([\\d\\.]+)\\.sql', '\\1') is version(current_version, '<=') with_fileglob: - - "upgrade/*.sql" + - "upgrade/*.sql" -- debug: - msg: - - "installed_version: {{ installed_version }}" - - "current_version: {{ current_version }}" - - "all_upgrades_available: {{ all_upgrades_available }}" +- debug: + msg: + - "installed_version: {{ installed_version }}" + - "current_version: {{ current_version }}" + - "all_upgrades_available: {{ all_upgrades_available }}" - name: Copy relevant upgrade files copy: - src: "upgrade/{{ item }}.sql" - dest: "{{ database_install_dir }}/upgrade/" - loop: "{{ upgrade_files }}" + src: "upgrade/{{ item }}.sql" + dest: "{{ database_install_dir }}/upgrade/" + loop: "{{ upgrade_files | community.general.version_sort }}" become: true -- name: include upgrades as postgresql_query is not available in all ansible versions - include_tasks: upgrade_database_new.yml - when: ansible_version.full is version('2.10', '>=') - -- name: include upgrades as postgresql_query is not available in all ansible versions - include_tasks: upgrade_database_old.yml - when: ansible_version.full is version('2.10', '<=') +- name: install upgrades + include_tasks: run-upgrade-file.yml + loop: "{{ upgrade_files | community.general.version_sort }}" + loop_control: + loop_var: upgrade_file diff --git a/roles/database/tasks/upgrade_database_new.yml b/roles/database/tasks/upgrade_database_new.yml deleted file mode 100644 index a34bd57089..0000000000 --- a/roles/database/tasks/upgrade_database_new.yml +++ /dev/null @@ -1,10 +0,0 @@ - -- name: install upgrades as_single_query - community.postgresql.postgresql_query: - db: "{{ fworch_db_name }}" - path_to_script: "{{ database_install_dir }}/upgrade/{{ item }}.sql" - as_single_query: "{{ postgresql_query_as_single_query }}" - loop: "{{ upgrade_files | sort }}" - become: true - ignore_errors: false - become_user: postgres diff --git a/roles/database/tasks/upgrade_database_old.yml b/roles/database/tasks/upgrade_database_old.yml deleted file mode 100644 index d7586b00ac..0000000000 --- a/roles/database/tasks/upgrade_database_old.yml +++ /dev/null @@ -1,9 +0,0 @@ - -- name: install upgrades normally - postgresql_query: - db: "{{ fworch_db_name }}" - path_to_script: "{{ database_install_dir }}/upgrade/{{ item }}.sql" - loop: "{{ upgrade_files | sort }}" - ignore_errors: false - become: true - become_user: postgres diff --git a/roles/docker/tasks/main.yml b/roles/docker/tasks/main.yml index 4daf5fde32..e860abe60e 100644 --- a/roles/docker/tasks/main.yml +++ b/roles/docker/tasks/main.yml @@ -1,58 +1,82 @@ --- -- block: - - set_fact: ansible_user="{{ lookup('env','USER') }}" - - - name: Install packages for docker download n installation - package: - name: "{{ item }}" - loop: - - gnupg2 - - apt-transport-https - - ca-certificates - - curl - - software-properties-common - - - name: adding docker apt signing key - get_url: - url: https://download.docker.com/linux/ubuntu/gpg - dest: /etc/apt/trusted.gpg.d/docker.asc - force: true - mode: "0644" - environment: "{{ proxy_env }}" - - - name: add docker repo - lineinfile: - path: "/etc/apt/sources.list.d/docker.list" - create: true - line: "deb [arch=amd64] https://download.docker.com/linux/debian buster stable" - - - name: apt update - apt: update_cache=true - environment: "{{ proxy_env }}" - - - name: Install all packages for docker - package: - name: "{{ item }}" - loop: - - docker-ce - - docker-ce-cli - - containerd.io - - - name: Add the group 'docker' for {{ ansible_user }} and {{ fworch_user }} to allow running docker - user: +- block: + - set_fact: + ansible_user: "{{ lookup('env','USER') }}" + os_codename: "{{ ansible_lsb.codename | lower }}" + docker_repo_distribution: "{{ ansible_distribution | lower }}" + + # for trixie there is no docker image yet + - set_fact: + os_codename: bookworm + when: "os_codename == 'trixie'" + + - name: define docker repo urls + set_fact: + docker_repo_base_url: "https://download.docker.com/linux/{{ docker_repo_distribution }}" + docker_repo_release_url: "https://download.docker.com/linux/{{ docker_repo_distribution }}/dists/{{ os_codename }}/Release" + + - name: Install packages for docker download n installation + package: + name: "{{ item }}" + loop: + - gnupg2 + - apt-transport-https + - ca-certificates + - curl + + - name: adding docker apt signing key + get_url: + url: https://download.docker.com/linux/ubuntu/gpg + dest: /etc/apt/trusted.gpg.d/docker.asc + force: true + mode: "0644" + environment: "{{ proxy_env }}" + + - name: validate docker apt repo metadata before changing apt source + uri: + url: "{{ docker_repo_release_url }}" + method: HEAD + status_code: 200 + environment: "{{ proxy_env }}" + + - name: add docker repo + apt_repository: + filename: docker + repo: "deb [arch=amd64] {{ docker_repo_base_url }} {{ os_codename }} stable" + state: present + update_cache: false + + - name: apt update + apt: update_cache=true + environment: "{{ proxy_env }}" + + - name: Install all packages for docker + package: + name: "{{ item }}" + loop: + - docker-ce + - docker-ce-cli + - containerd.io + + - name: Add the group 'docker' for {{ ansible_user }} and {{ fworch_user }} to allow running docker + user: name: "{{ item }}" groups: docker append: true - loop: - - "{{ ansible_user }}" - - "{{ fworch_user }}" + loop: + - "{{ ansible_user }}" + - "{{ fworch_user }}" + + - name: set proxy for docker daemon to get images via proxy + import_tasks: set-docker-daemon-proxy.yml + notify: "docker restart" - - name: set proxy for docker daemon to get images via proxy - import_tasks: set-docker-daemon-proxy.yml - notify: "docker restart" + - name: set docker daemon bridge network + import_tasks: set-docker-daemon-network.yml + when: docker_network is defined and docker_network | length > 0 - - name: include upgrade script - import_tasks: run-upgrades.yml - when: "installation_mode == 'upgrade'" + - name: include upgrade script + import_tasks: run-upgrades.yml + when: "installation_mode == 'upgrade'" become: true diff --git a/roles/docker/tasks/set-docker-daemon-network.yml b/roles/docker/tasks/set-docker-daemon-network.yml new file mode 100644 index 0000000000..e8d144ac90 --- /dev/null +++ b/roles/docker/tasks/set-docker-daemon-network.yml @@ -0,0 +1,33 @@ +--- +- name: read existing docker daemon config + slurp: + src: /etc/docker/daemon.json + register: docker_daemon_config_raw + ignore_errors: true + +- name: set docker daemon config base + set_fact: + docker_daemon_config: >- + {{ + (docker_daemon_config_raw.content | b64decode | from_json) + if ( + docker_daemon_config_raw is defined and + docker_daemon_config_raw.content is defined and + (docker_daemon_config_raw.content | b64decode | trim | length > 0) + ) + else {} + }} + +- name: set docker bridge network + set_fact: + docker_daemon_config: "{{ docker_daemon_config | combine({'bip': docker_network}, recursive=True) }}" + +- name: write docker daemon config + copy: + dest: /etc/docker/daemon.json + content: "{{ docker_daemon_config | to_nice_json }}\n" + mode: "0644" + owner: "root" + group: "root" + backup: true + notify: "docker restart" diff --git a/roles/final-display/tasks/main.yml b/roles/final-display/tasks/main.yml deleted file mode 100644 index eeea7e6b64..0000000000 --- a/roles/final-display/tasks/main.yml +++ /dev/null @@ -1,13 +0,0 @@ - -- name: show listener status - import_tasks: scripts/show-fworch-listeners.yml - become: true - -- name: display secrets for this installation - debug: - msg: - - "Your initial UI admin password is '{{ admin_password }}'" - - "Your api hasura admin secret is '{{ api_hasura_admin_secret }}'" - when: | - admin_password is defined and - api_hasura_admin_secret is defined diff --git a/roles/finalize/tasks/main.yml b/roles/finalize/tasks/main.yml new file mode 100644 index 0000000000..966824f944 --- /dev/null +++ b/roles/finalize/tasks/main.yml @@ -0,0 +1,138 @@ +# change version to new number in /etc/fworch/fworch.yaml + +- name: check for existing main config file + stat: + path: "{{ fworch_conf_file }}" + register: already_installed + +- set_fact: + already_installed: "{{ already_installed.stat.exists }}" + +- debug: + msg: "installation_mode={{ installation_mode }}, already_installed={{ already_installed }}" + +- name: fail if unknown installation_mode is set + fail: + msg: "Found undefined installation_mode: {{ installation_mode }}, aborting." + when: installation_mode != "new" and installation_mode != "uninstall" and installation_mode != "upgrade" + +- name: fail if not already installed and installation_mode is upgrade + fail: + msg: "Could not find existing installation but running with installation_mode set to {{ installation_mode }}. Try running with installation_mode=new" + when: not already_installed and installation_mode == "upgrade" + +- name: Modify the product version in the config file + block: + - name: Read config file + slurp: + path: "{{ fworch_conf_file }}" + register: config_file + + - name: Modify product_version + set_fact: + json_data: "{{ config_file.content | b64decode | from_json | combine({'product_version': product_version }) }}" + + - name: Save updated config to file + copy: + content: "{{ json_data | to_nice_json }}" + dest: "{{ fworch_conf_file }}" + owner: "{{ fworch_user }}" + group: "{{ fworch_group }}" + become: true + when: installation_mode == "upgrade" + +- name: include upgrade script + import_tasks: run-upgrades.yml + when: "installation_mode == 'upgrade'" + +- name: call external python scripts to set some customer specific config settings via API + script: "{{ item }}" + args: + executable: python3 + become: true + when: "'apiserver' in group_names" + with_fileglob: + - "scripts/customizing/api/*.py" + +# Do general cleanup +# - name: delete ldif files +# file: +# path: "{{ middleware_ldif_dir }}" +# state: absent +# become: true +# when: "'middlewareserver' in group_names" + +- name: restart UI to display new product version + ansible.builtin.systemd: + name: "{{ product_name }}-ui" + state: restarted + become: true + when: "'frontends' in group_names and (ui_deploy_changed | default(false) or product_version_changed | default(false))" + +- name: test whether demo data is present + postgresql_query: + db: "{{ fworch_db_name }}" + query: > + SELECT * FROM device WHERE dev_name='{{ sample_fortigate_name }}' + register: demo_data_present + become: true + become_user: postgres + when: "'sampleserver' in group_names" + +- name: find cron jobs in case of missing demo data + find: + paths: /etc/cron.d + patterns: "{{ product_name }}_sample_data_*" + register: files_to_delete + become: true + when: "demo_data_present.query_result == [] and 'sampleserver' in group_names" + +- name: delete cron jobs in case of missing demo data + file: + path: "{{ item.path }}" + state: absent + with_items: "{{ files_to_delete.files }}" + become: true + when: "demo_data_present.query_result == [] and 'sampleserver' in group_names" + +- name: start importer service + systemd: + name: "{{ product_name }}-importer-api" + state: started + daemon_reload: true + enabled: true + become: true + when: "'importers' in group_names" + +- name: remove maint website dir + file: + path: "{{ fworch_home }}/maint-website" + state: absent + become: true + +- name: deactivate maintenance web site + command: "a2dissite {{ product_name }}-maintenance" + ignore_errors: true + become: true + when: "installation_mode == 'upgrade' and 'frontends' in group_names" + +- name: restart apache without maintenance site + service: + name: "{{ webserver_package_name }}" + state: restarted + become: true + +- name: finally restart MW + ansible.builtin.systemd: + name: "{{ product_name }}-middleware" + state: restarted + become: true + when: "'middlewareserver' in group_names and (mw_deploy_changed | default(false))" + +# TODO - find out why UI sometimes crashes during upgrade of heavy data installations +- name: finally restart UI + ansible.builtin.systemd: + name: "{{ product_name }}-ui" + state: restarted + become: true + when: "'frontends' in group_names and (ui_deploy_changed | default(false))" diff --git a/roles/cleanup/tasks/run-upgrades.yml b/roles/finalize/tasks/run-upgrades.yml similarity index 100% rename from roles/cleanup/tasks/run-upgrades.yml rename to roles/finalize/tasks/run-upgrades.yml diff --git a/roles/cleanup/tasks/upgrade/5.6.2.yml b/roles/finalize/tasks/upgrade/5.6.2.yml similarity index 100% rename from roles/cleanup/tasks/upgrade/5.6.2.yml rename to roles/finalize/tasks/upgrade/5.6.2.yml diff --git a/roles/cleanup/tasks/upgrade/5.6.5.yml b/roles/finalize/tasks/upgrade/5.6.5.yml similarity index 100% rename from roles/cleanup/tasks/upgrade/5.6.5.yml rename to roles/finalize/tasks/upgrade/5.6.5.yml diff --git a/roles/finalize/tasks/upgrade/9.0.yml b/roles/finalize/tasks/upgrade/9.0.yml new file mode 100644 index 0000000000..dbfaa7d93d --- /dev/null +++ b/roles/finalize/tasks/upgrade/9.0.yml @@ -0,0 +1,20 @@ +- name: check for existing legacy importer service file + stat: + path: "/lib/systemd/system/{{ product_name }}-importer-legacy.service" + register: legacy_importer_service_check + +- name: stop and disable legacy importer service + ansible.builtin.systemd: + name: "{{ product_name }}-importer-legacy" + state: stopped + enabled: false + daemon_reload: true + become: true + when: "'importers' in group_names and legacy_importer_service_check.stat.exists" + +- name: remove legacy importer service file + file: + state: absent + path: "/lib/systemd/system/{{ product_name }}-importer-legacy.service" + become: true + when: legacy_importer_service_check.stat.exists diff --git a/roles/global.json b/roles/global.json new file mode 100644 index 0000000000..70976d298f --- /dev/null +++ b/roles/global.json @@ -0,0 +1,5 @@ +{ + "sdk": { + "version": "8.0.*" + } +} \ No newline at end of file diff --git a/roles/importer/files/import.conf b/roles/importer/files/import.conf deleted file mode 100644 index e18692bc52..0000000000 --- a/roles/importer/files/import.conf +++ /dev/null @@ -1,27 +0,0 @@ -# Config settings of import module - -ImportSleepTime 40 # time between import loops in seconds -ImportDir /usr/local/fworch/importer # Import main directory -PerlInc /usr/local/fworch/importer # Perl Include directory -fworch_workdir /usr/local/fworch/tmp/import # temp. dir for import data -archive_dir /usr/local/fworch/tmp/import_archive # dir for archiving of faulty import runs -simple_bin_dir /bin # dir for tar, date, mkdir, ... -save_import_results_to_file 0 - -# delimiter -usergroup_delimiter | -csv_delimiter % -csv_user_delimiter ; -group_delimiter | - -fworch_srv_user fworchimporter -output_method text -echo_bin /bin/echo -scp_bin /usr/bin/scp -ssh_bin /usr/bin/ssh -ssh_client_screenos /usr/local/fworch/importer/ssh-client.pl -chmod_bin /bin/chmod -scp_batch_mode_switch -B -q - -psql_exe /usr/bin/psql # for netscreen predef-services copy from -psql_params -t -q -A -h $fworch_srv_host -d $fworch_database -U $fworch_srv_user diff --git a/roles/importer/files/importer/CACTUS/FWORCH.pm b/roles/importer/files/importer/CACTUS/FWORCH.pm deleted file mode 100644 index 098b72160c..0000000000 --- a/roles/importer/files/importer/CACTUS/FWORCH.pm +++ /dev/null @@ -1,992 +0,0 @@ -package CACTUS::FWORCH; - -use strict; -use warnings; -use DBI; -require DBD::Pg; -use IO::File; -use Getopt::Long; -use File::Basename; -use CGI qw(:standard); -require Exporter; -require Sys::Syslog; -use CACTUS::read_config; - -our @ISA = qw(Exporter); - -our %EXPORT_TAGS = ( - 'basic' => [ qw( - &is_numeric &is_empty &calc_md5_of_files &file_exists &iconv_config_files_2_utf8 &iconv_2_utf8 - &replace_special_chars &remove_quotes &remove_space_at_end &print_syslog - &remove_literal_carriage_return - &output_txt &print_txt &print_linebreak &print_txt_with_linebreak &print_header &print_bold &print_error - &print_html_header &print_html_footer &print_html_only - &error_handler &error_handler_add &error_handler_get - $output_method $dbdriver - $echo_bin $chmod_bin $scp_bin $ssh_bin $scp_batch_mode_switch $ssh_client_screenos - $fworch_database $fworch_srv_host $fworch_srv_user $fworch_srv_user $fworch_srv_port $fworch_srv_pw $psql_exe $psql_params - &get_client_filter &get_device_ids_for_mgm - &eval_boolean_sql &exec_pgsql_file &exec_pgsql_cmd &exec_pgsql_cmd_no_result - &exec_pgsql_cmd_return_value &exec_pgsql_cmd_return_array_ref &exec_pgsql_cmd_return_table_ref - ©_file_to_db &get_rulebase_names &get_ruleset_name_list &get_local_ruleset_name_list &get_global_ruleset_name_list &evaluate_parameters &replace_import_id_in_csv - ) ]); - -our @EXPORT = (@{$EXPORT_TAGS{'basic'}}); -our $VERSION = '0.3'; - -# globale Variablen bzw. Konstanten -our $echo_bin = CACTUS::read_config::read_config('echo_bin'); -our $chmod_bin = CACTUS::read_config::read_config('chmod_bin'); -our $scp_bin = CACTUS::read_config::read_config('scp_bin'); -our $ssh_bin = CACTUS::read_config::read_config('ssh_bin'); -our $ssh_client_screenos = CACTUS::read_config::read_config('ssh_client_screenos'); -our $scp_batch_mode_switch = CACTUS::read_config::read_config('scp_batch_mode_switch'); -our $output_method = CACTUS::read_config::read_config('output_method'); -our $syslog_type = CACTUS::read_config::read_config('syslog_type'); -our $syslog_ident = CACTUS::read_config::read_config('syslog_ident'); -our $syslog_facility = CACTUS::read_config::read_config('syslog_facility'); - -our $webuser; -our $fworch_srv_pw = ''; -our $fworch_srv_host = &CACTUS::read_config::read_config("fworch database hostname"); -our $fworch_database = &CACTUS::read_config::read_config("fworch database name"); -our $fworch_srv_port = &CACTUS::read_config::read_config("fworch database port"); -our $csv_delimiter = &CACTUS::read_config::read_config("csv_delimiter"); -our $group_delimiter = &CACTUS::read_config::read_config("group_delimiter"); -our $csv_user_delimiter = &CACTUS::read_config::read_config("csv_user_delimiter"); -our $fworch_srv_user = &CACTUS::read_config::read_config("fworch_srv_user"); -our $psql_exe = &CACTUS::read_config::read_config("psql_exe"); -our $psql_params = &CACTUS::read_config::read_config("psql_params"); -our $dbdriver = "Pg"; -our $ssh_id_basename = 'import_user_secret'; - -############################################################ -# getnum -# hilfsfunktion fuer is_numeric -############################################################ -sub getnum { - use POSIX qw(strtod); - my $str = shift; - if (!defined($str)) {return undef;} - # $str =~ s/^\s+//; - # $str =~ s/\s+$//; - $str =~ s/\./\,/g; - $! = 0; - my ($num, $unparsed) = strtod($str); - if (($str eq '') || ($unparsed != 0) || $!) { - return undef; - } - else { - return $num; - } -} - -############################################################ -# is_numeric(scalar) -# liefert true wenn scalar ein numerischer Wert ist -############################################################ -sub is_numeric {defined getnum($_[0])} - -############################################################ -# is_empty(scalar) -# liefert true wenn scalar leer ist (nicht definiert oder leerer String) -############################################################ -sub is_empty {return (!defined($_[0]) || $_[0] eq '');} - -############################################################################################## -# package output; - -############################################################ -# print_syslog(text, prio) -# Ausgabe des Textes an syslog mit prio -############################################################ -sub print_syslog { - my $txt = shift; - my $syslog_priority = shift; - - if ($^O eq 'linux') { - - # syslog does not work properly for windows - &Sys::Syslog::setlogsock($syslog_type) or die $!; - &Sys::Syslog::openlog($syslog_ident, 'cons', $syslog_facility) - or die $!; - &Sys::Syslog::syslog($syslog_priority, $txt) - or die "syslog failed $!"; - &Sys::Syslog::closelog(); - } - return; -} - -############################################################ -# print_txt(text) -# Ausgabe des Textes -############################################################ -sub print_txt { - my $txt = shift; - print($txt); - return; -} - -sub output_txt { - my $txt = shift; - my $errlvl = shift; - - print($txt); - if (defined($errlvl) && $errlvl > 0) { - print_syslog($txt, 'err'); - - } - else { - print_syslog($txt, 'notice'); - } - return; -} - -############################################################ -# print_linebreak -# Ausgabe eines linebreaks -############################################################ -sub print_linebreak { - our $output_method; - if ($output_method eq 'html') {print_txt("
                      \n");} - else {print_txt("\n");} - return; -} - -############################################################ -# print_txt_with_linebreak(text) -# Ausgabe des Textes mit anschliessendem linebreak -############################################################ -sub print_txt_with_linebreak { - my $txt = shift; - print_txt($txt); - print_linebreak(); - return; -} - -############################################################ -# print_header(text) -# Ausgabe des Textes, bei html als

                      -############################################################ -sub print_header { - my $txt = shift; - our $output_method; - print_syslog($txt, 'info'); - if ($output_method eq 'html') {print_txt("

                      $txt

                      ");} - else {print_txt($txt);} - return; -} - -############################################################ -# print_bold(text) -# Ausgabe des Textes in fett, wenn html -############################################################ -sub print_bold { - my $txt = shift; - our $output_method; - print_syslog($txt, 'notice'); - if ($output_method eq 'html') {print_txt("$txt");} - else {print_txt($txt);} - return; -} - -############################################################ -# print_error(text) -# Ausgabe des Textes in rot (wenn HTML) -############################################################ -sub print_error { - my $txt = shift; - our $output_method; - print_syslog($txt, 'warning'); - if ($output_method eq 'html') { - print_txt(""); - print_bold($txt); - print_txt(""); - } - else {print_txt($txt);} - return; -} - -############################################################ -# print_html_only($html_txt) -# Ausgabe von HTML-Code, falls html -############################################################ -sub print_html_only { - my $htmlcode = shift; - our $output_method; - if ($output_method eq 'html') {print_txt("$htmlcode");} - return; -} - -############################################################ -# print_html_header() -# Ausgabe eines HTML-Headers, falls html -############################################################ -sub print_html_header { - our $output_method; - if ($output_method eq 'html') { - print_txt("Content-Type: text/html\n\n"); - print_txt(""); - print_txt( - ""); - print_txt( - ""); - print_txt( - "" - ); - print_txt("" - ); - } - return; -} - -############################################################ -# print_html_footer() -# Ausgabe der schliessenden TAGS -############################################################ -sub print_html_footer { - our $output_method; - if ($output_method eq 'html') { - print_txt(""); - } - return; -} - -############################################################ -# iconv_config_files_2_utf8 ($file,$tmpdir) -# convert latin1 to utf-8 -############################################################ -sub iconv_config_files_2_utf8 { - my $str_of_files_to_sum = shift; - my $tmpdir = shift; - my $file; - my @file_ar; - - if (@file_ar) { - @file_ar = split(/,/, $str_of_files_to_sum); - foreach $file (@file_ar) { - if ($file !~ /^fwauth\.NDB/) { - iconv_2_utf8($file, $tmpdir); - } - } - } - return; -} - -############################################################ -# iconv_2_utf8 ($file) -# convert latin1 to utf-8 -############################################################ -sub iconv_2_utf8 { - my $file_to_conv = shift; - my $tmpdir = shift; - my $md5sum_file = "$tmpdir/cfg_hash.md5"; - my $cmd = "/usr/bin/iconv --from-code latin1 --to-code utf-8 $file_to_conv --output $file_to_conv.utf-8"; - system($cmd); - $cmd = "/bin/mv $file_to_conv.utf-8 $file_to_conv"; - system($cmd); -} - - -############################################################ -# calc_md5_of_files ($file,$tmpdir) -# gibt den kontaktenierten MD5-Hash-Wert aller Files zurueck -############################################################ -sub calc_md5_of_files { - my $str_of_files_to_sum = shift; - my $tmpdir = shift; - my $file; - my $total = ''; - my @file_ar; - - @file_ar = split(/,/, $str_of_files_to_sum); - foreach $file (@file_ar) { - $total .= calc_md5_of_file($file, $tmpdir); - } - return $total; -} - -############################################################ -# calc_md5_of_file ($file) -# gibt den MD5-Hash-Wert zurueck -############################################################ -sub calc_md5_of_file { - my $file_to_sum = shift; - my $tmpdir = shift; - my $md5sum_file = "$tmpdir/cfg_hash.md5"; - my $cmd = "/usr/bin/md5sum $file_to_sum | cut --bytes=-32 >$md5sum_file"; - system($cmd); - open(MD5SUM, "<$md5sum_file"); - my $md5sum = ; - close MD5SUM; - $cmd = "/bin/rm -f $md5sum_file"; - system($cmd); - - if (defined($md5sum)) { - return substr($md5sum, 0, 32); - } - else { - return "error-in-md5-sum-calc"; - } -} - -############################################################ -# file_exists ($file) -# true, wenn das file $file existiert -############################################################ -sub file_exists { - return (-e $_[0]); -} - -# package error_handling; -############################################################ -# error_handler(string) -# fehlerbehandlung -# in der einfachsten Fassung Ausgabe des Fehlerstrings -# und exit 1 -############################################################ -sub error_handler { - my $err_str = $_[0]; - - # print ("Fehler: $err_str\n"); - return $err_str; - - # exit 1; -} - -############################################################ -# error_handler_get -# fehlermeldungen auslesen -############################################################ -sub error_handler_get { - my $current_import_id = shift; - - if (defined($current_import_id)) { - my $existing_error_str = &exec_pgsql_cmd_return_value("SELECT import_errors FROM import_control WHERE control_id=$current_import_id"); - return $existing_error_str; - } - else { - return undef; - } -} - -############################################################ -# error_handler_update -# fehlermeldungen anhaengen in import_control -############################################################ -sub error_handler_update { - my $current_import_id = shift; - my $new_error_str = shift; - - if (defined($current_import_id)) { - my $existing_error_str = &error_handler_get($current_import_id); - if (!defined($existing_error_str) || $existing_error_str eq '') {$existing_error_str = '';} - else {$existing_error_str .= "; ";} - &exec_pgsql_cmd_no_result("UPDATE import_control SET import_errors='$existing_error_str$new_error_str', successful_import=FALSE WHERE control_id=$current_import_id"); - } -} - -############################################################ -# error_handler_add -# fehlermeldungen an string anhaengen, wenn definiert -############################################################ -sub error_handler_add { - my $current_import_id = shift; - my $error_level = shift; - my $current_error_str = shift; - my $current_error_count = shift; - my $previous_errors_count = shift; - my $error_tag = 'DEBUG'; - - my $previous_errors_string = &error_handler_get($current_import_id); - # print ("debug error handler: lvl=$error_level, curr_err_str=$current_error_str, glob_err_str=$previous_errors_string, #curr_errors=$current_error_count, #total_errs=$previous_errors_count\n"); - my $total_error_str = (defined($previous_errors_string) ? "$previous_errors_string" : ''); - my $total_error_count = $previous_errors_count; - if ($error_level) { - if ($error_level == 1) {$error_tag = 'INFO';} - if ($error_level == 2) {$error_tag = 'WARN';} - if ($error_level == 3) {$error_tag = 'ERR';} - if ($error_level > 3) {$error_tag = 'FATAL-ERR';} - if (!defined($previous_errors_string)) {$previous_errors_string = '';} - if ($previous_errors_string ne '') {$previous_errors_string .= "\n";} - if ($current_error_count) {if ($current_error_str ne '') {$current_error_str = "$error_tag-$current_error_str";}} - if ($error_level > 1 && $current_error_count) {$total_error_str = "$previous_errors_string$current_error_str";} - # print ("current_error_count: $current_error_count\n"); - $total_error_count = $previous_errors_count + $current_error_count; - if ($error_level > 1 && $current_error_count) { - output_txt("$current_error_str\n", $error_level); - &error_handler_update($current_import_id, $current_error_str); - } - if ($error_level > 3 && $current_error_count) {exit $error_level;} - } - return $total_error_count; -} - -# package string_manipulation; -############################################################ -# remove_quotes(string) -# entfernt aus string alle Anfuehrungszeichen -############################################################ -sub remove_quotes { - my $str = $_[0]; - $str =~ s/"//g; - $str =~ s/'//g; - $str =~ s/`//g; - $str =~ s/´//g; - return $str; -} - -############################################################ -# remove_space_at_end(string) -# entfernt aus string das letzte Zeichen, wenn es ein space ist -############################################################ -sub remove_space_at_end { - my $str = $_[0]; - $str =~ s/\s$//g; - return $str; -} - -############################################################ -# remove_literal_carriage_return(filename) -# entfernt jedes Auftreten eines literal_carriage_returns inenrhalb des Files -############################################################ -sub remove_literal_carriage_return { - my $in_file = $_[0]; - my $out_file = "$in_file.no_cr"; - my $line; - - open(IN, $in_file) || die "$in_file konnte nicht geoeffnet werden.\n"; - open(OUT, ">$out_file") - || die "$out_file konnte nicht geoeffnet werden.\n"; - - while () { - $line = $_; # Zeileninhalt merken - $line =~ s/\r\n/\n/; # dos2unix - $line =~ s/\x0D/\\r/g; # literal carriage return entfernen - print OUT $line; - } - close(IN); - close(OUT); - rename($in_file, "$in_file.orig"); - rename($out_file, $in_file); - return; -} - -############################################################ -# replace_special_chars_in_string(string) -# ersetzt in string alle Sonderzeichen durch Standard ASCII-Zeichen -# hier fehlt noch ein Mechanismus, der gefundene Ersetzungen protokolliert -############################################################ -sub replace_special_chars_in_str { - my $str = $_[0]; - $str =~ s/ä/ae/g; - $str =~ s/ö/oe/g; - $str =~ s/ü/ue/g; - $str =~ s/Ä/Ae/g; - $str =~ s/Ö/Oe/g; - $str =~ s/Ü/Ue/g; - $str =~ s/ß/ss/g; - $str =~ s/é/e/g; - $str =~ s/è/e/g; - $str =~ s/á/a/g; - $str =~ s/à/a/g; - $str =~ s/í/i/g; - $str =~ s/ì/i/g; - return $str; -} - -############################################################ -# replace_special_chars(file_name) -# ersetzt in file_name alle Sonderzeichen durch ASCII-Zeichen -############################################################ -sub replace_special_chars { - my ($orig_line, $line, $input, $file, $output, @text); - @text = qw(); - - $input = new IO::File("< $_[0]") - or die "Cannot open file $_[0] for reading: $!"; - - while (<$input>) { - $line = $_; - $orig_line = $line; - $line = replace_special_chars_in_str($line); - push @text, ($line); - - # print $output $line; - if ($orig_line ne $line) {print "changed $orig_line to $line\n";} - } - $input->close; - $output = new IO::File("> $_[0]") - or die "Cannot open file $_[0] for writing: $!"; - foreach $line (@text) { - print $output $line; - } - $output->close; -} - - -############################################################ -# replace_import_id_in_csv -# -############################################################ -sub replace_import_id_in_csv { - my $csv_file = shift; - my $import_id = shift; - my $result = 0; - my $line; - - # s/^\"(\d+)\"/\"$import_id\"/g' $csv_file; - my $CSVFILE = new IO::File("< $csv_file"); - my $NEWCSVFILE = new IO::File("> $csv_file.tmp"); - if ($CSVFILE && $NEWCSVFILE) - { - while (<$CSVFILE>) { - $line = $_; - $line =~ s/^\"(\d+)\"/\"$import_id\"/; - #print ("line=$line"); - print $NEWCSVFILE $line; - } - $CSVFILE->close; - $NEWCSVFILE->close; - system("mv '$csv_file.tmp' '$csv_file'"); - } - else - { - output_txt("Cannot open file $csv_file for reading: $!", 3); - } - return (!$result); -} - -############################################################ -# copy_file_to_db -# -############################################################ -sub copy_file_to_db { - my $sqlcode = shift; - my $csv_file = shift; - my ($dbh, $sth); - my $result = 0; - - my $CSVFILE = new IO::File("< $csv_file"); - if ($CSVFILE) { - $dbh = DBI->connect("dbi:Pg:dbname=$fworch_database;host=$fworch_srv_host;port=$fworch_srv_port", "$fworch_srv_user", "$fworch_srv_pw"); - if (!defined $dbh) { - output_txt("Cannot connect to database!\n", 3); - } - else { - $dbh->do($sqlcode); - while (<$CSVFILE>) { - $dbh->pg_putline($_); - } - $result = $dbh->pg_endcopy; - $dbh->disconnect; - $CSVFILE->close; - } - } - else { - output_txt("Cannot open file $csv_file for reading: $!", 3); - } - return (!$result); -} - -############################################################ -# eval_boolean_sql(sql-befehl) -# wertet das Ergebnis des sql-befehls aus (true oder false -############################################################ -sub eval_boolean_sql { - my ($sqlcode); - my ($rc, $dbh, $sth); - my (@result); - our ($fworch_srv_host, $fworch_database, $fworch_srv_port, $fworch_srv_user, $fworch_srv_pw, $dbdriver); - - $sqlcode = $_[0]; - $dbh = DBI->connect("dbi:$dbdriver:dbname=$fworch_database;host=$fworch_srv_host;port=$fworch_srv_port", "$fworch_srv_user", "$fworch_srv_pw"); - if (!defined $dbh) {die "Cannot connect to database!\n";} - $sth = $dbh->prepare($sqlcode); - if (!defined $sth) {die "Cannot prepare statement: $DBI::errstr\n";} - $sth->execute; - @result = $sth->fetchrow_array; - $sth->finish; - $dbh->disconnect; - return $result[0]; -} - -############################################################ -# exec_pgsql_cmd_return_value(cmd) -# fuehrt den SQL-Befehl cmd aus und gibt das Resultat des SQL-Befehls zurueck -############################################################ -sub exec_pgsql_cmd_return_value { - return eval_boolean_sql($_[0]); -} - -############################################################ -# exec_pgsql_cmd_return_array_ref(cmd) -# fuehrt den SQL-Befehl cmd aus und gibt das Resultat des SQL-Befehls -# als Verweis auf ein Array zurueck -############################################################ -sub exec_pgsql_cmd_return_array_ref { - my ($res, $err_str, $err_flag, $sqlcode, $result); - # $result: references the result array - my ($rc, $dbh, $sth); - our ($fworch_srv_host, $fworch_database, $fworch_srv_port, $fworch_srv_user, $fworch_srv_pw, $dbdriver); - - $sqlcode = $_[0]; - $err_flag = 0; - $dbh = DBI->connect("dbi:$dbdriver:dbname=$fworch_database;host=$fworch_srv_host;port=$fworch_srv_port", "$fworch_srv_user", "$fworch_srv_pw"); - if (!defined $dbh) {die "Cannot connect to database!\n";} - if ($sqlcode !~ /^$/) { - # print "$sqlcode\n"; - $sth = $dbh->prepare($sqlcode); - if (!defined $sth) {die "Cannot prepare statement: $DBI::errstr\n";} - $res = $sth->execute; - $err_str = $sth->errstr; - if (defined($err_str) && length($err_str) > 0) { - $err_flag = 1; - } - } - $result = $sth->fetchrow_arrayref; - if (!$err_flag) { - $err_str = $sth->errstr; - if (defined($err_str) && length($err_str) > 0) { - $err_flag = 1; - } - } - $sth->finish; - $dbh->disconnect; - # print("locally: result[0][0]=$result->[0][0]"); - return $result; -} - -############################################################ -# exec_pgsql_cmd_return_table_ref(cmd) -# fuehrt den SQL-Befehl cmd aus und gibt das Resultat des SQL-Befehls -# als Verweis auf eine Tabelle (2-dim-Array) zurueck -############################################################ -sub exec_pgsql_cmd_return_table_ref { - my ($res, $err_str, $err_flag, $sqlcode, $result); - # $result: references the result array - my ($rc, $dbh, $sth); - our ($fworch_srv_host, $fworch_database, $fworch_srv_port, $fworch_srv_user, $fworch_srv_pw); - - $sqlcode = $_[0]; - my $keyfield = $_[1]; - $err_flag = 0; - $dbh = DBI->connect("dbi:Pg:dbname=$fworch_database;host=$fworch_srv_host;port=$fworch_srv_port", "$fworch_srv_user", "$fworch_srv_pw"); - if (!defined $dbh) {die "Cannot connect to database!\n";} - if ($sqlcode !~ /^$/) { - # print "$sqlcode\n"; - $sth = $dbh->prepare($sqlcode); - if (!defined $sth) {die "Cannot prepare statement: $DBI::errstr\n";} - $res = $sth->execute; - $err_str = $sth->errstr; - if (defined($err_str) && length($err_str) > 0) { - $err_flag = 1; - } - } - # $result = $sth->fetchrow_arrayref; - # $result = $sth->fetchall_arrayref; - $result = $sth->fetchall_hashref($keyfield); - if (!$err_flag) { - $err_str = $sth->errstr; - if (defined($err_str) && length($err_str) > 0) { - $err_flag = 1; - } - } - $sth->finish; - $dbh->disconnect; - # print("locally: result[0][0]=$result->[0][0]"); - return $result; -} - -############################################################ -# exec_pgsql_cmd(cmd) -# fuehrt den SQL-Befehl cmd aus und gibt error_code zurueck -# das Resultat des SQL-Befehls wird ueber $_[1] gemeldet -############################################################ -sub exec_pgsql_cmd { - my ($res, $err_str, $err_flag, $sqlcode, @result); - my ($rc, $dbh, $sth); - our ($fworch_srv_host, $fworch_database, $fworch_srv_port, $fworch_srv_user, $fworch_srv_pw); - - $sqlcode = $_[0]; - $err_flag = 0; - $dbh = DBI->connect("dbi:Pg:dbname=$fworch_database;host=$fworch_srv_host;port=$fworch_srv_port", "$fworch_srv_user", "$fworch_srv_pw"); - if (!defined $dbh) {die "Cannot connect to database!\n";} - if ($sqlcode !~ /^$/) { - # print "$sqlcode\n"; - $sth = $dbh->prepare($sqlcode); - if (!defined $sth) {die "Cannot prepare statement: $DBI::errstr\n";} - $res = $sth->execute; - $err_str = $sth->errstr; - if (defined($err_str) && length($err_str) > 0) { - $err_flag = 1; - } - } - @result = $sth->fetchrow_array; - if (!$err_flag) { - $err_str = $sth->errstr; - if (defined($err_str) && length($err_str) > 0) { - $err_flag = 1; - } - } - $sth->finish; - $dbh->disconnect; - # return $result[0]; - if (defined($_[1])) { - $_[1] = $result[0]; - if (!defined($result[0])) { - return error_handler('EMPTY_SQL_RESULT'); - } - } - if (!$err_flag) {return 0;} - else {return $err_str;} -} - -############################################################ -# exec_pgsql_cmd_no_result(cmd) -# fuehrt den SQL-Befehl cmd aus und gibt kein Resultat zurueck -############################################################ -sub exec_pgsql_cmd_no_result { - my ($res, $err_str, $sqlcode, $err_flag); - my ($dbh, $sth); - our ($fworch_srv_host, $fworch_database, $fworch_srv_port, $fworch_srv_user, $fworch_srv_pw); - - $err_flag = 0; - $sqlcode = $_[0]; - $dbh = DBI->connect("dbi:Pg:dbname=$fworch_database;host=$fworch_srv_host;port=$fworch_srv_port", "$fworch_srv_user", "$fworch_srv_pw"); - if (!defined $dbh) {die "Cannot connect to database!\n";} - if ($sqlcode !~ /^$/) { - # print "$sqlcode\n"; - $sth = $dbh->prepare($sqlcode); - if (!defined $sth) {die "Cannot prepare statement: $DBI::errstr\n";} - $res = $sth->execute; - $err_str = $sth->errstr; - if (defined($err_str) && length($err_str) > 0) { - $err_flag = 1; - } - } - $sth->finish; - $dbh->disconnect; - if (!$err_flag) {return 0;} - else {return $err_str;} -} - -############################################################ -# exec_pgsql_file(file_name) -# fuehrt die SQL-Befehle in file_name aus -############################################################ -sub exec_pgsql_file { - my ($line, $input, $file, $sqlcode, $res, $err_str, $err_flag); - my ($dbh, $sth); - our ($fworch_srv_host, $fworch_database, $fworch_srv_port, $fworch_srv_user, $fworch_srv_pw); - - $err_flag = 0; - $input = new IO::File("< $_[0]") or die "Cannot open file $_[0] for reading: $!"; - $dbh = DBI->connect("dbi:Pg:dbname=$fworch_database;host=$fworch_srv_host;port=$fworch_srv_port", "$fworch_srv_user", "$fworch_srv_pw"); - if (!defined $dbh) {die "Cannot connect to database!\n";} - while (<$input>) { - $sqlcode = $_; - if ($sqlcode !~ /^$/) { - # print "$sqlcode\n"; - $sth = $dbh->prepare($sqlcode); - if (!defined $sth) {die "Cannot prepare statement: $DBI::errstr\n";} - $res = $sth->execute; - $err_str = $sth->errstr; - if (defined($err_str) && length($err_str) > 0) { - $err_flag = 1; - last; - } - } - } - $input->close; - $sth->finish; - $dbh->disconnect; - if (!$err_flag) {return 0;} - else {return $err_str;} -} - -############################################################ -############################################################ - -sub get_device_ids_for_mgm { - my $mgm_id = $_[0]; - my $aref = exec_pgsql_cmd_return_table_ref("SELECT dev_id FROM device WHERE mgm_id=$mgm_id", 'dev_id'); - # print("aref0: $aref->[0], aref1: $aref->[1]"); - return $aref; -} - -############################################################ -# get_client_filter(client_id) -# zu einem Tenant einen Filter generieren -# Ergebnis ist ein String: zB. "ip<<'1.0.0.0/8' AND ip<<'2.0.0.0/16'" -# Sonderfall: wenn client_id=0 (nicht existent): RETURN "TRUE" --> kein Filter -# parameter1: client_id -############################################################ -sub get_client_filter { - my $client_id = $_[0]; - my ($client_net_ip, $filter, $dbh, $sth, $relevant_import_id, $err_str, $sqlcode); - our ($fworch_database, $fworch_srv_host, $fworch_srv_port, $fworch_srv_user, $fworch_srv_pw); - - $filter = "TRUE"; - if (defined($client_id) && $client_id ne '' && $client_id != 0) { - $sqlcode = "SELECT client_net_ip FROM client_network WHERE client_id=$client_id"; - $dbh = DBI->connect("dbi:Pg:dbname=$fworch_database;host=$fworch_srv_host;port=$fworch_srv_port", "$fworch_srv_user", "$fworch_srv_pw"); - if (!defined $dbh) {die "Cannot connect to database!\n";} - $sth = $dbh->prepare($sqlcode); - if (!defined $sth) {die "Cannot prepare statement: $DBI::errstr\n";} - $sth->execute; - $err_str = $sth->errstr; - if (defined($err_str) && length($err_str) > 0) {error_handler($err_str);} - $filter = "("; - while (($client_net_ip) = $sth->fetchrow()) { - $filter .= " obj_ip<<='$client_net_ip' OR '$client_net_ip'<<=obj_ip OR"; - # sollte eigentlich ein noch zu definierenden Operator sein: ip1 # ip2 ip1 und ip2 haben eine nicht leere Schnittmenge - } - $filter .= " FALSE)"; - $sth->finish; - $dbh->disconnect; - } - return $filter; -} - -sub get_rulebase_names { - # getting device-info for all devices of the current mgmt - my $mgm_id = shift; - my $dbdriver = shift; - my $fworch_database = shift; - my $fworch_srv_host = shift; - my $fworch_srv_port = shift; - my $fworch_srv_user = shift; - my $fworch_srv_pw = shift; - - my $dbh = DBI->connect("dbi:$dbdriver:dbname=$fworch_database;host=$fworch_srv_host;port=$fworch_srv_port", "$fworch_srv_user", "$fworch_srv_pw"); - if (!defined $dbh) {die "Cannot connect to database!\n";} -# my $sth = $dbh->prepare("SELECT dev_id,dev_name,local_rulebase_name,global_rulebase_name FROM device WHERE mgm_id=$mgm_id AND NOT do_not_import"); - my $sth = $dbh->prepare("SELECT dev_id,dev_name,local_rulebase_name FROM device WHERE mgm_id=$mgm_id AND NOT do_not_import"); - if (!defined $sth) {die "Cannot prepare statement: $DBI::errstr\n";} - $sth->execute; - my $rulebases = $sth->fetchall_hashref('dev_id'); - $sth->finish; - $dbh->disconnect; - return $rulebases; -} - -# convert hash to comma separated string -# sub get_ruleset_name_list { -# my $href_rulesetname = shift; -# my $result = ''; - -# while ( (my $key, my $value) = each %{$href_rulesetname}) { -# $result .= $value->{'dev_rulebase'} . ','; -# } -# if ($result =~ /^(.+?)\,$/) { # stripping off last comma -# return $1; -# } -# return $result; -# } - -# convert hash to comma separated string -sub get_local_ruleset_name_list { - my $href_rulesetname = shift; - my $result = ''; - - while ( (my $key, my $value) = each %{$href_rulesetname}) { - $result .= $value->{'local_rulebase_name'} . ','; - } - if ($result =~ /^(.+?)\,$/) { # stripping off last comma - return $1; - } - return $result; -} - -# convert hash to comma separated string -sub get_global_ruleset_name_list { - my $href_rulesetname = shift; - my $result = ''; - - if (defined($href_rulesetname)) { - while ( (my $key, my $value) = each %{$href_rulesetname}) { - if (defined($value->{'global_rulebase_name'})) { - $result .= $value->{'global_rulebase_name'} . ','; - } else { - $result .= ','; - } - } - if ($result =~ /^(.+?)\,$/) { # stripping off last comma - return $1; - } - return $result; - } else { - return ""; - } -} - -sub evaluate_parameters { - my $mgm_id = shift; - my $mgm_name = shift; - - if (!defined($mgm_id) || $mgm_id eq '') { - if (defined($mgm_name) && $mgm_name ne '') { - $mgm_id = exec_pgsql_cmd_return_value("select mgm_id from management where mgm_name='$mgm_name'"); - } - else {&error_handler_add(undef, my $error_level = 5, "fworch-importer-single.pl: missing argument (mgm_id || mgm_name)", 1, 0);} # no valid input given - } - if (!defined($mgm_id) || $mgm_id eq '') { - &error_handler_add(undef, my $error_level = 5, 'Management ' . (($mgm_name ne '') ? $mgm_name . ' ' : '') . 'not found', 1, 0); - } - return ($mgm_id, $mgm_name); -} - -##################################################################################### - -1; -__END__ - -=head1 NAME - -FWORCH - Perl extension for fworch - -=head1 SYNOPSIS - - use FWORCH; - the function read_basic_fworch_data() must be called first to - generate the hashes before using the DB-lookup functions - -=head1 DESCRIPTION - -fworch Perl Module -support for -- importing configs into fworch Database -- basic functions to access fworch DB - -=head2 EXPORT - - global variables - %managementID - %object_typID - %IP_protocolID - - DB functions - read_basic_fworch_data() - these functions perform the lookups into the above hashes: - get_mgmtID(management-name) - get_object_typID(objekt-name) - get_ip_protoID(IP-protocol-name) - - Basic functions - is_numeric(scalar) - -=head1 SEE ALSO - - behind the door - -=head1 AUTHOR - - Tim Purschke, tmp@cactus.de - -=cut diff --git a/roles/importer/files/importer/CACTUS/FWORCH/import.pm b/roles/importer/files/importer/CACTUS/FWORCH/import.pm deleted file mode 100644 index f4dd78e16d..0000000000 --- a/roles/importer/files/importer/CACTUS/FWORCH/import.pm +++ /dev/null @@ -1,1332 +0,0 @@ -package CACTUS::FWORCH::import; -use strict; -use warnings; -use DBD::Pg; -use DBI; -use IO::File; -use Getopt::Long; -use File::Basename; -use FileHandle; -use CGI qw(:standard); -use Time::HiRes qw(time); # fuer hundertstelsekundengenaue Messung der Ausfuehrdauer -use CACTUS::FWORCH; -use CACTUS::read_config; - -require Exporter; -our @ISA = qw(Exporter); - -our %EXPORT_TAGS = ( - 'basic' => [ qw( - &get_mgm_id_of_import &is_import_running &get_matching_import_id &remove_control_entry - &insert_control_entry &is_initial_import - &put_ssh_keys_in_place - &get_import_infos_for_device &get_import_infos_for_mgm - &import_cleanup_and_summary &ruleset_does_not_fit &clean_up_fworch_db - &print_debug &print_verbose &d2u &calc_subnetmask &convert_mask_to_dot_notation - &print_results_monitor - &print_results_files_objects - &print_results_files_rules - &print_results_files_users - &print_results_files_zones - &print_results_files_audit_log - &get_proto_number - &set_last_change_time - &fill_import_tables_from_csv_with_sql - &fill_import_tables_from_csv - %network_objects @network_objects %services @services %rulebases @ruleorder @rulebases @zones - %user %usergroup @user_ar $usergroupdelimiter - $audit_log_count %auditlog - $mode $last_change_time_of_config - $verbose $debug $mgm_name - @obj_outlist @srv_outlist @rule_outlist - ) ] ); - -our @EXPORT = ( @{ $EXPORT_TAGS{'basic'} } ); -our $VERSION = '0.3'; - - -our $verbose = 0; # globaler Schalter bzgl. der Ausgabe: 1=verbose, 0=silent; -our $debug = 0; # globaler Schalter bzgl. Druck der Debug info: 1=debug, 0=silent; -our $mode; - -# Laufvariablen Parser -our $mgm_name = ''; # globale Variable fuer den Namen des Managements -# nur innerhalb der objekte gueltig -# hashes zur Speicherung der Parserergebnisse (Eigenschaften) -our @zones; -our %network_objects; -our %services; -our %rulebases; # hash der rulebases -our @ruleorder; # Array mit Regel-IDs -# wird derzeit eigentlich nur fuer netscreen benoetigt -# CheckPoint: 1-n -# Netscreen: policy id), Feld startet mit 1! -# phion: wie Check Point - -our @network_objects = (); # liste aller namen der netzobjekte -our @services = (); # liste aller namen der services -our @rulebases = (); # liste der definierten rulebases - -our $audit_log_count = 0; -our %auditlog; - -our %user; -our %usergroup; -our @user_ar = (); -our $usergroupdelimiter = &CACTUS::read_config::read_config('usergroup_delimiter'); - -our $last_change_time_of_config; - -# Listen mit Schnittstelleninformationen -# xxx_outlist: Felder im Perl-Hash, die in CSV-Datei geschrieben werden -# xxx_import_fields: Felder der xxx_import-Tabellen, die aus der CSV-Datei gefuellt werden -# @xxx: (@services, @objects, ...): Listen mit den Namen? aller Basiselemente - -# TODO: zu jedem Gruppenmitglied die Moeglichkeit eines Negationsflags -# TODO: zu jeder Referenz (Gruppenmitglieder, Regelbestandteile) eindeutige UIDs einfuehren und nur diese fuer Import-Prozess verwenden - -# Ausgabe der Objektparameter -our @obj_outlist =(qw ( name type members member_refs cpver ipaddr ipaddr_last color comments location zone - UID last_change_admin last_change_time)); -# Planung: -# - member enthaelt nur noch eine Liste mit Referenzen und nicht mit Namen -# - Separator: | -# - Anzeige der Negation mit "$$__not__$$" -# - Neues DB-Feld fuer Negation fuer alle Gruppen- und Regelanteilbeziehungen - -our @obj_import_fields = qw ( - control_id - obj_name - obj_typ - obj_member_names - obj_member_refs - obj_sw - obj_ip - obj_ip_end - obj_color - obj_comment - obj_location - obj_zone - obj_uid - last_change_admin - last_change_time -); - -# Ausgabe der Serviceparameter -our @srv_outlist =(qw ( name typ type members member_refs color ip_proto port port_last src_port src_port_last - comments rpc_port timeout_std timeout UID last_change_admin last_change_time)); - -our @svc_import_fields = qw ( - control_id - svc_name - svc_typ - svc_prod_specific - svc_member_names - svc_member_refs - svc_color - ip_proto - svc_port - svc_port_end - svc_source_port - svc_source_port_end - svc_comment - rpc_nr - svc_timeout_std - svc_timeout - svc_uid - last_change_admin - last_change_time -); -# Ausgabe der Userparameter -our @user_outlist =(qw ( type members member_refs color comments uid expdate last_change_admin )); - -our @user_import_fields = qw ( - control_id - user_name - user_typ - user_member_names - user_member_refs - user_color - user_comment - user_uid - user_valid_until - last_change_admin -); - -our @zone_outlist =(qw ( zone )); - -our @zone_import_fields = qw ( - control_id - zone_name -); - -# Ausgabe der Regelparameter -our @rule_outlist =(qw ( rule_id disabled src.op src src.refs dst.op dst dst.refs services.op services services.refs - action track install time comments name UID header_text src.zone dst.zone last_change_admin parent_rule_uid)); - -our @rule_import_fields = qw ( - control_id - rule_num - rulebase_name - rule_ruleid - rule_disabled - rule_src_neg - rule_src - rule_src_refs - rule_dst_neg - rule_dst - rule_dst_refs - rule_svc_neg - rule_svc - rule_svc_refs - rule_action - rule_track - rule_installon - rule_time - rule_comment - rule_name - rule_uid - rule_head_text - rule_from_zone - rule_to_zone - last_change_admin - parent_rule_uid -); - -our @auditlog_outlist = qw ( change_time management_name changed_object_name changed_object_uid changed_object_type change_action change_admin ); - -our @auditlog_import_fields = qw ( control_id import_changelog_nr change_time management_name changed_object_name changed_object_uid changed_object_type change_action change_admin ); - -############################################################################################################ -# allgemeine Funktionen -############################################################################################################ - -sub put_ssh_keys_in_place { - my $workdir = shift; - my $ssh_public_key = shift; - my $ssh_private_key = shift; - my $fehler_count = 0; - - # debugging - # print ("put_ssh_keys_in_place::workdir=$workdir, ssh_public_key=$ssh_public_key, ssh_private_key=$ssh_private_key\n"); - $fehler_count += (system("$echo_bin \"$ssh_private_key\" > $workdir/$CACTUS::FWORCH::ssh_id_basename") != 0); - if (defined($ssh_public_key) && $ssh_public_key ne "") { - # only create public key file if the key is defined and not empty - $fehler_count += (system("$echo_bin \"$ssh_public_key\" > $workdir/$CACTUS::FWORCH::ssh_id_basename.pub") != 0); # only necessary for netscreen - } - $fehler_count += (system("$chmod_bin 400 $workdir/$CACTUS::FWORCH::ssh_id_basename") != 0); - return $fehler_count; -} - - -sub ruleset_does_not_fit { - my $rulebasename_to_find = shift; - my $href_rulesetname = shift; - my $result = 1; - - while ( (my $key, my $value) = each %{$href_rulesetname}) { - if ($rulebasename_to_find eq $value->{'local_rulebase_name'}) { - $result=0; - } - } - return $result; -} - -############################################################ -# get_mgm_id_of_import(mgm_id,mgm_name,dev_id,dev_name) -# liefert wenn herleitbar die mgm_id zurueck, ansonsten undef -############################################################ -sub get_mgm_id_of_import { - my $mgm_id = shift; - my $mgm_name = shift; - my $dev_id = shift; - my $dev_name = shift; - - if (is_empty($mgm_id)) { - if (!is_empty($dev_id)) { - $mgm_id = exec_pgsql_cmd_return_value("SELECT mgm_id FROM device WHERE dev_id=$dev_id"); - } elsif (!is_empty($mgm_name)) { - $mgm_id = exec_pgsql_cmd_return_value("SELECT mgm_id FROM management WHERE mgm_name='$mgm_name'"); - } elsif (!is_empty($dev_name)) { - $mgm_id = exec_pgsql_cmd_return_value("SELECT mgm_id FROM device WHERE dev_name='$dev_name'"); - } else { # no info to derive mgm_id from has been passed to sub - undef($mgm_id); - } - } - return $mgm_id; -} - -############################################################ -# is_import_running() -# liefert FALSE, wenn kein import aktiv ist -############################################################ -sub is_import_running { - my $mgm_id = shift; - return eval_boolean_sql("SELECT is_import_running($mgm_id)"); -} - -############################## -# is_initial import(MGM-ID) -# liefert TRUE, wenn noch kein import fuer MGM-ID gelaufen ist -############################################################ -sub is_initial_import { - my $mgm_id = shift; - return (!defined(&exec_pgsql_cmd_return_value("SELECT control_id FROM import_control WHERE mgm_id=\'$mgm_id\' AND successful_import "))); -} -############################################################ -# get_matching_import_id() -# relevanten Import raussuchen (datum und id) -# = letzter Import fuer das Device vor $time -# liefert die passende import ID zurueck -# parameter1: device ID -# parameter2: gesuchter Zeitpunkt -############################################################ -sub get_matching_import_id { - my $dev_id = $_[0]; - my $time = $_[1]; - my ($mgm_id, $dbh, $sth, $relevant_import_id, $err_str, $sqlcode); - - $sqlcode = "SELECT mgm_id FROM device WHERE dev_id=$dev_id"; - $dbh = DBI->connect("dbi:Pg:dbname=$CACTUS::FWORCH::fworch_database;host=$CACTUS::FWORCH::fworch_srv_host;port=$CACTUS::FWORCH::fworch_srv_port","$CACTUS::FWORCH::fworch_srv_user","$CACTUS::FWORCH::fworch_srv_pw"); - if ( !defined $dbh ) { die "Cannot connect to database!\n"; } - $sth = $dbh->prepare( $sqlcode ); - if ( !defined $sth ) { die "Cannot prepare statement: $DBI::errstr\n"; } - $sth->execute; - $err_str = $sth->errstr; - if (defined($err_str) && length($err_str)>0) { error_handler($err_str); } - ($mgm_id) = $sth->fetchrow(); - $sth->finish; - if (!defined($mgm_id)) { - print("Management zum Device $dev_id nicht gefunden."); - return -1; - } - #------ - $sqlcode = "SELECT control_id FROM import_control WHERE mgm_id=$mgm_id AND start_time<='" . - $time . "' AND successful_import ORDER BY control_id desc LIMIT 1"; - $sth = $dbh->prepare( $sqlcode ); - if ( !defined $sth ) { die "Cannot prepare statement: $DBI::errstr\n"; } - $sth->execute; - $err_str = $sth->errstr; - if (defined($err_str) && length($err_str)>0) { error_handler($err_str); } - ($relevant_import_id) = $sth->fetchrow(); - $sth->finish; - $dbh->disconnect; - if (!defined($relevant_import_id)) { - print("kein Import gefunden."); - return -1; - } - return $relevant_import_id; -} - -############################################################ -# insert_control_entry(is_initial_import, mgm_id) -# erzeugt neuen eintrag in import_control und -# liefert die control_id zurueck -############################################################ -sub insert_control_entry { - my $is_initial_import = shift; - my $mgm_id = shift; - my ($rc, $dbh, $sth); - my $current_control_id; - my $sql_str; - - $is_initial_import = (($is_initial_import)?'TRUE':'FALSE'); - $dbh = DBI->connect("dbi:Pg:dbname=$CACTUS::FWORCH::fworch_database;host=$CACTUS::FWORCH::fworch_srv_host;port=$CACTUS::FWORCH::fworch_srv_port", - "$CACTUS::FWORCH::fworch_srv_user","$CACTUS::FWORCH::fworch_srv_pw"); - if ( !defined $dbh ) { die "Cannot connect to database!\n"; } - $rc = $dbh->begin_work; - $sql_str = "INSERT INTO import_control (is_initial_import,mgm_id) VALUES ($is_initial_import,$mgm_id)"; - # print ("\n\nSQL: $sql_str\n\n"); - $sth = $dbh->prepare( $sql_str ); - if ( !defined $sth ) { die "Cannot prepare statement: $DBI::errstr\n"; } - $sth->execute; - $sth = $dbh->prepare( "SELECT MAX(control_id) FROM import_control;"); - if ( !defined $sth ) { die "Cannot prepare statement: $DBI::errstr\n"; } - $sth->execute; - ($current_control_id) = $sth->fetchrow(); - $rc = $dbh->commit; - $sth->finish; - $dbh->disconnect; - return $current_control_id; -} - -############################################################ -# set_last_change_time($last_change_time_of_config,$current_import_id) -# liefert die control_id zurueck -############################################################ -sub set_last_change_time { - my $last_change_time_of_config = shift; - my $current_import_id = shift; - - if (defined($last_change_time_of_config)) { - # print("\nlast change_time found: $last_change_time_of_config"); - my $sql_cmd1 = - "UPDATE import_control SET last_change_in_config='$last_change_time_of_config' " . - "WHERE control_id=$current_import_id"; - CACTUS::FWORCH::exec_pgsql_cmd_no_result($sql_cmd1); - } -} -############################################################ -# remove_control_entry($current_import_id) -# setzt Import-Eintrag auf NOT successful_import, wenn Fehler aufgetreten ist -############################################################ -sub remove_control_entry { - my $import_id = shift; - my $sql_str = "UPDATE import_control SET successful_import=FALSE WHERE control_id=$import_id"; - return exec_pgsql_cmd_no_result($sql_str); -} - -############################################################ -# get_import_infos_for_mgm($mgm_id, $fworch_workdir) -# liefert vielfaeltige Infos zu einem zu importierenden Management zurueck -############################################################ -sub get_import_infos_for_mgm { - my $mgm_id = shift; - my $fworch_workdir = shift; - my $cfg_dir = shift; - my ($dbh, $sth, $rc, $sth2); - my ($err_str, %devices_with_rulebases, $mgm_name, $fields, $tables, $filter, $order, $sqlcode, - $dev_typ_id,$ssh_hostname,$ssh_user,$ssh_private_key,$ssh_public_key,$hersteller); - my ($template, $obj_file, $obj_file_base, $user_file, $user_file_base, $rule_file, $rule_file_base, - $fworch_ctrl, $cmd_str, $is_netscreen, $ssh_port, $config_path_on_mgmt); - my @result = (); - my $fehler_cnt = 0; - my $res = ''; - my $fehler = 0; - my $res_array_ref; - my $str_of_config_files = ''; - my $version; - - $sqlcode = "SELECT mgm_name,management.dev_typ_id,dev_typ_manufacturer,dev_typ_version,ssh_hostname, " . - " username as ssh_user,secret, public_key as ssh_public_key,ssh_port,config_path FROM management " . - " LEFT JOIN import_credential ON (management.import_credential_id=import_credential.id) LEFT JOIN stm_dev_typ USING (dev_typ_id) " . - " WHERE stm_dev_typ.dev_typ_id=management.dev_typ_id AND mgm_id='$mgm_id'"; - $res_array_ref = exec_pgsql_cmd_return_array_ref($sqlcode, $fehler); - if (!defined($fehler) || $fehler || !defined($res_array_ref)) { - if (!defined($fehler)) { - $fehler = "undefined error"; - } - $fehler_cnt += 1; - @result = (1, $fehler); - return @result; - } - ($mgm_name,$dev_typ_id,$hersteller,$version,$ssh_hostname,$ssh_user,$ssh_private_key,$ssh_public_key,$ssh_port,$config_path_on_mgmt) = @$res_array_ref; - - $hersteller = lc(remove_space_at_end($hersteller)); - if ($hersteller =~ /netscreen/) { $is_netscreen = 1; $hersteller = 'netscreen'; } - else { $is_netscreen = 0; } - - #if ($hersteller =~ /check\spoint\sr8x/) { $hersteller = 'checkpointR8x'; } - print ("version: $version, manufacturer: $hersteller, "); - if ($hersteller =~ /check\spoint/ && $version eq 'R8x') { $hersteller = 'checkpointR8x'; } - elsif ($hersteller =~ /check/) { $hersteller = 'checkpoint'; } - if ($hersteller =~ /phion/) { $hersteller = 'phion'; } - - my $csv_zone_file = "$fworch_workdir/" . $mgm_name . "_zones" . ".csv"; - my $csv_obj_file = "$fworch_workdir/" . $mgm_name . "_netzobjekte" . ".csv"; - my $csv_svc_file = "$fworch_workdir/" . $mgm_name . "_services" . ".csv"; - my $csv_usr_file = "$fworch_workdir/" . $mgm_name . "_users" . ".csv"; - my $csv_auditlog_file = "$fworch_workdir/" . $mgm_name . "_auditlog" . ".csv"; - - if ($hersteller eq 'checkpoint') { # checkpoint - $obj_file_base = "objects_5_0.C"; - $obj_file = $cfg_dir . '/' . $obj_file_base; - $rule_file_base = "rulebases_5_0.fws"; - $rule_file = $cfg_dir . '/' . $rule_file_base; - $user_file_base = "fwauth.NDB"; - $user_file = $cfg_dir . '/' . $user_file_base; - $str_of_config_files = "${obj_file},${rule_file},${user_file}"; - } elsif ($hersteller eq 'checkpointr8x') { # checkpoint R80 ff. - print ("DEBUG: found hersteller checkpointr8x"); - $obj_file_base = "nw_objects.json"; - $obj_file = $cfg_dir . '/' . $obj_file_base; - $rule_file_base = "rules.json"; - $rule_file = $cfg_dir . '/' . $rule_file_base; - # $user_file_base = "fwauth.NDB"; - # $user_file = $cfg_dir . '/' . $user_file_base; - $str_of_config_files = "${obj_file},${rule_file}"; - } elsif ($hersteller eq 'phion') { # phion - $obj_file_base = ''; - $obj_file = $cfg_dir . "/" . $obj_file_base; - $rule_file_base = ''; - $rule_file = $obj_file; - $user_file_base = $obj_file_base; - $user_file = $obj_file; - $str_of_config_files = $cfg_dir . '/' . "iso-phion-config.tgz"; - } - else { # e.g. hersteller = juniper (JUNOS), cisco (ASA), netscreen (ScreenOS) - $obj_file_base = $mgm_name . ".cfg"; - $obj_file = $cfg_dir . "/" . $obj_file_base; - $rule_file_base = $obj_file_base; - $rule_file = $obj_file; - $user_file_base = $obj_file_base; - $user_file = $obj_file; - $str_of_config_files = $obj_file; - } - $rule_file = $cfg_dir . '/' . $rule_file_base; - @result = (0, "", $mgm_name, $dev_typ_id, - $obj_file_base,$obj_file,$user_file_base,$user_file,$rule_file_base,$rule_file, - $csv_zone_file, $csv_obj_file, $csv_svc_file, $csv_usr_file, $csv_auditlog_file, - $ssh_hostname,$ssh_user,$ssh_private_key,,$ssh_public_key,$hersteller,$is_netscreen,$str_of_config_files,$ssh_port,$config_path_on_mgmt); - return @result; -} - -############################################################ -# clean_up_fworch_db ($current_import_id) -# fuehrt vacuum analyze fuer diverse Tabellen durch -# loescht die Eintraege des aktuellen Imports aus den import_*-Tabellen -############################################################ -sub clean_up_fworch_db { - my $current_import_id = shift; - - # loeschen der Import-Tabellen und neuordnen - exec_pgsql_cmd_no_result ("DELETE FROM import_object WHERE control_id=$current_import_id"); - exec_pgsql_cmd_no_result ("DELETE FROM import_service WHERE control_id=$current_import_id"); - exec_pgsql_cmd_no_result ("DELETE FROM import_user WHERE control_id=$current_import_id"); - exec_pgsql_cmd_no_result ("DELETE FROM import_rule WHERE control_id=$current_import_id"); - exec_pgsql_cmd_no_result ("DELETE FROM import_zone WHERE control_id=$current_import_id"); -} - -# produktunabhaengige Parse Subroutinen -#------------------------------------------------------------------------------------------- - -#**************************** -# print_debug -# param1 auszugebender String -# return keiner -# Funktion zum Druck von debugging Info, wenn der Schalter entsprechend gesetzt ist. -#**************************** - -sub print_debug { - my $txt = shift; - my $debug_level = shift; - my $print_level = shift; - - if (!defined ($debug_level)) { $debug_level = 0; } - if (!defined ($print_level)) { $print_level = 0; } - if (&is_numeric($print_level) && &is_numeric($debug_level)) { - if ($print_level < $debug_level) { print "Debug ($debug_level/$print_level): $txt.\n"; } - } else { - print "Debug ($debug_level/$print_level): $txt.\n"; - } -} - -#**************************** -# print_verbose -# param1 auszugebender String -# return keiner -# Funktion zum Druck geschwaetziger (verbose) Info, wenn der Schalter entsprechend gesetzt ist. -#**************************** -sub print_verbose { - print "Verbose: " if ($debug); - print "$_[0]" if (($verbose)||($debug)); -} - -#**************************** -# d2u - dos 2 unix -# param1 zu aendernder String -# return \n fuer jedes \r\n in einem String -# Funktion zum Wandeln eines DOS in einen UNIX String -#**************************** -sub d2u { - return ($_[0]=~s/\r\n/\n/g); -} - -#**************************** -# calc_subnetmask_sub -# param1 netzmaske in der Form xxx -# return netzmaske als Bitzahl -# Unterfunktion zur Berechnung von Teil-Subnetzmasken -#**************************** -sub calc_subnetmask_sub { - my $netmask_in = shift; - my $count = 0; - my $temp = 0; - - if (!defined($netmask_in)) { - return undef; - } - for ( ;($temp < int ($netmask_in));$temp += (2 ** (7 - $count++))) { }; - return $count; -} - -#**************************** -# calc_subnetmask -# param1 netzmaske in der Form xxx.xxx.xxx.xxx -# return netzmaske als Bitzahl -# Funktion zur Berechnung von Subnetzmasken -#**************************** -sub calc_subnetmask { - my $netmask_in = shift; - if (!defined($netmask_in)) { - return undef; - } - $netmask_in =~ /([0-9]+).([0-9]+).([0-9]+).([0-9]+)/; - my $temp1 = calc_subnetmask_sub($1); - my $temp2 = calc_subnetmask_sub($2); - my $temp3 = calc_subnetmask_sub($3); - my $temp4 = calc_subnetmask_sub($4); - my $temp0= $temp1 +$temp2 + $temp3 + $temp4; - print_debug ("\t\t$temp0 = $1 - $temp1\t\t$2 - $temp2\t\t$3 - $temp3\t\t$4 - $temp4\n"); - return $temp0; -} - -#**************************** -# convert_mask_to_dot_notation -# param1 netzmaske in der Form /xx -# return netzmaske in dot-Notation (e.g. 255.255.255.248) -#**************************** -sub convert_mask_to_dot_notation { - my $bits = shift; - - if ($bits =~ /(\d\d?)/) { - $bits = $1/1; - } else { - $bits = 32; - } - $bits == 0 && do return "0.0.0.0"; - $bits == 1 && do return "128.0.0.0"; - $bits == 2 && do return "192.0.0.0"; - $bits == 3 && do return "224.0.0.0"; - $bits == 4 && do return "240.0.0.0"; - $bits == 5 && do return "248.0.0.0"; - $bits == 6 && do return "252.0.0.0"; - $bits == 7 && do return "254.0.0.0"; - $bits == 8 && do return "255.0.0.0"; - $bits == 9 && do return "255.128.0.0"; - $bits == 10 && do return "255.192.0.0"; - $bits == 11 && do return "255.224.0.0"; - $bits == 12 && do return "255.240.0.0"; - $bits == 13 && do return "255.248.0.0"; - $bits == 14 && do return "255.252.0.0"; - $bits == 15 && do return "255.254.0.0"; - $bits == 16 && do return "255.255.0.0"; - $bits == 17 && do return "255.255.128.0"; - $bits == 18 && do return "255.255.192.0"; - $bits == 19 && do return "255.255.224.0"; - $bits == 20 && do return "255.255.240.0"; - $bits == 21 && do return "255.255.248.0"; - $bits == 22 && do return "255.255.252.0"; - $bits == 23 && do return "255.255.254.0"; - $bits == 24 && do return "255.255.255.0"; - $bits == 25 && do return "255.255.255.128"; - $bits == 26 && do return "255.255.255.192"; - $bits == 27 && do return "255.255.255.224"; - $bits == 28 && do return "255.255.255.240"; - $bits == 29 && do return "255.255.255.248"; - $bits == 30 && do return "255.255.255.252"; - $bits == 31 && do return "255.255.255.254"; - $bits == 32 && do return "255.255.255.255"; -} - -#**************************** -# get_protocol_number -# param1 string des ip-proto -# return ip_proto_number -# Funktion zur Umwandlung von Protonamen in Protonummern -#**************************** -sub get_proto_number { - my $proto_in = shift; - my $proto_out = 'Fehler: proto nicht gefunden'; - - if (is_numeric($proto_in)) { - return $proto_in; - } elsif ($proto_in eq 'tcp') { - $proto_out = 6; - } elsif ($proto_in eq 'udp') { - $proto_out = 17; - } elsif ($proto_in eq 'icmp') { - $proto_out = 1; - } - if ($proto_out eq 'Fehler: proto nicht gefunden') { - # print ("error: proto_in not found in import.pm::get_proto_number: $proto_in\n"); - undef ($proto_out); - } - return $proto_out; -} - -#**************************** -# print_cell_no_delimiter Output in Dateien -# return keiner -# schreibt ein Feld der gefundenen Parserergebnisse in Datei, ohne abschliessenden Delimiter -#**************************** -sub print_cell_no_delimiter { - my $file = shift; - my $cell = shift; - $cell =~ s/$CACTUS::FWORCH::csv_delimiter/\\$CACTUS::FWORCH::csv_delimiter/g; - if (defined($cell) && $cell ne '') { - if ($cell =~ /^\".*?\"$/) { # Zelle schon von doppelten Anfuehrungszeichen eingerahmt - print $file "$cell"; - } else { - print $file "\"$cell\""; - } - } - return; -} - -#**************************** -# print_cell Output in Dateien -# return keiner -# schreibt ein Feld der gefundenen Parserergebnisse in Datei -#**************************** -sub print_cell { - my $file = shift; - my $cell = shift; - &print_cell_no_delimiter ($file, $cell); - print_cell_delimiter($file); - return; -} - -sub print_cell_delimiter { - my $file = shift; - print $file $CACTUS::FWORCH::csv_delimiter; - return; -} - - -############################ -# print_results_files_objects -############################ -sub print_results_files_objects { - my $out_dir = shift; - my $mgm_name = shift; - my $import_id = shift; - my $out_file; - my $header_text = ""; - my ($count,$local_schluessel,$schluessel); - - # Oeffnen der Ausgabedatei fuer Objekte - #---------------------------------------- - # print ("beginn csv schreiben\n"); - $out_file = "$out_dir/${mgm_name}_netzobjekte.csv"; - my $fh = new FileHandle; - if ($fh->open("> $out_file")) { - foreach $schluessel (sort (@network_objects)) { - # Ausnahmen fuer die Ausgabe abfragen - if (!defined($network_objects{"$schluessel.type"})) { - print ("\nerror key $schluessel, type not defined"); - } else { - unless ($network_objects{"$schluessel.type"} eq 'sofaware_profiles_security_level'){ - # sollten auch die dynamischen Netzobjekte ausgeblendet werden, ist die folgende Zeile statt der vorhergehenden zu zu aktivieren - # unless (($network_objects{"$schluessel.type"} eq 'sofaware_profiles_security_level') || ($network_objects{"$schluessel.type"} eq 'dynamic_net_obj')) { - # Version fuer Nachbearbeitung im Import Modul - # foreach $local_schluessel (qw ( name type members cp_ver comments color ipaddr ipaddr_last netmask sys location )) { - # if (defined ( $network_objects{"$schluessel.$local_schluessel"} )) { - # print FILEOUT_NETOBJ $network_objects{"$schluessel.$local_schluessel"}; - # } - # Version mit integrierter Nachbearbeitung - print_cell_no_delimiter($fh, $import_id); - foreach (@obj_outlist) { - $local_schluessel = $_; - print_cell_delimiter($fh); - # Ist der Wert definiert? > dann ausgeben - if (defined ( $network_objects{"$schluessel.$local_schluessel"} )) { - # Objekttypen fuer Ausgabe umsetzen ? - if (($local_schluessel eq 'type') && (($network_objects{"$schluessel.$local_schluessel"} eq 'gateway_cluster') || ($network_objects{"$schluessel.$local_schluessel"} eq 'cluster_member'))) { - print_cell_no_delimiter($fh, 'gateway'); - } - elsif (($local_schluessel eq 'type') && (($network_objects{"$schluessel.$local_schluessel"} eq 'machines_range' - || $network_objects{"$schluessel.$local_schluessel"} eq 'multicast_address_range'))) { - print_cell_no_delimiter($fh, 'ip_range'); - } - elsif (($local_schluessel eq 'type') && - (($network_objects{"$schluessel.$local_schluessel"} eq 'dynamic_net_obj' || - $network_objects{"$schluessel.$local_schluessel"} eq 'security_zone_obj' || - $network_objects{"$schluessel.$local_schluessel"} eq 'ips_sensor' || - $network_objects{"$schluessel.$local_schluessel"} eq 'voip_gk' || - $network_objects{"$schluessel.$local_schluessel"} eq 'voip_gw' || - $network_objects{"$schluessel.$local_schluessel"} eq 'voip_sip' || - $network_objects{"$schluessel.$local_schluessel"} eq 'voip_mgcp' || - $network_objects{"$schluessel.$local_schluessel"} eq 'voip_skinny'))) { - print_cell_no_delimiter($fh, 'host'); - } - elsif (($local_schluessel eq 'type') && - (($network_objects{"$schluessel.$local_schluessel"} eq 'group_with_exclusion' || - $network_objects{"$schluessel.$local_schluessel"} eq 'gsn_handover_group' || - $network_objects{"$schluessel.$local_schluessel"} eq 'domain'))) { - print_cell_no_delimiter($fh, 'group'); - # da es jetzt eine Aufloesung der Ausnahme-Gruppen in normale Gruppen gibt, ist das jetzt OK - } - # IP-adresse? - elsif (($local_schluessel eq 'ipaddr')||($local_schluessel eq 'ipaddr_last')) { - # machine ranges immer mit 32 Bit Maske - if ($network_objects{"$schluessel.type"} eq 'machines_range'){ - if ($network_objects{"$schluessel.$local_schluessel"} ne '') { - # print_cell_no_delimiter($fh, $network_objects{"$schluessel.$local_schluessel"}."/32"); - print_cell_no_delimiter($fh, $network_objects{"$schluessel.$local_schluessel"}); - } - } else { # sonst nur die IP-Adresse - my $maske; - if (defined($network_objects{"$schluessel.netmask"}) && - length($network_objects{"$schluessel.netmask"})>0 && - $local_schluessel eq 'ipaddr' && - $network_objects{"$schluessel.ipaddr"} !~ /\//) { - # berechnen - my $ip2 = CACTUS::FWORCH::remove_space_at_end(remove_quotes($network_objects{"$schluessel.$local_schluessel"})); - $maske = $network_objects{"$schluessel.netmask"}; - if ($maske =~ /^\d+\.\d+\.\d+\.\d+$/) { - $maske = calc_subnetmask($maske); # in bit-Notation umwandeln - } # else: Maske enthaelt keine Punkte --> direkt als Integer uebernehmen - if (length($ip2)>0) { - print_cell_no_delimiter($fh, "$ip2/$maske"); - } - } elsif ($network_objects{"$schluessel.ipaddr"} !~ /\//) { - # oder fix auf 32 Bit stellen, wenn maske fehlt und Fehlerausgabe - if (length($network_objects{"$schluessel.$local_schluessel"})>0) { - if ($network_objects{"$schluessel.$local_schluessel"} ne '') { - # print_cell_no_delimiter($fh, $network_objects{"$schluessel.$local_schluessel"}."/32"); - print_cell_no_delimiter($fh, $network_objects{"$schluessel.$local_schluessel"}); - } - } - } else { - if ($network_objects{"$schluessel.$local_schluessel"} ne '') { - print_cell_no_delimiter($fh, $network_objects{"$schluessel.$local_schluessel"}); - } - } - } - } - # default handling - else { - print_cell_no_delimiter($fh, $network_objects{"$schluessel.$local_schluessel"}); - } - } - } - # Datensatztrennzeichen ausgeben - print $fh "\n"; - } - } - } - $fh->close; # Schliessen der Ausgabedatei fuer NW-Objekte - } else { - die "NETOBJ: $out_file konnte nicht geoeffnet werden.\n"; - } - - # Oeffnen der Ausgabedatei fuer Services - #---------------------------------------- - $out_file = "$out_dir/${mgm_name}_services.csv"; - $fh = new FileHandle; - if ($fh->open("> $out_file")) { - # Ausgabe der Datensaetze - foreach $schluessel (sort (@services)) { - print_cell_no_delimiter ($fh, "$import_id"); - foreach (@srv_outlist) { - $local_schluessel = $_; - print_cell_delimiter($fh); - $local_schluessel = $_; - # Ist der Wert definiert? > dann ausgeben - if (defined ( $services{"$schluessel.$local_schluessel"} )) { - # Serviceport fuer rpc umsetzen ? - if (defined ($services{"$schluessel.typ"})) { - unless (($local_schluessel eq 'port') && ($services{"$schluessel.typ"} eq 'rpc')) { - print_cell_no_delimiter($fh, $services{"$schluessel.$local_schluessel"}); - } - } else { - print_cell_no_delimiter($fh, $services{"$schluessel.$local_schluessel"}); - } - } elsif ($local_schluessel eq 'rpc_port') { - # Serviceport fuer rpc umsetzten ? - if (defined ($services{"$schluessel.typ"})) { - if ($services{"$schluessel.typ"} eq 'rpc') { - print_cell_no_delimiter($fh, $services{"$schluessel.port"}); - } - } - } - } - # Datensatztrennzeichen ausgeben - print $fh "\n"; - } - $fh->close; # Schliessen der Ausgabedatei fuer Services - } else { - die "SVC_OUT: $out_file konnte nicht geoeffnet werden.\n"; - } -} - -#**************************** -# print_results_files_rules Output in Dateien -# return keiner -# gibt die gefundenen Parserergebnisse in Dateien aus -#**************************** -sub print_results_files_rules { - my $out_dir = shift; - my $mgm_name = shift; - my $import_id = shift; - my $is_first_in_loop; - my $out_file; - my $header_text = ""; - my ($count,$local_schluessel,$schluessel,$flat_file); - - foreach $schluessel (sort (@rulebases)) { - # Oeffnen der Ausgabedatei fuer Rulebases - #---------------------------------------- - # Regeln definiert? > Datei Oeffnen und schreiben - if ( !defined($rulebases{"$schluessel.rulecount"}) ) { - print ("\nwarning in import.pm: empty ruleset rulebases($schluessel.rulecount) not defined"); - } elsif ( $rulebases{"$schluessel.rulecount"} > 0 ) { - if (defined($rulebases{"$schluessel.ruleorder"})) { - @ruleorder = split (/,/, $rulebases{"$schluessel.ruleorder"}); - } else { # ruleorder ist aufsteigend von 0-n - @ruleorder = (); - for (my $i=0; $i<$rulebases{"$schluessel.rulecount"}; ++$i) { - push @ruleorder, ($i); - } - } - - # Dateinamen festlegen - if (!defined($out_dir)) { $out_dir = "."; } - $flat_file = $schluessel; $flat_file =~ s/\//\_/g; - $out_file = "$out_dir/${flat_file}_rulebase.csv"; - my $fh = new FileHandle; - if ($fh->open("> $out_file")) { - # Ausgabe der Datensaetze - for ($count = 0; $count < $rulebases{"$schluessel.rulecount"}; $count++) { - # Regelnummer ausgeben - print_cell($fh, $import_id); # import_id - print_cell ($fh, $count); # regel_nummer - print_cell_no_delimiter ($fh, $schluessel); # rulebase_name - foreach (@rule_outlist) { - $local_schluessel = $_; - print_cell_delimiter($fh); - # Ist der Wert definiert? > dann ausgeben - if ( defined ($rulebases{"$schluessel.$ruleorder[$count].$local_schluessel"})) { - print_cell_no_delimiter($fh, $rulebases{"$schluessel.$ruleorder[$count].$local_schluessel"}); - } else { - if ($local_schluessel eq 'track') { - print_cell_no_delimiter($fh, 'none'); - } - } - } - print $fh "\n"; # Datensatztrennzeichen ausgeben - } - $fh->close; # Schliessen der Ausgabedatei fuer Rules - } else { - die "RULE_OUT: $out_file konnte nicht geoeffnet werden.\n"; - } - print_verbose ("Output Datei: $out_file wurde geschlossen.\n\n"); - # keine Regeln, keine Regeldatei! - } else { - print_verbose ("$schluessel hat keine Regeln.\n"); - print_verbose ("Datei $out_file wurde nicht ausgegeben.\n\n"); - } - } -} - -#**************************** -# print_results_files_zones Output in Dateien -# return keiner -# gibt die gefundenen Parserergebnisse in Dateien aus -#**************************** -sub print_results_files_zones { - my $out_dir = shift; - my $mgm_name = shift; - my $import_id = shift; - my ($out_file,$schluessel); - - if (!defined($out_dir)) { $out_dir = "."; } - $out_file = "$out_dir/${mgm_name}_zones.csv"; - my $fh = new FileHandle; - if ($fh->open("> $out_file")) { - print_verbose ("Output Datei: $out_file wurde geoeffnet.\n"); - foreach $schluessel (sort (@zones)) { - print_cell_no_delimiter($fh, $import_id); # import id - print_cell_delimiter($fh); - print_cell_no_delimiter($fh, $schluessel); # zone name - print $fh "\n"; - } - $fh->close; # Schliessen der Ausgabedatei fuer Zonen - } else { - die "ZONE-OUT: $out_file konnte nicht geoeffnet werden.\n"; - } -} - -#**************************** -# print_results_files_audit_log Output in Dateien -# return keiner -# gibt die gefundenen Parserergebnisse in Dateien aus -#**************************** -sub print_results_files_audit_log { - my $out_dir = shift; - my $mgm_name = shift; - my $import_id = shift; - my ($out_file,$schluessel); - - if (!defined($out_dir)) { $out_dir = "."; } - $out_file = "$out_dir/${mgm_name}_auditlog.csv"; - my $fh = new FileHandle; - if ($fh->open("> $out_file")) { - for (my $idx = 0; $idx<$audit_log_count; $idx ++) { - print_cell ($fh, $import_id); - print_cell_no_delimiter ($fh, $idx); - foreach my $schluessel (@auditlog_outlist) { - print_cell_delimiter($fh); - if ( defined ($auditlog{"$idx.$schluessel"})) { # Ist der Wert definiert? > dann ausgeben - print_cell_no_delimiter($fh, $auditlog{"$idx.$schluessel"}); - } - } - print $fh "\n"; # EOL - $fh->close; # Schliessen der Ausgabedatei fuer Auditlog - } - } else { - die "AUDITLOG-OUT: $out_file konnte nicht geoeffnet werden.\n"; - } -} -#**************************** -# print_results_files_users Output in Dateien -# return keiner -# gibt die gefundenen Parserergebnisse in Dateien aus -#**************************** -sub print_results_files_users { - my $out_dir = shift; - my $mgm_name = shift; - my $import_id = shift; - my $s = ''; - my $is_first_in_loop; - my $schluessel; - my $out_file; - - if (!defined($out_dir)) { $out_dir = "."; } - $out_file = "$out_dir/${mgm_name}_users.csv"; - my $fh = new FileHandle; - if ($fh->open("> $out_file")) { - foreach my $name (sort @user_ar) { - print_cell ($fh, $import_id); - print_cell_no_delimiter($fh, $name); # user name - foreach my $schluessel (@user_outlist) { - print_cell_delimiter($fh); - if ( defined ($user{"$name.$schluessel"})) { # Ist der Wert definiert? > dann ausgeben - print_cell_no_delimiter($fh, $user{"$name.$schluessel"}); - } - } - print $fh "\n"; # EOL - } - } else { - die "USER_OUT: $out_file konnte nicht geoeffnet werden.\n"; - } -} - -#**************************** -# print_results_monitor Testoutput auf den Monitor -# return keiner -# druckt die gefundenen Parserergebnisse ohne weitere Aufbereitung oder Filterung der Informationen -#**************************** -sub print_results_monitor { - my $mode = $_[0]; - my ($schluessel, $local_schluessel, $count); - - # if steuert, ob jeweiliges printmodul aktiv => 0 unterdruecken - # => 1 ausgeben - SWITCH_parsemode: { - # nur im Modus "Objekte" - if ($mode eq 'objects') { - if ( 1 ) { - print "\n\nnetwork_objects:\n"; - foreach $schluessel (sort (keys( %network_objects))) { - if (!defined($network_objects{$schluessel})) { - print ("\nerror print_results_monitor nwobj $schluessel not defined"); - } else { - print "$schluessel\t\t\t $network_objects{$schluessel} \n"; - } - } - - } - if ( 1 ) { - print "\n\nservices:\n"; - foreach $schluessel (sort (keys( %services ))) { - print "$schluessel\t\t\t $services{$schluessel} \n"; - } - } - if ( 0 ) { - print "\n\nnetwork_objects:\n"; - foreach $schluessel (sort (@network_objects)) { - print "\t$schluessel\n"; - foreach $local_schluessel ( @obj_outlist ) { - print "\t\t$local_schluessel\t"; - if (defined ( $network_objects{"$schluessel.$local_schluessel"} )) { - print $network_objects{"$schluessel.$local_schluessel"}."\n"; - } else { - print "\n"; - } - } - } - } - if ( 0 ) { - print "\n\nservices:\n"; - foreach $schluessel (sort (@services)) { - print "\t$schluessel\n"; - foreach $local_schluessel ( @srv_outlist ) { - print "\t\t$local_schluessel\t"; - if (defined ( $services{"$schluessel.$local_schluessel"} )) { - print $services{"$schluessel.$local_schluessel"}."\n"; - } else { - print "\n"; - } - } - } - } - last SWITCH_parsemode; - } - #nur im Modus "Regeln" - - if ($mode eq 'rules') { - if ( 1 ) { - my $rule_no; - print "\n\nrulebases:\n"; - foreach $schluessel (sort (@rulebases)) { - if (defined($rulebases{"$schluessel.rulecount"} )) { - $rule_no = $rulebases{"$schluessel.rulecount"}; - } else { - $rule_no = 0; - } - print "\t(#regeln: " . $rule_no . ")\t$schluessel\n"; - } - } - if ( 0 ) { - foreach $schluessel (sort (@rulebases)) { - print "\n\nruleset:\t$schluessel\n"; - foreach $local_schluessel (sort (keys(%rulebases))) { - print $local_schluessel."\t".$rulebases{"$local_schluessel"}."\n"; - } - } - } - if ( 1 ) { - print "\n\nrules:\n"; - foreach $schluessel (sort (@rulebases)) { - print "Regeln des Regelwerks $schluessel:\n"; - if (defined($rulebases{"$schluessel.rulecount"})) { - @ruleorder = split (/,/, $rulebases{"$schluessel.ruleorder"}); - for ($count = 0; $count < $rulebases{"$schluessel.rulecount"}; $count++) { - foreach $local_schluessel ( @rule_outlist ) { - print "$schluessel\t$count\t$local_schluessel\t"; - if (defined ($rulebases{"$schluessel.$ruleorder[$count].$local_schluessel"})){ - print $rulebases{"$schluessel.$ruleorder[$count].$local_schluessel"}; - } - print "\n"; - } - } - print ("rulecount: " . $rulebases{"$schluessel.rulecount"} . "\n"); - if (defined($rulebases{"$schluessel.ruleorder"})) { - print ("ruleorder: " . $rulebases{"$schluessel.ruleorder"} . "\n"); - } - } - print "\n"; - } - } - last SWITCH_parsemode; - } - } -} - -############################################################ -# fill_import_tables_from_csv ($sqldatafile, $fehler_count, $dev_typ_id, -# $csv_obj_file, $csv_svc_file, $csv_usr_file, $csv_rule_file) -# fuellt die import_tabellen -############################################################ -sub fill_import_tables_from_csv { - my $fehler_count = 0; - my $dev_typ_id = shift; - my $csv_zone_file = shift; - my $csv_obj_file = shift; - my $csv_svc_file = shift; - my $csv_usr_file = shift; - my $rulebases = shift; # ref to hash of rulebase-infos - my $fworch_workdir = shift; - my $csv_audit_log_file = shift; - my ($csv_rule_file,$fehler, $fields, $sqlcode, $psql_cmd, $start_time); - - $start_time = time(); - if (file_exists($csv_zone_file)) { # optional (netscreen, fortigate) - $fields = "(" . join(',',@zone_import_fields) . ")"; - $sqlcode = "COPY import_zone $fields FROM STDIN DELIMITER '$CACTUS::FWORCH::csv_delimiter' CSV"; - $fehler = CACTUS::FWORCH::copy_file_to_db($sqlcode,$csv_zone_file); - } - if (defined($csv_audit_log_file) && file_exists($csv_audit_log_file)) { # optional if audit log exists - $fields = "(" . join(',',@auditlog_import_fields) . ")"; - $sqlcode = "COPY import_changelog $fields FROM STDIN DELIMITER '$CACTUS::FWORCH::csv_delimiter' CSV"; - $fehler = CACTUS::FWORCH::copy_file_to_db($sqlcode,$csv_audit_log_file); - } - $fields = "(" . join(',',@obj_import_fields) . ")"; - $sqlcode = "COPY import_object $fields FROM STDIN DELIMITER '$CACTUS::FWORCH::csv_delimiter' CSV"; - if ($fehler = CACTUS::FWORCH::copy_file_to_db($sqlcode,$csv_obj_file)) { - print_error("dbimport: $fehler"); print_linebreak(); $fehler_count += 1; - } - $fields = "(" . join(',',@svc_import_fields) . ")"; - $sqlcode = "copy import_service $fields FROM STDIN DELIMITER '$CACTUS::FWORCH::csv_delimiter' CSV"; - if ($fehler = CACTUS::FWORCH::copy_file_to_db($sqlcode,$csv_svc_file)) { - print_error("dbimport: $fehler"); print_linebreak(); $fehler_count += 1; - } - if (file_exists($csv_usr_file)) { - $fields = "(" . join(',',@user_import_fields) . ")"; - $sqlcode = "COPY import_user $fields FROM STDIN DELIMITER '$CACTUS::FWORCH::csv_delimiter' CSV"; - if ($fehler = CACTUS::FWORCH::copy_file_to_db($sqlcode,$csv_usr_file)) { } - } - $fields = "(" . join(',',@rule_import_fields) . ")"; - my @rulebase_ar = (); - foreach my $d (keys %{$rulebases}) { - my $rb = $rulebases->{$d}->{'local_rulebase_name'}; - my $rulebase_name_sanitized = join('__', split /\//, $rb); - if ( !grep( /^$rulebase_name_sanitized$/, @rulebase_ar ) ) { - @rulebase_ar = (@rulebase_ar, $rulebase_name_sanitized); - # print ("rulebase_name_sanitized: $rulebase_name_sanitized\n"); - $csv_rule_file = $fworch_workdir . '/' . $rulebase_name_sanitized . '_rulebase.csv'; - print ("rulebase found: $rulebase_name_sanitized, rule_file: $csv_rule_file, device: $d\n"); - $sqlcode = "COPY import_rule $fields FROM STDIN DELIMITER '$CACTUS::FWORCH::csv_delimiter' CSV"; - if ($fehler = CACTUS::FWORCH::copy_file_to_db($sqlcode,$csv_rule_file)) { - print_error("dbimport: $fehler"); print_linebreak(); $fehler_count += 1; - } - } else { - print ("ignoring another device ($d) with rulebase $rb\n"); - } - } print_bold("Database Import ... done in " . sprintf("%.2f",(time() - $start_time)) . " seconds"); print_linebreak(); - return $fehler_count; -} - -############################################################ -# fill_import_tables_from_csv_with_sql ($dev_typ_id, -# $sql_obj_file, $sql_svc_file, $sql_usr_file, $sql_rule_file) -# fuellt die import_tabellen mit einzelen sql-befehlen -# nur zum Debuggen verwendet, wenn der CSV-Import schiefgeht -############################################################ -sub fill_import_tables_from_csv_with_sql { - my $fehler_count = 0; - my $dev_typ_id = shift; - my $csv_zone_file = shift; - my $csv_obj_file = shift; - my $csv_svc_file = shift; - my $csv_usr_file = shift; - my $rulebases = shift; # ref to hash of rulebase-infos - my $fworch_workdir = shift; - my $csv_audit_log_file = shift; - my ($csv_rule_file,$fehler, $fields, $sqlcode, $psql_cmd, $start_time); - - sub build_and_exec_sql_statements { # baut aus csv-Files sql statements und fuehrt diese einzeln aus - my $target_table = shift; - my $str_of_fields = shift; - my $csv_file = shift; - my $input_line; - my $sqlcode; - my @values = (); - my $fehler; - my $fehler_count=0; - my $delimiter; - - sub str_to_sql_value { - my $input_str = remove_quotes(shift); - - if ($input_str eq '') { - return 'NULL'; - } else { - $input_str =~ s/\'/\\\'/g; - $input_str =~ s/^"//; - $input_str =~ s/"$//; - return "'$input_str'"; - } - } - - my $CSVhdl = new IO::File ("< $csv_file") or $fehler = "Cannot open file $csv_file for reading: $!"; - if ($fehler) { - print_error("FEHLER: $fehler"); - print_linebreak(); - $fehler_count += 1; - return $fehler_count; - } - $delimiter = qr/$CACTUS::FWORCH::csv_delimiter/; - - while ($input_line = <$CSVhdl>) { - $sqlcode = "INSERT INTO $target_table ($str_of_fields) VALUES ("; - $input_line =~ s/\n$//; - - $input_line =~ s/\\$delimiter/AbDdia679roe4711/g; - @values = split (/$delimiter/, $input_line); - my @values2 = @values; - @values = (); - foreach my $val (@values2) { - $val =~ s/AbDdia679roe4711/$delimiter/g; - @values = (@values, $val); - } - while ($input_line =~ /$delimiter$/) { # line ends with ; --> add NULL-value for last column - push @values, ""; - $input_line =~ s/$delimiter$//; - } - $sqlcode .= str_to_sql_value($values[0]); - my $i = 1; - while ($i<=$#values) { - $sqlcode .= "," . str_to_sql_value($values[$i++]); - } - $sqlcode .= ");"; - # print ("sql_code: $sqlcode\n"); - if ($fehler = CACTUS::FWORCH::exec_pgsql_cmd_no_result($sqlcode)) { - output_txt($fehler . "; $csv_file",3); - $fehler_count += 1; - } - } - $CSVhdl->close; - return $fehler_count; - } - - print_bold(" - Database Import (non-bulk)"); - print_linebreak(); print_txt("- writing data into import tables ... "); - $start_time = time(); - - if (file_exists($csv_zone_file)) { # optional nur fuer Netscreen - $fehler = build_and_exec_sql_statements('import_zone', join(',',@zone_import_fields), $csv_zone_file); - if ($fehler) { $fehler_count ++; } - } - if (defined($csv_audit_log_file) && file_exists($csv_audit_log_file)) { # optional nur wenn auditlog existiert - $fehler = build_and_exec_sql_statements('import_changelog', join(',',@auditlog_import_fields), $csv_audit_log_file); - if ($fehler) { $fehler_count ++; } - } - $fields = join(',', @obj_import_fields); - $fehler = build_and_exec_sql_statements('import_object',$fields, $csv_obj_file); - if ($fehler) { $fehler_count ++; } - - $fields = join(',',@svc_import_fields); - $fehler = build_and_exec_sql_statements('import_service',$fields, $csv_svc_file); - if ($fehler) { $fehler_count ++; } - - if (file_exists($csv_usr_file)) { - $fields = join(',',@user_import_fields); - $fehler = build_and_exec_sql_statements('import_user',$fields, $csv_usr_file); - } - $fields = join(',',@rule_import_fields); - foreach my $d (keys %{$rulebases}) { - my $rb = $rulebases->{$d}->{'local_rulebase_name'}; - $csv_rule_file = $fworch_workdir . '/' . $rb . '_rulebase.csv'; - $fehler = build_and_exec_sql_statements('import_rule',$fields, $csv_rule_file); - if ($fehler) { $fehler_count ++; } - } - print_bold ("done in " . sprintf("%.2f",(time() - $start_time)) . " seconds"); print_linebreak(); - return $fehler_count; -} - -##################################################################################### - -1; -__END__ - -=head1 NAME - -FWORCH::import - Perl extension for fworch Import - -=head1 SYNOPSIS - - use CACTUS::FWORCH::import; - -=head1 DESCRIPTION - -fworch Perl Module support for importing configs into fworch Database - -=head2 EXPORT - - global variables - - DB functions - -=head1 SEE ALSO - - behind the door - - -=head1 AUTHOR - - Cactus eSecurity, tmp@cactus.de - -=cut diff --git a/roles/importer/files/importer/CACTUS/FWORCH/import/checkpoint.pm b/roles/importer/files/importer/CACTUS/FWORCH/import/checkpoint.pm deleted file mode 100644 index a3ff30d049..0000000000 --- a/roles/importer/files/importer/CACTUS/FWORCH/import/checkpoint.pm +++ /dev/null @@ -1,2438 +0,0 @@ -package CACTUS::FWORCH::import::parser; - -use strict; -use warnings; -use IO::File; -use Getopt::Long; -use File::Basename; -use Time::HiRes qw(time); # fuer hundertstelsekundengenaue Messung der Ausfuehrdauer -use Net::CIDR; -use CACTUS::FWORCH; -use CACTUS::FWORCH::import; -use Date::Calc qw(Add_Delta_DHMS); - -require Exporter; -our @ISA = qw(Exporter); - -our %EXPORT_TAGS = ( 'basic' => [ qw( ©_config_from_mgm_to_iso &parse_config ) ] ); - -our @EXPORT = ( @{ $EXPORT_TAGS{'basic'} } ); -our $VERSION = '0.3'; - -# variblendefinition check point parser - global -# ------------------------------------------------------------------------------------------- -my $GROUPSEP = $CACTUS::FWORCH::group_delimiter; - -my $UID = "UID"; # globale konstante UID - -# Stati und anderes des Objektparsers -my $ln = 0; -my $line = ''; -our $parse_obj_state = 0; # moegliche Werte 0 kein status - # 1 objectclass gestartet - # 2 object gestartet - # 3...7 diverse attribute & werte (kontextsensitiv) - # >10 innerhalb einer Gruppe -our $parse_obj_type; # State 1 - aktuelle Objektklasse -our $parse_obj_name; # State 2 - name des aktuellen objektes -our $old_parse_obj_name; # State 2 - name des letzten objektes -our $parse_obj_attr; # State 3 - Attribut -our $parse_obj_attr_value; # State 3 - Wert des Attributes -our $parse_obj_attr_ext; # State 4 - Attributerweiterung (kontextsensitiv) -our $parse_obj_attr_ext_value - ; # State 4 - Wert des erweiterten Attributes (kontextsensitiv) -our $parse_obj_attr_ext2; # State 5 - Attributerweiterung (kontextsensitiv) -our $parse_obj_attr_ext2_value - ; # State 5 - Wert des erweiterten Attributes (kontextsensitiv) -our $parse_obj_attr_ext3; # State 6 - Attributerweiterung (kontextsensitiv) -our $parse_obj_attr_ext3_value - ; # State 6 - Wert des erweiterten Attributes (kontextsensitiv) -our $parse_obj_attr_ext4; # State 7 - Attributerweiterung (kontextsensitiv) -our $parse_obj_attr_ext4_value - ; # State 7 - Wert des erweiterten Attributes (kontextsensitiv) -our $parse_obj_groupmember; # string-array fuer gruppenmitglieder -our $parse_obj_groupmember_refs; # string-array fuer gruppenmitglieder -our $group_with_exclusion_marker; # gibt an, ob die aktuelle gruppe eine normale (undefined), - # positiv- (base), oder negativ-gruppe (exclusion) ist - -# Stati und anderes des Rulesparser -our $parserule_state = 0; # status des Regelparsers - # 0 kein Regelwerk - # 1 Regelwerk - # 2 Regel - # 14 Gruppe - # 15 Mitgliederliste der Gruppe - # 16 Mitglied einer Compound Gruppe -our $parserule_in_rule_base = 0; # wenn innerhalb eines Regelwerkes -our $parserule_in_rule = 0; # wenn innerhalb einer Regeldefinition -our $parserule_rulenum = -1; # aktuelle Regelnummer -our $parserule_rulebasename; # aktuellen Regelwerkes -our $parserule_ruleparameter; # Bezeichnung des aktuellen Parameter -our $parserule_groupmember; # Regelgruppenmitglieder -our $parserule_groupmember_refs; # String mit Uids -our $parserule_ruleparameter_ext; # Attributerweiterung (kontextsensitiv) -our $parserule_ruleparameter_ext_value - ; # Wert des erweiterten Attributes (kontextsensitiv) -our $parserule_ruleuser - ; # user, fuer die die Regel gilt (alle user aus der Quellspalte) -our %usergroup; - -##################################################################################### -# Start Check Point Parser -##################################################################################### - -sub parse_config { - my $object_file = shift; - my $rulebase_file = shift; - my $user_db_file = shift; - my $rulebase_name = shift; - my $output_dir = shift; - my $verbose = shift; - my $mgm_name = shift; - my $config_dir = shift; - my $import_id = shift; - my $audit_log_file= shift; - my $prev_import_time= shift; - my $parse_full_audit_log = shift; - my $debug_level = shift; - my $result; - - if ($result = cp_parse_main( $object_file, $output_dir, '', $verbose )) { return $result; } - - undef($parse_obj_state); - undef($parse_obj_type); - undef($old_parse_obj_name); - undef($parse_obj_attr); - undef($parse_obj_attr_value); - undef($parse_obj_attr_ext); - undef($parse_obj_attr_ext_value); - undef($parse_obj_attr_ext2); - undef($parse_obj_attr_ext2_value); - undef($parse_obj_groupmember); - undef($parse_obj_groupmember_refs); - - if ($result = cp_parse_main( $rulebase_file, $output_dir, $rulebase_name, $verbose )) { return $result; } - - if ($result = &cp_parse_users_main($user_db_file, $output_dir, $verbose)) { return $result; } - if ($result = &cp_parse_users_from_rulebase($rulebase_file)) { return $result; } - - if ( -e $audit_log_file ) { # if audit.log exists, process it - &parse_audit_log($audit_log_file, $prev_import_time, $parse_full_audit_log); - } - - &print_results_files_objects ( $output_dir, $mgm_name, $import_id ); - &print_results_files_rules ( $output_dir, $mgm_name, $import_id ); - &print_results_files_users ( $output_dir, $mgm_name, $import_id ); - &print_results_files_audit_log ( $output_dir, $mgm_name, $import_id ); - return 0; # done without errors -} - -############################################################ -# gen_uid (geparste uid) -# wandelt geparste uid in fworch-kompatible UID um -# derzeit ist lediglich ein upercase notwendig -############################################################ -sub gen_uid { - return ( uc(shift) ); -} - -sub add_delta_db_time { - my $db_time = shift; - my $diff_in_seconds = shift; - - my ($year, $month, $day, $hour, $min, $sec) = $db_time =~ m/(\d+)\-(\d+)\-(\d+)\s+(\d+)\:(\d+)\:(\d+)/; - ($year, $month, $day, $hour, $min, $sec) = Add_Delta_DHMS( $year, $month, $day, $hour, $min, $sec, 0, 0, 0, $diff_in_seconds ); - return sprintf("%04d-%02d-%02d %02d:%02d:%02d", $year, $month, $day, $hour, $min, $sec); -} - -############################################################ -# convert_checkpoint_to_db_date (string) -# konvertiert von Format 'Sun Jul 21 12:24:13 2002' -# oder '21Jul2007 12:24:13' -# oder '21-jul-2007' -# zu Format '2002-07-21 12:24:13' -############################################################ -sub convert_checkpoint_to_db_date { - my $month = 0; - my $sec = 0; - my ($result, $day, $year, $hour, $min); - -# '[Sun ]Jul 21 12:24:13 2007' - if ( $_[0] =~ /^\w+\s+(\w+)\s+(\d+)\s+(\d+)\:(\d+)\:?(\d+)?\s+(\d+)$/ ) { - $month = $1; - $day = $2; - $hour = $3; - $min = $4; - if (defined($5)) { $sec = $5; } - $year = $6; - } -# '21Jul2007 12:24:13' - if ( $_[0] =~ /^(\d+)\s?([a-zA-Z]{3})(\d{4})\s+(\d+)\:(\d+)\:?(\d+)?$/ ) { - $month = $2; - $day = $1; - $hour = $4; - $min = $5; - if (defined($6)) { $sec = $6; } - $year = $3; - } - -# '21-jul-2007' - if ( $_[0] =~ /^(\d+)\-([a-zA-Z]{3})\-(\d{4})$/ ) { - $month = $2; - $day = $1; - $year = $3; - } - SWITCH: { - if ($month =~ /jan/i) { $month = "01"; last SWITCH; } - if ($month =~ /feb/i) { $month = "02"; last SWITCH; } - if ($month =~ /mar/i) { $month = "03"; last SWITCH; } - if ($month =~ /apr/i) { $month = "04"; last SWITCH; } - if ($month =~ /may/i) { $month = "05"; last SWITCH; } - if ($month =~ /jun/i) { $month = "06"; last SWITCH; } - if ($month =~ /jul/i) { $month = "07"; last SWITCH; } - if ($month =~ /aug/i) { $month = "08"; last SWITCH; } - if ($month =~ /sep/i) { $month = "09"; last SWITCH; } - if ($month =~ /oct/i) { $month = "10"; last SWITCH; } - if ($month =~ /nov/i) { $month = "11"; last SWITCH; } - if ($month =~ /dec/i) { $month = "12"; last SWITCH; } - $month = 0; - } - if ( $month ne 0 ) { - if (defined ($year) && defined($month) && defined($day) && defined($hour) && defined($min) ) { - $result = sprintf("%04d-%02d-%02d %02d:%02d:%02d", $year, $month, $day, $hour, $min, $sec); - } elsif (defined ($year) && defined($month) && defined($day) ) { - $result = sprintf("%04d-%02d-%02d", $year, $month, $day); - } else { - print ("WARNING: convert_cp_to_db_date: " . $_[0] . " undefined value: $year-$month-$day $hour:$min:$sec\n"); - } - } - return $result; -} - -############################################################ -# convert_db_to_checkpoint_date (string) -# konvertiert von Format '2002-07-21 12:24:13' -# zu Format 'Jul 21 12:24:13 2002' -############################################################ -sub convert_db_to_checkpoint_date { - my $result; - my $month; - my $day; - my $year; - my $rest; - my $time = ' '; - - if ( $_[0] =~ /^(\d+)\-(\d+)\-(\d+)(.*)$/ ) { - $month = $2; - $day = $3; - $year = $1; - $rest = $4; - } else { - return ''; - } - my @months = qw(Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec); - $month = $months[$month-1]; - - if ( $rest =~ /(\d+)\:(\d+)\:?(\d+)?/ ) { - $time = " $1:$2"; - if (defined($3)) { - $time .= ":$3"; - } - $time .= ' '; - } - return "$month $day$time$year"; -} - -############################################################ -# copy_config_from_mgm_to_iso($ssh_private_key, $ssh_user, $ssh_hostname, $management_name, $obj_file_base, $cfg_dir, $rule_file_base) -# Kopieren der Config-Daten vom Management-System zum ITSecorg-Server -############################################################ -sub copy_config_from_mgm_to_iso { - my $ssh_user = shift; - my $ssh_hostname = shift; - my $management_name = shift; # not used - my $obj_file_base = shift; - my $cfg_dir = shift; - my $rule_file_base = shift; - my $workdir = shift; - my $auditlog = shift; - my $prev_import_time= shift; - my $ssh_port = shift; - my $config_path_on_mgmt = shift; - my $debug_level = shift; - my $user_db_file = 'fwauth.NDB'; - my $cmd; - my $return_code; - my $fehler_count = 0; - - if (!defined($config_path_on_mgmt) || $config_path_on_mgmt eq '') { - $config_path_on_mgmt = ""; - } - if (!defined($ssh_port) || $ssh_port eq '') { - $ssh_port = "22"; - } - my $tar_archive = 'cp_config.tar.gz'; # compress files for bandwidth optimization - my $tar_cmd = "cd $config_path_on_mgmt; tar chf $tar_archive $obj_file_base $rule_file_base $user_db_file"; - $cmd = "$ssh_bin -i $workdir/$CACTUS::FWORCH::ssh_id_basename $ssh_user\@$ssh_hostname \"$tar_cmd\""; -# print("DEBUG - tar_cmd = $cmd\n"); - $return_code = system($cmd); if ( $return_code != 0 ) { $fehler_count++; } - - $cmd = "$scp_bin $scp_batch_mode_switch -P $ssh_port -i $workdir/$CACTUS::FWORCH::ssh_id_basename $ssh_user\@$ssh_hostname:$config_path_on_mgmt$tar_archive $cfg_dir"; -# print("DEBUG - copy_cmd = $cmd\n"); - $return_code = system($cmd); if ( $return_code != 0 ) { $fehler_count++; } - - $cmd = "$ssh_bin -i $workdir/$CACTUS::FWORCH::ssh_id_basename $ssh_user\@$ssh_hostname \"rm $tar_archive\""; # cleanup -# print("DEBUG - tar_cmd = $cmd\n"); - - # gunzip -c xx.tar.gz | tar tvf - -# $tar_cmd = "cd $cfg_dir; gunzip -c $tar_archive | tar xf -"; - $tar_cmd = "cd $cfg_dir; tar xf $tar_archive"; - $return_code = system($tar_cmd); if ( $return_code != 0 ) { $fehler_count++; } - - if ( ! $fehler_count ) { - &remove_literal_carriage_return("$cfg_dir/$obj_file_base"); - &remove_literal_carriage_return("$cfg_dir/$rule_file_base"); - } - # do not return name of auditlog file to avoid testing for md5sum - return ( $fehler_count, "$cfg_dir/$obj_file_base,$cfg_dir/fwauth.NDB,$cfg_dir/$rule_file_base" ); -} - -#**************************** -# parser fuer audit log von check point -# insbesondere fuer die Erkennung von deletes (user et al.) zu verwenden -#**************************** -# syntaxbeispiele auditlog: -# 1Oct2007 12:18:22 accept sting < ObjectName: iso-test-user-1; ObjectType: user; ObjectTable: users; Operation: Create Object; Uid: {69907560-5FF5-4120-A62D-D373654D2C15}; Administrator: tim; Machine: stingray; Subject: Object Manipulation; Operation Number: 0; product: SmartDashboard; -# 2Oct2007 9:52:55 accept sting < ObjectName: iso-test-user-1; ObjectType: user; ObjectTable: users; Operation: Delete Object; Uid: {69907560-5FF5-4120-A62D-D373654D2C15}; Administrator: tim; Machine: stingray; Subject: Object Manipulation; Operation Number: 3; product: SmartDashboard; -# 2Oct2007 11:07:26 accept sting < ObjectName: isotstusr2; ObjectType: user; ObjectTable: users; Operation: Create Object; Uid: {9ACAF401-9450-4B27-9B4C-D158FC7D2F10}; Administrator: tim; Machine: stingray; Subject: Object Manipulation; Operation Number: 0; product: SmartDashboard; -# 4Oct2007 10:47:44 accept sting < ObjectName: cactus; ObjectType: firewall_policy; ObjectTable: fw_policies; Operation: Modify Object; Uid: {4DFA246F-BCB1-4283-B3D6-685FBF8DB89B}; Administrator: tim; Machine: stingray; FieldsChanges: Rule 3 Service: removed 'a-250' ;; Subject: Object Manipulation; Operation Number: 1; product: SmartDashboard; -# 4Oct2007 15:35:07 accept fw1 < Operation: Log In; Administrator: tufin1; Machine: localhost.localdomain; Subject: Administrator Login; Additional Info: Authentication method: Certificate; Operation Number: 10; product: CPMI Client; -# 4Oct2007 15:35:35 accept fw1 < Operation: Log Out; Administrator: tufin1; Machine: localhost.localdomain; Subject: Administrator Login; Operation Number: 12; product: CPMI Client; -sub parse_audit_log { - my $in_file = shift; - my $prev_import_time = shift; - my $process_whole_auditlog = shift; - my $line; - my ($db_date, $found_line, $found_basic_line, $date, $time, $action, $admin, $management, $obj_name, $obj_type, $obj_table, $operation, $uid); - my $prev_import_date_minus_5_minutes = &add_delta_db_time($prev_import_time,-600); - - open( IN, $in_file ) || die "$in_file konnte nicht geoeffnet werden.\n"; - - while () { - $line = $_; # Zeileninhalt merken - $line =~ s/\x0D/\\r/g; # literal carriage return entfernen - $line =~ s/\r\n/\n/g; # handle cr,nl (d2u ohne Unterprogrammaufruf) - chomp($line); - undef $date; undef $time; undef $action; undef $admin, undef $management; - undef $obj_name; undef $obj_type; undef $obj_table; undef $operation; undef $uid; - $found_line = 0; - $found_basic_line = 0; - - # Basisdaten sammeln (Datum, Zeit, ...) - if ( $line =~ /\s*(\d+\w+\d+)\s+(\d+\:\d+\:\d+)\s+(\w+)\s+(.*?)\s+\<\s+/ ) { - $date = $1; $time = $2; $action = $3; $management = $4; $found_basic_line = 1; - $db_date = &convert_checkpoint_to_db_date("$date $time"); - print (" date from auditlog: $db_date; date from prev_import-5minues: $prev_import_date_minus_5_minutes"); - } - if ($found_basic_line && ((defined($process_whole_auditlog) && $process_whole_auditlog) || $db_date gt $prev_import_date_minus_5_minutes)) { - # changelog eintrag mit uid - print ("processing ...\n"); - if ( $found_basic_line && $line =~ - /\s+\<\s+ObjectName\:\s([\w\_\-\s]+)\;\s+ObjectType\:\s+([\w\_\-\s]+)\;\s+ObjectTable\:\s+([\w\_\-\s]+)\;\s+Operation\:\s+([\w\_\-\s]+)\;\s+Uid\:\s+\{([\w\_\-\s]+)\}\;\s+Administrator\:\s+([\w\_\-\s]+)\;/ ) { - $obj_name = $1; $obj_type = $2; $obj_table = $3; $operation = $4; $uid = $5; $admin = $6; $found_line = 1; - } - - # changelog eintrag ohne uid - if ( $found_basic_line && $line =~ - /\s+\<\s+ObjectName\:\s([\w\_\-\s]+)\;\s+ObjectType\:\s+([\w\_\-\s]+)\;\s+ObjectTable\:\s+([\w\_\-\s]+)\;\s+Operation\:\s+([\w\_\-\s]+)\;\s+Administrator\:\s+([\w\_\-\s]+)\;/ ) { - $obj_name = $1; $obj_type = $2; $obj_table = $3; $operation = $4; $admin = $5; $found_line = 1; - } - # user login/logout - if ( $found_basic_line && $line =~ /\s+\<\s+Operation\:\s+(Log\s(In|Out))\;\s+Administrator\:\s+(.*?)\;/ ) { - $operation = $1; $admin = $3; $found_line = 1; - } - if ($found_line) { - $auditlog{"$audit_log_count.change_time"} = $db_date; - - if (defined($operation)) { - if ( $operation =~ /Create Object/ ) { $operation = 'I'; } - if ( $operation =~ /Modify Object/ ) { $operation = 'C'; } - if ( $operation =~ /Delete Object/ ) { $operation = 'D'; } - $auditlog{"$audit_log_count.change_action"} = $operation; - } - $auditlog{"$audit_log_count.management_name"} = $management; - if (defined($admin)) { $auditlog{"$audit_log_count.change_admin"} = $admin; } - if (defined($uid)) { $auditlog{"$audit_log_count.changed_object_uid"} = $uid; } - if (defined($obj_name)) { $auditlog{"$audit_log_count.changed_object_name"} = $obj_name; } - if (defined($obj_type)) { - if ( $obj_type =~ /\_protocol/ || $obj_type =~ /\_service/ ) { - $obj_type = 'service'; - } - if ( $obj_type =~ /network/ || $obj_type =~ /host\_plain/ || $obj_type =~ /address\_range/ ) { - $obj_type = 'network_object'; - } - if ( $obj_type =~ /user/ ) { - $obj_type = 'user'; - } - if ( $obj_type =~ /policies\_collection/ || $obj_type =~ /firewall_policy/ ) { - $obj_type = 'rule'; - } - $auditlog{"$audit_log_count.changed_object_type"} = $obj_type; - } - $audit_log_count ++; - - # debugging: -# print ("parse_audit_log found \@ $date $time for management $management: operation=$operation, admin=$admin"); - if ($operation !~ /^Log/ ) { - print (", obj_type=$obj_type, obj_name=$obj_name"); - if (defined($uid)) { print (", uid=$uid"); } - } - print ("\n"); - } - } - } - close IN; -} - -#**************************** -# Verarbeitung / Aufbereitung der identifizierten Parameter und Values (kontextsesitiv) -#**************************** -# result_handler_obj -# obj_state_3 -sub result_handler_obj { - my $local_name; # Variable als Zwischenspeicher in lokalen Schleifen - my $found; # flag, true falls Eintrag bekannt - - if ( $parse_obj_state >= 3 ) { - - # die Attribute von Anfuehrungszeichen befreien - if ( defined($parse_obj_attr_value) ) { - - # Test auf Primary Management - if ( ( $parse_obj_attr eq "primary_management" ) - && ( $parse_obj_attr_value eq "true" ) ) - { - $mgm_name = $parse_obj_name; # setting mgm_name defined in CACTUS::FWORCH::import.pm - } - - # Attribute in lowercase wandeln - if ( $parse_obj_attr eq "type" ) { - $parse_obj_attr_value = lc($parse_obj_attr_value); - } - } - - # objekte nach typen sortiert in arrays sammeln - SWITCH_OBJ_TYPE: { - if (defined($parse_obj_name)) { - # globals any obj - if ( $parse_obj_type eq "globals" - && $parse_obj_name eq 'Any' - && $parse_obj_attr eq 'AdminInfo' ) - { - @network_objects = ( @network_objects, $parse_obj_name ); - $network_objects{"$parse_obj_name.name"} = $parse_obj_name; - $network_objects{"$parse_obj_name.UID"} = - &gen_uid($parse_obj_attr_ext_value); - $network_objects{"$parse_obj_name.ipaddr"} = '0.0.0.0'; - $network_objects{"$parse_obj_name.comments"} = - '"implied any network object from objects.C global section"'; - $network_objects{"$parse_obj_name.type"} = 'network'; - $network_objects{"$parse_obj_name.netmask"} = '0.0.0.0'; - $network_objects{"$parse_obj_name.location"} = 'internal'; - @services = ( @services, $parse_obj_name ); - $services{"$parse_obj_name.name"} = $parse_obj_name; - $services{"$parse_obj_name.UID"} = - &gen_uid($parse_obj_attr_ext_value); - $services{"$parse_obj_name.comments"} = - '"any service from objects.C global section"'; - $services{"$parse_obj_name.typ"} = 'simple'; - $services{"$parse_obj_name.type"} = 'simple'; - last SWITCH_OBJ_TYPE; - } - # dynamic zone objects - if ( $parse_obj_name eq 'Internet_Zone' || $parse_obj_name eq 'Trusted_Zone') - { - @network_objects = ( @network_objects, $parse_obj_name ); - $network_objects{"$parse_obj_name.name"} = $parse_obj_name; - $network_objects{"$parse_obj_name.UID"} = - &gen_uid($parse_obj_attr_ext_value); - $network_objects{"$parse_obj_name.ipaddr"} = '0.0.0.0'; - $network_objects{"$parse_obj_name.comments"} = - '"checkpoint implied zone object, filled dynamically"'; - $network_objects{"$parse_obj_name.type"} = 'network'; - $network_objects{"$parse_obj_name.netmask"} = '0.0.0.0'; - $network_objects{"$parse_obj_name.location"} = 'internal'; - last SWITCH_OBJ_TYPE; - } - } - - # netzobjekte - if ( $parse_obj_type eq "network_objects" ) { - - # schon ein bekanntes network_object? - if ( !defined( $network_objects{"$parse_obj_name.name"} ) ) { - @network_objects = ( @network_objects, $parse_obj_name ); - $network_objects{"$parse_obj_name.name"} = $parse_obj_name; - } - - # Daten im Hash ergaenzen - if ( $parse_obj_state > 10 ) - { # group member alle eingesammelt, abspeichern und zurueck - if ( defined($parse_obj_groupmember) - && defined($parse_obj_groupmember_refs) ) - { - - # group member alle eingesammelt, abspeichern und zurueck - $network_objects{"$parse_obj_name.members"} = - $parse_obj_groupmember; - $network_objects{"$parse_obj_name.member_refs"} = - $parse_obj_groupmember_refs; - $network_objects{"$parse_obj_name.typ"} = 'group'; - } - $parse_obj_state -= 10; - } - if ( defined($parse_obj_attr_value) ) { - - # Attribute aufarbeiten - SWITCH_OBJ_ATTR: { - # start ipv6 - if ( $parse_obj_attr eq 'ipv6_prefix') { # IPV6 netmask - $parse_obj_attr_value = CACTUS::FWORCH::remove_space_at_end($parse_obj_attr_value); - $network_objects{"$parse_obj_name.netmask"} = $parse_obj_attr_value; - last SWITCH_OBJ_ATTR; - } - if ( $parse_obj_attr eq 'ipv6_address') { # IPV6 ip addr - $parse_obj_attr_value = CACTUS::FWORCH::remove_space_at_end($parse_obj_attr_value); - $network_objects{"$parse_obj_name.ipaddr"} = $parse_obj_attr_value; - last SWITCH_OBJ_ATTR; - } - if ( $parse_obj_attr eq 'ipv6_type') { # IPV6 ip addr - $parse_obj_attr_value = CACTUS::FWORCH::remove_space_at_end($parse_obj_attr_value); - $network_objects{"$parse_obj_name.type"} = $parse_obj_attr_value; - last SWITCH_OBJ_ATTR; - } - if ( $parse_obj_attr eq 'type' && $parse_obj_attr_value eq 'ipv6_object') { # ignore v6 type info - last SWITCH_OBJ_ATTR; - } - # end ipv6 - if ( $parse_obj_attr eq 'ipaddr_first' || $parse_obj_attr eq 'bogus_ip') { # R75 new feature zone objects without ip_addr - $parse_obj_attr_value = - CACTUS::FWORCH::remove_space_at_end($parse_obj_attr_value); - $network_objects{"$parse_obj_name.ipaddr"} = $parse_obj_attr_value; - last SWITCH_OBJ_ATTR; - } - if ( $parse_obj_attr eq 'AdminInfo' ) { - $network_objects{"$parse_obj_name.UID"} = - &gen_uid($parse_obj_attr_ext_value); - last SWITCH_OBJ_ATTR; - } - if ( $parse_obj_attr eq 'By' ) { - $network_objects{ - "$parse_obj_name.last_change_admin"} = - $parse_obj_attr_value; - last SWITCH_OBJ_ATTR; - } - if ( $parse_obj_attr eq 'Time' ) { - $network_objects{"$parse_obj_name.last_change_time"} - = $parse_obj_attr_value; - -# print("debug: setting last_change_time for nwobject $parse_obj_name to $parse_obj_attr_value\n"); - last SWITCH_OBJ_ATTR; - } - $network_objects{"$parse_obj_name.$parse_obj_attr"} = - $parse_obj_attr_value; - } - } - last SWITCH_OBJ_TYPE; - } - - # services & resources - if ( $parse_obj_type eq "services" || $parse_obj_type eq "resources") { - - # schon ein bekanntes network_object? - if ( !defined( $services{"$parse_obj_name.name"} ) ) { - @services = ( @services, $parse_obj_name ); - $services{"$parse_obj_name.name"} = $parse_obj_name; - } - - # Daten im Hash ergaenzen - if ( $parse_obj_state > 10 ) { - if ( defined($parse_obj_groupmember) - && defined($parse_obj_groupmember_refs) ) - { - - # group member alle eingesammelt, abspeichern und zurueck - @services{"$parse_obj_name.members"} = - $parse_obj_groupmember; - @services{"$parse_obj_name.member_refs"} = - $parse_obj_groupmember_refs; - @services{"$parse_obj_name.typ"} = 'group'; - } - $parse_obj_state -= 10; - } - if ( defined($parse_obj_attr_value) ) { - - # Attribute aufarbeiten - SWITCH_OBJ_ATTR: { - if ( $parse_obj_attr eq 'AdminInfo' ) { - $services{"$parse_obj_name.UID"} = - &gen_uid($parse_obj_attr_ext_value); - last SWITCH_OBJ_ATTR; - } - if ( $parse_obj_attr eq 'By' ) { - $services{"$parse_obj_name.last_change_admin"} = - $parse_obj_attr_value; - last SWITCH_OBJ_ATTR; - } - if ( $parse_obj_attr eq 'Time' ) { - $services{"$parse_obj_name.last_change_time"} = - $parse_obj_attr_value; - -# print("debug: setting last_change_time for service $parse_obj_name to $parse_obj_attr_value\n"); - last SWITCH_OBJ_ATTR; - } - if ( $parse_obj_attr eq 'port' ) { - - # >portnummer identifizieren - if ( $parse_obj_attr_value =~ (/"\>(\d+)/) ) { - $services{"$parse_obj_name.port"} = $1 + 1; - $services{"$parse_obj_name.port_last"} = 65535; - } - - # portnummer identifizieren SRC - if ( $parse_obj_attr_value =~ (/"\>(\d+)/) ) { - $services{"$parse_obj_name.src_port"} = $1 + 1; - $services{"$parse_obj_name.src_port_last"} = - 65535; - } - - # ) { - $line = $_; # Zeileninhalt merken - $last_line = $line; # fuer end of line check - $line =~ s/\x0D/\\r/g; # literal carriage return entfernen - $line =~ s/\r\n/\n/g; # handle cr,nl (d2u ohne Unterprogrammaufruf) - chomp($line); - $ln++; # Zeilennummer merken - - SWITCH_parsemode: { - - # objects oder rules parsen? - if ( $mode eq 'objects' ) { - - # group member collection - if ( $parse_obj_state > 10 ) { - - #kein neuer Parameter, d.h. ein Gruppenmitglied (Member) gefunden - # Pattern <=> Einzugtiefe, Doppelpunkt, 'Zeichenkette' - if (/^\t{3}:(\w+)/) - { # Ende der Member-Definition, weiter aber Member noch nicht wegschreiben - $parse_obj_state -= 10; - } - else { # Member anfuegen - # Pattern <=> Einruecktiefe, Doppelpunkt, "Name", Leerzeichen, 'Namensstring' - my $member_prefix = ''; - if (defined($group_with_exclusion_marker) && - ($group_with_exclusion_marker eq 'base' || $group_with_exclusion_marker eq 'exception')) - { - $member_prefix = "{$group_with_exclusion_marker}"; - undef ($group_with_exclusion_marker); - } - if (/^\t{4}:Name\s\(([\w\-\.\_]+)\)/) { - if ( defined($parse_obj_groupmember) ) { - $parse_obj_groupmember = - $parse_obj_groupmember . $GROUPSEP . $member_prefix . $1; - } - else { - $parse_obj_groupmember = $member_prefix . $1; - } - } - elsif (/^\t{4}:Uid\s\(\"\{([\w\-]+)\}\"\)/) { - if ( defined($parse_obj_groupmember_refs) ) { - $parse_obj_groupmember_refs = - $parse_obj_groupmember_refs - . $GROUPSEP - . &gen_uid($1); - } - else { - $parse_obj_groupmember_refs = &gen_uid($1); - } - } - } - } - - # globaler Aufbau der folgenden Abschnitte: - # -> Suche nach einem Muster in einen Status => Status heraufsetzen - # Pattern <=> Einzugtiefe, ':', ...weitere - # -> optionale Bloecke - # -> Suche nach einem Muster, das den Status beendet => Status herabsetzen - # Pattern <=> Einzugtiefe, Klammerzu - - # state 1 type ohne Config bzw. einzeilig, z.B. :serverobj (serverobj) - if (/^\t:([\w\-\.\_]+)\s\(.*?\)$/) { - } - elsif (/^\t:([\w\-\.\_]+) */) { - - # anfang parse obj state 1 - # Pattern <=> Einzugtiefe, ':', obj_typ - print_debug("up $parse_obj_state => 1 at $ln\n"); - $parse_obj_state = 1; - $parse_obj_type = $1; - } - elsif (/^\t\)$/) { - - # Ende des state 1 - # Pattern <=> Einzugtiefe, Klammerzu - $parse_obj_state = 0; - undef($parse_obj_type); - } - - # parse obj state 2 - objektnamen setzen - # Pattern <=> Einzugtiefe, ':', 'Leerzeichen', obj_name, 'Leerzeichen' - if ( (/^\t{2}:\s\(([\"\w\-\.\_]+)\s*/) - && ( ( $parse_obj_state == 2 ) - || ( $parse_obj_state == 1 ) ) ) - { - print_debug("up $parse_obj_state => 2 at $ln\n"); - $parse_obj_state = 2; - $parse_obj_name = $1; - undef($parse_obj_groupmember); # Gruppe initialisieren - undef($parse_obj_groupmember_refs); # Gruppe initialisieren - } - - # Ende des state 2 - # Pattern <=> Einzugtiefe, Klammerzu - if ( (/^\t{2}\)/) ) { # Ende der Objekt-Definition - # (alter status - neuer status) darf nicht groesser als eine Ebene sein, sonst ist die Struktur falsch interpretiert worden - $parse_obj_state = 1; - if ( defined($parse_obj_groupmember) ) - { # wenn group-member gefunden, diese jetzt wegschreiben - $parse_obj_state += 10; - result_handler_obj(); - } - undef($parse_obj_name); - } - -# parse obj state 3 -# in diesem und den hoeheren Stati werden die Objekteigenschaften festgelegt. -# Pattern <=> Einzugtiefe, ':', parameter, 'Leerzeichen', 'Klammerauf', value-wenn definiert, 'Klammerzu', - if ( (/^\t{3}:(\w+)\s\((.*)/) - && ( ( $parse_obj_state == 3 ) - || ( $parse_obj_state == 2 ) ) ) - { - print_debug("up $parse_obj_state => 3 at $ln\n"); - $parse_obj_state = 3; - $parse_obj_attr = - &remove_space_at_end($1); # TMP, remove space at end of attribute (eg. ip) - if ( defined($2) ) { # Klammer nicht leer - # value zwischenspeichern und untersuchen - my $local_line = $2; - print_debug("local_line: $local_line at $ln\n"); #TMP - # Ist der Wert in einer Zeile mit dem Parameter angegeben? - # Pattern <=> value, 'Klammerzu' - if ( $local_line =~ (/^(.*)\)$/) ) { - undef($parse_obj_attr_value); - if ( defined($1) ) { - $parse_obj_attr_value = - &remove_space_at_end($1) - ; # TMP, remove space at end of attribute (eg. ip) - } - - # derzeit nicht interpretierte Parameter ueberspringen - unless ( ( $parse_obj_attr eq 'members_query' ) - || ( $parse_obj_attr eq 'show_in_menus' ) - || ( $parse_obj_attr eq 'reload_proof' ) - || ( $parse_obj_attr eq 'etm_enabled' ) -# || ( $parse_obj_attr eq 'track' ) -# || ( $parse_obj_attr eq 'Wiznum' ) - || ( $parse_obj_attr eq 'include_in_any' ) ) - { - - # den Rest im Result Handler aufbereiten - print_debug("call result handler at $ln\n"); - result_handler_obj(); - } - print_debug( - " auto down $parse_obj_state => 2 at $ln\n"); - -# Keine Gruppe/Liste geoeffnt, daher direkt den parse_obj_state auf den Level 2 zuruecksetzen - $parse_obj_state = 2; - $parse_obj_attr = ""; - } - } - } - -# Gruppenmitglieder zu service oder nwobject (wichtig, nur Eintraege ohne 'members_query'!!!) -# Setzt nur den Status um >10 --> Gruppe -# Pattern <=> Einzugtiefe, ':', 'Leerzeichen', 'Klammerauf', 'ReferenceObject', 'Klammerzu', - if ( (/^\t{3}:\s\(ReferenceObject/) ) { - print_debug("up $parse_obj_state => 3 at $ln\n"); - $parse_obj_state = 3; - - # Gruppenstatus setzten - $parse_obj_state += 10; - } -# Behandlung von "group_with_exclusion" Objekten - if ( (/^\t{3}:base\s\(ReferenceObject/) ) { - $group_with_exclusion_marker = 'base'; - $parse_obj_state = 13; - } - if ( (/^\t{3}:exception\s\(ReferenceObject/) ) { - $group_with_exclusion_marker = 'exception'; - $parse_obj_state = 13; - } - - # Ende des state 3 - # Pattern <=> Einzugtiefe, Klammerzu - if ( (/^\t{3}\)/) ) { - -# (alter status - neuer status) darf nicht groesser als eine Ebene sein, sonst ist die Struktur falsch interpretiert worden - $parse_obj_state = 2; - $parse_obj_attr = ""; - } - -# parse obj state 4 -# Pattern <=> Einzugtiefe, ':', parameter, 'Leerzeichen', 'Klammerauf', value-wenn definiert, 'Klammerzu', - if ( - (/^\t{4}:(\w+)\s\((.*?)\)/) - && ( $parse_obj_state == 4 - || $parse_obj_state == 3 - || $parse_obj_state == 5 ) - ) - { - print_debug("up $parse_obj_state => 4 at $ln\n"); - $parse_obj_state = 4; - $parse_obj_attr_ext = $1; - if ( defined($2) ) { - $parse_obj_attr_ext_value = $2; - print_debug( - " auto down $parse_obj_state => 3 at $ln\n"); - if ( defined($parse_obj_attr_ext_value) ) { - $parse_obj_attr_ext_value = - &remove_space_at_end( - $parse_obj_attr_ext_value) - ; # TMP, remove space at end of attribute (eg. ip) - # Suche nach \t\t\t\t:chkpf_uid ("{9BD86F11-908B-4723-B7E9-31252A17B034}") - if ( $parse_obj_attr_ext eq 'chkpf_uid' ) { - - # Aufbereiten der UID, Pattern "{ entfernen - $parse_obj_attr_ext_value =~ s/\"\{//g; - - # Pattern }" entfernen - $parse_obj_attr_ext_value =~ s/\}\"//g; - $parse_obj_attr_ext_value = - $parse_obj_attr_ext_value; - - # Abspeichern der UID - result_handler_obj(); - undef($parse_obj_attr_ext_value); - } - } - $parse_obj_attr_ext = ""; - } - } - - # Ende des state 4 - # Pattern <=> Einzugtiefe, Klammerzu - if ( (/^\t{4}\)/) && ( $parse_obj_state < 10 ) ) { - -# (alter status - neuer status) darf nicht groesser als eine Ebene sein, sonst ist die Struktur falsch interpretiert worden - $parse_obj_state = 3; - undef($parse_obj_attr_ext); - undef($parse_obj_attr_ext_value); - } - -# parse obj state 5 -# Pattern <=> Einzugtiefe, ':', parameter, 'Leerzeichen', 'Klammerauf', value-wenn definiert, 'Klammerzu', - if ( - (/^\t{5}:(\w+)\s\((.*)/) && ( - $parse_obj_state == 5 - || $parse_obj_state == 4 - ) - ) - { - print_debug("up $parse_obj_state => 5 at $ln\n"); - $parse_obj_state = 5; - if ( defined($2) ) { - my $local_line = $2; - $parse_obj_attr = $1; - if ( $parse_obj_attr eq 'By' ) { - - # der attr_ext_value steht in einer Zeile mit dem attr_ext - # Pattern <=> 'beliebige Zeichen des values', Klammerzu - if ( $local_line =~ (/^(.*)\)$/) ) { - $parse_obj_attr_value = $1; - - # Abspeichern des last_change_admin - result_handler_obj(); - } - } - if ( $parse_obj_attr eq 'Time' ) { - my $timestamp; - if ( $local_line =~ (/^\"(.*)\"\)$/) ) { - $timestamp = convert_checkpoint_to_db_date($1); - if ( defined($timestamp) ) { - $parse_obj_attr_value = $timestamp; - result_handler_obj(); - if ( !defined($last_change_time_of_config) - || $last_change_time_of_config - lt $timestamp ) - { - - # das gefundene Aenderungsdatum ist neuer als das bisherige - $last_change_time_of_config = - $timestamp; - } - } - } - } - } - - # $parse_obj_state = 4; - } - - # Ende des state 5 - # Pattern <=> Einzugtiefe, Klammerzu - if ( (/^\t{5}\)/) && ( $parse_obj_state < 10 ) ) { - -# (alter status - neuer status) darf nicht groesser als eine Ebene sein, sonst ist die Struktur falsch interpretiert worden - $parse_obj_state = 4; - undef($parse_obj_attr_ext2); - undef($parse_obj_attr_ext2_value); - } - -# parse obj state 6 -# Pattern <=> Einzugtiefe, ':', parameter, 'Leerzeichen', 'Klammerauf', value-wenn definiert, 'Klammerzu', - if ( (/^\t{6}:(\w+)\s\((.*)/) - && ( ( $parse_obj_state == 6 ) - || ( $parse_obj_state == 5 ) ) ) - { - print_debug("up $parse_obj_state => 6 at $ln\n"); - $parse_obj_state = 6; - $parse_obj_attr_ext3 = - &remove_space_at_end($1) - ; # TMP, remove space at end of attribute (eg. ip) - if ( defined($2) ) { - my $local_line = $2; - - # der attr_ext_value steht in einer Zeile mit dem attr_ext - # Pattern <=> 'beliebe Zeichen des values', Klammerzu - if ( $local_line =~ (/^(.*)\)$/) ) { - print_debug( - " auto down $parse_obj_state => 6 at $ln\n"); - if ( defined($1) ) { - $parse_obj_attr_ext3_value = - &remove_space_at_end($1); # TMP, remove space at end of attribute - } - - #// insert parsresult handler call //# - #// wenn weitere Auswertung notwendig //# - $parse_obj_state = 5; - undef($parse_obj_attr_ext3); - undef($parse_obj_attr_ext3_value); - - # komplexes Attribut, ggf. im Resulthandler auszuwerten - } - } - } - - # Ende des state 6 - # Pattern <=> Einzugtiefe, Klammerzu - if ( (/^\t{6}\)/) && ( $parse_obj_state < 10 ) ) { - -# (alter status - neuer status) darf nicht groesser als eine Ebene sein, sonst ist die Struktur falsch interpretiert worden -# print_debug("down $parse_obj_state => 5 at $ln\n") || (($parse_obj_state - 4) >1); - $parse_obj_state = 5; - undef($parse_obj_attr_ext3); - undef($parse_obj_attr_ext3_value); - } - -# parse obj state 7 -# Pattern <=> Einzugtiefe, ':', parameter, 'Leerzeichen', 'Klammerauf', value-wenn definiert, 'Klammerzu', - if ( (/^\t{7}:(\w+)\s\((.*)/) - && ( ( $parse_obj_state == 7 ) - || ( $parse_obj_state == 6 ) ) ) - { - print_debug("up $parse_obj_state => 7 at $ln\n"); - $parse_obj_state = 7; - $parse_obj_attr_ext4 = - &remove_space_at_end($1) - ; # TMP, remove space at end of attribute - if ( defined($2) ) { - my $local_line = $2; - if ( $local_line =~ (/^(.*)\)$/) ) { - print_debug( - " auto down $parse_obj_state => 7 at $ln\n"); - if ( defined($1) ) { - $parse_obj_attr_ext4_value = - &remove_space_at_end($1) - ; # TMP, remove space at end of attribute - } - - #// insert parsresult handler call //# - #// wenn weitere Auswertung notwendig //# - $parse_obj_state = 6; - undef($parse_obj_attr_ext4); - undef($parse_obj_attr_ext4_value); - - # komplexes Attribut, ggf. im Resulthandler auszuwerten - # $parse_obj_attr = ""; - } - } - } - - # Pattern <=> Einzugtiefe, Klammerzu - if ( (/^\t{7}\)/) && ( $parse_obj_state < 10 ) ) { - -# (alter status - neuer status) darf nicht groesser als eine Ebene sein, sonst ist die Struktur falsch interpretiert worden -# print_debug("down $parse_obj_state => 6 at $ln\n") || (($parse_obj_state - 6) >1); - $parse_obj_state = 6; - undef($parse_obj_attr_ext4); - undef($parse_obj_attr_ext4_value); - } - - #// insert parsresult handler call //# - #// wenn weitere Auswertung notwendig //# - last SWITCH_parsemode; - } - - # Rules parsen - if ( $mode eq 'rules' ) { - - # rule member collection - # sammelt mitglieder einer Gruppe (entspricht hier einer Spalte) - if ( $parserule_state > 10 ) { - - #kein neuer Parameter - keine schliessende Klammer - # Pattern <=> Einzugtiefe, Klammerzu - unless (/^\t\t\t\)/) { - -# innerhalb der Gruppe Parameter suchen -# Pattern <=> Einzugtiefe, ':',Eigenschaft der Gruppe, Leerzeichen Klammerauf, value-wenn definiert, Klammerzu - if (/^\t{4}:(op)\s\((.*)\)/) { - $parserule_ruleparameter_ext = $1; - if ( defined($2) ) { - if ( $2 eq '"not in"' ) { - $parserule_ruleparameter_ext_value = "true"; - } - else { - $parserule_ruleparameter_ext_value = "false"; - } - $rulebases{"$parserule_rulebasename.$parserule_rulenum.$parserule_ruleparameter.$parserule_ruleparameter_ext"} = $parserule_ruleparameter_ext_value; - } - } - -# compound gruppenmitglieder, die Gruppe faengt hier an -# Pattern <=> Einzugtiefe, Doppelpunkt, "compound", Leerzeichen, Klammerauf, 'zeichenkette' - if (/^\t{4}:(compound)\s\((.*)/) { - - # kein Wert angegeben - # Pattern <=> Klammerzu - unless ( $2 =~ m/\)$/ ) { - $parserule_state = 16; - } - - # Werte werden zwischengespeichert, aber nicht verwendet - $parserule_ruleparameter_ext = $1; - $parserule_ruleparameter_ext_value = $2; - } - -# einfaches gruppenmitglied faengt hier an -# Pattern <=> Einzugtiefe, ':', Leerzeichen, Klammerauf, "ReferenceObject", Klammerzu - if (/^\t{4}:\s\(ReferenceObject/) { - $parserule_state = 15; - } - - # die eigentliche Gruppenliste hoert auf - # Pattern <=> Einzugtiefe, Klammerzu - elsif (/^\t{4}\)/) { - $parserule_state = 14; - } - -# einfaches Member anfuegen -# Pattern <=> Einzugtiefe, Doppelpunkt, "Name", Leezeichen, 'objektname', Klammerzu -# bei Name-Pattern auch Leerzeichen und optionale Hochkommata-Klammerung hinzugefuegt (fuer UserDefined 3) - if ( (/^\t{5}:Table\s\(([\w\-\.\_\s]+)\)/) - && ( $parserule_state == 15 ) ) - { - if ($1 =~ /^identity\_roles$/) { - # now not adding source network_objects but identity awareness user groups - $parse_obj_type = 'identity_roles'; - if ($prev_line =~ /^\t{5}:Name\s\(\"?([\w\-\.\_\s]+)\"?\)/) { - $parserule_ruleuser = $1; - } else { - print ("id:ERROR: found identity_roles Usergroup but no name in previous line=$prev_line\n"); - } - } - } - elsif ( (/^\t{5}:Name\s\(\"?([\w\-\.\_\s]+)\"?\)/) - && ( $parserule_state == 15 ) ) - { - if ( defined($parserule_groupmember) ) { - $parserule_groupmember = - $parserule_groupmember . $GROUPSEP . $1; - } - else { - $parserule_groupmember = $1; - } - } - elsif ((/^\t{5}:Uid\s\(\"\{([\w\-\.\_\s]+)\}\"\)/) - && ( $parserule_state == 15 ) ) - { -####### start identity_roles - if (defined($parse_obj_type) && $parse_obj_type eq 'identity_roles') { - # set identity role as user group @ any - # assuming always any source nw obj for identity rule objects - # might additionally parse identity_roles.C for specific_identity_entities (both locations and machines) -=cut - :locations ( - :restrict_to (Specific) - :specific_identity_entities ( - : (ReferenceObject - :Uid ("{BF1C6029-8D5D-4A05-A3AD-4B67E6E7A7AA}") - :Name (Cactus-100) - :Table (network_objects) - ) - : (ReferenceObject - :Uid ("{ABBA18CB-625D-4231-BF5A-6DBF646A155C}") - :Name (CACTUS-WLAN-Clients_client_auth) - :Table (network_objects) - ) - ) - ) - :machines ( - :type (machines_restriction) - :restrict_to (Specific) - :specific_identity_entities ( - : (ReferenceObject - :Uid ("{7D67B970-ABDE-4A97-8CEB-0EE8F6703750}") - :Name (ad_machine_Calamus) - :Table (ad_machines) - ) - : (ReferenceObject - :Uid ("{DDF26071-6C14-4DC1-8040-605C9042321E}") - :Name (ad_machine_TICK) - :Table (ad_machines) - ) - ) - ) -=cut - if ( defined($parserule_groupmember_refs) ) { - $parserule_groupmember_refs = $parserule_groupmember_refs . $GROUPSEP . $parserule_ruleuser . "@" . - &gen_uid($network_objects{"Any.UID"}); - $parserule_groupmember = $parserule_groupmember . $GROUPSEP . $parserule_ruleuser . '@Any'; - } - else { - $parserule_groupmember = $parserule_ruleuser . '@Any'; # assuming always any source nw obj for identity rule objects - $parserule_groupmember_refs = "$parserule_ruleuser" . "@" . &gen_uid($network_objects{"Any.UID"}); - } -# print ("id:found id_roles Usergroup User::$parserule_ruleuser, parserule_groupmember_refs: $parserule_groupmember_refs\n"); -####### end identity_roles - } else { - if ( defined($parserule_groupmember_refs) ) { - $parserule_groupmember_refs = - $parserule_groupmember_refs - . $GROUPSEP - . &gen_uid($1); - } - else { - $parserule_groupmember_refs = &gen_uid($1); - } - } - } - - # compound Member anfuegen - # Pattern <=> Einzugtiefe, Doppelpunkt, Klammerauf, 'Gruppenmitglied' - if ( (/^\t{5}:\s\((.*)/) - && ( $parserule_state == 16 ) ) - { - my $compound_name = $1; - if ( $compound_name =~ - /\w+\-\>\"?([\w\-\.\_\s]+)\"?/ ) - { # strip of resource-suffix (eg. http->) - # INFO: check point resources koennen in CP NGX und davor immer nur einzeln in Regeln auftauchen - $compound_name = $1; - $parserule_state = 18; # 18 = resource - } - if ( defined($parserule_groupmember) ) { - $parserule_groupmember = - $parserule_groupmember - . $GROUPSEP - . $compound_name; - } - else { - $parserule_groupmember = $compound_name; - } - - # Userinfo pro Regel ausfiltern - # user(-gruppen) stehen vor dem @ zeichen, gefolgt vom netz(-objekt) - if ( $compound_name =~ m/(.*)\@(.*)/ ) { - $current_user = $1; - $current_user =~ s/"//g; - if ( defined($parserule_ruleuser) ) { - $parserule_ruleuser = - $parserule_ruleuser - . $GROUPSEP - . $current_user; - } - else { - $parserule_ruleuser = $current_user; - } - } - } - - # resource - if ( (/^\t{6}:resource\s\(ReferenceObject$/) && ( $parserule_state == 18 ) ) - { - $parserule_state = 19; # 19 = uid einer Resource - } - - if ( (/^\t{7}:Uid\s\(\"\{(.*?)\}\"\)$/) && ( $parserule_state == 19 ) ) - { - $parserule_groupmember_refs = $1; -# $rulebases{"$parserule_rulebasename.$parserule_rulenum.services.refs"} = $1; -# $parserule_state = 14; - } - # end resource - - if ( (/^\t{6}:at\s\(ReferenceObject$/) && ( $parserule_state == 16 ) ) - { - $parserule_state = 17; - } - - # die Referenz auf das nwobjekt hinzufuegen - if ( (/^\t{7}:Uid\s\(\"\{(.*)\}\"\)$/) && ( $parserule_state == 17 ) ) - { - my $user_string = ''; - my $nwobj_uid = $1; - - if ( defined($current_user) ) { - $user_string = "$current_user@"; - undef($current_user); - } - if ( defined($parserule_groupmember_refs) ) { - $parserule_groupmember_refs = "$user_string" . &gen_uid($nwobj_uid) . "$GROUPSEP$parserule_groupmember_refs"; - } - else { - $parserule_groupmember_refs = "$user_string" . &gen_uid($nwobj_uid); - } - $parserule_state = 16; - } - - # alle Member gefunden, daher wegschreiben - } - else { - if ( defined($parserule_groupmember) ) { - $rulebases{"$parserule_rulebasename.$parserule_rulenum.$parserule_ruleparameter"} = $parserule_groupmember; - $rulebases{"$parserule_rulebasename.$parserule_rulenum.$parserule_ruleparameter.refs"} = $parserule_groupmember_refs; - } - - $parserule_state -= 10; - undef($parse_obj_type); - undef($parserule_groupmember); - undef($parserule_groupmember_refs); - undef($parserule_ruleuser); - } - } - - # parserule state 1 - Regelwerk faengt an - # Pattern <=> Einzugtiefe, ':rule-base' - if (/^\t:rule-base/) { - $parserule_in_rule_base = 1; - $parserule_rulenum = -1; - $parserule_state = 1; - -# den Namen identifizieren -# Pattern <=> beliebiger Anfang, Anfuehrungszeichen, Doppelkreuz, Doppelkreuz, 'name des Regelwerks', Anfuehrungszeichen - if (/.*\"##(.*)\"/) { - $parserule_rulebasename = $1; - if ( defined($rulesetname) && ruleset_does_not_fit($parserule_rulebasename, $rulesetname) ) - { # Nicht gesuchten Regelsatz uebergehen, $rulesetname = hashref - IGNORE_RULESET: while () { - $last_line = $_; - if ( $last_line =~ /^\t\)/ ) { - last IGNORE_RULESET; - } - } - } - else { - print_debug("Regelwerk $1 wird geparst\n"); - unless (defined($rulebases{"$parserule_rulebasename.name"})) - { - @rulebases = ( @rulebases, $parserule_rulebasename ); - $rulebases{"$parserule_rulebasename.name"} = $parserule_rulebasename; - $rulebases{"$parserule_rulebasename.rulecount"} = 0; - } - - # LastChangeAdmin und LastSaveTime fuer das Regelwerk identifizieren - IGNORE_ADM_INFO: while ( $line = ) - { # move to end of AdminInfo - $last_line = $_; - if ( $line =~ /^\t\t\)/ ) { - last IGNORE_ADM_INFO; - } - if ( $line =~ /^\t\t\t\t:By\s\((.+?)\)/ ) { - $rulebases{"$parserule_rulebasename.last_change_admin"} = $1; - } - if ( $line =~ /^\t\t\t\t:Time\s\(\"(.+?)\"\)/ ) - { - my $timestamp = convert_checkpoint_to_db_date($1); - if ( defined($timestamp) ) { - $rulebases{"$parserule_rulebasename.last_save_time"} = $timestamp; - if (!defined($last_change_time_of_config) || $last_change_time_of_config lt $timestamp) - { # das gefundene Aenderungsdatum ist neuer als das bisherige - $last_change_time_of_config = $timestamp; - } - } - } - } - } - } - } - - # parserule state 2 - Access Regel faengt an - # Pattern <=> Einzugtiefe, ':rule ' - if (/^\t{2}:rule\s/) { - $parserule_in_rule = 1; - $parserule_rulenum++; - print_debug( - "switching form state $parserule_state to 2.\n"); - $parserule_state = 2; - $rulebases{"$parserule_rulebasename.rulecount"} = - $parserule_rulenum + 1; - -# setzen des last_change_admin (bei CP leider global fuer das gesamte Regelwerk) - $rulebases{"$parserule_rulebasename.$parserule_rulenum.last_change_admin"} = - $rulebases{"$parserule_rulebasename.last_change_admin"}; - $ruleorder[$parserule_rulenum] = $parserule_rulenum; # Regeln sind einfach von 1-n durchnummeriert - # neu: Wegschreiben der Regelreihenfolge - $rulebases{"$parserule_rulebasename.ruleorder"} = - join( ',', @ruleorder ); - print_debug( - "rule: $parserule_in_rule\t$parserule_rulenum\n"); - } - if (/^\t{2}:rule_adtr\s/) - { # eingefuegt, um keine comments von AdrTrans-Regeln hineinzubekommen - print_debug("ignoring address translation rule\n"); - IGNORE_ADDR_TRANS: while () { - $last_line = $_; - if ( $last_line =~ /^\t\t\)/ ) { - last IGNORE_ADDR_TRANS; - } - } # lese Zeilen bis zur Ende-Klammerung der rule_adtr - } - - # parserule state 3 - Regeldetails fangen an - # Pattern <=> Einzugtiefe, ':', beliebiges dahinter - if ( ( /^\t{3}:(.*)/ && $parserule_state > 1 ) ) { - $parserule_state = 3; - } - - # Behandlung der Regeldetails - if ( $parserule_state >= 3 && $parserule_state < 10 ) { - - #Einzelfaelle behandeln - switch_rulepart: { - -# value in der gleichen Zeile -# Pattern <=> Einzugtiefe, ':', einer der parameter, Leerzeichen, Klammerauf, Wert-wenn definiert, Klammerzu - if (/^\t\t\t:(name|disabled|global_location|comments|header_text)\s\((.*)\)/) - { - $parserule_state = 4; - $parserule_ruleparameter = $1; - if ( defined($2) ) { - my $parserule_ruleparameter_value = $2; - $rulebases{"$parserule_rulebasename.$parserule_rulenum.$parserule_ruleparameter"} = $parserule_ruleparameter_value; - if (( $parserule_ruleparameter eq 'comments' ) && ( $parserule_ruleparameter_value =~ m/\@A(\d+)\@/ ) ) - { # customer specific customizing - $rulebases{"$parserule_rulebasename.$parserule_rulenum.rule_id"} = $1; - } - } - last switch_rulepart; - } - - # Value eine Zeile tiefer - # Pattern <=> Einzugtiefe, ':', action, Leerzeichen, Klammerauf - if (/^\t{3}:(action)\s\(/) { - $parserule_state = 4; - $parserule_ruleparameter = $1; - - #neue Zeile einlesen - $_ = ; - $line = $_; - $last_line = $line; - $ln++; - s/\r\n/\n/g - ; # handle cr,nl (d2u ohne Unterprogrammaufruf) - # Pattern <=> bel. Leerzeichen, Klammerauf, value - /\s*:\s\((.*)/; - - if ( defined($1) ) { - my $parserule_ruleparameter_value = $1; - $rulebases{"$parserule_rulebasename.$parserule_rulenum.$parserule_ruleparameter"} = $parserule_ruleparameter_value; - } - last switch_rulepart; - } - - # Value ist eine Auflistung - # Pattern <=> Einzugtiefe, ':', eine der Aktionen, Leerzeichen, Klammerauf - if (/^\t{3}:(src|dst|services|install|track|time|through)\s\(/) - { - $parserule_state = 14; - $parserule_ruleparameter = $1; - last switch_rulepart; - } - - # Value ist Rule AdminInfo - # Pattern <=> Einzugtiefe, ':', "AdminInfo", Leerzeichen, Klammerauf - if (/^\t{3}:(AdminInfo)\s\(/) { - # Zeilen lesen, bis UID gefunden - while () { - $line = $_; - $ln++; - $last_line = $line; - s/\r\n/\n/g - ; # handle cr,nl (d2u ohne Unterprogrammaufruf) - # Pattern <=> Einzugtiefe, ':', "chkpf_uid", Leerzeichen, Klammer auf, Doppeltes Hochkomma, geschw. Klammer auf, 'UID', geschw. Klammer zu, Doppeltes Hochkomma - if (/^\t\t\t\t:chkpf_uid\s\(\"\{(.*)\}\"\)/) { - my $rule_uid = &gen_uid($1); - -# folgenden Praefix eingefuegt wg. Bug bei CP (zwei Regeln eines Mgmts mit derselben UID) - $rulebases{"$parserule_rulebasename.$parserule_rulenum.UID"} = $parserule_rulebasename . '__uid__' . $rule_uid; - last; - } - if (/^\t{4}:ClassName\s\(security_header_rule\)/) - { - # ignore this rule except for :header_text - $header_FLAG = 1; - } - } - } - last switch_rulepart; - } - } - last SWITCH_parsemode; - } - } - $prev_line = $line; - } - - # Interpretation des Inputs ist abgeschlossen, - # Aufraeumen dateihandle etc. - #---------------------------------------- - #print "\t\t ... parsing abgeschlossen\n\n"; - close(IN); - print_debug("$in_file closed.\n"); - - # check auf Vollstaendigkeit des Config-Files: - if ( $last_line =~ m/^\)(\n)?$/ ) { return 0; } - else { - return "last line of config-file $in_file not correct: <$last_line>"; - } -} - -#################################### -# cp_parse_main -# Main-Routine zum Parsen von CP-Configs -# Ausgabe: CSV-Dateien im output-directory -# param1: input-filename -# param2: output-directory -# param3: verbose_flag (0/1) -#################################### -sub cp_parse_main { - my $in_file = $_[0]; - my $out_dir = $_[1]; - my $rulesetname = $_[2]; - my $verbose = $_[3]; - my $mode; - -# Setzen des Parsermodes -# umschalten des Betriebsmodus anhand der Dateiextension des uebergebenen Konfigurationsfiles - if ( $in_file =~ /\.fws/ ) { # eine *.fws datei => Regelwerke - $mode = 'rules'; - } - elsif ( $in_file =~ /\_5_0.C/ ) { # eine _5_0.C Datei => Objekte - $mode = 'objects'; - } - else { # etwas unbekanntes - die "unknown File extension in $in_file - exiting!\n"; - } - - # print_verbose ("using mode $mode\n"); - print "parsing config file: $in_file\n"; - - # print ("in_file: $in_file, mode: $mode, rulsetname: $rulesetname\n"); - my $result = parse_cp2( $in_file, $mode, $rulesetname ); - - if ($mode eq 'objects') { - &cp_resolve_groups_with_exception(); - } - -# &print_results_monitor($mode); - return $result; -} - -sub cp_parse_users_main { - my $user_db_file = shift; - my $output_dir = shift; - my $verbose = shift; - my $result = 0; - my $line = ''; - - # first check if it is the original DB format or an exported version of the group and user data (using fw dbexport) - if ( -T $user_db_file ) { # -T: is the file a text only file without binary chars? - my $INFILE = new IO::File("< $user_db_file") or die "cannot open file $user_db_file\n"; - $line = <$INFILE>; $INFILE->close; - if (defined($line)) { - if ( $line =~ /^name;\tgroups;\tcolor;\tcomments;\tis_administrator_group;/ ) { # start of user group definitions dbexport file - print "parsing users from csv dbexport: $user_db_file\n"; - &cp_parse_users_csv_db_exported($user_db_file, $output_dir, $verbose); - } - if ($line =~ /\<\?xml/) { - print "parsing users from xml: $user_db_file\n"; - &cp_parse_users_xml_exported($user_db_file, $output_dir, $verbose); - } - } - } else { # binary/original user file - print "NOTICE: currently not parsing Check Point users from binary config file $user_db_file\n"; - # $result = &cp_parse_users_original_format( $user_db_file, $output_dir, $verbose ); - } - &cp_parse_users_add_special_all_users_group(); - return $result; -} - -sub cp_parse_users_add_special_all_users_group { - my $name = 'All Users'; # adding special predefined user group "All Users" if it does not exist yet - if (!defined($user{"$name.type"})) { - push @user_ar, $name; - $user{"$name.type"} = 'group'; - $user{"$name.uid"} = $name; - $user{"$name.comments"} = 'special Check Point predefined usergroup containing all users'; - } -} - -sub cp_parse_users_add_member_to_group { - my $gruppe = shift; - my $member = shift; - my $debug = shift; - my $oldmembers = ""; - my @group_ar = (); - - if ( defined( $usergroup{"$gruppe"} ) ) { - $oldmembers = $usergroup{"$gruppe"} . $usergroupdelimiter; - @group_ar = split /[$usergroupdelimiter]/, $oldmembers; - } - if ($debug) { print (" cp_parse_users_add_member_to_group:: found member $member for group $gruppe; members so far: $oldmembers\n"); } - if ( !grep( /^${member}$/, @group_ar ) && $member ne $gruppe ) - { # doppelte Member und Rekursion vermeiden - $usergroup{"$gruppe"} = $oldmembers . $member; - } - return; -} - -sub cp_parse_users_add_groupmembers_final { - # bei CP sind Namen und UIDs der User identisch, da uid (derzeit) nicht aus fwauth.NDB ausgelesen werden kann - foreach my $gruppe ( keys %usergroup ) { - $user{"$gruppe.member_refs"} = $usergroup{"$gruppe"}; - $user{"$gruppe.members"} = $usergroup{"$gruppe"}; - $user{"$gruppe.type"} = "group"; - if ( !grep( /^${gruppe}$/, @user_ar ) ) { - push @user_ar, $gruppe; - } - } - return; -} - -sub cp_parse_users_xml_exported { - -=cut -syntax start: xxx -userdefinition: - -xxx -user|user_group|external_group -user_group: user-in-group users
                      -xxx - -
                      -ende:
                      -=cut - - my $in_file_main = shift; - my $fworch_workdir = shift; - my $debuglevel_main = shift; - my $line = ''; - my $last_line = ''; - my $parse_error = 0; - my $line_no = 0; - my $INFILE = new IO::File("< $in_file_main") or die "cannot open file $in_file_main\n"; - my $debug_lines = ''; - my $debug = 0; - my $start = 1; - my ($name, $type, $color, $comments, $is_admin, $uid, $expdate, $group_string, $rest_of_line); - - LINE: while ( $line = <$INFILE> ) { - $last_line = $line; - $line_no++; - if ($start && $line !~ /\/) { next LINE; } else { $start = 0; } - if (!$start && $line =~ /\/) { - if ( $line =~ /\\(.+?)\<\/Name\>\(.+?)\<\/Class\_Name\>(.+)$/ ) { # start of user definition - $name = $1; $type = $2; $uid = $name; $rest_of_line = $3; - } else { - print ("debug: no match in line: $line\n"); - } - } - if ($line =~ /\\s*(.*?)\s*<\/groups\>\s*\/ ) { # group membership definition - my $group_string = $1; - while ($group_string ne '') { -# print ("DEBUG: group_string=$group_string\n"); - if ($group_string =~ /^\\s*\\s*(.+?)\s*\<\/Name\>\s*\\s*users\s*\<\/Table\>\s*\<\/groups\>(.*)/ ) { # group membership definition - my $group = $1; - $group_string = $2; - &cp_parse_users_add_member_to_group ($group, $name, 0); -# print ("DEBUG: found group for user $name=$group\n"); - } else { -# print ("DEBUG warning: found no match in group_string $group_string - would result in endless looping\n"); - $group_string = ''; - } - } - } - if ($line =~ /\<\/user\>/) { # end of user definition - if ($type eq 'external_group' || $type eq 'user_group') { $type = 'group'; } - if ($type eq 'user') { $type = 'simple'; } - if ($type eq'simple' || $type eq 'group') { - push @user_ar, $name; - $user{"$name.type"} = $type; - $user{"$name.uid"} = $uid; - if ( defined($color) ) { $user{"$name.color"} = $color; } - if ( defined($comments) ) { $user{"$name.comments"} = $comments; } - if ( defined($expdate) ) { $user{"$name.expdate"} = $expdate; } - } - undef($name); undef($type); undef($color); undef($comments); undef($is_admin); undef($uid); undef($expdate); undef($group_string); - } - } - $INFILE->close; - &cp_parse_users_add_groupmembers_final; - # check auf Vollstaendigkeit des Config-Files: - if ( $last_line =~ /\<\/users\>/ && !$parse_error) { return 0; } - else { - print ("error while parsing exported userdata, last_line: <$last_line>"); - return "error while parsing exported userdata, last_line: <$last_line>"; - } -} - -sub cp_parse_users_csv_db_exported { - -=cut - -limitations: - -fw dbexport of user data does not export IDs (UIDs) so the UID field will be filled with the user name - -syntax groups: - -name; groups; color; comments; is_administrator_group; -group1; ; red; ; ; -group2; ; red; ; ; -group3; ; red; Kommentar3; ; -group4; ; orange; Kommentar4; ; - - -syntax users: - -name; color; groups; destinations; sources; auth_method; fromhour; tohour; expiration_date; days; accept_track; internal_password; SKEY_seed; SKEY_number; SKEY_passwd; SKEY_gateway; comments; radius_server; vlan_auth_list; userc; expire; isakmp.transform; isakmp.data.integrity; isakmp.encryption; isakmp.methods; isakmp.encmethods; isakmp.hashmethods; isakmp.authmethods; isakmp.shared.secret; tacacs_server; SKEY_method; administrator; administrator_profile; -user1; red; {group1,group4}; {Any}; {Any}; Internal Password; 00:00; 23:59; 20-Sep-1999; {MON,TUE,WED,THU,FRI,SAT,SUN}; None; 5bV0ZOoq921Bs; ; ; ; ; Kommentar1; Any; {}; {DES,DES,MD5}; 60; ; ; ; ; ; ; ; ; Any; ; false; ; -user2; orange; {group2,group3,group1}; {Any}; {Any}; Internal Password; 00:00; 23:59; 15-feb-2001; {MON,TUE,WED,THU,FRI,SAT,SUN}; AuthAlert; nb.NZXrB2qyxA; ; ; ; ; Testuser; Any; {}; {,,None}; ; ESP; SHA1; 3DES; ; {DES,3DES}; {MD5,SHA1}; {signatures}; ; Any; ; false; ; -user3; orange; {group2}; {Any}; {Any}; Internal Password; 08:00; 18:00; 27-Sep-1999; {MON,TUE,WED,THU,FRI,SAT,SUN}; None; 7b.SEuf5N.YV2; ; ; ; ; Testkennung f. acde; Any; {}; {DES,DES,MD5}; 60; ; ; ; ; ; ; ; ; Any; ; false; ; - -=cut - - my $in_file_main = shift; - my $fworch_workdir = shift; - my $debuglevel_main = shift; - my $line = ''; - my $last_line = ''; - my $parse_error = 0; - my $line_no = 0; - my $INFILE = new IO::File("< $in_file_main") or die "cannot open file $in_file_main\n"; - my $debug_lines = ''; - my $debug = 0; - my $type; - - while ( $line = <$INFILE> ) { - $line_no++; - if ( $line =~ /^name;\tgroups;\tcolor;\tcomments;\tis_administrator_group;/ ) { # start of user group definitions - $type = 'group'; - } elsif ( $line =~ /^name;\tcolor;\tgroups;\tdestinations;\tsources;/ ) { # start of user definitions - $type = 'simple'; - } else { # no header - plain user or group data from here on - my $name; - my $color; - my $comments; - my $is_admin; - my $uid; - my $expdate; - my $group_string; - - if ($type eq 'group' && $line =~ /^(.*?);\t(.*?);\t(.*?);\t(.*?);\t(.*?);/ ) { - $name = $1; - $group_string = $2; - $color = lc($3); - $comments = $4; - } elsif ($type eq 'simple' && $line =~ /^(.*?);\t(.*?);\t(.*?);\t(.*?);\t(.*?)\t(.*?);\t(.*?);\t(.*?);\t(.*?);\t(.*?);\t(.*?);\t(.*?);\t(.*?);\t(.*?);\t(.*?);\t(.*?);\t(.*?);\t(.*?);\t(.*?);\t(.*?);\t(.*?);\t(.*?);\t(.*?);\t(.*?);\t(.*?);\t(.*?);\t(.*?);\t(.*?);\t(.*?);\t(.*?);\t(.*?);\t(.*?);\t(.*?);/ ) { - $name = $1; - $color = lc($2); - $group_string = $3; - $comments = $17; - $expdate = &convert_checkpoint_to_db_date($9); - } else { # line not parsable - $parse_error = 1; - print (" $line_no: this line was not parsable: $line\n"); - } - $uid = $name; - if ($group_string ne '') { - my $group_string_without_brackets; - if ( $group_string =~ /\{(.*?)\}/ ) { $group_string_without_brackets = $1; } - my @groups_this_user_belongs_to_ar = split /,/, $group_string_without_brackets; - foreach my $gruppe (@groups_this_user_belongs_to_ar) { -# print (" adding user $name to group $gruppe\n"); - if ( $gruppe ne 'ReferenceObject' ) { -# TODO: Fehler fuer toten Link ausgeben - &cp_parse_users_add_member_to_group ($gruppe, $name, $debug); - } - } - } - push @user_ar, $name; -# print (" $line_no: adding new user $name\n"); - $user{"$name.type"} = $type; - $user{"$name.uid"} = $uid; - if ( defined($color) ) { $user{"$name.color"} = $color; } - if ( defined($comments) ) { $user{"$name.comments"} = $comments; } - if ( defined($expdate) ) { $user{"$name.expdate"} = $expdate; } - } - $last_line = $line; - } - $INFILE->close; - &cp_parse_users_add_groupmembers_final; - # check auf Vollstaendigkeit des Config-Files: - if ( $last_line =~ m/^.+?\;(.*?\;){31}/ && !$parse_error) { return 0; } - else { - print ("error while parsing exported userdata, last_line: <$last_line>"); - return "error while parsing exported userdata, last_line: <$last_line>"; - } -} -# parse user groups that are externally defined (e.g. LDAP) from rules in rulebase file -# does not work for individual users - all these groups will be empty - -sub cp_parse_users_from_rulebase { # ($rulebase_file) - my $in_file_main = shift; - my $line = ''; - my $last_line; - my $INFILE = new IO::File("< $in_file_main") or die "cannot open file $in_file_main\n"; - my $type; - my $name; - my $comments; - my $uid; - - print "parsing users from rulebase file: $in_file_main\n"; - LINE: while ( $line = <$INFILE> ) { - chomp($line); - if ($line =~ /^\t\t\t\t\t\: \(\"?(.+?)\@.+?$/) { # externally defined (e.g. ldap) user groups - $name = $1; - $comments = ""; - $type = 'group'; - $uid = $name; - if (!defined($user{"$name.type"})) { - push @user_ar, $name; - $user{"$name.type"} = 'group'; - $user{"$name.uid"} = $name; - $user{"$name.comments"} = ''; - } - } - if ($line =~ /\t+\:Table \(identity\_roles\)$/) { # identity awareness user groups - if ($last_line =~ /\t+\:Name \((.+)\)/) { - $name = $1; - $comments = "identity awareness user group"; - $type = 'group'; - $line = <$INFILE>; - if ($line =~ /\t+\:Uid \(\"\{(.+)\}\"\)$/) { - $uid = $1; - if (!defined($user{"$name.type"})) { - push @user_ar, $name; - $user{"$name.type"} = 'group'; -# $user{"$name.uid"} = $uid; - $user{"$name.uid"} = $name; - $user{"$name.comments"} = $comments; - } - } - } - } - $last_line = $line; - } - $INFILE->close; - return 0; -} - -sub cp_parse_users_original_format { - sub cp_parse_users_remove_nonprintable_chars { - sub cp_parse_user_remove_bin_data { - my $in_file_main = shift; - my $out_file_main = shift; - my $line = ''; - - my $INFILE = new IO::File("< $in_file_main") or die "cannot open file $in_file_main\n"; - binmode($INFILE); - my $OUTFILE = new IO::File("> $out_file_main") or die "cannot open file $out_file_main\n"; - binmode($OUTFILE); -# while ( sysread( $INFILE, $line, 256 ) ) { print $OUTFILE substr( $line, 3 ); } - while ( sysread( $INFILE, $line, 256 ) ) { print $OUTFILE substr( $line, 0 ); } - $INFILE->close; $OUTFILE->close; - return; - } - - my $in_file = shift; - my $out_file = shift; - my $line = ''; - my $orig_line = ''; - - &cp_parse_user_remove_bin_data( $in_file, "${in_file}_non_bin" ); -# my $INFILE = new IO::File("< ${in_file}") - my $INFILE = new IO::File("< ${in_file}_non_bin") - or die "cannot open file $in_file\n"; - my $OUTFILE = new IO::File("> $out_file") - or die "cannot open file $in_file\n"; - binmode($INFILE); - - while ( $line = <$INFILE> ) { - $orig_line = $line; - $line =~ s/\n/%EOL%/g; # preserve important non-printable chars - $line =~ s/\t/%TAB%/g; - if ( $line =~ /[^[:print:]]/ ) - { # replace all special characters with EOL - $line =~ s/[^[:print:]]+/%EOL%%EOL%/g; # zwei EOL, um eine leere Zeile zu erhalten - } - $line =~ s/%EOL%/\n/g; - $line =~ s/%TAB%/\t/g; - print $OUTFILE $line; - } - $INFILE->close; - $OUTFILE->close; - } - - my $in_file_main = shift; - my $fworch_workdir = shift; - my $debuglevel_main = shift; - my $line = ''; - my $name; - my $type; - my $color; - my $comments; - my $uid; - my $last_change_admin; - my $expdate; - my $user_def_type = 'simple'; - my $line_no = 0; - my $userparse_state = 0; # 0 = no user, 1 = in user definition, 2 = in group definition - my $debug_lines = ''; - my $debug = 0; - my $printable_usr_file = $in_file_main . '_printable'; - - &cp_parse_users_remove_nonprintable_chars( $in_file_main, $printable_usr_file ); - my $INFILE = new IO::File("< $printable_usr_file") or die "cannot open file $printable_usr_file\n"; - - while ( $line = <$INFILE> ) { - $line_no++; - if ( $line =~ /^([\w0-9\-_\s\.]+)\(\"?\1\"?$/ ) { # only take lines "username(username" as user definitions - $userparse_state = 1; # found start of user definition (username) - undef($type); undef($color); undef($uid); undef($comments); undef($last_change_admin); undef($expdate); - $name = $1; - if ($debug) { print ("$line_no: processing user $name\n"); } - } - if ( $userparse_state && ($name =~ /[0-9a-fA-F]{16}/ || $name =~ /[0-9a-fA-F]{24}/ || $name eq 'ALL_EXTUSRGROUPS' || $name eq 'ALL_TEMPLATES' || - $name eq 'ALL_GROUPS' || $name eq 'GROUPS_AND_EXTGROUPS' || $name eq 'ALL_KEYH' || $name eq 'Default' )) - { # no real user - $userparse_state = 0; undef($name); - } - if ( $userparse_state && $line =~ /^\)?$/ ) { # end of user def (empty lines as well as closing brackets) - if (defined($type) && defined($name) && $type ne 'rsacacertkey' && $type ne 'keyh' && $type ne 'template' ) - { # wenn Benutzer noch nicht existiert: anlegen - if ( !grep( /^${name}$/, @user_ar ) ) { - push @user_ar, $name; - if ($debug) { print (" $line_no: adding new user $name\n") } - } - $user{"$name.type"} = $type; - if ( defined($color) ) { $user{"$name.color"} = $color; } - if ( defined($comments) ) { $user{"$name.comments"} = $comments; } - $user{"$name.uid"} = $name; # nicht schoen, aber in den CP-Regeln sind fuer die User keine Uids!?, daher dient der Username als UID - if ( defined($last_change_admin) ) { $user{"$name.last_change_admin"} = $last_change_admin; } - if ( defined($expdate) ) { $user{"$name.expdate"} = $expdate; } - } - else { - if ($debug) { print ("undefined type; final line: $line; name: $name, type: $type.\n"); } - } - $userparse_state = 0; - } - if ( $userparse_state && ($line =~ /^\t\t:ClassName\s\(([\w0-9\-_\.]+?)\)/ || $line =~ /^\t:type \((\w+)\)$/ ) ) - { - if ($1 eq 'template' || $1 eq 'user_template') { # ignore all template users - $userparse_state = 0; - } - if (defined($type)) { - if ($debug) { print (" $line_no :: found type $1, but type already defined as $type, line: $line"); } - } else { - $type = $1; - if ($debug) { print (" $line_no :: found type $type, line: $line"); } - if ($type eq 'usrgroup' || $type eq 'extusrgroup' || $type eq 'external_group') - { $type = 'group'; } - else { $type = 'simple'; } - } - } - if ( $userparse_state) { $debug_lines .= $line_no . $line; } - if ( $userparse_state && $line =~ /^\t\t:chkpf_uid \("\{([\w0-9\-_\.]+?)\}"\)$/ ) { $uid = &gen_uid($1); } - if ( $userparse_state && $line =~ /^\t\t\t:By \(([\w0-9\-_\.]+)\)$/ ) { $last_change_admin = $1; } - if ( $userparse_state && $line =~ /^\t:Uid \("\{([\w0-9\-_\.]+?)\}"\)$/ ) { $uid = &gen_uid($1); } - -# usergroup processing - if ( $line =~ /:groups/ ) { # start of a group statement - if ($debug) { print (" start of group statement in $line_no, userparse_state = $userparse_state: $line"); } - } - if ( $userparse_state && $line =~ /^\t:groups \(\)$/ ) { # no group memberships - if ($debug) { print (" $line_no: user $name does not belong to any groups: $line"); } - } - if ( $userparse_state && $line =~ /^\t\:groups \($/ ) { - $userparse_state = 2; - if ($debug) { print (" $line_no: user $name belongs to groups: "); } - } - if ( $userparse_state == 2 && ($line =~ /^$/ || $line =~ /^\t\t\)$/) ) # || $line =~ /^\t\t:\s\(/ || $line =~ /^\t?\)/ )) - { # (premature) end of group-statement - $userparse_state = 1; - } - if ( $userparse_state == 2 && $line =~ /^\s+: \(([\w0-9\-_\.]+)$/ ) { - if ($debug) { print (" $line_no: entering cp_parse_users_add_member_to_group, line: $line"); } - &cp_parse_users_add_member_to_group( $1, $name, $debug ); - } - } - $INFILE->close; - if ($debug) { print $debug_lines; } - &cp_parse_users_add_groupmembers_final; -} - -sub cp_resolve_groups_with_exception { - sub is_group { - my $nwobj = shift; - if (defined ($network_objects{"$nwobj.type"})) { - return ($network_objects{"$nwobj.type"} eq 'group'); - } else { - print ("WARNING: type of $nwobj not defined\n"); - return 0; - } - } - sub is_non_empty_group { - my $nwobj = shift; - if (is_group($nwobj) && defined($network_objects{"$nwobj.members"}) && $network_objects{"$nwobj.members"} ne '') { - return 1; - } else { - return 0; - } - } - sub is_group_with_exclusion { - my $nwobj = shift; - return ($network_objects{"$nwobj.type"} eq 'group_with_exclusion'); - } - sub is_simple_ip { - my $obj_in = shift; - return ($network_objects{"$obj_in.type"} eq 'host' || $network_objects{"$obj_in.type"} eq 'gateway'); - } - sub is_network { - my $obj_in = shift; - return ($network_objects{"$obj_in.type"} eq 'network'); - } - sub is_ip_range { - my $obj_in = shift; - return ($network_objects{"$obj_in.type"} eq 'machines_range'); - } - sub to_cidr { - my $obj_in = shift; - my $obj; - if (is_network($obj_in)) { - $obj = Net::CIDR::addrandmask2cidr($network_objects{"$obj_in.ipaddr"}, $network_objects{"$obj_in.netmask"}); - } elsif (is_simple_ip($obj_in)) { - $obj = $network_objects{"$obj_in.ipaddr"} . "/32"; - } elsif (is_ip_range($obj_in)) { - $obj = $network_objects{"$obj_in.ipaddr"} . "-" . $network_objects{"$obj_in.ipaddr_last"} ; - } else { - print ("WARNING: $obj_in is neither network nor host nor range, but " . $network_objects{"$obj_in.type"}. " - empty?\n"); - if (defined($network_objects{"$obj_in.ipaddr"})) { - $obj = $network_objects{"$obj_in.ipaddr"} . "/32"; - } else { - undef $obj; - } - } - return $obj; - } - sub list_to_cidr { - my $obj_ar_in = shift; # ref to array - my @obj_ar_out = (); - - foreach my $obj (@{$obj_ar_in}) { - my $obj_out = &to_cidr($obj); - if (defined($obj_out)) { - @obj_ar_out = (@obj_ar_out, $obj_out); - } - } - return @obj_ar_out; - } - sub ip_overlaps_with_list { - my $obj1_in = shift; - my $obj_array_ref_in = shift; - - my $obj1 = &to_cidr($obj1_in); - my @cidr_array = (); - foreach my $obj (@{$obj_array_ref_in}) { - @cidr_array = (@cidr_array, &to_cidr($obj)); - } - my $result = &Net::CIDR::cidrlookup($obj1, @cidr_array); - return ($result); - } - sub ips_overlap { - my $obj1_in = shift; - my $obj2_in = shift; - - my $obj1 = &to_cidr($obj1_in); - my $obj2 = &to_cidr($obj2_in); - my $result = &Net::CIDR::cidrlookup($obj1, $obj2); - return ($result); - } - sub flatten { - my $group_in = shift; - if (defined($group_in) && defined($network_objects{"$group_in.members"}) && defined($network_objects{"$group_in.member_refs"})) { - my $member_string = $network_objects{"$group_in.members"}; - my $member_ref_string = $network_objects{"$group_in.member_refs"}; - my @member_ar = split (/[$GROUPSEP]/, $member_string); - my @member_ref_ar = split (/[$GROUPSEP]/, $member_ref_string); - my $i = 0; - while ($i < scalar @member_ar) { - my $m = $member_ar[$i]; - if (&is_non_empty_group ($m) && defined($m) && defined($GROUPSEP) && defined($network_objects{"$m.members"})) { - splice(@member_ar, $i, 1, split(/[$GROUPSEP]/, $network_objects{"$m.members"})); - $member_string = join ("$GROUPSEP", @member_ar); - splice(@member_ref_ar,$i,1, split(/[$GROUPSEP]/, $network_objects{"$m.member_refs"})); - $member_ref_string = join ("$GROUPSEP", @member_ref_ar); - } else { - $i++; - } - @member_ar = split (/[$GROUPSEP]/, $member_string); - @member_ref_ar = split (/[$GROUPSEP]/, $member_ref_string); - } - $network_objects{"$group_in.members"} = $member_string; - $network_objects{"$group_in.member_refs"} = $member_ref_string; - # print ("flatten_result: $member_string\n"); - } - return; - } - sub reduce_ip_by_one { - my $ip_in = shift; - my $result; - - if ($ip_in =~ /^0.0.0.0$/) { return undef; } - if ($ip_in =~ /^(\d+)\.(\d+)\.(\d+)\.(\d+)$/ ) { - if ($4 ne '0') { $result = "$1.$2.$3." . ($4-1); - } elsif ($3 ne '0') { $result = "$1.$2." . ($3-1) . ".255"; - } elsif ($2 ne '0') { $result = "$1." . ($2-1) . ".255.255"; - } else { $result = ($1-1) . ".255.255.255"; - } - return $result; - } else { - print ("WARNING: ip not well-formed: $ip_in\n"); - } - } - sub increase_ip_by_one { - my $ip_in = shift; - my $result; - - if ($ip_in =~ /^255.255.255.255$/) { return undef; } - if ($ip_in =~ /^(\d+)\.(\d+)\.(\d+)\.(\d+)$/ ) { - if ($4 ne '255') { $result = "$1.$2.$3." . ($4+1); - } elsif ($3 ne '255') { $result = "$1.$2." . ($3+1) . ".0"; - } elsif ($2 ne '255') { $result = "$1." . ($2+1) . ".0.0"; - } else { $result = ($1+1) . ".0.0.0"; - } - return $result; - } else { - print ("WARNING: ip not well-formed: $ip_in\n"); - } - } - sub pad_ip { # used only for correct sorting - my $ip = shift; - my $result; - if ($ip =~ /^(\d+)\.(\d+)\.(\d+)\.(\d+)$/ ) { - $result = sprintf("%03d.%03d.%03d.%03d", $1, $2, $3, $4); - } else { - print ("WARNING: ip not well-formed: $ip\n"); - return undef; - } - return $result; - } - sub calculate_non_overlapping_group { - my $pos_ip = shift; - my $neg_ip = shift; - my $group_name = shift; - - my ($pos_ip_range) = Net::CIDR::cidr2range($pos_ip); - my ($neg_ip_range) = Net::CIDR::cidr2range($neg_ip); - my ($pos_start, $pos_end) = split(/\-/, $pos_ip_range); - my ($neg_start, $neg_end) = split(/\-/, $neg_ip_range); - my @new_objs; - - if (&pad_ip($pos_start) lt &pad_ip($neg_start) && &pad_ip($pos_end) gt &pad_ip($neg_end)) { - # neg is fully contained in pos - # pos: 1.0.0.0-1.1.255.255, neg 1.1.2.3-1.1.2.3 - @new_objs = Net::CIDR::range2cidr(split(/,/, "$pos_start-" . - &reduce_ip_by_one($neg_start) . - "," . &increase_ip_by_one($neg_end) . "-" . $pos_end)); - } elsif (&pad_ip($neg_start) le &pad_ip($pos_start) && &pad_ip($neg_end) lt &pad_ip($pos_end)) { - # neg cuts off the beginning of pos - # pos: 1.6.0.0-1.7.255.255, neg 1.5.255.254-1.6.0.2 - @new_objs = Net::CIDR::range2cidr(&increase_ip_by_one($neg_end) . "-$pos_end"); - } elsif (&pad_ip($pos_start) lt &pad_ip($neg_start) && &pad_ip($neg_end) ge &pad_ip($pos_end)) { - # neg cuts off the end of pos --> pos = old_pos_start to start_of_neg - 1 - # pos: 1.6.0.0-1.7.255.255, neg 1.7.255.254-1.8.0.2 - @new_objs = Net::CIDR::range2cidr("$pos_start-" . &reduce_ip_by_one($neg_start)); - } else { - # neg fully contains pos --> result is empty, do nothing - @new_objs = (); - } - return join ("$GROUPSEP", @new_objs); - } - sub obj_is_created { - my $cidr_obj = shift; - - # currently we do not keep any original objects in pos group (assuming only object "any" in pos group anyway) - return 1; - } - sub create_new_obj { - my $new_obj = shift; - my $group_name = shift; - my $obj_name = "${group_name}_${new_obj}_isogrpexcl"; - my $obj_ref = "$obj_name.ref"; - - @network_objects = (@network_objects, $obj_name); - $network_objects{"$obj_name.name"} = $obj_name; - $network_objects{"$obj_name.UID"} = $obj_ref; - - if ($new_obj =~ /\// && $new_obj !~ /\/32$/ ) { # network - $network_objects{"$obj_name.type"} = 'network'; - $network_objects{"$obj_name.ipaddr"} = $new_obj; - } elsif ($new_obj =~ /^(\d+)\.(\d+)\.(\d+)\.(\d+)$/ || $new_obj =~ /\/32$/) { # simple host - $network_objects{"$obj_name.type"} = 'host'; - $network_objects{"$obj_name.ipaddr"} = $new_obj; - } elsif ($new_obj =~ /^(\d+)\.(\d+)\.(\d+)\.(\d+)-(\d+)\.(\d+)\.(\d+)\.(\d+)$/) { # range - $network_objects{"$obj_name.type"} = 'machines_range'; - print ("WARNING: $new_obj is range, but this should never occur.\n"); - } else { - print ("WARNING: $new_obj is neither network nor host nor range.\n"); - } - return ($obj_name, $obj_ref); - } - sub add_obj_to_group { - my $obj_name = shift; - my $obj_ref = shift; - my $group_name = shift; - - if (defined($network_objects{"$group_name.members"}) && $network_objects{"$group_name.members"} ne '') { - $network_objects{"$group_name.members"} .= "${GROUPSEP}$obj_name"; - $network_objects{"$group_name.member_refs"} .= "${GROUPSEP}$obj_ref"; - } else { - $network_objects{"$group_name.members"} = $obj_name; - $network_objects{"$group_name.member_refs"} = $obj_ref; - } - } - sub remove_obj_from_group { - my $obj_name = shift; - my $group_name = shift; - - my $idx = 0; - my @member_ar = split (/[$GROUPSEP]/, $network_objects{"$group_name.members"}); - my @member_ref_ar = split (/[$GROUPSEP]/, $network_objects{"$group_name.member_refs"}); - while ($idx < scalar (@member_ar)) { - if ($member_ar[$idx] eq $obj_name) { - splice (@member_ar, $idx, 1); - splice (@member_ref_ar, $idx, 1); - } - $idx++; - } - $network_objects{"$group_name.members"} = join ("$GROUPSEP", @member_ar); - $network_objects{"$group_name.member_refs"} = join ("$GROUPSEP", @member_ref_ar); - } - sub is_obj_the_any_obj { - my $obj_name_in = shift; - return (lc($network_objects{"$obj_name_in.name"}) eq 'any'); - } - - foreach my $nwobj ( @network_objects ) { - if (&is_group_with_exclusion($nwobj)) { -# print ("processing group_with_exclusion: $nwobj\n"); - my $members = $network_objects{"$nwobj.members"};; - - # remove pos_group from $nwobj and add its content instead - my ($positiv_gruppe, $negativ_gruppe, $pos_idx, $neg_idx, $pos_grp_ref, $neg_grp_ref); - my $idx = 0; - foreach my $member (split (/[$GROUPSEP]/, $network_objects{"$nwobj.members"})) { - if ($member =~ /^\{base\}(.+)$/) { $positiv_gruppe = $1; $pos_idx = $idx; } - if ($member =~ /^\{exception\}(.+)$/) { $negativ_gruppe = $1; $neg_idx = $idx; } - } - my @pos_member_list; - if (is_obj_the_any_obj($positiv_gruppe)) { - @pos_member_list = ("$positiv_gruppe"); - } else { - &flatten($positiv_gruppe); # flatten = untergruppen aufloesen - @pos_member_list = split (/[$GROUPSEP]/, $network_objects{"$positiv_gruppe.members"}); - } - &flatten($negativ_gruppe); - my @neg_member_list; - if (defined($negativ_gruppe) && defined($network_objects{"$negativ_gruppe.members"})) { - @neg_member_list = split (/[$GROUPSEP]/, $network_objects{"$negativ_gruppe.members"}); - } else { - @neg_member_list = (); - } - # convert all list members to cidr notation - @pos_member_list = &list_to_cidr(\@pos_member_list); - @neg_member_list = &list_to_cidr(\@neg_member_list); - - # ab hier ist @pos_member_list massgeblich (keine Veraenderung von $network_objects) - foreach my $negmember (@neg_member_list) { - if (&Net::CIDR::cidrlookup($negmember, @pos_member_list)) { # overlapping? - # am Ende dieses ifs wird die Liste @pos_member_list komplett neu definiert fuer den naechsten Schleifendurchlauf - my $i = 0; - while ($i < scalar @pos_member_list) { - my $posmember = $pos_member_list[$i]; - if (&Net::CIDR::cidrlookup ($negmember, $posmember)) { - my $new_obj_str = &calculate_non_overlapping_group ($posmember, $negmember); - my @new_objs = split (/[$GROUPSEP]/, $new_obj_str); - splice(@pos_member_list, $i, 1, @new_objs); - # for optimizing only: - $i += scalar @new_objs; - } else { - $i++; - } - } - } - } - # pos gruppe normieren/zusammenfassen/vereinfachen - my @new_non_redundant_objects = (); - foreach my $new_obj (@pos_member_list) { - @new_non_redundant_objects = Net::CIDR::cidradd($new_obj, @new_non_redundant_objects); - } - # jetzt werden die $network_objects wieder angefasst - # redefine members of group to empty group - $network_objects{"$nwobj.members"} = ''; - $network_objects{"$nwobj.member_refs"} = ''; - foreach my $obj (@new_non_redundant_objects) { - my ($obj_name, $obj_ref); - if (obj_is_created($obj)) { - ($obj_name, $obj_ref) = &create_new_obj ($obj, $nwobj); - } else { # -# ($obj_name, $obj_ref) = lookup_nwobj_data ($obj); - } - &add_obj_to_group ($obj_name, $obj_ref, $nwobj); - } - } - } - return; -} - -1; - -__END__ - -=head1 NAME - -CACTUS::FWORCH::parser - Perl extension for fworch check point parser - -=head1 SYNOPSIS - - use CACTUS::FWORCH::import::checkpoint; - -=head1 DESCRIPTION - -IT Security Organizer Perl Module -support for importing configs into fworch Database - -=head2 EXPORT - - global variables - -=head1 SEE ALSO - - behind the door - -=head1 AUTHOR - - Cactus eSecurity, tmp@cactus.de - -=cut diff --git a/roles/importer/files/importer/CACTUS/FWORCH/import/checkpointR8x.pm b/roles/importer/files/importer/CACTUS/FWORCH/import/checkpointR8x.pm deleted file mode 100644 index 05a632bea6..0000000000 --- a/roles/importer/files/importer/CACTUS/FWORCH/import/checkpointR8x.pm +++ /dev/null @@ -1,205 +0,0 @@ -package CACTUS::FWORCH::import::parser; - -use strict; -use warnings; -use IO::File; -use Getopt::Long; -use File::Basename; -use CACTUS::FWORCH; -use CACTUS::FWORCH::import; - -require Exporter; -our @ISA = qw(Exporter); - -our %EXPORT_TAGS = ( 'basic' => [ qw( ©_config_from_mgm_to_iso &parse_config ) ] ); - -our @EXPORT = ( @{ $EXPORT_TAGS{'basic'} } ); -our $VERSION = '0.3'; - -##################################################################################### -# Start Check Point Parser -##################################################################################### - -sub parse_config { - my $object_file = shift; - my $rulebase_file = shift; - my $user_db_file = shift; - my $rulebase_name = shift; - my $output_dir = shift; - my $verbose = shift; - my $mgm_name = shift; - my $config_dir = shift; - my $import_id = shift; - my $audit_log_file= shift; - my $prev_import_time= shift; - my $parse_full_audit_log = shift; - my $debug_level = shift; - my $result; - my $cmd; - my $return_code = 0; - # my $parser_py = "/usr/bin/python3 ./fworch_parse_config_cp_r8x_api.py"; - my $parser_py = "/usr/bin/python3 ./checkpointR8x/parse_config.py"; - my $users_csv = "$output_dir/${mgm_name}_users.csv"; - my $users_delimiter = "%"; # value is defined in parser_py = ./fworch_parse_config_cp_r8x_api.py !!! - - -# parsing rulebases - my $local_rulebase_names = get_local_ruleset_name_list($rulebase_name); - my $global_rulebase_names = get_global_ruleset_name_list($rulebase_name); - my @local_rulebase_name_ar = split /,/, $local_rulebase_names; - my @global_rulebase_name_ar = split /,/, $global_rulebase_names; - my $rulebase_with_slash; - my $rulebase_name_sanitized; - for (my $i=0; $i \"$output_dir/${rulebase_name_sanitized}_rulebase.csv\""; -# print("DEBUG - cmd = $cmd\n"); - $return_code = system($cmd); - if ( $return_code != 0 ) { print("ERROR in parse_config found: $return_code\n") } - - } -# foreach my $rulebase (@local_rulebase_name_ar) { -# my $rulebase_name_sanitized = join('__', split /\//, $rulebase); -# $cmd = "$parser_py -m $mgm_name -i $import_id -r \"$rulebase\" -f \"$object_file\" -d $debug_level > \"$output_dir/${rulebase_name_sanitized}_rulebase.csv\""; -# # print("DEBUG - cmd = $cmd\n"); -# $return_code = system($cmd); -# if ( $return_code != 0 ) { print("ERROR in parse_config found: $return_code\n") } -# } -# parsing users - $cmd = "$parser_py -m $mgm_name -i $import_id -u -f \"$object_file\" -d $debug_level > \"$output_dir/${mgm_name}_users.csv\""; -# print("DEBUG - cmd = $cmd\n"); - $return_code = system($cmd); - # system("ls -l $output_dir"); - if ( $return_code != 0 ) { print("ERROR in parse_config::users found: $return_code\n") } - - # in case of no users being returned, remove users_csv file - if (-r $users_csv) { - my $empty_flag = 0; - open FH, $users_csv; - my $firstline = ; - if (defined($firstline)) { - # print ("firstline=$firstline###\n"); - if(index($firstline,$users_delimiter)==-1) { - #print ("test: empty_flag=$empty_flag\n"); - $empty_flag = 1; - } - } - close FH; - if ($empty_flag == 1){ - # print ("unlinking users_csv file $users_csv\n"); - unlink $users_csv; - } - } - -# parsing svc objects - $cmd = "$parser_py -m $mgm_name -i $import_id -s -f \"$object_file\" -d $debug_level > \"$output_dir/${mgm_name}_services.csv\""; -# print("DEBUG - cmd = $cmd\n"); - $return_code = system($cmd); - if ( $return_code != 0 ) { print("ERROR in parse_config::services found: $return_code\n") } -# parsing nw objects - $cmd = "$parser_py -m $mgm_name -i $import_id -n -f \"$object_file\" -d $debug_level > \"$output_dir/${mgm_name}_netzobjekte.csv\""; -# print("DEBUG - cmd = $cmd\n"); - $return_code = system($cmd); - if ( $return_code != 0 ) { print("ERROR in parse_config::network_objects found: $return_code\n") } - return $return_code; -} - -############################################################ -# copy_config_from_mgm_to_iso($ssh_private_key, $ssh_user, $ssh_hostname, $management_name, $obj_file_base, $cfg_dir, $rule_file_base) -# Kopieren der Config-Daten vom Management-System zum ITSecorg-Server -############################################################ -sub copy_config_from_mgm_to_iso { - my $api_user = shift; - my $api_hostname = shift; - my $management_name = shift; # not used - my $obj_file_base = shift; - my $cfg_dir = shift; - my $layer_name = shift; - my $workdir = shift; - my $auditlog = shift; - my $prev_import_time= shift; - my $api_port = shift; - my $config_path_on_mgmt = shift; - my $rulebase_names_hash_ref = shift; - my $debug_level = shift; - my $return_code; - my $fehler_count = 0; - my $domain_setting = ""; - my $api_port_setting = ""; - my $ssl_verify = ""; - my $python_bin = "/usr/bin/python3"; - my $base_path = "/usr/local/fworch/importer"; - my $lib_path; - my $get_config_bin; - my $enrich_config_bin; - my $get_cmd; - my $enrich_cmd; - - my $rulebase_names = get_local_ruleset_name_list($rulebase_names_hash_ref); - if ( ${^CHILD_ERROR_NATIVE} ) { $fehler_count++; } - - if ( -r "$workdir/${CACTUS::FWORCH::ssh_id_basename}.pub" ) { - $ssl_verify = "-s $workdir/${CACTUS::FWORCH::ssh_id_basename}.pub"; - } - if (defined($config_path_on_mgmt) && $config_path_on_mgmt ne '') { - $domain_setting = "-D " . $config_path_on_mgmt; - } - if (defined($api_port) && $api_port ne '') { - $api_port_setting = "-p $api_port"; - } - - $lib_path = "$base_path/checkpointR8x"; - $get_config_bin = "$lib_path/get_basic_config.py"; - $enrich_config_bin = "$lib_path/enrich_config.py"; - $get_cmd = "$python_bin $get_config_bin -a $api_hostname -w '$workdir/$CACTUS::FWORCH::ssh_id_basename' -l '$rulebase_names' -u $api_user $api_port_setting $ssl_verify $domain_setting -o '$cfg_dir/$obj_file_base' -d $debug_level"; - $enrich_cmd = "$python_bin $enrich_config_bin -a $api_hostname -w '$workdir/$CACTUS::FWORCH::ssh_id_basename' -l '$rulebase_names' -u $api_user $api_port_setting $ssl_verify $domain_setting -c '$cfg_dir/$obj_file_base' -d $debug_level"; - - if ($debug_level>0) { - print("getting config with command: $get_cmd\n"); - } - $return_code = system($get_cmd); if ( $return_code != 0 ) { $fehler_count++; } - if ($debug_level>0) { - print("enriching config with command: $enrich_cmd\n"); - } - $return_code = system($enrich_cmd); if ( $return_code != 0 ) { $fehler_count++; } - return ( $fehler_count, "$cfg_dir/$obj_file_base,$cfg_dir/$layer_name"); -} - - -1; - -__END__ - -=head1 NAME - -parser - Perl extension for check point R8x API get and parse config - -=head1 SYNOPSIS - - use CACTUS::FWORCH::import::checkpointR8x; - -=head1 DESCRIPTION - -Perl Module support for importing configs into database - in this case only empty shell calling python code - -=head2 EXPORT - - global variables - -=head1 SEE ALSO - - behind the door - -=head1 AUTHOR - - Cactus eSecurity, tmp@cactus.de - -=cut diff --git a/roles/importer/files/importer/CACTUS/FWORCH/import/cisco.pm b/roles/importer/files/importer/CACTUS/FWORCH/import/cisco.pm deleted file mode 100644 index 6108adb867..0000000000 --- a/roles/importer/files/importer/CACTUS/FWORCH/import/cisco.pm +++ /dev/null @@ -1,983 +0,0 @@ -package CACTUS::FWORCH::import::parser; - -use strict; -use warnings; -use Time::HiRes qw(time); # fuer hundertstelsekundengenaue Messung der Ausfuehrdauer -use CACTUS::FWORCH; -use CACTUS::FWORCH::import; -use CACTUS::read_config; - -require Exporter; -our @ISA = qw(Exporter); - -our %EXPORT_TAGS = ( 'basic' => [ qw( ©_config_from_mgm_to_iso &parse_config ) ] ); - -our @EXPORT = ( @{ $EXPORT_TAGS{'basic'} } ); -our $VERSION = '0.3'; - -our @config_lines; # array der Zeilen des Config-Files im Originalzustand (kein d2u etc.) -our $parser_mode; # Typ des Config-Formates (basic, data) -our $rule_order = 0; # Reihenfolge der Rules im Configfile -our $rulebase_name; -our %junos_uuids = (); - -## parse_audit_log Funktion fuer ASA (noch) nicht implementiert -sub parse_audit_log { } - -##################################### -# add_nw_obj -# param1: obj_name -# param2: obj_ip (with netmask) -# param3: obj zone -# param4: debuglevel [0-?] -##################################### -sub add_nw_obj { - my $act_obj_name = shift; - my $act_obj_ipaddr = shift; - my $act_obj_mask = shift; - my $debuglevel = shift; - my $act_obj_ipaddr_last = ''; - my $act_obj_comm = ''; - my $act_obj_type = ''; - my $act_obj_loc = ''; - my $act_obj_color = 'black'; - my $act_obj_sys = ''; - my $act_obj_uid = ''; - - if (!defined($act_obj_mask) || $act_obj_mask eq '') { $act_obj_mask = "32"; } - elsif ($act_obj_mask =~ /\./) { $act_obj_mask = &calc_subnetmask($act_obj_mask); if ($act_obj_mask ne "32") { $act_obj_name = $act_obj_name . '_mask_' . $act_obj_mask; } } - # otherwise leave mask as is (assuming int between 0 and 32) - print_debug("add_nw_obj called with name=$act_obj_name, ip=$act_obj_ipaddr", $debuglevel, 5); - if (!defined ($network_objects{"$act_obj_name.name"})) { - @network_objects = (@network_objects, $act_obj_name); - $network_objects{"$act_obj_name.name"} = $act_obj_name; - $network_objects{"$act_obj_name.UID"} = $act_obj_name; - if ($act_obj_mask==32) { $network_objects{"$act_obj_name.type"} = 'host' }; - if ($act_obj_mask<32) { $network_objects{"$act_obj_name.type"} = 'network' }; - $network_objects{"$act_obj_name.netmask"} = $act_obj_mask ; - $network_objects{"$act_obj_name.ipaddr"} = $act_obj_ipaddr; - $network_objects{"$act_obj_name.ipaddr_last"} = $act_obj_ipaddr_last; - $network_objects{"$act_obj_name.color"} = $act_obj_color; - $network_objects{"$act_obj_name.comments"} = $act_obj_comm; - $network_objects{"$act_obj_name.location"} = $act_obj_loc; - $network_objects{"$act_obj_name.sys"} = $act_obj_sys; - } else { - print_debug ("found duplicate object definition for network object $act_obj_name", $debuglevel, 6); # no error with cisco configs - } -} - -##################################### -# add_nw_obj_group_member -# param1: input-line -# param2: debuglevel [0-?] -##################################### -sub add_nw_obj_group_member{ - my $group_name = shift; - my $member_name = shift; - my $debuglevel = shift; - - my $act_obj_name = ''; - my $act_obj_mbr = ''; - my $act_obj_fkt = ''; - my $act_obj_color = 'black'; - my $act_obj_comm = ''; - my $mbrlst = ''; - my $mbr_ref_lst = ''; - - if (!defined ($network_objects{"$group_name.name"})) { - @network_objects = (@network_objects, $group_name); - $network_objects{"$group_name.name"} = $group_name; - $network_objects{"$group_name.UID"} = $group_name; - print_debug ("added group $group_name", $debuglevel, 5); - $network_objects{"$group_name.type"} = 'group'; - $network_objects{"$group_name.color"} = $act_obj_color; - } -# die ("reference to undefined network object $member_name found in group $group_name, zone: $act_obj_zone"); - if (defined($network_objects{"$group_name.members"})) { - $mbrlst = $network_objects{"$group_name.members"}; - $mbr_ref_lst = $network_objects{"$group_name.member_refs"}; - } - if ( $mbrlst eq '' ) { - $mbrlst = $member_name; - $mbr_ref_lst = $member_name; - } - else { - $mbrlst = "$mbrlst|$member_name"; - $mbr_ref_lst = "$mbr_ref_lst|$member_name"; - } - $network_objects{"$group_name.members"} = $mbrlst; - $network_objects{"$group_name.member_refs"} = $mbr_ref_lst; - return; -} - -##################################### -# add_nw_service_obj -# param1: input-line -# param2: debuglevel [0-?] -##################################### -sub add_nw_service_obj { # ($application_name, $proto, $source_port, $destination_port, $uuid, $rpc, $icmp_art, $icmp_nummer, $debug_level_main) - my $act_obj_name = shift; - my $act_obj_proto = shift; - my $act_obj_src = shift; - my $act_obj_dst = shift; - my $act_obj_uid = shift; - my $act_obj_rpc = shift; - my $icmp_art = shift; - my $icmp_nummer = shift; - my $debuglevel = shift - my @range; - my $act_obj_typ = 'simple'; - my $act_obj_type = ''; - my $act_obj_src_last = ''; - my $act_obj_dst_last = ''; - my $act_obj_comm = ''; - my $act_obj_time = ''; - my $act_obj_time_std = ''; - my $act_obj_color = 'black'; - - if (!defined ($services{"$act_obj_name.name"})) { - @services = (@services, $act_obj_name); - $services{"$act_obj_name.name"} = $act_obj_name; - if (defined($act_obj_src)) { - @range = split ( /-/, $act_obj_src); - $services{"$act_obj_name.src_port"} = $range[0]; - if (defined($range[1])) { - $services{"$act_obj_name.src_port_last"} = $range[1]; - } else { - $services{"$act_obj_name.src_port_last"} = ''; - } - } - if (defined($act_obj_dst)) { - @range = split ( /-/, $act_obj_dst); - $services{"$act_obj_name.port"} = $range[0]; - if (defined($range[1])) { - $services{"$act_obj_name.port_last"} = $range[1]; - } else { - $services{"$act_obj_name.port_last"} = ''; - } - } - if (defined($act_obj_proto)) { - $services{"$act_obj_name.ip_proto"} = get_proto_number($act_obj_proto) - } else { - $services{"$act_obj_name.ip_proto"} = ''; - } - $services{"$act_obj_name.timeout"} = $act_obj_time; - $services{"$act_obj_name.color"} = $act_obj_color; - $services{"$act_obj_name.comments"} = $act_obj_comm; - $services{"$act_obj_name.typ"} = $act_obj_typ; - $services{"$act_obj_name.type"} = $act_obj_type; - if (defined($act_obj_rpc)) { - $services{"$act_obj_name.rpc_port"} = $act_obj_rpc; - } else { - $services{"$act_obj_name.rpc_port"} = ''; - } - $services{"$act_obj_name.UID"} = $act_obj_name; - if (defined($act_obj_uid) && $act_obj_uid ne '') { $junos_uuids{"$act_obj_uid"} = $act_obj_name; } # collect uid refs - print_debug("add_nw_service_obj: added application $act_obj_name", $debuglevel, 4); - } else { - print_debug("add_nw_service_obj: warning duplicate defintion of service $act_obj_name", $debuglevel, 1); - } - return; -} - -##################################### -# add_nw_service_obj_grp -# param1: input-line -# param2: debuglevel [0-?] -##################################### -sub add_nw_service_obj_grp { # ($application_name, $members, $members_proto, $members_uid, $debuglevel_main); - my $act_obj_name = shift; - my $act_obj_members = shift; - my $debuglevel = shift; - my $act_obj_typ = 'group'; - my $act_obj_type = ''; - my $act_obj_proto = ''; - my $act_obj_src_last = ''; - my $act_obj_dst_last = ''; - my $act_obj_comm = ''; - my $act_obj_time = ''; - my $act_obj_time_std = ''; - my $act_obj_color = 'black'; - my $act_obj_rpc = ''; - my $mbrlst = ''; - - if (!defined ($services{"$act_obj_name.name"})) { - @services = (@services, $act_obj_name); - $services{"$act_obj_name.name"} = $act_obj_name; - print_debug("adding service group $act_obj_name", $debuglevel, 5); - } else { - print_debug("re-defining service group $act_obj_name", $debuglevel, 5); - } - if (defined($act_obj_members) && $act_obj_members ne '') { - $services{"$act_obj_name.members"} = $act_obj_members; # simple group case - $services{"$act_obj_name.member_refs"} = $act_obj_members; # simple group case - print_debug("adding service group $act_obj_name with members $act_obj_members", $debuglevel, 5); - } else { - print_debug("no members defined", $debuglevel, 1); - } - $services{"$act_obj_name.ip_proto"} = $act_obj_proto; - $services{"$act_obj_name.timeout"} = $act_obj_time; - $services{"$act_obj_name.color"} = $act_obj_color; - $services{"$act_obj_name.comments"} = $act_obj_comm; - $services{"$act_obj_name.typ"} = $act_obj_typ; - $services{"$act_obj_name.type"} = $act_obj_type; - $services{"$act_obj_name.rpc_port"} = $act_obj_rpc; - $services{"$act_obj_name.UID"} = $act_obj_name; -} - -sub junos_split_list { # param1 = list of objects (network or service) - my $list = shift; - my $debug_level = shift; - my $orig_list = $list; - - if ($list =~ /^\[\s([\w\-\_\/\.\d\s]+?)\s\]$/) { # standard list format: [ x1 x2 x3 ] - $list = $1; - $list = join('|', split(/\s/, $list)); - } elsif ($list =~ /[\w\-\_\/\.\d]+/) { - # found single object, no changes necessary - } else { - print_debug("warning in junos_split_list: orig_list=$orig_list; found no match for object list", $debug_level, 1); - } -# print_debug("junos_split_list: orig_list=$orig_list, result=$list", $debug_level, 5); - return $list; -} - -##################################### -# add_rule -# param1: -# debuglevel [integer] -##################################### -sub add_rule { # ($rule_no, $from_zone, $to_zone, $policy_name, $disabled, $source, $destination, $application, $action, $track, $debuglevel_main) - my $rule_no = shift; - my $from_zone = shift; - my $to_zone = shift; - my $policy_name = shift; - my $disabled = shift; - my $source = shift; - my $destination = shift; - my $service = shift; - my $action = shift; - my $track = shift; - my $debuglevel = shift; - my $rule_id; - -# print_debug ("add_rule: rulebase_name=$rulebase_name, rulecount=" . $rulebases{"$rulebase_name.rulecount"}, $debuglevel, 4); - $rulebases{"$rulebase_name.rulecount"} = $rule_no + 1; # Anzahl der Regeln wird sukzessive hochgesetzt - $rule_id = "from_zone__$from_zone" . "__to_zone__$to_zone" . "__$policy_name"; - $ruleorder[$rule_no] = $rule_no; - - if (!defined($track) || $track eq '') { $track = 'none'; } - if (length($track)<3) { print_debug ("warning, short track: <$track>", $debuglevel, 1); } - - $rulebases{"$rulebase_name.$rule_no.src"} = ''; - foreach my $src (split(/\|/, &junos_split_list($source, $debuglevel))) { - if ($rulebases{"$rulebase_name.$rule_no.src"} ne '') { - $rulebases{"$rulebase_name.$rule_no.src"} .= '|'; - $rulebases{"$rulebase_name.$rule_no.src.refs"} .= '|'; - } - $rulebases{"$rulebase_name.$rule_no.src"} .= "$src"; - $rulebases{"$rulebase_name.$rule_no.src.refs"} .= ("$src" . "__zone__$from_zone"); - } - $rulebases{"$rulebase_name.$rule_no.dst"} = ''; - foreach my $dst (split(/\|/, &junos_split_list($destination, $debuglevel))) { - if ($rulebases{"$rulebase_name.$rule_no.dst"} ne '') { - $rulebases{"$rulebase_name.$rule_no.dst"} .= '|'; - $rulebases{"$rulebase_name.$rule_no.dst.refs"} .= '|'; - } - $rulebases{"$rulebase_name.$rule_no.dst"} .= "$dst"; - $rulebases{"$rulebase_name.$rule_no.dst.refs"} .= ("$dst" . "__zone__$to_zone"); - } - - $rulebases{"$rulebase_name.$rule_no.services"} = ''; - foreach my $svc (split(/\|/, &junos_split_list($service, $debuglevel))) { - if ($rulebases{"$rulebase_name.$rule_no.services"} ne '') { - $rulebases{"$rulebase_name.$rule_no.services"} .= '|'; - $rulebases{"$rulebase_name.$rule_no.services.refs"} .= '|'; - } - $rulebases{"$rulebase_name.$rule_no.services"} .= "$svc"; - $rulebases{"$rulebase_name.$rule_no.services.refs"} .= "$svc"; - } - - $rulebases{"$rulebase_name.$rule_no.id"} = $rule_id; - $rulebases{"$rulebase_name.$rule_no.ruleid"} = $rule_id; - $rulebases{"$rulebase_name.$rule_no.order"} = $rule_no; - if ($disabled eq 'inactive') { $rulebases{"$rulebase_name.$rule_no.disabled"} = '1'; } - else { $rulebases{"$rulebase_name.$rule_no.disabled"} = '0'; } - $rulebases{"$rulebase_name.$rule_no.src.zone"} = $from_zone; - $rulebases{"$rulebase_name.$rule_no.dst.zone"} = $to_zone; - $rulebases{"$rulebase_name.$rule_no.services.op"} = '0'; - $rulebases{"$rulebase_name.$rule_no.src.op"} = '0'; - $rulebases{"$rulebase_name.$rule_no.dst.op"} = '0'; - $rulebases{"$rulebase_name.$rule_no.action"} = $action; - $rulebases{"$rulebase_name.$rule_no.track"} = $track; - $rulebases{"$rulebase_name.$rule_no.install"} = ''; # set hostname verwenden ? - $rulebases{"$rulebase_name.$rule_no.name"} = ''; # kein Aequivalent zu CP rule_name - $rulebases{"$rulebase_name.$rule_no.time"} = ''; - $rulebases{"$rulebase_name.$rule_no.comments"} = $policy_name; - $rulebases{"$rulebase_name.$rule_no.UID"} = $rule_id; - $rulebases{"$rulebase_name.$rule_no.header_text"} = ''; - return $rule_no+1; -} - -############################################################ -# add_zone ($new_zone) -############################################################ -sub add_zone { - my $new_zone = shift; - my $debug = shift; - my $is_there = 0; - foreach my $elt (@zones) { if ($elt eq $new_zone) { $is_there = 1; last; } } - if (!$is_there) { push @zones, $new_zone; &print_debug("adding new zone: $new_zone", $debug, 1); } -} - -############################################################ -# object_address_add (name, ip, mask, zone, comment) -############################################################ -sub object_address_add { - my $act_obj_name = $_[0]; - my $act_obj_ipaddr = $_[1]; - my $act_obj_mask = $_[2]; - my $act_obj_zone = $_[3]; - my $act_obj_comm = $_[4]; - my @params; - my $act_obj_nameZ = ''; - my $act_obj_ipaddr_last = ''; - my $act_obj_type = 'simple'; - my $act_obj_loc = ''; - my $act_obj_color = 'black'; - my $act_obj_sys = ''; - my $act_obj_uid = ''; - - $act_obj_nameZ = "${act_obj_name}__zone__$act_obj_zone"; # Zone in Feldindex mit aufgenommen - if (!defined ($network_objects{"$act_obj_nameZ.name"})) { - @network_objects = (@network_objects, $act_obj_nameZ); - $network_objects{"$act_obj_nameZ.name"} = $act_obj_name; - } elsif (defined ($network_objects{"$act_obj_nameZ.name"})) { - print "sub ns_object_address NET_OBJECT: $act_obj_nameZ ist bereits definiert.\n"; - } else { - print "sub ns_object_address NET_OBJECT: $act_obj_nameZ ist undefiniert.\n"; - } - my $subnetbits = calc_subnetmask ($act_obj_mask); - if ($subnetbits==32) { $network_objects{"$act_obj_nameZ.type"} = 'host' }; - if ($subnetbits<32) { $network_objects{"$act_obj_nameZ.type"} = 'network' }; - $network_objects{"$act_obj_nameZ.netmask"} = $act_obj_mask ; - $network_objects{"$act_obj_nameZ.zone"} = $act_obj_zone; # neues Feld fuer Zone - $network_objects{"$act_obj_nameZ.ipaddr"} = $act_obj_ipaddr; - $network_objects{"$act_obj_nameZ.ipaddr_last"} = $act_obj_ipaddr_last; - $network_objects{"$act_obj_nameZ.color"} = $act_obj_color; - $network_objects{"$act_obj_nameZ.comments"} = $act_obj_comm; - $network_objects{"$act_obj_nameZ.location"} = $act_obj_loc; - $network_objects{"$act_obj_nameZ.sys"} = $act_obj_sys; - $network_objects{"$act_obj_nameZ.UID"} = $act_obj_nameZ; -} - -############################################################ -# read_predefined_services( -############################################################ -sub read_predefined_services { - my $device_type = shift; -# my $predefined_service_string = shift; - my $debug_level = shift; - my $predef_svc; - my ($svc_name,$ip_proto,$port,$port_end,$timeout,$comment,$typ,$group_members); - - $predef_svc = exec_pgsql_cmd_return_value ("SELECT dev_typ_predef_svc FROM stm_dev_typ WHERE dev_typ_id=$device_type"); - my @predef_svc = split /\n/, $predef_svc; - - &print_debug("inserting pre-defined services for junos: $predef_svc",$debug_level,8); - - foreach my $svc_line (@predef_svc) { - ($svc_name,$ip_proto,$port,$port_end,$timeout,$comment,$typ,$group_members) = split /;/, $svc_line; - $services{"$svc_name.name"} = $svc_name; - $services{"$svc_name.port"} = $port; - $services{"$svc_name.port_last"} = $port_end; - $services{"$svc_name.ip_proto"} = $ip_proto; - $services{"$svc_name.timeout"} = $timeout; - $services{"$svc_name.color"} = "black"; -# $services{"$svc_name.comments"} = "$predefined_service_string, $comment"; - $services{"$svc_name.comments"} = $comment; - $services{"$svc_name.typ"} = $typ; - $services{"$svc_name.type"} = ""; - $services{"$svc_name.rpc_port"} = ""; - $services{"$svc_name.UID"} = $svc_name; - $services{"$svc_name.members"} = $group_members; - $services{"$svc_name.member_refs"} = $group_members; - push @services, $svc_name; - } - return; -} - -sub resolve_service_uuid_references { # ($debuglevel_main); - my $debug = shift; - - foreach my $nw_svc (@services) { - &print_debug("resolve_service_uuid_references: checking service $nw_svc, typ=" . $services{"$nw_svc.typ"} . "type=" . $services{"$nw_svc.type"}, $debug, 5); - if ($services{"$nw_svc.typ"} eq 'group') { - &print_debug("resolve_service_uuid_references: checking service group $nw_svc", $debug, 5); - my @members = split (/\|/, $services{"$nw_svc.member_refs"}); - my $member_string = ''; - my $change_flag = 0; - foreach my $member (@members) { - &print_debug("resolve_service_uuid_references: checking member $member", $debug, 5); - if ($member =~ /^[a-f0-9]\-[a-f0-9]\-[a-f0-9]\-[a-f0-9]\-[a-f0-9]$/) { - my $old_member = $member; - $change_flag = 1; - $member = $junos_uuids{"$member"}; - &print_debug("resolve_service_uuid_references: replacing uuid $old_member with $member", $debug, 5); - } - if ($member_string ne '') { $member_string .= '|'; } - $member_string .= $member; - } - if ($change_flag) { - $services{"$nw_svc.members"} = $member_string; - $services{"$nw_svc.member_refs"} = $member_string; - } - } - } - return; -} - -############################################################ -# copy_config_from_mgm_to_iso($ssh_private_key, $ssh_user, $ssh_hostname, $management_name, -# $obj_file_base, $cfg_dir, $rule_file_base) -# Kopieren der Config-Daten vom Management-System zum ITSecorg-Server -############################################################ - -sub copy_config_from_mgm_to_iso { - my $ssh_user = shift; - my $ssh_hostname = shift; - my $management_name = shift; - my $obj_file_base = shift; - my $cfg_dir = shift; - my $rule_file_base = shift; - my $workdir = shift; - my $debug_level = shift; - my $cmd; - my $fehler_count = 0; - my $result; - - $cmd = "$scp_bin $scp_batch_mode_switch -i $workdir/$CACTUS::FWORCH::ssh_id_basename $ssh_user\@$ssh_hostname:asa_config $cfg_dir/$obj_file_base"; # dummy -# $cmd = "$ssh_bin -i $workdir/$CACTUS::FWORCH::ssh_id_basename $ssh_user\@$ssh_hostname show config > $cfg_dir/$obj_file_base"; # Cisco ASA - noch offen - if (system ($cmd)) { $fehler_count++; } - return ($fehler_count, "$cfg_dir/$obj_file_base" ); -} - -sub sort_rules_and_add_zone_headers { - my $anzahl_regeln; - my $count; - my $zone_string; - my @rule_zones = (); - - # Nachbereitung Regeln: Sortierung nach a) Zonen b) $ruleorder - if (!defined($rulebases{"$rulebase_name.rulecount"})) { - $anzahl_regeln = 0; - } else { - $anzahl_regeln = $rulebases{"$rulebase_name.rulecount"}; - } - for ($count=0; $count<$anzahl_regeln; $count++) { - $zone_string = $rulebases{"$rulebase_name.$ruleorder[$count].src.zone"}; - $zone_string .= " : "; - $zone_string .= $rulebases{"$rulebase_name.$ruleorder[$count].dst.zone"}; - push @rule_zones, $zone_string - } - my @idx = (); - my $item; - for (@rule_zones) { - ($item) = $_; - push @idx, $item; - } - - @ruleorder = @ruleorder[ sort { $idx[$a] cmp $idx[$b] } 0 .. $anzahl_regeln-1 ]; - @rule_zones = @rule_zones[ sort { $idx[$a] cmp $idx[$b] } 0 .. $anzahl_regeln-1 ]; - - # Nachbereitung Regeln: Header-Regeln vor Zonenwechsel einfuegen - my $new_zone_string; - my $old_zone_string = ""; - my $rule_header_count = 1; - my $rule_header_offset = &CACTUS::read_config::read_config('rule_header_offset') * 1; - my $new_rule_id; - for ($count = 0; $count < $anzahl_regeln; $count++) { - $new_zone_string = $rule_zones[$count]; - if ($new_zone_string ne $old_zone_string) { # insert header rule - $new_rule_id = $rule_header_offset+$rule_header_count++; - (my $src_zone, my $dst_zone) = split / : /, $new_zone_string; - splice(@ruleorder,$count,0,$new_rule_id); # fuegt neue Regel ein - splice(@rule_zones,$count,0,$new_zone_string); - $anzahl_regeln++; - $rulebases{"$rulebase_name.rulecount"} = $anzahl_regeln; - $rulebases{"$rulebase_name.$ruleorder[$count].id"} = $new_rule_id; - $rulebases{"$rulebase_name.$ruleorder[$count].header_text"} = $new_zone_string; - $rulebases{"$rulebase_name.$ruleorder[$count].UID"} = $new_rule_id; - $rulebases{"$rulebase_name.$ruleorder[$count].src"} = "any"; - $rulebases{"$rulebase_name.$ruleorder[$count].dst"} = "any"; - $rulebases{"$rulebase_name.$ruleorder[$count].services"} = "any"; - $rulebases{"$rulebase_name.$ruleorder[$count].action"} = "deny"; - $rulebases{"$rulebase_name.$ruleorder[$count].src.zone"} = $src_zone; - $rulebases{"$rulebase_name.$ruleorder[$count].dst.zone"} = $dst_zone; - $rulebases{"$rulebase_name.$ruleorder[$count].disabled"} = '0'; - $rulebases{"$rulebase_name.$ruleorder[$count].src.op"} = '0'; - $rulebases{"$rulebase_name.$ruleorder[$count].dst.op"} = '0'; - $rulebases{"$rulebase_name.$ruleorder[$count].services.op"} = '0'; - } - $old_zone_string = $new_zone_string; - } -} - -sub parse_mgm_name { # ($obj_file, $fworch_workdir, $debug_level, $mgm_name, $config_dir, $import_id) - my $in_file_main = shift; - my $fworch_workdir = shift; - my $debuglevel_main = shift; - my $mgm_name = shift; - my $config_dir = shift; - my $import_id = shift; - my $line = ''; - my $context = ''; - my @nodes= (); - - &print_debug("entering parse_mgm_name",$debuglevel_main,2); - NEW_LINE: foreach $line (@config_lines) { - chomp($line); - if ($line=~ /^hostname\s+(.+?)$/ && ($context eq '')) { - $mgm_name = $1; - @nodes = ($mgm_name, @nodes); - &print_debug("parse_mgm_name: found hostname: $mgm_name",$debuglevel_main,1); - $context = ''; - @rulebases = ($mgm_name); - $rulebase_name = $mgm_name; - &print_debug("parse_mgm_name: found hostname of single system: $mgm_name and setting rulebase_name to $mgm_name",$debuglevel_main,1); - return $mgm_name; - } - } - &print_debug("ERROR: end of parse_mgm_name: at end without match (mgm_name=$mgm_name)",$debuglevel_main,-1); -} - -sub extract_ip_addresses_from_string { - my $input_string = shift; - my $debug = shift; - my @list_of_ips = (); - my $network_part; - my $ip; - - print_debug("acl extract_ip_addresses_from_string entering with: input=$input_string", $debug, 4); - while ($input_string =~ /^.*?(h?o?s?t?)\s?(\d+\.\d+\.\d+\.\d+)(.*)$/) { # at least one explicit ip address included - my $rest = $6; - my $host = $1; - my $ip = $2; - if (defined($host) && $host ne '') { - @list_of_ips = (@list_of_ips, "$ip/32"); - } else { - if (defined($network_part)) { - @list_of_ips = (@list_of_ips, "$network_part/" . &calc_subnetmask($ip)); - undef($network_part); - } else { - $network_part = $ip; - } - } - $input_string = $rest; - } - return join(',', @list_of_ips); -} - -# result: ($application_name, $proto, $destination_port, $icmp_art) -sub extract_services_from_string { - my $input_string = shift; - my $debug = shift; - my @list_of_svcs = (); - my $svc; - my $proto; - my $destination_port; - my $icmp_art; - my $application_name; - - # cases: - # icmp object-group VPNConc 21.253.174.192 255.255.255.240 echo-reply - # udp object-group kraft_proxies any eq domain - # tcp host 82.122.108.51 host 46.162.37.17 eq 6614 - # esp any object-group VPNConc - - print_debug("acl extract_services_from_string entering with: input=$input_string", $debug, 4); - if ($input_string =~ /^.*?(tcp|udp)\s(.*?)\seq\s(.*)$/) { - $proto = $1; - $destination_port = $3; - $icmp_art = ''; - $application_name = "${proto}_$destination_port"; - @list_of_svcs = (@list_of_svcs, "$application_name/$proto/$destination_port/$icmp_art"); - } -=cut - # das funktioniert noch nicht, da der icmp type nicht trivial zu erkennen ist - if ($input_string =~ /^.*?(icmp)\s(.*?)\s([\w\-]+)$/) { - $proto = 'icmp'; - $destination_port = ''; - $icmp_art = $3; - $application_name = "${proto}_$icmp_art"; - @list_of_svcs = (@list_of_svcs, "$application_name/$proto/$destination_port/$icmp_art"); - } -=cut - return join(',', @list_of_svcs); -} - -# the following function does only parse simple objects without groups. Groups are parsed in a second run using function parse_config_group_objects -sub parse_config_base_objects { # ($obj_file, $fworch_workdir, $debug_level, $mgm_name, $config_dir, $import_id) - my $in_file_main = shift; - my $fworch_workdir = shift; - my $debug = shift; - my $mgm_name = shift; - my $config_dir = shift; - my $import_id = shift; - my ($zone, $address_group_name, $obj_name, $obj_ip, $group_member_name, $application_name, $group_name, $group_members, $proto, $icmp_art, $icmp_nummer, - $source_port, $destination_port, $uuid, $members, $members_uid, $members_proto, $rpc); - my $line = ''; - my $context = ''; - my @nodes= (); - my $obj_mask; - - &print_debug("entering parse_config_base_objects =======================================================",$debug,2); - NEW_LINE: foreach $line (@config_lines) { - chomp($line); - &print_debug("pcbo-line: $line", $debug, 9); -# parsing both nw nad svc objects - if ($line =~ /^access\-list\s.+?extended\s(permit|deny)\s(.+)$/ && ($context eq '' || $context eq 'network-object-group' || $context eq 'service-object-group' || $context eq 'acl-extended')) { - my $acl = $2; - $context = &switch_context($context, 'acl-extended', $debug); - print_debug("acl match part: $acl", $debug, 7); - foreach my $ip (split(/,/, &extract_ip_addresses_from_string($acl, $debug))) { - ($obj_ip, $obj_mask) = split (/\//, $ip); - $obj_name = $obj_ip; - print_debug("acl expl network definition: found network $obj_name (raw: $ip) with ip $obj_ip and mask $obj_mask", $debug, 7); - &add_nw_obj ($obj_name, $obj_ip, $obj_mask, $debug); - } - foreach my $svc (split(/,/, &extract_services_from_string($acl, $debug))) { - ($application_name, $proto, $destination_port, $icmp_art) = split (/\//, $svc); - print_debug("acl expl service definition: found name=$application_name, proto=$proto, dest_port=$destination_port,icmp_art=$icmp_art", $debug, 4); - &add_nw_service_obj ($application_name, $proto, $source_port, $destination_port, $uuid, $rpc, $icmp_art, $icmp_nummer, $debug); - undef($application_name); undef($source_port); undef($destination_port); undef($uuid); undef($rpc); undef($icmp_art); undef($icmp_nummer); - } - next NEW_LINE; - } -# parsing network objects - if ($line =~ /^object\-group\snetwork\s(.+?)$/ && ($context eq '' || $context eq 'network-object-group' || $context eq 'service-object-group')) { - $context = &switch_context($context, 'network-object-group', $debug); - next NEW_LINE; - } - if ($line=~ /^\s+network\-object\s(host\s)?([\d\.]+)\s?([\d\.]*)$/ && $context eq 'network-object-group') { - $obj_name = $2; - $obj_ip = $2; - $obj_mask = $3; - print_debug("found obj $obj_name with ip $obj_ip and mask $obj_mask", $debug, 4); - &add_nw_obj ($obj_name, $obj_ip, $obj_mask, $debug); - undef($obj_name); undef($obj_ip); undef($obj_mask); - next NEW_LINE; - } -# parsing network services - if ($line =~ /^object\-group\sservice\s(.+?)\s(.+?)$/ && ($context eq '' || $context eq 'network-object-group' || $context eq 'service-object-group')) { - $context = &switch_context($context, 'service-object-group', $debug); - $proto = $2; - next NEW_LINE; - } - if ($line =~ /^object\-group\sicmp\-type\s(.+?)$/ && ($context eq '' || $context eq 'network-object-group' || $context eq 'service-object-group')) { - $context = &switch_context($context, 'service-object-group', $debug); - $proto = 'icmp'; - next NEW_LINE; - } - if ($line=~ /^\s+port\-object\seq\s(.+?)$/ && $context eq 'service-object-group') { - print_debug("found svc proto $proto", $debug, 4); - $destination_port = $1; - $application_name = "${proto}_$destination_port"; - print_debug("found svc obj $application_name with destination port $destination_port", $debug, 4); - &add_nw_service_obj ($application_name, $proto, $source_port, $destination_port, $uuid, $rpc, $icmp_art, $icmp_nummer, $debug); - undef($application_name); undef($source_port); undef($destination_port); undef($uuid); undef($rpc); undef($icmp_art); undef($icmp_nummer); - # undef($proto); --> needed for following services in same group - next NEW_LINE; - } - if ($line=~ /^\s+icmp\-object\s(.+?)$/ && $context eq 'service-object-group') { - $icmp_art= $1; - print_debug("found icmp obj $icmp_art", $debug, 4); - $application_name = "${proto}_$icmp_art"; - print_debug("found svc icmp obj $application_name with type $icmp_art", $debug, 4); - &add_nw_service_obj ($application_name, $proto, $source_port, $destination_port, $uuid, $rpc, $icmp_art, $icmp_nummer, $debug); - undef($application_name); undef($source_port); undef($destination_port); undef($uuid); undef($rpc); undef($icmp_art); undef($icmp_nummer); - # undef($proto); --> needed for following services in same group - next NEW_LINE; - } - } - return 0; -} - -sub parse_config_group_objects { # ($obj_file, $fworch_workdir, $debug_level, $mgm_name, $config_dir, $import_id) - my $in_file_main = shift; - my $fworch_workdir = shift; - my $debug = shift; - my $mgm_name = shift; - my $config_dir = shift; - my $import_id = shift; - my ($zone, $address_group_name, $act_obj_mask, $obj_name, $obj_ip, $group_member_name, $application_name); - my ($comment, $proto, $icmp_art, $icmp_nummer, $source_port, $destination_port, $uuid, $members, $members_uid, $members_proto, $rpc, $service_group_name); - my $line = ''; - my $context = ''; - my @nodes= (); - - &print_debug("entering parse_config_group_objects =======================================================",$debug,2); - NEW_LINE: foreach $line (@config_lines) { - chomp($line); - &print_debug("pcgo-line: $line", $debug, 9); - if ($line =~ /^\s+description (.*)$/) { $comment = $1; } # general collection of description -# parsing network object groups - if ($line =~ /^object\-group\snetwork\s(.+?)$/ && ($context eq '' || $context eq 'network-object-group' || $context eq 'service-object-group')) { - $context = &switch_context($context, 'network-object-group', $debug); - $address_group_name = $1; - print_debug("found address group $address_group_name", $debug, 4); - next NEW_LINE; - } - if ($line=~ /^\s+network\-object\s(host\s)?([\d\.]+)\s?([\d\.]*)$/ && $context eq 'network-object-group') { - $group_member_name = $2; - $act_obj_mask = $3; - if (!defined($act_obj_mask) || $act_obj_mask eq '') { $act_obj_mask = "32"; } - else { $act_obj_mask = &calc_subnetmask($act_obj_mask); if ($act_obj_mask ne "32") { $group_member_name = $group_member_name . '_mask_' . $act_obj_mask; } } - print_debug("found address group member of group $address_group_name: $group_member_name", $debug, 4); - &add_nw_obj_group_member ($address_group_name, $group_member_name, $debug); - undef($group_member_name); - next NEW_LINE; - } -# parsing service groups - if ($line =~ /^object\-group\sservice\s(.+?)\s(.+?)$/ && ($context eq '' || $context eq 'network-object-group' || $context eq 'service-object-group')) { - $context = &switch_context($context, 'service-object-group', $debug); - $proto = $2; - $service_group_name = $1; - $members = ''; - next NEW_LINE; - } - if ($line=~ /^\s+port\-object\seq\s(.+?)$/ && $context eq 'service-object-group') { - $destination_port = $1; - $application_name = "${proto}_$destination_port"; - if ($members ne '') { $members .= '|'; } - $members .= "$application_name"; - print_debug("found application $application_name in service group $service_group_name", $debug, 6); - next NEW_LINE; - } - if ($line=~ /^\s+icmp\-object\s(.+?)$/ && $context eq 'service-object-group') { - $icmp_art= $1; - print_debug("found icmp obj $icmp_art", $debug, 4); - $application_name = "${proto}_$icmp_art"; - if ($members ne '') { $members .= '|'; } - $members .= "$application_name"; - print_debug("found application $application_name in service group $service_group_name", $debug, 6); - next NEW_LINE; - } - if ($context eq 'service-object-group' && $line =~ /^\w/) { - print_debug("adding service group $service_group_name", $debug, 6); - &add_nw_service_obj_grp ($service_group_name, $members, $comment, $debug); - undef($comment); - next NEW_LINE; - } - } - return 0; -} - -sub cfg_file_complete { # check auf Vollstaendigkeit des Config-Files: - my $debug_level = shift; - my $ln_cnt = $#config_lines; - my $cfg_file_complete = 1; - - while ($config_lines[$ln_cnt] =~ /^\s*$/ ) { $ln_cnt -- ; } # ignore empty lines at the end - if ($config_lines[$ln_cnt] !~ /^\:\send$/) { - $cfg_file_complete = 0; - print_debug ("ERROR: expected last line to contain either primary node info or top level curly bracket. Instead got: " . $config_lines[$ln_cnt], $debug_level, -1); - } - return $cfg_file_complete; -} - -sub switch_context { - my $old_level = shift; - my $new_level = shift; - my $debug_level = shift; - print_debug("switching context from $old_level to $new_level", $debug_level, 8); - return $new_level; -} - - sub parse_config_rules { # ($in_file_main, $fworch_workdir, $debuglevel_main, $mgm_name_in_config, $config_dir, $import_id) - my $in_file_main = shift; - my $fworch_workdir = shift; - my $debug = shift; - my $mgm_name = shift; - my $config_dir = shift; - my $import_id = shift; - my ($zone, $action, $source, $destination, $application, $from_zone, $to_zone, $policy_name, $disabled, $track); - my $line = ''; - my $context = ''; - my $rule_no = 0; - my $list; - my $list_typ; - - &print_debug("entering parse_config_rules =======================================================",$debug,2); - NEW_LINE: foreach $line (@config_lines) { - chomp($line); - &print_debug("pcr: $line", $debug, 9); -# rules start - if ($line =~ /^security\s\{$/ && $context eq '') { $context = &switch_context($context, 'security', $debug); next NEW_LINE; } - if ($line =~ /^\s+policies\s\{$/ && $context eq 'security') { $context = &switch_context($context, 'security/policies', $debug); next NEW_LINE; } - if ($line=~ /^\s+from\-zone\s(.+?)\sto\-zone\s(.+?)\s\{$/ && $context eq 'security/policies') { - $context = &switch_context($context, 'security/policies/zone', $debug); - $from_zone = $1; - $to_zone = $2; - &print_debug("entering policy from zone $from_zone to zone $to_zone",$debug,2); - next NEW_LINE; - } - if ($line=~ /^\s+(inactive)?\:?\s?policy\s(.+?)\s\{$/ && $context eq 'security/policies/zone') { - $disabled = $1; if (!defined($disabled)) { $disabled = ''; } - $policy_name = $2; - $context = &switch_context($context, 'security/policies/zone/policy', $debug); - &print_debug("entering policy $policy_name (zone $from_zone to $to_zone)",$debug,2); - next NEW_LINE; - } -# match part of rule - if ($line=~ /^\s+match\s\{$/ && $context eq 'security/policies/zone/policy') { $context = &switch_context($context, 'security/policies/zone/policy/match', $debug); next NEW_LINE; } - if ($line =~ /^\s+(source|destination)\-address\s(.+?)\;?$/ && $context eq 'security/policies/zone/policy/match') { - $list_typ = $1; - $list = $2; - if ($list_typ eq 'source') { $source = $list; } - if ($list_typ eq 'destination') { $destination = $list; } -# &print_debug("pcr: nw-list=$list", $debug, 9); - if ($list =~ /^\[/ && $list !~ /\]$/) { $context = &switch_context($context, "security/policies/zone/policy/match/$list_typ", $debug); } - next NEW_LINE; - } - if ($line =~ /^\s+application\s(.+?)\;?$/ && $context eq 'security/policies/zone/policy/match') { - $application = $1; -# &print_debug("pcr: appl-list=$application", $debug, 9); - if ($application =~ /^\[/ && $application !~ /\]$/) { $context = &switch_context($context, 'security/policies/zone/policy/match/application', $debug); } - next NEW_LINE; - } - if ($line=~ /^\s+\}$/ && $context eq 'security/policies/zone/policy/match') { $context = &switch_context($context, 'security/policies/zone/policy', $debug); next NEW_LINE; } -# dealing with multiple source, destination or application lines of rules - if ($context =~ /^security\/policies\/zone\/policy\/match\/(\w+)$/) { - $list_typ = $1; - my $multi_line; - if ($line =~ /\s*(.*?)\;?$/) { $multi_line = $1; } - if ($list_typ eq 'source') { $source .= " $multi_line"; } - if ($list_typ eq 'destination') { $destination.= " $multi_line"; } - if ($list_typ eq 'application') { $application .= " $multi_line"; } - if ($multi_line =~ /\]$/) { $context = &switch_context($context, "security/policies/zone/policy/match", $debug); undef($list_typ); undef($list); } # last line reached - next NEW_LINE; - } - -# action / track part of rule (then) - if ($line=~ /^\s+then\s\{$/ && $context eq 'security/policies/zone/policy') { $context = &switch_context($context, 'security/policies/zone/policy/action', $debug); next NEW_LINE; } - if ($line=~ /^\s+(permit|deny|reject)\;$/ && $context eq 'security/policies/zone/policy/action') { $action = $1; next NEW_LINE; } - if ($line=~ /^\s+(permit|deny|reject)\s\{$/ && $context eq 'security/policies/zone/policy/action') { - $action = $1; - $context = &switch_context($context, 'security/policies/zone/policy/action/action_parameter', $debug); - next NEW_LINE; - } # ignoring further action parameters - if ($line=~ /^\s+(log|count)\s\{$/ && $context eq 'security/policies/zone/policy/action') { - my $found_track = $1; - if ($track eq '') { $track = $1; } - elsif ($found_track eq 'count' && $track eq 'log') { $track = 'log count'; } - $context = &switch_context($context, 'security/policies/zone/policy/action/action_parameter', $debug); - next NEW_LINE; - } # ignoring further tracking parameters -=cut - track=log wird in diesem Fall nicht gefunden: - permit { - destination-address { - drop-untranslated; - } - } - log { - session-close; - } -=cut - if ($line=~ /^\s+.+?\{$/ && $context eq 'security/policies/zone/policy/action/action_parameter') { - $context = &switch_context($context, 'security/policies/zone/policy/action/action_parameter/null', $debug); - next NEW_LINE; - } -#closing sections - if ($line=~ /^\s+.+?\{$/ && $context eq 'security/policies/zone/policy/action/action_parameter/null') { - $context = &switch_context($context, 'security/policies/zone/policy/action/action_parameter', $debug); - next NEW_LINE; - } - if ($line=~ /^\s+\}$/ && $context eq 'security/policies/zone/policy/action/action_parameter') { $context = &switch_context($context, 'security/policies/zone/policy/action', $debug); next NEW_LINE; } - if ($line=~ /^\s+\}$/ && $context eq 'security/policies/zone/policy/action') { $context = &switch_context($context, 'security/policies/zone/policy', $debug); next NEW_LINE; } - if ($line=~ /^\s+\}$/ && $context eq 'security/policies/zone/policy') { - if (!defined($track)) { $track=''; } - &print_debug("found rule from $from_zone to $to_zone, name=$policy_name, disabled=$disabled: src=$source, dst=$destination, svc=$application, action=$action, track=$track",$debug,2); - # Regel wegschreiben - $rule_no = &add_rule ($rule_no, $from_zone, $to_zone, $policy_name, $disabled, $source, $destination, $application, $action, $track, $debug); - $context = &switch_context($context, 'security/policies/zone', $debug); - $track = ''; undef($policy_name); - next NEW_LINE; - } # end of rule - if ($line=~ /^\s+\}$/ && $context eq 'security/policies/zone') { $context = switch_context($context, 'security/policies', $debug); undef($from_zone); undef($to_zone); next NEW_LINE; } - if ($line=~ /^\s+\}$/ && $context eq 'security/policies') { $context = &switch_context($context, 'security', $debug); next NEW_LINE; } - if ($line=~ /^\}$/) { $context = &switch_context($context, '', $debug); next NEW_LINE; } - } - &sort_rules_and_add_zone_headers (); - $rulebases{"$rulebase_name.ruleorder"} = join(',', @ruleorder); - return 0; - } - -##################################################################################### -# MAIN - -sub parse_config { # ($obj_file, $rule_file, $rulebases, $user, $fworch_workdir, $debug_level, $mgm_name, $config_dir, $import_id) - my $in_file_main = shift; - shift; shift; shift; # $rule_file und $rulebases und $user nicht verwendet - my $fworch_workdir = shift; - my $debuglevel_main = shift; - my $mgm_name = shift; - my $config_dir = shift; - my $import_id = shift; - my $debug_level = shift; - - # initializing global variables: - @services = (); - @network_objects = (); - &print_debug ("in_file_main=$in_file_main, fworch_workdir=$fworch_workdir, debuglevel_main=$debuglevel_main, mgm_name=$mgm_name, config_dir=$config_dir, import_id=$import_id", $debuglevel_main, 6); - - open (IN, $in_file_main) || die "$in_file_main konnte nicht geoeffnet werden.\n"; - @config_lines = ; # sichern Config-array fuer spaetere Verwendung - close (IN); - - if (!&cfg_file_complete($debuglevel_main)) { return "incomplete-config-file-$mgm_name"; } - else { -# my $device_type=9; # ASA 8.x fest gesetzt # TODO move to config -# &read_predefined_services($device_type, $debuglevel_main); # schreibt die predefined services in @services und %services - my $mgm_name_in_config = &parse_mgm_name($in_file_main, $fworch_workdir, $debuglevel_main, $mgm_name, $config_dir, $import_id); - &parse_config_base_objects ($in_file_main, $fworch_workdir, $debuglevel_main, $mgm_name, $config_dir, $import_id); # zones, simple network and service objects - push @zones, "global"; # Global Zone immer hinzufuegen - foreach my $zone (@zones) { object_address_add("any", "0.0.0.0", "0.0.0.0", $zone, "any-obj for Zone added by fworch"); &print_debug(""); } # Any-Objekte fuer alle Zonen einfuegen - &parse_config_group_objects ($in_file_main, $fworch_workdir, $debuglevel_main, $mgm_name, $config_dir, $import_id); # groups are parsed in separate cycle to ensure that all base objects are complete -# &resolve_service_uuid_references ($debuglevel_main); - &parse_config_rules ($in_file_main, $fworch_workdir, $debuglevel_main, $mgm_name_in_config, $config_dir, $import_id); # finally parsing the rule base, ignoring the rulebase name in fworch config - - &print_results_files_objects($fworch_workdir, $mgm_name, $import_id); - &print_results_files_rules ($fworch_workdir, $mgm_name, $import_id); - &print_results_files_zones ($fworch_workdir, $mgm_name, $import_id); -# print_results_monitor('objects'); -# print_results_monitor('rules'); - } - return 0; -} - -1; -__END__ - -=head1 NAME - -CACTUS::FWORCH::parser - Perl extension for fworch cisco parser - -=head1 SYNOPSIS - - use CACTUS::FWORCH::import::cisco; - -=head1 DESCRIPTION - -fworch perl Module support for importing configs into fworch Database - -=head2 EXPORT - - global variables - -=head1 SEE ALSO - - behind the door - -=cut diff --git a/roles/importer/files/importer/CACTUS/FWORCH/import/fortinet.pm b/roles/importer/files/importer/CACTUS/FWORCH/import/fortinet.pm deleted file mode 100644 index e85a030b87..0000000000 --- a/roles/importer/files/importer/CACTUS/FWORCH/import/fortinet.pm +++ /dev/null @@ -1,1226 +0,0 @@ -package CACTUS::FWORCH::import::parser; - -use strict; -use warnings; -use Time::HiRes qw(time); # fuer hundertstelsekundengenaue Messung der Ausfuehrdauer -use CACTUS::FWORCH; -use CACTUS::FWORCH::import; -use CACTUS::read_config; - -require Exporter; -our @ISA = qw(Exporter); - -our %EXPORT_TAGS = ( 'basic' => [ qw( ©_config_from_mgm_to_iso &parse_config ) ] ); - -our @EXPORT = ( @{ $EXPORT_TAGS{'basic'} } ); -our $VERSION = '0.3'; - -our @config_lines; # array der Zeilen des Config-Files im Originalzustand (kein d2u etc.) -our $parser_mode; # Typ des Config-Formates (basic, data) -our $rule_order = 0; # Reihenfolge der Rules im Configfile -our $rulebase_name; - -##################################### -# add_nw_obj -# param1: obj_name -# param2: obj_ip (with netmask in form 1.2.3.0/24 or ::/0) -# param3: obj zone -# param4: debuglevel [0-?] -##################################### -sub add_nw_obj { - my $act_obj_name = shift; - my $obj_ip = shift; - my $obj_type = shift; - my $act_obj_zone = shift; - my $act_obj_comm = shift; - my $act_obj_ipaddr_last = shift; - my $uid_postfix = shift; - my $debuglevel = shift; - my $act_obj_nameZ = ''; - my $act_obj_ipaddr = ''; - my $act_obj_mask = ''; - my $act_obj_type = ''; - my $act_obj_loc = ''; - my $act_obj_color = 'black'; - my $act_obj_sys = ''; - my $act_obj_uid = ''; - my $ipv6 = 0; - - if (!defined($act_obj_ipaddr_last)) { $act_obj_ipaddr_last = ''; } - if (!defined($obj_type)) { $obj_type = ''; } - if (!defined($act_obj_comm)) { $act_obj_comm = ''; } - print_debug("add_nw_obj called with name=$act_obj_name, ip=$obj_ip, type=$obj_type, obj_ipaddr_last=$act_obj_ipaddr_last, zone=$act_obj_zone", $debuglevel, 4); -# if ($obj_type ne 'ip_range') { - ($act_obj_ipaddr, $act_obj_mask) = split (/\//, $obj_ip); - if ($obj_ip =~/\:/) { $ipv6 = 1; } - print_debug("split: ip=$act_obj_ipaddr, mask=$act_obj_mask", $debuglevel, 7); -# } - $act_obj_nameZ = "${act_obj_name}$uid_postfix"; # ipv6_uid_postfix in Feldindex mit aufgenommen, um kollidierende Namen zu verhindern - if (!defined ($network_objects{"$act_obj_nameZ.name"})) { - @network_objects = (@network_objects, $act_obj_nameZ); - $network_objects{"$act_obj_nameZ.name"} = $act_obj_name; - $network_objects{"$act_obj_nameZ.UID"} = $act_obj_nameZ; - if ($obj_type ne 'ip_range') { - if ((!$ipv6 && $act_obj_mask==32) || ($ipv6 && $act_obj_mask==128)) { $obj_type = 'host' } - else { $obj_type = 'network'; } - } - $network_objects{"$act_obj_nameZ.type"} = $obj_type; - $network_objects{"$act_obj_nameZ.netmask"} = $act_obj_mask ; - $network_objects{"$act_obj_nameZ.zone"} = $act_obj_zone; # neues Feld fuer Zone - $network_objects{"$act_obj_nameZ.ipaddr"} = $act_obj_ipaddr; - $network_objects{"$act_obj_nameZ.ipaddr_last"} = $act_obj_ipaddr_last; - $network_objects{"$act_obj_nameZ.color"} = $act_obj_color; - $network_objects{"$act_obj_nameZ.comments"} = $act_obj_comm; - $network_objects{"$act_obj_nameZ.location"} = $act_obj_loc; - $network_objects{"$act_obj_nameZ.sys"} = $act_obj_sys; - } else { - print_debug ("found duplicate object definition for network object $act_obj_name in zone $act_obj_zone", $debuglevel, -1); - } -} - - -##################################### -# add_nw_service_obj -# param1: input-line -# param2: debuglevel [0-?] -##################################### -sub add_nw_service_obj { # ($application_name, $proto, $source_port, $destination_port, $uuid, $rpc, $icmp_art, $icmp_nummer, $debug_level_main) - my $act_obj_name = shift; - my $act_obj_proto = shift; - my $act_obj_src = shift; - my $act_obj_dst = shift; - my $act_obj_uid = shift; - my $act_obj_rpc = shift; - my $icmp_art = shift; - my $icmp_nummer = shift; - my $comment = shift; - my $debuglevel = shift - my @range; - my $act_obj_typ = 'simple'; - my $act_obj_type = 'simple'; - my $act_obj_src_last = ''; - my $act_obj_dst_last = ''; - my $act_obj_time = ''; - my $act_obj_time_std = ''; - my $act_obj_color = 'black'; - - if (!defined ($services{"$act_obj_name.name"})) { - @services = (@services, $act_obj_name); - $services{"$act_obj_name.name"} = $act_obj_name; - if (defined($act_obj_src)) { - @range = split ( /-/, $act_obj_src); - $services{"$act_obj_name.src_port"} = $range[0]; - if (defined($range[1])) { - $services{"$act_obj_name.src_port_last"} = $range[1]; - } else { - $services{"$act_obj_name.src_port_last"} = ''; - } - } - if (defined($act_obj_dst)) { - @range = split ( /-/, $act_obj_dst); - $services{"$act_obj_name.port"} = $range[0]; - if (defined($range[1])) { - $services{"$act_obj_name.port_last"} = $range[1]; - } else { - $services{"$act_obj_name.port_last"} = ''; - } - } - if (defined($act_obj_proto)) { - $services{"$act_obj_name.ip_proto"} = get_proto_number($act_obj_proto) - } else { - # $services{"$act_obj_name.ip_proto"} = ''; - } - $services{"$act_obj_name.timeout"} = $act_obj_time; - $services{"$act_obj_name.color"} = $act_obj_color; - if (defined($comment) && $comment ne '') { $services{"$act_obj_name.comments"} = $comment; } else { $services{"$act_obj_name.comments"} = ''; } - $services{"$act_obj_name.typ"} = $act_obj_typ; - $services{"$act_obj_name.type"} = $act_obj_type; - if (defined($act_obj_rpc)) { - $services{"$act_obj_name.rpc_port"} = $act_obj_rpc; - } else { - $services{"$act_obj_name.rpc_port"} = ''; - } - $services{"$act_obj_name.UID"} = $act_obj_name; - print_debug("add_nw_service_obj: added application $act_obj_name", $debuglevel, 4); - } else { - print_debug("add_nw_service_obj: warning duplicate defintion of service $act_obj_name", $debuglevel, 1); - } - return; -} - -##################################### -# add_nw_obj_grp -# param1: input-line -# param2: debuglevel [0-?] -##################################### -sub add_nw_obj_grp { # ($obj_name, $members, $comment, $objgrp_uid, $debuglevel_main); - my $act_obj_name = shift; - my $act_obj_members = shift; - my $act_obj_zone = shift; - my $comment = shift; - my $uid = shift; - my $uid_postfix = shift; - my $debuglevel = shift; - my $act_obj_color = 'black'; - my $act_obj_nameZ; - my $members_refs_local = ''; - - print_debug("add_nw_obj_grp called with name=$act_obj_name", $debuglevel, 3); -# $act_obj_nameZ = "${act_obj_name}"; # CHANGE: Zone nicht in Feldindex aufgenommen - $act_obj_nameZ = "${act_obj_name}$uid_postfix"; # ipv6_uid_postfix in Feldindex mit aufgenommen, um kollidierende Namen zu verhindern - if (!defined ($network_objects{"$act_obj_nameZ.name"})) { - @network_objects = (@network_objects, $act_obj_nameZ); - $network_objects{"$act_obj_nameZ.name"} = $act_obj_name; -# if (defined($uid)) { -# $network_objects{"$act_obj_nameZ.UID"} = $uid . $uid_postfix; # $act_obj_nameZ; -# } else { - $network_objects{"$act_obj_nameZ.UID"} = $act_obj_nameZ; -# } - $network_objects{"$act_obj_nameZ.type"} = 'group'; - $network_objects{"$act_obj_nameZ.zone"} = $act_obj_zone; # neues Feld fuer Zone - $network_objects{"$act_obj_nameZ.color"} = $act_obj_color; - $network_objects{"$act_obj_nameZ.comments"} = $comment; - $network_objects{"$act_obj_nameZ.members"} = &fortinet_split_list($act_obj_members); - if ($uid_postfix ne '') { # only add ipv6 postfix for non-ipv4 objects - if ($act_obj_members =~ /^\"(.*?)\"$/) { # standard list format: "x1" "x2" "x3" - my @tmp_list = split(/\"\s\"/, $1); - foreach my $member_local (@tmp_list) { - $members_refs_local .= '"' . $member_local . $uid_postfix . '" '; - } - if ($members_refs_local =~ /^(.*?)\s$/) { $members_refs_local = $1; } - $network_objects{"$act_obj_nameZ.member_refs"} = &fortinet_split_list($members_refs_local); - } else { - print_debug ("add_nw_obj_grp::non-matching members format found $act_obj_name, members: $act_obj_members", $debuglevel, -1); - } - } else { - $network_objects{"$act_obj_nameZ.member_refs"} = &fortinet_split_list($act_obj_members); - } - } else { - print_debug ("found duplicate object definition for network object $act_obj_name in zone $act_obj_zone", $debuglevel, -1); - } -} - -##################################### -# add_nw_service_obj_grp -# param1: input-line -# param2: debuglevel [0-?] -##################################### -sub add_nw_service_obj_grp { # ($application_name, $members, $members_proto, $members_uid, $comment, $debuglevel_main); - my $act_obj_name = shift; - my $act_obj_members = shift; - my $comment = shift; - my $debuglevel = shift; - my $act_obj_typ = 'group'; - my $act_obj_type = 'group'; - my $act_obj_proto = ''; - my $act_obj_src_last = ''; - my $act_obj_dst_last = ''; - my $act_obj_time = ''; - my $act_obj_time_std = ''; - my $act_obj_color = 'black'; - my $act_obj_rpc = ''; - my $mbrlst = ''; - - @services = (@services, $act_obj_name); - $services{"$act_obj_name.name"} = $act_obj_name; - $services{"$act_obj_name.members"} = &fortinet_split_list($act_obj_members); - $services{"$act_obj_name.member_refs"} = &fortinet_split_list($act_obj_members); - print_debug("adding service group $act_obj_name with members $act_obj_members", $debuglevel, 6); - $services{"$act_obj_name.ip_proto"} = $act_obj_proto; - $services{"$act_obj_name.timeout"} = $act_obj_time; - $services{"$act_obj_name.color"} = $act_obj_color; - if (defined($comment) && $comment ne '') { $services{"$act_obj_name.comments"} = $comment; } else { $services{"$act_obj_name.comments"} = ''; } - $services{"$act_obj_name.typ"} = $act_obj_typ; - $services{"$act_obj_name.type"} = $act_obj_type; - $services{"$act_obj_name.rpc_port"} = $act_obj_rpc; - $services{"$act_obj_name.UID"} = $act_obj_name; -} - -sub fortinet_split_list { # param1 = list of objects (network or service) - my $list = shift; - my $debug_level = shift; - my $orig_list = $list; - - if ($list =~ /^\"(.*?)\"$/) { # standard list format: "x1" "x2" "x3" - $list = $1; - $list = join('|', split(/\"\s\"/, $list)); - } else { - print_debug("warning in fortinet_split_list: orig_list=$orig_list; found no match for object list", $debug_level, 1); - } -# print_debug("fortinet_split_list: orig_list=$orig_list, result=$list", $debug_level, 5); - return $list; -} - -##################################### -# add_rule -# param1: -# debuglevel [integer] -##################################### -sub add_rule { # ($rule_no, $from_zone, $to_zone, $policy_id, $disabled, $source, $destination, $application, $action, $track, $debuglevel_main) - my $rule_no = shift; - my $from_zone = shift; - my $to_zone = shift; - my $policy_id = shift; - my $disabled = shift; - my $source = shift; - my $destination = shift; - my $service = shift; - my $action = shift; - my $track = shift; - my $comment = shift; - my $policy_name = shift; - my $svc_neg = shift; - my $src_neg = shift; - my $dst_neg = shift; - my $uid_postfix = shift; - my $debuglevel = shift; - my $rule_id; - - -# print_debug ("add_rule: rulebase_name=$rulebase_name, rulecount=" . $rulebases{"$rulebase_name.rulecount"}, $debuglevel, 4); - $rulebases{"$rulebase_name.rulecount"} = $rule_no + 1; # Anzahl der Regeln wird sukzessive hochgesetzt -# $rule_id = "from_zone__$from_zone" . "__to_zone__$to_zone" . "__$rule_id"; - $ruleorder[$rule_no] = $rule_no; - - if (!defined($track) || $track eq '') { $track = 'none'; } - if (length($track)<3) { print_debug ("warning, short track: <$track>", $debuglevel, 1); } - - $rulebases{"$rulebase_name.$rule_no.src"} = ''; - foreach my $src (split(/\|/, &fortinet_split_list($source, $debuglevel))) { - if ($rulebases{"$rulebase_name.$rule_no.src"} ne '') { - $rulebases{"$rulebase_name.$rule_no.src"} .= '|'; - $rulebases{"$rulebase_name.$rule_no.src.refs"} .= '|'; - } - $rulebases{"$rulebase_name.$rule_no.src"} .= "$src"; -# $rulebases{"$rulebase_name.$rule_no.src.refs"} .= ("$src" . "__zone__$from_zone"); - $rulebases{"$rulebase_name.$rule_no.src.refs"} .= ("$src$uid_postfix"); # CHANGE - } - $rulebases{"$rulebase_name.$rule_no.dst"} = ''; - foreach my $dst (split(/\|/, &fortinet_split_list($destination, $debuglevel))) { - if ($rulebases{"$rulebase_name.$rule_no.dst"} ne '') { - $rulebases{"$rulebase_name.$rule_no.dst"} .= '|'; - $rulebases{"$rulebase_name.$rule_no.dst.refs"} .= '|'; - } - $rulebases{"$rulebase_name.$rule_no.dst"} .= "$dst"; -# $rulebases{"$rulebase_name.$rule_no.dst.refs"} .= ("$dst" . "__zone__$to_zone"); - $rulebases{"$rulebase_name.$rule_no.dst.refs"} .= ("$dst$uid_postfix"); # CHANGE - } - - $rulebases{"$rulebase_name.$rule_no.services"} = ''; - foreach my $svc (split(/\|/, &fortinet_split_list($service, $debuglevel))) { - if ($rulebases{"$rulebase_name.$rule_no.services"} ne '') { - $rulebases{"$rulebase_name.$rule_no.services"} .= '|'; - $rulebases{"$rulebase_name.$rule_no.services.refs"} .= '|'; - } - $rulebases{"$rulebase_name.$rule_no.services"} .= "$svc"; - $rulebases{"$rulebase_name.$rule_no.services.refs"} .= "$svc"; - } - - $rulebases{"$rulebase_name.$rule_no.id"} = $policy_id; - $rulebases{"$rulebase_name.$rule_no.ruleid"} = $policy_id; - $rulebases{"$rulebase_name.$rule_no.order"} = $rule_no; - if ($disabled eq 'inactive') { $rulebases{"$rulebase_name.$rule_no.disabled"} = '1'; } - else { $rulebases{"$rulebase_name.$rule_no.disabled"} = '0'; } - $rulebases{"$rulebase_name.$rule_no.src.zone"} = $from_zone; - $rulebases{"$rulebase_name.$rule_no.dst.zone"} = $to_zone; - $rulebases{"$rulebase_name.$rule_no.services.op"} = $svc_neg; - $rulebases{"$rulebase_name.$rule_no.src.op"} = $src_neg; - $rulebases{"$rulebase_name.$rule_no.dst.op"} = $dst_neg; - $rulebases{"$rulebase_name.$rule_no.action"} = $action; - $rulebases{"$rulebase_name.$rule_no.track"} = $track; - $rulebases{"$rulebase_name.$rule_no.install"} = ''; # set hostname verwenden ? - $rulebases{"$rulebase_name.$rule_no.name"} = $policy_name; - $rulebases{"$rulebase_name.$rule_no.time"} = ''; - if (defined($comment) && $comment ne '') { $rulebases{"$rulebase_name.$rule_no.comments"} = $comment; } - $rulebases{"$rulebase_name.$rule_no.UID"} = $policy_id; - $rulebases{"$rulebase_name.$rule_no.header_text"} = ''; - print_debug ("added_rule: rulebase_name=$rulebase_name, from_zone: " . $from_zone . ", to_zone: " . $to_zone, $debuglevel, 4); - return $rule_no+1; -} - -############################################################ -# add_zone ($new_zone) -############################################################ -sub add_zone { - my $new_zone = shift; - my $debug = shift; - my $is_there = 0; - foreach my $elt (@zones) { if ($elt eq $new_zone) { $is_there = 1; last; } } - if (!$is_there) { push @zones, $new_zone; &print_debug("adding new zone: $new_zone", $debug, 4); } -} - -############################################################ -# object_address_add (name, ip, mask, zone, comment) -############################################################ -sub object_address_add { - my $act_obj_name = $_[0]; - my $act_obj_ipaddr = $_[1]; - my $act_obj_mask = $_[2]; - my $act_obj_zone = $_[3]; - my $act_obj_comm = $_[4]; - my @params; - my $act_obj_nameZ = ''; - my $act_obj_ipaddr_last = ''; - my $act_obj_type = 'simple'; - my $act_obj_loc = ''; - my $act_obj_color = 'black'; - my $act_obj_sys = ''; - my $act_obj_uid = ''; - -# $act_obj_nameZ = "${act_obj_name}__zone__$act_obj_zone"; # Zone in Feldindex mit aufgenommen - $act_obj_nameZ = "${act_obj_name}"; # CHANGE Zone nicht in Feldindex aufgenommen - if (!defined ($network_objects{"$act_obj_nameZ.name"})) { - @network_objects = (@network_objects, $act_obj_nameZ); - $network_objects{"$act_obj_nameZ.name"} = $act_obj_name; - } elsif (defined ($network_objects{"$act_obj_nameZ.name"})) { - print "sub ns_object_address NET_OBJECT: $act_obj_nameZ ist bereits definiert.\n"; - } else { - print "sub ns_object_address NET_OBJECT: $act_obj_nameZ ist undefiniert.\n"; - } - my $subnetbits = &calc_subnetmask ($act_obj_mask); - if ($subnetbits==32) { $network_objects{"$act_obj_nameZ.type"} = 'host' }; - if ($subnetbits<32) { $network_objects{"$act_obj_nameZ.type"} = 'network' }; - $network_objects{"$act_obj_nameZ.netmask"} = $act_obj_mask ; - $network_objects{"$act_obj_nameZ.zone"} = $act_obj_zone; # neues Feld fuer Zone - $network_objects{"$act_obj_nameZ.ipaddr"} = $act_obj_ipaddr; - $network_objects{"$act_obj_nameZ.ipaddr_last"} = $act_obj_ipaddr_last; - $network_objects{"$act_obj_nameZ.color"} = $act_obj_color; - $network_objects{"$act_obj_nameZ.comments"} = $act_obj_comm; - $network_objects{"$act_obj_nameZ.location"} = $act_obj_loc; - $network_objects{"$act_obj_nameZ.sys"} = $act_obj_sys; - $network_objects{"$act_obj_nameZ.UID"} = $act_obj_nameZ; -} - -############################################################ -# copy_config_from_mgm_to_iso($ssh_private_key, $ssh_user, $ssh_hostname, $management_name, -# $obj_file_base, $cfg_dir, $rule_file_base) -# Kopieren der Config-Daten vom Management-System zum ITSecorg-Server -############################################################ - - -sub copy_config_from_mgm_to_iso { - my $ssh_user = shift; - my $ssh_hostname = shift; - my $management_name = shift; # not used - my $obj_file_base = shift; - my $cfg_dir = shift; - my $rule_file_base = shift; - my $workdir = shift; - my $auditlog = shift; - my $prev_import_time= shift; - my $ssh_port = shift; - my $config_path_on_mgmt = shift; - my $debug_level = shift; - my $cmd; - my $fehler_count = 0; - my $result; - - if ($config_path_on_mgmt ne '') { # not a real fortigate but a standard ssh server - $cmd = "$scp_bin $scp_batch_mode_switch -i $workdir/${CACTUS::FWORCH::ssh_id_basename} $ssh_user\@$ssh_hostname:$config_path_on_mgmt/fortigate.cfg $cfg_dir/$obj_file_base"; - } else { # standard fortigate - $cmd = "$ssh_bin -o StrictHostKeyChecking=no -i $workdir/${CACTUS::FWORCH::ssh_id_basename} $ssh_user\@$ssh_hostname show full-configuration > $cfg_dir/$obj_file_base"; # fortigate - # adding "-o StrictHostKeyChecking=no" to allow for failover of fortinet machines: - } - #print_debug("copy_config_from_mgm_to_iso cmd=$cmd", $debuglevel, 4); - if (system ($cmd)) { $fehler_count++; } - return ($fehler_count, "$cfg_dir/$obj_file_base" ); -} - -sub sort_rules_and_add_zone_headers { - my $debug = shift; - my $anzahl_regeln; - my $count; - my $zone_string; - my @rule_zones = (); - - # Nachbereitung Regeln: Sortierung nach a) Zonen b) $ruleorder - if (!defined($rulebases{"$rulebase_name.rulecount"})) { - $anzahl_regeln = 0; - } else { - $anzahl_regeln = $rulebases{"$rulebase_name.rulecount"}; - } - for ($count=0; $count<$anzahl_regeln; $count++) { - $zone_string = $rulebases{"$rulebase_name.$ruleorder[$count].src.zone"}; - $zone_string .= " : "; - $zone_string .= $rulebases{"$rulebase_name.$ruleorder[$count].dst.zone"}; - push @rule_zones, $zone_string - } - my @idx = (); - my $item; - for (@rule_zones) { - ($item) = $_; - push @idx, $item; - } - - @ruleorder = @ruleorder[ sort { $idx[$a] cmp $idx[$b] } 0 .. $anzahl_regeln-1 ]; - @rule_zones = @rule_zones[ sort { $idx[$a] cmp $idx[$b] } 0 .. $anzahl_regeln-1 ]; - - # Nachbereitung Regeln: Header-Regeln vor Zonenwechsel einfuegen - my $new_zone_string; - my $old_zone_string = ""; - my $rule_header_count = 1; - my $rule_header_offset = &CACTUS::read_config::read_config('rule_header_offset') * 1; - my $new_rule_id; - for ($count = 0; $count < $anzahl_regeln; $count++) { - $new_zone_string = $rule_zones[$count]; - if ($new_zone_string ne $old_zone_string) { # insert header rule - $new_rule_id = $rule_header_offset+$rule_header_count++; - (my $src_zone, my $dst_zone) = split (/ : /, $new_zone_string); - splice(@ruleorder,$count,0,$new_rule_id); # fuegt neue Regel ein - splice(@rule_zones,$count,0,$new_zone_string); - $anzahl_regeln++; - $rulebases{"$rulebase_name.rulecount"} = $anzahl_regeln; - $rulebases{"$rulebase_name.$ruleorder[$count].id"} = $new_rule_id; - $rulebases{"$rulebase_name.$ruleorder[$count].header_text"} = $new_zone_string; - $rulebases{"$rulebase_name.$ruleorder[$count].UID"} = $new_rule_id; - $rulebases{"$rulebase_name.$ruleorder[$count].src"} = "all"; - $rulebases{"$rulebase_name.$ruleorder[$count].src.refs"} = "all"; - $rulebases{"$rulebase_name.$ruleorder[$count].dst"} = "all"; - $rulebases{"$rulebase_name.$ruleorder[$count].dst.refs"} = "all"; - $rulebases{"$rulebase_name.$ruleorder[$count].services"} = "all"; - $rulebases{"$rulebase_name.$ruleorder[$count].action"} = "deny"; - $rulebases{"$rulebase_name.$ruleorder[$count].src.zone"} = $src_zone; - $rulebases{"$rulebase_name.$ruleorder[$count].dst.zone"} = $dst_zone; - $rulebases{"$rulebase_name.$ruleorder[$count].disabled"} = '0'; - $rulebases{"$rulebase_name.$ruleorder[$count].src.op"} = '0'; - $rulebases{"$rulebase_name.$ruleorder[$count].dst.op"} = '0'; - $rulebases{"$rulebase_name.$ruleorder[$count].services.op"} = '0'; - } - $old_zone_string = $new_zone_string; - } -=cut - # moving any:any section down to the end - my $destination_rule_no; - for ($count = $anzahl_regeln-1; $count >= 0; $count--) { - if ($rule_zones[$count] eq 'any : any') { # cut rule within any:any section and paste at the end - - $destination_rule_no = $anzahl_regeln-1; - - # this is the header rule to be moved to the top of the any:any section: - while ($rule_zones[$destination_rule_no] eq 'any : any' && $rulebases{"$rulebase_name.$ruleorder[$count].header_text"} ne '') { - $destination_rule_no--; - } - - # this is a deny rule (and no section header) to be moved to the bottom of the any:any section: - if ($rulebases{"$rulebase_name.$ruleorder[$count].action"} eq 'deny' && $rulebases{"$rulebase_name.$ruleorder[$count].header_text"} eq '') { - $destination_rule_no = $anzahl_regeln-1; - } - - # make sure that standard any:any rules are inserted before deny rules - while ($rule_zones[$destination_rule_no] eq 'any : any' && $rulebases{"$rulebase_name.$ruleorder[$destination_rule_no].action"} eq 'deny' && - $rulebases{"$rulebase_name.$ruleorder[$count].action"} ne 'deny' && - $rulebases{"$rulebase_name.$ruleorder[$count].header_text"} eq '') { - $destination_rule_no--; - } - - if ($count ne $destination_rule_no) { # avoid moving on the same spot - &print_debug("moving any : any rule with id " . $rulebases{"$rulebase_name.$ruleorder[$count].id"} . - " from pos $count to pos $destination_rule_no", $debug, 2); - splice( @ruleorder, $destination_rule_no, 0, splice( @ruleorder, $count, 1 ) ); - splice( @rule_zones, $destination_rule_no, 0, splice( @rule_zones, $count, 1 ) ); - } - } - } -=cut - # moving any:any section down to the end - my ($destination_rule_no, $first_any_rule, $last_any_rule, $number_of_any_rules); - for ($count=0; $count<$anzahl_regeln; $count++) { - if (!defined($first_any_rule) && $rule_zones[$count] eq 'any : any') { $first_any_rule = $count; } - if (defined($first_any_rule) && !defined($last_any_rule) && $rule_zones[$count] ne 'any : any') { $last_any_rule = $count-1; } - } - if (defined($first_any_rule) && !defined($last_any_rule)) { $last_any_rule = $number_of_any_rules-1; } - if (defined($first_any_rule)) { # only move any:any rules if they exist - $number_of_any_rules = $last_any_rule - $first_any_rule + 1; - $destination_rule_no = $anzahl_regeln-$number_of_any_rules; - &print_debug("moving any:any rules from pos $first_any_rule to pos $last_any_rule to the bottom ($destination_rule_no)", $debug, 2); - splice( @ruleorder, $destination_rule_no, 0, splice( @ruleorder, $first_any_rule, $number_of_any_rules ) ); - splice( @rule_zones, $destination_rule_no, 0, splice( @rule_zones, $first_any_rule, $number_of_any_rules ) ); - } -} - -sub parse_mgm_name { # params: $debug_level - # since fortiOS 5.6 the hostname is not part of the config?! - my $debuglevel_main = shift; - my $mgm_name = ''; - my $line = ''; - my $context = ''; - my @nodes= (); - - &print_debug("entering parse_mgm_name",$debuglevel_main,2); - NEW_LINE: foreach $line (@config_lines) { - chomp($line); - print_debug("parse_mgm_name::parsing line $line", $debuglevel_main, 9); -# parsing device name(s) --- set hostname "xxxx" - if ($line =~ /^config\ssystem\sglobal/ && $context eq '') { $context = "system global"; &print_debug("found system line: $line",$debuglevel_main,5); next NEW_LINE; } - if ($line=~ /^\s+set\s+hostname\s+\"(.+?)\"$/ && ($context eq 'system global')) { - $mgm_name = $1; - @nodes = ($mgm_name, @nodes); - &print_debug("parse_mgm_name: found hostname: $mgm_name",$debuglevel_main,1); - next NEW_LINE; - } - if ($line=~ /^end$/ && $context eq 'system global') { - $context = ''; - return $mgm_name; - } - } - &print_debug("ERROR: end of parse_mgm_name: at end without match (mgm_name=$mgm_name)",$debuglevel_main,-1); - return 0; -} - -sub parse_vdom_names { # ($debug_level) - my $debuglevel_main = shift; - my $line = ''; - my $context = ''; - my @vdom= (); - - &print_debug("entering parse_vdom_names",$debuglevel_main,2); - NEW_LINE: foreach $line (@config_lines) { - chomp($line); - print_debug("parse_vdom_names::parsing line $line", $debuglevel_main, 9); - if ($line=~ /^config\svdom$/ && $context eq '') { $context = 'vdom'; next NEW_LINE; } - if ($line=~ /^edit\s(.+?)$/ && $context eq 'vdom') { @vdom = (@vdom, $1); next NEW_LINE; } - if ($line=~ /^end$/ && $context eq 'vdom') { $context = ''; return join(',', @vdom); } - } - &print_debug("end of parse_vdom_names: at end without any vdom match",$debuglevel_main,2); - return ''; -} - -# the following function does only parse simple objects without groups. Groups are parsed in a second run using function parse_config_group_objects -sub parse_config_base_objects { # ($debug_level, $mgm_name) - sub transform_port_list_to_artificial_services { - # params: ($destination_port, $proto, $application_name, $source_port, $uuid, $rpc, $icmp_art, $icmp_nummer, $comment, $debug) - my $destination_port = shift; - my $proto = shift; - my $application_name = shift; - my $source_port = shift; - my $uuid = shift; - my $rpc = shift; - my $icmp_art = shift; - my $icmp_nummer = shift; - my $comment = shift; - my $debug = shift; - my $members = ''; - - foreach my $current_port (split (/\s/, $destination_port)) { - if ($current_port =~ /^(.+?)\:(.+?)$/) { # handle case: set tcp-portrange 0-65535:0-65535 - $current_port = $1; - $source_port = $2; - } - my $member = "${application_name}_FWORCH-multiGRP-${current_port}_$proto"; - $members .= '"' . $member . '" '; - print_debug("adding arty service ${application_name}::$member with dst-port $current_port", $debug, 7); - &add_nw_service_obj ($member, $proto, $source_port, $current_port, $uuid, $rpc, $icmp_art, $icmp_nummer, $comment, $debug); - } - $members =~ s/\s$//; # remove trailing blank - return $members - } - - my $debug = shift; - my $mgm_name = shift; - my ($zone, $address_group_name, $obj_type, $obj_name, $obj_ip, $obj_ip_last, $obj_netmask, $group_member_name, $application_name, $group_name, $group_members, $proto, $icmp_art, $icmp_nummer, - $source_port, $destination_port, $uuid, $members, $members_uid, $members_proto, $rpc, $comment, $uid_postfix); - my $line = ''; - my $context = ''; - my @nodes= (); - my $v6flag = 0; - - &print_debug("entering parse_config_base_objects =======================================================",$debug,2); - NEW_LINE: foreach $line (@config_lines) { - chomp($line); - &print_debug("pcbo-line: $line", $debug, 9); - if ($line =~ /^end$/ && ($context eq 'firewall address' || $context eq 'firewall addrgrp' || $context eq 'firewall vip')) { - &print_debug("switching back to top level, resetting uid_postfix", $debug, 6); - $context = &switch_context($context, '', $debug); $v6flag = 0; $uid_postfix = ''; next NEW_LINE; - } - if ($line =~ /^config firewall (multicast\-)?address(6?)$/ && $context eq '') { - my $mc = $1; - my $v6 = $2; - $v6flag = 0; $uid_postfix = ''; - if (defined($mc) && $mc eq 'multicast-') { $uid_postfix = '.multicast.uid'; } - if (defined($v6) && $v6 eq '6') { - $v6flag = 1; - if ($uid_postfix eq '.multicast.uid') { $uid_postfix = '.multicast.ipv6.uid'; } else { $uid_postfix = '.ipv6.uid'; } - } - &print_debug("switching to firewall address, uid_postfix=$uid_postfix", $debug, 6); - $context = &switch_context($context, 'firewall address', $debug); - next NEW_LINE; - } - if ($line =~ /^config firewall addrgrp(6?)$/ && $context eq '') { - if (defined($1) && $1 eq '6') { $v6flag = 1; $uid_postfix = ".ipv6.uid"; } else { $v6flag = 0; $uid_postfix = ''; } - &print_debug("switching to firewall addrgrp, v6_uid_postfix=$uid_postfix", $debug, 6); - $context = &switch_context($context, 'firewall addrgrp', $debug); - next NEW_LINE; - } - if ($line =~ /^\s+edit\s\"(.+)"$/ && ($context eq 'firewall address' || $context eq 'firewall addrgrp')) { - $obj_name = $1; - print_debug("found object name $obj_name", $debug, 6); - $context = &switch_context($context, $context . ' single object', $debug); - next NEW_LINE; - } - if ($line =~ /^\s+next$/ && $context eq 'firewall address single object') { - if (!defined($zone)) { $zone = 'global'; } - if (!defined($obj_ip)) { - if ($v6flag==1) { - $obj_ip = '::'; $obj_netmask = '0'; - } else { - $obj_ip = '0.0.0.0'; $obj_netmask = '0.0.0.0'; - } - } - if (!defined($obj_ip_last)) { $obj_ip_last = ''; } - if (!defined($obj_type)) { $obj_type = ''; } - if ($obj_type eq 'interface-subnet') - { - # interface-subnet is not CIDR conform, therefore we change the netmask to a single host - $obj_type = 'host'; - if ($v6flag==1) - { - $obj_netmask = '128'; - } - else - { - $obj_netmask = '255.255.255.255'; - } - } - if (!defined($comment)) { $comment = ''; } - if (!defined($obj_netmask)) { $obj_netmask = '255.255.255.255'; } - if (!$v6flag) { $obj_netmask = &calc_subnetmask($obj_netmask); } - print_debug("adding nw_obj type=$obj_type, name=$obj_name with ip $obj_ip/$obj_netmask, obj_ip_last=$obj_ip_last, zone=$zone", $debug, 5); - &add_nw_obj ($obj_name, "$obj_ip/$obj_netmask", $obj_type, $zone, $comment, $obj_ip_last, $uid_postfix, $debug); - undef($obj_name); undef($obj_ip); undef($comment); undef($zone); undef($obj_ip_last); undef($obj_type); undef($obj_netmask); - $context = &switch_context($context, 'firewall address', $debug); - next NEW_LINE; - } - # adding zone - if ($line=~ /^\s+set\sassociated\-interface\s\"(.+?)\"$/ && ($context eq 'firewall address single object' || $context eq 'firewall addrgrp single object')) { - $zone = $1; &add_zone ($zone, $debug); - print_debug("found zone $zone", $debug, 2); - next NEW_LINE; - } - if ($line =~ /^\s+set\suuid\s(\w+)$/ && ($context eq 'firewall address single object' || $context eq 'firewall addrgrp single object' || - $context eq 'firewall vip single object')) { - $uuid = $1; - print_debug("found object uid $uuid", $debug, 4); - next NEW_LINE; - } - if ($line =~ /^\s+set\stype\s([\w\-]+)$/ && $context eq 'firewall address single object') { - $obj_type = $1; - if ($obj_type eq 'multicastrange' || $obj_type eq 'iprange') { $obj_type = 'ip_range'; } - print_debug("found object type $obj_type", $debug, 4); - next NEW_LINE; - } - if ($line =~ /^\s+set\scomment\s[\'\"](.*?)[\'\"]$/ && ($context eq 'firewall address single object' || $context eq 'firewall addrgrp single object' - || $context eq 'firewall vip single object')) { - if (defined($comment) && $comment ne '') { $comment .= "; $1"; } else { $comment = $1; } - print_debug("found object comment $comment", $debug, 4); - next NEW_LINE; - } - if ($line =~ /^\s+set\s(wildcard\-)?fqdn\s\"(.*?)\"$/ && ($context eq 'firewall address single object' || $context eq 'firewall addrgrp single object')) { - my ($wcard, $fqdn); - if (defined($1)) { $wcard = $1; } else { $wcard = ''; } - $fqdn = $2; - if (defined($comment) && $comment ne '') { $comment .= "; ${wcard}fqdn $fqdn"; } else { $comment = "${wcard}fqdn $fqdn"; } - print_debug("found fqdn object $comment", $debug, 4); - next NEW_LINE; - } - - if ($line =~ /^\s+set\sassociated\-interface\s\"(\w+)\"$/ && $context eq 'firewall address single object') { - $zone = $1; - print_debug("found object zone $zone", $debug, 4); - next NEW_LINE; - } - if ($line =~ /^\s+set\ssubnet\s(.+?)\s(.+?)$/ && $context eq 'firewall address single object') { - $obj_ip = $1; - $obj_netmask = $2; - print_debug("found object ip $obj_ip with mask $obj_netmask", $debug, 4); - next NEW_LINE; - } -########### multicast/ip range ipv4 network objects ##################### - if ($context eq 'firewall address single object' && $line =~ /^\s+set\sstart\-ip\s([\d\.]+)$/) { - $obj_ip = $1; - print_debug("found ip range start-ip $obj_ip, context=$context", $debug, 6); - next NEW_LINE; - } - if ($context eq 'firewall address single object' && $line =~ /^\s+set\send\-ip\s([\d\.]+)$/) { - $obj_ip_last = "$1"; - print_debug("found ip range end-ip $obj_ip_last, context=$context", $debug, 6); - next NEW_LINE; - } -########### NAT network objects ##################### - if ( $context eq '' && $line =~ /^config firewall vip$/) { $context = &switch_context($context, 'firewall vip', $debug); next NEW_LINE; } - - if ($context eq 'firewall vip' && $line =~ /^\s+edit\s\"(.+)"$/) { - $obj_name = $1; - print_debug("found vip object name $obj_name", $debug, 4); - $context = &switch_context($context, $context . ' single object', $debug); - next NEW_LINE; - } - if ($context eq 'firewall vip single object' && $line =~ /^\s+set\sextip\s([\d\.]+)\-?(.*?)$/) { - $obj_ip = $1; - print_debug("found nat object (starting) ip $obj_ip", $debug, 5); - if (defined($2) && $2 ne '') { $obj_ip_last = "$2"; $obj_type = 'ip_range'; - print_debug("found nat object (ending) ip $obj_ip_last", $debug, 5); - } else { $obj_type = 'host'; } - next NEW_LINE; - } - if ($line =~ /^\s+set\stype\s(\w+?)\-nat$/ && $context eq 'firewall vip single object') { - $obj_type = $1; - print_debug("found object type $obj_type", $debug, 4); - $obj_type = 'host'; # dirty - resolve this to ip range type? - next NEW_LINE; - } - if ($line=~ /^\s+set\sextintf\s\"(.+?)\"$/ && $context eq 'firewall vip single object') { -# $zone = $1; -# if ($zone ne 'any') { -# &add_zone ($zone, $debug); -# print_debug("found zone $zone", $debug, 2); -# } else { -# $zone = 'global'; -# } - # above is not working with latest NAT example; so simply defining all VIPs as in zone global - $zone = 'global'; - next NEW_LINE; - } - if ($line =~ /^\s+next$/ && $context eq 'firewall vip single object') { - if (!defined($zone)) { $zone = 'global'; } - $obj_netmask = '255.255.255.255'; - print_debug("found nat obj $obj_name with ip $obj_ip in zone $zone", $debug, 5); - &add_nw_obj ($obj_name, $obj_ip . '/' . &calc_subnetmask ($obj_netmask), $obj_type, $zone, $comment, $obj_ip_last, $uid_postfix, $debug); - undef($obj_name); undef($obj_ip); undef($comment); undef($zone); - $context = &switch_context($context, 'firewall vip', $debug); - next NEW_LINE; - } - -#################### network object group #################################### - if ($line =~ /^\s+set\smember\s(.+)$/ && $context eq 'firewall addrgrp single object') { - $members = $1; - print_debug("found object member string $members", $debug, 4); - next NEW_LINE; - } - if ($line =~ /^\s+next$/ && $context eq 'firewall addrgrp single object') { - # address group wegschreiben - if (!defined($zone)) { $zone = 'global'; } - &add_nw_obj_grp ($obj_name, $members, $zone, $comment, $uuid, $uid_postfix, $debug); - undef($obj_name); undef($members); undef($comment); - $context = &switch_context($context, 'firewall addrgrp', $debug); - next NEW_LINE; - } - -########### service section -# --------------- parsing network services ---------------- - if ($line =~ /^config firewall service custom$/ && $context eq '') { - $context = &switch_context($context, 'firewall service custom', $debug); - next NEW_LINE; - } - if ($line =~ /^end$/ && $context eq 'firewall service custom') { - $context = &switch_context($context, '', $debug); - next NEW_LINE; - } - if ($line =~ /\s+edit\s\"(.+?)\"$/ && $context eq 'firewall service custom') { - $application_name = $1; - print_debug("found application $application_name", $debug, 5); - $context = &switch_context($context, 'firewall service custom single', $debug); - next NEW_LINE; - } - if ($line=~ /^\s+set\scomment\s[\'\"](.+?)[\'\"]$/ && $context eq 'firewall service custom single') { $comment = $1; } -# if ($line =~ /^\s+icmp\-(.+?)\s(\d+)\;$/ && $context eq 'applications/application') { $icmp_art = $1; $icmp_nummer = $2; next NEW_LINE; } - - if ($line =~ /\s+set\sprotocol\sICMP$/ && $context eq 'firewall service custom single') { - $proto = 'icmp'; - print_debug("found icmp based service $application_name", $debug, 5); - next NEW_LINE; - } -# set tcp-portrange 22:1024-65535 143-145:100-200 22123 -# set udp-portrange 68 889 789-891 -# rebuild this into a group of services with single ports - if ($line =~ /\s+set\s(udp|tcp)\-portrange\s(.+?)$/ && - ($context eq 'firewall service custom single' || $context eq 'firewall service single multi-port group')) { - my $old_proto = $proto; - my $old_destination_port = $destination_port; - $proto = $1; - $destination_port = $2; - if (defined($old_proto)) { # this is not the first portrange line for this service - $context = &switch_context($context, 'firewall service single multi-port group', $debug); - print_debug("starting multi-port firewall service group due to multi-proto service $application_name", $debug, 5); - # transform old portrange into group - $members = &transform_port_list_to_artificial_services($old_destination_port, $old_proto, $application_name, - $source_port, $uuid, $rpc, $icmp_art, $icmp_nummer, $comment, $debug); - print_debug("arty service 1st of 2 lines $application_name members: $members", $debug, 7); - $members .= " " . &transform_port_list_to_artificial_services($destination_port, $proto, $application_name, - $source_port, $uuid, $rpc, $icmp_art, $icmp_nummer, $comment, $debug); - print_debug("arty service 1st & 2nd line $application_name members: $members", $debug, 7); - } elsif ($destination_port =~ /\s/) { # more than one port separated by space - but first portrange line encountered - print_debug("starting multi-port firewall service group single proto $application_name", $debug, 5); - $context = &switch_context($context, 'firewall service single multi-port group', $debug); - $members = &transform_port_list_to_artificial_services($destination_port, $proto, $application_name, - $source_port, $uuid, $rpc, $icmp_art, $icmp_nummer, $comment, $debug); - print_debug("arty service 1st line $application_name members: $members", $debug, 5); - } else { # single port range - print_debug("starting vanilla service $application_name", $debug, 6); - # nothing else todo except for checking for source port - if ($destination_port =~ /^(.+?)\:(.+?)$/) { # handle port ranges including source ports: set tcp-portrange 0-65535:0-65535 - $destination_port = $1; - $source_port = $2; - } - } - next NEW_LINE; - } - if ($line =~ /\s+next$/ && $context eq 'firewall service custom single') { # service wegschreiben - &print_debug("before calling add_nw_service_obj: for application $application_name", $debug, 5); - &add_nw_service_obj ($application_name, $proto, $source_port, $destination_port, $uuid, $rpc, $icmp_art, $icmp_nummer, $comment, $debug); - $context = &switch_context($context, 'firewall service custom', $debug); - undef($application_name); undef($proto); undef($source_port); undef($destination_port); undef($uuid); undef($rpc); undef($icmp_art); undef($icmp_nummer); - undef ($comment); - next NEW_LINE; - } -# -------------- parsing service groups ------------------ - if ($line =~ /^config firewall service group$/ && $context eq '') { - print_debug("starting firewall service group", $debug, 6); - $context = &switch_context($context, 'firewall service group', $debug); - next NEW_LINE; - } - if ($line =~ /^\s+edit\s\"(.+?)"$/ && $context eq 'firewall service group') { - $context = &switch_context($context, 'firewall service single group', $debug); - $application_name = $1; - next NEW_LINE; - } - if ($line =~ /^\s+set\smember\s(.+)$/ && $context eq 'firewall service single group') { - $members = $1; - print_debug("found service members $members in service group $application_name", $debug, 6); - next NEW_LINE; - } - if ($line =~ /^\s+set\scomment\s[\'\"](.*?)[\'\"]$/ && ($context eq 'firewall service single group')) { - $comment = $1; - print_debug("found service group comment $comment", $debug, 4); - next NEW_LINE; - } -# closig statements - if ($line =~ /^end$/ && $context eq 'firewall service group') { $context = &switch_context($context, '', $debug); } - if ($line =~ /^\s+next$/ && ($context eq 'firewall service single group' || $context eq 'firewall service single multi-port group')) { - if ($context eq 'firewall service single group') { - $context = &switch_context($context, 'firewall service group', $debug); - } else { # moving from multi-port group back to non-group environment (context='firewall service single multi-port group') - $context = &switch_context($context, 'firewall service custom', $debug); - } - if (!defined($members)) { print_debug("warning: application group $application_name: members undefined", $debug, 1); } - print_debug("adding service group $application_name with members: $members", $debug, 5); - # service group wegschreiben - &add_nw_service_obj_grp ($application_name, $members, $comment, $debug); - undef($application_name); undef($proto); undef($source_port); undef($destination_port); undef($uuid); undef($rpc); undef($icmp_art); undef($icmp_nummer); - undef ($comment); undef ($members); - next NEW_LINE; - } - } - return 0; -} - - -sub cfg_file_complete { # check auf Vollstaendigkeit des Config-Files: - my $debug_level = shift; - my $ln_cnt = $#config_lines; - my $cfg_file_complete = 1; - - - while ($config_lines[$ln_cnt] =~ /^\s*$/ ) { $ln_cnt -- ; } # ignore empty lines at the end - if ($config_lines[$ln_cnt-2] !~ /^end/ && $config_lines[$ln_cnt-1] !~ /^$/ && $config_lines[$ln_cnt] !~ /^\w+ [\$\#] \.$/) { - $cfg_file_complete = 0; - print_debug ("ERROR: expected end of config to be end, blank line, prompt with fw name. Instead got: " . - $config_lines[$ln_cnt-2] . $config_lines[$ln_cnt-1] . $config_lines[$ln_cnt], $debug_level, -1); - } - return $cfg_file_complete; -} - -sub switch_context { - my $old_level = shift; - my $new_level = shift; - my $debug_level = shift; - print_debug("switching context from $old_level to $new_level", $debug_level, 4); - return $new_level; -} - -sub parse_config_rules { # ($debuglevel_main, $mgm_name_in_config) - my $debug = shift; - my $mgm_name = shift; - my ($source, $destination, $application, $from_zone, $to_zone, $policy_name, $track, $uid_postfix, $comment); - my $line = ''; - my $context = ''; - my $disabled =''; - my $action = 'deny'; - my $rule_no = 0; - my ($policy_id, $policy_uid); - my $list; - my $list_typ; - my $svc_neg = 0; - my $src_neg = 0; - my $dst_neg = 0; - my $policy_type; - - &print_debug("entering parse_config_rules =======================================================",$debug,2); - NEW_LINE: foreach $line (@config_lines) { - chomp($line); - &print_debug("pcr: $line", $debug, 9); - if ($line =~ /^config firewall policy(.*?)$/ && $context eq '') { # match all policy types 4, 6, 4to6 6to4, ... - $policy_type = $1; - $context = &switch_context($context, 'firewall policy', $debug); - next NEW_LINE; - } - if ($line =~ /^\s+edit\s(\d+)$/ && $context eq 'firewall policy') { - $context = &switch_context($context, 'firewall policy single rule', $debug); - $policy_id = $1; - # to avoid duplicate policy ids (v6 and v4 may have clashing ids) - if ($policy_type ne '') { $policy_id = "ipv$policy_type.$policy_id"; } - &print_debug("found policy $policy_id",$debug,2); - next NEW_LINE; - } - if ($line=~ /^\s+set\ssrcintf\s\"(.+?)\"$/ && $context eq 'firewall policy single rule') { - $from_zone = $1; - &add_zone ($from_zone, $debug); - &print_debug("found from zone $from_zone",$debug,5); - next NEW_LINE; - } - if ($line=~ /^\s+set\sdstintf\s\"(.+?)\"$/ && $context eq 'firewall policy single rule') { - $to_zone = $1; - &add_zone ($to_zone, $debug); - &print_debug("found to zone $to_zone",$debug,5); - next NEW_LINE; - } - # negated rule parts: - if ($line=~ /^\s+set\s(service|srcaddr|dstaddr)\-negate\senable$/ && $context eq 'firewall policy single rule') { - my $negation = $1; - if ($negation eq 'service') { $svc_neg= '1'; } - if ($negation eq 'srcaddr') { $src_neg= '1'; } - if ($negation eq 'dstaddr') { $dst_neg= '1'; } - &print_debug("found negation $negation",$debug,5); - next NEW_LINE; - } - - if ($line=~ /^\s+set\sname\s\"(.*?)\"$/ && $context eq 'firewall policy single rule') { - $policy_name = $1; - &print_debug("found rule name $policy_name",$debug,5); - next NEW_LINE; - } - if ($line=~ /^\s+set\scomments\s\"(.*?)\"$/ && $context eq 'firewall policy single rule') { - $comment = $1; - &print_debug("found single line rule comment $comment",$debug,5); - next NEW_LINE; - } - if ($line=~ /^\s+set\scomments\s\"(.*?)$/ && $context eq 'firewall policy single rule') { - $comment = $1; - $context = &switch_context($context, 'firewall policy single rule multi-line comment', $debug); - &print_debug("found start of multi-line rule comment $comment",$debug,5); - next NEW_LINE; - } - if ($line=~ /^(.*?)(\"?)$/ && $context eq 'firewall policy single rule multi-line comment') { - $comment .= "\n$1"; - &print_debug("found more lines of multi-line comment $comment",$debug,5); - if (defined($2) && $2 eq '"') { $context = &switch_context($context, 'firewall policy single rule', $debug); } - next NEW_LINE; - } - if ($line=~ /^\s+set\sstatus\s(en|dis)able$/ && $context eq 'firewall policy single rule') { - if ($1 eq 'en') { $disabled=''; } else { $disabled = "inactive" } - &print_debug("found rule dis/enable statement: $disabled",$debug,5); - next NEW_LINE; - } - if ($line=~ /^\s+set\suuid\s(.*?)$/ && $context eq 'firewall policy single rule') { - $policy_uid = $1; - &print_debug("found policy uid: $policy_uid",$debug,5); - next NEW_LINE; - } - - if ($line =~ /^\s+set (src|dst)addr\s(.+)$/ && $context eq 'firewall policy single rule') { - $list_typ = $1; - $list = $2; - if ($list_typ eq 'src') { $source = $list; } - if ($list_typ eq 'dst') { $destination = $list; } - &print_debug("found src/dst list ($list_typ): $list",$debug,5); - next NEW_LINE; - } - if ($line =~ /^\s+set\sservice\s(.*?)$/ && $context eq 'firewall policy single rule') { - $application = $1; - &print_debug("found service: $application",$debug,5); - next NEW_LINE; - } -# action / track part of rule (then) - if ($line=~ /^\s+set\saction\s(accept|deny|reject)$/ && $context eq 'firewall policy single rule') { - $action = $1; - &print_debug("found action: $action",$debug,5); - next NEW_LINE; - } - if ($line=~ /^\s+set\slogtraffic[\s|-](disable|utm|all|start enable)$/ && $context eq 'firewall policy single rule') { - my $found_track = $1; - if ($found_track eq 'disable') { $found_track = 'none'; } - if (!defined($track) || $track eq '') { $track = $found_track; } - elsif ($found_track eq 'start enable') { $track .= ' start'; } - &print_debug("found track: $track",$debug,5); - next NEW_LINE; - } -#closing sections - if ($line =~ /^end$/ && $context eq 'firewall policy') { - $context = &switch_context($context, '', $debug); - &print_debug("found end of policy section, stopping rule parsing.",$debug,5); - next NEW_LINE; -# config file may contain more than one "config firewall policy" section - } - if ($line =~ /^\s+next$/ && $context eq 'firewall policy single rule') { - if (!defined($track)) { $track=''; } - if (!defined($policy_name)) { $policy_name=''; } - if (!defined($from_zone)) { $from_zone=''; } - if (!defined($to_zone)) { $to_zone=''; } - if (!defined($policy_name)) { $policy_name=''; } - if ($policy_type ne '') { $uid_postfix = ".ipv$policy_type.uid"; } else { $uid_postfix = ''; } - &print_debug("found rule from $from_zone to $to_zone, name=$policy_name, disabled=$disabled, src=$source, dst=$destination, svc=$application, action=$action, track=$track", $debug,3); - # Regel wegschreiben - - # using UID as uid - # $rule_no = &add_rule ($rule_no, $from_zone, $to_zone, $policy_uid, $disabled, $source, $destination, $application, - # $action, $track, $comment, $policy_name, $svc_neg, $src_neg, $dst_neg, $uid_postfix, $debug); - - # using id as uid - $rule_no = &add_rule ($rule_no, $from_zone, $to_zone, $policy_id, $disabled, $source, $destination, $application, - $action, $track, $comment, $policy_name, $svc_neg, $src_neg, $dst_neg, $uid_postfix, $debug); - - $context = &switch_context($context, 'firewall policy', $debug); - # reset all values after a rule has been parsed: - $action='deny'; # default value for action = deny (not contained in config!) - $disabled=''; $source=''; $destination=''; $application=''; $uid_postfix=''; - undef($track); undef($policy_name); undef($comment); undef($from_zone); undef($to_zone); - $svc_neg = 0; $src_neg = 0; $dst_neg = 0; - - next NEW_LINE; - } # end of rule - } - &sort_rules_and_add_zone_headers($debug); - $rulebases{"$rulebase_name.ruleorder"} = join(',', @ruleorder); - return 0; -} - -sub purge_non_vdom_config_lines { # ($vdom_name) - my $vdom_name = shift; - my $debug = shift; - my $ln_cnt = 0; - my $found_correct_vdom = 0; - my @vdom_config_lines; - my ($start_of_vdom, $end_of_vdom); - - $end_of_vdom = $#config_lines; # if vdom is the last vdom in file - LINE: while (!$found_correct_vdom && $ln_cnt<$#config_lines) { - if (!defined($start_of_vdom) && - $config_lines[$ln_cnt] =~ /^config vdom$/ && - $config_lines[$ln_cnt+1] =~ /^edit ${vdom_name}$/ - # && $config_lines[$ln_cnt+2] =~ /^config system settings$/ - #&& $config_lines[$ln_cnt+2] =~ /^config system / - && $config_lines[$ln_cnt+2] !~ /^next$/ # filter out vdom defining lines at the very begining - ) - { - $start_of_vdom = $ln_cnt+2; - $ln_cnt++ ; - } - if (defined($start_of_vdom) && - $config_lines[$ln_cnt] =~ /^config vdom$/ && - $config_lines[$ln_cnt+1] =~ /^edit .+?$/ - #&& $config_lines[$ln_cnt+2] =~ /^config system / - && $config_lines[$ln_cnt+2] !~ /^next$/ - ) - { - $end_of_vdom = $ln_cnt; - $ln_cnt = $#config_lines; - } - $ln_cnt++ ; - } - @vdom_config_lines = splice(@config_lines, $start_of_vdom, $end_of_vdom-$start_of_vdom+1); - &print_debug("found vdom $vdom_name from line $start_of_vdom to line $end_of_vdom",$debug,1); - @config_lines = @vdom_config_lines; -} - -sub remove_pagination { # removes --More-- ^M ^M - my $debug = shift; - my $ln_cnt = 0; - - &print_debug("start of pagination removal",$debug,3); - while ($ln_cnt<$#config_lines) { - if ($config_lines[$ln_cnt] =~ /^\-\-More\-\-\s\r\s+\r(\s*.+)$/) { - $config_lines[$ln_cnt] = $1; - } - $ln_cnt++; - } - &print_debug("end of pagination removal",$debug,3); -} - -##################################################################################### -# MAIN - -sub parse_config { # ($obj_file, $rule_file, $rulebases, $user, $fworch_workdir, $debug_level, $mgm_name, $config_dir, $import_id) - my $in_file_main = shift; - shift; shift; shift; # $rule_file und $rulebases und $user nicht verwendet - my $fworch_workdir = shift; - my $debuglevel_main = shift; - my $mgm_name = shift; - my $config_dir = shift; - my $import_id = shift; - my $debug_level = shift; - my $vdom_name; - - # initializing global variables: - @services = (); - @network_objects = (); - &print_debug ("in_file_main=$in_file_main, fworch_workdir=$fworch_workdir, debuglevel_main=$debuglevel_main, mgm_name=$mgm_name, config_dir=$config_dir, import_id=$import_id", $debuglevel_main, 6); - - open (IN, $in_file_main) || die "$in_file_main konnte nicht geoeffnet werden.\n"; - @config_lines = ; # sichern Config-array fuer spaetere Verwendung - close (IN); - &remove_pagination($debuglevel_main); - - if (!&cfg_file_complete($debuglevel_main)) { return "incomplete-config-file-$mgm_name"; } - else { -# my $mgm_name_in_config = &parse_mgm_name($debuglevel_main); - @rulebases = ($mgm_name); - $rulebase_name = $mgm_name; - &print_debug("parse_mgm_name: found hostname of single system: $mgm_name and setting rulebase_name to $mgm_name",$debuglevel_main,1); - - my $vdom_names = &parse_vdom_names($debuglevel_main); - if ($vdom_names ne '' && $mgm_name =~ /.+?\_\_\_(.+)$/ ) { # file contains multiple vdoms and mgm_name also contains xxx___vdom_name - $vdom_name = $1; - &print_debug ("rulebase_name: $rulebase_name, mgm_name=$mgm_name, mgm_name_in_config=$mgm_name, vdom_name:$vdom_name", $debuglevel_main, 2); - &purge_non_vdom_config_lines ($vdom_name,$debuglevel_main); # removes all lines that do not belong to correct vdom from @config_lines - } - &parse_config_base_objects ($debuglevel_main, $mgm_name); # zones, simple network and service objects - push @zones, "global"; # Global Zone immer hinzufuegen - &parse_config_rules ($debuglevel_main, $mgm_name); # finally parsing the rule base, ignoring the rulebase name in fworch config - - &print_results_files_objects($fworch_workdir, $mgm_name, $import_id); - &print_results_files_rules ($fworch_workdir, $mgm_name, $import_id); - &print_results_files_zones ($fworch_workdir, $mgm_name, $import_id); -# print_results_monitor('objects'); -# print_results_monitor('rules'); - } - return 0; -} - -1; -__END__ - -=head1 NAME - -CACTUS::FWORCH::parser - Perl extension for fworch fortinet parser - -=head1 SYNOPSIS - - use CACTUS::FWORCH::import::fortinet; - -=head1 DESCRIPTION - -fworch Perl Module support for importing configs into fworch Database - -=head2 EXPORT - - global variables - - -=head1 SEE ALSO - - behind the door - -=head1 AUTHOR - -Cactus eSecurity, tmp@cactus.de - -=cut diff --git a/roles/importer/files/importer/CACTUS/FWORCH/import/juniper.pm b/roles/importer/files/importer/CACTUS/FWORCH/import/juniper.pm deleted file mode 100644 index 452268a52a..0000000000 --- a/roles/importer/files/importer/CACTUS/FWORCH/import/juniper.pm +++ /dev/null @@ -1,1075 +0,0 @@ - -package CACTUS::FWORCH::import::parser; - -use strict; -use warnings; -use Time::HiRes qw(time); # fuer hundertstelsekundengenaue Messung der Ausfuehrdauer -use CACTUS::FWORCH; -use CACTUS::FWORCH::import; -use CACTUS::read_config; - -require Exporter; -our @ISA = qw(Exporter); - -our %EXPORT_TAGS = ( 'basic' => [ qw( ©_config_from_mgm_to_iso &parse_config ) ] ); - -our @EXPORT = ( @{ $EXPORT_TAGS{'basic'} } ); -our $VERSION = '0.3'; - -our @config_lines; # array der Zeilen des Config-Files im Originalzustand (kein d2u etc.) -our $parser_mode; # Typ des Config-Formates (basic, data) -our $rule_order = 0; # Reihenfolge der Rules im Configfile -our $rulebase_name; -our %junos_uuids = (); - -## parse_audit_log Funktion fuer JunOS (noch) nicht implementiert -sub parse_audit_log { } - -##################################### -# add_nw_obj -# param1: obj_name -# param2: obj_ip (with netmask) -# param3: obj zone -# param4: debuglevel [0-?] -##################################### -sub add_nw_obj { - my $act_obj_name = shift; - my $obj_ip = shift; - my $act_obj_zone = shift; - my $act_obj_comm = shift; - my $debuglevel = shift; - my $act_obj_nameZ = ''; - my $act_obj_ipaddr = ''; - my $act_obj_ipaddr_last = ''; - my $act_obj_mask = ''; - my $act_obj_type = ''; - my $act_obj_loc = ''; - my $act_obj_color = 'black'; - my $act_obj_sys = ''; - my $act_obj_uid = ''; - my $ipv6 = 0; - - print_debug("add_nw_obj called with name=$act_obj_name, ip=$obj_ip, zone=$act_obj_zone", $debuglevel, 5); - ($act_obj_ipaddr, $act_obj_mask) = split (/\//, $obj_ip); - if ($obj_ip =~/\:/) { $ipv6 = 1; } - print_debug("split: ip=$act_obj_ipaddr, mask=$act_obj_mask", $debuglevel, 4); -# $act_obj_nameZ = "${act_obj_name}__zone__$act_obj_zone"; # Zone in Feldindex mit aufgenommen - $act_obj_nameZ = "${act_obj_name}"; # CHANGE: Zone nicht in Feldindex aufgenommen - if (!defined ($network_objects{"$act_obj_nameZ.name"})) { - @network_objects = (@network_objects, $act_obj_nameZ); - $network_objects{"$act_obj_nameZ.name"} = $act_obj_name; - $network_objects{"$act_obj_nameZ.UID"} = $act_obj_nameZ; - if ((!$ipv6 && $act_obj_mask==32) || ($ipv6 && $act_obj_mask==128)) { $network_objects{"$act_obj_nameZ.type"} = 'host' } - else { $network_objects{"$act_obj_nameZ.type"} = 'network' } - $network_objects{"$act_obj_nameZ.netmask"} = $act_obj_mask ; - $network_objects{"$act_obj_nameZ.zone"} = $act_obj_zone; # neues Feld fuer Zone - $network_objects{"$act_obj_nameZ.ipaddr"} = $act_obj_ipaddr; - $network_objects{"$act_obj_nameZ.ipaddr_last"} = $act_obj_ipaddr_last; - $network_objects{"$act_obj_nameZ.color"} = $act_obj_color; - $network_objects{"$act_obj_nameZ.comments"} = $act_obj_comm; - $network_objects{"$act_obj_nameZ.location"} = $act_obj_loc; - $network_objects{"$act_obj_nameZ.sys"} = $act_obj_sys; - } else { - print_debug ("found duplicate object definition for network object $act_obj_name in zone $act_obj_zone", $debuglevel, -1); - } -} - -##################################### -# add_nw_obj_group_member -# param1: input-line -# param2: debuglevel [0-?] -##################################### -sub add_nw_obj_group_member{ - my $group_name = shift; - my $member_name = shift; - my $act_obj_zone = shift; - my $comment = shift; - my $debuglevel = shift; - - my $act_obj_name = ''; - my $group_nameZ = ''; - my $act_obj_mbr = ''; - my $act_obj_fkt = ''; - my $act_obj_color = 'black'; - my $act_obj_comm = ''; - my $mbrlst = ''; - my $mbr_ref_lst = ''; - -# $group_nameZ = "${group_name}__zone__$act_obj_zone"; # Zone in Feldindex mit aufgenommen - $group_nameZ = "${group_name}"; # CHANGE: Zone nicht in Feldindex aufgenommen - if (!defined ($network_objects{"$group_nameZ.name"})) { - @network_objects = (@network_objects, $group_nameZ); - $network_objects{"$group_nameZ.name"} = $group_name; - $network_objects{"$group_nameZ.UID"} = $group_nameZ; - print_debug ("added group $group_nameZ", $debuglevel, 5); - $network_objects{"$group_nameZ.zone"} = $act_obj_zone; # neues Feld fuer Zone - $network_objects{"$group_nameZ.type"} = 'group'; - $network_objects{"$group_nameZ.color"} = $act_obj_color; - } -# die ("reference to undefined network object $member_name found in group $group_name, zone: $act_obj_zone"); - if (defined($network_objects{"$group_nameZ.members"})) { - $mbrlst = $network_objects{"$group_nameZ.members"}; - $mbr_ref_lst = $network_objects{"$group_nameZ.member_refs"}; - } - if ( $mbrlst eq '' ) { - $mbrlst = $member_name; -# $mbr_ref_lst = $member_name . "__zone__$act_obj_zone"; - $mbr_ref_lst = $member_name; #CHANGE - } - else { - $mbrlst = "$mbrlst|$member_name"; -# $mbr_ref_lst = "$mbr_ref_lst|$member_name" . "__zone__$act_obj_zone"; - $mbr_ref_lst = "$mbr_ref_lst|$member_name"; #CHANGE - } - $network_objects{"$group_nameZ.members"} = $mbrlst; - $network_objects{"$group_nameZ.member_refs"} = $mbr_ref_lst; - if (defined($comment) && $comment ne '') { $network_objects{"$group_nameZ.comments"} = $comment; } - return; -} - -##################################### -# add_nw_service_obj -# param1: input-line -# param2: debuglevel [0-?] -##################################### -sub add_nw_service_obj { # ($application_name, $proto, $source_port, $destination_port, $uuid, $rpc, $icmp_art, $icmp_nummer, $debug_level_main) - my $act_obj_name = shift; - my $act_obj_proto = shift; - my $act_obj_src = shift; - my $act_obj_dst = shift; - my $act_obj_uid = shift; - my $act_obj_rpc = shift; - my $icmp_art = shift; - my $icmp_nummer = shift; - my $comment = shift; - my $debuglevel = shift - my @range; - my $act_obj_typ = 'simple'; - my $act_obj_type = ''; - my $act_obj_src_last = ''; - my $act_obj_dst_last = ''; - my $act_obj_time = ''; - my $act_obj_time_std = ''; - my $act_obj_color = 'black'; - - if (!defined ($services{"$act_obj_name.name"})) { - @services = (@services, $act_obj_name); - $services{"$act_obj_name.name"} = $act_obj_name; - if (defined($act_obj_src)) { - @range = split ( /-/, $act_obj_src); - $services{"$act_obj_name.src_port"} = $range[0]; - if (defined($range[1])) { - $services{"$act_obj_name.src_port_last"} = $range[1]; - } else { - $services{"$act_obj_name.src_port_last"} = ''; - } - } - if (defined($act_obj_dst)) { - @range = split ( /-/, $act_obj_dst); - $services{"$act_obj_name.port"} = $range[0]; - if (defined($range[1])) { - $services{"$act_obj_name.port_last"} = $range[1]; - } else { - $services{"$act_obj_name.port_last"} = ''; - } - } - if (defined($act_obj_proto)) { - $services{"$act_obj_name.ip_proto"} = get_proto_number($act_obj_proto) - } else { - $services{"$act_obj_name.ip_proto"} = ''; - } - $services{"$act_obj_name.timeout"} = $act_obj_time; - $services{"$act_obj_name.color"} = $act_obj_color; - if (defined($comment) && $comment ne '') { $services{"$act_obj_name.comments"} = $comment; } else { $services{"$act_obj_name.comments"} = ''; } - $services{"$act_obj_name.typ"} = $act_obj_typ; - $services{"$act_obj_name.type"} = $act_obj_type; - if (defined($act_obj_rpc)) { - $services{"$act_obj_name.rpc_port"} = $act_obj_rpc; - } else { - $services{"$act_obj_name.rpc_port"} = ''; - } - $services{"$act_obj_name.UID"} = $act_obj_name; - if (defined($act_obj_uid) && $act_obj_uid ne '') { $junos_uuids{"$act_obj_uid"} = $act_obj_name; } # collect uid refs - print_debug("add_nw_service_obj: added application $act_obj_name", $debuglevel, 4); - } else { - print_debug("add_nw_service_obj: warning duplicate defintion of service $act_obj_name", $debuglevel, 1); - } - return; -} - -##################################### -# add_nw_service_obj_grp -# param1: input-line -# param2: debuglevel [0-?] -##################################### -sub add_nw_service_obj_grp { # ($application_name, $members, $members_proto, $members_uid, $comment, $debuglevel_main); - my $act_obj_name = shift; - my $act_obj_members = shift; - my $comment = shift; - my $debuglevel = shift; - my $act_obj_typ = 'group'; - my $act_obj_type = ''; - my $act_obj_proto = ''; - my $act_obj_src_last = ''; - my $act_obj_dst_last = ''; - my $act_obj_time = ''; - my $act_obj_time_std = ''; - my $act_obj_color = 'black'; - my $act_obj_rpc = ''; - my $mbrlst = ''; - - if (!defined ($services{"$act_obj_name.name"})) { - @services = (@services, $act_obj_name); - $services{"$act_obj_name.name"} = $act_obj_name; - print_debug("adding service group $act_obj_name", $debuglevel, 5); - } else { - print_debug("re-defining service group $act_obj_name", $debuglevel, 5); - } - if (defined($act_obj_members) && $act_obj_members ne '') { - $services{"$act_obj_name.members"} = $act_obj_members; # simple group case - $services{"$act_obj_name.member_refs"} = $act_obj_members; # simple group case - print_debug("adding service group $act_obj_name with members $act_obj_members", $debuglevel, 5); - } else { - print_debug("no members defined", $debuglevel, 1); - } - $services{"$act_obj_name.ip_proto"} = $act_obj_proto; - $services{"$act_obj_name.timeout"} = $act_obj_time; - $services{"$act_obj_name.color"} = $act_obj_color; - if (defined($comment) && $comment ne '') { $services{"$act_obj_name.comments"} = $comment; } else { $services{"$act_obj_name.comments"} = ''; } - $services{"$act_obj_name.typ"} = $act_obj_typ; - $services{"$act_obj_name.type"} = $act_obj_type; - $services{"$act_obj_name.rpc_port"} = $act_obj_rpc; - $services{"$act_obj_name.UID"} = $act_obj_name; -} - -sub junos_split_list { # param1 = list of objects (network or service) - my $list = shift; - my $debug_level = shift; - my $orig_list = $list; - -# if ($list =~ /^\[\s([\w\-\_\/\.\d\s]+?)\s\]$/) { # standard list format: [ x1 x2 x3 ] - if ($list =~ /^\[\s(.+?)\s\]$/) { # standard list format: [ x1 x2 x3 ] - $list = $1; - $list = join('|', split(/\s+/, $list)); -# } elsif ($list =~ /[\w\-\_\/\.\d]+/) { - } elsif ($list =~ /[^\s]+/) { - # found single object, no changes necessary - } else { - print_debug("warning in junos_split_list: orig_list=$orig_list; found no match for object list", $debug_level, 1); - } -# print_debug("junos_split_list: orig_list=$orig_list, result=$list", $debug_level, 5); - return $list; -} - -##################################### -# add_rule -# param1: -# debuglevel [integer] -##################################### -sub add_rule { # ($rule_no, $from_zone, $to_zone, $policy_name, $disabled, $source, $destination, $application, $action, $track, $debuglevel_main) - my $rule_no = shift; - my $from_zone = shift; - my $to_zone = shift; - my $policy_name = shift; - my $disabled = shift; - my $source = shift; - my $destination = shift; - my $service = shift; - my $action = shift; - my $track = shift; - my $comment = shift; - my $debuglevel = shift; - my $rule_id; - -# print_debug ("add_rule: rulebase_name=$rulebase_name, rulecount=" . $rulebases{"$rulebase_name.rulecount"}, $debuglevel, 4); - $rulebases{"$rulebase_name.rulecount"} = $rule_no + 1; # Anzahl der Regeln wird sukzessive hochgesetzt - $rule_id = "from_zone__$from_zone" . "__to_zone__$to_zone" . "__$policy_name"; - $ruleorder[$rule_no] = $rule_no; - - if (!defined($track) || $track eq '') { $track = 'none'; } - if (length($track)<3) { print_debug ("warning, short track: <$track>", $debuglevel, 1); } - - $rulebases{"$rulebase_name.$rule_no.src"} = ''; - foreach my $src (split(/\|/, &junos_split_list($source, $debuglevel))) { - if ($rulebases{"$rulebase_name.$rule_no.src"} ne '') { - $rulebases{"$rulebase_name.$rule_no.src"} .= '|'; - $rulebases{"$rulebase_name.$rule_no.src.refs"} .= '|'; - } - $rulebases{"$rulebase_name.$rule_no.src"} .= "$src"; -# $rulebases{"$rulebase_name.$rule_no.src.refs"} .= ("$src" . "__zone__$from_zone"); - $rulebases{"$rulebase_name.$rule_no.src.refs"} .= ("$src"); # CHANGE - } - $rulebases{"$rulebase_name.$rule_no.dst"} = ''; - foreach my $dst (split(/\|/, &junos_split_list($destination, $debuglevel))) { - if ($rulebases{"$rulebase_name.$rule_no.dst"} ne '') { - $rulebases{"$rulebase_name.$rule_no.dst"} .= '|'; - $rulebases{"$rulebase_name.$rule_no.dst.refs"} .= '|'; - } - $rulebases{"$rulebase_name.$rule_no.dst"} .= "$dst"; -# $rulebases{"$rulebase_name.$rule_no.dst.refs"} .= ("$dst" . "__zone__$to_zone"); - $rulebases{"$rulebase_name.$rule_no.dst.refs"} .= ("$dst"); # CHANGE - } - - $rulebases{"$rulebase_name.$rule_no.services"} = ''; - foreach my $svc (split(/\|/, &junos_split_list($service, $debuglevel))) { - if ($rulebases{"$rulebase_name.$rule_no.services"} ne '') { - $rulebases{"$rulebase_name.$rule_no.services"} .= '|'; - $rulebases{"$rulebase_name.$rule_no.services.refs"} .= '|'; - } - $rulebases{"$rulebase_name.$rule_no.services"} .= "$svc"; - $rulebases{"$rulebase_name.$rule_no.services.refs"} .= "$svc"; - } - - $rulebases{"$rulebase_name.$rule_no.id"} = $rule_id; - $rulebases{"$rulebase_name.$rule_no.ruleid"} = $rule_id; - $rulebases{"$rulebase_name.$rule_no.order"} = $rule_no; - if ($disabled eq 'inactive') { $rulebases{"$rulebase_name.$rule_no.disabled"} = '1'; } - else { $rulebases{"$rulebase_name.$rule_no.disabled"} = '0'; } - $rulebases{"$rulebase_name.$rule_no.src.zone"} = $from_zone; - $rulebases{"$rulebase_name.$rule_no.dst.zone"} = $to_zone; - $rulebases{"$rulebase_name.$rule_no.services.op"} = '0'; - $rulebases{"$rulebase_name.$rule_no.src.op"} = '0'; - $rulebases{"$rulebase_name.$rule_no.dst.op"} = '0'; - $rulebases{"$rulebase_name.$rule_no.action"} = $action; - $rulebases{"$rulebase_name.$rule_no.track"} = $track; - $rulebases{"$rulebase_name.$rule_no.install"} = ''; # set hostname verwenden ? - $rulebases{"$rulebase_name.$rule_no.name"} = $policy_name; # kein Aequivalent zu CP rule_name - $rulebases{"$rulebase_name.$rule_no.time"} = ''; - if (defined($comment) && $comment ne '') { $rulebases{"$rulebase_name.$rule_no.comments"} = $comment; } - else { $rulebases{"$rulebase_name.$rule_no.comments"} = $policy_name; } - $rulebases{"$rulebase_name.$rule_no.UID"} = $rule_id; - $rulebases{"$rulebase_name.$rule_no.header_text"} = ''; - return $rule_no+1; -} - -############################################################ -# add_zone ($new_zone) -############################################################ -sub add_zone { - my $new_zone = shift; - my $debug = shift; - my $is_there = 0; - foreach my $elt (@zones) { if ($elt eq $new_zone) { $is_there = 1; last; } } - if (!$is_there) { push @zones, $new_zone; &print_debug("adding new zone: $new_zone", $debug, 1); } -} - -############################################################ -# object_address_add (name, ip, mask, zone, comment) -############################################################ -sub object_address_add { - my $act_obj_name = $_[0]; - my $act_obj_ipaddr = $_[1]; - my $act_obj_mask = $_[2]; - my $act_obj_zone = $_[3]; - my $act_obj_comm = $_[4]; - my @params; - my $act_obj_nameZ = ''; - my $act_obj_ipaddr_last = ''; - my $act_obj_type = 'simple'; - my $act_obj_loc = ''; - my $act_obj_color = 'black'; - my $act_obj_sys = ''; - my $act_obj_uid = ''; - -# $act_obj_nameZ = "${act_obj_name}__zone__$act_obj_zone"; # Zone in Feldindex mit aufgenommen - $act_obj_nameZ = "${act_obj_name}"; # CHANGE Zone nicht in Feldindex aufgenommen - if (!defined ($network_objects{"$act_obj_nameZ.name"})) { - @network_objects = (@network_objects, $act_obj_nameZ); - $network_objects{"$act_obj_nameZ.name"} = $act_obj_name; - } elsif (defined ($network_objects{"$act_obj_nameZ.name"})) { - print "sub ns_object_address NET_OBJECT: $act_obj_nameZ ist bereits definiert.\n"; - } else { - print "sub ns_object_address NET_OBJECT: $act_obj_nameZ ist undefiniert.\n"; - } - my $subnetbits = calc_subnetmask ($act_obj_mask); - if ($subnetbits==32) { $network_objects{"$act_obj_nameZ.type"} = 'host' }; - if ($subnetbits<32) { $network_objects{"$act_obj_nameZ.type"} = 'network' }; - $network_objects{"$act_obj_nameZ.netmask"} = $act_obj_mask ; - $network_objects{"$act_obj_nameZ.zone"} = $act_obj_zone; # neues Feld fuer Zone - $network_objects{"$act_obj_nameZ.ipaddr"} = $act_obj_ipaddr; - $network_objects{"$act_obj_nameZ.ipaddr_last"} = $act_obj_ipaddr_last; - $network_objects{"$act_obj_nameZ.color"} = $act_obj_color; - $network_objects{"$act_obj_nameZ.comments"} = $act_obj_comm; - $network_objects{"$act_obj_nameZ.location"} = $act_obj_loc; - $network_objects{"$act_obj_nameZ.sys"} = $act_obj_sys; - $network_objects{"$act_obj_nameZ.UID"} = $act_obj_nameZ; -} - -############################################################ -# read_predefined_services( -############################################################ -sub read_predefined_services { - my $device_type = shift; -# my $predefined_service_string = shift; - my $debug_level = shift; - my $predef_svc; - my ($svc_name,$ip_proto,$port,$port_end,$timeout,$comment,$typ,$group_members); - - $predef_svc = exec_pgsql_cmd_return_value ("SELECT dev_typ_predef_svc FROM stm_dev_typ WHERE dev_typ_id=$device_type"); - my @predef_svc = split /\n/, $predef_svc; - - &print_debug("inserting pre-defined services for junos: $predef_svc",$debug_level,8); - - foreach my $svc_line (@predef_svc) { - ($svc_name,$ip_proto,$port,$port_end,$timeout,$comment,$typ,$group_members) = split /;/, $svc_line; - $services{"$svc_name.name"} = $svc_name; - $services{"$svc_name.port"} = $port; - $services{"$svc_name.port_last"} = $port_end; - $services{"$svc_name.ip_proto"} = $ip_proto; - $services{"$svc_name.timeout"} = $timeout; - $services{"$svc_name.color"} = "black"; -# $services{"$svc_name.comments"} = "$predefined_service_string, $comment"; - $services{"$svc_name.comments"} = $comment; - $services{"$svc_name.typ"} = $typ; - $services{"$svc_name.type"} = ""; - $services{"$svc_name.rpc_port"} = ""; - $services{"$svc_name.UID"} = $svc_name; - $services{"$svc_name.members"} = $group_members; - $services{"$svc_name.member_refs"} = $group_members; - push @services, $svc_name; - } - return; -} - -sub resolve_service_uuid_references { # ($debuglevel_main); - my $debug = shift; - - foreach my $nw_svc (@services) { - &print_debug("resolve_service_uuid_references: checking service $nw_svc, typ=" . $services{"$nw_svc.typ"} . "type=" . $services{"$nw_svc.type"}, $debug, 5); - if ($services{"$nw_svc.typ"} eq 'group') { - &print_debug("resolve_service_uuid_references: checking service group $nw_svc", $debug, 5); - my @members = split (/\|/, $services{"$nw_svc.member_refs"}); - my $member_string = ''; - my $change_flag = 0; - foreach my $member (@members) { - &print_debug("resolve_service_uuid_references: checking member $member", $debug, 5); - if ($member =~ /^[a-f0-9]\-[a-f0-9]\-[a-f0-9]\-[a-f0-9]\-[a-f0-9]$/) { - my $old_member = $member; - $change_flag = 1; - $member = $junos_uuids{"$member"}; - &print_debug("resolve_service_uuid_references: replacing uuid $old_member with $member", $debug, 5); - } - if ($member_string ne '') { $member_string .= '|'; } - $member_string .= $member; - } - if ($change_flag) { - $services{"$nw_svc.members"} = $member_string; - $services{"$nw_svc.member_refs"} = $member_string; - } - } - } - return; -} - -############################################################ -# copy_config_from_mgm_to_iso($ssh_private_key, $ssh_user, $ssh_hostname, $management_name, -# $obj_file_base, $cfg_dir, $rule_file_base) -# Kopieren der Config-Daten vom Management-System zum ITSecorg-Server -############################################################ - -sub copy_config_from_mgm_to_iso { - my $ssh_user = shift; - my $ssh_hostname = shift; - my $management_name = shift; - my $obj_file_base = shift; - my $cfg_dir = shift; - my $rule_file_base = shift; - my $workdir = shift; - my $debug_level = shift; - my $cmd; - my $fehler_count = 0; - my $result; - my $simulate = 0; - - if ($simulate) { # get config from std ssh server, not from native junos system - $cmd = "echo \"applications {\" > $cfg_dir/$obj_file_base"; - if (system ($cmd)) { $fehler_count++; } - $cmd = "$scp_bin $scp_batch_mode_switch -i $workdir/$CACTUS::FWORCH::ssh_id_basename $ssh_user\@$ssh_hostname:predef_svc_junos $cfg_dir/$obj_file_base.1"; - if (system ($cmd)) { $fehler_count++; } - $cmd = "cat $cfg_dir/$obj_file_base.1 >> $cfg_dir/$obj_file_base"; - if (system ($cmd)) { $fehler_count++; } - $cmd = "echo \"}\" >> $cfg_dir/$obj_file_base"; - if (system ($cmd)) { $fehler_count++; } - $cmd = "$scp_bin $scp_batch_mode_switch -i $workdir/$CACTUS::FWORCH::ssh_id_basename $ssh_user\@$ssh_hostname:junos_config $cfg_dir/$obj_file_base.1"; - if (system ($cmd)) { $fehler_count++; } - $cmd = "cat $cfg_dir/$obj_file_base.1 >> $cfg_dir/$obj_file_base"; - if (system ($cmd)) { $fehler_count++; } - $cmd = "rm $cfg_dir/$obj_file_base.1"; - if (system ($cmd)) { $fehler_count++; } - } else { - if (system ("echo \"applications {\" > $cfg_dir/$obj_file_base")) { $fehler_count++; } - $cmd = "$ssh_bin -i $workdir/$CACTUS::FWORCH::ssh_id_basename $ssh_user\@$ssh_hostname show configuration groups junos-defaults applications > $cfg_dir/$obj_file_base.1"; - if (system ($cmd)) { $fehler_count++; } - if (system ("cat $cfg_dir/$obj_file_base.1 >> $cfg_dir/$obj_file_base")) { $fehler_count++; } - if (system ("echo \"}\" >> $cfg_dir/$obj_file_base")) { $fehler_count++; } - $cmd = "$ssh_bin -i $workdir/$CACTUS::FWORCH::ssh_id_basename $ssh_user\@$ssh_hostname show config > $cfg_dir/$obj_file_base.1"; - if (system ($cmd)) { $fehler_count++; } - if (system ("cat $cfg_dir/$obj_file_base.1 >> $cfg_dir/$obj_file_base")) { $fehler_count++; } - if (system ("rm $cfg_dir/$obj_file_base.1")) { $fehler_count++; } - } - return ($fehler_count, "$cfg_dir/$obj_file_base" ); -} - -sub sort_rules_and_add_zone_headers { - my $anzahl_regeln; - my $count; - my $zone_string; - my @rule_zones = (); - - # Nachbereitung Regeln: Sortierung nach a) Zonen b) $ruleorder - if (!defined($rulebases{"$rulebase_name.rulecount"})) { - $anzahl_regeln = 0; - } else { - $anzahl_regeln = $rulebases{"$rulebase_name.rulecount"}; - } - for ($count=0; $count<$anzahl_regeln; $count++) { - $zone_string = $rulebases{"$rulebase_name.$ruleorder[$count].src.zone"}; - $zone_string .= " : "; - $zone_string .= $rulebases{"$rulebase_name.$ruleorder[$count].dst.zone"}; - push @rule_zones, $zone_string - } - my @idx = (); - my $item; - for (@rule_zones) { - ($item) = $_; - push @idx, $item; - } - - @ruleorder = @ruleorder[ sort { $idx[$a] cmp $idx[$b] } 0 .. $anzahl_regeln-1 ]; - @rule_zones = @rule_zones[ sort { $idx[$a] cmp $idx[$b] } 0 .. $anzahl_regeln-1 ]; - - # Nachbereitung Regeln: Header-Regeln vor Zonenwechsel einfuegen - my $new_zone_string; - my $old_zone_string = ""; - my $rule_header_count = 1; - my $rule_header_offset = &CACTUS::read_config::read_config('rule_header_offset') * 1; - my $new_rule_id; - for ($count = 0; $count < $anzahl_regeln; $count++) { - $new_zone_string = $rule_zones[$count]; - if ($new_zone_string ne $old_zone_string) { # insert header rule - $new_rule_id = $rule_header_offset+$rule_header_count++; - (my $src_zone, my $dst_zone) = split / : /, $new_zone_string; - splice(@ruleorder,$count,0,$new_rule_id); # fuegt neue Regel ein - splice(@rule_zones,$count,0,$new_zone_string); - $anzahl_regeln++; - $rulebases{"$rulebase_name.rulecount"} = $anzahl_regeln; - $rulebases{"$rulebase_name.$ruleorder[$count].id"} = $new_rule_id; - $rulebases{"$rulebase_name.$ruleorder[$count].header_text"} = $new_zone_string; - $rulebases{"$rulebase_name.$ruleorder[$count].UID"} = $new_rule_id; - $rulebases{"$rulebase_name.$ruleorder[$count].src"} = "any"; - $rulebases{"$rulebase_name.$ruleorder[$count].dst"} = "any"; - $rulebases{"$rulebase_name.$ruleorder[$count].services"} = "any"; - $rulebases{"$rulebase_name.$ruleorder[$count].action"} = "deny"; - $rulebases{"$rulebase_name.$ruleorder[$count].src.zone"} = $src_zone; - $rulebases{"$rulebase_name.$ruleorder[$count].dst.zone"} = $dst_zone; - $rulebases{"$rulebase_name.$ruleorder[$count].disabled"} = '0'; - $rulebases{"$rulebase_name.$ruleorder[$count].src.op"} = '0'; - $rulebases{"$rulebase_name.$ruleorder[$count].dst.op"} = '0'; - $rulebases{"$rulebase_name.$ruleorder[$count].services.op"} = '0'; - } - $old_zone_string = $new_zone_string; - } -} - -sub parse_mgm_name { # ($obj_file, $fworch_workdir, $debug_level, $mgm_name, $config_dir, $import_id) - my $in_file_main = shift; - my $fworch_workdir = shift; - my $debuglevel_main = shift; - my $mgm_name = shift; - my $config_dir = shift; - my $import_id = shift; - my $line = ''; - my $context = ''; - my @nodes= (); - - &print_debug("entering parse_mgm_name",$debuglevel_main,2); - NEW_LINE: foreach $line (@config_lines) { - chomp($line); -# parsing device name(s) - if ($line=~ /^\s+host\-name\s+(.+?)\;$/ && ($context eq 'groups/node/system' || $context eq 'system')) { - $mgm_name = $1; - @nodes = ($mgm_name, @nodes); - &print_debug("parse_mgm_name: found hostname: $mgm_name",$debuglevel_main,1); - next NEW_LINE; - } - # cluster node - if ($line =~ /^groups\s\{$/ && $context eq '') { $context = 'groups'; next NEW_LINE; } - if ($line =~ /^\s+node(\d+)\s\{$/ && $context eq 'groups') { $context .= "/node"; next NEW_LINE; } - if ($line =~ /^\s+system\s\{$/ && $context eq 'groups/node') { $context .= "/system"; &print_debug("found system line: $line",$debuglevel_main,5); next NEW_LINE; } - if ($line=~ /^\}$/ && $context eq 'groups/node/system') { # in case of cluster: add both node names to make up the cluster name - $context = ''; - $mgm_name = join('_', sort (@nodes)); - @rulebases = ($mgm_name); - $rulebase_name = $mgm_name; - &print_debug("parse_mgm_name: found hostname combined: $mgm_name and setting rulebase_name to $mgm_name",$debuglevel_main,1); - return $mgm_name; - } - # single node - if ($line =~ /^system\s\{$/ && $context eq '') { $context = "system"; &print_debug("found system line: $line",$debuglevel_main,5); next NEW_LINE; } - if ($line=~ /^\}$/ && $context eq 'system') { # in case of single system - $context = ''; - @rulebases = ($mgm_name); - $rulebase_name = $mgm_name; - &print_debug("parse_mgm_name: found hostname of single system: $mgm_name and setting rulebase_name to $mgm_name",$debuglevel_main,1); - return $mgm_name; - } - } - &print_debug("ERROR: end of parse_mgm_name: at end without match (mgm_name=$mgm_name)",$debuglevel_main,-1); -} - -# the following function does only parse simple objects without groups. Groups are parsed in a second run using function parse_config_group_objects -sub parse_config_base_objects { # ($obj_file, $fworch_workdir, $debug_level, $mgm_name, $config_dir, $import_id) - my $in_file_main = shift; - my $fworch_workdir = shift; - my $debug = shift; - my $mgm_name = shift; - my $config_dir = shift; - my $import_id = shift; - my ($zone, $address_group_name, $obj_name, $obj_ip, $group_member_name, $application_name, $group_name, $group_members, $proto, $icmp_art, $icmp_nummer, - $source_port, $destination_port, $uuid, $members, $members_uid, $members_proto, $rpc, $comment); - my $line = ''; - my $context = ''; - my @nodes= (); - - &print_debug("entering parse_config_base_objects =======================================================",$debug,2); - NEW_LINE: foreach $line (@config_lines) { - chomp($line); - &print_debug("pcbo-line: $line", $debug, 9); -# if ($line =~ /^\s+\}$/ && $context eq 'security/address-book') { $context = &switch_context($context, 'security', $debug); next NEW_LINE; } -# if ($line =~ /^\s+\}$/ && $context eq 'security/address-book/global') { $context = &switch_context($context, 'security/address-book', $debug); next NEW_LINE; } -# if ($line=~ /^\}$/) { $context = &switch_context($context, '', $debug); next NEW_LINE; } -# if ($line=~ /^\}$/ && $context eq 'applications/application') { $context = &switch_context($context, 'applications', $debug); next NEW_LINE; } - if ($line=~ /^\}$/ && $context ne 'applications/application' && $context ne 'applications/application-set' - && $context ne'') { $context = &switch_context($context, '', $debug); next NEW_LINE; } - # added ne 'applications/application' to enable parsing of predefined services in the beginning of the file -# parsing zones - if ($line =~ /^security\s\{$/ && $context eq '') { $context = &switch_context($context, 'security', $debug); next NEW_LINE; } - if ($line =~ /^\s+zones\s\{$/ && $context eq 'security') { $context = &switch_context($context, 'security/zones', $debug); next NEW_LINE; } - if ($line =~ /^\s+address-book\s\{$/ && $context eq 'security') { $context = &switch_context($context, 'security/address-book', $debug); next NEW_LINE; } - if ($line =~ /^\s+global\s\{$/ && $context eq 'security/address-book') { - $context = &switch_context($context, 'security/address-book/global', $debug); - $zone = 'global'; - next NEW_LINE; - } -# if ($line=~ /^\s+security\-zone\s([\w\.\_\-]+)\s\{$/ && ($context eq 'security/zones' || $context eq 'security/zones/address-book')) { - if ($line=~ /^\s+security\-zone\s([\w\.\_\-]+)\s\{$/) { - $zone = $1; &add_zone ($zone, $debug); - print_debug("found zone $zone", $debug, 2); - next NEW_LINE; - } -# parsing network objects - if ($line=~ /^\s+address\-book\s\{$/ && $context eq 'security/zones') { $context = &switch_context($context, 'security/zones/address-book', $debug); next NEW_LINE; } - # old comment syntax /* xxx */ - if ($line=~ /^\s+\/\*\s(.*?)\s\*\/$/ && $context eq 'security/zones/address-book') { $comment = $1; next NEW_LINE; } - # new comment syntax description "xx yy zz"; - if ($line=~ /^\s+description\s\"?(.+?)\"?\;$/ && - ($context eq 'security/zones/address-book' || $context eq 'security/address-book/global' || $context eq 'applications/application')) { - $comment = $1; - print_debug("found comment $comment", $debug, 4); - next NEW_LINE; - } - # start of comment brackets (containing only obj name) - if ($line=~ /^\s+address\s(.+?)\s\{$/ && ($context eq 'security/zones/address-book' || $context eq 'security/address-book/global')) { - $obj_name = $1; - print_debug("found object name $obj_name", $debug, 4); - next NEW_LINE; - } - # ip address only within comment brackets - if ($line=~ /^\s+([\d\:\.\/]+)\;$/ && ($context eq 'security/zones/address-book' || $context eq 'security/address-book/global')) { - $obj_ip = $1; - print_debug("found object ip $obj_ip for obj $obj_name", $debug, 4); - next NEW_LINE; - } - if ($line=~ /^\s+\}$/ && ($context eq 'security/zones/address-book' || $context eq 'security/address-book/global')) { - if (defined($obj_name) && defined($obj_ip) && defined($comment)) { - print_debug("found obj $obj_name with ip $obj_ip in zone $zone; comment=$comment", $debug, 4); - &add_nw_obj ($obj_name, $obj_ip, $zone, $comment, $debug); - undef($obj_name); undef($obj_ip); undef($comment); - next NEW_LINE; - } - } - if ($line=~ /^\s+address\s(.+?)\s([\d\:\.\/]+)\;$/ && ($context eq 'security/zones/address-book' || $context eq 'security/address-book/global')) { - $obj_name = $1; - $obj_ip = $2; - print_debug("found obj $obj_name with ip $obj_ip in zone $zone", $debug, 4); - &add_nw_obj ($obj_name, $obj_ip, $zone, $comment, $debug); - undef($obj_name); undef($obj_ip); undef($comment); - next NEW_LINE; - } -# parsing network services (applications) - if ($line =~ /^applications\s\{$/ && $context eq '') { - $context = &switch_context($context, 'applications', $debug); - next NEW_LINE; - } - if ($line=~ /^\s*\/\*\s(.*?)\s\*\/$/ && $context eq 'applications') { $comment = $1; } - if ($line =~ /^\s*application\s(.+?)\s\{/ && $context eq 'applications') { - $application_name = $1; - print_debug("found application $application_name", $debug, 4); - $context = &switch_context($context, 'applications/application', $debug); - next NEW_LINE; - } - if ($line =~ /^\s*application\s(.+?)\sprotocol\s(.+?)\;$/ && $context eq 'applications') { # sonderfall: single-line-service-definition - $application_name = $1; - &add_nw_service_obj ($1, $2, '', '1-65535', '', '', '', '', $comment, $debug); - print_debug("found application $application_name in single line definition", $debug, 4); - undef ($comment); - next NEW_LINE; - } - if ($line =~ /^\s+protocol\s(\w+?)\;$/ && $context eq 'applications/application') { $proto = $1; next NEW_LINE;} - if ($line =~ /^\s+source-port\s(.+?)\;$/ && $context eq 'applications/application') { $source_port = $1; next NEW_LINE; } - if ($line =~ /^\s+destination-port\s(.+?)\;$/ && $context eq 'applications/application') { $destination_port = $1; next NEW_LINE; } - if ($line =~ /^\s+uuid\s(.+?)\;$/ && $context eq 'applications/application') { $uuid = $1; next NEW_LINE; } - if ($line =~ /^\s+rpc\-program\-number\s([\d\-]+?)\;$/ && $context eq 'applications/application') { $rpc = $1; next NEW_LINE;} - if ($line =~ /^\s+icmp\-(.+?)\s(\d+)\;$/ && $context eq 'applications/application') { $icmp_art = $1; $icmp_nummer = $2; next NEW_LINE; } - if ($line =~ /^\s*\}$/ && $context eq 'applications/application') { - # service wegschreiben - &print_debug("before calling add_nw_service_obj: for application $application_name", $debug, 5); - &add_nw_service_obj ($application_name, $proto, $source_port, $destination_port, $uuid, $rpc, $icmp_art, $icmp_nummer, $comment, $debug); - $context = &switch_context($context, 'applications', $debug); - undef($application_name); undef($proto); undef($source_port); undef($destination_port); undef($uuid); undef($rpc); undef($icmp_art); undef($icmp_nummer); - undef ($comment); - next NEW_LINE; - } - } - return 0; -} - - -sub parse_config_group_objects { # ($obj_file, $fworch_workdir, $debug_level, $mgm_name, $config_dir, $import_id) - my $in_file_main = shift; - my $fworch_workdir = shift; - my $debug = shift; - my $mgm_name = shift; - my $config_dir = shift; - my $import_id = shift; - my ($zone, $address_group_name, $obj_name, $obj_ip, $group_member_name, $application_name, $proto, $icmp_art, $icmp_nummer, $source_port, $destination_port, $uuid, $members, $members_uid, $members_proto, $rpc); - my $line = ''; - my $context = ''; - my $comment; - my @nodes= (); - - &print_debug("entering parse_config_group_objects =======================================================",$debug,2); - NEW_LINE: foreach $line (@config_lines) { - chomp($line); - &print_debug("pcgo-line: $line", $debug, 9); - if ($line=~ /^application\s/ && $context eq 'applications') { - $context = &switch_context($context, 'applications/application', $debug); next NEW_LINE; - } - if ($line=~ /^\}$/ && $context eq 'applications/application') { $context = &switch_context($context, 'applications', $debug); next NEW_LINE; } - if ($line=~ /^\}$/ && $context ne 'applications' && $context ne 'applications/application' && $context ne 'applications/application-set' - && $context ne '') { $context = &switch_context($context, '', $debug); next NEW_LINE; } -# if ($line=~ /^\}$/) { $context = &switch_context($context, '', $debug); next NEW_LINE; } -# parsing zones - if ($line =~ /^security\s\{$/ && $context eq '') { $context = &switch_context($context, 'security', $debug); next NEW_LINE; } - if ($line =~ /^\s+zones\s\{$/ && $context eq 'security') { $context = &switch_context($context, 'security/zones', $debug); next NEW_LINE; } - if ($line=~ /^\s+security\-zone\s([\w\.\_\-]+)\s\{$/ && ($context eq 'security/zones' || $context eq 'security/zones/address-book')) { - $zone = $1; - print_debug("entering zone $zone, context=$context", $debug, 4); - next NEW_LINE; - } -# parsing network objects - if ($line=~ /^\s+address\-book\s\{$/ && ($context eq 'security/zones')) { $context = &switch_context($context, 'security/zones/address-book', $debug); next NEW_LINE; } - if ($line=~ /^\s+address\-book\s\{$/ && ($context eq 'security' || $context eq 'security')) { - $context = &switch_context($context, 'security/address-book', $debug); next NEW_LINE; - } - if ($line=~ /^\s+(.+?)\s\{$/ && $context eq 'security/address-book') { - $zone = $1; - $context = &switch_context($context, "security/address-book/$zone", $debug); - next NEW_LINE; - } -# parsing network object groups - if ($line=~ /^\s+\/\*\s(.*?)\s\*\/$/ && $context eq 'security/zones/address-book') { $comment = $1; next NEW_LINE; } - if ($line=~ /^\s+address\-set\s(.+?)\s\{$/ && ($context eq 'security/zones/address-book' || $context eq 'security/address-book/global')) { - $address_group_name = $1; - print_debug("entering network obj group $address_group_name in zone $zone, context=$context", $debug, 4); - $context = &switch_context($context, 'security/zones/address-book/address-set', $debug); - next NEW_LINE; - } - if ($line=~ /^\s+description\s\"?(.+?)\"?\;$/ && ($context eq 'security/zones/address-book/address-set' || $context eq 'security/address-book/global')) { - $comment = $1; - next NEW_LINE; - } - if ($line=~ /^\s+address\s(.+?)\;$/ && $context eq 'security/zones/address-book/address-set') { - $group_member_name = $1; - print_debug("found address group member of group $address_group_name: $group_member_name in zone $zone", $debug, 4); - &add_nw_obj_group_member ($address_group_name, $group_member_name, $zone, $comment, $debug); - undef($group_member_name); undef($comment); - next NEW_LINE; - } - if ($line=~ /^\s+\}$/ && $context eq 'security/zones/address-book/address-set') { $context = &switch_context($context, 'security/zones/address-book', $debug); next NEW_LINE; } - if ($line=~ /^\}$/ && ($context =~ '^security')) { $context = &switch_context($context, '', $debug); next NEW_LINE; } -# parsing network services - if ($line =~ /^applications\s\{$/ && $context eq '') { $context = &switch_context($context, 'applications', $debug); next NEW_LINE; } -# parsing service groups - if ($line =~ /^\s*application\-set\s(.+?)\s\{$/ && $context eq 'applications') { - $application_name = $1; - $members = ''; - print_debug("found application-set $application_name", $debug, 6); - $context = &switch_context($context, 'applications/application-set', $debug); - next NEW_LINE; - } - if ($line =~ /^\s+application\s([\w\-\.\_]+?)\;/ && $context eq 'applications/application-set') { - if ($members ne '') { $members .= '|'; } - $members .= "$1"; - print_debug("found application $1 in application-set $application_name", $debug, 6); - next NEW_LINE; - } -# parsing term quasi service groups - if ($line =~ /^\s+application\s(.+?)\s\{/ && $context eq 'applications') { - $application_name = $1; - print_debug("found application $application_name", $debug, 4); - $context = &switch_context($context, 'applications/application', $debug); - next NEW_LINE; - } - if ($line =~ /^\s+term\sterm0\sprotocol\s(\w+?)\suuid\s(.+?)\;$/ && $context eq 'applications/application') { # parse this line twice! - $members = ''; $members_uid = ''; $members_proto = ''; - $context = &switch_context($context, 'applications/application-set', $debug); - print_debug("pcgo: found term, switchting to group mode ($application_name)", $debug, 6); - } - if ($line =~ /^\s+term\sterm\d+\sprotocol\s\w+\suuid\s(.+?)\;$/ && $context eq 'applications/application-set') { - my $term_uuid = $1; - if (defined($junos_uuids{"$term_uuid"})) { - print_debug("pcgo: found single resolvable uuid ref (group: $application_name, uuid: $term_uuid) for application " . $junos_uuids{"$term_uuid"}, $debug, 6); - if ($members ne '') { $members .= '|'; } - $members .= $junos_uuids{"$term_uuid"}; - } else { - print_debug("pcgo: ignoring unresolvable uuid ref ($application_name): $term_uuid", $debug, 6); - } - next NEW_LINE; - } - if ($line =~ /^\s*\}$/ && $context eq 'applications/application') { $context = &switch_context($context, 'applications', $debug); } # ignore simple applications - if ($line =~ /^\s*\}$/ && $context eq 'applications/application-set') { - $context = &switch_context($context, 'applications', $debug); - # service group wegschreiben - &add_nw_service_obj_grp ($application_name, $members, $comment, $debug); - undef($comment); - next NEW_LINE; - } - if ($line =~ /^\}$/ && $context eq 'applications') { $context = &switch_context($context, '', $debug); next NEW_LINE; } - } - return 0; -} - -sub cfg_file_complete { # check auf Vollstaendigkeit des Config-Files: - my $debug_level = shift; - my $ln_cnt = $#config_lines; - my $cfg_file_complete = 1; - - while ($config_lines[$ln_cnt] =~ /^\s*$/ ) { $ln_cnt -- ; } # ignore empty lines at the end - if ($config_lines[$ln_cnt] !~ /^\s*\{primary\:node\d+\}$/ && $config_lines[$ln_cnt] !~ /^\}$/) { - $cfg_file_complete = 0; - print_debug ("ERROR: expected last line to contain either primary node info or top level curly bracket. Instead got: " . $config_lines[$ln_cnt], $debug_level, -1); - } - return $cfg_file_complete; -} - -sub switch_context { - my $old_level = shift; - my $new_level = shift; - my $debug_level = shift; - print_debug("switching context from $old_level to $new_level", $debug_level, 8); - return $new_level; -} - - sub parse_config_rules { # ($in_file_main, $fworch_workdir, $debuglevel_main, $mgm_name_in_config, $config_dir, $import_id) - my $in_file_main = shift; - my $fworch_workdir = shift; - my $debug = shift; - my $mgm_name = shift; - my $config_dir = shift; - my $import_id = shift; - my ($zone, $action, $source, $destination, $application, $from_zone, $to_zone, $policy_name, $disabled, $track); - my $line = ''; - my $context = ''; - my $rule_no = 0; - my $list; - my $list_typ; - my $comment; - - &print_debug("entering parse_config_rules =======================================================",$debug,2); - NEW_LINE: foreach $line (@config_lines) { - chomp($line); - &print_debug("pcr: $line", $debug, 9); -# rules start - if ($line =~ /^security\s\{$/ && $context eq '') { $context = &switch_context($context, 'security', $debug); next NEW_LINE; } - if ($line =~ /^\s+policies\s\{$/ && $context eq 'security') { $context = &switch_context($context, 'security/policies', $debug); next NEW_LINE; } - if ($line=~ /^\s+from\-zone\s(.+?)\sto\-zone\s(.+?)\s\{$/ && $context eq 'security/policies') { - $context = &switch_context($context, 'security/policies/zone', $debug); - $from_zone = $1; - $to_zone = $2; - &print_debug("entering policy from zone $from_zone to zone $to_zone",$debug,2); - next NEW_LINE; - } - if ($line=~ /^\s+\/\*\s(.*?)\s\*\/$/ && $context eq 'security/policies/zone') { $comment = $1; } -# if ($line=~ /^\s+\#\s(.*)$/ && $context eq 'security/policies/zone') { $comment = $1; } - if ($line=~ /^\s+(inactive)?\:?\s?policy\s(.+?)\s\{$/ && $context eq 'security/policies/zone') { - $disabled = $1; if (!defined($disabled)) { $disabled = ''; } - $policy_name = $2; - $context = &switch_context($context, 'security/policies/zone/policy', $debug); - &print_debug("entering policy $policy_name (zone $from_zone to $to_zone)",$debug,2); - next NEW_LINE; - } -# match part of rule - # new comment syntax description "xx yy zz"; - if ($line=~ /^\s+description\s\"?(.+?)\"?\;$/ && $context eq 'security/policies/zone/policy') { - $comment = $1; - print_debug("found rule comment $comment", $debug, 4); - next NEW_LINE; - } - - if ($line=~ /^\s+match\s\{$/ && $context eq 'security/policies/zone/policy') { $context = &switch_context($context, 'security/policies/zone/policy/match', $debug); next NEW_LINE; } - if ($line =~ /^\s+(source|destination)\-address\s(.+?)\;?$/ && $context eq 'security/policies/zone/policy/match') { - $list_typ = $1; - $list = $2; - if ($list_typ eq 'source') { $source = $list; } - if ($list_typ eq 'destination') { $destination = $list; } -# &print_debug("pcr: nw-list=$list", $debug, 9); - if ($list =~ /^\[/ && $list !~ /\]$/) { $context = &switch_context($context, "security/policies/zone/policy/match/$list_typ", $debug); } - next NEW_LINE; - } - if ($line =~ /^\s+application\s(.+?)\;?$/ && $context eq 'security/policies/zone/policy/match') { - $application = $1; -# &print_debug("pcr: appl-list=$application", $debug, 9); - if ($application =~ /^\[/ && $application !~ /\]$/) { $context = &switch_context($context, 'security/policies/zone/policy/match/application', $debug); } - next NEW_LINE; - } - if ($line=~ /^\s+\}$/ && $context eq 'security/policies/zone/policy/match') { $context = &switch_context($context, 'security/policies/zone/policy', $debug); next NEW_LINE; } -# dealing with multiple source, destination or application lines of rules - if ($context =~ /^security\/policies\/zone\/policy\/match\/(\w+)$/) { - $list_typ = $1; - my $multi_line; - if ($line =~ /\s*(.*?)\;?$/) { $multi_line = $1; } - if ($list_typ eq 'source') { $source .= " $multi_line"; } - if ($list_typ eq 'destination') { $destination.= " $multi_line"; } - if ($list_typ eq 'application') { $application .= " $multi_line"; } - if ($multi_line =~ /\]$/) { $context = &switch_context($context, "security/policies/zone/policy/match", $debug); undef($list_typ); undef($list); } # last line reached - next NEW_LINE; - } - -# action / track part of rule (then) - if ($line=~ /^\s+then\s\{$/ && $context eq 'security/policies/zone/policy') { $context = &switch_context($context, 'security/policies/zone/policy/action', $debug); next NEW_LINE; } - if ($line=~ /^\s+(permit|deny|reject)\;$/ && $context eq 'security/policies/zone/policy/action') { $action = $1; next NEW_LINE; } - if ($line=~ /^\s+(permit|deny|reject)\s\{$/ && $context eq 'security/policies/zone/policy/action') { - $action = $1; - $context = &switch_context($context, 'security/policies/zone/policy/action/action_parameter', $debug); - next NEW_LINE; - } # ignoring further action parameters - if ($line=~ /^\s+(log|count)\s\{$/ && $context eq 'security/policies/zone/policy/action') { - my $found_track = $1; - if (!defined($track) || $track eq '') { $track = $found_track; } - elsif ($found_track eq 'count' && $track eq 'log') { $track = 'log count'; } - $context = &switch_context($context, 'security/policies/zone/policy/action/action_parameter', $debug); - next NEW_LINE; - } # ignoring further tracking parameters -=cut - track=log wird in diesem Fall nicht gefunden: - permit { - destination-address { - drop-untranslated; - } - } - log { - session-close; - } -=cut - if ($line=~ /^\s+.+?\{$/ && $context eq 'security/policies/zone/policy/action/action_parameter') { - $context = &switch_context($context, 'security/policies/zone/policy/action/action_parameter/null', $debug); - next NEW_LINE; - } -#closing sections - if ($line=~ /^\s+.+?\{$/ && $context eq 'security/policies/zone/policy/action/action_parameter/null') { - $context = &switch_context($context, 'security/policies/zone/policy/action/action_parameter', $debug); - next NEW_LINE; - } - if ($line=~ /^\s+\}$/ && $context eq 'security/policies/zone/policy/action/action_parameter') { $context = &switch_context($context, 'security/policies/zone/policy/action', $debug); next NEW_LINE; } - if ($line=~ /^\s+\}$/ && $context eq 'security/policies/zone/policy/action') { $context = &switch_context($context, 'security/policies/zone/policy', $debug); next NEW_LINE; } - if ($line=~ /^\s+\}$/ && $context eq 'security/policies/zone/policy') { - if (!defined($track)) { $track=''; } - &print_debug("found rule from $from_zone to $to_zone, name=$policy_name, disabled=$disabled: src=$source, dst=$destination, svc=$application, action=$action, track=$track",$debug,2); - # Regel wegschreiben - $rule_no = &add_rule ($rule_no, $from_zone, $to_zone, $policy_name, $disabled, $source, $destination, $application, $action, $track, $comment, $debug); - $context = &switch_context($context, 'security/policies/zone', $debug); - $track = ''; undef($policy_name); undef($comment); - next NEW_LINE; - } # end of rule - if ($line=~ /^\s+\}$/ && $context eq 'security/policies/zone') { $context = switch_context($context, 'security/policies', $debug); undef($from_zone); undef($to_zone); next NEW_LINE; } - if ($line=~ /^\s+\}$/ && $context eq 'security/policies') { $context = &switch_context($context, 'security', $debug); next NEW_LINE; } - if ($line=~ /^\}$/) { $context = &switch_context($context, '', $debug); next NEW_LINE; } - } - &sort_rules_and_add_zone_headers (); - $rulebases{"$rulebase_name.ruleorder"} = join(',', @ruleorder); - return 0; - } - -##################################################################################### -# MAIN - -sub parse_config { # ($obj_file, $rule_file, $rulebases, $user, $fworch_workdir, $debug_level, $mgm_name, $config_dir, $import_id) - my $in_file_main = shift; - shift; shift; shift; # $rule_file und $rulebases und $user nicht verwendet - my $fworch_workdir = shift; - my $debuglevel_main = shift; - my $mgm_name = shift; - my $config_dir = shift; - my $import_id = shift; - my $debug_level = shift; - - # initializing global variables: - @services = (); - @network_objects = (); - &print_debug ("in_file_main=$in_file_main, fworch_workdir=$fworch_workdir, debuglevel_main=$debuglevel_main, mgm_name=$mgm_name, config_dir=$config_dir, import_id=$import_id", $debuglevel_main, 6); - - open (IN, $in_file_main) || die "$in_file_main konnte nicht geoeffnet werden.\n"; - @config_lines = ; # sichern Config-array fuer spaetere Verwendung - close (IN); - - if (!&cfg_file_complete($debuglevel_main)) { return "incomplete-config-file-$mgm_name"; } - else { - my $device_type=8; # junos 10.x fest gesetzt # move to config - &read_predefined_services($device_type, $debuglevel_main); # schreibt die predefined services in @services und %services - my $mgm_name_in_config = &parse_mgm_name($in_file_main, $fworch_workdir, $debuglevel_main, $mgm_name, $config_dir, $import_id); - &parse_config_base_objects ($in_file_main, $fworch_workdir, $debuglevel_main, $mgm_name, $config_dir, $import_id); # zones, simple network and service objects - push @zones, "global"; # Global Zone immer hinzufuegen - foreach my $zone (@zones) { object_address_add("any", "0.0.0.0", "0.0.0.0", $zone, "any-obj for zone $zone added by fworch"); &print_debug(""); } # Any-Objekte fuer alle Zonen einfuegen - &parse_config_group_objects ($in_file_main, $fworch_workdir, $debuglevel_main, $mgm_name, $config_dir, $import_id); # groups are parsed in separate cycle to ensure that all base objects are complete -# &resolve_service_uuid_references ($debuglevel_main); - &parse_config_rules ($in_file_main, $fworch_workdir, $debuglevel_main, $mgm_name_in_config, $config_dir, $import_id); # finally parsing the rule base, ignoring the rulebase name in fworch config - - &print_results_files_objects($fworch_workdir, $mgm_name, $import_id); - &print_results_files_rules ($fworch_workdir, $mgm_name, $import_id); - &print_results_files_zones ($fworch_workdir, $mgm_name, $import_id); -# print_results_monitor('objects'); -# print_results_monitor('rules'); - } - return 0; -} - -1; -__END__ - -=head1 NAME - -CACTUS::FWORCH::parser - Perl extension for JunOS parser - -=head1 SYNOPSIS - - use CACTUS::FWORCH::import::juniper; - -=head1 DESCRIPTION - -fworch Perl Module support for importing configs into fworch Database - -=head2 EXPORT - - global variables - - -=head1 SEE ALSO - - behind the door - -=head1 AUTHOR - - Cactus eSecurity, tmp@cactus.de - -=cut diff --git a/roles/importer/files/importer/CACTUS/FWORCH/import/netscreen.pm b/roles/importer/files/importer/CACTUS/FWORCH/import/netscreen.pm deleted file mode 100644 index 5f44d0d406..0000000000 --- a/roles/importer/files/importer/CACTUS/FWORCH/import/netscreen.pm +++ /dev/null @@ -1,1147 +0,0 @@ -package CACTUS::FWORCH::import::parser; - -use strict; -use warnings; -use Time::HiRes qw(time); # fuer hundertstelsekundengenaue Messung der Ausfuehrdauer -use CACTUS::FWORCH; -use CACTUS::FWORCH::import; -use CACTUS::read_config; -# use Scalar::Util; - -require Exporter; -our @ISA = qw(Exporter); - -our %EXPORT_TAGS = ( 'basic' => [ qw( ©_config_from_mgm_to_iso &parse_config ) ] ); - -our @EXPORT = ( @{ $EXPORT_TAGS{'basic'} } ); -our $VERSION = '0.3'; - -our @config_lines; # array der Zeilen des Config-Files im Originalzustand (kein d2u etc.) -our $parser_mode; # Typ des Config-Formates (basic, data) -our $rule_order = 0; # Reihenfolge der Rules im Configfile -our $rulebase_name; - -## parse_audit_log Funktion fuer netscreen noch nicht implementiert - -sub parse_audit_log { } - -###################################### -# remove_unwanted_chars -# param1: debuglevel [0-?] -# gobal var in and out: @config_lines -##################################### -sub remove_unwanted_chars { - my $debuglevel = shift; - my $line; - my @cleaned_lines = (); - - LINE: foreach $line (@config_lines) { - if ($line =~ /^\s*$/) { # ignore empty lines - } else { # remove non-printable characters - my $line_orig = $line; - $line =~ s/[^[:print:]]+//g; - if ($line =~ /^\s+(.+?)$/) { $line = $1; } - if ($line =~ /^(.+?)\s+$/) { $line = $1; } - $line .= "\n"; - @cleaned_lines = (@cleaned_lines, "$line"); -# if ($line_orig ne $line) { print ("cleaned config line containing non-printable characters.\nOriginal line: $line_orig to: $line"); } - } - } - @config_lines = @cleaned_lines; -} - -###################################### -# ns_mode_check -# bestimmt den Typ des Config-Formates -# param1: input-filename -# param2: debuglevel [0-?] -##################################### -sub ns_mode_check { - my $debuglevel = shift; - my $mode = ''; - my $line_num_for_check = 10; # number of lines for testing the config format - my $i = 0; - # Setzen des Parsermodes - # umschalten des Betriebsmodus anhand der ersten $line_num_for_check Zeile des uebergebenen Konfigurationsfiles - MODE_DEF: { - for ($i = 0; $i < $line_num_for_check; ++$i) { - if ($config_lines[$i]=~/^u?n?set\s/) { - $mode = 'basic'; - last MODE_DEF; - } - elsif ($config_lines[$i]=~/^\(DM/) { - $mode = 'data'; - last MODE_DEF; - } - else { - if ($mode !~ /basic/ or /data/) { - $mode = 'unknown'; - } - } - if ($debuglevel >= 7){ - print ("sub ns_mode_check line_$i, mode: $mode : $config_lines[$i]\n"); - } - } - $parser_mode = $mode; - if ($mode =~/unknown/) { - print "unknown format in config file - exiting!\n"; - return 1; - } - } - if ($debuglevel >= 1){ - print ("sub ns_mode_check line_$i, mode: $mode : $config_lines[$i]\n"); - } - return 0; -} - - -##################################### -# is_domain_name -# param1: string -# returns true if string is domain name and no ip -##################################### -sub is_domain_name { - my @parts = split(/\./, shift); - if (scalar(@parts) > 1) { - if (Scalar::Util::looks_like_number($parts[$#parts])) { - return 0; - } else { - return 1; - } - } - return 0; -} - -##################################### -# split_lines_to_parameter -# param1: input-line -# param2: debuglevel [0-?] -# Separator=space, Strings in double quotes -##################################### -sub split_lines_to_parameter { - my $line = $_[0]; - my $debuglevel = $_[1]; - my $i=0; - my $l=0; - my $k=$i; - my @params; - my @parameter = (); - - $parameter[$k] =''; - $line =~ s/\n//; - $line =~ s/\r//; - @params = split (/ /,$line); - while ($i <= $#params) { - if ($params[$i] =~ /^".+"$/) { - $parameter[$k] = "$params[$i]"; - $parameter[$k] =~ s/"//g; - $k++; - $i++; - } - elsif ($params[$i] =~ /^"/) { - do { - if (defined($parameter[$k])) { - $parameter[$k] = "$parameter[$k] $params[$i]"; - } else { - $parameter[$k] = "$params[$i]"; - } - } - while ($params[$i++] !~ /"$/ and $i <= $#params); - $parameter[$k] =~ s/^\s//; - $parameter[$k] =~ s/"//g; - $k++; - } - else { - $parameter[$k] = "$params[$i]"; - $k++; - $i++; - } - } - @parameter = @parameter; -} - - -##################################### -# ns_object_address -# param1: input-line -# param2: debuglevel [0-?] -##################################### -sub ns_object_address { - my $line = $_[0]; - my $debuglevel = $_[1]; - my $i=0; - my $l=0; - my @params; - my $act_obj_zone = ''; - my $act_obj_name = ''; - my $act_obj_nameZ = ''; - my $act_obj_ipaddr = ''; - my $act_obj_ipaddr_last = ''; - my $act_obj_mask = ''; - my $act_obj_comm = ''; - my $act_obj_type = ''; - my $act_obj_loc = ''; - my $act_obj_color = 'black'; - my $act_obj_sys = ''; - my $act_obj_uid = ''; - my $test = ''; - - @params = split_lines_to_parameter ($line,$debuglevel); - $act_obj_zone = $params[2]; - $act_obj_name = $params[3]; - $act_obj_ipaddr = $params[4]; - $act_obj_mask = $params[5]; - if ($params[6]) { - $act_obj_comm = $params[6]; - } else { - if (defined($act_obj_mask) && $act_obj_mask !~ /\d+\.\d+\.\d+\.\d+/) { # 5. Parameter ist keine Netzmask, sondern Kommentar (bei v6-Objekten) - $act_obj_comm = $act_obj_mask; - ($test, $act_obj_mask) = split(/\//, $act_obj_ipaddr); - } - } - if (&is_domain_name($act_obj_ipaddr)) { - if (!defined($act_obj_comm) || $act_obj_comm eq '') { - $act_obj_comm = "domain object: $act_obj_ipaddr"; - } else { - $act_obj_comm .= ", domain object: $act_obj_ipaddr"; - } - $act_obj_ipaddr = '0.0.0.1/32'; - } - - $act_obj_nameZ = "${act_obj_name}__zone__$act_obj_zone"; # Zone in Feldindex mit aufgenommen - OBJECT_DEF_GROUP: { - if (!defined ($network_objects{"$act_obj_nameZ.name"})) { - @network_objects = (@network_objects, $act_obj_nameZ); - $network_objects{"$act_obj_nameZ.name"} = $act_obj_name; - $network_objects{"$act_obj_nameZ.UID"} = $act_obj_nameZ; - if ($debuglevel >= 5){ print "ns_object_address: found new network object $act_obj_name\n"; } - } - else { - last OBJECT_DEF_GROUP; - } - } - my $is_ipv6 = ($act_obj_ipaddr =~ /\:/); - my $subnetbits; - if ($is_ipv6) { - if (defined($act_obj_mask)) { - $subnetbits = $act_obj_mask; - } else { - my $addr; - ($addr, $subnetbits) = split (/\//, $act_obj_ipaddr); - if (!defined($subnetbits)) { - $subnetbits = 128; - } - } - } else { - $subnetbits = &calc_subnetmask ($act_obj_mask); - } -# print ("debug: ip_addr = $act_obj_ipaddr, mask=$act_obj_mask, subnetbits = $subnetbits\n"); - if (!$is_ipv6) { - if (!defined($act_obj_mask)) { - $act_obj_mask = '255.255.255.255'; - } - if (!defined($subnetbits) || $subnetbits==32) { $network_objects{"$act_obj_nameZ.type"} = 'host'; } - else { $network_objects{"$act_obj_nameZ.type"} = 'network'; } - } else { - if ($subnetbits==128) { $network_objects{"$act_obj_nameZ.type"} = 'host'; } - else { $network_objects{"$act_obj_nameZ.type"} = 'network'; } - } - $network_objects{"$act_obj_nameZ.netmask"} = $act_obj_mask ; - $network_objects{"$act_obj_nameZ.zone"} = $act_obj_zone; # neues Feld fuer Zone - $network_objects{"$act_obj_nameZ.ipaddr"} = $act_obj_ipaddr; - $network_objects{"$act_obj_nameZ.ipaddr_last"} = $act_obj_ipaddr_last; - $network_objects{"$act_obj_nameZ.color"} = $act_obj_color; - $network_objects{"$act_obj_nameZ.comments"} = $act_obj_comm; - $network_objects{"$act_obj_nameZ.location"} = $act_obj_loc; - $network_objects{"$act_obj_nameZ.sys"} = $act_obj_sys; -} - -##################################### -# ns_object_address_add -# param1: name -# param2: ip -##################################### -sub ns_object_address_add { - my $act_obj_name = $_[0]; - my $act_obj_ipaddr = $_[1]; - my $act_obj_mask = $_[2]; - my $act_obj_zone = $_[3]; - my $act_obj_comm = $_[4]; - my @params; - my $act_obj_nameZ = ''; - my $act_obj_ipaddr_last = ''; - my $act_obj_type = 'simple'; - my $act_obj_loc = ''; - my $act_obj_color = 'black'; - my $act_obj_sys = ''; - my $act_obj_uid = ''; - my $subnetbits; - - $act_obj_nameZ = "${act_obj_name}__zone__$act_obj_zone"; # Zone in Feldindex mit aufgenommen - if (!defined ($network_objects{"$act_obj_nameZ.name"})) { - @network_objects = (@network_objects, $act_obj_nameZ); - $network_objects{"$act_obj_nameZ.name"} = $act_obj_name; - } elsif (defined ($network_objects{"$act_obj_nameZ.name"})) { - print "sub ns_object_address NET_OBJECT: $act_obj_nameZ ist bereits definiert.\n"; - } else { - print "sub ns_object_address NET_OBJECT: $act_obj_nameZ ist undefiniert.\n"; - } - my $is_ipv6 = ($act_obj_ipaddr =~ /\:/); - if ($is_ipv6) { - if (defined($act_obj_mask)) { - $subnetbits = $act_obj_mask; - } else { - $subnetbits = 128; - } - } else { - $subnetbits = &calc_subnetmask ($act_obj_mask); - } - if (!$is_ipv6) { - if (!defined($act_obj_mask)) { - $act_obj_mask = '255.255.255.255'; - } - if ($subnetbits==32) { $network_objects{"$act_obj_nameZ.type"} = 'host'; } - else { $network_objects{"$act_obj_nameZ.type"} = 'network'; } - } else { - if ($subnetbits==128) { $network_objects{"$act_obj_nameZ.type"} = 'host'; } - else { $network_objects{"$act_obj_nameZ.type"} = 'network'; } - } - if (&is_domain_name($act_obj_ipaddr)) { - if (!defined($act_obj_comm) || $act_obj_comm eq '') { - $act_obj_comm = "domain object: $act_obj_ipaddr"; - } else { - $act_obj_comm .= ", domain object: $act_obj_ipaddr"; - } - $act_obj_ipaddr = '0.0.0.1/32'; - } - - $network_objects{"$act_obj_nameZ.netmask"} = $act_obj_mask ; - $network_objects{"$act_obj_nameZ.zone"} = $act_obj_zone; # neues Feld fuer Zone - $network_objects{"$act_obj_nameZ.ipaddr"} = $act_obj_ipaddr; - $network_objects{"$act_obj_nameZ.ipaddr_last"} = $act_obj_ipaddr_last; - $network_objects{"$act_obj_nameZ.color"} = $act_obj_color; - $network_objects{"$act_obj_nameZ.comments"} = $act_obj_comm; - $network_objects{"$act_obj_nameZ.location"} = $act_obj_loc; - $network_objects{"$act_obj_nameZ.sys"} = $act_obj_sys; - $network_objects{"$act_obj_nameZ.UID"} = $act_obj_nameZ; -} - -##################################### -# ns_object_group_address -# param1: input-line -# param2: debuglevel [0-?] -##################################### -sub ns_object_group_address { - my $line = $_[0]; - my $debuglevel = $_[1]; - my $i=0; - my $l=0; - my @params; - my $act_obj_zone = ''; - my $act_obj_name = ''; - my $act_obj_nameZ = ''; - my $act_obj_mbr = ''; - my $act_obj_fkt = ''; - my $act_obj_color = 'black'; - my $act_obj_comm = ''; - my $mbrlst = ''; - my $mbr_ref_lst = ''; - - @params = split_lines_to_parameter ($line,$debuglevel); - $act_obj_zone = $params[3]; - $act_obj_name = $params[4]; - if ($params[6]) { $act_obj_mbr = $params[6]; } - if ($params[5]) { $act_obj_fkt = $params[5]; } - - $act_obj_nameZ = "${act_obj_name}__zone__$act_obj_zone"; # Zone in Feldindex mit aufgenommen - OBJECT_DEF: { - if (!defined ($network_objects{"$act_obj_nameZ.name"})) { - if ($debuglevel >= 5){ print "ns_object_group_address: found new network object group $act_obj_name\n"; } - @network_objects = (@network_objects, $act_obj_nameZ); - $network_objects{"$act_obj_nameZ.name"} = $act_obj_name; - $network_objects{"$act_obj_nameZ.UID"} = $act_obj_nameZ; - } - else { - last OBJECT_DEF; - } - } - $network_objects{"$act_obj_nameZ.zone"} = $act_obj_zone; # neues Feld fuer Zone - $network_objects{"$act_obj_nameZ.type"} = 'group'; - $network_objects{"$act_obj_nameZ.color"} = $act_obj_color; - if ( $act_obj_fkt =~ /add/ ) { - if (defined($network_objects{"$act_obj_nameZ.members"})) { - $mbrlst = $network_objects{"$act_obj_nameZ.members"}; - $mbr_ref_lst = $network_objects{"$act_obj_nameZ.member_refs"}; - } - if ( $mbrlst eq '' ) { - $mbrlst = $act_obj_mbr; - $mbr_ref_lst = $act_obj_mbr . "__zone__$act_obj_zone"; - } - else { - $mbrlst = "$mbrlst|$act_obj_mbr"; - $mbr_ref_lst = "$mbr_ref_lst|$act_obj_mbr" . "__zone__$act_obj_zone"; - } - $network_objects{"$act_obj_nameZ.members"} = $mbrlst; - $network_objects{"$act_obj_nameZ.member_refs"} = $mbr_ref_lst; - } -} - -##################################### -# ns_object_service -# param1: input-line -# param2: debuglevel [0-?] -##################################### -sub ns_object_service { - my $line = $_[0]; - my $debuglevel = $_[1]; - my $i=0; - my $l=0; - my @params; - my @range; - my $act_obj_typ = ''; - my $act_obj_type = ''; - my $act_obj_name = ''; - my $act_obj_proto = ''; - my $act_obj_src = ''; - my $act_obj_src_last = ''; - my $act_obj_dst = ''; - my $act_obj_dst_last = ''; - my $act_obj_comm = ''; - my $act_obj_time = ''; - my $act_obj_time_std = ''; - my $act_obj_color = 'black'; - my $act_obj_rpc = ''; - my $act_obj_uid = ''; - my $extention = 0; - - @params = split_lines_to_parameter ($line,$debuglevel); - $act_obj_name = $params[2]; - $extention = $params[3]; - $act_obj_typ = 'simple'; - $act_obj_type = $params[4]; - $act_obj_src = $params[6]; - $act_obj_dst = $params[8]; - if ($params[10]) { - my $time1 = $params[10]; - if ($time1 eq 'never') { - $time1 = 43200; # ca. 1 Monat sollte als utopisches Maximum reichen - } - $act_obj_time = 60 * $time1; - } - if ($extention =~ /protocol/) { - if (!defined ($services{"$act_obj_name.name"})) { - if ($debuglevel >= 5){ print "ns_object_service: found new service object $act_obj_name\n"; } - @services = (@services, $act_obj_name); - $services{"$act_obj_name.name"} = $act_obj_name; - $services{"$act_obj_name.extention"} = $extention; - } - else { - if ( $services{"$act_obj_name.comments"} =~ /netscreen_predefined_service/ ) { - } else { - print "sub ns_object_services SERVICE: $act_obj_name ist bereits definiert.\n"; - } - } - } - elsif ($extention =~ /\+/) { # MultiDienste (+service) - my $group_name = $act_obj_name; - if (!defined ($services{"$act_obj_name.name"})) { - print ("Fehler: +Service $act_obj_name ohne vorherige Definition\n"); - } else { - if ($services{"$act_obj_name.typ"} ne 'group') { # ersten Dienst erst in Gruppe umwandeln - # dazu erstmal den alten Dienst duplizieren (mit no=0) - my $first_name = $act_obj_name . "_netscreen_PLUS_1"; - $services{"$first_name.name"} = $first_name; - $services{"$first_name.src_port"} = $services{"$act_obj_name.src_port"}; - $services{"$first_name.src_port_last"} = $services{"$act_obj_name.src_port_last"}; - $services{"$first_name.port"} = $services{"$act_obj_name.port"}; - $services{"$first_name.port_last"} = $services{"$act_obj_name.port_last"}; - $services{"$first_name.ip_proto"} = $services{"$act_obj_name.ip_proto"}; - $services{"$first_name.timeout"} = $services{"$act_obj_name.timeout"}; - $services{"$first_name.color"} = $services{"$act_obj_name.color"}; - $services{"$first_name.comments"} = $services{"$act_obj_name.comments"}; - $services{"$first_name.typ"} = $services{"$act_obj_name.typ"}; - $services{"$first_name.type"} = $services{"$act_obj_name.type"}; - if (defined($services{"$act_obj_name.rpc_port"})) { - $services{"$first_name.rpc_port"} = $services{"$act_obj_name.rpc_port"}; - } - $services{"$first_name.UID"} = $first_name; - push @services, $first_name; - - # jetzt den Ursprungsdienst in eine Gruppe umwandeln - $services{"$group_name.typ"} = 'group'; - $services{"$group_name.members"} = "$first_name"; - $services{"$group_name.member_refs"} = "$first_name"; - $services{"$group_name.member_zahl"} = 1; - undef ( $services{"$group_name.src_port"} ); - undef ( $services{"$group_name.src_port_last"} ); - undef ( $services{"$group_name.port"} ); - undef ( $services{"$group_name.port_last"} ); - undef ( $services{"$group_name.ip_proto"} ); - } - $services{"$group_name.member_zahl"} = $services{"$group_name.member_zahl"} + 1; - my $member_zahl = $services{"$group_name.member_zahl"}; - my $new_plus_svc_name = $group_name . "_netscreen_PLUS_" . $services{"$group_name.member_zahl"}; - push @services, $new_plus_svc_name; - $act_obj_name = $new_plus_svc_name; - $services{"$act_obj_name.name"} = $act_obj_name; - $services{"$act_obj_name.UID"} = $act_obj_name; - $services{"$act_obj_name.extention"} = $extention; - $services{"$group_name.members"} .= "|$new_plus_svc_name"; - $services{"$group_name.member_refs"} .= "|$new_plus_svc_name"; - } - } else { - print "?\n"; - print "$line\n"; - } - if ($act_obj_type =~ /rpc/) { -# print "RPC-line: $line; obj_type: $act_obj_type, act_obj_src: $act_obj_src\n"; - $services{"$act_obj_name.src_port"} = 0; - $services{"$act_obj_name.src_port_last"} = 65535; - $services{"$act_obj_name.port"} = 0; - $services{"$act_obj_name.port_last"} = 65535; - $services{"$act_obj_name.typ"} ='rpc'; -# $services{"$act_obj_name.rpc_nr"} = $act_obj_src; - $act_obj_rpc = $act_obj_src; -# $act_obj_rpc = $act_obj_src; -# if ($line =~ /protocol ms-rpc (uuid .*)$/) { -# my $uuid = $1; -# print " found in RPC-line: $uuid\n"; -# $services{"$act_obj_name.rpc_nr"} = $1; -# $services{"$act_obj_name.svc_prod_specific"} = $1; -# } - } else { - @range = split ( /-/, $act_obj_src); - $services{"$act_obj_name.src_port"} = $range[0]; - $services{"$act_obj_name.src_port_last"} = $range[1]; - @range = split ( /-/, $act_obj_dst); - $services{"$act_obj_name.port"} = $range[0]; - $services{"$act_obj_name.port_last"} = $range[1]; - } - $services{"$act_obj_name.ip_proto"} = get_proto_number($act_obj_type); - $services{"$act_obj_name.timeout"} = $act_obj_time; - $services{"$act_obj_name.color"} = $act_obj_color; - $services{"$act_obj_name.comments"} = $act_obj_comm; - $services{"$act_obj_name.typ"} = $act_obj_typ; - $services{"$act_obj_name.type"} = $act_obj_type; - $services{"$act_obj_name.rpc_port"} = $act_obj_rpc; - $services{"$act_obj_name.UID"} = $act_obj_name; -} - -##################################### -# ns_object_group_service -# param1: input-line -# param2: debuglevel [0-?] -##################################### -sub ns_object_group_service { - my $line = $_[0]; - my $debuglevel = ""; - my $i=0; - my $l=0; - my @params; - my @range; - my $act_obj_typ = 'group'; - my $act_obj_type = ''; - my $act_obj_mbr = ''; - my $act_obj_fkt = ''; - my $act_obj_name = ''; - my $act_obj_proto = ''; - my $act_obj_src = ''; - my $act_obj_src_last = ''; - my $act_obj_dst = ''; - my $act_obj_dst_last = ''; - my $act_obj_comm = ''; - my $act_obj_time = ''; - my $act_obj_time_std = ''; - my $act_obj_color = 'black'; - my $act_obj_rpc = ''; - my $act_obj_uid = ''; - my $mbrlst = ''; - my $test = ''; - - if (defined($_[1])) { - $debuglevel = $_[1]; - } - @params = split_lines_to_parameter ($line,$debuglevel); - $act_obj_name = $params[3]; - if ($params[5]) { - $act_obj_mbr = $params[5]; - } - if ($params[4]) { - $act_obj_fkt = $params[4]; - } - - if (!defined ($services{"$act_obj_name.name"})) { - @services = (@services, $act_obj_name); - $services{"$act_obj_name.name"} = $act_obj_name; - } - if ( $act_obj_fkt =~ /add/ ) { - if (defined($services{"$act_obj_name.members"})) { - $mbrlst = $services{"$act_obj_name.members"}; - } - if ( $mbrlst eq '' ) { - $mbrlst = $act_obj_mbr; - } - else { - $mbrlst = "$mbrlst|$act_obj_mbr"; - } - $services{"$act_obj_name.members"} = $mbrlst; - $services{"$act_obj_name.member_refs"} = $mbrlst; - } - $services{"$act_obj_name.ip_proto"} = $act_obj_proto; - $services{"$act_obj_name.timeout"} = $act_obj_time; - $services{"$act_obj_name.color"} = $act_obj_color; - $services{"$act_obj_name.comments"} = $act_obj_comm; - $services{"$act_obj_name.typ"} = $act_obj_typ; - $services{"$act_obj_name.type"} = $act_obj_type; - $services{"$act_obj_name.rpc_port"} = $act_obj_rpc; - $services{"$act_obj_name.UID"} = $act_obj_name; -} - -##################################### -# ns_rules_initial -# param1: input-line [string] -# param2: rule_order, [integer] Reihenfolge der Rules im Configfile -#debuglevel [integer] -##################################### -sub ns_rules_initial { - my $line = $_[0]; - my $order = $_[1]; - my $debuglevel = $_[2]; - my $i=0; - my $l=0; - my $act_rule_id = -1; - my $act_rule_ruleid = -1; - my $act_rule_name = ''; - my $act_rule_Szone = ''; - my $act_rule_Dzone = ''; - my $act_rule_src = ''; - my $act_rule_dst = ''; - my $act_rule_srv = ''; - my $act_rule_act = ''; - my $act_rule_track = ''; - my $act_rule_count = ''; - my @params; - my @range; - my $from_zone_idx = 5; - my ($nat_idx, $action_idx); - - # Handling von dst MIP-IPs, muster: set policy id 8 from "Untrust" to "Trust" "Any" "MIP(12.7.2.0/24)" "ANY" permit log count - if ($line =~ /set policy id \d+ (name .*?)?from \"([\w\_\-\.]+)\" to \"([\w\_\-\.]+)\"\s+\".*?\"\s+\"MIP\(([\d\.]+)\/?(\d+)?\)\"/) { - my $mip_ip = $4; - my $dst_zone = $3; - my $netmask_bits = $5; - my $netmask_string = ''; - if (!defined($netmask_bits) || $netmask_bits eq '') { $netmask_bits = 32; } - my $netmask_dotted = &convert_mask_to_dot_notation($netmask_bits); - if ($netmask_bits<32) { $netmask_string = "/$netmask_bits"; } - if ($debuglevel>1) { print("ns_rules_initial: found dst MIP. MIP($mip_ip$netmask_string) in zone $dst_zone\n"); } - &ns_object_address_add("MIP($mip_ip$netmask_string)", "$mip_ip", $netmask_dotted, $dst_zone, 'Virtual MIP, generated by fworch from interface MIP definition'); - } -=cut - # Handling von src MIP-IPs (wenn es sowas gibt), muster: set policy id 8 from "Untrust" to "Trust" "MIP(12.7.2.27)" "Any" "ANY" permit log count - if ($line =~ /set policy id (name .*?)?\d+ from \"([\w\_\-\.]+)\" to \"([\w\_\-\.]+)\"\s+\"MIP\(([\d\.]+)\/?(\d+)?\)\"\s+\".*?\"/) { - my $mip_ip = $4; - my $src_zone = $2; - my $netmask_bits = $5; - my $netmask_string = ''; - if (!defined($netmask_bits) || $netmask_bits eq '') { $netmask_bits = 32; } - my $netmask_dotted = &convert_mask_to_dot_notation($netmask_bits); - if ($netmask_bits<32) { $netmask_string = "/$netmask_bits"; } - &ns_object_address_add("MIP($mip_ip$netmask_string)", "$mip_ip", $netmask_dotted, $src_zone, 'Virtual MIP, generated by fworch from interface MIP definition'); - } -=cut - $rulebases{"$rulebase_name.rulecount"} = $order + 1; # Anzahl der Regeln wird sukzessive hochgesetzt - @params = split_lines_to_parameter ($line,$debuglevel); - $act_rule_id = $params[3]; - $act_rule_ruleid = $act_rule_id; - $ruleorder[$order] = $act_rule_id; - if ($params[4] =~ /^name$/) { - $act_rule_name = $params[5]; - $from_zone_idx = 7; - } - $nat_idx = $from_zone_idx + 7; - $action_idx = $nat_idx; # Normalfall ohne NAT - $act_rule_Szone = $params[$from_zone_idx+0]; - $act_rule_Dzone = $params[$from_zone_idx+2]; - $act_rule_src = $params[$from_zone_idx+4]; - $act_rule_dst = $params[$from_zone_idx+5]; - my $act_rule_src_refs = "${act_rule_src}__zone__$act_rule_Szone"; - my $act_rule_dst_refs = "${act_rule_dst}__zone__$act_rule_Dzone"; - $act_rule_srv = $params[$from_zone_idx+6]; - if ($params[$nat_idx] =~ /^nat$/) { - my $nat_type = "initial"; - my $line_after_nat = "initial"; - my $found_nat = 0; - - if ($line =~ /(.*?)\s+nat\s+(.*)/) { $line_after_nat = $2; } - - if (!$found_nat && $line_after_nat =~ /^dst ip [\d\.]+ port \d+ .*/) { # nat dst ip 10.132.160.12 port 44316 permit log - $action_idx += 6; $found_nat = 1; $nat_type = '7 dst nat with port'; - } - if (!$found_nat && $line_after_nat =~ /^dst ip [\d\.]+ [\d\.]+ .*/) { # nat dst ip 2.52.20.0 2.52.21.255 permit log - $action_idx += 5; $found_nat = 1; $nat_type = '8 dst nat with ip range'; - } - if (!$found_nat && $line_after_nat =~ /^dst ip [\d\.]+ .*/) { # nat dst ip 10.132.160.12 permit log - $action_idx += 4; $found_nat = 1; $nat_type = '1 dst nat simple'; - } - if (!$found_nat && $line_after_nat =~ /^src dst ip [\d\.]+ port \d+ .*/) { # nat src dst ip 192.168.0.4 port 22 permit log - $action_idx += 7; $found_nat = 1; $nat_type = '9 src & dst & port nat'; - } - if (!$found_nat && $line_after_nat =~ /^src dip\-id \d+ dst ip [\d\.]+ port \d+ .*/) { # nat src dip-id 32 dst ip 10.132.160.12 [port 222] permit log - $action_idx += 9; $found_nat = 1; $nat_type = '6 src & dst & dip nat & port nat'; - } - if (!$found_nat && $line_after_nat =~ /^src dip\-id \d+ dst ip [\d\.]+ .*/) { # nat src dip-id 32 dst ip 10.132.160.12 permit log - $action_idx += 7; $found_nat = 1; $nat_type = '2 src & dst & dip nat'; - } - if (!$found_nat && $line_after_nat =~ /^src dst ip [\d\.]+ .*/) {# nat src dst ip 172.20.128.1 - $action_idx += 5; $found_nat = 1; $nat_type = '3 src dst nat'; - } - if (!$found_nat && $line_after_nat =~ /^src dip\-id \d+ .*/) {# nat src dip-id 4 permit log - $action_idx += 4; $found_nat = 1; $nat_type = '4 src & dip-id'; - } - if (!$found_nat && $line_after_nat =~ /^src .*/) { # nat src permit --> einfachster Fall der src nat ohne weitere Parameter - $action_idx += 2; $found_nat = 1; $nat_type = '5 simple src nat'; - } - } - if (defined($params[$action_idx+0])) { $act_rule_act = $params[$action_idx+0]; } - my $track_idx = $action_idx+1; - if (defined($act_rule_act) && $act_rule_act eq 'tunnel') { # vpn regel - $act_rule_act .= " $params[$action_idx+1]"; - $track_idx = $action_idx+2; # name des tunnels auslassen - } - if (defined($params[$track_idx]) && $params[$track_idx] =~ /auth|webauth/) { - $act_rule_act .= " $params[$track_idx]"; - $track_idx ++; - } - my @track_types = qw(log alert count alarm); - while (defined($params[$track_idx])) { # collecting track info - my $pattern_to_find = $params[$track_idx]; - if (grep(/$pattern_to_find/, @track_types)) { - if (defined($act_rule_track) && length($act_rule_track)>0) { - $act_rule_track .= " " . $params[$track_idx]; - } else { - $act_rule_track = $params[$track_idx]; - } - } - $track_idx ++; - } - if (!defined($act_rule_track) || $act_rule_track eq '') { $act_rule_track = 'none'; } - if (length($act_rule_track)<3) { - print ("warning, track short: <$act_rule_track>\n$line\n"); - } - if ($debuglevel >= 5){ print "ns_rules_initial: found new policy $act_rule_id\n"; } -=cut - if (!defined ($rulebases{"$rulebase_name.$act_rule_id.id"})) { - if ((($debuglevel >= 4)&&($debuglevel<=10))||(($debuglevel >= 14)&&($debuglevel<=20))){ - print "sub ns_rules_initial RULE: $act_rule_id neu definiert.\n"; - } - } - elsif (defined ($rulebases{"$rulebase_name.$act_rule_id.id"})) { - if ((($debuglevel >= 4)&&($debuglevel<=10))||(($debuglevel >= 14)&&($debuglevel<=20))){ - print "sub ns_rules_initial RULE: $act_rule_id ist bereits definiert.\n"; - } - } - else { - if ((($debuglevel >= 4)&&($debuglevel<=10))||(($debuglevel >= 14)&&($debuglevel<=20))){ - print "sub ns_rules_initial RULE: $act_rule_id ist undefiniert.\n"; - } - } -=cut - $rulebases{"$rulebase_name.$act_rule_id.id"} = $act_rule_id; - $rulebases{"$rulebase_name.$act_rule_id.ruleid"} = $act_rule_ruleid; - $rulebases{"$rulebase_name.$act_rule_id.order"} = $order; - $rulebases{"$rulebase_name.$act_rule_id.disabled"} = '0'; - $rulebases{"$rulebase_name.$act_rule_id.src.zone"} = $act_rule_Szone; - $rulebases{"$rulebase_name.$act_rule_id.src"} = $act_rule_src; - $rulebases{"$rulebase_name.$act_rule_id.src.refs"} = $act_rule_src_refs; - $rulebases{"$rulebase_name.$act_rule_id.dst.zone"} = $act_rule_Dzone; - $rulebases{"$rulebase_name.$act_rule_id.dst"} = $act_rule_dst; - $rulebases{"$rulebase_name.$act_rule_id.dst.refs"} = $act_rule_dst_refs; - $rulebases{"$rulebase_name.$act_rule_id.services.op"} = '0'; - $rulebases{"$rulebase_name.$act_rule_id.src.op"} = '0'; - $rulebases{"$rulebase_name.$act_rule_id.dst.op"} = '0'; - $rulebases{"$rulebase_name.$act_rule_id.services"} = $act_rule_srv; - $rulebases{"$rulebase_name.$act_rule_id.services.refs"} = $act_rule_srv; - $rulebases{"$rulebase_name.$act_rule_id.action"} = $act_rule_act; - $rulebases{"$rulebase_name.$act_rule_id.track"} = $act_rule_track; - $rulebases{"$rulebase_name.$act_rule_id.install"} = ''; # set hostname verwenden ? - $rulebases{"$rulebase_name.$act_rule_id.name"} = ''; # kein Aequivalent zu CP rule_name - $rulebases{"$rulebase_name.$act_rule_id.time"} = ''; - $rulebases{"$rulebase_name.$act_rule_id.comments"} = $act_rule_name; - $rulebases{"$rulebase_name.$act_rule_id.UID"} = $act_rule_id; - $rulebases{"$rulebase_name.$act_rule_id.header_text"} = ''; - -} - -##################################### -# ns_rules_extended -# param1: debuglevel [integer] -# keine Hashuebergabe - zu fehleranfaellig bei meinem stil - arbeite mit globalem hash -# Aufruf darf erst erfolgen, wenn ns_rules_initial alle Rules erfasst hat -# Rules werden nur ergaenzt, fall sRule-id nicht existiert -> Fehlermeldung -##################################### -sub ns_rules_extended { - my $debuglevel = $_[0]; - my $line = ''; - my $act_rule_id = -1; - my $act_rule_src = ''; - my $act_rule_dst = ''; - my $act_rule_srv = ''; - my @params; - - foreach $line (@config_lines) { - if ($debuglevel >= 9) { print $line; } - @params = split_lines_to_parameter ($line,$debuglevel); - - if (($line =~/^set policy id \d+/) && ($#params == 3)) { - $act_rule_id = $params[3]*1; - } elsif (($line =~/^exit/) && ($act_rule_id > -1)) { - $act_rule_id = -1; - } - if ($act_rule_id > -1) { - if ($line=~ /^set service / && $#params == 2) { -# if (!defined($rulebases{"$rulebase_name.$act_rule_id.services"})) { $rulebases{"$rulebase_name.$act_rule_id.services"} = ''; } -# if (!defined($rulebases{"$rulebase_name.$act_rule_id.services.refs"})) { $rulebases{"$rulebase_name.$act_rule_id.services.refs"} = ''; } - $act_rule_srv = $rulebases{"$rulebase_name.$act_rule_id.services"}; - $act_rule_srv = "$act_rule_srv|$params[2]"; - $rulebases{"$rulebase_name.$act_rule_id.services"} = $act_rule_srv; - $rulebases{"$rulebase_name.$act_rule_id.services.refs"} = $act_rule_srv; - } - if ($line=~ /^set src-address/ && $#params == 2) { - if ($line =~ /set src-address\s+\"MIP\(([\d\.]+)\/?(\d+)?\)\"/) { - my $src_zone = $rulebases{"$rulebase_name.$act_rule_id.src.zone"}; - my $mip_ip = $1; - my $netmask_bits = $2; - my $netmask_string = ''; - my $is_ipv6 = ($mip_ip =~ /\:/); - if ((!defined($netmask_bits) || $netmask_bits eq '') && $is_ipv6) { $netmask_bits = 128; } - if ((!defined($netmask_bits) || $netmask_bits eq '') && !$is_ipv6) { $netmask_bits = 32; } - my $netmask_dotted = &convert_mask_to_dot_notation($netmask_bits); - if ($is_ipv6 && $netmask_bits<128) { $netmask_string = "/$netmask_bits"; } - if (!$is_ipv6 && $netmask_bits<32) { $netmask_string = "/$netmask_bits"; } - &ns_object_address_add("MIP($mip_ip$netmask_string)", "$mip_ip", $netmask_dotted, $src_zone, 'Virtual MIP, generated by fworch from interface MIP definition'); - } - $act_rule_src = $rulebases{"$rulebase_name.$act_rule_id.src"}; - my $act_rule_src_refs = $rulebases{"$rulebase_name.$act_rule_id.src.refs"}; - my $zone = $rulebases{"$rulebase_name.$act_rule_id.src.zone"}; - $act_rule_src = "$act_rule_src|$params[2]"; - $act_rule_src_refs .= "|$params[2]__zone__$zone"; - $rulebases{"$rulebase_name.$act_rule_id.src"} = $act_rule_src; - $rulebases{"$rulebase_name.$act_rule_id.src.refs"} = $act_rule_src_refs; - # keine Konsistenzpruefung bzgl. Zone, da die Konsistenz der Konfig unter diesem Gesichtspunkt vorausgesetzt wird - } - if ($line=~ /^set dst-address/ && $#params == 2) { - # Handling von dst MIP-IPs, muster: set dst-address "MIP(89.19.225.170)" - if ($line =~ /set dst-address\s+\"MIP\(([\d\.]+)\/?(\d+)?\)\"/) { - my $dst_zone = $rulebases{"$rulebase_name.$act_rule_id.dst.zone"}; - my $mip_ip = $1; - my $netmask_bits = $2; - my $netmask_string = ''; - if (!defined($netmask_bits) || $netmask_bits eq '') { $netmask_bits = 32; } - my $netmask_dotted = &convert_mask_to_dot_notation($netmask_bits); - if ($netmask_bits<32) { $netmask_string = "/$netmask_bits"; } - &ns_object_address_add("MIP($mip_ip$netmask_string)", "$mip_ip", $netmask_dotted, $dst_zone, 'Virtual MIP, generated by fworch from interface MIP definition'); - } - $act_rule_dst = $rulebases{"$rulebase_name.$act_rule_id.dst"}; - my $act_rule_dst_refs = $rulebases{"$rulebase_name.$act_rule_id.dst.refs"}; - my $zone = $rulebases{"$rulebase_name.$act_rule_id.dst.zone"}; - $act_rule_dst = "$act_rule_dst|$params[2]"; - $act_rule_dst_refs .= "|$params[2]__zone__$zone"; - $rulebases{"$rulebase_name.$act_rule_id.dst"} = $act_rule_dst; - $rulebases{"$rulebase_name.$act_rule_id.dst.refs"} = $act_rule_dst_refs; - # keine Konsistenzpruefung bzgl. Zone, da die Konsistenz der Konfig unter diesem Gesichtspunkt vorausgesetzt wird - } - } - } -} - -############################################################ -# ns_add_zone ($new_zone) -############################################################ -sub ns_add_zone { - my $new_zone = shift; - my $debug_level = shift; - my $is_there = 0; - foreach my $elt (@zones) { if ($elt eq $new_zone) { $is_there = 1; last; } } - if (!$is_there) { - push @zones, $new_zone; - if ($debug_level >= 2){ print "ns_add_zone: found new zone $new_zone\n"; } - } -} - -############################################################ -# read_predefined_services( -############################################################ -sub read_predefined_services { - my $device_type = shift; - my $predefined_service_string = shift; - my $predef_svc; - my ($svc_name,$ip_proto,$port,$port_end,$timeout,$comment,$typ,$group_members); - - $predef_svc = exec_pgsql_cmd_return_value ("SELECT dev_typ_predef_svc FROM stm_dev_typ WHERE dev_typ_id=$device_type"); - my @predef_svc = split /\n/, $predef_svc; - foreach my $svc_line (@predef_svc) { - ($svc_name,$ip_proto,$port,$port_end,$timeout,$comment,$typ,$group_members) = split /;/, $svc_line; - $services{"$svc_name.name"} = $svc_name; - $services{"$svc_name.port"} = $port; - $services{"$svc_name.port_last"} = $port_end; - $services{"$svc_name.ip_proto"} = $ip_proto; - $services{"$svc_name.timeout"} = $timeout; - $services{"$svc_name.color"} = "black"; - $services{"$svc_name.comments"} = "$predefined_service_string, $comment"; - $services{"$svc_name.typ"} = $typ; - $services{"$svc_name.type"} = ""; - $services{"$svc_name.rpc_port"} = ""; - $services{"$svc_name.UID"} = $svc_name; - $services{"$svc_name.members"} = $group_members; - $services{"$svc_name.member_refs"} = $group_members; - push @services, $svc_name; - } - return; -} -############################################################ -# copy_config_from_mgm_to_iso($ssh_private_key, $ssh_user, $ssh_hostname, $management_name, -# $obj_file_base, $cfg_dir, $rule_file_base) -# Kopieren der Config-Daten vom Management-System zum ITSecorg-Server -############################################################ - -sub copy_config_from_mgm_to_iso { - my $ssh_user = shift; - my $ssh_hostname = shift; - my $management_name = shift; - my $obj_file_base = shift; - my $cfg_dir = shift; - my $rule_file_base = shift; - my $workdir = shift; - my $debug_level = shift; - my $cmd; - my $fehler_count = 0; - my $result; - -# the scp command has to be used for tests with non-netscreen devices -# $cmd = "$scp_bin $scp_batch_mode_switch -i $workdir/$CACTUS::FWORCH::ssh_id_basename $ssh_user\@$ssh_hostname:ns_sys_config $cfg_dir/$obj_file_base"; - $cmd = "$ssh_client_screenos -z $ssh_hostname -t netscreen -i $workdir/$CACTUS::FWORCH::ssh_id_basename -c 'get config' -u $ssh_user -d 0 -o $cfg_dir/$obj_file_base"; - if (system ($cmd)) { $fehler_count++; } - return ($fehler_count, "$cfg_dir/$obj_file_base" ); -} - -sub sort_rules_and_add_zone_headers { - my $anzahl_regeln = $rulebases{"$rulebase_name.rulecount"}; - my $count; - my $zone_string; - my @rule_zones = (); - - # Nachbereitung Regeln: Sortierung nach a) Zonen b) $ruleorder - - for ($count=0; $count<$anzahl_regeln; $count++) { - $zone_string = $rulebases{"$rulebase_name.$ruleorder[$count].src.zone"}; - $zone_string .= " : "; - $zone_string .= $rulebases{"$rulebase_name.$ruleorder[$count].dst.zone"}; - push @rule_zones, $zone_string - } - my @idx = (); - my $item; - for (@rule_zones) { - ($item) = $_; - push @idx, $item; - } - - @ruleorder = @ruleorder[ sort { $idx[$a] cmp $idx[$b] } 0 .. $anzahl_regeln-1 ]; - @rule_zones = @rule_zones[ sort { $idx[$a] cmp $idx[$b] } 0 .. $anzahl_regeln-1 ]; - - # Nachbereitung Regeln: Header-Regeln vor Zonenwechsel einfuegen - my $new_zone_string; - my $old_zone_string = ""; - my $rule_header_count = 1; - my $rule_header_offset = &CACTUS::read_config::read_config('rule_header_offset') * 1; - my $new_rule_id; - for ($count = 0; $count < $anzahl_regeln; $count++) { - $new_zone_string = $rule_zones[$count]; - if ($new_zone_string ne $old_zone_string) { # insert header rule - $new_rule_id = $rule_header_offset+$rule_header_count++; - (my $src_zone, my $dst_zone) = split / : /, $new_zone_string; - splice(@ruleorder,$count,0,$new_rule_id); # fuegt neue Regel ein - splice(@rule_zones,$count,0,$new_zone_string); - $anzahl_regeln++; - $rulebases{"$rulebase_name.rulecount"} = $anzahl_regeln; - $rulebases{"$rulebase_name.$ruleorder[$count].id"} = $new_rule_id; - $rulebases{"$rulebase_name.$ruleorder[$count].header_text"} = $new_zone_string; - $rulebases{"$rulebase_name.$ruleorder[$count].UID"} = $new_rule_id; - $rulebases{"$rulebase_name.$ruleorder[$count].src"} = "Any"; - $rulebases{"$rulebase_name.$ruleorder[$count].dst"} = "Any"; - $rulebases{"$rulebase_name.$ruleorder[$count].services"} = "ANY"; - $rulebases{"$rulebase_name.$ruleorder[$count].action"} = "deny"; - $rulebases{"$rulebase_name.$ruleorder[$count].src.zone"} = $src_zone; - $rulebases{"$rulebase_name.$ruleorder[$count].dst.zone"} = $dst_zone; - $rulebases{"$rulebase_name.$ruleorder[$count].disabled"} = '0'; - $rulebases{"$rulebase_name.$ruleorder[$count].src.op"} = '0'; - $rulebases{"$rulebase_name.$ruleorder[$count].dst.op"} = '0'; - $rulebases{"$rulebase_name.$ruleorder[$count].services.op"} = '0'; - } - $old_zone_string = $new_zone_string; - } -} - - -# check auf Vollstaendigkeit des Config-Files: -sub is_cfg_file_complete { - my $ln_cnt = $#config_lines; - my $cfg_file_complete = 1; - while ($config_lines[$ln_cnt] =~ /^\s*$/ ) { $ln_cnt -- ; } # ignore empty lines at the end - if ($config_lines[$ln_cnt] !~ /^.*set multicast\-group\-policy/) { - if ( $config_lines[$ln_cnt] =~ /^exit.?$/ || $config_lines[$ln_cnt] =~ /^set zone \"?.+?\"? ip-classification /) { - # last non-empty line must either be "exit" or multicast-related - $ln_cnt -- ; - if ( $config_lines[$ln_cnt] !~ /^(un)?set .*?route.*?$/ && $config_lines[$ln_cnt] !~ /^set zone \"?.+?\"? ip-classification /) { - # assuming that last config part deals with routing - $cfg_file_complete = 0; - print ("expected last line to deal with routing. Instead got: " . $config_lines[$ln_cnt] . "\n"); - } - } else { - $cfg_file_complete = 0; - print ("expected last line to either be 'exit' or mutlicast-related. Instead got: " . $config_lines[$ln_cnt] . "\n"); - } - } - return $cfg_file_complete; -} - -sub parse_users { # not implemented yet - my $line = shift; - if ( $line=~ /^set user.*/ ) { - # print "found user: $line\n"; - # noch auszuprogrammieren - # set user "oe560" uid 1 - # set user "oe560" type auth - # set user "oe560" hash-password "asdf askdfaslkdfjalsjfd" - # set user "oe560" "enable" - } -} - -##################################################################################### -# MAIN - -sub parse_config { - # ($obj_file, $rule_file, $rulebases, $fworch_workdir, $debug_level) - my $in_file_main = shift; - shift; - shift; # $rule_file und $user nicht verwendet - my $dev_info_hash = shift; # fuer netscreen gibt es pro management immer nur genau ein device - my $fworch_workdir = shift; - my $debuglevel_main = shift; - my $mgm_name = shift; - my $config_dir = shift; - my $import_id = shift; - my $debug_level = shift; - my $line = ''; - my $ln_cnt = $#config_lines; - my @vsys_lines = (); - my $vsys_started = 0; - my $dev_name = 'undefined_dev_name'; - - # Initializing - - @services = (); - @network_objects = (); - my $device_type=3; # netscreen v5.1 fest gesetzt, TODO: move to config - my $predefined_service_string = "netscreen_predefined_service"; # move to config - - if ($debuglevel_main >= 2){ print "in_file_main:$in_file_main!\ndebuglevel_main:$debuglevel_main!\n"; } - &read_predefined_services($device_type, $predefined_service_string); # schreibt die predefined services in @services und %services - - open (IN, $in_file_main) || die "$in_file_main konnte nicht geoeffnet werden.\n"; - @config_lines = ; - close (IN); - - &remove_unwanted_chars ($debuglevel_main); - - if (&ns_mode_check($debuglevel_main)) { return "unknown-netscreen-config-file-mode-$mgm_name"; } - - if (!&is_cfg_file_complete()) { return "incomplete-config-file-$mgm_name"; } - else { - foreach $line (@config_lines) { # extract all zone information (global zones can be used in vsys config) - if ( $line =~ /^set zone id \d+ "(.+)"/ || $line =~ /^set zone "(.+)" vrouter / || $line =~ /^set interface ".+" zone "(.+)"/ ) { - &ns_add_zone ($1, $debuglevel_main); - } - } - while ( (my $key, my $value) = each %{$dev_info_hash} ) { $dev_name = $value->{'dev_name'}; } # nur ein device pro netscreen management -# print ("searching for vsys with dev_name $dev_name, mgm_name=$mgm_name\n"); - @rulebases = ($dev_name); $rulebase_name = $dev_name; - if ($dev_name ne '') { # vsys config erwartet - foreach $line (@config_lines) { - if ($line =~ /^set vsys \"?$dev_name\"? /i) { # start of right vsys definition - $vsys_started = 1; - } elsif ($line =~ /^set vsys \"?/) { $vsys_started = 0; } - elsif ($vsys_started) { - @vsys_lines = (@vsys_lines, $line); - } - } - if ($#vsys_lines>0) { @config_lines = @vsys_lines; } # only copy vsys config if correct vsys has been found - } - LINE: foreach $line (@config_lines) { - if ($debuglevel_main >= 9) { print "main debug line: $line"; } - if ($line=~ /^set hostname ([\w\.\_\-]+)/) { $mgm_name = $1; @rulebases = ($mgm_name); $rulebase_name = $mgm_name; } # wird auch in ns_rules_initial verwendet - $line=~ (/^set address/) && do {&ns_object_address ($line,$debuglevel_main);}; - $line=~ (/^set group address/) && do {&ns_object_group_address ($line,$debuglevel_main);}; - if ($line=~ /^set service.+?protocol.*/ || $line=~ /^set service.+? \+ .*/) { ns_object_service ($line, $debuglevel_main); } - if ($line=~ /^set group service.*/) { ns_object_group_service ($line,$debuglevel_main); } -########### Start Regelparser - if ($line=~ /^set policy id \d+ (application|attack)/ ) { next LINE; } # ignore it - if ($line=~ /^set policy id (\d+) (name|from)/ ) { # Standardfall: eine Regeldefinition beginnt - if ($debuglevel_main >= 5){ print "parse_config: found new policy $1\n"; } - &ns_rules_initial ($line,$rule_order,$debuglevel_main); - $rule_order ++; - } - if ( $line=~ /^set policy id (\d+) disable.*/ ) { # Regel deaktiviert - if (defined($rulebases{"$rulebase_name.$1.id"})) { $rulebases{"$rulebase_name.$1.disabled"} = '1'; } - else { print ("Fehler: noch nicht definierte Regel disabled: $line\n"); } - } -########### Ende Regelparser - &parse_users($line); - } - &ns_rules_extended ($debuglevel_main); # file noch einmal durchgehen und diesmal nach Ergaenzungen der Regeln mit svc, src oder dst suchen - # Any-Objekte fuer alle Zonen einfuegen - push @zones, "Global"; # Global Zone immer hinzufuegen - foreach my $zone (@zones) { - &ns_object_address_add("Any", "0.0.0.0", "0.0.0.0", $zone, "Any-Obj for Zone added by fworch"); - &ns_object_address_add("Any-IPv4", "0.0.0.0", "0.0.0.0", $zone, "Any-IPv4-Obj for Zone added by fworch"); - &ns_object_address_add("Any-IPv6", "::", "0", $zone, "Any-IPv6-Obj for Zone added by fworch"); - } - &sort_rules_and_add_zone_headers (); - # neu: Wegschreiben der Regelreihenfolge - $rulebases{"$rulebase_name.ruleorder"} = join(',', @ruleorder); -# print_results_monitor('objects'); -# print_results_monitor('rules'); - print_results_files_objects($fworch_workdir, $mgm_name, $import_id); - print_results_files_rules ($fworch_workdir, $mgm_name, $import_id); - print_results_files_zones ($fworch_workdir, $mgm_name, $import_id); - return 0; - } -} - -1; -__END__ - -=head1 NAME - -CACTUS::FWORCH::parser - Perl extension for fworch netscreen parser - -=head1 SYNOPSIS - use CACTUS::FWORCH::import::netscreen; - -=head1 DESCRIPTION - -fworch Perl Module support for importing configs into fworch Database - -=head2 EXPORT - - global variables - -=head1 SEE ALSO - - behind the door - -=head1 AUTHOR - - Cactus eSecurity, tmp@cactus.de - -=cut diff --git a/roles/importer/files/importer/CACTUS/FWORCH/import/phion.pm b/roles/importer/files/importer/CACTUS/FWORCH/import/phion.pm deleted file mode 100644 index b043b0b10c..0000000000 --- a/roles/importer/files/importer/CACTUS/FWORCH/import/phion.pm +++ /dev/null @@ -1,1796 +0,0 @@ - -package CACTUS::FWORCH::import::parser; - -use strict; -use warnings; -use IO::File; -use File::Find; - -use CACTUS::FWORCH; -use CACTUS::FWORCH::import; -use Date::Calc qw(Add_Delta_DHMS Delta_DHMS); - -require Exporter; -our @ISA = qw(Exporter); - -our %EXPORT_TAGS = ( 'basic' => [ qw( ©_config_from_mgm_to_iso &parse_config ) ] ); - -our @EXPORT = ( @{ $EXPORT_TAGS{'basic'} } ); - -# variblendefinition parser -# ------------------------------------------------------------------------------------------- - -our $fwobj_file_extension = '.fwobj'; -our $fwobj_file_pattern = '\*\.fwobj'; - -our $forwarding_rule_file_extension = '.fwrule'; -our $forwarding_rule_file_pattern = '\*\.fwrule'; - -our $rev_marker = ',v'; # RCS files -our $rev_fwobj_file_extension = '.fwobj,v'; -our $rev_fwobj_file_pattern = '\*\.fwobj\,v'; - -our $rev_rule_file_extension = '.fwrule,v'; -our $rev_rule_file_pattern = '\*\.fwrule\,v'; - -our $debug_level = 0; - -# our $local_rule_file_extension = '.lfwrule7'; -# our $local_rule_file_pattern = '\*\.lfwrule7'; - -our $GROUPSEP = "|"; # globale Einstellung fuer Seperator in Gruppen; -our $config_path_praefix; -our $last_import_time; -our $last_change_admin; -# our @UTC_diff_identifier = (); -our $UTC_diff; -our $scope; - -# Stati und anderes des Objektparsers -# ------------------------------------------------------------------------------------------- -our $parse_obj_state = 0; # moegliche Werte 0 kein status - # 1 objectclass gestartet - # 2 object gestartet - # 3...5 diverse attribute & werte (kontextsensitiv) -our $parse_obj_type; # State 1 - aktuelle Objektklasse -our $parse_obj_id; # State 2 - id des aktuellen objektes ( name__uid__uid ) -our $parse_obj_name; # State 2 - name des aktuellen objektes -our $parse_obj_attr; # State 3 - Attribut -our $parse_obj_attr_value; # State 3 - Wert des Attributes -our $parse_obj_attr_ext; # State 4 - Attributerweiterung (kontextsensitiv) -our $parse_obj_attr_ext_value; # State 4 - Wert des erweiterten Attributes (kontextsensitiv) -our $parse_obj_neglist; # Flag fuer negierte Liste -our $collecting_group_members = 0; # flag -our $explicit_flag = 0; -our $create_explicit_element_flag = 0; -our $create_explicit_element_proto; -our $member_counter = 0; # zaehlt #Gruppenmitglieder -our $convert_simple_to_group_flag = 0; # Flag, um bei Bedarf ein als simple angefangenes Objekt zur Gruppe zu machen -our $proto_of_explicit_svc_group; - -# rule specific -our $parserule_rulenum; -our $parse_rule_field_details; -our $parse_rule_field; -our $config_files_str; - -our $sublist_flag = 0; -our $rulelist_flag = 0; -our $rulelist_name = ''; -our $indent = ''; -our @subrulebases = (); # local for checking on subrule lists - -## parse_audit_log Funktion fuer phion noch nicht implementiert -sub parse_audit_log { } - -############################################################ -# copy_config_from_mgm_to_iso($ssh_private_key, $ssh_user, $ssh_hostname, $management_name, $obj_file_base, $cfg_dir, $rule_file_base) -# Kopieren der Config-Daten vom Management-System zum ITSecorg-Server -############################################################ -sub copy_config_from_mgm_to_iso { - my $ssh_user = shift; - my $ssh_hostname = shift; - my $management_name = shift; - my $obj_file_base = shift; - my $cfg_dir = shift; - my $rule_file_base = shift; - my $workdir = shift; - my $auditlog = shift; # unused in phion - my $prev_import_time= shift; # unused in phion - my $ssh_port = shift; - my $config_path_on_mgmt = shift; # unused in phion - my $debug_level = shift; - - my $cmd; - my $return_code; - my $fehler_count = 0; - - my $tar_archive = 'iso-phion-config.tgz'; - - my $tar_cmd = 'tar cfz '.$tar_archive.' \`find . -type f ' . - '-name "' . $fwobj_file_pattern . '" ' . - '-o -name "' . $forwarding_rule_file_pattern . '" ' . - '-o -name "' . $rev_fwobj_file_pattern . '" ' . - '-o -name "' . $rev_rule_file_pattern . '" ' . - ' \`'; - - if (!defined($ssh_port) || $ssh_port eq '') { - $ssh_port = "22"; - } - - $cmd = "$ssh_bin -i $workdir/$CACTUS::FWORCH::ssh_id_basename -p $ssh_port $ssh_user\@$ssh_hostname $tar_cmd"; - $fehler_count += (system ($cmd) != 0); - - $cmd = "$scp_bin -i $workdir/$CACTUS::FWORCH::ssh_id_basename -P $ssh_port $ssh_user\@$ssh_hostname:$tar_archive $cfg_dir"; - $fehler_count += (system ($cmd) != 0); - - $cmd = "$ssh_bin -i $workdir/$CACTUS::FWORCH::ssh_id_basename -p $ssh_port $ssh_user\@$ssh_hostname rm $tar_archive"; - $fehler_count += (system ($cmd) != 0); - - $cmd = "cd $cfg_dir; tar xfz $tar_archive; rm $tar_archive"; - $fehler_count += (system ($cmd) != 0); - - find(\&collect_config_files, $cfg_dir); # erzeugt einen String mit allen gefundenen Config-Files - $UTC_diff = &get_UTC_diff_unix($ssh_user, $ssh_hostname, $ssh_port, "$workdir/$CACTUS::FWORCH::ssh_id_basename"); # hole UTC-Verschiebung mittels date-Befehl (globale Var setzen) - return ($fehler_count,$config_files_str); -} - -############################################################ -# get_UTC_diff_unix($ssh_private_key, $ssh_user, $ssh_hostname, $management_name, $work_dir) -# liefert die Verschiebung in Stunden zu UTC -############################################################ -sub get_UTC_diff_unix { - my $ssh_user = shift; - my $ssh_hostname = shift; - my $ssh_port = shift; - my $ssh_priv_key_file = shift; - - return (`$ssh_bin -i $ssh_priv_key_file -p $ssh_port $ssh_user\@$ssh_hostname date +\"%z\"` / 100); # Minuten "wegdividieren" (%z Format: +0200) -} - -sub collect_config_files { - if ( -f $File::Find::name && $File::Find::name !~ /$rev_marker/ ) { - if (defined($config_files_str)) { - $config_files_str .= ("," . $File::Find::name); - } else { - $config_files_str = $File::Find::name; - } - } -} - - -##################################################################################### -# Start Parser -##################################################################################### - -sub parse_config { - shift; # ignore filename - my $rulebase_file = shift; - my $user_db_file = shift; - my $rulebase_name = shift; - my $output_dir = shift; - my $debug = shift; - my $mgm_name = shift; - my $cfg_dir = shift; - my $import_id = shift; - my $audit_log_file= shift; - my $last_import_time_local = shift; - my $debug_level = shift; - - $debug_level = $debug; - # setting global vars as find cannot take any parameters - $config_path_praefix = $cfg_dir; - $last_import_time = $last_import_time_local; - - # parse all files and fill structures (hashes, arrays) - find(\&process_basic_object_files, $cfg_dir); -# exit 1; - find(\&process_forwarding_rule_files, $cfg_dir); -# find(\&process_local_rule_files,$cfg_dir); - &fix_bidir_rules(); - &add_basic_object_oids_in_rules_for_locally_defined_objects(); - &fix_rule_references(); - &link_subset_rules(); - §ion_titles_correction(); - - # write structures to file (debug: and screen) -# print_results_monitor('objects'); -# print_results_monitor('rules'); - &print_results_files_objects($output_dir, $mgm_name, $import_id); -# &print_results_files_users($output_dir, $mgm_name, $import_id); - &print_results_files_rules($output_dir, $mgm_name, $import_id); - return 0; # done without errors -} - -sub process_basic_object_files { - if ($File::Find::name =~ /^$config_path_praefix\/(.*?)$/) { - $scope = $1; -# $flat_file =~ s/\//\_/g; -# $scope = $flat_file; - if ($scope =~ /FactoryDefault/ || - $scope =~ /^Revision/ || - $scope =~ /^zrepo/ ) { # alle FactoryDefaults, Revisions und Revisions - ignorieren - if ($scope !~ /^Revision/) { print_debug ("ignoring basic element config file $scope ", $debug_level, 5); } - return; - } elsif ( -f $File::Find::name || -l $File::Find::name ) { - if ( -e $File::Find::name ) { - print_debug ("fwobj parser: processing file " . $File::Find::name, $debug_level, 1); -# if ($File::Find::name =~ /^$config_path_praefix\/(.*?)$/) { $scope = $1; } - &get_change_admin($File::Find::name, $last_import_time); -# output_txt ("change_admin: $change_admin"); - &parse_basic_elements ($File::Find::name); - } else { - output_txt ("ERROR: fworch-importer: phion.pm: cannot access file $File::Find::name\n", 2); - } - } - } -} - -sub process_rule_files { - my $extension = $_[0]; - - if ($File::Find::name =~ /$extension$/) { - if ($File::Find::name =~ /^$config_path_praefix\/(.*?)$/) { - $scope = $1; - $scope =~ s/\//\_/g; -# $scope = $flat_file; - } - if ($scope =~ /FactoryDefault/ || - $scope =~ /^Revision/ || - $scope =~ /^zrepo/ ) { # alle FactoryDefaults, Revisions und Revisions - ignorieren - if ($scope !~ /^Revision/) { print_debug ("ignoring ruleset file $scope", $debug_level, 3); } - return; - } elsif ( -f $File::Find::name || -l $File::Find::name ) { - if ( -e $File::Find::name ) { - print_debug ("rule parser: processing file " . $File::Find::name, $debug_level, 1); - @rulebases = (@rulebases, $scope); - $parserule_rulenum = 0; - &get_change_admin($File::Find::name, $last_import_time); -# output_txt ("change_admin: $change_admin"); - &parse_rules ($File::Find::name); - } else { - output_txt ("ERROR: fworch-importer: phion.pm: cannot access file $File::Find::name\n", 2); - } - } - } -} - -sub conv_time_UTC { - my $UTC_diff = shift; - my $year = shift; - my $month = shift; - my $day = shift; - my $hour = shift; - my $min = shift; - my $sec= shift; - - ($year, $month, $day, $hour, $min, $sec) = Add_Delta_DHMS( $year, $month, $day, $hour, $min, $sec, 0, $UTC_diff, 0, 0 ); - return sprintf("%04d-%02d-%02d %02d:%02d:%02d", $year, $month, $day, $hour, $min, $sec); -} - -sub get_change_admin { # sets name of last_change admin for current config file in $last_change_admin global var ("" if none) - my $cfg_file = $_[0]; - my $last_ch_time = $_[1]; - my $rev_file; - my $line; - my %change; - my @change_arr = (); - my $number_of_changes_found = 0; - my $result_lc_admin = ""; - my $fehler = 0; - - if ($cfg_file =~ /^$config_path_praefix\/(.*)\/([a-zA-Z0-9\_\-\.]+)$/) { - my $path_to_file = $1; - my $basename = $2; - $rev_file = "$config_path_praefix/Revision/$path_to_file/RCS/$basename,v"; - open (IN, $rev_file) or $fehler = "Cannot open file $rev_file for reading: $!"; - if ($fehler) { - print ("WARNING: $fehler\n"); - close (IN); - } else { - PARSE_LOOP: while ( ) { - $line = $_; # Zeileninhalt merken - if ( $line =~ /^date\s+(\d\d\d\d)\.(\d\d)\.(\d\d)\.(\d\d)\.(\d\d)\.(\d\d)\;\s+author\s+(\w+?)\_/ ) { - my $year = $1; my $month = $2; my $day = $3; my $hour = $4; my $min = $5; my $sec = $6; - my $sql_time = &conv_time_UTC ( $UTC_diff, $year, $month, $day, $hour, $min, $sec ); - if ($sql_time gt $last_ch_time) { # change time lies behind last import time - so proceed - my $local_last_change_admin = $7; - $change{"$sql_time.admin"} = $local_last_change_admin; - @change_arr = (@change_arr, $sql_time); - $number_of_changes_found ++; - } else { last PARSE_LOOP; } - } - if ( $line =~ /^next\s+\;$/ ) { last PARSE_LOOP; } - } # end of while - close (IN); - if ($number_of_changes_found > 0) { - my %seen = (); # only helper variable for unique operation below - my @list_of_admins = values %change; - my @unique_list_of_admins = grep {! $seen{$_}++} @list_of_admins; - my $no_of_admins = $#unique_list_of_admins + 1; - if ($no_of_admins == 1) { - my $time = $change_arr[0]; - $result_lc_admin = $change{"$time.admin"}; - } else { - output_txt ("warning: found $no_of_admins (>1) change-admin in $cfg_file since last import: " . join (':', @unique_list_of_admins), 2); - } - } - } - $last_change_admin = $result_lc_admin; - } - return; -} - -sub process_forwarding_rule_files { &process_rule_files($forwarding_rule_file_extension); } -# sub process_local_rule_files { &process_rule_files($local_rule_file_extension); } - - -sub normalize_phion_proto { - my $proto_str_in = shift; - my $typ = ''; - my $proto = ''; - - if (($proto_str_in eq 'echo')) { $typ = 'simple'; $proto = 1;} - elsif ($proto_str_in eq 'tcp') { $typ = 'simple'; $proto = 6;} - elsif (($proto_str_in eq 'udp')) { $typ = 'simple'; $proto = 17;} - elsif (($proto_str_in eq 'group')) { $typ = 'group'; } -# elsif (($proto_str_in eq 'other')) { # from ServiceEntryOther: wait for proto one level below - return ($typ, $proto); -} - -sub normalize_phion_ports { - my $port_in = shift; - my $port = ''; - my $port_last = ''; - - if ($port_in =~ /^\s(.*?)$/) { $port_in = $1; } # remove space at beginning - if ($port_in =~ /^(\d+)\-(\d+)$/) { - $port = $1; $port_last = $2; - } elsif ($port_in =~ /^(\d+)\s(\d+)$/) { # TODO: das ist jetzt "very dirty", weil es eigentlich nur zwei Ports sind und nicht alle Ports von $1 bis $2 - $port = $1; $port_last = $2; - } elsif ($port_in =~ /^\*$/) { - $port = 0; $port_last = 65535; - } else { - $port = $port_in; - } - return ($port,$port_last); -} - -sub analyze_phion_ip { - my $addr_in = shift; - my ($addr, $addr_last, $type); - if (!defined($addr_in)) { - return (undef,undef,undef); - } - my ($net,$mask); - ($net,$mask) = split /\//, $addr_in; -# print_debug ("analyze_phion_ip: start addr_in: '$addr_in'", $debug_level, 0); - if (defined ($mask)) { - my $max_mask; - if ($net =~ /\:/) { - $max_mask = 128; - } else { - $max_mask = 32; - } - if ($mask =~ /\d+/) { - $mask = $max_mask - $mask; # umrechnen von verdrehter phion maske auf normale maske - if ($mask == 2 || $mask==3) { print_debug("warning mask=2 or 3: $net/$mask", $debug_level, 3); } - $addr = "$net/$mask"; - $type = 'network'; - } else { - print_debug("non numeric mask found in ip $addr_in: $mask", $debug_level, 0); - return (undef,undef,undef); - } - } elsif ($addr_in =~ /(\d+\.\d+\.\d+\.)(\d+)\-([\d\.]+)/) { - $addr = "$1$2"; - $addr_last = $3; - if ($addr_last !~ /\./) { # second ip contains only last byte - $addr_last = "$1$3"; - } - $type = 'host'; # keep range type for later implementation - } elsif ($addr_in =~ /[\d\.\:a-f]+/) { - $addr = $addr_in; - $addr_last = undef; - $net = undef; - $type = 'host'; - } else { - print_debug ("analyze_phion_ip: found invalid ip address \'$addr_in\'", $debug_level, 0); - return (undef,undef,undef); - } -# print_debug ("analyze_phion_ip: end addr: '$addr', type='$type'", $debug_level, 0); - return ($type,$addr,$addr_last); -} - -#**************************** -# Verarbeitung / Aufbereitung der identifizierten Parameter und Values (kontextsensitiv) -#**************************** -# store_results -sub store_results { - if (!defined($parse_obj_type)) { - print_debug ("error store_results: parse_obj_type not defined", $debug_level, 0); - return; - } - if ($parse_obj_type ne 'rules') { - if (!defined($parse_obj_id)) { - print_debug ("error: parse_obj_id not defined; type: " . defined($parse_obj_type)?$parse_obj_type:'undefined' . ", name: " . - defined($parse_obj_name)?$parse_obj_name:'undefined' . ", attr: " . defined($parse_obj_attr)?$parse_obj_attr:'undefined' . - ", value: " . defined($parse_obj_attr_value)?$parse_obj_attr_value:'undefined', $debug_level, 0); - return; - } - if ($parse_obj_state < 3) { - print_debug("Warnung: store_results mit obj_state<3 aufgerufen", $debug_level, 1); - return; - } - } - my $debug_string = "name: " . (defined($parse_obj_name)? $parse_obj_name : 'undefined') . ", attr: " . - (defined($parse_obj_attr)? $parse_obj_attr : 'undefined') . ", value: " . (defined($parse_obj_attr_value)? $parse_obj_attr_value : 'undefined'); - print_debug ($debug_string, $debug_level, 8); - if ($parse_obj_type eq "netobj" || $parse_obj_type eq "connobj") { &store_results_nw_objects(); } - elsif ($parse_obj_type eq "srvobj") { &store_results_nw_services(); } - elsif ($parse_obj_type eq "rules") { &store_results_rules(); } - else { - print_debug("store_results: found unknown parse_obj_type=$parse_obj_type",$debug_level,2); - } -} - -sub store_results_nw_objects { - if (!defined ($network_objects{"$parse_obj_id.name"})) { # schon ein bekanntes network_object? - @network_objects = (@network_objects, $parse_obj_id); - $network_objects{"$parse_obj_id.name"} = $parse_obj_name; - $network_objects{"$parse_obj_id.scope"} = $scope; - $network_objects{"$parse_obj_id.typ"} = 'simple'; # setting default values (for NetESet objects) - $network_objects{"$parse_obj_id.type"} = 'host'; - $network_objects{"$parse_obj_id.UID"} = $parse_obj_id; # default Wert nur wichtig fuer explizite Objekte - $network_objects{"$parse_obj_id.last_change_admin"} = $last_change_admin; - } - if ($convert_simple_to_group_flag) { - # altes Objekt in Gruppe umwandeln - $network_objects{"$parse_obj_id.typ"} = 'group'; - $network_objects{"$parse_obj_id.type"} = 'group'; - # zwischenspeichern der IP des ersten Elements - my $addr = ''; - if (defined($network_objects{"$parse_obj_id.ipaddr"})) { # Speichern der Adresse des ersten Elements - $addr = $network_objects{"$parse_obj_id.ipaddr"}; - $network_objects{"$parse_obj_id.ipaddr"} = ''; - } - - # Anlegen eines neuen Objekts fuer das erste Element - my $obj_mbr_id = $parse_obj_id . '__' . $addr; - @network_objects = (@network_objects, $obj_mbr_id); - $network_objects{"$obj_mbr_id.name"} = $parse_obj_name . '__' . $addr; - $network_objects{"$obj_mbr_id.scope"} = $scope; - $network_objects{"$obj_mbr_id.typ"} = 'simple'; - $network_objects{"$obj_mbr_id.UID"} = $parse_obj_id . '__' . $addr; - $network_objects{"$obj_mbr_id.last_change_admin"} = $last_change_admin; - if ($addr =~ /\/32/ || $addr =~ /\.\d+$/ || $addr =~ /\:[\da-f]+$/i || $addr =~ /\/128/) { - print_debug ("1 rewriting type to host '$addr', name=" . $network_objects{"$obj_mbr_id.name"} . ", orig type=" . $network_objects{"$parse_obj_id.type"}, $debug_level, 7); - $network_objects{"$obj_mbr_id.type"} = 'host'; - } elsif ($addr eq '') { - print_debug ("2 rewriting type to group '$addr', name=" . $network_objects{"$obj_mbr_id.name"} . ", orig type=" . $network_objects{"$parse_obj_id.type"}, $debug_level, 7); - $network_objects{"$obj_mbr_id.type"} = 'group'; - } elsif ($addr =~ /\/\d+$/) { - print_debug ("3 rewriting type to network '$addr', name=" . $network_objects{"$obj_mbr_id.name"} . ", orig type=" . $network_objects{"$parse_obj_id.type"}, $debug_level, 7); - $network_objects{"$obj_mbr_id.type"} = 'network'; - } else { - print_debug ("4 leaving type as was '$addr', name=" . $network_objects{"$obj_mbr_id.name"} . ", orig type=" . $network_objects{"$parse_obj_id.type"}, $debug_level, 2); - $network_objects{"$obj_mbr_id.type"} = $network_objects{"$parse_obj_id.type"}; ### old line - } - $network_objects{"$obj_mbr_id.ipaddr"} = $addr; - $network_objects{"$obj_mbr_id.ipaddr_last"} = $network_objects{"$parse_obj_id.ipaddr_last"}; - $network_objects{"$parse_obj_id.members"} = $parse_obj_name . '__' . $addr; # jetzt das erste Element als einzigen Member hinzufuegen - $network_objects{"$parse_obj_id.member_refs"} = $obj_mbr_id; - - $convert_simple_to_group_flag = 0; - } # das zweite Element wird anschliessend (bei addr-Zeile in state 5) normal als member hinzugefuegt - # Daten im Hash ergaenzen - elsif ($collecting_group_members) { - if ($parse_obj_attr eq 'ref') { - if (defined($network_objects{"$parse_obj_id.members"})) { - $network_objects{"$parse_obj_id.members"} .= ( $GROUPSEP . $parse_obj_attr_value ); - } else { - $network_objects{"$parse_obj_id.members"} = $parse_obj_attr_value; - $network_objects{"$parse_obj_id.typ"} = 'group'; - $network_objects{"$parse_obj_id.type"} = 'group'; - } - } elsif ($parse_obj_attr eq 'refid') { - if (defined($network_objects{"$parse_obj_id.member_refs"})) { - $network_objects{"$parse_obj_id.member_refs"} .= ( $GROUPSEP . $parse_obj_attr_value ); - } else { - $network_objects{"$parse_obj_id.member_refs"} = $parse_obj_attr_value; - } - } elsif (($parse_obj_attr eq 'addr' || $parse_obj_attr eq 'addr6') && $parse_obj_attr_value ne '0.0.0.0') { # explizite Gruppe - # create new object - my ($tmp_addr, $tmp_addr_last, $tmp_type); - my $parse_obj_member_name; - my $parse_obj_member_id; - - ($tmp_type,$tmp_addr,$tmp_addr_last) = analyze_phion_ip($parse_obj_attr_value); - $parse_obj_member_name = $parse_obj_name . '__' . $tmp_addr; - $parse_obj_member_id = $parse_obj_id . '__' . $tmp_addr; - if (defined($tmp_addr_last)) { - $parse_obj_member_name .= "-$tmp_addr_last"; - $parse_obj_member_id .= "-$tmp_addr_last"; - } - $network_objects{"$parse_obj_member_id.type"} = $tmp_type; - $network_objects{"$parse_obj_member_id.ipaddr"} = $tmp_addr; - $network_objects{"$parse_obj_member_id.ipaddr_last"} = $tmp_addr_last; - print_debug ("\nfound new explicit nw_obj group member: $parse_obj_member_id", $debug_level, 8); - @network_objects = (@network_objects, $parse_obj_member_id); - $network_objects{"$parse_obj_member_id.name"} = $parse_obj_member_name; - $network_objects{"$parse_obj_member_id.scope"} = $scope; - $network_objects{"$parse_obj_member_id.typ"} = 'simple'; - $network_objects{"$parse_obj_member_id.UID"} = $parse_obj_member_id; - $network_objects{"$parse_obj_member_id.last_change_admin"} = $last_change_admin; - - # jetzt die Gruppenreferenzen auf das neue Objekt setzen, sind ja schon definiert, da hier #members >= 2 - $network_objects{"$parse_obj_id.member_refs"} .= ( $GROUPSEP . $parse_obj_member_id ); - $network_objects{"$parse_obj_id.members"} .= ( $GROUPSEP . $parse_obj_member_name ); - } else { - print_debug ("WARNING: store_nw_results called to add group member without match: $parse_obj_attr", $debug_level, 7); - } - } elsif (defined($parse_obj_attr_value)) { - # Attribute aufarbeiten - SWITCH_OBJ_ATTR: { - if ($parse_obj_attr eq 'oid') { - $network_objects{"$parse_obj_id.UID"} = $parse_obj_attr_value; - last SWITCH_OBJ_ATTR; - } - if (($parse_obj_attr eq 'addr' || $parse_obj_attr eq 'addr6') && $parse_obj_attr_value ne '0.0.0.0') { - $network_objects{"$parse_obj_id.typ"} = 'simple'; - ($network_objects{"$parse_obj_id.type"},$network_objects{"$parse_obj_id.ipaddr"},$network_objects{"$parse_obj_id.ipaddr_last"}) = - analyze_phion_ip($parse_obj_attr_value); - $parse_obj_attr_value = $network_objects{"$parse_obj_id.ipaddr"}; # necessary? - last SWITCH_OBJ_ATTR; - } - if ($parse_obj_attr eq 'comment') { - $network_objects{"$parse_obj_id.$parse_obj_attr"} = $parse_obj_attr_value; # stores only comments - } - } - } -} - -sub store_results_nw_services { - if (!defined ($services{"$parse_obj_id.name"})) { # schon ein bekannter dienst? - @services = (@services, $parse_obj_id); - $services{"$parse_obj_id.name"} = $parse_obj_name; - $services{"$parse_obj_id.scope"} = $scope; - $services{"$parse_obj_id.type"} = 'group'; - $services{"$parse_obj_id.typ"} = 'group'; - $services{"$parse_obj_id.UID"} = $parse_obj_id; # default Wert nur wichtig fuer explizite Dienste - $services{"$parse_obj_id.last_change_admin"} = $last_change_admin; - } - - if ($convert_simple_to_group_flag) { - # altes Objekt in Gruppe umwandeln - $services{"$parse_obj_id.typ"} = 'group'; - $services{"$parse_obj_id.type"} = 'group'; - # zwischenspeichern des Zielports des ersten Elements - my $proto = ''; - my $dport = ''; - my $dport_last = ''; - my $type = ''; - if (defined($services{"$parse_obj_id.port"})) { # Speichern der Daten des ersten Elements - $dport = $services{"$parse_obj_id.port"}; - $services{"$parse_obj_id.port"} = ''; - } - if (defined($services{"$parse_obj_id.port_last"})) { - $dport_last = $services{"$parse_obj_id.port_last"}; - $services{"$parse_obj_id.port_last"} = ''; - } - if (defined($services{"$parse_obj_id.ip_proto"})) { - $proto = $services{"$parse_obj_id.ip_proto"}; - $services{"$parse_obj_id.ip_proto"} = ''; - } - if (defined($services{"$parse_obj_id.type"})) { - $type = $services{"$parse_obj_id.type"}; - $services{"$parse_obj_id.type"} = ''; - } - my $svc_ext = "/$proto/$dport"; if ($dport_last ne '') { $svc_ext .= "-$dport_last"; } - - # Anlegen eines neuen Objekts fuer das erste Element - my $obj_mbr_id = "$parse_obj_id/$scope/$svc_ext"; - @services = (@services, $obj_mbr_id); - $services{"$obj_mbr_id.name"} = $parse_obj_name . $svc_ext; - $services{"$obj_mbr_id.scope"} = $scope; - $services{"$obj_mbr_id.typ"} = 'simple'; - $services{"$obj_mbr_id.type"} = $type; - $services{"$obj_mbr_id.UID"} = $obj_mbr_id; - $services{"$obj_mbr_id.port"} = $dport; - $services{"$obj_mbr_id.port_last"} = $dport_last; - $services{"$obj_mbr_id.ip_proto"} = $proto; - $services{"$obj_mbr_id.last_change_admin"} = $last_change_admin; - - # jetzt das erste Element als einzigen Member hinzufuegen - $services{"$parse_obj_id.members"} = $parse_obj_name . $svc_ext; - $services{"$parse_obj_id.member_refs"} = $obj_mbr_id; - - $convert_simple_to_group_flag = 0; - } # das zweite Element wird anschliessend (bei addr-Zeile in state 5) normal als member hinzugefuegt - # Daten im Hash ergaenzen - elsif ($collecting_group_members) { - if ($parse_obj_attr eq 'ref') { - if (defined($services{"$parse_obj_id.members"})) { - $services{"$parse_obj_id.members"} .= ( $GROUPSEP . $parse_obj_attr_value ); - } else { - $services{"$parse_obj_id.members"} = $parse_obj_attr_value; - $services{"$parse_obj_id.typ"} = 'group'; - $services{"$parse_obj_id.type"} = 'group'; - } - } elsif ($parse_obj_attr eq 'refid') { - if (defined($services{"$parse_obj_id.member_refs"})) { - $services{"$parse_obj_id.member_refs"} .= ( $GROUPSEP . $parse_obj_attr_value ); - } else { - $services{"$parse_obj_id.member_refs"} = $parse_obj_attr_value; - } - } elsif ($parse_obj_attr eq 'portLimit') { # explizite Gruppe - # create new object - my ($new_port, $new_port_last, $new_svc_ext, $new_proto); - $new_proto = &normalize_phion_proto($proto_of_explicit_svc_group); - ($new_port, $new_port_last) = &normalize_phion_ports($parse_obj_attr_value); - $new_svc_ext = "/$new_proto/$new_port"; if ($new_port_last ne '') { $new_svc_ext .= "-$new_port_last"; } - my $parse_obj_member_name = $parse_obj_name . $new_svc_ext; - my $parse_obj_member_id = "$parse_obj_id/$scope/$new_svc_ext"; - if (!defined($services{"$parse_obj_member_id.name"})) { - @services = (@services, $parse_obj_member_id); - $services{"$parse_obj_member_id.name"} = $parse_obj_member_name; - $services{"$parse_obj_member_id.scope"} = $scope; - $services{"$parse_obj_member_id.typ"} = 'simple'; - $services{"$parse_obj_member_id.type"} = (($parse_obj_attr_value =~ /\//)?'network':'host'); - $services{"$parse_obj_member_id.UID"} = $parse_obj_member_id; - $services{"$parse_obj_member_id.port"} = $new_port; - $services{"$parse_obj_member_id.port_last"} = $new_port_last; - $services{"$parse_obj_member_id.ip_proto"} = $new_proto; - $services{"$parse_obj_member_id.last_change_admin"} = $last_change_admin; - } - - # jetzt die Gruppenreferenzen auf das neue Objekt setzen, sind ja schon definiert, da hier #members >= 2 - $services{"$parse_obj_id.member_refs"} .= ( $GROUPSEP . $parse_obj_member_id ); - $services{"$parse_obj_id.members"} .= ( $GROUPSEP . $parse_obj_member_name ); - } else { - print_debug ("WARNING: store_nw_results called to add group member without match: $parse_obj_attr", $debug_level, 7); - } - } elsif (defined($parse_obj_attr_value)) { - # Attribute aufarbeiten - SWITCH_OBJ_ATTR: { - if ($parse_obj_attr eq 'oid') { - $services{"$parse_obj_id.UID"} = $parse_obj_attr_value; - last SWITCH_OBJ_ATTR; - } - if ($parse_obj_attr eq 'portLimit') { - ($services{"$parse_obj_id.port"}, $services{"$parse_obj_id.port_last"}) = - &normalize_phion_ports($parse_obj_attr_value); - last SWITCH_OBJ_ATTR; - } - if (($parse_obj_attr eq 'botClientPort')) { - $services{"$parse_obj_id.src_port"} = $parse_obj_attr_value; - last SWITCH_OBJ_ATTR; - } - if (($parse_obj_attr eq 'topClientPort')) { - $services{"$parse_obj_id.src_port_last"} = $parse_obj_attr_value; - last SWITCH_OBJ_ATTR; - } - if ($parse_obj_attr eq 'sessionTimeout') { - $services{"$parse_obj_id.timeout"} = $parse_obj_attr_value; - last SWITCH_OBJ_ATTR; - } - if (($parse_obj_attr eq 'proto')) { - $services{"$parse_obj_id.typ"} = 'simple'; - $services{"$parse_obj_id.ip_proto"} = $parse_obj_attr_value; - } - if (($parse_obj_attr eq 'type')) { - $services{"$parse_obj_id.$parse_obj_attr"} = $parse_obj_attr_value; - ($services{"$parse_obj_id.typ"},$services{"$parse_obj_id.ip_proto"}) = - &normalize_phion_proto($parse_obj_attr_value); - last SWITCH_OBJ_ATTR; - } - # Als default das Attribut und den Wert sichern - $services{"$parse_obj_id.$parse_obj_attr"} = $parse_obj_attr_value; - } - } -} - -sub store_results_maplist { # ($nat_group_name, $nat_group_oid, $nat_group_comment, $mapping_details, $debug_level); - my $nat_obj_name = shift; - my $nat_obj_uid = shift; - my $nat_obj_comment = shift; - my $list_of_nat = shift; - my $debug_level = shift; - my $member_count = 0; - my $remaining_nat_ip_line = $list_of_nat; - - if (!defined($debug_level)) { $debug_level = 0; } - - if (!defined($nat_obj_name) || !defined($nat_obj_uid)) { return; } - if (!defined($nat_obj_comment)) { $nat_obj_comment = ''; } - print_debug("entering store_results_maplist: nat obj name=$nat_obj_name, nat obj uid=$nat_obj_uid, comment=$nat_obj_comment, mapList=$list_of_nat", $debug_level, 5); - while ($remaining_nat_ip_line =~ /^\s*(\d+\.\d+\.\d+\.\d+)\-\>\d+\.\d+\.\d+\.\d+\s?(.*)/) { # multiple ip nattings - $parse_obj_attr_value = $1; # incoming ip address - $remaining_nat_ip_line = $2; - $parse_obj_attr = 'addr'; - if ($member_count==0) { - $parse_obj_name = $nat_obj_name; -# $parse_obj_id = $nat_obj_uid; -# problem: UID != oid but just the name of the object, needs to be this way for rule ref to work - $parse_obj_id = $nat_obj_name; - print_debug(" nat map storing nat group name=$parse_obj_name, value=$parse_obj_attr_value, attr=$parse_obj_attr, id=$parse_obj_id", $debug_level, 5); - &store_results(); # store group object as single ip host - # turn object into group: - $network_objects{"$nat_obj_name.typ"} = 'group'; - $network_objects{"$nat_obj_name.type"} = 'group'; - } - $parse_obj_name = "$nat_obj_name" . "_nat_ip_$parse_obj_attr_value"; - $parse_obj_id = $parse_obj_name . "_" . $nat_obj_uid; - print_debug(" nat map storing nat single ip name=$parse_obj_name, value=$parse_obj_attr_value, attr=$parse_obj_attr, id=$parse_obj_id", $debug_level, 5); - &store_results(); # store object as single ip host - # add object to group: - if ($member_count==0) { - $network_objects{"$nat_obj_name.member_refs"} = $parse_obj_id; - $network_objects{"$nat_obj_name.members"} = $parse_obj_name; - undef ($network_objects{"$nat_obj_name.ipaddr"}); - } else { - $network_objects{"$nat_obj_name.member_refs"} .= ( $GROUPSEP . $parse_obj_id ); - $network_objects{"$nat_obj_name.members"} .= ( $GROUPSEP . $parse_obj_name ); - } - $member_count ++; - } - return; -} - -#---------------------------------------- -# Funktion parse_basic_elements -# Parameter: in_file: config file # Parameter: rulesetname, um nicht alle rulesets zu parsen -# zeilenweises Einlesen der Konfigurationsdatei (nw-services und nw-objects) -# Resultat: keins -#---------------------------------------- - -sub parse_basic_elements { - my $in_file = $_[0]; - my $ln = 0; # line number - my $line = ''; - my $last_line = ''; - my ($nat_group_name, $nat_group_oid, $nat_group_comment); - - $parse_obj_state = 0; - open (IN, $in_file) || die "$in_file konnte nicht geoeffnet werden.\n"; - LINE: while ( ) { - $line = $_; # Zeileninhalt merken -# print ("line: $line\n"); - $last_line = $line; # fuer end of line check - $line =~ s/\x0D/\\r/g; # literal carriage return entfernen - $line =~ s/\r\n/\n/g; # handle cr,nl - chomp ($line); - $ln++; # Zeilennummer merken - -########## parse obj state 1: main level for dividing into obj,svc, ... ################################################ - # state 1 start of type, z.B. " netobj={" -# if ( /^\t([\w\-\.\_]+)\=\{$/ ) { - if ( /^\t(netobj)\=\{$/ || /^\t(srvobj)\=\{$/ || /^\t(connobj)\=\{$/ ) { - $parse_obj_state = 1; - $parse_obj_type = $1; - print_debug("up 0 (type: $parse_obj_type) => 1 at line no. $ln: $line", $debug_level, 3); - } elsif ( /^\t\}$/ ) { - $parse_obj_state = 0; - undef ($parse_obj_type); - } -########## parse obj state 2: main level for (new) element ################################################ - if (defined ($parse_obj_type)) { - if ((/^\t\t([\w]+)\{$/) && ( ($parse_obj_state == 2) || ($parse_obj_state == 1))) { - $parse_obj_state = 2; - } - if (/^\t\t\}$/) { # Ende der Element-Definition - $parse_obj_state = 1; - undef ($parse_obj_name); - undef ($parse_obj_id); - } - ########## parse obj state 3: get element base data (name, comment, ...) ################################################ - if ((/^\t{3}(\w+)\=\{(.*?)$/) && ( ($parse_obj_state == 3) || ($parse_obj_state == 2))) { - $parse_obj_state = 3; - $parse_obj_attr = $1; - if ($2 ne '') { # Ist der Wert in der aktuellen Zeile nicht leer? - # value zwischenspeichern und untersuchen - my $local_line = $2; - # Ist der Wert in einer Zeile mit dem Parameter angegeben und nicht leer? - if ($local_line =~(/^(.+)\}$/)) { - $parse_obj_attr_value = $1; -### maplist handling - if ($parse_obj_type eq 'connobj') { - if ($parse_obj_attr eq 'name') { $nat_group_name = $parse_obj_attr_value; } - if ($parse_obj_attr eq 'oid') { $nat_group_oid = $parse_obj_attr_value; } - if ($parse_obj_attr eq 'comment') { $nat_group_comment = $parse_obj_attr_value; } - if ($parse_obj_attr eq 'mapList') { -# storing dest nat object(s) from connection obj definition, assuming that mapList is always last statement of connobj definition - &store_results_maplist($nat_group_name, $nat_group_oid, $nat_group_comment, $parse_obj_attr_value, $debug_level); - } - next LINE; - } -### end of maplist handling - if ($parse_obj_attr eq 'name') { - $parse_obj_name = $parse_obj_attr_value; - $parse_obj_id = $parse_obj_attr_value; # Default-Wert fuer den Fall, dass keine OID vorhanden ist - } # found name of element - if ($parse_obj_attr eq 'oid') { $parse_obj_id = $parse_obj_attr_value; } - if ( ($parse_obj_attr eq 'comment') || ($parse_obj_attr eq 'oid') ) { - store_results(); - } - # Keine Gruppe/Liste geoeffnt, daher parse_obj_state auf Level 3 belassen - undef ($parse_obj_attr); - } - } elsif ($parse_obj_attr eq 'list' || $parse_obj_attr eq 'neglist') { - $parse_obj_neglist = 0; - $member_counter = 0; - if ($parse_obj_attr eq 'neglist') { - $parse_obj_neglist = 1; - } - $parse_obj_state = 4; # jetzt koennen beliebige Listen kommen (Laenge >=1) - } - } - if ((/^\t{3}\}$/)) { # Ende des state 3 - $collecting_group_members = 0; # jetzt ist die Gruppe, sofern angefangen, zu Ende - undef($parse_obj_attr); - } - ########## parse obj state 4: Zwischenebene mit wenig Configdaten ################################################ - if ( (/^\t{4}(\w+)\{$/) ) { - $parse_obj_state = 4; - $parse_obj_attr_ext = $1; - $convert_simple_to_group_flag = 0; - $member_counter ++; - if ($member_counter == 2 && !$collecting_group_members) { # doch eine "explizite" Gruppe - if (defined($parse_obj_name)) { print_debug ("found explicit group: $parse_obj_name", $debug_level, 5); } - # rename existing object (group_name + addr / destport) - # create group - $convert_simple_to_group_flag = 1; - &store_results(); # convert to group and add first (already read) group member - $collecting_group_members = 1; - } - if (!((($parse_obj_attr_ext eq 'NetEntry' || $parse_obj_attr_ext eq 'NetRef') && $parse_obj_type eq 'netobj') || - (($parse_obj_attr_ext eq 'ServiceEntryTCP' || $parse_obj_attr_ext eq 'ServiceEntryUDP' || - $parse_obj_attr_ext eq 'ServiceRef' || $parse_obj_attr_ext eq 'ServiceEntryEcho' || - $parse_obj_attr_ext eq 'ServiceEntryOther') # for other ip protos - && $parse_obj_type eq 'srvobj') )) { - print_debug ("WARNING: found unknown or misplaced element $parse_obj_attr_ext in section $parse_obj_type", $debug_level, 7); - } - if (!$collecting_group_members && ($parse_obj_attr_ext eq 'NetRef' || $parse_obj_attr_ext eq 'ServiceRef')) { - $collecting_group_members = 1; # Gruppe faengt an - } - if ($parse_obj_attr_ext =~ 'Entry') { - if ($parse_obj_attr_ext =~ /^ServiceEntry(.*?)$/ ) { - # das IP-Protokoll extrahieren - $parse_obj_attr = 'type'; - $parse_obj_attr_value = lc($1); - $proto_of_explicit_svc_group = $parse_obj_attr_value; - &store_results(); - $parse_obj_attr = ''; $parse_obj_attr_value = ''; - } - } - } - # Ende des state 4 - if ((/^\t{4}\}$/) && ($parse_obj_state < 10)) { - $parse_obj_state = 3; - undef ($parse_obj_attr_ext); undef ($parse_obj_attr_ext_value); - } - ########## parse obj state 5: get element details ################################################ - if ((/^\t{5}\s?(\w+)\=\{(.*?)\}$/) && ( ($parse_obj_state == 5) || ($parse_obj_state == 4))) { - $parse_obj_state = 5; - if ($2 ne '') { - $parse_obj_attr = $1; - $parse_obj_attr_value = $2; - if ($parse_obj_attr eq 'addr' || $parse_obj_attr eq 'addr6' || $parse_obj_attr eq 'comment' || - $parse_obj_attr eq 'sessionTimeout' || $parse_obj_attr eq 'botClientPort' || - $parse_obj_attr eq 'topClientPort' || $parse_obj_attr eq 'portLimit' || - $parse_obj_attr eq 'proto' || - $parse_obj_attr eq 'ref' || $parse_obj_attr eq 'refid' ) { - &store_results(); - } - } - } - # Ende des state 5 - if ((/^\t{5}\}$/)) { - $parse_obj_state = 4; - } - } - } # end of while - close (IN); - print_debug ("$in_file closed",$debug_level,8); - # check auf Vollstaendigkeit des Config-Files: - if ($last_line =~ m/^\}(\n)?$/) { return 0; } - else { return "ERROR: last line of config-file $in_file not correct: <$last_line>"; } -} - -##################################################### - -sub store_results_rules { - if ($parse_obj_state==0) { # nur am Ende eines Regelsatzes: Regelreihenfolge wegschreiben - $rulebases{"$scope.ruleorder"} = join (',', @ruleorder); - undef @ruleorder; - # last change admin fuer gesamtes Regelwerk setzen -# $rulebases{"$scope.last_change_admin"} = $last_change_admin; # wird derzeit nicht ausgewertet, nur pro Regel - } elsif ($parse_obj_state==1) { # nur am Ende einer Regel, ggf. UID setzen - $ruleorder[$parserule_rulenum] = $parserule_rulenum; # Regeln sind einfach von 1-n durchnummeriert - if (!defined ($rulebases{"$scope.$parserule_rulenum.UID"})) { # UID setzen, falls noch nicht geschehen - $rulebases{"$scope.$parserule_rulenum.UID"} = "$scope:" . $rulebases{"$scope.$parserule_rulenum.name"}; - } - $rulebases{"$scope.$parserule_rulenum.last_change_admin"} = $last_change_admin; # last_change_admin pro Regel setzen - $parserule_rulenum++; - undef ($parse_obj_name); - undef ($parse_obj_id); - } else { # schon eine bekannte Regel? - if (!defined ($rulebases{"$scope.$parserule_rulenum.name"})) { - if (!defined($rulebases{"$scope.rulecount"})) { - $rulebases{"$scope.rulecount"} = 1; - } else { - $rulebases{"$scope.rulecount"} += 1; - } - $rulebases{"$scope.$parserule_rulenum.name"} = $parse_obj_name; - $rulebases{"$scope.$parserule_rulenum.src.op"} = '0'; - $rulebases{"$scope.$parserule_rulenum.dst.op"} = '0'; - $rulebases{"$scope.$parserule_rulenum.services.op"} = '0'; - } - # Daten im Hash ergaenzen - if (defined($parse_rule_field)) { - if ($parse_obj_attr eq 'ref') { - if (defined($rulebases{"$scope.$parserule_rulenum.$parse_rule_field"})) { - $rulebases{"$scope.$parserule_rulenum.$parse_rule_field"} .= ( $GROUPSEP . $parse_obj_attr_value ); - $rulebases{"$scope.$parserule_rulenum.$parse_rule_field.refs"} .= $GROUPSEP; # ref_Feld ebenfalls erweitern um ein Element (falls ref_id leer) - } else { - $rulebases{"$scope.$parserule_rulenum.$parse_rule_field"} = $parse_obj_attr_value; - $rulebases{"$scope.$parserule_rulenum.$parse_rule_field.refs"} = '' - } - } elsif ($parse_obj_attr eq 'refid') { # Annahme: ref_id kommt immer nach ref - $rulebases{"$scope.$parserule_rulenum.$parse_rule_field.refs"} .= $parse_obj_attr_value; - } elsif ($parse_obj_attr eq 'action') { - print_debug ("found action: $parse_obj_attr_value", $debug_level, 7); - if ($parse_obj_attr_value eq 'ActionPass') { $parse_obj_attr_value = 'accept'; } - elsif ($parse_obj_attr_value eq 'ActionDeny') { $parse_obj_attr_value = 'reject'; } - elsif ($parse_obj_attr_value eq 'ActionBlock') { $parse_obj_attr_value = 'drop'; } - elsif ($parse_obj_attr_value eq 'ActionRedirect') { $parse_obj_attr_value = 'redirect'; } - elsif ($parse_obj_attr_value eq 'ActionMap') { $parse_obj_attr_value = 'map'; } - $rulebases{"$scope.$parserule_rulenum.action"} = $parse_obj_attr_value; - } elsif ($parse_obj_attr eq 'subsetName') { - print_debug ("found action subsetName: $parse_obj_attr_value", $debug_level,7); - $rulebases{"$scope.$parserule_rulenum.action.subsetName"} = $parse_obj_attr_value; - } else { - print_debug ("group member attribute: $parse_obj_attr/$parse_obj_attr_value - ignoring", $debug_level, 7); - } - } elsif (defined($parse_obj_attr_value)) { - if ($parse_obj_state < 5) { # rule top level - # Attribute aufarbeiten - SWITCH_OBJ_ATTR: { - if ($parse_obj_attr eq 'oid') { - $rulebases{"$scope.$parserule_rulenum.UID"} = $parse_obj_attr_value; - last SWITCH_OBJ_ATTR; - } - if ($parse_obj_attr eq 'deactivated') { - $rulebases{"$scope.$parserule_rulenum.disabled"} = $parse_obj_attr_value; - last SWITCH_OBJ_ATTR; - } - if ($parse_obj_attr eq 'noLog') { - if ($parse_obj_attr_value eq '0') { - $rulebases{"$scope.$parserule_rulenum.track"} = 'log'; - } elsif ($parse_obj_attr_value eq '1') { - $rulebases{"$scope.$parserule_rulenum.track"} = 'none'; - } - last SWITCH_OBJ_ATTR; - } - if ($parse_obj_attr eq 'timeAllow') { - $rulebases{"$scope.$parserule_rulenum.time"} = $parse_obj_attr_value; - last SWITCH_OBJ_ATTR; - } - if ($parse_obj_attr eq 'comment') { - $rulebases{"$scope.$parserule_rulenum.comments"} = $parse_obj_attr_value; - last SWITCH_OBJ_ATTR; - } - $rulebases{"$scope.$parserule_rulenum.$parse_obj_attr"} = $parse_obj_attr_value; - } - } - if ($parse_obj_attr eq 'bothWays' && $parse_obj_attr_value eq '1') { # bidirectional rule - $rulebases{"$scope.$parserule_rulenum.bidir"} = $parse_obj_attr_value; - } - } - } -} - -#---------------------------------------- -# Funktion section_titles_correction -# Parameter: none -#---------------------------------------- -# for each rule: -# check if src/dst/srv are empty -# add header_text -# add dummy src/dst/srv objects - -sub section_titles_correction { - my ($count, $rulebase_name); - my @ruleorder; - - sub get_any_nwobj_refs { - my $obj_id; - foreach $obj_id (@network_objects) { if ($network_objects{"$obj_id.name"} eq 'World') { return $obj_id; } } - return undef; - } - - sub get_any_srvobj_refs { - my $svc_id; - foreach $svc_id (@services) { if ($services{"$svc_id.name"} eq 'ALL') { return $svc_id; } } - return undef; - } - - sub is_phion_section_title { - my $rulebase_name = shift; - my $rule_number = shift; - - if ( !defined($rulebases{"$rulebase_name.$rule_number.src"}) && - !defined($rulebases{"$rulebase_name.$rule_number.dst"}) && - !defined($rulebases{"$rulebase_name.$rule_number.services"})) { - return 1; - } else { - return 0; - } - } - - my $any_nwobj_ref = &get_any_nwobj_refs(); - my $any_srvobj_ref = &get_any_srvobj_refs(); - - if (!defined($any_nwobj_ref) || !defined($any_srvobj_ref)) { - print_debug ('error: no any objects found in config', $debug_level, 1); - } else { - foreach $rulebase_name (@rulebases) { - if (defined($rulebases{"$rulebase_name.rulecount"}) && defined ($rulebases{"$rulebase_name.ruleorder"}) ) { - @ruleorder = split(/\,/, $rulebases{"$rulebase_name.ruleorder"}); - $count = 0; - while ($count < $rulebases{"$rulebase_name.rulecount"}) { - my $rule_number = $ruleorder[$count]; - print_debug ("rulebase: $rulebase_name, rule_no: $rule_number", $debug_level, 8); - if (&is_phion_section_title($rulebase_name, $rule_number)) { - # Section-Title vervollstaendigen - $rulebases{"$rulebase_name.$ruleorder[$count].header_text"} = $rulebases{"$rulebase_name.$ruleorder[$count].name"}; - if (defined($rulebases{"$rulebase_name.$ruleorder[$count].UID"})) { - $rulebases{"$rulebase_name.$ruleorder[$count].UID"} .= $rulebases{"$rulebase_name.$ruleorder[$count].name"}; - } else { - $rulebases{"$rulebase_name.$ruleorder[$count].UID"} = $rulebase_name . "." . $rulebases{"$rulebase_name.$ruleorder[$count].name"}; - } - $rulebases{"$rulebase_name.$ruleorder[$count].action"} = 'drop'; - $rulebases{"$rulebase_name.$ruleorder[$count].src"} = 'World'; - $rulebases{"$rulebase_name.$ruleorder[$count].src.refs"} = $any_nwobj_ref; - $rulebases{"$rulebase_name.$ruleorder[$count].dst"} = 'World'; - $rulebases{"$rulebase_name.$ruleorder[$count].dst.refs"} = $any_nwobj_ref; - $rulebases{"$rulebase_name.$ruleorder[$count].services"} = 'ALL'; - $rulebases{"$rulebase_name.$ruleorder[$count].services.refs"} = $any_srvobj_ref; - } - $count ++; - } - } - } - } -} - -sub fix_single_field_references { - my $rulebase_name = shift; - my $field = shift; - my $rule_count = shift; - my (@names, @names_original); - my @refs = (); - - if (defined ($rulebases{"$rulebase_name.$rule_count.$field"}) && $rulebases{"$rulebase_name.$rule_count.$field"} ne '') { - @names = split (/\|/, $rulebases{"$rulebase_name.$rule_count.$field"}); - @names_original = @names; - my $idx=0; my $changed=0; - if (defined $rulebases{"$rulebase_name.$rule_count.$field.refs"}) { - @refs = split (/\|/, $rulebases{"$rulebase_name.$rule_count.$field.refs"}); # explicit use of | instead of $GROUPSEP - } else { - print_debug ("phion.pm WARNING (0): $rulebase_name, all refs undefined for rule $rule_count.$field.refs, name: " . $rulebases{"$rulebase_name.$rule_count.$field"}, $debug_level, 8); - } - ELEMENT: while ($idx assume explicite object definition - if ($field eq 'services') { - if (defined ($services{"$names[$idx].name"}) && $services{"$names[$idx].name"} ne '') { - print_debug ("phion.pm fixref WARNING (1): service in $rulebase_name, repairing ref to explicite $field object " . $names[$idx], $debug_level, 6); - $refs[$idx] = $names[$idx]; - $changed=1; - } else { # even name is not set: delete element - print_debug ("phion.pm WARNING (2): service in $rulebase_name, deleting broken references to incomplete $field object " . $names[$idx], $debug_level, 6); - splice (@refs, $idx, 1); - splice (@names, $idx, 1); -# $idx--; - next ELEMENT; - } - } else { # network_objects - if (defined ($network_objects{"$names[$idx].name"}) && $network_objects{"$names[$idx].name"} ne '') { # no references are defined --> assume explicite object definition - if ((defined ($network_objects{"$names[$idx].ipaddr"}) && $network_objects{"$names[$idx].ipaddr"} ne '') || - (defined ($network_objects{"$names[$idx].members"}) && $network_objects{"$names[$idx].members"} ne '')) { - $refs[$idx] = $names[$idx]; - print_debug ("phion.pm fixref WARNING (3): $rulebase_name, fixing ref to $field object " . $names[$idx], $debug_level, 6); - } else { # even name is not set: delete element - print_debug ("phion.pm WARNING (4): $rulebase_name, deleting broken references to incomplete $field object " . $names[$idx], $debug_level, 6); - splice (@refs, $idx, 1); - splice (@names, $idx, 1); -# $idx--; - next ELEMENT; - } - } else { # network objects: network_object in rule is not defined - if ($names[$idx] =~ /(.*?)\:bwd$/) { # NAT network objects in dst - $names[$idx] = $1; - if (defined($network_objects{"$names[$idx].name"})) { - $refs[$idx] = $network_objects{"$names[$idx].UID"}; - print_debug ("phion.pm fixref WARNING (6): $rulebase_name, fixing ref to $field NAT object " . $names[$idx], $debug_level, 6); - } else { - if (defined($network_objects{"$names[$idx].name"}) || defined($network_objects{"$names[$idx].UID"})) { - print_debug ("phion.pm fixref WARNING (7): undefined NAT object " . $names[$idx] . ", nwobj-name: ". $network_objects{"$names[$idx].name"} . - ", uid=" . $network_objects{"$names[$idx].UID"}, $debug_level, 6); - } else { - print_debug ("phion.pm fixref WARNING (8): undefined NAT object " . $names[$idx], $debug_level, 6); - } - } - $changed = 1; - } else { # if no nat object and not defined as nw object, then delete it - print_debug ("phion.pm WARNING (5): $rulebase_name, deleting broken references to non-existant $field object " . $names[$idx], $debug_level, 6); - splice (@refs, $idx, 1); - splice (@names, $idx, 1); -# $idx--; - next ELEMENT; - } - } - $changed=1; - } - } else { - # refs are defined - but are they pointing anyhere? - } -=POD - if ((defined($refs[$idx]) && $refs[$idx] ne '' && $field eq 'services' && !defined ($services{"$refs[$idx].UID"}))) { # ref ist defined but points to nowhere - print ("phion.pm WARNING (10): $rulebase_name, removing broken references to incomplete $field object " . $names[$idx] . "\n"); - splice (@refs, $idx, 1); - splice (@names, $idx, 1); - $idx--; - $changed=1; - next ELEMENT; - } - if ((defined($refs[$idx]) && $refs[$idx] ne '' && ($field eq 'src' || $field eq 'dst')) && !defined($network_objects{"$refs[$idx].UID"})) { # ref ist defined but points to nowhere - print ("phion.pm WARNING (10): $rulebase_name, removing broken references to incomplete network $field object " . $names[$idx] . "\n"); - splice (@refs, $idx, 1); - splice (@names, $idx, 1); - $idx--; - $changed=1; - next ELEMENT; - } -=cut - $idx++; - } - if ($changed) { - print_debug ("changed list from " . join("$GROUPSEP", @names_original) . "\nto " . join("$GROUPSEP", @names), $debug_level, 6); - if (scalar(@names) == 0) { # if a whole field was deleted then delete the whole rule - print_debug ("phion.pm fixref ERROR (6): $rulebase_name, deleted whole field $field object of rule no. $idx:\n" . - "src: " . $rulebases{"$rulebase_name.$rule_count.src"} . "\n" . - "dst: " . $rulebases{"$rulebase_name.$rule_count.dst"} . "\n" . - "svc: " . $rulebases{"$rulebase_name.$rule_count.services"}, $debug_level, 7); - return ("\n"); - } - } - return join("$GROUPSEP", @names) . "\n" . join("$GROUPSEP", @refs); - } else { - return ("\n"); - } -} - -sub delete_whole_rule_if_a_relevant_field_is_empty { - my $rulebase_name = shift; - my $rule_count = shift; - my $to_be_deleted=0; - my @ruleorder = split(/\,/, $rulebases{"$rulebase_name.ruleorder"}); - - if (!defined($rulebases{"$rulebase_name.$ruleorder[$rule_count].src"}) || !defined($rulebases{"$rulebase_name.$ruleorder[$rule_count].dst"}) || - !defined($rulebases{"$rulebase_name.$ruleorder[$rule_count].services"})) { - $to_be_deleted = 1; - } elsif ($rulebases{"$rulebase_name.$ruleorder[$rule_count].src"} eq '' || $rulebases{"$rulebase_name.$ruleorder[$rule_count].dst"} eq '' || $rulebases{"$rulebase_name.$ruleorder[$rule_count].services"} eq '') { - $to_be_deleted = 1; - } - if ($to_be_deleted) { - splice(@ruleorder, $rule_count, 1); - print_debug("delete_whole_rule_if_a_relevant_field_is_empty: deleting in rulebase $rulebase_name rule no $rule_count, id=" . - $rulebases{"$rulebase_name.$ruleorder[$rule_count].UID"}, $debug_level, 3); -# $rule_count--; - $rulebases{"$rulebase_name.rulecount"} = $rulebases{"$rulebase_name.rulecount"} - 1; - $rulebases{"$rulebase_name.ruleorder"} = join (',', @ruleorder); - } - return $to_be_deleted; -} - -sub fix_bidir_rules { - - sub switch_rule_src_dst { - my $dstkey = shift; - my $src_tmp; - - $src_tmp = $rulebases{"$dstkey.src"}; - $rulebases{"$dstkey.src"} = $rulebases{"$dstkey.dst"}; - $rulebases{"$dstkey.dst"} = $src_tmp; - $src_tmp = $rulebases{"$dstkey.src.refs"}; - $rulebases{"$dstkey.src.refs"} = $rulebases{"$dstkey.dst.refs"}; - $rulebases{"$dstkey.dst.refs"} = $src_tmp; - $src_tmp = $rulebases{"$dstkey.src.op"}; - $rulebases{"$dstkey.src.op"} = $rulebases{"$dstkey.dst.op"}; - $rulebases{"$dstkey.dst.op"} = $src_tmp; - if (defined($rulebases{"$dstkey.name"})) { - $rulebases{"$dstkey.name"} .= ".bothWays_reverse"; - } else { - $rulebases{"$dstkey.name"} = "bothWays_reverse"; - } - } - - my ($rule_count, $rulebase_name, $new_rule_number, $dstkey, $srckey, @ruleorder); - - foreach $rulebase_name (@rulebases) { - if (defined($rulebases{"$rulebase_name.ruleorder"})) { - @ruleorder = split(/\,/, $rulebases{"$rulebase_name.ruleorder"}); - $rule_count = 0; - if (defined($rulebases{"$rulebase_name.rulecount"})) { - while ($rule_count < $rulebases{"$rulebase_name.rulecount"}) { - if (defined($rulebases{"$rulebase_name.$ruleorder[$rule_count].bidir"})) { - print_debug ("debug: fix_bidir_rules found bidir rule: $rulebase_name.$ruleorder[$rule_count]", $debug_level, 3); - $new_rule_number = $ruleorder[$rule_count]."reverse"; - $rulebases{"$rulebase_name.rulecount"} ++; # Gesamtzahl der Regeln um eins erhoehen - $rule_count ++; - splice(@ruleorder, $rule_count, 0, $new_rule_number); # fuegt neue Regel in ruleorder-array ein - $srckey = "$rulebase_name." . $ruleorder[$rule_count-1]; - $dstkey = "$rulebase_name." . $new_rule_number; - print_debug ("debug: phion.pm rulebase=$rulebase_name, srckey=$srckey, dstkey=$dstkey, rule_count=$rule_count, new_rule_number=$new_rule_number", $debug_level, 1); - ©_rule($srckey, $dstkey); - &switch_rule_src_dst($dstkey); - # now setting UID to a unique value for the case that a sublist is called more then once - $rulebases{"$dstkey.UID"} = $rulebases{"$dstkey.UID"} . '.' . 'reverse_direction_of_bothWays_rule'; - } - $rule_count++; - } - } else { - print_debug ("warning: phion.pm found undefined rulecount for $rulebase_name", $debug_level, 3); - } - $rulebases{"$rulebase_name.ruleorder"} = join(',', @ruleorder); - } else { - print_debug ("warning: phion.pm empty ruleset for rulebase $rulebase_name", $debug_level, 3); - } - } -} - -#---------------------------------------- -# for each rulebase: -# search basic objects in rulebase that do not contain an OID -# check if this object was defined anywhere -# if yes, add name as OID -# if no: delete object from rule and issue warning about broken ref -sub fix_rule_references { - my ($rule_count, $rulebase_name); - - foreach $rulebase_name (@rulebases) { - if (defined($rulebases{"$rulebase_name.ruleorder"})) { - @ruleorder = split(/\,/, $rulebases{"$rulebase_name.ruleorder"}); - $rule_count = 0; - if (defined($rulebases{"$rulebase_name.rulecount"})) { - while ($rule_count < $rulebases{"$rulebase_name.rulecount"}) { - ($rulebases{"$rulebase_name.$ruleorder[$rule_count].src"},$rulebases{"$rulebase_name.$ruleorder[$rule_count].src.refs"}) = - split(/\n/, &fix_single_field_references ($rulebase_name, "src", $ruleorder[$rule_count])); - ($rulebases{"$rulebase_name.$ruleorder[$rule_count].dst"},$rulebases{"$rulebase_name.$ruleorder[$rule_count].dst.refs"}) = - split(/\n/, &fix_single_field_references ($rulebase_name, "dst", $ruleorder[$rule_count])); - ($rulebases{"$rulebase_name.$ruleorder[$rule_count].services"},$rulebases{"$rulebase_name.$ruleorder[$rule_count].services.refs"}) = - split(/\n/, &fix_single_field_references ($rulebase_name, "services", $ruleorder[$rule_count])); - if (!&delete_whole_rule_if_a_relevant_field_is_empty($rulebase_name, $rule_count)) { - $rule_count++; - } - } - } else { - print_debug ("warning: phion.pm found undefined rulecount for $rulebase_name", $debug_level, 3); - } - } else { - print_debug ("warning: phion.pm empty ruleset for rulebase $rulebase_name", $debug_level, 3); - } - } -} - -#---------------------------------------- -# Funktion add_basic_object_oids_in_rules_for_locally_defined_objects -# Parameter: none -#---------------------------------------- -# for each rulebase: -# search basic objects in rulebase that do not contain an OID -# check if this object was defined locally -# if yes, add name as OID -sub add_basic_object_oids_in_rules_for_locally_defined_objects { - my ($rule_count, $rulebase_name); - - sub fix_references { - my $rulebase_name = shift; - my $field = shift; - my $rule_count = shift; - my @names; - my @refs = (); - - if (defined ($rulebases{"$rulebase_name.$rule_count.$field"}) && $rulebases{"$rulebase_name.$rule_count.$field"} ne '') { - @names = split (/\|/, $rulebases{"$rulebase_name.$rule_count.$field"}); - my $idx=0; my $changed=0; - if (defined $rulebases{"$rulebase_name.$rule_count.$field.refs"}) { - @refs = split (/\|/, $rulebases{"$rulebase_name.$rule_count.$field.refs"}); # explicit use of | instead of $GROUPSEP - } else { - print_debug ("WARNING (1): $rulebase_name, ref undefined for rule $rule_count.$field.refs, name: " . $rulebases{"$rulebase_name.$rule_count.$field", $debug_level, 6}); - } - while ($idx ) { - $line = $_; # Zeileninhalt merken - $last_line = $line; # fuer end of line check - $line =~ s/\x0D/\\r/g; # literal carriage return entfernen - $line =~ s/\r\n/\n/g; # handle cr,nl - chomp ($line); - print_debug ("Zeile $ln, line: $line", $debug_level, 13); - $ln++; - -########## parse rule state 1: main level for dividing into obj,svc, ... ################################################ - # state 1 start of rule section rules={" - - if ( /^\tsublists\=\{$/ ) { - $sublist_flag = 1; - $indent = '\t\t'; # Variabler Einzug (leer bei rules=, enthaelt zwei Tabs in sublist=) - } - if ( $sublist_flag && /^\t\tRuleList\{$/ ) { $rulelist_flag = 1; $parserule_rulenum = 0; } - if ( $rulelist_flag && /^\t\t\tname\=\{(.+?)\}$/ ) { - $rulelist_name = $1; - $rulebases{"$scope.$parserule_rulenum.UID"} = "$scope" . "__sublist__$rulelist_name"; - $scope_bu = $scope; - $scope .= "__sublist__$rulelist_name"; - } - - if ( $rulelist_flag && /^${indent}\}$/ ) { # Ende einer Rulelist - $rulelist_flag = 0; - $parse_obj_state = 0; - $parse_obj_type = 'rules'; - &store_results(); - $scope = $scope_bu; - $rulelist_name = ''; - } - - if ( /^${indent}\trules\=\{$/ ) { # Beginn der Regel-Section (sowohl main als auch sublist) - $parse_obj_state = 1; - $parse_obj_type = 'rules'; - } - if ( defined($parse_obj_state) && $parse_obj_state>=1 && /^${indent}\t\}$/ ) { # end of 'rules=' or end of 'sublists=' resetting sublist flags and values - $parse_obj_state = 0; - &store_results(); - undef ($parse_obj_type); - } - if ( defined($parse_obj_state) && $parse_obj_state>=1) { # alle anderen Bereiche ausser "rules" ueberspringen -########## parse rule state 2: main level for (new) rule ################################################ - if ((/^${indent}\t\tRule\{$/) && ( ($parse_obj_state == 2) || ($parse_obj_state == 1))) { - $parse_obj_state = 2; - } - if (/^${indent}\t\t\}$/) { # Ende der Element-Definition - $parse_obj_state = 1; - &store_results(); - } -########## parse rule state 3: get element base data (name, comment, ...) ################################################ - if ((/^${indent}\t{3}(\w+)\=\{(.*?)$/) && ( ($parse_obj_state == 3) || ($parse_obj_state == 2))) { - $parse_obj_state = 3; - $parse_obj_attr = $1; - $explicit_flag = 0; - if ($2 ne '') { # einzeilige Definition - # value zwischenspeichern und untersuchen - my $local_line = $2; - # Ist der Wert in einer Zeile mit dem Parameter angegeben und nicht leer? - if ($local_line =~(/^(.+)\}$/)) { - $parse_obj_attr_value = $1; - if ($parse_obj_attr eq 'name') { $parse_obj_name = $parse_obj_attr_value; } - if ($parse_obj_attr eq 'oid') { $parse_obj_id = $parse_obj_name . '__uid__' . $parse_obj_attr_value; } - if ( - ($parse_obj_attr eq 'comment') - || ($parse_obj_attr eq 'oid') - || ($parse_obj_attr eq 'deactivated') - || ($parse_obj_attr eq 'timeAllow') - || ($parse_obj_attr eq 'name') - || ($parse_obj_attr eq 'noLog') - ) { - &store_results(); - } - # Keine Gruppe/Liste geoeffnt, daher parse_obj_state auf Level 3 belassen - undef ($parse_obj_attr); - } - } else { - $parse_rule_field_details = $parse_obj_attr; - if ($parse_rule_field_details eq 'src' || $parse_rule_field_details eq 'srcExplicit') { - $parse_rule_field = 'src'; - } - elsif ($parse_rule_field_details eq 'dst' || $parse_rule_field_details eq 'dstExplicit') { - $parse_rule_field = 'dst'; - } - elsif ($parse_rule_field_details eq 'srv' || $parse_rule_field_details eq 'srvExplicit') { - $parse_rule_field = 'services'; - } - elsif ($parse_rule_field_details eq 'action') { - $parse_rule_field = 'action'; - } - else { - undef ($parse_rule_field); - } - if ($parse_rule_field_details =~ /^...Explicit$/) { - $explicit_flag = 1; - } - $parse_obj_state = 4; # jetzt koennen beliebige Listen kommen (Laenge >=1) - } - } - if ((/^${indent}\t{3}\}$/)) { # Ende des state 3 - undef ($parse_rule_field); # jetzt ist ein Gruppe, sofern angefangen, zu Ende - undef($parse_obj_attr); - } -########## parse rule state 4: Zwischenebene mit wenig Configdaten ################################################ - if ( (/^${indent}\t{4}(\w+)\{$/) ) { - $parse_obj_state = 4; - if (!defined($parse_rule_field)) { # wenn in State 4 kein Feld gesetzt wurde: ignorieren - if ($1 ne 'FilterGroupRef' && $1 ne 'DevGroupRef' && $1 ne 'PARPRef') { - print_debug ("warning parsing rule state 4 - ignoring $1", $debug_level, 6); - } - } else { - $parse_obj_attr_ext = $1; - if (!( - ( - ($parse_rule_field eq 'src' || $parse_rule_field eq 'dst') && - ($parse_obj_attr_ext eq 'NetEntry' || $parse_obj_attr_ext eq 'NetRef' || - $parse_obj_attr_ext eq 'NetSet' || $parse_obj_attr_ext eq 'NetESet') - ) || - ( - ($parse_rule_field eq 'services') && - ($parse_obj_attr_ext eq 'ServiceRef' || $parse_obj_attr_ext eq 'ServiceSet') - ) || - ( - ($parse_rule_field eq 'action') && ($parse_obj_attr_ext =~ /^Action/ ) - ) - )) { - print_debug ("rule state 4 error: found unknown or misplaced element $parse_obj_attr_ext in rule section $parse_rule_field, " . - "line: $ln, field: $parse_rule_field, attr_ext: $parse_obj_attr_ext", $debug_level, 1); - } else { # extracting rule details - $parse_rule_field_details = $1; - $parse_obj_state = 5; - if ($parse_rule_field eq 'action') { # action sofort auswerten - $parse_obj_attr = 'action'; - $parse_obj_attr_value = $parse_obj_attr_ext; - &store_results(); - } # alles andere in state 5 eins tiefer - } - } - } - # Ende des state 4 - if ( (/^${indent}\t{4}\}$/) ) { - $parse_obj_state = 3; - undef ($parse_rule_field); - undef ($parse_obj_attr_ext); undef ($parse_obj_attr_ext_value); - } - ########## parse rule state 5: get element details ################################################ -# if ( /^${indent}\t{5}(\w+)\=\{(.*?)\}?$/ && $parse_obj_state==5 ) { - if ( /^${indent}\t{5}(\w+)\=\{(.*?)\}?$/ ) { - if ($2 ne '') { # einzeilige Definition - direkt auslesen - $parse_obj_attr = $1; - $parse_obj_attr_value = $2; - if ($parse_obj_attr eq 'bothWays' && $parse_obj_attr_value eq '1') { # bidirectional rule -# print_debug ("notice parsing rule state 5 - found bidir rule in line # $ln: $line", $debug_level, 2); - &store_results(); - } - if ($parse_obj_attr eq 'name' || $parse_obj_attr eq 'comment' || - $parse_obj_attr eq 'subsetName' || - $parse_obj_attr eq 'ref' || $parse_obj_attr eq 'refid' ) { - &store_results(); - } - } else { - $parse_obj_attr = $1; - if ($parse_obj_attr eq 'list' || $parse_obj_attr eq 'neglist') { - $parse_obj_state = 6; - } - } - } - # Ende des state 5 - if ((/^${indent}\t{5}\}$/)) { - $parse_obj_state = 4; - undef ($parse_rule_field); - } -########## parse rule state 6: Zwischenebene mit wenig Configdaten ################################################ - if ( /^${indent}\t{6}(\w+)\{$/ && ($parse_obj_state == 5 || $parse_obj_state == 6) ) { - $create_explicit_element_flag = 0; - $parse_obj_attr_ext = $1; - if (!defined($parse_rule_field)) { $parse_rule_field = ''; } - if (!defined($parse_obj_attr_ext)) { $parse_obj_attr_ext = ''; } - if (!( - ( - ($parse_rule_field eq 'src' || $parse_rule_field eq 'dst') && - ($parse_obj_attr_ext eq 'NetEntry' || $parse_obj_attr_ext eq 'NetRef' || - $parse_obj_attr_ext eq 'NetSet') - ) || - ( - ($parse_rule_field eq 'services') && -# ($parse_obj_attr_ext eq 'ServiceRef' || $parse_obj_attr_ext eq 'ServiceSet') - ($parse_obj_attr_ext eq 'ServiceRef' || $parse_obj_attr_ext eq 'ServiceEntryTCP' || - $parse_obj_attr_ext eq 'ServiceEntryUDP' || $parse_obj_attr_ext eq 'ServiceEntryEcho' || - $parse_obj_attr_ext eq 'ServiceEntryOther' - ) - ) - )) { - if ( $parse_obj_attr_ext eq 'ConnRef' || $parse_obj_attr_ext eq 'ConnStd') { - } else { - print_debug ("state 6 error: found unknown or misplaced element $parse_obj_attr_ext in rule section $parse_rule_field" . - "line: $ln, field: $parse_rule_field, attr_ext: $parse_obj_attr_ext", $debug_level, 1); - } - } else { # extracting rule details - if ($explicit_flag && $parse_obj_attr_ext !~ /Ref$/) { # jetzt muss ein Basiselement angelegt werden - $create_explicit_element_flag = 1; - if ($parse_obj_attr_ext =~ /^ServiceEntry(.*?)$/ ) { - # das IP-Protokoll extrahieren - $create_explicit_element_proto = lc($1); - } - } - $parse_obj_state = 7; - } - } - # Ende des state 6 - if ( (/^${indent}\t{6}\}$/) ) { - $parse_obj_state = 5; -# undef ($parse_rule_field); - $create_explicit_element_flag = 0; - undef ($parse_obj_attr_ext); undef ($parse_obj_attr_ext_value); - } - ########## parse rule state 7: get element list details ################################################ - if ( /^${indent}\t{7}(\w+)\=\{\s?(.*?)\}$/ && $parse_obj_state==7 ) { - if ($2 ne '') { # einzeilige Definition - direkt auslesen - $parse_obj_attr = $1; - $parse_obj_attr_value = $2; - if ($create_explicit_element_flag) { - if ((($parse_obj_attr eq 'addr' || $parse_obj_attr eq 'addr6') && $parse_obj_attr_value ne '0.0.0.0') || $parse_obj_attr eq 'portLimit') { - # adding new base element to structure - $scope =~ /^(\d+)_(.+?)_(.+?)_(.+?)_(.+?)_(.+?)/; - my $clusterserver; if (defined($4)) { $clusterserver = "-$4"; } else { $clusterserver = ""; } - $parse_obj_name = $parse_obj_attr_value; - if (defined($create_explicit_element_proto)) { # only use this for svc nor for ip - $parse_obj_name = $create_explicit_element_proto . '_' . $parse_obj_name; - } - $parse_obj_name =~ s/\//_/ ; # replace '/' with '_' in name - $parse_obj_id = $parse_obj_name . '__uid__' . $parse_obj_name. $clusterserver; - if ($parse_obj_attr eq 'addr' || $parse_obj_attr eq 'addr6') { - $parse_obj_type = "netobj"; - &store_results(); # Element abspeichern - # hier werden vereinfachend alle anderen Parameter (comment, etc) ignoriert - } elsif ($parse_obj_attr eq 'portLimit' - # || $parse_obj_attr eq 'botClientPort' || $parse_obj_attr eq 'topClientPort') - ) { - $parse_obj_type = "srvobj"; - &store_results(); # Element abspeichern - if (defined($create_explicit_element_proto)) { - $parse_obj_attr = 'type'; - $parse_obj_attr_value = $create_explicit_element_proto; - &store_results(); # Protokoll hinterher - undef($create_explicit_element_proto); - } - # hier werden vereinfachend alle anderen Parameter (Client_Port, Timeout) ignoriert - } - $parse_obj_type = "rules"; # und zurueck zum Regelparser - - # now storing the reference to the new element in the rule - $parse_obj_attr = 'ref'; $parse_obj_attr_value = $parse_obj_name; - &store_results(); - $parse_obj_attr = 'refid'; $parse_obj_attr_value = $parse_obj_id; - &store_results(); - } - } elsif ($parse_obj_attr eq 'ref' || $parse_obj_attr eq 'refid' ) { - &store_results(); - } - } - } -########################################################################################################## - } - } # end of while - close (IN); - print_debug ("$in_file closed.",$debug_level, 8); - - # check auf Vollstaendigkeit des Config-Files: - if ($last_line =~ m/^\}(\n)?$/) { return 0; } - else { return "ERROR: last line of config-file $in_file not correct: <$last_line>"; } -} - -1; -__END__ - -=head1 NAME - -CACTUS::FWORCH::parser - Perl extension for fworch phion parser - -=head1 SYNOPSIS - - use CACTUS::FWORCH::import::phion; - -=head1 DESCRIPTION - -fworch Perl Module support for importing configs into fworch Database - -=head2 EXPORT - - ©_config_from_mgm_to_iso - transfer phion MC rangetree fw rules to fworch - &parse_config - parse phion MC config rangetree - -=head1 SEE ALSO - - behind the door - -=head1 AUTHOR - - Cactus eSecurity, tmp@cactus.de - -=cut diff --git a/roles/importer/files/importer/CACTUS/read_config.pm b/roles/importer/files/importer/CACTUS/read_config.pm deleted file mode 100644 index 36d67b5f99..0000000000 --- a/roles/importer/files/importer/CACTUS/read_config.pm +++ /dev/null @@ -1,86 +0,0 @@ -package CACTUS::read_config; - -use strict; -use warnings; -use IO::File; -require Exporter; -our @ISA = qw(Exporter); - -our %EXPORT_TAGS = ( - 'basic' => [ - qw( &read_config ) - ] -); - -our @EXPORT = ( @{ $EXPORT_TAGS{'basic'} } ); -our $VERSION = '1.2'; - -############################################################ -# read one file into string -############################################################ -sub read_file_into_string { - my $conf_file = shift; - my ($line, $lines); - - my $INFILE = new IO::File ("< $conf_file") or die "cannot open file $conf_file\n"; - $lines = ''; - - while ($line = <$INFILE>) { $lines .= $line; } - $INFILE->close; - return $lines; -} -############################################################ -# read parameter from config file -############################################################ -sub read_config { - my $param = shift; - my $confdir = '/usr/local/fworch/etc'; - my $result; - - my $global_conf_lines = &read_file_into_string ("$confdir/iso.conf"); - my $import_conf_lines = &read_file_into_string ("$confdir/import.conf"); - my $all_conf_lines = $global_conf_lines . '\n' . $import_conf_lines; - - my @config_lines = split (/\n/, $all_conf_lines); - - foreach my $line (@config_lines) { - if ($line =~ /(.*?)\#/) { $line = $1; } # remove comments - if ($line !~ /^$/ && $line =~ /^\s*$param\s+(.*?)\s*$/) { - $result = $1; -# print ("found matching config line for $param. Param: .$1.\n"); - } - } - if (!defined($result)) { print ("warning: config parameter $param neither found in global nor in import config file\n"); } - return $result; -} - -1; -__END__ - -=head1 NAME - -read_config - Perl extension for fworch - -=head1 SYNOPSIS - - use CACTUS::read_config; - -=head1 DESCRIPTION - -fworch Perl Module support for reading config files - -=head2 EXPORT - - Basic functions - read_config(parameter to read from file) - -=head1 SEE ALSO - - behind the door - - -=head1 AUTHOR - - Cactus eSecurity, tmp@cactus.de - -=cut diff --git a/roles/importer/files/importer/azure2022ff/azure_base.py b/roles/importer/files/importer/azure2022ff/azure_base.py deleted file mode 100644 index 113e58e1d7..0000000000 --- a/roles/importer/files/importer/azure2022ff/azure_base.py +++ /dev/null @@ -1 +0,0 @@ -azure_api_version_str = '?api-version=2022-07-01' diff --git a/roles/importer/files/importer/azure2022ff/azure_getter.py b/roles/importer/files/importer/azure2022ff/azure_getter.py deleted file mode 100644 index b7202cb756..0000000000 --- a/roles/importer/files/importer/azure2022ff/azure_getter.py +++ /dev/null @@ -1,105 +0,0 @@ -# library for API get functions -import base64 -from typing import Dict -from fwo_log import getFwoLogger -import requests.packages -import requests -import json -import fwo_globals -from fwo_exception import FwLoginFailed - - -def api_call(url, params = {}, headers = {}, data = {}, azure_jwt = '', show_progress=False, method='get'): - logger = getFwoLogger() - request_headers = {} - if not 'Content-Type' in headers: - request_headers = {'Content-Type': 'application/json'} - for header_key in headers: - request_headers[header_key] = headers[header_key] - if azure_jwt != '': - request_headers["Authorization"] = 'Bearer {azure_jwt}'.format(azure_jwt=azure_jwt) - if request_headers['Content-Type'] == 'application/json': - data=json.dumps(data) - else: # login only - data=data - - if method == "post": - response = requests.post(url, params=params, data=data, headers=request_headers, verify=fwo_globals.verify_certs) - elif method == "get": - response = requests.get(url, params=params, headers=request_headers, verify=fwo_globals.verify_certs) - else: - raise Exception("unknown HTTP method found in azure_getter") - - # error handling: - exception_text = '' - if response is None: - if 'password' in json.dumps(data): - exception_text = "error while sending api_call containing credential information to url '" + \ - str(url) - else: - exception_text = "error while sending api_call to url '" + str(url) + "' with payload '" + json.dumps( - data, indent=2) + "' and headers: '" + json.dumps(request_headers, indent=2) - if not response.ok: - exception_text = 'error code: {error_code}, error={error}'.format(error_code=response.status_code, error=response.content) - #logger.error(response.content) - if (len(response.content) == 0): - exception_text = 'empty response content' - - if exception_text != '': - raise Exception(exception_text) - - # no errors found - body_json = response.json() - - if fwo_globals.debug_level > 5: - if 'pass' in json.dumps(data): - logger.debug("api_call containing credential information to url '" + - str(url) + " - not logging query") - else: - logger.debug("api_call to url '" + str(url) + "' with payload '" + json.dumps( - data, indent=2) + "' and headers: '" + json.dumps(request_headers, indent=2)) - - return response.headers, body_json - - -def login(azure_user, azure_password, tenant_id, client_id, client_secret): - base_url = 'https://login.microsoftonline.com/{tenant_id}/oauth2/token'.format(tenant_id=tenant_id) - try: - headers, body = api_call(base_url, method="post", - headers={'Content-Type': 'application/x-www-form-urlencoded'}, - data={ - "grant_type" : "client_credentials", - "client_id": client_id, - "client_secret": client_secret, - "resource": "https://management.azure.com/", - "username": str(base64.b64encode((azure_user).encode('utf-8')), 'utf-8'), - "password": str(base64.b64encode((azure_password).encode('utf-8')), 'utf-8') - }) - except Exception as e: - raise FwLoginFailed("Azure login ERROR for client_id id=" + str(client_id) + " Message: " + str(e)) from None - - if body.get("access_token") == None: # leaving out payload as it contains pwd - raise FwLoginFailed("Azure login ERROR for client_id=" + str(client_id) + " Message: " + str(e)) from None - - if fwo_globals.debug_level > 2: - logger = getFwoLogger() - logger.debug("Login successful. Received JWT: " + body["access_token"]) - - return body["access_token"] - - -def update_config_with_azure_api_call(azure_jwt, api_base_url, config, api_path, key, parameters={}, payload={}, show_progress=False, limit: int=1000, method="get"): - offset = 0 - limit = 1000 - returned_new_data = True - - full_result = [] - #while returned_new_data: - # parameters["offset"] = offset - # parameters["limit"] = limit - result = api_call(api_base_url + api_path, azure_jwt=azure_jwt, params=parameters, data=payload, show_progress=show_progress, method=method)[1] - returned_new_data = len(result['value'])>0 - if returned_new_data: - full_result.extend(result["value"]) -# offset += limit - config.update({key: full_result}) diff --git a/roles/importer/files/importer/azure2022ff/azure_network.py b/roles/importer/files/importer/azure2022ff/azure_network.py deleted file mode 100644 index 7180b453d9..0000000000 --- a/roles/importer/files/importer/azure2022ff/azure_network.py +++ /dev/null @@ -1,121 +0,0 @@ -from asyncio.log import logger -from fwo_log import getFwoLogger -from fwo_const import list_delimiter -import ipaddress - - -def normalize_nwobjects(full_config, config2import, import_id, jwt=None, mgm_id=None): - nw_objects = [] - for obj_orig in full_config["networkObjects"]: - nw_objects.append(parse_object(obj_orig, import_id, config2import, nw_objects)) - for obj_grp_orig in full_config["networkObjectGroups"]: - obj_grp = extract_base_object_infos(obj_grp_orig, import_id, config2import, nw_objects) - obj_grp["obj_typ"] = "group" - obj_grp["obj_member_refs"], obj_grp["obj_member_names"] = parse_obj_group(obj_grp_orig, import_id, nw_objects, config2import) - nw_objects.append(obj_grp) - config2import['network_objects'] = nw_objects - - -def extract_base_object_infos(obj_orig, import_id, config2import, nw_objects): - obj = {} - - if "type" in obj_orig: - obj["obj_name"] = obj_orig["name"] - obj["obj_uid"] = obj_orig["id"] - if 'description' in obj_orig: - obj["obj_comment"] = obj_orig["description"] - if 'etag' in obj_orig and not 'obj_comment' in obj: - obj["obj_comment"] = obj_orig["etag"] - obj['control_id'] = import_id - return obj - - -def parse_obj_group(orig_grp, import_id, nw_objects, config2import, id = None): - refs = [] - names = [] - if "properties" in orig_grp: - if 'ipAddresses' in orig_grp['properties']: - for ip in orig_grp['properties']['ipAddresses']: - new_obj = parse_object(add_network_object(config2import, ip=ip), import_id, config2import, nw_objects) - names.append(new_obj['obj_name']) - refs.append(new_obj['obj_uid']) - nw_objects.append(new_obj) - return list_delimiter.join(refs), list_delimiter.join(names) - - -def parse_obj_list(ip_list, import_id, config, id): - refs = [] - names = [] - for ip in ip_list: - # TODO: lookup ip in network_objects and re-use - ip_obj = {} - ip_obj['obj_name'] = ip - ip_obj['obj_uid'] = ip_obj['obj_name'] + "_" + id - try: - ipaddress.ip_network(ip) - # valid ip - ip_obj['obj_ip'] = ip - except: - # no valid ip - asuming azureTag - ip_obj['obj_ip'] = '0.0.0.0/0' - ip = '0.0.0.0/0' - ip_obj['obj_name'] = "#"+ip_obj['obj_name'] - ip_obj['obj_type'] = 'simple' - ip_obj['obj_typ'] = 'host' - if "/" in ip: - ip_obj['obj_typ'] = 'network' - - if "-" in ip: # ip range - ip_obj['obj_typ'] = 'ip_range' - ip_range = ip.split("-") - ip_obj['obj_ip'] = ip_range[0] - ip_obj['obj_ip_end'] = ip_range[1] - - ip_obj['control_id'] = import_id - - config.append(ip_obj) - refs.append(ip_obj['obj_uid']) - names.append(ip_obj['obj_name']) - return list_delimiter.join(refs), list_delimiter.join(names) - - -def parse_object(obj_orig, import_id, config2import, nw_objects): - obj = extract_base_object_infos(obj_orig, import_id, config2import, nw_objects) - if obj_orig["type"] == "network": # network - obj["obj_typ"] = "network" - cidr = obj_orig["value"].split("/") - if str.isdigit(cidr[1]): - obj['obj_ip'] = cidr[0] + "/" + cidr[1] - else: # not real cidr (netmask after /) - obj['obj_ip'] = cidr[0] + "/" + str(IPAddress(cidr[1]).netmask_bits()) - elif obj_orig["type"] == "host": # host - obj["obj_typ"] = "host" - obj["obj_ip"] = obj_orig["ip"] - if obj_orig["ip"].find(":") != -1: # ipv6 - obj["obj_ip"] += "/128" - else: # ipv4 - obj["obj_ip"] += "/32" - elif obj_orig["type"] == "ip_range": # ip range - obj['obj_typ'] = 'ip_range' - ip_range = obj_orig['ip'].split("-") - obj['obj_ip'] = ip_range[0] - obj['obj_ip_end'] = ip_range[1] - elif obj_orig["type"] == "FQDN": # fully qualified domain name - obj['obj_typ'] = 'network' - obj['obj_ip'] = "0.0.0.0/0" - obj['obj_uid'] = obj_orig["id"] - else: # unknown type - obj["obj_name"] = obj["obj_name"] + " [not supported]" - obj['obj_typ'] = 'network' - obj['obj_ip'] = "0.0.0.0/0" - obj['control_id'] = import_id - - return obj - - -def add_network_object(config2import, ip=None): - if "-" in str(ip): - type = 'ip_range' - else: - type = 'host' - return {'ip': ip, 'name': ip, 'id': ip, 'type': type} diff --git a/roles/importer/files/importer/azure2022ff/azure_rule.py b/roles/importer/files/importer/azure2022ff/azure_rule.py deleted file mode 100644 index 8ac6ab9266..0000000000 --- a/roles/importer/files/importer/azure2022ff/azure_rule.py +++ /dev/null @@ -1,100 +0,0 @@ -from azure_service import parse_svc_list -from azure_network import parse_obj_list -from fwo_log import getFwoLogger -import hashlib -import base64 - - -def make_hash_sha256(o): - hasher = hashlib.sha256() - hasher.update(repr(make_hashable(o)).encode()) - return base64.b64encode(hasher.digest()).decode() - - -def make_hashable(o): - if isinstance(o, (tuple, list)): - return tuple((make_hashable(e) for e in o)) - - if isinstance(o, dict): - return tuple(sorted((k,make_hashable(v)) for k,v in o.items())) - - if isinstance(o, (set, frozenset)): - return tuple(sorted(make_hashable(e) for e in o)) - - return o - -# rule_access_scope_v4 = ['rules_global_header_v4', -# 'rules_adom_v4', 'rules_global_footer_v4'] -# rule_access_scope_v6 = ['rules_global_header_v6', -# 'rules_adom_v6', 'rules_global_footer_v6'] -# rule_access_scope = rule_access_scope_v6 + rule_access_scope_v4 -# rule_nat_scope = ['rules_global_nat', 'rules_adom_nat'] -# rule_scope = rule_access_scope + rule_nat_scope - - -def normalize_access_rules(full_config, config2import, import_id, mgm_details={}): - rules = [] - - nw_obj_names = [] - for o in config2import['network_objects']: - nw_obj_names.append(o["obj_name"]) - - for device in full_config["devices"]: - rule_number = 0 - for policy_name in full_config['devices'].keys(): - for rule_prop in full_config['devices'][policy_name]['rules']: - rule_coll_container = rule_prop['properties'] - if 'ruleCollections' in rule_coll_container: - for rule_coll in rule_coll_container['ruleCollections']: - if 'ruleCollectionType' in rule_coll and rule_coll['ruleCollectionType'] == 'FirewallPolicyFilterRuleCollection': - rule_action = "accept" - if rule_coll['action']['type'] == 'Deny': - rule_action = "deny" - - for rule_orig in rule_coll['rules']: - rule = {'rule_src': 'any', 'rule_dst': 'any', 'rule_svc': 'any', - 'rule_src_refs': 'any_obj_placeholder', 'rule_dst_refs': 'any_obj_placeholder', - 'rule_svc_refs': 'any_svc_placeholder'} - rule['rulebase_name'] = policy_name - rule["rule_name"] = rule_orig["name"] - rule['rule_type'] = "access" - rule['rule_num'] = rule_number - rule['rule_installon'] = None - rule['parent_rule_id'] = None - rule['rule_time'] = None - rule['rule_implied'] = False - rule["rule_comment"] = None - rule["rule_action"] = rule_action - rule["rule_track"] = "None" - rule["rule_disabled"] = False - rule["rule_uid"] = make_hash_sha256(rule) # generate uid from invariable rule parts without import_id - rule['control_id'] = import_id - - if "sourceAddresses" in rule_orig: - rule['rule_src_refs'], rule["rule_src"] = parse_obj_list(rule_orig["sourceAddresses"], import_id, config2import['network_objects'], rule["rule_uid"]) - if "destinationAddresses" in rule_orig: - undefObjects = [] - - for obj in rule_orig['destinationAddresses']: - if "obj_name" in obj: - if obj["obj_name"] not in nw_obj_names: - undefObjects.append(obj["obj_name"]) - elif obj not in nw_obj_names: # just a string with obj name - undefObjects.append(obj) - # rule['rule_src_refs'], rule["rule_src"] = parse_obj_list(undefObjects, import_id, config2import['network_objects'], rule["rule_uid"]) - rule['rule_dst_refs'], rule["rule_dst"] = parse_obj_list(rule_orig["destinationAddresses"], import_id, config2import['network_objects'], rule["rule_uid"]) - if "destinationPorts" in rule_orig: - rule['rule_svc_refs'], rule['rule_svc'] = parse_svc_list(rule_orig["destinationPorts"], rule_orig["ipProtocols"], import_id, config2import['service_objects'], rule["rule_uid"]) - # TODO: - # ipProtocols!! - # sourceIpGroups - # destinationIpGroups - # destinationFqdns - rule["rule_src_neg"] = False - rule["rule_dst_neg"] = False - rule["rule_svc_neg"] = False - - rule_number += 1 - rules.append(rule) - - config2import['rules'] = rules diff --git a/roles/importer/files/importer/azure2022ff/azure_service.py b/roles/importer/files/importer/azure2022ff/azure_service.py deleted file mode 100644 index d537e314a5..0000000000 --- a/roles/importer/files/importer/azure2022ff/azure_service.py +++ /dev/null @@ -1,106 +0,0 @@ -import random -from fwo_const import list_delimiter - - -def normalize_svcobjects(full_config, config2import, import_id): - svc_objects = [] - for svc_orig in full_config["serviceObjects"]: - svc_objects.append(parse_svc(svc_orig, import_id)) - for svc_grp_orig in full_config["serviceObjectGroups"]: - svc_grp = extract_base_svc_infos(svc_grp_orig, import_id) - svc_grp["svc_typ"] = "group" - svc_grp["svc_member_refs"] , svc_grp["svc_member_names"] = parse_svc_group(svc_grp_orig, import_id, svc_objects) - svc_objects.append(svc_grp) - config2import['service_objects'] = svc_objects - - -def extract_base_svc_infos(svc_orig, import_id): - svc = {} - if "id" in svc_orig: - svc["svc_uid"] = svc_orig["id"] - else: - svc["svc_uid"] = svc_orig["protocol"] - if "port" in svc_orig: - svc["svc_uid"] += "_" + svc_orig["port"] - if "name" in svc_orig: - svc["svc_name"] = svc_orig["name"] - else: - svc["svc_name"] = svc_orig["protocol"] - if "port" in svc_orig: - svc["svc_name"] += "_" + svc_orig["port"] - if "svc_comment" in svc_orig: - svc["svc_comment"] = svc_orig["comment"] - svc["svc_timeout"] = None - svc["svc_color"] = None - svc["control_id"] = import_id - return svc - - -def parse_svc(orig_svc, import_id): - svc = extract_base_svc_infos(orig_svc, import_id) - svc["svc_typ"] = "simple" - parse_port(orig_svc, svc) - if orig_svc["type"] == "ProtocolPortObject": - if orig_svc["protocol"] == "TCP": - svc["ip_proto"] = 6 - elif orig_svc["protocol"] == "UDP": - svc["ip_proto"] = 17 - elif orig_svc["protocol"] == "ESP": - svc["ip_proto"] = 50 - else: - svc["svc_name"] += " [Protocol \"" + orig_svc["protocol"] + "\" not supported]" - # TODO Icmp - # TODO add all protocols - elif orig_svc["type"] == "PortLiteral": - svc["ip_proto"] = orig_svc["protocol"] - else: - svc["svc_name"] += " [Not supported]" - return svc - - -def parse_port(orig_svc, svc): - if "port" in orig_svc: - if orig_svc["port"].find("-") != -1: # port range - port_range = orig_svc["port"].split("-") - svc["svc_port"] = port_range[0] - svc["svc_port_end"] = port_range[1] - else: # single port - svc["svc_port"] = orig_svc["port"] - svc["svc_port_end"] = None - - -def parse_svc_list(ports, ip_protos, import_id, svc_objects, id = None): - refs = [] - names = [] - for port in ports: - for ip_proto in ip_protos: - # TODO: lookup port in svc_objects and re-use - svc = {} - - - - if id == None: - id = str(random.random()) - - svc['svc_name'] = ip_proto + "_" + port - - svc['svc_uid'] = svc['svc_name'] + "_" + id - svc['svc_port'] = port - svc['svc_port_end'] = port - svc['svc_typ'] = 'simple' - if ip_proto == "TCP": - svc["ip_proto"] = 6 - elif ip_proto == "UDP": - svc["ip_proto"] = 17 - elif ip_proto == "ESP": - svc["ip_proto"] = 50 - elif ip_proto == "ICMP": - svc["ip_proto"] = 1 - else: - svc["svc_name"] += " [Protocol \"" + ip_proto + "\" not supported]" - svc['control_id'] = import_id - - svc_objects.append(svc) - refs.append(svc['svc_uid']) - names.append(svc['svc_name']) - return list_delimiter.join(refs), list_delimiter.join(names) diff --git a/roles/importer/files/importer/azure2022ff/fwcommon.py b/roles/importer/files/importer/azure2022ff/fwcommon.py deleted file mode 100644 index 0e77c454a8..0000000000 --- a/roles/importer/files/importer/azure2022ff/fwcommon.py +++ /dev/null @@ -1,134 +0,0 @@ -import sys -from common import importer_base_dir -sys.path.append(importer_base_dir + '/azure2022ff') -from azure_service import normalize_svcobjects -from azure_rule import normalize_access_rules -from azure_network import normalize_nwobjects -from azure_getter import login, update_config_with_azure_api_call -from fwo_log import getFwoLogger -from azure_base import azure_api_version_str - -def has_config_changed(full_config, mgm_details, force=False): - # dummy - may be filled with real check later on - return True - - -def get_config(config2import, full_config, current_import_id, mgm_details, limit=1000, force=False, jwt=''): - logger = getFwoLogger() - if full_config == {}: # no native config was passed in, so getting it from Azzure - parsing_config_only = False - else: - parsing_config_only = True - - if not parsing_config_only: # no native config was passed in, so getting it from Azure - azure_client_id = mgm_details["import_credential"]['cloudClientId'] - azure_client_secret = mgm_details["import_credential"]['cloudClientSecret'] - azure_password = mgm_details["import_credential"]['secret'] - azure_user = mgm_details["import_credential"]['user'] - azure_tenant_id = mgm_details['cloudTenantId'] - azure_subscription_id = mgm_details['cloudSubscriptionId'] - azure_resource_group = mgm_details['configPath'] - azure_api_worker_base_url = 'https://management.azure.com/subscriptions/{subscription_id}/'.format(subscription_id=azure_subscription_id) - - full_config["networkObjects"] = [] - full_config["networkObjectGroups"] = [] - - full_config["serviceObjects"] = [] - full_config["serviceObjectGroups"] = [] - - full_config["userObjects"] = [] - full_config["userObjectGroups"] = [] - - # login - azure_jwt = login(azure_user, azure_password, azure_tenant_id, azure_client_id, azure_client_secret) - if azure_jwt == None or azure_jwt == "": - logger.error('Did not succeed in logging in to Azure API, no jwt returned.') - return 1 - - # get objects: - # network objects - # network groups - api_path = 'resourceGroups/{resourceGroupName}/providers/Microsoft.Network/ipGroups{azure_api_version_str}'.format( - resourceGroupName=azure_resource_group, azure_api_version_str=azure_api_version_str) - update_config_with_azure_api_call(azure_jwt, azure_api_worker_base_url, full_config, - api_path, "networkObjectGroups") - - # network services - # network serivce groups - - # users - - # get rules - full_config.update({'devices': {}}) - for device in mgm_details["devices"]: - azure_policy_name = device['name'] - full_config['devices'].update({ device['name']: {} }) - - api_path = 'resourceGroups/{resourceGroupName}/providers/Microsoft.Network/firewallPolicies/{firewallPolicyName}/ruleCollectionGroups{azure_api_version_str}'.format( - resourceGroupName=azure_resource_group, firewallPolicyName=azure_policy_name, azure_api_version_str=azure_api_version_str) - - update_config_with_azure_api_call(azure_jwt, azure_api_worker_base_url, full_config['devices'][device['name']], api_path, "rules") - ##azure_rule.getNatPolicy(sessionId, azure_api_worker_base_url, full_config, domain, device, limit) TODO - - # extract objects from rules - for device in mgm_details["devices"]: - azure_policy_name = device['name'] - for policy_name in full_config['devices'].keys(): - extract_nw_objects(policy_name, full_config) - extract_svc_objects(policy_name, full_config) - extract_user_objects(policy_name, full_config) - - # now we normalize relevant parts of the raw config and write the results to config2import dict - - # normalize_network_data(full_config, config2import, mgm_details) - - # azure_user.normalize_users( - # full_config, config2import, current_import_id, user_scope) - normalize_nwobjects(full_config, config2import, current_import_id, jwt=jwt, mgm_id=mgm_details['id']) - normalize_svcobjects(full_config, config2import, current_import_id) - - any_nw_svc = {"svc_uid": "any_svc_placeholder", "svc_name": "Any", "svc_comment": "Placeholder service.", - "svc_typ": "simple", "ip_proto": -1, "svc_port": 0, "svc_port_end": 65535, "control_id": current_import_id} - any_nw_object = {"obj_uid": "any_obj_placeholder", "obj_name": "Any", "obj_comment": "Placeholder object.", - "obj_typ": "network", "obj_ip": "0.0.0.0/0", "control_id": current_import_id} - config2import["service_objects"].append(any_nw_svc) - config2import["network_objects"].append(any_nw_object) - - normalize_access_rules(full_config, config2import, current_import_id, mgm_details=mgm_details) - # azure_rule.normalize_nat_rules( - # full_config, config2import, current_import_id, jwt=jwt) - # azure_network.remove_nat_ip_entries(config2import) - return 0 - - -def extract_nw_objects(rule, config): - pass - - -def extract_svc_objects(rule, config): - pass - - -def extract_user_objects(rule, config): - pass - - -# def getDevices(azure_jwt, api_url, config, limit, devices): -# https://management.azure.com/subscriptions/{{ _.subscriptionId }}/providers/Microsoft.Network/applicationGateways?api-version=2022-05-01 - -# but this does not return firewalls! - -# logger = getFwoLogger() -# # get all devices -# config["devices"] = update_config_with_azure_api_call(azure_jwt, api_url, "fmc_config/v1/domain/" + "/devices/devicerecords", parameters={"expanded": True}, limit=limit) -# # filter for existent devices -# for cisco_api_device in config["devices"]: -# found = False -# for device in devices: -# if device["name"] == cisco_api_device["name"] or device["name"] == cisco_api_device["id"]: -# found = True -# break -# # remove device if not in fwo api -# if found == False: -# config["devices"].remove(cisco_api_device) -# logger.info("Device \"" + cisco_api_device["name"] + "\" was found but it is not registered in FWO. Ignoring it.") diff --git a/roles/importer/files/importer/checkpointR8x/cp_const.py b/roles/importer/files/importer/checkpointR8x/cp_const.py deleted file mode 100644 index 7c38cccc6f..0000000000 --- a/roles/importer/files/importer/checkpointR8x/cp_const.py +++ /dev/null @@ -1,34 +0,0 @@ -details_level = "full" # 'standard' -use_object_dictionary = 'false' - -# the following is the static across all installations unique any obj uid -# cannot fetch the Any object via API (<=1.7) at the moment -# therefore we have a workaround adding the object manually (as svc and nw) -any_obj_uid = "97aeb369-9aea-11d5-bd16-0090272ccb30" -# todo: read this from config (from API 1.6 on it is fetched) - -original_obj_uid = "85c0f50f-6d8a-4528-88ab-5fb11d8fe16c" -# used for nat only (both svc and nw obj) - - -nw_obj_table_names = [ - 'hosts', 'networks', 'groups', 'address-ranges', 'multicast-address-ranges', 'groups-with-exclusion', - 'gateways-and-servers', 'simple-gateways', - 'dns-domains', 'updatable-objects-repository-content' -] - -# simple as in: no groups -simple_svc_obj_types = ['services-tcp', 'services-udp', 'services-dce-rpc', 'services-rpc', 'services-other', - 'services-icmp', 'services-icmp6', 'services-sctp', 'services-gtp'] -group_svc_obj_types = ['service-groups', 'application-site-categories', 'application-sites'] - -svc_obj_table_names = group_svc_obj_types + simple_svc_obj_types + [ 'CpmiAnyObject' ] -# usr_obj_table_names : do not exist yet - not fetchable via API - -api_obj_types = nw_obj_table_names + svc_obj_table_names # all obj table names to look at during import - -cp_specific_object_types = [ # used for fetching enrichment data via "get object" separately (no specific API call) - 'simple-gateway', 'simple-cluster', 'CpmiVsClusterNetobj', 'CpmiVsxClusterNetobj', 'CpmiVsxClusterMember', 'CpmiVsNetobj', - 'CpmiAnyObject', 'CpmiClusterMember', 'CpmiGatewayPlain', 'CpmiHostCkp', 'CpmiGatewayCluster', 'checkpoint-host', - 'cluster-member' -] diff --git a/roles/importer/files/importer/checkpointR8x/cp_enrich.py b/roles/importer/files/importer/checkpointR8x/cp_enrich.py deleted file mode 100644 index f54e21ba79..0000000000 --- a/roles/importer/files/importer/checkpointR8x/cp_enrich.py +++ /dev/null @@ -1,168 +0,0 @@ -import sys -from common import importer_base_dir -from fwo_log import getFwoLogger -sys.path.append(importer_base_dir + '/checkpointR8x') -import time -import cp_getter -import fwo_globals -import cp_const -import cp_network - - -################# enrich ####################### -def enrich_config (config, mgm_details, limit=150, details_level=cp_const.details_level, noapi=False, sid=None): - - logger = getFwoLogger() - base_url = 'https://' + mgm_details['hostname'] + ':' + str(mgm_details['port']) + '/web_api/' - nw_objs_from_obj_tables = [] - svc_objs_from_obj_tables = [] - starttime = int(time.time()) - - # do nothing for empty configs - if config == {}: - return 0 - - ################################################################################# - # get object data which is only contained as uid in config by making additional api calls - # get all object uids (together with type) from all rules in fields src, dst, svc - nw_uids_from_rulebase = [] - svc_uids_from_rulebase = [] - - for rulebase in config['rulebases'] + config['nat_rulebases']: - if fwo_globals.debug_level>5: - if 'layername' in rulebase: - logger.debug ( "Searching for all uids in rulebase: " + rulebase['layername'] ) - cp_getter.collect_uids_from_rulebase(rulebase, nw_uids_from_rulebase, svc_uids_from_rulebase, "top_level") - - # remove duplicates from uid lists - nw_uids_from_rulebase = list(set(nw_uids_from_rulebase)) - svc_uids_from_rulebase = list(set(svc_uids_from_rulebase)) - - # get all uids in objects tables - for obj_table in config['object_tables']: - nw_objs_from_obj_tables.extend(cp_getter.get_all_uids_of_a_type(obj_table, cp_const.nw_obj_table_names)) - svc_objs_from_obj_tables.extend(cp_getter.get_all_uids_of_a_type(obj_table, cp_const.svc_obj_table_names)) - - # identify all objects (by type) that are missing in objects tables but present in rulebase - missing_nw_object_uids = cp_getter.get_broken_object_uids(nw_objs_from_obj_tables, nw_uids_from_rulebase) - missing_svc_object_uids = cp_getter.get_broken_object_uids(svc_objs_from_obj_tables, svc_uids_from_rulebase) - - # adding the uid of the Original object for natting: - missing_nw_object_uids.append(cp_const.original_obj_uid) - missing_svc_object_uids.append(cp_const.original_obj_uid) - - if fwo_globals.debug_level>4: - logger.debug ( "found missing nw objects: '" + ",".join(missing_nw_object_uids) + "'" ) - logger.debug ( "found missing svc objects: '" + ",".join(missing_svc_object_uids) + "'" ) - - if noapi == False: - # if sid is None: - # TODO: why is the re-genereation of a new sid necessary here? - # if mgm_details['domainUid'] != None: - # api_domain = mgm_details['domainUid'] - # else: - # api_domain = mgm_details['configPath'] - - # sid = cp_getter.login(mgm_details['import_credential']['user'],mgm_details['import_credential']['secret'],mgm_details['hostname'],mgm_details['port'],api_domain) - # logger.debug ( "re-logged into api" ) - - # if an object is not there: - # make api call: show object details-level full uid "" and add object to respective json - for missing_obj in missing_nw_object_uids: - show_params_host = {'details-level':cp_const.details_level,'uid':missing_obj} - logger.debug ( "fetching obj with uid: " + missing_obj) - obj = cp_getter.cp_api_call(base_url, 'show-object', show_params_host, sid) - if 'object' in obj: - obj = obj['object'] - if (obj['type'] == 'CpmiAnyObject'): - json_obj = {"object_type": "hosts", "object_chunks": [ { - "objects": [ { - 'uid': obj['uid'], 'name': obj['name'], 'color': obj['color'], - 'comments': 'any nw object checkpoint (hard coded)', - 'type': 'CpmiAnyObject', 'ipv4-address': '0.0.0.0/0', - } ] } ] } - config['object_tables'].append(json_obj) - elif (obj['type'] == 'simple-gateway' or obj['type'] == 'CpmiGatewayPlain' or obj['type'] == 'interop'): - json_obj = {"object_type": "hosts", "object_chunks": [ { - "objects": [ { - 'uid': obj['uid'], 'name': obj['name'], 'color': obj['color'], - 'comments': obj['comments'], 'type': 'host', 'ipv4-address': cp_network.get_ip_of_obj(obj), - } ] } ] } - config['object_tables'].append(json_obj) - elif obj['type'] == 'multicast-address-range': - logger.debug("found multicast-address-range: " + obj['name'] + " (uid:" + obj['uid']+ ")") - json_obj = {"object_type": "hosts", "object_chunks": [ { - "objects": [ { - 'uid': obj['uid'], 'name': obj['name'], 'color': obj['color'], - 'comments': obj['comments'], 'type': 'host', 'ipv4-address': cp_network.get_ip_of_obj(obj), - } ] } ] } - config['object_tables'].append(json_obj) - elif (obj['type'] == 'CpmiVsClusterMember' or obj['type'] == 'CpmiVsxClusterMember'): - json_obj = {"object_type": "hosts", "object_chunks": [ { - "objects": [ { - 'uid': obj['uid'], 'name': obj['name'], 'color': obj['color'], - 'comments': obj['comments'], 'type': 'host', 'ipv4-address': cp_network.get_ip_of_obj(obj), - } ] } ] } - config['object_tables'].append(json_obj) - logger.debug ('missing obj: ' + obj['name'] + obj['type']) - elif (obj['type'] == 'Global'): - json_obj = {"object_type": "hosts", "object_chunks": [ { - "objects": [ { - 'uid': obj['uid'], 'name': obj['name'], 'color': obj['color'], - 'comments': obj['comments'], 'type': 'host', 'ipv4-address': '0.0.0.0/0', - } ] } ] } - config['object_tables'].append(json_obj) - logger.debug ('missing obj: ' + obj['name'] + obj['type']) - elif (obj['type'] == 'updatable-object'): - json_obj = {"object_type": "hosts", "object_chunks": [ { - "objects": [ { - 'uid': obj['uid'], 'name': obj['name'], 'color': obj['color'], - 'comments': obj['comments'], 'type': 'group' #, 'ipv4-address': '0.0.0.0/0', - } ] } ] } - config['object_tables'].append(json_obj) - logger.debug ('missing obj: ' + obj['name'] + obj['type']) - elif (obj['type'] == 'Internet'): - json_obj = {"object_type": "hosts", "object_chunks": [ { - "objects": [ { - 'uid': obj['uid'], 'name': obj['name'], 'color': obj['color'], - 'comments': obj['comments'], 'type': 'network', 'ipv4-address': '0.0.0.0/0', - } ] } ] } - config['object_tables'].append(json_obj) - elif (obj['type'] == 'access-role'): - pass # ignorning user objects - else: - logger.warning ( "missing nw obj of unexpected type '" + obj['type'] + "': " + missing_obj ) - logger.debug ( "missing nw obj: " + missing_obj + " added" ) - else: - logger.warning("could not get the missing object with uid=" + missing_obj + " from CP API") - - for missing_obj in missing_svc_object_uids: - show_params_host = {'details-level':cp_const.details_level,'uid':missing_obj} - obj = cp_getter.cp_api_call(base_url, 'show-object', show_params_host, sid) - if 'object' in obj: - obj = obj['object'] - if (obj['type'] == 'CpmiAnyObject'): - json_obj = {"object_type": "services-other", "object_chunks": [ { - "objects": [ { - 'uid': obj['uid'], 'name': obj['name'], 'color': obj['color'], - 'comments': 'any svc object checkpoint (hard coded)', - 'type': 'service-other', 'ip-protocol': '0' - } ] } ] } - config['object_tables'].append(json_obj) - elif (obj['type'] == 'Global'): - json_obj = {"object_type": "services-other", "object_chunks": [ { - "objects": [ { - 'uid': obj['uid'], 'name': obj['name'], 'color': obj['color'], - 'comments': 'Original svc object checkpoint (hard coded)', - 'type': 'service-other', 'ip-protocol': '0' - } ] } ] } - config['object_tables'].append(json_obj) - else: - logger.warning ( "missing svc obj (uid=" + missing_obj + ") of unexpected type \"" + obj['type'] +"\"" ) - logger.debug ( "missing svc obj: " + missing_obj + " added") - - # logout_result = cp_getter.cp_api_call(base_url, 'logout', {}, sid) - - logger.debug ( "checkpointR8x/enrich_config - duration: " + str(int(time.time()) - starttime) + "s" ) - - return 0 diff --git a/roles/importer/files/importer/checkpointR8x/cp_getter.py b/roles/importer/files/importer/checkpointR8x/cp_getter.py deleted file mode 100644 index 6c455c12e3..0000000000 --- a/roles/importer/files/importer/checkpointR8x/cp_getter.py +++ /dev/null @@ -1,365 +0,0 @@ -# library for API get functions -from asyncio.log import logger -from distutils.log import debug -import json -import re -import requests, requests.packages -import time -from common import FwLoginFailed -from fwo_log import getFwoLogger -import fwo_globals - - -def cp_api_call(url, command, json_payload, sid, show_progress=False): - url += command - request_headers = {'Content-Type' : 'application/json'} - if sid != '': # only not set for login - request_headers.update({'X-chkp-sid' : sid}) - - if fwo_globals.debug_level>4: - logger.debug("using sid: " + sid ) - - try: - r = requests.post(url, json=json_payload, headers=request_headers, verify=fwo_globals.verify_certs) - except requests.exceptions.RequestException as e: - raise Exception("error, url: " + str(url)) - - if r is None: - if 'password' in json.dumps(json_payload): - exception_text = "\nerror while sending api_call containing credential information to url '" + str(url) - else: - exception_text = "\nerror while sending api_call to url '" + str(url) + "' with payload '" + json.dumps(json_payload, indent=2) + "' and headers: '" + json.dumps(request_headers, indent=2) - raise Exception (exception_text) - if show_progress: - print ('.', end='', flush=True) - - try: - json_response = r.json() - except: - raise Exception("checkpointR8x:api_call: response is not in valid json format: " + r.text) - return json_response - - -def login(user, password, api_host, api_port, domain): - logger = getFwoLogger() - payload = {'user': user, 'password': password} - if domain is not None and domain != '': - payload.update({'domain': domain}) - base_url = 'https://' + api_host + ':' + str(api_port) + '/web_api/' - if int(fwo_globals.debug_level)>2: - logger.debug("auto-discover - login to url " + base_url + " with user " + user) - response = cp_api_call(base_url, 'login', payload, '') - if "sid" not in response: - exception_text = "\ngetter ERROR: did not receive a sid during login, " + \ - "api call: api_host: " + str(api_host) + ", api_port: " + str(api_port) + ", base_url: " + str(base_url) + \ - ", ssl_verification: " + str(fwo_globals.verify_certs) - raise FwLoginFailed(exception_text) - return response["sid"] - - -def get_api_url(sid, api_host, api_port, user, base_url, limit, test_version, ssl_verification, debug_level=0): - logger = getFwoLogger() - - v_url = '' - if test_version == 'off': - v_url = base_url - else: - api_versions = cp_api_call(base_url, 'show-api-versions', {}, sid) - api_version = api_versions["current-version"] - api_supported = api_versions["supported-versions"] - - if debug_level>3: - logger.debug ("current version: " + api_version + "; supported versions: "+ ', '.join(api_supported) + "; limit:"+ str(limit) ) - logger.debug ("getter - login:" + user + "; sid:" + sid ) - if re.search(r'^\d+[\.\d+]+$', test_version) or re.search(r'^\d+$', test_version): - if test_version in api_supported : - v_url = base_url + 'v' + test_version + '/' - else: - raise Exception("api version " + test_version + " not supported") - else: - logger.debug ("not a valid version") - raise Exception("\"" + test_version +"\" - not a valid version") - logger.debug ("test_version: " + test_version + " - url: "+ v_url) - return v_url - - -def set_api_url(base_url,testmode,api_supported,hostname, debug_level=0): - logger = getFwoLogger() - url = '' - if testmode == 'off': - url = base_url - else: - if re.search(r'^\d+[\.\d+]+$', testmode) or re.search(r'^\d+$', testmode): - if testmode in api_supported : - url = base_url + 'v' + testmode + '/' - else: - raise Exception("api version " + testmode + " is not supported by the manager " + hostname + " - Import is canceled") - else: - logger.debug ("not a valid version") - raise Exception("\"" + testmode +"\" - not a valid version") - logger.debug ("testmode: " + testmode + " - url: "+ url) - return url - - -def get_changes(sid,api_host,api_port,fromdate): - logger = getFwoLogger() - payload = {'from-date' : fromdate, 'details-level' : 'uid'} - logger.debug ("payload: " + json.dumps(payload)) - base_url = 'https://' + api_host + ':' + str(api_port) + '/web_api/' - task_id = cp_api_call(base_url, 'show-changes', payload, sid) - - logger.debug ("task_id: " + json.dumps(task_id)) - sleeptime = 1 - status = 'in progress' - while (status == 'in progress'): - time.sleep(sleeptime) - tasks = cp_api_call(base_url, 'show-task', task_id, sid) - if 'tasks' in tasks: - for task in tasks['tasks']: - if fwo_globals.debug_level>5: - logger.debug ("task: " + json.dumps(task)) - if 'status' in task: - status = task['status'] - if 'succeeded' in status: - for detail in task['task-details']: - if detail['changes']: - logger.debug ("status: " + status + " -> changes found") - return 1 - else: - logger.debug ("status: " + status + " -> but no changes found") - elif status == 'failed': - logger.debug ("show-changes - status: failed -> no changes found") - elif status == 'in progress': - logger.debug ("status: in progress") - else: - logger.error ("unknown status: " + status) - return -1 - else: - logger.error ("no status in task") - return -1 - sleeptime += 2 - if sleeptime > 40: - logger.error ("task took too long, aborting") - return -1 - return 0 - - -def collect_uids_from_rule(rule, nw_uids_found, svc_uids_found): - # just a guard: - if 'rule-number' in rule and 'type' in rule and rule['type'] != 'place-holder': - logger = getFwoLogger() - - if rule['type']=='access-rule': # normal rule (no nat) - merging lists - lsources = rule["source"] - ldestinations = rule["destination"] - lservices = rule["service"] - - elif rule['type']=='nat-rule': - lsources = [rule["translated-source"], rule["original-source"]] - ldestinations = [rule["translated-destination"], rule["original-destination"]] - lservices = [rule["translated-service"], rule["original-service"]] - - for src in lsources: - if 'type' in src: - if src['type'] == 'LegacyUserAtLocation': - nw_uids_found.append(src["location"]) - elif src['type'] == 'access-role': - if isinstance(src['networks'], str): # just a single source - if src['networks'] != 'any': # ignore any objects as they do not contain a uid - nw_uids_found.append(src['networks']) - else: # more than one source - for nw in src['networks']: - nw_uids_found.append(nw) - else: # standard network objects as source, only here we have an uid value - nw_uids_found.append(src['uid']) - else: - #logger.warning ("found src without type field: " + json.dumps(src)) - if 'uid' in src: - nw_uids_found.append(src['uid']) - - for dst in ldestinations: - nw_uids_found.append(dst['uid']) - for svc in lservices: - svc_uids_found.append(svc['uid']) - return - - -def collect_uids_from_rulebase(rulebase, nw_uids_found, svc_uids_found, debug_text): - logger = getFwoLogger() - chunk_name = '' - if 'layerchunks' in rulebase: - chunk_name = 'layerchunks' - elif 'nat_rule_chunks' in rulebase: - chunk_name = 'nat_rule_chunks' - else: - for rule in rulebase: - if 'rulebase' in rule: - collect_uids_from_rulebase(rule['rulebase'], nw_uids_found, svc_uids_found, debug_text + '.') - else: - collect_uids_from_rule(rule, nw_uids_found, svc_uids_found) - return - for layer_chunk in rulebase[chunk_name]: - if 'rulebase' in layer_chunk: - if fwo_globals.debug_level>5: - debug_layer_str = "handling layer with uid " + layer_chunk['uid'] - if 'name' in layer_chunk: - debug_layer_str += '(' + layer_chunk['name'] + ')' - logger.debug ( debug_layer_str ) - for rule in layer_chunk['rulebase']: - if 'rule-number' in rule and 'type' in rule and rule['type'] != 'place-holder': - collect_uids_from_rule(rule, nw_uids_found, svc_uids_found) - else: - if 'rulebase' in rule and rule['rulebase'] != []: # found a layer within a rulebase, recursing - if fwo_globals.debug_level>8: - logger.debug ("found embedded rulebase - recursing") - collect_uids_from_rulebase(rule['rulebase'], nw_uids_found, svc_uids_found, debug_text + '.') - return - - -def get_all_uids_of_a_type(object_table, obj_table_names): - all_uids = [] - - if object_table['object_type'] in obj_table_names: - for chunk in object_table['object_chunks']: - if 'objects' in chunk: - for obj in chunk['objects']: - if 'uid' in obj: - all_uids.append(obj['uid']) # add non-group (simple) refs - elif 'uid-in-updatable-objects-repository' in obj: - all_uids.append(obj['uid-in-updatable-objects-repository']) # add updatable obj uid - else: - logger.warning ("found nw obj without UID: " + str(obj)) - - all_uids = list(set(all_uids)) # remove duplicates - return all_uids - - -def get_broken_object_uids(all_uids_from_obj_tables, all_uids_from_rules): - broken_uids = [] - for uid in all_uids_from_rules: - if not uid in all_uids_from_obj_tables: - broken_uids.append(uid) - return list(set(broken_uids)) - - -def get_layer_from_api_as_dict (api_v_url, sid, show_params_rules, layername, access_type='access', collection_type='rulebase'): - # access_type: access / nat - # collection_type: rulebase / layer - logger = getFwoLogger() - current_layer_json = { "layername": layername, "layerchunks": [] } - current=0 - total=current+1 - while (current5: - logger.debug ( "found inline layer " + inline_layer_name ) - inline_layer = get_layer_from_api_as_dict (api_v_url, sid, show_params_rules, inline_layer_name, access_type=access_type, collection_type=collection_type) - rulebase['rulebase'][rulebase_idx+1:rulebase_idx+1] = inline_layer['layerchunks'] #### insert inline layer here - rulebase_idx += len(inline_layer['layerchunks']) - - if 'name' in rule and rule['name'] == "Placeholder for domain rules": - logger.debug ("getter - found domain rules reference with uid " + rule["uid"]) - rulebase_idx += 1 - - -def get_nat_rules_from_api_as_dict (api_v_url, sid, show_params_rules): - logger = getFwoLogger() - nat_rules = { "nat_rule_chunks": [] } - current=0 - total=current+1 - while (current5: - logger.debug("result:\n" + json.dumps(top_ruleset_json, indent=2)) - return top_ruleset_json diff --git a/roles/importer/files/importer/checkpointR8x/cp_network.py b/roles/importer/files/importer/checkpointR8x/cp_network.py deleted file mode 100644 index be58428baf..0000000000 --- a/roles/importer/files/importer/checkpointR8x/cp_network.py +++ /dev/null @@ -1,158 +0,0 @@ -from fwo_log import getFwoLogger -import json -import cp_const -from fwo_const import list_delimiter -import fwo_alert, fwo_api -import ipaddress - - -def normalize_network_objects(full_config, config2import, import_id, mgm_id=0, debug_level=0): - nw_objects = [] - - for obj_table in full_config['object_tables']: - collect_nw_objects(obj_table, nw_objects, - debug_level=debug_level, mgm_id=mgm_id) - for nw_obj in nw_objects: - nw_obj.update({'control_id': import_id}) - for idx in range(0, len(nw_objects)-1): - if nw_objects[idx]['obj_typ'] == 'group': - add_member_names_for_nw_group(idx, nw_objects) - config2import.update({'network_objects': nw_objects}) - - -# collect_nw_objects from object tables and write them into global nw_objects dict -def collect_nw_objects(object_table, nw_objects, debug_level=0, mgm_id=0): - logger = getFwoLogger() - - if object_table['object_type'] in cp_const.nw_obj_table_names: - for chunk in object_table['object_chunks']: - if 'objects' in chunk: - for obj in chunk['objects']: - ip_addr = '' - member_refs = None - member_names = None - if 'members' in obj: - member_refs = '' - member_names = '' - for member in obj['members']: - member_refs += member + list_delimiter - member_refs = member_refs[:-1] - if obj['members'] == '': - obj['members'] = None - - ip_addr = get_ip_of_obj(obj, mgm_id=mgm_id) - first_ip = ip_addr - last_ip = None - obj_type = 'undef' - if 'type' in obj: - obj_type = obj['type'] - elif 'uid-in-updatable-objects-repository' in obj: - obj_type = 'group' - obj['name'] = obj['name-in-updatable-objects-repository'] - obj['uid'] = obj['uid-in-updatable-objects-repository'] - obj['color'] = 'black' - if obj_type == 'dns-domain': - first_ip = None - last_ip = None - obj_type = 'group' - - if obj_type == 'group-with-exclusion': - first_ip = None - last_ip = None - obj_type = 'group' - # TODO: handle exclusion groups correctly - - if obj_type == 'group': - first_ip = None - last_ip = None - - if obj_type == 'address-range' or obj_type == 'multicast-address-range': - obj_type = 'ip_range' - if debug_level > 5: - logger.debug( - "parse_network::collect_nw_objects - found range object '" + obj['name'] + "' with ip: " + ip_addr) - if '-' in str(ip_addr): - first_ip, last_ip = str(ip_addr).split('-') - else: - logger.warning("parse_network::collect_nw_objects - found range object '" + - obj['name'] + "' without hyphen: " + ip_addr) - elif obj_type in cp_const.cp_specific_object_types: - if debug_level > 5: - logger.debug("parse_network::collect_nw_objects - rewriting non-standard cp-host-type '" + - obj['name'] + "' with object type '" + obj_type + "' to host") - logger.debug("obj_dump:" + json.dumps(obj, indent=3)) - obj_type = 'host' - # adding the object: - if not 'comments' in obj or obj['comments'] == '': - obj['comments'] = None - nw_objects.extend([{'obj_uid': obj['uid'], 'obj_name': obj['name'], 'obj_color': obj['color'], - 'obj_comment': obj['comments'], - 'obj_typ': obj_type, 'obj_ip': first_ip, 'obj_ip_end': last_ip, - 'obj_member_refs': member_refs, 'obj_member_names': member_names}]) - - -# for members of groups, the name of the member obj needs to be fetched separately (starting from API v1.?) -def resolve_nw_uid_to_name(uid, nw_objects): - # return name of nw_objects element where obj_uid = uid - for obj in nw_objects: - if obj['obj_uid'] == uid: - return obj['obj_name'] - return 'ERROR: uid "' + uid + '" not found' - - -def add_member_names_for_nw_group(idx, nw_objects): - group = nw_objects.pop(idx) - if group['obj_member_refs'] == '' or group['obj_member_refs'] == None: - #member_names = None - #obj_member_refs = None - group['obj_member_names'] = None - group['obj_member_refs'] = None - else: - member_names = '' - obj_member_refs = group['obj_member_refs'].split(list_delimiter) - for ref in obj_member_refs: - member_name = resolve_nw_uid_to_name(ref, nw_objects) - member_names += member_name + list_delimiter - group['obj_member_names'] = member_names[:-1] - nw_objects.insert(idx, group) - - -def validate_ip_address(address): - try: - # ipaddress.ip_address(address) - ipaddress.ip_network(address) - return True - # print("IP address {} is valid. The object returned is {}".format(address, ip)) - except ValueError: - return False - # print("IP address {} is not valid".format(address)) - - -def get_ip_of_obj(obj, mgm_id=None): - if 'ipv4-address' in obj: - ip_addr = obj['ipv4-address'] - elif 'ipv6-address' in obj: - ip_addr = obj['ipv6-address'] - elif 'subnet4' in obj: - ip_addr = obj['subnet4'] + '/' + str(obj['mask-length4']) - elif 'subnet6' in obj: - ip_addr = obj['subnet6'] + '/' + str(obj['mask-length6']) - elif 'ipv4-address-first' in obj and 'ipv4-address-last' in obj: - ip_addr = obj['ipv4-address-first'] + '-' + str(obj['ipv4-address-last']) - elif 'ipv6-address-first' in obj and 'ipv6-address-last' in obj: - ip_addr = obj['ipv6-address-first'] + '-' + str(obj['ipv6-address-last']) - else: - ip_addr = None - - ## fix malformed ip addresses (should not regularly occur and constitutes a data issue in CP database) - if ip_addr is None or ('type' in obj and (obj['type'] == 'address-range' or obj['type'] == 'multicast-address-range')): - pass # ignore None and ranges here - elif not validate_ip_address(ip_addr): - alerter = fwo_alert.getFwoAlerter() - alert_description = "object is not a valid ip address (" + str(ip_addr) + ")" - fwo_api.create_data_issue(alerter['fwo_api_base_url'], alerter['jwt'], severity=2, obj_name=obj['name'], object_type=obj['type'], description=alert_description, mgm_id=mgm_id) - alert_description = "object '" + obj['name'] + "' (type=" + obj['type'] + ") is not a valid ip address (" + str(ip_addr) + ")" - fwo_api.setAlert(alerter['fwo_api_base_url'], alerter['jwt'], title="import error", severity=2, role='importer', \ - description=alert_description, source='import', alertCode=17, mgm_id=mgm_id) - ip_addr = '0.0.0.0/32' # setting syntactically correct dummy ip - return ip_addr diff --git a/roles/importer/files/importer/checkpointR8x/cp_rule.py b/roles/importer/files/importer/checkpointR8x/cp_rule.py deleted file mode 100644 index b52664a1ba..0000000000 --- a/roles/importer/files/importer/checkpointR8x/cp_rule.py +++ /dev/null @@ -1,438 +0,0 @@ -from asyncio.log import logger -from fwo_log import getFwoLogger -import json -import cp_const -import fwo_const -import fwo_globals -from fwo_const import list_delimiter, default_section_header_text -from fwo_base import sanitize -from fwo_exception import ImportRecursionLimitReached - -uid_to_name_map = {} - - -def normalize_rulebases_top_level (full_config, current_import_id, config2import): - logger = getFwoLogger() - target_rulebase = [] - rule_num = 0 - parent_uid="" - section_header_uids=[] - - # fill uid_to_name_map: - for nw_obj in config2import['network_objects']: - uid_to_name_map[nw_obj['obj_uid']] = nw_obj['obj_name'] - - rb_range = range(len(full_config['rulebases'])) - for rb_id in rb_range: - # if current_layer_name == args.rulebase: - if fwo_globals.debug_level>3: - logger.debug("parsing layer " + full_config['rulebases'][rb_id]['layername']) - - # parse access rules - rule_num = parse_rulebase( - full_config['rulebases'][rb_id], target_rulebase, full_config['rulebases'][rb_id]['layername'], - current_import_id, rule_num, section_header_uids, parent_uid, config2import) - # now parse the nat rulebase - - # parse nat rules - if len(full_config['nat_rulebases'])>0: - if len(full_config['nat_rulebases']) != len(rb_range): - logger.warning('get_config - found ' + str(len(full_config['nat_rulebases'])) + - ' nat rulebases and ' + str(len(rb_range)) + ' access rulebases') - else: - rule_num = parse_nat_rulebase( - full_config['nat_rulebases'][rb_id], target_rulebase, full_config['rulebases'][rb_id]['layername'], - current_import_id, rule_num, section_header_uids, parent_uid, config2import) - return target_rulebase - - -def parse_single_rule(src_rule, rulebase, layer_name, import_id, rule_num, parent_uid, config2import, debug_level=0): - logger = getFwoLogger() - # reference to domain rule layer, filling up basic fields - if 'type' in src_rule and src_rule['type'] != 'place-holder': - if 'rule-number' in src_rule: # standard rule, no section header - # SOURCE names - rule_src_name = '' - for src in src_rule["source"]: - if 'type' in src: - if src['type'] == 'LegacyUserAtLocation': - rule_src_name += src['name'] + list_delimiter - elif src['type'] == 'access-role': - if isinstance(src['networks'], str): # just a single source - if src['networks'] == 'any': - rule_src_name += src["name"] + \ - '@' + 'Any' + list_delimiter - else: - rule_src_name += src["name"] + '@' + \ - src['networks'] + list_delimiter - else: # more than one source - for nw in src['networks']: - nw_resolved = resolve_uid_to_name(nw) - if nw_resolved == "": - rule_src_name += src["name"] + list_delimiter - else: - rule_src_name += src["name"] + '@' + nw_resolved + list_delimiter - else: # standard network objects as source - rule_src_name += src["name"] + list_delimiter - else: - # assuming standard network object as source (interface) with missing type - rule_src_name += src["name"] + list_delimiter - - rule_src_name = rule_src_name[:-1] # removing last list_delimiter - - # SOURCE refs - rule_src_ref = '' - for src in src_rule["source"]: - if 'type' in src: - if src['type'] == 'LegacyUserAtLocation': - rule_src_ref += src["userGroup"] + '@' + \ - src["location"] + list_delimiter - elif src['type'] == 'access-role': - if isinstance(src['networks'], str): # just a single source - if src['networks'] == 'any': - rule_src_ref += src['uid'] + '@' + \ - cp_const.any_obj_uid + list_delimiter - else: - rule_src_ref += src['uid'] + '@' + \ - src['networks'] + list_delimiter - else: # more than one source - for nw in src['networks']: - rule_src_ref += src['uid'] + \ - '@' + nw + list_delimiter - else: # standard network objects as source - rule_src_ref += src["uid"] + list_delimiter - else: - # assuming standard network object as source (interface) with missing type - rule_src_ref += src["uid"] + list_delimiter - rule_src_ref = rule_src_ref[:-1] # removing last list_delimiter - - # rule_dst... - rule_dst_name = '' - for dst in src_rule["destination"]: - if 'type' in dst: - if dst['type'] == 'LegacyUserAtLocation': - rule_dst_name += dst['name'] + list_delimiter - elif dst['type'] == 'access-role': - if isinstance(dst['networks'], str): # just a single destination - if dst['networks'] == 'any': - rule_dst_name += dst["name"] + \ - '@' + 'Any' + list_delimiter - else: - rule_dst_name += dst["name"] + '@' + \ - dst['networks'] + list_delimiter - else: # more than one source - for nw in dst['networks']: - rule_dst_name += dst[ - # TODO: this is not correct --> need to reverse resolve name from given UID - "name"] + '@' + nw + list_delimiter - else: # standard network objects as destination - rule_dst_name += dst["name"] + list_delimiter - else: - # assuming standard network object as destination (interface) with missing type - rule_dst_name += dst["name"] + list_delimiter - - rule_dst_name = rule_dst_name[:-1] - - rule_dst_ref = '' - for dst in src_rule["destination"]: - if 'type' in dst: - if dst['type'] == 'LegacyUserAtLocation': - rule_dst_ref += dst["userGroup"] + '@' + \ - dst["location"] + list_delimiter - elif dst['type'] == 'access-role': - if isinstance(dst['networks'], str): # just a single destination - if dst['networks'] == 'any': - rule_dst_ref += dst['uid'] + '@' + \ - cp_const.any_obj_uid + list_delimiter - else: - rule_dst_ref += dst['uid'] + '@' + \ - dst['networks'] + list_delimiter - else: # more than one source - for nw in dst['networks']: - rule_dst_ref += dst['uid'] + \ - '@' + nw + list_delimiter - else: # standard network objects as destination - rule_dst_ref += dst["uid"] + list_delimiter - - else: - # assuming standard network object as destination (interface) with missing type - rule_dst_ref += dst["uid"] + list_delimiter - - rule_dst_ref = rule_dst_ref[:-1] - - # rule_svc... - rule_svc_name = '' - for svc in src_rule["service"]: - rule_svc_name += svc["name"] + list_delimiter - rule_svc_name = rule_svc_name[:-1] - - rule_svc_ref = '' - for svc in src_rule["service"]: - rule_svc_ref += svc["uid"] + list_delimiter - rule_svc_ref = rule_svc_ref[:-1] - - if 'name' in src_rule and src_rule['name'] != '': - rule_name = src_rule['name'] - else: - rule_name = None - - if 'meta-info' in src_rule and 'last-modifier' in src_rule['meta-info']: - rule_last_change_admin = src_rule['meta-info']['last-modifier'] - else: - rule_last_change_admin = None - - # new in v5.1.17: - if 'parent_rule_uid' in src_rule: - logger.debug( - 'found rule (uid=' + src_rule['uid'] + ') with parent_rule_uid set: ' + src_rule['parent_rule_uid']) - parent_rule_uid = src_rule['parent_rule_uid'] - else: - parent_rule_uid = parent_uid - if parent_rule_uid == '': - parent_rule_uid = None - - # new in v5.5.1: - if 'rule_type' in src_rule: - rule_type = src_rule['rule_type'] - else: - rule_type = 'access' - - if 'comments' in src_rule: - if src_rule['comments'] == '': - comments = None - else: - comments = src_rule['comments'] - else: - comments = None - - if 'hits' in src_rule and 'last-date' in src_rule['hits'] and 'iso-8601' in src_rule['hits']['last-date']: - last_hit = src_rule['hits']['last-date']['iso-8601'] - else: - last_hit = None - - rule = { - "control_id": int(import_id), - "rule_num": int(rule_num), - "rulebase_name": sanitize(layer_name), - # rule_ruleid - "rule_disabled": not bool(src_rule['enabled']), - "rule_src_neg": bool(src_rule['source-negate']), - "rule_src": sanitize(rule_src_name), - "rule_src_refs": sanitize(rule_src_ref), - "rule_dst_neg": bool(src_rule['destination-negate']), - "rule_dst": sanitize(rule_dst_name), - "rule_dst_refs": sanitize(rule_dst_ref), - "rule_svc_neg": bool(src_rule['service-negate']), - "rule_svc": sanitize(rule_svc_name), - "rule_svc_refs": sanitize(rule_svc_ref), - "rule_action": sanitize(src_rule['action']['name']), - "rule_track": sanitize(src_rule['track']['type']['name']), - "rule_installon": sanitize(src_rule['install-on'][0]['name']), - "rule_time": sanitize(src_rule['time'][0]['name']), - "rule_name": sanitize(rule_name), - "rule_uid": sanitize(src_rule['uid']), - "rule_implied": False, - "rule_type": sanitize(rule_type), - # "rule_head_text": sanitize(section_name), - # rule_from_zone - # rule_to_zone - "rule_last_change_admin": sanitize(rule_last_change_admin), - "parent_rule_uid": sanitize(parent_rule_uid), - "last_hit": sanitize(last_hit) - } - if comments is not None: - rule['rule_comment'] = sanitize(comments) - rulebase.append(rule) - return rule_num + 1 - return rule_num - - -def resolve_uid_to_name(nw_obj_uid): - if nw_obj_uid in uid_to_name_map: - return uid_to_name_map[nw_obj_uid] - else: - logger = getFwoLogger() - logger.warning("could not resolve network object with uid " + nw_obj_uid) - return "" - - -def insert_section_header_rule(rulebase, section_name, layer_name, import_id, rule_uid, rule_num, section_header_uids, parent_uid): - section_header_uids.append(sanitize(rule_uid)) - rule = { - "control_id": int(import_id), - "rule_num": int(rule_num), - "rulebase_name": sanitize(layer_name), - # rule_ruleid - "rule_disabled": False, - "rule_src_neg": False, - "rule_src": "Any", - "rule_src_refs": sanitize(cp_const.any_obj_uid), - "rule_dst_neg": False, - "rule_dst": "Any", - "rule_dst_refs": sanitize(cp_const.any_obj_uid), - "rule_svc_neg": False, - "rule_svc": "Any", - "rule_svc_refs": sanitize(cp_const.any_obj_uid), - "rule_action": "Accept", - "rule_track": "Log", - "rule_installon": "Policy Targets", - "rule_time": "Any", - "rule_implied": False, - # "rule_comment": None, - # rule_name - "rule_uid": sanitize(rule_uid), - "rule_head_text": sanitize(section_name), - # rule_from_zone - # rule_to_zone - # rule_last_change_admin - "parent_rule_uid": sanitize(parent_uid) - } - rulebase.append(rule) - return rule_num + 1 - - -def add_domain_rule_header_rule(rulebase, section_name, layer_name, import_id, rule_uid, rule_num, section_header_uids, parent_uid): - return insert_section_header_rule(rulebase, section_name, layer_name, - import_id, rule_uid, rule_num, section_header_uids, parent_uid) - - -def check_and_add_section_header(src_rulebase, target_rulebase, layer_name, import_id, rule_num, section_header_uids, parent_uid, config2import, debug_level=0, recursion_level=1): - # if current rulebase starts a new section, add section header, but only if it does not exist yet (can happen by chunking a section) - if 'type' in src_rulebase and src_rulebase['type'] == 'access-section' and 'uid' in src_rulebase: # and not src_rulebase['uid'] in section_header_uids: - section_name = default_section_header_text - if 'name' in src_rulebase: - section_name = src_rulebase['name'] - if 'parent_rule_uid' in src_rulebase: - parent_uid = src_rulebase['parent_rule_uid'] - else: - parent_uid = "" - rule_num = insert_section_header_rule(target_rulebase, section_name, layer_name, import_id, src_rulebase['uid'], rule_num, section_header_uids, parent_uid) - parent_uid = src_rulebase['uid'] - return rule_num - - -def parse_rulebase(src_rulebase, target_rulebase, layer_name, import_id, rule_num, section_header_uids, parent_uid, config2import, - debug_level=0, recursion_level=1, layer_disabled=False): - logger = getFwoLogger() - if (recursion_level > fwo_const.max_recursion_level): - raise ImportRecursionLimitReached("parse_rulebase") from None - - # parse chunks - if 'layerchunks' in src_rulebase: # found chunks of layers which need to be parsed separately - for chunk in src_rulebase['layerchunks']: - if 'rulebase' in chunk: - for rules_chunk in chunk['rulebase']: - rule_num = parse_rulebase(rules_chunk, target_rulebase, layer_name, import_id, rule_num, - section_header_uids, parent_uid, config2import, debug_level=debug_level, recursion_level=recursion_level+1) - else: - rule_num = parse_rulebase(chunk, target_rulebase, layer_name, import_id, rule_num, section_header_uids, parent_uid, config2import, debug_level=debug_level, recursion_level=recursion_level+1) - - check_and_add_section_header(src_rulebase, target_rulebase, layer_name, import_id, rule_num, section_header_uids, parent_uid, config2import, debug_level=debug_level, recursion_level=recursion_level+1) - - # parse layered rulebase - if 'rulebase' in src_rulebase: - # layer_disabled = not src_rulebase['enabled'] - for rule in src_rulebase['rulebase']: - if 'type' in rule: - if rule['type'] == 'place-holder': # add domain rules - section_name = "" - if 'name' in src_rulebase: - section_name = rule['name'] - rule_num = add_domain_rule_header_rule( - target_rulebase, section_name, layer_name, import_id, rule['uid'], rule_num, section_header_uids, parent_uid) - else: # parse standard sections - rule_num = parse_single_rule( - rule, target_rulebase, layer_name, import_id, rule_num, parent_uid, config2import, debug_level=debug_level) - if 'rulebase' in rule: # alsways check if a rule contains another layer - rule_num = parse_rulebase(rule, target_rulebase, layer_name, import_id, rule_num, section_header_uids, parent_uid, config2import, debug_level=debug_level, recursion_level=recursion_level+1) - - if 'type' in src_rulebase and src_rulebase['type'] == 'place-holder': # add domain rules - logger.debug('found domain rule ref: ' + src_rulebase['uid']) - section_name = "" - if 'name' in src_rulebase: - section_name = src_rulebase['name'] - rule_num = add_domain_rule_header_rule( - target_rulebase, section_name, layer_name, import_id, src_rulebase['uid'], rule_num, section_header_uids, parent_uid) - - if 'rule-number' in src_rulebase: # rulebase is just a single rule - rule_num = parse_single_rule(src_rulebase, target_rulebase, layer_name, import_id, rule_num, parent_uid, config2import) - - return rule_num - - -def parse_nat_rulebase(src_rulebase, target_rulebase, layer_name, import_id, rule_num, section_header_uids, parent_uid, config2import, debug_level=0, recursion_level=1): - - if (recursion_level > fwo_const.max_recursion_level): - raise ImportRecursionLimitReached( - "parse_nat_rulebase_json") from None - - logger = getFwoLogger() - if 'nat_rule_chunks' in src_rulebase: - for chunk in src_rulebase['nat_rule_chunks']: - if 'rulebase' in chunk: - for rules_chunk in chunk['rulebase']: - rule_num = parse_nat_rulebase(rules_chunk, target_rulebase, layer_name, import_id, rule_num, - section_header_uids, parent_uid, config2import, debug_level=debug_level, recursion_level=recursion_level+1) - else: - logger.warning( - "parse_rule: found no rulebase in chunk:\n" + json.dumps(chunk, indent=2)) - else: - if 'rulebase' in src_rulebase: - check_and_add_section_header(src_rulebase, target_rulebase, layer_name, import_id, rule_num, section_header_uids, parent_uid, config2import, debug_level=debug_level, recursion_level=recursion_level+1) - - for rule in src_rulebase['rulebase']: - (rule_match, rule_xlate) = parse_nat_rule_transform(rule, rule_num) - rule_num = parse_single_rule( - rule_match, target_rulebase, layer_name, import_id, rule_num, parent_uid, config2import) - parse_single_rule( # do not increase rule_num here - rule_xlate, target_rulebase, layer_name, import_id, rule_num, parent_uid, config2import) - - if 'rule-number' in src_rulebase: # rulebase is just a single rule (xlate rules do not count) - (rule_match, rule_xlate) = parse_nat_rule_transform( - src_rulebase, rule_num) - rule_num = parse_single_rule( - rule_match, target_rulebase, layer_name, import_id, rule_num, parent_uid, config2import) - parse_single_rule( # do not increase rule_num here (xlate rules do not count) - rule_xlate, target_rulebase, layer_name, import_id, rule_num, parent_uid, config2import) - return rule_num - - -def parse_nat_rule_transform(xlate_rule_in, rule_num): - # todo: cleanup certain fields (install-on, ....) - rule_match = { - 'uid': xlate_rule_in['uid'], - 'source': [xlate_rule_in['original-source']], - 'destination': [xlate_rule_in['original-destination']], - 'service': [xlate_rule_in['original-service']], - 'action': {'name': 'Drop'}, - 'track': {'type': {'name': 'None'}}, - 'type': 'nat', - 'rule-number': rule_num, - 'source-negate': False, - 'destination-negate': False, - 'service-negate': False, - 'install-on': [{'name': 'Policy Targets'}], - 'time': [{'name': 'Any'}], - 'enabled': xlate_rule_in['enabled'], - 'comments': xlate_rule_in['comments'], - 'rule_type': 'original' - } - rule_xlate = { - 'uid': xlate_rule_in['uid'], - 'source': [xlate_rule_in['translated-source']], - 'destination': [xlate_rule_in['translated-destination']], - 'service': [xlate_rule_in['translated-service']], - 'action': {'name': 'Drop'}, - 'track': {'type': {'name': 'None'}}, - 'type': 'nat', - 'rule-number': rule_num, - 'enabled': True, - 'source-negate': False, - 'destination-negate': False, - 'service-negate': False, - 'install-on': [{'name': 'Policy Targets'}], - 'time': [{'name': 'Any'}], - 'rule_type': 'xlate' - } - return (rule_match, rule_xlate) - diff --git a/roles/importer/files/importer/checkpointR8x/cp_service.py b/roles/importer/files/importer/checkpointR8x/cp_service.py deleted file mode 100644 index 294ac93be9..0000000000 --- a/roles/importer/files/importer/checkpointR8x/cp_service.py +++ /dev/null @@ -1,133 +0,0 @@ -import re -import cp_const -from fwo_const import list_delimiter - - -# collect_svcobjects writes svc info into global users dict -def collect_svc_objects(object_table, svc_objects): - proto_map = { - 'service-tcp': 6, - 'service-udp': 17, - 'service-icmp': 1 - } - - if object_table['object_type'] in cp_const.svc_obj_table_names: - session_timeout = '' - typ = 'undef' - if object_table['object_type'] in cp_const.group_svc_obj_types: - typ = 'group' - if object_table['object_type'] in cp_const.simple_svc_obj_types: - typ = 'simple' - for chunk in object_table['object_chunks']: - if 'objects' in chunk: - for obj in chunk['objects']: - if 'type' in obj and obj['type'] in proto_map: - proto = proto_map[obj['type']] - elif 'ip-protocol' in obj: - proto = obj['ip-protocol'] - else: - proto = 0 - member_refs = '' - port = '' - port_end = '' - rpc_nr = None - member_refs = None - if 'members' in obj: - member_refs = '' - for member in obj['members']: - member_refs += member + list_delimiter - member_refs = member_refs[:-1] - if 'session-timeout' in obj: - session_timeout = str(obj['session-timeout']) - else: - session_timeout = None - if 'interface-uuid' in obj: - rpc_nr = obj['interface-uuid'] - if 'program-number' in obj: - rpc_nr = obj['program-number'] - if 'port' in obj: - port = str(obj['port']) - port_end = port - pattern = re.compile('^\>(\d+)$') - match = pattern.match(port) - if match: - port = str(int(match.group()[1:]) + 1) - port_end = str(65535) - else: - pattern = re.compile('^\<(\d+)$') - match = pattern.match(port) - if match: - port = str(1) - port_end = str(int(match.group()[1:]) - 1) - else: - pattern = re.compile('^(\d+)\-(\d+)$') - match = pattern.match(port) - if match: - port, port_end = match.group().split('-') - else: # standard port without "<>-" - pattern = re.compile('^(\d+)$') - match = pattern.match(port) - if match: - # port stays unchanged - port_end = port - else: # Any - pattern = re.compile('^(Any)$') - match = pattern.match(port) - if match: - port = str(1) - port_end = str(65535) - else: # e.g. suspicious cases - port = None - port_end = None - else: - # rpc, group - setting ports to 0 - port = None - port_end = None - if not 'color' in obj: - # print('warning: no color found for service ' + obj['name']) - obj['color'] = 'black' - if not 'comments' in obj or obj['comments'] == '': - obj['comments'] = None - svc_objects.extend([{'svc_uid': obj['uid'], 'svc_name': obj['name'], 'svc_color': obj['color'], - 'svc_comment': obj['comments'], - 'svc_typ': typ, 'svc_port': port, 'svc_port_end': port_end, - 'svc_member_refs': member_refs, - 'svc_member_names': None, - 'ip_proto': proto, - 'svc_timeout': session_timeout, - 'rpc_nr': rpc_nr - }]) - - -# return name of nw_objects element where obj_uid = uid -def resolve_svc_uid_to_name(uid, svc_objects): - for obj in svc_objects: - if obj['svc_uid'] == uid: - return obj['svc_name'] - return 'ERROR: uid ' + uid + ' not found' - - -def add_member_names_for_svc_group(idx, svc_objects): - member_names = '' - group = svc_objects.pop(idx) - - if 'svc_member_refs' in group and group['svc_member_refs'] is not None: - svc_member_refs = group['svc_member_refs'].split(list_delimiter) - for ref in svc_member_refs: - member_name = resolve_svc_uid_to_name(ref, svc_objects) - member_names += member_name + list_delimiter - group['svc_member_names'] = member_names[:-1] - - svc_objects.insert(idx, group) - - -def normalize_service_objects(full_config, config2import, import_id, debug_level=0): - svc_objects = [] - for svc_table in full_config['object_tables']: - collect_svc_objects(svc_table, svc_objects) - for obj in svc_objects: - obj.update({'control_id': import_id}) - for idx in range(0, len(svc_objects)-1): - if svc_objects[idx]['svc_typ'] == 'group': - add_member_names_for_svc_group(idx, svc_objects) - config2import.update({'service_objects': svc_objects}) diff --git a/roles/importer/files/importer/checkpointR8x/cp_user.py b/roles/importer/files/importer/checkpointR8x/cp_user.py deleted file mode 100644 index c92fc49a92..0000000000 --- a/roles/importer/files/importer/checkpointR8x/cp_user.py +++ /dev/null @@ -1,60 +0,0 @@ - -from fwo_log import getFwoLogger -import json - - -def collect_users_from_rule(rule, users): - if 'rule-number' in rule: # standard rule - logger = getFwoLogger() - if 'type' in rule and rule['type'] != 'place-holder': - for src in rule["source"]: - if 'type' in src: - if src['type'] == 'access-role' or src['type'] == 'LegacyUserAtLocation': - if src['type'] == 'access-role': - user_name = src['name'] - user_uid = src['uid'] - user_typ = 'group' - user_comment = src['comments'] - user_color = src['color'] - if 'users' in src: - user_typ = 'simple' - elif src['type'] == 'LegacyUserAtLocation': - user_str = src["name"] - user_ar = user_str.split('@') - user_name = user_ar[0] - user_uid = src["userGroup"] - user_typ = 'group' - user_comment = src['comments'] - user_color = src['color'] - else: - break - if user_comment == '': - user_comment = None - users.update({user_name: {'user_uid': user_uid, 'user_typ': user_typ, - 'user_comment': user_comment, 'user_color': user_color}}) - else: - logger.warning("found src user without type field: " + json.dumps(src)) - if 'name' in src and 'uid' in src: - users.update({src["name"]: {'user_uid': src["uid"], 'user_typ': 'simple'}}) - - else: # section - collect_users_from_rulebase(rule["rulebase"], users) - - -# collect_users writes user info into global users dict -def collect_users_from_rulebase(rulebase, users): - if 'layerchunks' in rulebase: - for chunk in rulebase['layerchunks']: - if 'rulebase' in chunk: - for rule in chunk['rulebase']: - collect_users_from_rule(rule, users) - else: - for rule in rulebase: - collect_users_from_rule(rule, users) - - -# the following is only used within new python-only importer: -def parse_user_objects_from_rulebase(rulebase, users, import_id): - collect_users_from_rulebase(rulebase, users) - for user_name in users.keys(): - users[user_name]['control_id'] = import_id diff --git a/roles/importer/files/importer/checkpointR8x/fwcommon.py b/roles/importer/files/importer/checkpointR8x/fwcommon.py deleted file mode 100644 index ac6a80db31..0000000000 --- a/roles/importer/files/importer/checkpointR8x/fwcommon.py +++ /dev/null @@ -1,227 +0,0 @@ -import sys -import json -import copy -from common import importer_base_dir -from fwo_log import getFwoLogger -sys.path.append(importer_base_dir + '/checkpointR8x') -import time -import fwo_globals -import cp_rule -import cp_const, cp_network, cp_service -import cp_getter -from cp_enrich import enrich_config -from fwo_exception import FwLoginFailed, FwLogoutFailed -from cp_user import parse_user_objects_from_rulebase - - -def has_config_changed (full_config, mgm_details, force=False): - - if full_config != {}: # a native config was passed in, so we assume that an import has to be done (simulating changes here) - return 1 - - domain, _ = prepare_get_vars(mgm_details) - - try: # top level dict start, sid contains the domain information, so only sending domain during login - session_id = login_cp(mgm_details, domain) - except: - raise FwLoginFailed # maybe 2Temporary failure in name resolution" - - last_change_time = '' - if 'import_controls' in mgm_details: - for importctl in mgm_details['import_controls']: - if 'starttime' in importctl: - last_change_time = importctl['starttime'] - - if last_change_time==None or last_change_time=='' or force: - # if no last import time found or given or if force flag is set, do full import - result = 1 - else: # otherwise search for any changes since last import - result = (cp_getter.get_changes(session_id, mgm_details['hostname'], str(mgm_details['port']),last_change_time) != 0) - - try: # top level dict start, sid contains the domain information, so only sending domain during login - logout_result = cp_getter.cp_api_call("https://" + mgm_details['hostname'] + ":" + str(mgm_details['port']) + "/web_api/", 'logout', {}, session_id) - except: - raise FwLogoutFailed # maybe temporary failure in name resolution" - return result - - -def get_config(config2import, full_config, current_import_id, mgm_details, limit=150, force=False, jwt=None): - logger = getFwoLogger() - if full_config == {}: # no native config was passed in, so getting it from FW-Manager - parsing_config_only = False - else: - parsing_config_only = True - - if not parsing_config_only: # get config from cp fw mgr - starttime = int(time.time()) - - if 'users' not in full_config: - full_config.update({'users': {}}) - - domain, base_url = prepare_get_vars(mgm_details) - - sid = login_cp(mgm_details, domain) - - result_get_rules = get_rules (full_config, mgm_details, base_url, sid, force=force, limit=str(limit), details_level=cp_const.details_level, test_version='off') - if result_get_rules>0: - return result_get_rules - - result_get_objects = get_objects (full_config, mgm_details, base_url, sid, force=force, limit=str(limit), details_level=cp_const.details_level, test_version='off') - if result_get_objects>0: - return result_get_objects - - result_enrich_config = enrich_config (full_config, mgm_details, limit=str(limit), details_level=cp_const.details_level, sid=sid) - - if result_enrich_config>0: - return result_enrich_config - - duration = int(time.time()) - starttime - logger.debug ( "checkpointR8x/get_config - duration: " + str(duration) + "s" ) - - cp_network.normalize_network_objects(full_config, config2import, current_import_id, mgm_id=mgm_details['id']) - cp_service.normalize_service_objects(full_config, config2import, current_import_id) - parse_users_from_rulebases(full_config, full_config['rulebases'], full_config['users'], config2import, current_import_id) - config2import.update({'rules': cp_rule.normalize_rulebases_top_level(full_config, current_import_id, config2import) }) - if not parsing_config_only: # get config from cp fw mgr - try: # logout - logout_result = cp_getter.cp_api_call("https://" + mgm_details['hostname'] + ":" + str(mgm_details['port']) + "/web_api/", 'logout', {}, sid) - except: - raise FwLogoutFailed # maybe emporary failure in name resolution" - return 0 - - -def prepare_get_vars(mgm_details): - - # from 5.8 onwards: preferably use domain uid instead of domain name due to CP R81 bug with certain installations - if mgm_details['domainUid'] != None: - domain = mgm_details['domainUid'] - else: - domain = mgm_details['configPath'] - api_host = mgm_details['hostname'] - api_user = mgm_details['import_credential']['user'] - if mgm_details['domainUid'] != None: - api_domain = mgm_details['domainUid'] - else: - api_domain = mgm_details['configPath'] - api_port = str(mgm_details['port']) - api_password = mgm_details['import_credential']['secret'] - base_url = 'https://' + api_host + ':' + str(api_port) + '/web_api/' - - return domain, base_url - - -def login_cp(mgm_details, domain, ssl_verification=True): - return cp_getter.login(mgm_details['import_credential']['user'], mgm_details['import_credential']['secret'], mgm_details['hostname'], str(mgm_details['port']), domain) - - -def get_rules (config_json, mgm_details, v_url, sid, force=False, config_filename=None, - limit=150, details_level=cp_const.details_level, test_version='off', debug_level=0, ssl_verification=True): - - logger = getFwoLogger() - config_json.update({'rulebases': [], 'nat_rulebases': [] }) - with_hits = True - show_params_rules = {'limit':limit,'use-object-dictionary':cp_const.use_object_dictionary,'details-level':cp_const.details_level, 'show-hits' : with_hits} - - # read all rulebases: handle per device details - for device in mgm_details['devices']: - if device['global_rulebase_name'] != None and device['global_rulebase_name']!='': - show_params_rules['name'] = device['global_rulebase_name'] - # get global layer rulebase - logger.debug ( "getting layer: " + show_params_rules['name'] ) - current_layer_json = cp_getter.get_layer_from_api_as_dict (v_url, sid, show_params_rules, layername=device['global_rulebase_name']) - if current_layer_json is None: - return 1 - # now also get domain rules - show_params_rules['name'] = device['local_rulebase_name'] - current_layer_json['layername'] = device['local_rulebase_name'] - logger.debug ( "getting domain rule layer: " + show_params_rules['name'] ) - domain_rules = cp_getter.get_layer_from_api_as_dict (v_url, sid, show_params_rules, layername=device['local_rulebase_name']) - if current_layer_json is None: - return 1 - - # now handling possible reference to domain rules within global rules - # if we find the reference, replace it with the domain rules - if 'layerchunks' in current_layer_json: - for chunk in current_layer_json["layerchunks"]: - for rule in chunk['rulebase']: - if "type" in rule and rule["type"] == "place-holder": - logger.debug ("found domain rules place-holder: " + str(rule) + "\n\n") - current_layer_json = cp_getter.insert_layer_after_place_holder(current_layer_json, domain_rules, rule['uid']) - else: # no global rules, just get local ones - show_params_rules['name'] = device['local_rulebase_name'] - logger.debug ( "getting layer: " + show_params_rules['name'] ) - current_layer_json = cp_getter.get_layer_from_api_as_dict (v_url, sid, show_params_rules, layername=device['local_rulebase_name']) - if current_layer_json is None: - return 1 - - config_json['rulebases'].append(current_layer_json) - - # getting NAT rules - need package name for nat rule retrieval - # todo: each gateway/layer should have its own package name (pass management details instead of single data?) - if device['package_name'] != None and device['package_name'] != '': - show_params_rules = {'limit':limit,'use-object-dictionary':cp_const.use_object_dictionary,'details-level':cp_const.details_level, 'package': device['package_name'] } - if debug_level>3: - logger.debug ( "getting nat rules for package: " + device['package_name'] ) - nat_rules = cp_getter.get_nat_rules_from_api_as_dict (v_url, sid, show_params_rules) - if len(nat_rules)>0: - config_json['nat_rulebases'].append(nat_rules) - else: - config_json['nat_rulebases'].append({ "nat_rule_chunks": [] }) - else: # always making sure we have an (even empty) nat rulebase per device - config_json['nat_rulebases'].append({ "nat_rule_chunks": [] }) - return 0 - - -def get_objects(config_json, mgm_details, v_url, sid, force=False, config_filename=None, - limit=150, details_level=cp_const.details_level, test_version='off', debug_level=0, ssl_verification=True): - - logger = getFwoLogger() - - config_json["object_tables"] = [] - show_params_objs = {'limit':limit,'details-level': cp_const.details_level} - - for obj_type in cp_const.api_obj_types: - object_table = { "object_type": obj_type, "object_chunks": [] } - current=0 - total=current+1 - show_cmd = 'show-' + obj_type - if debug_level>5: - logger.debug ( "obj_type: "+ obj_type ) - while (current5: - logger.debug ( obj_type +" current:"+ str(current) + " of a total " + str(total) ) - else : - current = total - if debug_level>5: - logger.debug ( obj_type +" total:"+ str(total) ) - config_json["object_tables"].append(object_table) - # logout_result = cp_getter.cp_api_call(v_url, 'logout', {}, sid) - - # only write config to file if config_filename is given - if config_filename != None and len(config_filename)>1: - with open(config_filename, "w") as configfile_json: - configfile_json.write(json.dumps(config_json)) - return 0 - - -def parse_users_from_rulebases (full_config, rulebase, users, config2import, current_import_id): - if 'users' not in full_config: - full_config.update({'users': {}}) - - rb_range = range(len(full_config['rulebases'])) - for rb_id in rb_range: - parse_user_objects_from_rulebase (full_config['rulebases'][rb_id], full_config['users'], current_import_id) - - # copy users from full_config to config2import - # also converting users from dict to array: - config2import.update({'user_objects': []}) - for user_name in full_config['users'].keys(): - user = copy.deepcopy(full_config['users'][user_name]) - user.update({'user_name': user_name}) - config2import['user_objects'].append(user) diff --git a/roles/importer/files/importer/ciscofirepowerdomain7ff/cifp_getter.py b/roles/importer/files/importer/ciscofirepowerdomain7ff/cifp_getter.py deleted file mode 100644 index 93853aaa56..0000000000 --- a/roles/importer/files/importer/ciscofirepowerdomain7ff/cifp_getter.py +++ /dev/null @@ -1,96 +0,0 @@ -# library for API get functions -import base64 -from typing import Dict -from fwo_log import getFwoLogger -import requests.packages -import requests -import json -import fwo_globals -from fwo_exception import FwLoginFailed - -auth_token = "" - -def api_call(url, params = {}, headers = {}, json_payload = {}, auth_token = '', show_progress=False, method='get'): - logger = getFwoLogger() - request_headers = {'Content-Type': 'application/json'} - for header_key in headers: - request_headers[header_key] = headers[header_key] - if auth_token != '': - request_headers["X-auth-access-token"] = auth_token - - if method == "post": - response = requests.post(url, params=params, data=json.dumps(json_payload), headers=request_headers, - verify=fwo_globals.verify_certs) - elif method == "get": - response = requests.get(url, params=params, data=json.dumps(json_payload), headers=request_headers, - verify=fwo_globals.verify_certs) - else: - raise Exception("unknown HTTP method found in cifp_getter") - - if response is None: - if 'pass' in json.dumps(json_payload): - exception_text = "error while sending api_call containing credential information to url '" + \ - str(url) - else: - exception_text = "error while sending api_call to url '" + str(url) + "' with payload '" + json.dumps( - json_payload, indent=2) + "' and headers: '" + json.dumps(request_headers, indent=2) - raise Exception(exception_text) - if (len(response.content) > 0): - body_json = response.json() - else: - body_json = {} - - if fwo_globals.debug_level > 2: - if 'pass' in json.dumps(json_payload): - logger.debug("api_call containing credential information to url '" + - str(url) + " - not logging query") - else: - logger.debug("api_call to url '" + str(url) + "' with payload '" + json.dumps( - json_payload, indent=2) + "' and headers: '" + json.dumps(request_headers, indent=2)) - - if show_progress: - print('.', end='', flush=True) - return response.headers, body_json - -def login(user, password, api_host, api_port): - base_url = 'https://' + api_host + ':' + str(api_port) + '/api/' - try: - headers, _ = api_call(base_url + "fmc_platform/v1/auth/generatetoken", method="post", headers={"Authorization" : "Basic " + str(base64.b64encode((user + ":" + password).encode('utf-8')), 'utf-8')}) - except Exception as e: - raise FwLoginFailed( - "Cisco Firepower login ERROR: host=" + str(api_host) + ":" + str(api_port) + " Message: " + str(e)) from None - if headers.get("X-auth-access-token") == None: # leaving out payload as it contains pwd - raise FwLoginFailed( - "Cisco Firepower login ERROR: host=" + str(api_host) + ":" + str(api_port)) from None - if fwo_globals.debug_level > 2: - logger = getFwoLogger() - logger.debug("Login successful. Received auth token: " + headers["X-auth-access-token"]) - return headers.get("X-auth-access-token"), headers.get("DOMAINS") - -# TODO Is there an logout? -def logout(v_url, sid, method='exec'): - return - # logger = getFwoLogger() - # payload = {"params": [{}]} - - # response = api_call(v_url, 'sys/logout', payload, sid, method=method) - # if "result" in response and "status" in response["result"][0] and "code" in response["result"][0]["status"] and response["result"][0]["status"]["code"] == 0: - # logger.debug("successfully logged out") - # else: - # raise Exception("cifp_getter ERROR: did not get status code 0 when logging out, " + - # "api call: url: " + str(v_url) + ", + payload: " + str(payload)) - -def update_config_with_cisco_api_call(session_id, api_base_url, api_path, parameters={}, payload={}, show_progress=False, limit: int=1000, method="get"): - offset = 0 - limit = 1000 - returned_new_data = True - full_result = [] - while returned_new_data: - parameters["offset"] = offset - parameters["limit"] = limit - result = api_call(api_base_url + "/" + api_path, auth_token=session_id, params=parameters, json_payload=payload, show_progress=show_progress, method=method)[1] - returned_new_data = result["paging"]["count"] > 0 - if returned_new_data: - full_result.extend(result["items"]) - offset += limit - return full_result \ No newline at end of file diff --git a/roles/importer/files/importer/ciscofirepowerdomain7ff/cifp_network.py b/roles/importer/files/importer/ciscofirepowerdomain7ff/cifp_network.py deleted file mode 100644 index a78b47d87f..0000000000 --- a/roles/importer/files/importer/ciscofirepowerdomain7ff/cifp_network.py +++ /dev/null @@ -1,103 +0,0 @@ -from asyncio.log import logger -import random - -from fwo_log import getFwoLogger -from fwo_const import list_delimiter -from netaddr import IPAddress - -def normalize_nwobjects(full_config, config2import, import_id, jwt=None, mgm_id=None): - logger = getFwoLogger() - nw_objects = [] - for obj_orig in full_config["networkObjects"]: - nw_objects.append(parse_object(obj_orig, import_id)) - for obj_grp_orig in full_config["networkObjectGroups"]: - obj_grp = extract_base_object_infos(obj_grp_orig, import_id) - obj_grp["obj_typ"] = "group" - obj_grp["obj_member_refs"], obj_grp["obj_member_names"] = parse_obj_group(obj_grp_orig, import_id, nw_objects) - nw_objects.append(obj_grp) - config2import['network_objects'] = nw_objects - -def parse_obj_group(orig_grp, import_id, nw_objects, id = None): - refs = [] - names = [] - if "literals" in orig_grp: - if id == None: - id = orig_grp["id"] if "id" in orig_grp else random.random() - for orig_literal in orig_grp["literals"]: - literal = parse_object(orig_literal, import_id) - literal["obj_uid"] += "_" + str(id) - nw_objects.append(literal) - names.append(orig_literal["value"]) - refs.append(literal["obj_uid"]) - if "objects" in orig_grp: - for orig_obj in orig_grp["objects"]: - if "type" in orig_obj: - if (orig_obj["type"] != "NetworkGroup" and orig_obj["type"] != "Host" and - orig_obj["type"] != "Network" and orig_obj["type"] != "Range" and - orig_obj["type"] != "FQDN"): - logger = getFwoLogger() - logger.warn("Unknown network object type found: \"" + orig_obj["type"] + "\". Skipping.") - break - names.append(orig_obj["name"]) - refs.append(orig_obj["id"]) - - return list_delimiter.join(refs), list_delimiter.join(names) - -def extract_base_object_infos(obj_orig, import_id): - logger = getFwoLogger() - obj = {} - if "id" in obj_orig: - obj["obj_uid"] = obj_orig['id'] - else: - obj["obj_uid"] = obj_orig["value"] - if "name" in obj_orig: - obj["obj_name"] = obj_orig["name"] - else: - obj["obj_name"] = obj_orig["value"] - if 'description' in obj_orig: - obj["obj_comment"] = obj_orig["description"] - if 'color' in obj_orig: - # TODO Do colors exist? - logger.debug("colors exist :)") - obj['control_id'] = import_id - return obj - -def parse_object(obj_orig, import_id): - obj = extract_base_object_infos(obj_orig, import_id) - if obj_orig["type"] == "Network": # network - obj["obj_typ"] = "network" - if "value" in obj_orig: - cidr = obj_orig["value"].split("/") - if str.isdigit(cidr[1]): - obj['obj_ip'] = cidr[0] + "/" + cidr[1] - else: # not real cidr (netmask after /) - obj['obj_ip'] = cidr[0] + "/" + str(IPAddress(cidr[1]).netmask_bits()) - else: - logger.warn("missing value field in object - skipping: " + str(obj_orig)) - obj['obj_ip'] = "0.0.0.0" - elif obj_orig["type"] == "Host": # host - obj["obj_typ"] = "host" - if "value" in obj_orig: - obj["obj_ip"] = obj_orig["value"] - if obj_orig["value"].find(":") != -1: # ipv6 - if obj_orig["value"].find("/") == -1: - obj["obj_ip"] += "/128" - else: # ipv4 - if obj_orig["value"].find("/") == -1: - obj["obj_ip"] += "/32" - else: - logger.warn("missing value field in object - skipping: " + str(obj_orig)) - obj['obj_ip'] = "0.0.0.0/0" - elif obj_orig["type"] == "Range": # ip range - obj['obj_typ'] = 'ip_range' - ip_range = obj_orig['value'].split("-") - obj['obj_ip'] = ip_range[0] - obj['obj_ip_end'] = ip_range[1] - elif obj_orig["type"] == "FQDN": # fully qualified domain name - obj['obj_typ'] = 'network' - obj['obj_ip'] = "0.0.0.0/0" - else: # unknown type - obj["obj_name"] = obj["obj_name"] + " [not supported]" - obj['obj_typ'] = 'network' - obj['obj_ip'] = "0.0.0.0/0" - return obj diff --git a/roles/importer/files/importer/ciscofirepowerdomain7ff/cifp_rule.py b/roles/importer/files/importer/ciscofirepowerdomain7ff/cifp_rule.py deleted file mode 100644 index f2e64a4909..0000000000 --- a/roles/importer/files/importer/ciscofirepowerdomain7ff/cifp_rule.py +++ /dev/null @@ -1,85 +0,0 @@ - -from cifp_service import parse_svc_group -from cifp_network import parse_obj_group -import cifp_getter -from fwo_log import getFwoLogger - -rule_access_scope_v4 = ['rules_global_header_v4', - 'rules_adom_v4', 'rules_global_footer_v4'] -rule_access_scope_v6 = ['rules_global_header_v6', - 'rules_adom_v6', 'rules_global_footer_v6'] -rule_access_scope = rule_access_scope_v6 + rule_access_scope_v4 -rule_nat_scope = ['rules_global_nat', 'rules_adom_nat'] -rule_scope = rule_access_scope + rule_nat_scope - -def getAccessPolicy(sessionId, api_url, config, device, limit): - access_policy = device["accessPolicy"]["id"] - domain = device["domain"] - logger = getFwoLogger() - - device["rules"] = cifp_getter.update_config_with_cisco_api_call(sessionId, api_url, - "fmc_config/v1/domain/" + domain + "/policy/accesspolicies/" + access_policy + "/accessrules", parameters={"expanded": True}, limit=limit) - - return - -def normalize_access_rules(full_config, config2import, import_id, mgm_details={}, jwt=None): - any_nw_svc = {"svc_uid": "any_svc_placeholder", "svc_name": "Any", "svc_comment": "Placeholder service.", - "svc_typ": "simple", "ip_proto": -1, "svc_port": 0, "svc_port_end": 65535, "control_id": import_id} - any_nw_object = {"obj_uid": "any_obj_placeholder", "obj_name": "Any", "obj_comment": "Placeholder object.", - "obj_typ": "network", "obj_ip": "0.0.0.0/0", "control_id": import_id} - config2import["service_objects"].append(any_nw_svc) - config2import["network_objects"].append(any_nw_object) - - rules = [] - for device in full_config["devices"]: - access_policy = device["accessPolicy"] - rule_number = 0 - for rule_orig in device["rules"]: - rule = {'rule_src': 'any', 'rule_dst': 'any', 'rule_svc': 'any', - 'rule_src_refs': 'any_obj_placeholder', 'rule_dst_refs': 'any_obj_placeholder', - 'rule_svc_refs': 'any_svc_placeholder'} - rule['control_id'] = import_id - rule['rulebase_name'] = access_policy["name"] - rule["rule_uid"] = rule_orig["id"] - rule["rule_name"] = rule_orig["name"] - rule['rule_type'] = "access" - rule['rule_num'] = rule_number - rule['rule_installon'] = None - rule['parent_rule_id'] = None - rule['rule_time'] = None - rule['rule_implied'] = False - - if 'description' in rule_orig: - rule['rule_comment'] = rule_orig['description'] - else: - rule["rule_comment"] = None - if rule_orig["action"] == "ALLOW": - rule["rule_action"] = "Accept" - elif rule_orig["action"] == "BLOCK": - rule["rule_action"] = "Drop" - elif rule_orig["action"] == "TRUST": - rule["rule_action"] = "Accept" #TODO More specific? - elif rule_orig["action"] == "MONITOR": - continue #TODO No access rule (just tracking and logging) - if rule_orig["enableSyslog"]: - rule["rule_track"] = "Log" - else: - rule["rule_track"] = "None" - rule["rule_disabled"] = not rule_orig["enabled"] - - if "sourceNetworks" in rule_orig: - rule['rule_src_refs'], rule["rule_src"] = parse_obj_group(rule_orig["sourceNetworks"], import_id, config2import['network_objects'], rule["rule_uid"]) - if "destinationNetworks" in rule_orig: - rule['rule_dst_refs'], rule["rule_dst"] = parse_obj_group(rule_orig["destinationNetworks"], import_id, config2import['network_objects'], rule["rule_uid"]) - # TODO source ports - if "destinationPorts" in rule_orig: - rule["rule_svc_refs"], rule["rule_svc"] = parse_svc_group(rule_orig["destinationPorts"], import_id, config2import['service_objects'], rule["rule_uid"]) - - rule["rule_src_neg"] = False - rule["rule_dst_neg"] = False - rule["rule_svc_neg"] = False - - rule_number += 1 - rules.append(rule) - - config2import['rules'] = rules diff --git a/roles/importer/files/importer/ciscofirepowerdomain7ff/cifp_service.py b/roles/importer/files/importer/ciscofirepowerdomain7ff/cifp_service.py deleted file mode 100644 index 6245ae2241..0000000000 --- a/roles/importer/files/importer/ciscofirepowerdomain7ff/cifp_service.py +++ /dev/null @@ -1,86 +0,0 @@ -import random -from fwo_const import list_delimiter - - -def normalize_svcobjects(full_config, config2import, import_id): - svc_objects = [] - for svc_orig in full_config["serviceObjects"]: - svc_objects.append(parse_svc(svc_orig, import_id)) - for svc_grp_orig in full_config["serviceObjectGroups"]: - svc_grp = extract_base_svc_infos(svc_grp_orig, import_id) - svc_grp["svc_typ"] = "group" - svc_grp["svc_member_refs"] , svc_grp["svc_member_names"] = parse_svc_group(svc_grp_orig, import_id, svc_objects) - svc_objects.append(svc_grp) - config2import['service_objects'] = svc_objects - -def extract_base_svc_infos(svc_orig, import_id): - svc = {} - if "id" in svc_orig: - svc["svc_uid"] = svc_orig["id"] - else: - svc["svc_uid"] = svc_orig["protocol"] - if "port" in svc_orig: - svc["svc_uid"] += "_" + svc_orig["port"] - if "name" in svc_orig: - svc["svc_name"] = svc_orig["name"] - else: - svc["svc_name"] = svc_orig["protocol"] - if "port" in svc_orig: - svc["svc_name"] += "_" + svc_orig["port"] - if "svc_comment" in svc_orig: - svc["svc_comment"] = svc_orig["comment"] - svc["svc_timeout"] = None - svc["svc_color"] = None - svc["control_id"] = import_id - return svc - -def parse_svc(orig_svc, import_id): - svc = extract_base_svc_infos(orig_svc, import_id) - svc["svc_typ"] = "simple" - parse_port(orig_svc, svc) - if orig_svc["type"] == "ProtocolPortObject": - if orig_svc["protocol"] == "TCP": - svc["ip_proto"] = 6 - elif orig_svc["protocol"] == "UDP": - svc["ip_proto"] = 17 - elif orig_svc["protocol"] == "ESP": - svc["ip_proto"] = 50 - else: - svc["svc_name"] += " [Protocol \"" + orig_svc["protocol"] + "\" not supported]" - # TODO Icmp - # TODO add all protocols - elif orig_svc["type"] == "PortLiteral": - svc["ip_proto"] = orig_svc["protocol"] - else: - svc["svc_name"] += " [Not supported]" - return svc - -def parse_port(orig_svc, svc): - if "port" in orig_svc: - if orig_svc["port"].find("-") != -1: # port range - port_range = orig_svc["port"].split("-") - svc["svc_port"] = port_range[0] - svc["svc_port_end"] = port_range[1] - else: # single port - svc["svc_port"] = orig_svc["port"] - svc["svc_port_end"] = None - -def parse_svc_group(orig_svc_grp, import_id, svc_objects, id = None): - refs = [] - names = [] - - if "literals" in orig_svc_grp: - if id == None: - id = orig_svc_grp["id"] if "id" in orig_svc_grp else random.random() - for orig_literal in orig_svc_grp["literals"]: - literal = parse_svc(orig_literal, import_id) - literal["svc_uid"] += "_" + id - svc_objects.append(literal) - names.append(literal["svc_name"]) - refs.append(literal["svc_uid"]) - if "objects" in orig_svc_grp: - for svc_orig in orig_svc_grp["objects"]: - refs.append(svc_orig["id"]) - names.append(svc_orig["name"]) - return list_delimiter.join(refs), list_delimiter.join(names) - \ No newline at end of file diff --git a/roles/importer/files/importer/ciscofirepowerdomain7ff/discovery_logging.conf b/roles/importer/files/importer/ciscofirepowerdomain7ff/discovery_logging.conf deleted file mode 100644 index 139c55a9cb..0000000000 --- a/roles/importer/files/importer/ciscofirepowerdomain7ff/discovery_logging.conf +++ /dev/null @@ -1,41 +0,0 @@ -[loggers] -keys=root,discoveryDebugLogger -#keys=root,__main__ - -[handlers] -keys=consoleHandler,debugFileHandler - -[formatters] -keys=defaultFormatter,debugFileFormatter - -[logger_root] -level=DEBUG -handlers=consoleHandler - -[logger_discoveryDebugLogger] -#[logger___main__] -level=DEBUG -handlers=debugFileHandler -qualname=discoveryDebugLogger -#qualname=__main__ -propagate=0 - -[handler_consoleHandler] -class=StreamHandler -level=DEBUG -formatter=defaultFormatter -args=(sys.stderr,) - -[handler_debugFileHandler] -class=FileHandler -level=DEBUG -formatter=debugFileFormatter -args=('/tmp/fworch_discovery.log',) -# args=('/var/log/fworch/discovery.log',) - -[formatter_defaultFormatter] -format=%(levelname)s:%(name)s:%(message)s - -[formatter_debugFileFormatter] -format=%(asctime)s - %(name)s - %(levelname)s - %(message)s - diff --git a/roles/importer/files/importer/ciscofirepowerdomain7ff/fwcommon.py b/roles/importer/files/importer/ciscofirepowerdomain7ff/fwcommon.py deleted file mode 100644 index 3b6a8921f9..0000000000 --- a/roles/importer/files/importer/ciscofirepowerdomain7ff/fwcommon.py +++ /dev/null @@ -1,147 +0,0 @@ -import sys -from common import importer_base_dir -sys.path.append(importer_base_dir + '/ciscofirepowerdomain7ff') -import cifp_service -import cifp_rule -import cifp_network -import cifp_getter -import json -from fwo_log import getFwoLogger - - -def has_config_changed(full_config, mgm_details, force=False): - # dummy - may be filled with real check later on - return True - - -def get_config(config2import, full_config, current_import_id, mgm_details, limit=1000, force=False, jwt=''): - logger = getFwoLogger() - if full_config == {}: # no native config was passed in, so getting it from Cisco Management - parsing_config_only = False - else: - parsing_config_only = True - - if not parsing_config_only: # no native config was passed in, so getting it from Cisco Management - cisco_api_url = 'https://' + \ - mgm_details['hostname'] + ':' + \ - str(mgm_details['port']) + '/api' - sessionId, domains = cifp_getter.login(mgm_details["import_credential"]['user'], mgm_details["import_credential"]['secret'], - mgm_details['hostname'], mgm_details['port']) - domain = mgm_details["configPath"] - if sessionId == None or sessionId == "": - logger.error( - 'Did not succeed in logging in to Cisco Firepower API, no sid returned.') - return 1 - if domain == None or domain == "": - logger.error( - 'Configured domain is null or empty.') - return 1 - scopes = getScopes(domain, json.loads(domains)) - if len(scopes) == 0: - logger.error( - "Domain \"" + domain + "\" could not be found. \"" + domain + "\" does not appear to be a domain name or a domain UID.") - return 1 - - getDevices(sessionId, cisco_api_url, full_config, limit, scopes, mgm_details["devices"]) - getObjects(sessionId, cisco_api_url, full_config, limit, scopes) - - for device in full_config["devices"]: - cifp_rule.getAccessPolicy(sessionId, cisco_api_url, full_config, device, limit) - ##cifp_rule.getNatPolicy(sessionId, cisco_api_url, full_config, domain, device, limit) TODO - - try: # logout - cifp_getter.logout(cisco_api_url, sessionId) - except: - logger.warning( - "logout exception probably due to timeout - irrelevant, so ignoring it") - - # now we normalize relevant parts of the raw config and write the results to config2import dict - - # write normalized networking data to config2import - # this is currently not written to the database but only used for natting decisions - # later we will probably store the networking info in the database as well as a basis - # for path analysis - - # normalize_network_data(full_config, config2import, mgm_details) - - # cifp_user.normalize_users( - # full_config, config2import, current_import_id, user_scope) - cifp_network.normalize_nwobjects( - full_config, config2import, current_import_id, jwt=jwt, mgm_id=mgm_details['id']) - cifp_service.normalize_svcobjects( - full_config, config2import, current_import_id) - cifp_rule.normalize_access_rules( - full_config, config2import, current_import_id, mgm_details=mgm_details, jwt=jwt) - # cifp_rule.normalize_nat_rules( - # full_config, config2import, current_import_id, jwt=jwt) - # cifp_network.remove_nat_ip_entries(config2import) - return 0 - -def getAllAccessRules(sessionId, api_url, domains): - for domain in domains: - domain["access_policies"] = cifp_getter.update_config_with_cisco_api_call(sessionId, api_url, - "fmc_config/v1/domain/" + domain["uuid"] + "/policy/accesspolicies" , parameters={"expanded": True}, limit=1000) - - for access_policy in domain["access_policies"]: - access_policy["rules"] = cifp_getter.update_config_with_cisco_api_call(sessionId, api_url, - "fmc_config/v1/domain/" + domain["uuid"] + "/policy/accesspolicies/" + access_policy["id"] + "/accessrules", parameters={"expanded": True}, limit=1000) - return domains - -def getScopes(searchDomain, domains): - scopes = [] - for domain in domains: - if domain == domain["uuid"] or domain["name"].endswith(searchDomain): - scopes.append(domain["uuid"]) - return scopes - -def getDevices(sessionId, api_url, config, limit, scopes, devices): - logger = getFwoLogger() - # get all devices - for scope in scopes: - config["devices"] = cifp_getter.update_config_with_cisco_api_call(sessionId, api_url, - "fmc_config/v1/domain/" + scope + "/devices/devicerecords", parameters={"expanded": True}, limit=limit) - for device in config["devices"]: - if not "domain" in device: - device["domain"] = scope - # filter for existent devices - for cisco_api_device in config["devices"]: - found = False - for device in devices: - if device["name"] == cisco_api_device["name"] or device["name"] == cisco_api_device["id"]: - found = True - break - # remove device if not in fwo api - if found == False: - config["devices"].remove(cisco_api_device) - logger.info("Device \"" + cisco_api_device["name"] + "\" was found but it is not registered in FWO. Ignoring it.") - -def getObjects(sessionId, api_url, config, limit, scopes): - # network objects: - config["networkObjects"] = [] - config["networkObjectGroups"] = [] - # service objects: - config["serviceObjects"] = [] - config["serviceObjectGroups"] = [] - # user objects: - config["userObjects"] = [] - config["userObjectGroups"] = [] - - # get those objects that exist globally and on domain level - for scope in scopes: - # get network objects (groups): - # for object_type in nw_obj_types: - config["networkObjects"].extend(cifp_getter.update_config_with_cisco_api_call(sessionId, api_url, - "fmc_config/v1/domain/" + scope + "/object/networkaddresses", parameters={"expanded": True}, limit=limit)) - config["networkObjectGroups"].extend(cifp_getter.update_config_with_cisco_api_call(sessionId, api_url, - "fmc_config/v1/domain/" + scope + "/object/networkgroups", parameters={"expanded": True}, limit=limit)) - # get service objects: - # for object_type in svc_obj_types: - config["serviceObjects"].extend(cifp_getter.update_config_with_cisco_api_call(sessionId, api_url, - "fmc_config/v1/domain/" + scope + "/object/ports", parameters={"expanded": True}, limit=limit)) - config["serviceObjectGroups"].extend(cifp_getter.update_config_with_cisco_api_call(sessionId, api_url, - "fmc_config/v1/domain/" + scope + "/object/portobjectgroups", parameters={"expanded": True}, limit=limit)) - # get user objects: - config["userObjects"].extend(cifp_getter.update_config_with_cisco_api_call(sessionId, api_url, - "fmc_config/v1/domain/" + scope + "/object/realmusers", parameters={"expanded": True}, limit=limit)) - config["userObjectGroups"].extend(cifp_getter.update_config_with_cisco_api_call(sessionId, api_url, - "fmc_config/v1/domain/" + scope + "/object/realmusergroups", parameters={"expanded": True}, limit=limit)) diff --git a/roles/importer/files/importer/common.py b/roles/importer/files/importer/common.py index ba9ae768db..9d0f5e8a5b 100644 --- a/roles/importer/files/importer/common.py +++ b/roles/importer/files/importer/common.py @@ -1,370 +1,359 @@ +import sys +import time import traceback -import sys, time, datetime -import json, requests, requests.packages -from socket import gethostname -import importlib.util -from fwo_const import importer_base_dir from pathlib import Path -sys.path.append(importer_base_dir) # adding absolute path here once -import fwo_api -from fwo_log import getFwoLogger -from fwo_config import readConfig -from fwo_const import fw_module_name, full_config_size_limit -from fwo_const import fwo_config_filename, importer_pwd_file, importer_user_name, import_tmp_path -import fwo_globals -import jsonpickle -from fwo_exception import FwoApiLoginFailed, FwoApiFailedLockImport, ConfigFileNotFound, FwLoginFailed, ImportRecursionLimitReached -from fwo_base import split_config -from fwo_mail import send_change_notification_mail - -# import_management: import a single management (if no import for it is running) -# lock mgmt for import via FWORCH API call, generating new import_id y -# check if we need to import (no md5, api call if anything has changed since last import) -# get complete config (get, enrich, parse) -# write into json dict write json dict to new table (single entry for complete config) -# trigger import from json into csv and from there into destination tables -# release mgmt for import via FWORCH API call (also removing import_id y data from import_tables?) -# no changes: remove import_control? -def import_management(mgm_id=None, ssl_verification=None, debug_level_in=0, - limit=150, force=False, clearManagementData=False, suppress_cert_warnings_in=None, - in_file=None, normalized_in_file=None): - - check_input_parameters(mgm_id=mgm_id, ssl_verification=ssl_verification, debug_level_in=debug_level_in, - limit=limit, force=force, clearManagementData=clearManagementData, suppress_cert_warnings_in=suppress_cert_warnings_in, - in_file=in_file, normalized_in_file=normalized_in_file) - - error_count = 0 - change_count = 0 - error_string = '' - start_time = int(time.time()) - debug_level=int(debug_level_in) - config2import = { "network_objects": [], "service_objects": [], "user_objects": [], "zone_objects": [], "rules": [] } - config_changed_since_last_import = True - - logger = getFwoLogger() +from socket import gethostname - fwo_config = readConfig(fwo_config_filename) +from fw_modules.checkpointR8x.fwcommon import CheckpointR8xCommon +from fw_modules.ciscoasa9.fwcommon import CiscoAsa9Common +from fw_modules.fortiadom5ff.fwcommon import FortiAdom5ffCommon +from fw_modules.fortiosmanagementREST.fwcommon import FortiosManagementRESTCommon +from fwo_const import IMPORTER_BASE_DIR +from fwo_log import FWOLogger +from model_controllers.fwconfig_import_rollback import FwConfigImportRollback +from model_controllers.management_controller import ManagementController +from models.fw_common import FwCommon +from models.import_state import ImportState + +if IMPORTER_BASE_DIR not in sys.path: + sys.path.append(IMPORTER_BASE_DIR) # adding absolute path here once +import fwo_file_import +import fwo_globals +import fwo_signalling +from fwo_api_call import FwoApiCall +from fwo_base import string_is_uri, write_native_config_to_file +from fwo_const import IMPORT_TMP_PATH +from fwo_exceptions import ( + FwLoginFailedError, + FwoApiWriteError, + FwoImporterError, + FwoImporterErrorInconsistenciesError, + ImportInterruptionError, + ImportRecursionLimitReachedError, + ShutdownRequestedError, +) +from model_controllers.check_consistency import FwConfigImportCheckConsistency +from model_controllers.fwconfig_import import FwConfigImport +from model_controllers.fwconfigmanagerlist_controller import ( + FwConfigManagerListController, +) +from model_controllers.import_state_controller import ImportStateController +from models.gateway import Gateway +from services.enums import Services +from services.service_provider import ServiceProvider + +""" + import_management: import a single management (if no import for it is running) + if mgmId is that of a super management, it will import all submanagements as well + lock mgmt for import via FWORCH API call, generating new import_id + check if we need to import (no md5, api call if anything has changed since last import) + get complete config (get, enrich, parse) + write into json dict write json dict to new table (single entry for complete config) + this top level function mainly deals with exception handling + + expects service_provider to be initialized +""" + + +def import_management( + mgm_id: int, + api_call: FwoApiCall, + ssl_verification: bool, + limit: int, + clear_management_data: bool, + suppress_cert_warnings: bool, + file: str | None = None, + suppress_consistency_check: bool = False, +) -> None: + fwo_signalling.register_signalling_handlers() + service_provider = ServiceProvider() + import_state = service_provider.get_global_state().import_state + config_importer = FwConfigImport() + exception: BaseException | None = None - # authenticate to get JWT - with open(importer_pwd_file, 'r') as file: - importer_pwd = file.read().replace('\n', '') try: - jwt = fwo_api.login(importer_user_name, importer_pwd, fwo_config['user_management_api_base_url']) - except FwoApiLoginFailed as e: - logger.error(e.message) - return e.message - except: - return "unspecified error during FWO API login" - - # set global https connection values - fwo_globals.setGlobalValues (suppress_cert_warnings_in=suppress_cert_warnings_in, verify_certs_in=ssl_verification, debug_level_in=debug_level_in) - if fwo_globals.verify_certs is None: # not defined via parameter - fwo_globals.verify_certs = fwo_api.get_config_value(fwo_config['fwo_api_base_url'], jwt, key='importCheckCertificates')=='True' - if fwo_globals.suppress_cert_warnings is None: # not defined via parameter - fwo_globals.suppress_cert_warnings = fwo_api.get_config_value(fwo_config['fwo_api_base_url'], jwt, key='importSuppressCertificateWarnings')=='True' - if fwo_globals.suppress_cert_warnings: # not defined via parameter - requests.packages.urllib3.disable_warnings() # suppress ssl warnings only - - try: # get mgm_details (fw-type, port, ip, user credentials): - mgm_details = fwo_api.get_mgm_details(fwo_config['fwo_api_base_url'], jwt, {"mgmId": int(mgm_id)}, debug_level) - except: - logger.error("import_management - error while getting fw management details for mgm=" + str(mgm_id) ) + _import_management( + mgm_id, + ssl_verification, + file, + limit, + clear_management_data, + suppress_cert_warnings, + suppress_consistency_check, + ) + except FwLoginFailedError as e: + exception = e + import_state.delete_import() # delete whole import + roll_back_exception_handler(import_state, config_importer=config_importer, exc=e, error_text="") + except ( + ImportRecursionLimitReachedError, + FwoImporterErrorInconsistenciesError, + ) as e: + import_state.delete_import() # delete whole import + exception = e + except (KeyboardInterrupt, ImportInterruptionError, ShutdownRequestedError) as e: + roll_back_exception_handler( + import_state, + config_importer=config_importer, + exc=e, + error_text="shutdown requested", + ) raise - - if mgm_details['importDisabled']: - logger.info("import_management - import disabled for mgm " + str(mgm_id)) + except (FwoApiWriteError, FwoImporterError) as e: + exception = e + roll_back_exception_handler(import_state, config_importer=config_importer, exc=e, error_text="") + except Exception as e: + exception = e + handle_unexpected_exception(import_state=import_state, config_importer=config_importer, e=e) + finally: + try: + api_call.complete_import(import_state.state, exception) + ServiceProvider().dispose_service(Services.UID2ID_MAPPER, import_state.state.import_id) + except Exception as e: + FWOLogger.error(f"Error during import completion: {e!s}") + + +def _import_management( + mgm_id: int, + ssl_verification: bool, + file: str | None, + limit: int, + clear_management_data: bool, + suppress_cert_warnings: bool, + suppress_consistency_check: bool, +) -> None: + config_normalized: FwConfigManagerListController + + config_changed_since_last_import = True + service_provider = ServiceProvider() + import_state = service_provider.get_global_state().import_state + config_importer = FwConfigImport() + FWOLogger.debug(f"import_management - ssl_verification: {ssl_verification}", 9) + FWOLogger.debug(f"import_management - suppress_cert_warnings_in: {suppress_cert_warnings}", 9) + FWOLogger.debug(f"import_management - limit: {limit}", 9) + + if import_state.state.mgm_details.import_disabled and not import_state.state.force_import: + FWOLogger.info(f"import_management - import disabled for mgm {mgm_id!s} - skipping") + return + + if import_state.state.mgm_details.importer_hostname != gethostname() and not import_state.state.force_import: + FWOLogger.info( + f"import_management - this host ({gethostname()}) is not responsible for importing management {mgm_id!s}" + ) + import_state.state.responsible_for_importing = False + return + + Path(IMPORT_TMP_PATH).mkdir(parents=True, exist_ok=True) # make sure tmp path exists + gateways = ManagementController.build_gateway_list(import_state.state.mgm_details) + + import_state.state.import_id = import_state.api_call.set_import_lock( + import_state.state.mgm_details, + import_state.state.is_initial_import, + ) + FWOLogger.info( + f"starting import of management {import_state.state.mgm_details.name} ({mgm_id!s}), import_id={import_state.state.import_id!s}" + ) + + if clear_management_data: + config_normalized = config_importer.clear_management() else: - Path(import_tmp_path).mkdir(parents=True, exist_ok=True) # make sure tmp path exists - package_list = [] - for dev in mgm_details['devices']: - package_list.append(dev['package_name']) - - # only run if this is the correct import module - if mgm_details['importerHostname'] != gethostname() and not force: - logger.info("import_management - this host (" + gethostname() + ") is not responsible for importing management " + str(mgm_id)) - return "" - - current_import_id = -1 - - try: # set import lock - current_import_id = fwo_api.lock_import(fwo_config['fwo_api_base_url'], jwt, {"mgmId": int(mgm_id)}) - except: - logger.error("import_management - failed to get import lock for management id " + str(mgm_id)) - if current_import_id == -1: - fwo_api.create_data_issue(fwo_config['fwo_api_base_url'], jwt, mgm_id=int(mgm_id), severity=1, - description="failed to get import lock for management id " + str(mgm_id)) - fwo_api.setAlert(fwo_config['fwo_api_base_url'], jwt, import_id=current_import_id, title="import error", mgm_id=str(mgm_id), severity=1, role='importer', \ - description="fwo_api: failed to get import lock", source='import', alertCode=15, mgm_details=mgm_details) - raise FwoApiFailedLockImport("fwo_api: failed to get import lock for management id " + str(mgm_id)) from None - - logger.info("starting import of management " + mgm_details['name'] + '(' + str(mgm_id) + "), import_id=" + str(current_import_id)) - full_config_json = {} - - if clearManagementData: - logger.info('this import run will reset the configuration of this management to "empty"') + # get config + config_changed_since_last_import, config_normalized = get_config_top_level(import_state, file, gateways) + + # write normalized config to file + config_normalized.store_full_normalized_config_to_file(import_state.state) + FWOLogger.debug( + "import_management - getting config total duration " + + str(int(time.time()) - import_state.state.start_time) + + "s" + ) + + # check config consistency and import it + if config_changed_since_last_import or import_state.state.force_import: + if not suppress_consistency_check: + FwConfigImportCheckConsistency(import_state.state).check_fwconfig_managerlist_consistency(config_normalized) + config_importer.import_management_set(service_provider, config_normalized) + + # delete data that has passed the retention time + # TODO: replace by deletion of old data with removed date > retention? + if ( + not clear_management_data + and import_state.state.data_retention_days < import_state.state.days_since_last_full_import + ): + config_importer.delete_old_imports() # delete all imports of the current management before the last but one full import + + +def handle_unexpected_exception( + import_state: ImportStateController | None = None, + config_importer: FwConfigImport | None = None, + e: Exception | None = None, +): + if import_state is not None and config_importer is not None: + roll_back_exception_handler(import_state, config_importer=config_importer, exc=e) + + +def roll_back_exception_handler( + import_state: ImportStateController, + config_importer: FwConfigImport | None = None, + exc: BaseException | None = None, + error_text: str = "", +): + try: + if fwo_globals.shutdown_requested: + FWOLogger.warning("Shutdown requested.") + elif error_text != "": + FWOLogger.error(f"Exception: {error_text}") + elif exc is not None: + FWOLogger.error(f"Exception: {type(exc).__name__}") else: - if in_file is not None: # read native config from file - full_config_json, error_count, change_count = \ - read_fw_json_config_file(filename=in_file, error_string=error_string, error_count=error_count, \ - current_import_id=current_import_id, start_time=start_time, mgm_details=mgm_details, change_count=change_count, jwt=jwt) - - if normalized_in_file is not None: # read normalized config from file - config2import, error_count, change_count = \ - read_fw_json_config_file(filename=normalized_in_file, error_string=error_string, error_count=error_count, \ - current_import_id=current_import_id, start_time=start_time, mgm_details=mgm_details, change_count=change_count, jwt=jwt) - replace_import_id(config2import, current_import_id) - else: # standard case, read config from FW API - # note: we need to run get_config_from_api in any case (even when importing from a file) as this function - # also contains the conversion from native to config2import (parsing) - ### geting config from firewall manager ###################### - config_changed_since_last_import, error_string, error_count, change_count = get_config_from_api(mgm_details, full_config_json, config2import, jwt, current_import_id, start_time, - in_file=in_file, import_tmp_path=import_tmp_path, error_string=error_string, error_count=error_count, change_count=change_count, - limit=limit, force=force) - if (debug_level>7): # dump full native config read from fw API - logger.info(json.dumps(full_config_json, indent=2)) - - time_get_config = int(time.time()) - start_time - logger.debug("import_management - getting config total duration " + str(time_get_config) + "s") - - if config_changed_since_last_import: - try: # now we import the config via API chunk by chunk: - for config_chunk in split_config(config2import, current_import_id, mgm_id): - error_count += fwo_api.import_json_config(fwo_config['fwo_api_base_url'], jwt, mgm_id, config_chunk) - fwo_api.update_hit_counter(fwo_config['fwo_api_base_url'], jwt, mgm_id, config_chunk) - except: - logger.error("import_management - unspecified error while importing config via FWO API: " + str(traceback.format_exc())) - raise - time_write2api = int(time.time()) - time_get_config - start_time - logger.debug("import_management - writing config to API and stored procedure import duration: " + str(time_write2api) + "s") - - error_from_imp_control = "assuming error" - try: # checking for errors during stored_procedure db imort in import_control table - error_from_imp_control = fwo_api.get_error_string_from_imp_control(fwo_config['fwo_api_base_url'], jwt, {"importId": current_import_id}) - except: - logger.error("import_management - unspecified error while getting error string: " + str(traceback.format_exc())) - - if error_from_imp_control != None and error_from_imp_control != [{'import_errors': None}]: - error_count += 1 - error_string += str(error_from_imp_control) - # todo: if no objects found at all: at least throw a warning - - try: # get change count from db - change_count = fwo_api.count_changes_per_import(fwo_config['fwo_api_base_url'], jwt, current_import_id) - if change_count>0: - emailConfig = fwo_api.get_config_values(fwo_config['fwo_api_base_url'], jwt, keyFilter="email") - impChangeNotifyConfig = fwo_api.get_config_values(fwo_config['fwo_api_base_url'], jwt, keyFilter="impChangeNotify") - notificationConfig = dict(emailConfig, **impChangeNotifyConfig) # merge the two config dicts - send_change_notification_mail(notificationConfig, change_count, mgm_details['name'], mgm_id) - except: - logger.error("import_management - unspecified error while getting change count: " + str(traceback.format_exc())) - raise - - try: # calculate config sizes - full_config_size = sys.getsizeof(json.dumps(full_config_json)) - config2import_size = sys.getsizeof(jsonpickle.dumps(config2import)) - logger.debug("full_config size: " + str(full_config_size) + " bytes, config2import size: " + str(config2import_size) + " bytes") - except: - logger.error("import_management - unspecified error while calculating config sizes: " + str(traceback.format_exc())) - raise - - if (debug_level>5 or change_count > 0 or error_count > 0) and full_config_size < full_config_size_limit: # store full config in case of change or error - try: # store full config in DB - error_count += fwo_api.store_full_json_config(fwo_config['fwo_api_base_url'], jwt, mgm_id, { - "importId": current_import_id, "mgmId": mgm_id, "config": full_config_json}) - except: - logger.error("import_management - unspecified error while storing full config: " + str(traceback.format_exc())) - raise - else: # if no changes were found, we skip everything else without errors - pass - - if (debug_level>8): # dump normalized config for debugging purposes - logger.info(json.dumps(config2import, indent=2)) - - error_count = complete_import(current_import_id, error_string, start_time, mgm_details, change_count, error_count, jwt) - - return error_count - - -def get_config_from_api(mgm_details, full_config_json, config2import, jwt, current_import_id, start_time, - in_file=None, import_tmp_path='.', error_string='', error_count=0, change_count=0, limit=150, force=False): - logger = getFwoLogger() - fwo_config = readConfig(fwo_config_filename) - - try: # pick product-specific importer: - pkg_name = mgm_details['deviceType']['name'].lower().replace(' ', '') + mgm_details['deviceType']['version'] - fw_module = importlib.import_module("." + fw_module_name, pkg_name) - except: - logger.exception("import_management - error while loading product specific fwcommon module", traceback.format_exc()) - raise - - try: # get the config data from the firewall manager's API: - # check for changes from product-specific FW API - config_changed_since_last_import = in_file != None or fw_module.has_config_changed(full_config_json, mgm_details, force=force) - if config_changed_since_last_import: - logger.debug ( "has_config_changed: changes found or forced mode -> go ahead with getting config, Force = " + str(force)) + FWOLogger.error("Exception: no exception provided") + if config_importer is not None: + FwConfigImportRollback().rollback_current_import( + import_state=import_state.state, fwo_api_call=import_state.api_call + ) else: - logger.debug ( "has_config_changed: no new changes found") - - if config_changed_since_last_import: - fw_module.get_config( # get config from product-specific FW API - config2import, full_config_json, current_import_id, mgm_details, - limit=limit, force=force, jwt=jwt) - except (FwLoginFailed) as e: - error_string += " login failed: mgm_id=" + str(mgm_details['id']) + ", mgm_name=" + mgm_details['name'] + ", " + e.message - error_count += 1 - logger.error(error_string) - fwo_api.delete_import(fwo_config['fwo_api_base_url'], jwt, current_import_id) # deleting trace of not even begun import - error_count = complete_import(current_import_id, error_string, start_time, mgm_details, change_count, error_count, jwt) - raise FwLoginFailed(e.message) - except ImportRecursionLimitReached as e: - error_string += " recursion limit reached: mgm_id=" + str(mgm_details['id']) + ", mgm_name=" + mgm_details['name'] + ", " + e.message - error_count += 1 - logger.error(error_string) - fwo_api.delete_import(fwo_config['fwo_api_base_url'], jwt, current_import_id) # deleting trace of not even begun import - error_count = complete_import(current_import_id, error_string, start_time, mgm_details, change_count, error_count, jwt) - raise ImportRecursionLimitReached(e.message) - except: - error_string += " import_management - unspecified error while getting config: " + str(traceback.format_exc()) - logger.error(error_string) - error_count += 1 - error_count = complete_import(current_import_id, error_string, start_time, mgm_details, change_count, error_count, jwt) + FWOLogger.info("No config_importer found, skipping rollback.") + import_state.delete_import() # delete whole import + except Exception as rollbackError: + FWOLogger.error(f"Error during rollback: {type(rollbackError).__name__} - {rollbackError}") + + +def get_config_top_level( + import_state: ImportStateController, + in_file: str | None = None, + gateways: list[Gateway] | None = None, +) -> tuple[bool, FwConfigManagerListController]: + config_from_file = FwConfigManagerListController.generate_empty_config() + if gateways is None: + gateways = [] + config_uri = get_config_uri(import_state) + file_name = in_file or config_uri + if file_name is not None: + ### getting config from file ###################### + _, config_from_file = import_from_file(import_state, file_name) + if not config_from_file.is_native_non_empty(): + config_has_changes = True + return config_has_changes, config_from_file + # else we feed the native config back into the importer process for normalization + ### getting config from firewall manager API ###### + return get_config_from_api(import_state, config_from_file) + + +def import_from_file( + import_state: ImportStateController, file_name: str = "" +) -> tuple[bool, FwConfigManagerListController]: + FWOLogger.debug(f"import_management - not getting config from API but from file: {file_name}") + + config_changed_since_last_import = True + + set_filename(import_state, file_name=file_name) + + config_from_file = fwo_file_import.read_json_config_from_file(import_state.api_call, import_state.state) + + return config_changed_since_last_import, config_from_file + + +def get_module(import_state: ImportState) -> FwCommon: + # pick product-specific importer: + pkg_name = get_module_package_name(import_state) + match pkg_name: + case "ciscoasa9": + fw_module = CiscoAsa9Common() + case "fortiadom5ff": + fw_module = FortiAdom5ffCommon() + case "checkpointR8x": + fw_module = CheckpointR8xCommon() + case "fortiosmanagementREST": + fw_module = FortiosManagementRESTCommon() + case _: + raise FwoImporterError(f"import_management - no fwcommon module found for package name {pkg_name}") + + return fw_module + + +def get_config_from_api( + import_state: ImportStateController, config_in: FwConfigManagerListController +) -> tuple[bool, FwConfigManagerListController]: + try: # pick product-specific importer: + fw_module = get_module(import_state.state) + except Exception: + FWOLogger.exception( + "import_management - error while loading product specific fwcommon module", + traceback.format_exc(), + ) raise - logger.debug("import_management: get_config completed (including normalization), duration: " + str(int(time.time()) - start_time) + "s") + # check for changes from product-specific FW API, if we are importing from file we assume config changes + # TODO: implement real change detection + config_changed_since_last_import = fw_module.has_config_changed( + config_in, import_state, import_state.state.force_import + ) + if config_changed_since_last_import: + FWOLogger.info( + "has_config_changed: changes found or forced mode -> go ahead with getting config, Force = " + + str(import_state.state.force_import) + ) + else: + FWOLogger.info("has_config_changed: no new changes found") - if config_changed_since_last_import and fwo_globals.debug_level>2: # debugging: writing config to json file - debug_start_time = int(time.time()) - try: - normalized_config_filename = import_tmp_path + '/mgm_id_' + \ - str(mgm_details['id']) + '_config_normalized.json' - with open(normalized_config_filename, "w") as json_data: - json_data.write(json.dumps(jsonpickle.dumps(config2import))) - - if fwo_globals.debug_level>3: - full_native_config_filename = import_tmp_path + '/mgm_id_' + \ - str(mgm_details['id']) + '_config_native.json' - with open(full_native_config_filename, "w") as json_data: # create empty config file - json_data.write(json.dumps(full_config_json, indent=2)) - except: - logger.error("import_management - unspecified error while dumping config to json file: " + str(traceback.format_exc())) - raise - - time_write_debug_json = int(time.time()) - debug_start_time - logger.debug("import_management - writing debug config json files duration " + str(time_write_debug_json) + "s") - return config_changed_since_last_import, error_string, error_count, change_count - - -def check_input_parameters(mgm_id, ssl_verification=None, debug_level_in=0, - limit=150, force=False, clearManagementData=False, suppress_cert_warnings_in=None, - in_file=None, normalized_in_file=None): - - if mgm_id is None: - raise BaseException("parameter mgm_id is mandatory") - if in_file is not None and normalized_in_file is not None: - raise BaseException("you cannot specify both in_file and normalized_in_file") - - -def complete_import(current_import_id, error_string, start_time, mgm_details, change_count, error_count, jwt): - logger = getFwoLogger() - fwo_config = readConfig(fwo_config_filename) - - success = (error_count==0) - log_result = fwo_api.log_import_attempt(fwo_config['fwo_api_base_url'], jwt, mgm_details['id'], successful=success) - - try: # CLEANUP: delete configs of imports (without changes) (if no error occured) - if fwo_api.delete_json_config_in_import_table(fwo_config['fwo_api_base_url'], jwt, {"importId": current_import_id})<0: - error_count += 1 - except: - logger.error("import_management - unspecified error cleaning up import_config: " + str(traceback.format_exc())) - - try: # CLEANUP: delete data of this import from import_object/rule/service/user tables - if fwo_api.delete_import_object_tables(fwo_config['fwo_api_base_url'], jwt, {"importId": current_import_id})<0: - error_count += 1 - except: - logger.error("import_management - unspecified error cleaning up import_ object tables: " + str(traceback.format_exc())) - - try: # finalize import by unlocking it - error_count += fwo_api.unlock_import(fwo_config['fwo_api_base_url'], jwt, int( - mgm_details['id']), datetime.datetime.now().isoformat(), current_import_id, error_count, change_count) - except: - logger.error("import_management - unspecified error while unlocking import: " + str(traceback.format_exc())) - - import_result = "import_management: import no. " + str(current_import_id) + \ - " for management " + mgm_details['name'] + ' (id=' + str(mgm_details['id']) + ")" + \ - str(" threw errors," if error_count else " successful,") + \ - " change_count: " + str(change_count) + \ - ", duration: " + str(int(time.time()) - start_time) + "s" - import_result += ", ERRORS: " + error_string if len(error_string) > 0 else "" - - if error_count>0: - fwo_api.create_data_issue(fwo_config['fwo_api_base_url'], jwt, import_id=current_import_id, severity=1, description=error_string) - fwo_api.setAlert(fwo_config['fwo_api_base_url'], jwt, import_id=current_import_id, title="import error", mgm_id=mgm_details['id'], severity=2, role='importer', \ - description=error_string, source='import', alertCode=14, mgm_details=mgm_details) - - logger.info(import_result) - - return error_count - - -def read_fw_json_config_file(filename=None, config={}, error_string='', error_count=0, current_import_id=None, start_time=0, mgm_details=None, change_count=0, jwt=''): - - # when we read from a normalized config file, it contains non-matching dev_ids in gw_ tables - def replace_device_id(config, mgm_details): - logger = getFwoLogger() - if 'routing' in config or 'interfaces' in config: - if len(mgm_details['devices'])>1: - logger.warning('importing from config file with more than one device - just picking the first device at random') - if len(mgm_details['devices'])>=1: - # just picking the first device - dev_id = mgm_details['devices'][0]['id'] - if 'routing' in config: - i=0 - while i str | None: + mgm_details = import_state.state.mgm_details + if string_is_uri(mgm_details.hostname): + return mgm_details.hostname + if mgm_details.domain_name and string_is_uri(mgm_details.domain_name): + return mgm_details.domain_name + return None diff --git a/roles/importer/files/importer/dummyroutermanagement1/fwcommon.py b/roles/importer/files/importer/dummyroutermanagement1/fwcommon.py deleted file mode 100644 index 1e0f57bc62..0000000000 --- a/roles/importer/files/importer/dummyroutermanagement1/fwcommon.py +++ /dev/null @@ -1,68 +0,0 @@ -import sys -from common import importer_base_dir, complete_import -from fwo_exception import ConfigFileNotFound - -sys.path.append(importer_base_dir + '/dummyrouter') -from curses import raw -from fwo_log import getFwoLogger -import fwo_globals -from fwo_data_networking import Interface, Route, getRouteDestination -import json, requests, requests.packages -from datetime import datetime -import jsonpickle - -def has_config_changed(_, __, force=False): - return True - - -def get_config(config2import, _, current_import_id, mgm_details, limit=100, force=False, jwt=''): - router_file_url = mgm_details['configPath'] - error_count = 0 - change_count = 0 - start_time=datetime.now() - error_string = '' - - if len(mgm_details['devices'])!=1: - logger = getFwoLogger() - logger.error('expected exactly one device but found: ' + str(mgm_details['devices'])) - exit(1) - dev_id = mgm_details['devices'][0]['id'] - - try: - session = requests.Session() - #session.headers = { 'Content-Type': 'application/json' } - session.verify=fwo_globals.verify_certs - r = session.get(router_file_url, ) - r.raise_for_status() - cfg = json.loads(r.content) - - except requests.exceptions.RequestException: - error_string = "got HTTP status code" + str(r.status_code) + " while trying to read config file from URL " + router_file_url - error_count += 1 - error_count = complete_import(current_import_id, error_string, start_time, mgm_details, change_count, error_count, jwt) - raise ConfigFileNotFound(error_string) from None - except: - error_string = "Could not read config file " + router_file_url - error_count += 1 - error_count = complete_import(current_import_id, error_string, start_time, mgm_details, change_count, error_count, jwt) - raise ConfigFileNotFound(error_string) from None - - # deserialize network info from json into objects - - # device_id, name, ip, netmask_bits, state_up=True, ip_version=4 - ifaces = [] - for iface in cfg['interfaces']: - ifaces.append(Interface(dev_id, iface['name'], iface['ip'], iface['netmask_bits'], state_up=iface['state_up'], ip_version=iface['ip_version'])) - cfg['interfaces'] = ifaces - - # device_id, target_gateway, destination, static=True, source=None, interface=None, metric=None, distance=None, ip_version=4 - routes = [] - for route in cfg['routing']: - routes.append(Route(dev_id, route['target_gateway'], route['destination'], static=route['static'], interface=route['interface'], metric=route['metric'], distance=route['distance'], ip_version=route['ip_version'])) - cfg['routing'] = routes - - cfg['routing'].sort(key=getRouteDestination,reverse=True) - - config2import.update({'interfaces': cfg['interfaces'], 'routing': cfg['routing']}) - - return 0 diff --git a/roles/importer/files/importer/fortiadom5ff/autodiscover.sh b/roles/importer/files/importer/fortiadom5ff/autodiscover.sh deleted file mode 100644 index 1d421be37c..0000000000 --- a/roles/importer/files/importer/fortiadom5ff/autodiscover.sh +++ /dev/null @@ -1,111 +0,0 @@ -#!/bin/bash - -NAME_="dicovery-fgtmgr.sh" -SYNOPSIS_="$NAME_ [-d] [-H ] [-U ] [-K ]" -REQUIRES_="standard GNU commands" -VERSION_="0.1" -DATE_="2021-06-24" -AUTHOR_="Holger Dost " -PURPOSE_="extracts information from the fortimanager" -EXIT_ERROR=3 -EXIT_BUG=3 -EXIT_SUCCESS=0 - - -KEY='/usr/local/fworch/.ssh/id_rsa_forti' -USER='itsecorg' -SERVER='1.1.1.1' -REMCOM='diagnose dvm device list' -DEBUGMODE=0 -GREP="/bin/fgrep" -AWK="/usr/bin/awk" -HEAD="/usr/bin/head" - - -usage () { - echo >&2 "$NAME_ $VERSION_ - $PURPOSE_ -Usage: $SYNOPSIS_ -Requires: $REQUIRES_ -Example: discovery-fgtmgr.sh -d -H 1.1.1.1 -U testuser -K .ssh/id_rsa_testkey -" - exit 1 -} - -shopt -s extglob - -while getopts 'dhH:C:D:' OPTION ; do - case $OPTION in - h) usage $EXIT_SUCCESS - ;; - d) DEBUGMODE=1 - ;; - H) SERVER="$OPTARG" - ;; - U) USER="$OPTARG" - ;; - K) KEY="$OPTARG" - ;; - \?)echo "unknown option \"-$OPTARG\"." >&2 - usage $EXIT_ERROR - ;; - :) echo "option \"-$OPTARG\" argument missing" >&2 - usage $EXIT_ERROR - ;; - *) echo "bug ..." >&2 - usage $EXIT_BUG - ;; - esac -done - -# : ${SERVER:='1.1.1.1'} -# : ${USER:='itsecorg'} -# : ${KEY:='/usr/local/fworch/.ssh/id_rsa_forti'} - -DEBUG () { - if [ $DEBUGMODE -gt 0 ]; then - #printf "$1\n" - printf '%s\n' "$1" - fi -} -DEBUGWOLF () { - if [ $DEBUGMODE -gt 0 ]; then - printf '%s' "$1" - fi -} - -REMRES=`ssh -i ${KEY} ${USER}@${SERVER} "${REMCOM}" | egrep "fmg/faz|vdom|^TYPE" | grep -v 'root flags'` -LINECOUNT=0 -FMGLINECOUNT=0 -while read line; do - ((LINECOUNT++)) - #DEBUG "$line" - if [[ "$line" =~ "fmg/faz" ]]; then - ((FMGLINECOUNT++)) - IFS=' '; read -ra FMGLINE <<< $line - FMGVALCOUNT=0 - for FMGVAL in "${FMGLINE[@]}"; do - ((FMGVALCOUNT++)) - FMG[${FMGLINECOUNT},${FMGVALCOUNT}]=$FMGVAL - DEBUGWOLF "${FMG[${FMGLINECOUNT},${FMGVALCOUNT}]}," - done - DEBUG "" - # array für die Ausgabezeilen bauen, oder die Zeile direkt ausgeben - fi - if [[ "$line" =~ "vdom" ]]; then - ((VDOMLINECOUNT++)) - IFS=' '; read -ra VDOMLINE <<< $line - VDOMVALCOUNT=0 - for VDOMVAL in "${VDOMLINE[@]}"; do - ((VDOMVALCOUNT++)) - VDOM[${FMGLINECOUNT},${VDOMLINECOUNT},${VDOMVALCOUNT}]=$VDOMVAL - DEBUGWOLF "${VDOM[${FMGLINECOUNT},${VDOMLINECOUNT},${VDOMVALCOUNT}]}," - done - DEBUG "" - # wenn vdoms existieren obige zeile ergänzen, auch mehrfach - fi -done <<< "$REMRES" -FMGLINECOUNTMAX=$FMGLINECOUNT - -echo "${#FMG[@]}" -echo "${#VDOM[@]}" -#printf "${FMG[${FMGLINECOUNT},${FMGVALCOUNT}]} diff --git a/roles/importer/files/importer/fortiadom5ff/discovery_logging.conf b/roles/importer/files/importer/fortiadom5ff/discovery_logging.conf deleted file mode 100644 index 139c55a9cb..0000000000 --- a/roles/importer/files/importer/fortiadom5ff/discovery_logging.conf +++ /dev/null @@ -1,41 +0,0 @@ -[loggers] -keys=root,discoveryDebugLogger -#keys=root,__main__ - -[handlers] -keys=consoleHandler,debugFileHandler - -[formatters] -keys=defaultFormatter,debugFileFormatter - -[logger_root] -level=DEBUG -handlers=consoleHandler - -[logger_discoveryDebugLogger] -#[logger___main__] -level=DEBUG -handlers=debugFileHandler -qualname=discoveryDebugLogger -#qualname=__main__ -propagate=0 - -[handler_consoleHandler] -class=StreamHandler -level=DEBUG -formatter=defaultFormatter -args=(sys.stderr,) - -[handler_debugFileHandler] -class=FileHandler -level=DEBUG -formatter=debugFileFormatter -args=('/tmp/fworch_discovery.log',) -# args=('/var/log/fworch/discovery.log',) - -[formatter_defaultFormatter] -format=%(levelname)s:%(name)s:%(message)s - -[formatter_debugFileFormatter] -format=%(asctime)s - %(name)s - %(levelname)s - %(message)s - diff --git a/roles/importer/files/importer/fortiadom5ff/fmgr_getter.py b/roles/importer/files/importer/fortiadom5ff/fmgr_getter.py deleted file mode 100644 index 6a2d9faea7..0000000000 --- a/roles/importer/files/importer/fortiadom5ff/fmgr_getter.py +++ /dev/null @@ -1,137 +0,0 @@ -# library for API get functions -import re -from fwo_log import getFwoLogger -import requests.packages -import requests -import json -import fwo_globals -from fwo_exception import FwLoginFailed - - -def api_call(url, command, json_payload, sid, show_progress=False, method=''): - logger = getFwoLogger() - request_headers = {'Content-Type': 'application/json'} - if sid != '': - json_payload.update({"session": sid}) - if command != '': - for p in json_payload['params']: - p.update({"url": command}) - if method == '': - method = 'get' - json_payload.update({"method": method}) - - r = requests.post(url, data=json.dumps(json_payload), headers=request_headers, verify=fwo_globals.verify_certs) - if r is None: - if 'pass' in json.dumps(json_payload): - exception_text = "error while sending api_call containing credential information to url '" + str(url) - else: - exception_text = "error while sending api_call to url '" + str(url) + "' with payload '" + json.dumps(json_payload, indent=2) + "' and headers: '" + json.dumps(request_headers, indent=2) - raise Exception(exception_text) - result_json = r.json() - if 'result' not in result_json or len(result_json['result'])<1: - if 'pass' in json.dumps(json_payload): - raise Exception("error while sending api_call containing credential information to url '" + str(url)) - else: - if 'status' in result_json['result'][0]: - raise Exception("error while sending api_call to url '" + str(url) + "' with payload '" + - json.dumps(json_payload, indent=2) + "' and headers: '" + json.dumps(request_headers, indent=2) + ', result=' + json.dumps(r.json()['result'][0]['status'], indent=2)) - else: - raise Exception("error while sending api_call to url '" + str(url) + "' with payload '" + - json.dumps(json_payload, indent=2) + "' and headers: '" + json.dumps(request_headers, indent=2) + ', result=' + json.dumps(r.json()['result'][0], indent=2)) - if 'status' not in result_json['result'][0] or 'code' not in result_json['result'][0]['status'] or result_json['result'][0]['status']['code'] != 0: - # trying to ignore empty results as valid - pass # logger.warning('received empty result') - if fwo_globals.debug_level>2: - if 'pass' in json.dumps(json_payload): - logger.debug("api_call containing credential information to url '" + str(url) + " - not logging query") - else: - logger.debug("api_call to url '" + str(url) + "' with payload '" + json.dumps( - json_payload, indent=2) + "' and headers: '" + json.dumps(request_headers, indent=2)) - - if show_progress: - print('.', end='', flush=True) - return result_json - - -def login(user, password, base_url): - payload = { - "id": 1, - "params": [ { "data": [ { "user": user, "passwd": password, } ] } ] - } - try: - response = api_call(base_url, 'sys/login/user', payload, '', method="exec") - except Exception: - raise FwLoginFailed("FortiManager login ERROR: url=" + base_url) from None - if "session" not in response: # leaving out payload as it contains pwd - raise FwLoginFailed("FortiManager login ERROR: url=" + base_url) from None - return response["session"] - - -def logout(v_url, sid, method='exec'): - logger = getFwoLogger() - payload = {"params": [{}]} - - response = api_call(v_url, 'sys/logout', payload, sid, method=method) - if "result" in response and "status" in response["result"][0] and "code" in response["result"][0]["status"] and response["result"][0]["status"]["code"] == 0: - logger.debug("successfully logged out") - else: - raise Exception( "fmgr_getter ERROR: did not get status code 0 when logging out, " + - "api call: url: " + str(v_url) + ", + payload: " + str(payload)) - - -def set_api_url(base_url, testmode, api_supported, hostname): - url = '' - if testmode == 'off': - url = base_url - else: - if re.search(r'^\d+[\.\d+]+$', testmode) or re.search(r'^\d+$', testmode): - if testmode in api_supported: - url = base_url + 'v' + testmode + '/' - else: - raise Exception("api version " + testmode + - " is not supported by the manager " + hostname + " - Import is canceled") - else: - raise Exception("\"" + testmode + "\" - not a valid version") - return url - - -def update_config_with_fortinet_api_call(config_json, sid, api_base_url, api_path, result_name, payload={}, options=[], show_progress=False, limit=150, method="get"): - offset = 0 - limit = int(limit) - returned_new_objects = True - full_result = [] - while returned_new_objects: - range = [offset, limit] - if payload == {}: - payload = {"params": [{'range': range}]} - else: - if 'params' in payload and len(payload['params'])>0: - payload['params'][0].update({'range': range}) - - # adding options - if len(options)>0: - payload['params'][0].update({'option': options}) - # payload['params'][0].update({'filter': options}) - - result = fortinet_api_call(sid, api_base_url, api_path, payload=payload, show_progress=show_progress, method=method) - full_result.extend(result) - offset += limit - if len(result)5: - logger.warning('native configs contains the following keys ' + str(native_config.keys())) - normalized_config['networking'][full_vdom_name]['routingv6'] = [] - else: - for route in native_config['routing-table-ipv6/' + full_vdom_name]: - #gateway = None if route['gateway']=='::' else route['gateway'] # local network - normRoute = Route(dev_id, route['gateway'], route['ip_mask'], metric=route['metric'], - distance=route['distance'], interface=route['interface'], ip_version=6) - normalized_config['routing'].append(normRoute) - - normalized_config['routing'].sort(key=getRouteDestination,reverse=True) - - for interface in native_config['interfaces_per_device/' + full_vdom_name]: - if interface['ipv6']['ip6-address']!='::/0': - ipv6, netmask_bits = interface['ipv6']['ip6-address'].split('/') - normIfV6 = Interface(dev_id, interface['name'], IPAddress(ipv6), netmask_bits, ip_version=6) - normalized_config['interfaces'].append(normIfV6) - - if interface['ip']!=['0.0.0.0','0.0.0.0']: - ipv4 = IPAddress(interface['ip'][0]) - netmask_bits = IPAddress(interface['ip'][1]).netmask_bits() - normIfV4 = Interface(dev_id, interface['name'], ipv4, netmask_bits, ip_version=4) - normalized_config['interfaces'].append(normIfV4) - - #devices_without_default_route = get_devices_without_default_route(normalized_config) - #if len(devices_without_default_route)>0: - # logger.warning('found devices without default route') - - -def get_matching_route(destination_ip, routing_table): - - logger = getFwoLogger() - - def route_matches(ip, destination): - ip_n = IPNetwork(ip).cidr - dest_n = IPNetwork(destination).cidr - return ip_n in dest_n or dest_n in ip_n - - - if len(routing_table)==0: - logger.error('src nat behind interface: encountered empty routing table') - return None - - for route in routing_table: - if route_matches(destination_ip, route['destination']): - return route - - logger.warning('src nat behind interface: found no matching route in routing table - no default route?!') - return None - - -def get_ip_of_interface(interface, interface_list=[]): - - interface_details = next((sub for sub in interface_list if sub['name'] == interface), None) - - if interface_details is not None and 'ipv4' in interface_details: - return interface_details['ipv4'] - else: - return None - - -def sort_reverse(ar_in, key): - - def comp(left, right): - l_submask = int(left[key].split("/")[1]) - r_submask = int(right[key].split("/")[1]) - return l_submask - r_submask - - return sorted(ar_in, key=cmp_to_key(comp), reverse=True) - - -# strip off last part of a string separated by separator -def strip_off_last_part(string_in, separator='_'): - string_out = string_in - if separator in string_in: # strip off final _xxx part - str_ar = string_in.split(separator) - str_ar.pop() - string_out = separator.join(str_ar) - return string_out - - -def get_last_part(string_in, separator='_'): - string_out = '' - if separator in string_in: # strip off _vdom_name - str_ar = string_in.split(separator) - string_out = str_ar.pop() - return string_out - - -def get_plain_device_names_without_vdoms(devices): - device_array = [] - for dev in devices: - dev_name = strip_off_last_part(dev["name"]) - if dev_name not in device_array: - device_array.append(dev_name) - return device_array - - -# only getting one vdom as currently assuming routing to be -# the same for all vdoms on a device -def get_device_names_plus_one_vdom(devices): - device_array = [] - device_array_with_vdom = [] - for dev in devices: - dev_name = strip_off_last_part(dev["name"]) - vdom_name = get_last_part(dev["name"]) - if dev_name not in device_array: - device_array.append(dev_name) - device_array_with_vdom.append([dev_name, vdom_name]) - return device_array_with_vdom - - -# getting devices and their vdom names -def get_device_plus_full_vdom_names(devices): - device_array_with_vdom = [] - for dev in devices: - dev_name = strip_off_last_part(dev["name"]) - vdom_name = dev["name"] - device_array_with_vdom.append([dev_name, vdom_name]) - return device_array_with_vdom - - -# getting devices and their vdom names -def get_all_dev_names(devices): - device_array_with_vdom = [] - for dev in devices: - dev_id = dev["id"] - dev_name = strip_off_last_part(dev["name"]) - plain_vdom_name = get_last_part(dev["name"]) - full_vdom_name = dev["name"] - device_array_with_vdom.append([dev_id, dev_name, plain_vdom_name, full_vdom_name]) - return device_array_with_vdom - - -# get network information (currently only used for source nat) -def getInterfacesAndRouting(sid, fm_api_url, raw_config, adom_name, devices, limit): - - logger = getFwoLogger() - # strip off vdom names, just deal with the plain device - device_array = get_all_dev_names(devices) - - for dev_id, plain_dev_name, plain_vdom_name, full_vdom_name in device_array: - logger.info("dev_name: " + plain_dev_name + ", full vdom_name: " + full_vdom_name) - - # getting interfaces of device - all_interfaces_payload = { - "id": 1, - "params": [ - { - "fields": [ "name", "ip" ], - "filter": [ "vdom", "==", plain_vdom_name ], - "sub fetch": { - "client-options": { - "subfetch hidden": 1 - }, - "dhcp-snooping-server-list": { - "subfetch hidden": 1 - }, - "egress-queues": { - "subfetch hidden": 1 - }, - "ipv6": { - "fields": [ - "ip6-address" - ], - "sub fetch": { - "dhcp6-iapd-list": { - "subfetch hidden": 1 - }, - "ip6-delegated-prefix-list": { - "subfetch hidden": 1 - }, - "ip6-extra-addr": { - "subfetch hidden": 1 - }, - "ip6-prefix-list": { - "subfetch hidden": 1 - }, - "vrrp6": { - "subfetch hidden": 1 - } - } - }, - "l2tp-client-settings": { - "subfetch hidden": 1 - }, - "secondaryip": { - "subfetch hidden": 1 - }, - "tagging": { - "subfetch hidden": 1 - }, - "vrrp": { - "subfetch hidden": 1 - }, - "wifi-networks": { - "subfetch hidden": 1 - } - } - } - ] - } - # get_interfaces_payload = { - # "id": 1, - # "params": [ - # { - # "fields": [ "name", "ip" ], - # "filter": [ "vdom", "==", plain_vdom_name ], - # "option": [ "no loadsub" ], - # } - # ] - # } - try: # get interfaces from top level device (not vdom) - fmgr_getter.update_config_with_fortinet_api_call( - raw_config, sid, fm_api_url, "/pm/config/device/" + plain_dev_name + "/global/system/interface", - "interfaces_per_device/" + full_vdom_name, payload=all_interfaces_payload, limit=limit, method="get") - except: - logger.warning("error while getting interfaces of device " + plain_vdom_name + ", vdom=" + plain_vdom_name + ", ignoring, traceback: " + str(traceback.format_exc())) - - # now getting routing information - for ip_version in ["ipv4", "ipv6"]: - payload = { "params": [ { "data": { - "target": ["adom/" + adom_name + "/device/" + plain_dev_name], - "action": "get", - "resource": "/api/v2/monitor/router/" + ip_version + "/select?&vdom="+ plain_vdom_name } } ] } - try: # get routing table per vdom - routing_helper = {} - routing_table = [] - fmgr_getter.update_config_with_fortinet_api_call( - routing_helper, sid, fm_api_url, "/sys/proxy/json", - "routing-table-" + ip_version + '/' + full_vdom_name, - payload=payload, limit=limit, method="exec") - - if "routing-table-" + ip_version + '/' + full_vdom_name in routing_helper: - routing_helper = routing_helper["routing-table-" + ip_version + '/' + full_vdom_name] - if len(routing_helper)>0 and 'response' in routing_helper[0] and 'results' in routing_helper[0]['response']: - routing_table = routing_helper[0]['response']['results'] - else: - logger.warning("got empty " + ip_version + " routing table from device " + full_vdom_name + ", ignoring") - routing_table = [] - except: - logger.warning("could not get routing table for device " + full_vdom_name + ", ignoring") # exception " + str(traceback.format_exc())) - routing_table = [] - - # now storing the routing table: - raw_config.update({"routing-table-" + ip_version + '/' + full_vdom_name: routing_table}) - - -def get_device_from_package(package_name, mgm_details): - logger = getFwoLogger() - for dev in mgm_details['devices']: - if dev['local_rulebase_name'] == package_name: - return dev['id'] - logger.debug('get_device_from_package - could not find device for package "' + package_name + '"') - return None diff --git a/roles/importer/files/importer/fortiadom5ff/fmgr_network.py b/roles/importer/files/importer/fortiadom5ff/fmgr_network.py deleted file mode 100644 index 0019890d23..0000000000 --- a/roles/importer/files/importer/fortiadom5ff/fmgr_network.py +++ /dev/null @@ -1,261 +0,0 @@ -from asyncio.log import logger -import ipaddress -from fwo_log import getFwoLogger -from fwo_const import list_delimiter, nat_postfix -from fmgr_zone import add_zone_if_missing -from fwo_config import readConfig -from fwo_const import fwo_config_filename -from fwo_api import setAlert, create_data_issue - -def normalize_nwobjects(full_config, config2import, import_id, nw_obj_types, jwt=None, mgm_id=None): - logger = getFwoLogger() - nw_objects = [] - for obj_type in nw_obj_types: - for obj_orig in full_config[obj_type]: - obj_zone = 'global' - obj = {} - obj.update({'obj_name': obj_orig['name']}) - if 'subnet' in obj_orig: # ipv4 object - ipa = ipaddress.ip_network(str(obj_orig['subnet'][0]) + '/' + str(obj_orig['subnet'][1])) - if ipa.num_addresses > 1: - obj.update({ 'obj_typ': 'network' }) - else: - obj.update({ 'obj_typ': 'host' }) - obj.update({ 'obj_ip': ipa.with_prefixlen }) - elif 'ip6' in obj_orig: # ipv6 object - ipa = ipaddress.ip_network(str(obj_orig['ip6']).replace("\\", "")) - if ipa.num_addresses > 1: - obj.update({ 'obj_typ': 'network' }) - else: - obj.update({ 'obj_typ': 'host' }) - obj.update({ 'obj_ip': ipa.with_prefixlen }) - elif 'member' in obj_orig: # addrgrp4 / addrgrp6 - obj.update({ 'obj_typ': 'group' }) - obj.update({ 'obj_member_names' : list_delimiter.join(obj_orig['member']) }) - obj.update({ 'obj_member_refs' : resolve_objects(obj['obj_member_names'], list_delimiter, full_config, 'name', 'uuid', jwt=jwt, import_id=import_id)}, mgm_id=mgm_id) - elif 'startip' in obj_orig: # ippool object - obj.update({ 'obj_typ': 'ip_range' }) - obj.update({ 'obj_ip': obj_orig['startip'] }) - obj.update({ 'obj_ip_end': obj_orig['endip'] }) - elif 'start-ip' in obj_orig: # standard ip range object - obj.update({ 'obj_typ': 'ip_range' }) - obj.update({ 'obj_ip': obj_orig['start-ip'] }) - obj.update({ 'obj_ip_end': obj_orig['end-ip'] }) - elif 'extip' in obj_orig: # vip object, simplifying to a single ip - obj.update({ 'obj_typ': 'host' }) - if 'extip' not in obj_orig or len(obj_orig['extip'])==0: - logger.error("vip (extip): found empty extip field for " + obj_orig['name']) - else: - if len(obj_orig['extip'])>1: - logger.warning("vip (extip): found more than one extip, just using the first one for " + obj_orig['name']) - set_ip_in_obj(obj, obj_orig['extip'][0]) # resolving nat range if there is one - nat_obj = {} - nat_obj.update({'obj_typ': 'host' }) - nat_obj.update({'obj_color': 'black'}) - nat_obj.update({'obj_comment': 'FWO-auto-generated nat object for VIP'}) - if 'obj_ip_end' in obj: # this obj is a range - include the end ip in name and uid as well to avoid akey conflicts - nat_obj.update({'obj_ip_end': obj['obj_ip_end']}) - - # now dealing with the nat ip obj (mappedip) - if 'mappedip' not in obj_orig or len(obj_orig['mappedip'])==0: - logger.warning("vip (extip): found empty mappedip field for " + obj_orig['name']) - else: - if len(obj_orig['mappedip'])>1: - logger.warning("vip (extip): found more than one mappedip, just using the first one for " + obj_orig['name']) - nat_ip = obj_orig['mappedip'][0] - set_ip_in_obj(nat_obj, nat_ip) - obj.update({ 'obj_nat_ip': nat_obj['obj_ip'] }) # save nat ip in vip obj - if 'obj_ip_end' in nat_obj: # this nat obj is a range - include the end ip in name and uid as well to avoid akey conflicts - obj.update({ 'obj_nat_ip_end': nat_obj['obj_ip_end'] }) # save nat ip in vip obj - nat_obj.update({'obj_name': nat_obj['obj_ip'] + '-' + nat_obj['obj_ip_end'] + nat_postfix}) - else: - nat_obj.update({'obj_name': nat_obj['obj_ip'] + nat_postfix}) - nat_obj.update({'obj_uid': nat_obj['obj_name']}) - ###### range handling - - if 'associated-interface' in obj_orig and len(obj_orig['associated-interface'])>0: # and obj_orig['associated-interface'][0] != 'any': - obj_zone = obj_orig['associated-interface'][0] - nat_obj.update({'obj_zone': obj_zone }) - nat_obj.update({'control_id': import_id}) - if nat_obj not in nw_objects: # rare case when a destination nat is down for two different orig ips to the same dest ip - nw_objects.append(nat_obj) - else: - pass - else: # 'fqdn' in obj_orig: # "fully qualified domain name address" // other unknown types - obj.update({ 'obj_typ': 'network' }) - obj.update({ 'obj_ip': '0.0.0.0/0'}) - if 'comment' in obj_orig: - obj.update({'obj_comment': obj_orig['comment']}) - if 'color' in obj_orig and obj_orig['color']==0: - obj.update({'obj_color': 'black'}) # todo: deal with all other colors (will be currently ignored) - # we would need a list of fortinet color codes - if 'uuid' not in obj_orig: - obj_orig.update({'uuid': obj_orig['name']}) - obj.update({'obj_uid': obj_orig['uuid']}) - - # here only picking first associated interface as zone: - if 'associated-interface' in obj_orig and len(obj_orig['associated-interface'])>0: # and obj_orig['associated-interface'][0] != 'any': - obj_zone = obj_orig['associated-interface'][0] - # adding zone if it not yet exists - obj_zone = add_zone_if_missing (config2import, obj_zone, import_id) - obj.update({'obj_zone': obj_zone }) - - obj.update({'control_id': import_id}) - nw_objects.append(obj) - - # finally add "Original" network object for natting - original_obj_name = 'Original' - original_obj_uid = 'Original' - nw_objects.append(create_network_object(import_id=import_id, name=original_obj_name, type='network', ip='0.0.0.0/0',\ - uid=original_obj_uid, zone='global', color='black', comment='"original" network object created by FWO importer for NAT purposes')) - - config2import.update({'network_objects': nw_objects}) - - -def set_ip_in_obj(nw_obj, ip): # add start and end ip in nw_obj if it is a range, otherwise do nothing - if '-' in ip: # dealing with range - ip_start, ip_end = ip.split('-') - nw_obj.update({'obj_ip': ip_start }) - if ip_end != ip_start: - nw_obj.update({'obj_ip_end': ip_end }) - else: - nw_obj.update({'obj_ip': ip }) - - -# for members of groups, the name of the member obj needs to be fetched separately (starting from API v1.?) -def resolve_nw_uid_to_name(uid, nw_objects): - # return name of nw_objects element where obj_uid = uid - for obj in nw_objects: - if obj['obj_uid'] == uid: - return obj['obj_name'] - return 'ERROR: uid "' + uid + '" not found' - - -def add_member_names_for_nw_group(idx, nw_objects): - group = nw_objects.pop(idx) - if group['obj_member_refs'] == '' or group['obj_member_refs'] == None: - #member_names = None - #obj_member_refs = None - group['obj_member_names'] = None - group['obj_member_refs'] = None - else: - member_names = '' - obj_member_refs = group['obj_member_refs'].split(list_delimiter) - for ref in obj_member_refs: - member_name = resolve_nw_uid_to_name(ref, nw_objects) - member_names += member_name + list_delimiter - group['obj_member_names'] = member_names[:-1] - nw_objects.insert(idx, group) - - -def create_network_object(import_id, name, type, ip, uid, color, comment, zone): - # if zone is None or zone == '': - # zone = 'global' - return { - 'control_id': import_id, - 'obj_name': name, - 'obj_typ': type, - 'obj_ip': ip, - 'obj_uid': uid, - 'obj_color': color, - 'obj_comment': comment, - 'obj_zone': zone - } - - -# TODO: reduce commplexity if possible -def get_nw_obj(nat_obj_name, nwobjects): - for obj in nwobjects: - if 'obj_name' in obj and obj['obj_name']==nat_obj_name: - return obj - return None - - -# this removes all obj_nat_ip entries from all network objects -# these were used during import but might cause issues if imported into db -def remove_nat_ip_entries(config2import): - for obj in config2import['network_objects']: - if 'obj_nat_ip' in obj: - obj.pop('obj_nat_ip') - - -def get_first_ip_of_destination(obj_ref, config2import): - - logger = getFwoLogger() - if list_delimiter in obj_ref: - obj_ref = obj_ref.split(list_delimiter)[0] - # if destination does not contain exactly one ip, raise a warning - logger.info('src nat behind interface: more than one NAT IP - just using the first one for routing decision for obj_ref ' + obj_ref) - - for obj in config2import['network_objects']: - if 'obj_uid' in obj and obj['obj_uid']==obj_ref: - return obj['obj_ip'] - logger.warning('src nat behind interface: found no IP info for destination object ' + obj_ref) - return None - - -def resolve_objects (obj_name_string_list, delimiter, obj_dict, name_key, uid_key, rule_type=None, jwt=None, import_id=None, mgm_id=None): - # guessing ipv4 and adom (to also search global objects) - return resolve_raw_objects (obj_name_string_list, delimiter, obj_dict, name_key, uid_key, rule_type='v4_adom', obj_type='network', jwt=jwt, import_id=import_id, mgm_id=mgm_id) - - -def resolve_raw_objects (obj_name_string_list, delimiter, obj_dict, name_key, uid_key, rule_type=None, obj_type='network', jwt=None, import_id=None, rule_uid=None, object_type=None, mgm_id=None): - logger = getFwoLogger() - fwo_config = readConfig(fwo_config_filename) - - ref_list = [] - objects_not_found = [] - for el in obj_name_string_list.split(delimiter): - found = False - if rule_type is not None: - if obj_type == 'network': - if 'v4' in rule_type and 'global' in rule_type: - object_tables = [obj_dict['nw_obj_global_firewall/address'], obj_dict['nw_obj_global_firewall/addrgrp']] - elif 'v6' in rule_type and 'global' in rule_type: - object_tables = [obj_dict['nw_obj_global_firewall/address6'], obj_dict['nw_obj_global_firewall/addrgrp6']] - elif 'v4' in rule_type and 'adom' in rule_type: - object_tables = [obj_dict['nw_obj_adom_firewall/address'], obj_dict['nw_obj_adom_firewall/addrgrp'], \ - obj_dict['nw_obj_global_firewall/address'], obj_dict['nw_obj_global_firewall/addrgrp'], \ - obj_dict['nw_obj_adom_firewall/vip'] ] - elif 'v6' in rule_type and 'adom' in rule_type: - object_tables = [obj_dict['nw_obj_adom_firewall/address6'], obj_dict['nw_obj_adom_firewall/addrgrp6'], \ - obj_dict['nw_obj_global_firewall/address6'], obj_dict['nw_obj_global_firewall/addrgrp6']] - elif 'nat' in rule_type and 'adom' in rule_type: - object_tables = [obj_dict['nw_obj_adom_firewall/address'], obj_dict['nw_obj_adom_firewall/addrgrp'], \ - obj_dict['nw_obj_global_firewall/address'], obj_dict['nw_obj_global_firewall/addrgrp']] - elif 'nat' in rule_type and 'global' in rule_type: - object_tables = [obj_dict['nw_obj_global_firewall/address'], obj_dict['nw_obj_global_firewall/addrgrp']] - else: - object_tables = [] - break_flag = False # if we find a match we stop the two inner for-loops - for tab in object_tables: - if break_flag: - found = True - break - else: - for obj in tab: - if obj[name_key] == el: - ref_list.append(obj[uid_key]) - break_flag = True - found = True - break - elif obj_type == 'service': - print('later') # todo - else: - print('decide what to do') - if not found: - objects_not_found.append(el) - for obj in objects_not_found: - - if obj != 'all' and obj != 'Original': - if not create_data_issue(fwo_config['fwo_api_base_url'], jwt, import_id=import_id, obj_name=obj, severity=1, rule_uid=rule_uid, mgm_id=mgm_id, object_type=object_type): - logger.warning("resolve_raw_objects: encountered error while trying to log an import data issue using create_data_issue") - - desc = "found a broken network object reference '" + obj + "' " - if object_type is not None: - desc += "(type=" + object_type + ") " - desc += "in rule with UID '" + str(rule_uid) + "'" - setAlert(fwo_config['fwo_api_base_url'], jwt, import_id=import_id, title="object reference error", mgm_id=mgm_id, severity=1, role='importer', \ - description=desc, source='import', alertCode=16) - - return delimiter.join(ref_list) diff --git a/roles/importer/files/importer/fortiadom5ff/fmgr_rule.py b/roles/importer/files/importer/fortiadom5ff/fmgr_rule.py deleted file mode 100644 index fa7d8f31de..0000000000 --- a/roles/importer/files/importer/fortiadom5ff/fmgr_rule.py +++ /dev/null @@ -1,480 +0,0 @@ -import copy -import jsonpickle -from fwo_const import list_delimiter, nat_postfix -from fwo_base import extend_string_list -from fmgr_service import create_svc_object -from fmgr_network import create_network_object, get_first_ip_of_destination -import fmgr_zone, fmgr_getter -from fmgr_gw_networking import get_device_from_package -from fwo_log import getFwoLogger -from fwo_data_networking import get_matching_route_obj, get_ip_of_interface_obj -import ipaddress -from fmgr_network import resolve_objects, resolve_raw_objects -import time - -rule_access_scope_v4 = ['rules_global_header_v4', 'rules_adom_v4', 'rules_global_footer_v4'] -rule_access_scope_v6 = ['rules_global_header_v6', 'rules_adom_v6', 'rules_global_footer_v6'] -rule_access_scope = rule_access_scope_v6 + rule_access_scope_v4 -rule_nat_scope = ['rules_global_nat', 'rules_adom_nat'] -rule_scope = rule_access_scope + rule_nat_scope - - -def initializeRulebases(raw_config): - # initialize access rules - if 'rules_global_header_v4' not in raw_config: - raw_config.update({'rules_global_header_v4': {}}) - if 'rules_global_header_v6' not in raw_config: - raw_config.update({'rules_global_header_v6': {}}) - if 'rules_adom_v4' not in raw_config: - raw_config.update({'rules_adom_v4': {}}) - if 'rules_adom_v6' not in raw_config: - raw_config.update({'rules_adom_v6': {}}) - if 'rules_global_footer_v4' not in raw_config: - raw_config.update({'rules_global_footer_v4': {}}) - if 'rules_global_footer_v6' not in raw_config: - raw_config.update({'rules_global_footer_v6': {}}) - - # initialize nat rules - if 'rules_global_nat' not in raw_config: - raw_config.update({'rules_global_nat': {}}) - if 'rules_adom_nat' not in raw_config: - raw_config.update({'rules_adom_nat': {}}) - - -def getAccessPolicy(sid, fm_api_url, raw_config, adom_name, device, limit): - consolidated = '' # '/consolidated' - logger = getFwoLogger() - - local_pkg_name = device['local_rulebase_name'] - global_pkg_name = device['global_rulebase_name'] - # pkg_name = device['package_name'] pkg_name is not used at all - - # get global header rulebase: - if device['global_rulebase_name'] is None or device['global_rulebase_name'] == '': - logger.debug('no global rulebase name defined in fortimanager, ADOM=' + adom_name + ', local_package=' + local_pkg_name) - else: - fmgr_getter.update_config_with_fortinet_api_call( - raw_config['rules_global_header_v4'], sid, fm_api_url, "/pm/config/global/pkg/" + global_pkg_name + "/global/header" + consolidated + "/policy", local_pkg_name, limit=limit) - fmgr_getter.update_config_with_fortinet_api_call( - raw_config['rules_global_header_v6'], sid, fm_api_url, "/pm/config/global/pkg/" + global_pkg_name + "/global/header" + consolidated + "/policy6", local_pkg_name, limit=limit) - - # get local rulebase - fmgr_getter.update_config_with_fortinet_api_call( - raw_config['rules_adom_v4'], sid, fm_api_url, "/pm/config/adom/" + adom_name + "/pkg/" + local_pkg_name + "/firewall" + consolidated + "/policy", local_pkg_name, limit=limit) - fmgr_getter.update_config_with_fortinet_api_call( - raw_config['rules_adom_v6'], sid, fm_api_url, "/pm/config/adom/" + adom_name + "/pkg/" + local_pkg_name + "/firewall" + consolidated + "/policy6", local_pkg_name, limit=limit) - - # get global footer rulebase: - if device['global_rulebase_name'] != None and device['global_rulebase_name'] != '': - fmgr_getter.update_config_with_fortinet_api_call( - raw_config['rules_global_footer_v4'], sid, fm_api_url, "/pm/config/global/pkg/" + global_pkg_name + "/global/footer" + consolidated + "/policy", local_pkg_name, limit=limit) - fmgr_getter.update_config_with_fortinet_api_call( - raw_config['rules_global_footer_v6'], sid, fm_api_url, "/pm/config/global/pkg/" + global_pkg_name + "/global/footer" + consolidated + "/policy6", local_pkg_name, limit=limit) - - -def getNatPolicy(sid, fm_api_url, raw_config, adom_name, device, limit): - scope = 'global' - pkg = device['global_rulebase_name'] - if pkg is not None and pkg != '': # only read global rulebase if it exists - for nat_type in ['central/dnat', 'central/dnat6', 'firewall/central-snat-map']: - fmgr_getter.update_config_with_fortinet_api_call( - raw_config['rules_global_nat'], sid, fm_api_url, "/pm/config/" + scope + "/pkg/" + pkg + '/' + nat_type, device['local_rulebase_name'], limit=limit) - - scope = 'adom/'+adom_name - pkg = device['local_rulebase_name'] - for nat_type in ['central/dnat', 'central/dnat6', 'firewall/central-snat-map']: - fmgr_getter.update_config_with_fortinet_api_call( - raw_config['rules_adom_nat'], sid, fm_api_url, "/pm/config/" + scope + "/pkg/" + pkg + '/' + nat_type, device['local_rulebase_name'], limit=limit) - - -def normalize_access_rules(full_config, config2import, import_id, mgm_details={}, jwt=None): - logger = getFwoLogger() - rules = [] - first_v4 = True - first_v6 = True - nat_rule_number = 0 - rule_number = 0 - src_ref_all = "" - dst_ref_all = "" - for rule_table in rule_access_scope: - src_ref_all = resolve_raw_objects("all", list_delimiter, full_config, 'name', 'uuid', rule_type=rule_table, jwt=jwt, import_id=import_id, mgm_id=mgm_details['id']) - dst_ref_all = resolve_raw_objects("all", list_delimiter, full_config, 'name', 'uuid', rule_type=rule_table, jwt=jwt, import_id=import_id, mgm_id=mgm_details['id']) - for localPkgName in full_config[rule_table]: - dev_id = get_device_from_package(localPkgName, mgm_details) - if dev_id is None: - logger.info('normalize_access_rules - no matching device found for package "' + localPkgName + '" in rule_table ' + rule_table) - else: - rule_number, first_v4, first_v6 = insert_headers(rule_table, first_v6, first_v4, full_config, rules, import_id, localPkgName,src_ref_all,dst_ref_all,rule_number) - - for rule_orig in full_config[rule_table][localPkgName]: - rule = {'rule_src': '', 'rule_dst': '', 'rule_svc': ''} - xlate_rule = None - rule.update({ 'control_id': import_id}) - rule.update({ 'rulebase_name': localPkgName}) # the rulebase_name will be set to the pkg_name as there is no rulebase_name in FortiMangaer - rule.update({ 'rule_ruleid': rule_orig['policyid']}) - rule.update({ 'rule_uid': rule_orig['uuid']}) - rule.update({ 'rule_num': rule_number}) - if 'name' in rule_orig: - rule.update({ 'rule_name': rule_orig['name']}) - rule.update({ 'rule_installon': None }) - rule.update({ 'rule_implied': False }) - rule.update({ 'rule_time': None }) - rule.update({ 'rule_type': 'access' }) - rule.update({ 'parent_rule_id': None }) - - if 'comments' in rule_orig: - rule.update({ 'rule_comment': rule_orig['comments']}) - else: - rule.update({ 'rule_comment': None }) - if rule_orig['action']==0: - rule.update({ 'rule_action': 'Drop' }) - else: - rule.update({ 'rule_action': 'Accept' }) - if 'status' in rule_orig and (rule_orig['status']=='enable' or rule_orig['status']==1): - rule.update({ 'rule_disabled': False }) - else: - rule.update({ 'rule_disabled': True }) - if rule_orig['logtraffic'] == 'disable': - rule.update({ 'rule_track': 'None'}) - else: - rule.update({ 'rule_track': 'Log'}) - - if '_last_hit' not in rule_orig or rule_orig['_last_hit'] == 0: - rule.update({ 'last_hit': None}) - else: - rule.update({ 'last_hit': time.strftime("%Y-%m-%d", time.localtime(rule_orig['_last_hit']))}) - - rule['rule_src'] = extend_string_list(rule['rule_src'], rule_orig, 'srcaddr', list_delimiter, jwt=jwt, import_id=import_id) - rule['rule_dst'] = extend_string_list(rule['rule_dst'], rule_orig, 'dstaddr', list_delimiter, jwt=jwt, import_id=import_id) - rule['rule_svc'] = extend_string_list(rule['rule_svc'], rule_orig, 'service', list_delimiter, jwt=jwt, import_id=import_id) - rule['rule_src'] = extend_string_list(rule['rule_src'], rule_orig, 'srcaddr6', list_delimiter, jwt=jwt, import_id=import_id) - rule['rule_dst'] = extend_string_list(rule['rule_dst'], rule_orig, 'dstaddr6', list_delimiter, jwt=jwt, import_id=import_id) - - if len(rule_orig['srcintf'])>0: - src_obj_zone = fmgr_zone.add_zone_if_missing (config2import, rule_orig['srcintf'][0], import_id) - rule.update({ 'rule_from_zone': src_obj_zone }) # todo: currently only using the first zone - if len(rule_orig['dstintf'])>0: - dst_obj_zone = fmgr_zone.add_zone_if_missing (config2import, rule_orig['dstintf'][0], import_id) - rule.update({ 'rule_to_zone': dst_obj_zone }) # todo: currently only using the first zone - - rule.update({ 'rule_src_neg': rule_orig['srcaddr-negate']=='disable'}) - rule.update({ 'rule_dst_neg': rule_orig['dstaddr-negate']=='disable'}) - rule.update({ 'rule_svc_neg': rule_orig['service-negate']=='disable'}) - - rule.update({ 'rule_src_refs': resolve_raw_objects(rule['rule_src'], list_delimiter, full_config, 'name', 'uuid', \ - rule_type=rule_table, jwt=jwt, import_id=import_id, rule_uid=rule_orig['uuid'], object_type='network object', mgm_id=mgm_details['id']) }) - rule.update({ 'rule_dst_refs': resolve_raw_objects(rule['rule_dst'], list_delimiter, full_config, 'name', 'uuid', \ - rule_type=rule_table, jwt=jwt, import_id=import_id, rule_uid=rule_orig['uuid'], object_type='network object', mgm_id=mgm_details['id']) }) - rule.update({ 'rule_svc_refs': rule['rule_svc'] }) # services do not have uids, so using name instead - add_users_to_rule(rule_orig, rule) - - xlate_rule = handle_combined_nat_rule(rule, rule_orig, config2import, nat_rule_number, import_id, localPkgName, dev_id) - rules.append(rule) - if xlate_rule is not None: - rules.append(xlate_rule) - rule_number += 1 # nat rules have their own numbering - config2import.update({'rules': rules}) - - -# pure nat rules -def normalize_nat_rules(full_config, config2import, import_id, jwt=None): - nat_rules = [] - rule_number = 0 - - for rule_table in rule_nat_scope: - for localPkgName in full_config['rules_global_nat']: - for rule_orig in full_config[rule_table][localPkgName]: - rule = {'rule_src': '', 'rule_dst': '', 'rule_svc': ''} - if rule_orig['nat'] == 1: # assuming source nat - rule.update({ 'control_id': import_id}) - rule.update({ 'rulebase_name': localPkgName}) # the rulebase_name just has to be a unique string among devices - rule.update({ 'rule_ruleid': rule_orig['policyid']}) - rule.update({ 'rule_uid': rule_orig['uuid']}) - # rule.update({ 'rule_num': rule_orig['obj seq']}) - rule.update({ 'rule_num': rule_number }) - if 'comments' in rule_orig: - rule.update({ 'rule_comment': rule_orig['comments']}) - rule.update({ 'rule_action': 'Drop' }) # not used for nat rules - rule.update({ 'rule_track': 'None'}) # not used for nat rules - - rule['rule_src'] = extend_string_list(rule['rule_src'], rule_orig, 'orig-addr', list_delimiter, jwt=jwt, import_id=import_id) - rule['rule_dst'] = extend_string_list(rule['rule_dst'], rule_orig, 'dst-addr', list_delimiter, jwt=jwt, import_id=import_id) - - if rule_orig['protocol']==17: - svc_name = 'udp_' + str(rule_orig['orig-port']) - elif rule_orig['protocol']==6: - svc_name = 'tcp_' + str(rule_orig['orig-port']) - else: - svc_name = 'svc_' + str(rule_orig['orig-port']) - # need to create a helper service object and add it to the nat rule, also needs to be added to service list - - if not 'service_objects' in config2import: # is normally defined - config2import['service_objects'] = [] - config2import['service_objects'].append(create_svc_object( \ - import_id=import_id, name=svc_name, proto=rule_orig['protocol'], port=rule_orig['orig-port'], comment='service created by FWO importer for NAT purposes')) - rule['rule_svc'] = svc_name - - #rule['rule_src'] = extend_string_list(rule['rule_src'], rule_orig, 'srcaddr6', list_delimiter, jwt=jwt, import_id=import_id) - #rule['rule_dst'] = extend_string_list(rule['rule_dst'], rule_orig, 'dstaddr6', list_delimiter, jwt=jwt, import_id=import_id) - - if len(rule_orig['srcintf'])>0: - rule.update({ 'rule_from_zone': rule_orig['srcintf'][0] }) # todo: currently only using the first zone - if len(rule_orig['dstintf'])>0: - rule.update({ 'rule_to_zone': rule_orig['dstintf'][0] }) # todo: currently only using the first zone - - rule.update({ 'rule_src_neg': False}) - rule.update({ 'rule_dst_neg': False}) - rule.update({ 'rule_svc_neg': False}) - rule.update({ 'rule_src_refs': resolve_raw_objects(rule['rule_src'], list_delimiter, full_config, 'name', 'uuid', rule_type=rule_table) }, \ - jwt=jwt, import_id=import_id, rule_uid=rule_orig['uuid'], object_type='network object') - rule.update({ 'rule_dst_refs': resolve_raw_objects(rule['rule_dst'], list_delimiter, full_config, 'name', 'uuid', rule_type=rule_table) }, \ - jwt=jwt, import_id=import_id, rule_uid=rule_orig['uuid'], object_type='network object') - # services do not have uids, so using name instead - rule.update({ 'rule_svc_refs': rule['rule_svc'] }) - rule.update({ 'rule_type': 'original' }) - rule.update({ 'rule_installon': None }) - if 'status' in rule_orig and (rule_orig['status']=='enable' or rule_orig['status']==1): - rule.update({ 'rule_disabled': False }) - else: - rule.update({ 'rule_disabled': True }) - rule.update({ 'rule_implied': False }) - rule.update({ 'rule_time': None }) - rule.update({ 'parent_rule_id': None }) - - nat_rules.append(rule) - add_users_to_rule(rule_orig, rule) - - ############## now adding the xlate rule part ########################## - xlate_rule = dict(rule) # copy the original (match) rule - xlate_rule.update({'rule_src': '', 'rule_dst': '', 'rule_svc': ''}) - xlate_rule['rule_src'] = extend_string_list(xlate_rule['rule_src'], rule_orig, 'orig-addr', list_delimiter, jwt=jwt, import_id=import_id) - xlate_rule['rule_dst'] = 'Original' - - if rule_orig['protocol']==17: - svc_name = 'udp_' + str(rule_orig['nat-port']) - elif rule_orig['protocol']==6: - svc_name = 'tcp_' + str(rule_orig['nat-port']) - else: - svc_name = 'svc_' + str(rule_orig['nat-port']) - # need to create a helper service object and add it to the nat rule, also needs to be added to service list! - # fmgr_service.create_svc_object(name=svc_name, proto=rule_orig['protocol'], port=rule_orig['orig-port'], comment='service created by FWO importer for NAT purposes') - config2import['service_objects'].append(create_svc_object(import_id=import_id, name=svc_name, proto=rule_orig['protocol'], port=rule_orig['nat-port'], comment='service created by FWO importer for NAT purposes')) - xlate_rule['rule_svc'] = svc_name - - xlate_rule.update({ 'rule_src_refs': resolve_objects(xlate_rule['rule_src'], list_delimiter, full_config, 'name', 'uuid', rule_type=rule_table, jwt=jwt, import_id=import_id ) }) - xlate_rule.update({ 'rule_dst_refs': resolve_objects(xlate_rule['rule_dst'], list_delimiter, full_config, 'name', 'uuid', rule_type=rule_table, jwt=jwt, import_id=import_id ) }) - xlate_rule.update({ 'rule_svc_refs': xlate_rule['rule_svc'] }) # services do not have uids, so using name instead - - xlate_rule.update({ 'rule_type': 'xlate' }) - - nat_rules.append(xlate_rule) - rule_number += 1 - config2import['rules'].extend(nat_rules) - - -def insert_header(rules, import_id, header_text, rulebase_name, rule_uid, rule_number, src_refs, dst_refs): - rule = { - "control_id": import_id, - "rule_head_text": header_text, - "rulebase_name": rulebase_name, - "rule_ruleid": None, - "rule_uid": rule_uid + rulebase_name, - "rule_num": rule_number, - "rule_disabled": False, - "rule_src": "all", - "rule_dst": "all", - "rule_svc": "ALL", - "rule_src_neg": False, - "rule_dst_neg": False, - "rule_svc_neg": False, - "rule_src_refs": src_refs, - "rule_dst_refs": dst_refs, - "rule_svc_refs": "ALL", - "rule_action": "Accept", - "rule_track": "None", - "rule_installon": None, - "rule_time": None, - "rule_type": "access", - "parent_rule_id": None, - "rule_implied": False, - "rule_comment": None - } - rules.append(rule) - - -def create_xlate_rule(rule): - xlate_rule = copy.deepcopy(rule) - rule['rule_type'] = 'combined' - xlate_rule['rule_type'] = 'xlate' - xlate_rule['rule_comment'] = None - xlate_rule['rule_disabled'] = False - xlate_rule['rule_src'] = 'Original' - xlate_rule['rule_src_refs'] = 'Original' - xlate_rule['rule_dst'] = 'Original' - xlate_rule['rule_dst_refs'] = 'Original' - xlate_rule['rule_svc'] = 'Original' - xlate_rule['rule_svc_refs'] = 'Original' - return xlate_rule - - -def handle_combined_nat_rule(rule, rule_orig, config2import, nat_rule_number, import_id, localPkgName, dev_id): - # now dealing with VIPs (dst NAT part) of combined rules - logger = getFwoLogger() - xlate_rule = None - - # dealing with src NAT part of combined rules - if "nat" in rule_orig and rule_orig["nat"]==1: - logger.debug("found mixed Access/NAT rule no. " + str(nat_rule_number)) - nat_rule_number += 1 - xlate_rule = create_xlate_rule(rule) - if 'ippool' in rule_orig: - if rule_orig['ippool']==0: # hiding behind outbound interface - interface_name = 'unknownIF' - destination_interface_ip = '0.0.0.0' - destination_ip = get_first_ip_of_destination(rule['rule_dst_refs'], config2import) # get an ip of destination - hideInterface = 'undefined_interface' - if destination_ip is None: - logger.warning('src nat behind interface: found no valid destination ip in rule with UID ' + rule['rule_uid']) - else: - # matching_route = get_matching_route_obj(destination_ip, config2import['networking'][device_name]['routingv4']) - matching_route = get_matching_route_obj(destination_ip, config2import['routing'], dev_id) - if matching_route is None: - logger.warning('src nat behind interface: found no matching route in rule with UID ' - + rule['rule_uid'] + ', dest_ip: ' + destination_ip) - else: - destination_interface_ip = get_ip_of_interface_obj(matching_route.interface, dev_id, config2import['interfaces']) - interface_name = matching_route.interface - hideInterface=interface_name - if hideInterface is None: - logger.warning('src nat behind interface: found route with undefined interface ' + str(jsonpickle.dumps(matching_route, unpicklable=True))) - if destination_interface_ip is None: - logger.warning('src nat behind interface: found no matching interface IP in rule with UID ' - + rule['rule_uid'] + ', dest_ip: ' + destination_ip) - - # add dummy object "outbound-interface" - if hideInterface is not None: - obj_name = 'hide_IF_ip_' + str(hideInterface) + '_' + str(destination_interface_ip) - obj_comment = 'FWO auto-generated dummy object for source nat' - if type(ipaddress.ip_address(str(destination_interface_ip))) is ipaddress.IPv6Address: - HideNatIp = str(destination_interface_ip) + '/128' - elif type(ipaddress.ip_address(str(destination_interface_ip))) is ipaddress.IPv4Address: - HideNatIp = str(destination_interface_ip) + '/32' - else: - HideNatIp = '0.0.0.0/32' - logger.warning('found invalid HideNatIP ' + str(destination_interface_ip)) - obj = create_network_object(import_id, obj_name, 'host', HideNatIp, obj_name, 'black', obj_comment, 'global') - if obj not in config2import['network_objects']: - config2import['network_objects'].append(obj) - xlate_rule['rule_src'] = obj_name - xlate_rule['rule_src_refs'] = obj_name - - elif rule_orig['ippool']==1: # hiding behind one ip of an ip pool - poolNameArray = rule_orig['poolname'] - if len(poolNameArray)>0: - if len(poolNameArray)>1: - logger.warning("found more than one ippool - ignoring all but first pool") - poolName = poolNameArray[0] - xlate_rule['rule_src'] = poolName - xlate_rule['rule_src_refs'] = poolName - else: - logger.warning("found ippool rule without ippool: " + rule['rule_uid']) - else: - logger.warning("found ippool rule with unexpected ippool value: " + rule_orig['ippool']) - - if 'natip' in rule_orig and rule_orig['natip']!=["0.0.0.0","0.0.0.0"]: - logger.warning("found explicit natip rule - ignoring for now: " + rule['rule_uid']) - # need example for interpretation of config - - # todo: find out how match-vip=1 influences natting (only set in a few vip-nat rules) - # if "match-vip" in rule_orig and rule_orig["match-vip"]==1: - # logger.warning("found VIP destination Access/NAT rule (but not parsing yet); no. " + str(vip_nat_rule_number)) - # vip_nat_rule_number += 1 - - # deal with vip natting: check for each (dst) nw obj if it contains "obj_nat_ip" - rule_dst_list = rule['rule_dst'].split(list_delimiter) - nat_object_list = extract_nat_objects(rule_dst_list, config2import['network_objects']) - - if len(nat_object_list)>0: - if xlate_rule is None: # no source nat, so we create the necessary nat rule here - xlate_rule = create_xlate_rule(rule) - xlate_dst = [] - xlate_dst_refs = [] - for nat_obj in nat_object_list: - if 'obj_ip_end' in nat_obj: # this nat obj is a range - include the end ip in name and uid as well to avoid akey conflicts - xlate_dst.append(nat_obj['obj_nat_ip'] + '-' + nat_obj['obj_ip_end'] + nat_postfix) - nat_ref = nat_obj['obj_nat_ip'] - if 'obj_nat_ip_end' in nat_obj: - nat_ref += '-' + nat_obj['obj_nat_ip_end'] + nat_postfix - xlate_dst_refs.append(nat_ref) - else: - xlate_dst.append(nat_obj['obj_nat_ip'] + nat_postfix) - xlate_dst_refs.append(nat_obj['obj_nat_ip'] + nat_postfix) - xlate_rule['rule_dst'] = list_delimiter.join(xlate_dst) - xlate_rule['rule_dst_refs'] = list_delimiter.join(xlate_dst_refs) - # else: (no nat object found) no dnatting involved, dst stays "Original" - - return xlate_rule - - -def insert_headers(rule_table, first_v6, first_v4, full_config, rules, import_id, localPkgName,src_ref_all,dst_ref_all,rule_number): - if rule_table in rule_access_scope_v6 and first_v6: - insert_header(rules, import_id, "IPv6 rules", localPkgName, "IPv6HeaderText", rule_number, src_ref_all, dst_ref_all) - rule_number += 1 - first_v6 = False - elif rule_table in rule_access_scope_v4 and first_v4: - insert_header(rules, import_id, "IPv4 rules", localPkgName, "IPv4HeaderText", rule_number, src_ref_all, dst_ref_all) - rule_number += 1 - first_v4 = False - if rule_table == 'rules_adom_v4' and len(full_config['rules_adom_v4'][localPkgName])>0: - insert_header(rules, import_id, "Adom Rules IPv4", localPkgName, "IPv4AdomRules", rule_number, src_ref_all, dst_ref_all) - rule_number += 1 - elif rule_table == 'rules_adom_v6' and len(full_config['rules_adom_v6'][localPkgName])>0: - insert_header(rules, import_id, "Adom Rules IPv6", localPkgName, "IPv6AdomRules", rule_number, src_ref_all, dst_ref_all) - rule_number += 1 - elif rule_table == 'rules_global_header_v4' and len(full_config['rules_global_header_v4'][localPkgName])>0: - insert_header(rules, import_id, "Global Header Rules IPv4", localPkgName, "IPv4GlobalHeaderRules", rule_number, src_ref_all, dst_ref_all) - rule_number += 1 - elif rule_table == 'rules_global_header_v6' and len(full_config['rules_global_header_v6'][localPkgName])>0: - insert_header(rules, import_id, "Global Header Rules IPv6", localPkgName, "IPv6GlobalHeaderRules", rule_number, src_ref_all, dst_ref_all) - rule_number += 1 - elif rule_table == 'rules_global_footer_v4' and len(full_config['rules_global_footer_v4'][localPkgName])>0: - insert_header(rules, import_id, "Global Footer Rules IPv4", localPkgName, "IPv4GlobalFooterRules", rule_number, src_ref_all, dst_ref_all) - rule_number += 1 - elif rule_table == 'rules_global_footer_v6' and len(full_config['rules_global_footer_v6'][localPkgName])>0: - insert_header(rules, import_id, "Global Footer Rules IPv6", localPkgName, "IPv6GlobalFooterRules", rule_number, src_ref_all, dst_ref_all) - rule_number += 1 - return rule_number, first_v4, first_v6 - - -def extract_nat_objects(nwobj_list, all_nwobjects): - nat_obj_list = [] - for obj in nwobj_list: - for obj2 in all_nwobjects: - if obj2['obj_name']==obj: - if 'obj_nat_ip' in obj2: - nat_obj_list.append(obj2) - break - # if obj in all_nwobjects and 'obj_nat_ip' in all_nwobjects[obj]: - # nat_obj_list.append(obj) - return nat_obj_list - - -def add_users_to_rule(rule_orig, rule): - if 'groups' in rule_orig: - add_users(rule_orig['groups'], rule) - if 'users' in rule_orig: - add_users(rule_orig['users'], rule) - - -def add_users(users, rule): - for user in users: - rule_src_with_users = [] - for src in rule['rule_src'].split(list_delimiter): - rule_src_with_users.append(user + '@' + src) - rule['rule_src'] = list_delimiter.join(rule_src_with_users) - - # here user ref is the user name itself - rule_src_refs_with_users = [] - for src in rule['rule_src_refs'].split(list_delimiter): - rule_src_refs_with_users.append(user + '@' + src) - rule['rule_src_refs'] = list_delimiter.join(rule_src_refs_with_users) diff --git a/roles/importer/files/importer/fortiadom5ff/fmgr_service.py b/roles/importer/files/importer/fortiadom5ff/fmgr_service.py deleted file mode 100644 index 19cdb947c1..0000000000 --- a/roles/importer/files/importer/fortiadom5ff/fmgr_service.py +++ /dev/null @@ -1,198 +0,0 @@ -import re -from fwo_const import list_delimiter - -def normalize_svcobjects(full_config, config2import, import_id, scope): - svc_objects = [] - for s in scope: - for obj_orig in full_config[s]: - member_names = '' - if 'member' in obj_orig: - type = 'group' - for member in obj_orig['member']: - member_names += member + list_delimiter - member_names = member_names[:-1] - else: - type = 'simple' - - name = None - if 'name' in obj_orig: - name = str(obj_orig['name']) - - color = None - if 'color' in obj_orig and str(obj_orig['color']) != 0: - color = str(obj_orig['color']) - - session_timeout = None # todo: find the right timer - # if 'udp-idle-timer' in obj_orig and str(obj_orig['udp-idle-timer']) != 0: - # session_timeout = str(obj_orig['udp-idle-timer']) - - proto = 0 - range_names = '' - if 'protocol' in obj_orig: - added_svc_obj = 0 - if obj_orig['protocol'] == 1: - addObject(svc_objects, type, name, color, 1, None, None, session_timeout, import_id) - added_svc_obj += 1 - elif obj_orig['protocol'] == 2: - if 'protocol-number' in obj_orig: - proto = obj_orig['protocol-number'] - addObject(svc_objects, type, name, color, proto, None, None, session_timeout, import_id) - added_svc_obj += 1 - elif obj_orig['protocol'] == 5 or obj_orig['protocol'] == 11: - split = check_split(obj_orig) - if "tcp-portrange" in obj_orig and len(obj_orig['tcp-portrange']) > 0: - tcpname = name - if split: - tcpname += "_tcp" - range_names += tcpname + list_delimiter - addObject(svc_objects, type, tcpname, color, 6, obj_orig['tcp-portrange'], None, session_timeout, import_id) - added_svc_obj += 1 - if "udp-portrange" in obj_orig and len(obj_orig['udp-portrange']) > 0: - udpname = name - if split: - udpname += "_udp" - range_names += udpname + list_delimiter - addObject(svc_objects, type, udpname, color, 17, obj_orig['udp-portrange'], None, session_timeout, import_id) - added_svc_obj += 1 - if "sctp-portrange" in obj_orig and len(obj_orig['sctp-portrange']) > 0: - sctpname = name - if split: - sctpname += "_sctp" - range_names += sctpname + list_delimiter - addObject(svc_objects, type, sctpname, color, 132, obj_orig['sctp-portrange'], None, session_timeout, import_id) - added_svc_obj += 1 - if split: - range_names = range_names[:-1] - addObject(svc_objects, 'group', name, color, 0, None, range_names, session_timeout, import_id) - added_svc_obj += 1 - if added_svc_obj==0: # assuming RPC service which here has no properties at all - addObject(svc_objects, 'rpc', name, color, 0, None, None, None, import_id) - added_svc_obj += 1 - elif obj_orig['protocol'] == 6: - addObject(svc_objects, type, name, color, 58, None, None, session_timeout, import_id) - elif type == 'group': - addObject(svc_objects, type, name, color, 0, None, member_names, session_timeout, import_id) - else: - addObject(svc_objects, type, name, color, 0, None, None, session_timeout, import_id) - - # finally add "Original" service object for natting - original_obj_name = 'Original' - svc_objects.append(create_svc_object(import_id=import_id, name=original_obj_name, proto=0, port=None,\ - comment='"original" service object created by FWO importer for NAT purposes')) - - config2import.update({'service_objects': svc_objects}) - - -def check_split(obj_orig): - count = 0 - if "tcp-portrange" in obj_orig and len(obj_orig['tcp-portrange']) > 0: - count += 1 - if "udp-portrange" in obj_orig and len(obj_orig['udp-portrange']) > 0: - count += 1 - if "sctp-portrange" in obj_orig and len(obj_orig['sctp-portrange']) > 0: - count += 1 - return (count > 1) - - -def extractPorts(port_ranges): - ports = [] - port_ends = [] - if port_ranges is not None and len(port_ranges) > 0: - for port_range in port_ranges: - # remove src-ports - port = port_range.split(':')[0] - port_end = port - - # open ranges (not found so far in data) - pattern = re.compile('^\>(\d+)$') - match = pattern.match(port) - if match: - port = str(int(match.group()[1:]) + 1) - port_end = str(65535) - pattern = re.compile('^\<(\d+)$') - match = pattern.match(port) - if match: - port = str(1) - port_end = str(int(match.group()[1:]) - 1) - - # split ranges - pattern = re.compile('^(\d+)\-(\d+)$') - match = pattern.match(port) - if match: - port, port_end = match.group().split('-') - ports.append(port) - port_ends.append(port_end) - return ports, port_ends - - - -def create_svc_object(import_id, name, proto, port, comment): - return { - 'control_id': import_id, - 'svc_name': name, - 'svc_typ': 'simple', - 'svc_port': port, - 'ip_proto': proto, - 'svc_uid': name, # services have no uid in fortimanager - 'svc_comment': comment - } - - - -def addObject(svc_objects, type, name, color, proto, port_ranges, member_names, session_timeout, import_id): - if port_ranges is None: - svc_objects.extend([{'svc_typ': type, - 'svc_name': name, - 'svc_color': color, - 'svc_uid': name, # ? - 'svc_comment': None, # ? - 'ip_proto': proto, - 'svc_port': None, - 'svc_port_end': None, - 'svc_member_refs': member_names, # ? - 'svc_member_names': member_names, - 'svc_timeout': session_timeout, - 'rpc_nr': None, # ? - 'control_id': import_id - }]) - else: - range_names = '' - ports, port_ends = extractPorts(port_ranges) - split = (len(ports) > 1) - for index, port in enumerate(ports): - port_end = port_ends[index] - full_name = name - if split: - full_name += '_' + str(port) - range_names += full_name + list_delimiter - svc_objects.extend([{'svc_typ': type, - 'svc_name': full_name, - 'svc_color': color, - 'svc_uid': full_name, # ? - 'svc_comment': None, # ? - 'ip_proto': proto, - 'svc_port': port, - 'svc_port_end': port_end, - 'svc_member_refs': member_names, # ? - 'svc_member_names': member_names, - 'svc_timeout': session_timeout, - 'rpc_nr': None, # ? - 'control_id': import_id - }]) - if split: - range_names = range_names[:-1] - svc_objects.extend([{'svc_typ': 'group', - 'svc_name': name, - 'svc_color': color, - 'svc_uid': name, # ? - 'svc_comment': None, # ? - 'ip_proto': proto, - 'svc_port': None, - 'svc_port_end': None, - 'svc_member_refs': range_names, # ? - 'svc_member_names': range_names, - 'svc_timeout': session_timeout, - 'rpc_nr': None, # ? - 'control_id': import_id - }]) - diff --git a/roles/importer/files/importer/fortiadom5ff/fmgr_user.py b/roles/importer/files/importer/fortiadom5ff/fmgr_user.py deleted file mode 100644 index c8323694b7..0000000000 --- a/roles/importer/files/importer/fortiadom5ff/fmgr_user.py +++ /dev/null @@ -1,36 +0,0 @@ -from fwo_const import list_delimiter - -def normalize_users(full_config, config2import, import_id, user_scope): - users = [] - for scope in user_scope: - for user_orig in full_config[scope]: - name = None - type = 'simple' - color = None - member_names = None - comment = None - - if 'member' in user_orig: - type = 'group' - member_names = '' - for member in user_orig['member']: - member_names += member + list_delimiter - member_names = member_names[:-1] - if 'name' in user_orig: - name = str(user_orig['name']) - if 'comment' in user_orig: - comment = str(user_orig['comment']) - if 'color' in user_orig and str(user_orig['color']) != 0: - color = str(user_orig['color']) - - users.extend([{'user_typ': type, - 'user_name': name, - 'user_color': color, - 'user_uid': name, - 'user_comment': comment, - 'user_member_refs': member_names, - 'user_member_names': member_names, - 'control_id': import_id - }]) - - config2import.update({'user_objects': users}) diff --git a/roles/importer/files/importer/fortiadom5ff/fmgr_zone.py b/roles/importer/files/importer/fortiadom5ff/fmgr_zone.py deleted file mode 100644 index b9e41a1e68..0000000000 --- a/roles/importer/files/importer/fortiadom5ff/fmgr_zone.py +++ /dev/null @@ -1,29 +0,0 @@ - -def normalize_zones(full_config, config2import, import_id): - zones = [] - for orig_zone in full_config['zone_objects']['zone_list']: - zone = {} - zone.update({'zone_name': orig_zone}) - zone.update({'control_id': import_id}) - zones.append(zone) - - config2import.update({'zone_objects': zones}) - - -def add_zone_if_missing (config2import, zone_string, import_id): - # adding zone if it not yet exists - - # also transforming any into global (normalized global zone) - if zone_string == 'any': - zone_string = 'global' - if zone_string is not None: - if 'zone_objects' not in config2import: # no zones yet? add empty zone_objects array - config2import.update({'zone_objects': []}) - zone_exists = False - for zone in config2import['zone_objects']: - if zone_string == zone['zone_name']: - zone_exists = True - if not zone_exists: - config2import['zone_objects'].append({'zone_name': zone_string, 'control_id': import_id}) - return zone_string - \ No newline at end of file diff --git a/roles/importer/files/importer/fortiadom5ff/fwcommon.py b/roles/importer/files/importer/fortiadom5ff/fwcommon.py deleted file mode 100644 index 49494ab2be..0000000000 --- a/roles/importer/files/importer/fortiadom5ff/fwcommon.py +++ /dev/null @@ -1,172 +0,0 @@ -import sys -from common import importer_base_dir -sys.path.append(importer_base_dir + '/fortiadom5ff') -import fmgr_user -import fmgr_service -import fmgr_zone -import fmgr_rule -import fmgr_network -import fmgr_getter -from curses import raw -from fwo_log import getFwoLogger -from fmgr_gw_networking import getInterfacesAndRouting, normalize_network_data -from fwo_data_networking import get_ip_of_interface_obj - -scope = ['global', 'adom'] -nw_obj_types = ['firewall/address', 'firewall/address6', 'firewall/addrgrp', - 'firewall/addrgrp6', 'firewall/ippool', 'firewall/vip'] -svc_obj_types = ['application/list', 'application/group', 'application/categories', - 'application/custom', 'firewall/service/custom', 'firewall/service/group'] - -# build the product of all scope/type combinations -nw_obj_scope = ['nw_obj_' + s1 + '_' + - s2 for s1 in scope for s2 in nw_obj_types] -svc_obj_scope = ['svc_obj_' + s1 + '_' + - s2 for s1 in scope for s2 in svc_obj_types] - -# zone_types = ['zones_global', 'zones_adom'] - -user_obj_types = ['user/local', 'user/group'] -user_scope = ['user_obj_' + s1 + '_' + - s2 for s1 in scope for s2 in user_obj_types] - - -def has_config_changed(full_config, mgm_details, force=False): - # dummy - may be filled with real check later on - return True - - -def get_config(config2import, full_config, current_import_id, mgm_details, limit=100, force=False, jwt=''): - logger = getFwoLogger() - if full_config == {}: # no native config was passed in, so getting it from FortiManager - parsing_config_only = False - else: - parsing_config_only = True - - # fmgr API login - if not parsing_config_only: # no native config was passed in, so getting it from FortiManager - fm_api_url = 'https://' + \ - mgm_details['hostname'] + ':' + \ - str(mgm_details['port']) + '/jsonrpc' - sid = fmgr_getter.login(mgm_details['import_credential']['user'], mgm_details['import_credential']['secret'], fm_api_url) - if sid is None: - logger.error('did not succeed in logging in to FortiManager API, no sid returned') - return 1 - - adom_name = mgm_details['configPath'] - if adom_name is None: - logger.error('no ADOM name set for management ' + mgm_details['id']) - return 1 - else: - if not parsing_config_only: # no native config was passed in, so getting it from FortiManager - getObjects(sid, fm_api_url, full_config, adom_name, limit, scope, nw_obj_types, svc_obj_types) - # currently reading zone from objects/rules for backward compat with FortiManager 6.x - # getZones(sid, fm_api_url, full_config, adom_name, limit, debug_level) - getInterfacesAndRouting( - sid, fm_api_url, full_config, adom_name, mgm_details['devices'], limit) - - # initialize all rule dicts - fmgr_rule.initializeRulebases(full_config) - for dev in mgm_details['devices']: - fmgr_rule.getAccessPolicy( - sid, fm_api_url, full_config, adom_name, dev, limit) - fmgr_rule.getNatPolicy( - sid, fm_api_url, full_config, adom_name, dev, limit) - - try: # logout of fortimanager API - fmgr_getter.logout( - fm_api_url, sid) - except: - logger.warning("logout exception probably due to timeout - irrelevant, so ignoring it") - - # now we normalize relevant parts of the raw config and write the results to config2import dict - # currently reading zone from objects for backward compat with FortiManager 6.x - # fmgr_zone.normalize_zones(full_config, config2import, current_import_id) - - # write normalized networking data to config2import - # this is currently not written to the database but only used for natting decisions - # later we will probably store the networking info in the database as well as a basis - # for path analysis - - normalize_network_data(full_config, config2import, mgm_details) - - fmgr_user.normalize_users( - full_config, config2import, current_import_id, user_scope) - fmgr_network.normalize_nwobjects( - full_config, config2import, current_import_id, nw_obj_scope, jwt=jwt, mgm_id=mgm_details['id']) - fmgr_service.normalize_svcobjects( - full_config, config2import, current_import_id, svc_obj_scope) - fmgr_user.normalize_users( - full_config, config2import, current_import_id, user_scope) - fmgr_rule.normalize_access_rules( - full_config, config2import, current_import_id, mgm_details=mgm_details, jwt=jwt) - fmgr_rule.normalize_nat_rules( - full_config, config2import, current_import_id, jwt=jwt) - fmgr_network.remove_nat_ip_entries(config2import) - return 0 - - -def getObjects(sid, fm_api_url, raw_config, adom_name, limit, scope, nw_obj_types, svc_obj_types): - # get those objects that exist globally and on adom level - for s in scope: - # get network objects: - for object_type in nw_obj_types: - if s == 'adom': - adom_scope = 'adom/'+adom_name - else: - adom_scope = s - fmgr_getter.update_config_with_fortinet_api_call( - raw_config, sid, fm_api_url, "/pm/config/"+adom_scope+"/obj/" + object_type, "nw_obj_" + s + "_" + object_type, limit=limit) - - # get service objects: - # service/custom is an undocumented API call! - for object_type in svc_obj_types: - if s == 'adom': - adom_scope = 'adom/'+adom_name - else: - adom_scope = s - fmgr_getter.update_config_with_fortinet_api_call( - raw_config, sid, fm_api_url, "/pm/config/"+adom_scope+"/obj/" + object_type, "svc_obj_" + s + "_" + object_type, limit=limit) - - # user: /pm/config/global/obj/user/local, /pm/config/global/obj/user/group - # get user objects: - for object_type in user_obj_types: - if s == 'adom': - adom_scope = 'adom/'+adom_name - else: - adom_scope = s - fmgr_getter.update_config_with_fortinet_api_call( - raw_config, sid, fm_api_url, "/pm/config/"+adom_scope+"/obj/" + object_type, "user_obj_" + s + "_" + object_type, limit=limit) - - -# def getZones(sid, fm_api_url, raw_config, adom_name, limit, debug_level): -# raw_config.update({"zones": {}}) - -# # get global zones? - -# # get local zones -# for device in raw_config['devices']: -# local_pkg_name = device['package'] -# for adom in raw_config['adoms']: -# if adom['name']==adom_name: -# if local_pkg_name not in adom['package_names']: -# logger.error('local rulebase/package ' + local_pkg_name + ' not found in management ' + adom_name) -# return 1 -# else: -# fmgr_getter.update_config_with_fortinet_api_call( -# raw_config['zones'], sid, fm_api_url, "/pm/config/adom/" + adom_name + "/obj/dynamic/interface", device['id'], debug=debug_level, limit=limit) - -# raw_config['zones']['zone_list'] = [] -# for device in raw_config['zones']: -# for mapping in raw_config['zones'][device]: -# if not isinstance(mapping, str): -# if not mapping['dynamic_mapping'] is None: -# for dyn_mapping in mapping['dynamic_mapping']: -# if 'name' in dyn_mapping and not dyn_mapping['name'] in raw_config['zones']['zone_list']: -# raw_config['zones']['zone_list'].append(dyn_mapping['name']) -# if 'local-intf' in dyn_mapping and not dyn_mapping['local-intf'][0] in raw_config['zones']['zone_list']: -# raw_config['zones']['zone_list'].append(dyn_mapping['local-intf'][0]) -# if not mapping['platform_mapping'] is None: -# for dyn_mapping in mapping['platform_mapping']: -# if 'intf-zone' in dyn_mapping and not dyn_mapping['intf-zone'] in raw_config['zones']['zone_list']: -# raw_config['zones']['zone_list'].append(dyn_mapping['intf-zone']) diff --git a/roles/importer/files/importer/fortiosmanagementREST/fOS_common.py b/roles/importer/files/importer/fortiosmanagementREST/fOS_common.py deleted file mode 100644 index 154be9d417..0000000000 --- a/roles/importer/files/importer/fortiosmanagementREST/fOS_common.py +++ /dev/null @@ -1,34 +0,0 @@ -import sys -from common import importer_base_dir -sys.path.append(importer_base_dir + '/fortiosmanagementREST') -from curses import raw -from fwo_log import getFwoLogger -from fwo_const import list_delimiter, fwo_config_filename -from fwo_config import readConfig -from fwo_api import setAlert, create_data_issue - - -# TODO: deal with objects with identical names (e.g. all ipv4 & all ipv6) -def resolve_objects (obj_name_string_list, lookup_dict={}, delimiter=list_delimiter, jwt=None, import_id=None, mgm_id=None): - logger = getFwoLogger() - fwo_config = readConfig(fwo_config_filename) - - ref_list = [] - objects_not_found = [] - for el in obj_name_string_list.split(delimiter): - found = False - if el in lookup_dict: - ref_list.append(lookup_dict[el]) - else: - objects_not_found.append(el) - - for obj in objects_not_found: - if obj != 'all' and obj != 'Original': - if not create_data_issue(fwo_config['fwo_api_base_url'], jwt, import_id=import_id, obj_name=obj, severity=1, mgm_id=mgm_id): - logger.warning("resolve_raw_objects: encountered error while trying to log an import data issue using create_data_issue") - - desc = "found a broken object reference '" + obj + "' " - setAlert(fwo_config['fwo_api_base_url'], jwt, import_id=import_id, title="object reference error", mgm_id=mgm_id, severity=1, role='importer', \ - description=desc, source='import', alertCode=16) - - return delimiter.join(ref_list) diff --git a/roles/importer/files/importer/fortiosmanagementREST/fOS_getter.py b/roles/importer/files/importer/fortiosmanagementREST/fOS_getter.py deleted file mode 100644 index 181b476218..0000000000 --- a/roles/importer/files/importer/fortiosmanagementREST/fOS_getter.py +++ /dev/null @@ -1,75 +0,0 @@ -# library for API get functions -import re -from fwo_log import getFwoLogger -import requests.packages -import requests -import json -import fwo_globals -from fwo_exception import FwLoginFailed - - -def api_call(url, show_progress=False): - logger = getFwoLogger() - request_headers = {'Content-Type': 'application/json'} - - r = requests.get(url, headers=request_headers, verify=fwo_globals.verify_certs) - if r is None: - exception_text = "error while sending api_call to url '" + str(url) + "' with headers: '" + json.dumps(request_headers, indent=2) - raise Exception(exception_text) - result_json = r.json() - if 'results' not in result_json: - raise Exception("error while sending api_call to url '" + str(url) + "' with headers: '" + json.dumps(request_headers, indent=2) + ', results=' + json.dumps(r.json()['results'], indent=2)) - if 'status' not in result_json: - # trying to ignore empty results as valid - pass # logger.warning('received empty result') - if fwo_globals.debug_level>2: - logger.debug("api_call to url '" + str(url) + "' with headers: '" + json.dumps(request_headers, indent=2)) - if show_progress: - print('.', end='', flush=True) - return result_json - - -def set_api_url(base_url, testmode, api_supported, hostname): - url = '' - if testmode == 'off': - url = base_url - else: - if re.search(r'^\d+[\.\d+]+$', testmode) or re.search(r'^\d+$', testmode): - if testmode in api_supported: - url = base_url + 'v' + testmode + '/' - else: - raise Exception("api version " + testmode + - " is not supported by the manager " + hostname + " - Import is canceled") - else: - raise Exception("\"" + testmode + "\" - not a valid version") - return url - - -def update_config_with_fortiOS_api_call(config_json, api_url, result_name, show_progress=False, limit=150): - offset = 0 - limit = int(limit) - returned_new_objects = True - full_result = [] - result = fortiOS_api_call(api_url) - full_result.extend(result) - # removing loop for api gets (no limit option in FortiOS API) - # while returned_new_objects: - # range = [offset, limit] - # result = fortiOS_api_call(api_url) - # full_result.extend(result) - # offset += limit - # if len(result) 1: - obj.update({ 'obj_typ': 'network' }) - else: - obj.update({ 'obj_typ': 'host' }) - obj.update({ 'obj_ip': ipa.with_prefixlen }) - elif 'ip6' in obj_orig: # ipv6 object - ipa = ipaddress.ip_network(str(obj_orig['ip6']).replace("\\", "")) - if ipa.num_addresses > 1: - obj.update({ 'obj_typ': 'network' }) - else: - obj.update({ 'obj_typ': 'host' }) - obj.update({ 'obj_ip': ipa.with_prefixlen }) - elif 'member' in obj_orig: # addrgrp4 / addrgrp6 - obj.update({ 'obj_typ': 'group' }) - obj.update({ 'obj_member_names' : list_delimiter.join([d['name'] for d in obj_orig['member']]) }) - obj.update({ 'obj_member_refs' : list_delimiter.join([d['name'] for d in obj_orig['member']]) }) - elif 'startip' in obj_orig: # ippool object - obj.update({ 'obj_typ': 'ip_range' }) - obj.update({ 'obj_ip': obj_orig['startip'] }) - obj.update({ 'obj_ip_end': obj_orig['endip'] }) - elif 'start-ip' in obj_orig: # standard ip range object - obj.update({ 'obj_typ': 'ip_range' }) - obj.update({ 'obj_ip': obj_orig['start-ip'] }) - obj.update({ 'obj_ip_end': obj_orig['end-ip'] }) - elif 'extip' in obj_orig: # vip object, simplifying to a single ip - obj.update({ 'obj_typ': 'host' }) - if 'extip' not in obj_orig or len(obj_orig['extip'])==0: - logger.error("vip (extip): found empty extip field for " + obj_orig['name']) - else: - set_ip_in_obj(obj, obj_orig['extip']) # resolving nat range if there is one - nat_obj = {} - nat_obj.update({'obj_typ': 'host' }) - nat_obj.update({'obj_color': 'black'}) - nat_obj.update({'obj_comment': 'FWO-auto-generated nat object for VIP'}) - if 'obj_ip_end' in obj: # this obj is a range - include the end ip in name and uid as well to avoid akey conflicts - nat_obj.update({'obj_ip_end': obj['obj_ip_end']}) - - # now dealing with the nat ip obj (mappedip) - if 'mappedip' not in obj_orig or len(obj_orig['mappedip'])==0: - logger.warning("vip (extip): found empty mappedip field for " + obj_orig['name']) - else: - if len(obj_orig['mappedip'])>1: - logger.warning("vip (extip): found more than one mappedip, just using the first one for " + obj_orig['name']) - nat_ip = obj_orig['mappedip'][0]['range'] - set_ip_in_obj(nat_obj, nat_ip) - obj.update({ 'obj_nat_ip': nat_obj['obj_ip'] }) # save nat ip in vip obj - if 'obj_ip_end' in nat_obj: # this nat obj is a range - include the end ip in name and uid as well to avoid akey conflicts - obj.update({ 'obj_nat_ip_end': nat_obj['obj_ip_end'] }) # save nat ip in vip obj - nat_obj.update({'obj_name': nat_obj['obj_ip'] + '-' + nat_obj['obj_ip_end'] + nat_postfix}) - else: - nat_obj.update({'obj_name': str(nat_obj['obj_ip']) + nat_postfix}) - nat_obj.update({'obj_uid': nat_obj['obj_name']}) - ###### range handling - - if 'associated-interface' in obj_orig and len(obj_orig['associated-interface'])>0: # and obj_orig['associated-interface'][0] != 'any': - obj_zone = obj_orig['associated-interface'][0] - nat_obj.update({'obj_zone': obj_zone }) - nat_obj.update({'control_id': import_id}) - if nat_obj not in nw_objects: # rare case when a destination nat is down for two different orig ips to the same dest ip - nw_objects.append(nat_obj) - else: - pass - else: # 'fqdn' in obj_orig: # "fully qualified domain name address" // other unknown types - obj.update({ 'obj_typ': 'network' }) - obj.update({ 'obj_ip': '0.0.0.0/0'}) - if 'comment' in obj_orig: - obj.update({'obj_comment': obj_orig['comment']}) - if 'color' in obj_orig and obj_orig['color']==0: - obj.update({'obj_color': 'black'}) # todo: deal with all other colors (will be currently ignored) - # we would need a list of fortinet color codes - if 'uuid' not in obj_orig: - obj_orig.update({'uuid': obj_orig['name']}) - obj.update({'obj_uid': obj_orig['uuid']}) - - # here only picking first associated interface as zone: - if 'associated-interface' in obj_orig and len(obj_orig['associated-interface'])>0: # and obj_orig['associated-interface'][0] != 'any': - obj_zone = obj_orig['associated-interface'][0] - # adding zone if it not yet exists - obj_zone = add_zone_if_missing (config2import, obj_zone, import_id) - obj.update({'obj_zone': obj_zone }) - - obj.update({'control_id': import_id}) - nw_objects.append(obj) - full_config['nw_obj_lookup_dict'][obj['obj_name']] = obj['obj_uid'] - - # finally add "Original" network object for natting - original_obj_name = 'Original' - original_obj_uid = 'Original' - orig_obj = create_network_object(import_id=import_id, name=original_obj_name, type='network', ip='0.0.0.0/0',\ - uid=original_obj_uid, zone='global', color='black', comment='"original" network object created by FWO importer for NAT purposes') - full_config['nw_obj_lookup_dict'][original_obj_name] = original_obj_uid - nw_objects.append(orig_obj) - - resolve_nw_groups(nw_objects) - config2import.update({'network_objects': nw_objects}) - - -def set_ip_in_obj(nw_obj, ip): # add start and end ip in nw_obj if it is a range, otherwise do nothing - if '-' in ip: # dealing with range - ip_start, ip_end = ip.split('-') - nw_obj.update({'obj_ip': ip_start }) - if ip_end != ip_start: - nw_obj.update({'obj_ip_end': ip_end }) - else: - nw_obj.update({'obj_ip': ip }) - - -# for members of groups, the name of the member obj needs to be fetched separately (starting from API v1.?) -def resolve_nw_uid_to_name(uid, nw_objects): - # return name of nw_objects element where obj_uid = uid - for obj in nw_objects: - if obj['obj_uid'] == uid: - return obj['obj_name'] - return 'ERROR: uid "' + uid + '" not found' - - -def resolve_nw_groups(nw_objects): - # add uids (if possible) - - # build helper dict with idx = name - helper_dict = {} - for obj in nw_objects: - helper_dict[obj['obj_name']] = obj['obj_uid'] - - for obj in nw_objects: - if obj['obj_typ'] == 'group': - member_ref_ar = [] - for member_name in obj['obj_member_names'].split(list_delimiter): - member_ref_ar.append(helper_dict[member_name]) - obj['obj_member_refs'] = list_delimiter.join(member_ref_ar) - - -# def add_member_names_for_nw_group(idx, nw_objects): -# group = nw_objects.pop(idx) -# if group['obj_member_refs'] == '' or group['obj_member_refs'] == None: -# #member_names = None -# #obj_member_refs = None -# group['obj_member_names'] = None -# group['obj_member_refs'] = None -# else: -# member_names = '' -# obj_member_refs = group['obj_member_refs'].split(list_delimiter) -# for ref in obj_member_refs: -# member_name = resolve_nw_uid_to_name(ref, nw_objects) -# member_names += member_name + list_delimiter -# group['obj_member_names'] = member_names[:-1] -# nw_objects.insert(idx, group) - - -def create_network_object(import_id, name, type, ip, uid, color, comment, zone): - # if zone is None or zone == '': - # zone = 'global' - return { - 'control_id': import_id, - 'obj_name': name, - 'obj_typ': type, - 'obj_ip': ip, - 'obj_uid': uid, - 'obj_color': color, - 'obj_comment': comment, - 'obj_zone': zone - } - - -# TODO: reduce commplexity if possible -def get_nw_obj(nat_obj_name, nwobjects): - for obj in nwobjects: - if 'obj_name' in obj and obj['obj_name']==nat_obj_name: - return obj - return None - - -# this removes all obj_nat_ip entries from all network objects -# these were used during import but might cause issues if imported into db -def remove_nat_ip_entries(config2import): - for obj in config2import['network_objects']: - if 'obj_nat_ip' in obj: - obj.pop('obj_nat_ip') - - -def get_first_ip_of_destination(obj_ref, config2import): - - logger = getFwoLogger() - if list_delimiter in obj_ref: - obj_ref = obj_ref.split(list_delimiter)[0] - # if destination does not contain exactly one ip, raise a warning - logger.info('src nat behind interface: more than one NAT IP - just using the first one for routing decision for obj_ref ' + obj_ref) - - for obj in config2import['network_objects']: - if 'obj_uid' in obj and obj['obj_uid']==obj_ref: - return obj['obj_ip'] - logger.warning('src nat behind interface: found no IP info for destination object ' + obj_ref) - return None diff --git a/roles/importer/files/importer/fortiosmanagementREST/fOS_rule.py b/roles/importer/files/importer/fortiosmanagementREST/fOS_rule.py deleted file mode 100644 index 019f0d5903..0000000000 --- a/roles/importer/files/importer/fortiosmanagementREST/fOS_rule.py +++ /dev/null @@ -1,458 +0,0 @@ -import copy -import jsonpickle -from fwo_const import list_delimiter, nat_postfix -from fwo_base import extend_string_list -from fOS_service import create_svc_object -from fOS_network import create_network_object, get_first_ip_of_destination -import fOS_zone, fOS_getter -#from fOS_gw_networking import get_device_from_package -from fwo_log import getFwoLogger -from fwo_data_networking import get_matching_route_obj, get_ip_of_interface_obj -import ipaddress -from fOS_common import resolve_objects -import time - - -rule_access_scope_v4 = ['rules'] -rule_access_scope_v6 = [] - -rule_access_scope = ['rules'] -rule_nat_scope = ['rules_nat'] -rule_scope = rule_access_scope + rule_nat_scope - - -def initializeRulebases(raw_config): - for scope in rule_scope: - if scope not in raw_config: - raw_config.update({scope: {}}) - - -def getAccessPolicy(sid, fm_api_url, raw_config, limit): - fOS_getter.update_config_with_fortiOS_api_call(raw_config['rules'], fm_api_url + "/cmdb/firewall/policy" + "?access_token=" + sid, 'rules', limit=limit) - - -def getNatPolicy(sid, fm_api_url, raw_config, adom_name, device, limit): - scope = 'global' - pkg = device['global_rulebase_name'] - if pkg is not None and pkg != '': # only read global rulebase if it exists - for nat_type in ['central/dnat', 'central/dnat6', 'firewall/central-snat-map']: - fOS_getter.update_config_with_fortinet_api_call( - raw_config['rules_global_nat'], sid, fm_api_url, "/pm/config/" + scope + "/pkg/" + pkg + '/' + nat_type, device['local_rulebase_name'], limit=limit) - - scope = 'adom/'+adom_name - pkg = device['local_rulebase_name'] - for nat_type in ['central/dnat', 'central/dnat6', 'firewall/central-snat-map']: - fOS_getter.update_config_with_fortinet_api_call( - raw_config['rules_adom_nat'], sid, fm_api_url, "/pm/config/" + scope + "/pkg/" + pkg + '/' + nat_type, device['local_rulebase_name'], limit=limit) - - -def normalize_access_rules(full_config, config2import, import_id, mgm_details={}, jwt=None): - logger = getFwoLogger() - rules = [] - rule_number = 0 - # rule_number, first_v4, first_v6 = insert_headers(rule_table, first_v6, first_v4, full_config, rules, import_id, localPkgName,src_ref_all,dst_ref_all,rule_number) - - for rule_orig in full_config['rules']['rules']: - rule = {'rule_src': '', 'rule_dst': '', 'rule_svc': ''} - rule.update({ 'control_id': import_id}) - rule.update({ 'rulebase_name': 'access_rules'}) # the rulebase_name will be set to the pkg_name as there is no rulebase_name in FortiMangaer - rule.update({ 'rule_ruleid': rule_orig['policyid']}) - rule.update({ 'rule_uid': rule_orig['uuid']}) - rule.update({ 'rule_num': rule_number}) - if 'name' in rule_orig: - rule.update({ 'rule_name': rule_orig['name']}) - rule.update({ 'rule_installon': None }) - rule.update({ 'rule_implied': False }) - rule.update({ 'rule_time': None }) - rule.update({ 'rule_type': 'access' }) - rule.update({ 'parent_rule_id': None }) - - if 'comments' in rule_orig: - rule.update({ 'rule_comment': rule_orig['comments']}) - else: - rule.update({ 'rule_comment': None }) - if rule_orig['action']==0: - rule.update({ 'rule_action': 'Drop' }) - else: - rule.update({ 'rule_action': 'Accept' }) - if 'status' in rule_orig and (rule_orig['status']=='enable' or rule_orig['status']==1): - rule.update({ 'rule_disabled': False }) - else: - rule.update({ 'rule_disabled': True }) - if rule_orig['logtraffic'] == 'disable': - rule.update({ 'rule_track': 'None'}) - else: - rule.update({ 'rule_track': 'Log'}) - - if '_last_hit' not in rule_orig or rule_orig['_last_hit'] == 0: - rule.update({ 'last_hit': None}) - else: - rule.update({ 'last_hit': time.strftime("%Y-%m-%d", time.localtime(rule_orig['_last_hit']))}) - - rule['rule_src'] = list_delimiter.join([d['name'] for d in rule_orig['srcaddr']]) - rule['rule_dst'] = list_delimiter.join([d['name'] for d in rule_orig['dstaddr']]) - rule['rule_svc'] = list_delimiter.join([d['name'] for d in rule_orig['service']]) - - # handling internet-service rules - no mixed mode between (src/dst) and internet service (src), so overwriting) - if 'internet-service-src-name' in rule_orig and len(rule_orig['internet-service-src-name'])>0: - rule['rule_src'] = list_delimiter.join([d['name'] for d in rule_orig['internet-service-src-name']]) - set_service_field_internet_service(rule, config2import, import_id) - if 'internet-service-name' in rule_orig and len(rule_orig['internet-service-name'])>0: - rule['rule_dst'] = list_delimiter.join([d['name'] for d in rule_orig['internet-service-name']]) - set_service_field_internet_service(rule, config2import, import_id) - - # add ipv6 addresses - rule_src_v6 = [d['name'] for d in rule_orig['srcaddr6']] - rule_dst_v6 = [d['name'] for d in rule_orig['dstaddr6']] - if len(rule_src_v6)>0: - if len(rule['rule_src'])>0: - rule['rule_src'] = list_delimiter.join(rule['rule_src'].split(list_delimiter) + rule_src_v6) - else: - rule['rule_src'] = list_delimiter.join(rule_src_v6) - if len(rule_dst_v6)>0: - if len(rule['rule_dst'])>0: - rule['rule_dst'] = list_delimiter.join(rule['rule_dst'].split(list_delimiter) + rule_dst_v6) - else: - rule['rule_dst'] = list_delimiter.join(rule_dst_v6) - - # add zone information - if len(rule_orig['srcintf'])>0: - src_obj_zone = fOS_zone.add_zone_if_missing (config2import, rule_orig['srcintf'][0]['name'], import_id) - rule.update({ 'rule_from_zone': src_obj_zone }) # todo: currently only using the first zone - if len(rule_orig['dstintf'])>0: - dst_obj_zone = fOS_zone.add_zone_if_missing (config2import, rule_orig['dstintf'][0]['name'], import_id) - rule.update({ 'rule_to_zone': dst_obj_zone }) # todo: currently only using the first zone - - rule.update({ 'rule_src_neg': rule_orig['srcaddr-negate']!='disable'}) - rule.update({ 'rule_dst_neg': rule_orig['dstaddr-negate']!='disable'}) - rule.update({ 'rule_svc_neg': rule_orig['service-negate']!='disable'}) - - rule.update({ 'rule_src_refs': list_delimiter.join(resolve_objects(d, lookup_dict=full_config['nw_obj_lookup_dict'],jwt=jwt) for d in rule['rule_src'].split(list_delimiter))}) - rule.update({ 'rule_dst_refs': list_delimiter.join(resolve_objects(d, lookup_dict=full_config['nw_obj_lookup_dict'],jwt=jwt) for d in rule['rule_dst'].split(list_delimiter))}) - rule.update({ 'rule_svc_refs': rule['rule_svc']}) # for service name and uid are identical - - add_users_to_rule(rule_orig, rule) - - # xlate_rule = handle_combined_nat_rule(rule, rule_orig, config2import, nat_rule_number, import_id, localPkgName, dev_id) - rules.append(rule) - # if xlate_rule is not None: - # rules.append(xlate_rule) - rule_number += 1 # nat rules have their own numbering - config2import.update({'rules': rules}) - - -def set_service_field_internet_service(rule, config2import, import_id): - # check if dummy service "Internet Service" already exists and create if not - found_internet_service_obj = next((item for item in config2import['service_objects'] if item["svc_name"] == "Internet Service"), None) - if found_internet_service_obj is None: - config2import['service_objects'].append({ - 'svc_name': 'Internet Service', 'svc_typ': 'group', 'svc_uid': 'Internet Service', 'control_id': import_id - }) - - # set service to "Internet Service" - rule['rule_svc'] = 'Internet Service' - rule['rule_svc_refs'] = 'Internet Service' - - -# pure nat rules -def normalize_nat_rules(full_config, config2import, import_id, jwt=None): - nat_rules = [] - rule_number = 0 - - for rule_table in rule_nat_scope: - for localPkgName in full_config['rules_global_nat']: - for rule_orig in full_config[rule_table][localPkgName]: - rule = {'rule_src': '', 'rule_dst': '', 'rule_svc': ''} - if rule_orig['nat'] == 1: # assuming source nat - rule.update({ 'control_id': import_id}) - rule.update({ 'rulebase_name': localPkgName}) # the rulebase_name just has to be a unique string among devices - rule.update({ 'rule_ruleid': rule_orig['policyid']}) - rule.update({ 'rule_uid': rule_orig['uuid']}) - # rule.update({ 'rule_num': rule_orig['obj seq']}) - rule.update({ 'rule_num': rule_number }) - if 'comments' in rule_orig: - rule.update({ 'rule_comment': rule_orig['comments']}) - rule.update({ 'rule_action': 'Drop' }) # not used for nat rules - rule.update({ 'rule_track': 'None'}) # not used for nat rules - - rule['rule_src'] = extend_string_list(rule['rule_src'], rule_orig, 'orig-addr', list_delimiter, jwt=jwt, import_id=import_id) - rule['rule_dst'] = extend_string_list(rule['rule_dst'], rule_orig, 'dst-addr', list_delimiter, jwt=jwt, import_id=import_id) - - if rule_orig['protocol']==17: - svc_name = 'udp_' + str(rule_orig['orig-port']) - elif rule_orig['protocol']==6: - svc_name = 'tcp_' + str(rule_orig['orig-port']) - else: - svc_name = 'svc_' + str(rule_orig['orig-port']) - # need to create a helper service object and add it to the nat rule, also needs to be added to service list - - if not 'service_objects' in config2import: # is normally defined - config2import['service_objects'] = [] - config2import['service_objects'].append(create_svc_object( \ - import_id=import_id, name=svc_name, proto=rule_orig['protocol'], port=rule_orig['orig-port'], comment='service created by FWO importer for NAT purposes')) - rule['rule_svc'] = svc_name - - #rule['rule_src'] = extend_string_list(rule['rule_src'], rule_orig, 'srcaddr6', list_delimiter, jwt=jwt, import_id=import_id) - #rule['rule_dst'] = extend_string_list(rule['rule_dst'], rule_orig, 'dstaddr6', list_delimiter, jwt=jwt, import_id=import_id) - - if len(rule_orig['srcintf'])>0: - rule.update({ 'rule_from_zone': rule_orig['srcintf'][0] }) # todo: currently only using the first zone - if len(rule_orig['dstintf'])>0: - rule.update({ 'rule_to_zone': rule_orig['dstintf'][0] }) # todo: currently only using the first zone - - rule.update({ 'rule_src_neg': False}) - rule.update({ 'rule_dst_neg': False}) - rule.update({ 'rule_svc_neg': False}) - rule.update({ 'rule_src_refs': resolve_raw_objects(rule['rule_src'], list_delimiter, full_config, 'name', 'uuid', rule_type=rule_table) }, \ - jwt=jwt, import_id=import_id, rule_uid=rule_orig['uuid'], object_type='network object') - rule.update({ 'rule_dst_refs': resolve_raw_objects(rule['rule_dst'], list_delimiter, full_config, 'name', 'uuid', rule_type=rule_table) }, \ - jwt=jwt, import_id=import_id, rule_uid=rule_orig['uuid'], object_type='network object') - # services do not have uids, so using name instead - rule.update({ 'rule_svc_refs': rule['rule_svc'] }) - rule.update({ 'rule_type': 'original' }) - rule.update({ 'rule_installon': None }) - if 'status' in rule_orig and (rule_orig['status']=='enable' or rule_orig['status']==1): - rule.update({ 'rule_disabled': False }) - else: - rule.update({ 'rule_disabled': True }) - rule.update({ 'rule_implied': False }) - rule.update({ 'rule_time': None }) - rule.update({ 'parent_rule_id': None }) - - nat_rules.append(rule) - add_users_to_rule(rule_orig, rule) - - ############## now adding the xlate rule part ########################## - xlate_rule = dict(rule) # copy the original (match) rule - xlate_rule.update({'rule_src': '', 'rule_dst': '', 'rule_svc': ''}) - xlate_rule['rule_src'] = extend_string_list(xlate_rule['rule_src'], rule_orig, 'orig-addr', list_delimiter, jwt=jwt, import_id=import_id) - xlate_rule['rule_dst'] = 'Original' - - if rule_orig['protocol']==17: - svc_name = 'udp_' + str(rule_orig['nat-port']) - elif rule_orig['protocol']==6: - svc_name = 'tcp_' + str(rule_orig['nat-port']) - else: - svc_name = 'svc_' + str(rule_orig['nat-port']) - # need to create a helper service object and add it to the nat rule, also needs to be added to service list! - # fmgr_service.create_svc_object(name=svc_name, proto=rule_orig['protocol'], port=rule_orig['orig-port'], comment='service created by FWO importer for NAT purposes') - config2import['service_objects'].append(create_svc_object(import_id=import_id, name=svc_name, proto=rule_orig['protocol'], port=rule_orig['nat-port'], comment='service created by FWO importer for NAT purposes')) - xlate_rule['rule_svc'] = svc_name - - xlate_rule.update({ 'rule_src_refs': resolve_objects(xlate_rule['rule_src'], list_delimiter, full_config, 'name', 'uuid', rule_type=rule_table, jwt=jwt, import_id=import_id ) }) - xlate_rule.update({ 'rule_dst_refs': resolve_objects(xlate_rule['rule_dst'], list_delimiter, full_config, 'name', 'uuid', rule_type=rule_table, jwt=jwt, import_id=import_id ) }) - xlate_rule.update({ 'rule_svc_refs': xlate_rule['rule_svc'] }) # services do not have uids, so using name instead - - xlate_rule.update({ 'rule_type': 'xlate' }) - - nat_rules.append(xlate_rule) - rule_number += 1 - config2import['rules'].extend(nat_rules) - - -def insert_header(rules, import_id, header_text, rulebase_name, rule_uid, rule_number, src_refs, dst_refs): - rule = { - "control_id": import_id, - "rule_head_text": header_text, - "rulebase_name": rulebase_name, - "rule_ruleid": None, - "rule_uid": rule_uid + rulebase_name, - "rule_num": rule_number, - "rule_disabled": False, - "rule_src": "all", - "rule_dst": "all", - "rule_svc": "ALL", - "rule_src_neg": False, - "rule_dst_neg": False, - "rule_svc_neg": False, - "rule_src_refs": src_refs, - "rule_dst_refs": dst_refs, - "rule_svc_refs": "ALL", - "rule_action": "Accept", - "rule_track": "None", - "rule_installon": None, - "rule_time": None, - "rule_type": "access", - "parent_rule_id": None, - "rule_implied": False, - "rule_comment": None - } - rules.append(rule) - - -def create_xlate_rule(rule): - xlate_rule = copy.deepcopy(rule) - rule['rule_type'] = 'combined' - xlate_rule['rule_type'] = 'xlate' - xlate_rule['rule_comment'] = None - xlate_rule['rule_disabled'] = False - xlate_rule['rule_src'] = 'Original' - xlate_rule['rule_src_refs'] = 'Original' - xlate_rule['rule_dst'] = 'Original' - xlate_rule['rule_dst_refs'] = 'Original' - xlate_rule['rule_svc'] = 'Original' - xlate_rule['rule_svc_refs'] = 'Original' - return xlate_rule - - -def handle_combined_nat_rule(rule, rule_orig, config2import, nat_rule_number, import_id, localPkgName, dev_id): - # now dealing with VIPs (dst NAT part) of combined rules - logger = getFwoLogger() - xlate_rule = None - - # dealing with src NAT part of combined rules - if "nat" in rule_orig and rule_orig["nat"]==1: - logger.debug("found mixed Access/NAT rule no. " + str(nat_rule_number)) - nat_rule_number += 1 - xlate_rule = create_xlate_rule(rule) - if 'ippool' in rule_orig: - if rule_orig['ippool']==0: # hiding behind outbound interface - interface_name = 'unknownIF' - destination_interface_ip = '0.0.0.0' - destination_ip = get_first_ip_of_destination(rule['rule_dst_refs'], config2import) # get an ip of destination - hideInterface = 'undefined_interface' - if destination_ip is None: - logger.warning('src nat behind interface: found no valid destination ip in rule with UID ' + rule['rule_uid']) - else: - # matching_route = get_matching_route_obj(destination_ip, config2import['networking'][device_name]['routingv4']) - matching_route = get_matching_route_obj(destination_ip, config2import['routing'], dev_id) - if matching_route is None: - logger.warning('src nat behind interface: found no matching route in rule with UID ' - + rule['rule_uid'] + ', dest_ip: ' + destination_ip) - else: - destination_interface_ip = get_ip_of_interface_obj(matching_route.interface, dev_id, config2import['interfaces']) - interface_name = matching_route.interface - hideInterface=interface_name - if hideInterface is None: - logger.warning('src nat behind interface: found route with undefined interface ' + str(jsonpickle.dumps(matching_route, unpicklable=True))) - if destination_interface_ip is None: - logger.warning('src nat behind interface: found no matching interface IP in rule with UID ' - + rule['rule_uid'] + ', dest_ip: ' + destination_ip) - - # add dummy object "outbound-interface" - if hideInterface is not None: - obj_name = 'hide_IF_ip_' + str(hideInterface) + '_' + str(destination_interface_ip) - obj_comment = 'FWO auto-generated dummy object for source nat' - if type(ipaddress.ip_address(str(destination_interface_ip))) is ipaddress.IPv6Address: - HideNatIp = str(destination_interface_ip) + '/128' - elif type(ipaddress.ip_address(str(destination_interface_ip))) is ipaddress.IPv4Address: - HideNatIp = str(destination_interface_ip) + '/32' - else: - HideNatIp = '0.0.0.0/32' - logger.warning('found invalid HideNatIP ' + str(destination_interface_ip)) - obj = create_network_object(import_id, obj_name, 'host', HideNatIp, obj_name, 'black', obj_comment, 'global') - if obj not in config2import['network_objects']: - config2import['network_objects'].append(obj) - xlate_rule['rule_src'] = obj_name - xlate_rule['rule_src_refs'] = obj_name - - elif rule_orig['ippool']==1: # hiding behind one ip of an ip pool - poolNameArray = rule_orig['poolname'] - if len(poolNameArray)>0: - if len(poolNameArray)>1: - logger.warning("found more than one ippool - ignoring all but first pool") - poolName = poolNameArray[0] - xlate_rule['rule_src'] = poolName - xlate_rule['rule_src_refs'] = poolName - else: - logger.warning("found ippool rule without ippool: " + rule['rule_uid']) - else: - logger.warning("found ippool rule with unexpected ippool value: " + rule_orig['ippool']) - - if 'natip' in rule_orig and rule_orig['natip']!=["0.0.0.0","0.0.0.0"]: - logger.warning("found explicit natip rule - ignoring for now: " + rule['rule_uid']) - # need example for interpretation of config - - # todo: find out how match-vip=1 influences natting (only set in a few vip-nat rules) - # if "match-vip" in rule_orig and rule_orig["match-vip"]==1: - # logger.warning("found VIP destination Access/NAT rule (but not parsing yet); no. " + str(vip_nat_rule_number)) - # vip_nat_rule_number += 1 - - # deal with vip natting: check for each (dst) nw obj if it contains "obj_nat_ip" - rule_dst_list = rule['rule_dst'].split(list_delimiter) - nat_object_list = extract_nat_objects(rule_dst_list, config2import['network_objects']) - - if len(nat_object_list)>0: - if xlate_rule is None: # no source nat, so we create the necessary nat rule here - xlate_rule = create_xlate_rule(rule) - xlate_dst = [] - xlate_dst_refs = [] - for nat_obj in nat_object_list: - if 'obj_ip_end' in nat_obj: # this nat obj is a range - include the end ip in name and uid as well to avoid akey conflicts - xlate_dst.append(nat_obj['obj_nat_ip'] + '-' + nat_obj['obj_ip_end'] + nat_postfix) - nat_ref = nat_obj['obj_nat_ip'] - if 'obj_nat_ip_end' in nat_obj: - nat_ref += '-' + nat_obj['obj_nat_ip_end'] + nat_postfix - xlate_dst_refs.append(nat_ref) - else: - xlate_dst.append(nat_obj['obj_nat_ip'] + nat_postfix) - xlate_dst_refs.append(nat_obj['obj_nat_ip'] + nat_postfix) - xlate_rule['rule_dst'] = list_delimiter.join(xlate_dst) - xlate_rule['rule_dst_refs'] = list_delimiter.join(xlate_dst_refs) - # else: (no nat object found) no dnatting involved, dst stays "Original" - - return xlate_rule - - -def insert_headers(rule_table, first_v6, first_v4, full_config, rules, import_id, localPkgName,src_ref_all,dst_ref_all,rule_number): - if rule_table in rule_access_scope_v6 and first_v6: - insert_header(rules, import_id, "IPv6 rules", localPkgName, "IPv6HeaderText", rule_number, src_ref_all, dst_ref_all) - rule_number += 1 - first_v6 = False - elif rule_table in rule_access_scope_v4 and first_v4: - insert_header(rules, import_id, "IPv4 rules", localPkgName, "IPv4HeaderText", rule_number, src_ref_all, dst_ref_all) - rule_number += 1 - first_v4 = False - if rule_table == 'rules_adom_v4' and len(full_config['rules_adom_v4'][localPkgName])>0: - insert_header(rules, import_id, "Adom Rules IPv4", localPkgName, "IPv4AdomRules", rule_number, src_ref_all, dst_ref_all) - rule_number += 1 - elif rule_table == 'rules_adom_v6' and len(full_config['rules_adom_v6'][localPkgName])>0: - insert_header(rules, import_id, "Adom Rules IPv6", localPkgName, "IPv6AdomRules", rule_number, src_ref_all, dst_ref_all) - rule_number += 1 - elif rule_table == 'rules_global_header_v4' and len(full_config['rules_global_header_v4'][localPkgName])>0: - insert_header(rules, import_id, "Global Header Rules IPv4", localPkgName, "IPv4GlobalHeaderRules", rule_number, src_ref_all, dst_ref_all) - rule_number += 1 - elif rule_table == 'rules_global_header_v6' and len(full_config['rules_global_header_v6'][localPkgName])>0: - insert_header(rules, import_id, "Global Header Rules IPv6", localPkgName, "IPv6GlobalHeaderRules", rule_number, src_ref_all, dst_ref_all) - rule_number += 1 - elif rule_table == 'rules_global_footer_v4' and len(full_config['rules_global_footer_v4'][localPkgName])>0: - insert_header(rules, import_id, "Global Footer Rules IPv4", localPkgName, "IPv4GlobalFooterRules", rule_number, src_ref_all, dst_ref_all) - rule_number += 1 - elif rule_table == 'rules_global_footer_v6' and len(full_config['rules_global_footer_v6'][localPkgName])>0: - insert_header(rules, import_id, "Global Footer Rules IPv6", localPkgName, "IPv6GlobalFooterRules", rule_number, src_ref_all, dst_ref_all) - rule_number += 1 - return rule_number, first_v4, first_v6 - - -def extract_nat_objects(nwobj_list, all_nwobjects): - nat_obj_list = [] - for obj in nwobj_list: - for obj2 in all_nwobjects: - if obj2['obj_name']==obj: - if 'obj_nat_ip' in obj2: - nat_obj_list.append(obj2) - break - # if obj in all_nwobjects and 'obj_nat_ip' in all_nwobjects[obj]: - # nat_obj_list.append(obj) - return nat_obj_list - - -def add_users_to_rule(rule_orig, rule): - if 'groups' in rule_orig: - add_users(rule_orig['groups'], rule) - if 'users' in rule_orig: - add_users(rule_orig['users'], rule) - - -def add_users(users, rule): - for user in users: - rule_src_with_users = [] - for src in rule['rule_src'].split(list_delimiter): - rule_src_with_users.append(user + '@' + src) - rule['rule_src'] = list_delimiter.join(rule_src_with_users) - - # here user ref is the user name itself - rule_src_refs_with_users = [] - for src in rule['rule_src_refs'].split(list_delimiter): - rule_src_refs_with_users.append(user + '@' + src) - rule['rule_src_refs'] = list_delimiter.join(rule_src_refs_with_users) diff --git a/roles/importer/files/importer/fortiosmanagementREST/fOS_service.py b/roles/importer/files/importer/fortiosmanagementREST/fOS_service.py deleted file mode 100644 index 9a5f570733..0000000000 --- a/roles/importer/files/importer/fortiosmanagementREST/fOS_service.py +++ /dev/null @@ -1,211 +0,0 @@ -import re -from fwo_const import list_delimiter -from fwo_log import getFwoLogger - - -def normalize_svcobjects(full_config, config2import, import_id, scope): - logger = getFwoLogger() - svc_objects = [] - full_config['svc_obj_lookup_dict'] = {} - for s in scope: - for obj_orig in full_config[s]: - member_names = '' - if 'member' in obj_orig: - type = 'group' - for member in obj_orig['member']: - member_names += member['name'] + list_delimiter - member_names = member_names[:-1] - else: - type = 'simple' - - name = None - if 'name' in obj_orig: - name = str(obj_orig['name']) - - color = None - if 'color' in obj_orig and str(obj_orig['color']) != 0: - color = str(obj_orig['color']) - - session_timeout = None # todo: find the right timer - # if 'udp-idle-timer' in obj_orig and str(obj_orig['udp-idle-timer']) != 0: - # session_timeout = str(obj_orig['udp-idle-timer']) - - proto = 0 - range_names = '' - if 'protocol' in obj_orig: - added_svc_obj = 0 - # if obj_orig['protocol'] == 1: - # addObject(svc_objects, type, name, color, 1, None, None, session_timeout, import_id, full_config=full_config) - # added_svc_obj += 1 - # if obj_orig['protocol'] == 2: - # if 'protocol-number' in obj_orig: - # proto = obj_orig['protocol-number'] - # addObject(svc_objects, type, name, color, proto, None, None, session_timeout, import_id) - # added_svc_obj += 1 - # if obj_orig['protocol'] == 5 or obj_orig['protocol'] == 11 or obj_orig['protocol'] == 'TCP/UDP/SCTP': - if obj_orig['protocol'] == 'TCP/UDP/SCTP': - split = check_split(obj_orig) - if "tcp-portrange" in obj_orig and len(obj_orig['tcp-portrange']) > 0: - tcpname = name - if split: - tcpname += "_tcp" - range_names += tcpname + list_delimiter - addObject(svc_objects, type, tcpname, color, 6, obj_orig['tcp-portrange'], None, session_timeout, import_id, full_config=full_config) - added_svc_obj += 1 - if "udp-portrange" in obj_orig and len(obj_orig['udp-portrange']) > 0: - udpname = name - if split: - udpname += "_udp" - range_names += udpname + list_delimiter - addObject(svc_objects, type, udpname, color, 17, obj_orig['udp-portrange'], None, session_timeout, import_id, full_config=full_config) - added_svc_obj += 1 - if "sctp-portrange" in obj_orig and len(obj_orig['sctp-portrange']) > 0: - sctpname = name - if split: - sctpname += "_sctp" - range_names += sctpname + list_delimiter - addObject(svc_objects, type, sctpname, color, 132, obj_orig['sctp-portrange'], None, session_timeout, import_id, full_config=full_config) - added_svc_obj += 1 - if split: - range_names = range_names[:-1] - # TODO: collect group members - addObject(svc_objects, 'group', name, color, 0, None, range_names, session_timeout, import_id, full_config=full_config) - added_svc_obj += 1 - if added_svc_obj==0: # assuming RPC service which here has no properties at all - addObject(svc_objects, 'rpc', name, color, 0, None, None, None, import_id, full_config=full_config) - added_svc_obj += 1 - elif obj_orig['protocol'] == 'IP': - addObject(svc_objects, 'simple', name, color, obj_orig['protocol-number'], None, None, None, import_id, full_config=full_config) - added_svc_obj += 1 - elif obj_orig['protocol'] == 'ICMP': - addObject(svc_objects, 'simple', name, color, 1, None, None, None, import_id, full_config=full_config) - added_svc_obj += 1 - elif obj_orig['protocol'] == 'ICMP6': - addObject(svc_objects, 'simple', name, color, 1, None, None, None, import_id, full_config=full_config) - added_svc_obj += 1 - else: - logger.warning("Unknown service protocol found: " + obj_orig['name'] +', proto: ' + obj_orig['protocol']) - elif type == 'group': - addObject(svc_objects, type, name, color, 0, None, member_names, session_timeout, import_id, full_config=full_config) - else: - # application/list - addObject(svc_objects, type, name, color, 0, None, None, session_timeout, import_id, full_config=full_config) - - # finally add "Original" service object for natting - original_obj_name = 'Original' - svc_objects.append(create_svc_object(import_id=import_id, name=original_obj_name, proto=0, port=None,\ - comment='"original" service object created by FWO importer for NAT purposes')) - - config2import.update({'service_objects': svc_objects}) - - -def check_split(obj_orig): - count = 0 - if "tcp-portrange" in obj_orig and len(obj_orig['tcp-portrange']) > 0: - count += 1 - if "udp-portrange" in obj_orig and len(obj_orig['udp-portrange']) > 0: - count += 1 - if "sctp-portrange" in obj_orig and len(obj_orig['sctp-portrange']) > 0: - count += 1 - return (count > 1) - - -def extractSinglePortRange(port_range): - # remove src-ports - port = port_range.split(':')[0] - port_end = port - - # open ranges (not found so far in data) - pattern = re.compile('^\>(\d+)$') - match = pattern.match(port) - if match: - port = str(int(match.group()[1:]) + 1) - port_end = str(65535) - pattern = re.compile('^\<(\d+)$') - match = pattern.match(port) - if match: - port = str(1) - port_end = str(int(match.group()[1:]) - 1) - - # split ranges - pattern = re.compile('^(\d+)\-(\d+)$') - match = pattern.match(port) - if match: - port, port_end = match.group().split('-') - return port, port_end - - -def extractPorts(port_ranges): - ports = [] - port_ends = [] - if port_ranges is not None and len(port_ranges) > 0: - if ' ' in port_ranges: - # port range of the form "12 13 114" - port_ranges = port_ranges.split(' ') - - if not isinstance(port_ranges, str): - for port_range in port_ranges: - port1, port2 = extractSinglePortRange(port_range) - ports.append(port1) - port_ends.append(port2) - else: - port1, port2 = extractSinglePortRange(port_ranges) - ports.append(port1) - port_ends.append(port2) - return ports, port_ends - - -def create_svc_object(import_id, name, proto, port, comment): - return { - 'control_id': import_id, - 'svc_name': name, - 'svc_typ': 'simple', - 'svc_port': port, - 'ip_proto': proto, - 'svc_uid': name, # services have no uid in fortimanager - 'svc_comment': comment - } - - -def addObject(svc_objects, type, name, color, proto, port_ranges, member_names, session_timeout, import_id, full_config={}): - - # add service object in lookup table (currently no UID, name is the UID) - full_config['svc_obj_lookup_dict'][name] = name - - svc_obj = create_svc_object(import_id, name, proto, None, None) - svc_obj['svc_color'] = color - svc_obj['svc_typ'] = type - svc_obj['svc_port_end'] = None - svc_obj['svc_member_names'] = member_names - svc_obj['svc_member_refs'] = member_names - svc_obj['svc_timeout'] = session_timeout - - if port_ranges is not None: - range_names = '' - ports, port_ends = extractPorts(port_ranges) - split = (len(ports) > 1) - for index, port in enumerate(ports): - port_end = port_ends[index] - full_name = name - if split: - full_name += '_' + str(port) - range_names += full_name + list_delimiter - if port_end != port: - port_range_local = port + '-' + port_end - else: - port_range_local = port - addObject(svc_objects, 'simple', full_name, color, proto, port_range_local, None, None, import_id, full_config) - - svc_obj['svc_port'] = port - svc_obj['svc_port_end'] = port_end - - if split: - range_names = range_names[:-1] - svc_obj['svc_member_refs'] = range_names - svc_obj['svc_member_names'] = range_names - svc_obj['svc_typ'] = 'group' - svc_obj['svc_port'] = None - svc_obj['svc_port_end'] = None - - svc_objects.extend([svc_obj]) - diff --git a/roles/importer/files/importer/fortiosmanagementREST/fOS_user.py b/roles/importer/files/importer/fortiosmanagementREST/fOS_user.py deleted file mode 100644 index 6f92baf078..0000000000 --- a/roles/importer/files/importer/fortiosmanagementREST/fOS_user.py +++ /dev/null @@ -1,36 +0,0 @@ -from fwo_const import list_delimiter - -def normalize_users(full_config, config2import, import_id, user_scope): - users = [] - for scope in user_scope: - for user_orig in full_config[scope]: - name = None - type = 'simple' - color = None - member_names = None - comment = None - - if 'member' in user_orig: - type = 'group' - member_names = '' - for member in user_orig['member']: - member_names += member['name'] + list_delimiter - member_names = member_names[:-1] - if 'name' in user_orig: - name = str(user_orig['name']) - if 'comment' in user_orig: - comment = str(user_orig['comment']) - if 'color' in user_orig and str(user_orig['color']) != 0: - color = str(user_orig['color']) - - users.extend([{'user_typ': type, - 'user_name': name, - 'user_color': color, - 'user_uid': name, - 'user_comment': comment, - 'user_member_refs': member_names, - 'user_member_names': member_names, - 'control_id': import_id - }]) - - config2import.update({'user_objects': users}) diff --git a/roles/importer/files/importer/fortiosmanagementREST/fOS_zone.py b/roles/importer/files/importer/fortiosmanagementREST/fOS_zone.py deleted file mode 100644 index b9e41a1e68..0000000000 --- a/roles/importer/files/importer/fortiosmanagementREST/fOS_zone.py +++ /dev/null @@ -1,29 +0,0 @@ - -def normalize_zones(full_config, config2import, import_id): - zones = [] - for orig_zone in full_config['zone_objects']['zone_list']: - zone = {} - zone.update({'zone_name': orig_zone}) - zone.update({'control_id': import_id}) - zones.append(zone) - - config2import.update({'zone_objects': zones}) - - -def add_zone_if_missing (config2import, zone_string, import_id): - # adding zone if it not yet exists - - # also transforming any into global (normalized global zone) - if zone_string == 'any': - zone_string = 'global' - if zone_string is not None: - if 'zone_objects' not in config2import: # no zones yet? add empty zone_objects array - config2import.update({'zone_objects': []}) - zone_exists = False - for zone in config2import['zone_objects']: - if zone_string == zone['zone_name']: - zone_exists = True - if not zone_exists: - config2import['zone_objects'].append({'zone_name': zone_string, 'control_id': import_id}) - return zone_string - \ No newline at end of file diff --git a/roles/importer/files/importer/fortiosmanagementREST/fwcommon.py b/roles/importer/files/importer/fortiosmanagementREST/fwcommon.py deleted file mode 100644 index 86415b0acd..0000000000 --- a/roles/importer/files/importer/fortiosmanagementREST/fwcommon.py +++ /dev/null @@ -1,114 +0,0 @@ -import sys -from common import importer_base_dir -sys.path.append(importer_base_dir + '/fortiosmanagementREST') -import fOS_user -import fOS_service -import fOS_zone -import fOS_rule -import fOS_network -import fOS_getter -from curses import raw -from fwo_log import getFwoLogger -# from fOS_gw_networking import getInterfacesAndRouting, normalize_network_data -from fwo_data_networking import get_ip_of_interface_obj - -from fwo_const import list_delimiter, nat_postfix, fwo_config_filename -from fwo_config import readConfig -from fwo_api import setAlert, create_data_issue - - -nw_obj_types = ['firewall/address', 'firewall/address6', 'firewall/addrgrp', - 'firewall/addrgrp6', 'firewall/ippool', 'firewall/vip', - 'firewall/internet-service', 'firewall/internet-service-group'] - # internet-service is not a service as such but is used as dest (mainly) -svc_obj_types = ['application/list', 'application/group', - # 'application/categories', - #'application/custom', - 'firewall.service/custom', - 'firewall.service/group' - ] - -# build the product of all scope/type combinations -nw_obj_scope = ['nw_obj_' + s1 for s1 in nw_obj_types] -svc_obj_scope = ['svc_obj_' + s1 for s1 in svc_obj_types] - -# zone_types = ['zones_global', 'zones_adom'] - -user_obj_types = ['user/local', 'user/group'] -user_scope = ['user_obj_' + s1 for s1 in user_obj_types] - - -def has_config_changed(full_config, mgm_details, force=False): - # dummy - may be filled with real check later on - return True - - -def get_config(config2import, full_config, current_import_id, mgm_details, limit=100, force=False, jwt=''): - logger = getFwoLogger() - if full_config == {}: # no native config was passed in, so getting it from FortiManager - parsing_config_only = False - else: - parsing_config_only = True - - # fmgr API login - if not parsing_config_only: # no native config was passed in, so getting it from FortiManager - fm_api_url = 'https://' + mgm_details['hostname'] + ':' + str(mgm_details['port']) + '/api/v2' - sid = mgm_details['import_credential']['secret'] - - if not parsing_config_only: # no native config was passed in, so getting it from FortiManager - getObjects(sid, fm_api_url, full_config, limit, nw_obj_types, svc_obj_types) - # getInterfacesAndRouting( - # sid, fm_api_url, full_config, mgm_details['devices'], limit) - - # adding global zone first: - fOS_zone.add_zone_if_missing (config2import, 'global', current_import_id) - - # initialize all rule dicts - fOS_rule.initializeRulebases(full_config) - for dev in mgm_details['devices']: - fOS_rule.getAccessPolicy(sid, fm_api_url, full_config, limit) - # fOS_rule.getNatPolicy(sid, fm_api_url, full_config, limit) - - # now we normalize relevant parts of the raw config and write the results to config2import dict - # currently reading zone from objects for backward compat with FortiManager 6.x - # fmgr_zone.normalize_zones(full_config, config2import, current_import_id) - - # write normalized networking data to config2import - # this is currently not written to the database but only used for natting decisions - # later we will probably store the networking info in the database as well as a basis - # for path analysis - - # normalize_network_data(full_config, config2import, mgm_details) - - fOS_user.normalize_users( - full_config, config2import, current_import_id, user_scope) - fOS_network.normalize_nwobjects( - full_config, config2import, current_import_id, nw_obj_scope, jwt=jwt, mgm_id=mgm_details['id']) - fOS_service.normalize_svcobjects( - full_config, config2import, current_import_id, svc_obj_scope) - fOS_zone.add_zone_if_missing (config2import, 'global', current_import_id) - - fOS_rule.normalize_access_rules( - full_config, config2import, current_import_id, mgm_details=mgm_details, jwt=jwt) - # fOS_rule.normalize_nat_rules( - # full_config, config2import, current_import_id, jwt=jwt) - # fOS_network.remove_nat_ip_entries(config2import) - return 0 - - -def getObjects(sid, fm_api_url, raw_config, limit, nw_obj_types, svc_obj_types): - # get network objects: - for object_type in nw_obj_types: - fOS_getter.update_config_with_fortiOS_api_call( - raw_config, fm_api_url + "/cmdb/" + object_type + "?access_token=" + sid, "nw_obj_" + object_type, limit=limit) - - # get service objects: - for object_type in svc_obj_types: - fOS_getter.update_config_with_fortiOS_api_call( - raw_config, fm_api_url + "/cmdb/" + object_type + "?access_token=" + sid, "svc_obj_" + object_type, limit=limit) - - # get user objects: - for object_type in user_obj_types: - fOS_getter.update_config_with_fortiOS_api_call( - raw_config, fm_api_url + "/cmdb/" + object_type + "?access_token=" + sid, "user_obj_" + object_type, limit=limit) - diff --git a/roles/importer/files/importer/fortiosmanagementREST/unused_fOS_gw_networking.py b/roles/importer/files/importer/fortiosmanagementREST/unused_fOS_gw_networking.py deleted file mode 100644 index 2bb2126b3b..0000000000 --- a/roles/importer/files/importer/fortiosmanagementREST/unused_fOS_gw_networking.py +++ /dev/null @@ -1,276 +0,0 @@ -from asyncio.log import logger -from fwo_log import getFwoLogger -from netaddr import IPAddress, IPNetwork -from functools import cmp_to_key -import traceback -import fOS_getter as fOS_getter -import fwo_globals -from fwo_data_networking import Route, Interface -from fwo_data_networking import getRouteDestination - -def normalize_network_data(native_config, normalized_config, mgm_details): - - logger = getFwoLogger() - - normalized_config.update({'routing': {}, 'interfaces': {} }) - - for dev_id, plain_dev_name, plain_vdom_name, full_vdom_name in get_all_dev_names(mgm_details['devices']): - normalized_config.update({'routing': [], 'interfaces': []}) - - if 'routing-table-ipv4/' + full_vdom_name not in native_config: - logger.warning('could not find routing data routing-table-ipv4/' + full_vdom_name) - logger.warning('native configs contains the following keys ' + str(native_config.keys())) - normalized_config['networking'][full_vdom_name]['routingv4'] = [] - else: - for route in native_config['routing-table-ipv4/' + full_vdom_name]: - #gateway = None if route['gateway']=='0.0.0.0' else route['gateway'] # local network - normRoute = Route(dev_id, route['gateway'], route['ip_mask'], interface=route['interface'], metric=route['metric'], distance=route['distance']) - normalized_config['routing'].append(normRoute) - - if 'routing-table-ipv6/' + full_vdom_name not in native_config: - logger.warning('could not find routing data routing-table-ipv6/' + full_vdom_name) - if fwo_globals.debug_level>5: - logger.warning('native configs contains the following keys ' + str(native_config.keys())) - normalized_config['networking'][full_vdom_name]['routingv6'] = [] - else: - for route in native_config['routing-table-ipv6/' + full_vdom_name]: - #gateway = None if route['gateway']=='::' else route['gateway'] # local network - normRoute = Route(dev_id, route['gateway'], route['ip_mask'], metric=route['metric'], - distance=route['distance'], interface=route['interface'], ip_version=6) - normalized_config['routing'].append(normRoute) - - normalized_config['routing'].sort(key=getRouteDestination,reverse=True) - - for interface in native_config['interfaces_per_device/' + full_vdom_name]: - if interface['ipv6']['ip6-address']!='::/0': - ipv6, netmask_bits = interface['ipv6']['ip6-address'].split('/') - normIfV6 = Interface(dev_id, interface['name'], IPAddress(ipv6), netmask_bits, ip_version=6) - normalized_config['interfaces'].append(normIfV6) - - if interface['ip']!=['0.0.0.0','0.0.0.0']: - ipv4 = IPAddress(interface['ip'][0]) - netmask_bits = IPAddress(interface['ip'][1]).netmask_bits() - normIfV4 = Interface(dev_id, interface['name'], ipv4, netmask_bits, ip_version=4) - normalized_config['interfaces'].append(normIfV4) - - #devices_without_default_route = get_devices_without_default_route(normalized_config) - #if len(devices_without_default_route)>0: - # logger.warning('found devices without default route') - - -def get_matching_route(destination_ip, routing_table): - - logger = getFwoLogger() - - def route_matches(ip, destination): - ip_n = IPNetwork(ip).cidr - dest_n = IPNetwork(destination).cidr - return ip_n in dest_n or dest_n in ip_n - - - if len(routing_table)==0: - logger.error('src nat behind interface: encountered empty routing table') - return None - - for route in routing_table: - if route_matches(destination_ip, route['destination']): - return route - - logger.warning('src nat behind interface: found no matching route in routing table - no default route?!') - return None - - -def get_ip_of_interface(interface, interface_list=[]): - - interface_details = next((sub for sub in interface_list if sub['name'] == interface), None) - - if interface_details is not None and 'ipv4' in interface_details: - return interface_details['ipv4'] - else: - return None - - -def sort_reverse(ar_in, key): - - def comp(left, right): - l_submask = int(left[key].split("/")[1]) - r_submask = int(right[key].split("/")[1]) - return l_submask - r_submask - - return sorted(ar_in, key=cmp_to_key(comp), reverse=True) - - -# strip off last part of a string separated by separator -def strip_off_last_part(string_in, separator='_'): - string_out = string_in - if separator in string_in: # strip off final _xxx part - str_ar = string_in.split(separator) - str_ar.pop() - string_out = separator.join(str_ar) - return string_out - - -def get_last_part(string_in, separator='_'): - string_out = '' - if separator in string_in: # strip off _vdom_name - str_ar = string_in.split(separator) - string_out = str_ar.pop() - return string_out - - -def get_plain_device_names_without_vdoms(devices): - device_array = [] - for dev in devices: - dev_name = strip_off_last_part(dev["name"]) - if dev_name not in device_array: - device_array.append(dev_name) - return device_array - - -# only getting one vdom as currently assuming routing to be -# the same for all vdoms on a device -def get_device_names_plus_one_vdom(devices): - device_array = [] - device_array_with_vdom = [] - for dev in devices: - dev_name = strip_off_last_part(dev["name"]) - vdom_name = get_last_part(dev["name"]) - if dev_name not in device_array: - device_array.append(dev_name) - device_array_with_vdom.append([dev_name, vdom_name]) - return device_array_with_vdom - - -# getting devices and their vdom names -def get_device_plus_full_vdom_names(devices): - device_array_with_vdom = [] - for dev in devices: - dev_name = strip_off_last_part(dev["name"]) - vdom_name = dev["name"] - device_array_with_vdom.append([dev_name, vdom_name]) - return device_array_with_vdom - - -# getting devices and their vdom names -def get_all_dev_names(devices): - device_array_with_vdom = [] - for dev in devices: - dev_id = dev["id"] - dev_name = strip_off_last_part(dev["name"]) - plain_vdom_name = get_last_part(dev["name"]) - full_vdom_name = dev["name"] - device_array_with_vdom.append([dev_id, dev_name, plain_vdom_name, full_vdom_name]) - return device_array_with_vdom - - -# get network information (currently only used for source nat) -def getInterfacesAndRouting(sid, fm_api_url, raw_config, adom_name, devices, limit): - - logger = getFwoLogger() - # strip off vdom names, just deal with the plain device - device_array = get_all_dev_names(devices) - - for dev_id, plain_dev_name, plain_vdom_name, full_vdom_name in device_array: - logger.info("dev_name: " + plain_dev_name + ", full vdom_name: " + full_vdom_name) - - # getting interfaces of device - all_interfaces_payload = { - "id": 1, - "params": [ - { - "fields": [ "name", "ip" ], - "filter": [ "vdom", "==", plain_vdom_name ], - "sub fetch": { - "client-options": { - "subfetch hidden": 1 - }, - "dhcp-snooping-server-list": { - "subfetch hidden": 1 - }, - "egress-queues": { - "subfetch hidden": 1 - }, - "ipv6": { - "fields": [ - "ip6-address" - ], - "sub fetch": { - "dhcp6-iapd-list": { - "subfetch hidden": 1 - }, - "ip6-delegated-prefix-list": { - "subfetch hidden": 1 - }, - "ip6-extra-addr": { - "subfetch hidden": 1 - }, - "ip6-prefix-list": { - "subfetch hidden": 1 - }, - "vrrp6": { - "subfetch hidden": 1 - } - } - }, - "l2tp-client-settings": { - "subfetch hidden": 1 - }, - "secondaryip": { - "subfetch hidden": 1 - }, - "tagging": { - "subfetch hidden": 1 - }, - "vrrp": { - "subfetch hidden": 1 - }, - "wifi-networks": { - "subfetch hidden": 1 - } - } - } - ] - } - try: # get interfaces from top level device (not vdom) - fOS_getter.update_config_with_fortinet_api_call( - raw_config, sid, fm_api_url, "/pm/config/device/" + plain_dev_name + "/global/system/interface", - "interfaces_per_device/" + full_vdom_name, payload=all_interfaces_payload, limit=limit, method="get") - except: - logger.warning("error while getting interfaces of device " + plain_vdom_name + ", vdom=" + plain_vdom_name + ", ignoring, traceback: " + str(traceback.format_exc())) - - # now getting routing information - for ip_version in ["ipv4", "ipv6"]: - payload = { "params": [ { "data": { - "target": ["adom/" + adom_name + "/device/" + plain_dev_name], - "action": "get", - "resource": "/api/v2/monitor/router/" + ip_version + "/select?&vdom="+ plain_vdom_name } } ] } - try: # get routing table per vdom - routing_helper = {} - routing_table = [] - fOS_getter.update_config_with_fortinet_api_call( - routing_helper, sid, fm_api_url, "/sys/proxy/json", - "routing-table-" + ip_version + '/' + full_vdom_name, - payload=payload, limit=limit, method="exec") - - if "routing-table-" + ip_version + '/' + full_vdom_name in routing_helper: - routing_helper = routing_helper["routing-table-" + ip_version + '/' + full_vdom_name] - if len(routing_helper)>0 and 'response' in routing_helper[0] and 'results' in routing_helper[0]['response']: - routing_table = routing_helper[0]['response']['results'] - else: - logger.warning("got empty " + ip_version + " routing table from device " + full_vdom_name + ", ignoring") - routing_table = [] - except: - logger.warning("could not get routing table for device " + full_vdom_name + ", ignoring") # exception " + str(traceback.format_exc())) - routing_table = [] - - # now storing the routing table: - raw_config.update({"routing-table-" + ip_version + '/' + full_vdom_name: routing_table}) - - -def get_device_from_package(package_name, mgm_details): - logger = getFwoLogger() - for dev in mgm_details['devices']: - if dev['local_rulebase_name'] == package_name: - return dev['id'] - logger.debug('get_device_from_package - could not find device for package "' + package_name + '"') - return None diff --git a/roles/importer/files/importer/checkpointR8x/__init__.py b/roles/importer/files/importer/fw_modules/azure2022ff/__init__.py similarity index 100% rename from roles/importer/files/importer/checkpointR8x/__init__.py rename to roles/importer/files/importer/fw_modules/azure2022ff/__init__.py diff --git a/roles/importer/files/importer/fw_modules/azure2022ff/fwcommon.py b/roles/importer/files/importer/fw_modules/azure2022ff/fwcommon.py new file mode 100644 index 0000000000..65b4174a5f --- /dev/null +++ b/roles/importer/files/importer/fw_modules/azure2022ff/fwcommon.py @@ -0,0 +1,10 @@ +from model_controllers.fwconfigmanagerlist_controller import FwConfigManagerListController +from model_controllers.import_state_controller import ImportStateController +from models.fw_common import FwCommon + + +class Azure2022ffCommon(FwCommon): + def get_config( + self, config_in: FwConfigManagerListController, import_state: ImportStateController + ) -> tuple[int, FwConfigManagerListController]: + raise NotImplementedError("Azure 2022 ff is not supported yet in the new python importer.") diff --git a/roles/importer/files/importer/ciscofirepowerdomain7ff/__init__.py b/roles/importer/files/importer/fw_modules/checkpointR8x/__init__.py similarity index 100% rename from roles/importer/files/importer/ciscofirepowerdomain7ff/__init__.py rename to roles/importer/files/importer/fw_modules/checkpointR8x/__init__.py diff --git a/roles/importer/files/importer/fw_modules/checkpointR8x/cp_const.py b/roles/importer/files/importer/fw_modules/checkpointR8x/cp_const.py new file mode 100644 index 0000000000..de0369d729 --- /dev/null +++ b/roles/importer/files/importer/fw_modules/checkpointR8x/cp_const.py @@ -0,0 +1,106 @@ +details_level = "standard" +details_level_objects = "standard" +details_level_group_objects = "full" +use_object_dictionary = True +with_hits = True + +dummy_ip = "0.0.0.0/32" + +# the following is the static across all installations unique any obj uid +# cannot fetch the Any object via API (<=1.7) at the moment +# therefore we have a workaround adding the object manually (as svc and nw) +any_obj_uid = "97aeb369-9aea-11d5-bd16-0090272ccb30" +none_obj_uid = "97aeb36a-9aea-11d5-bd16-0090272ccb30" +internet_obj_uid = "f99b1488-7510-11e2-8668-87656188709b" +# TODO: read this from config (from API 1.6 on it is fetched) + +original_obj_uid = "85c0f50f-6d8a-4528-88ab-5fb11d8fe16c" +# used for nat only (both svc and nw obj) + +local_nw_obj_table_names = [ + "hosts", + "networks", + "groups", + "address-ranges", + "multicast-address-ranges", + "groups-with-exclusion", + "gateways-and-servers", + "simple-gateways", + "dns-domains", + "interoperable-devices", + "security-zones", + "access-roles", + "CpmiVoipSipDomain", + "CpmiVoipMgcpDomain", + "gsn_handover_group", +] + +time_obj_table_names = ["times"] + +# the global objects need to be fetched only once per super manager +global_nw_obj_table_names = ["updatable-objects", "dynamic-objects"] + +nw_obj_table_names = local_nw_obj_table_names + global_nw_obj_table_names + +# simple as in: no groups +simple_svc_obj_types = [ + "services-tcp", + "services-udp", + "services-dce-rpc", + "services-rpc", + "services-other", + "services-icmp", + "services-icmp6", + "services-sctp", + "services-gtp", +] + +local_group_svc_obj_types = ["service-groups"] +global_group_svc_obj_types = ["application-site-categories", "application-sites"] +group_svc_obj_types = local_group_svc_obj_types + global_group_svc_obj_types + +local_svc_obj_table_names = local_group_svc_obj_types + simple_svc_obj_types # + [ 'CpmiAnyObject' ] +global_svc_obj_table_names = [*global_group_svc_obj_types, "CpmiAnyObject"] +svc_obj_table_names = local_svc_obj_table_names + global_svc_obj_table_names + +local_api_obj_types = ( + local_nw_obj_table_names + local_svc_obj_table_names + time_obj_table_names +) # all obj table names to look at during import +global_api_obj_types = ( + global_nw_obj_table_names + global_svc_obj_table_names +) # all global obj table names to look at during import +api_obj_types = ( + nw_obj_table_names + svc_obj_table_names + time_obj_table_names +) # all obj table names to look at during import + +types_to_remove_globals_from = ["service-groups"] + +obj_types_full_fetch_needed = [ + "access-roles", + "groups", + "groups-with-exclusion", + "updatable-objects", + "gateways-and-servers", + "services-other", + *group_svc_obj_types, + *time_obj_table_names, +] + +cp_specific_object_types = [ # used for fetching enrichment data via "get object" separately (no specific API call) + "simple-gateway", + "simple-cluster", + "CpmiVsClusterNetobj", + "CpmiVsxClusterNetobj", + "CpmiVsxClusterMember", + "CpmiVsNetobj", + "CpmiAnyObject", + "CpmiVsxNetobj", + "CpmiClusterMember", + "CpmiGatewayPlain", + "CpmiHostCkp", + "CpmiGatewayCluster", + "checkpoint-host", + "cluster-member", + "CpmiVoipSipDomain", + "CpmiVoipMgcpDomain", +] diff --git a/roles/importer/files/importer/fw_modules/checkpointR8x/cp_gateway.py b/roles/importer/files/importer/fw_modules/checkpointR8x/cp_gateway.py new file mode 100644 index 0000000000..725467049b --- /dev/null +++ b/roles/importer/files/importer/fw_modules/checkpointR8x/cp_gateway.py @@ -0,0 +1,70 @@ +from typing import Any + +from fwo_log import FWOLogger +from models.import_state import ImportState + +""" + normalize all gateway details +""" + + +def normalize_gateways(native_config: dict[str, Any], import_state: ImportState, normalized_config: dict[str, Any]): + normalized_config["gateways"] = [] + normalize_rulebase_links(native_config, normalized_config) + normalize_interfaces(native_config, import_state, normalized_config) + normalize_routing(native_config, import_state, normalized_config) + + +def normalize_rulebase_links(native_config: dict[str, Any], normalized_config: dict[str, Any]): + gw_range = range(len(native_config["gateways"])) + for gw_id in gw_range: + gw_uid = native_config["gateways"][gw_id]["uid"] + if not gw_in_normalized_config(normalized_config, gw_uid): + gw_normalized = create_normalized_gateway(native_config, gw_id) + normalized_config["gateways"].append(gw_normalized) + for gw_normalized in normalized_config["gateways"]: + if gw_normalized["Uid"] == gw_uid: + gw_normalized["RulebaseLinks"] = get_normalized_rulebase_link(native_config, gw_id) + break + + +def get_normalized_rulebase_link(native_config: dict[str, Any], gw_id: int) -> list[dict[str, Any]]: + links = native_config.get("gateways", {})[gw_id].get("rulebase_links") + for link in links: + if "type" in link: + link["link_type"] = link["type"] + del link["type"] + else: + FWOLogger.warning("No type in rulebase link: " + str(link)) + + # Remove from_rulebase_uid and from_rule_uid if link_type is initial + if link["link_type"] == "initial": + if link["from_rulebase_uid"] is not None: + link["from_rulebase_uid"] = None + if link["from_rule_uid"] is not None: + link["from_rule_uid"] = None + return links + + +def create_normalized_gateway(native_config: dict[str, Any], gw_id: int) -> dict[str, Any]: + gw: dict[str, Any] = {} + gw["Uid"] = native_config["gateways"][gw_id]["uid"] + gw["Name"] = native_config["gateways"][gw_id]["name"] + gw["Interfaces"] = [] + gw["Routing"] = [] + gw["RulebaseLinks"] = [] + return gw + + +def normalize_interfaces(native_config: dict[str, Any], import_state: ImportState, normalized_config: dict[str, Any]): + # TODO: Implement this + pass + + +def normalize_routing(native_config: dict[str, Any], import_state: ImportState, normalized_config: dict[str, Any]): + # TODO: Implement this + pass + + +def gw_in_normalized_config(normalized_config: dict[str, Any], gw_uid: str) -> bool: + return any(gw["Uid"] == gw_uid for gw in normalized_config["gateways"]) diff --git a/roles/importer/files/importer/fw_modules/checkpointR8x/cp_getter.py b/roles/importer/files/importer/fw_modules/checkpointR8x/cp_getter.py new file mode 100644 index 0000000000..39dcb15e93 --- /dev/null +++ b/roles/importer/files/importer/fw_modules/checkpointR8x/cp_getter.py @@ -0,0 +1,974 @@ +# library for API get functions +import json +import time +from datetime import datetime +from typing import Any + +import fwo_const +import fwo_globals +import requests +from fw_modules.checkpointR8x import cp_const, cp_network +from fwo_exceptions import FwApiError, FwApiResponseDecodingError, FwLoginFailedError, FwoImporterError +from fwo_log import FWOLogger +from model_controllers.management_controller import ManagementController +from services.service_provider import ServiceProvider + +# Constants for status values +STATUS_IN_PROGRESS = "in progress" +STATUS_SUCCEEDED = "succeeded" +STATUS_FAILED = "failed" + + +def cp_api_call(url: str, command: str, json_payload: dict[str, Any], sid: str | None, show_progress: bool = False): + url += command + request_headers = {"Content-Type": "application/json"} + if sid: # only not set for login + request_headers.update({"X-chkp-sid": sid}) + + FWOLogger.debug(f"api call '{command}'", 9) + if command != "login": # do not log passwords + FWOLogger.debug("json_payload: " + str(json_payload), 10) + + try: + r = requests.post(url, json=json_payload, headers=request_headers, verify=fwo_globals.verify_certs) + except requests.exceptions.RequestException as _: + if "password" in json.dumps(json_payload): + exception_text = "\nerror while sending api_call containing credential information to url '" + str(url) + else: + exception_text = ( + "\nerror while sending api_call to url '" + + str(url) + + "' with payload '" + + json.dumps(json_payload, indent=2) + + "' and headers: '" + + json.dumps(request_headers, indent=2) + ) + raise FwApiError(exception_text) + if show_progress: + print(".", end="", flush=True) # noqa: T201 + + try: + json_response = r.json() + except Exception: + raise FwApiResponseDecodingError(f"checkpointR8x:api_call: response is not in valid json format: {r.text}") + return json_response + + +def login(mgm_details: ManagementController): + payload = {"user": mgm_details.import_user, "password": mgm_details.secret} + domain = mgm_details.get_domain_string() + if domain != "": + payload.update({"domain": domain}) + base_url = mgm_details.build_fw_api_string() + FWOLogger.debug(f"login - login to url {base_url} with user {mgm_details.import_user}", 3) + response = cp_api_call(base_url, "login", payload, "") + if "sid" not in response: + exception_text = ( + f"getter ERROR: did not receive a sid for api call: {base_url}. " + "Please check credentials, API URL, network connectivity, and user permissions." + ) + raise FwLoginFailedError(exception_text) + return response["sid"] + + +def logout(url: str, sid: str): + FWOLogger.debug("logout from url " + url, 3) + return cp_api_call(url, "logout", {}, sid) + + +def process_single_task(task: dict[str, Any]) -> tuple[str, int]: + """Process a single task and return status and result code.""" + FWOLogger.debug("task: " + json.dumps(task), 6) + + if "status" not in task: + FWOLogger.error("no status in task") + return STATUS_FAILED, -1 + + status = task["status"] + + if STATUS_SUCCEEDED in status: + result = check_task_details_for_changes(task) + return status, result + if status == STATUS_FAILED: + FWOLogger.debug("show-changes - status: failed -> no changes found") + return status, 0 + if status == STATUS_IN_PROGRESS: + FWOLogger.debug("status: in progress") + return status, 0 + FWOLogger.error("unknown status: " + status) + return STATUS_FAILED, -1 + + +def process_changes_task(base_url: str, task_id: dict[str, Any], sid: str) -> int: + """Process the changes task and return the result.""" + sleeptime = 1 + status = STATUS_IN_PROGRESS + + while status == STATUS_IN_PROGRESS: + time.sleep(sleeptime) + tasks = cp_api_call(base_url, "show-task", task_id, sid) + + if "tasks" not in tasks: + FWOLogger.error("no tasks in task response") + return -1 + + for task in tasks["tasks"]: + status, result = process_single_task(task) + if status != STATUS_IN_PROGRESS: + return result + + sleeptime += 2 + if sleeptime > 40: # noqa: PLR2004 + FWOLogger.error("task took too long, aborting") + return -1 + + return 0 + + +def check_task_details_for_changes(task: dict[str, Any]) -> int: + """Check task details to see if changes were found.""" + for detail in task["task-details"]: + if detail["changes"]: + FWOLogger.debug("status: succeeded -> changes found") + return 1 + FWOLogger.debug("status: succeeded -> but no changes found") + return 0 + + +def get_changes(sid: str, api_host: str, api_port: str, fromdate: str) -> int: + dt_object = datetime.fromisoformat(fromdate) + dt_truncated = dt_object.replace(microsecond=0) # Truncate microseconds + fromdate = dt_truncated.isoformat() + + payload = {"from-date": fromdate, "details-level": "uid"} + FWOLogger.debug("payload: " + json.dumps(payload)) + base_url = "https://" + api_host + ":" + str(api_port) + "/web_api/" + task_id = cp_api_call(base_url, "show-changes", payload, sid) + + FWOLogger.debug("task_id: " + json.dumps(task_id)) + return process_changes_task(base_url, task_id, sid) + + +def get_policy_structure( + api_v_url: str, + sid: str, + show_params_policy_structure: dict[str, Any], + manager_details: ManagementController, + policy_structure: list[dict[str, Any]] | None = None, +) -> int: + if policy_structure is None: + policy_structure = [] + + current = 0 + total = current + 1 + + show_params_policy_structure.update({"offset": current}) + + while current < total: + packages, current, total = get_show_packages_via_api(api_v_url, sid, show_params_policy_structure) + + for package in packages["packages"]: + current_package, already_fetched_package = parse_package(package, manager_details) + if not already_fetched_package: + continue + add_access_layers_to_current_package(package, current_package) + + # in future threat-layers may be fetched analog to add_access_layers_to_current_package + policy_structure.append(current_package) + + return 0 + + +def get_show_packages_via_api( + api_v_url: str, sid: str, show_params_policy_structure: dict[str, Any] +) -> tuple[dict[str, Any], int, int]: + try: + packages = cp_api_call(api_v_url, "show-packages", show_params_policy_structure, sid) + except Exception: + raise FwApiError("could not return 'show-packages'") + + if "total" in packages: + total = packages["total"] + else: + FWOLogger.error("packages do not contain total field") + FWOLogger.warning("sid: " + sid) + FWOLogger.warning("api_v_url: " + api_v_url) + for key, value in show_params_policy_structure.items(): + FWOLogger.warning("show_params_policy_structure " + key + ": " + str(value)) + for key, value in packages.items(): + FWOLogger.warning("packages " + key + ": " + str(value)) + raise FwApiError("packages do not contain total field") + + if total == 0: + current = 0 + elif "to" in packages: + current = packages["to"] + else: + raise FwApiError("packages do not contain to field") + return packages, current, total + + +def parse_package(package: dict[str, Any], manager_details: ManagementController) -> tuple[dict[str, Any], bool]: + already_fetched_package = False + current_package = {} + if "installation-targets" in package and package["installation-targets"] == "all": + if not already_fetched_package: + current_package: dict[str, Any] = { + "name": package["name"], + "uid": package["uid"], + "targets": [{"name": "all", "uid": "all"}], + "access-layers": [], + } + already_fetched_package = True + + elif "installation-targets-revision" in package: + for installation_target in package["installation-targets-revision"]: + if is_valid_installation_target(installation_target, manager_details): + if not already_fetched_package: + current_package = { + "name": package["name"], + "uid": package["uid"], + "targets": [], + "access-layers": [], + } + already_fetched_package = True + + current_package["targets"].append( + {"name": installation_target["target-name"], "uid": installation_target["target-uid"]} + ) + else: + FWOLogger.warning("installation target in package: " + package["uid"] + " is missing name or uid") + return current_package, already_fetched_package + + +def is_valid_installation_target(installation_target: dict[str, Any], manager_details: ManagementController) -> bool: + """Ensures that target is defined as gateway in database""" + if "target-name" in installation_target and "target-uid" in installation_target: + for device in manager_details.devices: + if ( + device["name"] == installation_target["target-name"] + and device["uid"] == installation_target["target-uid"] + ): + return True + return False + + +def add_access_layers_to_current_package(package: dict[str, Any], current_package: dict[str, Any]) -> None: + if "access-layers" in package: + for access_layer in package["access-layers"]: + if "name" in access_layer and "uid" in access_layer: + current_package["access-layers"].append( + {"name": access_layer["name"], "uid": access_layer["uid"], "domain": access_layer["domain"]["uid"]} + ) + else: + raise FwApiError("access layer in package: " + package["uid"] + " is missing name or uid") + + +def fetch_global_assignments_chunk( + api_v_url: str, sid: str, show_params_policy_structure: dict[str, Any] +) -> tuple[dict[str, Any], int, int]: + """Fetch a chunk of global assignments from the API.""" + try: + assignments = cp_api_call(api_v_url, "show-global-assignments", show_params_policy_structure, sid) + except Exception: + FWOLogger.error("could not return 'show-global-assignments'") + raise FwoImporterError('could not return "show-global-assignments"') + + if "total" not in assignments: + log_global_assignments_error(sid, api_v_url, show_params_policy_structure, assignments) + raise FwoImporterError('global assignments do not contain "total" field') + + total = assignments["total"] + + if total == 0: + current = 0 + else: + if "to" not in assignments: + raise FwoImporterError('global assignments do not contain "to" field') + current = assignments["to"] + + return assignments, current, total + + +def log_global_assignments_error( + sid: str, api_v_url: str, show_params_policy_structure: dict[str, Any], assignments: dict[str, Any] +) -> None: + """Log error information for global assignments debugging.""" + FWOLogger.warning("sid: " + sid) + FWOLogger.warning("api_v_url: " + api_v_url) + for key, value in show_params_policy_structure.items(): + FWOLogger.warning("show_params_policy_structure " + key + ": " + str(value)) + for key, value in assignments.items(): + FWOLogger.warning("global assignments " + key + ": " + str(value)) + + +def parse_global_assignment(assignment: dict[str, Any]) -> dict[str, Any]: + """Parse a single global assignment object.""" + if "type" not in assignment or assignment["type"] != "global-assignment": + raise FwoImporterError("global assignment with unexpected type") + + return { + "uid": assignment["uid"], + "global-domain": {"uid": assignment["global-domain"]["uid"], "name": assignment["global-domain"]["name"]}, + "dependent-domain": { + "uid": assignment["dependent-domain"]["uid"], + "name": assignment["dependent-domain"]["name"], + }, + "global-access-policy": assignment["global-access-policy"], + } + + +def get_global_assignments(api_v_url: str, sid: str, show_params_policy_structure: dict[str, Any]) -> list[Any]: + current = 0 + total = current + 1 + show_params_policy_structure.update({"offset": current}) + global_assignments: list[dict[str, Any]] = [] + + while current < total: + assignments, current, total = fetch_global_assignments_chunk(api_v_url, sid, show_params_policy_structure) + + # parse global assignments + for assignment in assignments["objects"]: + global_assignment = parse_global_assignment(assignment) + global_assignments.append(global_assignment) + + return global_assignments + + +def get_rulebases( + api_v_url: str, + sid: str | None, + show_params_rules: dict[str, Any], + native_config_domain: dict[str, Any] | None, + device_config: dict[str, Any] | None, + policy_rulebases_uid_list: list[str], + is_global: bool = False, + access_type: str = "access", + rulebase_uid: str | None = None, + rulebase_name: str | None = None, +) -> list[str]: + # i access_type : access / nat + native_config_rulebase_key = "rulebases" + current_rulebase = {} + + if native_config_domain is None: + native_config_domain = {"rulebases": [], "nat_rulebases": []} + if device_config is None: + device_config = {"rulebase_links": []} + + if access_type == "access": + native_config_rulebase_key = "rulebases" + elif access_type == "nat": + native_config_rulebase_key = "nat_rulebases" + else: + FWOLogger.error('access_type is neither "access" nor "nat", but ' + access_type) + + # get uid of rulebase + if rulebase_uid is None: + if rulebase_name is not None: + rulebase_uid = get_uid_of_rulebase(rulebase_name, api_v_url, access_type, sid) + else: + FWOLogger.error("must provide either rulebaseUid or rulebaseName") + policy_rulebases_uid_list.append(rulebase_uid) # type: ignore # TODO: get_uid_of_rulebase can return None but in theory should not # noqa: PGH003 + + # search all rulebases in nativeConfigDomain and import if rulebase is not already fetched + fetched_rulebase_list: list[str] = [] + for fetched_rulebase in native_config_domain[native_config_rulebase_key]: + fetched_rulebase_list.append(fetched_rulebase["uid"]) + if fetched_rulebase["uid"] == rulebase_uid: + current_rulebase = fetched_rulebase + break + + # get rulebase in chunks + if rulebase_uid not in fetched_rulebase_list: + current_rulebase = get_rulebases_in_chunks( + rulebase_uid, # type: ignore # noqa: PGH003 + show_params_rules, + api_v_url, + access_type, + sid, # type: ignore # noqa: PGH003 + native_config_domain, # type: ignore #TODO: check if None check is needed if yes, change type # noqa: PGH003 + ) # type: ignore # TODO: rulebaseUid can be None but in theory should not # noqa: PGH003 + native_config_domain[native_config_rulebase_key].append(current_rulebase) + + # use recursion to get inline layers + return get_inline_layers_recursively( + current_rulebase, + device_config, + native_config_domain, + api_v_url, + sid, + show_params_rules, + is_global, + policy_rulebases_uid_list, + ) + + +def get_uid_of_rulebase( + rulebase_name: str, api_v_url: str, access_type: str, sid: str | None +) -> str | None: # TODO: what happens if rulebaseUid None? Error? + rulebase_uid = None + get_rulebase_uid_params: dict[str, Any] = { + "name": rulebase_name, + "limit": 1, + "use-object-dictionary": False, + "details-level": "uid", + "show-hits": False, + } + try: + rulebase_for_uid = cp_api_call(api_v_url, "show-" + access_type + "-rulebase", get_rulebase_uid_params, sid) + rulebase_uid = rulebase_for_uid["uid"] + except Exception: + FWOLogger.error("could not find uid for rulebase name=" + rulebase_name) + + return rulebase_uid + + +def get_rulebases_in_chunks( + rulebase_uid: str, + show_params_rules: dict[str, Any], + api_v_url: str, + access_type: str, + sid: str, + native_config_domain: dict[str, Any], +) -> dict[str, Any]: + current_rulebase: dict[str, Any] = {"uid": rulebase_uid, "name": "", "chunks": []} + show_params_rules.update({"uid": rulebase_uid}) + current = 0 + total = current + 1 + + while current < total: + show_params_rules.update({"offset": current}) + + try: + rulebase = cp_api_call(api_v_url, "show-" + access_type + "-rulebase", show_params_rules, sid) + if current_rulebase["name"] == "" and "name" in rulebase: + current_rulebase.update({"name": rulebase["name"]}) + except Exception: + FWOLogger.error("could not find rulebase uid=" + rulebase_uid) + + service_provider = ServiceProvider() + global_state = service_provider.get_global_state() + description = f"failed to get show-access-rulebase {rulebase_uid}" + global_state.import_state.api_call.create_data_issue(severity=2, description=description) + raise FwApiError("") + + resolve_checkpoint_uids_via_object_dict( + rulebase, native_config_domain, current_rulebase, rulebase_uid, show_params_rules + ) + total, current = control_while_loop_in_get_rulebases_in_chunks( + current_rulebase, rulebase, sid, api_v_url, show_params_rules + ) + + return current_rulebase + + +def resolve_checkpoint_uids_via_object_dict( + rulebase: dict[str, Any], + native_config_domain: dict[str, Any], + current_rulebase: dict[str, Any], + rulebase_uid: str, + show_params_rules: dict[str, Any], +) -> None: + """ + Checkpoint stores some rulefields as uids, function translates them to names + """ + try: + for rule_field in ["source", "destination", "service", "action", "track", "install-on", "time"]: + resolve_ref_list_from_object_dictionary(rulebase, rule_field, native_config_domain=native_config_domain) + current_rulebase["chunks"].append(rulebase) + except Exception: + FWOLogger.error("error while getting a field of layer " + rulebase_uid + ", params: " + str(show_params_rules)) + + +def control_while_loop_in_get_rulebases_in_chunks( + current_rulebase: dict[str, Any], + rulebase: dict[str, Any], + sid: str, + api_v_url: str, + show_params_rules: dict[str, Any], +) -> tuple[int, int]: + total = 0 + if "total" in rulebase: + total = rulebase["total"] + else: + FWOLogger.error( + "rulebase does not contain total field, get_rulebase_chunk_from_api found garbled json " + + str(current_rulebase) + ) + FWOLogger.warning("sid: " + sid) + FWOLogger.warning("api_v_url: " + api_v_url) + for key, value in show_params_rules.items(): + FWOLogger.warning("show_params_rules " + key + ": " + str(value)) + for key, value in rulebase.items(): + FWOLogger.warning("rulebase " + key + ": " + str(value)) + + if total == 0: + current = 0 + elif "to" in rulebase: + current = rulebase["to"] + else: + raise FwoImporterError( + "get_nat_rules_from_api - rulebase does not contain to field, get_rulebase_chunk_from_api found garbled json " + + str(rulebase) + ) + return total, current + + +def get_inline_layers_recursively( + current_rulebase: dict[str, Any], + device_config: dict[str, Any], + native_config_domain: dict[str, Any], + api_v_url: str, + sid: str | None, + show_params_rules: dict[str, Any], + is_global: bool, + policy_rulebases_uid_list: list[str], +) -> list[str]: + """ + Takes current_rulebase, splits sections into sub-rulebases and searches for layerguards to fetch + """ + current_rulebase_uid = current_rulebase["uid"] + for rulebase_chunk in current_rulebase["chunks"]: + # search in case of access rulebase only + if "rulebase" in rulebase_chunk: + for section in rulebase_chunk["rulebase"]: + section_link, current_rulebase_uid = section_traversal_and_links( + section, current_rulebase_uid, device_config, is_global + ) + + for rule in section_link["rulebase"]: + if "inline-layer" in rule: + # add link to inline layer for current device + device_config["rulebase_links"].append( + { + "from_rulebase_uid": current_rulebase_uid, + "from_rule_uid": rule["uid"], + "to_rulebase_uid": rule["inline-layer"], + "type": "inline", + "is_initial": False, + "is_global": is_global, + "is_section": False, + } + ) + + # get inline layer + policy_rulebases_uid_list = get_rulebases( + api_v_url, + sid, + show_params_rules, + native_config_domain, + device_config, + policy_rulebases_uid_list, + is_global=is_global, + access_type="access", + rulebase_uid=rule["inline-layer"], + ) + + return policy_rulebases_uid_list + + +def section_traversal_and_links( + section: dict[str, Any], current_rulebase_uid: str, device_config: dict[str, Any], is_global: bool +) -> tuple[dict[str, Any], str]: + """ + If section is actually rule, fake it to be section and link sections as self-contained rulebases + """ + # if no section is used, create dummy section + dummy_section = False + is_section = True + if section["type"] != "access-section": + section = {"type": "access-section", "uid": section["uid"], "rulebase": [section]} + dummy_section = True + + # define placeholder rules as concatenated rulebase + if dummy_section and section["rulebase"][0]["type"] == "place-holder": + dummy_section = False + is_section = False + + # define section chain + if not dummy_section: + device_config["rulebase_links"].append( + { + "from_rulebase_uid": current_rulebase_uid, + "from_rule_uid": None, + "to_rulebase_uid": section["uid"], + "type": "concatenated", + "is_global": is_global, + "is_initial": False, + "is_section": is_section, + } + ) + current_rulebase_uid = section["uid"] + + return section, current_rulebase_uid + + +def get_placeholder_in_rulebase(rulebase: dict[str, Any]) -> tuple[str | None, str | None]: + placeholder_rule_uid = None + placeholder_rulebase_uid = None + for rulebase_chunk in rulebase["chunks"]: + # search in case of access rulebase only + if "rulebase" in rulebase_chunk: + for section in rulebase_chunk["rulebase"]: + # if no section is used, use dummy section + section_link = section + if section["type"] != "access-section": + section_link: dict[str, Any] = {"type": "access-section", "rulebase": [section]} + + for rule in section_link["rulebase"]: + placeholder_rule_uid, placeholder_rulebase_uid = assign_placeholder_uids( + rulebase, section, rule, placeholder_rule_uid, placeholder_rulebase_uid + ) + + return placeholder_rule_uid, placeholder_rulebase_uid + + +def assign_placeholder_uids( + rulebase: dict[str, Any], + section: dict[str, Any], + rule: dict[str, Any], + placeholder_rule_uid: str | None, + placeholder_rulebase_uid: str | None, +) -> tuple[str | None, str | None]: + if rule["type"] == "place-holder": + placeholder_rule_uid = rule["uid"] + placeholder_rulebase_uid = section["uid"] if "uid" in section else rulebase["uid"] + return placeholder_rule_uid, placeholder_rulebase_uid + + +def get_nat_rules_from_api_as_dict( + api_v_url: str, sid: str, show_params_rules: dict[str, Any], native_config_domain: dict[str, Any] | None = None +): + if native_config_domain is None: + native_config_domain = {} + nat_rules: dict[str, list[Any]] = {"nat_rule_chunks": []} + current = 0 + total = current + 1 + while current < total: + show_params_rules["offset"] = current + FWOLogger.debug("params: " + str(show_params_rules)) + rulebase = cp_api_call(api_v_url, "show-nat-rulebase", show_params_rules, sid) + + for rule_field in [ + "original-source", + "original-destination", + "original-service", + "translated-source", + "translated-destination", + "translated-service", + "action", + "track", + "install-on", + "time", + ]: + resolve_ref_list_from_object_dictionary(rulebase, rule_field, native_config_domain=native_config_domain) + + nat_rules["nat_rule_chunks"].append(rulebase) + if "total" in rulebase: + total = rulebase["total"] + else: + FWOLogger.error( + "get_nat_rules_from_api - rulebase does not contain total field, get_rulebase_chunk_from_api found garbled json " + + str(nat_rules) + ) + if total == 0: + current = 0 + elif "to" in rulebase: + current = rulebase["to"] + else: + raise FwApiError( + "get_nat_rules_from_api - rulebase does not contain to field, get_rulebase_chunk_from_api found garbled json " + + str(nat_rules) + ) + return nat_rules + + +def find_element_by_uid(array: list[dict[str, Any]], uid: str | None) -> dict[str, Any] | None: + for el in array: + if "uid" in el and el["uid"] == uid: + return el + return None + + +def resolve_ref_from_object_dictionary( + uid: str | None, + obj_dict: list[dict[str, Any]], + native_config_domain: dict[str, Any] | None = None, + field_name: str | None = None, +) -> dict[str, Any] | None: + if native_config_domain is None: + native_config_domain = {} + matched_obj = find_element_by_uid(obj_dict, uid) + + if matched_obj is None: # object not in dict - need to fetch it from API + if field_name != "track" and uid != "29e53e3d-23bf-48fe-b6b1-d59bd88036f9": + # 29e53e3d-23bf-48fe-b6b1-d59bd88036f9 is a track object uid (track None) which is not in the object dictionary, but used in some rules + if field_name is None: + field_name = "unknown" + if uid is None: + uid = "unknown" + FWOLogger.warning(f"object of type {field_name} with uid {uid} not found in object dictionary") + return None + # there are some objects (at least CpmiVoipSipDomain) which are not API-gettable with show-objects (only with show-object "UID") + # these must be added to the (network) objects tables + if matched_obj["type"] in ["CpmiVoipSipDomain", "CpmiVoipMgcpDomain", "gsn_handover_group"]: + FWOLogger.info( + f"adding {matched_obj['type']} '{matched_obj['name']}' object manually, because it is not retrieved by show objects API command" + ) + color = matched_obj.get("color", "black") + native_config_domain["objects"].append( + { + "type": matched_obj["type"], + "chunks": [ + { + "objects": [ + { + "uid": matched_obj["uid"], + "name": matched_obj["name"], + "color": color, + "type": matched_obj["type"], + "domain": matched_obj["domain"], + } + ] + } + ], + } + ) + + return matched_obj + + +# resolving all uid references using the object dictionary +# dealing with a single chunk +def resolve_ref_list_from_object_dictionary( + rulebase: list[dict[str, Any]] | dict[str, Any], + value: str, + obj_dicts: list[dict[str, Any]] | None = None, + native_config_domain: dict[str, Any] | None = None, +): # TODO: what is objDict: I think it should be a list of dicts + if native_config_domain is None: + native_config_domain = {} + if obj_dicts is None: + obj_dicts = [] + if isinstance(rulebase, dict) and "objects-dictionary" in rulebase: + obj_dicts = rulebase["objects-dictionary"] + if isinstance(rulebase, list): # found a list of rules + for rule in rulebase: + if value in rule: + categorize_value_for_resolve_ref(rule, value, obj_dicts, native_config_domain) # type: ignore # noqa: PGH003 + if "rulebase" in rule: + resolve_ref_list_from_object_dictionary( + rule["rulebase"], value, obj_dicts=obj_dicts, native_config_domain=native_config_domain + ) + elif "rulebase" in rulebase: + resolve_ref_list_from_object_dictionary( + rulebase["rulebase"], value, obj_dicts=obj_dicts, native_config_domain=native_config_domain + ) + + +def categorize_value_for_resolve_ref( + rule: dict[str, Any], value: str, obj_dict: list[dict[str, Any]], native_config_domain: dict[str, Any] +): + value_list: list[Any] = [] + if isinstance(rule[value], str): # assuming single uid + rule[value] = resolve_ref_from_object_dictionary( + rule[value], obj_dict, native_config_domain=native_config_domain, field_name=value + ) + elif "type" in rule[value]: # e.g. track + rule[value] = resolve_ref_from_object_dictionary( + rule[value]["type"], obj_dict, native_config_domain=native_config_domain, field_name=value + ) + else: # assuming list of rules + value_list.extend( + [ + resolve_ref_from_object_dictionary( + rule_id, obj_dict, native_config_domain=native_config_domain, field_name=value + ) + for rule_id in rule[value] + ] + ) + + rule[value] = value_list # replace ref list with object list + + +def handle_cpmi_any_object(obj: dict[str, Any]) -> dict[str, Any]: + """Handle CpmiAnyObject type objects.""" + color = obj.get("color", "black") + + if obj["name"] == "Any": + return { + "type": "hosts", + "chunks": [ + { + "objects": [ + { + "uid": obj["uid"], + "name": obj["name"], + "color": color, + "comments": "any nw object checkpoint (hard coded)", + "type": "network", + "ipv4-address": fwo_const.ANY_IP_IPV4, + "domain": obj["domain"], + } + ] + } + ], + } + if obj["name"] == "None": # None service or network object + return { + "type": "hosts", + "chunks": [ + { + "objects": [ + { + "uid": obj["uid"], + "name": obj["name"], + "color": color, + "comments": "none nw object checkpoint (hard coded)", + "type": "group", + "domain": obj["domain"], + } + ] + } + ], + } + return {} + + +def handle_gateway_objects(obj: dict[str, Any]) -> dict[str, Any]: + """Handle various gateway and network member objects.""" + color = obj.get("color", "black") + return { + "type": "hosts", + "chunks": [ + { + "objects": [ + { + "uid": obj["uid"], + "name": obj["name"], + "color": color, + "comments": obj["comments"], + "type": "host", + "ipv4-address": cp_network.get_ip_of_obj(obj), + "domain": obj["domain"], + } + ] + } + ], + } + + +def handle_global_object(obj: dict[str, Any]) -> dict[str, Any]: + """Handle Global type objects.""" + color = obj.get("color", "black") + return { + "type": "hosts", + "chunks": [ + { + "objects": [ + { + "uid": obj["uid"], + "name": obj["name"], + "color": color, + "comments": obj["comments"], + "type": "host", + "ipv4-address": fwo_const.ANY_IP_IPV4, + "domain": obj["domain"], + } + ] + } + ], + } + + +def handle_updatable_objects(obj: dict[str, Any]) -> dict[str, Any]: + """Handle updatable objects and VoIP domains.""" + color = obj.get("color", "black") + return { + "type": "hosts", + "chunks": [ + { + "objects": [ + { + "uid": obj["uid"], + "name": obj["name"], + "color": color, + "comments": obj["comments"], + "type": "host", + "domain": obj["domain"], + } + ] + } + ], + } + + +def handle_network_zone_objects(obj: dict[str, Any]) -> dict[str, Any]: + """Handle Internet and security-zone objects.""" + color = obj.get("color", "black") + return { + "type": "hosts", + "chunks": [ + { + "objects": [ + { + "uid": obj["uid"], + "name": obj["name"], + "color": color, + "comments": obj["comments"], + "type": "network", + "ipv4-address": fwo_const.ANY_IP_IPV4, + "domain": obj["domain"], + } + ] + } + ], + } + + +def get_object_details_from_api(uid_missing_obj: str, sid: str = "", apiurl: str = "") -> dict[str, Any]: + FWOLogger.debug(f"getting {uid_missing_obj} from API", 6) + + show_params_host = {"details-level": "full", "uid": uid_missing_obj} # need to get the full object here + try: + obj = cp_api_call(apiurl, "show-object", show_params_host, sid) + except Exception as e: + raise FwoImporterError(f"error while trying to get details for object with uid {uid_missing_obj}: {e}") + + if obj is None: + raise FwoImporterError(f"None received while trying to get details for object with uid {uid_missing_obj}") + + if "object" not in obj: + if "code" in obj: + FWOLogger.warning("broken ref in CP DB uid=" + uid_missing_obj + ": " + obj["code"]) + else: + FWOLogger.warning("broken ref in CP DB uid=" + uid_missing_obj) + return {} + + obj = obj["object"] + obj_type = obj["type"] + + # Handle different object types + if obj_type == "CpmiAnyObject": + return handle_cpmi_any_object(obj) + if obj_type in [ + "simple-gateway", + "CpmiGatewayPlain", + "interop", + "multicast-address-range", + "CpmiVsClusterMember", + "CpmiVsxClusterMember", + "CpmiVsxNetobj", + ]: + return handle_gateway_objects(obj) + if obj_type == "Global": + return handle_global_object(obj) + if obj_type in ["updatable-object", "CpmiVoipSipDomain", "CpmiVoipMgcpDomain", "gsn_handover_group"]: + return handle_updatable_objects(obj) + if obj_type in ["Internet", "security-zone"]: + return handle_network_zone_objects(obj) + if obj_type == "access-role" or obj_type in cp_const.api_obj_types: + return obj + FWOLogger.warning(f"missing nw obj of unexpected type '{obj_type}': {uid_missing_obj}") + return {} diff --git a/roles/importer/files/importer/fw_modules/checkpointR8x/cp_network.py b/roles/importer/files/importer/fw_modules/checkpointR8x/cp_network.py new file mode 100644 index 0000000000..d1f5b78883 --- /dev/null +++ b/roles/importer/files/importer/fw_modules/checkpointR8x/cp_network.py @@ -0,0 +1,318 @@ +import ipaddress +import json +from datetime import datetime, timezone +from typing import Any + +import fwo_const +from fw_modules.checkpointR8x import cp_const +from fw_modules.fortiadom5ff.fmgr_network import add_member_names_for_nw_group +from fwo_base import cidr_to_range +from fwo_const import ANY_IP_END, ANY_IP_START, LIST_DELIMITER +from fwo_log import FWOLogger +from models.time_object import TimeObject +from services.service_provider import ServiceProvider + + +def normalize_network_objects( + full_config: dict[str, Any], config2import: dict[str, Any], import_id: int, mgm_id: int = 0 +): + nw_objects: list[dict[str, Any]] = [] + global_domain = initialize_global_domain(full_config["objects"]) + + for obj_dict in full_config["objects"]: + if obj_dict["type"] in cp_const.time_obj_table_names: + continue # time objects are handled in separate function + collect_nw_objects(obj_dict, nw_objects, global_domain, mgm_id=mgm_id) + + for nw_obj in nw_objects: + nw_obj.update({"control_id": import_id}) + if nw_obj["obj_typ"] == "interoperable-device": + nw_obj.update({"obj_typ": "external-gateway"}) + if nw_obj["obj_typ"] == "CpmiVoipSipDomain": + FWOLogger.info("found VOIP object - tranforming to empty group") + nw_obj.update({"obj_typ": "group"}) + set_dummy_ip_for_object_without_ip(nw_obj) + + for idx in range(len(nw_objects) - 1): + if nw_objects[idx]["obj_typ"] == "group": + add_member_names_for_nw_group(idx, nw_objects) + + config2import.update({"network_objects": nw_objects}) + + +def set_dummy_ip_for_object_without_ip(nw_obj: dict[str, Any]) -> None: + if nw_obj["obj_typ"] != "group" and (nw_obj["obj_ip"] is None or nw_obj["obj_ip"] == ""): + FWOLogger.warning( + "found object without IP :" + nw_obj["obj_name"] + " (type=" + nw_obj["obj_typ"] + ") - setting dummy IP" + ) + nw_obj.update({"obj_ip": fwo_const.DUMMY_IP}) + nw_obj.update({"obj_ip_end": fwo_const.DUMMY_IP}) + + +def initialize_global_domain(objects: list[dict[str, Any]]) -> dict[str, Any]: + """ + Returns CP Global Domain for MDS and standalone domain otherwise + """ + if len(objects) == 0: + FWOLogger.warning("No objects found in full config, cannot initialize global domain") + return {} + + if "domain_uid" not in objects[0] or "domain_name" not in objects[0]: + FWOLogger.debug("No domain information found in objects, this seems to be a standalone management") + return {} + + return {"domain": {"uid": objects[0]["domain_uid"], "name": objects[0]["domain_name"]}} + + +def collect_nw_objects( + object_table: dict[str, Any], nw_objects: list[dict[str, Any]], global_domain: dict[str, Any], mgm_id: int = 0 +) -> None: + """ + Collect nw_objects from object tables and write them into global nw_objects dict + """ + if object_table["type"] not in cp_const.nw_obj_table_names: + return + for chunk in object_table["chunks"]: + if "objects" in chunk: + for obj in chunk["objects"]: + if is_obj_already_collected(nw_objects, obj): + continue + member_refs, member_names = handle_members(obj) + ip_addr = get_ip_of_obj(obj, mgm_id=mgm_id) + obj_type, first_ip, last_ip = handle_object_type_and_ip(obj, ip_addr) + comments = get_comment_and_color_of_obj(obj) + + nw_objects.append( + { + "obj_uid": obj["uid"], + "obj_name": obj["name"], + "obj_color": obj["color"], + "obj_comment": comments, + "obj_domain": get_domain_uid(obj, global_domain), + "obj_typ": obj_type, + "obj_ip": first_ip, + "obj_ip_end": last_ip, + "obj_member_refs": member_refs, + "obj_member_names": member_names, + } + ) + + +def get_domain_uid(obj: dict[str, Any], global_domain: dict[str, Any]) -> str | dict[str, Any] | None: + """ + Returns the domain UID for the given object. + If the object has a 'domain' key with a 'uid', it returns that UID. + Otherwise, it returns the global domain UID. + """ + if "domain" not in obj or "uid" not in obj["domain"]: + return obj.update({"domain": global_domain}) # TODO: check if the None value is wanted + return obj["domain"]["uid"] + + +def is_obj_already_collected(nw_objects: list[dict[str, Any]], obj: dict[str, Any]) -> bool: + if "uid" not in obj: + FWOLogger.warning("found nw_object without uid: " + str(obj)) + return False + + if "domain" in obj: + for already_collected_obj in nw_objects: + if ( + obj["uid"] == already_collected_obj["obj_uid"] + and obj["domain"]["uid"] == already_collected_obj["obj_domain"] + ): + return True + else: + FWOLogger.warning("found nw_object without domain: " + obj["uid"]) + + return False + + +def handle_members(obj: dict[str, Any]) -> tuple[str | None, str | None]: + """ + Gets group member uids, currently no member_names + """ + member_refs = None + member_names = None + if "members" in obj: + member_refs = "" + member_names = "" + for member in obj["members"]: + member_refs += member + LIST_DELIMITER + member_refs = member_refs[:-1] + if obj["members"] == "": + obj["members"] = None + return member_refs, member_names + + +def handle_object_type_and_ip(obj: dict[str, Any], ip_addr: str | None) -> tuple[str, str | None, str | None]: + obj_type = "undef" + ip_array = cidr_to_range(ip_addr) + first_ip = None + last_ip = None + if len(ip_array) == 2: # noqa: PLR2004 + first_ip = ip_array[0] + last_ip = ip_array[1] + elif len(ip_array) == 1: + first_ip = ip_array[0] + last_ip = None + + if "type" in obj: + obj_type = obj["type"] + + if obj_type == "updatable-object": + first_ip = ANY_IP_START + last_ip = ANY_IP_END + obj_type = "dynamic_net_obj" + + if obj_type in ["group-with-exclusion", "security-zone", "dynamic-object"]: + obj_type = "group" + # TODO: handle exclusion groups correctly + + if obj_type == "dns-domain": + obj_type = "domain" + first_ip = ANY_IP_START + last_ip = ANY_IP_END + + if obj_type == "security-zone": + first_ip = ANY_IP_START + last_ip = ANY_IP_END + obj_type = "network" + + if obj_type in ["address-range", "multicast-address-range"]: + obj_type = "ip_range" + if "-" in str(ip_addr): + first_ip, last_ip = str(ip_addr).split("-") + else: + FWOLogger.warning( + "parse_network::collect_nw_objects - found range object '" + + obj["name"] + + "' without hyphen: " + + ip_addr + ) + elif obj_type in cp_const.cp_specific_object_types: + FWOLogger.debug(f"rewriting non-standard cp-host-type '{obj['name']}' with object type '{obj_type}' to host", 6) + FWOLogger.debug("obj_dump:" + json.dumps(obj, indent=3), 6) + obj_type = "host" + + return obj_type, first_ip, last_ip + + +def get_comment_and_color_of_obj(obj: dict[str, Any]) -> str | None: + """ + Returns comment and sets missing color to black + """ + comments = None if "comments" not in obj or obj["comments"] == "" else obj["comments"] + if "color" not in obj or obj["color"] == "" or obj["color"] == "none": + obj["color"] = "black" + return comments + + +def validate_ip_address(address: str) -> bool: + try: + ipaddress.ip_network(address) + return True + except ValueError: + return False + + +def get_ip_of_obj(obj: dict[str, Any], mgm_id: int | None = None) -> str | None: + if "ipv4-address" in obj: + ip_addr = obj["ipv4-address"] + elif "ipv6-address" in obj: + ip_addr = obj["ipv6-address"] + elif "subnet4" in obj: + ip_addr = obj["subnet4"] + "/" + str(obj["mask-length4"]) + elif "subnet6" in obj: + ip_addr = obj["subnet6"] + "/" + str(obj["mask-length6"]) + elif "ipv4-address-first" in obj and "ipv4-address-last" in obj: + ip_addr = obj["ipv4-address-first"] + "-" + str(obj["ipv4-address-last"]) + elif "ipv6-address-first" in obj and "ipv6-address-last" in obj: + ip_addr = obj["ipv6-address-first"] + "-" + str(obj["ipv6-address-last"]) + else: + ip_addr = None + + ## fix malformed ip addresses (should not regularly occur and constitutes a data issue in CP database) + if ip_addr is None or ( + "type" in obj and (obj["type"] == "address-range" or obj["type"] == "multicast-address-range") + ): + pass # ignore None and ranges here + elif not validate_ip_address(ip_addr): + alert_description = "object is not a valid ip address (" + str(ip_addr) + ")" + service_provider = ServiceProvider() + global_state = service_provider.get_global_state() + api_call = global_state.import_state.api_call + api_call.create_data_issue( + severity=2, obj_name=obj["name"], object_type=obj["type"], description=alert_description, mgm_id=mgm_id + ) + alert_description = ( + "object '" + obj["name"] + "' (type=" + obj["type"] + ") is not a valid ip address (" + str(ip_addr) + ")" + ) + api_call.set_alert( + title="import error", + severity=2, + description=alert_description, + source="import", + alert_code=17, + mgm_id=mgm_id, + ) + ip_addr = fwo_const.DUMMY_IP # setting syntactically correct dummy ip + return ip_addr + + +def make_host(ip_in: str) -> str | None: + ip_obj: ipaddress.IPv4Address | ipaddress.IPv6Address = ipaddress.ip_address(ip_in) + + # If it's a valid address, append the appropriate CIDR notation + if isinstance(ip_obj, ipaddress.IPv4Address): + return f"{ip_in}/32" + if isinstance( + ip_obj, ipaddress.IPv6Address + ): # TODO: check if just else is sufficient # type: ignore # noqa: PGH003 + return f"{ip_in}/128" + return None + + +def convert_timestamp(timestamp: str) -> str: + """ + In CP, time objects' time stamps are interpreted per-gateway for their local time zone. This means, the timestamps + we get from api, even though with explicit utc time zone, will not necessarily match the actual point-in-time used + after installation on gw. We assume the gw time zone is the same as the importer time zone and convert all timestamps + to utc based on that assumption. + """ + try: + local_time = datetime.fromisoformat(timestamp) # interpret timestamp in local timezone + utc_time = local_time.astimezone(timezone.utc) + return utc_time.isoformat() + except ValueError: + FWOLogger.warning(f"Failed to parse timestamp '{timestamp}', leaving it unchanged") + return timestamp + + +def normalize_time_objects(full_config: dict[str, Any], config2import: dict[str, Any]): + time_objects: list[dict[str, Any]] = [] + + for obj_dict in full_config["objects"]: + if obj_dict["type"] not in cp_const.time_obj_table_names: + continue + for chunk in obj_dict["chunks"]: + time_objects.extend( + TimeObject( + time_obj_uid=obj["uid"], + time_obj_name=obj["name"], + start_time=None if obj["start-now"] else convert_timestamp(obj["start"]["iso-8601"]), + end_time=None if obj["end-never"] else convert_timestamp(obj["end"]["iso-8601"]), + ).model_dump() # TODO: rework dicts to models everywhere + for obj in chunk.get("objects", []) + ) + + # add default 'Any' time object + time_objects.append( + TimeObject( + time_obj_uid="Any", + time_obj_name="Any", + start_time=None, + end_time=None, + ).model_dump() + ) + + config2import.update({"time_objects": time_objects}) diff --git a/roles/importer/files/importer/fw_modules/checkpointR8x/cp_rule.py b/roles/importer/files/importer/fw_modules/checkpointR8x/cp_rule.py new file mode 100644 index 0000000000..755d801cea --- /dev/null +++ b/roles/importer/files/importer/fw_modules/checkpointR8x/cp_rule.py @@ -0,0 +1,513 @@ +import ast +import json +from typing import Any + +from fwo_base import sanitize, sort_and_join_refs +from fwo_const import DEFAULT_SECTION_HEADER_TEXT, LIST_DELIMITER +from fwo_exceptions import FwoImporterErrorInconsistenciesError +from fwo_log import FWOLogger +from models.import_state import ImportState +from models.rule import RuleNormalized +from models.rule_enforced_on_gateway import RuleEnforcedOnGatewayNormalized +from models.rulebase import Rulebase + +uid_to_name_map: dict[str, str] = {} + +""" + new import format which takes the following cases into account without duplicating any rules in the DB: + - single rulebase used on more than one gw + - global policies enforced on more than one gws + - inline layers (CP) + - migrate section headers from rule to ordering element + ... +""" + + +def normalize_rulebases( + native_config: dict[str, Any], + native_config_global: dict[str, Any] | None, + import_state: ImportState, + normalized_config_dict: dict[str, Any], + normalized_config_global: dict[str, Any] | None, + is_global_loop_iteration: bool, +): + normalized_config_dict["policies"] = [] + + # fill uid_to_name_map: + for nw_obj in normalized_config_dict["network_objects"]: + uid_to_name_map[nw_obj["obj_uid"]] = nw_obj["obj_name"] + + fetched_rulebase_uids: list[str] = [] + if normalized_config_global is not None and normalized_config_global != {}: + fetched_rulebase_uids.extend( + [normalized_rulebase_global.uid for normalized_rulebase_global in normalized_config_global["policies"]] + ) + for gateway in native_config["gateways"]: + normalize_rulebases_for_each_link_destination( + gateway, + fetched_rulebase_uids, + native_config, + native_config_global, + is_global_loop_iteration, + import_state, + normalized_config_dict, + normalized_config_global, # type: ignore # TODO: check if normalized_config_global can be None, I am pretty sure it cannot be None here # noqa: PGH003 + ) # TODO: parse nat rulebase here + + +def normalize_rulebases_for_each_link_destination( + gateway: dict[str, Any], + fetched_rulebase_uids: list[str], + native_config: dict[str, Any], + native_config_global: dict[str, Any] | None, + is_global_loop_iteration: bool, + import_state: ImportState, + normalized_config_dict: dict[str, Any], + normalized_config_global: dict[str, Any], +): + for rulebase_link in gateway["rulebase_links"]: + if rulebase_link["to_rulebase_uid"] not in fetched_rulebase_uids and rulebase_link["to_rulebase_uid"] != "": + rulebase_to_parse, is_section, is_placeholder = find_rulebase_to_parse( + native_config["rulebases"], rulebase_link["to_rulebase_uid"] + ) + # search in global rulebase + found_rulebase_in_global = False + if rulebase_to_parse == {} and not is_global_loop_iteration and native_config_global is not None: + rulebase_to_parse, is_section, is_placeholder = find_rulebase_to_parse( + native_config_global["rulebases"], rulebase_link["to_rulebase_uid"] + ) + found_rulebase_in_global = True + if rulebase_to_parse == {}: + FWOLogger.warning("found to_rulebase link without rulebase in nativeConfig: " + str(rulebase_link)) + continue + normalized_rulebase = initialize_normalized_rulebase(rulebase_to_parse, import_state.mgm_details.uid) + parse_rulebase( + rulebase_to_parse, is_section, is_placeholder, normalized_rulebase, gateway, native_config["policies"] + ) + fetched_rulebase_uids.append(rulebase_link["to_rulebase_uid"]) + + if found_rulebase_in_global: + normalized_config_global["policies"].append(normalized_rulebase) + else: + normalized_config_dict["policies"].append(normalized_rulebase) + + +def find_rulebase_to_parse(rulebase_list: list[dict[str, Any]], rulebase_uid: str) -> tuple[dict[str, Any], bool, bool]: + """ + Decide if input rulebase is true rulebase, section or placeholder + """ + for rulebase in rulebase_list: + if rulebase["uid"] == rulebase_uid: + return rulebase, False, False + rulebase_to_parse, is_section, is_placeholder = find_rulebase_to_parse_in_case_of_chunk(rulebase, rulebase_uid) + if rulebase_to_parse != {}: + return rulebase_to_parse, is_section, is_placeholder + + # handle case: no rulebase found + return {}, False, False + + +def find_rulebase_to_parse_in_case_of_chunk( + rulebase: dict[str, Any], rulebase_uid: str +) -> tuple[dict[str, Any], bool, bool]: + is_section = False + rulebase_to_parse = {} + for chunk in rulebase["chunks"]: + for section in chunk["rulebase"]: + if section["uid"] == rulebase_uid: + if section["type"] == "place-holder": + return section, False, True + rulebase_to_parse, is_section = find_rulebase_to_parse_in_case_of_section( + is_section, rulebase_to_parse, section + ) + return rulebase_to_parse, is_section, False + + +def find_rulebase_to_parse_in_case_of_section( + is_section: bool, rulebase_to_parse: dict[str, Any], section: dict[str, Any] +) -> tuple[dict[str, Any], bool]: + if is_section: + rulebase_to_parse = concatenat_sections_across_chunks(rulebase_to_parse, section) + else: + is_section = True + rulebase_to_parse = section + return rulebase_to_parse, is_section + + +def concatenat_sections_across_chunks(rulebase_to_parse: dict[str, Any], section: dict[str, Any]) -> dict[str, Any]: + if "to" in rulebase_to_parse and "from" in section: + if rulebase_to_parse["to"] + 1 == section["from"]: + if rulebase_to_parse["name"] == section["name"]: + for rule in section["rulebase"]: + rulebase_to_parse["rulebase"].append(rule) + rulebase_to_parse["to"] = section["to"] + else: + raise FwoImporterErrorInconsistenciesError("Inconsistent naming in Checkpoint Chunks.") + else: + raise FwoImporterErrorInconsistenciesError("Inconsistent numbering in Checkpoint Chunks.") + else: + raise FwoImporterErrorInconsistenciesError("Broken format in Checkpoint Chunks.") + return rulebase_to_parse + + +def initialize_normalized_rulebase(rulebase_to_parse: dict[str, Any], mgm_uid: str) -> Rulebase: + rulebase_name = rulebase_to_parse.get("name", DEFAULT_SECTION_HEADER_TEXT) + rulebase_uid = rulebase_to_parse["uid"] + return Rulebase(uid=rulebase_uid, name=rulebase_name, mgm_uid=mgm_uid, rules={}) + + +def parse_rulebase( + rulebase_to_parse: dict[str, Any], + is_section: bool, + is_placeholder: bool, + normalized_rulebase: Rulebase, + gateway: dict[str, Any], + policy_structure: list[dict[str, Any]], +): + if is_section: + for rule in rulebase_to_parse["rulebase"]: + # delte_v sind import_id, parent_uid, config2import wirklich egal? Dann können wir diese argumente löschen - NAT ACHTUNG + parse_single_rule(rule, normalized_rulebase, normalized_rulebase.uid, None, gateway, policy_structure) + + FWOLogger.debug("parsed rulebase " + normalized_rulebase.uid, 4) + elif is_placeholder: + parse_single_rule( + rulebase_to_parse, normalized_rulebase, normalized_rulebase.uid, None, gateway, policy_structure + ) + else: + parse_rulebase_chunk(rulebase_to_parse, normalized_rulebase, gateway, policy_structure) + + +def parse_rulebase_chunk( + rulebase_to_parse: dict[str, Any], + normalized_rulebase: Rulebase, + gateway: dict[str, Any], + policy_structure: list[dict[str, Any]], +): + for chunk in rulebase_to_parse["chunks"]: + for rule in chunk["rulebase"]: + if "rule-number" in rule: + parse_single_rule(rule, normalized_rulebase, normalized_rulebase.uid, None, gateway, policy_structure) + else: + FWOLogger.debug("found unparsable rulebase: " + str(rulebase_to_parse), 9) + + +def accept_malformed_parts(objects: dict[str, Any] | list[dict[str, Any]], part: str = "") -> dict[str, Any]: + FWOLogger.debug(f"about to accept malformed rule part ({part}): {objects!s}") + + # if we are dealing with a list with one element, resolve the list + if isinstance(objects, list) and len(objects) == 1: + objects = objects[0] + + if isinstance(objects, dict): + if part == "action": + return {"action": objects.get("name", None)} + if part == "install-on": + return {"install-on": objects.get("name", None)} + if part == "time": + return {"time": objects.get("uid", None)} + if part == "track": + return {"track": objects.get("type", {}).get("name", None)} + FWOLogger.warning(f"found no uid or name in rule part ({part}): {objects!s}") + return {} + FWOLogger.warning(f"objects is not a dictionary: {objects!s}") + return {} + + +def parse_rule_part( + objects: dict[str, Any] | list[dict[str, Any] | None] | None, part: str = "source" +) -> dict[str, Any]: + address_objects: dict[str, Any] = {} + + if objects is None: + FWOLogger.debug( + f"rule part {part} is None: {objects!s}, which is normal for track field in inline layer guards" + ) + return None # type: ignore # noqa: PGH003#TODO: check if this is ok or should raise an Exception + + if "chunks" in objects: # for chunks of actions?! + address_objects.update( + parse_rule_part(objects["chunks"], part=part) # type: ignore # noqa: PGH003 # TODO: This Has to be refactored + ) # need to parse chunk first + + if isinstance(objects, dict): + return _parse_single_address_object(address_objects, objects, part) + # assuming list of objects + for obj in objects: + if obj is None: + FWOLogger.warning(f"found list with a single None obj: {objects!s}") + continue + if "chunks" in obj: + address_objects.update( + parse_rule_part(obj["chunks"], part=part) + ) # need to parse chunk first # TODO: check if this is ok or should raise an Exception + elif "objects" in obj: + for o in obj["objects"]: + address_objects.update( + parse_rule_part(o, part=part) + ) # need to parse chunk first # TODO: check if this is ok or should raise an Exception + return address_objects + elif "type" in obj: # found checkpoint object + _parse_obj_with_type(obj, address_objects) + else: + return accept_malformed_parts(objects, part=part) # type: ignore # TODO: check if this is ok or should raise an Exception # noqa: PGH003 + + if "" in address_objects.values(): + FWOLogger.warning("found empty name in one rule part (" + part + "): " + str(address_objects)) + + return address_objects + + +def _parse_single_address_object(address_objects: dict[str, Any], objects: dict[str, Any], part: str): + if "uid" in objects and "name" in objects: + address_objects[objects["uid"]] = objects["name"] + return address_objects + return accept_malformed_parts(objects, part=part) + + +def _parse_obj_with_type(obj: dict[str, Any], address_objects: dict[str, Any]) -> None: + if obj["type"] == "LegacyUserAtLocation": + address_objects[obj["uid"]] = obj["name"] + + elif obj["type"] == "access-role": + _parse_obj_with_access_role(obj, address_objects) + elif obj["type"] == "time": + address_objects[obj["uid"]] = obj["uid"] + else: # standard object + address_objects[obj["uid"]] = obj["name"] + + +def _parse_obj_with_access_role(obj: dict[str, Any], address_objects: dict[str, Any]) -> None: + if "networks" not in obj: + address_objects[obj["uid"]] = obj["name"] # adding IA without IP info, TODO: get full networks details here! + return + if isinstance(obj["networks"], str): # just a single source + if obj["networks"] == "any": + address_objects[obj["uid"]] = obj["name"] + "@" + "Any" + else: + address_objects[obj["uid"]] = obj["name"] + "@" + obj["networks"] + else: # more than one source + for nw in obj["networks"]: + nw_resolved = resolve_nwobj_uid_to_name(nw) + if nw_resolved == "": + address_objects[obj["uid"]] = obj["name"] + else: + address_objects[obj["uid"]] = obj["name"] + "@" + nw_resolved + + +def parse_single_rule( + native_rule: dict[str, Any], + rulebase: Rulebase, + layer_name: str, + parent_uid: str | None, + gateway: dict[str, Any], + policy_structure: list[dict[str, Any]], +): + # reference to domain rule layer, filling up basic fields + if not ( + "type" in native_rule and native_rule["type"] != "place-holder" and "rule-number" in native_rule + ): # standard rule, no section header + return + # the following objects might come in chunks: + source_objects: dict[str, str] = parse_rule_part(native_rule["source"], "source") + rule_src_ref, rule_src_name = sort_and_join_refs(list(source_objects.items())) + + dst_objects: dict[str, str] = parse_rule_part(native_rule["destination"], "destination") + rule_dst_ref, rule_dst_name = sort_and_join_refs(list(dst_objects.items())) + svc_objects: dict[str, str] = parse_rule_part(native_rule["service"], "service") + rule_svc_ref, rule_svc_name = sort_and_join_refs(list(svc_objects.items())) + rule_enforced_on_gateways = parse_rule_enforced_on_gateway(gateway, policy_structure, native_rule=native_rule) + list_of_gw_uids = sorted({enforceEntry.dev_uid for enforceEntry in rule_enforced_on_gateways}) + str_list_of_gw_uids = LIST_DELIMITER.join(list_of_gw_uids) if list_of_gw_uids else None + + rule_track = _parse_track(native_rule=native_rule) + + action_objects = parse_rule_part(native_rule["action"], "action") + if action_objects is not None: # type: ignore # TODO: this should be never None # noqa: PGH003 + rule_action = LIST_DELIMITER.join(action_objects.values()) # expecting only a single action + else: + rule_action = None + FWOLogger.warning("found rule without action: " + str(native_rule)) + + time_objects = parse_rule_part(native_rule["time"], "time") + rule_time = LIST_DELIMITER.join(time_objects.values()) if time_objects else None + + # starting with the non-chunk objects + rule_name = native_rule.get("name") + + # new in v8.0.3: + rule_custom_fields = native_rule.get("custom-fields") + + # we leave out all last_admin info for now + last_change_admin = None + + parent_rule_uid = _parse_parent_rule_uid(parent_uid, native_rule=native_rule) + + # new in v5.5.1: + rule_type = native_rule.get("rule_type", "access") + + comments = native_rule.get("comments") + if comments == "": + comments = None + + if "hits" in native_rule and "last-date" in native_rule["hits"] and "iso-8601" in native_rule["hits"]["last-date"]: + last_hit = native_rule["hits"]["last-date"]["iso-8601"] + else: + last_hit = None + + rule: dict[str, Any] = { + "rule_num": 0, + "rule_num_numeric": 0, + "rulebase_name": sanitize(layer_name), + "rule_disabled": not bool(native_rule["enabled"]), + "rule_src_neg": bool(native_rule["source-negate"]), + "rule_src": sanitize(rule_src_name), + "rule_src_refs": sanitize(rule_src_ref), + "rule_dst_neg": bool(native_rule["destination-negate"]), + "rule_dst": sanitize(rule_dst_name), + "rule_dst_refs": sanitize(rule_dst_ref), + "rule_svc_neg": bool(native_rule["service-negate"]), + "rule_svc": sanitize(rule_svc_name), + "rule_svc_refs": sanitize(rule_svc_ref), + "rule_action": sanitize(rule_action, lower=True), + "rule_track": sanitize(rule_track, lower=True), + "rule_installon": sanitize(str_list_of_gw_uids), + "rule_time": sanitize(rule_time), + "rule_name": sanitize(rule_name), + "rule_uid": sanitize(native_rule["uid"]), + "rule_custom_fields": sanitize(rule_custom_fields), + "rule_implied": False, + "rule_type": sanitize(rule_type), + "last_change_admin": sanitize(last_change_admin), + "parent_rule_uid": sanitize(parent_rule_uid), + "last_hit": sanitize(last_hit), + } + if comments is not None: + rule["rule_comment"] = sanitize(comments) + rulebase.rules.update({rule["rule_uid"]: RuleNormalized(**rule)}) + + +def _parse_parent_rule_uid(parent_uid: str | None, native_rule: dict[str, Any]) -> str | None: + # new in v5.1.17: + if "parent_rule_uid" in native_rule: + FWOLogger.debug( + "found rule (uid=" + native_rule["uid"] + ") with parent_rule_uid set: " + native_rule["parent_rule_uid"] + ) + parent_rule_uid = native_rule["parent_rule_uid"] + else: + parent_rule_uid = parent_uid + + if parent_rule_uid == "": + parent_rule_uid = None + + return parent_rule_uid + + +def _parse_track(native_rule: dict[str, Any]) -> str: + if isinstance(native_rule["track"], str): + rule_track = native_rule["track"] + else: + track_objects = parse_rule_part(native_rule["track"], "track") + rule_track = "none" if track_objects is None else LIST_DELIMITER.join(track_objects.values()) # type: ignore[union-attr] # TODO: should never be None + return rule_track + + +def parse_rule_enforced_on_gateway( + gateway: dict[str, Any], policy_structure: list[dict[str, Any]], native_rule: dict[str, Any] +) -> list[RuleEnforcedOnGatewayNormalized]: + """ + Parse rule enforcement information from native rule. + + Args: + native_rule: The native rule dictionary containing install-on information + + Returns: + list of RuleEnforcedOnGatewayNormalized objects + + Raises: + ValueError: If nativeRule is None or empty + + """ + if not native_rule: + raise ValueError("Native rule cannot be empty") + + enforce_entries: list[RuleEnforcedOnGatewayNormalized] = [] + all_target_gw_names_dict = parse_rule_part(native_rule["install-on"], "install-on") + + for target_uid in all_target_gw_names_dict: + target_name = all_target_gw_names_dict[target_uid] + if target_name == "Policy Targets": # or target == 'Any' + device_uid_list = find_devices_for_current_policy(gateway, policy_structure) + for device_uid in device_uid_list: + enforce_entry = RuleEnforcedOnGatewayNormalized(rule_uid=native_rule["uid"], dev_uid=device_uid) + enforce_entries.append(enforce_entry) + else: + enforce_entry = RuleEnforcedOnGatewayNormalized(rule_uid=native_rule["uid"], dev_uid=target_uid) + enforce_entries.append(enforce_entry) + return enforce_entries + + +def find_devices_for_current_policy(gateway: dict[str, Any], policy_structure: list[dict[str, Any]]) -> list[str]: + device_uid_list: list[str] = [] + for policy in policy_structure: + for target in policy["targets"]: + if target["uid"] == gateway["uid"]: + device_uid_list.extend([device["uid"] for device in policy["targets"]]) + return device_uid_list + + +def resolve_nwobj_uid_to_name(nw_obj_uid: str) -> str: + if nw_obj_uid in uid_to_name_map: + return uid_to_name_map[nw_obj_uid] + FWOLogger.warning("could not resolve network object with uid " + nw_obj_uid) + return "" + + +# delete_v: left here only for nat case +def check_and_add_section_header( + src_rulebase: dict[str, Any], + target_rulebase: Rulebase, + layer_name: str, + import_id: str, + section_header_uids: set[str], +): + # TODO: re-implement + raise NotImplementedError("check_and_add_section_header is not implemented yet.") + + +def insert_section_header_rule( + _target_rulebase: Rulebase, + _section_name: str, + _layer_name: str, + _import_id: str, + _src_rulebase_uid: str, + _section_header_uids: set[str], + _parent_uid: str, +): + # TODO: re-implement + return + + +def ensure_json(raw: str) -> Any: + """ + Tries to parse the given string as valid JSON. + Falls back to ast.literal_eval() if the JSON is using single quotes + or is otherwise not strictly compliant. + + Args: + raw: The input string containing JSON-like data. + + Returns: + The parsed Python object (e.g., dict, list, str, int, etc.). + + Raises: + ValueError: If neither JSON parsing nor literal_eval() succeed. + + """ + try: + return json.loads(raw) + except json.JSONDecodeError: + try: + return ast.literal_eval(raw) + except (ValueError, SyntaxError) as e: + raise ValueError(f"Invalid JSON or literal: {e}") from e diff --git a/roles/importer/files/importer/fw_modules/checkpointR8x/cp_service.py b/roles/importer/files/importer/fw_modules/checkpointR8x/cp_service.py new file mode 100644 index 0000000000..ed676c8288 --- /dev/null +++ b/roles/importer/files/importer/fw_modules/checkpointR8x/cp_service.py @@ -0,0 +1,217 @@ +import re +from typing import Any + +from fw_modules.checkpointR8x import cp_const +from fwo_const import LIST_DELIMITER +from fwo_exceptions import FwoImporterErrorInconsistenciesError + + +# collect_svcobjects writes svc info into global users dict +def collect_svc_objects(object_table: dict[str, Any], svc_objects: list[dict[str, Any]]): + if object_table["type"] in cp_const.svc_obj_table_names: + typ = "undef" + if object_table["type"] in cp_const.group_svc_obj_types: + typ = "group" + if object_table["type"] in cp_const.simple_svc_obj_types: + typ = "simple" + for chunk in object_table["chunks"]: + if "objects" in chunk: + for obj in chunk["objects"]: + collect_single_svc_object(obj) + svc_objects.append( + { + "svc_uid": obj["uid"], + "svc_name": obj["name"], + "svc_color": obj["color"], + "svc_comment": obj["comments"], + "svc_domain": obj["domain_uid"], + "svc_typ": typ, + "svc_port": obj["port"], + "svc_port_end": obj["port_end"], + "svc_member_refs": obj["svc_member_refs"], + "svc_member_names": None, + "ip_proto": obj["proto"], + "svc_timeout": obj["session_timeout"], + "rpc_nr": obj["rpc_nr"], + } + ) + + +def _set_default_values(obj: dict[str, Any]): + """ + Set default values for color, comments, and domain_uid. + """ + if "color" not in obj or obj["color"] == "" or obj["color"] == "none": + obj["color"] = "black" + + if "comments" not in obj or obj["comments"] == "": + obj["comments"] = None + + obj["domain_uid"] = get_obj_domain_uid(obj) + + +def _get_rpc_number(obj: dict[str, Any]) -> str | None: + """ + Extract RPC number from interface-uuid or program-number. + Returns RPC number or None. + """ + if "interface-uuid" in obj: + return str(obj["interface-uuid"]) + if "program-number" in obj: + return str(obj["program-number"]) + return None + + +def _get_session_timeout(obj: dict[str, Any]) -> str | None: + """ + Extract and stringify session timeout. + Returns session timeout as string or None. + """ + if "session-timeout" in obj: + return str(obj["session-timeout"]) + return None + + +def _get_member_references(obj: dict[str, Any]) -> str | None: + """ + Process members list and return concatenated member references. + Returns member reference string or None. + """ + if "members" not in obj: + return None + + member_refs = "" + for member in obj["members"]: + if isinstance(member, str): + member_refs += member + LIST_DELIMITER + elif isinstance(member, dict) and "uid" in member and isinstance(member["uid"], str): + member_refs += member["uid"] + LIST_DELIMITER + return member_refs[:-1] if member_refs else None + + +def _get_protocol_number(obj: dict[str, Any]) -> int | None: + """ + Extract and validate protocol number from object. + Returns validated protocol number or None. + """ + proto_map = {"service-tcp": 6, "service-udp": 17, "service-icmp": 1} + + proto = None + if "type" in obj and obj["type"] in proto_map: + proto = proto_map[obj["type"]] + elif "ip-protocol" in obj: + proto_value = obj["ip-protocol"] + if isinstance(proto_value, str): + try: + proto = int(proto_value) + except ValueError: + proto = None + else: + proto = proto_value + + if not isinstance(proto, int): + return None + return proto if proto >= 0 else None + + +def collect_single_svc_object(obj: dict[str, Any]) -> None: + """ + Collects a single service object and appends its details to the svc_objects list. + Handles different types of service objects and normalizes port information. + """ + obj["proto"] = _get_protocol_number(obj) + + obj["svc_member_refs"] = _get_member_references(obj) + # svc_member_names are added later in add_member_names_for_svc_group() + + obj["session_timeout"] = _get_session_timeout(obj) + obj["rpc_nr"] = _get_rpc_number(obj) + + obj["port"], obj["port_end"] = normalize_port(obj) + _set_default_values(obj) + + +def normalize_port(obj: dict[str, Any]) -> tuple[str | None, str | None]: + """ + Normalizes the port information in the given object. + If the 'port' key exists, it processes the port value to handle ranges and special cases. + """ + port = None + port_end = None + if "port" in obj: + port = str(obj["port"]) + pattern = re.compile(r"^\>(\d+)$") + match = pattern.match(port) + if match: + return str(int(match.group()[1:]) + 1), str(65535) + pattern = re.compile(r"^\<(\d+)$") + match = pattern.match(port) + if match: + return str(1), str(int(match.group()[1:]) - 1) + pattern = re.compile(r"^(\d+)\-(\d+)$") + match = pattern.match(port) + if match: + match_result_list = match.group().split("-") + return match_result_list[0], match_result_list[1] + + # standard port without "<>-" + pattern = re.compile(r"^(\d+)$") + match = pattern.match(port) + if match: + # port stays unchanged + port_end = port + else: # Any + pattern = re.compile(r"^(Any)$") + match = pattern.match(port) + if match: + port = str(1) + port_end = str(65535) + else: # e.g. suspicious cases + port = None + port_end = None + return port, port_end + + +def get_obj_domain_uid(obj: dict[str, Any]) -> str: + """ + Returns the domain UID for the given object. + If the object has a 'domain' key with a 'uid', it returns that UID. + Otherwise, it returns the global domain UID. + """ + if "domain" in obj and "uid" in obj["domain"]: + return obj["domain"]["uid"] + return "DUMMY" # TODO: set domain uid correctly (updatable objects?) + + +# return name of nw_objects element where obj_uid = uid +def resolve_svc_uid_to_name(uid: str, svc_objects: list[dict[str, Any]]) -> str: + for obj in svc_objects: + if obj["svc_uid"] == uid: + return obj["svc_name"] + raise FwoImporterErrorInconsistenciesError("Service object member uid " + uid + " not found") + + +def add_member_names_for_svc_group(idx: int, svc_objects: list[dict[str, Any]]) -> None: + member_names = "" + group = svc_objects.pop(idx) + + if "svc_member_refs" in group and group["svc_member_refs"] is not None: + svc_member_refs = group["svc_member_refs"].split(LIST_DELIMITER) + for ref in svc_member_refs: + member_name = resolve_svc_uid_to_name(ref, svc_objects) + member_names += member_name + LIST_DELIMITER + group["svc_member_names"] = member_names[:-1] + + svc_objects.insert(idx, group) + + +def normalize_service_objects(full_config: dict[str, Any], config2import: dict[str, Any], import_id: int) -> None: + svc_objects: list[dict[str, Any]] = [] + for obj_dict in full_config["objects"]: + collect_svc_objects(obj_dict, svc_objects) + for obj in svc_objects: + obj.update({"control_id": import_id}) + for idx in range(len(svc_objects) - 1): + if svc_objects[idx]["svc_typ"] == "group": + add_member_names_for_svc_group(idx, svc_objects) + config2import.update({"service_objects": svc_objects}) diff --git a/roles/importer/files/importer/fw_modules/checkpointR8x/cp_user.py b/roles/importer/files/importer/fw_modules/checkpointR8x/cp_user.py new file mode 100644 index 0000000000..d0fb437585 --- /dev/null +++ b/roles/importer/files/importer/fw_modules/checkpointR8x/cp_user.py @@ -0,0 +1,119 @@ +import json +from typing import Any + +from fwo_log import FWOLogger + + +def extract_access_role_user(src: dict[str, Any]) -> tuple[str, str, str, str | None, str | None]: + """Extract user data from access-role type source object.""" + user_name = src["name"] + user_uid = src["uid"] + user_typ = "group" + user_comment = src.get("comments") + user_color = src.get("color") + if "users" in src: + user_typ = "simple" + return user_name, user_uid, user_typ, user_comment, user_color + + +def extract_legacy_user_at_location(src: dict[str, Any]) -> tuple[str, str | None, str, str | None, str | None]: + """Extract user data from LegacyUserAtLocation type source object.""" + user_str = src["name"] + user_ar = user_str.split("@") + user_name = user_ar[0] + user_uid = src.get("userGroup") + user_typ = "group" + user_comment = src.get("comments") + user_color = src.get("color") + return user_name, user_uid, user_typ, user_comment, user_color + + +def normalize_user_data(user_comment: str | None, user_color: str | None) -> tuple[str | None, str]: + """Normalize user comment and color values.""" + if user_comment == "": + user_comment = None + if user_color is None: + user_color = "black" + return user_comment, user_color + + +def process_typed_source_object(src: dict[str, Any], users: dict[str, Any]) -> None: + """Process a source object that has a type field.""" + if src["type"] == "access-role": + user_name, user_uid, user_typ, user_comment, user_color = extract_access_role_user(src) + elif src["type"] == "LegacyUserAtLocation": + user_name, user_uid, user_typ, user_comment, user_color = extract_legacy_user_at_location(src) + else: + return + + user_comment, user_color = normalize_user_data(user_comment, user_color) + + users.update( + { + user_name: { + "user_uid": user_uid, + "user_typ": user_typ, + "user_comment": user_comment, + "user_color": user_color, + } + } + ) + + +def process_untyped_source_object(src: dict[str, Any], users: dict[str, Any]) -> None: + """Process a source object that lacks a type field.""" + FWOLogger.warning("found src user without type field: " + json.dumps(src)) + if "name" in src and "uid" in src: + users.update({src["name"]: {"user_uid": src["uid"], "user_typ": "simple"}}) + + +def process_standard_rule(rule: dict[str, Any], users: dict[str, Any]) -> None: + """Process a standard rule to extract user information.""" + if "type" not in rule or rule["type"] == "place-holder": + return + + for src in rule["source"]: + if "type" in src: + process_typed_source_object(src, users) + else: + process_untyped_source_object(src, users) + + +def collect_users_from_rule(rule: dict[str, Any], users: dict[str, Any]) -> None: + """Collect user information from a single rule.""" + if "rule-number" in rule: # standard rule + process_standard_rule(rule, users) + else: # section + collect_users_from_rulebase(rule["rulebase"], users) + + +# collect_users writes user info into global users dict +def collect_users_from_rulebase(rulebase: dict[str, Any], users: dict[str, Any]) -> None: + if "rulebase_chunks" in rulebase: + for chunk in rulebase["rulebase_chunks"]: + if "rulebase" in chunk: + for rule in chunk["rulebase"]: + collect_users_from_rule(rule, users) + else: + for rule in rulebase: + collect_users_from_rule(rule, users) # type: ignore #TODO: refactor this # noqa: PGH003 + + +# the following is only used within new python-only importer: +def parse_user_objects_from_rulebase(rulebase: dict[str, Any], users: dict[str, Any], import_id: str) -> None: + collect_users_from_rulebase(rulebase, users) + for user_name, user_info in users.items(): + # TODO: get user info via API + _ = get_user_uid_from_cp_api(user_name) + # finally add the import id + user_info["control_id"] = import_id + + +def get_user_uid_from_cp_api(user_name: str) -> str: + # show-object with UID + # dummy implementation returning the name as uid + return user_name + + +def normalize_users_legacy() -> None: + raise NotImplementedError diff --git a/roles/importer/files/importer/azure2022ff/discovery_logging.conf b/roles/importer/files/importer/fw_modules/checkpointR8x/discovery_logging.conf similarity index 100% rename from roles/importer/files/importer/azure2022ff/discovery_logging.conf rename to roles/importer/files/importer/fw_modules/checkpointR8x/discovery_logging.conf diff --git a/roles/importer/files/importer/fw_modules/checkpointR8x/fwcommon.py b/roles/importer/files/importer/fw_modules/checkpointR8x/fwcommon.py new file mode 100644 index 0000000000..2d8f2fa3c1 --- /dev/null +++ b/roles/importer/files/importer/fw_modules/checkpointR8x/fwcommon.py @@ -0,0 +1,766 @@ +import time +from copy import deepcopy +from typing import Any + +import fwo_const +import fwo_globals +from fw_modules.checkpointR8x import cp_const, cp_gateway, cp_getter, cp_network, cp_rule, cp_service +from fwo_base import ConfigAction +from fwo_exceptions import FwLoginFailedError, FwoImporterError, ImportInterruptionError +from fwo_log import FWOLogger +from model_controllers.fwconfigmanagerlist_controller import FwConfigManagerListController +from model_controllers.import_state_controller import ImportStateController +from model_controllers.management_controller import ManagementController +from models.fw_common import FwCommon +from models.fwconfig_normalized import FwConfigNormalized +from models.fwconfigmanagerlist import FwConfigManager +from models.import_state import ImportState +from utils.conversion_utils import convert_list_to_dict + + +class CheckpointR8xCommon(FwCommon): + def has_config_changed( + self, full_config: FwConfigManagerListController, import_state: ImportStateController, force: bool = False + ) -> bool: + if full_config: # a config was passed in (read from file), so we assume that an import has to be done (simulating changes here) + return True + + session_id: str = cp_getter.login(import_state.mgm_details) + + if import_state.last_successful_import is None or import_state.last_successful_import == "" or force: + # if no last import time found or given or if force flag is set, do full import + result = True + else: # otherwise search for any changes since last import + result = ( + cp_getter.get_changes( + session_id, + import_state.mgm_details.hostname, + str(import_state.mgm_details.port), + import_state.last_successful_import, + ) + != 0 + ) + + cp_getter.logout(import_state.mgm_details.buildFwApiString(), session_id) + + return result > 0 + + def get_config( + self, config_in: FwConfigManagerListController, import_state: ImportStateController + ) -> tuple[int, FwConfigManagerListController]: + return get_config(config_in, import_state) + + +def get_config( + config_in: FwConfigManagerListController, import_state: ImportStateController +) -> tuple[int, FwConfigManagerListController]: + FWOLogger.debug("starting checkpointR8x/get_config") + + parsing_config_only = ( + not config_in.has_empty_config() + ) # no native config was passed in, so getting it from FW-Manager + + if not parsing_config_only: # get config from cp fw mgr + starttime = int(time.time()) + initialize_native_config(config_in, import_state.state) + + start_time_temp = int(time.time()) + FWOLogger.debug("checkpointR8x/get_config/getting objects ...") + + if config_in.native_config is None: + raise FwoImporterError("native_config is None in get_config") + + # IMPORTANT: cp api is expected to preserve order of refs in group objects (unlike refs in rules, which are sorted later) + result_get_objects = get_objects(config_in.native_config, import_state.state) + if result_get_objects > 0: + raise FwLoginFailedError("checkpointR8x/get_config/error while gettings objects") + FWOLogger.debug("checkpointR8x/get_config/fetched objects in " + str(int(time.time()) - start_time_temp) + "s") + + start_time_temp = int(time.time()) + FWOLogger.debug("checkpointR8x/get_config/getting rules ...") + result_get_rules = get_rules(config_in.native_config, import_state.state) + if result_get_rules > 0: + raise FwLoginFailedError("checkpointR8x/get_config/error while gettings rules") + FWOLogger.debug("checkpointR8x/get_config/fetched rules in " + str(int(time.time()) - start_time_temp) + "s") + + duration = int(time.time()) - starttime + FWOLogger.debug("checkpointR8x/get_config - fetch duration: " + str(duration) + "s") + + if config_in.contains_only_native(): + sid: str = "" + if not parsing_config_only: + sid = cp_getter.login(import_state.state.mgm_details) + normalized_config = normalize_config(import_state.state, config_in, parsing_config_only, sid) + FWOLogger.info("completed getting config") + return 0, normalized_config + # we already have a native config (from file import) + return 0, config_in + + +def initialize_native_config(config_in: FwConfigManagerListController, import_state: ImportState) -> None: + """ + Create domain structure in nativeConfig + """ + manager_details_list = create_ordered_manager_list(import_state) + if config_in.native_config is None: + raise FwoImporterError("native_config is None in initialize_native_config") + config_in.native_config.update({"domains": []}) + for manager_details in manager_details_list: + config_in.native_config["domains"].append( + { + "domain_name": manager_details.domain_name, + "domain_uid": manager_details.domain_uid, + "is-super-manager": manager_details.is_super_manager, + "management_name": manager_details.name, + "management_uid": manager_details.uid, + "objects": [], + "rulebases": [], + "nat_rulebases": [], + "gateways": [], + } + ) + + +def normalize_config( + import_state: ImportState, config_in: FwConfigManagerListController, parsing_config_only: bool, sid: str +) -> FwConfigManagerListController: + native_and_normalized_config_dict_list: list[dict[str, Any]] = [] + + if config_in.native_config is None: + raise FwoImporterError("Did not get a native config to normalize.") + + ensure_native_domains(config_in.native_config, import_state) + + # in case of mds, first nativ config domain is global + is_global_loop_iteration = False + native_config_global: dict[str, Any] = {} + normalized_config_global = {} + if config_in.native_config["domains"][0]["is-super-manager"]: + native_config_global = config_in.native_config["domains"][0] + is_global_loop_iteration = True + + for native_conf in config_in.native_config["domains"]: + normalized_config_dict = deepcopy(fwo_const.EMPTY_NORMALIZED_FW_CONFIG_JSON_DICT) + normalize_single_manager_config( + native_conf, + native_config_global, + normalized_config_dict, + normalized_config_global, + import_state, + parsing_config_only, + sid, + is_global_loop_iteration, + ) + + native_and_normalized_config_dict_list.append({"native": native_conf, "normalized": normalized_config_dict}) + + if is_global_loop_iteration: + normalized_config_global = normalized_config_dict + is_global_loop_iteration = False + + for native_and_normalized_config_dict in native_and_normalized_config_dict_list: + normalized_config = FwConfigNormalized( + action=ConfigAction.INSERT, + network_objects=convert_list_to_dict( + native_and_normalized_config_dict["normalized"]["network_objects"], "obj_uid" + ), + service_objects=convert_list_to_dict( + native_and_normalized_config_dict["normalized"]["service_objects"], "svc_uid" + ), + zone_objects=convert_list_to_dict( + native_and_normalized_config_dict["normalized"]["zone_objects"], "zone_name" + ), + time_objects=convert_list_to_dict( + native_and_normalized_config_dict["normalized"]["time_objects"], "time_obj_uid" + ), + rulebases=native_and_normalized_config_dict["normalized"]["policies"], + gateways=native_and_normalized_config_dict["normalized"]["gateways"], + ) + manager = FwConfigManager( + manager_name=native_and_normalized_config_dict["native"]["management_name"], + manager_uid=native_and_normalized_config_dict["native"]["management_uid"], + is_super_manager=native_and_normalized_config_dict["native"]["is-super-manager"], + sub_manager_ids=[], + domain_name=native_and_normalized_config_dict["native"]["domain_name"], + domain_uid=native_and_normalized_config_dict["native"]["domain_uid"], + configs=[normalized_config], + ) + config_in.ManagerSet.append(manager) + + return config_in + + +def ensure_native_domains(native_config: dict[str, Any], import_state: ImportState) -> None: + if "domains" in native_config: + return + + native_config["domains"] = [ + { + "domain_name": import_state.mgm_details.domain_name, + "domain_uid": import_state.mgm_details.domain_uid, + "is-super-manager": import_state.mgm_details.is_super_manager, + "management_name": import_state.mgm_details.name, + "management_uid": import_state.mgm_details.uid, + "objects": native_config.get("objects", []), + "rulebases": native_config.get("rulebases", []), + "nat_rulebases": native_config.get("nat_rulebases", []), + "gateways": native_config.get("gateways", []), + "policies": native_config.get("policies", []), + } + ] + + +def normalize_single_manager_config( + native_config: dict[str, Any], + native_config_global: dict[str, Any], + normalized_config_dict: dict[str, Any], + normalized_config_global: dict[str, Any], + import_state: ImportState, + parsing_config_only: bool, + sid: str, + is_global_loop_iteration: bool, +): + cp_network.normalize_network_objects( + native_config, normalized_config_dict, import_state.import_id, mgm_id=import_state.mgm_details.mgm_id + ) + FWOLogger.info("completed normalizing network objects") + cp_service.normalize_service_objects(native_config, normalized_config_dict, import_state.import_id) + FWOLogger.info("completed normalizing service objects") + cp_network.normalize_time_objects(native_config, normalized_config_dict) + FWOLogger.info("completed normalizing time objects") + cp_gateway.normalize_gateways(native_config, import_state, normalized_config_dict) + cp_rule.normalize_rulebases( + native_config, + native_config_global, + import_state, + normalized_config_dict, + normalized_config_global, + is_global_loop_iteration, + ) + if not parsing_config_only: # get config from cp fw mgr + cp_getter.logout(import_state.mgm_details.build_fw_api_string(), sid) + FWOLogger.info("completed normalizing rulebases") + + +def get_rules(native_config: dict[str, Any], import_state: ImportState) -> int: + """ + Main function to get rules. Divided into smaller sub-tasks for better readability and maintainability. + """ + show_params_policy_structure: dict[str, Any] = { + "limit": import_state.fwo_config.api_fetch_size, + "details-level": "full", + } + + global_assignments, global_policy_structure, global_domain, global_sid = None, None, None, None + manager_details_list = create_ordered_manager_list(import_state) + for manager_index, manager_details in enumerate(manager_details_list): + if manager_details.import_disabled and not import_state.force_import: + continue + cp_manager_api_base_url = import_state.mgm_details.build_fw_api_string() + + if manager_details.is_super_manager: + global_assignments, global_policy_structure, global_domain, global_sid = handle_super_manager( + manager_details, cp_manager_api_base_url, show_params_policy_structure + ) + + sid: str = cp_getter.login(manager_details) + policy_structure: list[dict[str, Any]] = [] + cp_getter.get_policy_structure( + cp_manager_api_base_url, + sid, + show_params_policy_structure, + manager_details, + policy_structure=policy_structure, + ) + + process_devices( + manager_details, + policy_structure, + global_assignments, + global_policy_structure, + global_domain, + global_sid, + cp_manager_api_base_url, + sid, + native_config["domains"][ + manager_index + ], # globalSid should not be None but is when the first manager is not supermanager + native_config["domains"][0], + import_state, + ) + native_config["domains"][manager_index].update({"policies": policy_structure}) + + return 0 + + +def create_ordered_manager_list(import_state: ImportState) -> list[ManagementController]: + """ + Creates list of manager details, supermanager is first + """ + manager_details_list: list[ManagementController] = [deepcopy(import_state.mgm_details)] + if import_state.mgm_details.is_super_manager: + manager_details_list.extend([deepcopy(sub_manager) for sub_manager in import_state.mgm_details.sub_managers]) # type: ignore TODO: why we are adding submanagers as ManagementController? + return manager_details_list + + +def handle_super_manager( + manager_details: ManagementController, cp_manager_api_base_url: str, show_params_policy_structure: dict[str, Any] +) -> tuple[list[Any], None, Any | None, str]: + # global assignments are fetched from mds domain + mds_sid: str = cp_getter.login(manager_details) + global_policy_structure = None + global_domain = None + global_assignments = cp_getter.get_global_assignments( + cp_manager_api_base_url, mds_sid, show_params_policy_structure + ) + global_sid = "" + # import global policies if at least one global assignment exists + + if len(global_assignments) > 0: + if "global-domain" in global_assignments[0] and "uid" in global_assignments[0]["global-domain"]: + global_domain = global_assignments[0]["global-domain"]["uid"] + + # policy structure is fetched from global domain + manager_details.domain_uid = global_domain + global_sid: str = cp_getter.login(manager_details) + cp_getter.get_policy_structure( + cp_manager_api_base_url, + global_sid, + show_params_policy_structure, + manager_details, + policy_structure=global_policy_structure, + ) + else: + raise FwoImporterError(f"Unexpected global assignments: {global_assignments!s}") + + return global_assignments, global_policy_structure, global_domain, global_sid + + +def process_devices( + manager_details: ManagementController, + policy_structure: list[dict[str, Any]], + global_assignments: list[Any] | None, + global_policy_structure: list[dict[str, Any]] | None, + global_domain: str | None, + global_sid: str | None, + cp_manager_api_base_url: str, + sid: str, + native_config_domain: dict[str, Any], + native_config_global_domain: dict[str, Any], + import_state: ImportState, +) -> None: + for device in manager_details.devices: + if device["importDisabled"] and not import_state.force_import: + continue + device_config: dict[str, Any] = initialize_device_config(device) + if not device_config: + continue + + ordered_layer_uids: list[str] = get_ordered_layer_uids( + policy_structure, device_config, manager_details.get_domain_string() + ) + if not ordered_layer_uids: + FWOLogger.warning(f"No ordered layers found for device: {device_config['name']}") + native_config_domain["gateways"].append(device_config) + continue + + global_ordered_layer_count = 0 + if import_state.mgm_details.is_super_manager: + global_ordered_layer_count = handle_global_rulebase_links( + manager_details, + import_state, + device_config, + global_assignments, + global_policy_structure, + global_domain, + global_sid, + ordered_layer_uids, + native_config_global_domain, + cp_manager_api_base_url, + ) + else: + define_initial_rulebase(device_config, ordered_layer_uids, is_global=False) + + add_ordered_layers_to_native_config( + ordered_layer_uids, + get_rules_params(import_state), + cp_manager_api_base_url, + sid, + native_config_domain, + device_config, + is_global=False, + global_ordered_layer_count=global_ordered_layer_count, + ) + + handle_nat_rules(device, native_config_domain, sid, import_state) + + native_config_domain["gateways"].append(device_config) + + +def initialize_device_config(device: dict[str, Any]) -> dict[str, Any]: + if "name" in device and "uid" in device: + return {"name": device["name"], "uid": device["uid"], "rulebase_links": []} + raise FwoImporterError(f"Device missing name or uid: {device}") + + +def handle_global_rulebase_links( + manager_details: ManagementController, + import_state: ImportState, + device_config: dict[str, Any], + global_assignments: list[Any] | None, + global_policy_structure: list[dict[str, Any]] | None, + global_domain: str | None, + global_sid: str | None, + ordered_layer_uids: list[str], + native_config_global_domain: dict[str, Any], + cp_manager_api_base_url: str, +) -> int: + """ + Searches for global access policy for current device policy, + adds global ordered layers and defines global rulebase link + """ + if global_assignments is None: + raise FwoImporterError("Global assignments is None in handle_global_rulebase_links") + + if global_policy_structure is None: + raise FwoImporterError("Global policy structure is None in handle_global_rulebase_links") + + for global_assignment in global_assignments: + if global_assignment["dependent-domain"]["uid"] != manager_details.get_domain_string(): + continue + for global_policy in global_policy_structure: + if global_policy["name"] == global_assignment["global-access-policy"]: + global_ordered_layer_uids = get_ordered_layer_uids([global_policy], device_config, global_domain) + if not global_ordered_layer_uids: + FWOLogger.warning(f"No access layer for global policy: {global_policy['name']}") + break + + global_ordered_layer_count = len(global_ordered_layer_uids) + global_policy_rulebases_uid_list = add_ordered_layers_to_native_config( + global_ordered_layer_uids, + get_rules_params(import_state), + cp_manager_api_base_url, + global_sid, + native_config_global_domain, + device_config, + is_global=True, + global_ordered_layer_count=global_ordered_layer_count, + ) + define_global_rulebase_link( + device_config, + global_ordered_layer_uids, + ordered_layer_uids, + native_config_global_domain, + global_policy_rulebases_uid_list, + ) + + return global_ordered_layer_count + + return 0 + + +def define_global_rulebase_link( + device_config: dict[str, Any], + global_ordered_layer_uids: list[str], + ordered_layer_uids: list[str], + native_config_global_domain: dict[str, Any], + global_policy_rulebases_uid_list: list[str], +): + """ + Links initial and placeholder rule for global rulebases + """ + define_initial_rulebase(device_config, global_ordered_layer_uids, is_global=True) + + # parse global rulebases, find place-holders and link local rulebases + placeholder_link_index = 0 + for global_rulebase_uid in global_policy_rulebases_uid_list: + placeholder_rule_uid = "" + for rulebase in native_config_global_domain["rulebases"]: + if rulebase["uid"] == global_rulebase_uid: + placeholder_rule_uid, placeholder_rulebase_uid = cp_getter.get_placeholder_in_rulebase(rulebase) + + if placeholder_rule_uid: + ordered_layer_uid = "" + # we might find more than one placeholder, may be unequal to number of domain ordered layers + if len(ordered_layer_uids) > placeholder_link_index: + ordered_layer_uid = ordered_layer_uids[placeholder_link_index] + + device_config["rulebase_links"].append( + { + "from_rulebase_uid": placeholder_rulebase_uid, + "from_rule_uid": None, + "to_rulebase_uid": ordered_layer_uid, + "type": "domain", + "is_global": False, + "is_initial": False, + "is_section": False, + } + ) + + placeholder_link_index += 1 + + +def define_initial_rulebase(device_config: dict[str, Any], ordered_layer_uids: list[str], is_global: bool): + device_config["rulebase_links"].append( + { + "from_rulebase_uid": None, + "from_rule_uid": None, + "to_rulebase_uid": ordered_layer_uids[0], + "type": "ordered", + "is_global": is_global, + "is_initial": True, + "is_section": False, + } + ) + + +def get_rules_params(import_state: ImportState) -> dict[str, Any]: + return { + "limit": import_state.fwo_config.api_fetch_size, + "use-object-dictionary": cp_const.use_object_dictionary, + "details-level": "standard", + "show-hits": cp_const.with_hits, + } + + +def handle_nat_rules(device: dict[str, Any], native_config_domain: dict[str, Any], sid: str, import_state: ImportState): + if device.get("package_name"): + show_params_rules: dict[str, Any] = { + "limit": import_state.fwo_config.api_fetch_size, + "use-object-dictionary": cp_const.use_object_dictionary, + "details-level": "standard", + "package": device["package_name"], + } + FWOLogger.debug(f"Getting NAT rules for package: {device['package_name']}", 4) + nat_rules = cp_getter.get_nat_rules_from_api_as_dict( + import_state.mgm_details.build_fw_api_string(), + sid, + show_params_rules, + native_config_domain=native_config_domain, + ) + if nat_rules: + native_config_domain["nat_rulebases"].append(nat_rules) + else: + native_config_domain["nat_rulebases"].append({"nat_rule_chunks": []}) + else: + native_config_domain["nat_rulebases"].append({"nat_rule_chunks": []}) + + +def add_ordered_layers_to_native_config( + ordered_layer_uids: list[str], + show_params_rules: dict[str, Any], + cp_manager_api_base_url: str, + sid: str | None, + native_config_domain: dict[str, Any], + device_config: dict[str, Any], + is_global: bool, + global_ordered_layer_count: int, +) -> list[str]: + """ + Fetches ordered layers and links them + """ + policy_rulebases_uid_list = [] + for ordered_layer_index, ordered_layer_uid in enumerate(ordered_layer_uids): + show_params_rules.update({"uid": ordered_layer_uid}) + + policy_rulebases_uid_list = cp_getter.get_rulebases( + cp_manager_api_base_url, + sid, + show_params_rules, + native_config_domain, + device_config, + policy_rulebases_uid_list, + is_global=is_global, + access_type="access", + rulebase_uid=ordered_layer_uid, + ) + + # link to next ordered layer + # in case of mds: domain ordered layers are linked once there is no global ordered layer counterpart + if (is_global or ordered_layer_index >= global_ordered_layer_count - 1) and ( + ordered_layer_index < len(ordered_layer_uids) - 1 + ): + device_config["rulebase_links"].append( + { + "from_rulebase_uid": ordered_layer_uid, + "from_rule_uid": None, + "to_rulebase_uid": ordered_layer_uids[ordered_layer_index + 1], + "type": "ordered", + "is_global": is_global, + "is_initial": False, + "is_section": False, + } + ) + + return policy_rulebases_uid_list + + +def get_ordered_layer_uids( + policy_structure: list[dict[str, Any]], device_config: dict[str, Any], domain: str | None +) -> list[str]: + """ + Get UIDs of ordered layers for policy of device + """ + ordered_layer_uids: list[str] = [] + for policy in policy_structure: + found_target_in_policy = False + for target in policy["targets"]: + if target["uid"] == device_config["uid"] or target["uid"] == "all": + found_target_in_policy = True + if found_target_in_policy: + append_access_layer_uid(policy, domain, ordered_layer_uids) + + return ordered_layer_uids + + +def append_access_layer_uid(policy: dict[str, Any], domain: str | None, ordered_layer_uids: list[str]) -> None: + ordered_layer_uids.extend( + [ + access_layer["uid"] + for access_layer in policy["access-layers"] + if access_layer["domain"] == domain or domain == "" + ] + ) + + +def get_objects(native_config_dict: dict[str, Any], import_state: ImportState) -> int: + show_params_objs = {"limit": import_state.fwo_config.api_fetch_size} + manager_details_list = create_ordered_manager_list(import_state) + + # loop over sub-managers in case of mds + manager_index = 0 + for manager_details in manager_details_list: + if manager_details.import_disabled and not import_state.force_import: + continue + + is_stand_alone_manager = len(manager_details_list) == 1 + if manager_details.is_super_manager or is_stand_alone_manager: + obj_type_array = cp_const.api_obj_types + else: + obj_type_array = cp_const.local_api_obj_types + + if manager_details.is_super_manager: + # for super managers we need to get both the global domain data and the Check Point Data (perdefined objects) + + # Check Point Data (perdefined objects) + manager_details.domain_name = "" + manager_details.domain_uid = "" # Check Point Data + get_objects_per_domain( + manager_details, + native_config_dict["domains"][0], + obj_type_array, + show_params_objs, + is_stand_alone_manager=is_stand_alone_manager, + ) + + # global domain containing the manually added global objects + manager_details.domain_name = "Global" + manager_details.domain_uid = "Global" + get_objects_per_domain( + manager_details, + native_config_dict["domains"][0], + obj_type_array, + show_params_objs, + is_stand_alone_manager=is_stand_alone_manager, + ) + else: + get_objects_per_domain( + manager_details, + native_config_dict["domains"][manager_index], + obj_type_array, + show_params_objs, + is_stand_alone_manager=is_stand_alone_manager, + ) + + manager_index += 1 + return 0 + + +def get_objects_per_domain( + manager_details: ManagementController, + native_domain: dict[str, Any], + obj_type_array: list[str], + show_params_objs: dict[str, Any], + is_stand_alone_manager: bool = True, +) -> None: + sid = cp_getter.login(manager_details) + cp_url = manager_details.build_fw_api_string() + for obj_type in obj_type_array: + object_table = get_objects_per_type(obj_type, show_params_objs, sid, cp_url) + add_special_objects_to_global_domain(object_table, obj_type, sid, cp_api_url=cp_url) + if not is_stand_alone_manager and not manager_details.is_super_manager: + remove_predefined_objects_for_domains(object_table) + native_domain["objects"].append(object_table) + + +def remove_predefined_objects_for_domains(object_table: dict[str, Any]) -> None: + if ( + "chunks" in object_table + and "type" in object_table + and object_table["type"] in cp_const.types_to_remove_globals_from + ): + return + + for chunk in object_table["chunks"]: + if "objects" in chunk: + for obj in chunk["objects"]: + domain_type = obj.get("domain", {}).get("domain-type", "") + if domain_type != "domain": + chunk["objects"].remove(obj) + + +def get_objects_per_type( + obj_type: str, show_params_objs: dict[str, Any], sid: str, cp_manager_api_base_url: str +) -> dict[str, Any]: + if fwo_globals.shutdown_requested: + raise ImportInterruptionError("Shutdown requested during object retrieval.") + if obj_type in cp_const.obj_types_full_fetch_needed: + show_params_objs.update({"details-level": cp_const.details_level_group_objects}) + else: + show_params_objs.update({"details-level": cp_const.details_level_objects}) + object_table: dict[str, Any] = {"type": obj_type, "chunks": []} + current = 0 + total = current + 1 + show_cmd = "show-" + obj_type + FWOLogger.debug("obj_type: " + obj_type, 6) + + while current < total: + show_params_objs["offset"] = current + objects = cp_getter.cp_api_call(cp_manager_api_base_url, show_cmd, show_params_objs, sid) + if fwo_globals.shutdown_requested: + raise ImportInterruptionError("Shutdown requested during object retrieval.") + + object_table["chunks"].append(objects) + if "total" in objects and "to" in objects: + total = objects["total"] + current = objects["to"] + FWOLogger.debug(obj_type + " current:" + str(current) + " of a total " + str(total), 6) + else: + current = total + + return object_table + + +def add_special_objects_to_global_domain( + object_table: dict[str, Any], obj_type: str, sid: str, cp_api_url: str +) -> None: + """ + Appends special objects Original, Any, None and Internet to global domain + """ + # getting Original (NAT) object (both for networks and services) + orig_obj = cp_getter.get_object_details_from_api(cp_const.original_obj_uid, sid=sid, apiurl=cp_api_url)["chunks"][0] + any_obj = cp_getter.get_object_details_from_api(cp_const.any_obj_uid, sid=sid, apiurl=cp_api_url)["chunks"][0] + none_obj = cp_getter.get_object_details_from_api(cp_const.none_obj_uid, sid=sid, apiurl=cp_api_url)["chunks"][0] + internet_obj = cp_getter.get_object_details_from_api(cp_const.internet_obj_uid, sid=sid, apiurl=cp_api_url)[ + "chunks" + ][0] + + if obj_type == "networks": + object_table["chunks"].append(orig_obj) + object_table["chunks"].append(any_obj) + object_table["chunks"].append(none_obj) + object_table["chunks"].append(internet_obj) + if obj_type == "services-other": + object_table["chunks"].append(orig_obj) + object_table["chunks"].append(any_obj) + object_table["chunks"].append(none_obj) diff --git a/roles/importer/files/importer/dummyroutermanagement1/__init__.py b/roles/importer/files/importer/fw_modules/ciscoasa9/__init__.py similarity index 100% rename from roles/importer/files/importer/dummyroutermanagement1/__init__.py rename to roles/importer/files/importer/fw_modules/ciscoasa9/__init__.py diff --git a/roles/importer/files/importer/fw_modules/ciscoasa9/asa_maps.py b/roles/importer/files/importer/fw_modules/ciscoasa9/asa_maps.py new file mode 100644 index 0000000000..3a458011c3 --- /dev/null +++ b/roles/importer/files/importer/fw_modules/ciscoasa9/asa_maps.py @@ -0,0 +1,129 @@ +from typing import Any + +name_to_port: dict[str, dict[str, Any]] = { + "aol": {"port": 5190, "protocols": ["TCP"], "description": "America Online"}, + "bgp": {"port": 179, "protocols": ["TCP"], "description": "Border Gateway Protocol, RFC 1163"}, + "biff": { + "port": 512, + "protocols": ["UDP"], + "description": "Used by mail system to notify users that new mail is received", + }, + "bootpc": {"port": 68, "protocols": ["UDP"], "description": "Bootstrap Protocol Client"}, + "bootps": {"port": 67, "protocols": ["UDP"], "description": "Bootstrap Protocol Server"}, + "chargen": {"port": 19, "protocols": ["TCP"], "description": "Character Generator"}, + "cifs": {"port": 3020, "protocols": ["TCP", "UDP"], "description": "Common Internet File System"}, + "citrix-ica": { + "port": 1494, + "protocols": ["TCP"], + "description": "Citrix Independent Computing Architecture (ICA) protocol", + }, + "cmd": { + "port": 514, + "protocols": ["TCP"], + "description": "Similar to exec except that cmd has automatic authentication", + }, + "ctiqbe": {"port": 2748, "protocols": ["TCP"], "description": "Computer Telephony Interface Quick Buffer Encoding"}, + "daytime": {"port": 13, "protocols": ["TCP"], "description": "Day time, RFC 867"}, + "discard": {"port": 9, "protocols": ["TCP", "UDP"], "description": "Discard"}, + "dnsix": {"port": 195, "protocols": ["UDP"], "description": "DNSIX Session Management Module Audit Redirector"}, + "domain": {"port": 53, "protocols": ["TCP", "UDP"], "description": "DNS"}, + "echo": {"port": 7, "protocols": ["TCP", "UDP"], "description": "Echo"}, + "exec": {"port": 512, "protocols": ["TCP"], "description": "Remote process execution"}, + "finger": {"port": 79, "protocols": ["TCP"], "description": "Finger"}, + "ftp": {"port": 21, "protocols": ["TCP"], "description": "File Transfer Protocol (control port)"}, + "ftp-data": {"port": 20, "protocols": ["TCP"], "description": "File Transfer Protocol (data port)"}, + "gopher": {"port": 70, "protocols": ["TCP"], "description": "Gopher"}, + "h323": {"port": 1720, "protocols": ["TCP"], "description": "H.323 call signaling"}, + "hostname": {"port": 101, "protocols": ["TCP"], "description": "NIC Host Name Server"}, + "http": {"port": 80, "protocols": ["TCP", "UDP"], "description": "World Wide Web HTTP"}, + "https": {"port": 443, "protocols": ["TCP"], "description": "HTTP over SSL"}, + "ident": {"port": 113, "protocols": ["TCP"], "description": "Ident authentication service"}, + "imap4": {"port": 143, "protocols": ["TCP"], "description": "Internet Message Access Protocol, version 4"}, + "irc": {"port": 194, "protocols": ["TCP"], "description": "Internet Relay Chat protocol"}, + "isakmp": { + "port": 500, + "protocols": ["UDP"], + "description": "Internet Security Association and Key Management Protocol", + }, + "kerberos": {"port": 750, "protocols": ["TCP", "UDP"], "description": "Kerberos"}, + "klogin": {"port": 543, "protocols": ["TCP"], "description": "KLOGIN"}, + "kshell": {"port": 544, "protocols": ["TCP"], "description": "Korn Shell"}, + "ldap": {"port": 389, "protocols": ["TCP"], "description": "Lightweight Directory Access Protocol"}, + "ldaps": {"port": 636, "protocols": ["TCP"], "description": "Lightweight Directory Access Protocol (SSL)"}, + "login": {"port": 513, "protocols": ["TCP"], "description": "Remote login"}, + "lotusnotes": {"port": 1352, "protocols": ["TCP"], "description": "IBM Lotus Notes"}, + "lpd": {"port": 515, "protocols": ["TCP"], "description": "Line Printer Daemon - printer spooler"}, + "mobile-ip": {"port": 434, "protocols": ["UDP"], "description": "Mobile IP-Agent"}, + "nameserver": {"port": 42, "protocols": ["UDP"], "description": "Host Name Server"}, + "netbios-dgm": {"port": 138, "protocols": ["UDP"], "description": "NetBIOS Datagram Service"}, + "netbios-ns": {"port": 137, "protocols": ["UDP"], "description": "NetBIOS Name Service"}, + "netbios-ssn": {"port": 139, "protocols": ["TCP"], "description": "NetBIOS Session Service"}, + "nfs": {"port": 2049, "protocols": ["TCP", "UDP"], "description": "Network File System - Sun Microsystems"}, + "nntp": {"port": 119, "protocols": ["TCP"], "description": "Network News Transfer Protocol"}, + "ntp": {"port": 123, "protocols": ["UDP"], "description": "Network Time Protocol"}, + "pcanywhere-data": {"port": 5631, "protocols": ["TCP"], "description": "pcAnywhere data"}, + "pcanywhere-status": {"port": 5632, "protocols": ["UDP"], "description": "pcAnywhere status"}, + "pim-auto-rp": { + "port": 496, + "protocols": ["TCP", "UDP"], + "description": "Protocol Independent Multicast, reverse path flooding, dense mode", + }, + "pop2": {"port": 109, "protocols": ["TCP"], "description": "Post Office Protocol - Version 2"}, + "pop3": {"port": 110, "protocols": ["TCP"], "description": "Post Office Protocol - Version 3"}, + "pptp": {"port": 1723, "protocols": ["TCP"], "description": "Point-to-Point Tunneling Protocol"}, + "radius": {"port": 1645, "protocols": ["UDP"], "description": "Remote Authentication Dial-In User Service"}, + "radius-acct": { + "port": 1646, + "protocols": ["UDP"], + "description": "Remote Authentication Dial-In User Service (accounting)", + }, + "rip": {"port": 520, "protocols": ["UDP"], "description": "Routing Information Protocol"}, + "rsh": {"port": 514, "protocols": ["TCP"], "description": "Remote Shell"}, + "rtsp": {"port": 554, "protocols": ["TCP"], "description": "Real Time Streaming Protocol"}, + "secureid-udp": {"port": 5510, "protocols": ["UDP"], "description": "SecureID over UDP"}, + "sip": {"port": 5060, "protocols": ["TCP", "UDP"], "description": "Session Initiation Protocol"}, + "smtp": {"port": 25, "protocols": ["TCP"], "description": "Simple Mail Transport Protocol"}, + "snmp": {"port": 161, "protocols": ["UDP"], "description": "Simple Network Management Protocol"}, + "snmptrap": {"port": 162, "protocols": ["UDP"], "description": "Simple Network Management Protocol - Trap"}, + "sqlnet": {"port": 1521, "protocols": ["TCP"], "description": "Structured Query Language Network"}, + "ssh": {"port": 22, "protocols": ["TCP"], "description": "Secure Shell"}, + "sunrpc": {"port": 111, "protocols": ["TCP", "UDP"], "description": "Sun Remote Procedure Call"}, + "syslog": {"port": 514, "protocols": ["UDP"], "description": "System Log"}, + "tacacs": { + "port": 49, + "protocols": ["TCP", "UDP"], + "description": "Terminal Access Controller Access Control System Plus", + }, + "talk": {"port": 517, "protocols": ["TCP", "UDP"], "description": "Talk"}, + "telnet": {"port": 23, "protocols": ["TCP"], "description": "RFC 854 Telnet"}, + "tftp": {"port": 69, "protocols": ["UDP"], "description": "Trivial File Transfer Protocol"}, + "time": {"port": 37, "protocols": ["UDP"], "description": "Time"}, + "uucp": {"port": 540, "protocols": ["TCP"], "description": "UNIX-to-UNIX Copy Program"}, + "vxlan": {"port": 4789, "protocols": ["UDP"], "description": "Virtual eXtensible Local Area Network (VXLAN)"}, + "who": {"port": 513, "protocols": ["UDP"], "description": "Who"}, + "whois": {"port": 43, "protocols": ["TCP"], "description": "Who Is"}, + "www": {"port": 80, "protocols": ["TCP", "UDP"], "description": "World Wide Web"}, + "xdmcp": {"port": 177, "protocols": ["UDP"], "description": "X Display Manager Control Protocol"}, +} + +protocol_map = { + "ah": 51, + "eigrp": 88, + "esp": 50, + "gre": 47, + "icmp": 1, + "icmp6": 58, + "igmp": 2, + "igrp": 9, + "ipinip": 4, + "ipsec": 50, + "nos": 94, + "ospf": 89, + "pcp": 108, + "pim": 103, + "pptp": 47, + "sctp": 132, + "snp": 77, + "tcp": 6, + "udp": 17, +} diff --git a/roles/importer/files/importer/fw_modules/ciscoasa9/asa_models.py b/roles/importer/files/importer/fw_modules/ciscoasa9/asa_models.py new file mode 100644 index 0000000000..59a7a559df --- /dev/null +++ b/roles/importer/files/importer/fw_modules/ciscoasa9/asa_models.py @@ -0,0 +1,198 @@ +from __future__ import annotations + +from typing import Literal + +from pydantic import BaseModel + + +class AsaEnablePassword(BaseModel): + password: str + encryption_function: str + + +class AsaServiceModule(BaseModel): + name: str + keepalive_timeout: int + keepalive_counter: int + + +class Names(BaseModel): + name: str + ip_address: str + description: str | None = None + + +class Interface(BaseModel): + name: str + nameif: str + bridge_group: str | None = None + security_level: int + ip_address: str | None = None + subnet_mask: str | None = None + additional_settings: list[str] + description: str | None = None + + +class AsaNetworkObject(BaseModel): + name: str + ip_address: str + ip_address_end: str | None = None # for range objects + subnet_mask: str | None = None + fqdn: str | None = None + description: str | None = None + + +class AsaNetworkObjectGroup(BaseModel): + name: str + objects: list[AsaNetworkObjectGroupMember] + description: str | None = None + + +class AsaNetworkObjectGroupMember(BaseModel): + kind: Literal["object", "object-group", "host", "hostv6", "subnet", "subnetv6"] + value: str + mask: str | None = None + + +class AsaServiceObject(BaseModel): + name: str + protocol: Literal["tcp", "udp", "ip", "tcp-udp", "icmp", "gre"] + dst_port_eq: str | None = None + dst_port_range: tuple[str, str] | None = None + description: str | None = None + + +class AsaServiceObjectGroup(BaseModel): + name: str + proto_mode: Literal["tcp", "udp", "tcp-udp"] | None + ports_eq: dict[str, list[str]] # protocol -> list of ports + ports_range: dict[str, list[tuple[str, str]]] # protocol -> list of (start_port, end_port) + nested_refs: list[str] + protocols: list[str] + description: str | None + + +class AsaProtocolGroup(BaseModel): + name: str + protocols: list[str] + description: str | None = None + + +class EndpointKind(BaseModel): + kind: Literal[ + "any", + "host", + "subnet", + "object", + "object-group", + "service", + "protocol-group", + "protocol", + "eq", + "range", + "service-group", + ] + value: str + mask: str | None = None + + +class AccessListEntry(BaseModel): + acl_name: str + action: Literal["permit", "deny"] + protocol: EndpointKind # Changed to use EndpointKind for kind and value + src: EndpointKind + dst: EndpointKind + dst_port: EndpointKind # Changed to use EndpointKind for kind and value + inactive: bool = False # Added field for inactive flag + description: str | None = None + + +class AccessList(BaseModel): + name: str + entries: list[AccessListEntry] + + +class AccessGroupBinding(BaseModel): + acl_name: str + direction: Literal["in", "out"] + interface: str + + +class NatRule(BaseModel): + object_name: str + src_if: str + dst_if: str + nat_type: Literal["dynamic", "static"] = "dynamic" + translated_object: str | None = None + + +class Route(BaseModel): + interface: str + destination: str + netmask: str + next_hop: str + distance: int | None = None + + +class MgmtAccessRule(BaseModel): + protocol: Literal["http", "ssh", "telnet"] + source_ip: str + source_mask: str + interface: str + + +class ClassMap(BaseModel): + name: str + matches: list[str] = [] # e.g., ["default-inspection-traffic"] + + +class DnsInspectParameters(BaseModel): + message_length_max_client: Literal["auto", "default"] | int | None = None + message_length_max: int | None = None + tcp_inspection: bool = True # "no tcp-inspection" -> False + + +class InspectionAction(BaseModel): + protocol: str # e.g., "dns", "ftp" + policy_map: str | None = None # e.g., "preset_dns_map" after "inspect dns preset_dns_map" + + +class PolicyClass(BaseModel): + class_name: str # e.g., "inspection_default" + inspections: list[InspectionAction] = [] + + +class PolicyMap(BaseModel): + name: str # e.g., "global_policy" or "preset_dns_map" + type_str: str | None = None # e.g., "inspect dns" for typed maps + parameters_dns: DnsInspectParameters | None = None + classes: list[PolicyClass] = [] + + +class ServicePolicyBinding(BaseModel): + policy_map: str # e.g., "global_policy" + scope: Literal["global", "interface"] = "global" + interface: str | None = None + + +class Config(BaseModel): + asa_version: str + hostname: str + enable_password: AsaEnablePassword + service_modules: list[AsaServiceModule] + additional_settings: list[str] + interfaces: list[Interface] + objects: list[AsaNetworkObject] + object_groups: list[AsaNetworkObjectGroup] + service_objects: list[AsaServiceObject] = [] + service_object_groups: list[AsaServiceObjectGroup] = [] + access_lists: list[AccessList] = [] + access_group_bindings: list[AccessGroupBinding] = [] + nat_rules: list[NatRule] = [] + routes: list[Route] = [] + mgmt_access: list[MgmtAccessRule] = [] + names: list[Names] = [] + class_maps: list[ClassMap] = [] + policy_maps: list[PolicyMap] = [] + service_policies: list[ServicePolicyBinding] = [] + protocol_groups: list[AsaProtocolGroup] = [] diff --git a/roles/importer/files/importer/fw_modules/ciscoasa9/asa_network.py b/roles/importer/files/importer/fw_modules/ciscoasa9/asa_network.py new file mode 100644 index 0000000000..307b452abf --- /dev/null +++ b/roles/importer/files/importer/fw_modules/ciscoasa9/asa_network.py @@ -0,0 +1,373 @@ +""" +ASA Network Object Management + +This module handles the normalization of network objects from ASA configurations. +It manages both explicit network objects/groups and implicit network objects created from +inline ACL or group definitions. +""" + +import fwo_base +import fwo_const +from fw_modules.ciscoasa9.asa_models import ( + AsaNetworkObject, + AsaNetworkObjectGroup, + AsaNetworkObjectGroupMember, + EndpointKind, + Names, +) +from fwo_log import FWOLogger +from models.networkobject import NetworkObject +from netaddr import IPAddress, IPNetwork + + +def create_network_host(name: str, ip_address: str, comment: str | None, ip_version: int) -> NetworkObject: + """ + Create a normalized host network object. + + Args: + name: Object name/UID + ip_address: IP address + comment: Optional description + ip_version: IP version (4 or 6) + + Returns: + Normalized NetworkObject instance + + """ + obj_ip = IPNetwork(f"{ip_address}/128", version=6) if ip_version == 6 else IPNetwork(f"{ip_address}/32") # noqa: PLR2004 + return NetworkObject( + obj_uid=name, + obj_name=name, + obj_typ="host", + obj_ip=obj_ip, + obj_ip_end=obj_ip, + obj_color=fwo_const.DEFAULT_COLOR, + obj_comment=comment, + ) + + +def create_network_subnet( + name: str, ip_address: str, subnet_mask: str | None, comment: str | None, ip_version: int +) -> NetworkObject: + """ + Create a normalized network object. + + Args: + name: Object name/UID + ip_address: Network address + subnet_mask: Subnet mask + comment: Optional description + ip_version: IP version (4 or 6) + + Returns: + Normalized NetworkObject instance + + """ + if ip_version == 6: # noqa: PLR2004 + # ip_address is expected to be in CIDR notation for IPv6 + network = IPNetwork(ip_address, version=6) + ip_start = IPNetwork(f"{IPAddress(network.first)}/128", version=6) + ip_end = IPNetwork(f"{IPAddress(network.last)}/128", version=6) + else: + if subnet_mask is None: + raise ValueError("Subnet mask is required for IPv4 subnet objects.") + network = IPNetwork(f"{ip_address}/{subnet_mask}") + ip_start = IPNetwork(f"{ip_address}/32") + ip_end = IPNetwork(f"{IPAddress(network.first + network.size - 1)}/32") + + return NetworkObject( + obj_uid=name, + obj_name=name, + obj_typ="network", + obj_ip=ip_start, + obj_ip_end=ip_end, + obj_color=fwo_const.DEFAULT_COLOR, + obj_comment=comment, + ) + + +def create_network_range(name: str, ip_start: str, ip_end: str, comment: str | None) -> NetworkObject: + """ + Create a normalized range network object. + + Args: + name: Object name/UID + ip_start: Start IP address + ip_end: End IP address + comment: Optional description + + Returns: + Normalized NetworkObject instance + + """ + return NetworkObject( + obj_uid=name, + obj_name=name, + obj_typ="ip_range", + obj_ip=IPNetwork(f"{ip_start}/32"), + obj_ip_end=IPNetwork(f"{ip_end}/32"), + obj_color=fwo_const.DEFAULT_COLOR, + obj_comment=comment, + ) + + +def create_network_group_object(name: str, member_refs: list[str], comment: str | None = None) -> NetworkObject: + """ + Create a network group object. + + Args: + name: Group name/UID + member_refs: List of member network object references + comment: Optional description + + Returns: + Normalized NetworkObject group instance + + """ + return NetworkObject( + obj_uid=name, + obj_name=name, + obj_typ="group", + obj_member_names=fwo_base.sort_and_join(member_refs), + obj_member_refs=fwo_base.sort_and_join(member_refs), + obj_color=fwo_const.DEFAULT_COLOR, + obj_comment=comment, + ) + + +def create_any_network_object() -> NetworkObject: + """ + Create the special 'any' network object representing all addresses. + + Returns: + Normalized NetworkObject for 'any' + + """ + return NetworkObject( + obj_uid="any", + obj_name="any", + obj_typ="network", + obj_member_names="", + obj_member_refs="", + obj_ip=IPNetwork("0.0.0.0/32"), + obj_ip_end=IPNetwork("255.255.255.255/32"), + obj_color=fwo_const.DEFAULT_COLOR, + obj_comment="network object created during import", + ) + + +def normalize_names(names: list[Names]) -> dict[str, NetworkObject]: + """ + Normalize 'names' entries (simple IP-to-name mappings). + + Args: + names: List of Names objects from ASA configuration + + Returns: + Dictionary of normalized network objects keyed by obj_uid + + """ + network_objects: dict[str, NetworkObject] = {} + + for name in names: + obj = create_network_host(name.name, name.ip_address, name.description, ip_version=4) + network_objects[name.name] = obj + + return network_objects + + +def normalize_network_objects(network_objects_list: list[AsaNetworkObject]) -> dict[str, NetworkObject]: + """ + Normalize network objects from ASA configuration. + + Args: + network_objects_list: List of AsaNetworkObject instances + + Returns: + Dictionary of normalized network objects keyed by obj_uid + + """ + network_objects: dict[str, NetworkObject] = {} + + for obj in network_objects_list: + if obj.fqdn is not None: + # handle FQDN objects as empty group for now /TODO + network_obj = create_network_group_object(obj.name, [], obj.description) + network_objects[obj.name] = network_obj + elif obj.ip_address and obj.subnet_mask: + # Network object with subnet mask + network_obj = create_network_subnet( + obj.name, obj.ip_address, obj.subnet_mask, obj.description, ip_version=4 + ) + network_objects[obj.name] = network_obj + elif obj.ip_address and obj.ip_address_end: + network_obj = create_network_range(obj.name, obj.ip_address, obj.ip_address_end, obj.description) + network_objects[obj.name] = network_obj + elif obj.ip_address: + # Host object (single IP address) + network_obj = create_network_host(obj.name, obj.ip_address, obj.description, ip_version=4) + network_objects[obj.name] = network_obj + + return network_objects + + +def normalize_network_object_groups( + object_groups: list[AsaNetworkObjectGroup], network_objects: dict[str, NetworkObject] +) -> dict[str, NetworkObject]: + """ + Normalize network object groups from ASA configuration. + + Args: + object_groups: List of AsaNetworkObjectGroup instances + network_objects: Existing network objects dictionary to update + logger: Logger instance for warnings + + Returns: + Updated network objects dictionary including groups + + """ + for group in object_groups: + member_refs: list[str] = [] + + for member in group.objects: + try: + # Use the modular function to create/get the member object + network_obj = get_network_group_member(member, network_objects) + + # Add the reference to the member list + member_refs.append(network_obj.obj_uid) + + except ValueError as e: # noqa: PERF203 + FWOLogger.warning(f"Error processing member in network object group '{group.name}': {e}") + + group_obj = create_network_group_object(group.name, member_refs, group.description) + network_objects[group.name] = group_obj + + return network_objects + + +def get_network_group_member_host(member: AsaNetworkObjectGroupMember) -> NetworkObject: + """ + Create a host network object for a network object group member. + + Args: + member: Network object group member of kind 'host' or 'hostv6' + + Returns: + NetworkObject instance + + """ + ip_version = 6 if member.kind == "hostv6" else 4 + return create_network_host(member.value, member.value, None, ip_version=ip_version) + + +def get_network_group_member_ref(member: AsaNetworkObjectGroupMember) -> str: + """ + Get the reference string for a network object group member. + + Args: + member: Network object group member + Returns: + + Reference string for the member + + """ + if member.kind == "subnet": + if member.mask is None: + raise ValueError("Subnet mask is required for subnet member kind.") + return f"{member.value}/{member.mask}" + return member.value + + +def create_network_group_member(ref: str, member: AsaNetworkObjectGroupMember) -> NetworkObject: + """ + Create a network object for a network object group member. + + Args: + ref: Reference string for the member + member: Network object group member + Returns: + NetworkObject instance + + """ + if member.kind == "host": + return create_network_host(ref, member.value, None, ip_version=4) + if member.kind == "hostv6": + return create_network_host(ref, member.value, None, ip_version=6) + if member.kind == "subnet": + return create_network_subnet(ref, member.value, member.mask, None, ip_version=4) + if member.kind == "subnetv6": + return create_network_subnet(ref, member.value, None, None, ip_version=6) + raise ValueError(f"Unsupported member kind '{member.kind}' in network object group.") + + +def get_network_group_member( + member: AsaNetworkObjectGroupMember, network_objects: dict[str, NetworkObject] +) -> NetworkObject: + """ + Get network object for a network object group member reference. If it does not exist, create it. + + Args: + member: Network object group member + network_objects: Dictionary of existing network objects + + Returns: + NetworkObject instance + + """ + ref = get_network_group_member_ref(member) + if ref in network_objects: + return network_objects[ref] + if member.kind in ("object", "object-group"): + raise ValueError(f"Referenced network object '{ref}' not found in configuration.") + + network_object = create_network_group_member(ref, member) + network_objects[network_object.obj_uid] = network_object + return network_object + + +def get_network_rule_endpoint(endpoint: EndpointKind, network_objects: dict[str, NetworkObject]) -> NetworkObject: + """ + Get network object for a rule endpoint. If it does not exist, create it. + + Args: + endpoint: Rule endpoint (src or dst) + network_objects: Dictionary of existing network objects + + Returns: + NetworkObject instance + + """ + network_object = None + if endpoint.kind == "host": + # Single host IP (e.g., 'host 10.0.0.1') + ref = endpoint.value + if ref in network_objects: + return network_objects[ref] + network_object = create_network_host(endpoint.value, endpoint.value, None, ip_version=4) + elif endpoint.kind == "subnet": + # Subnet with mask (e.g., '10.0.0.0 255.255.255.0') + # Object name is subnet in CIDR notation + ref = str(IPNetwork(f"{endpoint.value}/{endpoint.mask}")) + if ref in network_objects: + return network_objects[ref] + if endpoint.mask is None: + raise ValueError("Subnet mask is required for subnet endpoint kind.") + network_object = create_network_subnet(ref, endpoint.value, endpoint.mask, None, ip_version=4) + elif endpoint.kind == "any": + # 'any' keyword (0.0.0.0 - 255.255.255.255) + if "any" in network_objects: + return network_objects["any"] + network_object = create_any_network_object() + elif endpoint.kind in ("object", "object-group"): + # Reference to existing object or object-group - assume it already exists + ref = endpoint.value + ref_obj = network_objects.get(ref) + if not ref_obj: + raise ValueError(f"Referenced network object '{ref}' not found in configuration.") + return ref_obj + else: + raise ValueError(f"Unknown endpoint kind: {endpoint.kind}") + + network_objects[network_object.obj_uid] = network_object + return network_object diff --git a/roles/importer/files/importer/fw_modules/ciscoasa9/asa_normalize.py b/roles/importer/files/importer/fw_modules/ciscoasa9/asa_normalize.py new file mode 100644 index 0000000000..16b94a9ac2 --- /dev/null +++ b/roles/importer/files/importer/fw_modules/ciscoasa9/asa_normalize.py @@ -0,0 +1,185 @@ +""" +ASA Configuration Normalization + +This module handles the top-level normalization of ASA configurations, +orchestrating the conversion from native ASA format to the normalized +format used by the firewall orchestrator. +""" + +from fw_modules.ciscoasa9.asa_models import Config + +# Import the new modular functions +from fw_modules.ciscoasa9.asa_network import normalize_names, normalize_network_object_groups, normalize_network_objects +from fw_modules.ciscoasa9.asa_rule import build_rulebases_from_access_lists +from fw_modules.ciscoasa9.asa_service import ( + create_protocol_any_service_objects, + normalize_service_object_groups, + normalize_service_objects, +) +from fwo_enums import ConfigAction +from fwo_log import FWOLogger +from model_controllers.fwconfigmanagerlist_controller import FwConfigManagerListController +from models.fwconfig_normalized import FwConfigNormalized +from models.gateway import Gateway +from models.import_state import ImportState +from models.networkobject import NetworkObject +from models.rulebase_link import RulebaseLinkUidBased +from models.serviceobject import ServiceObject + + +def normalize_all_network_objects(native_config: Config) -> dict[str, NetworkObject]: + """ + Normalize all network objects from the native ASA configuration. + + This function processes: + - Named hosts (from 'names' command) + - Network objects (hosts and subnets) + - Network object groups + + Args: + native_config: Parsed ASA configuration containing network objects. + logger: Logger instance for warnings and debug messages. + + Returns: + Dictionary of normalized network objects keyed by obj_uid. + + """ + # Start with names (simple IP-to-name mappings) + network_objects = normalize_names(native_config.names) + + # Add individual network objects + network_objects.update(normalize_network_objects(native_config.objects)) + + # Add network object groups + normalize_network_object_groups(native_config.object_groups, network_objects) + + return network_objects + + +def normalize_all_service_objects(native_config: Config) -> dict[str, ServiceObject]: + """ + Normalize all service objects from the native ASA configuration. + + This function processes: + - Individual service objects (with specific ports or port ranges) + - Default 'any' service objects for common protocols + - Service object groups (including mixed protocol groups) + + Args: + native_config: Parsed ASA configuration containing service objects. + + Returns: + Dictionary of normalized service objects keyed by svc_uid. + + """ + # Start with individual service objects + service_objects = normalize_service_objects(native_config.service_objects) + + # Add default 'any' protocol service objects + service_objects.update(create_protocol_any_service_objects()) + + # Add service object groups + normalize_service_object_groups(native_config.service_object_groups, service_objects) + + return service_objects + + +def normalize_config( + config_in: FwConfigManagerListController, import_state: ImportState +) -> FwConfigManagerListController: + """ + Normalize the ASA configuration into a structured format for the database. + + This function orchestrates the normalization process: + 1. Parse the native configuration + 2. Normalize network objects (hosts, networks, groups) + 3. Normalize service objects (ports, protocols, groups) + 4. Build rulebases from access lists (including inline object creation) + 5. Create gateway and rulebase links + 6. Construct the final normalized configuration + + Args: + config_in: Configuration input details containing native config. + importState: Current import state with management details. + + Returns: + Updated config_in with normalized configuration. + + """ + # Parse the native configuration into structured objects + native_config: Config = Config.model_validate(config_in.native_config) + + # Step 1: Normalize network objects (names, objects, object-groups) + FWOLogger.debug("Normalizing network objects...") + network_objects = normalize_all_network_objects(native_config) + + # Step 2: Normalize service objects (service objects with ports/protocols) + FWOLogger.debug("Normalizing service objects...") + service_objects = normalize_all_service_objects(native_config) + + # Step 3: Build rulebases from access lists (this will create additional objects as needed) + FWOLogger.debug("Building rulebases from access lists...") + rulebases = build_rulebases_from_access_lists( + native_config.access_lists, + import_state.mgm_details.uid, + protocol_groups=native_config.protocol_groups, + network_objects=network_objects, + service_objects=service_objects, + ) + + # Step 4: Create rulebase links (ordered chain of rulebases) + rulebase_links: list[RulebaseLinkUidBased] = [] + if len(rulebases) > 0: + # First rulebase is the initial entry point + rulebase_links.append( + RulebaseLinkUidBased( + to_rulebase_uid=rulebases[0].uid, + link_type="ordered", + is_initial=True, + is_global=False, + is_section=False, + ) + ) + # Link subsequent rulebases in order + rulebase_links += [ + RulebaseLinkUidBased( + from_rulebase_uid=rulebases[idx - 1].uid, + to_rulebase_uid=rulebases[idx].uid, + link_type="ordered", + is_initial=False, + is_global=False, + is_section=False, + ) + for idx in range(1, len(rulebases)) + ] + + # Step 5: Create gateway object representing the ASA device + FWOLogger.debug("Creating gateway object...") + gateway = Gateway( + Uid=native_config.hostname, + Name=native_config.hostname, + Routing=[], + RulebaseLinks=rulebase_links, + GlobalPolicyUid=None, + EnforcedPolicyUids=[], + EnforcedNatPolicyUids=[], + ImportDisabled=False, + ShowInUI=True, + ) + + # Step 6: Construct the normalized configuration + FWOLogger.debug("Constructing normalized configuration...") + normalized_config = FwConfigNormalized( + action=ConfigAction.INSERT, + network_objects=network_objects, + service_objects=service_objects, + zone_objects={}, # ASA doesn't use zones like other firewalls + rulebases=rulebases, + gateways=[gateway], + ) + + # Update the configuration input with normalized data + config_in.ManagerSet[0].configs = [normalized_config] + config_in.ManagerSet[0].manager_uid = import_state.mgm_details.uid + + return config_in diff --git a/roles/importer/files/importer/fw_modules/ciscoasa9/asa_parser.py b/roles/importer/files/importer/fw_modules/ciscoasa9/asa_parser.py new file mode 100644 index 0000000000..2770a06026 --- /dev/null +++ b/roles/importer/files/importer/fw_modules/ciscoasa9/asa_parser.py @@ -0,0 +1,395 @@ +import json +import re +from pathlib import Path +from typing import TYPE_CHECKING + +from fw_modules.ciscoasa9.asa_models import ( + AccessGroupBinding, + AccessList, + AccessListEntry, + AsaEnablePassword, + AsaNetworkObject, + AsaNetworkObjectGroup, + AsaProtocolGroup, + AsaServiceModule, + AsaServiceObject, + AsaServiceObjectGroup, + ClassMap, + Config, + Interface, + MgmtAccessRule, + Names, + NatRule, + PolicyMap, + Route, + ServicePolicyBinding, +) +from fw_modules.ciscoasa9.asa_parser_functions import ( + clean_lines, + consume_block, + parse_access_list_entry, + parse_class_map_block, + parse_dns_inspect_policy_map_block, + parse_icmp_object_group_block, + parse_interface_block, + parse_network_object_block, + parse_network_object_group_block, + parse_policy_map_block, + parse_protocol_object_group_block, + parse_service_object_block, + parse_service_object_group_block, +) +from fwo_log import FWOLogger + +if TYPE_CHECKING: + from collections.abc import Callable + + +def parse_asa_config(raw_config: str) -> Config: + lines = clean_lines(raw_config) + + # Initialize state + state = _ParserState() + + # Handler registry: (pattern, handler_function) + handlers: list[tuple[re.Pattern[str], Callable[[re.Match[str], str, list[str], int, _ParserState], int]]] = [ + (re.compile(r"^ASA Version\s+(\S+)$", re.IGNORECASE), _handle_asa_version), + (re.compile(r"^hostname\s+(\S+)$", re.IGNORECASE), _handle_hostname), + (re.compile(r"^enable password\s+(\S+)\s+(\S+)$", re.IGNORECASE), _handle_enable_password), + ( + re.compile(r"^service-module\s+(\S+)\s+keepalive-timeout\s+(\d+)$", re.IGNORECASE), + _handle_service_module_timeout, + ), + ( + re.compile(r"^service-module\s+(\S+)\s+keepalive-counter\s+(\d+)$", re.IGNORECASE), + _handle_service_module_counter, + ), + (re.compile(r"^name\s+(\d{1,3}(?:\.\d{1,3}){3})\s+(\S+)(?:\s+description\s)?", re.IGNORECASE), _handle_name), + (re.compile(r"^interface\s+\S+", re.IGNORECASE), _handle_interface_block), + (re.compile(r"^object\s+network\s+\S+$", re.IGNORECASE), _handle_network_object_block), + (re.compile(r"^object-group\s+network\s+\S+$", re.IGNORECASE), _handle_network_object_group_block), + (re.compile(r"^object\s+service\s+\S+$", re.IGNORECASE), _handle_service_object_block), + ( + re.compile(r"^object-group\s+service\s+\S+", re.IGNORECASE), + _handle_service_object_group, + ), # left intentionally without $ + (re.compile(r"^object-group\s+icmp-type\s+\S+$", re.IGNORECASE), _handle_icmp_object_group_block), + (re.compile(r"^object-group\s+protocol\s+\S+$", re.IGNORECASE), _handle_protocol_object_group_block), + (re.compile(r"^access-list\s+\S+\s+extended\s+(permit|deny)\s+", re.IGNORECASE), _handle_access_list_entry), + (re.compile(r"^access-group\s+(\S+)\s+(in|out)\s+interface\s+(\S+)$", re.IGNORECASE), _handle_access_group), + (re.compile(r"^route\s+(\S+)\s+([\d.]+)\s+([\d.]+)\s+([\d.]+)(?:\s+(\d+))?$", re.IGNORECASE), _handle_route), + ( + re.compile(r"^(http|ssh|telnet)\s+(\d+\.\d+\.\d+\.\d+)\s+(\d+\.\d+\.\d+\.\d+)\s+(\S+)$", re.IGNORECASE), + _handle_mgmt_access, + ), + (re.compile(r"^class-map\s+\S+", re.IGNORECASE), _handle_class_map_block), + ( + re.compile(r"^policy-map\s+type\s+inspect\s+dns\s+(\S+)$", re.IGNORECASE), + _handle_dns_inspect_policy_map_block, + ), + (re.compile(r"^policy-map\s+(\S+)$", re.IGNORECASE), _handle_policy_map_block), + (re.compile(r"^service-policy\s+(\S+)\s+(global|interface\s+\S+)$", re.IGNORECASE), _handle_service_policy), + ] + + i = 0 + while i < len(lines): + line = lines[i].strip() + + if not line or line == "!": + i += 1 + continue + + handled = False + for pattern, handler in handlers: + match = pattern.match(line) + if match: + i = handler(match, line, lines, i, state) + handled = True + break + + if not handled: + _handle_additional_settings(line, state) + i += 1 + + return _build_config(state) + + +class _ParserState: + def __init__(self): + self.asa_version = "" + self.hostname = "" + self.enable_password: AsaEnablePassword | None = None + self.service_modules: list[AsaServiceModule] = [] + self.names: list[Names] = [] + self.interfaces: list[Interface] = [] + self.net_objects: list[AsaNetworkObject] = [] + self.net_obj_groups: list[AsaNetworkObjectGroup] = [] + self.svc_objects: list[AsaServiceObject] = [] + self.svc_obj_groups: list[AsaServiceObjectGroup] = [] + self.access_lists_map: dict[str, list[AccessListEntry]] = {} + self.access_groups: list[AccessGroupBinding] = [] + self.nat_rules: list[NatRule] = [] + self.routes: list[Route] = [] + self.mgmt_access: list[MgmtAccessRule] = [] + self.additional_settings: list[str] = [] + self.class_maps: list[ClassMap] = [] + self.policy_maps: dict[str, PolicyMap] = {} + self.service_policies: list[ServicePolicyBinding] = [] + self.protocol_groups: list[AsaProtocolGroup] = [] + + +def _handle_asa_version(match: re.Match[str], _line: str, _lines: list[str], i: int, state: _ParserState) -> int: + state.asa_version = match.group(1).strip() + return i + 1 + + +def _handle_hostname(match: re.Match[str], _line: str, _lines: list[str], i: int, state: _ParserState) -> int: + state.hostname = match.group(1) + return i + 1 + + +def _handle_enable_password(match: re.Match[str], _line: str, _lines: list[str], i: int, state: _ParserState) -> int: + state.enable_password = AsaEnablePassword(password=match.group(1), encryption_function=match.group(2)) + return i + 1 + + +def _handle_service_module_timeout( + match: re.Match[str], _line: str, lines: list[str], i: int, state: _ParserState +) -> int: + name = match.group(1) + timeout = int(match.group(2)) + keepalive_counter = _find_keepalive_counter(lines, i, name) + state.service_modules.append( + AsaServiceModule(name=name, keepalive_timeout=timeout, keepalive_counter=keepalive_counter) + ) + return i + 1 + + +def _find_keepalive_counter(lines: list[str], i: int, name: str) -> int: + for j in range(i + 1, min(i + 5, len(lines))): + m = re.match( + rf"^service-module\s+{re.escape(name)}\s+keepalive-counter\s+(\d+)$", lines[j].strip(), re.IGNORECASE + ) + if m: + return int(m.group(1)) + return 0 + + +def _handle_service_module_counter( + _match: re.Match[str], _line: str, _lines: list[str], i: int, _state: _ParserState +) -> int: + return i + 1 + + +def _handle_name(match: re.Match[str], line: str, _lines: list[str], i: int, state: _ParserState) -> int: + ip, alias = match.group(1), match.group(2) + desc = line[match.end() :].strip() or None + state.names.append(Names(name=alias, ip_address=ip, description=desc)) + return i + 1 + + +def _handle_interface_block(_match: re.Match[str], _line: str, lines: list[str], i: int, state: _ParserState) -> int: + block, new_i = consume_block(lines, i) + state.interfaces.append(parse_interface_block(block)) + return new_i + + +def _handle_network_object_block( + _match: re.Match[str], _line: str, lines: list[str], i: int, state: _ParserState +) -> int: + block, new_i = consume_block(lines, i) + net_obj, pending_nat = parse_network_object_block(block) + if net_obj: + state.net_objects.append(net_obj) + if pending_nat: + state.nat_rules.append(pending_nat) + return new_i + + +def _handle_network_object_group_block( + _match: re.Match[str], _line: str, lines: list[str], i: int, state: _ParserState +) -> int: + block, new_i = consume_block(lines, i) + state.net_obj_groups.append(parse_network_object_group_block(block)) + return new_i + + +def _handle_service_object_block( + _match: re.Match[str], _line: str, lines: list[str], i: int, state: _ParserState +) -> int: + block, new_i = consume_block(lines, i) + svc_obj = parse_service_object_block(block) + if svc_obj: + state.svc_objects.append(svc_obj) + return new_i + + +def _handle_service_object_group( + _match: re.Match[str], _line: str, lines: list[str], i: int, state: _ParserState +) -> int: + block, new_i = consume_block(lines, i) + state.svc_obj_groups.append(parse_service_object_group_block(block)) + return new_i + + +def _handle_icmp_object_group_block( + _match: re.Match[str], _line: str, lines: list[str], i: int, state: _ParserState +) -> int: + block, new_i = consume_block(lines, i) + state.svc_obj_groups.append(parse_icmp_object_group_block(block)) + return new_i + + +def _handle_protocol_object_group_block( + _match: re.Match[str], _line: str, lines: list[str], i: int, state: _ParserState +) -> int: + block, new_i = consume_block(lines, i) + state.protocol_groups.append(parse_protocol_object_group_block(block)) + return new_i + + +def _handle_access_list_entry(_match: re.Match[str], line: str, _lines: list[str], i: int, state: _ParserState) -> int: + try: + entry = parse_access_list_entry(line, state.protocol_groups, state.svc_objects, state.svc_obj_groups) + state.access_lists_map.setdefault(entry.acl_name, []).append(entry) + except Exception: + FWOLogger.warning(f"Failed to parse access-list entry: {line}") + return i + 1 + + +def _handle_access_group(match: re.Match[str], _line: str, _lines: list[str], i: int, state: _ParserState) -> int: + direction = match.group(2) + if direction not in ("in", "out"): + raise ValueError(f"Invalid direction value: {direction}") + state.access_groups.append( + AccessGroupBinding(acl_name=match.group(1), direction=direction, interface=match.group(3)) + ) + return i + 1 + + +def _handle_route(match: re.Match[str], _line: str, _lines: list[str], i: int, state: _ParserState) -> int: + state.routes.append( + Route( + interface=match.group(1), + destination=match.group(2), + netmask=match.group(3), + next_hop=match.group(4), + distance=int(match.group(5)) if match.group(5) else None, + ) + ) + return i + 1 + + +def _handle_mgmt_access(match: re.Match[str], _line: str, _lines: list[str], i: int, state: _ParserState) -> int: + protocol_str = match.group(1).lower() + if protocol_str not in ("http", "ssh", "telnet"): + raise ValueError(f"Invalid protocol for MgmtAccessRule: {protocol_str}") + state.mgmt_access.append( + MgmtAccessRule( + protocol=protocol_str, source_ip=match.group(2), source_mask=match.group(3), interface=match.group(4) + ) + ) + return i + 1 + + +def _handle_class_map_block(_match: re.Match[str], _line: str, lines: list[str], i: int, state: _ParserState) -> int: + block, new_i = consume_block(lines, i) + state.class_maps.append(parse_class_map_block(block)) + return new_i + + +def _handle_dns_inspect_policy_map_block( + match: re.Match[str], _line: str, lines: list[str], i: int, state: _ParserState +) -> int: + block, new_i = consume_block(lines, i) + pm_name = match.group(1) + pm = parse_dns_inspect_policy_map_block(block, pm_name) + state.policy_maps[pm_name] = pm + return new_i + + +def _handle_policy_map_block(match: re.Match[str], _line: str, lines: list[str], i: int, state: _ParserState) -> int: + block, new_i = consume_block(lines, i) + pm_name = match.group(1) + pm = parse_policy_map_block(block, pm_name) + state.policy_maps[pm_name] = pm + return new_i + + +def _handle_service_policy(match: re.Match[str], _line: str, _lines: list[str], i: int, state: _ParserState) -> int: + pm_name = match.group(1) + scope_part = match.group(2).lower() + if scope_part == "global": + state.service_policies.append(ServicePolicyBinding(policy_map=pm_name, scope="global")) + else: + iface = scope_part.split()[1] + state.service_policies.append(ServicePolicyBinding(policy_map=pm_name, scope="interface", interface=iface)) + return i + 1 + + +def _handle_additional_settings(line: str, state: _ParserState) -> None: + interesting_prefixes = ( + "ftp mode", + "same-security-traffic", + "dynamic-access-policy-record", + "service-policy", + "user-identity", + "aaa ", + "icmp ", + "arp ", + "ssh version", + "no ssh", + "ssh cipher", + "ssh key-exchange", + "ssh timeout", + "http server enable", + "no asdm", + "asdm ", + "crypto ", + "threat-detection", + "ssl cipher", + ) + for pref in interesting_prefixes: + if line.startswith(pref): + state.additional_settings.append(line) + break + + +def _build_config(state: _ParserState) -> Config: + access_lists = [AccessList(name=name, entries=entries) for name, entries in state.access_lists_map.items()] + + return Config( + asa_version=state.asa_version or "unknown", + hostname=state.hostname or "unknown", + enable_password=state.enable_password or AsaEnablePassword(password="", encryption_function=""), + service_modules=state.service_modules, + additional_settings=state.additional_settings, + interfaces=state.interfaces, + objects=state.net_objects, + object_groups=state.net_obj_groups, + service_objects=state.svc_objects, + service_object_groups=state.svc_obj_groups, + access_lists=access_lists, + access_group_bindings=state.access_groups, + nat_rules=state.nat_rules, + routes=state.routes, + mgmt_access=state.mgmt_access, + names=state.names, + class_maps=state.class_maps, + policy_maps=list(state.policy_maps.values()), + service_policies=state.service_policies, + protocol_groups=state.protocol_groups, + ) + + +# ───────────────────────── Example usage ───────────────────────── +if __name__ == "__main__": + cfg_file = Path("ciscoasa9/asa.conf") + + with cfg_file.open("r", encoding="utf-8") as f: + text = f.read() + + config = parse_asa_config(text) + + # You can dump the entire parsed config as JSON + FWOLogger.debug(json.dumps(config.model_dump(exclude_none=True)["names"], indent=2)) diff --git a/roles/importer/files/importer/fw_modules/ciscoasa9/asa_parser_functions.py b/roles/importer/files/importer/fw_modules/ciscoasa9/asa_parser_functions.py new file mode 100644 index 0000000000..ec979d55c7 --- /dev/null +++ b/roles/importer/files/importer/fw_modules/ciscoasa9/asa_parser_functions.py @@ -0,0 +1,696 @@ +import re + +from fw_modules.ciscoasa9.asa_models import ( + AccessListEntry, + AsaNetworkObject, + AsaNetworkObjectGroup, + AsaNetworkObjectGroupMember, + AsaProtocolGroup, + AsaServiceObject, + AsaServiceObjectGroup, + ClassMap, + DnsInspectParameters, + EndpointKind, + InspectionAction, + Interface, + NatRule, + PolicyClass, + PolicyMap, +) +from fwo_log import FWOLogger + + +def clean_lines(text: str) -> list[str]: + lines: list[str] = [] + for raw in text.splitlines(): + line = raw.rstrip() + # Skip leading metadata/comment lines starting with ':' (as in "show run") + if line.strip().startswith(":"): + continue + lines.append(line) + return lines + + +def consume_block(lines: list[str], start_idx: int) -> tuple[list[str], int]: + """ + Consume a block that starts at start_idx (matching start_re) and continues + until next top-level directive (blank line or line not starting with space) + or a '!' separator. Returns (block_lines, next_index). + """ + block = [lines[start_idx]] + i = start_idx + 1 + while i < len(lines): + line = lines[i] + if line.strip() == "!": + i += 1 + break + if line.startswith(" "): # continuation/indented + block.append(line) + i += 1 + continue + # another directive starts; end this block + break + return block, i + + +def parse_endpoint(tokens: list[str]) -> tuple[EndpointKind, int]: + """ + Parse an ACL endpoint from tokens; returns (EndpointKind, tokens_consumed). + Supported: + any + host A.B.C.D + object NAME + object-group NAME + A.B.C.D MASK + """ + if not tokens: + return EndpointKind(kind="any", value="any"), 0 + + t0 = tokens[0] + if t0 == "any": + return EndpointKind(kind="any", value="any"), 1 + if t0 == "host" and len(tokens) >= 2: # noqa: PLR2004 + return EndpointKind(kind="host", value=tokens[1]), 2 + if t0 == "object" and len(tokens) >= 2: # noqa: PLR2004 + return EndpointKind(kind="object", value=tokens[1]), 2 + if t0 == "object-group" and len(tokens) >= 2: # noqa: PLR2004 + return EndpointKind(kind="object-group", value=tokens[1]), 2 + # subnet notation: ip + mask + if ( + len(tokens) >= 2 # noqa: PLR2004 + and re.fullmatch(r"\d{1,3}(?:\.\d{1,3}){3}", tokens[0]) + and re.fullmatch(r"\d{1,3}(?:\.\d{1,3}){3}", tokens[1]) + ): + return EndpointKind(kind="subnet", value=tokens[0], mask=tokens[1]), 2 + # fallback + return EndpointKind(kind="any", value="any"), 1 + + +def _find_description(blocks: list[str]) -> str | None: + """Helper to find description line in a block.""" + return _find_line_with_prefix(list(blocks), "description ") + + +def _find_line_with_prefix(block: list[str], prefix: str, only_first: bool = False) -> str | None: + """Helper to find a single value in an interface block by prefix.""" + v = None + for b in list(block): + s = b.strip() + if s.startswith(prefix): + v = s.split()[1] if only_first else s[len(prefix) :].strip() + block.remove(b) + return v + + +def _parse_interface_block_find_ip_address(block: list[str], prefix: str) -> tuple[str | None, str | None]: + """Helper to find IP address and mask in an interface block.""" + ip = None + mask = None + for b in list(block): + s = b.strip() + if s.startswith(prefix): + parts = s.split() + if len(parts) >= 4: # noqa: PLR2004 + is_valid_ip = parts[2].count(".") == 3 and parts[3].count(".") == 3 # noqa: PLR2004 + if is_valid_ip: + ip, mask = parts[2], parts[3] + block.remove(b) + return ip, mask + + +def parse_interface_block(block: list[str]) -> Interface: + """Parse an interface block and return an Interface object.""" + if_name = block[0].split()[1] + blocks = list(block)[1:] + + # Extract values and remove consumed lines from blocks + nameif = _find_line_with_prefix(blocks, "nameif ", only_first=True) + br = _find_line_with_prefix(blocks, "bridge-group ", only_first=True) + sec = _find_line_with_prefix(blocks, "security-level ", only_first=True) + sec = int(sec) if sec is not None else 0 + ip, mask = _parse_interface_block_find_ip_address(blocks, "ip address ") + desc = _find_line_with_prefix(blocks, "description ") + # All non-consumed lines remain in blocks as additional + + # Defaults for missing bits + nameif = nameif or if_name + + return Interface( + name=if_name, + nameif=nameif, + bridge_group=br, + security_level=sec, + ip_address=ip, + subnet_mask=mask, + additional_settings=blocks, + description=desc, + ) + + +def _create_network_object_from_parts( + name: str, + host: str | None, + subnet: str | None, + mask: str | None, + ip_range: tuple[str, str] | None, + fqdn: str | None, + description: str | None, +) -> AsaNetworkObject | None: + """Helper to create AsaNetworkObject from parts.""" + if host and not subnet: + return AsaNetworkObject( + name=name, ip_address=host, ip_address_end=None, subnet_mask=None, fqdn=None, description=description + ) + if subnet: + return AsaNetworkObject( + name=name, ip_address=subnet, ip_address_end=None, subnet_mask=mask, fqdn=None, description=description + ) + if ip_range: + return AsaNetworkObject( + name=name, + ip_address=ip_range[0], + ip_address_end=ip_range[1], + subnet_mask=None, + fqdn=None, + description=description, + ) + if fqdn: + return AsaNetworkObject( + name=name, ip_address="", ip_address_end=None, subnet_mask=None, fqdn=fqdn, description=description + ) + + FWOLogger.warning(f"Cannot create network object {name}: no valid address information provided. NAT object?") + return None + + +def parse_network_object_block(block: list[str]) -> tuple[AsaNetworkObject | None, NatRule | None]: + """Parse an object network block. Returns (network_object, nat_rule).""" + obj_name = block[0].split()[2] + host = None + ip_range = None + subnet = None + mask = None + fqdn = None + desc = _find_description(block[1:]) + pending_nat = None + + for b in block[1:]: + s = b.strip() + mhost = re.match(r"^host\s+(\S+)$", s, re.IGNORECASE) + msub = re.match(r"^subnet\s+(\S+)\s+(\S+)$", s, re.IGNORECASE) + mrange = re.match(r"^range\s+(\S+)\s+(\S+)$", s, re.IGNORECASE) + mfqdn = re.match(r"^fqdn\s+v4\s+(\S+)$", s, re.IGNORECASE) + mnat = re.match(r"^nat\s+\(([^,]+),([^)]+)\)\s+(dynamic|static)\s+(\S+)$", s, re.IGNORECASE) + + if mhost: + host = mhost.group(1) + elif msub: + subnet, mask = msub.group(1), msub.group(2) + elif mrange: + ip_range = mrange.group(1), mrange.group(2) + elif mfqdn: + fqdn = mfqdn.group(1) + elif mnat: + src_if = mnat.group(1).strip() + dst_if = mnat.group(2).strip() + ntype = mnat.group(3).lower() + tobj = mnat.group(4).lower() + if ntype == "dynamic": + nat_type = "dynamic" + elif ntype == "static": + nat_type = "static" + else: + raise ValueError(f"Unsupported NAT type in line: {s}") + pending_nat = NatRule( + object_name=obj_name, + src_if=src_if, + dst_if=dst_if, + nat_type=nat_type, + translated_object=(None if tobj == "interface" else tobj), + ) + + # Create network object if we have host/subnet/fqdn + net_obj = _create_network_object_from_parts( + name=obj_name, + host=host, + subnet=subnet, + mask=mask, + ip_range=ip_range, + fqdn=fqdn, + description=desc, + ) + + return net_obj, pending_nat + + +def parse_network_object_group_block(block: list[str]) -> AsaNetworkObjectGroup: + """Parse an object-group network block.""" + grp_name = block[0].split()[2] + desc = _find_description(block[1:]) + members: list[AsaNetworkObjectGroupMember] = [] + + for b in block[1:]: + s = b.strip() + mobj = re.match(r"^network-object\s+object\s+(\S+)$", s, re.IGNORECASE) + mhost = re.match(r"^network-object\s+host\s+(\d+\.\d+\.\d+\.\d+)$", s, re.IGNORECASE) + mhostv6 = re.match(r"^network-object\s+host\s+(\S+)$", s, re.IGNORECASE) # e.g. 2001:db8:abcd::1 + msub = re.match(r"^network-object\s+(\d+\.\d+\.\d+\.\d+)\s+(\d+\.\d+\.\d+\.\d+)$", s, re.IGNORECASE) + msubv6 = re.match(r"^network-object\s+(\S+)$", s, re.IGNORECASE) # e.g. 2001:db8:abcd::/40 or 2001::/12 + mgroup = re.match(r"^group-object\s+(\S+)$", s, re.IGNORECASE) + + if mobj: + ref = mobj.group(1) + members.append(AsaNetworkObjectGroupMember(kind="object", value=ref)) + elif mhost: + ip = mhost.group(1) + members.append(AsaNetworkObjectGroupMember(kind="host", value=ip)) + elif mhostv6: + ip = mhostv6.group(1) + members.append(AsaNetworkObjectGroupMember(kind="hostv6", value=ip)) + elif msub: + ip = msub.group(1) + mask = msub.group(2) + members.append(AsaNetworkObjectGroupMember(kind="subnet", value=ip, mask=mask)) + elif msubv6: + ip = msubv6.group(1) + members.append(AsaNetworkObjectGroupMember(kind="subnetv6", value=ip)) + elif mgroup: + ref = mgroup.group(1) + members.append(AsaNetworkObjectGroupMember(kind="object-group", value=ref)) + + return AsaNetworkObjectGroup(name=grp_name, objects=members, description=desc) + + +def parse_service_object_block(block: list[str]) -> AsaServiceObject | None: + """Parse an object service block.""" + name = block[0].split()[2] + protocol = None + eq = None + prange = None + desc = _find_description(block[1:]) + + for b in block[1:]: + s = b.strip() + # e.g., "service tcp destination eq 1234" + meq = re.match(r"^service\s+(tcp|udp|ip)\s+destination\s+eq\s+(\S+)$", s, re.IGNORECASE) + mrange = re.match(r"^service\s+(tcp|udp|ip)\s+destination\s+range\s+(\S+)\s+(\S+)$", s, re.IGNORECASE) + micmp = re.match(r"^service\s+icmp.*$", s, re.IGNORECASE) + msvc = re.match(r"^service\s+(\S+)$", s, re.IGNORECASE) + + if meq: + protocol = meq.group(1).lower() + eq = meq.group(2) + elif mrange: + protocol = mrange.group(1).lower() + prange = (mrange.group(2), mrange.group(3)) + elif micmp: + protocol = "icmp" + elif msvc: + protocol = msvc.group(1).lower() + + if protocol is None or protocol not in ("tcp", "udp", "ip", "icmp", "gre"): + FWOLogger.warning(f"Unsupported or missing protocol {protocol} in service object {name}") + return None # unsupported protocol + + return AsaServiceObject(name=name, protocol=protocol, dst_port_eq=eq, dst_port_range=prange, description=desc) + + +def _convert_ports_to_dicts( + ports_eq: list[tuple[str, str]], ports_range: list[tuple[str, tuple[str, str]]] +) -> tuple[dict[str, list[str]], dict[str, list[tuple[str, str]]]]: + """ + Convert port lists to dictionaries grouped by protocol. + Returns (ports_eq_dict, ports_range_dict). + """ + ports_eq_dict: dict[str, list[str]] = {} + for proto, port in ports_eq: + if proto not in ports_eq_dict: + ports_eq_dict[proto] = [] + ports_eq_dict[proto].append(port) + + ports_range_dict: dict[str, list[tuple[str, str]]] = {} + for proto, prange in ports_range: + if proto not in ports_range_dict: + ports_range_dict[proto] = [] + ports_range_dict[proto].append(prange) + + return ports_eq_dict, ports_range_dict + + +def _consume_port_objects( + service_group_block: list[str], proto_mode: str +) -> tuple[list[tuple[str, str]], list[tuple[str, tuple[str, str]]]]: + """Helper to consume port-object lines from a service object group block.""" + ports_eq: list[tuple[str, str]] = [] + ports_range: list[tuple[str, tuple[str, str]]] = [] + + for b in list(service_group_block): + s = b.strip() + mport_eq = re.match(r"^port-object\s+eq\s+(\S+)$", s, re.IGNORECASE) + mport_range = re.match(r"^port-object\s+range\s+(\d+)\s+(\d+)$", s, re.IGNORECASE) + + if mport_eq: + ports_eq.append((proto_mode, mport_eq.group(1))) + elif mport_range: + ports_range.append((proto_mode, (mport_range.group(1), mport_range.group(2)))) + else: + continue + service_group_block.remove(b) + + return ports_eq, ports_range + + +def _consume_service_definitions( + service_group_block: list[str], +) -> tuple[list[tuple[str, str]], list[tuple[str, tuple[str, str]]], list[str]]: + """Helper to consume service-object definitions from a service object group block.""" + ports_eq: list[tuple[str, str]] = [] + ports_range: list[tuple[str, tuple[str, str]]] = [] + protocols: list[str] = [] # list of fully enabled protocols + + for b in list(service_group_block): + s = b.strip() + mproto = re.match(r"^service-object\s+(tcp|udp|icmp|tcp-udp)$", s, re.IGNORECASE) + msvc_eq = re.match( + r"^service-object\s+(tcp|udp|icmp|tcp-udp)\s+(?:destination\s+)?eq\s+(\S+)$", s, re.IGNORECASE + ) + msvc_range = re.match( + r"^service-object\s+(tcp|udp|icmp|tcp-udp)\s+(?:destination\s+)?range\s+(\S+)\s+(\S+)$", s, re.IGNORECASE + ) + if mproto: + protocols.append(mproto.group(1).lower()) + elif msvc_eq: + ports_eq.append((msvc_eq.group(1).lower(), msvc_eq.group(2))) + elif msvc_range: + ports_range.append((msvc_range.group(1).lower(), (msvc_range.group(2), msvc_range.group(3)))) + else: + continue + service_group_block.remove(b) + + return ports_eq, ports_range, protocols + + +def _consume_service_references(service_group_block: list[str]) -> list[str]: + """Helper to consume service-object and group-object lines from a service object group block.""" + nested_refs: list[str] = [] + + for b in service_group_block: + s = b.strip() + mobj = re.match(r"^service-object\s+object\s+(\S+)$", s, re.IGNORECASE) + mgrp = re.match(r"^group-object\s+(\S+)$", s, re.IGNORECASE) + + if mobj: + nested_refs.append(mobj.group(1)) + elif mgrp: + nested_refs.append(mgrp.group(1)) + else: + continue + service_group_block.remove(b) + + return nested_refs + + +def parse_service_object_group_block(block: list[str]) -> AsaServiceObjectGroup: + """Parse an object-group service block.""" + hdr = block[0].split() + name = hdr[2] + + # Optional global protocol set for all defined ports/ranges + proto_mode = None + if len(hdr) >= 4: # noqa: PLR2004 + pm = hdr[3].lower() + if pm in ("tcp", "udp", "tcp-udp"): + proto_mode = pm + else: + FWOLogger.warning(f"Unsupported proto_mode '{pm}' in service object group '{name}'") + + desc = _find_description(block[1:]) + + ports_eq: list[tuple[str, str]] = [] + ports_range: list[tuple[str, tuple[str, str]]] = [] + nested_refs: list[str] = [] + protocols: list[str] = [] + + if proto_mode: + ports_eq, ports_range = _consume_port_objects(block[1:], proto_mode) + else: + ports_eq, ports_range, protocols = _consume_service_definitions(block[1:]) + nested_refs = _consume_service_references(block[1:]) + + # Convert port lists to dictionaries using helper function + ports_eq_dict, ports_range_dict = _convert_ports_to_dicts(ports_eq, ports_range) + + return AsaServiceObjectGroup( + name=name, + proto_mode=proto_mode, + ports_eq=ports_eq_dict, + ports_range=ports_range_dict, + nested_refs=nested_refs, + protocols=protocols, + description=desc, + ) + + +def parse_class_map_block(block: list[str]) -> ClassMap: + """Parse a class-map block.""" + name = block[0].split()[1] + matches: list[str] = [] + + for b in block[1:]: + s = b.strip() + mm = re.match(r"^match\s", s, re.IGNORECASE) + if mm: + matches.append(s[mm.end() :].strip()) + + return ClassMap(name=name, matches=matches) + + +def _parse_dns_parameters_block(block: list[str], start_idx: int) -> tuple[DnsInspectParameters, int]: + """ + Parse a 'parameters' sub-block within a DNS inspect policy-map. + Returns (DnsInspectParameters, next_index). + """ + params = DnsInspectParameters() + k = start_idx + 1 + while k < len(block) and block[k].startswith(" "): # double indent + t = block[k].strip() + m1 = re.match(r"^message-length\s+maximum\s+client\s+(auto|\d+)$", t, re.IGNORECASE) + m2 = re.match(r"^message-length\s+maximum\s+(\d+)$", t, re.IGNORECASE) + m3 = re.match(r"^no\s+tcp-inspection$", t, re.IGNORECASE) + + if m1: + v = m1.group(1).lower() + params.message_length_max_client = "auto" if v == "auto" else int(v) + elif m2: + params.message_length_max = int(m2.group(1)) + elif m3: + params.tcp_inspection = False + k += 1 + return params, k + + +def parse_dns_inspect_policy_map_block(block: list[str], pm_name: str) -> PolicyMap: + """Parse a policy-map type inspect dns block.""" + pm = PolicyMap(name=pm_name, type_str="inspect dns") + params = DnsInspectParameters() + + j = 1 + while j < len(block): + s = block[j].strip() + if s == "parameters": + params, j = _parse_dns_parameters_block(block, j) + continue + j += 1 + + pm.parameters_dns = params + return pm + + +def _parse_policy_class_block(block: list[str], start_idx: int) -> tuple[PolicyClass | None, int]: + """ + Parse a 'class ' sub-block starting at start_idx. + Returns (PolicyClass or None, next_index). + """ + if start_idx >= len(block): + return None, start_idx + 1 + + header = block[start_idx].strip() + mc = re.match(r"^class\s+(\S+)$", header, re.IGNORECASE) + if not mc: + return None, start_idx + 1 + + class_name = mc.group(1) + inspections: list[InspectionAction] = [] + idx = start_idx + 1 + # collect lines under this class (1 indent) + while idx < len(block) and block[idx].startswith(" "): + t = block[idx].strip() + mi = re.match(r"^inspect\s+(\S+)(?:\s+(\S+))?$", t, re.IGNORECASE) + if mi: + inspections.append(InspectionAction(protocol=mi.group(1).lower(), policy_map=(mi.group(2) or None))) + # ignore other class-level lines for now + idx += 1 + + return PolicyClass(class_name=class_name, inspections=inspections), idx + + +def parse_policy_map_block(block: list[str], pm_name: str) -> PolicyMap: + """Parse a regular policy-map block.""" + pm = PolicyMap(name=pm_name) + + idx = 1 + while idx < len(block): + cls, next_idx = _parse_policy_class_block(block, idx) + if cls is not None: + pm.classes.append(cls) + idx = next_idx + + return pm + + +def _parse_access_list_entry_protocol( + parts: list[str], + protocol_groups: list[AsaProtocolGroup], + svc_objects: list[AsaServiceObject], + svc_obj_groups: list[AsaServiceObjectGroup], +) -> tuple[EndpointKind, list[str]]: + """ + Parse the protocol part of an access-list entry. + Returns (protocol EndpointKind, remaining tokens list[str]). + """ + # Determine protocol + protocol = None + tokens = [] # Ensure tokens is always initialized + if parts[4] == "object-group": + group_name = parts[5] + if any(group.name == group_name for group in protocol_groups): + protocol = EndpointKind(kind="protocol-group", value=group_name) + elif any(group.name == group_name for group in svc_obj_groups): + protocol = EndpointKind(kind="service-group", value=group_name) + else: + raise ValueError(f"Unknown object-group: {group_name}") + tokens = parts[6:] + elif parts[4] == "object": + obj_name = parts[5] + if any(obj.name == obj_name for obj in svc_objects): + protocol = EndpointKind(kind="service", value=obj_name) + else: + raise ValueError(f"Unknown service object: {obj_name}") + tokens = parts[6:] + else: + protocol = EndpointKind(kind="protocol", value=parts[4].lower()) + tokens = parts[5:] + + return protocol, tokens + + +def _parse_access_list_entry_dest_port(tokens: list[str], protocol: EndpointKind) -> tuple[EndpointKind, list[str]]: + """ + Parse the destination port part of an access-list entry. + Returns (dst_port EndpointKind, remaining tokens list[str]). + """ + dst_port = EndpointKind(kind="any", value="any") # Default value + if len(tokens) >= 2 and tokens[0] == "eq": # noqa: PLR2004 + dst_port = EndpointKind(kind="eq", value=tokens[1]) + tokens = tokens[2:] + elif len(tokens) >= 3 and tokens[0] == "range": # noqa: PLR2004 + dst_port = EndpointKind(kind="range", value=f"{tokens[1]} {tokens[2]}") + tokens = tokens[3:] + elif len(tokens) >= 2 and tokens[0] == "object-group": # noqa: PLR2004 + dst_port = EndpointKind(kind="service-group", value=tokens[1]) + tokens = tokens[2:] + elif len(tokens) >= 2 and tokens[0] == "object": # noqa: PLR2004 + dst_port = EndpointKind(kind="service", value=tokens[1]) + tokens = tokens[2:] + + # If protocol is a service-group and dst_port is empty, set dst_port to the group name + if protocol.kind == "service-group" and dst_port.value == "any": + dst_port = EndpointKind(kind="service-group", value=protocol.value) + elif protocol.kind == "service" and dst_port.value == "any": + dst_port = EndpointKind(kind="service", value=protocol.value) + + return dst_port, tokens + + +def parse_access_list_entry( + line: str, + protocol_groups: list[AsaProtocolGroup], + svc_objects: list[AsaServiceObject], + svc_obj_groups: list[AsaServiceObjectGroup], +) -> AccessListEntry: + """ + Parse an access-list entry line and return an AccessListEntry object. + Handles various formats as specified in the requirements. + """ + # Tokenize the line after 'access-list' + parts = line.split() + acl_name = parts[1] # Access list name + action = parts[3].lower() # Action (permit/deny) + + # Parse protocol or protocol/service object-group + protocol, tokens = _parse_access_list_entry_protocol(parts, protocol_groups, svc_objects, svc_obj_groups) + + # Parse source endpoint + src, consumed = parse_endpoint(tokens) + tokens = tokens[consumed:] + + # Parse destination endpoint + dst, consumed = parse_endpoint(tokens) + tokens = tokens[consumed:] + + # Parse destination port + dst_port, tokens = _parse_access_list_entry_dest_port(tokens, protocol) + + # Optional inactive flag + inactive = "inactive" in tokens + + # Ensure action is either 'permit' or 'deny' for type safety + action_literal = "permit" if action == "permit" else "deny" + + return AccessListEntry( + acl_name=acl_name, + action=action_literal, + protocol=protocol, + src=src, + dst=dst, + dst_port=dst_port, + inactive=inactive, + ) + + +def parse_protocol_object_group_block(block: list[str]) -> AsaProtocolGroup: + """Parse an object-group protocol block.""" + name = block[0].split()[2] + desc = _find_description(block[1:]) + protocols: list[str] = [] + + for b in block[1:]: + s = b.strip() + mproto = re.match(r"^protocol-object\s+(\S+)$", s, re.IGNORECASE) + + if mproto: + protocols.append(mproto.group(1)) + + return AsaProtocolGroup(name=name, protocols=protocols, description=desc) + + +def parse_icmp_object_group_block(block: list[str]) -> AsaServiceObjectGroup: + """Parse an object-group icmp-type block.""" + grp_name = block[0].split()[2] + desc = _find_description(block[1:]) + objects: list[str] = [] + for b in block[1:]: + s = b.strip() + mobj = re.match(r"^icmp-object\s+(\S+)$", s, re.IGNORECASE) + if mobj: + objects.append(mobj.group(1)) + + return AsaServiceObjectGroup( + name=grp_name, + proto_mode=None, + ports_eq={"icmp": objects}, + ports_range={}, + nested_refs=[], + protocols=[], + description=desc, + ) diff --git a/roles/importer/files/importer/fw_modules/ciscoasa9/asa_rule.py b/roles/importer/files/importer/fw_modules/ciscoasa9/asa_rule.py new file mode 100644 index 0000000000..f512558585 --- /dev/null +++ b/roles/importer/files/importer/fw_modules/ciscoasa9/asa_rule.py @@ -0,0 +1,205 @@ +""" +ASA Rule and Rulebase Management + +This module handles the creation of rules and rulebases from ASA access lists. +It processes ACL entries and converts them into normalized rules with proper +service, source, and destination references. +""" + +import fwo_base +from fw_modules.ciscoasa9.asa_models import AccessList, AccessListEntry, AsaProtocolGroup, EndpointKind +from fw_modules.ciscoasa9.asa_network import get_network_rule_endpoint +from fw_modules.ciscoasa9.asa_service import create_any_protocol_service, create_service_for_acl_entry +from fwo_log import FWOLogger +from models.networkobject import NetworkObject +from models.rule import RuleAction, RuleNormalized, RuleTrack, RuleType +from models.rulebase import Rulebase +from models.serviceobject import ServiceObject +from netaddr import IPNetwork + + +def create_service_for_protocol_group_entry( + protocol_group_name: str, protocol_groups: list[AsaProtocolGroup], service_objects: dict[str, ServiceObject] +) -> str: + """ + Resolve service reference for a protocol group. + + Args: + protocol_group_name: Name of the protocol group + protocol_groups: List of protocol groups for resolving references + service_objects: Dictionary of service objects to update if needed + Returns: + Service reference string + + """ + allowed_protocols = [] + for pg in protocol_groups: + if pg.name == protocol_group_name: + allowed_protocols = pg.protocols + break + + if allowed_protocols: + svc_refs: list[str] = [] + for proto in allowed_protocols: + svc_ref = create_any_protocol_service(proto, service_objects) + svc_refs.append(svc_ref) + return fwo_base.sort_and_join(svc_refs) + # Fallback if protocol group not found + FWOLogger.warning(f"Protocol group '{protocol_group_name}' not found. Defaulting to tcp/udp/icmp any.") + svc_refs = [] + for proto in ("tcp", "udp", "icmp"): + svc_refs.append(create_any_protocol_service(proto, service_objects)) + return fwo_base.sort_and_join(svc_refs) + + +def resolve_service_reference_for_rule( + entry: AccessListEntry, protocol_groups: list[AsaProtocolGroup], service_objects: dict[str, ServiceObject] +) -> str: + """ + Resolve service reference for a rule entry. + + Args: + entry: Access list entry + protocol_groups: List of protocol groups for resolving protocol-group references + service_objects: Dictionary of service objects to update if needed + + Returns: + Service reference string + + """ + if entry.protocol.kind == "protocol-group": + # Protocol group - resolve to list of protocols + return create_service_for_protocol_group_entry(entry.protocol.value, protocol_groups, service_objects) + # Handle other protocol types using existing function + return create_service_for_acl_entry(entry, service_objects) + + +def resolve_network_reference_for_rule(endpoint: EndpointKind, network_objects: dict[str, NetworkObject]) -> str: + """ + Resolve network reference for a rule endpoint. + + Args: + endpoint: Access list entry endpoint (src or dst) + network_objects: Dictionary of network objects to update if needed + + Returns: + Network reference string + + """ + # Create network object if needed and get reference + network_obj = get_network_rule_endpoint(endpoint, network_objects) + + # Return reference - convert subnet mask to CIDR if present + if hasattr(endpoint, "mask") and endpoint.mask is not None: + return str(IPNetwork(f"{endpoint.value}/{endpoint.mask}")) + return network_obj.obj_uid + + +def create_rule_from_acl_entry( + access_list_name: str, + entry: AccessListEntry, + protocol_groups: list[AsaProtocolGroup], + network_objects: dict[str, NetworkObject], + service_objects: dict[str, ServiceObject], +) -> RuleNormalized: + """ + Create a normalized rule from an ACL entry. + + Args: + access_list_name: Name of the access list + idx: Rule index (1-based) + entry: Access list entry to convert + protocol_groups: List of protocol groups for resolving references + network_objects: Dictionary of network objects to update if needed + service_objects: Dictionary of service objects to update if needed + + Returns: + Normalized rule object + + """ + # Generate unique rule UID by hashing entry dict + rule_uid = fwo_base.generate_hash_from_dict(entry.model_dump()) + + # Resolve service reference + svc_ref = resolve_service_reference_for_rule(entry, protocol_groups, service_objects) + + # Resolve source and destination references + src_ref = resolve_network_reference_for_rule(entry.src, network_objects) + dst_ref = resolve_network_reference_for_rule(entry.dst, network_objects) + + # Create normalized rule + return RuleNormalized( + rule_num=0, + rule_num_numeric=0, # will be set later + rule_disabled=entry.inactive, + rule_src_neg=False, + rule_src=src_ref, + rule_src_refs=src_ref, + rule_dst_neg=False, + rule_dst=dst_ref, + rule_dst_refs=dst_ref, + rule_svc_neg=False, + rule_svc=svc_ref, + rule_svc_refs=svc_ref, + rule_action=RuleAction.ACCEPT if entry.action == "permit" else RuleAction.DROP, + rule_track=RuleTrack.NONE, + rule_installon=None, # gateway_uid, TODO: commented out for now to avoid duplication issues + rule_time=None, + rule_name=access_list_name, + rule_uid=rule_uid, + rule_custom_fields=None, + rule_implied=False, + rule_type=RuleType.ACCESS, + last_change_admin=None, + parent_rule_uid=None, + last_hit=None, + rule_comment=entry.description, + rule_src_zone=None, + rule_dst_zone=None, + rule_head_text=None, + ) + + +def build_rulebases_from_access_lists( + access_lists: list[AccessList], + mgm_uid: str, + protocol_groups: list[AsaProtocolGroup], + network_objects: dict[str, NetworkObject], + service_objects: dict[str, ServiceObject], +) -> list[Rulebase]: + """ + Build rulebases from ASA access lists. + + Each access list becomes a separate rulebase containing normalized rules. + Rules are created from ACL entries with proper service, source, and destination references. + + Args: + access_lists: List of parsed ASA access lists + mgm_uid: Management UID for the device + protocol_groups: List of protocol groups for resolving protocol-group references + network_objects: Dictionary of network objects to update if needed + service_objects: Dictionary of service objects to update if needed + + Returns: + List of normalized rulebases + + """ + rulebases: list[Rulebase] = [] + + for access_list in access_lists: + rules: dict[str, RuleNormalized] = {} + + for entry in access_list.entries: + rule = create_rule_from_acl_entry( + access_list.name, entry, protocol_groups, network_objects, service_objects + ) + if rule.rule_uid is None: + FWOLogger.error(f"Failed to create rule UID for ACL entry: {entry}") + raise ValueError("Rule UID generation failed.") + rules[rule.rule_uid] = rule + + # Create rulebase for this access list + rulebase = Rulebase(uid=access_list.name, name=access_list.name, mgm_uid=mgm_uid, is_global=False, rules=rules) + rulebases.append(rulebase) + + return rulebases diff --git a/roles/importer/files/importer/fw_modules/ciscoasa9/asa_service.py b/roles/importer/files/importer/fw_modules/ciscoasa9/asa_service.py new file mode 100644 index 0000000000..ee3fff906b --- /dev/null +++ b/roles/importer/files/importer/fw_modules/ciscoasa9/asa_service.py @@ -0,0 +1,481 @@ +""" +ASA Service Object Management + +This module handles the creation and normalization of service objects from ASA configurations. +It manages both explicit service objects/groups and implicit service objects created from +inline ACL definitions. +""" + +import fwo_base +import fwo_const +from fw_modules.ciscoasa9.asa_maps import name_to_port, protocol_map +from fw_modules.ciscoasa9.asa_models import AccessListEntry, AsaServiceObject, AsaServiceObjectGroup +from fwo_log import FWOLogger +from models.serviceobject import ServiceObject + + +def create_service_object( + name: str, port: int, port_end: int, protocol: str, comment: str | None = None +) -> ServiceObject: + """ + Create a normalized service object. + + Args: + name: Service object name/UID + port: Start port number + port_end: End port number + protocol: Protocol name (tcp, udp, icmp, etc.) + comment: Optional description + + Returns: + Normalized ServiceObject instance + + """ + return ServiceObject( + svc_uid=name, + svc_name=name, + svc_port=port, + svc_port_end=port_end, + svc_color=fwo_const.DEFAULT_COLOR, + svc_typ="simple", + ip_proto=protocol_map.get(protocol, 0), + svc_comment=comment, + ) + + +def create_protocol_service_object(name: str, protocol: str, comment: str | None = None) -> ServiceObject: + """ + Create a service object for a protocol without specific ports. + + Args: + name: Service object name/UID + protocol: Protocol name + comment: Optional description + + Returns: + Normalized ServiceObject instance + + """ + return ServiceObject( + svc_uid=name, + svc_name=name, + svc_color=fwo_const.DEFAULT_COLOR, + svc_typ="simple", + ip_proto=protocol_map.get(protocol, 0), + svc_comment=comment, + ) + + +def create_service_group_object(name: str, member_refs: list[str], comment: str | None = None) -> ServiceObject: + """ + Create a service group object. + + Args: + name: Group name/UID + member_refs: List of member service object references + comment: Optional description + + Returns: + Normalized ServiceObject group instance + + """ + return ServiceObject( + svc_uid=name, + svc_name=name, + svc_typ="group", + svc_member_names=fwo_base.sort_and_join(member_refs), + svc_member_refs=fwo_base.sort_and_join(member_refs), + svc_color=fwo_const.DEFAULT_COLOR, + svc_comment=comment, + ) + + +def normalize_service_objects(service_objects: list[AsaServiceObject]) -> dict[str, ServiceObject]: + """ + Normalize individual service objects from ASA configuration. + + Args: + service_objects: List of parsed ASA service objects + + Returns: + Dictionary of normalized service objects keyed by svc_uid + + """ + normalized: dict[str, ServiceObject] = {} + + for svc in service_objects: + if svc.dst_port_eq: + # Service with specific port (eq) + port = svc.dst_port_eq + if not port.isdigit(): + port = name_to_port[port]["port"] + + obj = create_service_object(svc.name, int(port), int(port), svc.protocol, svc.description) + normalized[svc.name] = obj + + elif svc.dst_port_range: + # Service with port range + start, end = svc.dst_port_range + if not start.isdigit(): + start = name_to_port[start]["port"] + if not end.isdigit(): + end = name_to_port[end]["port"] + obj = create_service_object(svc.name, int(start), int(end), svc.protocol, svc.description) + normalized[svc.name] = obj + + else: + # Protocol-only service (no specific ports) + obj = create_protocol_service_object(svc.name, svc.protocol, svc.description) + normalized[svc.name] = obj + + return normalized + + +def create_protocol_any_service_objects() -> dict[str, ServiceObject]: + """ + Create default 'any' service objects for common protocols. + + Returns: + Dictionary of protocol-any service objects + + """ + service_objects: dict[str, ServiceObject] = {} + + for proto in ("tcp", "udp", "icmp", "ip"): + obj_name = f"any-{proto}" + obj = ServiceObject( + svc_uid=obj_name, + svc_name=obj_name, + svc_port=0, + svc_port_end=65535, + svc_color=fwo_const.DEFAULT_COLOR, + svc_typ="simple", + ip_proto=protocol_map.get(proto, 0), + svc_comment=f"any {proto}", + ) + service_objects[obj_name] = obj + + return service_objects + + +def create_service_for_port(port: str, proto: str, service_objects: dict[str, ServiceObject]) -> str: + """ + Create a service object for a single port and protocol if it doesn't exist. + + Args: + port: Port number or name + proto: Protocol name + service_objects: Dictionary to update with new service object + + Returns: + Service object name/UID + + """ + if proto == "icmp": + obj = create_protocol_service_object(f"icmp-{port}", "icmp", None) + service_objects[obj.svc_uid] = obj + return obj.svc_uid + obj_name = f"{port}-{proto}" + if obj_name not in service_objects: + description = None + if not port.isdigit(): + description = name_to_port[port]["description"] + port = name_to_port[port]["port"] + obj = create_service_object(obj_name, int(port), int(port), proto, description) + service_objects[obj_name] = obj + return obj_name + + +def create_service_for_port_range( + port_range: tuple[str, str], proto: str, service_objects: dict[str, ServiceObject] +) -> str: + """ + Create a service object for a port range and protocol if it doesn't exist. + + Args: + port_range: Tuple of (start_port, end_port) + proto: Protocol name + service_objects: Dictionary to update with new service object + + Returns: + Service object name/UID + + """ + obj_name = ( + f"{port_range[0]}-{port_range[1]}-{proto}" if port_range[0] != port_range[1] else f"{port_range[0]}-{proto}" + ) + if obj_name not in service_objects: + start, end = port_range + description = None + if not start.isdigit(): + description = f"{start}: {name_to_port[start]['description']}" + start = name_to_port[start]["port"] + if not end.isdigit(): + if not description: + description = f"{end}: {name_to_port[end]['description']}" + else: + description += f"; {end}: {name_to_port[end]['description']}" + end = name_to_port[end]["port"] + obj = create_service_object(obj_name, int(start), int(end), proto, description) + service_objects[obj_name] = obj + return obj_name + + +def create_any_protocol_service(proto: str, service_objects: dict[str, ServiceObject]) -> str: + """ + Create an 'any' service object for a protocol if it doesn't exist. + + Args: + proto: Protocol name + service_objects: Dictionary to update with new service object + + Returns: + Service object name/UID + + """ + obj_name = f"any-{proto}" + if obj_name not in service_objects: + port_range = (0, 65535) if proto in ("tcp", "udp") else (None, None) + obj = ServiceObject( + svc_uid=obj_name, + svc_name=obj_name, + svc_port=port_range[0], + svc_port_end=port_range[1], + svc_color=fwo_const.DEFAULT_COLOR, + svc_typ="simple", + ip_proto=protocol_map.get(proto, 0), + svc_comment=f"any {proto}", + ) + service_objects[obj_name] = obj + return obj_name + + +def create_service_for_protocol_entry_with_single_protocol( + entry: AccessListEntry, service_objects: dict[str, ServiceObject] +) -> str: + """ + Create service reference for a protocol entry with set protocol. + + Args: + entry: Access list entry with protocol + service_objects: Dictionary to update with new service objects + Returns: + Service reference string (single object or delimited list) + + """ + if entry.dst_port.kind == "eq": + # Single port (e.g., 'eq 443' or 'eq https') + return create_service_for_port(entry.dst_port.value, entry.protocol.value, service_objects) + + if entry.dst_port.kind == "range": + # Port range (e.g., 'range 1024 65535') + ports = entry.dst_port.value.split() # expecting "start end" + return create_service_for_port_range((ports[0], ports[1]), entry.protocol.value, service_objects) + + if entry.dst_port.kind == "any": + # Any port for the protocol + return create_any_protocol_service(entry.protocol.value, service_objects) + + if entry.dst_port.kind in ("service", "service-group"): + # Reference to existing service object/group + return entry.dst_port.value + # Default to any port for the protocol + return create_any_protocol_service(entry.protocol.value, service_objects) + + +def create_service_for_protocol_entry(entry: AccessListEntry, service_objects: dict[str, ServiceObject]) -> str: + """ + Create service reference for a protocol group entry. + + Args: + entry: Access list entry with protocol group + service_objects: Dictionary to update with new service objects + Returns: + Service reference string (single object or delimited list) + + """ + if entry.protocol.value in ("tcp", "udp", "icmp"): + return create_service_for_protocol_entry_with_single_protocol(entry, service_objects) + + if entry.protocol.value == "ip": + svc_refs = [create_any_protocol_service(proto, service_objects) for proto in protocol_map] + + reference_string = fwo_base.sort_and_join(svc_refs) + # create a service group for all protocols + service_objects["ANY"] = ServiceObject( + svc_uid="ANY", + svc_name="ANY", + svc_color=fwo_const.DEFAULT_COLOR, + svc_typ="group", + svc_member_names=reference_string, + svc_member_refs=reference_string, + ) + return "ANY" + # Unknown protocol, default to any for the protocol + return create_any_protocol_service(entry.protocol.value, service_objects) + + +def create_service_for_acl_entry(entry: AccessListEntry, service_objects: dict[str, ServiceObject]) -> str: + """ + Create service object(s) for an ACL entry and return the service reference. + + Args: + entry: Access list entry with protocol and port information + service_objects: Dictionary to update with new service objects + + Returns: + Service reference string (single object or delimited list) + + """ + if entry.protocol.kind == "protocol": + return create_service_for_protocol_entry(entry, service_objects) + + if entry.protocol.kind in ("service-group", "service"): + # Reference to service object or group + return entry.protocol.value + + if entry.protocol.kind == "protocol-group": + # Protocol group - will be resolved by caller + return entry.protocol.value + + # Default to all common protocols + svc_refs = [create_any_protocol_service(proto, service_objects) for proto in ("tcp", "udp", "icmp")] + return fwo_base.sort_and_join(svc_refs) + + +def process_mixed_protocol_eq_ports( + group: AsaServiceObjectGroup, service_objects: dict[str, ServiceObject] +) -> list[str]: + """Process equal ports for mixed protocol groups.""" + obj_names: list[str] = [] + for protos, eq_ports in group.ports_eq.items(): + for proto in protos.split("-"): # handles "tcp-udp" + for port in eq_ports: + obj_name = create_service_for_port(port, proto, service_objects) + obj_names.append(obj_name) + return obj_names + + +def process_mixed_protocol_range_ports( + group: AsaServiceObjectGroup, service_objects: dict[str, ServiceObject] +) -> list[str]: + """Process port ranges for mixed protocol groups.""" + obj_names: list[str] = [] + for proto, ranges in group.ports_range.items(): + for pr in ranges: + obj_name = create_service_for_port_range(pr, proto, service_objects) + obj_names.append(obj_name) + return obj_names + + +def process_fully_enabled_protocols( + group: AsaServiceObjectGroup, service_objects: dict[str, ServiceObject] +) -> list[str]: + """Process protocols that allow all ports.""" + obj_names: list[str] = [] + for proto in group.protocols: + obj_name = create_any_protocol_service(proto, service_objects) + obj_names.append(obj_name) + return obj_names + + +def process_mixed_protocol_group(group: AsaServiceObjectGroup, service_objects: dict[str, ServiceObject]) -> list[str]: + """Process a mixed protocol service group.""" + obj_names: list[str] = [] + + # Process ports_eq (single port values) + obj_names.extend(process_mixed_protocol_eq_ports(group, service_objects)) + + # Process ports_range (port ranges) + obj_names.extend(process_mixed_protocol_range_ports(group, service_objects)) + + # Process any-protocol references + obj_names.extend(process_fully_enabled_protocols(group, service_objects)) + + # Process nested references + obj_names.extend(group.nested_refs) + + return obj_names + + +def process_single_protocol_eq_ports( + protocol: str, ports: list[str], service_objects: dict[str, ServiceObject] +) -> list[str]: + """Process equal ports for single protocol groups.""" + obj_names: list[str] = [] + for port in ports: + obj_name = create_service_for_port(port, protocol, service_objects) + obj_names.append(obj_name) + return obj_names + + +def process_single_protocol_range_ports( + protocol: str, ranges: list[tuple[str, str]], service_objects: dict[str, ServiceObject] +) -> list[str]: + """Process port ranges for single protocol groups.""" + obj_names: list[str] = [] + for obj_range in ranges: + obj_name = create_service_for_port_range(obj_range, protocol, service_objects) + obj_names.append(obj_name) + return obj_names + + +def process_single_protocol_group(group: AsaServiceObjectGroup, service_objects: dict[str, ServiceObject]) -> list[str]: + """Process a single-protocol service group.""" + obj_names: list[str] = [] + + if not group.proto_mode: + raise ValueError(f"Service object group {group.name} missing proto_mode") + + for protocol in group.proto_mode.split("-"): # handles "tcp-udp" + if protocol not in protocol_map: + raise ValueError(f"Unknown protocol in service object group: {protocol}") + + # Process single port values + obj_names.extend( + process_single_protocol_eq_ports(protocol, group.ports_eq.get(group.proto_mode, []), service_objects) + ) + + # Process port ranges + obj_names.extend( + process_single_protocol_range_ports(protocol, group.ports_range.get(group.proto_mode, []), service_objects) + ) + + # Process nested references + obj_names.extend(group.nested_refs) + + return obj_names + + +def normalize_service_object_groups( + service_groups: list[AsaServiceObjectGroup], service_objects: dict[str, ServiceObject] +) -> dict[str, ServiceObject]: + """ + Normalize service object groups from ASA configuration. + + Args: + service_groups: List of parsed ASA service object groups + service_objects: Existing service objects dictionary to update + + Returns: + Updated service objects dictionary including groups + + """ + # Process each service group + for group in service_groups: + if group.proto_mode: + obj_names = process_single_protocol_group(group, service_objects) + else: + obj_names = process_mixed_protocol_group(group, service_objects) + + # look for duplicates and remove them + unique_obj_names = list(set(obj_names)) + if len(unique_obj_names) < len(obj_names): + duplicates = [x for x in obj_names if obj_names.count(x) > 1] + FWOLogger.debug(f"Removed duplicate service object references found in group {group.name}: {duplicates}") + + # Create the group object + group_obj = create_service_group_object(group.name, unique_obj_names, group.description) + service_objects[group.name] = group_obj + + return service_objects diff --git a/roles/importer/files/importer/fw_modules/ciscoasa9/fwcommon.py b/roles/importer/files/importer/fw_modules/ciscoasa9/fwcommon.py new file mode 100644 index 0000000000..a72e97017a --- /dev/null +++ b/roles/importer/files/importer/fw_modules/ciscoasa9/fwcommon.py @@ -0,0 +1,338 @@ +#!/usr/bin/env python3 +""" +ASA Configuration Import Module + +This module handles the main configuration import workflow for Cisco ASA devices. +It provides functions to connect to devices, retrieve configurations, and +orchestrate the normalization process. +""" + +import time +from pathlib import Path +from typing import Any + +from fw_modules.ciscoasa9.asa_normalize import normalize_config +from fw_modules.ciscoasa9.asa_parser import parse_asa_config +from fwo_base import write_native_config_to_file +from fwo_exceptions import FwoImporterError +from fwo_log import FWOLogger +from model_controllers.fwconfigmanagerlist_controller import FwConfigManagerListController +from model_controllers.import_state_controller import ImportStateController +from model_controllers.management_controller import ManagementController +from models.fw_common import FwCommon +from scrapli.driver import GenericDriver + + +class CiscoAsa9Common(FwCommon): + def get_config( + self, config_in: FwConfigManagerListController, import_state: ImportStateController + ) -> tuple[int, FwConfigManagerListController]: + return get_config(config_in, import_state) + + +def _connect_to_device(mgm_details: ManagementController) -> GenericDriver: + """ + Establish SSH connection to the device. + + Args: + mgm_details: ManagementController object with connection details. + + Returns: + Connected GenericDriver instance. + + """ + device: dict[str, Any] = { + "host": mgm_details.hostname, + "port": mgm_details.port, + "auth_username": mgm_details.import_user, + "auth_password": mgm_details.secret, + "auth_strict_key": False, + "transport_options": {"open_cmd": ["-o", "KexAlgorithms=+diffie-hellman-group14-sha1"]}, + } + conn = GenericDriver(**device) + conn.open() + return conn + + +def _prepare_virtual_asa(conn: GenericDriver) -> None: + """ + Connect to ASA module on virtual device. + + Args: + conn: Active connection to the device. + + """ + conn.send_command("connect module 1 console\n") + time.sleep(2) + conn.send_command("\n") + time.sleep(2) + + +def _get_current_prompt(conn: GenericDriver) -> str: + """ + Get the current prompt from the device. + + Args: + conn: Active connection to the device. + + Returns: + Current prompt as string. + + """ + try: + return conn.get_prompt().strip() + except Exception: + FWOLogger.warning("Could not get current prompt") + return "" + + +def _ensure_enable_mode(conn: GenericDriver, mgm_details: ManagementController) -> None: + """ + Ensure device is in enabled mode. + + Args: + conn: Active connection to the device. + mgm_details: ManagementController object with enable password. + + Raises: + FwoImporterError: If unable to enter enabled mode. + + """ + current_prompt = _get_current_prompt(conn) + FWOLogger.debug(f"Current prompt: {current_prompt}") + + if current_prompt.endswith(">"): + FWOLogger.debug("Device is in user mode, entering enable mode") + try: + conn.send_interactive([("enable", "Password", False), (mgm_details.cloud_client_secret, "#", True)]) + except Exception as e: + FWOLogger.warning(f"Could not enter enable mode: {e}") + current_prompt = _get_current_prompt(conn) + if current_prompt == "": + error_msg = "Could not retrieve prompt after attempting to enter enable mode." + FWOLogger.error(error_msg) + raise FwoImporterError(error_msg) from e + if not current_prompt.endswith("#"): + raise FwoImporterError("Failed to enter enable mode.") + + current_prompt = _get_current_prompt(conn) + if not current_prompt.endswith("#"): + error_msg = f"Not in enabled mode (prompt: {current_prompt})." + FWOLogger.error(error_msg) + raise FwoImporterError(error_msg) + + FWOLogger.debug("Device is in enabled mode") + + +def _get_running_config(conn: GenericDriver) -> str: + """ + Retrieve running configuration from device. + + Args: + conn: Active connection to the device. + + Returns: + Running configuration as string. + + """ + try: + conn.send_command("terminal pager 0") + except Exception as e: + FWOLogger.warning(f"Could not disable paging: {e}") + + response = conn.send_interactive([("show running", ": end", False)], timeout_ops=600) + return response.result.strip() + + +def _safe_close_connection(conn: GenericDriver | None) -> None: + """ + Safely close connection with proper cleanup. + + Args: + conn: Connection to close (can be None). + + """ + if conn is None: + return + + if not conn.isalive(): + FWOLogger.debug("Connection already closed") + return + + try: + conn.send_command("exit") + except Exception as e: + FWOLogger.warning(f"Could not exit session cleanly: {e}") + + try: + conn.close() + except Exception as e: + FWOLogger.warning(f"Error closing connection: {e}") + + +def _handle_connection_error(e: Exception, mgm_details: ManagementController, attempt: int, max_retries: int) -> str: + """ + Build detailed error message for connection failures. + + Args: + e: The exception that occurred. + mgm_details: Management details for context. + attempt: Current attempt number. + max_retries: Maximum retry attempts. + + Returns: + Formatted error message. + + """ + error_msg = f"Error connecting to device {mgm_details.hostname} (attempt {attempt + 1}/{max_retries}): {e}" + + error_str = str(e).lower() + if "password" in error_str or "enable" in error_str: + error_msg += "\nPossible causes: incorrect password, or device already in use by another import session" + elif "prompt" in error_str or "timeout" in error_str: + error_msg += ( + "\nPossible causes: concurrent access from multiple import processes, or device not responding as expected" + ) + + return error_msg + + +def _log_retry_attempt(attempt: int, max_retries: int) -> None: + """ + Log retry attempt with exponential backoff. + + Args: + attempt: Current attempt number (0-indexed). + max_retries: Maximum number of retries. + + """ + if attempt > 0: + backoff_time = 2 ** (attempt + 1) + FWOLogger.info(f"Retry attempt {attempt + 1}/{max_retries} after {backoff_time} seconds backoff") + time.sleep(backoff_time) + else: + FWOLogger.debug(f"Connection attempt {attempt + 1}/{max_retries}") + + +def _retrieve_config_from_device(conn: GenericDriver, mgm_details: ManagementController, is_virtual_asa: bool) -> str: + """ + Retrieve configuration from connected device. + + Args: + conn: Active connection to the device. + mgm_details: ManagementController object with connection details. + is_virtual_asa: Whether this is a virtual ASA device. + + Returns: + Running configuration as string. + + """ + if is_virtual_asa: + _prepare_virtual_asa(conn) + + _ensure_enable_mode(conn, mgm_details) + return _get_running_config(conn) + + +def _attempt_connection(mgm_details: ManagementController, is_virtual_asa: bool, attempt: int, max_retries: int) -> str: + """ + Attempt a single connection to retrieve configuration. + + Args: + mgm_details: ManagementController object with connection details. + is_virtual_asa: Whether this is a virtual ASA device. + attempt: Current attempt number. + max_retries: Maximum retry attempts. + + Returns: + Running configuration as string. + + Raises: + FwoImporterError: If connection fails and should not retry. + + """ + conn = None + + try: + conn = _connect_to_device(mgm_details) + config = _retrieve_config_from_device(conn, mgm_details, is_virtual_asa) + _safe_close_connection(conn) + + FWOLogger.debug(f"Successfully connected after {attempt + 1} attempt(s)") + + return config + + except Exception as e: + _safe_close_connection(conn) + error_msg = _handle_connection_error(e, mgm_details, attempt, max_retries) + + if attempt < max_retries - 1: + FWOLogger.warning(error_msg + "\nWill retry...") + else: + FWOLogger.error(error_msg + "\nMax retries exhausted.") + raise FwoImporterError(error_msg) from e + + +def load_config_from_management(mgm_details: ManagementController, is_virtual_asa: bool, max_retries: int = 10) -> str: + """ + Load ASA configuration from the management device using SSH with exponential backoff retry. + + Args: + mgm_details: ManagementController object with connection details. + is_virtual_asa: Boolean indicating if the device is a virtual ASA inside of a FirePower instance. + max_retries: Maximum number of retry attempts (default: 10). + + Returns: + The raw configuration as a string. + + Raises: + FwoImporterError: After all retry attempts are exhausted. + + """ + for attempt in range(max_retries): + _log_retry_attempt(attempt, max_retries) + + try: + return _attempt_connection(mgm_details, is_virtual_asa, attempt, max_retries) + except FwoImporterError as _: + if attempt >= max_retries - 1: + raise + raise FwoImporterError(f"Failed to connect to device {mgm_details.hostname} after {max_retries} attempts") + + +def get_config( + config_in: FwConfigManagerListController, import_state: ImportStateController +) -> tuple[int, FwConfigManagerListController]: + """ + Retrieve and parse the ASA configuration. + + Args: + config_in: Configuration input details. + importState: Current import state. + + Returns: + A tuple containing the status code and the parsed configuration. + + """ + FWOLogger.debug("starting ciscoAsa9/get_config") + + is_virtual_asa = import_state.state.mgm_details.device_type_name == "Cisco Asa on FirePower" + + if config_in.native_config_is_empty(): + # for debugging, use: raw_config = load_config_from_file("test_asa.conf") + raw_config = load_config_from_management(import_state.state.mgm_details, is_virtual_asa) + config2import = parse_asa_config(raw_config) + config_in.native_config = config2import.model_dump() + + write_native_config_to_file(import_state.state, config_in.native_config) + + normalize_config(config_in, import_state.state) + + return 0, config_in + + +def load_config_from_file(filename: str) -> str: + """Load ASA configuration from a file.""" + path = Path("roles", "importer", "files", "importer", "fw_modules", "ciscoasa9", filename) + with open(path) as f: + return f.read() diff --git a/roles/importer/files/importer/fw_modules/ciscoasa9/test_asa.conf b/roles/importer/files/importer/fw_modules/ciscoasa9/test_asa.conf new file mode 100644 index 0000000000..f9e5c8a1d6 --- /dev/null +++ b/roles/importer/files/importer/fw_modules/ciscoasa9/test_asa.conf @@ -0,0 +1,178 @@ +: Saved + +: +: Serial Number: JAD204201WA +: Hardware: ASA5506, 4096 MB RAM, CPU Atom C2000 series 1250 MHz, 1 CPU (4 cores) +: +ASA Version 9.16(4) +! +hostname ciscoasa +enable password ***** pbkdf2 +service-module 1 keepalive-timeout 4 +service-module 1 keepalive-counter 6 +service-module sfr keepalive-timeout 4 +service-module sfr keepalive-counter 6 + +! ===== DEMO: Names ===== +names +name 11.22.33.44 DEMO_OLD_OBJ +name 11.22.33.44 DEMO_OLD_OBJ2 description abc +name 203.0.113.10 DEMO-WEB +! +object network DEMO_OBJ_HOST_WEB + host 203.0.113.10 + description Public webserver +! +object network DEMO_OBJ_HOST_WEB_NAT + nat (inside,outside) static 203.0.113.10 +! +object network DEMO_OBJ_USER_NET + subnet 192.0.2.0 255.255.255.0 + description Inside users (demo) +! +object network DEMO_OBJ_FQDN + fqdn v4 www.example.com + description FQDN object (demo) +! +object network DEMO_OBJ_IP_RANGE + range 192.0.2.1 192.0.2.150 +! +object service DEMO_SVC_TCP_8443 + service tcp destination eq 8443 + description Alt HTTPS (demo) +! +object service DEMO_SVC_UDP_RANGE + service udp destination range 2000 2010 + description UDP port range (demo) +! +object service DEMO_UDP_NAME_RANGE + service udp destination range netbios-ns netbios-dgm + description UDP port range via names (demo) +! +object service echo-request + service icmp echo 0 +! +object service echo-reply + service icmp echo-reply 0 +! +object service icmp-fragmentation + service icmp unreachable 4 +! +object service time-exceeded + service icmp time-exceeded 0 +! +object service GRE + service gre + description GRE Tunnel Protokoll +! +object-group network DEMO_OG_NET_BASE + description Base network objects (demo) + network-object object DEMO_OBJ_USER_NET +! +object-group network DEMO_OG_NET_DMZ + network-object object DEMO_OBJ_HOST_WEB + network-object host 192.0.2.22 +! +object-group network DEMO_OG_NET_ALL + description All internal/DMZ nets (demo) + group-object DEMO_OG_NET_BASE + group-object DEMO_OG_NET_DMZ + network-object object DEMO_OBJ_FQDN +! +object-group network DEMO_OG_IPV6 + network-object 2001:db8:abcd::/40 + network-object 2001::/12 + network-object host 2001:db8:abcd::1 + network-object 192.0.2.0 255.255.255.0 + network-object host 192.0.2.10 + network-object object DEMO_OBJ_IP_RANGE +! +object-group service DEMO_OG_SVC_MIXED + description Mixed service refs (demo) + service-object object DEMO_SVC_TCP_8443 + service-object tcp destination eq https + service-object udp destination eq domain + service-object udp destination range 2000 2005 + service-object udp destination range netbios-ns netbios-dgm +! +object-group service DEMO_OG_SVC_PORTS tcp-udp + description Common app ports (demo) + port-object eq 135 + port-object range 138 139 + port-object eq ssh + port-object eq sqlnet +! +object-group service DEMO_OG_SVC_TCP + description Common TCP ports (demo) + service-object tcp-udp destination eq https +! +object-group service DEMO_OG_SVC_ICMP + description ICMP and a service object (demo) + service-object icmp + service-object object DEMO_SVC_TCP_8443 +! +object-group icmp-type DEMO_OG_SVC_ICMP + icmp-object echo + icmp-object echo-reply +! +object-group protocol DEMO_OG_PROTO_TCP + protocol-object tcp +! +object-group protocol DEMO_OG_PROTO_TCP_UDP + protocol-object tcp + protocol-object udp +! +object network DEMO_OBJ_EXT_A + host 198.51.100.100 + description External peer A (demo) +! +object network DEMO_OBJ_EXT_B + host 198.51.100.101 + description External peer B (demo) +! +object service DEMO_SVC_TCP_22hdsfkjskfjhsdkf tcp + service destination eq 22 + description SSH (demo) +! +object service DEMO_SVC_TCP_22sadahdsfkjskfjhsdkf tcp-udp + service destination eq 22 + description SSH (demo) +! +access-list DEMO_ACL extended permit ip host 192.0.2.10 host 203.0.113.10 +access-list DEMO_ACL extended permit ip object DEMO_OBJ_USER_NET object DEMO_OBJ_HOST_WEB +access-list DEMO_ACL extended permit ip object-group DEMO_OG_NET_ALL any4 +access-list DEMO_ACL extended permit ip object-group DEMO_OG_NET_BASE object-group DEMO_OG_NET_DMZ + +access-list DEMO_ACL extended permit object DEMO_SVC_TCP_8443 object DEMO_OBJ_USER_NET object DEMO_OBJ_HOST_WEB +access-list DEMO_ACL extended permit object-group DEMO_OG_PROTO_TCP any object DEMO_OBJ_HOST_WEB eq 8443 inactive +access-list DEMO_ACL extended permit object-group DEMO_OG_PROTO_TCP object-group DEMO_OG_NET_BASE object-group DEMO_OG_NET_DMZ object-group DEMO_OG_SVC_PORTS +access-list DEMO_ACL extended permit object-group DEMO_OG_PROTO_TCP object-group DEMO_OG_NET_BASE object-group DEMO_OG_NET_DMZ object DEMO_SVC_TCP_8443 +access-list DEMO_ACL extended permit object-group DEMO_OG_SVC_PORTS object-group DEMO_OG_NET_BASE object DEMO_OBJ_HOST_WEB + +access-list DEMO_ACL extended permit icmp any object-group DEMO_OG_NET_DMZ echo-reply +access-list DEMO_ACL extended permit icmp object-group DEMO_OG_NET_BASE object-group DEMO_OG_NET_DMZ +access-list DEMO_ACL extended permit icmp object DEMO_OBJ_USER_NET any4 + +access-list DEMO_ACL extended permit tcp object-group DEMO_OG_NET_BASE object-group DEMO_OG_NET_DMZ eq ssh +access-list DEMO_ACL extended permit udp object DEMO_OBJ_USER_NET object DEMO_OBJ_HOST_WEB eq bootps +access-list DEMO_ACL extended permit udp object DEMO_OBJ_USER_NET object-group DEMO_OG_NET_DMZ +access-list DEMO_ACL extended permit tcp any object DEMO_OBJ_HOST_WEB eq https inactive +access-list DEMO_ACL extended permit tcp any object DEMO_OBJ_HOST_WEB eq 8443 inactive +access-list DEMO_ACL extended permit tcp object-group DEMO_OG_NET_BASE object-group DEMO_OG_NET_DMZ eq 2345 +access-list DEMO_ACL extended permit tcp object-group DEMO_OG_NET_BASE object-group DEMO_OG_NET_DMZ range 2000 2005 +access-list DEMO_ACL extended permit tcp object-group DEMO_OG_NET_BASE object-group DEMO_OG_NET_DMZ object-group DEMO_OG_SVC_MIXED +access-list DEMO_ACL extended permit tcp object-group DEMO_OG_NET_BASE any eq https +access-list DEMO_ACL extended deny tcp object DEMO_OBJ_EXT_A object-group DEMO_OG_NET_DMZ eq https + +access-list acl1 extended permit ip host 1.2.3.4 host 2.3.4.5 +access-list acl1 extended permit ip host 1.2.3.4 host 2.3.4.6 + +access-list acl2 extended permit tcp 10.0.0.0 255.255.255.128 object DEMO_OBJ_USER_NET eq 8834 +access-list acl2 extended permit icmp 10.0.0.0 255.255.255.240 10.0.120.64 255.255.255.224 + +access-list acl3 extended permit udp object DEMO_OBJ_HOST_WEB 10.0.120.64 255.255.255.224 range 135 netbios-ssn + +! +access-group DEMO_ACL in interface inside_2 + +: end \ No newline at end of file diff --git a/roles/importer/files/importer/fortiadom5ff/__init__.py b/roles/importer/files/importer/fw_modules/ciscofirepowerdomain7ff/__init__.py similarity index 100% rename from roles/importer/files/importer/fortiadom5ff/__init__.py rename to roles/importer/files/importer/fw_modules/ciscofirepowerdomain7ff/__init__.py diff --git a/roles/importer/files/importer/fw_modules/ciscofirepowerdomain7ff/fwcommon.py b/roles/importer/files/importer/fw_modules/ciscofirepowerdomain7ff/fwcommon.py new file mode 100644 index 0000000000..e652fc97b6 --- /dev/null +++ b/roles/importer/files/importer/fw_modules/ciscofirepowerdomain7ff/fwcommon.py @@ -0,0 +1,10 @@ +from model_controllers.fwconfigmanagerlist_controller import FwConfigManagerListController +from model_controllers.import_state_controller import ImportStateController +from models.fw_common import FwCommon + + +class CiscoFirepowerDomain7ffCommon(FwCommon): + def get_config( + self, config_in: FwConfigManagerListController, import_state: ImportStateController + ) -> tuple[int, FwConfigManagerListController]: + raise NotImplementedError("Cisco Firepower Domain 7ff is not supported yet in the new python importer.") diff --git a/roles/importer/files/importer/fortiosmanagementREST/__init__.py b/roles/importer/files/importer/fw_modules/fortiadom5ff/__init__.py similarity index 100% rename from roles/importer/files/importer/fortiosmanagementREST/__init__.py rename to roles/importer/files/importer/fw_modules/fortiadom5ff/__init__.py diff --git a/roles/importer/files/importer/checkpointR8x/discovery_logging.conf b/roles/importer/files/importer/fw_modules/fortiadom5ff/discovery_logging.conf similarity index 100% rename from roles/importer/files/importer/checkpointR8x/discovery_logging.conf rename to roles/importer/files/importer/fw_modules/fortiadom5ff/discovery_logging.conf diff --git a/roles/importer/files/importer/fw_modules/fortiadom5ff/fmgr_base.py b/roles/importer/files/importer/fw_modules/fortiadom5ff/fmgr_base.py new file mode 100644 index 0000000000..abc3b1cd1a --- /dev/null +++ b/roles/importer/files/importer/fw_modules/fortiadom5ff/fmgr_base.py @@ -0,0 +1,59 @@ +from typing import Any + +from fwo_log import FWOLogger +from services.service_provider import ServiceProvider + + +# TODO: unused functions - remove? +def set_alerts_for_missing_objects( + objects_not_found: list[str], import_id: int, rule_uid: str | None, object_type: str | None, mgm_id: int +): + for obj in objects_not_found: + if obj in {"all", "Original"}: + continue + + service_provider = ServiceProvider() + global_state = service_provider.get_global_state() + + api_call = global_state.import_state.api_call + + api_call.create_data_issue(obj_name=obj, severity=1, rule_uid=rule_uid, mgm_id=mgm_id, object_type=object_type) + + desc = "found a broken network object reference '" + obj + "' " + if object_type is not None: + desc += "(type=" + object_type + ") " + desc += "in rule with UID '" + str(rule_uid) + "'" + api_call.set_alert( + import_id=import_id, + title="object reference error", + mgm_id=mgm_id, + severity=1, + description=desc, + source="import", + alert_code=16, + ) + + +def lookup_obj_in_tables( + el: str, object_tables: list[list[dict[str, Any]]], name_key: str, uid_key: str, ref_list: list[str] +) -> bool: + break_flag = False + found = False + + for tab in object_tables: + if break_flag: + found = True + break + for obj in tab: + if obj[name_key] == el: + if uid_key in obj: + ref_list.append(obj[uid_key]) + # in case of internet-service-object we find no uid field, but custom q_origin_key_ + elif "q_origin_key" in obj: + ref_list.append("q_origin_key_" + str(obj["q_origin_key"])) + else: + FWOLogger.error("found object without expected uid") + break_flag = True + found = True + break + return found diff --git a/roles/importer/files/importer/fw_modules/fortiadom5ff/fmgr_consts.py b/roles/importer/files/importer/fw_modules/fortiadom5ff/fmgr_consts.py new file mode 100644 index 0000000000..421e8e0d79 --- /dev/null +++ b/roles/importer/files/importer/fw_modules/fortiadom5ff/fmgr_consts.py @@ -0,0 +1,23 @@ +nw_obj_types = [ + "firewall/address", + "firewall/address6", + "firewall/addrgrp", + "firewall/addrgrp6", + "firewall/ippool", + "firewall/vip", + "system/external-resource", + "firewall/wildcard-fqdn/custom", + "firewall/wildcard-fqdn/group", +] + +svc_obj_types = [ + "application/list", + "application/group", + "application/categories", + "application/custom", + "firewall/service/custom", + "firewall/service/group", +] + +nat_types = ["central/dnat", "central/dnat6", "firewall/central-snat-map"] +user_obj_types = ["user/local", "user/group"] diff --git a/roles/importer/files/importer/fw_modules/fortiadom5ff/fmgr_getter.py b/roles/importer/files/importer/fw_modules/fortiadom5ff/fmgr_getter.py new file mode 100644 index 0000000000..dffa531d89 --- /dev/null +++ b/roles/importer/files/importer/fw_modules/fortiadom5ff/fmgr_getter.py @@ -0,0 +1,215 @@ +# library for API get functions +import json +from typing import Any + +import fwo_globals +import requests +from fwo_exceptions import ( + FwApiCallFailedError, + FwLoginFailedError, + FwLogoutFailedError, + FwoImporterError, + FwoUnknownDeviceForManagerError, +) +from fwo_log import FWOLogger +from models.management import Management + + +def api_call(url: str, command: str, json_payload: dict[str, Any], sid: str, method: str = "") -> dict[str, Any]: + request_headers = {"Content-Type": "application/json"} + if sid != "": + json_payload.update({"session": sid}) + if command != "": + for p in json_payload["params"]: + p.update({"url": command}) + if method == "": + method = "get" + json_payload.update({"method": method}) + + r = requests.post(url, data=json.dumps(json_payload), headers=request_headers, verify=fwo_globals.verify_certs) + result_json = r.json() + if "result" not in result_json or len(result_json["result"]) == 0: + if "pass" in json.dumps(json_payload): + raise FwApiCallFailedError(f"error while sending api_call containing credential information to url {url!s}") + result_data = r.json()["result"][0]["status"] if "status" in r.json()["result"][0] else r.json()["result"][0] + exception_text = ( + f"error while sending api_call to url {url!s} with payload {json.dumps(json_payload, indent=2)}" + ) + exception_text += ( + f" and headers: {json.dumps(request_headers, indent=2)}, result={json.dumps(result_data, indent=2)}" + ) + raise FwApiCallFailedError(exception_text) + if "pass" in json.dumps(json_payload): + FWOLogger.debug("api_call containing credential information to url " + str(url) + " - not logging query", 3) + else: + FWOLogger.debug( + "api_call to url " + + str(url) + + " with payload " + + json.dumps(json_payload, indent=2) + + " and headers: " + + json.dumps(request_headers, indent=2), + 3, + ) + + return result_json + + +def require_domain_name(domain_name: str | None, context: str) -> str: + if not domain_name: + raise FwoImporterError(f"Missing FortiManager ADOM domain name for {context}") + return domain_name + + +def login(user: str, password: str, base_url: str) -> str | None: + payload: dict[str, Any] = { + "id": 1, + "params": [ + { + "data": [ + { + "user": user, + "passwd": password, + } + ] + } + ], + } + try: + response = api_call(base_url, "sys/login/user", payload, "", method="exec") + except Exception: + raise FwLoginFailedError("FortiManager login ERROR: url=" + base_url) from None + if "session" not in response: # leaving out payload as it contains pwd + raise FwLoginFailedError("FortiManager login ERROR (no sid): url=" + base_url) from None + return response["session"] + + +def logout(v_url: str, sid: str, method: str = "exec"): + payload: dict[str, Any] = {"params": [{}]} + + response = api_call(v_url, "sys/logout", payload, sid, method=method) + if ( + "result" in response + and "status" in response["result"][0] + and "code" in response["result"][0]["status"] + and response["result"][0]["status"]["code"] == 0 + ): + FWOLogger.debug("successfully logged out") + else: + raise FwLogoutFailedError( + "fmgr_getter ERROR: did not get status code 0 when logging out, " + "api call: url: " + str(v_url) + ", + payload: " + str(payload) + ) + + +def update_config_with_fortinet_api_call( + config_json: list[dict[str, Any]], + sid: str, + api_base_url: str, + api_path: str, + result_name: str, + payload: dict[str, Any] | None = None, + options: list[Any] | None = None, + limit: int = 150, + method: str = "get", +): + if options is None: + options = [] + if payload is None: + payload = {} + offset = 0 + limit = int(limit) + returned_new_objects = True + full_result: list[Any] = [] + while returned_new_objects: + range_ = [offset, limit] + if payload == {}: + payload = {"params": [{"range": range_}]} + elif "params" in payload and len(payload["params"]) > 0: + payload["params"][0].update({"range": range_}) + + # adding options + if len(options) > 0: + payload["params"][0].update({"option": options}) + + result = fortinet_api_call(sid, api_base_url, api_path, payload=payload, method=method) + full_result.extend(result) + offset += limit + if len(result) < limit: + returned_new_objects = False + + full_result = parse_special_fortinet_api_results(result_name, full_result) + + config_json.append({"type": result_name, "data": full_result}) + + +def parse_special_fortinet_api_results(result_name: str, full_result: list[Any]) -> list[Any]: + if result_name == "nw_obj_global_firewall/internet-service-basic": + if len(full_result) > 0 and "response" in full_result[0] and "results" in full_result[0]["response"]: + full_result = full_result[0]["response"]["results"] + else: + FWOLogger.warning(f"did not get expected results for {result_name} - setting to empty list") + full_result = [] + return full_result + + +def fortinet_api_call( + sid: str, api_base_url: str, api_path: str, payload: dict[str, Any] | None = None, method: str = "get" +) -> list[Any]: + if payload is None: + payload = {} + if payload == {}: + payload = {"params": [{}]} + api_result = api_call(api_base_url, api_path, payload, sid, method=method) + plain_result: dict[str, Any] = api_result["result"][0] + if "data" in plain_result: + result = plain_result["data"] + if isinstance( + result, dict + ): # code implicitly expects result to be a list, but some fmgr data results are dicts + result: list[Any] = [result] + else: + result = [] + return result + + +def get_devices_from_manager(adom_mgm_details: Management, sid: str, fm_api_url: str) -> dict[str, Any]: + device_vdom_dict: dict[str, dict[str, str]] = {} + + adom_name = require_domain_name(adom_mgm_details.domain_name, "device inventory") + device_results = fortinet_api_call(sid, fm_api_url, "/dvmdb/adom/" + adom_name + "/device") + for mgm_details_device in adom_mgm_details.devices: + if not mgm_details_device["importDisabled"]: + found_fmgr_device = False + for fmgr_device in device_results: + found_fmgr_device = parse_device_and_vdom( + fmgr_device, mgm_details_device, device_vdom_dict, found_fmgr_device + ) + if not found_fmgr_device: + raise FwoUnknownDeviceForManagerError( + "Could not find " + mgm_details_device["name"] + " in Fortimanager Config" + ) from None + + return device_vdom_dict + + +def parse_device_and_vdom( + fmgr_device: dict[str, Any], + mgm_details_device: dict[str, Any], + device_vdom_dict: dict[str, dict[str, str]], + found_fmgr_device: bool, +) -> bool: + if "vdom" in fmgr_device: + for fmgr_vdom in fmgr_device["vdom"]: + if mgm_details_device["name"] == fmgr_device["name"] + "_" + fmgr_vdom["name"]: + found_fmgr_device = True + if fmgr_device["name"] in device_vdom_dict: + device_vdom_dict[fmgr_device["name"]].update({fmgr_vdom["name"]: ""}) + else: + device_vdom_dict.update({fmgr_device["name"]: {fmgr_vdom["name"]: ""}}) + return found_fmgr_device + + +def get_policy_packages_from_manager(sid: str, fm_api_url: str, adom: str = "") -> list[Any]: + url = "/pm/pkg/global" if adom == "" else "/pm/pkg/adom/" + adom + return fortinet_api_call(sid, fm_api_url, url) diff --git a/roles/importer/files/importer/fw_modules/fortiadom5ff/fmgr_gw_networking.py b/roles/importer/files/importer/fw_modules/fortiadom5ff/fmgr_gw_networking.py new file mode 100644 index 0000000000..cd46dfe146 --- /dev/null +++ b/roles/importer/files/importer/fw_modules/fortiadom5ff/fmgr_gw_networking.py @@ -0,0 +1,371 @@ +import traceback +from functools import cmp_to_key +from typing import Any + +import fmgr_getter +from fwo_log import FWOLogger +from model_controllers.interface_controller import Interface +from model_controllers.route_controller import Route, get_route_destination +from netaddr import IPAddress, IPNetwork + +# Constants +SUBFETCH_HIDDEN = "subfetch hidden" +INTERFACES_PER_DEVICE = "interfaces_per_device/" + + +def process_ipv4_routing( + native_config: dict[str, Any], normalized_config: dict[str, Any], dev_id: int, full_vdom_name: str +) -> None: + """Process IPv4 routing table for a single device/vdom.""" + routing_key = "routing-table-ipv4/" + full_vdom_name + + if routing_key not in native_config: + FWOLogger.warning("could not find routing data " + routing_key) + FWOLogger.warning("native configs contains the following keys " + str(native_config.keys())) + return + + for route in native_config[routing_key]: + norm_route = Route( + dev_id, + route["gateway"], + route["ip_mask"], + interface=route["interface"], + metric=route["metric"], + distance=route["distance"], + ) + normalized_config["routing"].append(norm_route) + + +def process_ipv6_routing( + native_config: dict[str, Any], normalized_config: dict[str, Any], dev_id: int, full_vdom_name: str +) -> None: + """Process IPv6 routing table for a single device/vdom.""" + routing_key = "routing-table-ipv6/" + full_vdom_name + + if routing_key not in native_config: + FWOLogger.warning("could not find routing data " + routing_key) + if FWOLogger.is_debug_level(6): + FWOLogger.warning("native configs contains the following keys " + str(native_config.keys())) + return + + for route in native_config[routing_key]: + norm_route = Route( + dev_id, + route["gateway"], + route["ip_mask"], + metric=route["metric"], + distance=route["distance"], + interface=route["interface"], + ip_version=6, + ) + normalized_config["routing"].append(norm_route) + + +def process_device_interfaces( + native_config: dict[str, Any], normalized_config: dict[str, Any], dev_id: int, full_vdom_name: str +) -> None: + """Process interfaces for a single device/vdom.""" + interfaces_key = INTERFACES_PER_DEVICE + full_vdom_name + + if interfaces_key not in native_config: + return + + for interface in native_config[interfaces_key]: + # Process IPv6 interface + if "ipv6" in interface and "ip6-address" in interface["ipv6"] and interface["ipv6"]["ip6-address"] != "::/0": + ipv6, netmask_bits = interface["ipv6"]["ip6-address"].split("/") + norm_if_v6 = Interface(dev_id, interface["name"], IPAddress(ipv6), netmask_bits, ip_version=6) + normalized_config["interfaces"].append(norm_if_v6) + + # Process IPv4 interface + if "ip" in interface and interface["ip"] != ["0.0.0.0", "0.0.0.0"]: + ipv4 = IPAddress(interface["ip"][0]) + netmask_bits = IPAddress(interface["ip"][1]).netmask_bits() + norm_if_v4 = Interface(dev_id, interface["name"], ipv4, netmask_bits, ip_version=4) + normalized_config["interfaces"].append(norm_if_v4) + + +def normalize_network_data( + native_config: dict[str, Any], normalized_config: dict[str, Any], mgm_details: dict[str, Any] +) -> None: + """Normalize network data by processing routing tables and interfaces for all devices.""" + normalized_config.update({"routing": [], "interfaces": []}) + + for dev_id, _, _, full_vdom_name in get_all_dev_names(mgm_details["devices"]): + # Process routing tables + process_ipv4_routing(native_config, normalized_config, dev_id, full_vdom_name) + process_ipv6_routing(native_config, normalized_config, dev_id, full_vdom_name) + + # Process interfaces + process_device_interfaces(native_config, normalized_config, dev_id, full_vdom_name) + + # Sort routing table by destination + normalized_config["routing"].sort(key=get_route_destination, reverse=True) + + +def get_matching_route(destination_ip: IPAddress, routing_table: list[dict[str, Any]]) -> dict[str, Any] | None: + def route_matches(ip: IPAddress, destination: str) -> bool: + ip_n = IPNetwork(ip).cidr + dest_n = IPNetwork(destination).cidr + return ip_n in dest_n or dest_n in ip_n + + if len(routing_table) == 0: + FWOLogger.error("src nat behind interface: encountered empty routing table") + return None + + for route in routing_table: + if route_matches(destination_ip, route["destination"]): + return route + + FWOLogger.warning("src nat behind interface: found no matching route in routing table - no default route?!") + return None + + +def get_ip_of_interface(interface: str, interface_list: list[dict[str, Any]] | None = None) -> str | None: + if interface_list is None: + interface_list = [] + interface_details = next((sub for sub in interface_list if sub["name"] == interface), None) + + if interface_details is not None and "ipv4" in interface_details: + return interface_details["ipv4"] + return None + + +def sort_reverse(ar_in: list[dict[str, Any]], key: str) -> list[dict[str, Any]]: + def comp(left: dict[str, Any], right: dict[str, Any]) -> int: + l_submask = int(left[key].split("/")[1]) + r_submask = int(right[key].split("/")[1]) + return l_submask - r_submask + + return sorted(ar_in, key=cmp_to_key(comp), reverse=True) + + +# strip off last part of a string separated by separator +def strip_off_last_part(string_in: str, separator: str = "_") -> str: + string_out = string_in + if separator in string_in: # strip off final _xxx part + str_ar = string_in.split(separator) + str_ar.pop() + string_out = separator.join(str_ar) + return string_out + + +def get_last_part(string_in: str, separator: str = "_") -> str: + string_out = "" + if separator in string_in: # strip off _vdom_name + str_ar = string_in.split(separator) + string_out = str_ar.pop() + return string_out + + +def get_plain_device_names_without_vdoms(devices: list[dict[str, Any]]) -> list[str]: + device_array: list[str] = [] + for dev in devices: + dev_name = strip_off_last_part(dev["name"]) + if dev_name not in device_array: + device_array.append(dev_name) + return device_array + + +# only getting one vdom as currently assuming routing to be +# the same for all vdoms on a device +def get_device_names_plus_one_vdom(devices: list[dict[str, Any]]) -> list[list[str]]: + device_array: list[str] = [] + device_array_with_vdom: list[list[str]] = [] + for dev in devices: + dev_name = strip_off_last_part(dev["name"]) + vdom_name = get_last_part(dev["name"]) + if dev_name not in device_array: + device_array.append(dev_name) + device_array_with_vdom.append([dev_name, vdom_name]) + return device_array_with_vdom + + +# getting devices and their vdom names +def get_device_plus_full_vdom_names(devices: list[dict[str, Any]]) -> list[list[str]]: + device_array_with_vdom: list[list[str]] = [] + for dev in devices: + dev_name = strip_off_last_part(dev["name"]) + vdom_name = dev["name"] + device_array_with_vdom.append([dev_name, vdom_name]) + return device_array_with_vdom + + +# getting devices and their vdom names +def get_all_dev_names(devices: list[dict[str, Any]]) -> list[list[Any]]: + device_array_with_vdom: list[list[Any]] = [] + for dev in devices: + dev_id = dev["id"] + dev_name = strip_off_last_part(dev["name"]) + plain_vdom_name = get_last_part(dev["name"]) + full_vdom_name = dev["name"] + device_array_with_vdom.append([dev_id, dev_name, plain_vdom_name, full_vdom_name]) + return device_array_with_vdom + + +# get network information (currently only used for source nat) +def create_interfaces_payload(plain_vdom_name: str) -> dict[str, Any]: + """Create payload for fetching interface information.""" + return { + "id": 1, + "params": [ + { + "fields": ["name", "ip"], + "filter": ["vdom", "==", plain_vdom_name], + "sub fetch": { + "client-options": {SUBFETCH_HIDDEN: 1}, + "dhcp-snooping-server-list": {SUBFETCH_HIDDEN: 1}, + "egress-queues": {SUBFETCH_HIDDEN: 1}, + "ipv6": { + "fields": ["ip6-address"], + "sub fetch": { + "dhcp6-iapd-list": {SUBFETCH_HIDDEN: 1}, + "ip6-delegated-prefix-list": {SUBFETCH_HIDDEN: 1}, + "ip6-extra-addr": {SUBFETCH_HIDDEN: 1}, + "ip6-prefix-list": {SUBFETCH_HIDDEN: 1}, + "vrrp6": {SUBFETCH_HIDDEN: 1}, + }, + }, + "l2tp-client-settings": {SUBFETCH_HIDDEN: 1}, + "secondaryip": {SUBFETCH_HIDDEN: 1}, + "tagging": {SUBFETCH_HIDDEN: 1}, + "vrrp": {SUBFETCH_HIDDEN: 1}, + "wifi-networks": {SUBFETCH_HIDDEN: 1}, + }, + } + ], + } + + +def fetch_device_interfaces( + sid: str, + fm_api_url: str, + native_config: dict[str, Any], + plain_dev_name: str, + plain_vdom_name: str, + full_vdom_name: str, + limit: int, +) -> None: + """Fetch interface information for a single device.""" + try: + all_interfaces_payload = create_interfaces_payload(plain_vdom_name) + # The API call expects a list but we need to work with a dict, + # so we work around this by using the pattern from the original code + temp_result: list[dict[str, Any]] = [] + fmgr_getter.update_config_with_fortinet_api_call( + temp_result, + sid, + fm_api_url, + "/pm/config/device/" + plain_dev_name + "/global/system/interface", + INTERFACES_PER_DEVICE + full_vdom_name, + payload=all_interfaces_payload, + limit=limit, + method="get", + ) + # Extract the data from the result and store in native_config + for item in temp_result: + if item["type"] == INTERFACES_PER_DEVICE + full_vdom_name: + native_config[INTERFACES_PER_DEVICE + full_vdom_name] = item["data"] + except Exception: + FWOLogger.warning( + "error while getting interfaces of device " + + plain_vdom_name + + ", vdom=" + + plain_vdom_name + + ", ignoring, traceback: " + + str(traceback.format_exc()) + ) + + +def fetch_routing_table( + sid: str, + fm_api_url: str, + native_config: dict[str, Any], + adom_name: str, + plain_dev_name: str, + plain_vdom_name: str, + full_vdom_name: str, + ip_version: str, + limit: int, +) -> None: + """Fetch routing table for a specific IP version and device.""" + payload: dict[str, Any] = { + "params": [ + { + "data": { + "target": ["adom/" + adom_name + "/device/" + plain_dev_name], + "action": "get", + "resource": "/api/v2/monitor/router/" + ip_version + "/select?&vdom=" + plain_vdom_name, + } + } + ] + } + + try: + routing_helper: list[dict[str, Any]] = [] + routing_table: list[Any] = [] + fmgr_getter.update_config_with_fortinet_api_call( + routing_helper, + sid, + fm_api_url, + "/sys/proxy/json", + "routing-table-" + ip_version + "/" + full_vdom_name, + payload=payload, + limit=limit, + method="exec", + ) + + # Extract routing table data from the result + routing_key = "routing-table-" + ip_version + "/" + full_vdom_name + for item in routing_helper: + if item["type"] == routing_key: + routing_data = item["data"] + if len(routing_data) > 0 and "response" in routing_data[0] and "results" in routing_data[0]["response"]: + routing_table = routing_data[0]["response"]["results"] + else: + FWOLogger.warning( + "got empty " + ip_version + " routing table from device " + full_vdom_name + ", ignoring" + ) + routing_table = [] + break + except Exception: + FWOLogger.warning("could not get routing table for device " + full_vdom_name + ", ignoring") + routing_table = [] + + # Store the routing table + native_config.update({"routing-table-" + ip_version + "/" + full_vdom_name: routing_table}) + + +def get_interfaces_and_routing( + sid: str, fm_api_url: str, native_config: dict[str, Any], adom_name: str, devices: list[dict[str, Any]], limit: int +) -> None: + """Get network information (interfaces and routing) for all devices.""" + device_array = get_all_dev_names(devices) + + for _, plain_dev_name, plain_vdom_name, full_vdom_name in device_array: + FWOLogger.info("dev_name: " + plain_dev_name + ", full vdom_name: " + full_vdom_name) + + # Fetch device interfaces + fetch_device_interfaces(sid, fm_api_url, native_config, plain_dev_name, plain_vdom_name, full_vdom_name, limit) + + # Fetch routing information for both IP versions + for ip_version in ["ipv4", "ipv6"]: + fetch_routing_table( + sid, + fm_api_url, + native_config, + adom_name, + plain_dev_name, + plain_vdom_name, + full_vdom_name, + ip_version, + limit, + ) + + +def get_device_from_package(package_name: str, mgm_details: dict[str, Any]) -> str | None: + for dev in mgm_details["devices"]: + if dev["local_rulebase_name"] == package_name: + return dev["id"] + FWOLogger.debug('get_device_from_package - could not find device for package "' + package_name + '"') + return None diff --git a/roles/importer/files/importer/fw_modules/fortiadom5ff/fmgr_network.py b/roles/importer/files/importer/fw_modules/fortiadom5ff/fmgr_network.py new file mode 100644 index 0000000000..5a37725755 --- /dev/null +++ b/roles/importer/files/importer/fw_modules/fortiadom5ff/fmgr_network.py @@ -0,0 +1,311 @@ +import ipaddress +from typing import Any + +from fw_modules.fortiadom5ff.fmgr_zone import find_zones_in_normalized_config +from fwo_base import sort_and_join_refs +from fwo_const import ANY_IP_END, ANY_IP_START, LIST_DELIMITER, NAT_POSTFIX +from fwo_exceptions import FwoImporterErrorInconsistenciesError +from fwo_log import FWOLogger + + +def normalize_network_objects( + native_config: dict[str, Any], + normalized_config_adom: dict[str, Any], + normalized_config_global: dict[str, Any], + nw_obj_types: list[str], +) -> None: + nw_objects: list[dict[str, Any]] = [] + + if "objects" not in native_config: + return # no objects to normalize + # objects dicts have type as toplevel key due to rewrite_native_config_obj_type_as_key + for current_obj_type in native_config["objects"]: + if not (current_obj_type in nw_obj_types and "data" in native_config["objects"][current_obj_type]): + continue + for obj_orig in native_config["objects"][current_obj_type]["data"]: + normalize_network_object( + obj_orig, + nw_objects, + normalized_config_adom, + normalized_config_global, + native_config["objects"], + current_obj_type, + ) + + if native_config.get("is-super-manager", False): + # finally add "Original" network object for natting (only in global domain) + original_obj_name = "Original" + original_obj_uid = "Original" + nw_objects.append( + create_network_object( + name=original_obj_name, + obj_type="network", + ip=ANY_IP_START, + ip_end=ANY_IP_END, + uid=original_obj_uid, + zone="global", + color="black", + comment='"original" network object created by FWO importer for NAT purposes', + ) + ) + + normalized_config_adom.update({"network_objects": nw_objects}) + + +def get_obj_member_refs_list( + obj_orig: dict[str, Any], native_config_objects: dict[str, Any], current_obj_type: str +) -> list[str]: + obj_member_refs_list: list[str] = [] + for member_name in obj_orig["member"]: + for obj_type in native_config_objects: + if exclude_object_types_in_member_ref_search(obj_type, current_obj_type): + continue + for potential_member in native_config_objects[obj_type]["data"]: + if potential_member["name"] == member_name: + obj_member_refs_list.append(potential_member.get("uuid", potential_member["name"])) # noqa: PERF401 + if len(obj_member_refs_list) != len(obj_orig["member"]): + raise FwoImporterErrorInconsistenciesError( + f"Member inconsistent for object {obj_orig['name']}, found members={obj_orig['member']!s} and member_refs={obj_member_refs_list!s}" + ) + return obj_member_refs_list + + +def exclude_object_types_in_member_ref_search(obj_type: str, current_obj_type: str) -> bool: + # TODO: expand for all kinds of missmatches in group and member + skip_member_ref_loop = False + if current_obj_type.endswith("firewall/addrgrp") and obj_type.endswith("firewall/ippool"): + skip_member_ref_loop = True + return skip_member_ref_loop + + +def normalize_network_object( + obj_orig: dict[str, Any], + nw_objects: list[dict[str, Any]], + normalized_config_adom: dict[str, Any], + normalized_config_global: dict[str, Any], + native_config_objects: dict[str, Any], + current_obj_type: str, +) -> None: + obj: dict[str, Any] = {} + obj.update({"obj_name": obj_orig["name"]}) + if "subnet" in obj_orig: # ipv4 object + _parse_subnet(obj, obj_orig) + elif "ip6" in obj_orig: # ipv6 object + normalize_network_object_ipv6(obj_orig, obj) + elif "member" in obj_orig: # addrgrp4, TODO for addrgrp6 change obj_typ to 'group_v6' and adjust obj_member_refs + member_name_list: list[str] = obj_orig["member"] + member_ref_list: list[str] = get_obj_member_refs_list(obj_orig, native_config_objects, current_obj_type) + sorted_member_refs, sorted_member_names = sort_and_join_refs( + list(zip(member_ref_list, member_name_list, strict=False)) + ) + obj.update({"obj_typ": "group"}) + obj.update({"obj_member_names": sorted_member_names}) + obj.update({"obj_member_refs": sorted_member_refs}) + elif "startip" in obj_orig: # ippool object + obj.update({"obj_typ": "ip_range"}) + obj.update({"obj_ip": obj_orig["startip"]}) + obj.update({"obj_ip_end": obj_orig["endip"]}) + elif "start-ip" in obj_orig: # standard ip range object + obj.update({"obj_typ": "ip_range"}) + obj.update({"obj_ip": obj_orig["start-ip"]}) + obj.update({"obj_ip_end": obj_orig["end-ip"]}) + elif "extip" in obj_orig: # vip object, simplifying to a single ip + normalize_vip_object(obj_orig, obj, nw_objects) + elif "wildcard-fqdn" in obj_orig or "fqdn" in obj_orig: # domain or wildcard-domain + obj.update({"obj_typ": "domain"}) + obj.update({"obj_ip": ANY_IP_START}) + obj.update({"obj_ip_end": ANY_IP_END}) + elif "q_origin_key" in obj_orig: + obj.update({"obj_typ": "dynamic_net_obj"}) + obj.update({"obj_ip": ANY_IP_START}) + obj.update({"obj_ip_end": ANY_IP_END}) + else: # unknown types + obj.update({"obj_typ": "network"}) + obj.update({"obj_ip": ANY_IP_START}) + obj.update({"obj_ip_end": ANY_IP_END}) + + # if obj_ip_end is not define, set it to obj_ip (assuming host) + if obj.get("obj_ip_end") is None and obj.get("obj_typ") == "host": + obj["obj_ip_end"] = obj.get("obj_ip") + + obj.update({"obj_comment": obj_orig.get("comment")}) + # TODO: deal with all other colors (will be currently ignored) + # we would need a list of fortinet color codes, maybe: + # https://community.fortinet.com/t5/Support-Forum/Object-color-codes-for-CLI/td-p/249479 + obj.update({"obj_color": "black"}) + + obj.update( + {"obj_uid": obj_orig.get("uuid", obj_orig["name"])} + ) # using name as fallback, but this should not happen + + associated_interfaces = find_zones_in_normalized_config( + obj_orig.get("associated-interface", []), normalized_config_adom, normalized_config_global + ) + obj.update({"obj_zone": LIST_DELIMITER.join(associated_interfaces)}) + + nw_objects.append(obj) + + +def _parse_subnet(obj: dict[str, Any], obj_orig: dict[str, Any]) -> None: + ipa = ipaddress.ip_network(str(obj_orig["subnet"][0]) + "/" + str(obj_orig["subnet"][1])) + if ipa.num_addresses > 1: + obj.update({"obj_typ": "network"}) + else: + obj.update({"obj_typ": "host"}) + obj.update({"obj_ip": str(ipa.network_address)}) + obj.update({"obj_ip_end": str(ipa.broadcast_address)}) + + +def normalize_network_object_ipv6(obj_orig: dict[str, Any], obj: dict[str, Any]) -> None: + ipa = ipaddress.ip_network(obj_orig["ip6"]) + if ipa.num_addresses > 1: + obj.update({"obj_typ": "network"}) + else: + obj.update({"obj_typ": "host"}) + obj.update({"obj_ip": str(ipa.network_address)}) + obj.update({"obj_ip_end": str(ipa.broadcast_address)}) + + +def normalize_vip_object(obj_orig: dict[str, Any], obj: dict[str, Any], nw_objects: list[dict[str, Any]]) -> None: + obj_zone = "global" + obj.update({"obj_typ": "host"}) + if "extip" not in obj_orig or len(obj_orig["extip"]) == 0: + FWOLogger.error("vip (extip): found empty extip field for " + obj_orig["name"]) + else: + if len(obj_orig["extip"]) > 1: + FWOLogger.warning( + "vip (extip): found more than one extip, just using the first one for " + obj_orig["name"] + ) + set_ip_in_obj(obj, obj_orig["extip"][0]) # resolving nat range if there is one + nat_obj: dict[str, Any] = {} + nat_obj.update({"obj_typ": "host"}) + nat_obj.update({"obj_color": "black"}) + nat_obj.update({"obj_comment": "FWO-auto-generated nat object for VIP"}) + if ( + "obj_ip_end" in obj + ): # this obj is a range - include the end ip in name and uid as well to avoid akey conflicts + nat_obj.update({"obj_ip_end": str(obj["obj_ip_end"])}) + + normalize_vip_object_nat_ip(obj_orig, obj, nat_obj) + + if "obj_ip_end" not in nat_obj: + nat_obj.update({"obj_ip_end": str(obj["obj_nat_ip"])}) + + if ( + "associated-interface" in obj_orig and len(obj_orig["associated-interface"]) > 0 + ): # and obj_orig['associated-interface'][0] != 'any': + obj_zone = obj_orig["associated-interface"][0] + nat_obj.update({"obj_zone": obj_zone}) + if ( + nat_obj not in nw_objects + ): # rare case when a destination nat is down for two different orig ips to the same dest ip + nw_objects.append(nat_obj) + + +def normalize_vip_object_nat_ip(obj_orig: dict[str, Any], obj: dict[str, Any], nat_obj: dict[str, Any]) -> None: + # now dealing with the nat ip obj (mappedip) + if "mappedip" not in obj_orig or len(obj_orig["mappedip"]) == 0: + FWOLogger.warning("vip (extip): found empty mappedip field for " + obj_orig["name"]) + return + + if len(obj_orig["mappedip"]) > 1: + FWOLogger.warning("vip (extip): found more than one mappedip, just using the first one for " + obj_orig["name"]) + nat_ip = obj_orig["mappedip"][0] + set_ip_in_obj(nat_obj, str(nat_ip)) + obj.update({"obj_nat_ip": str(nat_obj["obj_ip"])}) # save nat ip in vip obj + if ( + "obj_ip_end" in nat_obj + ): # this nat obj is a range - include the end ip in name and uid as well to avoid akey conflicts + obj.update({"obj_nat_ip_end": str(nat_obj["obj_ip_end"])}) # save nat ip in vip obj + nat_obj.update({"obj_name": nat_obj["obj_ip"] + "-" + nat_obj["obj_ip_end"] + NAT_POSTFIX}) + else: + obj.update({"obj_nat_ip_end": str(nat_obj["obj_ip"])}) # assuming host with obj_nat_ip_end = obj_nat_ip + nat_obj.update({"obj_name": nat_obj["obj_ip"] + NAT_POSTFIX}) + nat_obj.update({"obj_uid": nat_obj["obj_name"]}) + ###### range handling + + +def set_ip_in_obj( + nw_obj: dict[str, Any], ip: str +) -> None: # add start and end ip in nw_obj if it is a range, otherwise do nothing + if "-" in ip: # dealing with range + ip_start, ip_end = ip.split("-") + nw_obj.update({"obj_ip": str(ip_start)}) + if ip_end != ip_start: + nw_obj.update({"obj_ip_end": str(ip_end)}) + else: + nw_obj.update({"obj_ip": str(ip)}) + + +# for members of groups, the name of the member obj needs to be fetched separately (starting from API v1.?) +def resolve_nw_uid_to_name(uid: str, nw_objects: list[dict[str, Any]]) -> str: + # return name of nw_objects element where obj_uid = uid + for obj in nw_objects: + if obj["obj_uid"] == uid: + return obj["obj_name"] + return 'ERROR: uid "' + uid + '" not found' + + +def add_member_names_for_nw_group(idx: int, nw_objects: list[dict[str, Any]]) -> None: + group = nw_objects.pop(idx) + if group["obj_member_refs"] == "" or group["obj_member_refs"] is None: + group["obj_member_names"] = None + group["obj_member_refs"] = None + else: + member_names = "" + obj_member_refs = group["obj_member_refs"].split(LIST_DELIMITER) + for ref in obj_member_refs: + member_name = resolve_nw_uid_to_name(ref, nw_objects) + member_names += member_name + LIST_DELIMITER + group["obj_member_names"] = member_names[:-1] + nw_objects.insert(idx, group) + + +def create_network_object( + name: str, obj_type: str, ip: str, ip_end: str | None, uid: str, color: str, comment: str | None, zone: str | None +) -> dict[str, Any]: + return { + "obj_name": name, + "obj_typ": obj_type, + "obj_ip": ip, + "obj_ip_end": ip_end, + "obj_uid": uid, + "obj_color": color, + "obj_comment": comment, + "obj_zone": zone, + } + + +def get_nw_obj(nat_obj_name: str, nwobjects: list[dict[str, Any]]) -> dict[str, Any] | None: + for obj in nwobjects: + if "obj_name" in obj and obj["obj_name"] == nat_obj_name: + return obj + return None + + +# this removes all obj_nat_ip entries from all network objects +# these were used during import but might cause issues if imported into db +def remove_nat_ip_entries(config2import: dict[str, Any]) -> None: + for obj in config2import["network_objects"]: + if "obj_nat_ip" in obj: + obj.pop("obj_nat_ip") + + +def get_first_ip_of_destination(obj_ref: str, config2import: dict[str, Any]) -> str | None: + if LIST_DELIMITER in obj_ref: + obj_ref = obj_ref.split(LIST_DELIMITER, maxsplit=1)[0] + # if destination does not contain exactly one ip, raise a warning + FWOLogger.info( + "src nat behind interface: more than one NAT IP - just using the first one for routing decision for obj_ref " + + obj_ref + ) + + for obj in config2import["network_objects"]: + if "obj_uid" in obj and obj["obj_uid"] == obj_ref: + if "obj_type" in obj and obj["obj_type"] == "group": + if "obj_member_refs" in obj and LIST_DELIMITER in obj["obj_member_refs"]: + return get_first_ip_of_destination(obj["obj_member_refs"].split(LIST_DELIMITER)[0], config2import) + elif "obj_ip" in obj: + return obj["obj_ip"] + FWOLogger.warning("src nat behind interface: found no IP info for destination object " + obj_ref) + return None diff --git a/roles/importer/files/importer/fw_modules/fortiadom5ff/fmgr_rule.py b/roles/importer/files/importer/fw_modules/fortiadom5ff/fmgr_rule.py new file mode 100644 index 0000000000..99c63be7b7 --- /dev/null +++ b/roles/importer/files/importer/fw_modules/fortiadom5ff/fmgr_rule.py @@ -0,0 +1,792 @@ +import copy +import ipaddress +from datetime import datetime, timezone +from typing import Any + +from fw_modules.fortiadom5ff import fmgr_getter +from fw_modules.fortiadom5ff.fmgr_consts import nat_types +from fw_modules.fortiadom5ff.fmgr_zone import find_zones_in_normalized_config +from fwo_const import LIST_DELIMITER +from fwo_exceptions import FwoDeviceWithoutLocalPackageError, FwoImporterErrorInconsistenciesError +from fwo_log import FWOLogger +from models.rule import RuleAction, RuleNormalized, RuleTrack, RuleType +from models.rulebase import Rulebase + +NETWORK_OBJECT = "network_object" +STRING_PKG = "/pkg/" +STRING_PM_CONFIG_GLOBAL_PKG = "/pm/config/global/pkg/" +STRING_PM_CONFIG_ADOM = "/pm/config/adom/" +rule_access_scope_v4 = ["rules_global_header_v4", "rules_adom_v4", "rules_global_footer_v4"] +rule_access_scope_v6 = ["rules_global_header_v6", "rules_adom_v6", "rules_global_footer_v6"] +rule_access_scope = rule_access_scope_v6 + rule_access_scope_v4 +rule_nat_scope = ["rules_global_nat", "rules_adom_nat"] +rule_scope = rule_access_scope + rule_nat_scope + + +def normalize_rulebases( + mgm_uid: str, + native_config: dict[str, Any], + native_config_global: dict[str, Any], + normalized_config_adom: dict[str, Any], + normalized_config_global: dict[str, Any], + is_global_loop_iteration: bool, +) -> None: + normalized_config_adom["policies"] = [] + fetched_rulebase_uids: list[str] = [] + if normalized_config_global != {}: + fetched_rulebase_uids = [ + normalized_rulebase_global.uid + for normalized_rulebase_global in normalized_config_global.get("policies", []) + ] + for gateway in native_config["gateways"]: + normalize_rulebases_for_each_link_destination( + gateway, + mgm_uid, + fetched_rulebase_uids, + native_config, + native_config_global, + is_global_loop_iteration, + normalized_config_adom, + normalized_config_global, + ) + + +def normalize_rulebases_for_each_link_destination( + gateway: dict[str, Any], + mgm_uid: str, + fetched_rulebase_uids: list[str], + native_config: dict[str, Any], + native_config_global: dict[str, Any], + is_global_loop_iteration: bool, + normalized_config_adom: dict[str, Any], + normalized_config_global: dict[str, Any], +): + for rulebase_link in gateway["rulebase_links"]: + if rulebase_link["to_rulebase_uid"] not in fetched_rulebase_uids and rulebase_link["to_rulebase_uid"] != "": + rulebase_to_parse = find_rulebase_to_parse(native_config["rulebases"], rulebase_link["to_rulebase_uid"]) + # search in global rulebase + found_rulebase_in_global = False + if rulebase_to_parse == {} and not is_global_loop_iteration and native_config_global != {}: + rulebase_to_parse = find_rulebase_to_parse( + native_config_global["rulebases"], rulebase_link["to_rulebase_uid"] + ) + found_rulebase_in_global = True + if rulebase_to_parse == {}: + FWOLogger.warning("found to_rulebase link without rulebase in nativeConfig: " + str(rulebase_link)) + continue + + normalized_rulebase = initialize_normalized_rulebase(rulebase_to_parse, mgm_uid) + parse_rulebase( + normalized_config_adom, + normalized_config_global, + rulebase_to_parse, + normalized_rulebase, + found_rulebase_in_global, + ) + fetched_rulebase_uids.append(rulebase_link["to_rulebase_uid"]) + + if found_rulebase_in_global: + normalized_config_global["policies"].append(normalized_rulebase) + else: + normalized_config_adom["policies"].append(normalized_rulebase) + + # normalizing nat rulebases is work in progress + # normalize_nat_rulebase(rulebase_link, native_config, normalized_config_adom, normalized_config_global) # noqa: ERA001 + + +def normalize_nat_rulebase( + rulebase_link: dict[str, Any], + native_config: dict[str, Any], + normalized_config_adom: dict[str, Any], + normalized_config_global: dict[str, Any], +): + if not rulebase_link["is_section"]: + for nat_type in nat_types: + nat_type_string = nat_type + "_" + rulebase_link["to_rulebase_uid"] + nat_rulebase = get_native_nat_rulebase(native_config, nat_type_string) + parse_nat_rulebase(nat_rulebase, nat_type_string, normalized_config_adom, normalized_config_global) + + +def get_native_nat_rulebase(native_config: dict[str, Any], nat_type_string: str) -> list[dict[str, Any]]: + for nat_rulebase in native_config["nat_rulebases"]: + if nat_type_string == nat_rulebase["type"]: + return nat_rulebase["data"] + FWOLogger.warning("no nat data for " + nat_type_string) + return [] + + +def find_rulebase_to_parse(rulebase_list: list[dict[str, Any]], rulebase_uid: str) -> dict[str, Any]: + for rulebase in rulebase_list: + if rulebase["uid"] == rulebase_uid: + return rulebase + return {} + + +def initialize_normalized_rulebase(rulebase_to_parse: dict[str, Any], mgm_uid: str) -> Rulebase: + """ + We use 'type' as uid/name since a rulebase may have a v4 and a v6 part + """ + rulebase_name = rulebase_to_parse["type"] + rulebase_uid = rulebase_to_parse["type"] + return Rulebase(uid=rulebase_uid, name=rulebase_name, mgm_uid=mgm_uid, rules={}) + + +def parse_rulebase( + normalized_config_adom: dict[str, Any], + normalized_config_global: dict[str, Any], + rulebase_to_parse: dict[str, Any], + normalized_rulebase: Rulebase, + found_rulebase_in_global: bool, +): + """Parses a native Fortinet rulebase into a normalized rulebase.""" + for native_rule in rulebase_to_parse["data"]: + parse_single_rule(normalized_config_adom, normalized_config_global, native_rule, normalized_rulebase) + if not found_rulebase_in_global: + add_implicit_deny_rule(normalized_config_adom, normalized_config_global, normalized_rulebase) + + +def add_implicit_deny_rule( + normalized_config_adom: dict[str, Any], normalized_config_global: dict[str, Any], rulebase: Rulebase +): + deny_rule = { + "srcaddr": ["all"], + "srcaddr6": ["all"], + "dstaddr": ["all"], + "dstaddr6": ["all"], + "service": ["ALL"], + "srcintf": ["any"], + "dstintf": ["any"], + } + + rule_src_list, rule_src_refs_list = rule_parse_addresses( + deny_rule, "src", normalized_config_adom, normalized_config_global, is_nat=False + ) + rule_dst_list, rule_dst_refs_list = rule_parse_addresses( + deny_rule, "dst", normalized_config_adom, normalized_config_global, is_nat=False + ) + rule_svc_list, rule_svc_refs_list = rule_parse_service(deny_rule) + rule_src_zones = find_zones_in_normalized_config( + deny_rule.get("srcintf", []), normalized_config_adom, normalized_config_global + ) + rule_dst_zones = find_zones_in_normalized_config( + deny_rule.get("dstintf", []), normalized_config_adom, normalized_config_global + ) + + rule_normalized = RuleNormalized( + rule_num=0, + rule_num_numeric=0, + rule_disabled=False, + rule_src_neg=False, + rule_src=LIST_DELIMITER.join(rule_src_list), + rule_src_refs=LIST_DELIMITER.join(rule_src_refs_list), + rule_dst_neg=False, + rule_dst=LIST_DELIMITER.join(rule_dst_list), + rule_dst_refs=LIST_DELIMITER.join(rule_dst_refs_list), + rule_svc_neg=False, + rule_svc=LIST_DELIMITER.join(rule_svc_list), + rule_svc_refs=LIST_DELIMITER.join(rule_svc_refs_list), + rule_action=RuleAction.DROP, + rule_track=RuleTrack.NONE, # I guess this could also have different values + rule_installon=None, + rule_time=None, # Time-based rules not commonly used in basic Fortinet configs + rule_name="Implicit Deny", + rule_uid=f"{rulebase.uid}_implicit_deny", + rule_custom_fields=str({}), + rule_implied=True, + rule_type=RuleType.ACCESS, + last_change_admin=None, + parent_rule_uid=None, + last_hit=None, + rule_comment=None, + rule_src_zone=LIST_DELIMITER.join(rule_src_zones), + rule_dst_zone=LIST_DELIMITER.join(rule_dst_zones), + rule_head_text=None, + ) + + if rule_normalized.rule_uid is None: + raise FwoImporterErrorInconsistenciesError("rule_normalized.rule_uid is None when adding implicit deny rule") + rulebase.rules[rule_normalized.rule_uid] = rule_normalized + + +def parse_single_rule( + normalized_config_adom: dict[str, Any], + normalized_config_global: dict[str, Any], + native_rule: dict[str, Any], + rulebase: Rulebase, +): + """Parses a single native Fortinet rule into a normalized rule and adds it to the given rulebase.""" + # Extract basic rule information + rule_disabled = True # Default to disabled + if "status" in native_rule and (native_rule["status"] == 1 or native_rule["status"] == "enable"): + rule_disabled = False + + rule_action = rule_parse_action(native_rule) + + rule_track = rule_parse_tracking_info(native_rule) + + rule_src_list, rule_src_refs_list = rule_parse_addresses( + native_rule, "src", normalized_config_adom, normalized_config_global, is_nat=False + ) + rule_dst_list, rule_dst_refs_list = rule_parse_addresses( + native_rule, "dst", normalized_config_adom, normalized_config_global, is_nat=False + ) + + rule_svc_list, rule_svc_refs_list = rule_parse_service(native_rule) + + rule_src_zones = find_zones_in_normalized_config( + native_rule.get("srcintf", []), normalized_config_adom, normalized_config_global + ) + rule_dst_zones = find_zones_in_normalized_config( + native_rule.get("dstintf", []), normalized_config_adom, normalized_config_global + ) + + rule_src_neg, rule_dst_neg, rule_svc_neg = rule_parse_negation_flags(native_rule) + rule_installon = rule_parse_installon(native_rule) + + last_hit = rule_parse_last_hit(native_rule) + + time = rule_parse_time(native_rule) + + # Create the normalized rule + rule_normalized = RuleNormalized( + rule_num=0, + rule_num_numeric=0, + rule_disabled=rule_disabled, + rule_src_neg=rule_src_neg, + rule_src=LIST_DELIMITER.join(rule_src_list), + rule_src_refs=LIST_DELIMITER.join(rule_src_refs_list), + rule_dst_neg=rule_dst_neg, + rule_dst=LIST_DELIMITER.join(rule_dst_list), + rule_dst_refs=LIST_DELIMITER.join(rule_dst_refs_list), + rule_svc_neg=rule_svc_neg, + rule_svc=LIST_DELIMITER.join(rule_svc_list), + rule_svc_refs=LIST_DELIMITER.join(rule_svc_refs_list), + rule_action=rule_action, + rule_track=rule_track, + rule_installon=rule_installon, + rule_time=time, + rule_name=native_rule.get("name"), + rule_uid=native_rule.get("uuid"), + rule_custom_fields=str(native_rule.get("meta fields", {})), + rule_implied=False, + rule_type=RuleType.ACCESS, + last_change_admin=None, # native_rule.get('_last-modified-by', ''), not handled yet -> leave out to prevent mismatches + parent_rule_uid=None, + last_hit=last_hit, + rule_comment=native_rule.get("comments"), + rule_src_zone=LIST_DELIMITER.join(rule_src_zones), + rule_dst_zone=LIST_DELIMITER.join(rule_dst_zones), + rule_head_text=None, + ) + if rule_normalized.rule_uid is None: + raise FwoImporterErrorInconsistenciesError("rule_normalized.rule_uid is None when parsing single rule") + + # Add the rule to the rulebase + rulebase.rules[rule_normalized.rule_uid] = rule_normalized + + # TODO: handle combined NAT, see handle_combined_nat_rule + + +def rule_parse_action(native_rule: dict[str, Any]) -> RuleAction: + # Extract action - Fortinet uses 0 for deny/drop, 1 for accept + if native_rule.get("action", 0) == 0: + return RuleAction.DROP + return RuleAction.ACCEPT + + +def rule_parse_tracking_info(native_rule: dict[str, Any]) -> RuleTrack: + # TODO: Implement more detailed logging level extraction (difference between 1/2/3?) + logtraffic = native_rule.get("logtraffic", 0) + if (isinstance(logtraffic, int) and logtraffic > 0) or (isinstance(logtraffic, str) and logtraffic != "disable"): + return RuleTrack.LOG + return RuleTrack.NONE + + +def rule_parse_service(native_rule: dict[str, Any]) -> tuple[list[str], list[str]]: + """ + Parses services to ordered (!) name list and reference list. + """ + rule_svc_list: list[str] = [] + rule_svc_refs_list: list[str] = [] + for svc in sorted(native_rule.get("service", [])): + rule_svc_list.append(svc) + rule_svc_refs_list.append(svc) + if rule_svc_list == [] and "internet-service-name" in native_rule and len(native_rule["internet-service-name"]) > 0: + rule_svc_list.append("ALL") + rule_svc_refs_list.append("ALL") + if ( + rule_svc_list == [] + and "internet-service-src-name" in native_rule + and len(native_rule["internet-service-src-name"]) > 0 + ): + rule_svc_list.append("ALL") + rule_svc_refs_list.append("ALL") + + return rule_svc_list, rule_svc_refs_list + + +def rule_parse_addresses( + native_rule: dict[str, Any], + target: str, + normalized_config_adom: dict[str, Any], + normalized_config_global: dict[str, Any], + is_nat: bool, +) -> tuple[list[str], list[str]]: + """ + Parses addresses to ordered (!) name list and reference list for source or destination addresses. + """ + if target not in ["src", "dst"]: + raise FwoImporterErrorInconsistenciesError(f"target '{target}' must either be src or dst.") + addr_list: list[str] = [] + addr_ref_list: list[str] = [] + if not is_nat: + build_addr_list( + native_rule, target, normalized_config_adom, normalized_config_global, addr_list, addr_ref_list, is_v4=True + ) + build_addr_list( + native_rule, target, normalized_config_adom, normalized_config_global, addr_list, addr_ref_list, is_v4=False + ) + else: + build_nat_addr_list( + native_rule, target, normalized_config_adom, normalized_config_global, addr_list, addr_ref_list + ) + return addr_list, addr_ref_list + + +def build_addr_list( + native_rule: dict[str, Any], + target: str, + normalized_config_adom: dict[str, Any], + normalized_config_global: dict[str, Any], + addr_list: list[str], + addr_ref_list: list[str], + is_v4: bool, +) -> None: + """ + Builds ordered (!) address list and address reference list for source or destination addresses. + """ + if is_v4 and target == "src": + for addr in sorted(native_rule.get("srcaddr", [])) + sorted(native_rule.get("internet-service-src-name", [])): + addr_list.append(addr) + addr_ref_list.append(find_addr_ref(addr, is_v4, normalized_config_adom, normalized_config_global)) + elif not is_v4 and target == "src": + for addr in sorted(native_rule.get("srcaddr6", [])): + addr_list.append(addr) + addr_ref_list.append(find_addr_ref(addr, is_v4, normalized_config_adom, normalized_config_global)) + elif is_v4 and target == "dst": + for addr in sorted(native_rule.get("dstaddr", [])) + sorted(native_rule.get("internet-service-name", [])): + addr_list.append(addr) + addr_ref_list.append(find_addr_ref(addr, is_v4, normalized_config_adom, normalized_config_global)) + else: + for addr in sorted(native_rule.get("dstaddr6", [])): + addr_list.append(addr) + addr_ref_list.append(find_addr_ref(addr, is_v4, normalized_config_adom, normalized_config_global)) + + +def build_nat_addr_list( + native_rule: dict[str, Any], + target: str, + normalized_config_adom: dict[str, Any], + normalized_config_global: dict[str, Any], + addr_list: list[str], + addr_ref_list: list[str], +) -> None: + # so far only ip v4 expected + if target == "src": + for addr in sorted(native_rule.get("orig-addr", [])): + addr_list.append(addr) + addr_ref_list.append( + find_addr_ref( + addr, + is_v4=True, + normalized_config_adom=normalized_config_adom, + normalized_config_global=normalized_config_global, + ) + ) + if target == "dst": + for addr in sorted(native_rule.get("dst-addr", [])): + addr_list.append(addr) + addr_ref_list.append( + find_addr_ref( + addr, + is_v4=True, + normalized_config_adom=normalized_config_adom, + normalized_config_global=normalized_config_global, + ) + ) + + +def find_addr_ref( + addr: str, is_v4: bool, normalized_config_adom: dict[str, Any], normalized_config_global: dict[str, Any] +) -> str: + for nw_obj in normalized_config_adom["network_objects"] + normalized_config_global.get("network_objects", []): + if addr == nw_obj["obj_name"] and ((is_v4 and ip_type(nw_obj) == 4) or (not is_v4 and ip_type(nw_obj) == 6)): # noqa: PLR2004 + return nw_obj["obj_uid"] + raise FwoImporterErrorInconsistenciesError(f"No ref found for '{addr}'.") + + +def ip_type(nw_obj: dict[str, Any]) -> int: + # default to v4 + first_ip = nw_obj.get("obj_ip", "0.0.0.0/32") + if first_ip == "": + first_ip = "0.0.0.0/32" + net = ipaddress.ip_network(str(first_ip)) + return net.version + + +def rule_parse_negation_flags(native_rule: dict[str, Any]) -> tuple[bool, bool, bool]: + # if customer decides to mix internet-service and "normal" addr obj in src/dst and mix negates this will prob. not work correctly + if "srcaddr-negate" in native_rule: + rule_src_neg = native_rule["srcaddr-negate"] == 1 or native_rule["srcaddr-negate"] == "disable" + elif "internet-service-src-negate" in native_rule: + rule_src_neg = ( + native_rule["internet-service-src-negate"] == 1 or native_rule["internet-service-src-negate"] == "disable" + ) + else: + rule_src_neg = False + rule_dst_neg = "dstaddr-negate" in native_rule and ( + native_rule["dstaddr-negate"] == 1 or native_rule["dstaddr-negate"] == "disable" + ) # TODO: last part does not make sense? + rule_svc_neg = "service-negate" in native_rule and ( + native_rule["service-negate"] == 1 or native_rule["service-negate"] == "disable" + ) + return rule_src_neg, rule_dst_neg, rule_svc_neg + + +def rule_parse_installon(native_rule: dict[str, Any]) -> str | None: + rule_installon = None + if native_rule.get("scope_member"): + rule_installon = LIST_DELIMITER.join( + sorted({vdom["name"] + "_" + vdom["vdom"] for vdom in native_rule["scope_member"]}) + ) + return rule_installon + + +def rule_parse_last_hit(native_rule: dict[str, Any]) -> str | None: + last_hit = native_rule.get("_last_hit") + if last_hit is not None: + # FortiManager reports epoch seconds; preserve the local offset in the serialized value. + last_hit = datetime.fromtimestamp(float(last_hit), tz=timezone.utc).astimezone().isoformat(timespec="seconds") + return last_hit + + +def rule_parse_time(native_rule: dict[str, Any]) -> str | None: + schedule: list[str] | None = native_rule.get("schedule") + + if schedule is None: + return None + + return "|".join(schedule) + + +def get_access_policy( + sid: str, + fm_api_url: str, + native_config_adom: dict[str, Any], + native_config_global: dict[str, Any], + adom_device_vdom_policy_package_structure: dict[str, Any], + adom_name: str, + mgm_details_device: dict[str, Any], + device_config: dict[str, Any], + limit: int, +): + previous_rulebase = None + link_list: list[Any] = [] + local_pkg_name, global_pkg_name = find_packages( + adom_device_vdom_policy_package_structure, adom_name, mgm_details_device + ) + options = ["extra info", "scope member", "get meta"] + + previous_rulebase = get_and_link_global_rulebase( + "header", previous_rulebase, global_pkg_name, native_config_global, sid, fm_api_url, options, limit, link_list + ) + + previous_rulebase = get_and_link_local_rulebase( + "rules_adom", + previous_rulebase, + adom_name, + local_pkg_name, + native_config_adom, + sid, + fm_api_url, + options, + limit, + link_list, + ) + + previous_rulebase = get_and_link_global_rulebase( + "footer", previous_rulebase, global_pkg_name, native_config_global, sid, fm_api_url, options, limit, link_list + ) + + device_config["rulebase_links"].extend(link_list) + + +def get_and_link_global_rulebase( + header_or_footer: str, + previous_rulebase: str | None, + global_pkg_name: str, + native_config_global: dict[str, Any], + sid: str, + fm_api_url: str, + options: list[str], + limit: int, + link_list: list[Any], +) -> Any: + rulebase_type_prefix = "rules_global_" + header_or_footer + if global_pkg_name != "": + if not is_rulebase_already_fetched( + native_config_global["rulebases"], rulebase_type_prefix + "_v4_" + global_pkg_name + ): + fmgr_getter.update_config_with_fortinet_api_call( + native_config_global["rulebases"], + sid, + fm_api_url, + STRING_PM_CONFIG_GLOBAL_PKG + global_pkg_name + "/global/" + header_or_footer + "/policy", + rulebase_type_prefix + "_v4_" + global_pkg_name, + options=options, + limit=limit, + ) + if not is_rulebase_already_fetched( + native_config_global["rulebases"], rulebase_type_prefix + "_v6_" + global_pkg_name + ): + # delete_v: hier auch options=options? + fmgr_getter.update_config_with_fortinet_api_call( + native_config_global["rulebases"], + sid, + fm_api_url, + STRING_PM_CONFIG_GLOBAL_PKG + global_pkg_name + "/global/" + header_or_footer + "/policy6", + rulebase_type_prefix + "_v6_" + global_pkg_name, + limit=limit, + ) + previous_rulebase = link_rulebase( + link_list, + native_config_global["rulebases"], + global_pkg_name, + rulebase_type_prefix, + previous_rulebase, + is_global=True, + ) + return previous_rulebase + + +def get_and_link_local_rulebase( + rulebase_type_prefix: str, + previous_rulebase: str | None, + adom_name: str, + local_pkg_name: str, + native_config_adom: dict[str, Any], + sid: str, + fm_api_url: str, + options: list[str], + limit: int, + link_list: list[Any], +) -> Any: + if not is_rulebase_already_fetched(native_config_adom["rulebases"], rulebase_type_prefix + "_v4_" + local_pkg_name): + fmgr_getter.update_config_with_fortinet_api_call( + native_config_adom["rulebases"], + sid, + fm_api_url, + STRING_PM_CONFIG_ADOM + adom_name + STRING_PKG + local_pkg_name + "/firewall/policy", + rulebase_type_prefix + "_v4_" + local_pkg_name, + options=options, + limit=limit, + ) + if not is_rulebase_already_fetched(native_config_adom["rulebases"], rulebase_type_prefix + "_v6_" + local_pkg_name): + fmgr_getter.update_config_with_fortinet_api_call( + native_config_adom["rulebases"], + sid, + fm_api_url, + STRING_PM_CONFIG_ADOM + adom_name + STRING_PKG + local_pkg_name + "/firewall/policy6", + rulebase_type_prefix + "_v6_" + local_pkg_name, + limit=limit, + ) + return link_rulebase( + link_list, + native_config_adom["rulebases"], + local_pkg_name, + rulebase_type_prefix, + previous_rulebase, + is_global=False, + ) + + +def find_packages( + adom_device_vdom_policy_package_structure: dict[str, Any], adom_name: str, mgm_details_device: dict[str, Any] +) -> tuple[str, str]: + for device in adom_device_vdom_policy_package_structure[adom_name]: + for vdom in adom_device_vdom_policy_package_structure[adom_name][device]: + if mgm_details_device["name"] == device + "_" + vdom: + device_dict = adom_device_vdom_policy_package_structure[adom_name][device] + if ( + "local" in device_dict[vdom] + and "global" in adom_device_vdom_policy_package_structure[adom_name][device][vdom] + ): + return device_dict[vdom]["local"], adom_device_vdom_policy_package_structure[adom_name][device][ + vdom + ]["global"] + return "", "" + raise FwoDeviceWithoutLocalPackageError( + "Could not find local package for " + mgm_details_device["name"] + " in Fortimanager Config" + ) from None + + +def is_rulebase_already_fetched(rulebases: list[dict[str, Any]], typ: str) -> bool: + return any(rulebase["type"] == typ for rulebase in rulebases) + + +def link_rulebase( + link_list: list[Any], + rulebases: list[dict[str, Any]], + pkg_name: str, + rulebase_type_prefix: str, + previous_rulebase: str | None, + is_global: bool, +) -> str | None: + for version in ["v4", "v6"]: + full_pkg_name = rulebase_type_prefix + "_" + version + "_" + pkg_name + has_data = has_rulebase_data(rulebases, full_pkg_name, is_global, version, pkg_name) + if has_data: + link_list.append(build_link(previous_rulebase, full_pkg_name, is_global)) + previous_rulebase = full_pkg_name + + return previous_rulebase + + +def build_link(previous_rulebase: str | None, full_pkg_name: str, is_global: bool) -> dict[str, Any]: + if previous_rulebase is None: + is_initial = True + previous_rulebase = None + else: + is_initial = False + return { + "from_rulebase_uid": previous_rulebase, + "from_rule_uid": None, + "to_rulebase_uid": full_pkg_name, + "type": "ordered", + "is_global": is_global, + "is_initial": is_initial, + "is_section": False, + } + + +def has_rulebase_data( + rulebases: list[dict[str, Any]], full_pkg_name: str, is_global: bool, version: str, pkg_name: str +) -> bool: + """Adds name and uid to rulebase and removes empty global rulebases""" + has_data = False + is_v4 = version == "v4" + for rulebase in rulebases: + if rulebase["type"] == full_pkg_name: + rulebase.update( + { + "name": full_pkg_name, + "uid": full_pkg_name, + "is_global": is_global, + "is_v4": is_v4, + "package": pkg_name, + } + ) + if len(rulebase["data"]) > 0: + has_data = True + elif is_global: + rulebases.remove(rulebase) + return has_data + + +def get_nat_policy( + sid: str, + fm_api_url: str, + native_config: dict[str, Any], + adom_device_vdom_policy_package_structure: dict[str, Any], + adom_name: str, + mgm_details_device: dict[str, Any], + limit: int, +): + local_pkg_name, global_pkg_name = find_packages( + adom_device_vdom_policy_package_structure, adom_name, mgm_details_device + ) + if adom_name == "": + for nat_type in nat_types: + fmgr_getter.update_config_with_fortinet_api_call( + native_config["nat_rulebases"], + sid, + fm_api_url, + STRING_PM_CONFIG_GLOBAL_PKG + global_pkg_name + "/" + nat_type, + nat_type + "_global_" + global_pkg_name, + limit=limit, + ) + else: + for nat_type in nat_types: + fmgr_getter.update_config_with_fortinet_api_call( + native_config["nat_rulebases"], + sid, + fm_api_url, + STRING_PM_CONFIG_ADOM + adom_name + STRING_PKG + local_pkg_name + "/" + nat_type, + nat_type + "_adom_" + adom_name + "_" + local_pkg_name, + limit=limit, + ) + + +# delete_v: ab hier kann sehr viel weg, ich lasses vorerst zB für die nat +# pure nat rules + + +def parse_nat_rulebase( + _nat_rulebase: list[dict[str, Any]], + _nat_type_string: str, + _normalized_config_adom: dict[str, Any], + _normalized_config_global: dict[str, Any], +) -> None: + # this function is not called until it is ready check git commit for reference + return + + +def create_xlate_rule(rule: dict[str, Any]) -> dict[str, Any]: + xlate_rule = copy.deepcopy(rule) + rule["rule_type"] = "combined" + xlate_rule["rule_type"] = "xlate" + xlate_rule["rule_comment"] = None + xlate_rule["rule_disabled"] = False + xlate_rule["rule_src"] = "Original" + xlate_rule["rule_src_refs"] = "Original" + xlate_rule["rule_dst"] = "Original" + xlate_rule["rule_dst_refs"] = "Original" + xlate_rule["rule_svc"] = "Original" + xlate_rule["rule_svc_refs"] = "Original" + return xlate_rule + + +def handle_combined_nat_rule( + rule: dict[str, Any], rule_orig: dict[str, Any], config2import: dict[str, Any], nat_rule_number: int, dev_id: int +) -> dict[str, Any] | None: + # TODO: see fOS_rule for reference implementation + raise NotImplementedError("handle_combined_nat_rule is not implemented yet") + + +def extract_nat_objects(nwobj_list: list[str], all_nwobjects: list[dict[str, str]]) -> list[dict[str, str]]: + nat_obj_list: list[dict[str, str]] = [] + for obj in nwobj_list: + for obj2 in all_nwobjects: + if obj2["obj_name"] == obj: + if "obj_nat_ip" in obj2: + nat_obj_list.append(obj2) + break + return nat_obj_list + + +def add_users_to_rule(rule_orig: dict[str, Any], rule: dict[str, Any]) -> None: + if "groups" in rule_orig: + add_users(rule_orig["groups"], rule) + if "users" in rule_orig: + add_users(rule_orig["users"], rule) + + +def add_users(users: list[str], rule: dict[str, Any]) -> None: + for user in users: + rule_src_with_users = [user + "@" + src for src in rule["rule_src"].split(LIST_DELIMITER)] + + rule["rule_src"] = LIST_DELIMITER.join(rule_src_with_users) + + # here user ref is the user name itself + rule_src_refs_with_users = [user + "@" + src for src in rule["rule_src_refs"].split(LIST_DELIMITER)] + rule["rule_src_refs"] = LIST_DELIMITER.join(rule_src_refs_with_users) diff --git a/roles/importer/files/importer/fw_modules/fortiadom5ff/fmgr_service.py b/roles/importer/files/importer/fw_modules/fortiadom5ff/fmgr_service.py new file mode 100644 index 0000000000..959a8bed51 --- /dev/null +++ b/roles/importer/files/importer/fw_modules/fortiadom5ff/fmgr_service.py @@ -0,0 +1,274 @@ +import re +from typing import Any + +from fwo_base import sort_and_join +from fwo_const import LIST_DELIMITER + + +def normalize_service_objects( + native_config: dict[str, Any], normalized_config_adom: dict[str, Any], svc_obj_types: list[str] +) -> None: + svc_objects: list[dict[str, Any]] = [] + + if "objects" not in native_config: + return # no objects to normalize + for current_obj_type in native_config["objects"]: + if not (current_obj_type in svc_obj_types and "data" in native_config["objects"][current_obj_type]): + continue + for obj_orig in native_config["objects"][current_obj_type]["data"]: + normalize_service_object(obj_orig, svc_objects) + + if native_config.get("is-super-manager", False): + # finally add "Original" service object for natting (global domain only) + original_obj_name = "Original" + svc_objects.append( + create_svc_object( + name=original_obj_name, + proto=0, + color="foreground", + port=None, + comment='"original" service object created by FWO importer for NAT purposes', + ) + ) + + normalized_config_adom.update({"service_objects": svc_objects}) + + +def normalize_service_object(obj_orig: dict[str, Any], svc_objects: list[dict[str, Any]]) -> None: + member_names = "" + if "member" in obj_orig: + svc_type = "group" + for member in obj_orig["member"]: + member_names += member + LIST_DELIMITER + member_names = member_names[:-1] + else: + svc_type = "simple" + + name = None + if "name" in obj_orig: + name = str(obj_orig["name"]) + + if name is None: + raise ValueError("Service object without name encountered") + + color = "foreground" # TODO: color mapping. what is color: 0? (nativeconfig entwickler_fortimanager_stand_2025-07-27, service object 'gALL') + + session_timeout = None # TODO: find the right timer + + if "protocol" in obj_orig: + handle_svc_protocol(obj_orig, svc_objects, svc_type, name, color, session_timeout) + elif svc_type == "group": + add_object(svc_objects, svc_type, name, color, 0, None, member_names, session_timeout) + else: + add_object(svc_objects, svc_type, name, color, 0, None, None, session_timeout) + + +def handle_svc_protocol( + obj_orig: dict[str, Any], + svc_objects: list[dict[str, Any]], + svc_type: str, + name: str, + color: str, + session_timeout: Any, +) -> None: + proto = 0 + range_names = "" + added_svc_obj = 0 + + # forti uses strange protocol numbers, so we need to map them + + match obj_orig["protocol"]: + case 1: + add_object(svc_objects, svc_type, name, color, 1, None, None, session_timeout) + added_svc_obj += 1 + case 2: + if "protocol-number" in obj_orig: + proto = obj_orig["protocol-number"] + add_object(svc_objects, svc_type, name, color, proto, None, None, session_timeout) + added_svc_obj += 1 + case 5 | 11 | 15: # magic numbers from FortiNet: 5 = TCP/UDP, 11 = TCP/UDP/SCTP, 15 = TCP/UDP/SCTP/ICMP + parse_standard_protocols_with_ports( + obj_orig, svc_objects, svc_type, name, color, session_timeout, range_names, added_svc_obj + ) + case 6: + add_object(svc_objects, svc_type, name, color, 58, None, None, session_timeout) + case _: + pass # not doing anything for other protocols, e.g. GRE, ESP, ... + + +def parse_standard_protocols_with_ports( + obj_orig: dict[str, Any], + svc_objects: list[dict[str, Any]], + svc_type: str, + name: str, + color: str, + session_timeout: Any, + range_names: str, + added_svc_obj: int, +) -> None: + split = check_split(obj_orig) + if "tcp-portrange" in obj_orig and len(obj_orig["tcp-portrange"]) > 0: + tcpname = name + if split: + tcpname += "_tcp" + range_names += tcpname + LIST_DELIMITER + add_object(svc_objects, svc_type, tcpname, color, 6, obj_orig["tcp-portrange"], None, session_timeout) + added_svc_obj += 1 + if "udp-portrange" in obj_orig and len(obj_orig["udp-portrange"]) > 0: + udpname = name + if split: + udpname += "_udp" + range_names += udpname + LIST_DELIMITER + add_object(svc_objects, svc_type, udpname, color, 17, obj_orig["udp-portrange"], None, session_timeout) + added_svc_obj += 1 + if "sctp-portrange" in obj_orig and len(obj_orig["sctp-portrange"]) > 0: + sctpname = name + if split: + sctpname += "_sctp" + range_names += sctpname + LIST_DELIMITER + add_object(svc_objects, svc_type, sctpname, color, 132, obj_orig["sctp-portrange"], None, session_timeout) + added_svc_obj += 1 + if split: + range_names = range_names[:-1] + add_object(svc_objects, "group", name, color, 0, None, range_names, session_timeout) + added_svc_obj += 1 + if added_svc_obj == 0: # assuming RPC service which here has no properties at all + add_object(svc_objects, "rpc", name, color, 0, None, None, None) + added_svc_obj += 1 + + +def check_split(obj_orig: dict[str, Any]) -> bool: + count = 0 + if "tcp-portrange" in obj_orig and len(obj_orig["tcp-portrange"]) > 0: + count += 1 + if "udp-portrange" in obj_orig and len(obj_orig["udp-portrange"]) > 0: + count += 1 + if "sctp-portrange" in obj_orig and len(obj_orig["sctp-portrange"]) > 0: + count += 1 + return count > 1 + + +def extract_ports(port_ranges: list[str] | None) -> "tuple[list[Any], list[Any]]": + ports: list[Any] = [] + port_ends: list[Any] = [] + if port_ranges is not None and len(port_ranges) > 0: + for port_range in port_ranges: + # remove src-ports + port = port_range.split(":")[0] + port_end = port + + # open ranges (not found so far in data) + pattern = re.compile(r"^\>(\d+)$") + match = pattern.match(port) + if match: + port = str(int(match.group()[1:]) + 1) + port_end = str(65535) + pattern = re.compile(r"^\<(\d+)$") + match = pattern.match(port) + if match: + port = str(1) + port_end = str(int(match.group()[1:]) - 1) + + # split ranges + pattern = re.compile(r"^(\d+)\-(\d+)$") + match = pattern.match(port) + if match: + port, port_end = match.group().split("-") + ports.append(port) + port_ends.append(port_end) + return ports, port_ends + + +def create_svc_object(name: str, proto: int, color: str, port: Any, comment: str) -> "dict[str, Any]": + return { + "svc_name": name, + "svc_typ": "simple", + "svc_port": port, + "ip_proto": proto, + "svc_color": color, + "svc_uid": name, # services have no uid in fortimanager + "svc_comment": comment, + } + + +def add_object( + svc_objects: list[dict[str, Any]], + typ: str, + name: str, + color: str, + proto: int, + port_ranges: list[str] | None, + member_names: str | None, + session_timeout: Any, +) -> None: + if member_names: + member_names = sort_and_join( + member_names.split(LIST_DELIMITER) + ) # TODO: sorting should be done earlier on actual list + if port_ranges is None: + svc_objects.extend( + [ + { + "svc_typ": typ, + "svc_name": name, + "svc_color": color, + "svc_uid": name, # ? + "svc_comment": None, # ? + "ip_proto": proto, + "svc_port": None, + "svc_port_end": None, + "svc_member_refs": member_names, # ? + "svc_member_names": member_names, + "svc_timeout": session_timeout, + "rpc_nr": None, # ? + } + ] + ) + else: + range_names = "" + ports, port_ends = extract_ports(port_ranges) + split = len(ports) > 1 + for index, port in enumerate(ports): + port_end = port_ends[index] + full_name = name + if split: + full_name += "_" + str(port) + range_names += full_name + LIST_DELIMITER + svc_objects.extend( + [ + { + "svc_typ": typ, + "svc_name": full_name, + "svc_color": color, + "svc_uid": full_name, # ? + "svc_comment": None, # ? + "ip_proto": proto, + "svc_port": port, + "svc_port_end": port_end, + "svc_member_refs": member_names, # ? + "svc_member_names": member_names, + "svc_timeout": session_timeout, + "rpc_nr": None, # ? + } + ] + ) + if split: + range_names = range_names[:-1] + svc_objects.extend( + [ + { + "svc_typ": "group", + "svc_name": name, + "svc_color": color, + "svc_uid": name, # ? + "svc_comment": None, # ? + "ip_proto": proto, + "svc_port": None, + "svc_port_end": None, + "svc_member_refs": range_names, # ? + "svc_member_names": range_names, + "svc_timeout": session_timeout, + "rpc_nr": None, # ? + } + ] + ) diff --git a/roles/importer/files/importer/fw_modules/fortiadom5ff/fmgr_user.py b/roles/importer/files/importer/fw_modules/fortiadom5ff/fmgr_user.py new file mode 100644 index 0000000000..59380c4791 --- /dev/null +++ b/roles/importer/files/importer/fw_modules/fortiadom5ff/fmgr_user.py @@ -0,0 +1,51 @@ +from typing import Any + +from fwo_const import LIST_DELIMITER + + +# TODO: unused function +def normalize_users( + full_config: dict[str, list[dict[str, Any]]], config2import: dict[str, list[dict[str, Any]]], user_scope: list[str] +) -> None: + users: list[dict[str, Any]] = [] + for scope in user_scope: + for user_orig in full_config[scope]: + user_normalized = _parse_user(user_orig) + users.append(user_normalized) + + config2import.update({"user_objects": users}) + + +def _parse_user(user_orig: dict[str, Any]) -> dict[str, Any]: + name = None + svc_type = "simple" + color = None + member_names = None + comment = None + user: dict[str, Any] = {} + if "member" in user_orig: + svc_type = "group" + member_names = "" + for member in user_orig["member"]: + member_names += member + LIST_DELIMITER + member_names = member_names[:-1] + if "name" in user_orig: + name = str(user_orig["name"]) + if "comment" in user_orig: + comment = str(user_orig["comment"]) + if "color" in user_orig and str(user_orig["color"]) != "0": + color = str(user_orig["color"]) + + user.update( + { + "user_typ": svc_type, + "user_name": name, + "user_color": color, + "user_uid": name, + "user_comment": comment, + "user_member_refs": member_names, + "user_member_names": member_names, + } + ) + + return user diff --git a/roles/importer/files/importer/fw_modules/fortiadom5ff/fmgr_zone.py b/roles/importer/files/importer/fw_modules/fortiadom5ff/fmgr_zone.py new file mode 100644 index 0000000000..f5c761e88b --- /dev/null +++ b/roles/importer/files/importer/fw_modules/fortiadom5ff/fmgr_zone.py @@ -0,0 +1,83 @@ +from typing import Any + +from fw_modules.fortiadom5ff import fmgr_getter +from fwo_exceptions import FwoNormalizedConfigParseError + + +def get_zones(sid: str, fm_api_url: str, native_config: dict[str, Any], adom_name: str, limit: int): + if adom_name == "": + fmgr_getter.update_config_with_fortinet_api_call( + native_config["zones"], + sid, + fm_api_url, + "/pm/config/global/obj/dynamic/interface", + "interface_global", + limit=limit, + ) + else: + fmgr_getter.update_config_with_fortinet_api_call( + native_config["zones"], + sid, + fm_api_url, + "/pm/config/adom/" + adom_name + "/obj/dynamic/interface", + "interface_" + adom_name, + limit=limit, + ) + + +def normalize_zones( + native_config: dict[str, Any], normalized_config_adom: dict[str, Any], is_global_loop_iteration: bool +): + zones: list[dict[str, Any]] = [] + fetched_zones: list[str] = [] + if is_global_loop_iteration: # can not find the following zones in api return + statically_add_missing_global_zones(fetched_zones) + for zone_type in native_config["zones"]: + for mapping in zone_type.get("data", []): + if "defmap-intf" in mapping and mapping["defmap-intf"] not in fetched_zones: + fetched_zones.append(mapping["defmap-intf"]) + if mapping["dynamic_mapping"] is not None: + fetch_dynamic_mapping(mapping, fetched_zones) + if mapping["platform_mapping"] is not None: + fetch_platform_mapping(mapping, fetched_zones) + + zones = [{"zone_name": zone} for zone in fetched_zones] + normalized_config_adom.update({"zone_objects": zones}) + + +def statically_add_missing_global_zones(fetched_zones: list[str]) -> None: + fetched_zones.extend(["any", "sslvpn_tun_intf", "virtual-wan-link"]) + # double check, if these zones cannot be parsed from api results + + +def fetch_dynamic_mapping(mapping: dict[str, Any], fetched_zones: list[str]) -> None: + for dyn_mapping in mapping["dynamic_mapping"]: + if "name" in dyn_mapping and dyn_mapping["name"] not in fetched_zones: + fetched_zones.append(dyn_mapping["name"]) + if "local-intf" in dyn_mapping: + for local_interface in dyn_mapping["local-intf"]: + if local_interface not in fetched_zones: + fetched_zones.append(local_interface) + + +def fetch_platform_mapping(mapping: dict[str, Any], fetched_zones: list[str]) -> None: + for dyn_mapping in mapping["platform_mapping"]: + if "intf-zone" in dyn_mapping and dyn_mapping["intf-zone"] not in fetched_zones: + fetched_zones.append(dyn_mapping["intf-zone"]) + + +def find_zones_in_normalized_config( + native_zone_list: list[str], normalized_config_adom: dict[str, Any], normalized_config_global: dict[str, Any] +) -> list[str]: + """Verifies that input zones exist in normalized config""" + zone_out_list: list[str] = [] + for nativ_zone in native_zone_list: + was_zone_found = False + for normalized_zone in normalized_config_adom["zone_objects"] + normalized_config_global["zone_objects"]: + if nativ_zone == normalized_zone["zone_name"]: + zone_out_list.append(normalized_zone["zone_name"]) + was_zone_found = True + break + if not was_zone_found: + raise FwoNormalizedConfigParseError("Could not find zone " + nativ_zone + " in normalized config.") + return sorted(zone_out_list) diff --git a/roles/importer/files/importer/fw_modules/fortiadom5ff/fwcommon.py b/roles/importer/files/importer/fw_modules/fortiadom5ff/fwcommon.py new file mode 100644 index 0000000000..1760fea697 --- /dev/null +++ b/roles/importer/files/importer/fw_modules/fortiadom5ff/fwcommon.py @@ -0,0 +1,610 @@ +from copy import deepcopy +from datetime import datetime +from typing import Any, cast + +import fwo_const +from fw_modules.fortiadom5ff import fmgr_getter +from fw_modules.fortiadom5ff.fmgr_consts import nw_obj_types, svc_obj_types, user_obj_types +from fw_modules.fortiadom5ff.fmgr_network import normalize_network_objects +from fw_modules.fortiadom5ff.fmgr_rule import get_access_policy, get_nat_policy, normalize_rulebases +from fw_modules.fortiadom5ff.fmgr_service import normalize_service_objects +from fw_modules.fortiadom5ff.fmgr_zone import get_zones, normalize_zones +from fwo_base import ConfigAction, write_native_config_to_file +from fwo_exceptions import FwLoginFailedError, FwLogoutFailedError, ImportInterruptionError +from fwo_log import FWOLogger +from model_controllers.fwconfigmanagerlist_controller import FwConfigManagerListController +from model_controllers.import_state_controller import ImportStateController +from models.fw_common import FwCommon +from models.fwconfig_normalized import FwConfigNormalized +from models.fwconfigmanager import FwConfigManager +from models.import_state import ImportState +from models.management import Management +from models.time_object import TimeObject +from utils.conversion_utils import convert_list_to_dict + + +class FortiAdom5ffCommon(FwCommon): + def get_config( + self, config_in: FwConfigManagerListController, import_state: ImportStateController + ) -> tuple[int, FwConfigManagerListController]: + return get_config(config_in, import_state) + + +def get_config( + config_in: FwConfigManagerListController, import_state: ImportStateController +) -> tuple[int, FwConfigManagerListController]: + if config_in.has_empty_config(): # no native config was passed in, so getting it from FW-Manager + config_in.native_config.update({"domains": []}) # type: ignore #TYPING: What is this? None or not None this is the question # noqa: PGH003 + parsing_config_only = False + else: + parsing_config_only = True + + if not parsing_config_only: # no native config was passed in, so getting it from FortiManager + get_native_config(config_in, import_state) + + if not config_in.native_config: + raise ImportError("native config missing") + + normalized_managers = normalize_config(config_in.native_config) + FWOLogger.info("completed getting config") + return 0, normalized_managers + + +def get_native_config(config_in: FwConfigManagerListController, import_state: ImportStateController) -> None: + sid = get_sid(import_state.state) + limit = import_state.state.fwo_config.api_fetch_size + fm_api_url = import_state.state.mgm_details.build_fw_api_string() + native_config_global = initialize_native_config_domain(import_state.state.mgm_details) + config_in.native_config["domains"].append(native_config_global) # type: ignore #TYPING: None or not None this is the question # noqa: PGH003 + adom_list = build_adom_list(import_state.state) + adom_device_vdom_structure = build_adom_device_vdom_structure(adom_list, sid, fm_api_url, import_state.state) + # delete_v: das geht schief für unschöne adoms + arbitrary_vdom_for_updateable_objects = get_arbitrary_vdom(adom_device_vdom_structure) + adom_device_vdom_policy_package_structure = add_policy_package_to_vdoms(adom_device_vdom_structure, sid, fm_api_url) + + # get global + get_objects( + sid, + fm_api_url, + native_config_global, + native_config_global, + "", + limit, + nw_obj_types, + svc_obj_types, + "global", + arbitrary_vdom_for_updateable_objects, + ) + get_zones(sid, fm_api_url, native_config_global, "", limit) + + for adom in adom_list: + if adom.import_disabled and not import_state.state.force_import: + continue + # TODO: check if adom exists on fw and fail gracefully if not (custom exception) + adom_name = fmgr_getter.require_domain_name(adom.domain_name, "ADOM config import") + native_config_adom = initialize_native_config_domain(adom) + config_in.native_config["domains"].append(native_config_adom) # type: ignore #TYPING: None or not None this is the question # noqa: PGH003 + + adom_scope = "adom/" + adom_name + get_objects( + sid, + fm_api_url, + native_config_adom, + native_config_global, + adom_name, + limit, + nw_obj_types, + svc_obj_types, + adom_scope, + arbitrary_vdom_for_updateable_objects, + ) + # currently reading zone from objects/rules for backward compat with FortiManager 6.x + get_zones(sid, fm_api_url, native_config_adom, adom_name, limit) + + # TODO: bring interfaces and routing in new domain native config format + # getInterfacesAndRouting( + # sid, fm_api_url, nativeConfig, adom_name, adom.Devices, limit) + + for mgm_details_device in adom.devices: + if mgm_details_device["importDisabled"] and not import_state.state.force_import: + continue + # TODO: check if device exists on fw inside adom and fail gracefully if not (custom exception) + device_config = initialize_device_config(mgm_details_device) + native_config_adom["gateways"].append(device_config) + get_access_policy( + sid, + fm_api_url, + native_config_adom, + native_config_global, + adom_device_vdom_policy_package_structure, + adom_name, + mgm_details_device, + device_config, + limit, + ) + get_nat_policy( + sid, + fm_api_url, + native_config_adom, + adom_device_vdom_policy_package_structure, + adom_name, + mgm_details_device, + limit, + ) + + try: # logout of fortimanager API + fmgr_getter.logout(fm_api_url, sid) + except Exception: + raise FwLogoutFailedError("logout exception probably due to timeout - irrelevant, so ignoring it") + + write_native_config_to_file(import_state.state, config_in.native_config) + + +def initialize_native_config_domain(mgm_details: Management) -> dict[str, Any]: + return { + "domain_name": mgm_details.domain_name, + "domain_uid": mgm_details.domain_uid, + "is-super-manager": mgm_details.is_super_manager, + "management_name": mgm_details.name, + "management_uid": mgm_details.uid, + "objects": [], + "rulebases": [], + "nat_rulebases": [], + "zones": [], + "gateways": [], + "time_objects": [], + } + + +def get_arbitrary_vdom(adom_device_vdom_structure: dict[str, dict[str, dict[str, Any]]]) -> dict[str, str] | None: + for adom in adom_device_vdom_structure: # noqa: PLC0206 + for device in adom_device_vdom_structure[adom]: + for vdom in adom_device_vdom_structure[adom][device]: + return {"adom": adom, "device": device, "vdom": vdom} + return None + + +def normalize_config(native_config: dict[str, Any]) -> FwConfigManagerListController: + manager_list = FwConfigManagerListController() + + if "domains" not in native_config: + raise ImportInterruptionError("No domains found in native config. Cannot normalize config.") + + rewrite_native_config_obj_type_as_key(native_config) # for easier accessability of objects in normalization process + + native_config_global: dict[str, Any] = {} + normalized_config_global = {} + + for native_conf in native_config["domains"]: + normalized_config_adom = deepcopy(fwo_const.EMPTY_NORMALIZED_FW_CONFIG_JSON_DICT) + is_global_loop_iteration = False + + if native_conf["is-super-manager"]: + native_config_global = native_conf + normalized_config_global = normalized_config_adom + is_global_loop_iteration = True + + normalize_single_manager_config( + native_conf, + native_config_global, + normalized_config_adom, + normalized_config_global, + is_global_loop_iteration, + ) + + normalized_time_objects = normalized_config_adom.get("time_objects", {}) + if not isinstance(normalized_time_objects, dict): + normalized_time_objects = {} + + normalized_config = FwConfigNormalized( + action=ConfigAction.INSERT, + network_objects=convert_list_to_dict(normalized_config_adom.get("network_objects", []), "obj_uid"), + service_objects=convert_list_to_dict(normalized_config_adom.get("service_objects", []), "svc_uid"), + zone_objects=convert_list_to_dict(normalized_config_adom.get("zone_objects", []), "zone_name"), + rulebases=normalized_config_adom.get("policies", []), + gateways=normalized_config_adom.get("gateways", []), + time_objects=cast("dict[str, TimeObject]", normalized_time_objects), + ) + + # TODO: identify the correct manager + + manager = FwConfigManager( + manager_uid=native_conf.get("management_uid", ""), + manager_name=native_conf.get("management_name", ""), + is_super_manager=native_conf.get("is-super-manager", False), + domain_name=native_conf.get("domain_name", ""), + domain_uid=native_conf.get("domain_uid", ""), + sub_manager_ids=[], + configs=[normalized_config], + ) + + manager_list.add_manager(manager) + + return manager_list + + +def rewrite_native_config_obj_type_as_key(native_config: dict[str, Any]): + # rewrite native config objects to have the object type as key + # this is needed for the normalization process + + for domain in native_config["domains"]: + if "objects" not in domain: + continue + obj_dict: dict[str, Any] = {} + for obj_chunk in domain["objects"]: + if "type" not in obj_chunk: + continue + obj_type = obj_chunk["type"] + obj_dict.update({obj_type: obj_chunk}) + domain["objects"] = obj_dict + + +def normalize_single_manager_config( + native_config: "dict[str, Any]", + native_config_global: "dict[str, Any]", + normalized_config_adom: dict[str, Any], + normalized_config_global: dict[str, Any], + is_global_loop_iteration: bool, +): + current_nw_obj_types = deepcopy(nw_obj_types) + current_svc_obj_types = deepcopy(svc_obj_types) + if native_config["is-super-manager"]: + current_nw_obj_types = ["nw_obj_global_" + t for t in current_nw_obj_types] + current_nw_obj_types.append("nw_obj_global_firewall/internet-service-basic") + current_svc_obj_types = ["svc_obj_global_" + t for t in current_svc_obj_types] + else: + current_nw_obj_types = [f"nw_obj_adom/{native_config.get('domain_name', '')}_{t}" for t in current_nw_obj_types] + current_svc_obj_types = [ + f"svc_obj_adom/{native_config.get('domain_name', '')}_{t}" for t in current_svc_obj_types + ] + + normalize_zones(native_config, normalized_config_adom, is_global_loop_iteration) + FWOLogger.info("completed normalizing zones for manager: " + native_config.get("domain_name", "")) + normalize_network_objects(native_config, normalized_config_adom, normalized_config_global, current_nw_obj_types) + FWOLogger.info("completed normalizing network objects for manager: " + native_config.get("domain_name", "")) + normalize_service_objects(native_config, normalized_config_adom, current_svc_obj_types) + FWOLogger.info("completed normalizing service objects for manager: " + native_config.get("domain_name", "")) + mgm_uid = native_config["management_uid"] + normalize_rulebases( + mgm_uid, + native_config, + native_config_global, + normalized_config_adom, + normalized_config_global, + is_global_loop_iteration, + ) + FWOLogger.info("completed normalizing rulebases for manager: " + native_config.get("domain_name", "")) + normalize_time_objects(native_config, normalized_config_adom) + FWOLogger.info("completed normalizing time objects for manager: " + native_config.get("domain_name", "")) + + normalize_gateways(native_config, normalized_config_adom) + + +def build_adom_list(import_state: ImportState) -> list[Management]: + adom_list: list[Management] = [] + if import_state.mgm_details.is_super_manager: + adom_list = [deepcopy(sub_manager) for sub_manager in import_state.mgm_details.sub_managers] + return adom_list + + +def build_adom_device_vdom_structure( + adom_list: list[Management], sid: str, fm_api_url: str, import_state: ImportState +) -> dict[str, dict[str, dict[str, Any]]]: + adom_device_vdom_structure: dict[str, dict[str, dict[str, Any]]] = {} + for adom in adom_list: + if adom.import_disabled and not import_state.force_import: + continue + adom_name = fmgr_getter.require_domain_name(adom.domain_name, "ADOM device/vdom mapping") + adom_device_vdom_structure.update({adom_name: {}}) + if len(adom.devices) > 0: + device_vdom_dict = fmgr_getter.get_devices_from_manager(adom, sid, fm_api_url) + adom_device_vdom_structure[adom_name].update(device_vdom_dict) + return adom_device_vdom_structure + + +def add_policy_package_to_vdoms( + adom_device_vdom_structure: dict[str, dict[str, dict[str, str]]], sid: str, fm_api_url: str +) -> dict[str, dict[str, dict[str, Any]]]: + adom_device_vdom_policy_package_structure = deepcopy(adom_device_vdom_structure) + for adom in adom_device_vdom_policy_package_structure: + policy_packages_result = fmgr_getter.fortinet_api_call(sid, fm_api_url, "/pm/pkg/adom/" + adom) + for policy_package in policy_packages_result: + if "scope member" in policy_package: + parse_policy_package(policy_package, adom_device_vdom_policy_package_structure, adom) + add_global_policy_package_to_vdom(adom_device_vdom_policy_package_structure, sid, fm_api_url, adom) + return adom_device_vdom_policy_package_structure + + +def parse_policy_package( + policy_package: dict[str, Any], + adom_device_vdom_policy_package_structure: dict[str, dict[str, dict[str, Any]]], + adom: str, +): + for scope_member in policy_package["scope member"]: + for device in adom_device_vdom_policy_package_structure[adom]: + if device == scope_member["name"]: + for vdom in adom_device_vdom_policy_package_structure[adom][device]: + if vdom == scope_member["vdom"]: + adom_device_vdom_policy_package_structure[adom][device].update( + {vdom: {"local": policy_package["name"], "global": ""}} + ) + + +def add_global_policy_package_to_vdom( + adom_device_vdom_policy_package_structure: dict[str, dict[str, dict[str, Any]]], + sid: str, + fm_api_url: str, + adom: str, +): + global_assignment_result = fmgr_getter.fortinet_api_call( + sid, fm_api_url, "/pm/config/adom/" + adom + "/_adom/options" + ) + for global_assignment in global_assignment_result: + if global_assignment["assign_excluded"] == 0 and global_assignment["specify_assign_pkg_list"] == 0: + assign_case_all(adom_device_vdom_policy_package_structure, adom, global_assignment) + elif global_assignment["assign_excluded"] == 0 and global_assignment["specify_assign_pkg_list"] == 1: + assign_case_include(adom_device_vdom_policy_package_structure, adom, global_assignment) + elif global_assignment["assign_excluded"] == 1 and global_assignment["specify_assign_pkg_list"] == 1: + assign_case_exclude(adom_device_vdom_policy_package_structure, adom, global_assignment) + else: + raise ImportInterruptionError("Broken global assign format.") + + +def assign_case_all( + adom_device_vdom_policy_package_structure: dict[str, dict[str, dict[str, Any]]], + adom: str, + global_assignment: dict[str, Any], +): + for device in adom_device_vdom_policy_package_structure[adom]: + for vdom in adom_device_vdom_policy_package_structure[adom][device]: + adom_device_vdom_policy_package_structure[adom][device][vdom]["global"] = global_assignment["assign_name"] + + +def assign_case_include( + adom_device_vdom_policy_package_structure: dict[str, dict[str, dict[str, Any]]], + adom: str, + global_assignment: dict[str, Any], +): + for device in adom_device_vdom_policy_package_structure[adom]: + for vdom in adom_device_vdom_policy_package_structure[adom][device]: + match_assign_and_vdom_policy_package( + global_assignment, adom_device_vdom_policy_package_structure[adom][device][vdom], is_include=True + ) + + +def assign_case_exclude( + adom_device_vdom_policy_package_structure: dict[str, dict[str, dict[str, Any]]], + adom: str, + global_assignment: dict[str, Any], +): + for device in adom_device_vdom_policy_package_structure[adom]: + for vdom in adom_device_vdom_policy_package_structure[adom][device]: + match_assign_and_vdom_policy_package( + global_assignment, adom_device_vdom_policy_package_structure[adom][device][vdom], is_include=False + ) + + +def match_assign_and_vdom_policy_package( + global_assignment: dict[str, Any], vdom_structure: dict[str, Any], is_include: bool +): + for package in global_assignment["pkg list"]: + if is_include: + if package["name"] == vdom_structure["local"]: + vdom_structure["global"] = global_assignment["assign_name"] + elif package["name"] != vdom_structure["local"]: + vdom_structure["global"] = global_assignment["assign_name"] + + +def initialize_device_config(mgm_details_device: dict[str, Any]) -> dict[str, Any]: + device_config: dict[str, Any] = { + "name": mgm_details_device["name"], + "uid": mgm_details_device["uid"], + "rulebase_links": [], + } + return device_config + + +def get_sid(import_state: ImportState): + fm_api_url = "https://" + import_state.mgm_details.hostname + ":" + str(import_state.mgm_details.port) + "/jsonrpc" + sid = fmgr_getter.login(import_state.mgm_details.import_user, import_state.mgm_details.secret, fm_api_url) + if sid is None: + raise FwLoginFailedError("did not succeed in logging in to FortiManager API, no sid returned") + return sid + + +def get_objects( + sid: str, + fm_api_url: str, + native_config_domain: dict[str, Any], + native_config_global: dict[str, Any], + adom_name: str, + limit: int, + nw_obj_types: list[str], + svc_obj_types: list[str], + adom_scope: str, + arbitrary_vdom_for_updateable_objects: dict[str, Any] | None, +): + # get those objects that exist globally and on adom level + api_base_path = f"/pm/config/{adom_scope}/obj/" + + # get network objects: + for object_type in nw_obj_types: + fmgr_getter.update_config_with_fortinet_api_call( + native_config_domain["objects"], + sid, + fm_api_url, + api_base_path + object_type, + "nw_obj_" + adom_scope + "_" + object_type, + limit=limit, + ) + + # get service objects: + # service/custom is an undocumented API call! + for object_type in svc_obj_types: + fmgr_getter.update_config_with_fortinet_api_call( + native_config_domain["objects"], + sid, + fm_api_url, + api_base_path + object_type, + "svc_obj_" + adom_scope + "_" + object_type, + limit=limit, + ) + + # user: /pm/config/global/obj/user/local, /pm/config/global/obj/user/group + # get user objects: + for object_type in user_obj_types: + fmgr_getter.update_config_with_fortinet_api_call( + native_config_domain["objects"], + sid, + fm_api_url, + api_base_path + object_type, + "user_obj_" + adom_scope + "_" + object_type, + limit=limit, + ) + + # schedules: /pm/config/adom/root/obj/firewall/schedule/onetime, /pm/config/adom/root/obj/firewall/schedule/recurring, /pm/config/adom/root/obj/firewall/schedule/group + # get schedules: + for object_type in ["onetime", "recurring", "group"]: + fmgr_getter.update_config_with_fortinet_api_call( + native_config_domain["time_objects"], + sid, + fm_api_url, + api_base_path + "firewall/schedule/" + object_type, + "schedule_obj_" + adom_scope + "_" + "firewall/schedule/" + object_type, + limit=limit, + ) + + # get one arbitrary device and vdom to get dynamic objects + # they are equal across all adoms, vdoms, devices + if arbitrary_vdom_for_updateable_objects is None: + FWOLogger.error("arbitrary_vdom_for_updateable_objects is None, cannot get dynamic objects") + return + if arbitrary_vdom_for_updateable_objects["adom"] == adom_name: + # get dynamic objects + payload: dict[str, Any] = { + "params": [ + { + "data": { + "action": "get", + "resource": "/api/v2/monitor/firewall/internet-service-basic?vdom=" + + arbitrary_vdom_for_updateable_objects["vdom"], + "target": ["adom/" + adom_name + "/device/" + arbitrary_vdom_for_updateable_objects["device"]], + } + } + ] + } + fmgr_getter.update_config_with_fortinet_api_call( + native_config_global["objects"], + sid, + fm_api_url, + "sys/proxy/json", + "nw_obj_global_firewall/internet-service-basic", + limit=limit, + payload=payload, + method="exec", + ) + + +def normalize_gateways(native_config: dict[str, Any], normalized_config_adom: dict[str, Any]): + for gateway in native_config["gateways"]: + normalized_gateway = {} + normalized_gateway["Uid"] = gateway["uid"] + normalized_gateway["Name"] = gateway["name"] + normalized_gateway["Interfaces"] = normalize_interfaces() + normalized_gateway["Routing"] = normalize_routing() + normalized_gateway["RulebaseLinks"] = normalize_links(gateway["rulebase_links"]) + normalized_config_adom["gateways"].append(normalized_gateway) + + +def normalize_interfaces() -> list[Any]: + # TODO: Implement interface normalization + return [] + + +def normalize_routing() -> list[Any]: + # TODO: Implement routing normalization + return [] + + +def normalize_links(rulebase_links: list[dict[str, Any]]) -> list[dict[str, Any]]: + for link in rulebase_links: + link["link_type"] = link.pop("type") + + # Remove from_rulebase_uid and from_rule_uid if link_type is initial + if link["link_type"] == "initial": + if link["from_rulebase_uid"] is not None: + link["from_rulebase_uid"] = None + if link["from_rule_uid"] is not None: + link["from_rule_uid"] = None + return rulebase_links + + +def normalize_time_objects(native_config: dict[str, Any], normalized_config_adom: dict[str, Any]): + time_object_by_uid: dict[str, TimeObject] = {} + + # Get time objects from native + time_objects_from_native = [ + to_time_object(item) + for native_time_object in native_config.get("time_objects", []) + for item in native_time_object.get("data", []) + ] + + for rulebase in native_config.get("rulebases", []): # include nat rulebases? + for rule in rulebase.get("data", []): + if "schedule" in rule and rule["schedule"] is not None: + schedule_ref: list[str] = rule["schedule"] + + # Find the time object in native config that matches the schedule reference + + matching_time_objects = [obj for obj in time_objects_from_native if obj.time_obj_name in schedule_ref] + + if matching_time_objects: + time_object_by_uid.update({time_obj.time_obj_uid: time_obj for time_obj in matching_time_objects}) + else: + FWOLogger.warning( + f"Schedule reference {schedule_ref} in rule {rule['name']} does not match any known time object." + ) + + normalized_config_adom.update({"time_objects": time_object_by_uid}) + + +def to_time_object(d: dict[str, Any]) -> TimeObject: + def parse_schedule_timestamp(value: list[str] | str | None, field_name: str) -> str | None: + # format is like: "start": ["12:00", "2026/02/17"] + # or: "start": "00:00 2020/01/01" + # or: "start": "12:00" -> currently not supported + if value is None: + return None + if isinstance(value, str): + if value == "00:00": + return None + value = value.split() + if len(value) != 2: # noqa: PLR2004 + FWOLogger.warning( + f"Found time object with currently unsupported date/time format for {field_name} in time object {d.get('name', '')}: {value}" + ) + return None + time_part, date_part = value + # format needs to be like 1970-01-01T00:00:00+00:00 (including tz info) + try: + # we do not get tz info from fortimanager, so we assume firewall tz = system tz + dt = datetime.strptime(date_part + " " + time_part, "%Y/%m/%d %H:%M").astimezone() + return dt.isoformat(timespec="seconds") + except ValueError as e: + FWOLogger.warning(f"Error parsing date/time for {field_name} in time object {d.get('name', '')}: {e}") + return None + + name = d.get("name") + + if not name: + raise ImportInterruptionError("Time object missing name field, cannot normalize.") + + start_time = parse_schedule_timestamp(d.get("start"), "start") + end_time = parse_schedule_timestamp(d.get("end"), "end") + + return TimeObject( + time_obj_uid=name, + time_obj_name=name, + start_time=start_time, + end_time=end_time, + ) diff --git a/roles/importer/files/importer/paloaltomanagement2023ff/__init__.py b/roles/importer/files/importer/fw_modules/fortiosmanagementREST/__init__.py similarity index 100% rename from roles/importer/files/importer/paloaltomanagement2023ff/__init__.py rename to roles/importer/files/importer/fw_modules/fortiosmanagementREST/__init__.py diff --git a/roles/importer/files/importer/fw_modules/fortiosmanagementREST/fos_const.py b/roles/importer/files/importer/fw_modules/fortiosmanagementREST/fos_const.py new file mode 100644 index 0000000000..387bdcceaa --- /dev/null +++ b/roles/importer/files/importer/fw_modules/fortiosmanagementREST/fos_const.py @@ -0,0 +1,34 @@ +NW_OBJ_TYPES = [ + "firewall/address", + "firewall/address6", + "firewall/addrgrp", + "firewall/addrgrp6", + "firewall/ippool", + "firewall/vip", + "firewall/internet-service", + "firewall/internet-service-group", +] + +# internet-service is not a service as such but is used as dest (mainly) +SVC_OBJ_TYPES = [ + "application/list", + "application/group", + "firewall.service/custom", + "firewall.service/group", +] + +# build the product of all scope/type combinations +NW_OBJ_SCOPE = ["nw_obj_" + s1 for s1 in NW_OBJ_TYPES] +SVC_OBJ_SCOPE = ["svc_obj_" + s1 for s1 in SVC_OBJ_TYPES] + +# TODO: ZONE_TYPES = ['zones_global', 'zones_adom'] + +USER_OBJ_TYPES = ["user/local", "user/group"] +USER_SCOPE = ["user_obj_" + s1 for s1 in USER_OBJ_TYPES] + +RULE_ACCESS_SCOPE_V4 = ["rules"] +RULE_ACCESS_SCOPE_V6 = [] + +RULE_ACCESS_SCOPE = ["rules"] +RULE_NAT_SCOPE = ["rules_nat"] +RULE_SCOPE = RULE_ACCESS_SCOPE + RULE_NAT_SCOPE diff --git a/roles/importer/files/importer/fw_modules/fortiosmanagementREST/fos_getter.py b/roles/importer/files/importer/fw_modules/fortiosmanagementREST/fos_getter.py new file mode 100644 index 0000000000..7964a7ad83 --- /dev/null +++ b/roles/importer/files/importer/fw_modules/fortiosmanagementREST/fos_getter.py @@ -0,0 +1,221 @@ +# library for API get functions +import json +from typing import Any, TypeVar + +import fwo_globals +import requests +from fw_modules.fortiosmanagementREST.fos_models import ( + FortiOSConfig, + NwObjAddress, + NwObjAddress6, + NwObjAddrGrp, + NwObjAddrGrp6, + NwObjInternetService, + NwObjInternetServiceGroup, + NwObjIpPool, + NwObjVip, + Rule, + SvcObjApplicationGroup, + SvcObjApplicationList, + SvcObjCustom, + SvcObjGroup, + UserObjGroup, + UserObjLocal, + ZoneObject, +) +from fw_modules.fortiosmanagementREST.fos_zone import normalize_zone_name +from fwo_exceptions import FwApiCallFailedError +from fwo_log import FWOLogger +from pydantic import BaseModel, TypeAdapter + +T = TypeVar("T", bound=BaseModel) + +HTTP_OK = 200 + + +def fortios_api_call(api_url: str) -> list[dict[str, Any]]: + """ + Makes a GET request to the FortiOS REST API and returns the JSON response. + + Args: + api_url (str): The full URL for the API endpoint. + + Returns: + list[dict[str, Any]]: The list of results from the API. + + """ + request_headers = {"Content-Type": "application/json"} + + response = requests.get(api_url, headers=request_headers, verify=fwo_globals.verify_certs) + if response.status_code != HTTP_OK: + raise FwApiCallFailedError( + "error while sending api_call to url '" + + str(api_url) + + "' with headers: '" + + json.dumps(request_headers, indent=2) + + ", response code: " + + str(response.status_code) + + ", response text: " + + response.text + ) + result_json = response.json() + if "results" not in result_json: + raise FwApiCallFailedError( + "error while sending api_call to url '" + + str(api_url) + + "' including headers: '" + + json.dumps(request_headers, indent=2) + + ", response json: " + + json.dumps(result_json, indent=2) + ) + + FWOLogger.debug("api_call to url '" + str(api_url) + "', headers: '" + json.dumps(request_headers, indent=2), 3) + + return result_json["results"] + + +def parse_api_results(model_class: type[T], data: list[dict[str, Any]]) -> list[T]: # TODO: needs python 3.12 + """ + Parse API results into Pydantic model instances. + + Args: + model_class: The Pydantic model class to parse into. + data: The raw API response data. + + Returns: + List of parsed Pydantic model instances. + + """ + adapter = TypeAdapter(list[model_class]) + return adapter.validate_python(data) + + +def get_native_config(fm_api_url: str, sid: str) -> FortiOSConfig: + """ + Gets the native configuration from the FortiOS REST API. + + Args: + fm_api_url (str): The base URL for the FortiOS API. + sid (str): The session ID or access token for authentication. + + Returns: + FortiOSConfig: The native configuration. + + """ + native_config = FortiOSConfig() + + # Network objects + native_config.nw_obj_address.extend( + parse_api_results(NwObjAddress, fortios_api_call(fm_api_url + "/cmdb/firewall/address?access_token=" + sid)) + ) + native_config.nw_obj_address6.extend( + parse_api_results(NwObjAddress6, fortios_api_call(fm_api_url + "/cmdb/firewall/address6?access_token=" + sid)) + ) + native_config.nw_obj_addrgrp.extend( + parse_api_results(NwObjAddrGrp, fortios_api_call(fm_api_url + "/cmdb/firewall/addrgrp?access_token=" + sid)) + ) + native_config.nw_obj_addrgrp6.extend( + parse_api_results(NwObjAddrGrp6, fortios_api_call(fm_api_url + "/cmdb/firewall/addrgrp6?access_token=" + sid)) + ) + native_config.nw_obj_ippool.extend( + parse_api_results(NwObjIpPool, fortios_api_call(fm_api_url + "/cmdb/firewall/ippool?access_token=" + sid)) + ) + native_config.nw_obj_vip.extend( + parse_api_results(NwObjVip, fortios_api_call(fm_api_url + "/cmdb/firewall/vip?access_token=" + sid)) + ) + native_config.nw_obj_internet_service.extend( + parse_api_results( + NwObjInternetService, fortios_api_call(fm_api_url + "/cmdb/firewall/internet-service?access_token=" + sid) + ) + ) + native_config.nw_obj_internet_service_group.extend( + parse_api_results( + NwObjInternetServiceGroup, + fortios_api_call(fm_api_url + "/cmdb/firewall/internet-service-group?access_token=" + sid), + ) + ) + + # Service objects + native_config.svc_obj_application_list.extend( + parse_api_results( + SvcObjApplicationList, fortios_api_call(fm_api_url + "/cmdb/application/list?access_token=" + sid) + ) + ) + native_config.svc_obj_application_group.extend( + parse_api_results( + SvcObjApplicationGroup, fortios_api_call(fm_api_url + "/cmdb/application/group?access_token=" + sid) + ) + ) + native_config.svc_obj_custom.extend( + parse_api_results( + SvcObjCustom, fortios_api_call(fm_api_url + "/cmdb/firewall.service/custom?access_token=" + sid) + ) + ) + native_config.svc_obj_group.extend( + parse_api_results( + SvcObjGroup, fortios_api_call(fm_api_url + "/cmdb/firewall.service/group?access_token=" + sid) + ) + ) + + # User objects + native_config.user_obj_local.extend( + parse_api_results(UserObjLocal, fortios_api_call(fm_api_url + "/cmdb/user/local?access_token=" + sid)) + ) + native_config.user_obj_group.extend( + parse_api_results(UserObjGroup, fortios_api_call(fm_api_url + "/cmdb/user/group?access_token=" + sid)) + ) + + add_zone_if_missing(native_config, "global") + + # Rules + native_config.rules.extend( + parse_api_results(Rule, fortios_api_call(fm_api_url + "/cmdb/firewall/policy?access_token=" + sid)) + ) + + process_zones(native_config) + + # TODO: get nat rules + + return native_config + + +def add_zone_if_missing(native_config: FortiOSConfig, zone_name: str) -> str: + """ + Adds a zone to the native configuration if it is missing. + + Args: + native_config (FortiOSConfig): The native configuration. + zone_name (str): The name of the zone to add. + + Returns: + str: The normalized name of the zone that was ensured to exist in the configuration. + + """ + zone_name = normalize_zone_name(zone_name) + + if not any(z for z in native_config.zone_objects if z.zone_name == zone_name): + # zone not found - add it + native_config.zone_objects.append(ZoneObject(zone_name=zone_name)) + + return zone_name + + +def process_zones(native_config: FortiOSConfig) -> None: + """ + Extracts zones from interfaces in the native configuration, adding them to the zone objects list. + + Args: + native_config (FortiOSConfig): The native configuration. + + """ + for obj in native_config.nw_obj_address: + if obj.associated_interface: + obj.associated_interface = add_zone_if_missing(native_config, obj.associated_interface) + for obj in native_config.nw_obj_ippool: + if obj.associated_interface: + obj.associated_interface = add_zone_if_missing(native_config, obj.associated_interface) + for rule in native_config.rules: + for srcintf in rule.srcintf: + srcintf.name = add_zone_if_missing(native_config, srcintf.name) + for dstintf in rule.dstintf: + dstintf.name = add_zone_if_missing(native_config, dstintf.name) diff --git a/roles/importer/files/importer/fw_modules/fortiosmanagementREST/fos_models.py b/roles/importer/files/importer/fw_modules/fortiosmanagementREST/fos_models.py new file mode 100644 index 0000000000..79e9d297e7 --- /dev/null +++ b/roles/importer/files/importer/fw_modules/fortiosmanagementREST/fos_models.py @@ -0,0 +1,646 @@ +from typing import Any, Literal + +from pydantic import BaseModel, Field + +# ============================================================================ +# Network Object Models +# ============================================================================ + + +class NameRef(BaseModel): + """Generic name reference used in member lists""" + + name: str + q_origin_key: str + + +class NwObjAddress(BaseModel): + """firewall/address - IPv4 network address objects""" + + name: str + q_origin_key: str + uuid: str + type: Literal["ipmask", "iprange", "fqdn", "wildcard", "geography", "wildcard-fqdn", "dynamic", "interface-subnet"] + + # ipmask type fields + subnet: str | None = None + + # iprange type fields + start_ip: str | None = Field(None, alias="start-ip") + end_ip: str | None = Field(None, alias="end-ip") + + # fqdn type fields + fqdn: str | None = None + + # interface-subnet type fields + interface: str | None = None + + # dynamic type fields + sdn: str | None = None + obj_tag: str | None = Field(None, alias="obj-tag") + filter_: str | None = Field(None, alias="filter") + + # Common optional fields + sub_type: str | None = Field(None, alias="sub-type") + clearpass_spt: str | None = Field(None, alias="clearpass-spt") + macaddr: list[Any] = [] + country: str | None = None + cache_ttl: int | None = Field(None, alias="cache-ttl") + fsso_group: list[Any] = Field(default=[], alias="fsso-group") + obj_type: str | None = Field(None, alias="obj-type") + tag_detection_level: str | None = Field(None, alias="tag-detection-level") + tag_type: str | None = Field(None, alias="tag-type") + dirty: str | None = None + comment: str | None = None + associated_interface: str | None = Field(None, alias="associated-interface") + color: int | None = None + sdn_addr_type: str | None = Field(None, alias="sdn-addr-type") + node_ip_only: str | None = Field(None, alias="node-ip-only") + obj_id: str | None = Field(None, alias="obj-id") + list_: list[Any] = Field(default=[], alias="list") + tagging: list[Any] = [] + allow_routing: str | None = Field(None, alias="allow-routing") + fabric_object: str | None = Field(None, alias="fabric-object") + + +class NwObjAddress6(BaseModel): + """firewall/address6 - IPv6 network address objects""" + + name: str + q_origin_key: str + uuid: str + type: Literal["ipprefix", "iprange", "fqdn", "dynamic", "template"] + + # ipprefix type fields + ip6: str | None = None + + # iprange type fields + start_ip: str | None = Field(None, alias="start-ip") + end_ip: str | None = Field(None, alias="end-ip") + + # fqdn type fields + fqdn: str | None = None + + # dynamic type fields + sdn: str | None = None + sdn_tag: str | None = Field(None, alias="sdn-tag") + + # Common optional fields + macaddr: list[Any] = [] + country: str | None = None + cache_ttl: int | None = Field(None, alias="cache-ttl") + color: int | None = None + obj_id: str | None = Field(None, alias="obj-id") + list_: list[Any] = Field(default=[], alias="list") + tagging: list[Any] = [] + comment: str | None = None + template: str | None = None + subnet_segment: list[Any] = Field(default=[], alias="subnet-segment") + host_type: str | None = Field(None, alias="host-type") + tenant: str | None = None + epg_name: str | None = Field(None, alias="epg-name") + fabric_object: str | None = Field(None, alias="fabric-object") + + +class NwObjAddrGrp(BaseModel): + """firewall/addrgrp - IPv4 address groups""" + + name: str + q_origin_key: str + uuid: str + type: str | None = None + category: str | None = None + member: list[NameRef] = [] + comment: str | None = None + exclude: str | None = None + exclude_member: list[NameRef] = Field(default=[], alias="exclude-member") + color: int | None = None + tagging: list[Any] = [] + allow_routing: str | None = Field(None, alias="allow-routing") + fabric_object: str | None = Field(None, alias="fabric-object") + + +class NwObjAddrGrp6(BaseModel): + """firewall/addrgrp6 - IPv6 address groups""" + + name: str + q_origin_key: str + uuid: str + color: int | None = None + comment: str | None = None + member: list[NameRef] = [] + tagging: list[Any] = [] + fabric_object: str | None = Field(None, alias="fabric-object") + + +class NwObjIpPool(BaseModel): + """firewall/ippool - IP pool objects for NAT""" + + name: str + q_origin_key: str + type: str # Seen: "overload", likely also: "one-to-one", "fixed-port-range", "port-block-allocation" + startip: str + endip: str + startport: int | None = None + endport: int | None = None + source_startip: str | None = Field(None, alias="source-startip") + source_endip: str | None = Field(None, alias="source-endip") + block_size: int | None = Field(None, alias="block-size") + port_per_user: int | None = Field(None, alias="port-per-user") + num_blocks_per_user: int | None = Field(None, alias="num-blocks-per-user") + pba_timeout: int | None = Field(None, alias="pba-timeout") + permit_any_host: str | None = Field(None, alias="permit-any-host") + arp_reply: str | None = Field(None, alias="arp-reply") + arp_intf: str | None = Field(None, alias="arp-intf") + associated_interface: str | None = Field(None, alias="associated-interface") + comments: str | None = None + nat64: str | None = None + add_nat64_route: str | None = Field(None, alias="add-nat64-route") + + +class RangeRef(BaseModel): + """Generic range reference used in mappedip field""" + + range: str + q_origin_key: str + + +class NwObjVip(BaseModel): # TODO: correct? no example data available + """firewall/vip - Virtual IP objects for destination NAT""" + + name: str + q_origin_key: str + uuid: str | None = None + type: str | None = None + extip: str | None = None # External IP + extintf: str | None = None # External interface + mappedip: list[RangeRef] # Mapped internal IP(s) + comment: str | None = None + color: int | None = None + extport: str | None = None + mappedport: str | None = None + protocol: str | None = None + portforward: str | None = None + + +class NwObjInternetService(BaseModel): + """firewall/internet-service - Internet service objects""" + + id_: int = Field(alias="id") + q_origin_key: int + name: str + icon_id: int = Field(alias="icon-id") + direction: str + database: str + ip_range_number: int = Field(alias="ip-range-number") + extra_ip_range_number: int = Field(alias="extra-ip-range-number") + ip_number: int = Field(alias="ip-number") + ip6_range_number: int = Field(alias="ip6-range-number") + extra_ip6_range_number: int = Field(alias="extra-ip6-range-number") + singularity: int + obsolete: int + + +class NwObjInternetServiceGroup(BaseModel): # TODO: correct? no example data available + """firewall/internet-service-group - Internet service groups""" + + name: str + q_origin_key: str + comment: str | None = None + member: list[NameRef] = [] + + +class ZoneObject(BaseModel): + """zone object model""" + + zone_name: str + + +# ============================================================================ +# Service Object Models +# ============================================================================ + + +class AppCategory(BaseModel): + """Application category reference""" + + id_: int = Field(alias="id") + + +class SvcObjApplicationList(BaseModel): + """application/list - Application filter lists""" + + name: str + q_origin_key: str + comment: str | None = None + replacemsg_group: str | None = Field(None, alias="replacemsg-group") + extended_log: str | None = Field(None, alias="extended-log") + other_application_action: str | None = Field(None, alias="other-application-action") + app_replacemsg: str | None = Field(None, alias="app-replacemsg") + other_application_log: str | None = Field(None, alias="other-application-log") + enforce_default_app_port: str | None = Field(None, alias="enforce-default-app-port") + force_inclusion_ssl_di_sigs: str | None = Field(None, alias="force-inclusion-ssl-di-sigs") + unknown_application_action: str | None = Field(None, alias="unknown-application-action") + unknown_application_log: str | None = Field(None, alias="unknown-application-log") + default_network_services: list[Any] = Field(default=[], alias="default-network-services") + control_default_network_services: str | None = Field(None, alias="control-default-network-services") + options: str + entries: list[dict[str, Any]] = [] + # entries structure is complex with app-category, application, etc. + # keeping as generic dict since it's not directly used in normalization + + +class SvcObjApplicationGroup(BaseModel): # TODO: correct? no example data available + """application/group - Application groups""" + + name: str + q_origin_key: str + comment: str | None = None + type: str | None = None + category: list[AppCategory] = [] + application: list[NameRef] = [] + + +class SvcObjCustom(BaseModel): + """firewall.service/custom - Custom service objects""" + + name: str + q_origin_key: str + proxy: str | None = None + category: str | None = None + protocol: Literal["ALL", "TCP/UDP/SCTP", "ICMP", "ICMP6", "IP"] + helper: str | None = None + iprange: str | None = None + fqdn: str | None = None + + # TCP/UDP/SCTP port ranges (can have spaces like "80 8080" or single like "443") + tcp_portrange: str | None = Field(None, alias="tcp-portrange") + udp_portrange: str | None = Field(None, alias="udp-portrange") + sctp_portrange: str | None = Field(None, alias="sctp-portrange") + + # IP protocol number + protocol_number: int | None = Field(None, alias="protocol-number") + + # Timers + tcp_halfclose_timer: int | None = Field(None, alias="tcp-halfclose-timer") + tcp_halfopen_timer: int | None = Field(None, alias="tcp-halfopen-timer") + tcp_timewait_timer: int | None = Field(None, alias="tcp-timewait-timer") + tcp_rst_timer: int | None = Field(None, alias="tcp-rst-timer") + udp_idle_timer: int | None = Field(None, alias="udp-idle-timer") + session_ttl: str | None = Field(None, alias="session-ttl") + + # Common fields + check_reset_range: str | None = Field(None, alias="check-reset-range") + comment: str | None = None + color: int | None = None + visibility: str | None = None + app_service_type: str | None = Field(None, alias="app-service-type") + app_category: list[Any] = Field(default=[], alias="app-category") + application: list[Any] = [] + fabric_object: str | None = Field(None, alias="fabric-object") + + +class SvcObjGroup(BaseModel): + """firewall.service/group - Service groups""" + + name: str + q_origin_key: str + proxy: str | None = None + member: list[NameRef] = [] + comment: str | None = None + color: int | None = None + fabric_object: str | None = Field(None, alias="fabric-object") + + +# ============================================================================ +# User Object Models +# ============================================================================ + + +class UserObjLocal(BaseModel): + """user/local - Local user objects""" + + name: str + q_origin_key: str + id_: int = Field(alias="id") + status: str + type: str # Seen: "password", likely also: "radius", "ldap", "tacacs+" + passwd: str | None = None + ldap_server: str | None = Field(None, alias="ldap-server") + radius_server: str | None = Field(None, alias="radius-server") + tacacs_server: str | None = Field(None, alias="tacacs+-server") + two_factor: str | None = Field(None, alias="two-factor") + two_factor_authentication: str | None = Field(None, alias="two-factor-authentication") + two_factor_notification: str | None = Field(None, alias="two-factor-notification") + fortitoken: str | None = None + email_to: str | None = Field(None, alias="email-to") + sms_server: str | None = Field(None, alias="sms-server") + sms_custom_server: str | None = Field(None, alias="sms-custom-server") + sms_phone: str | None = Field(None, alias="sms-phone") + passwd_policy: str | None = Field(None, alias="passwd-policy") + passwd_time: str | None = Field(None, alias="passwd-time") + authtimeout: int | None = None + workstation: str | None = None + auth_concurrent_override: str | None = Field(None, alias="auth-concurrent-override") + auth_concurrent_value: int | None = Field(None, alias="auth-concurrent-value") + ppk_secret: str | None = Field(None, alias="ppk-secret") + ppk_identity: str | None = Field(None, alias="ppk-identity") + username_sensitivity: str | None = Field(None, alias="username-sensitivity") + + +class UserObjGroup(BaseModel): + """user/group - User groups""" + + name: str + q_origin_key: str + id_: int = Field(alias="id") + group_type: str = Field(alias="group-type") + authtimeout: int | None = None + auth_concurrent_override: str | None = Field(None, alias="auth-concurrent-override") + auth_concurrent_value: int | None = Field(None, alias="auth-concurrent-value") + http_digest_realm: str | None = Field(None, alias="http-digest-realm") + sso_attribute_value: str | None = Field(None, alias="sso-attribute-value") + member: list[NameRef] = [] + match: list[Any] = [] + + # Guest user specific fields + user_id: str | None = Field(None, alias="user-id") + password: str | None = None + user_name: str | None = Field(None, alias="user-name") + sponsor: str | None = None + company: str | None = None + email: str | None = None + mobile_phone: str | None = Field(None, alias="mobile-phone") + sms_server: str | None = Field(None, alias="sms-server") + sms_custom_server: str | None = Field(None, alias="sms-custom-server") + expire_type: str | None = Field(None, alias="expire-type") + expire: int | None = None + max_accounts: int | None = Field(None, alias="max-accounts") + multiple_guest_add: str | None = Field(None, alias="multiple-guest-add") + guest: list[Any] = [] + + +# ============================================================================ +# Rule Models +# ============================================================================ + + +class Rule(BaseModel): + """firewall/policy - Firewall access rules""" + + policyid: int + q_origin_key: int + status: Literal["enable", "disable"] + name: str + uuid: str + uuid_idx: int | None = Field(None, alias="uuid-idx") + + # Interfaces + srcintf: list[NameRef] = [] + dstintf: list[NameRef] = [] + + # Action + action: str # Seen: "accept", "deny" (code checks for 'deny'), possibly also: "ipsec" + + # NAT + nat: str | None = None + nat64: str | None = None + nat46: str | None = None + + # Addresses + srcaddr: list[NameRef] = [] + dstaddr: list[NameRef] = [] + srcaddr6: list[NameRef] = [] + dstaddr6: list[NameRef] = [] + + # Internet services + internet_service: str | None = Field(None, alias="internet-service") + internet_service_name: list[NameRef] = Field(default=[], alias="internet-service-name") + internet_service_group: list[NameRef] = Field(default=[], alias="internet-service-group") + internet_service_custom: list[NameRef] = Field(default=[], alias="internet-service-custom") + internet_service_custom_group: list[NameRef] = Field(default=[], alias="internet-service-custom-group") + internet_service_src: str | None = Field(None, alias="internet-service-src") + internet_service_src_name: list[NameRef] = Field(default=[], alias="internet-service-src-name") + internet_service_src_group: list[NameRef] = Field(default=[], alias="internet-service-src-group") + internet_service_src_custom: list[NameRef] = Field(default=[], alias="internet-service-src-custom") + internet_service_src_custom_group: list[NameRef] = Field(default=[], alias="internet-service-src-custom-group") + + # IPv6 Internet services + internet_service6: str | None = Field(None, alias="internet-service6") + internet_service6_name: list[NameRef] = Field(default=[], alias="internet-service6-name") + internet_service6_group: list[NameRef] = Field(default=[], alias="internet-service6-group") + internet_service6_custom: list[NameRef] = Field(default=[], alias="internet-service6-custom") + internet_service6_custom_group: list[NameRef] = Field(default=[], alias="internet-service6-custom-group") + internet_service6_src: str | None = Field(None, alias="internet-service6-src") + internet_service6_src_name: list[NameRef] = Field(default=[], alias="internet-service6-src-name") + internet_service6_src_group: list[NameRef] = Field(default=[], alias="internet-service6-src-group") + internet_service6_src_custom: list[NameRef] = Field(default=[], alias="internet-service6-src-custom") + internet_service6_src_custom_group: list[NameRef] = Field(default=[], alias="internet-service6-src-custom-group") + + # Network services + network_service_dynamic: list[Any] = Field(default=[], alias="network-service-dynamic") + network_service_src_dynamic: list[Any] = Field(default=[], alias="network-service-src-dynamic") + + # Services + service: list[NameRef] = [] + + # Schedule + schedule: str | None = None + schedule_timeout: str | None = Field(None, alias="schedule-timeout") + + # Policy expiry + policy_expiry: str | None = Field(None, alias="policy-expiry") + policy_expiry_date: str | None = Field(None, alias="policy-expiry-date") + + # Negation flags + srcaddr_negate: str | None = Field(None, alias="srcaddr-negate") + srcaddr6_negate: str | None = Field(None, alias="srcaddr6-negate") + dstaddr_negate: str | None = Field(None, alias="dstaddr-negate") + dstaddr6_negate: str | None = Field(None, alias="dstaddr6-negate") + service_negate: str | None = Field(None, alias="service-negate") + internet_service_negate: str | None = Field(None, alias="internet-service-negate") + internet_service_src_negate: str | None = Field(None, alias="internet-service-src-negate") + internet_service6_negate: str | None = Field(None, alias="internet-service6-negate") + internet_service6_src_negate: str | None = Field(None, alias="internet-service6-src-negate") + + # Logging + logtraffic: str | None = None # Seen: "disable", "utm", likely also: "all" + logtraffic_start: str | None = Field(None, alias="logtraffic-start") + + # Security profiles + utm_status: str | None = Field(None, alias="utm-status") + inspection_mode: str | None = Field(None, alias="inspection-mode") + profile_type: str | None = Field(None, alias="profile-type") + profile_group: str | None = Field(None, alias="profile-group") + profile_protocol_options: str | None = Field(None, alias="profile-protocol-options") + ssl_ssh_profile: str | None = Field(None, alias="ssl-ssh-profile") + av_profile: str | None = Field(None, alias="av-profile") + webfilter_profile: str | None = Field(None, alias="webfilter-profile") + dnsfilter_profile: str | None = Field(None, alias="dnsfilter-profile") + emailfilter_profile: str | None = Field(None, alias="emailfilter-profile") + dlp_profile: str | None = Field(None, alias="dlp-profile") + file_filter_profile: str | None = Field(None, alias="file-filter-profile") + ips_sensor: str | None = Field(None, alias="ips-sensor") + application_list: str | None = Field(None, alias="application-list") + voip_profile: str | None = Field(None, alias="voip-profile") + waf_profile: str | None = Field(None, alias="waf-profile") + ssh_filter_profile: str | None = Field(None, alias="ssh-filter-profile") + + # NAT configuration + ippool: str | None = None + poolname: list[NameRef] = [] + poolname6: list[NameRef] = [] + permit_any_host: str | None = Field(None, alias="permit-any-host") + permit_stun_host: str | None = Field(None, alias="permit-stun-host") + fixedport: str | None = None + natip: str | None = None + + # Direction + inbound: str | None = None + outbound: str | None = None + natinbound: str | None = None + natoutbound: str | None = None + + # VIP matching + match_vip: str | None = Field(None, alias="match-vip") + match_vip_only: str | None = Field(None, alias="match-vip-only") + + # Users and authentication + groups: list[NameRef] = [] + users: list[NameRef] = [] + fsso_groups: list[NameRef] = Field(default=[], alias="fsso-groups") + auth_path: str | None = Field(None, alias="auth-path") + + # VPN + vpntunnel: str | None = None + + # Traffic shaping + traffic_shaper: str | None = Field(None, alias="traffic-shaper") + traffic_shaper_reverse: str | None = Field(None, alias="traffic-shaper-reverse") + per_ip_shaper: str | None = Field(None, alias="per-ip-shaper") + + # QoS + tos: str | None = None + tos_mask: str | None = Field(None, alias="tos-mask") + tos_negate: str | None = Field(None, alias="tos-negate") + vlan_cos_fwd: int | None = Field(None, alias="vlan-cos-fwd") + vlan_cos_rev: int | None = Field(None, alias="vlan-cos-rev") + + # Comments and labels + comments: str | None = None + label: str | None = None + global_label: str | None = Field(None, alias="global-label") + + # ZTNA + ztna_status: str | None = Field(None, alias="ztna-status") + ztna_ems_tag: list[Any] = Field(default=[], alias="ztna-ems-tag") + ztna_geo_tag: list[Any] = Field(default=[], alias="ztna-geo-tag") + + # Reputation + reputation_minimum: int | None = Field(None, alias="reputation-minimum") + reputation_direction: str | None = Field(None, alias="reputation-direction") + reputation_minimum6: int | None = Field(None, alias="reputation-minimum6") + reputation_direction6: str | None = Field(None, alias="reputation-direction6") + + # Misc + send_deny_packet: str | None = Field(None, alias="send-deny-packet") + firewall_session_dirty: str | None = Field(None, alias="firewall-session-dirty") + session_ttl: str | None = Field(None, alias="session-ttl") + anti_replay: str | None = Field(None, alias="anti-replay") + tcp_session_without_syn: str | None = Field(None, alias="tcp-session-without-syn") + geoip_anycast: str | None = Field(None, alias="geoip-anycast") + geoip_match: str | None = Field(None, alias="geoip-match") + dynamic_shaping: str | None = Field(None, alias="dynamic-shaping") + passive_wan_health_measurement: str | None = Field(None, alias="passive-wan-health-measurement") + auto_asic_offload: str | None = Field(None, alias="auto-asic-offload") + np_acceleration: str | None = Field(None, alias="np-acceleration") + rtp_nat: str | None = Field(None, alias="rtp-nat") + rtp_addr: list[Any] = Field(default=[], alias="rtp-addr") + wccp: str | None = None + fec: str | None = None + + # Authentication + ntlm: str | None = None + ntlm_guest: str | None = Field(None, alias="ntlm-guest") + ntlm_enabled_browsers: list[Any] = Field(default=[], alias="ntlm-enabled-browsers") + fsso_agent_for_ntlm: str | None = Field(None, alias="fsso-agent-for-ntlm") + disclaimer: str | None = None + email_collect: str | None = Field(None, alias="email-collect") + auth_cert: str | None = Field(None, alias="auth-cert") + auth_redirect_addr: str | None = Field(None, alias="auth-redirect-addr") + + # Redirect + redirect_url: str | None = Field(None, alias="redirect-url") + http_policy_redirect: str | None = Field(None, alias="http-policy-redirect") + ssh_policy_redirect: str | None = Field(None, alias="ssh-policy-redirect") + webproxy_profile: str | None = Field(None, alias="webproxy-profile") + webproxy_forward_server: str | None = Field(None, alias="webproxy-forward-server") + + # Diffserv + diffserv_copy: str | None = Field(None, alias="diffserv-copy") + diffserv_forward: str | None = Field(None, alias="diffserv-forward") + diffserv_reverse: str | None = Field(None, alias="diffserv-reverse") + diffservcode_forward: str | None = Field(None, alias="diffservcode-forward") + diffservcode_rev: str | None = Field(None, alias="diffservcode-rev") + + # TCP MSS + tcp_mss_sender: int | None = Field(None, alias="tcp-mss-sender") + tcp_mss_receiver: int | None = Field(None, alias="tcp-mss-receiver") + + # Other + identity_based_route: str | None = Field(None, alias="identity-based-route") + block_notification: str | None = Field(None, alias="block-notification") + custom_log_fields: list[Any] = Field(default=[], alias="custom-log-fields") + replacemsg_override_group: str | None = Field(None, alias="replacemsg-override-group") + timeout_send_rst: str | None = Field(None, alias="timeout-send-rst") + captive_portal_exempt: str | None = Field(None, alias="captive-portal-exempt") + decrypted_traffic_mirror: str | None = Field(None, alias="decrypted-traffic-mirror") + dsri: str | None = None + radius_mac_auth_bypass: str | None = Field(None, alias="radius-mac-auth-bypass") + delay_tcp_npu_session: str | None = Field(None, alias="delay-tcp-npu-session") + vlan_filter: str | None = Field(None, alias="vlan-filter") + sgt_check: str | None = Field(None, alias="sgt-check") + sgt: list[Any] = [] + src_vendor_mac: list[Any] = Field(default=[], alias="src-vendor-mac") + sctp_filter_profile: str | None = Field(None, alias="sctp-filter-profile") + icap_profile: str | None = Field(None, alias="icap-profile") + cifs_profile: str | None = Field(None, alias="cifs-profile") + videofilter_profile: str | None = Field(None, alias="videofilter-profile") + + +# ============================================================================ +# Main Configuration Model +# ============================================================================ + + +class FortiOSConfig(BaseModel): + """Complete FortiOS configuration structure""" + + # Network objects + nw_obj_address: list[NwObjAddress] = Field(default=[], alias="nw_obj_firewall/address") + nw_obj_address6: list[NwObjAddress6] = Field(default=[], alias="nw_obj_firewall/address6") + nw_obj_addrgrp: list[NwObjAddrGrp] = Field(default=[], alias="nw_obj_firewall/addrgrp") + nw_obj_addrgrp6: list[NwObjAddrGrp6] = Field(default=[], alias="nw_obj_firewall/addrgrp6") + nw_obj_ippool: list[NwObjIpPool] = Field(default=[], alias="nw_obj_firewall/ippool") + nw_obj_vip: list[NwObjVip] = Field(default=[], alias="nw_obj_firewall/vip") + nw_obj_internet_service: list[NwObjInternetService] = Field(default=[], alias="nw_obj_firewall/internet-service") + nw_obj_internet_service_group: list[NwObjInternetServiceGroup] = Field( + default=[], alias="nw_obj_firewall/internet-service-group" + ) + + # Service objects + svc_obj_application_list: list[SvcObjApplicationList] = Field(default=[], alias="svc_obj_application/list") + svc_obj_application_group: list[SvcObjApplicationGroup] = Field(default=[], alias="svc_obj_application/group") + svc_obj_custom: list[SvcObjCustom] = Field(default=[], alias="svc_obj_firewall.service/custom") + svc_obj_group: list[SvcObjGroup] = Field(default=[], alias="svc_obj_firewall.service/group") + + # User objects + user_obj_local: list[UserObjLocal] = Field(default=[], alias="user_obj_user/local") + user_obj_group: list[UserObjGroup] = Field(default=[], alias="user_obj_user/group") + + # Zone objects + zone_objects: list[ZoneObject] = [] + + # Rules + rules: list[Rule] = [] + rules_nat: dict[str, Any] = Field(default_factory=dict) diff --git a/roles/importer/files/importer/fw_modules/fortiosmanagementREST/fos_network.py b/roles/importer/files/importer/fw_modules/fortiosmanagementREST/fos_network.py new file mode 100644 index 0000000000..588dab8d55 --- /dev/null +++ b/roles/importer/files/importer/fw_modules/fortiosmanagementREST/fos_network.py @@ -0,0 +1,274 @@ +from collections.abc import Generator +from ipaddress import IPv6Address + +import fwo_const +from fw_modules.fortiosmanagementREST.fos_models import FortiOSConfig, NwObjAddress6 +from fwo_log import FWOLogger +from models.networkobject import NetworkObject +from netaddr import IPAddress, IPNetwork + +DEFAULT_IPv4 = (IPNetwork("0.0.0.0/32"), IPNetwork("255.255.255.255/32")) + + +def normalize_ipv4_network_objects( + native_config: FortiOSConfig, nw_obj_lookup_dict: dict[str, str] +) -> Generator[NetworkObject]: + """ + Normalize IPv4 network objects from the native FortiOS configuration. + + Args: + native_config (FortiOSConfig): The native FortiOS configuration. + nw_obj_lookup_dict: Lookup dictionary for network object names to UIDs. + + Yields: + NetworkObject: The normalized network object. + + """ + for ip4_obj in native_config.nw_obj_address: + obj_typ = "host" + if ip4_obj.subnet: + host, mask = ip4_obj.subnet.split(" ") + # get ip_start/32 and ip_end/32 from subnet + network = IPNetwork(f"{host}/{mask}") + ip_start = IPNetwork(f"{IPAddress(network.first)}/32") + ip_end = IPNetwork(f"{IPAddress(network.first + network.size - 1)}/32") + if network.size > 1: + obj_typ = "network" + elif ip4_obj.start_ip: + ip_start = IPNetwork(f"{ip4_obj.start_ip}/32") + ip_end = IPNetwork(f"{ip4_obj.end_ip}/32") + obj_typ = "ip_range" + else: + FWOLogger.warning( + f"normalize_ipv4_network_objects: Unable to determine IP range for network object {ip4_obj.name}, setting to full range." + ) + ip_start, ip_end = DEFAULT_IPv4 + + nw_obj_lookup_dict[ip4_obj.name] = ip4_obj.uuid + + yield NetworkObject( + obj_name=ip4_obj.name, + obj_uid=ip4_obj.uuid, + obj_typ=obj_typ, + obj_ip=ip_start, + obj_ip_end=ip_end, + obj_color=fwo_const.DEFAULT_COLOR, + obj_comment=ip4_obj.comment, + ) + + +def normalize_single_ipv6_network_object(ip6_obj: NwObjAddress6, nw_obj_lookup_dict: dict[str, str]) -> NetworkObject: + """ + Normalize a single IPv6 network object from the native FortiOS configuration. + + Args: + ip6_obj (NwObjAddress6): The native IPv6 network object. + nw_obj_lookup_dict: Lookup dictionary for network object names to UIDs. + + Returns: + NetworkObject: The normalized network object. + + """ + obj_typ = "host" + if ip6_obj.ip6: + network = IPNetwork(ip6_obj.ip6, version=6) + ip_start = IPNetwork(f"{IPv6Address(network.first)}/128", version=6) + if ip6_obj.end_ip and ip6_obj.end_ip != "::": + ip_end = IPNetwork(f"{ip6_obj.end_ip}/128", version=6) + if ip_start != ip_end: + obj_typ = "ip_range" + else: + ip_end = IPNetwork(f"{IPv6Address(network.last)}/128", version=6) + if network.size > 1: + obj_typ = "network" + else: + FWOLogger.warning( + f"normalize_ipv6_network_objects: Unable to determine IP range for network object {ip6_obj.name}, setting to full range." + ) + ip_start = IPNetwork("::/128", version=6) + ip_end = IPNetwork("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff/128", version=6) + + nw_obj_lookup_dict[ip6_obj.name] = ip6_obj.uuid + + return NetworkObject( + obj_name=ip6_obj.name, + obj_uid=ip6_obj.uuid, + obj_typ=obj_typ, + obj_ip=ip_start, + obj_ip_end=ip_end, + obj_color=fwo_const.DEFAULT_COLOR, + obj_comment=ip6_obj.comment, + ) + + +def normalize_ipv6_network_objects( + native_config: FortiOSConfig, nw_obj_lookup_dict: dict[str, str] +) -> Generator[NetworkObject]: + """ + Normalize IPv6 network objects from the native FortiOS configuration. + + Args: + native_config (FortiOSConfig): The native FortiOS configuration. + nw_obj_lookup_dict: Lookup dictionary for network object names to UIDs. + + Yields: + NetworkObject: The normalized network object. + + """ + yield from ( + normalize_single_ipv6_network_object(ip6_obj, nw_obj_lookup_dict) for ip6_obj in native_config.nw_obj_address6 + ) + + +def normalize_nwobj_groups( + native_config: FortiOSConfig, nw_obj_lookup_dict: dict[str, str] +) -> Generator[NetworkObject]: + """ + Normalize address, address6 and internet service group objects from the native FortiOS configuration. + + Args: + native_config (FortiOSConfig): The native FortiOS configuration. + nw_obj_lookup_dict: Lookup dictionary for network object names to UIDs. + + Yields: + NetworkObject: The normalized network object. + + """ + for addrgrp_obj in ( + native_config.nw_obj_addrgrp + native_config.nw_obj_addrgrp6 + native_config.nw_obj_internet_service_group + ): + members = [member.name for member in addrgrp_obj.member] + member_refs: list[str] = [] + for member in members: + if member not in nw_obj_lookup_dict: + FWOLogger.warning( + f"normalize_nwobj_groups: Member object '{member}' of group '{addrgrp_obj.name}' not found in network object lookup." + ) + else: + member_refs.append(nw_obj_lookup_dict[member]) + + # uid is uuid for addrgrp and addrgrp6, name for internet service group + obj_uid = getattr(addrgrp_obj, "uuid", None) or addrgrp_obj.name + nw_obj_lookup_dict[addrgrp_obj.name] = obj_uid + + yield NetworkObject( + obj_name=addrgrp_obj.name, + obj_uid=obj_uid, + obj_typ="group", + obj_ip=None, + obj_ip_end=None, + obj_member_names=fwo_const.LIST_DELIMITER.join(members), + obj_member_refs=fwo_const.LIST_DELIMITER.join(member_refs), + obj_color=fwo_const.DEFAULT_COLOR, + obj_comment=addrgrp_obj.comment, + ) + + +def normalize_ip_pools(native_config: FortiOSConfig, nw_obj_lookup_dict: dict[str, str]) -> Generator[NetworkObject]: + """ + Normalize IP pool objects from the native FortiOS configuration. + + Args: + native_config (FortiOSConfig): The native FortiOS configuration. + nw_obj_lookup_dict: Lookup dictionary for network object names to UIDs. + + Yields: + NetworkObject: The normalized network object. + + """ + for ippool_obj in native_config.nw_obj_ippool: + if ippool_obj.startip and ippool_obj.endip: + ip_start = IPNetwork(f"{ippool_obj.startip}/32") + ip_end = IPNetwork(f"{ippool_obj.endip}/32") + else: + FWOLogger.warning( + f"normalize_ip_pools: Unable to determine IP range for IP pool object {ippool_obj.name}, setting to full range." + ) + ip_start, ip_end = DEFAULT_IPv4 + nw_obj_lookup_dict[ippool_obj.name] = ippool_obj.name + + yield NetworkObject( + obj_name=ippool_obj.name, + obj_uid=ippool_obj.name, + obj_typ="ip_range", + obj_ip=ip_start, + obj_ip_end=ip_end, + obj_color=fwo_const.DEFAULT_COLOR, + obj_comment=ippool_obj.comments, + ) + + +def normalize_vips(native_config: FortiOSConfig, nw_obj_lookup_dict: dict[str, str]) -> Generator[NetworkObject]: + """ + Normalize VIP objects from the native FortiOS configuration. + + Args: + native_config (FortiOSConfig): The native FortiOS configuration. + nw_obj_lookup_dict: Lookup dictionary for network object names to UIDs. + + Yields: + NetworkObject: The normalized network object. + + """ + raise NotImplementedError("normalize_vips is not yet implemented.") # TODO: need test data + + +def normalize_internet_services( + native_config: FortiOSConfig, nw_obj_lookup_dict: dict[str, str] +) -> Generator[NetworkObject]: + """ + Normalize internet service objects from the native FortiOS configuration. + + Args: + native_config (FortiOSConfig): The native FortiOS configuration. + nw_obj_lookup_dict: Lookup dictionary for network object names to UIDs. + + Yields: + NetworkObject: The normalized network object. + + """ + for is_obj in native_config.nw_obj_internet_service: + start_ip, end_ip = DEFAULT_IPv4 + nw_obj_lookup_dict[is_obj.name] = is_obj.name + yield NetworkObject( + obj_name=is_obj.name, + obj_uid=is_obj.name, + obj_typ="network", + obj_ip=start_ip, + obj_ip_end=end_ip, + obj_color=fwo_const.DEFAULT_COLOR, + obj_comment=None, + ) + + +def normalize_network_objects( + native_config: FortiOSConfig, nw_obj_lookup_dict: dict[str, str] +) -> Generator[NetworkObject]: + """ + Normalize all network objects from the native FortiOS configuration. + + Args: + native_config (FortiOSConfig): The native FortiOS configuration. + nw_obj_lookup_dict: Lookup dictionary for network object names to UIDs. + + Yields: + NetworkObject: The normalized network object. + + """ + yield from normalize_ipv4_network_objects(native_config, nw_obj_lookup_dict) + yield from normalize_ipv6_network_objects(native_config, nw_obj_lookup_dict) + # groups may use any of the above objects as members + yield from normalize_nwobj_groups(native_config, nw_obj_lookup_dict) + yield from normalize_ip_pools(native_config, nw_obj_lookup_dict) + # TODO: implement vips + yield from normalize_internet_services(native_config, nw_obj_lookup_dict) + # "Original" network object for natting + yield NetworkObject( + obj_name="Original", + obj_uid="Original", + obj_typ="network", + obj_ip=DEFAULT_IPv4[0], + obj_ip_end=DEFAULT_IPv4[1], + obj_color=fwo_const.DEFAULT_COLOR, + obj_comment="'original' network object created by FWO importer for NAT purposes", + ) diff --git a/roles/importer/files/importer/fw_modules/fortiosmanagementREST/fos_normalizer.py b/roles/importer/files/importer/fw_modules/fortiosmanagementREST/fos_normalizer.py new file mode 100644 index 0000000000..709630bd6a --- /dev/null +++ b/roles/importer/files/importer/fw_modules/fortiosmanagementREST/fos_normalizer.py @@ -0,0 +1,127 @@ +from collections.abc import Generator +from typing import TYPE_CHECKING, Any + +import fwo_const +from fw_modules.fortiosmanagementREST.fos_models import FortiOSConfig +from fw_modules.fortiosmanagementREST.fos_network import normalize_network_objects +from fw_modules.fortiosmanagementREST.fos_rule import get_rule_installon, normalize_access_rules +from fw_modules.fortiosmanagementREST.fos_service import normalize_service_objects +from fw_modules.fortiosmanagementREST.fos_zone import collect_zones +from fwo_log import FWOLogger +from model_controllers.management_controller import ManagementController +from models.fwconfig_normalized import FwConfigNormalized +from models.gateway import Gateway +from models.rulebase import Rulebase +from models.rulebase_link import RulebaseLinkUidBased + +if TYPE_CHECKING: + from models.rule import RuleNormalized + + +def normalize_config(native_config: FortiOSConfig, mgm_details: ManagementController) -> FwConfigNormalized: + """ + Normalize FortiOS Management REST native configuration. + + Args: + native_config (FortiOSConfig): The native FortiOS configuration. + mgm_details (ManagementController): The management details object. + + Returns: + FwConfigNormalized: The normalized configuration. + + """ + normalized_config = FwConfigNormalized() + + nw_obj_lookup_dict: dict[str, str] = {} + + for nw_obj in normalize_network_objects(native_config, nw_obj_lookup_dict): + normalized_config.network_objects[nw_obj.obj_uid] = nw_obj + FWOLogger.debug(f"Normalized {len(normalized_config.network_objects)} network objects.") + + for svc_obj in normalize_service_objects(native_config): + normalized_config.service_objects[svc_obj.svc_uid] = svc_obj + FWOLogger.debug(f"Normalized {len(normalized_config.service_objects)} service objects.") + + for user in normalize_users(native_config): + normalized_config.users[user["user_uid"]] = user + FWOLogger.debug(f"Normalized {len(normalized_config.users)} user objects.") + + for zone in collect_zones(native_config): + normalized_config.zone_objects[zone] = {"zone_name": zone} + + rulebase_name = "access_rules" + rules: dict[str, RuleNormalized] = {} + for rule in normalize_access_rules(native_config, mgm_details, nw_obj_lookup_dict): + if not rule.rule_uid: + FWOLogger.warning(f"Skipping rule '{rule.rule_name}' without UID.") + continue + rules[rule.rule_uid] = rule + rulebase = Rulebase(uid=rulebase_name, name=rulebase_name, mgm_uid=mgm_details.uid, is_global=False, rules=rules) + + rulebase_links = [ + RulebaseLinkUidBased( + to_rulebase_uid=rulebase.uid, + link_type="ordered", + is_initial=True, + is_global=False, + is_section=False, + ) + ] + + gateway_name = get_rule_installon(mgm_details) + gateway = Gateway( + Uid=gateway_name, + Name=gateway_name, + Routing=[], + RulebaseLinks=rulebase_links, + GlobalPolicyUid=None, + EnforcedPolicyUids=[], + EnforcedNatPolicyUids=[], + ImportDisabled=False, + ShowInUI=True, + ) + + normalized_config.gateways = [gateway] + normalized_config.rulebases = [rulebase] + + return normalized_config + + +def normalize_users(native_config: FortiOSConfig) -> Generator[dict[str, Any]]: + """ + Normalize a user object. + + Args: + native_config (FortiOSConfig): The native FortiOS configuration. + + Yields: + dict[str, Any]: The normalized user object. + + """ + # user/local + for user_obj in native_config.user_obj_local: + yield { + "user_name": user_obj.name, + "user_uid": user_obj.name, + "user_typ": "simple", + "user_color": fwo_const.DEFAULT_COLOR, + "user_comment": None, + "user_member_refs": None, + "user_member_names": None, + } + + # user/group + for user_obj in native_config.user_obj_group: + yield { + "user_name": user_obj.name, + "user_uid": user_obj.name, + "user_typ": "group", + "user_color": fwo_const.DEFAULT_COLOR, + "user_comment": None, + "user_member_refs": ( + fwo_const.LIST_DELIMITER.join([member.name for member in user_obj.member]) if user_obj.member else None + ), + "user_member_names": ( + fwo_const.LIST_DELIMITER.join([member.name for member in user_obj.member]) if user_obj.member else None + ), + } diff --git a/roles/importer/files/importer/fw_modules/fortiosmanagementREST/fos_rule.py b/roles/importer/files/importer/fw_modules/fortiosmanagementREST/fos_rule.py new file mode 100644 index 0000000000..8933018eff --- /dev/null +++ b/roles/importer/files/importer/fw_modules/fortiosmanagementREST/fos_rule.py @@ -0,0 +1,171 @@ +from collections.abc import Generator + +import fwo_const +from fw_modules.fortiosmanagementREST import fos_zone +from fw_modules.fortiosmanagementREST.fos_models import FortiOSConfig, Rule +from fwo_exceptions import FwoImporterError +from model_controllers.management_controller import ManagementController +from models.rule import RuleAction, RuleNormalized, RuleTrack, RuleType + + +def get_rule_installon(mgm_details: ManagementController) -> str: + if mgm_details.devices and "name" in mgm_details.devices[0]: + return mgm_details.devices[0]["name"] + if mgm_details.name: + return mgm_details.name + if mgm_details.hostname: + return mgm_details.hostname + raise FwoImporterError("Management details must contain a device name or management name/hostname.") + + +def normalize_rule_addresses(rule: Rule, nw_obj_lookup_dict: dict[str, str]) -> tuple[str, str, str, str]: + """ + Normalize rule addresses from a FortiOS rule. + + Args: + rule: The FortiOS rule object. + nw_obj_lookup_dict: Lookup dictionary for network object names to UIDs. + + Returns: + tuple[str, str, str, str]: The normalized source addresses, source references, + destination addresses, destination references. + + """ + if rule.internet_service_src_name: + rule_src_names = [src.name for src in rule.internet_service_src_name] + else: + rule_src_names = [src.name for src in rule.srcaddr + rule.srcaddr6] + + if not rule_src_names: + raise FwoImporterError(f"Rule '{rule.name}' has no source addresses defined.") + for src in rule_src_names: + if src not in nw_obj_lookup_dict: + raise FwoImporterError(f"Source network object '{src}' not found in network object lookup.") + + if rule.internet_service_name: + rule_dst_names = [dst.name for dst in rule.internet_service_name] + else: + rule_dst_names = [dst.name for dst in rule.dstaddr + rule.dstaddr6] + + if not rule_dst_names: + raise FwoImporterError(f"Rule '{rule.name}' has no destination addresses defined.") + for dst in rule_dst_names: + if dst not in nw_obj_lookup_dict: + raise FwoImporterError(f"Destination network object '{dst}' not found in network object lookup.") + + rule_src = fwo_const.LIST_DELIMITER.join(rule_src_names) + rule_src_refs = fwo_const.LIST_DELIMITER.join(nw_obj_lookup_dict[src] for src in rule_src_names) + rule_dst = fwo_const.LIST_DELIMITER.join(rule_dst_names) + rule_dst_refs = fwo_const.LIST_DELIMITER.join(nw_obj_lookup_dict[dst] for dst in rule_dst_names) + + return rule_src, rule_src_refs, rule_dst, rule_dst_refs + + +def normalize_rule_services(rule: Rule) -> tuple[str, str]: + """ + Normalize rule services from a FortiOS rule. + + Args: + rule: The FortiOS rule object. + + Returns: + tuple[str, str]: The normalized service names and service references. + + """ + rule_svc_names = [svc.name for svc in rule.service] + + if rule.internet_service_name or rule.internet_service_src_name: + rule_svc_names.append("Internet Service") + + if not rule_svc_names: + raise FwoImporterError(f"Rule '{rule.name}' has no services defined.") + + rule_svc = fwo_const.LIST_DELIMITER.join(rule_svc_names) + rule_svc_refs = rule_svc # Service objects use names as UIDs + + return rule_svc, rule_svc_refs + + +def normalize_rule_zones(rule: Rule) -> tuple[str | None, str | None]: + """ + Normalize rule zones from a FortiOS rule. + + Args: + rule: The FortiOS rule object. + + Returns: + tuple[str, str]: The normalized source zones and destination zones. + + """ + rule_src_zone = None + rule_dst_zone = None + + rule_src_zone_names = [fos_zone.normalize_zone_name(intf.name) for intf in rule.srcintf] + rule_dst_zone_names = [fos_zone.normalize_zone_name(intf.name) for intf in rule.dstintf] + + if rule_src_zone_names: + rule_src_zone = fwo_const.LIST_DELIMITER.join(rule_src_zone_names) + if rule_dst_zone_names: + rule_dst_zone = fwo_const.LIST_DELIMITER.join(rule_dst_zone_names) + + return rule_src_zone, rule_dst_zone + + +def normalize_access_rules( + native_config: FortiOSConfig, mgm_details: ManagementController, nw_obj_lookup_dict: dict[str, str] +) -> Generator[RuleNormalized]: + """ + Normalize access rules from the native FortiOS configuration. + + Args: + native_config (FortiOSConfig): The native FortiOS configuration. + mgm_details (ManagementController): The management details object. + nw_obj_lookup_dict (dict[str, str]): Lookup dictionary for network object names to UIDs. + + Yields: + RuleNormalized: The normalized access rule. + + """ + rule_installon = get_rule_installon(mgm_details) + + for rule in native_config.rules: + rule_type = RuleType.ACCESS + rule_name = rule.name + rule_uid = rule.uuid + # TODO: rule_ruleid from rule.policyid + rule_implied = False + rule_comment = rule.comments + rule_src, rule_src_refs, rule_dst, rule_dst_refs = normalize_rule_addresses(rule, nw_obj_lookup_dict) + rule_svc, rule_svc_refs = normalize_rule_services(rule) + rule_src_neg = rule.srcaddr_negate == "enable" + rule_dst_neg = rule.dstaddr_negate == "enable" + rule_svc_neg = rule.service_negate == "enable" + rule_src_zone, rule_dst_zone = normalize_rule_zones(rule) + rule_action = RuleAction.DROP if rule.action == "deny" else RuleAction.ACCEPT + rule_disabled = rule.status not in {"enable", 1} + rule_track = RuleTrack.NONE if rule.logtraffic == "disable" else RuleTrack.LOG + + yield RuleNormalized( + rule_num=0, + rule_num_numeric=0.0, + rule_name=rule_name, + rule_type=rule_type, + rule_uid=rule_uid, + rule_implied=rule_implied, + rule_comment=rule_comment, + rule_src=rule_src, + rule_src_refs=rule_src_refs, + rule_dst=rule_dst, + rule_dst_refs=rule_dst_refs, + rule_svc=rule_svc, + rule_svc_refs=rule_svc_refs, + rule_src_neg=rule_src_neg, + rule_dst_neg=rule_dst_neg, + rule_svc_neg=rule_svc_neg, + rule_src_zone=rule_src_zone, + rule_dst_zone=rule_dst_zone, + rule_action=rule_action, + rule_disabled=rule_disabled, + rule_installon=rule_installon, + rule_track=rule_track, + ) diff --git a/roles/importer/files/importer/fw_modules/fortiosmanagementREST/fos_service.py b/roles/importer/files/importer/fw_modules/fortiosmanagementREST/fos_service.py new file mode 100644 index 0000000000..84792eff86 --- /dev/null +++ b/roles/importer/files/importer/fw_modules/fortiosmanagementREST/fos_service.py @@ -0,0 +1,259 @@ +from collections.abc import Generator + +import fwo_const +from fw_modules.fortiosmanagementREST.fos_models import FortiOSConfig, SvcObjCustom +from models.serviceobject import ServiceObject + + +def normalize_app_service_objects(native_config: FortiOSConfig) -> Generator[ServiceObject]: + """ + Normalize service objects from the native FortiOS configuration. + + Args: + native_config (FortiOSConfig): The native FortiOS configuration. + + Yields: + ServiceObject: The normalized service object. + + """ + for svc_obj in native_config.svc_obj_application_list: + yield ServiceObject( + svc_uid=svc_obj.name, + svc_name=svc_obj.name, + svc_color=fwo_const.DEFAULT_COLOR, + svc_typ="simple", + ) + + +def parse_ports(ports: str) -> list[tuple[int | None, int | None]]: + """ + Parse ports string into a list of port ranges. Possible formats: + - "80" + - "80-90" + - "80 90 100-110" + - "513:512-514" (destination:source) -> only destination ports are considered + + Args: + ports (str): The ports string. + + Returns: + list[tuple[int | None, int | None]]: List of port ranges as tuples (start, end). + + """ + port_ranges: list[tuple[int | None, int | None]] = [] + for part in ports.split(): + port_str = part + if ":" in port_str: + dest_port, _ = port_str.split(":", 1) + port_str = dest_port + if "-" in port_str: + start_str, end_str = port_str.split("-", 1) + port_ranges.append((int(start_str), int(end_str))) + else: + port = int(port_str) + port_ranges.append((port, port)) + return port_ranges + + +def get_svcobjs_from_portrange( + portrange: str, base_name: str, comment: str | None, ip_proto: int, members: list[str] +) -> Generator[ServiceObject]: + """ + Generate service objects from a port range string. + + Args: + portrange (str): The port range string. + base_name (str): The base name for the service object. + comment (str | None): The comment for the service object. + ip_proto (int): The IP protocol number. + members (list[str]): List reference to collect members for parent group object. + + + Yields: + ServiceObject: The generated service object. + + """ + port_ranges = parse_ports(portrange) + for svc_port, svc_port_end in port_ranges: + name = base_name + if len(port_ranges) > 1: + name += f"_{svc_port}" + if svc_port != svc_port_end: + name += f"-{svc_port_end}" + members.append(name) + yield ServiceObject( + svc_name=name, + svc_uid=name, + svc_typ="simple", + ip_proto=ip_proto, + svc_port=svc_port, + svc_port_end=svc_port_end, + svc_color=fwo_const.DEFAULT_COLOR, + svc_comment=comment if len(port_ranges) == 1 else None, # only assign comment if single object + ) + + +def normalize_single_custom_service_object(svc_obj: SvcObjCustom) -> Generator[ServiceObject]: + """ + Normalize a single custom service object from the native FortiOS configuration. + + Args: + svc_obj (SvcObjCustom): The native custom service object. + + Yields: + ServiceObject: The normalized service object. + + """ + # determine if multiple port ranges are defined + split = ( + sum(1 for port_range in [svc_obj.tcp_portrange, svc_obj.udp_portrange, svc_obj.sctp_portrange] if port_range) + >= 2 # noqa: PLR2004 + ) + members: list[str] = [] + # only assign comment to parent group object + comment = svc_obj.comment if svc_obj.comment and not split else None + if svc_obj.tcp_portrange: + base_name = f"{svc_obj.name}_tcp" if split else svc_obj.name + yield from get_svcobjs_from_portrange(svc_obj.tcp_portrange, base_name, comment, ip_proto=6, members=members) + if svc_obj.udp_portrange: + base_name = f"{svc_obj.name}_udp" if split else svc_obj.name + yield from get_svcobjs_from_portrange(svc_obj.udp_portrange, base_name, comment, ip_proto=17, members=members) + if svc_obj.sctp_portrange: + base_name = f"{svc_obj.name}_sctp" if split else svc_obj.name + yield from get_svcobjs_from_portrange(svc_obj.sctp_portrange, base_name, comment, ip_proto=132, members=members) + + match svc_obj.protocol: + case "TCP/UDP/SCTP" if len(members) > 1: + # create parent group object + yield ServiceObject( + svc_name=svc_obj.name, + svc_uid=svc_obj.name, + svc_typ="group", + svc_member_names=fwo_const.LIST_DELIMITER.join(members), + svc_member_refs=fwo_const.LIST_DELIMITER.join(members), + svc_color=fwo_const.DEFAULT_COLOR, + svc_comment=svc_obj.comment, + ) + case "IP": + # IP protocol service object + yield ServiceObject( # TODO: check if ports really not available in this case + svc_name=svc_obj.name, + svc_uid=svc_obj.name, + svc_typ="simple", + ip_proto=svc_obj.protocol_number, + svc_color=fwo_const.DEFAULT_COLOR, + svc_comment=svc_obj.comment, + ) + case "ICMP" | "ICMP6": + yield ServiceObject( + svc_name=svc_obj.name, + svc_uid=svc_obj.name, + svc_typ="simple", + ip_proto=1 if svc_obj.protocol == "ICMP" else 58, + svc_color=fwo_const.DEFAULT_COLOR, + svc_comment=svc_obj.comment, + ) + case "ALL": + yield ServiceObject( + svc_name=svc_obj.name, + svc_uid=svc_obj.name, + svc_typ="simple", + ip_proto=0, + svc_color=fwo_const.DEFAULT_COLOR, + svc_comment=svc_obj.comment, + ) + case _: + pass # unknown protocol or TCP/UDP/SCTP with only one port range handled above + + +def normalize_custom_service_objects(native_config: FortiOSConfig) -> Generator[ServiceObject]: + """ + Normalize custom service objects from the native FortiOS configuration. + + Args: + native_config (FortiOSConfig): The native FortiOS configuration. + + Yields: + ServiceObject: The normalized service object. + + """ + for svc_obj in native_config.svc_obj_custom: + yield from normalize_single_custom_service_object(svc_obj) + + +def normalize_service_object_groups(native_config: FortiOSConfig) -> Generator[ServiceObject]: + """ + Normalize service object groups from the native FortiOS configuration. + + Args: + native_config (FortiOSConfig): The native FortiOS configuration. + + Yields: + ServiceObject: The normalized service object group. + + """ + for svc_obj in native_config.svc_obj_group: + yield ServiceObject( + svc_name=svc_obj.name, + svc_uid=svc_obj.name, + svc_typ="group", + svc_member_names=( + fwo_const.LIST_DELIMITER.join([member.name for member in svc_obj.member]) if svc_obj.member else None + ), + svc_member_refs=( + fwo_const.LIST_DELIMITER.join([member.name for member in svc_obj.member]) if svc_obj.member else None + ), + svc_color=fwo_const.DEFAULT_COLOR, + svc_comment=svc_obj.comment, + ) + + for svc_obj in native_config.svc_obj_application_group: # TODO: test with data if correct + yield ServiceObject( + svc_name=svc_obj.name, + svc_uid=svc_obj.name, + svc_typ="group", + svc_member_names=( + fwo_const.LIST_DELIMITER.join([app.name for app in svc_obj.application]) + if svc_obj.application + else None + ), + svc_member_refs=( + fwo_const.LIST_DELIMITER.join([app.name for app in svc_obj.application]) + if svc_obj.application + else None + ), + svc_color=fwo_const.DEFAULT_COLOR, + svc_comment=svc_obj.comment, + ) + + +def normalize_service_objects(native_config: FortiOSConfig) -> Generator[ServiceObject]: + """ + Normalize all service objects from the native FortiOS configuration. + + Args: + native_config (FortiOSConfig): The native FortiOS configuration. + + Yields: + ServiceObject: The normalized service object. + + """ + yield from normalize_app_service_objects(native_config) + yield from normalize_custom_service_objects(native_config) + yield from normalize_service_object_groups(native_config) + # "Original" service object for natting + yield ServiceObject( + svc_name="Original", + svc_uid="Original", + svc_typ="simple", + svc_color=fwo_const.DEFAULT_COLOR, + svc_comment="'original' service object created by FWO importer for NAT purposes", + ) + # "Internet service" object for internet services + yield ServiceObject( + svc_name="Internet Service", + svc_uid="Internet Service", + svc_typ="group", + svc_color=fwo_const.DEFAULT_COLOR, + svc_comment="'internet service' group object created by FWO importer for internet services", + ) diff --git a/roles/importer/files/importer/fw_modules/fortiosmanagementREST/fos_zone.py b/roles/importer/files/importer/fw_modules/fortiosmanagementREST/fos_zone.py new file mode 100644 index 0000000000..2bb6cbbc1a --- /dev/null +++ b/roles/importer/files/importer/fw_modules/fortiosmanagementREST/fos_zone.py @@ -0,0 +1,52 @@ +from collections.abc import Generator + +from fw_modules.fortiosmanagementREST.fos_models import FortiOSConfig + + +def normalize_zone_name(zone_name: str) -> str: + """ + Normalize a zone name. + + Args: + zone_name (str): The zone name. + + Returns: + str: The normalized zone name. + + """ + if zone_name == "any": + return "global" + return zone_name + + +def collect_zones(native_config: FortiOSConfig) -> Generator[str]: + """ + Normalize zone objects from the native FortiOS configuration. + + Args: + native_config (FortiOSConfig): The native FortiOS configuration. + + Yields: + str: The zone name. + + """ + seen_zones: set[str] = set() + + def record_and_yield_zone(zone_name: str) -> Generator[str]: + zone_name = normalize_zone_name(zone_name) + if zone_name not in seen_zones: + yield zone_name + seen_zones.add(zone_name) + + # zones from network objects with associated interfaces + for obj_with_intf in native_config.nw_obj_address + native_config.nw_obj_ippool: + if not obj_with_intf.associated_interface: + continue + yield from record_and_yield_zone(obj_with_intf.associated_interface) + + # zones from rules + for rule in native_config.rules: + for intf_ref in rule.srcintf + rule.dstintf: + yield from record_and_yield_zone(intf_ref.name) + + yield from record_and_yield_zone("global") # ensure "global" zone exists diff --git a/roles/importer/files/importer/fw_modules/fortiosmanagementREST/fwcommon.py b/roles/importer/files/importer/fw_modules/fortiosmanagementREST/fwcommon.py new file mode 100644 index 0000000000..5c39a011d3 --- /dev/null +++ b/roles/importer/files/importer/fw_modules/fortiosmanagementREST/fwcommon.py @@ -0,0 +1,74 @@ +from fw_modules.fortiosmanagementREST import fos_getter, fos_normalizer +from fw_modules.fortiosmanagementREST.fos_models import FortiOSConfig +from fwo_base import write_native_config_to_file +from fwo_exceptions import FwoNativeConfigParseError +from model_controllers.fwconfigmanagerlist_controller import FwConfigManagerListController +from model_controllers.import_state_controller import ImportStateController +from models.fw_common import FwCommon +from models.fwconfigmanager import FwConfigManager +from pydantic import ValidationError + + +class FortiosManagementRESTCommon(FwCommon): + def get_config( + self, config_in: FwConfigManagerListController, import_state: ImportStateController + ) -> tuple[int, FwConfigManagerListController]: + ensure_manager_set(config_in, import_state) + ensure_device_name(import_state) + if config_in.native_config_is_empty(): + # get native config via REST API + fm_api_url = ( + f"https://{import_state.state.mgm_details.hostname}:{import_state.state.mgm_details.port!s}/api/v2" + ) + sid = import_state.state.mgm_details.secret + native_config = fos_getter.get_native_config(fm_api_url, sid) + config_in.native_config = native_config.model_dump(by_alias=True) + else: + # parse native config from config file + try: + native_config = FortiOSConfig.model_validate(config_in.native_config, by_alias=True) + except ValidationError as ve: + raise FwoNativeConfigParseError("Error while parsing FortiOS native config from file: " + str(ve)) + + write_native_config_to_file(import_state.state, config_in.native_config) + + normalized_config = fos_normalizer.normalize_config(native_config, mgm_details=import_state.state.mgm_details) + + config_in.ManagerSet[0].configs = [normalized_config] + config_in.ManagerSet[0].manager_uid = import_state.state.mgm_details.uid + + return 0, config_in + + +def ensure_manager_set(config_in: FwConfigManagerListController, import_state: ImportStateController) -> None: + if len(config_in.ManagerSet) > 0: + return + config_in.add_manager( + manager=FwConfigManager( + manager_uid=import_state.state.mgm_details.uid, + manager_name=import_state.state.mgm_details.name, + is_super_manager=import_state.state.mgm_details.is_super_manager, + sub_manager_ids=import_state.state.mgm_details.sub_manager_ids, + domain_name=import_state.state.mgm_details.domain_name, + domain_uid=import_state.state.mgm_details.domain_uid, + configs=[], + ) + ) + + +def ensure_device_name(import_state: ImportStateController) -> None: + mgm_details = import_state.state.mgm_details + gw_map = import_state.state.gateway_map.get(mgm_details.current_mgm_id, {}) + gateway_uid = next(iter(gw_map.keys()), None) + + if ( + mgm_details.devices + and "name" in mgm_details.devices[0] + and (gateway_uid is None or mgm_details.devices[0]["name"] in gw_map) + ): + return + + if gateway_uid is None: + gateway_uid = mgm_details.name or mgm_details.hostname + + mgm_details.devices = [{"name": gateway_uid}] diff --git a/roles/test/files/importer/anonymizer/use_current_version_from_github.txt b/roles/importer/files/importer/fw_modules/nsx4ff/__init__.py similarity index 100% rename from roles/test/files/importer/anonymizer/use_current_version_from_github.txt rename to roles/importer/files/importer/fw_modules/nsx4ff/__init__.py diff --git a/roles/importer/files/importer/fw_modules/nsx4ff/fwcommon.py b/roles/importer/files/importer/fw_modules/nsx4ff/fwcommon.py new file mode 100644 index 0000000000..4b94bcd03d --- /dev/null +++ b/roles/importer/files/importer/fw_modules/nsx4ff/fwcommon.py @@ -0,0 +1,10 @@ +from model_controllers.fwconfigmanagerlist_controller import FwConfigManagerListController +from model_controllers.import_state_controller import ImportStateController +from models.fw_common import FwCommon + + +class Nsx4ffCommon(FwCommon): + def get_config( + self, config_in: FwConfigManagerListController, import_state: ImportStateController + ) -> tuple[int, FwConfigManagerListController]: + raise NotImplementedError("NSX 4ff is not supported yet in the new python importer.") diff --git a/roles/importer/files/importer/fw_modules/paloaltomanagement2023ff/__init__.py b/roles/importer/files/importer/fw_modules/paloaltomanagement2023ff/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/roles/importer/files/importer/fw_modules/paloaltomanagement2023ff/fwcommon.py b/roles/importer/files/importer/fw_modules/paloaltomanagement2023ff/fwcommon.py new file mode 100644 index 0000000000..5313a7b4b2 --- /dev/null +++ b/roles/importer/files/importer/fw_modules/paloaltomanagement2023ff/fwcommon.py @@ -0,0 +1,10 @@ +from model_controllers.fwconfigmanagerlist_controller import FwConfigManagerListController +from model_controllers.import_state_controller import ImportStateController +from models.fw_common import FwCommon + + +class PaloAltoManagement2023ffCommon(FwCommon): + def get_config( + self, config_in: FwConfigManagerListController, import_state: ImportStateController + ) -> tuple[int, FwConfigManagerListController]: + raise NotImplementedError("Palo Alto Management 2023 ff is not supported yet in the new python importer.") diff --git a/roles/importer/files/importer/fwo_alert.py b/roles/importer/files/importer/fwo_alert.py deleted file mode 100644 index b9086ee054..0000000000 --- a/roles/importer/files/importer/fwo_alert.py +++ /dev/null @@ -1,28 +0,0 @@ -import fwo_api -import json -import fwo_const -import fwo_log - -def getFwoAlerter(): - logger = fwo_log.getFwoLogger() - try: - with open(fwo_const.fwo_config_filename, "r") as fwo_config: - fwo_config = json.loads(fwo_config.read()) - user_management_api_base_url = fwo_config['middleware_uri'] - fwo_api_base_url = fwo_config['api_uri'] - except: - logger.error("getFwoAlerter - error while reading FWO config file") - raise - - try: - with open(fwo_const.base_dir + '/etc/secrets/importer_pwd', 'r') as file: - importer_pwd = file.read().replace('\n', '') - except: - logger.error("getFwoAlerter - error while reading importer pwd file") - raise - - jwt = fwo_api.login(fwo_const.importer_user_name, importer_pwd, user_management_api_base_url) - - return { "fwo_api_base_url": fwo_api_base_url, "jwt": jwt } - -# fwo_api.create_data_issue(fwo_api_base_url, jwt, import_id=import_id, obj_name=obj['obj_name'], severity=1, rule_uid=rule_uid, mgm_id=mgm_id, object_type=obj['obj_typ']) diff --git a/roles/importer/files/importer/fwo_api.py b/roles/importer/files/importer/fwo_api.py index 6d24dba866..86232110a0 100644 --- a/roles/importer/files/importer/fwo_api.py +++ b/roles/importer/files/importer/fwo_api.py @@ -1,609 +1,475 @@ -# library for FWORCH API calls -from asyncio.log import logger -from distutils.log import debug -import re -import traceback -from sqlite3 import Timestamp -from textwrap import indent -import requests.packages -import requests import json -import datetime -from fwo_log import getFwoLogger +import string +import time +import traceback +from collections.abc import MutableMapping +from pprint import pformat +from typing import Any + import fwo_globals -from fwo_const import fwo_api_http_import_timeout -from fwo_exception import FwoApiTServiceUnavailable, FwoApiTimeout, FwoApiLoginFailed -from fwo_base import writeAlertToLogFile - - -def showApiCallInfo(url, query, headers, type='debug'): - max_query_size_to_display = 1000 - query_string = json.dumps(query, indent=2) - header_string = json.dumps(headers, indent=2) - query_size = len(query_string) - - if type=='error': - result = "error while sending api_call to url " - else: - result = "successful FWO API call to url " - result += str(url) + " with payload \n" - if query_size < max_query_size_to_display: - result += query_string - else: - result += str(query)[:round(max_query_size_to_display/2)] + "\n ... [snip] ... \n" + \ - query_string[query_size-round(max_query_size_to_display/2):] + " (total query size=" + str(query_size) + " bytes)" - result += "\n and headers: \n" + header_string - return result - - -def call(url, jwt, query, query_variables="", role="reporter", show_progress=False, method=''): - request_headers = { 'Content-Type': 'application/json', 'Authorization': 'Bearer ' + jwt, 'x-hasura-role': role } - full_query = {"query": query, "variables": query_variables} - logger = getFwoLogger() - - with requests.Session() as session: - if fwo_globals.verify_certs is None: # only for first FWO API call (getting info on cert verification) - session.verify = False - else: - session.verify = fwo_globals.verify_certs - session.headers = request_headers +import requests +from fwo_const import FWO_API_HTTP_IMPORT_TIMEOUT +from fwo_exceptions import FwoApiLoginFailedError, FwoApiServiceUnavailableError, FwoApiTimeoutError, FwoImporterError +from fwo_log import FWOLogger +from query_analyzer import QueryAnalyzer +from services.service_provider import ServiceProvider + +JSON_CONTENT_TYPE = "application/json" + + +# this class is used for making calls to the FWO API (will supersede fwo_api.py) +class FwoApi: + fwo_api_url: str + fwo_jwt: str + query_info: dict[str, Any] + query_analyzer: QueryAnalyzer + + def __init__(self, api_uri: str, jwt: str): + self.fwo_api_url = api_uri + self.fwo_jwt = jwt + self.query_info = {} + self.query_analyzer = QueryAnalyzer() + + def call( + self, + query: str, + query_variables: dict[str, list[Any] | Any] | None = None, + analyze_payload: bool = False, + ) -> dict[str, Any]: + """ + The standard FWO API call. + """ + if query_variables is None: + query_variables = {} + role = "importer" + request_headers = { + "Content-Type": JSON_CONTENT_TYPE, + "Authorization": f"Bearer {self.fwo_jwt}", + "x-hasura-role": role, + } + full_query: dict[str, Any] = {"query": query, "variables": query_variables} + return_object = {} + + if analyze_payload: + self.query_info = self.query_analyzer.analyze_payload(query, query_variables) try: - r = session.post(url, data=json.dumps(full_query), timeout=int(fwo_api_http_import_timeout)) - r.raise_for_status() - except requests.exceptions.RequestException: - logger.error(showApiCallInfo(url, full_query, request_headers, type='error') + ":\n" + str(traceback.format_exc())) - if r != None: - if r.status_code == 503: - raise FwoApiTServiceUnavailable("FWO API HTTP error 503 (FWO API died?)" ) - if r.status_code == 502: - raise FwoApiTimeout("FWO API HTTP error 502 (might have reached timeout of " + str(int(fwo_api_http_import_timeout)/60) + " minutes)" ) + with requests.Session() as session: + if fwo_globals.verify_certs is None: # only for first FWO API call (getting info on cert verification) + session.verify = False + else: + session.verify = fwo_globals.verify_certs + session.headers.update(request_headers) + + if analyze_payload and self.query_info["chunking_info"]["needs_chunking"]: + started = time.time() + return_object: dict[str, Any] = self._call_chunked(session, query, query_variables) + elapsed_time = time.time() - started + affected_rows = 0 + if "data" in return_object and "affected_rows" in return_object["data"]: + # If the return object contains data, we can log the affected rows. + affected_rows = sum(obj["affected_rows"] for obj in return_object["data"].values()) + FWOLogger.debug( + f"Chunked API call ({self.query_info['query_name']}) processed in {elapsed_time:.4f} s. Affected rows: {affected_rows}." + ) + self.query_info = {} + else: + return_object: dict[str, Any] = self._post_query(session, full_query) + + self._try_show_api_call_info(full_query, request_headers) + + return return_object + + except requests.exceptions.RequestException as e: + self._handle_request_exception(e, full_query, request_headers) + except FwoImporterError as e: + # Handle FwoImporterError specifically, logging it and re-raising. + FWOLogger.error(f"FwoImporterError during API call: {e!s}") + raise + except Exception as e: + # Catch all other exceptions and log them. + FWOLogger.error(f"Unexpected error during API call: {e!s}") + FWOLogger.debug(pformat(self.query_info)) + try: + FWOLogger.debug(pformat(return_object)) + except NameError: + FWOLogger.error(f"Unexpected error during API call: {e!s}") + raise FwoImporterError(f"return_object not defined. Error during API call: {e!s}") + raise FwoImporterError(f"Unexpected error during API call: {e!s}") + return return_object + + @staticmethod + def login( + user: str, + password: str | None, + user_management_api_base_url: str | None, + method: str = "api/AuthenticationToken/Get", + ): + payload: dict[str, str | None] = {"Username": user, "Password": password} + + if user_management_api_base_url is None: + raise FwoApiLoginFailedError("fwo_api: user_management_api_base_url is None during login") + + with requests.Session() as session: + if fwo_globals.verify_certs is None: # only for first FWO API call (getting info on cert verification) + session.verify = False else: - raise - if int(fwo_globals.debug_level) > 4: - logger.debug (showApiCallInfo(url, full_query, request_headers, type='debug')) - if show_progress: - print('.', end='', flush=True) - if r != None: - return r.json() - else: - return None + session.verify = fwo_globals.verify_certs + session.headers = {"Content-Type": JSON_CONTENT_TYPE} + try: + response = session.post(user_management_api_base_url + method, data=json.dumps(payload)) + except requests.exceptions.RequestException: + raise FwoApiLoginFailedError( + "fwo_api: error during login to url: " + str(user_management_api_base_url) + " with user " + user + ) from None + + if response.status_code == 200: # noqa: PLR2004 + return response.text + error_txt = ( + "fwo_api: ERROR: did not receive a JWT during login" + ", api_url: " + + str(user_management_api_base_url) + + ", ssl_verification: " + + str(fwo_globals.verify_certs) + ) + raise FwoApiLoginFailedError(error_txt) + + def call_endpoint(self, method: str, endpoint: str, params: Any = None) -> Any: + """ + Generic method to call any middleware endpoint. -def login(user, password, user_management_api_base_url, method='api/AuthenticationToken/Get'): - payload = {"Username": user, "Password": password} + Args: + method: HTTP method (GET, POST, PUT, DELETE, PATCH) + endpoint: API endpoint path (e.g., "AuthenticationToken/Get", "User", "Role/User") + data: Request payload data - with requests.Session() as session: - if fwo_globals.verify_certs is None: # only for first FWO API call (getting info on cert verification) - session.verify = False - else: - session.verify = fwo_globals.verify_certs - session.headers = {'Content-Type': 'application/json'} + Returns: + Response data - could be various types based on the endpoint - try: - response = session.post(user_management_api_base_url + method, data=json.dumps(payload)) - except requests.exceptions.RequestException: - raise FwoApiLoginFailed ("fwo_api: error during login to url: " + str(user_management_api_base_url) + " with user " + user) from None + Raises: + FwoApiLoginFailed: If authentication fails + FwoImporterError: If request fails or returns error - if response.text is not None and response.status_code==200: - return response.text - else: - error_txt = "fwo_api: ERROR: did not receive a JWT during login" + \ - ", api_url: " + str(user_management_api_base_url) + \ - ", ssl_verification: " + str(fwo_globals.verify_certs) - raise FwoApiLoginFailed(error_txt) - - -def set_api_url(base_url, testmode, api_supported, hostname): - logger = getFwoLogger() - url = '' - if testmode == 'off': - url = base_url - else: - if re.search(r'^\d+[\.\d+]+$', testmode) or re.search(r'^\d+$', testmode): - if testmode in api_supported: - url = base_url + 'v' + testmode + '/' + """ + service_provider = ServiceProvider() + fwo_config = service_provider.get_fwo_config() + url = fwo_config["user_management_api_base_url"] + endpoint.lstrip("/") + + with requests.Session() as session: + if fwo_globals.verify_certs is None: + session.verify = False else: - exception_text = "api version " + testmode + \ - " is not supported by the manager " + hostname + " - Import is canceled" - raise Exception(exception_text) - else: - raise Exception("\"" + testmode + "\" - not a valid version") - logger.debug("testmode: " + testmode + " - url: " + url) - return url - - -def get_mgm_ids(fwo_api_base_url, jwt, query_variables): - mgm_query = """ - query getManagementIds { - management(where:{do_not_import:{_eq:false}} order_by: {mgm_name: asc}) { id: mgm_id } } """ - return call(fwo_api_base_url, jwt, mgm_query, query_variables=query_variables, role='importer')['data']['management'] - - -def get_config_value(fwo_api_base_url, jwt, key='limit'): - query_variables = {'key': key} - config_query = "query getConf($key: String) { config(where: {config_key: {_eq: $key}}) { config_value } }" - result = call(fwo_api_base_url, jwt, config_query, query_variables=query_variables, role='importer') - if 'data' in result and 'config' in result['data']: - first_result = result['data']['config'][0] - if 'config_value' in first_result: - return first_result['config_value'] - else: - return None - else: - return None - - -def get_config_values(fwo_api_base_url, jwt, keyFilter='limit'): - query_variables = {'keyFilter': keyFilter+"%"} - config_query = "query getConf($keyFilter: String) { config(where: {config_key: {_ilike: $keyFilter}}) { config_key config_value } }" - result = call(fwo_api_base_url, jwt, config_query, query_variables=query_variables, role='importer') - if 'data' in result and 'config' in result['data']: - resultArray = result['data']['config'] - dict1 = {v['config_key']: v['config_value'] for k,v in enumerate(resultArray)} - return dict1 - else: - return None - - -def get_mgm_details(fwo_api_base_url, jwt, query_variables, debug_level=0): - mgm_query = """ - query getManagementDetails($mgmId: Int!) { - management(where:{mgm_id:{_eq:$mgmId}} order_by: {mgm_name: asc}) { - id: mgm_id - name: mgm_name - hostname: ssh_hostname - port: ssh_port - import_credential { - id - credential_name - user: username - secret - sshPublicKey: public_key - cloudClientId: cloud_client_id - cloudClientSecret: cloud_client_secret - } - deviceType: stm_dev_typ { - id: dev_typ_id - name: dev_typ_name - version: dev_typ_version - } - configPath: config_path - domainUid: domain_uid - cloudSubscriptionId: cloud_subscription_id - cloudTenantId: cloud_tenant_id - importDisabled: do_not_import - forceInitialImport: force_initial_import - importerHostname: importer_hostname - debugLevel: debug_level - lastConfigHash: last_import_md5_complete_config - devices(where:{do_not_import:{_eq:false}}) { - id: dev_id - name: dev_name - local_rulebase_name - global_rulebase_name - package_name - } - import_controls(where: { successful_import: {_eq: true} } order_by: {control_id: desc}, limit: 1) { - starttime: start_time - } - } - } - """ - api_call_result = call(fwo_api_base_url, jwt, mgm_query, query_variables=query_variables, role='importer') - if 'data' in api_call_result and 'management' in api_call_result['data'] and len(api_call_result['data']['management'])>=1: - return api_call_result['data']['management'][0] - else: - raise Exception('did not succeed in getting management details from FWO API') - - -def log_import_attempt(fwo_api_base_url, jwt, mgm_id, successful=False): - now = datetime.datetime.now().isoformat() - query_variables = { "mgmId": mgm_id, "timeStamp": now, "success": successful } - mgm_mutation = """ - mutation logImportAttempt($mgmId: Int!, $timeStamp: timestamp!, $success: Boolean) { - update_management(where: {mgm_id: {_eq: $mgmId}}, _set: {last_import_attempt: $timeStamp, last_import_attempt_successful: $success } ) { affected_rows } - }""" - return call(fwo_api_base_url, jwt, mgm_mutation, query_variables=query_variables, role='importer') - - -def lock_import(fwo_api_base_url, jwt, query_variables): - lock_mutation = "mutation lockImport($mgmId: Int!) { insert_import_control(objects: {mgm_id: $mgmId}) { returning { control_id } } }" - lock_result = call(fwo_api_base_url, jwt, lock_mutation, query_variables=query_variables, role='importer') - if lock_result['data']['insert_import_control']['returning'][0]['control_id']: - return lock_result['data']['insert_import_control']['returning'][0]['control_id'] - else: - return -1 - - -def count_changes_per_import(fwo_api_base_url, jwt, import_id): - logger = getFwoLogger() - change_count_query = """ - query count_changes($importId: bigint!) { - changelog_object_aggregate(where: {control_id: {_eq: $importId}}) { aggregate { count } } - changelog_service_aggregate(where: {control_id: {_eq: $importId}}) { aggregate { count } } - changelog_user_aggregate(where: {control_id: {_eq: $importId}}) { aggregate { count } } - changelog_rule_aggregate(where: {control_id: {_eq: $importId}}) { aggregate { count } } - }""" - try: - count_result = call(fwo_api_base_url, jwt, change_count_query, query_variables={'importId': import_id}, role='importer') - changes_in_import = int(count_result['data']['changelog_object_aggregate']['aggregate']['count']) + \ - int(count_result['data']['changelog_service_aggregate']['aggregate']['count']) + \ - int(count_result['data']['changelog_user_aggregate']['aggregate']['count']) + \ - int(count_result['data']['changelog_rule_aggregate'] - ['aggregate']['count']) - except: - logger.exception("failed to count changes for import id " + str(import_id)) - changes_in_import = 0 - return changes_in_import - - -def unlock_import(fwo_api_base_url, jwt, mgm_id, stop_time, current_import_id, error_count, change_count): - logger = getFwoLogger() - error_during_import_unlock = 0 - query_variables = {"stopTime": stop_time, "importId": current_import_id, - "success": error_count == 0, "changesFound": change_count > 0} - - unlock_mutation = """ - mutation unlockImport($importId: bigint!, $stopTime: timestamp!, $success: Boolean, $changesFound: Boolean!) { - update_import_control(where: {control_id: {_eq: $importId}}, _set: {stop_time: $stopTime, successful_import: $success, changes_found: $changesFound}) { - affected_rows - } - }""" - - try: - unlock_result = call(fwo_api_base_url, jwt, unlock_mutation, - query_variables=query_variables, role='importer') - changes_in_import_control = unlock_result['data']['update_import_control']['affected_rows'] - except: - logger.exception("failed to unlock import for management id " + str(mgm_id)) - error_during_import_unlock = 1 - return error_during_import_unlock - - -# this effectively clears the management! -def delete_import(fwo_api_base_url, jwt, current_import_id): - logger = getFwoLogger() - query_variables = {"importId": current_import_id} - - delete_import_mutation = """ - mutation deleteImport($importId: bigint!) { - delete_import_control(where: {control_id: {_eq: $importId}}) { affected_rows } - }""" - - try: - result = call(fwo_api_base_url, jwt, delete_import_mutation, - query_variables=query_variables, role='importer') - api_changes = result['data']['delete_import_control']['affected_rows'] - except: - logger.exception( - "fwo_api: failed to unlock import for import id " + str(current_import_id)) - return 1 # signaling an error - if api_changes == 1: - return 0 # return code 0 is ok - else: - return 1 - - -def import_json_config(fwo_api_base_url, jwt, mgm_id, query_variables): - logger = getFwoLogger() - import_mutation = """ - mutation import($importId: bigint!, $mgmId: Int!, $config: jsonb!, $start_import_flag: Boolean!, $debug_mode: Boolean!, $chunk_number: Int!) { - insert_import_config(objects: {start_import_flag: $start_import_flag, import_id: $importId, mgm_id: $mgmId, chunk_number: $chunk_number, config: $config, debug_mode: $debug_mode}) { - affected_rows - } + session.verify = fwo_globals.verify_certs + + session.headers = {"Authorization": f"Bearer {self.fwo_jwt}", "Content-Type": JSON_CONTENT_TYPE} + + try: + if method.upper() == "GET": + response = session.get(url, json=params, timeout=int(FWO_API_HTTP_IMPORT_TIMEOUT)) + elif method.upper() == "POST": + response = session.post(url, json=params, timeout=int(FWO_API_HTTP_IMPORT_TIMEOUT)) + elif method.upper() == "PUT": + response = session.put(url, json=params, timeout=int(FWO_API_HTTP_IMPORT_TIMEOUT)) + elif method.upper() == "DELETE": + response = session.delete(url, json=params, timeout=int(FWO_API_HTTP_IMPORT_TIMEOUT)) + elif method.upper() == "PATCH": + response = session.patch(url, json=params, timeout=int(FWO_API_HTTP_IMPORT_TIMEOUT)) + else: + raise FwoImporterError(f"Unsupported HTTP method: {method}") + + # Check for HTTP errors + if response.status_code == 401: # noqa: PLR2004 + raise FwoApiLoginFailedError(f"Authentication failed for endpoint: {endpoint}") + if response.status_code == 503: # noqa: PLR2004 + raise FwoApiServiceUnavailableError("FWO Middleware API HTTP error 503 (middleware died?)") + if response.status_code == 502: # noqa: PLR2004 + raise FwoApiTimeoutError("FWO Middleware API HTTP error 502 (might have reached timeout)") + + response.raise_for_status() + + # Try to parse JSON response + try: + return response.json() + except ValueError: + # If response is not JSON, return the text content + return response.text + + except requests.exceptions.RequestException as e: + FWOLogger.error(f"Middleware API request failed: {e!s}") + raise FwoImporterError(f"Middleware API request failed: {e!s}") + + def _handle_request_exception( + self, exception: requests.exceptions.RequestException, query_payload: dict[str, Any], headers: dict[str, Any] + ) -> None: + """ + Error handling for the standard API call. + """ + FWOLogger.debug( + self.show_import_api_call_info(self.fwo_api_url, query_payload, headers, typ="error") + + ":\n" + + str(traceback.format_exc()), + 2, + ) + if hasattr(exception, "response") and exception.response is not None: + if exception.response.status_code == 503: # noqa: PLR2004 + raise FwoApiServiceUnavailableError("FWO API HTTP error 503 (FWO API died?)") + if exception.response.status_code == 502: # noqa: PLR2004 + raise FwoApiTimeoutError( + f"FWO API HTTP error 502 (might have reached timeout of {int(FWO_API_HTTP_IMPORT_TIMEOUT) / 60} minutes)" + ) + raise exception + + def _call_chunked( + self, session: requests.Session, query: str, query_variables: dict[str, list[Any]] | None = None + ) -> dict[str, Any]: + """ + Splits a defined query variable into chunks and posts the queries chunk by chunk. + """ + if query_variables is None: + query_variables = {} + chunk_number = 1 + total_processed_elements = 0 + return_object = {} + FWOLogger.info(f"Processing chunked API call ({self.query_info['query_name']})...") + + # Separate chunkable variables. + + chunkable_variables = { + variable: list_object + for variable, list_object in query_variables.items() + if variable in list(self.query_info["chunking_info"]["chunkable_variables"]) } - """ - try: - debug_mode = (fwo_globals.debug_level>0) - query_variables.update({'debug_mode': debug_mode}) - import_result = call(fwo_api_base_url, jwt, import_mutation, - query_variables=query_variables, role='importer') - # note: this will not detect errors in triggered stored procedure run - if 'errors' in import_result: - logger.exception("fwo_api:import_json_config - error while writing importable config for mgm id " + - str(mgm_id) + ": " + str(import_result['errors'])) - changes_in_import_control = import_result['data']['insert_import_config']['affected_rows'] - except: - logger.exception("failed to write importable config for mgm id " + str(mgm_id)) - return 1 # error - - if changes_in_import_control==1: - return 0 - else: - return 1 - - -def update_hit_counter(fwo_api_base_url, jwt, mgm_id, query_variables): - logger = getFwoLogger() - # currently only data for check point firewalls is collected! - - if 'config' in query_variables and 'rules' in query_variables['config']: - queryVariablesLocal = {"mgmId": mgm_id} - # prerequesite: rule_uids are unique across a management - # this is guaranteed for the newer devices - # older devices like netscreen or FortiGate (via ssh) need to be checked - # when hits information should be gathered here in the future - - found_hits = False - last_hit_update_mutation = """ - mutation updateRuleLastHit($mgmId:Int!) { - update_rule_metadata_many(updates: [ + + # Loops until all elements of the the query variable have been processed. + + while total_processed_elements < self.query_info["chunking_info"]["total_elements"]: + # Updates query variables to the current chunks data. + + self.query_info["chunking_info"]["adjusted_chunk_size"] = self.query_analyzer.get_adjusted_chunk_size( + chunkable_variables + ) + + FWOLogger.debug( + f"Chunk {chunk_number}: Chunk size adjusted\n{self.query_info['chunking_info']['adjusted_chunk_size']}", + 9, + ) + + total_chunk_elements = self._update_query_variables_by_chunk(query_variables, chunkable_variables) + + FWOLogger.debug(f"Chunk {chunk_number}: Query variables updated\n{pformat(query_variables)}", 9) + + # Post query. + + response = self._post_query(session, {"query": query, "variables": query_variables}) + + FWOLogger.debug(f"Chunk {chunk_number}: Query posted", 9) + + # Gather and merge returning data. + + return_object = self._handle_chunked_calls_response(return_object, response) + + # Log current state of the process and increment variables. + + total_processed_elements += total_chunk_elements + FWOLogger.debug( + f"Chunk {chunk_number}: {total_processed_elements}/{self.query_info['chunking_info']['total_elements']} processed elements." + ) + chunk_number += 1 + + return return_object + + def _update_query_variables_by_chunk( + self, query_variables: dict[str, list[Any]], chunkable_variables: dict[str, list[Any]] + ) -> int: + chunks: dict[str, Any] = {} + total_chunk_elements = 0 + + for variable, list_object in chunkable_variables.items(): + chunks[variable] = list_object[: self.query_info["chunking_info"]["adjusted_chunk_size"]] + chunkable_variables[variable] = list_object[self.query_info["chunking_info"]["adjusted_chunk_size"] :] + + for variable, chunk in chunks.items(): + query_variables[variable] = chunk + total_chunk_elements += len(chunk) + + return total_chunk_elements + + def _handle_chunked_calls_response(self, return_object: dict[str, Any], response: dict[str, Any]) -> dict[str, Any]: + if return_object == {}: + self._try_write_extended_log( + message=f"Return object is empty, initializing with response data: {pformat(response)}" + ) + + return response + + if "errors" in response: + error_txt = f"encountered error while handling chunked call: {response['errors']!s}" + FWOLogger.error(error_txt) + raise FwoImporterError(error_txt) + + for new_return_object_type, new_return_object in response["data"].items(): + if "data" in return_object: + self._handle_chunked_calls_response_with_return_data( + return_object, new_return_object_type, new_return_object + ) + elif "affected_rows" not in new_return_object: + FWOLogger.warning(f"no data found: {return_object} not found in return_object['data'].") + elif new_return_object["affected_rows"] == 0: + FWOLogger.warning(f"no data found: {new_return_object} not found in return_object['data'].") + + self._try_write_extended_log( + message=f"Returning object after handling chunked calls response: {pformat(return_object)}" + ) + + return return_object + + def _handle_chunked_calls_response_with_return_data( + self, return_object: dict[str, Any], new_return_object_type: str, new_return_object: dict[str, Any] | list[Any] + ) -> None: + total_affected_rows = 0 + returning_data: list[dict[str, Any]] = [] + + self._try_write_extended_log( + message=f"Handling chunked calls response for type '{new_return_object_type}' with data: {pformat(new_return_object)}" + ) + + if not isinstance(return_object["data"].get(new_return_object_type), dict): + return_object["data"][new_return_object_type] = {} + return_object["data"][new_return_object_type]["affected_rows"] = 0 + return_object["data"][new_return_object_type]["returning"] = [] + + self._try_write_extended_log( + message=f"Initialized return_object['data']['{new_return_object_type}'] as an empty dict: {pformat(return_object['data'][new_return_object_type])}" + ) + + # If the return object is a list we need to sum the affected rows and accumuluate the returning data, else we can set the values directly. + + if isinstance(new_return_object, list): + returning_data = [obj.get("returning", []) for obj in new_return_object if "returning" in obj] + total_affected_rows = sum(obj.get("affected_rows", 0) for obj in new_return_object) + else: + total_affected_rows = new_return_object.get("affected_rows", 0) + returning_data = new_return_object.get("returning", []) + + return_object["data"][new_return_object_type]["affected_rows"] += total_affected_rows + + if "returning" in return_object["data"][new_return_object_type] and len(returning_data) > 0: + self._try_write_extended_log( + message=f"Extending return_object['data']['{new_return_object_type}']['returning'] with new data: {pformat(returning_data)}" + ) + + return_object["data"][new_return_object_type]["returning"].extend(returning_data) + + def _post_query(self, session: requests.Session, query_payload: dict[str, Any]) -> dict[str, Any]: """ + Posts the given payload to the api endpoint. Returns the response as json or None if the response object is None. + """ + FWOLogger.debug( + self.show_import_api_call_info( + self.fwo_api_url, query_payload, session.headers, typ="debug", show_query_info=True + ), + 9, + ) - for rule in query_variables['config']['rules']: - if 'last_hit' in rule and rule['last_hit'] is not None: - found_hits = True - update_expr = '{{ where: {{ device: {{ mgm_id:{{_eq:$mgmId}} }} rule_uid: {{ _eq: "{rule_uid}" }} }}, _set: {{ rule_last_hit: "{last_hit}" }} }}, '.format(rule_uid=rule["rule_uid"], last_hit=rule['last_hit']) - last_hit_update_mutation += update_expr + r = session.post(self.fwo_api_url, data=json.dumps(query_payload), timeout=int(FWO_API_HTTP_IMPORT_TIMEOUT)) - last_hit_update_mutation += " ]) { affected_rows } }" + FWOLogger.debug("API response: " + pformat(r.json(), indent=2), 10) - if found_hits: - try: - update_result = call(fwo_api_base_url, jwt, last_hit_update_mutation, - query_variables=queryVariablesLocal, role='importer') - if 'errors' in update_result: - logger.exception("fwo_api:update_hit_counter - error while updating hit counters for mgm id " + - str(mgm_id) + ": " + str(update_result['errors'])) - update_counter = len(update_result['data']['update_rule_metadata_many']) - except: - logger.exception("failed to update hit counter for mgm id " + str(mgm_id)) - return 1 # error - - return 0 + r.raise_for_status() + + return r.json() + + def show_api_call_info(self, url: str, query: dict[str, Any], headers: dict[str, Any], typ: str = "debug"): + max_query_size_to_display = 1000 + query_string = json.dumps(query, indent=2) + header_string = json.dumps(headers, indent=2) + query_size = len(query_string) + + result = "error while sending api_call to url " if typ == "error" else "successful FWO API call to url " + result += str(url) + " with payload \n" + if query_size < max_query_size_to_display: + result += query_string else: - logger.debug("found no rules with hit information for mgm_id " + str(mgm_id)) - return 1 - else: - logger.debug("no rules found for mgm_id " + str(mgm_id)) - return 1 - - -def delete_import_object_tables(fwo_api_base_url, jwt, query_variables): - logger = getFwoLogger() - delete_mutation = """ - mutation deleteImportData($importId: bigint!) { - delete_import_object(where: {control_id: {_eq: $importId}}) { - affected_rows - } - delete_import_rule(where: {control_id: {_eq: $importId}}) { - affected_rows - } - delete_import_service(where: {control_id: {_eq: $importId}}) { - affected_rows - } - delete_import_user(where: {control_id: {_eq: $importId}}) { - affected_rows - } - } - """ - try: - delete_result = call(fwo_api_base_url, jwt, delete_mutation, - query_variables=query_variables, role='importer') - changes_in_delete_import_tables = \ - int(delete_result['data']['delete_import_object']['affected_rows']) + \ - int(delete_result['data']['delete_import_rule']['affected_rows']) + \ - int(delete_result['data']['delete_import_service']['affected_rows']) + \ - int(delete_result['data']['delete_import_user']['affected_rows']) - except: - logger.exception("failed to delete from import_ tables") - return -1 # indicating error - return changes_in_delete_import_tables - - -def delete_json_config_in_import_table(fwo_api_base_url, jwt, query_variables): - logger = getFwoLogger() - delete_mutation = """ - mutation delete_import_config($importId: bigint!) { - delete_import_config(where: {import_id: {_eq: $importId}}) { affected_rows } - } - """ - try: - delete_result = call(fwo_api_base_url, jwt, delete_mutation, - query_variables=query_variables, role='importer') - changes_in_delete_config = delete_result['data']['delete_import_config']['affected_rows'] - except: - logger.exception("failed to delete config without changes") - return -1 # indicating error - return changes_in_delete_config - - -def store_full_json_config(fwo_api_base_url, jwt, mgm_id, query_variables): - logger = getFwoLogger() - import_mutation = """ - mutation store_full_config($importId: bigint!, $mgmId: Int!, $config: jsonb!) { - insert_import_full_config(objects: {import_id: $importId, mgm_id: $mgmId, config: $config}) { - affected_rows - } - } - """ - - try: - import_result = call(fwo_api_base_url, jwt, import_mutation, - query_variables=query_variables, role='importer') - changes_in_import_full_config = import_result['data']['insert_import_full_config']['affected_rows'] - except: - logger.exception("failed to write full config for mgm id " + str(mgm_id)) - return 2 # indicating 1 error because we are expecting exactly one change - return changes_in_import_full_config-1 - - -def delete_full_json_config(fwo_api_base_url, jwt, query_variables): - logger = getFwoLogger() - delete_mutation = """ - mutation delete_import_full_config($importId: bigint!) { - delete_import_full_config(where: {import_id: {_eq: $importId}}) { - affected_rows - } - } - """ - - try: - delete_result = call(fwo_api_base_url, jwt, delete_mutation, - query_variables=query_variables, role='importer') - changes_in_delete_full_config = delete_result['data']['delete_import_full_config']['affected_rows'] - except: - logger.exception("failed to delete full config ") - return 2 # indicating 1 error - return changes_in_delete_full_config-1 - - -def get_error_string_from_imp_control(fwo_api_base_url, jwt, query_variables): - error_query = "query getErrors($importId:bigint) { import_control(where:{control_id:{_eq:$importId}}) { import_errors } }" - return call(fwo_api_base_url, jwt, error_query, query_variables=query_variables, role='importer')['data']['import_control'] - - -def create_data_issue(fwo_api_base_url, jwt, import_id=None, obj_name=None, mgm_id=None, dev_id=None, severity=1, role='importer', - rule_uid=None, object_type=None, description=None, source='import'): - logger = getFwoLogger() - if obj_name=='all' or obj_name=='Original': - return True # ignore resolve errors for enriched objects that are not in the native config - else: - create_data_issue_mutation = """ - mutation createDataIssue($source: String!, $severity: Int!, $importId: bigint, $objectName: String, - $objectType:String, $ruleUid: String, $description: String, - $mgmId: Int, $devId: Int) { - insert_log_data_issue(objects: {source: $source, severity: $severity, import_id: $importId, - object_name: $objectName, rule_uid: $ruleUid, - object_type:$objectType, description: $description, issue_dev_id: $devId, issue_mgm_id: $mgmId }) { - affected_rows - } - } + result += ( + str(query)[: round(max_query_size_to_display / 2)] + + "\n ... [snip] ... \n" + + query_string[query_size - round(max_query_size_to_display / 2) :] + + " (total query size=" + + str(query_size) + + " bytes)" + ) + result += "\n and headers: \n" + header_string + return result + + def _try_show_api_call_info(self, full_query: dict[str, Any], request_headers: dict[str, Any]) -> None: + """ + Tries to show the API call info if the debug level is high enough. """ + FWOLogger.debug( + self.show_import_api_call_info( + self.fwo_api_url, full_query, request_headers, typ="debug", show_query_info=True + ), + 9, + ) + + def _try_write_extended_log(self, message: str) -> None: + """ + Writes an extended log message if the debug level is high enough. + """ + FWOLogger.debug(message, 10) + + def show_import_api_call_info( + self, + api_url: str, + query: dict[str, Any], + headers: dict[str, Any] | MutableMapping[str, str | bytes], + typ: str = "debug", + show_query_info: bool = False, + ): + max_query_size_to_display = 1000 + query_string = json.dumps(query, indent=2) + header_string = json.dumps(dict(headers), indent=2) + api_url = json.dumps(api_url, indent=2) + query_size = len(query_string) + result = "error while sending api_call to url " if typ == "error" else "successful FWO API call to url " + result += str(self.fwo_api_url) + " with payload \n" + if query_size < max_query_size_to_display: + result += query_string + else: + result += ( + str(query)[: round(max_query_size_to_display / 2)] + + "\n ... [snip] ... \n" + + query_string[query_size - round(max_query_size_to_display / 2) :] + + " (total query size=" + + str(query_size) + + " bytes)" + ) + result += "\n and headers: \n" + header_string + ", api_url: " + api_url + + if show_query_info and self.query_info: + result += "\nQuery Info: \n" + pformat(self.query_info) + + return result + + @classmethod + def get_graphql_code(cls, file_list: list[str]) -> str: + code = "" + + for file in file_list: + try: + # read graphql code from file + printable_chars = set(string.printable) + with open(file, encoding="utf-8", errors="ignore") as f: + code += "".join(filter(printable_chars.__contains__, f.read())) + " " + except FileNotFoundError: # noqa: PERF203 + FWOLogger.error("fwo_api: file not found: " + file) + raise - query_variables = {"source": source, "severity": severity } - - if dev_id is not None: - query_variables.update({"devId": dev_id}) - if mgm_id is not None: - query_variables.update({"mgmId": mgm_id}) - if obj_name is not None: - query_variables.update({"objectName": obj_name}) - if object_type is not None: - query_variables.update({"objectType": object_type}) - # setting import_id leads to error: 'Foreign key violation. insert or update on table "log_data_issue" - # violates foreign key constraint "log_data_issue_import_control_control_id_fkey" - # if import_id is not None: - # query_variables.update({"importId": import_id}) - if rule_uid is not None: - query_variables.update({"ruleUid": rule_uid}) - if description is not None: - query_variables.update({"description": description}) - - # write data issue to alert.log file as well - # if severity>0: - # writeAlertToLogFile(query_variables) - - try: - import_result = call(fwo_api_base_url, jwt, create_data_issue_mutation, query_variables=query_variables, role=role) - changes = import_result['data']['insert_log_data_issue']['affected_rows'] - except: - logger.error("failed to create log_data_issue: " + json.dumps(query_variables)) - return False - return changes==1 - - -def setAlert(fwo_api_base_url, jwt, import_id=None, title=None, mgm_id=None, dev_id=None, severity=1, role='importer', - jsonData=None, description=None, source='import', user_id=None, refAlert=None, alertCode=None, mgm_details = None): - - logger = getFwoLogger() - - addAlert_mutation = """ - mutation addAlert( - $source: String! - $userId: Int - $title: String - $description: String - $mgmId: Int - $devId: Int - $jsonData: json - $refAlert: bigint - $alertCode: Int - ) - { - insert_alert( - objects: { - source: $source - user_id: $userId - title: $title - description: $description - alert_mgm_id: $mgmId - alert_dev_id: $devId - json_data: $jsonData - ref_alert_id: $refAlert - alert_code: $alertCode - } - ) - { - returning { newId: alert_id } - } - } - """ - getAlert_query = """ - query getAlerts($mgmId: Int!, $alertCode: Int!, $currentAlertId: bigint!) { - alert(where: { - alert_mgm_id: {_eq: $mgmId}, alert_code: {_eq: $alertCode} - ack_timestamp: {_is_null: true} - alert_id: {_neq: $currentAlertId}}) - { - alert_id - } - } - """ - ackAlert_mutation = """ - mutation ackAlert($userId: Int, $alertId: bigint, $ackTimeStamp: timestamp) { - update_alert(where: {alert_id: {_eq: $alertId}}, _set: {ack_by: $userId, ack_timestamp: $ackTimeStamp}) { - affected_rows - } - } - """ - - query_variables = {"source": source } - - if dev_id is not None: - query_variables.update({"devId": dev_id}) - if user_id is not None: - query_variables.update({"userId": user_id}) - if mgm_id is not None: - query_variables.update({"mgmId": mgm_id}) - if refAlert is not None: - query_variables.update({"refAlert": refAlert}) - if title is not None: - query_variables.update({"title": title}) - if description is not None: - query_variables.update({"description": description}) - if alertCode is not None: - query_variables.update({"alertCode": alertCode}) - - if jsonData is None: - jsonData = {} - if severity != None: - jsonData.update({"severity": severity}) - if import_id != None: - jsonData.update({"import_id": import_id}) - if mgm_details != None and 'name' in mgm_details: - jsonData.update({"mgm_name": mgm_details['name']}) - query_variables.update({"jsonData": json.dumps(jsonData)}) - - # write data issue to alert.log file as well - if severity>0: - writeAlertToLogFile(query_variables) - - try: - import_result = call(fwo_api_base_url, jwt, addAlert_mutation, query_variables=query_variables, role=role) - newAlertId = import_result['data']['insert_alert']['returning'][0]['newId'] - if alertCode is not None and mgm_id is not None: - # Acknowledge older alert for same problem on same management - query_variables = { "mgmId": mgm_id, "alertCode": alertCode, "currentAlertId": newAlertId } - existingUnacknowledgedAlerts = call(fwo_api_base_url, jwt, getAlert_query, query_variables=query_variables, role=role) - if 'data' in existingUnacknowledgedAlerts and 'alert' in existingUnacknowledgedAlerts['data']: - for alert in existingUnacknowledgedAlerts['data']['alert']: - if 'alert_id' in alert: - now = datetime.datetime.now().isoformat() - query_variables = { "userId": 0, "alertId": alert['alert_id'], "ackTimeStamp": now } - updateResult = call(fwo_api_base_url, jwt, ackAlert_mutation, query_variables=query_variables, role=role) - except: - logger.error("failed to create alert entry: " + json.dumps(query_variables)) - return False - return True + return code.replace("\n", " ").replace("\r", " ") + + @staticmethod + def _read_clean_text_from_file(file_path: str) -> str: + printable_chars = set(string.printable) + with open(file_path, encoding="utf-8", errors="ignore") as f: + return "".join(filter(printable_chars.__contains__, f.read())) diff --git a/roles/importer/files/importer/fwo_api_call.py b/roles/importer/files/importer/fwo_api_call.py new file mode 100644 index 0000000000..2221593603 --- /dev/null +++ b/roles/importer/files/importer/fwo_api_call.py @@ -0,0 +1,451 @@ +# library for all FWORCH API calls in importer module +import datetime +import json +import time +import traceback +from typing import TYPE_CHECKING, Any + +import fwo_const +from fwo_api import FwoApi +from fwo_exceptions import FwoApiFailedLockImportError +from fwo_log import FWOLogger +from model_controllers.management_controller import ManagementController +from models.fwconfig_normalized import FwConfigNormalized +from query_analyzer import QueryAnalyzer + +if TYPE_CHECKING: + from model_controllers.import_state_controller import ImportStateController + from models.import_state import ImportState + +# NOTE: we cannot import ImportState(Controller) here due to circular refs + + +class FwoApiCall: + def __init__(self, api: FwoApi): + self.api = api + self.query_info = {} + self.query_analyzer = QueryAnalyzer() + + def get_mgm_ids(self, query_variables: dict[str, list[Any]] | None = None) -> list[int]: + # from 9.0 do not import sub-managers separately + if query_variables is None: + query_variables = {} + mgm_query = FwoApi.get_graphql_code([fwo_const.GRAPHQL_QUERY_PATH + "device/getManagementWithSubs.graphql"]) + result = self.api.call(mgm_query, query_variables=query_variables) + if "data" in result and "management" in result["data"]: + return [mgm["id"] for mgm in result["data"]["management"]] + return [] + + def get_config_value(self, key: str = "limit") -> str | None: + query_variables: dict[str, str] = {"key": key} + cfg_query = FwoApi.get_graphql_code([fwo_const.GRAPHQL_QUERY_PATH + "config/getConfigValue.graphql"]) + + try: + result = self.api.call(cfg_query, query_variables=query_variables) + except Exception: + FWOLogger.error("fwo_api: failed to get config value for key " + key) + return None + + if "data" in result and "config" in result["data"]: + first_result = result["data"]["config"][0] + if "config_value" in first_result: + return first_result["config_value"] + return None + + def get_config_values(self, key_filter: str = "limit") -> dict[str, str] | None: + query_variables: dict[str, str] = {"keyFilter": key_filter + "%"} + config_query = FwoApi.get_graphql_code( + [fwo_const.GRAPHQL_QUERY_PATH + "config/getConfigValuesByKeyFilter.graphql"] + ) + + try: + result = self.api.call(config_query, query_variables=query_variables) + except Exception: + FWOLogger.error("fwo_api: failed to get config values for key filter " + key_filter) + return None + + if "data" in result and "config" in result["data"]: + result_array = result["data"]["config"] + return {v["config_key"]: v["config_value"] for _, v in enumerate(result_array)} + return None + + # this mgm field is used by mw dailycheck scheduler + def log_import_attempt(self, mgm_id: int, successful: bool): + now = datetime.datetime.now().isoformat() + query_variables: dict[str, Any] = { + "mgmId": mgm_id, + "timeStamp": now, + "success": successful, + } + mgm_mutation = FwoApi.get_graphql_code( + [fwo_const.GRAPHQL_QUERY_PATH + "import/updateManagementLastImportAttempt.graphql"] + ) + return self.api.call(mgm_mutation, query_variables=query_variables) + + def set_import_lock( + self, + mgm_details: ManagementController, + is_initial_import: int, + ) -> int: + import_id = -1 + mgm_id = mgm_details.mgm_id + try: # set import lock + lock_mutation = FwoApi.get_graphql_code([fwo_const.GRAPHQL_QUERY_PATH + "import/addImportForMgm.graphql"]) + lock_result = self.api.call( + lock_mutation, + query_variables={ + "mgmId": mgm_id, + "importTypeId": 1, + "isInitialImport": is_initial_import, + }, + ) + if lock_result["data"]["insert_import_control"]["returning"][0]["control_id"]: + import_id = lock_result["data"]["insert_import_control"]["returning"][0]["control_id"] + return import_id + except Exception: + FWOLogger.error("import_management - failed to get import lock for management id " + str(mgm_id)) + if import_id == -1: + self.create_data_issue( + mgm_id=mgm_id, + severity=1, + description="failed to get import lock for management id " + str(mgm_id), + ) + self.set_alert( + import_id=import_id, + title="import error", + mgm_id=mgm_id, + severity=1, + description="fwo_api: failed to get import lock", + source="import", + alert_code=15, + mgm_details=mgm_details, + ) + raise FwoApiFailedLockImportError( + "fwo_api: failed to get import lock for management id " + str(mgm_id) + ) from None + return import_id + + def count_rule_changes_per_import(self, import_id: int): + change_count_query = FwoApi.get_graphql_code( + [fwo_const.GRAPHQL_QUERY_PATH + "import/getRuleChangesPerImport.graphql"] + ) + try: + count_result = self.api.call(change_count_query, query_variables={"importId": import_id}) + rule_changes_in_import = int(count_result["data"]["changelog_rule_aggregate"]["aggregate"]["count"]) + except Exception as e: + FWOLogger.exception(f"failed to count changes for import id {import_id!s}: {e!s}") + rule_changes_in_import = 0 + return rule_changes_in_import + + def count_any_changes_per_import(self, import_id: int): + change_count_query = FwoApi.get_graphql_code( + [fwo_const.GRAPHQL_QUERY_PATH + "import/getChangesPerImport.graphql"] + ) + try: + count_result = self.api.call(change_count_query, query_variables={"importId": import_id}) + changes_in_import = ( + int(count_result["data"]["changelog_object_aggregate"]["aggregate"]["count"]) + + int(count_result["data"]["changelog_service_aggregate"]["aggregate"]["count"]) + + int(count_result["data"]["changelog_user_aggregate"]["aggregate"]["count"]) + + int(count_result["data"]["changelog_rule_aggregate"]["aggregate"]["count"]) + ) + except Exception as e: + FWOLogger.exception(f"failed to count changes for import id {import_id!s}: {e!s}") + changes_in_import = 0 + return changes_in_import + + def unlock_import(self, import_state: "ImportState", success: bool): + import_id = import_state.import_id + mgm_id = import_state.mgm_details.mgm_id + import_stats = import_state.stats + + try: + query_variables: dict[str, Any] = { + "stopTime": datetime.datetime.now().isoformat(), + "importId": import_id, + "success": success, + "changesFound": import_stats.get_total_change_number() > 0, + "policyChangesFound": import_stats.get_rule_change_number() > 0, + "changeNumber": import_stats.get_rule_change_number(), + } + + unlock_mutation = FwoApi.get_graphql_code( + [fwo_const.GRAPHQL_QUERY_PATH + "import/updateImportStopTime.graphql"] + ) + + unlock_result = self.api.call(unlock_mutation, query_variables=query_variables) + if "errors" in unlock_result: + raise FwoApiFailedLockImportError(unlock_result["errors"]) + _ = unlock_result["data"]["update_import_control"]["affected_rows"] + except Exception as e: + FWOLogger.exception("failed to unlock import for management id " + str(mgm_id) + ": " + str(e)) + + # currently temporarily only working with single chunk + def import_json_config( + self, + import_state: "ImportState", + config: FwConfigNormalized, + start_import: bool, + ): + import_mutation = FwoApi.get_graphql_code([fwo_const.GRAPHQL_QUERY_PATH + "import/addImportConfig.graphql"]) + + try: + query_vars: dict[str, Any] = { + "debug_mode": FWOLogger.is_debug_level(1), + "mgmId": import_state.mgm_details.mgm_id, + "importId": import_state.import_id, + "config": config, + "start_import_flag": start_import, + } + import_result = self.api.call(import_mutation, query_variables=query_vars) + # note: this will not detect errors in triggered stored procedure run + if "errors" in import_result: + FWOLogger.exception( + "fwo_api:import_json_config - error while writing importable config for mgm id " + + str(import_state.mgm_details.mgm_id) + + ": " + + str(import_result["errors"]) + ) + else: + _ = import_result["data"]["insert_import_config"]["affected_rows"] + except Exception: + FWOLogger.exception( + f"failed to write normalized config for mgm id {import_state.mgm_details.mgm_id!s}: {traceback.format_exc()!s}" + ) + + def delete_json_config_in_import_table(self, query_variables: dict[str, Any]): + delete_mutation = FwoApi.get_graphql_code([fwo_const.GRAPHQL_QUERY_PATH + "import/deleteImportConfig.graphql"]) + try: + delete_result = self.api.call(delete_mutation, query_variables=query_variables) + _ = delete_result["data"]["delete_import_config"]["affected_rows"] + except Exception: + FWOLogger.exception("failed to delete config without changes") + + def get_error_string_from_imp_control( + self, _: "ImportStateController", query_variables: dict[str, Any] + ) -> list[dict[str, Any]]: # TYPING: confirm return type + error_query = ( + "query getErrors($importId:bigint) { import_control(where:{control_id:{_eq:$importId}}) { import_errors } }" + ) + return self.api.call(error_query, query_variables=query_variables)["data"]["import_control"] + + def create_data_issue( + self, + obj_name: str | None = None, + mgm_id: int | None = None, + dev_id: int | None = None, + severity: int = 1, + rule_uid: str | None = None, + object_type: str | None = None, + description: str | None = None, + source: str = "import", + ) -> None: + if obj_name in {"all", "Original"}: + return # ignore resolve errors for enriched objects that are not in the native config + + create_data_issue_mutation = FwoApi.get_graphql_code( + [fwo_const.GRAPHQL_QUERY_PATH + "monitor/addLogEntry.graphql"] + ) + + query_variables: dict[str, Any] = {"source": source, "severity": severity} + + if dev_id is not None: + query_variables.update({"devId": dev_id}) + if mgm_id is not None: + query_variables.update({"mgmId": mgm_id}) + if obj_name is not None: + query_variables.update({"objectName": obj_name}) + if object_type is not None: + query_variables.update({"objectType": object_type}) + if rule_uid is not None: + query_variables.update({"ruleUid": rule_uid}) + if description is not None: + query_variables.update({"description": description}) + + try: + result = self.api.call(create_data_issue_mutation, query_variables=query_variables) + changes = result["data"]["insert_log_data_issue"]["returning"] + if len(changes) != 1: + FWOLogger.warning(f"create_data_issue: unexpected result creating data issue: {json.dumps(result)}") + except Exception as e: + FWOLogger.error(f"failed to create log_data_issue: {json.dumps(query_variables)}: {e!s}") + + def set_alert( + self, + import_id: int | None = None, + title: str | None = None, + mgm_id: int | None = None, + dev_id: int | None = None, + severity: int | None = 1, + json_data: dict[str, Any] | None = None, + description: str | None = None, + source: str = "import", + user_id: int | None = None, + ref_alert: str | None = None, + alert_code: int | None = None, + mgm_details: ManagementController | None = None, + ): + add_alert_mutation = FwoApi.get_graphql_code([fwo_const.GRAPHQL_QUERY_PATH + "monitor/addAlert.graphql"]) + get_alert_query = FwoApi.get_graphql_code( + [fwo_const.GRAPHQL_QUERY_PATH + "monitor/getAlertByManagement.graphql"] + ) + ack_alert_mutation = FwoApi.get_graphql_code([fwo_const.GRAPHQL_QUERY_PATH + "monitor/updateAlert.graphql"]) + + query_variables = {"source": source} + + self._set_alert_build_query_vars( + query_variables, + dev_id, + user_id, + mgm_id, + ref_alert, + title, + description, + alert_code, + ) + + if json_data is None: + json_data = {} + if severity is not None: + json_data.update({"severity": severity}) + if import_id is not None: + json_data.update({"import_id": import_id}) + if mgm_details is not None: + json_data.update({"mgm_name": mgm_details.name}) + query_variables.update({"jsonData": json.dumps(json_data)}) + + try: + import_result = self.api.call(add_alert_mutation, query_variables=query_variables) + new_alert_id = import_result["data"]["insert_alert"]["returning"][0]["newIdLong"] + if ( + alert_code is None or mgm_id is None + ): # WWS-CHECK: changed: "mgm_id is not None" -> "mgm_id is None" # TODO: review + return + + # Acknowledge older alert for same problem on same management + query_variables: dict[str, Any] = { + "mgmId": mgm_id, + "alertCode": alert_code, + "currentAlertId": new_alert_id, + } + existing_unacknowledged_alerts = self.api.call(get_alert_query, query_variables=query_variables) + if "data" not in existing_unacknowledged_alerts or "alert" not in existing_unacknowledged_alerts["data"]: + return + + for alert in existing_unacknowledged_alerts["data"]["alert"]: + if "alert_id" in alert: + now = datetime.datetime.now().isoformat() + query_variables = { + "userId": 0, + "alertId": alert["alert_id"], + "ackTimeStamp": now, + } + _ = self.api.call(ack_alert_mutation, query_variables=query_variables) + except Exception as e: + FWOLogger.error(f"failed to create alert entry: {json.dumps(query_variables)}; exception: {e!s}") + raise + + def _set_alert_build_query_vars( + self, + query_variables: dict[str, Any], + dev_id: int | None, + user_id: int | None, + mgm_id: int | None, + ref_alert: str | None, + title: str | None, + description: str | None, + alert_code: int | None, + ): + if dev_id is not None: + query_variables.update({"devId": dev_id}) + if user_id is not None: + query_variables.update({"userId": user_id}) + if mgm_id is not None: + query_variables.update({"mgmId": mgm_id}) + if ref_alert is not None: + query_variables.update({"refAlert": ref_alert}) + if title is not None: + query_variables.update({"title": title}) + if description is not None: + query_variables.update({"description": description}) + if alert_code is not None: + query_variables.update({"alertCode": alert_code}) + + def complete_import(self, import_state: "ImportState", exception: BaseException | None = None): + if not import_state.responsible_for_importing: + return + + try: + self.log_import_attempt(import_state.mgm_details.mgm_id, successful=exception is None) + except Exception: + FWOLogger.error("error while trying to log import attempt") + + self.unlock_import(import_state, success=exception is None) + + exception_message: str | None = None + if exception is not None and hasattr(exception, "message"): + exception_message = getattr(exception, "message", None) + else: + exception_message = str(exception) + + import_result = ( + "import_management: import no. " + + str(import_state.import_id) + + " for management " + + import_state.mgm_details.name + + " (id=" + + str(import_state.mgm_details.mgm_id) + + ")" + + str(" threw errors," if exception is not None else " successful,") + + " total change count: " + + str(import_state.stats.get_total_change_number()) + + ", rule change count: " + + str(import_state.stats.get_rule_change_number()) + + ", duration: " + + str(int(time.time()) - import_state.start_time) + + "s" + ) + import_result += ", ERRORS: " + exception_message if exception_message is not None else "" + + if import_state.stats.get_change_details() != {} and exception is None: + import_result += ", change details: " + str(import_state.stats.get_change_details()) + + if exception is not None: + self.create_data_issue(severity=1, description=exception_message) + self.set_alert( + import_id=import_state.import_id, + title="import error", + mgm_id=import_state.mgm_details.mgm_id, + severity=2, + description=exception_message, + source="import", + alert_code=14, + mgm_details=import_state.mgm_details, + ) + + FWOLogger.info(import_result.encode().decode("unicode_escape")) + + def get_last_complete_import(self, query_vars: dict[str, Any]) -> tuple[int, str]: + mgm_query = FwoApi.get_graphql_code([fwo_const.GRAPHQL_QUERY_PATH + "import/getLastCompleteImport.graphql"]) + last_full_import_date: str = "" + last_full_import_id: int = 0 + try: + past_details = self.api.call(mgm_query, query_variables=query_vars) + if len(past_details["data"]["import_control"]) > 0: + last_full_import_date = past_details["data"]["import_control"][0]["start_time"] + last_full_import_id = past_details["data"]["import_control"][0]["control_id"] + except Exception as _: + FWOLogger.error( + f"error while getting past import details for mgm {query_vars!s}: {traceback.format_exc()!s}" + ) + raise + + return last_full_import_id, last_full_import_date + + def call( + self, + query: str, + query_variables: dict[str, list[Any] | Any] | None = None, + analyze_payload: bool = False, + ) -> dict[str, Any]: + return self.api.call(query, query_variables, analyze_payload) diff --git a/roles/importer/files/importer/fwo_base.py b/roles/importer/files/importer/fwo_base.py index 0869c6c763..a149f2a5d5 100644 --- a/roles/importer/files/importer/fwo_base.py +++ b/roles/importer/files/importer/fwo_base.py @@ -1,166 +1,319 @@ +import hashlib +import ipaddress import json -import jsonpickle -from fwo_data_networking import InterfaceSerializable, RouteSerializable -import fwo_globals -from fwo_const import max_objs_per_chunk, csv_delimiter, apostrophe, line_delimiter -from fwo_log import getFwoLogger, getFwoAlertLogger -from copy import deepcopy +import re +import time +import traceback +from enum import Enum +from typing import TYPE_CHECKING, Any +import fwo_config +import fwo_const +from fwo_const import IMPORT_TMP_PATH +from fwo_enums import ConfFormat, ConfigAction -def split_list(list_in, max_list_length): - if len(list_in)max_number_of_chunks: - max_number_of_chunks = len(split_list_tmp) - else: - conf_split_dict_of_lists.update({obj_list_name: []}) - conf_split = [] - current_chunk = 0 - while current_chunk0: - config_split_with_metadata[len(config_split_with_metadata)-1]["debug_mode"] = True - return config_split_with_metadata - - -def csv_add_field(content, no_csv_delimiter=False): - if (content == None or content == '') and not no_csv_delimiter: # do not add apostrophes for empty fields - field_result = csv_delimiter - else: - # add apostrophes at beginning and end and remove any ocurrence of them within the string - if (isinstance(content, str)): - escaped_field = content.replace(apostrophe,"") - field_result = apostrophe + escaped_field + apostrophe - else: # leave non-string values as is - field_result = str(content) - if not no_csv_delimiter: - field_result += csv_delimiter - return field_result - - -def sanitize(content): - if content == None: +if TYPE_CHECKING: + from model_controllers.import_state_controller import ImportStateController + from models.import_state import ImportState +from fwo_log import FWOLogger +from services.enums import Lifetime, Services +from services.global_state import GlobalState +from services.group_flats_mapper import GroupFlatsMapper +from services.service_provider import ServiceProvider +from services.uid2id_mapper import Uid2IdMapper + + +def sanitize(content: Any, lower: bool = False) -> None | str: + if content is None: return None result = str(content) - result = result.replace(apostrophe,"") # remove possibly contained apostrophe - result = result.replace(line_delimiter," ") # replace possibly contained CR with space + result = result.replace('"', "") # remove possibly contained apostrophe + result = result.replace("\n", " ") # replace possibly contained CR with space + if lower: + return result.lower() return result -def extend_string_list(list_string, src_dict, key, delimiter, jwt=None, import_id=None): +def extend_string_list(list_string: str | None, src_dict: dict[str, list[str]], key: str, delimiter: str) -> str: if list_string is None: - list_string = '' - if list_string == '': - if key in src_dict: - result = delimiter.join(src_dict[key]) - else: - result = '' -# fwo_api.create_data_issue(fwo_api_base_url, jwt, import_id, key) + list_string = "" + if list_string == "": + result = delimiter.join(src_dict[key]) if key in src_dict else "" + elif key in src_dict: + old_list = list_string.split(delimiter) + combined_list = old_list + src_dict[key] + result = delimiter.join(combined_list) else: - if key in src_dict: - old_list = list_string.split(delimiter) - combined_list = old_list + src_dict[key] - result = delimiter.join(combined_list) - else: - result = list_string -# fwo_api.create_data_issue(fwo_api_base_url, jwt, import_id, key) + result = list_string return result -def jsonToLogFormat(jsonData): - if type(jsonData) is dict: - jsonString = json.dumps(jsonData) - elif isinstance(jsonData, str): - jsonString = jsonData - else: - jsonString = str(jsonData) - - if jsonString[0] == '{' and jsonString[-1] == '}': - jsonString = jsonString[1:len(jsonString)-1] - return jsonString - - -def writeAlertToLogFile(jsonData): - logger = getFwoAlertLogger() - jsonDataCopy = deepcopy(jsonData) # make sure the original alert is not changed - if type(jsonDataCopy) is dict and 'jsonData' in jsonDataCopy: - subDict = json.loads(jsonDataCopy.pop('jsonData')) - jsonDataCopy.update(subDict) - alertText = "FWORCHAlert - " + jsonToLogFormat(jsonDataCopy) - logger.info(alertText) - - -def set_ssl_verification(ssl_verification_mode): - logger = getFwoLogger() - if ssl_verification_mode == '' or ssl_verification_mode == 'off': - ssl_verification = False - if fwo_globals.debug_level>5: - logger.debug("ssl_verification: False") - else: - ssl_verification = ssl_verification_mode - if fwo_globals.debug_level>5: - logger.debug("ssl_verification: [ca]certfile=" + ssl_verification) - return ssl_verification +def string_is_uri(s: str) -> re.Match[str] | None: # TODO: should return bool? + return re.match("http://.+", s) or re.match("https://.+", s) or re.match("file://.+", s) + + +def deserialize_class_to_dict_rec( + obj: Any, seen: set[int] | None = None +) -> dict[str, Any] | list[Any] | Any | str | int | float | bool | None: # TYPING: using model is forbidden? + if seen is None: + seen = set() + + # Handle simple immutable types directly (int, float, bool, str) and None + if obj is None or isinstance(obj, (int, float, bool, str, ConfFormat, ConfigAction)): + return obj + + # Check for circular references + if id(obj) in seen: + return f"" + + seen.add(id(obj)) + + if isinstance(obj, list): + # If the object is a list, deserialize each item + return [deserialize_class_to_dict_rec(item, seen) for item in obj] # type: ignore # noqa: PGH003 + if isinstance(obj, dict): + # If the object is a dictionary, deserialize each key-value pair + return {key: deserialize_class_to_dict_rec(value, seen) for key, value in obj.items()} # type: ignore # noqa: PGH003 + if isinstance(obj, Enum): + # If the object is an Enum, convert it to its value + return obj.value + if hasattr(obj, "__dict__"): + # If the object is a class instance, deserialize its attributes + return { + key: deserialize_class_to_dict_rec(value, seen) + for key, value in obj.__dict__.items() + if not callable(value) and not key.startswith("__") + } + # For other types, return the value as is + return obj + + +def cidr_to_range( + ip: str | None, +) -> list[str]: + if isinstance(ip, str): + # dealing with ranges: + if "-" in ip: + return ip.split("-") + + ip_version = valid_ip_address(ip) + if ip_version == "Invalid": + FWOLogger.warning("error while decoding ip '" + ip + "'") + return [ip] + net = ipaddress.IPv4Network(ip) if ip_version == "IPv4" else ipaddress.IPv6Network(ip) + return [str(net.network_address), str(net.broadcast_address)] + + return [ip or ""] + + +def valid_ip_address(ip: str) -> str: + try: + # Try as network first (handles CIDR notation) + network = ipaddress.ip_network(ip, strict=False) + if network.version == 4: # noqa: PLR2004 + return "IPv4" + return "IPv6" + except ValueError: + try: + # Try as individual address + addr = ipaddress.ip_address(ip) + if addr.version == 4: # noqa: PLR2004 + return "IPv4" + return "IPv6" + except ValueError: + return "Invalid" + + +def lcs_dp(seq1: list[Any], seq2: list[Any]) -> tuple[list[list[int]], int]: + """ + Compute the length and dynamic programming (DP) table for the longest common subsequence (LCS) + between seq1 and seq2. Returns (dp, length) where dp is a 2D table and + length = dp[len(seq1)][len(seq2)]. + """ + m: int = len(seq1) + n: int = len(seq2) + dp: list[list[int]] = [[0] * (n + 1) for _ in range(m + 1)] + + for i in range(m): + for j in range(n): + if seq1[i] == seq2[j]: + dp[i + 1][j + 1] = dp[i][j] + 1 + else: + dp[i + 1][j + 1] = max(dp[i + 1][j], dp[i][j + 1]) + return dp, dp[m][n] + + +def backtrack_lcs(seq1: list[Any], seq2: list[Any], dp: list[list[int]]) -> list[tuple[int, int]]: + """ + Backtracks the dynamic programming (DP) table to recover one longest common subsequence (LCS) (as a list of (i, j) index pairs). + These index pairs indicate positions in seq1 and seq2 that match in the LCS. + """ + lcs_indices: list[tuple[int, int]] = [] + i: int = len(seq1) + j: int = len(seq2) + while i > 0 and j > 0: + if seq1[i - 1] == seq2[j - 1]: + lcs_indices.append((i - 1, j - 1)) + i -= 1 + j -= 1 + elif dp[i - 1][j] >= dp[i][j - 1]: + i -= 1 + else: + j -= 1 + lcs_indices.reverse() + return lcs_indices + + +def compute_min_moves(source: list[Any], target: list[Any]) -> dict[str, Any]: + """ + Computes the minimal number of operations required to transform the source list into the target list, + where allowed operations are: + - pop-and-reinsert a common element (to reposition it) + - delete (an element in source not present in target) + - insert (an element in target not present in source) + + Returns a dictionary with all gathered data (total_moves, operations, deletions, insertions and moves) where operations is a list of suggested human readable operations. + """ + # Build sets (assume uniqueness for membership checks) + target_set: set[Any] = set(target) + source_set: set[Any] = set(source) + + # Identify the common elements: + s_common: list[Any] = [elem for elem in source if elem in target_set] + t_common: list[Any] = [elem for elem in target if elem in source_set] + + # Calculate deletions and insertions: + deletions: list[tuple[int, Any]] = [(i, elem) for i, elem in enumerate(source) if elem not in target_set] + insertions: list[tuple[int, Any]] = [(j, elem) for j, elem in enumerate(target) if elem not in source_set] + + # Compute the longest common subsequence (LCS) between S_common and T_common - these are common elements already in correct relative order. + lcs_data: tuple[list[list[int]], int] = lcs_dp(s_common, t_common) + lcs_indices: list[tuple[int, int]] = backtrack_lcs(s_common, t_common, lcs_data[0]) + + # To decide which common elements must be repositioned, mark the indices in S_common which are part of the LCS. + in_place: list[bool] = [False] * len(s_common) + for i, _ in lcs_indices: + in_place[i] = True + # Every common element in S_common not in the LCS will need a pop-and-reinsert. + reposition_moves: list[tuple[int, Any, int]] = [] + # To better explain (rough indexing): We traverse the source list and when we get to a common element, + # we check if it is “in place”. Note that because S_common is a filtered version of source, we need + # to convert back to indices in the original source. We do this by iterating over source and whenever + # we encounter an element in target_set, we pop the next value from S_common. + s_common_iter: int = 0 + for orig_index, elem in enumerate(source): + if elem in target_set: + # This element is one of the common ones. + if not in_place[s_common_iter]: + # This element is not in the LCS so it will be repositioned. + # We will reinsert it to the position where it should appear in target. + reposition_moves.append((orig_index, elem, target.index(elem))) + s_common_iter += 1 + + total_moves: int = len(deletions) + len(insertions) + len(reposition_moves) + + return { + "moves": total_moves, + "deletions": deletions, + "insertions": insertions, + "reposition_moves": reposition_moves, + } + + +def write_native_config_to_file(import_state: "ImportState", config_native: dict[str, Any] | None) -> None: + if FWOLogger.is_debug_level(7): + debug_start_time = int(time.time()) + try: + full_native_config_filename = ( + f"{IMPORT_TMP_PATH}/mgm_id_{import_state.mgm_details.mgm_id!s}_config_native.json" + ) + with open(full_native_config_filename, "w") as json_data: + json_data.write(json.dumps(config_native, indent=2)) + except Exception: + FWOLogger.error( + f"import_management - unspecified error while dumping config to json file: {traceback.format_exc()!s}" + ) + raise + + time_write_debug_json = int(time.time()) - debug_start_time + FWOLogger.debug(f"import_management - writing debug config json files duration {time_write_debug_json!s}s") + + +def init_service_provider() -> ServiceProvider: + service_provider = ServiceProvider() + service_provider.register(Services.FWO_CONFIG, fwo_config.read_config, Lifetime.SINGLETON) + service_provider.register(Services.GROUP_FLATS_MAPPER, GroupFlatsMapper, Lifetime.IMPORT) + service_provider.register(Services.PREV_GROUP_FLATS_MAPPER, GroupFlatsMapper, Lifetime.IMPORT) + service_provider.register(Services.UID2ID_MAPPER, Uid2IdMapper, Lifetime.IMPORT) + return service_provider + + +def register_global_state(import_state: "ImportStateController") -> None: + service_provider = ServiceProvider() + service_provider.register(Services.GLOBAL_STATE, lambda: GlobalState(import_state), Lifetime.SINGLETON) + + +def _diff_dicts(a: dict[Any, Any], b: dict[Any, Any], strict: bool, path: str) -> list[str]: + diffs: list[str] = [] + for k, v in a.items(): + if k not in b: + diffs.append(f"Key '{k}' missing in second object at {path}") + else: + diffs.extend(find_all_diffs(v, b[k], strict, f"{path}.{k}")) + diffs.extend([f"Key '{k}' missing in first object at {path}" for k in b if k not in a]) + return diffs + + +def _diff_lists(a: list[Any], b: list[Any], strict: bool, path: str) -> list[str]: + if len(a) != len(b): + return [f"list length mismatch at {path}: {len(a)} != {len(b)}"] + diffs: list[str] = [] + for i, (x, y) in enumerate(zip(a, b, strict=False)): + diffs.extend(find_all_diffs(x, y, strict, f"{path}[{i}]")) + return diffs + + +def _diff_scalars(a: Any, b: Any, strict: bool, path: str) -> list[str]: + diffs: list[str] = [] + if a != b: + if not strict and (a is None or a == "") and (b is None or b == ""): + return diffs + diffs.append(f"Value mismatch at {path}: {a} != {b}") + return diffs + + +def find_all_diffs(a: Any, b: Any, strict: bool = False, path: str = "root") -> list[str]: + if isinstance(a, dict) and isinstance(b, dict): + return _diff_dicts(a, b, strict, path) # type: ignore # noqa: PGH003 + if isinstance(a, list) and isinstance(b, list): + return _diff_lists(a, b, strict, path) # type: ignore # noqa: PGH003 + return _diff_scalars(a, b, strict, path) + + +def sort_and_join(input_list: list[str]) -> str: + """Sorts the input list of strings and joins them using the standard list delimiter.""" + return fwo_const.LIST_DELIMITER.join(sorted(input_list)) + + +def sort_and_join_refs(input_list: list[tuple[str, str]]) -> tuple[str, str]: + """Sorts the input list of (uid, name) tuples and joins uids and names separately using the standard list delimiter.""" + sorted_list = sorted(input_list, key=lambda x: x[1]) # sort by name + uids = [item[0] for item in sorted_list] + names = [item[1] for item in sorted_list] + joined_uids = fwo_const.LIST_DELIMITER.join(uids) + joined_names = fwo_const.LIST_DELIMITER.join(names) + return joined_uids, joined_names + + +def generate_hash_from_dict(input_dict: dict[Any, Any]) -> str: + """Generates a consistent hash from a dictionary by serializing it with sorted keys.""" + dict_string = json.dumps(input_dict, sort_keys=True) + return hashlib.sha256(dict_string.encode("utf-8")).hexdigest() + + +def replace_none_with_empty( + s: str | None, +) -> str: + if s is None or s == "": + return "" + return str(s) diff --git a/roles/importer/files/importer/fwo_config.py b/roles/importer/files/importer/fwo_config.py index 8aa1ac2e47..e9720ca8d5 100644 --- a/roles/importer/files/importer/fwo_config.py +++ b/roles/importer/files/importer/fwo_config.py @@ -1,23 +1,37 @@ +import json +import sys -from fwo_log import getFwoLogger -import sys, json +from fwo_const import IMPORTER_PWD_FILE +from fwo_log import FWOLogger -def readConfig(fwo_config_filename='/etc/fworch/fworch.json'): - logger = getFwoLogger() + +def read_config(fwo_config_filename: str = "/etc/fworch/fworch.json") -> dict[str, str | int | None]: try: # read fwo config (API URLs) - with open(fwo_config_filename, "r") as fwo_config: - fwo_config = json.loads(fwo_config.read()) - user_management_api_base_url = fwo_config['middleware_uri'] - fwo_api_base_url = fwo_config['api_uri'] + with open(fwo_config_filename) as fwo_config: + fwo_config_json = json.loads(fwo_config.read()) + user_management_api_base_url = fwo_config_json["middleware_uri"] + fwo_api_base_url = fwo_config_json["api_uri"] + fwo_version = fwo_config_json["product_version"] + fwo_major_version = int(fwo_version.split(".")[0]) + + # read importer password from file + with open(IMPORTER_PWD_FILE) as file: + importer_pwd = file.read().replace("\n", "") + except KeyError as e: - logger.error("config key not found in "+ fwo_config_filename + ": " + e.args[0]) + FWOLogger.error("config key not found in " + fwo_config_filename + ": " + e.args[0]) sys.exit(1) - except FileNotFoundError as e: - logger.error("config file not found or unable to access: "+ fwo_config_filename) + except FileNotFoundError: + FWOLogger.error("config file not found or unable to access: " + fwo_config_filename) sys.exit(1) - except: - logger.error("unspecified error occured while trying to read config file: "+ fwo_config_filename) + except Exception: + FWOLogger.error("unspecified error occurred while trying to read config file: " + fwo_config_filename) sys.exit(1) - config = { "user_management_api_base_url": user_management_api_base_url, "fwo_api_base_url": fwo_api_base_url } + config: dict[str, str | int | None] = { + "fwo_major_version": fwo_major_version, + "user_management_api_base_url": user_management_api_base_url, + "fwo_api_base_url": fwo_api_base_url, + "importerPassword": importer_pwd, + } return config diff --git a/roles/importer/files/importer/fwo_const.py b/roles/importer/files/importer/fwo_const.py index 1a3fd56863..2e259abbbd 100644 --- a/roles/importer/files/importer/fwo_const.py +++ b/roles/importer/files/importer/fwo_const.py @@ -1,36 +1,43 @@ -import sys -import json -from urllib.parse import urlparse -import socket +from typing import Any -base_dir = '/usr/local/fworch' -importer_base_dir = base_dir + '/importer' -sys.path.append(importer_base_dir) # adding absolute path here once +BASE_DIR = "/usr/local/fworch" +IMPORTER_BASE_DIR = BASE_DIR + "/importer" -fw_module_name = 'fwcommon' # the module start-point for product specific code -full_config_size_limit = 5000000 # native configs greater than 5 MB will not be stored in DB -csv_delimiter = '%' -list_delimiter = '|' -line_delimiter = "\n" -apostrophe = "\"" -section_header_uids=[] -nat_postfix = '_NatNwObj' -fwo_api_http_import_timeout = 14400 # 4 hours -importer_user_name = 'importer' # todo: move to config file? -fwo_config_filename = base_dir + '/etc/fworch.json' -importer_pwd_file = base_dir + '/etc/secrets/importer_pwd' -import_tmp_path = base_dir + '/tmp/import' -fwo_config_filename = base_dir + '/etc/fworch.json' -max_recursion_level = 25 # do not call a function recursively more than this -default_section_header_text = 'section without name' +FW_MODULE_NAME = "fwcommon" # the module start-point for product specific code +FULL_CONFIG_SIZE_LIMIT = 5000000 # native configs greater than 5 MB will not be stored in DB +LIST_DELIMITER = "|" +USER_DELIMITER = "@" +ANY_IP_IPV4 = "0.0.0.0/0" +ANY_IP_START = "0.0.0.0/32" +ANY_IP_END = "255.255.255.255/32" +DUMMY_IP = "0.0.0.0/32" +DEFAULT_COLOR = "black" +NAT_POSTFIX = "_NatNwObj" +FWO_API_HTTP_IMPORT_TIMEOUT = 14400 # 4 hours +IMPORTER_USER_NAME = "importer" # TODO: move to config file? +FWO_CONFIG_FILENAME = BASE_DIR + "/etc/fworch.json" +MAIN_KEY_FILE = BASE_DIR + "/etc/secrets/main_key" +IMPORTER_PWD_FILE = BASE_DIR + "/etc/secrets/importer_pwd" +IMPORT_TMP_PATH = BASE_DIR + "/tmp/import" # noqa: S108 +DEFAULT_SECTION_HEADER_TEXT = "section without name" +GRAPHQL_QUERY_PATH = BASE_DIR + "/fwo-api-calls/" + +# possible ConfigFormat values: normalized|checkpoint|fortimanager|fortioOS|azure|ciscoFirePower +# info legacy : barracuda|junos|netscreen # how many objects (network, services, rules, ...) should be sent to the FWO API in one go? # should be between 500 and 2.000 in production (results in a max obj number of max. 5 x this value - nwobj/svc/rules/...) # the database has a limit of 255 MB per jsonb # https://stackoverflow.com/questions/12632871/size-limit-of-json-data-type-in-postgresql # >25.000 rules exceed this limit -max_objs_per_chunk = 1000 +API_CALL_CHUNK_SIZE = 1000 +RULE_NUM_NUMERIC_STEPS = 1024.0 -# with open(fwo_config_filename, "r") as fwo_config: -# fwo_config = json.loads(fwo_config.read()) -# fwo_api_base_url = fwo_config['api_uri'] +EMPTY_NORMALIZED_FW_CONFIG_JSON_DICT: dict[str, list[Any]] = { # TYPING: DO NOT USE THIS!!!! + "network_objects": [], + "service_objects": [], + "user_objects": [], + "zone_objects": [], + "rules": [], + "gateways": [], +} diff --git a/roles/importer/files/importer/fwo_data_networking.py b/roles/importer/files/importer/fwo_data_networking.py deleted file mode 100644 index cc56d83c62..0000000000 --- a/roles/importer/files/importer/fwo_data_networking.py +++ /dev/null @@ -1,163 +0,0 @@ -from fwo_log import getFwoLogger -from netaddr import IPAddress, IPNetwork - - -class Interface: - def __init__(self, device_id, name, ip, netmask_bits, state_up=True, ip_version=4): - self.routing_device = int(device_id) - # check if routing device id exists? - self.name = str(name) - self.ip = IPAddress(ip) - netmask_bits = int(netmask_bits) - if netmask_bits<0 or netmask_bits>128: - logger = getFwoLogger() - logger.error('interface ' + self.name + ' with invalid bitmask: ' + str(netmask_bits)) - else: - self.netmask_bits = netmask_bits - self.state_up = bool(state_up) - ip_version = int(ip_version) - if ip_version != 4 and ip_version != 6: - logger = getFwoLogger() - logger.error('interface ' + self.name + ' with invalid ip protocal: ' + str(ip_version)) - else: - self.ip_version = ip_version - - self.ip_version = ip_version - -class InterfaceSerializable(Interface): - def __init__(self, ifaceIn): - if type(ifaceIn) is dict: - self.name = ifaceIn['name'] - self.routing_device = ifaceIn['routing_device'] - self.ip = str(ifaceIn['ip']) - self.netmask_bits = ifaceIn['netmask_bits'] - self.state_up = ifaceIn['state_up'] - self.ip_version = ifaceIn['ip_version'] - elif isinstance(ifaceIn, Interface): - self.name = ifaceIn.name - self.routing_device = ifaceIn.routing_device - self.ip = str(ifaceIn.ip) - self.netmask_bits = ifaceIn.netmask_bits - self.state_up = ifaceIn.state_up - self.ip_version = ifaceIn.ip_version - - -class Route: - def __init__(self, device_id, target_gateway, destination, - static=True, source=None, interface=None, metric=None, distance=None, ip_version=4): - self.routing_device = int(device_id) - if interface is not None: - self.interface = str(interface) - else: - self.interface = None - self.target_gateway = IPAddress(target_gateway) - self.destination = IPNetwork(destination) - if source is not None: - self.source = IPNetwork(source) - else: - self.source = None - self.static = bool(static) - if metric is not None: - self.metric = int(metric) - if distance is not None: - self.distance = int(distance) - ip_version = int(ip_version) - if ip_version != 4 and ip_version != 6: - logger = getFwoLogger() - logger.error('found route for destination ' + str(self.destination) + ' with invalid ip protocal: ' + str(ip_version)) - else: - self.ip_version = ip_version - - - def isDefaultRoute(self): - return self.isDefaultRouteV4() or self.isDefaultRouteV6() - - - def isDefaultRouteV4(self): - return self.ip_version == 4 and self.destination == IPNetwork('0.0.0.0/0') - - - def isDefaultRouteV6(self): - return self.ip_version==6 and self.destination == IPNetwork('::/0') - - - def routeMatches(self, destination, dev_id): - ip_n = IPNetwork(self.destination).cidr - dest_n = IPNetwork(destination).cidr - return dev_id == self.routing_device and (ip_n in dest_n or dest_n in ip_n) - - -class RouteSerializable(Route): - def __init__(self, routeIn): - if type(routeIn) is dict: - self.routing_device = routeIn['routing_device'] - self.interface = routeIn['interface'] - self.target_gateway = str(routeIn['target_gateway']) - self.destination = str(routeIn['destination']) - if routeIn['source'] is None: - self.source = None - else: - self.source = str(routeIn['source']) - self.static = routeIn['static'] - self.metric = routeIn['metric'] - self.distance = routeIn['distance'] - self.ip_version = routeIn['ip_version'] - elif isinstance(routeIn, Route): - self.routing_device = routeIn.routing_device - self.interface = routeIn.interface - self.target_gateway = str(routeIn.target_gateway) - self.destination = str(routeIn.destination) - if routeIn.source is None: - self.source = None - else: - self.source = str(routeIn.source) - self.static = routeIn.static - self.metric = routeIn.metric - self.distance = routeIn.distance - self.ip_version = routeIn.ip_version - - -def getRouteDestination(obj): - return obj.destination - - -# def test_if_default_route_exists_obj(routing_table): -# default_route_v4 = list(filter(lambda default_route: default_route.destination == IPNetwork('0.0.0.0/0'), routing_table)) -# default_route_v6 = list(filter(lambda default_route: default_route.destination == IPNetwork('::/0'), routing_table)) -# if default_route_v4 == [] and default_route_v6 == []: -# return False -# else: -# return True - - -# def get_devices_without_default_route(routing_table): -# dev_ids = vars(routing_table) -# default_route_v4 = list(filter(lambda default_route: default_route.destination == IPNetwork('0.0.0.0/0'), routing_table)) -# default_route_v6 = list(filter(lambda default_route: default_route.destination == IPNetwork('::/0'), routing_table)) -# return default_route_v4.append(default_route_v6) - - -def get_matching_route_obj(destination_ip, routing_table, dev_id): - - logger = getFwoLogger() - - if len(routing_table)==0: - logger.error('found empty routing table for device id ' + str(dev_id)) - return None - - # assuiming routing table to be in sorted state already - for route in routing_table: - if route.routeMatches(destination_ip, dev_id): - return route - - logger.warning('src nat behind interface: found no matching route in routing table - no default route?!') - return None - - -def get_ip_of_interface_obj(interface_name, dev_id, interface_list=[]): - interface_details = next((sub for sub in interface_list if sub.name == interface_name and sub.routing_device==dev_id), None) - - if interface_details is not None: - return interface_details.ip - else: - return None diff --git a/roles/importer/files/importer/fwo_encrypt.py b/roles/importer/files/importer/fwo_encrypt.py new file mode 100644 index 0000000000..16d5be321d --- /dev/null +++ b/roles/importer/files/importer/fwo_encrypt.py @@ -0,0 +1,49 @@ +import base64 +import traceback + +from cryptography.hazmat.backends import default_backend +from cryptography.hazmat.primitives import padding +from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes +from fwo_const import MAIN_KEY_FILE +from fwo_log import FWOLogger + + +# can be used for decrypting text encrypted with C# (mw-server) +def decrypt_aes_ciphertext(base64_encrypted_text: str, passphrase: str) -> str: + encrypted_data = base64.b64decode(base64_encrypted_text) + iv_length = 16 # IV length for AES is 16 bytes + + # Extract IV from the encrypted data + iv = encrypted_data[:iv_length] + + # Initialize AES cipher with provided passphrase and IV + backend = default_backend() + cipher = Cipher(algorithms.AES(passphrase.encode()), modes.CBC(iv), backend=backend) + decryptor = cipher.decryptor() + + # Decrypt the ciphertext + decrypted_data = decryptor.update(encrypted_data[iv_length:]) + decryptor.finalize() + + # Remove padding + unpadder = padding.PKCS7( + algorithms.AES.block_size # type: ignore # noqa: PGH003 + ).unpadder() # TODO: Check if block_size is correct + try: + unpadded_data = unpadder.update(decrypted_data) + unpadder.finalize() + return unpadded_data.decode("utf-8") # Assuming plaintext is UTF-8 encoded + except ValueError as e: + raise ValueError("AES decryption failed:", e) + + +# wrapper for trying the different decryption methods +def decrypt(encrypted_data: str, passphrase: str) -> str: + try: + return decrypt_aes_ciphertext(encrypted_data, passphrase) + except Exception: + FWOLogger.warning("Unspecified error while decrypting with AES: " + str(traceback.format_exc())) + return encrypted_data + + +def read_main_key(file_path: str = MAIN_KEY_FILE) -> str: + with open(file_path) as keyfile: + return keyfile.read().rstrip(" \n") diff --git a/roles/importer/files/importer/fwo_enums.py b/roles/importer/files/importer/fwo_enums.py new file mode 100644 index 0000000000..030389a63e --- /dev/null +++ b/roles/importer/files/importer/fwo_enums.py @@ -0,0 +1,17 @@ +from enum import Enum + + +class ConfigAction(Enum): + INSERT = "INSERT" + UPDATE = "UPDATE" + DELETE = "DELETE" + + +class ConfFormat(Enum): + NORMALIZED = "NORMALIZED" + + CHECKPOINT = "CHECKPOINT" + FORTINET = "FORTINET" + FORTIMANAGER = "FORTIMANAGER" + PALOALTO = "PALOALTO" + CISCOFIREPOWER = "CISCOFIREPOWER" diff --git a/roles/importer/files/importer/fwo_exception.py b/roles/importer/files/importer/fwo_exception.py deleted file mode 100644 index c2c1e69da9..0000000000 --- a/roles/importer/files/importer/fwo_exception.py +++ /dev/null @@ -1,64 +0,0 @@ - -class FwLoginFailed(Exception): - """Raised when login to FW management failed""" - - def __init__(self, message="Login to FW management failed"): - self.message = message - super().__init__(self.message) - -class FwLogoutFailed(Exception): - """Raised when logout from FW management failed""" - - def __init__(self, message="Logout from FW management failed"): - self.message = message - super().__init__(self.message) - -class FwoApiLoginFailed(Exception): - """Raised when login to FWO API failed""" - - def __init__(self, message="Login to FWO API failed"): - self.message = message - super().__init__(self.message) - -class FwoApiFailedLockImport(Exception): - """Raised when unable to lock import (import running?)""" - - def __init__(self, message="Locking import failed - already running?"): - self.message = message - super().__init__(self.message) - -class FwoApiFailure(Exception): - """Raised for any other FwoApi call exceptions""" - - def __init__(self, message="There was an unclassified error while executing an FWO API call"): - self.message = message - super().__init__(self.message) - -class FwoApiTimeout(Exception): - """Raised for 502 http error with proxy due to timeout""" - - def __init__(self, message="reverse proxy timeout error during FWO API call - try increasing the reverse proxy timeout"): - self.message = message - super().__init__(self.message) - -class FwoApiTServiceUnavailable(Exception): - """Raised for 503 http error Serice unavailable""" - - def __init__(self, message="FWO API Hasura container died"): - self.message = message - super().__init__(self.message) - -class ConfigFileNotFound(Exception): - """can only happen when specifying config file with -i switch""" - - def __init__(self, message="Could not read config file"): - self.message = message - super().__init__(self.message) - - -class ImportRecursionLimitReached(Exception): - """Raised when recursion of function inimport process reaches max allowed recursion limit""" - - def __init__(self, message="Max recursion level reached - aborting"): - self.message = message - super().__init__(self.message) diff --git a/roles/importer/files/importer/fwo_exceptions.py b/roles/importer/files/importer/fwo_exceptions.py new file mode 100644 index 0000000000..96dd03cb13 --- /dev/null +++ b/roles/importer/files/importer/fwo_exceptions.py @@ -0,0 +1,213 @@ +rollback_string = "Operation interrupted. Rollback required." + + +class FwLoginFailedError(Exception): + """Raised when login to FW management failed""" + + def __init__(self, message: str = "Login to FW management failed"): + self.message = message + super().__init__(self.message) + + +class FwApiCallFailedError(Exception): + """Raised when FW management API call failed""" + + def __init__(self, message: str = "An API call to the FW management failed"): + self.message = message + super().__init__(self.message) + + +class FwLogoutFailedError(Exception): + """Raised when logout from FW management failed""" + + def __init__(self, message: str = "Logout from FW management failed"): + self.message = message + super().__init__(self.message) + + +class FwoNativeConfigParseError(Exception): + """Raised when native config from file does not conform to firewall-specific config model""" + + def __init__(self, message: str = "Native config parsing failed"): + self.message = message + super().__init__(self.message) + + +class FwoNativeConfigFetchError(Exception): + """Raised when getting native config from FW management fails, no rollback necessary""" + + def __init__(self, message: str = "Login to FW management failed"): + self.message = message + super().__init__(self.message) + + +class FwoNormalizedConfigParseError(Exception): + """Raised while parsing normalized config""" + + def __init__(self, message: str = "Parsing normalized config failed"): + self.message = message + super().__init__(self.message) + + +class SecretDecryptionFailedError(Exception): + """Raised when the attempt to decrypt a secret with the given key fails""" + + def __init__(self, message: str = "Could not decrypt an API secret with given key"): + self.message = message + super().__init__(self.message) + + +class FwoApiLoginFailedError(Exception): + """Raised when login to FWO API fails""" + + def __init__(self, message: str = "Login to FWO API failed"): + self.message = message + super().__init__(self.message) + + +class FwoApiFailedLockImportError(Exception): + """Raised when unable to lock import (import running?)""" + + def __init__(self, message: str = "Locking import failed - already running?"): + self.message = message + super().__init__(self.message) + + +class FwoApiFailedUnLockImportError(Exception): + """Raised when unable to remove import lock""" + + def __init__(self, message: str = "Unlocking import failed"): + self.message = message + super().__init__(self.message) + + +class FwoApiWriteError(Exception): + """Raised when an FWO API mutation fails""" + + def __init__(self, message: str = "FWO API mutation failed"): + self.message = message + super().__init__(self.message) + + +class FwoApiFailureError(Exception): + """Raised for any other FwoApi call exceptions""" + + def __init__(self, message: str = "There was an unclassified error while executing an FWO API call"): + self.message = message + super().__init__(self.message) + + +class FwoApiTimeoutError(Exception): + """Raised for 502 http error with proxy due to timeout""" + + def __init__( + self, + message: str = "reverse proxy timeout error during FWO API call - try increasing the reverse proxy timeout", + ): + self.message = message + super().__init__(self.message) + + +class FwoApiServiceUnavailableError(Exception): + """Raised for 503 http error Serice unavailable""" + + def __init__(self, message: str = "FWO API Hasura container died"): + self.message = message + super().__init__(self.message) + + +class ConfigFileNotFoundError(Exception): + """can only happen when specifying config file with -i switch""" + + def __init__(self, message: str = "Could not read config file"): + self.message = message + super().__init__(self.message) + + +class ImportRecursionLimitReachedError(Exception): + """Raised when recursion of function inimport process reaches max allowed recursion limit""" + + def __init__(self, message: str = "Max recursion level reached - aborting"): + self.message = message + super().__init__(self.message) + + +class ImportInterruptionError(Exception): + """Custom exception to signal an interrupted call requiring rollback.""" + + def __init__(self, message: str = rollback_string): + super().__init__(message) + + +class FwoImporterError(Exception): + """Custom exception to signal a failed import attempt.""" + + def __init__(self, message: str = rollback_string): + super().__init__(message) + + +class FwoImporterErrorInconsistenciesError(Exception): + """Custom exception to signal a failed import attempt.""" + + def __init__(self, message: str = rollback_string): + super().__init__(message) + + +class RollbackNecessaryError(Exception): + """Custom exception to signal a failed import attempt which needs a rollback.""" + + def __init__(self, message: str = "Rollback required."): + super().__init__(message) + + +class RollbackError(Exception): + """Custom exception to signal a failed rollback attempt.""" + + def __init__(self, message: str = "Rollback failed."): + super().__init__(message) + + +class FwApiError(Exception): + """Custom exception to signal a failure during access checkpoint api.""" + + def __init__(self, message: str = "Error while trying to access firewall management API."): + super().__init__(message) + + +class FwApiResponseDecodingError(Exception): + """Custom exception to signal a failure during decoding checkpoint api response to JSON.""" + + def __init__(self, message: str = "Error while trying to decode firewall management API response into JSON."): + super().__init__(message) + + +class FwoApiFailedDeleteOldImportsError(Exception): + """Custom exception to signal a failure during deletion of old import data.""" + + def __init__(self, message: str = "Error while trying to remove old import data."): + super().__init__(message) + + +class FwoDuplicateKeyViolationError(Exception): + """Custom exception to signal a duplicate key violation during import.""" + + def __init__(self, message: str = "Error while trying to add data with duplicate keys"): + super().__init__(message) + + +class FwoUnknownDeviceForManagerError(Exception): + """Custom exception to signal an unknown device during import.""" + + def __init__(self, message: str = "Could not find device in manager config"): + super().__init__(message) + + +class FwoDeviceWithoutLocalPackageError(Exception): + """Custom exception to signal a device without local package.""" + + def __init__(self, message: str = "Could not local package for device in manager config"): + super().__init__(message) + + +class ShutdownRequestedError(Exception): + pass diff --git a/roles/importer/files/importer/fwo_file_import.py b/roles/importer/files/importer/fwo_file_import.py new file mode 100644 index 0000000000..ea202411da --- /dev/null +++ b/roles/importer/files/importer/fwo_file_import.py @@ -0,0 +1,118 @@ +""" +read config from file +""" + +import json +import traceback +from typing import Any + +import fwo_globals +import requests +from fwo_api_call import FwoApiCall +from fwo_exceptions import ConfigFileNotFoundError, FwoImporterError +from fwo_log import FWOLogger +from model_controllers.fwconfigmanagerlist_controller import ( + FwConfigManagerListController, +) +from models.import_state import ImportState + +""" + supported input formats: + + normalized (new from v9 onwards) --> dicts with uid as id + + { + "ConfigFormat": "NORMALIZED", + "managers": [ + { + "ManagerUid": "6ae3760206b9bfbd2282b5964f6ea07869374f427533c72faa7418c28f7a77f2", + "ManagerName": "MGM NAME", + "IsGlobal": false, + "Configs": { + "action": "INSERT", + "network_objects": [ + { + + } + } + } + ] + } + + output formats: + + a) NORMALIZED: + + check point + { + "users": {}, + "object_tables": [ + { + "object_type": "hosts", + "object_chunks": [ + { + "objects": [ + } + + +""" + + +def read_json_config_from_file(fwo_api_call: FwoApiCall, import_state: ImportState) -> FwConfigManagerListController: + config_json = read_file(fwo_api_call, import_state) + + # try to convert normalized config from file to config object + try: + manager_list = FwConfigManagerListController(**config_json) # TYPING: use model load + if len(manager_list.ManagerSet) == 0: + FWOLogger.warning( + f"read a config file without manager sets from {import_state.import_file_name}, trying native config" + ) + manager_list.native_config = config_json + return manager_list + except Exception: # legacy stuff from here + FWOLogger.info(f"could not serialize config {traceback.format_exc()!s}") + raise FwoImporterError(f"could not serialize config {import_state.import_file_name}") + + +def read_file(fwo_api_call: FwoApiCall, import_state: ImportState) -> dict[str, Any]: + config_json: dict[str, Any] = {} + r = None + if import_state.import_file_name == "": + return config_json + try: + if import_state.import_file_name.startswith("http://") or import_state.import_file_name.startswith( + "https://" + ): # get conf file via http(s) + session = requests.Session() + session.headers = {"Content-Type": "application/json"} + session.verify = fwo_globals.verify_certs + r = session.get( + import_state.import_file_name, + ) + if r.ok: + return json.loads(r.text) + r.raise_for_status() + else: # reading from local file + if import_state.import_file_name.startswith("file://"): # remove file uri identifier + filename = import_state.import_file_name[7:] + else: + filename = import_state.import_file_name + with open(filename) as json_file: + config_json = json.load(json_file) + except requests.exceptions.RequestException as e: + if r is not None: + FWOLogger.error( + f"got HTTP status code{r.status_code!s} while trying to read config file from URL {import_state.import_file_name}" + ) + else: + FWOLogger.error(f"got error while trying to read config file from URL {import_state.import_file_name}") + + fwo_api_call.complete_import(import_state, e) + raise ConfigFileNotFoundError(str(e)) from None + except Exception as e: + FWOLogger.error("unspecified error while reading config file: " + str(traceback.format_exc())) + fwo_api_call.complete_import(import_state, e) + raise ConfigFileNotFoundError(f"unspecified error while reading config file {import_state.import_file_name}") + + return config_json diff --git a/roles/importer/files/importer/fwo_globals.py b/roles/importer/files/importer/fwo_globals.py index f8f762703c..86364eee2e 100644 --- a/roles/importer/files/importer/fwo_globals.py +++ b/roles/importer/files/importer/fwo_globals.py @@ -1,18 +1,11 @@ -from urllib.parse import urlparse -import socket +# fwo_globals.py +verify_certs = None +suppress_cert_warnings = None +debug_level = 0 +shutdown_requested = False -debug_level=0 - -def setGlobalValues ( - verify_certs_in=None, - suppress_cert_warnings_in=None, - debug_level_in = 0, - ): - global verify_certs - global suppress_cert_warnings - global debug_level +def set_global_values(verify_certs_in: bool | None, suppress_cert_warnings_in: bool | None): + global verify_certs, suppress_cert_warnings # noqa: PLW0603 verify_certs = verify_certs_in suppress_cert_warnings = suppress_cert_warnings_in - debug_level = int(debug_level_in) - \ No newline at end of file diff --git a/roles/importer/files/importer/fwo_local_settings.py b/roles/importer/files/importer/fwo_local_settings.py new file mode 100644 index 0000000000..a74415689c --- /dev/null +++ b/roles/importer/files/importer/fwo_local_settings.py @@ -0,0 +1,24 @@ +import json +import os +from pathlib import Path + +from fwo_log import FWOLogger + +python_unit_tests_verbose: bool = False + + +def _load_from_env(): + global python_unit_tests_verbose # noqa: PLW0603 + + path = os.getenv("FWORCH_LOCAL_SETTINGS_PATH") + + if path and Path(path).is_file(): + try: + with open(path, encoding="utf-8") as f: + data = json.load(f) + python_unit_tests_verbose = bool(data.get("test.unittests.python.verbose", False)) + except Exception as e: + FWOLogger.error(f"Reading local settings from {path} failed ({e}). Using defaults.") + + +_load_from_env() diff --git a/roles/importer/files/importer/fwo_log.py b/roles/importer/files/importer/fwo_log.py index 7080299471..14ddaf049b 100644 --- a/roles/importer/files/importer/fwo_log.py +++ b/roles/importer/files/importer/fwo_log.py @@ -1,54 +1,218 @@ import logging -from sys import stdout -import fwo_globals -#from fwo_globals import global_debug_level - - -def getFwoLogger(): - debug_level=int(fwo_globals.debug_level) - if debug_level>=1: - llevel = logging.DEBUG - else: - llevel = logging.INFO - - logger = logging.getLogger() # use root logger - logHandler = logging.StreamHandler(stream=stdout) - logformat = "%(asctime)s [%(levelname)-5.5s] [%(filename)-10.10s:%(funcName)-10.10s:%(lineno)4d] %(message)s" - logHandler.setLevel(llevel) - handlers = [logHandler] - logging.basicConfig(format=logformat, datefmt="%Y-%m-%dT%H:%M:%S%z", handlers=handlers, level=llevel) - logger.setLevel(llevel) - - # set log level for noisy requests/connectionpool module to WARNING: - connection_log = logging.getLogger("urllib3.connectionpool") - connection_log.setLevel(logging.WARNING) - connection_log.propagate = True - - if debug_level>8: - logger.debug ("debug_level=" + str(debug_level) ) - return logger +import threading +import time +from typing import TYPE_CHECKING + +if TYPE_CHECKING: + from models.import_state import ImportState + + from importer.services.uid2id_mapper import Uid2IdMapper + +from typing import Any, Literal + + +class LogLock: + semaphore = threading.Semaphore() + + @staticmethod + def handle_log_lock(): + # Initialize values + lock_file_path = "/var/fworch/lock/importer_api_log.lock" + log_owned = False + stopwatch = time.time() + + while True: + try: + with open(lock_file_path, "a+") as file: + # Jump to the beginning of the file + file.seek(0) + # Read the file content + lock_file_content = file.read().strip() + + if log_owned: + # Forcefully release lock after timeout + if time.time() - stopwatch > 10: # noqa: PLR2004 + file.write("FORCEFULLY RELEASED\n") + stopwatch = -1 + LogLock.semaphore.release() + log_owned = False + + elif lock_file_content.endswith("RELEASED"): + # RELEASED - lock was released by log swap process + # only release lock if it was formerly requested by us + stopwatch = -1 + LogLock.semaphore.release() + log_owned = False + + elif lock_file_content.endswith("GRANTED"): + # Request lock if it is not already requested by us + # (in case of restart with log already granted) + LogLock.semaphore.acquire() + stopwatch = time.time() + log_owned = True + + elif lock_file_content.endswith("REQUESTED"): + # REQUESTED - lock was requested by log swap process + LogLock.semaphore.acquire() + stopwatch = time.time() + log_owned = True + file.write("GRANTED\n") + except Exception as _: # noqa: S110 + pass + # Wait a second + time.sleep(1) + + +class FWOLogger: + logger: logging.Logger + debug_level: int + + def __new__(cls, _debug_level: int = 0): + if not hasattr(cls, "instance"): + cls.instance = super().__new__(cls) + return cls.instance + + def __init__(self, _debug_level: int = 0): + self.logger = get_fwo_logger(_debug_level) + self.debug_level = _debug_level + + def get_logger(self) -> logging.Logger: + return self.logger + + def set_debug_level(self, debug_level: int): + log_level = logging.DEBUG if int(debug_level) >= 1 else logging.INFO + self.logger.setLevel(log_level) + @staticmethod + def debug(msg: str, needed_level: int = 1): + log = FWOLogger.instance.get_logger() + if FWOLogger.instance.debug_level >= needed_level: + # Find the caller's frame to show correct file/function/line info + log.debug(msg, stacklevel=2) -def getFwoAlertLogger(debug_level=0): - debug_level=int(debug_level) - if debug_level>=1: - llevel = logging.DEBUG - else: - llevel = logging.INFO + @staticmethod + def error(msg: str): + logger = FWOLogger.instance.get_logger() + logger.error(msg, stacklevel=2) - logger = logging.getLogger() # use root logger - logHandler = logging.StreamHandler(stream=stdout) - logformat = "%(asctime)s %(message)s" - logHandler.setLevel(llevel) - handlers = [logHandler] - logging.basicConfig(format=logformat, datefmt="", handlers=handlers, level=llevel) - logger.setLevel(llevel) + @staticmethod + def info(msg: str): + logger = FWOLogger.instance.get_logger() + logger.info(msg, stacklevel=2) - # set log level for noisy requests/connectionpool module to WARNING: + @staticmethod + def warning(msg: str): + logger = FWOLogger.instance.get_logger() + logger.warning(msg, stacklevel=2) + + @staticmethod + def exception(msg: str, exc_info: Any = None): + logger = FWOLogger.instance.get_logger() + logger.exception(msg, exc_info=exc_info, stacklevel=2) + + @staticmethod + def is_debug_level(level: int) -> bool: + return FWOLogger.instance.debug_level >= level + + +def get_fwo_logger(debug_level: int = 0) -> logging.Logger: + log_level = logging.DEBUG if int(debug_level) >= 1 else logging.INFO + + logger = logging.getLogger() + log_format = "%(asctime)s [%(levelname)-5.5s] [%(filename)-25.25s:%(funcName)-25.25s:%(lineno)4d] %(message)s" + + logging.basicConfig(format=log_format, datefmt="%Y-%m-%dT%H:%M:%S%z", level=log_level) + logger.setLevel(log_level) + + # Set log level for noisy requests/connectionpool module to WARNING: connection_log = logging.getLogger("urllib3.connectionpool") connection_log.setLevel(logging.WARNING) connection_log.propagate = True - - if debug_level>8: - logger.debug ("debug_level=" + str(debug_level) ) return logger + + +class ChangeLogger: + """ + A singleton service that holds data and provides logic to compute changelog data for network objects, services and rules. + """ + + _instance = None + changed_object_id_map: dict[int, int] + changed_service_id_map: dict[int, int] + _import_state: "ImportState | None" = None + _uid2id_mapper: "Uid2IdMapper | None" = None + + def __new__(cls): + """ + Singleton pattern: Creates instance and sets defaults if constructed first time and sets that object to a protected class variable. + If the constructor is called when there is already an instance returns that instance instead. That way there will only be one instance of this type throudgh the whole runtime. + """ + if cls._instance is None: + cls._instance = super().__new__(cls) + cls.changed_object_id_map = {} + cls.changed_service_id_map = {} + return cls._instance + + def create_change_id_maps( + self, + uid2id_mapper: "Uid2IdMapper", + changed_nw_objs: list[str], + changed_svcs: list[str], + removed_nw_objs: list[dict[str, Any]], + removed_nw_svcs: list[dict[str, Any]], + ): + self._uid2id_mapper = uid2id_mapper + + self.changed_object_id_map = { + next( + removedNwObjId["obj_id"] for removedNwObjId in removed_nw_objs if removedNwObjId["obj_uid"] == old_item + ): self._uid2id_mapper.get_network_object_id(old_item) + for old_item in changed_nw_objs + } + + self.changed_service_id_map = { + next( + removedNwSvcId["svc_id"] for removedNwSvcId in removed_nw_svcs if removedNwSvcId["svc_uid"] == old_item + ): self._uid2id_mapper.get_service_object_id(old_item) + for old_item in changed_svcs + } + + def create_changelog_import_object( + self, + typ: str, + import_state: "ImportState", + change_action: str, + change_typ: Literal[2, 3], + import_time: str, + rule_id: int, + rule_id_alternative: int = 0, + ) -> dict[str, Any]: + unique_name = self._get_changelog_import_object_unique_name(rule_id) + old_rule_id = None + new_rule_id = None + self._import_state = import_state + + if change_action in ["I", "C"]: + new_rule_id = rule_id + + if change_action == "C": + old_rule_id = rule_id_alternative + + if change_action == "D": + old_rule_id = rule_id + + rule_changelog_object: dict[str, Any] = { + f"new_{typ}_id": new_rule_id, + f"old_{typ}_id": old_rule_id, + "control_id": self._import_state.import_id, + "change_action": change_action, + "mgm_id": self._import_state.mgm_details.current_mgm_id, + "change_type_id": change_typ, + "change_time": import_time, + "unique_name": unique_name, + } + + return rule_changelog_object + + def _get_changelog_import_object_unique_name(self, changelog_entity_id: int) -> str: + return str(changelog_entity_id) diff --git a/roles/importer/files/importer/fwo_mail.py b/roles/importer/files/importer/fwo_mail.py deleted file mode 100644 index de8a60ae73..0000000000 --- a/roles/importer/files/importer/fwo_mail.py +++ /dev/null @@ -1,82 +0,0 @@ -import json -import jsonpickle -from fwo_data_networking import InterfaceSerializable, RouteSerializable -import fwo_globals -from fwo_const import max_objs_per_chunk, csv_delimiter, apostrophe, line_delimiter -from fwo_log import getFwoLogger, getFwoAlertLogger -from copy import deepcopy -import smtplib, ssl -from email.message import EmailMessage - - -def send_mail(recipient_list, subject, body, fwo_config): - logger = getFwoLogger() - # Create a text/plain message - msg = EmailMessage() - senderAddress = "" - msg.set_content(body) - msg['Subject'] = subject - if 'emailSenderAddress' in fwo_config: - senderAddress = fwo_config['emailSenderAddress'] - msg['From'] = senderAddress - msg['To'] = recipient_list - tlsSetting = "" - - try: - if 'emailTls' not in fwo_config or fwo_config['emailTls']=='StartTls': - smtp_server = smtplib.SMTP(fwo_config['emailServerAddress'], int(fwo_config['emailPort'])) - if 'emailTls' in fwo_config and fwo_config['emailTls']=='StartTls': - tlsSetting = fwo_config['emailTls'] - smtp_server.starttls() #setting up to TLS connection - smtp_server.ehlo() #calling the ehlo() again as encryption happens on calling startttls() - else: - smtp_server.ehlo() #setting the ESMTP protocol - elif fwo_config['emailTls']=='Tls': - context = ssl.create_default_context() - context.check_hostname = False - context.verify_mode = ssl.CERT_NONE - smtp_server = smtplib.SMTP(fwo_config['emailServerAddress'], int(fwo_config['emailPort'])) - smtp_server.starttls(context=context) - smtp_server.ehlo() - if 'emailUser' in fwo_config and 'emailPassword' in fwo_config and fwo_config['emailUser']!="": - smtp_server.login(fwo_config['emailUser'], fwo_config['emailPassword']) #logging into out email id - - #sending the mail by specifying the from and to address and the message - smtp_server.send_message(msg) - smtp_server.quit() #terminating the server - except Exception as e: - if 'emailPort' not in fwo_config: - logger.warning("Missing email server port config. Double-check your emailPort configuration") - elif int(fwo_config['emailPort'])<1 or int(fwo_config['emailPort'])>65535: - logger.warning("Email server port configuration out of bounds: " + str(fwo_config['emailPort']) + ". Double-check your emailPort configuration") - elif 'emailServer' not in fwo_config: - logger.warning("Missing email server address. Double-check your emailServer configuration") - elif len(fwo_config['emailServer'])==0: - logger.warning("Empty email server address. Double-check your emailServer configuration") - elif recipient_list is None: - logger.warning("Undefined email recipient list. Double-check your email recipient list") - elif len(recipient_list)==0: - logger.warning("Empty email recipient list. Double-check your email recipient list") - else: - logger.warning("error while sending import change notification email: " + - "emailServer: " + fwo_config['emailServerAddress'] + ", " + - "emailSenderAddress: " + senderAddress + ", " + - "emailPort: " + fwo_config['emailPort'] + ", " + - "emailTls: " + str(tlsSetting) + ", " + - "impChangeNotifyRecipients: " + str(recipient_list) + ", " + - "error: " + str(e) - ) - - -def send_change_notification_mail(fwo_config, number_of_changes, mgm_name, mgm_id): - if 'impChangeNotifyActive' in fwo_config and bool(fwo_config['impChangeNotifyActive']) and 'impChangeNotifyRecipients' in fwo_config: - body = "" - if 'impChangeNotifyBody' in fwo_config: - body += fwo_config['impChangeNotifyBody'] + ": " - body += str(number_of_changes) + ", Management: " + mgm_name + " (id=" + mgm_id + ")" - send_mail( - fwo_config['impChangeNotifyRecipients'].split(','), - fwo_config['impChangeNotifySubject'] if 'impChangeNotifySubject' in fwo_config else "firewall orchestrator change notification", - body, - fwo_config - ) diff --git a/roles/importer/files/importer/fwo_signalling.py b/roles/importer/files/importer/fwo_signalling.py new file mode 100644 index 0000000000..8c14b71aeb --- /dev/null +++ b/roles/importer/files/importer/fwo_signalling.py @@ -0,0 +1,16 @@ +import signal +from typing import Any + +import fwo_globals +from fwo_exceptions import ShutdownRequestedError + + +def handle_shutdown_signal(_: int, __: Any): + fwo_globals.shutdown_requested = True + raise ShutdownRequestedError + + +def register_signalling_handlers(): + # Register signal handlers for system shutdown interrupts + signal.signal(signal.SIGTERM, handle_shutdown_signal) # Handle termination signal + signal.signal(signal.SIGINT, handle_shutdown_signal) # Handle interrupt signal (e.g., Ctrl+C) diff --git a/roles/importer/files/importer/fworch-importer-main.pl b/roles/importer/files/importer/fworch-importer-main.pl deleted file mode 100755 index 02e24785b1..0000000000 --- a/roles/importer/files/importer/fworch-importer-main.pl +++ /dev/null @@ -1,48 +0,0 @@ -#! /usr/bin/perl -w -use strict; -use lib '.'; -use CACTUS::FWORCH; -use CACTUS::read_config; -use CGI qw(:standard); -use Sys::Hostname; - -my $isobase = &CACTUS::read_config::read_config('TopDir'); -my $importdir = &CACTUS::read_config::read_config('ImportDir'); -my $sleep_time = &CACTUS::read_config::read_config('ImportSleepTime'); -my $hostname_localhost = hostname(); -my $importer_hostname = $hostname_localhost; -my ($res, $mgm_name, $mgm_id, $fehler); - -if ($#ARGV>=0) { if (defined($ARGV[0]) && is_numeric($ARGV[0])) { $sleep_time = $ARGV[0] * 1; } } - -while (1) { - # output_txt("Import: another loop is starting... "); - # get management systems from the database - my $dbh1 = DBI->connect("dbi:Pg:dbname=$fworch_database;host=$fworch_srv_host;port=$fworch_srv_port","$fworch_srv_user","$fworch_srv_pw"); - if ( !defined $dbh1 ) { die "Cannot connect to database!\n"; } - my $sth1 = $dbh1->prepare("SELECT mgm_id, mgm_name, do_not_import, importer_hostname from management LEFT JOIN stm_dev_typ USING (dev_typ_id)" . - " WHERE NOT do_not_import ORDER BY mgm_name" ); - if ( !defined $sth1 ) { die "Cannot prepare statement: $DBI::errstr\n"; } - $res = $sth1->execute; - my $management_hash = $sth1->fetchall_hashref('mgm_name'); - $sth1->finish; - $dbh1->disconnect; - # loop across all management systems - foreach $mgm_name (sort keys %{$management_hash}) { - $fehler = 0; - # output_txt("Import: looking at $mgm_name ... "); - $mgm_id = $management_hash->{"$mgm_name"}->{"mgm_id"}; - if (defined($management_hash->{"$mgm_name"}->{"importer_hostname"})) { - $importer_hostname = $management_hash->{"$mgm_name"}->{"importer_hostname"}; - } - if ($importer_hostname eq $hostname_localhost) { - # output_txt("Import: running on responsible importer $importer_hostname ... "); - $fehler = system("$importdir/fworch-importer-single.pl mgm_id=$mgm_id"); - if ($fehler) { - output_txt("Import error: $fehler"); - } - } - } - output_txt("-------- legacy import module going back to sleep for $sleep_time seconds --------\n"); - sleep $sleep_time; -} diff --git a/roles/importer/files/importer/fworch-importer-reset-all.pl b/roles/importer/files/importer/fworch-importer-reset-all.pl deleted file mode 100755 index 65892f0ce4..0000000000 --- a/roles/importer/files/importer/fworch-importer-reset-all.pl +++ /dev/null @@ -1,30 +0,0 @@ -#! /usr/bin/perl -w -use strict; -use lib '.'; -use CACTUS::FWORCH; -use CACTUS::read_config; -use CGI qw(:standard); - -my ($res, $mgm_name, $mgm_id, $fehler); - -# get management systems from the database -my $dbh1 = DBI->connect("dbi:Pg:dbname=$fworch_database;host=$fworch_srv_host;port=$fworch_srv_port","$fworch_srv_user","$fworch_srv_pw"); -if ( !defined $dbh1 ) { die "Cannot connect to database!\n"; } -my $sth1 = $dbh1->prepare("SELECT mgm_id, mgm_name from management LEFT JOIN stm_dev_typ USING (dev_typ_id)" . - " ORDER BY mgm_name" ); -if ( !defined $sth1 ) { die "Cannot prepare statement: $DBI::errstr\n"; } -$res = $sth1->execute; -my $management_hash = $sth1->fetchall_hashref('mgm_name'); -$sth1->finish; -$dbh1->disconnect; - -my $isobase = &CACTUS::read_config::read_config('TopDir'); -my $importdir = &CACTUS::read_config::read_config('ImportDir'); - -# Schleife ueber alle Managementsysteme: Loeschen und wieder einlesen aller Configs -foreach $mgm_name (sort keys %{$management_hash}) { - $mgm_id = $management_hash->{"$mgm_name"}->{"mgm_id"}; - $fehler = system("$importdir/fworch-importer-single.pl mgm_id=$mgm_id -no-md5-checks -clear-management"); - $fehler = system("$importdir/fworch-importer-single.pl mgm_id=$mgm_id -no-md5-checks"); -} -exit(0); diff --git a/roles/importer/files/importer/fworch-importer-single.pl b/roles/importer/files/importer/fworch-importer-single.pl deleted file mode 100755 index 109c290c52..0000000000 --- a/roles/importer/files/importer/fworch-importer-single.pl +++ /dev/null @@ -1,272 +0,0 @@ -#! /usr/bin/perl -w - -use strict; -use lib '.'; -use CACTUS::FWORCH; # base functions and variables for fworch db access -use CACTUS::FWORCH::import; # import functions, parsers -use CGI qw(:standard); # provides argument handling -use Time::HiRes qw(time tv_interval); # provides exact measurement of import execution time -use File::Path qw(make_path rmtree); -use File::Find; -use CACTUS::read_config; - -############################################## - -sub empty_rule_files { # deletes a rule file and creates an empty rule file instead - if ($File::Find::name =~ /\_rulebase\.csv$/) { - system("rm '$File::Find::name'"); - system("touch '$File::Find::name'"); - } -} - -sub empty_config_files { # deletes a csv config file and creates an empty csv file instead - if ($File::Find::name =~ /\.csv$/) { - system("rm '$File::Find::name'"); - system("touch '$File::Find::name'"); - print ("emptying csv config file '" . $File::Find::name . "'\n"); - } else { - print ("leaving config file '" . $File::Find::name . "' untouched\n"); - } -} - -my ($user, $output, $dev_name, $cfg_typ, $admin, $hersteller); -my ($cmd, $dauer, $first_start_time, $start_time, $sqlcode, $fields); -my ($current_import_id, $dev_id, $dev_typ_id); -my $changes = ''; -my $error_str_local = ''; my $error_count_global = 0; my $error_count_local = 0; my $error_level; -my ($template, $obj_file, $obj_file_base, $rule_file, $rule_file_base, $user_file, $user_file_base, $config_files, $config_files_str, - $cmd_str, $is_netscreen,$ssh_hostname,$ssh_user,$ssh_private_key, $ssh_public_key, $ssh_port, $config_path_on_mgmt); -my ($sqldatafile, $csv_zone_file, $csv_obj_file, $csv_svc_file, $csv_usr_file, $csv_auditlog_file, $csv_rule_file, $logfiles, - $show_all_import_errors, $fullauditlog, $clear_all_rules, $clear_whole_mgm_config, $no_md5_checks); -my $prev_imp_id; -my $prev_imp_time = "2000-01-01 00:00:00"; # management has never been imported --> default value -my $do_not_copy = 0; -my $use_scp = 0; -my $no_cleanup = 0; -my $debug_level=0; -my $configfile=""; -my $csvonly = 0; - - -$first_start_time = time; $start_time = $first_start_time; - -my ($mgm_id, $mgm_name) = - &evaluate_parameters((defined(scalar param("mgm_id")))?scalar param("mgm_id"):'', (defined(scalar param("mgm_name")))?scalar param("mgm_name"):''); -if (defined(param("-show-only-first-import-error"))) { $show_all_import_errors = 0; } else { $show_all_import_errors = 1; } -if (defined(param("-fullauditlog"))) { $fullauditlog = 1; } else { $fullauditlog = 0; } -if (defined(param("-clear-all-rules"))) { $clear_all_rules = 1; } else { $clear_all_rules = 0; } -if (defined(param("-clear-management"))) { $clear_whole_mgm_config = 1; } else { $clear_whole_mgm_config = 0; } -if (defined(param("-no-md5-checks"))) { $no_md5_checks = 1; } else { $no_md5_checks = 0; } -if (defined(param("-do-not-copy"))) { $do_not_copy = 1; $no_md5_checks = 1; } # assumes that config has already been copied to fworch importer -if (defined(param("-use-scp"))) { $use_scp = 1; $no_md5_checks = 1; } # assumes that config has already been copied to fworch importer -if (defined(param("-no-cleanup"))) { $no_cleanup = 1; $no_md5_checks = 1; } # assumes that config has already been copied to fworch importer -if (defined(param("-debug"))) { $debug_level = param("-debug"); } -if (defined(param("-configfile"))) { $configfile = param("-configfile"); } -if (defined(param("-csvonly"))) { $csvonly = 1; $do_not_copy = 1; $no_md5_checks = 1; } # for testing - only run db import from existing csv files - -# set basic parameters (read from import.conf) -my $fworch_workdir = &read_config('fworch_workdir') . "/$mgm_id"; -my $archive_dir = &read_config('archive_dir'); -my $cfg_dir = "${fworch_workdir}/cfg"; -my $audit_log_file = "auditlog.export"; -my $bin_path = &read_config('simple_bin_dir') . "/"; -my $save_import_results_to_file = &read_config('save_import_results_to_file'); -my $new_md5sum = 1; -my $stored_md5sum_of_last_import = 2; -my $rulebases; - -# get import info -($error_count_local, $error_str_local, $mgm_name, $dev_typ_id, $obj_file_base,$obj_file,$user_file_base,$user_file,$rule_file_base,$rule_file, - $csv_zone_file, $csv_obj_file, $csv_svc_file, $csv_usr_file, $csv_auditlog_file, - $ssh_hostname,$ssh_user,$ssh_private_key,$ssh_public_key,$hersteller,$is_netscreen, $config_files, $ssh_port, $config_path_on_mgmt) = - &get_import_infos_for_mgm($mgm_id, $fworch_workdir, $cfg_dir); -$error_count_global = &error_handler_add(undef, $error_level = 5, "mgm-id-not-found: $mgm_id", $error_count_local, $error_count_global); - -# check if device is a legacy device, otherwise exit here without doing anything -# (2,'Netscreen','5.x-6.x','Netscreen', ''); -# (4,'FortiGateStandalone','5ff','Fortinet',''); -# (5,'Barracuda Firewall Control Center','Vx','phion',''); -# (6,'phion netfence','3.x','phion',''); -# (7,'Check Point','R5x-R7x','Check Point',''); -if (!(grep {$_ eq $dev_typ_id} (2,4,5,6,7,8))) { - output_txt("Management $mgm_name (mgm_id=$mgm_id, dev_typ_id=$dev_typ_id): not a legacy device type, skipping\n"); - exit (0); -} - -my $import_was_already_running = (&is_import_running($mgm_id))?1:0; -my $initial_import_flag = &is_initial_import($mgm_id); -$current_import_id = &insert_control_entry($initial_import_flag,$mgm_id); # set import lock - -output_txt ("current_import_id=$current_import_id"); -$error_count_global = &error_handler_add($current_import_id, $error_level = 3, "set-import-lock-failed", !defined($current_import_id), $error_count_global); -$error_count_global = &error_handler_add($current_import_id, $error_level = 2, "import-already-running: $mgm_name (ID: $mgm_id)", - $import_was_already_running, $error_count_global); - -if (!$error_count_global) { - require "CACTUS/FWORCH/import/$hersteller.pm"; # load the matching parser at run time - $rulebases = &get_rulebase_names($mgm_id, $CACTUS::FWORCH::dbdriver, $fworch_database, $fworch_srv_host, $fworch_srv_port, $fworch_srv_user, $fworch_srv_pw); - if (!$do_not_copy && !$csvonly) { - rmtree($fworch_workdir); make_path($fworch_workdir,{mode => 0700}); make_path($cfg_dir,{mode => 0700}); - $error_count_global = &error_handler_add($current_import_id, $error_level = 2, "copy-ssh-keys-failed", - $error_count_local = &put_ssh_keys_in_place ($fworch_workdir, $ssh_public_key, $ssh_private_key), $error_count_global); - if (!$initial_import_flag) { - $prev_imp_id = exec_pgsql_cmd_return_value("SELECT get_last_import_id_for_mgmt($mgm_id)"); - $prev_imp_time = exec_pgsql_cmd_return_value("SELECT start_time FROM import_control WHERE control_id=$prev_imp_id AND successful_import"); - } - # 1) read names of rulebases of each device from database - # copy config data from management system to fworch import system - if ($configfile ne "") { - system ("${bin_path}scp $configfile $cfg_dir/$obj_file_base"); - } - else { - ($error_count_local, $config_files_str) = - &CACTUS::FWORCH::import::parser::copy_config_from_mgm_to_iso - ($ssh_user, $ssh_hostname, $mgm_name, $obj_file_base, $cfg_dir, $rule_file_base, - $fworch_workdir, $audit_log_file, $prev_imp_time, $ssh_port, $config_path_on_mgmt, $rulebases, $debug_level); # TODO: add use_scp parameter - } - if ($error_count_local) { - if ($is_netscreen) { # file-check wg. Netscreen-Return-Code eingebaut - my $file_size = -s "$cfg_dir/$obj_file_base"; - if (!defined ($file_size) || $file_size==0) { - $error_count_global = &error_handler_add($current_import_id, $error_level = 3, "netscreen-copy-config-failed: $mgm_name, $error_str_local", - $error_count_local=1, $error_count_global); - } - } else { - $error_count_global = &error_handler_add($current_import_id, $error_level = 3, "copy-config-failed: $mgm_name, $error_str_local", - $error_count_local=1, $error_count_global); - } - } - # check if config has changed - $stored_md5sum_of_last_import = exec_pgsql_cmd_return_value ("SELECT last_import_md5_complete_config FROM management WHERE mgm_id=$mgm_id"); - if (!defined($stored_md5sum_of_last_import)) { $stored_md5sum_of_last_import = -1; } - # clear stored md5 hash in any case to force import during next run even if transfer of config fails this time - &exec_pgsql_cmd_no_result("UPDATE management SET last_import_md5_complete_config='cleared' WHERE mgm_id=$mgm_id"); - &iconv_config_files_2_utf8($config_files_str, $fworch_workdir); # convert config files from latin1 to utf-8 - - $new_md5sum = &calc_md5_of_files($config_files_str, $fworch_workdir); # fworch_workdir is here tmpdir - $error_count_global = &error_handler_add ($current_import_id, $error_level = 3, "calc-md5sum-failed", (defined($new_md5sum))?0:1, $error_count_global); - } # end of do_not_copy / $csvonly - if (!$error_count_global) { - if ($new_md5sum ne $stored_md5sum_of_last_import || $no_md5_checks) { - if (!$csvonly) - { - $start_time = time(); # parse start time - output_txt("---------------------------------------------------------------------------\n"); - output_txt("Starting import of management: $mgm_name\n"); - # 2) parse config - $error_count_local = &CACTUS::FWORCH::import::parser::parse_config ($obj_file, $rule_file, $user_file, $rulebases, $fworch_workdir, $debug_level, $mgm_name, $cfg_dir, - $current_import_id, "$cfg_dir/$audit_log_file", $prev_imp_time, $fullauditlog, $debug_level); - if ($error_count_local) { - $error_count_global = &error_handler_add( $current_import_id, $error_level = 3, "parse-$error_count_local", $error_count_local=1, $error_count_global); - if (defined($current_import_id)) - { - $error_count_local = &exec_pgsql_cmd_no_result("SELECT remove_import_lock($current_import_id)"); - } - $error_count_global = &error_handler_add - ($current_import_id, $error_level = 3, "remove-import-lock-failed: $error_count_local", $error_count_local, $error_count_global); - } - output_txt("Parsing done in " . sprintf("%.2f",(time() - $start_time)) . " seconds"); - } - if (!$error_count_global) { - if (!$csvonly) - { - &set_last_change_time($last_change_time_of_config, $current_import_id); # Zeit eintragen, zu der die letzte Aenderung an der Config vorgenommen wurde (tuning) - } - # starting import from csv to database - # 3a) fill import tables with bulk copy cmd from csv - if ($clear_all_rules) # clear rule csv files, if we want to enforce an initial import - { - find(\&empty_rule_files,$fworch_workdir); - print("clearing rule files\n"); - } - if ($clear_whole_mgm_config) # clear all data to force initial import - { - find(\&empty_config_files,$fworch_workdir); - print("clearing all csv files\n"); - } - if (-e $csv_usr_file) { &iconv_2_utf8($csv_usr_file, $fworch_workdir); } # utf-8 conversion of user data - - # if $csvonly is set: replace import id in all csv files with $current_import_id - if ($csvonly) - { - my @rulebase_basenames = split(/,/, get_local_ruleset_name_list($rulebases)); - my @rulebase_fullnames = (); - for my $filename (@rulebase_basenames) { - @rulebase_fullnames = (@rulebase_fullnames, $fworch_workdir . '/' . $filename . '_rulebase.csv' ); - } - for my $csvfile (($csv_zone_file, $csv_obj_file, $csv_svc_file, $csv_usr_file, @rulebase_fullnames)) { - # print ("replacing import_id in csvfile=$csvfile\n"); - if (-e $csvfile) { - replace_import_id_in_csv($csvfile, $current_import_id); - } - } - } - - $error_count_local = &fill_import_tables_from_csv($dev_typ_id,$csv_zone_file, $csv_obj_file, $csv_svc_file, $csv_usr_file, $rulebases, $fworch_workdir, $csv_auditlog_file); - - # 3b) if an error occured, import everything in single sql statement steps to be able to spot the error - if ($error_count_local) { - $error_count_global = &error_handler_add ($current_import_id, $error_level = 3, "first problems while filling database: $error_count_local", - $error_count_local, $error_count_global); - if ($show_all_import_errors) { - - &fill_import_tables_from_csv_with_sql ($dev_typ_id,$csv_zone_file, $csv_obj_file, $csv_svc_file, $csv_usr_file, $rulebases, $fworch_workdir, $csv_auditlog_file); - - } - } - # 4) wrapping up - # updating last import attempt date directly in DB - &exec_pgsql_cmd_no_result("UPDATE management SET last_import_attempt=now() WHERE mgm_id=$mgm_id"); - - if (!$error_count_global) { # import ony when no previous errors occured - $error_count_local = 0; - my $imp_result_str = &exec_pgsql_cmd_return_value("SET client_min_messages TO NOTICE; SELECT import_all_main($current_import_id, FALSE)"); - if ($imp_result_str ne '') { - $error_count_local = 1; - print("first import run found errors: " . $imp_result_str . ", re-running import with DEBUG option\n"); - &exec_pgsql_cmd_return_value("SET client_min_messages TO DEBUG1; SELECT import_all_main($current_import_id, FALSE)"); - print("second import run with debugging completed\n"); - } else { - print("found no errors during import\n"); - } - $error_count_global = &error_handler_add ($current_import_id, $error_level = 3, "", $error_count_local, $error_count_global); - $changes = &exec_pgsql_cmd_return_value("SELECT show_change_summary($current_import_id)"); - # updating md5sum - if (!$error_count_global) { &exec_pgsql_cmd_no_result("UPDATE management SET last_import_md5_complete_config='$new_md5sum' WHERE mgm_id=$mgm_id"); } - } - } - # output results and set import status - if ($changes ne '') { output_txt("Changes: $changes\n"); } - if ($error_count_global) { output_txt ("Import of management $mgm_name (mgm_id=$mgm_id, import_id=$current_import_id): FOUND $error_count_global error(s)\n", 2); } - else { - my $changes_found = 0; - if ($changes ne '') { $changes_found = 1; } - output_txt ("Import of management $mgm_name (mgm_id=$mgm_id, import_id=$current_import_id)" . - ", total time: " . sprintf("%.2fs",(time() - $first_start_time)) . "): no errors found" . (($changes_found )?"":", no changes found") . "\n"); - my $sql_cmd = 'UPDATE import_control SET successful_import=TRUE' . (($changes_found)? ', changes_found=TRUE':'') . ' WHERE control_id=' . $current_import_id; - &exec_pgsql_cmd_no_result($sql_cmd); # if no error occured - set import_control.successful_import to true - } - } else { - output_txt("Management $mgm_name (mgm_id=$mgm_id), no changes in configuration files (MD5)\n"); - &exec_pgsql_cmd_no_result("DELETE FROM import_control WHERE control_id=$current_import_id"); # remove imports with unchanged data - &exec_pgsql_cmd_no_result("UPDATE management SET last_import_md5_complete_config='$new_md5sum' WHERE mgm_id=$mgm_id"); - } - } - # Cleanup and statistics - if (defined($current_import_id)) - { - &exec_pgsql_cmd_no_result("SELECT remove_import_lock($current_import_id)"); # this sets import_control.stop_time to now() - } - &clean_up_fworch_db($current_import_id); - if (defined($save_import_results_to_file) && $save_import_results_to_file && ($error_count_global || $changes ne '')) { # if changes or errors occured: move config & csv to archive - system ("${bin_path}mkdir -p $archive_dir; cd $fworch_workdir; ${bin_path}tar cfz $archive_dir/${current_import_id}_`${bin_path}date +%F_%T`_mgm_id_$mgm_id.tgz ."); - } - #`cp -f $fworch_workdir/cfg/*.cfg /var/itsecorg/fw-config/`; # special backup for several configs - dos-box - if (!$no_cleanup) { rmtree $fworch_workdir; } -} else { - if (defined($current_import_id)) - { - &exec_pgsql_cmd_no_result("SELECT remove_import_lock($current_import_id)"); # this sets import_control.stop_time to now() - } -} -exit ($error_count_global); diff --git a/roles/importer/files/importer/fworch-importer-srv-helper b/roles/importer/files/importer/fworch-importer-srv-helper deleted file mode 100755 index 3d60311ac1..0000000000 --- a/roles/importer/files/importer/fworch-importer-srv-helper +++ /dev/null @@ -1,10 +0,0 @@ -#!/bin/sh - -IMPORTER_SINGLE=fworch-importer-single.pl -RES=`pidof -x $IMPORTER_SINGLE >/dev/null;echo $?` -if [ $RES -eq 0 ]; then - while [ $RES -eq 0 ]; do - sleep 5 - RES=`pidof -x $IMPORTER_SINGLE >/dev/null;echo $?` - done -fi diff --git a/roles/importer/files/importer/import-api-stop-helper b/roles/importer/files/importer/import-api-stop-helper deleted file mode 100755 index 6ba5135e7c..0000000000 --- a/roles/importer/files/importer/import-api-stop-helper +++ /dev/null @@ -1,10 +0,0 @@ -#!/bin/sh - -IMPORTER_SINGLE=import-mgm.py -RES=`pidof -x $IMPORTER_SINGLE >/dev/null;echo $?` -if [ $RES -eq 0 ]; then - while [ $RES -eq 0 ]; do - sleep 5 - RES=`pidof -x $IMPORTER_SINGLE >/dev/null;echo $?` - done -fi diff --git a/roles/importer/files/importer/import-main-loop.py b/roles/importer/files/importer/import-main-loop.py deleted file mode 100755 index f619a1283b..0000000000 --- a/roles/importer/files/importer/import-main-loop.py +++ /dev/null @@ -1,165 +0,0 @@ -#!/usr/bin/python3 -# add main importer loop in pyhton (also able to run distributed) -# run import loop every x seconds (adjust sleep time per management depending on the change frequency ) - -import signal -import traceback -import argparse -import sys -import time -import json -import requests, warnings -import fwo_api# common # from current working dir -from common import import_management -from fwo_log import getFwoLogger -import fwo_globals, fwo_config -from fwo_const import base_dir, importer_base_dir -from fwo_exception import FwoApiLoginFailed, FwoApiFailedLockImport, FwLoginFailed - - -# https://stackoverflow.com/questions/18499497/how-to-process-sigterm-signal-gracefully -class GracefulKiller: - kill_now = False - - def __init__(self): - signal.signal(signal.SIGINT, self.exit_gracefully) - signal.signal(signal.SIGTERM, self.exit_gracefully) - - def exit_gracefully(self, *args): - self.kill_now = True - - -if __name__ == '__main__': - parser = argparse.ArgumentParser( - description='Run import loop across all managements to read configuration from FW managements via API calls') - parser.add_argument('-d', '--debug', metavar='debug_level', default='0', - help='Debug Level: 0=off, 1=send debug to console, 2=send debug to file, 3=keep temporary config files; default=0') - parser.add_argument('-v', "--verify_certificates", action='store_true', default = None, - help = "verify certificates") - parser.add_argument('-s', "--suppress_certificate_warnings", action='store_true', default = None, - help = "suppress certificate warnings") - parser.add_argument('-c', '--clear', action='store_true', default=False, - help='If set all imports will run once to delete all data instead of importing') - parser.add_argument('-f', '--force', action='store_true', default=False, - help='If set all imports will be run without checking for changes before') - - args = parser.parse_args() - - fwo_config = fwo_config.readConfig() - fwo_globals.setGlobalValues(verify_certs_in=args.verify_certificates, - suppress_cert_warnings_in=args.suppress_certificate_warnings, - debug_level_in=args.debug) - if args.suppress_certificate_warnings: - requests.packages.urllib3.disable_warnings() - - debug_level = int(args.debug) - logger = getFwoLogger() - - logger.info("importer-main-loop starting ...") - sys.path.append(importer_base_dir) - importer_user_name = 'importer' # todo: move to config file? - fwo_config_filename = base_dir + '/etc/fworch.json' - importer_pwd_file = base_dir + '/etc/secrets/importer_pwd' - - # setting defaults (only as fallback if config defaults cannot be fetched via API): - api_fetch_limit = 150 - sleep_timer = 90 - jwt = "" - mgm_ids = [] - - # read fwo config (API URLs) - try: - with open(fwo_config_filename, "r") as fwo_config: - fwo_config = json.loads(fwo_config.read()) - user_management_api_base_url = fwo_config['middleware_uri'] - fwo_api_base_url = fwo_config['api_uri'] - except: - logger.error("import-main-loop - error while reading FWO config file") - raise - - mgm_details = {} - killer = GracefulKiller() - while not killer.kill_now: - # authenticate to get JWT - skipping = False - try: - with open(importer_pwd_file, 'r') as file: - importer_pwd = file.read().replace('\n', '') - except: - logger.error("import-main-loop - error while reading importer pwd file") - raise - - try: - jwt = fwo_api.login(importer_user_name, importer_pwd, user_management_api_base_url) - except FwoApiLoginFailed as e: - logger.error(e.message) - skipping = True - except: - logger.error("import-main-loop - Unspecified error while logging into FWO API: " + str(traceback.format_exc())) - skipping = True - - requests.packages.urllib3.disable_warnings() # suppress ssl warnings only - verify_certificates = fwo_api.get_config_value(fwo_api_base_url, jwt, key='importCheckCertificates')=='True' - suppress_certificate_warnings = fwo_api.get_config_value(fwo_api_base_url, jwt, key='importSuppressCertificateWarnings')=='True' - if not suppress_certificate_warnings: - warnings.resetwarnings() - - if not skipping: - try: - mgm_ids = fwo_api.get_mgm_ids(fwo_api_base_url, jwt, {}) - except: - logger.error("import-main-loop - error while getting FW management ids: " + str(traceback.format_exc())) - skipping = True - - try: - api_fetch_limit = fwo_api.get_config_value(fwo_api_base_url, jwt, key='fwApiElementsPerFetch') - sleep_timer = fwo_api.get_config_value(fwo_api_base_url, jwt, key='importSleepTime') - if api_fetch_limit == None: - api_fetch_limit = 150 - if sleep_timer == None: - sleep_timer = 90 - except: - logger.debug("import-main-loop - could not get config values from FWO API - using default values") - - if not skipping: - for mgm_id in mgm_ids: - if killer.kill_now: - break - if 'id' not in mgm_id: - logger.error("import-main-loop - did not get mgm_id: " + str(traceback.format_exc())) - else: - id = str(mgm_id['id']) - # getting a new JWT in case the old one is not valid anymore after a long previous import - try: - jwt = fwo_api.login(importer_user_name, importer_pwd, user_management_api_base_url) - except FwoApiLoginFailed as e: - logger.error(e.message) - skipping = True - except: - logger.error("import-main-loop - unspecified error during FWO API login - skipping: " + str(traceback.format_exc())) - skipping = True - if not skipping: - try: - mgm_details = fwo_api.get_mgm_details(fwo_api_base_url, jwt, {"mgmId": id}) - except: - logger.error("import-main-loop - error while getting FW management details for mgm_id=" + str(id) + " - skipping: " + str(traceback.format_exc())) - skipping = True - if not skipping and mgm_details["deviceType"]["id"] in (9, 11, 17, 22, 23, 24): # only handle CPR8x Manager, fortiManager, Cisco MgmCenter, Palo Panorama, Palo FW, FortiOS REST - logger.debug("import-main-loop: starting import of mgm_id=" + id) - try: - import_result = import_management(mgm_id=id, debug_level_in=debug_level, - clearManagementData=args.clear, force=args.force, limit=str(api_fetch_limit)) - except (FwoApiFailedLockImport, FwLoginFailed): - pass # minor errors for a single mgm, go to next one - except: # all other exceptions are logged here - logger.error("import-main-loop - unspecific error while importing mgm_id=" + str(id) + ", " + str(traceback.format_exc())) - if args.clear: - break # while loop - if not killer.kill_now: - logger.info("import-main-loop.py: sleeping between loops for " + str(sleep_timer) + " seconds") - counter=0 - while counter < int(sleep_timer) and not killer.kill_now: - time.sleep(1) - counter += 1 - - logger.info("importer-main-loop exited gracefully.") diff --git a/roles/importer/files/importer/import-mgm.py b/roles/importer/files/importer/import-mgm.py deleted file mode 100755 index b1897c2d87..0000000000 --- a/roles/importer/files/importer/import-mgm.py +++ /dev/null @@ -1,66 +0,0 @@ -#!/usr/bin/python3 -import sys, traceback -from fwo_log import getFwoLogger -import argparse -import requests, requests.packages -from common import importer_base_dir, import_management -import fwo_globals, fwo_config -sys.path.append(importer_base_dir) - - -if __name__ == "__main__": - parser = argparse.ArgumentParser( - description='Read configuration from FW management via API calls') - parser.add_argument('-m', '--mgm_id', metavar='management_id', - required=True, help='FWORCH DB ID of the management server to import') - parser.add_argument('-c', '--clear', action='store_true', default=False, - help='If set the import will delete all data for the given management instead of importing') - parser.add_argument('-f', '--force', action='store_true', default=False, - help='If set the import will be attempted without checking for changes or if the importer module is the one defined') - parser.add_argument('-d', '--debug', metavar='debug_level', default='0', - help='Debug Level: \ - 0=off, \ - 1=send debug to console, \ - 2=send debug to file, \ - 3=save noramlized config file, \ - 4=additionally save native config file, \ - 8=send native config (as read from firewall) to standard out, \ - 9=send normalized config to standard out, \ - (default=0), \ - config files are saved to $FWORCH/tmp/import dir') - parser.add_argument('-v', "--verify_certificates", action='store_true', default = None, - help = "verify certificates") - parser.add_argument('-s', "--suppress_certificate_warnings", action='store_true', default = None, - help = "suppress certificate warnings") - parser.add_argument('-l', '--limit', metavar='api_limit', default='150', - help='The maximal number of returned results per HTTPS Connection; default=150') - parser.add_argument('-i', '--in_file', metavar='config_file_input', - help='if set, the config will not be fetched from firewall but read from native json config file specified here; may also be an url.') - parser.add_argument('-n', '--normalized_in_file', metavar='config_file_normalized_input', - help='if set, the config will not be fetched from firewall but read from normalized json config file specified here; may also be an url.') - - args = parser.parse_args() - if len(sys.argv) == 1: - parser.print_help(sys.stderr) - sys.exit(1) - - fwo_config = fwo_config.readConfig() - fwo_globals.setGlobalValues(verify_certs_in=args.verify_certificates, - suppress_cert_warnings_in=args.suppress_certificate_warnings, - debug_level_in=args.debug) - if args.suppress_certificate_warnings: - requests.packages.urllib3.disable_warnings() - logger = getFwoLogger() - - try: - error_count = import_management( - mgm_id=args.mgm_id, in_file=args.in_file, normalized_in_file=args.normalized_in_file, debug_level_in=args.debug, ssl_verification=args.verify_certificates, - force=args.force, limit=args.limit, clearManagementData=args.clear, suppress_cert_warnings_in=args.suppress_certificate_warnings) - except SystemExit: - print ("import-mgm - error while importing mgm_id=" + str(args.mgm_id)) - error_count = 1 - except: - logger.error("import-mgm - error while importing mgm_id=" + str(args.mgm_id) + ": " + str(traceback.format_exc())) - error_count = 1 - - sys.exit(error_count) diff --git a/roles/importer/files/importer/import-stop-helper b/roles/importer/files/importer/import-stop-helper deleted file mode 100755 index 3d60311ac1..0000000000 --- a/roles/importer/files/importer/import-stop-helper +++ /dev/null @@ -1,10 +0,0 @@ -#!/bin/sh - -IMPORTER_SINGLE=fworch-importer-single.pl -RES=`pidof -x $IMPORTER_SINGLE >/dev/null;echo $?` -if [ $RES -eq 0 ]; then - while [ $RES -eq 0 ]; do - sleep 5 - RES=`pidof -x $IMPORTER_SINGLE >/dev/null;echo $?` - done -fi diff --git a/roles/importer/files/importer/import_main_loop.py b/roles/importer/files/importer/import_main_loop.py new file mode 100755 index 0000000000..9f22a6c607 --- /dev/null +++ b/roles/importer/files/importer/import_main_loop.py @@ -0,0 +1,287 @@ +#!/usr/bin/env python3 +# main importer loop in python (also able to run distributed) +# run import loop every x seconds (adjust sleep time per management depending on the change frequency ) + +import argparse +import sys +import time +import traceback +import warnings + +import fwo_globals +import urllib3 +from common import import_management # type: ignore[import-not-found] +from fwo_api import FwoApi +from fwo_api_call import FwoApiCall +from fwo_base import init_service_provider, register_global_state +from fwo_const import BASE_DIR, IMPORTER_BASE_DIR +from fwo_exceptions import ( + FwLoginFailedError, + FwoApiFailedLockImportError, + FwoApiLoginFailedError, +) +from fwo_log import FWOLogger +from model_controllers.import_state_controller import ImportStateController +from model_controllers.management_controller import ( + ConnectionInfo, + CredentialInfo, + DeviceInfo, + DomainInfo, + ManagementController, + ManagerInfo, +) +from services.service_provider import ServiceProvider + + +def get_fwo_jwt(import_user: str, import_pwd: str, user_management_api: str) -> str | None: + try: + return FwoApi.login(import_user, import_pwd, user_management_api) + except FwoApiLoginFailedError as e: + FWOLogger.error(e.message) + except Exception: + FWOLogger.error( + "import_main_loop - unspecified error during FWO API login - skipping: " + str(traceback.format_exc()) + ) + + +def wait_with_shutdown_check(sleep_time: int): + counter = 0 + while counter < sleep_time: + if fwo_globals.shutdown_requested: + FWOLogger.info("import_main_loop - shutdown requested. Exiting...") + raise SystemExit("import_main_loop - shutdown requested") + time.sleep(1) + counter += 1 + + +def import_single_management( + mgm_id: int, + fwo_api_call: FwoApiCall, + verify_certificates: bool, + api_fetch_limit: int, + clear: bool, + suppress_certificate_warnings: bool, + force: bool, + fwo_major_version: int, + sleep_timer: int, + suppress_consistency_check: bool = False, +): + wait_with_shutdown_check(0) + import_state = ImportStateController.initialize_import( + mgm_id=mgm_id, + api_call=fwo_api_call, + suppress_cert_warnings=suppress_certificate_warnings, + ssl_verification=verify_certificates, + force=force, + version=fwo_major_version, + is_clearing_import=clear, + ) + + register_global_state(import_state) + + try: + mgm_controller = ManagementController( + mgm_id, + "", + [], + DeviceInfo(), + ConnectionInfo(), + "", + CredentialInfo(), + ManagerInfo(), + DomainInfo(), + ) + mgm_details = mgm_controller.get_mgm_details(fwo_api_call.api, mgm_id) + except Exception: + FWOLogger.error( + "import_main_loop - error while getting FW management details for mgm_id=" + + str(mgm_id) + + " - skipping: " + + str(traceback.format_exc()) + ) + wait_with_shutdown_check(sleep_timer) + return + + # only handle CPR8x Manager, fortiManager, Cisco MgmCenter, Palo Panorama, Palo FW, FortiOS REST, Cisco Asa, Asa on FirePower + if mgm_details["deviceType"]["id"] not in (9, 12, 17, 22, 23, 24, 28, 29): + return + + FWOLogger.debug(f"import_main_loop: starting import of mgm_id={mgm_id}") + + try: + import_management( + mgm_id, + fwo_api_call, + verify_certificates, + api_fetch_limit, + clear, + suppress_certificate_warnings, + suppress_consistency_check=suppress_consistency_check, + ) + except (FwoApiFailedLockImportError, FwLoginFailedError): + FWOLogger.info(f"import_main_loop - minor error while importing mgm_id={mgm_id}, {traceback.format_exc()!s}") + return # minor errors for a single mgm, go to next one + except Exception: # all other exceptions are logged here + FWOLogger.error( + f"import_main_loop - unspecific error while importing mgm_id={mgm_id}, {traceback.format_exc()!s}" + ) + + +def main_loop( + importer_pwd_file: str, + importer_user_name: str, + user_management_api_base_url: str, + fwo_api_base_url: str, + fwo_major_version: int, + api_fetch_limit: int, + sleep_timer: int, + clear: bool, + force: bool, +): + wait_with_shutdown_check(0) + + try: + with open(importer_pwd_file) as f: + importer_pwd = f.read().replace("\n", "") + except Exception: + FWOLogger.error("import_main_loop - error while reading importer pwd file") + raise + + jwt = get_fwo_jwt(importer_user_name, importer_pwd, user_management_api_base_url) + # check if login was successful - if not, wait and retry + if jwt is None: + wait_with_shutdown_check(sleep_timer) + return + + fwo_api = FwoApi(fwo_api_base_url, jwt) + fwo_api_call = FwoApiCall(fwo_api) + + urllib3.disable_warnings() # type: ignore[suppress ssl warnings only] + verify_certificates = fwo_api_call.get_config_value(key="importCheckCertificates") == "True" + suppress_certificate_warnings = fwo_api_call.get_config_value(key="importSuppressCertificateWarnings") == "True" + if not suppress_certificate_warnings: + warnings.resetwarnings() + + try: + mgm_ids = fwo_api_call.get_mgm_ids() + except Exception: + FWOLogger.error(f"import_main_loop - error while getting FW management ids: {traceback.format_exc()!s}") + wait_with_shutdown_check(sleep_timer) + return + + api_fetch_limit = int(fwo_api_call.get_config_value(key="fwApiElementsPerFetch") or api_fetch_limit) + sleep_timer = int(fwo_api_call.get_config_value(key="importSleepTime") or sleep_timer) + + ## loop through all managements + for mgm_id in mgm_ids: + init_service_provider() + import_single_management( + mgm_id, + fwo_api_call, + verify_certificates, + api_fetch_limit, + clear, + suppress_certificate_warnings, + force, + fwo_major_version, + sleep_timer, + ) + + ServiceProvider().reset() + + FWOLogger.info(f"import_main_loop: sleeping for {sleep_timer} seconds until next import cycle") + wait_with_shutdown_check(sleep_timer) + + +def main( + debug_level: int, + verify_certificates: bool | None = None, + suppress_certificate_warnings: bool | None = None, + clear: bool = False, + force: bool = False, +): + FWOLogger(debug_level) + service_provider = init_service_provider() + fwo_config = service_provider.get_fwo_config() + fwo_api_base_url = fwo_config["fwo_api_base_url"] + fwo_major_version = fwo_config["fwo_major_version"] + user_management_api_base_url = fwo_config["user_management_api_base_url"] + fwo_globals.set_global_values(verify_certificates, suppress_certificate_warnings) + if suppress_certificate_warnings: + urllib3.disable_warnings() # type: ignore[suppress ssl warnings only] + + FWOLogger.info("importer_main_loop starting ...") + if IMPORTER_BASE_DIR not in sys.path: + sys.path.append(IMPORTER_BASE_DIR) + importer_user_name = "importer" # move to config file? + importer_pwd_file = BASE_DIR + "/etc/secrets/importer_pwd" + + # setting defaults (only as fallback if config defaults cannot be fetched via API): + api_fetch_limit: int = 150 + sleep_timer: int = 90 + + while True: + main_loop( + importer_pwd_file, + importer_user_name, + user_management_api_base_url, + fwo_api_base_url, + fwo_major_version, + api_fetch_limit, + sleep_timer, + clear, + force, + ) + if clear: + break + + +if __name__ == "__main__": + parser = argparse.ArgumentParser( + description="Run import loop across all managements to read configuration from FW managements via API calls" + ) + parser.add_argument( + "-d", + "--debug", + metavar="debug_level", + default="0", + help="Debug Level: 0=off, 1=send debug to console, 2=send debug to file, 3=keep temporary config files; default=0", + ) + parser.add_argument( + "-v", + "--verify_certificates", + action="store_true", + default=None, + help="verify certificates", + ) + parser.add_argument( + "-s", + "--suppress_certificate_warnings", + action="store_true", + default=None, + help="suppress certificate warnings", + ) + parser.add_argument( + "-c", + "--clear", + action="store_true", + default=False, + help="If set all imports will run once to delete all data instead of importing", + ) + parser.add_argument( + "-f", + "--force", + action="store_true", + default=False, + help="If set all imports will be run without checking for changes before", + ) + + args = parser.parse_args() + + main( + debug_level=int(args.debug), + verify_certificates=args.verify_certificates, + suppress_certificate_warnings=args.suppress_certificate_warnings, + clear=args.clear, + force=args.force, + ) diff --git a/roles/importer/files/importer/import_mgm.py b/roles/importer/files/importer/import_mgm.py new file mode 100755 index 0000000000..4d311e120b --- /dev/null +++ b/roles/importer/files/importer/import_mgm.py @@ -0,0 +1,198 @@ +#!/usr/local/fworch/importer/importer-venv/bin/python3 +import argparse +import sys +import traceback +import warnings + +import urllib3 +from common import import_management # type: ignore[import-not-found] +from fwo_api import FwoApi +from fwo_api_call import FwoApiCall +from fwo_base import init_service_provider, register_global_state +from fwo_const import BASE_DIR, IMPORTER_BASE_DIR +from fwo_exceptions import FwoApiLoginFailedError +from fwo_log import FWOLogger +from model_controllers.import_state_controller import ImportStateController + +if IMPORTER_BASE_DIR not in sys.path: + sys.path.append(IMPORTER_BASE_DIR) + + +def get_fwo_jwt(import_user: str, import_pwd: str, user_management_api: str) -> str | None: + try: + return FwoApi.login(import_user, import_pwd, user_management_api) + except FwoApiLoginFailedError as e: + FWOLogger.error(e.message) + except Exception: + FWOLogger.error( + "import_main_loop - unspecified error during FWO API login - skipping: " + str(traceback.format_exc()) + ) + + +def main( + mgm_id: int, + file: str | None = None, + debug_level: int = 0, + verify_certificates_default: bool = False, + force: bool = False, + limit: int = 150, + clear_management_data: bool = False, + suppress_certificate_warnings: bool = False, + suppress_consistency_check: bool = False, +): + FWOLogger(debug_level) + FWOLogger.debug("debug level set to " + str(debug_level)) + + service_provider = init_service_provider() + fwo_config = service_provider.get_fwo_config() + verify_certificates = verify_certificates_default + fwo_api_base_url = fwo_config["fwo_api_base_url"] + fwo_major_version = fwo_config["fwo_major_version"] + user_management_api_base_url = fwo_config["user_management_api_base_url"] + if suppress_certificate_warnings: + urllib3.disable_warnings() + + FWOLogger.info("import-mgm starting ...") + if IMPORTER_BASE_DIR not in sys.path: + sys.path.append(IMPORTER_BASE_DIR) + + importer_user_name = "importer" # move to config file? + importer_pwd_file = BASE_DIR + "/etc/secrets/importer_pwd" + + try: + importer_pwd = open(importer_pwd_file).read().replace("\n", "") # noqa: SIM115 + except Exception: + FWOLogger.error("error while reading importer pwd file") + raise + + jwt = get_fwo_jwt(importer_user_name, importer_pwd, user_management_api_base_url) + # check if login was successful - if not, wait and retry + if jwt is None: + FWOLogger.error("cannot proceed without successful login - exiting") + return + + fwo_api = FwoApi(fwo_api_base_url, jwt) + fwo_api_call = FwoApiCall(fwo_api) + + urllib3.disable_warnings() # suppress ssl warnings only + verify_certificates = fwo_api_call.get_config_value(key="importCheckCertificates") == "True" + suppress_certificate_warnings = fwo_api_call.get_config_value(key="importSuppressCertificateWarnings") == "True" + if not suppress_certificate_warnings: + warnings.resetwarnings() + + import_state = ImportStateController.initialize_import( + mgm_id, + fwo_api_call, + suppress_certificate_warnings, + verify_certificates, + force, + fwo_major_version, + clear_management_data, + ) + register_global_state(import_state) + + import_management( + mgm_id, + fwo_api_call, + verify_certificates, + limit, + clear_management_data, + suppress_certificate_warnings, + file, + suppress_consistency_check, + ) + + +if __name__ == "__main__": + parser = argparse.ArgumentParser(description="Read configuration from FW management via API calls") + parser.add_argument( + "-m", + "--mgmId", + metavar="management_id", + required=True, + help="FWORCH DB ID of the management server to import", + ) + parser.add_argument( + "-c", + "--clear", + action="store_true", + default=False, + help="If set the import will delete all data for the given management instead of importing", + ) + parser.add_argument( + "-f", + "--force", + action="store_true", + default=False, + help="If set the import will be attempted without checking for changes or if the importer module is the one defined", + ) + parser.add_argument( + "-d", + "--debug", + metavar="debug_level", + default="0", + help="Debug Level: \ + 0=off, \ + 1=send debug to console, \ + 2=send debug to file, \ + 3=save noramlized config file, \ + 4=additionally save native config file, \ + 8=send native config (as read from firewall) to standard out, \ + 9=send normalized config to standard out, \ + (default=0), \ + config files are saved to $FWORCH/tmp/import dir", + ) + parser.add_argument( + "-v", + "--verify_certificates", + action="store_true", + default=None, + help="verify certificates", + ) + parser.add_argument( + "-s", + "--suppress_certificate_warnings", + action="store_true", + default=None, + help="suppress certificate warnings", + ) + parser.add_argument( + "-l", + "--limit", + metavar="api_limit", + default="150", + help="The maximal number of returned results per HTTPS Connection; default=150", + ) + parser.add_argument( + "-i", + "--in_file", + metavar="config_file_input", + help="if set, the config will not be fetched from firewall but read from json config (native or normalized) file specified here; may also be an url.", + ) + parser.add_argument( + "--suppress_consistency_check", + action="store_true", + default=False, + help="If set, skip FwConfigImportCheckConsistency before importing", + ) + + args = parser.parse_args() + + try: + main( + int(args.mgmId), # TYPING: this should be snake case + args.in_file, + int(args.debug), + args.verify_certificates, + args.force, + int(args.limit), + args.clear, + args.suppress_certificate_warnings, + args.suppress_consistency_check, + ) + except Exception: + FWOLogger.error( + "import-mgm - error while importing mgmId=" + str(args.mgmId) + ": " + str(traceback.format_exc()) + ) + + sys.exit() diff --git a/roles/importer/files/importer/model_controllers/__init__.py b/roles/importer/files/importer/model_controllers/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/roles/importer/files/importer/model_controllers/check_consistency.py b/roles/importer/files/importer/model_controllers/check_consistency.py new file mode 100644 index 0000000000..1329f6c09f --- /dev/null +++ b/roles/importer/files/importer/model_controllers/check_consistency.py @@ -0,0 +1,892 @@ +from collections.abc import Callable +from typing import TYPE_CHECKING, Any + +import fwo_const +from fwo_exceptions import FwoImporterErrorInconsistenciesError +from fwo_log import FWOLogger +from model_controllers.fwconfigmanagerlist_controller import ( + FwConfigManagerListController, +) +from models.fwconfig_normalized import FwConfigNormalized +from models.import_state import ImportState +from models.rulebase import Rulebase + +if TYPE_CHECKING: + from models.networkobject import NetworkObject + from models.rule import RuleNormalized + from models.rulebase_link import RulebaseLinkUidBased + + +class FwConfigImportCheckConsistency: + issues: dict[str, Any] + import_state: ImportState + + def __init__(self, import_state: ImportState): + self.import_state = import_state + self.issues = {} + self.network_objects_to_remove: list[str] = [] + self.service_objects_to_remove: list[str] = [] + self.user_objects_to_remove: list[str] = [] + self.rules_to_remove: list[str] = [] + self.invalid_rulebase_links_exist: bool = False + + # pre-flight checks + def check_fwconfig_managerlist_consistency(self, config: FwConfigManagerListController): + """ + Check the consistency of all given normalized configs of the given manager list. + If inconsistencies are found, an exception is raised. + + Args: + config (FwConfigManagerListController): The configurations to check. + + Raises: + FwoImporterErrorInconsistenciesError: If inconsistencies are found in the configurations + + """ + global_config: FwConfigNormalized | None = None + for mgr in sorted(config.ManagerSet, key=lambda m: not getattr(m, "IsSuperManager", False)): + if len(mgr.configs) == 0: + continue + if len(mgr.configs) > 1: + raise FwoImporterErrorInconsistenciesError( + f"Manager {mgr.manager_uid} has more than one config, which is currently not supported." + ) + if mgr.is_super_manager: + global_config = mgr.configs[0] + self.check_config_consistency(mgr.configs[0], global_config, fix_config=False) + + def check_config_consistency( + self, config: FwConfigNormalized, global_config: FwConfigNormalized | None, fix_config: bool + ): + """ + Check the consistency of a given normalized config and corresponding global normalized config. + If inconsistencies are found, an exception is raised. + When fix_config is set to True, the given configs will be modified to fix certain inconsistencies, namely + unresolvable references in groups (network/service/user), rules (containing network/service/user/zone refs), + and rulebase links (containing rulebase/rule refs). + + All objects (network/service/user/rules/rulebase links) containing unresolvable references will be removed from the config. + Any corresponding corrupt entries in the database are expected to be removed later, according to collected + - network_objects_to_remove + - service_objects_to_remove + - user_objects_to_remove + - rules_to_remove + - invalid_rulebase_links_exist + + Args: + config (FwConfigNormalized): The configuration to check. + global_config (FwConfigNormalized | None): The corresponding global configuration to check. + fix_config (bool): Whether to attempt to fix inconsistencies. + + Raises: + FwoImporterErrorInconsistenciesError: If inconsistencies are found in the configurations + + """ + self.check_color_consistency(config, fix=True) + self.check_network_object_consistency(config, global_config, fix_unresolvable_refs=fix_config) + self.check_service_object_consistency(config, global_config, fix_inconsistencies=fix_config) + self.check_user_object_consistency(config, global_config, fix_unresolvable_refs=fix_config) + self.check_zone_object_consistency(config, global_config, fix_unresolvable_refs=fix_config) + self.check_time_object_consistency(config, global_config) + self.check_rulebase_consistency(config, fix_inconsistencies=fix_config) + self.check_gateway_consistency(config) + self.check_rulebase_link_consistency(config, global_config, fix_inconsistencies=fix_config) + + if self.issues: + raise FwoImporterErrorInconsistenciesError( + "Inconsistencies found in the configuration: " + str(self.issues) + ) + + FWOLogger.debug("Consistency check completed without issues remaining.") + + def check_network_object_consistency( + self, config: FwConfigNormalized, global_config: FwConfigNormalized | None, fix_unresolvable_refs: bool + ): + # add all new obj refs from all rules + all_used_obj_refs: list[str] = [] + for rb in config.rulebases: + all_used_obj_refs += self._collect_all_used_objects_from_rules(rb) + + all_used_obj_refs += self._collect_all_used_objects_from_groups(config) + + all_network_object_uids = set(config.network_objects.keys()) + if global_config is not None: + all_network_object_uids |= set(global_config.network_objects.keys()) + + # now make list unique and get all refs not contained in network_objects + unresolvable_nw_obj_refs = set(all_used_obj_refs) - all_network_object_uids + + if unresolvable_nw_obj_refs: + if fix_unresolvable_refs: + self.remove_nwobj_refs_from_config(config, unresolvable_nw_obj_refs) + else: + self.issues.update({"unresolvableNwObjRefs": list(unresolvable_nw_obj_refs)}) + + self._check_network_object_types_exist(config) + self._check_objects_with_missing_ips(config) + self._check_network_object_circular_references(config) + + def _check_service_object_circular_references(self, config: FwConfigNormalized): + """ + Check for circular references in service object groups. + + :param self: FwConfigImportCheckConsistency instance + :param config: FwConfigNormalized instance + :type config: FwConfigNormalized + """ + self._find_cycles( + objects=config.service_objects, + # Object access needs .attr + is_group_fn=lambda x: getattr(x, "svc_typ", "") == "group", + get_members_fn=lambda x: getattr(x, "svc_member_refs", ""), + issue_key="circularSvcObjRefs", + ) + + def _check_network_object_circular_references(self, config: FwConfigNormalized): + """ + Check for circular references in network object groups. + + :param self: FwConfigImportCheckConsistency instance + :param config: FwConfigNormalized instance + :type config: FwConfigNormalized + """ + self._find_cycles( + objects=config.network_objects, + # Object access needs .attr + is_group_fn=lambda x: getattr(x, "obj_typ", "") == "group", + get_members_fn=lambda x: getattr(x, "obj_member_refs", ""), + issue_key="circularNwObjRefs", + ) + + def _check_network_object_types_exist(self, config: FwConfigNormalized): + all_used_obj_types: set[str] = set() + + for obj_id in config.network_objects: + all_used_obj_types.add(config.network_objects[obj_id].obj_typ) + missing_nw_obj_types = all_used_obj_types - self.import_state.network_obj_type_map.keys() + + if missing_nw_obj_types: + self.issues.update({"unresolvableNwObjTypes": list(missing_nw_obj_types)}) + + def _collect_all_used_objects_from_groups( + self, + single_config: FwConfigNormalized, + ) -> list[str]: + all_used_obj_refs: list[str] = [] + # add all nw obj refs from groups + for obj_id in single_config.network_objects: + if single_config.network_objects[obj_id].obj_typ == "group": + obj_member_refs = single_config.network_objects[obj_id].obj_member_refs + if obj_member_refs: + all_used_obj_refs += obj_member_refs.split(fwo_const.LIST_DELIMITER) + return all_used_obj_refs + + def _collect_all_used_objects_from_rules(self, rb: Rulebase) -> list[str]: + all_used_obj_refs: list[str] = [] + for rule_uid in rb.rules: + all_used_obj_refs += rb.rules[rule_uid].rule_src_refs.split(fwo_const.LIST_DELIMITER) + all_used_obj_refs += rb.rules[rule_uid].rule_dst_refs.split(fwo_const.LIST_DELIMITER) + + return all_used_obj_refs + + def _check_objects_with_missing_ips(self, config: FwConfigNormalized): + # check if there are any objects with obj_typ<>group and empty ip addresses (breaking constraint) + non_group_nw_obj_with_missing_ips: list[NetworkObject] = [] + for obj_id in config.network_objects: + if config.network_objects[obj_id].obj_typ != "group": + ip1 = config.network_objects[obj_id].obj_ip + ip2 = config.network_objects[obj_id].obj_ip_end + if ip1 is None or ip2 is None: + non_group_nw_obj_with_missing_ips.append(config.network_objects[obj_id]) + if non_group_nw_obj_with_missing_ips: + self.issues.update( + {"non-group network object with undefined IP addresse(s)": list(non_group_nw_obj_with_missing_ips)} + ) + + def check_service_object_consistency( + self, config: FwConfigNormalized, global_config: FwConfigNormalized | None, fix_inconsistencies: bool + ): + # check if all uid refs are valid + all_used_obj_refs: set[str] = set() + all_used_obj_refs |= self._collect_service_object_refs_from_rules(config) + all_used_obj_refs |= self._collect_all_service_object_refs_from_groups(config) + self._check_service_object_types_exist(config) + + # get all refs not contained in service_objects + all_service_object_uids = set(config.service_objects.keys()) + if global_config is not None: + all_service_object_uids |= set(global_config.service_objects.keys()) + + unresolvable_obj_refs = all_used_obj_refs - all_service_object_uids + + if unresolvable_obj_refs: + if fix_inconsistencies: + self.remove_svcobj_refs_from_config(config, unresolvable_obj_refs) + else: + self.issues.update({"unresolvableSvcObjRefs": list(unresolvable_obj_refs)}) + + self._check_service_object_circular_references(config) + + def _check_service_object_types_exist(self, config: FwConfigNormalized): + # check that all obj_typ exist + all_used_obj_types: set[str] = set() + for obj_id in config.service_objects: + all_used_obj_types.add(config.service_objects[obj_id].svc_typ) + missing_obj_types = all_used_obj_types - self.import_state.service_obj_type_map.keys() + if missing_obj_types: + self.issues.update({"unresolvableSvcObjTypes": list(missing_obj_types)}) + + def _collect_all_service_object_refs_from_groups( + self, + single_config: FwConfigNormalized, + ) -> set[str]: + all_used_obj_refs: set[str] = set() + for obj_id in single_config.service_objects: + if ( + single_config.service_objects[obj_id].svc_typ == "group" + and single_config.service_objects[obj_id].svc_member_refs is not None + ): + member_refs = single_config.service_objects[obj_id].svc_member_refs + if not member_refs: + continue + all_used_obj_refs |= set(member_refs.split(fwo_const.LIST_DELIMITER)) + return all_used_obj_refs + + def _collect_service_object_refs_from_rules( + self, + single_config: FwConfigNormalized, + ) -> set[str]: + all_used_obj_refs: set[str] = set() + for rb in single_config.rulebases: + for rule_uid in rb.rules: + all_used_obj_refs |= set(rb.rules[rule_uid].rule_svc_refs.split(fwo_const.LIST_DELIMITER)) + return all_used_obj_refs + + def check_user_object_consistency( + self, config: FwConfigNormalized, global_config: FwConfigNormalized | None, fix_unresolvable_refs: bool + ): + all_used_obj_refs: set[str] = set() + # add all user refs from all rules + all_used_obj_refs |= self._collect_users_from_rules(config) + all_used_obj_refs |= self._collect_users_from_groups(config) + self._check_user_types_exist(config) + + all_user_object_uids = set(config.users.keys()) + if global_config is not None: + all_user_object_uids |= set(global_config.users.keys()) + + # now make list unique and get all refs not contained in users + unresolvable_obj_refs = set(all_used_obj_refs) - all_user_object_uids + + if unresolvable_obj_refs: + if fix_unresolvable_refs: + self.remove_userobj_refs_from_config(config, unresolvable_obj_refs) + else: + self.issues.update({"unresolvableUserObjRefs": list(unresolvable_obj_refs)}) + + self._check_user_object_circular_references(config) + + def _check_user_object_circular_references(self, config: FwConfigNormalized): + """ + Check for circular references in user object groups. + + :param self: FwConfigImportCheckConsistency instance + :param config: FwConfigNormalized instance + :type config: FwConfigNormalized + """ + self._find_cycles( + objects=config.users, + is_group_fn=lambda x: x.get("user_typ") == "group", + get_members_fn=lambda x: x.get("user_member_refs", ""), + issue_key="circularUserObjRefs", + ) + + def _collect_users_from_rules(self, single_config: FwConfigNormalized) -> set[str]: + all_used_obj_refs: set[str] = set() + for rb in single_config.rulebases: + for rule_uid in rb.rules: + if fwo_const.USER_DELIMITER in rb.rules[rule_uid].rule_src_refs: + all_used_obj_refs |= set( + self._collect_users_from_refs(rb.rules[rule_uid].rule_src_refs.split(fwo_const.LIST_DELIMITER)) + ) + all_used_obj_refs |= set( + self._collect_users_from_refs(rb.rules[rule_uid].rule_dst_refs.split(fwo_const.LIST_DELIMITER)) + ) + return all_used_obj_refs + + def _collect_users_from_refs(self, nw_refs: list[str]) -> list[str]: + user_refs: list[str] = [] + for ref in nw_refs: + split_result = ref.split(fwo_const.USER_DELIMITER) + if len(split_result) == 2: # noqa: PLR2004 + user_refs.append(split_result[0]) + return user_refs + + def _collect_users_from_groups(self, config: FwConfigNormalized) -> set[str]: + all_used_obj_refs: set[str] = set() + for obj_id in config.users: + if config.users[obj_id]["user_typ"] == "group" and config.users[obj_id]["user_member_refs"] is not None: + member_refs = config.users[obj_id]["user_member_refs"] + if not member_refs: + continue + all_used_obj_refs |= set(member_refs.split(fwo_const.LIST_DELIMITER)) + return all_used_obj_refs + + def _check_user_types_exist(self, single_config: FwConfigNormalized): + # check that all obj_typ exist + all_used_obj_types: set[str] = set() + for obj_id in single_config.users: + all_used_obj_types.add(single_config.users[obj_id]["user_typ"]) # make list unique + missing_obj_types = all_used_obj_types - self.import_state.user_obj_type_map.keys() + if missing_obj_types: + self.issues.update({"unresolvableUserObjTypes": list(missing_obj_types)}) + + def check_zone_object_consistency( + self, config: FwConfigNormalized, global_config: FwConfigNormalized | None, fix_unresolvable_refs: bool + ): + all_used_obj_refs: set[str] = set() + all_used_obj_refs |= self._collect_zone_refs_from_rules(config) + + all_zone_object_uids = set(config.zone_objects.keys()) + if global_config is not None: + all_zone_object_uids |= set(global_config.zone_objects.keys()) + + # get all refs not contained in zone_objects + unresolvable_object_refs = all_used_obj_refs - all_zone_object_uids + if unresolvable_object_refs: + if fix_unresolvable_refs: + self.remove_zoneobj_refs_from_config(config, unresolvable_object_refs) + else: + self.issues.update({"unresolvableZoneObjRefs": list(unresolvable_object_refs)}) + + def _collect_zone_refs_from_rules(self, single_config: FwConfigNormalized) -> set[str]: + all_used_zones_refs: set[str] = set() + for rb in single_config.rulebases: + for rule_uid in rb.rules: + rule = rb.rules[rule_uid] + if rule.rule_src_zone is not None: + all_used_zones_refs.update(rule.rule_src_zone.split(fwo_const.LIST_DELIMITER)) + if rule.rule_dst_zone is not None: + all_used_zones_refs.update(rule.rule_dst_zone.split(fwo_const.LIST_DELIMITER)) + return all_used_zones_refs + + def check_time_object_consistency(self, config: FwConfigNormalized, global_config: FwConfigNormalized | None): + all_used_obj_refs = { + time_obj_uid + for rb in config.rulebases + for rule in rb.rules.values() + if rule.rule_time is not None + for time_obj_uid in rule.rule_time.split(fwo_const.LIST_DELIMITER) + } + all_time_object_uids = set(config.time_objects.keys()) + if global_config is not None: + all_time_object_uids |= set(global_config.time_objects.keys()) + unresolvable_object_refs = all_used_obj_refs - all_time_object_uids + if unresolvable_object_refs: + self.issues.update({"unresolvableTimeObjRefs": list(unresolvable_object_refs)}) + + # check if all color refs are valid (in the DB) + # fix=True means that missing color refs will be replaced by the default color (black) + def check_color_consistency(self, config: FwConfigNormalized, fix: bool): + """ + Check that all color refs used in the config are resolvable + + Args: + config (FwConfigNormalized): The configuration to check. + fix (bool): Fix unresolvable color references by replacing them with the default color. + + """ + ( + all_used_nw_obj_color_ref_set, + all_used_svc_color_ref_set, + all_used_user_color_ref_set, + ) = self._collect_all_used_colors(config) + + ( + unresolvable_nw_obj_colors, + unresolvable_svc_colors, + unresolvable_user_colors, + ) = self._check_resolvability_of_used_colors( + all_used_nw_obj_color_ref_set, + all_used_svc_color_ref_set, + all_used_user_color_ref_set, + ) + + if fix: + self._fix_colors( + config, + unresolvable_nw_obj_colors, + unresolvable_svc_colors, + unresolvable_user_colors, + ) + elif unresolvable_nw_obj_colors or unresolvable_svc_colors or unresolvable_user_colors: + self.issues.update( + { + "unresolvableColorRefs": { + "nwObjColors": unresolvable_nw_obj_colors, + "svcColors": unresolvable_svc_colors, + "userColors": unresolvable_user_colors, + } + } + ) + + def _collect_all_used_colors(self, single_config: FwConfigNormalized): + all_used_nw_obj_color_ref_set: set[str] = set() + all_used_svc_color_ref_set: set[str] = set() + all_used_user_color_ref_set: set[str] = set() + + for uid in single_config.network_objects: + if single_config.network_objects[uid].obj_color is not None: # type: ignore #TODO: obj_color cant be None # noqa: PGH003 + all_used_nw_obj_color_ref_set.add(single_config.network_objects[uid].obj_color) + for uid in single_config.service_objects: + if single_config.service_objects[uid].svc_color is not None: # type: ignore #TODO: svc_color cant be None # noqa: PGH003 + all_used_svc_color_ref_set.add(single_config.service_objects[uid].svc_color) + for uid in single_config.users: + if single_config.users[uid]["user_color"] is not None: + all_used_user_color_ref_set.add(single_config.users[uid]["user_color"]) + + return ( + all_used_nw_obj_color_ref_set, + all_used_svc_color_ref_set, + all_used_user_color_ref_set, + ) + + def _check_resolvability_of_used_colors( + self, + all_used_nw_obj_color_ref_set: set[str], + all_used_svc_color_ref_set: set[str], + all_used_user_color_ref_set: set[str], + ): + unresolvable_nw_obj_colors: list[str] = [] + unresolvable_svc_colors: list[str] = [] + unresolvable_user_colors: list[str] = [] + # check all nwobj color refs + for color_string in all_used_nw_obj_color_ref_set: + color_id = self.import_state.lookup_color_id_unresolved(color_string) + if color_id is None: # type: ignore # TODO: lookupColorId cant return None # noqa: PGH003 + unresolvable_nw_obj_colors.append(color_string) + + # check all nwobj color refs + for color_string in all_used_svc_color_ref_set: + color_id = self.import_state.lookup_color_id_unresolved(color_string) + if color_id is None: # type: ignore # TODO: lookupColorId cant return None # noqa: PGH003 + unresolvable_svc_colors.append(color_string) + + # check all user color refs + for color_string in all_used_user_color_ref_set: + color_id = self.import_state.lookup_color_id_unresolved(color_string) + if color_id is None: # type: ignore # TODO: lookupColorId cant return None # noqa: PGH003 + unresolvable_user_colors.append(color_string) + + return ( + unresolvable_nw_obj_colors, + unresolvable_svc_colors, + unresolvable_user_colors, + ) + + def _fix_colors( + self, + config: FwConfigNormalized, + unresolvable_nw_obj_colors: list[str], + unresolvable_svc_colors: list[str], + unresolvable_user_colors: list[str], + ): + # Replace unresolvable network object colors + for obj in config.network_objects.values(): + if obj.obj_color in unresolvable_nw_obj_colors: + obj.obj_color = fwo_const.DEFAULT_COLOR + # Replace unresolvable service object colors + for obj in config.service_objects.values(): + if obj.svc_color in unresolvable_svc_colors: + obj.svc_color = fwo_const.DEFAULT_COLOR + # Replace unresolvable user object colors + for obj in config.users.values(): + if obj["user_color"] in unresolvable_user_colors: + obj["user_color"] = fwo_const.DEFAULT_COLOR + + def _extract_rule_track_n_action_refs( + self, + rulebases: list[Rulebase], + ) -> tuple[set[str], set[str]]: + track_refs: set[str] = set() + action_refs: set[str] = set() + for rb in rulebases: + track_refs.update(rule.rule_track for rule in rb.rules.values()) + action_refs.update(rule.rule_action for rule in rb.rules.values()) + return track_refs, action_refs + + def _check_rule_consistency(self, rulebases: list[Rulebase]) -> tuple[int, list[str], list[str]]: + """ + Check rules for missing UIDs, duplicate UIDs, and empty source or destination fields. + """ + seen_rule_uids: set[str] = set() + rules_missing_uid = 0 + duplicate_rule_uids: list[str] = [] + rules_with_empty_src_or_dst: list[str] = [] + for rb in rulebases: + for rule in rb.rules.values(): + if rule.rule_uid is None: + rules_missing_uid += 1 + continue + if rule.rule_uid in seen_rule_uids: + duplicate_rule_uids.append(rule.rule_uid) + seen_rule_uids.add(rule.rule_uid) + if rule.rule_src == "" or rule.rule_dst == "": + rules_with_empty_src_or_dst.append(rule.rule_uid) + return rules_missing_uid, duplicate_rule_uids, rules_with_empty_src_or_dst + + def check_rulebase_consistency(self, config: FwConfigNormalized, fix_inconsistencies: bool): + all_used_track_refs, all_used_action_refs = self._extract_rule_track_n_action_refs(config.rulebases) + + unresolvable_tracks = all_used_track_refs - self.import_state.tracks.keys() + if unresolvable_tracks: + self.issues.update({"unresolvableRuleTracks": list(unresolvable_tracks)}) + + unresolvable_actions = all_used_action_refs - self.import_state.actions.keys() + if unresolvable_actions: + self.issues.update({"unresolvableRuleActions": list(unresolvable_actions)}) + + ( + rules_missing_uid, + duplicate_rule_uids, + rules_with_empty_src_or_dst, + ) = self._check_rule_consistency(config.rulebases) + + # rules missing uid are serious enough to always raise an issue + if rules_missing_uid > 0: + self.issues.update({"rulesMissingUidCount": rules_missing_uid}) + + if fix_inconsistencies: + self.fix_rulebase_inconsistencies( + config, + set(duplicate_rule_uids + rules_with_empty_src_or_dst), + ) + return + + if duplicate_rule_uids: + self.issues.update({"duplicateRuleUids": duplicate_rule_uids}) + if rules_with_empty_src_or_dst: + self.issues.update({"rulesWithEmptySrcOrDst": rules_with_empty_src_or_dst}) + + # e.g. check routing, interfaces refs + def check_gateway_consistency(self, config: FwConfigNormalized): + # TODO: implement + pass + + def check_rulebase_link_consistency( + self, config: FwConfigNormalized, global_config: FwConfigNormalized | None, fix_inconsistencies: bool = False + ): + unresolvable_rulebases: set[str] = set() + unresolvable_rules: set[str] = set() + + all_rulebase_uids, all_rule_uids = self.get_all_refs_from_rb_links(config, global_config) + + rb_links_with_gw_uid = ((rb_link, gw.Uid) for gw in config.gateways for rb_link in gw.RulebaseLinks) + + for rulebase_link, gw_uid in rb_links_with_gw_uid: + if rulebase_link.from_rulebase_uid and rulebase_link.from_rulebase_uid not in all_rulebase_uids: + unresolvable_rulebases.add(f"'{rulebase_link.from_rulebase_uid}' in gw '{gw_uid}'") + if rulebase_link.to_rulebase_uid not in all_rulebase_uids: + unresolvable_rulebases.add(f"'{rulebase_link.to_rulebase_uid}' in gw '{gw_uid}'") + if rulebase_link.from_rule_uid and rulebase_link.from_rule_uid not in all_rule_uids: + unresolvable_rules.add(f"'{rulebase_link.from_rule_uid}' in gw '{gw_uid}'") + + if fix_inconsistencies and (unresolvable_rulebases or unresolvable_rules): + self.fix_rulebase_link_inconsistencies(config, all_rulebase_uids, all_rule_uids) + return + + if unresolvable_rulebases: + self.issues.update({"unresolvableRulebaseLinksRulebases": list(unresolvable_rulebases)}) + if unresolvable_rules: + self.issues.update({"unresolvableRulebaseLinksRules": list(unresolvable_rules)}) + + def get_all_refs_from_rb_links( + self, config: FwConfigNormalized, global_config: FwConfigNormalized | None + ) -> tuple[set[str], set[str]]: + all_rulebase_uids: set[str] = set() + all_rule_uids: set[str] = set() + for rb in config.rulebases: + all_rulebase_uids.add(rb.uid) + for rule_uid in rb.rules: + all_rule_uids.add(rule_uid) + if global_config is not None: + for rb in global_config.rulebases: + all_rulebase_uids.add(rb.uid) + for rule_uid in rb.rules: + all_rule_uids.add(rule_uid) + return all_rulebase_uids, all_rule_uids + + def _cascade_remove_nwobj_groups(self, config: FwConfigNormalized, unresolvable_nw_obj_refs: set[str]): + """ + Iteratively remove network group objects that reference unresolvable objects. + Groups referencing removed groups are also removed (cascade effect). + Extends the unresolvable_nw_obj_refs set with newly found unresolvable group object UIDs. + """ + while True: + newly_unresolvable: set[str] = set() + for obj_uid, nw_obj in config.network_objects.items(): + if obj_uid in unresolvable_nw_obj_refs: + continue + if nw_obj.obj_member_refs is not None: + member_refs = set(nw_obj.obj_member_refs.split(fwo_const.LIST_DELIMITER)) + if member_refs & unresolvable_nw_obj_refs: + newly_unresolvable.add(obj_uid) + if not newly_unresolvable: + break + unresolvable_nw_obj_refs |= newly_unresolvable + self.network_objects_to_remove.extend(newly_unresolvable) + + config.network_objects = { + obj_uid: nw_obj + for obj_uid, nw_obj in config.network_objects.items() + if obj_uid not in unresolvable_nw_obj_refs + } + + def remove_nwobj_refs_from_config(self, config: FwConfigNormalized, unresolvable_nw_obj_refs: set[str]): + """ + Remove rules and network group objects containing unresolvable network object references from the given config. + + Args: + config (FwConfigNormalized): The configuration to modify. + unresolvable_nw_obj_refs (set[str]): Set of unresolvable network object references to remove. + + """ + self._cascade_remove_nwobj_groups(config, unresolvable_nw_obj_refs) + + # remove rules containing unresolvable nw obj refs + for rb in config.rulebases: + filtered_rules: dict[str, RuleNormalized] = {} + for rule_uid, rule in rb.rules.items(): + src_refs = set(rule.rule_src_refs.split(fwo_const.LIST_DELIMITER)) + dst_refs = set(rule.rule_dst_refs.split(fwo_const.LIST_DELIMITER)) + if src_refs & unresolvable_nw_obj_refs or dst_refs & unresolvable_nw_obj_refs: + self.rules_to_remove.append(rule_uid) + else: + filtered_rules[rule_uid] = rule + rb.rules = filtered_rules + + def _cascade_remove_svcobj_groups(self, config: FwConfigNormalized, unresolvable_svc_obj_refs: set[str]): + """ + Iteratively remove service group objects that reference unresolvable objects. + Groups referencing removed groups are also removed (cascade effect). + Extends the unresolvable_svc_obj_refs set with newly found unresolvable group object UIDs. + """ + while True: + newly_unresolvable: set[str] = set() + for obj_uid, svc_obj in config.service_objects.items(): + if obj_uid in unresolvable_svc_obj_refs: + continue + if svc_obj.svc_member_refs is not None: + member_refs = set(svc_obj.svc_member_refs.split(fwo_const.LIST_DELIMITER)) + if member_refs & unresolvable_svc_obj_refs: + newly_unresolvable.add(obj_uid) + if not newly_unresolvable: + break + unresolvable_svc_obj_refs |= newly_unresolvable + self.service_objects_to_remove.extend(newly_unresolvable) + + config.service_objects = { + obj_uid: svc_obj + for obj_uid, svc_obj in config.service_objects.items() + if obj_uid not in unresolvable_svc_obj_refs + } + + def remove_svcobj_refs_from_config(self, config: FwConfigNormalized, unresolvable_svc_obj_refs: set[str]): + """ + Remove rules and service group objects containing unresolvable service object references from the given config. + + Args: + config (FwConfigNormalized): The configuration to modify. + unresolvable_svc_obj_refs (set[str]): Set of unresolvable service object references to remove. + + """ + self._cascade_remove_svcobj_groups(config, unresolvable_svc_obj_refs) + + # remove rules containing unresolvable svc obj refs + for rb in config.rulebases: + filtered_rules: dict[str, RuleNormalized] = {} + for rule_uid, rule in rb.rules.items(): + svc_refs = set(rule.rule_svc_refs.split(fwo_const.LIST_DELIMITER)) + if svc_refs & unresolvable_svc_obj_refs: + self.rules_to_remove.append(rule_uid) + else: + filtered_rules[rule_uid] = rule + rb.rules = filtered_rules + + def _cascade_remove_userobj_groups(self, config: FwConfigNormalized, unresolvable_user_obj_refs: set[str]): + """ + Iteratively remove user group objects that reference unresolvable objects. + Groups referencing removed groups are also removed (cascade effect). + Extends the unresolvable_user_obj_refs set with newly found unresolvable group object UIDs. + """ + while True: + newly_unresolvable: set[str] = set() + for obj_uid, user_obj in config.users.items(): + if obj_uid in unresolvable_user_obj_refs: + continue + if user_obj["user_member_refs"] is not None: + member_refs = set(user_obj["user_member_refs"].split(fwo_const.LIST_DELIMITER)) + if member_refs & unresolvable_user_obj_refs: + newly_unresolvable.add(obj_uid) + if not newly_unresolvable: + break + unresolvable_user_obj_refs |= newly_unresolvable + self.user_objects_to_remove.extend(newly_unresolvable) + + config.users = { + obj_uid: user_obj for obj_uid, user_obj in config.users.items() if obj_uid not in unresolvable_user_obj_refs + } + + def remove_userobj_refs_from_config(self, config: FwConfigNormalized, unresolvable_user_obj_refs: set[str]): + """ + Remove rules and user group objects containing unresolvable user object references from the given config. + + Args: + config (FwConfigNormalized): The configuration to modify. + unresolvable_user_obj_refs (set[str]): Set of unresolvable user object references to remove. + + """ + self._cascade_remove_userobj_groups(config, unresolvable_user_obj_refs) + + # remove rules containing unresolvable user obj refs + for rb in config.rulebases: + filtered_rules: dict[str, RuleNormalized] = {} + for rule_uid, rule in rb.rules.items(): + src_refs = rule.rule_src_refs.split(fwo_const.LIST_DELIMITER) + dst_refs = rule.rule_dst_refs.split(fwo_const.LIST_DELIMITER) + src_user_refs = self._collect_users_from_refs(src_refs) + dst_user_refs = self._collect_users_from_refs(dst_refs) + if set(src_user_refs) & unresolvable_user_obj_refs or set(dst_user_refs) & unresolvable_user_obj_refs: + self.rules_to_remove.append(rule_uid) + else: + filtered_rules[rule_uid] = rule + rb.rules = filtered_rules + + def remove_zoneobj_refs_from_config(self, config: FwConfigNormalized, unresolvable_zone_obj_refs: set[str]): + """ + Remove rules containing unresolvable zone object references from the given config. + + Args: + config (FwConfigNormalized): The configuration to modify. + unresolvable_zone_obj_refs (set[str]): Set of unresolvable zone object references to remove. + + """ + # remove rules containing unresolvable zone obj refs + for rb in config.rulebases: + filtered_rules: dict[str, RuleNormalized] = {} + for rule_uid, rule in rb.rules.items(): + src_zone_refs: set[str] = set() + dst_zone_refs: set[str] = set() + if rule.rule_src_zone is not None: + src_zone_refs = set(rule.rule_src_zone.split(fwo_const.LIST_DELIMITER)) + if rule.rule_dst_zone is not None: + dst_zone_refs = set(rule.rule_dst_zone.split(fwo_const.LIST_DELIMITER)) + if src_zone_refs & unresolvable_zone_obj_refs or dst_zone_refs & unresolvable_zone_obj_refs: + self.rules_to_remove.append(rule_uid) + else: + filtered_rules[rule_uid] = rule + rb.rules = filtered_rules + + def fix_rulebase_inconsistencies(self, config: FwConfigNormalized, rule_uids_to_remove: set[str]): + """ + Remove rules with the given UIDs from all rulebases in the given config. + + Args: + config (FwConfigNormalized): The configuration to modify. + rule_uids_to_remove (set[str]): Set of rule UIDs to remove. + + """ + for rb in config.rulebases: + filtered_rules: dict[str, RuleNormalized] = {} + for rule_uid, rule in rb.rules.items(): + if rule_uid in rule_uids_to_remove: + self.rules_to_remove.append(rule_uid) + else: + filtered_rules[rule_uid] = rule + rb.rules = filtered_rules + + def fix_rulebase_link_inconsistencies( + self, config: FwConfigNormalized, all_rulebase_uids: set[str], all_rule_uids: set[str] + ): + """ + Remove rulebase links containing unresolvable references from the given config. + + Args: + config (FwConfigNormalized): The configuration to modify. + all_rulebase_uids (set[str]): Set of all rulebase UIDs. + all_rule_uids (set[str]): Set of all rule UIDs. + + """ + for gw in config.gateways: + filtered_rulebase_links: list[RulebaseLinkUidBased] = [] + for rulebase_link in gw.RulebaseLinks: + if ( + (rulebase_link.from_rulebase_uid and rulebase_link.from_rulebase_uid not in all_rulebase_uids) + or (rulebase_link.from_rule_uid and rulebase_link.from_rule_uid not in all_rule_uids) + or (rulebase_link.to_rulebase_uid not in all_rulebase_uids) + ): + self.invalid_rulebase_links_exist = True + else: + filtered_rulebase_links.append(rulebase_link) + gw.RulebaseLinks = filtered_rulebase_links + + def _detect_circular_reference( + self, all_groups: dict[str, Any], get_members_fn: Callable[[Any], str], current_group_id: str, path: set[str] + ) -> bool: + """ + Helper function to detect circular references using DFS. + + :param all_groups: Dictionary of all group objects + :param get_members_fn: Function to get member references from a group object + :param current_group_id: The current group ID being checked + :param path: Set of group IDs in the current DFS path + :return: True if a circular reference is detected, False otherwise + """ + if current_group_id in path: + return True # Circular reference detected + + path.add(current_group_id) + current_group = all_groups.get(current_group_id) + + raw_refs = get_members_fn(current_group) if current_group else None + + if raw_refs: + member_ids = raw_refs.split(fwo_const.LIST_DELIMITER) + for member_id in member_ids: + if member_id in all_groups and self._detect_circular_reference( + all_groups, get_members_fn, member_id, path + ): + return True + + path.remove(current_group_id) + return False + + def _find_cycles( + self, + objects: dict[str, Any], + is_group_fn: Callable[[Any], bool], + get_members_fn: Callable[[Any], str], + issue_key: str, + ): + """ + Generic DFS algorithm to detect circular references. + + :param objects: The dictionary of objects to scan (users, network_objects, etc.) + :param is_group_fn: A function returning True if the object is a group + :param get_members_fn: A function returning the raw member string (e.g. "id1|id2") + :param issue_key: The key to update in self.issues if cycles are found + """ + # 1. Filter only groups using the provided lambda + all_groups = {obj_id: obj for obj_id, obj in objects.items() if is_group_fn(obj)} + + visited: set[str] = set() + circular_references: set[str] = set() + + for group_id in all_groups: + if group_id not in visited: + if self._detect_circular_reference(all_groups, get_members_fn, group_id, set()): + circular_references.add(group_id) + visited.add(group_id) + + if circular_references: + self.issues.update({issue_key: list(circular_references)}) diff --git a/roles/importer/files/importer/model_controllers/fwconfig_import.py b/roles/importer/files/importer/model_controllers/fwconfig_import.py new file mode 100644 index 0000000000..76020f1530 --- /dev/null +++ b/roles/importer/files/importer/model_controllers/fwconfig_import.py @@ -0,0 +1,815 @@ +import traceback +from typing import Any + +import fwo_const +import fwo_globals +from fwo_api import FwoApi +from fwo_base import ConfigAction, find_all_diffs +from fwo_exceptions import FwoApiFailedDeleteOldImportsError, FwoImporterError, ImportInterruptionError +from fwo_log import FWOLogger +from model_controllers.check_consistency import FwConfigImportCheckConsistency +from model_controllers.fwconfig_import_gateway import FwConfigImportGateway +from model_controllers.fwconfig_import_object import FwConfigImportObject +from model_controllers.fwconfig_import_rule import FwConfigImportRule +from model_controllers.fwconfigmanagerlist_controller import FwConfigManagerListController +from model_controllers.import_state_controller import ImportStateController +from model_controllers.management_controller import ( + ConnectionInfo, + CredentialInfo, + DeviceInfo, + DomainInfo, + ManagementController, + ManagerInfo, +) +from models.fwconfig_normalized import FwConfigNormalized +from models.fwconfigmanagerlist import FwConfigManager +from services.global_state import GlobalState +from services.service_provider import ServiceProvider + + +# this class is used for importing a config into the FWO API +class FwConfigImport: + import_state: ImportStateController + normalized_config: FwConfigNormalized | None + + _fw_config_import_rule: FwConfigImportRule + _fw_config_import_object: FwConfigImportObject + _fw_config_import_gateway: FwConfigImportGateway + _global_state: GlobalState + + @property + def fwconfig_import_object(self): + return self._fw_config_import_object + + def __init__(self): + service_provider = ServiceProvider() + self._global_state = service_provider.get_global_state() + self.import_state = self._global_state.import_state + + self.normalized_config = self._global_state.normalized_config + + self._fw_config_import_object = FwConfigImportObject() + self._fw_config_import_rule = FwConfigImportRule() + self._fw_config_import_gateway = FwConfigImportGateway() + + def import_single_config(self, single_manager: FwConfigManager): + # current implementation restriction: assuming we always get the full config (only inserts) from API + mgm_id = self.import_state.state.lookup_management_id(single_manager.manager_uid) + if mgm_id is None: + raise FwoImporterError(f"could not find manager id in DB for UID {single_manager.manager_uid}") + previous_config = self.get_latest_config_from_db() + previous_global_config: FwConfigNormalized | None = None + self._global_state.previous_config = previous_config + if single_manager.is_super_manager: + self._global_state.previous_global_config = previous_config + else: + # only set global config for sub managers + previous_global_config = self._global_state.previous_global_config + + self.check_and_fix_db_consistency(previous_config, previous_global_config) + + # calculate differences and write them to the database via API + self.update_diffs(previous_config, previous_global_config, single_manager) + + def import_management_set(self, service_provider: ServiceProvider, mgr_set: FwConfigManagerListController): + for manager in sorted(mgr_set.ManagerSet, key=lambda m: not getattr(m, "IsSuperManager", False)): + """ + the following loop is a preparation for future functionality + we might add support for multiple configs per manager + e.g. one config only adds data, one only deletes data, etc. + currently we always only have one config per manager + """ + for config in manager.configs: + self.import_config(service_provider, manager, config) + self.update_removed_managers(mgr_set.ManagerSet) + + def import_config(self, service_provider: ServiceProvider, manager: FwConfigManager, config: FwConfigNormalized): + global_state = service_provider.get_global_state() + global_state.normalized_config = config + if manager.is_super_manager: + # store global config as it is needed when importing sub managers which might reference it + global_state.global_normalized_config = config + mgm_id = self.import_state.state.lookup_management_id(manager.manager_uid) + if mgm_id is None: + raise FwoImporterError(f"could not find manager id in DB for UID {manager.manager_uid}") + # TODO: clean separation between values relevant for all managers and those only relevant for specific managers - see #3646 + self.import_state.state.mgm_details.current_mgm_id = mgm_id + self.import_state.state.mgm_details.current_mgm_is_super_manager = manager.is_super_manager + config_importer = FwConfigImport() # TODO: strange to create another import object here - see #3154 + config_importer.import_single_config(manager) + config_importer.consistency_check_config_against_db() + config_importer.write_latest_config() + + def update_removed_managers(self, mgr_set: list[FwConfigManager]): + """ + Sets removed flag on all db entries associated with sub-managers which are not part of the current import set. + """ + if not self.import_state.state.mgm_details.is_super_manager: + return # nothing to do for single management imports + get_sub_mgrs_query = FwoApi.get_graphql_code( + [fwo_const.GRAPHQL_QUERY_PATH + "device/getSubManagerUids.graphql"] + ) + query_variables = {"mgmId": self.import_state.state.mgm_details.mgm_id} + try: + query_result = self.import_state.api_connection.call(get_sub_mgrs_query, query_variables=query_variables) + if "errors" in query_result: + raise FwoImporterError( + f"failed to get sub manager UIDs for super manager mgm id {self.import_state.state.mgm_details.mgm_id!s}: {query_result['errors']!s}" + ) + mgrs_in_db = query_result["data"]["management"] + except Exception: + FWOLogger.exception( + f"failed to get sub manager UIDs for super manager mgm id {self.import_state.state.mgm_details.mgm_id!s}: {traceback.format_exc()!s}" + ) + raise FwoImporterError("error while trying to get the sub manager UIDs") from None + mgr_uids_in_db = {mgr["mgm_uid"] for mgr in mgrs_in_db} + mgr_uids_in_import = {mgr.manager_uid for mgr in mgr_set} + mgr_uids_to_remove = list(mgr_uids_in_db - mgr_uids_in_import) + if not mgr_uids_to_remove: + return # nothing to do + FWOLogger.info(f"marking all entries associated with sub-managers {mgr_uids_to_remove!s} as removed") + mutation = FwoApi.get_graphql_code( + file_list=[fwo_const.GRAPHQL_QUERY_PATH + "device/markManagersRemoved.graphql"] + ) + query_variables: dict[str, Any] = { + "mgmIds": [mgr["mgm_id"] for mgr in mgrs_in_db if mgr["mgm_uid"] in mgr_uids_to_remove], + "importId": self.import_state.state.import_id, + } + try: + result = self.import_state.api_connection.call(mutation, query_variables=query_variables) + + affected_tables = {key: value["affected_rows"] for key, value in result["data"].items()} + FWOLogger.debug(f"marked sub-managers {mgr_uids_to_remove!s} as removed in tables: {affected_tables!s}") + FWOLogger.info( + f"marked {sum(affected_tables.values())!s} entries as removed for sub-managers {mgr_uids_to_remove!s}" + ) + self.import_state.state.stats.statistics.network_object_delete_count += affected_tables.get( + "update_object", 0 + ) + self.import_state.state.stats.statistics.service_object_delete_count += affected_tables.get( + "update_service", 0 + ) + self.import_state.state.stats.statistics.user_object_delete_count += affected_tables.get("update_usr", 0) + self.import_state.state.stats.statistics.zone_object_delete_count += affected_tables.get("update_zone", 0) + self.import_state.state.stats.statistics.rule_delete_count += affected_tables.get("update_rule", 0) + self.import_state.state.stats.statistics.rulebase_delete_count += affected_tables.get("update_rulebase", 0) + except Exception: + FWOLogger.exception( + f"failed to mark sub-managers as removed for super manager mgm id {self.import_state.state.mgm_details.mgm_id!s}: {traceback.format_exc()!s}" + ) + raise FwoImporterError("error while trying to mark sub-managers as removed") from None + + def clear_management(self) -> FwConfigManagerListController: + FWOLogger.info('this import run will reset the configuration of this management to "empty"') + config_normalized = FwConfigManagerListController() + mgm_details = self.import_state.state.mgm_details + # Reset management + config_normalized.add_manager( + manager=FwConfigManager( + manager_uid=mgm_details.uid, + manager_name=mgm_details.name, + is_super_manager=mgm_details.is_super_manager, + sub_manager_ids=mgm_details.sub_manager_ids, + domain_name=mgm_details.domain_name, + domain_uid=mgm_details.domain_uid, + configs=[], + ) + ) + if len(self.import_state.state.mgm_details.sub_manager_ids) > 0: + # Read config + fwo_api = self.import_state.api_connection + + # Reset submanagement + for sub_manager_id in self.import_state.state.mgm_details.sub_manager_ids: + # Fetch sub management details + mgm_controller = ManagementController( + mgm_id=int(sub_manager_id), + uid="", + devices=[], + device_info=DeviceInfo(), + connection_info=ConnectionInfo(), + importer_hostname="", + credential_info=CredentialInfo(), + manager_info=ManagerInfo(), + domain_info=DomainInfo(), + ) + mgm_details_raw = mgm_controller.get_mgm_details(fwo_api, sub_manager_id) + mgm_details = ManagementController.from_json(mgm_details_raw) + config_normalized.add_manager( + manager=FwConfigManager( + manager_uid=mgm_details.uid, + manager_name=mgm_details.name, + is_super_manager=mgm_details.is_super_manager, + sub_manager_ids=mgm_details.sub_manager_ids, + domain_name=mgm_details.domain_name, + domain_uid=mgm_details.domain_uid, + configs=[], + ) + ) + # Reset objects + for management in config_normalized.ManagerSet: + management.configs.append( + FwConfigNormalized( + action=ConfigAction.INSERT, + network_objects={}, + service_objects={}, + users={}, + zone_objects={}, + rulebases=[], + gateways=[], + ) + ) + self.import_state.state.is_clearing_import = True # the now following import is a full one + + return config_normalized + + def update_diffs( + self, + prev_config: FwConfigNormalized, + prev_global_config: FwConfigNormalized | None, + single_manager: FwConfigManager, + ): + self._fw_config_import_object.update_object_diffs(prev_config, prev_global_config, single_manager) + + if fwo_globals.shutdown_requested: + raise ImportInterruptionError("Shutdown requested during updateObjectDiffs.") + + self._fw_config_import_rule.update_rulebase_diffs(prev_config) + + if fwo_globals.shutdown_requested: + raise ImportInterruptionError("Shutdown requested during updateRulebaseDiffs.") + + self._fw_config_import_gateway.update_gateway_diffs() + + # cleanup configs which do not need to be retained according to data retention time + def delete_old_imports(self) -> None: + mgm_id = int(self.import_state.state.mgm_details.mgm_id) + delete_mutation = FwoApi.get_graphql_code([fwo_const.GRAPHQL_QUERY_PATH + "import/deleteOldImports.graphql"]) + + try: + delete_result = self.import_state.api_call.call( + delete_mutation, + query_variables={"mgmId": mgm_id}, + ) + if delete_result["data"]["delete_import_control"]["returning"]["control_id"]: + imports_deleted = len(delete_result["data"]["delete_import_control"]["returning"]["control_id"]) + if imports_deleted > 0: + FWOLogger.info( + f"deleted {imports_deleted!s} imports which passed the retention time of {self.import_state.state.data_retention_days} days" + ) + except Exception: + fwo_api_call = self.import_state.api_call + FWOLogger.error( + f"error while trying to delete old imports for mgm {self.import_state.state.mgm_details.mgm_id!s}" + ) + fwo_api_call.create_data_issue( + mgm_id=self.import_state.state.mgm_details.mgm_id, + severity=1, + description="failed to get import lock for management id " + str(mgm_id), + ) + fwo_api_call.set_alert( + import_id=self.import_state.state.import_id, + title="import error", + mgm_id=mgm_id, + severity=1, + description="fwo_api: failed to get import lock", + source="import", + alert_code=15, + mgm_details=self.import_state.state.mgm_details, + ) + raise FwoApiFailedDeleteOldImportsError(f"management id: {mgm_id}") from None + + def write_latest_config(self): + if self.import_state.state.import_version > 8: # noqa: PLR2004 + if self.normalized_config is None: + raise FwoImporterError("cannot write latest config: NormalizedConfig is None") + # convert FwConfigImport to FwConfigNormalized + self.normalized_config = FwConfigNormalized( + action=self.normalized_config.action, + network_objects=self.normalized_config.network_objects, + service_objects=self.normalized_config.service_objects, + users=self.normalized_config.users, + zone_objects=self.normalized_config.zone_objects, + rulebases=self.normalized_config.rulebases, + gateways=self.normalized_config.gateways, + ConfigFormat=self.normalized_config.ConfigFormat, + ) + + self.delete_latest_config_of_management() + insert_mutation = FwoApi.get_graphql_code( + [fwo_const.GRAPHQL_QUERY_PATH + "import/storeLatestConfig.graphql"] + ) + try: + query_variables: dict[str, Any] = { + "mgmId": self.import_state.state.mgm_details.current_mgm_id, + "importId": self.import_state.state.import_id, + "config": self.normalized_config.model_dump_json(), + } + import_result = self.import_state.api_call.call(insert_mutation, query_variables=query_variables) + if "errors" in import_result: + FWOLogger.exception( + "fwo_api:storeLatestConfig - error while writing importable config for mgm id " + + str(self.import_state.state.mgm_details.current_mgm_id) + + ": " + + str(import_result["errors"]) + ) + FWOLogger.warning( + f"error while writing latest config for import_id {self.import_state.state.import_id}, mgm_id: {self.import_state.state.mgm_details.mgm_id}, mgm_uid: {self.import_state.state.mgm_details.uid}" + ) + else: + _ = import_result["data"]["insert_latest_config"]["affected_rows"] + except Exception: + FWOLogger.exception( + f"failed to write latest normalized config for mgm id {self.import_state.state.mgm_details.current_mgm_id!s}: {traceback.format_exc()!s}" + ) + raise + + def delete_latest_config_of_management(self): + delete_mutation = FwoApi.get_graphql_code( + [fwo_const.GRAPHQL_QUERY_PATH + "import/deleteLatestConfigOfManagement.graphql"] + ) + try: + query_variables = {"mgmId": self.import_state.state.mgm_details.current_mgm_id} + import_result = self.import_state.api_call.call(delete_mutation, query_variables=query_variables) + if "errors" in import_result: + FWOLogger.exception( + "fwo_api:import_latest_config - error while deleting last config for mgm id " + + str(self.import_state.state.mgm_details.current_mgm_id) + + ": " + + str(import_result["errors"]) + ) + else: + _ = import_result["data"]["delete_latest_config"]["affected_rows"] + except Exception: + FWOLogger.exception( + f"failed to delete latest normalized config for mgm id {self.import_state.state.mgm_details.current_mgm_id!s}: {traceback.format_exc()!s}" + ) + + def get_latest_import_id(self) -> int | None: + query = FwoApi.get_graphql_code([fwo_const.GRAPHQL_QUERY_PATH + "import/getLastSuccessImport.graphql"]) + query_variables = {"mgmId": self.import_state.state.mgm_details.mgm_id} + try: + query_result = self.import_state.api_connection.call(query, query_variables=query_variables) + if "errors" in query_result: + raise FwoImporterError( + f"failed to get latest import id for mgm id {self.import_state.state.mgm_details.mgm_id!s}: {query_result['errors']!s}" + ) + if len(query_result["data"]["import_control"]) == 0: + return None + return query_result["data"]["import_control"][0]["control_id"] + except Exception: + FWOLogger.exception( + f"failed to get latest import id for mgm id {self.import_state.state.mgm_details.mgm_id!s}: {traceback.format_exc()!s}" + ) + raise FwoImporterError("error while trying to get the latest import id") + + # return previous config or empty config if there is none; only returns the config of a single management + def get_latest_config(self) -> FwConfigNormalized: + mgm_id = self.import_state.state.mgm_details.current_mgm_id + prev_config = FwConfigNormalized() + + latest_import_id = self.get_latest_import_id() + if latest_import_id is None: + FWOLogger.info(f"first import - no existing import was found for mgm id {mgm_id}") # TODO: change msg + return prev_config + + query = FwoApi.get_graphql_code([fwo_const.GRAPHQL_QUERY_PATH + "import/getLatestConfig.graphql"]) + query_variables = {"mgmId": mgm_id} + try: + query_result = self.import_state.api_connection.call(query, query_variables=query_variables) + if "errors" in query_result: + raise FwoImporterError( + f"failed to get latest config for mgm id {self.import_state.state.mgm_details.mgm_id!s}: {query_result['errors']!s}" + ) + if len(query_result["data"]["latest_config"]) > 0: # do we have a prev config? + if query_result["data"]["latest_config"][0]["import_id"] == latest_import_id: + return FwConfigNormalized.model_validate_json(query_result["data"]["latest_config"][0]["config"]) + FWOLogger.warning( + f"fwo_api:import_latest_config - latest config for mgm id {mgm_id} did not match last import id {latest_import_id}" + ) + FWOLogger.info("fetching latest config from DB as fallback") + return self.get_latest_config_from_db() + except Exception: + FWOLogger.exception( + f"failed to get latest normalized config for mgm id {self.import_state.state.mgm_details.current_mgm_id!s}: {traceback.format_exc()!s}" + ) + raise FwoImporterError("error while trying to get the previous config") + + def get_latest_config_from_db(self) -> FwConfigNormalized: + params = {"mgm-ids": [self.import_state.state.mgm_details.current_mgm_id]} + result = self.import_state.api_connection.call_endpoint("POST", "api/NormalizedConfig/Get", params=params) + try: + return FwConfigNormalized.model_validate(result) + except Exception: + FWOLogger.exception( + f"failed to get latest normalized config from db for mgm id {self.import_state.state.mgm_details.mgm_id!s}: {traceback.format_exc()!s}" + ) + raise FwoImporterError("error while trying to get the latest config") + + def _sort_lists(self, config: FwConfigNormalized): + # sort lists in config to have consistent ordering for diff checks + config.rulebases.sort(key=lambda rb: rb.uid) + if any(gw.Uid is None for gw in config.gateways): + raise FwoImporterError( + "found gateway without UID while sorting gateways for consistency check - this should not happen" + ) + config.gateways.sort(key=lambda gw: gw.Uid or "") + for gw in config.gateways: + gw.RulebaseLinks.sort(key=lambda rbl: f"{rbl.from_rulebase_uid}-{rbl.from_rule_uid}-{rbl.to_rulebase_uid}") + if gw.EnforcedPolicyUids is not None: + gw.EnforcedPolicyUids.sort() + if gw.EnforcedNatPolicyUids is not None: + gw.EnforcedNatPolicyUids.sort() + # TODO: interfaces and routing as soon as they are implemented + + def consistency_check_config_against_db(self): + normalized_config = self.normalized_config + if normalized_config is None: + raise FwoImporterError("cannot perform consistency check: NormalizedConfig is None") + normalized_config_from_db = self.get_latest_config_from_db() + self._sort_lists(normalized_config) + self._sort_lists(normalized_config_from_db) + # filter gateways from DB which are not part of the current import (e.g. in case of import_disabled) + normalized_config_from_db.gateways = [ + gw + for gw in normalized_config_from_db.gateways + if any(gw.Uid == imported_gw.Uid for imported_gw in normalized_config.gateways) + ] + all_diffs = find_all_diffs(normalized_config.model_dump(), normalized_config_from_db.model_dump(), strict=True) + if len(all_diffs) > 0: + FWOLogger.warning( + f"normalized config for mgm id {self.import_state.state.mgm_details.current_mgm_id} is inconsistent to database state: {all_diffs[0]}" + ) + FWOLogger.debug(f"all {len(all_diffs)} differences:\n\t" + "\n\t".join(all_diffs)) + # TODO: long-term this should raise an error: + + def check_and_fix_db_consistency( + self, + previous_config: FwConfigNormalized, + previous_global_config: FwConfigNormalized | None, + ): + """ + Check consistency of the latest config (=previous config) built from database state before import. + If inconsistencies are found, they will be fixed in the database by marking objects/rules/links as removed. + """ + consistency_checker = FwConfigImportCheckConsistency(self.import_state.state) + consistency_checker.check_config_consistency(previous_config, previous_global_config, fix_config=True) + self.fix_objects_in_db( + consistency_checker.network_objects_to_remove, + consistency_checker.service_objects_to_remove, + consistency_checker.user_objects_to_remove, + ) + self.fix_rules_in_db(consistency_checker.rules_to_remove) + if consistency_checker.invalid_rulebase_links_exist: + self.fix_rulebase_links_in_db() + self.fix_rule_to_gw_refs_in_db(previous_config, previous_global_config) + self.fix_ref_tables_in_db() + self.fix_changelog_rule() + + def fix_objects_in_db(self, nwobj_uids: list[str], svcobj_uids: list[str], user_uids: list[str]): + """ + Sets removed flag on network objects, service objects and user objects with the given UIDs in the database + to fix consistency issues. + """ + if not nwobj_uids and not svcobj_uids and not user_uids: + return # nothing to do + + mutation = FwoApi.get_graphql_code( + file_list=[fwo_const.GRAPHQL_QUERY_PATH + "allObjects/upsertObjects.graphql"] + ) + + query_variables: dict[str, Any] = { + "mgmId": self.import_state.state.mgm_details.current_mgm_id, + "importId": self.import_state.state.import_id, + "newNwObjects": [], + "newSvcObjects": [], + "newUsers": [], + "newZones": [], + "removedNwObjectUids": nwobj_uids, + "removedSvcObjectUids": svcobj_uids, + "removedUserUids": user_uids, + "removedZoneUids": [], + } + + try: + result = self.import_state.api_call.call(mutation, query_variables=query_variables, analyze_payload=True) + + removed_nwobj_ids = result["data"]["update_object"]["returning"] + removed_nwsvc_ids = result["data"]["update_service"]["returning"] + removed_user_ids = result["data"]["update_usr"]["returning"] + FWOLogger.info( + f"removed {len(removed_nwobj_ids)!s} network objects, {len(removed_nwsvc_ids)!s} service objects and {len(removed_user_ids)!s} user objects from DB to fix consistency issues" + ) + self.import_state.state.stats.statistics.inconsistent_nwobj_delete_count += len(removed_nwobj_ids) + self.import_state.state.stats.statistics.inconsistent_svcobj_delete_count += len(removed_nwsvc_ids) + self.import_state.state.stats.statistics.inconsistent_userobj_delete_count += len(removed_user_ids) + except Exception: + FWOLogger.exception( + f"failed to fix object consistency issues for mgm id {self.import_state.state.mgm_details.current_mgm_id!s}: {traceback.format_exc()!s}" + ) + raise FwoImporterError("error while trying to fix object consistency issues") from None + + def fix_rules_in_db(self, rule_uids: list[str]): + """ + Sets removed flag on rules with the given UIDs in the database to fix consistency issues. + """ + if not rule_uids: + return # nothing to do + + mutation = """ + mutation markRulesRemoved($importId: bigint!, $mgmId: Int!, $uids: [String!]!) { + update_rule(where: {removed: { _is_null: true }, rule_uid: {_in: $uids}, mgm_id: {_eq: $mgmId}}, _set: {removed: $importId}) { + affected_rows + returning { rule_id } + } + } + """ + query_variables: dict[str, Any] = { + "mgmId": self.import_state.state.mgm_details.current_mgm_id, + "importId": self.import_state.state.import_id, + "uids": rule_uids, + } + try: + result = self.import_state.api_call.call(mutation, query_variables=query_variables, analyze_payload=True) + + removed_rule_ids = result["data"]["update_rule"]["returning"] + FWOLogger.info(f"marked {len(removed_rule_ids)!s} rules as removed in DB to fix consistency issues") + self.import_state.state.stats.statistics.inconsistent_rule_delete_count += len(removed_rule_ids) + except Exception: + FWOLogger.exception( + f"failed to fix rule consistency issues for mgm id {self.import_state.state.mgm_details.current_mgm_id!s}: {traceback.format_exc()!s}" + ) + raise FwoImporterError("error while trying to fix rule consistency issues") from None + + def fix_rulebase_links_in_db(self): + """ + Removes inconsistent rulebase links from the database to fix consistency issues. + """ + mutation = FwoApi.get_graphql_code( + file_list=[fwo_const.GRAPHQL_QUERY_PATH + "rule/removeInconsistentRulebaseLinks.graphql"] + ) + query_variables: dict[str, Any] = { + "mgmId": self.import_state.state.mgm_details.current_mgm_id, + "importId": self.import_state.state.import_id, + } + try: + result = self.import_state.api_call.call(mutation, query_variables=query_variables) + + removed_links = result["data"]["update_rulebase_link"]["affected_rows"] + FWOLogger.info(f"removed {removed_links!s} inconsistent rulebase links from DB to fix consistency issues") + self.import_state.state.stats.statistics.inconsistent_rulebase_link_delete_count += removed_links + except Exception: + FWOLogger.exception( + f"failed to remove inconsistent rulebase links for mgm id {self.import_state.state.mgm_details.current_mgm_id!s}: {traceback.format_exc()!s}" + ) + raise FwoImporterError("error while trying to remove inconsistent rulebase links") from None + + def _insert_missing_rule_to_gw_refs_in_db(self, refs_to_add: set[tuple[str, str]]): + """Inserts missing rule enforced on gateway references to the database to fix consistency issues.""" + if not refs_to_add: + return # nothing to do + mgm_id = self.import_state.state.mgm_details.current_mgm_id + fetch_rule_ids_query = FwoApi.get_graphql_code( + file_list=[fwo_const.GRAPHQL_QUERY_PATH + "rule/getRulesByUidsWithCreate.graphql"] + ) + fetch_rule_ids_variables: dict[str, Any] = { + "mgmId": mgm_id, + "uids": [rule_uid for rule_uid, _gw_uid in refs_to_add], + } + try: + fetch_rule_ids_result = self.import_state.api_call.call( + fetch_rule_ids_query, query_variables=fetch_rule_ids_variables, analyze_payload=True + ) + if "errors" in fetch_rule_ids_result: + raise FwoImporterError( + f"failed to fetch rule ids for rule UIDs {fetch_rule_ids_variables['uids']!s} for mgm id {mgm_id!s}: {fetch_rule_ids_result['errors']!s}" + ) + rule_uid_to_id_create = { + rule["rule_uid"]: (rule["rule_id"], rule["rule_create"]) + for rule in fetch_rule_ids_result["data"]["rule"] + } + except Exception: + FWOLogger.exception( + f"failed to fetch rule ids for rule UIDs {fetch_rule_ids_variables['uids']!s} for mgm id {mgm_id!s}: {traceback.format_exc()!s}" + ) + raise FwoImporterError("error while trying to fetch rule ids for rule UIDs") from None + mutation = FwoApi.get_graphql_code( + file_list=[fwo_const.GRAPHQL_QUERY_PATH + "rule/insertRuleEnforcedOnGateway.graphql"] + ) + query_variables: dict[str, Any] = { + "rulesEnforcedOnGateway": [ + { + "rule_id": rule_uid_to_id_create[rule_uid][0], + "dev_id": self.import_state.state.gateway_map[mgm_id][gw_uid], + "created": rule_uid_to_id_create[rule_uid][1], + } + for rule_uid, gw_uid in refs_to_add + ], + } + try: + result = self.import_state.api_call.call(mutation, query_variables=query_variables, analyze_payload=True) + + added_refs = result["data"]["insert_rule_enforced_on_gateway"]["affected_rows"] + FWOLogger.info( + f"added {added_refs!s} missing rule enforced on gateway references to DB to fix consistency issues" + ) + except Exception: + FWOLogger.exception( + f"failed to add missing rule enforced on gateway references for mgm id {self.import_state.state.mgm_details.current_mgm_id!s}: {traceback.format_exc()!s}" + ) + raise FwoImporterError("error while trying to add missing rule enforced on gateway references") from None + + def fix_rule_to_gw_refs_in_db( + self, previous_config: FwConfigNormalized, previous_global_config: FwConfigNormalized | None + ): + """ + Set inconsistent rule_enforced_on_gateway entries removed and insert missing ones. + """ + mgm_id = self.import_state.state.mgm_details.current_mgm_id + if mgm_id not in self.import_state.state.gateway_map: + # no gateways assigned to management (e.g. super-mgr) + return + gw_ids = list(self.import_state.state.gateway_map[mgm_id].values()) + query = FwoApi.get_graphql_code( + file_list=[fwo_const.GRAPHQL_QUERY_PATH + "rule/getRulesEnforcedOnGateways.graphql"] + ) + query_variables: dict[str, Any] = { + "gwIds": gw_ids, + } + try: + result = self.import_state.api_call.call(query, query_variables=query_variables) + if "errors" in result: + raise FwoImporterError( + f"failed to get rules enforced on gateways for mgm id {self.import_state.state.mgm_details.current_mgm_id!s}: {result['errors']!s}" + ) + rules_enforced_on_gw = result["data"]["rule_enforced_on_gateway"] + except Exception: + FWOLogger.exception( + f"failed to get rules enforced on gateways for mgm id {self.import_state.state.mgm_details.current_mgm_id!s}: {traceback.format_exc()!s}" + ) + raise FwoImporterError("error while trying to get rules enforced on gateways") from None + # need to set removed flag on active refs referencing removed rule + ref_with_removed_rule_exists = any(ref for ref in rules_enforced_on_gw if ref["rule"]["removed"] is not None) + # comparing expected refs from config with existing refs to *active* rules to determine missing refs to add + expected_refs = FwConfigImportRule.get_rule_to_gw_refs( + previous_config.rulebases, + previous_global_config.rulebases if previous_global_config else None, + previous_config.gateways, + ) + refs_in_db_active_rule = { + (ref["rule"]["rule_uid"], ref["device"]["dev_uid"]) + for ref in rules_enforced_on_gw + if ref["rule"]["removed"] is None + } + refs_to_add = expected_refs - refs_in_db_active_rule + # Note: incorrect entries referencing *active* rules will not be fixed here. + unexpected_refs_in_db = sum( + 1 + for ref in rules_enforced_on_gw + if ref["rule"]["removed"] is None + and (ref["rule"]["rule_uid"], ref["device"]["dev_uid"]) not in expected_refs + ) + if unexpected_refs_in_db > 0: + FWOLogger.warning( + f"{unexpected_refs_in_db} inconsistent rule enforced on gateway refs cannot be removed as they reference active rules" + ) + if ref_with_removed_rule_exists: + mutation = FwoApi.get_graphql_code( + file_list=[fwo_const.GRAPHQL_QUERY_PATH + "rule/removeInconsistentEnforcedOnGateways.graphql"] + ) + query_variables: dict[str, Any] = { + "gwIds": gw_ids, + "importId": self.import_state.state.import_id, + } + try: + result = self.import_state.api_call.call(mutation, query_variables=query_variables) + if "errors" in result: + raise FwoImporterError( + f"failed to remove inconsistent rule enforced on gateway references for mgm id {self.import_state.state.mgm_details.current_mgm_id!s}: {result['errors']!s}" + ) + removed_refs = result["data"]["update_rule_enforced_on_gateway"]["affected_rows"] + FWOLogger.info( + f"removed {removed_refs!s} inconsistent rule enforced on gateway references from DB to fix consistency issues" + ) + self.import_state.state.stats.statistics.inconsistent_ref_delete_count += removed_refs + except Exception: + FWOLogger.exception( + f"failed to remove inconsistent rule enforced on gateway references for mgm id {self.import_state.state.mgm_details.current_mgm_id!s}: {traceback.format_exc()!s}" + ) + raise FwoImporterError( + "error while trying to remove inconsistent rule enforced on gateway references" + ) from None + + if refs_to_add: + self._insert_missing_rule_to_gw_refs_in_db(refs_to_add) + + def fix_ref_tables_in_db(self): + """ + Check ref tables for active references to objects/rules which were marked as removed and remove these + references to fix consistency issues. + """ + mutation = FwoApi.get_graphql_code(file_list=[fwo_const.GRAPHQL_QUERY_PATH + "allObjects/fixRefTables.graphql"]) + query_variables: dict[str, Any] = { + "mgmId": self.import_state.state.mgm_details.current_mgm_id, + "importId": self.import_state.state.import_id, + } + try: + result = self.import_state.api_call.call(mutation, query_variables=query_variables) + + affected_rows = {key: value["affected_rows"] for key, value in result["data"].items()} + if sum(affected_rows.values()) > 0: + FWOLogger.info( + f"fixed references to removed objects/rules in ref tables to fix consistency issues: {affected_rows!s}" + ) + self.import_state.state.stats.statistics.inconsistent_ref_delete_count += sum(affected_rows.values()) + except Exception: + FWOLogger.exception( + f"failed to fix references to removed objects/rules in ref tables for mgm id {self.import_state.state.mgm_details.current_mgm_id!s}: {traceback.format_exc()!s}" + ) + raise FwoImporterError( + "error while trying to fix references to removed objects/rules in ref tables" + ) from None + + def fix_changelog_rule(self): + """ + Fix changelog entries with old_rule_id == new_rule_id (both containing new_rule_id due to a bug in the past) + """ + get_changelog_entries_query = FwoApi.get_graphql_code( + file_list=[fwo_const.GRAPHQL_QUERY_PATH + "rule/getChangelogRulesCForMgm.graphql"] + ) + query_variables: dict[str, Any] = { + "mgmId": self.import_state.state.mgm_details.current_mgm_id, + } + try: + result = self.import_state.api_call.call(get_changelog_entries_query, query_variables=query_variables) + if "errors" in result: + raise FwoImporterError( + f"failed to get changelog entries for mgm id {self.import_state.state.mgm_details.current_mgm_id!s}: {result['errors']!s}" + ) + changelog_entries = result["data"]["changelog_rule"] + entries_to_fix = [ + entry + for entry in changelog_entries + if entry["new_rule_id"] is not None + and entry["old_rule_id"] is not None + and entry["new_rule_id"] == entry["old_rule_id"] + ] + if not entries_to_fix: + return # nothing to fix + FWOLogger.info( + f"found {len(entries_to_fix)!s} changelog entries with identical new and old rule id for mgm id {self.import_state.state.mgm_details.current_mgm_id!s}, fixing these entries now" + ) + # get correct old rule ids + get_rule_ids_mutation = FwoApi.get_graphql_code( + file_list=[fwo_const.GRAPHQL_QUERY_PATH + "rule/getRulesByUidsForMgm.graphql"] + ) + get_rule_ids_variables: dict[str, Any] = { + "mgmId": self.import_state.state.mgm_details.current_mgm_id, + "ruleUids": list({entry["rule"]["rule_uid"] for entry in entries_to_fix}), + } + get_rule_ids_result = self.import_state.api_call.call( + get_rule_ids_mutation, query_variables=get_rule_ids_variables, analyze_payload=True + ) + if "errors" in get_rule_ids_result: + raise FwoImporterError( + f"failed to get rule ids for UIDs of changelog entries to fix for mgm id {self.import_state.state.mgm_details.current_mgm_id!s}: {get_rule_ids_result['errors']!s}" + ) + correct_old_rule_ids: dict[int, int] = {} + for entry in entries_to_fix: + rule_uid = entry["rule"]["rule_uid"] + new_rule_id = entry["new_rule_id"] + correct_old_rule_id = max( + rule["rule_id"] + for rule in get_rule_ids_result["data"]["rule"] + if rule["rule_uid"] == rule_uid and rule["rule_id"] < new_rule_id + ) + correct_old_rule_ids[entry["log_rule_id"]] = correct_old_rule_id + changelog_rule_updates = { + "updates": [ + {"where": {"log_rule_id": {"_eq": log_rule_id}}, "_set": {"old_rule_id": old_rule_id}} + for log_rule_id, old_rule_id in correct_old_rule_ids.items() + ] + } + update_changelog_entries_mutation = FwoApi.get_graphql_code( + file_list=[fwo_const.GRAPHQL_QUERY_PATH + "rule/updateChangelogRuleEntries.graphql"] + ) + update_result = self.import_state.api_call.call( + update_changelog_entries_mutation, query_variables=changelog_rule_updates, analyze_payload=True + ) + if "errors" in update_result: + raise FwoImporterError( + f"failed to update changelog entries with correct old rule ids for mgm id {self.import_state.state.mgm_details.current_mgm_id!s}: {update_result['errors']!s}" + ) + updated_entries = sum( + update["affected_rows"] for update in update_result["data"]["update_changelog_rule_many"] + ) + FWOLogger.info( + f"updated {updated_entries!s} changelog entries with correct old rule ids for mgm id {self.import_state.state.mgm_details.current_mgm_id!s}" + ) + except Exception: + FWOLogger.exception( + f"failed to fix changelog entries with identical new and old rule id for mgm id {self.import_state.state.mgm_details.current_mgm_id!s}: {traceback.format_exc()!s}" + ) + raise FwoImporterError( + "error while trying to fix changelog entries with identical new and old rule id" + ) from None diff --git a/roles/importer/files/importer/model_controllers/fwconfig_import_gateway.py b/roles/importer/files/importer/model_controllers/fwconfig_import_gateway.py new file mode 100644 index 0000000000..565772f56a --- /dev/null +++ b/roles/importer/files/importer/model_controllers/fwconfig_import_gateway.py @@ -0,0 +1,243 @@ +import traceback +from typing import Any + +import fwo_const +from fwo_api import FwoApi +from fwo_exceptions import FwoImporterError +from fwo_log import FWOLogger +from model_controllers.rulebase_link_controller import RulebaseLinkController +from models.gateway import Gateway +from models.rulebase_link import ( # TODO: check if we need RulebaseLinkUidBased as well + RulebaseLink, + RulebaseLinkUidBased, +) +from services.global_state import GlobalState +from services.service_provider import ServiceProvider +from services.uid2id_mapper import Uid2IdMapper + + +class FwConfigImportGateway: + """ + Provides methods import gateway information into the FWO API. + """ + + _global_state: GlobalState + _uid2id_mapper: Uid2IdMapper + _rb_link_controller: RulebaseLinkController + + def __init__(self): + service_provider = ServiceProvider() + self._global_state = service_provider.get_global_state() + self._uid2id_mapper = service_provider.get_uid2id_mapper(self._global_state.import_state.state.import_id) + self._rb_link_controller = RulebaseLinkController() + + def get_rb_link_controller(self) -> RulebaseLinkController: + return self._rb_link_controller + + def get_global_state(self) -> GlobalState: + return self._global_state + + def update_gateway_diffs(self): + # add gateway details: + self._rb_link_controller.get_rulebase_links( + self._global_state.import_state.state, self._global_state.import_state.api_call + ) + if ( + self._global_state.import_state.state.is_clearing_import + and self._global_state.normalized_config is not None + and len(self._global_state.normalized_config.gateways) == 0 + ): + removed_link_ids = [link.id for link in self._rb_link_controller.rb_links if link.id is not None] + self._rb_link_controller.remove_rulebase_links( + self._global_state.import_state.api_call, + self._global_state.import_state.state.stats, + self._global_state.import_state.state.import_id, + removed_link_ids, + ) + self.update_interface_diffs() + self.update_routing_diffs() + return + required_inserts, required_removes = self.update_rulebase_link_diffs() + self._rb_link_controller.insert_rulebase_links( + self._global_state.import_state.api_call, self._global_state.import_state.state.stats, required_inserts + ) + self._rb_link_controller.remove_rulebase_links( + self._global_state.import_state.api_call, + self._global_state.import_state.state.stats, + self._global_state.import_state.state.import_id, + required_removes, + ) + self.update_interface_diffs() + self.update_routing_diffs() + self.update_removed_gateways() + + def update_rulebase_link_diffs(self) -> tuple[list[dict[str, Any]], list[int]]: + if self._global_state.normalized_config is None: + raise FwoImporterError("normalized_config is None in update_rulebase_link_diffs") + if self._global_state.previous_config is None: + raise FwoImporterError("previous_config is None in update_rulebase_link_diffs") + + required_inserts: list[dict[str, Any]] = [] + required_removes: list[int] = [] + + for gw in self._global_state.normalized_config.gateways: + previous_config_gw = next( + (p_gw for p_gw in self._global_state.previous_config.gateways if gw.Uid == p_gw.Uid), None + ) + + if gw in self._global_state.previous_config.gateways: + # this check finds all changes in gateway (including rulebase link changes) + # gateway found with exactly same properties in previous config + continue + + FWOLogger.debug(f"gateway {gw!s} NOT found in previous config", 9) + if gw.Uid is None: + raise FwoImporterError("found gateway with Uid = None") + gw_id = self._global_state.import_state.state.lookup_gateway_id(gw.Uid) + + self._create_insert_args(gw, previous_config_gw, gw_id, required_inserts) + + if previous_config_gw: + self._create_remove_args(gw, previous_config_gw, gw_id, required_removes) + + return required_inserts, required_removes + + def _create_insert_args( + self, + normalized_gateway: Gateway, + previous_gateway: Gateway | None, + gw_id: int | None, + arg_list: list[dict[str, Any]], + ): + rulebase_links = [] + + for link in normalized_gateway.RulebaseLinks: + if previous_gateway: + rulebase_links = previous_gateway.RulebaseLinks + self._try_add_single_link(arg_list, link, rulebase_links, gw_id, is_insert=True) + + def _create_remove_args( + self, normalized_gateway: Gateway, previous_gateway: Gateway, gw_id: int | None, arg_list: list[int] + ): + removed_rulebase_links: list[dict[str, Any]] = [] + + for link in previous_gateway.RulebaseLinks: + self._try_add_single_link( + removed_rulebase_links, link, normalized_gateway.RulebaseLinks, gw_id, is_insert=False + ) + for link in removed_rulebase_links: + link_in_db = self._try_get_id_based_link(link, self._rb_link_controller.rb_links) + if link_in_db and link_in_db.id is not None: + arg_list.append(link_in_db.id) + + def _try_add_single_link( + self, + rb_link_list: list[dict[str, Any]], + link: RulebaseLinkUidBased, + link_list: list[RulebaseLinkUidBased], + gw_id: int | None, + is_insert: bool, + ): + # For updates, if rule changed we need the id of the old version, since the rulebase links still have the old fks (for updates) + # For inserts, we need the id of the new version + from_rule_id = ( + self._uid2id_mapper.get_rule_id(link.from_rule_uid, before_update=not is_insert) + if link.from_rule_uid + else None + ) + + if link.from_rulebase_uid is None or link.from_rulebase_uid == "": + from_rulebase_id = None + else: + from_rulebase_id = self._uid2id_mapper.get_rulebase_id(link.from_rulebase_uid, before_update=not is_insert) + to_rulebase_id = self._uid2id_mapper.get_rulebase_id(link.to_rulebase_uid, before_update=not is_insert) + link_type_id = self._global_state.import_state.state.lookup_link_type(link.link_type) + if type(link_type_id) is not int: + FWOLogger.warning(f"did not find a link_type_id for link_type {link.link_type}") + + if not self._link_is_in_link_list(link, link_list): + if gw_id is None: + FWOLogger.warning(f"did not find a gwId for UID {link}") + return + rb_link_list.append( + RulebaseLink( + gw_id=gw_id, + from_rule_id=from_rule_id, + to_rulebase_id=to_rulebase_id, + link_type=link_type_id, + is_initial=link.is_initial, + is_global=link.is_global, + is_section=link.is_section, + from_rulebase_id=from_rulebase_id, + created=self._global_state.import_state.state.import_id, + ).to_dict() + ) + + FWOLogger.debug(f"link {link} was added", 9) + + def _link_is_in_link_list(self, link: RulebaseLinkUidBased, link_list: list[RulebaseLinkUidBased]) -> bool: + if link_list: + existing_link = next( + (existing_link for existing_link in link_list if existing_link.to_dict() == link.to_dict()), None + ) + + if existing_link: + return True + + return False + + def _try_get_id_based_link(self, link: dict[str, Any], link_list: list[RulebaseLink]): + return next( + ( + existing_link + for existing_link in link_list + if {**existing_link.to_dict(), "created": 0} == {**link, "created": 0} + ), + None, + ) + + def update_interface_diffs(self): + # TODO: needs to be implemented + pass + + def update_routing_diffs(self): + # TODO: needs to be implemented + pass + + def update_removed_gateways(self): + if self._global_state.normalized_config is None or self._global_state.previous_config is None: + raise FwoImporterError("normalized_config or previous_config is None in update_removed_gateways") + gw_uids_to_remove = [ + gw.Uid + for gw in self._global_state.previous_config.gateways + if gw.Uid not in [ngw.Uid for ngw in self._global_state.normalized_config.gateways] + ] + + if not gw_uids_to_remove: + return # nothing to do + gw_ids_to_remove = [ + self._global_state.import_state.state.lookup_gateway_id(gw_uid) for gw_uid in gw_uids_to_remove if gw_uid + ] + + FWOLogger.info(f"marking all entries associated with gateways {gw_uids_to_remove!s} as removed") + mutation = FwoApi.get_graphql_code( + file_list=[fwo_const.GRAPHQL_QUERY_PATH + "device/markGatewaysRemoved.graphql"] + ) + query_variables = { + "gwIds": gw_ids_to_remove, + "importId": self._global_state.import_state.state.import_id, + } + try: + result = self._global_state.import_state.api_connection.call(mutation, query_variables=query_variables) + affected_tables = {key: value["affected_rows"] for key, value in result["data"].items()} + FWOLogger.debug(f"marked gateways {gw_uids_to_remove!s} as removed in tables: {affected_tables!s}") + FWOLogger.info( + f"marked {sum(affected_tables.values())!s} entries as removed for gateways {gw_uids_to_remove!s}" + ) + self._global_state.import_state.state.stats.statistics.rulebase_link_delete_count += affected_tables.get( + "update_rulebase_link", 0 + ) + except Exception: + FWOLogger.error( + f"fwconfig_import_gateway - error while marking gateways {gw_uids_to_remove!s} as removed: {traceback.format_exc()!s}" + ) diff --git a/roles/importer/files/importer/model_controllers/fwconfig_import_object.py b/roles/importer/files/importer/model_controllers/fwconfig_import_object.py new file mode 100644 index 0000000000..8d850e90a0 --- /dev/null +++ b/roles/importer/files/importer/model_controllers/fwconfig_import_object.py @@ -0,0 +1,910 @@ +import datetime +import traceback +from enum import Enum +from typing import Any + +import fwo_const +from fwo_api_call import FwoApi +from fwo_exceptions import FwoDuplicateKeyViolationError, FwoImporterError +from fwo_log import ChangeLogger, FWOLogger +from model_controllers.import_state_controller import ImportStateController +from models.fwconfig_normalized import FwConfigNormalized +from models.fwconfigmanager import FwConfigManager +from models.networkobject import NetworkObjectForImport +from models.serviceobject import ServiceObjectForImport +from models.time_object import TimeObject, TimeObjectForImport +from services.group_flats_mapper import GroupFlatsMapper +from services.service_provider import ServiceProvider +from services.uid2id_mapper import Uid2IdMapper + + +class Type(Enum): + NETWORK_OBJECT = "network_object" + SERVICE_OBJECT = "service_object" + USER = "user" + + +# this class is used for importing a config into the FWO API +class FwConfigImportObject: + import_state: ImportStateController + normalized_config: FwConfigNormalized | None = None + global_normalized_config: FwConfigNormalized | None = None + group_flats_mapper: GroupFlatsMapper + prev_group_flats_mapper: GroupFlatsMapper + uid2id_mapper: Uid2IdMapper + + def __init__(self): + # Get state, config and services. + service_provider = ServiceProvider() + global_state = service_provider.get_global_state() + self.import_state = global_state.import_state + self.normalized_config = global_state.normalized_config + self.global_normalized_config = global_state.global_normalized_config + self.group_flats_mapper = service_provider.get_group_flats_mapper(self.import_state.state.import_id) + self.prev_group_flats_mapper = service_provider.get_prev_group_flats_mapper(self.import_state.state.import_id) + self.uid2id_mapper = service_provider.get_uid2id_mapper(self.import_state.state.import_id) + + def update_object_diffs( + self, + prev_config: FwConfigNormalized, + prev_global_config: FwConfigNormalized | None, + single_manager: FwConfigManager, + ): + change_logger = ChangeLogger() + if self.normalized_config is None: + raise FwoImporterError("no normalized config available in FwConfigImportObject.update_object_diffs") + # calculate network object diffs + # here we are handling the previous config as a dict for a while + deleted_nw_obj_uids: list[str] = list( + prev_config.network_objects.keys() - self.normalized_config.network_objects.keys() + ) + new_nw_obj_uids: list[str] = list( + self.normalized_config.network_objects.keys() - prev_config.network_objects.keys() + ) + nw_obj_uids_in_both: list[str] = list( + self.normalized_config.network_objects.keys() & prev_config.network_objects.keys() + ) + + # For correct changelog and stats. + changed_nw_objs: list[str] = [] + changed_svcs: list[str] = [] + + # decide if it is prudent to mix changed, deleted and added rules here: + for nw_obj_uid in nw_obj_uids_in_both: + if self.normalized_config.network_objects[nw_obj_uid] != prev_config.network_objects[nw_obj_uid]: + new_nw_obj_uids.append(nw_obj_uid) + deleted_nw_obj_uids.append(nw_obj_uid) + changed_nw_objs.append(nw_obj_uid) + + # calculate service object diffs + deleted_svc_obj_uids: list[str] = list( + prev_config.service_objects.keys() - self.normalized_config.service_objects.keys() + ) + new_svc_obj_uids: list[str] = list( + self.normalized_config.service_objects.keys() - prev_config.service_objects.keys() + ) + svc_obj_uids_in_both: list[str] = list( + self.normalized_config.service_objects.keys() & prev_config.service_objects.keys() + ) + + for svc_obj_uid in svc_obj_uids_in_both: + if self.normalized_config.service_objects[svc_obj_uid] != prev_config.service_objects[svc_obj_uid]: + new_svc_obj_uids.append(svc_obj_uid) + deleted_svc_obj_uids.append(svc_obj_uid) + changed_svcs.append(svc_obj_uid) + + # calculate user diffs + deleted_user_uids: list[str] = list(prev_config.users.keys() - self.normalized_config.users.keys()) + new_user_uids: list[str] = list(self.normalized_config.users.keys() - prev_config.users.keys()) + user_uids_in_both: list[str] = list(self.normalized_config.users.keys() & prev_config.users.keys()) + for user_uid in user_uids_in_both: + if self.normalized_config.users[user_uid] != prev_config.users[user_uid]: + new_user_uids.append(user_uid) + deleted_user_uids.append(user_uid) + + # initial mapping of object uids to ids. needs to be updated, if more objects are created in the db after this point + # TODO: only fetch objects needed later. Esp for !isFullImport. but: newNwObjIds not enough! + # -> newObjs + extract all objects from new/changed rules and groups, flatten them. Complete? + self.uid2id_mapper.update_network_object_mapping(is_global=single_manager.is_super_manager) + self.uid2id_mapper.update_service_object_mapping(is_global=single_manager.is_super_manager) + self.uid2id_mapper.update_user_mapping(is_global=single_manager.is_super_manager) + self.uid2id_mapper.update_zone_mapping(is_global=single_manager.is_super_manager) + + self.group_flats_mapper.init_config(self.normalized_config, self.global_normalized_config) + self.prev_group_flats_mapper.init_config(prev_config, prev_global_config) + + # need to do this first, since we need the old object IDs for the group memberships + # TODO: computationally expensive? Even without changes, all group objects and their members are compared to the previous config. + self.remove_outdated_memberships(prev_config, Type.NETWORK_OBJECT) + self.remove_outdated_memberships(prev_config, Type.SERVICE_OBJECT) + self.remove_outdated_memberships(prev_config, Type.USER) + + # calculate zone object diffs + deleted_zone_names: list[str] = list( + prev_config.zone_objects.keys() - self.normalized_config.zone_objects.keys() + ) + new_zone_names: list[str] = list(self.normalized_config.zone_objects.keys() - prev_config.zone_objects.keys()) + zone_names_in_both: list[str] = list( + self.normalized_config.zone_objects.keys() & prev_config.zone_objects.keys() + ) + changed_zones: list[str] = [] + + for zone_name in zone_names_in_both: + if self.normalized_config.zone_objects[zone_name] != prev_config.zone_objects[zone_name]: + new_zone_names.append(zone_name) + deleted_zone_names.append(zone_name) + changed_zones.append(zone_name) + + # add newly created objects + ( + new_nw_obj_ids, + new_svc_obj_ids, + new_user_ids, + new_zone_ids, + removed_nw_obj_ids, + removed_svc_obj_ids, + _, + _, + ) = self.update_objects_via_api( + single_manager, + new_nw_obj_uids, + new_svc_obj_uids, + new_user_uids, + new_zone_names, + deleted_nw_obj_uids, + deleted_svc_obj_uids, + deleted_user_uids, + deleted_zone_names, + ) + self.update_time_objs_via_api( + prev_config.time_objects, self.normalized_config.time_objects, is_global=single_manager.is_super_manager + ) + + self.uid2id_mapper.add_network_object_mappings(new_nw_obj_ids, is_global=single_manager.is_super_manager) + self.uid2id_mapper.add_service_object_mappings(new_svc_obj_ids, is_global=single_manager.is_super_manager) + self.uid2id_mapper.add_user_mappings(new_user_ids, is_global=single_manager.is_super_manager) + self.uid2id_mapper.add_zone_mappings(new_zone_ids, is_global=single_manager.is_super_manager) + + # insert new and updated group memberships + self.add_group_memberships(prev_config, Type.NETWORK_OBJECT) + self.add_group_memberships(prev_config, Type.SERVICE_OBJECT) + self.add_group_memberships(prev_config, Type.USER) + + # these objects have really been deleted so there should be no refs to them anywhere! verify this + + # TODO: calculate user diffs + # TODO: write changelog for zones + # Get Changed Ids. + + change_logger.create_change_id_maps( + self.uid2id_mapper, + changed_nw_objs, + changed_svcs, + removed_nw_obj_ids, + removed_svc_obj_ids, + ) + + # Seperate changes from adds and removes for changelog and stats. + + new_nw_obj_ids = [ + new_nw_obj_id + for new_nw_obj_id in new_nw_obj_ids + if new_nw_obj_id["obj_id"] not in list(change_logger.changed_object_id_map.values()) + ] + removed_nw_obj_ids = [ + removed_nw_obj_id + for removed_nw_obj_id in removed_nw_obj_ids + if removed_nw_obj_id["obj_id"] not in list(change_logger.changed_object_id_map.keys()) + ] + new_svc_obj_ids = [ + new_svc_obj_id + for new_svc_obj_id in new_svc_obj_ids + if new_svc_obj_id["svc_id"] not in list(change_logger.changed_service_id_map.values()) + ] + removed_svc_obj_ids = [ + removed_svc_obj_id + for removed_svc_obj_id in removed_svc_obj_ids + if removed_svc_obj_id["svc_id"] not in list(change_logger.changed_service_id_map.keys()) + ] + + # Write change logs to tables. + + self.add_changelog_objs(new_nw_obj_ids, new_svc_obj_ids, removed_nw_obj_ids, removed_svc_obj_ids) + + # note changes: + self.import_state.state.stats.increment_network_object_add_count(len(new_nw_obj_ids)) + self.import_state.state.stats.increment_network_object_delete_count(len(removed_nw_obj_ids)) + self.import_state.state.stats.increment_network_object_change_count( + len(change_logger.changed_object_id_map.items()) + ) + self.import_state.state.stats.increment_service_object_add_count(len(new_svc_obj_ids)) + self.import_state.state.stats.increment_service_object_delete_count(len(removed_svc_obj_ids)) + self.import_state.state.stats.increment_service_object_change_count( + len(change_logger.changed_service_id_map.items()) + ) + + # TODO: split into multiple functions again, as large queries are not handled efficiently in some scenarios + def update_objects_via_api( + self, + single_manager: FwConfigManager, + new_nw_object_uids: list[str], + new_svc_obj_uids: list[str], + new_user_uids: list[str], + new_zone_names: list[str], + removed_nw_object_uids: list[str], + removed_svc_object_uids: list[str], + removed_user_uids: list[str], + removed_zone_names: list[str], + ) -> tuple[ + list[dict[str, Any]], + list[dict[str, Any]], + list[dict[str, Any]], + list[dict[str, Any]], + list[dict[str, Any]], + list[dict[str, Any]], + list[dict[str, Any]], + list[dict[str, Any]], + ]: + """ + Update objects via FWO API. + + Args: + single_manager (FwConfigManager): The manager for which the objects are being updated. + new_nw_object_uids (list[str]): List of UIDs for new network objects to be added. + new_svc_obj_uids (list[str]): List of UIDs for new service objects to be added. + new_user_uids (list[str]): List of UIDs for new users to be added. + new_zone_names (list[str]): List of names for new zones to be added. + removed_nw_object_uids (list[str]): List of UIDs for network objects to be removed. + removed_svc_object_uids (list[str]): List of UIDs for service objects to be removed. + removed_user_uids (list[str]): List of UIDs for users to be removed. + removed_zone_names (list[str]): List of names for zones to be removed. + + Returns: + tuple: A tuple containing lists of dictionaries for new and removed objects' IDs. + + """ + # here we also mark old objects removed before adding the new versions + new_nwobj_ids = [] + new_nwsvc_ids = [] + new_user_ids = [] + new_zone_ids = [] + removed_nwobj_ids = [] + removed_nwsvc_ids = [] + removed_user_ids = [] + removed_zone_ids = [] + this_managements_id = self.import_state.state.lookup_management_id(single_manager.manager_uid) + if this_managements_id is None: + raise FwoImporterError( + f"failed to update objects in updateObjectsViaApi: no management id found for manager uid '{single_manager.manager_uid}'" + ) + import_mutation = FwoApi.get_graphql_code( + file_list=[fwo_const.GRAPHQL_QUERY_PATH + "allObjects/upsertObjects.graphql"] + ) + query_variables: dict[str, Any] = { + "mgmId": this_managements_id, + "importId": self.import_state.state.import_id, + "newNwObjects": self.prepare_new_nwobjs(new_nw_object_uids, this_managements_id), + "newSvcObjects": self.prepare_new_svcobjs(new_svc_obj_uids, this_managements_id), + "newUsers": self.prepare_new_userobjs(new_user_uids, this_managements_id), + "newZones": self.prepare_new_zones(new_zone_names, this_managements_id), + "removedNwObjectUids": removed_nw_object_uids, + "removedSvcObjectUids": removed_svc_object_uids, + "removedUserUids": removed_user_uids, + "removedZoneUids": removed_zone_names, + } + + FWOLogger.debug(f"fwo_api:importNwObject - import_mutation: {import_mutation}", 9) + + try: + import_result = self.import_state.api_call.call( + import_mutation, query_variables=query_variables, analyze_payload=True + ) + if "errors" in import_result: + raise FwoImporterError(f"failed to update objects in updateObjectsViaApi: {import_result['errors']!s}") + _ = ( + int(import_result["data"]["insert_object"]["affected_rows"]) + + int(import_result["data"]["insert_service"]["affected_rows"]) + + int(import_result["data"]["insert_usr"]["affected_rows"]) + + int(import_result["data"]["update_object"]["affected_rows"]) + + int(import_result["data"]["update_service"]["affected_rows"]) + + int(import_result["data"]["update_usr"]["affected_rows"]) + + int(import_result["data"]["update_zone"]["affected_rows"]) + ) + new_nwobj_ids = import_result["data"]["insert_object"]["returning"] + new_nwsvc_ids = import_result["data"]["insert_service"]["returning"] + new_user_ids = import_result["data"]["insert_usr"]["returning"] + new_zone_ids = import_result["data"]["insert_zone"]["returning"] + removed_nwobj_ids = import_result["data"]["update_object"]["returning"] + removed_nwsvc_ids = import_result["data"]["update_service"]["returning"] + removed_user_ids = import_result["data"]["update_usr"]["returning"] + removed_zone_ids = import_result["data"]["update_zone"]["returning"] + except Exception: + raise FwoImporterError(f"failed to update objects: {traceback.format_exc()!s}") + return ( + new_nwobj_ids, + new_nwsvc_ids, + new_user_ids, + new_zone_ids, + removed_nwobj_ids, + removed_nwsvc_ids, + removed_user_ids, + removed_zone_ids, + ) + + def update_time_objs_via_api( + self, previous_time_objs: dict[str, TimeObject], current_time_objs: dict[str, TimeObject], is_global: bool + ) -> None: + """ + Insert new time objects and update removed time objects via FWO API. + Also updates uid2id mapping for time objects and import statistics. + """ + self.uid2id_mapper.update_time_object_mapping(is_global=is_global) + import_mutation = FwoApi.get_graphql_code( + file_list=[fwo_const.GRAPHQL_QUERY_PATH + "time/upsertTimeObjects.graphql"] + ) + new_uids = list(current_time_objs.keys() - previous_time_objs.keys()) + removed_uids = list(previous_time_objs.keys() - current_time_objs.keys()) + # changed time objects will be set to removed and re-added with new data + changed_uids = [ + uid + for uid in current_time_objs.keys() & previous_time_objs.keys() + if current_time_objs[uid] != previous_time_objs[uid] + ] + query_variables: dict[str, Any] = { + "mgmId": self.import_state.state.mgm_details.current_mgm_id, + "importId": self.import_state.state.import_id, + "newTimeObjects": [ + TimeObjectForImport.from_normalized( + current_time_objs[uid], + self.import_state.state.mgm_details.current_mgm_id, + self.import_state.state.import_id, + ).model_dump() + for uid in new_uids + changed_uids + ], + "removedTimeObjectIds": [self.uid2id_mapper.get_time_object_id(uid) for uid in removed_uids + changed_uids], + } + try: + import_result = self.import_state.api_call.call( + import_mutation, query_variables=query_variables, analyze_payload=True + ) + if "errors" in import_result: + raise FwoImporterError(f"failed to update time objects: {import_result['errors']!s}") + insert_count = int(import_result["data"]["insert_time_object"]["affected_rows"]) + update_count = int(import_result["data"]["update_time_object"]["affected_rows"]) + self.uid2id_mapper.add_time_object_mappings( + import_result["data"]["insert_time_object"]["returning"], is_global=is_global + ) + self.import_state.state.stats.statistics.time_object_add_count += len(new_uids) + self.import_state.state.stats.statistics.time_object_delete_count += len(removed_uids) + self.import_state.state.stats.statistics.time_object_change_count += len(changed_uids) + FWOLogger.debug( + f"fwo_api:importTimeObject - updated time objects via API. Inserted: {insert_count}, Updated: {update_count}" + ) + except Exception: + raise FwoImporterError(f"failed to update time objects: {traceback.format_exc()!s}") + + def prepare_new_nwobjs(self, new_nwobj_uids: list[str], mgm_id: int) -> list[dict[str, Any]]: + if self.normalized_config is None: + raise FwoImporterError("no normalized config available in FwConfigImportObject.prepare_new_nwobjs") + new_nwobjs: list[dict[str, Any]] = [] + for nwobj_uid in new_nwobj_uids: + new_nwobj = NetworkObjectForImport( + nw_object=self.normalized_config.network_objects[nwobj_uid], + mgm_id=mgm_id, + import_id=self.import_state.state.import_id, + color_id=self.import_state.state.lookup_color_id( + self.normalized_config.network_objects[nwobj_uid].obj_color + ), + typ_id=self.import_state.state.lookup_network_obj_type_id( + self.normalized_config.network_objects[nwobj_uid].obj_typ + ), + ) + new_nwobj_dict = new_nwobj.to_dict() + new_nwobjs.append(new_nwobj_dict) + return new_nwobjs + + def prepare_new_svcobjs(self, new_svcobj_uids: list[str], mgm_id: int) -> list[dict[str, Any]]: + if self.normalized_config is None: + raise FwoImporterError("no normalized config available in FwConfigImportObject.prepare_new_svcobjs") + return [ + ServiceObjectForImport( + svc_object=self.normalized_config.service_objects[uid], + mgm_id=mgm_id, + import_id=self.import_state.state.import_id, + color_id=self.import_state.state.lookup_color_id(self.normalized_config.service_objects[uid].svc_color), + typ_id=self.import_state.state.lookup_service_obj_type_id( + self.normalized_config.service_objects[uid].svc_typ + ), + ).to_dict() + for uid in new_svcobj_uids + ] + + def prepare_new_userobjs(self, new_user_uids: list[str], mgm_id: int) -> list[dict[str, Any]]: + if self.normalized_config is None: + raise FwoImporterError("no normalized config available in FwConfigImportObject.prepare_new_userobjs") + return [ + { + "user_uid": uid, + "mgm_id": mgm_id, + "user_create": self.import_state.state.import_id, + "user_last_seen": self.import_state.state.import_id, + "usr_typ_id": self.import_state.state.lookup_user_obj_type_id( + self.normalized_config.users[uid]["user_typ"] + ), + "user_name": self.normalized_config.users[uid]["user_name"], + } + for uid in new_user_uids + ] + + def prepare_new_zones(self, new_zone_names: list[str], mgm_id: int) -> list[dict[str, Any]]: + if self.normalized_config is None: + raise FwoImporterError("no normalized config available in FwConfigImportObject.prepare_new_zones") + + return [ + { + "mgm_id": mgm_id, + "zone_create": self.import_state.state.import_id, + "zone_last_seen": self.import_state.state.import_id, + "zone_name": self.normalized_config.zone_objects[uid]["zone_name"], + } + for uid in new_zone_names + ] + + def get_config_objects(self, typ: Type, prev_config: FwConfigNormalized) -> tuple[dict[str, Any], dict[str, Any]]: + if self.normalized_config is None: + raise FwoImporterError("no normalized config available in FwConfigImportObject.get_config_objects") + if typ == Type.NETWORK_OBJECT: + return prev_config.network_objects, self.normalized_config.network_objects + if typ == Type.SERVICE_OBJECT: + return prev_config.service_objects, self.normalized_config.service_objects + return prev_config.users, self.normalized_config.users + + def get_id(self, typ: Type, uid: str, before_update: bool = False) -> int | None: + if typ == Type.NETWORK_OBJECT: + return self.uid2id_mapper.get_network_object_id(uid, before_update) + if typ == Type.SERVICE_OBJECT: + return self.uid2id_mapper.get_service_object_id(uid, before_update) + return self.uid2id_mapper.get_user_id(uid, before_update) + + def get_local_id(self, typ: Type, uid: str, before_update: bool = False) -> int | None: + if typ == Type.NETWORK_OBJECT: + return self.uid2id_mapper.get_network_object_id(uid, before_update, local_only=True) + if typ == Type.SERVICE_OBJECT: + return self.uid2id_mapper.get_service_object_id(uid, before_update, local_only=True) + return self.uid2id_mapper.get_user_id(uid, before_update, local_only=True) + + def is_group(self, typ: Type, obj: Any) -> bool | None: + if typ == Type.NETWORK_OBJECT: + return obj.obj_typ == "group" + if typ == Type.SERVICE_OBJECT: + return obj.svc_typ == "group" + return obj.get("user_typ", None) == "group" + + def get_refs(self, typ: Type, obj: Any) -> str | None: + if typ == Type.NETWORK_OBJECT: + return obj.obj_member_refs + if typ == Type.SERVICE_OBJECT: + return obj.svc_member_refs + return obj.get("user_member_refs", None) + + def get_members(self, typ: Type, refs: str | None) -> list[str]: + if typ == Type.NETWORK_OBJECT: + return ( + [member.split(fwo_const.USER_DELIMITER)[0] for member in refs.split(fwo_const.LIST_DELIMITER) if member] + if refs + else [] + ) + return refs.split(fwo_const.LIST_DELIMITER) if refs else [] + + def get_flats(self, typ: Type, uid: str) -> list[str]: + if typ == Type.NETWORK_OBJECT: + return self.group_flats_mapper.get_network_object_flats([uid]) + if typ == Type.SERVICE_OBJECT: + return self.group_flats_mapper.get_service_object_flats([uid]) + return self.group_flats_mapper.get_user_flats([uid]) + + def get_prev_flats(self, typ: Type, uid: str) -> list[str]: + if typ == Type.NETWORK_OBJECT: + return self.prev_group_flats_mapper.get_network_object_flats([uid]) + if typ == Type.SERVICE_OBJECT: + return self.prev_group_flats_mapper.get_service_object_flats([uid]) + return self.prev_group_flats_mapper.get_user_flats([uid]) + + def get_prefix(self, typ: Type): + if typ == Type.NETWORK_OBJECT: + return "objgrp" + if typ == Type.SERVICE_OBJECT: + return "svcgrp" + return "usergrp" + + def remove_outdated_memberships(self, prev_config: FwConfigNormalized, typ: Type): + removed_members: list[dict[str, Any]] = [] + removed_flats: list[dict[str, Any]] = [] + + prev_config_objects, current_config_objects = self.get_config_objects(typ, prev_config) + prefix = self.get_prefix(typ) + + for uid in prev_config_objects: + self.find_removed_objects( + current_config_objects, + prev_config_objects, + removed_members, + removed_flats, + prefix, + uid, + typ, + ) + # remove outdated group memberships + if len(removed_members) == 0: + return + + import_mutation = f""" + mutation removeOutdated{prefix.capitalize()}Memberships($importId: bigint!, $removedMembers: [{prefix}_bool_exp!]!, $removedFlats: [{prefix}_flat_bool_exp!]!) {{ + update_{prefix}(where: {{_and: [{{_or: $removedMembers}}, {{removed: {{_is_null: true}}}}]}}, + _set: {{ + removed: $importId, + active: false + }} + ) {{ + affected_rows + }} + update_{prefix}_flat(where: {{_and: [{{_or: $removedFlats}}, {{removed: {{_is_null: true}}}}]}}, + _set: {{ + removed: $importId, + active: false + }} + ) {{ + affected_rows + }} + }} + """ + query_variables: dict[str, Any] = { + "importId": self.import_state.state.import_id, + "removedMembers": removed_members, + "removedFlats": removed_flats, + } + try: + import_result = self.import_state.api_call.call( + import_mutation, query_variables=query_variables, analyze_payload=True + ) + if "errors" in import_result: + FWOLogger.exception( + f"fwo_api:importNwObject - error in removeOutdated{prefix.capitalize()}Memberships: {import_result['errors']!s}" + ) + else: + _ = int(import_result["data"][f"update_{prefix}"]["affected_rows"]) + int( + import_result["data"][f"update_{prefix}_flat"]["affected_rows"] + ) + except Exception: + FWOLogger.exception(f"failed to remove outdated group memberships for {typ}: {traceback.format_exc()!s}") + + def find_removed_objects( + self, + current_config_objects: dict[str, Any], + prev_config_objects: dict[str, Any], + removed_members: list[dict[str, Any]], + removed_flats: list[dict[str, Any]], + prefix: str, + uid: str, + typ: Type, + ) -> None: + if not self.is_group(typ, prev_config_objects[uid]): + return + db_id = self.get_id(typ, uid, before_update=True) + prev_member_uids = self.get_members(typ, self.get_refs(typ, prev_config_objects[uid])) + prev_flat_member_uids = self.get_prev_flats(typ, uid) + member_uids = [] # all members need to be removed if group deleted or changed + flat_member_uids = [] + # group not removed and group not changed -> check for changes in members + if uid in current_config_objects and current_config_objects[uid] == prev_config_objects[uid]: + member_uids = self.get_members(typ, self.get_refs(typ, current_config_objects[uid])) + flat_member_uids = self.get_flats(typ, uid) + for prev_member_uid in prev_member_uids: + if ( + prev_member_uid in member_uids + and current_config_objects[prev_member_uid] == prev_config_objects[prev_member_uid] + ): + continue # member was not removed or changed + prev_member_id = self.get_id(typ, prev_member_uid, before_update=True) + removed_members.append( + { + "_and": [ + {f"{prefix}_id": {"_eq": db_id}}, + {f"{prefix}_member_id": {"_eq": prev_member_id}}, + ] + } + ) + for prev_flat_member_uid in prev_flat_member_uids: + if ( + prev_flat_member_uid in flat_member_uids + and current_config_objects[prev_flat_member_uid] == prev_config_objects[prev_flat_member_uid] + ): + continue # flat member was not removed or changed + prev_flat_member_id = self.get_id(typ, prev_flat_member_uid, before_update=True) + removed_flats.append( + { + "_and": [ + {f"{prefix}_flat_id": {"_eq": db_id}}, + {f"{prefix}_flat_member_id": {"_eq": prev_flat_member_id}}, + ] + } + ) + + def add_group_memberships(self, prev_config: FwConfigNormalized, obj_type: Type): + """ + Function is used to update group memberships for nwobjs, services or users in the database. + It adds group memberships and flats for new and updated members. + + Args: + prev_config (FwConfigNormalized): The previous normalized config. + + """ + new_group_members: list[dict[str, Any]] = [] + new_group_member_flats: list[dict[str, Any]] = [] + prev_config_objects, current_config_objects = self.get_config_objects(obj_type, prev_config) + prefix = self.get_prefix(obj_type) + for uid in current_config_objects: + if not self.is_group(obj_type, current_config_objects[uid]): + continue + member_uids = self.get_members(obj_type, self.get_refs(obj_type, current_config_objects[uid])) + prev_member_uids = [] # all members need to be added if group added or changed + prev_flat_member_uids = [] + if uid in prev_config_objects and current_config_objects[uid] == prev_config_objects[uid]: + # group not changed -> check for changes in members + prev_member_uids = self.get_members(obj_type, self.get_refs(obj_type, prev_config_objects[uid])) + prev_flat_member_uids = self.get_prev_flats(obj_type, uid) + + group_id = self.get_id(obj_type, uid) + if group_id is None: + FWOLogger.error(f"failed to add group memberships: no id found for group uid '{uid}'") + continue + + self.collect_group_members( + group_id, + current_config_objects, + new_group_members, + member_uids, + obj_type, + prefix, + prev_member_uids, + prev_config_objects, + ) + flat_member_uids = self.get_flats(obj_type, uid) + self.collect_flat_group_members( + group_id, + current_config_objects, + new_group_member_flats, + flat_member_uids, + obj_type, + prefix, + prev_flat_member_uids, + prev_config_objects, + ) + + if len(new_group_members) == 0: + return + + self.write_member_updates(new_group_members, new_group_member_flats, prefix) + + def collect_flat_group_members( + self, + group_id: int, + current_config_objects: dict[str, Any], + new_group_member_flats: list[dict[str, Any]], + flat_member_uids: list[str], + obj_type: Type, + prefix: str, + prev_flat_member_uids: list[str], + prev_config_objects: dict[str, Any], + ): + for flat_member_uid in flat_member_uids: + if ( + flat_member_uid in prev_flat_member_uids + and prev_config_objects[flat_member_uid] == current_config_objects[flat_member_uid] + ): + continue # flat member was not added or changed + flat_member_id = self.get_id(obj_type, flat_member_uid) + new_group_member_flats.append( + { + f"{prefix}_flat_id": group_id, + f"{prefix}_flat_member_id": flat_member_id, + "import_created": self.import_state.state.import_id, + "import_last_seen": self.import_state.state.import_id, # to be removed in the future + } + ) + + def collect_group_members( + self, + group_id: int, + current_config_objects: dict[str, Any], + new_group_members: list[dict[str, Any]], + member_uids: list[str], + obj_type: Type, + prefix: str, + prev_member_uids: list[str], + prev_config_objects: dict[str, Any], + ): + for member_uid in member_uids: + if member_uid in prev_member_uids and prev_config_objects[member_uid] == current_config_objects[member_uid]: + continue # member was not added or changed + member_id = self.get_id(obj_type, member_uid) + new_group_members.append( + { + f"{prefix}_id": group_id, + f"{prefix}_member_id": member_id, + "import_created": self.import_state.state.import_id, + "import_last_seen": self.import_state.state.import_id, # to be removed in the future + } + ) + + def write_member_updates( + self, + new_group_members: list[dict[str, Any]], + new_group_member_flats: list[dict[str, Any]], + prefix: str, + ): + import_mutation = f""" + mutation update{prefix.capitalize()}Groups($groups: [{prefix}_insert_input!]!, $groupFlats: [{prefix}_flat_insert_input!]!) {{ + insert_{prefix}(objects: $groups) {{ + affected_rows + }} + insert_{prefix}_flat(objects: $groupFlats) {{ + affected_rows + }} + }} + """ + query_variables = { + "groups": new_group_members, + "groupFlats": new_group_member_flats, + } + try: + import_result = self.import_state.api_call.call( + import_mutation, query_variables=query_variables, analyze_payload=True + ) + if "errors" in import_result: + FWOLogger.exception(f"fwo_api:addGroupMemberships: {import_result['errors']!s}") + if "duplicate" in import_result["errors"]: + raise FwoDuplicateKeyViolationError(str(import_result["errors"])) + raise FwoImporterError(str(import_result["errors"])) + _ = int(import_result["data"][f"insert_{prefix}"]["affected_rows"]) + int( + import_result["data"][f"insert_{prefix}_flat"]["affected_rows"] + ) + except Exception: + FWOLogger.exception(f"failed to write new objects: {traceback.format_exc()!s}") + raise + + def prepare_changelog_objects( + self, + nw_obj_ids_added: list[dict[str, int]], + svc_obj_ids_added: list[dict[str, int]], + nw_obj_ids_removed: list[dict[str, int]], + svc_obj_ids_removed: list[dict[str, int]], + ) -> tuple[list[dict[str, Any]], list[dict[str, Any]]]: + """ + Insert into stm_change_type (change_type_id,change_type_name) VALUES (1,'factory settings'); + insert into stm_change_type (change_type_id,change_type_name) VALUES (2,'initial import'); + insert into stm_change_type (change_type_id,change_type_name) VALUES (3,'in operation'); + """ + # TODO: deal with object changes where we need old and new obj id + + nw_objs: list[dict[str, Any]] = [] + svc_objs: list[dict[str, Any]] = [] + import_time = datetime.datetime.now().isoformat() + change_typ = 3 # standard + change_logger = ChangeLogger() + + if self.import_state.state.is_initial_import or self.import_state.state.is_clearing_import: + change_typ = 2 # initial - to be ignored in change reports + + # Write changelog for network objects. + + nw_objs = [ + change_logger.create_changelog_import_object( + "obj", self.import_state.state, "I", change_typ, import_time, nw_obj_id + ) + for nw_obj_id in [nw_obj_ids_added_item["obj_id"] for nw_obj_ids_added_item in nw_obj_ids_added] + ] + + nw_objs.extend( + [ + change_logger.create_changelog_import_object( + "obj", + self.import_state.state, + "D", + change_typ, + import_time, + nw_obj_id, + ) + for nw_obj_id in [nw_obj_ids_removed_item["obj_id"] for nw_obj_ids_removed_item in nw_obj_ids_removed] + ] + ) + + for old_nw_obj_id, new_nw_obj_id in change_logger.changed_object_id_map.items(): + nw_objs.append( + change_logger.create_changelog_import_object( + "obj", + self.import_state.state, + "C", + change_typ, + import_time, + new_nw_obj_id, + old_nw_obj_id, + ) + ) + + # Write changelog for Services. + + svc_objs.extend( + [ + change_logger.create_changelog_import_object( + "svc", self.import_state.state, "I", change_typ, import_time, svc_id + ) + for svc_id in [svc_ids_added_item["svc_id"] for svc_ids_added_item in svc_obj_ids_added] + ] + ) + + svc_objs.extend( + [ + change_logger.create_changelog_import_object( + "svc", self.import_state.state, "D", change_typ, import_time, svc_id + ) + for svc_id in [svc_ids_removed_item["svc_id"] for svc_ids_removed_item in svc_obj_ids_removed] + ] + ) + + for old_svc_id, new_svc_id in change_logger.changed_service_id_map.items(): + svc_objs.append( + change_logger.create_changelog_import_object( + "svc", + self.import_state.state, + "C", + change_typ, + import_time, + new_svc_id, + old_svc_id, + ) + ) + + return nw_objs, svc_objs + + def add_changelog_objs( + self, + nwobj_ids_added: list[dict[str, int]], + svc_obj_ids_added: list[dict[str, int]], + nw_obj_ids_removed: list[dict[str, int]], + svc_obj_ids_removed: list[dict[str, int]], + ): + nwobjs_changed, svcobjs_changed = self.prepare_changelog_objects( + nwobj_ids_added, svc_obj_ids_added, nw_obj_ids_removed, svc_obj_ids_removed + ) + changelog_mutation = """ + mutation updateObjChangelogs($nwObjChanges: [changelog_object_insert_input!]!, $svcObjChanges: [changelog_service_insert_input!]!) { + insert_changelog_object(objects: $nwObjChanges) { + affected_rows + } + insert_changelog_service(objects: $svcObjChanges) { + affected_rows + } + } + """ + + query_variables = { + "nwObjChanges": nwobjs_changed, + "svcObjChanges": svcobjs_changed, + } + + if len(nwobjs_changed) + len(svcobjs_changed) > 0: + try: + changelog_result = self.import_state.api_call.call( + changelog_mutation, + query_variables=query_variables, + analyze_payload=True, + ) + if "errors" in changelog_result: + FWOLogger.exception( + f"error while adding changelog entries for objects: {changelog_result['errors']!s}" + ) + except Exception: + FWOLogger.exception( + f"fatal error while adding changelog entries for objects: {traceback.format_exc()!s}" + ) diff --git a/roles/importer/files/importer/model_controllers/fwconfig_import_rollback.py b/roles/importer/files/importer/model_controllers/fwconfig_import_rollback.py new file mode 100644 index 0000000000..9806a33f62 --- /dev/null +++ b/roles/importer/files/importer/model_controllers/fwconfig_import_rollback.py @@ -0,0 +1,35 @@ +import traceback + +import fwo_const +from fwo_api import FwoApi +from fwo_api_call import FwoApiCall +from fwo_log import FWOLogger +from models.import_state import ImportState + + +# this class is used for rolling back an import +class FwConfigImportRollback: + # this function deletes all new entries added in this import + # also resets all entries that have been marked removed + # also deletes latest_config for this management + # TODO: also take super management id into account as second option + + def rollback_current_import(self, import_state: ImportState, fwo_api_call: FwoApiCall): + rollback_mutation = FwoApi.get_graphql_code([f"{fwo_const.GRAPHQL_QUERY_PATH}import/rollbackImport.graphql"]) + try: + query_variables = {"importId": import_state.import_id} + rollback_result = fwo_api_call.call(rollback_mutation, query_variables=query_variables) + if "errors" in rollback_result: + FWOLogger.exception( + "error while trying to roll back current import for mgm id " + + str(import_state.mgm_details.mgm_id) + + ": " + + str(rollback_result["errors"]) + ) + else: + FWOLogger.info("import " + str(import_state.import_id) + " has been rolled back successfully") + + except Exception: + FWOLogger.exception( + f"failed to rollback current import for mgm id {import_state.mgm_details.mgm_id!s}: {traceback.format_exc()!s}" + ) diff --git a/roles/importer/files/importer/model_controllers/fwconfig_import_rule.py b/roles/importer/files/importer/model_controllers/fwconfig_import_rule.py new file mode 100644 index 0000000000..153efc9ca5 --- /dev/null +++ b/roles/importer/files/importer/model_controllers/fwconfig_import_rule.py @@ -0,0 +1,1316 @@ +import json +import traceback +from collections.abc import Callable +from datetime import datetime +from enum import Enum +from typing import Any, TypeVar + +import fwo_const +from fwo_api import FwoApi +from fwo_exceptions import ( + FwoApiWriteError, + FwoImporterError, + FwoImporterErrorInconsistenciesError, +) +from fwo_log import ChangeLogger, FWOLogger +from model_controllers.fwconfig_import_ruleorder import update_rule_order_diffs +from model_controllers.import_state_controller import ImportStateController +from models.fwconfig_normalized import FwConfigNormalized +from models.gateway import Gateway +from models.networkobject import NetworkObject +from models.rule import Rule, RuleNormalized +from models.rule_from import RuleFrom +from models.rule_metadatum import RuleMetadatum +from models.rule_service import RuleService +from models.rule_to import RuleTo +from models.rulebase import Rulebase, RulebaseForImport +from models.serviceobject import ServiceObject +from models.time_object import TimeObject +from services.global_state import GlobalState +from services.group_flats_mapper import GroupFlatsMapper +from services.service_provider import ServiceProvider +from services.uid2id_mapper import Uid2IdMapper + + +class RefType(Enum): + SRC = "rule_from" + DST = "rule_to" + SVC = "rule_service" + NWOBJ_RESOLVED = "rule_nwobj_resolved" + SVC_RESOLVED = "rule_svc_resolved" + USER_RESOLVED = "rule_user_resolved" + SRC_ZONE = "rule_from_zone" + DST_ZONE = "rule_to_zone" + TIME = "rule_time" + + +# this class is used for importing rules and rule refs into the FWO API +class FwConfigImportRule: + global_state: GlobalState + import_details: ImportStateController + normalized_config: FwConfigNormalized | None = None + uid2id_mapper: Uid2IdMapper + group_flats_mapper: GroupFlatsMapper + prev_group_flats_mapper: GroupFlatsMapper + + def __init__(self): + service_provider = ServiceProvider() + self.global_state = service_provider.get_global_state() + self.import_details = self.global_state.import_state + # TODO: why is there a state where this is initialized with normalized_config = None? - see #3154 + self.normalized_config = self.global_state.normalized_config + self.uid2id_mapper = service_provider.get_uid2id_mapper(self.import_details.state.import_id) + self.group_flats_mapper = service_provider.get_group_flats_mapper(self.import_details.state.import_id) + self.prev_group_flats_mapper = service_provider.get_prev_group_flats_mapper(self.import_details.state.import_id) + + def update_rulebase_diffs(self, prev_config: FwConfigNormalized) -> None: + if self.normalized_config is None: + raise FwoImporterError("cannot update rulebase diffs: normalized_config is None") + + # set rule_num_numeric values based on rule order changes and moves. needs to be done + # before any other processing to have the correct rule numbers available for all following steps + update_rule_order_diffs(prev_config, self.normalized_config) + + # collect rules with rulebase information for diffing, rule_uid -> (rule, rulebase_uid) + prev_rules: dict[str, RuleNormalized] = { + rule_uid: rule for rb in prev_config.rulebases for rule_uid, rule in rb.rules.items() + } + prev_rule_to_rulebase: dict[str, str] = { + rule_uid: rb.uid for rb in prev_config.rulebases for rule_uid in rb.rules + } + curr_rules: dict[str, RuleNormalized] = { + rule_uid: rule for rb in self.normalized_config.rulebases for rule_uid, rule in rb.rules.items() + } + curr_rule_to_rulebase: dict[str, str] = { + rule_uid: rb.uid for rb in self.normalized_config.rulebases for rule_uid in rb.rules + } + + ( + added_rule_uids, + removed_rule_uids, + changed_rule_uids, + ) = self.get_all_rule_diffs(prev_rules, curr_rules, prev_rule_to_rulebase, curr_rule_to_rulebase) + + # collect hit information for all rules with hit data + new_hit_information: list[dict[str, Any]] = [] + self.collect_all_hit_information(prev_config, new_hit_information) + + # update rule_metadata before adding rules + _, _ = self.add_new_rule_metadata([curr_rules[rule_uid] for rule_uid in added_rule_uids]) + self.update_rule_metadata_last_hit(new_hit_information) + + # fetch initial rule and rulebase ids + self.uid2id_mapper.update_rule_mapping() + self.uid2id_mapper.update_rulebase_mapping() + + # add new rulebases + new_rulebases = [ + rb + for rb in self.normalized_config.rulebases + if rb.uid not in {prev_rb.uid for prev_rb in prev_config.rulebases} + ] + num_added_rulebases, new_rulebase_ids = self.add_new_rulebases(new_rulebases) + self.uid2id_mapper.add_rulebase_mappings(new_rulebase_ids) + + num_inserted_rules, inserted_rule_ids = self.add_new_rules( + { + rule_uid: (curr_rules[rule_uid], curr_rule_to_rulebase[rule_uid]) + for rule_uid in (added_rule_uids | changed_rule_uids) + } + ) + + self.uid2id_mapper.add_rule_mappings(inserted_rule_ids) + refs_added = self.add_new_refs(prev_config) + + num_set_removed_rules, _removed_rule_ids = self.mark_rules_removed(list(removed_rule_uids | changed_rule_uids)) + # remove old rulebases + removed_rulebase_uids = [ + prev_rb.uid + for prev_rb in prev_config.rulebases + if prev_rb.uid not in {rb.uid for rb in self.normalized_config.rulebases} + ] + num_deleted_rulebases = self.mark_rulebases_removed(removed_rulebase_uids) + refs_removed = self.remove_outdated_refs(prev_config) + + rule_to_gw_refs_added, rule_to_gw_refs_removed = self.update_rule_enforced_on_gateway(changed_rule_uids) + + self.write_changelog_rules( + [curr_rules[rule_uid] for rule_uid in added_rule_uids], + [prev_rules[rule_uid] for rule_uid in removed_rule_uids], + [(prev_rules[rule_uid], curr_rules[rule_uid]) for rule_uid in changed_rule_uids], + ) + + num_moved_rules = self.count_moved_rules( + {rule_uid: (prev_rules[rule_uid], prev_rule_to_rulebase[rule_uid]) for rule_uid in changed_rule_uids}, + {rule_uid: (curr_rules[rule_uid], curr_rule_to_rulebase[rule_uid]) for rule_uid in changed_rule_uids}, + ) + num_added_rules = len(added_rule_uids) + num_removed_rules = len(removed_rule_uids) + num_changed_rules = len(changed_rule_uids) + + self.import_details.state.stats.increment_rulebase_add_count(num_added_rulebases) + self.import_details.state.stats.increment_rulebase_delete_count(num_deleted_rulebases) + self.import_details.state.stats.increment_rule_add_count(num_added_rules) + self.import_details.state.stats.increment_rule_delete_count(num_removed_rules) + self.import_details.state.stats.increment_rule_move_count(num_moved_rules) + self.import_details.state.stats.increment_rule_change_count(num_changed_rules) + self.import_details.state.stats.increment_rule_ref_add_count(refs_added + rule_to_gw_refs_added) + self.import_details.state.stats.increment_rule_ref_delete_count(refs_removed + rule_to_gw_refs_removed) + + # change counts returned from db mutations should match counts calculated from diffs, if not log a warning + if num_inserted_rules != len(added_rule_uids) + len(changed_rule_uids): + FWOLogger.warning( + f"Number of inserted rules ({num_inserted_rules}) does not match number of added + changed rules ({len(added_rule_uids) + len(changed_rule_uids)} = {len(added_rule_uids)} + {len(changed_rule_uids)})" + ) + if num_set_removed_rules != len(removed_rule_uids) + len(changed_rule_uids): + FWOLogger.warning( + f"Number of removed rules ({num_set_removed_rules}) does not match number of removed + changed rules ({len(removed_rule_uids) + len(changed_rule_uids)} = {len(removed_rule_uids)} + {len(changed_rule_uids)})" + ) + + def get_all_rule_diffs( + self, + prev_rules: dict[str, RuleNormalized], + curr_rules: dict[str, RuleNormalized], + prev_rule_to_rulebase: dict[str, str], + curr_rule_to_rulebase: dict[str, str], + ) -> tuple[set[str], set[str], set[str]]: + """ + Get all rule differences between previous and current config. + + Args: + prev_rules: Dictionary of rule_uid to RuleNormalized for previous config + curr_rules: Dictionary of rule_uid to RuleNormalized for current config + prev_rule_to_rulebase: Mapping of rule_uid to rulebase_uid for previous config + curr_rule_to_rulebase: Mapping of rule_uid to rulebase_uid for current config + + Returns: + added_rule_uids: Set of rule_uids for new rules + removed_rule_uids: Set of rule_uids for removed rules + changed_rule_uids: Set of rule_uids for rules that exist in both configs but have changes + + """ + changed_rule_uids: set[str] = set() + + if self.normalized_config is None: + raise FwoImporterError("cannot get rule diffs: normalized_config is None") + + added_rule_uids = set(curr_rules.keys()) - set(prev_rules.keys()) + removed_rule_uids = set(prev_rules.keys()) - set(curr_rules.keys()) + for rule_uid in set(curr_rules.keys()) & set(prev_rules.keys()): + curr_rule = curr_rules[rule_uid] + prev_rule = prev_rules[rule_uid] + curr_rb_uid = curr_rule_to_rulebase.get(rule_uid) + prev_rb_uid = prev_rule_to_rulebase.get(rule_uid) + if curr_rule != prev_rule or curr_rb_uid != prev_rb_uid: + changed_rule_uids.add(rule_uid) + + return added_rule_uids, removed_rule_uids, changed_rule_uids + + def collect_all_hit_information(self, prev_config: FwConfigNormalized, new_hit_information: list[dict[str, Any]]): + """ + Consolidated hit information collection for ALL rules that need hit updates. + + Args: + prev_config: Previous configuration for comparison + new_hit_information: List to append hit update information to + + """ + processed_rules: set[str] = set() + + def add_hit_update(new_hit_information: list[dict[str, Any]], rule: RuleNormalized): + """Add a hit information update entry for a rule.""" + new_hit_information.append( + { + "where": { + "rule_uid": {"_eq": rule.rule_uid}, + "mgm_id": {"_eq": self.import_details.state.mgm_details.current_mgm_id}, + }, + "_set": {"rule_last_hit": rule.last_hit}, + } + ) + + # check all rulebases in current config + if self.normalized_config is None: + raise FwoImporterError("cannot collect hit information: normalized_config is None") + + for current_rulebase in self.normalized_config.rulebases: + previous_rulebase = prev_config.get_rulebase_or_none(current_rulebase.uid) + + for rule_uid in current_rulebase.rules: + current_rule = current_rulebase.rules[rule_uid] + previous_rule = previous_rulebase.rules.get(rule_uid) if previous_rulebase else None + + if current_rule.last_hit is None: + continue # No hit information to update + + if previous_rule is None or (current_rule.last_hit != previous_rule.last_hit): + # rulebase or rule is new or hit information changed + add_hit_update(new_hit_information, current_rule) + processed_rules.add(rule_uid) + + def update_rule_metadata_last_hit(self, new_hit_information: list[dict[str, Any]]): + """ + Updates rule_metadata.rule_last_hit for all rules with hit information changes. + This method executes the actual database updates for hit information. + + Args: + new_hit_information (list[dict]): The hit information to update. + + """ + if len(new_hit_information) > 0: + update_last_hit_mutation = FwoApi.get_graphql_code( + [fwo_const.GRAPHQL_QUERY_PATH + "rule_metadata/updateLastHits.graphql"] + ) + query_variables = {"hit_info": new_hit_information} + + try: + import_result = self.import_details.api_call.call( + update_last_hit_mutation, + query_variables=query_variables, + analyze_payload=True, + ) + if "errors" in import_result: + FWOLogger.exception( + f"fwo_api:importNwObject - error in addNewRuleMetadata: {import_result['errors']!s}" + ) + # do not count last hit changes as changes here + except Exception: + raise FwoApiWriteError(f"failed to update RuleMetadata last hit info: {traceback.format_exc()!s}") + + def get_rule_refs( + self, rule: RuleNormalized, is_prev: bool = False + ) -> dict[RefType, list[tuple[str, str | None]] | list[str]]: + froms: list[tuple[str, str | None]] = [] + tos: list[tuple[str, str | None]] = [] + users: list[str] = [] + nwobj_resolveds = [] + svc_resolveds = [] + user_resolveds = [] + from_zones = [] + to_zones = [] + for refs in rule.rule_src_refs.split(fwo_const.LIST_DELIMITER): + user_ref = None + if fwo_const.USER_DELIMITER in refs: + src_ref, user_ref = refs.split(fwo_const.USER_DELIMITER) + users.append(user_ref) + else: + src_ref = refs + froms.append((src_ref, user_ref)) + for refs in rule.rule_dst_refs.split(fwo_const.LIST_DELIMITER): + user_ref = None + if fwo_const.USER_DELIMITER in refs: + dst_ref, user_ref = refs.split(fwo_const.USER_DELIMITER) + users.append(user_ref) + else: + dst_ref = refs + tos.append((dst_ref, user_ref)) + svcs = rule.rule_svc_refs.split(fwo_const.LIST_DELIMITER) + if is_prev: + nwobj_resolveds = self.prev_group_flats_mapper.get_network_object_flats([ref[0] for ref in froms + tos]) + svc_resolveds = self.prev_group_flats_mapper.get_service_object_flats(svcs) + user_resolveds = self.prev_group_flats_mapper.get_user_flats(users) + else: + nwobj_resolveds = self.group_flats_mapper.get_network_object_flats([ref[0] for ref in froms + tos]) + svc_resolveds = self.group_flats_mapper.get_service_object_flats(svcs) + user_resolveds = self.group_flats_mapper.get_user_flats(users) + from_zones = rule.rule_src_zone.split(fwo_const.LIST_DELIMITER) if rule.rule_src_zone else [] + to_zones = rule.rule_dst_zone.split(fwo_const.LIST_DELIMITER) if rule.rule_dst_zone else [] + times = rule.rule_time.split(fwo_const.LIST_DELIMITER) if rule.rule_time else [] + return { + RefType.SRC: froms, + RefType.DST: tos, + RefType.SVC: svcs, + RefType.NWOBJ_RESOLVED: nwobj_resolveds, + RefType.SVC_RESOLVED: svc_resolveds, + RefType.USER_RESOLVED: user_resolveds, + RefType.SRC_ZONE: from_zones, + RefType.DST_ZONE: to_zones, + RefType.TIME: times, + } + + T = TypeVar("T") + + def _lookup_object( + self, + uid: str, + previous: bool, + config_accessor: Callable[[FwConfigNormalized], dict[str, T]], + object_type_name: str, + ) -> T: + """Generic object lookup from config with fallback to global config.""" + config = self.global_state.previous_config if previous else self.normalized_config + global_config = ( + self.global_state.previous_global_config if previous else self.global_state.global_normalized_config + ) + config_type = "previous" if previous else "current" + + if config is None: + raise FwoImporterError(f"cannot lookup {object_type_name}: {config_type} config is None") + + obj = config_accessor(config).get(uid, None) + if obj is None: + # try lookup in global config + if global_config is None: + raise FwoImporterError(f"{object_type_name} not found in {config_type} config: {uid}") + obj = config_accessor(global_config).get(uid, None) + if obj is None: + raise FwoImporterError( + f"{object_type_name} not found in {config_type} config and {config_type} global config: {uid}" + ) + return obj + + def lookup_network_object(self, uid: str, previous: bool = False) -> NetworkObject: + return self._lookup_object(uid, previous, lambda cfg: cfg.network_objects, "network object") + + def lookup_service_object(self, uid: str, previous: bool = False) -> ServiceObject: + return self._lookup_object(uid, previous, lambda cfg: cfg.service_objects, "service object") + + def lookup_user(self, uid: str, previous: bool = False) -> dict[str, Any]: + return self._lookup_object(uid, previous, lambda cfg: cfg.users, "user") + + def lookup_zone(self, uid: str, previous: bool = False) -> dict[str, Any]: + return self._lookup_object(uid, previous, lambda cfg: cfg.zone_objects, "zone") + + def lookup_time(self, uid: str, previous: bool = False) -> TimeObject: + return self._lookup_object(uid, previous, lambda cfg: cfg.time_objects, "time object") + + def is_ref_unchanged(self, ref_type: RefType, ref_uid: tuple[str, str | None] | str) -> bool: + """ + Check if a reference object is unchanged between previous and current config. + + Returns True if the object is the same in both configs, False if it changed. + """ + if ref_type in (RefType.SRC, RefType.DST): + if not isinstance(ref_uid, tuple) or len(ref_uid) != 2: # noqa: PLR2004 + raise TypeError( + f"ref_uid for {ref_type.name} must be a tuple of length 2, not {type(ref_uid).__name__}" + ) + nwobj_uid, user_uid = ref_uid + prev_nwobj = self.lookup_network_object(nwobj_uid, previous=True) + curr_nwobj = self.lookup_network_object(nwobj_uid, previous=False) + prev_user = self.lookup_user(user_uid, previous=True) if user_uid else None + curr_user = self.lookup_user(user_uid, previous=False) if user_uid else None + return (prev_nwobj, prev_user) == (curr_nwobj, curr_user) + + if not isinstance(ref_uid, str): + raise TypeError(f"ref_uid must be str, not {type(ref_uid).__name__}") + + if ref_type == RefType.NWOBJ_RESOLVED: + return self.lookup_network_object(ref_uid, previous=True) == self.lookup_network_object( + ref_uid, previous=False + ) + if ref_type in (RefType.SVC, RefType.SVC_RESOLVED): + return self.lookup_service_object(ref_uid, previous=True) == self.lookup_service_object( + ref_uid, previous=False + ) + if ref_type == RefType.USER_RESOLVED: + return self.lookup_user(ref_uid, previous=True) == self.lookup_user(ref_uid, previous=False) + if ref_type in (RefType.SRC_ZONE, RefType.DST_ZONE): + return self.lookup_zone(ref_uid, previous=True) == self.lookup_zone(ref_uid, previous=False) + if ref_type == RefType.TIME: + return self.lookup_time(ref_uid, previous=True) == self.lookup_time(ref_uid, previous=False) + + raise FwoImporterError(f"unknown ref type: {ref_type}") + + def get_ref_remove_statement( + self, ref_type: RefType, rule_uid: str, ref_uid: tuple[str, str | None] | str + ) -> dict[str, Any]: + if ref_type in (RefType.SRC, RefType.DST): + nwobj_uid, user_uid = ref_uid + statement = { + "_and": [ + {"rule_id": {"_eq": self.uid2id_mapper.get_rule_id(rule_uid, before_update=True)}}, + {"obj_id": {"_eq": self.uid2id_mapper.get_network_object_id(nwobj_uid, before_update=True)}}, + ] + } + if user_uid: + statement["_and"].append( + {"user_id": {"_eq": self.uid2id_mapper.get_user_id(user_uid, before_update=True)}} + ) + else: + statement["_and"].append({"user_id": {"_is_null": True}}) + return statement + if ref_type in (RefType.SVC, RefType.SVC_RESOLVED): + return { + "_and": [ + {"rule_id": {"_eq": self.uid2id_mapper.get_rule_id(rule_uid, before_update=True)}}, + {"svc_id": {"_eq": self.uid2id_mapper.get_service_object_id(ref_uid, before_update=True)}}, # type: ignore # ref_uid is str here # noqa: PGH003 + ] + } + if ref_type == RefType.NWOBJ_RESOLVED: + return { + "_and": [ + {"rule_id": {"_eq": self.uid2id_mapper.get_rule_id(rule_uid, before_update=True)}}, + {"obj_id": {"_eq": self.uid2id_mapper.get_network_object_id(ref_uid, before_update=True)}}, # type: ignore # ref_uid is str here # noqa: PGH003 + ] + } + if ref_type == RefType.USER_RESOLVED: + return { + "_and": [ + {"rule_id": {"_eq": self.uid2id_mapper.get_rule_id(rule_uid, before_update=True)}}, + {"user_id": {"_eq": self.uid2id_mapper.get_user_id(ref_uid, before_update=True)}}, # type: ignore # ref_uid is str here # noqa: PGH003 + ] + } + if ref_type in (RefType.SRC_ZONE, RefType.DST_ZONE): + return { + "_and": [ + {"rule_id": {"_eq": self.uid2id_mapper.get_rule_id(rule_uid, before_update=True)}}, + {"zone_id": {"_eq": self.uid2id_mapper.get_zone_object_id(ref_uid, before_update=True)}}, # type: ignore # ref_uid is str here TODO: Cleanup ref_uid dict # noqa: PGH003 + ] + } + if ref_type == RefType.TIME: + return { + "_and": [ + {"rule_id": {"_eq": self.uid2id_mapper.get_rule_id(rule_uid, before_update=True)}}, + {"time_obj_id": {"_eq": self.uid2id_mapper.get_time_object_id(ref_uid, before_update=True)}}, # type: ignore # ref_uid is str here TODO: Cleanup ref_uid dict # noqa: PGH003 + ] + } + raise FwoImporterError(f"unknown ref type: {ref_type}") + + def get_outdated_refs_to_remove( + self, prev_rule: RuleNormalized, rule: RuleNormalized | None, remove_all: bool + ) -> dict[RefType, list[dict[str, Any]]]: + """ + Get the references that need to be removed for a rule based on comparison with the previous rule. + + Args: + prev_rule (RuleNormalized): The previous version of the rule. + rule (RuleNormalized | None): The current version of the rule. + remove_all (bool): If True, all references will be removed. If False, it will check for changes in references that need to be removed. + + """ + ref_uids: dict[RefType, list[tuple[str, str | None]] | list[str]] = {ref_type: [] for ref_type in RefType} + + if not remove_all and rule is not None: + ref_uids = self.get_rule_refs(rule) + prev_ref_uids = self.get_rule_refs(prev_rule, is_prev=True) + refs_to_remove: dict[RefType, list[dict[str, Any]]] = {} + for ref_type in RefType: + refs_to_remove[ref_type] = [] + for prev_ref_uid in prev_ref_uids[ref_type]: + if prev_ref_uid in ref_uids[ref_type] and self.is_ref_unchanged(ref_type, prev_ref_uid): + continue # ref not removed or changed + # ref removed or changed + if prev_rule.rule_uid is None: + raise FwoImporterError( + f"previous reference UID is None: {prev_ref_uid} in rule {prev_rule.rule_uid}" + ) + refs_to_remove[ref_type].append( + self.get_ref_remove_statement(ref_type, prev_rule.rule_uid, prev_ref_uid) + ) + return refs_to_remove + + def get_refs_to_remove(self, prev_config: FwConfigNormalized) -> dict[RefType, list[dict[str, Any]]]: + all_refs_to_remove: dict[RefType, list[dict[str, Any]]] = {ref_type: [] for ref_type in RefType} + if self.normalized_config is None: + raise FwoImporterError("cannot remove outdated refs: normalized_config is None") + for prev_rulebase in prev_config.rulebases: + rules: dict[str, RuleNormalized] = {} + rules = next( + (rb.rules for rb in self.normalized_config.rulebases if rb.uid == prev_rulebase.uid), + rules, + ) + for prev_rule in prev_rulebase.rules.values(): + uid = prev_rule.rule_uid + if uid is None: + raise FwoImporterError(f"rule UID is None: {prev_rule} in rulebase {prev_rulebase.name}") + rule_removed_or_changed = ( + uid not in rules or prev_rule != rules[uid] + ) # rule removed or changed -> all refs need to be removed + rule_refs_to_remove = self.get_outdated_refs_to_remove( + prev_rule, rules.get(uid, None), rule_removed_or_changed + ) + for ref_type, ref_statements in rule_refs_to_remove.items(): + all_refs_to_remove[ref_type].extend(ref_statements) + return all_refs_to_remove + + def remove_outdated_refs(self, prev_config: FwConfigNormalized) -> int: + """ + Remove all types of outdated rule references based on comparison with the previous configuration. This includes + source, destination, service, resolved network object, resolved service, resolved user, source zone, and + destination zone references. + """ + all_refs_to_remove = self.get_refs_to_remove(prev_config) + + if not any(all_refs_to_remove.values()): + return 0 + + import_mutation = FwoApi.get_graphql_code([fwo_const.GRAPHQL_QUERY_PATH + "rule/updateRuleRefs.graphql"]) + + query_variables: dict[str, Any] = { + "importId": self.import_details.state.import_id, + "ruleFroms": all_refs_to_remove[RefType.SRC], + "ruleTos": all_refs_to_remove[RefType.DST], + "ruleServices": all_refs_to_remove[RefType.SVC], + "ruleNwObjResolveds": all_refs_to_remove[RefType.NWOBJ_RESOLVED], + "ruleSvcResolveds": all_refs_to_remove[RefType.SVC_RESOLVED], + "ruleUserResolveds": all_refs_to_remove[RefType.USER_RESOLVED], + "ruleFromZones": all_refs_to_remove[RefType.SRC_ZONE], + "ruleToZones": all_refs_to_remove[RefType.DST_ZONE], + "ruleTimes": all_refs_to_remove[RefType.TIME], + } + + try: + import_result = self.import_details.api_call.call( + import_mutation, query_variables=query_variables, analyze_payload=True + ) + if "errors" in import_result: + FWOLogger.error(f"failed to remove outdated rule references: {import_result['errors']!s}") + raise FwoApiWriteError(f"failed to remove outdated rule references: {import_result['errors']!s}") + return sum( + import_result["data"][f"update_{ref_type.value}"].get("affected_rows", 0) for ref_type in RefType + ) + except Exception: + raise FwoApiWriteError(f"failed to remove outdated rule references: {traceback.format_exc()!s}") + + def get_ref_add_statement( + self, + ref_type: RefType, + rule: RuleNormalized, + ref_uid: tuple[str, str | None] | str, + ) -> dict[str, Any]: + if rule.rule_uid is None: + raise FwoImporterError( + f"rule UID is None: {rule} in rulebase during get_ref_add_statement" + ) # should not happen + + import_id = self.import_details.state.import_id + mgm_id = self.import_details.state.mgm_details.current_mgm_id + + if ref_type == RefType.SRC: + nwobj_uid, user_uid = ref_uid + _ = self.uid2id_mapper.get_network_object_id(nwobj_uid) # check if nwobj exists + return RuleFrom( + rule_id=self.uid2id_mapper.get_rule_id(rule.rule_uid), + obj_id=self.uid2id_mapper.get_network_object_id(nwobj_uid), + user_id=self.uid2id_mapper.get_user_id(user_uid) if user_uid else None, + rf_create=import_id, + rf_last_seen=import_id, # TODO: to be removed in the future + negated=rule.rule_src_neg, + ).model_dump() + if ref_type == RefType.DST: + nwobj_uid, user_uid = ref_uid + return RuleTo( + rule_id=self.uid2id_mapper.get_rule_id(rule.rule_uid), + obj_id=self.uid2id_mapper.get_network_object_id(nwobj_uid), + user_id=self.uid2id_mapper.get_user_id(user_uid) if user_uid else None, + rt_create=import_id, + rt_last_seen=import_id, # TODO: to be removed in the future + negated=rule.rule_dst_neg, + ).model_dump() + if ref_type == RefType.SVC: + return RuleService( + rule_id=self.uid2id_mapper.get_rule_id(rule.rule_uid), + svc_id=self.uid2id_mapper.get_service_object_id(ref_uid), # type: ignore # ref_uid is str here TODO: Cleanup ref_uid dict # noqa: PGH003 + rs_create=import_id, + rs_last_seen=import_id, # TODO: to be removed in the future + ).model_dump() + if ref_type == RefType.NWOBJ_RESOLVED: + return { + "mgm_id": mgm_id, + "rule_id": self.uid2id_mapper.get_rule_id(rule.rule_uid), + "obj_id": self.uid2id_mapper.get_network_object_id(ref_uid), # type: ignore # ref_uid is str here TODO: Cleanup ref_uid dict # noqa: PGH003 + "created": import_id, + } + if ref_type == RefType.SVC_RESOLVED: + return { + "mgm_id": mgm_id, + "rule_id": self.uid2id_mapper.get_rule_id(rule.rule_uid), + "svc_id": self.uid2id_mapper.get_service_object_id(ref_uid), # type: ignore # ref_uid is str here TODO: Cleanup ref_uid dict # noqa: PGH003 + "created": import_id, + } + if ref_type == RefType.USER_RESOLVED: + return { + "mgm_id": mgm_id, + "rule_id": self.uid2id_mapper.get_rule_id(rule.rule_uid), + "user_id": self.uid2id_mapper.get_user_id(ref_uid), # type: ignore # ref_uid is str here TODO: Cleanup ref_uid dict # noqa: PGH003 + "created": import_id, + } + if ref_type in (RefType.SRC_ZONE, RefType.DST_ZONE): + return { + "rule_id": self.uid2id_mapper.get_rule_id(rule.rule_uid), + "zone_id": self.uid2id_mapper.get_zone_object_id(ref_uid), # type: ignore # ref_uid is str here TODO: Cleanup ref_uid dict # noqa: PGH003 + "created": import_id, + } + if ref_type == RefType.TIME: + return { + "rule_id": self.uid2id_mapper.get_rule_id(rule.rule_uid), + "time_obj_id": self.uid2id_mapper.get_time_object_id(ref_uid), # type: ignore # ref_uid is str here TODO: Cleanup ref_uid dict # noqa: PGH003 + "created": import_id, + } + return None + + def get_new_refs_to_add( + self, rule: RuleNormalized, prev_rule: RuleNormalized | None, add_all: bool + ) -> dict[RefType, list[dict[str, Any]]]: + """ + Get the references that need to be added for a rule based on comparison with the previous rule. + + Args: + rule (RuleNormalized): The current version of the rule. + prev_rule (RuleNormalized): The previous version of the rule. + add_all (bool): If True, all references will be added. If False, it will check for changes in references that need to be added. + + """ + prev_ref_uids: dict[RefType, list[tuple[str, str | None]] | list[str]] = {ref_type: [] for ref_type in RefType} + if not add_all and prev_rule is not None: + prev_ref_uids = self.get_rule_refs(prev_rule, is_prev=True) + ref_uids = self.get_rule_refs(rule) + refs_to_add: dict[RefType, list[dict[str, Any]]] = {} + for ref_type in RefType: + refs_to_add[ref_type] = [] + for ref_uid in ref_uids[ref_type]: + if ref_uid in prev_ref_uids[ref_type] and self.is_ref_unchanged(ref_type, ref_uid): + continue # ref not added or changed + # ref added or changed + refs_to_add[ref_type].append(self.get_ref_add_statement(ref_type, rule, ref_uid)) + return refs_to_add + + def add_new_refs(self, prev_config: FwConfigNormalized) -> int: + """ + Add all types of new references for all rules compared to the previous config. This includes source, destination, + service, resolved network objects, resolved services, resolved users, source zones, and destination zones + + Args: + prev_config (FwConfigNormalized): The previous configuration for comparison. + + Returns: + int: The total number of references added. + + """ + all_refs_to_add: dict[RefType, list[dict[str, Any]]] = {ref_type: [] for ref_type in RefType} + if self.normalized_config is None: + raise FwoImporterError("cannot add new refs: normalized_config is None") + for rulebase in self.normalized_config.rulebases: + prev_rules: dict[str, RuleNormalized] = {} + prev_rules = next( + (rb.rules for rb in prev_config.rulebases if rb.uid == rulebase.uid), + prev_rules, + ) + for rule in rulebase.rules.values(): + uid = rule.rule_uid + if uid is None: + raise FwoImporterError(f"rule UID is None: {rule} in rulebase {rulebase.name}") + rule_added_or_changed = ( + uid not in prev_rules or rule != prev_rules[uid] + ) # rule added or changed -> all refs need to be added + rule_refs_to_add = self.get_new_refs_to_add(rule, prev_rules.get(uid, None), rule_added_or_changed) + for ref_type, ref_statements in rule_refs_to_add.items(): + all_refs_to_add[ref_type].extend(ref_statements) + + if not any(all_refs_to_add.values()): + return 0 + + import_mutation = FwoApi.get_graphql_code([fwo_const.GRAPHQL_QUERY_PATH + "rule/insertRuleRefs.graphql"]) + query_variables = { + "ruleFroms": all_refs_to_add[RefType.SRC], + "ruleTos": all_refs_to_add[RefType.DST], + "ruleServices": all_refs_to_add[RefType.SVC], + "ruleNwObjResolveds": all_refs_to_add[RefType.NWOBJ_RESOLVED], + "ruleSvcResolveds": all_refs_to_add[RefType.SVC_RESOLVED], + "ruleUserResolveds": all_refs_to_add[RefType.USER_RESOLVED], + "ruleFromZones": all_refs_to_add[RefType.SRC_ZONE], + "ruleToZones": all_refs_to_add[RefType.DST_ZONE], + "ruleTimes": all_refs_to_add[RefType.TIME], + } + + try: + import_result = self.import_details.api_call.call( + import_mutation, query_variables=query_variables, analyze_payload=True + ) + except Exception: + raise FwoApiWriteError(f"failed to add new rule references: {traceback.format_exc()!s}") + if "errors" in import_result: + raise FwoApiWriteError(f"failed to add new rule references: {import_result['errors']!s}") + return sum(import_result["data"][f"insert_{ref_type.value}"].get("affected_rows", 0) for ref_type in RefType) + + # adds new rule_metadatum to the database + def add_new_rule_metadata(self, new_rules: list[RuleNormalized]) -> tuple[int, list[int]]: + """ + Adds new rule metadata entries for the given rules. + + Args: + new_rules (list[RuleNormalized]): List of RuleNormalized objects for new rules. + + Returns: + tuple[int, list[int]]: A tuple containing the number of changes made and a list of newly added rule metadata IDs. + + """ + changes: int = 0 + new_rule_ids: list[int] = [] + + add_new_rule_metadata_mutation = """mutation upsertRuleMetadata($ruleMetadata: [rule_metadata_insert_input!]!) { + insert_rule_metadata(objects: $ruleMetadata, on_conflict: {constraint: rule_metadata_mgm_id_rule_uid_unique, update_columns: []}) { + affected_rows + returning { + rule_metadata_id + } + } + } + """ + + add_new_rule_metadata: list[dict[str, Any]] = self.prepare_new_rule_metadata(new_rules) + query_variables = {"ruleMetadata": add_new_rule_metadata} + + FWOLogger.debug(json.dumps(query_variables), 10) # just for debugging purposes + + try: + import_result = self.import_details.api_call.call( + add_new_rule_metadata_mutation, + query_variables=query_variables, + analyze_payload=True, + ) + except Exception: + raise FwoApiWriteError(f"failed to write new RulesMetadata: {traceback.format_exc()!s}") + if "errors" in import_result: + raise FwoApiWriteError(f"failed to write new RulesMetadata: {import_result['errors']!s}") + # reduce change number by number of rulebases + changes = import_result["data"]["insert_rule_metadata"]["affected_rows"] + + return changes, new_rule_ids + + def add_new_rules(self, rules: dict[str, tuple[RuleNormalized, str]]) -> tuple[int, list[dict[str, Any]]]: + """ + Insert new and changed rules into the database and return the number of changes and the new rule IDs. + + Args: + rules (dict[str, tuple[RuleNormalized, str]]): Dictionary mapping rule_uid to a tuple of RuleNormalized and rulebase_uid. + + Returns: + tuple[int, list[dict]]: A tuple containing the number of changes made and a list of dictionaries, + each with 'rule_id' and 'rule_uid' for each newly added rule. + + """ + changes: int = 0 + new_rule_ids: list[dict[str, Any]] = [] + + upsert_rules = """mutation upsertRules($rules: [rule_insert_input!]!) { + insert_rule( + objects: $rules, + ) { + affected_rows, + returning { + rule_id, + rule_uid + } + } + } + """ + new_rules: list[Rule] = [ + self.prepare_rule_for_import(rule, rulebase_uid) for _rule_uid, (rule, rulebase_uid) in rules.items() + ] + if len(new_rules) > 0: + query_variables = {"rules": [rule.model_dump() for rule in new_rules]} + try: + import_result = self.import_details.api_call.call( + upsert_rules, query_variables=query_variables, analyze_payload=True + ) + except Exception: + FWOLogger.exception( + f"fwo_api:addRulesWithinRulebases - error in addRulesWithinRulebases: {traceback.format_exc()!s}" + ) + raise FwoApiWriteError(f"failed to write new rules: {traceback.format_exc()!s}") + if "errors" in import_result: + FWOLogger.exception( + f"fwo_api:addRulesWithinRulebases - error in addRulesWithinRulebases: {import_result['errors']!s}" + ) + raise FwoApiWriteError(f"failed to write new rules: {import_result['errors']!s}") + changes += import_result["data"]["insert_rule"]["affected_rows"] + new_rule_ids += import_result["data"]["insert_rule"]["returning"] + return changes, new_rule_ids + + def add_new_rulebases(self, new_rulebases: list[Rulebase]) -> tuple[int, list[dict[str, Any]]]: + """ + Adds new rulebases to the database without adding their rules. + + Args: + new_rulebases (list[Rulebase]): A list of Rulebase objects to be added. + + Returns: + tuple[int, list[dict[str, Any]]]: A tuple containing the number of changes made and a list of dictionaries, + each with 'uid' and 'id' for each newly added rulebase. + + """ + add_rulebases_without_rules_mutation = """mutation upsertRulebaseWithoutRules($rulebases: [rulebase_insert_input!]!) { + insert_rulebase( + objects: $rulebases, + ) { + affected_rows, + returning { uid, id } + } + } + """ + + new_rulebases_for_import = [ + RulebaseForImport.from_rulebase( + rb, + self.import_details.state.mgm_details.current_mgm_id, + self.import_details.state.import_id, + ) + for rb in new_rulebases + ] + query_variables = {"rulebases": [rb.model_dump(by_alias=True) for rb in new_rulebases_for_import]} + + try: + import_result = self.import_details.api_call.call( + add_rulebases_without_rules_mutation, + query_variables=query_variables, + analyze_payload=True, + ) + except Exception: + FWOLogger.exception(f"fwo_api:importRules - error in addNewRulebases: {traceback.format_exc()!s}") + raise FwoApiWriteError(f"failed to write new rulebases: {traceback.format_exc()!s}") + if "errors" in import_result: + FWOLogger.exception(f"fwo_api:importRules - error in addNewRulebases: {import_result['errors']!s}") + raise FwoApiWriteError(f"failed to write new rulebases: {import_result['errors']!s}") + + return import_result["data"]["insert_rulebase"]["affected_rows"], import_result["data"]["insert_rulebase"][ + "returning" + ] + + def prepare_new_rule_metadata(self, new_rules: list[RuleNormalized]) -> list[dict[str, Any]]: + if self.normalized_config is None: + raise FwoImporterError("cannot prepare new rule metadata: normalized_config is None") + + new_rule_metadata: list[dict[str, Any]] = [] + + for rule in new_rules: + if not rule.rule_uid: + raise FwoImporterError(f"rule UID is None: {rule} in rulebase during prepare_new_rule_metadata") + rm4import = RuleMetadatum( + rule_uid=rule.rule_uid, + mgm_id=self.import_details.state.mgm_details.current_mgm_id, + rule_created=self.import_details.state.import_id, + rule_last_hit=rule.last_hit, + ) + new_rule_metadata.append(rm4import.model_dump()) + # TODO: add other fields + return new_rule_metadata + + def mark_rulebases_removed(self, removed_rulebase_uids: list[str]) -> int: + """ + Marks rulebases as removed in the database. + + Args: + removed_rulebase_uids (list[str]): A list of rulebase UIDs to be marked as removed. + + Returns: + int: The number of rulebases that were marked as removed. + + """ + if len(removed_rulebase_uids) == 0: + return 0 + + remove_mutation = """ + mutation markRulebasesRemoved($importId: bigint!, $ids: [Int!]!) { + update_rulebase(where: {removed: { _is_null: true }, id: {_in: $ids}}, _set: {removed: $importId}) { + affected_rows + } + } + """ + query_variables: dict[str, Any] = { + "importId": self.import_details.state.import_id, + "ids": [self.uid2id_mapper.get_rulebase_id(uid) for uid in removed_rulebase_uids], + } + + try: + remove_result = self.import_details.api_call.call( + remove_mutation, query_variables=query_variables, analyze_payload=True + ) + except Exception: + raise FwoApiWriteError(f"failed to remove rulebases: {traceback.format_exc()!s}") + if "errors" in remove_result: + raise FwoApiWriteError(f"failed to remove rulebases: {remove_result['errors']!s}") + + return int(remove_result["data"]["update_rulebase"]["affected_rows"]) + + def mark_rules_removed(self, rule_uids_to_remove: list[str]) -> tuple[int, list[int]]: + """ + Marks removed and changed rules as removed in the database and returns the number of changes and the list of removed rule IDs. + """ + changes = 0 + rule_ids_to_remove = [ + self.uid2id_mapper.get_rule_id(rule_uid, before_update=True) for rule_uid in rule_uids_to_remove + ] + + remove_mutation = """ + mutation markRulesRemoved($importId: bigint!, $ruleIds: [bigint!]!) { + update_rule(where: {removed: { _is_null: true }, rule_id: {_in: $ruleIds}}, _set: {removed: $importId, active:false}) { + affected_rows + returning { rule_id } + } + } + """ + query_variables: dict[str, Any] = { + "importId": self.import_details.state.import_id, + "ruleIds": rule_ids_to_remove, + } + + try: + remove_result = self.import_details.api_call.call( + remove_mutation, query_variables=query_variables, analyze_payload=True + ) + except Exception: + raise FwoApiWriteError(f"failed to remove rules: {traceback.format_exc()!s}") + if "errors" in remove_result: + raise FwoApiWriteError(f"failed to remove rules: {remove_result['errors']!s}") + changes = int(remove_result["data"]["update_rule"]["affected_rows"]) + removed_rule_ids = [item["rule_id"] for item in remove_result["data"]["update_rule"]["returning"]] + + return changes, removed_rule_ids + + # TODO: find a better place for these kind of functions that simply return from config data + @staticmethod + def get_rule_to_gw_refs( + rulebases: list[Rulebase], + global_rulebases: list[Rulebase] | None, + gateways: list[Gateway], + ) -> set[tuple[str, str]]: + """ + Get all rule_enforced_on_gateway (rule to gateway) refs based on the given rulebases and gateways. + """ + # first, gather all rule to gateway references from install-on fields + # need to check global rulebases for rules installed on this mgms gws as well + rulebases_to_check = rulebases + (global_rulebases or []) + rule_to_gw_refs = { + (rule_uid, gw_installon) + for rulebase in rulebases_to_check + for rule_uid, rule in rulebase.rules.items() + for gw_installon in (rule.rule_installon.split(fwo_const.LIST_DELIMITER) if rule.rule_installon else []) + } + rules_with_installon = {rule_uid for rule_uid, _ in rule_to_gw_refs} + + def lookup_rb_by_uid(rb_uid: str) -> Rulebase: + rb = next((rb for rb in rulebases if rb.uid == rb_uid), None) + if rb: + return rb + if not global_rulebases: + raise FwoImporterErrorInconsistenciesError( + f"could not find rulebase with UID {rb_uid} in previous config" + ) + rb = next((rb for rb in global_rulebases if rb.uid == rb_uid), None) + if not rb: + raise FwoImporterErrorInconsistenciesError( + f"could not find rulebase with UID {rb_uid} in previous global config" + ) + return rb + + # second, gather all rule to gateway references from enforced policies on gateways + rule_to_gw_refs.update( + (rule_uid, gateway.Uid or "") + for gateway in gateways + for rulebase_link in gateway.RulebaseLinks + for rule_uid in lookup_rb_by_uid(rulebase_link.to_rulebase_uid).rules + # if rule has installon, this is the source of truth for enforced on gateway refs + if rule_uid not in rules_with_installon + ) + gw_uids: set[str] = {gw.Uid for gw in gateways if gw.Uid is not None} + # filter for all gateways which are part of the current management in the database + return {(rule_uid, gw_uid) for rule_uid, gw_uid in rule_to_gw_refs if gw_uid in gw_uids} + + def update_rule_enforced_on_gateway(self, changed_rule_uids: set[str]) -> tuple[int, int]: + """ + Update the rule_enforced_on_gateway table based on changes in rule to gateway references. + + Args: + changed_rule_uids (set[str]): set of UIDs of rules that changed in this import + + Returns: + tuple[int, int]: A tuple containing the number of added references and the number of removed references + + """ + if not self.global_state.previous_config: + raise FwoImporterError("cannot update rule enforced on gateway: previous_config is None") + if not self.global_state.normalized_config: + raise FwoImporterError("cannot update rule enforced on gateway: normalized_config is None") + prev_rule_to_gw_refs = self.get_rule_to_gw_refs( + self.global_state.previous_config.rulebases, + self.global_state.previous_global_config.rulebases if self.global_state.previous_global_config else None, + self.global_state.previous_config.gateways, + ) + new_rule_to_gw_refs = self.get_rule_to_gw_refs( + self.global_state.normalized_config.rulebases, + self.global_state.global_normalized_config.rulebases + if self.global_state.global_normalized_config + else None, + self.global_state.normalized_config.gateways, + ) + # check for changed rule_uid -> gw uid assignments + refs_to_add = new_rule_to_gw_refs - prev_rule_to_gw_refs + refs_to_remove = prev_rule_to_gw_refs - new_rule_to_gw_refs + # also add unchanged assignments where the rule was changed -> need to be removed and inserted with new rule id + changed_rule_to_gw_refs = { + (rule_uid, gw_uid) for rule_uid, gw_uid in new_rule_to_gw_refs if rule_uid in changed_rule_uids + } + refs_to_add.update(changed_rule_to_gw_refs) + refs_to_remove.update(changed_rule_to_gw_refs) + + added_refs, removed_refs = 0, 0 + + if refs_to_remove: + remove_mutation = FwoApi.get_graphql_code( + [fwo_const.GRAPHQL_QUERY_PATH + "rule/updateRuleEnforcedOnGateway.graphql"] + ) + remove_variables = { + "rulesEnforcedOnGateway": [ + { + "_and": [ + {"rule_id": {"_eq": self.uid2id_mapper.get_rule_id(rule_uid, before_update=True)}}, + {"dev_id": {"_eq": self.import_details.state.lookup_gateway_id(gw_uid)}}, + ] + } + for rule_uid, gw_uid in refs_to_remove + ], + "importId": self.import_details.state.import_id, + } + try: + remove_result = self.import_details.api_call.call( + remove_mutation, + query_variables=remove_variables, + analyze_payload=True, + ) + except Exception: + FWOLogger.exception(f"failed to remove rule enforced on gateway refs: {traceback.format_exc()!s}") + raise FwoApiWriteError(f"failed to remove rule enforced on gateway refs: {traceback.format_exc()!s}") + if "errors" in remove_result: + FWOLogger.exception( + f"fwo_api:update_rule_enforced_on_gateway - error while updating moved rules refs: {remove_result['errors']!s}" + ) + raise FwoApiWriteError(f"failed to remove rule enforced on gateway refs: {remove_result['errors']!s}") + removed_refs = int(remove_result["data"]["update_rule_enforced_on_gateway"]["affected_rows"]) + if refs_to_add: + add_mutation = FwoApi.get_graphql_code( + [fwo_const.GRAPHQL_QUERY_PATH + "rule/insertRuleEnforcedOnGateway.graphql"] + ) + add_variables = { + "rulesEnforcedOnGateway": [ + { + "rule_id": self.uid2id_mapper.get_rule_id(rule_uid), + "dev_id": self.import_details.state.lookup_gateway_id(gw_uid), + "created": self.import_details.state.import_id, + } + for rule_uid, gw_uid in refs_to_add + ] + } + try: + add_result = self.import_details.api_call.call( + add_mutation, query_variables=add_variables, analyze_payload=True + ) + except Exception: + FWOLogger.exception(f"failed to add rule enforced on gateway refs: {traceback.format_exc()!s}") + raise FwoApiWriteError(f"failed to add rule enforced on gateway refs: {traceback.format_exc()!s}") + if "errors" in add_result: + FWOLogger.exception( + f"fwo_api:update_rule_enforced_on_gateway - error while adding moved rules refs: {add_result['errors']!s}" + ) + raise FwoApiWriteError(f"failed to add rule enforced on gateway refs: {add_result['errors']!s}") + added_refs = int(add_result["data"]["insert_rule_enforced_on_gateway"]["affected_rows"]) + + return added_refs, removed_refs + + def prepare_rule_for_import(self, rule: RuleNormalized, rulebase_uid: str) -> Rule: + rulebase_id = self.uid2id_mapper.get_rulebase_id(rulebase_uid) + return Rule( + mgm_id=self.import_details.state.mgm_details.current_mgm_id, + rule_num=rule.rule_num, + rule_disabled=rule.rule_disabled, + rule_src_neg=rule.rule_src_neg, + rule_src=rule.rule_src, + rule_src_refs=rule.rule_src_refs, + rule_dst_neg=rule.rule_dst_neg, + rule_dst=rule.rule_dst, + rule_dst_refs=rule.rule_dst_refs, + rule_svc_neg=rule.rule_svc_neg, + rule_svc=rule.rule_svc, + rule_svc_refs=rule.rule_svc_refs, + rule_action=rule.rule_action, + rule_track=rule.rule_track, + rule_time=rule.rule_time, + rule_name=rule.rule_name, + rule_uid=rule.rule_uid, + rule_custom_fields=rule.rule_custom_fields, + rule_implied=rule.rule_implied, + rule_comment=rule.rule_comment, + rule_from_zone=None, # TODO: to be removed or changed to string of joined zone names + rule_to_zone=None, # TODO: to be removed or changed to string of joined zone names + access_rule=True, + nat_rule=False, + is_global=False, + rulebase_id=rulebase_id, + rule_create=self.import_details.state.import_id, + rule_last_seen=self.import_details.state.import_id, + rule_num_numeric=rule.rule_num_numeric, + action_id=self.import_details.state.lookup_action(rule.rule_action), + track_id=self.import_details.state.lookup_track(rule.rule_track), + rule_head_text=rule.rule_head_text, + rule_installon=rule.rule_installon, + last_change_admin=None, # TODO: get id from rule.last_change_admin + ) + + def write_changelog_rules( + self, + added_rules: list[RuleNormalized], + removed_rules: list[RuleNormalized], + changed_rules: list[tuple[RuleNormalized, RuleNormalized]], + ) -> None: + """ + Writes changelog entries for added, removed, and changed rules. + + Args: + new_rules (list[RuleNormalized]): List of newly added rules. + removed_rules (list[RuleNormalized]): List of removed rules. + changed_rules (list[tuple[RuleNormalized, RuleNormalized]]): List of tuples containing old and new versions of changed rules. + + """ + added_rules_ids = [ + self.uid2id_mapper.get_rule_id(rule.rule_uid) for rule in added_rules if rule.rule_uid is not None + ] + removed_rules_ids = [ + self.uid2id_mapper.get_rule_id(rule.rule_uid) for rule in removed_rules if rule.rule_uid is not None + ] + changed_rules_ids: list[tuple[int, int]] = [] # (new_rule_id, old_rule_id) + for old_rule, new_rule in changed_rules: + if ( + new_rule.rule_uid is not None + and old_rule.rule_uid is not None + and self.is_change_security_relevant(old_rule, new_rule) + ): + rule_uid = new_rule.rule_uid + changed_rules_ids.append( + ( + self.uid2id_mapper.get_rule_id(rule_uid), + self.uid2id_mapper.get_rule_id(rule_uid, before_update=True), + ) + ) + + changelog_rule_insert_objects = self.prepare_changelog_rules_insert_objects( + added_rules_ids, removed_rules_ids, changed_rules_ids + ) + + update_changelog_rules = FwoApi.get_graphql_code( + [fwo_const.GRAPHQL_QUERY_PATH + "rule/updateChanglogRules.graphql"] + ) + + query_variables = {"rule_changes": changelog_rule_insert_objects} + + if len(changelog_rule_insert_objects) > 0: + try: + update_changelog_rules_result = self.import_details.api_call.call( + update_changelog_rules, + query_variables=query_variables, + analyze_payload=True, + ) + if "errors" in update_changelog_rules_result: + FWOLogger.exception( + f"error while adding changelog entries for objects: {update_changelog_rules_result['errors']!s}" + ) + except Exception: + FWOLogger.exception( + f"fatal error while adding changelog entries for objects: {traceback.format_exc()!s}" + ) + + def prepare_changelog_rules_insert_objects( + self, + added_rules_ids: list[int], + removed_rules_ids: list[int], + changed_rules_ids: list[tuple[int, int]], + ) -> list[dict[str, Any]]: + """ + Creates two lists of insert arguments for the changelog_rules db table, one for new rules, one for deleted. + """ + change_logger = ChangeLogger() + changelog_rule_insert_objects: list[dict[str, Any]] = [] + import_time = datetime.now().isoformat() + change_typ = 3 + if self.import_details.state.is_initial_import or self.import_details.state.is_clearing_import: + change_typ = 2 # initial - to be ignored in change reports + + changelog_rule_insert_objects.extend( + [ + change_logger.create_changelog_import_object( + "rule", + self.import_details.state, + "I", + change_typ, + import_time, + rule_id, + ) + for rule_id in added_rules_ids + ] + ) + + changelog_rule_insert_objects.extend( + [ + change_logger.create_changelog_import_object( + "rule", + self.import_details.state, + "D", + change_typ, + import_time, + rule_id, + ) + for rule_id in removed_rules_ids + ] + ) + + changelog_rule_insert_objects.extend( + [ + change_logger.create_changelog_import_object( + "rule", + self.import_details.state, + "C", + change_typ, + import_time, + new_rule_id, + old_rule_id, + ) + for new_rule_id, old_rule_id in changed_rules_ids + ] + ) + + return changelog_rule_insert_objects + + def is_change_security_relevant(self, old_rule: RuleNormalized, new_rule: RuleNormalized) -> bool: + """ + Checks if a change between an old and a new version of a rule is security-relevant, + meaning it should be included in the changelog and change reports. + """ + exclude = { + "last_hit", + "rule_num", + "rule_src_zone", + "rule_dst_zone", + "rule_name", + "rule_comment", + "rule_custom_fields", + } + old_dict = old_rule.model_dump(exclude=exclude) + new_dict = new_rule.model_dump(exclude=exclude) + return old_dict != new_dict + + def count_moved_rules( + self, + removed_rules: dict[str, tuple[RuleNormalized, str]], + added_rules: dict[str, tuple[RuleNormalized, str]], + ) -> int: + """ + Counts the number of moved rules based on comparison of removed and added (= changed) rules. + + Args: + removed_rules (dict[str, tuple[RuleNormalized, str]]): A dictionary mapping rule_uid -> (RuleNormalized, rulebase_uid) for removed rules. + added_rules (dict[str, tuple[RuleNormalized, str]]): A dictionary mapping rule_uid -> (RuleNormalized, rulebase_uid) for added rules. + + Returns: + int: The number of moved rules. + + """ + moved_rules = 0 + + for rule_uid in set(removed_rules.keys()) & set(added_rules.keys()): + old_rule, old_rb_uid = removed_rules[rule_uid] + new_rule, new_rb_uid = added_rules[rule_uid] + old_rule_num = old_rule.rule_num_numeric + new_rule_num = new_rule.rule_num_numeric + if old_rb_uid != new_rb_uid or old_rule_num != new_rule_num: + moved_rules += 1 + return moved_rules diff --git a/roles/importer/files/importer/model_controllers/fwconfig_import_ruleorder.py b/roles/importer/files/importer/model_controllers/fwconfig_import_ruleorder.py new file mode 100644 index 0000000000..13192a84b3 --- /dev/null +++ b/roles/importer/files/importer/model_controllers/fwconfig_import_ruleorder.py @@ -0,0 +1,73 @@ +from typing import TYPE_CHECKING + +from fwo_base import compute_min_moves +from fwo_const import RULE_NUM_NUMERIC_STEPS +from fwo_log import FWOLogger + +if TYPE_CHECKING: + from models.fwconfig_normalized import FwConfigNormalized + from models.rulebase import Rulebase + + +def update_rule_order_diffs(previous_config: "FwConfigNormalized", normalized_config: "FwConfigNormalized") -> None: + """ + Sets all rule_num_numeric values in normalized_config based on previous config, changes in the rule order and new inserts. + + Args: + previous_config (FwConfigNormalized): The previous normalized configuration. + normalized_config (FwConfigNormalized): The current normalized configuration to update. + + """ + for rulebase in normalized_config.rulebases: + previous_rulebase = next((rb for rb in previous_config.rulebases if rb.uid == rulebase.uid), None) + if previous_rulebase is None: + calculate_initial_rule_nums(rulebase) + else: + update_rule_nums_based_on_previous(rulebase, previous_rulebase) + + +def calculate_initial_rule_nums(rulebase: "Rulebase") -> None: + """Sets initial rule_num_numeric values for all rules in a rulebase.""" + current_rule_num_numeric = 0 + for rule in rulebase.rules.values(): + current_rule_num_numeric += RULE_NUM_NUMERIC_STEPS + rule.rule_num_numeric = current_rule_num_numeric + + +def update_rule_nums_based_on_previous(current_rulebase: "Rulebase", previous_rulebase: "Rulebase") -> None: + """Calculates and sets rule_num_numeric values based on previous rulebase, moves and inserts.""" + min_moves_result = compute_min_moves(list(previous_rulebase.rules.keys()), list(current_rulebase.rules.keys())) + _deletions = {uid for _, uid in min_moves_result["deletions"]} + insertions = {uid for _, uid in min_moves_result["insertions"]} + reposition_moves = {uid for _, uid, _pos in min_moves_result["reposition_moves"]} + # calculate new rule_num_numerics for moved and inserted rules + uids_num_unchanged = current_rulebase.rules.keys() - insertions - reposition_moves + for rule_uid in uids_num_unchanged: + # preserve rule_num_numeric for rules that existed and were not moved + current_rulebase.rules[rule_uid].rule_num_numeric = previous_rulebase.rules[rule_uid].rule_num_numeric + # Precompute ordered lists of rule UIDs and rule objects to avoid repeated list construction in the loop + rule_uids = list(current_rulebase.rules.keys()) + rule_list = list(current_rulebase.rules.values()) + for index, rule in enumerate(rule_list): + if rule.rule_num_numeric: + continue # already set, no need to update + prev_num_numeric = 0.0 + if index > 0: + prev_rule_uid = rule_uids[index - 1] + prev_num_numeric = current_rulebase.rules[prev_rule_uid].rule_num_numeric + next_num_numeric = next( + (rule.rule_num_numeric for idx, rule in enumerate(rule_list) if idx > index and rule.rule_num_numeric), + None, + ) + if next_num_numeric is not None: + rule.rule_num_numeric = (prev_num_numeric + next_num_numeric) / 2 + else: + rule.rule_num_numeric = prev_num_numeric + RULE_NUM_NUMERIC_STEPS + + # if there are any rule_num_numeric collisions, recalculate all rule_num_numeric values + rule_num_numerics = [rule.rule_num_numeric for rule in current_rulebase.rules.values()] + if len(rule_num_numerics) != len(set(rule_num_numerics)): + FWOLogger.info( + f"Rule number collisions detected in rulebase {current_rulebase.name} ({current_rulebase.uid}). Recalculating all rule numbers." + ) + calculate_initial_rule_nums(current_rulebase) diff --git a/roles/importer/files/importer/model_controllers/fwconfigmanager_controller.py b/roles/importer/files/importer/model_controllers/fwconfigmanager_controller.py new file mode 100644 index 0000000000..8e6817f6d1 --- /dev/null +++ b/roles/importer/files/importer/model_controllers/fwconfigmanager_controller.py @@ -0,0 +1,39 @@ +from typing import Any + +from models.fwconfig_normalized import FwConfigNormalized +from models.fwconfigmanager import FwConfigManager + + +class FwConfigManagerController(FwConfigManager): + manager_uid: str + manager_name: str + is_global: bool = False + dependant_manager_uids: list[str] + configs: list[FwConfigNormalized] + model_config = {"arbitrary_types_allowed": True} # noqa: RUF012 + + def __init__( + self, + manager_uid: str, + manager_name: str, + is_global: bool, + dependant_manager_uids: list[str], + configs: list[FwConfigNormalized], + ): + self.manager_uid = manager_uid + self.manager_name = manager_name + self.is_global = is_global + self.dependant_manager_uids = dependant_manager_uids + self.configs = configs + + @classmethod + def from_json(cls, json_dict: dict[str, Any]) -> "FwConfigManagerController": + manager_uid: str = json_dict["manager_uid"] + manager_name: str = json_dict["mgm_name"] + is_global: bool = json_dict["is_global"] + dependant_manager_uids: list[str] = json_dict["dependant_manager_uids"] + configs: list[FwConfigNormalized] = json_dict["configs"] + return cls(manager_uid, manager_name, is_global, dependant_manager_uids, configs) + + def __str__(self): + return f"{self.manager_uid}({self.configs!s})" diff --git a/roles/importer/files/importer/model_controllers/fwconfigmanagerlist_controller.py b/roles/importer/files/importer/model_controllers/fwconfigmanagerlist_controller.py new file mode 100644 index 0000000000..43ebefc0fe --- /dev/null +++ b/roles/importer/files/importer/model_controllers/fwconfigmanagerlist_controller.py @@ -0,0 +1,162 @@ +import json +import time +import traceback +from copy import deepcopy + +from fwo_base import ConfFormat +from fwo_const import IMPORT_TMP_PATH +from fwo_log import FWOLogger +from models.fwconfigmanager import FwConfigManager +from models.fwconfigmanagerlist import FwConfigManagerList +from models.import_state import ImportState +from utils.fwconfig_json_encoder import FwConfigJsonEncoder + +""" + a list of normalized configuratons of a firewall management to import + FwConfigManagerList: [ FwConfigManager ] +""" + + +class FwConfigManagerListController(FwConfigManagerList): + def __str__(self): + return f"{self.ManagerSet!s})" + + def to_json_string(self, pretty_print: bool = False): + json_dict = self.model_dump(by_alias=True) + if pretty_print: + return json.dumps(json_dict, indent=2, cls=FwConfigJsonEncoder) + return json.dumps(json_dict) + + def merge_configs(self, conf2: "FwConfigManagerListController"): + if self.ConfigFormat == conf2.ConfigFormat: + self.ManagerSet.extend(conf2.ManagerSet) + + @staticmethod + def generate_empty_config(is_super_manager: bool = False) -> "FwConfigManagerListController": + """ + Generates an empty FwConfigManagerListController with a single empty FwConfigManager. + """ + empty_config = FwConfigManagerListController() + empty_config.ConfigFormat = ConfFormat.NORMALIZED + empty_manager = FwConfigManager( + manager_uid="", + is_super_manager=is_super_manager, + sub_manager_ids=[], + configs=[], + domain_name="", + domain_uid="", + manager_name="", + ) + empty_config.add_manager(empty_manager) + empty_config.native_config = {} + return empty_config + + def get_all_zone_names(self, mgr_uid: str) -> set[str]: + """ + Returns a list of all zone UIDs in the configuration. + """ + all_zone_names: list[str] = [] + for mgr in self.ManagerSet: + if mgr.is_super_manager or mgr.manager_uid == mgr_uid: + for single_config in mgr.configs: + all_zone_names.extend(single_config.zone_objects.keys()) + return set(all_zone_names) + + def get_all_network_object_uids(self, mgr_uid: str) -> set[str]: + """ + Returns a list of all network objects in the configuration. + """ + all_network_objects: list[str] = [] + for mgr in self.ManagerSet: + if mgr.is_super_manager or mgr.manager_uid == mgr_uid: + for single_config in mgr.configs: + all_network_objects.extend(single_config.network_objects.keys()) + return set(all_network_objects) + + def get_all_service_object_uids(self, mgr_uid: str) -> set[str]: + """ + Returns a list of all service objects in the configuration. + """ + all_service_objects: list[str] = [] + for mgr in self.ManagerSet: + if mgr.is_super_manager or mgr.manager_uid == mgr_uid: + for single_config in mgr.configs: + all_service_objects.extend(single_config.service_objects.keys()) + return set(all_service_objects) + + def get_all_user_object_uids(self, mgr_uid: str) -> set[str]: + """ + Returns a list of all user objects in the configuration. + """ + all_user_objects: list[str] = [] + for mgr in self.ManagerSet: + if mgr.is_super_manager or mgr.manager_uid == mgr_uid: + for single_config in mgr.configs: + all_user_objects.extend(single_config.users.keys()) + return set(all_user_objects) + + def add_manager(self, manager: FwConfigManager): + self.ManagerSet.append(manager) + + def get_first_manager(self): + if len(self.ManagerSet) > 0: + return self.ManagerSet[0] + return None + + @staticmethod + def get_device_uid_from_rulebase_name(rb_name: str) -> str: + return rb_name + + @staticmethod + def get_policy_uid_from_rulebase_name(rb_name: str) -> str: + return rb_name + + def store_full_normalized_config_to_file(self, import_state: ImportState): + if FWOLogger.is_debug_level(6): + debug_start_time = int(time.time()) + try: + normalized_config_filename = ( + f"{IMPORT_TMP_PATH}/mgm_id_{import_state.mgm_details.mgm_id!s}_config_normalized.json" + ) + + config_copy_without_native = deepcopy(self) + config_copy_without_native.native_config = {} + + with open(normalized_config_filename, "w") as json_data: + json_data.write(config_copy_without_native.to_json_string(pretty_print=True)) + time_write_debug_json = int(time.time()) - debug_start_time + FWOLogger.debug( + f"storeFullNormalizedConfigToFile - writing normalized config json files duration {time_write_debug_json!s}s" + ) + + return normalized_config_filename + + except Exception: + FWOLogger.error( + f"import_management - unspecified error while dumping normalized config to json file: {traceback.format_exc()!s}" + ) + raise + return None + + def is_native(self) -> bool: + return self.native_config is not None + + def is_native_non_empty(self) -> bool: + return self.native_config is not None and self.native_config != {} + + def contains_only_native(self) -> bool: + return self.is_native() and ( + len(self.ManagerSet) == 0 or (len(self.ManagerSet) == 1 and len(self.ManagerSet[0].configs) == 0) + ) + + def native_config_is_empty(self) -> bool: + return self.native_config is None or self.native_config == {} + + def normalized_config_is_empty(self) -> bool: + return len(self.ManagerSet) == 1 and len(self.ManagerSet[0].configs) == 0 + + def is_normalized(self) -> bool: + return not self.is_native() + + def has_empty_config(self) -> bool: + return self.native_config_is_empty() and self.normalized_config_is_empty() diff --git a/roles/importer/files/importer/model_controllers/fworch_config_controller.py b/roles/importer/files/importer/model_controllers/fworch_config_controller.py new file mode 100644 index 0000000000..663fe37b4c --- /dev/null +++ b/roles/importer/files/importer/model_controllers/fworch_config_controller.py @@ -0,0 +1,42 @@ +from typing import Any + +from models.fworch_config import FworchConfig + +""" + the configuraton of a firewall orchestrator itself + as read from the global config file including FWO URI +""" + + +class FworchConfigController(FworchConfig): + def __init__( + self, + fwo_api_url: str | None, + fwo_user_mgmt_api_uri: str | None, + importer_pwd: str | None, + api_fetch_size: int = 500, + ): + if fwo_api_url is not None: + self.fwo_api_url = fwo_api_url + else: + self.fwo_api_fwo_user_mgmt_api_uri = None + if fwo_user_mgmt_api_uri is not None: + self.fwo_user_mgmt_api_uri = fwo_user_mgmt_api_uri + else: + self.fwo_user_mgmt_api_uri = None + self.importer_password = importer_pwd + self.api_fetch_size = api_fetch_size + + @classmethod + def from_json(cls, json_dict: dict[str, Any]) -> "FworchConfigController": + fwo_api_uri = json_dict["fwo_api_base_url"] + fwo_user_mgmt_api_uri = json_dict["user_management_api_base_url"] + fwo_importer_pwd = json_dict.get("importerPassword") + + return cls(fwo_api_uri, fwo_user_mgmt_api_uri, fwo_importer_pwd) + + def __str__(self): + return f"{self.fwo_api_url}, {self.fwo_user_mgmt_api_uri}, {self.api_fetch_size}" + + def set_importer_pwd(self, importer_password: str | None): + self.importer_password = importer_password diff --git a/roles/importer/files/importer/model_controllers/gateway_controller.py b/roles/importer/files/importer/model_controllers/gateway_controller.py new file mode 100644 index 0000000000..e035a23219 --- /dev/null +++ b/roles/importer/files/importer/model_controllers/gateway_controller.py @@ -0,0 +1,22 @@ +from models.gateway import Gateway + + +class GatewayController(Gateway): # noqa: PLW1641 + def __init__(self, gw: Gateway): + self.Gateway = gw + + def __eq__(self, other: object) -> bool: + if isinstance(other, Gateway): + return ( + self.Name == other.Name + and self.Uid == other.Uid + and self.Routing == other.Routing + and self.Interfaces == other.Interfaces + and self.RulebaseLinks == other.RulebaseLinks + and self.EnforcedNatPolicyUids == other.EnforcedNatPolicyUids + and self.EnforcedPolicyUids == other.EnforcedPolicyUids + and self.GlobalPolicyUid == other.GlobalPolicyUid + and self.ImportDisabled == other.ImportDisabled + and self.ShowInUI == other.ShowInUI + ) + return NotImplemented diff --git a/roles/importer/files/importer/model_controllers/import_state_controller.py b/roles/importer/files/importer/model_controllers/import_state_controller.py new file mode 100644 index 0000000000..fd2aed00e3 --- /dev/null +++ b/roles/importer/files/importer/model_controllers/import_state_controller.py @@ -0,0 +1,337 @@ +import traceback +from datetime import datetime, timezone + +import fwo_globals +import urllib3 +from dateutil import parser +from fwo_api import FwoApi +from fwo_api_call import FwoApiCall +from fwo_config import read_config +from fwo_const import FWO_CONFIG_FILENAME, GRAPHQL_QUERY_PATH +from fwo_exceptions import FwoImporterError +from fwo_log import FWOLogger +from model_controllers.fworch_config_controller import FworchConfigController +from model_controllers.management_controller import ( + ConnectionInfo, + CredentialInfo, + DeviceInfo, + DomainInfo, + ManagementController, + ManagerInfo, +) +from models.import_state import ImportState + +"""Used for storing state during import process per management""" + + +class ImportStateController: + state: ImportState + api_connection: FwoApi + api_call: FwoApiCall + + def __init__(self, state: ImportState, api_call: FwoApiCall): + self.state = state + self.api_call = api_call + self.api_connection = api_call.api + + def __str__(self): + return f"{self.state.mgm_details!s}(import_id={self.state.import_id})" + + def set_import_file_name(self, import_file_name: str): + self.state.import_file_name = import_file_name + + def set_import_id(self, import_id: int): + self.state.import_id = import_id + + @classmethod + def initialize_import( + cls, + mgm_id: int, + api_call: FwoApiCall, + suppress_cert_warnings: bool, + ssl_verification: bool, + force: bool, + version: int, + is_clearing_import: bool, + ): + fwo_config = FworchConfigController.from_json(read_config(FWO_CONFIG_FILENAME)) + + # set global https connection values + fwo_globals.set_global_values( + suppress_cert_warnings_in=suppress_cert_warnings, + verify_certs_in=ssl_verification, + ) + if fwo_globals.suppress_cert_warnings: + urllib3.disable_warnings() # suppress ssl warnings only + + try: # get mgm_details (fw-type, port, ip, user credentials): + mgm_controller = ManagementController( + mgm_id, + "", + [], + DeviceInfo(), + ConnectionInfo(), + "", + CredentialInfo(), + ManagerInfo(), + DomainInfo(), + ) + mgm_details = mgm_controller.get_mgm_details(api_call.api, mgm_id) + except Exception as _: + FWOLogger.error( + f"import_management - error while getting fw management details for mgm={mgm_id}: {traceback.format_exc()!s}" + ) + raise + + try: # get last import data + _, last_import_date = api_call.get_last_complete_import({"mgmId": mgm_id}) + except Exception: + FWOLogger.error(f"import_management - error while getting last import data for mgm={mgm_id}") + raise + + state = ImportState() + state.config_changed_since_last_import = True + state.fwo_config = fwo_config + state.mgm_details = ManagementController.from_json(mgm_details) + state.force_import = force + state.import_version = version + state.is_clearing_import = is_clearing_import + state.is_initial_import = last_import_date == "" + state.verify_certs = ssl_verification + state.last_successful_import = last_import_date + + result = cls(state, api_call) + result.get_past_import_infos() + result.set_core_data() + + if type(result) is str: # type: ignore # TODO: This should never happen # noqa: PGH003 + FWOLogger.error("error while getting import state") + raise FwoImporterError("error while getting import state") + + return result + + def get_past_import_infos(self): + try: # get past import details (LastFullImport, ...): + day_string = self.api_call.get_config_value(key="dataRetentionTime") + if day_string: + self.state.data_retention_days = int(day_string) + self.state.last_full_import_id, self.state.last_full_import_date = self.api_call.get_last_complete_import( + {"mgmId": int(self.state.mgm_details.mgm_id)} + ) + except Exception: + FWOLogger.error( + f"import_management - error while getting past import details for mgm={self.state.mgm_details.mgm_id!s}: {traceback.format_exc()!s}" + ) + raise FwoImporterError(f"Error while getting past import details: {traceback.format_exc()!s}") + + if self.state.last_full_import_date != "": + self.state.last_successful_import = self.state.last_full_import_date + + # Convert the string to a datetime object + past_date = parser.parse(self.state.last_full_import_date) + + # Ensure "now" is timezone-aware (UTC here) + now = datetime.now(timezone.utc) + + # Normalize pastDate too (convert to UTC if it had a tz) + past_date = ( + past_date.replace(tzinfo=timezone.utc) + if past_date.tzinfo is None + else past_date.astimezone(timezone.utc) + ) + + difference = now - past_date + + self.state.days_since_last_full_import = difference.days + else: + self.state.days_since_last_full_import = 0 + + def set_core_data(self): + self.set_track_map() + self.set_action_map() + self.set_link_type_map() + self.set_color_ref_map() + self.set_network_obj_type_map() + self.set_service_obj_type_map() + self.set_user_obj_type_map() + self.set_protocol_map() + self.set_gateway_map() + self.set_management_map() + + def set_action_map(self): + query = "query getActionMap { stm_action { action_name action_id allowed } }" + try: + result = self.api_call.call(query=query, query_variables={}) + except Exception as e: + FWOLogger.error(f"Error while getting stm_action: {e!s}") + raise FwoImporterError(f"Error while getting stm_action: {e!s}") + + action_map: dict[str, int] = {} + for action in result["data"]["stm_action"]: + action_map.update({action["action_name"]: action["action_id"]}) + self.state.actions = action_map + + def set_track_map(self): + query = "query getTrackMap { stm_track { track_name track_id } }" + try: + result = self.api_call.call(query=query, query_variables={}) + except Exception as e: + FWOLogger.error(f"Error while getting stm_track: {e!s}") + raise FwoImporterError(f"Error while getting stm_track: {e!s}") + + track_map: dict[str, int] = {} + for track in result["data"]["stm_track"]: + track_map.update({track["track_name"]: track["track_id"]}) + self.state.tracks = track_map + + def set_link_type_map(self): + query = "query getLinkType { stm_link_type { id name } }" + try: + result = self.api_call.call(query=query, query_variables={}) + except Exception as e: + FWOLogger.error(f"Error while getting stm_link_type: {e!s}") + raise FwoImporterError(f"Error while getting stm_link_type: {e!s}") + + link_map: dict[str, int] = {} + for track in result["data"]["stm_link_type"]: + link_map.update({track["name"]: track["id"]}) + self.state.link_types = link_map + + def set_color_ref_map(self): + get_colors_query = FwoApi.get_graphql_code([GRAPHQL_QUERY_PATH + "stmTables/getColors.graphql"]) + + try: + result = self.api_call.call(query=get_colors_query, query_variables={}) + except Exception as e: + FWOLogger.error(f"Error while getting stm_color: {e!s}") + raise FwoImporterError(f"Error while getting stm_color: {e!s}") + + color_map: dict[str, int] = {} + for color in result["data"]["stm_color"]: + color_map.update({color["color_name"]: color["color_id"]}) + self.state.color_map = color_map + + def set_network_obj_type_map(self): + query = "query getNetworkObjTypeMap { stm_obj_typ { obj_typ_name obj_typ_id } }" + try: + result = self.api_call.call(query=query, query_variables={}) + except Exception as e: + FWOLogger.error(f"Error while getting stm_obj_typ: {e!s}") + raise FwoImporterError(f"Error while getting stm_obj_typ: {e!s}") + + nwobj_type_map: dict[str, int] = {} + for nw_type in result["data"]["stm_obj_typ"]: + nwobj_type_map.update({nw_type["obj_typ_name"]: nw_type["obj_typ_id"]}) + self.state.network_obj_type_map = nwobj_type_map + + def set_service_obj_type_map(self): + query = "query getServiceObjTypeMap { stm_svc_typ { svc_typ_name svc_typ_id } }" + try: + result = self.api_call.call(query=query, query_variables={}) + except Exception as e: + FWOLogger.error(f"Error while getting stm_svc_typ: {e!s}") + raise FwoImporterError(f"Error while getting stm_svc_typ: {e!s}") + + svc_type_map: dict[str, int] = {} + for svc_type in result["data"]["stm_svc_typ"]: + svc_type_map.update({svc_type["svc_typ_name"]: svc_type["svc_typ_id"]}) + self.state.service_obj_type_map = svc_type_map + + def set_user_obj_type_map(self): + query = "query getUserObjTypeMap { stm_usr_typ { usr_typ_name usr_typ_id } }" + try: + result = self.api_call.call(query=query, query_variables={}) + except Exception as e: + FWOLogger.error(f"Error while getting stm_usr_typ: {e!s}") + raise FwoImporterError(f"Error while getting stm_usr_typ: {e!s}") + + user_type_map: dict[str, int] = {} + for usr_type in result["data"]["stm_usr_typ"]: + user_type_map.update({usr_type["usr_typ_name"]: usr_type["usr_typ_id"]}) + self.state.user_obj_type_map = user_type_map + + def set_protocol_map(self): + query = "query getIpProtocols { stm_ip_proto { ip_proto_id ip_proto_name } }" + try: + result = self.api_call.call(query=query, query_variables={}) + except Exception as e: + FWOLogger.error(f"Error while getting stm_ip_proto: {e!s}") + raise FwoImporterError(f"Error while getting stm_ip_proto: {e!s}") + + protocol_map: dict[str, int] = {} + for proto in result["data"]["stm_ip_proto"]: + protocol_map.update({proto["ip_proto_name"].lower(): proto["ip_proto_id"]}) + self.state.protocol_map = protocol_map + + # getting all gateways (not limitited to the current mgm_id) to support super managements + # creates a dict with key = gateway.uid and value = gateway.id + # and also key = gateway.name and value = gateway.id + def set_gateway_map(self): + query = """ + query getGatewayMap { + device { + mgm_id + dev_id + dev_uid + } + } + """ + try: + result = self.api_call.call(query=query, query_variables={}) + except Exception: + FWOLogger.error("Error while getting gateways") + self.state.gateway_map = {} + raise FwoImporterError("Error while getting gateways") + + m = {} + for gw in result["data"]["device"]: + if gw["mgm_id"] not in m: + m[gw["mgm_id"]] = {} + m[gw["mgm_id"]][gw["dev_uid"]] = gw["dev_id"] + self.state.gateway_map = m + + # getting all managements (not limitited to the current mgm_id) to support super managements + # creates a dict with key = management.uid and value = management.id + def set_management_map(self): + query = """ + query getManagementMap($mgmId: Int!) { + management(where: {mgm_id: {_eq: $mgmId}}) { + mgm_id + mgm_uid + sub_managers: managementByMultiDeviceManagerId { + mgm_id + mgm_uid + } + } + } + """ + try: + result = self.api_call.call(query=query, query_variables={"mgmId": self.state.mgm_details.mgm_id}) + except Exception: + FWOLogger.error("Error while getting managements") + self.state.management_map = {} + raise FwoImporterError("Error while getting managements") + + m: dict[str, int] = {} + mgm = result["data"]["management"][0] + m.update({mgm["mgm_uid"]: mgm["mgm_id"]}) + for sub_mgr in mgm["sub_managers"]: + m.update({sub_mgr["mgm_uid"]: sub_mgr["mgm_id"]}) + + self.state.management_map = m + + def delete_import(self): + delete_import_mutation = """ + mutation deleteImport($importId: bigint!) { + delete_import_control(where: {control_id: {_eq: $importId}}) { affected_rows } + }""" + + try: + result = self.api_connection.call( + delete_import_mutation, + query_variables={"importId": self.state.import_id}, + ) + _ = result["data"]["delete_import_control"]["affected_rows"] + FWOLogger.info(f"removed import with id {self.state.import_id!s} completely") + except Exception: + FWOLogger.exception("fwo_api: failed to unlock import for import id " + str(self.state.import_id)) diff --git a/roles/importer/files/importer/model_controllers/import_statistics_controller.py b/roles/importer/files/importer/model_controllers/import_statistics_controller.py new file mode 100644 index 0000000000..5607056020 --- /dev/null +++ b/roles/importer/files/importer/model_controllers/import_statistics_controller.py @@ -0,0 +1,177 @@ +from models.import_statistics import ImportStatistics + + +class ImportStatisticsController: + def __init__(self, statistics: ImportStatistics | None = None): + self.statistics = statistics if statistics is not None else ImportStatistics() + + def get_total_change_number(self): + return ( + self.statistics.network_object_add_count + + self.statistics.network_object_delete_count + + self.statistics.network_object_change_count + + self.statistics.service_object_add_count + + self.statistics.service_object_delete_count + + self.statistics.service_object_change_count + + self.statistics.user_object_add_count + + self.statistics.user_object_delete_count + + self.statistics.user_object_change_count + + self.statistics.zone_object_add_count + + self.statistics.zone_object_delete_count + + self.statistics.time_object_add_count + + self.statistics.time_object_delete_count + + self.statistics.time_object_change_count + + self.statistics.rule_add_count + + self.statistics.rule_delete_count + + self.statistics.rule_change_count + + self.statistics.rule_ref_add_count + + self.statistics.rule_ref_delete_count + + self.statistics.rulebase_add_count + + self.statistics.rulebase_change_count + + self.statistics.rulebase_delete_count + ) + + def get_rule_change_number(self): + return ( + self.statistics.rule_add_count + + self.statistics.rule_delete_count + + self.statistics.rule_change_count + + self.statistics.rulebase_add_count + + self.statistics.rulebase_change_count + + self.statistics.rulebase_delete_count + ) + + def get_change_details(self): + result: dict[str, int] = {} + self.collect_nw_obj_change_details(result) + self.collect_svc_obj_change_details(result) + self.collect_usr_obj_change_details(result) + self.collect_time_obj_change_details(result) + self.collect_zone_obj_change_details(result) + self.collect_rule_change_details(result) + self.collect_inconsistent_deletion_details(result) + return result + + def collect_nw_obj_change_details(self, result: dict[str, int]): + if self.statistics.network_object_add_count > 0: + result["network_object_add_count"] = self.statistics.network_object_add_count + if self.statistics.network_object_delete_count > 0: + result["network_object_delete_count"] = self.statistics.network_object_delete_count + if self.statistics.network_object_change_count > 0: + result["network_object_change_count"] = self.statistics.network_object_change_count + + def collect_svc_obj_change_details(self, result: dict[str, int]): + if self.statistics.service_object_add_count > 0: + result["service_object_add_count"] = self.statistics.service_object_add_count + if self.statistics.service_object_delete_count > 0: + result["service_object_delete_count"] = self.statistics.service_object_delete_count + if self.statistics.service_object_change_count > 0: + result["service_object_change_count"] = self.statistics.service_object_change_count + + def collect_usr_obj_change_details(self, result: dict[str, int]): + if self.statistics.user_object_add_count > 0: + result["user_object_add_count"] = self.statistics.user_object_add_count + if self.statistics.user_object_delete_count > 0: + result["user_object_delete_count"] = self.statistics.user_object_delete_count + if self.statistics.user_object_change_count > 0: + result["user_object_change_count"] = self.statistics.user_object_change_count + + def collect_zone_obj_change_details(self, result: dict[str, int]): + if self.statistics.zone_object_add_count > 0: + result["zone_object_add_count"] = self.statistics.zone_object_add_count + if self.statistics.zone_object_delete_count > 0: + result["zone_object_delete_count"] = self.statistics.zone_object_delete_count + + def collect_time_obj_change_details(self, result: dict[str, int]): + if self.statistics.time_object_add_count > 0: + result["time_object_add_count"] = self.statistics.time_object_add_count + if self.statistics.time_object_delete_count > 0: + result["time_object_delete_count"] = self.statistics.time_object_delete_count + if self.statistics.time_object_change_count > 0: + result["time_object_change_count"] = self.statistics.time_object_change_count + + def collect_rule_change_details(self, result: dict[str, int]): + if self.statistics.rule_add_count > 0: + result["rule_add_count"] = self.statistics.rule_add_count + if self.statistics.rule_delete_count > 0: + result["rule_delete_count"] = self.statistics.rule_delete_count + if self.statistics.rule_change_count > 0: + result["rule_change_count"] = self.statistics.rule_change_count + if self.statistics.rule_move_count > 0: + result["rule_move_count"] = self.statistics.rule_move_count + if self.statistics.rule_ref_add_count > 0: + result["rule_ref_add_count"] = self.statistics.rule_ref_add_count + if self.statistics.rule_ref_delete_count > 0: + result["rule_ref_delete_count"] = self.statistics.rule_ref_delete_count + if self.statistics.rulebase_change_count > 0: + result["rulebase_change_count"] = self.statistics.rulebase_change_count + if self.statistics.rulebase_add_count > 0: + result["rulebase_add_count"] = self.statistics.rulebase_add_count + if self.statistics.rulebase_delete_count > 0: + result["rulebase_delete_count"] = self.statistics.rulebase_delete_count + if self.statistics.rulebase_link_add_count > 0: + result["rulebase_link_add_count"] = self.statistics.rulebase_link_add_count + if self.statistics.rulebase_link_delete_count > 0: + result["rulebase_link_delete_count"] = self.statistics.rulebase_link_delete_count + + def collect_inconsistent_deletion_details(self, result: dict[str, int]): + if self.statistics.inconsistent_nwobj_delete_count > 0: + result["inconsistent_network_object_delete_count"] = self.statistics.inconsistent_nwobj_delete_count + if self.statistics.inconsistent_svcobj_delete_count > 0: + result["inconsistent_service_object_delete_count"] = self.statistics.inconsistent_svcobj_delete_count + if self.statistics.inconsistent_userobj_delete_count > 0: + result["inconsistent_user_object_delete_count"] = self.statistics.inconsistent_userobj_delete_count + if self.statistics.inconsistent_rule_delete_count > 0: + result["inconsistent_rule_delete_count"] = self.statistics.inconsistent_rule_delete_count + if self.statistics.inconsistent_ref_delete_count > 0: + result["inconsistent_ref_delete_count"] = self.statistics.inconsistent_ref_delete_count + if self.statistics.inconsistent_rulebase_link_delete_count > 0: + result["inconsistent_rulebase_link_delete_count"] = self.statistics.inconsistent_rulebase_link_delete_count + + def increment_network_object_add_count(self, increment: int = 1): + self.statistics.network_object_add_count += increment + + def increment_network_object_delete_count(self, increment: int = 1): + self.statistics.network_object_delete_count += increment + + def increment_network_object_change_count(self, increment: int = 1): + self.statistics.network_object_change_count += increment + + def increment_service_object_add_count(self, increment: int = 1): + self.statistics.service_object_add_count += increment + + def increment_service_object_delete_count(self, increment: int = 1): + self.statistics.service_object_delete_count += increment + + def increment_service_object_change_count(self, increment: int = 1): + self.statistics.service_object_change_count += increment + + def increment_rulebase_add_count(self, increment: int = 1): + self.statistics.rulebase_add_count += increment + + def increment_rulebase_delete_count(self, increment: int = 1): + self.statistics.rulebase_delete_count += increment + + def increment_rule_add_count(self, increment: int = 1): + self.statistics.rule_add_count += increment + + def increment_rule_delete_count(self, increment: int = 1): + self.statistics.rule_delete_count += increment + + def increment_rule_change_count(self, increment: int = 1): + self.statistics.rule_change_count += increment + + def increment_rule_move_count(self, increment: int = 1): + self.statistics.rule_move_count += increment + + def increment_rule_ref_add_count(self, increment: int = 1): + self.statistics.rule_ref_add_count += increment + + def increment_rule_ref_delete_count(self, increment: int = 1): + self.statistics.rule_ref_delete_count += increment + + def increment_rulebase_link_add_count(self, increment: int = 1): + self.statistics.rulebase_link_add_count += increment + + def increment_rulebase_link_delete_count(self, increment: int = 1): + self.statistics.rulebase_link_delete_count += increment diff --git a/roles/importer/files/importer/model_controllers/interface_controller.py b/roles/importer/files/importer/model_controllers/interface_controller.py new file mode 100644 index 0000000000..3d67b9ef3c --- /dev/null +++ b/roles/importer/files/importer/model_controllers/interface_controller.py @@ -0,0 +1,53 @@ +from typing import Any + +from fwo_log import FWOLogger +from netaddr import IPAddress + + +class Interface: + def __init__( + self, device_id: int, name: str, ip: IPAddress, netmask_bits: int, state_up: bool = True, ip_version: int = 4 + ): + self.routing_device = int(device_id) + # check if routing device id exists? + self.name = str(name) + self.ip = IPAddress(ip) + netmask_bits = int(netmask_bits) + if netmask_bits < 0 or netmask_bits > 128: # noqa: PLR2004 + FWOLogger.error("interface " + self.name + " with invalid bitmask: " + str(netmask_bits)) + else: + self.netmask_bits = netmask_bits + self.state_up = bool(state_up) + ip_version = int(ip_version) + if ip_version not in {4, 6}: + FWOLogger.error("interface " + self.name + " with invalid ip protocal: " + str(ip_version)) + else: + self.ip_version = ip_version + + self.ip_version = ip_version + + +class InterfaceSerializable(Interface): + name: str + routing_device: int + ip: str + netmask_bits: int + state_up: bool + ip_version: int + + # TYPING: check if these types are correct + def __init__(self, iface_in: dict[Any, Any] | Interface): + if type(iface_in) is dict: + self.name = iface_in["name"] + self.routing_device = iface_in["routing_device"] + self.ip = str(iface_in["ip"]) + self.netmask_bits = iface_in["netmask_bits"] + self.state_up = iface_in["state_up"] + self.ip_version = iface_in["ip_version"] + elif isinstance(iface_in, Interface): + self.name = iface_in.name + self.routing_device = iface_in.routing_device + self.ip = str(iface_in.ip) + self.netmask_bits = iface_in.netmask_bits + self.state_up = iface_in.state_up + self.ip_version = iface_in.ip_version diff --git a/roles/importer/files/importer/model_controllers/management_controller.py b/roles/importer/files/importer/model_controllers/management_controller.py new file mode 100644 index 0000000000..99e5e34d83 --- /dev/null +++ b/roles/importer/files/importer/model_controllers/management_controller.py @@ -0,0 +1,210 @@ +import hashlib +from dataclasses import dataclass +from typing import Any + +from fwo_api import FwoApi +from fwo_base import replace_none_with_empty +from fwo_const import GRAPHQL_QUERY_PATH +from fwo_encrypt import decrypt, read_main_key +from fwo_exceptions import ( + FwLoginFailedError, + FwoApiFailureError, + SecretDecryptionFailedError, +) +from models.gateway import Gateway +from models.management import Management + + +@dataclass +class DeviceInfo: + name: str = "" + type_name: str = "" + type_version: str = "" + + +@dataclass +class ConnectionInfo: + hostname: str = "" + port: int = 443 + + +@dataclass +class CredentialInfo: + secret: str = "" + import_user: str = "" + cloud_client_id: str = "" + cloud_client_secret: str = "" + + +@dataclass +class ManagerInfo: + is_super_manager: bool = False + sub_manager_ids: list[int] | None = None + sub_managers: list["Management"] | None = None + + +@dataclass +class DomainInfo: + domain_name: str | None = None + domain_uid: str | None = None + + +class ManagementController(Management): + def __init__( + self, + mgm_id: int, + uid: str, + devices: list[dict[str, Any]], + device_info: DeviceInfo, + connection_info: ConnectionInfo, + importer_hostname: str, + credential_info: CredentialInfo, + manager_info: ManagerInfo, + domain_info: DomainInfo, + import_disabled: bool = False, + ): + super().__init__( + mgm_id=mgm_id, + uid=uid, + devices=devices, + import_disabled=import_disabled, + name=device_info.name, + device_type_name=device_info.type_name, + device_type_version=device_info.type_version, + hostname=connection_info.hostname, + port=connection_info.port, + importer_hostname=importer_hostname, + import_user=credential_info.import_user, + secret=credential_info.secret, + is_super_manager=manager_info.is_super_manager, + sub_manager_ids=manager_info.sub_manager_ids or [], + sub_managers=manager_info.sub_managers or [], + current_mgm_id=mgm_id, + current_mgm_is_super_manager=manager_info.is_super_manager, + domain_name=domain_info.domain_name, + domain_uid=domain_info.domain_uid, + cloud_client_id=credential_info.cloud_client_id, + cloud_client_secret=credential_info.cloud_client_secret, + ) + + @classmethod + def from_json(cls, json_dict: dict[str, Any]) -> "ManagementController": + device_info = DeviceInfo( + name=json_dict["name"], + type_name=json_dict["deviceType"]["name"], + type_version=json_dict["deviceType"]["version"], + ) + + connection_info = ConnectionInfo( + hostname=json_dict["hostname"], + port=json_dict["port"], + ) + + credential_info = CredentialInfo( + import_user=json_dict["import_credential"]["user"], + secret=json_dict["import_credential"]["secret"], + cloud_client_id=json_dict["import_credential"]["cloud_client_id"], + cloud_client_secret=json_dict["import_credential"]["cloud_client_secret"], + ) + + manager_info = ManagerInfo( + is_super_manager=json_dict["isSuperManager"], + sub_manager_ids=[subManager["id"] for subManager in json_dict["subManagers"]], + sub_managers=[cls.from_json(subManager) for subManager in json_dict["subManagers"]], + ) + domain_info = DomainInfo(domain_name=json_dict.get("configPath"), domain_uid=json_dict.get("domainUid")) + + return cls( + mgm_id=json_dict["id"], + uid=json_dict["uid"], + devices=json_dict["devices"], + device_info=device_info, + connection_info=connection_info, + importer_hostname=json_dict["importerHostname"], + credential_info=credential_info, + manager_info=manager_info, + domain_info=domain_info, + import_disabled=json_dict["importDisabled"], + ) + + def __str__(self): + return f"{self.hostname}({self.mgm_id})" + + # TODO: fix device type URIs + def build_fw_api_string(self): + if self.device_type_name == "Check Point": + return f"https://{self.hostname}:{self.port!s}/web_api/" + if self.device_type_name == "CiscoFMC": + return f"https://{self.hostname}:{self.port!s}/api/fmc_platform/v1/" + if self.device_type_name == "Fortinet": + return f"https://{self.hostname}:{self.port!s}/api/v2/" + if self.device_type_name in {"FortiAdom", "FortiManager"}: + return f"https://{self.hostname}:{self.port!s}/jsonrpc" + if self.device_type_name == "PaloAlto": + return f"https://{self.hostname}:{self.port!s}/restapi/v10.0/" + raise FwLoginFailedError(f"Unsupported device type: {self.device_type_name}") + + def get_domain_string(self) -> str: + return self.domain_uid if self.domain_uid is not None else self.domain_name # type: ignore #TODO: check if None check is needed if yes, change type # noqa: PGH003 + + @classmethod + def build_gateway_list(cls, mgm_details: "ManagementController") -> list["Gateway"]: + devs: list[Gateway] = [] + for dev in mgm_details.devices: + # check if gateway import is enabled + if dev.get("do_not_import"): + continue + devs.append( + Gateway( + Name=dev["name"], + Uid=f"{dev['name']}/{mgm_details.calc_manager_uid_hash()}", + ) + ) + return devs + + def calc_manager_uid_hash(self): + combination = f""" + {replace_none_with_empty(self.hostname)} + {replace_none_with_empty(str(self.port))} + {replace_none_with_empty(self.domain_uid)} + {replace_none_with_empty(self.domain_name)} + """ + return hashlib.sha256(combination.encode()).hexdigest() + + def get_mgm_details(self, api_conn: FwoApi, mgm_id: int) -> dict[str, Any]: + get_mgm_details_query = FwoApi.get_graphql_code( + [ + GRAPHQL_QUERY_PATH + "device/getSingleManagementDetails.graphql", + GRAPHQL_QUERY_PATH + "device/fragments/managementDetails.graphql", + GRAPHQL_QUERY_PATH + "device/fragments/subManagements.graphql", + GRAPHQL_QUERY_PATH + "device/fragments/deviceTypeDetails.graphql", + GRAPHQL_QUERY_PATH + "device/fragments/importCredentials.graphql", + ] + ) + + api_call_result = api_conn.call(get_mgm_details_query, query_variables={"mgmId": mgm_id}) + if ( + "data" not in api_call_result + or "management" not in api_call_result["data"] + or len(api_call_result["data"]["management"]) < 1 + ): + raise FwoApiFailureError("did not succeed in getting management details from FWO API") + + if "://" not in api_call_result["data"]["management"][0]["hostname"]: + # only decrypt if we have a real management and are not fetching the config from an URL + # decrypt secret read from API + try: + secret = api_call_result["data"]["management"][0]["import_credential"]["secret"] + decrypted_secret = decrypt(secret, read_main_key()) + except Exception: + raise SecretDecryptionFailedError + api_call_result["data"]["management"][0]["import_credential"]["secret"] = decrypted_secret + if "subManagers" in api_call_result["data"]["management"][0]: + for sub_mgm in api_call_result["data"]["management"][0]["subManagers"]: + try: + secret = sub_mgm["import_credential"]["secret"] + decrypted_secret = decrypt(secret, read_main_key()) + except Exception: + raise SecretDecryptionFailedError + sub_mgm["import_credential"]["secret"] = decrypted_secret + return api_call_result["data"]["management"][0] diff --git a/roles/importer/files/importer/model_controllers/route_controller.py b/roles/importer/files/importer/model_controllers/route_controller.py new file mode 100644 index 0000000000..ce957da0cd --- /dev/null +++ b/roles/importer/files/importer/model_controllers/route_controller.py @@ -0,0 +1,120 @@ +from typing import Any + +from fwo_log import FWOLogger +from model_controllers.interface_controller import InterfaceSerializable +from netaddr import IPAddress, IPNetwork + + +class Route: + def __init__( + self, + device_id: int, + target_gateway: str, + destination: str, + static: bool = True, + source: str | None = None, + interface: str | None = None, + metric: int | None = None, + distance: int | None = None, + ip_version: int = 4, + ): + self.routing_device = int(device_id) + if interface is not None: + self.interface = str(interface) + else: + self.interface = None + self.target_gateway = IPAddress(target_gateway) + self.destination = IPNetwork(destination) + if source is not None: + self.source = IPNetwork(source) + else: + self.source = None + self.static = bool(static) + if metric is not None: + self.metric = int(metric) + if distance is not None: + self.distance = int(distance) + ip_version = int(ip_version) + if ip_version not in {4, 6}: + FWOLogger.error( + "found route for destination " + str(self.destination) + " with invalid ip protocal: " + str(ip_version) + ) + else: + self.ip_version = ip_version + + def is_default_route(self): + return self.is_default_route_v4() or self.is_default_route_v6() + + def is_default_route_v4(self): + return self.ip_version == 4 and self.destination == IPNetwork("0.0.0.0/0") # noqa: PLR2004 + + def is_default_route_v6(self): + return self.ip_version == 6 and self.destination == IPNetwork("::/0") # noqa: PLR2004 + + def route_matches(self, destination: str, dev_id: int) -> bool: + ip_n = IPNetwork(self.destination).cidr + dest_n = IPNetwork(destination).cidr + return dev_id == self.routing_device and (ip_n in dest_n or dest_n in ip_n) + + def get_route_destination(self): + return self.destination + + +class RouteSerializable(Route): + def __init__(self, route_in: dict[str, Any] | Route): + if type(route_in) is dict: + self.routing_device = route_in["routing_device"] + self.interface = route_in["interface"] + self.target_gateway = str(route_in["target_gateway"]) + self.destination = str(route_in["destination"]) + if route_in["source"] is None: + self.source = None + else: + self.source = str(route_in["source"]) + self.static = route_in["static"] + self.metric = route_in["metric"] + self.distance = route_in["distance"] + self.ip_version = route_in["ip_version"] + elif isinstance(route_in, Route): + self.routing_device = route_in.routing_device + self.interface = route_in.interface + self.target_gateway = str(route_in.target_gateway) + self.destination = str(route_in.destination) + if route_in.source is None: + self.source = None + else: + self.source = str(route_in.source) + self.static = route_in.static + self.metric = route_in.metric + self.distance = route_in.distance + self.ip_version = route_in.ip_version + + +def get_route_destination(obj: Route): + return obj.destination + + +def get_matching_route_obj(destination_ip: str, routing_table: list[Route], dev_id: int) -> Route | None: + if len(routing_table) == 0: + FWOLogger.error("found empty routing table for device id " + str(dev_id)) + return None + + # assuiming routing table to be in sorted state already + for route in routing_table: + if route.route_matches(destination_ip, dev_id): + return route + + FWOLogger.warning("src nat behind interface: found no matching route in routing table - no default route?!") + return None + + +def get_ip_of_interface_obj( + interface_name: str | None, dev_id: int, interface_list: list[InterfaceSerializable] +) -> str | None: + interface_details = next( + (sub for sub in interface_list if sub.name == interface_name and sub.routing_device == dev_id), None + ) + + if interface_details is not None: + return interface_details.ip + return None diff --git a/roles/importer/files/importer/model_controllers/rulebase_link_controller.py b/roles/importer/files/importer/model_controllers/rulebase_link_controller.py new file mode 100644 index 0000000000..38e885d167 --- /dev/null +++ b/roles/importer/files/importer/model_controllers/rulebase_link_controller.py @@ -0,0 +1,69 @@ +from typing import Any + +import fwo_const +from fwo_api import FwoApi +from fwo_api_call import FwoApiCall +from fwo_log import FWOLogger +from model_controllers.import_statistics_controller import ImportStatisticsController +from models.import_state import ImportState +from models.rulebase_link import RulebaseLink, parse_rulebase_links + + +class RulebaseLinkController: + rb_links: list[RulebaseLink] + + def __init__(self) -> None: + self.rb_links = [] + + def insert_rulebase_links( + self, fwo_api_call: FwoApiCall, stats: ImportStatisticsController, rb_links: list[dict[str, Any]] + ) -> None: + query_variables = {"rulebaseLinks": rb_links} + if len(rb_links) == 0: + return + mutation = FwoApi.get_graphql_code([f"{fwo_const.GRAPHQL_QUERY_PATH}rule/insertRulebaseLinks.graphql"]) + add_result = fwo_api_call.call(mutation, query_variables=query_variables) + if "errors" in add_result: + FWOLogger.exception(f"fwo_api:insertRulebaseLinks - error while inserting: {add_result['errors']!s}") + else: + changes = add_result["data"]["insert_rulebase_link"]["affected_rows"] + stats.increment_rulebase_link_add_count(changes) + + def remove_rulebase_links( + self, + fwo_api_call: FwoApiCall, + stats: ImportStatisticsController, + import_id: int, + removed_rb_links_ids: list[int], + ) -> None: + query_variables: dict[str, Any] = {"removedRulebaseLinks": removed_rb_links_ids, "importId": import_id} + if len(removed_rb_links_ids) == 0: + return + mutation = FwoApi.get_graphql_code([f"{fwo_const.GRAPHQL_QUERY_PATH}rule/removeRulebaseLinks.graphql"]) + add_result = fwo_api_call.call(mutation, query_variables=query_variables) + if "errors" in add_result: + FWOLogger.exception(f"fwo_api:removeRulebaseLinks - error while removing: {add_result['errors']!s}") + else: + changes = add_result["data"]["update_rulebase_link"]["affected_rows"] + stats.increment_rulebase_link_delete_count(changes) + + def get_rulebase_links(self, import_state: ImportState, fwo_api_call: FwoApiCall) -> None: + gw_ids = import_state.lookup_all_gateway_ids() + if len(gw_ids) == 0: + FWOLogger.warning( + "RulebaseLinkController:get_rulebase_links - no gateway ids found for current management - skipping getting rulebase links" + ) + self.rb_links = [] + return + # we always need to provide gwIds since rulebase_links may be duplicate across different gateways + query_variables = {"gwIds": gw_ids} + + query = FwoApi.get_graphql_code(file_list=[f"{fwo_const.GRAPHQL_QUERY_PATH}rule/getRulebaseLinks.graphql"]) + links = fwo_api_call.call(query, query_variables=query_variables) + if "errors" in links: + FWOLogger.exception(f"fwo_api:getRulebaseLinks - error while getting rulebaseLinks: {links['errors']!s}") + else: + parsable_rulebase_links = [ + link for link in links["data"]["rulebase_link"] if link.get("created") is not None + ] # TODO: is this necessary or was the bug some corrupted local db stuff? But why does integration test fail? + self.rb_links: list[RulebaseLink] = parse_rulebase_links(parsable_rulebase_links) diff --git a/roles/importer/files/importer/models/__init__.py b/roles/importer/files/importer/models/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/roles/importer/files/importer/models/action.py b/roles/importer/files/importer/models/action.py new file mode 100644 index 0000000000..bf55cb7683 --- /dev/null +++ b/roles/importer/files/importer/models/action.py @@ -0,0 +1,7 @@ +from pydantic import BaseModel + + +class Action(BaseModel): + action_id: int + action_name: str + allowed: bool = True diff --git a/roles/importer/files/importer/models/caseinsensitiveenum.py b/roles/importer/files/importer/models/caseinsensitiveenum.py new file mode 100644 index 0000000000..2da76f5d4b --- /dev/null +++ b/roles/importer/files/importer/models/caseinsensitiveenum.py @@ -0,0 +1,14 @@ +from enum import Enum + + +class CaseInsensitiveEnum(str, Enum): + @classmethod + def _missing_(cls, value: object) -> object | None: + if isinstance(value, str): + s = value.strip() + for member in cls: + # match either the value or the name, case-insensitive + if s.lower() in (member.value.lower(), member.name.lower()): + return member + # returning None -> Enum will raise the usual ValueError + return None diff --git a/roles/importer/files/importer/models/fw_common.py b/roles/importer/files/importer/models/fw_common.py new file mode 100644 index 0000000000..03e9766c9d --- /dev/null +++ b/roles/importer/files/importer/models/fw_common.py @@ -0,0 +1,17 @@ +from abc import ABC, abstractmethod + +from model_controllers.fwconfigmanagerlist_controller import FwConfigManagerListController +from model_controllers.import_state_controller import ImportStateController + + +class FwCommon(ABC): + def has_config_changed( + self, _full_config: FwConfigManagerListController, _import_state: ImportStateController, _force: bool = False + ) -> bool: + return True + + @abstractmethod + def get_config( + self, config_in: FwConfigManagerListController, import_state: ImportStateController + ) -> tuple[int, FwConfigManagerListController]: + raise NotImplementedError("Please Implement this method") diff --git a/roles/importer/files/importer/models/fwconfig.py b/roles/importer/files/importer/models/fwconfig.py new file mode 100644 index 0000000000..2de36298df --- /dev/null +++ b/roles/importer/files/importer/models/fwconfig.py @@ -0,0 +1,15 @@ +from typing import Any + +from fwo_base import ConfFormat +from pydantic import BaseModel + +""" + the configuraton of a firewall management to import + could be normalized or native config + management could be standard of super manager (MDS, fortimanager) +""" + + +class FwConfig(BaseModel): + ConfigFormat: ConfFormat + FwConf: dict[str, Any] = {} diff --git a/roles/importer/files/importer/models/fwconfig_normalized.py b/roles/importer/files/importer/models/fwconfig_normalized.py new file mode 100644 index 0000000000..7e4972ce97 --- /dev/null +++ b/roles/importer/files/importer/models/fwconfig_normalized.py @@ -0,0 +1,99 @@ +from typing import Any + +from fwo_base import ConfFormat, ConfigAction +from models.gateway import Gateway +from models.networkobject import NetworkObject +from models.rulebase import Rulebase +from models.serviceobject import ServiceObject +from models.time_object import TimeObject +from pydantic import BaseModel + + +class FwConfig(BaseModel): + ConfigFormat: ConfFormat = ConfFormat.NORMALIZED + + +""" + the normalized configuraton of a firewall management to import + this applies to a single management which might be either a global or a stand-alone management + + FwConfigNormalized: + { + 'action': 'INSERT|UPDATE|DELETE', + 'network_objects': [ ... ], + 'service_objects': [ ... ], + 'users': [...], + 'zone_objects': [ ... ], + 'policies': [ + { + 'policy_name': 'pol1', + 'policy_uid': 'a32bc348234-23432a', + 'rules': [ { ... }, { ... }, ... ] + } + ], + 'gateways': # this is also a change, so these mappings are only listed once for insertion + { + 'gw-uid-1': { + 'name': 'gw1', + 'global_policy_uid': 'pol-global-1', + 'policies': ['policy_uid_1', 'policy_uid_2'] # here order is the order of policies on the gateway + } + } + + } + + write methods to + a) split a config into < X MB chunks + b) combine configs to a single config + +""" + + +class FwConfigNormalized(FwConfig): + action: ConfigAction = ConfigAction.INSERT + network_objects: dict[str, NetworkObject] = {} + service_objects: dict[str, ServiceObject] = {} + users: dict[str, Any] = {} + zone_objects: dict[str, Any] = {} + time_objects: dict[str, TimeObject] = {} + rulebases: list[Rulebase] = [] + gateways: list[Gateway] = [] + ConfigFormat: ConfFormat = ConfFormat.NORMALIZED + + model_config = {"arbitrary_types_allowed": True} + + def get_rulebase(self, rulebase_uid: str) -> Rulebase: + """ + Get the policy with a specific uid + + Args: + rulebase_uid (str): The UID of the relevant policy. + + Returns: + Rulebase: Returns the policy with a specific uid. + + Raises: + KeyError: If no policy with the given uid is found. + + """ + rulebase = self.get_rulebase_or_none(rulebase_uid) + if rulebase is not None: + return rulebase + + raise KeyError(f"Rulebase with UID {rulebase_uid} not found.") + + def get_rulebase_or_none(self, rulebase_uid: str) -> Rulebase | None: + """ + Get the policy with a specific uid + + Args: + rulebase_uid (str): The UID of the relevant policy. + + Returns: + Rulebase | None: Returns the policy with a specific uid or None if not found. + + """ + for rb in self.rulebases: + if rb.uid == rulebase_uid: + return rb + return None diff --git a/roles/importer/files/importer/models/fwconfigmanager.py b/roles/importer/files/importer/models/fwconfigmanager.py new file mode 100644 index 0000000000..f26c84243a --- /dev/null +++ b/roles/importer/files/importer/models/fwconfigmanager.py @@ -0,0 +1,25 @@ +from typing import Any + +from models.fwconfig_normalized import FwConfigNormalized +from pydantic import BaseModel, ConfigDict, Field +from pydantic.alias_generators import to_pascal + + +class FwConfigManager(BaseModel): + model_config = ConfigDict(alias_generator=to_pascal, validate_by_name=True) + + manager_uid: str = Field(description="Unique identifier string of the management") + manager_name: str = Field(description="Name of the management") + is_super_manager: bool = Field(description="Indicates if the management is a super manager", default=False) + domain_uid: str | None = Field(default=None, description="Domain UID") + domain_name: str | None = Field(default=None, description="Domain name") + sub_manager_ids: list[int] = Field(default=[], description="List of sub-manager IDs") + configs: list[FwConfigNormalized] = Field(description="List of normalized firewall configurations") + + def model_dump(self, **kwargs: Any) -> dict[str, Any]: + kwargs.setdefault("by_alias", True) + return super().model_dump(**kwargs) + + def model_dump_json(self, **kwargs: Any) -> str: + kwargs.setdefault("by_alias", True) + return super().model_dump_json(**kwargs) diff --git a/roles/importer/files/importer/models/fwconfigmanagerlist.py b/roles/importer/files/importer/models/fwconfigmanagerlist.py new file mode 100644 index 0000000000..1f9d0fe9a9 --- /dev/null +++ b/roles/importer/files/importer/models/fwconfigmanagerlist.py @@ -0,0 +1,23 @@ +from typing import Any + +from fwo_enums import ConfFormat +from models.fwconfigmanager import FwConfigManager +from pydantic import BaseModel + +""" + a list of normalized configuratons of a firewall management to import + FwConfigManagerList: [ FwConfigManager ] +""" + + +class FwConfigManagerList(BaseModel): + ConfigFormat: ConfFormat = ConfFormat.NORMALIZED + ManagerSet: list[FwConfigManager] = [] + native_config: ( + dict[str, Any] | None + ) = {} # native config as dict, if available # TODO: change inital value to None? + + model_config = {"arbitrary_types_allowed": True} + + def __str__(self): + return f"{self.ManagerSet!s})" diff --git a/roles/importer/files/importer/models/fworch_config.py b/roles/importer/files/importer/models/fworch_config.py new file mode 100644 index 0000000000..5b3926207c --- /dev/null +++ b/roles/importer/files/importer/models/fworch_config.py @@ -0,0 +1,11 @@ +""" +the configuraton of a firewall orchestrator itself +as read from the global config file including FWO URI +""" + + +class FworchConfig: + fwo_api_url: str + fwo_user_mgmt_api_uri: str | None + api_fetch_size: int + importer_password: str | None diff --git a/roles/importer/files/importer/models/gateway.py b/roles/importer/files/importer/models/gateway.py new file mode 100644 index 0000000000..1be452acb6 --- /dev/null +++ b/roles/importer/files/importer/models/gateway.py @@ -0,0 +1,29 @@ +from typing import Any + +from models.rulebase_link import RulebaseLinkUidBased +from pydantic import BaseModel + +""" +Gateway + { + 'gw-uid-1': { + 'name': 'gw1', + 'global_policy_uid': 'pol-global-1', + 'policies': ['policy_uid_1', 'policy_uid_2'] # here order is the order of policies on the gateway + 'nat-policies': ['nat_policy_uid_1'] # is always only a single policy? + } +} +""" + + +class Gateway(BaseModel): + Uid: str | None = None + Name: str | None = None + Routing: list[dict[str, Any]] = [] + Interfaces: list[dict[str, Any]] = [] + RulebaseLinks: list[RulebaseLinkUidBased] = [] + GlobalPolicyUid: str | None = None + EnforcedPolicyUids: list[str] | None = [] + EnforcedNatPolicyUids: list[str] | None = [] + ImportDisabled: bool = False + ShowInUI: bool = True diff --git a/roles/importer/files/importer/models/import_state.py b/roles/importer/files/importer/models/import_state.py new file mode 100644 index 0000000000..ab5985b542 --- /dev/null +++ b/roles/importer/files/importer/models/import_state.py @@ -0,0 +1,123 @@ +import time + +from fwo_exceptions import FwoImporterError +from fwo_log import FWOLogger +from model_controllers.fworch_config_controller import FworchConfigController +from model_controllers.import_statistics_controller import ImportStatisticsController +from model_controllers.management_controller import ManagementController + +"""Used for storing state during import process per management""" + + +class ImportState: + debug_level: int + verify_certs: bool = False + config_changed_since_last_import: bool + fwo_config: FworchConfigController + mgm_details: ManagementController + import_id: int = -1 + import_file_name: str = "" + force_import: bool + import_version: int + data_retention_days: int + days_since_last_full_import: int + last_full_import_id: int + last_full_import_date: str | None = None + last_successful_import: str | None = None + is_initial_import: bool = False + responsible_for_importing: bool = True + is_clearing_import: bool = False + + def __init__(self) -> None: + self.stats: ImportStatisticsController = ImportStatisticsController() + self.start_time: int = int(time.time()) + self.actions: dict[str, int] = {} + self.tracks: dict[str, int] = {} + self.link_types: dict[str, int] = {} + self.gateway_map: dict[int, dict[str, int]] = {} + self.rulebase_map: dict[str, int] = {} + self.management_map: dict[str, int] = {} + self.color_map: dict[str, int] = {} + self.network_obj_type_map: dict[str, int] = {} + self.service_obj_type_map: dict[str, int] = {} + self.user_obj_type_map: dict[str, int] = {} + self.protocol_map: dict[str, int] = {} + self.data_retention_days: int = 30 + + def lookup_action(self, action_str: str) -> int: + action_id = self.actions.get(action_str.lower(), None) + if action_id is None: + FWOLogger.error(f"Action {action_str} not found") + raise FwoImporterError(f"Action {action_str} not found") + return action_id + + def lookup_track(self, track_str: str) -> int: + track_id = self.tracks.get(track_str.lower(), None) + if track_id is None: + FWOLogger.error(f"Track {track_str} not found") + raise FwoImporterError(f"Track {track_str} not found") + return track_id + + def lookup_link_type(self, link_uid: str) -> int: + link_type_id = self.link_types.get(link_uid, None) + if not link_type_id: + FWOLogger.error(f"Link type {link_uid} not found") + raise FwoImporterError(f"Link type {link_uid} not found") + return link_type_id + + def lookup_network_obj_type_id(self, obj_type_str: str) -> int: + obj_type_id = self.network_obj_type_map.get(obj_type_str, None) + if obj_type_id is None: + FWOLogger.error(f"Network object type {obj_type_str} not found") + raise FwoImporterError(f"Network object type {obj_type_str} not found") + return obj_type_id + + def lookup_service_obj_type_id(self, svc_type_str: str) -> int: + obj_type_id = self.service_obj_type_map.get(svc_type_str, None) + if obj_type_id is None: + FWOLogger.error(f"Service object type {svc_type_str} not found") + raise FwoImporterError(f"Service object type {svc_type_str} not found") + return obj_type_id + + def lookup_user_obj_type_id(self, usr_type_str: str) -> int: + obj_type_id = self.user_obj_type_map.get(usr_type_str, None) + if obj_type_id is None: + FWOLogger.error(f"User object type {usr_type_str} not found") + raise FwoImporterError(f"User object type {usr_type_str} not found") + return obj_type_id + + def lookup_protocol_id(self, proto_str: str) -> int: + proto_id = self.protocol_map.get(proto_str.lower(), None) + if proto_id is None: + FWOLogger.error(f"Protocol {proto_str} not found") + raise FwoImporterError(f"Protocol {proto_str} not found") + return proto_id + + def lookup_gateway_id(self, gw_uid: str) -> int: + mgm_id = self.mgm_details.current_mgm_id + gws_for_mgm = self.gateway_map.get(mgm_id, {}) + gw_id = gws_for_mgm.get(gw_uid, None) + if gw_id is None: + FWOLogger.error( + f"fwo_api:import_latest_config - no gateway id found for current mgm id '{mgm_id}' and gateway uid '{gw_uid}' in {len(gws_for_mgm)} known gateways for this mgm" + ) + raise FwoImporterError( + f"fwo_api:import_latest_config - no gateway id found for current mgm id '{mgm_id}' and gateway uid '{gw_uid}' in {len(gws_for_mgm)} known gateways for this mgm" + ) + return gw_id + + def lookup_all_gateway_ids(self) -> list[int]: + mgm_id = self.mgm_details.current_mgm_id + gws_for_mgm = self.gateway_map.get(mgm_id, {}) + return list(gws_for_mgm.values()) + + def lookup_management_id(self, mgm_uid: str) -> int | None: + if not self.management_map.get(mgm_uid, None): + FWOLogger.error(f"fwo_api:import_latest_config - no mgm id found for current manager uid '{mgm_uid}'") + return self.management_map.get(mgm_uid, None) + + def lookup_color_id_unresolved(self, color_str: str) -> int | None: + return self.color_map.get(color_str, None) + + def lookup_color_id(self, color_str: str) -> int: + return self.color_map.get(color_str, 1) # 1 = forground color black diff --git a/roles/importer/files/importer/models/import_statistics.py b/roles/importer/files/importer/models/import_statistics.py new file mode 100644 index 0000000000..7f0ad4125a --- /dev/null +++ b/roles/importer/files/importer/models/import_statistics.py @@ -0,0 +1,32 @@ +class ImportStatistics: + network_object_add_count: int = 0 + network_object_delete_count: int = 0 + network_object_change_count: int = 0 + service_object_add_count: int = 0 + service_object_delete_count: int = 0 + service_object_change_count: int = 0 + user_object_add_count: int = 0 + user_object_delete_count: int = 0 + user_object_change_count: int = 0 + zone_object_add_count: int = 0 + zone_object_delete_count: int = 0 + time_object_add_count: int = 0 + time_object_delete_count: int = 0 + time_object_change_count: int = 0 + rule_add_count: int = 0 + rule_delete_count: int = 0 + rule_change_count: int = 0 + rule_move_count: int = 0 # when a rule is moved. implies rule_change_count + rule_ref_add_count: int = 0 # e.g. rule_to, rule_nwobj_resolved, rule_enforced_on_gateway + rule_ref_delete_count: int = 0 + rulebase_add_count: int = 0 + rulebase_change_count: int = 0 + rulebase_delete_count: int = 0 + rulebase_link_add_count: int = 0 + rulebase_link_delete_count: int = 0 + inconsistent_nwobj_delete_count: int = 0 + inconsistent_svcobj_delete_count: int = 0 + inconsistent_userobj_delete_count: int = 0 + inconsistent_rule_delete_count: int = 0 + inconsistent_rulebase_link_delete_count: int = 0 + inconsistent_ref_delete_count: int = 0 diff --git a/roles/importer/files/importer/models/management.py b/roles/importer/files/importer/models/management.py new file mode 100644 index 0000000000..26f7e5c416 --- /dev/null +++ b/roles/importer/files/importer/models/management.py @@ -0,0 +1,27 @@ +from typing import Any + +from pydantic import BaseModel + + +class Management(BaseModel): + mgm_id: int + name: str + uid: str + is_super_manager: bool + hostname: str + import_disabled: bool + devices: list[dict[str, Any]] + importer_hostname: str + device_type_name: str + device_type_version: str + port: int + import_user: str + secret: str + sub_manager_ids: list[int] + current_mgm_id: int + current_mgm_is_super_manager: bool + domain_name: str | None + domain_uid: str | None + sub_managers: list["Management"] + cloud_client_id: str | None = None + cloud_client_secret: str | None = None diff --git a/roles/importer/files/importer/models/networkobject.py b/roles/importer/files/importer/models/networkobject.py new file mode 100644 index 0000000000..ba2e8b3a30 --- /dev/null +++ b/roles/importer/files/importer/models/networkobject.py @@ -0,0 +1,94 @@ +from typing import Any + +from netaddr import AddrFormatError, IPNetwork +from pydantic import BaseModel, field_serializer, field_validator + + +class NetworkObject(BaseModel): + obj_uid: str + obj_name: str + obj_ip: IPNetwork | None = None + obj_ip_end: IPNetwork | None = None + obj_color: str + obj_typ: str + obj_member_refs: str | None = None + obj_member_names: str | None = None + obj_comment: str | None = None + + @field_validator("obj_ip", "obj_ip_end", mode="before") + @classmethod + def convert_strings_to_ip_objects(cls, value: object, info: Any) -> IPNetwork | None: + """ + Convert string values to IPNetwork objects, treating 'None' or empty as None. + """ + if value is None: + return None + if isinstance(value, IPNetwork): + return value + + s = str(value).strip() + if s.lower() == "none" or s == "": + return None + + try: + return IPNetwork(s) + except AddrFormatError as e: + raise ValueError(f"Invalid {info.field_name} network format: {value}") from e + + @field_serializer("obj_ip", "obj_ip_end") + def serialize_ipnetwork(self, value: IPNetwork | None, _info: Any) -> str | None: + """ + Serialize IPNetwork objects to strings, keeping None as None. + """ + return None if value is None else str(value) + + model_config = {"arbitrary_types_allowed": True} + + +class NetworkObjectForImport: + obj_uid: str + obj_name: str + obj_ip: str | None + obj_ip_end: str | None + obj_color_id: int | None + obj_member_refs: str | None + obj_member_names: str | None + obj_comment: str | None + mgm_id: int + obj_create: int + obj_last_seen: int + obj_typ_id: int + + def __init__(self, nw_object: NetworkObject, mgm_id: int, import_id: int, color_id: int, typ_id: int): + self.obj_uid = nw_object.obj_uid + self.obj_name = nw_object.obj_name + self.obj_ip = str(nw_object.obj_ip) + self.obj_ip_end = str(nw_object.obj_ip_end) + self.obj_color_id = color_id + self.obj_member_refs = nw_object.obj_member_refs + self.obj_member_names = nw_object.obj_member_names + self.obj_comment = nw_object.obj_comment + self.mgm_id = mgm_id + self.obj_create = import_id + self.obj_last_seen = import_id + self.obj_typ_id = typ_id + + def to_dict(self) -> dict[str, Any]: + result: dict[str, Any] = { + "obj_uid": self.obj_uid, + "obj_name": self.obj_name, + "obj_color_id": self.obj_color_id, + "obj_member_refs": self.obj_member_refs, + "obj_member_names": self.obj_member_names, + "obj_comment": self.obj_comment, + "mgm_id": self.mgm_id, + "obj_create": self.obj_create, + "obj_last_seen": self.obj_last_seen, + "obj_typ_id": self.obj_typ_id, + } + + if self.obj_ip is not None and self.obj_ip != "None": + result.update({"obj_ip": self.obj_ip}) + if self.obj_ip_end is not None and self.obj_ip_end != "None": + result.update({"obj_ip_end": self.obj_ip_end}) + return result diff --git a/roles/importer/files/importer/models/rule.py b/roles/importer/files/importer/models/rule.py new file mode 100644 index 0000000000..ffd78d48f3 --- /dev/null +++ b/roles/importer/files/importer/models/rule.py @@ -0,0 +1,184 @@ +from datetime import datetime, timezone + +from models.caseinsensitiveenum import CaseInsensitiveEnum +from pydantic import BaseModel, field_validator + + +class RuleType(CaseInsensitiveEnum): + ACCESS = "access" + NAT = "nat" + ACCESSANDNAT = "accessandnat" + SECTIONHEADER = "sectionheader" + + +class RuleAction(CaseInsensitiveEnum): + ACCEPT = "accept" + DROP = "drop" + REJECT = "reject" + CLIENTAUTH = "client auth" + INNERLAYER = "inner layer" + INFORM = "inform" + ASK = "ask" + + +class RuleTrack(CaseInsensitiveEnum): + NONE = "none" + LOG = "log" + ALERT = "alert" + DETAILEDLOG = "detailed log" + EXTENDEDLOG = "extended log" + USERDEFINED = "userdefined" + MAIL = "mail" + ACCOUNT = "account" + USERDEFINED1 = "userdefined 1" + USERDEFINED2 = "userdefined 2" + USERDEFINED3 = "userdefined 3" + SNMPTRAP = "snmptrap" + + +# RuleNormalized is the model for a normalized rule (containing no DB IDs) +class RuleNormalized(BaseModel): # noqa: PLW1641 + rule_num: int + rule_num_numeric: float + rule_disabled: bool + rule_src_neg: bool + rule_src: str + rule_src_refs: str + rule_dst_neg: bool + rule_dst: str + rule_dst_refs: str + rule_svc_neg: bool + rule_svc: str + rule_svc_refs: str + rule_action: RuleAction + rule_track: RuleTrack + rule_installon: str | None = None + rule_time: str | None = None + rule_name: str | None = None + rule_uid: str | None = None + rule_custom_fields: str | None = None + rule_implied: bool + rule_type: RuleType = RuleType.SECTIONHEADER + last_change_admin: str | None = None + parent_rule_uid: str | None = None + last_hit: str | None = None + rule_comment: str | None = None + rule_src_zone: str | None = None + rule_dst_zone: str | None = None + rule_head_text: str | None = None + + @field_validator("last_hit") + @classmethod + def validate_last_hit_format(cls, value: str | None) -> str | None: + if value is None: + return value + try: + normalized_value = value.replace("Z", "+00:00") + parsed_time = datetime.fromisoformat(normalized_value) + if parsed_time.tzinfo is None: + parsed_time = parsed_time.replace(tzinfo=timezone.utc) + return parsed_time.astimezone(timezone.utc).isoformat(timespec="seconds") + except ValueError: + raise ValueError( + f"Rule last_hit value '{value}' does not match format 'YYYY-MM-DDTHH:MM:SS+HH:MM'" + ) from None + + def __eq__(self, other: object) -> bool: + if not isinstance(other, RuleNormalized): + return NotImplemented + # Compare all fields except 'last_hit' and 'rule_num' and zones + # Zones are excluded because they are currently not written to the rule directly, + # only linked through rule_from_zone and rule_to_zone tables (similar to _resolved tables) + exclude = {"last_hit", "rule_num", "rule_src_zone", "rule_dst_zone"} + self_dict = self.model_dump(exclude=exclude) + other_dict = other.model_dump(exclude=exclude) + return self_dict == other_dict + + +""" + based on public.rule: + + "rule_id" BIGSERIAL, + "last_change_admin" Integer, + "rule_name" Varchar, + "mgm_id" Integer NOT NULL, + "parent_rule_id" BIGINT, + "parent_rule_type" smallint, + "active" Boolean NOT NULL Default TRUE, + "removed" BIGINT, + "rule_num" Integer NOT NULL, + "rule_num_numeric" NUMERIC(16, 8), + "rule_ruleid" Varchar, + "rule_uid" Text, + "rule_disabled" Boolean NOT NULL Default false, + "rule_src_neg" Boolean NOT NULL Default false, + "rule_dst_neg" Boolean NOT NULL Default false, + "rule_svc_neg" Boolean NOT NULL Default false, + "action_id" Integer NOT NULL, + "track_id" Integer NOT NULL, + "rule_src" Text NOT NULL, + "rule_dst" Text NOT NULL, + "rule_svc" Text NOT NULL, + "rule_src_refs" Text, + "rule_dst_refs" Text, + "rule_svc_refs" Text, + "rule_from_zone" Integer, + "rule_to_zone" Integer, + "rule_action" Text NOT NULL, + "rule_track" Text NOT NULL, + "rule_installon" Varchar, + "rule_time" Varchar, + "rule_comment" Text, + "rule_head_text" Text, + "rule_implied" Boolean NOT NULL Default FALSE, + "rule_create" BIGINT NOT NULL, + "rule_last_seen" BIGINT NOT NULL, + "dev_id" Integer, + "rule_custom_fields" jsonb, + "access_rule" BOOLEAN Default TRUE, + "nat_rule" BOOLEAN Default FALSE, + "xlate_rule" BIGINT, + "is_global" BOOLEAN DEFAULT FALSE NOT NULL, + "rulebase_id" Integer NOT NULL, +""" + + +# Rule is the model for a rule to be imported into the DB (containing IDs) +class Rule(BaseModel): + access_rule: bool = True + action_id: int + is_global: bool = False + last_change_admin: int | None = None + mgm_id: int + nat_rule: bool = False + parent_rule_id: int | None = None + removed: int | None = None + rule_action: str + rule_comment: str | None = None + rule_create: int + rule_custom_fields: str | None = None + rule_disabled: bool + rule_dst: str + rule_dst_neg: bool + rule_dst_refs: str + rule_from_zone: int | None = None + rule_head_text: str | None = None + rule_implied: bool = False + rule_installon: str | None = None + rule_last_seen: int + rule_name: str | None = None + rule_num: int + rule_num_numeric: float + rule_src: str + rule_src_neg: bool + rule_src_refs: str + rule_svc: str + rule_svc_neg: bool + rule_svc_refs: str + rule_time: str | None = None + rule_to_zone: int | None = None + track_id: int + xlate_rule: int | None = None + rule_track: str + rule_uid: str | None = None + rulebase_id: int | None = None diff --git a/roles/importer/files/importer/models/rule_enforced_on_gateway.py b/roles/importer/files/importer/models/rule_enforced_on_gateway.py new file mode 100644 index 0000000000..0ef7b0c8fb --- /dev/null +++ b/roles/importer/files/importer/models/rule_enforced_on_gateway.py @@ -0,0 +1,34 @@ +from typing import Any + +from pydantic import BaseModel + + +# the model for a connection between a rule and a gateway +# each rule has to be linked to the gateway the rule is enforced on +# this is e.g. used for the "install on" feature in Check Point +class RuleEnforcedOnGateway(BaseModel): + # "rule_id" Integer NOT NULL, + # "dev_id" Integer, -- NULL if rule is available for all gateways of its management + # "created" BIGINT, + # "removed" BIGINT + rule_id: int + dev_id: int + created: int | None + removed: int | None + + def __init__(self, rule_id: int, dev_id: int, created: int | None = None, removed: int | None = None) -> None: + self.rule_id = rule_id + self.dev_id = dev_id + self.created = created + self.removed = removed + + def to_dict(self) -> dict[str, Any]: + return {"rule_id": self.rule_id, "dev_id": self.dev_id, "created": self.created, "removed": self.removed} + + +# normalized config without db ids +class RuleEnforcedOnGatewayNormalized(BaseModel): + rule_uid: str + dev_uid: str + + model_config = {"arbitrary_types_allowed": True} diff --git a/roles/importer/files/importer/models/rule_from.py b/roles/importer/files/importer/models/rule_from.py new file mode 100644 index 0000000000..354e2aae0c --- /dev/null +++ b/roles/importer/files/importer/models/rule_from.py @@ -0,0 +1,14 @@ +from pydantic import BaseModel + + +# RuleFrom is the model for a normalized rule (containing DB IDs) +# does not contain the rule_from_id primary key as this one is set by the database +class RuleFrom(BaseModel): + active: bool = True + rule_id: int + obj_id: int + rf_create: int + rf_last_seen: int + removed: int | None = None + user_id: int | None = None + negated: bool = False diff --git a/roles/importer/files/importer/models/rule_metadatum.py b/roles/importer/files/importer/models/rule_metadatum.py new file mode 100644 index 0000000000..ae11bcb4b2 --- /dev/null +++ b/roles/importer/files/importer/models/rule_metadatum.py @@ -0,0 +1,14 @@ +from pydantic import BaseModel + + +# Rule is the model for a normalized rule_metadata +class RuleMetadatum(BaseModel): + rule_uid: str + mgm_id: int + rule_created: int + rule_last_hit: str | None = None + + +# RuleForImport is the model for a rule to be imported into the DB (containing IDs) +class RuleMetadatumForImport(RuleMetadatum): + rule_metadata_id: int | None = None diff --git a/roles/importer/files/importer/models/rule_service.py b/roles/importer/files/importer/models/rule_service.py new file mode 100644 index 0000000000..ca59126b6f --- /dev/null +++ b/roles/importer/files/importer/models/rule_service.py @@ -0,0 +1,11 @@ +from pydantic import BaseModel + + +class RuleService(BaseModel): + active: bool = True + rule_id: int + svc_id: int + rs_create: int + rs_last_seen: int + removed: int | None = None + negated: bool = False diff --git a/roles/importer/files/importer/models/rule_to.py b/roles/importer/files/importer/models/rule_to.py new file mode 100644 index 0000000000..81079929f5 --- /dev/null +++ b/roles/importer/files/importer/models/rule_to.py @@ -0,0 +1,14 @@ +from pydantic import BaseModel + + +# RuleTo is the model for a normalized rule (containing DB IDs) +# does not contain the rule_to_id primary key as this one is set by the database +class RuleTo(BaseModel): + active: bool = True + rule_id: int + obj_id: int + rt_create: int + rt_last_seen: int + removed: int | None = None + user_id: int | None = None + negated: bool = False diff --git a/roles/importer/files/importer/models/rulebase.py b/roles/importer/files/importer/models/rulebase.py new file mode 100644 index 0000000000..457d674945 --- /dev/null +++ b/roles/importer/files/importer/models/rulebase.py @@ -0,0 +1,53 @@ +from models.rule import RuleNormalized +from pydantic import BaseModel + + +# Rulebase is the model for a rulebase (containing no DB IDs) +class Rulebase(BaseModel): + uid: str + name: str + mgm_uid: str + is_global: bool = False + rules: dict[str, RuleNormalized] = {} + + def to_json(self) -> dict[str, object]: + return { + "uid": self.uid, + "name": self.name, + "mgm_uid": self.mgm_uid, + "is_global": self.is_global, + "rules": {uid: rule.model_dump() for uid, rule in self.rules.items()}, + } + + +# RulebaseForImport is the model for a rule to be imported into the DB (containing IDs) +""" + based on public.rulebase: + + # "id" SERIAL primary key, + # "name" Varchar NOT NULL, + # "uid" Varchar NOT NULL, + # "mgm_id" Integer NOT NULL, + # "is_global" BOOLEAN DEFAULT FALSE NOT NULL, + # "created" BIGINT, + # "removed" BIGINT +""" + + +class RulebaseForImport(BaseModel): + name: str + uid: str + mgm_id: int + is_global: bool = False + created: int + removed: int | None = None + + @classmethod + def from_rulebase(cls, rulebase: Rulebase, mgm_id: int, created: int) -> "RulebaseForImport": + return cls( + name=rulebase.name, + uid=rulebase.uid, + mgm_id=mgm_id, + is_global=rulebase.is_global, + created=created, + ) diff --git a/roles/importer/files/importer/models/rulebase_link.py b/roles/importer/files/importer/models/rulebase_link.py new file mode 100644 index 0000000000..2ef6e8f7d1 --- /dev/null +++ b/roles/importer/files/importer/models/rulebase_link.py @@ -0,0 +1,59 @@ +from typing import Any + +from pydantic import BaseModel, ConfigDict, TypeAdapter + + +# RulebaseLinkUidBased is the model for a rulebase_link (containing no DB IDs) +class RulebaseLinkUidBased(BaseModel): + from_rulebase_uid: str | None = None + from_rule_uid: str | None = None + to_rulebase_uid: str + link_type: str = "section" + is_initial: bool + is_global: bool + is_section: bool + + def to_dict(self) -> dict[str, object | str | bool | None]: + return { + "from_rule_uid": self.from_rule_uid, + "from_rulebase_uid": self.from_rulebase_uid, + "to_rulebase_uid": self.to_rulebase_uid, + "link_type": self.link_type, + "is_initial": self.is_initial, + "is_global": self.is_global, + "is_section": self.is_section, + } + + +class RulebaseLink(BaseModel): + id: int | None = None # will be created during db import + gw_id: int + from_rule_id: int | None = None # null for initial rulebase + from_rulebase_id: int | None = None # either from_rule_id or from_rulebase_id must be set + to_rulebase_id: int + link_type: int = 1 + is_initial: bool + is_global: bool + is_section: bool + created: int + removed: int | None = None + model_config = ConfigDict(populate_by_name=True) + + def to_dict(self) -> dict[str, Any]: + return { + "gw_id": self.gw_id, + "from_rule_id": self.from_rule_id, + "from_rulebase_id": self.from_rulebase_id, + "to_rulebase_id": self.to_rulebase_id, + "link_type": self.link_type, + "is_initial": self.is_initial, + "is_global": self.is_global, + "is_section": self.is_section, + "created": self.created, + "removed": self.removed, + } + + +def parse_rulebase_links(data: list[dict[str, Any]]) -> list[RulebaseLink]: + adapter = TypeAdapter(list[RulebaseLink]) + return adapter.validate_python(data) diff --git a/roles/importer/files/importer/models/serviceobject.py b/roles/importer/files/importer/models/serviceobject.py new file mode 100644 index 0000000000..522745bf21 --- /dev/null +++ b/roles/importer/files/importer/models/serviceobject.py @@ -0,0 +1,73 @@ +from typing import Any + +from pydantic import BaseModel + + +class ServiceObject(BaseModel): + svc_uid: str + svc_name: str + svc_port: int | None = None + svc_port_end: int | None = None + svc_color: str + svc_typ: str # TODO: ENUM + ip_proto: int | None = None + svc_member_refs: str | None = None + svc_member_names: str | None = None + svc_comment: str | None = None + svc_timeout: int | None = None + rpc_nr: str | None = None + + +class ServiceObjectForImport: + svc_uid: str + svc_name: str + svc_port: int | None + svc_port_end: int | None + svc_color_id: int + svc_typ: str # TODO: ENUM + ip_proto_id: int | None + svc_member_refs: str | None + svc_member_names: str | None + svc_comment: str | None + svc_timeout: int | None + svc_rpcnr: str | None + mgm_id: int + svc_create: int + svc_last_seen: int + svc_typ_id: int + + def __init__(self, svc_object: ServiceObject, mgm_id: int, import_id: int, color_id: int, typ_id: int): + self.svc_uid = svc_object.svc_uid + self.svc_name = svc_object.svc_name + self.svc_port = svc_object.svc_port + self.svc_port_end = svc_object.svc_port_end + self.svc_color_id = color_id + self.svc_typ_id = typ_id + self.ip_proto_id = svc_object.ip_proto + self.svc_member_refs = svc_object.svc_member_refs + self.svc_member_names = svc_object.svc_member_names + self.svc_comment = svc_object.svc_comment + self.svc_timeout = svc_object.svc_timeout + self.svc_rpcnr = svc_object.rpc_nr + self.mgm_id = mgm_id + self.svc_create = import_id + self.svc_last_seen = import_id + + def to_dict(self) -> dict[str, Any]: + return { + "svc_uid": self.svc_uid, + "svc_name": self.svc_name, + "svc_port": self.svc_port, + "svc_port_end": self.svc_port_end, + "ip_proto_id": self.ip_proto_id, + "svc_color_id": self.svc_color_id, + "svc_member_refs": self.svc_member_refs, + "svc_member_names": self.svc_member_names, + "svc_comment": self.svc_comment, + "svc_create": self.svc_create, + "svc_last_seen": self.svc_last_seen, + "svc_typ_id": self.svc_typ_id, + "svc_rpcnr": self.svc_rpcnr, + "svc_timeout": self.svc_timeout, + "mgm_id": self.mgm_id, + } diff --git a/roles/importer/files/importer/models/time_object.py b/roles/importer/files/importer/models/time_object.py new file mode 100644 index 0000000000..6bd5875e19 --- /dev/null +++ b/roles/importer/files/importer/models/time_object.py @@ -0,0 +1,65 @@ +import re +from datetime import datetime, timezone + +from pydantic import BaseModel, field_validator + + +class TimeObject(BaseModel): + time_obj_uid: str + time_obj_name: str + start_time: str | None = None + end_time: str | None = None + + # time format must be like '1970-01-01T00:00:00+00:00'. + # needs to match format from database, otherwise changes will be detected for all time objects during import + # we only write UTC times to the database, so we convert any timezone-aware time to UTC and store it in that format + @field_validator("start_time", "end_time") + @classmethod + def validate_time_format(cls, value: str | None) -> str | None: + if value is None: + return value + try: + parsed_time = cls._parse_iso_timestamp(value) + if parsed_time.tzinfo is None: + parsed_time = parsed_time.replace(tzinfo=timezone.utc) + return parsed_time.astimezone(timezone.utc).isoformat(timespec="seconds") + except ValueError: + raise ValueError( + f"Time value '{value}' does not match supported ISO formats " + "'YYYY-MM-DDTHH:MM:SS', 'YYYY-MM-DDTHH:MM:SSZ', 'YYYY-MM-DDTHH:MM:SS+HH:MM', or 'YYYY-MM-DDTHH:MM:SS+HHMM'." + ) from None + + @staticmethod + def _parse_iso_timestamp(value: str) -> datetime: + normalized_value = value.strip().replace("Z", "+00:00") + + # Python 3.10 is stricter and does not always parse offsets like +0000. + # Convert +HHMM / -HHMM to +HH:MM / -HH:MM before parsing. + if re.search(r"[+-]\d{4}$", normalized_value): + normalized_value = f"{normalized_value[:-5]}{normalized_value[-5:-2]}:{normalized_value[-2:]}" + + return datetime.fromisoformat(normalized_value) + + +class TimeObjectForImport(BaseModel): + """ + TimeObject model containing all fields required for import into the database. + """ + + mgm_id: int + time_obj_uid: str + time_obj_name: str + start_time: str | None = None + end_time: str | None = None + created: int + + @classmethod + def from_normalized(cls, time_obj: TimeObject, mgm_id: int, import_id: int) -> "TimeObjectForImport": + return cls( + time_obj_uid=time_obj.time_obj_uid, + time_obj_name=time_obj.time_obj_name, + start_time=time_obj.start_time, + end_time=time_obj.end_time, + mgm_id=mgm_id, + created=import_id, + ) diff --git a/roles/importer/files/importer/models/track.py b/roles/importer/files/importer/models/track.py new file mode 100644 index 0000000000..5816a9e559 --- /dev/null +++ b/roles/importer/files/importer/models/track.py @@ -0,0 +1,6 @@ +from pydantic import BaseModel + + +class Track(BaseModel): + track_id: int + track_name: str diff --git a/roles/importer/files/importer/paloaltomanagement2023ff/discovery_logging.conf b/roles/importer/files/importer/paloaltomanagement2023ff/discovery_logging.conf deleted file mode 100644 index 139c55a9cb..0000000000 --- a/roles/importer/files/importer/paloaltomanagement2023ff/discovery_logging.conf +++ /dev/null @@ -1,41 +0,0 @@ -[loggers] -keys=root,discoveryDebugLogger -#keys=root,__main__ - -[handlers] -keys=consoleHandler,debugFileHandler - -[formatters] -keys=defaultFormatter,debugFileFormatter - -[logger_root] -level=DEBUG -handlers=consoleHandler - -[logger_discoveryDebugLogger] -#[logger___main__] -level=DEBUG -handlers=debugFileHandler -qualname=discoveryDebugLogger -#qualname=__main__ -propagate=0 - -[handler_consoleHandler] -class=StreamHandler -level=DEBUG -formatter=defaultFormatter -args=(sys.stderr,) - -[handler_debugFileHandler] -class=FileHandler -level=DEBUG -formatter=debugFileFormatter -args=('/tmp/fworch_discovery.log',) -# args=('/var/log/fworch/discovery.log',) - -[formatter_defaultFormatter] -format=%(levelname)s:%(name)s:%(message)s - -[formatter_debugFileFormatter] -format=%(asctime)s - %(name)s - %(levelname)s - %(message)s - diff --git a/roles/importer/files/importer/paloaltomanagement2023ff/fwcommon.py b/roles/importer/files/importer/paloaltomanagement2023ff/fwcommon.py deleted file mode 100644 index 87de874495..0000000000 --- a/roles/importer/files/importer/paloaltomanagement2023ff/fwcommon.py +++ /dev/null @@ -1,101 +0,0 @@ -import sys -from common import importer_base_dir -sys.path.append(importer_base_dir + "/paloaltomanagement2023ff") -from palo_service import normalize_svcobjects -from palo_application import normalize_application_objects -from palo_rule import normalize_access_rules -from palo_network import normalize_nwobjects -from palo_zone import normalize_zones -from palo_getter import login, update_config_with_palofw_api_call -from fwo_log import getFwoLogger -from palo_base import api_version_str - -def has_config_changed(full_config, mgm_details, force=False): - # dummy - may be filled with real check later on - return True - - -def get_config(config2import, full_config, current_import_id, mgm_details, limit=1000, force=False, jwt=''): - logger = getFwoLogger() - if full_config == {}: # no native config was passed in, so getting it from Azzure - parsing_config_only = False - else: - parsing_config_only = True - - if not parsing_config_only: # no native config was passed in, so getting it from Palo Firewall - apipwd = mgm_details["import_credential"]['secret'] - apiuser = mgm_details["import_credential"]['user'] - apihost = mgm_details["hostname"] - - vsys_objects = ["/Network/Zones", "/Objects/Addresses", "/Objects/Services", "/Objects/AddressGroups", "/Objects/ServiceGroups", "/Objects/Tags"] - predef_objects = ["/Objects/Applications"] - rulebase_names = ["/Policies/SecurityRules", "/Policies/NATRules"] - - for obj_path in vsys_objects: - full_config[obj_path] = [] - - for obj_path in predef_objects: - full_config[obj_path] = [] - - # login - key = login(apiuser, apipwd, apihost) - if key == None or key == "": - logger.error('Did not succeed in logging in to Palo API, no key returned.') - return 1 - - ## get objects: - base_url = "https://{apihost}/restapi/v{api_version_str}".format(apihost=apihost, api_version_str=api_version_str) - - vsys_name = "vsys1" # TODO - automate this hard-coded name - location = "vsys" # alternative: panorama-pushed - - for obj_path in vsys_objects: - update_config_with_palofw_api_call(key, base_url, full_config, obj_path + "?location={location}&vsys={vsys_name}".format(location=location, vsys_name=vsys_name), obj_type=obj_path) - - for obj_path in predef_objects: - update_config_with_palofw_api_call(key, base_url, full_config, obj_path + "?location={location}".format(location="predefined"), obj_type=obj_path) - - # users - - # get rules - full_config.update({'devices': {}}) - for device in mgm_details["devices"]: - dev_id = device['id'] - dev_name = device['local_rulebase_name'] - full_config['devices'].update({ dev_id: {} }) - - for obj_path in rulebase_names: - update_config_with_palofw_api_call( - key, base_url, full_config['devices'][device['id']], - obj_path + "?location={location}&vsys={vsys_name}".format(location="vsys", vsys_name=dev_name), - obj_type=obj_path) - - ################## - # now we normalize relevant parts of the raw config and write the results to config2import dict - - normalize_nwobjects(full_config, config2import, current_import_id, jwt=jwt, mgm_id=mgm_details['id']) - normalize_svcobjects(full_config, config2import, current_import_id) - normalize_application_objects(full_config, config2import, current_import_id) - # normalize_users(full_config, config2import, current_import_id, user_scope) - - # adding default any and predefined objects - any_nw_svc = {"svc_uid": "any_svc_placeholder", "svc_name": "any", "svc_comment": "Placeholder service.", - "svc_typ": "simple", "ip_proto": -1, "svc_port": 0, "svc_port_end": 65535, "control_id": current_import_id} - http_svc = {"svc_uid": "http_predefined_svc", "svc_name": "service-http", "svc_comment": "Predefined service", - "svc_typ": "simple", "ip_proto": 6, "svc_port": 80, "control_id": current_import_id} - https_svc = {"svc_uid": "https_predefined_svc", "svc_name": "service-https", "svc_comment": "Predefined service", - "svc_typ": "simple", "ip_proto": 6, "svc_port": 443, "control_id": current_import_id} - - config2import["service_objects"].append(any_nw_svc) - config2import["service_objects"].append(http_svc) - config2import["service_objects"].append(https_svc) - - any_nw_object = {"obj_uid": "any_obj_placeholder", "obj_name": "any", "obj_comment": "Placeholder object.", - "obj_typ": "network", "obj_ip": "0.0.0.0/0", "control_id": current_import_id} - config2import["network_objects"].append(any_nw_object) - - normalize_zones(full_config, config2import, current_import_id) - normalize_access_rules(full_config, config2import, current_import_id, mgm_details=mgm_details) - # normalize_nat_rules(full_config, config2import, current_import_id, jwt=jwt) - - return 0 diff --git a/roles/importer/files/importer/paloaltomanagement2023ff/palo_application.py b/roles/importer/files/importer/paloaltomanagement2023ff/palo_application.py deleted file mode 100644 index 4652fa0c6a..0000000000 --- a/roles/importer/files/importer/paloaltomanagement2023ff/palo_application.py +++ /dev/null @@ -1,37 +0,0 @@ -from fwo_const import list_delimiter -from fwo_log import getFwoLogger - - -def normalize_application_objects(full_config, config2import, import_id): - app_objects = [] - for app_orig in full_config["/Objects/Applications"]: - app_objects.append(parse_app(app_orig, import_id,config2import)) - config2import['service_objects'] += app_objects - - -def extract_base_app_infos(app_orig, import_id): - app = {} - if "@name" in app_orig: - app["svc_uid"] = app_orig["@name"] - app["svc_name"] = app_orig["@name"] - if "comment" in app_orig: - app["svc_comment"] = app_orig["comment"] - app["control_id"] = import_id - app["svc_typ"] = 'simple' - return app - - -def parse_app(app_orig, import_id,config2import): - svc = extract_base_app_infos(app_orig, import_id) - app_comment = '' - if 'category' in app_orig: - app_comment = "category: " + app_orig['category'] - if 'subcategory' in app_orig: - app_comment += ", " + "subcategory: " + app_orig['subcategory'] - if 'technology' in app_orig: - app_comment += ", " + "technology: " + app_orig['technology'] - if 'svc_comment' in svc: - svc['svc_comment'] += "; " + app_comment - else: - svc['svc_comment'] = app_comment - return svc diff --git a/roles/importer/files/importer/paloaltomanagement2023ff/palo_base.py b/roles/importer/files/importer/paloaltomanagement2023ff/palo_base.py deleted file mode 100644 index e4a69e545f..0000000000 --- a/roles/importer/files/importer/paloaltomanagement2023ff/palo_base.py +++ /dev/null @@ -1,2 +0,0 @@ - -api_version_str="9.1" diff --git a/roles/importer/files/importer/paloaltomanagement2023ff/palo_getter.py b/roles/importer/files/importer/paloaltomanagement2023ff/palo_getter.py deleted file mode 100644 index 4e926c638b..0000000000 --- a/roles/importer/files/importer/paloaltomanagement2023ff/palo_getter.py +++ /dev/null @@ -1,100 +0,0 @@ -# library for API get functions -import base64 -from typing import Dict -from fwo_log import getFwoLogger -import requests.packages -import requests -import xmltodict, json -import fwo_globals -from fwo_exception import FwLoginFailed - - -def api_call(url, params = {}, headers = {}, data = {}, key = '', show_progress=False, method='get'): - logger = getFwoLogger() - result_type='xml' - request_headers = {'Content-Type': 'application/json'} - for header_key in headers: - request_headers[header_key] = headers[header_key] - if key != '': - request_headers["X-PAN-KEY"] = '{key}'.format(key=key) - result_type='json' - - if method == "post": - response = requests.post(url, params=params, data=data, headers=request_headers, verify=fwo_globals.verify_certs) - elif method == "get": - response = requests.get(url, params=params, headers=request_headers, verify=fwo_globals.verify_certs) - else: - raise Exception("unknown HTTP method found in palo_getter") - - # error handling: - exception_text = '' - if response is None: - if 'password' in json.dumps(data): - exception_text = "error while sending api_call containing credential information to url '" + \ - str(url) - else: - exception_text = "error while sending api_call to url '" + str(url) + "' with payload '" + json.dumps( - data, indent=2) + "' and headers: '" + json.dumps(request_headers, indent=2) - if not response.ok: - exception_text = 'error code: {error_code}, error={error}'.format(error_code=response.status_code, error=response.content) - #logger.error(response.content) - if (len(response.content) == 0): - exception_text = 'empty response content' - - if exception_text != '': - raise Exception(exception_text) - - # no errors found - if result_type=='xml': - r = xmltodict.parse(response.content) - body_json = json.loads(json.dumps(r)) - elif result_type=='json': - body_json = json.loads(response.content) - if 'result' in body_json: - body_json = body_json['result'] - - else: - body_json = None - - # if fwo_globals.debug_level > 5: - # if 'pass' in json.dumps(data): - # logger.debug("api_call containing credential information to url '" + - # str(url) + " - not logging query") - # else: - # logger.debug("api_call to url '" + str(url) + "' with payload '" + json.dumps( - # data, indent=2) + "' and headers: '" + json.dumps(request_headers, indent=2)) - - return body_json - - -def login(apiuser, apipwd, apihost): - base_url = "https://{apihost}/api/?type=keygen&user={apiuser}&password={apipwd}".format(apihost=apihost, apiuser=apiuser, apipwd=apipwd) - try: - body = api_call(base_url, method="get", headers={}, data={}) - except Exception as e: - raise FwLoginFailed("Palo FW login to firewall=" + str(apihost) + " failed; Message: " + str(e)) from None - - if 'response' in body and 'result' in body['response'] and 'key' in body['response']['result'] and not body['response']['result']['key'] == None: - key = body['response']['result']['key'] - else: - raise FwLoginFailed("Palo FW login to firewall=" + str(apihost) + " failed") from None - - if fwo_globals.debug_level > 2: - logger = getFwoLogger() - logger.debug("Login successful. Received key: " + key) - - return key - - -def update_config_with_palofw_api_call(key, api_base_url, config, api_path, obj_type='generic', parameters={}, payload={}, show_progress=False, limit: int=1000, method="get"): - returned_new_data = True - - full_result = [] - result = api_call(api_base_url + api_path,key=key, params=parameters, data=payload, show_progress=show_progress, method=method) - if "entry" in result: - returned_new_data = len(result['entry'])>0 - else: - returned_new_data = False - if returned_new_data: - full_result.extend(result["entry"]) - config.update({obj_type: full_result}) diff --git a/roles/importer/files/importer/paloaltomanagement2023ff/palo_network.py b/roles/importer/files/importer/paloaltomanagement2023ff/palo_network.py deleted file mode 100644 index 252ba38cf2..0000000000 --- a/roles/importer/files/importer/paloaltomanagement2023ff/palo_network.py +++ /dev/null @@ -1,175 +0,0 @@ -from asyncio.log import logger -from fwo_log import getFwoLogger -from fwo_const import list_delimiter -import ipaddress - - -def normalize_nwobjects(full_config, config2import, import_id, jwt=None, mgm_id=None): - logger = getFwoLogger() - nw_objects = [] - nw_tagged_groups = {} - for obj_orig in full_config["/Objects/Addresses"]: - nw_objects.append(parse_object(obj_orig, import_id, config2import, nw_objects)) - if 'tag' in obj_orig and 'member' in obj_orig['tag']: - logger.info("found simple network object with tags: " + obj_orig['@name']) - for t in obj_orig['tag']['member']: - collect_tag_information(nw_tagged_groups, "#"+t, obj_orig['@name']) - - for tag in nw_tagged_groups: - logger.info("handling nw_tagged_group: " + tag + " with members: " + list_delimiter.join(nw_tagged_groups[tag])) - obj = {} - obj["obj_name"] = tag - obj["obj_uid"] = tag - obj["obj_comment"] = 'dynamic group defined by tagging' - obj['control_id'] = import_id - obj['obj_typ'] = 'group' - members = nw_tagged_groups[tag] # parse_dynamic_object_group(obj_grp_orig, nw_tagged_groups) - obj['obj_members'] = list_delimiter.join(members) - obj['obj_member_refs'] = list_delimiter.join(members) - nw_objects.append(obj) - - for obj_grp_orig in full_config["/Objects/AddressGroups"]: - logger.info("found network group: " + obj_grp_orig['@name']) - obj_grp = extract_base_object_infos(obj_grp_orig, import_id, config2import, nw_objects) - obj_grp["obj_typ"] = "group" - if 'static' in obj_grp_orig and 'filter' in obj_grp_orig['static']: - obj_grp["obj_member_refs"], obj_grp["obj_member_names"] = parse_static_obj_group(obj_grp_orig, import_id, nw_objects, config2import) - if 'dynamic' in obj_grp_orig and 'filter' in obj_grp_orig['dynamic']: - members = parse_dynamic_object_group(obj_grp_orig, nw_tagged_groups) - obj_grp["obj_member_refs"] = list_delimiter.join(members) - obj_grp["obj_member_names"] = list_delimiter.join(members) - nw_objects.append(obj_grp) - if 'tag' in obj_grp_orig and 'member' in obj_grp_orig['tag']: - logger.info("found network group with tags: " + obj_grp_orig['@name']) - for t in obj_grp_orig['tag']['member']: - logger.info(" found tag " + t) - collect_tag_information(nw_tagged_groups, "#"+t, obj_grp_orig['@name']) - - config2import['network_objects'] = nw_objects - - -def parse_object(obj_orig, import_id, config2import, nw_objects): - obj = extract_base_object_infos(obj_orig, import_id, config2import, nw_objects) - obj['obj_ip'] = obj_orig['ip-netmask'] - if '/' in obj['obj_ip'] and not '/32' in obj['obj_ip']: - obj['obj_typ'] = 'network' - else: - obj['obj_typ'] = 'host' - return obj - - -def extract_base_object_infos(obj_orig, import_id, config2import, nw_objects): - obj = {} - obj["obj_name"] = obj_orig["@name"] - obj["obj_uid"] = obj_orig["@name"] - if 'description' in obj_orig: - obj["obj_comment"] = obj_orig["description"] - if 'tag' in obj_orig: - tag_list = ",".join(obj_orig["tag"]['member']) - if 'obj_comment' in obj: - obj["obj_comment"] += ("; tags: " + tag_list) - else: - obj["obj_comment"] = tag_list - obj['control_id'] = import_id - return obj - - -def parse_dynamic_object_group(orig_grp, nw_tagged_groups): - if "dynamic" in orig_grp: - if 'filter' in orig_grp['dynamic']: - if ' ' not in orig_grp['dynamic']['filter']: - # just a single tag - # add all nw objects with the tag to this group - tag = "#" + orig_grp['dynamic']['filter'][1:-1] - if tag in nw_tagged_groups: - return nw_tagged_groups[tag] - else: - # later: deal with more complex tagging (and/or) - return [] - return [] - - -def parse_static_obj_group(orig_grp, import_id, nw_objects, config2import, id = None): - refs = [] - names = [] - - if "static" in orig_grp and "member" in orig_grp["static"]: - for m in orig_grp['static']['member']: - names.append(m) - refs.append(m) - return list_delimiter.join(refs), list_delimiter.join(names) - - -def parse_obj_list(nw_obj_list, import_id, obj_list, id, type='network'): - refs = [] - names = [] - for obj_name in nw_obj_list: - names.append(obj_name) - refs.append(lookup_obj_uid(obj_name, obj_list, import_id, type=type)) - return list_delimiter.join(refs), list_delimiter.join(names) - - -def lookup_obj_uid(obj_name, obj_list, import_id, type='network'): - for o in obj_list: - if type=='network' and 'obj_name' in o: - if o['obj_name']==obj_name: - return o['obj_uid'] - elif type=='service' and 'svc_name' in o: - if o['svc_name']==obj_name: - return o['svc_uid'] - else: - logger.warning("could not find object name in object " + str(o)) - - # could not find existing obj in obj list, so creating new one - if type=='network': - refs, names = add_ip_obj([obj_name], obj_list, import_id) - return refs ## assuming only one object here - elif type=='service': - logger.warning("could not find service object " + str(obj_name)) - else: - logger.warning("unknown object type '" + type + "' for object " + str(obj_name)) - return None - - -def add_ip_obj(ip_list, obj_list, import_id): - refs = [] - names = [] - for ip in ip_list: - # TODO: lookup ip in network_objects and re-use - ip_obj = {} - ip_obj['obj_name'] = ip - ip_obj['obj_uid'] = ip_obj['obj_name'] - try: - ipaddress.ip_network(ip) - # valid ip - ip_obj['obj_ip'] = ip - except: - # no valid ip - asusming Tag - ip_obj['obj_ip'] = '0.0.0.0/0' - ip = '0.0.0.0/0' - ip_obj['obj_name'] = "#"+ip_obj['obj_name'] - ip_obj['obj_uid'] = ip_obj['obj_name'] - ip_obj['obj_type'] = 'simple' - ip_obj['obj_typ'] = 'host' - if "/" in ip: - ip_obj['obj_typ'] = 'network' - - if "-" in ip: # ip range - ip_obj['obj_typ'] = 'ip_range' - ip_range = ip.split("-") - ip_obj['obj_ip'] = ip_range[0] - ip_obj['obj_ip_end'] = ip_range[1] - - ip_obj['control_id'] = import_id - - obj_list.append(ip_obj) - refs.append(ip_obj['obj_uid']) - names.append(ip_obj['obj_name']) - return list_delimiter.join(refs), list_delimiter.join(names) - - -def collect_tag_information(tagged_groups, tag, obj_name): - if tag in tagged_groups.keys(): - tagged_groups[tag].append(obj_name) - else: - tagged_groups.update({tag: [obj_name]}) diff --git a/roles/importer/files/importer/paloaltomanagement2023ff/palo_rule.py b/roles/importer/files/importer/paloaltomanagement2023ff/palo_rule.py deleted file mode 100644 index 36d1945907..0000000000 --- a/roles/importer/files/importer/paloaltomanagement2023ff/palo_rule.py +++ /dev/null @@ -1,143 +0,0 @@ -from palo_service import parse_svc_list -from palo_network import parse_obj_list -from fwo_log import getFwoLogger -from fwo_const import list_delimiter -import hashlib -import base64 - - -def make_hash_sha256(o): - hasher = hashlib.sha256() - hasher.update(repr(make_hashable(o)).encode()) - return base64.b64encode(hasher.digest()).decode() - - -def make_hashable(o): - if isinstance(o, (tuple, list)): - return tuple((make_hashable(e) for e in o)) - - if isinstance(o, dict): - return tuple(sorted((k,make_hashable(v)) for k,v in o.items())) - - if isinstance(o, (set, frozenset)): - return tuple(sorted(make_hashable(e) for e in o)) - - return o - - -def normalize_access_rules(full_config, config2import, import_id, mgm_details={}): - rules = [] - - nw_obj_names = [] - for o in config2import['network_objects']: - nw_obj_names.append(o["obj_name"]) - - for device in full_config["devices"]: - rule_number = 0 - for dev_id in full_config['devices'].keys(): - for rulebase in list(full_config['devices'][dev_id].keys()): - for rule_orig in full_config['devices'][dev_id][rulebase]: - rule = {'rule_src': 'any', 'rule_dst': 'any', 'rule_svc': 'any', - 'rule_src_refs': 'any_obj_placeholder', 'rule_dst_refs': 'any_obj_placeholder', - 'rule_src_neg': False, 'rule_dst_neg': False, - 'rule_svc_refs': 'any_svc_placeholder'} - if 'negate-source' in rule_orig and rule_orig['negate-source']=='yes': - rule["rule_src_neg"] = True - if 'negate-destination' in rule_orig and rule_orig['negate-destination']=='yes': - rule["rule_dst_neg"] = True - rule.update({ - "rule_svc_neg": False, # not possible to negate the svc field on Palo - "rulebase_name": rule_orig['@vsys'], - "rule_name": rule_orig['@name'], - 'rule_type': 'access', - 'rule_num': rule_number, - 'rule_installon': rule_orig['@vsys'], - 'parent_rule_id': None, - 'rule_time': None, - 'rule_implied': False, - 'rule_comment': None, - 'rule_track': 'None', - 'rule_uid': rule_orig['@uuid'], - 'rule_disabled': False, - 'control_id': import_id - }) - - if "action" in rule_orig: - if rule_orig['action']=='allow': - rule['rule_action'] = 'accept' - elif rule_orig['action']=='drop': - rule['rule_action'] = 'drop' - elif rule_orig['action']=='deny': - rule['rule_action'] = 'deny' - elif rule_orig['action']=='reset-client': - rule['rule_action'] = 'reject' - else: - print ("found undefined action:" + str(rule_orig)) - else: # NAT rules - rule['rule_action'] = "accept" - rule['rule_type'] = 'nat' - - # TODO: should either duplicate the rule for each zone to zone pair - # or much better allow for n:m rule:zone mappings --> change of DB necessary - # instead we are just picking the last one!!! - for z in rule_orig['from']['member']: - rule.update({'rule_from_zone': z}) - for z in rule_orig['to']['member']: - rule.update({'rule_to_zone': z}) - - if 'disabled' in rule_orig and rule_orig['disabled']=='yes': - rule['rule_disabled'] = True - if 'log-start' in rule_orig: - if rule_orig['log-start']=='yes': - rule['rule_track'] = 'all start' - elif rule_orig['log-start']=='no': - rule['rule_track'] = 'None' - else: - print ("found undefined track:" + str(rule_orig)) - rule['rule_track'] = 'None' - else: - rule['rule_track'] = 'None' - - if "source" in rule_orig: - if 'member' in rule_orig["source"]: - source_objects = rule_orig["source"]["member"] - else: - source_objects = [rule_orig["service"]] - rule['rule_src_refs'], rule["rule_src"] = parse_obj_list(source_objects, import_id, config2import['network_objects'], rule["rule_uid"]) - else: - print ("found undefined source in rule: " + str(rule_orig)) - - if "destination" in rule_orig: - if 'member' in rule_orig["destination"]: - destination_objects = rule_orig["destination"]["member"] - else: - destination_objects = [rule_orig["destination"]] - rule['rule_dst_refs'], rule["rule_dst"] = parse_obj_list(destination_objects, import_id, config2import['network_objects'], rule["rule_uid"]) - else: - print ("found undefined destination in rule: " + str(rule_orig)) - - services = [] - if "service" in rule_orig: - if 'member' in rule_orig['service']: - services = rule_orig["service"]["member"] - else: - services = [rule_orig["service"]] - if services[0] == 'application-default' or services[0] == 'any': - services = [] - apps = [] - if 'application' in rule_orig: - # no services given but applications - parse apps - if 'member' in rule_orig['application']: - # apps = ['any'] ## TEMP before app parsing - apps = rule_orig["application"]["member"] - else: - apps = [rule_orig["application"]] - if apps[0] == 'any': - apps = [] - - rule['rule_svc_refs'], rule["rule_svc"] = parse_svc_list(apps + services, import_id, config2import['service_objects'], rule["rule_uid"], type='service') - - rule_number += 1 - rules.append(rule) - - config2import['rules'] += rules diff --git a/roles/importer/files/importer/paloaltomanagement2023ff/palo_service.py b/roles/importer/files/importer/paloaltomanagement2023ff/palo_service.py deleted file mode 100644 index c8d932f7b4..0000000000 --- a/roles/importer/files/importer/paloaltomanagement2023ff/palo_service.py +++ /dev/null @@ -1,134 +0,0 @@ -from fwo_const import list_delimiter -from fwo_log import getFwoLogger - - -def normalize_svcobjects(full_config, config2import, import_id): - svc_objects = [] - for svc_orig in full_config["/Objects/Services"]: - svc_objects.append(parse_svc(svc_orig, import_id,config2import)) - for svc_grp_orig in full_config["/Objects/ServiceGroups"]: - svc_grp = extract_base_svc_infos(svc_grp_orig, import_id) - svc_grp["svc_typ"] = "group" - svc_grp["svc_member_refs"] , svc_grp["svc_member_names"] = parse_svc_group(svc_grp_orig,config2import) - svc_objects.append(svc_grp) - config2import['service_objects'] += svc_objects - - -def parse_svc_group(orig_grp,config2import): - refs = [] - names = [] - if "dynamic" in orig_grp: - pass - if "static" in orig_grp and "member" in orig_grp["static"]: - for m in orig_grp['static']['member']: - names.append(m) - refs.append(m) - return list_delimiter.join(refs), list_delimiter.join(names) - - -def extract_base_svc_infos(svc_orig, import_id): - svc = {} - if "@name" in svc_orig: - svc["svc_uid"] = svc_orig["@name"] - svc["svc_name"] = svc_orig["@name"] - if "comment" in svc_orig: - svc["svc_comment"] = svc_orig["comment"] - svc["svc_timeout"] = None - svc["svc_color"] = None - svc["control_id"] = import_id - svc["svc_typ"] = 'simple' - return svc - - -def parse_svc(svc_orig, import_id,config2import): - svc = extract_base_svc_infos(svc_orig, import_id) - if 'protocol' in svc_orig: - proto_string = 'undefined' - if 'tcp' in svc_orig['protocol']: - svc["ip_proto"] = 6 - proto_string = 'tcp' - svc["svc_port"] = svc_orig['protocol']['tcp']['port'] - elif 'udp' in svc_orig['protocol']: - svc["ip_proto"] = 17 - proto_string = 'udp' - - if proto_string=='undefined': - svc["svc_name"] += " [Protocol \"" + str(svc_orig["protocol"]) + "\" not supported]" - else: - port_string = svc_orig['protocol'][proto_string]['port'] - if ',' in port_string: - svc["svc_typ"] = "group" - svc["svc_port"] = None - members = [] - for p in port_string.split(","): - hlp_svc = create_helper_service(p, proto_string, svc["svc_name"], import_id) - add_service(hlp_svc, config2import) - members.append(hlp_svc['svc_uid']) - svc["svc_members"] = list_delimiter.join(members) - svc["svc_member_refs"] = list_delimiter.join(members) - else: # just a single port (range) - extract_port_for_service(port_string, svc) - return svc - - -def add_service(svc, config2import): - config2import['service_objects'].append(svc) - - -def extract_port_for_service(port_string, svc): - if '-' in port_string: - port_range = port_string.split("-") - if len(port_range)==2: - svc["svc_port"] = port_range[0] - svc["svc_port_end"] = port_range[1] - else: - logger = getFwoLogger() - logger.warning("found strange port range with more than one hyphen: " + str(port_string)) - else: - svc["svc_port"] = port_string - - -def create_helper_service(ports, proto_string, parent_svc_name, import_id): - svc = { - "svc_name": parent_svc_name + "_" + proto_string + "_" + ports, - "svc_uid": parent_svc_name + "_" + proto_string + "_" + ports, - "svc_comment": "helper service for Palo Alto multiple port range object: " + parent_svc_name, - "control_id": import_id, - "svc_typ": 'simple' - } - - extract_port_for_service(ports, svc) - return svc - - -def parse_svc_list(nw_obj_list, import_id, obj_list, id, type='network'): - refs = [] - names = [] - for obj_name in nw_obj_list: - names.append(obj_name) - refs.append(lookup_svc_obj_uid(obj_name, obj_list, import_id, type=type)) - return list_delimiter.join(refs), list_delimiter.join(names) - - -def lookup_svc_obj_uid(obj_name, obj_list, import_id, type='network'): - logger = getFwoLogger() - for o in obj_list: - if type=='service' and 'svc_name' in o: - if o['svc_name']==obj_name: - return o['svc_uid'] - else: - logger.warning("could not find object name in object " + str(o)) - - # could not find existing obj in obj list, so creating new one - return add_svc_obj(obj_name, obj_list, import_id) - - -def add_svc_obj(svc_in, svc_list, import_id): - svc_obj = {} - svc_obj['svc_name'] = "#" + svc_in - svc_obj['svc_uid'] = "#" + svc_in - svc_obj['control_id'] = import_id - svc_obj['svc_typ'] = 'simple' - - svc_list.append(svc_obj) - return svc_obj['svc_name'] diff --git a/roles/importer/files/importer/paloaltomanagement2023ff/palo_zone.py b/roles/importer/files/importer/paloaltomanagement2023ff/palo_zone.py deleted file mode 100644 index a55f86dc95..0000000000 --- a/roles/importer/files/importer/paloaltomanagement2023ff/palo_zone.py +++ /dev/null @@ -1,15 +0,0 @@ -from asyncio.log import logger -from fwo_log import getFwoLogger -from fwo_const import list_delimiter - - -def normalize_zones(full_config, config2import, import_id): - zones = [] - for zone_orig in full_config["/Network/Zones"]: - zones.append({ - "zone_name": zone_orig["@name"], - "zone_uid": zone_orig["@name"], - "control_id": import_id - }) - - config2import['zone_objects'] = zones diff --git a/roles/importer/files/importer/query_analyzer.py b/roles/importer/files/importer/query_analyzer.py new file mode 100644 index 0000000000..26e3ad15d7 --- /dev/null +++ b/roles/importer/files/importer/query_analyzer.py @@ -0,0 +1,167 @@ +try: + # GraphQL-core v3+ + from graphql import parse, print_ast, visit + from graphql.language import Visitor + from graphql.language.ast import DocumentNode as Document # type: ignore # noqa: PGH003 + from graphql.language.ast import OperationDefinitionNode as OperationDefinition + from graphql.language.ast import VariableDefinitionNode as VariableDefinition +except ImportError: + # GraphQL-core v2 + from graphql import parse, print_ast, visit + from graphql.language.ast import Document, OperationDefinition, VariableDefinition # type: ignore # noqa: PGH003 + from graphql.language.visitor import Visitor + +from typing import Any + +from fwo_const import API_CALL_CHUNK_SIZE + + +class QueryAnalyzer(Visitor): + """ + A class for analyzing GraphQL queries. + """ + + _ast: Document | None + _variable_definitions: dict[str, dict[str, Any]] + _query_string: str + _query_variables: dict[str, Any] + _query_info: dict[str, Any] + + @property + def variable_definitions(self) -> dict[str, dict[str, Any]]: + """Returns the dictionary of extracted variable definitions.""" + return self._variable_definitions + + @property + def ast(self) -> Document | None: # type: ignore # noqa: PGH003 + """Returns the AST.""" + return self._ast # type: ignore # noqa: PGH003 + + @property + def query_string(self) -> str: + """Returns the original query string.""" + return self._query_string + + @property + def query_variables(self) -> dict[str, Any]: + """Returns the provided query variables.""" + return self._query_variables + + def __init__(self): + super().__init__() + self._ast = None + self._variable_definitions = {} + self._query_string = "" + self._query_variables = {} + self._query_info = {} + + def analyze_payload(self, query_string: str, query_variables: dict[str, Any] | None = None) -> dict[str, Any]: + """ + Analyzes a GraphQL query and returns information about it. + """ + self._ast = parse(query_string) + self._query_string = query_string + self._query_variables = query_variables or {} + self._variable_definitions = {} + + # Apply visitor pattern (calls enter_* methods) + + visit(self._ast, self) # type: ignore # noqa: PGH003 + + # Analyze necessity of chunking and parameters that are necessary for the chunking process. + + needs_chunking, adjusted_chunk_size, list_elements_length, chunkable_variables = self._get_chunking_info( + query_variables + ) + self._query_info["chunking_info"] = { + "needs_chunking": needs_chunking, + "adjusted_chunk_size": adjusted_chunk_size, + "chunkable_variables": chunkable_variables, + "total_elements": list_elements_length, + } + + return self._query_info + + def get_adjusted_chunk_size(self, lists_in_query_variable: dict[str, Any]) -> int: + """ + Gets an adjusted chunk size. + """ + return ( + int( + API_CALL_CHUNK_SIZE + / len([list_object for list_object in lists_in_query_variable.values() if len(list_object) > 0]) + ) + or 1 + ) + + def enter_OperationDefinition(self, node: OperationDefinition, *_): # type: ignore # noqa: N802, PGH003 + """ + Called by visit function for each variable definition in the AST. + """ + self.enter_operation_definition(node) # type: ignore # noqa: PGH003 + + def enter_VariableDefinition(self, node: VariableDefinition, *_): # type: ignore # noqa: N802, PGH003 + """ + Called by visit function for each variable definition in the AST. + """ + self.enter_variable_definition(node) # type: ignore # noqa: PGH003 + + def enter_operation_definition(self, node: OperationDefinition, *_): # type: ignore # noqa: PGH003 + """ + Called by visit function for each variable definition in the AST. + """ + self._query_info["query_type"] = node.operation # type: ignore # noqa: PGH003 + self._query_info["query_name"] = node.name.value if node.name else "" # type: ignore # noqa: PGH003 + + def enter_variable_definition(self, node: VariableDefinition, *_): # type: ignore # noqa: PGH003 + """ + Called by visit function for each variable definition in the AST. + """ + var_name = node.variable.name.value # type: ignore # noqa: PGH003 + type_str = print_ast(node.type) # type: ignore # noqa: PGH003 + + # Store information about the variable definitions. + + if "query_args" not in self._query_info: + self._query_info["query_args"] = {} + + self._query_info["query_args"][var_name] = type_str + + self._variable_definitions[var_name] = { + "type": type_str, + "required": "!" in type_str, + "is_list": "[" in type_str, + } + + # If a value was provided for this variable, store it. + + if var_name in self._query_variables: + self._variable_definitions[var_name]["provided_value"] = self._query_variables[var_name] + + def _get_chunking_info(self, query_variables: dict[str, Any] | None) -> tuple[bool, int, int, list[str]]: + # Get all query variables of type list. + query_vars = query_variables or {} + + lists_in_query_variable: dict[str, Any] = { + chunkable_variable_name: list_object + for chunkable_variable_name, list_object in query_vars.items() + if isinstance(list_object, list) + } + + # If there is no list typed query variable there is nothing chunkable. + + if not lists_in_query_variable or len(lists_in_query_variable.items()) == 0: + return False, 0, 0, [] + + list_elements_length = sum(len(list_object) for list_object in lists_in_query_variable.values()) + + # If the number of all elements is lower than the configured threshold, there is no need for chunking. + + if list_elements_length < API_CALL_CHUNK_SIZE: + return False, 0, 0, [] + + # If there are more than one chunkable variable, the chunk_size has to be adjusted accordingly. + + adjusted_chunk_size = self.get_adjusted_chunk_size(lists_in_query_variable) + + return True, adjusted_chunk_size, list_elements_length, list(lists_in_query_variable.keys()) diff --git a/roles/importer/files/importer/requirements.txt b/roles/importer/files/importer/requirements.txt new file mode 100644 index 0000000000..6fe36b96a5 --- /dev/null +++ b/roles/importer/files/importer/requirements.txt @@ -0,0 +1,27 @@ +# Core runtime +pydantic>=2.0,<3.0 +jsonpickle>=3.0 +python-dateutil>=2.8 +netaddr>=1.0 + +# Crypto (AES/CBC via cryptography.hazmat) +cryptography>=46.0.7 + +# HTTP / GraphQL stack +# Note: Requests >=2.32.0 is compatible with urllib3 2.x +requests>=2.32.0 +urllib3>=2.0 +graphql-core>=3.0 + +# SSH +scrapli>=2025.01.30 +scrapli-community>=2025.01.30 + +# Test +pytest>=9.0.3 +pytest-mock>=3.0 + +# Linting +ruff==0.15.0 +pre-commit>=3.0 +pyright>=1.1.407 diff --git a/roles/importer/files/importer/services/__init__.py b/roles/importer/files/importer/services/__init__.py new file mode 100644 index 0000000000..8b13789179 --- /dev/null +++ b/roles/importer/files/importer/services/__init__.py @@ -0,0 +1 @@ + diff --git a/roles/importer/files/importer/services/enums.py b/roles/importer/files/importer/services/enums.py new file mode 100644 index 0000000000..8f567fdc3b --- /dev/null +++ b/roles/importer/files/importer/services/enums.py @@ -0,0 +1,17 @@ +from enum import Enum + + +class Lifetime(Enum): + SINGLETON = "singleton" + TRANSIENT = "transient" + IMPORT = "import" + MANAGEMENT = "management" # only holds data with a scope valid for a single sub-management + + +class Services(Enum): + UID2ID_MAPPER = "uid2id_mapper" + GROUP_FLATS_MAPPER = "group_flats_mapper" + PREV_GROUP_FLATS_MAPPER = "prev_group_flats_mapper" + GLOBAL_STATE = "global_state" + FW_CONFIG_IMPORT_GATEWAY = "fwconfig_import_gateway" + FWO_CONFIG = "fwo_config" diff --git a/roles/importer/files/importer/services/global_state.py b/roles/importer/files/importer/services/global_state.py new file mode 100644 index 0000000000..981e81cf50 --- /dev/null +++ b/roles/importer/files/importer/services/global_state.py @@ -0,0 +1,26 @@ +from __future__ import annotations + +from typing import TYPE_CHECKING + +if TYPE_CHECKING: + from model_controllers.import_state_controller import ImportStateController + from models.fwconfig_normalized import FwConfigNormalized + + +class GlobalState: + """ + State that is invariant during the import process of a single management. + """ + + import_state: ImportStateController + previous_config: FwConfigNormalized | None + previous_global_config: FwConfigNormalized | None + normalized_config: FwConfigNormalized | None + global_normalized_config: FwConfigNormalized | None + + def __init__(self, import_state: ImportStateController): + self.import_state = import_state + self.previous_config = None + self.previous_global_config = None + self.normalized_config = None + self.global_normalized_config = None diff --git a/roles/importer/files/importer/services/group_flats_mapper.py b/roles/importer/files/importer/services/group_flats_mapper.py new file mode 100644 index 0000000000..081d795dd4 --- /dev/null +++ b/roles/importer/files/importer/services/group_flats_mapper.py @@ -0,0 +1,210 @@ +from __future__ import annotations + +from typing import TYPE_CHECKING, Any + +if TYPE_CHECKING: + from model_controllers.import_state_controller import ImportStateController + from models.fwconfig_normalized import FwConfigNormalized + from models.networkobject import NetworkObject + from models.serviceobject import ServiceObject +import fwo_const +from fwo_log import FWOLogger +from services.service_provider import ServiceProvider + +MAX_RECURSION_LEVEL = 20 +CONFIG_NOT_SET_MESSAGE = "normalized config is not set" + + +class GroupFlatsMapper: + """ + Class is responsible for mapping group objects to their fully resolved members. + """ + + import_state: ImportStateController + normalized_config: FwConfigNormalized | None = None + global_normalized_config: FwConfigNormalized | None = None + + def __init__(self): + global_state = ServiceProvider().get_global_state() + self.import_state = global_state.import_state + self.network_object_flats: dict[str, set[str]] = {} + self.service_object_flats: dict[str, set[str]] = {} + self.user_flats: dict[str, set[str]] = {} + + def log_error(self, message: str) -> None: + """ + Log an error message. + + Args: + message (str): The error message to log. + + """ + FWOLogger.error(message) + + def init_config( + self, normalized_config: FwConfigNormalized, global_normalized_config: FwConfigNormalized | None = None + ) -> None: + self.normalized_config = normalized_config + self.global_normalized_config = global_normalized_config + self.network_object_flats = {} + self.service_object_flats = {} + self.user_flats = {} + + def get_network_object_flats(self, uids: list[str]) -> list[str]: + """ + Flatten the network object UIDs to all members, including group objects, and the top-level group object itself. + Does not check if the given objects are group objects or not. + + Args: + uids (list[str]): The list of network object UIDs to flatten. + + Returns: + list[str]: The flattened network object UIDs. + + """ + if self.normalized_config is None: + self.log_error(f"{CONFIG_NOT_SET_MESSAGE} - networks") + return [] + all_members: set[str] = set() + for uid in uids: + members = self.flat_nwobj_members_recursive(uid) + if members is not None: + all_members.update(members) + return list(all_members) + + def flat_nwobj_members_recursive(self, group_uid: str, recursion_level: int = 0) -> set[str] | None: + if recursion_level > MAX_RECURSION_LEVEL: + FWOLogger.warning(f"recursion level exceeded for group {group_uid}") + return None + if group_uid in self.network_object_flats: + return self.network_object_flats[group_uid] + nwobj = self.get_nwobj(group_uid) + if nwobj is None: + self.log_error(f"object with uid {group_uid} not found in network objects of config") + return None + members: set[str] = {group_uid} + if nwobj.obj_member_refs is None or nwobj.obj_member_refs == "": + return members + for refs in nwobj.obj_member_refs.split(fwo_const.LIST_DELIMITER): + member_uid = refs.split(fwo_const.USER_DELIMITER)[0] if fwo_const.USER_DELIMITER in refs else refs + flat_members = self.flat_nwobj_members_recursive(member_uid, recursion_level + 1) + if flat_members is None: + continue + members.update(flat_members) + self.network_object_flats[group_uid] = members + return members + + def get_nwobj(self, group_uid: str) -> NetworkObject | None: + if not self.normalized_config: + return None + nwobj = self.normalized_config.network_objects.get(group_uid, None) + if nwobj is None and self.global_normalized_config is not None: + nwobj = self.global_normalized_config.network_objects.get(group_uid, None) + return nwobj + + def get_service_object_flats(self, uids: list[str]) -> list[str]: + """ + Flatten the service object UIDs to all members, including group objects, and the top-level group object itself. + Does not check if the given objects are group objects or not. + + Args: + uids (list[str]): The list of service object UIDs to flatten. + + Returns: + list[str]: The flattened service object UIDs. + + """ + if self.normalized_config is None: + self.log_error(f"{CONFIG_NOT_SET_MESSAGE} - services") + return [] + all_members: set[str] = set() + for uid in uids: + members = self.flat_svcobj_members_recursive(uid) + if members is not None: + all_members.update(members) + return list(all_members) + + def flat_svcobj_members_recursive(self, group_uid: str, recursion_level: int = 0) -> set[str] | None: + if recursion_level > MAX_RECURSION_LEVEL: + FWOLogger.warning(f"recursion level exceeded for group {group_uid}") + return None + if group_uid in self.service_object_flats: + return self.service_object_flats[group_uid] + svcobj = self.get_svcobj(group_uid) + if svcobj is None: + self.log_error(f"object with uid {group_uid} not found in service objects of config") + return None + members: set[str] = {group_uid} + if svcobj.svc_member_refs is None or svcobj.svc_member_refs == "": + return members + for member_uid in svcobj.svc_member_refs.split(fwo_const.LIST_DELIMITER): + flat_members = self.flat_svcobj_members_recursive(member_uid, recursion_level + 1) + if flat_members is None: + continue + members.update(flat_members) + self.service_object_flats[group_uid] = members + return members + + def get_svcobj(self, group_uid: str) -> ServiceObject | None: + if not self.normalized_config: + return None + svcobj = self.normalized_config.service_objects.get(group_uid, None) + if svcobj is None and self.global_normalized_config is not None: + # try to get from global normalized config if not found in current normalized config + svcobj = self.global_normalized_config.service_objects.get(group_uid, None) + return svcobj + + def get_user_flats(self, uids: list[str]) -> list[str]: + """ + Flatten the user UIDs to all members, including groups, and the top-level group itself. + Does not check if the given users are groups or not. + + Args: + uids (list[str]): The list of user UIDs to flatten. + + Returns: + list[str]: The flattened user UIDs. + + """ + if self.normalized_config is None: + self.log_error(f"{CONFIG_NOT_SET_MESSAGE} - users") + return [] + all_members: set[str] = set() + for uid in uids: + members = self.flat_user_members_recursive(uid) + if members is not None: + all_members.update(members) + return list(all_members) + + def flat_user_members_recursive(self, group_uid: str, recursion_level: int = 0) -> set[str] | None: + if recursion_level > MAX_RECURSION_LEVEL: + FWOLogger.warning(f"recursion level exceeded for group {group_uid}") + return None + if group_uid in self.user_flats: + return self.user_flats[group_uid] + + user = self.get_user(group_uid) + if user is None: + self.log_error(f"object with uid {group_uid} not found in users of config") + return None + members: set[str] = {group_uid} + if "user_member_refs" not in user or user["user_member_refs"] is None or user["user_member_refs"] == "": + return members + for member_uid in user["user_member_refs"].split( + fwo_const.LIST_DELIMITER + ): # TODO: adjust when/if users are refactored into objects + flat_members = self.flat_user_members_recursive(member_uid, recursion_level + 1) + if flat_members is None: + continue + members.update(flat_members) + self.user_flats[group_uid] = members + return members + + def get_user(self, group_uid: str) -> Any | None: + if not self.normalized_config: + return None + user = self.normalized_config.users.get(group_uid, None) + if user is None and self.global_normalized_config is not None: + # try to get from global normalized config if not found in current normalized config + user = self.global_normalized_config.users.get(group_uid, None) + return user diff --git a/roles/importer/files/importer/services/service_provider.py b/roles/importer/files/importer/services/service_provider.py new file mode 100644 index 0000000000..51510bdb88 --- /dev/null +++ b/roles/importer/files/importer/services/service_provider.py @@ -0,0 +1,161 @@ +from collections.abc import Callable +from typing import TYPE_CHECKING, Any + +from services.enums import Lifetime, Services + +if TYPE_CHECKING: + from services.global_state import GlobalState + from services.group_flats_mapper import GroupFlatsMapper + from services.uid2id_mapper import Uid2IdMapper + + +class ServiceProviderEntry: + def __init__(self, constructor: Callable[[], Any], lifetime: Lifetime): + self.constructor = constructor + self.lifetime = lifetime + + +class ServiceProvider: + """ + Class serves as an IOC-container (IOC = inversion of controls) and its purpose is to manage instantiation and lifetime of service classes. + """ + + _instance: "ServiceProvider | None" = None + _services: dict[Services, ServiceProviderEntry] + _singletons: dict[Services, Any] + _import: dict[tuple[int, Services], Any] + _management: dict[tuple[int, Services], Any] + + def __new__(cls): + if cls._instance is None: + cls._instance = super().__new__(cls) + cls._instance._services = {} # noqa: SLF001 + cls._instance._singletons = {} # noqa: SLF001 + cls._instance._import = {} # noqa: SLF001 + + return cls._instance + + def register(self, key: Services, constructor: Callable[[], Any], lifetime: Lifetime): + self._services[key] = ServiceProviderEntry(constructor, lifetime) + + def get_global_state(self) -> "GlobalState": + return self.get_service(Services.GLOBAL_STATE) + + def dispose_global_state(self): + self.dispose_service(Services.GLOBAL_STATE) + + def get_fwo_config(self) -> dict[str, Any]: + return self.get_service(Services.FWO_CONFIG) + + def dispose_fwo_config(self): + self.dispose_service(Services.FWO_CONFIG) + + def get_group_flats_mapper(self, import_id: int = 0) -> "GroupFlatsMapper": + return self.get_service(Services.GROUP_FLATS_MAPPER, import_id=import_id) + + def dispose_group_flats_mapper(self, import_id: int = 0): + self.dispose_service(Services.GROUP_FLATS_MAPPER, import_id=import_id) + + def get_prev_group_flats_mapper(self, import_id: int = 0) -> "GroupFlatsMapper": + return self.get_service(Services.PREV_GROUP_FLATS_MAPPER, import_id=import_id) + + def dispose_prev_group_flats_mapper(self, import_id: int = 0): + self.dispose_service(Services.PREV_GROUP_FLATS_MAPPER, import_id=import_id) + + def get_uid2id_mapper(self, import_id: int = 0) -> "Uid2IdMapper": + return self.get_service(Services.UID2ID_MAPPER, import_id=import_id) + + def dispose_uid2id_mapper(self, import_id: int = 0): + self.dispose_service(Services.UID2ID_MAPPER, import_id=import_id) + + def reset(self): + self._services = {} + self._singletons = {} + self._import = {} + self._management = {} + + def get_service(self, key: Services, import_id: int = 0, management_id: int = 0) -> Any: + """ + Get an instance of a service based on its lifetime. The service will be instantiated if it does not already exist. + + :param key: The service to get. + :param import_id: The import ID for IMPORT lifetime services. + :param management_id: The management ID for MANAGEMENT lifetime services. + :return: The instance of the requested service. + """ + entry = self._services.get(key) + service_instance = None + + if not entry: + raise ValueError(f"Service '{key}' is not registered.") + + match entry.lifetime: + case Lifetime.SINGLETON: + if key not in self._singletons: + self._singletons[key] = entry.constructor() + service_instance = self._singletons[key] + + case Lifetime.IMPORT: + import_specific_key = (import_id, key) + if import_specific_key not in self._import: + self._import[import_specific_key] = entry.constructor() + service_instance = self._import[import_specific_key] + + case Lifetime.MANAGEMENT: + management_specific_key = (management_id, key) + if management_specific_key not in self._management: + self._management[management_specific_key] = entry.constructor() + service_instance = self._management[management_specific_key] + + case _: + raise ValueError(f"Unsupported lifetime '{entry.lifetime}' for service '{key}'.") + + return service_instance + + def dispose_service(self, key: Services, import_id: int = 0, management_id: int = 0): + """ + Dispose of a service instance based on its lifetime. + + :param key: The service to dispose of. + :param import_id: The import ID for IMPORT lifetime services. + :param management_id: The management ID for MANAGEMENT lifetime services. + """ + entry = self._services.get(key) + if not entry: + raise ValueError(f"Service '{key}' is not registered.") + + match entry.lifetime: + case Lifetime.SINGLETON: + if key in self._singletons: + del self._singletons[key] + + case Lifetime.IMPORT: + import_specific_key = (import_id, key) + if import_specific_key in self._import: + del self._import[import_specific_key] + + case Lifetime.MANAGEMENT: + management_specific_key = (management_id, key) + if management_specific_key in self._management: + del self._management[management_specific_key] + + case _: + raise ValueError(f"Unsupported lifetime '{entry.lifetime}' for service '{key}'.") + + def dispose_scope_import(self, import_id: int): + """ + Dispose of all services associated with a specific import ID. + :param import_id: The import ID whose services should be disposed of. + """ + keys_to_remove = [key for key in self._import if key[0] == import_id] + for key in keys_to_remove: + del self._import[key] + + def dispose_scope_management(self, management_id: int): + """ + Dispose of all services associated with a specific management ID. + :param management_id: The management ID whose services should be disposed of. + """ + keys_to_remove = [key for key in self._management if key[0] == management_id] + for key in keys_to_remove: + del self._management[key] diff --git a/roles/importer/files/importer/services/uid2id_mapper.py b/roles/importer/files/importer/services/uid2id_mapper.py new file mode 100644 index 0000000000..1436b38503 --- /dev/null +++ b/roles/importer/files/importer/services/uid2id_mapper.py @@ -0,0 +1,513 @@ +from typing import TYPE_CHECKING, Any + +from fwo_log import FWOLogger + +if TYPE_CHECKING: + from model_controllers.import_state_controller import ImportStateController +import fwo_const +from fwo_api import FwoApi +from fwo_exceptions import FwoImporterError +from services.enums import Services +from services.service_provider import ServiceProvider + + +class Uid2IdMap: + """ + A simple data structure to hold UID to ID mappings. + Includes current and outdated, local and global mappings. + """ + + def __init__(self) -> None: + self.local: dict[str, int] = {} + self.outdated_local: dict[str, int] = {} + self.global_map: dict[str, int] = {} + self.outdated_global: dict[str, int] = {} + + def get(self, uid: str, before_update: bool = False, local_only: bool = False) -> int | None: + if before_update: + outdated_id = self.outdated_local.get(uid) or self.outdated_global.get(uid) + if outdated_id is not None: + return outdated_id + return self.local.get(uid) or self.global_map.get(uid) # was not updated, use current + if local_only: + return self.local.get(uid) + return self.local.get(uid) or self.global_map.get(uid) + + def set(self, uid: str, db_id: int, is_global: bool = False) -> None: + target_map = self.global_map if is_global else self.local + outdated_map = self.outdated_global if is_global else self.outdated_local + if uid in target_map: + outdated_map[uid] = target_map[uid] + target_map[uid] = db_id + + def update(self, new_mappings: dict[str, int], is_global: bool = False) -> None: + target_map = self.global_map if is_global else self.local + outdated_map = self.outdated_global if is_global else self.outdated_local + for uid, db_id in new_mappings.items(): + if uid in target_map: + outdated_map[uid] = target_map[uid] + target_map[uid] = db_id + + +class Uid2IdMapper: + """ + A class to map unique identifiers (UIDs) to IDs. + This class is used to maintain a mapping between UID and relevant ID in the database. + """ + + import_state: "ImportStateController" + + nwobj_uid2id: Uid2IdMap + svc_uid2id: Uid2IdMap + user_uid2id: Uid2IdMap + zone_name2id: Uid2IdMap + timeobj_uid2id: Uid2IdMap + rule_uid2id: Uid2IdMap + rulebase_uid2id: Uid2IdMap + + @property + def api_connection(self) -> FwoApi: + return self.import_state.api_connection + + def __init__(self) -> None: + """ + Initialize the Uid2IdMapper. + """ + global_state = ServiceProvider().get_service(Services.GLOBAL_STATE) + self.import_state = global_state.import_state + self.nwobj_uid2id = Uid2IdMap() + self.svc_uid2id = Uid2IdMap() + self.user_uid2id = Uid2IdMap() + self.zone_name2id = Uid2IdMap() + self.timeobj_uid2id = Uid2IdMap() + self.rule_uid2id = Uid2IdMap() + self.rulebase_uid2id = Uid2IdMap() + + def get_network_object_id(self, uid: str, before_update: bool = False, local_only: bool = False) -> int: + """ + Get the ID for a given network object UID. + + Args: + uid (str): The UID of the network object. + before_update (bool): If True, use the outdated mapping if available. + + Returns: + int: The ID of the network object. + + """ + nwobj_id = self.nwobj_uid2id.get(uid, before_update, local_only) + if nwobj_id is None: + raise KeyError(f"Network object UID '{uid}' not found in mapping.") + return nwobj_id + + def get_service_object_id(self, uid: str, before_update: bool = False, local_only: bool = False) -> int: + """ + Get the ID for a given service object UID. + + Args: + uid (str): The UID of the service object. + before_update (bool): If True, use the outdated mapping if available. + + Returns: + int: The ID of the service object. + + """ + svc_id = self.svc_uid2id.get(uid, before_update, local_only) + if svc_id is None: + raise KeyError(f"Service object UID '{uid}' not found in mapping.") + return svc_id + + def get_user_id(self, uid: str, before_update: bool = False, local_only: bool = False) -> int: + """ + Get the ID for a given user UID. + + Args: + uid (str): The UID of the user. + before_update (bool): If True, use the outdated mapping if available. + + Returns: + int: The ID of the user. + + """ + user_id = self.user_uid2id.get(uid, before_update, local_only) + if user_id is None: + raise KeyError(f"User UID '{uid}' not found in mapping.") + return user_id + + def get_zone_object_id(self, name: str, before_update: bool = False, local_only: bool = False) -> int: + """ + Get the ID for a given zone UID. + + Args: + name (str): The name of the zone. + before_update (bool): If True, use the outdated mapping if available. + + Returns: + int: The ID of the zone + + """ + zone_id = self.zone_name2id.get(name, before_update, local_only) + if zone_id is None: + raise KeyError(f"Zone Name '{name}' not found in mapping.") + return zone_id + + def get_time_object_id(self, uid: str, before_update: bool = False, local_only: bool = False) -> int: + """ + Get the ID for a given time object UID. + + Args: + uid (str): The UID of the time object. + before_update (bool): If True, use the outdated mapping if available. + + Returns: + int: The ID of the time object. + + """ + time_obj_id = self.timeobj_uid2id.get(uid, before_update, local_only) + if time_obj_id is None: + raise KeyError(f"Time object UID '{uid}' not found in mapping.") + return time_obj_id + + def get_rule_id(self, uid: str, before_update: bool = False) -> int: + """ + Get the ID for a given rule UID. + + Args: + uid (str): The UID of the rule. + before_update (bool): If True, use the outdated mapping if available. + + Returns: + int: The ID of the rule. + + """ + rule_id = self.rule_uid2id.get(uid, before_update) + if rule_id is None: + raise KeyError(f"Rule UID '{uid}' not found in mapping.") + return rule_id + + def get_rulebase_id(self, uid: str, before_update: bool = False) -> int: + """ + Get the ID for a given rulebase UID. + + Args: + uid (str): The UID of the rulebase. + before_update (bool): If True, use the outdated mapping if available. + + Returns: + int: The ID of the rulebase. + + """ + rulebase_id = self.rulebase_uid2id.get(uid, before_update) + if rulebase_id is None: + raise KeyError(f"Rulebase UID '{uid}' not found in mapping.") + return rulebase_id + + def add_network_object_mappings(self, mappings: list[dict[str, Any]], is_global: bool = False): + """ + Add network object mappings to the internal mapping dictionary. + + Args: + mappings (list[dict]): A list of dictionaries containing UID and ID mappings. + Each dictionary should have 'obj_uid' and 'obj_id' keys. + + """ + for mapping in mappings: + if "obj_uid" not in mapping or "obj_id" not in mapping: + raise ValueError("Invalid mapping format. Each mapping must contain 'obj_uid' and 'obj_id'.") + self.nwobj_uid2id.set(mapping["obj_uid"], mapping["obj_id"], is_global) + + FWOLogger.debug(f"Added {len(mappings)} {'global ' if is_global else ''}network object mappings.") + + def add_service_object_mappings(self, mappings: list[dict[str, Any]], is_global: bool = False): + """ + Add service object mappings to the internal mapping dictionary. + + Args: + mappings (list[dict]): A list of dictionaries containing UID and ID mappings. + Each dictionary should have 'svc_uid' and 'svc_id' keys. + + """ + for mapping in mappings: + if "svc_uid" not in mapping or "svc_id" not in mapping: + raise ValueError("Invalid mapping format. Each mapping must contain 'svc_uid' and 'svc_id'.") + self.svc_uid2id.set(mapping["svc_uid"], mapping["svc_id"], is_global) + + FWOLogger.debug(f"Added {len(mappings)} {'global ' if is_global else ''}service object mappings.") + + def add_user_mappings(self, mappings: list[dict[str, Any]], is_global: bool = False): + """ + Add user object mappings to the internal mapping dictionary. + + Args: + mappings (list[dict]): A list of dictionaries containing UID and ID mappings. + Each dictionary should have 'user_uid' and 'user_id' keys. + + """ + for mapping in mappings: + if "user_uid" not in mapping or "user_id" not in mapping: + raise ValueError("Invalid mapping format. Each mapping must contain 'user_uid' and 'user_id'.") + self.user_uid2id.set(mapping["user_uid"], mapping["user_id"], is_global) + + FWOLogger.debug(f"Added {len(mappings)} {'global ' if is_global else ''}user mappings.") + + def add_zone_mappings(self, mappings: list[dict[str, Any]], is_global: bool = False): + """ + Add zone object mappings to the internal mapping dictionary. + + Args: + mappings (list[dict]): A list of dictionaries containing Name and ID mappings. + Each dictionary should have 'zone_name' and 'zone_id' keys. + + """ + for mapping in mappings: + if "zone_name" not in mapping or "zone_id" not in mapping: + raise ValueError("Invalid mapping format. Each mapping must contain 'zone_name' and 'zone_id'.") + self.zone_name2id.set(mapping["zone_name"], mapping["zone_id"], is_global) + + FWOLogger.debug(f"Added {len(mappings)} {'global ' if is_global else ''}zone mappings.") + + def add_time_object_mappings(self, mappings: list[dict[str, Any]], is_global: bool = False): + """ + Add time object mappings to the internal mapping dictionary. + + Args: + mappings (list[dict]): A list of dictionaries containing UID and ID mappings. + Each dictionary should have 'time_obj_uid' and 'time_obj_id' keys. + + """ + for mapping in mappings: + if "time_obj_uid" not in mapping or "time_obj_id" not in mapping: + raise ValueError("Invalid mapping format. Each mapping must contain 'time_obj_uid' and 'time_obj_id'.") + self.timeobj_uid2id.set(mapping["time_obj_uid"], mapping["time_obj_id"], is_global) + + FWOLogger.debug(f"Added {len(mappings)} {'global ' if is_global else ''}time object mappings.") + + def add_rule_mappings(self, mappings: list[dict[str, Any]]): + """ + Add rule mappings to the internal mapping dictionary. + + Args: + mappings (list[dict]): A list of dictionaries containing UID and ID mappings. + Each dictionary should have 'rule_uid' and 'rule_id' keys. + + """ + for mapping in mappings: + if "rule_uid" not in mapping or "rule_id" not in mapping: + raise ValueError("Invalid mapping format. Each mapping must contain 'rule_uid' and 'rule_id'.") + self.rule_uid2id.set(mapping["rule_uid"], mapping["rule_id"]) + + FWOLogger.debug(f"Added {len(mappings)} rule mappings.") + + def add_rulebase_mappings(self, mappings: list[dict[str, Any]]): + """ + Add rulebase mappings to the internal mapping dictionary. + + Args: + mappings (list[dict]): A list of dictionaries containing UID and ID mappings. + Each dictionary should have 'uid' and 'id' keys. + + """ + for mapping in mappings: + if "uid" not in mapping or "id" not in mapping: + raise ValueError("Invalid mapping format. Each mapping must contain 'uid' and 'id'.") + self.rulebase_uid2id.set(mapping["uid"], mapping["id"]) + + FWOLogger.debug(f"Added {len(mappings)} rulebase mappings.") + + def update_network_object_mapping(self, uids: list[str] | None = None, is_global: bool = False) -> None: + """ + Update the mapping for network objects based on the provided UIDs. + + Args: + uids (list[str]): A list of UIDs to update the mapping for. If None, all UIDs for the Management will be fetched. + + """ + query = FwoApi.get_graphql_code([fwo_const.GRAPHQL_QUERY_PATH + "networkObject/getMapOfUid2Id.graphql"]) + + if uids is not None: + if len(uids) == 0: + FWOLogger.debug("Network object mapping updated for 0 objects") + return + variables = {"uids": uids} + else: + # If no UIDs are provided, fetch all UIDs for the Management + variables = {"mgmId": self.import_state.state.mgm_details.current_mgm_id} + try: + response = self.import_state.api_connection.call(query, variables) + if "errors" in response: + raise FwoImporterError(f"Error updating network object mapping: {response['errors']}") + self.nwobj_uid2id.update( + {obj["obj_uid"]: obj["obj_id"] for obj in response["data"]["object"]}, + is_global, + ) + FWOLogger.debug(f"Network object mapping updated for {len(response['data']['object'])} objects") + except Exception as e: + raise FwoImporterError(f"Error updating network object mapping: {e}") + + def update_service_object_mapping(self, uids: list[str] | None = None, is_global: bool = False) -> None: + """ + Update the mapping for service objects based on the provided UIDs. + + Args: + uids (list[str] | None): A list of UIDs to update the mapping for. If None, all UIDs for the Management will be fetched. + + """ + query = FwoApi.get_graphql_code([fwo_const.GRAPHQL_QUERY_PATH + "networkService/getMapOfUid2Id.graphql"]) + if uids is not None: + if len(uids) == 0: + FWOLogger.debug("Service object mapping updated for 0 objects") + return + variables = {"uids": uids} + else: + # If no UIDs are provided, fetch all UIDs for the Management + variables = {"mgmId": self.import_state.state.mgm_details.current_mgm_id} + try: + response = self.import_state.api_connection.call(query, variables) + if "errors" in response: + raise FwoImporterError(f"Error updating service object mapping: {response['errors']}") + self.svc_uid2id.update( + {obj["svc_uid"]: obj["svc_id"] for obj in response["data"]["service"]}, + is_global, + ) + FWOLogger.debug(f"Service object mapping updated for {len(response['data']['service'])} objects") + except Exception as e: + raise FwoImporterError(f"Error updating service object mapping: {e}") + + def update_user_mapping(self, uids: list[str] | None = None, is_global: bool = False) -> None: + """ + Update the mapping for users based on the provided UIDs. + + Args: + uids (list[str] | None): A list of UIDs to update the mapping for. If None, all UIDs for the Management will be fetched. + + """ + query = FwoApi.get_graphql_code([fwo_const.GRAPHQL_QUERY_PATH + "user/getMapOfUid2Id.graphql"]) + if uids is not None: + if len(uids) == 0: + FWOLogger.debug("User mapping updated for 0 objects") + return + variables = {"uids": uids} + else: + # If no UIDs are provided, fetch all UIDs for the Management + variables = {"mgmId": self.import_state.state.mgm_details.current_mgm_id} + try: + response = self.import_state.api_connection.call(query, variables) + if "errors" in response: + raise FwoImporterError(f"Error updating user mapping: {response['errors']}") + self.user_uid2id.update( + {obj["user_uid"]: obj["user_id"] for obj in response["data"]["usr"]}, + is_global, + ) + FWOLogger.debug(f"User mapping updated for {len(response['data']['usr'])} objects") + except Exception as e: + raise FwoImporterError(f"Error updating user mapping: {e}") + + def update_zone_mapping(self, names: list[str] | None = None, is_global: bool = False) -> None: + """ + Update the mapping for zones based on the provided names. + + Args: + names (list[str] | None): A list of zone names to update the mapping for. If None, all zones for the Management will be fetched. + + """ + query = FwoApi.get_graphql_code([fwo_const.GRAPHQL_QUERY_PATH + "zone/getMapOfName2Id.graphql"]) + if names is not None: + if len(names) == 0: + FWOLogger.debug("Zone mapping updated for 0 objects") + return + variables = {"names": names} + else: + # If no names are provided, fetch all zones for the Management + variables = {"mgmId": self.import_state.state.mgm_details.current_mgm_id} + try: + response = self.import_state.api_connection.call(query, variables) + if "errors" in response: + raise FwoImporterError(f"Error updating zone mapping: {response['errors']}") + self.zone_name2id.update( + {obj["zone_name"]: obj["zone_id"] for obj in response["data"]["zone"]}, + is_global, + ) + FWOLogger.debug(f"Zone mapping updated for {len(response['data']['zone'])} objects") + except Exception as e: + raise FwoImporterError(f"Error updating zone mapping: {e}") + + def update_time_object_mapping(self, uids: list[str] | None = None, is_global: bool = False) -> None: + """ + Update the mapping for time objects based on the provided UIDs. + + Args: + uids (list[str] | None): A list of UIDs to update the mapping for. If None, all UIDs for the Management will be fetched. + + """ + query = FwoApi.get_graphql_code([fwo_const.GRAPHQL_QUERY_PATH + "time/getMapOfUid2Id.graphql"]) + if uids is not None: + if len(uids) == 0: + FWOLogger.debug("Time object mapping updated for 0 objects") + return + variables = {"uids": uids} + else: + # If no UIDs are provided, fetch all UIDs for the Management + variables = {"mgmId": self.import_state.state.mgm_details.current_mgm_id} + try: + response = self.import_state.api_connection.call(query, variables) + if "errors" in response: + raise FwoImporterError(f"Error updating time object mapping: {response['errors']}") + self.timeobj_uid2id.update( + {obj["time_obj_uid"]: obj["time_obj_id"] for obj in response["data"]["time_object"]}, + is_global, + ) + FWOLogger.debug(f"Time object mapping updated for {len(response['data']['time_object'])} objects") + except Exception as e: + raise FwoImporterError(f"Error updating time object mapping: {e}") + + def update_rule_mapping(self, uids: list[str] | None = None) -> None: + """ + Update the mapping for rules based on the provided UIDs. + + Args: + uids (list[str] | None): A list of UIDs to update the mapping for. If None, all UIDs for the Management will be fetched. + + """ + query = FwoApi.get_graphql_code([fwo_const.GRAPHQL_QUERY_PATH + "rule/getMapOfUid2Id.graphql"]) + if uids is not None: + if len(uids) == 0: + FWOLogger.debug("Rule mapping updated for 0 objects") + return + variables = {"uids": uids} + else: + # If no UIDs are provided, fetch all UIDs for the Management + variables = {"mgmId": self.import_state.state.mgm_details.current_mgm_id} + try: + response = self.import_state.api_connection.call(query, variables) + if "errors" in response: + raise FwoImporterError(f"Error updating rule mapping: {response['errors']}") + self.rule_uid2id.update({obj["rule_uid"]: obj["rule_id"] for obj in response["data"]["rule"]}) + FWOLogger.debug(f"Rule mapping updated for {len(response['data']['rule'])} objects") + except Exception as e: + raise FwoImporterError(f"Error updating rule mapping: {e}") + + def update_rulebase_mapping(self, uids: list[str] | None = None) -> None: + """ + Update the mapping for rulebases based on the provided UIDs. + + Args: + uids (list[str] | None): A list of UIDs to update the mapping for. If None, all UIDs for the Management will be fetched. + + """ + query = FwoApi.get_graphql_code([fwo_const.GRAPHQL_QUERY_PATH + "rulebase/getMapOfUid2Id.graphql"]) + if uids is not None: + if len(uids) == 0: + FWOLogger.debug("Rulebase mapping updated for 0 objects") + return + variables = {"uids": uids} + else: + # If no UIDs are provided, fetch all UIDs for the Management + variables = {"mgmId": self.import_state.state.mgm_details.current_mgm_id} + try: + response = self.import_state.api_connection.call(query, variables) + if "errors" in response: + raise FwoImporterError(f"Error updating rulebase mapping: {response['errors']}") + self.rulebase_uid2id.update({obj["uid"]: obj["id"] for obj in response["data"]["rulebase"]}) + FWOLogger.debug(f"Rulebase mapping updated for {len(response['data']['rulebase'])} objects") + except Exception as e: + raise FwoImporterError(f"Error updating rulebase mapping: {e}") diff --git a/roles/importer/files/importer/ssh-client.pl b/roles/importer/files/importer/ssh-client.pl deleted file mode 100755 index a20c7d8b63..0000000000 --- a/roles/importer/files/importer/ssh-client.pl +++ /dev/null @@ -1,1360 +0,0 @@ -#! /usr/bin/perl -w -#origin: program: sendcommand.pl 2009-2011 -#author: Youri Reddy-Girard (melk0r101@yahoo.com - http//sendcommand.sourceforge.net/) -#version: 0.1.6 (20110213) -# SendCommand is a perl script using expect library. It permits the execution of remote -# command via telnet or ssh on different network devices (Cisco switch, Juniper Netscreen, -# Blue Coat proxySG, TippingPoint IPS, Linux). Output is highly customizable. -# IMPORTANT: You need the expect.pm module installed. -# - on debian type "aptitude install libexpect-perl" -# - on centos type "cpan" and then type "install Expect" -# -# calling syntax: ./ssh-client.pl -z 89.19.225.167 -t netscreen -i .ssh/id_rsa -c "get config" -u cadmin -d 0 -o /tmp/publikat_fw02.cfg -# needed to handle netscreen imports - -#external librairies -use strict; -use warnings; -use diagnostics; -use File::Path; -use POSIX qw(strftime); -use Expect; -# $Expect::Debug = 9; -use Getopt::Long qw(:config no_ignore_case bundling); - -############################################################# -# GLOBAL VARIABLE DECLARATION -############################################################# -#global constants -use constant PROGRAM => 'ssh-client.pl'; # name of this program / script -use constant VERSION => "1.1"; # version of the program -use constant SSH => "/usr/bin/ssh"; # path to the ssh binary -use constant TELNET => "/usr/bin/telnet"; # path to the telnet binary -use constant TIMEOUT_COMMAND => 600; # timeout in seconds after sending the command if no prompt is seen -use constant TIMEOUT_CONNECT => 120; # timeout in seconds after opening the socket to get the login prompt -use constant TIMEOUT_GENERIC => 10; # timeout in seconds used for all remaining expect commands -use constant MAXVAR => 9; # Number of variables (columns) read in the input file -use constant NBTRY => 1; # Default number of retry if connection fails -use constant DISPLAYLEVEL => 1; # Default display level -use constant METHOD => "ssh"; # Default method -use constant OUTPUTFILEAPPEND => 0; # Default mode for output file (0=erase 1=append) -use constant PROMPT_REGEX_DEBIAN => "\r\n[^\r\n ]+:[^\r\n]+[\\\$#] "; -use constant PROMPT_REGEX_IPSO => "\r\n[^\r\n ]+\\\[[^\r\n]+\\\]#"; -use constant PROMPT_REGEX_SPLAT => "\r\n\\\[[^\r\n ]+@[^\r\n]+\\\]#"; -use constant PROMPT_REGEX_REDHAT => "\r\n\\\[[^\r\n ]+@[^\r\n]+\\\]#"; -#use constant PROMPT_REGEX_GENTOO => "[^\n]+@[^\n]+ [^\n]+ \\\$|[^\n]+ [^\n]+ #"; -use constant PROMPT_REGEX_POSIX => PROMPT_REGEX_DEBIAN."|".PROMPT_REGEX_IPSO."|".PROMPT_REGEX_SPLAT."|".PROMPT_REGEX_REDHAT; -use constant PROMPT_REGEX_BLUECOAT => "\r\n[^\r\n ]+>"; -use constant PROMPT_REGEX_BLUECOATENABLE => "\r\n[^\r\n ]+#"; -use constant PROMPT_REGEX_BLUECOATCONFIG => "\r\n[^\r\n ]+#([^)]+)"; -use constant PROMPT_REGEX_CISCO => "\r\n[^\r\n# ]+>"; -use constant PROMPT_REGEX_CISCOENABLE => "\r\n[^\r\n# ]+#"; -#use constant PROMPT_REGEX_NETSCREEN => qr/\r\n.+?\(.\)\-\>/; # das funktioniert mit clustern -use constant PROMPT_REGEX_NETSCREEN => - qr/\r\n(\-\-\-\smore\s\-\-\-)?([^\s]+?)\-\>/; # annahme: prompt-Zeile enthält kein Whitespace vor -> -#use constant PROMPT_REGEX_NETSCREEN => "\r?\n?[^\r\n ]+([^\r\n ]+)->"; -#use constant PROMPT_REGEX_TIPPINGPOINT => "\r\n[^\r\n ]+#"; # original -use constant PROMPT_REGEX_TIPPINGPOINT => "[\r\n]+[^\r\n ]+#"; #TippingPoint is bugged and returned tons of \r when no rows and columns are sent (TTY: telnet and ssh) - - -#global expect -$Expect::Log_Stdout = 0; - -#global variables -my $PROMPT_REGEX; -my $LOGFILE; -my $DISPLAYLEVEL; - - - -############################################################# -# FUNCTIONS DECLARATION -############################################################# - -# append_array_to_file() -# Append an array to a file -# IN: -# $file = filename -# $parr = pointer to array to append -# OUT: -# 1 = OK -# 0 = NOK -sub append_array_to_file(){ - my $file = $_[0]; - my $parr = $_[1]; - my $result = 0; - if (open(FILE, ">>", $file)){ - if (print FILE @$parr){ - $result = 1; - } - close(FILE); - } -} - -# append_string_to_file() -# Append a string to a file -# IN: -# $file = filename -# $string = string to append -# OUT: -# 1 = OK -# 0 = NOK -sub append_string_to_file(){ - my $file = $_[0]; - my $string = $_[1]; - my $result = 0; - if (open(FILE, ">>", $file)){ - if (print FILE $string){ - $result = 1; - } - close(FILE); - } -} - -# exp_connect() -# Connects to any known equipment type -# IN: -# $exp = Expect object -# $equipmenttype = Equipment type (must be supported) -# $method = Method (must be supported) -# $port = Port -# $parrEquipment = Array containing equipmentname, hostname, username, password, enablepassword -# OUT: -# 1 = OK -# 0 = NOK -sub exp_connect(){ - my $exp = $_[0]; - my $equipmenttype = $_[1]; - my $method = $_[2]; - my $port = $_[3]; - my $parrEquipment = $_[4]; - my $identity_file = $_[5]; - my $result = 0; - if (($equipmenttype eq "posix") && ($method eq "ssh")){ - $result = &exp_connect_ssh($exp, @$parrEquipment[0], @$parrEquipment[1], @$parrEquipment[2], @$parrEquipment[3], $port, PROMPT_REGEX_POSIX, $identity_file); - }elsif (($equipmenttype eq "posix") && ($method eq "telnet")){ - $result = &exp_connect_telnet($exp, @$parrEquipment[0], @$parrEquipment[1], @$parrEquipment[2], @$parrEquipment[3], $port, PROMPT_REGEX_POSIX); - }elsif (($equipmenttype eq "netscreen") && ($method eq "ssh")){ - $result = &exp_connect_ssh($exp, @$parrEquipment[0], @$parrEquipment[1], @$parrEquipment[2], @$parrEquipment[3], $port, PROMPT_REGEX_NETSCREEN, $identity_file); - }elsif (($equipmenttype eq "bluecoat")&&($method eq "ssh")){ - $result = &exp_connect_ssh($exp, @$parrEquipment[0], @$parrEquipment[1], @$parrEquipment[2], @$parrEquipment[3], $port, PROMPT_REGEX_BLUECOAT, $identity_file); - if ($result){ - $result = &exp_enter_enable_mode($exp, @$parrEquipment[0], @$parrEquipment[4], PROMPT_REGEX_BLUECOATENABLE); - if ($result){ - $result = &exp_enter_config_mode($exp, @$parrEquipment[0], PROMPT_REGEX_BLUECOATCONFIG); - if ($result){ - my $commandresult = ""; - my $sendcommandresult = 0; - $sendcommandresult = &exp_send_command($exp, $equipmenttype, @$parrEquipment[0], "line-vty ;mode", \$commandresult); - if ($sendcommandresult){ - $sendcommandresult = &exp_send_command($exp, $equipmenttype, @$parrEquipment[0], "no length", \$commandresult); - if ($sendcommandresult){ - $sendcommandresult = &exp_send_command($exp, $equipmenttype, @$parrEquipment[0], "exit", \$commandresult); - if (!$sendcommandresult){ - &log_msg("@$parrEquipment[0]: error when exiting line-vty mode"); - } - }else{ - &log_msg("@$parrEquipment[0]: error when entering line-vty mode"); - } - }else{ - &log_msg("@$parrEquipment[0]: error when entering line-vty mode"); - } - $result = $sendcommandresult; - if ($result){ - $result = &exp_exit_config_mode($exp, @$parrEquipment[0], PROMPT_REGEX_BLUECOATENABLE); - } - } - } - } - }elsif (($equipmenttype eq "cisco")&&($method eq "ssh")){ - $result = &exp_connect_ssh($exp, @$parrEquipment[0], @$parrEquipment[1], @$parrEquipment[2], @$parrEquipment[3], $port, PROMPT_REGEX_CISCO); - if ($result){ - $result = &exp_enter_enable_mode($exp, @$parrEquipment[0], @$parrEquipment[4], PROMPT_REGEX_CISCOENABLE); - if ($result){ - my $commandresult = ""; - my $sendcommandresult = &exp_send_command($exp, $equipmenttype, @$parrEquipment[0], "term length 0", \$commandresult); - if (!$sendcommandresult){ - &log_msg("@$parrEquipment[0]: error when setting term length"); - } - $result = $sendcommandresult; - } - } - }elsif (($equipmenttype eq "cisco")&&($method eq "telnet")){ - $result = &exp_connect_telnet($exp, @$parrEquipment[0], @$parrEquipment[1], @$parrEquipment[2], @$parrEquipment[3], $port, PROMPT_REGEX_CISCO); - if ($result){ - $result = &exp_enter_enable_mode($exp, @$parrEquipment[0], @$parrEquipment[4], PROMPT_REGEX_CISCOENABLE); - if ($result){ - my $commandresult = ""; - my $sendcommandresult = &exp_send_command($exp, $equipmenttype, @$parrEquipment[0], "term length 0", \$commandresult); - if (!$sendcommandresult){ - &log_msg("@$parrEquipment[0]: error when setting term length"); - } - $result = $sendcommandresult; - } - } - }elsif (($equipmenttype eq "tippingpoint") && ($method eq "ssh")){ - $result = &exp_connect_ssh($exp, @$parrEquipment[0], @$parrEquipment[1], @$parrEquipment[2], @$parrEquipment[3], $port, PROMPT_REGEX_TIPPINGPOINT); - }else{ - &log_msg("Connection for equipmenttype and method combination undefined. (equipmenttype=$equipmenttype method=$method)"); - } - return $result; -} - -# exp_connect_ssh -# Expect sequences to connect to a system via ssh -# IN: -# $exp = Expect object -# $equipmentname = equipment name / id / label -# $hostname = hostname or ip address -# $username = remote username -# $password = remote password -# $port = remote ssh port -# $prompt_regex = prompt expected -# OUT: -# 1 = OK -# 0 = NOK -sub exp_connect_ssh(){ - my $exp = $_[0]; - my $equipmentname = $_[1]; - my $hostname = $_[2]; - my $username = $_[3]; - my $password = $_[4]; - my $port = $_[5]; - my $prompt_regex = $_[6]; - my $identity_file = $_[7]; - my $result=0; - - if (defined($identity_file) && $identity_file ne '') { - $identity_file = " -i $identity_file"; - } else { - $identity_file = ''; - } - - my $port_txt = ' '; - if ($port ne "") { $port_txt = " -p $port "; } - $exp->spawn(SSH." $identity_file -T $port_txt $username\@$hostname"); - &log_msg("$equipmentname: connecting via ssh $port_txt to $username\@$hostname..."); - $exp->notransfer(1); - $exp->expect(TIMEOUT_CONNECT,[ - "-re","Terminal type",sub{ #ipso specific - $exp->set_accum($exp->after); - &log_msg("$equipmentname: terminal type requested. sending CR"); - $exp->send("\r"); - $exp->exp_continue; - } - ],[ - "-re",$prompt_regex,sub{ - $exp->notransfer(0); - $PROMPT_REGEX = $prompt_regex; - &log_msg("$equipmentname: login successfully"); - $result=1; - } - ],[ - "-re","[^\n]+assword:",sub{ - $exp->notransfer(0); - $exp->set_accum($exp->after); - if($password){ - $exp->send("$password\r"); - $exp->notransfer(1); - $exp->expect(TIMEOUT_GENERIC,[ - "-re","Terminal type",sub{ #ipso specific - $exp->set_accum($exp->after); - &log_msg("$equipmentname: terminal type requested. sending CR"); - $exp->send("\r"); - $exp->exp_continue; - } - ],[ - "-re",$prompt_regex,sub{ - $exp->notransfer(0); - $PROMPT_REGEX = $prompt_regex; - &log_msg("$equipmentname: login successfully"); - $result=1; - } - ],[ - "-re","[^\n]+assword:",sub{ - $exp->set_accum($exp->after); - $exp->notransfer(0); - &log_error("$equipmentname: invalid username/password"); - $exp->hard_close(); - $result=0; - } - ],[ - timeout => sub{ - $exp->set_accum($exp->after); - $exp->notransfer(0); - &log_error("$equipmentname: timeout due to unknown input after login"); - $exp->hard_close(); - $result=0; - } - ]); - }else{ - &log_error("$equipmentname: password requested but no password supplied. disconnecting"); - $exp->hard_close(); - $result=0; - } - } - ],[ - "-re","[^\n]+not known",sub{ - $exp->notransfer(0); - $exp->set_accum($exp->after); - &log_error("$equipmentname: unknown hostname $hostname"); - $exp->soft_close(); - $result=0; - } - ],[ - "-re","[^\n]+refused",sub{ - $exp->notransfer(0); - $exp->set_accum($exp->after); - &log_error("$equipmentname: connection refused to $hostname"); - $exp->soft_close(); - $result=0; - } - ],[ - "-re","Host key verification failed",sub{ - $exp->notransfer(0); - $exp->set_accum($exp->after); - &log_error("$equipmentname: Host $hostname key verification failed"); - $exp->soft_close(); - $result=0; - } - ],[ - "Are you sure you want to continue connecting (yes/no)?",sub{ - $exp->set_accum($exp->after); - &log_msg("$equipmentname: new key fingerprint"); - $exp->send("yes\r"); - $exp->exp_continue; - } - ],[ - timeout => sub{ - if ($exp->before() eq ""){ - &log_error("$equipmentname: connection timeout"); - }else{ - &log_error("$equipmentname: timeout due to unknown input before login"); - } - $result=0; - } - ]); - return $result; -} - - -# exp_connect_telnet -# Expect sequences to connect to a system via telnet -# IN: -# $exp = Expect object -# $equipmentname = equipment name / id / label -# $hostname = hostname or ip address -# $username = remote username -# $password = remote password -# $port = remote ssh port -# $prompt_regex = prompt expected -# OUT: -# 1 = OK -# 0 = NOK -sub exp_connect_telnet(){ - my $exp = $_[0]; - my $equipmentname = $_[1]; - my $hostname = $_[2]; - my $username = $_[3]; - my $password = $_[4]; - my $port = $_[5]; - my $prompt_regex = $_[6]; - my $result=0; - - if ($port ne ""){ - $exp->spawn(TELNET." $hostname $port"); - &log_msg("$equipmentname: connecting via telnet to $hostname on port $port..."); - }else{ - $exp->spawn(TELNET." $hostname"); - &log_msg("$equipmentname: connecting via telnet to $hostname..."); - } - - $exp->expect(TIMEOUT_CONNECT,[ - "-re","[^\n]+incorrect",sub{ - $exp->set_accum($exp->after); - $exp->notransfer(0); - &log_error("$equipmentname: invalid username"); - $exp->hard_close(); - $result=0; - } - ],[ - "-re","[^\n]+ogin:|Username:",sub{ - $exp->send("$username\r"); - &log_msg("$equipmentname: login prompt detected. sending username (username=$username)"); - $exp->exp_continue; - } - ],[ - "-re","[^\n]+assword:",sub{ - if($password){ - $exp->send("$password\r"); - $exp->notransfer(1); - $exp->expect(TIMEOUT_GENERIC,[ - "-re","Terminal type",sub{ #ipso specific - $exp->set_accum($exp->after); - &log_msg("$equipmentname: terminal type requested. sending CR"); - $exp->send("\r"); - $exp->exp_continue; - } - ],[ - "-re",$prompt_regex,sub{ - $exp->notransfer(0); - $PROMPT_REGEX = $prompt_regex; - &log_msg("$equipmentname: login successfully"); - $result=1; - } - ],[ - "-re","[^\n]+incorrect|[^\n]+invalid",sub{ - $exp->set_accum($exp->after); - $exp->notransfer(0); - &log_error("$equipmentname: invalid username/password"); - $exp->hard_close(); - $result=0; - } - ],[ - "-re","[^\n]+assword:",sub{ - $exp->set_accum($exp->after); - $exp->notransfer(0); - &log_error("$equipmentname: invalid username/password"); - $exp->hard_close(); - $result=0; - } - ],[ - timeout => sub{ - $exp->set_accum($exp->after); - $exp->notransfer(0); - &log_error("$equipmentname: timeout due to unknown input after login"); - $exp->hard_close(); - $result=0; - } - ]); - }else{ - &log_error("$equipmentname: password requested but no password supplied. disconnecting"); - $exp->hard_close(); - $result=0; - } - } - ],[ - "-re","[^\n]+not known",sub{ - $exp->notransfer(0); - $exp->set_accum($exp->after); - &log_error("$equipmentname: unknown hostname $hostname"); - $exp->soft_close(); - $result=0; - } - ],[ - "-re","[^\n]+refused",sub{ - $exp->notransfer(0); - $exp->set_accum($exp->after); - &log_error("$equipmentname: connection refused to $hostname"); - $exp->soft_close(); - $result=0; - } - ],[ - timeout => sub{ - if ($exp->before() eq ""){ - &log_error("$equipmentname: connection timeout"); - }else{ - &log_error("$equipmentname: timeout due to unknown input before login"); - } - $result=0; - } - ]); - return $result; -} - -# exp_exit_config_mode -# Expect sequences to exit config mode -# IN: -# $exp = Expect object -# $equipmentname = equipment name / id / label -# $promptenable_regex = prompt expected in enable mode -# OUT: -# 1 = OK -# 0 = NOK -sub exp_exit_config_mode(){ - my $exp = $_[0]; - my $equipmentname = $_[1]; - my $promptenable_regex = $_[2]; - my $result=0; - - $exp->expect(TIMEOUT_GENERIC,[ - "-re",$PROMPT_REGEX,sub{ - $exp->send("exit\r"); - $exp->notransfer(1); - $exp->expect(TIMEOUT_GENERIC,[ - "-re",$promptenable_regex,sub{ - $exp->notransfer(0); - $PROMPT_REGEX=$promptenable_regex; - &log_msg("$equipmentname: exiting config mode successfully"); - $result=1; - } - ],[ - timeout => sub{ - $exp->notransfer(0); - &log_error("$equipmentname: timeout due to unknown input after trying to exit config mode"); - $exp->hard_close(); - $result=0; - } - ]); - } - ],[ - timeout => sub{ - $exp->notransfer(0); - &log_error("$equipmentname: timeout due to unknown input before trying to exit config mode"); - $exp->hard_close(); - $result=0; - } - ]); - return $result; -} - -# exp_enter_config_mode -# Expect sequences to enter config mode -# IN: -# $exp = Expect object -# $equipmentname = equipment name / id / label -# $promptconfig_regex = prompt expected in config mode -# OUT: -# 1 = OK -# 0 = NOK -sub exp_enter_config_mode(){ - my $exp = $_[0]; - my $equipmentname = $_[1]; - my $promptconfig_regex = $_[2]; - my $result=0; - - $exp->expect(TIMEOUT_GENERIC,[ - "-re",$PROMPT_REGEX,sub{ - $exp->send("configure terminal\r"); - $exp->notransfer(1); - $exp->expect(TIMEOUT_GENERIC,[ - "-re",$promptconfig_regex,sub{ - $exp->notransfer(0); - $PROMPT_REGEX=$promptconfig_regex; - &log_msg("$equipmentname: entering config mode successfully"); - $result=1; - } - ],[ - timeout => sub{ - $exp->notransfer(0); - &log_error("$equipmentname: timeout due to unknown input after trying to enter config mode"); - $exp->hard_close(); - $result=0; - } - ]); - } - ],[ - timeout => sub{ - $exp->notransfer(0); - &log_error("$equipmentname: timeout due to unknown input before trying to enter config mode"); - $exp->hard_close(); - $result=0; - } - ]); - return $result; -} - -# exp_enter_enable_mode -# Expect sequences to enter enable mode -# IN: -# $exp = Expect object -# $equipmentname = equipment name / id / label -# $enablepassword = remote enablepassword -# $promptenable_regex = prompt expected in enable mode -# OUT: -# 1 = OK -# 0 = NOK -sub exp_enter_enable_mode(){ - my $exp = $_[0]; - my $equipmentname = $_[1]; - my $enablepassword = $_[2]; - my $promptenable_regex = $_[3]; - my $result=0; - - $exp->expect(TIMEOUT_GENERIC,[ - "-re",$PROMPT_REGEX,sub{ - $exp->send("enable\r"); - $exp->expect(TIMEOUT_GENERIC,[ - "-re","[^\n]+assword:",sub{ - $exp->send("$enablepassword\r"); - $exp->notransfer(1); - $exp->expect(TIMEOUT_GENERIC,[ - "-re",$promptenable_regex,sub{ - $exp->notransfer(0); - $PROMPT_REGEX=$promptenable_regex; - &log_msg("$equipmentname: entering enable mode successfully"); - $result=1; - } - ],[ - "-re","[^\n]+assword:",sub{ - $exp->notransfer(0); - &log_error("$equipmentname: invalid enable password"); - $exp->hard_close(); - $result=0; - } - ],[ - timeout => sub{ - $exp->notransfer(0); - &log_error("$equipmentname: timeout due to unknown input after enable password has been sent"); - $exp->hard_close(); - $result=0; - } - ]); - } - ],[ - timeout => sub{ - &log_error("$equipmentname: timeout due to unknown input after enable command"); - $exp->hard_close(); - $result=0; - } - ]); - } - ],[ - timeout => sub{ - $exp->notransfer(0); - &log_error("$equipmentname: timeout due to unknown input before sending enable command"); - $exp->hard_close(); - $result=0; - } - ]); - return $result; -} - -# exp_disconnect() -# Disconnect from equipment -# IN: -# $exp = Expect object -# $equipmenttype = Equipment type (must be supported) -# $method = Method (must be supported) -# $parrEquipment = Array containing equipmentname, hostname, username, password, enablepassword -# OUT: -# 1 = OK -# 0 = NOK -sub exp_disconnect(){ - my $exp = $_[0]; - my $equipmenttype = $_[1]; - my $method = $_[2]; - my $parrEquipment = $_[3]; - my $result; - if (($equipmenttype eq "posix")||($equipmenttype eq "bluecoat")||($equipmenttype eq "cisco")||($equipmenttype eq "netscreen")){ - $result = &exp_disconnect_generic_exit($exp, @$parrEquipment[0]); - }elsif (($equipmenttype eq "tippingpoint")){ - $result = &exp_disconnect_generic_quit($exp, @$parrEquipment[0]); - }else{ - &log_msg("Disconnection for equipmenttype and method combination undefined. (equipmenttype=$equipmenttype method=$method)"); - } - return !$result; -} - -# exp_disconnect_generic_exit -# Expect sequences - disconnect from generic system (ie: send "exit") -# IN: -# $equipmentname = equipment name / id / label -# OUT: -# 1 = OK -# 0 = NOK -sub exp_disconnect_generic_exit(){ - my $exp = $_[0]; - my $equipmentname = $_[1]; - my $result=0; - $exp->expect(TIMEOUT_GENERIC,[ - "-re",$PROMPT_REGEX,sub{ - $exp->send("exit\r"); - $exp->expect(TIMEOUT_GENERIC,[ - "-re","Configuration modified, save?",sub{ #netscreen specific - &log_msg("$equipmentname: equipment wants to save config, sending no"); - $exp->send("n\r"); - $exp->exp_continue; - } - ],[ - "-re","onnection[^\n]+closed",sub{ - &log_msg("$equipmentname: clean disconnect"); - $exp->soft_close(); - $result=1; - } - ],[ - timeout => sub{ - &log_error("$equipmentname: timeout due to unknown input after disconnect"); - $exp->soft_close(); - $result=0; - } - ]); - } - ],[ - timeout => sub{ - log_error("$equipmentname: timeout due to unknown input before disconnect"); - $exp->soft_close(); - $result=0; - } - ]); - return $result; -} - -# exp_disconnect_generic_quit -# Expect sequences - disconnect from generic system (ie: send "quit") -# IN: -# $equipmentname = equipment name / id / label -# OUT: -# 1 = OK -# 0 = NOK -sub exp_disconnect_generic_quit(){ - my $exp = $_[0]; - my $equipmentname = $_[1]; - my $result=0; - $exp->expect(TIMEOUT_GENERIC,[ - "-re",$PROMPT_REGEX,sub{ - $exp->send("quit\r"); - $exp->expect(TIMEOUT_GENERIC,[ - timeout => sub{ - &log_error("$equipmentname: timeout due to unknown input after disconnect"); - $exp->soft_close(); - $result=0; - } - ]); - } - ],[ - timeout => sub{ - log_error("$equipmentname: timeout due to unknown input before disconnect"); - $exp->soft_close(); - $result=0; - } - ]); - return $result; -} - -# exp_send_command -# Send command to equipment -# IN: -# $exp = Expect object -# $equipmenttype = Type of equipment -# $equipmentname = Equipment name -# $command = command to be sent -# $pcommandresult = pointer to commandresult variable in order to bring back result -# OUT: -# 1 = OK -# 0 = NOK -sub exp_send_command(){ - my $exp = $_[0]; - my $equipmenttype = $_[1]; - my $equipmentname = $_[2]; - my $command = $_[3]; - my $pcommandresult = $_[4]; - my $result; - if (($equipmenttype eq "posix")||($equipmenttype eq "bluecoat")||($equipmenttype eq "cisco")||($equipmenttype eq "netscreen")||($equipmenttype eq "tippingpoint")){ - $result = &exp_send_command_generic($exp, $equipmentname, $command, $pcommandresult); - }else{ - &log_msg("Send command for equipmenttype undefined. (equipmenttype=$equipmenttype)"); - } - return $result; -} - - sub print_debug_expect { - my $before = shift; - my $match = shift; - my $after = shift; - print("\n\n>>>>>TESTING-START<<<<<<\n"); - print("\n>>>BEFORE:###".$before."###\n"); - print("\n>>>MATCH:###".$match."###\n"); - print("\n>>>AFTER:###".$after."###\n"); - print("\n>>>>>TESTING-END<<<<<<\n"); - } - -# exp_send_command_generic -# Expect sequences to send command to remote equipment -# IN: -# $exp = Expect object -# $equipmentname = Equipment name -# $command = command to be sent -# $pcommandresult = pointer to commandresult variable in order to bring back result -# OUT: -# 1 = OK -# 0 = NOK -sub exp_send_command_generic(){ - my $exp = $_[0]; - my $equipmentname = $_[1]; - my $command = $_[2]; - my $pcommandresult = $_[3]; - my $result=0; - my $more = "--- more --- "; - - $exp->expect(TIMEOUT_GENERIC,[ - "-re",$PROMPT_REGEX,sub{ - $exp->send("$command\r"); -# $exp->notransfer(1); - $exp->expect(TIMEOUT_COMMAND,[ - "-re",$PROMPT_REGEX,sub{ -# $exp->notransfer(0); - log_msg("$equipmentname: command sent successfully (cmd = $command)"); - ${$pcommandresult} .= $exp->before(); -# ${$pcommandresult} .= substr($exp->before(),index($exp->before(),"\n")+1)."\r\n"; -# print("\n\n>>>>>TESTING-START<<<<<<\n"); -# my $before=$exp->before(); -# $before=~s/\r/\\r/g; -# $before=~s/\n/\\n/g; -# my $match=$exp->match(); -# $match=~s/\r/\\r/g; -# $match=~s/\n/\\n/g; -# my $after=$exp->after(); -# $after=~s/\r/\\r/g; -# $after=~s/\n/\\n/g; -# print("\n>>>BEFORE:###".$before."###\n"); -# print("\n>>>MATCH:###".$match."###\n"); -# print("\n>>>AFTER:###".$after."###\n"); -# print("\n>>>>>TESTING-END<<<<<<\n"); - $result=1; - $exp->send("\r\n"); # sending line break for exit match - } - ],[ - "-re",$more,sub{ -# $exp->notransfer(0); - log_msg("$equipmentname: found --- more --- "); -# ${$pcommandresult} .= substr($exp->before(),index($exp->before(),"\n")+1); - ${$pcommandresult} .= $exp->before(); -# &print_debug_expect ($exp->before(), $exp->match(), $exp->after()); - $exp->send(" \n"); -# $exp->notransfer(1); - $exp->exp_continue; - } - ],[ - "-re","onnection[^\n]+closed",sub{ -# $exp->notransfer(0); - log_msg("$equipmentname: connection closed while waiting for prompt"); - $exp->soft_close(); - $result=1; - } -# ],[ -# "-re",$PROMPT_REGEX,sub{ -# $exp->notransfer(0); -# print("\n\n>>>>>TESTING-START<<<<<<\n"); -# my $before=$exp->before(); -# $before=~s/\r/\\r/g; -# $before=~s/\n/\\n/g; -# my $match=$exp->match(); -# $match=~s/\r/\\r/g; -# $match=~s/\n/\\n/g; -# my $after=$exp->after(); -# $after=~s/\r/\\r/g; -# $after=~s/\n/\\n/g; -# print("\n>>>BEFORE:###".$before."###\n"); -# print("\n>>>MATCH:###".$match."###\n"); -# print("\n>>>AFTER:###".$after."###\n"); -# print("\n>>>>>TESTING-END<<<<<<\n"); -# print("\n\n"); -# $result=0; -# } - ],[ - timeout => sub{ -# $exp->notransfer(0); - log_error("$equipmentname: timeout due to unknown input after command"); -# print("\n>>>PROMPT_REGEX:###".$PROMPT_REGEX."###\n"); -# print("\n>>>BEFORE:###".$exp->before()."###\n"); -# print("\n>>>MATCH:###".$exp->match()."###\n"); -# print("\n>>>AFTER:###".$exp->after()."###\n"); - $exp->soft_close(); - $result=0; - } - ]); - } - ],[ - timeout => sub{ - log_error("$equipmentname: timeout due to unknown input before command"); - $exp->soft_close(); - $result=0; - } - ]); - return $result; -} - -# fill_arrCommandFile_from_dir() -# Fill array of commandfiles, outputfiles from the commandirectory -# IN: -# $passCommandFileOutputFileFile = Pointer to associative array of commandfiles and outputfiles -# $commanddir = directory containing commandfiles -# OUT: -# 1 = OK -# 0 = NOK -sub fill_arrCommandFile_from_dir(){ - my $passCommandFileOutputFileFile = $_[0]; - my $commanddir = $_[1]; - my @arrCommandFile; - my @arrOutputFileFile; - my $numcommandfiles = 0; - my $result = 0; - opendir(DIR,$commanddir); - @arrCommandFile = grep {/.*\.C/ && -f "$commanddir/$_"} readdir(DIR); - closedir(DIR); - opendir(DIR,$commanddir); - @arrOutputFileFile = grep {/.*\.O/ && -f "$commanddir/$_"} readdir(DIR); - closedir(DIR); - for (@arrCommandFile) { - $_ = $commanddir."/".$_; - $_ =~ s/\/\//\//g; # replace // with / - } - for (@arrOutputFileFile) { - $_ = $commanddir."/".$_; - $_ =~ s/\/\//\//g; # replace // with / - } - - for (@arrCommandFile) { - my $commandfile = $_; - my $commandfileprefix = $commandfile; - my $outputfilematched = ""; - $commandfileprefix =~ s/.C$//g; - for (@arrOutputFileFile) { - my $outputfile = $_; - my $outputfileprefix = $outputfile; - $outputfileprefix =~ s/.O$//g; - if ($commandfileprefix eq $outputfileprefix){ - $outputfilematched = $outputfile; - last; - } - } - $$passCommandFileOutputFileFile{$commandfile} = $outputfilematched; - } - $numcommandfiles = keys(%$passCommandFileOutputFileFile); - if ($numcommandfiles ne ""){ - $result = 1; - } - return $result; -} - -# get_directory() -# Returns the directory part of a fullpath -# IN: -# $fullpath = path to file -# OUT: -# $directory = directory containing $fullpath -sub get_directory(){ - my $fullpath = $_[0]; - my $directory = $fullpath; - $directory =~ s/[^\/]*$//g; - return $directory; -} - - -# get_timestamp() -# Return timestamp -# IN: -# $msg = error message -sub get_timestamp(){ - return (strftime "%Y%m%d %H:%M:%S", localtime); -} - - -# is_directory() -# Returns true if $directory is a real directory -# IN: -# $directory = directory to verify -# OUT: -# 1 = TRUE -# 0 = FALSE -sub is_directory(){ - my $directory = $_[0]; - my $result = 0; - if (opendir(DIR,$directory)){ - $result = 1; - closedir(DIR); - } - return $result; -} - - - -# log_error() -# Log error message using default settings -# IN: -# $msg = error message -sub log_error(){ - my $msg = $_[0]; - my $timestamp = &get_timestamp(); - if ($DISPLAYLEVEL>=1 && $DISPLAYLEVEL<=4){ - print("[LOGFILE: $timestamp $msg]\n"); - }elsif ($DISPLAYLEVEL>=5){ - print("\n[LOGFILE: $timestamp $msg]\n"); - } - if ($LOGFILE ne ""){ - &append_string_to_file($LOGFILE, "$timestamp $msg\n"); - } -} - -# log_msg() -# Log message using default settings -# IN: -# $msg = error message -sub log_msg(){ - my $msg = $_[0]; - my $timestamp = &get_timestamp(); - if ($DISPLAYLEVEL==4){ - print("[LOGFILE: $timestamp $msg]\n"); - }elsif ($DISPLAYLEVEL>=5){ - print("\n[LOGFILE: $timestamp $msg]\n"); - } - if ($LOGFILE ne ""){ - &append_string_to_file($LOGFILE, "$timestamp $msg\n"); - } -} - -sub normalize_commandresult { - my $pinput = $_[0]; - my $prompt = $_[1]; - my $result = ''; - my $line_count = 0; - foreach my $line (split(/\n/, ${$pinput})) { - $line =~ s/\r//g; - $line =~ s/\s+$//; - if ($line =~ /(\010)+(.*?)$/) { $line = $2;} - if ($line_count>0 && $line !~ /^.+?\(\w\)\-\>/ && $line !~ /^\-+$/ && $line !~ /^--- more/) { $result .= "$line\n"; } - # remove first line which contains the command - # remove trailing line if it contains prompt - # remove trailing line if it contains -------------------- - # remore --- more relict which only happens if last line contains more when paging config - $line_count++; - } - ${$pinput} = $result; -} - -# process_commandresult() -# Display to stdout depending of settings and send to outputfile -# IN: -# $parrEquipment = array containing equipmentname, hostname, username, password, enablepassword -# $command = command sent to equipment -# $commandresult = command result -# $outputfile = file to put command result in -# $outputfileappend = if true then append instead of writing. -# OUT: -# 1 = OK -# 0 = NOK -sub process_commandresult(){ - my $parrEquipment = $_[0]; - my $command = $_[1]; - my $commandresult = $_[2]; - $commandresult =~ s/\r\r\n\r\n\r\n\r/\r\n/g; #special replacement for tippingpoint columns and rows display bug - my $outputfile = $_[3]; - my $outputfileappend = $_[4]; - if ($DISPLAYLEVEL==0){ - }elsif ($DISPLAYLEVEL==1){ - print($commandresult); - }elsif ($DISPLAYLEVEL==2){ - print(@$parrEquipment[0]." ".$commandresult); - }elsif ($DISPLAYLEVEL>=3){ - print("--------------------------------------------------------------\n"); - print("EQUIPMENT: ".@$parrEquipment[0]."\n"); - print("COMMAND: ".$command."\n"); - print("RESULT: ".$commandresult); - if ($outputfile ne ""){ - print("OUTPUTFILE: ".$outputfile."\n"); - } - print("--------------------------------------------------------------\n"); - print("\n"); - } - if ($outputfile ne ""){ - my $directory = &get_directory($outputfile); - if ($directory ne "" && !&is_directory($directory)){ - &log_msg("@$parrEquipment[0]: creating $directory because it does not exist"); - mkpath($directory); - } - #if outputfileappend is true then we append to existing files - if ($outputfileappend){ - &log_msg("@$parrEquipment[0]: appending command result to output file $outputfile"); - &append_string_to_file($outputfile, $commandresult); - - } else { - &log_msg("@$parrEquipment[0]: writing command result to output file $outputfile"); - &write_string_to_file($outputfile, $commandresult); - } - } -} - -# show_help() -# Print out usage with complete details -sub show_help() { - show_version(); - show_usage(); - print "Parameter details: --i inputfile : File containing the list of equipment with credentials. Expected format: - equipmentname1 hostname1 username1 password1 enablepassword1 - equipmentname2 hostname2 username2 password2 enablepassword2 - (...) --t equipmenttype : Type of equipment. Valid values: posix, bluecoat, cisco, netscreen, tippingpoint. --c command : Command to run on remote equipment. --C commandir : Directory containing many commands to be run in one connection on a remote equipment. It must have the following content: - Files named *.C : Contain command(s) to run. - Files named *.O : Contain name of output file for corresponding commands. --m method : Method used to access equipment. Valid values: ssh, telnet. Default is ssh. --p port : Specify port in order to access equipment. Default is using standard port for service. --r numretry : Number of times the script will try to connect to the equipment on timeout. Default is ".NBTRY." --d displaylevel : Level of information displayed on stdout. Expected level are: - 0 : Nothing displayed. - 1 : Result of command displayed. DEFAULT. - 2 : Equipment's name and command results displayed on one line. - 3 : Equipment's name, command and command results all displayed on multiple lines. - 4 : Equipment's name, command and command results all displayed on multiple lines. Logs displayed. - 5 : Equipment's name, command and command results all displayed on multiple lines. Logs displayed. Session logs displayed. --o outputfile : File where results of command will be saved. --a : append to output file instead of writing new content. --l logfile : File where logs will be saved. --L sessionlogfile : File where session logs (the entire remote session) will be saved. --v : show version. --h : show this help. - -User variables: -It is possible to use variables in the output file and in the command string. Use the following syntax: - \%VAR0\% = equipmentname - \%VAR1\% = hostname - (...) - \%VAR".MAXVAR."\% = custom variables - -Concrete examples: - ".PROGRAM." -i login.txt -t posix -m ssh -c \"uptime\" - ".PROGRAM." -i login.txt -t posix -m ssh -c \"uptime\" -d 0 -o \"%VAR0%-uptime.txt\" - -"; -} - -# show_usage() -# Print out usage -sub show_usage() { - print("usage: ".PROGRAM." -z zielhost -u username -t equipmenttype -i identity-file -c command [-C commanddir] [-m method] [-p port] [-r numretry] [-d displaylevel] [-o outputfile] [-a] [-l logfile] [-L sessionlogfile] [-v] [-h]\n\n"); -} - -# show_version() -# Print out usage -sub show_version() { - print(PROGRAM." v".VERSION." by Youri Reddy-Girard http://sendcommand.sourceforge.net/\n\n"); -} - -# validate_arguments() -# Validate arguments received by command line argument -# IN: -# $inputfile = Filename containing the list of equipment with credentials. -# $equipmenttype = Type of equipment (posix, bluecoat, cisco or netscreen). -# $command = Command to run on remote equipment. -# $commanddir = Directory containing commands and output files. -# $method = Method used to access equipment (ssh, telnet). -# $port = Port to connect to -# $numretry = Number of times the script will try to connect to the equipment on timeout -# $displaylevel = Level on information displayed on stdout. -# $outputfile = File that will contain the result of the command. -# $outputfileappend = Append to output file instead of writing new content. -# $logfile = File where logging will take place. -# $sessionlogfile = File where session logging will take place. -# $version = if variable defined, show version. -# $help = if variable defined, show help. -# OUT: -# 1 = OK -# 0 = NOK -sub validate_arguments(){ - my $inputfile = $_[0]; - my $equipmenttype = $_[1]; - my $command = $_[2]; - my $commanddir = $_[3]; - my $method = $_[4]; - my $port = $_[5]; - my $numretry = $_[6]; - my $displaylevel = $_[7]; - my $outputfile = $_[8]; - my $outputfileappend = $_[9]; - my $logfile = $_[10]; - my $sessionlogfile = $_[11]; - my $version = $_[12]; - my $help = $_[13]; - my $result = 1; - if ($inputfile eq ""){ - printf("ERROR - missing inputfile.\n"); - $result = 0; - } - if ($equipmenttype eq ""){ - printf("ERROR - missing equipment type.\n"); - $result = 0; - }elsif ( $equipmenttype ne "posix" && $equipmenttype ne "bluecoat" && $equipmenttype ne "cisco" && $equipmenttype ne "netscreen" && $equipmenttype ne "tippingpoint"){ - printf("ERROR - Unknown equipment type. Valid values are posix, bluecoat, cisco, netscreen and tippingpoint.\n"); - $result = 0; - } - if (($method ne "ssh") && ($method ne "telnet")){ - printf("ERROR - unreconized method $method.\n"); - $result = 0; - } - if (($port ne "")&&(!(($port>0)&&($port<65535)))){ - printf("ERROR - port must be numeric between 0 and 65534.\n"); - $result = 0; - } - if (($command eq "") && ($commanddir eq "")){ - printf("ERROR - missing command.\n"); - $result = 0; - } - if ($commanddir ne ""){ - if (&is_directory($commanddir)){ - }else{ - printf("ERROR - commanddir $commanddir is not a directory.\n"); - $result = 0; - } - } - return $result; -} - -# validate_equipment() -# Validate equipment input file -# IN: -# equipmenttype : Type of equipment (posix, bluecoat, ...) -# arrEquipment : Array containing equipmentname, hostname, username, password, enablepassword -# OUT: -# 1 = OK -# 0 = NOK -sub validate_equipment(){ - my $equipmenttype = $_[0]; - my $parrEquipment = $_[1]; - my $result = 0; - my $size = @$parrEquipment; - #if (($equipmenttype eq "posix") && ($size==3 || $size==4)){ - if (($equipmenttype eq "posix") && ($size>=3)){ - $result = 1; - #}elsif ($equipmenttype eq "bluecoat" && $size==5){ - }elsif ($equipmenttype eq "bluecoat" && $size>=5){ - $result = 1; - #}elsif ($equipmenttype eq "cisco" && $size==5){ - }elsif ($equipmenttype eq "cisco" && $size>=5){ - $result = 1; - #}elsif ($equipmenttype eq "netscreen" && $size==4){ - }elsif ($equipmenttype eq "netscreen" && $size>=4){ - $result = 1; - #}elsif ($equipmenttype eq "tippingpoint" && $size==4){ - }elsif ($equipmenttype eq "tippingpoint" && $size>=4){ - $result = 1; - }else{ - $result = 0; - } - return $result; -} - -# write_array_to_file() -# Write an array to a file -# IN: -# $file = filename -# $parr = pointer to array to write -# OUT: -# 1 = OK -# 0 = NOK -sub write_array_to_file(){ - my $file = $_[0]; - my $parr = $_[1]; - my $result = 0; - if (open(FILE, ">", $file)){ - if (print FILE @$parr){ - $result = 1; - } - close(FILE); - } -} - -# write_string_to_file() -# Write a string to a file -# IN: -# $file = filename -# $string = string to write -# OUT: -# 1 = OK -# 0 = NOK -sub write_string_to_file(){ - my $file = $_[0]; - my $string = $_[1]; - my $result = 0; - if (open(FILE, ">", $file)){ - if (print FILE $string){ - $result = 1; - } - close(FILE); - } -} - -sub get_prompt { - my $equipmenttype = shift; - - if ($equipmenttype eq "netscreen") { return PROMPT_REGEX_NETSCREEN; } - if ($equipmenttype eq "bluecoat") { return PROMPT_REGEX_BLUECOAT; } - return PROMPT_REGEX_POSIX; -} - -############################################################# -# MAIN PROGRAM -############################################################# -# (command line arguments : -i inputfile -t equipmenttype -c command [-C commanddir] [-m method] [-p port] [-r numretry] [-d displaylevel] [-o outputfile] [-l logfile] [-L sessionlogfile]) - my $inputfile = ""; - my $equipmenttype = "netscreen"; - my $command = ""; - my $commandformatted = ""; - my $commanddir = ""; - my $method = METHOD; - my $port = ""; - my $numretry = NBTRY; - my $displaylevel = DISPLAYLEVEL; - my $outputfile = ""; - my $outputfileformatted = ""; - my $outputfileappend = OUTPUTFILEAPPEND; - my $outputfileappendcontext = ""; - my $logfile = ""; - my $sessionlogfile = ""; - my $version = ""; - my $help = ""; - my $identity_file = ""; - my $username= ""; - my $zielhost = ""; - my $return_code = 0; - my $connect_check = 0; - my $send_command_check = 0; - - #Get command line arguments - GetOptions("i:s"=>\$identity_file, "z:s"=>\$zielhost, "u:s"=>\$username, "t:s"=>\$equipmenttype, "c:s"=>\$command, - "C:s"=>\$commanddir, "m:s"=>\$method, "p:i"=>\$port, "n:i"=>\$numretry, "d:i"=>\$displaylevel, "o:s"=>\$outputfile, "a"=>\$outputfileappend, - "l:s"=>\$logfile, "v" => \$version, "L:s"=>\$sessionlogfile, "help" => \$help, "h" => \$help); - my $prompt = &get_prompt($equipmenttype); - - if ($help){ show_help(); exit 0; } #if -h is specified - if ($version){ show_version(); exit 0; } #if -v is specified - #validate command line arguments - if (!&validate_arguments("dummy_input_file", $equipmenttype, $command, $commanddir, $method, $port, $numretry, $displaylevel, $outputfile, $outputfileappend, $logfile, $sessionlogfile, $version, $help)){ - show_usage(); - exit 1; - } - #Fill global variables - $LOGFILE = $logfile; - $DISPLAYLEVEL = $displaylevel; - my @arrEquipment = ($zielhost, $zielhost, $username, 'dummy_password', 'dummy_enable_password'); - if(&validate_equipment($equipmenttype, \@arrEquipment)){ - my $iTry=0; - my $bConnected=0; - while($iTry<$numretry && $bConnected==0){ - my $objExpect = Expect->new(); - if ($sessionlogfile ne ""){ - $objExpect->log_file($sessionlogfile); - } - if ($DISPLAYLEVEL>=5){ - $objExpect->log_user(1); - } - $bConnected=&exp_connect($objExpect, $equipmenttype, $method, $port, \@arrEquipment, $identity_file); - if ($bConnected) { - if ($command ne ""){ - #replace user variables - $commandformatted = $command; - $outputfileformatted = $outputfile; - foreach my $i(0..MAXVAR) { - $commandformatted =~ s/%VAR$i%/$arrEquipment[$i]/g; - $outputfileformatted =~ s/%VAR$i%/$arrEquipment[$i]/g; - } - my $commandresult = ""; - $send_command_check = &exp_send_command($objExpect, $equipmenttype, $arrEquipment[0], $commandformatted, \$commandresult); - if ($send_command_check){ - &normalize_commandresult(\$commandresult, $prompt); - &process_commandresult(\@arrEquipment, $commandformatted, $commandresult, $outputfileformatted, $outputfileappend); - $return_code = 0; - } else{ - &log_msg("$arrEquipment[0]: Error when sending command. (command=$commandformatted)"); - $return_code = 1; - } - } - if (&exp_disconnect($objExpect, $equipmenttype, $method, \@arrEquipment)) { $return_code = 1; } - } - $iTry++; - } - $return_code = $return_code || (!$bConnected); - } else { $return_code = 1; } - exit ($return_code); \ No newline at end of file diff --git a/roles/importer/files/importer/test/__init__.py b/roles/importer/files/importer/test/__init__.py new file mode 100644 index 0000000000..5ffffad98f --- /dev/null +++ b/roles/importer/files/importer/test/__init__.py @@ -0,0 +1,3 @@ +from fwo_log import FWOLogger + +FWOLogger(5) \ No newline at end of file diff --git a/roles/importer/files/importer/test/conftest.py b/roles/importer/files/importer/test/conftest.py new file mode 100644 index 0000000000..e6d7c140b0 --- /dev/null +++ b/roles/importer/files/importer/test/conftest.py @@ -0,0 +1,189 @@ +import unittest.mock + +import pytest +from fwo_api import FwoApi +from fwo_api_call import FwoApiCall +from model_controllers.fwconfig_import_gateway import FwConfigImportGateway +from model_controllers.fwconfig_import_object import FwConfigImportObject +from model_controllers.fwconfig_import_rule import FwConfigImportRule +from model_controllers.import_state_controller import ImportStateController +from model_controllers.management_controller import ( + ConnectionInfo, + CredentialInfo, + DeviceInfo, + DomainInfo, + ManagementController, + ManagerInfo, +) +from models.fwconfig_normalized import FwConfigNormalized +from models.fwconfigmanager import FwConfigManager +from models.import_state import ImportState +from pytest_mock import MockerFixture +from services.enums import Lifetime, Services +from services.global_state import GlobalState +from services.group_flats_mapper import GroupFlatsMapper +from services.service_provider import ServiceProvider +from services.uid2id_mapper import Uid2IdMapper +from test.utils.config_builder import FwConfigBuilder + + +@pytest.fixture +def api_call(mocker: MockerFixture, api_connection: FwoApi) -> FwoApiCall: + fwo_api_call: FwoApiCall = unittest.mock.create_autospec(FwoApiCall) + fwo_api_call.call = mocker.MagicMock() + fwo_api_call.api = api_connection + return fwo_api_call + + +@pytest.fixture +def api_connection(mocker: MockerFixture) -> FwoApi: + fwo_api_connection: FwoApi = unittest.mock.create_autospec(FwoApi) + fwo_api_connection.call = mocker.MagicMock() + return fwo_api_connection + + +@pytest.fixture +def import_state_controller( + management_controller: ManagementController, + api_call: FwoApiCall, + api_connection: FwoApi, +) -> ImportStateController: + import_state = ImportState() + import_state.mgm_details = management_controller + import_state.tracks = {"ordered": 2, "inline": 3, "concatenated": 4, "domain": 5} + import_state.link_types = { + "ordered": 2, + "inline": 3, + "concatenated": 4, + "domain": 5, + } + + import_state.color_map = { + "black": 1, + "red": 2, + "green": 3, + "blue": 4, + } + + import_state.actions = { + "none": 1, + "accept": 2, + } + + import_state.tracks = { + "none": 1, + "log": 2, + } + + import_state.network_obj_type_map = {"network": 1, "group": 2, "host": 3, "machine_range": 4} + import_state.service_obj_type_map = {"simple": 1, "group": 2, "rpc": 3} + import_state.user_obj_type_map = {"group": 1, "simple": 2} + + import_state_controller: ImportStateController = unittest.mock.create_autospec(ImportStateController) + import_state_controller.state = import_state + import_state_controller.api_call = api_call + import_state_controller.api_connection = api_connection + + return import_state_controller + + +@pytest.fixture +def group_flats_mapper() -> GroupFlatsMapper: + return unittest.mock.create_autospec(GroupFlatsMapper) + + +@pytest.fixture +def global_state( + import_state_controller: ImportStateController, +) -> GlobalState: + global_state = GlobalState(import_state_controller) + global_state.normalized_config = FwConfigNormalized() + global_state.global_normalized_config = FwConfigNormalized() + global_state.previous_config = FwConfigNormalized() + global_state.previous_global_config = FwConfigNormalized() + return global_state + + +@pytest.fixture +def fwconfig_import_gateway() -> FwConfigImportGateway: + return FwConfigImportGateway() + + +@pytest.fixture +def management_controller() -> ManagementController: + return ManagementController( + mgm_id=3, + uid="mock-uid", + devices=[], + device_info=DeviceInfo(name="Mock Management", type_name="MockDevice", type_version="1.0"), + connection_info=ConnectionInfo(hostname="mock.example.com", port=443), + importer_hostname="mock-importer", + credential_info=CredentialInfo( + secret="mock-secret", # noqa: S106 + import_user="mock-user", + cloud_client_id="", + cloud_client_secret="", + ), + manager_info=ManagerInfo(is_super_manager=False, sub_manager_ids=[], sub_managers=[]), + domain_info=DomainInfo(domain_name="mock-domain", domain_uid="mock-domain-uid"), + import_disabled=False, + ) + + +@pytest.fixture +def fwconfig_builder() -> FwConfigBuilder: + return FwConfigBuilder() + + +@pytest.fixture +def uid2id_mapper( + service_provider: ServiceProvider, + global_state: GlobalState, +) -> Uid2IdMapper: + uid2id_mapper = service_provider.get_uid2id_mapper(import_id=global_state.import_state.state.import_id) + uid2id_mapper.update_rulebase_mapping = unittest.mock.MagicMock() + return uid2id_mapper + + +@pytest.fixture(autouse=True) +def service_provider( + global_state: GlobalState, + group_flats_mapper: GroupFlatsMapper, +) -> ServiceProvider: + service_provider = ServiceProvider() + service_provider.reset() + + service_provider.register(Services.GLOBAL_STATE, lambda: global_state, Lifetime.SINGLETON) + service_provider.register(Services.GROUP_FLATS_MAPPER, lambda: group_flats_mapper, Lifetime.IMPORT) + service_provider.register(Services.PREV_GROUP_FLATS_MAPPER, lambda: group_flats_mapper, Lifetime.IMPORT) + service_provider.register(Services.UID2ID_MAPPER, Uid2IdMapper, Lifetime.IMPORT) + return service_provider + + +@pytest.fixture +def fwconfig_import_rule_mock() -> FwConfigImportRule: + fw_config_import_rule: FwConfigImportRule = unittest.mock.create_autospec(FwConfigImportRule) + return fw_config_import_rule + + +@pytest.fixture +def fwconfig_import_rule() -> FwConfigImportRule: + return FwConfigImportRule() + + +@pytest.fixture +def fwconfig_import_object() -> FwConfigImportObject: + return FwConfigImportObject() + + +@pytest.fixture +def fw_config_manager() -> FwConfigManager: + return FwConfigManager( + manager_uid="mock-manager-uid", + manager_name="Mock Manager", + is_super_manager=False, + domain_uid="mock-domain-uid", + domain_name="Mock Domain", + sub_manager_ids=[], + configs=[], + ) diff --git a/roles/importer/files/importer/test/data/__init__.py b/roles/importer/files/importer/test/data/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/roles/importer/files/importer/test/data/mock_objects.py b/roles/importer/files/importer/test/data/mock_objects.py new file mode 100644 index 0000000000..25bdd88317 --- /dev/null +++ b/roles/importer/files/importer/test/data/mock_objects.py @@ -0,0 +1,181 @@ +from enum import Enum +from typing import Any + +from models.fwconfig_normalized import FwConfigNormalized +from models.fwconfigmanager import FwConfigManager +from test.utils.partial_dict import PartialDict + + +class ChangelogObjectType(Enum): + NETWORK_OBJECT = "obj" + SERVICE_OBJECT = "svc" + + +class ChangelogChangeAction(Enum): + INSERT = "I" + DELETE = "D" + CHANGE = "C" + + +class MockObjectsFactory: + @staticmethod + def get_mock_mgm_details() -> dict[str, Any]: + return { + "data": { + "management": [ + { + "id": 12, + "name": "Checkpoint_MDS", + "hostname": "192.168.10.5", # Needs to NOT have "://" to trigger decryption logic + "ssh_port": 22, + # Required for: api_call_result["data"]["management"][0]["import_credential"]["secret"] + "import_credential": {"id": 45, "username": "api_admin", "secret": ""}, + # Optional: The code iterates this if present + "subManagers": [ + { + "id": 101, + "name": "CMA_London", + "hostname": "192.168.10.6", + "import_credential": {"id": 46, "secret": ""}, + } + ], + } + ] + }, + "deviceType": {"id": 12, "name": "Checkpoint MDS"}, + } + + @staticmethod + def get_standard_fwconfig_manager(config: FwConfigNormalized | None = None) -> FwConfigManager: + return FwConfigManager( + manager_uid="mgr1", + is_super_manager=True, + sub_manager_ids=[], + configs=[config] if config else [], + domain_name="", + domain_uid="", + manager_name="mgr1", + ) + + @staticmethod + def get_standard_changelog_return_value() -> dict[str, Any]: + return { + "data": { + "add_nwobj_changelog": { + "nwobj_changelog": { + "id": 1, + } + }, + "add_svc_changelog": { + "svc_changelog": { + "id": 2, + } + }, + } + } + + @staticmethod + def build_changelog_object( + change_action: ChangelogChangeAction, + object_type: ChangelogObjectType, + object_id: int, + change_type_id: int = 3, + ) -> PartialDict: + def get_new_id() -> int | None: + if change_action == ChangelogChangeAction.INSERT: + return object_id + if change_action == ChangelogChangeAction.CHANGE: + return int(f"{object_id}0") + return None + + return PartialDict( + { + "change_action": change_action.value, + "change_type_id": change_type_id, + f"new_{object_type.value}_id": get_new_id(), + f"old_{object_type.value}_id": None if change_action == ChangelogChangeAction.INSERT else object_id, + "unique_name": str(object_id) + if change_action != ChangelogChangeAction.CHANGE + else str(int(f"{object_id}0")), + } + ) + + @staticmethod + def get_changelog_object_insert_delete(change_type_id: int = 3) -> list[PartialDict]: + return [ + MockObjectsFactory.build_changelog_object( + change_action=ChangelogChangeAction.INSERT, + object_type=ChangelogObjectType.NETWORK_OBJECT, + object_id=1, + change_type_id=change_type_id, + ), + MockObjectsFactory.build_changelog_object( + change_action=ChangelogChangeAction.DELETE, + object_type=ChangelogObjectType.NETWORK_OBJECT, + object_id=2, + change_type_id=change_type_id, + ), + ] + + @staticmethod + def get_changelog_object_insert_delete_change(change_type_id: int = 3) -> list[PartialDict]: + return [ + MockObjectsFactory.build_changelog_object( + change_action=ChangelogChangeAction.INSERT, + object_type=ChangelogObjectType.NETWORK_OBJECT, + object_id=1, + change_type_id=change_type_id, + ), + MockObjectsFactory.build_changelog_object( + change_action=ChangelogChangeAction.DELETE, + object_type=ChangelogObjectType.NETWORK_OBJECT, + object_id=2, + change_type_id=change_type_id, + ), + MockObjectsFactory.build_changelog_object( + change_action=ChangelogChangeAction.CHANGE, + object_type=ChangelogObjectType.NETWORK_OBJECT, + object_id=1, + change_type_id=change_type_id, + ), + ] + + @staticmethod + def get_changelog_svc_objects_insert_delete(change_type_id: int = 3) -> list[PartialDict]: + return [ + MockObjectsFactory.build_changelog_object( + change_action=ChangelogChangeAction.INSERT, + object_type=ChangelogObjectType.SERVICE_OBJECT, + object_id=3, + change_type_id=change_type_id, + ), + MockObjectsFactory.build_changelog_object( + change_action=ChangelogChangeAction.DELETE, + object_type=ChangelogObjectType.SERVICE_OBJECT, + object_id=4, + change_type_id=change_type_id, + ), + ] + + @staticmethod + def get_changelog_svc_objects_insert_delete_change(change_type_id: int = 3) -> list[PartialDict]: + return [ + MockObjectsFactory.build_changelog_object( + change_action=ChangelogChangeAction.INSERT, + object_type=ChangelogObjectType.SERVICE_OBJECT, + object_id=3, + change_type_id=change_type_id, + ), + MockObjectsFactory.build_changelog_object( + change_action=ChangelogChangeAction.DELETE, + object_type=ChangelogObjectType.SERVICE_OBJECT, + object_id=4, + change_type_id=change_type_id, + ), + MockObjectsFactory.build_changelog_object( + change_action=ChangelogChangeAction.CHANGE, + object_type=ChangelogObjectType.SERVICE_OBJECT, + object_id=3, + change_type_id=change_type_id, + ), + ] diff --git a/roles/importer/files/importer/test/test_base.py b/roles/importer/files/importer/test/test_base.py new file mode 100644 index 0000000000..af969572d4 --- /dev/null +++ b/roles/importer/files/importer/test/test_base.py @@ -0,0 +1,104 @@ +import unittest.mock + +import pytest +from fwo_api_call import FwoApiCall +from fwo_exceptions import FwoImporterError +from model_controllers.fwconfig_import_gateway import FwConfigImportGateway +from model_controllers.import_state_controller import ImportStateController +from pytest_mock import MockerFixture +from test.utils.test_utils import mock_get_graphql_code + + +def test_fwconfig_import_gateway_init( + import_state_controller: ImportStateController, + fwconfig_import_gateway: FwConfigImportGateway, + api_call: FwoApiCall, + mocker: MockerFixture, +): + gateway_id = 69 + from_rule_id = 123 + from_rulebase_id = 456 + to_rulebase_id = 789 + link_type = 1 + + api_call.call = unittest.mock.Mock( + return_value={ + "data": { + "rulebase_link": [ + { + "gw_id": gateway_id, + "from_rule_id": from_rule_id, + "from_rulebase_id": from_rulebase_id, + "to_rulebase_id": to_rulebase_id, + "link_type": link_type, + "is_initial": True, + "is_global": False, + "is_section": False, + "created": 1234567890, + "removed": None, + }, + ] + } + } + ) + + get_graphql_code = mock_get_graphql_code(mocker, "lol") + + import_state_controller.state.gateway_map = {3: {"uid": 69}} + + fwconfig_import_gateway.update_gateway_diffs() + + get_graphql_code.assert_called_once() + assert fwconfig_import_gateway.get_rb_link_controller().rb_links is not None + assert len(fwconfig_import_gateway.get_rb_link_controller().rb_links) == 1 + assert fwconfig_import_gateway.get_rb_link_controller().rb_links[0].from_rule_id == from_rule_id + assert fwconfig_import_gateway.get_rb_link_controller().rb_links[0].from_rulebase_id == from_rulebase_id + assert fwconfig_import_gateway.get_rb_link_controller().rb_links[0].to_rulebase_id == to_rulebase_id + assert fwconfig_import_gateway.get_rb_link_controller().rb_links[0].link_type == link_type + + +def test_fwconfig_import_gateway_init_no_links( + fwconfig_import_gateway: FwConfigImportGateway, + api_call: FwoApiCall, + mocker: MockerFixture, +): + api_call.call = unittest.mock.Mock(return_value={"data": {"rulebase_link": []}}) + + get_graphql_code = mock_get_graphql_code(mocker, "lol") + + import_state = fwconfig_import_gateway.get_global_state().import_state.state + + import_state.gateway_map = {} + get_graphql_code.assert_not_called() + + fwconfig_import_gateway.update_gateway_diffs() + assert fwconfig_import_gateway.get_rb_link_controller().rb_links is not None + assert len(fwconfig_import_gateway.get_rb_link_controller().rb_links) == 0 + + +def test_fwconfig_import_gateway_init_no_gateway_ids( + fwconfig_import_gateway: FwConfigImportGateway, + api_call: FwoApiCall, + mocker: MockerFixture, +): + api_call.call = unittest.mock.Mock(return_value={"data": {"rulebase_link": []}}) + + get_graphql_code = mock_get_graphql_code(mocker, "lol") + + import_state = fwconfig_import_gateway.get_global_state().import_state.state + + import_state.gateway_map = {1: {}} + + fwconfig_import_gateway.update_gateway_diffs() + get_graphql_code.assert_not_called() + assert fwconfig_import_gateway.get_rb_link_controller().rb_links is not None + assert len(fwconfig_import_gateway.get_rb_link_controller().rb_links) == 0 + + +def test_fwconfig_import_gateway_update_rulebase_link_diffs_no_configs( + fwconfig_import_gateway: FwConfigImportGateway, +): + fwconfig_import_gateway.get_global_state().normalized_config = None + with pytest.raises(FwoImporterError) as excinfo: + fwconfig_import_gateway.update_rulebase_link_diffs() + assert "normalized_config is None in update_rulebase_link_diffs" in str(excinfo.value) diff --git a/roles/importer/files/importer/test/test_caseinsensitiveenum.py b/roles/importer/files/importer/test/test_caseinsensitiveenum.py new file mode 100644 index 0000000000..7a26fe10a0 --- /dev/null +++ b/roles/importer/files/importer/test/test_caseinsensitiveenum.py @@ -0,0 +1,16 @@ +import pytest +from models.rule import RuleAction + + +def test_caseinsensitiveenum_matches_value_and_name_ignoring_case(): + assert RuleAction("accept") is RuleAction.ACCEPT + assert RuleAction("ACCEPT") is RuleAction.ACCEPT + + +def test_caseinsensitiveenum_raises_on_unknown_value(): + with pytest.raises(ValueError, match="not a valid RuleAction"): + RuleAction("unknown-action") + + +def test_caseinsensitiveenum_members_are_strings(): + assert isinstance(RuleAction.ACCEPT, str) diff --git a/roles/importer/files/importer/test/test_checkpoint_file_import.py b/roles/importer/files/importer/test/test_checkpoint_file_import.py new file mode 100644 index 0000000000..23f773ddc8 --- /dev/null +++ b/roles/importer/files/importer/test/test_checkpoint_file_import.py @@ -0,0 +1,37 @@ +import unittest.mock + +from fw_modules.checkpointR8x import fwcommon +from model_controllers.fwconfigmanagerlist_controller import FwConfigManagerListController +from model_controllers.import_state_controller import ImportStateController + + +class TestCheckpointNativeFileImport: + def test_checkpoint_native_file_import_skips_login(self, import_state_controller: ImportStateController): + config_in = FwConfigManagerListController() + config_in.native_config = { + "domains": [ + { + "domain_name": "", + "domain_uid": "", + "is-super-manager": False, + "management_name": "unit-test", + "management_uid": "uid", + "objects": [], + "rulebases": [], + "nat_rulebases": [], + "gateways": [], + } + ] + } + + import_state = import_state_controller + + fwcommon.cp_getter.login = unittest.mock.Mock( + side_effect=AssertionError("login should not be called for native config imports") + ) + + fwcommon.normalize_config = unittest.mock.Mock(return_value=config_in) + + _, result = fwcommon.get_config(config_in, import_state) + + assert result is config_in diff --git a/roles/importer/files/importer/test/test_checkpoint_service_protocol.py b/roles/importer/files/importer/test/test_checkpoint_service_protocol.py new file mode 100644 index 0000000000..09ffdccae0 --- /dev/null +++ b/roles/importer/files/importer/test/test_checkpoint_service_protocol.py @@ -0,0 +1,13 @@ +from fw_modules.checkpointR8x import cp_service + + +def test_get_protocol_number_handles_string_protocol(): + obj = {"ip-protocol": "17"} + + assert cp_service._get_protocol_number(obj) == 17 # pyright: ignore[reportPrivateUsage] + + +def test_get_rpc_number_stringifies_program_number(): + obj = {"program-number": 100235} + + assert cp_service._get_rpc_number(obj) == "100235" # pyright: ignore[reportPrivateUsage] diff --git a/roles/importer/files/importer/test/test_common_config_uri.py b/roles/importer/files/importer/test/test_common_config_uri.py new file mode 100644 index 0000000000..955c271021 --- /dev/null +++ b/roles/importer/files/importer/test/test_common_config_uri.py @@ -0,0 +1,56 @@ +import pytest +from common import get_config_uri, set_filename +from fwo_api import FwoApi +from fwo_api_call import FwoApiCall +from model_controllers.import_state_controller import ImportStateController +from model_controllers.management_controller import ManagementController +from models.import_state import ImportState + + +@pytest.fixture +def import_state_controller( + management_controller: ManagementController, + api_call: FwoApiCall, + api_connection: FwoApi, +) -> ImportStateController: + import_state = ImportState() + import_state.mgm_details = management_controller + controller = ImportStateController(state=import_state, api_call=api_call) + controller.state = import_state + controller.api_call = api_call + controller.api_connection = api_connection + return controller + + +class TestCommonConfigUri: + def test_get_config_uri_prefers_hostname_uri( + self, + import_state_controller: ImportStateController, + ): + import_state = import_state_controller + import_state.state.mgm_details.hostname = "https://example.com/config.json" + import_state.state.mgm_details.domain_name = "https://example.com/ignored.json" + + assert get_config_uri(import_state) == "https://example.com/config.json" + + def test_get_config_uri_falls_back_to_config_path_uri( + self, + import_state_controller: ImportStateController, + ): + import_state = import_state_controller + import_state.state.mgm_details.hostname = "fw.example.com" + import_state.state.mgm_details.domain_name = "file:///tmp/config.json" + + assert get_config_uri(import_state) == "file:///tmp/config.json" + + def test_set_filename_uses_config_uri_when_present( + self, + import_state_controller: ImportStateController, + ): + import_state = import_state_controller + import_state.state.mgm_details.hostname = "fw.example.com" + import_state.state.mgm_details.domain_name = "https://example.com/config.json" + + set_filename(import_state) + + assert import_state.state.import_file_name == "https://example.com/config.json" diff --git a/roles/importer/files/importer/test/test_fortiadom5ff.py b/roles/importer/files/importer/test/test_fortiadom5ff.py new file mode 100644 index 0000000000..fb537c8678 --- /dev/null +++ b/roles/importer/files/importer/test/test_fortiadom5ff.py @@ -0,0 +1,120 @@ +from datetime import datetime, timezone + +import pytest +from fw_modules.fortiadom5ff.fmgr_rule import rule_parse_last_hit +from fw_modules.fortiadom5ff.fwcommon import to_time_object +from fwo_exceptions import ImportInterruptionError +from models.time_object import TimeObject +from pytest_mock import MockerFixture + + +class TestToTimeObject: + @staticmethod + def _expected_as_utc(date_part: str, time_part: str) -> str: + return ( + datetime.strptime(f"{date_part} {time_part}", "%Y/%m/%d %H:%M") + .astimezone() + .astimezone(timezone.utc) + .isoformat(timespec="seconds") + ) + + def test_to_time_object_parses_list_timestamps(self): + time_obj = to_time_object( + { + "name": "work-hours", + "start": ["12:00", "2026/02/17"], + "end": ["18:30", "2026/02/17"], + } + ) + + assert time_obj.time_obj_uid == "work-hours" + assert time_obj.time_obj_name == "work-hours" + assert time_obj.start_time == self._expected_as_utc("2026/02/17", "12:00") + assert time_obj.end_time == self._expected_as_utc("2026/02/17", "18:30") + + def test_to_time_object_parses_single_string_timestamp(self): + time_obj = to_time_object( + { + "name": "legacy-format", + "start": "00:00 2020/01/01", + "end": "23:59 2020/01/01", + } + ) + + assert time_obj.start_time == self._expected_as_utc("2020/01/01", "00:00") + assert time_obj.end_time == self._expected_as_utc("2020/01/01", "23:59") + + def test_time_object_converts_timezone_offset_to_utc(self): + time_obj = TimeObject( + time_obj_uid="tz-conversion", + time_obj_name="tz-conversion", + start_time="2026-03-11T11:57:00+01:00", + end_time="2026-03-11T12:57:00+01:00", + ) + + assert time_obj.start_time == "2026-03-11T10:57:00+00:00" + assert time_obj.end_time == "2026-03-11T11:57:00+00:00" + + def test_to_time_object_returns_none_for_default_start_time(self): + time_obj = to_time_object( + { + "name": "all-day", + "start": "00:00", + "end": None, + } + ) + + assert time_obj.start_time is None + assert time_obj.end_time is None + + def test_to_time_object_logs_warning_for_unsupported_time_only_format(self, mocker: MockerFixture): + warning_mock = mocker.patch("fwo_log.FWOLogger.warning") + + time_obj = to_time_object( + { + "name": "unsupported", + "start": "12:00", + "end": "15:00", + } + ) + + assert time_obj.start_time is None + assert time_obj.end_time is None + assert warning_mock.call_count == 2 + + def test_to_time_object_logs_warning_for_invalid_datetime(self, mocker: MockerFixture): + warning_mock = mocker.patch("fwo_log.FWOLogger.warning") + + time_obj = to_time_object( + { + "name": "broken-date", + "start": ["12:00", "2026/13/17"], + "end": ["99:99", "2026/02/17"], + } + ) + + assert time_obj.start_time is None + assert time_obj.end_time is None + assert warning_mock.call_count == 2 + + @pytest.mark.parametrize("missing_name", [None, ""]) + def test_to_time_object_raises_on_missing_name(self, missing_name: str | None): + with pytest.raises(ImportInterruptionError): + to_time_object( + { + "name": missing_name, + "start": ["12:00", "2026/02/17"], + "end": ["18:00", "2026/02/17"], + } + ) + + +def test_rule_parse_last_hit_returns_offset_aware_iso_timestamp(): + epoch_seconds = 1761998205 + + parsed = rule_parse_last_hit({"_last_hit": epoch_seconds}) + + assert parsed is not None + parsed_time = datetime.fromisoformat(parsed) + assert parsed_time.tzinfo is not None + assert int(parsed_time.timestamp()) == epoch_seconds diff --git a/roles/importer/files/importer/test/test_fortiadom_domain_info.py b/roles/importer/files/importer/test/test_fortiadom_domain_info.py new file mode 100644 index 0000000000..e26cd16820 --- /dev/null +++ b/roles/importer/files/importer/test/test_fortiadom_domain_info.py @@ -0,0 +1,13 @@ +import pytest +from fw_modules.fortiadom5ff import fmgr_getter +from fwo_exceptions import FwoImporterError + + +@pytest.mark.parametrize("domain_name", [None, ""]) +def test_require_domain_name_raises_when_missing(domain_name: str | None): + with pytest.raises(FwoImporterError): + fmgr_getter.require_domain_name(domain_name, "unit-test") + + +def test_require_domain_name_returns_value(): + assert fmgr_getter.require_domain_name("root", "unit-test") == "root" diff --git a/roles/importer/files/importer/test/test_fos_fwcommon_device_name.py b/roles/importer/files/importer/test/test_fos_fwcommon_device_name.py new file mode 100644 index 0000000000..b09ef0c4a5 --- /dev/null +++ b/roles/importer/files/importer/test/test_fos_fwcommon_device_name.py @@ -0,0 +1,28 @@ +from fw_modules.fortiosmanagementREST import fwcommon +from model_controllers.import_state_controller import ImportStateController + + +class TestEnsureDeviceName: + def test_ensure_device_name_uses_gateway_uid( + self, + import_state_controller: ImportStateController, + ): + import_state = import_state_controller + import_state.state.gateway_map = {import_state.state.mgm_details.current_mgm_id: {"gw-uid": 1}} + import_state.state.mgm_details.devices = [] + + fwcommon.ensure_device_name(import_state) + + assert import_state.state.mgm_details.devices[0]["name"] == "gw-uid" + + def test_ensure_device_name_overrides_non_matching_device( + self, + import_state_controller: ImportStateController, + ): + import_state = import_state_controller + import_state.state.gateway_map = {import_state.state.mgm_details.current_mgm_id: {"gw-uid": 1}} + import_state.state.mgm_details.devices = [{"name": "fortigate_demo"}] + + fwcommon.ensure_device_name(import_state) + + assert import_state.state.mgm_details.devices[0]["name"] == "gw-uid" diff --git a/roles/importer/files/importer/test/test_fos_fwcommon_manager_set.py b/roles/importer/files/importer/test/test_fos_fwcommon_manager_set.py new file mode 100644 index 0000000000..a9cf65b491 --- /dev/null +++ b/roles/importer/files/importer/test/test_fos_fwcommon_manager_set.py @@ -0,0 +1,14 @@ +from fw_modules.fortiosmanagementREST import fwcommon +from model_controllers.fwconfigmanagerlist_controller import FwConfigManagerListController +from model_controllers.import_state_controller import ImportStateController + + +class TestEnsureManagerSet: + def test_ensure_manager_set_adds_manager(self, import_state_controller: ImportStateController): + import_state = import_state_controller + config_in = FwConfigManagerListController() + + fwcommon.ensure_manager_set(config_in, import_state) + + assert len(config_in.ManagerSet) == 1 + assert config_in.ManagerSet[0].manager_uid == import_state.state.mgm_details.uid diff --git a/roles/importer/files/importer/test/test_fos_models_rules.py b/roles/importer/files/importer/test/test_fos_models_rules.py new file mode 100644 index 0000000000..7387978d82 --- /dev/null +++ b/roles/importer/files/importer/test/test_fos_models_rules.py @@ -0,0 +1,27 @@ +from fw_modules.fortiosmanagementREST.fos_models import FortiOSConfig + + +def test_rules_dict_coerces_to_list(): + config = FortiOSConfig.model_validate( + { + "rules": [ + { + "policyid": 1, + "name": "rule1", + "action": "accept", + "srcintf": [{"name": "port1", "q_origin_key": "port1"}], + "dstintf": [{"name": "port2", "q_origin_key": "port2"}], + "srcaddr": [{"name": "all", "q_origin_key": "all"}], + "dstaddr": [{"name": "all", "q_origin_key": "all"}], + "service": [{"name": "ALL", "q_origin_key": "ALL"}], + "schedule": "always", + "status": "enable", + "logtraffic": "all", + "q_origin_key": 1, + "uuid": "uuid-rule1", + } + ] + } + ) + + assert len(config.rules) == 1 diff --git a/roles/importer/files/importer/test/test_fos_models_subnet.py b/roles/importer/files/importer/test/test_fos_models_subnet.py new file mode 100644 index 0000000000..fe7c90e57f --- /dev/null +++ b/roles/importer/files/importer/test/test_fos_models_subnet.py @@ -0,0 +1,15 @@ +from fw_modules.fortiosmanagementREST.fos_models import NwObjAddress + + +def test_subnet_list_coerces_to_string(): + obj = NwObjAddress.model_validate( + { + "name": "net1", + "q_origin_key": "net1", + "uuid": "uuid1", + "type": "ipmask", + "subnet": "1.2.3.4/32", + } + ) + + assert obj.subnet == "1.2.3.4/32" diff --git a/roles/importer/files/importer/test/test_fos_normalizer_gateway_fallback.py b/roles/importer/files/importer/test/test_fos_normalizer_gateway_fallback.py new file mode 100644 index 0000000000..60c94609d0 --- /dev/null +++ b/roles/importer/files/importer/test/test_fos_normalizer_gateway_fallback.py @@ -0,0 +1,17 @@ +from fw_modules.fortiosmanagementREST.fos_models import FortiOSConfig +from fw_modules.fortiosmanagementREST.fos_normalizer import normalize_config +from model_controllers.import_state_controller import ImportStateController + + +class TestFosNormalizerGatewayFallback: + def test_normalize_config_uses_management_name_when_devices_missing( + self, + import_state_controller: ImportStateController, + ): + mgm_details = import_state_controller.state.mgm_details + mgm_details.name = "unit-test-gateway" + mgm_details.devices = [] + + normalized = normalize_config(FortiOSConfig(), mgm_details) + + assert normalized.gateways[0].Name == mgm_details.name diff --git a/roles/importer/files/importer/test/test_fwconfig_import_clear_management.py b/roles/importer/files/importer/test/test_fwconfig_import_clear_management.py new file mode 100644 index 0000000000..9e6b4a0240 --- /dev/null +++ b/roles/importer/files/importer/test/test_fwconfig_import_clear_management.py @@ -0,0 +1,18 @@ +from fwo_base import init_service_provider +from model_controllers.fwconfig_import import FwConfigImport +from model_controllers.import_state_controller import ImportStateController + + +class TestFwconfigImportClearManagement: + def test_clear_management_uses_management_uid( + self, + import_state_controller: ImportStateController, + ): + service_provider = init_service_provider() + import_state = import_state_controller + service_provider.get_global_state().import_state = import_state + + importer = FwConfigImport() + config = importer.clear_management() + + assert config.ManagerSet[0].manager_uid == import_state.state.mgm_details.uid diff --git a/roles/importer/files/importer/test/test_fwconfig_import_consistency.py b/roles/importer/files/importer/test/test_fwconfig_import_consistency.py new file mode 100644 index 0000000000..7b3510315a --- /dev/null +++ b/roles/importer/files/importer/test/test_fwconfig_import_consistency.py @@ -0,0 +1,1003 @@ +from model_controllers.check_consistency import FwConfigImportCheckConsistency +from model_controllers.fwconfigmanagerlist_controller import FwConfigManagerListController +from model_controllers.import_state_controller import ImportStateController +from models.networkobject import NetworkObject +from netaddr import IPNetwork +from test.data.mock_objects import MockObjectsFactory +from test.utils.config_builder import FwConfigBuilder + + +class TestCheckConsistencyColors: + def test_check_network_object_color_consistency_valid( + self, + import_state_controller: ImportStateController, + fwconfig_builder: FwConfigBuilder, + ): + config, _ = fwconfig_builder.build_config( + network_object_count=10, + service_object_count=10, + rulebase_count=3, + rules_per_rulebase_count=10, + ) + + config.network_objects["NetworkObject1"] = NetworkObject( + obj_uid="NetworkObject1", + obj_name="NetworkObject1", + obj_ip=IPNetwork("192.168.1.1/32"), + obj_ip_end=IPNetwork("192.168.1.1/32"), + obj_typ="network", + obj_color="red", + ) + + consistency_checker = FwConfigImportCheckConsistency( + import_state=import_state_controller.state, + ) + + consistency_checker.check_color_consistency(config=config, fix=False) + + assert len(consistency_checker.issues) == 0 + + def test_check__network_object_color_consistency_invalid_no_fix( + self, + import_state_controller: ImportStateController, + fwconfig_builder: FwConfigBuilder, + ): + config, _ = fwconfig_builder.build_config( + network_object_count=10, + service_object_count=10, + rulebase_count=3, + rules_per_rulebase_count=10, + ) + + nw_obj = fwconfig_builder.add_standard_network_host_object(config) + nw_obj.obj_color = "nonexistent_color" + + consistency_checker = FwConfigImportCheckConsistency( + import_state=import_state_controller.state, + ) + + consistency_checker.check_color_consistency(config=config, fix=False) + + assert len(consistency_checker.issues) == 1 + assert consistency_checker.issues == { + "unresolvableColorRefs": {"nwObjColors": ["nonexistent_color"], "svcColors": [], "userColors": []} + } + + def test_check_network_object_color_consistency_invalid_with_fix( + self, + import_state_controller: ImportStateController, + fwconfig_builder: FwConfigBuilder, + ): + config, _ = fwconfig_builder.build_config( + network_object_count=10, + service_object_count=10, + rulebase_count=3, + rules_per_rulebase_count=10, + ) + + nw_obj = fwconfig_builder.add_standard_network_host_object(config) + nw_obj.obj_color = "nonexistent_color" + + consistency_checker = FwConfigImportCheckConsistency( + import_state=import_state_controller.state, + ) + + consistency_checker.check_color_consistency(config=config, fix=True) + configured_color = config.network_objects[nw_obj.obj_uid].obj_color + + assert len(consistency_checker.issues) == 0 + assert configured_color == "black" # default color assigned when fix=True + + def test_check_service_object_color_consistency_valid( + self, + import_state_controller: ImportStateController, + fwconfig_builder: FwConfigBuilder, + ): + config, _ = fwconfig_builder.build_config( + network_object_count=10, + service_object_count=10, + rulebase_count=3, + rules_per_rulebase_count=10, + ) + + nw_obj = fwconfig_builder.add_standard_network_host_object(config) + nw_obj.obj_color = "red" + + consistency_checker = FwConfigImportCheckConsistency( + import_state=import_state_controller.state, + ) + + consistency_checker.check_color_consistency(config=config, fix=False) + + assert len(consistency_checker.issues) == 0 + + def test_check__service_object_color_consistency_invalid_no_fix( + self, + import_state_controller: ImportStateController, + fwconfig_builder: FwConfigBuilder, + ): + config, _ = fwconfig_builder.build_config( + network_object_count=10, + service_object_count=10, + rulebase_count=3, + rules_per_rulebase_count=10, + ) + + svc_obj = fwconfig_builder.add_standard_service_object(config) + svc_obj.svc_color = "nonexistent_color" + + consistency_checker = FwConfigImportCheckConsistency( + import_state=import_state_controller.state, + ) + + consistency_checker.check_color_consistency(config=config, fix=False) + + assert len(consistency_checker.issues) == 1 + assert consistency_checker.issues == { + "unresolvableColorRefs": {"nwObjColors": [], "svcColors": ["nonexistent_color"], "userColors": []} + } + + def test_check_service_object_color_consistency_invalid_with_fix( + self, + import_state_controller: ImportStateController, + fwconfig_builder: FwConfigBuilder, + ): + config, _ = fwconfig_builder.build_config( + network_object_count=10, + service_object_count=10, + rulebase_count=3, + rules_per_rulebase_count=10, + ) + + svc_obj = fwconfig_builder.add_standard_service_object(config) + svc_obj.svc_color = "nonexistent_color" + + consistency_checker = FwConfigImportCheckConsistency( + import_state=import_state_controller.state, + ) + + consistency_checker.check_color_consistency(config=config, fix=True) + configured_color = config.service_objects[svc_obj.svc_uid].svc_color + + assert len(consistency_checker.issues) == 0 + assert configured_color == "black" # default color assigned when fix=True + + +class TestCheckConsistencyNetworkObjects: + def test_check_network_object_consistency_valid( + self, + fwconfig_builder: FwConfigBuilder, + import_state_controller: ImportStateController, + ): + config, _ = fwconfig_builder.build_config( + network_object_count=10, + service_object_count=10, + rulebase_count=3, + rules_per_rulebase_count=10, + ) + + consistency_checker = FwConfigImportCheckConsistency( + import_state=import_state_controller.state, + ) + + consistency_checker.check_color_consistency(config=config, fix=False) + + assert len(consistency_checker.issues) == 0 + + def test_check_network_object_consistency_invalid( + self, + fwconfig_builder: FwConfigBuilder, + import_state_controller: ImportStateController, + ): + config, _ = fwconfig_builder.build_config( + network_object_count=10, + service_object_count=10, + rulebase_count=3, + rules_per_rulebase_count=10, + ) + # Introduce an inconsistency by referencing a non-existent network object + + nw_obj = fwconfig_builder.add_standard_network_host_object(config) + nw_obj.obj_typ = "DoesNotExist" + + manager_controller = FwConfigManagerListController() + manager = MockObjectsFactory.get_standard_fwconfig_manager(config) + manager_controller.add_manager(manager) + + consistency_checker = FwConfigImportCheckConsistency( + import_state=import_state_controller.state, + ) + + consistency_checker.check_network_object_consistency( + config=config, global_config=None, fix_unresolvable_refs=False + ) + + assert len(consistency_checker.issues) == 1 + assert consistency_checker.issues == {"unresolvableNwObjTypes": ["DoesNotExist"]} + + def test_check_network_object_consistency_with_single_host_in_group( + self, + import_state_controller: ImportStateController, + fwconfig_builder: FwConfigBuilder, + ): + config, _ = fwconfig_builder.build_config( + network_object_count=10, + service_object_count=10, + rulebase_count=3, + rules_per_rulebase_count=10, + ) + + nw_obj = fwconfig_builder.add_standard_network_host_object(config) + fwconfig_builder.add_standard_network_group_object(config, [nw_obj]) + + consistency_checker = FwConfigImportCheckConsistency( + import_state=import_state_controller.state, + ) + + consistency_checker.check_network_object_consistency( + config=config, global_config=None, fix_unresolvable_refs=False + ) + + assert len(consistency_checker.issues) == 0 + + def test_check_network_object_consistency_with_multiple_hosts_in_group( + self, + import_state_controller: ImportStateController, + fwconfig_builder: FwConfigBuilder, + ): + config, _ = fwconfig_builder.build_config( + network_object_count=10, + service_object_count=10, + rulebase_count=3, + rules_per_rulebase_count=10, + ) + + nw_obj1 = fwconfig_builder.add_standard_network_host_object(config) + nw_obj2 = fwconfig_builder.add_standard_network_host_object(config) + fwconfig_builder.add_standard_network_group_object(config, obj_members=[nw_obj1, nw_obj2]) + consistency_checker = FwConfigImportCheckConsistency( + import_state=import_state_controller.state, + ) + + consistency_checker.check_network_object_consistency( + config=config, global_config=None, fix_unresolvable_refs=False + ) + + assert len(consistency_checker.issues) == 0 + + def test_check_network_object_consistency_with_group_referencing_itself( + self, + import_state_controller: ImportStateController, + fwconfig_builder: FwConfigBuilder, + ): + config, _ = fwconfig_builder.build_config( + network_object_count=10, + service_object_count=10, + rulebase_count=3, + rules_per_rulebase_count=10, + ) + + nw_group_obj = fwconfig_builder.add_standard_network_group_object(config, obj_members=[]) + nw_group_obj.obj_member_refs = nw_group_obj.obj_uid # Circular reference + + consistency_checker = FwConfigImportCheckConsistency( + import_state=import_state_controller.state, + ) + + consistency_checker.check_network_object_consistency( + config=config, global_config=None, fix_unresolvable_refs=False + ) + + assert len(consistency_checker.issues) == 1 + assert consistency_checker.issues == {"circularNwObjRefs": [nw_group_obj.obj_uid]} + + def test_check_network_object_consistency_with_two_groups_circular_reference( + self, + import_state_controller: ImportStateController, + fwconfig_builder: FwConfigBuilder, + ): + config, _ = fwconfig_builder.build_config( + network_object_count=10, + service_object_count=10, + rulebase_count=3, + rules_per_rulebase_count=10, + ) + + group_a = fwconfig_builder.add_standard_network_group_object(config, obj_members=[]) + group_b = fwconfig_builder.add_standard_network_group_object(config, obj_members=[]) + + group_a.obj_member_refs = group_b.obj_uid + group_b.obj_member_refs = group_a.obj_uid + + consistency_checker = FwConfigImportCheckConsistency( + import_state=import_state_controller.state, + ) + + consistency_checker.check_network_object_consistency( + config=config, global_config=None, fix_unresolvable_refs=False + ) + + assert len(consistency_checker.issues) == 1 + assert set(consistency_checker.issues["circularNwObjRefs"]) == {group_a.obj_uid, group_b.obj_uid} + + def test_check_network_object_consistency_with_empty_group( + self, + import_state_controller: ImportStateController, + fwconfig_builder: FwConfigBuilder, + ): + config, _ = fwconfig_builder.build_config( + network_object_count=10, + service_object_count=10, + rulebase_count=3, + rules_per_rulebase_count=10, + ) + + fwconfig_builder.add_standard_network_group_object(config, obj_members=[]) + + consistency_checker = FwConfigImportCheckConsistency( + import_state=import_state_controller.state, + ) + + consistency_checker.check_network_object_consistency( + config=config, global_config=None, fix_unresolvable_refs=False + ) + + assert len(consistency_checker.issues) == 0 + + def test_check_network_object_consistency_with_group_referencing_nonexistent_object( + self, + import_state_controller: ImportStateController, + fwconfig_builder: FwConfigBuilder, + ): + config, _ = fwconfig_builder.build_config( + network_object_count=10, + service_object_count=10, + rulebase_count=3, + rules_per_rulebase_count=10, + ) + + nw_group_obj = fwconfig_builder.add_standard_network_group_object(config, obj_members=[]) + nw_group_obj.obj_member_refs = "NonExistentHost" + + manager_controller = FwConfigManagerListController() + manager = MockObjectsFactory.get_standard_fwconfig_manager(config) + manager_controller.add_manager(manager) + consistency_checker = FwConfigImportCheckConsistency( + import_state=import_state_controller.state, + ) + + consistency_checker.check_network_object_consistency( + config=config, global_config=None, fix_unresolvable_refs=False + ) + assert len(consistency_checker.issues) == 1 + assert consistency_checker.issues == {"unresolvableNwObjRefs": ["NonExistentHost"]} + + def test_check_network_object_consistency_with_mixed_valid_and_invalid_references( + self, + import_state_controller: ImportStateController, + fwconfig_builder: FwConfigBuilder, + ): + config, _ = fwconfig_builder.build_config( + network_object_count=10, + service_object_count=10, + rulebase_count=3, + rules_per_rulebase_count=10, + ) + + valid_nw_obj = fwconfig_builder.add_standard_network_host_object(config) + group_obj = fwconfig_builder.add_standard_network_group_object(config, obj_members=[valid_nw_obj]) + group_obj.obj_member_refs += "|InvalidHost" # pyright: ignore[reportOperatorIssue] + + consistency_checker = FwConfigImportCheckConsistency( + import_state=import_state_controller.state, + ) + consistency_checker.check_network_object_consistency( + config=config, global_config=None, fix_unresolvable_refs=False + ) + assert len(consistency_checker.issues) == 1 + assert consistency_checker.issues == {"unresolvableNwObjRefs": ["InvalidHost"]} + + def test_check_network_object_consistency_none_group_without_ip( + self, + import_state_controller: ImportStateController, + fwconfig_builder: FwConfigBuilder, + ): + config, _ = fwconfig_builder.build_config( + network_object_count=10, + service_object_count=10, + rulebase_count=3, + rules_per_rulebase_count=10, + ) + + nw_obj = fwconfig_builder.add_standard_network_host_object(config) + nw_obj.obj_ip = None + nw_obj.obj_ip_end = None + + consistency_checker = FwConfigImportCheckConsistency( + import_state=import_state_controller.state, + ) + consistency_checker.check_network_object_consistency( + config=config, global_config=None, fix_unresolvable_refs=False + ) + assert len(consistency_checker.issues) == 1 + assert consistency_checker.issues == {"non-group network object with undefined IP addresse(s)": [nw_obj]} + + +class TestCheckConsistencyServiceObjects: + def test_check_service_object_consistency_valid( + self, + fwconfig_builder: FwConfigBuilder, + import_state_controller: ImportStateController, + ): + config, _ = fwconfig_builder.build_config( + network_object_count=10, + service_object_count=10, + rulebase_count=3, + rules_per_rulebase_count=10, + ) + + svc_obj = fwconfig_builder.add_standard_service_object(config) + fwconfig_builder.add_standard_service_group_object(config, [svc_obj]) + + consistency_checker = FwConfigImportCheckConsistency( + import_state=import_state_controller.state, + ) + + consistency_checker.check_service_object_consistency( + config=config, global_config=None, fix_inconsistencies=False + ) + + assert len(consistency_checker.issues) == 0 + + def test_check_service_object_consistency_unresolvable_object( + self, + fwconfig_builder: FwConfigBuilder, + import_state_controller: ImportStateController, + ): + config, _ = fwconfig_builder.build_config( + network_object_count=10, + service_object_count=10, + rulebase_count=3, + rules_per_rulebase_count=10, + ) + + svc_group_obj = fwconfig_builder.add_standard_service_group_object(config) + svc_group_obj.svc_member_refs = "NonExistentService" + + consistency_checker = FwConfigImportCheckConsistency( + import_state=import_state_controller.state, + ) + + consistency_checker.check_service_object_consistency( + config=config, global_config=None, fix_inconsistencies=False + ) + assert len(consistency_checker.issues) == 1 + assert consistency_checker.issues == {"unresolvableSvcObjRefs": ["NonExistentService"]} + + def test_check_service_object_consistency_invalid_type( + self, + fwconfig_builder: FwConfigBuilder, + import_state_controller: ImportStateController, + ): + config, _ = fwconfig_builder.build_config( + network_object_count=10, + service_object_count=10, + rulebase_count=3, + rules_per_rulebase_count=10, + ) + + svc_obj = fwconfig_builder.add_standard_service_object(config) + svc_obj.svc_typ = "DoesNotExist" + + consistency_checker = FwConfigImportCheckConsistency( + import_state=import_state_controller.state, + ) + + consistency_checker.check_service_object_consistency( + config=config, global_config=None, fix_inconsistencies=False + ) + assert len(consistency_checker.issues) == 1 + assert consistency_checker.issues == {"unresolvableSvcObjTypes": ["DoesNotExist"]} + + def test_check_service_object_consistency_with_multiple_members_in_group( + self, + import_state_controller: ImportStateController, + fwconfig_builder: FwConfigBuilder, + ): + config, _ = fwconfig_builder.build_config( + network_object_count=10, + service_object_count=10, + rulebase_count=3, + rules_per_rulebase_count=10, + ) + + fwconfig_builder.add_standard_service_object(config) + fwconfig_builder.add_standard_service_object(config) + + consistency_checker = FwConfigImportCheckConsistency( + import_state=import_state_controller.state, + ) + + consistency_checker.check_service_object_consistency( + config=config, global_config=None, fix_inconsistencies=False + ) + assert len(consistency_checker.issues) == 0 + + def test_check_service_object_consistency_with_group_referencing_itself( + self, + import_state_controller: ImportStateController, + fwconfig_builder: FwConfigBuilder, + ): + config, _ = fwconfig_builder.build_config( + network_object_count=10, + service_object_count=10, + rulebase_count=3, + rules_per_rulebase_count=10, + ) + + svc_group_obj = fwconfig_builder.add_standard_service_group_object(config) + svc_group_obj.svc_member_refs = svc_group_obj.svc_uid # Circular reference + + consistency_checker = FwConfigImportCheckConsistency( + import_state=import_state_controller.state, + ) + + consistency_checker.check_service_object_consistency( + config=config, global_config=None, fix_inconsistencies=False + ) + assert len(consistency_checker.issues) == 1 + assert consistency_checker.issues == {"circularSvcObjRefs": [svc_group_obj.svc_uid]} + + def test_check_service_object_consistency_with_two_groups_circular_reference( + self, + import_state_controller: ImportStateController, + fwconfig_builder: FwConfigBuilder, + ): + config, _ = fwconfig_builder.build_config( + network_object_count=10, + service_object_count=10, + rulebase_count=3, + rules_per_rulebase_count=10, + ) + + group_a = fwconfig_builder.add_standard_service_group_object(config) + group_b = fwconfig_builder.add_standard_service_group_object(config) + + group_a.svc_member_refs = group_b.svc_uid + group_b.svc_member_refs = group_a.svc_uid + + consistency_checker = FwConfigImportCheckConsistency( + import_state=import_state_controller.state, + ) + + consistency_checker.check_service_object_consistency( + config=config, global_config=None, fix_inconsistencies=False + ) + assert len(consistency_checker.issues) == 1 + assert set(consistency_checker.issues["circularSvcObjRefs"]) == {group_a.svc_uid, group_b.svc_uid} + + def test_check_service_object_consistency_with_empty_group( + self, + import_state_controller: ImportStateController, + fwconfig_builder: FwConfigBuilder, + ): + config, _ = fwconfig_builder.build_config( + network_object_count=10, + service_object_count=10, + rulebase_count=3, + rules_per_rulebase_count=10, + ) + + svc_group_obj = fwconfig_builder.add_standard_service_group_object(config) + svc_group_obj.svc_member_refs = "" + + consistency_checker = FwConfigImportCheckConsistency( + import_state=import_state_controller.state, + ) + + consistency_checker.check_service_object_consistency( + config=config, global_config=None, fix_inconsistencies=False + ) + assert len(consistency_checker.issues) == 0 + + def test_check_service_object_consistency_with_mixed_valid_and_invalid_references( + self, + import_state_controller: ImportStateController, + fwconfig_builder: FwConfigBuilder, + ): + config, _ = fwconfig_builder.build_config( + network_object_count=10, + service_object_count=10, + rulebase_count=3, + rules_per_rulebase_count=10, + ) + + svc_obj = fwconfig_builder.add_standard_service_object(config) + + svc_group_obj = fwconfig_builder.add_standard_service_group_object(config) + svc_group_obj.svc_member_refs = f"{svc_obj.svc_uid}|InvalidService" + + consistency_checker = FwConfigImportCheckConsistency( + import_state=import_state_controller.state, + ) + + consistency_checker.check_service_object_consistency( + config=config, global_config=None, fix_inconsistencies=False + ) + assert len(consistency_checker.issues) == 1 + assert consistency_checker.issues == {"unresolvableSvcObjRefs": ["InvalidService"]} + + +class TestCheckUserObjectConsistency: + def test_check_user_object_consistency_valid( + self, + fwconfig_builder: FwConfigBuilder, + import_state_controller: ImportStateController, + ): + config, _ = fwconfig_builder.build_config( + network_object_count=10, + service_object_count=10, + rulebase_count=3, + rules_per_rulebase_count=10, + user_object_count=1, + user_group_object_count=2, + user_group_object_member_count=2, + ) + + consistency_checker = FwConfigImportCheckConsistency( + import_state=import_state_controller.state, + ) + consistency_checker.check_service_object_consistency( + config=config, global_config=None, fix_inconsistencies=False + ) + assert len(consistency_checker.issues) == 0 + + def test_check_user_object_unresolvable_object( + self, + fwconfig_builder: FwConfigBuilder, + import_state_controller: ImportStateController, + ): + config, _ = fwconfig_builder.build_config( + network_object_count=10, + service_object_count=10, + rulebase_count=3, + rules_per_rulebase_count=10, + user_object_count=1, + user_group_object_count=2, + user_group_object_member_count=2, + ) + + # Add a user object that is not referenced anywhere + group = { + "user_typ": "group", + "user_uid": "GroupWithInvalidMember", + "user_name": "GroupWithInvalidMember", + "user_member_names": "DoesNotExist", + "user_member_refs": "DoesNotExist", + } + + config.users["GroupWithInvalidMember"] = group + + consistency_checker = FwConfigImportCheckConsistency( + import_state=import_state_controller.state, + ) + + consistency_checker.check_user_object_consistency( + config=config, global_config=None, fix_unresolvable_refs=False + ) + assert len(consistency_checker.issues) == 1 + assert consistency_checker.issues == {"unresolvableUserObjRefs": ["DoesNotExist"]} + + def test_check_user_object_circular_reference( + self, + fwconfig_builder: FwConfigBuilder, + import_state_controller: ImportStateController, + ): + config, _ = fwconfig_builder.build_config( + network_object_count=10, + service_object_count=10, + rulebase_count=3, + rules_per_rulebase_count=10, + user_object_count=1, + user_group_object_count=2, + user_group_object_member_count=2, + ) + + group = { + "user_typ": "group", + "user_uid": "GroupWithCircularRef", + "user_name": "GroupWithCircularRef", + "user_member_names": "GroupWithCircularRef", + "user_member_refs": "GroupWithCircularRef", + } + + config.users["GroupWithCircularRef"] = group + + consistency_checker = FwConfigImportCheckConsistency( + import_state=import_state_controller.state, + ) + + consistency_checker.check_user_object_consistency( + config=config, global_config=None, fix_unresolvable_refs=False + ) + assert len(consistency_checker.issues) == 1 + assert consistency_checker.issues == {"circularUserObjRefs": ["GroupWithCircularRef"]} + + def test_check_user_object_with_two_groups_circular_reference( + self, + fwconfig_builder: FwConfigBuilder, + import_state_controller: ImportStateController, + ): + config, _ = fwconfig_builder.build_config( + network_object_count=10, + service_object_count=10, + rulebase_count=3, + rules_per_rulebase_count=10, + user_object_count=1, + user_group_object_count=2, + user_group_object_member_count=2, + ) + + group_a = { + "user_typ": "group", + "user_uid": "GroupA", + "user_name": "GroupA", + "user_member_names": "GroupB", + "user_member_refs": "GroupB", + } + + group_b = { + "user_typ": "group", + "user_uid": "GroupB", + "user_name": "GroupB", + "user_member_names": "GroupA", + "user_member_refs": "GroupA", + } + + config.users["GroupA"] = group_a + config.users["GroupB"] = group_b + + consistency_checker = FwConfigImportCheckConsistency( + import_state=import_state_controller.state, + ) + + consistency_checker.check_user_object_consistency( + config=config, global_config=None, fix_unresolvable_refs=False + ) + assert len(consistency_checker.issues) == 1 + assert set(consistency_checker.issues["circularUserObjRefs"]) == {"GroupA", "GroupB"} + + +class TestRulebaseConsistency: + def test_check_rulebase_consistency_valid( + self, + fwconfig_builder: FwConfigBuilder, + import_state_controller: ImportStateController, + ): + config, _ = fwconfig_builder.build_config( + network_object_count=10, + service_object_count=10, + rulebase_count=3, + rules_per_rulebase_count=10, + ) + + consistency_checker = FwConfigImportCheckConsistency( + import_state=import_state_controller.state, + ) + + consistency_checker.check_service_object_consistency( + config=config, global_config=None, fix_inconsistencies=False + ) + assert len(consistency_checker.issues) == 0 + + def test_check_rulebase_consistency_with_empty_config( + self, + fwconfig_builder: FwConfigBuilder, + import_state_controller: ImportStateController, + ): + empty_config = fwconfig_builder.build_empty_config() + consistency_checker = FwConfigImportCheckConsistency( + import_state=import_state_controller.state, + ) + + consistency_checker.check_rulebase_consistency(config=empty_config, fix_inconsistencies=False) + + assert len(consistency_checker.issues) == 0 + + def test_check_rulebase_consistency_with_unresolvable_tracks( + self, + fwconfig_builder: FwConfigBuilder, + import_state_controller: ImportStateController, + ): + config, _ = fwconfig_builder.build_config( + network_object_count=10, + service_object_count=10, + rulebase_count=3, + rules_per_rulebase_count=10, + ) + + rule_uid = next(iter(config.rulebases[0].rules.keys())) + config.rulebases[0].rules[rule_uid].rule_track = "NonExistent" # pyright: ignore[reportAttributeAccessIssue] + + consistency_checker = FwConfigImportCheckConsistency( + import_state=import_state_controller.state, + ) + + consistency_checker.check_rulebase_consistency(config=config, fix_inconsistencies=False) + + assert len(consistency_checker.issues) == 1 + assert consistency_checker.issues == {"unresolvableRuleTracks": ["NonExistent"]} + + def test_check_rulebase_consistency_with_unresolvable_actions( + self, + fwconfig_builder: FwConfigBuilder, + import_state_controller: ImportStateController, + ): + config, _ = fwconfig_builder.build_config( + network_object_count=10, + service_object_count=10, + rulebase_count=3, + rules_per_rulebase_count=10, + ) + + rule_uid = next(iter(config.rulebases[0].rules.keys())) + config.rulebases[0].rules[rule_uid].rule_action = "NonExistent" # pyright: ignore[reportAttributeAccessIssue] + + consistency_checker = FwConfigImportCheckConsistency( + import_state=import_state_controller.state, + ) + + consistency_checker.check_rulebase_consistency(config=config, fix_inconsistencies=False) + + assert len(consistency_checker.issues) == 1 + assert consistency_checker.issues == {"unresolvableRuleActions": ["NonExistent"]} + + +class TestRulebaseLinkConsistency: + def test_check_rulebase_link_consistency_valid( + self, + fwconfig_builder: FwConfigBuilder, + import_state_controller: ImportStateController, + ): + config, _ = fwconfig_builder.build_config( + network_object_count=10, + service_object_count=10, + rulebase_count=3, + rules_per_rulebase_count=10, + ) + + consistency_checker = FwConfigImportCheckConsistency( + import_state=import_state_controller.state, + ) + + consistency_checker.check_rulebase_link_consistency( + config=config, global_config=None, fix_inconsistencies=False + ) + + assert len(consistency_checker.issues) == 0 + + def test_check_rulebase_link_consistency_with_broken_links( + self, + fwconfig_builder: FwConfigBuilder, + import_state_controller: ImportStateController, + ): + config, _ = fwconfig_builder.build_config( + network_object_count=10, + service_object_count=10, + rulebase_count=3, + rules_per_rulebase_count=10, + ) + config.gateways[0].RulebaseLinks[0].from_rule_uid = "NonExistentRuleUid" + config.gateways[0].RulebaseLinks[0].from_rulebase_uid = "NonExistentFromRulebaseUID" + config.gateways[0].RulebaseLinks[0].to_rulebase_uid = "NonExistentToRulebaseUID" + + consistency_checker = FwConfigImportCheckConsistency( + import_state=import_state_controller.state, + ) + + consistency_checker.check_rulebase_link_consistency( + config=config, global_config=None, fix_inconsistencies=False + ) + + assert len(consistency_checker.issues) == 2 + assert len(consistency_checker.issues["unresolvableRulebaseLinksRulebases"]) == 2 + assert len(consistency_checker.issues["unresolvableRulebaseLinksRules"]) == 1 + + +class TestZoneObjectConsistency: + def test_check_zone_object_consistency_valid( + self, + fwconfig_builder: FwConfigBuilder, + import_state_controller: ImportStateController, + ): + config, _ = fwconfig_builder.build_config( + network_object_count=10, + service_object_count=10, + rulebase_count=3, + rules_per_rulebase_count=10, + ) + + consistency_checker = FwConfigImportCheckConsistency( + import_state=import_state_controller.state, + ) + consistency_checker.check_zone_object_consistency( + config=config, global_config=None, fix_unresolvable_refs=False + ) + assert len(consistency_checker.issues) == 0 + + def test_check_zone_object_consistency_with_unresolvable_object_src( + self, + import_state_controller: ImportStateController, + fwconfig_builder: FwConfigBuilder, + ): + config, _ = fwconfig_builder.build_config( + network_object_count=10, + service_object_count=10, + rulebase_count=3, + rules_per_rulebase_count=10, + ) + + rule_uid = next(iter(config.rulebases[0].rules.keys())) + config.rulebases[0].rules[rule_uid].rule_src_zone = "NonExistent" # pyright: ignore[reportAttributeAccessIssue] + + consistency_checker = FwConfigImportCheckConsistency( + import_state=import_state_controller.state, + ) + consistency_checker.check_zone_object_consistency( + config=config, global_config=None, fix_unresolvable_refs=False + ) + + assert len(consistency_checker.issues) == 1 + assert consistency_checker.issues == {"unresolvableZoneObjRefs": ["NonExistent"]} + + def test_check_zone_object_consistency_with_unresolvable_object_dst( + self, + import_state_controller: ImportStateController, + fwconfig_builder: FwConfigBuilder, + ): + config, _ = fwconfig_builder.build_config( + network_object_count=10, + service_object_count=10, + rulebase_count=3, + rules_per_rulebase_count=10, + ) + + rule_uid = next(iter(config.rulebases[0].rules.keys())) + config.rulebases[0].rules[rule_uid].rule_dst_zone = "NonExistent" # pyright: ignore[reportAttributeAccessIssue] + + consistency_checker = FwConfigImportCheckConsistency( + import_state=import_state_controller.state, + ) + consistency_checker.check_zone_object_consistency( + config=config, global_config=None, fix_unresolvable_refs=False + ) + + assert len(consistency_checker.issues) == 1 + assert consistency_checker.issues == {"unresolvableZoneObjRefs": ["NonExistent"]} + + +class TestFullConfigConsistencyCheck: + def test_full_config_consistency_check( + self, + fwconfig_builder: FwConfigBuilder, + import_state_controller: ImportStateController, + ): + config, _ = fwconfig_builder.build_config( + network_object_count=10, + service_object_count=10, + rulebase_count=3, + rules_per_rulebase_count=10, + user_group_object_count=2, + user_group_object_member_count=2, + user_object_count=5, + ) + + consistency_checker = FwConfigImportCheckConsistency( + import_state=import_state_controller.state, + ) + + consistency_checker.check_zone_object_consistency( + config=config, global_config=None, fix_unresolvable_refs=False + ) + + assert len(consistency_checker.issues) == 0 diff --git a/roles/importer/files/importer/test/test_fwconfig_import_gateway_clear.py b/roles/importer/files/importer/test/test_fwconfig_import_gateway_clear.py new file mode 100644 index 0000000000..b8563e5764 --- /dev/null +++ b/roles/importer/files/importer/test/test_fwconfig_import_gateway_clear.py @@ -0,0 +1,75 @@ +import unittest.mock + +import pytest +from model_controllers.fwconfig_import_gateway import FwConfigImportGateway +from model_controllers.import_state_controller import ImportStateController +from model_controllers.rulebase_link_controller import RulebaseLinkController +from models.fwconfig_normalized import FwConfigNormalized +from models.gateway import Gateway +from models.rulebase_link import RulebaseLink +from services.global_state import GlobalState + + +@pytest.fixture +def rulebase_link_controller() -> RulebaseLinkController: + rulebase_link_controller = RulebaseLinkController() + rulebase_link_controller.rb_links = [] + + def get_rulebase_links(): + rulebase_link_controller.rb_links = [ + RulebaseLink( + id=1, + gw_id=1, + from_rule_id=None, + from_rulebase_id=None, + to_rulebase_id=2, + link_type=1, + is_initial=True, + is_global=False, + is_section=True, + created=1, + ) + ] + + rulebase_link_controller.get_rulebase_links = unittest.mock.Mock( + side_effect=get_rulebase_links, + ) + + return rulebase_link_controller + + +@pytest.fixture +def fwconfig_import_gateway( + rulebase_link_controller: RulebaseLinkController, +) -> FwConfigImportGateway: + import_gateway = FwConfigImportGateway() + import_gateway._rb_link_controller = unittest.mock.MagicMock() # pyright: ignore[reportPrivateUsage] + import_gateway.get_rb_link_controller = unittest.mock.MagicMock( + return_value=rulebase_link_controller, # pyright: ignore[reportPrivateUsage] + ) + + return import_gateway + + +class TestFwconfigImportGatewayClear: + def test_update_gateway_diffs_removes_links_on_clear( + self, + import_state_controller: ImportStateController, + global_state: GlobalState, + rulebase_link_controller: RulebaseLinkController, + ): + import_state = import_state_controller + import_state.state.is_clearing_import = True + + global_state.import_state = import_state + global_state.normalized_config = FwConfigNormalized(gateways=[]) + global_state.previous_config = FwConfigNormalized(gateways=[Gateway(Uid="gw-1")]) + insert_called = False + + gateway_importer = FwConfigImportGateway() + gateway_importer._rb_link_controller = unittest.mock.MagicMock() # pyright: ignore[reportPrivateUsage] + + gateway_importer.update_gateway_diffs() + + assert rulebase_link_controller.rb_links == [] + assert insert_called is False diff --git a/roles/importer/files/importer/test/test_fwconfig_import_object.py b/roles/importer/files/importer/test/test_fwconfig_import_object.py new file mode 100644 index 0000000000..e0ed1a65f5 --- /dev/null +++ b/roles/importer/files/importer/test/test_fwconfig_import_object.py @@ -0,0 +1,2369 @@ +import copy +from typing import Any + +import pytest +from fwo_api_call import FwoApiCall +from fwo_const import LIST_DELIMITER +from fwo_exceptions import FwoDuplicateKeyViolationError, FwoImporterError +from fwo_log import ChangeLogger, FWOLogger +from model_controllers.fwconfig_import_object import FwConfigImportObject, Type +from model_controllers.import_state_controller import ImportStateController +from models.fwconfig_normalized import FwConfigNormalized +from models.fwconfigmanager import FwConfigManager +from models.networkobject import NetworkObjectForImport +from models.serviceobject import ServiceObjectForImport +from pytest_mock import MockerFixture +from services.uid2id_mapper import Uid2IdMapper +from test.data.mock_objects import MockObjectsFactory +from test.utils.config_builder import FwConfigBuilder +from test.utils.test_utils import mock_get_graphql_code + + +class TestFwConfigImportObjectAddChangelogObjs: + def test_add_changelog_objects( + self, fwconfig_import_object: FwConfigImportObject, api_call: FwoApiCall, mocker: MockerFixture + ): + # Arrange + api_call.call = mocker.Mock( + return_value=MockObjectsFactory.get_standard_changelog_return_value(), + ) + + # Act + fwconfig_import_object.add_changelog_objs( + nwobj_ids_added=[{"obj_id": 1}], + nw_obj_ids_removed=[{"obj_id": 2}], + svc_obj_ids_added=[{"svc_id": 3}], + svc_obj_ids_removed=[{"svc_id": 4}], + ) + + # Assert + api_call.call.assert_any_call( + mocker.ANY, + query_variables={ + "nwObjChanges": MockObjectsFactory.get_changelog_object_insert_delete(), + "svcObjChanges": MockObjectsFactory.get_changelog_svc_objects_insert_delete(), + }, + analyze_payload=True, + ) + + def test_add_changelog_objects_with_errors( + self, fwconfig_import_object: FwConfigImportObject, api_call: FwoApiCall, mocker: MockerFixture + ): + # Arrange + mock_logger = mocker.patch("fwo_log.FWOLogger.exception") + api_call.call = mocker.Mock(return_value={"errors": [{"message": "Some error occurred"}]}) + + # Act + fwconfig_import_object.add_changelog_objs( + nwobj_ids_added=[{"obj_id": 1}], + nw_obj_ids_removed=[{"obj_id": 2}], + svc_obj_ids_added=[{"svc_id": 3}], + svc_obj_ids_removed=[{"svc_id": 4}], + ) + + # Assert + mock_logger.assert_called_once_with( + "error while adding changelog entries for objects: [{'message': 'Some error occurred'}]" + ) + + def test_add_changelog_objects_with_exception( + self, fwconfig_import_object: FwConfigImportObject, api_call: FwoApiCall, mocker: MockerFixture + ): + # Arrange + mock_logger = mocker.patch("fwo_log.FWOLogger.exception") + api_call.call = mocker.Mock(side_effect=Exception("API call failed")) + + # Act + fwconfig_import_object.add_changelog_objs( + nwobj_ids_added=[{"obj_id": 1}], + nw_obj_ids_removed=[{"obj_id": 2}], + svc_obj_ids_added=[{"svc_id": 3}], + svc_obj_ids_removed=[{"svc_id": 4}], + ) + + # Assert + assert mock_logger.call_count == 1 + assert str(mock_logger.call_args[0][0]).startswith( + "fatal error while adding changelog entries for objects: Traceback (most recent call last):" + ) + + +class TestFwConfigImportObjectPrepareChangelogObjects: + def test_prepare_changelog_objects( + self, + fwconfig_import_object: FwConfigImportObject, + ): + # Act + nwobjs_changed, svcobjs_changed = fwconfig_import_object.prepare_changelog_objects( + nw_obj_ids_added=[{"obj_id": 1}], + nw_obj_ids_removed=[{"obj_id": 2}], + svc_obj_ids_added=[{"svc_id": 3}], + svc_obj_ids_removed=[{"svc_id": 4}], + ) + + # Assert + assert nwobjs_changed == MockObjectsFactory.get_changelog_object_insert_delete() + assert svcobjs_changed == MockObjectsFactory.get_changelog_svc_objects_insert_delete() + + def test_prepare_changelog_objects_initial_import( + self, fwconfig_import_object: FwConfigImportObject, import_state_controller: ImportStateController + ): + # Arrange + import_state_controller.state.is_initial_import = True + + # Act + nwobjs_changed, svcobjs_changed = fwconfig_import_object.prepare_changelog_objects( + nw_obj_ids_added=[{"obj_id": 1}], + nw_obj_ids_removed=[{"obj_id": 2}], + svc_obj_ids_added=[{"svc_id": 3}], + svc_obj_ids_removed=[{"svc_id": 4}], + ) + + # Assert + + assert svcobjs_changed == MockObjectsFactory.get_changelog_svc_objects_insert_delete(2) + assert nwobjs_changed == MockObjectsFactory.get_changelog_object_insert_delete(2) + + def test_prepare_changelog_objects_clearing_import( + self, fwconfig_import_object: FwConfigImportObject, import_state_controller: ImportStateController + ): + # Arrange + import_state_controller.state.is_clearing_import = True + + # Act + nwobjs_changed, svcobjs_changed = fwconfig_import_object.prepare_changelog_objects( + nw_obj_ids_added=[{"obj_id": 1}], + nw_obj_ids_removed=[{"obj_id": 2}], + svc_obj_ids_added=[{"svc_id": 3}], + svc_obj_ids_removed=[{"svc_id": 4}], + ) + + # Assert + assert nwobjs_changed == MockObjectsFactory.get_changelog_object_insert_delete(2) + assert svcobjs_changed == MockObjectsFactory.get_changelog_svc_objects_insert_delete(2) + + def test_prepare_changelog_objects_with_logged_changes( + self, + fwconfig_import_object: FwConfigImportObject, + ): + # Arrange + change_logger = ChangeLogger() + change_logger.changed_object_id_map = {1: 10} + change_logger.changed_service_id_map = {3: 30} + + # Act + nwobjs_changed, svcobjs_changed = fwconfig_import_object.prepare_changelog_objects( + nw_obj_ids_added=[{"obj_id": 1}], + nw_obj_ids_removed=[{"obj_id": 2}], + svc_obj_ids_added=[{"svc_id": 3}], + svc_obj_ids_removed=[{"svc_id": 4}], + ) + + # Assert + assert nwobjs_changed == MockObjectsFactory.get_changelog_object_insert_delete_change() + assert svcobjs_changed == MockObjectsFactory.get_changelog_svc_objects_insert_delete_change() + + +class TestFwConfigImportObjectLookupProtoNameToId: + def test_lookup_proto_name_to_id_unknown_name( + self, + import_state_controller: ImportStateController, + ): + # Arrange + proto_name = "tcp" + + # Act and Assert + with pytest.raises(FwoImporterError): + import_state_controller.state.lookup_protocol_id(proto_name) + + def test_lookup_proto_name_to_id_known_name( + self, + import_state_controller: ImportStateController, + ): + # Arrange + proto_name = "icmp" + expected_proto_id = 1 + import_state_controller.state.protocol_map = { + "icmp": 1, + "tcp": 6, + "udp": 17, + } + + # Act + proto_id = import_state_controller.state.lookup_protocol_id(proto_name) + # Assert + assert proto_id == expected_proto_id + + +class TestFwConfigImportObjectLookupUserType: + def test_lookup_user_type_unknown( + self, + import_state_controller: ImportStateController, + ): + # Arrange + user_type_str = "some-user-type" + + # Act and Assert + with pytest.raises(FwoImporterError): + import_state_controller.state.lookup_user_obj_type_id(user_type_str) + + def test_lookup_user_type_known( + self, + import_state_controller: ImportStateController, + ): + # Arrange + user_type_str = "imported" + expected_user_type = 2 + import_state_controller.state.user_obj_type_map = { + "admin": 1, + "imported": 2, + "readonly": 3, + } + + # Act + user_type = import_state_controller.state.lookup_user_obj_type_id(user_type_str) + + # Assert + assert user_type == expected_user_type + + +class TestFwConfigImportObjectLookupSvcType: + def test_lookup_svc_type_unknown( + self, + import_state_controller: ImportStateController, + ): + # Arrange + svc_type_str = "some-svc-type" + + # Act and Assert + with pytest.raises(FwoImporterError): + import_state_controller.state.lookup_service_obj_type_id(svc_type_str) + + def test_lookup_svc_type_known( + self, + import_state_controller: ImportStateController, + ): + # Arrange + svc_type_str = "imported" + expected_svc_type = 2 + import_state_controller.state.service_obj_type_map = { + "builtin": 1, + "imported": 2, + "custom": 3, + } + + # Act + svc_type = import_state_controller.state.lookup_service_obj_type_id(svc_type_str) + + # Assert + assert svc_type == expected_svc_type + + +class TestFwConfigImportObjectWriteMemberUpdates: + def test_write_member_updates( + self, + fwconfig_import_object: FwConfigImportObject, + api_call: FwoApiCall, + mocker: MockerFixture, + ): + # Arrange + prefix = "nwobj" + api_call.call = mocker.Mock( + return_value={ + "data": { + f"insert_{prefix}": { + "affected_rows": 1, + }, + f"insert_{prefix}_flat": { + "affected_rows": 1, + }, + } + } + ) + + # Act + fwconfig_import_object.write_member_updates( + new_group_member_flats=[ + { + "admin": 1, + } + ], + new_group_members=[ + { + "admin": 1, + } + ], + prefix=prefix, + ) + + # Assert + api_call.call.assert_any_call( + mocker.ANY, + query_variables={ + "groups": [ + { + "admin": 1, + } + ], + "groupFlats": [ + { + "admin": 1, + } + ], + }, + analyze_payload=True, + ) + + def test_write_member_updates_no_updates( + self, + fwconfig_import_object: FwConfigImportObject, + api_call: FwoApiCall, + mocker: MockerFixture, + ): + # Arrange + prefix = "nwobj" + api_call.call = mocker.Mock( + return_value={ + "data": { + f"insert_{prefix}": { + "affected_rows": 0, + }, + f"insert_{prefix}_flat": { + "affected_rows": 0, + }, + } + } + ) + + # Act + fwconfig_import_object.write_member_updates( + new_group_member_flats=[], + new_group_members=[], + prefix=prefix, + ) + + # Assert + api_call.call.assert_any_call( + mocker.ANY, + query_variables={ + "groups": [], + "groupFlats": [], + }, + analyze_payload=True, + ) + + def test_write_member_updates_with_error( + self, + fwconfig_import_object: FwConfigImportObject, + api_call: FwoApiCall, + mocker: MockerFixture, + ): + # Arrange + prefix = "nwobj" + mock_logger = mocker.patch("fwo_log.FWOLogger.exception") + api_call.call = mocker.Mock( + return_value={ + "errors": [ + { + "message": "Some error occurred", + } + ] + } + ) + + # Act + with pytest.raises(FwoImporterError): + fwconfig_import_object.write_member_updates( + new_group_member_flats=[], + new_group_members=[], + prefix=prefix, + ) + + # Assert + assert mock_logger.call_count == 2 + assert ( + mock_logger.call_args_list[0][0][0] == "fwo_api:addGroupMemberships: [{'message': 'Some error occurred'}]" + ) + assert str(mock_logger.call_args_list[1][0][0]).startswith("failed to write new objects: Traceback") + + def test_write_member_updates_with_duplicate_error( + self, + fwconfig_import_object: FwConfigImportObject, + api_call: FwoApiCall, + mocker: MockerFixture, + ): + # Arrange + prefix = "nwobj" + mock_logger = mocker.patch("fwo_log.FWOLogger.exception") + api_call.call = mocker.Mock( + return_value={ + "errors": [ + "duplicate", + ] + } + ) + + # Act + with pytest.raises(FwoDuplicateKeyViolationError): + fwconfig_import_object.write_member_updates( + new_group_member_flats=[], + new_group_members=[], + prefix=prefix, + ) + + # Assert + assert mock_logger.call_count == 2 + assert mock_logger.call_args_list[0][0][0] == "fwo_api:addGroupMemberships: ['duplicate']" + assert str(mock_logger.call_args_list[1][0][0]).startswith("failed to write new objects: Traceback") + assert "duplicate" in str(mock_logger.call_args_list[1][0][0]) + + def test_write_member_updates_with_wrong_return_format( + self, + fwconfig_import_object: FwConfigImportObject, + api_call: FwoApiCall, + mocker: MockerFixture, + ): + # Arrange + prefix = "nwobj" + mock_logger = mocker.patch("fwo_log.FWOLogger.exception") + api_call.call = mocker.Mock(return_value={"data": []}) + + # Act + with pytest.raises(TypeError): + fwconfig_import_object.write_member_updates( + new_group_member_flats=[], + new_group_members=[], + prefix=prefix, + ) + + # Assert + assert mock_logger.call_count == 1 + assert str(mock_logger.call_args_list[0][0][0]).startswith("failed to write new objects: Traceback") + assert "TypeError" in str(mock_logger.call_args_list[0][0][0]) + + +class TestFwConfigImportObjectCollectGroupMembers: + def test_collect_group_members_empty( + self, + fwconfig_import_object: FwConfigImportObject, + ): + # Arrange + new_group_members: list[dict[str, Any]] = [] + + # Act + fwconfig_import_object.collect_group_members( + current_config_objects={}, + group_id=1, + prefix="nwobj", + member_uids=[], + new_group_members=new_group_members, + obj_type=Type.NETWORK_OBJECT, + prev_config_objects={}, + prev_member_uids=[], + ) + + # Assert + assert new_group_members == [] + + def test_collect_group_members_no_changes( + self, + fwconfig_import_object: FwConfigImportObject, + ): + # Arrange + new_group_members: list[dict[str, Any]] = [] + + # Act + fwconfig_import_object.collect_group_members( + current_config_objects={"1": {"id": 1, "uid": "1"}}, + group_id=1, + prefix="nwobj", + member_uids=["1"], + new_group_members=new_group_members, + obj_type=Type.NETWORK_OBJECT, + prev_config_objects={"1": {"id": 1, "uid": "1"}}, + prev_member_uids=["1"], + ) + + # Assert + assert new_group_members == [] + + def test_collect_group_members_with_changes( + self, + fwconfig_import_object: FwConfigImportObject, + mocker: MockerFixture, + ): + # Arrange + prefix = "nwobj" + new_group_members: list[dict[str, Any]] = [] + fwconfig_import_object.uid2id_mapper.get_network_object_id = mocker.Mock(return_value=2) + fwconfig_import_object.import_state.state.import_id = 5 + + # Act + fwconfig_import_object.collect_group_members( + current_config_objects={ + "1": {"id": 1, "uid": "1"}, + "2": {"id": 2, "uid": "2"}, + }, + group_id=1, + prefix=prefix, + member_uids=["1", "2"], + new_group_members=new_group_members, + obj_type=Type.NETWORK_OBJECT, + prev_config_objects={ + "1": {"id": 1, "uid": "1"}, + "3": {"id": 3, "uid": "3"}, + }, + prev_member_uids=["1", "3"], + ) + + # Assert + assert new_group_members == [ + {f"{prefix}_id": 1, f"{prefix}_member_id": 2, "import_created": 5, "import_last_seen": 5} + ] + + +class TestFwConfigImportObjectCollectFlatGroupMembers: + def test_collect_flat_group_members_empty( + self, + fwconfig_import_object: FwConfigImportObject, + ): + # Arrange + new_group_member_flats: list[dict[str, Any]] = [] + + # Act + fwconfig_import_object.collect_flat_group_members( + current_config_objects={}, + group_id=1, + prefix="nwobj", + new_group_member_flats=new_group_member_flats, + obj_type=Type.NETWORK_OBJECT, + prev_config_objects={}, + flat_member_uids=[], + prev_flat_member_uids=[], + ) + + # Assert + assert new_group_member_flats == [] + + def test_collect_flat_group_members_no_changes( + self, + fwconfig_import_object: FwConfigImportObject, + ): + # Arrange + new_group_member_flats: list[dict[str, Any]] = [] + + # Act + fwconfig_import_object.collect_flat_group_members( + current_config_objects={"1": {"id": 1, "uid": "1"}}, + group_id=1, + prefix="nwobj", + new_group_member_flats=new_group_member_flats, + obj_type=Type.NETWORK_OBJECT, + prev_config_objects={"1": {"id": 1, "uid": "1"}}, + flat_member_uids=["1"], + prev_flat_member_uids=["1"], + ) + + # Assert + assert new_group_member_flats == [] + + def test_collect_flat_group_members_with_changes( + self, + fwconfig_import_object: FwConfigImportObject, + mocker: MockerFixture, + ): + # Arrange + prefix = "nwobj" + new_group_member_flats: list[dict[str, Any]] = [] + fwconfig_import_object.uid2id_mapper.get_network_object_id = mocker.Mock(return_value=2) + fwconfig_import_object.import_state.state.import_id = 5 + + # Act + fwconfig_import_object.collect_flat_group_members( + current_config_objects={ + "1": {"id": 1, "uid": "1"}, + "2": {"id": 2, "uid": "2"}, + }, + group_id=1, + prefix=prefix, + new_group_member_flats=new_group_member_flats, + obj_type=Type.NETWORK_OBJECT, + prev_config_objects={ + "1": {"id": 1, "uid": "1"}, + "3": {"id": 3, "uid": "3"}, + }, + flat_member_uids=["1", "2"], + prev_flat_member_uids=["1", "3"], + ) + + # Assert + assert new_group_member_flats == [ + {f"{prefix}_flat_id": 1, f"{prefix}_flat_member_id": 2, "import_created": 5, "import_last_seen": 5} + ] + + +class TestFwConfigImportObjectAddGroupMemberships: + def test_add_group_memberships_no_changes( + self, + fwconfig_import_object: FwConfigImportObject, + ): + # Arrange + new_group_members: list[dict[str, Any]] = [] + + # Act + fwconfig_import_object.add_group_memberships( + obj_type=Type.NETWORK_OBJECT, + prev_config=FwConfigNormalized(), + ) + + # Assert + assert new_group_members == [] + + def test_add_group_memberships_not_a_group( + self, + fwconfig_import_object: FwConfigImportObject, + fwconfig_builder: FwConfigBuilder, + mocker: MockerFixture, + ): + # Arrange + fwconfig_import_object.normalized_config, _ = fwconfig_builder.build_config( + network_object_count=1, + ) + prev_config, _ = fwconfig_builder.build_config( + network_object_count=1, + ) + fwconfig_import_object.write_member_updates = mocker.Mock() + + for obj in fwconfig_import_object.normalized_config.network_objects.values(): + obj.obj_typ = "not-a-group" + for obj in prev_config.network_objects.values(): + obj.obj_typ = "not-a-group" + + # Act + fwconfig_import_object.add_group_memberships( + obj_type=Type.NETWORK_OBJECT, + prev_config=prev_config, + ) + + # Assert + fwconfig_import_object.write_member_updates.assert_not_called() + + def test_add_group_memberships_no_group_changes( + self, + fwconfig_import_object: FwConfigImportObject, + fwconfig_builder: FwConfigBuilder, + mocker: MockerFixture, + ): + # Arrange + fwconfig_import_object.normalized_config, _ = fwconfig_builder.build_config( + network_object_count=1, + ) + prev_config = copy.deepcopy(fwconfig_import_object.normalized_config) + fwconfig_import_object.write_member_updates = mocker.Mock() + fwconfig_import_object.uid2id_mapper.get_network_object_id = mocker.Mock(return_value=1) + + # Act + fwconfig_import_object.add_group_memberships( + obj_type=Type.NETWORK_OBJECT, + prev_config=prev_config, + ) + + # Assert + fwconfig_import_object.write_member_updates.assert_not_called() + + def test_add_group_memberships_no_group_id( + self, + fwconfig_import_object: FwConfigImportObject, + fwconfig_builder: FwConfigBuilder, + mocker: MockerFixture, + ): + # Arrange + mock_logger = mocker.patch("fwo_log.FWOLogger.error") + fwconfig_import_object.normalized_config, _ = fwconfig_builder.build_config( + network_object_count=1, + ) + prev_config, __ = fwconfig_builder.build_config( + network_object_count=1, + ) + fwconfig_import_object.write_member_updates = mocker.Mock() + fwconfig_import_object.uid2id_mapper.get_network_object_id = mocker.Mock(return_value=None) + + # Act + fwconfig_import_object.add_group_memberships( + obj_type=Type.NETWORK_OBJECT, + prev_config=prev_config, + ) + + # Assert + fwconfig_import_object.write_member_updates.assert_not_called() + + assert mock_logger.call_count == 1 + assert ( + mock_logger.call_args[0][0] + == f"failed to add group memberships: no id found for group uid '{next(iter(fwconfig_import_object.normalized_config.network_objects.keys()))}'" + ) + + def test_add_group_memberships_with_changes( + self, + fwconfig_import_object: FwConfigImportObject, + fwconfig_builder: FwConfigBuilder, + mocker: MockerFixture, + ): + # Arrange + fwconfig_import_object.normalized_config, _ = fwconfig_builder.build_config( + network_object_count=1, + ) + fwconfig_import_object.import_state.state.import_id = 5 + prev_config = copy.deepcopy(fwconfig_import_object.normalized_config) + for obj in fwconfig_import_object.normalized_config.network_objects.values(): + obj.obj_member_refs = "new-member-uid" + fwconfig_import_object.write_member_updates = mocker.Mock() + fwconfig_import_object.uid2id_mapper.get_network_object_id = mocker.Mock(return_value=1) + fwconfig_import_object.prev_group_flats_mapper.get_network_object_flats = mocker.Mock( + return_value=["old-member-uid"] + ) + + # Act + fwconfig_import_object.add_group_memberships( + obj_type=Type.NETWORK_OBJECT, + prev_config=prev_config, + ) + + # Assert + fwconfig_import_object.write_member_updates.assert_called_once_with( + [ + { + "import_created": 5, + "import_last_seen": 5, + "objgrp_id": 1, + "objgrp_member_id": 1, + }, + ], + [ + { + "import_created": 5, + "import_last_seen": 5, + "objgrp_flat_id": 1, + "objgrp_flat_member_id": 1, + } + ], + "objgrp", + ) + + def test_add_group_memberships_self_reference_group( + self, + fwconfig_import_object: FwConfigImportObject, + fwconfig_builder: FwConfigBuilder, + mocker: MockerFixture, + ): + # Arrange + fwconfig_import_object.normalized_config, _ = fwconfig_builder.build_config( + network_object_count=1, + service_object_count=0, + include_gateway=False, + ) + prev_config = fwconfig_builder.build_empty_config() + group_obj = next(iter(fwconfig_import_object.normalized_config.network_objects.values())) + group_obj.obj_member_refs = group_obj.obj_uid + fwconfig_import_object.import_state.state.import_id = 7 + fwconfig_import_object.write_member_updates = mocker.Mock() + fwconfig_import_object.uid2id_mapper.get_network_object_id = mocker.Mock(return_value=1) + fwconfig_import_object.group_flats_mapper.get_network_object_flats = mocker.Mock( + return_value=[group_obj.obj_uid] + ) + + # Act + fwconfig_import_object.add_group_memberships( + obj_type=Type.NETWORK_OBJECT, + prev_config=prev_config, + ) + + # Assert + fwconfig_import_object.write_member_updates.assert_called_once_with( + [ + { + "import_created": 7, + "import_last_seen": 7, + "objgrp_id": 1, + "objgrp_member_id": 1, + } + ], + [ + { + "import_created": 7, + "import_last_seen": 7, + "objgrp_flat_id": 1, + "objgrp_flat_member_id": 1, + } + ], + "objgrp", + ) + + def test_add_group_memberships_member_changed( + self, + fwconfig_import_object: FwConfigImportObject, + fwconfig_builder: FwConfigBuilder, + mocker: MockerFixture, + ): + # Arrange + fwconfig_import_object.normalized_config, _ = fwconfig_builder.build_config( + network_object_count=2, + service_object_count=0, + include_gateway=False, + ) + prev_config = copy.deepcopy(fwconfig_import_object.normalized_config) + group_uid, member_uid = list(fwconfig_import_object.normalized_config.network_objects.keys())[:2] + fwconfig_import_object.normalized_config.network_objects[group_uid].obj_member_refs = member_uid + prev_config.network_objects[group_uid].obj_member_refs = member_uid + fwconfig_import_object.normalized_config.network_objects[member_uid].obj_typ = "host" + prev_config.network_objects[member_uid].obj_typ = "host" + fwconfig_import_object.normalized_config.network_objects[member_uid].obj_name = "changed-member" + + def fake_get_id(uid: str, _before_update: bool = False): + return 1 if uid == group_uid else 2 + + fwconfig_import_object.import_state.state.import_id = 9 + fwconfig_import_object.write_member_updates = mocker.Mock() + fwconfig_import_object.uid2id_mapper.get_network_object_id = mocker.Mock(side_effect=fake_get_id) + fwconfig_import_object.group_flats_mapper.get_network_object_flats = mocker.Mock(return_value=[member_uid]) + fwconfig_import_object.prev_group_flats_mapper.get_network_object_flats = mocker.Mock(return_value=[member_uid]) + + # Act + fwconfig_import_object.add_group_memberships( + obj_type=Type.NETWORK_OBJECT, + prev_config=prev_config, + ) + + # Assert + fwconfig_import_object.write_member_updates.assert_called_once_with( + [ + { + "import_created": 9, + "import_last_seen": 9, + "objgrp_id": 1, + "objgrp_member_id": 2, + } + ], + [ + { + "import_created": 9, + "import_last_seen": 9, + "objgrp_flat_id": 1, + "objgrp_flat_member_id": 2, + } + ], + "objgrp", + ) + + def test_add_group_memberships_group_changed_adds_all_members_and_flats( + self, + fwconfig_import_object: FwConfigImportObject, + fwconfig_builder: FwConfigBuilder, + mocker: MockerFixture, + ): + # Arrange + fwconfig_import_object.normalized_config, _ = fwconfig_builder.build_config( + network_object_count=3, + service_object_count=0, + include_gateway=False, + ) + prev_config = copy.deepcopy(fwconfig_import_object.normalized_config) + group_uid, member_uid_one, member_uid_two = list( + fwconfig_import_object.normalized_config.network_objects.keys() + )[:3] + fwconfig_import_object.normalized_config.network_objects[ + group_uid + ].obj_member_refs = f"{member_uid_one}{LIST_DELIMITER}{member_uid_two}" + prev_config.network_objects[group_uid].obj_member_refs = member_uid_one + fwconfig_import_object.normalized_config.network_objects[member_uid_one].obj_typ = "host" + fwconfig_import_object.normalized_config.network_objects[member_uid_two].obj_typ = "host" + prev_config.network_objects[member_uid_one].obj_typ = "host" + prev_config.network_objects[member_uid_two].obj_typ = "host" + + def fake_get_id(uid: str, _before_update: bool = False): + mapping = { + group_uid: 1, + member_uid_one: 2, + member_uid_two: 3, + } + return mapping[uid] + + fwconfig_import_object.import_state.state.import_id = 11 + fwconfig_import_object.write_member_updates = mocker.Mock() + fwconfig_import_object.uid2id_mapper.get_network_object_id = mocker.Mock(side_effect=fake_get_id) + fwconfig_import_object.group_flats_mapper.get_network_object_flats = mocker.Mock( + return_value=[member_uid_one, member_uid_two] + ) + + # Act + fwconfig_import_object.add_group_memberships( + obj_type=Type.NETWORK_OBJECT, + prev_config=prev_config, + ) + + # Assert + fwconfig_import_object.write_member_updates.assert_called_once_with( + [ + { + "import_created": 11, + "import_last_seen": 11, + "objgrp_id": 1, + "objgrp_member_id": 2, + }, + { + "import_created": 11, + "import_last_seen": 11, + "objgrp_id": 1, + "objgrp_member_id": 3, + }, + ], + [ + { + "import_created": 11, + "import_last_seen": 11, + "objgrp_flat_id": 1, + "objgrp_flat_member_id": 2, + }, + { + "import_created": 11, + "import_last_seen": 11, + "objgrp_flat_id": 1, + "objgrp_flat_member_id": 3, + }, + ], + "objgrp", + ) + + +class TestFwConfigImportObjectFindRemovedObjects: + def test_find_removed_objects_not_a_group( + self, + fwconfig_import_object: FwConfigImportObject, + fwconfig_builder: FwConfigBuilder, + ): + # Arrange + fwconfig_import_object.normalized_config, _ = fwconfig_builder.build_config( + network_object_count=2, + ) + prev_config, _ = fwconfig_builder.build_config( + network_object_count=3, + ) + for obj in fwconfig_import_object.normalized_config.network_objects.values(): + obj.obj_typ = "not-a-group" + for obj in prev_config.network_objects.values(): + obj.obj_typ = "not-a-group" + removed_flats: list[dict[str, Any]] = [] + removed_members: list[dict[str, Any]] = [] + + # Act + fwconfig_import_object.find_removed_objects( + current_config_objects=fwconfig_import_object.normalized_config.network_objects, + prev_config_objects=prev_config.network_objects, + prefix="nwobj", + removed_flats=removed_flats, + removed_members=removed_members, + typ=Type.NETWORK_OBJECT, + uid=next(iter(prev_config.network_objects.values())).obj_uid, + ) + + # Assert + assert removed_flats == [] + assert removed_members == [] + + def test_find_removed_objects_no_changes( + self, + fwconfig_import_object: FwConfigImportObject, + fwconfig_builder: FwConfigBuilder, + mocker: MockerFixture, + ): + # Arrange + fwconfig_import_object.normalized_config, _ = fwconfig_builder.build_config( + network_object_count=2, + ) + prev_config = copy.deepcopy(fwconfig_import_object.normalized_config) + removed_flats: list[dict[str, Any]] = [] + removed_members: list[dict[str, Any]] = [] + fwconfig_import_object.uid2id_mapper.get_network_object_id = mocker.Mock(return_value=1) + + # Act + fwconfig_import_object.find_removed_objects( + current_config_objects=fwconfig_import_object.normalized_config.network_objects, + prev_config_objects=prev_config.network_objects, + prefix="nwobj", + removed_flats=removed_flats, + removed_members=removed_members, + typ=Type.NETWORK_OBJECT, + uid=next(iter(prev_config.network_objects.values())).obj_uid, + ) + + # Assert + assert removed_flats == [] + assert removed_members == [] + + def test_find_removed_objects_with_changes( + self, + fwconfig_import_object: FwConfigImportObject, + fwconfig_builder: FwConfigBuilder, + mocker: MockerFixture, + ): + # Arrange + fwconfig_import_object.normalized_config, _ = fwconfig_builder.build_config( + network_object_count=2, + ) + prev_config = copy.deepcopy(fwconfig_import_object.normalized_config) + for obj in fwconfig_import_object.normalized_config.network_objects.values(): + obj.obj_member_refs = "new-member-uid" + for obj in prev_config.network_objects.values(): + obj.obj_member_refs = "old-member-uid" + removed_flats: list[dict[str, Any]] = [] + removed_members: list[dict[str, Any]] = [] + fwconfig_import_object.uid2id_mapper.get_network_object_id = mocker.Mock(return_value=1) + fwconfig_import_object.prev_group_flats_mapper.get_network_object_flats = mocker.Mock(return_value=[2]) + + # Act + fwconfig_import_object.find_removed_objects( + current_config_objects=fwconfig_import_object.normalized_config.network_objects, + prev_config_objects=prev_config.network_objects, + prefix="nwobj", + removed_flats=removed_flats, + removed_members=removed_members, + typ=Type.NETWORK_OBJECT, + uid=next(iter(prev_config.network_objects.values())).obj_uid, + ) + + # Assert + assert removed_flats == [ + { + "_and": [ + { + "nwobj_flat_id": { + "_eq": 1, + }, + }, + { + "nwobj_flat_member_id": { + "_eq": 1, + }, + }, + ] + }, + ] + assert removed_members == [ + { + "_and": [ + { + "nwobj_id": { + "_eq": 1, + }, + }, + { + "nwobj_member_id": { + "_eq": 1, + }, + }, + ] + }, + ] + + def test_find_removed_objects_no_member_changes( + self, + fwconfig_import_object: FwConfigImportObject, + fwconfig_builder: FwConfigBuilder, + mocker: MockerFixture, + ): + # Arrange + fwconfig_import_object.normalized_config, _ = fwconfig_builder.build_config( + network_object_count=2, + ) + prev_config = copy.deepcopy(fwconfig_import_object.normalized_config) + last_obj_uid = list(fwconfig_import_object.normalized_config.network_objects.keys())[-1] + for obj in list(fwconfig_import_object.normalized_config.network_objects.values())[:-1]: + obj.obj_member_refs = last_obj_uid + for obj in list(prev_config.network_objects.values())[:-1]: + obj.obj_member_refs = last_obj_uid + removed_flats: list[dict[str, Any]] = [] + removed_members: list[dict[str, Any]] = [] + fwconfig_import_object.uid2id_mapper.get_network_object_id = mocker.Mock(return_value=last_obj_uid) + fwconfig_import_object.prev_group_flats_mapper.get_network_object_flats = mocker.Mock( + return_value=[last_obj_uid] + ) + + # Act + fwconfig_import_object.find_removed_objects( + current_config_objects=fwconfig_import_object.normalized_config.network_objects, + prev_config_objects=prev_config.network_objects, + prefix="nwobj", + removed_flats=removed_flats, + removed_members=removed_members, + typ=Type.NETWORK_OBJECT, + uid=next(iter(prev_config.network_objects.values())).obj_uid, + ) + + # Assert + assert removed_flats == [] + assert removed_members == [] + + +class TestFwConfigImportObjectRemoveOutdatedMemberships: + def test_remove_outdated_memberships_no_changes( + self, + fwconfig_import_object: FwConfigImportObject, + mocker: MockerFixture, + ): + # Arrange + fwconfig_import_object.normalized_config, _ = FwConfigBuilder().build_config( + network_object_count=2, + ) + prev_config = copy.deepcopy(fwconfig_import_object.normalized_config) + fwconfig_import_object.import_state.api_call.call = mocker.Mock() + fwconfig_import_object.uid2id_mapper.get_network_object_id = mocker.Mock(return_value=1) + + # Act + fwconfig_import_object.remove_outdated_memberships( + prev_config=prev_config, + typ=Type.NETWORK_OBJECT, + ) + + # Assert + fwconfig_import_object.import_state.api_call.call.assert_not_called() + + def test_remove_outdated_memberships_with_changes_and_success( + self, + fwconfig_import_object: FwConfigImportObject, + mocker: MockerFixture, + fwconfig_builder: FwConfigBuilder, + ): + # Arrange + fwconfig_import_object.normalized_config, _ = fwconfig_builder.build_config( + network_object_count=2, + ) + prev_config = copy.deepcopy(fwconfig_import_object.normalized_config) + for obj in prev_config.network_objects.values(): + obj.obj_member_refs = "old-member-uid" + for obj in fwconfig_import_object.normalized_config.network_objects.values(): + obj.obj_member_refs = "new-member-uid" + + fwconfig_import_object.uid2id_mapper.get_network_object_id = mocker.Mock(return_value=1) + fwconfig_import_object.prev_group_flats_mapper.get_network_object_flats = mocker.Mock(return_value=[2]) + fwconfig_import_object.import_state.api_call.call = mocker.Mock( + return_value={ + "data": { + "update_objgrp_flat": { + "affected_rows": 1, + }, + "update_objgrp": { + "affected_rows": 1, + }, + } + } + ) + fwconfig_import_object.import_state.state.import_id = 5 + + # Act + fwconfig_import_object.remove_outdated_memberships( + prev_config=prev_config, + typ=Type.NETWORK_OBJECT, + ) + + # Assert + fwconfig_import_object.import_state.api_call.call.assert_called_once() + call_args = fwconfig_import_object.import_state.api_call.call.call_args + assert call_args.kwargs["query_variables"] == { + "importId": 5, + "removedMembers": [ + {"_and": [{"objgrp_id": {"_eq": 1}}, {"objgrp_member_id": {"_eq": 1}}]}, + {"_and": [{"objgrp_id": {"_eq": 1}}, {"objgrp_member_id": {"_eq": 1}}]}, + ], + "removedFlats": [ + {"_and": [{"objgrp_flat_id": {"_eq": 1}}, {"objgrp_flat_member_id": {"_eq": 1}}]}, + {"_and": [{"objgrp_flat_id": {"_eq": 1}}, {"objgrp_flat_member_id": {"_eq": 1}}]}, + ], + } + + def test_remove_outdated_memberships_with_changes_and_errors( + self, + fwconfig_import_object: FwConfigImportObject, + mocker: MockerFixture, + fwconfig_builder: FwConfigBuilder, + ): + # Arrange + fwconfig_import_object.normalized_config, _ = fwconfig_builder.build_config( + network_object_count=2, + ) + prev_config = copy.deepcopy(fwconfig_import_object.normalized_config) + fwconfig_import_object.uid2id_mapper.get_network_object_id = mocker.Mock(return_value=1) + for obj in fwconfig_import_object.normalized_config.network_objects.values(): + obj.obj_member_refs = "new-member-uid" + for obj in prev_config.network_objects.values(): + obj.obj_member_refs = "old-member-uid" + + fwconfig_import_object.prev_group_flats_mapper.get_network_object_flats = mocker.Mock(return_value=[2]) + fwconfig_import_object.import_state.api_call.call = mocker.Mock( + return_value={ + "errors": [ + { + "message": "Some error occurred", + } + ] + } + ) + fwconfig_import_object.import_state.state.import_id = 5 + mock_logger = mocker.patch("fwo_log.FWOLogger.exception") + + # Act + fwconfig_import_object.remove_outdated_memberships( + prev_config=prev_config, + typ=Type.NETWORK_OBJECT, + ) + + # Assert + fwconfig_import_object.import_state.api_call.call.assert_called_once() + mock_logger.assert_called_once() + assert ( + mock_logger.call_args[0][0] + == "fwo_api:importNwObject - error in removeOutdatedObjgrpMemberships: [{'message': 'Some error occurred'}]" + ) + + def test_remove_outdated_memberships_with_changes_and_exception( + self, + fwconfig_import_object: FwConfigImportObject, + mocker: MockerFixture, + fwconfig_builder: FwConfigBuilder, + ): + # Arrange + fwconfig_import_object.normalized_config, _ = fwconfig_builder.build_config( + network_object_count=2, + ) + prev_config = copy.deepcopy(fwconfig_import_object.normalized_config) + for obj in fwconfig_import_object.normalized_config.network_objects.values(): + obj.obj_member_refs = "new-member-uid" + for obj in prev_config.network_objects.values(): + obj.obj_member_refs = "old-member-uid" + fwconfig_import_object.uid2id_mapper.get_network_object_id = mocker.Mock(return_value=1) + fwconfig_import_object.prev_group_flats_mapper.get_network_object_flats = mocker.Mock(return_value=[2]) + fwconfig_import_object.import_state.api_call.call = mocker.Mock( + return_value={ + "error": "Some unexpected error occurred", + } + ) + fwconfig_import_object.import_state.state.import_id = 5 + mock_logger = mocker.patch("fwo_log.FWOLogger.exception") + + # Act + fwconfig_import_object.remove_outdated_memberships( + prev_config=prev_config, + typ=Type.NETWORK_OBJECT, + ) + + # Assert + fwconfig_import_object.import_state.api_call.call.assert_called_once() + mock_logger.assert_called_once() + assert str(mock_logger.call_args[0][0]).startswith( + "failed to remove outdated group memberships for Type.NETWORK_OBJECT: Traceback" + ) + + def test_remove_outdated_memberships_group_removed( + self, + fwconfig_import_object: FwConfigImportObject, + mocker: MockerFixture, + fwconfig_builder: FwConfigBuilder, + ): + # Arrange + prev_config, _ = fwconfig_builder.build_config( + network_object_count=2, + service_object_count=0, + include_gateway=False, + ) + group_uid, member_uid = list(prev_config.network_objects.keys())[:2] + prev_config.network_objects[group_uid].obj_member_refs = member_uid + prev_config.network_objects[member_uid].obj_typ = "host" + fwconfig_import_object.normalized_config = FwConfigNormalized() + + def fake_get_id(uid: str, _before_update: bool = False): + return 10 if uid == group_uid else 20 + + fwconfig_import_object.uid2id_mapper.get_network_object_id = mocker.Mock(side_effect=fake_get_id) + fwconfig_import_object.prev_group_flats_mapper.get_network_object_flats = mocker.Mock(return_value=[member_uid]) + fwconfig_import_object.import_state.api_call.call = mocker.Mock( + return_value={ + "data": { + "update_objgrp": {"affected_rows": 1}, + "update_objgrp_flat": {"affected_rows": 1}, + } + } + ) + fwconfig_import_object.import_state.state.import_id = 6 + + # Act + fwconfig_import_object.remove_outdated_memberships( + prev_config=prev_config, + typ=Type.NETWORK_OBJECT, + ) + + # Assert + call_args = fwconfig_import_object.import_state.api_call.call.call_args + assert call_args.kwargs["query_variables"] == { + "importId": 6, + "removedMembers": [{"_and": [{"objgrp_id": {"_eq": 10}}, {"objgrp_member_id": {"_eq": 20}}]}], + "removedFlats": [{"_and": [{"objgrp_flat_id": {"_eq": 10}}, {"objgrp_flat_member_id": {"_eq": 20}}]}], + } + + def test_remove_outdated_memberships_group_changed_removes_all_prev_members_and_flats( + self, + fwconfig_import_object: FwConfigImportObject, + mocker: MockerFixture, + fwconfig_builder: FwConfigBuilder, + ): + # Arrange + fwconfig_import_object.normalized_config, _ = fwconfig_builder.build_config( + network_object_count=3, + service_object_count=0, + include_gateway=False, + ) + prev_config = copy.deepcopy(fwconfig_import_object.normalized_config) + group_uid, member_uid_one, member_uid_two = list(prev_config.network_objects.keys())[:3] + prev_config.network_objects[group_uid].obj_member_refs = f"{member_uid_one}{LIST_DELIMITER}{member_uid_two}" + fwconfig_import_object.normalized_config.network_objects[group_uid].obj_member_refs = member_uid_one + prev_config.network_objects[member_uid_one].obj_typ = "host" + prev_config.network_objects[member_uid_two].obj_typ = "host" + fwconfig_import_object.normalized_config.network_objects[member_uid_one].obj_typ = "host" + fwconfig_import_object.normalized_config.network_objects[member_uid_two].obj_typ = "host" + + def fake_get_id(uid: str, _before_update: bool = False): + mapping = { + group_uid: 100, + member_uid_one: 200, + member_uid_two: 300, + } + return mapping[uid] + + fwconfig_import_object.uid2id_mapper.get_network_object_id = mocker.Mock(side_effect=fake_get_id) + fwconfig_import_object.prev_group_flats_mapper.get_network_object_flats = mocker.Mock( + return_value=[member_uid_one, member_uid_two] + ) + fwconfig_import_object.import_state.api_call.call = mocker.Mock( + return_value={ + "data": { + "update_objgrp": {"affected_rows": 2}, + "update_objgrp_flat": {"affected_rows": 2}, + } + } + ) + fwconfig_import_object.import_state.state.import_id = 12 + + # Act + fwconfig_import_object.remove_outdated_memberships( + prev_config=prev_config, + typ=Type.NETWORK_OBJECT, + ) + + # Assert + call_args = fwconfig_import_object.import_state.api_call.call.call_args + assert call_args.kwargs["query_variables"] == { + "importId": 12, + "removedMembers": [ + {"_and": [{"objgrp_id": {"_eq": 100}}, {"objgrp_member_id": {"_eq": 200}}]}, + {"_and": [{"objgrp_id": {"_eq": 100}}, {"objgrp_member_id": {"_eq": 300}}]}, + ], + "removedFlats": [ + {"_and": [{"objgrp_flat_id": {"_eq": 100}}, {"objgrp_flat_member_id": {"_eq": 200}}]}, + {"_and": [{"objgrp_flat_id": {"_eq": 100}}, {"objgrp_flat_member_id": {"_eq": 300}}]}, + ], + } + + +class TestFwConfigImportObjectGetPrefix: + def test_get_prefix_network_object( + self, + fwconfig_import_object: FwConfigImportObject, + ): + # Arrange + expected_prefix = "objgrp" + + # Act + prefix = fwconfig_import_object.get_prefix(Type.NETWORK_OBJECT) + + # Assert + assert prefix == expected_prefix + + def test_get_prefix_service_object( + self, + fwconfig_import_object: FwConfigImportObject, + ): + # Arrange + expected_prefix = "svcgrp" + + # Act + prefix = fwconfig_import_object.get_prefix(Type.SERVICE_OBJECT) + + # Assert + assert prefix == expected_prefix + + def test_get_prefix_user_object( + self, + fwconfig_import_object: FwConfigImportObject, + ): + # Arrange + expected_prefix = "usergrp" + + # Act + prefix = fwconfig_import_object.get_prefix(Type.USER) + + # Assert + assert prefix == expected_prefix + + +class TestFwConfigImportObjectGetPrevFlats: + def test_get_prev_flats_network_object( + self, + fwconfig_import_object: FwConfigImportObject, + mocker: MockerFixture, + ): + # Arrange + fwconfig_import_object.prev_group_flats_mapper.get_network_object_flats = mocker.Mock(return_value=[1, 2, 3]) + + # Act + flats = fwconfig_import_object.get_prev_flats(Type.NETWORK_OBJECT, "some-uid") + + # Assert + assert flats == [1, 2, 3] + + def test_get_prev_flats_service_object( + self, + fwconfig_import_object: FwConfigImportObject, + mocker: MockerFixture, + ): + # Arrange + fwconfig_import_object.prev_group_flats_mapper.get_service_object_flats = mocker.Mock(return_value=[4, 5, 6]) + + # Act + flats = fwconfig_import_object.get_prev_flats(Type.SERVICE_OBJECT, "some-uid") + + # Assert + assert flats == [4, 5, 6] + + def test_get_prev_flats_user_object( + self, + fwconfig_import_object: FwConfigImportObject, + mocker: MockerFixture, + ): + # Arrange + fwconfig_import_object.prev_group_flats_mapper.get_user_flats = mocker.Mock(return_value=[7, 8, 9]) + + # Act + flats = fwconfig_import_object.get_prev_flats(Type.USER, "some-uid") + + # Assert + assert flats == [7, 8, 9] + + +class TestFwConfigImportObjectGetFlats: + def test_get_flats_network_object( + self, + fwconfig_import_object: FwConfigImportObject, + mocker: MockerFixture, + ): + # Arrange + fwconfig_import_object.group_flats_mapper.get_network_object_flats = mocker.Mock(return_value=[1, 2, 3]) + + # Act + flats = fwconfig_import_object.get_flats(Type.NETWORK_OBJECT, "some-uid") + + # Assert + assert flats == [1, 2, 3] + + def test_get_flats_service_object( + self, + fwconfig_import_object: FwConfigImportObject, + mocker: MockerFixture, + ): + # Arrange + fwconfig_import_object.group_flats_mapper.get_service_object_flats = mocker.Mock(return_value=[4, 5, 6]) + + # Act + flats = fwconfig_import_object.get_flats(Type.SERVICE_OBJECT, "some-uid") + + # Assert + assert flats == [4, 5, 6] + + def test_get_flats_user_object( + self, + fwconfig_import_object: FwConfigImportObject, + mocker: MockerFixture, + ): + # Arrange + fwconfig_import_object.group_flats_mapper.get_user_flats = mocker.Mock(return_value=[7, 8, 9]) + + # Act + flats = fwconfig_import_object.get_flats(Type.USER, "some-uid") + + # Assert + assert flats == [7, 8, 9] + + +class TestFwConfigImportObjectGetMembers: + def test_get_members_network_object_empty( + self, + fwconfig_import_object: FwConfigImportObject, + ): + # Act + members = fwconfig_import_object.get_members(Type.NETWORK_OBJECT, "") + + # Assert + assert members == [] + + def test_get_members_network_object( + self, + fwconfig_import_object: FwConfigImportObject, + ): + # Act + members = fwconfig_import_object.get_members( + Type.NETWORK_OBJECT, "some-uid" + LIST_DELIMITER + "some-user@another-uid" + ) + + # Assert + assert members == [ + "some-uid", + "some-user", + ] + + def test_get_members_service_object_empty( + self, + fwconfig_import_object: FwConfigImportObject, + ): + # Act + members = fwconfig_import_object.get_members(Type.SERVICE_OBJECT, "") + + # Assert + assert members == [] + + def test_get_members_service_object( + self, + fwconfig_import_object: FwConfigImportObject, + ): + # Act + members = fwconfig_import_object.get_members( + Type.SERVICE_OBJECT, "some-uid" + LIST_DELIMITER + "some-user@another-uid" + ) + + # Assert + assert members == [ + "some-uid", + "some-user@another-uid", + ] + + +class TestFwConfigImportObjectGetRefs: + def test_get_refs_network_object( + self, + fwconfig_import_object: FwConfigImportObject, + fwconfig_builder: FwConfigBuilder, + ): + # Arrange + config, _ = fwconfig_builder.build_config(network_object_count=1) + obj = next(iter(config.network_objects.values())) + obj.obj_member_refs = "some-uid" + LIST_DELIMITER + "some-user@another-uid" + + # Act + refs = fwconfig_import_object.get_refs(Type.NETWORK_OBJECT, obj) + + # Assert + assert refs == "some-uid" + LIST_DELIMITER + "some-user@another-uid" + + def test_get_refs_service_object( + self, + fwconfig_import_object: FwConfigImportObject, + fwconfig_builder: FwConfigBuilder, + ): + # Arrange + config, _ = fwconfig_builder.build_config(service_object_count=1) + obj = next(iter(config.service_objects.values())) + obj.svc_member_refs = "some-uid" + LIST_DELIMITER + "some-user@another-uid" + + # Act + refs = fwconfig_import_object.get_refs(Type.SERVICE_OBJECT, obj) + + # Assert + assert refs == "some-uid" + LIST_DELIMITER + "some-user@another-uid" + + def test_get_refs_user_object( + self, + fwconfig_import_object: FwConfigImportObject, + ): + # Act + refs = fwconfig_import_object.get_refs( + Type.USER, {"user_member_refs": "some-uid" + LIST_DELIMITER + "some-user@another-uid"} + ) + + # Assert + assert refs == "some-uid" + LIST_DELIMITER + "some-user@another-uid" + + +class TestFwConfigImportObjectIsGroup: + def test_is_group_true_network_object( + self, + fwconfig_import_object: FwConfigImportObject, + fwconfig_builder: FwConfigBuilder, + ): + # Arrange + config, _ = fwconfig_builder.build_config(network_object_count=1) + obj = next(iter(config.network_objects.values())) + obj.obj_typ = "group" + + # Act + is_group = fwconfig_import_object.is_group(Type.NETWORK_OBJECT, obj) + + # Assert + assert is_group is True + + def test_is_group_false_network_object( + self, + fwconfig_import_object: FwConfigImportObject, + fwconfig_builder: FwConfigBuilder, + ): + # Arrange + config, _ = fwconfig_builder.build_config(network_object_count=1) + obj = next(iter(config.network_objects.values())) + obj.obj_typ = "not-a-group" + + # Act + is_group = fwconfig_import_object.is_group(Type.NETWORK_OBJECT, obj) + + # Assert + assert is_group is False + + def test_is_group_true_service_object( + self, + fwconfig_import_object: FwConfigImportObject, + fwconfig_builder: FwConfigBuilder, + ): + # Arrange + config, _ = fwconfig_builder.build_config(service_object_count=1) + obj = next(iter(config.service_objects.values())) + obj.svc_typ = "group" + + # Act + is_group = fwconfig_import_object.is_group(Type.SERVICE_OBJECT, obj) + + # Assert + assert is_group is True + + def test_is_group_false_service_object( + self, + fwconfig_import_object: FwConfigImportObject, + fwconfig_builder: FwConfigBuilder, + ): + # Arrange + config, _ = fwconfig_builder.build_config(service_object_count=1) + obj = next(iter(config.service_objects.values())) + obj.svc_typ = "not-a-group" + + # Act + is_group = fwconfig_import_object.is_group(Type.SERVICE_OBJECT, obj) + + # Assert + assert is_group is False + + def test_is_group_true_user_object( + self, + fwconfig_import_object: FwConfigImportObject, + ): + # Arrange + obj = {"user_typ": "group"} + + # Act + is_group = fwconfig_import_object.is_group(Type.USER, obj) + + # Assert + assert is_group is True + + def test_is_group_false_user_object( + self, + fwconfig_import_object: FwConfigImportObject, + ): + # Arrange + obj = {"user_typ": "not-a-group"} + + # Act + is_group = fwconfig_import_object.is_group(Type.USER, obj) + + # Assert + assert is_group is False + + +class TestFwConfigImportObjectGetLocalId: + def test_get_local_id_network_object( + self, + fwconfig_import_object: FwConfigImportObject, + mocker: MockerFixture, + ): + # Arrange + fwconfig_import_object.uid2id_mapper.get_network_object_id = mocker.Mock(return_value=42) + + # Act + local_id = fwconfig_import_object.get_local_id(Type.NETWORK_OBJECT, "some-uid") + + # Assert + assert local_id == 42 + + def test_get_local_id_service_object( + self, + fwconfig_import_object: FwConfigImportObject, + mocker: MockerFixture, + ): + # Arrange + fwconfig_import_object.uid2id_mapper.get_service_object_id = mocker.Mock(return_value=43) + + # Act + local_id = fwconfig_import_object.get_local_id(Type.SERVICE_OBJECT, "some-uid") + + # Assert + assert local_id == 43 + + def test_get_local_id_user_object( + self, + fwconfig_import_object: FwConfigImportObject, + mocker: MockerFixture, + ): + # Arrange + fwconfig_import_object.uid2id_mapper.get_user_id = mocker.Mock(return_value=44) + + # Act + local_id = fwconfig_import_object.get_local_id(Type.USER, "some-uid") + + # Assert + assert local_id == 44 + + +class TestFwConfigImportObjectGetId: + def test_get_id_network_object( + self, + fwconfig_import_object: FwConfigImportObject, + mocker: MockerFixture, + ): + # Arrange + fwconfig_import_object.uid2id_mapper.get_network_object_id = mocker.Mock(return_value=42) + + # Act + obj_id = fwconfig_import_object.get_id(Type.NETWORK_OBJECT, "some-uid") + + # Assert + assert obj_id == 42 + + def test_get_id_service_object( + self, + fwconfig_import_object: FwConfigImportObject, + mocker: MockerFixture, + ): + # Arrange + fwconfig_import_object.uid2id_mapper.get_service_object_id = mocker.Mock(return_value=43) + + # Act + obj_id = fwconfig_import_object.get_id(Type.SERVICE_OBJECT, "some-uid") + + # Assert + assert obj_id == 43 + + def test_get_id_user_object( + self, + fwconfig_import_object: FwConfigImportObject, + mocker: MockerFixture, + ): + # Arrange + fwconfig_import_object.uid2id_mapper.get_user_id = mocker.Mock(return_value=44) + + # Act + obj_id = fwconfig_import_object.get_id(Type.USER, "some-uid") + + # Assert + assert obj_id == 44 + + +class TestFwConfigImportObjectGetConfigObjects: + def test_get_config_objects_no_normalized_config( + self, + fwconfig_import_object: FwConfigImportObject, + ): + # Arrange + fwconfig_import_object.normalized_config = None + + # Act + with pytest.raises(FwoImporterError): + fwconfig_import_object.get_config_objects( + typ=Type.NETWORK_OBJECT, + prev_config=FwConfigNormalized(), + ) + + def test_get_config_objects_network_objects( + self, + fwconfig_import_object: FwConfigImportObject, + fwconfig_builder: FwConfigBuilder, + ): + # Arrange + fwconfig_import_object.normalized_config, _ = fwconfig_builder.build_config(network_object_count=2) + prev_config, __ = fwconfig_builder.build_config(network_object_count=1) + + # Act + prev_objs, current_objs = fwconfig_import_object.get_config_objects( + typ=Type.NETWORK_OBJECT, + prev_config=prev_config, + ) + + # Assert + assert prev_objs == prev_config.network_objects + assert current_objs == fwconfig_import_object.normalized_config.network_objects + + def test_get_config_objects_service_objects( + self, + fwconfig_import_object: FwConfigImportObject, + fwconfig_builder: FwConfigBuilder, + ): + # Arrange + fwconfig_import_object.normalized_config, _ = fwconfig_builder.build_config(service_object_count=2) + prev_config, __ = fwconfig_builder.build_config(service_object_count=1) + + # Act + prev_objs, current_objs = fwconfig_import_object.get_config_objects( + typ=Type.SERVICE_OBJECT, + prev_config=prev_config, + ) + + # Assert + assert prev_objs == prev_config.service_objects + assert current_objs == fwconfig_import_object.normalized_config.service_objects + + def test_get_config_objects_user_objects( + self, + fwconfig_import_object: FwConfigImportObject, + fwconfig_builder: FwConfigBuilder, + ): + # Arrange + fwconfig_import_object.normalized_config, _ = fwconfig_builder.build_config(user_object_count=2) + prev_config, __ = fwconfig_builder.build_config(user_object_count=1) + + # Act + prev_objs, current_objs = fwconfig_import_object.get_config_objects( + typ=Type.USER, + prev_config=prev_config, + ) + + # Assert + assert prev_objs == prev_config.users + assert current_objs == fwconfig_import_object.normalized_config.users + + +class TestFwConfigImportObjectPrepareNewZones: + def test_prepare_new_zones_no_normalized_config( + self, + fwconfig_import_object: FwConfigImportObject, + ): + # Arrange + fwconfig_import_object.normalized_config = None + + # Act + with pytest.raises(FwoImporterError): + fwconfig_import_object.prepare_new_zones( + mgm_id=1, + new_zone_names=["zone1", "zone2"], + ) + + def test_prepare_new_zones( + self, + fwconfig_import_object: FwConfigImportObject, + fwconfig_builder: FwConfigBuilder, + ): + # Arrange + fwconfig_import_object.normalized_config, _ = fwconfig_builder.build_config() + new_zone_names = ["zone1", "zone2"] + for zone_name in new_zone_names: + fwconfig_import_object.normalized_config.zone_objects[zone_name] = { + "zone_name": zone_name, + } + fwconfig_import_object.import_state.state.import_id = 5 + + # Act + new_zones = fwconfig_import_object.prepare_new_zones( + mgm_id=1, + new_zone_names=new_zone_names, + ) + + # Assert + assert new_zones == [ + { + "mgm_id": 1, + "zone_create": 5, + "zone_last_seen": 5, + "zone_name": "zone1", + }, + { + "mgm_id": 1, + "zone_create": 5, + "zone_last_seen": 5, + "zone_name": "zone2", + }, + ] + + +class TestFwConfigImportObjectPrepareNewUserobjs: + def test_prepare_new_userobjs_no_normalized_config( + self, + fwconfig_import_object: FwConfigImportObject, + ): + # Arrange + fwconfig_import_object.normalized_config = None + + # Act + with pytest.raises(FwoImporterError): + fwconfig_import_object.prepare_new_userobjs( + mgm_id=1, + new_user_uids=["user1", "user2"], + ) + + def test_prepare_new_userobjs( + self, + fwconfig_import_object: FwConfigImportObject, + fwconfig_builder: FwConfigBuilder, + ): + # Arrange + fwconfig_import_object.normalized_config, _ = fwconfig_builder.build_config(user_object_count=2) + new_user_uids = list(fwconfig_import_object.normalized_config.users.keys())[:2] + fwconfig_import_object.import_state.state.import_id = 5 + + # Act + new_userobjs = fwconfig_import_object.prepare_new_userobjs( + mgm_id=1, + new_user_uids=new_user_uids, + ) + + # Assert + assert new_userobjs == [ + { + "mgm_id": 1, + "user_create": 5, + "user_last_seen": 5, + "user_name": f"user-{new_user_uids[0]}", + "user_uid": new_user_uids[0], + "usr_typ_id": 2, + }, + { + "mgm_id": 1, + "user_create": 5, + "user_last_seen": 5, + "user_name": f"user-{new_user_uids[1]}", + "user_uid": new_user_uids[1], + "usr_typ_id": 2, + }, + ] + + +class TestFwConfigImportObjectPrepareNewSvcobjs: + def test_prepare_new_svcobjs_no_normalized_config( + self, + fwconfig_import_object: FwConfigImportObject, + ): + # Arrange + fwconfig_import_object.normalized_config = None + + # Act + with pytest.raises(FwoImporterError): + fwconfig_import_object.prepare_new_svcobjs( + mgm_id=1, + new_svcobj_uids=["svc1", "svc2"], + ) + + def test_prepare_new_svcobjs( + self, + fwconfig_import_object: FwConfigImportObject, + fwconfig_builder: FwConfigBuilder, + ): + # Arrange + fwconfig_import_object.normalized_config, _ = fwconfig_builder.build_config(service_object_count=2) + new_svc_uids = list(fwconfig_import_object.normalized_config.service_objects.keys())[:2] + fwconfig_import_object.import_state.state.import_id = 5 + + # Act + new_svcobjs = fwconfig_import_object.prepare_new_svcobjs( + mgm_id=1, + new_svcobj_uids=new_svc_uids, + ) + + # Assert + assert new_svcobjs == [ + ServiceObjectForImport( + svc_object=fwconfig_import_object.normalized_config.service_objects[uid], + mgm_id=1, + import_id=fwconfig_import_object.import_state.state.import_id, + color_id=fwconfig_import_object.import_state.state.lookup_color_id( + fwconfig_import_object.normalized_config.service_objects[uid].svc_color + ), + typ_id=fwconfig_import_object.import_state.state.lookup_service_obj_type_id( + fwconfig_import_object.normalized_config.service_objects[uid].svc_typ + ), + ).to_dict() + for uid in new_svc_uids + ] + + +class TestFwConfgImportObjectPrepareNewNwobjs: + def test_prepare_new_nwobjs_no_normalized_config( + self, + fwconfig_import_object: FwConfigImportObject, + ): + # Arrange + fwconfig_import_object.normalized_config = None + + # Act + with pytest.raises(FwoImporterError): + fwconfig_import_object.prepare_new_nwobjs( + mgm_id=1, + new_nwobj_uids=["nwobj1", "nwobj2"], + ) + + def test_prepare_new_nwobjs( + self, + fwconfig_import_object: FwConfigImportObject, + fwconfig_builder: FwConfigBuilder, + ): + # Arrange + fwconfig_import_object.normalized_config, _ = fwconfig_builder.build_config(network_object_count=2) + new_nwobj_uids = list(fwconfig_import_object.normalized_config.network_objects.keys())[:2] + fwconfig_import_object.import_state.state.import_id = 5 + + # Act + new_nwobjs = fwconfig_import_object.prepare_new_nwobjs( + mgm_id=1, + new_nwobj_uids=new_nwobj_uids, + ) + + # Assert + assert new_nwobjs == [ + NetworkObjectForImport( + nw_object=fwconfig_import_object.normalized_config.network_objects[uid], + mgm_id=1, + import_id=fwconfig_import_object.import_state.state.import_id, + color_id=fwconfig_import_object.import_state.state.lookup_color_id( + fwconfig_import_object.normalized_config.network_objects[uid].obj_color + ), + typ_id=fwconfig_import_object.import_state.state.lookup_network_obj_type_id( + fwconfig_import_object.normalized_config.network_objects[uid].obj_typ + ), + ).to_dict() + for uid in new_nwobj_uids + ] + + +class TestFwConfigImportObjectUpdateObjectsViaApi: + def test_update_objects_via_api_no_management_id( + self, + fwconfig_import_object: FwConfigImportObject, + mocker: MockerFixture, + fw_config_manager: FwConfigManager, + ): + # Arrange + fwconfig_import_object.import_state.state.lookup_management_id = mocker.Mock(return_value=None) + fwconfig_import_object.import_state.api_call.call = mocker.Mock() + + # Act + with pytest.raises(FwoImporterError): + fwconfig_import_object.update_objects_via_api( + new_nw_object_uids=[], + new_svc_obj_uids=[], + new_user_uids=[], + new_zone_names=[], + removed_nw_object_uids=[], + removed_svc_object_uids=[], + removed_user_uids=[], + removed_zone_names=[], + single_manager=fw_config_manager, + ) + + # Assert + fwconfig_import_object.import_state.api_call.call.assert_not_called() + + def test_update_objects_via_api_with_errors( + self, + fwconfig_import_object: FwConfigImportObject, + mocker: MockerFixture, + fw_config_manager: FwConfigManager, + ): + # Arrange + fwconfig_import_object.import_state.state.lookup_management_id = mocker.Mock(return_value=1) + mock_get_graphql_code(mocker, "importObjectsMutation") + fwconfig_import_object.import_state.api_call.call = mocker.Mock( + return_value={ + "errors": [ + { + "message": "Some error occurred", + } + ] + } + ) + + # Act + with pytest.raises(FwoImporterError): + fwconfig_import_object.update_objects_via_api( + new_nw_object_uids=[], + new_svc_obj_uids=[], + new_user_uids=[], + new_zone_names=[], + removed_nw_object_uids=[], + removed_svc_object_uids=[], + removed_user_uids=[], + removed_zone_names=[], + single_manager=fw_config_manager, + ) + + # Assert + fwconfig_import_object.import_state.api_call.call.assert_called_once() + + def test_update_objects_via_api_with_exception( + self, + fwconfig_import_object: FwConfigImportObject, + mocker: MockerFixture, + fw_config_manager: FwConfigManager, + ): + # Arrange + fwconfig_import_object.import_state.state.lookup_management_id = mocker.Mock(return_value=1) + mock_get_graphql_code(mocker, "importObjectsMutation") + fwconfig_import_object.import_state.api_call.call = mocker.Mock( + side_effect=Exception("Unexpected error occurred") + ) + + # Act + with pytest.raises(FwoImporterError): + fwconfig_import_object.update_objects_via_api( + new_nw_object_uids=[], + new_svc_obj_uids=[], + new_user_uids=[], + new_zone_names=[], + removed_nw_object_uids=[], + removed_svc_object_uids=[], + removed_user_uids=[], + removed_zone_names=[], + single_manager=fw_config_manager, + ) + + # Assert + fwconfig_import_object.import_state.api_call.call.assert_called_once() + + def test_update_objects_via_api_with_wrong_response_format( + self, + fwconfig_import_object: FwConfigImportObject, + mocker: MockerFixture, + fw_config_manager: FwConfigManager, + ): + # Arrange + fwconfig_import_object.import_state.state.lookup_management_id = mocker.Mock(return_value=1) + mock_get_graphql_code(mocker, "importObjectsMutation") + fwconfig_import_object.import_state.api_call.call = mocker.Mock(return_value={"unexpected_key": {}}) + + # Act + with pytest.raises(FwoImporterError): + fwconfig_import_object.update_objects_via_api( + new_nw_object_uids=[], + new_svc_obj_uids=[], + new_user_uids=[], + new_zone_names=[], + removed_nw_object_uids=[], + removed_svc_object_uids=[], + removed_user_uids=[], + removed_zone_names=[], + single_manager=fw_config_manager, + ) + + # Assert + fwconfig_import_object.import_state.api_call.call.assert_called_once() + + def test_update_objects_via_api( + self, + fwconfig_import_object: FwConfigImportObject, + mocker: MockerFixture, + fw_config_manager: FwConfigManager, + ): + # Arrange + FWOLogger.instance.debug_level = 9 + fwconfig_import_object.import_state.state.lookup_management_id = mocker.Mock(return_value=1) + fwconfig_import_object.import_state.api_call.call = mocker.Mock( + return_value={ + "data": { + "insert_object": {"affected_rows": 1, "returning": [{"id": 1}]}, + "insert_service": {"affected_rows": 1, "returning": [{"id": 2}]}, + "insert_usr": {"affected_rows": 1, "returning": [{"id": 3}]}, + "insert_zone": {"affected_rows": 1, "returning": [{"id": 4}]}, + "update_object": {"affected_rows": 1, "returning": [{"id": 5}]}, + "update_service": {"affected_rows": 1, "returning": [{"id": 6}]}, + "update_usr": {"affected_rows": 1, "returning": [{"id": 7}]}, + "update_zone": {"affected_rows": 1, "returning": [{"id": 8}]}, + } + } + ) + mock_get_graphql_code(mocker, "importObjectsMutation") + + # Act + ( + new_nwobj_ids, + new_nwsvc_ids, + new_user_ids, + new_zone_ids, + removed_nwobj_ids, + removed_nwsvc_ids, + removed_user_ids, + removed_zone_ids, + ) = fwconfig_import_object.update_objects_via_api( + new_nw_object_uids=[], + new_svc_obj_uids=[], + new_user_uids=[], + new_zone_names=[], + removed_nw_object_uids=[], + removed_svc_object_uids=[], + removed_user_uids=[], + removed_zone_names=[], + single_manager=fw_config_manager, + ) + + # Assert + assert new_nwobj_ids == [{"id": 1}] + assert new_nwsvc_ids == [{"id": 2}] + assert new_user_ids == [{"id": 3}] + assert new_zone_ids == [{"id": 4}] + assert removed_nwobj_ids == [{"id": 5}] + assert removed_nwsvc_ids == [{"id": 6}] + assert removed_user_ids == [{"id": 7}] + assert removed_zone_ids == [{"id": 8}] + + +class TestFwConfigImportObjectUpdateObjectDiffs: + def test_update_object_diffs_no_normalized_config( + self, + fwconfig_import_object: FwConfigImportObject, + fw_config_manager: FwConfigManager, + ): + # Arrange + fwconfig_import_object.normalized_config = None + + # Act + with pytest.raises(FwoImporterError): + fwconfig_import_object.update_object_diffs( + prev_config=FwConfigNormalized(), + prev_global_config=None, + single_manager=fw_config_manager, + ) + + def test_update_object_diffs_changes_and_filters( + self, + fwconfig_import_object: FwConfigImportObject, + mocker: MockerFixture, + fw_config_manager: FwConfigManager, + fwconfig_builder: FwConfigBuilder, + ): + # Arrange: + prev_config, _ = fwconfig_builder.build_config( + network_object_count=10, + service_object_count=10, + rulebase_count=3, + rules_per_rulebase_count=10, + user_object_count=10, + zone_object_count=3, + ) + + curr_config = copy.deepcopy(prev_config) + + first_nwobj_uid = next(iter(prev_config.network_objects.keys())) + first_svcobj_uid = next(iter(prev_config.service_objects.keys())) + first_userobj_uid = next(iter(prev_config.users.keys())) + first_zone_name = next(iter(prev_config.zone_objects.keys())) + + first_nwobj = curr_config.network_objects[first_nwobj_uid] + first_svcobj = curr_config.service_objects[first_svcobj_uid] + first_userobj = curr_config.users[first_userobj_uid] + first_zoneobj = curr_config.zone_objects[first_zone_name] + + first_nwobj.obj_name = "modified-name" + first_svcobj.svc_name = "modified-name" + first_userobj["user_name"] = "modified-name" + first_zoneobj["zone_name"] = "modified-name" + + fwconfig_import_object.normalized_config = curr_config + + fwconfig_import_object.uid2id_mapper.update_network_object_mapping = mocker.Mock() + fwconfig_import_object.uid2id_mapper.update_service_object_mapping = mocker.Mock() + fwconfig_import_object.uid2id_mapper.update_user_mapping = mocker.Mock() + fwconfig_import_object.uid2id_mapper.update_zone_mapping = mocker.Mock() + fwconfig_import_object.uid2id_mapper.add_network_object_mappings = mocker.Mock() + fwconfig_import_object.uid2id_mapper.add_service_object_mappings = mocker.Mock() + fwconfig_import_object.uid2id_mapper.add_user_mappings = mocker.Mock() + fwconfig_import_object.uid2id_mapper.add_zone_mappings = mocker.Mock() + + fwconfig_import_object.remove_outdated_memberships = mocker.Mock() + fwconfig_import_object.add_group_memberships = mocker.Mock() + fwconfig_import_object.add_changelog_objs = mocker.Mock() + + fwconfig_import_object.update_objects_via_api = mocker.Mock( + return_value=( + [{"obj_id": 1}, {"obj_id": 2}], + [{"svc_id": 3}], + [], + [], + [{"obj_id": 10}, {"obj_id": 11}], + [{"svc_id": 30}], + [], + [], + ) + ) + + def fake_create_change_id_maps( + self: ChangeLogger, + _uid2id_mapper: Uid2IdMapper, + _changed_nw_objs: list[str], + _changed_svcs: list[str], + _removed_nw_objs: list[dict[str, Any]], + _removed_nw_svcs: list[dict[str, Any]], + ): + self.changed_object_id_map = {10: 1} + self.changed_service_id_map = {30: 3} + + mocker.patch.object(ChangeLogger, "create_change_id_maps", new=fake_create_change_id_maps) + + stats = fwconfig_import_object.import_state.state.stats + stats.increment_network_object_add_count = mocker.Mock() + stats.increment_network_object_delete_count = mocker.Mock() + stats.increment_network_object_change_count = mocker.Mock() + stats.increment_service_object_add_count = mocker.Mock() + stats.increment_service_object_delete_count = mocker.Mock() + stats.increment_service_object_change_count = mocker.Mock() + + # Act + fwconfig_import_object.update_object_diffs( + prev_config=prev_config, + prev_global_config=None, + single_manager=fw_config_manager, + ) + + # Assert: update_objects_via_api called with expected uid sets + args, _ = fwconfig_import_object.update_objects_via_api.call_args + assert args[0] is fw_config_manager + assert set(args[1]) == {first_nwobj_uid} + assert set(args[2]) == {first_svcobj_uid} + assert set(args[3]) == {first_userobj_uid} + assert set(args[4]) == {first_zone_name} + assert set(args[5]) == {first_nwobj_uid} + assert set(args[6]) == {first_svcobj_uid} + assert set(args[7]) == {first_userobj_uid} + assert set(args[8]) == {first_zone_name} + + assert fwconfig_import_object.remove_outdated_memberships.call_count == 3 + assert fwconfig_import_object.add_group_memberships.call_count == 3 + + fwconfig_import_object.add_changelog_objs.assert_called_once_with( + [{"obj_id": 2}], + [], + [{"obj_id": 11}], + [], + ) + + stats.increment_network_object_add_count.assert_called_once_with(1) + stats.increment_network_object_delete_count.assert_called_once_with(1) + stats.increment_network_object_change_count.assert_called_once_with(1) + stats.increment_service_object_add_count.assert_called_once_with(0) + stats.increment_service_object_delete_count.assert_called_once_with(0) + stats.increment_service_object_change_count.assert_called_once_with(1) diff --git a/roles/importer/files/importer/test/test_fwconfig_import_rule.py b/roles/importer/files/importer/test/test_fwconfig_import_rule.py new file mode 100644 index 0000000000..3636ea81d1 --- /dev/null +++ b/roles/importer/files/importer/test/test_fwconfig_import_rule.py @@ -0,0 +1,76 @@ +from model_controllers.fwconfig_import_rule import FwConfigImportRule +from pytest_mock import MockerFixture +from test.utils.test_utils import mock_get_graphql_code + + +class TestFwConfigImportRule: + def test_write_changelog_rules_changed_rule_writes_new_and_old_ids( + self, + fwconfig_import_rule: FwConfigImportRule, + mocker: MockerFixture, + ): + # Arrange + mock_get_graphql_code(mocker, "mutation { dummy }") + + rule_uid = "changed-rule-uid" + old_rule_id = 101 + new_rule_id = 202 + + def get_rule_id_side_effect(_uid: str, before_update: bool = False) -> int: + return old_rule_id if before_update else new_rule_id + + fwconfig_import_rule.uid2id_mapper.get_rule_id = mocker.Mock(side_effect=get_rule_id_side_effect) + fwconfig_import_rule.is_change_security_relevant = mocker.Mock(return_value=True) + fwconfig_import_rule.import_details.api_call.call = mocker.Mock(return_value={"data": {}}) + + old_rule = mocker.Mock(rule_uid=rule_uid) + new_rule = mocker.Mock(rule_uid=rule_uid) + + # Act + fwconfig_import_rule.write_changelog_rules( + added_rules=[], + removed_rules=[], + changed_rules=[(old_rule, new_rule)], + ) + + # Assert + fwconfig_import_rule.import_details.api_call.call.assert_called_once() + query_variables = fwconfig_import_rule.import_details.api_call.call.call_args.kwargs["query_variables"] + rule_changes = query_variables["rule_changes"] + + assert len(rule_changes) == 1 + assert rule_changes[0]["change_action"] == "C" + assert rule_changes[0]["new_rule_id"] == new_rule_id + assert rule_changes[0]["old_rule_id"] == old_rule_id + + def test_write_changelog_rules_uses_current_mgm_id_for_sub_management( + self, + fwconfig_import_rule: FwConfigImportRule, + mocker: MockerFixture, + ): + # Arrange + mock_get_graphql_code(mocker, "mutation { dummy }") + + fwconfig_import_rule.import_details.state.mgm_details.mgm_id = 3 + fwconfig_import_rule.import_details.state.mgm_details.current_mgm_id = 7 + fwconfig_import_rule.uid2id_mapper.get_rule_id = mocker.Mock(return_value=202) + fwconfig_import_rule.import_details.api_call.call = mocker.Mock(return_value={"data": {}}) + + added_rule = mocker.Mock(rule_uid="added-rule-uid") + + # Act + fwconfig_import_rule.write_changelog_rules( + added_rules=[added_rule], + removed_rules=[], + changed_rules=[], + ) + + # Assert + fwconfig_import_rule.import_details.api_call.call.assert_called_once() + query_variables = fwconfig_import_rule.import_details.api_call.call.call_args.kwargs["query_variables"] + rule_changes = query_variables["rule_changes"] + + assert len(rule_changes) == 1 + assert rule_changes[0]["change_action"] == "I" + assert rule_changes[0]["mgm_id"] == fwconfig_import_rule.import_details.state.mgm_details.current_mgm_id + assert rule_changes[0]["mgm_id"] != fwconfig_import_rule.import_details.state.mgm_details.mgm_id diff --git a/roles/importer/files/importer/test/test_fwconfig_import_rule_refs.py b/roles/importer/files/importer/test/test_fwconfig_import_rule_refs.py new file mode 100644 index 0000000000..4925b094f5 --- /dev/null +++ b/roles/importer/files/importer/test/test_fwconfig_import_rule_refs.py @@ -0,0 +1,106 @@ +import unittest.mock + +import pytest +from fwo_api import FwoApi +from fwo_api_call import FwoApiCall +from model_controllers.fwconfig_import_rule import FwConfigImportRule, RefType +from model_controllers.import_state_controller import ImportStateController +from model_controllers.management_controller import ManagementController +from models.import_state import ImportState +from models.rule import RuleAction, RuleNormalized, RuleTrack, RuleType +from services.uid2id_mapper import Uid2IdMapper + + +def build_rule(rule_uid: str) -> RuleNormalized: + return RuleNormalized( + rule_num=1, + rule_num_numeric=1.0, + rule_disabled=False, + rule_src_neg=False, + rule_src="src", + rule_src_refs="src", + rule_dst_neg=False, + rule_dst="dst", + rule_dst_refs="dst", + rule_svc_neg=False, + rule_svc="svc", + rule_svc_refs="svc", + rule_src_zone="src_zone", + rule_dst_zone="dst_zone", + rule_time="time", + rule_action=RuleAction.ACCEPT, + rule_track=RuleTrack.NONE, + rule_implied=False, + rule_type=RuleType.ACCESS, + rule_uid=rule_uid, + ) + + +@pytest.fixture +def import_state_controller( + management_controller: ManagementController, + api_call: FwoApiCall, + api_connection: FwoApi, +) -> ImportStateController: + import_state = ImportState() + import_state.mgm_details = management_controller + controller = ImportStateController(state=import_state, api_call=api_call) + controller.state = import_state + controller.api_call = api_call + controller.api_connection = api_connection + return controller + + +class TestFwconfigImportRuleRefs: + def test_get_outdated_refs_to_remove_removes_all_on_missing_rule( + self, + uid2id_mapper: Uid2IdMapper, + fwconfig_import_rule: FwConfigImportRule, + ): + prev_rule = build_rule("rule-1") + + fake_refs = { + RefType.SRC: [("src", None)], + RefType.DST: [("dst", "user")], + RefType.SVC: ["svc"], + RefType.NWOBJ_RESOLVED: ["src", "dst"], + RefType.SVC_RESOLVED: ["svc"], + RefType.USER_RESOLVED: ["user"], + RefType.SRC_ZONE: ["src_zone"], + RefType.DST_ZONE: ["dst_zone"], + RefType.TIME: ["time"], + } + + uid2id_mapper.get_rule_id = unittest.mock.MagicMock(return_value=100) + + def _get_network_object_id(uid: str, before_update: bool = True) -> int: # noqa: ARG001 + return {"src": 10, "dst": 11}[uid] + + def _get_zone_object_id(uid: str, before_update: bool = True) -> int: # noqa: ARG001 + return {"src_zone": 40, "dst_zone": 41}[uid] + + uid2id_mapper.get_network_object_id = unittest.mock.MagicMock(side_effect=_get_network_object_id) + uid2id_mapper.get_user_id = unittest.mock.MagicMock(return_value=30) + uid2id_mapper.get_service_object_id = unittest.mock.MagicMock(return_value=20) + uid2id_mapper.get_zone_object_id = unittest.mock.MagicMock(side_effect=_get_zone_object_id) + uid2id_mapper.get_time_object_id = unittest.mock.MagicMock(return_value=50) + + fwconfig_import_rule.get_rule_refs = unittest.mock.MagicMock( + return_value=fake_refs, + ) + refs_to_remove = fwconfig_import_rule.get_outdated_refs_to_remove(prev_rule, None, remove_all=True) + + assert { + "_and": [{"rule_id": {"_eq": 100}}, {"obj_id": {"_eq": 10}}, {"user_id": {"_is_null": True}}] + } in refs_to_remove[RefType.SRC] + assert { + "_and": [{"rule_id": {"_eq": 100}}, {"obj_id": {"_eq": 11}}, {"user_id": {"_eq": 30}}] + } in refs_to_remove[RefType.DST] + assert {"_and": [{"rule_id": {"_eq": 100}}, {"svc_id": {"_eq": 20}}]} in refs_to_remove[RefType.SVC] + assert {"_and": [{"rule_id": {"_eq": 100}}, {"obj_id": {"_eq": 10}}]} in refs_to_remove[RefType.NWOBJ_RESOLVED] + assert {"_and": [{"rule_id": {"_eq": 100}}, {"obj_id": {"_eq": 11}}]} in refs_to_remove[RefType.NWOBJ_RESOLVED] + assert {"_and": [{"rule_id": {"_eq": 100}}, {"svc_id": {"_eq": 20}}]} in refs_to_remove[RefType.SVC_RESOLVED] + assert {"_and": [{"rule_id": {"_eq": 100}}, {"user_id": {"_eq": 30}}]} in refs_to_remove[RefType.USER_RESOLVED] + assert {"_and": [{"rule_id": {"_eq": 100}}, {"zone_id": {"_eq": 40}}]} in refs_to_remove[RefType.SRC_ZONE] + assert {"_and": [{"rule_id": {"_eq": 100}}, {"zone_id": {"_eq": 41}}]} in refs_to_remove[RefType.DST_ZONE] + assert {"_and": [{"rule_id": {"_eq": 100}}, {"time_obj_id": {"_eq": 50}}]} in refs_to_remove[RefType.TIME] diff --git a/roles/importer/files/importer/test/test_fwconfig_import_ruleorder.py b/roles/importer/files/importer/test/test_fwconfig_import_ruleorder.py new file mode 100644 index 0000000000..d38cb7f72d --- /dev/null +++ b/roles/importer/files/importer/test/test_fwconfig_import_ruleorder.py @@ -0,0 +1,386 @@ +# pyright: reportPrivateUsage=false + +import copy + +from fwo_const import RULE_NUM_NUMERIC_STEPS +from model_controllers.fwconfig_import_ruleorder import update_rule_order_diffs +from test.utils.config_builder import FwConfigBuilder +from test.utils.rule_helper_functions import ( + get_rule, + insert_rule_in_config, + move_rule_in_config, + remove_rule_from_rulebase, +) + + +class TestFwConfigImportRuleOrderOldMigration: + def test_initialize_on_insert_delete_and_move( + self, + fwconfig_builder: FwConfigBuilder, + ): + # Arrange + normalized_config, _ = fwconfig_builder.build_config( + network_object_count=10, + service_object_count=10, + rulebase_count=3, + rules_per_rulebase_count=10, + ) + + previous_config = copy.deepcopy(normalized_config) + fwconfig_builder.initialize_rule_num_numerics(previous_config) + + rulebase = normalized_config.rulebases[0] + rule_uids = list(rulebase.rules.keys()) + removed_rule_uid = rule_uids[0] + + remove_rule_from_rulebase(normalized_config, rulebase.uid, removed_rule_uid, rule_uids) + inserted_rule_uid = insert_rule_in_config(normalized_config, rulebase.uid, 0, rule_uids, fwconfig_builder) + + moved_rule_uid = move_rule_in_config(normalized_config, rulebase.uid, 9, 0, rule_uids) + # Act + update_rule_order_diffs(normalized_config=normalized_config, previous_config=previous_config) + + last_rule_uid = list(normalized_config.rulebases[0].rules.keys())[-1] + + # Assert + assert inserted_rule_uid is not None + assert moved_rule_uid is not None + insert_rule = get_rule(normalized_config, 0, inserted_rule_uid) + assert insert_rule is not None + + moved_rule = get_rule(normalized_config, 0, moved_rule_uid) + assert moved_rule is not None + + assert moved_rule.rule_num_numeric == RULE_NUM_NUMERIC_STEPS, ( + f"Moved rule_num_numeric is {normalized_config.rulebases[0].rules[inserted_rule_uid].rule_num_numeric}, expected {RULE_NUM_NUMERIC_STEPS}" + ) + + assert insert_rule.rule_num_numeric == 3 * RULE_NUM_NUMERIC_STEPS / 2, ( + f"Inserted rule_num_numeric is {normalized_config.rulebases[0].rules[moved_rule_uid].rule_num_numeric}, expected {RULE_NUM_NUMERIC_STEPS / 2}" + ) + + assert last_rule_uid is not None + last_rule = get_rule(normalized_config, 0, last_rule_uid) + assert last_rule is not None + expected_last_rule_num_numeric = 9 * RULE_NUM_NUMERIC_STEPS + assert last_rule.rule_num_numeric == expected_last_rule_num_numeric, ( + f"Last rule_num_numeric is {normalized_config.rulebases[0].rules[last_rule_uid].rule_num_numeric}, expected {expected_last_rule_num_numeric}" + ) + + def test_initialize_on_consecutive_insertions( + self, + fwconfig_builder: FwConfigBuilder, + ): + # Arrange + normalized_config, _ = fwconfig_builder.build_config( + network_object_count=10, + service_object_count=10, + rulebase_count=3, + rules_per_rulebase_count=10, + ) + previous_config = copy.deepcopy(normalized_config) + fwconfig_builder.initialize_rule_num_numerics(previous_config) + + assert normalized_config is not None + rulebase = normalized_config.rulebases[0] + rule_uids = list(rulebase.rules.keys()) + + # Inserting three new rules at the beginning of the rulebase + rule_1_1_uid = insert_rule_in_config(normalized_config, rulebase.uid, 0, rule_uids, fwconfig_builder) + rule_1_2_uid = insert_rule_in_config(normalized_config, rulebase.uid, 1, rule_uids, fwconfig_builder) + rule_1_3_uid = insert_rule_in_config(normalized_config, rulebase.uid, 2, rule_uids, fwconfig_builder) + + # Inserting three new rules in the middle of the rulebase + rule_1_6_uid = insert_rule_in_config(normalized_config, rulebase.uid, 5, rule_uids, fwconfig_builder) + rule_1_7_uid = insert_rule_in_config(normalized_config, rulebase.uid, 6, rule_uids, fwconfig_builder) + rule_1_8_uid = insert_rule_in_config(normalized_config, rulebase.uid, 7, rule_uids, fwconfig_builder) + + # Inserting three new rules at the end of the rulebase + rule_1_17_uid = insert_rule_in_config(normalized_config, rulebase.uid, 16, rule_uids, fwconfig_builder) + rule_1_18_uid = insert_rule_in_config(normalized_config, rulebase.uid, 17, rule_uids, fwconfig_builder) + rule_1_19_uid = insert_rule_in_config(normalized_config, rulebase.uid, 18, rule_uids, fwconfig_builder) + + # Act + + update_rule_order_diffs(normalized_config=normalized_config, previous_config=previous_config) + + # Assert + assert rule_1_1_uid is not None + rule_1_1 = get_rule(normalized_config, 0, rule_1_1_uid) + assert rule_1_1 is not None + assert rule_1_1.rule_num_numeric == RULE_NUM_NUMERIC_STEPS / 2, ( + f"Rule 1.1 rule_num_numeric: {rule_1_1.rule_num_numeric}, expected {RULE_NUM_NUMERIC_STEPS / 2}" + ) + assert rule_1_2_uid is not None + rule_1_2 = get_rule(normalized_config, 0, rule_1_2_uid) + assert rule_1_2 is not None + assert rule_1_2.rule_num_numeric == 3 * RULE_NUM_NUMERIC_STEPS / 4, ( + f"Rule 1.2 rule_num_numeric: {rule_1_2.rule_num_numeric}, expected {3 * RULE_NUM_NUMERIC_STEPS / 4}" + ) + + assert rule_1_3_uid is not None + rule_1_3 = get_rule(normalized_config, 0, rule_1_3_uid) + assert rule_1_3 is not None + assert rule_1_3.rule_num_numeric == 7 * RULE_NUM_NUMERIC_STEPS / 8, ( + f"Rule 1.3 rule_num_numeric: {rule_1_3.rule_num_numeric}, expected {7 * RULE_NUM_NUMERIC_STEPS / 8}" + ) + + assert rule_1_6_uid is not None + rule_1_6 = get_rule(normalized_config, 0, rule_1_6_uid) + assert rule_1_6 is not None + assert rule_1_6.rule_num_numeric == 5 * RULE_NUM_NUMERIC_STEPS / 2, ( + f"Rule 1.6 rule_num_numeric: {rule_1_6.rule_num_numeric}, expected {5 * RULE_NUM_NUMERIC_STEPS / 2}" + ) + assert rule_1_7_uid is not None + rule_1_7 = get_rule(normalized_config, 0, rule_1_7_uid) + assert rule_1_7 is not None + assert rule_1_7.rule_num_numeric == 11 * RULE_NUM_NUMERIC_STEPS / 4, ( + f"Rule 1.7 rule_num_numeric: {rule_1_7.rule_num_numeric}, expected {11 * RULE_NUM_NUMERIC_STEPS / 4}" + ) + assert rule_1_8_uid is not None + rule_1_8 = get_rule(normalized_config, 0, rule_1_8_uid) + assert rule_1_8 is not None + assert rule_1_8.rule_num_numeric == 23 * RULE_NUM_NUMERIC_STEPS / 8, ( + f"Rule 1.8 rule_num_numeric: {rule_1_8.rule_num_numeric}, expected {23 * RULE_NUM_NUMERIC_STEPS / 8}" + ) + + assert rule_1_17_uid is not None + rule_1_17 = get_rule(normalized_config, 0, rule_1_17_uid) + assert rule_1_17 is not None + assert rule_1_17.rule_num_numeric == 11 * RULE_NUM_NUMERIC_STEPS, ( + f"Rule 1.17 rule_num_numeric: {rule_1_17.rule_num_numeric}, expected {11 * RULE_NUM_NUMERIC_STEPS}" + ) + assert rule_1_18_uid is not None + rule_1_18 = get_rule(normalized_config, 0, rule_1_18_uid) + assert rule_1_18 is not None + assert rule_1_18.rule_num_numeric == 12 * RULE_NUM_NUMERIC_STEPS, ( + f"Rule 1.18 rule_num_numeric: {rule_1_18.rule_num_numeric}, expected {12 * RULE_NUM_NUMERIC_STEPS}" + ) + assert rule_1_19_uid is not None + rule_1_19 = get_rule(normalized_config, 0, rule_1_19_uid) + assert rule_1_19 is not None + assert rule_1_19.rule_num_numeric == 13 * RULE_NUM_NUMERIC_STEPS, ( + f"Rule 1.19 rule_num_numeric: {rule_1_19.rule_num_numeric}, expected {13 * RULE_NUM_NUMERIC_STEPS}" + ) + + def test_initialize_on_move_across_rulebases( + self, + fwconfig_builder: FwConfigBuilder, + ): + # Arrange + normalized_config, _ = fwconfig_builder.build_config( + network_object_count=10, + service_object_count=10, + rulebase_count=3, + rules_per_rulebase_count=10, + ) + + previous_config = copy.deepcopy(normalized_config) + fwconfig_builder.initialize_rule_num_numerics(previous_config) + + assert normalized_config is not None + source_rulebase = normalized_config.rulebases[0] + source_rulebase_uids = list(source_rulebase.rules.keys()) + target_rulebase = normalized_config.rulebases[1] + target_rulebase_uids = list(target_rulebase.rules.keys()) + deleted_rule = remove_rule_from_rulebase( + normalized_config, source_rulebase.uid, source_rulebase_uids[0], source_rulebase_uids + ) + insert_rule_in_config( + normalized_config, + target_rulebase.uid, + 0, + target_rulebase_uids, + fwconfig_builder, + deleted_rule, + ) + # Act + + update_rule_order_diffs(normalized_config=normalized_config, previous_config=previous_config) # Assert + assert deleted_rule.rule_uid is not None + rule = get_rule(normalized_config, 1, deleted_rule.rule_uid) + assert rule is not None + assert rule.rule_num_numeric == RULE_NUM_NUMERIC_STEPS / 2, ( + f"Moved rule_num_numeric is {normalized_config.rulebases[1].rules[deleted_rule.rule_uid].rule_num_numeric}, expected {RULE_NUM_NUMERIC_STEPS / 2}" + ) + + def test_update_rulebase_diffs_on_moves_to_beginning_middle_and_end_of_rulebase( + self, + fwconfig_builder: FwConfigBuilder, + ): + # Arrange + normalized_config, _ = fwconfig_builder.build_config( + network_object_count=10, + service_object_count=10, + rulebase_count=3, + rules_per_rulebase_count=10, + ) + + previous_config = copy.deepcopy(normalized_config) + fwconfig_builder.initialize_rule_num_numerics(previous_config) + + rulebase = normalized_config.rulebases[0] + rule_uids = list(rulebase.rules.keys()) + + beginning_rule_uid = move_rule_in_config(normalized_config, rulebase.uid, 5, 0, rule_uids) # Move to beginning + middle_rule_uid = move_rule_in_config(normalized_config, rulebase.uid, 1, 4, rule_uids) # Move to middle + end_rule_uid = move_rule_in_config(normalized_config, rulebase.uid, 2, 9, rule_uids) # Move to end + + # Act + + update_rule_order_diffs(normalized_config=normalized_config, previous_config=previous_config) + + # Assert + assert beginning_rule_uid is not None + beginning_rule = get_rule(normalized_config, 0, beginning_rule_uid) + assert beginning_rule is not None + assert beginning_rule.rule_num_numeric == RULE_NUM_NUMERIC_STEPS, ( + f"Beginning moved rule_num_numeric is {normalized_config.rulebases[0].rules[beginning_rule_uid].rule_num_numeric}, expected {RULE_NUM_NUMERIC_STEPS / 2}" + ) + + assert middle_rule_uid is not None + middle_rule = get_rule(normalized_config, 0, middle_rule_uid) + assert middle_rule is not None + assert middle_rule.rule_num_numeric == 4608, ( + f"Middle moved rule_num_numeric is {normalized_config.rulebases[0].rules[middle_rule_uid].rule_num_numeric}, expected 4608" + ) + assert end_rule_uid is not None + end_rule = get_rule(normalized_config, 0, end_rule_uid) + assert end_rule is not None + assert end_rule.rule_num_numeric == 11 * RULE_NUM_NUMERIC_STEPS, ( + f"End moved rule_num_numeric is {normalized_config.rulebases[0].rules[end_rule_uid].rule_num_numeric}, expected {11 * RULE_NUM_NUMERIC_STEPS}" + ) + + def test_update_rulebase_diffs_multiple_on_same_spot( + self, + fwconfig_builder: FwConfigBuilder, + ): + # Arrange + normalized_config, _ = fwconfig_builder.build_config( + network_object_count=10, + service_object_count=10, + rulebase_count=3, + rules_per_rulebase_count=10, + ) + + previous_config = copy.deepcopy(normalized_config) + fwconfig_builder.initialize_rule_num_numerics(previous_config) + + rulebase = normalized_config.rulebases[0] + rule_uids = list(rulebase.rules.keys()) + # Move rule 5 to position 0, then move rule 6 (which is now at position 6) to position 0 as well and insert a new rule at position 0 + rule_1_uid = insert_rule_in_config(normalized_config, rulebase.uid, 5, rule_uids, fwconfig_builder) + rule_2_uid = insert_rule_in_config(normalized_config, rulebase.uid, 5, rule_uids, fwconfig_builder) + rule_3_uid = insert_rule_in_config(normalized_config, rulebase.uid, 5, rule_uids, fwconfig_builder) + rule_4_uid = insert_rule_in_config(normalized_config, rulebase.uid, 5, rule_uids, fwconfig_builder) + + # Act + + update_rule_order_diffs(normalized_config=normalized_config, previous_config=previous_config) + + # Assert + for i in range(5): + rule = get_rule(normalized_config, 0, rule_uids[i]) + assert rule is not None + expected_rule_num_numeric = (i + 1) * RULE_NUM_NUMERIC_STEPS + assert rule.rule_num_numeric == expected_rule_num_numeric, ( + f"Rule at position {i} has rule_num_numeric {rule.rule_num_numeric}, expected {expected_rule_num_numeric}" + ) + + assert rule_uids[5] == rule_4_uid + assert rule_4_uid is not None + rule_4 = get_rule(normalized_config, 0, rule_4_uid) + assert rule_4 is not None + assert rule_4.rule_num_numeric == 11 * RULE_NUM_NUMERIC_STEPS / 2, ( + f"Rule 4 rule_num_numeric is {normalized_config.rulebases[0].rules[rule_4_uid].rule_num_numeric}, expected {11 * RULE_NUM_NUMERIC_STEPS / 2}" + ) + + assert rule_uids[6] == rule_3_uid + assert rule_3_uid is not None + rule_3 = get_rule(normalized_config, 0, rule_3_uid) + assert rule_3 is not None + assert rule_3.rule_num_numeric == 23 * RULE_NUM_NUMERIC_STEPS / 4, ( + f"Rule 3 rule_num_numeric is {normalized_config.rulebases[0].rules[rule_3_uid].rule_num_numeric}, expected {23 * RULE_NUM_NUMERIC_STEPS / 4}" + ) + + assert rule_uids[7] == rule_2_uid + assert rule_2_uid is not None + rule_2 = get_rule(normalized_config, 0, rule_2_uid) + assert rule_2 is not None + assert rule_2.rule_num_numeric == 47 * RULE_NUM_NUMERIC_STEPS / 8, ( + f"Rule 2 rule_num_numeric is {normalized_config.rulebases[0].rules[rule_2_uid].rule_num_numeric}, expected {47 * RULE_NUM_NUMERIC_STEPS / 8}" + ) + + assert rule_uids[8] == rule_1_uid + assert rule_1_uid is not None + rule_1 = get_rule(normalized_config, 0, rule_1_uid) + assert rule_1 is not None + assert rule_1.rule_num_numeric == 95 * RULE_NUM_NUMERIC_STEPS / 16, ( + f"Rule 1 rule_num_numeric is {normalized_config.rulebases[0].rules[rule_1_uid].rule_num_numeric}, expected {95 * RULE_NUM_NUMERIC_STEPS / 16}" + ) + + def test_update_rulebase_diffs_on_no_changes( + self, + fwconfig_builder: FwConfigBuilder, + ): + # Arrange + normalized_config, _ = fwconfig_builder.build_config( + network_object_count=10, + service_object_count=10, + rulebase_count=3, + rules_per_rulebase_count=10, + ) + + previous_config = copy.deepcopy(normalized_config) + fwconfig_builder.initialize_rule_num_numerics(previous_config) + + # Act + + update_rule_order_diffs(normalized_config=normalized_config, previous_config=previous_config) + + # Assert - rule_num_numeric values should remain unchanged + for rulebase in normalized_config.rulebases: + for rule_uid, rule in rulebase.rules.items(): + previous_rule = next( + (r for rb in previous_config.rulebases for r_uid, r in rb.rules.items() if r_uid == rule_uid), None + ) + assert previous_rule is not None + assert rule.rule_num_numeric == previous_rule.rule_num_numeric, ( + f"Rule {rule_uid} has rule_num_numeric {rule.rule_num_numeric}, expected {previous_rule.rule_num_numeric}" + ) + + def test_update_rulebase_diffs_on_all_rules_moved( + self, + fwconfig_builder: FwConfigBuilder, + ): + # Arrange + normalized_config, _ = fwconfig_builder.build_config( + network_object_count=10, + service_object_count=10, + rulebase_count=3, + rules_per_rulebase_count=10, + ) + + previous_config = copy.deepcopy(normalized_config) + fwconfig_builder.initialize_rule_num_numerics(previous_config) + + rulebase = normalized_config.rulebases[0] + rule_uids = list(rulebase.rules.keys()) + # Move all rules down by one position, last rule goes to position 0 + for i in range(len(rule_uids)): + move_rule_in_config(normalized_config, rulebase.uid, i, (i + 1) % len(rule_uids), rule_uids) + + # Act + + update_rule_order_diffs(normalized_config=normalized_config, previous_config=previous_config) + + # Assert - all rules should have the same rule_num_numeric as before since the order is the same just rotated + for rulebase in normalized_config.rulebases: + for rule_uid, rule in rulebase.rules.items(): + previous_rule = next( + (r for rb in previous_config.rulebases for r_uid, r in rb.rules.items() if r_uid == rule_uid), None + ) + assert previous_rule is not None + assert rule.rule_num_numeric == previous_rule.rule_num_numeric, ( + f"Rule {rule_uid} has rule_num_numeric {rule.rule_num_numeric}, expected {previous_rule.rule_num_numeric}" + ) diff --git a/roles/importer/files/importer/test/test_fwo_base.py b/roles/importer/files/importer/test/test_fwo_base.py new file mode 100644 index 0000000000..8b6ca78095 --- /dev/null +++ b/roles/importer/files/importer/test/test_fwo_base.py @@ -0,0 +1,73 @@ +from fwo_base import compute_min_moves + + +def test_compute_min_moves_on_insert(): + # arrange + source_sequence = ["element a", "element b", "element c"] + target_sequence = list(source_sequence) + new_element = "element d" + insert_position = 2 + target_sequence.insert(insert_position, new_element) + expected_result = { + "moves": 1, + "insertions": [(insert_position, new_element)], + "deletions": [], + "reposition_moves": [], + } + + # act + compute_min_moves_result = compute_min_moves(source_sequence, target_sequence) + + # assert + assert compute_min_moves_result["moves"] == expected_result["moves"] + assert compute_min_moves_result["insertions"] == expected_result["insertions"] + assert compute_min_moves_result["deletions"] == expected_result["deletions"] + assert compute_min_moves_result["reposition_moves"] == expected_result["reposition_moves"] + + +def test_compute_min_moves_on_delete(): + # arrange + source_sequence = ["element a", "element c"] + target_sequence = list(source_sequence) + delete_position = 1 + deleted_element = target_sequence.pop(delete_position) + expected_result = { + "moves": 1, + "insertions": [], + "deletions": [(delete_position, deleted_element)], + "reposition_moves": [], + } + + # act + compute_min_moves_result = compute_min_moves(source_sequence, target_sequence) + + # assert + assert compute_min_moves_result["moves"] == expected_result["moves"] + assert compute_min_moves_result["insertions"] == expected_result["insertions"] + assert compute_min_moves_result["deletions"] == expected_result["deletions"] + assert compute_min_moves_result["reposition_moves"] == expected_result["reposition_moves"] + + +def test_compute_min_moves_on_move(): + # arrange + source_sequence = ["element a", "element b", "element c"] + target_sequence = list(source_sequence) + move_source_position = 2 + move_target_position = 1 + moved_element = target_sequence.pop(move_source_position) + target_sequence.insert(move_target_position, moved_element) + expected_result = { + "moves": 1, + "insertions": [], + "deletions": [], + "reposition_moves": [(move_source_position, moved_element, move_target_position)], + } + + # act + compute_min_moves_result = compute_min_moves(source_sequence, target_sequence) + + # assert + assert compute_min_moves_result["moves"] == expected_result["moves"] + assert compute_min_moves_result["insertions"] == expected_result["insertions"] + assert compute_min_moves_result["deletions"] == expected_result["deletions"] + assert compute_min_moves_result["reposition_moves"] == expected_result["reposition_moves"] diff --git a/roles/importer/files/importer/test/test_import_main_loop.py b/roles/importer/files/importer/test/test_import_main_loop.py new file mode 100644 index 0000000000..5b3cc23c5a --- /dev/null +++ b/roles/importer/files/importer/test/test_import_main_loop.py @@ -0,0 +1,178 @@ +import fwo_globals +import pytest +from fwo_api_call import FwoApiCall +from fwo_exceptions import FwoApiLoginFailedError +from model_controllers.import_state_controller import ImportStateController +from model_controllers.management_controller import ManagementController +from pytest_mock.plugin import MockerFixture +from test.data.mock_objects import MockObjectsFactory +from test.utils.test_utils import mock_get_graphql_code, mock_login + +from importer.import_main_loop import ( + get_fwo_jwt, + import_single_management, + wait_with_shutdown_check, +) + + +class TestGetFwoJwt: + def test_get_fwo_jwt_success( + self, + mocker: MockerFixture, + ): + # Arrange + expected_value = "mocked_value" + mock_login(mocker, return_value=expected_value) + + # Act + jwt_token = get_fwo_jwt("mocked_username", "", "mocked_mgm_api") + + # Assert + assert jwt_token == expected_value + + def test_get_fwo_jwt_failure( + self, + mocker: MockerFixture, + ): + # Arrange + mock_logger = mocker.patch("fwo_log.FWOLogger.error") + side_effect = FwoApiLoginFailedError("Login failed") + mock_login(mocker, side_effect=side_effect) + + # Act + jwt_token = get_fwo_jwt("mocked_username", "", "mocked_mgm_api") + + # Assert + assert jwt_token is None + call_args = mock_logger.call_args[0][0] + assert call_args == "Login failed" + + def test_get_fwo_jwt_unexpected_exception( + self, + mocker: MockerFixture, + ): + # Arrange + mock_logger = mocker.patch("fwo_log.FWOLogger.error") + mock_login(mocker, side_effect=Exception("Unexpected error")) + + # Act & Assert + jwt_token = get_fwo_jwt("mocked_username", "", "mocked_mgm_api") + + # Assert + assert jwt_token is None + logged_error_message = mock_logger.call_args[0][0] + assert logged_error_message.startswith( + "import_main_loop - unspecified error during FWO API login - skipping: Traceback" + ) + + +class TestWaitWithShutdownCheck: + def test_wait_completes_without_shutdown( + self, + mocker: MockerFixture, + ): + # Arrange + mock_sleep = mocker.patch("import_main_loop.time.sleep") + mock_logger = mocker.patch("fwo_log.FWOLogger") + fwo_globals.shutdown_requested = False + + sleep_duration = 3 + + # Execute + wait_with_shutdown_check(sleep_duration) + + # Assert + assert mock_sleep.call_count == sleep_duration + mock_logger.info.assert_not_called() + + def test_shutdown_requested_immediately( + self, + mocker: MockerFixture, + ): + # Arrange + mock_sleep = mocker.patch("importer.import_main_loop.time.sleep") + mock_logger = mocker.patch("importer.import_main_loop.FWOLogger") + fwo_globals.shutdown_requested = True + + # Act + with pytest.raises(SystemExit) as excinfo: + wait_with_shutdown_check(5) + + # Assert + assert "shutdown requested" in str(excinfo.value) + mock_sleep.assert_not_called() + mock_logger.info.assert_called_once() + + def test_shutdown_requested_during_loop( + self, + mocker: MockerFixture, + ): + # Arrange + mock_sleep = mocker.patch("importer.import_main_loop.time.sleep") + mock_logger = mocker.patch("importer.import_main_loop.FWOLogger") + fwo_globals.shutdown_requested = False + + def side_effect_simulating_external_shutdown(_: int): + if mock_sleep.call_count >= 2: + fwo_globals.shutdown_requested = True + + mock_sleep.side_effect = side_effect_simulating_external_shutdown + + # Act + with pytest.raises(SystemExit) as excinfo: + wait_with_shutdown_check(10) # Requesting 10 seconds + + # Assert + assert "shutdown requested" in str(excinfo.value) + assert mock_sleep.call_count == 2 + mock_logger.info.assert_called_once() + + +class TestImportSingleManagement: + def test_import_single_management_calls_wait_with_shutdown_check( + self, + mocker: MockerFixture, + import_state_controller: ImportStateController, + api_call: FwoApiCall, + ): + # Arrange + mock_wait = mocker.patch("importer.import_main_loop.wait_with_shutdown_check") + mock_initialize_import = mocker.patch.object( + ImportStateController, + "initialize_import", + return_value=import_state_controller, + ) + mock_register_global_state = mocker.patch("importer.import_main_loop.register_global_state") + mock_get_graphql_code(mocker, return_value={"data": {"jwt": "mocked_jwt"}}) + mock_get_mgm_details = mocker.patch.object( + ManagementController, + "get_mgm_details", + return_value=MockObjectsFactory.get_mock_mgm_details(), + ) + + # Act + import_single_management( + mgm_id=1, + fwo_api_call=api_call, + verify_certificates=True, + api_fetch_limit=100, + clear=False, + suppress_certificate_warnings=False, + force=False, + fwo_major_version=9, + sleep_timer=0, + ) + + # Assert + mock_wait.assert_called_with(0) + mock_get_mgm_details.assert_called_once() + mock_initialize_import.assert_called_once_with( + mgm_id=1, + api_call=api_call, + suppress_cert_warnings=False, + ssl_verification=True, + force=False, + version=9, + is_clearing_import=False, + ) + mock_register_global_state.assert_called_once_with(import_state_controller) diff --git a/roles/importer/files/importer/test/test_import_state_controller.py b/roles/importer/files/importer/test/test_import_state_controller.py new file mode 100644 index 0000000000..7a8088b76b --- /dev/null +++ b/roles/importer/files/importer/test/test_import_state_controller.py @@ -0,0 +1,260 @@ +import pytest +from fwo_api import FwoApi +from fwo_api_call import FwoApiCall +from fwo_exceptions import FwoImporterError +from model_controllers.fwconfig_import_object import FwConfigImportObject +from model_controllers.import_state_controller import ImportStateController +from model_controllers.management_controller import ManagementController +from models.import_state import ImportState +from pytest_mock import MockerFixture + + +@pytest.fixture +def import_state_controller( + management_controller: ManagementController, + api_call: FwoApiCall, + api_connection: FwoApi, +) -> ImportStateController: + import_state = ImportState() + import_state.mgm_details = management_controller + import_state.tracks = {"ordered": 2, "inline": 3, "concatenated": 4, "domain": 5} + import_state.link_types = { + "ordered": 2, + "inline": 3, + "concatenated": 4, + "domain": 5, + } + controller = ImportStateController(state=import_state, api_call=api_call) + controller.state = import_state + controller.api_call = api_call + controller.api_connection = api_connection + return controller + + +class TestFwConfigImportObjectGetProtocolMap: + def test_get_protocol_map( + self, + fwconfig_import_object: FwConfigImportObject, + import_state_controller: ImportStateController, + mocker: MockerFixture, + ): + # Arrange + fwconfig_import_object.import_state.api_call.call = mocker.Mock( + return_value={ + "data": { + "stm_ip_proto": [ + { + "ip_proto_name": "tcp", + "ip_proto_id": 6, + } + ] + } + } + ) + expected_protocol_map = { + "tcp": 6, + } + + # Act + import_state_controller.set_protocol_map() + + # Assert + assert import_state_controller.state.protocol_map == expected_protocol_map + + def test_get_protocol_map_with_exception( + self, + fwconfig_import_object: FwConfigImportObject, + import_state_controller: ImportStateController, + mocker: MockerFixture, + ): + # Arrange + fwconfig_import_object.import_state.api_call.call = mocker.Mock( + side_effect=Exception("Unexpected error occurred") + ) + mock_logger = mocker.patch("fwo_log.FWOLogger.error") + + # Act and Assert + with pytest.raises(FwoImporterError): + import_state_controller.set_protocol_map() + + # Assert + mock_logger.assert_called_once() + assert import_state_controller.state.protocol_map == {} + + +class TestFwConfigImportObjectGetUserObjTypeMap: + def test_get_userobj_type_map( + self, + fwconfig_import_object: FwConfigImportObject, + mocker: MockerFixture, + ): + # Arrange + fwconfig_import_object.import_state.api_call.call = mocker.Mock( + return_value={ + "data": { + "stm_usr_typ": [ + { + "usr_typ_name": "user", + "usr_typ_id": 1, + } + ] + } + } + ) + expected_userobj_type_map = { + "user": 1, + } + + # Act + fwconfig_import_object.import_state.set_user_obj_type_map() + + # Assert + assert fwconfig_import_object.import_state.state.user_obj_type_map == expected_userobj_type_map + + def test_get_userobj_type_map_with_exception( + self, + fwconfig_import_object: FwConfigImportObject, + mocker: MockerFixture, + ): + # Arrange + fwconfig_import_object.import_state.api_call.call = mocker.Mock( + side_effect=Exception("Unexpected error occurred") + ) + mock_logger = mocker.patch("fwo_log.FWOLogger.error") + + # Act and Assert + with pytest.raises(FwoImporterError): + fwconfig_import_object.import_state.set_user_obj_type_map() + + # Assert + mock_logger.assert_called_once() + assert fwconfig_import_object.import_state.state.user_obj_type_map == {} + + +class TestFwConfigImportObjectGetServiceObjTypeMap: + def test_get_serviceobj_type_map( + self, + fwconfig_import_object: FwConfigImportObject, + mocker: MockerFixture, + ): + # Arrange + fwconfig_import_object.import_state.api_call.call = mocker.Mock( + return_value={ + "data": { + "stm_svc_typ": [ + { + "svc_typ_name": "service", + "svc_typ_id": 1, + } + ] + } + } + ) + expected_serviceobj_type_map = { + "service": 1, + } + + # Act + fwconfig_import_object.import_state.set_service_obj_type_map() + + # Assert + assert fwconfig_import_object.import_state.state.service_obj_type_map == expected_serviceobj_type_map + + def test_get_serviceobj_type_map_with_exception( + self, + fwconfig_import_object: FwConfigImportObject, + mocker: MockerFixture, + ): + # Arrange + fwconfig_import_object.import_state.api_call.call = mocker.Mock( + side_effect=Exception("Unexpected error occurred") + ) + mock_logger = mocker.patch("fwo_log.FWOLogger.error") + + # Act and Assert + with pytest.raises(FwoImporterError): + fwconfig_import_object.import_state.set_service_obj_type_map() + + # Assert + mock_logger.assert_called_once() + assert fwconfig_import_object.import_state.state.service_obj_type_map == {} + + +class TestFwConfigImportObjectGetNetworkObjTypeMap: + def test_get_networkobj_type_map( + self, + fwconfig_import_object: FwConfigImportObject, + mocker: MockerFixture, + ): + # Arrange + fwconfig_import_object.import_state.api_call.call = mocker.Mock( + return_value={ + "data": { + "stm_obj_typ": [ + { + "obj_typ_name": "network", + "obj_typ_id": 1, + } + ] + } + } + ) + expected_networkobj_type_map = { + "network": 1, + } + + # Act + fwconfig_import_object.import_state.set_network_obj_type_map() + + # Assert + assert fwconfig_import_object.import_state.state.network_obj_type_map == expected_networkobj_type_map + + def test_get_networkobj_type_map_with_exception( + self, + fwconfig_import_object: FwConfigImportObject, + mocker: MockerFixture, + ): + # Arrange + fwconfig_import_object.import_state.api_call.call = mocker.Mock( + side_effect=Exception("Unexpected error occurred") + ) + mock_logger = mocker.patch("fwo_log.FWOLogger.error") + + # Act + with pytest.raises(FwoImporterError): + fwconfig_import_object.import_state.set_network_obj_type_map() + + # Assert + mock_logger.assert_called_once() + + +class TestFwConfigImportObjectLookupObjType: + def test_lookup_obj_type_unknown( + self, + import_state_controller: ImportStateController, + ): + # Arrange + obj_type_str = "some-obj-type" + + # Act and Assert + with pytest.raises(FwoImporterError): + import_state_controller.state.lookup_network_obj_type_id(obj_type_str) + + def test_lookup_obj_type_known( + self, + import_state_controller: ImportStateController, + ): + # Arrange + obj_type_str = "imported" + expected_obj_type = 2 + import_state_controller.state.network_obj_type_map = { + "builtin": 1, + "imported": 2, + "custom": 3, + } + + # Act + obj_type = import_state_controller.state.lookup_network_obj_type_id(obj_type_str) + + # Assert + assert obj_type == expected_obj_type diff --git a/roles/importer/files/importer/test/test_rule_model.py b/roles/importer/files/importer/test/test_rule_model.py new file mode 100644 index 0000000000..dc0fc49caa --- /dev/null +++ b/roles/importer/files/importer/test/test_rule_model.py @@ -0,0 +1,49 @@ +from models.rule import RuleAction, RuleNormalized, RuleTrack, RuleType + + +def test_last_hit_normalizes_offset_aware_timestamp_to_utc(): + rule = RuleNormalized( + rule_num=1, + rule_num_numeric=1.0, + rule_disabled=False, + rule_src_neg=False, + rule_src="src", + rule_src_refs="src_ref", + rule_dst_neg=False, + rule_dst="dst", + rule_dst_refs="dst_ref", + rule_svc_neg=False, + rule_svc="svc", + rule_svc_refs="svc_ref", + rule_action=RuleAction.ACCEPT, + rule_track=RuleTrack.NONE, + rule_implied=False, + rule_type=RuleType.ACCESS, + last_hit="2026-03-11T11:57:00+01:00", + ) + + assert rule.last_hit == "2026-03-11T10:57:00+00:00" + + +def test_last_hit_normalizes_timezone_naive_timestamp_to_utc(): + rule = RuleNormalized( + rule_num=1, + rule_num_numeric=1.0, + rule_disabled=False, + rule_src_neg=False, + rule_src="src", + rule_src_refs="src_ref", + rule_dst_neg=False, + rule_dst="dst", + rule_dst_refs="dst_ref", + rule_svc_neg=False, + rule_svc="svc", + rule_svc_refs="svc_ref", + rule_action=RuleAction.ACCEPT, + rule_track=RuleTrack.NONE, + rule_implied=False, + rule_type=RuleType.ACCESS, + last_hit="2026-03-11T11:57:00", + ) + + assert rule.last_hit == "2026-03-11T11:57:00+00:00" diff --git a/roles/importer/files/importer/test/test_update_rulebase_diffs.py b/roles/importer/files/importer/test/test_update_rulebase_diffs.py new file mode 100644 index 0000000000..1e11f8847e --- /dev/null +++ b/roles/importer/files/importer/test/test_update_rulebase_diffs.py @@ -0,0 +1,240 @@ +import copy +import unittest.mock +from typing import Any + +import pytest +from fwo_api import FwoApi +from fwo_api_call import FwoApiCall +from model_controllers.fwconfig_import_rule import FwConfigImportRule +from model_controllers.import_state_controller import ImportStateController +from models.rule import RuleNormalized +from pytest_mock import MockerFixture +from services.global_state import GlobalState +from services.uid2id_mapper import Uid2IdMapper +from test.utils.config_builder import FwConfigBuilder +from test.utils.rule_helper_functions import insert_rule_in_config, move_rule_in_config, remove_rule_from_rulebase +from test.utils.test_utils import mock_get_graphql_code + + +@pytest.fixture +def mock_graphql(mocker: MockerFixture): + mock_get_graphql_code(mocker, "query { dummy }") + + +@pytest.fixture +def mock_uid2id_mapper_response(uid2id_mapper: Uid2IdMapper, fwconfig_import_rule: FwConfigImportRule): + uid2id_mapper.get_rulebase_id = unittest.mock.Mock(return_value=69) + fwconfig_import_rule.uid2id_mapper.get_network_object_id = unittest.mock.Mock(return_value=42) + fwconfig_import_rule.uid2id_mapper.rule_uid2id.get = unittest.mock.Mock(return_value=43) + fwconfig_import_rule.uid2id_mapper.get_service_object_id = unittest.mock.Mock(return_value=84) + + +@pytest.fixture +def mock_api_connection_response(api_connection: FwoApi): + api_connection.call = unittest.mock.Mock( + return_value={"data": {"insert_rulebase": {"affected_rows": 1}, "rule": []}} + ) + + +@pytest.fixture +def mock_import_state_controller_response(import_state_controller: ImportStateController): + import_state_controller.state.lookup_gateway_id = unittest.mock.Mock(return_value=1) + + +@pytest.fixture +def mock_fwconfig_import_rule_side_effects(fwconfig_import_rule: FwConfigImportRule): + def side_effect_mark_rules_removed(removed_rule_uids: list[str]) -> tuple[int, list[int]]: + changes = 0 + changes = len(removed_rule_uids) + collected_removed_rule_ids = [42 + i for i in range(len(removed_rule_uids))] + + return changes, collected_removed_rule_ids + + fwconfig_import_rule.mark_rules_removed = unittest.mock.Mock(side_effect=side_effect_mark_rules_removed) + + def side_effect_add_new_rules(rulebases: dict[str, tuple[RuleNormalized, str]]) -> tuple[int, list[dict[str, Any]]]: + changes = 0 + new_rule_ids: list[dict[str, Any]] = [] + + for rule, _rulebase_uid in rulebases.values(): + changes += 1 + new_rule_ids.append({"rule_uid": rule.rule_uid, "rule_id": changes}) + + return changes, new_rule_ids + + fwconfig_import_rule.add_new_rules = unittest.mock.Mock(side_effect=side_effect_add_new_rules) + + +@pytest.fixture +def mock_api_call_response(api_call: FwoApiCall): + def api_call_side_effect( + query: str, # noqa: ARG001 + query_variables: dict[str, dict[str, Any]], + analyze_payload: bool = False, # noqa: ARG001 + ) -> dict[str, Any]: + outcome: dict[str, Any] = {"data": {}} + + if "ruleMetadata" in query_variables: + outcome["data"].update( + {"insert_rule_metadata": {"affected_rows": len(query_variables.get("ruleMetadata", []))}} + ) + + if "rulebases" in query_variables: + outcome["data"].update( + { + "insert_rulebase": { + "affected_rows": len(query_variables.get("rulebases", [])), + "returning": [{"id": 999} for _ in range(len(query_variables.get("rulebases", [])))], + } + } + ) + + if "uids" in query_variables and "objects" in query_variables: + outcome["data"].update( + { + "update_rule": { + "affected_rows": len(query_variables.get("uids", [])), + "returning": [ + {"rule_id": 888 + i, "rule_uid": uid} + for i, uid in enumerate(query_variables.get("uids", [])) + ], + }, + "insert_rule": { + "affected_rows": len(query_variables.get("uids", [])), + "returning": [ + {"rule_id": 777 + i, "rule_uid": uid} + for i, uid in enumerate(query_variables.get("uids", [])) + ], + }, + } + ) + + if "ruleFroms" in query_variables: + outcome["data"].update( + { + "insert_rule_from": { + "affected_rows": len(query_variables.get("ruleFroms", [])), + }, + "insert_rule_to": { + "affected_rows": len(query_variables.get("ruleTos", [])), + }, + "insert_rule_service": { + "affected_rows": len(query_variables.get("ruleServices", [])), + }, + "insert_rule_nwobj_resolved": { + "affected_rows": len(query_variables.get("ruleNwObjResolveds", [])), + }, + "insert_rule_svc_resolved": { + "affected_rows": len(query_variables.get("ruleSvcResolveds", [])), + }, + "insert_rule_user_resolved": { + "affected_rows": len(query_variables.get("ruleUserResolveds", [])), + }, + "insert_rule_from_zone": { + "affected_rows": len(query_variables.get("ruleFromZones", [])), + }, + "insert_rule_to_zone": { + "affected_rows": len(query_variables.get("ruleToZones", [])), + }, + "insert_rule_time": { + "affected_rows": len(query_variables.get("ruleTimes", [])), + }, + "update_rule_from": { + "affected_rows": len(query_variables.get("ruleFroms", [])), + }, + "update_rule_to": { + "affected_rows": len(query_variables.get("ruleTos", [])), + }, + "update_rule_service": { + "affected_rows": len(query_variables.get("ruleServices", [])), + }, + "update_rule_nwobj_resolved": { + "affected_rows": len(query_variables.get("ruleNwObjResolveds", [])), + }, + "update_rule_svc_resolved": { + "affected_rows": len(query_variables.get("ruleSvcResolveds", [])), + }, + "update_rule_user_resolved": { + "affected_rows": len(query_variables.get("ruleUserResolveds", [])), + }, + "update_rule_from_zone": { + "affected_rows": len(query_variables.get("ruleFromZones", [])), + }, + "update_rule_to_zone": { + "affected_rows": len(query_variables.get("ruleToZones", [])), + }, + "update_rule_time": { + "affected_rows": len(query_variables.get("ruleTimes", [])), + }, + } + ) + + if "rulesEnforcedOnGateway" in query_variables: + outcome["data"].update( + { + "update_rule_enforced_on_gateway": { + "affected_rows": len(query_variables.get("rulesEnforcedOnGateway", [])), + }, + "insert_rule_enforced_on_gateway": { + "affected_rows": len(query_variables.get("rulesEnforcedOnGateway", [])), + }, + } + ) + + return outcome + + api_call.call = unittest.mock.Mock(side_effect=api_call_side_effect) + + +class TestFwconfigImportRuleUpdateRulebaseDiffOldMigration: + def test_update_rulebase_diffs_on_insert_delete_and_move( + self, + import_state_controller: ImportStateController, + fwconfig_import_rule: FwConfigImportRule, + fwconfig_builder: FwConfigBuilder, + global_state: GlobalState, + mock_graphql: None, # noqa: ARG002 + mock_uid2id_mapper_response: None, # noqa: ARG002 + mock_api_connection_response: None, # noqa: ARG002 + mock_import_state_controller_response: None, # noqa: ARG002 + mock_fwconfig_import_rule_side_effects: None, # noqa: ARG002 + mock_api_call_response: None, # noqa: ARG002 + ): + # Arrange + config, _ = fwconfig_builder.build_config( + network_object_count=10, + service_object_count=10, + rulebase_count=3, + rules_per_rulebase_count=10, + ) + + global_state.previous_config = config + global_state.normalized_config = copy.deepcopy(config) + fwconfig_builder.initialize_rule_num_numerics(global_state.previous_config) + fwconfig_import_rule.normalized_config = global_state.normalized_config + + rulebase = global_state.normalized_config.rulebases[0] + rule_uids = list(rulebase.rules.keys()) + rule_uid = rule_uids[0] + remove_rule_from_rulebase(global_state.normalized_config, rulebase.uid, rule_uid, rule_uids) + insert_rule_in_config(global_state.normalized_config, rulebase.uid, 0, rule_uids, fwconfig_builder) + move_rule_in_config(global_state.normalized_config, rulebase.uid, 9, 0, rule_uids) + + # Act + + fwconfig_import_rule.update_rulebase_diffs(global_state.previous_config) + + # The order of the entries in normalized_config + assert rule_uids == list(rulebase.rules.keys()) + + sorted_rulebase_rules = sorted(rulebase.rules.values(), key=lambda r: r.rule_num_numeric) + sorted_rulebase_rules_uids = [r.rule_uid for r in sorted_rulebase_rules] + + # The sequence of the rule_num_numeric values + assert rule_uids == sorted_rulebase_rules_uids + + # Insert, delete and move recognized in ImportDetails + assert import_state_controller.state.stats.statistics.rule_add_count == 1 + assert import_state_controller.state.stats.statistics.rule_delete_count == 1 + assert import_state_controller.state.stats.statistics.rule_change_count == 1 + assert import_state_controller.state.stats.statistics.rule_move_count == 1 diff --git a/roles/importer/files/importer/test/test_update_rulebase_link_diffs.py b/roles/importer/files/importer/test/test_update_rulebase_link_diffs.py new file mode 100644 index 0000000000..cef72d0777 --- /dev/null +++ b/roles/importer/files/importer/test/test_update_rulebase_link_diffs.py @@ -0,0 +1,321 @@ +import copy + +from model_controllers.fwconfig_import_gateway import FwConfigImportGateway +from model_controllers.import_state_controller import ImportStateController +from services.global_state import GlobalState +from services.uid2id_mapper import Uid2IdMapper +from test.utils.config_builder import FwConfigBuilder + + +def test_add_cp_section_header_at_the_bottom( + global_state: GlobalState, + import_state_controller: ImportStateController, + fwconfig_import_gateway: FwConfigImportGateway, + fwconfig_builder: FwConfigBuilder, + uid2id_mapper: Uid2IdMapper, +): + # Arrange + config, mgm_id = fwconfig_builder.build_config( + network_object_count=10, + service_object_count=10, + rulebase_count=3, + rules_per_rulebase_count=10, + ) + global_state.normalized_config = copy.deepcopy(config) + global_state.previous_config = copy.deepcopy(config) + import_state_controller.state.mgm_details.uid = mgm_id + + last_rulebase = config.rulebases[-1] + last_rulebase_last_rule_uid = list(last_rulebase.rules.keys())[-1] + new_rulebase = fwconfig_builder.add_rulebase(config, mgm_id) + gateway = global_state.normalized_config.gateways[0] + fwconfig_builder.add_cp_section_header(gateway, last_rulebase.uid, new_rulebase.uid, last_rulebase_last_rule_uid) + + fwconfig_builder.update_rule_map_and_rulebase_map(config, import_state_controller.state.import_id) + to_rulebase_id = uid2id_mapper.get_rulebase_id(new_rulebase.uid) + from_rulebase_id = uid2id_mapper.get_rulebase_id(last_rulebase.uid) + fwconfig_builder.update_rb_links(gateway.RulebaseLinks, 1, fwconfig_import_gateway, uid2id_mapper) + + import_state_controller.state.gateway_map[3] = {global_state.normalized_config.gateways[0].Uid or "": 1} + + # Act + new_links, _ = fwconfig_import_gateway.update_rulebase_link_diffs() + + # Assert + + assert new_links[0]["from_rulebase_id"] == from_rulebase_id, ( + f"expected last rulebase link to have from_rulebase_id {from_rulebase_id}, got {new_links[0]['from_rulebase_id']}" + ) + assert len(new_links) == 1, f"expected {1} new rulebase link, got {len(new_links)}" + + assert new_links[0]["to_rulebase_id"] == to_rulebase_id, ( + f"expected last rulebase link to point to new rulebase id {to_rulebase_id}, got {new_links[0]['to_rulebase_id']}" + ) + + assert new_links[0]["is_section"], "expected last rulebase link to have is_section true, got false" + + +def test_add_cp_section_header_in_existing_rulebase( + global_state: GlobalState, + import_state_controller: ImportStateController, + fwconfig_import_gateway: FwConfigImportGateway, + fwconfig_builder: FwConfigBuilder, + uid2id_mapper: Uid2IdMapper, +): + # Arrange + config, mgm_id = fwconfig_builder.build_config( + network_object_count=10, + service_object_count=10, + rulebase_count=3, + rules_per_rulebase_count=10, + ) + + global_state.normalized_config = copy.deepcopy(config) + global_state.previous_config = copy.deepcopy(config) + import_state_controller.state.mgm_details.uid = mgm_id + + last_rulebase = global_state.normalized_config.rulebases[-1] + last_rulebase_last_rule_uid = list(last_rulebase.rules.keys())[-1] + last_rulebase_last_rule = last_rulebase.rules.pop(last_rulebase_last_rule_uid) + + new_rulebase = fwconfig_builder.add_rulebase( + global_state.normalized_config, import_state_controller.state.mgm_details.uid + ) + fwconfig_builder.add_rule(global_state.normalized_config, new_rulebase.uid, rule=last_rulebase_last_rule) + gateway = global_state.normalized_config.gateways[0] + fwconfig_builder.add_cp_section_header(gateway, last_rulebase.uid, new_rulebase.uid, last_rulebase_last_rule_uid) + + fwconfig_builder.update_rule_map_and_rulebase_map( + global_state.normalized_config, import_state_controller.state.import_id + ) + to_rulebase_id = uid2id_mapper.get_rulebase_id(new_rulebase.uid) + from_rulebase_id = uid2id_mapper.get_rulebase_id(last_rulebase.uid) + fwconfig_builder.update_rb_links(gateway.RulebaseLinks, 1, fwconfig_import_gateway, uid2id_mapper) + + import_state_controller.state.gateway_map[3] = {global_state.normalized_config.gateways[0].Uid or "": 1} + + # Act + new_links, _ = fwconfig_import_gateway.update_rulebase_link_diffs() + + # Assert + assert len(new_links) == 1, f"expected {1} new rulebase link, got {len(new_links)}" + assert new_links[0]["from_rulebase_id"] == from_rulebase_id, ( + f"expected last rulebase link to have from_rulebase_id {from_rulebase_id}, got {new_links[0]['from_rulebase_id']}" + ) + assert new_links[0]["to_rulebase_id"] == to_rulebase_id, ( + f"expected last rulebase link to point to new rulebase id {to_rulebase_id}, got {new_links[0]['to_rulebase_id']}" + ) + + assert new_links[0]["is_section"], "expected last rulebase link to have is_section true, got false" + + +def test_delete_cp_section_header( + global_state: GlobalState, + import_state_controller: ImportStateController, + fwconfig_import_gateway: FwConfigImportGateway, + fwconfig_builder: FwConfigBuilder, + uid2id_mapper: Uid2IdMapper, +): + # Arrange + config, mgm_id = fwconfig_builder.build_config( + network_object_count=10, + service_object_count=10, + rulebase_count=3, + rules_per_rulebase_count=10, + ) + + global_state.normalized_config = copy.deepcopy(config) + global_state.previous_config = copy.deepcopy(config) + import_state_controller.state.mgm_details.uid = mgm_id + + last_rulebase = global_state.previous_config.rulebases[-1] + last_five_rules_uids = list(last_rulebase.rules.keys())[-5:] + + new_rulebase = fwconfig_builder.add_rulebase(global_state.previous_config, mgm_id) + + for rule_uid in last_five_rules_uids: + rule = last_rulebase.rules.pop(rule_uid) + fwconfig_builder.add_rule(global_state.previous_config, new_rulebase.uid, rule=rule) + # Create rulebase link for cp_section header (previous config) + + last_rulebase_last_rule_uid = list(last_rulebase.rules.keys())[-1] + gateway = global_state.previous_config.gateways[0] + fwconfig_builder.add_cp_section_header(gateway, last_rulebase.uid, new_rulebase.uid, last_rulebase_last_rule_uid) + + fwconfig_builder.update_rule_map_and_rulebase_map( + global_state.previous_config, import_state_controller.state.import_id + ) + fwconfig_builder.update_rule_num_numerics(global_state.previous_config) + fwconfig_builder.update_rb_links(gateway.RulebaseLinks, 1, fwconfig_import_gateway, uid2id_mapper) + import_state_controller.state.gateway_map[3] = {global_state.normalized_config.gateways[0].Uid or "": 1} + + # Act + _, deleted_links_ids = fwconfig_import_gateway.update_rulebase_link_diffs() + + # Assert + assert deleted_links_ids[0] == fwconfig_import_gateway.get_rb_link_controller().rb_links[-1].id + + +def test_add_inline_layer( + global_state: GlobalState, + import_state_controller: ImportStateController, + fwconfig_import_gateway: FwConfigImportGateway, + fwconfig_builder: FwConfigBuilder, + uid2id_mapper: Uid2IdMapper, +): + # Arrange + config, mgm_id = fwconfig_builder.build_config( + network_object_count=10, + service_object_count=10, + rulebase_count=3, + rules_per_rulebase_count=10, + ) + + global_state.normalized_config = config + global_state.previous_config = copy.deepcopy(config) + import_state_controller.state.mgm_details.uid = mgm_id + + from_rulebase = config.rulebases[-1] + from_rule = next(iter(from_rulebase.rules.values())) + + added_rulebase = fwconfig_builder.add_rulebase(config, mgm_id) + fwconfig_builder.add_rule(config, added_rulebase.uid) + + gateway = config.gateways[0] + fwconfig_builder.add_inline_layer(gateway, from_rulebase.uid, from_rule.rule_uid or "", added_rulebase.uid) + fwconfig_builder.update_rule_map_and_rulebase_map(config, import_state_controller.state.import_id) + + assert from_rule.rule_uid is not None, "from_rule_id is None in test setup" + from_rule_id = uid2id_mapper.get_rule_id(from_rule.rule_uid) + from_rulebase_id = uid2id_mapper.get_rulebase_id(from_rulebase.uid) + to_rulebase_id = uid2id_mapper.get_rulebase_id(added_rulebase.uid) + fwconfig_builder.update_rb_links(gateway.RulebaseLinks, 1, fwconfig_import_gateway, uid2id_mapper) + import_state_controller.state.gateway_map[3] = {global_state.normalized_config.gateways[0].Uid or "": 1} + + # Act + new_links, _ = fwconfig_import_gateway.update_rulebase_link_diffs() + + # Assert + assert len(new_links) == 1, f"expected {1} new rulebase link, got {len(new_links)}" + assert new_links[0]["from_rule_id"] == from_rule_id, ( + f"expected last rulebase link to have from_rule_id {from_rule_id}, got {new_links[0]['from_rule_id']}" + ) + assert new_links[0]["from_rulebase_id"] == from_rulebase_id, ( + f"expected last rulebase link to have from_rulebase_id {from_rulebase_id}, got {new_links[0]['from_rulebase_id']}", + ) + assert new_links[0]["to_rulebase_id"] == to_rulebase_id, ( + f"expected last rulebase link to point to new rulebase id {to_rulebase_id}, got {new_links[0]['to_rulebase_id']}", + ) + assert not new_links[0]["is_section"], "expected last rulebase link to have is_section false, got true" + + +def test_delete_inline_layer( + global_state: GlobalState, + import_state_controller: ImportStateController, + fwconfig_import_gateway: FwConfigImportGateway, + fwconfig_builder: FwConfigBuilder, + uid2id_mapper: Uid2IdMapper, +): + # Arrange + config, mgm_id = fwconfig_builder.build_config( + network_object_count=10, + service_object_count=10, + rulebase_count=3, + rules_per_rulebase_count=10, + ) + + global_state.normalized_config = copy.deepcopy(config) + global_state.previous_config = copy.deepcopy(config) + import_state_controller.state.mgm_details.uid = mgm_id + + from_rulebase = global_state.previous_config.rulebases[-1] + from_rule = next(iter(from_rulebase.rules.values())) + + added_rulebase = fwconfig_builder.add_rulebase(global_state.previous_config, mgm_id) + fwconfig_builder.add_rule(global_state.previous_config, added_rulebase.uid) + + gateway = global_state.previous_config.gateways[0] + fwconfig_builder.add_inline_layer(gateway, from_rulebase.uid, from_rule.rule_uid or "", added_rulebase.uid) + + fwconfig_builder.update_rule_map_and_rulebase_map( + global_state.previous_config, import_state_controller.state.import_id + ) + fwconfig_builder.update_rb_links(gateway.RulebaseLinks, 1, fwconfig_import_gateway, uid2id_mapper) + import_state_controller.state.gateway_map[3] = {global_state.normalized_config.gateways[0].Uid or "": 1} + + # Act + _, deleted_links_ids = fwconfig_import_gateway.update_rulebase_link_diffs() + + # Assert + assert len(deleted_links_ids) == 1, f"expected {1} new rulebase link, got {len(deleted_links_ids)}" + assert deleted_links_ids[0] == fwconfig_import_gateway.get_rb_link_controller().rb_links[-1].id + + +def test_move_inline_layer( + global_state: GlobalState, + import_state_controller: ImportStateController, + fwconfig_import_gateway: FwConfigImportGateway, + fwconfig_builder: FwConfigBuilder, + uid2id_mapper: Uid2IdMapper, +): + # Arrange + config, mgm_id = fwconfig_builder.build_config( + network_object_count=10, + service_object_count=10, + rulebase_count=3, + rules_per_rulebase_count=10, + ) + + global_state.normalized_config = copy.deepcopy(config) + global_state.previous_config = copy.deepcopy(config) + import_state_controller.state.mgm_details.uid = mgm_id + + from_rulebase_previous = global_state.previous_config.rulebases[-1] + from_rule_previous = next(iter(from_rulebase_previous.rules.values())) + + from_rulebase_normalized = global_state.normalized_config.rulebases[0] + from_rule_normalized = next(iter(from_rulebase_normalized.rules.values())) + + added_rulebase = fwconfig_builder.add_rulebase(global_state.previous_config, mgm_id) + fwconfig_builder.add_rule(global_state.previous_config, added_rulebase.uid) + added_rulebase_copy = copy.deepcopy(added_rulebase) + fwconfig_builder.add_rulebase(global_state.normalized_config, mgm_id, added_rulebase_copy) + + gateway_previous = global_state.previous_config.gateways[0] + fwconfig_builder.add_inline_layer( + gateway_previous, from_rulebase_previous.uid, from_rule_previous.rule_uid or "", added_rulebase.uid + ) + gateway_normalized = global_state.normalized_config.gateways[0] + fwconfig_builder.add_inline_layer( + gateway_normalized, from_rulebase_normalized.uid, from_rule_normalized.rule_uid or "", added_rulebase_copy.uid + ) + + fwconfig_builder.update_rule_map_and_rulebase_map( + global_state.previous_config, import_state_controller.state.import_id + ) + + assert from_rule_normalized.rule_uid is not None, "from_rule_id is None in test setup" + from_rule_id = uid2id_mapper.get_rule_id(from_rule_normalized.rule_uid) + from_rulebase_id = uid2id_mapper.get_rulebase_id(from_rulebase_normalized.uid) + to_rulebase_id = uid2id_mapper.get_rulebase_id(added_rulebase_copy.uid) + + fwconfig_builder.update_rb_links(gateway_previous.RulebaseLinks, 1, fwconfig_import_gateway, uid2id_mapper) + import_state_controller.state.gateway_map[3] = {global_state.normalized_config.gateways[0].Uid or "": 1} + + # Act + new_links, deleted_links_ids = fwconfig_import_gateway.update_rulebase_link_diffs() + + # Assert + assert len(new_links) == 1, f"expected {1} new rulebase link, got {len(new_links)}" + assert new_links[0]["from_rule_id"] == from_rule_id, ( + f"expected last rulebase link to have from_rule_id {from_rule_id}, got {new_links[0]['from_rule_id']}" + ) + assert new_links[0]["from_rulebase_id"] == from_rulebase_id, ( + f"expected last rulebase link to have from_rulebase_id {from_rulebase_id}, got {new_links[0]['from_rulebase_id']}" + ) + assert new_links[0]["to_rulebase_id"] == to_rulebase_id, ( + f"expected last rulebase link to point to new rulebase id {to_rulebase_id}, got {new_links[0]['to_rulebase_id']}" + ) + assert not new_links[0]["is_section"], "expected last rulebase link to have is_section false, got true" + assert len(deleted_links_ids) == 1, f"expected {1} new rulebase link, got {len(deleted_links_ids)}" + assert deleted_links_ids[0] == fwconfig_import_gateway.get_rb_link_controller().rb_links[-1].id diff --git a/roles/importer/files/importer/test/utils/__init__.py b/roles/importer/files/importer/test/utils/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/roles/importer/files/importer/test/utils/config_builder.py b/roles/importer/files/importer/test/utils/config_builder.py new file mode 100644 index 0000000000..b940ae2e4f --- /dev/null +++ b/roles/importer/files/importer/test/utils/config_builder.py @@ -0,0 +1,478 @@ +"""Test helper to assemble and tweak FwConfigNormalized instances.""" + +from __future__ import annotations + +import random +from typing import TYPE_CHECKING, Any, TypeVar + +from fwo_const import DUMMY_IP, LIST_DELIMITER, RULE_NUM_NUMERIC_STEPS +from models.fwconfig_normalized import FwConfigNormalized +from models.gateway import Gateway +from models.networkobject import NetworkObject +from models.rule import RuleAction, RuleNormalized, RuleTrack, RuleType +from models.rulebase import Rulebase +from models.rulebase_link import RulebaseLink, RulebaseLinkUidBased +from models.serviceobject import ServiceObject +from netaddr import IPNetwork +from services.service_provider import ServiceProvider +from services.uid2id_mapper import Uid2IdMap, Uid2IdMapper + +from .uid_manager import UidManager + +if TYPE_CHECKING: + from collections.abc import Iterable + + from model_controllers.fwconfig_import_gateway import FwConfigImportGateway +T = TypeVar("T") + + +class FwConfigBuilder: + """Utility for creating and modifying normalized configs in unit tests.""" + + def __init__(self, seed: int = 42): + self._seed = seed + self.reset() + + def reset(self) -> None: + self.uid_manager = UidManager() + self._rng = random.Random(self._seed) # noqa: S311 + + def build_config( + self, + rulebase_count: int = 1, + rules_per_rulebase_count: int = 1, + network_object_count: int = 3, + service_object_count: int = 2, + include_gateway: bool = True, + user_object_count: int = 0, + zone_object_count: int = 0, + user_group_object_count: int = 0, + user_group_object_member_count: int = 0, + ) -> tuple[FwConfigNormalized, str]: + config = FwConfigNormalized() + mgm_uid = self.uid_manager.create_uid() + + for _ in range(network_object_count): + self.add_network_object(config) + + for _ in range(service_object_count): + self.add_service_object(config) + + for _ in range(user_object_count): + self.add_user_object(config) + + for _ in range(zone_object_count): + self.add_zone_object(config) + + for _ in range(user_group_object_count): + self.add_user_group_object(config, member_count=user_group_object_member_count) + + for _ in range(rulebase_count): + rb = self.add_rulebase(config, mgm_uid) + for _ in range(rules_per_rulebase_count): + rule = self.add_rule(config, rb.uid) + self.add_references_to_rule(config, rule) + + if include_gateway: + self.add_gateway(config) + + return config, mgm_uid + + def build_empty_config(self) -> FwConfigNormalized: + config, _ = self.build_config( + rulebase_count=0, + rules_per_rulebase_count=0, + network_object_count=0, + service_object_count=0, + include_gateway=False, + ) + return config + + def add_network_object(self, config: FwConfigNormalized, *, name: str | None = None) -> NetworkObject: + uid = self.uid_manager.create_uid() + obj = NetworkObject( + obj_uid=uid, + obj_name=name or f"nw-{uid}", + obj_ip=IPNetwork(DUMMY_IP), + obj_ip_end=IPNetwork(DUMMY_IP), + obj_color="black", + obj_typ="group", + obj_member_names="", + obj_member_refs="", + ) + config.network_objects[uid] = obj + return obj + + def add_service_object(self, config: FwConfigNormalized, *, name: str | None = None) -> ServiceObject: + uid = self.uid_manager.create_uid() + svc = ServiceObject( + svc_uid=uid, + svc_name=name or f"svc-{uid}", + svc_color="black", + svc_typ="group", + svc_port=None, + svc_port_end=None, + ip_proto=None, + svc_member_names="", + svc_member_refs="", + ) + config.service_objects[uid] = svc + return svc + + def add_rulebase( + self, + config: FwConfigNormalized, + mgm_uid: str, + rulebase: Rulebase | None = None, + *, + name: str | None = None, + ) -> Rulebase: + if rulebase is None: + uid = self.uid_manager.create_uid() + rb = Rulebase(uid=uid, name=name or f"rb-{uid}", mgm_uid=mgm_uid) + else: + rb = rulebase + config.rulebases.append(rb) + return rb + + def initialize_rule_num_numerics(self, config: FwConfigNormalized) -> None: + for rulebase in config.rulebases: + current_rule_num_numeric = 0 + for rule in rulebase.rules.values(): + current_rule_num_numeric += RULE_NUM_NUMERIC_STEPS + rule.rule_num_numeric = current_rule_num_numeric + + def add_rule( + self, + config: FwConfigNormalized, + rulebase_uid: str, + rule: RuleNormalized | None = None, + *, + name: str | None = None, + rule_type: RuleType = RuleType.SECTIONHEADER, + ) -> RuleNormalized: + if rule is None: + uid = self.uid_manager.create_uid() + normalized_rule = RuleNormalized( + rule_num=0, + rule_num_numeric=0.0, + rule_disabled=False, + rule_src_neg=False, + rule_src="", + rule_src_refs="", + rule_dst_neg=False, + rule_dst="", + rule_dst_refs="", + rule_svc_neg=False, + rule_svc="", + rule_svc_refs="", + rule_action=RuleAction.ACCEPT, + rule_track=RuleTrack.NONE, + rule_installon=None, + rule_time=None, + rule_name=name or f"rule-{uid}", + rule_uid=uid, + rule_custom_fields=None, + rule_implied=False, + rule_type=rule_type, + last_change_admin=None, + parent_rule_uid=None, + last_hit=None, + rule_comment=None, + rule_src_zone=None, + rule_dst_zone=None, + rule_head_text=None, + ) + else: + uid = rule.rule_uid or self.uid_manager.create_uid() + normalized_rule = rule + + rulebase = self._get_rulebase(config, rulebase_uid) + rulebase.rules[uid] = normalized_rule + return normalized_rule + + def add_references_to_rule( + self, + config: FwConfigNormalized, + rule: RuleNormalized, + *, + num_src: int = 1, + num_dst: int = 1, + num_svc: int = 1, + ) -> None: + src_objs = self._pick(config.network_objects.values(), num_src) + dst_objs = self._pick(config.network_objects.values(), num_dst) + svc_objs = self._pick(config.service_objects.values(), num_svc) + + rule.rule_src = LIST_DELIMITER.join(obj.obj_name for obj in src_objs) + rule.rule_src_refs = LIST_DELIMITER.join(obj.obj_uid for obj in src_objs) + rule.rule_dst = LIST_DELIMITER.join(obj.obj_name for obj in dst_objs) + rule.rule_dst_refs = LIST_DELIMITER.join(obj.obj_uid for obj in dst_objs) + rule.rule_svc = LIST_DELIMITER.join(svc.svc_name for svc in svc_objs) + rule.rule_svc_refs = LIST_DELIMITER.join(svc.svc_uid for svc in svc_objs) + + def add_gateway(self, config: FwConfigNormalized, *, name: str | None = None) -> Gateway: + uid = self.uid_manager.create_uid() + gw = Gateway(Uid=uid, Name=name or f"gw-{uid}", RulebaseLinks=self.create_rulebase_links(config)) + config.gateways.append(gw) + return gw + + def add_user_object(self, config: FwConfigNormalized, *, name: str | None = None) -> dict[str, Any]: + uid = self.uid_manager.create_uid() + obj = { + "user_typ": "simple", + "user_uid": uid, + "user_name": name or f"user-{uid}", + "user_color": "black", + } + config.users[uid] = obj + return obj + + def add_user_group_object( + self, config: FwConfigNormalized, member_count: int, *, name: str | None = None + ) -> dict[str, Any]: + uid = self.uid_manager.create_uid() + obj = { + "user_typ": "group", + "user_uid": uid, + "user_name": name or f"user-group-{uid}", + "user_color": "black", + } + config.users[uid] = obj + + for _ in range(member_count): + member_obj = self.add_user_object(config) + if obj.get("user_member_names"): + obj["user_member_names"] += LIST_DELIMITER + obj["user_member_refs"] += LIST_DELIMITER + else: + obj["user_member_names"] = "" + obj["user_member_refs"] = "" + obj["user_member_names"] += member_obj["user_name"] + obj["user_member_refs"] += member_obj["user_uid"] + return obj + + def add_zone_object(self, config: FwConfigNormalized, *, name: str | None = None) -> dict[str, Any]: + uid = self.uid_manager.create_uid() + obj = { + "zone_typ": "zone", + "zone_uid": uid, + "zone_name": name or f"zone-{uid}", + } + config.zone_objects[uid] = obj + return obj + + def add_cp_section_header( + self, gateway: Gateway, from_rulebase_uid: str, to_rulebase_uid: str, from_rule_uid: str + ) -> None: + gateway.RulebaseLinks.append( + RulebaseLinkUidBased( + from_rulebase_uid=from_rulebase_uid, + from_rule_uid=from_rule_uid, + to_rulebase_uid=to_rulebase_uid, + link_type="ordered", + is_initial=False, + is_global=False, + is_section=True, + ) + ) + + def add_inline_layer( + self, + gateway: Gateway, + from_rulebase_uid: str, + from_rule_uid: str, + to_rulebase_uid: str, + *, + index: int = 0, + ) -> None: + if index == 0: + index = len(gateway.RulebaseLinks) + gateway.RulebaseLinks.insert( + index, + RulebaseLinkUidBased( + from_rulebase_uid=from_rulebase_uid, + from_rule_uid=from_rule_uid, + to_rulebase_uid=to_rulebase_uid, + link_type="inline", + is_initial=False, + is_global=False, + is_section=False, + ), + ) + + def create_rulebase_links(self, config: FwConfigNormalized) -> list[RulebaseLinkUidBased]: + if not config.rulebases: + return [] + + links: list[RulebaseLinkUidBased] = [ + RulebaseLinkUidBased( + from_rulebase_uid=None, + from_rule_uid=None, + to_rulebase_uid=config.rulebases[0].uid, + link_type="ordered", + is_initial=True, + is_global=False, + is_section=False, + ) + ] + + for previous, current in zip(config.rulebases, config.rulebases[1:], strict=False): + last_rule_uid = list(previous.rules.keys())[-1] + links.append( + RulebaseLinkUidBased( + from_rulebase_uid=previous.uid, + from_rule_uid=last_rule_uid, + to_rulebase_uid=current.uid, + link_type="ordered", + is_initial=False, + is_global=False, + is_section=False, + ) + ) + return links + + def _get_rulebase(self, config: FwConfigNormalized, rulebase_uid: str) -> Rulebase: + rulebase = config.get_rulebase_or_none(rulebase_uid) + if rulebase is None: + raise KeyError(f"Rulebase with UID {rulebase_uid} not found") + return rulebase + + def _pick(self, items: Iterable[T], count: int) -> list[T]: + pool = list(items) + if not pool: + return [] + if count >= len(pool): + return pool + return self._rng.sample(pool, count) + + def update_rule_map_and_rulebase_map(self, config: FwConfigNormalized, import_id: int) -> None: + service_provider = ServiceProvider() + uid2id_mapper = service_provider.get_uid2id_mapper(import_id=import_id) + uid2id_mapper.rulebase_uid2id = Uid2IdMap() + uid2id_mapper.rule_uid2id = Uid2IdMap() + + rulebase_id = 1 + rule_id = 1 + + for rulebase in config.rulebases: + uid2id_mapper.rulebase_uid2id.set(rulebase.uid, rulebase_id) + rulebase_id += 1 + for rule in rulebase.rules.values(): + if rule.rule_uid: + uid2id_mapper.rule_uid2id.set(rule.rule_uid, rule_id) + rule_id += 1 + + def update_rb_links( + self, + rulebase_links: list[RulebaseLinkUidBased], + gateway_id: int, + fwconfig_import_gateway: FwConfigImportGateway, + uid2id_mapper: Uid2IdMapper, + ): + new_rb_links: list[RulebaseLink] = [] + rb_link_controller = fwconfig_import_gateway.get_rb_link_controller() + + for link_id, link in enumerate(rulebase_links): + link_type = 0 + match link.link_type: + case "ordered": + link_type = 2 + case "inline": + link_type = 3 + case "concatenated": + link_type = 4 + case "domain": + link_type = 5 + case _: + link_type = 0 + + new_rb_links.append( + RulebaseLink( + id=link_id, + gw_id=gateway_id, + from_rule_id=uid2id_mapper.get_rule_id(link.from_rule_uid) if link.from_rule_uid else None, + from_rulebase_id=uid2id_mapper.get_rulebase_id(link.from_rulebase_uid) + if link.from_rulebase_uid + else None, + to_rulebase_id=uid2id_mapper.get_rulebase_id(link.to_rulebase_uid), + link_type=link_type, + is_initial=link.is_initial, + is_global=link.is_global, + is_section=link.is_section, + created=0, + ) + ) + + rb_link_controller.rb_links = new_rb_links + + def update_rule_num_numerics(self, config: FwConfigNormalized): + for rulebase in config.rulebases: + new_num_numeric = 0 + for rule in rulebase.rules.values(): + new_num_numeric += RULE_NUM_NUMERIC_STEPS + rule.rule_num_numeric = new_num_numeric + + def add_standard_network_host_object(self, config: FwConfigNormalized) -> NetworkObject: + uid = self.uid_manager.create_uid() + network_object = NetworkObject( + obj_uid="NetworkObject" + uid, + obj_name="NetworkObject" + uid, + obj_ip=IPNetwork("192.168.1.1/32"), + obj_ip_end=IPNetwork("192.168.1.1/32"), + obj_typ="host", + obj_color="black", + ) + config.network_objects[network_object.obj_uid] = network_object + return network_object + + def add_standard_network_group_object( + self, config: FwConfigNormalized, obj_members: list[NetworkObject] | None = None + ) -> NetworkObject: + uid = self.uid_manager.create_uid() + network_object = NetworkObject( + obj_uid="NetworkGroupObject" + uid, + obj_name="NetworkGroupObject" + uid, + obj_typ="group", + obj_color="black", + obj_member_names=LIST_DELIMITER.join([member.obj_name for member in obj_members]) + if obj_members is not None + else None, + obj_member_refs=LIST_DELIMITER.join([member.obj_uid for member in obj_members]) + if obj_members is not None + else None, + ) + config.network_objects[network_object.obj_uid] = network_object + return network_object + + def add_standard_service_object(self, config: FwConfigNormalized) -> ServiceObject: + uid = self.uid_manager.create_uid() + service_object = ServiceObject( + svc_uid="ServiceObject" + uid, + svc_name="ServiceObject" + uid, + svc_port=80, + svc_port_end=80, + svc_color="blue", + svc_typ="simple", + ) + config.service_objects[service_object.svc_uid] = service_object + return service_object + + def add_standard_service_group_object( + self, config: FwConfigNormalized, svc_members: list[ServiceObject] | None = None + ) -> ServiceObject: + uid = self.uid_manager.create_uid() + service_object = ServiceObject( + svc_uid="ServiceGroupObject" + uid, + svc_name="ServiceGroupObject" + uid, + svc_typ="group", + svc_color="blue", + svc_member_names=LIST_DELIMITER.join([member.svc_name for member in svc_members]) + if svc_members is not None + else None, + svc_member_refs=LIST_DELIMITER.join([member.svc_uid for member in svc_members]) + if svc_members is not None + else None, + ) + config.service_objects[service_object.svc_uid] = service_object + return service_object diff --git a/roles/importer/files/importer/test/utils/partial_dict.py b/roles/importer/files/importer/test/utils/partial_dict.py new file mode 100644 index 0000000000..c6964f1d71 --- /dev/null +++ b/roles/importer/files/importer/test/utils/partial_dict.py @@ -0,0 +1,14 @@ +from typing import Any, cast + + +class PartialDict(dict[str, Any]): # noqa: PLW1641 + def __eq__(self, other: object) -> bool: + try: + if not isinstance(other, dict): + return False + + # Checks if this dict's keys/values are a subset of 'other' + other_dict: dict[str, Any] = cast("dict[str, Any]", other) + return all(other_dict.get(k) == v for k, v in self.items()) + except Exception: + return False diff --git a/roles/importer/files/importer/test/utils/rule_helper_functions.py b/roles/importer/files/importer/test/utils/rule_helper_functions.py new file mode 100644 index 0000000000..2d84779902 --- /dev/null +++ b/roles/importer/files/importer/test/utils/rule_helper_functions.py @@ -0,0 +1,99 @@ +import copy + +from models.fwconfig_normalized import FwConfigNormalized +from models.rule import RuleNormalized +from test.utils.config_builder import FwConfigBuilder + + +def remove_rule_from_rulebase( + config: FwConfigNormalized, rulebase_uid: str, rule_uid: str, uid_sequence: list[str] | None = None +) -> RuleNormalized: + """ + Imitates the deletion of a rule in the config dict. + """ + rulebase = next((rb for rb in config.rulebases if rb.uid == rulebase_uid), None) + + if rulebase: + rule = rulebase.rules.pop(rule_uid) + + if uid_sequence: + uid_sequence[:] = [uid for uid in uid_sequence if uid != rule_uid] + + return rule + raise ValueError(f"Rulebase with UID {rulebase_uid} not found.") + + +def reorder_rulebase_rules_dict(config: FwConfigNormalized, rulebase_uid: str, rule_uids: list[str]): + """ + Imitates the changes in order in the config dict. + """ + rulebase = next((rb for rb in config.rulebases if rb.uid == rulebase_uid), None) + + if rulebase: + rules = copy.deepcopy(rulebase.rules) + rulebase.rules = {} + for rule_uid in rule_uids: + rulebase.rules[rule_uid] = rules[rule_uid] + + +def insert_rule_in_config( + config: FwConfigNormalized, + rulebase_uid: str, + rule_position: int, + rule_uids: list[str], + config_builder: FwConfigBuilder, + rule: RuleNormalized | None = None, +) -> str | None: + """ + Imitates the insertion of a rule in the config dict. + """ + rulebase = next((rb for rb in config.rulebases if rb.uid == rulebase_uid), None) + inserted_rule_uid = None + + if rulebase: + if rule is None: + inserted_rule = config_builder.add_rule(config, rulebase_uid) + else: + inserted_rule = rule + assert inserted_rule.rule_uid is not None + rulebase.rules[inserted_rule.rule_uid] = inserted_rule + + assert inserted_rule.rule_uid is not None + rule_uids.insert(rule_position, inserted_rule.rule_uid) + + reorder_rulebase_rules_dict(config, rulebase_uid, rule_uids) + + inserted_rule_uid = inserted_rule.rule_uid + + return inserted_rule_uid + + +def move_rule_in_config( + config: FwConfigNormalized, rulebase_uid: str, source_position: int, target_position: int, rule_uids: list[str] +): + """ + Imitates the moving of a rule in the config dict. + """ + rulebase = next((rb for rb in config.rulebases if rb.uid == rulebase_uid), None) + moved_rule_uid = None + + if rulebase: + rule_uid = list(rulebase.rules.keys())[source_position] + rule = rulebase.rules.pop(rule_uid) + rulebase.rules[rule_uid] = rule + rule_uids.pop(source_position) + rule_uids.insert(target_position, rule_uid) + + reorder_rulebase_rules_dict(config, rulebase.uid, rule_uids) + + moved_rule_uid = rule_uid + + return moved_rule_uid + + +def get_rule(normalized_config: FwConfigNormalized, rulebase_index: int, rule_uid: str) -> RuleNormalized | None: + """ + Helper method to get a rule from the normalized config. + """ + rulebase = normalized_config.rulebases[rulebase_index] + return rulebase.rules.get(rule_uid, None) diff --git a/roles/importer/files/importer/test/utils/test_utils.py b/roles/importer/files/importer/test/utils/test_utils.py new file mode 100644 index 0000000000..c45951e4d7 --- /dev/null +++ b/roles/importer/files/importer/test/utils/test_utils.py @@ -0,0 +1,14 @@ +from typing import Any + +from fwo_api import FwoApi +from pytest_mock import MockerFixture, MockType + + +def mock_get_graphql_code(mocker: MockerFixture, return_value: Any) -> MockType: + return mocker.patch.object(FwoApi, "get_graphql_code", return_value=return_value) + + +def mock_login(mocker: MockerFixture, return_value: Any | None = None, side_effect: Any | None = None) -> MockType: + assert not (return_value is not None and side_effect is not None), "Cannot set both return_value and side_effect" + assert return_value is not None or side_effect is not None, "Either return_value or side_effect must be set" + return mocker.patch.object(FwoApi, "login", return_value=return_value, side_effect=side_effect) diff --git a/roles/importer/files/importer/test/utils/uid_manager.py b/roles/importer/files/importer/test/utils/uid_manager.py new file mode 100644 index 0000000000..6b43f32540 --- /dev/null +++ b/roles/importer/files/importer/test/utils/uid_manager.py @@ -0,0 +1,18 @@ +import uuid + + +class UidManager: + def __init__(self): + self.used_uids: list[str] = [] + + def create_uid(self): + need_new_uid = True + new_uid = "" + + while need_new_uid: + new_uid = str(uuid.uuid4()) + if new_uid not in self.used_uids: + self.used_uids.append(new_uid) + need_new_uid = False + + return new_uid diff --git a/roles/importer/files/importer/utils/__init__.py b/roles/importer/files/importer/utils/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/roles/importer/files/importer/utils/conversion_utils.py b/roles/importer/files/importer/utils/conversion_utils.py new file mode 100644 index 0000000000..e6a15d1641 --- /dev/null +++ b/roles/importer/files/importer/utils/conversion_utils.py @@ -0,0 +1,14 @@ +from typing import Any + +from fwo_log import FWOLogger + + +def convert_list_to_dict(list_in: list[Any], id_field: str) -> dict[Any, Any]: + result: dict[Any, Any] = {} + for item in list_in: + if id_field in item: + key = item[id_field] + result[key] = item + else: + FWOLogger.error(f"dict {item!s} does not contain id field {id_field}") + return result # { listIn[idField]: listIn for listIn in listIn } diff --git a/roles/importer/files/importer/utils/fwconfig_json_encoder.py b/roles/importer/files/importer/utils/fwconfig_json_encoder.py new file mode 100644 index 0000000000..eafc8b9592 --- /dev/null +++ b/roles/importer/files/importer/utils/fwconfig_json_encoder.py @@ -0,0 +1,19 @@ +import json + +from fwo_base import ConfFormat, ConfigAction +from models.rulebase import Rulebase +from netaddr import IPNetwork + + +class FwConfigJsonEncoder(json.JSONEncoder): + def default(self, o: object) -> object: + if isinstance(o, (ConfigAction, ConfFormat)): + return o.name + + if isinstance(o, Rulebase): + return o.to_json() + + if isinstance(o, IPNetwork): + return str(o) + + return json.JSONEncoder.default(self, o) diff --git a/roles/importer/importer.pyproj b/roles/importer/importer.pyproj deleted file mode 100644 index 6beb77572a..0000000000 --- a/roles/importer/importer.pyproj +++ /dev/null @@ -1,57 +0,0 @@ - - - - Debug - 2.0 - {1a1b90a0-227d-4041-a62a-f83af9c9c7cf} - - files\importer\import-mgm.py - - . - . - {888888a0-9f3d-457c-b088-3a5042f75d52} - Standard Python launcher - - -m4 -d4 -f -iC:/Users/Nils/Downloads/fortiManager_NAT_mgm_id_25_config_native.json.anon -l250 - False - - - - - 10.0 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/roles/importer/tasks/fetch-importer-pwd.yml b/roles/importer/tasks/fetch-importer-pwd.yml index 675ed5f993..0244777bec 100644 --- a/roles/importer/tasks/fetch-importer-pwd.yml +++ b/roles/importer/tasks/fetch-importer-pwd.yml @@ -1,10 +1,17 @@ -- name: write importer_password from install host to secrets directory +- name: read importer_password from middleware host + slurp: + src: "{{ importer_password_file }}" + register: importer_password_slurp + delegate_to: "{{ groups['middlewareserver'][0] }}" + become: true + +- name: write importer_password to secrets directory copy: - src: "{{ importer_password_file_on_installer }}" + content: "{{ importer_password_slurp.content | b64decode }}" dest: "{{ importer_password_file }}" mode: '0600' owner: "{{ fworch_user }}" group: "{{ fworch_group }}" become: true -# when: installation_mode == 'new' + diff --git a/roles/importer/tasks/main.yml b/roles/importer/tasks/main.yml index ac439a1c63..93cdd002d9 100644 --- a/roles/importer/tasks/main.yml +++ b/roles/importer/tasks/main.yml @@ -1,114 +1,92 @@ - block: - - name: initialize handler for datarecovery - set_fact: - importer_handler_guard: start - changed_when: true - notify: - - importer handler - when: installation_mode == "upgrade" + - name: initialize handler for datarecovery + set_fact: + importer_handler_guard: start + changed_when: true + notify: + - importer handler + when: installation_mode == "upgrade" - - name: check for importer dir - stat: - path: "{{ fworch_home }}/importer" - register: importer_dir_check + - name: check for importer dir + stat: + path: "{{ fworch_home }}/importer" + register: importer_dir_check - - name: backup importer dir - synchronize: - src: "{{ fworch_home }}/importer" - dest: "{{ fworch_home }}/backup_importer" - delegate_to: "{{ inventory_hostname }}" - when: importer_dir_check.stat.exists and installation_mode == "upgrade" + - name: backup importer dir + synchronize: + src: "{{ fworch_home }}/importer" + dest: "{{ fworch_home }}/backup_importer" + delegate_to: "{{ inventory_hostname }}" + when: importer_dir_check.stat.exists and installation_mode == "upgrade" - - name: remove importer dir - file: - state: absent - path: "{{ fworch_home }}/importer" - when: installation_mode == "upgrade" + - name: copy importer files + synchronize: + src: "importer" + dest: "{{ fworch_home }}" + rsync_opts: + - "--delete" + - "--chmod=0755" + - "--chown={{ fworch_user }}:{{ fworch_group }}" + tags: ["test"] - - name: Install importer perl modules - package: name={{ item }} state=present - loop: - - libdbi-perl - - libdbd-pg-perl - - libdate-calc-perl - - psmisc - - libnet-cidr-perl - - libsys-syslog-perl - - libexpect-perl - - libcgi-pm-perl - - python3-jsonpickle + - name: Install importer python3-venv package (for Ubuntu/Debian) + package: + name: python3-venv + state: present + when: ansible_python_interpreter == '/usr/bin/python3' # Skip if using custom python - - name: Install importer python modules - package: name={{ item }} state=present - loop: - - python3-netaddr - - name: copy importer files - copy: - src: "importer" - dest: "{{ fworch_home }}" - owner: "{{ fworch_user }}" - group: "{{ fworch_group }}" - mode: "0755" - tags: [ 'test' ] + - name: Create Python virtual environment + ansible.builtin.command: + cmd: '{{ ansible_python_interpreter }} -m venv {{ importer_venv_dir }}' + creates: "{{ importer_venv_dir }}" - - name: set x-flag for importer executables (top level only) - file: - path: "{{ item }}" - state: file - mode: "0755" - with_fileglob: "{{ fworch_home }}/importer/*" + - name: Install Python packages from requirements.txt + ansible.builtin.pip: + requirements: "{{ fworch_home }}/importer/requirements.txt" + virtualenv: "{{ importer_venv_dir }}" + environment: "{{ proxy_env }}" - - name: create default /var/{{ product_name }} dirs for importer - file: - path: "{{ item }}" - state: directory - owner: "{{ fworch_user }}" - group: "{{ fworch_group }}" - mode: "0755" - loop: - - /var/{{ product_name }} - - /var/{{ product_name }}/tmp - - /var/{{ product_name }}/import_archive + - name: set x-flag for importer executables (top level only) + file: + path: "{{ item }}" + state: file + mode: "0755" + with_fileglob: "{{ fworch_home }}/importer/*" - - name: copy import.conf - copy: - src: "import.conf" - dest: "{{ fworch_home }}/etc/import.conf" - mode: "0755" - owner: "{{ fworch_user }}" - group: "{{ fworch_group }}" + - name: create default /var/{{ product_name }} dirs for importer + file: + path: "{{ item }}" + state: directory + owner: "{{ fworch_user }}" + group: "{{ fworch_group }}" + mode: "0755" + loop: + - /var/{{ product_name }} + - /var/{{ product_name }}/tmp + - /var/{{ product_name }}/import_archive - - name: copy importer systemd service script - template: - src: "{{ product_name }}-importer-legacy.service.j2" - dest: "/lib/systemd/system/{{ product_name }}-importer-legacy.service" - backup: true - mode: "0644" - owner: "root" - become: true + - name: copy api-importer systemd service script + template: + src: "{{ product_name }}-importer-api.service.j2" + dest: "/lib/systemd/system/{{ product_name }}-importer-api.service" + backup: true + mode: "0644" + owner: "root" + become: true - - name: copy api-importer systemd service script - template: - src: "{{ product_name }}-importer-api.service.j2" - dest: "/lib/systemd/system/{{ product_name }}-importer-api.service" - backup: true - mode: "0644" - owner: "root" - become: true + - name: include fetch importer pwd script + import_tasks: fetch-importer-pwd.yml - - name: include fetch importer pwd script - import_tasks: fetch-importer-pwd.yml + - name: include upgrade script + import_tasks: run-upgrades.yml + when: "installation_mode == 'upgrade'" - - name: include upgrade script - import_tasks: run-upgrades.yml - when: "installation_mode == 'upgrade'" - - - name: finalize handler for datarecovery - set_fact: - importer_handler_guard: stop - changed_when: true - notify: "importer handler" - when: installation_mode == "upgrade" + - name: finalize handler for datarecovery + set_fact: + importer_handler_guard: stop + changed_when: true + notify: "importer handler" + when: installation_mode == "upgrade" become: true diff --git a/roles/importer/tasks/upgrade/9.0.0.yml b/roles/importer/tasks/upgrade/9.0.0.yml new file mode 100644 index 0000000000..80c6aa5aeb --- /dev/null +++ b/roles/importer/tasks/upgrade/9.0.0.yml @@ -0,0 +1,5 @@ +- name: Install importer python modules + package: name={{ item }} state=present + loop: + - python3-pydantic + become: true diff --git a/roles/importer/templates/fworch-importer-api.service.j2 b/roles/importer/templates/fworch-importer-api.service.j2 index 1287133fe5..78a64d53b7 100644 --- a/roles/importer/templates/fworch-importer-api.service.j2 +++ b/roles/importer/templates/fworch-importer-api.service.j2 @@ -12,16 +12,20 @@ After=network.target remote-fs.target nss-lookup.target {%- endif %} [Service] +Type=simple WorkingDirectory={{ importer_home }} ExecStartPre=/bin/sleep 10 -ExecStart={{ importer_home }}/import-main-loop.py -# ExecStop={{ importer_home }}/import-api-stop-helper +ExecStart={{ importer_venv_dir }}/bin/python {{ importer_home}}/import_main_loop.py +Environment="PATH={{ importer_venv_dir }}/bin:/usr/bin:/bin" +Environment="VIRTUAL_ENV={{ importer_venv_dir }}" TimeoutStopSec=300min StandardOutput=journal StandardError=journal SyslogIdentifier={{ product_name }}-importer-api User={{ fworch_user }} KillSignal=SIGINT +Group={{ fworch_group }} +Restart=always [Install] WantedBy=multi-user.target diff --git a/roles/importer/templates/fworch-importer-legacy.service.j2 b/roles/importer/templates/fworch-importer-legacy.service.j2 deleted file mode 100644 index ba32e021e3..0000000000 --- a/roles/importer/templates/fworch-importer-legacy.service.j2 +++ /dev/null @@ -1,17 +0,0 @@ -[Unit] -Description={{ product_name }} importer -After=network.target remote-fs.target nss-lookup.target postgresql.service - -[Service] -WorkingDirectory={{ importer_home }} -ExecStartPre=/bin/sleep 10 -ExecStart={{ importer_home }}/fworch-importer-main.pl -ExecStop={{ importer_home }}/import-stop-helper -StandardOutput=journal -StandardError=journal -SyslogIdentifier={{ product_name }}-importer-legacy -User={{ fworch_user }} -Environment="PERL5LIB={{ importer_home }}" - -[Install] -WantedBy=multi-user.target diff --git a/roles/lib/files/FWO.Api.Client/APIConnection.cs b/roles/lib/files/FWO.Api.Client/APIConnection.cs index 76c2ae95c2..e9266a1fb6 100644 --- a/roles/lib/files/FWO.Api.Client/APIConnection.cs +++ b/roles/lib/files/FWO.Api.Client/APIConnection.cs @@ -1,8 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; +using FWO.Logging; namespace FWO.Api.Client { @@ -12,7 +8,9 @@ public abstract class ApiConnection : IDisposable public event EventHandler? OnAuthHeaderChanged; - protected List subscriptions = new List(); + public Basics.Interfaces.ILogger Logger = new Logger(); + + protected List subscriptions = []; protected void InvokeOnAuthHeaderChanged(object? sender, string newAuthHeader) { @@ -23,22 +21,81 @@ protected void InvokeOnAuthHeaderChanged(object? sender, string newAuthHeader) public abstract void SetRole(string role); + public abstract void SetBestRole(System.Security.Claims.ClaimsPrincipal user, List targetRoleList); + public abstract void SetProperRole(System.Security.Claims.ClaimsPrincipal user, List targetRoleList); public abstract void SwitchBack(); - public abstract Task SendQueryAsync(string query, object? variables = null, string? operationName = null); + public async Task RunWithRole(string role, Func action) + { + SetRole(role); + try + { + await action(); + } + finally + { + SwitchBack(); + } + } + + public async Task RunWithRole(string role, Func> action) + { + SetRole(role); + try + { + return await action(); + } + finally + { + SwitchBack(); + } + } - public abstract GraphQlApiSubscription GetSubscription(Action exceptionHandler, GraphQlApiSubscription.SubscriptionUpdate subscriptionUpdateHandler, string subscription, object? variables = null, string? operationName = null); + public async Task RunWithProperRole(System.Security.Claims.ClaimsPrincipal user, List targetRoleList, Func action) + { + SetProperRole(user, targetRoleList); + try + { + await action(); + } + finally + { + SwitchBack(); + } + } - protected virtual void AddSubscription(ApiSubscription subscription) + public async Task RunWithProperRole(System.Security.Claims.ClaimsPrincipal user, List targetRoleList, Func> action) { - subscriptions.Add(subscription); + SetProperRole(user, targetRoleList); + try + { + return await action(); + } + finally + { + SwitchBack(); + } } + /// + /// Sends an API call and returns the deserialized result or throws on errors. + /// + public abstract Task SendQueryAsync(string query, object? variables = null, string? operationName = null); + + /// + /// Sends an API call and returns a non-throwing response wrapper containing data or errors. + /// + public abstract Task> SendQuerySafeAsync(string query, object? variables = null, string? operationName = null); + + public abstract GraphQlApiSubscription GetSubscription(Action exceptionHandler, + GraphQlApiSubscription.SubscriptionUpdate subscriptionUpdateHandler, string subscription, object? variables = null, string? operationName = null); + protected abstract void Dispose(bool disposing); + public abstract void DisposeSubscriptions(); - ~ ApiConnection() + ~ApiConnection() { if (disposed) return; Dispose(false); diff --git a/roles/lib/files/FWO.Api.Client/APIcalls/allObjects/getAllObjectDetails.graphql b/roles/lib/files/FWO.Api.Client/APIcalls/allObjects/getAllObjectDetails.graphql deleted file mode 100644 index e62d3c8f9f..0000000000 --- a/roles/lib/files/FWO.Api.Client/APIcalls/allObjects/getAllObjectDetails.graphql +++ /dev/null @@ -1,62 +0,0 @@ -query getAllObjectDetails ( - $management_id: [Int!] - $type: [String!] - $uid: [String!] - $time: String - $obj_name: [String!] - $limit: Int - $offset: Int -) { - management( - where: { - hide_in_gui: { _eq: false } - mgm_id: { _in: $management_id } - stm_dev_typ:{ - is_pure_routing_device:{_eq:false} - } - } - order_by: { mgm_name: asc } - ) { - id: mgm_id - name: mgm_name - networkObjects: objects ( - limit: $limit - offset: $offset - where: { - stm_obj_typ: { obj_typ_name: { _in: $type } } - active: { _eq: true } - obj_name: { _in: $obj_name } - obj_uid: { _in: $uid } - } - order_by: { obj_name: asc } - ) { - ...networkObjectDetails - } - serviceObjects: services ( - limit: $limit - offset: $offset - where: { - stm_svc_typ: { svc_typ_name: { _in: $type } } - active: { _eq: true } - svc_name: { _in: $obj_name } - svc_uid: { _in: $uid } - } - order_by: { svc_name: asc } - ) { - ...networkServiceDetails - } - userObjects: usrs ( - limit: $limit - offset: $offset - where: { - stm_usr_typ: { usr_typ_name: { _in: $type } } - active: { _eq: true } - user_name: { _in: $obj_name } - user_uid: { _in: $uid } - } - order_by: { user_name: asc } - ) { - ...userDetails - } - } -} diff --git a/roles/lib/files/FWO.Api.Client/APIcalls/auth/addUser.graphql b/roles/lib/files/FWO.Api.Client/APIcalls/auth/addUser.graphql deleted file mode 100644 index 9523a3ad7d..0000000000 --- a/roles/lib/files/FWO.Api.Client/APIcalls/auth/addUser.graphql +++ /dev/null @@ -1,25 +0,0 @@ -mutation addUser( - $uiuser_username: String! - $uuid: String! - $email: String - $tenant: Int - $loginTime: timestamptz - $passwordMustBeChanged: Boolean - $ldapConnectionId: bigint -) { - insert_uiuser( - objects: { - uiuser_username: $uiuser_username - uuid: $uuid - uiuser_email: $email - tenant_id: $tenant - uiuser_last_login: $loginTime - uiuser_password_must_be_changed: $passwordMustBeChanged - ldap_connection_id: $ldapConnectionId - } - ) { - returning { - newId: uiuser_id - } - } -} diff --git a/roles/lib/files/FWO.Api.Client/APIcalls/auth/deleteDeviceFromTenant.graphql b/roles/lib/files/FWO.Api.Client/APIcalls/auth/deleteDeviceFromTenant.graphql deleted file mode 100644 index 27b89c10b2..0000000000 --- a/roles/lib/files/FWO.Api.Client/APIcalls/auth/deleteDeviceFromTenant.graphql +++ /dev/null @@ -1,12 +0,0 @@ -mutation delete_tenant_to_device_by_pk ( - $tenantId: Int! - $deviceId: Int! -) { - delete_tenant_to_device_by_pk ( - tenant_id: $tenantId - device_id: $deviceId - ) { - DeletedId: device_id - } -} - diff --git a/roles/lib/files/FWO.Api.Client/APIcalls/auth/getLdapConnections.graphql b/roles/lib/files/FWO.Api.Client/APIcalls/auth/getLdapConnections.graphql deleted file mode 100644 index 1f630fea69..0000000000 --- a/roles/lib/files/FWO.Api.Client/APIcalls/auth/getLdapConnections.graphql +++ /dev/null @@ -1,24 +0,0 @@ -# returns a list of all available ldap connections -# the field ldap_searchpath_for_roles is not null only for the internal ldap - -query getLdapConnections { - ldap_connection(where: {active: {_eq: true}} order_by: {ldap_connection_id: desc}) { - ldap_name - ldap_server - ldap_port - ldap_type - ldap_pattern_length - ldap_search_user - ldap_tls - ldap_tenant_level - ldap_connection_id - ldap_search_user_pwd - ldap_searchpath_for_users - ldap_searchpath_for_roles - ldap_searchpath_for_groups - ldap_write_user - ldap_write_user_pwd - tenant_id - ldap_global_tenant_name - } -} diff --git a/roles/lib/files/FWO.Api.Client/APIcalls/auth/getTenants.graphql b/roles/lib/files/FWO.Api.Client/APIcalls/auth/getTenants.graphql deleted file mode 100644 index 32064aefe9..0000000000 --- a/roles/lib/files/FWO.Api.Client/APIcalls/auth/getTenants.graphql +++ /dev/null @@ -1,16 +0,0 @@ -query getTenants { - tenant { - tenant_id - tenant_name - tenant_comment - tenant_projekt - tenant_can_view_all_devices - tenant_is_superadmin - tenant_to_devices { - device { - id: dev_id - name: dev_name - } - } - } -} diff --git a/roles/lib/files/FWO.Api.Client/APIcalls/compliance/addNetworkZone.graphql b/roles/lib/files/FWO.Api.Client/APIcalls/compliance/addNetworkZone.graphql deleted file mode 100644 index 8b81935486..0000000000 --- a/roles/lib/files/FWO.Api.Client/APIcalls/compliance/addNetworkZone.graphql +++ /dev/null @@ -1,25 +0,0 @@ -mutation insert_compliance_network_zone ($name: String!, $description: String!, $ip_ranges: [compliance_ip_range_insert_input!]!, $super_network_zone_id: bigint, -$communication_sources: [compliance_network_zone_communication_insert_input!]!, $communication_destinations: [compliance_network_zone_communication_insert_input!]!, -$sub_network_zones: [compliance_network_zone_insert_input!]!) { - insert_compliance_network_zone_one ( - object: { - super_network_zone_id: $super_network_zone_id, - name: $name, - description: $description, - ip_ranges: { - data: $ip_ranges - }, - network_zone_communication_destinations: { - data: $communication_destinations - }, - network_zone_communication_sources: { - data: $communication_sources - }, - sub_network_zones: { - data: $sub_network_zones - } - } - ) { - id - } -} \ No newline at end of file diff --git a/roles/lib/files/FWO.Api.Client/APIcalls/compliance/deleteNetworkZone.graphql b/roles/lib/files/FWO.Api.Client/APIcalls/compliance/deleteNetworkZone.graphql deleted file mode 100644 index 7800da5be1..0000000000 --- a/roles/lib/files/FWO.Api.Client/APIcalls/compliance/deleteNetworkZone.graphql +++ /dev/null @@ -1,7 +0,0 @@ -mutation delete_compliance_network_zone ($id: bigint!) { - delete_compliance_network_zone_by_pk ( - id: $id - ) { - id - } -} diff --git a/roles/lib/files/FWO.Api.Client/APIcalls/compliance/getNetworkZones.graphql b/roles/lib/files/FWO.Api.Client/APIcalls/compliance/getNetworkZones.graphql deleted file mode 100644 index cca37df145..0000000000 --- a/roles/lib/files/FWO.Api.Client/APIcalls/compliance/getNetworkZones.graphql +++ /dev/null @@ -1,31 +0,0 @@ -query get_compliance_network_zones { - compliance_network_zone (order_by: {name: asc}) { - id - name - description - ip_ranges { - ip_range_start - ip_range_end - } - super_network_zone { - id - name - } - sub_network_zones { - id - name - } - network_zone_communication_destinations { - to_network_zone { - id - name - } - } - network_zone_communication_sources { - from_network_zone { - id - name - } - } - } -} \ No newline at end of file diff --git a/roles/lib/files/FWO.Api.Client/APIcalls/compliance/updateNetworkZone.graphql b/roles/lib/files/FWO.Api.Client/APIcalls/compliance/updateNetworkZone.graphql deleted file mode 100644 index 3b25ce7fb4..0000000000 --- a/roles/lib/files/FWO.Api.Client/APIcalls/compliance/updateNetworkZone.graphql +++ /dev/null @@ -1,68 +0,0 @@ -mutation update_compliance_network_zone ($network_zone_id: bigint!, $name: String!, $description: String!, $super_network_zone_id: bigint, - $add_ip_ranges: [compliance_ip_range_insert_input!]!, $delete_ip_ranges_exp: [compliance_ip_range_bool_exp!]!, - $add_zone_communication: [compliance_network_zone_communication_insert_input!]!, $delete_zone_communication_exp: [compliance_network_zone_communication_bool_exp!]!, - $add_sub_zones_exp: [compliance_network_zone_bool_exp!]!, $delete_sub_zones_exp: [compliance_network_zone_bool_exp!]!) -{ - update_compliance_network_zone ( - where: {id: {_eq: $network_zone_id}} - _set: { - name: $name, - description: $description, - super_network_zone_id: $super_network_zone_id - } - ) { - affected_rows - } - - delete_compliance_ip_range ( - where: { - network_zone_id: {_eq: $network_zone_id}, - _or: $delete_ip_ranges_exp - } - ) { - affected_rows - } - - insert_compliance_ip_range ( - objects: $add_ip_ranges - ) { - affected_rows - } - - delete_compliance_network_zone_communication ( - where: { - _or: $delete_zone_communication_exp - } - ) { - affected_rows - } - - insert_compliance_network_zone_communication ( - objects: $add_zone_communication - ) { - affected_rows - } - - update_compliance_network_zone_many ( - updates: [ - { - where: { - _or: $delete_sub_zones_exp - } - _set: { - super_network_zone_id: null - } - }, - { - where: { - _or: $add_sub_zones_exp - } - _set: { - super_network_zone_id: $network_zone_id - } - } - ] - ) { - affected_rows - } -} \ No newline at end of file diff --git a/roles/lib/files/FWO.Api.Client/APIcalls/compliance/updateNetworkZoneCommunication.graphql b/roles/lib/files/FWO.Api.Client/APIcalls/compliance/updateNetworkZoneCommunication.graphql deleted file mode 100644 index 54aed3e5f2..0000000000 --- a/roles/lib/files/FWO.Api.Client/APIcalls/compliance/updateNetworkZoneCommunication.graphql +++ /dev/null @@ -1,18 +0,0 @@ -mutation update_compliance_network_zone_communication( - $delete_zone_communication_exp: [compliance_network_zone_communication_bool_exp!]!, - $add_zone_communication: [compliance_network_zone_communication_insert_input!]!,) -{ - delete_compliance_network_zone_communication ( - where: { - _or: $delete_zone_communication_exp - } - ) { - affected_rows - } - - insert_compliance_network_zone_communication ( - objects: $add_zone_communication - ) { - affected_rows - } -} \ No newline at end of file diff --git a/roles/lib/files/FWO.Api.Client/APIcalls/config/getConfigSubscription.graphql b/roles/lib/files/FWO.Api.Client/APIcalls/config/getConfigSubscription.graphql deleted file mode 100644 index 1ef57c7876..0000000000 --- a/roles/lib/files/FWO.Api.Client/APIcalls/config/getConfigSubscription.graphql +++ /dev/null @@ -1,6 +0,0 @@ -subscription getConfigItemsByUser($userId: Int) { - config(where: {config_user: {_eq: $userId}}) { - config_key - config_value - } -} diff --git a/roles/lib/files/FWO.Api.Client/APIcalls/config/subscribeDailyCheckConfigChanges.graphql b/roles/lib/files/FWO.Api.Client/APIcalls/config/subscribeDailyCheckConfigChanges.graphql deleted file mode 100644 index f7f1f26165..0000000000 --- a/roles/lib/files/FWO.Api.Client/APIcalls/config/subscribeDailyCheckConfigChanges.graphql +++ /dev/null @@ -1,6 +0,0 @@ -subscription subscribeDailyCheckConfigChanges { - config (where: { config_key: {_eq: "dailyCheckStartAt"}}, limit: 1){ - config_key - config_value - } -} diff --git a/roles/lib/files/FWO.Api.Client/APIcalls/monitor/getImportStatus.graphql b/roles/lib/files/FWO.Api.Client/APIcalls/monitor/getImportStatus.graphql deleted file mode 100644 index 906af35195..0000000000 --- a/roles/lib/files/FWO.Api.Client/APIcalls/monitor/getImportStatus.graphql +++ /dev/null @@ -1,49 +0,0 @@ -query getImportStatus { - management(where: {stm_dev_typ: {dev_typ_is_multi_mgmt: {_eq: false}}} order_by: { mgm_name: asc }) { - mgm_id - mgm_name - importDisabled: do_not_import - last_import_attempt - last_import_attempt_successful - deviceType: stm_dev_typ { - id: dev_typ_id - name: dev_typ_name - version: dev_typ_version - manufacturer: dev_typ_manufacturer - isPureRoutingDevice: is_pure_routing_device - } - last_import: import_controls(order_by: { control_id: desc }, limit: 1) { - control_id - start_time - stop_time - successful_import - import_errors - } - last_successful_import: import_controls(where: { successful_import: {_eq: true} } order_by: {control_id: desc}, limit: 1) { - control_id - start_time - stop_time - successful_import - import_errors - } - last_incomplete_import: import_controls(where: { successful_import: {_eq: false}, stop_time: { _is_null: true } } order_by: {control_id: desc}, limit: 1) { - control_id - start_time - stop_time - successful_import - import_errors - } - first_import: import_controls(order_by: { control_id: asc }, limit: 1) { - control_id - start_time - stop_time - successful_import - import_errors - } - erroneous_imports: import_controls(where: { successful_import: {_eq: false} } order_by: {control_id: desc}) { - control_id - import_errors - } - - } -} diff --git a/roles/lib/files/FWO.Api.Client/APIcalls/networkObject/fragments/networkObjectDetails.graphql b/roles/lib/files/FWO.Api.Client/APIcalls/networkObject/fragments/networkObjectDetails.graphql deleted file mode 100644 index 2c218a6a1b..0000000000 --- a/roles/lib/files/FWO.Api.Client/APIcalls/networkObject/fragments/networkObjectDetails.graphql +++ /dev/null @@ -1,49 +0,0 @@ -fragment networkObjectDetails on object { - obj_id - obj_name - obj_ip - obj_ip_end - obj_uid - zone { - zone_id - zone_name - } - active - obj_create - obj_create_time: import_control { - time: start_time - } - obj_last_seen - type: stm_obj_typ { - name: obj_typ_name - } - obj_comment - obj_member_names - obj_member_refs - objgrps(order_by: {objgrp_member_id: asc}) { - id: objgrp_member_id - byId: objectByObjgrpMemberId { - obj_id - obj_name - type: stm_obj_typ { - name: obj_typ_name - } - } - } - objgrp_flats(order_by: {objgrp_flat_member_id: asc}) { - id_flat: objgrp_flat_id - byFlatId: objectByObjgrpFlatMemberId { - network_object_limits { - first_ip - last_ip - } - obj_id - obj_name - obj_ip - obj_ip_end - type: stm_obj_typ { - name: obj_typ_name - } - } - } -} diff --git a/roles/lib/files/FWO.Api.Client/APIcalls/networkObject/getNetworkObjectDetails.graphql b/roles/lib/files/FWO.Api.Client/APIcalls/networkObject/getNetworkObjectDetails.graphql deleted file mode 100644 index 6a94e0a261..0000000000 --- a/roles/lib/files/FWO.Api.Client/APIcalls/networkObject/getNetworkObjectDetails.graphql +++ /dev/null @@ -1,29 +0,0 @@ -query getNetworkObjectDetails( - $management_id: [Int!] - $nwObjTyp: [String!] - $nwObjUid: [String!] - $time: String - $obj_name: [String!] - $obj_ip: [cidr!] - $limit: Int - $offset: Int -) { - management(where: { mgm_id: { _in: $management_id }, stm_dev_typ:{dev_typ_is_multi_mgmt:{_eq:false}} }) { - id: mgm_id - name: mgm_name - networkObjects: objects( - limit: $limit - offset: $offset - where: { - stm_obj_typ: { obj_typ_name: { _in: $nwObjTyp } } - active: { _eq: true } - obj_name: { _in: $obj_name } - obj_ip: { _in: $obj_ip } - obj_uid: { _in: $nwObjUid } - } - order_by: { obj_name: asc } - ) { - ...networkObjectDetails - } - } -} diff --git a/roles/lib/files/FWO.Api.Client/APIcalls/networkService/fragments/networkServiceDetails.graphql b/roles/lib/files/FWO.Api.Client/APIcalls/networkService/fragments/networkServiceDetails.graphql deleted file mode 100644 index 92a0a6f904..0000000000 --- a/roles/lib/files/FWO.Api.Client/APIcalls/networkService/fragments/networkServiceDetails.graphql +++ /dev/null @@ -1,55 +0,0 @@ -fragment networkServiceDetails on service { - svc_id - svc_name - svc_uid - svc_port - svc_port_end - svc_source_port - svc_source_port_end - svc_code - svc_timeout - svc_typ_id - active - svc_create - svc_create_time: import_control { - time: start_time - } - svc_last_seen - service_type: stm_svc_typ { - name: svc_typ_name - } - svc_comment - svc_color_id - protocol_name: stm_ip_proto { - id: ip_proto_id - name: ip_proto_name - } - svc_member_names - svc_member_refs - svcgrps(order_by: { svcgrp_member_id: asc }) { - id: svcgrp_member_id - byId: serviceBySvcgrpMemberId { - svc_id - svc_name - service_type: stm_svc_typ { - name: svc_typ_name - } - } - } - svcgrp_flats(order_by: { svcgrp_flat_member_id: asc }) { - flat_id: svcgrp_flat_id - byFlatId: serviceBySvcgrpFlatMemberId { - svc_id - svc_name - svc_port - svc_port_end - protocol_name: stm_ip_proto { - id: ip_proto_id - name: ip_proto_name - } - service_type: stm_svc_typ { - name: svc_typ_name - } - } - } -} diff --git a/roles/lib/files/FWO.Api.Client/APIcalls/networkService/getNetworkServiceDetails.graphql b/roles/lib/files/FWO.Api.Client/APIcalls/networkService/getNetworkServiceDetails.graphql deleted file mode 100644 index 9b1588fa1d..0000000000 --- a/roles/lib/files/FWO.Api.Client/APIcalls/networkService/getNetworkServiceDetails.graphql +++ /dev/null @@ -1,25 +0,0 @@ -query getNetworkServiceDetails( - $management_id: [Int!] - $time: String - $svc_name: [String!] - $svc_port: [Int!] - $limit: Int - $offset: Int -) { - management(where: { mgm_id: { _in: $management_id }, stm_dev_typ:{dev_typ_is_multi_mgmt:{_eq:false}} }) { - id: mgm_id - name: mgm_name - serviceObjects : services( - limit: $limit - offset: $offset - where: { - active: { _eq: true } - svc_name: { _in: $svc_name } - svc_port: { _in: $svc_port } - } - order_by: { svc_name: asc } - ) { - ...networkServiceDetails - } - } -} diff --git a/roles/lib/files/FWO.Api.Client/APIcalls/owner/deleteNetworkOwnerships.graphql b/roles/lib/files/FWO.Api.Client/APIcalls/owner/deleteNetworkOwnerships.graphql deleted file mode 100644 index 82fe219a25..0000000000 --- a/roles/lib/files/FWO.Api.Client/APIcalls/owner/deleteNetworkOwnerships.graphql +++ /dev/null @@ -1,5 +0,0 @@ -mutation deleteNetworkOwnerships($ownerId: Int!) { - delete_owner_network(where: {owner_id: {_eq: $ownerId}}) { - affected_rows - } -} diff --git a/roles/lib/files/FWO.Api.Client/APIcalls/owner/fragments/ownerDetails.graphql b/roles/lib/files/FWO.Api.Client/APIcalls/owner/fragments/ownerDetails.graphql deleted file mode 100644 index c7031f2ec3..0000000000 --- a/roles/lib/files/FWO.Api.Client/APIcalls/owner/fragments/ownerDetails.graphql +++ /dev/null @@ -1,12 +0,0 @@ -fragment ownerDetails on owner { - id - name - dn - group_dn - is_default - tenant_id - recert_interval - app_id_external - recert_check_params - last_recert_check -} diff --git a/roles/lib/files/FWO.Api.Client/APIcalls/owner/getOwnerIdsForUser.graphql b/roles/lib/files/FWO.Api.Client/APIcalls/owner/getOwnerIdsForUser.graphql deleted file mode 100644 index 569645a713..0000000000 --- a/roles/lib/files/FWO.Api.Client/APIcalls/owner/getOwnerIdsForUser.graphql +++ /dev/null @@ -1,7 +0,0 @@ - -query getOwnerIdsForUser ($userDn: String!) { - owner (where: {dn: {_eq: $userDn}} order_by: { id: asc }){ - id - recert_interval - } -} diff --git a/roles/lib/files/FWO.Api.Client/APIcalls/owner/getOwnerIdsFromGroups.graphql b/roles/lib/files/FWO.Api.Client/APIcalls/owner/getOwnerIdsFromGroups.graphql deleted file mode 100644 index d8b8bbf99c..0000000000 --- a/roles/lib/files/FWO.Api.Client/APIcalls/owner/getOwnerIdsFromGroups.graphql +++ /dev/null @@ -1,7 +0,0 @@ - -query getOwnerIdsFromGroups ($groupDns: [String]!) { - owner (where: {group_dn: {_in: $groupDns}} order_by: { id: asc }){ - id - recert_interval - } -} diff --git a/roles/lib/files/FWO.Api.Client/APIcalls/owner/newNetworkOwnership.graphql b/roles/lib/files/FWO.Api.Client/APIcalls/owner/newNetworkOwnership.graphql deleted file mode 100644 index 69ddf5a652..0000000000 --- a/roles/lib/files/FWO.Api.Client/APIcalls/owner/newNetworkOwnership.graphql +++ /dev/null @@ -1,13 +0,0 @@ -mutation newNetworkOwnership( - $ownerId: Int! - $ip: cidr - ) { - insert_owner_network(objects: { - owner_id: $ownerId - ip: $ip - }) { - returning { - newId: id - } - } -} diff --git a/roles/lib/files/FWO.Api.Client/APIcalls/owner/newOwner.graphql b/roles/lib/files/FWO.Api.Client/APIcalls/owner/newOwner.graphql deleted file mode 100644 index d80d4ba113..0000000000 --- a/roles/lib/files/FWO.Api.Client/APIcalls/owner/newOwner.graphql +++ /dev/null @@ -1,23 +0,0 @@ -mutation newOwner( - $name: String! - $dn: String! - $groupDn: String! - $tenantId: Int - $recertInterval: Int - $appIdExternal: String! - $recertCheckParams: String - ) { - insert_owner(objects: { - name: $name - dn: $dn - group_dn: $groupDn - tenant_id: $tenantId - recert_interval: $recertInterval - app_id_external: $appIdExternal - recert_check_params: $recertCheckParams - }) { - returning { - newId: id - } - } -} diff --git a/roles/lib/files/FWO.Api.Client/APIcalls/owner/updateOwner.graphql b/roles/lib/files/FWO.Api.Client/APIcalls/owner/updateOwner.graphql deleted file mode 100644 index f273b3fbd8..0000000000 --- a/roles/lib/files/FWO.Api.Client/APIcalls/owner/updateOwner.graphql +++ /dev/null @@ -1,24 +0,0 @@ -mutation updateOwner( - $id: Int! - $name: String! - $dn: String! - $groupDn: String! - $tenantId: Int - $recertInterval: Int - $appIdExternal: String! - $recertCheckParams: String - ) { - update_owner_by_pk( - pk_columns: { id: $id } - _set: { - name: $name - dn: $dn - group_dn: $groupDn - tenant_id: $tenantId - recert_interval: $recertInterval - app_id_external: $appIdExternal - recert_check_params: $recertCheckParams - }) { - UpdatedId: id - } -} diff --git a/roles/lib/files/FWO.Api.Client/APIcalls/recertification/addRecertEntries.graphql b/roles/lib/files/FWO.Api.Client/APIcalls/recertification/addRecertEntries.graphql deleted file mode 100644 index b5b6011556..0000000000 --- a/roles/lib/files/FWO.Api.Client/APIcalls/recertification/addRecertEntries.graphql +++ /dev/null @@ -1,9 +0,0 @@ -mutation addOpenRecerts($recerts:[recertification_insert_input!]!) { - insert_recertification( - objects: $recerts - ) { - returning { - id - } - } -} diff --git a/roles/lib/files/FWO.Api.Client/APIcalls/recertification/clearOpenRecerts.graphql b/roles/lib/files/FWO.Api.Client/APIcalls/recertification/clearOpenRecerts.graphql deleted file mode 100644 index 209d55b087..0000000000 --- a/roles/lib/files/FWO.Api.Client/APIcalls/recertification/clearOpenRecerts.graphql +++ /dev/null @@ -1,13 +0,0 @@ -mutation clearOpenRecerts($ownerId: Int, $mgmId: Int) { - delete_recertification( - where: { - owner_id: { _eq: $ownerId } - rule_metadatum: { device: { mgm_id: { _eq: $mgmId } } } - recert_date: { _is_null: true } - } - ) { - returning { - id - } - } -} diff --git a/roles/lib/files/FWO.Api.Client/APIcalls/recertification/fragments/ruleOpenCertOverview.graphql b/roles/lib/files/FWO.Api.Client/APIcalls/recertification/fragments/ruleOpenCertOverview.graphql deleted file mode 100644 index e8f07924b8..0000000000 --- a/roles/lib/files/FWO.Api.Client/APIcalls/recertification/fragments/ruleOpenCertOverview.graphql +++ /dev/null @@ -1,81 +0,0 @@ -fragment ruleOpenCertOverview on rule { - rule_id - rule_uid - rule_action - device { - dev_id - } - section_header: rule_head_text - rule_comment - rule_track - rule_disabled - src_zone: zone { - zone_name - zone_id - } - rule_metadatum { - rule_metadata_id - rule_created - rule_first_hit - rule_last_hit - rule_last_modified - rule_last_certified - rule_last_certifier_dn - rule_to_be_removed - rule_decert_date - rule_recertification_comment - recertification: recertifications (where: { owner: $ownerWhere, recert_date: {_is_null: true}, next_recert_date: {_lte: $refdate1}}, order_by: { owner: { name: asc }}) { - recert_date - recertified - ip_match - next_recert_date - owner { - id - group_dn - name - } - } - recert_history: recertifications (where: { owner: $ownerWhere, recert_date: {_is_null: false}}, order_by: { recert_date: desc }) { - recert_date - recertified - user_dn - comment - owner { - name - } - } - } - rule_src_neg - rule_dst_neg - rule_svc_neg - rule_num_numeric - rule_name - access_rule - nat_rule - xlate_rule - rule_froms { - usr { - ...userOverview - } - object { - ...networkObjectOverview - } - } - dst_zone: zoneByRuleToZone { - zone_name - zone_id - } - rule_tos { - usr { - ...userOverview - } - object { - ...networkObjectOverview - } - } - rule_services { - service { - ...networkServiceOverview - } - } -} diff --git a/roles/lib/files/FWO.Api.Client/APIcalls/recertification/getOpenRecerts.graphql b/roles/lib/files/FWO.Api.Client/APIcalls/recertification/getOpenRecerts.graphql deleted file mode 100644 index 0c96596aa8..0000000000 --- a/roles/lib/files/FWO.Api.Client/APIcalls/recertification/getOpenRecerts.graphql +++ /dev/null @@ -1,17 +0,0 @@ -query getFutureRecertsForOwners($ownerId: Int!, $mgmId: Int!) { - recert_get_one_owner_one_mgm( - where: { recert_date: { _is_null: true } } - args: { i_mgm_id: $mgmId, i_owner_id: $ownerId } - ) { - id - rule_metadata_id - rule_id - ip_match - owner_id - user_dn - recertified - next_recert_date - recert_date - comment - } -} diff --git a/roles/lib/files/FWO.Api.Client/APIcalls/report/deleteGeneratedReport.graphql b/roles/lib/files/FWO.Api.Client/APIcalls/report/deleteGeneratedReport.graphql deleted file mode 100644 index 5e7ffe478c..0000000000 --- a/roles/lib/files/FWO.Api.Client/APIcalls/report/deleteGeneratedReport.graphql +++ /dev/null @@ -1,7 +0,0 @@ -mutation deleteGeneratedReport ($report_id : bigint!) { - delete_report( - where: {report_id: {_eq: $report_id}} - ) { - affected_rows - } -} \ No newline at end of file diff --git a/roles/lib/files/FWO.Api.Client/APIcalls/report/editReportTemplate.graphql b/roles/lib/files/FWO.Api.Client/APIcalls/report/editReportTemplate.graphql deleted file mode 100644 index 5b08744dd5..0000000000 --- a/roles/lib/files/FWO.Api.Client/APIcalls/report/editReportTemplate.graphql +++ /dev/null @@ -1,23 +0,0 @@ -mutation editReportTemplate( - $reportTemplateId: Int - $reportTemplateName: String - $reportTemplateCreate: timestamp - $reportTemplateComment: String - $reportFilterLine: String - $reportTemplateOwner: Int - $reportParameters: json -) { - update_report_template( - where: { report_template_id: { _eq: $reportTemplateId } } - _set: { - report_template_name: $reportTemplateName - report_template_create: $reportTemplateCreate - report_template_comment: $reportTemplateComment - report_filter: $reportFilterLine - report_template_owner: $reportTemplateOwner - report_parameters: $reportParameters - } - ) { - affected_rows - } -} diff --git a/roles/lib/files/FWO.Api.Client/APIcalls/report/getAllObjectDetailsInReport.graphql b/roles/lib/files/FWO.Api.Client/APIcalls/report/getAllObjectDetailsInReport.graphql deleted file mode 100644 index da6290fd36..0000000000 --- a/roles/lib/files/FWO.Api.Client/APIcalls/report/getAllObjectDetailsInReport.graphql +++ /dev/null @@ -1,33 +0,0 @@ -query getObjectsInReport( - $mgmIds: [Int!] - $ruleIds: _int8 - $importId: bigint - $limit: Int - $offset: Int -) { - management(where: { mgm_id: { _in: $mgmIds }, stm_dev_typ:{dev_typ_is_multi_mgmt:{_eq:false}} }) { - name: mgm_name - id: mgm_id - reportNetworkObjects: filter_rule_nwobj_resolveds ( - args: {rule_ids: $ruleIds, import_id: $importId} - limit: $limit - offset: $offset - ) { - ...networkObjectDetails - } - reportServiceObjects: filter_rule_svc_resolveds ( - args: {rule_ids: $ruleIds, import_id: $importId} - limit: $limit - offset: $offset - ) { - ...networkServiceDetails - } - reportUserObjects: filter_rule_user_resolveds ( - args: {rule_ids: $ruleIds, import_id: $importId} - limit: $limit - offset: $offset - ) { - ...userDetails - } - } -} diff --git a/roles/lib/files/FWO.Api.Client/APIcalls/report/getGeneratedReports.graphql b/roles/lib/files/FWO.Api.Client/APIcalls/report/getGeneratedReports.graphql deleted file mode 100644 index f885eede1d..0000000000 --- a/roles/lib/files/FWO.Api.Client/APIcalls/report/getGeneratedReports.graphql +++ /dev/null @@ -1,16 +0,0 @@ -query getGeneratedReports { - report(order_by:{report_id:desc}) { - report_id - report_name - report_start_time - report_end_time - report_type - description - uiuser { - uiuser_username - } - report_template { - report_template_name - } - } -} diff --git a/roles/lib/files/FWO.Api.Client/APIcalls/report/getNetworkObjectDetailsInReport.graphql b/roles/lib/files/FWO.Api.Client/APIcalls/report/getNetworkObjectDetailsInReport.graphql deleted file mode 100644 index dfa0d9faa3..0000000000 --- a/roles/lib/files/FWO.Api.Client/APIcalls/report/getNetworkObjectDetailsInReport.graphql +++ /dev/null @@ -1,19 +0,0 @@ -query getNetworkObjectsInReport ( - $mgmIds: [Int!] - $importId: bigint - $ruleIds: _int8 - $limit: Int - $offset: Int -) { - management(where: { mgm_id: { _in: $mgmIds }, stm_dev_typ:{dev_typ_is_multi_mgmt:{_eq:false}} }) { - name: mgm_name - id: mgm_id - reportNetworkObjects: filter_rule_nwobj_resolveds ( - args: {rule_ids: $ruleIds, import_id: $importId} - limit: $limit - offset: $offset - ) { - ...networkObjectDetails - } - } -} diff --git a/roles/lib/files/FWO.Api.Client/APIcalls/report/getNetworkServiceDetailsInReport.graphql b/roles/lib/files/FWO.Api.Client/APIcalls/report/getNetworkServiceDetailsInReport.graphql deleted file mode 100644 index 51f708ed17..0000000000 --- a/roles/lib/files/FWO.Api.Client/APIcalls/report/getNetworkServiceDetailsInReport.graphql +++ /dev/null @@ -1,19 +0,0 @@ -query getServicesInReport ( - $mgmIds: [Int!] - $importId: bigint - $ruleIds: _int8 - $limit: Int - $offset: Int -) { - management(where: { mgm_id: { _in: $mgmIds }, stm_dev_typ:{dev_typ_is_multi_mgmt:{_eq:false}} }) { - name: mgm_name - id: mgm_id - reportServiceObjects: filter_rule_svc_resolveds ( - args: {rule_ids: $ruleIds, import_id: $importId} - limit: $limit - offset: $offset - ) { - ...networkServiceDetails - } - } -} diff --git a/roles/lib/files/FWO.Api.Client/APIcalls/report/getObjectsNotInReport.graphql b/roles/lib/files/FWO.Api.Client/APIcalls/report/getObjectsNotInReport.graphql deleted file mode 100644 index fe817e1b2d..0000000000 --- a/roles/lib/files/FWO.Api.Client/APIcalls/report/getObjectsNotInReport.graphql +++ /dev/null @@ -1,22 +0,0 @@ - -query getObjectsNotInReport($mgmIds: [Int!], $ruleIds: [bigint!]!) { - management(where: {mgm_id: {_in: $mgmIds}}) { - name: mgm_name - id: mgm_id - reportNetworkObjects: rule_nwobj_resolveds(where: {rule_id: {_nin: $ruleIds}}, distinct_on: [obj_id]) { - object { - ...networkObjectDetails - } - } - reportServiceObjects: rule_svc_resolveds(distinct_on: [svc_id], where: {rule_id: {_nin: $ruleIds}}) { - service { - ...networkServiceDetails - } - } - reportUserObjects: rule_user_resolveds(distinct_on: [user_id], where: {rule_id: {_nin: $ruleIds}}) { - usr { - ...userDetails - } - } - } -} diff --git a/roles/lib/files/FWO.Api.Client/APIcalls/report/getRelevantImportIdsAtTime.graphql b/roles/lib/files/FWO.Api.Client/APIcalls/report/getRelevantImportIdsAtTime.graphql deleted file mode 100644 index 7a8aec8b00..0000000000 --- a/roles/lib/files/FWO.Api.Client/APIcalls/report/getRelevantImportIdsAtTime.graphql +++ /dev/null @@ -1,20 +0,0 @@ -query getRelevantImportIdsAtTime($time: timestamp!, $mgmIds: [Int!]) { - management(where: { - hide_in_gui: {_eq: false} - mgm_id: {_in: $mgmIds} - stm_dev_typ:{ - dev_typ_is_multi_mgmt:{_eq:false} - is_pure_routing_device:{_eq:false} - } - } order_by: {mgm_name: asc}) { - Name: mgm_name - id: mgm_id - import: import_controls_aggregate(where: {stop_time: {_lte: $time}, successful_import: {_eq: true}, changes_found: {_eq: true}}) { - aggregate { - max { - id: control_id - } - } - } - } -} diff --git a/roles/lib/files/FWO.Api.Client/APIcalls/report/getReportSchedules.graphql b/roles/lib/files/FWO.Api.Client/APIcalls/report/getReportSchedules.graphql deleted file mode 100644 index 91053869dd..0000000000 --- a/roles/lib/files/FWO.Api.Client/APIcalls/report/getReportSchedules.graphql +++ /dev/null @@ -1,27 +0,0 @@ -query getReportSchedules { - report_schedule(order_by: {report_schedule_id: desc}) { - report_schedule_id - report_schedule_name - report_schedule_every - report_schedule_repeat - report_schedule_start_time - report_schedule_owner_user: uiuser { - uiuser_id - uiuser_username - ldap_connection: ldap_connection { - ldap_connection_id - } - } - report_schedule_active - report_schedule_template: report_template { - report_template_id - report_template_name - report_filter - report_parameters - } - report_schedule_formats { - report_schedule_format_name - } - report_schedule_counter - } -} diff --git a/roles/lib/files/FWO.Api.Client/APIcalls/report/getRuleIdsOfImport.graphql b/roles/lib/files/FWO.Api.Client/APIcalls/report/getRuleIdsOfImport.graphql deleted file mode 100644 index 9487b7a1be..0000000000 --- a/roles/lib/files/FWO.Api.Client/APIcalls/report/getRuleIdsOfImport.graphql +++ /dev/null @@ -1,11 +0,0 @@ -query getRuleIdsOfImport($importId: bigint!, $devIds: [Int!]) { - rule( - where: { - rule_last_seen: { _gte: $importId } - rule_create: { _lte: $importId } - dev_id: { _in: $devIds } - } - ) { - rule_id - } -} diff --git a/roles/lib/files/FWO.Api.Client/APIcalls/report/getUsageDataCount.graphql b/roles/lib/files/FWO.Api.Client/APIcalls/report/getUsageDataCount.graphql deleted file mode 100644 index a76006fea1..0000000000 --- a/roles/lib/files/FWO.Api.Client/APIcalls/report/getUsageDataCount.graphql +++ /dev/null @@ -1,8 +0,0 @@ - -query getUsageDataCount($devId: Int) { - rule_aggregate(where: {_and: [ {dev_id: {_eq: $devId } }, { rule_metadatum: {rule_last_hit: { _is_null: false } } } ] }) { - aggregate { - count - } - } -} diff --git a/roles/lib/files/FWO.Api.Client/APIcalls/report/getUserDetailsInReport.graphql b/roles/lib/files/FWO.Api.Client/APIcalls/report/getUserDetailsInReport.graphql deleted file mode 100644 index 6d7f20eddd..0000000000 --- a/roles/lib/files/FWO.Api.Client/APIcalls/report/getUserDetailsInReport.graphql +++ /dev/null @@ -1,19 +0,0 @@ -query getUsersInReport ( - $mgmIds: [Int!] - $importId: bigint - $ruleIds: _int8 - $limit: Int - $offset: Int -) { - management(where: { mgm_id: { _in: $mgmIds }, stm_dev_typ:{dev_typ_is_multi_mgmt:{_eq:false}} }) { - name: mgm_name - id: mgm_id - reportUserObjects: filter_rule_user_resolveds ( - args: {rule_ids: $ruleIds, import_id: $importId} - limit: $limit - offset: $offset - ) { - ...userDetails - } - } -} \ No newline at end of file diff --git a/roles/lib/files/FWO.Api.Client/APIcalls/report/subscribeReportScheduleChanges.graphql b/roles/lib/files/FWO.Api.Client/APIcalls/report/subscribeReportScheduleChanges.graphql deleted file mode 100644 index d16fdd6598..0000000000 --- a/roles/lib/files/FWO.Api.Client/APIcalls/report/subscribeReportScheduleChanges.graphql +++ /dev/null @@ -1,27 +0,0 @@ -subscription subscribeReportScheduleChanges { - report_schedule(order_by: {report_schedule_id: desc}) { - report_schedule_id - report_schedule_name - report_schedule_every - report_schedule_repeat - report_schedule_start_time - report_schedule_owner_user: uiuser { - uiuser_id - uiuser_username - ldap_connection: ldap_connection { - ldap_connection_id - } - } - report_schedule_active - report_schedule_template: report_template { - report_template_id - report_template_name - report_filter - report_parameters - } - report_schedule_formats { - report_schedule_format_name - } - report_schedule_counter - } -} diff --git a/roles/lib/files/FWO.Api.Client/APIcalls/report/unused_addReportTemplatePlusPermissions.graphql b/roles/lib/files/FWO.Api.Client/APIcalls/report/unused_addReportTemplatePlusPermissions.graphql deleted file mode 100644 index 6cc0ea43ee..0000000000 --- a/roles/lib/files/FWO.Api.Client/APIcalls/report/unused_addReportTemplatePlusPermissions.graphql +++ /dev/null @@ -1,24 +0,0 @@ -mutation addReportTemplateWithPermissions( - $reportTemplateName: String! - $reportFilterLine: String! - $userId: Int - $tenantId: Int - $reportParameters: json -) { - insert_report_template( - objects: [ - { - report_template_name: $reportTemplateName - report_filter: $reportFilterLine - report_template_owner: $userId - report_template_viewable_by_users: { data: { uiuser_id: $userId } } - report_template_viewable_by_tenants: { data: { tenant_id: $tenantId } } - report_parameters: $reportParameters - } - ] - ) { - returning { - report_template_id - } - } -} diff --git a/roles/lib/files/FWO.Api.Client/APIcalls/report/unused_getAllChangeDetails.graphql b/roles/lib/files/FWO.Api.Client/APIcalls/report/unused_getAllChangeDetails.graphql deleted file mode 100644 index 0573da6047..0000000000 --- a/roles/lib/files/FWO.Api.Client/APIcalls/report/unused_getAllChangeDetails.graphql +++ /dev/null @@ -1,96 +0,0 @@ -query changeReport($start: timestamp, $stop: timestamp) { - management(order_by: {mgm_name: asc}) { - mgm_id - mgm_name - devices (order_by: {dev_name: asc}) { - dev_id - dev_name - changelog_rules( - where: { - _and: [ - { import_control: { stop_time: { _gte: $start } } } - { import_control: { stop_time: { _lte: $stop } } } - ] - change_type_id: { _eq: 3 } - security_relevant: { _eq: true } - } - order_by: { control_id: asc } - ) { - change_time - change_action - old: ruleByOldRuleId { - ...ruleOverview - } - new: rule { - ...ruleOverview - } - } - } - changelog_objects( - where: { - _and: [ - { import_control: { stop_time: { _gte: $start } } } - { import_control: { stop_time: { _lte: $stop } } } - ] - change_type_id: { _eq: 3 } - security_relevant: { _eq: true } - } - order_by: { control_id: asc } - ) { - change_time - security_relevant - change_action - change_type_id - old: objectByOldObjId { - ...networkObjectOverview - } - new: object { - ...networkObjectOverview - } - } - changelog_services( - where: { - _and: [ - { import_control: { stop_time: { _gte: $start } } } - { import_control: { stop_time: { _lte: $stop } } } - ] - change_type_id: { _eq: 3 } - security_relevant: { _eq: true } - } - order_by: { control_id: asc } - ) { - change_time - security_relevant - change_action - change_type_id - old: serviceByOldSvcId { - ...networkServiceOverview - } - new: service { - ...networkServiceOverview - } - } - changelog_users( - where: { - _and: [ - { import_control: { stop_time: { _gte: $start } } } - { import_control: { stop_time: { _lte: $stop } } } - ] - change_type_id: { _eq: 3 } - security_relevant: { _eq: true } - } - order_by: { control_id: asc } - ) { - change_time - security_relevant - change_action - change_type_id - old: usrByOldUserId { - ...userOverview - } - new: usr { - ...userOverview - } - } - } -} diff --git a/roles/lib/files/FWO.Api.Client/APIcalls/report/unused_getRuleChangeDetails.graphql b/roles/lib/files/FWO.Api.Client/APIcalls/report/unused_getRuleChangeDetails.graphql deleted file mode 100644 index 8e60a96dd1..0000000000 --- a/roles/lib/files/FWO.Api.Client/APIcalls/report/unused_getRuleChangeDetails.graphql +++ /dev/null @@ -1,30 +0,0 @@ -query changeRuleReport($start: timestamp, $stop: timestamp) { - management(order_by: {mgm_name: asc}) { - mgm_id - mgm_name - devices (order_by: {dev_name: asc}) { - dev_id - dev_name - changelog_rules( - where: { - _and: [ - { import_control: { stop_time: { _gte: $start } } } - { import_control: { stop_time: { _lte: $stop } } } - ] - change_type_id: { _eq: 3 } - security_relevant: { _eq: true } - } - order_by: { control_id: asc } - ) { - change_time - change_action - old: ruleByOldRuleId { - ...ruleOverview - } - new: rule { - ...ruleOverview - } - } - } - } -} diff --git a/roles/lib/files/FWO.Api.Client/APIcalls/request/getTickets.graphql b/roles/lib/files/FWO.Api.Client/APIcalls/request/getTickets.graphql deleted file mode 100644 index e96a893dcb..0000000000 --- a/roles/lib/files/FWO.Api.Client/APIcalls/request/getTickets.graphql +++ /dev/null @@ -1,5 +0,0 @@ -query getTickets($from_state: Int!, $to_state: Int!) { - request_ticket(where: {_or: [{_and: [{state_id: {_gte: $from_state}}, {state_id: {_lt: $to_state}}]}, {reqtasks: {_and: [{state_id: {_gte: $from_state}}, {state_id: {_lt: $to_state}}]}}]}, order_by: {id: asc}) { - ...ticketDetails - } -} diff --git a/roles/lib/files/FWO.Api.Client/APIcalls/request/upsertState.graphql b/roles/lib/files/FWO.Api.Client/APIcalls/request/upsertState.graphql deleted file mode 100644 index c62f595336..0000000000 --- a/roles/lib/files/FWO.Api.Client/APIcalls/request/upsertState.graphql +++ /dev/null @@ -1,16 +0,0 @@ -mutation upsertState($id: Int!, $name: String!) { - insert_request_state( - objects: { - id: $id - name: $name - }, - on_conflict: { - constraint: state_pkey , - update_columns: [name] - } - ) { - returning { - id: id - } - } -} diff --git a/roles/lib/files/FWO.Api.Client/APIcalls/rule/fragments/natRuleDetails.graphql b/roles/lib/files/FWO.Api.Client/APIcalls/rule/fragments/natRuleDetails.graphql deleted file mode 100644 index 92d5b97603..0000000000 --- a/roles/lib/files/FWO.Api.Client/APIcalls/rule/fragments/natRuleDetails.graphql +++ /dev/null @@ -1,35 +0,0 @@ -fragment natRuleDetails on rule { - ...ruleDetails - translate: ruleByXlateRule { - rule_src - rule_src_refs - rule_src_neg - rule_dst - rule_dst_refs - rule_dst_neg - rule_svc - rule_svc_refs - rule_svc_neg - rule_froms { - usr { - ...userDetails - } - object { - ...networkObjectDetails - } - } - rule_tos { - usr { - ...userDetails - } - object { - ...networkObjectDetails - } - } - rule_services { - service { - ...networkServiceDetails - } - } - } -} \ No newline at end of file diff --git a/roles/lib/files/FWO.Api.Client/APIcalls/rule/fragments/natRuleDetailsForReport.graphql b/roles/lib/files/FWO.Api.Client/APIcalls/rule/fragments/natRuleDetailsForReport.graphql deleted file mode 100644 index de1928ce38..0000000000 --- a/roles/lib/files/FWO.Api.Client/APIcalls/rule/fragments/natRuleDetailsForReport.graphql +++ /dev/null @@ -1,35 +0,0 @@ -fragment natRuleDetails on rule { - ...ruleDetails - translate: ruleByXlateRule { - rule_src - rule_src_refs - rule_src_neg - rule_dst - rule_dst_refs - rule_dst_neg - rule_svc - rule_svc_refs - rule_svc_neg - rule_froms(where: {object:{obj_create:{_lte:$relevantImportId}, obj_last_seen:{_gte:$relevantImportId}}}) { - usr { - ...userDetails - } - object { - ...networkObjectDetails - } - } - rule_tos(where: {object:{obj_create:{_lte:$relevantImportId}, obj_last_seen:{_gte:$relevantImportId}}}) { - usr { - ...userDetails - } - object { - ...networkObjectDetails - } - } - rule_services(where: {service:{svc_create:{_lte:$relevantImportId}, svc_last_seen:{_gte:$relevantImportId}}}) { - service { - ...networkServiceDetails - } - } - } -} diff --git a/roles/lib/files/FWO.Api.Client/APIcalls/rule/fragments/natRuleOverview.graphql b/roles/lib/files/FWO.Api.Client/APIcalls/rule/fragments/natRuleOverview.graphql deleted file mode 100644 index 04b77331f7..0000000000 --- a/roles/lib/files/FWO.Api.Client/APIcalls/rule/fragments/natRuleOverview.graphql +++ /dev/null @@ -1,35 +0,0 @@ -fragment natRuleOverview on rule { - ...ruleOverview - translate: ruleByXlateRule { - rule_src - rule_src_refs - rule_src_neg - rule_dst - rule_dst_refs - rule_dst_neg - rule_svc - rule_svc_refs - rule_svc_neg - rule_froms(where: {object:{obj_create:{_lte:$relevantImportId}, obj_last_seen:{_gte:$relevantImportId}}}) { - usr { - ...userOverview - } - object { - ...networkObjectOverview - } - } - rule_tos(where: {object:{obj_create:{_lte:$relevantImportId}, obj_last_seen:{_gte:$relevantImportId}}}) { - usr { - ...userOverview - } - object { - ...networkObjectOverview - } - } - rule_services(where: {service:{svc_create:{_lte:$relevantImportId}, svc_last_seen:{_gte:$relevantImportId}}}) { - service { - ...networkServiceOverview - } - } - } -} diff --git a/roles/lib/files/FWO.Api.Client/APIcalls/rule/fragments/ruleDetails.graphql b/roles/lib/files/FWO.Api.Client/APIcalls/rule/fragments/ruleDetails.graphql deleted file mode 100644 index 33b764bf52..0000000000 --- a/roles/lib/files/FWO.Api.Client/APIcalls/rule/fragments/ruleDetails.graphql +++ /dev/null @@ -1,51 +0,0 @@ -fragment ruleDetails on rule { - rule_id - rule_uid - dev_id - rule_action - section_header: rule_head_text - rule_comment - rule_track - rule_disabled - src_zone: zone { - zone_name - zone_id - } - active - rule_create - rule_last_seen - rule_src_neg - rule_dst_neg - rule_svc_neg - rule_num_numeric - rule_name - access_rule - nat_rule - xlate_rule - rule_froms { - usr { - ...userDetails - } - object { - ...networkObjectDetails - } - } - dst_zone: zoneByRuleToZone { - zone_name - zone_id - } - rule_tos { - usr { - ...userDetails - } - object { - ...networkObjectDetails - } - } - rule_svc - rule_services { - service { - ...networkServiceDetails - } - } -} \ No newline at end of file diff --git a/roles/lib/files/FWO.Api.Client/APIcalls/rule/fragments/ruleDetailsForReport.graphql b/roles/lib/files/FWO.Api.Client/APIcalls/rule/fragments/ruleDetailsForReport.graphql deleted file mode 100644 index 8ffa213698..0000000000 --- a/roles/lib/files/FWO.Api.Client/APIcalls/rule/fragments/ruleDetailsForReport.graphql +++ /dev/null @@ -1,50 +0,0 @@ -fragment ruleDetails on rule { - rule_id - rule_uid - dev_id - rule_action - section_header: rule_head_text - rule_comment - rule_track - rule_disabled - src_zone: zone { - zone_name - zone_id - } - active - rule_create - rule_last_seen - rule_src_neg - rule_dst_neg - rule_svc_neg - rule_num_numeric - rule_name - access_rule - nat_rule - xlate_rule - rule_froms(where: {object:{obj_create:{_lte:$relevantImportId}, obj_last_seen:{_gte:$relevantImportId}}}) { - usr { - ...userDetails - } - object { - ...networkObjectDetails - } - } - dst_zone: zoneByRuleToZone { - zone_name - zone_id - } - rule_tos(where: {object:{obj_create:{_lte:$relevantImportId}, obj_last_seen:{_gte:$relevantImportId}}}) { - usr { - ...userDetails - } - object { - ...networkObjectDetails - } - } - rule_services(where: {service:{svc_create:{_lte:$relevantImportId}, svc_last_seen:{_gte:$relevantImportId}}}) { - service { - ...networkServiceDetails - } - } -} diff --git a/roles/lib/files/FWO.Api.Client/APIcalls/rule/fragments/ruleOverview.graphql b/roles/lib/files/FWO.Api.Client/APIcalls/rule/fragments/ruleOverview.graphql deleted file mode 100644 index 5042df8cf9..0000000000 --- a/roles/lib/files/FWO.Api.Client/APIcalls/rule/fragments/ruleOverview.graphql +++ /dev/null @@ -1,59 +0,0 @@ -fragment ruleOverview on rule { - rule_id - rule_uid - dev_id - rule_action - section_header: rule_head_text - rule_comment - rule_track - rule_disabled - src_zone: zone { - zone_name - zone_id - } - rule_metadatum { - rule_metadata_id - rule_created - rule_first_hit - rule_last_hit - rule_last_modified - rule_last_certified - rule_last_certifier_dn - rule_to_be_removed - rule_decert_date - rule_recertification_comment - } - rule_src_neg - rule_dst_neg - rule_svc_neg - rule_num_numeric - rule_name - access_rule - nat_rule - xlate_rule - rule_froms(where: {object: {obj_create: {_lte: $relevantImportId}, obj_last_seen: {_gte: $relevantImportId}}}) { - usr { - ...userOverview - } - object { - ...networkObjectOverview - } - } - dst_zone: zoneByRuleToZone { - zone_name - zone_id - } - rule_tos(where: {object: {obj_create: {_lte: $relevantImportId}, obj_last_seen: {_gte: $relevantImportId}}}) { - usr { - ...userOverview - } - object { - ...networkObjectOverview - } - } - rule_services(where: {service: {svc_create: {_lte: $relevantImportId}, svc_last_seen: {_gte: $relevantImportId}}}) { - service { - ...networkServiceOverview - } - } -} diff --git a/roles/lib/files/FWO.Api.Client/APIcalls/rule/getNatRuleDetails.graphql b/roles/lib/files/FWO.Api.Client/APIcalls/rule/getNatRuleDetails.graphql deleted file mode 100644 index 54852040fc..0000000000 --- a/roles/lib/files/FWO.Api.Client/APIcalls/rule/getNatRuleDetails.graphql +++ /dev/null @@ -1,41 +0,0 @@ -query listNatRulesDetails( - $management_id: [Int!] - $device_id: [Int!] - $rule_id: [bigint!] - $rule_uid: [String!] - $ruleSrcName: [String!] - $ruleSrcIp: [cidr!] - $limit: Int - $offset: Int -) { - management( - where: { mgm_id: { _in: $management_id } } - order_by: { mgm_name: asc } - ) { - id: mgm_id - name: mgm_name - devices( - where: { dev_id: { _in: $device_id } } - order_by: { dev_name: asc } - ) { - dev_id - dev_name - rules( - limit: $limit - offset: $offset - where: { - rule_id: { _in: $rule_id } - rule_uid: { _in: $rule_uid } - active: { _eq: true } - rule_src: { _in: $ruleSrcName } - rule_froms: { object: { obj_ip: { _in: $ruleSrcIp } } } - nat_rule: { _eq: true } - } - order_by: { rule_num_numeric: asc } - ) { - mgm_id: mgm_id - ...natRuleDetails - } - } - } -} diff --git a/roles/lib/files/FWO.Api.Client/APIcalls/rule/getRuleDetails.graphql b/roles/lib/files/FWO.Api.Client/APIcalls/rule/getRuleDetails.graphql deleted file mode 100644 index b0433c25ee..0000000000 --- a/roles/lib/files/FWO.Api.Client/APIcalls/rule/getRuleDetails.graphql +++ /dev/null @@ -1,41 +0,0 @@ -query listRulesDetails( - $management_id: [Int!] - $device_id: [Int!] - $rule_id: [bigint!] - $rule_uid: [String!] - $ruleSrcName: [String!] - $ruleSrcIp: [cidr!] - $limit: Int - $offset: Int -) { - management( - where: { mgm_id: { _in: $management_id } } - order_by: { mgm_name: asc } - ) { - id: mgm_id - name: mgm_name - devices( - where: { dev_id: { _in: $device_id } } - order_by: { dev_name: asc } - ) { - dev_id - dev_name - rules( - limit: $limit - offset: $offset - where: { - rule_id: { _in: $rule_id } - rule_uid: { _in: $rule_uid } - active: { _eq: true } - rule_src: { _in: $ruleSrcName } - rule_froms: { object: { obj_ip: { _in: $ruleSrcIp } } } - access_rule: { _eq: true } - } - order_by: { rule_num_numeric: asc } - ) { - mgm_id: mgm_id - ...ruleDetails - } - } - } -} diff --git a/roles/lib/files/FWO.Api.Client/APIcalls/user/fragments/userDetails.graphql b/roles/lib/files/FWO.Api.Client/APIcalls/user/fragments/userDetails.graphql deleted file mode 100644 index 18c9bb1d30..0000000000 --- a/roles/lib/files/FWO.Api.Client/APIcalls/user/fragments/userDetails.graphql +++ /dev/null @@ -1,39 +0,0 @@ -fragment userDetails on usr { - user_id - user_uid - user_create - user_create_time: import_control { - time: start_time - } - user_last_seen - user_name - user_comment - user_lastname - user_firstname - usr_typ_id - type: stm_usr_typ { - usr_typ_name - } - user_member_names - user_member_refs - usergrps(order_by: { usergrp_member_id: asc }) { - id: usergrp_id - byId: usrByUsergrpMemberId { - user_id - user_name - type: stm_usr_typ { - usr_typ_name - } - } - } - usergrp_flats(order_by: { usergrp_flat_member_id: asc }) { - flat_id: usergrp_flat_id - byFlatId: usrByUsergrpFlatMemberId { - user_id - user_name - type: stm_usr_typ { - usr_typ_name - } - } - } -} diff --git a/roles/lib/files/FWO.Api.Client/APIcalls/user/getUserDetails.graphql b/roles/lib/files/FWO.Api.Client/APIcalls/user/getUserDetails.graphql deleted file mode 100644 index 25fc572778..0000000000 --- a/roles/lib/files/FWO.Api.Client/APIcalls/user/getUserDetails.graphql +++ /dev/null @@ -1,20 +0,0 @@ -query listUsers( - $management_id: [Int!] - $time: String - $user_name: [String!] - $limit: Int - $offset: Int -) { - management(where: { mgm_id: { _in: $management_id }, stm_dev_typ:{dev_typ_is_multi_mgmt:{_eq:false}} }) { - id: mgm_id - name: mgm_name - userObjects: usrs( - limit: $limit - offset: $offset - where: { active: { _eq: true }, user_name: { _in: $user_name } } - order_by: { user_name: asc } - ) { - ...userDetails - } - } -} diff --git a/roles/lib/files/FWO.Api.Client/ApiConstants.cs b/roles/lib/files/FWO.Api.Client/ApiConstants.cs index 63773c77df..92914b482c 100644 --- a/roles/lib/files/FWO.Api.Client/ApiConstants.cs +++ b/roles/lib/files/FWO.Api.Client/ApiConstants.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Generic; using System.Linq; using System.Text; diff --git a/roles/lib/files/FWO.Api.Client/ApiCrudHelper.cs b/roles/lib/files/FWO.Api.Client/ApiCrudHelper.cs deleted file mode 100644 index fe3da42b9b..0000000000 --- a/roles/lib/files/FWO.Api.Client/ApiCrudHelper.cs +++ /dev/null @@ -1,41 +0,0 @@ -using System.Text.Json.Serialization; -using Newtonsoft.Json; - -namespace FWO.Api.Client -{ - public class ReturnId - { - [JsonProperty("newId"), JsonPropertyName("newId")] - public int NewId { get; set; } - - [JsonProperty("UpdatedId"), JsonPropertyName("UpdatedId")] - public int UpdatedId { get; set; } - - [JsonProperty("DeletedId"), JsonPropertyName("DeletedId")] - public int DeletedId { get; set; } - - [JsonProperty("affected_rows"), JsonPropertyName("affected_rows")] - public int AffectedRows { get; set; } - - [JsonProperty("uiuser_password_must_be_changed"), JsonPropertyName("uiuser_password_must_be_changed")] - public bool PasswordMustBeChanged { get; set; } - } - - public class NewReturning - { - [JsonProperty("returning"), JsonPropertyName("returning")] - public ReturnId[]? ReturnIds { get; set; } - } - - public class AggregateCount - { - [JsonProperty("aggregate"), JsonPropertyName("aggregate")] - public Aggregate Aggregate {get; set;} = new Aggregate(); - } - - public class Aggregate - { - [JsonProperty("count"), JsonPropertyName("count")] - public int Count { get; set; } - } -} diff --git a/roles/lib/files/FWO.Api.Client/ApiResponse.cs b/roles/lib/files/FWO.Api.Client/ApiResponse.cs index 751ca7ccbe..100245627e 100644 --- a/roles/lib/files/FWO.Api.Client/ApiResponse.cs +++ b/roles/lib/files/FWO.Api.Client/ApiResponse.cs @@ -1,30 +1,37 @@ -// TODO: NOT IN USE - -using System; -using System.Collections.Generic; -using System.Text; - namespace FWO.Api.Client { - //public class ApiResponse - //{ - // public ResponseType[]? Result { get; internal set; } - - // public string[]? Errors { get; internal set; } - - // internal ApiResponse(ResponseType[] result) - // { - // Result = result; - // } + /// + /// Wraps API data with optional error information to avoid exceptions in callers. + /// + public sealed class ApiResponse + { + /// + /// The successfully deserialized result, if available. + /// + public ResponseType? Result { get; } + /// + /// Errors returned by the API, if any. + /// + public string[]? Errors { get; } + /// + /// Indicates whether the response contains errors. + /// + public bool HasErrors => Errors is { Length: > 0 }; - // internal ApiResponse(params string[] errors) - // { - // Errors = errors; - // } + /// + /// Creates a successful response wrapper. + /// + public ApiResponse(ResponseType result) + { + Result = result; + } - // public ResultType GetResult(string resultName) - // { - // return default(ResultType); - // } - //} + /// + /// Creates a response wrapper containing error messages. + /// + public ApiResponse(params string[] errors) + { + Errors = errors; + } + } } diff --git a/roles/lib/files/FWO.Api.Client/ApiSubscription.cs b/roles/lib/files/FWO.Api.Client/ApiSubscription.cs index b8f9647714..e20989c736 100644 --- a/roles/lib/files/FWO.Api.Client/ApiSubscription.cs +++ b/roles/lib/files/FWO.Api.Client/ApiSubscription.cs @@ -1,29 +1,19 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - namespace FWO.Api.Client { public abstract class ApiSubscription : IDisposable { - private bool disposed = false; + private bool _disposed; + + protected bool IsDisposed => _disposed; protected abstract void Dispose(bool disposing); public void Dispose() { - if (disposed) return; + if (_disposed) return; Dispose(true); - disposed = true; + _disposed = true; GC.SuppressFinalize(this); } - - ~ ApiSubscription() - { - if (disposed) return; - Dispose(false); - } } } diff --git a/roles/lib/files/FWO.Api.Client/Data/Cidr.cs b/roles/lib/files/FWO.Api.Client/Data/Cidr.cs deleted file mode 100644 index f51ec7cfc4..0000000000 --- a/roles/lib/files/FWO.Api.Client/Data/Cidr.cs +++ /dev/null @@ -1,53 +0,0 @@ -using NetTools; - -namespace FWO.Api.Data -{ - public class Cidr - { - private IPAddressRange IpRange { get; set; } = new IPAddressRange(); - - public bool Valid { get; set; } = false; - - public string CidrString - { - get => this.getCidrString(); - set => this.setCidrFromString(value); - } - - public Cidr() - {} - - public Cidr(string value) - { - this.setCidrFromString(value); - } - - private string getCidrString() - { - return (Valid ? IpRange.ToCidrString() : ""); - } - - private void setCidrFromString(string value) - { - try - { - IpRange = IPAddressRange.Parse(value); - Valid = true; - // we only want cidr - try - { - IpRange.GetPrefixLength(); - } - catch(Exception) - { - // ignore range end - IpRange.End = IpRange.Begin; - } - } - catch(Exception) - { - Valid = false; - } - } - } -} diff --git a/roles/lib/files/FWO.Api.Client/Data/Client.cs b/roles/lib/files/FWO.Api.Client/Data/Client.cs deleted file mode 100644 index 1d82635cce..0000000000 --- a/roles/lib/files/FWO.Api.Client/Data/Client.cs +++ /dev/null @@ -1,15 +0,0 @@ -// TODO: UNUSED - -using System; -using System.Collections.Generic; -using System.Linq; -using System.Threading.Tasks; - -namespace FWO.Api.Data -{ - //public class Client - //{ - // public readonly string Name; - // public readonly Manufacturer[] Manufacturers; - //} -} diff --git a/roles/lib/files/FWO.Api.Client/Data/ComplianceNetworkZone.cs b/roles/lib/files/FWO.Api.Client/Data/ComplianceNetworkZone.cs deleted file mode 100644 index fe825434d2..0000000000 --- a/roles/lib/files/FWO.Api.Client/Data/ComplianceNetworkZone.cs +++ /dev/null @@ -1,181 +0,0 @@ -using FWO.Api.Client; -using NetTools; -using Newtonsoft.Json; -using System.Net; -using System.Text.Json.Serialization; - -namespace FWO.Api.Data -{ - public class ComplianceNetworkZone - { - [JsonProperty("id"), JsonPropertyName("id")] - public int Id { get; set; } = -1; - - [JsonProperty("name"), JsonPropertyName("name")] - public string Name { get; set; } = ""; - - [JsonProperty("description"), JsonPropertyName("description")] - public string Description { get; set; } = ""; - - [JsonProperty("ip_ranges", ItemConverterType = typeof(IpAddressRangeJsonTypeConverter)), JsonPropertyName("ip_ranges")] - public IPAddressRange[] IPRanges { get; set; } = new IPAddressRange[0]; - - [JsonProperty("super_network_zone"), JsonPropertyName("super_network_zone")] - public ComplianceNetworkZone? Superzone { get; set; } = null; - - [JsonProperty("sub_network_zones"), JsonPropertyName("sub_network_zones")] - public ComplianceNetworkZone[] Subzones { get; set; } = new ComplianceNetworkZone[0]; - - [JsonProperty("network_zone_communication_sources", ItemConverterType = typeof(WrapperConverter), - ItemConverterParameters = new object[] { "from_network_zone" }), JsonPropertyName("network_zone_communication_sources")] - public ComplianceNetworkZone[] AllowedCommunicationSources { get; set; } = new ComplianceNetworkZone[0]; - - [JsonProperty("network_zone_communication_destinations", ItemConverterType = typeof(WrapperConverter), - ItemConverterParameters = new object[] { "to_network_zone" }), JsonPropertyName("network_zone_communication_destinations")] - public ComplianceNetworkZone[] AllowedCommunicationDestinations { get; set; } = new ComplianceNetworkZone[0]; - - - public bool CommunicationAllowedFrom(ComplianceNetworkZone from) - { - return AllowedCommunicationSources.Contains(from); - } - - public bool CommunicationAllowedTo(ComplianceNetworkZone to) - { - return AllowedCommunicationDestinations.Contains(to); - } - - public bool OverlapExists(List ipRanges, List> unseenIpRanges) - { - bool result = false; - - for (int i = 0; i < IPRanges.Length; i++) - { - for (int j = 0; j < ipRanges.Count; j++) - { - if (OverlapExists(IPRanges[i], ipRanges[j])) - { - result = true; - RemoveOverlap(unseenIpRanges[j], IPRanges[i]); - } - } - } - return result; - } - - /// - /// Checks if IP range a and b overlap. - /// - /// First IP range - /// Second IP range - /// True, if IP ranges overlap, false otherwise. - private bool OverlapExists(IPAddressRange a, IPAddressRange b) - { - return IpToUint(a.Begin) <= IpToUint(b.End) && IpToUint(b.Begin) <= IpToUint(a.End); - } - - private void RemoveOverlap(List ranges, IPAddressRange toRemove) - { - for (int i = 0; i < ranges.Count; i++) - { - if (OverlapExists(ranges[i], toRemove)) - { - if (IpToUint(toRemove.Begin) <= IpToUint(ranges[i].Begin) && IpToUint(toRemove.End) >= IpToUint(ranges[i].End)) - { - // Complete overlap, remove the entire range - ranges.RemoveAt(i); - i--; - } - else if (IpToUint(toRemove.Begin) <= IpToUint(ranges[i].Begin)) - { - // Overlap on the left side, update the start - ranges[i].Begin = UintToIp(IpToUint(toRemove.End) + 1); - } - else if (IpToUint(toRemove.End) >= IpToUint(ranges[i].End)) - { - // Overlap on the right side, update the end - ranges[i].End = UintToIp(IpToUint(toRemove.Begin) - 1); - } - else - { - // Overlap in the middle, split the range - // begin..remove.begin-1 - IPAddress end = ranges[i].End; - ranges[i].End = UintToIp(IpToUint(toRemove.Begin) - 1); - // remove.end+1..end - ranges.Insert(i, new IPAddressRange(UintToIp(IpToUint(toRemove.End) + 1), end)); - i++; - } - } - } - } - - private uint IpToUint(IPAddress ipAddress) - { - byte[] bytes = ipAddress.GetAddressBytes(); - - // flip big-endian(network order) to little-endian - if (BitConverter.IsLittleEndian) - { - Array.Reverse(bytes); - } - - return BitConverter.ToUInt32(bytes, 0); - } - - private IPAddress UintToIp(uint ipAddress) - { - byte[] bytes = BitConverter.GetBytes(ipAddress); - - // flip big-endian(network order) to little-endian - if (BitConverter.IsLittleEndian) - { - Array.Reverse(bytes); - } - - return new IPAddress(bytes); - } - - public object Clone() - { - IPAddressRange[] ipRangesClone = new IPAddressRange[IPRanges.Length]; - for (int i = 0; i < IPRanges.Length; i++) - { - ipRangesClone[i] = new IPAddressRange(IPRanges[i].Begin, IPRanges[i].End); - } - - return new ComplianceNetworkZone() - { - Id = Id, - Superzone = (ComplianceNetworkZone?)Superzone?.Clone(), - Name = Name, - Description = Description, - IPRanges = ipRangesClone, - Subzones = CloneArray(Subzones), - AllowedCommunicationSources = CloneArray(AllowedCommunicationSources), - AllowedCommunicationDestinations = CloneArray(AllowedCommunicationDestinations) - }; - } - - private static ComplianceNetworkZone[] CloneArray(ComplianceNetworkZone[] array) - { - ComplianceNetworkZone[] arrayClone = new ComplianceNetworkZone[array.Length]; - for (int i = 0; i < array.Length; i++) - { - arrayClone[i] = (ComplianceNetworkZone)array[i].Clone(); - } - return arrayClone; - } - - public override bool Equals(object? obj) - { - if (obj == null) return false; - return ((ComplianceNetworkZone)obj).Id == Id; - } - - public override int GetHashCode() - { - return HashCode.Combine(Id); - } - } -} diff --git a/roles/lib/files/FWO.Api.Client/Data/Device.cs b/roles/lib/files/FWO.Api.Client/Data/Device.cs deleted file mode 100644 index 8205b7468d..0000000000 --- a/roles/lib/files/FWO.Api.Client/Data/Device.cs +++ /dev/null @@ -1,147 +0,0 @@ -using System.Text.Json.Serialization; -using Newtonsoft.Json; - -namespace FWO.Api.Data -{ - public class Device - { - [JsonProperty("id"), JsonPropertyName("id")] - public int Id { get; set; } - - [JsonProperty("name"), JsonPropertyName("name")] - public string? Name { get; set; } - - [JsonProperty("deviceType"), JsonPropertyName("deviceType")] - public DeviceType DeviceType { get; set; } = new DeviceType(); - - [JsonProperty("management"), JsonPropertyName("management")] - public Management Management { get; set; } = new Management(); - - [JsonProperty("local_rulebase_name"), JsonPropertyName("local_rulebase_name")] - public string? LocalRulebase { get; set; } - - [JsonProperty("global_rulebase_name"), JsonPropertyName("global_rulebase_name")] - public string? GlobalRulebase { get; set; } - - [JsonProperty("package_name"), JsonPropertyName("package_name")] - public string? Package { get; set; } - - [JsonProperty("importDisabled"), JsonPropertyName("importDisabled")] - public bool ImportDisabled { get; set; } - - [JsonProperty("hideInUi"), JsonPropertyName("hideInUi")] - public bool HideInUi { get; set; } - - [JsonProperty("comment"), JsonPropertyName("comment")] - public string? Comment { get; set; } - - [JsonProperty("rules"), JsonPropertyName("rules")] - public Rule[]? Rules { get; set; } - - [JsonProperty("changelog_rules"), JsonPropertyName("changelog_rules")] - public RuleChange[]? RuleChanges { get; set; } - - [JsonProperty("rules_aggregate"), JsonPropertyName("rules_aggregate")] - public ObjectStatistics RuleStatistics { get; set; } = new ObjectStatistics(); - - public bool Selected { get; set; } = false; - public bool Relevant { get; set; } - public bool AwaitMgmt { get; set; } - public bool Delete { get; set; } - public long ActionId { get; set; } - - public Device() - { } - - public Device(Device device) - { - Id = device.Id; - Name = device.Name; - DeviceType = new DeviceType(device.DeviceType); - Management = new Management(device.Management); - LocalRulebase = device.LocalRulebase; - GlobalRulebase = device.GlobalRulebase; - Package = device.Package; - ImportDisabled = device.ImportDisabled; - HideInUi = device.HideInUi; - Comment = device.Comment; - Relevant = device.Relevant; - AwaitMgmt = device.AwaitMgmt; - Delete = device.Delete; - ActionId = device.ActionId; - } - - public void AssignRuleNumbers() - { - if (Rules != null) - { - int ruleNumber = 1; - - foreach (Rule rule in Rules) - { - if (string.IsNullOrEmpty(rule.SectionHeader)) // Not a section header - { - rule.DisplayOrderNumber = ruleNumber++; - } - } - } - } - - public bool Sanitize() - { - bool shortened = false; - Name = Sanitizer.SanitizeOpt(Name, ref shortened); - LocalRulebase = Sanitizer.SanitizeOpt(LocalRulebase, ref shortened); - GlobalRulebase = Sanitizer.SanitizeOpt(GlobalRulebase, ref shortened); - Package = Sanitizer.SanitizeOpt(Package, ref shortened); - Comment = Sanitizer.SanitizeCommentOpt(Comment, ref shortened); - return shortened; - } - - public bool ContainsRules() - { - return (Rules != null && Rules.Count()>0); - } - } - - - public static class DeviceUtility - { - // adding rules fetched in slices - public static bool Merge(this Device[] devices, Device[] devicesToMerge) - { - bool newObjects = false; - - for (int i = 0; i < devices.Length && i < devicesToMerge.Length; i++) - { - if (devices[i].Id == devicesToMerge[i].Id) - { - try - { - if (devices[i].Rules != null && devicesToMerge[i].Rules != null && devicesToMerge[i].Rules?.Length > 0) - { - devices[i].Rules = devices[i].Rules?.Concat(devicesToMerge[i].Rules!).ToArray(); - newObjects = true; - } - if (devices[i].RuleChanges != null && devicesToMerge[i].RuleChanges != null && devicesToMerge[i].RuleChanges?.Length > 0) - { - devices[i].RuleChanges = devices[i].RuleChanges!.Concat(devicesToMerge[i].RuleChanges!).ToArray(); - newObjects = true; - } - if (devices[i].RuleStatistics != null && devicesToMerge[i].RuleStatistics != null) - devices[i].RuleStatistics.ObjectAggregate.ObjectCount += devicesToMerge[i].RuleStatistics.ObjectAggregate.ObjectCount; // correct ?? - } - catch (NullReferenceException) - { - throw new ArgumentNullException("Rules is null"); - } - } - else - { - throw new NotSupportedException("Devices have to be in the same order in oder to merge."); - } - } - return newObjects; - } - } -} diff --git a/roles/lib/files/FWO.Api.Client/Data/DeviceFilter.cs b/roles/lib/files/FWO.Api.Client/Data/DeviceFilter.cs deleted file mode 100644 index 3bfbd4b4cf..0000000000 --- a/roles/lib/files/FWO.Api.Client/Data/DeviceFilter.cs +++ /dev/null @@ -1,197 +0,0 @@ -using System.Text; -using System.Text.Json.Serialization; -using Microsoft.AspNetCore.Components; -using Newtonsoft.Json; - -namespace FWO.Api.Data -{ - public class ManagementSelect - { - [JsonProperty("id"), JsonPropertyName("id")] - public int Id { get; set; } - - [JsonProperty("name"), JsonPropertyName("name")] - public string? Name { get; set; } - - [JsonProperty("devices"), JsonPropertyName("devices")] - public List Devices { get; set; } = new List(); - - public ElementReference? UiReference { get; set; } - - public bool Selected { get; set; } = false; - } - - public class DeviceSelect - { - [JsonProperty("id"), JsonPropertyName("id")] - public int Id { get; set; } - - [JsonProperty("name"), JsonPropertyName("name")] - public string? Name { get; set; } - - public bool Selected { get; set; } = false; - } - - public class DeviceFilter - { - [JsonProperty("management"), JsonPropertyName("management")] - public List Managements { get; set; } = new List(); - - - public DeviceFilter() - {} - - public DeviceFilter(DeviceFilter devFilter) - { - Managements = devFilter.Managements; - } - - public DeviceFilter(List devIds) - { - ManagementSelect dummyManagement = new ManagementSelect(); - foreach(int id in devIds) - { - dummyManagement.Devices.Add(new DeviceSelect(){Id = id}); - } - Managements.Add(dummyManagement); - } - - public bool areAllDevicesSelected() - { - foreach (ManagementSelect management in Managements) - foreach (DeviceSelect device in management.Devices) - if (!device.Selected) - return false; - return true; - } - - public bool isAnyDeviceFilterSet() - { - foreach (ManagementSelect management in Managements) - foreach (DeviceSelect device in management.Devices) - if (device.Selected) - return true; - return false; - } - - public void applyFullDeviceSelection(bool selectAll) - { - foreach (ManagementSelect management in Managements) - { - management.Selected = selectAll; - foreach (DeviceSelect device in management.Devices) - { - device.Selected = selectAll; - } - } - } - - public static bool IsSelectedManagement(ManagementSelect management) - { - foreach (DeviceSelect device in management.Devices) - { - if (device.Selected) - { - return true; - } - } - return false; - } - - public List getSelectedManagements() - { - List selectedMgmts = new List(); - foreach (ManagementSelect mgmt in Managements) - { - if (IsSelectedManagement(mgmt)) - { - selectedMgmts.Add(mgmt.Id); - } - } - return selectedMgmts; - } - - public string listAllSelectedDevices() - { - List devs = new List(); - foreach (ManagementSelect mgmt in Managements) - foreach (DeviceSelect dev in mgmt.Devices) - if (dev.Selected) - devs.Add(dev.Name ?? ""); - return string.Join(", ", devs); - } - - public static List ExtractAllDevIds(Management[] managements) - { - List devs = new List(); - foreach (Management mgmt in managements) - foreach (Device dev in mgmt.Devices) - devs.Add(dev.Id); - return devs; - } - - public static List ExtractSelectedDevIds(Management[] managements) - { - List selectedDevs = new List(); - foreach (Management mgmt in managements) - foreach (Device dev in mgmt.Devices) - if (dev.Selected) - selectedDevs.Add(dev.Id); - return selectedDevs; - } - - public void SynchronizeDevFilter(DeviceFilter incomingDevFilter) - { - // unknown incoming devices (e.g. from templates) are ignored, because they have been removed inbetween - foreach (ManagementSelect management in Managements) - { - ManagementSelect? incomingMgt = incomingDevFilter.Managements.Find(x => x.Id == management.Id); - if (incomingMgt != null) - { - foreach (DeviceSelect device in management.Devices) - { - DeviceSelect? incomingDev = incomingMgt.Devices.Find(x => x.Id == device.Id); - if (incomingDev != null) - { - device.Selected = incomingDev.Selected; - } - } - } - } - SynchronizeMgmtFilter(); - } - - public void SynchronizeMgmtFilter() - { - foreach (ManagementSelect management in Managements) - { - int selectedDevicesCount = management.Devices.Where(d => d.Selected).Count(); - management.Selected = management.Devices.Count > 0 && selectedDevicesCount == management.Devices.Count; - } - } - - public int NumberMgmtDev() - { - int counter = 0; - foreach (ManagementSelect management in Managements) - { - counter ++; - foreach (DeviceSelect device in management.Devices) - { - counter ++; - } - } - return counter; - } - - public override string ToString() - { - StringBuilder result = new StringBuilder(); - foreach (ManagementSelect management in Managements) - { - result.Append($"{management.Name} [{string.Join(", ", management.Devices.ConvertAll(device => device.Name))}]; "); - } - return result.ToString(); - } - } -} diff --git a/roles/lib/files/FWO.Api.Client/Data/DistName.cs b/roles/lib/files/FWO.Api.Client/Data/DistName.cs deleted file mode 100644 index 4239feb4fb..0000000000 --- a/roles/lib/files/FWO.Api.Client/Data/DistName.cs +++ /dev/null @@ -1,103 +0,0 @@ -namespace FWO.Api.Data -{ - public class DistName - { - public string UserName { get; set; } - public string Role { get; set; } - public string Group { get; set; } - public List Root { get; set; } - public List Path { get; set; } - - public DistName(string? dn) - { - //Regex r = new Regex("(?:^|,\\s?)(?:(?[A-Z]+)=(?\"(?:[^\"]| \"\")+\"|(?:\\,|[^,])+))+"); - //GroupCollection groups = r.Match(dn ?? "").Groups; - //foreach (string group in r.GetGroupNames()) - //{ - // groups[group]; - //} - - UserName = ""; - Role = ""; - Group = ""; - Root = new List(); - Path = new List(); - bool lastValue = false; - if (dn != null) - { - while (lastValue == false) - { - int IndexPrefixDelim = dn.IndexOf("="); - if(IndexPrefixDelim > 0) - { - string Name = dn.Substring(0, IndexPrefixDelim); - string Value; - dn = dn.Substring (IndexPrefixDelim + 1); - int IndexValueDelim = dn.IndexOf(","); - if(IndexValueDelim > 0) - { - Value = dn.Substring(0, IndexValueDelim); - dn = dn.Substring (IndexValueDelim + 1); - } - else - { - Value = dn; - lastValue = true; - } - switch (Name.ToLower()) - { - case "uid": - case "samaccountname": - case "userprincipalname": - case "mail": - UserName = Value; - break; - case "cn": - if(UserName == "") - { - // the first one may be the user if not delivered as uid or a role or a group - UserName = Value; - Role = Value; - Group = Value; - } - else - { - // following ones belong to the path - Path.Add(Value); - } - break; - case "ou": - case "o": - case "l": - case "st": - case "street": - Path.Add(Value); - break; - case "dc": - case "c": - Root.Add(Value); - Path.Add(Value); - break; - default: - break; - } - } - else - { - lastValue = true; - } - } - } - } - - public bool IsInternal() - { - return Root.Contains("fworch") && Root.Contains("internal"); - } - - public string getTenant (int tenantLevel = 1) - { - return (tenantLevel > 0 && Path.Count >= tenantLevel) ? Path[Path.Count - tenantLevel] : ""; - } - } -} diff --git a/roles/lib/files/FWO.Api.Client/Data/FileFormat.cs b/roles/lib/files/FWO.Api.Client/Data/FileFormat.cs deleted file mode 100644 index ff36d8adc8..0000000000 --- a/roles/lib/files/FWO.Api.Client/Data/FileFormat.cs +++ /dev/null @@ -1,40 +0,0 @@ -using System.Text.Json.Serialization; -using Newtonsoft.Json; - -namespace FWO.Api.Data -{ - public class FileFormat - { - [JsonProperty("report_schedule_format_name"), JsonPropertyName("report_schedule_format_name")] - public string Name { get; set; } = ""; - } - - //public class FileFormatReportSchedule - //{ - // [JsonProperty("file_format_name"), JsonPropertyName("file_format_name")] - // public string FileFormatName { get; set; } - - // [JsonProperty("report_schedule_id"), JsonPropertyName("report_schedule_id")] - // public string ReportScheduleId { get; set; } - //} - - public static class FileFormatUtil - { - public static FileFormat Find(this IEnumerable fileFormats, string name) - { - return fileFormats.First(fileFormat => fileFormat.Name == name); - } - - public static void AddOrRemove(this List fileFormats, string name) - { - if (fileFormats.RemoveAll(fileFormat => fileFormat.Name == name) == 0) - { - fileFormats.Add(new FileFormat { Name = name }); - } - } - public static void Remove(this List fileFormats, string name) - { - fileFormats.RemoveAll(fileFormat => fileFormat.Name == name); - } - } -} diff --git a/roles/lib/files/FWO.Api.Client/Data/FwoOwner.cs b/roles/lib/files/FWO.Api.Client/Data/FwoOwner.cs deleted file mode 100644 index dcecfae0e6..0000000000 --- a/roles/lib/files/FWO.Api.Client/Data/FwoOwner.cs +++ /dev/null @@ -1,38 +0,0 @@ -using System.Text.Json.Serialization; -using Newtonsoft.Json; - -namespace FWO.Api.Data -{ - public class FwoOwner : FwoOwnerBase - { - [JsonProperty("id"), JsonPropertyName("id")] - public int Id { get; set; } - - [JsonProperty("last_recert_check"), JsonPropertyName("last_recert_check")] - public DateTime? LastRecertCheck { get; set; } - - [JsonProperty("recert_check_params"), JsonPropertyName("recert_check_params")] - public string? RecertCheckParamString { get; set; } - - public List NwObjElements { get; set; } = new List(); - - - public FwoOwner() - { } - - public FwoOwner(FwoOwner owner) : base(owner) - { - Id = owner.Id; - NwObjElements = owner.NwObjElements; - LastRecertCheck = owner.LastRecertCheck; - RecertCheckParamString = owner.RecertCheckParamString; - } - } - - public class FwoOwnerDataHelper - { - [JsonProperty("owner"), JsonPropertyName("owner")] - public FwoOwner Owner { get; set; } = new FwoOwner(); - } - -} diff --git a/roles/lib/files/FWO.Api.Client/Data/FwoOwnerBase.cs b/roles/lib/files/FWO.Api.Client/Data/FwoOwnerBase.cs deleted file mode 100644 index 41bb9daf8d..0000000000 --- a/roles/lib/files/FWO.Api.Client/Data/FwoOwnerBase.cs +++ /dev/null @@ -1,54 +0,0 @@ -using System.Text.Json.Serialization; -using Newtonsoft.Json; - -namespace FWO.Api.Data -{ - public class FwoOwnerBase - { - [JsonProperty("name"), JsonPropertyName("name")] - public string Name { get; set; } = ""; - - [JsonProperty("dn"), JsonPropertyName("dn")] - public string Dn { get; set; } = ""; - - [JsonProperty("group_dn"), JsonPropertyName("group_dn")] - public string GroupDn { get; set; } = ""; - - [JsonProperty("is_default"), JsonPropertyName("is_default")] - public bool IsDefault { get; set; } = false; - - [JsonProperty("tenant_id"), JsonPropertyName("tenant_id")] - public int? TenantId { get; set; } - - [JsonProperty("recert_interval"), JsonPropertyName("recert_interval")] - public int? RecertInterval { get; set; } - - [JsonProperty("app_id_external"), JsonPropertyName("app_id_external")] - public string ExtAppId { get; set; } = ""; - - - public FwoOwnerBase() - { } - - public FwoOwnerBase(FwoOwnerBase owner) - { - Name = owner.Name; - Dn = owner.Dn; - GroupDn = owner.GroupDn; - IsDefault = owner.IsDefault; - TenantId = owner.TenantId; - RecertInterval = owner.RecertInterval; - ExtAppId = owner.ExtAppId; - } - - public virtual bool Sanitize() - { - bool shortened = false; - Name = Sanitizer.SanitizeMand(Name, ref shortened); - Dn = Sanitizer.SanitizeLdapPathMand(Dn, ref shortened); - GroupDn = Sanitizer.SanitizeLdapPathMand(GroupDn, ref shortened); - ExtAppId = Sanitizer.SanitizeMand(ExtAppId, ref shortened); - return shortened; - } - } -} diff --git a/roles/lib/files/FWO.Api.Client/Data/ImportCredential.cs b/roles/lib/files/FWO.Api.Client/Data/ImportCredential.cs deleted file mode 100644 index a31915e9ba..0000000000 --- a/roles/lib/files/FWO.Api.Client/Data/ImportCredential.cs +++ /dev/null @@ -1,64 +0,0 @@ -using Newtonsoft.Json; -using System.Text.Json.Serialization; - -namespace FWO.Api.Data -{ - public class ImportCredential - { - [JsonProperty("id"), JsonPropertyName("id")] - public int Id { get; set; } - - [JsonProperty("credential_name"), JsonPropertyName("credential_name")] - public string Name { get; set; } = ""; - - [JsonProperty("is_key_pair"), JsonPropertyName("is_key_pair")] - public Boolean IsKeyPair { get; set; } = false; - - [JsonProperty("user"), JsonPropertyName("user")] - public string? ImportUser { get; set; } - - [JsonProperty("secret"), JsonPropertyName("secret")] - public string Secret { get; set; } = ""; - - [JsonProperty("sshPublicKey"), JsonPropertyName("sshPublicKey")] - public string? PublicKey { get; set; } - - [JsonProperty("cloud_client_id"), JsonPropertyName("cloud_client_id")] - public string? CloudClientId { get; set; } - - [JsonProperty("cloud_client_secret"), JsonPropertyName("cloud_client_secret")] - public string? CloudClientSecret { get; set; } - - public ImportCredential() - {} - - public ImportCredential(ImportCredential cred) - { - Id = cred.Id; - Name = cred.Name; - IsKeyPair = cred.IsKeyPair; - ImportUser = cred.ImportUser; - Secret = cred.Secret; - PublicKey = cred.PublicKey; - CloudClientId = cred.CloudClientId; - CloudClientSecret = cred.CloudClientSecret; - } - public ImportCredential(string username, string password) - { - ImportUser = username; - Secret = password; - } - public bool Sanitize() - { - bool shortened = false; - Name = Sanitizer.SanitizeMand(Name, ref shortened); - ImportUser = Sanitizer.SanitizeOpt(ImportUser, ref shortened); - PublicKey = Sanitizer.SanitizeKeyOpt(PublicKey, ref shortened); - // Secret = (DevType.IsLegacyDevType() ? Sanitizer.SanitizeKeyMand(Secret, ref shortened) : Sanitizer.SanitizePasswMand(Secret, ref shortened)); - Secret = Sanitizer.SanitizeKeyMand(Secret, ref shortened); - CloudClientId = Sanitizer.SanitizeOpt(CloudClientId, ref shortened); - CloudClientSecret = Sanitizer.SanitizeKeyOpt(CloudClientSecret, ref shortened); - return shortened; - } - } -} diff --git a/roles/lib/files/FWO.Api.Client/Data/ImportId.cs b/roles/lib/files/FWO.Api.Client/Data/ImportId.cs deleted file mode 100644 index 80c5e78d89..0000000000 --- a/roles/lib/files/FWO.Api.Client/Data/ImportId.cs +++ /dev/null @@ -1,24 +0,0 @@ -using System.Text.Json.Serialization; -using Newtonsoft.Json; - -namespace FWO.Api.Data -{ - public class Import - { - [JsonProperty("aggregate"), JsonPropertyName("aggregate")] - public ImportAggregate ImportAggregate { get; set; } = new ImportAggregate(); - } - - public class ImportAggregate - { - [JsonProperty("max"), JsonPropertyName("max")] - public ImportAggregateMax ImportAggregateMax { get; set; } = new ImportAggregateMax(); - } - - public class ImportAggregateMax - { - [JsonProperty("id"), JsonPropertyName("id")] - public long? RelevantImportId { get; set; } - } - -} diff --git a/roles/lib/files/FWO.Api.Client/Data/IpProtocol.cs b/roles/lib/files/FWO.Api.Client/Data/IpProtocol.cs deleted file mode 100644 index 52bbc872e0..0000000000 --- a/roles/lib/files/FWO.Api.Client/Data/IpProtocol.cs +++ /dev/null @@ -1,14 +0,0 @@ -using System.Text.Json.Serialization; -using Newtonsoft.Json; - -namespace FWO.Api.Data -{ - public class IpProtocol - { - [JsonProperty("ip_proto_id"), JsonPropertyName("ip_proto_id")] - public int Id { get; set; } - - [JsonProperty("ip_proto_name"), JsonPropertyName("ip_proto_name")] - public string Name { get; set; } = ""; - } -} diff --git a/roles/lib/files/FWO.Api.Client/Data/LdapConnectionBase.cs b/roles/lib/files/FWO.Api.Client/Data/LdapConnectionBase.cs deleted file mode 100644 index 61c28061eb..0000000000 --- a/roles/lib/files/FWO.Api.Client/Data/LdapConnectionBase.cs +++ /dev/null @@ -1,116 +0,0 @@ -using System.Text.Json.Serialization; -using Newtonsoft.Json; -using FWO.Middleware.RequestParameters; - -namespace FWO.Api.Data -{ - public enum LdapType - { - Default = 0, - ActiveDirectory = 1, - OpenLdap = 2 - } - - public class LdapConnectionBase - { - [JsonProperty("ldap_connection_id"), JsonPropertyName("ldap_connection_id")] - public int Id { get; set; } - - [JsonProperty("ldap_server"), JsonPropertyName("ldap_server")] - public string Address { get; set; } = ""; - - [JsonProperty("ldap_port"), JsonPropertyName("ldap_port")] - public int Port { get; set; } - - [JsonProperty("ldap_type"), JsonPropertyName("ldap_type")] - public int Type { get; set; } - - [JsonProperty("ldap_pattern_length"), JsonPropertyName("ldap_pattern_length")] - public int PatternLength { get; set; } - - [JsonProperty("ldap_search_user"), JsonPropertyName("ldap_search_user")] - public string? SearchUser { get; set; } - - [JsonProperty("ldap_tls"), JsonPropertyName("ldap_tls")] - public bool Tls { get; set; } - - [JsonProperty("ldap_tenant_level"), JsonPropertyName("ldap_tenant_level")] - public int TenantLevel { get; set; } - - [JsonProperty("ldap_search_user_pwd"), JsonPropertyName("ldap_search_user_pwd")] - public string? SearchUserPwd { get; set; } - - [JsonProperty("ldap_searchpath_for_users"), JsonPropertyName("ldap_searchpath_for_users")] - public string? UserSearchPath { get; set; } - - [JsonProperty("ldap_searchpath_for_roles"), JsonPropertyName("ldap_searchpath_for_roles")] - public string? RoleSearchPath { get; set; } - - [JsonProperty("ldap_searchpath_for_groups"), JsonPropertyName("ldap_searchpath_for_groups")] - public string? GroupSearchPath { get; set; } - - [JsonProperty("ldap_write_user"), JsonPropertyName("ldap_write_user")] - public string? WriteUser { get; set; } - - [JsonProperty("ldap_write_user_pwd"), JsonPropertyName("ldap_write_user_pwd")] - public string? WriteUserPwd { get; set; } - - [JsonProperty("tenant_id"), JsonPropertyName("tenant_id")] - public int? TenantId { get; set; } - - [JsonProperty("ldap_global_tenant_name"), JsonPropertyName("ldap_global_tenant_name")] - public string? GlobalTenantName { get; set; } - - [JsonProperty("active"), JsonPropertyName("active")] - public bool Active { get; set; } = true; - - public LdapConnectionBase() - {} - - public LdapConnectionBase(LdapGetUpdateParameters ldapGetUpdateParameters) - { - Id = ldapGetUpdateParameters.Id; - Address = ldapGetUpdateParameters.Address; - Port = ldapGetUpdateParameters.Port; - Type = ldapGetUpdateParameters.Type; - PatternLength = ldapGetUpdateParameters.PatternLength; - SearchUser = ldapGetUpdateParameters.SearchUser; - Tls = ldapGetUpdateParameters.Tls; - TenantLevel = ldapGetUpdateParameters.TenantLevel; - SearchUserPwd = ldapGetUpdateParameters.SearchUserPwd; - UserSearchPath = ldapGetUpdateParameters.SearchpathForUsers; - RoleSearchPath = ldapGetUpdateParameters.SearchpathForRoles; - GroupSearchPath = ldapGetUpdateParameters.SearchpathForGroups; - WriteUser = ldapGetUpdateParameters.WriteUser; - WriteUserPwd = ldapGetUpdateParameters.WriteUserPwd; - TenantId = ldapGetUpdateParameters.TenantId; - GlobalTenantName = ldapGetUpdateParameters.GlobalTenantName; - Active = ldapGetUpdateParameters.Active; - } - - public string Host() - { - return (Address != "" ? Address + ":" + Port : ""); - } - - public bool IsWritable() - { - return (WriteUser != null && WriteUser != ""); - } - - public bool HasGroupHandling() - { - return (GroupSearchPath != null && GroupSearchPath != ""); - } - - public bool HasRoleHandling() - { - return (RoleSearchPath != null && RoleSearchPath != ""); - } - - public bool IsInternal() - { - return ((new DistName(UserSearchPath)).IsInternal()); - } - } -} diff --git a/roles/lib/files/FWO.Api.Client/Data/Management.cs b/roles/lib/files/FWO.Api.Client/Data/Management.cs deleted file mode 100644 index d178648c75..0000000000 --- a/roles/lib/files/FWO.Api.Client/Data/Management.cs +++ /dev/null @@ -1,265 +0,0 @@ -using Newtonsoft.Json; -using System.Text.Json.Serialization; - -namespace FWO.Api.Data -{ - public class Management - { - [JsonProperty("id"), JsonPropertyName("id")] - public int Id { get; set; } - - [JsonProperty("name"), JsonPropertyName("name")] - public string Name { get; set; } = ""; - - [JsonProperty("hostname"), JsonPropertyName("hostname")] - public string Hostname { get; set; } = ""; - - [JsonProperty("import_credential"), JsonPropertyName("import_credential")] - public ImportCredential ImportCredential { get; set; } = new ImportCredential(); - - [JsonProperty("configPath"), JsonPropertyName("configPath")] - public string ConfigPath { get; set; } = ""; - - [JsonProperty("domainUid"), JsonPropertyName("domainUid")] - public string? DomainUid { get; set; } = ""; - - [JsonProperty("cloudSubscriptionId"), JsonPropertyName("cloudSubscriptionId")] - public string? CloudSubscriptionId { get; set; } = ""; - - [JsonProperty("cloudTenantId"), JsonPropertyName("cloudTenantId")] - public string? CloudTenantId { get; set; } = ""; - - [JsonProperty("superManager"), JsonPropertyName("superManager")] - public int? SuperManagerId { get; set; } - - [JsonProperty("importerHostname"), JsonPropertyName("importerHostname")] - public string ImporterHostname { get; set; } = ""; - - [JsonProperty("port"), JsonPropertyName("port")] - public int Port { get; set; } - - [JsonProperty("importDisabled"), JsonPropertyName("importDisabled")] - public bool ImportDisabled { get; set; } - - [JsonProperty("forceInitialImport"), JsonPropertyName("forceInitialImport")] - public bool ForceInitialImport { get; set; } - - [JsonProperty("hideInUi"), JsonPropertyName("hideInUi")] - public bool HideInUi { get; set; } - - [JsonProperty("comment"), JsonPropertyName("comment")] - public string? Comment { get; set; } - - [JsonProperty("debugLevel"), JsonPropertyName("debugLevel")] - public int? DebugLevel { get; set; } - - [JsonProperty("tenant_id"), JsonPropertyName("tenant_id")] - public int TenantId { get; set; } - - [JsonProperty("devices"), JsonPropertyName("devices")] - public Device[] Devices { get; set; } = new Device[]{}; - - [JsonProperty("networkObjects"), JsonPropertyName("networkObjects")] - public NetworkObject[] Objects { get; set; } = new NetworkObject[]{}; - - [JsonProperty("serviceObjects"), JsonPropertyName("serviceObjects")] - public NetworkService[] Services { get; set; } = new NetworkService[]{}; - - [JsonProperty("userObjects"), JsonPropertyName("userObjects")] - public NetworkUser[] Users { get; set; } = new NetworkUser[]{}; - - [JsonProperty("reportNetworkObjects"), JsonPropertyName("reportNetworkObjects")] - public NetworkObject[] ReportObjects { get; set; } = new NetworkObject[]{}; - - [JsonProperty("reportServiceObjects"), JsonPropertyName("reportServiceObjects")] - public NetworkService[] ReportServices { get; set; } = new NetworkService[]{}; - - [JsonProperty("reportUserObjects"), JsonPropertyName("reportUserObjects")] - public NetworkUser[] ReportUsers { get; set; } = new NetworkUser[]{}; - - [JsonProperty("deviceType"), JsonPropertyName("deviceType")] - public DeviceType DeviceType { get; set; } = new DeviceType(); - - [JsonProperty("import"), JsonPropertyName("import")] - public Import Import { get; set; } = new Import(); - - public long? RelevantImportId { get; set; } - public bool Ignore { get; set; } - public bool AwaitDevice { get; set; } - public bool Delete { get; set; } - public long ActionId { get; set; } - - //[JsonProperty("rule_id"), JsonPropertyName("rule_id")] - public List ReportedRuleIds { get; set; } = new List(); - public List ReportedNetworkServiceIds { get; set; } = new List(); - - [JsonProperty("objects_aggregate"), JsonPropertyName("objects_aggregate")] - public ObjectStatistics NetworkObjectStatistics { get; set; } = new ObjectStatistics(); - - [JsonProperty("services_aggregate"), JsonPropertyName("services_aggregate")] - public ObjectStatistics ServiceObjectStatistics { get; set; } = new ObjectStatistics(); - - [JsonProperty("usrs_aggregate"), JsonPropertyName("usrs_aggregate")] - public ObjectStatistics UserObjectStatistics { get; set; } = new ObjectStatistics(); - - [JsonProperty("rules_aggregate"), JsonPropertyName("rules_aggregate")] - public ObjectStatistics RuleStatistics { get; set; } = new ObjectStatistics(); - - public Management() - {} - - public Management(Management management) - { - Id = management.Id; - Name = management.Name; - Hostname = management.Hostname; - if (management.ImportCredential != null) - ImportCredential = new ImportCredential(management.ImportCredential); - else - ImportCredential = new ImportCredential(); - ConfigPath = management.ConfigPath; - DomainUid = management.DomainUid; - CloudSubscriptionId = management.CloudSubscriptionId; - CloudTenantId = management.CloudTenantId; - ImporterHostname = management.ImporterHostname; - Port = management.Port; - ImportDisabled = management.ImportDisabled; - ForceInitialImport = management.ForceInitialImport; - HideInUi = management.HideInUi; - Comment = management.Comment; - DebugLevel = management.DebugLevel; - TenantId = management.TenantId; - Devices = management.Devices; - Objects = management.Objects; - Services = management.Services; - Users = management.Users; - ReportObjects = management.ReportObjects; - ReportServices = management.ReportServices; - ReportUsers = management.ReportUsers; - DeviceType = management.DeviceType; - Import = management.Import; - Ignore = management.Ignore; - AwaitDevice = management.AwaitDevice; - Delete = management.Delete; - ActionId = management.ActionId; - ReportedRuleIds = management.ReportedRuleIds; - SuperManagerId = management.SuperManagerId; - ReportedNetworkServiceIds = management.ReportedNetworkServiceIds; - if (management.Import != null && management.Import.ImportAggregate != null && - management.Import.ImportAggregate.ImportAggregateMax != null && - management.Import.ImportAggregate.ImportAggregateMax.RelevantImportId != null) - RelevantImportId = management.Import.ImportAggregate.ImportAggregateMax.RelevantImportId; - - if (management.DeviceType != null) - DeviceType = new DeviceType(management.DeviceType); - } - - public string Host() - { - return Hostname + ":" + Port; - } - - public void AssignRuleNumbers() - { - foreach (Device device in Devices) - { - device.AssignRuleNumbers(); - } - } - - public bool Sanitize() - { - bool shortened = false; - shortened = ImportCredential.Sanitize(); - Name = Sanitizer.SanitizeMand(Name, ref shortened); - Hostname = Sanitizer.SanitizeMand(Hostname, ref shortened); - ConfigPath = Sanitizer.SanitizeMand(ConfigPath, ref shortened); - DomainUid = Sanitizer.SanitizeOpt(DomainUid, ref shortened); - ImporterHostname = Sanitizer.SanitizeMand(ImporterHostname, ref shortened); - Comment = Sanitizer.SanitizeCommentOpt(Comment, ref shortened); - CloudSubscriptionId = Sanitizer.SanitizeOpt(CloudSubscriptionId, ref shortened); - CloudTenantId = Sanitizer.SanitizeOpt(CloudTenantId, ref shortened); - return shortened; - } - } - - public static class ManagementUtility - { - public static bool Merge(this Management[] managements, Management[] managementsToMerge) - { - bool newObjects = false; - - for (int i = 0; i < managementsToMerge.Length; i++) - newObjects |= managements[i].Merge(managementsToMerge[i]); - - return newObjects; - } - - public static bool Merge(this Management management, Management managementToMerge) - { - bool newObjects = false; - - if (management.Objects != null && managementToMerge.Objects != null && managementToMerge.Objects.Length > 0) - { - management.Objects = management.Objects.Concat(managementToMerge.Objects).ToArray(); - newObjects = true; - } - - if (management.Services != null && managementToMerge.Services != null && managementToMerge.Services.Length > 0) - { - management.Services = management.Services.Concat(managementToMerge.Services).ToArray(); - newObjects = true; - } - - if (management.Users != null && managementToMerge.Users != null && managementToMerge.Users.Length > 0) - { - management.Users = management.Users.Concat(managementToMerge.Users).ToArray(); - newObjects = true; - } - - if (management.Devices != null && managementToMerge.Devices != null && managementToMerge.Devices.Length > 0) - { - // important: if any management still returns rules, newObjects is set to true - if (management.Devices.Merge(managementToMerge.Devices) == true) - newObjects = true; - } - return newObjects; - } - - public static bool MergeReportObjects(this Management management, Management managementToMerge) - { - bool newObjects = false; - - if (management.ReportObjects != null && managementToMerge.ReportObjects != null && managementToMerge.ReportObjects.Length > 0) - { - management.ReportObjects = management.ReportObjects.Concat(managementToMerge.ReportObjects).ToArray(); - newObjects = true; - } - - if (management.ReportServices != null && managementToMerge.ReportServices != null && managementToMerge.ReportServices.Length > 0) - { - management.ReportServices = management.ReportServices.Concat(managementToMerge.ReportServices).ToArray(); - newObjects = true; - } - - if (management.ReportUsers != null && managementToMerge.ReportUsers != null && managementToMerge.ReportUsers.Length > 0) - { - management.ReportUsers = management.ReportUsers.Concat(managementToMerge.ReportUsers).ToArray(); - newObjects = true; - } - - if (management.Devices != null && managementToMerge.Devices != null && managementToMerge.Devices.Length > 0) - { - // important: if any management still returns rules, newObjects is set to true - if (management.Devices.Merge(managementToMerge.Devices) == true) - newObjects = true; - } - return newObjects; - } - - public static string NameAndDeviceNames(this Management management, string separator = ", ") - { - return $"{management.Name} [{string.Join(separator, Array.ConvertAll(management.Devices, device => device.Name))}]"; - } - } -} diff --git a/roles/lib/files/FWO.Api.Client/Data/NetworkLocation.cs b/roles/lib/files/FWO.Api.Client/Data/NetworkLocation.cs deleted file mode 100644 index fa2cbc41ea..0000000000 --- a/roles/lib/files/FWO.Api.Client/Data/NetworkLocation.cs +++ /dev/null @@ -1,43 +0,0 @@ -using System.Text.Json.Serialization; -using Newtonsoft.Json; - -namespace FWO.Api.Data -{ - public class NetworkLocation : IComparable - { - [JsonProperty("object"), JsonPropertyName("object")] - public NetworkObject Object { get; set; } = new NetworkObject() { }; - - [JsonProperty("usr"), JsonPropertyName("usr")] - public NetworkUser User { get; set; } = new NetworkUser() { }; - - public NetworkLocation(NetworkUser user, NetworkObject network) - { - User = user; - Object = network; - } - - int IComparable.CompareTo(object? secondObject) - { - if (secondObject != null && secondObject is NetworkLocation) - { - NetworkLocation secondNetworkLocation = (secondObject as NetworkLocation)!; - if (this.User != null && secondNetworkLocation.User != null) - { - if (this.User?.Name.CompareTo(secondNetworkLocation.User?.Name) != 0) - return this.User!.Name.CompareTo(secondNetworkLocation.User!.Name); - else - return this.Object.Name.CompareTo(secondNetworkLocation.Object.Name); - } - else - { - return this.Object.Name.CompareTo(secondNetworkLocation.Object.Name); - } - } - else - { - throw new Exception("Uncomparable"); - } - } - } -} diff --git a/roles/lib/files/FWO.Api.Client/Data/NetworkObject.cs b/roles/lib/files/FWO.Api.Client/Data/NetworkObject.cs deleted file mode 100644 index 012e402883..0000000000 --- a/roles/lib/files/FWO.Api.Client/Data/NetworkObject.cs +++ /dev/null @@ -1,103 +0,0 @@ -using System.Text.Json.Serialization; -using Newtonsoft.Json; - -namespace FWO.Api.Data -{ - public class NetworkObject - { - [JsonProperty("obj_id"), JsonPropertyName("obj_id")] - public long Id { get; set; } - - [JsonProperty("obj_name"), JsonPropertyName("obj_name")] - public string Name { get; set; } = ""; - - [JsonProperty("obj_ip"), JsonPropertyName("obj_ip")] - public string IP { get; set; } = ""; - - [JsonProperty("obj_ip_end"), JsonPropertyName("obj_ip_end")] - public string IpEnd { get; set; } = ""; - - [JsonProperty("obj_uid"), JsonPropertyName("obj_uid")] - public string Uid { get; set; } = ""; - - [JsonProperty("zone"), JsonPropertyName("zone")] - public NetworkZone Zone { get; set; } = new NetworkZone(){}; - - [JsonProperty("active"), JsonPropertyName("active")] - public bool Active { get; set; } - - [JsonProperty("obj_create"), JsonPropertyName("obj_create")] - public int Create { get; set; } - - [JsonProperty("obj_create_time"), JsonPropertyName("obj_create_time")] - public TimeWrapper CreateTime { get; set; } = new TimeWrapper(){}; - - [JsonProperty("obj_last_seen"), JsonPropertyName("obj_last_seen")] - public int LastSeen { get; set; } - - [JsonProperty("type"), JsonPropertyName("type")] - public NetworkObjectType Type { get; set; } = new NetworkObjectType(){}; - - [JsonProperty("obj_comment"), JsonPropertyName("obj_comment")] - public string Comment { get; set; } = ""; - - [JsonProperty("obj_member_names"), JsonPropertyName("obj_member_names")] - public string MemberNames { get; set; } = ""; - - [JsonProperty("obj_member_refs"), JsonPropertyName("obj_member_refs")] - public string MemberRefs { get; set; } = ""; - - [JsonProperty("objgrps"), JsonPropertyName("objgrps")] - public Group[] ObjectGroups { get; set; } = new Group[]{}; - - [JsonProperty("objgrp_flats"), JsonPropertyName("objgrp_flats")] - public GroupFlat[] ObjectGroupFlats { get; set; } = new GroupFlat[]{}; - - public override bool Equals(object? obj) - { - return obj switch - { - NetworkObject nobj => Id == nobj.Id, - _ => base.Equals(obj), - }; - } - - public override int GetHashCode() - { - return Id.GetHashCode(); - } - - // obj_id - // obj_name - // obj_ip - // obj_ip_end - // obj_uid - // zone_id <--- - // active - // obj_create - // obj_last_seen - // type: stm_obj_typ { - // name: obj_typ_name - // } - // obj_comment - // obj_member_names - // obj_member_refs - // objgrps - // { - // objgrp_member_id - // objectByObjgrpMemberId - // { - // obj_id - // obj_name - // } - // } - // objgrp_flats { - // objgrp_flat_id - // objectByObjgrpFlatMemberId - // { - // obj_id - // obj_name - // } - // } - } -} diff --git a/roles/lib/files/FWO.Api.Client/Data/NetworkObjectType.cs b/roles/lib/files/FWO.Api.Client/Data/NetworkObjectType.cs deleted file mode 100644 index 7bba25b908..0000000000 --- a/roles/lib/files/FWO.Api.Client/Data/NetworkObjectType.cs +++ /dev/null @@ -1,11 +0,0 @@ -using System.Text.Json.Serialization; -using Newtonsoft.Json; - -namespace FWO.Api.Data -{ - public class NetworkObjectType - { - [JsonProperty("name"), JsonPropertyName("name")] - public string Name { get; set; } = ""; - } -} diff --git a/roles/lib/files/FWO.Api.Client/Data/NetworkObjectWrapper.cs b/roles/lib/files/FWO.Api.Client/Data/NetworkObjectWrapper.cs deleted file mode 100644 index 606d978115..0000000000 --- a/roles/lib/files/FWO.Api.Client/Data/NetworkObjectWrapper.cs +++ /dev/null @@ -1,11 +0,0 @@ -using System.Text.Json.Serialization; -using Newtonsoft.Json; - -namespace FWO.Api.Data -{ - public class NetworkObjectWrapper - { - [JsonProperty("object"), JsonPropertyName("object")] - public NetworkObject Content { get; set; } = new NetworkObject(){}; - } -} diff --git a/roles/lib/files/FWO.Api.Client/Data/NetworkProtocol.cs b/roles/lib/files/FWO.Api.Client/Data/NetworkProtocol.cs deleted file mode 100644 index ac8e1a3e7d..0000000000 --- a/roles/lib/files/FWO.Api.Client/Data/NetworkProtocol.cs +++ /dev/null @@ -1,14 +0,0 @@ -using System.Text.Json.Serialization; -using Newtonsoft.Json; - -namespace FWO.Api.Data -{ - public class NetworkProtocol - { - [JsonProperty("id"), JsonPropertyName("id")] - public int Id { get; set; } - - [JsonProperty("name"), JsonPropertyName("name")] - public string Name { get; set; } = ""; - } -} diff --git a/roles/lib/files/FWO.Api.Client/Data/NetworkService.cs b/roles/lib/files/FWO.Api.Client/Data/NetworkService.cs deleted file mode 100644 index 56a9e8b03c..0000000000 --- a/roles/lib/files/FWO.Api.Client/Data/NetworkService.cs +++ /dev/null @@ -1,130 +0,0 @@ -using System.Text.Json.Serialization; -using Newtonsoft.Json; - -namespace FWO.Api.Data -{ - public class NetworkService - { - [JsonProperty("svc_id"), JsonPropertyName("svc_id")] - public long Id { get; set; } - - [JsonProperty("svc_name"), JsonPropertyName("svc_name")] - public string Name { get; set; } = ""; - - [JsonProperty("svc_uid"), JsonPropertyName("svc_uid")] - public string Uid { get; set; } = ""; - - [JsonProperty("svc_port"), JsonPropertyName("svc_port")] - public int? DestinationPort { get; set; } - - [JsonProperty("svc_port_end"), JsonPropertyName("svc_port_end")] - public int? DestinationPortEnd { get; set; } - - [JsonProperty("svc_source_port"), JsonPropertyName("svc_source_port")] - public int? SourcePort { get; set; } - - [JsonProperty("svc_source_port_end"), JsonPropertyName("svc_source_port_end")] - public int? SourcePortEnd { get; set; } - - [JsonProperty("svc_code"), JsonPropertyName("svc_code")] - public string Code { get; set; } = ""; - - [JsonProperty("svc_timeout"), JsonPropertyName("svc_timeout")] - public int? Timeout { get; set; } - - [JsonProperty("svc_typ_id"), JsonPropertyName("svc_typ_id")] - public int? TypeId { get; set; } - - [JsonProperty("active"), JsonPropertyName("active")] - public bool Active { get; set; } - - [JsonProperty("svc_create"), JsonPropertyName("svc_create")] - public int Create { get; set; } - - [JsonProperty("svc_create_time"), JsonPropertyName("svc_create_time")] - public TimeWrapper CreateTime { get; set; } = new TimeWrapper(){}; - - [JsonProperty("svc_last_seen"), JsonPropertyName("svc_last_seen")] - public int LastSeen { get; set; } - - [JsonProperty("service_type"), JsonPropertyName("service_type")] - public NetworkServiceType Type { get; set; } = new NetworkServiceType(){}; - - [JsonProperty("svc_comment"), JsonPropertyName("svc_comment")] - public string Comment { get; set; } = ""; - - [JsonProperty("svc_color_id"), JsonPropertyName("svc_color_id")] - public int? ColorId { get; set; } - - [JsonProperty("ip_proto_id"), JsonPropertyName("ip_proto_id")] - public int? ProtoId { get; set; } - - [JsonProperty("protocol_name"), JsonPropertyName("protocol_name")] - public NetworkProtocol Protocol { get; set; } = new NetworkProtocol(){}; - - [JsonProperty("svc_member_names"), JsonPropertyName("svc_member_names")] - public string MemberNames { get; set; } = ""; - - [JsonProperty("svc_member_refs"), JsonPropertyName("svc_member_refs")] - public string MemberRefs { get; set; } = ""; - - [JsonProperty("svcgrps"), JsonPropertyName("svcgrps")] - public Group[] ServiceGroups { get; set; } = new Group[]{}; - - [JsonProperty("svcgrp_flats"), JsonPropertyName("svcgrp_flats")] - public GroupFlat[] ServiceGroupFlats { get; set; } = new GroupFlat[]{}; - - public override bool Equals(object? obj) - { - return obj switch - { - NetworkService nsrv => Id == nsrv.Id, - _ => base.Equals(obj), - }; - } - - public override int GetHashCode() - { - return Id.GetHashCode(); - } - - // svc_id - // svc_name - // svc_uid - // svc_port - // svc_port_end - // svc_source_port - // svc_source_port_end - // svc_code - // svc_timeout - // svc_typ_id - // active - // svc_create - // svc_last_seen - // service_type: stm_svc_typ { - // name: svc_typ_name - // } - // svc_comment - // svc_color_id - // ip_proto_id - // protocol_name: stm_ip_proto { - // name: ip_proto_name - // } - // svc_member_names - // svc_member_refs - // svcgrps { - // id: svcgrp_member_id - // byId: serviceBySvcgrpMemberId { - // svc_id - // svc_name - // } - // } - // svcgrp_flats { - // flat_id: svcgrp_flat_id - // byFlatId: serviceBySvcgrpFlatMemberId { - // svc_id - // svc_name - // } - // } - } -} diff --git a/roles/lib/files/FWO.Api.Client/Data/NetworkServiceType.cs b/roles/lib/files/FWO.Api.Client/Data/NetworkServiceType.cs deleted file mode 100644 index 997ec61340..0000000000 --- a/roles/lib/files/FWO.Api.Client/Data/NetworkServiceType.cs +++ /dev/null @@ -1,11 +0,0 @@ -using System.Text.Json.Serialization; -using Newtonsoft.Json; - -namespace FWO.Api.Data -{ - public class NetworkServiceType - { - [JsonProperty("name"), JsonPropertyName("name")] - public string Name { get; set; } = ""; - } -} diff --git a/roles/lib/files/FWO.Api.Client/Data/NetworkUser.cs b/roles/lib/files/FWO.Api.Client/Data/NetworkUser.cs deleted file mode 100644 index b45aa6c129..0000000000 --- a/roles/lib/files/FWO.Api.Client/Data/NetworkUser.cs +++ /dev/null @@ -1,95 +0,0 @@ -using System.Text.Json.Serialization; -using Newtonsoft.Json; - -namespace FWO.Api.Data -{ - public class NetworkUser - { - [JsonProperty("user_id"), JsonPropertyName("user_id")] - public long Id { get; set; } - - [JsonProperty("user_uid"), JsonPropertyName("user_uid")] - public string Uid { get; set; } = ""; - - [JsonProperty("user_name"), JsonPropertyName("user_name")] - public string Name { get; set; } = ""; - - [JsonProperty("user_comment"), JsonPropertyName("user_comment")] - public string Comment { get; set; } = ""; - - [JsonProperty("user_lastname"), JsonPropertyName("user_lastname")] - public string LastName { get; set; } = ""; - - [JsonProperty("user_firstname"), JsonPropertyName("user_firstname")] - public string FirstName { get; set; } = ""; - - [JsonProperty("usr_typ_id"), JsonPropertyName("usr_typ_id")] - public int TypeId { get; set; } - - [JsonProperty("type"), JsonPropertyName("type")] - public NetworkUserType Type { get; set; } = new(){}; - - [JsonProperty("user_create"), JsonPropertyName("user_create")] - public int Create { get; set; } - - [JsonProperty("user_create_time"), JsonPropertyName("user_create_time")] - public TimeWrapper CreateTime { get; set; } = new(){}; - - [JsonProperty("user_last_seen"), JsonPropertyName("user_last_seen")] - public int LastSeen { get; set; } - - [JsonProperty("user_member_names"), JsonPropertyName("user_member_names")] - public string MemberNames { get; set; } = ""; - - [JsonProperty("user_member_refs"), JsonPropertyName("user_member_refs")] - public string MemberRefs { get; set; } = ""; - - [JsonProperty("usergrps"), JsonPropertyName("usergrps")] - public Group[] UserGroups { get; set; } = new Group[]{}; - - [JsonProperty("usergrp_flats"), JsonPropertyName("usergrp_flats")] - public GroupFlat[] UserGroupFlats { get; set; } = new GroupFlat[]{}; - - public override bool Equals(object? obj) - { - return obj switch - { - NetworkUser user => Id == user.Id, - _ => base.Equals(obj), - }; - } - - public override int GetHashCode() - { - return Id.GetHashCode(); - } - - // user_id - // user_uid - // user_name - // user_comment - // user_lastname - // user_firstname - // usr_typ_id - // stm_usr_typ { - // usr_typ_name - // } - // user_member_names - // user_member_refs - // usergrps { - // id: usergrp_id - // byId: usrByUsergrpMemberId { - // user_id - // user_name - // } - // } - // usergrp_flats { - // flat_id: usergrp_flat_id - // byFlatId: usrByUsergrpFlatMemberId { - // user_id - // user_name - // } - // } - - } -} diff --git a/roles/lib/files/FWO.Api.Client/Data/NwObjectElement.cs b/roles/lib/files/FWO.Api.Client/Data/NwObjectElement.cs deleted file mode 100644 index 976f1b13a8..0000000000 --- a/roles/lib/files/FWO.Api.Client/Data/NwObjectElement.cs +++ /dev/null @@ -1,59 +0,0 @@ -using System.Text.Json.Serialization; -using Newtonsoft.Json; - -namespace FWO.Api.Data -{ - public class NwObjectElement - { - - [JsonProperty("id"), JsonPropertyName("id")] - public long ElemId { get; set; } - - [JsonProperty("ip"), JsonPropertyName("ip")] - public string IpString - { - get { return Cidr.CidrString; } - set { Cidr = new Cidr(value); } - } - public Cidr Cidr { get; set; } = new Cidr(); - - public long TaskId { get; set; } - - public long? NetworkId { get; set; } - - public NwObjectElement() - {} - - public NwObjectElement(string cidrString, long taskId) - { - Cidr = new Cidr(cidrString); - TaskId = taskId; - } - - public RequestReqElement ToReqElement(ElemFieldType field) - { - RequestReqElement element = new RequestReqElement() - { - Id = ElemId, - TaskId = TaskId, - Field = field.ToString(), - Cidr = new Cidr(Cidr.CidrString), - NetworkId = NetworkId - }; - return element; - } - - public RequestImplElement ToImplElement(ElemFieldType field) - { - RequestImplElement element = new RequestImplElement() - { - Id = ElemId, - ImplTaskId = TaskId, - Field = field.ToString(), - Cidr = new Cidr(Cidr.CidrString), - NetworkId = NetworkId, - }; - return element; - } - } -} diff --git a/roles/lib/files/FWO.Api.Client/Data/NwRuleElement.cs b/roles/lib/files/FWO.Api.Client/Data/NwRuleElement.cs deleted file mode 100644 index 6c5a9641dc..0000000000 --- a/roles/lib/files/FWO.Api.Client/Data/NwRuleElement.cs +++ /dev/null @@ -1,34 +0,0 @@ -namespace FWO.Api.Data -{ - public class NwRuleElement - { - public long ElemId { get; set; } - public long TaskId { get; set; } - public string RuleUid { get; set; } = ""; - - - public RequestReqElement ToReqElement() - { - RequestReqElement element = new RequestReqElement() - { - Id = ElemId, - TaskId = TaskId, - Field = ElemFieldType.rule.ToString(), - RuleUid = RuleUid - }; - return element; - } - - public RequestImplElement ToImplElement() - { - RequestImplElement element = new RequestImplElement() - { - Id = ElemId, - ImplTaskId = TaskId, - Field = ElemFieldType.rule.ToString(), - RuleUid = RuleUid - }; - return element; - } - } -} diff --git a/roles/lib/files/FWO.Api.Client/Data/NwServiceElement.cs b/roles/lib/files/FWO.Api.Client/Data/NwServiceElement.cs deleted file mode 100644 index 7cdebdf1c7..0000000000 --- a/roles/lib/files/FWO.Api.Client/Data/NwServiceElement.cs +++ /dev/null @@ -1,40 +0,0 @@ -namespace FWO.Api.Data -{ - public class NwServiceElement - { - public long ElemId { get; set; } - public long TaskId { get; set; } - public int Port { get; set; } - public int ProtoId { get; set; } - public long? ServiceId { get; set; } - - - public RequestReqElement ToReqElement() - { - RequestReqElement element = new RequestReqElement() - { - Id = ElemId, - TaskId = TaskId, - Field = ElemFieldType.service.ToString(), - Port = Port, - ProtoId = ProtoId, - ServiceId = ServiceId - }; - return element; - } - - public RequestImplElement ToImplElement() - { - RequestImplElement element = new RequestImplElement() - { - Id = ElemId, - ImplTaskId = TaskId, - Field = ElemFieldType.service.ToString(), - Port = Port, - ProtoId = ProtoId, - ServiceId = ServiceId - }; - return element; - } - } -} diff --git a/roles/lib/files/FWO.Api.Client/Data/ObjectStatistics.cs b/roles/lib/files/FWO.Api.Client/Data/ObjectStatistics.cs deleted file mode 100644 index f874685dd4..0000000000 --- a/roles/lib/files/FWO.Api.Client/Data/ObjectStatistics.cs +++ /dev/null @@ -1,20 +0,0 @@ -using System.Text.Json.Serialization; -using Newtonsoft.Json; - -namespace FWO.Api.Data -{ - public class ObjectStatistics - { - [JsonProperty("aggregate"), JsonPropertyName("aggregate")] - public ObjectAggregate ObjectAggregate { get; set; } = new ObjectAggregate(); - } - - public class ObjectAggregate - { - [JsonProperty("count"), JsonPropertyName("count")] - public int ObjectCount { get; set; } = 0; - - } - -} - diff --git a/roles/lib/files/FWO.Api.Client/Data/RecertFilter.cs b/roles/lib/files/FWO.Api.Client/Data/RecertFilter.cs deleted file mode 100644 index 55a130942e..0000000000 --- a/roles/lib/files/FWO.Api.Client/Data/RecertFilter.cs +++ /dev/null @@ -1,12 +0,0 @@ -namespace FWO.Api.Data -{ - public class RecertFilter - { - public List RecertOwnerList {get; set;} = new List(); - public bool RecertOverdueOnly {get; set;} = false; - public bool RecertShowAnyMatch {get; set;} = false; - public bool RecertSingleLinePerRule {get; set;} = false; - public int RecertificationDisplayPeriod = 0; - - } -} diff --git a/roles/lib/files/FWO.Api.Client/Data/ReportTemplate.cs b/roles/lib/files/FWO.Api.Client/Data/ReportTemplate.cs deleted file mode 100644 index a3d2476e10..0000000000 --- a/roles/lib/files/FWO.Api.Client/Data/ReportTemplate.cs +++ /dev/null @@ -1,73 +0,0 @@ -using System.Text.Json.Serialization; -using Newtonsoft.Json; - -namespace FWO.Api.Data -{ - public class ReportTemplate - { - [JsonProperty("report_template_id"), JsonPropertyName("report_template_id")] - public int Id { get; set; } - - [JsonProperty("report_template_name"), JsonPropertyName("report_template_name")] - public string Name { get; set; } = ""; - - [JsonProperty("report_template_create"), JsonPropertyName("report_template_create")] - public DateTime CreationDate { get; set; } - - [JsonProperty("report_template_comment"), JsonPropertyName("report_template_comment")] - public string Comment { get; set; } = ""; - - [JsonProperty("report_template_owner"), JsonPropertyName("report_template_owner")] - public int Owner { get; set; } - - [JsonProperty("report_filter"), JsonPropertyName("report_filter")] - public string Filter { get; set; } = ""; - - [JsonProperty("report_parameters"), JsonPropertyName("report_parameters")] - public ReportParams ReportParams { get; set; } = new ReportParams(); - - public bool Detailed = false; - - - public ReportTemplate() - {} - - public ReportTemplate(string filter, DeviceFilter deviceFilter, int? reportType, TimeFilter timeFilter, RecertFilter recertFilter, UnusedFilter? unusedFilter) - { - Filter = filter; - ReportParams.DeviceFilter = deviceFilter; - ReportParams.ReportType = reportType; - ReportParams.TimeFilter = timeFilter; - ReportParams.RecertFilter = recertFilter; - ReportParams.UnusedFilter = unusedFilter ?? new UnusedFilter(); - Detailed = false; - } - - public bool Sanitize() - { - bool shortened = false; - Name = Sanitizer.SanitizeMand(Name, ref shortened); - Comment = Sanitizer.SanitizeMand(Comment, ref shortened); - return shortened; - } - } - - public class ReportParams - { - [JsonProperty("report_type"), JsonPropertyName("report_type")] - public int? ReportType { get; set; } = 0; - - [JsonProperty("device_filter"), JsonPropertyName("device_filter")] - public DeviceFilter DeviceFilter { get; set; } = new DeviceFilter(); - - [JsonProperty("time_filter"), JsonPropertyName("time_filter")] - public TimeFilter TimeFilter { get; set; } = new TimeFilter(); - - [JsonProperty("recert_filter"), JsonPropertyName("recert_filter")] - public RecertFilter RecertFilter { get; set; } = new RecertFilter(); - - [JsonProperty("unused_filter"), JsonPropertyName("unused_filter")] - public UnusedFilter UnusedFilter { get; set; } = new UnusedFilter(); - - } -} diff --git a/roles/lib/files/FWO.Api.Client/Data/RequestApproval.cs b/roles/lib/files/FWO.Api.Client/Data/RequestApproval.cs deleted file mode 100644 index b5890b7c1a..0000000000 --- a/roles/lib/files/FWO.Api.Client/Data/RequestApproval.cs +++ /dev/null @@ -1,52 +0,0 @@ -using System.Text.Json.Serialization; -using Newtonsoft.Json; - -namespace FWO.Api.Data -{ - public class RequestApproval : RequestApprovalBase - { - [JsonProperty("id"), JsonPropertyName("id")] - public long Id { get; set; } - - [JsonProperty("task_id"), JsonPropertyName("task_id")] - public long TaskId { get; set; } - - [JsonProperty("comments"), JsonPropertyName("comments")] - public List Comments { get; set; } = new List(); - - - public RequestApproval() - { } - - public RequestApproval(RequestApproval approval) : base(approval) - { - Id = approval.Id; - TaskId = approval.TaskId; - Comments = approval.Comments; - } - - public string getAllComments() - { - string allComments = ""; - foreach(var comment in Comments) - { - allComments += comment.Comment.CreationDate.ToShortDateString() + " " - + comment.Comment.Creator.Name + ": " - + comment.Comment.CommentText + " "; - } - return allComments; - } - } - - public class ApprovalParams - { - [JsonProperty("state_id"), JsonPropertyName("state_id")] - public int StateId { get; set; } - - [JsonProperty("approver_group"), JsonPropertyName("approver_group")] - public string ApproverGroup { get; set; } = ""; - - [JsonProperty("deadline"), JsonPropertyName("deadline")] - public int Deadline { get; set; } - } -} diff --git a/roles/lib/files/FWO.Api.Client/Data/RequestApprovalBase.cs b/roles/lib/files/FWO.Api.Client/Data/RequestApprovalBase.cs deleted file mode 100644 index b99a194904..0000000000 --- a/roles/lib/files/FWO.Api.Client/Data/RequestApprovalBase.cs +++ /dev/null @@ -1,55 +0,0 @@ -using System.Text.Json.Serialization; -using Newtonsoft.Json; - -namespace FWO.Api.Data -{ - public class RequestApprovalBase : RequestStatefulObject - { - [JsonProperty("date_opened"), JsonPropertyName("date_opened")] - public DateTime DateOpened { get; set; } = DateTime.Now; - - [JsonProperty("approval_date"), JsonPropertyName("approval_date")] - public DateTime? ApprovalDate { get; set; } - - [JsonProperty("approval_deadline"), JsonPropertyName("approval_deadline")] - public DateTime? Deadline { get; set; } - - [JsonProperty("approver_group"), JsonPropertyName("approver_group")] - public string? ApproverGroup { get; set; } - -// [JsonProperty("approver"), JsonPropertyName("approver")] -// public UiUser? Approver { get; set; } - - [JsonProperty("approver"), JsonPropertyName("approver")] - public string? ApproverDn { get; set; } = ""; - - [JsonProperty("tenant_id"), JsonPropertyName("tenant_id")] - public int? TenantId { get; set; } - - [JsonProperty("initial_approval"), JsonPropertyName("initial_approval")] - public bool InitialApproval { get; set; } = true; - - - public RequestApprovalBase() - { } - - public RequestApprovalBase(RequestApprovalBase approval) : base(approval) - { - DateOpened = approval.DateOpened; - ApprovalDate = approval.ApprovalDate; - Deadline = approval.Deadline; - ApproverGroup = approval.ApproverGroup; - ApproverDn = approval.ApproverDn; - TenantId = approval.TenantId; - InitialApproval = approval.InitialApproval; - } - - public override bool Sanitize() - { - bool shortened = base.Sanitize(); - ApproverGroup = Sanitizer.SanitizeLdapPathOpt(ApproverGroup, ref shortened); - ApproverDn = Sanitizer.SanitizeLdapPathOpt(ApproverDn, ref shortened); - return shortened; - } - } -} diff --git a/roles/lib/files/FWO.Api.Client/Data/RequestApprovalWriter.cs b/roles/lib/files/FWO.Api.Client/Data/RequestApprovalWriter.cs deleted file mode 100644 index bb629235cb..0000000000 --- a/roles/lib/files/FWO.Api.Client/Data/RequestApprovalWriter.cs +++ /dev/null @@ -1,12 +0,0 @@ -namespace FWO.Api.Data -{ - public class RequestApprovalWriter : RequestApprovalBase - { - public RequestApprovalWriter() - { } - - public RequestApprovalWriter(RequestApproval approval) : base(approval) - { - } - } -} diff --git a/roles/lib/files/FWO.Api.Client/Data/RequestComment.cs b/roles/lib/files/FWO.Api.Client/Data/RequestComment.cs deleted file mode 100644 index 12a559c345..0000000000 --- a/roles/lib/files/FWO.Api.Client/Data/RequestComment.cs +++ /dev/null @@ -1,35 +0,0 @@ -using System.Text.Json.Serialization; -using Newtonsoft.Json; - -namespace FWO.Api.Data -{ - public class RequestComment : RequestCommentBase - { - [JsonProperty("id"), JsonPropertyName("id")] - public int Id { get; set; } - - - public RequestComment() - { } - - public RequestComment(RequestComment comment) : base(comment) - { - Id = comment.Id; - } - } - - public class RequestCommentDataHelper - { - [JsonProperty("comment"), JsonPropertyName("comment")] - public RequestComment Comment { get; set; } = new RequestComment(); - - - public RequestCommentDataHelper() - {} - - public RequestCommentDataHelper(RequestComment comment) - { - Comment = comment; - } - } -} diff --git a/roles/lib/files/FWO.Api.Client/Data/RequestCommentBase.cs b/roles/lib/files/FWO.Api.Client/Data/RequestCommentBase.cs deleted file mode 100644 index 1a5014ee2b..0000000000 --- a/roles/lib/files/FWO.Api.Client/Data/RequestCommentBase.cs +++ /dev/null @@ -1,44 +0,0 @@ -using System.Text.Json.Serialization; -using Newtonsoft.Json; - -namespace FWO.Api.Data -{ - public class RequestCommentBase - { - [JsonProperty("ref_id"), JsonPropertyName("ref_id")] - public long? RefId { get; set; } - - [JsonProperty("scope"), JsonPropertyName("scope")] - public string Scope { get; set; } = ""; - - [JsonProperty("creation_date"), JsonPropertyName("creation_date")] - public DateTime CreationDate { get; set; } = DateTime.Now; - - [JsonProperty("creator"), JsonPropertyName("creator")] - public UiUser Creator { get; set; } = new UiUser(); - - [JsonProperty("comment_text"), JsonPropertyName("comment_text")] - public string CommentText { get; set; } = ""; - - - public RequestCommentBase() - { } - - public RequestCommentBase(RequestCommentBase comment) - { - RefId = comment.RefId; - Scope = comment.Scope; - CreationDate = comment.CreationDate; - Creator = comment.Creator; - CommentText = comment.CommentText; - } - - public virtual bool Sanitize() - { - bool shortened = false; - Scope = Sanitizer.SanitizeMand(Scope, ref shortened); - CommentText = Sanitizer.SanitizeMand(CommentText, ref shortened); - return shortened; - } - } -} diff --git a/roles/lib/files/FWO.Api.Client/Data/RequestElementBase.cs b/roles/lib/files/FWO.Api.Client/Data/RequestElementBase.cs deleted file mode 100644 index 26f23757e5..0000000000 --- a/roles/lib/files/FWO.Api.Client/Data/RequestElementBase.cs +++ /dev/null @@ -1,69 +0,0 @@ -using System.Text.Json.Serialization; -using Newtonsoft.Json; - -namespace FWO.Api.Data -{ - public enum ElemFieldType - { - source, - destination, - service, - rule - } - - public class RequestElementBase - { - [JsonProperty("ip"), JsonPropertyName("ip")] - public string? IpString { get; set; } - - [JsonProperty("port"), JsonPropertyName("port")] - public int? Port { get; set; } - - [JsonProperty("ip_proto_id"), JsonPropertyName("ip_proto_id")] - public int? ProtoId { get; set; } - - [JsonProperty("network_object_id"), JsonPropertyName("network_object_id")] - public long? NetworkId { get; set; } - - [JsonProperty("service_id"), JsonPropertyName("service_id")] - public long? ServiceId { get; set; } - - [JsonProperty("field"), JsonPropertyName("field")] - public string Field { get; set; } = ElemFieldType.source.ToString(); - - [JsonProperty("user_id"), JsonPropertyName("user_id")] - public long? UserId { get; set; } - - [JsonProperty("original_nat_id"), JsonPropertyName("original_nat_id")] - public long? OriginalNatId { get; set; } - - [JsonProperty("rule_uid"), JsonPropertyName("rule_uid")] - public string? RuleUid { get; set; } - - - public RequestElementBase() - { } - - public RequestElementBase(RequestElementBase element) - { - IpString = element.IpString; - Port = element.Port; - ProtoId = element.ProtoId; - NetworkId = element.NetworkId; - ServiceId = element.ServiceId; - Field = element.Field; - UserId = element.UserId; - OriginalNatId = element.OriginalNatId; - RuleUid = element.RuleUid; - } - - public virtual bool Sanitize() - { - bool shortened = false; - IpString = Sanitizer.SanitizeOpt(IpString, ref shortened); - Field = Sanitizer.SanitizeMand(Field, ref shortened); - RuleUid = Sanitizer.SanitizeOpt(RuleUid, ref shortened); - return shortened; - } - } -} diff --git a/roles/lib/files/FWO.Api.Client/Data/RequestImplElement.cs b/roles/lib/files/FWO.Api.Client/Data/RequestImplElement.cs deleted file mode 100644 index 1c8061100e..0000000000 --- a/roles/lib/files/FWO.Api.Client/Data/RequestImplElement.cs +++ /dev/null @@ -1,45 +0,0 @@ -using System.Text.Json.Serialization; -using Newtonsoft.Json; - -namespace FWO.Api.Data -{ - public class RequestImplElement : RequestElementBase - { - [JsonProperty("id"), JsonPropertyName("id")] - public long Id { get; set; } - - [JsonProperty("implementation_task_id"), JsonPropertyName("implementation_task_id")] - public long ImplTaskId { get; set; } - - [JsonProperty("implementation_action"), JsonPropertyName("implementation_action")] - public string ImplAction { get; set; } = "create"; - - public Cidr Cidr { get; set; } = new Cidr(); - - public RequestImplElement() - {} - - public RequestImplElement(RequestImplElement element) : base(element) - { - Id = element.Id; - ImplTaskId = element.ImplTaskId; - ImplAction = element.ImplAction; - Cidr = new Cidr(element.Cidr != null ? element.Cidr.CidrString : ""); - } - - public RequestImplElement(RequestReqElement element) - { - Id = 0; - ImplAction = element.RequestAction; - Cidr = new Cidr(element.Cidr != null ? element.Cidr.CidrString : ""); - Port = element.Port; - ProtoId = element.ProtoId; - NetworkId = element.NetworkId; - ServiceId = element.ServiceId; - Field = element.Field; - UserId = element.UserId; - OriginalNatId = element.OriginalNatId; - RuleUid = element.RuleUid; - } - } -} diff --git a/roles/lib/files/FWO.Api.Client/Data/RequestImplTask.cs b/roles/lib/files/FWO.Api.Client/Data/RequestImplTask.cs deleted file mode 100644 index 70c63224a2..0000000000 --- a/roles/lib/files/FWO.Api.Client/Data/RequestImplTask.cs +++ /dev/null @@ -1,167 +0,0 @@ -using System.Text.Json.Serialization; -using Newtonsoft.Json; - -namespace FWO.Api.Data -{ - public class RequestImplTask: RequestTaskBase - { - [JsonProperty("id"), JsonPropertyName("id")] - public long Id { get; set; } - - [JsonProperty("reqtask_id"), JsonPropertyName("reqtask_id")] - public long ReqTaskId { get; set; } - - [JsonProperty("device_id"), JsonPropertyName("device_id")] - public int? DeviceId { get; set; } - - [JsonProperty("implementation_action"), JsonPropertyName("implementation_action")] - public string ImplAction { get; set; } = FWO.Api.Data.RequestAction.create.ToString(); - - [JsonProperty("elements"), JsonPropertyName("elements")] - public List ImplElements { get; set; } = new List(); - - [JsonProperty("comments"), JsonPropertyName("comments")] - public List Comments { get; set; } = new List(); - - - public List RemovedElements { get; set; } = new List(); - public long TicketId { get; set; } - - - public RequestImplTask() - {} - - public RequestImplTask(RequestImplTask implTask): base(implTask) - { - Id = implTask.Id; - ReqTaskId = implTask.ReqTaskId; - ImplAction = implTask.ImplAction; - DeviceId = implTask.DeviceId; - ImplElements = implTask.ImplElements; - Comments = implTask.Comments; - TicketId = implTask.TicketId; - } - - - public RequestImplTask(RequestReqTask reqtask, bool copyComments = true) - { - Id = 0; - Title = reqtask.Title; - ReqTaskId = reqtask.Id; - TaskNumber = 0; - StateId = 0; - TaskType = reqtask.TaskType; - ImplAction = reqtask.RequestAction; - RuleAction = reqtask.RuleAction; - Tracking = reqtask.Tracking; - Start = null; - Stop = null; - ServiceGroupId = reqtask.ServiceGroupId; - NetworkGroupId = reqtask.NetworkGroupId; - UserGroupId = reqtask.UserGroupId; - CurrentHandler = reqtask.CurrentHandler; - RecentHandler = reqtask.RecentHandler; - AssignedGroup = reqtask.AssignedGroup; - TargetBeginDate = reqtask.TargetBeginDate; - TargetEndDate = reqtask.TargetEndDate; - FreeText = reqtask.FreeText; - DeviceId = null; - TicketId = reqtask.TicketId; - if (reqtask.Elements != null && reqtask.Elements.Count > 0) - { - if(reqtask.TaskType == FWO.Api.Data.TaskType.rule_delete.ToString()) - { - DeviceId = reqtask.Elements[0].DeviceId; - } - ImplElements = new List(); - foreach(RequestReqElement element in reqtask.Elements) - { - ImplElements.Add(new RequestImplElement(element)); - } - } - if(copyComments) - { - foreach(var comm in reqtask.Comments) - { - comm.Comment.Scope = RequestObjectScopes.ImplementationTask.ToString(); - Comments.Add(comm); - } - } - } - - public override bool Sanitize() - { - bool shortened = base.Sanitize(); - return shortened; - } - - public List getNwObjectElements(ElemFieldType field) - { - List elements = new List(); - foreach(var implElem in ImplElements) - { - if (implElem.Field == field.ToString()) - { - elements.Add( new NwObjectElement() - { - ElemId = implElem.Id, - TaskId = implElem.ImplTaskId, - Cidr = new Cidr(implElem.Cidr != null ? implElem.Cidr.CidrString : ""), - NetworkId = implElem.NetworkId - }); - } - } - return elements; - } - - public List getServiceElements() - { - List elements = new List(); - foreach(var implElem in ImplElements) - { - if (implElem.Field == ElemFieldType.service.ToString()) - { - elements.Add( new NwServiceElement() - { - ElemId = implElem.Id, - TaskId = implElem.ImplTaskId, - Port = implElem.Port ?? 0, - ProtoId = implElem.ProtoId ?? 0, - ServiceId = implElem.ServiceId - }); - } - } - return elements; - } - - public List getRuleElements() - { - List elements = new List(); - foreach(var implElem in ImplElements) - { - if (implElem.Field == ElemFieldType.rule.ToString()) - { - elements.Add( new NwRuleElement() - { - ElemId = implElem.Id, - TaskId = implElem.ImplTaskId, - RuleUid = implElem.RuleUid ?? "" - }); - } - } - return elements; - } - - public string getAllComments() - { - string allComments = ""; - foreach(var comment in Comments) - { - allComments += comment.Comment.CreationDate.ToShortDateString() + " " - + comment.Comment.Creator.Name + ": " - + comment.Comment.CommentText + "\n"; - } - return allComments; - } - } -} diff --git a/roles/lib/files/FWO.Api.Client/Data/RequestPriority.cs b/roles/lib/files/FWO.Api.Client/Data/RequestPriority.cs deleted file mode 100644 index cbaff92ba2..0000000000 --- a/roles/lib/files/FWO.Api.Client/Data/RequestPriority.cs +++ /dev/null @@ -1,21 +0,0 @@ -using System.Text.Json.Serialization; -using Newtonsoft.Json; - - -namespace FWO.Api.Data -{ - public class RequestPriority - { - [JsonProperty("numeric_prio"), JsonPropertyName("numeric_prio")] - public int NumPrio { get; set; } - - [JsonProperty("name"), JsonPropertyName("name")] - public string Name { get; set; } = ""; - - [JsonProperty("ticket_deadline"), JsonPropertyName("ticket_deadline")] - public int TicketDeadline { get; set; } - - [JsonProperty("approval_deadline"), JsonPropertyName("approval_deadline")] - public int ApprovalDeadline { get; set; } - } -} diff --git a/roles/lib/files/FWO.Api.Client/Data/RequestReqElement.cs b/roles/lib/files/FWO.Api.Client/Data/RequestReqElement.cs deleted file mode 100644 index a21bff8703..0000000000 --- a/roles/lib/files/FWO.Api.Client/Data/RequestReqElement.cs +++ /dev/null @@ -1,34 +0,0 @@ -using System.Text.Json.Serialization; -using Newtonsoft.Json; - -namespace FWO.Api.Data -{ - public class RequestReqElement : RequestElementBase - { - [JsonProperty("id"), JsonPropertyName("id")] - public long Id { get; set; } - - [JsonProperty("task_id"), JsonPropertyName("task_id")] - public long TaskId { get; set; } - - [JsonProperty("request_action"), JsonPropertyName("request_action")] - public string RequestAction { get; set; } = FWO.Api.Data.RequestAction.create.ToString(); - - [JsonProperty("device_id"), JsonPropertyName("device_id")] - public int? DeviceId { get; set; } - - public Cidr Cidr { get; set; } = new Cidr(); - - public RequestReqElement() - {} - - public RequestReqElement(RequestReqElement element) : base (element) - { - Id = element.Id; - TaskId = element.TaskId; - RequestAction = element.RequestAction; - DeviceId = element.DeviceId; - Cidr = new Cidr(element.Cidr != null ? element.Cidr.CidrString : ""); - } - } -} diff --git a/roles/lib/files/FWO.Api.Client/Data/RequestReqElementWriter.cs b/roles/lib/files/FWO.Api.Client/Data/RequestReqElementWriter.cs deleted file mode 100644 index 3bd49903f5..0000000000 --- a/roles/lib/files/FWO.Api.Client/Data/RequestReqElementWriter.cs +++ /dev/null @@ -1,24 +0,0 @@ -using System.Text.Json.Serialization; -using Newtonsoft.Json; - -namespace FWO.Api.Data -{ - public class RequestReqElementWriter : RequestElementBase - { - [JsonProperty("request_action"), JsonPropertyName("request_action")] - public string RequestAction { get; set; } = FWO.Api.Data.RequestAction.create.ToString(); - - [JsonProperty("device_id"), JsonPropertyName("device_id")] - public int? DeviceId { get; set; } - - public RequestReqElementWriter() - {} - - public RequestReqElementWriter(RequestReqElement element) : base(element) - { - RequestAction = element.RequestAction; - DeviceId = element.DeviceId; - IpString = (element.Cidr != null && element.Cidr.Valid ? element.Cidr.CidrString : null); - } - } -} diff --git a/roles/lib/files/FWO.Api.Client/Data/RequestReqTask.cs b/roles/lib/files/FWO.Api.Client/Data/RequestReqTask.cs deleted file mode 100644 index f47c9de6a0..0000000000 --- a/roles/lib/files/FWO.Api.Client/Data/RequestReqTask.cs +++ /dev/null @@ -1,151 +0,0 @@ -using System.Text.Json.Serialization; -using Newtonsoft.Json; - -namespace FWO.Api.Data -{ - public class RequestReqTask : RequestReqTaskBase - { - [JsonProperty("id"), JsonPropertyName("id")] - public long Id { get; set; } - - [JsonProperty("ticket_id"), JsonPropertyName("ticket_id")] - public long TicketId { get; set; } - - [JsonProperty("elements"), JsonPropertyName("elements")] - public List Elements { get; set; } = new List(); - - [JsonProperty("implementation_tasks"), JsonPropertyName("implementation_tasks")] - public List ImplementationTasks { get; set; } = new List(); - - [JsonProperty("request_approvals"), JsonPropertyName("request_approvals")] - public List Approvals { get; set; } = new List(); - - [JsonProperty("owners"), JsonPropertyName("owners")] - public List Owners { get; set; } = new List(); - - [JsonProperty("comments"), JsonPropertyName("comments")] - public List Comments { get; set; } = new List(); - - public List RemovedElements { get; set; } = new List(); - - - public RequestReqTask() - { } - - public RequestReqTask(RequestReqTask reqtask) : base(reqtask) - { - Id = reqtask.Id; - TicketId = reqtask.TicketId; - Elements = reqtask.Elements; - ImplementationTasks = reqtask.ImplementationTasks; - Approvals = reqtask.Approvals; - Owners = reqtask.Owners; - Comments = reqtask.Comments; - RemovedElements = reqtask.RemovedElements; - } - - public string OwnerList() - { - List ownerNames = new List(); - foreach(var owner in Owners) - { - ownerNames.Add(owner.Owner.Name); - } - return string.Join(", ", ownerNames); - } - - public int HighestImplTaskNumber() - { - int highestNumber = 0; - foreach(var implTask in ImplementationTasks) - { - if (implTask.TaskNumber > highestNumber) - { - highestNumber = implTask.TaskNumber; - } - } - return highestNumber; - } - - public List getNwObjectElements(ElemFieldType field) - { - List elements = new List(); - foreach(var reqElem in Elements) - { - if (reqElem.Field == field.ToString()) - { - elements.Add( new NwObjectElement() - { - ElemId = reqElem.Id, - TaskId = reqElem.TaskId, - Cidr = new Cidr(reqElem.Cidr != null ? reqElem.Cidr.CidrString : ""), - NetworkId = reqElem.NetworkId - }); - } - } - return elements; - } - - public List getServiceElements() - { - List elements = new List(); - foreach(var reqElem in Elements) - { - if (reqElem.Field == ElemFieldType.service.ToString()) - { - elements.Add( new NwServiceElement() - { - ElemId = reqElem.Id, - TaskId = reqElem.TaskId, - Port = reqElem.Port ?? 0, - ProtoId = reqElem.ProtoId ?? 0, - ServiceId = reqElem.ServiceId - }); - } - } - return elements; - } - - public List getRuleElements() - { - List elements = new List(); - foreach(var reqElem in Elements) - { - if (reqElem.Field == ElemFieldType.rule.ToString()) - { - elements.Add( new NwRuleElement() - { - ElemId = reqElem.Id, - TaskId = reqElem.TaskId, - RuleUid = reqElem.RuleUid ?? "" - }); - } - } - return elements; - } - - public string getAllComments() - { - string allComments = ""; - foreach(var comment in Comments) - { - allComments += comment.Comment.CreationDate.ToShortDateString() + " " - + comment.Comment.Creator.Name + ": " - + comment.Comment.CommentText + "\n"; - } - return allComments; - } - - public int getRuleDeviceId() - { - foreach(var reqElem in Elements) - { - if (reqElem.Field == ElemFieldType.rule.ToString() && reqElem.DeviceId != null) - { - return (int)reqElem.DeviceId; - } - } - return 0; - } - } -} diff --git a/roles/lib/files/FWO.Api.Client/Data/RequestReqTaskBase.cs b/roles/lib/files/FWO.Api.Client/Data/RequestReqTaskBase.cs deleted file mode 100644 index 75020c063b..0000000000 --- a/roles/lib/files/FWO.Api.Client/Data/RequestReqTaskBase.cs +++ /dev/null @@ -1,75 +0,0 @@ -using System.Text.Json.Serialization; -using Newtonsoft.Json; - -namespace FWO.Api.Data -{ - public enum AutoCreateImplTaskOptions - { - never, - onlyForOneDevice, - forEachDevice, - enterInReqTask, - afterPathAnalysis - } - - - public class RequestReqTaskBase : RequestTaskBase - { - [JsonProperty("request_action"), JsonPropertyName("request_action")] - public string RequestAction { get; set; } = FWO.Api.Data.RequestAction.create.ToString(); - - [JsonProperty("reason"), JsonPropertyName("reason")] - public string? Reason { get; set; } - - [JsonProperty("last_recert_date"), JsonPropertyName("last_recert_date")] - public DateTime? LastRecertDate { get; set; } - - [JsonProperty("devices"), JsonPropertyName("devices")] - public string SelectedDevices - { - get => System.Text.Json.JsonSerializer.Serialize>(deviceList) ?? throw new Exception("DeviceList could not be parsed."); - set - { - if(value != null && value != "") - { - deviceList = System.Text.Json.JsonSerializer.Deserialize>(value) ?? throw new Exception("value could not be parsed."); - } - } - } - - private List deviceList { get; set; } = new List(); - - - public RequestReqTaskBase() - { } - - public RequestReqTaskBase(RequestReqTaskBase reqtask) : base(reqtask) - { - RequestAction = reqtask.RequestAction; - Reason = reqtask.Reason; - LastRecertDate = reqtask.LastRecertDate; - SelectedDevices = reqtask.SelectedDevices; - } - - public List getDeviceList() - { - return deviceList; - } - - public void SetDeviceList(List devList) - { - deviceList = new List(); - foreach(var dev in devList) - { - deviceList.Add(dev.Id); - } - } - - public override bool Sanitize() - { - bool shortened = base.Sanitize(); - Reason = Sanitizer.SanitizeOpt(Reason, ref shortened); - return shortened; - } - } -} diff --git a/roles/lib/files/FWO.Api.Client/Data/RequestReqTaskWriter.cs b/roles/lib/files/FWO.Api.Client/Data/RequestReqTaskWriter.cs deleted file mode 100644 index d0b6f485be..0000000000 --- a/roles/lib/files/FWO.Api.Client/Data/RequestReqTaskWriter.cs +++ /dev/null @@ -1,38 +0,0 @@ -using System.Text.Json.Serialization; -using Newtonsoft.Json; - -namespace FWO.Api.Data -{ - public class RequestReqTaskWriter : RequestReqTaskBase - { - [JsonProperty("elements"), JsonPropertyName("elements")] - public RequestElementDataHelper Elements { get; set; } = new RequestElementDataHelper(); - - [JsonProperty("approvals"), JsonPropertyName("approvals")] - public RequestApprovalDataHelper Approvals { get; set; } = new RequestApprovalDataHelper(); - - public RequestReqTaskWriter(RequestReqTask reqtask) : base(reqtask) - { - foreach(var element in reqtask.Elements) - { - Elements.RequestElementList.Add(new RequestReqElementWriter(element)); - } - foreach(var approval in reqtask.Approvals) - { - Approvals.RequestApprovalList.Add(new RequestApprovalWriter(approval)); - } - } - } - - public class RequestElementDataHelper - { - [JsonProperty("data"), JsonPropertyName("data")] - public List RequestElementList { get; set; } = new List(); - } - - public class RequestApprovalDataHelper - { - [JsonProperty("data"), JsonPropertyName("data")] - public List RequestApprovalList { get; set; } = new List(); - } -} diff --git a/roles/lib/files/FWO.Api.Client/Data/RequestStateAction.cs b/roles/lib/files/FWO.Api.Client/Data/RequestStateAction.cs deleted file mode 100644 index 65e1349e74..0000000000 --- a/roles/lib/files/FWO.Api.Client/Data/RequestStateAction.cs +++ /dev/null @@ -1,64 +0,0 @@ -using System.Text.Json.Serialization; -using Newtonsoft.Json; - -namespace FWO.Api.Data -{ - public enum StateActionTypes - { - DoNothing = 0, - AutoPromote = 1, - AddApproval = 2, - SetAlert = 5, - TrafficPathAnalysis = 6, - ExternalCall = 10 - } - - public enum StateActionEvents - { - None = 0, - OnSet = 1, - OnLeave = 2, - // WhileSet = 3, - OfferButton = 4 - } - - public class RequestStateAction - { - [JsonProperty("id"), JsonPropertyName("id")] - public int Id { get; set; } - - [JsonProperty("name"), JsonPropertyName("name")] - public string Name { get; set; } = ""; - - [JsonProperty("action_type"), JsonPropertyName("action_type")] - public string ActionType { get; set; } = StateActionTypes.DoNothing.ToString(); - - [JsonProperty("scope"), JsonPropertyName("scope")] - public string Scope { get; set; } = RequestObjectScopes.None.ToString(); - - [JsonProperty("task_type"), JsonPropertyName("task_type")] - public string TaskType { get; set; } = ""; - - [JsonProperty("phase"), JsonPropertyName("phase")] - public string Phase { get; set; } = ""; - - [JsonProperty("event"), JsonPropertyName("event")] - public string? Event { get; set; } = StateActionEvents.None.ToString(); - - [JsonProperty("button_text"), JsonPropertyName("button_text")] - public string? ButtonText { get; set; } = ""; - - [JsonProperty("external_parameters"), JsonPropertyName("external_parameters")] - public string ExternalParams { get; set; } = ""; - - - public RequestStateAction() - { } - } - - public class RequestStateActionDataHelper - { - [JsonProperty("action"), JsonPropertyName("action")] - public RequestStateAction Action { get; set; } = new RequestStateAction(); - } -} diff --git a/roles/lib/files/FWO.Api.Client/Data/RequestStatefulObject.cs b/roles/lib/files/FWO.Api.Client/Data/RequestStatefulObject.cs deleted file mode 100644 index 42a7511a1b..0000000000 --- a/roles/lib/files/FWO.Api.Client/Data/RequestStatefulObject.cs +++ /dev/null @@ -1,96 +0,0 @@ -using System.Text.Json.Serialization; -using Newtonsoft.Json; - -namespace FWO.Api.Data -{ - public enum RequestObjectScopes - { - None = 0, - Ticket = 1, - RequestTask = 2, - ImplementationTask = 3, - Approval = 4 - } - - public class RequestStatefulObject - { - [JsonProperty("state_id"), JsonPropertyName("state_id")] - public int StateId - { - get { return stateId; } - set - { - if(!stateChanged) - { - stateChanged = oldStateId != value; - oldStateId = stateId; - } - stateId = value; - } - } - - [JsonProperty("current_handler"), JsonPropertyName("current_handler")] - public UiUser? CurrentHandler { get; set; } - - [JsonProperty("recent_handler"), JsonPropertyName("recent_handler")] - public UiUser? RecentHandler { get; set; } - - [JsonProperty("assigned_group"), JsonPropertyName("assigned_group")] - public string? AssignedGroup { get; set; } - - - // need private declarations, else we get problems with request_reqtask_arr_rel_insert_input in newTicket - private int stateId; - private int oldStateId; - private bool stateChanged = false; - private string? optComment; - - public string? OptComment() - { - return optComment; - } - - public void SetOptComment(string? comm) - { - optComment = comm; - } - - public bool StateChanged() - { - return stateChanged; - } - - public int ChangedFrom() - { - return oldStateId; - } - - public void ResetStateChanged() - { - oldStateId = stateId; - stateChanged = false; - } - - public RequestStatefulObject() - { } - - public RequestStatefulObject(RequestStatefulObject obj) - { - stateId = obj.stateId; - oldStateId = obj.oldStateId; - stateChanged = obj.stateChanged; - optComment = obj.optComment; - CurrentHandler = obj.CurrentHandler; - RecentHandler = obj.RecentHandler; - AssignedGroup = obj.AssignedGroup; - } - - public virtual bool Sanitize() - { - bool shortened = false; - optComment = Sanitizer.SanitizeOpt(optComment, ref shortened); - AssignedGroup = Sanitizer.SanitizeLdapPathOpt(AssignedGroup, ref shortened); - return shortened; - } - } -} diff --git a/roles/lib/files/FWO.Api.Client/Data/RequestStates.cs b/roles/lib/files/FWO.Api.Client/Data/RequestStates.cs deleted file mode 100644 index 6dd5fc313f..0000000000 --- a/roles/lib/files/FWO.Api.Client/Data/RequestStates.cs +++ /dev/null @@ -1,53 +0,0 @@ -using FWO.Api.Client; -using System.Text.Json.Serialization; -using Newtonsoft.Json; - - -namespace FWO.Api.Data -{ - public class RequestState - { - [JsonProperty("id"), JsonPropertyName("id")] - public int Id { get; set; } - - [JsonProperty("name"), JsonPropertyName("name")] - public string Name { get; set; } = ""; - - [JsonProperty("actions"), JsonPropertyName("actions")] - public List Actions { get; set; } = new List(); - - - public RequestState(){} - - public RequestState(RequestState state) - { - Id = state.Id; - Name = state.Name; - Actions = state.Actions; - } - - public string ActionList() - { - List actionNames = new List(); - foreach(var action in Actions) - { - actionNames.Add(action.Action.Name); - } - return string.Join(", ", actionNames); - } - } - - public class RequestStateDict - { - public Dictionary Name = new Dictionary(); - - public async Task Init(ApiConnection apiConnection) - { - List states = await apiConnection.SendQueryAsync>(FWO.Api.Client.Queries.RequestQueries.getStates); - foreach(var state in states) - { - Name.Add(state.Id, state.Name); - } - } - } -} diff --git a/roles/lib/files/FWO.Api.Client/Data/RequestTaskBase.cs b/roles/lib/files/FWO.Api.Client/Data/RequestTaskBase.cs deleted file mode 100644 index 81a67a6ccc..0000000000 --- a/roles/lib/files/FWO.Api.Client/Data/RequestTaskBase.cs +++ /dev/null @@ -1,95 +0,0 @@ -using System.Text.Json.Serialization; -using Newtonsoft.Json; - -namespace FWO.Api.Data -{ - public enum TaskType - { - master = 0, - generic = 1, - access = 2, - rule_delete = 3, - rule_modify = 4, - group_create = 5, - group_modify = 6, - group_delete = 7 - } - - public enum RequestAction - { - create, - delete, - modify - } - - public class RequestTaskBase : RequestStatefulObject - { - [JsonProperty("title"), JsonPropertyName("title")] - public string Title { get; set; } = ""; - - [JsonProperty("task_number"), JsonPropertyName("task_number")] - public int TaskNumber { get; set; } - - [JsonProperty("task_type"), JsonPropertyName("task_type")] - public string TaskType { get; set; } = FWO.Api.Data.TaskType.access.ToString(); - - [JsonProperty("rule_action"), JsonPropertyName("rule_action")] - public int? RuleAction { get; set; } - - [JsonProperty("rule_tracking"), JsonPropertyName("rule_tracking")] - public int? Tracking { get; set; } - - [JsonProperty("start"), JsonPropertyName("start")] - public DateTime? Start { get; set; } - - [JsonProperty("stop"), JsonPropertyName("stop")] - public DateTime? Stop { get; set; } - - [JsonProperty("svc_grp_id"), JsonPropertyName("svc_grp_id")] - public int? ServiceGroupId { get; set; } - - [JsonProperty("nw_obj_grp_id"), JsonPropertyName("nw_obj_grp_id")] - public int? NetworkGroupId { get; set; } - - [JsonProperty("user_grp_id"), JsonPropertyName("user_grp_id")] - public int? UserGroupId { get; set; } - - [JsonProperty("free_text"), JsonPropertyName("free_text")] - public string? FreeText { get; set; } - - [JsonProperty("target_begin_date"), JsonPropertyName("target_begin_date")] - public DateTime? TargetBeginDate { get; set; } - - [JsonProperty("target_end_date"), JsonPropertyName("target_end_date")] - public DateTime? TargetEndDate { get; set; } - - - public RequestTaskBase() - { } - - public RequestTaskBase(RequestTaskBase reqtask) : base(reqtask) - { - Title = reqtask.Title; - TaskNumber = reqtask.TaskNumber; - TaskType = reqtask.TaskType; - RuleAction = reqtask.RuleAction; - Tracking = reqtask.Tracking; - Start = reqtask.Start; - Stop = reqtask.Stop; - ServiceGroupId = reqtask.ServiceGroupId; - NetworkGroupId = reqtask.NetworkGroupId; - UserGroupId = reqtask.UserGroupId; - FreeText = reqtask.FreeText; - TargetBeginDate = reqtask.TargetBeginDate; - TargetEndDate = reqtask.TargetEndDate; - } - - public override bool Sanitize() - { - bool shortened = base.Sanitize(); - Title = Sanitizer.SanitizeMand(Title, ref shortened); - FreeText = Sanitizer.SanitizeOpt(FreeText, ref shortened); - return shortened; - } - } -} diff --git a/roles/lib/files/FWO.Api.Client/Data/RequestTicket.cs b/roles/lib/files/FWO.Api.Client/Data/RequestTicket.cs deleted file mode 100644 index 7d768a416a..0000000000 --- a/roles/lib/files/FWO.Api.Client/Data/RequestTicket.cs +++ /dev/null @@ -1,82 +0,0 @@ -using System.Text.Json.Serialization; -using Newtonsoft.Json; - -namespace FWO.Api.Data -{ - public class RequestTicket : RequestTicketBase - { - [JsonProperty("reqtasks"), JsonPropertyName("reqtasks")] - public List Tasks { get; set; } = new List(); - - [JsonProperty("comments"), JsonPropertyName("comments")] - public List Comments { get; set; } = new List(); - - - public RequestTicket() - {} - - public RequestTicket(RequestTicket ticket) : base(ticket) - { - Tasks = ticket.Tasks; - Comments = ticket.Comments; - } - - public int HighestTaskNumber() - { - int highestNumber = 0; - foreach(var reqtask in Tasks) - { - if (reqtask.TaskNumber > highestNumber) - { - highestNumber = reqtask.TaskNumber; - } - } - return highestNumber; - } - - public int NumberImplTasks() - { - int numberImplTasks = 0; - foreach(var reqtask in Tasks) - { - numberImplTasks += reqtask.ImplementationTasks.Count; - } - return numberImplTasks; - } - - public void UpdateCidrStringsInTaskElements() - { - foreach (RequestReqTask reqtask in Tasks) - { - foreach(RequestReqElement elem in reqtask.Elements) - { - elem.IpString = (elem.Cidr != null && elem.Cidr.Valid ? elem.Cidr.CidrString : null) ; - } - } - } - - public void UpdateCidrsInTaskElements() - { - foreach (RequestReqTask reqtask in Tasks) - { - foreach(RequestReqElement elem in reqtask.Elements) - { - if (elem.IpString != null) - { - elem.Cidr = new Cidr(elem.IpString); - } - } - foreach(RequestImplTask implTask in reqtask.ImplementationTasks) - { - foreach(RequestImplElement elem in implTask.ImplElements) - { - if (elem.IpString != null) - { - elem.Cidr = new Cidr(elem.IpString); - } - } - } - } - } - } -} diff --git a/roles/lib/files/FWO.Api.Client/Data/RequestTicketBase.cs b/roles/lib/files/FWO.Api.Client/Data/RequestTicketBase.cs deleted file mode 100644 index 758bf62882..0000000000 --- a/roles/lib/files/FWO.Api.Client/Data/RequestTicketBase.cs +++ /dev/null @@ -1,78 +0,0 @@ -using System.Text.Json.Serialization; -using Newtonsoft.Json; - -namespace FWO.Api.Data -{ - public class RequestTicketBase: RequestStatefulObject - { - [JsonProperty("id"), JsonPropertyName("id")] - public long Id { get; set; } - - [JsonProperty("title"), JsonPropertyName("title")] - public string Title { get; set; } = ""; - - [JsonProperty("date_created"), JsonPropertyName("date_created")] - public DateTime CreationDate { get; set; } - - [JsonProperty("date_completed"), JsonPropertyName("date_completed")] - public DateTime? CompletionDate { get; set; } - - [JsonProperty("requester"), JsonPropertyName("requester")] - public UiUser? Requester { get; set; } - - [JsonProperty("requester_dn"), JsonPropertyName("requester_dn")] - public string? RequesterDn { get; set; } = ""; - - [JsonProperty("requester_group"), JsonPropertyName("requester_group")] - public string? RequesterGroup { get; set; } - - [JsonProperty("tenant_id"), JsonPropertyName("tenant_id")] - public int? TenantId { get; set; } - - [JsonProperty("reason"), JsonPropertyName("reason")] - public string? Reason { get; set; } - - [JsonProperty("external_ticket_id"), JsonPropertyName("external_ticket_id")] - public string? ExternalTicketId { get; set; } - - [JsonProperty("external_ticket_source"), JsonPropertyName("external_ticket_source")] - public int? ExternalTicketSource { get; set; } - - [JsonProperty("ticket_deadline"), JsonPropertyName("ticket_deadline")] - public DateTime? Deadline { get; set; } - - [JsonProperty("ticket_priority"), JsonPropertyName("ticket_priority")] - public int? Priority { get; set; } - - - public RequestTicketBase() - { } - - public RequestTicketBase(RequestTicketBase ticket) : base(ticket) - { - Id = ticket.Id; - Title = ticket.Title; - CreationDate = ticket.CreationDate; - CompletionDate = ticket.CompletionDate; - Requester = ticket.Requester; - RequesterDn = ticket.RequesterDn; - RequesterGroup = ticket.RequesterGroup; - TenantId = ticket.TenantId; - Reason = ticket.Reason; - ExternalTicketId = ticket.ExternalTicketId; - ExternalTicketSource = ticket.ExternalTicketSource; - Deadline = ticket.Deadline; - } - - public override bool Sanitize() - { - bool shortened = base.Sanitize(); - Title = Sanitizer.SanitizeMand(Title, ref shortened); - RequesterDn = Sanitizer.SanitizeLdapPathOpt(RequesterDn, ref shortened); - RequesterGroup = Sanitizer.SanitizeLdapPathOpt(RequesterGroup, ref shortened); - Reason = Sanitizer.SanitizeOpt(Reason, ref shortened); - ExternalTicketId = Sanitizer.SanitizeOpt(ExternalTicketId, ref shortened); - return shortened; - } - } -} diff --git a/roles/lib/files/FWO.Api.Client/Data/RequestTicketWriter.cs b/roles/lib/files/FWO.Api.Client/Data/RequestTicketWriter.cs deleted file mode 100644 index ceab87a2b8..0000000000 --- a/roles/lib/files/FWO.Api.Client/Data/RequestTicketWriter.cs +++ /dev/null @@ -1,21 +0,0 @@ -using System.Text.Json.Serialization; -using Newtonsoft.Json; - -namespace FWO.Api.Data -{ - public class RequestTicketWriter - { - - [JsonProperty("data"), JsonPropertyName("data")] - public List Tasks { get; set; } = new List(); - - - public RequestTicketWriter(RequestTicket ticket) - { - foreach(var reqtask in ticket.Tasks) - { - Tasks.Add(new RequestReqTaskWriter(reqtask)); - } - } - } -} diff --git a/roles/lib/files/FWO.Api.Client/Data/Role.cs b/roles/lib/files/FWO.Api.Client/Data/Role.cs deleted file mode 100644 index ed9ab71a2e..0000000000 --- a/roles/lib/files/FWO.Api.Client/Data/Role.cs +++ /dev/null @@ -1,33 +0,0 @@ -namespace FWO.Api.Data -{ - public class Role - { - public string Name { get; set; } = ""; - public string Dn { get; set; } = ""; - public string Description { get; set; } = ""; - public List Users { get; set; } - - public Role() - { - Users = new List(); - } - - public Role(Role role) - { - Name = role.Name; - Dn = role.Dn; - Description = role.Description; - Users = new List(role.Users); - } - - public string UserList() - { - List userNames = new List(); - foreach(UiUser user in Users) - { - userNames.Add(user.Name); - } - return string.Join(", ", userNames); - } - } -} diff --git a/roles/lib/files/FWO.Api.Client/Data/Rule.cs b/roles/lib/files/FWO.Api.Client/Data/Rule.cs deleted file mode 100644 index 9d69e73835..0000000000 --- a/roles/lib/files/FWO.Api.Client/Data/Rule.cs +++ /dev/null @@ -1,95 +0,0 @@ -using System.Text.Json.Serialization; -using Newtonsoft.Json; - -namespace FWO.Api.Data -{ - public class Rule - { - [JsonProperty("rule_id"), JsonPropertyName("rule_id")] - public long Id { get; set; } - - [JsonProperty("rule_uid"), JsonPropertyName("rule_uid")] - public string? Uid { get; set; } = ""; - - [JsonProperty("mgm_id"), JsonPropertyName("mgm_id")] - public int MgmtId { get; set; } - - [JsonProperty("rule_num_numeric"), JsonPropertyName("rule_num_numeric")] - public double OrderNumber { get; set; } - - [JsonProperty("rule_name"), JsonPropertyName("rule_name")] - public string? Name { get; set; } = ""; - - [JsonProperty("rule_comment"), JsonPropertyName("rule_comment")] - public string? Comment { get; set; } = ""; - - [JsonProperty("rule_disabled"), JsonPropertyName("rule_disabled")] - public bool Disabled { get; set; } - - [JsonProperty("rule_services"), JsonPropertyName("rule_services")] - public ServiceWrapper[] Services { get; set; } = new ServiceWrapper[]{}; - - [JsonProperty("rule_svc_neg"), JsonPropertyName("rule_svc_neg")] - public bool ServiceNegated { get; set; } - - [JsonProperty("rule_svc"), JsonPropertyName("rule_svc")] - public string Service { get; set; } = ""; - - [JsonProperty("rule_src_neg"), JsonPropertyName("rule_src_neg")] - public bool SourceNegated { get; set; } - - [JsonProperty("rule_src"), JsonPropertyName("rule_src")] - public string Source { get; set; } = ""; - - [JsonProperty("src_zone"), JsonPropertyName("src_zone")] - public NetworkZone? SourceZone { get; set; } = new NetworkZone(); - - [JsonProperty("rule_froms"), JsonPropertyName("rule_froms")] - public NetworkLocation[] Froms { get; set; } = new NetworkLocation[]{}; - - [JsonProperty("rule_dst_neg"), JsonPropertyName("rule_dst_neg")] - public bool DestinationNegated { get; set; } - - [JsonProperty("rule_dst"), JsonPropertyName("rule_dst")] - public string Destination { get; set; } = ""; - - [JsonProperty("dst_zone"), JsonPropertyName("dst_zone")] - public NetworkZone? DestinationZone { get; set; } = new NetworkZone(); - - [JsonProperty("rule_tos"), JsonPropertyName("rule_tos")] - public NetworkLocation[] Tos { get; set; } = new NetworkLocation[]{}; - - [JsonProperty("rule_action"), JsonPropertyName("rule_action")] - public string Action { get; set; } = ""; - - [JsonProperty("rule_track"), JsonPropertyName("rule_track")] - public string Track { get; set; } = ""; - - [JsonProperty("section_header"), JsonPropertyName("section_header")] - public string? SectionHeader { get; set; } = ""; - - [JsonProperty("rule_metadatum"), JsonPropertyName("rule_metadatum")] - public RuleMetadata Metadata {get; set;} = new RuleMetadata(); - - [JsonProperty("translate"), JsonPropertyName("translate")] - public NatData NatData {get; set;} = new NatData(); - - [JsonProperty("owner_name"), JsonPropertyName("owner_name")] - public string OwnerName {get; set;} = ""; - - [JsonProperty("owner_id"), JsonPropertyName("owner_id")] - public int? OwnerId {get; set;} - - [JsonProperty("matches"), JsonPropertyName("matches")] - public string IpMatch {get; set;} = ""; - - [JsonProperty("dev_id"), JsonPropertyName("dev_id")] - public int DeviceId { get; set; } - - - public int DisplayOrderNumber { get; set; } - public bool Certified { get; set; } - public string DeviceName { get; set; } = ""; - } - -} diff --git a/roles/lib/files/FWO.Api.Client/Data/RuleMetadata.cs b/roles/lib/files/FWO.Api.Client/Data/RuleMetadata.cs deleted file mode 100644 index a3b7a32f7f..0000000000 --- a/roles/lib/files/FWO.Api.Client/Data/RuleMetadata.cs +++ /dev/null @@ -1,79 +0,0 @@ -using System.Text.Json.Serialization; -using Newtonsoft.Json; - -namespace FWO.Api.Data -{ - public class RuleMetadata - { - [JsonProperty("rule_metadata_id"), JsonPropertyName("rule_metadata_id")] - public long Id { get; set; } - - [JsonProperty("rule_created"), JsonPropertyName("rule_created")] - public DateTime? Created { get; set; } - - [JsonProperty("rule_last_modified"), JsonPropertyName("rule_last_modified")] - public DateTime? LastModified { get; set; } - - [JsonProperty("rule_first_hit"), JsonPropertyName("rule_first_hit")] - public DateTime? FirstHit { get; set; } - - [JsonProperty("rule_last_hit"), JsonPropertyName("rule_last_hit")] - public DateTime? LastHit { get; set; } - - [JsonProperty("rule_last_certified"), JsonPropertyName("rule_last_certified")] - public DateTime? LastCertified { get; set; } - - [JsonProperty("rule_last_certifier_dn"), JsonPropertyName("rule_last_certifier_dn")] - public string LastCertifierDn { get; set; } = ""; - - [JsonProperty("rule_to_be_removed"), JsonPropertyName("rule_to_be_removed")] - public bool ToBeRemoved { get; set; } - - [JsonProperty("rule_decert_date"), JsonPropertyName("rule_decert_date")] - public DateTime? DecertificationDate { get; set; } - - [JsonProperty("rule_recertification_comment"), JsonPropertyName("rule_recertification_comment")] - public string Comment { get; set; } = ""; - - [JsonProperty("recertification"), JsonPropertyName("recertification")] - public List RuleRecertification { get; set; } = new List(); - - [JsonProperty("recert_history"), JsonPropertyName("recert_history")] - public List RecertHistory { get; set; } = new List(); - - public DateTime NextRecert { get; set; } - - public string LastCertifierName { get; set; } = ""; - - public bool Recert { get; set; } - - public string Style { get; set; } = ""; - - - - - - - public void UpdateRecertPeriods(int recertificationPeriod, int recertificationNoticePeriod) - { - - if (LastCertifierDn != null && LastCertifierDn != "") - LastCertifierName = (new FWO.Api.Data.DistName(LastCertifierDn)).UserName; - else - LastCertifierName = "-"; - - if (LastCertified != null) - NextRecert = ((DateTime)LastCertified).AddDays(recertificationPeriod); - else if (Created != null) - NextRecert = ((DateTime)Created).AddDays(recertificationPeriod); - else - NextRecert = DateTime.Now; - - if (NextRecert <= DateTime.Now) - Style = "background-overdue"; - else if (NextRecert <= DateTime.Now.AddDays(recertificationNoticePeriod)) - Style = "background-upcoming"; - } - } - -} diff --git a/roles/lib/files/FWO.Api.Client/Data/Sanitizer.cs b/roles/lib/files/FWO.Api.Client/Data/Sanitizer.cs deleted file mode 100644 index 523b362ce3..0000000000 --- a/roles/lib/files/FWO.Api.Client/Data/Sanitizer.cs +++ /dev/null @@ -1,140 +0,0 @@ -using System.Text.RegularExpressions; - -namespace FWO.Api.Data -{ - public class Sanitizer - { - // Standard input fields - public static string SanitizeMand(string input, ref bool shortened) - { - string output = Regex.Replace(input, @"[^\w\.\*\-\:\?@/\(\)\[\]\{\}\$\+<>#\$ ]", "").Trim(); - if(output.Length < input.Length) - { - shortened = true; - } - return output; - } - - public static string? SanitizeOpt(string? input, ref bool shortened) - { - if (input != null) - { - return SanitizeMand(input, ref shortened); - } - else return null; - } - - - // Ldap names: more restrictive due to Ldap restrictions. Chars not allowed (would have to be escaped in Dn): +;,\"<># - public static string SanitizeLdapNameMand(string input, ref bool shortened) - { - string output = Regex.Replace(input, @"[^\w\.\*\-\:\?@/\(\)]", "").Trim(); - if(output.Length < input.Length) - { - shortened = true; - } - return output; - } - - public static string? SanitizeLdapNameOpt(string? input, ref bool shortened) - { - if (input != null) - { - return SanitizeLdapNameMand(input, ref shortened); - } - else return null; - } - - - // Ldap path (Dn): Additionally needed on top of Ldap names chars: =, - public static string SanitizeLdapPathMand(string input, ref bool shortened) - { - string output = Regex.Replace(input, @"[^\w\.\*\-\:\?@/\(\)\=\,]", "").Trim(); - if(output.Length < input.Length) - { - shortened = true; - } - return output; - } - - public static string? SanitizeLdapPathOpt(string? input, ref bool shortened) - { - if (input != null) - { - return SanitizeLdapPathMand(input, ref shortened); - } - else return null; - } - - - // Passwords should not have Whitespaces except inner blanks - public static string SanitizePasswMand(string input, ref bool shortened) - { - string output = Regex.Replace(input, @"[^\S ]", "").Trim(); - if(output.Length < input.Length) - { - shortened = true; - } - return output; - } - - public static string? SanitizePasswOpt(string? input, ref bool shortened) - { - if (input != null) - { - return SanitizePasswMand(input, ref shortened); - } - else return null; - } - - - // Keys are only trimmed - public static string SanitizeKeyMand(string input, ref bool shortened) - { - string output = input.Trim(); - if(output.Length < input.Length) - { - shortened = true; - } - return output; - } - - // Comments may contain everything but quotes (EOL chars are allowed) - public static string? SanitizeCommentOpt(string? input, ref bool shortened) - { - if (input!=null) - { - return SanitizeCommentMand(input, ref shortened); - } - else return null; - } - - public static string SanitizeCommentMand(string input, ref bool shortened) - { - string output = Regex.Replace(input, @"[""'']", "").Trim(); - string ignorableChangeCompareString = output + "\n"; - if (input!=null) - { - if(output.Length < input.Length) // there is always an EOL char added in text fields - { - if(ignorableChangeCompareString != input ) - { - shortened = true; - } - } - - } - return output; - } - - public static string? SanitizeKeyOpt(string? input, ref bool shortened) - { - if (input != null) - { - return SanitizeKeyMand(input, ref shortened); - } - else return null; - } - - } -} diff --git a/roles/lib/files/FWO.Api.Client/Data/ScheduledReport.cs b/roles/lib/files/FWO.Api.Client/Data/ScheduledReport.cs deleted file mode 100644 index 087f89bda9..0000000000 --- a/roles/lib/files/FWO.Api.Client/Data/ScheduledReport.cs +++ /dev/null @@ -1,54 +0,0 @@ -using System.Text.Json.Serialization; -using Newtonsoft.Json; - -namespace FWO.Api.Data -{ - public class ScheduledReport - { - [JsonProperty("report_schedule_id"), JsonPropertyName("report_schedule_id")] - public int Id { get; set; } - - [JsonProperty("report_schedule_name"), JsonPropertyName("report_schedule_name")] - public string Name { get; set; } = ""; - - [JsonProperty("report_schedule_owner_user"), JsonPropertyName("report_schedule_owner_user")] - public UiUser Owner { get; set; } = new UiUser(); - - [JsonProperty("report_schedule_start_time"), JsonPropertyName("report_schedule_start_time")] - public DateTime StartTime { get; set; } = DateTime.Now.AddSeconds(-DateTime.Now.Second); - - [JsonProperty("report_schedule_repeat"), JsonPropertyName("report_schedule_repeat")] - public int RepeatOffset { get; set; } = 1; - - [JsonProperty("report_schedule_every"), JsonPropertyName("report_schedule_every")] - public Interval RepeatInterval { get; set; } - - [JsonProperty("report_schedule_template"), JsonPropertyName("report_schedule_template")] - public ReportTemplate Template { get; set; } = new ReportTemplate(); - - [JsonProperty("report_schedule_formats"), JsonPropertyName("report_schedule_formats")] - public List OutputFormat { get; set; } = new List(); - - [JsonProperty("report_schedule_active"), JsonPropertyName("report_schedule_active")] - public bool Active { get; set; } - - [JsonProperty("report_schedule_counter"), JsonPropertyName("report_schedule_counter")] - public int Counter { get; set; } - - public bool Sanitize() - { - bool shortened = false; - Name = Sanitizer.SanitizeMand(Name, ref shortened); - return shortened; - } - } - - public enum Interval - { - Never = 0, - Days = 2, - Weeks = 3, - Months = 4, - Years = 5 - } -} diff --git a/roles/lib/files/FWO.Api.Client/Data/ServiceWrapper.cs b/roles/lib/files/FWO.Api.Client/Data/ServiceWrapper.cs deleted file mode 100644 index 7cb8027109..0000000000 --- a/roles/lib/files/FWO.Api.Client/Data/ServiceWrapper.cs +++ /dev/null @@ -1,16 +0,0 @@ -using System.Text.Json.Serialization; -using Newtonsoft.Json; - -namespace FWO.Api.Data -{ - public class ServiceWrapper - { - [JsonProperty("service"), JsonPropertyName("service")] - public NetworkService Content { get; set; } = new NetworkService(); - } - // public class ServiceObjectRecursiveWrapper - // { - // [JsonProperty("service"), JsonPropertyName("service")] - // public ServiceObjectRecursiveFlatsWrapper Content { get; set; } - // } -} diff --git a/roles/lib/files/FWO.Api.Client/Data/StateMatrix.cs b/roles/lib/files/FWO.Api.Client/Data/StateMatrix.cs deleted file mode 100644 index 3d6d08d942..0000000000 --- a/roles/lib/files/FWO.Api.Client/Data/StateMatrix.cs +++ /dev/null @@ -1,202 +0,0 @@ -using FWO.Api.Client.Queries; -using FWO.Api.Data; -using System.Text.Json.Serialization; -using Newtonsoft.Json; - -namespace FWO.Api.Client -{ - public enum WorkflowPhases - { - request = 0, - approval = 1, - planning = 2, - verification = 3, - implementation = 4, - review = 5, - recertification = 6 - } - - public class StateMatrix - { - [JsonProperty("matrix"), JsonPropertyName("matrix")] - public Dictionary> Matrix { get; set; } = new Dictionary>(); - - [JsonProperty("derived_states"), JsonPropertyName("derived_states")] - public Dictionary DerivedStates { get; set; } = new Dictionary(); - - [JsonProperty("lowest_input_state"), JsonPropertyName("lowest_input_state")] - public int LowestInputState { get; set; } - - [JsonProperty("lowest_start_state"), JsonPropertyName("lowest_start_state")] - public int LowestStartedState { get; set; } - - [JsonProperty("lowest_end_state"), JsonPropertyName("lowest_end_state")] - public int LowestEndState { get; set; } - - [JsonProperty("active"), JsonPropertyName("active")] - public bool Active { get; set; } - - public Dictionary PhaseActive = new Dictionary(); - public bool IsLastActivePhase = true; - public int MinImplTasksNeeded; - - public async Task Init(WorkflowPhases phase, ApiConnection apiConnection, TaskType taskType = TaskType.master) - { - GlobalStateMatrix glbStateMatrix = new GlobalStateMatrix(); - await glbStateMatrix.Init(apiConnection, taskType); - Matrix = glbStateMatrix.GlobalMatrix[phase].Matrix; - DerivedStates = glbStateMatrix.GlobalMatrix[phase].DerivedStates; - LowestInputState = glbStateMatrix.GlobalMatrix[phase].LowestInputState; - LowestStartedState = glbStateMatrix.GlobalMatrix[phase].LowestStartedState; - LowestEndState = glbStateMatrix.GlobalMatrix[phase].LowestEndState; - Active = glbStateMatrix.GlobalMatrix[phase].Active; - foreach (var phas in glbStateMatrix.GlobalMatrix) - { - PhaseActive.Add(phas.Key, glbStateMatrix.GlobalMatrix[phas.Key].Active); - if(glbStateMatrix.GlobalMatrix[phas.Key].Active && phas.Key > phase) - { - IsLastActivePhase = false; - } - } - MinImplTasksNeeded = glbStateMatrix.GlobalMatrix[WorkflowPhases.implementation].LowestInputState; - } - - public List getAllowedTransitions(int stateIn) - { - List statesOut = new List(); - if(Matrix.ContainsKey(stateIn)) - { - statesOut = Matrix[stateIn]; - } - return statesOut; - } - - public int getDerivedStateFromSubStates(List statesIn) - { - if(statesIn.Count == 0) - { - return 0; - } - int stateOut = 0; - int backAssignedState = LowestInputState; - int initState = 0; - int inWorkState = LowestEndState; - int minFinishedState = 999; - int backAssignedTasks = 0; - int openTasks = 0; - int inWorkTasks = 0; - int finishedTasks = 0; - foreach(int state in statesIn) - { - if(state < LowestInputState) - { - backAssignedTasks++; - if(state < backAssignedState) - { - backAssignedState = state; - } - } - else if(state < LowestStartedState) - { - openTasks++; - initState = state; - } - else if(state < LowestEndState) - { - inWorkTasks++; - if(state < inWorkState) - { - inWorkState = state; - } - } - else - { - finishedTasks++; - if(state < minFinishedState) - { - minFinishedState = state; - } - } - } - - if(backAssignedTasks > 0) - { - stateOut = backAssignedState; - } - else if(inWorkTasks > 0) - { - stateOut = inWorkState; - } - else if(finishedTasks == statesIn.Count) - { - stateOut = minFinishedState; - } - else if(openTasks == statesIn.Count) - { - stateOut = initState; - } - else - { - stateOut = LowestStartedState; - } - - if(DerivedStates.ContainsKey(stateOut)) - { - return DerivedStates[stateOut]; - } - return stateOut; - } - } - public class GlobalStateMatrix - { - [JsonProperty("config_value"), JsonPropertyName("config_value")] - public Dictionary GlobalMatrix { get; set; } = new Dictionary(); - - - public async Task Init(ApiConnection apiConnection, TaskType taskType = TaskType.master, bool reset = false) - { - string matrixKey = taskType switch - { - TaskType.master => "reqMasterStateMatrix", - TaskType.generic => "reqGenStateMatrix", - TaskType.access => "reqAccStateMatrix", - TaskType.rule_delete => "reqRulDelStateMatrix", - TaskType.rule_modify => "reqRulModStateMatrix", - TaskType.group_create => "reqGrpCreStateMatrix", - TaskType.group_modify => "reqGrpModStateMatrix", - TaskType.group_delete => "reqGrpDelStateMatrix", - _ => throw new Exception($"Error: wrong task type:" + taskType.ToString()), - }; - - if(reset) - { - matrixKey += "Default"; - } - - List confData = await apiConnection.SendQueryAsync>(ConfigQueries.getConfigItemByKey, new { key = matrixKey }); - GlobalStateMatrix glbStateMatrix = System.Text.Json.JsonSerializer.Deserialize(confData[0].ConfData) ?? throw new Exception("Config data could not be parsed."); - GlobalMatrix = glbStateMatrix.GlobalMatrix; - } - } - - public class GlobalStateMatrixHelper - { - [JsonProperty("config_value"), JsonPropertyName("config_value")] - public string ConfData = ""; - } - - public class StateMatrixDict - { - public Dictionary Matrices { get; set; } = new Dictionary(); - - public async Task Init(WorkflowPhases phase, ApiConnection apiConnection) - { - Matrices = new Dictionary(); - foreach(TaskType taskType in Enum.GetValues(typeof(TaskType))) - { - Matrices.Add(taskType.ToString(), new StateMatrix()); - await Matrices[taskType.ToString()].Init(phase, apiConnection, taskType); - } - } - } -} diff --git a/roles/lib/files/FWO.Api.Client/Data/Tenant.cs b/roles/lib/files/FWO.Api.Client/Data/Tenant.cs deleted file mode 100644 index 0ade5f7866..0000000000 --- a/roles/lib/files/FWO.Api.Client/Data/Tenant.cs +++ /dev/null @@ -1,132 +0,0 @@ -using System.Text.Json.Serialization; -using Newtonsoft.Json; -using FWO.Middleware.RequestParameters; - -namespace FWO.Api.Data -{ - public class Tenant - { - [JsonProperty("tenant_id"), JsonPropertyName("tenant_id")] - public int Id { get; set; } - - [JsonProperty("tenant_name"), JsonPropertyName("tenant_name")] - public string Name { get; set; } = ""; - - [JsonProperty("tenant_comment"), JsonPropertyName("tenant_comment")] - public string? Comment { get; set; } - - [JsonProperty("tenant_projekt"), JsonPropertyName("tenant_projekt")] - public string? Project { get; set; } - - [JsonProperty("tenant_can_view_all_devices"), JsonPropertyName("tenant_can_view_all_devices")] - public bool ViewAllDevices { get; set; } - - [JsonProperty("tenant_is_superadmin"), JsonPropertyName("tenant_is_superadmin")] - public bool Superadmin { get; set; } // curently not in use - - [JsonProperty("tenant_to_devices"), JsonPropertyName("tenant_to_devices")] - public TenantDevice[] TenantDevices { get; set; } // TODO: Replace with Device[] (probably not possible) - - public int[] VisibleDevices { get; set; } // TODO: Remove later (probably not possible) - public int[] VisibleManagements { get; set; } // TODO: Remove later (probably not possible) - - public Tenant() - { - TenantDevices = new TenantDevice[]{}; - VisibleDevices = new int[]{}; - VisibleManagements = new int[]{}; - } - - public Tenant(Tenant tenant) - { - Id = tenant.Id; - Name = tenant.Name; - Comment = tenant.Comment; - Project = tenant.Project; - ViewAllDevices = tenant.ViewAllDevices; - // Superadmin = tenant.Superadmin; - TenantDevices = tenant.TenantDevices; - VisibleDevices = tenant.VisibleDevices; - VisibleManagements = tenant.VisibleManagements; - } - - public Tenant(TenantGetReturnParameters tenantGetParameters) - { - Id = tenantGetParameters.Id; - Name = tenantGetParameters.Name; - Comment = tenantGetParameters.Comment; - Project = tenantGetParameters.Project; - ViewAllDevices = tenantGetParameters.ViewAllDevices; - // Superadmin = tenantGetParameters.Superadmin; - List deviceList = new List(); - if (tenantGetParameters.Devices != null) - { - foreach(TenantViewDevice apiDevice in tenantGetParameters.Devices) - { - Device visibleDevice = new Device(){Id = apiDevice.Id, Name = apiDevice.Name}; - deviceList.Add(new TenantDevice(){VisibleDevice = visibleDevice}); - } - } - TenantDevices = deviceList.ToArray(); - VisibleDevices = new int[]{}; - VisibleManagements = new int[]{}; - } - - public string DeviceList() - { - List deviceList = new List(); - foreach (TenantDevice device in TenantDevices) - { - if (device.VisibleDevice.Name != null) - deviceList.Add(device.VisibleDevice.Name); - } - return string.Join(", ", deviceList); - } - - public bool Sanitize() - { - bool shortened = false; - Name = Sanitizer.SanitizeLdapNameMand(Name, ref shortened); - Comment = Sanitizer.SanitizeOpt(Comment, ref shortened); - Project = Sanitizer.SanitizeOpt(Project, ref shortened); - return shortened; - } - - public TenantGetReturnParameters ToApiParams() - { - TenantGetReturnParameters tenantGetParams = new TenantGetReturnParameters - { - Id = this.Id, - Name = this.Name, - Comment = this.Comment, - Project = this.Project, - ViewAllDevices = this.ViewAllDevices, - // Superadmin = this.Superadmin, - Devices = new List() - }; - foreach (TenantDevice device in TenantDevices) - { - tenantGetParams.Devices.Add(new TenantViewDevice(){ Id = device.VisibleDevice.Id, Name = (device.VisibleDevice.Name != null ? device.VisibleDevice.Name : "")}); - } - return tenantGetParams; - } - - public TenantEditParameters ToApiUpdateParams() - { - TenantEditParameters tenantUpdateParams = new TenantEditParameters - { - Id = this.Id, - Comment = this.Comment, - Project = this.Project, - ViewAllDevices = this.ViewAllDevices - }; - return tenantUpdateParams; - } - } - - public class TenantDevice - { - [JsonProperty("device"), JsonPropertyName("device")] - public Device VisibleDevice { get; set; } = new Device(); - } -} diff --git a/roles/lib/files/FWO.Api.Client/Data/TimeFilter.cs b/roles/lib/files/FWO.Api.Client/Data/TimeFilter.cs deleted file mode 100644 index 984ab155fa..0000000000 --- a/roles/lib/files/FWO.Api.Client/Data/TimeFilter.cs +++ /dev/null @@ -1,65 +0,0 @@ -using System.Text.Json.Serialization; -using Newtonsoft.Json; - -namespace FWO.Api.Data -{ - public enum TimeRangeType - { - Shortcut = 0, - Interval = 1, - Fixeddates = 2 - } - - public class TimeRangeShortcuts - { - // of course an enum would be better, but there are already values with blanks in the database - public static List Ranges = new List - { - "this year", - "last year", - "this month", - "last month", - "this week", - "last week", - "today", - "yesterday" - }; - } - - public class TimeFilter - { - [JsonProperty("is_shortcut"), JsonPropertyName("is_shortcut")] - public bool IsShortcut { get; set; } = true; - - [JsonProperty("shortcut"), JsonPropertyName("shortcut")] - public string TimeShortcut { get; set; } = "now"; - - [JsonProperty("report_time"), JsonPropertyName("report_time")] - public DateTime ReportTime { get; set; } = DateTime.Now.AddSeconds(-DateTime.Now.Second); - - - [JsonProperty("timerange_type"), JsonPropertyName("timerange_type")] - public TimeRangeType TimeRangeType { get; set; } = TimeRangeType.Shortcut; - - [JsonProperty("shortcut_range"), JsonPropertyName("shortcut_range")] - public string TimeRangeShortcut { get; set; } = "this year"; - - [JsonProperty("offset"), JsonPropertyName("offset")] - public int Offset { get; set; } = 0; - - [JsonProperty("interval"), JsonPropertyName("interval")] - public Interval Interval { get; set; } = Interval.Days; - - [JsonProperty("start_time"), JsonPropertyName("start_time")] - public DateTime StartTime { get; set; } = DateTime.Now.AddSeconds(-DateTime.Now.Second); - - [JsonProperty("open_start"), JsonPropertyName("open_start")] - public bool OpenStart { get; set; } = false; - - [JsonProperty("end_time"), JsonPropertyName("end_time")] - public DateTime EndTime { get; set; } = DateTime.Now.AddSeconds(-DateTime.Now.Second); - - [JsonProperty("open_end"), JsonPropertyName("open_end")] - public bool OpenEnd { get; set; } = false; - } -} diff --git a/roles/lib/files/FWO.Api.Client/Data/TimeWrapper.cs b/roles/lib/files/FWO.Api.Client/Data/TimeWrapper.cs deleted file mode 100644 index dd29d17a62..0000000000 --- a/roles/lib/files/FWO.Api.Client/Data/TimeWrapper.cs +++ /dev/null @@ -1,16 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Text.Json.Serialization; -using Newtonsoft.Json; -using System.Threading.Tasks; - -namespace FWO.Api.Data -{ - public class TimeWrapper - { - [JsonProperty("time"), JsonPropertyName("time")] - public DateTime Time { get; set; } - } -} diff --git a/roles/lib/files/FWO.Api.Client/Data/UiLdapConnection.cs b/roles/lib/files/FWO.Api.Client/Data/UiLdapConnection.cs deleted file mode 100644 index 3ec58cb0c8..0000000000 --- a/roles/lib/files/FWO.Api.Client/Data/UiLdapConnection.cs +++ /dev/null @@ -1,96 +0,0 @@ -using System.Text.Json.Serialization; -using Newtonsoft.Json; -using FWO.Middleware.RequestParameters; - -namespace FWO.Api.Data -{ - public class UiLdapConnection : LdapConnectionBase - { - private string name = ""; - - [JsonProperty("ldap_name"), JsonPropertyName("ldap_name")] - public string Name - { - get - { - // for compatibility: take hostname if not filled - return ((name != null && name != "") ? name : Host()); - } - set - { - name = value; - } - } - - public UiLdapConnection() - {} - - public UiLdapConnection(LdapGetUpdateParameters ldapGetUpdateParameters) : base(ldapGetUpdateParameters) - { - Name = (ldapGetUpdateParameters.Name != null ? ldapGetUpdateParameters.Name : ""); - } - - public UiLdapConnection(UiLdapConnection ldapConnection) - { - Id = ldapConnection.Id; - Name = ldapConnection.Name; - Address = ldapConnection.Address; - Port = ldapConnection.Port; - Type = ldapConnection.Type; - PatternLength = ldapConnection.PatternLength; - SearchUser = ldapConnection.SearchUser; - Tls = ldapConnection.Tls; - TenantLevel = ldapConnection.TenantLevel; - SearchUserPwd = ldapConnection.SearchUserPwd; - UserSearchPath = ldapConnection.UserSearchPath; - RoleSearchPath = ldapConnection.RoleSearchPath; - GroupSearchPath = ldapConnection.GroupSearchPath; - WriteUser = ldapConnection.WriteUser; - WriteUserPwd = ldapConnection.WriteUserPwd; - TenantId = ldapConnection.TenantId; - GlobalTenantName = ldapConnection.GlobalTenantName; - Active = ldapConnection.Active; - } - - public bool Sanitize() - { - bool shortened = false; - Name = Sanitizer.SanitizeMand(Name, ref shortened); - Address = Sanitizer.SanitizeMand(Address, ref shortened); - SearchUser = Sanitizer.SanitizeLdapPathOpt(SearchUser, ref shortened); - UserSearchPath = Sanitizer.SanitizeLdapPathOpt(UserSearchPath, ref shortened); - RoleSearchPath = Sanitizer.SanitizeLdapPathOpt(RoleSearchPath, ref shortened); - GroupSearchPath = Sanitizer.SanitizeLdapPathOpt(GroupSearchPath, ref shortened); - WriteUser = Sanitizer.SanitizeLdapPathOpt(WriteUser, ref shortened); - GlobalTenantName = Sanitizer.SanitizeOpt(GlobalTenantName, ref shortened); - SearchUserPwd = Sanitizer.SanitizePasswOpt(SearchUserPwd, ref shortened); - WriteUserPwd = Sanitizer.SanitizePasswOpt(WriteUserPwd, ref shortened); - return shortened; - } - - public LdapGetUpdateParameters ToApiParams() - { - return new LdapGetUpdateParameters - { - Id = this.Id, - Name = this.Name, - Address = this.Address, - Port = this.Port, - Type = this.Type, - PatternLength = this.PatternLength, - SearchUser = this.SearchUser, - Tls = this.Tls, - TenantLevel = this.TenantLevel, - SearchUserPwd = this.SearchUserPwd, - SearchpathForUsers = this.UserSearchPath, - SearchpathForRoles = this.RoleSearchPath, - SearchpathForGroups = this.GroupSearchPath, - WriteUser = this.WriteUser, - WriteUserPwd = this.WriteUserPwd, - TenantId = this.TenantId, - GlobalTenantName = this.GlobalTenantName, - Active = this.Active - }; - } - } -} diff --git a/roles/lib/files/FWO.Api.Client/Data/UiUser.cs b/roles/lib/files/FWO.Api.Client/Data/UiUser.cs deleted file mode 100644 index 872b4d33f5..0000000000 --- a/roles/lib/files/FWO.Api.Client/Data/UiUser.cs +++ /dev/null @@ -1,121 +0,0 @@ -using System.Text.Json.Serialization; -using Newtonsoft.Json; -using FWO.Middleware.RequestParameters; - -namespace FWO.Api.Data -{ - public class UiUser - { - [JsonProperty("uiuser_username"), JsonPropertyName("uiuser_username")] - public string Name { get; set; } = ""; - - [JsonProperty("uiuser_id"), JsonPropertyName("uiuser_id")] - public int DbId { get; set; } - - [JsonProperty("uuid"), JsonPropertyName("uuid")] - public string Dn { get; set; } = ""; - - public string Password { get; set; } = ""; - - [JsonProperty("uiuser_email"), JsonPropertyName("uiuser_email")] - public string? Email { get; set; } - - [JsonProperty("tenant"), JsonPropertyName("tenant")] - public Tenant? Tenant { get; set;} - - [JsonProperty("uiuser_language"), JsonPropertyName("uiuser_language")] - public string? Language { get; set; } - - [JsonProperty("uiuser_last_login"), JsonPropertyName("uiuser_last_login")] - public DateTime? LastLogin { get; set; } - - [JsonProperty("uiuser_last_password_change"), JsonPropertyName("uiuser_last_password_change")] - public DateTime? LastPasswordChange { get; set; } - - [JsonProperty("uiuser_password_must_be_changed"), JsonPropertyName("uiuser_password_must_be_changed")] - public bool PasswordMustBeChanged { get; set; } - - [JsonProperty("ldap_connection"), JsonPropertyName("ldap_connection")] - public UiLdapConnection LdapConnection { get; set;} = new UiLdapConnection(); - - public List Roles { get; set; } = new List(); - - public string Jwt { get; set; } = ""; - - public List Groups { get; set; } = new List(); - - public UiUser() - { - Tenant = new Tenant(); - LdapConnection = new UiLdapConnection(); - } - - public UiUser(UiUser user) - { - Name = user.Name; - DbId = user.DbId; - Dn = user.Dn; - if (user.Tenant != null) - { - Tenant = new Tenant(user.Tenant); - } - Password = user.Password; - Email = user.Email; - Language = user.Language; - Groups = user.Groups; - Roles = user.Roles; - if (user.LdapConnection != null) - { - LdapConnection = new UiLdapConnection(user.LdapConnection); - } - } - - public UiUser(UserGetReturnParameters userGetReturnParameters) - { - Name = userGetReturnParameters.Name; - DbId = userGetReturnParameters.UserId; - Dn = userGetReturnParameters.UserDn; - Email = userGetReturnParameters.Email; - if (userGetReturnParameters.TenantId != 0) - { - Tenant = new Tenant(){Id = userGetReturnParameters.TenantId}; - } - Language = userGetReturnParameters.Language; - LastLogin = userGetReturnParameters.LastLogin; - LastPasswordChange = userGetReturnParameters.LastPasswordChange; - PasswordMustBeChanged = userGetReturnParameters.PwChangeRequired; - LdapConnection = new UiLdapConnection(){Id = userGetReturnParameters.LdapId}; - } - - public bool isInternal() - { - return new DistName(Dn).IsInternal(); - } - - public bool Sanitize() - { - bool shortened = false; - Name = Sanitizer.SanitizeLdapNameMand(Name, ref shortened); - Email = Sanitizer.SanitizeOpt(Email, ref shortened); - Password = Sanitizer.SanitizePasswMand(Password, ref shortened); - return shortened; - } - - public UserGetReturnParameters ToApiParams() - { - return new UserGetReturnParameters - { - Name = this.Name, - UserId = this.DbId, - UserDn = this.Dn, - Email = this.Email, - TenantId = (this.Tenant != null ? this.Tenant.Id : 0), - Language = this.Language, - LastLogin = this.LastLogin, - LastPasswordChange = this.LastPasswordChange, - PwChangeRequired = this.PasswordMustBeChanged, - LdapId = this.LdapConnection.Id - }; - } - } -} diff --git a/roles/lib/files/FWO.Api.Client/FWO.Api.Client.csproj b/roles/lib/files/FWO.Api.Client/FWO.Api.Client.csproj index 9bdbde2262..8487bd7e7f 100644 --- a/roles/lib/files/FWO.Api.Client/FWO.Api.Client.csproj +++ b/roles/lib/files/FWO.Api.Client/FWO.Api.Client.csproj @@ -1,23 +1,28 @@  - net6.0 + net10.0 enable enable - - - - - + + + + + + + + - + + + diff --git a/roles/lib/files/FWO.Api.Client/GraphQlApiConnection.cs b/roles/lib/files/FWO.Api.Client/GraphQlApiConnection.cs index c8685a5385..2504031715 100644 --- a/roles/lib/files/FWO.Api.Client/GraphQlApiConnection.cs +++ b/roles/lib/files/FWO.Api.Client/GraphQlApiConnection.cs @@ -1,28 +1,23 @@ -using System; -using System.Net.Http; using System.Text.Json; -using System.Threading.Tasks; -using FWO.Logging; using GraphQL; using GraphQL.Client.Http; using GraphQL.Client.Serializer.SystemTextJson; using GraphQL.Client.Serializer.Newtonsoft; using GraphQL.Client.Abstractions; -using System.Linq; -using System.Net.WebSockets; -using System.Net.Security; using Newtonsoft.Json.Linq; +using FWO.Logging; +using System.Security.Claims; namespace FWO.Api.Client { public class GraphQlApiConnection : ApiConnection { + private const string LogCategory = "API Connections"; // Server URL - public string ApiServerUri { get; private set; } + public string ApiServerUri { get; private set; } = ""; - private GraphQLHttpClient graphQlClient; + private GraphQLHttpClient graphQlClient = null!; - private string? jwt; private string prevRole = ""; private void Initialize(string ApiServerUri) @@ -31,7 +26,7 @@ private void Initialize(string ApiServerUri) this.ApiServerUri = ApiServerUri; // Allow all certificates | TODO: REMOVE IF SERVER GOT VALID CERTIFICATE - HttpClientHandler Handler = new HttpClientHandler + HttpClientHandler Handler = new() { ServerCertificateCustomValidationCallback = (message, cert, chain, errors) => true }; @@ -39,7 +34,7 @@ private void Initialize(string ApiServerUri) graphQlClient = new GraphQLHttpClient(new GraphQLHttpClientOptions() { EndPoint = new Uri(this.ApiServerUri), - HttpMessageHandler = Handler, + HttpMessageHandler = Handler, UseWebSocketForQueriesAndMutations = false, // TODO: Use websockets for performance reasons ConfigureWebsocketOptions = webSocketOptions => webSocketOptions.RemoteCertificateValidationCallback += (message, cert, chain, errors) => true }, ApiConstants.UseSystemTextJsonSerializer ? new SystemTextJsonSerializer() : new NewtonsoftJsonSerializer()); @@ -61,7 +56,6 @@ public GraphQlApiConnection(string ApiServerUri) public override void SetAuthHeader(string jwt) { - this.jwt = jwt; graphQlClient.HttpClient.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", jwt); // Change jwt in auth header graphQlClient.Options.ConfigureWebSocketConnectionInitPayload = httpClientOptions => new { headers = new { authorization = $"Bearer {jwt}" } }; InvokeOnAuthHeaderChanged(this, jwt); @@ -69,41 +63,119 @@ public override void SetAuthHeader(string jwt) public override void SetRole(string role) { + prevRole = GetActRole(); graphQlClient.HttpClient.DefaultRequestHeaders.Remove("x-hasura-role"); graphQlClient.HttpClient.DefaultRequestHeaders.Add("x-hasura-role", role); } - public override void SetProperRole(System.Security.Claims.ClaimsPrincipal user, List targetRoleList) + public bool IsActRole(string role) { - try + return role == GetActRole(); + } + + public string GetActRole() + { + if (graphQlClient.HttpClient.DefaultRequestHeaders.TryGetValues("x-hasura-role", out IEnumerable? roles)) { - prevRole = graphQlClient.HttpClient.DefaultRequestHeaders.GetValues("x-hasura-role")?.First() ?? ""; + if (roles.Count() > 1) + { + Log.WriteDebug("API call", $"More than one role in x-hasura-role: {roles}"); + } + return roles.First(); } - catch(Exception){} + return ""; + } - // first look if user is already in one of the target roles - foreach(string role in targetRoleList) + public override void SetBestRole(System.Security.Claims.ClaimsPrincipal user, List targetRoleList) + { + prevRole = GetActRole(); + foreach (string role in targetRoleList) { - if (user.IsInRole(role)) + if (HasAllowedRole(user, role)) { SetRole(role); return; } } + } + + public override void SetProperRole(System.Security.Claims.ClaimsPrincipal user, List targetRoleList) + { + prevRole = GetActRole(); + + // first look if user is already in one of the target roles + if (targetRoleList.Contains(prevRole)) + { + return; + } // now look if user has a target role as allowed role - foreach(string role in targetRoleList) + SetBestRole(user, targetRoleList); + } + + public override void SwitchBack() + { + if (prevRole != "") { - if(user.Claims.FirstOrDefault(claim => claim.Type == "x-hasura-allowed-roles" && claim.Value == role) != null) + SetRole(prevRole); + } + } + + private static bool HasAllowedRole(ClaimsPrincipal user, string role) + { + if (user.IsInRole(role)) + { + return true; + } + + foreach (Claim claim in user.Claims.Where(currentClaim => IsHasuraAllowedRolesClaim(currentClaim.Type))) + { + if (claim.Value == role) { - SetRole(role); - return; + return true; + } + + if (TryParseAllowedRoles(claim.Value, out List parsedRoles) + && parsedRoles.Contains(role, StringComparer.OrdinalIgnoreCase)) + { + return true; } } + + return false; } - public override void SwitchBack() + private static bool IsHasuraAllowedRolesClaim(string claimType) + { + if (claimType.Equals("x-hasura-allowed-roles", StringComparison.OrdinalIgnoreCase)) + { + return true; + } + + return claimType.EndsWith("/x-hasura-allowed-roles", StringComparison.OrdinalIgnoreCase); + } + + private static bool TryParseAllowedRoles(string claimValue, out List parsedRoles) { - SetRole(prevRole); + parsedRoles = []; + if (string.IsNullOrWhiteSpace(claimValue)) + { + return false; + } + + try + { + string[]? roleArray = JsonSerializer.Deserialize(claimValue); + if (roleArray == null) + { + return false; + } + parsedRoles = roleArray.Where(role => !string.IsNullOrWhiteSpace(role)).ToList(); + return true; + } + catch + { + return false; + } } /// @@ -119,8 +191,8 @@ public override async Task SendQueryAsync( { try { - Log.WriteDebug("API call", $"Sending API call {operationName}: {query.Substring(0, Math.Min(query.Length, 50)).Replace(Environment.NewLine, "")}... " + - (variables != null ? $"with variables: { JsonSerializer.Serialize(variables).Substring(0, Math.Min(JsonSerializer.Serialize(variables).Length, 50)).Replace(Environment.NewLine, "")}..." : "")); + Log.WriteDebug("API call", $"Sending API call {operationName} in role {GetActRole()}: {query.Substring(0, Math.Min(query.Length, 70)).Replace(Environment.NewLine, "")}... " + + (variables != null ? $"with variables: {JsonSerializer.Serialize(variables).Substring(0, Math.Min(JsonSerializer.Serialize(variables).Length, 50)).Replace(Environment.NewLine, "")}..." : "")); GraphQLResponse response = await graphQlClient.SendQueryAsync(query, variables, operationName); // Log.WriteDebug("API call", "API response received."); @@ -135,11 +207,11 @@ public override async Task SendQueryAsync( // JwtEventService } - Log.WriteError("API Connection", $"Error while sending query to GraphQL API. Caught by GraphQL client library. \nMessage: {error.Message}"); + Log.WriteError(LogCategory, $"Error while sending query to GraphQL API. Caught by GraphQL client library. \nMessage: {error.Message}"); errorMessage += $"{error.Message}\n"; } - throw new Exception(errorMessage); + throw new InvalidOperationException(errorMessage); } else { @@ -150,19 +222,19 @@ public override async Task SendQueryAsync( if (ApiConstants.UseSystemTextJsonSerializer) { - JsonElement.ObjectEnumerator responseObjectEnumerator = response.Data.EnumerateObject(); - responseObjectEnumerator.MoveNext(); - QueryResponseType returnValue = JsonSerializer.Deserialize(responseObjectEnumerator.Current.Value.GetRawText()) ?? - throw new Exception($"Could not convert result from Json to {typeof(QueryResponseType)}.\nJson: {responseObjectEnumerator.Current.Value.GetRawText()}"); - return returnValue; + // JsonElement.ObjectEnumerator responseObjectEnumerator = response.Data.EnumerateObject(); + // responseObjectEnumerator.MoveNext(); + // QueryResponseType returnValue = JsonSerializer.Deserialize(responseObjectEnumerator.Current.Value.GetRawText()) ?? + // throw new Exception($"Could not convert result from Json to {typeof(QueryResponseType)}.\nJson: {responseObjectEnumerator.Current.Value.GetRawText()}"); + // return returnValue; } else { JObject data = (JObject)response.Data; - JProperty prop = (JProperty)(data.First ?? throw new Exception($"Could not retrieve unique result attribute from Json.\nJson: {response.Data}")); + JProperty prop = (JProperty)(data.First ?? throw new InvalidOperationException($"Could not retrieve unique result attribute from Json.\nJson: {response.Data}")); JToken result = prop.Value; QueryResponseType returnValue = result.ToObject() ?? - throw new Exception($"Could not convert result from Json to {typeof(QueryResponseType)}.\nJson: {response.Data}"); + throw new InvalidOperationException($"Could not convert result from Json to {typeof(QueryResponseType)}.\nJson: {response.Data}"); return returnValue; } } @@ -170,21 +242,65 @@ public override async Task SendQueryAsync( catch (Exception exception) { - Log.WriteError("API Connection", $"Error while sending query to GraphQL API. Query: {(query != null ? query : "")}, variables: {(variables != null ? JsonSerializer.Serialize(variables) : "")}", exception); + Log.WriteError(LogCategory, $"Error while sending query to GraphQL API. Query: {query}, variables: {(variables != null ? JsonSerializer.Serialize(variables) : "")}", exception); throw; } } + /// + /// Sends an API call and returns a non-throwing response wrapper containing data or errors. + /// + public override async Task> SendQuerySafeAsync(string query, object? variables = null, string? operationName = null) + { + try + { + Log.WriteDebug("API call", $"Sending API call {operationName} in role {GetActRole()}: {query.Substring(0, Math.Min(query.Length, 70)).Replace(Environment.NewLine, "")}... " + + (variables != null ? $"with variables: {JsonSerializer.Serialize(variables).Substring(0, Math.Min(JsonSerializer.Serialize(variables).Length, 50)).Replace(Environment.NewLine, "")}..." : "")); + GraphQLResponse response = await graphQlClient.SendQueryAsync(query, variables, operationName); + + if (response.Errors != null) + { + List errorMessages = response.Errors.Select(error => + { + Log.WriteError(LogCategory, $"Error while sending query to GraphQL API. Caught by GraphQL client library. \nMessage: {error.Message}"); + return error.Message; + }).ToList(); + return new ApiResponse(errorMessages.ToArray()); + } + + if (ApiConstants.UseSystemTextJsonSerializer) + { + throw new NotImplementedException("System.Text.Json is not supported anymore."); + } + + JObject data = (JObject)response.Data; + JProperty prop = (JProperty)(data.First ?? throw new InvalidOperationException($"Could not retrieve unique result attribute from Json.\nJson: {response.Data}")); + JToken result = prop.Value; + QueryResponseType returnValue = result.ToObject() ?? + throw new InvalidOperationException($"Could not convert result from Json to {typeof(QueryResponseType)}.\nJson: {response.Data}"); + return new ApiResponse(returnValue); + } + catch (Exception exception) + { + Log.WriteError(LogCategory, $"Error while sending query to GraphQL API. Query: {query}, variables: {(variables != null ? JsonSerializer.Serialize(variables) : "")}", exception); + return new ApiResponse(exception.Message); + } + } + public override GraphQlApiSubscription GetSubscription(Action exceptionHandler, GraphQlApiSubscription.SubscriptionUpdate subscriptionUpdateHandler, string subscription, object? variables = null, string? operationName = null) { try { - GraphQLRequest request = new GraphQLRequest(subscription, variables, operationName); - return new GraphQlApiSubscription(this, graphQlClient, request, exceptionHandler, subscriptionUpdateHandler); + GraphQLRequest request = new(subscription, variables, operationName); + GraphQlApiSubscription newSub = + new(this, graphQlClient, request, exceptionHandler, subscriptionUpdateHandler); + subscriptions.Add(newSub); + + return newSub; } catch (Exception exception) { - Log.WriteError("API Connection", "Error while creating subscription to GraphQL API.", exception); + Log.WriteError(LogCategory, "Error while creating subscription to GraphQL API.", exception); throw; } } @@ -194,7 +310,21 @@ protected override void Dispose(bool disposing) if (disposing) { graphQlClient.Dispose(); + foreach (ApiSubscription subscription in subscriptions) + { + subscription.Dispose(); + } + } + } + + public override void DisposeSubscriptions() + { + foreach (ApiSubscription subscription in subscriptions.Where(_ => _.GetType() == typeof(T))) + { + subscription.Dispose(); } + + subscriptions.RemoveAll(_ => _.GetType() == typeof(T)); } } } diff --git a/roles/lib/files/FWO.Api.Client/GraphQlApiSubscription.cs b/roles/lib/files/FWO.Api.Client/GraphQlApiSubscription.cs index b0ed669510..1711ef7e72 100644 --- a/roles/lib/files/FWO.Api.Client/GraphQlApiSubscription.cs +++ b/roles/lib/files/FWO.Api.Client/GraphQlApiSubscription.cs @@ -1,37 +1,39 @@ -using GraphQL; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Text.Json; -using System.Threading.Tasks; -using FWO.Api.Client; -using Newtonsoft.Json.Linq; using FWO.Logging; -using GraphQL.Client.Abstractions; +using GraphQL; using GraphQL.Client.Http; +using Newtonsoft.Json.Linq; +using System.Diagnostics.CodeAnalysis; namespace FWO.Api.Client { - public class GraphQlApiSubscription : ApiSubscription, IDisposable + [SuppressMessage("Design", "S3060:DoNotCallOverridableMethodsInConstructors", + Justification = "CreateSubscription is virtual for unit tests only. This is a design choice.")] + public class GraphQlApiSubscription : ApiSubscription { - public delegate void SubscriptionUpdate(SubscriptionResponseType reponse); - public event SubscriptionUpdate OnUpdate; + public delegate void SubscriptionUpdate(SubscriptionResponseType response); + public event SubscriptionUpdate? OnUpdate; + + private IObservable>? _subscriptionStream; + private IDisposable? _subscription; - private IObservable> subscriptionStream; - private IDisposable subscription; - private readonly GraphQLHttpClient graphQlClient; - private readonly GraphQLRequest request; - private readonly Action internalExceptionHandler; + private readonly GraphQLHttpClient _graphQlClient; + private readonly GraphQLRequest _request; + private readonly Action _internalExceptionHandler; + private readonly ApiConnection _apiConnection; - public GraphQlApiSubscription(ApiConnection apiConnection, GraphQLHttpClient graphQlClient, GraphQLRequest request, Action exceptionHandler, SubscriptionUpdate OnUpdate) + private readonly object _lock = new(); + private bool _disposed; + + public GraphQlApiSubscription(ApiConnection apiConnection, GraphQLHttpClient graphQlClient, GraphQLRequest request, Action exceptionHandler, SubscriptionUpdate onUpdate) { - this.OnUpdate = OnUpdate; - this.graphQlClient = graphQlClient; - this.request = request; + _apiConnection = apiConnection; + _graphQlClient = graphQlClient; + _request = request; + + OnUpdate += onUpdate; // handle subscription terminating exceptions - internalExceptionHandler = (Exception exception) => + _internalExceptionHandler = (Exception exception) => { // Case: Jwt expired if (exception.Message.Contains("JWTExpired")) @@ -45,65 +47,84 @@ public GraphQlApiSubscription(ApiConnection apiConnection, GraphQLHttpClient gra CreateSubscription(); - apiConnection.OnAuthHeaderChanged += ApiConnectionOnAuthHeaderChanged; + _apiConnection.OnAuthHeaderChanged += ApiConnectionOnAuthHeaderChanged; } - private void CreateSubscription() + protected virtual void CreateSubscription() { - Log.WriteDebug("API", $"Creating API subscription {request.OperationName}."); - subscriptionStream = graphQlClient.CreateSubscriptionStream(request, internalExceptionHandler); - Log.WriteDebug("API", "API subscription created."); - - subscription = subscriptionStream.Subscribe(response => + lock (_lock) { - if (ApiConstants.UseSystemTextJsonSerializer) - { - JsonElement.ObjectEnumerator responseObjectEnumerator = response.Data.EnumerateObject(); - responseObjectEnumerator.MoveNext(); - SubscriptionResponseType returnValue = JsonSerializer.Deserialize(responseObjectEnumerator.Current.Value.GetRawText()) ?? - throw new Exception($"Could not convert result from Json to {nameof(SubscriptionResponseType)}.\nJson: {responseObjectEnumerator.Current.Value.GetRawText()}"); ; - OnUpdate(returnValue); - } - else + if (_disposed) return; + + _subscription?.Dispose(); + _subscription = null; + + Log.WriteDebug("API", $"Creating API subscription {_request.OperationName}."); + _subscriptionStream = _graphQlClient.CreateSubscriptionStream(_request, _internalExceptionHandler); + Log.WriteDebug("API", "API subscription created."); + + _subscription = _subscriptionStream.Subscribe(response => { - try + if (_disposed) return; + + if (ApiConstants.UseSystemTextJsonSerializer) { - // If repsonse.Data == null -> Jwt expired - connection was closed - // Leads to this method getting called again - if (response.Data == null) + throw new NotImplementedException("System.Text.Json is not supported anymore."); + } + else + { + try { - // Terminate subscription - subscription.Dispose(); + // If repsonse.Data == null -> Jwt expired - connection was closed + // Leads to this method getting called again + if (response.Data == null) + { + // Terminate subscription + lock (_lock) + { + _subscription?.Dispose(); + _subscription = null; + } + } + else + { + JObject data = (JObject)response.Data; + JProperty prop = (JProperty)(data.First ?? throw new Exception($"Could not retrieve unique result attribute from Json.\nJson: {response.Data}")); + JToken result = prop.Value; + SubscriptionResponseType returnValue = result.ToObject() ?? throw new Exception($"Could not convert result from Json to {typeof(SubscriptionResponseType)}.\nJson: {response.Data}"); + OnUpdate?.Invoke(returnValue); + } } - else + catch (Exception ex) { - JObject data = (JObject)response.Data; - JProperty prop = (JProperty)(data.First ?? throw new Exception($"Could not retrieve unique result attribute from Json.\nJson: {response.Data}")); - JToken result = prop.Value; - SubscriptionResponseType returnValue = result.ToObject() ?? throw new Exception($"Could not convert result from Json to {typeof(SubscriptionResponseType)}.\nJson: {response.Data}"); - OnUpdate(returnValue); + Log.WriteError("GraphQL Subscription", "Subscription lead to exception", ex); + throw; } } - catch (Exception ex) - { - Log.WriteError("GraphQL Subscription", "Subscription lead to exception", ex); - throw; - } - } - }); + }); + } } private void ApiConnectionOnAuthHeaderChanged(object? sender, string jwt) { - subscription.Dispose(); + // Recreate subscription (CreateSubscription handles disposal + locking) CreateSubscription(); } protected override void Dispose(bool disposing) { - if (disposing) + if (!disposing) return; + + lock (_lock) { - subscription.Dispose(); + if (_disposed) return; + _disposed = true; + + // Important: detach from ApiConnection event to avoid keeping this subscription alive. + _apiConnection.OnAuthHeaderChanged -= ApiConnectionOnAuthHeaderChanged; + _subscription?.Dispose(); + _subscription = null; + OnUpdate = null; } } } diff --git a/roles/lib/files/FWO.Api.Client/JsonCustomConverters.cs b/roles/lib/files/FWO.Api.Client/JsonCustomConverters.cs deleted file mode 100644 index 06dd7624fa..0000000000 --- a/roles/lib/files/FWO.Api.Client/JsonCustomConverters.cs +++ /dev/null @@ -1,82 +0,0 @@ -using NetTools; -using Newtonsoft.Json; -using Newtonsoft.Json.Linq; -using System; -using System.Collections.Generic; -using System.Diagnostics; -using System.Linq; -using System.Net; -using System.Text; -using System.Text.Json.Nodes; -using System.Threading.Tasks; - -namespace FWO.Api.Client -{ - public class WrapperConverter : JsonConverter - { - private readonly string wrappedObjectName = ""; - - public WrapperConverter(string wrappedObjectName) - { - this.wrappedObjectName = wrappedObjectName; - } - - public override bool CanConvert(Type objectType) => typeof(ValueType).IsAssignableFrom(objectType); - - public override object? ReadJson(JsonReader reader, Type objectType, object? existingValue, JsonSerializer serializer) - { - // Load the JSON as a JObject - JObject jsonObject = JObject.Load(reader); - - // Check if the "wrappedObjectName" property exists - if (jsonObject.TryGetValue(wrappedObjectName, out JToken? wrappedObjectToken)) - { - // Deserialize the wrapped object - return wrappedObjectToken.ToObject(serializer); - } - - // Deserialize the wrapper object otherwise - return jsonObject.ToObject(serializer); - } - - public override void WriteJson(JsonWriter writer, object? value, JsonSerializer serializer) - { - // Wrap the object with a property named "wrappedObjectName" - JObject jsonObject = new JObject - { - { wrappedObjectName, value == null ? null : JToken.FromObject(value, serializer) } - }; - - // Write the JSON - jsonObject.WriteTo(writer); - } - } - - public class IpAddressRangeJsonTypeConverter : JsonConverter - { - public override IPAddressRange ReadJson(JsonReader reader, Type objectType, IPAddressRange? existingValue, bool hasExistingValue, JsonSerializer serializer) - { - // Load the JSON as a JObject - JObject jsonObject = JObject.Load(reader); - // Deserialize the IP address range based on the properties ip_range_start and ip_range_end - IPAddress start = IPAddress.Parse((jsonObject.GetValue("ip_range_start")?.ToObject() ?? throw new ArgumentNullException("ip_range_start")).Replace("/32", "")); - IPAddress end = IPAddress.Parse((jsonObject.GetValue("ip_range_end")?.ToObject() ?? throw new ArgumentNullException("ip_range_start")).Replace("/32", "")); - return new IPAddressRange(start, end); - } - - public override void WriteJson(JsonWriter writer, IPAddressRange? value, JsonSerializer serializer) - { - if (value != null) - { - // Create a JSON JObject - JObject result = new JObject - { - { "ip_range_start", value.Begin.ToString() }, - { "ip_range_end", value.Begin.ToString() } - }; - - result.WriteTo(writer); - } - } - } -} diff --git a/roles/lib/files/FWO.Api.Client/Queries/AuthQueries.cs b/roles/lib/files/FWO.Api.Client/Queries/AuthQueries.cs index 8a9eb76c2b..3f3711ae79 100644 --- a/roles/lib/files/FWO.Api.Client/Queries/AuthQueries.cs +++ b/roles/lib/files/FWO.Api.Client/Queries/AuthQueries.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.IO; using FWO.Logging; @@ -12,22 +12,32 @@ public class AuthQueries : Queries public static readonly string updateTenant; public static readonly string deleteTenant; public static readonly string addDeviceToTenant; - public static readonly string deleteDeviceFromTenant; + public static readonly string addTenantToManagement; + public static readonly string addTenantToGateway; + public static readonly string deleteAllGatewaysOfTenant; + public static readonly string deleteAllManagementsOfTenant; + public static readonly string getVisibleDeviceIdsPerTenant; + public static readonly string getVisibleManagementIdsPerTenant; + public static readonly string getTenantNetworks; + public static readonly string addTenantNetwork; + public static readonly string deleteTenantNetwork; + public static readonly string getUsers; + public static readonly string getUserEmails; public static readonly string getUserByDn; public static readonly string getUserByDbId; - public static readonly string addUser; + public static readonly string upsertUiUser; public static readonly string updateUserEmail; public static readonly string updateUserLanguage; public static readonly string updateUserLastLogin; public static readonly string updateUserPasswordChange; public static readonly string deleteUser; public static readonly string assertUserExists; - public static readonly string getVisibleDeviceIdsPerTenant; - public static readonly string getVisibleManagementIdsPerTenant; + public static readonly string getLdapConnections; public static readonly string getAllLdapConnections; public static readonly string getLdapConnectionsSubscription; + public static readonly string getLdapConnectionForUserSearchById; public static readonly string newLdapConnection; public static readonly string updateLdapConnection; public static readonly string deleteLdapConnection; @@ -36,36 +46,50 @@ static AuthQueries() { try { - getTenantId = File.ReadAllText(QueryPath + "auth/getTenantId.graphql"); - getTenants = File.ReadAllText(QueryPath + "auth/getTenants.graphql"); - addTenant = File.ReadAllText(QueryPath + "auth/addTenant.graphql"); - updateTenant = File.ReadAllText(QueryPath + "auth/updateTenant.graphql"); - deleteTenant = File.ReadAllText(QueryPath + "auth/deleteTenant.graphql"); - addDeviceToTenant = File.ReadAllText(QueryPath + "auth/addDeviceToTenant.graphql"); - deleteDeviceFromTenant = File.ReadAllText(QueryPath + "auth/deleteDeviceFromTenant.graphql"); - getVisibleDeviceIdsPerTenant = File.ReadAllText(QueryPath + "auth/getVisibleDeviceIdsPerTenant.graphql"); - getVisibleManagementIdsPerTenant = File.ReadAllText(QueryPath + "auth/getVisibleManagementIdsPerTenant.graphql"); - getLdapConnections = File.ReadAllText(QueryPath + "auth/getLdapConnections.graphql"); - getAllLdapConnections = File.ReadAllText(QueryPath + "auth/getAllLdapConnections.graphql"); - getLdapConnectionsSubscription = File.ReadAllText(QueryPath + "auth/getLdapConnectionsSubscription.graphql"); - getUsers = File.ReadAllText(QueryPath + "auth/getUsers.graphql"); - getUserByDn = File.ReadAllText(QueryPath + "auth/getUserByDn.graphql"); - getUserByDbId = File.ReadAllText(QueryPath + "auth/getUserByDbId.graphql"); - addUser = File.ReadAllText(QueryPath + "auth/addUser.graphql"); - updateUserEmail = File.ReadAllText(QueryPath + "auth/updateUserEmail.graphql"); - updateUserLanguage = File.ReadAllText(QueryPath + "auth/updateUserLanguage.graphql"); - updateUserLastLogin = File.ReadAllText(QueryPath + "auth/updateUserLastLogin.graphql"); - updateUserPasswordChange = File.ReadAllText(QueryPath + "auth/updateUserPasswordChange.graphql"); - deleteUser = File.ReadAllText(QueryPath + "auth/deleteUser.graphql"); - assertUserExists = File.ReadAllText(QueryPath + "auth/assertUserExists.graphql"); - newLdapConnection = File.ReadAllText(QueryPath + "auth/newLdapConnection.graphql"); - updateLdapConnection = File.ReadAllText(QueryPath + "auth/updateLdapConnection.graphql"); - deleteLdapConnection = File.ReadAllText(QueryPath + "auth/deleteLdapConnection.graphql"); + getTenantId = GetQueryText("auth/getTenantId.graphql"); + getTenants = GetQueryText("auth/getTenants.graphql"); + addTenant = GetQueryText("auth/addTenant.graphql"); + updateTenant = GetQueryText("auth/updateTenant.graphql"); + deleteTenant = GetQueryText("auth/deleteTenant.graphql"); + addDeviceToTenant = GetQueryText("auth/addDeviceToTenant.graphql"); + addTenantToManagement = GetQueryText("auth/addTenantToManagement.graphql"); + addTenantToGateway = GetQueryText("auth/addTenantToGateway.graphql"); + deleteAllGatewaysOfTenant = GetQueryText("auth/deleteAllGatewaysOfTenant.graphql"); + deleteAllManagementsOfTenant = GetQueryText("auth/deleteAllManagementsOfTenant.graphql"); + getVisibleDeviceIdsPerTenant = GetQueryText("auth/getTenantVisibleDeviceIds.graphql"); + getVisibleManagementIdsPerTenant = GetQueryText("auth/getTenantVisibleManagementIds.graphql"); + getTenantNetworks = GetQueryText("auth/getTenantNetworks.graphql"); + addTenantNetwork = GetQueryText("auth/addTenantNetwork.graphql"); + deleteTenantNetwork = GetQueryText("auth/deleteTenantNetwork.graphql"); + + getUsers = GetQueryText("auth/getUsers.graphql"); + getUserEmails = GetQueryText("auth/getUserEmails.graphql"); + getUserByDn = GetQueryText("auth/getUserByDn.graphql"); + getUserByDbId = GetQueryText("auth/getUserByDbId.graphql"); + upsertUiUser = GetQueryText("auth/upsertUiUser.graphql"); + updateUserEmail = GetQueryText("auth/updateUserEmail.graphql"); + updateUserLanguage = GetQueryText("auth/updateUserLanguage.graphql"); + updateUserLastLogin = GetQueryText("auth/updateUserLastLogin.graphql"); + updateUserPasswordChange = GetQueryText("auth/updateUserPasswordChange.graphql"); + deleteUser = GetQueryText("auth/deleteUser.graphql"); + assertUserExists = GetQueryText("auth/assertUserExists.graphql"); + + getLdapConnections = GetQueryText("auth/getLdapConnections.graphql"); + getAllLdapConnections = GetQueryText("auth/getAllLdapConnections.graphql"); + getLdapConnectionsSubscription = GetQueryText("auth/getLdapConnectionsSubscription.graphql"); + getLdapConnectionForUserSearchById = GetQueryText("auth/getLdapConnectionForUserSearchById.graphql"); + newLdapConnection = GetQueryText("auth/newLdapConnection.graphql"); + updateLdapConnection = GetQueryText("auth/updateLdapConnection.graphql"); + deleteLdapConnection = GetQueryText("auth/deleteLdapConnection.graphql"); } catch (Exception exception) { Log.WriteError("Initialize AuthQueries", "Api AuthQueries could not be loaded.", exception); +#if RELEASE Environment.Exit(-1); +#else + throw; +#endif } } } diff --git a/roles/lib/files/FWO.Api.Client/Queries/ComplianceQueries.cs b/roles/lib/files/FWO.Api.Client/Queries/ComplianceQueries.cs index a31b87581f..4676dacb01 100644 --- a/roles/lib/files/FWO.Api.Client/Queries/ComplianceQueries.cs +++ b/roles/lib/files/FWO.Api.Client/Queries/ComplianceQueries.cs @@ -1,29 +1,90 @@ -using FWO.Logging; +using FWO.Logging; namespace FWO.Api.Client.Queries { public class ComplianceQueries : Queries { public static readonly string addNetworkZone; - public static readonly string deleteNetworkZone; - public static readonly string getNetworkZones; - public static readonly string updateNetworkZones; - public static readonly string modifyNetworkZoneCommunication; + public static readonly string removeNetworkZone; + public static readonly string getNetworkZonesForMatrix; + public static readonly string updateNetworkZone; + + public static readonly string updateNetworkZoneCommunication; + + public static readonly string addViolations; + public static readonly string getViolations; + public static readonly string updateViolationById; + public static readonly string removeViolations; + public static readonly string getViolationsChunk; + public static readonly string getViolationsByRuleID; + public static readonly string getViolationsByRuleUid; + + public static readonly string addPolicy; + public static readonly string disablePolicy; + public static readonly string getPolicies; + public static readonly string getPolicyById; + + public static readonly string addCriterion; + public static readonly string removeCriterion; + public static readonly string updateCriterionMetadata; + public static readonly string getCriteria; + public static readonly string getMatrices; + public static readonly string getMatrixByName; + + public static readonly string addCritToPolicy; + public static readonly string removeCritFromPolicy; + public static readonly string getPolicyIdsForCrit; + + public static readonly string deleteAllViolations; + public static readonly string getViolationCount; static ComplianceQueries() { try { - addNetworkZone = File.ReadAllText(QueryPath + "compliance/addNetworkZone.graphql"); - deleteNetworkZone = File.ReadAllText(QueryPath + "compliance/deleteNetworkZone.graphql"); - getNetworkZones = File.ReadAllText(QueryPath + "compliance/getNetworkZones.graphql"); - updateNetworkZones = File.ReadAllText(QueryPath + "compliance/updateNetworkZone.graphql"); - modifyNetworkZoneCommunication = File.ReadAllText(QueryPath + "compliance/updateNetworkZoneCommunication.graphql"); + addNetworkZone = GetQueryText("compliance/addNetworkZone.graphql"); + removeNetworkZone = GetQueryText("compliance/removeNetworkZone.graphql"); + getNetworkZonesForMatrix = GetQueryText("compliance/getNetworkZonesForMatrix.graphql"); + updateNetworkZone = GetQueryText("compliance/updateNetworkZone.graphql"); + + updateNetworkZoneCommunication = GetQueryText("compliance/updateNetworkZoneCommunication.graphql"); + + addViolations = GetQueryText("compliance/addViolations.graphql"); + getViolations = GetQueryText("compliance/getViolations.graphql"); + updateViolationById = GetQueryText("compliance/updateViolationById.graphql"); + removeViolations = GetQueryText("compliance/removeViolations.graphql"); + + addPolicy = GetQueryText("compliance/addPolicy.graphql"); + disablePolicy = GetQueryText("compliance/disablePolicy.graphql"); + getPolicies = GetQueryText("compliance/getPolicies.graphql"); + getPolicyById = GetQueryText("compliance/getPolicyById.graphql"); + + addCriterion = GetQueryText("compliance/addCriterion.graphql"); + removeCriterion = GetQueryText("compliance/removeCriterion.graphql"); + updateCriterionMetadata = GetQueryText("compliance/updateCriterionMetadata.graphql"); + getCriteria = GetQueryText("compliance/getCriteria.graphql"); + getMatrices = GetQueryText("compliance/getMatrices.graphql"); + getMatrixByName = GetQueryText("compliance/getMatrixByName.graphql"); + + addCritToPolicy = GetQueryText("compliance/addCritToPolicy.graphql"); + removeCritFromPolicy = GetQueryText("compliance/removeCritFromPolicy.graphql"); + getPolicyIdsForCrit = GetQueryText("compliance/getPolicyIdsForCrit.graphql"); + + getViolationsChunk = GetQueryText("compliance/getViolationsChunk.graphql"); + getViolationsByRuleID = GetQueryText("compliance/getViolationsByRuleID.graphql"); + getViolationsByRuleUid = GetQueryText("compliance/getViolationsByRuleUid.graphql"); + + deleteAllViolations = GetQueryText("compliance/deleteAllViolations.graphql"); + getViolationCount = GetQueryText("compliance/getViolationCount.graphql"); } catch (Exception exception) { Log.WriteError("Initialize Compliance Queries", "Api compliance queries could not be loaded.", exception); +#if RELEASE Environment.Exit(-1); +#else + throw; +#endif } } } diff --git a/roles/lib/files/FWO.Api.Client/Queries/ConfigQueries.cs b/roles/lib/files/FWO.Api.Client/Queries/ConfigQueries.cs index ea6d9cb2b1..f9984aa6b6 100644 --- a/roles/lib/files/FWO.Api.Client/Queries/ConfigQueries.cs +++ b/roles/lib/files/FWO.Api.Client/Queries/ConfigQueries.cs @@ -1,4 +1,4 @@ -using FWO.Logging; +using FWO.Logging; namespace FWO.Api.Client.Queries { @@ -7,35 +7,62 @@ public class ConfigQueries : Queries public static readonly string getLanguages; public static readonly string getAllTexts; public static readonly string getTextsPerLanguage; - public static readonly string getConfigSubscription; + public static readonly string getCustomTextsPerLanguage; + public static readonly string upsertCustomText; + public static readonly string deleteCustomText; + public static readonly string subscribeConfigChangesByUser; public static readonly string addConfigItem; public static readonly string updateConfigItem; public static readonly string upsertConfigItem; + public static readonly string upsertConfigItems; public static readonly string getConfigItemsByUser; public static readonly string getConfigItemByKey; public static readonly string subscribeAutodiscoveryConfigChanges; + public static readonly string subscribeExternalRequestConfigChanges; public static readonly string subscribeDailyCheckConfigChanges; + public static readonly string subscribeImportAppDataConfigChanges; + public static readonly string subscribeImportIpDataConfigChanges; + public static readonly string subscribeImportNotifyConfigChanges; + public static readonly string subscribeVarianceAnalysisConfigChanges; + public static readonly string subscribeComplianceCheckConfigChanges; + public static readonly string subscribeUpdateRuleOwnerMappingConfigChanges; + static ConfigQueries() { try { - getLanguages = File.ReadAllText(QueryPath + "config/getLanguages.graphql"); - getAllTexts = File.ReadAllText(QueryPath + "config/getTexts.graphql"); - getTextsPerLanguage = File.ReadAllText(QueryPath + "config/getTextsPerLanguage.graphql"); - addConfigItem = File.ReadAllText(QueryPath + "config/addConfigItem.graphql"); - updateConfigItem = File.ReadAllText(QueryPath + "config/updateConfigItem.graphql"); - getConfigItemsByUser = File.ReadAllText(QueryPath + "config/getConfigItemsByUser.graphql"); - getConfigItemByKey = File.ReadAllText(QueryPath + "config/getConfigItemByKey.graphql"); - upsertConfigItem = File.ReadAllText(QueryPath + "config/upsertConfigItem.graphql"); - subscribeAutodiscoveryConfigChanges = File.ReadAllText(QueryPath + "config/subscribeAutodiscoveryConfigChanges.graphql"); - getConfigSubscription = File.ReadAllText(QueryPath + "config/getConfigSubscription.graphql"); - subscribeDailyCheckConfigChanges = File.ReadAllText(QueryPath + "config/subscribeDailyCheckConfigChanges.graphql"); + getLanguages = GetQueryText("config/getLanguages.graphql"); + getAllTexts = GetQueryText("config/getTexts.graphql"); + getTextsPerLanguage = GetQueryText("config/getTextsPerLanguage.graphql"); + getCustomTextsPerLanguage = GetQueryText("config/getCustomTextsPerLanguage.graphql"); + upsertCustomText = GetQueryText("config/upsertCustomText.graphql"); + deleteCustomText = GetQueryText("config/deleteCustomText.graphql"); + subscribeConfigChangesByUser = GetQueryText("config/subscribeConfigChangesByUser.graphql"); + addConfigItem = GetQueryText("config/addConfigItem.graphql"); + updateConfigItem = GetQueryText("config/updateConfigItem.graphql"); + getConfigItemsByUser = GetQueryText("config/getConfigItemsByUser.graphql"); + getConfigItemByKey = GetQueryText("config/getConfigItemByKey.graphql"); + upsertConfigItem = GetQueryText("config/upsertConfigItem.graphql"); + upsertConfigItems = GetQueryText("config/upsertConfigItems.graphql"); + subscribeAutodiscoveryConfigChanges = GetQueryText("config/subscribeAutodiscoveryConfigChanges.graphql"); + subscribeExternalRequestConfigChanges = GetQueryText("config/subscribeExternalRequestConfigChanges.graphql"); + subscribeDailyCheckConfigChanges = GetQueryText("config/subscribeDailyCheckConfigChanges.graphql"); + subscribeImportAppDataConfigChanges = GetQueryText("config/subscribeImportAppDataConfigChanges.graphql"); + subscribeImportIpDataConfigChanges = GetQueryText("config/subscribeImportSubnetDataConfigChanges.graphql"); + subscribeImportNotifyConfigChanges = GetQueryText("config/subscribeImportNotifyConfigChanges.graphql"); + subscribeVarianceAnalysisConfigChanges = GetQueryText("config/subscribeVarianceAnalysisConfigChanges.graphql"); + subscribeComplianceCheckConfigChanges = GetQueryText("config/subscribeComplianceCheckConfigChanges.graphql"); + subscribeUpdateRuleOwnerMappingConfigChanges = GetQueryText("config/subscribeUpdateRuleOwnerMappingConfigChanges.graphql"); } catch (Exception exception) { Log.WriteError("Initialize ConfigQueries", "Api ConfigQueries could not be loaded.", exception); +#if RELEASE Environment.Exit(-1); +#else + throw; +#endif } } } diff --git a/roles/lib/files/FWO.Api.Client/Queries/DeviceQueries.cs b/roles/lib/files/FWO.Api.Client/Queries/DeviceQueries.cs index 5eafa3d520..3c143baa16 100644 --- a/roles/lib/files/FWO.Api.Client/Queries/DeviceQueries.cs +++ b/roles/lib/files/FWO.Api.Client/Queries/DeviceQueries.cs @@ -1,28 +1,29 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Threading.Tasks; -using System.IO; using FWO.Logging; namespace FWO.Api.Client.Queries { public class DeviceQueries : Queries { - public static readonly string getDevicesByManagements; + public static readonly string getDevicesByManagement; + public static readonly string getManagementNames; public static readonly string getManagementsDetails; public static readonly string getManagementDetailsWithoutSecrets; + public static readonly string getManagementsWithRulebases; public static readonly string getDeviceTypeDetails; public static readonly string newManagement; public static readonly string updateManagement; + public static readonly string updateManagementUid; + public static readonly string updateManagementUids; public static readonly string changeManagementState; public static readonly string deleteManagement; public static readonly string getDeviceDetails; + public static readonly string getDevicesWithRulebaseLinks; public static readonly string newDevice; + public static readonly string getGatewayId; public static readonly string updateDevice; + public static readonly string updateGatewayUid; public static readonly string changeDeviceState; public static readonly string deleteDevice; - public static readonly string deleteImport; public static readonly string getCredentials; public static readonly string getCredentialsWithoutSecrets; public static readonly string newCredential; @@ -34,44 +35,54 @@ static DeviceQueries() { try { - getDevicesByManagements = File.ReadAllText(QueryPath + "device/getDevicesByManagement.graphql"); - getManagementsDetails = File.ReadAllText(QueryPath + "device/getManagementsDetails.graphql") + " " - + File.ReadAllText(QueryPath + "device/fragments/managementDetails.graphql") + " " - + File.ReadAllText(QueryPath + "device/fragments/deviceTypeDetails.graphql") + " " - + File.ReadAllText(QueryPath + "device/fragments/importCredentials.graphql"); - getManagementDetailsWithoutSecrets = File.ReadAllText(QueryPath + "device/getManagementDetailsWithoutSecrets.graphql") + " " - + File.ReadAllText(QueryPath + "device/fragments/managementDetailsWithoutSecrets.graphql") + " " - + File.ReadAllText(QueryPath + "device/fragments/deviceTypeDetails.graphql") + " " - + File.ReadAllText(QueryPath + "device/fragments/importCredentialsWithoutSecrets.graphql"); - getDeviceTypeDetails = File.ReadAllText(QueryPath + "device/getDeviceTypeDetails.graphql") + " " - + File.ReadAllText(QueryPath + "device/fragments/deviceTypeDetails.graphql"); - newManagement = File.ReadAllText(QueryPath + "device/newManagement.graphql"); - updateManagement = File.ReadAllText(QueryPath + "device/updateManagement.graphql"); - changeManagementState = File.ReadAllText(QueryPath + "device/changeManagementState.graphql"); - deleteManagement = File.ReadAllText(QueryPath + "device/deleteManagement.graphql"); - getDeviceDetails = File.ReadAllText(QueryPath + "device/getDeviceDetails.graphql") + " " - + File.ReadAllText(QueryPath + "device/fragments/deviceDetails.graphql") + " " - + File.ReadAllText(QueryPath + "device/fragments/deviceTypeDetails.graphql"); + getDevicesByManagement = GetQueryText("device/getDevicesByManagement.graphql"); + getManagementNames = GetQueryText("device/getManagementNames.graphql"); + getManagementsDetails = GetQueryText("device/getManagementsDetails.graphql") + + GetQueryText("device/fragments/subManagements.graphql") + + GetQueryText("device/fragments/managementDetails.graphql") + + GetQueryText("device/fragments/deviceTypeDetails.graphql") + + GetQueryText("device/fragments/importCredentials.graphql"); + getManagementDetailsWithoutSecrets = GetQueryText("device/getManagementDetailsWithoutSecrets.graphql") + + GetQueryText("device/fragments/managementDetailsWithoutSecrets.graphql") + + GetQueryText("device/fragments/deviceTypeDetails.graphql") + + GetQueryText("device/fragments/importCredentialsWithoutSecrets.graphql"); + getManagementsWithRulebases = GetQueryText("device/getManagementsWithRulebases.graphql"); + getDeviceTypeDetails = GetQueryText("device/getDeviceTypeDetails.graphql") + + GetQueryText("device/fragments/deviceTypeDetails.graphql"); + newManagement = GetQueryText("device/newManagement.graphql"); + updateManagement = GetQueryText("device/updateManagement.graphql"); + updateManagementUid = GetQueryText("device/updateManagementUid.graphql"); + updateManagementUids = GetQueryText("device/updateManagementUids.graphql"); + changeManagementState = GetQueryText("device/changeManagementState.graphql"); + deleteManagement = GetQueryText("device/deleteManagement.graphql"); + getDeviceDetails = GetQueryText("device/getDeviceDetails.graphql") + + GetQueryText("device/fragments/deviceDetails.graphql") + + GetQueryText("device/fragments/deviceTypeDetails.graphql"); + getDevicesWithRulebaseLinks = GetQueryText("device/getDevicesWithRulebaseLinks.graphql"); + newDevice = GetQueryText("device/newDevice.graphql"); + updateDevice = GetQueryText("device/updateDevice.graphql"); + updateGatewayUid = GetQueryText("device/updateGatewayUid.graphql"); + getGatewayId = GetQueryText("device/getGatewayId.graphql"); + changeDeviceState = GetQueryText("device/changeDeviceState.graphql"); + deleteDevice = GetQueryText("device/deleteDevice.graphql"); - newDevice = File.ReadAllText(QueryPath + "device/newDevice.graphql"); - updateDevice = File.ReadAllText(QueryPath + "device/updateDevice.graphql"); - changeDeviceState = File.ReadAllText(QueryPath + "device/changeDeviceState.graphql"); - deleteDevice = File.ReadAllText(QueryPath + "device/deleteDevice.graphql"); - deleteImport = File.ReadAllText(QueryPath + "device/deleteImport.graphql"); - - getCredentials = File.ReadAllText(QueryPath + "device/getCredentials.graphql") + " " - + File.ReadAllText(QueryPath + "device/fragments/importCredentials.graphql"); - getCredentialsWithoutSecrets = File.ReadAllText(QueryPath + "device/getCredentialsWithoutSecrets.graphql") + " " - + File.ReadAllText(QueryPath + "device/fragments/importCredentialsWithoutSecrets.graphql"); - newCredential = File.ReadAllText(QueryPath + "device/newCredential.graphql"); - updateCredential = File.ReadAllText(QueryPath + "device/updateCredential.graphql"); - deleteCredential = File.ReadAllText(QueryPath + "device/deleteCredential.graphql"); - getMgmtNumberUsingCred = File.ReadAllText(QueryPath + "device/getMgmtNumberUsingCred.graphql"); + getCredentials = GetQueryText("device/getCredentials.graphql") + + GetQueryText("device/fragments/importCredentials.graphql"); + getCredentialsWithoutSecrets = GetQueryText("device/getCredentialsWithoutSecrets.graphql") + + GetQueryText("device/fragments/importCredentialsWithoutSecrets.graphql"); + newCredential = GetQueryText("device/newCredential.graphql"); + updateCredential = GetQueryText("device/updateCredential.graphql"); + deleteCredential = GetQueryText("device/deleteCredential.graphql"); + getMgmtNumberUsingCred = GetQueryText("device/getMgmtNumberUsingCred.graphql"); } catch (Exception exception) { Log.WriteError("Initialize DeviceQueries", "Api DeviceQueries could not be loaded.", exception); +#if RELEASE Environment.Exit(-1); +#else + throw; +#endif } } } diff --git a/roles/lib/files/FWO.Api.Client/Queries/ExtRequestQueries.cs b/roles/lib/files/FWO.Api.Client/Queries/ExtRequestQueries.cs new file mode 100644 index 0000000000..9d38d86b36 --- /dev/null +++ b/roles/lib/files/FWO.Api.Client/Queries/ExtRequestQueries.cs @@ -0,0 +1,57 @@ +using FWO.Logging; + +namespace FWO.Api.Client.Queries +{ + public class ExtRequestQueries : Queries + { + public static readonly string extRequestDetailsFragment; + + public static readonly string addTicketId; + public static readonly string getLatestTicketIds; + public static readonly string getLatestTicketId; + public static readonly string addExtRequest; + public static readonly string getOpenRequests; + public static readonly string getAndLockOpenRequests; + public static readonly string getLastRequest; + public static readonly string updateExtRequestCreation; + public static readonly string updateExtRequestProcess; + public static readonly string updateExtRequestFinal; + public static readonly string updateExternalRequestWaitCycles; + public static readonly string updateExternalRequestLock; + + public static readonly string subscribeExtRequestStateUpdate; + + + static ExtRequestQueries() + { + try + { + extRequestDetailsFragment = GetQueryText("extRequest/fragments/extRequestDetails.graphql"); + + addTicketId = GetQueryText("extRequest/addTicketId.graphql"); + getLatestTicketIds = GetQueryText("extRequest/getLatestTicketIds.graphql"); + getLatestTicketId = GetQueryText("extRequest/getLatestTicketId.graphql"); + addExtRequest = GetQueryText("extRequest/addExtRequest.graphql"); + getOpenRequests = extRequestDetailsFragment + GetQueryText("extRequest/getOpenRequests.graphql"); + getAndLockOpenRequests = extRequestDetailsFragment + GetQueryText("extRequest/getAndLockOpenRequests.graphql"); + getLastRequest = extRequestDetailsFragment + GetQueryText("extRequest/getLastRequest.graphql"); + updateExtRequestCreation = GetQueryText("extRequest/updateExtRequestCreation.graphql"); + updateExtRequestProcess = GetQueryText("extRequest/updateExtRequestProcess.graphql"); + updateExtRequestFinal = GetQueryText("extRequest/updateExtRequestFinal.graphql"); + updateExternalRequestWaitCycles = GetQueryText("extRequest/updateExternalRequestWaitCycles.graphql"); + updateExternalRequestLock = GetQueryText("extRequest/updateExternalRequestLock.graphql"); + + subscribeExtRequestStateUpdate = GetQueryText("extRequest/subscribeExtRequestStateUpdate.graphql"); + } + catch (Exception exception) + { + Log.WriteError("Initialize ExtRequestQueries", "Api ExtRequestQueries could not be loaded.", exception); +#if RELEASE + Environment.Exit(-1); +#else + throw; +#endif + } + } + } +} diff --git a/roles/lib/files/FWO.Api.Client/Queries/GraphQL b/roles/lib/files/FWO.Api.Client/Queries/GraphQL new file mode 120000 index 0000000000..65e2d6280a --- /dev/null +++ b/roles/lib/files/FWO.Api.Client/Queries/GraphQL @@ -0,0 +1 @@ +../../../../common/files/fwo-api-calls/ \ No newline at end of file diff --git a/roles/lib/files/FWO.Api.Client/Queries/ImportQueries.cs b/roles/lib/files/FWO.Api.Client/Queries/ImportQueries.cs new file mode 100644 index 0000000000..e6f330ccbe --- /dev/null +++ b/roles/lib/files/FWO.Api.Client/Queries/ImportQueries.cs @@ -0,0 +1,45 @@ +using FWO.Logging; + +namespace FWO.Api.Client.Queries +{ + public class ImportQueries : Queries + { + + public static readonly string deleteImport; + public static readonly string rollbackImport; + public static readonly string deleteLatestConfigOfManagement; + public static readonly string getLastImport; + public static readonly string getMaxImportId; + public static readonly string addImportForOwner; + public static readonly string addImportForRuleOwner; + public static readonly string updateImportControlForRuleOwnerFull; + public static readonly string updateImportControlForRuleOwnerInc; + public static readonly string getPendingRuleOwnerImports; + + static ImportQueries() + { + try + { + deleteImport = GetQueryText("import/deleteImport.graphql"); + rollbackImport = GetQueryText("import/rollbackImport.graphql"); + deleteLatestConfigOfManagement = GetQueryText("import/deleteLatestConfigOfManagement.graphql"); + getLastImport = GetQueryText("import/getLastImport.graphql"); + getMaxImportId = GetQueryText("import/getMaxImportId.graphql"); + addImportForOwner = GetQueryText("import/addImportForOwner.graphql"); + addImportForRuleOwner = GetQueryText("import/addImportForRuleOwner.graphql"); + updateImportControlForRuleOwnerFull = GetQueryText("import/updateImportControlForRuleOwnerFull.graphql"); + getPendingRuleOwnerImports = GetQueryText("import/getPendingRuleOwnerImports.graphql"); + updateImportControlForRuleOwnerInc = GetQueryText("import/updateImportControlForRuleOwnerInc.graphql"); + } + catch (Exception exception) + { + Log.WriteError("Initialize DeviceQueries", "Api DeviceQueries could not be loaded.", exception); +#if RELEASE + Environment.Exit(-1); +#else + throw; +#endif + } + } + } +} diff --git a/roles/lib/files/FWO.Api.Client/Queries/ModellingQueries.cs b/roles/lib/files/FWO.Api.Client/Queries/ModellingQueries.cs new file mode 100644 index 0000000000..1ce06037dd --- /dev/null +++ b/roles/lib/files/FWO.Api.Client/Queries/ModellingQueries.cs @@ -0,0 +1,247 @@ +using FWO.Logging; + +namespace FWO.Api.Client.Queries +{ + public class ModellingQueries : Queries + { + public static readonly string appServerDetailsFragment; + public static readonly string appRoleDetailsFragment; + public static readonly string areaDetailsFragment; + public static readonly string serviceDetailsFragment; + public static readonly string serviceGroupDetailsFragment; + public static readonly string connectionDetailsFragment; + public static readonly string connectionResolvedDetailsFragment; + + public static readonly string getAreas; + public static readonly string newArea; + public static readonly string setNwGroupDeletedState; + public static readonly string newAreaIpData; + public static readonly string getConnectionIdsForNwGroup; + + public static readonly string getAppServersByIp; + public static readonly string getAppServersByName; + public static readonly string getAppServersForOwner; + public static readonly string getAppServersBySource; + public static readonly string getAllAppServers; + public static readonly string newAppServer; + public static readonly string updateAppServer; + public static readonly string setAppServerDeletedState; + public static readonly string setAppServerType; + public static readonly string setAppServerName; + public static readonly string deleteAppServer; + public static readonly string getAppRolesForAppServer; + public static readonly string getConnectionIdsForAppServer; + + public static readonly string getPublishedInterfaces; + public static readonly string getRequestedInterfaces; + public static readonly string getConnectionById; + public static readonly string getConnections; + public static readonly string getConnectionsResolved; + public static readonly string getConnectionsByTicketId; + public static readonly string getDeletedConnections; + public static readonly string getInterfaceUsers; + public static readonly string getCommonServices; + public static readonly string newConnection; + public static readonly string updateConnection; + public static readonly string updateProposedConnectionOwner; + public static readonly string updateConnectionPublish; + public static readonly string updateConnectionProperties; + public static readonly string replaceUsedInterface; + public static readonly string updateConnectionFwRequested; + public static readonly string updateConnectionRemove; + public static readonly string updateConnectionDecommission; + public static readonly string deleteConnection; + public static readonly string addAppServerToConnection; + public static readonly string removeAppServerFromConnection; + public static readonly string removeAllAppServersFromConnection; + public static readonly string updateNwObjectInConnection; + public static readonly string addNwGroupToConnection; + public static readonly string removeNwGroupFromConnection; + public static readonly string removeAllNwGroupsFromConnection; + public static readonly string addServiceToConnection; + public static readonly string removeServiceFromConnection; + public static readonly string removeAllServicesFromConnection; + public static readonly string addServiceGroupToConnection; + public static readonly string removeServiceGroupFromConnection; + public static readonly string removeAllServiceGroupsFromConnection; + public static readonly string getConnectionIdsForService; + public static readonly string getConnectionIdsForServiceGroup; + public static readonly string getConnectionsForNwGroup; + + public static readonly string getSelectedConnections; + public static readonly string addSelectedConnection; + public static readonly string removeSelectedConnectionFromApp; + public static readonly string removeSelectedConnection; + public static readonly string addPermittedOwner; + public static readonly string deletePermittedOwner; + public static readonly string getPermittedOwnersForConnection; + + public static readonly string getNwGroupObjects; + public static readonly string getSelectedNwGroupObjects; + public static readonly string addSelectedNwGroupObject; + public static readonly string removeSelectedNwGroupObject; + public static readonly string removeSelectedNwGroupObjectFromAllApps; + + public static readonly string getAppRoles; + public static readonly string getNewestAppRoles; + public static readonly string getDummyAppRole; + public static readonly string newAppRole; + public static readonly string updateAppRole; + public static readonly string deleteNwGroup; + // public static readonly string getAppServerForAppRole; + public static readonly string addNwObjectToNwGroup; + public static readonly string removeNwObjectFromNwGroup; + public static readonly string updateNwObjectInNwGroup; + + public static readonly string getServicesForApp; + public static readonly string getGlobalServices; + public static readonly string newService; + public static readonly string updateService; + public static readonly string deleteService; + + public static readonly string getServiceGroupsForApp; + public static readonly string getServiceGroupById; + public static readonly string getGlobalServiceGroups; + public static readonly string newServiceGroup; + public static readonly string updateServiceGroup; + public static readonly string deleteServiceGroup; + public static readonly string addServiceToServiceGroup; + public static readonly string removeServiceFromServiceGroup; + public static readonly string getServiceGroupIdsForService; + + public static readonly string getHistory; + public static readonly string getHistoryForApp; + public static readonly string addHistoryEntry; + + public static readonly string newAppZone; + public static readonly string getAppZonesByAppId; + + static ModellingQueries() + { + try + { + appServerDetailsFragment = GetQueryText("modelling/fragments/appServerDetails.graphql"); + appRoleDetailsFragment = GetQueryText("modelling/fragments/appRoleDetails.graphql"); + areaDetailsFragment = GetQueryText("modelling/fragments/areaDetails.graphql"); + serviceDetailsFragment = GetQueryText("modelling/fragments/serviceDetails.graphql"); + serviceGroupDetailsFragment = GetQueryText("modelling/fragments/serviceGroupDetails.graphql"); + connectionDetailsFragment = appServerDetailsFragment + appRoleDetailsFragment + serviceDetailsFragment + serviceGroupDetailsFragment + + GetQueryText("modelling/fragments/connectionDetails.graphql"); + connectionResolvedDetailsFragment = appServerDetailsFragment + appRoleDetailsFragment + areaDetailsFragment + serviceDetailsFragment + serviceGroupDetailsFragment + + GetQueryText("modelling/fragments/connectionResolvedDetails.graphql"); + + getAreas = areaDetailsFragment + GetQueryText("modelling/getAreas.graphql"); + newArea = GetQueryText("modelling/newArea.graphql"); + setNwGroupDeletedState = GetQueryText("modelling/setNwGroupDeletedState.graphql"); + newAreaIpData = GetQueryText("modelling/newAreaIpData.graphql"); + getConnectionIdsForNwGroup = GetQueryText("modelling/getConnectionIdsForNwGroup.graphql"); + getConnectionsForNwGroup = connectionDetailsFragment + GetQueryText("modelling/getConnectionsForNwGroup.graphql"); + + getAppServersByIp = appServerDetailsFragment + GetQueryText("modelling/getAppServersByIp.graphql"); + getAppServersByName = appServerDetailsFragment + GetQueryText("modelling/getAppServersByName.graphql"); + getAppServersForOwner = appServerDetailsFragment + GetQueryText("modelling/getAppServersForOwner.graphql"); + getAppServersBySource = appServerDetailsFragment + GetQueryText("modelling/getAppServersBySource.graphql"); + getAllAppServers = appServerDetailsFragment + GetQueryText("modelling/getAllAppServers.graphql"); + newAppServer = GetQueryText("modelling/newAppServer.graphql"); + updateAppServer = GetQueryText("modelling/updateAppServer.graphql"); + setAppServerDeletedState = GetQueryText("modelling/setAppServerDeletedState.graphql"); + setAppServerName = GetQueryText("modelling/setAppServerName.graphql"); + setAppServerType = GetQueryText("modelling/setAppServerType.graphql"); + deleteAppServer = GetQueryText("modelling/deleteAppServer.graphql"); + getAppRolesForAppServer = GetQueryText("modelling/getAppRolesForAppServer.graphql"); + getConnectionIdsForAppServer = GetQueryText("modelling/getConnectionIdsForAppServer.graphql"); + + getPublishedInterfaces = connectionDetailsFragment + GetQueryText("modelling/getPublishedInterfaces.graphql"); + getRequestedInterfaces = connectionDetailsFragment + GetQueryText("modelling/getRequestedInterfaces.graphql"); + getConnectionById = connectionDetailsFragment + GetQueryText("modelling/getConnectionById.graphql"); + getConnections = connectionDetailsFragment + GetQueryText("modelling/getConnections.graphql"); + getConnectionsResolved = connectionResolvedDetailsFragment + GetQueryText("modelling/getConnectionsResolved.graphql"); + getConnectionsByTicketId = connectionDetailsFragment + GetQueryText("modelling/getConnectionsByTicketId.graphql"); + getDeletedConnections = connectionDetailsFragment + GetQueryText("modelling/getDeletedConnections.graphql"); + getInterfaceUsers = GetQueryText("modelling/getInterfaceUsers.graphql"); + getCommonServices = connectionDetailsFragment + GetQueryText("modelling/getCommonServices.graphql"); + newConnection = GetQueryText("modelling/newConnection.graphql"); + updateConnection = GetQueryText("modelling/updateConnection.graphql"); + updateProposedConnectionOwner = GetQueryText("modelling/updateProposedConnectionOwner.graphql"); + updateConnectionPublish = GetQueryText("modelling/updateConnectionPublish.graphql"); + updateConnectionProperties = GetQueryText("modelling/updateConnectionProperties.graphql"); + replaceUsedInterface = GetQueryText("modelling/replaceUsedInterface.graphql"); + updateConnectionFwRequested = GetQueryText("modelling/updateConnectionFwRequested.graphql"); + updateConnectionRemove = GetQueryText("modelling/updateConnectionRemove.graphql"); + deleteConnection = GetQueryText("modelling/deleteConnection.graphql"); + addAppServerToConnection = GetQueryText("modelling/addAppServerToConnection.graphql"); + removeAppServerFromConnection = GetQueryText("modelling/removeAppServerFromConnection.graphql"); + removeAllAppServersFromConnection = GetQueryText("modelling/removeAllAppServersFromConnection.graphql"); + updateNwObjectInConnection = GetQueryText("modelling/updateNwObjectInConnection.graphql"); + addNwGroupToConnection = GetQueryText("modelling/addNwGroupToConnection.graphql"); + removeNwGroupFromConnection = GetQueryText("modelling/removeNwGroupFromConnection.graphql"); + removeAllNwGroupsFromConnection = GetQueryText("modelling/removeAllNwGroupsFromConnection.graphql"); + addServiceToConnection = GetQueryText("modelling/addServiceToConnection.graphql"); + removeServiceFromConnection = GetQueryText("modelling/removeServiceFromConnection.graphql"); + removeAllServicesFromConnection = GetQueryText("modelling/removeAllServicesFromConnection.graphql"); + addServiceGroupToConnection = GetQueryText("modelling/addServiceGroupToConnection.graphql"); + removeServiceGroupFromConnection = GetQueryText("modelling/removeServiceGroupFromConnection.graphql"); + removeAllServiceGroupsFromConnection = GetQueryText("modelling/removeAllServiceGroupsFromConnection.graphql"); + getConnectionIdsForService = GetQueryText("modelling/getConnectionIdsForService.graphql"); + getConnectionIdsForServiceGroup = GetQueryText("modelling/getConnectionIdsForServiceGroup.graphql"); + updateConnectionDecommission = GetQueryText("modelling/updateConnectionDecommission.graphql"); + + getSelectedConnections = connectionDetailsFragment + GetQueryText("modelling/getSelectedConnections.graphql"); + addSelectedConnection = GetQueryText("modelling/addSelectedConnection.graphql"); + removeSelectedConnectionFromApp = GetQueryText("modelling/removeSelectedConnectionFromApp.graphql"); + removeSelectedConnection = GetQueryText("modelling/removeSelectedConnection.graphql"); + addPermittedOwner = GetQueryText("modelling/addPermittedOwner.graphql"); + deletePermittedOwner = GetQueryText("modelling/deletePermittedOwner.graphql"); + getPermittedOwnersForConnection = GetQueryText("modelling/getPermittedOwnersForConnection.graphql"); + + getNwGroupObjects = GetQueryText("modelling/getNwGroupObjects.graphql"); + getSelectedNwGroupObjects = GetQueryText("modelling/getSelectedNwGroupObjects.graphql"); + addSelectedNwGroupObject = GetQueryText("modelling/addSelectedNwGroupObject.graphql"); + removeSelectedNwGroupObject = GetQueryText("modelling/removeSelectedNwGroupObject.graphql"); + removeSelectedNwGroupObjectFromAllApps = GetQueryText("modelling/removeSelectedNwGroupObjectFromAllApps.graphql"); + + getAppRoles = appServerDetailsFragment + appRoleDetailsFragment + GetQueryText("modelling/getAppRoles.graphql"); + getNewestAppRoles = GetQueryText("modelling/getNewestAppRoles.graphql"); + getDummyAppRole = appServerDetailsFragment + appRoleDetailsFragment + GetQueryText("modelling/getDummyAppRole.graphql"); + newAppRole = GetQueryText("modelling/newAppRole.graphql"); + updateAppRole = GetQueryText("modelling/updateAppRole.graphql"); + deleteNwGroup = GetQueryText("modelling/deleteNwGroup.graphql"); + addNwObjectToNwGroup = GetQueryText("modelling/addNwObjectToNwGroup.graphql"); + removeNwObjectFromNwGroup = GetQueryText("modelling/removeNwObjectFromNwGroup.graphql"); + updateNwObjectInNwGroup = GetQueryText("modelling/updateNwObjectInNwGroup.graphql"); + + getServicesForApp = serviceDetailsFragment + GetQueryText("modelling/getServicesForApp.graphql"); + getGlobalServices = serviceDetailsFragment + GetQueryText("modelling/getGlobalServices.graphql"); + newService = GetQueryText("modelling/newService.graphql"); + updateService = GetQueryText("modelling/updateService.graphql"); + deleteService = GetQueryText("modelling/deleteService.graphql"); + + getServiceGroupsForApp = serviceDetailsFragment + serviceGroupDetailsFragment + GetQueryText("modelling/getServiceGroupsForApp.graphql"); + getServiceGroupById = serviceDetailsFragment + serviceGroupDetailsFragment + GetQueryText("modelling/getServiceGroupById.graphql"); + getGlobalServiceGroups = serviceDetailsFragment + serviceGroupDetailsFragment + GetQueryText("modelling/getGlobalServiceGroups.graphql"); + newServiceGroup = GetQueryText("modelling/newServiceGroup.graphql"); + updateServiceGroup = GetQueryText("modelling/updateServiceGroup.graphql"); + deleteServiceGroup = GetQueryText("modelling/deleteServiceGroup.graphql"); + addServiceToServiceGroup = GetQueryText("modelling/addServiceToServiceGroup.graphql"); + removeServiceFromServiceGroup = GetQueryText("modelling/removeServiceFromServiceGroup.graphql"); + getServiceGroupIdsForService = GetQueryText("modelling/getServiceGroupIdsForService.graphql"); + + getHistory = GetQueryText("modelling/getHistory.graphql"); + getHistoryForApp = GetQueryText("modelling/getHistoryForApp.graphql"); + addHistoryEntry = GetQueryText("modelling/addHistoryEntry.graphql"); + + newAppZone = GetQueryText("modelling/addNwAppZone.graphql"); + getAppZonesByAppId = appServerDetailsFragment + GetQueryText("modelling/getAppZonesByAppId.graphql"); + } + catch (Exception exception) + { + Log.WriteError("Initialize ModellingQueries", "Api ModellingQueries could not be loaded.", exception); +#if RELEASE + Environment.Exit(-1); +#else + throw; +#endif + } + } + } +} diff --git a/roles/lib/files/FWO.Api.Client/Queries/MonitorQueries.cs b/roles/lib/files/FWO.Api.Client/Queries/MonitorQueries.cs index debe8d00e9..a3d74c69ba 100644 --- a/roles/lib/files/FWO.Api.Client/Queries/MonitorQueries.cs +++ b/roles/lib/files/FWO.Api.Client/Queries/MonitorQueries.cs @@ -1,4 +1,4 @@ -using FWO.Logging; +using FWO.Logging; namespace FWO.Api.Client.Queries { @@ -15,43 +15,56 @@ public class MonitorQueries : Queries public static readonly string getAlerts; public static readonly string getAlertById; public static readonly string acknowledgeAlert; + public static readonly string acknowledgeAllOpenAlerts; public static readonly string subscribeAlertChanges; public static readonly string addAutodiscoveryLogEntry; public static readonly string getAutodiscoveryLogEntrys; public static readonly string getDailyCheckLogEntrys; + public static readonly string addDataImportLogEntry; + public static readonly string getDataImportLogEntrys; public static readonly string getImportStatus; + public static readonly string getOwnerTickets; static MonitorQueries() { try { - addLogEntry = File.ReadAllText(QueryPath + "monitor/addLogEntry.graphql"); - getLogEntrys = File.ReadAllText(QueryPath + "monitor/getLogEntrys.graphql"); + addLogEntry = GetQueryText("monitor/addLogEntry.graphql"); + getLogEntrys = GetQueryText("monitor/getLogEntrys.graphql"); - addUiLogEntry = File.ReadAllText(QueryPath + "monitor/addUiLogEntry.graphql"); - getUiLogEntrys = File.ReadAllText(QueryPath + "monitor/getUiLogEntrys.graphql"); - getAllUiLogEntrys = File.ReadAllText(QueryPath + "monitor/getAllUiLogEntrys.graphql"); + addUiLogEntry = GetQueryText("monitor/addUiLogEntry.graphql"); + getUiLogEntrys = GetQueryText("monitor/getUiLogEntrys.graphql"); + getAllUiLogEntrys = GetQueryText("monitor/getAllUiLogEntrys.graphql"); - getImportLogEntrys = File.ReadAllText(QueryPath + "monitor/getImportLogEntrys.graphql"); + getImportLogEntrys = GetQueryText("monitor/getImportLogEntrys.graphql"); - addAlert = File.ReadAllText(QueryPath + "monitor/addAlert.graphql"); - getOpenAlerts = File.ReadAllText(QueryPath + "monitor/getOpenAlerts.graphql"); - getAlerts = File.ReadAllText(QueryPath + "monitor/getAlerts.graphql"); - getAlertById = File.ReadAllText(QueryPath + "monitor/getAlertById.graphql"); - acknowledgeAlert = File.ReadAllText(QueryPath + "monitor/acknowledgeAlert.graphql"); - subscribeAlertChanges = File.ReadAllText(QueryPath + "monitor/subscribeAlertChanges.graphql"); + addAlert = GetQueryText("monitor/addAlert.graphql"); + getOpenAlerts = GetQueryText("monitor/getOpenAlerts.graphql"); + getAlerts = GetQueryText("monitor/getAlerts.graphql"); + getAlertById = GetQueryText("monitor/getAlertById.graphql"); + acknowledgeAlert = GetQueryText("monitor/acknowledgeAlert.graphql"); + acknowledgeAllOpenAlerts = GetQueryText("monitor/acknowledgeAllOpenAlerts.graphql"); + subscribeAlertChanges = GetQueryText("monitor/subscribeAlertChanges.graphql"); - getImportStatus = File.ReadAllText(QueryPath + "monitor/getImportStatus.graphql"); + getImportStatus = GetQueryText("monitor/getImportStatus.graphql"); - addAutodiscoveryLogEntry = File.ReadAllText(QueryPath + "monitor/addAutodiscoveryLogEntry.graphql"); - getAutodiscoveryLogEntrys = File.ReadAllText(QueryPath + "monitor/getAutodiscoveryLogEntrys.graphql"); - getDailyCheckLogEntrys = File.ReadAllText(QueryPath + "monitor/getDailyCheckLogEntrys.graphql"); + addAutodiscoveryLogEntry = GetQueryText("monitor/addAutodiscoveryLogEntry.graphql"); + getAutodiscoveryLogEntrys = GetQueryText("monitor/getAutodiscoveryLogEntrys.graphql"); + getDailyCheckLogEntrys = GetQueryText("monitor/getDailyCheckLogEntrys.graphql"); + addDataImportLogEntry = GetQueryText("monitor/addDataImportLogEntry.graphql"); + getDataImportLogEntrys = GetQueryText("monitor/getDataImportLogEntrys.graphql"); + + getOwnerTickets = RequestQueries.ticketOverviewFragment + GetQueryText("monitor/getOwnerTickets.graphql"); } catch (Exception exception) { Log.WriteError("Initialize MonitorQueries", "Api MonitorQueries could not be loaded.", exception); +#if RELEASE Environment.Exit(-1); +#else + throw; +#endif } } } diff --git a/roles/lib/files/FWO.Api.Client/Queries/NetworkAnalysisQueries.cs b/roles/lib/files/FWO.Api.Client/Queries/NetworkAnalysisQueries.cs index 2654c7822d..83e3534ba4 100644 --- a/roles/lib/files/FWO.Api.Client/Queries/NetworkAnalysisQueries.cs +++ b/roles/lib/files/FWO.Api.Client/Queries/NetworkAnalysisQueries.cs @@ -1,4 +1,4 @@ -using FWO.Logging; +using FWO.Logging; namespace FWO.Api.Client.Queries { @@ -6,18 +6,22 @@ public class NetworkAnalysisQueries : Queries { public static readonly string pathAnalysis; - static NetworkAnalysisQueries() + static NetworkAnalysisQueries() { try { pathAnalysis = - File.ReadAllText(QueryPath + "networking/analyzePath.graphql"); + GetQueryText("networking/analyzePath.graphql"); } catch (Exception exception) { - Log.WriteError("Initialize Api Queries", "Api Object Queries could not be loaded." , exception); + Log.WriteError("Initialize Api Queries", "Api Object Queries could not be loaded.", exception); +#if RELEASE Environment.Exit(-1); +#else + throw; +#endif } } } diff --git a/roles/lib/files/FWO.Api.Client/Queries/NotificationQueries.cs b/roles/lib/files/FWO.Api.Client/Queries/NotificationQueries.cs new file mode 100644 index 0000000000..2cfac0ee49 --- /dev/null +++ b/roles/lib/files/FWO.Api.Client/Queries/NotificationQueries.cs @@ -0,0 +1,36 @@ +using FWO.Logging; + +namespace FWO.Api.Client.Queries +{ + public class NotificationQueries : Queries + { + public static readonly string getNotifications; + public static readonly string addNotification; + public static readonly string updateNotification; + public static readonly string updateNotificationsLastSent; + + public static readonly string deleteNotification; + + + static NotificationQueries() + { + try + { + getNotifications = File.ReadAllText(QueryPath + "notification/getNotifications.graphql"); + addNotification = File.ReadAllText(QueryPath + "notification/addNotification.graphql"); + updateNotification = File.ReadAllText(QueryPath + "notification/updateNotification.graphql"); + updateNotificationsLastSent = File.ReadAllText(QueryPath + "notification/updateNotificationsLastSent.graphql"); + deleteNotification = File.ReadAllText(QueryPath + "notification/deleteNotification.graphql"); + } + catch (Exception exception) + { + Log.WriteError("Initialize NotificationQueries", "Api NotificationQueries could not be loaded.", exception); +#if RELEASE + Environment.Exit(-1); +#else + throw; +#endif + } + } + } +} diff --git a/roles/lib/files/FWO.Api.Client/Queries/ObjectQueries.cs b/roles/lib/files/FWO.Api.Client/Queries/ObjectQueries.cs index 77409e2d52..c857744825 100644 --- a/roles/lib/files/FWO.Api.Client/Queries/ObjectQueries.cs +++ b/roles/lib/files/FWO.Api.Client/Queries/ObjectQueries.cs @@ -1,75 +1,88 @@ -using FWO.Logging; +using FWO.Logging; namespace FWO.Api.Client.Queries { public class ObjectQueries : Queries { public static readonly string networkObjectDetailsFragment; + public static readonly string networkObjectDetailsForVarianceFragment; public static readonly string getNetworkObjectDetails; - public static readonly string networkServiceObjectDetailsFragment; - public static readonly string getNetworkServiceObjectDetails; + public static readonly string getNetworkObjectsForManagement; + public static readonly string networkServiceDetailsFragment; + public static readonly string getNetworkServiceDetails; public static readonly string userDetailsFragment; public static readonly string getUserDetails; public static readonly string getAllObjectDetails; public static readonly string getReportFilteredObjectDetails; public static readonly string getReportFilteredNetworkObjectDetails; - public static readonly string getReportFilteredNetworkServiceObjectDetails; + public static readonly string getReportFilteredNetworkServiceDetails; public static readonly string getReportFilteredUserDetails; - static ObjectQueries() + static ObjectQueries() { try { networkObjectDetailsFragment = - File.ReadAllText(QueryPath + "networkObject/fragments/networkObjectDetails.graphql"); + GetQueryText("networkObject/fragments/networkObjectDetails.graphql"); + + networkObjectDetailsForVarianceFragment = + GetQueryText("networkObject/fragments/networkObjectDetailsForVariance.graphql"); getNetworkObjectDetails = networkObjectDetailsFragment + - File.ReadAllText(QueryPath + "networkObject/getNetworkObjectDetails.graphql"); + GetQueryText("networkObject/getNetworkObjectDetails.graphql"); + + getNetworkObjectsForManagement = + networkObjectDetailsForVarianceFragment + + GetQueryText("networkObject/getNetworkObjectsForManagement.graphql"); - networkServiceObjectDetailsFragment = - File.ReadAllText(QueryPath + "networkService/fragments/networkServiceDetails.graphql"); + networkServiceDetailsFragment = + GetQueryText("networkService/fragments/networkServiceDetails.graphql"); - getNetworkServiceObjectDetails = - networkServiceObjectDetailsFragment + - File.ReadAllText(QueryPath + "networkService/getNetworkServiceDetails.graphql"); + getNetworkServiceDetails = + networkServiceDetailsFragment + + GetQueryText("networkService/getNetworkServiceDetails.graphql"); - userDetailsFragment = File.ReadAllText(QueryPath + "user/fragments/userDetails.graphql"); + userDetailsFragment = GetQueryText("user/fragments/userDetails.graphql"); getUserDetails = userDetailsFragment + - File.ReadAllText(QueryPath + "user/getUserDetails.graphql"); + GetQueryText("user/getUserDetails.graphql"); // used for right side bar objects getAllObjectDetails = userDetailsFragment + - networkServiceObjectDetailsFragment + + networkServiceDetailsFragment + networkObjectDetailsFragment + - File.ReadAllText(QueryPath + "allObjects/getAllObjectDetails.graphql"); + GetQueryText("allObjects/getAllObjectDetails.graphql"); // for rule export and RSB obj filtering per report - getReportFilteredObjectDetails = + getReportFilteredObjectDetails = userDetailsFragment + - networkServiceObjectDetailsFragment + + networkServiceDetailsFragment + networkObjectDetailsFragment + - File.ReadAllText(QueryPath + "report/getAllObjectDetailsInReport.graphql"); + GetQueryText("report/getReportFilteredObjectDetails.graphql"); getReportFilteredNetworkObjectDetails = networkObjectDetailsFragment + - File.ReadAllText(QueryPath + "report/getNetworkObjectDetailsInReport.graphql"); + GetQueryText("report/getReportFilteredNetworkObjectDetails.graphql"); - getReportFilteredNetworkServiceObjectDetails = - networkServiceObjectDetailsFragment + - File.ReadAllText(QueryPath + "report/getNetworkServiceDetailsInReport.graphql"); + getReportFilteredNetworkServiceDetails = + networkServiceDetailsFragment + + GetQueryText("report/getReportFilteredNetworkServiceDetails.graphql"); getReportFilteredUserDetails = userDetailsFragment + - File.ReadAllText(QueryPath + "report/getUserDetailsInReport.graphql"); + GetQueryText("report/getReportFilteredUserDetails.graphql"); } catch (Exception exception) { - Log.WriteError("Initialize Api Queries", "Api Object Queries could not be loaded." , exception); + Log.WriteError("Initialize Api Queries", "Api Object Queries could not be loaded.", exception); +#if RELEASE Environment.Exit(-1); +#else + throw; +#endif } } } diff --git a/roles/lib/files/FWO.Api.Client/Queries/OwnerQueries.cs b/roles/lib/files/FWO.Api.Client/Queries/OwnerQueries.cs index a8a4e13f66..8273cdf657 100644 --- a/roles/lib/files/FWO.Api.Client/Queries/OwnerQueries.cs +++ b/roles/lib/files/FWO.Api.Client/Queries/OwnerQueries.cs @@ -1,4 +1,4 @@ -using FWO.Logging; +using FWO.Logging; namespace FWO.Api.Client.Queries { @@ -6,41 +6,120 @@ public class OwnerQueries : Queries { public static readonly string ownerDetailsFragment; + public static readonly string getOwnerById; public static readonly string getOwners; + public static readonly string getOwnersWithNetworks; + public static readonly string getOwnersForRuleOwnerCustomField; + public static readonly string getOwnersForRuleOwnerIpBased; + public static readonly string getOwnersWithConn; + public static readonly string getEditableOwners; + public static readonly string getEditableOwnersWithConn; + public static readonly string getOwnersForDns; + public static readonly string getOwnersForResponsibleType; + public static readonly string getOwnersForDnsWithConn; + public static readonly string getOwnersForDnsWithModellingWithConn; public static readonly string newOwner; + public static readonly string newOwnerLifeCycle; public static readonly string updateOwner; + public static readonly string updateOwnerLifeCycle; + public static readonly string deactivateOwner; public static readonly string deleteOwner; + public static readonly string deleteOwnerLifeCycle; + public static readonly string getOwnerLifeCycleStates; // public static readonly string setDefaultOwner; public static readonly string setOwnerLastCheck; - public static readonly string getOwnerIdsFromGroups; - public static readonly string getOwnerIdsForUser; + public static readonly string setOwnerLastRecert; + public static readonly string getOwnersFromGroups; + public static readonly string getOwnersForUser; + public static readonly string getOwnersForDnsWithRecertification; + public static readonly string getOwnerResponsibleTypes; public static readonly string getNetworkOwnerships; public static readonly string newNetworkOwnership; - public static readonly string deleteNetworkOwnerships; + public static readonly string deleteNetworkOwnership; + public static readonly string deleteAreaIpData; + public static readonly string getRuleOwnerships; + public static readonly string newRuleOwnership; + public static readonly string deleteRuleOwnership; + public static readonly string getOwnerId; + public static readonly string newOwnerResponsibles; + public static readonly string deleteOwnerResponsibles; + public static readonly string deleteSpecificOwnerResponsibles; + public static readonly string setAllActiveRuleOwnersRemoved; + public static readonly string setAffectedRuleOwnersRemoved; + public static readonly string insertRuleOwners; + public static readonly string getRuleOwnerToRemoveByRule; + public static readonly string getRuleOwnerToRemoveByOwner; + public static readonly string newOwnerResponsibleType; + public static readonly string updateOwnerResponsibleType; + public static readonly string deleteOwnerResponsibleType; + public static readonly string updateChangelogOwner; + public static readonly string getChangedOwnersForRuleOwnerMappingCustomField; + public static readonly string getChangedOwnersForRuleOwnerMappingIpBased; static OwnerQueries() { try { - ownerDetailsFragment = File.ReadAllText(QueryPath + "owner/fragments/ownerDetails.graphql"); + ownerDetailsFragment = GetQueryText("owner/fragments/ownerDetails.graphql"); - getOwners = ownerDetailsFragment + File.ReadAllText(QueryPath + "owner/getOwners.graphql"); - newOwner = File.ReadAllText(QueryPath + "owner/newOwner.graphql"); - updateOwner = File.ReadAllText(QueryPath + "owner/updateOwner.graphql"); - deleteOwner = File.ReadAllText(QueryPath + "owner/deleteOwner.graphql"); - //setDefaultOwner = File.ReadAllText(QueryPath + "owner/setDefaultOwner.graphql"); - setOwnerLastCheck = File.ReadAllText(QueryPath + "owner/setOwnerLastCheck.graphql"); - getOwnerIdsFromGroups = ownerDetailsFragment + File.ReadAllText(QueryPath + "owner/getOwnerIdsFromGroups.graphql"); - getOwnerIdsForUser = ownerDetailsFragment + File.ReadAllText(QueryPath + "owner/getOwnerIdsForUser.graphql"); - getNetworkOwnerships = ownerDetailsFragment + File.ReadAllText(QueryPath + "owner/getNetworkOwnerships.graphql"); - newNetworkOwnership = ownerDetailsFragment + File.ReadAllText(QueryPath + "owner/newNetworkOwnership.graphql"); - deleteNetworkOwnerships = ownerDetailsFragment + File.ReadAllText(QueryPath + "owner/deleteNetworkOwnerships.graphql"); + getOwnerById = GetQueryText("owner/getOwnerById.graphql"); + getOwners = ownerDetailsFragment + GetQueryText("owner/getOwners.graphql"); + getOwnersWithNetworks = ownerDetailsFragment + GetQueryText("owner/getOwnersWithNetworks.graphql"); + getOwnersForRuleOwnerCustomField = GetQueryText("owner/getOwnersForRuleOwnerCustomField.graphql"); + getOwnersForRuleOwnerIpBased = GetQueryText("owner/getOwnersForRuleOwnerIpBased.graphql"); + getOwnersWithConn = ownerDetailsFragment + GetQueryText("owner/getOwnersWithConn.graphql"); + getEditableOwners = ownerDetailsFragment + GetQueryText("owner/getEditableOwners.graphql"); + getEditableOwnersWithConn = ownerDetailsFragment + GetQueryText("owner/getEditableOwnersWithConn.graphql"); + getOwnersForDns = ownerDetailsFragment + GetQueryText("owner/getOwnersForDns.graphql"); + getOwnersForResponsibleType = GetQueryText("owner/getOwnersForResponsibleType.graphql"); + getOwnersForDnsWithConn = ownerDetailsFragment + GetQueryText("owner/getOwnersForDnsWithConn.graphql"); + getOwnersForDnsWithModellingWithConn = ownerDetailsFragment + GetQueryText("owner/getOwnersForDnsWithModellingWithConn.graphql"); + newOwner = GetQueryText("owner/newOwner.graphql"); + newOwnerLifeCycle = GetQueryText("owner/newOwnerLifeCycle.graphql"); + updateOwner = GetQueryText("owner/updateOwner.graphql"); + updateOwnerLifeCycle = GetQueryText("owner/updateOwnerLifeCycle.graphql"); + deactivateOwner = GetQueryText("owner/deactivateOwner.graphql"); + deleteOwner = GetQueryText("owner/deleteOwner.graphql"); + deleteOwnerLifeCycle = GetQueryText("owner/deleteOwnerLifeCycle.graphql"); + getOwnerLifeCycleStates = GetQueryText("owner/getOwnerLifeCycleStates.graphql"); + setOwnerLastCheck = GetQueryText("owner/setOwnerLastCheck.graphql"); + setOwnerLastRecert = GetQueryText("owner/setOwnerLastRecert.graphql"); + getOwnersFromGroups = ownerDetailsFragment + GetQueryText("owner/getOwnersFromGroups.graphql"); + getOwnersForUser = ownerDetailsFragment + GetQueryText("owner/getOwnersForUser.graphql"); + getOwnersForDnsWithRecertification = ownerDetailsFragment + GetQueryText("owner/getOwnersForDnsWithRecertification.graphql"); + getOwnerResponsibleTypes = GetQueryText("owner/getOwnerResponsibleTypes.graphql"); + getNetworkOwnerships = ownerDetailsFragment + GetQueryText("owner/getNetworkOwnerships.graphql"); + newNetworkOwnership = ownerDetailsFragment + GetQueryText("owner/newNetworkOwnership.graphql"); + deleteNetworkOwnership = ownerDetailsFragment + GetQueryText("owner/deleteNetworkOwnership.graphql"); + deleteAreaIpData = GetQueryText("owner/deleteAreaIpData.graphql"); + getRuleOwnerships = GetQueryText("owner/getRuleOwnerships.graphql"); + newRuleOwnership = ownerDetailsFragment + GetQueryText("owner/newRuleOwnership.graphql"); + deleteRuleOwnership = ownerDetailsFragment + GetQueryText("owner/deleteRuleOwnership.graphql"); + getOwnerId = GetQueryText("owner/getOwnerId.graphql"); + newOwnerResponsibles = GetQueryText("owner/newOwnerResponsibles.graphql"); + deleteOwnerResponsibles = GetQueryText("owner/deleteOwnerResponsibles.graphql"); + deleteSpecificOwnerResponsibles = GetQueryText("owner/deleteSpecificOwnerResponsibles.graphql"); + setAllActiveRuleOwnersRemoved = GetQueryText("owner/setAllActiveRuleOwnersRemoved.graphql"); + setAffectedRuleOwnersRemoved = GetQueryText("owner/setAffectedRuleOwnersRemoved.graphql"); + insertRuleOwners = GetQueryText("owner/insertRuleOwners.graphql"); + getRuleOwnerToRemoveByRule = GetQueryText("owner/getRuleOwnerToRemoveByRule.graphql"); + newOwnerResponsibleType = GetQueryText("owner/newOwnerResponsibleType.graphql"); + updateOwnerResponsibleType = GetQueryText("owner/updateOwnerResponsibleType.graphql"); + deleteOwnerResponsibleType = GetQueryText("owner/deleteOwnerResponsibleType.graphql"); + updateChangelogOwner = GetQueryText("owner/updateChangelogOwner.graphql"); + getChangedOwnersForRuleOwnerMappingCustomField = GetQueryText("owner/getChangedOwnersForRuleOwnerMappingCustomField.graphql"); + getChangedOwnersForRuleOwnerMappingIpBased = GetQueryText("owner/getChangedOwnersForRuleOwnerMappingIpBased.graphql"); + getRuleOwnerToRemoveByOwner = GetQueryText("owner/getRuleOwnerToRemoveByOwner.graphql"); } catch (Exception exception) { Log.WriteError("Initialize OwnerQueries", "Api OwnerQueries could not be loaded.", exception); +#if RELEASE Environment.Exit(-1); +#else + throw; +#endif } } } diff --git a/roles/lib/files/FWO.Api.Client/Queries/Queries.cs b/roles/lib/files/FWO.Api.Client/Queries/Queries.cs index a935237d78..20e307aef6 100644 --- a/roles/lib/files/FWO.Api.Client/Queries/Queries.cs +++ b/roles/lib/files/FWO.Api.Client/Queries/Queries.cs @@ -1,23 +1,43 @@ -using System; -using System.Collections.Generic; -using System.IO; -using System.Linq; -using System.Threading.Tasks; -using FWO.Config; using System.Text.RegularExpressions; +using FWO.Basics; namespace FWO.Api.Client.Queries { public class Queries { - protected static readonly string QueryPath = AppDomain.CurrentDomain.BaseDirectory + "../../../../../../lib/files/FWO.Api.Client/APIcalls/"; - public static string compact(string raw_query) - { // return Regex.Replace(input, @"[^\w\.\*\-\:\?@/\(\)\[\]\{\}\$\+<>#\$ ]", "").Trim(); - raw_query = Regex.Replace(raw_query, @"\\t+", @"\s").Trim(); // replace tabs with a single space - raw_query = Regex.Replace(raw_query, @"\\s+", @"\s"); // replace multiple space chars by a single one - raw_query = Regex.Replace(raw_query, @"[\n]", ""); // remove EOL chars + protected static readonly string QueryPath = GlobalConst.kFwoBaseDir + "/fwo-api-calls/"; + + protected static string GetQueryText(string relativeQueryFileName) + { + return Compact(" " + File.ReadAllText(QueryPath + relativeQueryFileName) + " "); + } + public static string Compact(string raw_query) + { + // Split the input into lines + var lines = raw_query.Split(new[] { '\n' }, StringSplitOptions.None); + + // Remove comments and process each line + for (int i = 0; i < lines.Length; i++) + { + // Remove everything starting from '#' to the end of the line + lines[i] = Regex.Replace(lines[i], @"#.*", "", RegexOptions.None, TimeSpan.FromMilliseconds(100)).Trim(); + } + + // Rejoin the lines back into a single string + raw_query = string.Join("\n", lines); + + // Replace tabs with a single space + raw_query = Regex.Replace(raw_query, @"\t+", " ", RegexOptions.None, TimeSpan.FromMilliseconds(100)).Trim(); + + // Replace multiple spaces with a single space + raw_query = Regex.Replace(raw_query, @"\s+", " ", RegexOptions.None, TimeSpan.FromMilliseconds(100)); + + // Remove remaining newline characters (if needed) + raw_query = Regex.Replace(raw_query, @"[\n]", "", RegexOptions.None, TimeSpan.FromMilliseconds(100)); + return raw_query; } + } } diff --git a/roles/lib/files/FWO.Api.Client/Queries/RecertQueries.cs b/roles/lib/files/FWO.Api.Client/Queries/RecertQueries.cs index 99087179fb..907a19dc76 100644 --- a/roles/lib/files/FWO.Api.Client/Queries/RecertQueries.cs +++ b/roles/lib/files/FWO.Api.Client/Queries/RecertQueries.cs @@ -1,4 +1,4 @@ -using FWO.Logging; +using FWO.Logging; namespace FWO.Api.Client.Queries { @@ -9,10 +9,16 @@ public class RecertQueries : Queries public static readonly string prepareNextRecertification; public static readonly string recertify; + public static readonly string recertifyOwner; + public static readonly string recertifyRuleDirectly; public static readonly string getOpenRecertsForRule; - public static readonly string getOpenRecerts; + public static readonly string getOpenRecertsForOwners; public static readonly string clearOpenRecerts; public static readonly string addRecertEntries; + public static readonly string refreshViewRuleWithOwner; + public static readonly string getOwnerRecerts; + public static readonly string getInitialOwnerRecert; + public static readonly string updateRecertReportId; static RecertQueries() @@ -20,23 +26,33 @@ static RecertQueries() try { ruleOverviewFragments = - File.ReadAllText(QueryPath + "networkObject/fragments/networkObjectOverview.graphql") + - File.ReadAllText(QueryPath + "networkService/fragments/networkServiceOverview.graphql") + - File.ReadAllText(QueryPath + "user/fragments/userOverview.graphql") + - File.ReadAllText(QueryPath + "rule/fragments/ruleOverview.graphql"); - ruleOpenRecertFragments = ruleOverviewFragments + File.ReadAllText(QueryPath + "recertification/fragments/ruleOpenCertOverview.graphql"); - - prepareNextRecertification = File.ReadAllText(QueryPath + "recertification/prepareNextRecertification.graphql"); - recertify = File.ReadAllText(QueryPath + "recertification/recertify.graphql"); - getOpenRecertsForRule = File.ReadAllText(QueryPath + "recertification/getOpenRecertsForRule.graphql"); - getOpenRecerts = File.ReadAllText(QueryPath + "recertification/getOpenRecerts.graphql"); - clearOpenRecerts = File.ReadAllText(QueryPath + "recertification/clearOpenRecerts.graphql"); - addRecertEntries = File.ReadAllText(QueryPath + "recertification/addRecertEntries.graphql"); + GetQueryText("networkObject/fragments/networkObjectOverview.graphql") + + GetQueryText("networkService/fragments/networkServiceOverview.graphql") + + GetQueryText("user/fragments/userOverview.graphql") + + GetQueryText("rule/fragments/ruleOverview.graphql") + + GetQueryText("rule/fragments/rulebaseOverview.graphql"); + ruleOpenRecertFragments = ruleOverviewFragments + GetQueryText("recertification/fragments/ruleOpenCertOverview.graphql"); + prepareNextRecertification = GetQueryText("recertification/prepareNextRecertification.graphql"); + recertify = GetQueryText("recertification/recertify.graphql"); + recertifyOwner = GetQueryText("recertification/recertifyOwner.graphql"); + recertifyRuleDirectly = GetQueryText("recertification/recertifyRuleDirectly.graphql"); + getOpenRecertsForRule = GetQueryText("recertification/getOpenRecertsForRule.graphql"); + getOpenRecertsForOwners = GetQueryText("recertification/getOpenRecertsForOwners.graphql"); + clearOpenRecerts = GetQueryText("recertification/clearOpenRecerts.graphql"); + addRecertEntries = GetQueryText("recertification/addRecertEntries.graphql"); + refreshViewRuleWithOwner = GetQueryText("recertification/refreshViewRuleWithOwner.graphql"); + getOwnerRecerts = GetQueryText("recertification/getOwnerRecerts.graphql"); + getInitialOwnerRecert = GetQueryText("recertification/getInitialOwnerRecert.graphql"); + updateRecertReportId = GetQueryText("recertification/updateRecertReportId.graphql"); } catch (Exception exception) { Log.WriteError("Initialize Api Queries", "Api Recert Queries could not be loaded.", exception); +#if RELEASE Environment.Exit(-1); +#else + throw; +#endif } } } diff --git a/roles/lib/files/FWO.Api.Client/Queries/ReportQueries.cs b/roles/lib/files/FWO.Api.Client/Queries/ReportQueries.cs index c222c39860..90f0b57f5c 100644 --- a/roles/lib/files/FWO.Api.Client/Queries/ReportQueries.cs +++ b/roles/lib/files/FWO.Api.Client/Queries/ReportQueries.cs @@ -1,8 +1,3 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Threading.Tasks; -using System.IO; using FWO.Logging; namespace FWO.Api.Client.Queries @@ -11,7 +6,7 @@ public class ReportQueries : Queries { public static readonly string getReportTemplates; public static readonly string addReportTemplate; - public static readonly string editReportTemplate; + public static readonly string updateReportTemplate; public static readonly string deleteReportTemplate; public static readonly string subscribeReportScheduleChanges; @@ -26,6 +21,7 @@ public class ReportQueries : Queries public static readonly string getReportsById; public static readonly string getRelevantImportIdsAtTime; + public static readonly string getRelevantImportIdsInTimeRange; public static readonly string statisticsReportCurrent; public static readonly string subscribeGeneratedReportsChanges; @@ -35,38 +31,55 @@ public class ReportQueries : Queries public static readonly string addGeneratedReport; public static readonly string getUsageDataCount; + public static readonly string getImportsToNotify; + public static readonly string getImportsToNotifyForAnyChanges; + public static readonly string setImportsNotified; - static ReportQueries() + public static readonly string getManagementForNormalizedConfig; + public static readonly string getManagementForLatestNormalizedConfig; + + static ReportQueries() { try { - addReportTemplate = File.ReadAllText(QueryPath + "report/addReportTemplate.graphql"); - addReportSchedule = File.ReadAllText(QueryPath + "report/addReportSchedule.graphql"); - addReportScheduleFileFormats = File.ReadAllText(QueryPath + "report/addReportScheduleFileFormats.graphql"); - editReportSchedule = File.ReadAllText(QueryPath + "report/editReportSchedule.graphql"); - deleteReportSchedule = File.ReadAllText(QueryPath + "report/deleteReportSchedule.graphql"); - getReportSchedules = File.ReadAllText(QueryPath + "report/getReportSchedules.graphql"); - countReportSchedule = File.ReadAllText(QueryPath + "report/countReportSchedule.graphql"); - getReportsOverview = File.ReadAllText(QueryPath + "report/getReportsOverview.graphql"); - getReportsById = File.ReadAllText(QueryPath + "report/getReportById.graphql"); - getReportTemplates = File.ReadAllText(QueryPath + "report/getReportTemplates.graphql"); - getRelevantImportIdsAtTime = File.ReadAllText(QueryPath + "report/getRelevantImportIdsAtTime.graphql"); - statisticsReportCurrent = File.ReadAllText(QueryPath + "report/statisticsCurrent.graphql"); - statisticsReportCurrent = File.ReadAllText(QueryPath + "report/statisticsCurrentOverall.graphql"); - editReportTemplate = File.ReadAllText(QueryPath + "report/editReportTemplate.graphql"); - deleteReportTemplate = File.ReadAllText(QueryPath + "report/deleteReportTemplate.graphql"); - subscribeReportScheduleChanges = File.ReadAllText(QueryPath + "report/subscribeReportScheduleChanges.graphql"); - subscribeGeneratedReportsChanges = File.ReadAllText(QueryPath + "report/subscribeGeneratedReportsChanges.graphql"); - getGeneratedReports = File.ReadAllText(QueryPath + "report/getGeneratedReports.graphql"); - getGeneratedReport = File.ReadAllText(QueryPath + "report/getGeneratedReport.graphql"); - deleteGeneratedReport = File.ReadAllText(QueryPath + "report/deleteGeneratedReport.graphql"); - addGeneratedReport = File.ReadAllText(QueryPath + "report/addGeneratedReport.graphql"); - getUsageDataCount = File.ReadAllText(QueryPath + "report/getUsageDataCount.graphql"); + addReportTemplate = GetQueryText("report/addReportTemplate.graphql"); + addReportSchedule = GetQueryText("report/addReportSchedule.graphql"); + addReportScheduleFileFormats = GetQueryText("report/addReportScheduleFileFormats.graphql"); + editReportSchedule = GetQueryText("report/editReportSchedule.graphql"); + deleteReportSchedule = GetQueryText("report/deleteReportSchedule.graphql"); + getReportSchedules = GetQueryText("report/getReportSchedules.graphql"); + countReportSchedule = GetQueryText("report/countReportSchedule.graphql"); + getReportsOverview = GetQueryText("report/getReportsOverview.graphql"); + getReportsById = GetQueryText("report/getReportById.graphql"); + getReportTemplates = GetQueryText("report/getReportTemplates.graphql"); + getRelevantImportIdsAtTime = GetQueryText("report/getRelevantImportIdsAtTime.graphql"); + getRelevantImportIdsInTimeRange = GetQueryText("report/getRelevantImportIdsInTimeRange.graphql"); + statisticsReportCurrent = GetQueryText("report/statisticsCurrent.graphql"); + statisticsReportCurrent = GetQueryText("report/statisticsCurrentOverall.graphql"); + updateReportTemplate = GetQueryText("report/updateReportTemplate.graphql"); + deleteReportTemplate = GetQueryText("report/deleteReportTemplate.graphql"); + subscribeReportScheduleChanges = GetQueryText("report/subscribeReportScheduleChanges.graphql"); + subscribeGeneratedReportsChanges = GetQueryText("report/subscribeGeneratedReportsChanges.graphql"); + getGeneratedReports = GetQueryText("report/getGeneratedReports.graphql"); + getGeneratedReport = GetQueryText("report/getGeneratedReport.graphql"); + deleteGeneratedReport = GetQueryText("report/deleteGeneratedReport.graphql"); + addGeneratedReport = GetQueryText("report/addGeneratedReport.graphql"); + getUsageDataCount = GetQueryText("report/getUsageDataCount.graphql"); + // note: currently we only check for rule changes, but this should be extended to other changes in the future + getImportsToNotify = GetQueryText("report/getImportsToNotifyForRuleChanges.graphql"); + getImportsToNotifyForAnyChanges = GetQueryText("report/getImportsToNotifyForAnyChanges.graphql"); + setImportsNotified = GetQueryText("report/setImportsNotified.graphql"); + getManagementForNormalizedConfig = GetQueryText("report/getManagementForNormalizedConfig.graphql"); + getManagementForLatestNormalizedConfig = GetQueryText("report/getManagementForLatestNormalizedConfig.graphql"); } catch (Exception exception) { - Log.WriteError("Initialize Api Queries", "Api ReportQueries could not be loaded." , exception); + Log.WriteError("Initialize Api Queries", "Api ReportQueries could not be loaded.", exception); +#if RELEASE Environment.Exit(-1); +#else + throw; +#endif } } } diff --git a/roles/lib/files/FWO.Api.Client/Queries/RequestQueries.cs b/roles/lib/files/FWO.Api.Client/Queries/RequestQueries.cs index d4baa41fa8..277b8ee6ce 100644 --- a/roles/lib/files/FWO.Api.Client/Queries/RequestQueries.cs +++ b/roles/lib/files/FWO.Api.Client/Queries/RequestQueries.cs @@ -1,4 +1,4 @@ -using FWO.Logging; +using FWO.Logging; namespace FWO.Api.Client.Queries { @@ -7,15 +7,27 @@ public class RequestQueries : Queries public static readonly string commentDetailsFragment; public static readonly string implTaskDetailsFragment; public static readonly string reqTaskDetailsFragment; + public static readonly string reqElementDetailsFragment; public static readonly string ticketDetailsFragment; + public static readonly string reqTaskOverviewFragment; + public static readonly string ticketOverviewFragment; + public static readonly string ticketDetailsReqTaskOverviewFragment; + public static readonly string getTickets; + public static readonly string getFullTickets; + public static readonly string getOwnerTicketIds; public static readonly string getTicketById; + public static readonly string getTicketsByParameters; + public static readonly string getRequestTasksByIds; public static readonly string newTicket; public static readonly string updateTicket; public static readonly string updateTicketState; + public static readonly string subscribeTicketStateChanges; + public static readonly string subscribeTaskChanges; public static readonly string newRequestTask; public static readonly string updateRequestTask; public static readonly string updateRequestTaskState; + public static readonly string updateRequestTaskAdditionalInfo; public static readonly string deleteRequestTask; public static readonly string newRequestElement; public static readonly string updateRequestElement; @@ -32,6 +44,9 @@ public class RequestQueries : Queries public static readonly string getStates; public static readonly string upsertState; public static readonly string deleteState; + public static readonly string getExtStates; + public static readonly string addExtState; + public static readonly string removeExtState; public static readonly string getActions; public static readonly string newAction; public static readonly string updateAction; @@ -43,57 +58,79 @@ public class RequestQueries : Queries public static readonly string addCommentToImplTask; public static readonly string addCommentToTicket; public static readonly string addCommentToApproval; + public static readonly string addOwnerToReqTask; + public static readonly string removeOwnerFromReqTask; static RequestQueries() { try { - commentDetailsFragment = File.ReadAllText(QueryPath + "request/fragments/commentDetails.graphql"); - implTaskDetailsFragment = commentDetailsFragment + File.ReadAllText(QueryPath + "request/fragments/implTaskDetails.graphql"); - reqTaskDetailsFragment = OwnerQueries.ownerDetailsFragment + implTaskDetailsFragment + File.ReadAllText(QueryPath + "request/fragments/reqTaskDetails.graphql"); - ticketDetailsFragment = reqTaskDetailsFragment + File.ReadAllText(QueryPath + "request/fragments/ticketDetails.graphql"); + commentDetailsFragment = GetQueryText("request/fragments/commentDetails.graphql"); + implTaskDetailsFragment = commentDetailsFragment + GetQueryText("request/fragments/implTaskDetails.graphql"); + reqElementDetailsFragment = GetQueryText("request/fragments/reqElementDetails.graphql"); + reqTaskDetailsFragment = OwnerQueries.ownerDetailsFragment + reqElementDetailsFragment + implTaskDetailsFragment + GetQueryText("request/fragments/reqTaskDetails.graphql"); + ticketDetailsFragment = reqTaskDetailsFragment + GetQueryText("request/fragments/ticketDetails.graphql"); + reqTaskOverviewFragment = OwnerQueries.ownerDetailsFragment + GetQueryText("request/fragments/reqTaskOverview.graphql"); + ticketOverviewFragment = reqTaskOverviewFragment + GetQueryText("request/fragments/ticketOverview.graphql"); + ticketDetailsReqTaskOverviewFragment = commentDetailsFragment + reqTaskOverviewFragment + GetQueryText("request/fragments/ticketDetailsReqTaskOverview.graphql"); - getTickets = ticketDetailsFragment + File.ReadAllText(QueryPath + "request/getTickets.graphql"); - getTicketById = ticketDetailsFragment + File.ReadAllText(QueryPath + "request/getTicketById.graphql"); - newTicket = File.ReadAllText(QueryPath + "request/newTicket.graphql"); - updateTicket = File.ReadAllText(QueryPath + "request/updateTicket.graphql"); - updateTicketState = File.ReadAllText(QueryPath + "request/updateTicketState.graphql"); - newRequestTask = File.ReadAllText(QueryPath + "request/newRequestTask.graphql"); - updateRequestTask = File.ReadAllText(QueryPath + "request/updateRequestTask.graphql"); - updateRequestTaskState = File.ReadAllText(QueryPath + "request/updateRequestTaskState.graphql"); - deleteRequestTask = File.ReadAllText(QueryPath + "request/deleteRequestTask.graphql"); - newRequestElement = File.ReadAllText(QueryPath + "request/newRequestElement.graphql"); - updateRequestElement = File.ReadAllText(QueryPath + "request/updateRequestElement.graphql"); - deleteRequestElement = File.ReadAllText(QueryPath + "request/deleteRequestElement.graphql"); - newImplementationTask = File.ReadAllText(QueryPath + "request/newImplementationTask.graphql"); - updateImplementationTask = File.ReadAllText(QueryPath + "request/updateImplementationTask.graphql"); - updateImplementationTaskState = File.ReadAllText(QueryPath + "request/updateImplementationTaskState.graphql"); - deleteImplementationTask = File.ReadAllText(QueryPath + "request/deleteImplementationTask.graphql"); - newImplementationElement = File.ReadAllText(QueryPath + "request/newImplementationElement.graphql"); - updateImplementationElement = File.ReadAllText(QueryPath + "request/updateImplementationElement.graphql"); - deleteImplementationElement = File.ReadAllText(QueryPath + "request/deleteImplementationElement.graphql"); - newApproval = File.ReadAllText(QueryPath + "request/newApproval.graphql"); - updateApproval = File.ReadAllText(QueryPath + "request/updateApproval.graphql"); - getStates = File.ReadAllText(QueryPath + "request/getStates.graphql"); - upsertState = File.ReadAllText(QueryPath + "request/upsertState.graphql"); - deleteState = File.ReadAllText(QueryPath + "request/deleteState.graphql"); - getActions = File.ReadAllText(QueryPath + "request/getActions.graphql"); - newAction = File.ReadAllText(QueryPath + "request/newAction.graphql"); - updateAction = File.ReadAllText(QueryPath + "request/updateAction.graphql"); - deleteAction = File.ReadAllText(QueryPath + "request/deleteAction.graphql"); - addStateAction = File.ReadAllText(QueryPath + "request/addStateAction.graphql"); - removeStateAction = File.ReadAllText(QueryPath + "request/removeStateAction.graphql"); - newComment = File.ReadAllText(QueryPath + "request/newComment.graphql"); - addCommentToReqTask = File.ReadAllText(QueryPath + "request/addCommentToReqTask.graphql"); - addCommentToImplTask = File.ReadAllText(QueryPath + "request/addCommentToImplTask.graphql"); - addCommentToTicket = File.ReadAllText(QueryPath + "request/addCommentToTicket.graphql"); - addCommentToApproval = File.ReadAllText(QueryPath + "request/addCommentToApproval.graphql"); + getTickets = ticketDetailsReqTaskOverviewFragment + GetQueryText("request/getTickets.graphql"); + getFullTickets = ticketDetailsFragment + GetQueryText("request/getFullTickets.graphql"); + getOwnerTicketIds = GetQueryText("monitor/getOwnerTicketIds.graphql"); + getTicketsByParameters = ticketDetailsReqTaskOverviewFragment + GetQueryText("request/getTicketsByParameters.graphql"); + getRequestTasksByIds = reqTaskDetailsFragment + GetQueryText("request/getRequestTasksByIds.graphql"); + getTicketById = ticketDetailsFragment + GetQueryText("request/getTicketById.graphql"); + newTicket = GetQueryText("request/newTicket.graphql"); + updateTicket = GetQueryText("request/updateTicket.graphql"); + updateTicketState = GetQueryText("request/updateTicketState.graphql"); + subscribeTicketStateChanges = GetQueryText("request/subscribeTicketStateChanges.graphql"); + subscribeTaskChanges = reqElementDetailsFragment + GetQueryText("request/subscribeTaskChanges.graphql"); + newRequestTask = GetQueryText("request/newRequestTask.graphql"); + updateRequestTask = GetQueryText("request/updateRequestTask.graphql"); + updateRequestTaskState = GetQueryText("request/updateRequestTaskState.graphql"); + updateRequestTaskAdditionalInfo = GetQueryText("request/updateRequestTaskAdditionalInfo.graphql"); + deleteRequestTask = GetQueryText("request/deleteRequestTask.graphql"); + newRequestElement = GetQueryText("request/newRequestElement.graphql"); + updateRequestElement = GetQueryText("request/updateRequestElement.graphql"); + deleteRequestElement = GetQueryText("request/deleteRequestElement.graphql"); + newImplementationTask = GetQueryText("request/newImplementationTask.graphql"); + updateImplementationTask = GetQueryText("request/updateImplementationTask.graphql"); + updateImplementationTaskState = GetQueryText("request/updateImplementationTaskState.graphql"); + deleteImplementationTask = GetQueryText("request/deleteImplementationTask.graphql"); + newImplementationElement = GetQueryText("request/newImplementationElement.graphql"); + updateImplementationElement = GetQueryText("request/updateImplementationElement.graphql"); + deleteImplementationElement = GetQueryText("request/deleteImplementationElement.graphql"); + newApproval = GetQueryText("request/newApproval.graphql"); + updateApproval = GetQueryText("request/updateApproval.graphql"); + getStates = GetQueryText("request/getStates.graphql"); + upsertState = GetQueryText("request/upsertState.graphql"); + deleteState = GetQueryText("request/deleteState.graphql"); + getExtStates = GetQueryText("request/getExtStates.graphql"); + addExtState = GetQueryText("request/addExtState.graphql"); + removeExtState = GetQueryText("request/removeExtState.graphql"); + getActions = GetQueryText("request/getActions.graphql"); + newAction = GetQueryText("request/newAction.graphql"); + updateAction = GetQueryText("request/updateAction.graphql"); + deleteAction = GetQueryText("request/deleteAction.graphql"); + addStateAction = GetQueryText("request/addStateAction.graphql"); + removeStateAction = GetQueryText("request/removeStateAction.graphql"); + newComment = GetQueryText("request/newComment.graphql"); + addCommentToReqTask = GetQueryText("request/addCommentToReqTask.graphql"); + addCommentToImplTask = GetQueryText("request/addCommentToImplTask.graphql"); + addCommentToTicket = GetQueryText("request/addCommentToTicket.graphql"); + addCommentToApproval = GetQueryText("request/addCommentToApproval.graphql"); + addOwnerToReqTask = GetQueryText("request/addOwnerToReqTask.graphql"); + removeOwnerFromReqTask = GetQueryText("request/removeOwnerFromReqTask.graphql"); } catch (Exception exception) { Log.WriteError("Initialize RequestQueries", "Api RequestQueries could not be loaded.", exception); +#if RELEASE Environment.Exit(-1); +#else + throw; +#endif } } } diff --git a/roles/lib/files/FWO.Api.Client/Queries/RuleQueries.cs b/roles/lib/files/FWO.Api.Client/Queries/RuleQueries.cs index 2276668ed6..1e0c26950e 100644 --- a/roles/lib/files/FWO.Api.Client/Queries/RuleQueries.cs +++ b/roles/lib/files/FWO.Api.Client/Queries/RuleQueries.cs @@ -1,95 +1,144 @@ -using FWO.Logging; +using FWO.Logging; namespace FWO.Api.Client.Queries { public class RuleQueries : Queries { public static readonly string ruleOverviewFragments; + public static readonly string ruleOverviewForChangeReportFragments; public static readonly string ruleDetailsFragments; public static readonly string ruleDetailsForReportFragments; + public static readonly string ruleDetailsForAppRuleReportFragments; + public static readonly string ruleDetailsForChangeReportFragments; + public static readonly string natRuleOverviewFragments; + public static readonly string natRuleDetailsFragments; + public static readonly string natRuleDetailsForReportFragments; + public static readonly string getRuleOverview; public static readonly string getRuleDetails; - public static readonly string getRuleDetailsForReport; + // public static readonly string getRuleDetailsForReport; public static readonly string getRuleByUid; public static readonly string getRuleNetworkObjectDetails; public static readonly string getRuleIdsOfImport; - - public static readonly string natRuleOverviewFragments; - public static readonly string natRuleDetailsFragments; - public static readonly string natRuleDetailsForReportFragments; + public static readonly string getRuleUidsOfDevice; + public static readonly string getRuleUidsOfRulebase; + public static readonly string getRulesByManagement; + public static readonly string getModelledRulesByManagementName; + public static readonly string getModelledRulesByManagementComment; public static readonly string getNatRuleOverview; public static readonly string getNatRuleDetails; - public static readonly string getNatRuleDetailsForReport; + // public static readonly string getNatRuleDetailsForReport; + + public static readonly string countRules; + public static readonly string countActiveRules; + public static readonly string getRulesWithViolationsInTimespanByChunk; + public static readonly string getRulesWithCurrentViolationsByChunk; + public static readonly string getRulesForSelectedManagements; + public static readonly string getRulesForOwnerMappingCustomField; + public static readonly string getRulesForOwnerMappingIpBased; + public static readonly string getChangedRulesForRuleOwnerMappingCustomField; + public static readonly string getChangedRulesForRuleOwnerMappingIpBased; + public static readonly string getRulesForRuleOwnerCustomField; + public static readonly string getRulesForRuleOwnerIpBased; + public static readonly string getRulesForRuleOwnerByOwnerToUpdateCustomField; + public static readonly string getRuleDetailsById; + public static readonly string getTimeBasedRulesByOwner; + public static readonly string getRuleIdsByRuleOwner; + public static readonly string getActiveRulesByOwner; + + - static RuleQueries() { try { ruleOverviewFragments = - File.ReadAllText(QueryPath + "networkObject/fragments/networkObjectOverview.graphql") + - File.ReadAllText(QueryPath + "networkService/fragments/networkServiceOverview.graphql") + - File.ReadAllText(QueryPath + "user/fragments/userOverview.graphql") + - File.ReadAllText(QueryPath + "rule/fragments/ruleOverview.graphql"); - - getRuleOverview = ruleOverviewFragments + File.ReadAllText(QueryPath + "rule/getRuleOverview.graphql"); - + GetQueryText("networkObject/fragments/networkObjectOverview.graphql") + + GetQueryText("networkService/fragments/networkServiceOverview.graphql") + + GetQueryText("user/fragments/userOverview.graphql") + + GetQueryText("rule/fragments/ruleOverview.graphql"); + ruleOverviewForChangeReportFragments = + GetQueryText("networkObject/fragments/networkObjectOverview.graphql") + + GetQueryText("networkService/fragments/networkServiceOverview.graphql") + + GetQueryText("user/fragments/userOverview.graphql") + + GetQueryText("rule/fragments/ruleOverviewChangesOld.graphql") + + GetQueryText("rule/fragments/ruleOverviewChangesNew.graphql") + + GetQueryText("networkObject/fragments/networkObjectDetailsChangesOld.graphql") + + GetQueryText("networkObject/fragments/networkObjectDetailsChangesNew.graphql") + + GetQueryText("networkService/fragments/networkServiceDetailsChangesOld.graphql") + + GetQueryText("networkService/fragments/networkServiceDetailsChangesNew.graphql") + + GetQueryText("user/fragments/userDetailsChangesOld.graphql") + + GetQueryText("user/fragments/userDetailsChangesNew.graphql"); ruleDetailsFragments = - ObjectQueries.networkObjectDetailsFragment + - ObjectQueries.networkServiceObjectDetailsFragment + - ObjectQueries.userDetailsFragment + - File.ReadAllText(QueryPath + "rule/fragments/ruleDetails.graphql"); - + ObjectQueries.networkObjectDetailsFragment + + ObjectQueries.networkServiceDetailsFragment + + ObjectQueries.userDetailsFragment + + GetQueryText("rule/fragments/ruleDetails.graphql"); ruleDetailsForReportFragments = ObjectQueries.networkObjectDetailsFragment + - ObjectQueries.networkServiceObjectDetailsFragment + + ObjectQueries.networkServiceDetailsFragment + ObjectQueries.userDetailsFragment + - File.ReadAllText(QueryPath + "rule/fragments/ruleDetailsForReport.graphql"); - - getRuleDetails = - ruleDetailsFragments + - File.ReadAllText(QueryPath + "rule/getRuleDetails.graphql"); - - getRuleDetailsForReport = - ruleDetailsForReportFragments + - File.ReadAllText(QueryPath + "rule/getRuleDetails.graphql"); - - getRuleByUid = File.ReadAllText(QueryPath + "rule/getRuleByUid.graphql"); - - getRuleNetworkObjectDetails = - ObjectQueries.networkObjectDetailsFragment; - - getRuleIdsOfImport = - File.ReadAllText(QueryPath + "report/getRuleIdsOfImport.graphql"); - - natRuleOverviewFragments = ruleOverviewFragments + - File.ReadAllText(QueryPath + "rule/fragments/natRuleOverview.graphql"); - - getNatRuleOverview = natRuleOverviewFragments + File.ReadAllText(QueryPath + "rule/getNatRuleOverview.graphql"); - - natRuleDetailsFragments = - ruleDetailsFragments + - File.ReadAllText(QueryPath + "rule/fragments/natRuleDetails.graphql"); - + GetQueryText("rule/fragments/ruleDetailsForReport.graphql"); + ruleDetailsForAppRuleReportFragments = + GetQueryText("networkObject/fragments/networkObjectDetailsForAppRules.graphql") + + GetQueryText("networkService/fragments/networkServiceOverview.graphql") + + GetQueryText("user/fragments/userOverview.graphql") + + GetQueryText("rule/fragments/ruleDetailsForAppRuleReport.graphql"); + natRuleOverviewFragments = ruleOverviewFragments + GetQueryText("rule/fragments/natRuleOverview.graphql"); + natRuleDetailsFragments = ruleDetailsFragments + GetQueryText("rule/fragments/natRuleDetails.graphql"); natRuleDetailsForReportFragments = ObjectQueries.networkObjectDetailsFragment + - ObjectQueries.networkServiceObjectDetailsFragment + + ObjectQueries.networkServiceDetailsFragment + ObjectQueries.userDetailsFragment + - File.ReadAllText(QueryPath + "rule/fragments/natRuleDetailsForReport.graphql"); - - getNatRuleDetails = - natRuleDetailsFragments + - File.ReadAllText(QueryPath + "rule/getNatRuleDetails.graphql"); - - getNatRuleDetailsForReport = - natRuleDetailsForReportFragments + - File.ReadAllText(QueryPath + "rule/getNatRuleDetails.graphql"); - + GetQueryText("rule/fragments/natRuleDetailsForReport.graphql"); + ruleDetailsForChangeReportFragments = + GetQueryText("networkObject/fragments/networkObjectOverview.graphql") + + GetQueryText("networkObject/fragments/networkObjectDetailsChangesOld.graphql") + + GetQueryText("networkObject/fragments/networkObjectDetailsChangesNew.graphql") + + GetQueryText("networkService/fragments/networkServiceDetailsChangesOld.graphql") + + GetQueryText("networkService/fragments/networkServiceDetailsChangesNew.graphql") + + GetQueryText("user/fragments/userDetailsChangesOld.graphql") + + GetQueryText("user/fragments/userDetailsChangesNew.graphql") + + GetQueryText("rule/fragments/ruleDetailsChangesOld.graphql") + + GetQueryText("rule/fragments/ruleDetailsChangesNew.graphql"); + + getRuleOverview = ruleOverviewFragments + GetQueryText("rule/getRuleOverview.graphql"); + getRuleDetails = ruleDetailsFragments + GetQueryText("rule/getRuleDetails.graphql"); + getRuleByUid = GetQueryText("rule/getRuleByUid.graphql"); + getRuleNetworkObjectDetails = ObjectQueries.networkObjectDetailsFragment; + getRuleIdsOfImport = GetQueryText("rule/getRuleIdsOfImport.graphql"); + getRuleUidsOfDevice = GetQueryText("rule/getRuleUidsOfDevice.graphql"); + getRuleUidsOfRulebase = GetQueryText("rule/getRuleUidsOfRulebase.graphql"); + getRulesByManagement = ruleDetailsFragments + GetQueryText("rule/getRulesByManagement.graphql"); + getModelledRulesByManagementName = ruleDetailsForReportFragments + GetQueryText("report/getModelledRulesByManagementName.graphql"); + getModelledRulesByManagementComment = ruleDetailsForReportFragments + GetQueryText("report/getModelledRulesByManagementComment.graphql"); + getNatRuleOverview = natRuleOverviewFragments + GetQueryText("rule/getNatRuleOverview.graphql"); + getNatRuleDetails = natRuleDetailsFragments + GetQueryText("rule/getNatRuleDetails.graphql"); + getRulesWithViolationsInTimespanByChunk = ruleDetailsFragments + GetQueryText("rule/getRulesWithViolationsInTimespanByChunk.graphql"); + getRulesWithCurrentViolationsByChunk = ruleDetailsFragments + GetQueryText("rule/getRulesWithCurrentViolationsByChunk.graphql"); + getRulesForSelectedManagements = ruleDetailsFragments + GetQueryText("rule/getRulesForSelectedManagements.graphql"); + countRules = GetQueryText("rule/countRules.graphql"); + countActiveRules = GetQueryText("rule/countActiveRules.graphql"); + getRulesForOwnerMappingCustomField = GetQueryText("rule/getRulesForOwnerMappingCustomField.graphql"); + getRulesForOwnerMappingIpBased = GetQueryText("rule/getRulesForOwnerMappingIpBased.graphql"); + getChangedRulesForRuleOwnerMappingCustomField = GetQueryText("rule/getChangedRulesForRuleOwnerMappingCustomField.graphql"); + getChangedRulesForRuleOwnerMappingIpBased = GetQueryText("rule/getChangedRulesForRuleOwnerMappingIpBased.graphql"); + getRulesForRuleOwnerCustomField = GetQueryText("rule/getRulesForRuleOwnerCustomField.graphql"); + getRulesForRuleOwnerIpBased = GetQueryText("rule/getRulesForRuleOwnerIpBased.graphql"); + getRulesForRuleOwnerByOwnerToUpdateCustomField = GetQueryText("rule/getRulesForRuleOwnerByOwnerToUpdateCustomField.graphql"); + getRuleDetailsById = GetQueryText("rule/getRuleDetailByID.graphql"); + getTimeBasedRulesByOwner = GetQueryText("rule/getTimeBasedRulesByOwner.graphql"); + getRuleIdsByRuleOwner = GetQueryText("rule/getRuleIdsByRuleOwner.graphql"); + getActiveRulesByOwner = GetQueryText("rule/getActiveRulesByOwner.graphql"); } catch (Exception exception) { Log.WriteError("Initialize Api Queries", "Api Rule Queries could not be loaded.", exception); +#if RELEASE Environment.Exit(-1); +#else + throw; +#endif } } } diff --git a/roles/lib/files/FWO.Api.Client/Queries/StmQueries.cs b/roles/lib/files/FWO.Api.Client/Queries/StmQueries.cs index fc93625e4d..ecef8e7991 100644 --- a/roles/lib/files/FWO.Api.Client/Queries/StmQueries.cs +++ b/roles/lib/files/FWO.Api.Client/Queries/StmQueries.cs @@ -1,4 +1,4 @@ -using FWO.Logging; +using FWO.Logging; namespace FWO.Api.Client.Queries { @@ -8,19 +8,22 @@ public class StmQueries : Queries public static readonly string getRuleActions; public static readonly string getTracking; - static StmQueries() { try { - getIpProtocols = File.ReadAllText(QueryPath + "stmTables/getIpProtocols.graphql"); - getRuleActions = File.ReadAllText(QueryPath + "stmTables/getRuleActions.graphql"); - getTracking = File.ReadAllText(QueryPath + "stmTables/getTracking.graphql"); + getIpProtocols = GetQueryText("stmTables/getIpProtocols.graphql"); + getRuleActions = GetQueryText("stmTables/getRuleActions.graphql"); + getTracking = GetQueryText("stmTables/getTracking.graphql"); } catch (Exception exception) { Log.WriteError("Initialize StmQueries", "Api StmQueries could not be loaded.", exception); +#if RELEASE Environment.Exit(-1); +#else + throw; +#endif } } } diff --git a/roles/lib/files/FWO.Api.Client/RestApiClient.cs b/roles/lib/files/FWO.Api.Client/RestApiClient.cs new file mode 100644 index 0000000000..730e7270a7 --- /dev/null +++ b/roles/lib/files/FWO.Api.Client/RestApiClient.cs @@ -0,0 +1,48 @@ +using RestSharp; +using RestSharp.Authenticators; +using RestSharp.Serializers; +using RestSharp.Serializers.NewtonsoftJson; +using System.Net.Security; + +namespace FWO.Api.Client +{ + public abstract class RestApiClient + { + protected RestClient restClient; + readonly string BaseUrl; + readonly TimeSpan? ResponseTimeout; + readonly bool CheckCertificates; + + protected RestApiClient(string baseUrl, double? timeout = null, bool checkCertificates = false) + { + BaseUrl = baseUrl; + ResponseTimeout = timeout != null ? TimeSpan.FromSeconds((double)timeout) : null; + CheckCertificates = checkCertificates; + restClient = CreateRestClient(authenticator: null); + } + + public void SetAuthenticationToken(string jwt) + { + restClient = CreateRestClient(new JwtAuthenticator(jwt)); + } + + private RestClient CreateRestClient(IAuthenticator? authenticator) + { + RestClientOptions restClientOptions = new() { Timeout = ResponseTimeout }; + restClientOptions.RemoteCertificateValidationCallback += (requestMessage, cert, chain, sslErrors) => + { + // Todo: further customization? + return !CheckCertificates || sslErrors == SslPolicyErrors.None; + }; + restClientOptions.BaseUrl = new Uri(BaseUrl); + restClientOptions.Authenticator = authenticator; + return new RestClient(restClientOptions, null, ConfigureRestClientSerialization); + } + + private static void ConfigureRestClientSerialization(SerializerConfig config) + { + JsonNetSerializer serializer = new(); // Case insensivitive is enabled by default + config.UseSerializer(() => serializer); + } + } +} diff --git a/roles/lib/files/FWO.Basics/BooleanExtensions.cs b/roles/lib/files/FWO.Basics/BooleanExtensions.cs new file mode 100644 index 0000000000..94f5dd3b40 --- /dev/null +++ b/roles/lib/files/FWO.Basics/BooleanExtensions.cs @@ -0,0 +1,28 @@ +using Microsoft.AspNetCore.Components; + +namespace FWO.Basics +{ + public static class BooleanExtensions + { + public static MarkupString ShowAsHtml(this bool boolVal) + { + return ShowAsHtml(boolVal, withColors: false); + } + + public static MarkupString ShowAsHtml(this bool boolVal, bool withColors) + { + // shows check (true) or x (false) in UI + string colorClass = ""; + if (withColors) + { + colorClass = boolVal ? "text-success" : "text-danger"; + } + var htmlString = boolVal + ? $"" + : $""; + return new MarkupString(htmlString); + } + } + +} + diff --git a/roles/lib/files/FWO.Basics/Comparer/ComplianceViolationComparer.cs b/roles/lib/files/FWO.Basics/Comparer/ComplianceViolationComparer.cs new file mode 100644 index 0000000000..4c2eb676f9 --- /dev/null +++ b/roles/lib/files/FWO.Basics/Comparer/ComplianceViolationComparer.cs @@ -0,0 +1,23 @@ +using FWO.Basics.Interfaces; + +namespace FWO.Basics.Comparer +{ + public class ComplianceViolationComparer : IEqualityComparer + { + public bool Equals(IComplianceViolation? x, IComplianceViolation? y) + { + if (ReferenceEquals(x, y)) return true; + if (x is null || y is null) return false; + + return x.RuleId == y.RuleId && + x.PolicyId == y.PolicyId && + x.CriterionId == y.CriterionId && + x.Details == y.Details; + } + + public int GetHashCode(IComplianceViolation obj) + { + return HashCode.Combine(obj.RuleId, obj.PolicyId, obj.CriterionId, obj.Details); + } + } +} diff --git a/roles/lib/files/FWO.Basics/Comparer/IPAddressComparer.cs b/roles/lib/files/FWO.Basics/Comparer/IPAddressComparer.cs new file mode 100644 index 0000000000..89c13386fd --- /dev/null +++ b/roles/lib/files/FWO.Basics/Comparer/IPAddressComparer.cs @@ -0,0 +1,26 @@ +using System.Net; +using NetTools; +using FWO.Basics; + +namespace FWO.Basics.Comparer +{ + public class IPAdressComparer : IComparer + { + public int Compare(IPAddress? x, IPAddress? y) + { + if (x is null || y is null) + { + return 0; + } + + int compareIPFamiliesResult = IpOperations.CompareIpFamilies(x, y); + + if (compareIPFamiliesResult != 0) + { + return compareIPFamiliesResult; + } + + return IpOperations.CompareIpValues(x, y); + } + } +} diff --git a/roles/lib/files/FWO.Basics/Comparer/IPAddressRangeComparer.cs b/roles/lib/files/FWO.Basics/Comparer/IPAddressRangeComparer.cs new file mode 100644 index 0000000000..08fe255201 --- /dev/null +++ b/roles/lib/files/FWO.Basics/Comparer/IPAddressRangeComparer.cs @@ -0,0 +1,54 @@ +using System.Numerics; +using NetTools; + +namespace FWO.Basics.Comparer +{ + public class IPAddressRangeComparer : IComparer + { + public int Compare(IPAddressRange? x, IPAddressRange? y) + { + if (x is null || y is null) + { + return 0; + } + + IPAdressComparer iPAdressComparer = new(); + int compareIPAddressResult = iPAdressComparer.Compare(x.Begin, y.Begin); + + if (compareIPAddressResult != 0) + { + return compareIPAddressResult; + } + + BigInteger xRangeSize = GetIPRangeSize(x); + BigInteger yRangeSize = GetIPRangeSize(y); + + if (xRangeSize < yRangeSize) + { + return -1; + } + + if (xRangeSize > yRangeSize) + { + return 1; + } + + return 0; + } + + public BigInteger GetIPRangeSize(IPAddressRange range) + { + byte[] startBytes = range.Begin.GetAddressBytes(); + byte[] endBytes = range.End.GetAddressBytes(); + + // prevents overflow problem + byte[] startBytesPadded = startBytes.Reverse().Concat(new byte[] { 0 }).ToArray(); + byte[] endBytesPadded = endBytes.Reverse().Concat(new byte[] { 0 }).ToArray(); + + BigInteger startValue = new BigInteger(startBytesPadded); + BigInteger endValue = new BigInteger(endBytesPadded); + + return endValue - startValue; + } + } +} diff --git a/roles/lib/files/FWO.Basics/DailyCheckModule.cs b/roles/lib/files/FWO.Basics/DailyCheckModule.cs new file mode 100644 index 0000000000..bc19a9ff02 --- /dev/null +++ b/roles/lib/files/FWO.Basics/DailyCheckModule.cs @@ -0,0 +1,21 @@ +namespace FWO.Basics +{ + public enum DailyCheckModule + { + DemoData = 1, + Imports = 2, + RecertRefresh = 3, + RecertCheck = 4, + UnansweredInterfaceRequests = 5, + RuleExpiryCheck = 6, + OwnerActiveRules = 7 + } + + public static class DailyCheckModuleGroups + { + public static string AllModulesNumList() + { + return $"[{string.Join(",", Enum.GetValues(typeof(DailyCheckModule)).Cast().Select(m => (int)m).ToList())}]"; + } + } +} diff --git a/roles/lib/files/FWO.Basics/Enums/AssessabilityIssue.cs b/roles/lib/files/FWO.Basics/Enums/AssessabilityIssue.cs new file mode 100644 index 0000000000..7c5207fcd3 --- /dev/null +++ b/roles/lib/files/FWO.Basics/Enums/AssessabilityIssue.cs @@ -0,0 +1,10 @@ +namespace FWO.Basics.Enums +{ + public enum AssessabilityIssue + { + IPNull, + AllIPs, + HostAddress, + Broadcast + } +} diff --git a/roles/lib/files/FWO.Basics/Exceptions/ConfigException.cs b/roles/lib/files/FWO.Basics/Exceptions/ConfigException.cs new file mode 100644 index 0000000000..cfb2440cd2 --- /dev/null +++ b/roles/lib/files/FWO.Basics/Exceptions/ConfigException.cs @@ -0,0 +1,8 @@ +namespace FWO.Basics.Exceptions +{ + public class ConfigException : Exception + { + public ConfigException(string message) : base(message) { } + public ConfigException(string message, Exception innerException) : base(message, innerException) { } + } +} diff --git a/roles/lib/files/FWO.Basics/Exceptions/EnvironmentException.cs b/roles/lib/files/FWO.Basics/Exceptions/EnvironmentException.cs new file mode 100644 index 0000000000..c4713bc5ce --- /dev/null +++ b/roles/lib/files/FWO.Basics/Exceptions/EnvironmentException.cs @@ -0,0 +1,8 @@ +namespace FWO.Basics.Exceptions +{ + public class EnvironmentException : Exception + { + public EnvironmentException(string message) : base(message) { } + public EnvironmentException(string message, Exception innerException) : base(message, innerException) { } + } +} diff --git a/roles/lib/files/FWO.Basics/Exceptions/InternalException.cs b/roles/lib/files/FWO.Basics/Exceptions/InternalException.cs new file mode 100644 index 0000000000..16ea3dcd60 --- /dev/null +++ b/roles/lib/files/FWO.Basics/Exceptions/InternalException.cs @@ -0,0 +1,8 @@ +namespace FWO.Basics.Exceptions +{ + public class InternalException : Exception + { + public InternalException(string message) : base(message) { } + public InternalException(string message, Exception innerException) : base(message, innerException) { } + } +} diff --git a/roles/lib/files/FWO.Basics/Exceptions/LdapConnectionException.cs b/roles/lib/files/FWO.Basics/Exceptions/LdapConnectionException.cs new file mode 100644 index 0000000000..3fc8e7e66c --- /dev/null +++ b/roles/lib/files/FWO.Basics/Exceptions/LdapConnectionException.cs @@ -0,0 +1,8 @@ +namespace FWO.Basics.Exceptions +{ + public class LdapConnectionException : Exception + { + public LdapConnectionException(string message) : base(message) { } + public LdapConnectionException(string message, Exception innerException) : base(message, innerException) { } + } +} diff --git a/roles/lib/files/FWO.Basics/Exceptions/ProcessingFailedException.cs b/roles/lib/files/FWO.Basics/Exceptions/ProcessingFailedException.cs new file mode 100644 index 0000000000..55e93ef639 --- /dev/null +++ b/roles/lib/files/FWO.Basics/Exceptions/ProcessingFailedException.cs @@ -0,0 +1,8 @@ +namespace FWO.Basics.Exceptions +{ + public class ProcessingFailedException : Exception + { + public ProcessingFailedException(string message) : base(message) { } + public ProcessingFailedException(string message, Exception innerException) : base(message, innerException) { } + } +} diff --git a/roles/lib/files/FWO.Basics/FWO.Basics.csproj b/roles/lib/files/FWO.Basics/FWO.Basics.csproj new file mode 100644 index 0000000000..5b32b1ec4b --- /dev/null +++ b/roles/lib/files/FWO.Basics/FWO.Basics.csproj @@ -0,0 +1,19 @@ + + + + net10.0 + enable + enable + + + + + + + + + + + + + diff --git a/roles/lib/files/FWO.Basics/GlobalConstants.cs b/roles/lib/files/FWO.Basics/GlobalConstants.cs new file mode 100644 index 0000000000..f8d29251a7 --- /dev/null +++ b/roles/lib/files/FWO.Basics/GlobalConstants.cs @@ -0,0 +1,211 @@ +namespace FWO.Basics +{ + /// + /// Global string constants used e.g. as database keys etc. + /// + public struct GlobalConst + { + public const string kFwoProdName = "fworch"; + public const string kFwoBaseDir = "/usr/local/" + kFwoProdName; + public const string kMainKeyFile = kFwoBaseDir + "/etc/secrets/main_key"; + + public const string kEnglish = "English"; + public const int kTenant0Id = 1; + + public const int kSessionExpirationTimeDefault = 720; // 60 * 12 + + public const int kSidebarLeftWidth = 300; + public const int kGlobLibraryWidth = kSidebarLeftWidth + 400; + public const int kObjLibraryWidth = kSidebarLeftWidth + 300; + public const int kSidebarRightWidth = 300; + public const int kDaysToMilliseconds = 86400000; + public const int kHoursToMilliseconds = 3600000; + public const int kMinutesToMilliseconds = 60000; + public const int kSecondsToMilliseconds = 1000; + public const int kDaysPerWeek = 7; + public const int kMaxPortNumber = 65535; + public const int kOwnerResponsibleTypeMain = 1; + public const int kOwnerResponsibleTypeSupporting = 2; + public const int kOwnerResponsibleTypeOptionalEscalation = 3; + + public const string kHtml = "html"; + public const string kPdf = "pdf"; + public const string kJson = "json"; + public const string kCsv = "csv"; + + public const string kAutodiscovery = "autodiscovery"; + public const string kDailyCheck = "dailycheck"; + public const string kUi = "ui"; + public const string kCertification = "Certification"; + public const string kImportAppData = "importAppData"; + public const string kAdjustAppServerNames = "adjustAppServerNames"; + public const string kImportAreaSubnetData = "importAreaSubnetData"; + public const string kImportZoneMatrixData = "importZoneMatrixData"; + public const string kVarianceAnalysis = "varianceAnalysis"; + public const string kManual = "manual"; + public const string kCSV_ = "CSV_"; + public const string kDoku_ = "Doku_"; + public const string k_user = "_user"; + public const string k_user2 = "-user"; + public const string kUpdatable = "updatable"; + public const string kNAT = "NAT"; + public const string k_demo = "_demo"; + public const string kClosed = "closed"; + + public const string kPlaceholderMarker = "@@"; + public const string kModellerGroup = "ModellerGroup_"; + public const string kImportChangeNotify = "importChangeNotify"; + public const string kExternalRequest = "externalRequest"; + public const string kComplianceCheck = "complianceCheck"; + public const string kLdapInternalPostfix = "dc=" + kFwoProdName + ",dc=internal"; + public const int kLdapInternalId = 1; + public const string kDummyAppRole = "DummyAppRole"; + public const string kUndefinedText = "(undefined text)"; + + public const string kStyleHighlightedRed = "color: red;"; + public const string kStyleHighlightedGreen = "color: green;"; + public const string kStyleDeleted = "color: red; text-decoration: line-through red;"; + public const string kStyleAdded = "color: green; text-decoration: bold;"; + + public const string ChromeBinPathLinux = "/usr/local/fworch/bin"; + public const string TestPDFFilePath = "pdffile.pdf"; + public const string TestPDFHtmlTemplate = "

                      test

                      test mit puppteer

                      "; + + public const int MaxUploadFileSize = 5 * 1024 * 1024; // 5 MB + + // qad: these two strings should be replaced by customer specific setting values asap + public const string kField2 = "field-2"; + public const string kDatumRegelpr = "Datum-Regelpruefung"; + } + + public struct PageName + { + public const string ReportGeneration = "report/generation"; + public const string Certification = "certification"; + public const string Modelling = "networkmodelling"; + } + + public struct ObjectType + { + public const string Group = "group"; + public const string Host = "host"; + public const string Network = "network"; + public const string IPRange = "ip_range"; + public const string AccessRole = "access-role"; + } + + public struct ServiceType + { + public const string Group = "group"; + public const string SimpleService = "simple"; + public const string Rpc = "rpc"; + } + + public struct MarkerLocation + { + public const string Rulename = "rulename"; + public const string Comment = "comment"; + public const string Customfields = "customfields"; + } + + public struct QueryVar + { + public const string Limit = "limit"; + public const string Offset = "offset"; + public const string Time = "time"; + public const string ImportIdStart = "import_id_start"; + public const string ImportIdEnd = "import_id_end"; + public const string ImportIdOld = "import_id_old"; + public const string ImportIdNew = "import_id_new"; + public const string IncludeObjectsInChangesReport = "include_objects_in_changes_report"; + public const string MgmIds = "mgmIds"; + public const string MgmId = "mgmId"; + public const string ManagementId = "management_id"; + public const string RuleIds = "ruleIds"; + public const string RuleId = "rule_id"; + } + + public struct Placeholder + { + public const string APPNAME = "@@APPNAME@@"; + public const string APPID = "@@APPID@@"; + + public const string ACTION = "@@ACTION@@"; + public const string CHANGEACTION = "@@CHANGEACTION@@"; + public const string COMMENT = "@@COMMENT@@"; + public const string CONN_NUMBER = "@@CONN_NUMBER@@"; + public const string DAYS = "@@DAYS@@"; + public const string DESTINATIONS = "@@DESTINATIONS@@"; + public const string FAIL_NUMBER = "@@FAIL_NUMBER@@"; + public const string GROUPNAME = "@@GROUPNAME@@"; + public const string INTERFACE_LINK = "@@INTERFACE_LINK@@"; + public const string INTERFACE_NAME = "@@INTERFACE_NAME@@"; + public const string IP = "@@IP@@"; + public const string MANAGEMENT_ID = "@@MANAGEMENT_ID@@"; + public const string MANAGEMENT_NAME = "@@MANAGEMENT_NAME@@"; + public const string MEMBERS = "@@MEMBERS@@"; + public const string NEW_INTERFACE_LINK = "@@NEW_INTERFACE_LINK@@"; + public const string NEW_INTERFACE_NAME = "@@NEW_INTERFACE_NAME@@"; + public const string OBJECT_DETAILS = "@@OBJECT_DETAILS@@"; + public const string OBJECTNAME = "@@OBJECTNAME@@"; + public const string OBJECT_TYPE = "@@OBJECT_TYPE@@"; + public const string OBJUPDSTATUS = "@@OBJUPDSTATUS@@"; + public const string OK_NUMBER = "@@OK_NUMBER@@"; + public const string ONBEHALF = "@@ONBEHALF@@"; + public const string ORDERNAME = "@@ORDERNAME@@"; + public const string PORT = "@@PORT@@"; + public const string PRIORITY = "@@PRIORITY@@"; + public const string PROTOCOLNAME = "@@PROTOCOLNAME@@"; + public const string PROTOCOLID = "@@PROTOCOLID@@"; + public const string REASON = "@@REASON@@"; + public const string REQUESTDATE = "@@REQUESTDATE@@"; + public const string REQUESTER = "@@REQUESTER@@"; + public const string REQUESTING_APPNAME = "@@REQUESTING_APPNAME@@"; + public const string REQUESTING_APPID = "@@REQUESTING_APPID@@"; + public const string RULE_NUMBER = "@@RULE_NUMBER@@"; + public const string RULE_TABLE = "@@RULE_TABLE@@"; + public const string SERVICENAME = "@@SERVICENAME@@"; + public const string SERVICES = "@@SERVICES@@"; + public const string SOURCES = "@@SOURCES@@"; + public const string STATUS = "@@STATUS@@"; + public const string TASKCOMMENT = "@@TASKCOMMENT@@"; + public const string TASKS = "@@TASKS@@"; + public const string TICKET_SUBJECT = "@@TICKET_SUBJECT@@"; + public const string TIME_INTERVAL = "@@TIME_INTERVAL@@"; + public const string TYPE = "@@TYPE@@"; + public const string USER_NAME = "@@USER_NAME@@"; + } + + public enum OwnerMappingSourceStm + { + IpBased = 1, + CustomField = 2, + NameField = 3, + Manual = 4 + } + + public struct ImportType + { + public const int RULE = 1; + public const int OWNER = 2; + public const int ADMIN_VIA_REINITIALIZE_BTN = 3; + } + + public struct ChangelogActionType + { + public const Char INSERT = 'I'; + public const Char CHANGE = 'C'; + public const Char DELETE = 'D'; + public const Char DEACTIVATE = 'X'; + public const Char REACTIVATE = 'R'; + } + + public struct RuleActions + { + public const string Accept = "accept"; + public const string Deny = "deny"; + public const string Any = "any"; + public const string Reject = "reject"; + public const string Drop = "drop"; + } +} diff --git a/roles/lib/files/FWO.Basics/ITreeItem.cs b/roles/lib/files/FWO.Basics/ITreeItem.cs new file mode 100644 index 0000000000..f7a794cbe4 --- /dev/null +++ b/roles/lib/files/FWO.Basics/ITreeItem.cs @@ -0,0 +1,20 @@ +namespace FWO.Basics +{ + public interface ITreeItem + { + List> Children { get; set; } + List> ElementsFlat { get; set; } + List? Position { get; set; } + ITreeItem? Parent { get; set; } + ITreeItem? LastAddedItem { get; set; } + TItem? Data { get; set; } + string? Identifier { get; set; } + bool IsRoot { get; set; } + string Header { get; set; } + + string GetPositionString(); + void SetPosition(string orderNumberString); + ITreeItem AddItem(ITreeItem? item = null, List? position = null, string header = "", bool isRoot = false, bool addToFlatList = false, bool addToChildren = false, bool setLastAddedItem = false); + string ToJson(); + } +} diff --git a/roles/lib/files/FWO.Basics/Icons.cs b/roles/lib/files/FWO.Basics/Icons.cs new file mode 100644 index 0000000000..1c8c4f7e28 --- /dev/null +++ b/roles/lib/files/FWO.Basics/Icons.cs @@ -0,0 +1,143 @@ +namespace FWO.Basics +{ + public struct Icons + { + // Bootstrap + public const string Save = "bi bi-floppy-fill"; + public const string Select = "bi bi-floppy-fill"; + public const string Cancel = "bi bi-x-square-fill"; + public const string Confirm = "bi bi-hand-thumbs-up-fill"; + public const string Reject = "bi bi-hand-thumbs-down-fill"; + public const string Recertify = "bi bi-patch-check-fill"; + public const string RequestFwChange = "bi bi-sign-intersection-t-fill"; + public const string ShowHistory = "bi bi-clock-history"; + public const string GenerateReport = "bi bi-newspaper"; + public const string Export = "bi bi-box-arrow-up-right"; + public const string Rollout = "bi bi-rocket-takeoff-fill"; + public const string Download = "bi bi-download"; + public const string Load = "bi bi-file-arrow-down-fill"; + public const string ChangeState = "bi bi-graph-up-arrow"; + public const string Approve = "bi bi-hand-thumbs-up-fill"; + public const string Cleanup = "bi bi-slash-circle-fill"; + public const string Create = "bi bi-patch-plus-fill"; + public const string Enter = "bi bi-arrow-return-left"; + public const string Migrate = "bi-database-fill-gear"; + + // General + public const string Locked = "bi bi-lock-fill"; + public const string Unlocked = "bi bi-unlock-fill"; + public const string Type = "bi bi-list-ul"; + public const string Example = "bi bi-eye-fill"; + public const string Requirement = "bi bi-eye-fill"; + public const string Security = "bi bi-shield-shaded"; + public const string FurtherReading = "bi bi-book-fill"; + public const string Clipboard = "bi bi-clipboard-fill"; + public const string Warning = "bi bi-exclamation-triangle-fill"; + public const string Question = "bi bi-question-lg"; + + // Actions + public const string Add = "bi bi-plus-lg"; + public const string Edit = "bi bi-pencil-fill"; + public const string Delete = "bi bi-trash-fill"; + public const string Search = "bi bi-search"; + public const string Display = "bi bi-eye-fill"; + public const string Use = "bi bi-arrow-right"; + public const string Unuse = "bi bi-arrow-left"; + public const string Close = "bi bi-x-lg"; + public const string Login = "bi bi-box-arrow-in-right"; + public const string Logout = "bi bi-box-arrow-left"; + public const string Check = "bi bi-check-lg"; + public const string Swap = "bi bi-arrow-repeat"; + public const string CollapseUp = "bi bi-chevron-up"; + public const string CollapseDown = "bi bi-chevron-down"; + public const string CollapseLeft = "bi bi-chevron-left"; + public const string CollapseRight = "bi bi-chevron-right"; + public const string Share = "bi bi-share-fill"; + public const string OrderByAsc = "bi bi-caret-up-fill"; + public const string OrderByDesc = "bi bi-caret-down-fill"; + public const string Refresh = "bi bi-arrow-clockwise"; + public const string Undo = "bi bi-arrow-counterclockwise"; + + //Actions Html + public const string HtmlArrowExpanded = "▼"; + public const string HtmlArrowCollapsed = "▶"; + + // Object types: General + public const string Ldap = "bi bi-journal-bookmark-fill"; + public const string Management = "bi bi-inbox-fill"; + public const string Gateway = "bi bi-shield-shaded"; + public const string Credential = "bi bi-key-fill"; + public const string Role = "bi bi-tags-fill"; + public const string Tenant = "bi bi-command"; + public const string Owner = "bi bi-flag-fill"; + public const string Email = "bi bi-envelope-fill"; + + // Object types: Reporting + public const string UserGroup = "bi bi-people-fill"; + public const string ObjGroup = "bi bi-list-ul"; + public const string Host = "bi bi-pc-display-horizontal"; + public const string Network = "bi bi-diagram-3-fill"; + public const string Range = "bi bi-three-dots"; + public const string NwObject = "bi bi-pc-display-horizontal"; + public const string Service = "bi bi-wrench-adjustable"; + public const string User = "bi bi-person-fill"; + + // Object types: Modelling + public const string ModObject = "bi bi-box"; + public const string ServiceGroup = "bi bi-list-ul"; + public const string AppRole = "bi bi-tag-fill"; + public const string NwGroup = "bi bi-folder-fill"; + public const string Connection = "bi bi-arrow-left-right"; + public const string Interface = "bi bi-ethernet"; + + // Modules + public const string Reporting = "bi bi-table"; + public const string Workflow = "bi bi-signpost-split-fill"; + public const string Recertification = "bi bi-award-fill"; + public const string Modelling = "bi bi-puzzle-fill"; + public const string NetworkAnalysis = "bi bi-table"; + public const string Compliance = "bi bi-speedometer"; + public const string Monitoring = "bi bi-display-fill"; + public const string Settings = "bi bi-gear-wide-connected"; + public const string Help = "bi bi-info-lg"; + public const string Api = "bi bi-eye-fill"; + + // Reporting + public const string Template = "bi bi-file-earmark-text-fill"; + public const string Schedule = "bi bi-stopwatch-fill"; + public const string Archive = "bi bi-archive-fill"; + public const string Output = "bi bi-share-fill"; + public const string Filter = "bi bi-funnel-fill"; + + // Workflow + public const string Tickets = "bi bi-front"; + public const string CreateTicket = "bi bi-plus-square-dotted"; + public const string Approval = "bi bi-check-lg"; + public const string Planning = "bi bi-map-fill"; + public const string Implementation = "bi bi-wrench-adjustable"; + public const string Review = "bi bi-patch-check-fill"; + public const string State = "bi bi-tag-fill"; + public const string Matrix = "bi bi-grid-3x3-gap-fill"; + public const string Action = "bi bi-arrow-right"; + public const string Phase = "bi bi-arrow-repeat"; + public const string Assign = "bi bi-arrow-right-square-fill"; + + // Monitoring + public const string Alarm = "bi bi-bell-fill"; + public const string Acknowledge = "bi bi-patch-check-fill"; + public const string Import = "bi bi-download"; + public const string UiMessages = "bi bi-chat-fill"; + + // Settings + public const string Policy = "bi bi-file-earmark-medical-fill"; + public const string Text = "bi bi-fonts"; + public const string Language = "bi bi-translate"; + + // Api + public const string RestDoku = "bi bi-file-earmark-code-fill"; + public const string GraphQL = "bi bi-code-slash"; + public const string Hasura = "bi bi-file-earmark-spreadsheet-fill"; + public const string Mutation = "bi bi-pencil-fill"; + public const string Query = "bi bi-database-fill-down"; + } +} diff --git a/roles/lib/files/FWO.Basics/Interfaces/IComplianceViolation.cs b/roles/lib/files/FWO.Basics/Interfaces/IComplianceViolation.cs new file mode 100644 index 0000000000..5b14f7b4a9 --- /dev/null +++ b/roles/lib/files/FWO.Basics/Interfaces/IComplianceViolation.cs @@ -0,0 +1,15 @@ +namespace FWO.Basics.Interfaces +{ + public interface IComplianceViolation + { + int RuleId { get; set; } + DateTime FoundDate { get; set; } + DateTime? RemovedDate { get; set; } + string Details { get; set; } + long RiskScore { get; set; } + int PolicyId { get; set; } + int CriterionId { get; set; } + } +} + + diff --git a/roles/lib/files/FWO.Basics/Interfaces/ILogger.cs b/roles/lib/files/FWO.Basics/Interfaces/ILogger.cs new file mode 100644 index 0000000000..68c8f6cc02 --- /dev/null +++ b/roles/lib/files/FWO.Basics/Interfaces/ILogger.cs @@ -0,0 +1,12 @@ +namespace FWO.Basics.Interfaces +{ + public interface ILogger + { + void TryWriteInfo(string title, string text, bool condition); + void TryWriteDebug(string title, string text, bool condition); + void TryWriteWarning(string title, string text, bool condition); + void TryWriteError(string title, string text, bool condition); + void TryWriteError(string title, Exception exception, bool condition); + void TryWriteAudit(string title, string text, bool condition); + } +} diff --git a/roles/lib/files/FWO.Basics/Interfaces/IRuleViewData.cs b/roles/lib/files/FWO.Basics/Interfaces/IRuleViewData.cs new file mode 100644 index 0000000000..adbdc68504 --- /dev/null +++ b/roles/lib/files/FWO.Basics/Interfaces/IRuleViewData.cs @@ -0,0 +1,22 @@ +namespace FWO.Basics.Interfaces +{ + public interface IRuleViewData + { + string MgmtId { get; set; } + string Uid { get; set; } + string Name { get; set; } + string Source { get; set; } + string Destination { get; set; } + string Services { get; set; } + string Action { get; set; } + string InstallOn { get; set; } + string Compliance { get; set; } + string ViolationDetails { get; set; } + string ChangeID { get; set; } + string AdoITID { get; set; } + string Comment { get; set; } + string LastModified { get; set; } + string RulebaseId { get; set; } + string Enabled { get; set; } + } +} diff --git a/roles/lib/files/FWO.Basics/IpOperations.cs b/roles/lib/files/FWO.Basics/IpOperations.cs new file mode 100644 index 0000000000..8ca8fc7e56 --- /dev/null +++ b/roles/lib/files/FWO.Basics/IpOperations.cs @@ -0,0 +1,579 @@ +using System.Net; +using System.Net.Sockets; +using System.Numerics; +using DnsClient; +using NetTools; + +namespace FWO.Basics +{ + /// + /// Provides helper methods for DNS lookups and IP address conversions. + /// + public static class IpOperations + { + // Reuse the client to avoid socket churn and disable client-side caching. + private static readonly LookupClient ReverseLookupClient = new(new LookupClientOptions + { + UseCache = false, + ContinueOnDnsError = true, + ThrowDnsErrors = false + }); + + /// + /// Resolves all PTR records for an IP address. + /// + public static async Task> DnsReverseLookUpAllAsync( + IPAddress address, + CancellationToken cancellationToken = default) + { + // QueryReverseAsync issues a PTR query and returns all answers from the DNS server. + IDnsQueryResponse response = await ReverseLookupClient.QueryReverseAsync(address, cancellationToken) + .ConfigureAwait(false); + + if (response.HasError || response.Answers.Count == 0) + { + return Array.Empty(); + } + + return response.Answers + .PtrRecords() + .Select(ptr => ptr.PtrDomainName.Value.TrimEnd('.')) // Drop the trailing DNS root dot. + .Distinct(StringComparer.OrdinalIgnoreCase) + .ToArray(); + } + + /// + /// Resolves the preferred PTR record for an IP address. + /// + public static async Task DnsReverseLookUpPreferredAsync(IPAddress address) + { + IReadOnlyList names = await DnsReverseLookUpAllAsync(address); + return names.FirstOrDefault(name => !name.StartsWith("lx", StringComparison.OrdinalIgnoreCase)) + ?? names.FirstOrDefault() + ?? ""; + } + + /// + /// Resolves the host name for an IP address. + /// + public static async Task DnsReverseLookUp(IPAddress address) + { + try + { + return (await Dns.GetHostEntryAsync(address)).HostName; + } + catch (Exception) + { + return ""; + } + } + + /// + /// Resolves the first IPv4 address for a host name. + /// + public static async Task DnsLookUp(string hostname) + { + try + { + return (await Dns.GetHostAddressesAsync(hostname)) + .FirstOrDefault(a => a.AddressFamily == AddressFamily.InterNetwork)? + .ToString() ?? ""; + } + catch (Exception) + { + return ""; + } + } + + /// + /// Converts a single IP, CIDR, or explicit range string into start and end addresses. + /// + public static (string, string) SplitIpToRange(string ipString) + { + if (ipString.TryGetNetmask(out _)) + { + return ipString.CidrToRangeString(); + } + + return TryParseExplicitRange(ipString, out IPAddressRange ipRange) + ? (ipRange.Begin.ToString(), ipRange.End.ToString()) + : (ipString, ipString); + } + + /// + /// Tries to parse a single IP, CIDR, or range string into string endpoints. + /// + public static bool TryParseIPStringToRange(this string ipString, out (string start, string end) ipRange, bool strictv4Parse = false) + { + ipRange = default; + if (!TryParseAddressPair(ipString, strictv4Parse, out string ipStart, out string ipEnd, out _, out _)) + { + return false; + } + + ipRange = (ipStart, ipEnd); + return true; + } + + /// + /// Tries to parse a single IP, CIDR, or range string into a supported target type. + /// + public static bool TryParseIPString(this string ipString, out T? ipResult, bool strictv4Parse = false) + { + ipResult = default; + if (!TryParseAddressPair(ipString, strictv4Parse, out _, out _, out IPAddress? addressStart, out IPAddress? addressEnd)) + { + return false; + } + + object? parsedValue = typeof(T) switch + { + var t when t == typeof((string, string)) => + (addressStart!.ToString(), addressEnd!.ToString()), + + var t when t == typeof(IPAddressRange) => + new IPAddressRange(addressStart!, addressEnd!), + + var t when t == typeof((IPAddress, IPAddress)) => + (addressStart!, addressEnd!), + + _ => null + }; + + if (parsedValue is null) + { + return false; + } + + ipResult = (T)parsedValue; + return true; + } + + private static bool IsValidIPv4(string ipAddress) + { + string[] octets = ipAddress.Split('.'); + return octets.Length == 4 && octets.All(octet => byte.TryParse(octet, out _)); + } + + /// + /// Returns the matching object type for one or two IP values. + /// + public static string GetObjectType(string ip1, string ip2) + { + ip1 = ip1.StripOffUnnecessaryNetmask(); + ip2 = ip2.StripOffUnnecessaryNetmask(); + + if (ip1 == ip2 || ip2 == "") + { + return ip1.TryGetNetmask(out _) ? ObjectType.Network : ObjectType.Host; + } + + return SpanSingleNetwork(ip1, ip2) ? ObjectType.Network : ObjectType.IPRange; + } + + private static bool SpanSingleNetwork(string ipStart, string ipEnd) + { + IPAddressRange range = IPAddressRange.Parse(ipStart.StripOffNetmask() + "-" + ipEnd.StripOffNetmask()); + return HasValidNetmask(range); + } + + private static bool HasValidNetmask(IPAddressRange range) + { + // Adapted from IPAddressRange.getPrefixLength() without exception handling. + byte[] addressBytes = range.Begin.GetAddressBytes(); + if (range.Begin.Equals(range.End)) + { + return true; + } + + int num = addressBytes.Length * 8; + for (int i = 0; i < num; i++) + { + byte[] bitMask = Bits.GetBitMask(addressBytes.Length, i); + if (new IPAddress(Bits.And(addressBytes, bitMask)).Equals(range.Begin) && + new IPAddress(Bits.Or(addressBytes, Bits.Not(bitMask))).Equals(range.End)) + { + return true; + } + } + + return false; + } + + /// + /// Checks whether two IP ranges overlap. + /// + /// The first IP range. + /// The second IP range. + /// true when the ranges overlap, otherwise false. + public static bool RangeOverlapExists(IPAddressRange a, IPAddressRange b) + { + return IpToUint(a.Begin) <= IpToUint(b.End) && IpToUint(b.Begin) <= IpToUint(a.End); + } + + /// + /// Calculates the intersection of two IP address ranges. + /// + /// The first IP address range. + /// The second IP address range. + /// + /// A new representing the overlapping range, + /// or null if the ranges do not overlap. + /// + public static IPAddressRange? GetIntersection(IPAddressRange a, IPAddressRange b) + { + if (a.Begin.AddressFamily != b.Begin.AddressFamily) + { + return null; + } + + BigInteger startA = ToBigInteger(a.Begin); + BigInteger endA = ToBigInteger(a.End); + BigInteger startB = ToBigInteger(b.Begin); + BigInteger endB = ToBigInteger(b.End); + + BigInteger startOverlap = BigInteger.Max(startA, startB); + BigInteger endOverlap = BigInteger.Min(endA, endB); + + if (startOverlap <= endOverlap) + { + return new IPAddressRange( + FromBigInteger(startOverlap, a.Begin.AddressFamily), + FromBigInteger(endOverlap, a.Begin.AddressFamily) + ); + } + + return null; + } + + /// + /// Converts an IPv4 address to an unsigned integer. + /// + public static uint IpToUint(IPAddress ipAddress) + { + byte[] bytes = ipAddress.GetAddressBytes(); + + // Convert from network byte order to host byte order. + if (BitConverter.IsLittleEndian) + { + Array.Reverse(bytes); + } + + return BitConverter.ToUInt32(bytes, 0); + } + + /// + /// Converts an unsigned integer to an IPv4 address. + /// + public static IPAddress UintToIp(uint ipAddress) + { + byte[] bytes = BitConverter.GetBytes(ipAddress); + + // Convert from host byte order to network byte order. + if (BitConverter.IsLittleEndian) + { + Array.Reverse(bytes); + } + + return new IPAddress(bytes); + } + + /// + /// Checks whether two single IP, CIDR, or range strings overlap. + /// + public static bool CheckOverlap(string ip1, string ip2) + { + IPAddressRange range1 = GetIPAdressRange(ip1); + IPAddressRange range2 = GetIPAdressRange(ip2); + + if (range1.Begin.AddressFamily != range2.Begin.AddressFamily) + { + return false; + } + + return RangeOverlapExists(range1, range2); + } + + /// + /// Converts a single IP, CIDR, or range string into an . + /// + public static IPAddressRange GetIPAdressRange(string ip) + { + (string start, string end) = SplitIpToRange(ip); + return new IPAddressRange(IPAddress.Parse(start), IPAddress.Parse(end)); + } + + /// + /// Converts start and end addresses to dotted mask notation for the matching network. + /// + public static string ToDotNotation(string startIp, string endIp) + { + if (!IPAddress.TryParse(startIp.StripOffNetmask(), out IPAddress? start)) + { + throw new ArgumentException($"IP {startIp} is not valid"); + } + + if (!IPAddress.TryParse(endIp.StripOffNetmask(), out IPAddress? end)) + { + throw new ArgumentException($"IP {endIp} is not valid"); + } + + // Ensure both IPs are in the same address family. + if (start.AddressFamily != end.AddressFamily) + { + throw new ArgumentException("Start and end IPs must be of the same address family."); + } + + // Walk from the most specific prefix down to the least specific prefix. + int maxPrefixLength = start.AddressFamily == AddressFamily.InterNetwork ? 32 : 128; + + for (int prefixLength = maxPrefixLength; prefixLength >= 0; prefixLength--) + { + IPNetwork network = IPNetwork.Parse($"{start}/{prefixLength}"); + if (network.Contains(start) && network.Contains(end)) + { + string subnetMask = start.AddressFamily == AddressFamily.InterNetwork + ? GetIPv4SubnetMask(network.PrefixLength) + : $"(IPv6) /{network.PrefixLength}"; + + return $"{network.ToString().StripOffNetmask()}/{subnetMask}"; + } + } + + return ""; + } + + // Convert a prefix length to an IPv4 subnet mask. + private static string GetIPv4SubnetMask(int prefixLength) + { + uint mask = 0xffffffff << (32 - prefixLength); + uint[] bytes = [(mask >> 24) & 0xff, (mask >> 16) & 0xff, (mask >> 8) & 0xff, mask & 0xff]; + return string.Join(".", bytes); + } + + /// + /// Compares two IP addresses byte by byte. + /// + public static int CompareIpValues(IPAddress ip1, IPAddress ip2) + { + byte[] ip1Bytes = ip1.GetAddressBytes(); + byte[] ip2Bytes = ip2.GetAddressBytes(); + + for (int i = 0; i < ip1Bytes.Length; i++) + { + if (ip1Bytes[i] < ip2Bytes[i]) + { + return -1; + } + + if (ip1Bytes[i] > ip2Bytes[i]) + { + return 1; + } + } + + return 0; + } + + /// + /// Compares two IP address objects by address family. + /// + public static int CompareIpFamilies(IPAddress ip1, IPAddress ip2) + { + return (ip1.AddressFamily, ip2.AddressFamily) switch + { + (AddressFamily.InterNetwork, AddressFamily.InterNetworkV6) => -1, + (AddressFamily.InterNetworkV6, AddressFamily.InterNetwork) => 1, + _ => 0 + }; + } + + /// + /// Subtracts one or more ranges from a source range. + /// + public static List Subtract(this IPAddressRange source, List subtractor) + { + return ToNetworks([source]).Subtract(ToNetworks(subtractor)).ToMergedRanges(); + } + + /// + /// Subtracts each network in from all source networks. + /// + public static IEnumerable Subtract( + this IEnumerable source, + IEnumerable subtract) + { + ArgumentNullException.ThrowIfNull(source); + ArgumentNullException.ThrowIfNull(subtract); + + List result = source.ToList(); + foreach (IPNetwork2 sub in subtract) + { + // Subtract each network from the current result set. + result = result + .SelectMany(network => network - sub) // Use IPNetwork2's subtraction operator. + .ToList(); + } + + return result; + } + + /// + /// Merges overlapping or adjacent networks into address ranges. + /// + public static List ToMergedRanges(this IEnumerable networks, bool includeNetworkAndBroadcast = true) + { + List networkList = networks.ToList(); + if (networkList.Count == 0) + { + return []; + } + + // Convert to inclusive [start, end] intervals. + List<(IPAddress start, IPAddress end)> intervals = networkList.Select(network => + { + IPAddress start = includeNetworkAndBroadcast ? network.Network : network.FirstUsable ?? network.Network; + IPAddress end = includeNetworkAndBroadcast ? network.Broadcast ?? start : network.LastUsable ?? start; + return (start, end); + }).ToList(); + + // Ensure all intervals use the same address family. + AddressFamily addressFamily = intervals[0].start.AddressFamily; + if (intervals.Any(interval => interval.start.AddressFamily != addressFamily || interval.end.AddressFamily != addressFamily)) + { + throw new InvalidOperationException("Mixed address families (IPv4/IPv6) are not supported."); + } + + intervals.Sort((left, right) => CompareIpValues(left.start, right.start)); + + List<(IPAddress start, IPAddress end)> merged = new(); + (IPAddress start, IPAddress end) currentInterval = intervals[0]; + + foreach ((IPAddress start, IPAddress end) in intervals.Skip(1)) + { + if (CompareIpValues(start, AddIp(currentInterval.end, 1)) <= 0) + { + if (CompareIpValues(end, currentInterval.end) > 0) + { + currentInterval.end = end; + } + } + else + { + merged.Add(currentInterval); + currentInterval = (start, end); + } + } + + merged.Add(currentInterval); + return [.. merged.Select(interval => new IPAddressRange(interval.start, interval.end))]; + } + + private static IPAddress AddIp(IPAddress ip, long delta) + { + BigInteger value = ToBigInteger(ip) + new BigInteger(delta); + if (value < BigInteger.Zero) + { + value = BigInteger.Zero; + } + + AddressFamily family = ip.AddressFamily; + BigInteger max = MaxValue(family); + if (value > max) + { + value = max; + } + + return FromBigInteger(value, family); + } + + public static BigInteger ToBigInteger(IPAddress ip) + { + byte[] bytes = ip.GetAddressBytes(); // Big-endian. + byte[] littleEndian = [.. bytes.Reverse(), 0]; // Little-endian plus unsigned padding. + return new BigInteger(littleEndian); + } + + private static IPAddress FromBigInteger(BigInteger value, AddressFamily family) + { + int length = family == AddressFamily.InterNetwork ? 4 : 16; + byte[] bytesLittleEndian = value.ToByteArray(); // Little-endian. + byte[] bytesBigEndian = new byte[length]; + + for (int i = 0; i < length; i++) + { + bytesBigEndian[length - 1 - i] = i < bytesLittleEndian.Length ? bytesLittleEndian[i] : (byte)0; + } + + return new IPAddress(bytesBigEndian); + } + + private static BigInteger MaxValue(AddressFamily family) + { + int bits = family == AddressFamily.InterNetwork ? 32 : 128; + return (BigInteger.One << bits) - 1; + } + + private static bool TryParseExplicitRange(string ipString, out IPAddressRange ipRange) + { + ipRange = default!; + return ipString.TrySplit('-', 1, out _) && IPAddressRange.TryParse(ipString, out ipRange); + } + + private static bool TryParseAddressPair( + string ipString, + bool strictv4Parse, + out string ipStart, + out string ipEnd, + out IPAddress? addressStart, + out IPAddress? addressEnd) + { + ipStart = ipEnd = ""; + addressStart = addressEnd = null; + + try + { + (ipStart, ipEnd) = SplitIpToRange(ipString); + return IPAddress.TryParse(ipStart, out addressStart) + && IPAddress.TryParse(ipEnd, out addressEnd) + && !HasStrictIPv4ParseError(ipStart, ipEnd, addressStart, addressEnd, strictv4Parse); + } + catch (Exception) + { + return false; + } + } + + private static bool HasStrictIPv4ParseError( + string ipStart, + string ipEnd, + IPAddress addressStart, + IPAddress addressEnd, + bool strictv4Parse) + { + return strictv4Parse + && addressStart.AddressFamily == AddressFamily.InterNetwork + && addressEnd.AddressFamily == AddressFamily.InterNetwork + && (!IsValidIPv4(ipStart) || !IsValidIPv4(ipEnd)); + } + + private static List ToNetworks(IEnumerable ranges) + { + List networks = new(); + foreach (IPAddressRange range in ranges) + { + if (range.Begin.Equals(range.End)) + { + int mask = range.Begin.AddressFamily == AddressFamily.InterNetwork ? 32 : 128; + networks.Add(IPNetwork2.Parse(range.ToString(), (byte)mask)); + } + else if (IPNetwork2.TryParseRange(range.ToString(), out IEnumerable? parsedRanges)) + { + networks.AddRange(parsedRanges); + } + } + + return networks; + } + } +} diff --git a/roles/lib/files/FWO.Basics/JwtClaimParser.cs b/roles/lib/files/FWO.Basics/JwtClaimParser.cs new file mode 100644 index 0000000000..e2c859fb2b --- /dev/null +++ b/roles/lib/files/FWO.Basics/JwtClaimParser.cs @@ -0,0 +1,167 @@ +using System.Security.Claims; +using System.Text.Json; + +namespace FWO.Basics +{ + public static class JwtClaimParser + { + public static List ExtractStringClaimValues(IEnumerable claims, string claimType) + { + List result = []; + foreach (Claim claim in claims.Where(currentClaim => ClaimTypeMatches(currentClaim.Type, claimType))) + { + AddStringClaimValue(result, claim.Value); + } + return result; + } + + public static List ExtractIntClaimValues(IEnumerable claims, string claimType) + { + List result = []; + foreach (Claim claim in claims.Where(currentClaim => ClaimTypeMatches(currentClaim.Type, claimType))) + { + AddIntClaimValue(result, claim.Value); + } + return result; + } + + public static bool ClaimTypeMatches(string claimType, string expectedClaimType) + { + if (claimType.Equals(expectedClaimType, StringComparison.OrdinalIgnoreCase)) + { + return true; + } + + return claimType.EndsWith("/" + expectedClaimType, StringComparison.OrdinalIgnoreCase); + } + + private static void AddStringClaimValue(List result, string claimValue) + { + if (string.IsNullOrWhiteSpace(claimValue)) + { + return; + } + + string trimmedValue = claimValue.Trim(); + if (TryDeserializeStringArray(trimmedValue, out List parsedStrings)) + { + AddDistinctStrings(result, parsedStrings); + return; + } + + if (trimmedValue.StartsWith('{') && trimmedValue.EndsWith('}')) + { + AddDistinctStrings(result, SplitSeparatedValues(trimmedValue)); + return; + } + + if (!result.Contains(trimmedValue, StringComparer.OrdinalIgnoreCase)) + { + result.Add(trimmedValue); + } + } + + private static void AddIntClaimValue(List result, string claimValue) + { + if (string.IsNullOrWhiteSpace(claimValue)) + { + return; + } + + string trimmedValue = claimValue.Trim(); + if (TryDeserializeIntArray(trimmedValue, out List parsedInts)) + { + AddDistinctInts(result, parsedInts); + return; + } + + foreach (string token in SplitSeparatedValues(trimmedValue)) + { + if (int.TryParse(token, out int parsedInt) && !result.Contains(parsedInt)) + { + result.Add(parsedInt); + } + } + } + + private static bool TryDeserializeStringArray(string claimValue, out List values) + { + values = []; + if (TryDeserializeJsonArray(claimValue, out string[]? directStringArray) && directStringArray != null) + { + values = directStringArray.Where(value => !string.IsNullOrWhiteSpace(value)).ToList(); + return true; + } + return false; + } + + private static bool TryDeserializeIntArray(string claimValue, out List values) + { + values = []; + if (TryDeserializeJsonArray(claimValue, out int[]? directIntArray) && directIntArray != null) + { + values = directIntArray.ToList(); + return true; + } + + if (!TryDeserializeJsonArray(claimValue, out string[]? stringIntArray) || stringIntArray == null) + { + return false; + } + + foreach (string value in stringIntArray) + { + if (int.TryParse(value, out int parsedInt)) + { + values.Add(parsedInt); + } + } + return values.Count > 0; + } + + private static bool TryDeserializeJsonArray(string claimValue, out T[]? values) + { + values = null; + try + { + values = JsonSerializer.Deserialize(claimValue); + return true; + } + catch + { + return false; + } + } + + private static List SplitSeparatedValues(string value) + { + char[] separators = [',', '{', '}', '[', ']']; + return value + .Split(separators, StringSplitOptions.TrimEntries | StringSplitOptions.RemoveEmptyEntries) + .Where(token => !string.IsNullOrWhiteSpace(token)) + .ToList(); + } + + private static void AddDistinctStrings(List target, IEnumerable values) + { + foreach (string value in values) + { + if (!target.Contains(value, StringComparer.OrdinalIgnoreCase)) + { + target.Add(value); + } + } + } + + private static void AddDistinctInts(List target, IEnumerable values) + { + foreach (int value in values) + { + if (!target.Contains(value)) + { + target.Add(value); + } + } + } + } +} diff --git a/roles/lib/files/FWO.Basics/JwtConstants.cs b/roles/lib/files/FWO.Basics/JwtConstants.cs new file mode 100644 index 0000000000..252e81a635 --- /dev/null +++ b/roles/lib/files/FWO.Basics/JwtConstants.cs @@ -0,0 +1,8 @@ +namespace FWO.Basics +{ + public class JwtConstants + { + public const string Issuer = "FWO Middleware Module"; + public const string Audience = "FWO"; + } +} diff --git a/roles/lib/files/FWO.Basics/LocalSettings.cs b/roles/lib/files/FWO.Basics/LocalSettings.cs new file mode 100644 index 0000000000..cfd4e25e3d --- /dev/null +++ b/roles/lib/files/FWO.Basics/LocalSettings.cs @@ -0,0 +1,53 @@ +using System.Text.Json; + +namespace FWO.Basics +{ + public static class LocalSettings + { + public static bool CSharpUnitTestsVerbose { get; set; } = false; + + public static bool ComplianceCheckVerbose { get; set; } = true; + + /// + /// Static constructor to load local settings from a JSON file specified by the + /// FWORCH_LOCAL_SETTINGS_PATH environment variable. To set this environment variable permanently on a linux system, + /// you can run a command like this in your terminal: 'export FWORCH_LOCAL_SETTINGS_PATH="//.vscode/settings.local.json"'. + /// Please adjust the path according to your setup. + /// If the environment variable is not set, the file is not found or cannot be read, default settings are used. + /// + static LocalSettings() + { + TryGetLocalSettings(); + } + + public static void TryGetLocalSettings() + { + string? localSettings = Environment.GetEnvironmentVariable("FWORCH_LOCAL_SETTINGS_PATH"); + + if (File.Exists(localSettings)) + { + try + { + using FileStream s = File.OpenRead(localSettings); + JsonDocument json = JsonDocument.Parse(s); + + if (json.RootElement.TryGetProperty("test.unittests.csharp.verbose", out var testUnitTestsCSharpVerbose)) + { + CSharpUnitTestsVerbose = testUnitTestsCSharpVerbose.GetBoolean(); + } + + if (json.RootElement.TryGetProperty("log.compliancecheck.verbose", out var logComplianceCheckVerbose)) + { + ComplianceCheckVerbose = logComplianceCheckVerbose.GetBoolean(); + } + + } + catch + { + Console.WriteLine($"Reading local settings from {localSettings} failed. Using default settings."); + } + } + } + } +} + diff --git a/roles/lib/files/FWO.Basics/Module.cs b/roles/lib/files/FWO.Basics/Module.cs new file mode 100644 index 0000000000..98963e7e56 --- /dev/null +++ b/roles/lib/files/FWO.Basics/Module.cs @@ -0,0 +1,20 @@ +namespace FWO.Basics +{ + public enum Module + { + Report = 1, + Workflow = 2, + Recertification = 3, + Modelling = 4, + NetworkAnalysis = 5, + Compliance = 6 + } + + public static class ModuleGroups + { + public static string AllModulesNumList() + { + return $"[{string.Join(",", Enum.GetValues(typeof(Module)).Cast().Select(m => (int)m).ToList())}]"; + } + } +} diff --git a/roles/lib/files/FWO.Basics/OwnerResponsibleRoleHelper.cs b/roles/lib/files/FWO.Basics/OwnerResponsibleRoleHelper.cs new file mode 100644 index 0000000000..18d4435ae5 --- /dev/null +++ b/roles/lib/files/FWO.Basics/OwnerResponsibleRoleHelper.cs @@ -0,0 +1,38 @@ +using System.Collections.Generic; +using System.Linq; + +namespace FWO.Basics +{ + public static class OwnerResponsibleRoleHelper + { + public static bool IsModellingRole(string role) + { + return role == Roles.Modeller; + } + + public static bool IsRecertificationRole(string role) + { + return role == Roles.Recertifier; + } + + public static bool IsWriteSensitiveRole(string role) + { + return IsModellingRole(role) || IsRecertificationRole(role); + } + + public static List FilterRoles(IEnumerable roles, bool allowModelling, bool allowRecertification) + { + List roleList = roles.ToList(); + if (allowModelling && allowRecertification) + { + return roleList; + } + + return roleList + .Where(role => + (!IsModellingRole(role) || allowModelling) + && (!IsRecertificationRole(role) || allowRecertification)) + .ToList(); + } + } +} diff --git a/roles/lib/files/FWO.Basics/ReportType.cs b/roles/lib/files/FWO.Basics/ReportType.cs new file mode 100644 index 0000000000..533dbf4549 --- /dev/null +++ b/roles/lib/files/FWO.Basics/ReportType.cs @@ -0,0 +1,235 @@ +namespace FWO.Basics +{ + public enum ReportType + { + Undefined = 0, + Rules = 1, + Changes = 2, + Statistics = 3, + NatRules = 4, + ResolvedRules = 5, + ResolvedRulesTech = 6, + Recertification = 7, + ResolvedChanges = 8, + ResolvedChangesTech = 9, + UnusedRules = 10, + + Connections = 21, + AppRules = 22, + VarianceAnalysis = 23, + OwnerRecertification = 24, + RecertificationEvent = 25, + RecertEventReport = 26, + + ComplianceReport = 31, + ComplianceDiffReport = 32, + + TicketReport = 41, + TicketChangeReport = 42, + + Owners = 51 + } + + public static class ReportTypeGroups + { + public static bool IsRuleReport(this ReportType reportType) + { + return reportType switch + { + ReportType.Rules or + ReportType.ResolvedRules or + ReportType.ResolvedRulesTech or + ReportType.NatRules or + ReportType.Recertification or + ReportType.UnusedRules or + ReportType.AppRules or + ReportType.RecertEventReport => true, + _ => false + }; + } + + public static bool IsChangeReport(this ReportType reportType) + { + return reportType switch + { + ReportType.Changes or + ReportType.ResolvedChanges or + ReportType.ResolvedChangesTech => true, + _ => false + }; + } + + public static bool IsResolvedReport(this ReportType reportType) + { + return reportType switch + { + ReportType.ResolvedRules or + ReportType.ResolvedRulesTech or + ReportType.ResolvedChanges or + ReportType.ResolvedChangesTech or + ReportType.ComplianceReport or + ReportType.ComplianceDiffReport => true, + _ => false, + }; + } + + public static bool IsTechReport(this ReportType reportType) + { + return reportType switch + { + ReportType.ResolvedRulesTech or + ReportType.ResolvedChangesTech => true, + _ => false + }; + } + + public static bool IsDeviceRelatedReport(this ReportType reportType) + { + return reportType.IsRuleReport() || reportType.IsChangeReport() || reportType == ReportType.Statistics; + } + + public static bool IsConnectionRelatedReport(this ReportType reportType) + { + return reportType switch + { + ReportType.Connections or + ReportType.VarianceAnalysis or + ReportType.RecertificationEvent => true, + _ => false + }; + } + + public static bool IsModellingReport(this ReportType reportType) + { + return reportType switch + { + ReportType.Connections or + ReportType.AppRules or + ReportType.VarianceAnalysis or + ReportType.OwnerRecertification or + ReportType.RecertificationEvent or + ReportType.RecertEventReport => true, + _ => false + }; + } + + public static bool IsOwnerReport(this ReportType reportType) + { + return reportType == ReportType.Owners || reportType == ReportType.OwnerRecertification; + } + + public static bool IsComplianceReport(this ReportType reportType) + { + return reportType == ReportType.ComplianceReport || reportType == ReportType.ComplianceDiffReport; + } + + public static bool IsRulebaseReport(this ReportType reportType) + { + return reportType == ReportType.Recertification || reportType == ReportType.AppRules; + } + + public static bool IsWorkflowReport(this ReportType reportType) + { + return reportType == ReportType.TicketReport || reportType == ReportType.TicketChangeReport; + } + + public static bool IsArchiveOnlyReport(this ReportType reportType) + { + return reportType == ReportType.RecertificationEvent; + } + + public static bool HasTimeFilter(this ReportType reportType) + { + return reportType switch + { + ReportType.Rules or + ReportType.ResolvedRules or + ReportType.ResolvedRulesTech or + ReportType.NatRules or + ReportType.Statistics or + ReportType.Changes or + ReportType.ResolvedChanges or + ReportType.ResolvedChangesTech or + ReportType.TicketChangeReport => true, + _ => false + }; + } + + public static bool SupportsCsvExport(this ReportType reportType, bool detailedView = false) + { + return reportType.IsResolvedReport() + || reportType.IsComplianceReport() + || reportType.IsOwnerReport() + || reportType.IsWorkflowReport() && !detailedView; + } + + /// + /// Determines whether a report type supports HTML export. + /// + public static bool SupportsHtmlExport(this ReportType reportType) + { + return !reportType.IsComplianceReport(); + } + + /// + /// Determines whether a report type supports PDF export. + /// + public static bool SupportsPdfExport(this ReportType reportType) + { + return reportType.SupportsHtmlExport(); + } + + public static List AllReportTypes() + { + return [.. Enum.GetValues(typeof(ReportType)).Cast().Where(r => r != ReportType.Undefined)]; + } + + public static List ReportTypeSelection(ReportVisibility? visibility = null) + { + return CustomSortReportType([.. Enum.GetValues(typeof(ReportType)).Cast()], visibility ?? new(true, true, true, true, true)); + } + + public static bool IsVisibleTemplateType(this ReportType reportType, ReportVisibility visibility, bool modellingOwnerAllowed = true) + { + return !reportType.IsArchiveOnlyReport() && ( + visibility.RuleRelated && reportType.IsDeviceRelatedReport() && !reportType.IsModellingReport() + || visibility.ModellingRelated && reportType.IsModellingReport() && (modellingOwnerAllowed || reportType.IsOwnerReport()) + || visibility.OwnerRelated && reportType == ReportType.Owners + || visibility.ComplianceRelated && reportType.IsComplianceReport() + || visibility.WorkflowRelated && reportType.IsWorkflowReport()); + } + + public static List CustomSortReportType(List ListIn, ReportVisibility visibility) + { + List ListOut = []; + List orderedReportTypeList = + [ + ReportType.Undefined, + ReportType.RecertificationEvent, + ReportType.Rules, ReportType.ResolvedRules, ReportType.ResolvedRulesTech, ReportType.UnusedRules, ReportType.NatRules, + ReportType.Changes, ReportType.ResolvedChanges, ReportType.ResolvedChangesTech, + ReportType.Statistics, + ReportType.Connections, + ReportType.AppRules, + ReportType.VarianceAnalysis, + ReportType.Recertification, + ReportType.OwnerRecertification, + ReportType.RecertEventReport, + ReportType.Owners, + ReportType.TicketReport, + ReportType.TicketChangeReport + ]; + foreach (var reportType in orderedReportTypeList.Where(r => ListIn.Contains(r))) + { + if (reportType == ReportType.Undefined || reportType.IsVisibleTemplateType(visibility)) + { + ListOut.Add(reportType); + } + ListIn.Remove(reportType); + } + // Finally add only remaining report types the current user may actually see. + ListOut.AddRange(ListIn.Where(reportType => reportType.IsVisibleTemplateType(visibility))); + return ListOut; + } + } +} diff --git a/roles/lib/files/FWO.Basics/Roles.cs b/roles/lib/files/FWO.Basics/Roles.cs new file mode 100644 index 0000000000..637f4f95b7 --- /dev/null +++ b/roles/lib/files/FWO.Basics/Roles.cs @@ -0,0 +1,71 @@ +using System.Security.Claims; + +namespace FWO.Basics +{ + public struct Roles + { + // General + public const string Anonymous = "anonymous"; + public const string Admin = "admin"; + public const string Auditor = "auditor"; + public const string FwAdmin = "fw-admin"; + + // Rules + public const string Reporter = "reporter"; + public const string ReporterViewAll = "reporter-viewall"; + public const string Recertifier = "recertifier"; + public const string Modeller = "modeller"; + + // Workflow + public const string Requester = "requester"; + public const string Approver = "approver"; + public const string Planner = "planner"; + public const string Implementer = "implementer"; + public const string Reviewer = "reviewer"; + public const string WorkflowRolesList = $"{Requester}, {Approver}, {Planner}, {Implementer}, {Reviewer}"; + + // Technical + public const string MiddlewareServer = "middleware-server"; + public const string Importer = "importer"; + public const string DbBackup = "dbbackup"; + } + + public static class RoleGroups + { + public static bool IsTechnicalOrAnonymous(string role) + { + return role == Roles.MiddlewareServer || role == Roles.Importer || role == Roles.DbBackup || role == Roles.Anonymous; + } + + public static ReportVisibility GetReportVisibility(ClaimsPrincipal user) + { + return new ReportVisibility( + RuleRelated: user.IsInRole(Roles.Reporter) + || user.IsInRole(Roles.ReporterViewAll) + || user.IsInRole(Roles.FwAdmin) + || user.IsInRole(Roles.Admin) + || user.IsInRole(Roles.Auditor) + || user.IsInRole(Roles.Recertifier), + ModellingRelated: user.IsInRole(Roles.Modeller) + || user.IsInRole(Roles.Admin) + || user.IsInRole(Roles.Auditor) + || user.IsInRole(Roles.Recertifier), + ComplianceRelated: user.IsInRole(Roles.Admin) + || user.IsInRole(Roles.FwAdmin) + || user.IsInRole(Roles.Auditor), + OwnerRelated: user.IsInRole(Roles.Admin) + || user.IsInRole(Roles.FwAdmin) + || user.IsInRole(Roles.Auditor), + WorkflowRelated: user.IsInRole(Roles.Admin) + || user.IsInRole(Roles.FwAdmin) + || user.IsInRole(Roles.Auditor) + || user.IsInRole(Roles.Requester) + || user.IsInRole(Roles.Approver) + || user.IsInRole(Roles.Planner) + || user.IsInRole(Roles.Implementer) + || user.IsInRole(Roles.Reviewer)); + } + } + + public readonly record struct ReportVisibility(bool RuleRelated, bool ModellingRelated, bool ComplianceRelated, bool OwnerRelated, bool WorkflowRelated); +} diff --git a/roles/lib/files/FWO.Basics/SCConstants.cs b/roles/lib/files/FWO.Basics/SCConstants.cs new file mode 100644 index 0000000000..f81c4ba74b --- /dev/null +++ b/roles/lib/files/FWO.Basics/SCConstants.cs @@ -0,0 +1,10 @@ +namespace FWO.Basics +{ + public struct SCConstants + { + // If the API is called to open a ticket for a SecureApp application with more than 100 ARs, + // it must be split into multiple tickets of up to 100 ARs each. + public const int SCMaxBundledTasks = 100; + public const bool SCBundleGateways = true; + } +} diff --git a/roles/lib/files/FWO.Basics/StringExtensionsHtml.cs b/roles/lib/files/FWO.Basics/StringExtensionsHtml.cs new file mode 100644 index 0000000000..c4cd84ae89 --- /dev/null +++ b/roles/lib/files/FWO.Basics/StringExtensionsHtml.cs @@ -0,0 +1,52 @@ +using System; +using System.Collections.Generic; +using System.Text.RegularExpressions; + +namespace FWO.Basics +{ + public static partial class StringExtensions + { + + private const string HtmlTagPattern = "<[^>]*>"; + private static readonly HashSet SafeHtmlTags = new HashSet(["br", "i", "hr", "b", "u", "strong", "em", "p", "ul", "ol", "li", "span", "div"], StringComparer.Ordinal); + + + public static string StripDangerousHtmlTags(this string text, RegexOptions options = RegexOptions.None) + { + return Regex.Replace(text, HtmlTagPattern, StripIfDangerousTag, options, TimeSpan.FromMilliseconds(100)); + } + + public static string StripHtmlTags(this string text, RegexOptions options = RegexOptions.None) + { + return Regex.Replace(text, HtmlTagPattern, string.Empty, options, TimeSpan.FromMilliseconds(100)); + } + + private static string StripIfDangerousTag(Match tagMatch) + { + string tagName = ExtractTagName(tagMatch.Value); + return SafeHtmlTags.Contains(tagName) ? tagMatch.Value : string.Empty; + } + + private static string ExtractTagName(string tag) + { + if (string.IsNullOrEmpty(tag) || tag.Length < 3) + { + return string.Empty; + } + + int index = 1; + while (index < tag.Length && (tag[index] == '/' || char.IsWhiteSpace(tag[index]))) + { + index++; + } + + int start = index; + while (index < tag.Length && char.IsLetterOrDigit(tag[index])) + { + index++; + } + + return index > start ? tag[start..index] : string.Empty; + } + } +} diff --git a/roles/lib/files/FWO.Basics/StringExtensionsIp.cs b/roles/lib/files/FWO.Basics/StringExtensionsIp.cs new file mode 100644 index 0000000000..d27377d6cb --- /dev/null +++ b/roles/lib/files/FWO.Basics/StringExtensionsIp.cs @@ -0,0 +1,310 @@ + +using System.Net; +using System.Numerics; +using System.Net.Sockets; +using System.Text.RegularExpressions; +using NetTools; + +namespace FWO.Basics +{ + public static partial class StringExtensions + { + + public static int Compare(this string left, string right) + { + if (!IPAddress.TryParse(left?.Trim(), out var a)) + throw new ArgumentException("Invalid IP address: " + left, nameof(left)); + if (!IPAddress.TryParse(right?.Trim(), out var b)) + throw new ArgumentException("Invalid IP address: " + right, nameof(right)); + + var a16 = ToComparableBytes(a); + var b16 = ToComparableBytes(b); + + // Lexicographic compare, most-significant byte first (network byte order). + for (int i = 0; i < 16; i++) + { + int diff = a16[i].CompareTo(b16[i]); + if (diff != 0) return diff; + } + return 0; + } + + public static bool IsGreater(this string left, string right) => Compare(left, right) > 0; + + private static byte[] ToComparableBytes(IPAddress ip) + { + // Ensure a 16-byte representation: + // - IPv4 -> IPv6-mapped (::ffff:a.b.c.d) + // - IPv6 -> as-is + IPAddress v6 = ip.AddressFamily == AddressFamily.InterNetwork + ? ip.MapToIPv6() + : ip; + + var bytes = v6.GetAddressBytes(); // always 16 for IPv6 + if (bytes.Length != 16) + throw new InvalidOperationException("Expected a 16-byte IPv6 address after mapping."); + return bytes; + } + + public static bool GenerousCompare(this string? string1, string? string2) + { + return string.IsNullOrEmpty(string1) && string.IsNullOrEmpty(string2) || string1 == string2; + } + + [GeneratedRegex(@"(\/[\d\.\:]+)\D?")] + private static partial Regex NetmaskRegex(); + + + public static bool TrySplit(this string text, char separator, int index, out string output) + { + string[] splits = text.Split(separator); + + output = ""; + + if (splits.Length < 2 || splits.Length < index + 1) + return false; + + output = splits[index]; + + return true; + } + + public static bool TryGetNetmask(this string ip, out string netmask) + { + netmask = ""; + + Match match = NetmaskRegex().Match(ip); + + if (match.Success) + netmask = match.Groups[1].Value; + + return match.Success; + } + + public static bool TrySplit(this string text, char separator, out int length) + { + string[] splits = text.Split(separator); + + length = 0; + + if (splits.Length < 2) + return false; + + length = splits.Length; + + return true; + } + + public static bool CheckOverlap(this string ip1, string ip2) + { + return IpOperations.CheckOverlap(ip1, ip2); + } + + public static string GetNetmask(this string ip) + { + int pos = ip.LastIndexOf('/'); + if (pos > -1 && ip.Length > pos + 1) + { + return ip[(pos + 1)..]; + } + return ""; + } + + public static bool IsV6Address(this string ip) + { + return ip.Contains(':'); + } + + public static bool IsV4Address(this string ip) + { + return ip.Contains('.'); + } + + public static string StripOffNetmask(this string ip) + { + if (ip.TryGetNetmask(out string netmask)) + return ip.Replace(netmask, ""); + + return ip; + } + + public static string StripOffUnnecessaryNetmask(this string ip) + { + string netmask = ip.GetNetmask(); + if (ip.IsV4Address() && netmask == "32" || ip.IsV6Address() && netmask == "128") + { + return ip.StripOffNetmask(); + } + return ip; + } + + public static bool IsIPv4(this string ipAddress) + { + if (IPAddress.TryParse(ipAddress, out IPAddress? addr)) + { + if (addr.AddressFamily == AddressFamily.InterNetwork) + return true; + + return false; + } + + return false; + } + + public static bool IsIPv6(this string ipAddress) + { + if (IPAddress.TryParse(ipAddress, out IPAddress? addr)) + { + if (addr.AddressFamily == AddressFamily.InterNetworkV6) + return true; + + return false; + } + + return false; + } + + public static string IpAsCidr(this string ip) + { + return IPAddressRange.Parse(ip).ToCidrString(); + } + + public static string ToComparableIpString(this string ip) + { + return ip.IpAsCidr().PadLeft(43, '0'); // max length of an IPv6 CIDR string is 43 chars + } + + public static (string start, string end) CidrToRangeString(this string cidr) + { + IPAddress ipStart; + IPAddress ipEnd; + + (ipStart, ipEnd) = CidrToRange(cidr); + + return (ipStart.ToString(), ipEnd.ToString()); + } + + public static (IPAddress start, IPAddress end) CidrToRange(this string cidr) + { + string[] parts = cidr.Split('/'); + if (parts.Length != 2) + { + throw new FormatException("Invalid CIDR format."); + } + + var ip = IPAddress.Parse(parts[0]); + int prefixLength = int.Parse(parts[1]); + + var addressBytes = ip.GetAddressBytes(); + + if (addressBytes.Length == 4) + { + // IPv4 case + return IPv4CidrToRange(addressBytes, prefixLength); + } + else if (addressBytes.Length == 16) + { + // IPv6 case + return IPv6CidrToRange(addressBytes, prefixLength); + } + else + { + throw new FormatException("Invalid IP address format."); + } + } + + private static (IPAddress start, IPAddress end) IPv4CidrToRange(byte[] addressBytes, int prefixLength) + { + if (prefixLength is < 0 or > 32) + throw new ArgumentOutOfRangeException(nameof(prefixLength)); + + uint ipAddress = BitConverter.ToUInt32([.. addressBytes.Reverse()], 0); + + uint mask = prefixLength == 0 + ? 0u + : uint.MaxValue << (32 - prefixLength); + + uint startIp = ipAddress & mask; + uint endIp = startIp | ~mask; + + return (new IPAddress([.. BitConverter.GetBytes(startIp).Reverse()]), + new IPAddress([.. BitConverter.GetBytes(endIp).Reverse()])); + } + + + private static (IPAddress start, IPAddress end) IPv6CidrToRange(byte[] addressBytes, int prefixLength) + { + if (BitConverter.IsLittleEndian) + { + addressBytes = [.. addressBytes.Reverse()]; // Reverse byte array for BigInteger compatibility + } + + var addressBigInt = new BigInteger(addressBytes.Concat(new byte[] { 0 }).ToArray()); // Treat as unsigned + + var mask = BigInteger.Pow(2, 128) - BigInteger.Pow(2, 128 - prefixLength); // Compute mask + var startIpBigInt = addressBigInt & mask; // Apply mask for the start IP + var endIpBigInt = startIpBigInt | (~mask & BigInteger.Pow(2, 128) - 1); // Compute end IP + + var startIpBytes = startIpBigInt.ToByteArray(); + var endIpBytes = endIpBigInt.ToByteArray(); + + // Ensure the byte arrays are 16 bytes (128 bits) for IPv6 + startIpBytes = NormalizeBytes(startIpBytes, 16); + endIpBytes = NormalizeBytes(endIpBytes, 16); + + if (BitConverter.IsLittleEndian) + { + startIpBytes = [.. startIpBytes.Reverse()]; + endIpBytes = [.. endIpBytes.Reverse()]; + } + + return (new IPAddress(startIpBytes), new IPAddress(endIpBytes)); + } + + private static byte[] NormalizeBytes(byte[] bytes, int targetLength) + { + if (bytes.Length < targetLength) + { + // Pad the byte array to the required length + byte[] padded = new byte[targetLength]; + Array.Copy(bytes, padded, bytes.Length); + return padded; + } + return [.. bytes.Take(targetLength)]; // Ensure it's exactly targetLength bytes + } + + public static IEnumerable GetMatches(this string input, string pattern, string groupName) + { + return Regex.Matches(input, pattern) + .Cast() + .Select(m => m.Groups[groupName].Value); + } + + public static IEnumerable GetMatches(this string input, string pattern, int groupIndex) + { + return Regex.Matches(input, pattern) + .Cast() + .Select(m => m.Groups[groupIndex].Value); + } + + public static string ReplaceAll(this string input, IEnumerable values, string replacement) + { + foreach (string value in values) + { + input = input.Replace(value, replacement); + } + + return input; + } + /// + /// Parses a string to an IPAdress object and a string that represents the subnet mask (empty if there is no subnet mask). + /// + public static (IPAddress, string) ToIPAdressAndSubnetMask(this string str) + { + IPAddress ipAdress = IPAddress.Parse(str.StripOffNetmask()); + var hasSubnetMask = str.TryGetNetmask(out string subnetMask); + + return (ipAdress, hasSubnetMask ? subnetMask[1..] : ""); + } + } +} diff --git a/roles/lib/files/FWO.Basics/StringExtensionsLdap.cs b/roles/lib/files/FWO.Basics/StringExtensionsLdap.cs new file mode 100644 index 0000000000..01dc390dfb --- /dev/null +++ b/roles/lib/files/FWO.Basics/StringExtensionsLdap.cs @@ -0,0 +1,19 @@ +using System.Text.RegularExpressions; + +namespace FWO.Basics +{ + public static partial class StringExtensions + { + public static string ExtractCommonNameFromDn(this string dn) + { + if (string.IsNullOrWhiteSpace(dn)) + return string.Empty; + + var match = MyRegex().Match(dn); + return match.Success ? match.Groups[1].Value : string.Empty; + } + + [GeneratedRegex(@"CN=([^,]+)", RegexOptions.IgnoreCase)] + private static partial Regex MyRegex(); + } +} diff --git a/roles/lib/files/FWO.Basics/StringExtensionsSanitizer.cs b/roles/lib/files/FWO.Basics/StringExtensionsSanitizer.cs new file mode 100644 index 0000000000..e02e26ed5b --- /dev/null +++ b/roles/lib/files/FWO.Basics/StringExtensionsSanitizer.cs @@ -0,0 +1,206 @@ +using System.Text.RegularExpressions; + +namespace FWO.Basics +{ + public static partial class StringExtensions + { + public static string SanitizeMand(this string text) + { + bool shortened = false; + string output = SanitizeMand(text, ref shortened); + return output; + } + + public static string SanitizeMand(this string text, ref bool shortened) + { + string output = StandardSanitizationRegex().Replace(text, "").Trim(); + if (output.Length < text.Length) + { + shortened = true; + } + return output; + } + + public static string? SanitizeOpt(this string? text, ref bool shortened) + { + if (text != null) + { + return text.SanitizeMand(ref shortened); + } + else return null; + } + + public static string SanitizeLdapNameMand(this string input, ref bool shortened) + { + string output = LdapNameRegex().Replace(input, "").Trim(); + if (output.Length < input.Length) + { + shortened = true; + } + return output; + } + + public static string? SanitizeLdapNameOpt(this string? input, ref bool shortened) + { + if (input != null) + { + return input.SanitizeLdapNameMand(ref shortened); + } + else return null; + } + + public static string SanitizeLdapPathMand(this string input, ref bool shortened) + { + string output = LdapPathRegex().Replace(input, "").Trim(); + if (output.Length < input.Length) + { + shortened = true; + } + return output; + } + + public static string? SanitizeLdapPathOpt(this string? input, ref bool shortened) + { + if (input != null) + { + return input.SanitizeLdapPathMand(ref shortened); + } + else return null; + } + + public static string SanitizePasswMand(this string input, ref bool shortened) + { + string output = PasswdRegex().Replace(input, "").Trim(); + if (output.Length < input.Length) + { + shortened = true; + } + return output; + } + + public static string? SanitizePasswOpt(this string? input, ref bool shortened) + { + if (input != null) + { + return input.SanitizePasswMand(ref shortened); + } + else return null; + } + + public static string SanitizeKeyMand(this string input, ref bool shortened) + { + string output = input.Trim(); + if (output.Length < input.Length) + { + shortened = true; + } + return output; + } + + public static string? SanitizeKeyOpt(this string? input, ref bool shortened) + { + if (input != null) + { + return input.SanitizeKeyMand(ref shortened); + } + else return null; + } + + public static string SanitizeCommentMand(this string input, ref bool shortened) + { + string output = CommentRegex().Replace(input, "").Trim(); + string ignorableChangeCompareString = output + "\n"; + if (input != null && output.Length < input.Length && ignorableChangeCompareString != input) + { + shortened = true; + } + return output; + } + + public static string? SanitizeCommentOpt(this string? input, ref bool shortened) + { + if (input != null) + { + return input.SanitizeCommentMand(ref shortened); + } + else return null; + } + + public static string SanitizeCidrMand(this string input, ref bool shortened) + { + string output = CidrRegex().Replace(input, "").Trim(); + if (output.Length < input.Length) + { + shortened = true; + } + return output; + } + + public static string? SanitizeCidrOpt(this string? input, ref bool shortened) + { + if (input != null) + { + return input.SanitizeCidrMand(ref shortened); + } + else return null; + } + + public static string SanitizeJsonMand(this string input, ref bool shortened) + { + string output = JsonRegex().Replace(input, "").Trim(); + if (output.Length < input.Length) + { + shortened = true; + } + return output; + } + + public static string SanitizeJsonFieldMand(this string input, ref bool changed) + { + string output = JsonFieldRegex().Replace(input.Trim(), "_"); + if (output != input) + { + changed = true; + } + return output; + } + + public static string SanitizeEolMand(this string input, ref bool shortened) + { + string output = EolRegex().Replace(input, " ").Trim(); + if (output.Length < input.Length) + { + shortened = true; + } + return output; + } + + [GeneratedRegex(@"[^\w\.\*\-\:\?@/\(\)\[\]\{\}\$\+<>#\$ ]")] + private static partial Regex StandardSanitizationRegex(); + + [GeneratedRegex(@"[^\w\.\*\-\:\?@/\(\) ]")] + private static partial Regex LdapNameRegex(); + + [GeneratedRegex(@"[^\w\.\*\-\:\?@/\(\)\=\, \\]")] + private static partial Regex LdapPathRegex(); + + [GeneratedRegex(@"[^\S ]")] + private static partial Regex PasswdRegex(); + + [GeneratedRegex(@"[""'']")] + private static partial Regex CommentRegex(); + + [GeneratedRegex(@"[^a-fA-F0-9\.\:/]")] + private static partial Regex CidrRegex(); + + [GeneratedRegex(@"[^\S ]")] + private static partial Regex JsonRegex(); + + [GeneratedRegex(@"[\+\*\(\)\{\}\[\]\?\!#<>\=\,\;\/\\\t@\$\%\^\|\&\~ ]")] + private static partial Regex JsonFieldRegex(); + + [GeneratedRegex(@"[\n\r]")] + private static partial Regex EolRegex(); + + } +} diff --git a/roles/lib/files/FWO.Basics/TestDataGeneration/TestDataGenerationResult.cs b/roles/lib/files/FWO.Basics/TestDataGeneration/TestDataGenerationResult.cs new file mode 100644 index 0000000000..92dc39e0c9 --- /dev/null +++ b/roles/lib/files/FWO.Basics/TestDataGeneration/TestDataGenerationResult.cs @@ -0,0 +1,10 @@ +namespace FWO.Basics.TestDataGeneration +{ + public class TestDataGenerationResult + { + public bool ProcessSuccessful { get; set; } + public T? SingleInstance { get; set; } + public List? Collection { get; set; } + public T? SubjectUnderTest { get; set; } + } +} diff --git a/roles/lib/files/FWO.Basics/TestDataGeneration/TestDataGenerator.cs b/roles/lib/files/FWO.Basics/TestDataGeneration/TestDataGenerator.cs new file mode 100644 index 0000000000..029eff2e8f --- /dev/null +++ b/roles/lib/files/FWO.Basics/TestDataGeneration/TestDataGenerator.cs @@ -0,0 +1,230 @@ +using System.Reflection; +using System.Text.Json; +using System.Text.Json.Nodes; + +namespace FWO.Basics.TestDataGeneration +{ + public class TestDataGenerator where T : class, new() + { + public TestDataGenerationResult ImportInstance(string json) + { + TestDataGenerationResult result = new(); + + try + { + T? generatedInstance = DeserializeFromJson(json); + + if (generatedInstance != null) + { + result.SingleInstance = generatedInstance; + result.ProcessSuccessful = true; + } + else + { + result.ProcessSuccessful = false; + } + } + catch + { + result.ProcessSuccessful = false; + } + + return result; + } + + public TestDataGenerationResult GenerateInstance(string json) + { + TestDataGenerationResult result = new(); + + try + { + // create instance + + T instance = new(); + if (instance == null) + { + result.ProcessSuccessful = false; + return result; + } + + // get config as json array + + JsonNode? rootNode = JsonNode.Parse(json); + if (rootNode == null) + { + result.ProcessSuccessful = false; + return result; + } + + JsonArray? configArray = rootNode["config"]?.AsArray(); + if (configArray == null || configArray.Count == 0) + { + result.ProcessSuccessful = false; + return result; + } + + // loop over settings + + foreach (var item in configArray) + { + // get set object + if (item is JsonObject jsonObject + && jsonObject.TryGetPropertyValue("set", out JsonNode? setNode) + && setNode is JsonObject setObject) + { + KeyValuePair kvp = setObject.FirstOrDefault(); + + if (string.IsNullOrWhiteSpace(kvp.Key) || kvp.Value is null) + { + continue; + } + + if (kvp.Value is not JsonObject valueSettingsObject) + { + continue; + } + + string propertyName = kvp.Key; + Dictionary valuesWithProbabilities = new(); + + foreach (var valueSetting in valueSettingsObject) + { + if (valueSetting.Value != null) + { + valuesWithProbabilities[valueSetting.Key] = valueSetting.Value.GetValue(); + } + } + + string randomizedValue = GetRandomValueByProbability(valuesWithProbabilities); + + // get property + PropertyInfo? property = typeof(T).GetProperty(propertyName); + if (property == null) + { + throw new ArgumentException($"Property '{propertyName}' not found on type '{typeof(T)}'."); + } + + // validate that property can be set + if (!property.CanWrite) + { + throw new InvalidOperationException($"Property '{propertyName}' is read-only and cannot be set."); + } + + object convertedValue = Convert.ChangeType(randomizedValue, property.PropertyType); + property.SetValue(instance, convertedValue); + + } + } + + result.SingleInstance = instance; + result.ProcessSuccessful = true; + return result; + } + catch + { + result.ProcessSuccessful = false; + return result; + } + } + + + public void SetUpInstance(T instance, string json) + { + ArgumentNullException.ThrowIfNull(instance); + + try + { + JsonNode? rootNode = JsonNode.Parse(json); + if (rootNode == null) return; + + var configArray = rootNode["config"]?.AsArray(); + if (configArray == null || configArray.Count == 0) return; + + var setObject = configArray[0]?["set"]; + if (setObject is not JsonObject setObjectJson) return; + + var nameNode = setObjectJson["name"]; + if (nameNode is not JsonObject nameObject) return; + + // Zufällige Auswahl eines Namens basierend auf den Keys + var possibleNames = nameObject.Select(kvp => kvp.Key).ToList(); + if (possibleNames.Count == 0) return; + + Random random = new(); + string selectedName = possibleNames[random.Next(possibleNames.Count)]; + + // Instanz mit neuen Werten konfigurieren + var nameProperty = typeof(T).GetProperty("Name"); + if (nameProperty != null && nameProperty.PropertyType == typeof(string)) + { + nameProperty.SetValue(instance, selectedName); + } + } + catch + { + // Falls Fehler auftreten, keine Änderungen an der Instanz vornehmen + } + } + + private TDeserializedObject? DeserializeFromJson(string json) + { + bool isValidated = ValidateJson(json); + + if (isValidated) + { + TDeserializedObject? generatedInstance = JsonSerializer.Deserialize(json); + + if (generatedInstance != null) + { + return generatedInstance; + } + } + + throw new Exception(); + } + + private bool ValidateJson(string json) + { + try + { + JsonDocument jsonDoc = JsonDocument.Parse(json); + JsonElement rootElement = jsonDoc.RootElement; + + return true; + } + catch + { + return false; + } + } + + private static string GetRandomValueByProbability(Dictionary valuesWithProbabilities) + { + Random random = new(); + + // validates correct probability config + double total = valuesWithProbabilities.Values.Sum(); + if (total != 1) + { + throw new InvalidOperationException("The sum of the probabilities has to be equal 1."); + } + + double roll = random.NextDouble(); + double cumulative = 0; + string lastKey = string.Empty; + + foreach (KeyValuePair entry in valuesWithProbabilities) + { + cumulative += entry.Value; + lastKey = entry.Key; + if (roll <= cumulative) + { + return entry.Key; + } + } + + return lastKey; + } + } + +} diff --git a/roles/lib/files/FWO.Basics/TreeItem.cs b/roles/lib/files/FWO.Basics/TreeItem.cs new file mode 100644 index 0000000000..253b60765e --- /dev/null +++ b/roles/lib/files/FWO.Basics/TreeItem.cs @@ -0,0 +1,186 @@ +using System.Text.Json; +using System.Text.Json.Serialization; + +namespace FWO.Basics +{ + /// + /// A generic class to build tree structures. + /// + /// + public class TreeItem : ITreeItem + { + /// + /// Direct Children of this item. + /// + public List> Children { get; set; } = new(); + /// + /// A flat list of every tree item that is somewhere in the tree. + /// + public List> ElementsFlat { get; set; } = new(); + + /// + /// N-dimensional numeric indicator for the position of this item in the tree. + /// + public List? Position { get; set; } = new(); + /// + /// Direct parent of this tree item. + /// + public ITreeItem? Parent { get; set; } + /// + /// The last item that was added to the tree. + /// + public ITreeItem? LastAddedItem { get; set; } + /// + /// The object that is organized with its kins in the tree structure + /// + public TItem? Data { get; set; } + /// + /// An identifier for the object. + /// + public string? Identifier { get; set; } + + /// + /// Flag that indicates wether this is the root item of the tree. + /// + public bool IsRoot { get; set; } = false; + /// + /// A header for items that are organizational groups (like sections, or ordered layers for rules). + /// + public string Header { get; set; } = ""; + + /// + /// Returns the position as a dotted number of type string. + /// + public string GetPositionString() + { + if (Position != null) + { + return string.Join(".", Position); + } + else + { + return ""; + } + + } + + /// + /// Sets the position on the basis of a (dotted number) string. + /// + public void SetPosition(string orderNumberString) + { + Position = orderNumberString + .Split('.') + .Select(int.Parse) + .ToList(); + } + + /// + /// Adds an item to the tree. + /// + public virtual ITreeItem AddItem(ITreeItem? item = null, List? position = null, string header = "", bool isRoot = false, bool addToFlatList = false, bool addToChildren = false, bool setLastAddedItem = false) + { + ITreeItem newItem = item ?? new TreeItem(); + + newItem.Parent = this; + newItem.Position = position; + newItem.Header = header; + newItem.IsRoot = isRoot; + + if (addToFlatList) + { + ElementsFlat.Add(newItem); + } + + if (addToChildren) + { + Children.Add(newItem); + } + + if (setLastAddedItem) + { + LastAddedItem = newItem; + } + + return newItem; + } + + /// + /// Creates a json string for the structure, taking this item as the root. + /// + public string ToJson() + { + var rootNode = BuildSerializableNode(this); + + var options = new JsonSerializerOptions + { + WriteIndented = true + }; + + return JsonSerializer.Serialize(rootNode, options); + } + + /// + /// Creates items that can be serialized to a json. + /// + private SerializableTreeNode BuildSerializableNode(ITreeItem node) + { + var serializable = new SerializableTreeNode(); + + if (node.Identifier != null) + { + serializable.Identifier = node.Identifier; + } + + if (node.IsRoot == true) + { + serializable.IsRoot = true; + } + + if (node.Header != "") + { + serializable.Header = node.Header; + } + + if (node.Data != null) + { + serializable.Position = node.GetPositionString(); + } + + if (node.Children.Any()) + { + serializable.Children = new(); + + foreach (var child in node.Children) + { + serializable.Children.Add(BuildSerializableNode(child)); + } + } + + + return serializable; + } + + /// + /// Definition which data of the actual items are processed and how they are processed during serialization. + /// + private class SerializableTreeNode + { + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? Identifier { get; set; } + + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? IsRoot { get; set; } + + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? Header { get; set; } + + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? Position { get; set; } + + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public List? Children { get; set; } + } + + } +} diff --git a/roles/lib/files/FWO.Compliance/ComplianceCheck.cs b/roles/lib/files/FWO.Compliance/ComplianceCheck.cs new file mode 100644 index 0000000000..2dc6f51779 --- /dev/null +++ b/roles/lib/files/FWO.Compliance/ComplianceCheck.cs @@ -0,0 +1,1192 @@ +using FWO.Api.Client; +using FWO.Api.Client.Queries; +using FWO.Basics; +using FWO.Basics.Interfaces; +using FWO.Basics.Enums; +using FWO.Config.Api; +using FWO.Data; +using NetTools; +using FWO.Logging; +using FWO.Ui.Display; +using FWO.Data.Extensions; +using System.Net; +using System.Collections.Concurrent; +using FWO.Services; + +namespace FWO.Compliance +{ + /// + /// Provides the state and methods required to evaluate how well + /// firewall management rules comply with the defined compliance policy. + /// + /// The ComplianceCheck class encapsulates the logic used to analyze + /// rule configurations, identify deviations from policy requirements, + /// and deliver a structured assessment of compliance status. + /// + public class ComplianceCheck + { + #region Props & fields + + /// + /// Active policy that defines the compliance criteria. + /// + public CompliancePolicy? Policy = null; + + /// + /// Network zones to use for matrix compliance check. + /// + public List NetworkZones { get; set; } = []; + + /// + /// Wraps the static class FWO.Logging.Log to make it accessible for unit tests. + /// + public ILogger Logger { get; set; } = new Logger(); + + /// + /// Violations found in the last run of CheckAll. + /// + public List CurrentViolationsInCheck { get; private set; } = []; + + /// + /// Rules that are to be evaluated in the next run of CheckAll. + /// + public List? RulesInCheck { get; set; } = []; + + /// + /// Managements that are the subjects of the check. + /// + public List? Managements { get; set; } = []; + + /// + /// Access to API. + /// + private readonly ApiConnection _apiConnection; + /// + /// Access to user config. + /// + private readonly UserConfig _userConfig; + + /// + /// Parameter for treating domain and dynamic network objects as part of the auto-calculated internet zone. + /// + private bool _treatDomainAndDynamicObjectsAsInternet = false; + /// + /// True if the feature auto-calculated internet zone is activated. + /// + private bool _autoCalculatedInternetZoneActive = false; + /// + /// Id of the compliance policy that is configured for the check. + /// + private int _complianceCheckPolicyId = 0; + /// + /// Number of elements that are treated as a chunk in parallelized processes + /// + private int _elementsPerFetch; + /// + /// Limit of threads that may be used for the compliance check. + /// + private int _maxDegreeOfParallelism; + /// + /// Collection that is suitable for parallel processing and receives and holds insert arguments for newly found violations. + /// + private readonly ConcurrentBag _violationsToAdd = new(); + /// + /// Collection that is suitable for parallel processing and receives and holds remove arguments for deprecated violations. + /// + private readonly ConcurrentBag _violationsToRemove = new(); + /// + /// Collection that is suitable for parallel processing and receives and holds violations as a result of the current check. + /// + private readonly ConcurrentBag _currentViolations = new(); + /// + /// Multi-threading helper. + /// + private readonly ParallelProcessor _parallelProcessor; + + #endregion + + #region Ctor + + /// + /// Constructor for compliance check + /// + /// User configuration + /// Api connection + /// Log + public ComplianceCheck(UserConfig userConfig, ApiConnection apiConnection, ILogger? logger = null) + { + _apiConnection = apiConnection; + _userConfig = userConfig; + + if (logger != null) + { + Logger = logger; + } + + _parallelProcessor = new(apiConnection, Logger); + + if (_userConfig.GlobalConfig == null) + { + Logger.TryWriteInfo("Compliance Check", "Global config not found.", _userConfig.GlobalConfig == null); + } + + } + + #endregion + + #region Public Methods + /// + /// Executes a compliance check based on the provided . + /// + /// Specifies the type of compliance check to perform. + /// + /// When is , + /// the method first queries the system for existing violations. + /// If no violations are found, the full compliance check is treated as an initial run. + /// For or other types, + /// a standard full compliance check is performed without the initial flag. + /// + /// + /// A task representing the asynchronous operation. + /// + public async Task RunComplianceCheck(ComplianceCheckType complianceCheckType) + { + switch (complianceCheckType) + { + case ComplianceCheckType.Variable: + bool isInitial = false; + AggregateCount violationCount = await _apiConnection.SendQueryAsync(ComplianceQueries.getViolationCount); + if (violationCount.Aggregate.Count == 0) + { + isInitial = true; + } + await CheckAll(isInitial); + break; + case ComplianceCheckType.Standard: + default: + await CheckAll(); + break; + } + } + + /// + /// Evaluates the provided rules against all selected policies and returns true only if every selected policy passes. + /// + /// Compliance policy identifiers to evaluate. + /// Rules to check for compliance. + public async Task AreRulesCompliant(IEnumerable policyIds, IEnumerable rulesToCheck) + { + GlobalConfig? globalConfig = _userConfig.GlobalConfig; + if (globalConfig == null) + { + Logger.TryWriteInfo("Compliance Check", "Global config is necessary for compliance check, but was not found. Aborting compliance check.", true); + return false; + } + + List selectedPolicyIds = policyIds.Where(id => id > 0).Distinct().ToList(); + List selectedRules = rulesToCheck.Select(rule => new Rule(rule)).ToList(); + + if (selectedPolicyIds.Count == 0 || selectedRules.Count == 0) + { + return false; + } + + ApplyGlobalConfig(globalConfig); + Managements = await _apiConnection.SendQueryAsync>(DeviceQueries.getManagementNames); + + foreach (int policyId in selectedPolicyIds) + { + Policy = await _apiConnection.SendQueryAsync(ComplianceQueries.getPolicyById, new { id = policyId }); + if (Policy == null || Policy.Criteria.Count == 0) + { + return false; + } + + RulesInCheck = []; + CurrentViolationsInCheck.Clear(); + _currentViolations.Clear(); + await LoadNetworkZones(); + await CalculateCompliance(selectedRules.Select(rule => new Rule(rule)).ToList()); + CurrentViolationsInCheck = _currentViolations.ToList(); + + if (CurrentViolationsInCheck.Count > 0) + { + return false; + } + } + + return true; + } + + /// + /// Retrieves rules with violations from DB, calculates current violations, and prepares diff arguments. + /// + /// Management identifiers whose rules should be checked. + /// Whether this is part of an initial check + /// List of all rules that have been analyzed. + public async Task> PerformCheckAsync(List managementIds, bool isInitial = false) + { + // Getting max import id for query vars. + + long? maxImportId = 0; + + + Import? import = await _apiConnection.SendQueryAsync(ImportQueries.getMaxImportId); + + if (import != null && import.ImportAggregate != null && import.ImportAggregate.ImportAggregateMax != null) + { + maxImportId = import.ImportAggregate.ImportAggregateMax.RelevantImportId ?? 0; + + } + + // Getting total number of rules, for calculating chunks. + + AggregateCount? result = await _apiConnection.SendQueryAsync( + RuleQueries.countActiveRules, + new { mgm_ids = managementIds } + ); + int activeRulesCount = result?.Aggregate?.Count ?? 0; + + Logger.TryWriteInfo("Compliance Check", $"Loading {activeRulesCount} active rules in chunks of {_elementsPerFetch} for managements: {string.Join(",", managementIds)}.", LocalSettings.ComplianceCheckVerbose); + + // Retrieve rules and check current compliance for every rule. + + _parallelProcessor.SetUp(activeRulesCount, _maxDegreeOfParallelism, _elementsPerFetch); + + List[]? chunks = await _parallelProcessor.SendParallelizedQueriesAsync(RuleQueries.getRulesForSelectedManagements, CalculateCompliance, managementIds, maxImportId); + + if (chunks == null) + { + Logger.TryWriteInfo("Compliance Check", $"Chunks could not be loaded from the database.", LocalSettings.ComplianceCheckVerbose); + return []; + } + + Logger.TryWriteInfo("Compliance Check", $"Attempted to load {chunks.Length} chunks of rules.", LocalSettings.ComplianceCheckVerbose); + + List? rules = chunks + .SelectMany(rule => rule) + .ToList(); + + Logger.TryWriteInfo("Compliance Check", $"Loaded {rules.Count} rules.", LocalSettings.ComplianceCheckVerbose); + + CurrentViolationsInCheck = _currentViolations.ToList(); + + Logger.TryWriteInfo("Compliance Check", $"Found {CurrentViolationsInCheck.Count} violations.", LocalSettings.ComplianceCheckVerbose); + + Logger.TryWriteInfo("Compliance Check", $"Post-processing {rules.Count} rules.", LocalSettings.ComplianceCheckVerbose); + + // Create diffs and fill argument bags. + + await PostProcessRulesAsync(rules, isInitial); + + + return rules; + } + + /// + /// Creates insert/remove violation lists by comparing DB state with current check results. + /// + /// Rules including the violations persisted in the database. + /// Whether this is part of an initial check + public Task PostProcessRulesAsync(List ruleFromDb, bool isInitial = false) + { + List<(ComplianceViolation Violation, string Key)> dbViolationsWithKeys = ruleFromDb + .SelectMany(rule => rule.Violations) + .Select(violation => (violation, CreateUniqueViolationKey(violation))) + .ToList(); + + List<(ComplianceViolation Violation, string Key)> currentViolationsWithKeys = CurrentViolationsInCheck + .Select(violation => (violation, CreateUniqueViolationKey(violation))) + .ToList(); + + HashSet currentKeySet = currentViolationsWithKeys.Select(v => v.Key).ToHashSet(StringComparer.Ordinal); + HashSet dbKeySet = dbViolationsWithKeys.Select(v => v.Key).ToHashSet(StringComparer.Ordinal); + + ParallelOptions parallelOptions = new() + { + MaxDegreeOfParallelism = Math.Max(1, _maxDegreeOfParallelism) + }; + + // Get remove args. + + Logger.TryWriteInfo("Compliance Check", $"Getting violations to remove.", LocalSettings.ComplianceCheckVerbose); + + _violationsToRemove.Clear(); + + Parallel.ForEach( + dbViolationsWithKeys, + parallelOptions, + pair => + { + if (!currentKeySet.Contains(pair.Key)) + { + _violationsToRemove.Add(pair.Violation); + } + }); + + Logger.TryWriteInfo("Compliance Check", $"Got {_violationsToRemove.Count} violations to remove.", LocalSettings.ComplianceCheckVerbose); + + // Get insert args. + + Logger.TryWriteInfo("Compliance Check", $"Getting violations to insert.", LocalSettings.ComplianceCheckVerbose); + + _violationsToAdd.Clear(); + + Parallel.ForEach( + currentViolationsWithKeys, + parallelOptions, + pair => + { + if (!dbKeySet.Contains(pair.Key)) + { + ComplianceViolationBase violationBase = ComplianceViolationBase.CreateBase(pair.Violation, isInitial); + _violationsToAdd.Add(violationBase); + } + }); + + Logger.TryWriteInfo("Compliance Check", $"Got {_violationsToAdd.Count} violations to insert.", LocalSettings.ComplianceCheckVerbose); + + return Task.CompletedTask; + } + + /// + /// Updates the violation db table. + /// + public async Task PersistDataAsync() + { + try + { + Logger.TryWriteInfo("Compliance Check", "Persisting violations.", true); + + if (_violationsToAdd.Count == 0) + { + Logger.TryWriteInfo("Compliance Check", "No new violations to persist.", LocalSettings.ComplianceCheckVerbose); + } + else + { + List violations = _violationsToAdd.ToList(); + object variablesAdd = new + { + violations + }; + + await _apiConnection.SendQueryAsync(ComplianceQueries.addViolations, variablesAdd); + + Logger.TryWriteInfo("Compliance Check", $"Persisted {_violationsToAdd.Count} new violations.", LocalSettings.ComplianceCheckVerbose); + } + + List ids = _violationsToRemove.Select(violation => violation.Id).ToList(); + + if (ids.Count == 0) + { + Logger.TryWriteInfo("Compliance Check", "No violations to remove.", LocalSettings.ComplianceCheckVerbose); + } + else + { + Logger.TryWriteInfo("Compliance Check", $"{ids.Count} violations to remove.", LocalSettings.ComplianceCheckVerbose); + + DateTime removedAt = DateTime.UtcNow; + + object variablesRemove = new + { + ids, + removedAt + }; + + await _apiConnection.SendQueryAsync(ComplianceQueries.removeViolations, variablesRemove); + + Logger.TryWriteInfo("Compliance Check", $"Removed {ids.Count} violations.", LocalSettings.ComplianceCheckVerbose && ids.Count > 0); + } + + Logger.TryWriteInfo("Compliance Check", "Persisting of violations completed.", true); + } + catch (Exception e) + { + Logger.TryWriteError("ComplianceCheck - PersistDataAsync", e, true); + } + } + + /// + /// Checks whether a rule can be assessed, i.e. contains only evaluable network objects. + /// + /// Rule that is currently under test. + /// Fully resolved source objects. + /// Fully resolved destination objects. + /// Compliance criterion for assessability. + /// True if the rule can be assessed, otherwise false. + public Task CheckAssessability(Rule rule, List resolvedSources, List resolvedDestinations, ComplianceCriterion criterion) + { + bool isAssessable = true; + + // If treated as part of internet zone dynamic and domain objects are irrelevant for the assessability check. + + resolvedSources = TryFilterDynamicAndDomainObjects(resolvedSources); + resolvedDestinations = TryFilterDynamicAndDomainObjects(resolvedDestinations); + + // Check only accept rules for assessability. + + if (rule.Action == RuleActions.Accept) + { + foreach (NetworkObject networkObject in resolvedSources.Concat(resolvedDestinations)) + { + // Get assessability issue type if existing. + + AssessabilityIssue? assessabilityIssue = TryGetAssessabilityIssue(networkObject); + + if (assessabilityIssue != null) + { + // Create check result object. + + ComplianceCheckResult complianceCheckResult; + + if (resolvedSources.Contains(networkObject)) + { + complianceCheckResult = new(rule, ComplianceViolationType.NotAssessable) + { + Source = networkObject + }; + } + else + { + complianceCheckResult = new(rule, ComplianceViolationType.NotAssessable) + { + Destination = networkObject + }; + } + + complianceCheckResult.AssessabilityIssue = assessabilityIssue; + complianceCheckResult.Criterion = criterion; + + // Create violation. + + CreateViolation(ComplianceViolationType.NotAssessable, rule, complianceCheckResult); + isAssessable = false; + } + } + } + + return Task.FromResult(isAssessable); + } + + /// + /// Evaluates a rule against all configured compliance criteria. + /// + /// Rule whose compliance should be checked. + /// Set of criteria derived from the policy. + /// True if the rule is compliant with every criterion. + public async Task CheckRuleCompliance(Rule rule, IEnumerable criteria) + { + bool ruleIsCompliant = true; + + if (rule.Action == RuleActions.Accept) + { + // Resolve network locations + + NetworkLocation[] networkLocations = rule.Froms.Concat(rule.Tos).ToArray(); + List resolvedNetworkLocations = RuleDisplayBase.GetResolvedNetworkLocations(networkLocations); + + List resolvedSources = RuleDisplayBase + .GetResolvedNetworkLocations(rule.Froms) + .Select(from => from.Object) + .ToList(); + + List resolvedDestinations = RuleDisplayBase + .GetResolvedNetworkLocations(rule.Tos) + .Select(to => to.Object) + .ToList(); + + try + { + foreach (var criterion in criteria) + { + switch (criterion.CriterionType) + { + case nameof(CriterionType.Assessability): + ruleIsCompliant &= CheckAssessability(rule, resolvedSources, resolvedDestinations, criterion).Result; + break; + case nameof(CriterionType.Matrix): + ruleIsCompliant &= await CheckMatrixCompliance(rule, criterion, resolvedSources, resolvedDestinations); + break; + case nameof(CriterionType.ForbiddenService): + ruleIsCompliant &= CheckForForbiddenService(rule, criterion); + break; + default: + break; + } + } + } + catch (System.Exception e) + { + Logger.TryWriteError("Compliance Check", e, true); + } + + } + + return ruleIsCompliant; + } + + /// + /// Extracts the IP ranges represented by a network object in all supported forms. + /// + /// Network object to parse. + /// List of ranges (empty if parsing is not possible). + public static List ParseIpRange(NetworkObject networkObject) + { + List ranges = []; + + if (networkObject.Type.Name == ObjectType.IPRange || (networkObject.Type.Name == ObjectType.Network && networkObject.IP.Equals(networkObject.IpEnd) == false)) + { + if (IPAddress.TryParse(networkObject.IP.StripOffNetmask(), out IPAddress? ipStart) && IPAddress.TryParse(networkObject.IpEnd.StripOffNetmask(), out IPAddress? ipEnd)) + { + ranges.Add(new IPAddressRange(ipStart, ipEnd)); + } + } + else if (networkObject.Type.Name != ObjectType.Group && networkObject.ObjectGroupFlats.Length > 0) + { + for (int j = 0; j < networkObject.ObjectGroupFlats.Length; j++) + { + if (networkObject.ObjectGroupFlats[j].Object != null) + { + ranges.AddRange(ParseIpRange(networkObject.ObjectGroupFlats[j].Object!)); + } + } + } + else if (networkObject.IP != null) + { + // CIDR notation or single (host) IP can be parsed directly + ranges.Add(IPAddressRange.Parse(networkObject.IP)); + } + + return ranges; + } + + /// + /// Compliance check used in current UI implementation. + /// + /// Source range provided by the UI. + /// Destination range provided by the UI. + /// Network zones to test against the provided ranges. + /// List of forbidden communications found by the matrix check. + public List<(ComplianceNetworkZone, ComplianceNetworkZone)> CheckIpRangeInputCompliance(IPAddressRange? sourceIpRange, IPAddressRange? destinationIpRange, List networkZones) + { + NetworkZones = networkZones; + List<(ComplianceNetworkZone, ComplianceNetworkZone)> forbiddenCommunicationsOutput = []; + + if (sourceIpRange != null && destinationIpRange != null) + { + CheckMatrixCompliance + ( + [sourceIpRange], + [destinationIpRange], + out forbiddenCommunicationsOutput + ); + } + + return forbiddenCommunicationsOutput; + } + + /// + /// Filters the provided managements so that only the configured IDs remain. + /// + /// Global configuration containing the ID list. + /// All managements retrieved from the API. + /// Subset of managements that are relevant for the compliance check. + public static List GetRelevantManagements(GlobalConfig globalConfig, List managements) + { + List? filteredManagements = []; + List relevantManagementIDs = []; + + if (!string.IsNullOrEmpty(globalConfig.ComplianceCheckRelevantManagements)) + { + try + { + relevantManagementIDs = globalConfig.ComplianceCheckRelevantManagements + .Split(',', StringSplitOptions.RemoveEmptyEntries) + .Select(s => int.Parse(s.Trim())) + .ToList(); + + filteredManagements = managements.Where(m => relevantManagementIDs.Contains(m.Id)).ToList(); + + } + catch (Exception e) + { + Log.TryWriteLog(LogType.Error, "Compliance Report", $"Error while parsing relevant management IDs: {e.Message}", LocalSettings.ComplianceCheckVerbose); + } + } + + return filteredManagements; + } + #endregion + + #region Private Methods + + /// + /// Full compliance check + /// + /// Task that completes when the asynchronous compliance evaluation finished. + private async Task CheckAll(bool isInitial = false) + { + DateTime startTime = DateTime.UtcNow; + + try + { + // Gathering necessary parameters for compliance check. + + Logger.TryWriteInfo("Compliance Check", "Starting compliance check.", true); + + GlobalConfig? globalConfig = _userConfig.GlobalConfig; + + if (globalConfig == null) + { + Logger.TryWriteInfo("Compliance Check", "Global config is necessary for compliance check, but was not found. Aborting compliance check.", true); + return; + } + + _complianceCheckPolicyId = globalConfig.ComplianceCheckPolicyId; + ApplyGlobalConfig(globalConfig); + + Logger.TryWriteInfo("Compliance Check", $"Parallelizing config: {_elementsPerFetch} elements per fetch and {_maxDegreeOfParallelism} processors.", LocalSettings.ComplianceCheckVerbose); + + if (_complianceCheckPolicyId == 0) + { + Logger.TryWriteInfo("Compliance Check", "No Policy defined. Compliance check not possible.", true); + return; + } + + Policy = await _apiConnection.SendQueryAsync(ComplianceQueries.getPolicyById, new { id = _complianceCheckPolicyId }); + + if (Policy == null) + { + Logger.TryWriteError("Compliance Check", $"Policy with id {_complianceCheckPolicyId} not found.", true); + return; + } + + Managements = await _apiConnection.SendQueryAsync>(DeviceQueries.getManagementNames); + Managements = GetRelevantManagements(globalConfig, Managements); + + if (Managements == null || Managements.Count == 0) + { + Logger.TryWriteInfo("Compliance Check", "No relevant managements found. Compliance check not possible.", true); + return; + } + + Logger.TryWriteInfo("Compliance Check", $"Using policy {_complianceCheckPolicyId}", LocalSettings.ComplianceCheckVerbose); + + Logger.TryWriteInfo("Compliance Check", $"Policy criteria: {Policy.Criteria.Count} criteria found.", LocalSettings.ComplianceCheckVerbose); + + if (Policy.Criteria.Count == 0) + { + Logger.TryWriteInfo("Compliance Check", $"Policy without criteria. Compliance check not possible.", LocalSettings.ComplianceCheckVerbose); + return; + } + + foreach (var criterion in Policy.Criteria) + { + Logger.TryWriteInfo("Compliance Check", $"Criterion: {criterion.Content.Name} ({criterion.Content.CriterionType}).", LocalSettings.ComplianceCheckVerbose); + } + + // Clear previous check data + + RulesInCheck = []; + CurrentViolationsInCheck.Clear(); + _currentViolations.Clear(); + + // Load data for evaluation. + + await LoadNetworkZones(); + + // Perform check. + + RulesInCheck = await PerformCheckAsync(Managements!.Select(m => m.Id).ToList(), isInitial); + + if (RulesInCheck == null || RulesInCheck.Count == 0) + { + Logger.TryWriteInfo("Compliance Check", "No relevant rules found. Compliance check not possible.", true); + return; + } + + TimeSpan elapsed = DateTime.UtcNow - startTime; + + Logger.TryWriteInfo("Compliance Check", $"Compliance check evaluated {RulesInCheck.Count} rules in {elapsed.TotalSeconds} seconds.", true); + Logger.TryWriteInfo("Compliance Check", "Compliance check completed.", true); + + } + catch (Exception e) + { + TimeSpan elapsed = DateTime.UtcNow - startTime; + Logger.TryWriteInfo("Compliance Check", $"Compliance check failed after {elapsed.TotalSeconds} seconds.", true); + Logger.TryWriteError("Compliance Check", e, true); + } + + } + + private void ApplyGlobalConfig(GlobalConfig globalConfig) + { + _autoCalculatedInternetZoneActive = globalConfig.AutoCalculateInternetZone; + _treatDomainAndDynamicObjectsAsInternet = globalConfig.TreatDynamicAndDomainObjectsAsInternet; + _elementsPerFetch = globalConfig.ComplianceCheckElementsPerFetch; + _maxDegreeOfParallelism = globalConfig.ComplianceCheckAvailableProcessors; + } + + /// + /// Performs the matrix compliance check for a rule by mapping resolved objects to zones. + /// + /// Rule under test. + /// Matrix criterion. + /// Resolved source objects. + /// Resolved destination objects. + private async Task CheckMatrixCompliance(Rule rule, ComplianceCriterion criterion, List resolvedSources, List resolvedDestinations) + { + Task ipRanges)>> fromsTask = GetNetworkObjectsWithIpRanges(resolvedSources); + Task ipRanges)>> tosTask = GetNetworkObjectsWithIpRanges(resolvedDestinations); + + await Task.WhenAll(fromsTask, tosTask); + + bool ruleIsCompliant = true; + + List<(NetworkObject networkObject, List networkZones)> sourceZones = MapZonesToNetworkObjects(fromsTask.Result); + List<(NetworkObject networkObject, List networkZones)> destinationZones = MapZonesToNetworkObjects(tosTask.Result); + + Dictionary> sourceObjectsByZone = MapObjectsByZone(sourceZones); + Dictionary> destinationObjectsByZone = MapObjectsByZone(destinationZones); + + foreach ((ComplianceNetworkZone sourceZone, List sourceObjects) in sourceObjectsByZone) + { + foreach ((ComplianceNetworkZone destinationZone, List destinationObjects) in destinationObjectsByZone) + { + if (!sourceZone.CommunicationAllowedTo(destinationZone)) + { + ruleIsCompliant = false; + string sourceObjectsString = string.Join(", ", sourceObjects.Select(GetNwObjectString).Distinct()); + string destinationObjectsString = string.Join(", ", destinationObjects.Select(GetNwObjectString).Distinct()); + + string details = $"{_userConfig.GetText("H5839")}: {sourceZone.Name} ({sourceObjectsString}) -> {destinationZone.Name} ({destinationObjectsString})"; + + ComplianceCheckResult complianceCheckResult = new(rule, ComplianceViolationType.MatrixViolation) + { + Criterion = criterion, + SourceZone = sourceZone, + DestinationZone = destinationZone + }; + + CreateViolation(ComplianceViolationType.MatrixViolation, rule, complianceCheckResult, details); + } + } + } + + return ruleIsCompliant; + } + + /// + /// Creates a violation entry from a compliance check result and stores it in the current run buffer. + /// + /// Type of violation to record. + /// Impacted rule. + /// Details assembled during the check. + /// Optional string used if details need to be customized. + private void CreateViolation(ComplianceViolationType violationType, Rule rule, ComplianceCheckResult complianceCheckResult, string? detailsOverride = null) + { + ComplianceViolation violation = new() + { + RuleId = (int)rule.Id, + RuleUid = rule.Uid ?? "", + MgmtUid = Managements?.FirstOrDefault(m => m.Id == rule.MgmtId)?.Uid ?? "", + PolicyId = Policy?.Id ?? 0, + CriterionId = complianceCheckResult.Criterion!.Id + }; + + switch (violationType) + { + case ComplianceViolationType.MatrixViolation: + + if (!string.IsNullOrEmpty(detailsOverride)) + { + violation.Details = detailsOverride; + } + else if (complianceCheckResult.Source is NetworkObject s && complianceCheckResult.Destination is NetworkObject d) + { + string sourceString = GetNwObjectString(s); + string destinationString = GetNwObjectString(d); + violation.Details = $"{_userConfig.GetText("H5839")}: {sourceString} (Zone: {complianceCheckResult.SourceZone?.Name ?? ""}) -> {destinationString} (Zone: {complianceCheckResult.DestinationZone?.Name ?? ""})"; + } + + break; + + case ComplianceViolationType.ServiceViolation: + + if (complianceCheckResult.Service is NetworkService svc) + { + violation.Details = $"{_userConfig.GetText("H5840")}: {svc.Name}"; + } + else + { + throw new ArgumentNullException(paramName: "complianceCheckResult.Service", message: "The service argument must be non-null when creating a service violation."); + } + + break; + + case ComplianceViolationType.NotAssessable: + + if (complianceCheckResult.AssessabilityIssue != null) + { + string networkObject = ""; + + if (complianceCheckResult.Source != null) + { + networkObject = GetNwObjectString(complianceCheckResult.Source); + } + else if (complianceCheckResult.Destination != null) + { + networkObject = GetNwObjectString(complianceCheckResult.Destination); + } + + string assessabilityIssueType = complianceCheckResult.AssessabilityIssue.Value.ToAssessabilityIssueString(); + + violation.Details = $"{_userConfig.GetText("H5841")}: {_userConfig.GetText(assessabilityIssueType)}({networkObject})"; + } + + break; + + default: + + return; + } + + _currentViolations.Add(violation); + } + + /// + /// Returns a readable representation of a network object including its IP range. + /// + /// Network object to display. + private string GetNwObjectString(NetworkObject networkObject) + { + string networkObjectString = ""; + + networkObjectString += networkObject.Name; + networkObjectString += NwObjDisplay.DisplayIp(networkObject.IP, networkObject.IpEnd, networkObject.Type.Name, true); + + return networkObjectString; + } + + /// + /// Checks two IP range sets against the network zone matrix. + /// + /// Source ranges. + /// Destination ranges. + /// Output list of forbidden zone combinations. + private bool CheckMatrixCompliance(List source, List destination, out List<(ComplianceNetworkZone, ComplianceNetworkZone)> forbiddenCommunication) + { + // Determine all matching source zones + List sourceZones = DetermineZones(source); + + // Determine all matching destination zones + List destinationZones = DetermineZones(destination); + + forbiddenCommunication = []; + + foreach (ComplianceNetworkZone sourceZone in sourceZones) + { + foreach (ComplianceNetworkZone destinationZone in destinationZones.Where(d => !sourceZone.CommunicationAllowedTo(d))) + { + forbiddenCommunication.Add((sourceZone, destinationZone)); + } + } + + return forbiddenCommunication.Count == 0; + } + + /// + /// Validates whether a rule uses a service forbidden by the given criterion. + /// + /// Rule that may contain forbidden services. + /// Criterion defining the restricted service set. + private bool CheckForForbiddenService(Rule rule, ComplianceCriterion criterion) + { + bool ruleIsCompliant = true; + + List restrictedServices = [.. criterion.Content.Split(',').Select(s => s.Trim()) + .Where(s => !string.IsNullOrEmpty(s))]; + + if (restrictedServices.Count > 0) + { + foreach (var service in rule.Services.Where(s => restrictedServices.Contains(s.Content.Uid))) + { + ComplianceCheckResult complianceCheckResult = new(rule, ComplianceViolationType.ServiceViolation) + { + Criterion = criterion, + Service = service.Content + }; + + CreateViolation(ComplianceViolationType.ServiceViolation, rule, complianceCheckResult); + ruleIsCompliant = false; + } + } + + return ruleIsCompliant; + } + + /// + /// Builds a helper structure combining network objects with the IP ranges they represent. + /// + /// Objects that should be resolved to ranges. + private static Task ipRanges)>> GetNetworkObjectsWithIpRanges(List networkObjects) + { + List<(NetworkObject networkObject, List ipRanges)> networkObjectsWithIpRange = []; + + foreach (NetworkObject networkObject in networkObjects) + { + networkObjectsWithIpRange.Add((networkObject, ParseIpRange(networkObject))); + } + + return Task.FromResult(networkObjectsWithIpRange); + } + + + /// + /// Loads all network zones referenced by the policy matrix criterion. + /// + private async Task LoadNetworkZones() + { + if (Policy != null) + { + // ToDo later: work with several matrices? + int? matrixId = Policy.Criteria.FirstOrDefault(c => c.Content.CriterionType == CriterionType.Matrix.ToString())?.Content.Id; + if (matrixId != null) + { + Logger.TryWriteInfo("Compliance Check", $"Loading network zones for Matrix {matrixId}.", LocalSettings.ComplianceCheckVerbose); + NetworkZones = await _apiConnection.SendQueryAsync>(ComplianceQueries.getNetworkZonesForMatrix, new { criterionId = matrixId }); + Logger.TryWriteInfo("Compliance Check", $"Loaded {NetworkZones.Count} network zones for Matrix {matrixId}.", LocalSettings.ComplianceCheckVerbose); + } + } + } + + + /// + /// Builds a unique key identifying a violation over management, rule, policy, criterion, and detail. + /// + private string CreateUniqueViolationKey(ComplianceViolation violation) + { + string key = ""; + + try + { + key = $"{violation.MgmtUid}_{violation.RuleUid}_{violation.PolicyId}_{violation.CriterionId}_{violation.Details}"; + } + catch (Exception e) + { + Logger.TryWriteError("Compliance Check", e, true); + } + + return key; + } + + /// + /// Calculates compliance for all provided rules (or the rules from the last check) and stores violations. + /// + /// Explicit set of rules; when null, the rules prepared by are used. + /// List of rules that have been processed. + public async Task> CalculateCompliance(List? rulesToCheck = null) + { + List rules = rulesToCheck ?? RulesInCheck ?? []; + + int nonCompliantRules = 0; + int checkedRules = 0; + + Logger.TryWriteInfo("Compliance Check", $"Checking compliance for {rules.Count} rules.", LocalSettings.ComplianceCheckVerbose); + + if (Policy == null || Policy.Criteria == null) + { + Logger.TryWriteError("Compliance Check", $"Checking compliance for rules not possible, because criteria could not be loaded.", true); + return await Task.FromResult(rules); + } + + if (Policy.Criteria.Count == 0) + { + Logger.TryWriteError("Compliance Check", $"Checking compliance for rules not possible, because policy does not contain criteria.", true); + return await Task.FromResult(rules); + } + + List criteria = Policy.Criteria.Select(c => c.Content).ToList(); + + if (criteria.Count == 0) + { + Logger.TryWriteError("Compliance Check", $"Checking compliance for rules not possible, because criteria were malformed.", true); + return await Task.FromResult(rules); + } + + Logger.TryWriteInfo("Compliance Check", $"Checking compliance for {Policy.Criteria.Count} criteria.", LocalSettings.ComplianceCheckVerbose); + + foreach (Rule rule in rules) + { + bool ruleIsCompliant = await CheckRuleCompliance(rule, criteria); + + if (!ruleIsCompliant) + { + nonCompliantRules++; + } + + checkedRules++; + } + + Logger.TryWriteInfo("Compliance Check", $"Checked compliance for {checkedRules} rules and found {nonCompliantRules} non-compliant rules. Total violations: {_currentViolations.Count}.", LocalSettings.ComplianceCheckVerbose); + return await Task.FromResult(rules); + } + + /// + /// Maps previously resolved IP ranges to their matching compliance zones. + /// + /// Pairs of network objects and IP ranges. + private List<(NetworkObject networkObject, List networkZones)> MapZonesToNetworkObjects(List<(NetworkObject networkObject, List ipRanges)> inputData) + { + List<(NetworkObject networkObject, List networkZones)> map = []; + + foreach ((NetworkObject networkObject, List ipRanges) dataItem in inputData) + { + List networkZones = []; + + if (_autoCalculatedInternetZoneActive && _treatDomainAndDynamicObjectsAsInternet && (dataItem.networkObject.Type.Name == "dynamic_net_obj" || dataItem.networkObject.Type.Name == "domain")) + { + List complianceNetworkZones = NetworkZones.Where(zone => zone.IsAutoCalculatedInternetZone).ToList(); + + foreach (ComplianceNetworkZone zone in complianceNetworkZones) + { + networkZones.Add(zone); + } + } + else if (dataItem.ipRanges.Count > 0) + { + if (TryGetAssessabilityIssue(dataItem.networkObject) != null) + { + continue; + } + + networkZones = DetermineZones(dataItem.ipRanges); + } + + map.Add((dataItem.networkObject, networkZones)); + } + + return map; + } + + /// + /// Groups network objects by their associated compliance zone. + /// + /// Network objects enriched by their zones. + private Dictionary> MapObjectsByZone(List<(NetworkObject networkObject, List networkZones)> objectsWithZones) + { + Dictionary> map = new(); + + foreach ((NetworkObject networkObject, List networkZones) item in objectsWithZones) + { + if (item.networkZones == null || item.networkZones.Count == 0) + { + continue; + } + + foreach (ComplianceNetworkZone zone in item.networkZones) + { + if (!map.TryGetValue(zone, out List? objectsInZone)) + { + objectsInZone = []; + map.Add(zone, objectsInZone); + } + + objectsInZone.Add(item.networkObject); + } + } + + return map; + } + + /// + /// Finds every compliance zone overlapped by the provided IP ranges (plus implicit internet zone when necessary). + /// + /// Ranges to look up. + private List DetermineZones(List ranges) + { + List result = []; + List> unseenIpAddressRanges = []; + + for (int i = 0; i < ranges.Count; i++) + { + unseenIpAddressRanges.Add( + [ + new(ranges[i].Begin, ranges[i].End) + ]); + } + + foreach (ComplianceNetworkZone zone in NetworkZones.Where(z => z.OverlapExists(ranges, unseenIpAddressRanges))) + { + result.Add(zone); + } + + // No need to proceed if auto calculated internet zone is activated. + + if (_autoCalculatedInternetZoneActive) + { + return result; + } + + // Get ip ranges that are not in any zone + + List undefinedIpRanges = [.. unseenIpAddressRanges.SelectMany(x => x)]; + + if (undefinedIpRanges.Count > 0) + { + result.Add + ( + new ComplianceNetworkZone() + { + Name = _userConfig.GetText("internet_local_zone"), + } + ); + } + + return result; + } + + /// + /// Removes dynamic/domain objects when the feature treats them implicitly as internet. + /// + /// Network objects to filter. + private List TryFilterDynamicAndDomainObjects(List networkObjects) + { + if (_userConfig.GlobalConfig is GlobalConfig globalConfig && globalConfig.AutoCalculateInternetZone && globalConfig.TreatDynamicAndDomainObjectsAsInternet) + { + networkObjects = networkObjects + .Where(n => !new List { "domain", "dynamic_net_obj" }.Contains(n.Type.Name)) + .ToList(); + } + + return networkObjects; + } + + /// + /// Detects assessability issues (like overly broad objects) for a given network object. + /// + /// Network object to evaluate. + private AssessabilityIssue? TryGetAssessabilityIssue(NetworkObject networkObject) + { + if (networkObject.IP == null && networkObject.IpEnd == null) + return AssessabilityIssue.IPNull; + + if (networkObject.IP == "0.0.0.0/32" && networkObject.IpEnd == "255.255.255.255/32") + return AssessabilityIssue.AllIPs; + + if (networkObject.IP == "::/128" && networkObject.IpEnd == "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff/128") + return AssessabilityIssue.AllIPs; + + if (networkObject.IP == "255.255.255.255/32" && networkObject.IpEnd == "255.255.255.255/32") + return AssessabilityIssue.Broadcast; + + if (networkObject.IP == "0.0.0.0/32" && networkObject.IpEnd == "0.0.0.0/32") + return AssessabilityIssue.HostAddress; + + return null; + } + + #endregion + } +} diff --git a/roles/lib/files/FWO.Compliance/ComplianceCheckResult.cs b/roles/lib/files/FWO.Compliance/ComplianceCheckResult.cs new file mode 100644 index 0000000000..bd0b9667ad --- /dev/null +++ b/roles/lib/files/FWO.Compliance/ComplianceCheckResult.cs @@ -0,0 +1,28 @@ +using FWO.Basics.Enums; +using FWO.Data; + +namespace FWO.Compliance +{ + public class ComplianceCheckResult + { + public Rule Rule { get; set; } + public ComplianceViolationType Compliance { get; set; } + + public ComplianceCriterion? Criterion { get; set; } + + public NetworkObject? Source { get; set; } + public ComplianceNetworkZone? SourceZone { get; set; } + public NetworkObject? Destination { get; set; } + public ComplianceNetworkZone? DestinationZone { get; set; } + public NetworkService? Service { get; set; } + public AssessabilityIssue? AssessabilityIssue { get; set; } + + public ComplianceCheckResult(Rule rule, ComplianceViolationType compliance = ComplianceViolationType.None) + { + Rule = rule; + Compliance = compliance; + } + + } + +} diff --git a/roles/lib/files/FWO.Compliance/ComplianceRequestedRulePolicyChecker.cs b/roles/lib/files/FWO.Compliance/ComplianceRequestedRulePolicyChecker.cs new file mode 100644 index 0000000000..e4f30fb860 --- /dev/null +++ b/roles/lib/files/FWO.Compliance/ComplianceRequestedRulePolicyChecker.cs @@ -0,0 +1,155 @@ +using FWO.Api.Client; +using FWO.Basics; +using FWO.Config.Api; +using FWO.Data; +using FWO.Data.Workflow; +using FWO.Services.Workflow; + +namespace FWO.Compliance +{ + public class ComplianceRequestedRulePolicyChecker(UserConfig userConfig, ApiConnection apiConnection) : IRequestedRulePolicyChecker + { + public async Task AreRequestTasksCompliant(IEnumerable policyIds, IEnumerable requestTasks) + { + List selectedPolicyIds = policyIds.Where(id => id > 0).Distinct().ToList(); + List rules = BuildRulesFromRequestTasks(requestTasks); + if (selectedPolicyIds.Count == 0 || rules.Count == 0) + { + return false; + } + + ComplianceCheck complianceCheck = new(userConfig, apiConnection); + return await complianceCheck.AreRulesCompliant(selectedPolicyIds, rules); + } + + private static List BuildRulesFromRequestTasks(IEnumerable requestTasks) + { + List rules = []; + + foreach (WfReqTask task in requestTasks + .Where(task => task.ManagementId != null) + .Where(task => !string.Equals(task.RequestAction, nameof(RequestAction.delete), StringComparison.OrdinalIgnoreCase)) + .Where(task => task.GetNwObjectElements(ElemFieldType.source).Count > 0) + .Where(task => task.GetNwObjectElements(ElemFieldType.destination).Count > 0) + .Where(task => task.GetServiceElements().Count > 0)) + { + Rule? rule = BuildRuleFromRequestTask(task); + if (rule != null) + { + rules.Add(rule); + } + } + + return rules; + } + + private static Rule? BuildRuleFromRequestTask(WfReqTask requestTask) + { + if (requestTask.ManagementId == null) + { + return null; + } + + List froms = requestTask.GetNwObjectElements(ElemFieldType.source) + .Where(IsRequestedElementActive) + .Select(BuildNetworkLocation) + .Where(location => location != null) + .Cast() + .ToList(); + + List tos = requestTask.GetNwObjectElements(ElemFieldType.destination) + .Where(IsRequestedElementActive) + .Select(BuildNetworkLocation) + .Where(location => location != null) + .Cast() + .ToList(); + + List services = requestTask.GetServiceElements() + .Where(IsRequestedElementActive) + .Select(BuildService) + .Where(service => service != null) + .Cast() + .ToList(); + + if (froms.Count == 0 || tos.Count == 0 || services.Count == 0) + { + return null; + } + + return new Rule() + { + MgmtId = requestTask.ManagementId.Value, + Uid = requestTask.GetRuleElements() + .Select(rule => rule.RuleUid) + .FirstOrDefault(uid => !string.IsNullOrWhiteSpace(uid)) ?? "", + Name = requestTask.Title, + Action = GetRuleAction(requestTask), + Froms = [.. froms], + Tos = [.. tos], + Services = [.. services] + }; + } + + private static NetworkLocation? BuildNetworkLocation(NwObjectElement element) + { + if (string.IsNullOrWhiteSpace(element.IpString)) + { + return null; + } + + NetworkObject inlineObject = new() + { + Name = element.Name ?? "", + IP = element.IpString, + IpEnd = element.IpEndString + }; + inlineObject.Type = new NetworkObjectType() + { + Name = !string.IsNullOrWhiteSpace(element.IpEndString) && !string.Equals(element.IpString, element.IpEndString, StringComparison.Ordinal) + ? ObjectType.IPRange + : ObjectType.Network + }; + return new NetworkLocation(new(), inlineObject); + } + + private static ServiceWrapper? BuildService(NwServiceElement element) + { + if (element.Port == 0 && element.ProtoId == 0) + { + return null; + } + + return new ServiceWrapper() + { + Content = new NetworkService() + { + Name = element.Name ?? "", + DestinationPort = element.Port, + DestinationPortEnd = element.PortEnd, + ProtoId = element.ProtoId + } + }; + } + + private static bool IsRequestedElementActive(NwObjectElement element) + { + return !string.Equals(element.RequestAction, nameof(RequestAction.delete), StringComparison.OrdinalIgnoreCase); + } + + private static bool IsRequestedElementActive(NwServiceElement element) + { + return !string.Equals(element.RequestAction, nameof(RequestAction.delete), StringComparison.OrdinalIgnoreCase); + } + + private static string GetRuleAction(WfReqTask requestTask) + { + if (string.Equals(requestTask.TaskType, WfTaskType.rule_delete.ToString(), StringComparison.OrdinalIgnoreCase) || + string.Equals(requestTask.RequestAction, nameof(RequestAction.delete), StringComparison.OrdinalIgnoreCase)) + { + return RuleActions.Drop; + } + + return RuleActions.Accept; + } + } +} diff --git a/roles/lib/files/FWO.Compliance/FWO.Compliance.csproj b/roles/lib/files/FWO.Compliance/FWO.Compliance.csproj new file mode 100644 index 0000000000..d822dbf942 --- /dev/null +++ b/roles/lib/files/FWO.Compliance/FWO.Compliance.csproj @@ -0,0 +1,22 @@ + + + + net10.0 + enable + enable + + + + + + + + + + + + + + + + diff --git a/roles/lib/files/FWO.Config.Api/Config.cs b/roles/lib/files/FWO.Config.Api/Config.cs index 2b163058a0..57919064e1 100644 --- a/roles/lib/files/FWO.Config.Api/Config.cs +++ b/roles/lib/files/FWO.Config.Api/Config.cs @@ -1,58 +1,89 @@ -using FWO.Api.Client; +using FWO.Api.Client; using FWO.Api.Client.Queries; using FWO.Config.Api.Data; using FWO.Logging; -using System; -using System.Collections.Generic; using System.ComponentModel; -using System.Linq; using System.Reflection; -using System.Text; using System.Text.Json.Serialization; -using System.Threading.Tasks; +using System.Threading; namespace FWO.Config.Api { - public abstract class Config : ConfigData + public abstract class Config : ConfigData, IDisposable { /// /// Internal connection to api server. Used to get/edit config data. /// - protected ApiConnection apiConnection; + protected ApiConnection? apiConnection; + + // Track if we own the ApiConnection and thus have to dispose it + private bool owningApiConnection = false; public int UserId { get; private set; } public bool Initialized { get; private set; } = false; public event Action? OnChange; - protected SemaphoreSlim semaphoreSlim = new SemaphoreSlim(1, 1); + protected readonly SemaphoreSlim semaphoreSlim = new(1, 1); + + // To detect redundant dispose calls + private bool _isDisposed; + protected bool IsDisposed => _isDisposed; + + // GraphQL Subscription handling + private GraphQlApiSubscription? _configGraphQlSubscription; - public ConfigItem[] RawConfigItems { get; set; } + public ConfigItem[] RawConfigItems { get; set; } = []; protected Config() { } - protected Config(ApiConnection apiConnection, int userId) + protected Config(ApiConnection apiConnection, int userId, bool withSubscription = false, bool owningApiConnection = false) { - SetUserId(apiConnection, userId).Wait(); + InitWithUserId(apiConnection, userId, withSubscription, owningApiConnection).GetAwaiter().GetResult(); } - public async Task SetUserId(ApiConnection apiConnection, int userId, bool waitForFirstUpdate = true) + public async Task InitWithUserId(ApiConnection apiConnection, int userId, bool withSubscription = false, bool owningApiConnection = false) { + ThrowIfDisposed(); this.apiConnection = apiConnection; + this.owningApiConnection = owningApiConnection; + UserId = userId; - apiConnection.GetSubscription(SubscriptionExceptionHandler, SubscriptionUpdateHandler, ConfigQueries.getConfigSubscription, new { UserId }); - if (waitForFirstUpdate) + + if (withSubscription) // used in Ui context { - await Task.Run(async () => { while (!Initialized) { await Task.Delay(10); } }); + // Re-init (e.g. login) can happen; dispose previous subscription to avoid handler accumulation. + _configGraphQlSubscription?.Dispose(); + _configGraphQlSubscription = null; + + List ignoreKeys = []; // currently nothing ignored, may be used later + _configGraphQlSubscription = apiConnection.GetSubscription(SubscriptionExceptionHandler, SubscriptionUpdateHandler, + ConfigQueries.subscribeConfigChangesByUser, new { UserId, ignoreKeys }); + + while (!Initialized) + { + await Task.Delay(10); + } + } + else // when only simple read is needed, e.g. during scheduled report in middleware server + { + ConfigItem[] configItems = await apiConnection.SendQueryAsync(ConfigQueries.getConfigItemsByUser, new { User = UserId }); + if (configItems.Length > 0) + { + Update(configItems); + RawConfigItems = configItems; + } + Initialized = true; } } - protected void SubscriptionUpdateHandler(ConfigItem[] configItems) + public void SubscriptionUpdateHandler(ConfigItem[] configItems) { + if (_isDisposed) return; semaphoreSlim.Wait(); try { - Log.WriteDebug("Config subscription update", "New config values received from config subscription"); + Log.WriteDebug("Config subscription update", $"New {configItems.Length} config values received from config subscription"); RawConfigItems = configItems; Update(configItems); OnChange?.Invoke(this, configItems); @@ -63,49 +94,82 @@ protected void SubscriptionUpdateHandler(ConfigItem[] configItems) protected void Update(ConfigItem[] configItems) { + ThrowIfDisposed(); + List remainingConfigItemNames = Array.ConvertAll(configItems, c => c.Key).ToList(); foreach (PropertyInfo property in GetType().GetProperties()) { - // Is the property storing a config value (marked by JsonPropertyName Attribute)? - if (property.GetCustomAttribute() != null) + if (TryGetConfigKey(property, out string? key)) { - string key = property.GetCustomAttribute()!.Name; - ConfigItem? configItem = configItems.FirstOrDefault(configItem => configItem.Key == key); + string resolvedKey = key!; + ConfigItem? configItem = configItems.FirstOrDefault(item => item.Key == resolvedKey); + ApplyConfigValue(property, resolvedKey, configItem, remainingConfigItemNames); + } + } + foreach (var name in remainingConfigItemNames.Where(n => !n.Contains("StateMatrix"))) // StateMatrix ConfigItems are handled separately + { + Log.WriteDebug($"Load {(UserId == 0 ? "Global " : "")}Config Items", $"Config item with key \"{name}\" could not be found. {(UserId == 0 ? "" : "User might not have customized the setting. ")}Using default value."); + } + } - if (configItem != null) - { - try - { - Type propertyType = property.PropertyType; - TypeConverter converter = TypeDescriptor.GetConverter(property.PropertyType); - property.SetValue(this, converter.ConvertFromString(configItem.Value - ?? throw new Exception($"Config value (with key: {configItem.Key}) is null.")) - ?? throw new Exception($"Config value (with key: {configItem.Key}) is not convertible to {property.GetType()}.")); - } - catch (Exception exception) - { - Log.WriteError("Load Config Items", $"Config item with key \"{key}\" could not be loaded. Using default value.", exception); - } - } - else - { - // If this is a global config - if (UserId == 0) - { - Log.WriteDebug("Load Global Config Items", $"Config item with key \"{key}\" could not be found. Using default value."); - } - // If this is a user config item (user might not have changed the default setting) - else if (property.GetCustomAttribute() != null) - { - Log.WriteDebug("Load Config Items", $"Config item with key \"{key}\" could not be found. User might not have customized the setting. Using default value."); - } - } + /// + /// Tries to resolve the config key from a property marked with . + /// + private static bool TryGetConfigKey(PropertyInfo property, out string? key) + { + key = property.GetCustomAttribute()?.Name; + return key != null; + } + + /// + /// Applies a config item value to the matching property and logs conversion issues. + /// + private void ApplyConfigValue(PropertyInfo property, string key, ConfigItem? configItem, List remainingConfigItemNames) + { + if (configItem == null) + { + return; + } + + try + { + remainingConfigItemNames.Remove(configItem.Key); + property.SetValue(this, ConvertConfigValue(property, configItem)); + } + catch (ArgumentException exception) when (property.PropertyType.IsEnum) + { + Log.WriteWarning("Load Config Items", $"Config item with key \"{key}\" contains unsupported value \"{configItem.Value}\". Using default value."); + Log.WriteDebug("Load Config Items", $"Unsupported enum value ignored for key \"{key}\": {exception.Message}"); + } + catch (Exception exception) + { + Log.WriteError("Load Config Items", $"Config item with key \"{key}\" could not be loaded. Using default value.", exception); + } + } + + private static object ConvertConfigValue(PropertyInfo property, ConfigItem configItem) + { + string rawValue = configItem.Value ?? throw new ArgumentNullException($"Config value (with key: {configItem.Key}) is null."); + + if (property.PropertyType.IsEnum) + { + object parsedEnum = Enum.Parse(property.PropertyType, rawValue, ignoreCase: true); + if (!Enum.IsDefined(property.PropertyType, parsedEnum)) + { + throw new InvalidEnumArgumentException(property.Name, Convert.ToInt32(parsedEnum), property.PropertyType); } + return parsedEnum; } + + TypeConverter converter = TypeDescriptor.GetConverter(property.PropertyType); + return converter.ConvertFromString(rawValue) + ?? throw new ArgumentException($"Config value (with key: {configItem.Key}) is not convertible to {property.PropertyType}."); } public async Task WriteToDatabase(ConfigData editedData, ApiConnection apiConnection) { + ThrowIfDisposed(); await semaphoreSlim.WaitAsync(); + List configItemChanges = []; try { foreach (PropertyInfo property in GetType().GetProperties()) @@ -120,12 +184,12 @@ public async Task WriteToDatabase(ConfigData editedData, ApiConnection apiConnec try { - TypeConverter converter = TypeDescriptor.GetConverter(property.GetType()); + TypeConverter converter = TypeDescriptor.GetConverter(property.PropertyType); string stringValue = converter.ConvertToString(property.GetValue(editedData) - ?? throw new Exception($"Config value (with key: {key}) is null")) - ?? throw new Exception($"Config value (with key: {key}) is not convertible to {property.GetType()}."); - // Update or insert config item - await apiConnection.SendQueryAsync(ConfigQueries.upsertConfigItem, new ConfigItem { Key = key, Value = stringValue, User = UserId }); + ?? throw new ArgumentNullException($"Config value (with key: {key}) is null")) + ?? throw new ArgumentException($"Config value (with key: {key}) is not convertible to {property.PropertyType}."); + // Add config item to the list of changed config items + configItemChanges.Add(new ConfigItem { Key = key, Value = stringValue, User = UserId }); } catch (Exception exception) { @@ -134,14 +198,20 @@ public async Task WriteToDatabase(ConfigData editedData, ApiConnection apiConnec } } } + // Update or insert all config item + await apiConnection.SendQueryAsync(ConfigQueries.upsertConfigItems, new { config_items = configItemChanges }); } finally { semaphoreSlim.Release(); } } public async Task GetEditableConfig() { + ThrowIfDisposed(); await semaphoreSlim.WaitAsync(); - try { return (ConfigData)CloneEditable(); } + try + { + return (ConfigData)CloneEditable(); + } finally { semaphoreSlim.Release(); } } @@ -150,17 +220,43 @@ protected static void SubscriptionExceptionHandler(Exception exception) Log.WriteError("Config Subscription", "Config subscription lead to error.", exception); } - // TODO: Move method - public static string ShowBool(bool boolVal) - { - return boolVal ? "\u2714" : "\u2716"; - } - protected void InvokeOnChange(Config config, ConfigItem[] configItems) { + ThrowIfDisposed(); OnChange?.Invoke(config, configItems); } public abstract string GetText(string key); + + protected void ThrowIfDisposed() + { + ObjectDisposedException.ThrowIf(_isDisposed, this); + } + + protected virtual void Dispose(bool disposing) + { + if (!_isDisposed) + { + if (disposing) + { + _configGraphQlSubscription?.Dispose(); + _configGraphQlSubscription = null; + if (owningApiConnection) + { + apiConnection?.Dispose(); + } + apiConnection = null; + semaphoreSlim.Dispose(); + OnChange = null; + } + _isDisposed = true; + } + } + + public void Dispose() + { + Dispose(disposing: true); + GC.SuppressFinalize(this); + } } } diff --git a/roles/lib/files/FWO.Config.Api/Data/CommonArea.cs b/roles/lib/files/FWO.Config.Api/Data/CommonArea.cs new file mode 100644 index 0000000000..ac4fc1223c --- /dev/null +++ b/roles/lib/files/FWO.Config.Api/Data/CommonArea.cs @@ -0,0 +1,33 @@ +using Newtonsoft.Json; +using System.Text.Json.Serialization; +using FWO.Basics; +using FWO.Data.Modelling; + +namespace FWO.Config.Api.Data +{ + public class CommonAreaConfig + { + [JsonProperty("area_id"), JsonPropertyName("area_id")] + public long AreaId { get; set; } = 0; + + [JsonProperty("use_in_src"), JsonPropertyName("use_in_src")] + public bool UseInSrc { get; set; } = true; + + [JsonProperty("use_in_dst"), JsonPropertyName("use_in_dst")] + public bool UseInDst { get; set; } = true; + } + + public class CommonArea + { + public ModellingNwGroupWrapper Area { get; set; } = new(); + + public bool UseInSrc { get; set; } = true; + + public bool UseInDst { get; set; } = true; + + public CommonAreaConfig ToConfigItem() + { + return new() { AreaId = Area.Content.Id, UseInSrc = UseInSrc, UseInDst = UseInDst }; + } + } +} diff --git a/roles/lib/files/FWO.Config.Api/Data/ConfigData.cs b/roles/lib/files/FWO.Config.Api/Data/ConfigData.cs index c818d04158..35abf9ad11 100644 --- a/roles/lib/files/FWO.Config.Api/Data/ConfigData.cs +++ b/roles/lib/files/FWO.Config.Api/Data/ConfigData.cs @@ -1,7 +1,9 @@ -using Newtonsoft.Json; +using Newtonsoft.Json; using System.Text.Json; using System.Text.Json.Serialization; -using FWO.Api.Data; +using FWO.Basics; +using FWO.Data; +using FWO.Data.Workflow; using FWO.Mail; namespace FWO.Config.Api.Data @@ -14,7 +16,7 @@ public class ConfigData : ICloneable public readonly bool Editable; [JsonProperty("DefaultLanguage"), JsonPropertyName("DefaultLanguage")] - public virtual string DefaultLanguage { get; set; } = "English"; + public virtual string DefaultLanguage { get; set; } = GlobalConst.kEnglish; [JsonProperty("sessionTimeout"), JsonPropertyName("sessionTimeout")] public int SessionTimeout { get; set; } = 720; @@ -22,8 +24,23 @@ public class ConfigData : ICloneable [JsonProperty("sessionTimeoutNoticePeriod"), JsonPropertyName("sessionTimeoutNoticePeriod")] public int SessionTimeoutNoticePeriod { get; set; } = 60; - // [JsonProperty("maxMessages"), JsonPropertyName("maxMessages"), UserConfigData] - // public int MaxMessages { get; set; } = 3; + [JsonProperty("uiHostName"), JsonPropertyName("uiHostName")] + public string UiHostName { get; set; } = "http://localhost:5000"; + + [JsonProperty("welcomeMessage"), JsonPropertyName("welcomeMessage")] + public string WelcomeMessage { get; set; } = ""; + + [JsonProperty("useCustomLogo"), JsonPropertyName("useCustomLogo")] + public bool UseCustomLogo { get; set; } + + [JsonProperty("customLogoData"), JsonPropertyName("customLogoData")] + public string CustomLogoData { get; set; } = ""; + + [JsonProperty("availableModules"), JsonPropertyName("availableModules")] + public string AvailableModules { get; set; } = ""; + + [JsonProperty("maxMessages"), JsonPropertyName("maxMessages"), UserConfigData] + public int MaxMessages { get; set; } = 3; [JsonProperty("elementsPerFetch"), JsonPropertyName("elementsPerFetch"), UserConfigData] public int ElementsPerFetch { get; set; } = 100; @@ -40,6 +57,9 @@ public class ConfigData : ICloneable [JsonProperty("creationTolerance"), JsonPropertyName("creationTolerance")] public int CreationTolerance { get; set; } = 90; + [JsonProperty("availableReportTypes"), JsonPropertyName("availableReportTypes")] + public string AvailableReportTypes { get; set; } = "[]"; + [JsonProperty("dataRetentionTime"), JsonPropertyName("dataRetentionTime")] public int DataRetentionTime { get; set; } = 731; @@ -56,7 +76,7 @@ public class ConfigData : ICloneable public int AutoDiscoverSleepTime { get; set; } = 24; [JsonProperty("autoDiscoverStartAt"), JsonPropertyName("autoDiscoverStartAt")] - public DateTime AutoDiscoverStartAt { get; set; } = new DateTime(); + public DateTime AutoDiscoverStartAt { get; set; } = DateTime.Now; [JsonProperty("fwApiElementsPerFetch"), JsonPropertyName("fwApiElementsPerFetch")] public int FwApiElementsPerFetch { get; set; } = 150; @@ -73,10 +93,45 @@ public class ConfigData : ICloneable [JsonProperty("impChangeNotifyActive"), JsonPropertyName("impChangeNotifyActive")] public bool ImpChangeNotifyActive { get; set; } = false; + [JsonProperty("impChangeIncludeObjectChanges"), JsonPropertyName("impChangeIncludeObjectChanges")] + public bool ImpChangeIncludeObjectChanges { get; set; } = false; + + [JsonProperty("impChangeNotifyType"), JsonPropertyName("impChangeNotifyType")] + public int ImpChangeNotifyType { get; set; } + + [JsonProperty("impChangeNotifySleepTime"), JsonPropertyName("impChangeNotifySleepTime")] + public int ImpChangeNotifySleepTime { get; set; } = 60; + + [JsonProperty("impChangeNotifyStartAt"), JsonPropertyName("impChangeNotifyStartAt")] + public DateTime ImpChangeNotifyStartAt { get; set; } = DateTime.Now; + + [JsonProperty("updateRuleOwnerMappingActive"), JsonPropertyName("updateRuleOwnerMappingActive")] + public bool UpdateRuleOwnerMappingActive { get; set; } = false; + + [JsonProperty("updateRuleOwnerMappingSleepTime"), JsonPropertyName("updateRuleOwnerMappingSleepTime")] + public int UpdateRuleOwnerMappingSleepTime { get; set; } = 60; + + [JsonProperty("updateRuleOwnerMappingStartAt"), JsonPropertyName("updateRuleOwnerMappingStartAt")] + public DateTime UpdateRuleOwnerMappingStartAt { get; set; } = DateTime.Now; + + [JsonProperty("externalRequestSleepTime"), JsonPropertyName("externalRequestSleepTime")] + public int ExternalRequestSleepTime { get; set; } = 60; + + [JsonProperty("externalRequestStartAt"), JsonPropertyName("externalRequestStartAt")] + public DateTime ExternalRequestStartAt { get; set; } = DateTime.Now; + + [JsonProperty("recertificationMode"), JsonPropertyName("recertificationMode")] + public RecertificationMode RecertificationMode { get; set; } = RecertificationMode.RuleByRule; [JsonProperty("recertificationPeriod"), JsonPropertyName("recertificationPeriod")] public int RecertificationPeriod { get; set; } = 365; + [JsonProperty("initialRecertificationPeriod"), JsonPropertyName("initialRecertificationPeriod")] + public int InitialRecertificationPeriod { get; set; } = 365; + + [JsonProperty("initialRecertifier"), JsonPropertyName("initialRecertifier")] + public string InitialRecertifier { get; set; } = ""; + [JsonProperty("recertificationNoticePeriod"), JsonPropertyName("recertificationNoticePeriod")] public int RecertificationNoticePeriod { get; set; } = 30; @@ -164,6 +219,15 @@ public class ConfigData : ICloneable [JsonProperty("emailSenderAddress"), JsonPropertyName("emailSenderAddress")] public string EmailSenderAddress { get; set; } = ""; + [JsonProperty("useDummyEmailAddress"), JsonPropertyName("useDummyEmailAddress")] + public bool UseDummyEmailAddress { get; set; } = false; + + [JsonProperty("dummyEmailAddress"), JsonPropertyName("dummyEmailAddress")] + public string DummyEmailAddress { get; set; } = ""; + + [JsonProperty("notificationLanguage"), JsonPropertyName("notificationLanguage")] + public string NotificationLanguage { get; set; } = ""; + [JsonProperty("minCollapseAllDevices"), JsonPropertyName("minCollapseAllDevices"), UserConfigData] public int MinCollapseAllDevices { get; set; } = 15; @@ -171,7 +235,10 @@ public class ConfigData : ICloneable public int MessageViewTime { get; set; } = 7; [JsonProperty("dailyCheckStartAt"), JsonPropertyName("dailyCheckStartAt")] - public DateTime DailyCheckStartAt { get; set; } = new DateTime(); + public DateTime DailyCheckStartAt { get; set; } = DateTime.Now; + + [JsonProperty("dailyCheckModules"), JsonPropertyName("dailyCheckModules")] + public string DailyCheckModules { get; set; } = ""; [JsonProperty("maxImportDuration"), JsonPropertyName("maxImportDuration")] public int MaxImportDuration { get; set; } = 4; @@ -182,6 +249,12 @@ public class ConfigData : ICloneable [JsonProperty("reqAvailableTaskTypes"), JsonPropertyName("reqAvailableTaskTypes")] public string ReqAvailableTaskTypes { get; set; } = ""; + [JsonProperty("reqOwnerBased"), JsonPropertyName("reqOwnerBased")] + public bool ReqOwnerBased { get; set; } = false; + + [JsonProperty("reqReducedView"), JsonPropertyName("reqReducedView")] + public bool ReqReducedView { get; set; } = false; + [JsonProperty("reqAllowObjectSearch"), JsonPropertyName("reqAllowObjectSearch")] public bool ReqAllowObjectSearch { get; set; } = false; @@ -189,7 +262,7 @@ public class ConfigData : ICloneable public bool AllowManualOwnerAdmin { get; set; } = false; [JsonProperty("reqPriorities"), JsonPropertyName("reqPriorities")] - public string ReqPriorities { get; set; } = ""; + public string ReqPriorities { get; set; } = "[]"; [JsonProperty("reqAutoCreateImplTasks"), JsonPropertyName("reqAutoCreateImplTasks")] public AutoCreateImplTaskOptions ReqAutoCreateImplTasks { get; set; } = AutoCreateImplTaskOptions.never; @@ -197,6 +270,321 @@ public class ConfigData : ICloneable [JsonProperty("reqActivatePathAnalysis"), JsonPropertyName("reqActivatePathAnalysis")] public bool ReqActivatePathAnalysis { get; set; } = true; + [JsonProperty("reqShowCompliance"), JsonPropertyName("reqShowCompliance")] + public bool ReqShowCompliance { get; set; } = false; + + [JsonProperty("reqAllowedChangesByApprover"), JsonPropertyName("reqAllowedChangesByApprover")] + public string ReqAllowedChangesByApprover { get; set; } = System.Text.Json.JsonSerializer.Serialize(new ApproverAllowedChangesConfig()); + + [JsonProperty("ruleOwnershipMode"), JsonPropertyName("ruleOwnershipMode")] + public RuleOwnershipMode RuleOwnershipMode { get; set; } = RuleOwnershipMode.mixed; + + [JsonProperty("allowServerInConn"), JsonPropertyName("allowServerInConn")] + public bool AllowServerInConn { get; set; } = true; + + [JsonProperty("allowServiceInConn"), JsonPropertyName("allowServiceInConn")] + public bool AllowServiceInConn { get; set; } = true; + + [JsonProperty("overviewDisplayLines"), JsonPropertyName("overviewDisplayLines")] + public int OverviewDisplayLines { get; set; } = 3; + + [JsonProperty("reducedProtocolSet"), JsonPropertyName("reducedProtocolSet")] + public bool ReducedProtocolSet { get; set; } = true; + + [JsonProperty("createApplicationZones"), JsonPropertyName("createApplicationZones")] + public bool CreateAppZones { get; set; } + + [JsonProperty("dnsLookup"), JsonPropertyName("dnsLookup")] + public bool DnsLookup { get; set; } = false; + + [JsonProperty("overwriteExistingNames"), JsonPropertyName("overwriteExistingNames")] + public bool OverwriteExistingNames { get; set; } = false; + + [JsonProperty("autoReplaceAppServer"), JsonPropertyName("autoReplaceAppServer")] + public bool AutoReplaceAppServer { get; set; } = false; + + [JsonProperty("importAppDataPath"), JsonPropertyName("importAppDataPath")] + public string ImportAppDataPath { get; set; } = ""; + + [JsonProperty("importAppDataScriptArgs"), JsonPropertyName("importAppDataScriptArgs")] + public string ImportAppDataScriptArgs { get; set; } = ""; + + [JsonProperty("importAppDataSleepTime"), JsonPropertyName("importAppDataSleepTime")] + public int ImportAppDataSleepTime { get; set; } = 24; + + [JsonProperty("importAppDataStartAt"), JsonPropertyName("importAppDataStartAt")] + public DateTime ImportAppDataStartAt { get; set; } = DateTime.Now; + + [JsonProperty("OwnerSoruceMappingID"), JsonPropertyName("OwnerSoruceMappingID")] + public int OwnerSoruceMappingID { get; set; } = 0; + + [JsonProperty("CustomFieldOwnerKey"), JsonPropertyName("CustomFieldOwnerKey")] + public string CustomFieldOwnerKey { get; set; } = ""; + + [JsonProperty("CustomFieldChangeIdKey"), JsonPropertyName("CustomFieldChangeIdKey")] + public string CustomFieldChangeIdKey { get; set; } = ""; + + [JsonProperty("rolesWithAppDataImport"), JsonPropertyName("rolesWithAppDataImport")] + public string RolesWithAppDataImport { get; set; } = "[]"; + + [JsonProperty("ownerDataImportSyncUsers"), JsonPropertyName("ownerDataImportSyncUsers")] + public bool OwnerDataImportSyncUsers { get; set; } = true; + + [JsonProperty("importSubnetDataPath"), JsonPropertyName("importSubnetDataPath")] + public string ImportSubnetDataPath { get; set; } = ""; + + [JsonProperty("importSubnetDataSleepTime"), JsonPropertyName("importSubnetDataSleepTime")] + public int ImportSubnetDataSleepTime { get; set; } = 24; + + [JsonProperty("importSubnetDataStartAt"), JsonPropertyName("importSubnetDataStartAt")] + public DateTime ImportSubnetDataStartAt { get; set; } = DateTime.Now; + + [JsonProperty("modNamingConvention"), JsonPropertyName("modNamingConvention")] + public string ModNamingConvention { get; set; } = ""; + + [JsonProperty("modIconify"), JsonPropertyName("modIconify")] + public bool ModIconify { get; set; } = true; + + [JsonProperty("modCommonAreas"), JsonPropertyName("modCommonAreas")] + public string ModCommonAreas { get; set; } = ""; + + [JsonProperty("modSpecUserAreas"), JsonPropertyName("modSpecUserAreas")] + public string ModSpecUserAreas { get; set; } = ""; + + [JsonProperty("modUpdatableObjAreas"), JsonPropertyName("modUpdatableObjAreas")] + public string ModUpdatableObjAreas { get; set; } = ""; + + [JsonProperty("modAppServerTypes"), JsonPropertyName("modAppServerTypes")] + public string ModAppServerTypes { get; set; } = ""; + + [JsonProperty("modReqInterfaceName"), JsonPropertyName("modReqInterfaceName")] + public string ModReqInterfaceName { get; set; } = ""; + + [JsonProperty("modReqEmailReceiver"), JsonPropertyName("modReqEmailReceiver")] + public string ModReqEmailReceiver { get; set; } = nameof(EmailRecipientOption.None); + + [JsonProperty("modReqEmailRequesterInCc"), JsonPropertyName("modReqEmailRequesterInCc")] + public bool ModReqEmailRequesterInCc { get; set; } = true; + + [JsonProperty("modReqEmailOtherAddresses"), JsonPropertyName("modReqEmailOtherAddresses")] + public string ModReqEmailOtherAddresses { get; set; } = ""; + + [JsonProperty("modReqEmailSubject"), JsonPropertyName("modReqEmailSubject")] + public string ModReqEmailSubject { get; set; } = ""; + + [JsonProperty("modReqEmailBody"), JsonPropertyName("modReqEmailBody")] + public string ModReqEmailBody { get; set; } = ""; + + [JsonProperty("modUnansweredReqEmailBody"), JsonPropertyName("modUnansweredReqEmailBody")] + public string ModUnansweredReqEmailBody { get; set; } = ""; + + [JsonProperty("ruleExpiryEmailBody"), JsonPropertyName("ruleExpiryEmailBody")] + public string RuleExpiryEmailBody { get; set; } = ""; + + [JsonProperty("ownerActiveRuleEmailBody"), JsonPropertyName("ownerActiveRuleEmailBody")] + public string OwnerActiveRuleEmailBody { get; set; } = ""; + + [JsonProperty("ruleExpiryInitiatorKeys"), JsonPropertyName("ruleExpiryInitiatorKeys")] + public string RuleExpiryInitiatorKeys { get; set; } = ""; + + [JsonProperty("modReqTicketTitle"), JsonPropertyName("modReqTicketTitle")] + public string ModReqTicketTitle { get; set; } = ""; + + [JsonProperty("modReqTaskTitle"), JsonPropertyName("modReqTaskTitle")] + public string ModReqTaskTitle { get; set; } = ""; + + [JsonProperty("modDecommEmailReceiver"), JsonPropertyName("modDecommEmailReceiver")] + public string ModDecommEmailReceiver { get; set; } = nameof(EmailRecipientOption.None); + + [JsonProperty("modDecommEmailOtherAddresses"), JsonPropertyName("modDecommEmailOtherAddresses")] + public string ModDecommEmailOtherAddresses { get; set; } = ""; + + [JsonProperty("modDecommEmailSubject"), JsonPropertyName("modDecommEmailSubject")] + public string ModDecommEmailSubject { get; set; } = ""; + + [JsonProperty("modDecommEmailBody"), JsonPropertyName("modDecommEmailBody")] + public string ModDecommEmailBody { get; set; } = ""; + + [JsonProperty("modRolloutActive"), JsonPropertyName("modRolloutActive")] + public bool ModRolloutActive { get; set; } = true; + + [JsonProperty("modRolloutResolveServiceGroups"), JsonPropertyName("modRolloutResolveServiceGroups")] + public bool ModRolloutResolveServiceGroups { get; set; } = true; + + [JsonProperty("modRolloutBundleTasks"), JsonPropertyName("modRolloutBundleTasks")] + public bool ModRolloutBundleTasks { get; set; } = false; + + [JsonProperty("modRolloutNatHeuristic"), JsonPropertyName("modRolloutNatHeuristic")] + public bool ModRolloutNatHeuristic { get; set; } = false; + + [JsonProperty("modRolloutRemovedAppServers"), JsonPropertyName("modRolloutRemovedAppServers")] + public bool ModRolloutRemovedAppServers { get; set; } = false; + + [JsonProperty("modRequestOnlyOwnObjects"), JsonPropertyName("modRequestOnlyOwnObjects")] + public bool ModRequestOnlyOwnObjects { get; set; } = false; + + [JsonProperty("modRolloutErrorText"), JsonPropertyName("modRolloutErrorText")] + public string ModRolloutErrorText { get; set; } = ""; + + [JsonProperty("modRecertActive"), JsonPropertyName("modRecertActive")] + public bool ModRecertActive { get; set; } = false; + + [JsonProperty("modRecertExpectAllModelled"), JsonPropertyName("modRecertExpectAllModelled")] + public bool ModRecertExpectAllModelled { get; set; } = false; + + [JsonProperty("modRecertText"), JsonPropertyName("modRecertText")] + public string ModRecertText { get; set; } = ""; + + [JsonProperty("externalRequestWaitCycles"), JsonPropertyName("externalRequestWaitCycles")] + public int ExternalRequestWaitCycles { get; set; } = 0; + + [JsonProperty("extTicketSystems"), JsonPropertyName("extTicketSystems")] + public string ExtTicketSystems { get; set; } = ""; + + [JsonProperty("modExtraConfigs"), JsonPropertyName("modExtraConfigs")] + public string ModExtraConfigs { get; set; } = ""; + + [JsonProperty("modModelledMarker"), JsonPropertyName("modModelledMarker")] + public string ModModelledMarker { get; set; } = "FWOC"; + + [JsonProperty("modModelledMarkerLocation"), JsonPropertyName("modModelledMarkerLocation")] + public string ModModelledMarkerLocation { get; set; } = MarkerLocation.Rulename; + + [JsonProperty("ruleRecognitionOption"), JsonPropertyName("ruleRecognitionOption")] + public string RuleRecognitionOption { get; set; } = ""; + + [JsonProperty("varianceAnalysisSleepTime"), JsonPropertyName("varianceAnalysisSleepTime")] + public int VarianceAnalysisSleepTime { get; set; } = 0; + + [JsonProperty("varianceAnalysisStartAt"), JsonPropertyName("varianceAnalysisStartAt")] + public DateTime VarianceAnalysisStartAt { get; set; } = DateTime.Now; + + [JsonProperty("varianceAnalysisSync"), JsonPropertyName("varianceAnalysisSync")] + public bool VarianceAnalysisSync { get; set; } = false; + + [JsonProperty("varianceAnalysisRefresh"), JsonPropertyName("varianceAnalysisRefresh")] + public bool VarianceAnalysisRefresh { get; set; } = false; + + [JsonProperty("resolveNetworkAreas"), JsonPropertyName("resolveNetworkAreas")] + public bool ResolveNetworkAreas { get; set; } = false; + + [JsonProperty("complianceCheckSleepTime"), JsonPropertyName("complianceCheckSleepTime")] + public int ComplianceCheckSleepTime { get; set; } = 0; + + [JsonProperty("complianceCheckStartAt"), JsonPropertyName("complianceCheckStartAt")] + public DateTime ComplianceCheckStartAt { get; set; } = DateTime.Now; + + [JsonProperty("complianceCheckPolicy"), JsonPropertyName("complianceCheckPolicy")] + public int ComplianceCheckPolicyId { get; set; } = 0; + + [JsonProperty("complianceCheckMailRecipients"), JsonPropertyName("complianceCheckMailRecipients")] + public string ComplianceCheckMailRecipients { get; set; } = ""; + + [JsonProperty("complianceCheckMailSubject"), JsonPropertyName("complianceCheckMailSubject")] + public string ComplianceCheckMailSubject { get; set; } = ""; + + [JsonProperty("complianceCheckMailBody"), JsonPropertyName("complianceCheckMailBody")] + public string ComplianceCheckMailBody { get; set; } = ""; + + [JsonProperty("complianceMatrixAllowNetworkZones"), JsonPropertyName("complianceMatrixAllowNetworkZones")] + public bool ComplianceMatrixAllowNetworkZones { get; set; } = false; + + [JsonProperty("complianceCheckScheduledDiffReportsIntervals"), JsonPropertyName("complianceCheckScheduledDiffReportsIntervals")] + public string ComplianceCheckScheduledDiffReportsIntervals { get; set; } = ""; + + [JsonProperty("complianceCheckInternetZoneObject"), JsonPropertyName("complianceCheckInternetZoneObject")] + public string ComplianceCheckInternetZoneObject { get; set; } = ""; + + [JsonProperty("complianceCheckMaxPrintedViolations"), JsonPropertyName("complianceCheckMaxPrintedViolations")] + public int ComplianceCheckMaxPrintedViolations { get; set; } = 0; + + [JsonProperty("complianceCheckSortMatrixByID"), JsonPropertyName("complianceCheckSortMatrixByID")] + public bool ComplianceCheckSortMatrixByID { get; set; } = false; + + [JsonProperty("complianceCheckRelevantManagements"), JsonPropertyName("complianceCheckRelevantManagements")] + public string ComplianceCheckRelevantManagements { get; set; } = ""; + + [JsonProperty("reportSchedulerConfig"), JsonPropertyName("reportSchedulerConfig")] + public string ReportSchedulerConfig { get; set; } = ""; + + [JsonProperty("debugConfig"), JsonPropertyName("debugConfig")] + public string DebugConfig { get; set; } = ""; + + [JsonProperty("autoCalculateInternetZone"), JsonPropertyName("autoCalculateInternetZone")] + public bool AutoCalculateInternetZone { get; set; } = true; + + [JsonProperty("autoCalculateUndefinedInternalZone"), JsonPropertyName("autoCalculateUndefinedInternalZone")] + public bool AutoCalculateUndefinedInternalZone { get; set; } = true; + + [JsonProperty("internalZoneRange_10_0_0_0_8"), JsonPropertyName("internalZoneRange_10_0_0_0_8")] + public bool InternalZoneRange_10_0_0_0_8 { get; set; } = true; + + [JsonProperty("internalZoneRange_172_16_0_0_12"), JsonPropertyName("internalZoneRange_172_16_0_0_12")] + public bool InternalZoneRange_172_16_0_0_12 { get; set; } = true; + + [JsonProperty("internalZoneRange_192_168_0_0_16"), JsonPropertyName("internalZoneRange_192_168_0_0_16")] + public bool InternalZoneRange_192_168_0_0_16 { get; set; } = true; + + [JsonProperty("internalZoneRange_0_0_0_0_8"), JsonPropertyName("internalZoneRange_0_0_0_0_8")] + public bool InternalZoneRange_0_0_0_0_8 { get; set; } = true; + + [JsonProperty("internalZoneRange_127_0_0_0_8"), JsonPropertyName("internalZoneRange_127_0_0_0_8")] + public bool InternalZoneRange_127_0_0_0_8 { get; set; } = true; + + [JsonProperty("internalZoneRange_169_254_0_0_16"), JsonPropertyName("internalZoneRange_169_254_0_0_16")] + public bool InternalZoneRange_169_254_0_0_16 { get; set; } = true; + + [JsonProperty("internalZoneRange_224_0_0_0_4"), JsonPropertyName("internalZoneRange_224_0_0_0_4")] + public bool InternalZoneRange_224_0_0_0_4 { get; set; } = true; + + [JsonProperty("internalZoneRange_240_0_0_0_4"), JsonPropertyName("internalZoneRange_240_0_0_0_4")] + public bool InternalZoneRange_240_0_0_0_4 { get; set; } = true; + + [JsonProperty("internalZoneRange_255_255_255_255_32"), JsonPropertyName("internalZoneRange_255_255_255_255_32")] + public bool InternalZoneRange_255_255_255_255_32 { get; set; } = true; + + [JsonProperty("internalZoneRange_192_0_2_0_24"), JsonPropertyName("internalZoneRange_192_0_2_0_24")] + public bool InternalZoneRange_192_0_2_0_24 { get; set; } = true; + + [JsonProperty("internalZoneRange_198_51_100_0_24"), JsonPropertyName("internalZoneRange_198_51_100_0_24")] + public bool InternalZoneRange_198_51_100_0_24 { get; set; } = true; + + [JsonProperty("internalZoneRange_203_0_113_0_24"), JsonPropertyName("internalZoneRange_203_0_113_0_24")] + public bool InternalZoneRange_203_0_113_0_24 { get; set; } = true; + + [JsonProperty("internalZoneRange_100_64_0_0_10"), JsonPropertyName("internalZoneRange_100_64_0_0_10")] + public bool InternalZoneRange_100_64_0_0_10 { get; set; } = true; + + [JsonProperty("internalZoneRange_192_0_0_0_24"), JsonPropertyName("internalZoneRange_192_0_0_0_24")] + public bool InternalZoneRange_192_0_0_0_24 { get; set; } = true; + + [JsonProperty("internalZoneRange_192_88_99_0_24"), JsonPropertyName("internalZoneRange_192_88_99_0_24")] + public bool InternalZoneRange_192_88_99_0_24 { get; set; } = true; + + [JsonProperty("internalZoneRange_198_18_0_0_15"), JsonPropertyName("internalZoneRange_198_18_0_0_15")] + public bool InternalZoneRange_198_18_0_0_15 { get; set; } = true; + + [JsonProperty("autoCalculatedZonesAtTheEnd"), JsonPropertyName("autoCalculatedZonesAtTheEnd")] + public bool AutoCalculatedZonesAtTheEnd { get; set; } = true; + + [JsonProperty("treatDynamicAndDomainObjectsAsInternet"), JsonPropertyName("treatDynamicAndDomainObjectsAsInternet")] + public bool TreatDynamicAndDomainObjectsAsInternet { get; set; } = true; + + [JsonProperty("showShortColumnsInComplianceReports"), JsonPropertyName("showShortColumnsInComplianceReports")] + public bool ShowShortColumnsInComplianceReports { get; set; } = true; + + [JsonProperty("importedMatrixReadOnly"), JsonPropertyName("importedMatrixReadOnly")] + public bool ImportedMatrixReadOnly { get; set; } = true; + + [JsonProperty("complianceCheckElementsPerFetch"), JsonPropertyName("complianceCheckElementsPerFetch")] + public int ComplianceCheckElementsPerFetch { get; set; } = 500; + + [JsonProperty("complianceCheckAvailableProcessors"), JsonPropertyName("complianceCheckAvailableProcessors")] + public int ComplianceCheckAvailableProcessors { get; set; } = 4; + + [JsonProperty("complianceFilterOutInitialViolations"), JsonPropertyName("complianceFilterOutInitialViolations")] + public bool ComplianceFilterOutInitialViolations { get; set; } = false; + public ConfigData(bool editable = false) { diff --git a/roles/lib/files/FWO.Config.Api/Data/Language.cs b/roles/lib/files/FWO.Config.Api/Data/Language.cs index b861d0bdd3..fb24a3f830 100644 --- a/roles/lib/files/FWO.Config.Api/Data/Language.cs +++ b/roles/lib/files/FWO.Config.Api/Data/Language.cs @@ -1,4 +1,4 @@ -using System.Text.Json.Serialization; +using System.Text.Json.Serialization; using Newtonsoft.Json; namespace FWO.Config.Api.Data diff --git a/roles/lib/files/FWO.Config.Api/Data/RecertCheckParams.cs b/roles/lib/files/FWO.Config.Api/Data/RecertCheckParams.cs index a96895a969..c23bc8836e 100644 --- a/roles/lib/files/FWO.Config.Api/Data/RecertCheckParams.cs +++ b/roles/lib/files/FWO.Config.Api/Data/RecertCheckParams.cs @@ -1,13 +1,13 @@ using Newtonsoft.Json; using System.Text.Json.Serialization; -using FWO.Api.Data; +using FWO.Data; namespace FWO.Config.Api.Data { public class RecertCheckParams { [JsonProperty("check_interval"), JsonPropertyName("check_interval")] - public Interval RecertCheckInterval { get; set; } = Interval.Months; + public SchedulerInterval RecertCheckInterval { get; set; } = SchedulerInterval.Months; [JsonProperty("check_offset"), JsonPropertyName("check_offset")] public int RecertCheckOffset { get; set; } = 1; diff --git a/roles/lib/files/FWO.Config.Api/Data/UiText.cs b/roles/lib/files/FWO.Config.Api/Data/UiText.cs index 02fb4eb530..008dacf279 100644 --- a/roles/lib/files/FWO.Config.Api/Data/UiText.cs +++ b/roles/lib/files/FWO.Config.Api/Data/UiText.cs @@ -1,5 +1,4 @@ -using System.Text.Json.Serialization; -using System.Collections.Generic; +using System.Text.Json.Serialization; using Newtonsoft.Json; namespace FWO.Config.Api.Data @@ -18,19 +17,4 @@ public class UiText [JsonProperty("language"), JsonPropertyName("language")] public string Language { get; set; } = ""; } - - - /// - /// contains texts needed for displaying UI in a single language - /// - public class SingleLanguage - { - public Dictionary text { get; set; } = new Dictionary(); - - // key of all_text ref is a combination ${language,id} - public SingleLanguage(string language, ref Dictionary all_text) - { - - } - } } diff --git a/roles/lib/files/FWO.Config.Api/FWO.Config.Api.csproj b/roles/lib/files/FWO.Config.Api/FWO.Config.Api.csproj index 0c705e24c9..5924f3c09b 100644 --- a/roles/lib/files/FWO.Config.Api/FWO.Config.Api.csproj +++ b/roles/lib/files/FWO.Config.Api/FWO.Config.Api.csproj @@ -1,12 +1,13 @@ - net6.0 + net10.0 enable enable + diff --git a/roles/lib/files/FWO.Config.Api/GlobalConfig.cs b/roles/lib/files/FWO.Config.Api/GlobalConfig.cs index d9878e5017..0ece20fd7a 100644 --- a/roles/lib/files/FWO.Config.Api/GlobalConfig.cs +++ b/roles/lib/files/FWO.Config.Api/GlobalConfig.cs @@ -1,11 +1,9 @@ -using System; -using System.Collections.Generic; using FWO.Logging; using FWO.Config.File; +using FWO.Basics; using FWO.Api.Client; using FWO.Config.Api.Data; using FWO.Api.Client.Queries; -using System.ComponentModel; namespace FWO.Config.Api { @@ -15,28 +13,29 @@ namespace FWO.Config.Api public class GlobalConfig : Config { /// - /// Global string constants used e.g. as database keys etc. + /// Global config constants /// - public static readonly string kEnglish = "English"; + public string ProductVersion { get; set; } + public Language[] UiLanguages { get; set; } + public Dictionary> LangDict { get; set; } + public Dictionary> OverDict { get; set; } - public static readonly int kSidebarLeftWidth = 300; - public static readonly int kSidebarRightWidth = 300; - - public static readonly string kAutodiscovery = "autodiscovery"; - public static readonly string kDailyCheck = "dailycheck"; - public static readonly string kUi = "ui"; - - public string productVersion { get; set; } - - public Language[] uiLanguages { get; set; } - public Dictionary> langDict { get; set; } + /// + /// create a config collection (used centrally once in a UI server for all users) + /// + public static async Task ConstructAsync(string jwt, bool loadLanguageData = true, bool withSubscription = false) + { + ApiConnection apiConnection = new GraphQlApiConnection(ConfigFile.ApiServerUri, jwt); + return await ConstructAsync(apiConnection, loadLanguageData, withSubscription, owningApiConnection: true); + } - public static async Task ConstructAsync(ApiConnection apiConnection, bool loadLanguageData = true) + public static async Task ConstructAsync(ApiConnection apiConnection, bool loadLanguageData = true, bool withSubscription = false, bool owningApiConnection = false) { string productVersion = ConfigFile.ProductVersion; - Language[] uiLanguages = Array.Empty(); - Dictionary> langDict = new(); + Language[] uiLanguages = []; + Dictionary> tmpLangDicts = []; + Dictionary> tmpLangOverDicts = []; if (loadLanguageData) { @@ -52,16 +51,11 @@ public static async Task ConstructAsync(ApiConnection apiConnectio } try { + // add language dictionaries to dictionary of dictionaries foreach (Language lang in uiLanguages) { - var languageVariable = new { language = lang.Name }; - Dictionary dict = new(); - UiText[] uiTexts = await apiConnection.SendQueryAsync(ConfigQueries.getTextsPerLanguage, languageVariable); - foreach (UiText text in uiTexts) - dict.Add(text.Id, text.Txt); // add "word" to dictionary - - // add language dictionary to dictionary of dictionaries - langDict.Add(lang.Name, dict); + tmpLangDicts.Add(lang.Name, await LoadLangDict(lang, apiConnection)); + tmpLangOverDicts.Add(lang.Name, await LoadLangDict(lang, apiConnection, true)); } } catch (Exception exception) @@ -71,34 +65,83 @@ public static async Task ConstructAsync(ApiConnection apiConnectio } } - return new GlobalConfig(apiConnection, productVersion, uiLanguages, langDict); + return new GlobalConfig(apiConnection, productVersion, uiLanguages, tmpLangDicts, tmpLangOverDicts, withSubscription, owningApiConnection); + } + + /// + /// constructor only used in unit tests + /// + public GlobalConfig() : base() + { + ProductVersion = "1.0"; + UiLanguages = []; + LangDict = []; + OverDict = []; } - public static async Task ConstructAsync(string jwt, bool loadLanguageData = true) + private GlobalConfig(ApiConnection apiConnection, string productVersion, Language[] uiLanguages, Dictionary> langDict, + Dictionary> overDict, bool withSubscription = false, bool owningApiConnection = false) + : base(apiConnection, 0, withSubscription, owningApiConnection) { - ApiConnection apiConnection = new GraphQlApiConnection(ConfigFile.ApiServerUri, jwt); - return await ConstructAsync(apiConnection, loadLanguageData); + ProductVersion = productVersion; + UiLanguages = uiLanguages; + LangDict = langDict; + OverDict = overDict; } - public override string GetText(string key) + public override string GetText(string key) { - if(langDict.ContainsKey(DefaultLanguage) && langDict[DefaultLanguage].ContainsKey(key)) + ThrowIfDisposed(); + return GetTextInLanguage(key, DefaultLanguage); + } + + public string GetNotificationLanguage() + { + ThrowIfDisposed(); + return string.IsNullOrWhiteSpace(NotificationLanguage) ? DefaultLanguage : NotificationLanguage; + } + + public string GetNotificationText(string key) + { + ThrowIfDisposed(); + return GetTextInLanguage(key, GetNotificationLanguage()); + } + + public string GetTextInLanguage(string key, string? languageName) + { + ThrowIfDisposed(); + string resolvedLanguage = string.IsNullOrWhiteSpace(languageName) ? DefaultLanguage : languageName; + if (LangDict.TryGetValue(resolvedLanguage, out Dictionary? langDict) && langDict.TryGetValue(key, out string? value)) { - return System.Web.HttpUtility.HtmlDecode(langDict[DefaultLanguage][key]); + return System.Web.HttpUtility.HtmlDecode(value); } - return "(undefined text)"; - } + if (resolvedLanguage != DefaultLanguage && LangDict.TryGetValue(DefaultLanguage, out Dictionary? defaultLangDict) + && defaultLangDict.TryGetValue(key, out string? defaultValue)) + { + return System.Web.HttpUtility.HtmlDecode(defaultValue); + } - /// - /// create a config collection (used centrally once in a UI server for all users) - /// - private GlobalConfig(ApiConnection apiConnection, string productVersion, Language[] uiLanguages, Dictionary> langDict) - : base(apiConnection, 0) + if (resolvedLanguage != GlobalConst.kEnglish && DefaultLanguage != GlobalConst.kEnglish + && LangDict.TryGetValue(GlobalConst.kEnglish, out Dictionary? englishLangDict) + && englishLangDict.TryGetValue(key, out string? englishValue)) + { + return System.Web.HttpUtility.HtmlDecode(englishValue); + } + + return GlobalConst.kUndefinedText; + } + + private static async Task> LoadLangDict(Language lang, ApiConnection apiConnection, bool over = false) { - this.productVersion = productVersion; - this.uiLanguages = uiLanguages; - this.langDict = langDict; + var languageVariable = new { language = lang.Name }; + Dictionary dict = []; + List uiTexts = await apiConnection.SendQueryAsync>(over ? ConfigQueries.getCustomTextsPerLanguage : ConfigQueries.getTextsPerLanguage, languageVariable); + foreach (UiText text in uiTexts) + { + dict.Add(text.Id, text.Txt); // add "word" to dictionary + } + return dict; } } } diff --git a/roles/lib/files/FWO.Config.Api/UserConfig.cs b/roles/lib/files/FWO.Config.Api/UserConfig.cs index 16fd11830c..e38c5ec3da 100644 --- a/roles/lib/files/FWO.Config.Api/UserConfig.cs +++ b/roles/lib/files/FWO.Config.Api/UserConfig.cs @@ -1,8 +1,9 @@ -using System.Text.RegularExpressions; +using System.Text.RegularExpressions; +using FWO.Basics; using FWO.Logging; using FWO.Config.Api.Data; using FWO.Api.Client; -using FWO.Api.Data; +using FWO.Data; using FWO.Api.Client.Queries; using System.Reflection; using System.Text.Json.Serialization; @@ -14,49 +15,60 @@ namespace FWO.Config.Api /// public class UserConfig : Config { - private readonly GlobalConfig globalConfig; + public GlobalConfig? GlobalConfig => globalConfig; + private readonly GlobalConfig? globalConfig; - public Dictionary Translate { get; set; } + public Dictionary Translate { get; set; } = []; + public Dictionary Overwrite { get; set; } = []; public UiUser User { private set; get; } - public static async Task ConstructAsync(GlobalConfig globalConfig, ApiConnection apiConnection, int userId) + public static async Task ConstructAsync(GlobalConfig globalConfig, ApiConnection apiConnection, int userId, bool owningApiConnection = false) { UiUser[] users = await apiConnection.SendQueryAsync(AuthQueries.getUserByDbId, new { userId = userId }); UiUser? user = users.FirstOrDefault(); if (user == null) { Log.WriteError("Load user config", $"User with id {userId} could not be found in database."); - throw new Exception(); + throw new KeyNotFoundException(); } - return new UserConfig(globalConfig, apiConnection, user); + return new UserConfig(globalConfig, apiConnection, user, owningApiConnection); } - public UserConfig(GlobalConfig globalConfig, ApiConnection apiConnection, UiUser user) : base(apiConnection, user.DbId) + public UserConfig(GlobalConfig globalConfig, ApiConnection apiConnection, UiUser user, bool owningApiConnection = false) : base(apiConnection, user.DbId, withSubscription: false, owningApiConnection) { User = user; - Translate = globalConfig.langDict[user.Language!]; + Translate = globalConfig.LangDict[user.Language!]; + Overwrite = apiConnection != null ? Task.Run(async () => await GetCustomDict(user.Language!)).Result : globalConfig.OverDict[user.Language!]; this.globalConfig = globalConfig; - globalConfig.OnChange += GlobalConfigOnChange; + OnGlobalConfigChange(globalConfig, globalConfig.RawConfigItems); + globalConfig.OnChange += OnGlobalConfigChange; } - public UserConfig(GlobalConfig globalConfig) : base() + // Warning: only for Texts, ConfigItems contain Default content, correct ConfigItems are only in this.globalConfig + public UserConfig(GlobalConfig globalConfig, bool registerOnChangeHandler = true) : base() { User = new UiUser(); - Translate = globalConfig.langDict[globalConfig.DefaultLanguage]; + Translate = globalConfig.LangDict[globalConfig.DefaultLanguage]; this.globalConfig = globalConfig; - globalConfig.OnChange += GlobalConfigOnChange; + + if (registerOnChangeHandler) + { + globalConfig.OnChange += OnGlobalConfigChange; + } } - // only for unit tests - protected UserConfig() : base() - {} - - private void GlobalConfigOnChange(Config config, ConfigItem[] changedItems) + public UserConfig() : base() { + User = new UiUser(); + } + + private void OnGlobalConfigChange(Config config, ConfigItem[] changedItems) + { + if (IsDisposed) return; // Get properties that belong to the user config IEnumerable properties = GetType().GetProperties() - .Where(prop => prop.CustomAttributes.Any(attr => attr.GetType() == typeof(UserConfigDataAttribute))); + .Where(prop => prop.GetCustomAttribute() != null); // Exclude all properties from update that belong to the user config ConfigItem[] relevantChangedItems = changedItems.Where(configItem => @@ -68,12 +80,18 @@ private void GlobalConfigOnChange(Config config, ConfigItem[] changedItems) public async Task SetUserInformation(string userDn, ApiConnection apiConnection) { - GlobalConfigOnChange(globalConfig, globalConfig.RawConfigItems); + ThrowIfDisposed(); + if (globalConfig != null) + { + OnGlobalConfigChange(globalConfig, globalConfig.RawConfigItems); + } Log.WriteDebug("Get User Data", $"Get user data from user with DN: \"{userDn}\""); UiUser[]? users = await apiConnection.SendQueryAsync(AuthQueries.getUserByDn, new { dn = userDn }); if (users.Length > 0) + { User = users[0]; - await SetUserId(apiConnection, User.DbId); + } + await InitWithUserId(apiConnection, User.DbId, true); if (User.Language == null) { @@ -84,56 +102,181 @@ public async Task SetUserInformation(string userDn, ApiConnection apiConnection) public async Task ChangeLanguage(string languageName, ApiConnection apiConnection) { - await apiConnection.SendQueryAsync(AuthQueries.updateUserLanguage, new { id = User.DbId, language = languageName }); - Translate = globalConfig.langDict[languageName]; - User.Language = languageName; - InvokeOnChange(this, null); + ThrowIfDisposed(); + if (globalConfig != null) + { + await apiConnection.SendQueryAsync(AuthQueries.updateUserLanguage, new { id = User.DbId, language = languageName }); + Translate = globalConfig.LangDict[languageName]; + Overwrite = apiConnection != null ? await GetCustomDict(languageName) : globalConfig.OverDict[languageName]; + User.Language = languageName; + InvokeOnChange(this, []); + } } public string GetUserLanguage() { + ThrowIfDisposed(); return User.Language ?? ""; } public void SetLanguage(string languageName) { - User = new UiUser() { Language = globalConfig.DefaultLanguage }; - if (languageName != null && languageName != "") + ThrowIfDisposed(); + string defaultLanguage = globalConfig != null ? globalConfig.DefaultLanguage : GlobalConst.kEnglish; + + User = new UiUser() { - User.Language = languageName; - } - if (globalConfig.langDict.ContainsKey(User.Language)) + Language = languageName != null && languageName != "" ? languageName : defaultLanguage + }; + if (globalConfig != null && globalConfig.LangDict.TryGetValue(User.Language, out Dictionary? langDict)) { - Translate = globalConfig.langDict[User.Language]; + Translate = langDict; + Overwrite = globalConfig.OverDict[User.Language]; } } public override string GetText(string key) { - if (Translate.ContainsKey(key)) + ThrowIfDisposed(); + if (Overwrite != null && Overwrite.TryGetValue(key, out string? overwriteValue)) { - return Convert(Translate[key]); + return Convert(overwriteValue); + } + if (Translate != null && Translate.TryGetValue(key, out string? translateValue)) + { + return Convert(translateValue); } else { - string defaultLanguage = globalConfig.DefaultLanguage; - if (defaultLanguage == "") + if (globalConfig != null) { - defaultLanguage = GlobalConfig.kEnglish; + string defaultLanguage = globalConfig.DefaultLanguage; + if (defaultLanguage == "") + { + defaultLanguage = GlobalConst.kEnglish; + } + if (globalConfig.LangDict[defaultLanguage].TryGetValue(key, out string? defaultLangValue)) + { + return Convert(defaultLangValue); + } + else if (defaultLanguage != GlobalConst.kEnglish && globalConfig.LangDict[GlobalConst.kEnglish].TryGetValue(key, out string? englValue)) + { + return Convert(englValue); + } } - if (globalConfig.langDict[defaultLanguage].ContainsKey(key)) + return GlobalConst.kUndefinedText; + } + } + + public string PureLine(string text) + { + ThrowIfDisposed(); + return PureLineStat(GetText(text)); + } + + public static string PureLineStat(string text) + { + var regex = new Regex(@"\s", RegexOptions.None, TimeSpan.FromSeconds(1)); + string output = RemoveLinks(regex.Replace(text.Trim(), " ")); + output = ReplaceListElems(output); + bool cont = true; + while (cont) + { + string outputOrig = output; + output = Regex.Replace(outputOrig, @" ", " "); + if (output.Length == outputOrig.Length) { - return Convert(globalConfig.langDict[defaultLanguage][key]); + cont = false; } - else if (defaultLanguage != GlobalConfig.kEnglish && globalConfig.langDict[GlobalConfig.kEnglish].ContainsKey(key)) + } + return output; + } + + public string GetApiText(string key) + { + ThrowIfDisposed(); + string text = key; + string pattern = @"[A]\d\d\d\d"; + Match m = Regex.Match(key, pattern); + if (m.Success) + { + string msg = GetText(key[..5]); + if (msg != GlobalConst.kUndefinedText) { - return Convert(globalConfig.langDict[GlobalConfig.kEnglish][key]); + text = msg; + } + } + return text; + } + + public async Task> GetCustomDict(string languageName) + { + ThrowIfDisposed(); + Dictionary dict = []; + if (apiConnection == null) + { + Log.WriteError("ApiConnection is null", "The ApiConnection is not initialized."); + return dict; + } + try + { + List uiTexts = await apiConnection.SendQueryAsync>(ConfigQueries.getCustomTextsPerLanguage, new { language = languageName }); + if (uiTexts != null) + { + foreach (UiText text in uiTexts) + { + dict.Add(text.Id, text.Txt); + } + } + } + catch (Exception exception) + { + Log.WriteError("Read custom dictionary", $"Could not read custom dict.", exception); + } + return dict; + } + + private static string RemoveLinks(string txtString) + { + string startLink = "= 0) + { + end = txtString.IndexOf('>', begin + startLink.Length); + if (end > 0) + { + txtString = txtString.Remove(begin, end - begin + 1); + } + else + { + cont = false; + } } else { - return "(undefined text)"; + cont = false; } } + txtString = Regex.Replace(txtString, "", ""); + return txtString; + } + + private static string ReplaceListElems(string txtString) + { + txtString = Regex.Replace(txtString, "
                        ", ""); + txtString = Regex.Replace(txtString, "
                      ", ""); + txtString = Regex.Replace(txtString, "
                        ", ""); + txtString = Regex.Replace(txtString, "
                      ", ""); + txtString = Regex.Replace(txtString, "
                    • ", "\r\n"); + txtString = Regex.Replace(txtString, "
                    • ", ""); + txtString = Regex.Replace(txtString, "
                      ", "\r\n"); + return txtString; } private string Convert(string rawText) @@ -155,7 +298,7 @@ private string Convert(string rawText) begin = plainText.IndexOf(startLink, index); if (begin >= 0) { - end = plainText.IndexOf("\"", begin + startLink.Length); + end = plainText.IndexOf('"', begin + startLink.Length); if (end > 0) { plainText = plainText.Insert(end, insertString); @@ -175,20 +318,14 @@ private string Convert(string rawText) return plainText; } - public string GetApiText(string key) + protected override void Dispose(bool disposing) { - string text = key; - string pattern = @"[A]\d\d\d\d"; - Match m = Regex.Match(key, pattern); - if (m.Success) + if (disposing && globalConfig != null) { - string msg = GetText(key.Substring(0, 5)); - if (msg != "(undefined text)") - { - text = msg; - } + globalConfig.OnChange -= OnGlobalConfigChange; } - return text; + + base.Dispose(disposing); // Call base class dispose } } } diff --git a/roles/lib/files/FWO.Config.File/ConfigFile.cs b/roles/lib/files/FWO.Config.File/ConfigFile.cs index c76317e398..e0c5678a18 100644 --- a/roles/lib/files/FWO.Config.File/ConfigFile.cs +++ b/roles/lib/files/FWO.Config.File/ConfigFile.cs @@ -1,9 +1,7 @@ -using FWO.Logging; +using FWO.Logging; using Microsoft.IdentityModel.Tokens; -using System; -using System.Collections.Generic; -using System.IO; using System.Text.Json; +using System.Text.Json.Serialization; namespace FWO.Config.File { @@ -26,23 +24,43 @@ public class ConfigFile private const string jwtPrivateKeyPath = basePath + "/secrets/jwt_private_key.pem"; /// - /// Internal connection to middleware server. Used to connect with api server. + /// All config data found in the main config file /// - //private readonly MiddlewareClient middlewareClient; + private class ConfigFileData + { + /// + /// Uri of the middleware server (http) + /// + [JsonPropertyName("middleware_native_uri")] + public string? MiddlewareServerNativeUri { get; set; } + + /// + /// Uri of the middleware server reverse proxy (https) + /// + [JsonPropertyName("middleware_uri")] + public string? MiddlewareServerUri { get; set; } + + [JsonPropertyName("api_uri")] + public string? ApiServerUri { get; set; } + + [JsonPropertyName("remote_addresses")] + public string[]? RemoteAddresses { get; set; } + + [JsonPropertyName("product_version")] + public string? ProductVersion { get; set; } + } /// - /// Internal connection to api server. Used to get/edit config data. + /// Config file data found in the main config file /// - //private readonly APIConnection apiConnection; - + private static ConfigFileData Data { get; set; } = new ConfigFileData(); private static RsaSecurityKey? jwtPrivateKey = null; public static RsaSecurityKey JwtPrivateKey { get { - jwtPrivateKey = CriticalConfigValueLoaded(jwtPrivateKey); - return jwtPrivateKey; + return CriticalConfigValueLoaded(jwtPrivateKey); } } @@ -51,57 +69,47 @@ public static RsaSecurityKey JwtPublicKey { get { - jwtPublicKey = CriticalConfigValueLoaded(jwtPublicKey); - return jwtPublicKey; + return CriticalConfigValueLoaded(jwtPublicKey); } } - private static string? apiServerUri = null; public static string ApiServerUri { get { - apiServerUri = CriticalConfigValueLoaded(apiServerUri); - return apiServerUri; + return CriticalConfigValueLoaded(Data.ApiServerUri); } } - private static string? middlewareServerNativeUri = null; public static string MiddlewareServerNativeUri { get { - middlewareServerNativeUri = CriticalConfigValueLoaded(middlewareServerNativeUri); - return middlewareServerNativeUri; + return CriticalConfigValueLoaded(Data.MiddlewareServerNativeUri); } } - private static string? middlewareServerUri = null; public static string MiddlewareServerUri { get { - middlewareServerUri = CriticalConfigValueLoaded(middlewareServerUri); - return middlewareServerUri; + return CriticalConfigValueLoaded(Data.MiddlewareServerUri); } } - private static string? productVersion = null; public static string ProductVersion { get { - productVersion = CriticalConfigValueLoaded(productVersion); - return productVersion; + return CriticalConfigValueLoaded(Data.ProductVersion); } } - private static Dictionary customSettings = new Dictionary(); - public Dictionary CustomSettings + public static string[] RemoteAddresses { get { - return customSettings; + return CriticalConfigValueLoaded(Data.RemoteAddresses); } } @@ -114,21 +122,17 @@ private static void Read(string configFilePath, string privateKeyFilePath, strin { try { - // Reset all values - jwtPrivateKey = null; - jwtPublicKey = null; - middlewareServerNativeUri = null; - middlewareServerUri = null; - apiServerUri = null; - productVersion = null; - // Read config as json from file string configFile = System.IO.File.ReadAllText(configFilePath).TrimEnd(); // Deserialize config to dictionary - Dictionary configFileData = JsonSerializer.Deserialize>(configFile) ?? throw new Exception("Config file could not be parsed."); + Data = JsonSerializer.Deserialize(configFile) ?? throw new JsonException("Config file could not be parsed."); - // Errors can be ignored. If a configuration value that could not be loaded is requested from outside this class, an excpetion is thrown. See NotNullCriticalConfigValue() + // Errors can be ignored. If a configuration value that could not be loaded is requested from outside this class, an excpetion is thrown. See CriticalConfigValueLoaded() + + // Reset all keys + jwtPrivateKey = null; + jwtPublicKey = null; // Try to read jwt private key IgnoreExceptions(() => jwtPrivateKey = KeyImporter.ExtractKeyFromPem(System.IO.File.ReadAllText(privateKeyFilePath), isPrivateKey: true)); @@ -136,17 +140,6 @@ private static void Read(string configFilePath, string privateKeyFilePath, strin // Try to read jwt public key IgnoreExceptions(() => jwtPublicKey = KeyImporter.ExtractKeyFromPem(System.IO.File.ReadAllText(publicKeyFilePath), isPrivateKey: false)); - // Try to get uri of the middleware server (http) - IgnoreExceptions(() => middlewareServerNativeUri = configFileData["middleware_native_uri"]); - - // Try to get uri of the middleware server reverse proxy (https) - IgnoreExceptions(() => middlewareServerUri = configFileData["middleware_uri"]); - - // Try to get api uri - IgnoreExceptions(() => apiServerUri = configFileData["api_uri"]); - - // Try to get productVersion - IgnoreExceptions(() => productVersion = configFileData["product_version"]); } catch (Exception configFileReadException) { @@ -173,10 +166,10 @@ private static ConfigValueType CriticalConfigValueLoaded(Config return configValue; } } - + private static void IgnoreExceptions(Action method) { - try { method(); } catch (Exception e){ Log.WriteDebug("Config value", $"Config value could not be loaded. Error: {e.Message}"); } + try { method(); } catch (Exception e) { Log.WriteDebug("Config value", $"Config value could not be loaded. Error: {e.Message}"); } } } } diff --git a/roles/lib/files/FWO.Config.File/FWO.Config.File.csproj b/roles/lib/files/FWO.Config.File/FWO.Config.File.csproj index 81c80289e2..841d81aa5a 100644 --- a/roles/lib/files/FWO.Config.File/FWO.Config.File.csproj +++ b/roles/lib/files/FWO.Config.File/FWO.Config.File.csproj @@ -1,16 +1,17 @@ - + - net6.0 + net10.0 enable enable - + + diff --git a/roles/lib/files/FWO.Config.File/KeyImporter.cs b/roles/lib/files/FWO.Config.File/KeyImporter.cs index 03527e383e..386633dc2f 100644 --- a/roles/lib/files/FWO.Config.File/KeyImporter.cs +++ b/roles/lib/files/FWO.Config.File/KeyImporter.cs @@ -1,4 +1,4 @@ -using FWO.Logging; +using FWO.Logging; using Microsoft.IdentityModel.Tokens; using System; using System.Collections.Generic; @@ -17,7 +17,7 @@ public class KeyImporter { byte[] keyBytes = Convert.FromBase64String(keyText); // creating the RSA key - RSACryptoServiceProvider provider = new RSACryptoServiceProvider(); + RSACryptoServiceProvider provider = new(3072); // keylength just given for satisfying sonarcube checks (as we import the key later) if (isPrivateKey) { if (isRsaKey) @@ -72,7 +72,7 @@ private static (string key, bool isRsa) ExtractKeyFromPemAsString(string rawKey) Log.WriteError("Key extraction", "Error while trying to read key from file.", exception); throw; } - + Log.WriteDebug("Key extraction", "Key was succesfully extracted."); return (keyText, isRsaKey); } diff --git a/roles/lib/files/FWO.Api.Client/Data/ActionItem.cs b/roles/lib/files/FWO.Data/ActionItem.cs similarity index 97% rename from roles/lib/files/FWO.Api.Client/Data/ActionItem.cs rename to roles/lib/files/FWO.Data/ActionItem.cs index 6236100a42..b73d602b31 100644 --- a/roles/lib/files/FWO.Api.Client/Data/ActionItem.cs +++ b/roles/lib/files/FWO.Data/ActionItem.cs @@ -1,4 +1,4 @@ -namespace FWO.Api.Data +namespace FWO.Data { public enum ActionCode { @@ -33,7 +33,7 @@ public class ActionItem public bool Done { get; set; } = false; public ActionItem() - {} + { } public ActionItem(Alert alert) { diff --git a/roles/lib/files/FWO.Api.Client/Data/Alert.cs b/roles/lib/files/FWO.Data/Alert.cs similarity index 90% rename from roles/lib/files/FWO.Api.Client/Data/Alert.cs rename to roles/lib/files/FWO.Data/Alert.cs index 5f6e0fdd16..6e61df1363 100644 --- a/roles/lib/files/FWO.Api.Client/Data/Alert.cs +++ b/roles/lib/files/FWO.Data/Alert.cs @@ -1,7 +1,7 @@ using System.Text.Json.Serialization; using Newtonsoft.Json; -namespace FWO.Api.Data +namespace FWO.Data { public enum AlertCode { @@ -18,11 +18,23 @@ public enum AlertCode ImportBrokenObjectReferences = 16, MalformedIpAddress = 17, RecursionLimitReached = 18, - + Autodiscovery = 21, AutoDiscoveryErrorUnspecific = 22, - WorkflowAlert = 31 + WorkflowAlert = 31, + + ImportAppData = 41, + ImportAreaSubnetData = 42, + AdjustAppServerNames = 43, + + ImportChangeNotify = 51, + + ExternalRequest = 61, + + VarianceAnalysis = 71, + + ComplianceCheck = 81 } public class Alert diff --git a/roles/lib/files/FWO.Data/ApiCrudHelper.cs b/roles/lib/files/FWO.Data/ApiCrudHelper.cs new file mode 100644 index 0000000000..2a29be73f5 --- /dev/null +++ b/roles/lib/files/FWO.Data/ApiCrudHelper.cs @@ -0,0 +1,89 @@ +using System.Text.Json.Serialization; +using Newtonsoft.Json; +using FWO.Data; + +namespace FWO.Data +{ + public class ReturnId + { + [JsonProperty("newId"), JsonPropertyName("newId")] + public int NewId { get; set; } + + [JsonProperty("newIdLong"), JsonPropertyName("newIdLong")] + public long NewIdLong { get; set; } + + [JsonProperty("updatedId"), JsonPropertyName("updatedId")] + public int UpdatedId { get; set; } + + [JsonProperty("id"), JsonPropertyName("id")] + public long? Id { get; set; } + + [JsonProperty("updatedIdLong"), JsonPropertyName("updatedIdLong")] + public long UpdatedIdLong { get; set; } + + [JsonProperty("deletedId"), JsonPropertyName("deletedId")] + public int DeletedId { get; set; } + + [JsonProperty("deletedIdLong"), JsonPropertyName("deletedIdLong")] + public long DeletedIdLong { get; set; } + + [JsonProperty("insertedId"), JsonPropertyName("insertedId")] + public int InsertedId { get; set; } + + [JsonProperty("insertedIdLong"), JsonPropertyName("insertedIdLong")] + public long InsertedIdLong { get; set; } + + [JsonProperty("affected_rows"), JsonPropertyName("affected_rows")] + public int AffectedRows { get; set; } + + [JsonProperty("uiuser_password_must_be_changed"), JsonPropertyName("uiuser_password_must_be_changed")] + public bool PasswordMustBeChanged { get; set; } + } + + public class ReturnIdWrapper + { + [JsonProperty("returning"), JsonPropertyName("returning")] + public ReturnId[]? ReturnIds { get; set; } + } + + public class AggregateCountLastHit + // NOSONAR - temporarily disabled { + // [JsonProperty("device"), JsonPropertyName("device")] + // public List Devices {get; set;} = []; + // } + // public class DeviceLastHit + { + [JsonProperty("rulebase_link"), JsonPropertyName("rulebase_link")] + public List RulebasesOnGateway { get; set; } = []; + } + + public class RulebaseOnGatewaysLastHit + { + [JsonProperty("rulebase"), JsonPropertyName("rulebase")] + public RulebaseLastHit Rulebase { get; set; } = new RulebaseLastHit(); + } + + public class RulebaseLastHit + { + [JsonProperty("rulesWithHits"), JsonPropertyName("rulesWithHits")] + public AggregateCount RulesWithHits { get; set; } = new AggregateCount(); + } + + public class AggregateCount + { + [JsonProperty("aggregate"), JsonPropertyName("aggregate")] + public Aggregate Aggregate { get; set; } = new Aggregate(); + } + + public class Aggregate + { + [JsonProperty("count"), JsonPropertyName("count")] + public int Count { get; set; } + } + + public class DeleteAllViolationsResult + { + [JsonProperty("affected_rows"), JsonPropertyName("affected_rows")] + public int AffectedRows { get; set; } + } +} diff --git a/roles/lib/files/FWO.Data/CSVAppServerImportModel.cs b/roles/lib/files/FWO.Data/CSVAppServerImportModel.cs new file mode 100644 index 0000000000..07a0afca68 --- /dev/null +++ b/roles/lib/files/FWO.Data/CSVAppServerImportModel.cs @@ -0,0 +1,34 @@ +using FWO.Basics; +using FWO.Data.Modelling; + +namespace FWO.Data +{ + public class CSVAppServerImportModel + { + public string? AppServerName { get; set; } + public string? AppID { get; set; } + public string? AppServerTyp { get; set; } + public string? AppIPRangeStart { get; set; } + public string? AppIPRangeEnd { get; set; } + + public CSVAppServerImportModel(string ipString) + { + (AppIPRangeStart, AppIPRangeEnd) = IpOperations.SplitIpToRange(ipString); + } + + public CSVAppServerImportModel() + { + + } + + public ModellingAppServer ToModellingAppServer() + { + return new ModellingAppServer() + { + Name = AppServerName ?? "", + Ip = AppIPRangeStart ?? "", + IpEnd = AppIPRangeEnd ?? "" + }; + } + } +} diff --git a/roles/lib/files/FWO.Data/CSVFileUploadErrorModel.cs b/roles/lib/files/FWO.Data/CSVFileUploadErrorModel.cs new file mode 100644 index 0000000000..15cb6dc5d5 --- /dev/null +++ b/roles/lib/files/FWO.Data/CSVFileUploadErrorModel.cs @@ -0,0 +1,17 @@ +namespace FWO.Data +{ + /// + /// Defines a model for errors that occured on csv file upload + /// + public class CSVFileUploadErrorModel : ErrorBaseModel + { + public CSVFileUploadErrorModel() : base() + { + } + + /// + /// Additional Data/Info + /// + public string? EntryData { get; set; } + } +} diff --git a/roles/lib/files/FWO.Api.Client/Data/ChangeImport.cs b/roles/lib/files/FWO.Data/ChangeImport.cs similarity index 78% rename from roles/lib/files/FWO.Api.Client/Data/ChangeImport.cs rename to roles/lib/files/FWO.Data/ChangeImport.cs index bb3fa3c986..ab2b18c936 100644 --- a/roles/lib/files/FWO.Api.Client/Data/ChangeImport.cs +++ b/roles/lib/files/FWO.Data/ChangeImport.cs @@ -1,19 +1,19 @@ using System; using System.Collections.Generic; using System.Linq; -using System.Text.Json.Serialization; +using System.Text.Json.Serialization; using Newtonsoft.Json; using System.Threading.Tasks; -namespace FWO.Api.Data +namespace FWO.Data { public class ChangeImport { [JsonProperty("time"), JsonPropertyName("time")] public DateTime Time { get; set; } - public ChangeImport() {} - + public ChangeImport() { } + public ChangeImport(ChangeImport changeImport) { Time = changeImport.Time; diff --git a/roles/lib/files/FWO.Data/ChangeLogConstants.cs b/roles/lib/files/FWO.Data/ChangeLogConstants.cs new file mode 100644 index 0000000000..630afa3e56 --- /dev/null +++ b/roles/lib/files/FWO.Data/ChangeLogConstants.cs @@ -0,0 +1,39 @@ +namespace FWO.Data +{ + public enum ChangeLogFamily + { + Manual, + Import + } + + public enum ChangeLogObject + { + Matrix, + Management, + Gateway + } + + public enum ChangeLogOperation + { + Create, + Update, + Delete, + SetRemoved, + Disable, + Activate + } + + public enum PromptLogEvent + { + Created, + Dismissed, + Completed + } + + public enum ChangeLogOrigin + { + UiSettings, + Autodiscovery, + Import + } +} diff --git a/roles/lib/files/FWO.Data/Cidr.cs b/roles/lib/files/FWO.Data/Cidr.cs new file mode 100644 index 0000000000..bfaf0c127f --- /dev/null +++ b/roles/lib/files/FWO.Data/Cidr.cs @@ -0,0 +1,62 @@ +using NetTools; + +namespace FWO.Data +{ + public class Cidr + { + private IPAddressRange IpRange { get; set; } = new IPAddressRange(); + + public bool Valid { get; set; } = false; + + public string CidrString + { + get => this.GetCidrString(); + set => this.SetCidrFromString(value); + } + + public Cidr() + { } + + public Cidr(string value) + { + this.SetCidrFromString(value); + } + + private string GetCidrString() + { + return Valid ? IpRange.ToCidrString() : ""; + } + + private void SetCidrFromString(string value) + { + try + { + IpRange = IPAddressRange.Parse(value); + Valid = true; + // we only want cidr + try + { + IpRange.GetPrefixLength(); + } + catch (Exception) + { + // ignore range end + IpRange.End = IpRange.Begin; + } + } + catch (Exception) + { + Valid = false; + } + } + + public bool IsV6() + { + return CidrString.Contains(':'); + } + public bool IsV4() + { + return !IsV6(); + } + } +} diff --git a/roles/lib/files/FWO.Data/Color.cs b/roles/lib/files/FWO.Data/Color.cs new file mode 100644 index 0000000000..f17804d5af --- /dev/null +++ b/roles/lib/files/FWO.Data/Color.cs @@ -0,0 +1,12 @@ + +using System.Text.Json.Serialization; +using Newtonsoft.Json; + +namespace FWO.Data +{ + public class Color + { + [JsonProperty("color_name"), JsonPropertyName("color_name")] + public string Name { get; set; } = ""; + } +} diff --git a/roles/lib/files/FWO.Data/ComplianceCheckType.cs b/roles/lib/files/FWO.Data/ComplianceCheckType.cs new file mode 100644 index 0000000000..d6d584e991 --- /dev/null +++ b/roles/lib/files/FWO.Data/ComplianceCheckType.cs @@ -0,0 +1,7 @@ +namespace FWO.Data; + +public enum ComplianceCheckType +{ + Standard, + Variable +} diff --git a/roles/lib/files/FWO.Data/ComplianceCriterion.cs b/roles/lib/files/FWO.Data/ComplianceCriterion.cs new file mode 100644 index 0000000000..71eca20e1a --- /dev/null +++ b/roles/lib/files/FWO.Data/ComplianceCriterion.cs @@ -0,0 +1,49 @@ +using Newtonsoft.Json; +using System.Text.Json.Serialization; + +namespace FWO.Data +{ + public enum CriterionType + { + Matrix = 1, + Assessability = 2, + + ForbiddenService = 10, + ForbiddenSource = 11, + ForbiddenDestination = 12, + ForbiddenTrack = 13 + } + + public class ComplianceCriterion + { + [JsonProperty("id"), JsonPropertyName("id")] + public int Id { get; set; } + + [JsonProperty("name"), JsonPropertyName("name")] + public string Name { get; set; } = ""; + + [JsonProperty("import_source"), JsonPropertyName("import_source")] + public string ImportSource { get; set; } = ""; + + [JsonProperty("criterion_type"), JsonPropertyName("criterion_type")] + public string CriterionType { get; set; } = ""; + + [JsonProperty("content"), JsonPropertyName("content")] + public string Content { get; set; } = ""; + + [JsonProperty("comment"), JsonPropertyName("comment")] + public string? Comment { get; set; } + + [JsonProperty("created"), JsonPropertyName("created")] + public DateTime Created { get; set; } = DateTime.UtcNow; + + [JsonProperty("removed"), JsonPropertyName("removed")] + public DateTime? Removed { get; set; } + } + + public class ComplianceCriterionWrapper + { + [JsonProperty("criterion"), JsonPropertyName("criterion")] + public virtual ComplianceCriterion Content { get; set; } = new(); + } +} diff --git a/roles/lib/files/FWO.Data/ComplianceNetworkZone.cs b/roles/lib/files/FWO.Data/ComplianceNetworkZone.cs new file mode 100644 index 0000000000..0b5fc01b35 --- /dev/null +++ b/roles/lib/files/FWO.Data/ComplianceNetworkZone.cs @@ -0,0 +1,162 @@ +using FWO.Basics; +using NetTools; +using Newtonsoft.Json; +using System.Net; +using System.Text.Json.Serialization; + +namespace FWO.Data +{ + public class ComplianceNetworkZone + { + [JsonProperty("id"), JsonPropertyName("id")] + public int Id { get; set; } = -1; + + [JsonProperty("name"), JsonPropertyName("name")] + public string Name { get; set; } = ""; + + [JsonProperty("id_string"), JsonPropertyName("id_string")] + public string IdString { get; set; } = ""; + + [JsonProperty("description"), JsonPropertyName("description")] + public string Description { get; set; } = ""; + + [JsonProperty("ip_ranges", ItemConverterType = typeof(IpAddressRangeJsonTypeConverter)), JsonPropertyName("ip_ranges")] + public IPAddressRange[] IPRanges { get; set; } = []; + + [JsonProperty("super_network_zone"), JsonPropertyName("super_network_zone")] + public ComplianceNetworkZone? Superzone { get; set; } = null; + + [JsonProperty("sub_network_zones"), JsonPropertyName("sub_network_zones")] + public ComplianceNetworkZone[] Subzones { get; set; } = []; + + [JsonProperty("network_zone_communication_sources", ItemConverterType = typeof(WrapperConverter), + ItemConverterParameters = ["from_network_zone"]), JsonPropertyName("network_zone_communication_sources")] + public ComplianceNetworkZone[] AllowedCommunicationSources { get; set; } = []; + + [JsonProperty("network_zone_communication_destinations", ItemConverterType = typeof(WrapperConverter), + ItemConverterParameters = ["to_network_zone"]), JsonPropertyName("network_zone_communication_destinations")] + public ComplianceNetworkZone[] AllowedCommunicationDestinations { get; set; } = []; + + [JsonProperty("created"), JsonPropertyName("created")] + public DateTime Created { get; set; } + + [JsonProperty("removed"), JsonPropertyName("removed")] + public DateTime? Removed { get; set; } + + [JsonProperty("criterion_id"), JsonPropertyName("criterion_id")] + public int CriterionId { get; set; } = 0; + + [JsonProperty("is_auto_calculated_internet_zone"), JsonPropertyName("is_auto_calculated_internet_zone")] + public bool IsAutoCalculatedInternetZone { get; set; } = false; + + [JsonProperty("is_auto_calculated_undefined_internal_zone"), JsonPropertyName("is_auto_calculated_undefined_internal_zone")] + public bool IsAutoCalculatedUndefinedInternalZone { get; set; } = false; + + public bool CommunicationAllowedFrom(ComplianceNetworkZone from) + { + return AllowedCommunicationSources.Contains(from); + } + + public bool CommunicationAllowedTo(ComplianceNetworkZone to) + { + return AllowedCommunicationDestinations.Contains(to); + } + + public bool OverlapExists(List ipRanges, List> unseenIpRanges) + { + bool result = false; + + for (int i = 0; i < IPRanges.Length; i++) + { + for (int j = 0; j < ipRanges.Count; j++) + { + if (IpOperations.RangeOverlapExists(IPRanges[i], ipRanges[j])) + { + result = true; + RemoveOverlap(unseenIpRanges[j], IPRanges[i]); + } + } + } + return result; + } + + private static void RemoveOverlap(List ranges, IPAddressRange toRemove) + { + for (int i = 0; i < ranges.Count; i++) + { + if (IpOperations.RangeOverlapExists(ranges[i], toRemove)) + { + if (IpOperations.IpToUint(toRemove.Begin) <= IpOperations.IpToUint(ranges[i].Begin) && IpOperations.IpToUint(toRemove.End) >= IpOperations.IpToUint(ranges[i].End)) + { + // Complete overlap, remove the entire range + ranges.RemoveAt(i); + i--; + } + else if (IpOperations.IpToUint(toRemove.Begin) <= IpOperations.IpToUint(ranges[i].Begin)) + { + // Overlap on the left side, update the start + ranges[i].Begin = IpOperations.UintToIp(IpOperations.IpToUint(toRemove.End) + 1); + } + else if (IpOperations.IpToUint(toRemove.End) >= IpOperations.IpToUint(ranges[i].End)) + { + // Overlap on the right side, update the end + ranges[i].End = IpOperations.UintToIp(IpOperations.IpToUint(toRemove.Begin) - 1); + } + else + { + // Overlap in the middle, split the range + // begin..remove.begin-1 + IPAddress end = ranges[i].End; + ranges[i].End = IpOperations.UintToIp(IpOperations.IpToUint(toRemove.Begin) - 1); + // remove.end+1..end + ranges.Insert(i, new IPAddressRange(IpOperations.UintToIp(IpOperations.IpToUint(toRemove.End) + 1), end)); + i++; + } + } + } + } + + public object Clone() + { + IPAddressRange[] ipRangesClone = new IPAddressRange[IPRanges.Length]; + for (int i = 0; i < IPRanges.Length; i++) + { + ipRangesClone[i] = new IPAddressRange(IPRanges[i].Begin, IPRanges[i].End); + } + + return new ComplianceNetworkZone() + { + Id = Id, + Superzone = (ComplianceNetworkZone?)Superzone?.Clone(), + Name = Name, + Description = Description, + IPRanges = ipRangesClone, + CriterionId = CriterionId, + Subzones = CloneArray(Subzones), + AllowedCommunicationSources = CloneArray(AllowedCommunicationSources), + AllowedCommunicationDestinations = CloneArray(AllowedCommunicationDestinations) + }; + } + + private static ComplianceNetworkZone[] CloneArray(ComplianceNetworkZone[] array) + { + ComplianceNetworkZone[] arrayClone = new ComplianceNetworkZone[array.Length]; + for (int i = 0; i < array.Length; i++) + { + arrayClone[i] = (ComplianceNetworkZone)array[i].Clone(); + } + return arrayClone; + } + + public override bool Equals(object? obj) + { + if (obj == null) return false; + return ((ComplianceNetworkZone)obj).Id == Id; + } + + public override int GetHashCode() + { + return HashCode.Combine(Id); + } + } +} diff --git a/roles/lib/files/FWO.Data/CompliancePolicy.cs b/roles/lib/files/FWO.Data/CompliancePolicy.cs new file mode 100644 index 0000000000..9b172693cf --- /dev/null +++ b/roles/lib/files/FWO.Data/CompliancePolicy.cs @@ -0,0 +1,32 @@ +using Newtonsoft.Json; +using System.Text.Json.Serialization; + +namespace FWO.Data +{ + public class CompliancePolicy + { + [JsonProperty("id"), JsonPropertyName("id")] + public int Id { get; set; } + + [JsonProperty("name"), JsonPropertyName("name")] + public string Name { get; set; } = ""; + + [JsonProperty("created_date"), JsonPropertyName("created_date")] + public DateTime CreatedDate { get; set; } = DateTime.Now; + + [JsonProperty("disabled"), JsonPropertyName("disabled")] + public bool Disabled { get; set; } = false; + + [JsonProperty("criteria"), JsonPropertyName("criteria")] + public List Criteria { get; set; } = []; + } + + public struct LinkedPolicy + { + [JsonProperty("criterion_id"), JsonPropertyName("criterion_id")] + public int CriterionId { get; set; } + + [JsonProperty("policy_id"), JsonPropertyName("policy_id")] + public int PolicyId { get; set; } + } +} diff --git a/roles/lib/files/FWO.Data/ComplianceViolation.cs b/roles/lib/files/FWO.Data/ComplianceViolation.cs new file mode 100644 index 0000000000..8598404d42 --- /dev/null +++ b/roles/lib/files/FWO.Data/ComplianceViolation.cs @@ -0,0 +1,115 @@ +using FWO.Basics.Interfaces; +using Newtonsoft.Json; +using System.Text.Json.Serialization; + + +namespace FWO.Data +{ + + [Newtonsoft.Json.JsonConverter(typeof(ComplianceViolationConverter))] + public class ComplianceViolation : ComplianceViolationBase, IComplianceViolation + { + [JsonProperty("id"), JsonPropertyName("id")] + public int Id { get; set; } = 0; + + public ComplianceViolationType Type { get; set; } = ComplianceViolationType.None; + + public ComplianceViolation() + { + + } + + public ComplianceViolation(int id, ComplianceViolationBase baseObj) + { + Id = id; + RuleId = baseObj.RuleId; + RuleUid = baseObj.RuleUid; + MgmtUid = baseObj.MgmtUid; + FoundDate = baseObj.FoundDate; + RemovedDate = baseObj.RemovedDate; + Details = baseObj.Details; + RiskScore = baseObj.RiskScore; + PolicyId = baseObj.PolicyId; + CriterionId = baseObj.CriterionId; + Criterion = baseObj.Criterion; + } + + + public ComplianceViolationType ParseViolationType(ComplianceCriterion? criterion) + { + if (criterion == null) + { + return ComplianceViolationType.None; + } + + switch (criterion.CriterionType) + { + case "Matrix": + return ComplianceViolationType.MatrixViolation; + + case "Assessability": + return ComplianceViolationType.NotAssessable; + + case "ForbiddenService": + return ComplianceViolationType.ServiceViolation; + + // TODO : implement for all criterion types + + default: + return ComplianceViolationType.None; + } + } + } + + /// + /// Insertable base class for compliance violations. + /// This class is used to insert new compliance violations into the database. + /// + public class ComplianceViolationBase + { + [JsonProperty("rule_id"), JsonPropertyName("rule_id")] + public int RuleId { get; set; } + [JsonProperty("rule_uid"), JsonPropertyName("rule_uid")] + public string RuleUid { get; set; } = ""; + [JsonProperty("mgmt_uid"), JsonPropertyName("mgmt_uid")] + public string MgmtUid { get; set; } = ""; + [JsonProperty("found_date"), JsonPropertyName("found_date")] + public DateTime FoundDate { get; set; } = DateTime.Now; + [JsonProperty("removed_date"), JsonPropertyName("removed_date")] + public DateTime? RemovedDate { get; set; } = null; + [JsonProperty("details"), JsonPropertyName("details")] + public string Details { get; set; } = ""; + [JsonProperty("risk_score"), JsonPropertyName("risk_score")] + public long RiskScore { get; set; } + [JsonProperty("policy_id"), JsonPropertyName("policy_id")] + public int PolicyId { get; set; } + [JsonProperty("criterion_id"), JsonPropertyName("criterion_id")] + public int CriterionId { get; set; } + [JsonProperty("criterion"), JsonPropertyName("criterion")] + public ComplianceCriterion? Criterion { get; set; } + + [JsonProperty("is_initial"), JsonPropertyName("is_initial")] + public bool IsInitial { get; set; } + + public static ComplianceViolationBase CreateBase(ComplianceViolation violation, bool isInitial) + { + return new() + { + RuleId = violation.RuleId, + RuleUid = violation.RuleUid, + MgmtUid = violation.MgmtUid, + FoundDate = violation.FoundDate, + RemovedDate = violation.RemovedDate, + Details = violation.Details, + RiskScore = violation.RiskScore, + PolicyId = violation.PolicyId, + CriterionId = violation.CriterionId, + Criterion = violation.Criterion, + IsInitial = isInitial + }; + + } + } +} + + diff --git a/roles/lib/files/FWO.Data/ComplianceViolationType.cs b/roles/lib/files/FWO.Data/ComplianceViolationType.cs new file mode 100644 index 0000000000..eb6680715e --- /dev/null +++ b/roles/lib/files/FWO.Data/ComplianceViolationType.cs @@ -0,0 +1,12 @@ +namespace FWO.Data +{ + public enum ComplianceViolationType + { + None, // rule is compliant + NotAssessable, // compliance cant be evaluated (e.g. zone internet) + MatrixViolation, + ServiceViolation, + MultipleViolations + + } +} diff --git a/roles/lib/files/FWO.Data/CustomFieldResolver.cs b/roles/lib/files/FWO.Data/CustomFieldResolver.cs new file mode 100644 index 0000000000..c6392a5605 --- /dev/null +++ b/roles/lib/files/FWO.Data/CustomFieldResolver.cs @@ -0,0 +1,79 @@ +using FWO.Logging; +using System.Text.Json; + +namespace FWO.Data +{ + /// + /// Provides helpers for reading typed values from a rule's serialized custom fields. + /// + public static class CustomFieldResolver + { + /// + /// Extracts the first matching custom field value from using the ordered keys in . + /// + /// The expected target type of the custom field value. + /// The rule containing the serialized custom fields. + /// A JSON array of candidate custom field keys to check in order. + /// + /// The deserialized custom field value when a matching key is found and can be converted to ; + /// otherwise, . + /// + public static T? ExtractCustomFieldValue(Rule? rule, string keysJson, out string? errorMessage) + { + errorMessage = null; + + if (rule == null || string.IsNullOrWhiteSpace(rule.CustomFields) || string.IsNullOrWhiteSpace(keysJson)) + { + return default; + } + + Dictionary customFields; + List keysList; + + try + { + customFields = JsonSerializer.Deserialize>(rule.CustomFields.Replace("'", "\"")) ?? new Dictionary(); + keysList = JsonSerializer.Deserialize>(keysJson) ?? new List(); + } + catch (JsonException e) + { + errorMessage = $"Error while resolving custom fields. Raw Data: {rule.CustomFields}"; + new Logger().TryWriteError("CustomFieldResolver", $"Error while resolving rule '{rule.Uid}': {e.Message}", true); + return default; + } + + if (customFields.Count == 0 || keysList.Count == 0) + { + return default; + } + + foreach (var key in keysList) + { + if (!customFields.TryGetValue(key, out var value)) + { + continue; + } + + if (value.ValueKind == JsonValueKind.Null || + value.ValueKind == JsonValueKind.Undefined || + (value.ValueKind == JsonValueKind.String && string.IsNullOrWhiteSpace(value.GetString()))) + { + continue; + } + + try + { + errorMessage = null; + return value.Deserialize(); + } + catch (Exception e) + { + errorMessage = $"Error while resolving custom fields. Invalid value for key '{key}'. Raw Data: {rule?.CustomFields}"; + new Logger().TryWriteWarning("CustomFieldResolver", $"Failed to deserialize key '{key}' for rule '{rule?.Uid}' to type {typeof(T).Name}: {e.Message}", true); + continue; + } + } + return default; + } + } +} diff --git a/roles/lib/files/FWO.Data/Device.cs b/roles/lib/files/FWO.Data/Device.cs new file mode 100644 index 0000000000..f628c3c9bc --- /dev/null +++ b/roles/lib/files/FWO.Data/Device.cs @@ -0,0 +1,152 @@ +using System.Collections.Generic; +using System.Text.Json.Serialization; +using FWO.Basics; +using Newtonsoft.Json; + +namespace FWO.Data +{ + public sealed class Device : IEqualityComparer + { + [JsonProperty("id"), JsonPropertyName("id")] + public int Id { get; set; } + + [JsonProperty("uid"), JsonPropertyName("uid")] + public string? Uid { get; set; } + + [JsonProperty("name"), JsonPropertyName("name")] + public string? Name { get; set; } + + [JsonProperty("deviceType"), JsonPropertyName("deviceType")] + public DeviceType DeviceType { get; set; } = new DeviceType(); + + [JsonProperty("management"), JsonPropertyName("management")] + public Management Management { get; set; } = new Management(); + + [JsonProperty("local_rulebase_name"), JsonPropertyName("local_rulebase_name")] + public string? LocalRulebase { get; set; } + + [JsonProperty("global_rulebase_name"), JsonPropertyName("global_rulebase_name")] + public string? GlobalRulebase { get; set; } + + [JsonProperty("global_rulebase_uid"), JsonPropertyName("global_rulebase_uid")] + public string? GlobalRulebaseUid { get; set; } + + [JsonProperty("package_name"), JsonPropertyName("package_name")] + public string? Package { get; set; } + + [JsonProperty("importDisabled"), JsonPropertyName("importDisabled")] + public bool ImportDisabled { get; set; } + + [JsonProperty("hideInUi"), JsonPropertyName("hideInUi")] + public bool HideInUi { get; set; } + + [JsonProperty("comment"), JsonPropertyName("comment")] + public string? Comment { get; set; } + + [JsonProperty("rulebase_links"), JsonPropertyName("rulebase_links")] + public RulebaseLink[] RulebaseLinks { get; set; } = []; + + public bool Selected { get; set; } = false; + public bool Relevant { get; set; } + public bool AwaitMgmt { get; set; } + public bool Delete { get; set; } + public long ActionId { get; set; } + + public Device() + { } + + public Device(Device device) + { + Id = device.Id; + Name = device.Name; + Uid = device.Uid; + DeviceType = new DeviceType(device.DeviceType); + Management = new Management(device.Management); + LocalRulebase = device.LocalRulebase; + GlobalRulebase = device.GlobalRulebase; + Package = device.Package; + ImportDisabled = device.ImportDisabled; + HideInUi = device.HideInUi; + Comment = device.Comment; + Relevant = device.Relevant; + AwaitMgmt = device.AwaitMgmt; + Delete = device.Delete; + ActionId = device.ActionId; + } + + /// + /// Compares this device against another device based on name and UID. + /// + /// The device to compare against. + /// True when name and UID are considered equal. + public bool Equals(Device? device) + { + if (device == null) + { + return false; + } + return Name.GenerousCompare(device.Name) && Uid.GenerousCompare(device.Uid); + } + + /// + /// Determines whether two devices are equal based on name and UID. + /// + /// The first device instance. + /// The second device instance. + /// True when both devices are considered equal. + public bool Equals(Device? first, Device? second) + { + if (ReferenceEquals(first, second)) + { + return true; + } + if (first is null || second is null) + { + return false; + } + return first.Name.GenerousCompare(second.Name) && first.Uid.GenerousCompare(second.Uid); + } + + /// + /// Returns a hash code for a device based on name and UID. + /// + /// The device to hash. + /// A hash code that aligns with the equality comparison. + public int GetHashCode(Device device) + { + if (device == null) + { + return 0; + } + + unchecked + { + int hash = 17; + hash = (hash * 31) + StringComparer.Ordinal.GetHashCode(NormalizeComparable(device.Name)); + hash = (hash * 31) + StringComparer.Ordinal.GetHashCode(NormalizeComparable(device.Uid)); + return hash; + } + } + + private static string NormalizeComparable(string? value) + { + return string.IsNullOrEmpty(value) ? string.Empty : value; + } + + /// + /// Sanitizes string properties and returns whether any values were shortened. + /// + /// True when any property required shortening. + public bool Sanitize() + { + bool shortened = false; + Name = Name.SanitizeOpt(ref shortened); + Uid = Uid.SanitizeOpt(ref shortened); + LocalRulebase = LocalRulebase.SanitizeOpt(ref shortened); + GlobalRulebase = GlobalRulebase.SanitizeOpt(ref shortened); + Package = Package.SanitizeOpt(ref shortened); + Comment = Comment.SanitizeCommentOpt(ref shortened); + return shortened; + } + } +} diff --git a/roles/lib/files/FWO.Api.Client/Data/DeviceType.cs b/roles/lib/files/FWO.Data/DeviceType.cs similarity index 77% rename from roles/lib/files/FWO.Api.Client/Data/DeviceType.cs rename to roles/lib/files/FWO.Data/DeviceType.cs index ad221bab74..0192a387ea 100644 --- a/roles/lib/files/FWO.Api.Client/Data/DeviceType.cs +++ b/roles/lib/files/FWO.Data/DeviceType.cs @@ -1,9 +1,7 @@ -using System.ComponentModel; -using System.Globalization; using System.Text.Json.Serialization; -using FWO.Api.Client; using Newtonsoft.Json; -namespace FWO.Api.Data + +namespace FWO.Data { public class DeviceType { @@ -25,23 +23,23 @@ public class DeviceType [JsonProperty("isManagement"), JsonPropertyName("isManagement")] public bool IsManagement { get; set; } - private static List LegacyDevTypeList = new List - { + private static readonly List LegacyDevTypeList = + [ 2, // Netscreen 5.x-6.x 4, // FortiGateStandalone 5ff 5, // Barracuda Firewall Control Center Vx 6, // phion netfence 3.x 7, // Check Point R5x-R7x 8 // JUNOS 10-21 - }; + ]; - private static Dictionary SupermanagerMap = new Dictionary + private static readonly Dictionary SupermanagerMap = new() { // Mgmt -> Supermgmt { 11, 12 }, // FortiADOM 5ff -> FortiManager 5ff { 9, 13 } // Check Point R8x -> Check Point MDS R8x }; - private static Dictionary SupermanagerGatewayMap = new Dictionary + private static readonly Dictionary SupermanagerGatewayMap = new() { // Supermgmt -> Gateway { 12, 10}, // FortiManager 5ff-> FortiGate 5ff @@ -50,20 +48,20 @@ public class DeviceType { 14, 16} // Cisco Firepower }; - private static List CheckPointManagers = new List - { + private static readonly List CheckPointManagers = + [ 13, 9 // Check Point MDS R8x and Check Point R8x - }; + ]; - private static List FortiManagers = new List - { + private static readonly List FortiManagers = + [ 12 // FortiManager 5ff - }; + ]; public DeviceType() - {} - + { } + public DeviceType(DeviceType deviceType) { Id = deviceType.Id; @@ -96,17 +94,22 @@ public bool IsDummyRouter() public bool CanHaveSupermanager() { - return SupermanagerMap.Keys.Contains(Id); + return SupermanagerMap.ContainsKey(Id); } public bool CanBeSupermanager() { - return SupermanagerMap.Values.Contains(Id); + return SupermanagerMap.ContainsValue(Id); } public bool CanBeAutodiscovered(Management mgmt) { - return SupermanagerMap.Values.Contains(Id) || (CheckPointManagers.Contains(Id) && mgmt.SuperManagerId==null); + return !IsUri(mgmt.Hostname) && (SupermanagerMap.ContainsValue(Id) || (CheckPointManagers.Contains(Id) && mgmt.SuperManagerId == null)); + } + + private static bool IsUri(string hostname) + { + return hostname.StartsWith("https://") || hostname.StartsWith("http://") || hostname.StartsWith("file://"); } public int GetSupermanagerId() diff --git a/roles/lib/files/FWO.Data/DeviceWrapper.cs b/roles/lib/files/FWO.Data/DeviceWrapper.cs new file mode 100644 index 0000000000..6fea7c146a --- /dev/null +++ b/roles/lib/files/FWO.Data/DeviceWrapper.cs @@ -0,0 +1,11 @@ +using System.Text.Json.Serialization; +using Newtonsoft.Json; + +namespace FWO.Data +{ + public class DeviceWrapper + { + [JsonProperty("device"), JsonPropertyName("device")] + public Device Content { get; set; } = new Device(); + } +} diff --git a/roles/lib/files/FWO.Data/Direction.cs b/roles/lib/files/FWO.Data/Direction.cs new file mode 100644 index 0000000000..2728e61496 --- /dev/null +++ b/roles/lib/files/FWO.Data/Direction.cs @@ -0,0 +1,8 @@ +namespace FWO.Data +{ + public enum Direction + { + Source, + Destination + } +} diff --git a/roles/lib/files/FWO.Data/DisplayBase.cs b/roles/lib/files/FWO.Data/DisplayBase.cs new file mode 100644 index 0000000000..efcad85201 --- /dev/null +++ b/roles/lib/files/FWO.Data/DisplayBase.cs @@ -0,0 +1,352 @@ +using System.Text; +using NetTools; +using FWO.Logging; +using System.Net; +using FWO.Basics; + +namespace FWO.Data +{ + public static class DisplayBase + { + public static StringBuilder DisplayGateway(Device gateway, bool isTechReport, string? gatewayName = null) + { + StringBuilder result = new(); + result.Append($" {gateway.Name}"); + return result; + } + public static StringBuilder DisplayService(NetworkService service, bool isTechReport, string? serviceName = null) + { + StringBuilder result = new(); + string ports = service.DestinationPortEnd == null || service.DestinationPortEnd == 0 || service.DestinationPort == service.DestinationPortEnd ? + $"{service.DestinationPort}" : $"{service.DestinationPort}-{service.DestinationPortEnd}"; + bool displayPorts = service.Protocol != null && service.Protocol.HasPorts() && service.DestinationPort != null; + if (isTechReport) + { + if (displayPorts) + { + result.Append($"{ports}/{service.Protocol?.Name}"); + } + else + { + result.Append(ShouldDisplayProtocolName(service) ? $"{service.Protocol?.Name}" : $"{service.Name}"); + } + } + else + { + result.Append($"{serviceName ?? service.Name}"); + if (displayPorts) + { + result.Append($" ({ports}/{service.Protocol?.Name})"); + } + else if (ShouldDisplayProtocolName(service)) + { + result.Append($" ({service.Protocol?.Name})"); + } + } + return result; + } + + public static string DisplayService(Workflow.NwServiceElement svcElem, List IpProtos) + { + IpProtocol? ipProt = IpProtos.FirstOrDefault(p => p.Id == svcElem.ProtoId); + NetworkService svc = new() + { + DestinationPort = svcElem.Port, + DestinationPortEnd = svcElem.PortEnd, + Protocol = ipProt != null ? new NetworkProtocol(ipProt) : new NetworkProtocol() + }; + return DisplayService(svc, true).ToString(); + } + + public static List CustomSortProtocols(List ListIn) + { + List ListOut = []; + IpProtocol? tcp = ListIn.Find(x => x.Name.ToLower() == "tcp"); + if (tcp != null) + { + ListOut.Add(tcp); + ListIn.Remove(tcp); + } + IpProtocol? udp = ListIn.Find(x => x.Name.ToLower() == "udp"); + if (udp != null) + { + ListOut.Add(udp); + ListIn.Remove(udp); + } + IpProtocol? icmp = ListIn.Find(x => x.Name.ToLower() == "icmp"); + if (icmp != null) + { + ListOut.Add(icmp); + ListIn.Remove(icmp); + } + foreach (var proto in ListIn.Where(p => p.Name.ToLower() != "unassigned").OrderBy(x => x.Name).ToList()) + { + ListOut.Add(proto); + } + return ListOut; + } + + public static string DisplayIpWithName(NetworkObject elem) + { + if (elem.Name != null && elem.Name != "") + { + return elem.Name + DisplayIp(elem.IP, elem.IpEnd, true); + } + return DisplayIp(elem.IP, elem.IpEnd); + } + + public static string DisplayIp(string ip1, string ip2, bool inBrackets = false) + { + try + { + if (string.IsNullOrEmpty(ip1) && !string.IsNullOrEmpty(ip2)) + { + ip1 = ip2; + } + if (ip2 == "") + { + ip2 = ip1; + } + string nwObjType = IpOperations.GetObjectType(ip1, ip2); + return DisplayIp(ip1, ip2, nwObjType, inBrackets); + } + catch (Exception exc) + { + Log.WriteError("Ip displaying", $"Exception thrown: {exc.Message}"); + return ""; + } + } + + public static string DisplayIp(string ip1, string ip2, string nwObjType, bool inBrackets = false) + { + string result = ""; + if (nwObjType != ObjectType.Group) + { + + if (string.IsNullOrEmpty(ip2)) + { + ip2 = ip1; + } + + if (string.IsNullOrEmpty(ip1)) + { + Log.WriteDebug("Ip displaying", $"Nessessary parameter {nameof(ip1)} is empty."); + } + else if (!ip1.IsV4Address() && !ip1.IsV6Address()) + { + Log.WriteError("Ip displaying", $"Found undefined IP family: {ip1} - {ip2}"); + } + else if (ip1.IsV4Address() == ip2.IsV6Address()) + { + Log.WriteError("Ip displaying", $"Found mixed IP family: {ip1} - {ip2}"); + } + else + { + string IpStart = ip1.StripOffUnnecessaryNetmask(); + string IpEnd = ip2.StripOffUnnecessaryNetmask(); + + try + { + result = inBrackets ? " (" : ""; + if (nwObjType == ObjectType.Network) + { + if (IpStart.GetNetmask() == "") + { + if (IpStart.IsGreater(IpEnd)) + { + // swap + Log.WriteWarning("Ip displaying", $"Wrong ip format {IpStart} - {IpEnd} - swapping values"); + string temp = IpStart; + IpStart = IpEnd; + IpEnd = temp; + } + IPAddressRange ipRange = new(IPAddress.Parse(IpStart), IPAddress.Parse(IpEnd)); + if (ipRange != null) + { + try + { + // tryint to convert range to network + string rangeString = ipRange.ToCidrString(); + result += rangeString; + } + catch (Exception exc) + { + Log.WriteWarning("Ip displaying", $"Wrong ip format {IpStart} - {IpEnd} is not a network\nMessage: {exc.Message}"); + // we display the incorrect ip data nevertheless without throwing errors + result += $"{IpStart}-{IpEnd}"; + } + } + } + else + { + result += IpStart; + } + } + else + { + result += IpStart; + if (nwObjType == ObjectType.IPRange) + { + result += $"-{IpEnd}"; + } + } + result += inBrackets ? ")" : ""; + } + catch (Exception exc) + { + Log.WriteWarning("Ip displaying", $"Wrong ip format {IpStart} - {IpEnd}\nMessage: {exc.Message}"); + // we display the incorrect ip data nevertheless without throwing errors + result += $"{IpStart}-{IpEnd}"; + result += inBrackets ? ")" : ""; + } + } + } + return result; + } + + public static string DisplayIpRange(string ip1, string ip2, bool inBrackets = false) + { + string result = ""; + string nwObjType = IpOperations.GetObjectType(ip1, ip2); + if (nwObjType != ObjectType.Group) + { + if (!ip1.IsV4Address() && !ip1.IsV6Address()) + { + Log.WriteError("Ip displaying", $"Found undefined IP family: {ip1} - {ip2}"); + } + else if (ip1.IsV4Address() == ip2.IsV6Address()) + { + Log.WriteError("Ip displaying", $"Found mixed IP family: {ip1} - {ip2}"); + } + else + { + if (ip2 == "") + { + ip2 = ip1; + } + string IpStart = ip1.StripOffUnnecessaryNetmask(); + string IpEnd = ip2.StripOffUnnecessaryNetmask(); + + try + { + result = inBrackets ? " (" : ""; + if (nwObjType == ObjectType.Network) + { + if (IpStart.GetNetmask() == "") + { + IPAddressRange ipRange = new(IPAddress.Parse(IpStart), IPAddress.Parse(IpEnd)); + if (ipRange != null) + { + result += $"{ipRange.Begin}-{ipRange.End}"; + } + } + else + { + result += IpStart; + } + } + else + { + result += IpStart; + if (nwObjType == ObjectType.IPRange) + { + result += $"-{IpEnd}"; + } + } + result += inBrackets ? ")" : ""; + } + catch (Exception exc) + { + Log.WriteError("Ip displaying", $"Wrong ip format {IpStart} - {IpEnd}\nMessage: {exc.Message}"); + } + } + } + return result; + } + + public static string DisplayPort(int? port, int? portEnd, bool inBrackets = false, string? proto = null) + { + string result = ""; + if (port != null) + { + result = inBrackets ? " (" : ""; + if (portEnd == null || portEnd == 0 || port == portEnd) + { + result += $"{port}"; + } + else + { + result += $"{port}-{portEnd}"; + } + result += proto != null ? $"/{proto}" : ""; + result += inBrackets ? ")" : ""; + } + return result; + } + + public static string MemberNamesAsJson(string MemberNames) + { + // Falls MemberNames leer ist, leeres Array zurückgeben + if (string.IsNullOrEmpty(MemberNames)) + return "[]"; + + // Splitten, trimmen + var members = MemberNames + .Split('|', StringSplitOptions.RemoveEmptyEntries) + .Select(m => m.Trim()) + .ToArray(); + + // Wenn nach Split nichts übrig bleibt, leeres Array + if (members.Length == 0) + return "[]"; + + // Jedes Element in Anführungszeichen setzen + var quoted = members.Select(m => $"\"{m}\""); + + // Mit Komma verbinden und in eckige Klammern setzen + return $"[{string.Join(",", quoted)}]"; + } + + public static string MemberNamesAsHtml(string MemberNames) + { + if (MemberNames != null && MemberNames.Contains("|")) + { + return $"{string.Join("
                      ", MemberNames.Split('|'))}"; + } + else + { + return $"{MemberNames}"; + } + } + public static string MemberNamesWithoutHtml(string MemberNames) + { + if (MemberNames != null && MemberNames.Contains("|")) + { + return $"{string.Join("
                      ", MemberNames.Split('|'))}"; + } + else + { + return $"{MemberNames}"; + } + } + + public static string MemberNamesAsCSV(string MemberNames) + { + if (MemberNames != null && MemberNames.Contains('|')) + { + return $"{string.Join(",", MemberNames.Split('|'))}"; + } + else + { + return $"{MemberNames}"; + } + } + + private static bool ShouldDisplayProtocolName(NetworkService service) + { + return service.Protocol?.Name != null && + !(service.Protocol.Id == 0 && + (service.Name.Equals("Any") || service.Name.Equals("ALL"))); + } + } +} diff --git a/roles/lib/files/FWO.Data/DistName.cs b/roles/lib/files/FWO.Data/DistName.cs new file mode 100644 index 0000000000..476f2dee7f --- /dev/null +++ b/roles/lib/files/FWO.Data/DistName.cs @@ -0,0 +1,211 @@ +using FWO.Basics; +using System.Text; + +namespace FWO.Data +{ + public class DistName + { + public string UserName { get; set; } + public string Role { get; set; } + public string Group { get; set; } + public List Root { get; set; } + public List Path { get; set; } + + public DistName(string? dn) + { + //Regex r = new Regex("(?:^|,\\s?)(?:(?[A-Z]+)=(?\"(?:[^\"]| \"\")+\"|(?:\\,|[^,])+))+"); + //GroupCollection groups = r.Match(dn ?? "").Groups; + //foreach (string group in r.GetGroupNames()) + //{ + // groups[group]; + //} + + UserName = ""; + Role = ""; + Group = ""; + Root = []; + Path = []; + bool lastValue = false; + if (dn != null) + { + while (lastValue == false) + { + int indexPrefixDelim = dn.IndexOf('='); + if (indexPrefixDelim > 0) + { + string name = dn[..indexPrefixDelim]; + (string value, string remainingDn) = ReadDnValue(dn[(indexPrefixDelim + 1)..]); + dn = remainingDn; + lastValue = dn.Length == 0; + + switch (name.ToLower()) + { + case "uid": + case "samaccountname": + case "userprincipalname": + case "mail": + UserName = value; + break; + case "cn": + if (UserName == "") + { + // the first one may be the user if not delivered as uid or a role or a group + UserName = value; + Role = value; + Group = value; + } + else + { + // following ones belong to the path + Path.Add(value); + } + break; + case "ou": + case "o": + case "l": + case "st": + case "street": + Path.Add(value); + break; + case "dc": + case "c": + Root.Add(value); + Path.Add(value); + break; + default: + break; + } + } + else + { + lastValue = true; + } + } + } + } + + private static (string value, string remainingDn) ReadDnValue(string dn) + { + StringBuilder value = new(); + int index = 0; + + while (index < dn.Length) + { + char currentChar = dn[index]; + + if (currentChar == ',') + { + return (value.ToString(), dn[(index + 1)..]); + } + + if (currentChar == '\\') + { + if (TryReadHexEscapedValue(dn, index, out string hexEscapedValue, out int nextIndex)) + { + value.Append(hexEscapedValue); + index = nextIndex; + continue; + } + + if (index + 1 < dn.Length) + { + value.Append(dn[index + 1]); + index += 2; + continue; + } + } + + value.Append(currentChar); + index++; + } + + return (value.ToString(), ""); + } + + /// + /// Normalizes a distinguished name for safe membership comparisons across equivalent escaped forms. + /// + /// Distinguished name to normalize. + /// Normalized distinguished name. + public static string NormalizeDnForComparison(string? dn) + { + if (string.IsNullOrWhiteSpace(dn)) + { + return ""; + } + + StringBuilder normalizedDn = new(); + int index = 0; + + while (index < dn.Length) + { + if (TryReadHexEscapedValue(dn, index, out string decodedValue, out int nextIndex)) + { + normalizedDn.Append(decodedValue); + index = nextIndex; + continue; + } + + if (dn[index] == '\\' && index + 1 < dn.Length) + { + normalizedDn.Append(dn[index + 1]); + index += 2; + continue; + } + + normalizedDn.Append(dn[index]); + index++; + } + + return normalizedDn.ToString().ToLowerInvariant(); + } + + private static bool TryReadHexEscapedValue(string dn, int currentIndex, out string decodedValue, out int nextIndex) + { + decodedValue = ""; + nextIndex = currentIndex; + if (currentIndex + 2 >= dn.Length || !IsHexPair(dn, currentIndex + 1)) + { + return false; + } + + List escapedBytes = []; + int scanIndex = currentIndex; + + do + { + escapedBytes.Add(Convert.ToByte(dn.Substring(scanIndex + 1, 2), 16)); + scanIndex += 3; + } + while (scanIndex + 2 < dn.Length && dn[scanIndex] == '\\' && IsHexPair(dn, scanIndex + 1)); + + decodedValue = Encoding.UTF8.GetString([.. escapedBytes]); + nextIndex = scanIndex; + return true; + } + + private static bool IsHexPair(string value, int startIndex) + { + return startIndex + 1 < value.Length + && IsHexCharacter(value[startIndex]) + && IsHexCharacter(value[startIndex + 1]); + } + + private static bool IsHexCharacter(char character) + { + return (character >= '0' && character <= '9') + || (character >= 'a' && character <= 'f') + || (character >= 'A' && character <= 'F'); + } + + public bool IsInternal() + { + return Root.Contains(GlobalConst.kFwoProdName) && Root.Contains("internal"); + } + + public string GetTenantNameViaLdapTenantLevel(int tenantLevel = 1) + { + return (tenantLevel > 0 && Path.Count >= tenantLevel) ? Path[^tenantLevel] : ""; + } + } +} diff --git a/roles/lib/files/FWO.Data/EmailRecipientOption.cs b/roles/lib/files/FWO.Data/EmailRecipientOption.cs new file mode 100644 index 0000000000..7fe8e57437 --- /dev/null +++ b/roles/lib/files/FWO.Data/EmailRecipientOption.cs @@ -0,0 +1,36 @@ +namespace FWO.Data +{ + public enum EmailRecipientOption + { + None = 0, + + CurrentHandler = 1, + RecentHandler = 2, + AssignedGroup = 3, + + OwnerMainResponsible = 10, + AllOwnerResponsibles = 11, + OwnerGroupOnly = 12, + FallbackToMainResponsibleIfOwnerGroupEmpty = 13, + + Requester = 20, + Approver = 21, + LastCommenter = 30, + // AllCommenters = 31 + + OtherAddresses = 40 + } + + public static class EmailRecipientGroups + { + public static List GetModellingOptions() + { + return [ EmailRecipientOption.None, + EmailRecipientOption.OwnerGroupOnly, + EmailRecipientOption.AllOwnerResponsibles, + EmailRecipientOption.OwnerMainResponsible, + EmailRecipientOption.FallbackToMainResponsibleIfOwnerGroupEmpty, + EmailRecipientOption.OtherAddresses ]; + } + } +} diff --git a/roles/lib/files/FWO.Data/ErrorBaseModel.cs b/roles/lib/files/FWO.Data/ErrorBaseModel.cs new file mode 100644 index 0000000000..6fbd69dbad --- /dev/null +++ b/roles/lib/files/FWO.Data/ErrorBaseModel.cs @@ -0,0 +1,20 @@ +namespace FWO.Data +{ + public class ErrorBaseModel() + { + /// + /// The error message containing infos abour what went wrong + /// + public string? Message { get; set; } + + /// + /// Additional info on errors at system level + /// + public Exception? InternalException { get; set; } + + /// + /// Identifier for severity typing + /// + public MessageType MessageType { get; set; } + } +} diff --git a/roles/lib/files/FWO.Data/ExtStates.cs b/roles/lib/files/FWO.Data/ExtStates.cs new file mode 100644 index 0000000000..6cf983a506 --- /dev/null +++ b/roles/lib/files/FWO.Data/ExtStates.cs @@ -0,0 +1,21 @@ +namespace FWO.Data +{ + public enum ExtStates + { + Done = 0, + Rejected = 1, + + // states used in ExternalRequestHandler, to be mapped in internal workflow states + ExtReqInitialized = 10, + ExtReqFailed = 20, + ExtReqRequested = 21, + ExtReqInProgress = 22, + ExtReqRejected = 23, + ExtReqDone = 24, + + // to be used in ExternalRequestHandler, not reflected in internal workflow states + ExtReqAckRejected = 30, + ExtReqAcknowledged = 31, + ExtReqDiscarded = 32 + } +} diff --git a/roles/lib/files/FWO.Data/Extensions/ComplianceExtensions.cs b/roles/lib/files/FWO.Data/Extensions/ComplianceExtensions.cs new file mode 100644 index 0000000000..516e188a47 --- /dev/null +++ b/roles/lib/files/FWO.Data/Extensions/ComplianceExtensions.cs @@ -0,0 +1,19 @@ +using FWO.Basics.Enums; + +namespace FWO.Data.Extensions +{ + public static partial class ComplianceExtensions + { + public static string ToAssessabilityIssueString(this AssessabilityIssue assessabilityIssue) + { + return assessabilityIssue switch + { + AssessabilityIssue.IPNull => "assess_ip_null", + AssessabilityIssue.AllIPs => "assess_all_ips", + AssessabilityIssue.HostAddress => "assess_host_address", + AssessabilityIssue.Broadcast => "assess_broadcast", + _ => throw new NotImplementedException() + }; + } + } +} diff --git a/roles/lib/files/FWO.Data/ExternalRequest.cs b/roles/lib/files/FWO.Data/ExternalRequest.cs new file mode 100644 index 0000000000..be43899ff0 --- /dev/null +++ b/roles/lib/files/FWO.Data/ExternalRequest.cs @@ -0,0 +1,71 @@ +using System.Text.Json.Serialization; +using Newtonsoft.Json; + + +namespace FWO.Data +{ + public struct ExternalVarKeys + { + public const string BundledTasks = "BundledTasks"; + } + + public class ExternalRequest + { + [JsonProperty("id"), JsonPropertyName("id")] + public long Id { get; set; } + + [JsonProperty("owner"), JsonPropertyName("owner")] + public FwoOwner Owner { get; set; } = new(); + + [JsonProperty("ticket_id"), JsonPropertyName("ticket_id")] + public long TicketId { get; set; } + + [JsonProperty("task_number"), JsonPropertyName("task_number")] + public int TaskNumber { get; set; } + + [JsonProperty("wait_cycles"), JsonPropertyName("wait_cycles")] + public int WaitCycles { get; set; } + + [JsonProperty("attempts"), JsonPropertyName("attempts")] + public int Attempts { get; set; } = 0; + + [JsonProperty("ext_ticket_system"), JsonPropertyName("ext_ticket_system")] + public string ExtTicketSystem { get; set; } = ""; + + [JsonProperty("ext_request_type"), JsonPropertyName("ext_request_type")] + public string ExtRequestType { get; set; } = ""; + + [JsonProperty("ext_request_content"), JsonPropertyName("ext_request_content")] + public string ExtRequestContent { get; set; } = ""; + + [JsonProperty("ext_query_variables"), JsonPropertyName("ext_query_variables")] + public string ExtQueryVariables { get; set; } = ""; + + [JsonProperty("ext_request_state"), JsonPropertyName("ext_request_state")] + public string ExtRequestState { get; set; } = ""; + + [JsonProperty("ext_ticket_id"), JsonPropertyName("ext_ticket_id")] + public string? ExtTicketId { get; set; } + + [JsonProperty("last_creation_response"), JsonPropertyName("last_creation_response")] + public string? LastCreationResponse { get; set; } + + [JsonProperty("last_processing_response"), JsonPropertyName("last_processing_response")] + public string? LastProcessingResponse { get; set; } + + [JsonProperty("create_date"), JsonPropertyName("create_date")] + public DateTime CreationDate { get; set; } + + [JsonProperty("locked"), JsonPropertyName("locked")] + public bool Locked { get; set; } = false; + + public string? LastMessage { get; set; } + } + + public class ExternalRequestDataHelper + { + [JsonProperty("returning"), JsonPropertyName("returning")] + public List ExternalRequests { get; set; } = []; + } + +} diff --git a/roles/lib/files/FWO.Data/ExternalTicketSystem.cs b/roles/lib/files/FWO.Data/ExternalTicketSystem.cs new file mode 100644 index 0000000000..6bad3d966a --- /dev/null +++ b/roles/lib/files/FWO.Data/ExternalTicketSystem.cs @@ -0,0 +1,147 @@ +using FWO.Basics; +using FWO.Data.Workflow; +using Newtonsoft.Json; +using System.Text.Json; +using System.Text.Json.Serialization; + +namespace FWO.Data +{ + public enum ExternalTicketSystemType + { + Generic, + TufinSecureChange, + AlgoSec, + ServiceNow + } + + public class ExternalTicketSystem + { + [JsonProperty(nameof(Id)), JsonPropertyName(nameof(Id))] + public int Id { get; set; } = 0; + + [JsonProperty(nameof(ExternalTicketSystemType)), JsonPropertyName(nameof(ExternalTicketSystemType))] + public ExternalTicketSystemType Type { get; set; } = ExternalTicketSystemType.Generic; + + [JsonProperty(nameof(Authorization)), JsonPropertyName(nameof(Authorization))] + public string Authorization { get; set; } = "Basic xyz"; // replace xyz with b64encode(username:password) + + [JsonProperty(nameof(Name)), JsonPropertyName(nameof(Name))] + public string Name { get; set; } = ""; + + [JsonProperty(nameof(Url)), JsonPropertyName(nameof(Url))] + public string Url { get; set; } = ""; + + [JsonProperty(nameof(LookupRequesterId)), JsonPropertyName(nameof(LookupRequesterId))] + public bool LookupRequesterId { get; set; } = false; + + [JsonProperty(nameof(Templates)), JsonPropertyName(nameof(Templates))] + public List Templates { get; set; } = []; + + // just for backward compatibility + [JsonProperty(nameof(TicketTemplate)), JsonPropertyName(nameof(TicketTemplate))] + public string TicketTemplate { get; set; } = ""; + + [JsonProperty(nameof(TasksTemplate)), JsonPropertyName(nameof(TasksTemplate))] + public string TasksTemplate { get; set; } = ""; + + [JsonProperty(nameof(ResponseTimeout)), JsonPropertyName(nameof(ResponseTimeout))] + public int ResponseTimeout { get; set; } = 300; + + [JsonProperty(nameof(MaxAttempts)), JsonPropertyName(nameof(MaxAttempts))] + public int MaxAttempts { get; set; } = 3; + + [JsonProperty(nameof(CyclesBetweenAttempts)), JsonPropertyName(nameof(CyclesBetweenAttempts))] + public int CyclesBetweenAttempts { get; set; } = 5; + + public int MaxBundledTasks() + { + return Type switch + { + ExternalTicketSystemType.TufinSecureChange => SCConstants.SCMaxBundledTasks, + _ => 1 + }; + } + + public bool BundleGateways() + { + return Type switch + { + ExternalTicketSystemType.TufinSecureChange => SCConstants.SCBundleGateways, + _ => false + }; + } + + public List TaskTypesToBundleGateways() + { + return Type switch + { + ExternalTicketSystemType.TufinSecureChange => [WfTaskType.rule_modify.ToString(), WfTaskType.rule_delete.ToString()], + _ => [] + }; + } + + public bool Sanitize() + { + bool shortened = false; + Name = Name.SanitizeMand(ref shortened); + Url = Url.SanitizeMand(ref shortened); + TicketTemplate = TicketTemplate.SanitizeJsonMand(ref shortened); + TasksTemplate = TasksTemplate.SanitizeJsonMand(ref shortened); + foreach (var template in Templates) + { + shortened = template.Sanitize(); + } + return shortened; + } + } + + public class ExternalTicketTemplate + { + [JsonProperty(nameof(TaskType)), JsonPropertyName(nameof(TaskType))] + public string TaskType { get; set; } = ""; + + [JsonProperty(nameof(TicketTemplate)), JsonPropertyName(nameof(TicketTemplate))] + public string TicketTemplate { get; set; } = ""; + + [JsonProperty(nameof(TasksTemplate)), JsonPropertyName(nameof(TasksTemplate))] + public string TasksTemplate { get; set; } = ""; + + [JsonProperty(nameof(ObjectTemplate)), JsonPropertyName(nameof(ObjectTemplate))] + public string ObjectTemplate { get; set; } = ""; + + [JsonProperty(nameof(ObjectTemplateShort)), JsonPropertyName(nameof(ObjectTemplateShort))] + public string ObjectTemplateShort { get; set; } = ""; + + [JsonProperty(nameof(IpTemplate)), JsonPropertyName(nameof(IpTemplate))] + public string IpTemplate { get; set; } = ""; + + [JsonProperty(nameof(NwObjGroupTemplate)), JsonPropertyName(nameof(NwObjGroupTemplate))] + public string NwObjGroupTemplate { get; set; } = ""; + + [JsonProperty(nameof(ServiceTemplate)), JsonPropertyName(nameof(ServiceTemplate))] + public string ServiceTemplate { get; set; } = ""; + + [JsonProperty(nameof(IcmpTemplate)), JsonPropertyName(nameof(IcmpTemplate))] + public string IcmpTemplate { get; set; } = ""; + + [JsonProperty(nameof(IpProtocolTemplate)), JsonPropertyName(nameof(IpProtocolTemplate))] + public string IpProtocolTemplate { get; set; } = ""; + + + public bool Sanitize() + { + bool shortened = false; + TaskType = TaskType.SanitizeMand(ref shortened); + TicketTemplate = TicketTemplate.SanitizeJsonMand(ref shortened); + TasksTemplate = TasksTemplate.SanitizeJsonMand(ref shortened); + ObjectTemplate = ObjectTemplate.SanitizeJsonMand(ref shortened); + ObjectTemplateShort = ObjectTemplateShort.SanitizeJsonMand(ref shortened); + IpTemplate = IpTemplate.SanitizeJsonMand(ref shortened); + NwObjGroupTemplate = NwObjGroupTemplate.SanitizeJsonMand(ref shortened); + ServiceTemplate = ServiceTemplate.SanitizeJsonMand(ref shortened); + IcmpTemplate = IcmpTemplate.SanitizeJsonMand(ref shortened); + IpProtocolTemplate = IpProtocolTemplate.SanitizeJsonMand(ref shortened); + return shortened; + } + } +} diff --git a/roles/lib/files/FWO.Data/FWO.Data.csproj b/roles/lib/files/FWO.Data/FWO.Data.csproj new file mode 100644 index 0000000000..4ad3fb36c2 --- /dev/null +++ b/roles/lib/files/FWO.Data/FWO.Data.csproj @@ -0,0 +1,24 @@ + + + + net10.0 + enable + enable + + + + + + + + + + + + + + + + + + diff --git a/roles/lib/files/FWO.Data/FwoNotification.cs b/roles/lib/files/FWO.Data/FwoNotification.cs new file mode 100644 index 0000000000..2aade5292c --- /dev/null +++ b/roles/lib/files/FWO.Data/FwoNotification.cs @@ -0,0 +1,143 @@ +using System.Text.Json.Serialization; +using Newtonsoft.Json; + +namespace FWO.Data +{ + public enum NotificationClient + { + None = 0, + Recertification = 1, + ImportChange = 2, + Compliance = 3, + InterfaceRequest = 4, + RuleTimer = 5, + AppDecomm = 6, + Report = 7 + } + + public enum NotificationChannel + { + Email = 1 + } + + public enum NotificationDeadline + { + None = 0, + RecertDate = 1, + RequestDate = 2, + RuleExpiry = 3, + DecommissionDate = 4 + } + + public enum BundleType + { + Attachments = 1 + } + + public static class NotificationDeadlineGroups + { + /// + /// Returns whether the deadline source is only meaningful as a past event and therefore + /// cannot support a "before deadline" notification configuration. + /// + /// Deadline type to classify. + /// True for deadlines that are always treated as past events. + public static bool IsAlwaysInPast(this NotificationDeadline notificationDeadline) + { + return notificationDeadline switch + { + NotificationDeadline.RequestDate or + NotificationDeadline.DecommissionDate => true, + _ => false + }; + } + } + + public class FwoNotification + { + [JsonProperty("id"), JsonPropertyName("id")] + public int Id { get; set; } + + [JsonProperty("notification_client"), JsonPropertyName("notification_client")] + public NotificationClient NotificationClient { get; set; } = NotificationClient.None; + + [JsonProperty("user_id"), JsonPropertyName("user_id")] + public int? UserId { get; set; } + + [JsonProperty("owner_id"), JsonPropertyName("owner_id")] + public int? OwnerId { get; set; } + + [JsonProperty("channel"), JsonPropertyName("channel")] + public NotificationChannel Channel { get; set; } = NotificationChannel.Email; + + [JsonProperty("name"), JsonPropertyName("name")] + public string Name { get; set; } = ""; + + [JsonProperty("recipient_to"), JsonPropertyName("recipient_to")] + public EmailRecipientOption RecipientTo { get; set; } = EmailRecipientOption.None; + + [JsonProperty("email_address_to"), JsonPropertyName("email_address_to")] + public string EmailAddressTo { get; set; } = ""; + + [JsonProperty("recipient_cc"), JsonPropertyName("recipient_cc")] + public EmailRecipientOption RecipientCc { get; set; } = EmailRecipientOption.None; + + [JsonProperty("email_address_cc"), JsonPropertyName("email_address_cc")] + public string EmailAddressCc { get; set; } = ""; + + [JsonProperty("email_subject"), JsonPropertyName("email_subject")] + public string EmailSubject { get; set; } = ""; + + [JsonProperty("email_body"), JsonPropertyName("email_body")] + public string EmailBody { get; set; } = ""; + + [JsonProperty("schedule_id"), JsonPropertyName("schedule_id")] + public int? ScheduleId { get; set; } + + [JsonProperty("bundle_type"), JsonPropertyName("bundle_type")] + public BundleType? BundleType { get; set; } + + [JsonProperty("bundle_id"), JsonPropertyName("bundle_id")] + public string? BundleId { get; set; } + + [JsonProperty("layout"), JsonPropertyName("layout")] + public NotificationLayout Layout { get; set; } = NotificationLayout.SimpleText; + + [JsonProperty("deadline"), JsonPropertyName("deadline")] + public NotificationDeadline Deadline { get; set; } = NotificationDeadline.None; + + [JsonProperty("interval_before_deadline"), JsonPropertyName("interval_before_deadline")] + public SchedulerInterval? IntervalBeforeDeadline { get; set; } + + [JsonProperty("offset_before_deadline"), JsonPropertyName("offset_before_deadline")] + public int? OffsetBeforeDeadline { get; set; } + + [JsonProperty("repeat_interval_after_deadline"), JsonPropertyName("repeat_interval_after_deadline")] + public SchedulerInterval? RepeatIntervalAfterDeadline { get; set; } + + [JsonProperty("initial_offset_after_deadline"), JsonPropertyName("initial_offset_after_deadline")] + public int? InitialOffsetAfterDeadline { get; set; } + + [JsonProperty("repeat_offset_after_deadline"), JsonPropertyName("repeat_offset_after_deadline")] + public int? RepeatOffsetAfterDeadline { get; set; } + + [JsonProperty("repetitions_after_deadline"), JsonPropertyName("repetitions_after_deadline")] + public int? RepetitionsAfterDeadline { get; set; } + + [JsonProperty("last_sent"), JsonPropertyName("last_sent")] + public DateTime? LastSent { get; set; } + + + public static List OfferedDeadlineOptions(NotificationClient client) + { + return client switch + { + NotificationClient.Recertification => [NotificationDeadline.RecertDate], + NotificationClient.RuleTimer => [NotificationDeadline.RuleExpiry], + NotificationClient.InterfaceRequest => [NotificationDeadline.RequestDate], + NotificationClient.AppDecomm => [NotificationDeadline.None, NotificationDeadline.DecommissionDate], + _ => Enum.GetValues(typeof(NotificationDeadline)).Cast().ToList() + }; + } + } +} diff --git a/roles/lib/files/FWO.Data/FwoOwner.cs b/roles/lib/files/FWO.Data/FwoOwner.cs new file mode 100644 index 0000000000..a961f25ede --- /dev/null +++ b/roles/lib/files/FWO.Data/FwoOwner.cs @@ -0,0 +1,131 @@ +using FWO.Basics; +using Newtonsoft.Json; +using System.Text.Json.Serialization; + +namespace FWO.Data +{ + public class FwoOwner : FwoOwnerBase + { + [JsonProperty("id"), JsonPropertyName("id")] + public int Id { get; set; } + + [JsonProperty("last_recert_check"), JsonPropertyName("last_recert_check")] + public DateTime? LastRecertCheck { get; set; } + + [JsonProperty("recert_check_params"), JsonPropertyName("recert_check_params")] + public string? RecertCheckParamString { get; set; } + + [JsonProperty("additional_info"), JsonPropertyName("additional_info")] + public Dictionary? AdditionalInfo { get; set; } + + [JsonProperty("criticality"), JsonPropertyName("criticality")] + public string? Criticality { get; set; } + + [JsonProperty("owner_lifecycle_state_id"), JsonPropertyName("owner_lifecycle_state_id")] + public int? OwnerLifeCycleStateId { get; set; } + + [JsonProperty("active"), JsonPropertyName("active")] + public bool Active { get; set; } = true; + + [JsonProperty("import_source"), JsonPropertyName("import_source")] + public string? ImportSource { get; set; } + + [JsonProperty("owner_networks"), JsonPropertyName("owner_networks")] + public OwnerNetwork[] OwnerNetworks { get; set; } = []; + + [JsonProperty("common_service_possible"), JsonPropertyName("common_service_possible")] + public bool CommSvcPossible { get; set; } = false; + + [JsonProperty("connections_aggregate"), JsonPropertyName("connections_aggregate")] + public AggregateCount ConnectionCount { get; set; } = new(); + + [JsonProperty("last_recertified"), JsonPropertyName("last_recertified")] + public DateTime? LastRecertified { get; set; } + + [JsonProperty("last_recertifier"), JsonPropertyName("last_recertifier")] + public int? LastRecertifierId { get; set; } + + [JsonProperty("last_recertifier_dn"), JsonPropertyName("last_recertifier_dn")] + public string? LastRecertifierDn { get; set; } + + [JsonProperty("next_recert_date"), JsonPropertyName("next_recert_date")] + public DateTime? NextRecertDate { get; set; } + + [JsonProperty("decomm_date"), JsonPropertyName("decomm_date")] + public DateTime? DecommDate { get; set; } + + [JsonProperty("recert_active"), JsonPropertyName("recert_active")] + public bool RecertActive { get; set; } = false; + + public bool RecertOverdue { get; set; } = false; + public bool RecertUpcoming { get; set; } = false; + public long? LastRecertId { get; set; } + + public FwoOwner() + { } + + public FwoOwner(FwoOwner owner) : base(owner) + { + Id = owner.Id; + LastRecertCheck = owner.LastRecertCheck; + RecertCheckParamString = owner.RecertCheckParamString; + AdditionalInfo = owner.AdditionalInfo == null ? null : new Dictionary(owner.AdditionalInfo); + Criticality = owner.Criticality; + Active = owner.Active; + ImportSource = owner.ImportSource; + CommSvcPossible = owner.CommSvcPossible; + ConnectionCount = owner.ConnectionCount; + LastRecertified = owner.LastRecertified; + LastRecertifierId = owner.LastRecertifierId; + LastRecertifierDn = owner.LastRecertifierDn; + NextRecertDate = owner.NextRecertDate; + DecommDate = owner.DecommDate; + RecertOverdue = owner.RecertOverdue; + RecertUpcoming = owner.RecertUpcoming; + LastRecertId = owner.LastRecertId; + } + + public string Display(string comSvcTxt) + { + string comSvcAppendix = CommSvcPossible && comSvcTxt != "" ? $", {comSvcTxt}" : ""; + string appIdPart = !string.IsNullOrEmpty(ExtAppId) ? $" ({ExtAppId}{comSvcAppendix})" : ""; + + return $"{Name}{appIdPart}"; + } + + public string DisplayWithoutAppId(string comSvcTxt) + { + if (CommSvcPossible) + { + return $"{Name} ({comSvcTxt})"; + } + + return $"{Name}"; + } + + public override bool Sanitize() + { + bool shortened = base.Sanitize(); + Criticality = Criticality.SanitizeOpt(ref shortened); + ImportSource = ImportSource.SanitizeCommentOpt(ref shortened); + LastRecertifierDn = LastRecertifierDn.SanitizeLdapPathOpt(ref shortened); + return shortened; + } + + public int CompareTo(FwoOwner secondOwner) + { + if (Id <= 0 || secondOwner.Id <= 0) + { + return Id.CompareTo(secondOwner.Id); + } + return Name?.CompareTo(secondOwner.Name) ?? -1; + } + } + + public class FwoOwnerDataHelper + { + [JsonProperty("owner"), JsonPropertyName("owner")] + public FwoOwner Owner { get; set; } = new FwoOwner(); + } + +} diff --git a/roles/lib/files/FWO.Data/FwoOwnerBase.cs b/roles/lib/files/FWO.Data/FwoOwnerBase.cs new file mode 100644 index 0000000000..0f89f1e916 --- /dev/null +++ b/roles/lib/files/FWO.Data/FwoOwnerBase.cs @@ -0,0 +1,154 @@ +using FWO.Basics; +using Newtonsoft.Json; +using System; +using System.Text.Json.Serialization; +using System.Linq; + +namespace FWO.Data +{ + public enum RuleOwnershipMode + { + mixed, + exclusive + } + + public class FwoOwnerBase + { + [JsonProperty("name"), JsonPropertyName("name")] + public string Name { get; set; } = ""; + + [JsonProperty("owner_responsibles"), JsonPropertyName("owner_responsibles")] + public List OwnerResponsibles { get; set; } = []; + + [JsonProperty("is_default"), JsonPropertyName("is_default")] + public bool IsDefault { get; set; } = false; + + [JsonProperty("tenant_id"), JsonPropertyName("tenant_id")] + public int? TenantId { get; set; } + + [JsonProperty("recert_interval"), JsonPropertyName("recert_interval")] + public int? RecertInterval { get; set; } + + [JsonProperty("app_id_external"), JsonPropertyName("app_id_external")] + public string? ExtAppId { get; set; } + + public FwoOwnerBase() + { } + + public FwoOwnerBase(FwoOwnerBase owner) + { + Name = owner.Name; + OwnerResponsibles = owner.OwnerResponsibles.Select(responsible => new OwnerResponsible(responsible)).ToList(); + IsDefault = owner.IsDefault; + TenantId = owner.TenantId; + RecertInterval = owner.RecertInterval; + ExtAppId = owner.ExtAppId; + } + + public virtual string Display() + { + return Name + (!string.IsNullOrEmpty(ExtAppId) ? " (" + ExtAppId + ")" : ""); + } + + public virtual bool Sanitize() + { + bool shortened = false; + Name = Name.SanitizeMand(ref shortened); + OwnerResponsibles = SanitizeResponsibles(OwnerResponsibles ?? [], ref shortened); + ExtAppId = ExtAppId.SanitizeCommentOpt(ref shortened); + return shortened; + } + + public List GetAllOwnerResponsibles() + { + HashSet responsibles = new(StringComparer.OrdinalIgnoreCase); + foreach (OwnerResponsible responsible in OwnerResponsibles ?? []) + AddResponsible(responsibles, responsible.Dn); + return responsibles.ToList(); + } + + public List GetOwnerResponsiblesByType(int responsibleType) + { + return (OwnerResponsibles ?? []) + .Where(responsible => responsible.ResponsibleTypeId == responsibleType) + .Select(responsible => responsible.Dn) + .Where(dn => !string.IsNullOrWhiteSpace(dn)) + .Distinct(StringComparer.OrdinalIgnoreCase) + .ToList(); + } + + public void SetOwnerResponsiblesByType(int responsibleType, IEnumerable dns) + { + OwnerResponsibles ??= []; + OwnerResponsibles.RemoveAll(responsible => responsible.ResponsibleTypeId == responsibleType); + foreach (string dn in dns.Where(dn => !string.IsNullOrWhiteSpace(dn))) + { + OwnerResponsibles.Add(new OwnerResponsible { Dn = dn, ResponsibleTypeId = responsibleType }); + } + } + + public void AddOwnerResponsible(int responsibleType, string dn) + { + if (string.IsNullOrWhiteSpace(dn)) + { + return; + } + OwnerResponsibles ??= []; + if (!OwnerResponsibles.Any(r => r.ResponsibleTypeId == responsibleType && r.Dn.Equals(dn, StringComparison.OrdinalIgnoreCase))) + { + OwnerResponsibles.Add(new OwnerResponsible { Dn = dn, ResponsibleTypeId = responsibleType }); + } + } + + public void RemoveOwnerResponsible(int responsibleType, string dn) + { + if (string.IsNullOrWhiteSpace(dn)) + { + return; + } + OwnerResponsibles?.RemoveAll(responsible => + responsible.ResponsibleTypeId == responsibleType && responsible.Dn.Equals(dn, StringComparison.OrdinalIgnoreCase)); + } + + private static void AddResponsible(HashSet responsibles, string? dn) + { + if (!string.IsNullOrWhiteSpace(dn)) + responsibles.Add(dn); + } + + private static List SanitizeResponsibles(List responsibles, ref bool shortened) + { + List sanitized = []; + foreach (OwnerResponsible responsible in responsibles) + { + if (!string.IsNullOrWhiteSpace(responsible.Dn)) + { + sanitized.Add(new OwnerResponsible + { + Dn = responsible.Dn.SanitizeLdapPathMand(ref shortened), + ResponsibleTypeId = responsible.ResponsibleTypeId + }); + } + } + return sanitized; + } + } + + public class OwnerResponsible + { + [JsonProperty("dn"), JsonPropertyName("dn")] + public string Dn { get; set; } = ""; + + [JsonProperty("responsible_type"), JsonPropertyName("responsible_type")] + public int ResponsibleTypeId { get; set; } + + public OwnerResponsible() + { } + + public OwnerResponsible(OwnerResponsible responsible) + { + Dn = responsible.Dn; + ResponsibleTypeId = responsible.ResponsibleTypeId; + } + } +} diff --git a/roles/lib/files/FWO.Api.Client/Data/Group.cs b/roles/lib/files/FWO.Data/Group.cs similarity index 79% rename from roles/lib/files/FWO.Api.Client/Data/Group.cs rename to roles/lib/files/FWO.Data/Group.cs index a523cb3588..71d6347da3 100644 --- a/roles/lib/files/FWO.Api.Client/Data/Group.cs +++ b/roles/lib/files/FWO.Data/Group.cs @@ -1,7 +1,7 @@ -using System.Text.Json.Serialization; +using System.Text.Json.Serialization; using Newtonsoft.Json; -namespace FWO.Api.Data +namespace FWO.Data { public class Group { diff --git a/roles/lib/files/FWO.Api.Client/Data/GroupFlat.cs b/roles/lib/files/FWO.Data/GroupFlat.cs similarity index 80% rename from roles/lib/files/FWO.Api.Client/Data/GroupFlat.cs rename to roles/lib/files/FWO.Data/GroupFlat.cs index 2d4b823611..9f09b75444 100644 --- a/roles/lib/files/FWO.Api.Client/Data/GroupFlat.cs +++ b/roles/lib/files/FWO.Data/GroupFlat.cs @@ -1,7 +1,7 @@ -using System.Text.Json.Serialization; +using System.Text.Json.Serialization; using Newtonsoft.Json; -namespace FWO.Api.Data +namespace FWO.Data { public class GroupFlat { diff --git a/roles/lib/files/FWO.Data/Import.cs b/roles/lib/files/FWO.Data/Import.cs new file mode 100644 index 0000000000..73a39d0a78 --- /dev/null +++ b/roles/lib/files/FWO.Data/Import.cs @@ -0,0 +1,24 @@ +using System.Text.Json.Serialization; +using Newtonsoft.Json; + +namespace FWO.Data +{ + public class Import + { + [JsonProperty("aggregate"), JsonPropertyName("aggregate")] + public ImportAggregate ImportAggregate { get; set; } = new ImportAggregate(); + } + + public class ImportAggregate + { + [JsonProperty("max"), JsonPropertyName("max")] + public ImportAggregateMax ImportAggregateMax { get; set; } = new ImportAggregateMax(); + } + + public class ImportAggregateMax + { + [JsonProperty("id"), JsonPropertyName("id")] + public long? RelevantImportId { get; set; } + } + +} diff --git a/roles/lib/files/FWO.Data/ImportCredential.cs b/roles/lib/files/FWO.Data/ImportCredential.cs new file mode 100644 index 0000000000..ff68a497b7 --- /dev/null +++ b/roles/lib/files/FWO.Data/ImportCredential.cs @@ -0,0 +1,64 @@ +using FWO.Basics; +using Newtonsoft.Json; +using System.Text.Json.Serialization; + +namespace FWO.Data +{ + public class ImportCredential + { + [JsonProperty("id"), JsonPropertyName("id")] + public int Id { get; set; } + + [JsonProperty("credential_name"), JsonPropertyName("credential_name")] + public string Name { get; set; } = ""; + + [JsonProperty("is_key_pair"), JsonPropertyName("is_key_pair")] + public Boolean IsKeyPair { get; set; } = false; + + [JsonProperty("user"), JsonPropertyName("user")] + public string? ImportUser { get; set; } + + [JsonProperty("secret"), JsonPropertyName("secret")] + public string Secret { get; set; } = ""; + + [JsonProperty("sshPublicKey"), JsonPropertyName("sshPublicKey")] + public string? PublicKey { get; set; } + + [JsonProperty("cloud_client_id"), JsonPropertyName("cloud_client_id")] + public string? CloudClientId { get; set; } + + [JsonProperty("cloud_client_secret"), JsonPropertyName("cloud_client_secret")] + public string? CloudClientSecret { get; set; } + + public ImportCredential() + { } + + public ImportCredential(ImportCredential cred) + { + Id = cred.Id; + Name = cred.Name; + IsKeyPair = cred.IsKeyPair; + ImportUser = cred.ImportUser; + Secret = cred.Secret; + PublicKey = cred.PublicKey; + CloudClientId = cred.CloudClientId; + CloudClientSecret = cred.CloudClientSecret; + } + public ImportCredential(string username, string password) + { + ImportUser = username; + Secret = password; + } + public bool Sanitize() + { + bool shortened = false; + Name = Name.SanitizeMand(ref shortened); + ImportUser = ImportUser.SanitizeOpt(ref shortened); + PublicKey = PublicKey.SanitizeKeyOpt(ref shortened); + Secret = Secret.SanitizeKeyMand(ref shortened); + CloudClientId = CloudClientId.SanitizeOpt(ref shortened); + CloudClientSecret = CloudClientSecret.SanitizeKeyOpt(ref shortened); + return shortened; + } + } +} diff --git a/roles/lib/files/FWO.Api.Client/Data/ImportStatus.cs b/roles/lib/files/FWO.Data/ImportStatus.cs similarity index 78% rename from roles/lib/files/FWO.Api.Client/Data/ImportStatus.cs rename to roles/lib/files/FWO.Data/ImportStatus.cs index 2f713b2ce1..1545610220 100644 --- a/roles/lib/files/FWO.Api.Client/Data/ImportStatus.cs +++ b/roles/lib/files/FWO.Data/ImportStatus.cs @@ -1,8 +1,7 @@ -using System; -using System.Text.Json.Serialization; +using System.Text.Json.Serialization; using Newtonsoft.Json; -namespace FWO.Api.Data +namespace FWO.Data { public class ImportControl { @@ -20,6 +19,15 @@ public class ImportControl [JsonProperty("import_errors"), JsonPropertyName("import_errors")] public string? ImportErrors { get; set; } + + [JsonProperty("import_type_id"), JsonPropertyName("import_type_id")] + public int? ImportTypeId { get; set; } + + [JsonProperty("rule_owner_mapping_done"), JsonPropertyName("rule_owner_mapping_done")] + public bool RuleOwnerMappingDone { get; set; } + + [JsonProperty("changes_found"), JsonPropertyName("changes_found")] + public bool ChangesFound { get; set; } } public class ImportStatus @@ -29,7 +37,7 @@ public class ImportStatus [JsonProperty("mgm_name"), JsonPropertyName("mgm_name")] public string MgmName { get; set; } = ""; - + [JsonProperty("importDisabled"), JsonPropertyName("importDisabled")] public bool ImportDisabled { get; set; } @@ -55,10 +63,16 @@ public class ImportStatus [JsonProperty("first_import"), JsonPropertyName("first_import")] public ImportControl[]? FirstImport { get; set; } - + [JsonProperty("erroneous_imports"), JsonPropertyName("erroneous_imports")] public ImportControl[]? ErroneousImports { get; set; } public int ErrorCount = 0; } + + public class InsertImportControl + { + [JsonProperty("returning"), JsonPropertyName("returning")] + public List Returning { get; set; } = new(); + } } diff --git a/roles/lib/files/FWO.Data/IpProtocol.cs b/roles/lib/files/FWO.Data/IpProtocol.cs new file mode 100644 index 0000000000..b9f4d1eb7d --- /dev/null +++ b/roles/lib/files/FWO.Data/IpProtocol.cs @@ -0,0 +1,19 @@ +using System.Text.Json.Serialization; +using Newtonsoft.Json; + +namespace FWO.Data +{ + public class IpProtocol + { + [JsonProperty("ip_proto_id"), JsonPropertyName("ip_proto_id")] + public int Id { get; set; } + + [JsonProperty("ip_proto_name"), JsonPropertyName("ip_proto_name")] + public string Name { get; set; } = ""; + + public bool HasPorts() + { + return Id == 6 || Id == 17; + } + } +} diff --git a/roles/lib/files/FWO.Data/JsonCustomConverters.cs b/roles/lib/files/FWO.Data/JsonCustomConverters.cs new file mode 100644 index 0000000000..6acb7c5398 --- /dev/null +++ b/roles/lib/files/FWO.Data/JsonCustomConverters.cs @@ -0,0 +1,131 @@ + +using NetTools; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; +using System.Net; + +namespace FWO.Data +{ + public class WrapperConverter : JsonConverter + { + private readonly string wrappedObjectName = ""; + + public WrapperConverter(string wrappedObjectName) + { + this.wrappedObjectName = wrappedObjectName; + } + + public override bool CanConvert(Type objectType) => typeof(ValueType).IsAssignableFrom(objectType); + + public override object? ReadJson(JsonReader reader, Type objectType, object? existingValue, JsonSerializer serializer) + { + // Load the JSON as a JObject + JObject jsonObject = JObject.Load(reader); + + // Check if the "wrappedObjectName" property exists + if (jsonObject.TryGetValue(wrappedObjectName, out JToken? wrappedObjectToken)) + { + // Deserialize the wrapped object + return wrappedObjectToken.ToObject(serializer); + } + + // Deserialize the wrapper object otherwise + return jsonObject.ToObject(serializer); + } + + public override void WriteJson(JsonWriter writer, object? value, JsonSerializer serializer) + { + // Wrap the object with a property named "wrappedObjectName" + JObject jsonObject = new JObject + { + { wrappedObjectName, value == null ? null : JToken.FromObject(value, serializer) } + }; + + // Write the JSON + jsonObject.WriteTo(writer); + } + } + + public class IpAddressRangeJsonTypeConverter : JsonConverter + { + public override IPAddressRange ReadJson(JsonReader reader, Type objectType, IPAddressRange? existingValue, bool hasExistingValue, JsonSerializer serializer) + { + // Load the JSON as a JObject + JObject jsonObject = JObject.Load(reader); + // Deserialize the IP address range based on the properties ip_range_start and ip_range_end + IPAddress start = IPAddress.Parse((jsonObject.GetValue("ip_range_start")?.ToObject() ?? throw new ArgumentNullException("ip_range_start")).Replace("/32", "")); + IPAddress end = IPAddress.Parse((jsonObject.GetValue("ip_range_end")?.ToObject() ?? throw new ArgumentNullException("ip_range_start")).Replace("/32", "")); + return new IPAddressRange(start, end); + } + + public override void WriteJson(JsonWriter writer, IPAddressRange? value, JsonSerializer serializer) + { + if (value != null) + { + // Create a JSON JObject + JObject result = new JObject + { + { "ip_range_start", value.Begin.ToString() }, + { "ip_range_end", value.Begin.ToString() } + }; + + result.WriteTo(writer); + } + } + } + + public class ComplianceViolationConverter : JsonConverter + { + public override ComplianceViolation? ReadJson(JsonReader reader, Type objectType, ComplianceViolation? existingValue, bool hasExistingValue, JsonSerializer serializer) + { + ComplianceViolation? violation = null; + + if (reader.TokenType != JsonToken.Null) + { + // Try deserialize base. + + JObject jsonObject = JObject.Load(reader); + ComplianceViolationBase? violationBase = jsonObject.ToObject(serializer); + + if (violationBase != null) + { + // Get id from json object. + + int id = jsonObject.GetValue("id")?.ToObject() ?? 0; + + // Create instance from base and set id. + + violation = new(id, violationBase); + + // Parse Violation Type via criterion. + + violation.Type = violation.ParseViolationType(violation.Criterion); + } + } + + return violation; + } + + public override void WriteJson(JsonWriter writer, ComplianceViolation? value, JsonSerializer serializer) + { + if (value == null) + { + writer.WriteNull(); + return; + } + + if (value.Criterion != null) + { + value.Criterion.CriterionType = value.Type switch + { + ComplianceViolationType.MatrixViolation => "Matrix", + ComplianceViolationType.NotAssessable => "Assessability", + ComplianceViolationType.ServiceViolation => "ForbiddenService", + _ => value.Criterion.CriterionType + }; + } + + serializer.Serialize(writer, value); + } + } +} diff --git a/roles/lib/files/FWO.Data/LdapConnectionBase.cs b/roles/lib/files/FWO.Data/LdapConnectionBase.cs new file mode 100644 index 0000000000..588989a5bb --- /dev/null +++ b/roles/lib/files/FWO.Data/LdapConnectionBase.cs @@ -0,0 +1,160 @@ +using FWO.Basics; +using FWO.Data.Middleware; +using Newtonsoft.Json; +using System.Text.Json.Serialization; + +namespace FWO.Data +{ + public enum LdapType + { + Default = 0, + ActiveDirectory = 1, + OpenLdap = 2 + } + + public class LdapConnectionBase + { + [JsonProperty("ldap_connection_id"), JsonPropertyName("ldap_connection_id")] + public int Id { get; set; } + + [JsonProperty("ldap_server"), JsonPropertyName("ldap_server")] + public string Address { get; set; } = ""; + + [JsonProperty("ldap_port"), JsonPropertyName("ldap_port")] + public int Port { get; set; } + + [JsonProperty("ldap_type"), JsonPropertyName("ldap_type")] + public int Type { get; set; } + + [JsonProperty("ldap_pattern_length"), JsonPropertyName("ldap_pattern_length")] + public int PatternLength { get; set; } + + [JsonProperty("ldap_search_user"), JsonPropertyName("ldap_search_user")] + public string SearchUser { get; set; } = ""; + + [JsonProperty("ldap_tls"), JsonPropertyName("ldap_tls")] + public bool Tls { get; set; } + + [JsonProperty("ldap_tenant_level"), JsonPropertyName("ldap_tenant_level")] + public int TenantLevel { get; set; } + + [JsonProperty("ldap_search_user_pwd"), JsonPropertyName("ldap_search_user_pwd")] + public string SearchUserPwd { get; set; } = ""; + + [JsonProperty("ldap_searchpath_for_users"), JsonPropertyName("ldap_searchpath_for_users")] + public string? UserSearchPath { get; set; } + + [JsonProperty("ldap_searchpath_for_roles"), JsonPropertyName("ldap_searchpath_for_roles")] + public string? RoleSearchPath { get; set; } + + [JsonProperty("ldap_searchpath_for_groups"), JsonPropertyName("ldap_searchpath_for_groups")] + public string? GroupSearchPath { get; set; } + + [JsonProperty("ldap_writepath_for_groups"), JsonPropertyName("ldap_writepath_for_groups")] + public string? GroupWritePath { get; set; } + + [JsonProperty("ldap_write_user"), JsonPropertyName("ldap_write_user")] + public string? WriteUser { get; set; } + + [JsonProperty("ldap_write_user_pwd"), JsonPropertyName("ldap_write_user_pwd")] + public string? WriteUserPwd { get; set; } + + [JsonProperty("tenant_id"), JsonPropertyName("tenant_id")] + public int? TenantId { get; set; } + + [JsonProperty("ldap_global_tenant_name"), JsonPropertyName("ldap_global_tenant_name")] + public string? GlobalTenantName { get; set; } + + [JsonProperty("active"), JsonPropertyName("active")] + public bool Active { get; set; } = true; + + public LdapConnectionBase() + { } + + public LdapConnectionBase(LdapConnectionBase ldapConnection) + { + Id = ldapConnection.Id; + Address = ldapConnection.Address; + Port = ldapConnection.Port; + Type = ldapConnection.Type; + PatternLength = ldapConnection.PatternLength; + SearchUser = ldapConnection.SearchUser; + Tls = ldapConnection.Tls; + TenantLevel = ldapConnection.TenantLevel; + SearchUserPwd = ldapConnection.SearchUserPwd; + UserSearchPath = ldapConnection.UserSearchPath; + RoleSearchPath = ldapConnection.RoleSearchPath; + GroupSearchPath = ldapConnection.GroupSearchPath; + GroupWritePath = ldapConnection.GroupWritePath; + WriteUser = ldapConnection.WriteUser; + WriteUserPwd = ldapConnection.WriteUserPwd; + TenantId = ldapConnection.TenantId; + GlobalTenantName = ldapConnection.GlobalTenantName; + Active = ldapConnection.Active; + } + + public LdapConnectionBase(LdapGetUpdateParameters ldapGetUpdateParameters) + { + Id = ldapGetUpdateParameters.Id; + Address = ldapGetUpdateParameters.Address; + Port = ldapGetUpdateParameters.Port; + Type = ldapGetUpdateParameters.Type; + PatternLength = ldapGetUpdateParameters.PatternLength; + SearchUser = ldapGetUpdateParameters.SearchUser ?? ""; + Tls = ldapGetUpdateParameters.Tls; + TenantLevel = ldapGetUpdateParameters.TenantLevel; + SearchUserPwd = ldapGetUpdateParameters.SearchUserPwd ?? ""; + UserSearchPath = ldapGetUpdateParameters.SearchpathForUsers; + RoleSearchPath = ldapGetUpdateParameters.SearchpathForRoles; + GroupSearchPath = ldapGetUpdateParameters.SearchpathForGroups; + GroupWritePath = ldapGetUpdateParameters.WritepathForGroups; + WriteUser = ldapGetUpdateParameters.WriteUser; + WriteUserPwd = ldapGetUpdateParameters.WriteUserPwd; + TenantId = ldapGetUpdateParameters.TenantId; + GlobalTenantName = ldapGetUpdateParameters.GlobalTenantName; + Active = ldapGetUpdateParameters.Active; + } + + public virtual bool Sanitize() + { + bool shortened = false; + Address = Address.SanitizeMand(ref shortened); + SearchUser = SearchUser.SanitizeLdapPathOpt(ref shortened) ?? ""; + UserSearchPath = UserSearchPath.SanitizeLdapPathOpt(ref shortened); + RoleSearchPath = RoleSearchPath.SanitizeLdapPathOpt(ref shortened); + GroupSearchPath = GroupSearchPath.SanitizeLdapPathOpt(ref shortened); + GroupWritePath = GroupWritePath.SanitizeLdapPathOpt(ref shortened); + WriteUser = WriteUser.SanitizeLdapPathOpt(ref shortened); + GlobalTenantName = GlobalTenantName.SanitizeOpt(ref shortened); + SearchUserPwd = SearchUserPwd.SanitizePasswOpt(ref shortened) ?? ""; + WriteUserPwd = WriteUserPwd.SanitizePasswOpt(ref shortened); + return shortened; + } + + public string Host() + { + return Address != "" ? Address + ":" + Port : ""; + } + + public bool IsWritable() + { + return WriteUser != null && WriteUser != ""; + } + + public bool HasGroupHandling() + { + return (GroupSearchPath != null && GroupSearchPath != "") + || (GroupWritePath != null && GroupWritePath != ""); + } + + public bool HasRoleHandling() + { + return RoleSearchPath != null && RoleSearchPath != ""; + } + + public bool IsInternal() + { + return new DistName(UserSearchPath).IsInternal(); + } + } +} diff --git a/roles/lib/files/FWO.Data/LinkType.cs b/roles/lib/files/FWO.Data/LinkType.cs new file mode 100644 index 0000000000..cddba04f55 --- /dev/null +++ b/roles/lib/files/FWO.Data/LinkType.cs @@ -0,0 +1,15 @@ + +using System.Text.Json.Serialization; +using Newtonsoft.Json; + +namespace FWO.Data +{ + public class LinkType + { + [JsonProperty("id"), JsonPropertyName("id")] + public int Id { get; set; } + + [JsonProperty("name"), JsonPropertyName("name")] + public string Name { get; set; } = ""; + } +} diff --git a/roles/lib/files/FWO.Api.Client/Data/LogEntry.cs b/roles/lib/files/FWO.Data/LogEntry.cs similarity index 96% rename from roles/lib/files/FWO.Api.Client/Data/LogEntry.cs rename to roles/lib/files/FWO.Data/LogEntry.cs index 0f6846d0c4..dff78a4cd6 100644 --- a/roles/lib/files/FWO.Api.Client/Data/LogEntry.cs +++ b/roles/lib/files/FWO.Data/LogEntry.cs @@ -1,7 +1,7 @@ -using System.Text.Json.Serialization; +using System.Text.Json.Serialization; using Newtonsoft.Json; -namespace FWO.Api.Data +namespace FWO.Data { public class LogEntry { diff --git a/roles/lib/files/FWO.Data/Logging/ChangeLogRequest.cs b/roles/lib/files/FWO.Data/Logging/ChangeLogRequest.cs new file mode 100644 index 0000000000..033a5f7ab8 --- /dev/null +++ b/roles/lib/files/FWO.Data/Logging/ChangeLogRequest.cs @@ -0,0 +1,13 @@ +namespace FWO.Data.Logging +{ + public sealed record ChangeLogRequest + { + public required ChangeLogFamily Family { get; init; } + public required ChangeLogObject Object { get; init; } + public required ChangeLogOperation Operation { get; init; } + public required string UserId { get; init; } + public required ChangeLogOrigin Origin { get; init; } + public DateTime Timestamp { get; init; } = DateTime.UtcNow; + public (string Key, object? Value)[] Fields { get; init; } = []; + } +} diff --git a/roles/lib/files/FWO.Data/Logging/GatewayChangeLogRequest.cs b/roles/lib/files/FWO.Data/Logging/GatewayChangeLogRequest.cs new file mode 100644 index 0000000000..33d9251b93 --- /dev/null +++ b/roles/lib/files/FWO.Data/Logging/GatewayChangeLogRequest.cs @@ -0,0 +1,33 @@ +namespace FWO.Data.Logging +{ + public sealed record GatewayChangeLogRequest + { + public required ChangeLogFamily Family { get; init; } + public required ChangeLogOperation Operation { get; init; } + public required string UserId { get; init; } + public required ChangeLogOrigin Origin { get; init; } + public DateTime Timestamp { get; init; } = DateTime.UtcNow; + public int? DeviceId { get; init; } + public string? DeviceName { get; init; } + public int? ManagementId { get; init; } + + public ChangeLogRequest ToChangeLogRequest() + { + return new ChangeLogRequest + { + Family = Family, + Object = ChangeLogObject.Gateway, + Operation = Operation, + UserId = UserId, + Origin = Origin, + Timestamp = Timestamp, + Fields = + [ + ("Device ID", DeviceId), + ("Device Name", DeviceName), + ("Management ID", ManagementId) + ] + }; + } + } +} diff --git a/roles/lib/files/FWO.Data/Logging/GatewayPromptLogRequest.cs b/roles/lib/files/FWO.Data/Logging/GatewayPromptLogRequest.cs new file mode 100644 index 0000000000..a1716b54b7 --- /dev/null +++ b/roles/lib/files/FWO.Data/Logging/GatewayPromptLogRequest.cs @@ -0,0 +1,35 @@ +namespace FWO.Data.Logging +{ + public sealed record GatewayPromptLogRequest + { + public required PromptLogEvent PromptEvent { get; init; } + public required ChangeLogOperation Operation { get; init; } + public required string UserId { get; init; } + public required ChangeLogOrigin Origin { get; init; } + public DateTime Timestamp { get; init; } = DateTime.UtcNow; + public int? DeviceId { get; init; } + public string? DeviceName { get; init; } + public int? ManagementId { get; init; } + public string? ManagementName { get; init; } + + public PromptLogRequest ToPromptLogRequest() + { + return new PromptLogRequest + { + PromptEvent = PromptEvent, + Object = ChangeLogObject.Gateway, + Operation = Operation, + UserId = UserId, + Origin = Origin, + Timestamp = Timestamp, + Fields = + [ + ("Device ID", DeviceId), + ("Device Name", DeviceName), + ("Management ID", ManagementId), + ("Management Name", ManagementName) + ] + }; + } + } +} diff --git a/roles/lib/files/FWO.Data/Logging/ManagementChangeLogRequest.cs b/roles/lib/files/FWO.Data/Logging/ManagementChangeLogRequest.cs new file mode 100644 index 0000000000..c575963d05 --- /dev/null +++ b/roles/lib/files/FWO.Data/Logging/ManagementChangeLogRequest.cs @@ -0,0 +1,31 @@ +namespace FWO.Data.Logging +{ + public sealed record ManagementChangeLogRequest + { + public required ChangeLogFamily Family { get; init; } + public required ChangeLogOperation Operation { get; init; } + public required string UserId { get; init; } + public required ChangeLogOrigin Origin { get; init; } + public DateTime Timestamp { get; init; } = DateTime.UtcNow; + public int? ManagementId { get; init; } + public string? ManagementName { get; init; } + + public ChangeLogRequest ToChangeLogRequest() + { + return new ChangeLogRequest + { + Family = Family, + Object = ChangeLogObject.Management, + Operation = Operation, + UserId = UserId, + Origin = Origin, + Timestamp = Timestamp, + Fields = + [ + ("Management ID", ManagementId), + ("Management Name", ManagementName) + ] + }; + } + } +} diff --git a/roles/lib/files/FWO.Data/Logging/ManagementPromptLogRequest.cs b/roles/lib/files/FWO.Data/Logging/ManagementPromptLogRequest.cs new file mode 100644 index 0000000000..318000dbe0 --- /dev/null +++ b/roles/lib/files/FWO.Data/Logging/ManagementPromptLogRequest.cs @@ -0,0 +1,31 @@ +namespace FWO.Data.Logging +{ + public sealed record ManagementPromptLogRequest + { + public required PromptLogEvent PromptEvent { get; init; } + public required ChangeLogOperation Operation { get; init; } + public required string UserId { get; init; } + public required ChangeLogOrigin Origin { get; init; } + public DateTime Timestamp { get; init; } = DateTime.UtcNow; + public int? ManagementId { get; init; } + public string? ManagementName { get; init; } + + public PromptLogRequest ToPromptLogRequest() + { + return new PromptLogRequest + { + PromptEvent = PromptEvent, + Object = ChangeLogObject.Management, + Operation = Operation, + UserId = UserId, + Origin = Origin, + Timestamp = Timestamp, + Fields = + [ + ("Management ID", ManagementId), + ("Management Name", ManagementName) + ] + }; + } + } +} diff --git a/roles/lib/files/FWO.Data/Logging/MatrixChangeLogRequest.cs b/roles/lib/files/FWO.Data/Logging/MatrixChangeLogRequest.cs new file mode 100644 index 0000000000..1dad0cf5ac --- /dev/null +++ b/roles/lib/files/FWO.Data/Logging/MatrixChangeLogRequest.cs @@ -0,0 +1,31 @@ +namespace FWO.Data.Logging +{ + public sealed record MatrixChangeLogRequest + { + public required ChangeLogFamily Family { get; init; } + public required ChangeLogOperation Operation { get; init; } + public required string UserId { get; init; } + public required ChangeLogOrigin Origin { get; init; } + public DateTime Timestamp { get; init; } = DateTime.UtcNow; + public int? MatrixId { get; init; } + public string? MatrixName { get; init; } + + public ChangeLogRequest ToChangeLogRequest() + { + return new ChangeLogRequest + { + Family = Family, + Object = ChangeLogObject.Matrix, + Operation = Operation, + UserId = UserId, + Origin = Origin, + Timestamp = Timestamp, + Fields = + [ + ("Matrix ID", MatrixId), + ("Matrix Name", MatrixName) + ] + }; + } + } +} diff --git a/roles/lib/files/FWO.Data/Logging/PromptLogRequest.cs b/roles/lib/files/FWO.Data/Logging/PromptLogRequest.cs new file mode 100644 index 0000000000..3c4604bdd4 --- /dev/null +++ b/roles/lib/files/FWO.Data/Logging/PromptLogRequest.cs @@ -0,0 +1,13 @@ +namespace FWO.Data.Logging +{ + public sealed record PromptLogRequest + { + public required PromptLogEvent PromptEvent { get; init; } + public required ChangeLogObject Object { get; init; } + public required ChangeLogOperation Operation { get; init; } + public required string UserId { get; init; } + public required ChangeLogOrigin Origin { get; init; } + public DateTime Timestamp { get; init; } = DateTime.UtcNow; + public (string Key, object? Value)[] Fields { get; init; } = []; + } +} diff --git a/roles/lib/files/FWO.Data/Management.cs b/roles/lib/files/FWO.Data/Management.cs new file mode 100644 index 0000000000..4934d7fa42 --- /dev/null +++ b/roles/lib/files/FWO.Data/Management.cs @@ -0,0 +1,198 @@ +using FWO.Basics; +using Newtonsoft.Json; +using System.Text.Json.Serialization; + +namespace FWO.Data +{ + public struct ExtMgtData + { + [JsonProperty("id"), JsonPropertyName("id")] + public string? ExtId { get; set; } + + [JsonProperty("name"), JsonPropertyName("name")] + public string? ExtName { get; set; } + } + + public sealed class Management + { + [JsonProperty("id"), JsonPropertyName("id")] + public int Id { get; set; } + + [JsonProperty("name"), JsonPropertyName("name")] + public string Name { get; set; } = ""; + + [JsonProperty("uid"), JsonPropertyName("uid")] + public string? Uid { get; set; } = ""; + + [JsonProperty("hostname"), JsonPropertyName("hostname")] + public string Hostname { get; set; } = ""; + + [JsonProperty("import_credential"), JsonPropertyName("import_credential")] + public ImportCredential ImportCredential { get; set; } = new(); + + [JsonProperty("configPath"), JsonPropertyName("configPath")] + public string? ConfigPath { get; set; } = ""; + + [JsonProperty("domainUid"), JsonPropertyName("domainUid")] + public string? DomainUid { get; set; } = ""; + + [JsonProperty("cloudSubscriptionId"), JsonPropertyName("cloudSubscriptionId")] + public string? CloudSubscriptionId { get; set; } = ""; + + [JsonProperty("cloudTenantId"), JsonPropertyName("cloudTenantId")] + public string? CloudTenantId { get; set; } = ""; + + [JsonProperty("multi_device_manager_id"), JsonPropertyName("multi_device_manager_id")] + public int? SuperManagerId { get; set; } + + [JsonProperty("is_super_manager"), JsonPropertyName("is_super_manager")] + public bool IsSupermanager { get; set; } = false; + + [JsonProperty("importerHostname"), JsonPropertyName("importerHostname")] + public string? ImporterHostname { get; set; } = ""; + + [JsonProperty("port"), JsonPropertyName("port")] + public int Port { get; set; } + + [JsonProperty("importDisabled"), JsonPropertyName("importDisabled")] + public bool ImportDisabled { get; set; } + + [JsonProperty("forceInitialImport"), JsonPropertyName("forceInitialImport")] + public bool ForceInitialImport { get; set; } + + [JsonProperty("hideInUi"), JsonPropertyName("hideInUi")] + public bool HideInUi { get; set; } + + [JsonProperty("comment"), JsonPropertyName("comment")] + public string? Comment { get; set; } + + [JsonProperty("debugLevel"), JsonPropertyName("debugLevel")] + public int? DebugLevel { get; set; } + + [JsonProperty("devices"), JsonPropertyName("devices")] + public Device[] Devices { get; set; } = []; + + [JsonProperty("rulebases"), JsonPropertyName("rulebases")] + public Rulebase[] Rulebases { get; set; } = []; + + [JsonProperty("networkObjects"), JsonPropertyName("networkObjects")] + public NetworkObject[] Objects { get; set; } = []; + + [JsonProperty("serviceObjects"), JsonPropertyName("serviceObjects")] + public NetworkService[] Services { get; set; } = []; + + [JsonProperty("userObjects"), JsonPropertyName("userObjects")] + public NetworkUser[] Users { get; set; } = []; + + [JsonProperty("zoneObjects"), JsonPropertyName("zoneObjects")] + public NetworkZone[] Zones { get; set; } = []; + + [JsonProperty("timeObjects"), JsonPropertyName("timeObjects")] + public TimeObject[] TimeObjects { get; set; } = []; + + [JsonProperty("deviceType"), JsonPropertyName("deviceType")] + public DeviceType DeviceType { get; set; } = new(); + + [JsonProperty("import"), JsonPropertyName("import")] + public Import Import { get; set; } = new(); + + [JsonProperty("extMgtData"), JsonPropertyName("extMgtData")] + public string? ExtMgtData { get; set; } + + // only relevant for super managers, normal managers do not have rulebases + [JsonProperty("rulebase_name"), JsonPropertyName("rulebase_name")] + public string? RulebaseName { get; set; } + + // only relevant for super managers, normal managers do not have rulebases + [JsonProperty("rulebase_uid"), JsonPropertyName("rulebase_uid")] + public string? RulebaseUid { get; set; } + + public long? RelevantImportId { get; set; } + public bool Ignore { get; set; } + public bool AwaitDevice { get; set; } + public bool Delete { get; set; } + public long ActionId { get; set; } + + public Management() + { } + + public Management(Management management) + { + Id = management.Id; + Name = management.Name; + Uid = management.Uid; + Hostname = management.Hostname; + if (management.ImportCredential != null) + ImportCredential = new ImportCredential(management.ImportCredential); + else + ImportCredential = new ImportCredential(); + ConfigPath = management.ConfigPath; + DomainUid = management.DomainUid; + CloudSubscriptionId = management.CloudSubscriptionId; + CloudTenantId = management.CloudTenantId; + SuperManagerId = management.SuperManagerId; + ImporterHostname = management.ImporterHostname; + Port = management.Port; + ImportDisabled = management.ImportDisabled; + ForceInitialImport = management.ForceInitialImport; + HideInUi = management.HideInUi; + Comment = management.Comment; + DebugLevel = management.DebugLevel; + Devices = management.Devices; + if (management.DeviceType != null) + DeviceType = new DeviceType(management.DeviceType); + Import = management.Import; + if (management.Import != null && management.Import.ImportAggregate != null && + management.Import.ImportAggregate.ImportAggregateMax != null && + management.Import.ImportAggregate.ImportAggregateMax.RelevantImportId != null) + { + RelevantImportId = management.Import.ImportAggregate.ImportAggregateMax.RelevantImportId; + } + Ignore = management.Ignore; + AwaitDevice = management.AwaitDevice; + Delete = management.Delete; + ActionId = management.ActionId; + ExtMgtData = management.ExtMgtData; + } + + public string Host() + { + return Hostname + ":" + Port; + } + + public bool Equals(Management management) + { + return Uid.GenerousCompare(management.Uid) && + Name.GenerousCompare(management.Name) && + Hostname.GenerousCompare(management.Hostname) && + ConfigPath.GenerousCompare(management.ConfigPath) && + DomainUid.GenerousCompare(management.DomainUid) && + CloudSubscriptionId.GenerousCompare(management.CloudSubscriptionId) && + CloudTenantId.GenerousCompare(management.CloudTenantId) && + SuperManagerId == management.SuperManagerId && + Port == management.Port; + } + + public bool Sanitize() + { + bool shortened = false; + Name = Name.SanitizeMand(ref shortened); + Uid = Uid.SanitizeOpt(ref shortened); + Hostname = Hostname.SanitizeMand(ref shortened); + ConfigPath = ConfigPath.SanitizeOpt(ref shortened); + DomainUid = DomainUid.SanitizeOpt(ref shortened); + if (ImporterHostname != null) + { + ImporterHostname = ImporterHostname.SanitizeMand(ref shortened); + } + else + { + ImporterHostname = ""; + } + Comment = Comment.SanitizeCommentOpt(ref shortened); + CloudSubscriptionId = CloudSubscriptionId.SanitizeOpt(ref shortened); + CloudTenantId = CloudTenantId.SanitizeOpt(ref shortened); + return shortened; + } + } +} diff --git a/roles/lib/files/FWO.Data/MessageType.cs b/roles/lib/files/FWO.Data/MessageType.cs new file mode 100644 index 0000000000..a9e74e3a02 --- /dev/null +++ b/roles/lib/files/FWO.Data/MessageType.cs @@ -0,0 +1,10 @@ +namespace FWO.Data +{ + public enum MessageType + { + Info, + Success, + Warning, + Error + } +} diff --git a/roles/lib/files/FWO.Middleware/RequestParameters/AuthenticationServerParameters.cs b/roles/lib/files/FWO.Data/Middleware/AuthenticationServerParameters.cs similarity index 90% rename from roles/lib/files/FWO.Middleware/RequestParameters/AuthenticationServerParameters.cs rename to roles/lib/files/FWO.Data/Middleware/AuthenticationServerParameters.cs index 8579b46314..9401879408 100644 --- a/roles/lib/files/FWO.Middleware/RequestParameters/AuthenticationServerParameters.cs +++ b/roles/lib/files/FWO.Data/Middleware/AuthenticationServerParameters.cs @@ -1,4 +1,4 @@ -namespace FWO.Middleware.RequestParameters +namespace FWO.Data.Middleware { public class LdapAddParameters { @@ -14,6 +14,7 @@ public class LdapAddParameters public string? SearchpathForUsers { get; set; } public string? SearchpathForRoles { get; set; } public string? SearchpathForGroups { get; set; } + public string? WritepathForGroups { get; set; } public string? WriteUser { get; set; } public string? WriteUserPwd { get; set; } public int? TenantId { get; set; } @@ -21,7 +22,7 @@ public class LdapAddParameters public bool Active { get; set; } public LdapAddParameters() - {} + { } public LdapAddParameters(LdapAddParameters ldapAddParameters) { @@ -37,6 +38,7 @@ public LdapAddParameters(LdapAddParameters ldapAddParameters) SearchpathForUsers = ldapAddParameters.SearchpathForUsers; SearchpathForRoles = ldapAddParameters.SearchpathForRoles; SearchpathForGroups = ldapAddParameters.SearchpathForGroups; + WritepathForGroups = ldapAddParameters.WritepathForGroups; WriteUser = ldapAddParameters.WriteUser; WriteUserPwd = ldapAddParameters.WriteUserPwd; TenantId = ldapAddParameters.TenantId; @@ -50,9 +52,9 @@ public class LdapGetUpdateParameters : LdapAddParameters public int Id { get; set; } public LdapGetUpdateParameters() - {} + { } - public LdapGetUpdateParameters(LdapAddParameters ldapAddParameters, int id) : base (ldapAddParameters) + public LdapGetUpdateParameters(LdapAddParameters ldapAddParameters, int id) : base(ldapAddParameters) { Id = id; } diff --git a/roles/lib/files/FWO.Middleware/RequestParameters/AuthenticationTokenParameters.cs b/roles/lib/files/FWO.Data/Middleware/AuthenticationTokenParameters.cs similarity index 75% rename from roles/lib/files/FWO.Middleware/RequestParameters/AuthenticationTokenParameters.cs rename to roles/lib/files/FWO.Data/Middleware/AuthenticationTokenParameters.cs index 1048915426..7715d9c0b8 100644 --- a/roles/lib/files/FWO.Middleware/RequestParameters/AuthenticationTokenParameters.cs +++ b/roles/lib/files/FWO.Data/Middleware/AuthenticationTokenParameters.cs @@ -1,10 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace FWO.Middleware.RequestParameters +namespace FWO.Data.Middleware { public class AuthenticationTokenGetParameters { diff --git a/roles/lib/files/FWO.Data/Middleware/ComplianceParameters.cs b/roles/lib/files/FWO.Data/Middleware/ComplianceParameters.cs new file mode 100644 index 0000000000..e5310a295a --- /dev/null +++ b/roles/lib/files/FWO.Data/Middleware/ComplianceParameters.cs @@ -0,0 +1,15 @@ +namespace FWO.Data.Middleware +{ + public class ComplianceReportParameters + { + public List ManagementIds { get; set; } = []; + } + + public class ComplianceImportMatrixParameters + { + public string FileName { get; set; } = ""; + public string Data { get; set; } = ""; + public string UserName { get; set; } = ""; + public string UserDn { get; set; } = ""; + } +} diff --git a/roles/lib/files/FWO.Data/Middleware/DebugConfig.cs b/roles/lib/files/FWO.Data/Middleware/DebugConfig.cs new file mode 100644 index 0000000000..7207588ece --- /dev/null +++ b/roles/lib/files/FWO.Data/Middleware/DebugConfig.cs @@ -0,0 +1,21 @@ +using Newtonsoft.Json; +using System.Text.Json.Serialization; + +namespace FWO.Data.Middleware +{ + public class DebugConfig + { + [JsonProperty("debugLevel"), JsonPropertyName("debugLevel")] + public int DebugLevel { get; set; } = 0; + + [JsonProperty("extendedLogComplianceCheck"), JsonPropertyName("extendedLogComplianceCheck")] + public bool ExtendedLogComplianceCheck { get; set; } = false; + + [JsonProperty("extendedLogReportGeneration"), JsonPropertyName("extendedLogReportGeneration")] + public bool ExtendedLogReportGeneration { get; set; } = false; + + [JsonProperty("extendedLogScheduler"), JsonPropertyName("extendedLogScheduler")] + public bool ExtendedLogScheduler { get; set; } = false; + + } +} diff --git a/roles/lib/files/FWO.Data/Middleware/ExternalRequestParameters.cs b/roles/lib/files/FWO.Data/Middleware/ExternalRequestParameters.cs new file mode 100644 index 0000000000..0c1979dcc7 --- /dev/null +++ b/roles/lib/files/FWO.Data/Middleware/ExternalRequestParameters.cs @@ -0,0 +1,16 @@ +namespace FWO.Data.Middleware +{ + public class ExternalRequestAddParameters + { + public long TicketId { get; set; } + } + + public class ExternalRequestPatchStateParameters + { + public long ExtRequestId { get; set; } + public long TicketId { get; set; } + public int TaskNumber { get; set; } + public string ExtQueryVariables { get; set; } = ""; + public string ExtRequestState { get; set; } = ""; + } +} diff --git a/roles/lib/files/FWO.Data/Middleware/GroupParameters.cs b/roles/lib/files/FWO.Data/Middleware/GroupParameters.cs new file mode 100644 index 0000000000..1b8e8d7d93 --- /dev/null +++ b/roles/lib/files/FWO.Data/Middleware/GroupParameters.cs @@ -0,0 +1,49 @@ +namespace FWO.Data.Middleware +{ + public class GroupGetParameters + { + public int LdapId { get; set; } + public string SearchPattern { get; set; } = ""; + } + + public class GroupGetReturnParameters + { + public string GroupDn { get; set; } = ""; + public bool OwnerGroup { get; set; } = false; + public List Members { get; set; } = new List(); + } + + public class GroupAddDeleteParameters + { + public string GroupName { get; set; } = ""; + public bool OwnerGroup { get; set; } = false; + } + + public class GroupEditParameters + { + public string OldGroupName { get; set; } = ""; + public string NewGroupName { get; set; } = ""; + } + + public class GroupAddDeleteUserParameters + { + public string UserDn { get; set; } = ""; + public string GroupDn { get; set; } = ""; + } + + public class GroupMemberGetParameters + { + public string GroupDn { get; set; } = ""; + } + + public class GroupMembershipGetParameters + { + public string UserDn { get; set; } = ""; + public string UserName { get; set; } = ""; + } + + public class GroupResolveParameters + { + public List Dns { get; set; } = new(); + } +} diff --git a/roles/lib/files/FWO.Data/Middleware/NormalizedConfigParameters.cs b/roles/lib/files/FWO.Data/Middleware/NormalizedConfigParameters.cs new file mode 100644 index 0000000000..7181ee976c --- /dev/null +++ b/roles/lib/files/FWO.Data/Middleware/NormalizedConfigParameters.cs @@ -0,0 +1,14 @@ + +using System.Text.Json.Serialization; + +namespace FWO.Data.Middleware +{ + public class NormalizedConfigGetParameters + { + [JsonPropertyName("mgm-ids")] + public int[] ManagementIds { get; set; } = []; + + [JsonPropertyName("config-time")] + public string? ConfigTime { get; set; } + } +} diff --git a/roles/lib/files/FWO.Data/Middleware/ReportParameters.cs b/roles/lib/files/FWO.Data/Middleware/ReportParameters.cs new file mode 100644 index 0000000000..3dcfc5f0d9 --- /dev/null +++ b/roles/lib/files/FWO.Data/Middleware/ReportParameters.cs @@ -0,0 +1,85 @@ +using System.Text.Json.Serialization; +using Newtonsoft.Json; + +namespace FWO.Data.Middleware +{ + public class ReportGetParameters + { + // { + // "device-filter": { + // "management-ids": [2, 4], + // "gateway-ids": [6,8, 9] + // }, + // "report-type": "rules [default] |changes|....", + // "report-view": ["standard|resolved|technical|with-zones|with-labels|..."], + // "rule-filter": { + // "source-ip": ["1.2.3.0/24", "3.4.5.6"], + // "destination-ip": ["1.2.3.0/24", "3.4.5.6"], + // "ip": ["1.2.3.0/24", "3.4.5.6"], + // "service": [ + // { + // "protocol": 17, + // "name": "http", + // "port": 4711 + // } + // ], + // "action": "allow", + // "active": true + // } + // } + + [JsonProperty("device-filter"), JsonPropertyName("device-filter")] + public ApiDeviceFilter ApiDeviceFilter { get; set; } = new(); + + [JsonProperty("report-type"), JsonPropertyName("report-type")] + public string ApiReportType { get; set; } = ""; + + [JsonProperty("report-view"), JsonPropertyName("report-view")] + public List ApiReportView { get; set; } = []; + + [JsonProperty("rule-filter"), JsonPropertyName("rule-filter")] + public ApiRuleFilter ApiRuleFilter { get; set; } = new(); + + [JsonProperty("action"), JsonPropertyName("action")] + public string? Action { get; set; } + + [JsonProperty("active"), JsonPropertyName("active")] + public bool? Active { get; set; } + } + + public class ApiDeviceFilter + { + [JsonProperty("management-ids"), JsonPropertyName("management-ids")] + public List ManagementIds { get; set; } = []; + + [JsonProperty("gateway-ids"), JsonPropertyName("gateway-ids")] + public List DeviceIds { get; set; } = []; + } + + public class ApiRuleFilter + { + [JsonProperty("ip"), JsonPropertyName("ip")] + public List Ips { get; set; } = []; + + [JsonProperty("source-ip"), JsonPropertyName("source-ip")] + public List SourceIps { get; set; } = []; + + [JsonProperty("destination-ip"), JsonPropertyName("destination-ip")] + public List DestinationIps { get; set; } = []; + + [JsonProperty("service"), JsonPropertyName("service")] + public List Services { get; set; } = []; + } + + public class ApiService + { + [JsonProperty("protocol"), JsonPropertyName("protocol")] + public int? Protocol { get; set; } + + [JsonProperty("name"), JsonPropertyName("name")] + public string? Name { get; set; } + + [JsonProperty("port"), JsonPropertyName("port")] + public int? Port { get; set; } + } +} diff --git a/roles/lib/files/FWO.Middleware/RequestParameters/RoleParameters.cs b/roles/lib/files/FWO.Data/Middleware/RoleParameters.cs similarity index 91% rename from roles/lib/files/FWO.Middleware/RequestParameters/RoleParameters.cs rename to roles/lib/files/FWO.Data/Middleware/RoleParameters.cs index 051d5f8805..39c31dcc66 100644 --- a/roles/lib/files/FWO.Middleware/RequestParameters/RoleParameters.cs +++ b/roles/lib/files/FWO.Data/Middleware/RoleParameters.cs @@ -1,4 +1,4 @@ -namespace FWO.Middleware.RequestParameters +namespace FWO.Data.Middleware { public class RoleAddDeleteUserParameters { diff --git a/roles/lib/files/FWO.Data/Middleware/SchedulerParameters.cs b/roles/lib/files/FWO.Data/Middleware/SchedulerParameters.cs new file mode 100644 index 0000000000..c87593f09b --- /dev/null +++ b/roles/lib/files/FWO.Data/Middleware/SchedulerParameters.cs @@ -0,0 +1,20 @@ +namespace FWO.Data.Middleware +{ + /// Represents a Quartz job exposed to the UI. + public class SchedulerJobInfo + { + public string JobName { get; set; } = ""; + public string Group { get; set; } = ""; + public DateTimeOffset? NextFireTimeUtc { get; set; } + public DateTimeOffset? LastFireTimeUtc { get; set; } + public string IntervalDescription { get; set; } = ""; + public SchedulerJobExecutionStatus LastExecutionStatus { get; set; } = SchedulerJobExecutionStatus.None; + public string LastExecutionError { get; set; } = ""; + } + + /// Request payload to trigger a job manually. + public class SchedulerJobTriggerParameters + { + public string JobName { get; set; } = ""; + } +} diff --git a/roles/lib/files/FWO.Data/Middleware/TenantParameters.cs b/roles/lib/files/FWO.Data/Middleware/TenantParameters.cs new file mode 100644 index 0000000000..bd7d34a994 --- /dev/null +++ b/roles/lib/files/FWO.Data/Middleware/TenantParameters.cs @@ -0,0 +1,66 @@ +namespace FWO.Data.Middleware + +// used for accessing tenant data stored in LDAP via REST UserManagement API +// but tenant to device mappings (not stored in LDAP but in DB) are also handled here + +{ + public class TenantAddParameters + { + public string Name { get; set; } = ""; + public string? Comment { get; set; } + public string? Project { get; set; } + public bool ViewAllDevices { get; set; } + // public bool Superadmin { get; set; } + } + + public class TenantGetReturnParameters : TenantAddParameters + { + public int Id { get; set; } + public List SharedGateways { get; set; } = new List(); + public List SharedManagements { get; set; } = new List(); + public List UnfilteredGateways { get; set; } = new List(); + public List UnfilteredManagements { get; set; } = new List(); + public List VisibleGateways { get; set; } = new List(); + public List VisibleManagements { get; set; } = new List(); + } + + public class TenantViewGateway + { + public int Id { get; set; } + public string Name { get; set; } = ""; + public bool Shared { get; set; } = true; + + public TenantViewGateway(int id, string name = "", bool shared = true) + { + Id = id; + Name = name; + Shared = shared; + } + } + public class TenantViewManagement + { + public int Id { get; set; } + public string Name { get; set; } = ""; + public bool Shared { get; set; } = true; + public TenantViewManagement(int id, string name = "", bool shared = true) + { + Id = id; + Name = name; + Shared = shared; + } + } + + public class TenantEditParameters + { + public int Id { get; set; } + public string? Comment { get; set; } + public string? Project { get; set; } + public bool ViewAllDevices { get; set; } + } + + public class TenantDeleteParameters + { + public int Id { get; set; } + public string Name { get; set; } = ""; + } +} diff --git a/roles/lib/files/FWO.Middleware/RequestParameters/UserParameters.cs b/roles/lib/files/FWO.Data/Middleware/UserParameters.cs similarity index 83% rename from roles/lib/files/FWO.Middleware/RequestParameters/UserParameters.cs rename to roles/lib/files/FWO.Data/Middleware/UserParameters.cs index 9c2f96f5bc..6bce9b4bf0 100644 --- a/roles/lib/files/FWO.Middleware/RequestParameters/UserParameters.cs +++ b/roles/lib/files/FWO.Data/Middleware/UserParameters.cs @@ -1,4 +1,4 @@ -namespace FWO.Middleware.RequestParameters +namespace FWO.Data.Middleware { public class UserGetReturnParameters { @@ -6,6 +6,8 @@ public class UserGetReturnParameters public int UserId { get; set; } public string UserDn { get; set; } = ""; public string? Email { get; set; } + public string? Firstname { get; set; } + public string? Lastname { get; set; } public int TenantId { get; set; } public string? Language { get; set; } public DateTime? LastLogin { get; set; } @@ -24,6 +26,8 @@ public class LdapUserGetReturnParameters { public string UserDn { get; set; } = ""; public string? Email { get; set; } + public string? Firstname { get; set; } + public string? Lastname { get; set; } } public class UserAddParameters @@ -32,6 +36,8 @@ public class UserAddParameters public string UserDn { get; set; } = ""; public string Password { get; set; } = ""; public string? Email { get; set; } + public string? Firstname { get; set; } + public string? Lastname { get; set; } public int TenantId { get; set; } public bool PwChangeRequired { get; set; } } @@ -41,6 +47,8 @@ public class UserEditParameters public int LdapId { get; set; } public int UserId { get; set; } public string? Email { get; set; } + public string? Firstname { get; set; } + public string? Lastname { get; set; } } public class UserChangePasswordParameters diff --git a/roles/lib/files/FWO.Data/Modelling/ModellingAppRole.cs b/roles/lib/files/FWO.Data/Modelling/ModellingAppRole.cs new file mode 100644 index 0000000000..e4eaa284e3 --- /dev/null +++ b/roles/lib/files/FWO.Data/Modelling/ModellingAppRole.cs @@ -0,0 +1,133 @@ +using System.Text.Json.Serialization; +using Newtonsoft.Json; +using FWO.Basics; + +namespace FWO.Data.Modelling +{ + public class ModellingAppRole : ModellingNwGroup + { + [JsonProperty("comment"), JsonPropertyName("comment")] + public string? Comment { get; set; } + + [JsonProperty("creator"), JsonPropertyName("creator")] + public string? Creator { get; set; } + + [JsonProperty("creation_date"), JsonPropertyName("creation_date")] + public DateTime? CreationDate { get; set; } + + [JsonProperty("nwobjects"), JsonPropertyName("nwobjects")] + public List AppServers { get; set; } = []; + + public ModellingNetworkArea? Area { get; set; } = new(); + public bool IsMissing { get; set; } = false; + public bool HasDifference { get; set; } = false; + public List SurplusAppServers { get; set; } = []; + public string ManagementName { get; set; } = ""; + + + public ModellingAppRole() + { } + + public ModellingAppRole(ModellingAppRole appRole) : base(appRole) + { + Comment = appRole.Comment; + Creator = appRole.Creator; + CreationDate = appRole.CreationDate; + AppServers = appRole.AppServers; + Area = appRole.Area; + IsMissing = appRole.IsMissing; + HasDifference = appRole.HasDifference; + SurplusAppServers = appRole.SurplusAppServers; + ManagementName = appRole.ManagementName; + } + + public ModellingAppRole(NetworkObject nwObj, ModellingNamingConvention? namCon = null) : base(nwObj, namCon) + { + Comment = nwObj.Comment; + CreationDate = nwObj.CreateTime.Time; + AppServers = ConvertNwObjectsToAppServers(nwObj.ObjectGroupFlats); + // Todo: Fill Area + AppId from IdString (-> Naming Convention)? + } + + protected static List ConvertNwObjectsToAppServers(GroupFlat[] groupFlats) + { + List appServers = []; + foreach (var obj in groupFlats.Where(x => x.Object?.IP != null && x.Object?.IP != "").Select(o => o.Object)) + { + appServers.Add(new ModellingAppServerWrapper() { Content = obj != null ? new(obj) : new() }); + } + return appServers; + } + + public ModellingNwGroup ToBase() + { + return new ModellingNwGroup() + { + Id = Id, + Number = Number, + GroupType = GroupType, + IdString = IdString, + Name = Name, + AppId = AppId, + IsDeleted = IsDeleted + }; + } + + public override string DisplayWithIcon() + { + return $" " + DisplayHtml(); + } + + public override string DisplayProblematicWithIcon() + { + return $" " + DisplayHtml() + $""; + } + + public override NetworkObject ToNetworkObjectGroup(bool IdAsName = false, bool ListMembers = true) + { + Group[] objectGroups = ModellingAppRoleWrapper.ResolveAppServersAsNetworkObjectGroup(AppServers ?? []); + GroupFlat[] objectGroupFlats = ModellingAppRoleWrapper.ResolveAppServersAsNetworkObjectGroupFlat(AppServers ?? []); + + return new() + { + Id = Id, + Number = Number, + Name = IdAsName ? IdString : Name + " (" + IdString + ")" ?? IdString ?? "", + Comment = Comment ?? "", + Type = new NetworkObjectType() { Name = ObjectType.Group }, + ObjectGroups = objectGroups, + ObjectGroupFlats = objectGroupFlats, + MemberNames = ListMembers ? string.Join("|", Array.ConvertAll(objectGroups, o => o.Object?.Name)) : "..." + }; + } + + public override bool Sanitize() + { + bool shortened = base.Sanitize(); + Comment = Comment.SanitizeCommentOpt(ref shortened); + Creator = Creator.SanitizeOpt(ref shortened); + return shortened; + } + } + + public class ModellingAppRoleWrapper + { + [JsonProperty("nwgroup"), JsonPropertyName("nwgroup")] + public ModellingAppRole Content { get; set; } = new(); + + public static ModellingAppRole[] Resolve(List wrappedList) + { + return Array.ConvertAll(wrappedList.ToArray(), wrapper => wrapper.Content); + } + + public static Group[] ResolveAppServersAsNetworkObjectGroup(List wrappedList) + { + return Array.ConvertAll(wrappedList.ToArray(), wrapper => new Group { Id = wrapper.Content.Id, Object = ModellingAppServer.ToNetworkObject(wrapper.Content) }); + } + + public static GroupFlat[] ResolveAppServersAsNetworkObjectGroupFlat(List wrappedList) + { + return Array.ConvertAll(wrappedList.ToArray(), wrapper => new GroupFlat { Id = wrapper.Content.Id, Object = ModellingAppServer.ToNetworkObject(wrapper.Content) }); + } + } +} diff --git a/roles/lib/files/FWO.Data/Modelling/ModellingAppServer.cs b/roles/lib/files/FWO.Data/Modelling/ModellingAppServer.cs new file mode 100644 index 0000000000..8a03c868c6 --- /dev/null +++ b/roles/lib/files/FWO.Data/Modelling/ModellingAppServer.cs @@ -0,0 +1,122 @@ +using System.Text.Json.Serialization; +using Newtonsoft.Json; +using FWO.Basics; + +namespace FWO.Data.Modelling +{ + public class ModellingAppServer : ModellingNwObject + { + [JsonProperty("ip"), JsonPropertyName("ip")] + public string Ip { get; set; } = ""; + + [JsonProperty("ip_end"), JsonPropertyName("ip_end")] + public string IpEnd { get; set; } = ""; + + [JsonProperty("import_source"), JsonPropertyName("import_source")] + public string ImportSource { get; set; } = ""; + + [JsonProperty("custom_type"), JsonPropertyName("custom_type")] + public int? CustomType { get; set; } + + public bool InUse { get; set; } = true; + public bool HighestPrio { get; set; } = true; + public bool NotImplemented { get; set; } = false; + + + public override string Display() + { + return (IsDeleted ? "!" : "") + (InUse ? "" : "*") + DisplayBase.DisplayIpWithName(ToNetworkObject(this)); + } + + public override string DisplayHtml() + { + string tooltip = $"data-toggle=\"tooltip\" title=\"{TooltipText}\""; + return $"{base.DisplayHtml()}"; + } + + public override string DisplayWithIcon() + { + return $" " + DisplayHtml(); + } + + public override bool Sanitize() + { + bool shortened = base.Sanitize(); + Ip = Ip.SanitizeCidrMand(ref shortened); + IpEnd = IpEnd.SanitizeCidrMand(ref shortened); + ImportSource = ImportSource.SanitizeMand(ref shortened); + return shortened; + } + + public static NetworkObject ToNetworkObject(ModellingAppServer appServer) + { + return new NetworkObject() + { + Id = appServer.Id, + Number = appServer.Number, + Name = appServer.Name, + IP = appServer.Ip, + IpEnd = appServer.IpEnd + }; + } + + public ModellingAppServer() + { } + + public ModellingAppServer(ModellingAppServer appServer) : base(appServer) + { + Ip = appServer.Ip; + IpEnd = appServer.IpEnd; + ImportSource = appServer.ImportSource; + InUse = appServer.InUse; + CustomType = appServer.CustomType; + HighestPrio = appServer.HighestPrio; + NotImplemented = appServer.NotImplemented; + } + + public ModellingAppServer(NetworkObject nwObj) : base(nwObj) + { + Ip = nwObj.IP; + IpEnd = nwObj.IpEnd; + CustomType = 0; + } + + public override bool Equals(object? obj) + { + return obj switch + { + ModellingAppServer apps => Id == apps.Id && AppId == apps.AppId && Name == apps.Name && IsDeleted == apps.IsDeleted + && Ip == apps.Ip && IpEnd == apps.IpEnd && ImportSource == apps.ImportSource && InUse == apps.InUse && CustomType == apps.CustomType, + _ => base.Equals(obj), + }; + } + + public override int GetHashCode() + { + return Id.GetHashCode(); + } + } + + + public class ModellingAppServerWrapper + { + [JsonProperty("owner_network"), JsonPropertyName("owner_network")] + public ModellingAppServer Content { get; set; } = new(); + + public static ModellingAppServer[] Resolve(List wrappedList) + { + return Array.ConvertAll(wrappedList.ToArray(), wrapper => wrapper.Content); + } + + /// + /// Converts an array of ModellingAppServer objects to a list of ModellingAppServerWrapper objects + /// + /// + /// + public static List Wrap(ModellingAppServer[] appServers) + { + ModellingAppServerWrapper[] wrappedArray = Array.ConvertAll(appServers, appServer => new ModellingAppServerWrapper() { Content = appServer }); + return wrappedArray.ToList(); + } + } +} diff --git a/roles/lib/files/FWO.Data/Modelling/ModellingAppZone.cs b/roles/lib/files/FWO.Data/Modelling/ModellingAppZone.cs new file mode 100644 index 0000000000..49cc85bbfe --- /dev/null +++ b/roles/lib/files/FWO.Data/Modelling/ModellingAppZone.cs @@ -0,0 +1,29 @@ +namespace FWO.Data.Modelling +{ + public class ModellingAppZone : ModellingAppRole + { + public bool AlreadyExistsInDb { get; set; } = false; + public List AppServersNew = []; + public List AppServersRemoved = []; + public List AppServersUnchanged = []; + + public ModellingAppZone() + { } + + public ModellingAppZone(int? appId) + { + AppId = appId; + } + + public ModellingAppZone(ModellingAppZone appZone) : base(appZone) + { + AlreadyExistsInDb = appZone.AlreadyExistsInDb; + } + + public ModellingAppZone(ModellingAppRole appRole) : base(appRole) + { } + + public ModellingAppZone(NetworkObject nwObj, ModellingNamingConvention? namCon = null) : base(nwObj, namCon) + { } + } +} diff --git a/roles/lib/files/FWO.Data/Modelling/ModellingConnection.cs b/roles/lib/files/FWO.Data/Modelling/ModellingConnection.cs new file mode 100644 index 0000000000..537c9eb6cb --- /dev/null +++ b/roles/lib/files/FWO.Data/Modelling/ModellingConnection.cs @@ -0,0 +1,546 @@ +using FWO.Basics; +using System.Text.Json.Serialization; +using Newtonsoft.Json; + +namespace FWO.Data.Modelling +{ + public enum ConState + { + // Connections: + InterfaceRequested = 1, + InterfaceRejected = 2, + InterfaceDecommissioned = 3, + InterfaceNoPermission = 4, + + // Interfaces: + Requested = 11, + Rejected = 12, + Decommissioned = 13, + + EmptyAppRoles = 21, + DeletedObjects = 22, + EmptySvcGrps = 23, + DocumentationOnly = 24, + ForeignNonProdObjects = 25, + + VarianceChecked = 31, + NotImplemented = 32, + VarianceFound = 33 + } + + public enum InterfacePermissions + { + Public = 1, + Restricted = 2, + Private = 3 + } + + public class ModellingConnection + { + [JsonProperty("id"), JsonPropertyName("id")] + public int Id { get; set; } + + [JsonProperty("app_id"), JsonPropertyName("app_id")] + public int? AppId { get; set; } + + [JsonProperty("proposed_app_id"), JsonPropertyName("proposed_app_id")] + public int? ProposedAppId { get; set; } + + [JsonProperty("owner"), JsonPropertyName("owner")] + public FwoOwner App { get; set; } = new(); + + [JsonProperty("name"), JsonPropertyName("name")] + public string? Name { get; set; } = ""; + + [JsonProperty("reason"), JsonPropertyName("reason")] + public string? Reason { get; set; } = ""; + + [JsonProperty("is_interface"), JsonPropertyName("is_interface")] + public bool IsInterface { get; set; } = false; + + [JsonProperty("used_interface_id"), JsonPropertyName("used_interface_id")] + public long? UsedInterfaceId { get; set; } + + [JsonProperty("is_requested"), JsonPropertyName("is_requested")] + public bool IsRequested { get; set; } = false; + + [JsonProperty("is_published"), JsonPropertyName("is_published")] + public bool IsPublished { get; set; } = false; + + [JsonProperty("ticket_id"), JsonPropertyName("ticket_id")] + public long? TicketId { get; set; } + + [JsonProperty("common_service"), JsonPropertyName("common_service")] + public bool IsCommonService { get; set; } = false; + + [JsonProperty("creator"), JsonPropertyName("creator")] + public string? Creator { get; set; } + + [JsonProperty("creation_date"), JsonPropertyName("creation_date")] + public DateTime? CreationDate { get; set; } + + [JsonProperty("conn_prop"), JsonPropertyName("conn_prop")] + public string? Properties { get; set; } = ""; + + [JsonProperty("extra_params"), JsonPropertyName("extra_params")] + public string? ExtraParams { get; set; } = ""; + + [JsonProperty("services"), JsonPropertyName("services")] + public List Services { get; set; } = []; + + [JsonProperty("service_groups"), JsonPropertyName("service_groups")] + public List ServiceGroups { get; set; } = []; + + [JsonProperty("source_nwobjects"), JsonPropertyName("source_nwobjects")] + public List SourceAppServers { get; set; } = []; + + [JsonProperty("source_approles"), JsonPropertyName("source_approles")] + public List SourceAppRoles { get; set; } = []; + + [JsonProperty("destination_nwobjects"), JsonPropertyName("destination_nwobjects")] + public List DestinationAppServers { get; set; } = []; + + [JsonProperty("destination_approles"), JsonPropertyName("destination_approles")] + public List DestinationAppRoles { get; set; } = []; + + [JsonProperty("source_areas"), JsonPropertyName("source_areas")] + public List SourceAreas { get; set; } = []; + + [JsonProperty("destination_areas"), JsonPropertyName("destination_areas")] + public List DestinationAreas { get; set; } = []; + + [JsonProperty("source_other_groups"), JsonPropertyName("source_other_groups")] + public List SourceOtherGroups { get; set; } = []; + + [JsonProperty("destination_other_groups"), JsonPropertyName("destination_other_groups")] + public List DestinationOtherGroups { get; set; } = []; + + [JsonProperty("requested_on_fw"), JsonPropertyName("requested_on_fw")] + public bool RequestedOnFw { get; set; } = false; + + [JsonProperty("removed"), JsonPropertyName("removed")] + public bool Removed { get; set; } = false; + + [JsonProperty("removal_date"), JsonPropertyName("removal_date")] + public DateTime? RemovalDate { get; set; } + + [JsonProperty("interface_permission"), JsonPropertyName("interface_permission")] + public string InterfacePermission + { + get => interfacePermission; + set => interfacePermission = value ?? InterfacePermissions.Public.ToString(); + } + + [JsonProperty("permitted_owners"), JsonPropertyName("permitted_owners")] + public List PermittedOwnerWrappers + { + get => permittedOwnerWrappers; + set + { + permittedOwnerWrappers = value ?? []; + permittedOwners = [.. permittedOwnerWrappers.Select(w => w.Owner).Where(o => o != null)]; + } + } + + + public bool SrcFromInterface { get; set; } = false; + public bool DstFromInterface { get; set; } = false; + public bool InterfaceIsRequested { get; set; } = false; + public bool InterfaceIsRejected { get; set; } = false; + public bool InterfaceIsDecommissioned { get; set; } = false; + public bool InterfaceNoPermission { get; set; } = false; + + public int OrderNumber { get; set; } = 0; + public Dictionary? Props { get; set; } + public List ExtraConfigs + { + get => ExtraParams != null && ExtraParams != "" ? System.Text.Json.JsonSerializer.Deserialize>(ExtraParams) ?? throw new JsonException("ExtraParams could not be parsed.") : []; + set + { + if (value != null) + { + ExtraParams = System.Text.Json.JsonSerializer.Serialize(value) ?? throw new JsonException("value could not be parsed."); + } + } + } + public List ExtraConfigsFromInterface { get; set; } = []; + public bool ProdRuleFound { get; set; } = false; + private List permittedOwners = []; + public List PermittedOwners + { + get => permittedOwners; + set => permittedOwners = value ?? []; + } + + private string interfacePermission = InterfacePermissions.Public.ToString(); + private List permittedOwnerWrappers = []; + + + public ModellingConnection() + { } + + public ModellingConnection(ModellingConnection conn) : this(conn, true) + { + } + + public ModellingConnection(ModellingConnection conn, bool includeLists) + { + OrderNumber = conn.OrderNumber; + Id = conn.Id; + AppId = conn.AppId; + App = conn.App; + ProposedAppId = conn.ProposedAppId; + Name = conn.Name; + Reason = conn.Reason; + IsInterface = conn.IsInterface; + UsedInterfaceId = conn.UsedInterfaceId; + IsRequested = conn.IsRequested; + IsPublished = conn.IsPublished; + TicketId = conn.TicketId; + IsCommonService = conn.IsCommonService; + Creator = conn.Creator; + CreationDate = conn.CreationDate; + Properties = conn.Properties; + ExtraParams = conn.ExtraParams; + RequestedOnFw = conn.RequestedOnFw; + Removed = conn.Removed; + RemovalDate = conn.RemovalDate; + SrcFromInterface = conn.SrcFromInterface; + DstFromInterface = conn.DstFromInterface; + InterfaceIsRequested = conn.InterfaceIsRequested; + InterfaceIsRejected = conn.InterfaceIsRejected; + InterfaceIsDecommissioned = conn.InterfaceIsDecommissioned; + InterfaceNoPermission = conn.InterfaceNoPermission; + InterfacePermission = conn.InterfacePermission; + PermittedOwnerWrappers = conn.PermittedOwnerWrappers; + PermittedOwners = conn.PermittedOwners; + if (includeLists) + { + Services = [.. conn.Services]; + ServiceGroups = [.. conn.ServiceGroups]; + SourceAppServers = [.. conn.SourceAppServers]; + SourceAppRoles = [.. conn.SourceAppRoles]; + SourceAreas = [.. conn.SourceAreas]; + SourceOtherGroups = [.. conn.SourceOtherGroups]; + DestinationAppServers = [.. conn.DestinationAppServers]; + DestinationAppRoles = [.. conn.DestinationAppRoles]; + DestinationAreas = [.. conn.DestinationAreas]; + DestinationOtherGroups = [.. conn.DestinationOtherGroups]; + ExtraConfigsFromInterface = conn.ExtraConfigsFromInterface; + } + } + + public int CompareTo(ModellingConnection secondConnection) + { + int interfaceCompare = Compare(IsInterface, secondConnection.IsInterface); + if (interfaceCompare != 0) + { + return interfaceCompare; + } + int comSvcCompare = Compare(IsCommonService, secondConnection.IsCommonService); + if (comSvcCompare != 0) + { + return comSvcCompare; + } + int publishedCompare = Compare(IsPublished, secondConnection.IsPublished); + if (publishedCompare != 0) + { + return publishedCompare; + } + int rejectedCompare = -Compare(GetBoolProperty(ConState.Rejected.ToString()), secondConnection.GetBoolProperty(ConState.Rejected.ToString())); + if (rejectedCompare != 0) + { + return rejectedCompare; + } + int decommCompare = -Compare(GetBoolProperty(ConState.Decommissioned.ToString()), secondConnection.GetBoolProperty(ConState.Decommissioned.ToString())); + if (decommCompare != 0) + { + return decommCompare; + } + return Name?.CompareTo(secondConnection.Name) ?? -1; + } + + public string DisplayNameWithOwner(FwoOwner owner) + { + return Name + " (" + owner.ExtAppId + ":" + owner.Name + ")"; + } + + public bool SourceFilled() + { + return SourceAppServers.Count > 0 || SourceAppRoles.Count > 0 || SourceAreas.Count > 0 || SourceOtherGroups.Count > 0; + } + + public bool DestinationFilled() + { + return DestinationAppServers.Count > 0 || DestinationAppRoles.Count > 0 || DestinationAreas.Count > 0 || DestinationOtherGroups.Count > 0; + } + + public bool IsRelevantForVarianceAnalysis(long dummyAppRoleId, bool rolloutRemoved = false, bool withInterfaces = false) + { + return !((IsInterface && !(withInterfaces && IsPublished)) || + GetBoolProperty(ConState.InterfaceRequested.ToString()) || + GetBoolProperty(ConState.InterfaceRejected.ToString()) || + GetBoolProperty(ConState.InterfaceDecommissioned.ToString()) || + GetBoolProperty(ConState.InterfaceNoPermission.ToString()) || // or not ?? + EmptyAppRolesFound(dummyAppRoleId) || + DeletedObjectsFound(rolloutRemoved) || + EmptyServiceGroupsFound()); + } + + public void AddProperty(string key, string value = "") + { + InitProps(); + Props?.TryAdd(key, value); + Properties = System.Text.Json.JsonSerializer.Serialize(Props); + } + + public void RemoveProperty(string key) + { + InitProps(); + if (Props != null && Props.Count > 0 && Props.ContainsKey(key)) + { + Props.Remove(key); + } + Properties = System.Text.Json.JsonSerializer.Serialize(Props); + } + + public void UpdateProperty(string key, bool condition) + { + if (condition) + { + AddProperty(key); + } + else + { + RemoveProperty(key); + } + } + + public string GetStringProperty(string prop) + { + InitProps(); + if (Props != null && Props.Count > 0 && Props.TryGetValue(prop, out string? value)) + { + return value; + } + return ""; + } + + public bool GetBoolProperty(string prop) + { + InitProps(); + return Props?.ContainsKey(prop) ?? false; + } + + + public void SyncState(long dummyAppRoleId, bool rolloutRemoved = false) + { + if (IsInterface) + { + SyncInterface(); + } + else if (UsedInterfaceId != null) + { + SyncInterfaceUser(); + } + SyncMemberIssues(dummyAppRoleId, rolloutRemoved); + UpdateProperty(ConState.DocumentationOnly.ToString(), IsDocumentationOnly()); + } + + private void SyncInterface() + { + if (!GetBoolProperty(ConState.Rejected.ToString())) + { + UpdateProperty(ConState.Requested.ToString(), !IsPublished && IsRequested); + UpdateProperty(ConState.Decommissioned.ToString(), IsPublished && Removed); + } + } + + private void SyncInterfaceUser() + { + if (InterfaceIsRejected) + { + RemoveProperty(ConState.InterfaceRequested.ToString()); + AddProperty(ConState.InterfaceRejected.ToString()); + } + else + { + UpdateProperty(ConState.InterfaceRequested.ToString(), InterfaceIsRequested); + UpdateProperty(ConState.InterfaceDecommissioned.ToString(), InterfaceIsDecommissioned); + UpdateProperty(ConState.InterfaceNoPermission.ToString(), InterfaceNoPermission); + } + } + + private void SyncMemberIssues(long dummyAppRoleId, bool rolloutRemoved) + { + UpdateProperty(ConState.EmptyAppRoles.ToString(), EmptyAppRolesFound(dummyAppRoleId)); + UpdateProperty(ConState.DeletedObjects.ToString(), DeletedObjectsFound(rolloutRemoved)); + UpdateProperty(ConState.EmptySvcGrps.ToString(), EmptyServiceGroupsFound()); + } + + public void CleanUpVarianceResults() + { + RemoveProperty(ConState.VarianceChecked.ToString()); + RemoveProperty(ConState.VarianceFound.ToString()); + RemoveProperty(ConState.NotImplemented.ToString()); + } + + public bool EmptyAppRolesFound(long dummyAppRoleId) + { + return SourceAppRoles.Any(a => a.Content.Id != dummyAppRoleId && a.Content.AppServers.Count == 0) || + DestinationAppRoles.Any(a => a.Content.Id != dummyAppRoleId && a.Content.AppServers.Count == 0); + } + + public bool EmptyServiceGroupsFound() + => ServiceGroups.Any(_ => _.Content.Services.Count == 0); + + public bool IsDocumentationOnly() + => ExtraConfigs.Any(_ => _.ExtraConfigType.StartsWith(GlobalConst.kDoku_)); + + public bool IsNat() + => ExtraConfigs.Any(_ => _.ExtraConfigType.ToUpper() == GlobalConst.kNAT); + + public Dictionary GetSpecialUserObjectNames() + { + Dictionary userObjectNames = []; + foreach (var extraConfig in ExtraConfigs.Where(e => e.ExtraConfigType.ToLower().EndsWith(GlobalConst.k_user) + || e.ExtraConfigType.ToLower().EndsWith(GlobalConst.k_user2))) + { + userObjectNames.Add(extraConfig.ExtraConfigText.ToLower(), false); + } + return userObjectNames; + } + + public Dictionary GetUpdatableObjectNames() + { + Dictionary updatableObjectNames = []; + foreach (var extraConfig in ExtraConfigs.Where(e => e.ExtraConfigType.ToLower().StartsWith(GlobalConst.kUpdatable))) + { + updatableObjectNames.Add(extraConfig.ExtraConfigText.ToLower(), false); + } + return updatableObjectNames; + } + + private bool DeletedObjectsFound(bool rolloutRemoved = false) + { + if (rolloutRemoved) + { + return SourceAreas.Any(a => a.Content.IsDeleted) || + DestinationAreas.Any(a => a.Content.IsDeleted); + } + return SourceAreas.Any(a => a.Content.IsDeleted) || + DestinationAreas.Any(a => a.Content.IsDeleted) || + SourceAppRoles.Any(aR => aR.Content.AppServers.Any(a => a.Content.IsDeleted)) || + DestinationAppRoles.Any(aR => aR.Content.AppServers.Any(a => a.Content.IsDeleted)) || + SourceAppServers.Any(a => a.Content.IsDeleted) || + DestinationAppServers.Any(a => a.Content.IsDeleted); + } + + public Rule ToRule() + { + List froms = []; + foreach (var areaWrapper in SourceAreas) + { + froms.Add(new(new(), areaWrapper.Content.ToNetworkObjectGroup())); + } + foreach (var groupWrapper in SourceOtherGroups) + { + froms.Add(new(new(), groupWrapper.Content.ToNetworkObjectGroup())); + } + foreach (var appRoleWrapper in SourceAppRoles) + { + froms.Add(new(new(), appRoleWrapper.Content.ToNetworkObjectGroup())); + } + foreach (var appServerWrapper in SourceAppServers) + { + froms.Add(new(new(), ModellingAppServer.ToNetworkObject(appServerWrapper.Content))); + } + + List tos = []; + foreach (var areaWrapper in DestinationAreas) + { + tos.Add(new(new(), areaWrapper.Content.ToNetworkObjectGroup())); + } + foreach (var groupWrapper in DestinationOtherGroups) + { + tos.Add(new(new(), groupWrapper.Content.ToNetworkObjectGroup())); + } + foreach (var appRoleWrapper in DestinationAppRoles) + { + tos.Add(new(new(), appRoleWrapper.Content.ToNetworkObjectGroup())); + } + foreach (var appServerWrapper in DestinationAppServers) + { + tos.Add(new(new(), ModellingAppServer.ToNetworkObject(appServerWrapper.Content))); + } + + List services = []; + foreach (var svcGrp in ServiceGroups) + { + services.Add(new() { Content = svcGrp.Content.ToNetworkServiceGroup() }); + } + foreach (var svc in Services) + { + services.Add(new() { Content = ModellingService.ToNetworkService(svc.Content) }); + } + + return new Rule() + { + Name = Name, + Froms = [.. froms], + Tos = [.. tos], + Services = [.. services] + }; + } + + public bool Sanitize() + { + bool shortened = false; + Name = Name.SanitizeOpt(ref shortened); + Reason = Reason.SanitizeCommentOpt(ref shortened); + Creator = Creator.SanitizeOpt(ref shortened); + Properties = Properties.SanitizeKeyOpt(ref shortened); + ExtraParams = ExtraParams.SanitizeKeyOpt(ref shortened); + return shortened; + } + + private void InitProps() + { + Props ??= []; + if (Properties != null && Properties != "") + { + Props = System.Text.Json.JsonSerializer.Deserialize>(Properties) ?? []; + } + } + + private static int Compare(bool first, bool second) + { + if (first && !second) + { + return -1; + } + if (!first && second) + { + return 1; + } + return 0; + } + } + + public class ModellingConnectionWrapper + { + [JsonProperty("connection"), JsonPropertyName("connection")] + public ModellingConnection Content { get; set; } = new(); + + public static ModellingConnection[] Resolve(List wrappedList) + { + return Array.ConvertAll(wrappedList.ToArray(), wrapper => wrapper.Content); + } + } + + public class PermittedOwnerWrapper + { + [JsonProperty("owner"), JsonPropertyName("owner")] + public FwoOwner Owner { get; set; } = new(); + } +} diff --git a/roles/lib/files/FWO.Data/Modelling/ModellingDnDContainer.cs b/roles/lib/files/FWO.Data/Modelling/ModellingDnDContainer.cs new file mode 100644 index 0000000000..e22eb03155 --- /dev/null +++ b/roles/lib/files/FWO.Data/Modelling/ModellingDnDContainer.cs @@ -0,0 +1,24 @@ +namespace FWO.Data.Modelling +{ + public class ModellingDnDContainer + { + public List AppServerElements { get; set; } = []; + public List AppRoleElements { get; set; } = []; + public List AreaElements { get; set; } = []; + public List NwGroupElements { get; set; } = []; + public List SvcElements { get; set; } = []; + public List SvcGrpElements { get; set; } = []; + public ModellingConnection? ConnElement { get; set; } + + public void Clear() + { + AppServerElements = []; + AppRoleElements = []; + AreaElements = []; + NwGroupElements = []; + SvcElements = []; + SvcGrpElements = []; + ConnElement = null; + } + } +} diff --git a/roles/lib/files/FWO.Data/Modelling/ModellingExtraConfig.cs b/roles/lib/files/FWO.Data/Modelling/ModellingExtraConfig.cs new file mode 100644 index 0000000000..05e1a202ad --- /dev/null +++ b/roles/lib/files/FWO.Data/Modelling/ModellingExtraConfig.cs @@ -0,0 +1,42 @@ +using FWO.Basics; +using System.Text.Json.Serialization; +using Newtonsoft.Json; + +namespace FWO.Data.Modelling +{ + public class ModellingExtraConfig + { + [JsonProperty("id"), JsonPropertyName("id")] + public long Id { get; set; } + + [JsonProperty("extraConfigType"), JsonPropertyName("extraConfigType")] + public string ExtraConfigType { get; set; } = ""; + + [JsonProperty("extraConfigText"), JsonPropertyName("extraConfigText")] + public string ExtraConfigText { get; set; } = ""; + + public ModellingExtraConfig() + { } + + public ModellingExtraConfig(ModellingExtraConfig conf) + { + Id = conf.Id; + ExtraConfigType = conf.ExtraConfigType; + ExtraConfigText = conf.ExtraConfigText; + } + + public string Display() + { + return ExtraConfigType.StartsWith(GlobalConst.kDoku_) ? + $"{ExtraConfigType[GlobalConst.kDoku_.Length..]}" : $"{ExtraConfigType}: {ExtraConfigText}"; + } + + public bool Sanitize() + { + bool shortened = false; + ExtraConfigType = ExtraConfigType.SanitizeMand(ref shortened); + ExtraConfigText = ExtraConfigText.SanitizeMand(ref shortened); + return shortened; + } + } +} diff --git a/roles/lib/files/FWO.Data/Modelling/ModellingHistoryEntry.cs b/roles/lib/files/FWO.Data/Modelling/ModellingHistoryEntry.cs new file mode 100644 index 0000000000..36087cfac2 --- /dev/null +++ b/roles/lib/files/FWO.Data/Modelling/ModellingHistoryEntry.cs @@ -0,0 +1,36 @@ +using System.Text.Json.Serialization; +using FWO.Basics; +using Newtonsoft.Json; + +namespace FWO.Data.Modelling +{ + public class ModellingHistoryEntry + { + [JsonProperty("id"), JsonPropertyName("id")] + public long Id { get; set; } + + [JsonProperty("app_id"), JsonPropertyName("app_id")] + public int? AppId { get; set; } + + [JsonProperty("change_type"), JsonPropertyName("change_type")] + public int ChangeType { get; set; } + + [JsonProperty("object_type"), JsonPropertyName("object_type")] + public int ObjectType { get; set; } + + [JsonProperty("object_id"), JsonPropertyName("object_id")] + public long ObjectId { get; set; } + + [JsonProperty("change_text"), JsonPropertyName("change_text")] + public string ChangeText { get; set; } = ""; + + [JsonProperty("changer"), JsonPropertyName("changer")] + public string Changer { get; set; } = ""; + + [JsonProperty("change_time"), JsonPropertyName("change_time")] + public DateTime? ChangeTime { get; set; } + + [JsonProperty("change_source"), JsonPropertyName("change_source")] + public string ChangeSource { get; set; } = GlobalConst.kManual; + } +} diff --git a/roles/lib/files/FWO.Data/Modelling/ModellingManagedIdString.cs b/roles/lib/files/FWO.Data/Modelling/ModellingManagedIdString.cs new file mode 100644 index 0000000000..0d33cf34e0 --- /dev/null +++ b/roles/lib/files/FWO.Data/Modelling/ModellingManagedIdString.cs @@ -0,0 +1,212 @@ +namespace FWO.Data.Modelling +{ + public class ModellingManagedIdString + { + private string IdString = ""; + private const string separator = "-"; + + public ModellingNamingConvention NamingConvention { get; set; } = new(); + + + public ModellingManagedIdString() + { } + + public ModellingManagedIdString(string idstring) + { + IdString = idstring; + NamingConvention = new(); + } + + public ModellingManagedIdString(ModellingManagedIdString managedIdstring) + { + IdString = managedIdstring.IdString; + NamingConvention = managedIdstring.NamingConvention; + } + + public string Whole + { + get + { + return IdString; + } + set + { + IdString = value; + } + } + + public string FixedPart + { + get + { + return IdString.Length >= NamingConvention.FixedPartLength ? IdString.Substring(0, NamingConvention.FixedPartLength) : IdString; + } + set + { + string valueToInsert = value.Length > NamingConvention.FixedPartLength ? value.Substring(0, NamingConvention.FixedPartLength) : value; + valueToInsert = FillFixedIfNecessary(valueToInsert, "?"); + if (IdString.Length >= NamingConvention.FixedPartLength) + { + IdString = valueToInsert + IdString.Substring(NamingConvention.FixedPartLength); + } + else + { + IdString = valueToInsert; + } + } + } + + public string AppPart + { + get + { + return NamingConvention.UseAppPart ? (AppPartExisting() ? IdString.Substring(NamingConvention.FixedPartLength, AppPartEnd() - NamingConvention.FixedPartLength + 1) : "") : ""; + } + set + { + if (NamingConvention.UseAppPart) + { + IdString = FillFixedIfNecessary(IdString); + IdString = IdString.Substring(0, NamingConvention.FixedPartLength) + value + FreePart; + } + } + } + + public string CombinedFixPart + { + get + { + return FixedPart + (AppPart.EndsWith(separator) ? AppPart.Substring(0, AppPart.Length - 1) : AppPart); + } + set + { + IdString = value + FreePart; + } + } + + public string Separator + { + get + { + return NamingConvention.UseAppPart && AppPart.EndsWith(separator) ? separator : ""; + } + set + { + if (NamingConvention.UseAppPart) + { + AppPart += value; + } + } + } + + public string FreePart + { + get + { + if (NamingConvention.UseAppPart && AppPartExisting()) + { + int appPartEnd = AppPartEnd(); + int startIndex = appPartEnd + 1; + if (startIndex >= 0 && startIndex < IdString.Length) + { + return IdString.Substring(startIndex); + } + else + { + return string.Empty; + } + } + else + { + int startIndex = NamingConvention.FixedPartLength; + if (startIndex >= 0 && startIndex < IdString.Length) + { + return IdString.Substring(startIndex); + } + else + { + return string.Empty; + } + } + } + set + { + IdString = FillFixedIfNecessary(IdString); + int insertIndex = AppPartExisting() ? AppPartEnd() + 1 : NamingConvention.FixedPartLength; + if (insertIndex >= 0 && insertIndex <= IdString.Length) + { + IdString = IdString.Substring(0, insertIndex) + value; + } + else + { + IdString += value; + } + } + } + + public void SetAppPartFromExtId(string extAppId) + { + string zoneType = extAppId.StartsWith("APP") ? "0" : (extAppId.StartsWith("COM") ? "1" : "?"); + int idx = extAppId.IndexOf(separator); + string appNumber = idx > 0 ? extAppId.Substring(idx + 1, extAppId.Length - idx - 1) : ""; + AppPart = zoneType + appNumber + separator; + } + + public void SetAppPartFromExtIdAZ(string extAppId) + { + string zoneType = extAppId.StartsWith("APP") ? "0" : (extAppId.StartsWith("COM") ? "1" : "?"); + int idx = extAppId.IndexOf("-"); + string appNumber = idx > 0 ? extAppId.Substring(idx + 1, extAppId.Length - idx - 1) : ""; + AppPart = zoneType + appNumber; + IdString = $"{NamingConvention.AppZone}{zoneType}{appNumber}"; + } + + public void ConvertAreaToAppRoleFixedPart(string areaIdString) + { + FixedPart = ConvertAreaToAppRole(areaIdString, NamingConvention); + } + + public static string ConvertAreaToAppRole(string areaIdString, ModellingNamingConvention namingConvention) + { + if (areaIdString.Length >= namingConvention.FixedPartLength) + { + return areaIdString.Substring(0, namingConvention.FixedPartLength).Remove(0, namingConvention.NetworkAreaPattern.Length).Insert(0, namingConvention.AppRolePattern); + } + return areaIdString; + } + + public static string ConvertAppRoleToArea(string appRoleIdString, ModellingNamingConvention namingConvention) + { + int convLength = namingConvention.AppRolePattern.Length > namingConvention.FixedPartLength ? namingConvention.FixedPartLength : namingConvention.AppRolePattern.Length; + if (appRoleIdString.Length >= namingConvention.FixedPartLength) + { + return appRoleIdString.Substring(0, namingConvention.FixedPartLength).Remove(0, convLength).Insert(0, namingConvention.NetworkAreaPattern); + } + return ""; + } + + + private int AppPartEnd() + { + return IdString.IndexOf(separator); + } + + private bool AppPartExisting() + { + return AppPartEnd() > NamingConvention.FixedPartLength && IdString.Length >= AppPartEnd(); + } + + private string FillFixedIfNecessary(string idString, string filler = " ") + { + if (idString.Length < NamingConvention.FixedPartLength) + { + int positionsToFill = NamingConvention.FixedPartLength - idString.Length; + for (int i = 0; i < positionsToFill; i++) + { + idString += filler; + } + } + return idString; + } + } +} diff --git a/roles/lib/files/FWO.Data/Modelling/ModellingNamingConvention.cs b/roles/lib/files/FWO.Data/Modelling/ModellingNamingConvention.cs new file mode 100644 index 0000000000..658c27f9ed --- /dev/null +++ b/roles/lib/files/FWO.Data/Modelling/ModellingNamingConvention.cs @@ -0,0 +1,38 @@ +using System.Text.Json.Serialization; +using Newtonsoft.Json; + +namespace FWO.Data.Modelling +{ + public class ModellingNamingConvention + { + [JsonProperty("networkAreaRequired"), JsonPropertyName("networkAreaRequired")] + public bool NetworkAreaRequired { get; set; } = false; + + [JsonProperty("useAppPart"), JsonPropertyName("useAppPart")] + public bool UseAppPart { get; set; } = false; + + [JsonProperty("fixedPartLength"), JsonPropertyName("fixedPartLength")] + public int FixedPartLength { get; set; } + + [JsonProperty("freePartLength"), JsonPropertyName("freePartLength")] + public int FreePartLength { get; set; } + + [JsonProperty("networkAreaPattern"), JsonPropertyName("networkAreaPattern")] + public string NetworkAreaPattern { get; set; } = ""; + + [JsonProperty("appRolePattern"), JsonPropertyName("appRolePattern")] + public string AppRolePattern { get; set; } = ""; + + [JsonProperty("applicationZone"), JsonPropertyName("applicationZone")] + public string AppZone { get; set; } = ""; + + [JsonProperty("appServerPrefix"), JsonPropertyName("appServerPrefix")] + public string? AppServerPrefix { get; set; } = ""; + + [JsonProperty("networkPrefix"), JsonPropertyName("networkPrefix")] + public string? NetworkPrefix { get; set; } = ""; + + [JsonProperty("ipRangePrefix"), JsonPropertyName("ipRangePrefix")] + public string? IpRangePrefix { get; set; } = ""; + } +} diff --git a/roles/lib/files/FWO.Data/Modelling/ModellingNetworkArea.cs b/roles/lib/files/FWO.Data/Modelling/ModellingNetworkArea.cs new file mode 100644 index 0000000000..694067c23d --- /dev/null +++ b/roles/lib/files/FWO.Data/Modelling/ModellingNetworkArea.cs @@ -0,0 +1,121 @@ +using System.Text.Json.Serialization; +using Newtonsoft.Json; +using FWO.Basics; + +namespace FWO.Data.Modelling +{ + public class ModellingNetworkArea : ModellingNwGroup + { + [JsonProperty("ip_data"), JsonPropertyName("ip_data")] + public List IpData { get; set; } = []; + + public int MemberCount = 0; + + public ModellingNetworkArea() { } + + public ModellingNetworkArea(ModellingNwGroup nwgroup) : base(nwgroup) + { } + + public override NetworkObject ToNetworkObjectGroup(bool IdAsName = false, bool ListMembers = true) + { + Group[] objectGroups = NetworkDataWrapper.ResolveIpDataAsNetworkObjectGroup(IpData ?? []); + return new() + { + Id = Id, + Number = Number, + Name = IdAsName ? IdString : Name + " (" + IdString + ")" ?? IdString ?? "", + Type = new NetworkObjectType() { Name = ObjectType.Group }, + ObjectGroups = objectGroups, + MemberNames = ListMembers ? string.Join("|", Array.ConvertAll(objectGroups, o => o.Object?.Name)) : "..." + }; + } + + public int CompareTo(ModellingNetworkArea secondArea) + { + if (MemberCount == 0 && secondArea.MemberCount > 0) + { + return 1; + } + if (MemberCount > 0 && secondArea.MemberCount == 0) + { + return -1; + } + return Name?.CompareTo(secondArea.Name) ?? -1; + } + + public override bool Sanitize() + { + bool shortened = base.Sanitize(); + foreach (var ip in IpData) + { + shortened |= ip.Content.Sanitize(); + } + return shortened; + } + } + + public class ModellingNetworkAreaWrapper + { + [JsonProperty("nwgroup"), JsonPropertyName("nwgroup")] + public ModellingNetworkArea Content { get; set; } = new(); + + public static ModellingNetworkArea[] Resolve(List wrappedList) + { + return Array.ConvertAll(wrappedList.ToArray(), wrapper => wrapper.Content); + } + } + + + public class NetworkSubnet + { + [JsonProperty("id"), JsonPropertyName("id")] + public int Id { get; set; } = 0; + + [JsonProperty("name"), JsonPropertyName("name")] + public string Name { get; set; } = ""; + + // -> cidr + [JsonProperty("ip"), JsonPropertyName("ip")] + public string? Ip { get; set; } + + [JsonProperty("ip_end"), JsonPropertyName("ip_end")] + public string? IpEnd { get; set; } + + public static NetworkObject ToNetworkObject(NetworkSubnet subnet) + { + return new NetworkObject() + { + Id = subnet.Id, + Name = subnet.Name, + IP = subnet.Ip ?? "", + IpEnd = subnet.IpEnd ?? "" + }; + } + + public bool Sanitize() + { + bool shortened = false; + Name = Name.SanitizeMand(ref shortened); + Ip = Ip.SanitizeOpt(ref shortened); + IpEnd = IpEnd.SanitizeOpt(ref shortened); + return shortened; + } + } + + public class NetworkDataWrapper + { + [JsonProperty("owner_network"), JsonPropertyName("owner_network")] + public NetworkSubnet Content { get; set; } = new(); + + public static NetworkSubnet[] Resolve(List wrappedList) + { + return Array.ConvertAll(wrappedList.ToArray(), wrapper => wrapper.Content); + } + + public static Group[] ResolveIpDataAsNetworkObjectGroup(List wrappedList) + { + return Array.ConvertAll(wrappedList.ToArray(), wrapper => new Group + { Id = wrapper.Content.Id, Object = NetworkSubnet.ToNetworkObject(wrapper.Content) }); + } + } +} diff --git a/roles/lib/files/FWO.Data/Modelling/ModellingNwGroup.cs b/roles/lib/files/FWO.Data/Modelling/ModellingNwGroup.cs new file mode 100644 index 0000000000..37b9d523f7 --- /dev/null +++ b/roles/lib/files/FWO.Data/Modelling/ModellingNwGroup.cs @@ -0,0 +1,93 @@ +using System.Text.Json.Serialization; +using Newtonsoft.Json; +using FWO.Basics; + +namespace FWO.Data.Modelling +{ + public class ModellingNwGroup : ModellingNwObject + { + [JsonProperty("group_type"), JsonPropertyName("group_type")] + public int GroupType { get; set; } + + [JsonProperty("id_string"), JsonPropertyName("id_string")] + public string IdString + { + get { return ManagedIdString.Whole; } + set { ManagedIdString = new(value); } + } + public ModellingManagedIdString ManagedIdString { get; set; } = new(); + + + public ModellingNwGroup() + { } + + public ModellingNwGroup(ModellingNwGroup nwGroup) : base(nwGroup) + { + GroupType = nwGroup.GroupType; + IdString = nwGroup.IdString; + ManagedIdString.NamingConvention = nwGroup.ManagedIdString.NamingConvention; + } + + public ModellingNwGroup(NetworkObject nwObj, ModellingNamingConvention? namCon = null) : base(nwObj) + { + GroupType = MapObjectType(nwObj.Type.Name); + IdString = nwObj.Name; + ManagedIdString.NamingConvention = namCon ?? new(); + } + + public override string Display() + { + return base.Display() + " (" + IdString + ")"; + } + + public override string DisplayHtml() + { + return $"{base.DisplayHtml()}"; + } + + public override string DisplayWithIcon() + { + return $" " + DisplayHtml(); + } + + public virtual NetworkObject ToNetworkObjectGroup(bool IdAsName = false, bool ListMembers = true) + { + return new() + { + Id = Id, + Name = IdAsName ? IdString : Name + " (" + IdString + ")", + Number = Number, + Type = new NetworkObjectType() { Name = ObjectType.Group } + }; + } + + public override bool Sanitize() + { + bool shortened = base.Sanitize(); + ManagedIdString.FreePart = ManagedIdString.FreePart.SanitizeMand(ref shortened); + return shortened; + } + + protected static int MapObjectType(string nwObjType) + { + return nwObjType switch + { + ObjectType.Group => (int)ModellingTypes.ModObjectType.AppRole, + ObjectType.Network => (int)ModellingTypes.ModObjectType.Network, + ObjectType.Host or ObjectType.IPRange => (int)ModellingTypes.ModObjectType.AppServer, + _ => (int)ModellingTypes.ModObjectType.AppRole, + }; + } + } + + public class ModellingNwGroupWrapper + { + [JsonProperty("nwgroup"), JsonPropertyName("nwgroup")] + public virtual ModellingNwGroup Content { get; set; } = new(); + + public static ModellingNwGroup[] Resolve(List wrappedList) + { + return Array.ConvertAll(wrappedList.ToArray(), wrapper => wrapper.Content); + } + } +} diff --git a/roles/lib/files/FWO.Data/Modelling/ModellingNwObject.cs b/roles/lib/files/FWO.Data/Modelling/ModellingNwObject.cs new file mode 100644 index 0000000000..c76c75eb5c --- /dev/null +++ b/roles/lib/files/FWO.Data/Modelling/ModellingNwObject.cs @@ -0,0 +1,41 @@ +using System.Text.Json.Serialization; +using Newtonsoft.Json; + +namespace FWO.Data.Modelling +{ + public class ModellingNwObject : ModellingObject + { + [JsonProperty("id"), JsonPropertyName("id")] + public long Id { get; set; } + + [JsonProperty("is_deleted"), JsonPropertyName("is_deleted")] + public bool IsDeleted { get; set; } + + + public ModellingNwObject() + { } + + public ModellingNwObject(ModellingNwObject nwObject) : base(nwObject) + { + Id = nwObject.Id; + IsDeleted = nwObject.IsDeleted; + } + + public ModellingNwObject(NetworkObject nwObj) : base(nwObj) + { + Id = nwObj.Id; + IsDeleted = false; // Todo: !nwObj.Active ? + } + + public override string Display() + { + return (IsDeleted ? "!" : "") + Name; + } + + public override string DisplayHtml() + { + string tooltip = $"data-toggle=\"tooltip\" title=\"{TooltipText}\""; + return $"{(IsDeleted ? "" : "")}{base.DisplayHtml()}{(IsDeleted ? "" : "")}"; + } + } +} diff --git a/roles/lib/files/FWO.Data/Modelling/ModellingObject.cs b/roles/lib/files/FWO.Data/Modelling/ModellingObject.cs new file mode 100644 index 0000000000..f85d6e91a8 --- /dev/null +++ b/roles/lib/files/FWO.Data/Modelling/ModellingObject.cs @@ -0,0 +1,74 @@ +using System.Text.Json.Serialization; +using Newtonsoft.Json; +using FWO.Basics; + +namespace FWO.Data.Modelling +{ + public class ModellingObject + { + [JsonProperty("name"), JsonPropertyName("name")] + public string Name { get; set; } = ""; + + [JsonProperty("app_id"), JsonPropertyName("app_id")] + public int? AppId { get; set; } + + public string TooltipText = ""; + public long Number; + + + public ModellingObject() + { } + + public ModellingObject(ModellingObject modellingObject) + { + Name = modellingObject.Name; + AppId = modellingObject.AppId; + TooltipText = modellingObject.TooltipText; + Number = modellingObject.Number; + } + + public ModellingObject(NetworkObject nwObj) + { + Name = nwObj.Name; + Number = nwObj.Number; + } + + public virtual string Display() + { + return Name; + } + + public virtual string DisplayHtml() + { + return $"{Display()}"; + } + + public virtual string DisplayProblematicWithIcon() + { + return $" " + DisplayHtml() + $""; + } + + public virtual string DisplayProblematicWithIcon(bool displayGrey, bool decomm) + { + string interfClass = decomm ? "text-danger" : "text-secondary"; + return $"{DisplayProblematicWithIcon()}"; + } + + public virtual string DisplayWithIcon(bool displayGrey, bool decomm) + { + string interfClass = decomm ? "text-danger" : "text-secondary"; + return $"{DisplayWithIcon()}"; + } + public virtual string DisplayWithIcon() + { + return $" " + DisplayHtml(); + } + + public virtual bool Sanitize() + { + bool shortened = false; + Name = Name.SanitizeMand(ref shortened); + return shortened; + } + } +} diff --git a/roles/lib/files/FWO.Data/Modelling/ModellingService.cs b/roles/lib/files/FWO.Data/Modelling/ModellingService.cs new file mode 100644 index 0000000000..61cb46714e --- /dev/null +++ b/roles/lib/files/FWO.Data/Modelling/ModellingService.cs @@ -0,0 +1,73 @@ +using System.Text.Json.Serialization; +using Newtonsoft.Json; +using FWO.Basics; + +namespace FWO.Data.Modelling +{ + public class ModellingService : ModellingSvcObject + { + [JsonProperty("port"), JsonPropertyName("port")] + public int? Port { get; set; } + + [JsonProperty("port_end"), JsonPropertyName("port_end")] + public int? PortEnd { get; set; } + + [JsonProperty("proto_id"), JsonPropertyName("proto_id")] + public int? ProtoId { get; set; } + + [JsonProperty("protocol"), JsonPropertyName("protocol")] + public NetworkProtocol? Protocol { get; set; } = new(); + + + public ModellingService() + { } + + public ModellingService(ModellingService service) : base(service) + { + Port = service.Port; + PortEnd = service.PortEnd; + ProtoId = service.ProtoId; + Protocol = service.Protocol; + } + + public override string Display() + { + return DisplayBase.DisplayService(ToNetworkService(this), false, Name).ToString(); + } + + public override string DisplayWithIcon() + { + return $" " + DisplayHtml(); + } + + public static NetworkService ToNetworkService(ModellingService service) + { + return new NetworkService() + { + Id = service.Id, + Number = service.Number, + Name = service?.Name ?? "", + DestinationPort = service?.Port, + DestinationPortEnd = service?.PortEnd, + ProtoId = service?.ProtoId, + Protocol = service?.Protocol ?? new NetworkProtocol() + }; + } + } + + public class ModellingServiceWrapper + { + [JsonProperty("service"), JsonPropertyName("service")] + public ModellingService Content { get; set; } = new(); + + public static ModellingService[] Resolve(List wrappedList) + { + return Array.ConvertAll(wrappedList.ToArray(), wrapper => wrapper.Content); + } + + public static NetworkService[] ResolveAsNetworkServices(List wrappedList) + { + return Array.ConvertAll(wrappedList.ToArray(), wrapper => ModellingService.ToNetworkService(wrapper.Content)); + } + } +} diff --git a/roles/lib/files/FWO.Data/Modelling/ModellingServiceGroup.cs b/roles/lib/files/FWO.Data/Modelling/ModellingServiceGroup.cs new file mode 100644 index 0000000000..97e6c9723a --- /dev/null +++ b/roles/lib/files/FWO.Data/Modelling/ModellingServiceGroup.cs @@ -0,0 +1,88 @@ +using System.Text.Json.Serialization; +using Newtonsoft.Json; +using FWO.Basics; + +namespace FWO.Data.Modelling +{ + public class ModellingServiceGroup : ModellingSvcObject + { + [JsonProperty("comment"), JsonPropertyName("comment")] + public string? Comment { get; set; } + + [JsonProperty("creator"), JsonPropertyName("creator")] + public string? Creator { get; set; } + + [JsonProperty("creation_date"), JsonPropertyName("creation_date")] + public DateTime? CreationDate { get; set; } + + [JsonProperty("services"), JsonPropertyName("services")] + public List Services { get; set; } = []; + + + public ModellingServiceGroup() + { } + + public ModellingServiceGroup(ModellingServiceGroup svcGroup) : base(svcGroup) + { + Comment = svcGroup.Comment; + Creator = svcGroup.Creator; + CreationDate = svcGroup.CreationDate; + Services = svcGroup.Services; + } + + public override string DisplayWithIcon() + { + return $" " + DisplayHtml(); + } + + public override string DisplayProblematicWithIcon() + { + return $" " + DisplayHtml() + $""; + } + + public NetworkService ToNetworkServiceGroup() + { + Group[] serviceGroups = ModellingServiceGroupWrapper.ResolveAsNetworkServiceGroup(Services ?? []); + GroupFlat[] serviceGroupFlats = ModellingServiceGroupWrapper.ResolveAsNetworkServiceGroupFlat(Services ?? []); + return new() + { + Id = Id, + Name = Name ?? "", + Comment = Comment ?? "", + Type = new NetworkServiceType() { Name = ServiceType.Group }, + ServiceGroups = serviceGroups, + ServiceGroupFlats = serviceGroupFlats, + MemberNames = string.Join("|", Array.ConvertAll(serviceGroups, o => o.Object?.Name)) + }; + } + + public override bool Sanitize() + { + bool shortened = base.Sanitize(); + Comment = Comment.SanitizeCommentOpt(ref shortened); + Creator = Creator.SanitizeOpt(ref shortened); + return shortened; + } + } + + public class ModellingServiceGroupWrapper + { + [JsonProperty("service_group"), JsonPropertyName("service_group")] + public ModellingServiceGroup Content { get; set; } = new(); + + public static ModellingServiceGroup[] Resolve(List wrappedList) + { + return Array.ConvertAll(wrappedList.ToArray(), wrapper => wrapper.Content); + } + + public static Group[] ResolveAsNetworkServiceGroup(List wrappedList) + { + return Array.ConvertAll(wrappedList.ToArray(), wrapper => new Group { Id = wrapper.Content.Id, Object = ModellingService.ToNetworkService(wrapper.Content) }); + } + + public static GroupFlat[] ResolveAsNetworkServiceGroupFlat(List wrappedList) + { + return Array.ConvertAll(wrappedList.ToArray(), wrapper => new GroupFlat { Id = wrapper.Content.Id, Object = ModellingService.ToNetworkService(wrapper.Content) }); + } + } +} diff --git a/roles/lib/files/FWO.Data/Modelling/ModellingSvcObject.cs b/roles/lib/files/FWO.Data/Modelling/ModellingSvcObject.cs new file mode 100644 index 0000000000..7ac3e575c7 --- /dev/null +++ b/roles/lib/files/FWO.Data/Modelling/ModellingSvcObject.cs @@ -0,0 +1,29 @@ +using System.Text.Json.Serialization; +using Newtonsoft.Json; + +namespace FWO.Data.Modelling +{ + public class ModellingSvcObject : ModellingObject + { + [JsonProperty("id"), JsonPropertyName("id")] + public int Id { get; set; } + + [JsonProperty("is_global"), JsonPropertyName("is_global")] + public bool IsGlobal { get; set; } = false; + + + public ModellingSvcObject() + { } + + public ModellingSvcObject(ModellingSvcObject svcObj) : base(svcObj) + { + Id = svcObj.Id; + IsGlobal = svcObj.IsGlobal; + } + + public override string DisplayHtml() + { + return $"{(IsGlobal ? "" : "")}{Display()}{(IsGlobal ? "" : "")}"; + } + } +} diff --git a/roles/lib/files/FWO.Data/Modelling/ModellingTypes.cs b/roles/lib/files/FWO.Data/Modelling/ModellingTypes.cs new file mode 100644 index 0000000000..c5ff225fae --- /dev/null +++ b/roles/lib/files/FWO.Data/Modelling/ModellingTypes.cs @@ -0,0 +1,79 @@ +namespace FWO.Data.Modelling +{ + public static class ModellingTypes + { + public enum ConnectionField + { + Source = 1, + Destination = 2 + } + + public enum ChangeType + { + Insert = 1, + Update = 2, + Delete = 3, + Assign = 4, + Unassign = 5, + MarkDeleted = 6, + Reactivate = 7, + Replace = 8, + InitRequests = 9, + Request = 10, + Implement = 11, + Reject = 12, + Decommission = 13, + Recertify = 14, + Publish = 15 + } + + public enum ModObjectType + { + Connection = 1, + CommunicationProfile = 2, + + AppServer = 10, + Network = 11, + + AppRole = 20, + AppZone = 21, + NetworkZone = 22, + NetworkArea = 23, + + Service = 30, + ServiceGroup = 31, + } + + public static bool IsNwGroup(this ModObjectType objectType) + { + switch (objectType) + { + case ModObjectType.AppRole: + case ModObjectType.AppZone: + case ModObjectType.NetworkZone: + case ModObjectType.NetworkArea: + return true; + default: + return false; + } + } + + public static bool IsNwObject(this ModObjectType objectType) + { + switch (objectType) + { + case ModObjectType.AppServer: + case ModObjectType.Network: + return true; + default: + return false; + } + } + } + + public class AppServerType + { + public int Id { get; set; } = 0; + public string Name { get; set; } = ""; + } +} diff --git a/roles/lib/files/FWO.Data/Modelling/ModellingVarianceResult.cs b/roles/lib/files/FWO.Data/Modelling/ModellingVarianceResult.cs new file mode 100644 index 0000000000..d367407fc8 --- /dev/null +++ b/roles/lib/files/FWO.Data/Modelling/ModellingVarianceResult.cs @@ -0,0 +1,116 @@ +using FWO.Data.Report; + +namespace FWO.Data.Modelling +{ + public class ModProdDifference + { + public ModellingConnection ModelledConnection { get; set; } = new(); + public List ImplementedRules { get; set; } = []; + } + + public class AppRoleStats + { + public int ModelledAppRolesCount { get; set; } = 0; + public int AppRolesOk { get; set; } = 0; + public int AppRolesMissingCount { get; set; } = 0; + public int AppRolesDifferenceCount { get; set; } = 0; + } + + public class ModellingVarianceResult + { + public List ConnsNotImplemented { get; set; } = []; + public List RuleDifferences { get; set; } = []; + public List OkRules { get; set; } = []; + public Dictionary> UnModelledRules { get; set; } = []; + public Dictionary> DeletedModelsRules { get; set; } = []; + public int ModelledCount { get; set; } = 0; + public List Managements { get; set; } = []; + + public Dictionary> MissingAppRoles { get; set; } = []; + public Dictionary> DifferingAppRoles { get; set; } = []; + public AppRoleStats AppRoleStats { get; set; } = new(); + public Dictionary> DeviceRules { get; set; } = []; + + + public List UnModelledRulesReport { get; set; } = []; + + public void AddDifference(ModellingConnection conn, Rule rule) + { + ModProdDifference? diff = RuleDifferences.FirstOrDefault(d => d.ModelledConnection.Id == conn.Id); + if (diff == null) + { + RuleDifferences.Add(new() { ModelledConnection = conn, ImplementedRules = [rule] }); + } + else + { + diff.ImplementedRules.Add(rule); + } + } + + public void AddOkRule(ModellingConnection conn, Rule rule) + { + ModProdDifference? diff = OkRules.FirstOrDefault(d => d.ModelledConnection.Id == conn.Id); + if (diff == null) + { + OkRules.Add(new() { ModelledConnection = conn, ImplementedRules = [rule] }); + } + else + { + diff.ImplementedRules.Add(rule); + } + } + + public List GetAllOkRules() + { + List allOkRules = []; + foreach (var rulesPerConn in OkRules.Select(x => x.ImplementedRules)) + { + allOkRules.AddRange(rulesPerConn); + } + return allOkRules; + } + + public List UnmodelledRuleDataToReport() + { + return MgtDataToReport(UnModelledRules); + } + + public List DeletedConnRuleDataToReport() + { + return MgtDataToReport(DeletedModelsRules); + } + + private List MgtDataToReport(Dictionary> rulesToReport) + { + List managementReports = []; + foreach (var mgtId in rulesToReport.Keys.Where(m => rulesToReport[m].Count > 0)) + { + Management? mgt = Managements.FirstOrDefault(m => m.Id == mgtId); + if (mgt != null) + { + ManagementReport managementReport = new() { Id = mgtId, Name = mgt.Name ?? "" }; + List deviceReports = []; + foreach (var dev in mgt.Devices) + { + DeviceReport devReport = new() { Id = dev.Id, Name = dev.Name }; + devReport.SetRulesForDev(FilterRulesForDev(rulesToReport[mgtId], mgtId, dev)); + deviceReports.Add(devReport); + } + managementReport.Devices = [.. deviceReports]; + managementReports.Add(managementReport); + } + } + return managementReports; + } + + public List FilterRulesForDev(List rulesToReport, int mgtId, Device device) + { + DeviceReport? devReport = DeviceRules[mgtId]?.FirstOrDefault(d => d.Id == device.Id); + if (devReport != null) + { + return [.. rulesToReport.Where(devReport.IsLinked)]; + } + return []; + } + } +} diff --git a/roles/lib/files/FWO.Data/Modelling/RuleRecognitionOption.cs b/roles/lib/files/FWO.Data/Modelling/RuleRecognitionOption.cs new file mode 100644 index 0000000000..6fb00389b1 --- /dev/null +++ b/roles/lib/files/FWO.Data/Modelling/RuleRecognitionOption.cs @@ -0,0 +1,38 @@ +using Newtonsoft.Json; +using System.Text.Json.Serialization; + +namespace FWO.Data.Modelling +{ + public class RuleRecognitionOption + { + [JsonProperty("nwRegardIp"), JsonPropertyName("nwRegardIp")] + public bool NwRegardIp { get; set; } = true; + + [JsonProperty("nwRegardName"), JsonPropertyName("nwRegardName")] + public bool NwRegardName { get; set; } = false; + + [JsonProperty("nwRegardGroupName"), JsonPropertyName("nwRegardGroupName")] + public bool NwRegardGroupName { get; set; } = false; + + [JsonProperty("nwResolveGroup"), JsonPropertyName("nwResolveGroup")] + public bool NwResolveGroup { get; set; } = false; + + [JsonProperty("nwSeparateGroupAnalysis"), JsonPropertyName("nwSeparateGroupAnalysis")] + public bool NwSeparateGroupAnalysis { get; set; } = true; + + [JsonProperty("svcRegardPortAndProt"), JsonPropertyName("svcRegardPortAndProt")] + public bool SvcRegardPortAndProt { get; set; } = true; + + [JsonProperty("svcRegardName"), JsonPropertyName("svcRegardName")] + public bool SvcRegardName { get; set; } = false; + + [JsonProperty("svcRegardGroupName"), JsonPropertyName("svcRegardGroupName")] + public bool SvcRegardGroupName { get; set; } = false; + + [JsonProperty("svcResolveGroup"), JsonPropertyName("svcResolveGroup")] + public bool SvcResolveGroup { get; set; } = true; + + [JsonProperty("svcSplitPortRanges"), JsonPropertyName("svcSplitPortRanges")] + public bool SvcSplitPortRanges { get; set; } = false; + } +} diff --git a/roles/lib/files/FWO.Data/ModellingEmailRecipientSelection.cs b/roles/lib/files/FWO.Data/ModellingEmailRecipientSelection.cs new file mode 100644 index 0000000000..4830dd498d --- /dev/null +++ b/roles/lib/files/FWO.Data/ModellingEmailRecipientSelection.cs @@ -0,0 +1,258 @@ +using FWO.Basics; +using FWO.Logging; +using System.Text.Json; +using System.Text.Json.Serialization; + +namespace FWO.Data +{ + /// + /// Represents the selectable recipient options for modelling request/decommission emails. + /// + public class ModellingEmailRecipientSelection + { + [JsonPropertyName("none")] + public bool None { get; set; } = true; + + [JsonPropertyName("other_addresses")] + public bool OtherAddresses { get; set; } = false; + + [JsonPropertyName("ensure_at_least_one_notification")] + public bool EnsureAtLeastOneNotification { get; set; } = false; + + [JsonPropertyName("owner_responsible_type_ids")] + public List OwnerResponsibleTypeIds { get; set; } = []; + + /// + /// Parses a config value into a modelling recipient selection. + /// Supports new JSON values and legacy enum names. + /// + public static ModellingEmailRecipientSelection Parse(string? configValue, IEnumerable? activeOwnerResponsibleTypeIds = null) + { + string rawValue = configValue?.Trim() ?? ""; + if (string.IsNullOrWhiteSpace(rawValue)) + { + return CreateDefault().Sanitize(activeOwnerResponsibleTypeIds); + } + + ModellingEmailRecipientSelection parsedSelection = TryParseValue(rawValue, activeOwnerResponsibleTypeIds) + ?? CreateDefault(); + return parsedSelection.Sanitize(activeOwnerResponsibleTypeIds); + } + + /// + /// Converts the selection into a persisted config value. + /// + public string ToConfigValue(IEnumerable? activeOwnerResponsibleTypeIds = null) + { + ModellingEmailRecipientSelection sanitized = Sanitize(activeOwnerResponsibleTypeIds); + if (!sanitized.HasAnyRecipientOption()) + { + return nameof(EmailRecipientOption.None); + } + return JsonSerializer.Serialize(sanitized); + } + + /// + /// Returns true when at least one effective recipient option is selected. + /// + public bool HasAnyRecipientOption() + { + return !None && (OtherAddresses || OwnerResponsibleTypeIds.Count > 0); + } + + /// + /// Returns selected owner responsible types in fallback order. + /// Highest sort order is tried first. + /// + public IEnumerable GetOwnerResponsibleTypeFallbackOrder(IEnumerable? ownerResponsibleTypes) + { + HashSet selectedTypeIds = OwnerResponsibleTypeIds.ToHashSet(); + if (selectedTypeIds.Count == 0) + { + return []; + } + + if (ownerResponsibleTypes != null) + { + List orderedTypeIds = ownerResponsibleTypes + .Where(type => type.Active && selectedTypeIds.Contains(type.Id)) + .OrderByDescending(type => type.SortOrder) + .ThenByDescending(type => type.Id) + .Select(type => type.Id) + .ToList(); + + if (orderedTypeIds.Count > 0) + { + return orderedTypeIds; + } + } + + return selectedTypeIds.OrderByDescending(typeId => typeId).ToList(); + } + + private ModellingEmailRecipientSelection Sanitize(IEnumerable? activeOwnerResponsibleTypeIds) + { + ModellingEmailRecipientSelection sanitized = new() + { + None = None, + OtherAddresses = OtherAddresses, + EnsureAtLeastOneNotification = EnsureAtLeastOneNotification, + OwnerResponsibleTypeIds = OwnerResponsibleTypeIds + .Where(id => id > 0) + .Distinct() + .ToList() + }; + + if (activeOwnerResponsibleTypeIds != null) + { + HashSet activeTypeIds = activeOwnerResponsibleTypeIds.ToHashSet(); + sanitized.OwnerResponsibleTypeIds = sanitized.OwnerResponsibleTypeIds + .Where(activeTypeIds.Contains) + .ToList(); + } + + if (sanitized.None) + { + sanitized.OtherAddresses = false; + sanitized.EnsureAtLeastOneNotification = false; + sanitized.OwnerResponsibleTypeIds = []; + } + else if (!sanitized.OtherAddresses && sanitized.OwnerResponsibleTypeIds.Count == 0) + { + sanitized.None = true; + } + + return sanitized; + } + + private static ModellingEmailRecipientSelection? TryParseValue(string rawValue, IEnumerable? activeOwnerResponsibleTypeIds) + { + if (LooksLikeJson(rawValue) && TryParseJson(rawValue, out ModellingEmailRecipientSelection jsonSelection)) + { + return jsonSelection; + } + + if (TryParseLegacy(rawValue, activeOwnerResponsibleTypeIds, out ModellingEmailRecipientSelection legacySelection)) + { + return legacySelection; + } + + return null; + } + + private static bool TryParseJson(string rawValue, out ModellingEmailRecipientSelection selection) + { + selection = CreateDefault(); + try + { + ModellingEmailRecipientSelection? parsedSelection = JsonSerializer.Deserialize(rawValue); + if (parsedSelection != null) + { + parsedSelection.OwnerResponsibleTypeIds ??= []; + selection = parsedSelection; + return true; + } + } + catch + { + Log.WriteWarning( + "Parse ModellingEmailRecipientSelection", + $"Could not parse recipient selection JSON value \"{rawValue}\". Falling back to legacy parsing."); + } + + return false; + } + + private static bool TryParseLegacy( + string rawValue, + IEnumerable? activeOwnerResponsibleTypeIds, + out ModellingEmailRecipientSelection selection) + { + List activeTypeIds = ResolveActiveOwnerResponsibleTypeIds(activeOwnerResponsibleTypeIds); + + switch (rawValue) + { + case nameof(EmailRecipientOption.None): + case "0": + selection = CreateNoneSelection(); + return true; + case nameof(EmailRecipientOption.OtherAddresses): + selection = CreateOtherAddressSelection(); + return true; + case nameof(EmailRecipientOption.OwnerMainResponsible): + selection = CreateOwnerResponsibleTypeSelection(GlobalConst.kOwnerResponsibleTypeMain); + return true; + case nameof(EmailRecipientOption.OwnerGroupOnly): + selection = CreateOwnerResponsibleTypeSelection(GlobalConst.kOwnerResponsibleTypeSupporting); + return true; + case nameof(EmailRecipientOption.AllOwnerResponsibles): + selection = CreateOwnerResponsibleTypeSelection(activeTypeIds); + return true; + case nameof(EmailRecipientOption.FallbackToMainResponsibleIfOwnerGroupEmpty): + selection = CreateFallbackSelection(); + return true; + default: + selection = CreateDefault(); + return false; + } + } + + private static bool LooksLikeJson(string rawValue) + { + return rawValue.StartsWith('{'); + } + + private static List ResolveActiveOwnerResponsibleTypeIds(IEnumerable? activeOwnerResponsibleTypeIds) + { + if (activeOwnerResponsibleTypeIds != null) + { + return activeOwnerResponsibleTypeIds.ToList(); + } + + return [GlobalConst.kOwnerResponsibleTypeMain, GlobalConst.kOwnerResponsibleTypeSupporting, GlobalConst.kOwnerResponsibleTypeOptionalEscalation]; + } + + private static ModellingEmailRecipientSelection CreateNoneSelection() + { + return CreateDefault(); + } + + private static ModellingEmailRecipientSelection CreateOtherAddressSelection() + { + return new ModellingEmailRecipientSelection + { + None = false, + OtherAddresses = true + }; + } + + private static ModellingEmailRecipientSelection CreateOwnerResponsibleTypeSelection(params int[] ownerResponsibleTypeIds) + { + return CreateOwnerResponsibleTypeSelection((IEnumerable)ownerResponsibleTypeIds); + } + + private static ModellingEmailRecipientSelection CreateOwnerResponsibleTypeSelection(IEnumerable ownerResponsibleTypeIds) + { + return new ModellingEmailRecipientSelection + { + None = false, + OwnerResponsibleTypeIds = ownerResponsibleTypeIds.ToList() + }; + } + + private static ModellingEmailRecipientSelection CreateFallbackSelection() + { + return new ModellingEmailRecipientSelection + { + None = false, + EnsureAtLeastOneNotification = true, + OwnerResponsibleTypeIds = [GlobalConst.kOwnerResponsibleTypeSupporting, GlobalConst.kOwnerResponsibleTypeMain] + }; + } + + private static ModellingEmailRecipientSelection CreateDefault() + { + return new ModellingEmailRecipientSelection(); + } + } +} diff --git a/roles/lib/files/FWO.Api.Client/Data/NatData.cs b/roles/lib/files/FWO.Data/NatData.cs similarity index 89% rename from roles/lib/files/FWO.Api.Client/Data/NatData.cs rename to roles/lib/files/FWO.Data/NatData.cs index b7c760cb2e..547e6e0abf 100644 --- a/roles/lib/files/FWO.Api.Client/Data/NatData.cs +++ b/roles/lib/files/FWO.Data/NatData.cs @@ -1,7 +1,7 @@ -using System.Text.Json.Serialization; +using System.Text.Json.Serialization; using Newtonsoft.Json; -namespace FWO.Api.Data +namespace FWO.Data { public class NatData { @@ -12,7 +12,7 @@ public class NatData public string TranslatedService { get; set; } = ""; [JsonProperty("rule_services"), JsonPropertyName("rule_services")] - public ServiceWrapper[] TranslatedServices { get; set; } = new ServiceWrapper[]{}; + public ServiceWrapper[] TranslatedServices { get; set; } = []; [JsonProperty("rule_src_neg"), JsonPropertyName("rule_src_neg")] public bool TranslatedSourceNegated { get; set; } @@ -21,7 +21,7 @@ public class NatData public string TranslatedSource { get; set; } = ""; [JsonProperty("rule_froms"), JsonPropertyName("rule_froms")] - public NetworkLocation[] TranslatedFroms { get; set; } = new NetworkLocation[]{}; + public NetworkLocation[] TranslatedFroms { get; set; } = new NetworkLocation[] { }; [JsonProperty("rule_dst_neg"), JsonPropertyName("rule_dst_neg")] public bool TranslatedDestinationNegated { get; set; } @@ -30,6 +30,6 @@ public class NatData public string TranslatedDestination { get; set; } = ""; [JsonProperty("rule_tos"), JsonPropertyName("rule_tos")] - public NetworkLocation[] TranslatedTos { get; set; } = new NetworkLocation[]{}; + public NetworkLocation[] TranslatedTos { get; set; } = new NetworkLocation[] { }; } } diff --git a/roles/lib/files/FWO.Data/NetworkLocation.cs b/roles/lib/files/FWO.Data/NetworkLocation.cs new file mode 100644 index 0000000000..55f21c5036 --- /dev/null +++ b/roles/lib/files/FWO.Data/NetworkLocation.cs @@ -0,0 +1,45 @@ +using System.Text.Json.Serialization; +using Newtonsoft.Json; + +namespace FWO.Data +{ + public class NetworkLocation : IComparable + { + [JsonProperty("object"), JsonPropertyName("object")] + public NetworkObject Object { get; set; } + + [JsonProperty("usr"), JsonPropertyName("usr")] + public NetworkUser User { get; set; } + + public NetworkLocation(NetworkUser user, NetworkObject? networkObject) + { + Object = networkObject ?? new(); + User = user; + } + + int IComparable.CompareTo(object? obj) + { + if (obj is NetworkLocation) + { + NetworkLocation secondNetworkLocation = (obj as NetworkLocation)!; + if (this.User?.Name != null && secondNetworkLocation.User?.Name != null + && this.User.Name.CompareTo(secondNetworkLocation.User.Name) != 0) + { + return this.User!.Name.CompareTo(secondNetworkLocation.User!.Name); + } + if (this.Object != null && secondNetworkLocation.Object != null) + { + return this.Object.Name.CompareTo(secondNetworkLocation.Object.Name); + } + else + { + return 0; + } + } + else + { + throw new ArgumentException("Uncomparable"); + } + } + } +} diff --git a/roles/lib/files/FWO.Data/NetworkObject.cs b/roles/lib/files/FWO.Data/NetworkObject.cs new file mode 100644 index 0000000000..83530910ec --- /dev/null +++ b/roles/lib/files/FWO.Data/NetworkObject.cs @@ -0,0 +1,94 @@ +using NetTools; +using Newtonsoft.Json; +using System.Text.Json.Serialization; + +namespace FWO.Data +{ + public class NetworkObject + { + [JsonProperty("obj_id"), JsonPropertyName("obj_id")] + public long Id { get; set; } + + [JsonProperty("obj_name"), JsonPropertyName("obj_name")] + public string Name { get; set; } = ""; + + [JsonProperty("obj_ip"), JsonPropertyName("obj_ip")] + public string IP { get; set; } = ""; + + [JsonProperty("obj_ip_end"), JsonPropertyName("obj_ip_end")] + public string IpEnd { get; set; } = ""; + + [JsonProperty("obj_uid"), JsonPropertyName("obj_uid")] + public string Uid { get; set; } = ""; + + [JsonProperty("zone"), JsonPropertyName("zone")] + public NetworkZone? Zone { get; set; } + + [JsonProperty("active"), JsonPropertyName("active")] + public bool Active { get; set; } + + [JsonProperty("obj_create"), JsonPropertyName("obj_create")] + public int Create { get; set; } + + [JsonProperty("obj_create_time"), JsonPropertyName("obj_create_time")] + public TimeWrapper CreateTime { get; set; } = new(); + + [JsonProperty("obj_last_seen"), JsonPropertyName("obj_last_seen")] + public int LastSeen { get; set; } + + [JsonProperty("type"), JsonPropertyName("type")] + public NetworkObjectType Type { get; set; } = new(); + + [JsonProperty("obj_color"), JsonPropertyName("obj_color")] + public Color? Color { get; set; } + + [JsonProperty("obj_comment"), JsonPropertyName("obj_comment")] + public string Comment { get; set; } = ""; + + [JsonProperty("obj_member_names"), JsonPropertyName("obj_member_names")] + public string MemberNames { get; set; } = ""; + + [JsonProperty("obj_member_refs"), JsonPropertyName("obj_member_refs")] + public string MemberRefs { get; set; } = ""; + + [JsonProperty("objgrps"), JsonPropertyName("objgrps")] + public Group[] ObjectGroups { get; set; } = []; + + [JsonProperty("objgrp_flats"), JsonPropertyName("objgrp_flats")] + public GroupFlat[] ObjectGroupFlats { get; set; } = []; + + public long Number; + public bool Highlighted = false; + public bool IsSurplus = false; + + /// + /// List of IP ranges that overlap with matched owner ranges. + /// Used for IP-based owner mapping. + /// + [JsonProperty("overlapping_ranges", NullValueHandling = NullValueHandling.Ignore)] + [JsonPropertyName("overlapping_ranges")] + [System.Text.Json.Serialization.JsonIgnore(Condition = System.Text.Json.Serialization.JsonIgnoreCondition.WhenWritingNull)] + public List? OverlappingRanges { get; set; } + + + public override bool Equals(object? obj) + { + return obj switch + { + NetworkObject nobj => Id == nobj.Id, + _ => base.Equals(obj), + }; + } + + public override int GetHashCode() + { + return Id.GetHashCode(); + } + + public bool IsAnyObject() + { + return IP == "0.0.0.0/32" && IpEnd == "255.255.255.255/32" || + IP == "::/128" && IpEnd == "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff/128"; + } + } +} diff --git a/roles/lib/files/FWO.Data/NetworkObjectType.cs b/roles/lib/files/FWO.Data/NetworkObjectType.cs new file mode 100644 index 0000000000..954599ba1b --- /dev/null +++ b/roles/lib/files/FWO.Data/NetworkObjectType.cs @@ -0,0 +1,14 @@ +using System.Text.Json.Serialization; +using Newtonsoft.Json; + +namespace FWO.Data +{ + public class NetworkObjectType + { + [JsonProperty("id"), JsonPropertyName("id")] + public int Id { get; set; } = 0; + + [JsonProperty("name"), JsonPropertyName("name")] + public string Name { get; set; } = ""; + } +} diff --git a/roles/lib/files/FWO.Data/NetworkObjectWrapper.cs b/roles/lib/files/FWO.Data/NetworkObjectWrapper.cs new file mode 100644 index 0000000000..47bdcdd545 --- /dev/null +++ b/roles/lib/files/FWO.Data/NetworkObjectWrapper.cs @@ -0,0 +1,11 @@ +using System.Text.Json.Serialization; +using Newtonsoft.Json; + +namespace FWO.Data +{ + public class NetworkObjectWrapper + { + [JsonProperty("object"), JsonPropertyName("object")] + public NetworkObject Content { get; set; } = new NetworkObject() { }; + } +} diff --git a/roles/lib/files/FWO.Data/NetworkProtocol.cs b/roles/lib/files/FWO.Data/NetworkProtocol.cs new file mode 100644 index 0000000000..fb228ffbdf --- /dev/null +++ b/roles/lib/files/FWO.Data/NetworkProtocol.cs @@ -0,0 +1,29 @@ +using System.Text.Json.Serialization; +using Newtonsoft.Json; + +namespace FWO.Data +{ + public class NetworkProtocol + { + [JsonProperty("id"), JsonPropertyName("id")] + public int Id { get; set; } + + [JsonProperty("name"), JsonPropertyName("name")] + public string Name { get; set; } = ""; + + + public NetworkProtocol() + { } + + public NetworkProtocol(IpProtocol i) + { + Id = i.Id; + Name = i.Name; + } + + public bool HasPorts() + { + return Id == 6 || Id == 17; + } + } +} diff --git a/roles/lib/files/FWO.Data/NetworkService.cs b/roles/lib/files/FWO.Data/NetworkService.cs new file mode 100644 index 0000000000..a4b767498f --- /dev/null +++ b/roles/lib/files/FWO.Data/NetworkService.cs @@ -0,0 +1,132 @@ +using System.Text.Json.Serialization; +using Newtonsoft.Json; + +namespace FWO.Data +{ + public class NetworkService + { + [JsonProperty("svc_id"), JsonPropertyName("svc_id")] + public long Id { get; set; } + + [JsonProperty("svc_name"), JsonPropertyName("svc_name")] + public string Name { get; set; } = ""; + + [JsonProperty("svc_uid"), JsonPropertyName("svc_uid")] + public string Uid { get; set; } = ""; + + [JsonProperty("svc_port"), JsonPropertyName("svc_port")] + public int? DestinationPort { get; set; } + + [JsonProperty("svc_port_end"), JsonPropertyName("svc_port_end")] + public int? DestinationPortEnd { get; set; } + + [JsonProperty("svc_source_port"), JsonPropertyName("svc_source_port")] + public int? SourcePort { get; set; } + + [JsonProperty("svc_source_port_end"), JsonPropertyName("svc_source_port_end")] + public int? SourcePortEnd { get; set; } + + [JsonProperty("svc_code"), JsonPropertyName("svc_code")] + public string Code { get; set; } = ""; + + [JsonProperty("svc_timeout"), JsonPropertyName("svc_timeout")] + public int? Timeout { get; set; } + + [JsonProperty("svc_typ_id"), JsonPropertyName("svc_typ_id")] + public int? TypeId { get; set; } + + [JsonProperty("active"), JsonPropertyName("active")] + public bool Active { get; set; } + + [JsonProperty("svc_create"), JsonPropertyName("svc_create")] + public int Create { get; set; } + + [JsonProperty("svc_create_time"), JsonPropertyName("svc_create_time")] + public TimeWrapper CreateTime { get; set; } = new(); + + [JsonProperty("svc_last_seen"), JsonPropertyName("svc_last_seen")] + public int LastSeen { get; set; } + + [JsonProperty("service_type"), JsonPropertyName("service_type")] + public NetworkServiceType Type { get; set; } = new(); + + [JsonProperty("svc_comment"), JsonPropertyName("svc_comment")] + public string Comment { get; set; } = ""; + + [JsonProperty("svc_color_id"), JsonPropertyName("svc_color_id")] + public int? ColorId { get; set; } + + [JsonProperty("stm_color"), JsonPropertyName("stm_color")] + public Color? Color { get; set; } + + [JsonProperty("ip_proto_id"), JsonPropertyName("ip_proto_id")] + public int? ProtoId { get; set; } + + [JsonProperty("protocol_name"), JsonPropertyName("protocol_name")] + public NetworkProtocol? Protocol { get; set; } + + [JsonProperty("svc_member_names"), JsonPropertyName("svc_member_names")] + public string MemberNames { get; set; } = ""; + + [JsonProperty("svc_member_refs"), JsonPropertyName("svc_member_refs")] + public string MemberRefs { get; set; } = ""; + + [JsonProperty("svcgrps"), JsonPropertyName("svcgrps")] + public Group[] ServiceGroups { get; set; } = []; + + [JsonProperty("svcgrp_flats"), JsonPropertyName("svcgrp_flats")] + public GroupFlat[] ServiceGroupFlats { get; set; } = []; + + [JsonProperty("svc_rpcnr"), JsonPropertyName("svc_rpcnr")] + public long? RpcNumber { get; set; } + + public long Number; + public bool IsSurplus = false; + + public NetworkService() + { } + + public NetworkService(NetworkService networkService) + { + Id = networkService.Id; + Name = networkService.Name; + Uid = networkService.Uid; + DestinationPort = networkService.DestinationPort; + DestinationPortEnd = networkService.DestinationPortEnd; + SourcePort = networkService.SourcePort; + SourcePortEnd = networkService.SourcePortEnd; + Code = networkService.Code; + Timeout = networkService.Timeout; + TypeId = networkService.TypeId; + Active = networkService.Active; + Create = networkService.Create; + CreateTime = networkService.CreateTime; + LastSeen = networkService.LastSeen; + Type = networkService.Type; + Comment = networkService.Comment; + ColorId = networkService.ColorId; + ProtoId = networkService.ProtoId; + Protocol = networkService.Protocol; + MemberNames = networkService.MemberNames; + MemberRefs = networkService.MemberRefs; + ServiceGroups = networkService.ServiceGroups; + ServiceGroupFlats = networkService.ServiceGroupFlats; + Number = networkService.Number; + IsSurplus = networkService.IsSurplus; + } + + public override bool Equals(object? obj) + { + return obj switch + { + NetworkService nsrv => Id == nsrv.Id, + _ => base.Equals(obj), + }; + } + + public override int GetHashCode() + { + return Id.GetHashCode(); + } + } +} diff --git a/roles/lib/files/FWO.Data/NetworkServiceType.cs b/roles/lib/files/FWO.Data/NetworkServiceType.cs new file mode 100644 index 0000000000..3ef968b5f6 --- /dev/null +++ b/roles/lib/files/FWO.Data/NetworkServiceType.cs @@ -0,0 +1,11 @@ +using System.Text.Json.Serialization; +using Newtonsoft.Json; + +namespace FWO.Data +{ + public class NetworkServiceType + { + [JsonProperty("name"), JsonPropertyName("name")] + public string Name { get; set; } = ""; + } +} diff --git a/roles/lib/files/FWO.Data/NetworkUser.cs b/roles/lib/files/FWO.Data/NetworkUser.cs new file mode 100644 index 0000000000..513347e5bf --- /dev/null +++ b/roles/lib/files/FWO.Data/NetworkUser.cs @@ -0,0 +1,79 @@ +using System.Text.Json.Serialization; +using Newtonsoft.Json; + +namespace FWO.Data +{ + public class NetworkUser + { + [JsonProperty("user_id"), JsonPropertyName("user_id")] + public long Id { get; set; } + + [JsonProperty("user_uid"), JsonPropertyName("user_uid")] + public string Uid { get; set; } = ""; + + [JsonProperty("user_name"), JsonPropertyName("user_name")] + public string Name { get; set; } = ""; + + [JsonProperty("user_comment"), JsonPropertyName("user_comment")] + public string Comment { get; set; } = ""; + + [JsonProperty("user_lastname"), JsonPropertyName("user_lastname")] + public string LastName { get; set; } = ""; + + [JsonProperty("user_firstname"), JsonPropertyName("user_firstname")] + public string FirstName { get; set; } = ""; + + [JsonProperty("usr_typ_id"), JsonPropertyName("usr_typ_id")] + public int TypeId { get; set; } + + [JsonProperty("type"), JsonPropertyName("type")] + public NetworkUserType Type { get; set; } = new(); + + [JsonProperty("user_create"), JsonPropertyName("user_create")] + public int Create { get; set; } + + [JsonProperty("user_create_time"), JsonPropertyName("user_create_time")] + public TimeWrapper CreateTime { get; set; } = new(); + + [JsonProperty("user_last_seen"), JsonPropertyName("user_last_seen")] + public int LastSeen { get; set; } + + [JsonProperty("user_member_names"), JsonPropertyName("user_member_names")] + public string MemberNames { get; set; } = ""; + + [JsonProperty("user_member_refs"), JsonPropertyName("user_member_refs")] + public string MemberRefs { get; set; } = ""; + + [JsonProperty("usergrps"), JsonPropertyName("usergrps")] + public Group[] UserGroups { get; set; } = new Group[] { }; + + [JsonProperty("usergrp_flats"), JsonPropertyName("usergrp_flats")] + public GroupFlat[] UserGroupFlats { get; set; } = new GroupFlat[] { }; + + public override bool Equals(object? obj) + { + return obj switch + { + NetworkUser user => Id == user.Id, + _ => base.Equals(obj), + }; + } + + public override int GetHashCode() + { + return Id.GetHashCode(); + } + + public string MemberNamesAsHtml() + { + if (MemberNames != null && MemberNames.Contains("|")) + { + return $"{string.Join("
                      ", MemberNames.Split('|'))}"; + } + else + { + return $"{MemberNames}"; + } + } + } +} diff --git a/roles/lib/files/FWO.Api.Client/Data/NetworkUserType.cs b/roles/lib/files/FWO.Data/NetworkUserType.cs similarity index 75% rename from roles/lib/files/FWO.Api.Client/Data/NetworkUserType.cs rename to roles/lib/files/FWO.Data/NetworkUserType.cs index a85842a75e..2d15ea3669 100644 --- a/roles/lib/files/FWO.Api.Client/Data/NetworkUserType.cs +++ b/roles/lib/files/FWO.Data/NetworkUserType.cs @@ -1,7 +1,7 @@ -using System.Text.Json.Serialization; +using System.Text.Json.Serialization; using Newtonsoft.Json; -namespace FWO.Api.Data +namespace FWO.Data { public class NetworkUserType { diff --git a/roles/lib/files/FWO.Api.Client/Data/NetworkZone.cs b/roles/lib/files/FWO.Data/NetworkZone.cs similarity index 93% rename from roles/lib/files/FWO.Api.Client/Data/NetworkZone.cs rename to roles/lib/files/FWO.Data/NetworkZone.cs index aeb0c16b10..4a231cfd28 100644 --- a/roles/lib/files/FWO.Api.Client/Data/NetworkZone.cs +++ b/roles/lib/files/FWO.Data/NetworkZone.cs @@ -3,7 +3,7 @@ using NetTools; using Newtonsoft.Json; -namespace FWO.Api.Data +namespace FWO.Data { public class NetworkZone { diff --git a/roles/lib/files/FWO.Data/NormalizedConfig.cs b/roles/lib/files/FWO.Data/NormalizedConfig.cs new file mode 100644 index 0000000000..b8282a03a8 --- /dev/null +++ b/roles/lib/files/FWO.Data/NormalizedConfig.cs @@ -0,0 +1,44 @@ +using System.Text.Json.Serialization; +using Newtonsoft.Json; + +namespace FWO.Data +{ + public class NormalizedConfig + { + [JsonProperty("ConfigFormat"), JsonPropertyName("ConfigFormat")] + public string ConfigFormat { get; set; } = ""; + + [JsonProperty("action"), JsonPropertyName("action")] + public string Action { get; set; } = ""; + + [JsonProperty("network_objects"), JsonPropertyName("network_objects")] + public Dictionary NetworkObjects { get; set; } = []; + + [JsonProperty("service_objects"), JsonPropertyName("service_objects")] + public Dictionary ServiceObjects { get; set; } = []; + + [JsonProperty("users"), JsonPropertyName("users")] + public Dictionary Users { get; set; } = []; + + [JsonProperty("zone_objects"), JsonPropertyName("zone_objects")] + public Dictionary ZoneObjects { get; set; } = []; + + [JsonProperty("time_objects"), JsonPropertyName("time_objects")] + public Dictionary TimeObjects { get; set; } = []; + + [JsonProperty("rulebases"), JsonPropertyName("rulebases")] + public NormalizedRulebase[] Rulebases { get; set; } = []; + + [JsonProperty("gateways"), JsonPropertyName("gateways")] + public NormalizedGateway[] Gateways { get; set; } = []; + + public static string FormatDatetimeZ(DateTime dateTime, bool convertToUtc = false) + { + if (convertToUtc) + { + dateTime = dateTime.ToUniversalTime(); + } + return dateTime.ToString("yyyy-MM-ddTHH:mm:sszzz"); + } + } +} diff --git a/roles/lib/files/FWO.Data/NormalizedGateway.cs b/roles/lib/files/FWO.Data/NormalizedGateway.cs new file mode 100644 index 0000000000..f779a99a64 --- /dev/null +++ b/roles/lib/files/FWO.Data/NormalizedGateway.cs @@ -0,0 +1,55 @@ +using System.Text.Json.Serialization; +using Newtonsoft.Json; + +namespace FWO.Data +{ + public class NormalizedGateway + { + [JsonProperty("Uid"), JsonPropertyName("Uid")] + public string? Uid { get; set; } + + [JsonProperty("Name"), JsonPropertyName("Name")] + public string? Name { get; set; } + + [JsonProperty("Routing"), JsonPropertyName("Routing")] + public object[] Routing { get; set; } = []; + + [JsonProperty("Interfaces"), JsonPropertyName("Interfaces")] + public object[] Interfaces { get; set; } = []; + + [JsonProperty("RulebaseLinks"), JsonPropertyName("RulebaseLinks")] + public NormalizedRulebaseLink[] RulebaseLinks { get; set; } = []; + + [JsonProperty("GlobalPolicyUid"), JsonPropertyName("GlobalPolicyUid")] + public string? GlobalPolicyUid { get; set; } + + [JsonProperty("EnforcedPolicyUids"), JsonPropertyName("EnforcedPolicyUids")] + public string[]? EnforcedPolicyUids { get; set; } + + [JsonProperty("EnforcedNatPolicyUids"), JsonPropertyName("EnforcedNatPolicyUids")] + public string[]? EnforcedNatPolicyUids { get; set; } + + [JsonProperty("ImportDisabled"), JsonPropertyName("ImportDisabled")] + public bool ImportDisabled { get; set; } + + [JsonProperty("ShowInUI"), JsonPropertyName("ShowInUI")] + public bool ShowInUI { get; set; } + + public static NormalizedGateway FromDevice(Device device) + { + return new NormalizedGateway + { + Uid = device.Uid, + Name = device.Name, + Routing = [], // TODO: implement (see #3645) + Interfaces = [], // TODO: implement (see #3645) + RulebaseLinks = [.. device.RulebaseLinks.Select(NormalizedRulebaseLink.FromRulebaseLink)], + GlobalPolicyUid = device.GlobalRulebaseUid, + EnforcedPolicyUids = [], // TODO: implement (see #3645) + EnforcedNatPolicyUids = [], // TODO: implement - property not available in Device (see #3645) + ImportDisabled = device.ImportDisabled, + ShowInUI = !device.HideInUi + }; + } + } +} diff --git a/roles/lib/files/FWO.Data/NormalizedNetworkObject.cs b/roles/lib/files/FWO.Data/NormalizedNetworkObject.cs new file mode 100644 index 0000000000..c0fe2318dd --- /dev/null +++ b/roles/lib/files/FWO.Data/NormalizedNetworkObject.cs @@ -0,0 +1,56 @@ +using System.Text.Json.Serialization; +using Newtonsoft.Json; + +namespace FWO.Data +{ + public class NormalizedNetworkObject + { + [JsonProperty("obj_uid"), JsonPropertyName("obj_uid")] + public string ObjUid { get; set; } = ""; + + [JsonProperty("obj_name"), JsonPropertyName("obj_name")] + public string ObjName { get; set; } = ""; + + [JsonProperty("obj_ip"), JsonPropertyName("obj_ip")] + public string? ObjIp { get; set; } + + [JsonProperty("obj_ip_end"), JsonPropertyName("obj_ip_end")] + public string? ObjIpEnd { get; set; } + + [JsonProperty("obj_color"), JsonPropertyName("obj_color")] + public string ObjColor { get; set; } = ""; + + [JsonProperty("obj_typ"), JsonPropertyName("obj_typ")] + public string ObjType { get; set; } = ""; + + [JsonProperty("obj_member_refs"), JsonPropertyName("obj_member_refs")] + public string? ObjMemberRefs { get; set; } + + [JsonProperty("obj_member_names"), JsonPropertyName("obj_member_names")] + public string? ObjMemberNames { get; set; } + + [JsonProperty("obj_comment"), JsonPropertyName("obj_comment")] + public string? ObjComment { get; set; } + + /// + /// Creates a NormalizedNetworkObject from a NetworkObject. + /// + /// The NetworkObject to normalize. + /// A normalized NetworkObject. + public static NormalizedNetworkObject FromNetworkObject(NetworkObject networkObject) + { + return new NormalizedNetworkObject + { + ObjUid = networkObject.Uid, + ObjName = networkObject.Name, + ObjIp = networkObject.IP, + ObjIpEnd = networkObject.IpEnd, + ObjColor = networkObject.Color?.Name ?? "", + ObjType = networkObject.Type.Name, + ObjMemberRefs = networkObject.MemberRefs, + ObjMemberNames = networkObject.MemberNames, + ObjComment = networkObject.Comment + }; + } + } +} diff --git a/roles/lib/files/FWO.Data/NormalizedRule.cs b/roles/lib/files/FWO.Data/NormalizedRule.cs new file mode 100644 index 0000000000..ec2885b2d9 --- /dev/null +++ b/roles/lib/files/FWO.Data/NormalizedRule.cs @@ -0,0 +1,134 @@ +using System.Text.Json.Serialization; +using Newtonsoft.Json; + +namespace FWO.Data +{ + public class NormalizedRule + { + [JsonProperty("rule_num"), JsonPropertyName("rule_num")] + public int RuleNum { get; set; } + + [JsonProperty("rule_num_numeric"), JsonPropertyName("rule_num_numeric")] + public double RuleNumNumeric { get; set; } + + [JsonProperty("rule_disabled"), JsonPropertyName("rule_disabled")] + public bool RuleDisabled { get; set; } + + [JsonProperty("rule_src_neg"), JsonPropertyName("rule_src_neg")] + public bool RuleSrcNeg { get; set; } + + [JsonProperty("rule_src"), JsonPropertyName("rule_src")] + public string RuleSrc { get; set; } = ""; + + [JsonProperty("rule_src_refs"), JsonPropertyName("rule_src_refs")] + public string RuleSrcRefs { get; set; } = ""; + + [JsonProperty("rule_dst_neg"), JsonPropertyName("rule_dst_neg")] + public bool RuleDstNeg { get; set; } + + [JsonProperty("rule_dst"), JsonPropertyName("rule_dst")] + public string RuleDst { get; set; } = ""; + + [JsonProperty("rule_dst_refs"), JsonPropertyName("rule_dst_refs")] + public string RuleDstRefs { get; set; } = ""; + + [JsonProperty("rule_svc_neg"), JsonPropertyName("rule_svc_neg")] + public bool RuleSvcNeg { get; set; } + + [JsonProperty("rule_svc"), JsonPropertyName("rule_svc")] + public string RuleSvc { get; set; } = ""; + + [JsonProperty("rule_svc_refs"), JsonPropertyName("rule_svc_refs")] + public string RuleSvcRefs { get; set; } = ""; + + [JsonProperty("rule_action"), JsonPropertyName("rule_action")] + public string RuleAction { get; set; } = ""; + + [JsonProperty("rule_track"), JsonPropertyName("rule_track")] + public string RuleTrack { get; set; } = ""; + + [JsonProperty("rule_installon"), JsonPropertyName("rule_installon")] + public string? RuleInstallOn { get; set; } + + [JsonProperty("rule_time"), JsonPropertyName("rule_time")] + public string? RuleTime { get; set; } + + [JsonProperty("rule_name"), JsonPropertyName("rule_name")] + public string? RuleName { get; set; } + + [JsonProperty("rule_uid"), JsonPropertyName("rule_uid")] + public string? RuleUid { get; set; } + + [JsonProperty("rule_custom_fields"), JsonPropertyName("rule_custom_fields")] + public string? RuleCustomFields { get; set; } + + [JsonProperty("rule_implied"), JsonPropertyName("rule_implied")] + public bool RuleImplied { get; set; } + + [JsonProperty("rule_type"), JsonPropertyName("rule_type")] + public string RuleType { get; set; } = ""; + + [JsonProperty("rule_last_change_admin"), JsonPropertyName("rule_last_change_admin")] + public string? RuleLastChangeAdmin { get; set; } + + [JsonProperty("parent_rule_uid"), JsonPropertyName("parent_rule_uid")] + public string? ParentRuleUid { get; set; } + + [JsonProperty("last_hit"), JsonPropertyName("last_hit")] + public string? LastHit { get; set; } + + [JsonProperty("rule_comment"), JsonPropertyName("rule_comment")] + public string? RuleComment { get; set; } + + [JsonProperty("rule_src_zone"), JsonPropertyName("rule_src_zone")] + public string? RuleSrcZone { get; set; } + + [JsonProperty("rule_dst_zone"), JsonPropertyName("rule_dst_zone")] + public string? RuleDstZone { get; set; } + + [JsonProperty("rule_head_text"), JsonPropertyName("rule_head_text")] + public string? RuleHeadText { get; set; } + + /// + /// Creates a NormalizedRule from a Rule. + /// + /// The Rule to normalize. + /// A normalized Rule. + public static NormalizedRule FromRule(Rule rule) + { + DateTime? lastHit = rule.Metadata.LastHit; + + return new NormalizedRule + { + RuleNum = rule.RuleOrderNumber, + RuleNumNumeric = rule.OrderNumber, + RuleDisabled = rule.Disabled, + RuleSrcNeg = rule.SourceNegated, + RuleSrc = rule.Source, + RuleSrcRefs = rule.SourceRefs, + RuleDstNeg = rule.DestinationNegated, + RuleDst = rule.Destination, + RuleDstRefs = rule.DestinationRefs, + RuleSvcNeg = rule.ServiceNegated, + RuleSvc = rule.Service, + RuleSvcRefs = rule.ServiceRefs, + RuleAction = rule.Action, + RuleTrack = rule.Track, + RuleInstallOn = rule.InstallOn, + RuleTime = rule.Time, + RuleName = rule.Name, + RuleUid = rule.Uid, + RuleCustomFields = rule.CustomFields, + RuleImplied = rule.Implied, + RuleType = rule.NatRule ? "nat" : "access", + RuleLastChangeAdmin = rule.LastChangeAdmin?.Name, + ParentRuleUid = rule.ParentRule?.Uid, + LastHit = lastHit.HasValue ? NormalizedConfig.FormatDatetimeZ(lastHit.Value, convertToUtc: true) : null, + RuleComment = rule.Comment, + RuleSrcZone = rule.RuleFromZones?.Length > 0 ? string.Join("|", rule.RuleFromZones.Select(z => z.Content.Name).Order()) : null, + RuleDstZone = rule.RuleToZones?.Length > 0 ? string.Join("|", rule.RuleToZones.Select(z => z.Content.Name).Order()) : null, + RuleHeadText = rule.SectionHeader + }; + } + } +} diff --git a/roles/lib/files/FWO.Data/NormalizedRulebase.cs b/roles/lib/files/FWO.Data/NormalizedRulebase.cs new file mode 100644 index 0000000000..603de4367f --- /dev/null +++ b/roles/lib/files/FWO.Data/NormalizedRulebase.cs @@ -0,0 +1,53 @@ +using System.Text.Json.Serialization; +using Newtonsoft.Json; + +namespace FWO.Data +{ + public class NormalizedRulebase + { + [JsonProperty("id"), JsonPropertyName("id")] + public long? Id { get; set; } + + [JsonProperty("uid"), JsonPropertyName("uid")] + public string Uid { get; set; } = ""; + + [JsonProperty("name"), JsonPropertyName("name")] + public string Name { get; set; } = ""; + + [JsonProperty("mgm_uid"), JsonPropertyName("mgm_uid")] + public string MgmUid { get; set; } = ""; + + [JsonProperty("is_global"), JsonPropertyName("is_global")] + public bool IsGlobal { get; set; } + + [JsonProperty("rules"), JsonPropertyName("Rules")] + public Dictionary Rules { get; set; } = []; + + /// + /// Creates a NormalizedRulebase from a Rulebase. + /// + /// The Rulebase to normalize. + /// The management UID. + /// A normalized Rulebase. + /// Thrown if any rule in the rulebase lacks a UID. + public static NormalizedRulebase FromRulebase(Rulebase rulebase, string mgmUid) + { + if (rulebase.Rules.Any(r => r.Uid == null)) + { + throw new ArgumentException("All rules in the rulebase must have a UID."); + } + return new NormalizedRulebase + { + Id = null, // Id is omitted in normalized representation + Uid = rulebase.Uid, + Name = rulebase.Name, + MgmUid = mgmUid, + IsGlobal = rulebase.IsGlobal, + Rules = rulebase.Rules.ToDictionary( + r => r.Uid!, + NormalizedRule.FromRule + ) + }; + } + } +} diff --git a/roles/lib/files/FWO.Data/NormalizedRulebaseLink.cs b/roles/lib/files/FWO.Data/NormalizedRulebaseLink.cs new file mode 100644 index 0000000000..85031e4356 --- /dev/null +++ b/roles/lib/files/FWO.Data/NormalizedRulebaseLink.cs @@ -0,0 +1,48 @@ +using System.Text.Json.Serialization; +using Newtonsoft.Json; + +namespace FWO.Data +{ + public class NormalizedRulebaseLink + { + [JsonProperty("from_rulebase_uid"), JsonPropertyName("from_rulebase_uid")] + public string? FromRulebaseUid { get; set; } + + [JsonProperty("from_rule_uid"), JsonPropertyName("from_rule_uid")] + public string? FromRuleUid { get; set; } + + [JsonProperty("to_rulebase_uid"), JsonPropertyName("to_rulebase_uid")] + public string ToRulebaseUid { get; set; } = ""; + + [JsonProperty("link_type"), JsonPropertyName("link_type")] + public string LinkType { get; set; } = ""; + + [JsonProperty("is_initial"), JsonPropertyName("is_initial")] + public bool IsInitial { get; set; } + + [JsonProperty("is_global"), JsonPropertyName("is_global")] + public bool IsGlobal { get; set; } + + [JsonProperty("is_section"), JsonPropertyName("is_section")] + public bool IsSection { get; set; } + + public static NormalizedRulebaseLink FromRulebaseLink(RulebaseLink rulebaseLink) + { + if (rulebaseLink.ToRulebase == null || rulebaseLink.LinkTypeObj == null) + { + throw new ArgumentException("ToRulebase and LinkTypeObj cannot be null in RulebaseLink."); + } + + return new NormalizedRulebaseLink + { + FromRulebaseUid = rulebaseLink.FromRulebase?.Uid, + FromRuleUid = rulebaseLink.FromRule?.Uid, + ToRulebaseUid = rulebaseLink.ToRulebase.Uid, + LinkType = rulebaseLink.LinkTypeObj.Name, + IsInitial = rulebaseLink.IsInitial, + IsGlobal = rulebaseLink.IsGlobal, + IsSection = rulebaseLink.IsSection + }; + } + } +} diff --git a/roles/lib/files/FWO.Data/NormalizedServiceObject.cs b/roles/lib/files/FWO.Data/NormalizedServiceObject.cs new file mode 100644 index 0000000000..3bff3f92e7 --- /dev/null +++ b/roles/lib/files/FWO.Data/NormalizedServiceObject.cs @@ -0,0 +1,63 @@ +using System.Text.Json.Serialization; +using Newtonsoft.Json; + +namespace FWO.Data +{ + public class NormalizedServiceObject + { + [JsonProperty("svc_uid"), JsonPropertyName("svc_uid")] + public string SvcUid { get; set; } = ""; + + [JsonProperty("svc_name"), JsonPropertyName("svc_name")] + public string SvcName { get; set; } = ""; + + [JsonProperty("svc_port"), JsonPropertyName("svc_port")] + public int? SvcPort { get; set; } + + [JsonProperty("svc_port_end"), JsonPropertyName("svc_port_end")] + public int? SvcPortEnd { get; set; } + + [JsonProperty("svc_color"), JsonPropertyName("svc_color")] + public string SvcColor { get; set; } = ""; + + [JsonProperty("svc_typ"), JsonPropertyName("svc_typ")] + public string SvcType { get; set; } = ""; + + [JsonProperty("ip_proto"), JsonPropertyName("ip_proto")] + public int? IpProtocol { get; set; } + + [JsonProperty("svc_member_refs"), JsonPropertyName("svc_member_refs")] + public string? SvcMemberRefs { get; set; } + + [JsonProperty("svc_member_names"), JsonPropertyName("svc_member_names")] + public string? SvcMemberNames { get; set; } + + [JsonProperty("svc_comment"), JsonPropertyName("svc_comment")] + public string? SvcComment { get; set; } + + [JsonProperty("svc_timeout"), JsonPropertyName("svc_timeout")] + public int? SvcTimeout { get; set; } + + [JsonProperty("rpc_nr"), JsonPropertyName("rpc_nr")] + public string? RpcNumber { get; set; } + + public static NormalizedServiceObject FromNetworkService(NetworkService networkService) + { + return new NormalizedServiceObject + { + SvcUid = networkService.Uid, + SvcName = networkService.Name, + SvcPort = networkService.DestinationPort, + SvcPortEnd = networkService.DestinationPortEnd, + SvcColor = networkService.Color?.Name ?? "", + SvcType = networkService.Type.Name, + IpProtocol = networkService.ProtoId, + SvcMemberRefs = networkService.MemberRefs, + SvcMemberNames = networkService.MemberNames, + SvcComment = networkService.Comment, + SvcTimeout = networkService.Timeout, + RpcNumber = networkService.RpcNumber?.ToString() + }; + } + } +} diff --git a/roles/lib/files/FWO.Data/NormalizedTimeObject.cs b/roles/lib/files/FWO.Data/NormalizedTimeObject.cs new file mode 100644 index 0000000000..f8e8caa5c0 --- /dev/null +++ b/roles/lib/files/FWO.Data/NormalizedTimeObject.cs @@ -0,0 +1,31 @@ + +using System.Text.Json.Serialization; +using Newtonsoft.Json; + +namespace FWO.Data +{ + public class NormalizedTimeObject + { + [JsonProperty("time_obj_uid"), JsonPropertyName("time_obj_uid")] + public string Uid { get; set; } = ""; + + [JsonProperty("time_obj_name"), JsonPropertyName("time_obj_name")] + public string Name { get; set; } = ""; + + [JsonProperty("start_time"), JsonPropertyName("start_time")] + public string? StartTime { get; set; } + + [JsonProperty("end_time"), JsonPropertyName("end_time")] + public string? EndTime { get; set; } + public static NormalizedTimeObject FromTimeObject(TimeObject timeObject) + { + return new NormalizedTimeObject + { + Uid = timeObject.Uid, + Name = timeObject.Name, + StartTime = timeObject.StartTime.HasValue ? NormalizedConfig.FormatDatetimeZ(timeObject.StartTime.Value, convertToUtc: true) : null, + EndTime = timeObject.EndTime.HasValue ? NormalizedConfig.FormatDatetimeZ(timeObject.EndTime.Value, convertToUtc: true) : null + }; + } + } +} diff --git a/roles/lib/files/FWO.Data/NormalizedZoneObject.cs b/roles/lib/files/FWO.Data/NormalizedZoneObject.cs new file mode 100644 index 0000000000..d3c78763f4 --- /dev/null +++ b/roles/lib/files/FWO.Data/NormalizedZoneObject.cs @@ -0,0 +1,19 @@ +using System.Text.Json.Serialization; +using Newtonsoft.Json; + +namespace FWO.Data +{ + public class NormalizedZoneObject + { + [JsonProperty("zone_name"), JsonPropertyName("zone_name")] + public string ZoneName { get; set; } = ""; + + public static NormalizedZoneObject FromZoneObject(NetworkZone networkZone) + { + return new NormalizedZoneObject + { + ZoneName = networkZone.Name + }; + } + } +} diff --git a/roles/lib/files/FWO.Data/NotificationLayout.cs b/roles/lib/files/FWO.Data/NotificationLayout.cs new file mode 100644 index 0000000000..2b0509fee6 --- /dev/null +++ b/roles/lib/files/FWO.Data/NotificationLayout.cs @@ -0,0 +1,30 @@ +namespace FWO.Data +{ + public enum NotificationLayout + { + SimpleText = 0, + HtmlInBody = 1, + PdfAsAttachment = 10, + HtmlAsAttachment = 11, + CsvAsAttachment = 12, + JsonAsAttachment = 13 + } + + public static class NotificationLayoutGroups + { + public static List ListWithoutCsv() + { + return [ NotificationLayout.SimpleText, + NotificationLayout.HtmlInBody, + NotificationLayout.PdfAsAttachment, + NotificationLayout.HtmlAsAttachment, + NotificationLayout.JsonAsAttachment ]; + } + + public static List WithoutAttachments() + { + return [ NotificationLayout.SimpleText, + NotificationLayout.HtmlInBody ]; + } + } +} diff --git a/roles/lib/files/FWO.Data/ObjectChange.cs b/roles/lib/files/FWO.Data/ObjectChange.cs new file mode 100644 index 0000000000..a261b9fe0e --- /dev/null +++ b/roles/lib/files/FWO.Data/ObjectChange.cs @@ -0,0 +1,25 @@ +using Newtonsoft.Json; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Text.Json.Serialization; +using System.Threading.Tasks; + +namespace FWO.Data +{ + public class ObjectChange + { + [JsonProperty("import"), JsonPropertyName("import")] + public ChangeImport ChangeImport { get; set; } = new ChangeImport(); + + [JsonProperty("change_action"), JsonPropertyName("change_action")] + public char ChangeAction { get; set; } + + [JsonProperty("old"), JsonPropertyName("old")] + public NetworkObject OldObject { get; set; } = new NetworkObject(); + + [JsonProperty("new"), JsonPropertyName("new")] + public NetworkObject NewObject { get; set; } = new NetworkObject(); + } +} diff --git a/roles/lib/files/FWO.Data/ObjectStatistics.cs b/roles/lib/files/FWO.Data/ObjectStatistics.cs new file mode 100644 index 0000000000..339c8ae052 --- /dev/null +++ b/roles/lib/files/FWO.Data/ObjectStatistics.cs @@ -0,0 +1,35 @@ +using System.Text.Json.Serialization; +using Newtonsoft.Json; + +namespace FWO.Data +{ + public class ObjectStatistics + { + [JsonProperty("aggregate"), JsonPropertyName("aggregate")] + public ObjectAggregate ObjectAggregate { get; set; } = new ObjectAggregate(); + + + [JsonProperty("rules_aggregate"), JsonPropertyName("rules_aggregate")] + [System.Diagnostics.CodeAnalysis.SuppressMessage("CodeQuality", "IDE0051:Remove unused private members", Justification = "Used by JSON deserialization")] + private ObjectStatistics RulesAggregateWrapper + { + get => default!; + set + { + if (value != null && value.ObjectAggregate != null) + { + ObjectAggregate = value.ObjectAggregate; + } + } + } + } + + public class ObjectAggregate + { + [JsonProperty("count"), JsonPropertyName("count")] + public int ObjectCount { get; set; } = 0; + + } + +} + diff --git a/roles/lib/files/FWO.Data/OwnerAdditionalInfoJson.cs b/roles/lib/files/FWO.Data/OwnerAdditionalInfoJson.cs new file mode 100644 index 0000000000..48a483c390 --- /dev/null +++ b/roles/lib/files/FWO.Data/OwnerAdditionalInfoJson.cs @@ -0,0 +1,60 @@ +using System.Linq; +using System.Text.Json; + +namespace FWO.Data +{ + /// + /// Converts owner additional information dictionaries to and from editable JSON text. + /// + public static class OwnerAdditionalInfoJson + { + private static readonly JsonSerializerOptions kJsonOptions = new() + { + WriteIndented = true + }; + + /// + /// Serializes owner additional information for UI editing. + /// + /// Additional owner metadata. + /// Indented JSON text or an empty string when no data is present. + public static string Serialize(Dictionary? additionalInfo) + { + if (additionalInfo == null || additionalInfo.Count == 0) + { + return ""; + } + + return JsonSerializer.Serialize(additionalInfo, kJsonOptions); + } + + /// + /// Tries to parse owner additional information from editable JSON text. + /// + /// JSON text entered by the user. + /// Parsed metadata dictionary or null when the input is empty. + /// True when parsing succeeded, otherwise false. + public static bool TryDeserialize(string? json, out Dictionary? additionalInfo) + { + additionalInfo = null; + + if (string.IsNullOrWhiteSpace(json)) + { + return true; + } + + try + { + Dictionary parsedAdditionalInfo = + JsonSerializer.Deserialize>(json, kJsonOptions) ?? []; + additionalInfo = parsedAdditionalInfo.ToDictionary(entry => entry.Key, entry => entry.Value ?? ""); + return true; + } + catch (JsonException) + { + additionalInfo = null; + return false; + } + } + } +} diff --git a/roles/lib/files/FWO.Data/OwnerChange.cs b/roles/lib/files/FWO.Data/OwnerChange.cs new file mode 100644 index 0000000000..73ae566d48 --- /dev/null +++ b/roles/lib/files/FWO.Data/OwnerChange.cs @@ -0,0 +1,26 @@ +using Newtonsoft.Json; +using System; +using System.Collections.Generic; +using System.Text; +using System.Text.Json.Serialization; + +namespace FWO.Data +{ + public class OwnerChange + { + [JsonProperty("import"), JsonPropertyName("import")] + public ChangeImport ChangeImport { get; set; } = new ChangeImport(); + + [JsonProperty("change_action"), JsonPropertyName("change_action")] + public char ChangeAction { get; set; } + + [JsonProperty("old"), JsonPropertyName("old")] + public FwoOwner OldOwner { get; set; } = new FwoOwner(); + + [JsonProperty("new"), JsonPropertyName("new")] + public FwoOwner NewOwner { get; set; } = new FwoOwner(); + + [JsonProperty("source_id"), JsonPropertyName("source_id")] + public string source_id { get; set; } = ""; + } +} diff --git a/roles/lib/files/FWO.Data/OwnerIdModel.cs b/roles/lib/files/FWO.Data/OwnerIdModel.cs new file mode 100644 index 0000000000..da9d37e2e9 --- /dev/null +++ b/roles/lib/files/FWO.Data/OwnerIdModel.cs @@ -0,0 +1,11 @@ +using Newtonsoft.Json; +using System.Text.Json.Serialization; + +namespace FWO.Data +{ + public class OwnerIdModel + { + [JsonProperty("id"), JsonPropertyName("id")] + public int Id { get; set; } + } +} diff --git a/roles/lib/files/FWO.Data/OwnerLifeCycleState.cs b/roles/lib/files/FWO.Data/OwnerLifeCycleState.cs new file mode 100644 index 0000000000..770acc8725 --- /dev/null +++ b/roles/lib/files/FWO.Data/OwnerLifeCycleState.cs @@ -0,0 +1,65 @@ +using Newtonsoft.Json; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Text.Json.Serialization; +using System.Threading.Tasks; + +namespace FWO.Data +{ + public class OwnerLifeCycleState + { + [JsonProperty("id"), JsonPropertyName("id")] + public int Id { get; set; } + + [JsonProperty("name"), JsonPropertyName("name")] + public string Name { get; set; } = ""; + + [JsonProperty("active_state"), JsonPropertyName("active_state")] + public bool ActiveState { get; set; } = true; + + public OwnerLifeCycleState() + { } + + public OwnerLifeCycleState(OwnerLifeCycleState ownerLifeCycleState) + { + Id = ownerLifeCycleState.Id; + Name = ownerLifeCycleState.Name; + ActiveState = ownerLifeCycleState.ActiveState; + } + + + public bool Sanitize() + { + bool shortened = false; + Name = Sanitizer.SanitizeMand(Name, ref shortened); + return shortened; + } + + public string Display(string inactiveText) + { + return ActiveState ? Name : $"{Name} ({inactiveText})"; + } + + public static DateTime? GetDecommDate(DateTime? currentDecommDate, OwnerLifeCycleState? oldState, OwnerLifeCycleState? newState, DateTime nowUtc) + { + if (newState == null) + { + return currentDecommDate; + } + + if (!newState.ActiveState && currentDecommDate == null) + { + return nowUtc; + } + + if (oldState == null || oldState.ActiveState == newState.ActiveState) + { + return currentDecommDate; + } + + return newState.ActiveState ? null : nowUtc; + } + } +} diff --git a/roles/lib/files/FWO.Data/OwnerNetwork.cs b/roles/lib/files/FWO.Data/OwnerNetwork.cs new file mode 100644 index 0000000000..4cc8e3e6ac --- /dev/null +++ b/roles/lib/files/FWO.Data/OwnerNetwork.cs @@ -0,0 +1,45 @@ +using Newtonsoft.Json; +using System; +using System.Collections.Generic; +using System.Text; +using System.Text.Json.Serialization; + +namespace FWO.Data +{ + public class OwnerNetwork + { + [JsonProperty("id"), JsonPropertyName("id")] + public long Id { get; set; } + + [JsonProperty("owner_id"), JsonPropertyName("owner_id")] + public int OwnerId { get; set; } + + [JsonProperty("name"), JsonPropertyName("name")] + public string Name { get; set; } = ""; + + [JsonProperty("ip"), JsonPropertyName("ip")] + public string IP { get; set; } = ""; + + [JsonProperty("ip_end"), JsonPropertyName("ip_end")] + public string IpEnd { get; set; } = ""; + + [JsonProperty("port"), JsonPropertyName("port")] + public int Port { get; set; } + + [JsonProperty("ip_proto_id"), JsonPropertyName("ip_proto_id")] + public int IpProtoId { get; set; } + + [JsonProperty("nw_type"), JsonPropertyName("nw_type")] + public int NwType { get; set; } + + [JsonProperty("import_source"), JsonPropertyName("import_source")] + public string ImportSource { get; set; } = ""; + + [JsonProperty("is_deleted"), JsonPropertyName("is_deleted")] + public bool IsDeleted { get; set; } + + [JsonProperty("custom_type"), JsonPropertyName("custom_type")] + public int CustomType { get; set; } + + } +} diff --git a/roles/lib/files/FWO.Data/OwnerRecertification.cs b/roles/lib/files/FWO.Data/OwnerRecertification.cs new file mode 100644 index 0000000000..0920a7a771 --- /dev/null +++ b/roles/lib/files/FWO.Data/OwnerRecertification.cs @@ -0,0 +1,32 @@ +using System.Text.Json.Serialization; +using Newtonsoft.Json; + +namespace FWO.Data +{ + public class OwnerRecertification + { + [JsonProperty("id"), JsonPropertyName("id")] + public long Id { get; set; } + + [JsonProperty("owner_id"), JsonPropertyName("owner_id")] + public int OwnerId { get; set; } + + [JsonProperty("user_dn"), JsonPropertyName("user_dn")] + public string? RecertifierDn { get; set; } + + [JsonProperty("recert_date"), JsonPropertyName("recert_date")] + public DateTime? RecertDate { get; set; } + + [JsonProperty("recertified"), JsonPropertyName("recertified")] + public bool Recertified { get; set; } = false; + + [JsonProperty("next_recert_date"), JsonPropertyName("next_recert_date")] + public DateTime? NextRecertDate { get; set; } + + [JsonProperty("comment"), JsonPropertyName("comment")] + public string Comment { get; set; } = ""; + + [JsonProperty("report_id"), JsonPropertyName("report_id")] + public long? ReportId { get; set; } + } +} diff --git a/roles/lib/files/FWO.Data/OwnerRefresh.cs b/roles/lib/files/FWO.Data/OwnerRefresh.cs new file mode 100644 index 0000000000..1e55909f7b --- /dev/null +++ b/roles/lib/files/FWO.Data/OwnerRefresh.cs @@ -0,0 +1,34 @@ +using System.Text.Json.Serialization; +using Newtonsoft.Json; + +namespace FWO.Data +{ + + // refresh_view_rule_with_owner { + // id + // view_name + // refreshed_at + // status + // } + public class OwnerRefresh + { + + [JsonProperty("id"), JsonPropertyName("id")] + private int Id { get; set; } = 0; + + [JsonProperty("view_name"), JsonPropertyName("view_name")] + private string ViewName { get; set; } = ""; + + [JsonProperty("refreshed_at"), JsonPropertyName("refreshed_at")] + private string RefreshedAt { get; set; } = ""; + + [JsonProperty("status"), JsonPropertyName("status")] + private string Status { get; set; } = ""; + + + public string GetStatus() + { + return Status; + } + } +} diff --git a/roles/lib/files/FWO.Data/OwnerResponsibleType.cs b/roles/lib/files/FWO.Data/OwnerResponsibleType.cs new file mode 100644 index 0000000000..8747b6c236 --- /dev/null +++ b/roles/lib/files/FWO.Data/OwnerResponsibleType.cs @@ -0,0 +1,26 @@ +using Newtonsoft.Json; +using System.Text.Json.Serialization; + +namespace FWO.Data +{ + public class OwnerResponsibleType + { + [JsonProperty("id"), JsonPropertyName("id")] + public int Id { get; set; } + + [JsonProperty("name"), JsonPropertyName("name")] + public string Name { get; set; } = ""; + + [JsonProperty("active"), JsonPropertyName("active")] + public bool Active { get; set; } = true; + + [JsonProperty("allow_modelling"), JsonPropertyName("allow_modelling")] + public bool AllowModelling { get; set; } + + [JsonProperty("allow_recertification"), JsonPropertyName("allow_recertification")] + public bool AllowRecertification { get; set; } + + [JsonProperty("sort_order"), JsonPropertyName("sort_order")] + public int SortOrder { get; set; } + } +} diff --git a/roles/lib/files/FWO.Api.Client/Data/PaginationVariables.cs b/roles/lib/files/FWO.Data/PaginationVariables.cs similarity index 87% rename from roles/lib/files/FWO.Api.Client/Data/PaginationVariables.cs rename to roles/lib/files/FWO.Data/PaginationVariables.cs index 13214f9783..954ba74437 100644 --- a/roles/lib/files/FWO.Api.Client/Data/PaginationVariables.cs +++ b/roles/lib/files/FWO.Data/PaginationVariables.cs @@ -1,11 +1,7 @@ -using System; -using System.Collections.Generic; -using System.Linq; using Newtonsoft.Json; using System.Text.Json.Serialization; -using System.Threading.Tasks; -namespace FWO.Api.Data +namespace FWO.Data { public class PaginationVariables { diff --git a/roles/lib/files/FWO.Api.Client/Data/Recertification.cs b/roles/lib/files/FWO.Data/Recertification.cs similarity index 81% rename from roles/lib/files/FWO.Api.Client/Data/Recertification.cs rename to roles/lib/files/FWO.Data/Recertification.cs index d10fa1576b..0c7eac9b36 100644 --- a/roles/lib/files/FWO.Api.Client/Data/Recertification.cs +++ b/roles/lib/files/FWO.Data/Recertification.cs @@ -1,7 +1,7 @@ using System.Text.Json.Serialization; using Newtonsoft.Json; -namespace FWO.Api.Data +namespace FWO.Data { public class Recertification : RecertificationBase { @@ -9,6 +9,6 @@ public class Recertification : RecertificationBase public FwoOwner? FwoOwner { get; set; } = new FwoOwner(); [JsonProperty("user_dn"), JsonPropertyName("user_dn")] - public string UserDn { get; set; } = ""; + public string UserDn { get; set; } = ""; } } diff --git a/roles/lib/files/FWO.Api.Client/Data/RecertificationBase.cs b/roles/lib/files/FWO.Data/RecertificationBase.cs similarity index 89% rename from roles/lib/files/FWO.Api.Client/Data/RecertificationBase.cs rename to roles/lib/files/FWO.Data/RecertificationBase.cs index fc33d97ac6..d0281ace33 100644 --- a/roles/lib/files/FWO.Api.Client/Data/RecertificationBase.cs +++ b/roles/lib/files/FWO.Data/RecertificationBase.cs @@ -1,7 +1,7 @@ using System.Text.Json.Serialization; using Newtonsoft.Json; -namespace FWO.Api.Data +namespace FWO.Data { public class RecertificationBase { @@ -25,10 +25,10 @@ public class RecertificationBase public string Comment { get; set; } = ""; [JsonProperty("rule_id"), JsonPropertyName("rule_id")] - public int RuleId { get; set; } + public long RuleId { get; set; } [JsonProperty("rule_metadata_id"), JsonPropertyName("rule_metadata_id")] - public int RuleMetadataId { get; set; } + public long RuleMetadataId { get; set; } } } diff --git a/roles/lib/files/FWO.Data/RecertificationMode.cs b/roles/lib/files/FWO.Data/RecertificationMode.cs new file mode 100644 index 0000000000..051c746107 --- /dev/null +++ b/roles/lib/files/FWO.Data/RecertificationMode.cs @@ -0,0 +1,8 @@ +namespace FWO.Data +{ + public enum RecertificationMode + { + RuleByRule = 0, + OwnersAndRules = 1 + } +} diff --git a/roles/lib/files/FWO.Data/Report/ComplianceFilter.cs b/roles/lib/files/FWO.Data/Report/ComplianceFilter.cs new file mode 100644 index 0000000000..6b3207d463 --- /dev/null +++ b/roles/lib/files/FWO.Data/Report/ComplianceFilter.cs @@ -0,0 +1,25 @@ +using System.Text.Json.Serialization; +using Newtonsoft.Json; + +namespace FWO.Data.Report +{ + public class ComplianceFilter + { + [JsonProperty("diff_reference_in_days"), JsonPropertyName("diff_reference_in_days")] + public int DiffReferenceInDays { get; set; } = 0; + [JsonProperty("show_non_impact_rules"), JsonPropertyName("show_non_impact_rules")] + public bool ShowNonImpactRules { get; set; } = false; + + public ComplianceFilter() + { + + } + + public ComplianceFilter(ComplianceFilter complianceFilter) + { + DiffReferenceInDays = complianceFilter.DiffReferenceInDays; + ShowNonImpactRules = complianceFilter.ShowNonImpactRules; + } + } + +} diff --git a/roles/lib/files/FWO.Data/Report/ConnectionReport.cs b/roles/lib/files/FWO.Data/Report/ConnectionReport.cs new file mode 100644 index 0000000000..d41604a9e6 --- /dev/null +++ b/roles/lib/files/FWO.Data/Report/ConnectionReport.cs @@ -0,0 +1,214 @@ +using FWO.Basics; +using FWO.Data.Modelling; + +namespace FWO.Data.Report +{ + public class ConnectionReport + { + public string Name { get; set; } = ""; + + public List AllObjects { get; set; } = []; + public List AllServices { get; set; } = []; + + public ConnectionReport() + { } + + public ConnectionReport(ConnectionReport report) + { + Name = report.Name; + AllObjects = report.AllObjects; + AllServices = report.AllServices; + } + + public static void AssignConnectionNumbers(List connections) + { + int connNumber = 1; + foreach (var conn in connections) + { + conn.OrderNumber = connNumber++; + } + } + + public void PrepareObjectData(bool resolveNetworkAreas) + { + AllObjects = GetAllNetworkObjects(true, resolveNetworkAreas); + SetObjectNumbers(AllObjects); + AllServices = GetAllServices(true); + SetSvcNumbers(AllServices); + } + + public virtual List GetAllNetworkObjects(bool resolved = false, bool resolveNetworkAreas = false) + { + return []; + } + + public virtual List GetAllServices(bool resolved = false) + { + return []; + } + + public static void SetSvcNumbers(List svcList) + { + long number = 1; + foreach (var svc in svcList) + { + svc.Number = number++; + } + } + + public static void SetObjectNumbers(List objList) + { + long number = 1; + foreach (var obj in objList) + { + obj.Number = number++; + } + } + + public static List GetAllServices(List connections, bool resolved = false) + { + List allServices = []; + foreach (var conn in connections) + { + List svcList = []; + foreach (var svcGrp in conn.ServiceGroups.Select(s => s.Content)) + { + NetworkService serviceGroup = svcGrp.ToNetworkServiceGroup(); + svcList.Add(svcGrp.ToNetworkServiceGroup()); + if (resolved) + { + foreach (var svc in serviceGroup.ServiceGroups.Where(s => s.Object != null)) + { + svcList.Add(svc.Object!); + } + } + } + allServices = allServices.Union(svcList).ToList(); + allServices = [.. allServices.Union([.. ModellingServiceWrapper.ResolveAsNetworkServices(conn.Services)])]; + } + return allServices; + } + + public static List GetAllNetworkObjects(List connections, bool resolved = false, bool resolveNetworkAreas = false, long dummyARid = 0) + { + List allObjects = []; + foreach (var conn in connections) + { + allObjects = [.. allObjects.Union(GetAllNwGrpObjectsFromConn(conn, resolved, resolveNetworkAreas, dummyARid))]; + } + allObjects = [.. allObjects.Union(GetAllAppServers(connections).ConvertAll(ModellingAppServer.ToNetworkObject))]; + return allObjects; + } + + public long ResolveObjId(ModellingNwObject networkObject) + { + return AllObjects.FirstOrDefault(x => x.Name.StartsWith(networkObject.Name))?.Id ?? 0; + } + + public long ResolveSvcId(ModellingSvcObject serviceObject) + { + return AllServices.FirstOrDefault(x => x.Name == serviceObject.Name)?.Id ?? 0; + } + + private static List GetAllAppServers(List connections) + { + List allAppServers = []; + foreach (var conn in connections) + { + allAppServers = [.. allAppServers.Union([.. ModellingAppServerWrapper.Resolve(conn.SourceAppServers)])]; + allAppServers = [.. allAppServers.Union([.. ModellingAppServerWrapper.Resolve(conn.DestinationAppServers)])]; + } + return allAppServers; + } + + private static List GetAllNwGrpObjectsFromConn(ModellingConnection conn, bool resolved = false, bool resolveNetworkAreas = false, long dummyARid = 0) + { + List objList = []; + GetObjectsFromAreas(conn.SourceAreas, ref objList, resolved, resolveNetworkAreas); + GetObjectsFromAreas(conn.DestinationAreas, ref objList, resolved, resolveNetworkAreas); + GetObjectsFromAR(conn.SourceAppRoles, ref objList, resolved, dummyARid); + GetObjectsFromAR(conn.DestinationAppRoles, ref objList, resolved, dummyARid); + GetObjectsFromOtherGroups(conn.SourceOtherGroups, ref objList, resolved); + GetObjectsFromOtherGroups(conn.DestinationOtherGroups, ref objList, resolved); + return objList; + } + + private static void GetObjectsFromAreas(List areas, ref List objectList, bool resolved = false, bool resolveNetworkAreas = false) + { + foreach (var areaWrapper in areas.Select(a => a.Content)) + { + objectList.Add(areaWrapper.ToNetworkObjectGroup(false, resolveNetworkAreas)); + if (resolved && resolveNetworkAreas) + { + foreach (var obj in areaWrapper.ToNetworkObjectGroup().ObjectGroups.Where(o => o.Object != null)) + { + objectList.Add(obj.Object!); + } + } + } + } + + private static void GetObjectsFromOtherGroups(List nwGroups, ref List objectList, bool resolved = false) + { + foreach (var nwGrpWrapper in nwGroups.Select(n => n.Content)) + { + objectList.Add(nwGrpWrapper.ToNetworkObjectGroup()); + if (resolved) + { + foreach (var obj in nwGrpWrapper.ToNetworkObjectGroup().ObjectGroups.Where(o => o.Object != null)) + { + objectList.Add(obj.Object!); + } + } + } + } + + private static void GetObjectsFromAR(List appRoles, ref List objectList, bool resolved = false, long dummyARid = 0) + { + foreach (var aRWrapper in appRoles.Select(w => w.Content).Where(a => a.Id != dummyARid)) + { + objectList.Add(aRWrapper.ToNetworkObjectGroup()); + if (resolved) + { + foreach (var obj in aRWrapper.ToNetworkObjectGroup().ObjectGroups.Where(o => o.Object != null)) + { + objectList.Add(obj.Object!); + } + } + } + } + + public static string ListAppServers(List appServers, List surplusAppServers, bool diffMode = false, bool forExport = false) + { + if (diffMode) + { + List allAppServers = [.. appServers.ConvertAll(a => DisplayAppServerWithDiff(a, forExport))]; + allAppServers.AddRange(surplusAppServers.ConvertAll(a => DisplayAppServerWithDiff(a, forExport, true))); + return string.Join(", ", allAppServers); + } + else + { + return string.Join(", ", appServers.ConvertAll(a => DisplayBase.DisplayIpWithName(ModellingAppServer.ToNetworkObject(a)))); + } + } + + private static string DisplayAppServerWithDiff(ModellingAppServer appServer, bool forExport, bool surplus = false) + { + string styleOrClass = $"{(forExport ? "style" : "class")}=\"{StyleOrCssClass(appServer, forExport, surplus)}\""; + return $"{DisplayBase.DisplayIpWithName(ModellingAppServer.ToNetworkObject(appServer))}"; + } + + private static string StyleOrCssClass(ModellingAppServer appServer, bool forExport, bool surplus) + { + if (surplus) + { + return forExport ? GlobalConst.kStyleHighlightedGreen : "text-success"; + } + if (appServer.NotImplemented) + { + return forExport ? GlobalConst.kStyleHighlightedRed : "text-danger"; + } + return ""; + } + } +} diff --git a/roles/lib/files/FWO.Data/Report/DeviceFilter.cs b/roles/lib/files/FWO.Data/Report/DeviceFilter.cs new file mode 100644 index 0000000000..967bac0428 --- /dev/null +++ b/roles/lib/files/FWO.Data/Report/DeviceFilter.cs @@ -0,0 +1,274 @@ +using System.Text; +using System.Text.Json.Serialization; +using Microsoft.AspNetCore.Components; +using Newtonsoft.Json; + +namespace FWO.Data.Report +{ + public class ManagementSelect + { + [JsonProperty("id"), JsonPropertyName("id")] + public int Id { get; set; } + + [JsonProperty("name"), JsonPropertyName("name")] + public string? Name { get; set; } + + [JsonProperty("uid"), JsonPropertyName("uid")] + public string Uid { get; set; } = ""; + + [JsonProperty("devices"), JsonPropertyName("devices")] + public List Devices { get; set; } = []; + + public ElementReference? UiReference { get; set; } + + public bool Visible { get; set; } = true; + public bool Selected { get; set; } = false; + public bool Shared { get; set; } = true; + public ManagementSelect Clone() + { + List ClonedDevices = []; + foreach (var dev in Devices) + { + ClonedDevices.Add(new DeviceSelect(dev)); + } + + return new ManagementSelect() + { + Id = Id, + Name = Name, + Devices = ClonedDevices, + UiReference = UiReference, + Visible = Visible, + Selected = Selected + }; + } + } + + public class DeviceSelect + { + [JsonProperty("id"), JsonPropertyName("id")] + public int Id { get; set; } + + [JsonProperty("name"), JsonPropertyName("name")] + public string? Name { get; set; } + + public bool Visible { get; set; } = true; + + public bool Selected { get; set; } = false; + public bool Shared { get; set; } = true; + public DeviceSelect() + { } + + public DeviceSelect(DeviceSelect dev) + { + Id = dev.Id; + Name = dev.Name; + Visible = dev.Visible; + Selected = dev.Selected; + } + } + + public class DeviceFilter + { + [JsonProperty("management"), JsonPropertyName("management")] + public List Managements { get; set; } = []; + + [JsonProperty("visibleManagements"), JsonPropertyName("visibleManagements")] + public List VisibleManagements { get; set; } = []; + + [JsonProperty("visibleGateways"), JsonPropertyName("visibleGateways")] + public List VisibleGateways { get; set; } = []; + + public DeviceFilter() + { } + + public DeviceFilter(DeviceFilter devFilter) + { + Managements = [.. devFilter.Managements]; + } + + public DeviceFilter(List mgmSelect) + { + Managements = [.. mgmSelect]; + } + + public DeviceFilter Clone() + { + List ClonedManagements = []; + foreach (var mgt in Managements) + { + ClonedManagements.Add(mgt.Clone()); + } + + return new DeviceFilter() + { + Managements = ClonedManagements + }; + } + + public bool AreAllDevicesSelected() + { + foreach (ManagementSelect management in Managements) + foreach (DeviceSelect device in management.Devices) + if (!device.Selected && device.Visible) + return false; + return true; + } + + public bool IsAnyDeviceFilterSet() + { + foreach (ManagementSelect management in Managements) + foreach (DeviceSelect device in management.Devices) + if (device.Selected) + return true; + return false; + } + + public void ApplyFullDeviceSelection(bool selectAll) + { + foreach (ManagementSelect management in Managements) + { + // only select visible managements + management.Selected = selectAll && management.Visible; + foreach (DeviceSelect device in management.Devices) + { + // only select visible devices + device.Selected = selectAll && device.Visible; + } + } + } + + public static bool IsSelectedManagement(ManagementSelect management) + { + foreach (DeviceSelect device in management.Devices) + { + if (device.Selected) + { + return true; + } + } + return false; + } + + public List GetSelectedManagements() + { + List selectedMgmts = []; + foreach (ManagementSelect mgmt in Managements) + { + if (IsSelectedManagement(mgmt)) + { + selectedMgmts.Add(mgmt.Id); + } + } + return selectedMgmts; + } + + public string ListAllSelectedDevices() + { + List devs = []; + foreach (ManagementSelect mgmt in Managements) + foreach (DeviceSelect dev in mgmt.Devices) + if (dev.Selected) + devs.Add(dev.Name ?? ""); + return string.Join(", ", devs); + } + + public string ListAllSelectedManagements() + { + List managements = []; + foreach (ManagementSelect mgmt in Managements) + { + if (IsSelectedManagement(mgmt)) + { + managements.Add(mgmt.Name ?? ""); + } + } + return string.Join(", ", managements); + } + + public static List ExtractAllDevIds(Management[] managements) + { + List devs = []; + foreach (Management mgmt in managements) + foreach (Device dev in mgmt.Devices) + devs.Add(dev.Id); + return devs; + } + + public static List ExtractSelectedDevIds(Management[] managements) + { + List selectedDevs = []; + foreach (Management mgmt in managements) + foreach (Device dev in mgmt.Devices) + if (dev.Selected) + selectedDevs.Add(dev.Id); + return selectedDevs; + } + + public void SynchronizeDevFilter(DeviceFilter incomingDevFilter) + { + // unknown incoming devices (e.g. from templates) are ignored, because they have been removed inbetween + foreach (ManagementSelect management in Managements) + { + ManagementSelect? incomingMgt = incomingDevFilter.Managements.Find(x => x.Id == management.Id); + if (incomingMgt != null) + { + foreach (DeviceSelect device in management.Devices) + { + DeviceSelect? incomingDev = incomingMgt.Devices.Find(x => x.Id == device.Id); + if (incomingDev != null) + { + // the next line could be the problem as it changes an object: + if (device.Visible) + { + device.Selected = incomingDev.Selected; + } + } + } + } + } + SynchronizeMgmtFilter(); + } + + public void SynchronizeMgmtFilter() + { + foreach (ManagementSelect management in Managements) + { + int selectedDevicesCount = management.Devices.Where(d => d.Selected).Count(); + int visibleDevicesCount = management.Devices.Where(d => d.Visible).Count(); + // Management is selected if all visible devices are selected + management.Selected = management.Devices.Count > 0 && selectedDevicesCount == visibleDevicesCount; + } + } + + public int NumberMgmtDev() + { + int counter = 0; + foreach (ManagementSelect management in Managements) + { + if (management.Visible) + { + counter++; + foreach (DeviceSelect device in management.Devices) + { + if (device.Visible) + { + counter++; + } + } + } + } + return counter; + } + + public override string ToString() + { + StringBuilder result = new(); + foreach (ManagementSelect management in Managements) + { + result.Append($"{management.Name} [{string.Join(", ", management.Devices.ConvertAll(device => device.Name))}]; "); + } + return result.ToString(); + } + } +} diff --git a/roles/lib/files/FWO.Data/Report/DeviceReport.cs b/roles/lib/files/FWO.Data/Report/DeviceReport.cs new file mode 100644 index 0000000000..4c46ddb6fd --- /dev/null +++ b/roles/lib/files/FWO.Data/Report/DeviceReport.cs @@ -0,0 +1,88 @@ +using System.Text.Json.Serialization; +using Newtonsoft.Json; + +namespace FWO.Data.Report +{ + public class DeviceReport + { + [JsonProperty("uid"), JsonPropertyName("uid")] + public string Uid { get; set; } = ""; + + [JsonProperty("id"), JsonPropertyName("id")] + public int Id { get; set; } + + [JsonProperty("name"), JsonPropertyName("name")] + public string? Name { get; set; } + + [JsonProperty("rulebase_links"), JsonPropertyName("rulebase_links")] + public RulebaseLink[] RulebaseLinks { get; set; } + + [JsonProperty("changelog_rules"), JsonPropertyName("changelog_rules")] + public RuleChange[]? RuleChanges { get; set; } + + [JsonProperty("rules_aggregate"), JsonPropertyName("rules_aggregate")] + public ObjectStatistics RuleStatistics { get; set; } = new ObjectStatistics(); + + [JsonProperty("unusedRules_Count"), JsonPropertyName("unusedRules_Count")] + public ObjectStatistics UnusedRulesStatistics { get; set; } = new(); + + + private List Rules = []; + + + public void SetRulesForDev(List rulesToReport) + { + Rules = rulesToReport; + } + + public bool IsLinked(Rule rule) + { + List activeRulebaseLinks = [.. RulebaseLinks.Where(link => link.GatewayId == Id && link.Removed == null)]; + return activeRulebaseLinks.Any(link => link.NextRulebaseId == rule.RulebaseId); + } + + public List GetRuleList() + { + return Rules; + } + + public DeviceReport() + { + RulebaseLinks = []; + } + + public DeviceReport(DeviceReport deviceReport) + { + Uid = deviceReport.Uid; + Id = deviceReport.Id; + Name = deviceReport.Name; + RulebaseLinks = deviceReport.RulebaseLinks; + } + + public int? GetInitialRulebaseId(ManagementReport managementReport) + { + return RulebaseLinks.FirstOrDefault(_ => _.IsInitial)?.NextRulebaseId; + } + + public void AddRule(Rule rule) + { + Rules.Add(rule); + } + + public int GetNumberOfRules() + { + return Rules.Count; + } + + /// + /// Conforms internal data to be valid for further usage. + /// + public void EnforceValidity() + { + if (UnusedRulesStatistics.ObjectAggregate.ObjectCount >= RuleStatistics.ObjectAggregate.ObjectCount) + { + UnusedRulesStatistics.ObjectAggregate.ObjectCount = 0; + } + } + } +} diff --git a/roles/lib/files/FWO.Data/Report/FileFormat.cs b/roles/lib/files/FWO.Data/Report/FileFormat.cs new file mode 100644 index 0000000000..cf3da43abe --- /dev/null +++ b/roles/lib/files/FWO.Data/Report/FileFormat.cs @@ -0,0 +1,31 @@ +using System.Text.Json.Serialization; +using Newtonsoft.Json; + +namespace FWO.Data.Report +{ + public class FileFormat + { + [JsonProperty("report_schedule_format_name"), JsonPropertyName("report_schedule_format_name")] + public string Name { get; set; } = ""; + } + + public static class FileFormatUtil + { + public static FileFormat Find(this IEnumerable fileFormats, string name) + { + return fileFormats.First(fileFormat => fileFormat.Name == name); + } + + public static void AddOrRemove(this List fileFormats, string name) + { + if (fileFormats.RemoveAll(fileFormat => fileFormat.Name == name) == 0) + { + fileFormats.Add(new FileFormat { Name = name }); + } + } + public static void Remove(this List fileFormats, string name) + { + fileFormats.RemoveAll(fileFormat => fileFormat.Name == name); + } + } +} diff --git a/roles/lib/files/FWO.Data/Report/GlobalCommonSvcReport.cs b/roles/lib/files/FWO.Data/Report/GlobalCommonSvcReport.cs new file mode 100644 index 0000000000..520f76ccca --- /dev/null +++ b/roles/lib/files/FWO.Data/Report/GlobalCommonSvcReport.cs @@ -0,0 +1,27 @@ +using FWO.Data.Modelling; + +namespace FWO.Data.Report +{ + public class GlobalCommonSvcReport : ConnectionReport + { + public List GlobalComSvcs = []; + + public GlobalCommonSvcReport() : base() + { } + + public GlobalCommonSvcReport(GlobalCommonSvcReport report) : base(report) + { + GlobalComSvcs = report.GlobalComSvcs; + } + + public override List GetAllNetworkObjects(bool resolved = false, bool resolveNetworkAreas = false) + { + return GetAllNetworkObjects(GlobalComSvcs, resolved, resolveNetworkAreas); + } + + public override List GetAllServices(bool resolved = false) + { + return GetAllServices(GlobalComSvcs, resolved); + } + } +} diff --git a/roles/lib/files/FWO.Data/Report/ManagementReport.cs b/roles/lib/files/FWO.Data/Report/ManagementReport.cs new file mode 100644 index 0000000000..7984548868 --- /dev/null +++ b/roles/lib/files/FWO.Data/Report/ManagementReport.cs @@ -0,0 +1,275 @@ +using Newtonsoft.Json; +using System.Text.Json.Serialization; +using System.Xml.Linq; +using System.Linq; + +namespace FWO.Data.Report +{ + public class ManagementReport + { + [JsonProperty("id"), JsonPropertyName("id")] + public int Id { get; set; } + + [JsonProperty("uid"), JsonPropertyName("uid")] + public string Uid { get; set; } + + [JsonProperty("name"), JsonPropertyName("name")] + public string Name { get; set; } = ""; + + [JsonProperty("devices"), JsonPropertyName("devices")] + public DeviceReport[] Devices { get; set; } = []; + + [JsonProperty("rulebases"), JsonPropertyName("rulebases")] + public RulebaseReport[] Rulebases { get; set; } = []; + + [JsonProperty("changelog_rules"), JsonPropertyName("changelog_rules")] + public RuleChange[]? RuleChanges { get; set; } + + [JsonProperty("changelog_objects"), JsonPropertyName("changelog_objects")] + public ObjectChange[]? ObjectChanges { get; set; } + + [JsonProperty("changelog_services"), JsonPropertyName("changelog_services")] + public ServiceChange[]? ServiceChanges { get; set; } + + [JsonProperty("changelog_users"), JsonPropertyName("changelog_users")] + public UserChange[]? UserChanges { get; set; } + + [JsonProperty("import"), JsonPropertyName("import")] + public Import Import { get; set; } = new(); + + [JsonProperty("import_controls"), JsonPropertyName("import_controls")] + public List ImportControls { get; set; } = []; + public long? RelevantImportId { get; set; } + + [JsonProperty("is_super_manager"), JsonPropertyName("is_super_manager")] + public bool IsSuperManager { get; set; } + + [JsonProperty("multi_device_manager_id"), JsonPropertyName("multi_device_manager_id")] + public int? SuperManagerId { get; set; } + + [JsonProperty("management"), JsonPropertyName("management")] + public Management? SuperManager { get; set; } + + [JsonProperty("managementByMultiDeviceManagerId"), JsonPropertyName("managementByMultiDeviceManagerId")] + public List SubManagements { get; set; } = []; + + [JsonProperty("networkObjects"), JsonPropertyName("networkObjects")] + public NetworkObject[] Objects { get; set; } = []; + + [JsonProperty("serviceObjects"), JsonPropertyName("serviceObjects")] + public NetworkService[] Services { get; set; } = []; + + [JsonProperty("userObjects"), JsonPropertyName("userObjects")] + public NetworkUser[] Users { get; set; } = []; + + [JsonProperty("zoneObjects"), JsonPropertyName("zoneObjects")] + public NetworkZone[] Zones { get; set; } = []; + + [JsonProperty("reportNetworkObjects"), JsonPropertyName("reportNetworkObjects")] + public NetworkObject[] ReportObjects { get; set; } = []; + + [JsonProperty("reportServiceObjects"), JsonPropertyName("reportServiceObjects")] + public NetworkService[] ReportServices { get; set; } = []; + + [JsonProperty("reportUserObjects"), JsonPropertyName("reportUserObjects")] + public NetworkUser[] ReportUsers { get; set; } = []; + + + //[JsonProperty("rule_id"), JsonPropertyName("rule_id")] + public List ReportedRuleIds { get; set; } = []; + public List ReportedNetworkServiceIds { get; set; } = []; + + [JsonProperty("objects_aggregate"), JsonPropertyName("objects_aggregate")] + public ObjectStatistics NetworkObjectStatistics { get; set; } = new(); + + [JsonProperty("services_aggregate"), JsonPropertyName("services_aggregate")] + public ObjectStatistics ServiceObjectStatistics { get; set; } = new(); + + [JsonProperty("usrs_aggregate"), JsonPropertyName("usrs_aggregate")] + public ObjectStatistics UserObjectStatistics { get; set; } = new(); + + [JsonProperty("rules_aggregate"), JsonPropertyName("rules_aggregate")] + public ObjectStatistics RuleStatistics { get; set; } = new(); + + [JsonProperty("unusedRules_Count"), JsonPropertyName("unusedRules_Count")] + public ObjectStatistics UnusedRulesStatistics { get; set; } = new(); + + public bool Ignore { get; set; } + public List RelevantObjectIds = []; + public List HighlightedObjectIds = []; + + public bool[] Detailed = [false, false, false]; // nobj, nsrv, user + + public ManagementReport() + { + Uid = string.Empty; + } + + + public string NameAndDeviceNames(string separator = ", ") + { + return $"{Name} [{string.Join(separator, Array.ConvertAll(Devices, device => device.Name))}]"; + } + + public string NameAndRulebaseNames(string separator = ", ") + { + return $"{Name} [{string.Join(separator, Array.ConvertAll(Devices, device => device.Name))}]"; + } + + /// + /// Conforms internal data to be valid for further usage. + /// + public void EnforceValidity() + { + if (UnusedRulesStatistics.ObjectAggregate.ObjectCount >= RuleStatistics.ObjectAggregate.ObjectCount) + { + UnusedRulesStatistics.ObjectAggregate.ObjectCount = 0; + } + + foreach (var device in Devices) + { + device.EnforceValidity(); + } + } + + public RulebaseReport? GetNextRulebase(RulebaseLink? currentRbLink) + { + if (currentRbLink == null) + { + return null; + } + return Rulebases + .FirstOrDefault(rb => rb.Id == currentRbLink.NextRulebaseId); + } + + /// + /// Collect all rule ids from contained rulebases. + /// + public List GetAllRuleIds() + { + return Rulebases + .SelectMany(rulebase => rulebase.Rules) + .Select(rule => rule.Id) + .Distinct() + .ToList(); + } + + } + public static class ManagementUtility + { + private static void MergeReportObjects(ManagementReport target, ManagementReport source, Dictionary addedCounts, ref bool newObjects) + { + if (target.ReportObjects != null && source.ReportObjects != null && source.ReportObjects.Length > 0) + { + target.ReportObjects = target.ReportObjects.Concat(source.ReportObjects).ToArray(); + newObjects = true; + addedCounts["ReportObjects"] = source.ReportObjects.Length; + } + + if (target.ReportServices != null && source.ReportServices != null && source.ReportServices.Length > 0) + { + target.ReportServices = target.ReportServices.Concat(source.ReportServices).ToArray(); + newObjects = true; + addedCounts["ReportServices"] = source.ReportServices.Length; + } + + if (target.ReportUsers != null && source.ReportUsers != null && source.ReportUsers.Length > 0) + { + target.ReportUsers = target.ReportUsers.Concat(source.ReportUsers).ToArray(); + newObjects = true; + addedCounts["ReportUsers"] = source.ReportUsers.Length; + } + } + + public static (bool, Dictionary) Merge(this List managementReports, List managementReportsToMerge) + { + bool newObjects = false; + Dictionary maxAddedCounts = new() + { + { "NetworkObjects", 0 }, + { "NetworkServices", 0 }, + { "NetworkUsers", 0 }, + { "Rules", 0 }, + { "RuleChanges", 0 }, + { "ObjectChanges", 0 }, + { "ServiceChanges", 0 }, + { "UserChanges", 0 }, + }; + + foreach (var managementReportToMerge in managementReportsToMerge) + { + ManagementReport? mgmtToFill = managementReports.FirstOrDefault(m => m.Id == managementReportToMerge.Id); + if (mgmtToFill != null) + { + (bool newObjs, Dictionary addedCounts) = mgmtToFill.Merge(managementReportToMerge); + if (newObjs) + { + newObjects = true; + maxAddedCounts["NetworkObjects"] = Math.Max(maxAddedCounts["NetworkObjects"], addedCounts["NetworkObjects"]); + maxAddedCounts["NetworkServices"] = Math.Max(maxAddedCounts["NetworkServices"], addedCounts["NetworkServices"]); + maxAddedCounts["NetworkUsers"] = Math.Max(maxAddedCounts["NetworkUsers"], addedCounts["NetworkUsers"]); + maxAddedCounts["Rules"] = Math.Max(maxAddedCounts["Rules"], addedCounts["Rules"]); + maxAddedCounts["RuleChanges"] = Math.Max(maxAddedCounts["RuleChanges"], addedCounts["RuleChanges"]); + maxAddedCounts["ObjectChanges"] = Math.Max(maxAddedCounts["ObjectChanges"], addedCounts["ObjectChanges"]); + maxAddedCounts["ServiceChanges"] = Math.Max(maxAddedCounts["ServiceChanges"], addedCounts["ServiceChanges"]); + maxAddedCounts["UserChanges"] = Math.Max(maxAddedCounts["UserChanges"], addedCounts["UserChanges"]); + } + } + } + return (newObjects, maxAddedCounts); + } + + public static (bool, Dictionary) Merge(this ManagementReport managementReport, ManagementReport managementReportToMerge) + { + bool newObjects = false; + Dictionary maxAddedCounts = new() + { + { "NetworkObjects", 0 }, + { "NetworkServices", 0 }, + { "NetworkUsers", 0 }, + { "Rules", 0 }, + { "RuleChanges", 0 }, + { "ObjectChanges", 0 }, + { "ServiceChanges", 0 }, + { "UserChanges", 0 }, + }; + + T[] MergeArray(T[]? target, T[]? source, string key) + { + if (source != null && source.Length > 0) + { + target ??= Array.Empty(); // sicherstellen, dass target nicht null ist + newObjects = true; + maxAddedCounts[key] = Math.Max(maxAddedCounts[key], source.Length); + return [.. target, .. source]; + } + return target ?? Array.Empty(); // falls target null, leeres Array zurückgeben + } + + managementReport.Objects = MergeArray(managementReport.Objects, managementReportToMerge.Objects, "NetworkObjects"); + managementReport.Services = MergeArray(managementReport.Services, managementReportToMerge.Services, "NetworkServices"); + managementReport.Users = MergeArray(managementReport.Users, managementReportToMerge.Users, "NetworkUsers"); + managementReport.RuleChanges = MergeArray(managementReport.RuleChanges, managementReportToMerge.RuleChanges, "RuleChanges"); + managementReport.ObjectChanges = MergeArray(managementReport.ObjectChanges, managementReportToMerge.ObjectChanges, "ObjectChanges"); + managementReport.ServiceChanges = MergeArray(managementReport.ServiceChanges, managementReportToMerge.ServiceChanges, "ServiceChanges"); + managementReport.UserChanges = MergeArray(managementReport.UserChanges, managementReportToMerge.UserChanges, "UserChanges"); + + MergeReportObjects(managementReport, managementReportToMerge, maxAddedCounts, ref newObjects); + + foreach (RulebaseReport rulebaseReport in managementReport.Rulebases) + { + if (!managementReportToMerge.Rulebases.Any(rbr => rbr.Id == rulebaseReport.Id)) + throw new NotSupportedException("Cannot merge ManagementReports with different Rulebases."); + RulebaseReport rulebaseReportToMerge = managementReportToMerge.Rulebases.First(rbr => rbr.Id == rulebaseReport.Id); + if (rulebaseReportToMerge.Rules.Length > 0) + { + rulebaseReport.Rules = [.. rulebaseReport.Rules, .. rulebaseReportToMerge.Rules]; + newObjects = true; + maxAddedCounts["Rules"] = Math.Max(maxAddedCounts["Rules"], rulebaseReportToMerge.Rules.Length); + } + } + + return (newObjects, maxAddedCounts); + } + } +} diff --git a/roles/lib/files/FWO.Data/Report/ModellingFilter.cs b/roles/lib/files/FWO.Data/Report/ModellingFilter.cs new file mode 100644 index 0000000000..7175f5d190 --- /dev/null +++ b/roles/lib/files/FWO.Data/Report/ModellingFilter.cs @@ -0,0 +1,48 @@ +namespace FWO.Data.Report +{ + public class ModellingFilter + { + public List SelectedOwners { get; set; } = []; + public FwoOwner SelectedOwner + { + get { return SelectedOwners.FirstOrDefault() ?? new(); } + set { SelectedOwners = [value]; } + } + + public FwoOwner SelectedTemplateOwner { get; set; } = new(); + public bool ShowSourceMatch { get; set; } = true; + public bool ShowDestinationMatch { get; set; } = true; + public bool ShowAnyMatch { get; set; } = false; + public bool ShowFullRules { get; set; } = false; + public bool ShowDropRules { get; set; } = false; + + public bool AnalyseRemainingRules { get; set; } = false; + public bool RulesForDeletedConns { get; set; } = false; + + public bool ShowAllOwners { get; set; } = false; + public bool ShowInactiveRecertOwners { get; set; } = false; + public long? OwnerRecertId { get; set; } + public long? ReportId { get; set; } + + + public ModellingFilter() + { } + + public ModellingFilter(ModellingFilter modellingFilter) + { + SelectedOwners = modellingFilter.SelectedOwners; + SelectedTemplateOwner = modellingFilter.SelectedTemplateOwner; + ShowSourceMatch = modellingFilter.ShowSourceMatch; + ShowDestinationMatch = modellingFilter.ShowDestinationMatch; + ShowAnyMatch = modellingFilter.ShowAnyMatch; + ShowFullRules = modellingFilter.ShowFullRules; + ShowDropRules = modellingFilter.ShowDropRules; + AnalyseRemainingRules = modellingFilter.AnalyseRemainingRules; + RulesForDeletedConns = modellingFilter.RulesForDeletedConns; + ShowAllOwners = modellingFilter.ShowAllOwners; + ShowInactiveRecertOwners = modellingFilter.ShowInactiveRecertOwners; + OwnerRecertId = modellingFilter.OwnerRecertId; + ReportId = modellingFilter.ReportId; + } + } +} diff --git a/roles/lib/files/FWO.Data/Report/OwnerConnectionReport.cs b/roles/lib/files/FWO.Data/Report/OwnerConnectionReport.cs new file mode 100644 index 0000000000..6a1207ef16 --- /dev/null +++ b/roles/lib/files/FWO.Data/Report/OwnerConnectionReport.cs @@ -0,0 +1,63 @@ +using FWO.Data.Modelling; + +namespace FWO.Data.Report +{ + public class OwnerConnectionReport : ConnectionReport + { + public FwoOwner Owner { get; set; } = new(); + public List Connections { get; set; } = []; + public List RegularConnections { get; set; } = []; + public List Interfaces { get; set; } = []; + public List CommonServices { get; set; } = []; + public List UnmodelledRules { get; set; } = []; + public List RulesForDeletedConns { get; set; } = []; + public List RuleDifferences { get; set; } = []; + private readonly long DummyARid = -1; + public int ModelledConnectionsCount { get; set; } + + public Dictionary> MissingAppRoles { get; set; } = []; + public Dictionary> DifferingAppRoles { get; set; } = []; + public AppRoleStats AppRoleStats { get; set; } = new(); + public string ImplementationState { get; set; } = ""; + + + public OwnerConnectionReport() + { } + + public OwnerConnectionReport(long dummyARid) + { + DummyARid = dummyARid; + } + + public OwnerConnectionReport(OwnerConnectionReport report) : base(report) + { + Owner = report.Owner; + Connections = report.Connections; + RegularConnections = report.RegularConnections; + Interfaces = report.Interfaces; + CommonServices = report.CommonServices; + UnmodelledRules = report.UnmodelledRules; + RulesForDeletedConns = report.RulesForDeletedConns; + RuleDifferences = report.RuleDifferences; + DummyARid = report.DummyARid; + ModelledConnectionsCount = report.ModelledConnectionsCount; + AppRoleStats = report.AppRoleStats; + } + + public override List GetAllNetworkObjects(bool resolved = false, bool resolveNetworkAreas = false) + { + return GetAllNetworkObjects(Connections, resolved, resolveNetworkAreas, DummyARid); + } + + public override List GetAllServices(bool resolved = false) + { + return GetAllServices(Connections, resolved); + } + + public void ExtractConnectionsToAnalyse() + { + Connections = [.. Connections.Where(x => x.IsRelevantForVarianceAnalysis(DummyARid)).OrderByDescending(y => y.IsCommonService)]; + ModelledConnectionsCount = Connections.Count; + } + } +} diff --git a/roles/lib/files/FWO.Data/Report/OwnerFilter.cs b/roles/lib/files/FWO.Data/Report/OwnerFilter.cs new file mode 100644 index 0000000000..6ed60427de --- /dev/null +++ b/roles/lib/files/FWO.Data/Report/OwnerFilter.cs @@ -0,0 +1,17 @@ +namespace FWO.Data.Report +{ + public class OwnerFilter + { + public int? SelectedOwnerLifeCycleStateId { get; set; } + public string? SelectedCriticality { get; set; } + + public OwnerFilter() + { } + + public OwnerFilter(OwnerFilter ownerFilter) + { + SelectedOwnerLifeCycleStateId = ownerFilter.SelectedOwnerLifeCycleStateId; + SelectedCriticality = ownerFilter.SelectedCriticality; + } + } +} diff --git a/roles/lib/files/FWO.Data/Report/RecertFilter.cs b/roles/lib/files/FWO.Data/Report/RecertFilter.cs new file mode 100644 index 0000000000..146d829632 --- /dev/null +++ b/roles/lib/files/FWO.Data/Report/RecertFilter.cs @@ -0,0 +1,19 @@ +namespace FWO.Data.Report +{ + public class RecertFilter + { + public List RecertOwnerList { get; set; } = []; + public bool RecertShowAnyMatch { get; set; } = false; + public int RecertificationDisplayPeriod { get; set; } = 0; + + public RecertFilter() + { } + + public RecertFilter(RecertFilter recertFilter) + { + RecertOwnerList = [.. recertFilter.RecertOwnerList]; + RecertShowAnyMatch = recertFilter.RecertShowAnyMatch; + RecertificationDisplayPeriod = recertFilter.RecertificationDisplayPeriod; + } + } +} diff --git a/roles/lib/files/FWO.Data/Report/ReportData.cs b/roles/lib/files/FWO.Data/Report/ReportData.cs new file mode 100644 index 0000000000..890c40e487 --- /dev/null +++ b/roles/lib/files/FWO.Data/Report/ReportData.cs @@ -0,0 +1,40 @@ +using FWO.Basics.Interfaces; +using FWO.Data.Workflow; + +namespace FWO.Data.Report +{ + public class ReportData + { + public List ManagementData { get; set; } = []; + public List OwnerData { get; set; } = []; + public List GlobalComSvc { get; set; } = []; + public ManagementReport GlobalStats { get; set; } = new(); + /// + /// Gets or sets the workflow tickets contained in a workflow report. + /// + public List Tickets { get; set; } = []; + public Dictionary TicketReferenceDates { get; set; } = []; + public Dictionary WorkflowStateNames { get; set; } = []; + public WorkflowFilter WorkflowFilter { get; set; } = new(); + public List RulesFlat = []; + public IEnumerable RuleViewData = []; + public int ElementsCount { get; set; } + public int RecertificationDisplayPeriod { get; set; } = 0; + + public ReportData() + { } + + public ReportData(ReportData reportData) + { + ManagementData = reportData.ManagementData; + OwnerData = reportData.OwnerData; + GlobalComSvc = reportData.GlobalComSvc; + GlobalStats = reportData.GlobalStats; + Tickets = reportData.Tickets; + TicketReferenceDates = reportData.TicketReferenceDates; + WorkflowStateNames = reportData.WorkflowStateNames; + WorkflowFilter = reportData.WorkflowFilter; + RecertificationDisplayPeriod = reportData.RecertificationDisplayPeriod; + } + } +} diff --git a/roles/lib/files/FWO.Api.Client/Data/ReportFile.cs b/roles/lib/files/FWO.Data/Report/ReportFile.cs similarity index 76% rename from roles/lib/files/FWO.Api.Client/Data/ReportFile.cs rename to roles/lib/files/FWO.Data/Report/ReportFile.cs index 6acde08c93..1f3835d97b 100644 --- a/roles/lib/files/FWO.Api.Client/Data/ReportFile.cs +++ b/roles/lib/files/FWO.Data/Report/ReportFile.cs @@ -1,7 +1,9 @@ -using System.Text.Json.Serialization; +using FWO.Basics; using Newtonsoft.Json; +using System.Text.Json.Serialization; -namespace FWO.Api.Data + +namespace FWO.Data.Report { public class ReportFile { @@ -18,16 +20,16 @@ public class ReportFile public DateTime GenerationDateEnd { get; set; } [JsonProperty("report_template"), JsonPropertyName("report_template")] - public ReportTemplate Template { get; set; } = new ReportTemplate(); + public ReportTemplate Template { get; set; } = new(); [JsonProperty("report_template_id"), JsonPropertyName("report_template_id")] public int TemplateId { get; set; } [JsonProperty("uiuser"), JsonPropertyName("uiuser")] - public UiUser Owner { get; set; } = new UiUser(); + public UiUser ReportOwningUser { get; set; } = new(); [JsonProperty("report_owner_id"), JsonPropertyName("report_owner_id")] - public int OwnerId { get; set; } + public int OwningUserId { get; set; } [JsonProperty("report_json"), JsonPropertyName("report_json")] public string? Json { get; set; } @@ -47,10 +49,16 @@ public class ReportFile [JsonProperty("description"), JsonPropertyName("description")] public String? Description { get; set; } + [JsonProperty("read_only"), JsonPropertyName("read_only")] + public bool ReadOnly { get; set; } = false; + + [JsonProperty("owner"), JsonPropertyName("owner")] + public FwoOwner? Owner { get; set; } + public bool Sanitize() { bool shortened = false; - Name = Sanitizer.SanitizeMand(Name, ref shortened); + Name = Name.SanitizeMand(ref shortened); return shortened; } } diff --git a/roles/lib/files/FWO.Data/Report/ReportSchedule.cs b/roles/lib/files/FWO.Data/Report/ReportSchedule.cs new file mode 100644 index 0000000000..02268cb4bb --- /dev/null +++ b/roles/lib/files/FWO.Data/Report/ReportSchedule.cs @@ -0,0 +1,54 @@ +using FWO.Basics; +using FWO.Data; +using Newtonsoft.Json; +using System.Text.Json.Serialization; + + +namespace FWO.Data.Report +{ + public class ReportSchedule + { + [JsonProperty("report_schedule_id"), JsonPropertyName("report_schedule_id")] + public int Id { get; set; } + + [JsonProperty("report_schedule_name"), JsonPropertyName("report_schedule_name")] + public string Name { get; set; } = ""; + + [JsonProperty("report_schedule_owner_user"), JsonPropertyName("report_schedule_owner_user")] + public UiUser ScheduleOwningUser { get; set; } = new(); + + [JsonProperty("report_schedule_start_time"), JsonPropertyName("report_schedule_start_time")] + public DateTime StartTime { get; set; } = DateTime.Now.AddSeconds(-DateTime.Now.Second); + + [JsonProperty("report_schedule_repeat"), JsonPropertyName("report_schedule_repeat")] + public int RepeatOffset { get; set; } = 1; + + [JsonProperty("report_schedule_every"), JsonPropertyName("report_schedule_every")] + public SchedulerInterval RepeatInterval { get; set; } + + [JsonProperty("report_schedule_template"), JsonPropertyName("report_schedule_template")] + public ReportTemplate Template { get; set; } = new(); + + [JsonProperty("report_schedule_formats"), JsonPropertyName("report_schedule_formats")] + public List OutputFormat { get; set; } = []; + + [JsonProperty("report_schedule_active"), JsonPropertyName("report_schedule_active")] + public bool Active { get; set; } = true; + + [JsonProperty("report_schedule_counter"), JsonPropertyName("report_schedule_counter")] + public int Counter { get; set; } + + [JsonProperty("archive"), JsonPropertyName("archive")] + public bool Archive { get; set; } + + [JsonProperty("notifications"), JsonPropertyName("notifications")] + public List Notifications { get; set; } = []; + + public bool Sanitize() + { + bool shortened = false; + Name = Name.SanitizeMand(ref shortened); + return shortened; + } + } +} diff --git a/roles/lib/files/FWO.Data/Report/ReportTemplate.cs b/roles/lib/files/FWO.Data/Report/ReportTemplate.cs new file mode 100644 index 0000000000..8a07c3cf6d --- /dev/null +++ b/roles/lib/files/FWO.Data/Report/ReportTemplate.cs @@ -0,0 +1,95 @@ +using FWO.Basics; +using Newtonsoft.Json; +using System.Text.Json.Serialization; + +namespace FWO.Data.Report +{ + public class ReportTemplate + { + [JsonProperty("report_template_id"), JsonPropertyName("report_template_id")] + public int Id { get; set; } + + [JsonProperty("report_template_name"), JsonPropertyName("report_template_name")] + public string Name { get; set; } = ""; + + [JsonProperty("report_template_create"), JsonPropertyName("report_template_create")] + public DateTime CreationDate { get; set; } + + [JsonProperty("report_template_comment"), JsonPropertyName("report_template_comment")] + public string Comment { get; set; } = ""; + + [JsonProperty("report_template_owner"), JsonPropertyName("report_template_owner")] + public int TemplateOwningUserId { get; set; } + + [JsonProperty("report_filter"), JsonPropertyName("report_filter")] + public string Filter { get; set; } = ""; + + [JsonProperty("report_parameters"), JsonPropertyName("report_parameters")] + public ReportParams ReportParams { get; set; } = new(); + + public bool Detailed { get; set; } = false; + + public ReportTemplate() + { } + + public ReportTemplate(string filter, ReportParams reportParams) + { + Filter = filter; + ReportParams = reportParams; + Detailed = false; + } + + public bool Sanitize() + { + bool shortened = false; + Name = Name.SanitizeMand(ref shortened); + Comment = Comment.SanitizeMand(ref shortened); + return shortened; + } + } + + public class ReportParams + { + [JsonProperty("report_type"), JsonPropertyName("report_type")] + public int ReportType { get; set; } = 0; + + [JsonProperty("include_objects"), JsonPropertyName("include_objects")] + public bool IncludeObjects { get; set; } = false; + + [JsonProperty("device_filter"), JsonPropertyName("device_filter")] + public DeviceFilter DeviceFilter { get; set; } = new(); + + [JsonProperty("time_filter"), JsonPropertyName("time_filter")] + public TimeFilter TimeFilter { get; set; } = new(); + + [JsonProperty("tenant_filter"), JsonPropertyName("tenant_filter")] + public TenantFilter TenantFilter { get; set; } = new(); + + [JsonProperty("recert_filter"), JsonPropertyName("recert_filter")] + public RecertFilter RecertFilter { get; set; } = new(); + + [JsonProperty("unused_filter"), JsonPropertyName("unused_filter")] + public UnusedFilter UnusedFilter { get; set; } = new(); + + [JsonProperty("modelling_filter"), JsonPropertyName("modelling_filter")] + public ModellingFilter ModellingFilter { get; set; } = new(); + + [JsonProperty("owner_filter"), JsonPropertyName("owner_filter")] + public OwnerFilter OwnerFilter { get; set; } = new(); + + [JsonProperty("compliance_filter"), JsonPropertyName("compliance_filter")] + public ComplianceFilter ComplianceFilter { get; set; } = new(); + + [JsonProperty("workflow_filter"), JsonPropertyName("workflow_filter")] + public WorkflowFilter WorkflowFilter { get; set; } = new(); + + public ReportParams() + { } + + public ReportParams(int reportType, DeviceFilter deviceFilter) + { + ReportType = reportType; + DeviceFilter = deviceFilter; + } + } +} diff --git a/roles/lib/files/FWO.Data/Report/RulebaseReport.cs b/roles/lib/files/FWO.Data/Report/RulebaseReport.cs new file mode 100644 index 0000000000..953ff3a4ce --- /dev/null +++ b/roles/lib/files/FWO.Data/Report/RulebaseReport.cs @@ -0,0 +1,26 @@ +using Newtonsoft.Json; +using System.Text.Json.Serialization; + +namespace FWO.Data.Report +{ + public class RulebaseReport + { + [JsonProperty("id"), JsonPropertyName("id")] + public int Id { get; set; } + + [JsonProperty("name"), JsonPropertyName("name")] + public string? Name { get; set; } + + [JsonProperty("changelog_rules"), JsonPropertyName("changelog_rules")] + public RuleChange[]? RuleChanges { get; set; } + + [JsonProperty("rules_aggregate"), JsonPropertyName("rules_aggregate")] + public ObjectStatistics RuleStatistics { get; set; } = new ObjectStatistics(); + + [JsonProperty("rules"), JsonPropertyName("rules")] + public Rule[] Rules { get; set; } = []; + + public RulebaseReport() + { } + } +} diff --git a/roles/lib/files/FWO.Data/Report/TenantFilter.cs b/roles/lib/files/FWO.Data/Report/TenantFilter.cs new file mode 100644 index 0000000000..b702ac593c --- /dev/null +++ b/roles/lib/files/FWO.Data/Report/TenantFilter.cs @@ -0,0 +1,30 @@ +using System.Text.Json.Serialization; +using FWO.Basics; +using Newtonsoft.Json; + +namespace FWO.Data.Report +{ + public class TenantFilter + { + [JsonProperty("is_active"), JsonPropertyName("is_active")] + public bool IsActive { get; set; } = false; + + [JsonProperty("tenant_id"), JsonPropertyName("tenant_id")] + public int TenantId { get; set; } + + public TenantFilter() + { } + + public TenantFilter(TenantFilter tenantFilter) + { + IsActive = tenantFilter.IsActive; + TenantId = tenantFilter.TenantId; + } + + public TenantFilter(Tenant? tenant) + { + IsActive = tenant?.Id > GlobalConst.kTenant0Id; + TenantId = tenant?.Id ?? 0; + } + } +} diff --git a/roles/lib/files/FWO.Data/Report/TimeFilter.cs b/roles/lib/files/FWO.Data/Report/TimeFilter.cs new file mode 100644 index 0000000000..17856e48e6 --- /dev/null +++ b/roles/lib/files/FWO.Data/Report/TimeFilter.cs @@ -0,0 +1,84 @@ +using System.Text.Json.Serialization; +using Newtonsoft.Json; + + +namespace FWO.Data.Report +{ + public enum TimeRangeType + { + Shortcut = 0, + Interval = 1, + Fixeddates = 2 + } + + public class TimeRangeShortcuts + { + // of course an enum would be better, but there are already values with blanks in the database + public static List Ranges = + [ + "this year", + "last year", + "this month", + "last month", + "this week", + "last week", + "today", + "yesterday" + ]; + } + + public class TimeFilter + { + [JsonProperty("is_shortcut"), JsonPropertyName("is_shortcut")] + public bool IsShortcut { get; set; } = true; + + [JsonProperty("shortcut"), JsonPropertyName("shortcut")] + public string TimeShortcut { get; set; } = "now"; + + [JsonProperty("report_time"), JsonPropertyName("report_time")] + public DateTime ReportTime { get; set; } = DateTime.Now.AddSeconds(-DateTime.Now.Second); + + [JsonProperty("timerange_type"), JsonPropertyName("timerange_type")] + public TimeRangeType TimeRangeType { get; set; } = TimeRangeType.Shortcut; + + [JsonProperty("shortcut_range"), JsonPropertyName("shortcut_range")] + public string TimeRangeShortcut { get; set; } = "this year"; + + [JsonProperty("offset"), JsonPropertyName("offset")] + // Number of interval units (days/weeks/months/years) to shift relative time windows. + public int Offset { get; set; } = 0; + + [JsonProperty("interval"), JsonPropertyName("interval")] + public SchedulerInterval Interval { get; set; } = SchedulerInterval.Days; + + [JsonProperty("start_time"), JsonPropertyName("start_time")] + public DateTime StartTime { get; set; } = DateTime.Now.AddSeconds(-DateTime.Now.Second); + + [JsonProperty("open_start"), JsonPropertyName("open_start")] + public bool OpenStart { get; set; } = false; + + [JsonProperty("end_time"), JsonPropertyName("end_time")] + public DateTime EndTime { get; set; } = DateTime.Now.AddSeconds(-DateTime.Now.Second); + + [JsonProperty("open_end"), JsonPropertyName("open_end")] + public bool OpenEnd { get; set; } = false; + + public TimeFilter() + { } + + public TimeFilter(TimeFilter source) + { + IsShortcut = source.IsShortcut; + TimeShortcut = source.TimeShortcut; + ReportTime = source.ReportTime; + TimeRangeType = source.TimeRangeType; + TimeRangeShortcut = source.TimeRangeShortcut; + Offset = source.Offset; + Interval = source.Interval; + StartTime = source.StartTime; + OpenStart = source.OpenStart; + EndTime = source.EndTime; + OpenEnd = source.OpenEnd; + } + } +} diff --git a/roles/lib/files/FWO.Api.Client/Data/UnusedFilter.cs b/roles/lib/files/FWO.Data/Report/UnusedFilter.cs similarity index 84% rename from roles/lib/files/FWO.Api.Client/Data/UnusedFilter.cs rename to roles/lib/files/FWO.Data/Report/UnusedFilter.cs index 83d65ed9b8..9db13cd913 100644 --- a/roles/lib/files/FWO.Api.Client/Data/UnusedFilter.cs +++ b/roles/lib/files/FWO.Data/Report/UnusedFilter.cs @@ -1,4 +1,4 @@ -namespace FWO.Api.Data +namespace FWO.Data.Report { public class UnusedFilter { diff --git a/roles/lib/files/FWO.Data/Report/WorkflowFilter.cs b/roles/lib/files/FWO.Data/Report/WorkflowFilter.cs new file mode 100644 index 0000000000..f5ee22e947 --- /dev/null +++ b/roles/lib/files/FWO.Data/Report/WorkflowFilter.cs @@ -0,0 +1,121 @@ +using Newtonsoft.Json; +using System.Text.Json.Serialization; +using FWO.Data.Workflow; + +namespace FWO.Data.Report +{ + public enum WorkflowReferenceDate + { + TicketCreation, + TicketClosure, + ApprovalOpened, + Approved, + TaskStart, + TaskEnd, + ImplementationStart, + ImplementationEnd, + AnyActivity + } + + internal static class WorkflowReferenceDateSerialization + { + public static WorkflowReferenceDate Parse(string? value) + { + if (string.IsNullOrWhiteSpace(value)) + { + return WorkflowReferenceDate.AnyActivity; + } + + if (Enum.TryParse(value.Trim(), true, out WorkflowReferenceDate referenceDate)) + { + return referenceDate; + } + + throw new JsonException($"Unknown workflow reference date '{value}'."); + } + + public static string Format(WorkflowReferenceDate value) + { + return value.ToString(); + } + } + + public enum WorkflowLabelFilterMode + { + not_existing, + existing, + value + } + + public class WorkflowLabelFilter + { + [JsonProperty("name"), JsonPropertyName("name")] + public string Name { get; set; } = ""; + + [JsonProperty("mode"), JsonPropertyName("mode")] + public WorkflowLabelFilterMode Mode { get; set; } = WorkflowLabelFilterMode.existing; + + [JsonProperty("value"), JsonPropertyName("value")] + public string Value { get; set; } = ""; + + public WorkflowLabelFilter() + { } + + public WorkflowLabelFilter(WorkflowLabelFilter workflowLabelFilter) + { + Name = workflowLabelFilter.Name; + Mode = workflowLabelFilter.Mode; + Value = workflowLabelFilter.Value; + } + } + + public class WorkflowFilter + { + [JsonProperty("reference_date"), JsonPropertyName("reference_date")] + public string ReferenceDateRaw { get; set; } = WorkflowReferenceDateSerialization.Format(WorkflowReferenceDate.AnyActivity); + + [Newtonsoft.Json.JsonIgnore, System.Text.Json.Serialization.JsonIgnore] + public WorkflowReferenceDate ReferenceDate + { + get => WorkflowReferenceDateSerialization.Parse(ReferenceDateRaw); + set => ReferenceDateRaw = WorkflowReferenceDateSerialization.Format(value); + } + + [JsonProperty("task_types"), JsonPropertyName("task_types")] + public List TaskTypes { get; set; } = DefaultTaskTypes(); + + [JsonProperty("state_ids"), JsonPropertyName("state_ids")] + public List StateIds { get; set; } = []; + + [JsonProperty("phase"), JsonPropertyName("phase")] + public string Phase { get; set; } = ""; + + [JsonProperty("label_filter"), JsonPropertyName("label_filter")] + public WorkflowLabelFilter LabelFilter { get; set; } = new(); + + [JsonProperty("detailed_view"), JsonPropertyName("detailed_view")] + public bool DetailedView { get; set; } = false; + + [JsonProperty("show_full_ticket"), JsonPropertyName("show_full_ticket")] + public bool ShowFullTicket { get; set; } = false; + + public WorkflowFilter() + { } + + public WorkflowFilter(WorkflowFilter workflowFilter) + { + ReferenceDate = workflowFilter.ReferenceDate; + TaskTypes = workflowFilter.TaskTypes.Count > 0 ? [.. workflowFilter.TaskTypes] : DefaultTaskTypes(); + StateIds = [.. workflowFilter.StateIds]; + Phase = workflowFilter.Phase; + LabelFilter = new(workflowFilter.LabelFilter); + DetailedView = workflowFilter.DetailedView; + ShowFullTicket = workflowFilter.ShowFullTicket; + } + + private static List DefaultTaskTypes() + { + return [.. Enum.GetValues(typeof(WfTaskType)).Cast().Where(taskType => taskType != WfTaskType.master)]; + } + } +} diff --git a/roles/lib/files/FWO.Data/Role.cs b/roles/lib/files/FWO.Data/Role.cs new file mode 100644 index 0000000000..75a1606bc0 --- /dev/null +++ b/roles/lib/files/FWO.Data/Role.cs @@ -0,0 +1,45 @@ + +namespace FWO.Data +{ + public class Role + { + public string Name { get; set; } = ""; + public string Dn { get; set; } = ""; + public string Description { get; set; } = ""; + public List Users { get; set; } + + public Role() + { + Users = []; + } + + public Role(Role role) + { + Name = role.Name; + Dn = role.Dn; + Description = role.Description; + Users = new(role.Users); + } + + private static string DisplayUserName(string name) + { + // replace encoded comma with real comma for displaying + // also put name in square brackets if it contains commas + if (name.Contains("\\2c", StringComparison.OrdinalIgnoreCase)) + { + return $"[{name.Replace("\\2c", ",", StringComparison.OrdinalIgnoreCase)}]"; + } + return name; + } + + public string UserList() + { + List userNames = []; + foreach (UiUser user in Users) + { + userNames.Add(DisplayUserName(new DistName(user.Dn).UserName)); + } + return string.Join(", ", userNames); + } + } +} diff --git a/roles/lib/files/FWO.Data/Rule.cs b/roles/lib/files/FWO.Data/Rule.cs new file mode 100644 index 0000000000..d5016cb7bd --- /dev/null +++ b/roles/lib/files/FWO.Data/Rule.cs @@ -0,0 +1,257 @@ +using FWO.Basics; +using System.Text.Json.Serialization; +using Newtonsoft.Json; +using SystemTextJsonIgnore = System.Text.Json.Serialization.JsonIgnoreAttribute; + +namespace FWO.Data +{ + public class Rule + { + [JsonProperty("rule_id"), JsonPropertyName("rule_id")] + public long Id { get; set; } + + [JsonProperty("rule_uid"), JsonPropertyName("rule_uid")] + public string? Uid { get; set; } = ""; + + [JsonProperty("mgm_id"), JsonPropertyName("mgm_id")] + public int MgmtId { get; set; } + + [JsonProperty("rule_num_numeric"), JsonPropertyName("rule_num_numeric")] + public double OrderNumber { get; set; } + + [JsonProperty("rule_name"), JsonPropertyName("rule_name")] + public string? Name { get; set; } = ""; + + [JsonProperty("rule_comment"), JsonPropertyName("rule_comment")] + public string? Comment { get; set; } = ""; + + [JsonProperty("rule_disabled"), JsonPropertyName("rule_disabled")] + public bool Disabled { get; set; } + + [JsonProperty("rule_services"), JsonPropertyName("rule_services")] + public ServiceWrapper[] Services { get; set; } = []; + + [JsonProperty("rule_svc_neg"), JsonPropertyName("rule_svc_neg")] + public bool ServiceNegated { get; set; } + + [JsonProperty("rule_svc"), JsonPropertyName("rule_svc")] + public string Service { get; set; } = ""; + + [JsonProperty("rule_svc_refs"), JsonPropertyName("rule_svc_refs")] + public string ServiceRefs { get; set; } = ""; + + [JsonProperty("rule_src_neg"), JsonPropertyName("rule_src_neg")] + public bool SourceNegated { get; set; } + + [JsonProperty("rule_src"), JsonPropertyName("rule_src")] + public string Source { get; set; } = ""; + + [JsonProperty("rule_src_refs"), JsonPropertyName("rule_src_refs")] + public string SourceRefs { get; set; } = ""; + + [JsonProperty("rule_from_zones"), JsonPropertyName("rule_from_zones")] + public ZoneWrapper[] RuleFromZones { get; set; } = []; + + [JsonProperty("rule_froms"), JsonPropertyName("rule_froms")] + public NetworkLocation[] Froms { get; set; } = []; + + [JsonProperty("rule_dst_neg"), JsonPropertyName("rule_dst_neg")] + public bool DestinationNegated { get; set; } + + [JsonProperty("rule_dst"), JsonPropertyName("rule_dst")] + public string Destination { get; set; } = ""; + + [JsonProperty("rule_dst_refs"), JsonPropertyName("rule_dst_refs")] + public string DestinationRefs { get; set; } = ""; + + [JsonProperty("rule_to_zones"), JsonPropertyName("rule_to_zones")] + public ZoneWrapper[] RuleToZones { get; set; } = []; + + [JsonProperty("rule_tos"), JsonPropertyName("rule_tos")] + public NetworkLocation[] Tos { get; set; } = []; + + [JsonProperty("rule_action"), JsonPropertyName("rule_action")] + public string Action { get; set; } = ""; + + [JsonProperty("rule_track"), JsonPropertyName("rule_track")] + public string Track { get; set; } = ""; + + [JsonProperty("section_header"), JsonPropertyName("section_header")] + public string? SectionHeader { get; set; } = ""; + + [JsonProperty("rule_metadatum"), JsonPropertyName("rule_metadatum")] + public RuleMetadata Metadata { get; set; } = new(); + + [SystemTextJsonIgnore] + [JsonProperty("rule_last_seen"), JsonPropertyName("rule_last_seen")] + public long? LastSeenImportId { get; set; } + + [SystemTextJsonIgnore] + [JsonProperty("importControlByRuleLastSeen"), JsonPropertyName("importControlByRuleLastSeen")] + public ImportControl? LastSeenImport { get; set; } + + [SystemTextJsonIgnore] + [JsonProperty("createdImport"), JsonPropertyName("createdImport")] + public ImportControl? CreatedImport { get; set; } + + [SystemTextJsonIgnore] + public DateTime? LastModified => LastSeenImport?.StartTime ?? Metadata?.Created; + + [JsonProperty("translate"), JsonPropertyName("translate")] + public NatData NatData { get; set; } = new(); + + [JsonProperty("owner_name"), JsonPropertyName("owner_name")] + public string OwnerName { get; set; } = ""; + + [JsonProperty("owner_id"), JsonPropertyName("owner_id")] + public int? OwnerId { get; set; } + + [JsonProperty("matches"), JsonPropertyName("matches")] + public string IpMatch { get; set; } = ""; + + [JsonProperty("rule_custom_fields"), JsonPropertyName("rule_custom_fields")] + public string CustomFields { get; set; } = ""; + + [JsonProperty("rule_implied"), JsonPropertyName("rule_implied")] + public bool Implied { get; set; } + + [JsonProperty("nat_rule"), JsonPropertyName("nat_rule")] + public bool NatRule { get; set; } + + [JsonProperty("rulebase_id"), JsonPropertyName("rulebase_id")] + public int RulebaseId { get; set; } + + [JsonProperty("rule_num"), JsonPropertyName("rule_num")] + public int RuleOrderNumber { get; set; } + + [JsonProperty("rule_enforced_on_gateways"), JsonPropertyName("rule_enforced_on_gateways")] + public DeviceWrapper[] EnforcingGateways { get; set; } = []; + + [JsonProperty("rule_installon"), JsonPropertyName("rule_installon")] + public string? InstallOn { get; set; } + + [JsonProperty("rule_time"), JsonPropertyName("rule_time")] + public string? Time { get; set; } + + [JsonProperty("rule_times"), JsonPropertyName("rule_times")] + public List RuleTimes { get; set; } = []; + + [JsonProperty("violations"), JsonPropertyName("violations")] + public List Violations { get; set; } = []; + + [JsonProperty("rulebase"), JsonPropertyName("rulebase")] + public Rulebase Rulebase { get; set; } = new(); + + [JsonProperty("uiuser"), JsonPropertyName("uiuser")] + public UiUser? LastChangeAdmin { get; set; } + + [JsonProperty("rule"), JsonPropertyName("rule")] + public Rule? ParentRule { get; set; } + + [JsonProperty("rule_owners"), JsonPropertyName("rule_owners")] + public RuleOwner?[] RuleOwner { get; set; } = []; + + public string ChangeID { get; set; } = ""; + public string AdoITID { get; set; } = ""; + + public ComplianceViolationType Compliance { get; set; } = ComplianceViolationType.None; + public string ViolationDetails { get; set; } = ""; + + public string DisplayOrderNumberString { get; set; } = ""; + public int DisplayOrderNumber { get; set; } + public bool Certified { get; set; } + public string ManagementName = ""; + public string DeviceName { get; set; } = ""; + public string RulebaseName { get; set; } = ""; + public NetworkLocation[] DisregardedFroms { get; set; } = []; + public NetworkLocation[] DisregardedTos { get; set; } = []; + public NetworkService[] DisregardedServices { get; set; } = []; + public bool ShowDisregarded { get; set; } = false; + public long ConnId; + public bool ModellFound = false; + public bool ModellOk = false; + public bool Detailed = false; + public List UnusedSpecialUserObjects = []; + public List UnusedUpdatableObjects = []; + + public Rule() + { } + + public Rule(Rule rule) + { + Id = rule.Id; + Uid = rule.Uid; + MgmtId = rule.MgmtId; + OrderNumber = rule.OrderNumber; + Name = rule.Name; + Comment = rule.Comment; + Disabled = rule.Disabled; + Services = rule.Services; + ServiceNegated = rule.ServiceNegated; + Service = rule.Service; + SourceNegated = rule.SourceNegated; + Source = rule.Source; + SourceRefs = rule.SourceRefs; + RuleFromZones = rule.RuleFromZones; + Froms = rule.Froms; + DestinationNegated = rule.DestinationNegated; + Destination = rule.Destination; + DestinationRefs = rule.DestinationRefs; + RuleToZones = rule.RuleToZones; + Tos = rule.Tos; + Action = rule.Action; + Track = rule.Track; + SectionHeader = rule.SectionHeader; + Metadata = rule.Metadata; + NatData = rule.NatData; + OwnerName = rule.OwnerName; + OwnerId = rule.OwnerId; + IpMatch = rule.IpMatch; + CustomFields = rule.CustomFields; + Implied = rule.Implied; + NatRule = rule.NatRule; + RulebaseId = rule.RulebaseId; + RuleOrderNumber = rule.RuleOrderNumber; + EnforcingGateways = rule.EnforcingGateways; + InstallOn = rule.InstallOn; + Time = rule.Time; + RuleTimes = rule.RuleTimes; + Violations = rule.Violations; + Rulebase = rule.Rulebase; + LastChangeAdmin = rule.LastChangeAdmin; + ParentRule = rule.ParentRule; + DisplayOrderNumberString = rule.DisplayOrderNumberString; + DisplayOrderNumber = rule.DisplayOrderNumber; + Certified = rule.Certified; + ManagementName = rule.ManagementName; + DeviceName = rule.DeviceName; + RulebaseName = rule.RulebaseName; + DisregardedFroms = rule.DisregardedFroms; + DisregardedTos = rule.DisregardedTos; + DisregardedServices = rule.DisregardedServices; + ShowDisregarded = rule.ShowDisregarded; + ConnId = rule.ConnId; + ModellFound = rule.ModellFound; + ModellOk = rule.ModellOk; + Detailed = rule.Detailed; + UnusedSpecialUserObjects = rule.UnusedSpecialUserObjects; + UnusedUpdatableObjects = rule.UnusedUpdatableObjects; + } + + public bool IsDropRule() + { + return Action == RuleActions.Drop || Action == RuleActions.Reject || Action == RuleActions.Deny; + } + + /// + /// Creates an exact copy of this rule. Returns new rule on fail. + /// + public Rule CreateClone() + { + var json = JsonConvert.SerializeObject(this); + Rule rule = JsonConvert.DeserializeObject(json) ?? new(); + + return rule; + } + } +} diff --git a/roles/lib/files/FWO.Api.Client/Data/RuleAction.cs b/roles/lib/files/FWO.Data/RuleAction.cs similarity index 82% rename from roles/lib/files/FWO.Api.Client/Data/RuleAction.cs rename to roles/lib/files/FWO.Data/RuleAction.cs index 579c9316b3..ed4c7510de 100644 --- a/roles/lib/files/FWO.Api.Client/Data/RuleAction.cs +++ b/roles/lib/files/FWO.Data/RuleAction.cs @@ -1,7 +1,7 @@ -using System.Text.Json.Serialization; +using System.Text.Json.Serialization; using Newtonsoft.Json; -namespace FWO.Api.Data +namespace FWO.Data { public class RuleAction { diff --git a/roles/lib/files/FWO.Api.Client/Data/RuleChange.cs b/roles/lib/files/FWO.Data/RuleChange.cs similarity index 82% rename from roles/lib/files/FWO.Api.Client/Data/RuleChange.cs rename to roles/lib/files/FWO.Data/RuleChange.cs index 10fe3e2efd..41c3273ec6 100644 --- a/roles/lib/files/FWO.Api.Client/Data/RuleChange.cs +++ b/roles/lib/files/FWO.Data/RuleChange.cs @@ -1,7 +1,7 @@ -using System.Text.Json.Serialization; +using System.Text.Json.Serialization; using Newtonsoft.Json; -namespace FWO.Api.Data +namespace FWO.Data { public class RuleChange { @@ -17,6 +17,6 @@ public class RuleChange [JsonProperty("new"), JsonPropertyName("new")] public Rule NewRule { get; set; } = new Rule(); - public string DeviceName { get; set; } = ""; + public string RulebaseName { get; set; } = ""; } } diff --git a/roles/lib/files/FWO.Data/RuleMetadata.cs b/roles/lib/files/FWO.Data/RuleMetadata.cs new file mode 100644 index 0000000000..bc9b0b0142 --- /dev/null +++ b/roles/lib/files/FWO.Data/RuleMetadata.cs @@ -0,0 +1,75 @@ +using System.Linq; +using System.Text.Json.Serialization; +using Newtonsoft.Json; +using NewtonsoftJsonIgnore = Newtonsoft.Json.JsonIgnoreAttribute; +using SystemTextJsonIgnore = System.Text.Json.Serialization.JsonIgnoreAttribute; + +namespace FWO.Data +{ + public class RuleMetadata + { + [JsonProperty("rule_metadata_id"), JsonPropertyName("rule_metadata_id")] + public long Id { get; set; } + + [JsonProperty("rule_created"), JsonPropertyName("rule_created")] + public long? CreatedImportId { get; set; } + + [JsonProperty("created_import"), JsonPropertyName("created_import")] + public ImportControl? CreatedImport { get; set; } + + [JsonProperty("removed"), JsonPropertyName("removed")] + public long? RemovedImportId { get; set; } + + [JsonProperty("removed_import"), JsonPropertyName("removed_import")] + public ImportControl? RemovedImport { get; set; } + + [JsonProperty("rule_first_hit"), JsonPropertyName("rule_first_hit")] + public DateTime? FirstHit { get; set; } + + private DateTime? lastHit; + + [JsonProperty("rule_last_hit"), JsonPropertyName("rule_last_hit")] + public DateTime? LastHit + { + get => lastHit; + set => lastHit = value.HasValue && value.Value.Kind == DateTimeKind.Unspecified + ? DateTime.SpecifyKind(value.Value, DateTimeKind.Utc) + : value; + } + + [JsonProperty("recertification"), JsonPropertyName("recertification")] + public List RuleRecertification { get; set; } = []; + + [JsonProperty("recert_history"), JsonPropertyName("recert_history")] + public List RecertHistory { get; set; } = []; + + [JsonProperty("rule_uid"), JsonPropertyName("rule_uid")] + public string? Uid { get; set; } = ""; + + [JsonProperty("rules"), JsonPropertyName("rules")] + public Rule[] Rules { get; set; } = []; + + [SystemTextJsonIgnore, NewtonsoftJsonIgnore] + public DateTime? Created => CreatedImport?.StartTime; + + [SystemTextJsonIgnore, NewtonsoftJsonIgnore] + public DateTime? Removed => RemovedImport?.StartTime; + + [SystemTextJsonIgnore, NewtonsoftJsonIgnore] + public string Comment => RecertHistory.OrderByDescending(r => r.RecertDate).FirstOrDefault()?.Comment ?? ""; + + [SystemTextJsonIgnore, NewtonsoftJsonIgnore] + public DateTime? LastCertified => RecertHistory.Where(r => r.Recertified) + .OrderByDescending(r => r.RecertDate).FirstOrDefault()?.RecertDate; + + [SystemTextJsonIgnore, NewtonsoftJsonIgnore] + public DateTime? DecertificationDate => RecertHistory.Where(r => !r.Recertified) + .OrderByDescending(r => r.RecertDate).FirstOrDefault()?.RecertDate; + + [SystemTextJsonIgnore, NewtonsoftJsonIgnore] + public bool ToBeRemoved { get; set; } + + + public bool Recert { get; set; } + } +} diff --git a/roles/lib/files/FWO.Data/RuleOwner.cs b/roles/lib/files/FWO.Data/RuleOwner.cs new file mode 100644 index 0000000000..3005a885d9 --- /dev/null +++ b/roles/lib/files/FWO.Data/RuleOwner.cs @@ -0,0 +1,58 @@ +using System.Linq; +using System.Text.Json.Serialization; +using Newtonsoft.Json; +using NewtonsoftJsonIgnore = Newtonsoft.Json.JsonIgnoreAttribute; +using SystemTextJsonIgnore = System.Text.Json.Serialization.JsonIgnoreAttribute; + +namespace FWO.Data +{ + public class RuleOwner + { + [JsonProperty("owner_id"), JsonPropertyName("owner_id")] + public int OwnerId { get; set; } + + [JsonProperty("rule_metadata_id"), JsonPropertyName("rule_metadata_id")] + public long? RuleMetadataId { get; set; } + + [JsonProperty("rule_id"), JsonPropertyName("rule_id")] + public long RuleId { get; set; } + + [JsonProperty("created"), JsonPropertyName("created")] + public long Created { get; set; } + + [JsonProperty("removed"), JsonPropertyName("removed")] + public long? Removed { get; set; } + + [JsonProperty("owner_mapping_source_id"), JsonPropertyName("owner_mapping_source_id")] + public int OwnerMappingSourceId { get; set; } + + [JsonProperty("matched_objects"), JsonPropertyName("matched_objects")] + public string? MatchedObjects { get; set; } = null; + } + + + public class RuleOwnerMutationWrapper + { + [JsonProperty("update_rule_owner"), JsonPropertyName("update_rule_owner")] + public UpdateRuleOwner? UpdateRuleOwner { get; set; } + + [JsonProperty("insert_rule_owner"), JsonPropertyName("insert_rule_owner")] + public InsertRuleOwnerResult? InsertRuleOwner { get; set; } + } + + public class UpdateRuleOwner + { + [JsonProperty("affected_rows"), JsonPropertyName("affected_rows")] + public int AffectedRows { get; set; } + } + + public class InsertRuleOwnerResult + { + [JsonProperty("affected_rows"), JsonPropertyName("affected_rows")] + public int AffectedRows { get; set; } + + [JsonProperty("returning"), JsonPropertyName("returning")] + public List? Returning { get; set; } + } + +} diff --git a/roles/lib/files/FWO.Data/RuleTime.cs b/roles/lib/files/FWO.Data/RuleTime.cs new file mode 100644 index 0000000000..49a753e7b0 --- /dev/null +++ b/roles/lib/files/FWO.Data/RuleTime.cs @@ -0,0 +1,26 @@ +using System.Text.Json.Serialization; +using Newtonsoft.Json; + +namespace FWO.Data +{ + public class RuleTime + { + [JsonProperty("rule_time_id"), JsonPropertyName("rule_time_id")] + public long Id { get; set; } + + [JsonProperty("rule_id"), JsonPropertyName("rule_id")] + public long RuleId { get; set; } + + [JsonProperty("time_obj_id"), JsonPropertyName("time_obj_id")] + public long TimeObjId { get; set; } + + [JsonProperty("created"), JsonPropertyName("created")] + public long Created { get; set; } + + [JsonProperty("removed"), JsonPropertyName("removed")] + public long? Removed { get; set; } + + [JsonProperty("time_object"), JsonPropertyName("time_object")] + public TimeObject? TimeObj { get; set; } + } +} diff --git a/roles/lib/files/FWO.Data/Rulebase.cs b/roles/lib/files/FWO.Data/Rulebase.cs new file mode 100644 index 0000000000..0cd028cdca --- /dev/null +++ b/roles/lib/files/FWO.Data/Rulebase.cs @@ -0,0 +1,33 @@ +using System.Text.Json.Serialization; +using Newtonsoft.Json; + +namespace FWO.Data +{ + public class Rulebase + { + [JsonProperty("id"), JsonPropertyName("id")] + public long Id { get; set; } + + [JsonProperty("name"), JsonPropertyName("name")] + public string Name { get; set; } = ""; + + [JsonProperty("uid"), JsonPropertyName("uid")] + public string Uid { get; set; } = ""; + + [JsonProperty("mgm_id"), JsonPropertyName("mgm_id")] + public int MgmtId { get; set; } + + [JsonProperty("is_global"), JsonPropertyName("is_global")] + public bool IsGlobal { get; set; } + + [JsonProperty("created"), JsonPropertyName("created")] + public long Created { get; set; } + + [JsonProperty("removed"), JsonPropertyName("removed")] + public long Removed { get; set; } + + [JsonProperty("rules"), JsonPropertyName("rules")] + public Rule[] Rules { get; set; } = []; + + } +} diff --git a/roles/lib/files/FWO.Data/RulebaseLink.cs b/roles/lib/files/FWO.Data/RulebaseLink.cs new file mode 100644 index 0000000000..3264e5367d --- /dev/null +++ b/roles/lib/files/FWO.Data/RulebaseLink.cs @@ -0,0 +1,50 @@ +using System.Text.Json.Serialization; +using Newtonsoft.Json; + +namespace FWO.Data +{ + public class RulebaseLink + { + [JsonProperty("gw_id"), JsonPropertyName("gw_id")] + public int GatewayId { get; set; } + + [JsonProperty("from_rule_id"), JsonPropertyName("from_rule_id")] + public int? FromRuleId { get; set; } // nullable for initial rulebase and for fromRulebase links + + [JsonProperty("rule"), JsonPropertyName("rule")] + public Rule? FromRule { get; set; } + + [JsonProperty("rulebaseByFromRulebaseId"), JsonPropertyName("rulebaseByFromRulebaseId")] + public Rulebase? FromRulebase { get; set; } + + [JsonProperty("from_rulebase_id"), JsonPropertyName("from_rulebase_id")] + public int? FromRulebaseId { get; set; } // nullable for fromRule links + + [JsonProperty("rulebase"), JsonPropertyName("rulebase")] + public Rulebase? ToRulebase { get; set; } + + [JsonProperty("link_type"), JsonPropertyName("link_type")] + public int LinkType { get; set; } + + [JsonProperty("stm_link_type"), JsonPropertyName("stm_link_type")] + public LinkType? LinkTypeObj { get; set; } + + [JsonProperty("is_initial"), JsonPropertyName("is_initial")] + public bool IsInitial { get; set; } = false; + + [JsonProperty("is_global"), JsonPropertyName("is_global")] + public bool IsGlobal { get; set; } = false; + + [JsonProperty("is_section"), JsonPropertyName("is_section")] + public bool IsSection { get; set; } = false; + + [JsonProperty("to_rulebase_id"), JsonPropertyName("to_rulebase_id")] + public int NextRulebaseId = new(); + + [JsonProperty("created"), JsonPropertyName("created")] + public long? Created; + + [JsonProperty("removed"), JsonPropertyName("removed")] + public long? Removed; + } +} diff --git a/roles/lib/files/FWO.Data/Sanitizer.cs b/roles/lib/files/FWO.Data/Sanitizer.cs new file mode 100644 index 0000000000..1a7c4acbb6 --- /dev/null +++ b/roles/lib/files/FWO.Data/Sanitizer.cs @@ -0,0 +1,190 @@ +using FWO.Basics; +using System.Text.RegularExpressions; + +namespace FWO.Data +{ + public class Sanitizer + { + // Standard input fields + public static string SanitizeMand(string input, ref bool shortened) + { + string output = Regex.Replace(input, @"[^\w\.\*\-\:\?@/\(\)\[\]\{\}\$\+<>#\$ ]", "").Trim(); + if (output.Length < input.Length) + { + shortened = true; + } + return output; + } + + public static string? SanitizeOpt(string? input, ref bool shortened) + { + if (input != null) + { + return SanitizeMand(input, ref shortened); + } + else return null; + } + + + // Ldap names: more restrictive due to Ldap restrictions. Chars not allowed (would have to be escaped in Dn): +;,\"<># + public static string SanitizeLdapNameMand(string input, ref bool shortened) + { + string output = Regex.Replace(input, @"[^\w\.\*\-\:\?@/\(\) ]", "").Trim(); + if (output.Length < input.Length) + { + shortened = true; + } + return output; + } + + public static string? SanitizeLdapNameOpt(string? input, ref bool shortened) + { + if (input != null) + { + return input.SanitizeLdapNameMand(ref shortened); + } + else return null; + } + + + // Ldap path (Dn): Additionally needed on top of Ldap names chars: =, + public static string SanitizeLdapPathMand(string input, ref bool shortened) + { + string output = Regex.Replace(input, @"[^\w\.\*\-\:\?@/\(\)\=\, \\]", "").Trim(); + if (output.Length < input.Length) + { + shortened = true; + } + return output; + } + + public static string? SanitizeLdapPathOpt(string? input, ref bool shortened) + { + if (input != null) + { + return input.SanitizeLdapPathMand(ref shortened); + } + else return null; + } + + + // Passwords should not have Whitespaces except inner blanks + public static string SanitizePasswMand(string input, ref bool shortened) + { + string output = Regex.Replace(input, @"[^\S ]", "").Trim(); + if (output.Length < input.Length) + { + shortened = true; + } + return output; + } + + public static string? SanitizePasswOpt(string? input, ref bool shortened) + { + if (input != null) + { + return input.SanitizePasswMand(ref shortened); + } + else return null; + } + + + // Keys are only trimmed + public static string SanitizeKeyMand(string input, ref bool shortened) + { + string output = input.Trim(); + if (output.Length < input.Length) + { + shortened = true; + } + return output; + } + + public static string? SanitizeKeyOpt(string? input, ref bool shortened) + { + if (input != null) + { + return input.SanitizeKeyMand(ref shortened); + } + else return null; + } + + // Comments may contain everything but quotes (EOL chars are allowed) + public static string? SanitizeCommentOpt(string? input, ref bool shortened) + { + if (input != null) + { + return SanitizeCommentMand(input, ref shortened); + } + else return null; + } + + public static string SanitizeCommentMand(string input, ref bool shortened) + { + string output = Regex.Replace(input, @"[""'']", "").Trim(); + string ignorableChangeCompareString = output + "\n"; + if (input != null) + { + if (output.Length < input.Length) // there is always an EOL char added in text fields + { + if (ignorableChangeCompareString != input) + { + shortened = true; + } + } + } + return output; + } + + // Cidrs may contain Numbers[a-f]:./ + public static string SanitizeCidrMand(string input, ref bool shortened) + { + string output = Regex.Replace(input, @"[^a-fA-F0-9\.\:/]", "").Trim(); + if (output.Length < input.Length) + { + shortened = true; + } + return output; + } + + public static string? SanitizeCidrOpt(string? input, ref bool shortened) + { + if (input != null) + { + return input.SanitizeCidrMand(ref shortened); + } + else return null; + } + + public static string SanitizeJsonMand(string input, ref bool shortened) + { + string output = Regex.Replace(input, @"[^\S ]", "").Trim(); + if (output.Length < input.Length) + { + shortened = true; + } + return output; + } + + // not allowed: +*(){}[]?!#<>=,;'\"'/\\\t@$%^|&~ -> replaced by "_" + public static string SanitizeJsonFieldMand(string input, ref bool changed) + { + string output = Regex.Replace(input.Trim(), @"[\+\*\(\)\{\}\[\]\?\!#<>\=\,\;\/\\\t@\$\%\^\|\&\~ ]", "_"); + if (output != input) + { + changed = true; + } + return output; + } + + public static string SanitizeEolMand(string input, ref bool shortened) + { + string output = Regex.Replace(input, @"[\n\r]", " ").Trim(); + if (output.Length < input.Length) + { + shortened = true; + } + return output; + } + } +} diff --git a/roles/lib/files/FWO.Data/SchedulerInterval.cs b/roles/lib/files/FWO.Data/SchedulerInterval.cs new file mode 100644 index 0000000000..24235302f1 --- /dev/null +++ b/roles/lib/files/FWO.Data/SchedulerInterval.cs @@ -0,0 +1,53 @@ +namespace FWO.Data +{ + public enum SchedulerInterval + { + Never = 0, + Days = 2, + Weeks = 3, + Months = 4, + Years = 5, + Hours = 6, + Minutes = 7, + Seconds = 8 + } + + public static class SchedulerIntervalGroups + { + public static bool OfferedForReport(this SchedulerInterval schedulerInterval) + { + return schedulerInterval switch + { + SchedulerInterval.Days or + SchedulerInterval.Weeks or + SchedulerInterval.Months or + SchedulerInterval.Years => true, + _ => false, + }; + } + + public static bool OfferedForReportOrNever(this SchedulerInterval schedulerInterval) + { + return schedulerInterval switch + { + SchedulerInterval.Days or + SchedulerInterval.Weeks or + SchedulerInterval.Months or + SchedulerInterval.Years or + SchedulerInterval.Never => true, + _ => false, + }; + } + + public static bool OfferedForRecert(this SchedulerInterval schedulerInterval) + { + return schedulerInterval switch + { + SchedulerInterval.Days or + SchedulerInterval.Weeks or + SchedulerInterval.Months => true, + _ => false, + }; + } + } +} diff --git a/roles/lib/files/FWO.Data/SchedulerJobExecutionStatus.cs b/roles/lib/files/FWO.Data/SchedulerJobExecutionStatus.cs new file mode 100644 index 0000000000..bc9c1da74d --- /dev/null +++ b/roles/lib/files/FWO.Data/SchedulerJobExecutionStatus.cs @@ -0,0 +1,9 @@ +namespace FWO.Data +{ + public enum SchedulerJobExecutionStatus + { + None = 0, + Success = 1, + Failed = 2 + } +} diff --git a/roles/lib/files/FWO.Data/ServiceChange.cs b/roles/lib/files/FWO.Data/ServiceChange.cs new file mode 100644 index 0000000000..f568d4d854 --- /dev/null +++ b/roles/lib/files/FWO.Data/ServiceChange.cs @@ -0,0 +1,25 @@ +using Newtonsoft.Json; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Text.Json.Serialization; +using System.Threading.Tasks; + +namespace FWO.Data +{ + public class ServiceChange + { + [JsonProperty("import"), JsonPropertyName("import")] + public ChangeImport ChangeImport { get; set; } = new ChangeImport(); + + [JsonProperty("change_action"), JsonPropertyName("change_action")] + public char ChangeAction { get; set; } + + [JsonProperty("old"), JsonPropertyName("old")] + public NetworkService OldService { get; set; } = new NetworkService(); + + [JsonProperty("new"), JsonPropertyName("new")] + public NetworkService NewService { get; set; } = new NetworkService(); + } +} diff --git a/roles/lib/files/FWO.Data/ServiceWrapper.cs b/roles/lib/files/FWO.Data/ServiceWrapper.cs new file mode 100644 index 0000000000..d63edc997a --- /dev/null +++ b/roles/lib/files/FWO.Data/ServiceWrapper.cs @@ -0,0 +1,11 @@ +using System.Text.Json.Serialization; +using Newtonsoft.Json; + +namespace FWO.Data +{ + public class ServiceWrapper + { + [JsonProperty("service"), JsonPropertyName("service")] + public NetworkService Content { get; set; } = new NetworkService(); + } +} diff --git a/roles/lib/files/FWO.Data/Tenant.cs b/roles/lib/files/FWO.Data/Tenant.cs new file mode 100644 index 0000000000..46b92fc6d2 --- /dev/null +++ b/roles/lib/files/FWO.Data/Tenant.cs @@ -0,0 +1,161 @@ +using FWO.Basics; +using FWO.Data.Middleware; +using Newtonsoft.Json; +using System.Text.Json.Serialization; + + +namespace FWO.Data +{ + public class Tenant + { + [JsonProperty("tenant_id"), JsonPropertyName("tenant_id")] + public int Id { get; set; } + + [JsonProperty("tenant_name"), JsonPropertyName("tenant_name")] + public string Name { get; set; } = ""; + + [JsonProperty("tenant_comment"), JsonPropertyName("tenant_comment")] + public string? Comment { get; set; } + + [JsonProperty("tenant_projekt"), JsonPropertyName("tenant_projekt")] + public string? Project { get; set; } + + [JsonProperty("tenant_can_view_all_devices"), JsonPropertyName("tenant_can_view_all_devices")] + public bool ViewAllDevices { get; set; } + + [JsonProperty("tenant_is_superadmin"), JsonPropertyName("tenant_is_superadmin")] + public bool Superadmin { get; set; } // curently not in use + + [JsonProperty("tenant_to_devices"), JsonPropertyName("tenant_to_devices")] + public TenantGateway[] TenantGateways { get; set; } = []; // TODO: Replace with Device[] (probably not possible) + + [JsonProperty("tenant_to_managements"), JsonPropertyName("tenant_to_managements")] + public TenantManagement[] TenantManagements { get; set; } = []; + + public int[] VisibleGatewayIds { get; set; } = []; + public int[] VisibleManagementIds { get; set; } = []; + + public TenantViewManagement[] TenantVisibleManagements { get; set; } = []; + public TenantViewGateway[] TenantVisibleGateways { get; set; } = []; + + + public Tenant() + { } + + public Tenant(Tenant tenant) + { + Id = tenant.Id; + Name = tenant.Name; + Comment = tenant.Comment; + Project = tenant.Project; + ViewAllDevices = tenant.ViewAllDevices; + TenantGateways = tenant.TenantGateways; + TenantManagements = tenant.TenantManagements; + + foreach (TenantGateway gateway in tenant.TenantGateways) + { + VisibleGatewayIds = [.. VisibleGatewayIds, gateway.VisibleGateway.Id]; + } + } + + public Tenant(TenantGetReturnParameters tenantGetParameters) + { + Id = tenantGetParameters.Id; + Name = tenantGetParameters.Name; + Comment = tenantGetParameters.Comment; + Project = tenantGetParameters.Project; + ViewAllDevices = tenantGetParameters.ViewAllDevices; + List deviceList = []; + + foreach (int id in VisibleGatewayIds) + { + TenantVisibleGateways = [.. TenantVisibleGateways, new TenantViewGateway(id, "", true)]; + } + + TenantVisibleGateways = [.. deviceList]; // ??? + } + + public bool Sanitize() + { + bool shortened = false; + Name = Name.SanitizeLdapNameMand(ref shortened); + Comment = Comment.SanitizeOpt(ref shortened); + Project = Project.SanitizeOpt(ref shortened); + return shortened; + } + + public TenantGetReturnParameters ToApiParams() + { + TenantGetReturnParameters tenantGetParams = new() + { + Id = Id, + Name = Name, + Comment = Comment, + Project = Project, + ViewAllDevices = ViewAllDevices, + VisibleGateways = [], + VisibleManagements = [], + SharedGateways = [], + UnfilteredGateways = [], + SharedManagements = [], + UnfilteredManagements = [] + }; + + foreach (var gateway in TenantGateways) + { + tenantGetParams.VisibleGateways.Add(new TenantViewGateway(gateway.VisibleGateway.Id, gateway.VisibleGateway.Name ?? "")); + if (gateway.Shared) + { + tenantGetParams.SharedGateways.Add(new TenantViewGateway(gateway.VisibleGateway.Id, gateway.VisibleGateway.Name ?? "")); + } + else + { + tenantGetParams.UnfilteredGateways.Add(new TenantViewGateway(gateway.VisibleGateway.Id, gateway.VisibleGateway.Name ?? "", false)); + } + } + foreach (var mgm in TenantManagements) + { + tenantGetParams.VisibleManagements.Add(new TenantViewManagement(mgm.VisibleManagement.Id, mgm.VisibleManagement.Name ?? "")); + if (mgm.Shared) + { + tenantGetParams.SharedManagements.Add(new TenantViewManagement(mgm.VisibleManagement.Id, mgm.VisibleManagement.Name ?? "")); + } + else + { + tenantGetParams.UnfilteredManagements.Add(new TenantViewManagement(mgm.VisibleManagement.Id, mgm.VisibleManagement.Name ?? "")); + } + } + return tenantGetParams; + } + + public TenantEditParameters ToApiUpdateParams() + { + TenantEditParameters tenantUpdateParams = new() + { + Id = Id, + Comment = Comment, + Project = Project, + ViewAllDevices = ViewAllDevices + }; + return tenantUpdateParams; + } + } + + public class TenantGateway + { + [JsonProperty("device"), JsonPropertyName("device")] + public Device VisibleGateway { get; set; } = new Device(); + + [JsonProperty("shared"), JsonPropertyName("shared")] + public bool Shared { get; set; } = false; + } + + public class TenantManagement + { + [JsonProperty("management"), JsonPropertyName("management")] + public Management VisibleManagement { get; set; } = new Management(); + + [JsonProperty("shared"), JsonPropertyName("shared")] + public bool Shared { get; set; } = false; + } +} diff --git a/roles/lib/files/FWO.Data/TicketId.cs b/roles/lib/files/FWO.Data/TicketId.cs new file mode 100644 index 0000000000..272e2da696 --- /dev/null +++ b/roles/lib/files/FWO.Data/TicketId.cs @@ -0,0 +1,11 @@ +using System.Text.Json.Serialization; +using Newtonsoft.Json; + +namespace FWO.Data +{ + public class TicketId + { + [JsonProperty("ticket_id"), JsonPropertyName("ticket_id")] + public long Id { get; set; } + } +} diff --git a/roles/lib/files/FWO.Data/TimeObject.cs b/roles/lib/files/FWO.Data/TimeObject.cs new file mode 100644 index 0000000000..5e2ee35707 --- /dev/null +++ b/roles/lib/files/FWO.Data/TimeObject.cs @@ -0,0 +1,26 @@ +using System.Text.Json.Serialization; +using Newtonsoft.Json; + +namespace FWO.Data +{ + public class TimeObject + { + [JsonProperty("time_obj_id"), JsonPropertyName("time_obj_id")] + public long Id { get; set; } + + [JsonProperty("time_obj_name"), JsonPropertyName("time_obj_name")] + public string Name { get; set; } = ""; + + [JsonProperty("time_obj_uid"), JsonPropertyName("time_obj_uid")] + public string Uid { get; set; } = ""; + + [JsonProperty("start_time"), JsonPropertyName("start_time")] + public DateTime? StartTime { get; set; } + + [JsonProperty("end_time"), JsonPropertyName("end_time")] + public DateTime? EndTime { get; set; } + + [JsonProperty("created"), JsonPropertyName("created")] + public long Created { get; set; } + } +} diff --git a/roles/lib/files/FWO.Data/TimeWrapper.cs b/roles/lib/files/FWO.Data/TimeWrapper.cs new file mode 100644 index 0000000000..661036d35b --- /dev/null +++ b/roles/lib/files/FWO.Data/TimeWrapper.cs @@ -0,0 +1,11 @@ +using System.Text.Json.Serialization; +using Newtonsoft.Json; + +namespace FWO.Data +{ + public class TimeWrapper + { + [JsonProperty("time"), JsonPropertyName("time")] + public DateTime Time { get; set; } + } +} diff --git a/roles/lib/files/FWO.Api.Client/Data/Tracking.cs b/roles/lib/files/FWO.Data/Tracking.cs similarity index 81% rename from roles/lib/files/FWO.Api.Client/Data/Tracking.cs rename to roles/lib/files/FWO.Data/Tracking.cs index e1addf7cd0..b2873d67a7 100644 --- a/roles/lib/files/FWO.Api.Client/Data/Tracking.cs +++ b/roles/lib/files/FWO.Data/Tracking.cs @@ -1,13 +1,20 @@ -using System.Text.Json.Serialization; +using System.Text.Json.Serialization; using Newtonsoft.Json; -namespace FWO.Api.Data +namespace FWO.Data { public class Tracking { [JsonProperty("track_id"), JsonPropertyName("track_id")] public int Id { get; set; } + + + + + + + [JsonProperty("track_name"), JsonPropertyName("track_name")] public string Name { get; set; } = ""; } diff --git a/roles/lib/files/FWO.Data/UiLdapConnection.cs b/roles/lib/files/FWO.Data/UiLdapConnection.cs new file mode 100644 index 0000000000..307fccd3ed --- /dev/null +++ b/roles/lib/files/FWO.Data/UiLdapConnection.cs @@ -0,0 +1,72 @@ +using FWO.Basics; +using FWO.Data.Middleware; +using Newtonsoft.Json; +using System.Text.Json.Serialization; + +namespace FWO.Data +{ + public class UiLdapConnection : LdapConnectionBase + { + private string name = ""; + + [JsonProperty("ldap_name"), JsonPropertyName("ldap_name")] + public string Name + { + get + { + // for compatibility: take hostname if not filled + return (name != null && name != "") ? name : Host(); + } + set + { + name = value; + } + } + + public UiLdapConnection() + { } + + public UiLdapConnection(LdapGetUpdateParameters ldapGetUpdateParameters) : base(ldapGetUpdateParameters) + { + Name = ldapGetUpdateParameters.Name ?? ""; + } + + public UiLdapConnection(UiLdapConnection ldapConnection) : base(ldapConnection) + { + Name = ldapConnection.Name; + } + + public override bool Sanitize() + { + bool shortened = base.Sanitize(); + Name = Name.SanitizeMand(ref shortened); + return shortened; + } + + public LdapGetUpdateParameters ToApiParams() + { + return new LdapGetUpdateParameters + { + Id = this.Id, + Name = this.Name, + Address = this.Address, + Port = this.Port, + Type = this.Type, + PatternLength = this.PatternLength, + SearchUser = this.SearchUser, + Tls = this.Tls, + TenantLevel = this.TenantLevel, + SearchUserPwd = this.SearchUserPwd, + SearchpathForUsers = this.UserSearchPath, + SearchpathForRoles = this.RoleSearchPath, + SearchpathForGroups = this.GroupSearchPath, + WritepathForGroups = this.GroupWritePath, + WriteUser = this.WriteUser, + WriteUserPwd = this.WriteUserPwd, + TenantId = this.TenantId, + GlobalTenantName = this.GlobalTenantName, + Active = this.Active + }; + } + } +} diff --git a/roles/lib/files/FWO.Data/UiUser.cs b/roles/lib/files/FWO.Data/UiUser.cs new file mode 100644 index 0000000000..d32777c39f --- /dev/null +++ b/roles/lib/files/FWO.Data/UiUser.cs @@ -0,0 +1,149 @@ +using FWO.Basics; +using FWO.Data.Middleware; +using Newtonsoft.Json; +using System.Text.Json.Serialization; + +namespace FWO.Data +{ + public class UiUser + { + [JsonProperty("uiuser_username"), JsonPropertyName("uiuser_username")] + public string Name { get; set; } = ""; + + [JsonProperty("uiuser_id"), JsonPropertyName("uiuser_id")] + public int DbId { get; set; } + + [JsonProperty("uuid"), JsonPropertyName("uuid")] + public string Dn { get; set; } = ""; + + public string Password { get; set; } = ""; + + [JsonProperty("uiuser_email"), JsonPropertyName("uiuser_email")] + public string? Email { get; set; } + + [JsonProperty("uiuser_first_name"), JsonPropertyName("uiuser_first_name")] + public string? Firstname { get; set; } + + [JsonProperty("uiuser_last_name"), JsonPropertyName("uiuser_last_name")] + public string? Lastname { get; set; } + + [JsonProperty("tenant"), JsonPropertyName("tenant")] + public Tenant? Tenant { get; set; } + + [JsonProperty("uiuser_language"), JsonPropertyName("uiuser_language")] + public string? Language { get; set; } + + [JsonProperty("uiuser_last_login"), JsonPropertyName("uiuser_last_login")] + public DateTime? LastLogin { get; set; } + + [JsonProperty("uiuser_last_password_change"), JsonPropertyName("uiuser_last_password_change")] + public DateTime? LastPasswordChange { get; set; } + + [JsonProperty("uiuser_password_must_be_changed"), JsonPropertyName("uiuser_password_must_be_changed")] + public bool PasswordMustBeChanged { get; set; } + + [JsonProperty("ldap_connection"), JsonPropertyName("ldap_connection")] + public UiLdapConnection LdapConnection { get; set; } = new(); + + public string Jwt { get; set; } = ""; + public List Roles { get; set; } = []; + public List Groups { get; set; } = []; + public List Ownerships { get; set; } = []; + public List RecertOwnerships { get; set; } = []; + + + public UiUser() + { + Tenant = new(); + LdapConnection = new(); + } + + public UiUser(UiUser user) + { + Name = user.Name; + DbId = user.DbId; + Dn = user.Dn; + if (user.Tenant != null) + { + Tenant = new Tenant(user.Tenant); + } + Password = user.Password; + Firstname = user.Firstname; + Lastname = user.Lastname; + Email = user.Email; + Language = user.Language; + Groups = user.Groups; + Roles = user.Roles; + Ownerships = user.Ownerships; + RecertOwnerships = user.RecertOwnerships; + if (user.LdapConnection != null) + { + LdapConnection = new UiLdapConnection(user.LdapConnection); + } + } + + public UiUser(UserGetReturnParameters userGetReturnParameters) + { + Name = userGetReturnParameters.Name; + DbId = userGetReturnParameters.UserId; + Dn = userGetReturnParameters.UserDn; + Email = userGetReturnParameters.Email; + Firstname = userGetReturnParameters.Firstname; + Lastname = userGetReturnParameters.Lastname; + if (userGetReturnParameters.TenantId != 0) + { + Tenant = new() { Id = userGetReturnParameters.TenantId }; + } + Language = userGetReturnParameters.Language; + LastLogin = userGetReturnParameters.LastLogin; + LastPasswordChange = userGetReturnParameters.LastPasswordChange; + PasswordMustBeChanged = userGetReturnParameters.PwChangeRequired; + LdapConnection = new() { Id = userGetReturnParameters.LdapId }; + } + + public bool IsInternal() + { + return new DistName(Dn).IsInternal(); + } + + public bool Sanitize() + { + bool shortened = false; + Name = Name.SanitizeLdapNameMand(ref shortened); + Email = Email.SanitizeOpt(ref shortened); + Firstname = Firstname.SanitizeOpt(ref shortened); + Lastname = Lastname.SanitizeOpt(ref shortened); + Password = Password.SanitizePasswMand(ref shortened); + return shortened; + } + + public UserGetReturnParameters ToApiParams() + { + return new UserGetReturnParameters + { + Name = this.Name, + UserId = this.DbId, + UserDn = this.Dn, + Email = this.Email, + Firstname = this.Firstname, + Lastname = this.Lastname, + TenantId = this.Tenant != null ? this.Tenant.Id : 0, + Language = this.Language, + LastLogin = this.LastLogin, + LastPasswordChange = this.LastPasswordChange, + PwChangeRequired = this.PasswordMustBeChanged, + LdapId = this.LdapConnection.Id + }; + } + + public string RoleList() + { + return string.Join(", ", Roles); + } + + public string GroupList() + { + return string.Join(", ", Groups); + } + } +} diff --git a/roles/lib/files/FWO.Data/UserChange.cs b/roles/lib/files/FWO.Data/UserChange.cs new file mode 100644 index 0000000000..c3c725abeb --- /dev/null +++ b/roles/lib/files/FWO.Data/UserChange.cs @@ -0,0 +1,25 @@ +using Newtonsoft.Json; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Text.Json.Serialization; +using System.Threading.Tasks; + +namespace FWO.Data +{ + public class UserChange + { + [JsonProperty("import"), JsonPropertyName("import")] + public ChangeImport ChangeImport { get; set; } = new ChangeImport(); + + [JsonProperty("change_action"), JsonPropertyName("change_action")] + public char ChangeAction { get; set; } + + [JsonProperty("old"), JsonPropertyName("old")] + public NetworkUser OldUser { get; set; } = new NetworkUser(); + + [JsonProperty("new"), JsonPropertyName("new")] + public NetworkUser NewUser { get; set; } = new NetworkUser(); + } +} diff --git a/roles/lib/files/FWO.Api.Client/Data/UserGroup.cs b/roles/lib/files/FWO.Data/UserGroup.cs similarity index 86% rename from roles/lib/files/FWO.Api.Client/Data/UserGroup.cs rename to roles/lib/files/FWO.Data/UserGroup.cs index 9f8e2dd3cf..38b4d9e332 100644 --- a/roles/lib/files/FWO.Api.Client/Data/UserGroup.cs +++ b/roles/lib/files/FWO.Data/UserGroup.cs @@ -1,4 +1,6 @@ -namespace FWO.Api.Data +using FWO.Basics; + +namespace FWO.Data { public class UserGroup { @@ -9,7 +11,7 @@ public class UserGroup public List Roles { get; set; } = new List(); public UserGroup() - {} + { } public UserGroup(UserGroup group) { @@ -23,7 +25,7 @@ public UserGroup(UserGroup group) public string UserList() { List userNames = new List(); - foreach(UiUser user in Users) + foreach (UiUser user in Users) { userNames.Add(user.Name); } @@ -38,7 +40,7 @@ public string RoleList() public bool Sanitize() { bool shortened = false; - Name = Sanitizer.SanitizeLdapNameMand(Name, ref shortened); + Name = Name.SanitizeLdapNameMand(ref shortened); return shortened; } } diff --git a/roles/lib/files/FWO.Api.Client/Data/UserWrapper.cs b/roles/lib/files/FWO.Data/UserWrapper.cs similarity index 75% rename from roles/lib/files/FWO.Api.Client/Data/UserWrapper.cs rename to roles/lib/files/FWO.Data/UserWrapper.cs index 6cf2ec1ae1..277049a9d8 100644 --- a/roles/lib/files/FWO.Api.Client/Data/UserWrapper.cs +++ b/roles/lib/files/FWO.Data/UserWrapper.cs @@ -1,7 +1,7 @@ -using System.Text.Json.Serialization; +using System.Text.Json.Serialization; using Newtonsoft.Json; -namespace FWO.Api.Data +namespace FWO.Data { public class UserWrapper { diff --git a/roles/lib/files/FWO.Data/Workflow/ApproverAllowedChangesConfig.cs b/roles/lib/files/FWO.Data/Workflow/ApproverAllowedChangesConfig.cs new file mode 100644 index 0000000000..7a062929a5 --- /dev/null +++ b/roles/lib/files/FWO.Data/Workflow/ApproverAllowedChangesConfig.cs @@ -0,0 +1,261 @@ +using System.Text.Json; + +namespace FWO.Data.Workflow +{ + public static class WorkflowEditableFieldKeys + { + public const string Title = "title"; + public const string Priority = "priority"; + public const string Deadline = "deadline"; + public const string Reason = "reason"; + public const string FreeText = "free_text"; + public const string Management = "management"; + public const string Gateways = "gateways"; + public const string Gateway = "gateway"; + public const string RuleAction = "rule_action"; + public const string Track = "track"; + public const string ValidFrom = "valid_from"; + public const string ValidTo = "valid_to"; + public const string Source = "source"; + public const string Destination = "destination"; + public const string Services = "services"; + public const string Rules = "rules"; + public const string Owner = "owner"; + public const string RequestingOwner = "requesting_owner"; + public const string Name = "name"; + } + + public class WorkflowEditableFieldDefinition + { + public string Key { get; set; } = ""; + + public WorkflowEditableFieldDefinition() + { } + + public WorkflowEditableFieldDefinition(string key) + { + Key = key; + } + } + + public class ApproverAllowedChangesConfig + { + public List TicketFields { get; set; } = []; + public Dictionary> TaskTypeFields { get; set; } = []; + + public static ApproverAllowedChangesConfig Parse(string? serializedConfig) + { + ApproverAllowedChangesConfig config; + if (string.IsNullOrWhiteSpace(serializedConfig)) + { + config = new(); + } + else + { + try + { + config = JsonSerializer.Deserialize(serializedConfig) ?? new(); + } + catch (JsonException) + { + config = new(); + } + } + config.TicketFields ??= []; + config.TaskTypeFields ??= []; + foreach (WfTaskType taskType in ApproverAllowedChangesCatalog.TaskTypeFields.Keys) + { + if (!config.TaskTypeFields.ContainsKey(taskType.ToString())) + { + config.TaskTypeFields[taskType.ToString()] = []; + } + } + return config; + } + + public string ToConfigValue() + { + return JsonSerializer.Serialize(this); + } + + public bool IsTicketFieldAllowed(string fieldKey) + { + return TicketFields.Contains(fieldKey); + } + + public bool IsTaskFieldAllowed(WfTaskType taskType, string fieldKey) + { + return TaskTypeFields.TryGetValue(taskType.ToString(), out List? fields) + && fields.Contains(fieldKey); + } + + public bool HasTicketFieldChanges() + { + return TicketFields.Count > 0; + } + + public bool HasTaskFieldChanges(WfTaskType taskType) + { + return TaskTypeFields.TryGetValue(taskType.ToString(), out List? fields) + && fields.Count > 0; + } + + public void SetTicketField(string fieldKey, bool allowed) + { + SetField(TicketFields, fieldKey, allowed); + } + + public void SetTaskField(WfTaskType taskType, string fieldKey, bool allowed) + { + string taskTypeKey = taskType.ToString(); + if (!TaskTypeFields.ContainsKey(taskTypeKey)) + { + TaskTypeFields[taskTypeKey] = []; + } + SetField(TaskTypeFields[taskTypeKey], fieldKey, allowed); + } + + private static void SetField(List fields, string fieldKey, bool allowed) + { + if (allowed) + { + if (!fields.Contains(fieldKey)) + { + fields.Add(fieldKey); + } + } + else + { + fields.Remove(fieldKey); + } + } + } + + public static class ApproverAllowedChangesAccess + { + public class TaskFieldEditContext + { + public bool IsApprovalPhase { get; set; } + public bool EditReqTaskMode { get; set; } + public bool ApproveReqTaskMode { get; set; } + public bool ReadOnlyMode { get; set; } + public WfTaskType TaskType { get; set; } + public bool HasImplementationTasks { get; set; } + } + + public static bool IsCopiedToImplementationTask(WfTaskType taskType, string fieldKey) + { + return fieldKey switch + { + WorkflowEditableFieldKeys.Title => true, + WorkflowEditableFieldKeys.Gateways => taskType == WfTaskType.access, + WorkflowEditableFieldKeys.Gateway => taskType == WfTaskType.rule_modify || taskType == WfTaskType.rule_delete, + WorkflowEditableFieldKeys.RuleAction => taskType == WfTaskType.access || taskType == WfTaskType.rule_modify || taskType == WfTaskType.rule_delete, + WorkflowEditableFieldKeys.Track => taskType == WfTaskType.access || taskType == WfTaskType.rule_modify || taskType == WfTaskType.rule_delete, + WorkflowEditableFieldKeys.ValidFrom => taskType == WfTaskType.access || taskType == WfTaskType.rule_modify || taskType == WfTaskType.rule_delete, + WorkflowEditableFieldKeys.ValidTo => taskType == WfTaskType.access || taskType == WfTaskType.rule_modify || taskType == WfTaskType.rule_delete, + WorkflowEditableFieldKeys.FreeText => taskType == WfTaskType.generic, + WorkflowEditableFieldKeys.Source => taskType == WfTaskType.access, + WorkflowEditableFieldKeys.Destination => taskType == WfTaskType.access, + WorkflowEditableFieldKeys.Services => taskType == WfTaskType.access, + WorkflowEditableFieldKeys.Rules => taskType == WfTaskType.rule_modify || taskType == WfTaskType.rule_delete, + _ => false + }; + } + + public static bool CanEditTicketField(ApproverAllowedChangesConfig config, bool isApprovalPhase, bool editTicketMode, bool readOnlyMode, string fieldKey) + { + return editTicketMode || isApprovalPhase && !readOnlyMode && config.IsTicketFieldAllowed(fieldKey); + } + + public static bool CanSaveTicketChanges(ApproverAllowedChangesConfig config, bool isApprovalPhase, bool editTicketMode, bool readOnlyMode) + { + return editTicketMode || isApprovalPhase && !readOnlyMode && config.HasTicketFieldChanges(); + } + + public static bool CanEditTaskField(ApproverAllowedChangesConfig config, TaskFieldEditContext context, string fieldKey) + { + return context.EditReqTaskMode || context.IsApprovalPhase && context.ApproveReqTaskMode && !context.ReadOnlyMode + && config.IsTaskFieldAllowed(context.TaskType, fieldKey) + && (!context.HasImplementationTasks || !IsCopiedToImplementationTask(context.TaskType, fieldKey)); + } + + public static bool CanSaveTaskChanges(ApproverAllowedChangesConfig config, TaskFieldEditContext context) + { + return context.EditReqTaskMode || context.IsApprovalPhase && context.ApproveReqTaskMode && !context.ReadOnlyMode + && config.HasTaskFieldChanges(context.TaskType); + } + } + + public static class ApproverAllowedChangesCatalog + { + public static readonly List TicketFields = + [ + new(WorkflowEditableFieldKeys.Title), + new(WorkflowEditableFieldKeys.Priority), + new(WorkflowEditableFieldKeys.Deadline), + new(WorkflowEditableFieldKeys.Reason) + ]; + + public static readonly Dictionary> TaskTypeFields = new() + { + [WfTaskType.generic] = + [ + new(WorkflowEditableFieldKeys.Title), + new(WorkflowEditableFieldKeys.FreeText) + ], + [WfTaskType.access] = + [ + new(WorkflowEditableFieldKeys.Title), + new(WorkflowEditableFieldKeys.Management), + new(WorkflowEditableFieldKeys.Gateways), + new(WorkflowEditableFieldKeys.RuleAction), + new(WorkflowEditableFieldKeys.Track), + new(WorkflowEditableFieldKeys.ValidFrom), + new(WorkflowEditableFieldKeys.ValidTo), + new(WorkflowEditableFieldKeys.Reason), + new(WorkflowEditableFieldKeys.Source), + new(WorkflowEditableFieldKeys.Destination), + new(WorkflowEditableFieldKeys.Services) + ], + [WfTaskType.rule_modify] = + [ + new(WorkflowEditableFieldKeys.Title), + new(WorkflowEditableFieldKeys.Management), + new(WorkflowEditableFieldKeys.Gateway), + new(WorkflowEditableFieldKeys.RuleAction), + new(WorkflowEditableFieldKeys.Track), + new(WorkflowEditableFieldKeys.ValidFrom), + new(WorkflowEditableFieldKeys.ValidTo), + new(WorkflowEditableFieldKeys.Reason), + new(WorkflowEditableFieldKeys.Rules) + ], + [WfTaskType.rule_delete] = + [ + new(WorkflowEditableFieldKeys.Title), + new(WorkflowEditableFieldKeys.Management), + new(WorkflowEditableFieldKeys.Gateway), + new(WorkflowEditableFieldKeys.RuleAction), + new(WorkflowEditableFieldKeys.Track), + new(WorkflowEditableFieldKeys.ValidFrom), + new(WorkflowEditableFieldKeys.ValidTo), + new(WorkflowEditableFieldKeys.Reason), + new(WorkflowEditableFieldKeys.Rules) + ], + [WfTaskType.new_interface] = + [ + new(WorkflowEditableFieldKeys.Title), + new(WorkflowEditableFieldKeys.Owner), + new(WorkflowEditableFieldKeys.RequestingOwner), + new(WorkflowEditableFieldKeys.Reason) + ], + [WfTaskType.group_create] = + [ + new(WorkflowEditableFieldKeys.Title), + new(WorkflowEditableFieldKeys.Management), + new(WorkflowEditableFieldKeys.Name), + new(WorkflowEditableFieldKeys.Reason) + ] + }; + } +} diff --git a/roles/lib/files/FWO.Data/Workflow/NwObjectElement.cs b/roles/lib/files/FWO.Data/Workflow/NwObjectElement.cs new file mode 100644 index 0000000000..dc02dbc7cb --- /dev/null +++ b/roles/lib/files/FWO.Data/Workflow/NwObjectElement.cs @@ -0,0 +1,91 @@ +using System.Text.Json.Serialization; +using Newtonsoft.Json; +using NetTools; + +namespace FWO.Data.Workflow +{ + public class NwObjectElement + { + [JsonProperty("id"), JsonPropertyName("id")] + public long ElemId { get; set; } + + [JsonProperty("ip"), JsonPropertyName("ip")] + public string IpString + { + get { return Cidr.CidrString; } + set { Cidr = new Cidr(value); } + } + public Cidr Cidr { get; set; } = new(); + + [JsonProperty("ip_end"), JsonPropertyName("ip_end")] + public string IpEndString + { + get { return CidrEnd.CidrString; } // ?? Cidr.CidrString; } + set { CidrEnd = new Cidr(value ?? Cidr.CidrString); } // if End value is not set, asume host and set start ip as end ip + } + public Cidr CidrEnd { get; set; } = new(); + + [JsonProperty("name"), JsonPropertyName("name")] + public string? Name { get; set; } + + [JsonProperty("comment"), JsonPropertyName("comment")] + public string? Comment { get; set; } + + public long TaskId { get; set; } + public long? NetworkId { get; set; } + public string GroupName { get; set; } = ""; + public string RequestAction { get; set; } = Workflow.RequestAction.create.ToString(); + + public NwObjectElement() + { } + + public NwObjectElement(string cidrString, long taskId) + { + Cidr = new Cidr(cidrString); + TaskId = taskId; + } + + public NwObjectElement(IPAddressRange ipAddressRange, long taskId) + { + Cidr = new Cidr(ipAddressRange.Begin.ToString()); + if (ipAddressRange.End != null && ipAddressRange.End != ipAddressRange.Begin) + { + CidrEnd = new Cidr(ipAddressRange.End.ToString()); + } + TaskId = taskId; + } + + public WfReqElement ToReqElement(ElemFieldType field) + { + WfReqElement element = new() + { + Id = ElemId, + TaskId = TaskId, + Field = field.ToString(), + Cidr = new Cidr(Cidr.CidrString), + CidrEnd = new Cidr(CidrEnd.CidrString), + NetworkId = NetworkId, + GroupName = GroupName, + RequestAction = RequestAction, + Name = Name + }; + return element; + } + + public WfImplElement ToImplElement(ElemFieldType field) + { + WfImplElement element = new() + { + Id = ElemId, + ImplTaskId = TaskId, + Field = field.ToString(), + Cidr = new Cidr(Cidr.CidrString), + CidrEnd = new Cidr(CidrEnd.CidrString), + NetworkId = NetworkId, + GroupName = GroupName, + Name = Name + }; + return element; + } + } +} diff --git a/roles/lib/files/FWO.Data/Workflow/NwRuleElement.cs b/roles/lib/files/FWO.Data/Workflow/NwRuleElement.cs new file mode 100644 index 0000000000..b61276afdb --- /dev/null +++ b/roles/lib/files/FWO.Data/Workflow/NwRuleElement.cs @@ -0,0 +1,38 @@ +namespace FWO.Data.Workflow +{ + public class NwRuleElement + { + public long ElemId { get; set; } + public long TaskId { get; set; } + public string RuleUid { get; set; } = ""; + public string? Name { get; set; } = ""; + + + + public WfReqElement ToReqElement() + { + WfReqElement element = new() + { + Id = ElemId, + TaskId = TaskId, + Field = ElemFieldType.rule.ToString(), + RuleUid = RuleUid, + Name = Name + }; + return element; + } + + public WfImplElement ToImplElement() + { + WfImplElement element = new() + { + Id = ElemId, + ImplTaskId = TaskId, + Field = ElemFieldType.rule.ToString(), + RuleUid = RuleUid, + Name = Name + }; + return element; + } + } +} diff --git a/roles/lib/files/FWO.Data/Workflow/NwServiceElement.cs b/roles/lib/files/FWO.Data/Workflow/NwServiceElement.cs new file mode 100644 index 0000000000..c34694434a --- /dev/null +++ b/roles/lib/files/FWO.Data/Workflow/NwServiceElement.cs @@ -0,0 +1,47 @@ +namespace FWO.Data.Workflow +{ + public class NwServiceElement + { + public long ElemId { get; set; } + public long TaskId { get; set; } + public int Port { get; set; } + public int? PortEnd { get; set; } + public int ProtoId { get; set; } + public long? ServiceId { get; set; } + public string? Name { get; set; } + public string RequestAction { get; set; } = Workflow.RequestAction.create.ToString(); + + public WfReqElement ToReqElement() + { + WfReqElement element = new() + { + Id = ElemId, + TaskId = TaskId, + Field = ElemFieldType.service.ToString(), + Port = Port, + PortEnd = PortEnd, + ProtoId = ProtoId, + ServiceId = ServiceId, + Name = Name, + RequestAction = RequestAction + }; + return element; + } + + public WfImplElement ToImplElement() + { + WfImplElement element = new() + { + Id = ElemId, + ImplTaskId = TaskId, + Field = ElemFieldType.service.ToString(), + Port = Port, + PortEnd = PortEnd, + ProtoId = ProtoId, + ServiceId = ServiceId, + Name = Name + }; + return element; + } + } +} diff --git a/roles/lib/files/FWO.Data/Workflow/OwnerTicket.cs b/roles/lib/files/FWO.Data/Workflow/OwnerTicket.cs new file mode 100644 index 0000000000..38fdfa59ce --- /dev/null +++ b/roles/lib/files/FWO.Data/Workflow/OwnerTicket.cs @@ -0,0 +1,14 @@ +using Newtonsoft.Json; +using System.Text.Json.Serialization; + +namespace FWO.Data.Workflow +{ + public class OwnerTicket + { + [JsonProperty("owner"), JsonPropertyName("owner")] + public FwoOwner Owner { get; set; } = new(); + + [JsonProperty("ticket"), JsonPropertyName("ticket")] + public WfTicket Ticket { get; set; } = new(); + } +} diff --git a/roles/lib/files/FWO.Data/Workflow/WfApproval.cs b/roles/lib/files/FWO.Data/Workflow/WfApproval.cs new file mode 100644 index 0000000000..899502e844 --- /dev/null +++ b/roles/lib/files/FWO.Data/Workflow/WfApproval.cs @@ -0,0 +1,40 @@ +using System.Text.Json.Serialization; +using Newtonsoft.Json; + +namespace FWO.Data.Workflow +{ + public class WfApproval : WfApprovalBase + { + [JsonProperty("id"), JsonPropertyName("id")] + public long Id { get; set; } + + [JsonProperty("task_id"), JsonPropertyName("task_id")] + public long TaskId { get; set; } + + [JsonProperty("comments"), JsonPropertyName("comments")] + public List Comments { get; set; } = []; + + + public WfApproval() + { } + + public WfApproval(WfApproval approval) : base(approval) + { + Id = approval.Id; + TaskId = approval.TaskId; + Comments = approval.Comments; + } + } + + public class ApprovalParams + { + [JsonProperty("state_id"), JsonPropertyName("state_id")] + public int StateId { get; set; } + + [JsonProperty("approver_group"), JsonPropertyName("approver_group")] + public string ApproverGroup { get; set; } = ""; + + [JsonProperty("deadline"), JsonPropertyName("deadline")] + public int Deadline { get; set; } + } +} diff --git a/roles/lib/files/FWO.Data/Workflow/WfApprovalBase.cs b/roles/lib/files/FWO.Data/Workflow/WfApprovalBase.cs new file mode 100644 index 0000000000..8067408b67 --- /dev/null +++ b/roles/lib/files/FWO.Data/Workflow/WfApprovalBase.cs @@ -0,0 +1,56 @@ +using FWO.Basics; +using Newtonsoft.Json; +using System.Text.Json.Serialization; + +namespace FWO.Data.Workflow +{ + public class WfApprovalBase : WfStatefulObject + { + [JsonProperty("date_opened"), JsonPropertyName("date_opened")] + public DateTime DateOpened { get; set; } = DateTime.Now; + + [JsonProperty("approval_date"), JsonPropertyName("approval_date")] + public DateTime? ApprovalDate { get; set; } + + [JsonProperty("approval_deadline"), JsonPropertyName("approval_deadline")] + public DateTime? Deadline { get; set; } + + [JsonProperty("approver_group"), JsonPropertyName("approver_group")] + public string? ApproverGroup { get; set; } + + // [JsonProperty("approver"), JsonPropertyName("approver")] + // public UiUser? Approver { get; set; } + + [JsonProperty("approver"), JsonPropertyName("approver")] + public string? ApproverDn { get; set; } = ""; + + [JsonProperty("tenant_id"), JsonPropertyName("tenant_id")] + public int? TenantId { get; set; } + + [JsonProperty("initial_approval"), JsonPropertyName("initial_approval")] + public bool InitialApproval { get; set; } = true; + + + public WfApprovalBase() + { } + + public WfApprovalBase(WfApprovalBase approval) : base(approval) + { + DateOpened = approval.DateOpened; + ApprovalDate = approval.ApprovalDate; + Deadline = approval.Deadline; + ApproverGroup = approval.ApproverGroup; + ApproverDn = approval.ApproverDn; + TenantId = approval.TenantId; + InitialApproval = approval.InitialApproval; + } + + public override bool Sanitize() + { + bool shortened = base.Sanitize(); + ApproverGroup = ApproverGroup.SanitizeLdapPathOpt(ref shortened); + ApproverDn = ApproverDn.SanitizeLdapPathOpt(ref shortened); + return shortened; + } + } +} diff --git a/roles/lib/files/FWO.Data/Workflow/WfApprovalWriter.cs b/roles/lib/files/FWO.Data/Workflow/WfApprovalWriter.cs new file mode 100644 index 0000000000..82c1fee482 --- /dev/null +++ b/roles/lib/files/FWO.Data/Workflow/WfApprovalWriter.cs @@ -0,0 +1,8 @@ +namespace FWO.Data.Workflow +{ + public class WfApprovalWriter : WfApprovalBase + { + public WfApprovalWriter(WfApproval approval) : base(approval) + { } + } +} diff --git a/roles/lib/files/FWO.Data/Workflow/WfComment.cs b/roles/lib/files/FWO.Data/Workflow/WfComment.cs new file mode 100644 index 0000000000..7f6ec985be --- /dev/null +++ b/roles/lib/files/FWO.Data/Workflow/WfComment.cs @@ -0,0 +1,35 @@ +using System.Text.Json.Serialization; +using Newtonsoft.Json; + +namespace FWO.Data.Workflow +{ + public class WfComment : WfCommentBase + { + [JsonProperty("id"), JsonPropertyName("id")] + public long Id { get; set; } + + + public WfComment() + { } + + public WfComment(WfComment comment) : base(comment) + { + Id = comment.Id; + } + } + + public class WfCommentDataHelper + { + [JsonProperty("comment"), JsonPropertyName("comment")] + public WfComment Comment { get; set; } = new(); + + + public WfCommentDataHelper() + { } + + public WfCommentDataHelper(WfComment comment) + { + Comment = comment; + } + } +} diff --git a/roles/lib/files/FWO.Data/Workflow/WfCommentBase.cs b/roles/lib/files/FWO.Data/Workflow/WfCommentBase.cs new file mode 100644 index 0000000000..e04cb89cc9 --- /dev/null +++ b/roles/lib/files/FWO.Data/Workflow/WfCommentBase.cs @@ -0,0 +1,45 @@ +using FWO.Basics; +using Newtonsoft.Json; +using System.Text.Json.Serialization; + +namespace FWO.Data.Workflow +{ + public class WfCommentBase + { + [JsonProperty("ref_id"), JsonPropertyName("ref_id")] + public long? RefId { get; set; } + + [JsonProperty("scope"), JsonPropertyName("scope")] + public string Scope { get; set; } = ""; + + [JsonProperty("creation_date"), JsonPropertyName("creation_date")] + public DateTime CreationDate { get; set; } = DateTime.Now; + + [JsonProperty("creator"), JsonPropertyName("creator")] + public UiUser Creator { get; set; } = new UiUser(); + + [JsonProperty("comment_text"), JsonPropertyName("comment_text")] + public string CommentText { get; set; } = ""; + + + public WfCommentBase() + { } + + public WfCommentBase(WfCommentBase comment) + { + RefId = comment.RefId; + Scope = comment.Scope; + CreationDate = comment.CreationDate; + Creator = comment.Creator; + CommentText = comment.CommentText; + } + + public virtual bool Sanitize() + { + bool shortened = false; + Scope = Scope.SanitizeMand(ref shortened); + CommentText = CommentText.SanitizeMand(ref shortened); + return shortened; + } + } +} diff --git a/roles/lib/files/FWO.Data/Workflow/WfElementBase.cs b/roles/lib/files/FWO.Data/Workflow/WfElementBase.cs new file mode 100644 index 0000000000..8fec7c4181 --- /dev/null +++ b/roles/lib/files/FWO.Data/Workflow/WfElementBase.cs @@ -0,0 +1,101 @@ +using FWO.Basics; +using Newtonsoft.Json; +using System.Text.Json.Serialization; + +namespace FWO.Data.Workflow +{ + public enum ElemFieldType + { + source, + destination, + service, + rule, + modelled_source, + modelled_destination + } + + public class WfElementBase + { + [JsonProperty("ip"), JsonPropertyName("ip")] + public string? IpString { get; set; } + + [JsonProperty("ip_end"), JsonPropertyName("ip_end")] + public string? IpEnd { get; set; } + + [JsonProperty("port"), JsonPropertyName("port")] + public int? Port { get; set; } + + [JsonProperty("port_end"), JsonPropertyName("port_end")] + public int? PortEnd { get; set; } + + [JsonProperty("ip_proto_id"), JsonPropertyName("ip_proto_id")] + public int? ProtoId { get; set; } + + [JsonProperty("network_object_id"), JsonPropertyName("network_object_id")] + public long? NetworkId { get; set; } + + [JsonProperty("service_id"), JsonPropertyName("service_id")] + public long? ServiceId { get; set; } + + [JsonProperty("field"), JsonPropertyName("field")] + public string Field { get; set; } = ElemFieldType.source.ToString(); + + [JsonProperty("user_id"), JsonPropertyName("user_id")] + public long? UserId { get; set; } + + [JsonProperty("original_nat_id"), JsonPropertyName("original_nat_id")] + public long? OriginalNatId { get; set; } + + [JsonProperty("rule_uid"), JsonPropertyName("rule_uid")] + public string? RuleUid { get; set; } + + [JsonProperty("group_name"), JsonPropertyName("group_name")] + public string? GroupName { get; set; } + + [JsonProperty("name"), JsonPropertyName("name")] + public string? Name { get; set; } + + + public WfElementBase() + { } + + public WfElementBase(WfElementBase element) + { + IpString = element.IpString; + IpEnd = element.IpEnd; + Port = element.Port; + PortEnd = element.PortEnd; + ProtoId = element.ProtoId; + NetworkId = element.NetworkId; + ServiceId = element.ServiceId; + Field = element.Field; + UserId = element.UserId; + OriginalNatId = element.OriginalNatId; + RuleUid = element.RuleUid; + GroupName = element.GroupName; + Name = element.Name; + } + + public static NetworkObject ToNetworkObject(WfElementBase elem) + { + return new NetworkObject() + { + Name = elem.Name ?? "", + IP = elem.IpString ?? "", + IpEnd = elem.IpEnd ?? "" + }; + } + + public virtual bool Sanitize() + { + bool shortened = false; + IpString = IpString.SanitizeOpt(ref shortened); + IpEnd = IpEnd.SanitizeOpt(ref shortened); + Field = Field.SanitizeMand(ref shortened); + RuleUid = RuleUid.SanitizeOpt(ref shortened); + GroupName = GroupName.SanitizeOpt(ref shortened); + Name = Name.SanitizeOpt(ref shortened); + return shortened; + } + } +} diff --git a/roles/lib/files/FWO.Data/Workflow/WfExtState.cs b/roles/lib/files/FWO.Data/Workflow/WfExtState.cs new file mode 100644 index 0000000000..119c56d404 --- /dev/null +++ b/roles/lib/files/FWO.Data/Workflow/WfExtState.cs @@ -0,0 +1,18 @@ +using System.Text.Json.Serialization; +using Newtonsoft.Json; + + +namespace FWO.Data.Workflow +{ + public class WfExtState + { + [JsonProperty("id"), JsonPropertyName("id")] + public int? Id { get; set; } + + [JsonProperty("name"), JsonPropertyName("name")] + public string Name { get; set; } = ""; + + [JsonProperty("state_id"), JsonPropertyName("state_id")] + public int? StateId { get; set; } + } +} diff --git a/roles/lib/files/FWO.Data/Workflow/WfImplElement.cs b/roles/lib/files/FWO.Data/Workflow/WfImplElement.cs new file mode 100644 index 0000000000..fcae09c087 --- /dev/null +++ b/roles/lib/files/FWO.Data/Workflow/WfImplElement.cs @@ -0,0 +1,50 @@ +using System.Text.Json.Serialization; +using Newtonsoft.Json; + +namespace FWO.Data.Workflow +{ + public class WfImplElement : WfElementBase + { + [JsonProperty("id"), JsonPropertyName("id")] + public long Id { get; set; } + + [JsonProperty("implementation_task_id"), JsonPropertyName("implementation_task_id")] + public long ImplTaskId { get; set; } + + [JsonProperty("implementation_action"), JsonPropertyName("implementation_action")] + public string ImplAction { get; set; } = "create"; + + public Cidr? Cidr { get; set; } = new(); + public Cidr? CidrEnd { get; set; } = new(); + + public WfImplElement() + { } + + public WfImplElement(WfImplElement element) : base(element) + { + Id = element.Id; + ImplTaskId = element.ImplTaskId; + ImplAction = element.ImplAction; + Cidr = element.Cidr; + CidrEnd = element.CidrEnd; + } + + public WfImplElement(WfReqElement element) + { + Id = 0; + ImplAction = element.RequestAction; + Cidr = element.Cidr; + CidrEnd = element.CidrEnd; + Port = element.Port; + PortEnd = element.PortEnd; + ProtoId = element.ProtoId; + NetworkId = element.NetworkId; + ServiceId = element.ServiceId; + Field = element.Field; + UserId = element.UserId; + OriginalNatId = element.OriginalNatId; + RuleUid = element.RuleUid; + GroupName = element.GroupName; + } + } +} diff --git a/roles/lib/files/FWO.Data/Workflow/WfImplTask.cs b/roles/lib/files/FWO.Data/Workflow/WfImplTask.cs new file mode 100644 index 0000000000..723aa5548e --- /dev/null +++ b/roles/lib/files/FWO.Data/Workflow/WfImplTask.cs @@ -0,0 +1,160 @@ +using System.Text.Json.Serialization; +using Newtonsoft.Json; + +namespace FWO.Data.Workflow +{ + public class WfImplTask : WfTaskBase + { + [JsonProperty("id"), JsonPropertyName("id")] + public long Id { get; set; } + + [JsonProperty("reqtask_id"), JsonPropertyName("reqtask_id")] + public long ReqTaskId { get; set; } + + [JsonProperty("device_id"), JsonPropertyName("device_id")] + public int? DeviceId { get; set; } + + [JsonProperty("implementation_action"), JsonPropertyName("implementation_action")] + public string ImplAction { get; set; } = RequestAction.create.ToString(); + + [JsonProperty("elements"), JsonPropertyName("elements")] + public List ImplElements { get; set; } = []; + + [JsonProperty("comments"), JsonPropertyName("comments")] + public List Comments { get; set; } = []; + + + public List RemovedElements { get; set; } = []; + public long TicketId { get; set; } + + + public WfImplTask() + { } + + public WfImplTask(WfImplTask implTask) : base(implTask) + { + Id = implTask.Id; + ReqTaskId = implTask.ReqTaskId; + ImplAction = implTask.ImplAction; + DeviceId = implTask.DeviceId; + ImplElements = implTask.ImplElements; + Comments = implTask.Comments; + RemovedElements = implTask.RemovedElements; + TicketId = implTask.TicketId; + } + + + public WfImplTask(WfReqTask reqtask, bool copyComments = true) + { + Id = 0; + Title = reqtask.Title; + ReqTaskId = reqtask.Id; + TaskNumber = 0; + StateId = 0; + TaskType = reqtask.TaskType; + ImplAction = reqtask.RequestAction; + RuleAction = reqtask.RuleAction; + Tracking = reqtask.Tracking; + Start = null; + Stop = null; + ServiceGroupId = reqtask.ServiceGroupId; + NetworkGroupId = reqtask.NetworkGroupId; + UserGroupId = reqtask.UserGroupId; + CurrentHandler = reqtask.CurrentHandler; + RecentHandler = reqtask.RecentHandler; + AssignedGroup = reqtask.AssignedGroup; + TargetBeginDate = reqtask.TargetBeginDate; + TargetEndDate = reqtask.TargetEndDate; + FreeText = reqtask.FreeText; + DeviceId = null; + TicketId = reqtask.TicketId; + if (reqtask.Elements != null && reqtask.Elements.Count > 0) + { + if (reqtask.TaskType == WfTaskType.rule_delete.ToString()) + { + DeviceId = reqtask.Elements[0].DeviceId; + } + ImplElements = new List(); + foreach (WfReqElement element in reqtask.Elements) + { + ImplElements.Add(new WfImplElement(element)); + } + } + if (copyComments) + { + foreach (var comm in reqtask.Comments) + { + comm.Comment.Scope = WfObjectScopes.ImplementationTask.ToString(); + Comments.Add(comm); + } + } + } + + public override bool Sanitize() + { + bool shortened = base.Sanitize(); + return shortened; + } + + public List GetNwObjectElements(ElemFieldType field) + { + List elements = []; + foreach (var implElem in ImplElements) + { + if (implElem.Field == field.ToString()) + { + elements.Add(new NwObjectElement() + { + ElemId = implElem.Id, + TaskId = implElem.ImplTaskId, + Cidr = new Cidr(implElem.Cidr != null ? implElem.Cidr.CidrString : ""), + IpString = implElem.IpString ?? "", + NetworkId = implElem.NetworkId, + Name = implElem.Name + }); + } + } + return elements; + } + + public List GetServiceElements() + { + List elements = []; + foreach (var implElem in ImplElements) + { + if (implElem.Field == ElemFieldType.service.ToString()) + { + elements.Add(new NwServiceElement() + { + ElemId = implElem.Id, + TaskId = implElem.ImplTaskId, + Port = implElem.Port ?? 0, + PortEnd = implElem.PortEnd, + ProtoId = implElem.ProtoId ?? 0, + ServiceId = implElem.ServiceId + }); + } + } + return elements; + } + + public List GetRuleElements() + { + List elements = []; + foreach (var implElem in ImplElements) + { + if (implElem.Field == ElemFieldType.rule.ToString()) + { + elements.Add(new NwRuleElement() + { + ElemId = implElem.Id, + TaskId = implElem.ImplTaskId, + RuleUid = implElem.RuleUid ?? "", + Name = implElem.Name + }); + } + } + return elements; + } + } +} diff --git a/roles/lib/files/FWO.Data/Workflow/WfOwnerWriter.cs b/roles/lib/files/FWO.Data/Workflow/WfOwnerWriter.cs new file mode 100644 index 0000000000..913ebf5fb7 --- /dev/null +++ b/roles/lib/files/FWO.Data/Workflow/WfOwnerWriter.cs @@ -0,0 +1,16 @@ +using System.Text.Json.Serialization; +using Newtonsoft.Json; + +namespace FWO.Data.Workflow +{ + public class WfOwnerWriter + { + [JsonProperty("owner_id"), JsonPropertyName("owner_id")] + public int? OwnerId { get; set; } + + public WfOwnerWriter(FwoOwner owner) + { + OwnerId = owner.Id; + } + } +} diff --git a/roles/lib/files/FWO.Data/Workflow/WfPriority.cs b/roles/lib/files/FWO.Data/Workflow/WfPriority.cs new file mode 100644 index 0000000000..c4a228abd5 --- /dev/null +++ b/roles/lib/files/FWO.Data/Workflow/WfPriority.cs @@ -0,0 +1,21 @@ +using System.Text.Json.Serialization; +using Newtonsoft.Json; + + +namespace FWO.Data.Workflow +{ + public class WfPriority + { + [JsonProperty("numeric_prio"), JsonPropertyName("numeric_prio")] + public int NumPrio { get; set; } + + [JsonProperty("name"), JsonPropertyName("name")] + public string Name { get; set; } = ""; + + [JsonProperty("ticket_deadline"), JsonPropertyName("ticket_deadline")] + public int TicketDeadline { get; set; } + + [JsonProperty("approval_deadline"), JsonPropertyName("approval_deadline")] + public int ApprovalDeadline { get; set; } + } +} diff --git a/roles/lib/files/FWO.Data/Workflow/WfReqElement.cs b/roles/lib/files/FWO.Data/Workflow/WfReqElement.cs new file mode 100644 index 0000000000..2d9a1dec15 --- /dev/null +++ b/roles/lib/files/FWO.Data/Workflow/WfReqElement.cs @@ -0,0 +1,37 @@ +using System.Text.Json.Serialization; +using Newtonsoft.Json; + +namespace FWO.Data.Workflow +{ + public class WfReqElement : WfElementBase + { + [JsonProperty("id"), JsonPropertyName("id")] + public long Id { get; set; } + + [JsonProperty("task_id"), JsonPropertyName("task_id")] + public long TaskId { get; set; } + + [JsonProperty("request_action"), JsonPropertyName("request_action")] + public string RequestAction { get; set; } = Workflow.RequestAction.create.ToString(); + + [JsonProperty("device_id"), JsonPropertyName("device_id")] + public int? DeviceId { get; set; } + + public Cidr? Cidr { get; set; } = new(); + public Cidr? CidrEnd { get; set; } = new(); + + + public WfReqElement() + { } + + public WfReqElement(WfReqElement element) : base(element) + { + Id = element.Id; + TaskId = element.TaskId; + RequestAction = element.RequestAction; + DeviceId = element.DeviceId; + Cidr = element.Cidr; + CidrEnd = element.CidrEnd; + } + } +} diff --git a/roles/lib/files/FWO.Data/Workflow/WfReqElementWriter.cs b/roles/lib/files/FWO.Data/Workflow/WfReqElementWriter.cs new file mode 100644 index 0000000000..ce1ce138cd --- /dev/null +++ b/roles/lib/files/FWO.Data/Workflow/WfReqElementWriter.cs @@ -0,0 +1,22 @@ +using System.Text.Json.Serialization; +using Newtonsoft.Json; + +namespace FWO.Data.Workflow +{ + public class WfReqElementWriter : WfElementBase + { + [JsonProperty("request_action"), JsonPropertyName("request_action")] + public string RequestAction { get; set; } = Workflow.RequestAction.create.ToString(); + + [JsonProperty("device_id"), JsonPropertyName("device_id")] + public int? DeviceId { get; set; } + + public WfReqElementWriter(WfReqElement element) : base(element) + { + RequestAction = element.RequestAction; + DeviceId = element.DeviceId; + IpString = element.Cidr != null && element.Cidr.Valid ? element.Cidr.CidrString : null; + IpEnd = element.CidrEnd != null && element.CidrEnd.Valid ? element.CidrEnd.CidrString : null; + } + } +} diff --git a/roles/lib/files/FWO.Data/Workflow/WfReqTask.cs b/roles/lib/files/FWO.Data/Workflow/WfReqTask.cs new file mode 100644 index 0000000000..40bbb72c29 --- /dev/null +++ b/roles/lib/files/FWO.Data/Workflow/WfReqTask.cs @@ -0,0 +1,178 @@ +using System.Text.Json.Serialization; +using Newtonsoft.Json; + +namespace FWO.Data.Workflow +{ + public class WfReqTask : WfReqTaskBase + { + [JsonProperty("id"), JsonPropertyName("id")] + public long Id { get; set; } + + [JsonProperty("ticket_id"), JsonPropertyName("ticket_id")] + public long TicketId { get; set; } + + [JsonProperty("elements"), JsonPropertyName("elements")] + public List Elements { get; set; } = []; + + [JsonProperty("implementation_tasks"), JsonPropertyName("implementation_tasks")] + public List ImplementationTasks { get; set; } = []; + + [JsonProperty("request_approvals"), JsonPropertyName("request_approvals")] + public List Approvals { get; set; } = []; + + [JsonProperty("owners"), JsonPropertyName("owners")] + public List Owners { get; set; } = []; + + [JsonProperty("comments"), JsonPropertyName("comments")] + public List Comments { get; set; } = []; + + [JsonProperty("on_management"), JsonPropertyName("on_management")] + public Management? OnManagement { get; set; } + + public List RemovedElements { get; set; } = []; + public List NewOwners { get; set; } = []; + public List RemovedOwners { get; set; } = []; + + public WfReqTask() + { } + + public WfReqTask(WfReqTask reqtask) : base(reqtask) + { + Id = reqtask.Id; + TicketId = reqtask.TicketId; + Elements = reqtask.Elements; + ImplementationTasks = reqtask.ImplementationTasks; + Approvals = reqtask.Approvals; + Owners = reqtask.Owners; + Comments = reqtask.Comments; + RemovedElements = reqtask.RemovedElements; + NewOwners = reqtask.NewOwners; + RemovedOwners = reqtask.RemovedOwners; + OnManagement = reqtask.OnManagement; + } + + public string OwnerList() + { + List ownerNames = []; + foreach (var owner in Owners) + { + ownerNames.Add(owner.Owner.Name); + } + return string.Join(", ", ownerNames); + } + + public int HighestImplTaskNumber() + { + int highestNumber = 0; + foreach (var implTask in ImplementationTasks) + { + if (implTask.TaskNumber > highestNumber) + { + highestNumber = implTask.TaskNumber; + } + } + return highestNumber; + } + + public List GetNwObjectElements(ElemFieldType field) + { + List elements = []; + foreach (var reqElem in Elements) + { + if (reqElem.Field == field.ToString()) + { + elements.Add(new NwObjectElement() + { + ElemId = reqElem.Id, + TaskId = reqElem.TaskId, + Cidr = new Cidr(reqElem.Cidr != null ? reqElem.Cidr.CidrString : ""), + CidrEnd = new Cidr(reqElem.CidrEnd != null ? reqElem.CidrEnd.CidrString : ""), + IpString = reqElem.IpString ?? "", + NetworkId = reqElem.NetworkId, + RequestAction = reqElem.RequestAction, + Name = reqElem.Name, + GroupName = reqElem.GroupName ?? "" + }); + } + } + return elements; + } + + public List GetServiceElements() + { + List elements = []; + foreach (var reqElem in Elements) + { + if (reqElem.Field == ElemFieldType.service.ToString()) + { + elements.Add(new NwServiceElement() + { + ElemId = reqElem.Id, + TaskId = reqElem.TaskId, + Port = reqElem.Port ?? 0, + PortEnd = reqElem.PortEnd, + ProtoId = reqElem.ProtoId ?? 0, + ServiceId = reqElem.ServiceId, + Name = reqElem.Name, + RequestAction = reqElem.RequestAction + }); + } + } + return elements; + } + + public List GetRuleElements() + { + List elements = []; + foreach (var reqElem in Elements) + { + if (reqElem.Field == ElemFieldType.rule.ToString()) + { + elements.Add(new NwRuleElement() + { + ElemId = reqElem.Id, + TaskId = reqElem.TaskId, + RuleUid = reqElem.RuleUid ?? "", + Name = reqElem.Name + }); + } + } + return elements; + } + + public string GetFirstCommentText() + { + if (Comments.Count > 0) + { + return Comments[0].Comment.CommentText; + } + return ""; + } + + public int GetRuleDeviceId() + { + foreach (var reqElem in Elements) + { + if (reqElem.Field == ElemFieldType.rule.ToString() && reqElem.DeviceId != null) + { + return (int)reqElem.DeviceId; + } + } + return 0; + } + + public override List GetDeviceList() + { + if (DeviceList.Count > 0) + { + return DeviceList; + } + return [.. Elements.Where(r => r.Field == ElemFieldType.rule.ToString() && r.DeviceId != null).Select(e => (int)e.DeviceId!)]; + } + + public bool IsNetworkFlavor() + { + return Elements.FirstOrDefault(e => e.IpString != null) != null; + } + } +} diff --git a/roles/lib/files/FWO.Data/Workflow/WfReqTaskBase.cs b/roles/lib/files/FWO.Data/Workflow/WfReqTaskBase.cs new file mode 100644 index 0000000000..ceb68cc7e2 --- /dev/null +++ b/roles/lib/files/FWO.Data/Workflow/WfReqTaskBase.cs @@ -0,0 +1,174 @@ +using FWO.Basics; +using Newtonsoft.Json; +using System.Text.Json.Serialization; + +namespace FWO.Data.Workflow +{ + public enum AutoCreateImplTaskOptions + { + never, + onlyForOneDevice, + forEachDevice, + enterInReqTask, + oneTaskForAllDevices, + afterPathAnalysis + } + + public struct AdditionalInfoKeys + { + public const string ConnId = "ConnId"; + public const string ReqOwner = "ReqOwner"; + public const string GrpName = "GrpName"; + public const string ExtIcketId = "ExtIcketId"; + public const string AppRoleId = "AppRoleId"; + public const string SvcGrpId = "SvcGrpId"; + } + + public class WfReqTaskBase : WfTaskBase + { + public const int kAllDevicesId = -1; + + [JsonProperty("request_action"), JsonPropertyName("request_action")] + public string RequestAction { get; set; } = Workflow.RequestAction.create.ToString(); + + [JsonProperty("reason"), JsonPropertyName("reason")] + public string? Reason { get; set; } + + [JsonProperty("additional_info"), JsonPropertyName("additional_info")] + public string? AdditionalInfo { get; set; } + + [JsonProperty("last_recert_date"), JsonPropertyName("last_recert_date")] + public DateTime? LastRecertDate { get; set; } + + [JsonProperty("mgm_id"), JsonPropertyName("mgm_id")] + public int? ManagementId { get; set; } + + [JsonProperty("devices"), JsonPropertyName("devices")] + public string SelectedDevices + { + get => System.Text.Json.JsonSerializer.Serialize>(DeviceList) ?? throw new JsonException("DeviceList could not be parsed."); + set + { + if (value != null && value != "") + { + DeviceList = System.Text.Json.JsonSerializer.Deserialize>(value) ?? throw new JsonException("value could not be parsed."); + } + } + } + + protected List DeviceList { get; set; } = []; + + + public WfReqTaskBase() + { } + + public WfReqTaskBase(WfReqTaskBase reqtask) : base(reqtask) + { + RequestAction = reqtask.RequestAction; + Reason = reqtask.Reason; + AdditionalInfo = reqtask.AdditionalInfo; + LastRecertDate = reqtask.LastRecertDate; + SelectedDevices = reqtask.SelectedDevices; + ManagementId = reqtask.ManagementId; + } + + public virtual List GetDeviceList() + { + return DeviceList; + } + + public bool HasAllDevicesSelected() + { + return GetDeviceList().Contains(kAllDevicesId); + } + + public virtual List GetResolvedDeviceList(List devices) + { + if (HasAllDevicesSelected()) + { + return [.. devices.Select(device => device.Id)]; + } + return GetDeviceList(); + } + + public void SetDeviceList(List deviceIds) + { + DeviceList = [.. deviceIds]; + } + + public void SetDeviceList(List devList) + { + SetDeviceList([.. devList.Select(dev => dev.Id)]); + } + + public int? GetAddInfoIntValue(string key) + { + if (int.TryParse(GetAddInfoValue(key), out int value)) + { + return value; + } + return null; + } + + public int GetAddInfoIntValueOrZero(string key) + { + if (int.TryParse(GetAddInfoValue(key), out int value)) + { + return value; + } + return 0; + } + + public long? GetAddInfoLongValue(string key) + { + if (long.TryParse(GetAddInfoValue(key), out long value)) + { + return value; + } + return null; + } + + public string GetAddInfoValue(string key) + { + Dictionary? addInfo = GetAddInfos(); + if (addInfo != null && addInfo.TryGetValue(key, out string? value)) + { + return value; + } + return ""; + } + + public void SetAddInfo(string key, string newValue) + { + Dictionary? addInfo = GetAddInfos(); + if (addInfo == null) + { + addInfo = new() { { key, newValue } }; + } + else + { + if (!addInfo.TryAdd(key, newValue)) + { + addInfo[key] = newValue; + } + } + AdditionalInfo = System.Text.Json.JsonSerializer.Serialize(addInfo); + } + + private Dictionary? GetAddInfos() + { + if (AdditionalInfo != null && AdditionalInfo != "") + { + return System.Text.Json.JsonSerializer.Deserialize>(AdditionalInfo); + } + return null; + } + + public override bool Sanitize() + { + bool shortened = base.Sanitize(); + Reason = Reason.SanitizeOpt(ref shortened); + return shortened; + } + } +} diff --git a/roles/lib/files/FWO.Data/Workflow/WfReqTaskWriter.cs b/roles/lib/files/FWO.Data/Workflow/WfReqTaskWriter.cs new file mode 100644 index 0000000000..4d712389ab --- /dev/null +++ b/roles/lib/files/FWO.Data/Workflow/WfReqTaskWriter.cs @@ -0,0 +1,51 @@ +using System.Text.Json.Serialization; +using Newtonsoft.Json; + +namespace FWO.Data.Workflow +{ + public class WfReqTaskWriter : WfReqTaskBase + { + [JsonProperty("elements"), JsonPropertyName("elements")] + public WfElementDataHelper Elements { get; set; } = new(); + + [JsonProperty("approvals"), JsonPropertyName("approvals")] + public WfApprovalDataHelper Approvals { get; set; } = new(); + + [JsonProperty("reqtask_owners"), JsonPropertyName("reqtask_owners")] + public WfOwnerDataHelper Owners { get; set; } = new(); + + public WfReqTaskWriter(WfReqTask reqtask) : base(reqtask) + { + foreach (var element in reqtask.Elements) + { + Elements.WfElementList.Add(new WfReqElementWriter(element)); + } + foreach (var approval in reqtask.Approvals) + { + Approvals.WfApprovalList.Add(new WfApprovalWriter(approval)); + } + foreach (var owner in reqtask.Owners) + { + Owners.WfOwnerList.Add(new WfOwnerWriter(owner.Owner)); + } + } + } + + public class WfElementDataHelper + { + [JsonProperty("data"), JsonPropertyName("data")] + public List WfElementList { get; set; } = []; + } + + public class WfApprovalDataHelper + { + [JsonProperty("data"), JsonPropertyName("data")] + public List WfApprovalList { get; set; } = []; + } + + public class WfOwnerDataHelper + { + [JsonProperty("data"), JsonPropertyName("data")] + public List WfOwnerList { get; set; } = []; + } +} diff --git a/roles/lib/files/FWO.Data/Workflow/WfStateAction.cs b/roles/lib/files/FWO.Data/Workflow/WfStateAction.cs new file mode 100644 index 0000000000..e531bcaed4 --- /dev/null +++ b/roles/lib/files/FWO.Data/Workflow/WfStateAction.cs @@ -0,0 +1,139 @@ +using System.Text.Json.Serialization; +using Newtonsoft.Json; +using Newtonsoft.Json.Converters; + +namespace FWO.Data.Workflow +{ + public enum StateActionTypes + { + DoNothing = 0, + AutoPromote = 1, + AddApproval = 2, + SetAlert = 5, + TrafficPathAnalysis = 6, + ExternalCall = 10, + SendEmail = 15, + UpdateConnectionOwner = 21, + UpdateConnectionRelease = 22, + DisplayConnection = 23, + UpdateConnectionReject = 24 + // CreateReport = 30 + } + + public enum StateActionEvents + { + None = 0, + OnSet = 1, + OnLeave = 2, + // WhileSet = 3, + OfferButton = 4, + OwnerChange = 10, + OnAssignment = 15 + } + + public enum ToBeCalled + { + PolicyCheck = 1 + } + + public class WfStateAction + { + [JsonProperty("id"), JsonPropertyName("id")] + public int Id { get; set; } + + [JsonProperty("name"), JsonPropertyName("name")] + public string Name { get; set; } = ""; + + [JsonProperty("action_type"), JsonPropertyName("action_type")] + public string ActionType { get; set; } = StateActionTypes.DoNothing.ToString(); + + [JsonProperty("scope"), JsonPropertyName("scope")] + public string Scope { get; set; } = WfObjectScopes.None.ToString(); + + [JsonProperty("task_type"), JsonPropertyName("task_type")] + public string TaskType { get; set; } = ""; + + [JsonProperty("phase"), JsonPropertyName("phase")] + public string Phase { get; set; } = ""; + + [JsonProperty("event"), JsonPropertyName("event")] + public string? Event { get; set; } = StateActionEvents.None.ToString(); + + [JsonProperty("button_text"), JsonPropertyName("button_text")] + public string? ButtonText { get; set; } = ""; + + [JsonProperty("external_parameters"), JsonPropertyName("external_parameters")] + public string ExternalParams { get; set; } = ""; + + + public WfStateAction() + { } + + public static bool IsReadonlyType(string actionTypeString) + { + if (Enum.TryParse(actionTypeString, out StateActionTypes actionType)) + { + return actionType switch + { + StateActionTypes.TrafficPathAnalysis => true, + StateActionTypes.DisplayConnection => true, + _ => false, + }; + } + return false; + } + + public static bool TryParseAutoPromoteParams(string externalParams, out int? toStateId, out ConditionalAutoPromoteParams? conditionalParams) + { + toStateId = null; + conditionalParams = null; + + if (string.IsNullOrWhiteSpace(externalParams)) + { + return true; + } + + if (int.TryParse(externalParams, out int parsedStateId)) + { + toStateId = parsedStateId; + return true; + } + + try + { + conditionalParams = System.Text.Json.JsonSerializer.Deserialize(externalParams); + return conditionalParams != null; + } + catch + { + return false; + } + } + } + + public class ConditionalAutoPromoteParams + { + [Newtonsoft.Json.JsonConverter(typeof(StringEnumConverter))] + [System.Text.Json.Serialization.JsonConverter(typeof(JsonStringEnumConverter))] + [JsonProperty("to_be_called"), JsonPropertyName("to_be_called")] + public ToBeCalled ToBeCalled { get; set; } = ToBeCalled.PolicyCheck; + + [JsonProperty("policy_ids"), JsonPropertyName("policy_ids")] + public List PolicyIds { get; set; } = []; + + [JsonProperty("check_result_label"), JsonPropertyName("check_result_label")] + public string CheckResultLabel { get; set; } = ""; + + [JsonProperty("if_compliant_state"), JsonPropertyName("if_compliant_state")] + public int IfCompliantState { get; set; } + + [JsonProperty("if_not_compliant_state"), JsonPropertyName("if_not_compliant_state")] + public int IfNotCompliantState { get; set; } + } + + public class WfStateActionDataHelper + { + [JsonProperty("action"), JsonPropertyName("action")] + public WfStateAction Action { get; set; } = new WfStateAction(); + } +} diff --git a/roles/lib/files/FWO.Data/Workflow/WfStatefulObject.cs b/roles/lib/files/FWO.Data/Workflow/WfStatefulObject.cs new file mode 100644 index 0000000000..19db364804 --- /dev/null +++ b/roles/lib/files/FWO.Data/Workflow/WfStatefulObject.cs @@ -0,0 +1,109 @@ +using FWO.Basics; +using Newtonsoft.Json; +using System.Text.Json.Serialization; + +namespace FWO.Data.Workflow +{ + public enum WfObjectScopes + { + None = 0, + Ticket = 1, + RequestTask = 2, + ImplementationTask = 3, + Approval = 4 + } + + public class WfStatefulObject + { + [JsonProperty("state_id"), JsonPropertyName("state_id")] + public int StateId + { + get { return stateId; } + set + { + if (!stateChanged) + { + stateChanged = oldStateId != value; + oldStateId = stateId; + } + stateId = value; + } + } + + [JsonProperty("current_handler"), JsonPropertyName("current_handler")] + public UiUser? CurrentHandler { get; set; } + + [JsonProperty("recent_handler"), JsonPropertyName("recent_handler")] + public UiUser? RecentHandler { get; set; } + + [JsonProperty("assigned_group"), JsonPropertyName("assigned_group")] + public string? AssignedGroup { get; set; } + + + // need private declarations, else we get problems with request_reqtask_arr_rel_insert_input in newTicket + private int stateId; + private int oldStateId; + private bool stateChanged = false; + private string? optComment; + + public string? OptComment() + { + return optComment; + } + + public void SetOptComment(string? comm) + { + optComment = comm; + } + + public bool StateChanged() + { + return stateChanged; + } + + public int ChangedFrom() + { + return oldStateId; + } + + public void ResetStateChanged() + { + oldStateId = stateId; + stateChanged = false; + } + + public WfStatefulObject() + { } + + public WfStatefulObject(WfStatefulObject obj) + { + stateId = obj.stateId; + oldStateId = obj.oldStateId; + stateChanged = obj.stateChanged; + optComment = obj.optComment; + CurrentHandler = obj.CurrentHandler; + RecentHandler = obj.RecentHandler; + AssignedGroup = obj.AssignedGroup; + } + + public virtual bool Sanitize() + { + bool shortened = false; + optComment = optComment.SanitizeOpt(ref shortened); + AssignedGroup = AssignedGroup.SanitizeLdapPathOpt(ref shortened); + return shortened; + } + + public static string DisplayAllComments(List Comments, bool asMarkup = false) + { + string allComments = ""; + foreach (var comment in Comments) + { + allComments += comment.Comment.CreationDate.ToShortDateString() + " " + + comment.Comment.Creator.Name + ": " + + comment.Comment.CommentText + (asMarkup ? "
                      " : "\r\n"); + } + return allComments; + } + } +} diff --git a/roles/lib/files/FWO.Data/Workflow/WfStates.cs b/roles/lib/files/FWO.Data/Workflow/WfStates.cs new file mode 100644 index 0000000000..bc341e1060 --- /dev/null +++ b/roles/lib/files/FWO.Data/Workflow/WfStates.cs @@ -0,0 +1,42 @@ +using System.Text.Json.Serialization; +using Newtonsoft.Json; + + +namespace FWO.Data.Workflow +{ + public class WfState + { + [JsonProperty("id"), JsonPropertyName("id")] + public int Id { get; set; } + + [JsonProperty("name"), JsonPropertyName("name")] + public string Name { get; set; } = ""; + + [JsonProperty("automatic_only"), JsonPropertyName("automatic_only")] + public bool AutomaticOnly { get; set; } = false; + + [JsonProperty("actions"), JsonPropertyName("actions")] + public List Actions { get; set; } = []; + + + public WfState() { } + + public WfState(WfState state) + { + Id = state.Id; + Name = state.Name; + AutomaticOnly = state.AutomaticOnly; + Actions = state.Actions; + } + + public string ActionList() + { + List actionNames = []; + foreach (var action in Actions) + { + actionNames.Add(action.Action.Name); + } + return string.Join(", ", actionNames); + } + } +} diff --git a/roles/lib/files/FWO.Data/Workflow/WfTaskBase.cs b/roles/lib/files/FWO.Data/Workflow/WfTaskBase.cs new file mode 100644 index 0000000000..2358c2f750 --- /dev/null +++ b/roles/lib/files/FWO.Data/Workflow/WfTaskBase.cs @@ -0,0 +1,99 @@ +using FWO.Basics; +using Newtonsoft.Json; +using System.Text.Json.Serialization; + +namespace FWO.Data.Workflow +{ + public enum WfTaskType + { + master = 0, + generic = 1, + access = 2, + rule_delete = 3, + rule_modify = 4, + group_create = 5, + group_modify = 6, + group_delete = 7, + new_interface = 11 + } + + public enum RequestAction + { + create, + delete, + modify, + unchanged, + addAfterCreation + } + + public class WfTaskBase : WfStatefulObject + { + [JsonProperty("title"), JsonPropertyName("title")] + public string Title { get; set; } = ""; + + [JsonProperty("task_number"), JsonPropertyName("task_number")] + public int TaskNumber { get; set; } + + [JsonProperty("task_type"), JsonPropertyName("task_type")] + public string TaskType { get; set; } = WfTaskType.access.ToString(); + + [JsonProperty("rule_action"), JsonPropertyName("rule_action")] + public int? RuleAction { get; set; } + + [JsonProperty("rule_tracking"), JsonPropertyName("rule_tracking")] + public int? Tracking { get; set; } + + [JsonProperty("start"), JsonPropertyName("start")] + public DateTime? Start { get; set; } + + [JsonProperty("stop"), JsonPropertyName("stop")] + public DateTime? Stop { get; set; } + + [JsonProperty("svc_grp_id"), JsonPropertyName("svc_grp_id")] + public int? ServiceGroupId { get; set; } + + [JsonProperty("nw_obj_grp_id"), JsonPropertyName("nw_obj_grp_id")] + public int? NetworkGroupId { get; set; } + + [JsonProperty("user_grp_id"), JsonPropertyName("user_grp_id")] + public int? UserGroupId { get; set; } + + [JsonProperty("free_text"), JsonPropertyName("free_text")] + public string? FreeText { get; set; } + + [JsonProperty("target_begin_date"), JsonPropertyName("target_begin_date")] + public DateTime? TargetBeginDate { get; set; } + + [JsonProperty("target_end_date"), JsonPropertyName("target_end_date")] + public DateTime? TargetEndDate { get; set; } + + + public WfTaskBase() + { } + + public WfTaskBase(WfTaskBase task) : base(task) + { + Title = task.Title; + TaskNumber = task.TaskNumber; + TaskType = task.TaskType; + RuleAction = task.RuleAction; + Tracking = task.Tracking; + Start = task.Start; + Stop = task.Stop; + ServiceGroupId = task.ServiceGroupId; + NetworkGroupId = task.NetworkGroupId; + UserGroupId = task.UserGroupId; + FreeText = task.FreeText; + TargetBeginDate = task.TargetBeginDate; + TargetEndDate = task.TargetEndDate; + } + + public override bool Sanitize() + { + bool shortened = base.Sanitize(); + Title = Title.SanitizeMand(ref shortened); + FreeText = FreeText.SanitizeOpt(ref shortened); + return shortened; + } + } +} diff --git a/roles/lib/files/FWO.Data/Workflow/WfTicket.cs b/roles/lib/files/FWO.Data/Workflow/WfTicket.cs new file mode 100644 index 0000000000..d0e8eac8bc --- /dev/null +++ b/roles/lib/files/FWO.Data/Workflow/WfTicket.cs @@ -0,0 +1,105 @@ +using System.Text.Json.Serialization; +using Newtonsoft.Json; + +namespace FWO.Data.Workflow +{ + public class WfTicket : WfTicketBase + { + [JsonProperty("reqtasks"), JsonPropertyName("reqtasks")] + public List Tasks { get; set; } = []; + + [JsonProperty("comments"), JsonPropertyName("comments")] + public List Comments { get; set; } = []; + + public bool Editable { get; set; } = true; + + + public WfTicket() + { } + + public WfTicket(WfTicket ticket) : base(ticket) + { + Tasks = ticket.Tasks; + Comments = ticket.Comments; + } + + public int HighestTaskNumber() + { + int highestNumber = 0; + foreach (var tasknumber in Tasks.Select(r => r.TaskNumber).Where(t => t > highestNumber)) + { + highestNumber = tasknumber; + } + return highestNumber; + } + + public int NumberImplTasks() + { + int numberImplTasks = 0; + foreach (var reqtask in Tasks) + { + numberImplTasks += reqtask.ImplementationTasks.Count; + } + return numberImplTasks; + } + + public void UpdateIpStringsFromCidrInTaskElements() + { + foreach (WfReqTask reqtask in Tasks) + { + foreach (WfReqElement elem in reqtask.Elements) + { + elem.IpString = elem.Cidr != null && elem.Cidr.Valid ? elem.Cidr.CidrString : null; + elem.IpEnd = elem.CidrEnd != null && elem.CidrEnd.Valid ? elem.CidrEnd.CidrString : null; + } + } + } + + public void UpdateCidrsInTaskElements() + { + foreach (WfReqTask reqtask in Tasks) + { + foreach (WfReqElement elem in reqtask.Elements) + { + if (elem.IpString != null) + { + elem.Cidr = new Cidr(elem.IpString); + } + if (elem.IpEnd != null) + { + elem.CidrEnd = new Cidr(elem.IpEnd); + } + } + UpdateCidrsInImplTaskElements(reqtask.ImplementationTasks); + } + } + + public static void UpdateCidrsInImplTaskElements(List implementationTasks) + { + foreach (WfImplTask implTask in implementationTasks) + { + foreach (WfImplElement elem in implTask.ImplElements) + { + if (elem.IpString != null) + { + elem.Cidr = new Cidr(elem.IpString); + } + if (elem.IpEnd != null) + { + elem.CidrEnd = new Cidr(elem.IpEnd); + } + } + } + } + + public bool IsEditableForOwner(List ticketIds, List ownerIds, int requesterId) + { + return ticketIds.Contains(Id) || Tasks.Any(ta => ta.Owners.Any(ow => ownerIds.Contains(ow.Owner.Id))) || Requester?.DbId == requesterId; + } + + public bool IsVisibleForOwner(List ticketIds, List ownerIds, int requesterId) + { + return IsEditableForOwner(ticketIds, ownerIds, requesterId) || Tasks.Any(ta => ownerIds.Contains(ta.GetAddInfoIntValueOrZero(AdditionalInfoKeys.ReqOwner))); + } + } +} diff --git a/roles/lib/files/FWO.Data/Workflow/WfTicketBase.cs b/roles/lib/files/FWO.Data/Workflow/WfTicketBase.cs new file mode 100644 index 0000000000..2359e2e978 --- /dev/null +++ b/roles/lib/files/FWO.Data/Workflow/WfTicketBase.cs @@ -0,0 +1,80 @@ +using FWO.Basics; +using Newtonsoft.Json; +using System.Text.Json.Serialization; + +namespace FWO.Data.Workflow +{ + public class WfTicketBase : WfStatefulObject + { + [JsonProperty("id"), JsonPropertyName("id")] + public long Id { get; set; } + + [JsonProperty("title"), JsonPropertyName("title")] + public string Title { get; set; } = ""; + + [JsonProperty("date_created"), JsonPropertyName("date_created")] + public DateTime CreationDate { get; set; } + + [JsonProperty("date_completed"), JsonPropertyName("date_completed")] + public DateTime? CompletionDate { get; set; } + + [JsonProperty("requester"), JsonPropertyName("requester")] + public UiUser? Requester { get; set; } + + [JsonProperty("requester_dn"), JsonPropertyName("requester_dn")] + public string? RequesterDn { get; set; } = ""; + + [JsonProperty("requester_group"), JsonPropertyName("requester_group")] + public string? RequesterGroup { get; set; } + + [JsonProperty("tenant_id"), JsonPropertyName("tenant_id")] + public int? TenantId { get; set; } + + [JsonProperty("reason"), JsonPropertyName("reason")] + public string? Reason { get; set; } + + [JsonProperty("external_ticket_id"), JsonPropertyName("external_ticket_id")] + public string? ExternalTicketId { get; set; } + + [JsonProperty("external_ticket_source"), JsonPropertyName("external_ticket_source")] + public int? ExternalTicketSource { get; set; } + + [JsonProperty("ticket_deadline"), JsonPropertyName("ticket_deadline")] + public DateTime? Deadline { get; set; } + + [JsonProperty("ticket_priority"), JsonPropertyName("ticket_priority")] + public int? Priority { get; set; } + + + public WfTicketBase() + { } + + public WfTicketBase(WfTicketBase ticket) : base(ticket) + { + Id = ticket.Id; + Title = ticket.Title; + CreationDate = ticket.CreationDate; + CompletionDate = ticket.CompletionDate; + Requester = ticket.Requester; + RequesterDn = ticket.RequesterDn; + RequesterGroup = ticket.RequesterGroup; + TenantId = ticket.TenantId; + Reason = ticket.Reason; + ExternalTicketId = ticket.ExternalTicketId; + ExternalTicketSource = ticket.ExternalTicketSource; + Deadline = ticket.Deadline; + Priority = ticket.Priority; + } + + public override bool Sanitize() + { + bool shortened = base.Sanitize(); + Title = Title.SanitizeMand(ref shortened); + RequesterDn = RequesterDn.SanitizeLdapPathOpt(ref shortened); + RequesterGroup = RequesterGroup.SanitizeLdapPathOpt(ref shortened); + Reason = Reason.SanitizeOpt(ref shortened); + ExternalTicketId = ExternalTicketId.SanitizeOpt(ref shortened); + return shortened; + } + } +} diff --git a/roles/lib/files/FWO.Data/Workflow/WfTicketWriter.cs b/roles/lib/files/FWO.Data/Workflow/WfTicketWriter.cs new file mode 100644 index 0000000000..66a8182a95 --- /dev/null +++ b/roles/lib/files/FWO.Data/Workflow/WfTicketWriter.cs @@ -0,0 +1,21 @@ +using System.Text.Json.Serialization; +using Newtonsoft.Json; + +namespace FWO.Data.Workflow +{ + public class WfTicketWriter + { + + [JsonProperty("data"), JsonPropertyName("data")] + public List Tasks { get; set; } = []; + + + public WfTicketWriter(WfTicket ticket) + { + foreach (var reqtask in ticket.Tasks) + { + Tasks.Add(new WfReqTaskWriter(reqtask)); + } + } + } +} diff --git a/roles/lib/files/FWO.Data/ZoneWrapper.cs b/roles/lib/files/FWO.Data/ZoneWrapper.cs new file mode 100644 index 0000000000..aeef1a99ef --- /dev/null +++ b/roles/lib/files/FWO.Data/ZoneWrapper.cs @@ -0,0 +1,16 @@ +using Newtonsoft.Json; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Text.Json.Serialization; +using System.Threading.Tasks; + +namespace FWO.Data +{ + public class ZoneWrapper + { + [JsonProperty("zone"), JsonPropertyName("zone")] + public NetworkZone Content { get; set; } = new NetworkZone(); + } +} diff --git a/roles/lib/files/FWO.DeviceAutoDiscovery/AutoDiscoveryBase.cs b/roles/lib/files/FWO.DeviceAutoDiscovery/AutoDiscoveryBase.cs index bcbbae0647..c674a89404 100644 --- a/roles/lib/files/FWO.DeviceAutoDiscovery/AutoDiscoveryBase.cs +++ b/roles/lib/files/FWO.DeviceAutoDiscovery/AutoDiscoveryBase.cs @@ -1,5 +1,7 @@ -using FWO.Api.Data; using FWO.Api.Client; +using FWO.Basics; +using FWO.Data; +using FWO.Encryption; using FWO.Logging; using System.Text.Json; @@ -7,88 +9,48 @@ namespace FWO.DeviceAutoDiscovery { public class AutoDiscoveryBase { - public Management superManagement = new Management(); - private readonly ApiConnection apiConnection; - - List existingManagements = new List(); - + public Management SuperManagement { get; set; } + protected readonly ApiConnection apiConnection; public AutoDiscoveryBase(Management mgm, ApiConnection apiConn) { - superManagement = mgm; + SuperManagement = mgm; + SuperManagement.ImportCredential.Secret = AesEnc.TryDecrypt(SuperManagement.ImportCredential.Secret, true, + "AutoDiscovery", $"Could not decrypt secret in credential named '{SuperManagement.ImportCredential.Name}'.", true); apiConnection = apiConn; } public virtual Task> Run() { - return superManagement.DeviceType.Name switch + return SuperManagement.DeviceType.Name switch { - "FortiManager" => new AutoDiscoveryFortiManager(superManagement, apiConnection).Run(), - "CheckPoint" => new AutoDiscoveryCpMds(superManagement, apiConnection).Run(), - "Check Point" => new AutoDiscoveryCpMds(superManagement, apiConnection).Run(), + "FortiManager" => new AutoDiscoveryFortiManager(SuperManagement, apiConnection).Run(), + "CheckPoint" => new AutoDiscoveryCpMds(SuperManagement, apiConnection).Run(), + "Check Point" => new AutoDiscoveryCpMds(SuperManagement, apiConnection).Run(), _ => throw new NotSupportedException("SuperManager Type is not supported."), }; } public async Task> GetDeltas(List discoveredManagements) { - List deltaManagements = new List(); + List deltaManagements = []; try { - existingManagements = await apiConnection.SendQueryAsync>(FWO.Api.Client.Queries.DeviceQueries.getManagementsDetails); + List existingManagements = await apiConnection.SendQueryAsync>(FWO.Api.Client.Queries.DeviceQueries.getManagementsDetails); + bool compareDevicesByUidOnly = SuperManagement.DeviceType.Name == "FortiManager"; foreach (Management discoveredMgmt in discoveredManagements.Where(x => x.ConfigPath != "global")) { - Management? existMgmt = FindManagementIfExist(discoveredMgmt, existingManagements); - if (existMgmt == null) - { - // new management - discoveredMgmt.Delete = false; - deltaManagements.Add(discoveredMgmt); - } - else - { - Management changedMgmt = existMgmt; - changedMgmt.Delete = false; - bool foundChange = false; - List newDevs = new List(); - // new devices in existing management - foreach (Device discoveredDev in discoveredMgmt.Devices) - { - if (checkDeviceNotInMgmt(discoveredDev, existMgmt) || discoveredDev.ImportDisabled) - { - discoveredDev.Delete = false; - newDevs.Add(discoveredDev); - foundChange = true; - } - } - - // deleted devices in existing management - foreach (Device existDev in existMgmt.Devices) - { - if (checkDeviceNotInMgmt(existDev, discoveredMgmt) && !existDev.ImportDisabled) - { - existDev.Delete = true; - newDevs.Add(existDev); - foundChange = true; - } - } - changedMgmt.Devices = newDevs.ToArray(); - - if (foundChange || changedMgmt.ImportDisabled) - { - deltaManagements.Add(changedMgmt); - } - } + DiscoverManagementDetails(discoveredMgmt, deltaManagements, existingManagements, compareDevicesByUidOnly); } // deleted managements - foreach (Management existMgmt in existingManagements.Where(mgt => mgt.SuperManagerId == superManagement.Id && mgt.ConfigPath != "global")) + foreach (Management existMgmtDisregardingUid in existingManagements.Where(mgt => mgt.SuperManagerId == SuperManagement.Id && mgt.ConfigPath != "global")) { - Management? foundMgmt = FindManagementIfExist(existMgmt, discoveredManagements); - if (foundMgmt == null && !existMgmt.ImportDisabled) + Management? foundMgmt = FindManagementIfExist(existMgmtDisregardingUid, discoveredManagements); + if (foundMgmt == null && !existMgmtDisregardingUid.ImportDisabled) { - existMgmt.Delete = true; - deltaManagements.Add(existMgmt); + existMgmtDisregardingUid.Delete = true; + deltaManagements.Add(existMgmtDisregardingUid); } } } @@ -99,12 +61,68 @@ public async Task> GetDeltas(List discoveredManagem return deltaManagements; } - private Management? FindManagementIfExist(Management mgm, List mgmtList) + private static void DiscoverManagementDetails( + Management discoveredMgmt, + List deltaManagements, + List existingManagements, + bool compareDevicesByUidOnly) + { + Management? existMgmtDisregardingUid = FindManagementIfExist(discoveredMgmt, existingManagements); + if (existMgmtDisregardingUid == null) + { + // new management + discoveredMgmt.Delete = false; + deltaManagements.Add(discoveredMgmt); + } + else + { + HandleChangedManagement(discoveredMgmt, existMgmtDisregardingUid, deltaManagements, compareDevicesByUidOnly); + } + } + + private static void HandleChangedManagement( + Management discoveredMgmt, + Management existMgmtDisregardingUid, + List deltaManagements, + bool compareDevicesByUidOnly) + { + Management changedMgmt = existMgmtDisregardingUid; + changedMgmt.Delete = false; + bool foundChange = false; + List newDevs = []; + // new devices in existing management + foreach (Device discoveredDev in discoveredMgmt.Devices) + { + if (CheckDeviceNotInMgmt(discoveredDev, existMgmtDisregardingUid, compareDevicesByUidOnly) || + discoveredDev.ImportDisabled) + { + discoveredDev.Delete = false; + newDevs.Add(discoveredDev); + foundChange = true; + } + } + + // deleted devices in existing management + foreach (Device existDev in existMgmtDisregardingUid.Devices) + { + if (CheckDeviceNotInMgmt(existDev, discoveredMgmt, compareDevicesByUidOnly) && !existDev.ImportDisabled) + { + existDev.Delete = true; + newDevs.Add(existDev); + foundChange = true; + } + } + changedMgmt.Devices = newDevs.ToArray(); + + if (foundChange || changedMgmt.ImportDisabled) + { + deltaManagements.Add(changedMgmt); + } + } + + private static Management? FindManagementIfExist(Management mgm, List mgmtList) { - Management? existingManagement = mgmtList.FirstOrDefault(x => - x.Name == mgm.Name - && x.ConfigPath == mgm.ConfigPath - && x.SuperManagerId == mgm.SuperManagerId); + Management? existingManagement = mgmtList.FirstOrDefault(m => m.Equals(mgm)); if (existingManagement != null) { return existingManagement; @@ -112,19 +130,30 @@ public async Task> GetDeltas(List discoveredManagem return null; } - private bool checkDeviceNotInMgmt(Device dev, Management mgmt) + private static bool CheckDeviceNotInMgmt(Device dev, Management mgmt, bool compareDevicesByUidOnly) { - if (mgmt.Devices.FirstOrDefault(devInMgt => - devInMgt.Name == dev.Name && devInMgt.LocalRulebase == dev.LocalRulebase) != null) + if (compareDevicesByUidOnly) + { + if (mgmt.Devices.FirstOrDefault(devInMgt => devInMgt.Uid.GenerousCompare(dev.Uid)) != null) + { + return false; + } + return true; + } + + if (mgmt.Devices.FirstOrDefault(devInMgt => devInMgt.Equals(dev)) != null) { return false; } return true; } + protected virtual Management CreateManagement(Management superManagement, string domainName, string domainUid) { return new(); } + + public List ConvertToActions(List diffList) { - List actions = new List(); + List actions = []; int counter = 0; try { @@ -132,132 +161,15 @@ public List ConvertToActions(List diffList) { if (changedMgmt.Delete) { - actions.Add(new ActionItem - { - Number = ++counter, - Supermanager = superManagement.Name, - ActionType = ActionCode.DeleteManagement.ToString(), - ManagementId = changedMgmt.Id, - DeviceId = null, - JsonData = null - }); - foreach (Device dev in changedMgmt.Devices) - { - actions.Add(new ActionItem - { - Number = ++counter, - Supermanager = superManagement.Name, - ActionType = ActionCode.DeleteGateway.ToString(), - ManagementId = changedMgmt.Id, - DeviceId = dev?.Id, - JsonData = null - }); - } + DeleteManagement(changedMgmt, actions, counter); } else if (changedMgmt.Id == 0) // adding new management { - DeviceType devtype = new DeviceType(); - if (changedMgmt.DeviceType != null || changedMgmt.DeviceType?.Id == 0) - devtype = changedMgmt.DeviceType; - else - devtype = new DeviceType() { Id = superManagement.DeviceType.GetManagementTypeId() }; - - Management MgtVariables = new Management - { - Hostname = superManagement.Hostname, - ImportCredential = superManagement.ImportCredential, - ImporterHostname = superManagement.ImporterHostname, - DebugLevel = superManagement.DebugLevel, - Port = superManagement.Port, - ImportDisabled = false, - ForceInitialImport = true, - HideInUi = false, - ConfigPath = changedMgmt.ConfigPath, - DomainUid = changedMgmt.DomainUid, - Name = changedMgmt.Name, - DeviceType = devtype, - SuperManagerId = superManagement.Id - }; - actions.Add(new ActionItem - { - Number = ++counter, - Supermanager = superManagement.Name, - ActionType = ActionCode.AddManagement.ToString(), - ManagementId = null, - DeviceId = null, - JsonData = JsonSerializer.Serialize(MgtVariables) - }); - - foreach (Device dev in changedMgmt.Devices) - { - dev.DeviceType.Id = superManagement.DeviceType.GetGatewayTypeId(); - dev.Management.Id = 0; - actions.Add(new ActionItem - { - Number = ++counter, - Supermanager = superManagement.Name, - ActionType = ActionCode.AddGatewayToNewManagement.ToString(), - ManagementId = null, - DeviceId = null, - JsonData = JsonSerializer.Serialize(dev) - }); - } + AddManagement(changedMgmt, actions, counter); } else { - if (changedMgmt.ImportDisabled) - { - actions.Add(new ActionItem - { - Number = ++counter, - Supermanager = superManagement.Name, - ActionType = ActionCode.ReactivateManagement.ToString(), - ManagementId = changedMgmt.Id, - DeviceId = null, - JsonData = null - }); - } - foreach (Device dev in changedMgmt.Devices) - { - if (dev.Delete) - { - actions.Add(new ActionItem - { - Number = ++counter, - Supermanager = superManagement.Name, - ActionType = ActionCode.DeleteGateway.ToString(), - ManagementId = changedMgmt.Id, - DeviceId = dev?.Id, - JsonData = null - }); - } - else if (dev.ImportDisabled) - { - actions.Add(new ActionItem - { - Number = ++counter, - Supermanager = superManagement.Name, - ActionType = ActionCode.ReactivateGateway.ToString(), - ManagementId = changedMgmt.Id, - DeviceId = dev.Id, - JsonData = null - }); - } - else - { - dev.DeviceType.Id = superManagement.DeviceType.GetGatewayTypeId(); - dev.Management.Id = changedMgmt.Id; - actions.Add(new ActionItem - { - Number = ++counter, - Supermanager = superManagement.Name, - ActionType = ActionCode.AddGatewayToExistingManagement.ToString(), - ManagementId = changedMgmt.Id, - DeviceId = null, - JsonData = JsonSerializer.Serialize(dev) - }); - } - } + ChangeManagement(changedMgmt, actions, counter); } } } @@ -268,6 +180,138 @@ public List ConvertToActions(List diffList) return actions; } + private void DeleteManagement(Management changedMgmt, List actions, int counter) + { + actions.Add(new ActionItem + { + Number = ++counter, + Supermanager = SuperManagement.Name, + ActionType = ActionCode.DeleteManagement.ToString(), + ManagementId = changedMgmt.Id, + DeviceId = null, + JsonData = null + }); + foreach (Device dev in changedMgmt.Devices) + { + actions.Add(new ActionItem + { + Number = ++counter, + Supermanager = SuperManagement.Name, + ActionType = ActionCode.DeleteGateway.ToString(), + ManagementId = changedMgmt.Id, + DeviceId = dev?.Id, + JsonData = null + }); + } + } + + private void AddManagement(Management changedMgmt, List actions, int counter) + { + DeviceType devtype; + if (changedMgmt.DeviceType != null || changedMgmt.DeviceType?.Id == 0) + devtype = changedMgmt.DeviceType; + else + devtype = new DeviceType() { Id = SuperManagement.DeviceType.GetManagementTypeId() }; + + Management MgtVariables = new() + { + Hostname = SuperManagement.Hostname, + ImportCredential = SuperManagement.ImportCredential, + ImporterHostname = SuperManagement.ImporterHostname, + DebugLevel = SuperManagement.DebugLevel, + Port = SuperManagement.Port, + ImportDisabled = false, + ForceInitialImport = true, + HideInUi = false, + ConfigPath = changedMgmt.ConfigPath, + DomainUid = changedMgmt.DomainUid, + Name = changedMgmt.Name, + Uid = changedMgmt.Uid, + DeviceType = devtype, + SuperManagerId = SuperManagement.Id, + IsSupermanager = changedMgmt.IsSupermanager + }; + actions.Add(new ActionItem + { + Number = ++counter, + Supermanager = SuperManagement.Name, + ActionType = ActionCode.AddManagement.ToString(), + ManagementId = null, + DeviceId = null, + JsonData = JsonSerializer.Serialize(MgtVariables) + }); + + foreach (Device dev in changedMgmt.Devices) + { + dev.DeviceType.Id = SuperManagement.DeviceType.GetGatewayTypeId(); + dev.Management.Id = 0; + actions.Add(new ActionItem + { + Number = ++counter, + Supermanager = SuperManagement.Name, + ActionType = ActionCode.AddGatewayToNewManagement.ToString(), + ManagementId = null, + DeviceId = null, + JsonData = JsonSerializer.Serialize(dev) + }); + } + } + + private void ChangeManagement(Management changedMgmt, List actions, int counter) + { + if (changedMgmt.ImportDisabled) + { + actions.Add(new ActionItem + { + Number = ++counter, + Supermanager = SuperManagement.Name, + ActionType = ActionCode.ReactivateManagement.ToString(), + ManagementId = changedMgmt.Id, + DeviceId = null, + JsonData = null + }); + } + foreach (Device dev in changedMgmt.Devices) + { + if (dev.Delete) + { + actions.Add(new ActionItem + { + Number = ++counter, + Supermanager = SuperManagement.Name, + ActionType = ActionCode.DeleteGateway.ToString(), + ManagementId = changedMgmt.Id, + DeviceId = dev.Id, + JsonData = null + }); + } + else if (dev.ImportDisabled) + { + actions.Add(new ActionItem + { + Number = ++counter, + Supermanager = SuperManagement.Name, + ActionType = ActionCode.ReactivateGateway.ToString(), + ManagementId = changedMgmt.Id, + DeviceId = dev.Id, + JsonData = null + }); + } + else + { + dev.DeviceType.Id = SuperManagement.DeviceType.GetGatewayTypeId(); + dev.Management.Id = changedMgmt.Id; + actions.Add(new ActionItem + { + Number = ++counter, + Supermanager = SuperManagement.Name, + ActionType = ActionCode.AddGatewayToExistingManagement.ToString(), + ManagementId = changedMgmt.Id, + DeviceId = null, + JsonData = JsonSerializer.Serialize(dev) + }); + } + } + } } } - diff --git a/roles/lib/files/FWO.DeviceAutoDiscovery/AutoDiscoveryCpMds.cs b/roles/lib/files/FWO.DeviceAutoDiscovery/AutoDiscoveryCpMds.cs index a0606844c0..1e147d3116 100644 --- a/roles/lib/files/FWO.DeviceAutoDiscovery/AutoDiscoveryCpMds.cs +++ b/roles/lib/files/FWO.DeviceAutoDiscovery/AutoDiscoveryCpMds.cs @@ -1,156 +1,248 @@ -using FWO.Api.Data; using FWO.Api.Client; +using FWO.Api.Client.Queries; +using FWO.Basics; +using FWO.Data; using FWO.Logging; -using FWO.Rest.Client; -using System.Net; +using MailKit.Security; using RestSharp; +using System.Net; namespace FWO.DeviceAutoDiscovery { public class AutoDiscoveryCpMds : AutoDiscoveryBase { + private readonly string Autodiscovery = "Autodiscovery"; + private readonly string CheckpointHost = "checkpoint-host"; + private readonly string CheckpointClusterMember = "cluster-member"; + public AutoDiscoveryCpMds(Management mgm, ApiConnection apiConn) : base(mgm, apiConn) { } - public override async Task> Run() + + override public async Task> Run() { - if (superManagement == null) + List discoveredDevices = []; + if (SuperManagement == null) + { return null!; + } + Log.WriteAudit(Autodiscovery, $"starting discovery for {SuperManagement.Name} (id={SuperManagement.Id})"); + + if (SuperManagement.DeviceType.Name == "Check Point") + { + Log.WriteDebug(Autodiscovery, $"discovering CP domains & gateways"); + + (string sessionId, CheckPointClient restClientCP) = await LoginCp(SuperManagement); + + // when passing sessionId, we always need to use @ verbatim identifier for special chars in sessionId + if (string.IsNullOrEmpty(SuperManagement.Uid) || + (SuperManagement.DeviceType.CanBeSupermanager() && string.IsNullOrEmpty(SuperManagement.DomainUid))) // pre v9 managements might not have a UID + { + // update manager Uid in existing management; typically triggered in daily scheduler + await UpdateMgmUids(SuperManagement, restClientCP, @sessionId); + } + List domainList = []; + + if (SuperManagement.DeviceType.Id == 13) // 13=MDS + { + domainList = await restClientCP.GetDomains(@sessionId); + } + else if (SuperManagement.DeviceType.Id == 9) // 9=stand-alone manager + { + domainList.Add(new Domain() { DomainType = "standalone", Name = "", Uid = "" }); + } + discoveredDevices = await DiscoverDomainDevices(domainList, restClientCP); + await LogoutCp(restClientCP, @sessionId); + } + return await GetDeltas(discoveredDevices); + } + + override protected Management CreateManagement(Management superManagement, string domainName, string domainUid) + { + Management currentManagement = new() + { + Name = superManagement.Name + "__" + domainName, + Uid = superManagement.Uid, + ImporterHostname = superManagement.ImporterHostname, + Hostname = superManagement.Hostname, + ImportCredential = superManagement.ImportCredential, + Port = superManagement.Port, + ImportDisabled = false, + ForceInitialImport = true, + HideInUi = false, + ConfigPath = domainName, + DomainUid = domainUid, + DebugLevel = superManagement.DebugLevel, + SuperManagerId = superManagement.Id, + DeviceType = new DeviceType { Id = 9 }, + Devices = [] + }; + // if super manager is just a simple management, overwrite the default (supermanager) values + if (domainName == "") + { + currentManagement.Name = superManagement.Name; + currentManagement.ConfigPath = ""; + currentManagement.SuperManagerId = null; + currentManagement.DomainUid = ""; + currentManagement.IsSupermanager = false; + } + return currentManagement; + } + + private async Task> DiscoverDomainDevices(List domainList, CheckPointClient restClientCP) + { + List discoveredDevices = []; + foreach (Domain domain in domainList) + { + Log.WriteDebug(Autodiscovery, $"found domain '{domain.Name}'"); + Management currentManagement = CreateManagement(SuperManagement, domain.Name, domain.Uid); + currentManagement.IsSupermanager = false; + // session id pins this session to a specific domain (if domain is given during login) + string sessionIdPerDomain = await LoginCp(currentManagement, restClientCP); + currentManagement.Uid = await GetMgmUid(restClientCP, @sessionIdPerDomain, currentManagement.Hostname); + + if (sessionIdPerDomain != "") + { + currentManagement.Devices = await GetGateways(restClientCP, @sessionIdPerDomain); + await LogoutCp(restClientCP, @sessionIdPerDomain); + } + discoveredDevices.Add(currentManagement); + } + return discoveredDevices; + } + + private async Task UpdateMgmUids(Management mgm, CheckPointClient restClientCP, string sessionId) + { + if (mgm.DeviceType.Id == 13) // MDS + { + mgm.Uid = await restClientCP.GetMdsUid(mgm); + } + else // single management + { + mgm.Uid = await GetMgmUid(restClientCP, sessionId, SuperManagement.Hostname); + } + + var vars = new { id = mgm.Id, uid = mgm.Uid, domainUid = mgm.DomainUid }; + _ = (await apiConnection.SendQueryAsync(DeviceQueries.updateManagementUids, vars)).UpdatedId; + } + + private async Task<(string, CheckPointClient)> LoginCp(Management mgm) + { + CheckPointClient restClientCP = new(mgm); + return (await LoginCp(mgm, restClientCP), restClientCP); + } + private async Task LoginCp(Management mgm, CheckPointClient restClientCP) + { + string? domainString = mgm.ConfigPath; + string sessionId = ""; + if (mgm.DomainUid != null && mgm.DomainUid != "") + domainString = mgm.DomainUid; + RestResponse sessionResponse = await restClientCP.AuthenticateUser(mgm.ImportCredential.ImportUser, mgm.ImportCredential.Secret, domainString); + if (sessionResponse.StatusCode == HttpStatusCode.OK && sessionResponse.IsSuccessful && sessionResponse.Data?.SessionId != null && sessionResponse.Data?.SessionId != "") + { + if (sessionResponse?.Data?.SessionId == null || sessionResponse.Data.SessionId == "") + { + Log.WriteWarning(Autodiscovery, $"Did not receive a correct session ID when trying to login to manager {SuperManagement.Name} (id={SuperManagement.Id})"); + } + else + { + sessionId = sessionResponse.Data.SessionId; + Log.WriteDebug(Autodiscovery, $"successful CP Manager login, got SessionID: {sessionId}"); + } + } + else + { + string errorTxtCatch = $"{SuperManagement.Name}"; + string errorTxt = $"error while logging in to {SuperManagement.Name}: {sessionResponse.ErrorMessage} "; + if (string.IsNullOrEmpty(sessionResponse.Data?.SessionId)) + { + errorTxt += $"could not authenticate to {SuperManagement.Name} - got empty session ID"; + } + Log.WriteWarning(Autodiscovery, errorTxt); + throw new AuthenticationException(errorTxtCatch); + } + return sessionId; + } + + private async Task LogoutCp(CheckPointClient restClientCP, string sessionId) + { + RestResponse sessionResponse = await restClientCP.DeAuthenticateUser(@sessionId); + if (sessionResponse.StatusCode == HttpStatusCode.OK) + { + Log.WriteDebug(Autodiscovery, $"successful CP Manager logout"); + return true; + } else { - List discoveredDevices = new List(); - string ManagementType = ""; - Log.WriteAudit("Autodiscovery", $"starting discovery for {superManagement.Name} (id={superManagement.Id})"); + Log.WriteWarning(Autodiscovery, $"error while logging out from CP Manager: {sessionResponse.ErrorMessage}"); + return false; + } + } + + private async Task GetGateways(CheckPointClient restClientCP, string sessionIdPerDomain) + { + List devList = await restClientCP.GetGateways(@sessionIdPerDomain); + List devices = []; - if (superManagement.DeviceType.Name == "Check Point") + // add devices to currentManagement + foreach (CpDevice cpDev in devList) + { + if (cpDev.CpDevType != CheckpointHost && cpDev.CpDevType != CheckpointClusterMember) // leave out the management host "cluster-member" and cluster members "cluster-member" { - Log.WriteDebug("Autodiscovery", $"discovering CP domains & gateways"); - CheckPointClient restClientCP = new CheckPointClient(superManagement); - string domainString = superManagement.ConfigPath; - if (superManagement.DomainUid != null && superManagement.DomainUid != "") - domainString= superManagement.DomainUid; - RestResponse sessionResponse = await restClientCP.AuthenticateUser(superManagement.ImportCredential.ImportUser, superManagement.ImportCredential.Secret, domainString); - if (sessionResponse.StatusCode == HttpStatusCode.OK && sessionResponse.IsSuccessful && sessionResponse.Data?.SessionId != null && sessionResponse.Data?.SessionId != "") - { - // if (sessionResponse==null || sessionResponse.Data==null || sessionResponse.Data.SessionId==null || sessionResponse.Data.SessionId=="") - if (sessionResponse?.Data?.SessionId == null || sessionResponse.Data.SessionId == "") - { - Log.WriteWarning("Autodiscovery", $"Did not receive a correct session ID when trying to login to manager {superManagement.Name} (id={superManagement.Id})"); - return new List() { }; - } - string sessionId = sessionResponse.Data.SessionId; - Log.WriteDebug("Autodiscovery", $"successful CP Manager login, got SessionID: {sessionId}"); - // need to use @ verbatim identifier for special chars in sessionId - RestResponse domainResponse = await restClientCP.GetDomains(@sessionId); - if (domainResponse.StatusCode == HttpStatusCode.OK && domainResponse.IsSuccessful && domainResponse.Data?.DomainList != null) - { - List domainList = domainResponse.Data.DomainList; - if (domainList.Count == 0) - { - Log.WriteDebug("Autodiscovery", $"found no domains - assuming this is a standard management, adding dummy domain with empty name"); - domainList.Add(new Domain { Name = "" }); - ManagementType = "stand-alone"; - } - else - ManagementType = "MDS"; - - foreach (Domain domain in domainList) - { - Log.WriteDebug("Autodiscovery", $"found domain '{domain.Name}'"); - - Management currentManagement = new Management - { - Name = superManagement.Name + "__" + domain.Name, - ImporterHostname = superManagement.ImporterHostname, - Hostname = superManagement.Hostname, - ImportCredential = superManagement.ImportCredential, - Port = superManagement.Port, - ImportDisabled = false, - ForceInitialImport = true, - HideInUi = false, - ConfigPath = domain.Name, - DomainUid = domain.Uid, - DebugLevel = superManagement.DebugLevel, - SuperManagerId = superManagement.Id, - DeviceType = new DeviceType { Id = 9 }, - Devices = new Device[] { } - }; - // if super manager is just a simple management - if (domain.Name == "") // set some settings identical to "superManager", so that no new manager is created - { - currentManagement.Name = superManagement.Name; - currentManagement.ConfigPath = ""; - currentManagement.SuperManagerId = null; - currentManagement.DomainUid = ""; - } - - // session id pins this session to a specific domain (if domain is given during login) - RestResponse sessionResponsePerDomain = - await restClientCP.AuthenticateUser(currentManagement.ImportCredential.ImportUser, currentManagement.ImportCredential.Secret, currentManagement.DomainUid); - - if (sessionResponsePerDomain.StatusCode == HttpStatusCode.OK && - sessionResponsePerDomain.IsSuccessful && - sessionResponsePerDomain.Data?.SessionId != null && - sessionResponsePerDomain.Data?.SessionId != "") - { - string sessionIdPerDomain = sessionResponsePerDomain.Data!.SessionId; - Log.WriteDebug("Autodiscovery", $"successful CP manager login, domain: {domain.Name}/{domain.Uid}, got SessionID: {sessionIdPerDomain}"); - - // now fetching per gateway information (including package and layer names) - List devList = await restClientCP.GetGateways(@sessionIdPerDomain, ManagementType); - - // add devices to currentManagement - foreach (CpDevice cpDev in devList) - { - if (cpDev.Package.CpAccessLayers.Count < 1) - { - // Log.WriteWarning("AutoDiscovery", $"did not find any layers"); - continue; - } - - if (cpDev.CpDevType != "checkpoint-host") // leave out the management host?! - { - Device dev = new Device - { - Name = cpDev.Name, - LocalRulebase = cpDev.LocalLayerName, - GlobalRulebase = cpDev.GlobalLayerName, - Package = cpDev.Package.Name, - DeviceType = new DeviceType { Id = 9 } // CheckPoint GW - }; - currentManagement.Devices = currentManagement.Devices.Append(dev).ToArray(); - } - sessionResponsePerDomain = await restClientCP.DeAuthenticateUser(@sessionIdPerDomain); - } - } - else - { - Log.WriteWarning("Autodiscovery", - $"CP manager: could not login to manager {currentManagement.Name}, domain: {domain.Name}, got SessionID: {sessionResponsePerDomain.Data?.SessionId}"); - } - discoveredDevices.Add(currentManagement); - } - Log.WriteDebug("Autodiscovery", $"found a total of {domainList.Count} domains"); - } - else - Log.WriteWarning("AutoDiscovery", $"error while getting domain list: {domainResponse.ErrorMessage}"); - - sessionResponse = await restClientCP.DeAuthenticateUser(@sessionId); - if (sessionResponse.StatusCode == HttpStatusCode.OK) - Log.WriteDebug("Autodiscovery", $"successful CP Manager logout"); - else - Log.WriteWarning("Autodiscovery", $"error while logging out from CP Manager: {sessionResponse.ErrorMessage}"); - } - else + Device dev = new() { - string errorTxt = $"error while logging in to CP Manager: {sessionResponse.ErrorMessage} "; - if (sessionResponse?.Data?.SessionId == "") - errorTxt += "could not authenticate to CP manager - got empty session ID"; - Log.WriteWarning("AutoDiscovery", errorTxt); - throw new Exception(errorTxt); - } + Name = cpDev.Name, + Uid = cpDev.Uid, + DeviceType = new DeviceType { Id = 9 } // CheckPoint GW + }; + devices.Add(dev); } - return await GetDeltas(discoveredDevices); } + return [.. devices]; + } + + protected async Task GetMgmUid(CheckPointClient restClientCP, string sessionIdPerDomain, string mgmHostname) + { + List devList = await restClientCP.GetGateways(sessionIdPerDomain); + + string mgmIp = await IpOperations.DnsLookUp(mgmHostname); + + if (string.IsNullOrEmpty(mgmIp)) + { + Log.WriteWarning(Autodiscovery, $"Could not resolve management host {mgmHostname} - using hostname instead"); + mgmIp = mgmHostname; + } + + // Try to find a matching device by IP + foreach (CpDevice cpDev in devList) + { + if (cpDev.CpDevType == CheckpointHost && cpDev.ManagementIp == mgmIp) + { + return cpDev.Uid; + } + } + + // Fallback: return UID of the first checkpoint-host device + var fallbackDevice = devList.FirstOrDefault(d => d.CpDevType == CheckpointHost); + if (fallbackDevice != null) + { + Log.WriteWarning(Autodiscovery, $"No exact IP match for {mgmHostname}, falling back to first found checkpoint-host: {fallbackDevice.Name}"); + return fallbackDevice.Uid; + } + + Log.WriteDebug(Autodiscovery, $"Did not find any checkpoint-host devices - could not set UID"); + return ""; + } + + protected async Task> GetManagers(CheckPointClient restClientCP, string sessionId) + { + List devList = await restClientCP.GetAllCpDevices(sessionId); + List mgmList = [.. devList.Where(d => d.CpDevType == CheckpointHost)]; + return mgmList; + } + + protected static async Task GetGlobalDomainUid(CheckPointClient restClientCP, string sessionIdPerDomain) + { + return await restClientCP.GetGlobalDomainUid(sessionIdPerDomain); } } } diff --git a/roles/lib/files/FWO.DeviceAutoDiscovery/AutoDiscoveryFortiManager.cs b/roles/lib/files/FWO.DeviceAutoDiscovery/AutoDiscoveryFortiManager.cs index 5c9f358c13..8be82585ef 100644 --- a/roles/lib/files/FWO.DeviceAutoDiscovery/AutoDiscoveryFortiManager.cs +++ b/roles/lib/files/FWO.DeviceAutoDiscovery/AutoDiscoveryFortiManager.cs @@ -1,157 +1,262 @@ -using System.Net; -using RestSharp; -using FWO.Api.Data; using FWO.Api.Client; +using FWO.Api.Client.Queries; +using FWO.Config.Api; +using FWO.Data; using FWO.Logging; -using FWO.Rest.Client; +using MailKit.Security; +using RestSharp; +using System.Net; + namespace FWO.DeviceAutoDiscovery { public class AutoDiscoveryFortiManager : AutoDiscoveryBase { + const string AdomSeparator = "_"; + const string VdomSeparator = "_"; + + private readonly List PredefinedAdoms = // TODO: move this to config file + ["FortiAnalyzer", "FortiAuthenticator", "FortiCache", "FortiCarrier", "FortiFirewallCarrier", "FortiClient", + "FortiDDoS", "FortiDeceptor", "FortiFirewall", "FortiMail", "FortiManager", "FortiNAC", "FortiProxy", + "FortiSandbox", "FortiWeb", "Syslog", "Unmanaged_Devices", "others", "rootp"]; + + private readonly string Autodiscovery = "Autodiscovery"; + public AutoDiscoveryFortiManager(Management superManagement, ApiConnection apiConn) : base(superManagement, apiConn) { } + public override async Task> Run() { - List discoveredDevices = new List(); - Log.WriteAudit("Autodiscovery", $"starting discovery for {superManagement.Name} (id={superManagement.Id})"); + List discoveredDevices = []; + Log.WriteAudit(Autodiscovery, $"starting discovery for {SuperManagement.Name} (id={SuperManagement.Id})"); // #if DEBUG - // discoveredDevices = fillTestDevices(); + // discoveredDevices = fillTestDevices(); // #endif - if (superManagement.DeviceType.Name == "FortiManager") + if (SuperManagement.DeviceType.Name == "FortiManager") { - List customAdoms = new List() { }; - List predefinedAdoms = // TODO: move this to config file - new List {"FortiAnalyzer", "FortiAuthenticator", "FortiCache", "FortiCarrier", "FortiClient", - "FortiDDoS", "FortiDeceptor", "FortiFirewall", "FortiMail", "FortiManager", "FortiNAC", "FortiProxy", - "FortiSandbox", "FortiWeb", "Syslog", "Unmanaged_Devices", "others", "rootp"}; - Log.WriteDebug("Autodiscovery", $"discovering FortiManager adoms, vdoms, devices"); - FortiManagerClient restClientFM = new FortiManagerClient(superManagement); - - RestResponse sessionResponse = await restClientFM.AuthenticateUser(superManagement.ImportCredential.ImportUser, superManagement.ImportCredential.Secret); - if (sessionResponse.StatusCode == HttpStatusCode.OK && sessionResponse.IsSuccessful && !string.IsNullOrEmpty(sessionResponse?.Data?.SessionId)) + SuperManagement.IsSupermanager = true; // just to be sure + Log.WriteDebug(Autodiscovery, $"discovering FortiManager adoms, vdoms, devices"); + FortiManagerClient restClientFM = new(SuperManagement); + RestResponse sessionResponse = await restClientFM.AuthenticateUser(SuperManagement.ImportCredential.ImportUser, SuperManagement.ImportCredential.Secret); + if (sessionResponse.StatusCode == HttpStatusCode.OK && sessionResponse.IsSuccessful && !string.IsNullOrEmpty(sessionResponse.Data?.SessionId)) + { + return await DiscoverySession(discoveredDevices); + } + else { - string sessionId = sessionResponse.Data.SessionId; - Log.WriteDebug("Autodiscovery", $"successful FortiManager login, got SessionID: {sessionId}"); - // need to use @ verbatim identifier for special chars in sessionId - RestResponse adomResponse = await restClientFM.GetAdoms(sessionId); - if (adomResponse.StatusCode == HttpStatusCode.OK && adomResponse.IsSuccessful) + string errorTxtCatch = $"{SuperManagement.Name}"; + string errorTxt = $"error while logging in to {SuperManagement.Name}: {sessionResponse.ErrorMessage} "; + if (string.IsNullOrEmpty(sessionResponse.Data?.SessionId)) { - List? adomList = adomResponse?.Data?.Result[0]?.AdomList; - if (adomList?.Count > 0) - { - Log.WriteDebug("Autodiscovery", $"found a total of {adomList.Count} adoms"); - foreach (Adom adom in adomList) - { - Log.WriteDebug("Autodiscovery", $"found adom {adom.Name}"); - if (!predefinedAdoms.Contains(adom.Name)) - { - Log.WriteDebug("Autodiscovery", $"found non-predefined adom {adom.Name}"); - customAdoms.Add(adom); - } - } - customAdoms.Add(new Adom { Name = "global" }); // adding global adom - } - else - Log.WriteWarning("Autodiscovery", $"found no adoms at all!"); + errorTxt += $"could not authenticate to {SuperManagement.Name} - got empty session ID"; } - else - Log.WriteWarning("AutoDiscovery", $"error while getting ADOM list: {adomResponse.ErrorMessage}"); + Log.WriteWarning(Autodiscovery, errorTxt); + throw new AuthenticationException(errorTxtCatch); + } + } + return discoveredDevices; + } + + private async Task> DiscoverySession(List discoveredDevices) + { + Log.WriteDebug(Autodiscovery, $"discovering FortiManager adoms, vdoms, devices"); + FortiManagerClient restClientFM = new(SuperManagement); + + RestResponse sessionResponse = await restClientFM.AuthenticateUser(SuperManagement.ImportCredential.ImportUser, SuperManagement.ImportCredential.Secret); + if (sessionResponse.StatusCode == HttpStatusCode.OK && sessionResponse.IsSuccessful && !string.IsNullOrEmpty(sessionResponse.Data?.SessionId)) + { + string sessionId = sessionResponse.Data.SessionId; + Log.WriteDebug(Autodiscovery, $"successful FortiManager login, got SessionID: {sessionId}"); + // need to use @ verbatim identifier for special chars in sessionId - RestResponse deviceResponse = await restClientFM.GetDevices(@sessionId); - if (deviceResponse.StatusCode == HttpStatusCode.OK && deviceResponse.IsSuccessful) + discoveredDevices = await CollectDevices(sessionId, restClientFM); + await UpdateMgmtUid(sessionId, restClientFM); + sessionResponse = await restClientFM.DeAuthenticateUser(sessionId); + if (sessionResponse.StatusCode == HttpStatusCode.OK) + { + Log.WriteDebug(Autodiscovery, $"successful FortiManager logout"); + } + else + { + Log.WriteWarning(Autodiscovery, $"error while logging out from FortiManager: {sessionResponse.ErrorMessage}"); + } + } + return await GetDeltas(discoveredDevices); + } + + private async Task UpdateMgmtUid(string sessionId, FortiManagerClient restClientFM) + { + // when passing sessionId, we always need to use @ verbatim identifier for special chars in sessionId + if (string.IsNullOrEmpty(SuperManagement.Uid)) // pre v9 managements might not have a UID + { + // update manager UID in existing management; typically triggered in daily scheduler + // this update happens only once when AutoDiscovery v9.0 is run for the first time + SuperManagement.Uid = GetFortiManagerUid(restClientFM, sessionId, SuperManagement.Name); + var vars = new { id = SuperManagement.Id, uid = SuperManagement.Uid }; + _ = (await apiConnection.SendQueryAsync(DeviceQueries.updateManagementUid, vars)).UpdatedId; + // TODO: also add UIDs in gateways? + } + } + + private async Task> CollectDevices(string sessionId, FortiManagerClient restClientFM) + { + List customAdoms = await GetAdoms(sessionId, restClientFM); + await BuildAdomDeviceVdomStructure(sessionId, customAdoms, restClientFM); + return ConvertAdomsToManagements(customAdoms); + } + + public async Task BuildAdomDeviceVdomStructure(string sessionId, List customAdoms, FortiManagerClient restClientFM) + { + + foreach (Adom adom in customAdoms) + { + List additionalVdomDevices = []; + RestResponse deviceResponse = await restClientFM.GetDevicesPerAdom(sessionId, adom.Name); + if (deviceResponse != null && deviceResponse.StatusCode == HttpStatusCode.OK && deviceResponse.IsSuccessful) + { + adom.DeviceList = deviceResponse.Data?.Result[0].FortiGates ?? []; + } + } + // now get vdoms per device + foreach (Adom adom in customAdoms) + { + List additionalVdomDevices = []; + if (adom.DeviceList != null) + { + foreach (FortiGate fg in adom.DeviceList) { - if(deviceResponse.Data != null && deviceResponse.Data.Result.Count > 0) - { - List fortigateList = deviceResponse.Data.Result[0].DeviceList; - foreach (FortiGate fg in fortigateList) - { - Log.WriteDebug("Autodiscovery", $"found device {fg.Name} belonging to management VDOM {fg.MgtVdom}"); - foreach (Vdom vdom in fg.VdomList) - { - Log.WriteDebug("Autodiscovery", $"found vdom {vdom.Name} belonging to device {fg.Name}"); - } - } - } - foreach (Adom adom in customAdoms) + BuildAdomDeviceVdomStructurePerPhysicalDevice(fg, additionalVdomDevices); + } + } + if (additionalVdomDevices.Count > 0) + { + // replace physical devices with vdoms + adom.DeviceList = additionalVdomDevices; + } + } + } + public void BuildAdomDeviceVdomStructurePerPhysicalDevice(FortiGate fg, List additionalVdomDevices) + { + Log.WriteDebug(Autodiscovery, $"found device {fg.Name} belonging to management VDOM {fg.MgtVdom}"); + if (fg.VdomList != null) + { + // add vdom as device + foreach (Vdom vdom in fg.VdomList) + { + Log.WriteDebug(Autodiscovery, $"found vdom {vdom.Name} belonging to device {fg.Name}"); + // add vdom as device + additionalVdomDevices.Add(new FortiGate + { + Name = $"{fg.Name}{AdomSeparator}{vdom.Name}", + Hostname = fg.Hostname, + MgtVdom = vdom.Name, + Uid = $"{fg.Name}{AdomSeparator}{vdom.Name}", + VdomList = [] + }); + } + } + } + + private void LogDeviceResponse(RestResponse deviceResponse) + { + if (deviceResponse.Data != null && deviceResponse.Data.Result.Count > 0) + { + List fortigateList = deviceResponse.Data.Result[0].FortiGates; + foreach (FortiGate fg in fortigateList) + { + Log.WriteDebug(Autodiscovery, $"found device {fg.Name} belonging to management VDOM {fg.MgtVdom}"); + foreach (Vdom vdom in fg.VdomList) + { + Log.WriteDebug(Autodiscovery, $"found vdom {vdom.Name} belonging to device {fg.Name}"); + } + } + } + } + + private async Task> GetAdoms(string sessionId, FortiManagerClient restClientFM) + { + List customAdoms = []; + RestResponse adomResponse = await restClientFM.GetAdoms(sessionId); + if (adomResponse.StatusCode == HttpStatusCode.OK && adomResponse.IsSuccessful) + { + List? adomList = adomResponse.Data?.Result[0]?.AdomList; + if (adomList?.Count > 0) + { + Log.WriteDebug(Autodiscovery, $"found a total of {adomList.Count} adoms"); + foreach (Adom adom in adomList) + { + Log.WriteDebug(Autodiscovery, $"found adom {adom.Name}"); + if (!PredefinedAdoms.Contains(adom.Name)) { - // create object from discovered adom - Management currentManagement = new Management - { - Name = superManagement.Name + "__" + adom.Name, - ImporterHostname = superManagement.ImporterHostname, - Hostname = superManagement.Hostname, - ImportCredential = superManagement.ImportCredential, - Port = superManagement.Port, - ImportDisabled = false, - ForceInitialImport = true, - HideInUi = false, - ConfigPath = adom.Name, - DebugLevel = superManagement.DebugLevel, - SuperManagerId = superManagement.Id, - DeviceType = new DeviceType { Id = 11 }, - Devices = new Device[] { } - }; - - RestResponse assignResponse = await restClientFM.GetPackageAssignmentsPerAdom(@sessionId, adom.Name); - if (assignResponse.StatusCode == HttpStatusCode.OK && assignResponse.IsSuccessful) - { - if(assignResponse.Data != null && assignResponse.Data.Result.Count > 0) - { - List assignmentList = assignResponse.Data.Result[0].AssignmentList; - foreach (Assignment assign in assignmentList) - { - Device devFound = new Device(); - // assign.PackageName = assign.PackageName.Replace("/", "\\/"); // replace / in package name with \/ - Log.WriteDebug("Autodiscovery", $"found assignment1 in ADOM {adom.Name}: package {assign.PackageName} assigned to device {assign.DeviceName}, vdom: {assign.VdomName} "); - if (assign.DeviceName != null) - { - Log.WriteDebug("Autodiscovery", $"found assignment2 (device<>null) in ADOM {adom.Name}: package {assign.PackageName} assigned to device {assign.DeviceName}, vdom: {assign.VdomName} "); - if (assign.DeviceName != "") - { - Log.WriteDebug("Autodiscovery", $"found assignment3 (non-device-empty-string) in ADOM {adom.Name}: package {assign.PackageName} assigned to device {assign.DeviceName}, vdom: {assign.VdomName} "); - string devName = assign.DeviceName; - if (assign.VdomName != null && assign.VdomName != "") - devName += "_" + assign.VdomName; - devFound = new Device - { - Name = devName, - LocalRulebase = assign.PackageName, - Package = assign.PackageName, - DeviceType = new DeviceType { Id = 10 } // fortiGate - }; - // handle global vs. local based on VdomName? - Log.WriteDebug("Autodiscovery", $"assignment devFound Name = {devFound.Name}"); - Log.WriteDebug("Autodiscovery", $"assignment currentManagement before Append contains {currentManagement.Devices.Length} devices"); - currentManagement.Devices = currentManagement.Devices.Append(devFound).ToArray(); - Log.WriteDebug("Autodiscovery", $"assignment currentManagement after Append contains {currentManagement.Devices.Length} devices"); - } - } - adom.Assignments.Add(assign); - } - } - } - discoveredDevices.Add(currentManagement); // add discovered adom including devices + Log.WriteDebug(Autodiscovery, $"found non-predefined adom {adom.Name}"); + customAdoms.Add(adom); } } - else - Log.WriteWarning("AutoDiscovery", $"error while getting device/fortigate list: {deviceResponse.ErrorMessage}"); - - sessionResponse = await restClientFM.DeAuthenticateUser(sessionId); - if (sessionResponse.StatusCode == HttpStatusCode.OK) - Log.WriteDebug("Autodiscovery", $"successful FortiManager logout"); - else - Log.WriteWarning("Autodiscovery", $"error while logging out from FortiManager: {sessionResponse.ErrorMessage}"); + customAdoms.Add(new Adom { Name = "global" }); // adding global adom } else { - string errorTxt = $"error while logging in to FortiManager: {sessionResponse?.ErrorMessage} "; - if (sessionResponse?.Data?.SessionId == "") - errorTxt += "could not authenticate to FortiManager - got empty session ID"; - Log.WriteWarning("AutoDiscovery", errorTxt); - throw new Exception(errorTxt); + Log.WriteWarning(Autodiscovery, $"found no adoms at all!"); } } - return await GetDeltas(discoveredDevices); + else + { + Log.WriteWarning(Autodiscovery, $"error while getting ADOM list: {adomResponse.ErrorMessage}"); + } + return customAdoms; + } + + override protected Management CreateManagement(Management superManagement, string domainName, string domainUid) + { + // create object from discovered adom + Management currentManagement = new() + { + Name = $"{superManagement.Name}{AdomSeparator}{domainName}", + Uid = domainUid, + ImporterHostname = superManagement.ImporterHostname, + Hostname = superManagement.Hostname, + ImportCredential = superManagement.ImportCredential, + Port = superManagement.Port, + ImportDisabled = false, + ForceInitialImport = true, + HideInUi = false, + ConfigPath = domainName, + DebugLevel = superManagement.DebugLevel, + SuperManagerId = superManagement.Id, + DeviceType = new DeviceType { Id = 11 }, + Devices = [] + }; + return currentManagement; + } + + protected static string GetFortiManagerUid(FortiManagerClient restClient, string sessionIdPerDomain, string mgmName) + { + return mgmName; // fortiManager does not have a real UID + } + + private List ConvertAdomsToManagements(List customAdoms) + { + List discoveredDevices = []; + foreach (Adom adom in customAdoms) + { + Management currentManagement = CreateManagement(SuperManagement, adom.Name, adom.Uid); + if (adom.DeviceList != null) + { + foreach (FortiGate fg in adom.DeviceList) + { + string devName = fg.Name; + Device devFound = new() + { + Name = devName, + Uid = string.IsNullOrEmpty(fg.Uid) ? devName : fg.Uid, + DeviceType = new DeviceType { Id = 10 } // fortiGate + }; + currentManagement.Devices = currentManagement.Devices.Append(devFound).ToArray(); + Log.WriteDebug(Autodiscovery, $"adom device found Name = {devFound.Name}"); + } + } + discoveredDevices.Add(currentManagement); + } + return discoveredDevices; } // #if DEBUG @@ -160,7 +265,7 @@ public override async Task> Run() // List testDevices = new List(); // Management currentManagement = new Management // { - // Name = superManagement.Name + "__TestAdom", + // Name = $"{superManagement.Name}{AdomSeparator}{TestAdom}", // ImporterHostname = superManagement.ImporterHostname, // Hostname = superManagement.Hostname, // ImportUser = superManagement.ImportUser, diff --git a/roles/lib/files/FWO.DeviceAutoDiscovery/CheckPointAPI.cs b/roles/lib/files/FWO.DeviceAutoDiscovery/CheckPointAPI.cs index baade3e83a..e39dc74e30 100644 --- a/roles/lib/files/FWO.DeviceAutoDiscovery/CheckPointAPI.cs +++ b/roles/lib/files/FWO.DeviceAutoDiscovery/CheckPointAPI.cs @@ -1,191 +1,205 @@ +using FWO.Api.Client; +using FWO.Data; +using FWO.Logging; +using Newtonsoft.Json; using RestSharp; +using System.Net; using System.Text.Json; -using FWO.Api.Data; using System.Text.Json.Serialization; -using Newtonsoft.Json; -using FWO.Logging; -using RestSharp.Serializers.NewtonsoftJson; -using System.Text.Encodings.Web; -using System.Text; -using RestSharp.Serializers; -namespace FWO.Rest.Client + +namespace FWO.DeviceAutoDiscovery { - public class CheckPointClient + public class CheckPointClient : RestApiClient { - readonly RestClient restClient; + private readonly string CPSidHeaderKey = "X-chkp-sid"; + private readonly string Autodiscovery = "Autodiscovery"; + private readonly string ContentType = "Content-Type"; + private readonly string ApplicationJson = "application/json"; - public CheckPointClient(Management manager) - { - RestClientOptions restClientOptions = new RestClientOptions(); - restClientOptions.RemoteCertificateValidationCallback += (_, _, _, _) => true; - restClientOptions.BaseUrl = new Uri("https://" + manager.Hostname + ":" + manager.Port + "/web_api/"); - restClient = new RestClient(restClientOptions, null, ConfigureRestClientSerialization); - } - - private void ConfigureRestClientSerialization(SerializerConfig config) - { - JsonNetSerializer serializer = new JsonNetSerializer(); // Case insensivitive is enabled by default - config.UseSerializer(() => serializer); - } + public CheckPointClient(Management manager) : base("https://" + manager.Hostname + ":" + manager.Port + "/web_api/") + { } public async Task> AuthenticateUser(string? user, string? pwd, string? domain) { if (user == null || user == "") { - Log.WriteWarning("Autodiscovery", $"GetDomains got empty user string, aborting"); + Log.WriteWarning(Autodiscovery, $"GetDomains got empty user string, aborting"); return new RestResponse(new RestRequest()); } - if (pwd == null) - pwd = ""; - if (domain == null) - domain = ""; - Dictionary body = new Dictionary(); - body.Add("user", user); - body.Add("password", pwd); + pwd ??= ""; + domain ??= ""; + Dictionary body = new() + { + { "user", user }, + { "password", pwd } + }; if (domain != "") body.Add("domain", domain); - RestRequest request = new RestRequest("login", Method.Post); + RestRequest request = new("login", Method.Post); request.AddJsonBody(body); - request.AddHeader("Content-Type", "application/json"); + request.AddHeader(ContentType, ApplicationJson); return await restClient.ExecuteAsync(request); } public async Task> DeAuthenticateUser(string session) { - RestRequest request = new RestRequest("logout", Method.Post); - request.AddHeader("Content-Type", "application/json"); - request.AddHeader("X-chkp-sid", session); + RestRequest request = new("logout", Method.Post); + request.AddHeader(ContentType, ApplicationJson); + request.AddHeader(CPSidHeaderKey, session); request.AddJsonBody(new { }); return await restClient.ExecuteAsync(request); } - public async Task> GetDomains(string session) + public async Task> GetDomains(string session) { - RestRequest request = new RestRequest("show-domains", Method.Post); - request.AddHeader("X-chkp-sid", session); - request.AddHeader("Content-Type", "application/json"); - Dictionary body = new Dictionary(); - body.Add("details-level", "full"); + RestRequest request = new("show-domains", Method.Post); + request.AddHeader(CPSidHeaderKey, session); + request.AddHeader(ContentType, ApplicationJson); + Dictionary body = new() + { + { "details-level", "full" } + }; request.AddJsonBody(body); - return await restClient.ExecuteAsync(request); - } + RestResponse domainResponse = await restClient.ExecuteAsync(request); - private static bool containsDomainLayer(List layers) - { - foreach (CpAccessLayer layer in layers) + if (domainResponse.StatusCode == HttpStatusCode.OK && domainResponse.IsSuccessful && domainResponse.Data?.DomainList != null) { - if (layer.ParentLayer != "") - return true; + List domainList = domainResponse.Data.DomainList; + if (domainList.Count == 0) + { + Log.WriteDebug(Autodiscovery, $"found no domains - assuming this is a standard management, adding dummy domain with empty name"); + domainList.Add(new Domain { Name = "" }); + } + return domainList; } - return false; + return []; } - public async Task> GetGateways(string session, string ManagementType) + public async Task> GetAllCpDevices(string session) // session id pins this session to a specific domain (if domain was given during login) { - RestRequest request = new RestRequest("show-gateways-and-servers", Method.Post); - request.AddHeader("X-chkp-sid", session); - request.AddHeader("Content-Type", "application/json"); - Dictionary body = new Dictionary(); - body.Add("details-level", "full"); + RestRequest request = new("show-gateways-and-servers", Method.Post); + request.AddHeader(CPSidHeaderKey, session); + request.AddHeader(ContentType, ApplicationJson); + Dictionary body = new() + { + { "details-level", "full" } + }; request.AddJsonBody(body); - Log.WriteDebug("Autodiscovery", $"using CP REST API call 'show-gateways-and-servers'"); - List gwTypes = new List { "simple-gateway", "simple-cluster", "CpmiVsClusterNetobj", "CpmiGatewayPlain", "CpmiGatewayCluster", "CpmiVsxClusterNetobj" }; + Log.WriteDebug(Autodiscovery, $"using CP REST API call 'show-gateways-and-servers'"); - // getting all gateways of this management + // getting all devices of this management RestResponse devices = await restClient.ExecuteAsync(request); - if(devices.Data != null) + if (devices.Data != null) { - foreach (CpDevice dev in devices.Data.DeviceList) + return devices.Data.DeviceList; + } + return []; + } + + public async Task> GetManagers(string session, string ManagementType) + // session id pins this session to a specific domain (if domain was given during login) + { + List gwTypes = ["simple-gateway", "simple-cluster", "CpmiVsNetobj", "CpmiVsClusterNetobj", "CpmiGatewayPlain", "CpmiGatewayCluster", "CpmiVsxClusterNetobj", "CpmiVsxNetobj"]; + + List devices = await GetAllCpDevices(session); + if (devices != null) + { + foreach (CpDevice dev in devices) { - if (gwTypes.Contains(dev.CpDevType)) + if (gwTypes.Contains(dev.CpDevType) && !dev.Policy.AccessPolicyInstalled) { - if (dev.Policy.AccessPolicyInstalled) // get package info - { - Log.WriteDebug("Autodiscovery", $"found gateway '{dev.Name}' with access policy '{dev.Policy.AccessPolicyName}'"); - RestRequest requestPackage = new RestRequest("show-package", Method.Post); - requestPackage.AddHeader("X-chkp-sid", session); - requestPackage.AddHeader("Content-Type", "application/json"); - Dictionary packageBody = new Dictionary(); - packageBody.Add("name", dev.Policy.AccessPolicyName); - packageBody.Add("details-level", "full"); - requestPackage.AddJsonBody(packageBody); - RestResponse package = await restClient.ExecuteAsync(requestPackage); - if (dev != null && package != null && package.Data != null) - { - dev.Package = package.Data; - Log.WriteDebug("Autodiscovery", $"for gateway '{dev.Name}' we found a package '{dev?.Package?.Name}' with {dev?.Package?.CpAccessLayers.Count} layers"); - - extractLayerNames(dev!.Package, dev.Name, ManagementType, out string localLayerName, out string globalLayerName); - dev.LocalLayerName = localLayerName; - dev.GlobalLayerName = globalLayerName; - } - } - else - Log.WriteWarning("Autodiscovery", $"found gateway '{dev.Name}' without access policy"); + Log.WriteWarning(Autodiscovery, $"found gateway '{dev.Name}' without access policy"); } } - return devices.Data.DeviceList; + return devices; } - return new List(); + return []; } - private void extractLayerNames(CpPackage package, string devName, string managementType, out string localLayerName, out string globalLayerName) + public async Task> GetGateways(string session) + // session id pins this session to a specific domain (if domain was given during login) { - localLayerName = ""; - globalLayerName = ""; - // getting rid of unneccessary layers (eg. url filtering, application, ...) - List relevantLayers = new List(); - if (package.CpAccessLayers.Count == 1) // default: pick the first layer found (if any) - relevantLayers.Add(package.CpAccessLayers[0]); - else if (package.CpAccessLayers.Count > 1) + List gwTypes = ["simple-gateway", "simple-cluster", "CpmiVsNetobj", "CpmiVsClusterNetobj", "CpmiGatewayPlain", "CpmiGatewayCluster", "CpmiVsxClusterNetobj", "CpmiVsxNetobj"]; + + List devices = await GetAllCpDevices(session); + if (devices != null) { - Log.WriteWarning("Autodiscovery", $"for gateway '{devName}'/ package '{package.Name}' we found multiple ({package.CpAccessLayers.Count}) layers"); - // for now: pick the layer which the most "firewall-ish" - TODO: deal with layer chaining - foreach (CpAccessLayer layer in package.CpAccessLayers) + foreach (CpDevice dev in devices) { - if (layer.IsFirewallEnabled && !layer.IsApplicationsAndUrlFilteringEnabled && !layer.IsContentAwarenessEnabled && !layer.IsMobileAccessEnabled) - relevantLayers.Add(layer); + if (gwTypes.Contains(dev.CpDevType) && !dev.Policy.AccessPolicyInstalled) + { + Log.WriteWarning(Autodiscovery, $"found gateway '{dev.Name}' without access policy"); + } } + return devices; } + return []; + } - foreach (CpAccessLayer layer in relevantLayers) + public async Task GetGlobalDomainUid(string session) + { + RestRequest request = new("show-global-domain", Method.Post); + request.AddHeader("X-chkp-sid", session); + request.AddHeader(ContentType, ApplicationJson); + Dictionary body = new() { - if (layer.Type != "access-layer") // only dealing with access layers, ignore the rest - continue; + { "details-level", "full" }, + { "name", "Global" } + }; + request.AddJsonBody(body); + Log.WriteDebug(Autodiscovery, $"using CP REST API call 'show-global-domain'"); - if (layer.ParentLayer != "") // this is a domain layer - { - localLayerName = layer.Name; - layer.LayerType = "domain-layer"; - Log.WriteDebug("Autodiscovery", $"found domain layer with link to parent layer '{layer.ParentLayer}'"); - } - else if (managementType == "stand-alone") + // getting name and uid of the global domain + RestResponse globalDomain = await restClient.ExecuteAsync(request); + if (globalDomain.Data != null) + { + return globalDomain.Data.Uid; + } + return ""; + } + + public async Task GetMdsUid(Management management) + { + RestResponse response = await AuthenticateUser(management.ImportCredential.ImportUser, management.ImportCredential.Secret, "System Data"); + if (response.StatusCode != HttpStatusCode.OK || !response.IsSuccessful) + { + Log.WriteError(Autodiscovery, $"failed to authenticate user '{management.ImportCredential.ImportUser}'"); + return ""; + } + string session = response.Data?.SessionId ?? ""; + if (session == "") + { + Log.WriteError(Autodiscovery, $"failed to authenticate user '{management.ImportCredential.ImportUser}'"); + return ""; + } + + RestRequest request = new("show-mdss", Method.Post); + request.AddHeader("X-chkp-sid", session); + request.AddHeader(ContentType, ApplicationJson); + Dictionary body = []; + request.AddJsonBody(body); + Log.WriteDebug(Autodiscovery, $"using CP REST API call 'show-mdss'"); + + // getting name and uid of the global domain + RestResponse mdsObjects = await restClient.ExecuteAsync(request); + if (mdsObjects.Data?.Mds != null) + { + if (mdsObjects.Data.Mds.Count == 0) { - localLayerName = layer.Name; - layer.LayerType = "local-layer"; - Log.WriteDebug("Autodiscovery", $"found stand-alone layer '{layer.Name}'"); - } - else if (containsDomainLayer(package.CpAccessLayers)) - { // this must the be global layer - layer.LayerType = "global-layer"; - globalLayerName = layer.Name; - Log.WriteDebug("Autodiscovery", $"found global layer '{layer.Name}'"); + Log.WriteDebug(Autodiscovery, $"found no MDS - assuming this is a standard management, adding dummy domain with empty name"); + mdsObjects.Data.Mds.Add(new CpNameUidHelper { Name = "", Uid = "" }); + return ""; } else - { // in domain context, but no global layer exists - layer.LayerType = "stand-alone-layer"; - localLayerName = layer.Name; - Log.WriteDebug("Autodiscovery", $"found stand-alone layer in domain context '{layer.Name}'"); + { + return mdsObjects.Data.Mds[0].Uid; } - // TODO: this will contstantly overwrite local layer name if more than one exists, the last one wins! } - - package.CpAccessLayers = relevantLayers; - if (relevantLayers.Count == 0) - Log.WriteWarning("Autodiscovery", $"found gateway '{devName}' without access layers"); + return ""; } + } public class CpSessionAuthInfo @@ -206,11 +220,10 @@ public class CpApiStatus public class CpDomainHelper { [JsonProperty("objects"), JsonPropertyName("objects")] - public List DomainList { get; set; } = new List(); + public List DomainList { get; set; } = []; [JsonProperty("total"), JsonPropertyName("total")] public int Total { get; set; } - } public class Domain @@ -223,14 +236,33 @@ public class Domain [JsonProperty("domain-type"), JsonPropertyName("domain-type")] public string DomainType { get; set; } = ""; + } + + public class CpNameUidHelper + { + [JsonProperty("name"), JsonPropertyName("name")] + public string Name { get; set; } = ""; + + [JsonProperty("uid"), JsonPropertyName("uid")] + public string Uid { get; set; } = ""; + } - // public List Assignments = new List(); + public class MdsHelper + { + [JsonProperty("objects"), JsonPropertyName("objects")] + public List Mds { get; set; } = []; + } + + public class CpPackagesHelper + { + [JsonProperty("packages"), JsonPropertyName("packages")] + public List PackageList { get; set; } = []; } public class CpDeviceHelper { [JsonProperty("objects"), JsonPropertyName("objects")] - public List DeviceList { get; set; } = new List(); + public List DeviceList { get; set; } = []; } public class CpDevice @@ -250,11 +282,16 @@ public class CpDevice [JsonProperty("policy"), JsonPropertyName("policy")] public CpPolicy Policy { get; set; } = new CpPolicy(); + [JsonProperty("ipv4-address"), JsonPropertyName("ipv4-address")] + public string ManagementIp { get; set; } = ""; + public CpPackage Package { get; set; } = new CpPackage(); public string LocalLayerName { get; set; } = ""; public string GlobalLayerName { get; set; } = ""; + public List Layers { get; set; } = []; + } public class DevObjectsHelper @@ -284,7 +321,7 @@ public class CpPackage public Domain Domain { get; set; } = new Domain(); [JsonProperty("access-layers"), JsonPropertyName("access-layers")] - public List CpAccessLayers { get; set; } = new List(); + public List CpAccessLayers { get; set; } = []; } public class CpAccessLayer diff --git a/roles/lib/files/FWO.DeviceAutoDiscovery/FWO.DeviceAutoDiscovery.csproj b/roles/lib/files/FWO.DeviceAutoDiscovery/FWO.DeviceAutoDiscovery.csproj index 8f9ca77df5..28b515d686 100644 --- a/roles/lib/files/FWO.DeviceAutoDiscovery/FWO.DeviceAutoDiscovery.csproj +++ b/roles/lib/files/FWO.DeviceAutoDiscovery/FWO.DeviceAutoDiscovery.csproj @@ -1,22 +1,17 @@ - net6.0 + net10.0 enable enable - - - - - - - + + diff --git a/roles/lib/files/FWO.DeviceAutoDiscovery/FortiManagerAPI.cs b/roles/lib/files/FWO.DeviceAutoDiscovery/FortiManagerAPI.cs index abf4d533ef..64f69b6367 100644 --- a/roles/lib/files/FWO.DeviceAutoDiscovery/FortiManagerAPI.cs +++ b/roles/lib/files/FWO.DeviceAutoDiscovery/FortiManagerAPI.cs @@ -1,42 +1,21 @@ -using RestSharp; -using RestSharp.Serializers.SystemTextJson; -using System.Text.Json; -using FWO.Api.Data; -using System.Text; -using System.Text.Json.Serialization; -using System.Text.Encodings.Web; -using Newtonsoft.Json; +using FWO.Api.Client; +using FWO.Data; using FWO.Logging; -using RestSharp.Serializers.NewtonsoftJson; -using RestSharp.Serializers; +using RestSharp; -namespace FWO.Rest.Client +namespace FWO.DeviceAutoDiscovery { - public class FortiManagerClient + public class FortiManagerClient : RestApiClient { - readonly RestClient restClient; + public FortiManagerClient(Management fortiManager) : base("https://" + fortiManager.Hostname + ":" + fortiManager.Port + "/jsonrpc") + { } - public FortiManagerClient(Management fortiManager) + public async Task> AuthenticateUser(string? user, string pwd, string domainString = "") { - RestClientOptions restClientOptions = new RestClientOptions(); - restClientOptions.RemoteCertificateValidationCallback += (_, _, _, _) => true; - restClientOptions.BaseUrl = new Uri("https://" + fortiManager.Hostname + ":" + fortiManager.Port + "/jsonrpc"); - restClient = new RestClient(restClientOptions, null, ConfigureRestClientSerialization); - } - - private void ConfigureRestClientSerialization(SerializerConfig config) - { - JsonNetSerializer serializer = new JsonNetSerializer(); // Case insensivitive is enabled by default - config.UseSerializer(() => serializer); - } - - - public async Task> AuthenticateUser(string? user, string pwd) - { - List dataList = new List(); + List dataList = []; dataList.Add(new { passwd = pwd, user = user }); - List paramList = new List(); + List paramList = []; paramList.Add(new { data = dataList, url = "/sys/login/user" }); var body = new @@ -45,14 +24,14 @@ public async Task> AuthenticateUser(string? user, id = 1, @params = paramList // because "params" is a c# keyword, we have to escape it here with @ }; - RestRequest request = new RestRequest("", Method.Post); + RestRequest request = new("", Method.Post); request.AddJsonBody(body); return await restClient.ExecuteAsync(request); } public async Task> DeAuthenticateUser(string session) { - List paramList = new List(); + List paramList = []; paramList.Add(new { session = session, url = "/sys/logout" }); var body = new @@ -61,15 +40,35 @@ public async Task> DeAuthenticateUser(string sessi id = 1, @params = paramList // because "params" is a c# keyword, we have to escape it here with @ }; - RestRequest request = new RestRequest("", Method.Post); + RestRequest request = new("", Method.Post); request.AddJsonBody(body); return await restClient.ExecuteAsync(request); } - public async Task> GetAdoms(string session) + public async Task GetFortiManagerDetails(string sessionId) + { + string[] fieldArray = ["name", "oid", "uuid"]; + List paramList = [new { fields = fieldArray, url = "/sys/status" }]; + + var body = new + { + @params = paramList, + method = "get", + id = 1, + session = sessionId + }; + RestRequest request = new("", Method.Post); + request.AddJsonBody(body); + Log.WriteDebug("Autodiscovery", $"using FortiManager REST API call with body='{body.ToString()}' and paramList='{paramList.ToString()}'"); + await restClient.ExecuteAsync(request); + + return "dummy-uid"; + } + + public async Task> GetAdoms(string sessionId) { string[] fieldArray = { "name", "oid", "uuid" }; - List paramList = new List(); + List paramList = []; paramList.Add(new { fields = fieldArray, url = "/dvmdb/adom" }); var body = new @@ -77,18 +76,18 @@ public async Task> GetAdoms(string session) @params = paramList, method = "get", id = 1, - session = session + session = sessionId }; - RestRequest request = new RestRequest("", Method.Post); + RestRequest request = new("", Method.Post); request.AddJsonBody(body); Log.WriteDebug("Autodiscovery", $"using FortiManager REST API call with body='{body.ToString()}' and paramList='{paramList.ToString()}'"); return await restClient.ExecuteAsync(request); } - public async Task> GetDevices(string session) + public async Task> GetDevices(string sessionId) { - string[] fieldArray = { "name", "desc", "hostname", "vdom", "ip", "mgmt_id", "mgt_vdom", "os_type", "os_ver", "platform_str", "dev_status" }; - List paramList = new List(); + string[] fieldArray = ["name", "desc", "hostname", "vdom", "ip", "mgmt_id", "mgt_vdom", "os_type", "os_ver", "platform_str", "dev_status"]; + List paramList = []; paramList.Add(new { fields = fieldArray, url = "/dvmdb/device" }); var body = new @@ -96,173 +95,29 @@ public async Task> GetDevices(string sessio @params = paramList, method = "get", id = 1, - session = session + session = sessionId }; - RestRequest request = new RestRequest("", Method.Post); + RestRequest request = new("", Method.Post); request.AddJsonBody(body); return await restClient.ExecuteAsync(request); } - public async Task> GetPackageAssignmentsPerAdom(string session, string adomName) + public async Task> GetDevicesPerAdom(string sessionId, string adomName) { - List paramList = new List(); - string urlString = "/pm/config/"; - - if (adomName=="global") - urlString += "global/_package/status"; - else - urlString += "adom/" + adomName + "/_package/status"; - paramList.Add(new { url = urlString }); + string[] fieldArray = ["name", "desc", "hostname", "vdom", "ip", "mgmt_id", "mgt_vdom", "os_type", "os_ver", "platform_str", "dev_status"]; + List paramList = []; + paramList.Add(new { fields = fieldArray, url = $"/dvmdb/adom/{adomName}/device" }); var body = new { @params = paramList, method = "get", id = 1, - session = session + session = sessionId }; - RestRequest request = new RestRequest("", Method.Post); + RestRequest request = new("", Method.Post); request.AddJsonBody(body); - return await restClient.ExecuteAsync(request); + return await restClient.ExecuteAsync(request); } } - - public class SessionAuthInfo - { - [JsonProperty("session"), JsonPropertyName("session")] - public string SessionId { get; set; } = ""; - } - - public class FmApiStatus - { - [JsonProperty("code"), JsonPropertyName("code")] - public int Code { get; set; } - - [JsonProperty("message"), JsonPropertyName("message")] - public string Message { get; set; } = ""; - } - -/////////////////////////////////////////////////////////////////////////////////////////////////// - public class FmApiTopLevelHelper - { - [JsonProperty("id"), JsonPropertyName("id")] - public int Id { get; set; } - - [JsonProperty("status"), JsonPropertyName("status")] - public FmApiStatus Status { get; set; } = new FmApiStatus(); - - [JsonProperty("result"), JsonPropertyName("result")] - public List Result { get; set; } = new List(); - } - - public class FmApiDataHelper - { - [JsonProperty("data"), JsonPropertyName("data")] - public List AdomList { get; set; } = new List(); - } - - public class Adom - { - [JsonProperty("oid"), JsonPropertyName("oid")] - public int Oid { get; set; } - - [JsonProperty("name"), JsonPropertyName("name")] - public string Name { get; set; } = ""; - - [JsonProperty("uuid"), JsonPropertyName("uuid")] - public string Uid { get; set; } = ""; - - // public List Packages = new List(); - public List Assignments = new List(); - } - -/////////////////////////////////////////////////////////////////////////////////////////////////// - - public class FmApiTopLevelHelperDev - { - [JsonProperty("id"), JsonPropertyName("id")] - public int Id { get; set; } - - [JsonProperty("status"), JsonPropertyName("status")] - public FmApiStatus Status { get; set; } = new FmApiStatus(); - - [JsonProperty("result"), JsonPropertyName("result")] - public List Result { get; set; } = new List(); - } - - public class FmApiDataHelperDev - { - [JsonProperty("data"), JsonPropertyName("data")] - public List DeviceList { get; set; } = new List(); - } - public class FortiGate - { - [JsonProperty("oid"), JsonPropertyName("oid")] - public int Oid { get; set; } - - [JsonProperty("name"), JsonPropertyName("name")] - public string Name { get; set; } = ""; - - [JsonProperty("hostname"), JsonPropertyName("hostname")] - public string Hostname { get; set; } = ""; - - // [JsonProperty("ip"), JsonPropertyName("ip")] - // public string Ip { get; set; } = ""; - - [JsonProperty("mgt_vdom"), JsonPropertyName("mgt_vdom")] - public string MgtVdom { get; set; } = ""; - - // [JsonProperty("os_ver"), JsonPropertyName("os_ver")] - // public string OsVer { get; set; } = ""; - - // [JsonProperty("dev_status"), JsonPropertyName("dev_status")] - // public string DevStatus { get; set; } = ""; - - [JsonProperty("vdom"), JsonPropertyName("vdom")] - public List VdomList { get; set; } = new List(); - - // "name", "desc", "hostname", "vdom", "ip", "mgmt_id", "mgt_vdom", "os_type", "os_ver", "platform_str", "dev_status" - } - public class Vdom - { - [JsonProperty("oid"), JsonPropertyName("oid")] - public int Oid { get; set; } - - [JsonProperty("name"), JsonPropertyName("name")] - public string Name { get; set; } = ""; - } - -/////////////////////////////////////////////////////////////////////////////////////////////////// - - public class FmApiTopLevelHelperAssign - { - [JsonProperty("id"), JsonPropertyName("id")] - public int Id { get; set; } - - [JsonProperty("status"), JsonPropertyName("status")] - public FmApiStatus Status { get; set; } = new FmApiStatus(); - - [JsonProperty("result"), JsonPropertyName("result")] - public List Result { get; set; } = new List(); - } - - public class FmApiDataHelperAssign - { - [JsonProperty("data"), JsonPropertyName("data")] - public List AssignmentList { get; set; } = new List(); - } - public class Assignment - { - [JsonProperty("oid"), JsonPropertyName("oid")] - public int Oid { get; set; } - - [JsonProperty("dev"), JsonPropertyName("dev")] - public string DeviceName { get; set; } = ""; - - [JsonProperty("vdom"), JsonPropertyName("vdom")] - public string VdomName { get; set; } = ""; - - [JsonProperty("pkg"), JsonPropertyName("pkg")] - public string PackageName { get; set; } = ""; - } } diff --git a/roles/lib/files/FWO.DeviceAutoDiscovery/FortiManagerData.cs b/roles/lib/files/FWO.DeviceAutoDiscovery/FortiManagerData.cs new file mode 100644 index 0000000000..07ce221582 --- /dev/null +++ b/roles/lib/files/FWO.DeviceAutoDiscovery/FortiManagerData.cs @@ -0,0 +1,103 @@ +using Newtonsoft.Json; +using System.Text.Json; +using System.Text.Json.Serialization; + +namespace FWO.DeviceAutoDiscovery +{ + public class FmApiStatus + { + [JsonProperty("code"), JsonPropertyName("code")] + public int Code { get; set; } + + [JsonProperty("message"), JsonPropertyName("message")] + public string Message { get; set; } = ""; + } + + public class FmApiTopLevelHelper + { + [JsonProperty("id"), JsonPropertyName("id")] + public int Id { get; set; } + + [JsonProperty("status"), JsonPropertyName("status")] + public FmApiStatus Status { get; set; } = new(); + + [JsonProperty("result"), JsonPropertyName("result")] + public List Result { get; set; } = []; + } + + public class FmApiDataHelper + { + [JsonProperty("data"), JsonPropertyName("data")] + public List AdomList { get; set; } = []; + } + + public class Adom + + { + [JsonProperty("oid"), JsonPropertyName("oid")] + public int Oid { get; set; } + + [JsonProperty("name"), JsonPropertyName("name")] + public string Name { get; set; } = ""; + + [JsonProperty("uuid"), JsonPropertyName("uuid")] + public string Uid { get; set; } = ""; + + [JsonProperty("devices"), JsonPropertyName("devices")] + public List DeviceList { get; set; } = []; + } + + + public class FmApiTopLevelHelperDev + { + [JsonProperty("id"), JsonPropertyName("id")] + public int Id { get; set; } + + [JsonProperty("status"), JsonPropertyName("status")] + public FmApiStatus Status { get; set; } = new(); + + [JsonProperty("result"), JsonPropertyName("result")] + public List Result { get; set; } = []; + } + + public class FmApiDataHelperDev + { + [JsonProperty("data"), JsonPropertyName("data")] + public List FortiGates { get; set; } = []; + } + public class FortiGate + { + [JsonProperty("oid"), JsonPropertyName("oid")] + public int Oid { get; set; } + + [JsonProperty("name"), JsonPropertyName("name")] + public string Name { get; set; } = ""; + + [JsonProperty("hostname"), JsonPropertyName("hostname")] + public string Hostname { get; set; } = ""; + + [JsonProperty("mgt_vdom"), JsonPropertyName("mgt_vdom")] + public string MgtVdom { get; set; } = ""; + + [JsonProperty("vdom"), JsonPropertyName("vdom")] + public List VdomList { get; set; } = []; + + // uid is not really contained in fortigate, we will set it to the name instead + public string Uid { get; set; } = ""; + + } + public class Vdom + { + [JsonProperty("oid"), JsonPropertyName("oid")] + public int Oid { get; set; } + + [JsonProperty("name"), JsonPropertyName("name")] + public string Name { get; set; } = ""; + } + + public class SessionAuthInfo + { + [JsonProperty("session"), JsonPropertyName("session")] + public string SessionId { get; set; } = ""; + } +} diff --git a/roles/lib/files/FWO.Encryption/AesEnc.cs b/roles/lib/files/FWO.Encryption/AesEnc.cs new file mode 100644 index 0000000000..01a6628742 --- /dev/null +++ b/roles/lib/files/FWO.Encryption/AesEnc.cs @@ -0,0 +1,209 @@ +using System.Security.Cryptography; +using System.Text; +using FWO.Basics; +using FWO.Logging; + +namespace FWO.Encryption +{ + public static class AesEnc + { + public static string TryEncrypt(string secret) + { + string mainKey = GetMainKey(); + + // only encrypt secret if it was not already encrypted + if (TryDecrypt(secret, mainKey, out _)) + { + return secret; + } + + return Encrypt(secret, mainKey); + } + + public static string TryDecrypt(string secret, bool returnOrigin = false, string logMessageTitle = "", string logText = "", bool onlyWarning = false) + { + string mainKey; + try + { + mainKey = GetMainKey(); + } + catch (Exception exception) + { + HandleDecryptLog(logMessageTitle, logText, onlyWarning, exception); + return returnOrigin ? secret : ""; + } + + if (TryDecrypt(secret, mainKey, out string decryptedText)) + { + return decryptedText; + } + + HandleDecryptLog(logMessageTitle, logText, onlyWarning); + return returnOrigin ? secret : ""; + } + + public static bool TryDecrypt(string encryptedDataString, string key, out string decryptedText) + { + decryptedText = string.Empty; + + if (string.IsNullOrEmpty(encryptedDataString)) + { + return false; + } + + try + { + if (!TryDecodeBase64String(encryptedDataString, out byte[] encryptedBytes)) + { + return false; + } + + string? decrypted = CustomAesCbcDecrypt(encryptedBytes, key); + if (decrypted == null) + { + return false; + } + + decryptedText = decrypted; + return true; + } + catch (Exception) + { + decryptedText = string.Empty; + return false; + } + } + + private static void HandleDecryptLog(string logMessageTitle, string logText, bool onlyWarning, Exception? exception = null) + { + if (string.IsNullOrEmpty(logMessageTitle)) + { + return; + } + + string message = string.IsNullOrEmpty(logText) ? "Could not decrypt secret." : logText; + + if (onlyWarning) + { + Log.WriteWarning(logMessageTitle, message); + } + else + { + if (exception != null) + { + Log.WriteError(logMessageTitle, message, exception); + } + else + { + Log.WriteError(logMessageTitle, message); + } + } + } + + public static string GetMainKey() + { + try + { + string mainKey = File.ReadAllText(GlobalConst.kMainKeyFile); + mainKey = mainKey.TrimEnd(); // remove trailing whitespace + return mainKey; + } + catch (Exception e) + { + Log.WriteError("Main Key File", "Main key file could not be read.", e); + throw; + } + } + + public static string Encrypt(string plaintext, string key) + { + return CustomAesCbcEncryptBase64(plaintext, key); + } + + public static string Decrypt(string encryptedDataString, string key) + { + return TryDecrypt(encryptedDataString, key, out string decryptedText) + ? decryptedText + : string.Empty; + } + + private static string CustomAesCbcEncryptBase64(string plaintext, string key) + { + using Aes aes = Aes.Create(); + aes.Key = Encoding.UTF8.GetBytes(key); + aes.GenerateIV(); + aes.Mode = CipherMode.CBC; + aes.Padding = PaddingMode.PKCS7; + + using ICryptoTransform encryptor = aes.CreateEncryptor(aes.Key, aes.IV); + byte[] plaintextBytes = Encoding.UTF8.GetBytes(plaintext); + byte[] encryptedBytes = encryptor.TransformFinalBlock(plaintextBytes, 0, plaintextBytes.Length); + + // Combine IV and encrypted text + byte[] ivAndEncrypted = new byte[aes.IV.Length + encryptedBytes.Length]; + Array.Copy(aes.IV, ivAndEncrypted, aes.IV.Length); + Array.Copy(encryptedBytes, 0, ivAndEncrypted, aes.IV.Length, encryptedBytes.Length); + + return Convert.ToBase64String(ivAndEncrypted); + } + + private static bool TryDecodeBase64String(string ciphertext, out byte[] decodedBytes) + { + decodedBytes = Array.Empty(); + + if (string.IsNullOrWhiteSpace(ciphertext)) + { + return false; + } + + byte[] buffer = new byte[ciphertext.Length]; + if (!Convert.TryFromBase64String(ciphertext, buffer, out int bytesWritten)) + { + return false; + } + + decodedBytes = new byte[bytesWritten]; + Array.Copy(buffer, decodedBytes, bytesWritten); + return true; + } + + private static string? CustomAesCbcDecrypt(byte[] encryptedBytes, string key) + { + // IV size for AES-CBC is typically 16 bytes + int ivSize = 16; + if (encryptedBytes.Length < ivSize) + { + return null; + } + byte[] iv = new byte[ivSize]; + byte[] encryptedText = new byte[encryptedBytes.Length - ivSize]; + + // Extract IV from the beginning of the ciphertext + Array.Copy(encryptedBytes, 0, iv, 0, ivSize); + Array.Copy(encryptedBytes, ivSize, encryptedText, 0, encryptedText.Length); + + using Aes aes = Aes.Create(); + aes.Key = Encoding.UTF8.GetBytes(key); + aes.IV = iv; + aes.Mode = CipherMode.CBC; + aes.Padding = PaddingMode.PKCS7; + + int blockSizeBytes = aes.BlockSize / 8; + if (encryptedText.Length % blockSizeBytes != 0) + { + return null; + } + + try + { + using ICryptoTransform decryptor = aes.CreateDecryptor(aes.Key, aes.IV); + byte[] decryptedBytes = decryptor.TransformFinalBlock(encryptedText, 0, encryptedText.Length); + return Encoding.UTF8.GetString(decryptedBytes); + } + catch (CryptographicException) + { + return null; + } + } + } +} diff --git a/roles/lib/files/FWO.Encryption/FWO.Encryption.csproj b/roles/lib/files/FWO.Encryption/FWO.Encryption.csproj new file mode 100644 index 0000000000..233446dbcb --- /dev/null +++ b/roles/lib/files/FWO.Encryption/FWO.Encryption.csproj @@ -0,0 +1,13 @@ + + + + net10.0 + enable + enable + + + + + + + diff --git a/roles/lib/files/FWO.ExternalSystems/ExternalTicket.cs b/roles/lib/files/FWO.ExternalSystems/ExternalTicket.cs new file mode 100644 index 0000000000..897d9b4f6b --- /dev/null +++ b/roles/lib/files/FWO.ExternalSystems/ExternalTicket.cs @@ -0,0 +1,59 @@ +using FWO.Data; +using FWO.Data.Workflow; +using FWO.Data.Modelling; +using FWO.Logging; +using Newtonsoft.Json; +using RestSharp; +using System.Text.Json.Serialization; + +namespace FWO.ExternalSystems +{ + public class ExternalTicket + { + [JsonProperty("ticketText"), JsonPropertyName("ticketText")] + public string TicketText { get; set; } = ""; + + public string? TicketId { get; set; } = ""; + protected List TicketTasks = []; + public ExternalTicketSystem TicketSystem { get; set; } = new(); + + public ExternalTicket() { } + + public virtual Task CreateRequestString(List tasks, List ipProtos, ModellingNamingConvention? namingConvention) + { + throw new NotImplementedException(); + } + + public virtual string GetTaskTypeAsString(WfReqTask task) + { + return ""; + } + + public virtual Task<(string, string?)> GetNewState(string oldState) + { + throw new NotImplementedException(); + } + + public virtual Task> CreateExternalTicket() + { + throw new NotImplementedException(); + } + + protected virtual Task> PollExternalTicket() + { + throw new NotImplementedException(); + } + + protected static void CheckForProperJson(string jsonString) + { + try + { + System.Text.Json.JsonSerializer.Deserialize(jsonString); + } + catch (Exception ex) + { + Log.WriteError("Check Json string: ", ex.ToString()); + } + } + } +} diff --git a/roles/lib/files/FWO.ExternalSystems/ExternalTicketTask.cs b/roles/lib/files/FWO.ExternalSystems/ExternalTicketTask.cs new file mode 100644 index 0000000000..70b07e5c27 --- /dev/null +++ b/roles/lib/files/FWO.ExternalSystems/ExternalTicketTask.cs @@ -0,0 +1,24 @@ +using FWO.Data; +using FWO.Data.Workflow; +using FWO.Data.Modelling; + +namespace FWO.ExternalSystems +{ + public abstract class ExternalTicketTask + { + public readonly WfReqTask ReqTask; + public string TaskText { get; set; } = ""; + public ModellingNamingConvention? NamingConvention { get; set; } + protected List IpProtos; + + + protected ExternalTicketTask(WfReqTask reqTask, List ipProtos, ModellingNamingConvention? namingConvention) + { + ReqTask = reqTask; + IpProtos = ipProtos; + NamingConvention = namingConvention; + } + + public abstract void FillTaskText(ExternalTicketTemplate template); + } +} diff --git a/roles/lib/files/FWO.ExternalSystems/FWO.ExternalSystems.csproj b/roles/lib/files/FWO.ExternalSystems/FWO.ExternalSystems.csproj new file mode 100644 index 0000000000..a5042b9d68 --- /dev/null +++ b/roles/lib/files/FWO.ExternalSystems/FWO.ExternalSystems.csproj @@ -0,0 +1,14 @@ + + + + net10.0 + enable + enable + + + + + + + + diff --git a/roles/lib/files/FWO.ExternalSystems/Tufin.SecureChange/SCAccessRequestTicketTask.cs b/roles/lib/files/FWO.ExternalSystems/Tufin.SecureChange/SCAccessRequestTicketTask.cs new file mode 100644 index 0000000000..bb36f3764e --- /dev/null +++ b/roles/lib/files/FWO.ExternalSystems/Tufin.SecureChange/SCAccessRequestTicketTask.cs @@ -0,0 +1,131 @@ +using FWO.Data; +using FWO.Data.Workflow; +using FWO.Data.Modelling; +using FWO.Basics; + +namespace FWO.ExternalSystems.Tufin.SecureChange +{ + public class SCAccessRequestTicketTask : SCTicketTask + { + public SCAccessRequestTicketTask(WfReqTask reqTask, List ipProtos, ModellingNamingConvention? namingConvention = null) : base(reqTask, ipProtos, namingConvention) + { } + + /// { + /// "order": "@@ORDERNAME@@", + /// "verifier_result": { + /// "status": "not run" + /// }, + /// "use_topology": true, + /// "targets": { + /// "target": { + /// "@type": "ANY" + /// } + /// }, + /// "action": @@ACTION@@, + /// "sources": { + /// "source": @@SOURCES@@ + /// }, + /// "destinations": { + /// "destination": @@DESTINATIONS@@ + /// }, + /// "services": { + /// "service": @@SERVICES@@ + /// }, + /// "labels": "", + /// "comment": "@@TASKCOMMENT@@ + /// } + public override void FillTaskText(ExternalTicketTemplate template) + { + ExtMgtData extMgt = ReqTask.OnManagement != null && ReqTask.OnManagement?.ExtMgtData != null ? + System.Text.Json.JsonSerializer.Deserialize(ReqTask.OnManagement?.ExtMgtData ?? "{}") : new(); + TaskText = template.TasksTemplate + .Replace(Placeholder.ORDERNAME, "AR" + ReqTask.TaskNumber.ToString()) + .Replace(Placeholder.TASKCOMMENT, ReqTask.GetFirstCommentText()) + .Replace(Placeholder.ACTION, MapActionType(ReqTask)) + .Replace(Placeholder.SOURCES, ConvertNetworkElems(template, UseModelled() ? ElemFieldType.modelled_source : ElemFieldType.source, extMgt.ExtName)) + .Replace(Placeholder.DESTINATIONS, ConvertNetworkElems(template, UseModelled() ? ElemFieldType.modelled_destination : ElemFieldType.destination, extMgt.ExtName)) + .Replace(Placeholder.SERVICES, ConvertServiceElems(template)); + } + + private static string MapActionType(WfReqTask reqTask) + { + return reqTask.TaskType switch + { + nameof(WfTaskType.access) => SCActionType.Accept, + nameof(WfTaskType.rule_modify) => SCActionType.Accept, + nameof(WfTaskType.rule_delete) => SCActionType.Remove, + _ => "", + }; + } + + private string ConvertNetworkElems(ExternalTicketTemplate template, ElemFieldType fieldType, string? mgtName) + { + List nwObjects = ReqTask.GetNwObjectElements(fieldType) + .OrderBy(nwObj => ResolveSortName(nwObj), StringComparer.OrdinalIgnoreCase) + .ToList(); + List convertedObjects = []; + foreach (var nwObj in nwObjects) + { + if (nwObj.GroupName != "") + { + if (convertedObjects.FirstOrDefault(o => o == nwObj.GroupName) == null) + { + convertedObjects.Add(FillNwObjGroupTemplate(template, nwObj.GroupName, mgtName ?? "")); + } + } + else + { + convertedObjects.Add(FillIpTemplate(template, nwObj.IpString)); + } + } + return "[" + string.Join(",", convertedObjects) + "]"; + } + + private static string ResolveSortName(NwObjectElement nwObj) + { + if (!string.IsNullOrWhiteSpace(nwObj.GroupName)) + { + return nwObj.GroupName; + } + + if (!string.IsNullOrWhiteSpace(nwObj.Name)) + { + return nwObj.Name; + } + + return nwObj.IpString; + } + + private string ConvertServiceElems(ExternalTicketTemplate template) + { + List nwServiceElements = ReqTask.GetServiceElements(); + List convertedObjects = []; + foreach (var svc in nwServiceElements) + { + if (svc.ProtoId == 1) // ICMP + { + convertedObjects.Add(FillIcmpTemplate(template, svc.Name ?? "")); + } + else if (svc.ProtoId == 6 || svc.ProtoId == 17) // TCP, UDP + { + convertedObjects.Add(FillServiceTemplate(template, IpProtos.FirstOrDefault(x => x.Id == svc.ProtoId)?.Name ?? svc.ProtoId.ToString(), DisplayPortRange(svc.Port, svc.PortEnd), svc.Name ?? "")); + } + else + { + convertedObjects.Add(FillIpProtocolTemplate(template, IpProtos.FirstOrDefault(x => x.Id == svc.ProtoId)?.Name ?? svc.ProtoId.ToString(), svc.ProtoId.ToString(), svc.Name ?? "")); + } + } + return "[" + string.Join(",", convertedObjects) + "]"; + } + + public static string DisplayPortRange(int port, int? portEnd) + { + return portEnd == null || portEnd == 0 || port == portEnd ? $"{port}" : $"{port}-{portEnd}"; + } + + private bool UseModelled() + { + return ReqTask.TaskType == WfTaskType.rule_delete.ToString() && ReqTask.Elements.Where(e => e.Field == ElemFieldType.modelled_source.ToString()).ToList().Count > 0; + } + } +} diff --git a/roles/lib/files/FWO.ExternalSystems/Tufin.SecureChange/SCClient.cs b/roles/lib/files/FWO.ExternalSystems/Tufin.SecureChange/SCClient.cs new file mode 100644 index 0000000000..e75b655e08 --- /dev/null +++ b/roles/lib/files/FWO.ExternalSystems/Tufin.SecureChange/SCClient.cs @@ -0,0 +1,49 @@ +using FWO.Api.Client; +using FWO.Data; +using FWO.Logging; +using RestSharp; +using System.Text; + +namespace FWO.ExternalSystems.Tufin.SecureChange +{ + public class SCClient : RestApiClient + { + readonly ExternalTicketSystem TicketSystem; + + public SCClient(ExternalTicketSystem ticketSystem) : base(ticketSystem.Url, ticketSystem.ResponseTimeout) + { + TicketSystem = ticketSystem; + } + + public virtual async Task> RestCall(RestRequest request, string restEndPoint) + { + request.AddHeader("Content-Type", "application/json"); + request.AddHeader("Authorization", TicketSystem.Authorization); + request.AddHeader("Accept", "application/json"); + + // Debugging SecureChange API call + Log.WriteDebug("API", DebugApiCallText(request, restClient, restEndPoint)); + + // send API call + return await restClient.ExecuteAsync(request); + } + + private static string DebugApiCallText(RestRequest request, RestClient restClient, string restEndPoint) + { + StringBuilder headers = new(); + string body = ""; + foreach (Parameter p in request.Parameters) + { + if (p.Name == "") + { + body = $"data: '{p.Value}'"; + } + else if (p.Name != "Authorization") // avoid logging of credentials + { + headers.AppendLine($"header: '{p.Name}: {p.Value}' "); + } + } + return $"Sending API Call to SecureChange:\nrequest: {request.Method}, base url: {restClient.Options.BaseUrl}, restEndpoint: {restEndPoint}, body: {body}, {headers}"; + } + } +} diff --git a/roles/lib/files/FWO.ExternalSystems/Tufin.SecureChange/SCNetworkObjectModifyTicketTask.cs b/roles/lib/files/FWO.ExternalSystems/Tufin.SecureChange/SCNetworkObjectModifyTicketTask.cs new file mode 100644 index 0000000000..f03f9cfb2f --- /dev/null +++ b/roles/lib/files/FWO.ExternalSystems/Tufin.SecureChange/SCNetworkObjectModifyTicketTask.cs @@ -0,0 +1,45 @@ +using FWO.Basics; +using FWO.Data; +using FWO.Data.Workflow; +using FWO.Data.Modelling; + +namespace FWO.ExternalSystems.Tufin.SecureChange +{ + public class SCNetworkObjectModifyTicketTask : SCTicketTask + { + private readonly string ChangeAction; + public SCNetworkObjectModifyTicketTask(WfReqTask reqTask, string changeAction, List ipProtos, ModellingNamingConvention? namingConvention) : base(reqTask, ipProtos, namingConvention) + { + ChangeAction = changeAction; + } + + /// "task": { + /// "fields": { + /// "field": { + /// "@xsi.type": "multi_group_change", + /// "name": "Modify network object group", + /// "group_change": { + /// "name": "@@GROUPNAME@@", + /// "management_id": @@MANAGEMENT_ID@@, + /// "management_name": "@@MANAGEMENT_NAME@@", + /// "members": { + /// "member": @@MEMBERS@@ + /// }, + /// "change_action": "@@CHANGEACTION@@" + /// } + /// } + /// } + public override void FillTaskText(ExternalTicketTemplate template) + { + ExtMgtData extMgt = ReqTask.OnManagement != null && ReqTask.OnManagement?.ExtMgtData != null ? + System.Text.Json.JsonSerializer.Deserialize(ReqTask.OnManagement?.ExtMgtData ?? "{}") : new(); + bool shortened = false; + TaskText = template.TasksTemplate + .Replace(Placeholder.GROUPNAME, ReqTask.GetAddInfoValue(AdditionalInfoKeys.GrpName).SanitizeJsonFieldMand(ref shortened)) + .Replace(Placeholder.MANAGEMENT_ID, extMgt.ExtId ?? "0") + .Replace(Placeholder.MANAGEMENT_NAME, extMgt.ExtName) + .Replace(Placeholder.CHANGEACTION, ChangeAction) + .Replace(Placeholder.MEMBERS, ConvertNetworkObjects(template, extMgt.ExtId, NamingConvention)); + } + } +} diff --git a/roles/lib/files/FWO.ExternalSystems/Tufin.SecureChange/SCTicket.cs b/roles/lib/files/FWO.ExternalSystems/Tufin.SecureChange/SCTicket.cs new file mode 100644 index 0000000000..a08e75d2f2 --- /dev/null +++ b/roles/lib/files/FWO.ExternalSystems/Tufin.SecureChange/SCTicket.cs @@ -0,0 +1,499 @@ +using FWO.Basics; +using FWO.Basics.Exceptions; +using FWO.Data; +using FWO.Data.Modelling; +using FWO.Data.Workflow; +using FWO.Logging; +using Newtonsoft.Json; +using RestSharp; +using System.Net; +using System.Text.Json.Serialization; + +namespace FWO.ExternalSystems.Tufin.SecureChange +{ + public enum SCTaskType + { + AccessRequest = 0, + NetworkObjectModify = 10, + NetworkServiceCreate = 20, + NetworkServiceUpdate = 21 + } + + public enum SCTicketPriority + { + Low, + Normal, + High, + Critical + } + + public struct SCChangeAction + { + public const string Create = "CREATE"; + public const string Update = "UPDATE"; + } + + public class SCTicket : ExternalTicket + { + public string Subject { get; set; } = ""; + public string Priority { get; set; } = SCTicketPriority.Normal.ToString(); + public string Requester { get; set; } = ""; + readonly private string DefaultReason = "Kommunikationsprofil der Anwendung"; + readonly private string Content = "Content: "; + private string actTicketTemplate; + private SCTaskType actTaskType; + private readonly SCClient SCClient; + + + /// "ticket": { + /// "id": 2, + /// "subject": "Clone Server Policy Ticket", + /// "requester": "a", + /// "requester_id": 12, + /// "priority": "Normal", + /// "status": "In Progress",... + // Todo: move to template settings? + sealed private class SCPollTicketResponseStatus + { + [JsonProperty("status"), JsonPropertyName("status")] + public string Status { get; set; } = ""; + } + + sealed private class SCPollTicketResponse + { + [JsonProperty("ticket"), JsonPropertyName("ticket")] + public SCPollTicketResponseStatus Ticket { get; set; } = new(); + } + + /// "users": { + /// "user": [ + /// { + /// "@xsi.type": "user", + /// "id": 55, + /// "type": "user", + /// "name": "Userxyz", + sealed private class SCLookupUserResponseUser + { + [JsonProperty("id"), JsonPropertyName("id")] + public int Id { get; set; } + } + + sealed private class SCLookupUserResponseUsers + { + [JsonProperty("user"), JsonPropertyName("user")] + public List User { get; set; } = []; + } + + sealed private class SCLookupUsersResponse + { + [JsonProperty("users"), JsonPropertyName("users")] + public SCLookupUserResponseUsers Users { get; set; } = new(); + } + + + public SCTicket(ExternalTicketSystem tufinSystem, SCClient? sCClient = null) + { + if (sCClient != null) + { + SCClient = sCClient; + } + else + { + SCClient = new(tufinSystem); + } + TicketSystem = tufinSystem; + actTicketTemplate = TicketSystem.Templates.FirstOrDefault()?.TicketTemplate ?? ""; + } + + public override async Task CreateRequestString(List tasks, List ipProtos, ModellingNamingConvention? namingConvention) + { + CreateTicketTasks(tasks, ipProtos, namingConvention); + await CreateTicketText(tasks.FirstOrDefault()); + if (TicketText.Contains(GlobalConst.kPlaceholderMarker)) + { + throw new ConfigException("Template error. Unhandled placeholder found."); + } + } + + public override string GetTaskTypeAsString(WfReqTask task) + { + return GetTaskType(task).ToString(); + } + + public override async Task<(string, string?)> GetNewState(string oldState) + { + RestResponse restResponse = await PollExternalTicket(); + if (restResponse.StatusCode == HttpStatusCode.OK && restResponse.Content != null) + { + Log.WriteDebug("Poll external ticket status OK", Content + restResponse.Content); + SCPollTicketResponse? scResponse = System.Text.Json.JsonSerializer.Deserialize(restResponse.Content); + if (scResponse != null) + { + return (GetInternalState(scResponse.Ticket.Status.ToUpper()), restResponse.Content); + } + } + Log.WriteError($"Poll status failed for external ticket {TicketId}.", Content + restResponse.Content + ", Error Message: " + restResponse.ErrorMessage); + throw new ProcessingFailedException(restResponse.ErrorMessage ?? ""); + } + + public override async Task> CreateExternalTicket() + { + string restEndPoint = "tickets.json"; + RestRequest request = new(restEndPoint, Method.Post); + request.AddJsonBody(TicketText); + + // https://192.168.1.1/securechangeworkflow/api/securechange/tickets + return await SCClient.RestCall(request, restEndPoint); + } + + protected override async Task> PollExternalTicket() + { + if (TicketId != null) + { + string restEndPoint = "tickets/" + TicketId; + RestRequest request = new(restEndPoint, Method.Get); + return await SCClient.RestCall(request, restEndPoint); + } + throw new ArgumentException("No Ticket Id given."); + } + + // IN_PROGRESS, REJECTED, CLOSED, CANCELLED, RESOLVED + private static string GetInternalState(string externalState) + { + if (externalState.Contains("REJECTED") || externalState.Contains("CANCELLED")) + { + return ExtStates.ExtReqRejected.ToString(); + } + else if (externalState.Contains("RESOLVED") || externalState.Contains("CLOSED")) + { + return ExtStates.ExtReqDone.ToString(); + } + else + { + return ExtStates.ExtReqInProgress.ToString(); + } + } + + private static (SCTaskType, string) GetTaskType(WfReqTask task) + { + switch (task.TaskType) + { + case nameof(WfTaskType.access): + case nameof(WfTaskType.rule_modify): + case nameof(WfTaskType.rule_delete): + return (SCTaskType.AccessRequest, ""); + case nameof(WfTaskType.group_create): + if (task.IsNetworkFlavor()) + { + return (SCTaskType.NetworkObjectModify, SCChangeAction.Create); + } + else + { + return (SCTaskType.NetworkServiceCreate, SCChangeAction.Create); + } + case nameof(WfTaskType.group_modify): + if (task.IsNetworkFlavor()) + { + return (SCTaskType.NetworkObjectModify, SCChangeAction.Update); + } + else + { + return (SCTaskType.NetworkServiceUpdate, SCChangeAction.Update); + } + default: return (SCTaskType.AccessRequest, ""); + } + } + + private void CreateTicketTasks(List tasks, List ipProtos, ModellingNamingConvention? namingConvention) + { + foreach (var task in tasks) + { + SCTicketTask? ticketTask = null; + string changeAction; + (actTaskType, changeAction) = GetTaskType(task); + switch (actTaskType) + { + case SCTaskType.AccessRequest: + ticketTask = new SCAccessRequestTicketTask(task, ipProtos); + break; + case SCTaskType.NetworkObjectModify: + ticketTask = new SCNetworkObjectModifyTicketTask(task, changeAction, ipProtos, namingConvention); + break; + } + if (ticketTask != null) + { + ExternalTicketTemplate? template = TicketSystem.Templates.FirstOrDefault(t => t.TaskType == actTaskType.ToString()); + if (template == null) + { + throw new ConfigException($"No Template found for task type {actTaskType}."); + } + else + { + ticketTask.FillTaskText(template); + actTicketTemplate = template.TicketTemplate; + } + TicketTasks.Add(ticketTask.TaskText); + } + } + } + + /// "ticket": { + /// "subject": "@@TICKET_SUBJECT@@", + /// "priority": "@@PRIORITY@@", + /// "requester": "@@ONBEHALF@@", + /// "domain_name": "", + /// "workflow": {"name": "Standard Firewall Request"}, + /// "steps": { + /// "step": [ + /// { + /// "name": "Erfassung des Antrags", + /// "tasks": { + /// "task": { + /// "fields": { + /// "field": [ + /// @@TASKS@@ + /// ] + /// }, + /// { + /// "@xsi.type": "text_area", + /// "name": "Grund für den Antrag", + /// "read_only": false, + /// "text": "@@REASON@@" + /// }, + /// { + /// "@xsi.type": "text_field", + /// "name": "Anwendungs-ID", + /// "text": "@@APPID@@" + + private async Task CreateTicketText(WfReqTask? reqTask) + { + string appId = reqTask != null && reqTask.Owners.Count > 0 ? reqTask.Owners[0]?.Owner.ExtAppId ?? "" : ""; + string onBehalf = TicketSystem.LookupRequesterId ? (await LookupRequesterId(Requester)).ToString() : Requester; + TicketText = actTicketTemplate + .Replace(Placeholder.TICKET_SUBJECT, Subject) + .Replace(Placeholder.PRIORITY, Priority) + .Replace(Placeholder.ONBEHALF, onBehalf) + .Replace(Placeholder.REASON, reqTask?.Reason ?? DefaultReason) + .Replace(Placeholder.APPID, appId) + .Replace(Placeholder.TASKS, string.Join(",", TicketTasks)); + bool shortened = false; + TicketText = TicketText.SanitizeEolMand(ref shortened); + CheckForProperJson(TicketText); + } + + private async Task LookupRequesterId(string requesterName) + { + if (!string.IsNullOrEmpty(requesterName)) + { + string restEndPoint = "users.json?user_name=" + requesterName; + RestRequest request = new(restEndPoint, Method.Get); + RestResponse restResponse = await SCClient.RestCall(request, restEndPoint); + if (restResponse.StatusCode == HttpStatusCode.OK && restResponse.Content != null) + { + if (string.IsNullOrWhiteSpace(restResponse.Content)) + { + throw new ProcessingFailedException($"Lookup external requester: User {requesterName} not known in SecureChange - contact Tufin Admin"); + } + Log.WriteDebug("Lookup external requester id OK", Content + restResponse.Content); + SCLookupUsersResponse? scResponse = System.Text.Json.JsonSerializer.Deserialize(restResponse.Content); + if (scResponse != null) + { + return scResponse.Users.User.FirstOrDefault()?.Id ?? 0; + } + } + else + { + throw new ProcessingFailedException($"Lookup external requester id not OK: {Content + restResponse.Content}"); + } + } + return 0; + } + } +} + + +/** + Create Ticket for creating network groups + + parameters: + - management_id: we need to get all management ids from tufin st? + - + + workflow: + - get all management ids (from sc or do we need to access sc as well?) + - loop over all managements + - create group modify ticket with all groups of the app (first: adds only) + - store ticket ids for checking status + - check status and wait for status "closed" + + curl --request POST \ + --insecure \ + --url https://tufin-stest.xxx.de/securechangeworkflow/api/securechange/tickets.json \ + --header 'Authorization: Basic xxx' \ + --header 'Content-Type: application/json' \ + --data '{ + "ticket": { + "subject": "Neue automatische Gruppenerstellung", + "priority": "Normal", + "domain_name": "", + "workflow": { + "name": "Automatische Gruppenerstellung" + }, + "steps": { + "step": [ + { + "name": "Submit Request", + "tasks": { + "task": { + "fields": { + "field": { + "@xsi.type": "multi_group_change", + "name": "Modify network object group", + "group_change": { + "name": "test-group-change-ticket-1", + "management_id": 1, + "management_name": mgmt_name, + "members": { + "member": [] + }, + "change_action": "CREATE" + } + } + } + } + } + } + ] + } + } + }' + + + Create Ticket for access rule + + curl --request POST \ + --insecure \ + --url https://tufin-stest.xxx.de/securechangeworkflow/api/securechange/tickets.json \ + --header 'Authorization: Basic xxx' \ + --header 'Content-Type: application/json' \ + --data '{ + "ticket": { + "subject": "NeMo-Testing", + "priority": "Normal", + "domain_name": "", + "workflow": { + "name": "1. xxx Standard Firewall Request" + }, + "steps": { + "step": [ + { + "name": "Erfassung des Antrags", + "tasks": { + "task": { + "fields": { + "field": [ + { + "@xsi.type": "multi_access_request", + "name": "Gewünschter Zugang", + "read_only": false, + "access_request": { + "order": "AR1", + "verifier_result": { + "status": "not run" + }, + "use_topology": true, + "targets": { + "target": { + "@type": "ANY" + } + }, + "users": { + "user": [ + "Any" + ] + }, + "sources": { + "source": [ + { + "@type": "IP", + "ip_address": "10.10.100.10", + "netmask": "255.255.255.255", + "cidr": 32 + } + ] + }, + "destinations": { + "destination": [ + { + "@type": "IP", + "ip_address": "10.20.200.0", + "netmask": "255.255.255.128", + "cidr": 25 + } + ] + }, + "services": { + "service": [ + { + "@type": "PREDEFINED", + "protocol": "TCP", + "port": 23, + "predefined_name": "telnet" + }, + { + "@type": "PREDEFINED", + "protocol": "TCP", + "port": 79, + "predefined_name": "finger" + }, + { + "@type": "PROTOCOL", + "protocol": "TCP", + "port": 90 + } + ] + }, + "action": "Accept", + "labels": "" + } + }, + { + "@xsi.type": "text_area", + "name": "Grund für den Antrag", + "read_only": false, + "text": "dsadsa" + }, + { + "@xsi.type": "drop_down_list", + "name": "Regel Log aktivieren?", + "selection": "Ja" + }, + { + "@xsi.type": "date", + "name": "Regel befristen bis:" + }, + { + "@xsi.type": "text_field", + "name": "Anwendungs-ID", + "text": "APP-3838" + }, + { + "@xsi.type": "checkbox", + "name": "Die benötigte Kommunikationsverbindung ist im Kommunikationsprofil nach IT-Sicherheitsstandard hinterlegt", + "value": false + }, + { + "@xsi.type": "drop_down_list", + "name": "Expertenmodus: Exakt wie beantragt implementieren (Designervorschlag ignorieren)", + "selection": "Nein" + } + ] + } + } + } + } + ] + } + } + }' +**/ diff --git a/roles/lib/files/FWO.ExternalSystems/Tufin.SecureChange/SCTicketTask.cs b/roles/lib/files/FWO.ExternalSystems/Tufin.SecureChange/SCTicketTask.cs new file mode 100644 index 0000000000..e7f70843ab --- /dev/null +++ b/roles/lib/files/FWO.ExternalSystems/Tufin.SecureChange/SCTicketTask.cs @@ -0,0 +1,229 @@ +using FWO.Data; +using FWO.Data.Workflow; +using FWO.Data.Modelling; +using FWO.Basics; + +namespace FWO.ExternalSystems.Tufin.SecureChange +{ + + public abstract class SCTicketTask : ExternalTicketTask + { + // To use a service object in a new request you must use two parameters to specify the object. The parameter options are: + // 1. Both object_UID and management_id + // 2. Both object_name and management_name + + // To use a network object in a new request you must use two parameters to specify the object. The parameter options are: + // 1. Both object_UID and management_id (for Access Request and Group Change workflow) + // 2. Both object_name and management_name (only for Access Request workflow) + // 3. Both object_name and management_id (only for Group Change workflow) + // **Note: If both object_UID and object_name are defined, object_UID takes precedence over object_name + + // * Network object types: + // SecureTrack API element includes one of the following types: + // gateway_ckp, host_ckp, connectra, interspect, gateway_cluster, cluster_member, + // sofaware_gateway, sofaware_gateway_profile, vsx_box, vs_cluster_member, vs_cluster_netobj, + // vsx_cluster_member, vsx_cluster_netobj, vs_netobj, mygw_EVR, vsx_netobj, embedded_device, + // host_plain, interface, network, network_object_group, group_with_exception, gsn_handover_group, address_range + + // Service object types: + // SecureTrack API element includes one of the following types: + // icmp_service, service_group, sctp_service, other_service, tcp_service, udp_service + + // @type (string, optional): The data type, in cases where object_updated_status is EXISTING_NOT_EDITED or EXISTING_EDITED, use type="Object", + // protected enum MemberTypes + // ANY, + // IP, + // DNS, + // Object, // Device's existing object + // INTERNET, + // LDAP, + // host, // ?? not in swagger + // network // ?? not in swagger + + protected enum SCStatusValue + { + NOT_CHANGED, + ADDED, + DELETED + } + + protected enum SCObjStatusValue + { + EXISTING_NOT_EDITED, + EXISTING_EDITED, + NEW + } + + protected struct SCObjectType + { + public const string Host = "host"; + public const string Network = "network"; + public const string Range = "range"; + } + + protected struct SCActionType + { + public const string Accept = "accept"; + public const string Remove = "remove"; + } + + protected struct SCObjectInfo + { + public string Name { get; set; } + public string Type { get; set; } + public string Details { get; set; } + public string Comment { get; set; } + public string Status { get; set; } + public string UpdateStatus { get; set; } + } + + protected SCTicketTask(WfReqTask reqTask, List ipProtos, ModellingNamingConvention? namingConvention) : base(reqTask, ipProtos, namingConvention) + { } + + /// { + /// "@type": "Object", + /// "name": "xyz1234.xxx.de", + /// "object_type": "host", + /// "object_details": "1.2.3.4/32", + /// "management_id": 1, + /// "status": "ADDED", + /// "comment": "", + /// "object_updated_status": "EXISTING_NOT_EDITED" + /// } + protected static string FillObjectTemplate(ExternalTicketTemplate template, string type, SCObjectInfo objInfo, string mgmId) + { + bool shortened = false; + return template.ObjectTemplate + .Replace(Placeholder.TYPE, type) + .Replace(Placeholder.OBJECTNAME, objInfo.Name.SanitizeJsonFieldMand(ref shortened)) + .Replace(Placeholder.OBJECT_TYPE, objInfo.Type) + .Replace(Placeholder.OBJECT_DETAILS, objInfo.Details) + .Replace(Placeholder.COMMENT, objInfo.Comment) + .Replace(Placeholder.STATUS, objInfo.Status) + .Replace(Placeholder.OBJUPDSTATUS, objInfo.UpdateStatus) + .Replace(Placeholder.MANAGEMENT_ID, mgmId); + } + + /// { + /// "@type": "Object", + /// "name": "ip_1.2.3.4", + /// "management_id": 1, + /// "status": "NOT_CHANGED", + /// "object_updated_status": "EXISTING_NOT_EDITED" + //// } + protected static string FillObjectTemplateShort(ExternalTicketTemplate template, string objName, string status, string objUpdStatus, string mgmId) + { + bool shortened = false; + return template.ObjectTemplateShort + .Replace(Placeholder.OBJECTNAME, objName.SanitizeJsonFieldMand(ref shortened)) + .Replace(Placeholder.STATUS, status) + .Replace(Placeholder.OBJUPDSTATUS, objUpdStatus) + .Replace(Placeholder.MANAGEMENT_ID, mgmId); + } + + protected static string FillIpTemplate(ExternalTicketTemplate template, string ipString) + { + return template.IpTemplate.Replace(Placeholder.IP, ipString); + } + + protected static string FillServiceTemplate(ExternalTicketTemplate template, string protocolName, string port, string serviceName) + { + return template.ServiceTemplate.Replace(Placeholder.PROTOCOLNAME, protocolName).Replace(Placeholder.PORT, port).Replace(Placeholder.SERVICENAME, serviceName); + } + + protected static string FillIcmpTemplate(ExternalTicketTemplate template, string serviceName) + { + return template.IcmpTemplate.Replace(Placeholder.SERVICENAME, serviceName); + } + + protected static string FillIpProtocolTemplate(ExternalTicketTemplate template, string protocolName, string protocolId, string serviceName) + { + return template.IpProtocolTemplate.Replace(Placeholder.PROTOCOLNAME, protocolName).Replace(Placeholder.PROTOCOLID, protocolId).Replace(Placeholder.SERVICENAME, serviceName); + } + + protected static string FillNwObjGroupTemplate(ExternalTicketTemplate template, string groupName, string mgtName) + { + return template.NwObjGroupTemplate.Replace(Placeholder.GROUPNAME, groupName).Replace(Placeholder.MANAGEMENT_NAME, mgtName); + } + + protected string ConvertNetworkObjects(ExternalTicketTemplate template, string? mgmId, ModellingNamingConvention? namingConvention) + { + List nwObjects = ReqTask.GetNwObjectElements(ElemFieldType.source); + List convertedObjects = []; + foreach (var nwObj in nwObjects) + { + if (nwObj.RequestAction == RequestAction.create.ToString() || nwObj.RequestAction == RequestAction.addAfterCreation.ToString()) + { + string scObjType = GetSCObjectType(IpOperations.GetObjectType(nwObj.IpString, nwObj.IpEndString)); + string objUpdStatus = ObjUpdStatus(nwObj.RequestAction); + convertedObjects.Add(FillObjectTemplate(template, + objUpdStatus == SCObjStatusValue.NEW.ToString() ? scObjType : "Object", + new() + { + Name = ConstructObjectName(nwObj, namingConvention), + Type = scObjType, + Details = ConstructObjectIp(nwObj, scObjType), + Comment = nwObj.Comment ?? "", + Status = ObjStatus(nwObj.RequestAction), + UpdateStatus = objUpdStatus + }, + mgmId ?? "0")); + } + else + { + convertedObjects.Add(FillObjectTemplateShort(template, ConstructObjectName(nwObj, namingConvention), + ObjStatus(nwObj.RequestAction), ObjUpdStatus(nwObj.RequestAction), mgmId ?? "0")); + } + } + return "[" + string.Join(",", convertedObjects) + "]"; + } + + private static string ConstructObjectName(NwObjectElement nwObj, ModellingNamingConvention? namingConvention) + { + // shouldn't be necessary here anymore? + if (string.IsNullOrEmpty(nwObj.Name)) + { + return namingConvention?.AppServerPrefix + DisplayBase.DisplayIp(nwObj.IpString, nwObj.IpEndString); + } + return char.IsLetter(nwObj.Name[0]) ? nwObj.Name : namingConvention?.AppServerPrefix + nwObj.Name; + } + + private static string ConstructObjectIp(NwObjectElement nwObj, string scObjType) + { + return scObjType switch + { + SCObjectType.Network => IpOperations.ToDotNotation(nwObj.IpString, nwObj.IpEndString), + SCObjectType.Range => $"{nwObj.IpString}-{nwObj.IpEndString}",// TODO: not really implemented yet + _ => nwObj.IpString, // single host + }; + } + + private static string GetSCObjectType(string fwoObjType) + { + return fwoObjType switch + { + ObjectType.Host => SCObjectType.Host.ToString(), + ObjectType.Network => SCObjectType.Network.ToString(), + ObjectType.IPRange => SCObjectType.Range.ToString(), // ??? Todo + _ => "", + }; + } + + private static string ObjStatus(string action) + { + return action switch + { + nameof(RequestAction.create) => SCStatusValue.ADDED.ToString(), + nameof(RequestAction.addAfterCreation) => SCStatusValue.ADDED.ToString(), + nameof(RequestAction.delete) => SCStatusValue.DELETED.ToString(), + nameof(RequestAction.unchanged) => SCStatusValue.NOT_CHANGED.ToString(), + _ => "", + }; + } + + private static string ObjUpdStatus(string action) + { + return action == nameof(RequestAction.create) ? SCObjStatusValue.NEW.ToString() : SCObjStatusValue.EXISTING_NOT_EDITED.ToString(); + } + } +} diff --git a/roles/lib/files/FWO.Logging/FWO.Logging.csproj b/roles/lib/files/FWO.Logging/FWO.Logging.csproj index 0da2a6f35b..48bff95a68 100644 --- a/roles/lib/files/FWO.Logging/FWO.Logging.csproj +++ b/roles/lib/files/FWO.Logging/FWO.Logging.csproj @@ -1,7 +1,12 @@ + + + + + - net6.0 + net10.0 enable enable diff --git a/roles/lib/files/FWO.Logging/Log.cs b/roles/lib/files/FWO.Logging/Log.cs index 16fc7da667..385accd83a 100644 --- a/roles/lib/files/FWO.Logging/Log.cs +++ b/roles/lib/files/FWO.Logging/Log.cs @@ -1,14 +1,18 @@ -using System.Diagnostics; +using System.Diagnostics; using System.Reflection; using System.Runtime.CompilerServices; +using System.Globalization; +using System.Text; +using FWO.Basics; +using FWO.Basics.Interfaces; namespace FWO.Logging { public static class Log { - private static SemaphoreSlim semaphore = new SemaphoreSlim(1, 1); - private static string lockFilePath = $"/var/fworch/lock/{Assembly.GetEntryAssembly()?.GetName().Name}_log.lock"; - private static Random random = new Random(); + private static SemaphoreSlim semaphore = new(1, 1); + private static readonly string lockFilePath = $"/var/fworch/lock/{Assembly.GetEntryAssembly()?.GetName().Name}_log.lock"; + private static readonly Random random = new(); static Log() { @@ -16,7 +20,7 @@ static Log() { // log switch - log file locking bool logOwnedByExternal = false; - Stopwatch stopwatch = new Stopwatch(); + Stopwatch stopwatch = new(); while (true) { @@ -25,13 +29,13 @@ static Log() // Open file using FileStream file = await GetFile(lockFilePath); // Read file content - using StreamReader reader = new StreamReader(file); + using StreamReader reader = new(file); string lockFileContent = (await reader.ReadToEndAsync()).Trim(); // Forcefully release lock after timeout if (logOwnedByExternal && stopwatch.ElapsedMilliseconds > 10_000) { - using StreamWriter writer = new StreamWriter(file); + using StreamWriter writer = new(file); await writer.WriteLineAsync("FORCEFULLY RELEASED"); stopwatch.Reset(); semaphore.Release(); @@ -59,14 +63,14 @@ static Log() stopwatch.Restart(); logOwnedByExternal = true; } - using StreamWriter writer = new StreamWriter(file); + using StreamWriter writer = new(file); await writer.WriteLineAsync("GRANTED"); } // RELEASED - lock was released by log swap process else if (lockFileContent.EndsWith("RELEASED")) { // only release lock if it was formerly requested by us - if (logOwnedByExternal) + if (logOwnedByExternal) { stopwatch.Reset(); semaphore.Release(); @@ -91,8 +95,8 @@ private static async Task GetFile(string path) { return File.Open(path, FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.None); } - catch (Exception) - { + catch (Exception) + { //WriteDebug("Log file locking", $"Could not access log lock file: {e.Message}."); } await Task.Delay(random.Next(100)); @@ -128,7 +132,6 @@ public static void WriteError(string Title, string? Text = null, Exception? Erro $"Stack Trace: \n {Error?.StackTrace?.TrimStart()}" : ""); - WriteLog("Error", Title, DisplayText, callerName, callerFile, callerLineNumber, ConsoleColor.Red); } @@ -146,8 +149,55 @@ public static void WriteError(string Title, string Text, bool LogStackTrace, [Ca WriteLog("Error", Title, DisplayText, callerName, callerFile, callerLineNumber, ConsoleColor.Red); } - public static void WriteAudit(string Title, string Text, [CallerMemberName] string callerName = "", [CallerFilePath] string callerFile = "", [CallerLineNumber] int callerLineNumber = 0) + /// + /// Writes an audit log entry with the specified title and text. + /// Optionally appends a separator line to the log entry. + /// + /// The title of the audit log entry. + /// The content of the audit log entry. + /// Whether to append a separator line to the log entry. Default is true. + /// The name of the calling method (automatically supplied). + /// The file path of the calling method (automatically supplied). + /// The line number in the source file at which the method is called (automatically supplied). + public static void WriteAudit(string Title, string Text, bool WithSeparatorLine = true, [CallerMemberName] string callerName = "", [CallerFilePath] string callerFile = "", [CallerLineNumber] int callerLineNumber = 0) { + if (WithSeparatorLine) + { + Text += $"{Environment.NewLine}----{Environment.NewLine}"; + } + + WriteLog("Audit", Title, Text, callerName, callerFile, callerLineNumber, ConsoleColor.Yellow); + } + + /// + /// Writes an audit log entry with the specified title, text, user name, and user distinguished name (DN). + /// Optionally appends a separator line to the log entry. + /// + /// The title of the audit log entry. + /// The content of the audit log entry. + /// The name of the user performing the action. + /// The distinguished name (DN) of the user. + /// Whether to append a separator line to the log entry. Default is true. + /// The name of the calling method (automatically supplied). + /// The file path of the calling method (automatically supplied). + /// The line number in the source file at which the method is called (automatically supplied). + public static void WriteAudit(string Title, string Text, string UserName, string UserDN, bool WithSeparatorLine = true, [CallerMemberName] string callerName = "", [CallerFilePath] string callerFile = "", [CallerLineNumber] int callerLineNumber = 0) + { + if (!string.IsNullOrEmpty(UserName)) + { + Text += $" by User: {UserName}"; + } + + if (!string.IsNullOrEmpty(UserDN)) + { + Text += $" (DN: {UserDN})"; + } + + if (WithSeparatorLine) + { + Text += $"{Environment.NewLine}----{Environment.NewLine}"; + } + WriteLog("Audit", Title, Text, callerName, callerFile, callerLineNumber, ConsoleColor.Yellow); } @@ -170,9 +220,75 @@ private static void WriteInColor(string Text, ConsoleColor? ForegroundColor = nu Console.ForegroundColor = (ConsoleColor)ForegroundColor; if (BackgroundColor != null) Console.BackgroundColor = (ConsoleColor)BackgroundColor; - Console.Out.WriteLine(Text); // TODO: async method ? + Console.Out.WriteLine(SanitizeForLogOutput(Text)); // TODO: async method ? Console.ResetColor(); semaphore.Release(); } + + /// + /// Preserves meaningful punctuation in log messages while removing invisible control + /// and format characters that can break parsing or obfuscate terminal output. + /// + private static string SanitizeForLogOutput(string text) + { + StringBuilder sanitizedText = new(text.Length); + bool previousCharacterWasSpace = false; + + foreach (char currentCharacter in text) + { + if (char.IsWhiteSpace(currentCharacter) && currentCharacter != ' ') + { + if (!previousCharacterWasSpace) + { + sanitizedText.Append(' '); + previousCharacterWasSpace = true; + } + } + else if (IsVisibleLogCharacter(currentCharacter)) + { + sanitizedText.Append(currentCharacter); + previousCharacterWasSpace = currentCharacter == ' '; + } + } + + return sanitizedText.ToString().Trim(); + } + + private static bool IsVisibleLogCharacter(char currentCharacter) + { + UnicodeCategory characterCategory = char.GetUnicodeCategory(currentCharacter); + return characterCategory != UnicodeCategory.Control + && characterCategory != UnicodeCategory.Format + && characterCategory != UnicodeCategory.LineSeparator + && characterCategory != UnicodeCategory.ParagraphSeparator + && characterCategory != UnicodeCategory.Surrogate + && characterCategory != UnicodeCategory.PrivateUse + && characterCategory != UnicodeCategory.OtherNotAssigned; + } + + public static void TryWriteLog(LogType logType, string title, string text, bool condition) + { + if (condition) + { + switch (logType) + { + case LogType.Debug: + WriteDebug(title, text); + break; + case LogType.Info: + WriteInfo(title, text); + break; + case LogType.Warning: + WriteWarning(title, text); + break; + case LogType.Error: + WriteError(title, text); + break; + case LogType.Audit: + WriteAudit(title, text); + break; + } + } + } } } diff --git a/roles/lib/files/FWO.Logging/LogType.cs b/roles/lib/files/FWO.Logging/LogType.cs new file mode 100644 index 0000000000..fa719195ac --- /dev/null +++ b/roles/lib/files/FWO.Logging/LogType.cs @@ -0,0 +1,11 @@ +namespace FWO.Logging +{ + public enum LogType + { + Debug, + Info, + Warning, + Error, + Audit + } +} diff --git a/roles/lib/files/FWO.Logging/Logger.cs b/roles/lib/files/FWO.Logging/Logger.cs new file mode 100644 index 0000000000..5a088cb048 --- /dev/null +++ b/roles/lib/files/FWO.Logging/Logger.cs @@ -0,0 +1,55 @@ +using FWO.Basics.Interfaces; + +namespace FWO.Logging +{ + public class Logger : ILogger + { + public void TryWriteInfo(string title, string text, bool condition) + { + if (condition) + { + Log.WriteInfo(title, text); + } + } + + public void TryWriteDebug(string title, string text, bool condition) + { + if (condition) + { + Log.WriteDebug(title, text); + } + } + + public void TryWriteWarning(string title, string text, bool condition) + { + if (condition) + { + Log.WriteWarning(title, text); + } + } + + public void TryWriteError(string title, string text, bool condition) + { + if (condition) + { + Log.WriteError(title, text); + } + } + + public void TryWriteError(string title, Exception exception, bool condition) + { + if (condition) + { + Log.WriteError(title, Error: exception); + } + } + + public void TryWriteAudit(string title, string text, bool condition) + { + if (condition) + { + Log.WriteAudit(title, text); + } + } + } +} diff --git a/roles/lib/files/FWO.Mail/EmailConnection.cs b/roles/lib/files/FWO.Mail/EmailConnection.cs index e0a691a8d2..93403e45ee 100644 --- a/roles/lib/files/FWO.Mail/EmailConnection.cs +++ b/roles/lib/files/FWO.Mail/EmailConnection.cs @@ -18,11 +18,11 @@ public class EmailConnection public string? SenderEmailAddress { get; set; } public EmailConnection() - {} + { } public EmailConnection(string address, int port, EmailEncryptionMethod encryption, string user, string password, string senderAddress) { ServerAddress = address; - Port= port; + Port = port; Encryption = encryption; User = user; Password = password; diff --git a/roles/lib/files/FWO.Mail/EmailForm.cs b/roles/lib/files/FWO.Mail/EmailForm.cs index 826f6d5447..ccef0e0a44 100644 --- a/roles/lib/files/FWO.Mail/EmailForm.cs +++ b/roles/lib/files/FWO.Mail/EmailForm.cs @@ -17,4 +17,4 @@ public class EmailForm public string? EmailSenderAddress { get; set; } } -} \ No newline at end of file +} diff --git a/roles/lib/files/FWO.Mail/FWO.Mail.csproj b/roles/lib/files/FWO.Mail/FWO.Mail.csproj index d18254d79f..fa52e4176e 100644 --- a/roles/lib/files/FWO.Mail/FWO.Mail.csproj +++ b/roles/lib/files/FWO.Mail/FWO.Mail.csproj @@ -1,14 +1,19 @@ - net6.0 + net10.0 enable enable - - + + + + + + + diff --git a/roles/lib/files/FWO.Mail/MailerMailKit.cs b/roles/lib/files/FWO.Mail/MailerMailKit.cs index ac5f5852d3..4f06245e1c 100644 --- a/roles/lib/files/FWO.Mail/MailerMailKit.cs +++ b/roles/lib/files/FWO.Mail/MailerMailKit.cs @@ -3,58 +3,34 @@ using MailKit.Net.Smtp; using MailKit.Security; using MimeKit; +using Microsoft.AspNetCore.Http; +using FWO.Encryption; namespace FWO.Mail { - public class MailData + public class MailData(List to, string subject) { // Receiver - public List To { get; } - public List Bcc { get; } + public List To { get; } = to; + public List Bcc { get; set; } = []; - public List Cc { get; } + public List Cc { get; set; } = []; // Sender - public string? From { get; } + public string? From { get; set; } - public string? DisplayName { get; } + public string? DisplayName { get; set; } - public string? ReplyTo { get; } + public string? ReplyTo { get; set; } - public string? ReplyToName { get; } + public string? ReplyToName { get; set; } // Content - public string Subject { get; } - - public string? Body { get; } - - public MailData( - List to, - string subject, - string? body = null, - string? from = null, - string? displayName = null, - string? replyTo = null, - string? replyToName = null, - List? bcc = null, - List? cc = null - ) - { - // Receiver - To = to; - Bcc = bcc ?? new List(); - Cc = cc ?? new List(); + public string Subject { get; } = subject; - // Sender - From = from; - DisplayName = displayName; - ReplyTo = replyTo; - ReplyToName = replyToName; - - // Content - Subject = subject; - Body = body; - } + public string? Body { get; set; } + + public IFormFileCollection? Attachments { get; set; } } public interface IMailService @@ -62,81 +38,20 @@ public interface IMailService Task SendAsync(MailData mailData, EmailConnection emailConn, CancellationToken ct); } - public class MailKitMailer + public static class MailKitMailer { - private EmailConnection EmailConn; - - public MailKitMailer(EmailConnection emailConn) - { - EmailConn = emailConn; - } - - public async Task SendAsync( + public static async Task SendAsync( MailData mailData, EmailConnection emailConn, - CancellationToken ct = default, - bool mailFormatHtml = false + bool mailFormatHtml = false, + CancellationToken ct = default ) { try { - // Initialize a new instance of the MimeKit.MimeMessage class var mail = new MimeMessage(); - string senderString = ""; - if (emailConn.SenderEmailAddress != null) - { - senderString = emailConn.SenderEmailAddress; - } - - #region Sender / Receiver - // Sender - mail.From.Add(new MailboxAddress(senderString, senderString)); - mail.Sender = new MailboxAddress(senderString, senderString); - - // Receiver - foreach (string mailAddress in mailData.To) - mail.To.Add(MailboxAddress.Parse(mailAddress)); - - // Set Reply to if specified in mail data - if (!string.IsNullOrEmpty(mailData.ReplyTo)) - mail.ReplyTo.Add(new MailboxAddress(mailData.ReplyToName, mailData.ReplyTo)); - - // BCC - // Check if a BCC was supplied in the request - if (mailData.Bcc != null) - { - // Get only addresses where value is not null or with whitespace. x = value of address - foreach ( - string mailAddress in mailData.Bcc.Where(x => !string.IsNullOrWhiteSpace(x)) - ) - mail.Bcc.Add(MailboxAddress.Parse(mailAddress.Trim())); - } - - // CC - // Check if a CC address was supplied in the request - if (mailData.Cc != null) - { - foreach ( - string mailAddress in mailData.Cc.Where(x => !string.IsNullOrWhiteSpace(x)) - ) - mail.Cc.Add(MailboxAddress.Parse(mailAddress.Trim())); - } - #endregion - - #region Content - - // Add Content to Mime Message - var body = new BodyBuilder(); - mail.Subject = mailData.Subject; - if (mailFormatHtml) - body.HtmlBody = mailData.Body; - else - body.TextBody = mailData.Body; - mail.Body = body.ToMessageBody(); - - #endregion - - #region Send Mail + AddRecipients(emailConn, mailData, mail); + await AddContent(mailData, mail, mailFormatHtml); using var smtp = new SmtpClient(); smtp.Timeout = 5000; @@ -172,13 +87,11 @@ await smtp.ConnectAsync( } if (emailConn.User != null && emailConn.User != "") { - await smtp.AuthenticateAsync(emailConn.User, emailConn.Password, ct); + await smtp.AuthenticateAsync(emailConn.User, AesEnc.TryDecrypt(emailConn.Password ?? "", true), ct); } await smtp.SendAsync(mail, ct); await smtp.DisconnectAsync(true, ct); - #endregion - return true; } catch (Exception) @@ -186,5 +99,94 @@ await smtp.ConnectAsync( return false; } } + + private static void AddRecipients(EmailConnection emailConn, MailData mailData, MimeMessage mail) + { + string senderString = ""; + if (emailConn.SenderEmailAddress != null) + { + senderString = emailConn.SenderEmailAddress; + } + + // Sender + mail.From.Add(new MailboxAddress(senderString, senderString)); + mail.Sender = new MailboxAddress(senderString, senderString); + + // Receiver + foreach (string mailAddress in mailData.To.Where(x => !string.IsNullOrWhiteSpace(x))) + { + mail.To.Add(MailboxAddress.Parse(mailAddress)); + } + + // Set Reply to if specified in mail data + if (!string.IsNullOrEmpty(mailData.ReplyTo)) + { + mail.ReplyTo.Add(new MailboxAddress(mailData.ReplyToName, mailData.ReplyTo)); + } + + // BCC + // Check if a BCC was supplied in the request + if (mailData.Bcc != null) + { + // Get only addresses where value is not null or with whitespace. x = value of address + foreach (string mailAddress in mailData.Bcc.Where(x => !string.IsNullOrWhiteSpace(x))) + { + mail.Bcc.Add(MailboxAddress.Parse(mailAddress.Trim())); + } + } + + // CC + // Check if a CC address was supplied in the request + if (mailData.Cc != null) + { + foreach (string mailAddress in mailData.Cc.Where(x => !string.IsNullOrWhiteSpace(x))) + { + mail.Cc.Add(MailboxAddress.Parse(mailAddress.Trim())); + } + } + } + + private static async Task AddContent(MailData mailData, MimeMessage mail, bool mailFormatHtml) + { + var body = new BodyBuilder(); + mail.Subject = mailData.Subject; + if (mailFormatHtml) + { + body.HtmlBody = mailData.Body; + } + else + { + body.TextBody = mailData.Body; + + // Check if we got any attachments and add the to the builder for our message + await AddAttachments(mailData, body); + } + mail.Body = body.ToMessageBody(); // correction compared to source code + } + + private static async Task AddAttachments(MailData mailData, MimeKit.BodyBuilder body) + { + if (mailData.Attachments != null) + { + byte[] attachmentFileByteArray; + + foreach (IFormFile attachment in mailData.Attachments) + { + // Check if length of the file in bytes is larger than 0 + if (attachment.Length > 0) + { + // Create a new memory stream and attach attachment to mail body + using (MemoryStream memoryStream = new()) + { + // Copy the attachment to the stream + await attachment.CopyToAsync(memoryStream); + attachmentFileByteArray = memoryStream.ToArray(); + } + // Add the attachment from the byte array + body.Attachments.Add(attachment.FileName, attachmentFileByteArray, ContentType.Parse(attachment.ContentType)); + } + } + } + } } } diff --git a/roles/lib/files/FWO.Middleware.Client/FWO.Middleware.Client.csproj b/roles/lib/files/FWO.Middleware.Client/FWO.Middleware.Client.csproj index 6d261e2f88..8e41cf2cb2 100644 --- a/roles/lib/files/FWO.Middleware.Client/FWO.Middleware.Client.csproj +++ b/roles/lib/files/FWO.Middleware.Client/FWO.Middleware.Client.csproj @@ -1,20 +1,13 @@  - net6.0 + net10.0 enable enable - - - - - - - - + diff --git a/roles/lib/files/FWO.Middleware.Client/JwtReader.cs b/roles/lib/files/FWO.Middleware.Client/JwtReader.cs index c3d9b52520..725ed62582 100644 --- a/roles/lib/files/FWO.Middleware.Client/JwtReader.cs +++ b/roles/lib/files/FWO.Middleware.Client/JwtReader.cs @@ -1,20 +1,20 @@ -using System; -using System.IdentityModel.Tokens.Jwt; -using Microsoft.IdentityModel.Tokens; -using System.IO; -using System.Linq; -using System.Security.Claims; using FWO.Config.File; using FWO.Logging; +using Microsoft.IdentityModel.JsonWebTokens; +using Microsoft.IdentityModel.Tokens; +using System.Security.Claims; namespace FWO.Middleware.Client { public class JwtReader { private readonly string jwtString; - private JwtSecurityToken? jwt; + private JsonWebToken? jwt; private readonly RsaSecurityKey jwtPublicKey; + private readonly string JwtValidation = "Jwt Validation"; + private readonly string JwtNotValidated = "Jwt was not validated yet."; + public JwtReader(string jwtString) { @@ -22,41 +22,40 @@ public JwtReader(string jwtString) this.jwtString = jwtString; // Get public key from config lib - ConfigFile config = new ConfigFile(); - jwtPublicKey = ConfigFile.JwtPublicKey ?? throw new Exception("Jwt public key could not be read form config file."); + jwtPublicKey = ConfigFile.JwtPublicKey ?? throw new ArgumentException("Jwt public key could not be read form config file."); } - /// - /// Checks if JWT in HTTP header contains role. - /// + /// + /// Checks if JWT in HTTP header contains role. + /// /// Role name to check. - /// True if JWT contains specified role, otherwise false. - public bool ContainsRole(string roleName) + /// True if JWT contains specified role, otherwise false. + public bool ContainsRole(string roleName) { - Log.WriteDebug($"{roleName} Role Jwt", "Checking Jwt for admin role."); + Log.WriteDebug($"{roleName} Role Jwt", "Checking Jwt for admin role."); - if (jwt == null) - throw new ArgumentNullException(nameof(jwt), "Jwt was not validated yet."); + if (jwt == null) + throw new ArgumentException(nameof(jwt), JwtNotValidated); - return jwt.Claims.FirstOrDefault(claim => claim.Type == "role" && claim.Value == roleName) != null; - } + return jwt.Claims.FirstOrDefault(claim => claim.Type == "role" && claim.Value == roleName) != null; + } - /// - /// Checks if JWT in HTTP header contains role in x-hasura-allowed-roles. - /// + /// + /// Checks if JWT in HTTP header contains role in x-hasura-allowed-roles. + /// /// Role name to check. - /// True if JWT contains specified role in x-hasura-allowed-roles, otherwise false. - public bool ContainsAllowedRole(string roleName) + /// True if JWT contains specified role in x-hasura-allowed-roles, otherwise false. + public bool ContainsAllowedRole(string roleName) { - Log.WriteDebug($"{roleName} Role Jwt", "Checking Jwt for allowed role."); + Log.WriteDebug($"{roleName} Role Jwt", "Checking Jwt for allowed role."); - if (jwt == null) - throw new ArgumentNullException(nameof(jwt), "Jwt was not validated yet."); + if (jwt == null) + throw new ArgumentException(nameof(jwt), JwtNotValidated); - return jwt.Claims.FirstOrDefault(claim => claim.Type == "x-hasura-allowed-roles" && claim.Value == roleName) != null; - } + return jwt.Claims.FirstOrDefault(claim => claim.Type == "x-hasura-allowed-roles" && claim.Value == roleName) != null; + } - public bool Validate() + public async Task Validate() { try { @@ -64,44 +63,48 @@ public bool Validate() { RequireExpirationTime = true, RequireSignedTokens = true, + ValidateLifetime = true, ValidateAudience = true, + ValidAudiences = [FWO.Basics.JwtConstants.Audience], ValidateIssuer = true, - ValidateLifetime = true, - ValidAudience = JwtConstants.Audience, - ValidIssuer = JwtConstants.Issuer, - IssuerSigningKey = jwtPublicKey + ValidIssuer = FWO.Basics.JwtConstants.Issuer, + IssuerSigningKey = jwtPublicKey, }; - JwtSecurityTokenHandler handler = new JwtSecurityTokenHandler(); - handler.ValidateToken(jwtString, validationParameters, out SecurityToken validatedSecurityToken); - jwt = (JwtSecurityToken)validatedSecurityToken; - Log.WriteDebug("Jwt Validation", "Jwt was successfully validated."); - return true; + JsonWebTokenHandler handler = new(); + TokenValidationResult tokenValidationResult = await handler.ValidateTokenAsync(jwtString, validationParameters); + if (tokenValidationResult.IsValid) + { + jwt = tokenValidationResult.SecurityToken as JsonWebToken; + Log.WriteDebug(JwtValidation, "Jwt was successfully validated."); + return true; + } + return false; } catch (SecurityTokenExpiredException) { - Log.WriteDebug("Jwt Validation", "Jwt lifetime expired."); + Log.WriteDebug(JwtValidation, "Jwt lifetime expired: {jwtString}."); return false; } catch (SecurityTokenInvalidSignatureException InvalidSignatureException) { - Log.WriteError("Jwt Validation", $"Jwt signature could not be verified. Potential attack!", InvalidSignatureException); + Log.WriteError(JwtValidation, $"Jwt signature could not be verified. Potential attack: {jwtString}.", InvalidSignatureException); return false; } catch (SecurityTokenInvalidAudienceException InvalidAudienceException) { - Log.WriteError("Jwt Validation", $"Jwt audience incorrect.", InvalidAudienceException); + Log.WriteError(JwtValidation, $"Jwt audience incorrect: {jwtString}.", InvalidAudienceException); return false; } catch (SecurityTokenInvalidIssuerException InvalidIssuerException) { - Log.WriteError("Jwt Validation", $"Jwt issuer incorrect.", InvalidIssuerException); + Log.WriteError(JwtValidation, $"Jwt issuer incorrect: {jwtString}.", InvalidIssuerException); return false; } catch (Exception UnexpectedError) { - Log.WriteError("Jwt Validation", $"Unexpected problem while trying to verify Jwt", UnexpectedError); + Log.WriteError(JwtValidation, $"Unexpected problem while trying to verify Jwt: {jwtString}.", UnexpectedError); return false; } } @@ -110,7 +113,7 @@ public Claim[] GetClaims() { Log.WriteDebug("Claims Jwt", "Reading claims from Jwt."); if (jwt == null) - throw new ArgumentNullException(nameof(jwt), "Jwt was not validated yet."); + throw new ArgumentException(nameof(jwt), JwtNotValidated); return jwt.Claims.ToArray(); } @@ -118,7 +121,7 @@ public Claim[] GetClaims() public TimeSpan TimeUntilExpiry() { if (jwt == null) - throw new ArgumentNullException(nameof(jwt), "Jwt was not validated yet."); + throw new ArgumentException(nameof(jwt), JwtNotValidated); return jwt.ValidTo - DateTime.UtcNow; } @@ -126,7 +129,7 @@ public TimeSpan TimeUntilExpiry() public string GetRole() { if (jwt == null) - throw new ArgumentNullException(nameof(jwt), "Jwt was not validated yet."); + throw new ArgumentException(nameof(jwt), JwtNotValidated); return jwt.Claims.FirstOrDefault(claim => claim.Type == "role")?.Value ?? ""; } } diff --git a/roles/lib/files/FWO.Middleware.Client/MiddlewareClient.cs b/roles/lib/files/FWO.Middleware.Client/MiddlewareClient.cs index 08ed76d5c5..7d921467c9 100644 --- a/roles/lib/files/FWO.Middleware.Client/MiddlewareClient.cs +++ b/roles/lib/files/FWO.Middleware.Client/MiddlewareClient.cs @@ -1,248 +1,291 @@ -using RestSharp; -using FWO.Middleware.RequestParameters; -using RestSharp.Authenticators; -using RestSharp.Serializers.SystemTextJson; -using System.Text.Json; -using RestSharp.Serializers.NewtonsoftJson; -using Newtonsoft.Json; -using RestSharp.Serializers; -using System.Runtime.CompilerServices; +using FWO.Api.Client; +using FWO.Data.Middleware; +using RestSharp; namespace FWO.Middleware.Client { - public class MiddlewareClient : IDisposable + public class MiddlewareClient : RestApiClient, IDisposable { private bool disposed = false; - private RestClient restClient; - readonly string middlewareServerUri; - public MiddlewareClient(string middlewareServerUri) - { - this.middlewareServerUri = middlewareServerUri; - restClient = CreateRestClient(authenticator: null); - } - - private RestClient CreateRestClient(IAuthenticator? authenticator) - { - RestClientOptions restClientOptions = new RestClientOptions(); - restClientOptions.RemoteCertificateValidationCallback += (_, _, _, _) => true; - restClientOptions.BaseUrl = new Uri(middlewareServerUri + "api/"); - restClientOptions.Authenticator = authenticator; - return new RestClient(restClientOptions, null, ConfigureRestClientSerialization); - } - - private void ConfigureRestClientSerialization(SerializerConfig config) - { - JsonNetSerializer serializer = new JsonNetSerializer(); // Case insensivitive is enabled by default - config.UseSerializer(() => serializer); - } - - public void SetAuthenticationToken(string jwt) - { - restClient = CreateRestClient(new JwtAuthenticator(jwt)); - } + public MiddlewareClient(string middlewareServerUri) : base(middlewareServerUri + "api/") + { } public async Task> AuthenticateUser(AuthenticationTokenGetParameters parameters) { - RestRequest request = new RestRequest("AuthenticationToken/Get", Method.Post); + RestRequest request = new("AuthenticationToken/Get", Method.Post); request.AddJsonBody(parameters); return await restClient.ExecuteAsync(request); } public async Task> CreateInitialJWT() { - RestRequest request = new RestRequest("AuthenticationToken/Get", Method.Post); + RestRequest request = new("AuthenticationToken/Get", Method.Post); request.AddJsonBody(new object()); return await restClient.ExecuteAsync(request); } public async Task> TestConnection(LdapGetUpdateParameters parameters) { - RestRequest request = new RestRequest("AuthenticationServer/TestConnection", Method.Get); + RestRequest request = new("AuthenticationServer/TestConnection", Method.Get); request.AddJsonBody(parameters); return await restClient.ExecuteAsync(request); } public async Task>> GetLdaps() { - RestRequest request = new RestRequest("AuthenticationServer", Method.Get); + RestRequest request = new("AuthenticationServer", Method.Get); request.AddJsonBody(new object()); return await restClient.ExecuteAsync>(request); } public async Task> AddLdap(LdapAddParameters parameters) { - RestRequest request = new RestRequest("AuthenticationServer", Method.Post); + RestRequest request = new("AuthenticationServer", Method.Post); request.AddJsonBody(parameters); return await restClient.ExecuteAsync(request); } public async Task> UpdateLdap(LdapGetUpdateParameters parameters) { - RestRequest request = new RestRequest("AuthenticationServer", Method.Put); + RestRequest request = new("AuthenticationServer", Method.Put); request.AddJsonBody(parameters); return await restClient.ExecuteAsync(request); } public async Task> DeleteLdap(LdapDeleteParameters parameters) { - RestRequest request = new RestRequest("AuthenticationServer", Method.Delete); + RestRequest request = new("AuthenticationServer", Method.Delete); request.AddJsonBody(parameters); return await restClient.ExecuteAsync(request); } public async Task> ChangePassword(UserChangePasswordParameters parameters) { - RestRequest request = new RestRequest("User/EditPassword", Method.Patch); + RestRequest request = new("User/EditPassword", Method.Patch); request.AddJsonBody(parameters); return await restClient.ExecuteAsync(request); } public async Task>> GetAllRoles() { - RestRequest request = new RestRequest("Role", Method.Get); + RestRequest request = new("Role", Method.Get); return await restClient.ExecuteAsync>(request); } public async Task>> GetGroups(GroupGetParameters parameters) { - RestRequest request = new RestRequest("Group/Get", Method.Post); + RestRequest request = new("Group/Get", Method.Post); + request.AddJsonBody(parameters); + return await restClient.ExecuteAsync>(request); + } + + public async Task>> GetGroupMembers(GroupMemberGetParameters parameters) + { + RestRequest request = new("Group/Members", Method.Post); + request.AddJsonBody(parameters); + return await restClient.ExecuteAsync>(request); + } + + public async Task>> ResolveGroupMembers(GroupResolveParameters parameters) + { + RestRequest request = new("Group/Resolve", Method.Post); + request.AddJsonBody(parameters); + return await restClient.ExecuteAsync>(request); + } + + public async Task>> GetGroupMemberships(GroupMembershipGetParameters parameters) + { + RestRequest request = new("Group/Memberships", Method.Post); request.AddJsonBody(parameters); return await restClient.ExecuteAsync>(request); } public async Task>> GetInternalGroups() { - RestRequest request = new RestRequest("Group", Method.Get); + RestRequest request = new("Group", Method.Get); return await restClient.ExecuteAsync>(request); } public async Task>> GetUsers() { - RestRequest request = new RestRequest("User", Method.Get); + RestRequest request = new("User", Method.Get); request.AddJsonBody(new object()); return await restClient.ExecuteAsync>(request); } public async Task>> GetLdapUsers(LdapUserGetParameters parameters) { - RestRequest request = new RestRequest("User/Get", Method.Post); + RestRequest request = new("User/Get", Method.Post); request.AddJsonBody(parameters); return await restClient.ExecuteAsync>(request); } public async Task> AddUser(UserAddParameters parameters) { - RestRequest request = new RestRequest("User", Method.Post); + RestRequest request = new("User", Method.Post); request.AddJsonBody(parameters); return await restClient.ExecuteAsync(request); } public async Task> UpdateUser(UserEditParameters parameters) { - RestRequest request = new RestRequest("User", Method.Put); + RestRequest request = new("User", Method.Put); request.AddJsonBody(parameters); return await restClient.ExecuteAsync(request); } public async Task> SetPassword(UserResetPasswordParameters parameters) { - RestRequest request = new RestRequest("User/ResetPassword", Method.Patch); + RestRequest request = new("User/ResetPassword", Method.Patch); request.AddJsonBody(parameters); return await restClient.ExecuteAsync(request); } public async Task> DeleteUser(UserDeleteParameters parameters) { - RestRequest request = new RestRequest("User", Method.Delete); + RestRequest request = new("User", Method.Delete); request.AddJsonBody(parameters); return await restClient.ExecuteAsync(request); } public async Task> AddGroup(GroupAddDeleteParameters parameters) { - RestRequest request = new RestRequest("Group", Method.Post); + RestRequest request = new("Group", Method.Post); request.AddJsonBody(parameters); return await restClient.ExecuteAsync(request); } public async Task> UpdateGroup(GroupEditParameters parameters) { - RestRequest request = new RestRequest("Group", Method.Put); + RestRequest request = new("Group", Method.Put); request.AddJsonBody(parameters); return await restClient.ExecuteAsync(request); } public async Task> DeleteGroup(GroupAddDeleteParameters parameters) { - RestRequest request = new RestRequest("Group", Method.Delete); + RestRequest request = new("Group", Method.Delete); request.AddJsonBody(parameters); return await restClient.ExecuteAsync(request); } public async Task> AddUserToRole(RoleAddDeleteUserParameters parameters) { - RestRequest request = new RestRequest("Role/User", Method.Post); + RestRequest request = new("Role/User", Method.Post); request.AddJsonBody(parameters); return await restClient.ExecuteAsync(request); } public async Task> RemoveUserFromRole(RoleAddDeleteUserParameters parameters) { - RestRequest request = new RestRequest("Role/User", Method.Delete); + RestRequest request = new("Role/User", Method.Delete); request.AddJsonBody(parameters); return await restClient.ExecuteAsync(request); } public async Task> AddUserToGroup(GroupAddDeleteUserParameters parameters) { - RestRequest request = new RestRequest("Group/User", Method.Post); + RestRequest request = new("Group/User", Method.Post); request.AddJsonBody(parameters); return await restClient.ExecuteAsync(request); } public async Task> RemoveUserFromGroup(GroupAddDeleteUserParameters parameters) { - RestRequest request = new RestRequest("Group/User", Method.Delete); + RestRequest request = new("Group/User", Method.Delete); request.AddJsonBody(parameters); return await restClient.ExecuteAsync(request); } public async Task> RemoveUserFromAllEntries(UserDeleteAllEntriesParameters parameters) { - RestRequest request = new RestRequest("User/AllGroupsAndRoles", Method.Delete); + RestRequest request = new("User/AllGroupsAndRoles", Method.Delete); request.AddJsonBody(parameters); return await restClient.ExecuteAsync(request); } public async Task>> GetTenants() { - RestRequest request = new RestRequest("Tenant", Method.Get); + RestRequest request = new("Tenant", Method.Get); request.AddJsonBody(new object()); return await restClient.ExecuteAsync>(request); } public async Task> AddTenant(TenantAddParameters parameters) { - RestRequest request = new RestRequest("Tenant", Method.Post); + RestRequest request = new("Tenant", Method.Post); request.AddJsonBody(parameters); return await restClient.ExecuteAsync(request); } public async Task> UpdateTenant(TenantEditParameters parameters) { - RestRequest request = new RestRequest("Tenant", Method.Put); + RestRequest request = new("Tenant", Method.Put); request.AddJsonBody(parameters); return await restClient.ExecuteAsync(request); } public async Task> DeleteTenant(TenantDeleteParameters parameters) { - RestRequest request = new RestRequest("Tenant", Method.Delete); + RestRequest request = new("Tenant", Method.Delete); + request.AddJsonBody(parameters); + return await restClient.ExecuteAsync(request); + } + + public async Task> AddExternalRequest(ExternalRequestAddParameters parameters) + { + RestRequest request = new("ExternalRequest", Method.Post); request.AddJsonBody(parameters); return await restClient.ExecuteAsync(request); } + public async Task> PatchExternalRequestState(ExternalRequestPatchStateParameters parameters) + { + RestRequest request = new("ExternalRequest/PatchState", Method.Patch); + request.AddJsonBody(parameters); + return await restClient.ExecuteAsync(request); + } + + public async Task> GetReport(ReportGetParameters parameters) + { + RestRequest request = new("Report", Method.Post); + request.AddJsonBody(parameters); + return await restClient.ExecuteAsync(request); + } + + public async Task> GetComplianceReport(ComplianceReportParameters parameters) + { + RestRequest request = new("Compliance/Report", Method.Post); + request.AddJsonBody(parameters); + return await restClient.ExecuteAsync(request); + } + + public async Task> ImportCompianceMatrix(ComplianceImportMatrixParameters parameters) + { + RestRequest request = new("Compliance/ImportMatrix", Method.Post); + request.AddJsonBody(parameters); + return await restClient.ExecuteAsync(request); + } + public async Task>> GetSchedulerJobs() + { + RestRequest request = new("Scheduler", Method.Get); + return await restClient.ExecuteAsync>(request); + } + + public async Task> RunSchedulerJob(SchedulerJobTriggerParameters parameters) + { + RestRequest request = new("Scheduler/Run", Method.Post); + request.AddJsonBody(parameters); + return await restClient.ExecuteAsync(request); + } + + public async Task> RunComplianceCheck() + { + RestRequest request = new("Compliance/ComplianceCheck"); + return await restClient.ExecuteAsync(request); + } + protected virtual void Dispose(bool disposing) { if (disposed) return; @@ -259,7 +302,7 @@ public void Dispose() GC.SuppressFinalize(this); } - ~ MiddlewareClient() + ~MiddlewareClient() { Dispose(false); } diff --git a/roles/lib/files/FWO.Middleware/FWO.Middleware.csproj b/roles/lib/files/FWO.Middleware/FWO.Middleware.csproj deleted file mode 100644 index 5750e2fa72..0000000000 --- a/roles/lib/files/FWO.Middleware/FWO.Middleware.csproj +++ /dev/null @@ -1,17 +0,0 @@ - - - - net6.0 - enable - enable - - - - - - - - - - - diff --git a/roles/lib/files/FWO.Middleware/JwtConstants.cs b/roles/lib/files/FWO.Middleware/JwtConstants.cs deleted file mode 100644 index d8348955b9..0000000000 --- a/roles/lib/files/FWO.Middleware/JwtConstants.cs +++ /dev/null @@ -1,14 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace FWO.Middleware -{ - public class JwtConstants - { - public const string Issuer = "FWO Middleware Module"; - public const string Audience = "FWO"; - } -} diff --git a/roles/lib/files/FWO.Middleware/RequestParameters/GroupParameters.cs b/roles/lib/files/FWO.Middleware/RequestParameters/GroupParameters.cs deleted file mode 100644 index 2c57a07597..0000000000 --- a/roles/lib/files/FWO.Middleware/RequestParameters/GroupParameters.cs +++ /dev/null @@ -1,33 +0,0 @@ -namespace FWO.Middleware.RequestParameters -{ - public class GroupGetParameters - { - public int LdapId { get; set; } - public string SearchPattern { get; set; } = ""; - } - - public class GroupGetReturnParameters - { - public string GroupDn { get; set; } = ""; - public bool OwnerGroup { get; set; } = false; - public List Members { get; set; } = new List(); - } - - public class GroupAddDeleteParameters - { - public string GroupName { get; set; } = ""; - public bool OwnerGroup { get; set; } = false; - } - - public class GroupEditParameters - { - public string OldGroupName { get; set; } = ""; - public string NewGroupName { get; set; } = ""; - } - - public class GroupAddDeleteUserParameters - { - public string UserDn { get; set; } = ""; - public string GroupDn { get; set; } = ""; - } -} diff --git a/roles/lib/files/FWO.Middleware/RequestParameters/TenantParameters.cs b/roles/lib/files/FWO.Middleware/RequestParameters/TenantParameters.cs deleted file mode 100644 index cd5db98cca..0000000000 --- a/roles/lib/files/FWO.Middleware/RequestParameters/TenantParameters.cs +++ /dev/null @@ -1,37 +0,0 @@ -namespace FWO.Middleware.RequestParameters -{ - public class TenantAddParameters - { - public string Name { get; set; } = ""; - public string? Comment { get; set; } - public string? Project { get; set; } - public bool ViewAllDevices { get; set; } - // public bool Superadmin { get; set; } - } - - public class TenantGetReturnParameters : TenantAddParameters - { - public int Id { get; set; } - public List Devices { get; set; } = new List(); - } - - public class TenantViewDevice - { - public int Id { get; set; } - public string Name { get; set; } = ""; - } - - public class TenantEditParameters - { - public int Id { get; set; } - public string? Comment { get; set; } - public string? Project { get; set; } - public bool ViewAllDevices { get; set; } - } - - public class TenantDeleteParameters - { - public int Id { get; set; } - public string Name { get; set; } = ""; - } -} diff --git a/roles/lib/files/FWO.Recert/FWO.Recert.csproj b/roles/lib/files/FWO.Recert/FWO.Recert.csproj index 8316cdeab8..2504cdc6bf 100644 --- a/roles/lib/files/FWO.Recert/FWO.Recert.csproj +++ b/roles/lib/files/FWO.Recert/FWO.Recert.csproj @@ -1,7 +1,7 @@ - net6.0 + net10.0 enable enable @@ -9,6 +9,8 @@ + + diff --git a/roles/lib/files/FWO.Recert/RecertHandler.cs b/roles/lib/files/FWO.Recert/RecertHandler.cs new file mode 100644 index 0000000000..b3a958ec09 --- /dev/null +++ b/roles/lib/files/FWO.Recert/RecertHandler.cs @@ -0,0 +1,126 @@ +using FWO.Api.Client; +using FWO.Api.Client.Queries; +using FWO.Config.Api; +using FWO.Data; + +namespace FWO.Recert +{ + public class RecertHandler(ApiConnection apiConnection, UserConfig userConfig) + { + public async Task InitOwnerRecert(FwoOwner owner) + { + if ((await apiConnection.SendQueryAsync>(RecertQueries.getInitialOwnerRecert, new { ownerId = owner.Id })).Count == 0) + { + await RecertifyOwner(owner, "Initial Owner Recert", true); + } + } + + public async Task RecertifyOwnerWithRules(FwoOwner owner, List rules, string? comment, bool initialRecert = false) + { + FwoOwner recertifiedOwner = await RecertifyOwner(owner, comment, initialRecert); + foreach (var rule in rules) + { + await RecertifySingleRuleFromOwner(rule, recertifiedOwner, comment); + } + return recertifiedOwner; + } + + public async Task RecertifySingleRule(Rule rule, FwoOwner? owner, string? comment) + { + var variables = new + { + ruleId = rule.Id, + ownerId = owner?.Id ?? 0, + userDn = userConfig.User.Dn, + recertified = rule.Metadata.Recert, + recertDate = DateTime.Now, + comment = comment, + ownerRecertId = owner?.LastRecertId == 0 ? null : owner?.LastRecertId + }; + bool recertOk = (await apiConnection.SendQueryAsync(RecertQueries.recertify, variables)).AffectedRows > 0; + if (rule.Metadata.Recert) + { + await InitRuleRecert(rule, owner); + } + return recertOk; + } + + private async Task RecertifyOwner(FwoOwner owner, string? comment = "", bool initialRecert = false) + { + FwoOwner recertifiedOwner = new(owner); + DateTime recertDate = DateTime.Now; + DateTime? nextRecertDate = CalcNextRecertDate(owner, recertDate, initialRecert); + var recertVariables = new + { + ownerId = owner.Id, + userDn = initialRecert ? userConfig.InitialRecertifier : userConfig.User.Dn, + recertified = !initialRecert, + recertDate = recertDate, + nextRecertDate = nextRecertDate, + comment = comment + }; + ReturnId[]? returnIds = (await apiConnection.SendQueryAsync(RecertQueries.recertifyOwner, recertVariables)).ReturnIds; + if (returnIds != null && returnIds.Length > 0) + { + recertifiedOwner.LastRecertId = returnIds[0].NewIdLong; + recertifiedOwner.LastRecertified = recertDate; + recertifiedOwner.LastRecertifierId = initialRecert ? null : userConfig.User.DbId; + recertifiedOwner.LastRecertifierDn = initialRecert ? userConfig.InitialRecertifier : userConfig.User.Dn; + recertifiedOwner.NextRecertDate = nextRecertDate; + await UpdateRecertifiedOwner(recertifiedOwner); + } + return recertifiedOwner; + } + + private DateTime? CalcNextRecertDate(FwoOwner owner, DateTime recertDate, bool initial) + { + int nextRegularCertInterval = owner.RecertInterval ?? userConfig.RecertificationPeriod; + int recertInterval = initial ? Math.Min(userConfig.InitialRecertificationPeriod, nextRegularCertInterval) : nextRegularCertInterval; + return recertInterval > 0 ? recertDate.AddDays(recertInterval) : null; + } + + private async Task UpdateRecertifiedOwner(FwoOwner owner) + { + var ownerVariables = new + { + id = owner.Id, + lastRecert = owner.LastRecertified, + lastRecertifierId = owner.LastRecertifierId, + lastRecertifierDn = owner.LastRecertifierDn, + nextRecertDate = owner.NextRecertDate + }; + await apiConnection.SendQueryAsync(OwnerQueries.setOwnerLastRecert, ownerVariables); + } + + private async Task RecertifySingleRuleFromOwner(Rule rule, FwoOwner? owner, string? comment) + { + var variables = new + { + ruleMetadataId = rule.Metadata.Id, + ruleId = rule.Id, + ownerId = owner?.Id ?? 0, + nextRecertDate = owner?.NextRecertDate, + userDn = userConfig.User.Dn, + recertified = true, + recertDate = DateTime.Now, + comment = comment, + ownerRecertId = owner?.LastRecertId + }; + return (await apiConnection.SendQueryAsync(RecertQueries.recertifyRuleDirectly, variables)).ReturnIds?[0].NewIdLong > 0; + } + + private async Task InitRuleRecert(Rule rule, FwoOwner? owner) + { + int recertInterval = owner?.RecertInterval ?? userConfig.RecertificationPeriod; + var prepvariables = new + { + ruleMetadataId = rule.Metadata.Id, + ruleId = rule.Id, + ipMatch = rule.IpMatch != "" ? rule.IpMatch : null, + ownerId = owner?.Id ?? 0, + nextRecertDate = DateTime.Now.AddDays(recertInterval) + }; + await apiConnection.SendQueryAsync(RecertQueries.prepareNextRecertification, prepvariables); + } + } +} diff --git a/roles/lib/files/FWO.Recert/RecertRefresh.cs b/roles/lib/files/FWO.Recert/RecertRefresh.cs index 4f151a8c02..a9fd3452e9 100644 --- a/roles/lib/files/FWO.Recert/RecertRefresh.cs +++ b/roles/lib/files/FWO.Recert/RecertRefresh.cs @@ -1,41 +1,37 @@ -using System.Diagnostics; -using FWO.Api.Data; +using System.Diagnostics; +using FWO.Data; using FWO.Api.Client; +using FWO.Api.Client.Queries; using FWO.Logging; namespace FWO.Recert { - public class RecertRefresh + public static class RecertRefresh { - private readonly ApiConnection apiConnection; - - public RecertRefresh (ApiConnection apiConnectionIn) + public static async Task RecalcRecerts(ApiConnection apiConnection) { - apiConnection = apiConnectionIn; - } - - public async Task RecalcRecerts() - { - double refreshDuration = 0; - Stopwatch watch = new System.Diagnostics.Stopwatch(); - string secs = ""; - var noVariables = new { }; + Stopwatch watch = new(); try { watch.Start(); - List owners = await apiConnection.SendQueryAsync>(FWO.Api.Client.Queries.OwnerQueries.getOwners); - List managements = await apiConnection.SendQueryAsync>(FWO.Api.Client.Queries.DeviceQueries.getManagementDetailsWithoutSecrets); - ReturnId[]? returnIds = - (await apiConnection.SendQueryAsync(FWO.Api.Client.Queries.RecertQueries.clearOpenRecerts, noVariables)).ReturnIds; - // the clearOpenRecerts refreshes materialized view view_rule_with_owner as a side-effect + List owners = await apiConnection.SendQueryAsync>(OwnerQueries.getOwners); + List managements = await apiConnection.SendQueryAsync>(DeviceQueries.getManagementDetailsWithoutSecrets); + ReturnId[]? returnIds = (await apiConnection.SendQueryAsync(RecertQueries.clearOpenRecerts)).ReturnIds; + Log.WriteDebug("Delete open recerts", $"deleted Ids: {(returnIds != null ? string.Join(",", Array.ConvertAll(returnIds, Id => Id.DeletedIdLong)) : "")}"); + OwnerRefresh? refreshResult = (await apiConnection.SendQueryAsync>(RecertQueries.refreshViewRuleWithOwner)).FirstOrDefault(); + if (refreshResult == null || refreshResult.GetStatus() != "Materialized view refreshed successfully") + { + Log.WriteError("Refresh materialized view view_rule_with_owner", "refresh failed"); + return true; + } watch.Stop(); - refreshDuration = watch.ElapsedMilliseconds / 1000.0; - secs = refreshDuration.ToString("0.00"); - Log.WriteDebug("Refresh materialized view view_rule_with_owner", $"refresh took {secs} seconds"); + Log.WriteDebug("Refresh materialized view view_rule_with_owner", $"refresh took {(watch.ElapsedMilliseconds / 1000.0).ToString("0.00")} seconds"); foreach (FwoOwner owner in owners) - await RecalcRecertsOfOwner(owner, managements); + { + await RecalcRecertsOfOwner(owner, managements, apiConnection); + } } catch (Exception) { @@ -44,30 +40,24 @@ public async Task RecalcRecerts() return false; } - private async Task RecalcRecertsOfOwner(FwoOwner owner, List managements) + private static async Task RecalcRecertsOfOwner(FwoOwner owner, List managements, ApiConnection apiConnection) { - double refreshDuration = 0; - Stopwatch watch = new System.Diagnostics.Stopwatch(); - string secs = ""; + Stopwatch watch = new(); watch.Start(); foreach (Management mgm in managements) { List currentRecerts = - await apiConnection.SendQueryAsync>(FWO.Api.Client.Queries.RecertQueries.getOpenRecerts, new { ownerId = owner.Id, mgmId = mgm.Id }); + await apiConnection.SendQueryAsync>(RecertQueries.getOpenRecertsForOwners, new { ownerId = owner.Id, mgmId = mgm.Id }); if (currentRecerts.Count > 0) { - ReturnId[]? returnedIds = (await apiConnection.SendQueryAsync(FWO.Api.Client.Queries.RecertQueries.addRecertEntries, new { recerts = currentRecerts })).ReturnIds; + await apiConnection.SendQueryAsync(RecertQueries.addRecertEntries, new { recerts = currentRecerts }); } } watch.Stop(); - refreshDuration = watch.ElapsedMilliseconds / 1000.0; - secs = refreshDuration.ToString("0.00"); - Log.WriteDebug("Refresh Recertification", $"refresh for owner {owner.Name} took {secs} seconds"); + Log.WriteDebug("Refresh Recertification", $"refresh for owner {owner.Name} took {(watch.ElapsedMilliseconds / 1000.0).ToString("0.00")} seconds"); } - } } - diff --git a/roles/lib/files/FWO.Report.Filter/Ast/AstKind.cs b/roles/lib/files/FWO.Report.Filter/Ast/AstKind.cs index e8be0870b2..ec5a641b88 100644 --- a/roles/lib/files/FWO.Report.Filter/Ast/AstKind.cs +++ b/roles/lib/files/FWO.Report.Filter/Ast/AstKind.cs @@ -1,7 +1,3 @@ -using System; -using System.Collections.Generic; -using System.Text; - namespace FWO.Report.Filter.Ast { public enum AstKind diff --git a/roles/lib/files/FWO.Report.Filter/Ast/AstNode.cs b/roles/lib/files/FWO.Report.Filter/Ast/AstNode.cs index 7e12be5995..b9caa04cf7 100644 --- a/roles/lib/files/FWO.Report.Filter/Ast/AstNode.cs +++ b/roles/lib/files/FWO.Report.Filter/Ast/AstNode.cs @@ -1,4 +1,7 @@ -namespace FWO.Report.Filter.Ast +using FWO.Basics; + + +namespace FWO.Report.Filter.Ast { public abstract class AstNode { diff --git a/roles/lib/files/FWO.Report.Filter/Ast/AstNodeConnector.cs b/roles/lib/files/FWO.Report.Filter/Ast/AstNodeConnector.cs index 3b82fa64ac..898723db7e 100644 --- a/roles/lib/files/FWO.Report.Filter/Ast/AstNodeConnector.cs +++ b/roles/lib/files/FWO.Report.Filter/Ast/AstNodeConnector.cs @@ -1,4 +1,6 @@ -using FWO.Report.Filter.Exceptions; +using FWO.Report.Filter.Exceptions; +using FWO.Basics; + namespace FWO.Report.Filter.Ast { @@ -7,29 +9,42 @@ public class AstNodeConnector : AstNode public AstNode? Right { get; set; } public AstNode? Left { get; set; } public Token? Connector { get; set; } + private readonly string StartAnd = "_and: [{"; + private readonly string StartOr = "_or: [{"; + private readonly string Inbetween = "}, {"; + private readonly string CloseBrackets = "}] "; + public override void Extract(ref DynGraphqlQuery query, ReportType? reportType) { if (Connector == null) - throw new ArgumentNullException(nameof(Connector)); + { + throw new InvalidOperationException(nameof(Connector)); + } if (Left == null) - throw new ArgumentNullException(nameof(Left)); + { + throw new InvalidOperationException(nameof(Left)); + } if (Right == null) - throw new ArgumentNullException(nameof(Right)); + { + throw new InvalidOperationException(nameof(Right)); + } switch (Connector.Kind) { case TokenKind.And: // and terms should be enclosed in [] - query.ruleWhereStatement += "_and: [{"; - query.nwObjWhereStatement += "_and: [{"; - query.svcObjWhereStatement += "_and: [{"; - query.userObjWhereStatement += "_and: [{"; + query.RuleWhereStatement += StartAnd; + query.NwObjWhereStatement += StartAnd; + query.SvcObjWhereStatement += StartAnd; + query.UserObjWhereStatement += StartAnd; + query.ConnectionWhereStatement += StartAnd; break; case TokenKind.Or: // or terms need to be enclosed in [] - query.ruleWhereStatement += "_or: [{"; - query.nwObjWhereStatement += "_or: [{"; - query.svcObjWhereStatement += "_or: [{"; - query.userObjWhereStatement += "_or: [{"; + query.RuleWhereStatement += StartOr; + query.NwObjWhereStatement += StartOr; + query.SvcObjWhereStatement += StartOr; + query.UserObjWhereStatement += StartOr; + query.ConnectionWhereStatement += StartOr; break; default: throw new SemanticException($"### Compiler Error: Found unexpected and unsupported connector token (prefix): \"{Connector}\". ###", Connector.Position); @@ -41,10 +56,11 @@ public override void Extract(ref DynGraphqlQuery query, ReportType? reportType) { case TokenKind.And: case TokenKind.Or: - query.ruleWhereStatement += "}, {"; - query.nwObjWhereStatement += "}, {"; - query.svcObjWhereStatement += "}, {"; - query.userObjWhereStatement += "}, {"; + query.RuleWhereStatement += Inbetween; + query.NwObjWhereStatement += Inbetween; + query.SvcObjWhereStatement += Inbetween; + query.UserObjWhereStatement += Inbetween; + query.ConnectionWhereStatement += Inbetween; break; default: throw new SemanticException($"### Compiler Error: Found unexpected and unsupported connector token (operator): \"{Connector}\". ###", Connector.Position); @@ -56,10 +72,11 @@ public override void Extract(ref DynGraphqlQuery query, ReportType? reportType) { case TokenKind.And: case TokenKind.Or: - query.ruleWhereStatement += "}] "; - query.nwObjWhereStatement += "}] "; - query.svcObjWhereStatement += "}] "; - query.userObjWhereStatement += "}] "; + query.RuleWhereStatement += CloseBrackets; + query.NwObjWhereStatement += CloseBrackets; + query.SvcObjWhereStatement += CloseBrackets; + query.UserObjWhereStatement += CloseBrackets; + query.ConnectionWhereStatement += CloseBrackets; break; default: throw new SemanticException($"### Compiler Error: Found unexpected and unsupported connector token (suffix): \"{Connector}\" ###", Connector.Position); diff --git a/roles/lib/files/FWO.Report.Filter/Ast/AstNodeFilter.cs b/roles/lib/files/FWO.Report.Filter/Ast/AstNodeFilter.cs index 8e989e6d20..04d62a1e4e 100644 --- a/roles/lib/files/FWO.Report.Filter/Ast/AstNodeFilter.cs +++ b/roles/lib/files/FWO.Report.Filter/Ast/AstNodeFilter.cs @@ -1,4 +1,6 @@ using FWO.Report.Filter.Exceptions; +using FWO.Report.Filter.FilterTypes; + namespace FWO.Report.Filter.Ast { @@ -7,9 +9,8 @@ abstract class AstNodeFilter : AstNode public Token Name { get; set; } = new Token(new Range(), "", TokenKind.Value); public Token Operator { get; set; } = new Token(new Range(), "", TokenKind.Value); public Token Value { get; set; } = new Token(new Range(), "", TokenKind.Value); - private List? ruleFieldNames { get; set; } - protected void CheckOperator(Token isOperator, bool equalsIsExactEquals, params TokenKind[] expectedOperators) + protected static void CheckOperator(Token isOperator, bool equalsIsExactEquals, params TokenKind[] expectedOperators) { if (equalsIsExactEquals) { @@ -34,11 +35,11 @@ protected string ExtractOperator() }; } - protected string AddVariable(DynGraphqlQuery query, string name, TokenKind op, Type value) + protected static string AddVariable(DynGraphqlQuery query, string name, TokenKind op, Type value) { string queryVarName = name + query.parameterCounter++; - string queryVarType = ""; - string queryVarValue = ""; + string queryVarType; + string queryVarValue; switch (value) { @@ -46,7 +47,7 @@ protected string AddVariable(DynGraphqlQuery query, string name, TokenKind queryVarType = "Boolean"; queryVarValue = boolValue ? "true" : "false"; break; - + case string stringValue: queryVarType = "String"; queryVarValue = stringValue; @@ -66,7 +67,7 @@ protected string AddVariable(DynGraphqlQuery query, string name, TokenKind queryVarType = "timestamp"; if (dateTimeValue.Start == null && dateTimeValue.End == null) throw new NotSupportedException($"LastHit filter with missing date"); - DateTime date = new DateTime(); + DateTime date = new(); if (dateTimeValue.End != null) date = (DateTime)dateTimeValue.End; if (dateTimeValue.Start != null) @@ -85,6 +86,5 @@ protected string AddVariable(DynGraphqlQuery query, string name, TokenKind } public abstract void ConvertToSemanticType(); - } } diff --git a/roles/lib/files/FWO.Report.Filter/Ast/AstNodeFilterBool.cs b/roles/lib/files/FWO.Report.Filter/Ast/AstNodeFilterBool.cs index 68f75fbb4e..156ce6e6cb 100644 --- a/roles/lib/files/FWO.Report.Filter/Ast/AstNodeFilterBool.cs +++ b/roles/lib/files/FWO.Report.Filter/Ast/AstNodeFilterBool.cs @@ -1,9 +1,6 @@ -using FWO.Report.Filter.Exceptions; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; +using FWO.Report.Filter.Exceptions; +using FWO.Basics; + namespace FWO.Report.Filter.Ast { @@ -32,7 +29,6 @@ public override void Extract(ref DynGraphqlQuery query, ReportType? reportType) { case TokenKind.Disabled: ExtractDisabledQuery(query); - //throw new NotSupportedException("Token of type \"Disabled\" is currently not supported."); break; case TokenKind.SourceNegated: // ExtractSourceNegatedQuery(query); @@ -51,18 +47,26 @@ public override void Extract(ref DynGraphqlQuery query, ReportType? reportType) } } - private DynGraphqlQuery ExtractRemoveFilter(DynGraphqlQuery query) + private void ExtractRemoveFilter(DynGraphqlQuery query) { string queryVarName = AddVariable(query, "remove", Operator.Kind, semanticValue); - query.ruleWhereStatement += $"rule_metadatum: {{rule_to_be_removed: {{ {ExtractOperator()}: ${queryVarName} }}}}"; - return query; + query.RuleWhereStatement += $"rule_metadatum: {{rule_to_be_removed: {{ {ExtractBooleanOperator()}: ${queryVarName} }}}}"; } - private DynGraphqlQuery ExtractDisabledQuery(DynGraphqlQuery query) + private void ExtractDisabledQuery(DynGraphqlQuery query) { string queryVarName = AddVariable(query, "disabled", Operator.Kind, semanticValue); - query.ruleWhereStatement += $"rule_disabled: {{ {ExtractOperator()}: ${queryVarName} }}"; - return query; + query.RuleWhereStatement += $"rule_disabled: {{ {ExtractBooleanOperator()}: ${queryVarName} }}"; + } + + private string ExtractBooleanOperator() + { + return Operator.Kind switch + { + TokenKind.EQ or TokenKind.EEQ => "_eq", + TokenKind.NEQ => "_neq", + _ => throw new SemanticException("Invalid boolean operator.", Operator.Position), + }; } } } diff --git a/roles/lib/files/FWO.Report.Filter/Ast/AstNodeFilterDateTimeRange.cs b/roles/lib/files/FWO.Report.Filter/Ast/AstNodeFilterDateTimeRange.cs index 0de31b27ed..89c3263808 100644 --- a/roles/lib/files/FWO.Report.Filter/Ast/AstNodeFilterDateTimeRange.cs +++ b/roles/lib/files/FWO.Report.Filter/Ast/AstNodeFilterDateTimeRange.cs @@ -1,8 +1,12 @@ -namespace FWO.Report.Filter.Ast +using FWO.Report.Filter.FilterTypes; +using FWO.Basics; + + +namespace FWO.Report.Filter.Ast { internal class AstNodeFilterDateTimeRange : AstNodeFilter { - DateTimeRange semanticValue; + DateTimeRange? semanticValue; public override void ConvertToSemanticType() { @@ -17,22 +21,22 @@ public override void Extract(ref DynGraphqlQuery query, ReportType? reportType) switch (Name.Kind) { case TokenKind.LastHit: - ExtractLastHitFilter(query, (ReportType)reportType); + ExtractLastHitFilter(query, reportType); break; default: break; } } - private DynGraphqlQuery ExtractLastHitFilter(DynGraphqlQuery query, ReportType reportType) + private void ExtractLastHitFilter(DynGraphqlQuery query, ReportType? reportType) { string queryVarName = AddVariable(query, "lastHitLimit", Operator.Kind, semanticValue!); - - if (reportType.IsChangeReport()) + + if (reportType != null && ((ReportType)reportType).IsChangeReport()) { - if (Operator.Kind==TokenKind.LSS) // only show rules which have a hit before a certain date (including no hit rules) + if (Operator.Kind == TokenKind.LSS) // only show rules which have a hit before a certain date (including no hit rules) { - query.ruleWhereStatement += $@" + query.RuleWhereStatement += $@" _or: [ {{ rule: {{ rule_metadatum: {{ rule_last_hit: {{{ExtractOperator()}: ${queryVarName} }} }} }} }} {{ rule: {{ rule_metadatum: {{ rule_last_hit: {{_is_null: true }} }} }} }} @@ -40,14 +44,14 @@ private DynGraphqlQuery ExtractLastHitFilter(DynGraphqlQuery query, ReportType r } else // only show rules which have a hit after a certain date (leaving out no hit rules) { - query.ruleWhereStatement += $"rule: {{ rule_metadatum:{{ rule_last_hit: {{{ExtractOperator()}: ${queryVarName} }} }} }}"; + query.RuleWhereStatement += $"rule: {{ rule_metadatum:{{ rule_last_hit: {{{ExtractOperator()}: ${queryVarName} }} }} }}"; } } else { - if (Operator.Kind==TokenKind.LSS) // only show rules which have a hit before a certain date (including no hit rules) + if (Operator.Kind == TokenKind.LSS) // only show rules which have a hit before a certain date (including no hit rules) { - query.ruleWhereStatement += $@" + query.RuleWhereStatement += $@" _or: [ {{ rule_metadatum: {{ rule_last_hit: {{{ExtractOperator()}: ${queryVarName} }} }} }} {{ rule_metadatum: {{ rule_last_hit: {{_is_null: true }} }} }} @@ -55,10 +59,9 @@ private DynGraphqlQuery ExtractLastHitFilter(DynGraphqlQuery query, ReportType r } else // only show rules which have a hit after a certain date (leaving out no hit rules) { - query.ruleWhereStatement += $"rule_metadatum: {{ rule_last_hit: {{{ExtractOperator()}: ${queryVarName} }} }}"; + query.RuleWhereStatement += $"rule_metadatum: {{ rule_last_hit: {{{ExtractOperator()}: ${queryVarName} }} }}"; } } - return query; } } } diff --git a/roles/lib/files/FWO.Report.Filter/Ast/AstNodeFilterInt.cs b/roles/lib/files/FWO.Report.Filter/Ast/AstNodeFilterInt.cs index 2e5611e3d4..6f878c56f6 100644 --- a/roles/lib/files/FWO.Report.Filter/Ast/AstNodeFilterInt.cs +++ b/roles/lib/files/FWO.Report.Filter/Ast/AstNodeFilterInt.cs @@ -1,4 +1,6 @@ -using FWO.Report.Filter.Exceptions; +using FWO.Report.Filter.Exceptions; +using FWO.Basics; + namespace FWO.Report.Filter.Ast { @@ -31,9 +33,6 @@ public override void Extract(ref DynGraphqlQuery query, ReportType? reportType) case TokenKind.RecertDisplay: ExtractRecertDisplayFilter(query); break; - case TokenKind.Owner: - ExtractOwnerFilter(query); - break; case TokenKind.Unused: ExtractUnusedFilter(query); break; @@ -42,36 +41,28 @@ public override void Extract(ref DynGraphqlQuery query, ReportType? reportType) } } - private DynGraphqlQuery ExtractRecertDisplayFilter(DynGraphqlQuery query) + private void ExtractRecertDisplayFilter(DynGraphqlQuery query) { // string queryVarName = AddVariable(query, "refdate", Operator.Kind, DateTime.Now.AddDays(semanticValue)); // query.ruleWhereStatement += $@" rule_metadatum: {{ recertifications: {{ next_recert_date: {{ _lte: ${queryVarName} }} }} }}"; - return query; } - private DynGraphqlQuery ExtractDestinationPortFilter(DynGraphqlQuery query) + private void ExtractDestinationPortFilter(DynGraphqlQuery query) { string queryVarName = AddVariable(query, "dport", Operator.Kind, semanticValue); - query.ruleWhereStatement += "rule_services: { service: { svcgrp_flats: { serviceBySvcgrpFlatMemberId: { svc_port: {_lte" + + query.RuleWhereStatement += "rule_services: { service: { svcgrp_flats: { serviceBySvcgrpFlatMemberId: { svc_port: {_lte" + ": $" + queryVarName + "}, svc_port_end: {_gte: $" + queryVarName + " } } } } }"; - return query; - } - - private DynGraphqlQuery ExtractOwnerFilter(DynGraphqlQuery query) - { - string QueryVarName = AddVariable(query, "owner", Operator.Kind, Value.Text); - query.ruleWhereStatement += $"owner: {{ {ExtractOperator()}: ${QueryVarName} }}"; - return query; + query.ConnectionWhereStatement += $"_or: [ {{ service_connections: {{service: {{ port: {{ _lte: ${queryVarName} }}, port_end: {{ _gte: ${queryVarName} }} }} }} }}, " + + $"{{ service_group_connections: {{service_group: {{ service_service_groups: {{ service: {{ port: {{ _lte: ${queryVarName} }}, port_end: {{ _gte: ${queryVarName} }} }} }} }} }} }} ]"; } - private DynGraphqlQuery ExtractUnusedFilter(DynGraphqlQuery query) + private void ExtractUnusedFilter(DynGraphqlQuery query) { string QueryVarName = AddVariable(query, "cut", Operator.Kind, DateTime.Now.AddDays(-semanticValue)); - query.ruleWhereStatement += $@"rule_metadatum: {{_or: [ + query.RuleWhereStatement += $@"rule_metadatum: {{_or: [ {{_and: [{{rule_last_hit: {{_is_null: false}} }}, {{rule_last_hit: {{_lte: ${QueryVarName} }} }} ] }}, {{ rule_last_hit: {{_is_null: true}} }} ]}}"; - return query; } } } diff --git a/roles/lib/files/FWO.Report.Filter/Ast/AstNodeFilterNetwork.cs b/roles/lib/files/FWO.Report.Filter/Ast/AstNodeFilterNetwork.cs index 6421eb3174..9226fed1b0 100644 --- a/roles/lib/files/FWO.Report.Filter/Ast/AstNodeFilterNetwork.cs +++ b/roles/lib/files/FWO.Report.Filter/Ast/AstNodeFilterNetwork.cs @@ -1,11 +1,8 @@ -using NetTools; -using System; -using System.Collections.Generic; -using System.Linq; +using NetTools; using System.Net; -using System.Text; -using System.Threading.Tasks; using FWO.Logging; +using FWO.Basics; + namespace FWO.Report.Filter.Ast { @@ -14,7 +11,6 @@ internal class AstNodeFilterNetwork : AstNodeFilter public override void ConvertToSemanticType() { CheckOperator(Operator, false, TokenKind.EQ, TokenKind.EEQ, TokenKind.NEQ); - // semanticValue = int.Parse(Value.Text); } public override void Extract(ref DynGraphqlQuery query, ReportType? reportType) @@ -34,77 +30,84 @@ public override void Extract(ref DynGraphqlQuery query, ReportType? reportType) } } - private DynGraphqlQuery ExtractDestinationFilter(DynGraphqlQuery query) + private void ExtractDestinationFilter(DynGraphqlQuery query) { if (IsCidr(Value.Text)) // filtering for ip addresses - query = ExtractIpFilter(query, location: "dst", locationTable: "rule_tos"); + { + ExtractIpFilter(query, location: "dst", locationTable: "rule_tos"); + } else // string search against dst obj name { string QueryVarName = AddVariable(query, "dst", Operator.Kind, Value.Text); - query.ruleWhereStatement += $"rule_tos: {{ object: {{ objgrp_flats: {{ objectByObjgrpFlatMemberId: {{ obj_name: {{ {ExtractOperator()}: ${QueryVarName} }} }} }} }} }}"; + query.RuleWhereStatement += $"rule_tos: {{ object: {{ objgrp_flats: {{ objectByObjgrpFlatMemberId: {{ obj_name: {{ {ExtractOperator()}: ${QueryVarName} }} }} }} }} }}"; + query.ConnectionWhereStatement += ConnWhere(QueryVarName, 2); } - return query; } - private DynGraphqlQuery ExtractSourceFilter(DynGraphqlQuery query) + private void ExtractSourceFilter(DynGraphqlQuery query) { if (IsCidr(Value.Text)) // filtering for ip addresses - query = ExtractIpFilter(query, location: "src", locationTable: "rule_froms"); + { + ExtractIpFilter(query, location: "src", locationTable: "rule_froms"); + } else // string search against src obj name { string QueryVarName = AddVariable(query, "src", Operator.Kind, Value.Text); - query.ruleWhereStatement += $"rule_froms: {{ object: {{ objgrp_flats: {{ objectByObjgrpFlatMemberId: {{ obj_name: {{ {ExtractOperator()}: ${QueryVarName} }} }} }} }} }}"; + query.RuleWhereStatement += $"rule_froms: {{ object: {{ objgrp_flats: {{ objectByObjgrpFlatMemberId: {{ obj_name: {{ {ExtractOperator()}: ${QueryVarName} }} }} }} }} }}"; + query.ConnectionWhereStatement += ConnWhere(QueryVarName, 1); } - return query; } - private static string SanitizeIp(string cidr_str) + private string ConnWhere(string QueryVarName, int field) { - IPAddress? ip; - if (IPAddress.TryParse(cidr_str, out ip)) + return $"_or: [ {{ nwobject_connections: {{connection_field: {{ _eq: {field} }}, owner_network: {{name: {{ {ExtractOperator()}: ${QueryVarName} }} }} }} }}, " + + $"{{ nwgroup_connections: {{connection_field: {{ _eq: {field} }}, nwgroup: {{ _or: [ {{ name: {{ {ExtractOperator()}: ${QueryVarName} }} }}, {{ id_string: {{ {ExtractOperator()}: ${QueryVarName} }} }} ] }} }} }} ]"; + } + + private static string SanitizeIp(string cidrStr) + { + if (IPAddress.TryParse(cidrStr, out IPAddress? ip)) { if (ip != null) { if (ip.AddressFamily == System.Net.Sockets.AddressFamily.InterNetworkV6) { - cidr_str = ip.ToString(); - if (cidr_str.IndexOf("/") < 0) // a single ip without mask - { - cidr_str += "/128"; - } - if (cidr_str.IndexOf("/") == cidr_str.Length - 1) // wrong format (/ at the end, fixing this by adding 128 mask) - { - cidr_str += "128"; - } + return SanitizeIp(ip, true); } else if (ip.AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork) { - cidr_str = ip.ToString(); - if (cidr_str.IndexOf("/") < 0) // a single ip without mask - { - cidr_str += "/32"; - } - if (cidr_str.IndexOf("/") == cidr_str.Length - 1) // wrong format (/ at the end, fixing this by adding 32 mask) - { - cidr_str += "32"; - } + return SanitizeIp(ip, false); } } - else + else { - Log.WriteWarning("SanitizeIP", $"unexpected IP address family (neither v4 nor v6) found"); + Log.WriteWarning("SanitizeIP", $"unexpected IP address family (neither v4 nor v6) found"); } } - return cidr_str; + return cidrStr; + } + + private static string SanitizeIp(IPAddress ip, bool v6) + { + string cidrStr = ip.ToString(); + if (cidrStr.IndexOf('/') < 0) // a single ip without mask + { + cidrStr += v6 ? "/128" : "/32"; + } + if (cidrStr.IndexOf('/') == cidrStr.Length - 1) // wrong format (/ at the end, fixing this by adding 128 mask) + { + cidrStr += v6 ? "128" : "32"; + } + return cidrStr; } private static bool IsCidr(string cidr) { - return IPAddressRange.TryParse(cidr, out IPAddressRange range); + return IPAddressRange.TryParse(cidr, out _); } - private DynGraphqlQuery ExtractIpFilter(DynGraphqlQuery query, string location, string locationTable) + private void ExtractIpFilter(DynGraphqlQuery query, string location, string locationTable) { IPAddressRange filterIP = IPAddressRange.Parse(SanitizeIp(Value.Text)); string firstFilterIp = filterIP.Begin.ToString(); @@ -115,88 +118,52 @@ private DynGraphqlQuery ExtractIpFilter(DynGraphqlQuery query, string location, query.QueryVariables[QueryVarNameLast2] = lastFilterIp; query.QueryParameters.Add($"${QueryVarNameFirst1}: cidr! "); query.QueryParameters.Add($"${QueryVarNameLast2}: cidr! "); - // covering the following cases: - // 1 - current ip is fully contained in filter ip range - // 2 - current ip fully contains filter ip range - does not work - // 3 - current ip overlaps with lower boundary of filter ip range - // 4 - current ip overlaps with upper boundary of filter ip range // TODO: might simply set all header IP addresses to 0.0.0.0/32 instead of 0.0.0.0/0 to filter them out + + // logic: end_ip1 >= start_ip2 and start_ip1 <= end_ip2 + // end_ip1 = obj_ip_end + // start_ip2 = QueryVarNameFirst1 + // start_ip1 = obj_ip + // end_ip2 = QueryVarNameLast2 + // obj_ip_end >= QueryVarNameFirst1 and obj_ip <= QueryVarNameLast2 + string ipFilterString = - $@" _or: [ - {{ _and: - [ - {{ obj_ip: {{ _gte: ${QueryVarNameFirst1} }} }} - {{ obj_ip: {{ _lte: ${QueryVarNameLast2} }} }} - ] - }} - {{ _and: - [ - {{ obj_ip: {{ _lte: ${QueryVarNameFirst1} }} }} - {{ obj_ip: {{ _gte: ${QueryVarNameFirst1} }} }} - ] - }} - {{ _and: - [ - {{ obj_ip: {{ _lte: ${QueryVarNameLast2} }} }} - {{ obj_ip: {{ _gte: ${QueryVarNameLast2} }} }} - ] - }} - {{ _and: - [ - {{ obj_ip: {{ _lte: ${QueryVarNameFirst1} }} }} - {{ obj_ip: {{ _gte: ${QueryVarNameLast2} }} }} - ] - }} - {{ - _and: - [ - {{ network_object_limits: {{ first_ip: {{ _lte: ${QueryVarNameFirst1} }} }} }} - {{ network_object_limits: {{ last_ip: {{ _gte: ${QueryVarNameLast2} }} }} }} - ] - }} - ]"; - query.ruleWhereStatement += - $@" {locationTable}: - {{ object: - {{ objgrp_flats: - {{ objectByObjgrpFlatMemberId: - {{ {ipFilterString} }} - }} - }} - }}"; - query.nwObjWhereStatement += - $@" {locationTable}: - {{ object: - {{ objgrp_flats: - {{ objectByObjgrpFlatMemberId: - {{ {ipFilterString} }} - }} - }} - }}"; - return query; + $@" obj_ip_end: {{ _gte: ${QueryVarNameFirst1} }} + obj_ip: {{ _lte: ${QueryVarNameLast2} }}"; + query.RuleWhereStatement += + $@" _or: [ + {{ + rule_{location}_neg: {{_eq: false}}, + {locationTable}: {{ + _or: [{{_and: [{{negated: {{_eq: false}}}}, {{object: {{objgrp_flats: {{objectByObjgrpFlatMemberId: {{ {ipFilterString} }}}}}}}}]}}, + {{_and: [{{negated: {{_eq: true}}}}, {{object: {{_not: {{objgrp_flats: {{objectByObjgrpFlatMemberId: {{ {ipFilterString} }}}}}}}}}}]}} + ]}} + }}, + {{ + rule_{location}_neg: {{_eq: true}}, + {locationTable}: {{ + _or: [{{_and: [{{negated: {{_eq: false}}}}, {{object: {{_not: {{objgrp_flats: {{objectByObjgrpFlatMemberId: {{ {ipFilterString} }}}}}}}}}}]}}, + {{_and: [{{negated: {{_eq: true}}}}, {{object: {{objgrp_flats: {{objectByObjgrpFlatMemberId: {{ {ipFilterString} }}}}}}}}]}} + ]}} + }}, + ] + "; + query.NwObjWhereStatement += + $@" {locationTable}: {{ + _or: [{{_and: [{{negated: {{_eq: false}}}}, {{object: {{objgrp_flats: {{objectByObjgrpFlatMemberId: {{ {ipFilterString} }}}}}}}}]}}, + {{_and: [{{negated: {{_eq: true}}}}, {{object: {{_not: {{objgrp_flats: {{objectByObjgrpFlatMemberId: {{ {ipFilterString} }}}}}}}}}}]}} + ] + }}"; + ExtractIpFilterForConn(query, location, QueryVarNameFirst1, QueryVarNameLast2); } - // functions["Disabled"] = this.ExtractDisabled; - // private DynGraphqlQuery ExtractDisabledQuery(DynGraphqlQuery query) - // { - // string QueryOperation = SetQueryOpString(Operator, Name, Value); - - // if (QueryOperation == null) - // { - // QueryOperation = EQ; - // } - // if (isCidr(Value)) // filtering for ip addresses - // query = ExtractIpFilter(query, location: "src", locationTable: "rule_froms"); - // else // string search against src obj name - // { - // string QueryVarName = "src" + query.parameterCounter++; - // query.QueryVariables[QueryVarName] = $"%{Value}%"; - // query.QueryParameters.Add($"${QueryVarName}: String! "); - // query.ruleWhereStatement += $"rule_froms: {{ object: {{ objgrp_flats: {{ objectByObjgrpFlatMemberId: {{ obj_name: {{ {QueryOperation}: ${QueryVarName} }} }} }} }} }}"; - // } - // return query; - // } // functions["SourceNegated"] = this.ExtractSourceNegated; - // // functions["DestinationNegated"] = this.ExtractDestinationNegated; - // // functions["ServiceNegated"] = this.ExtractServiceNegated; + private static void ExtractIpFilterForConn(DynGraphqlQuery query, string location, string QueryVarNameFirst1, string QueryVarNameLast2) + { + string ipFilterString = $@" ip_end: {{ _gte: ${QueryVarNameFirst1} }} ip: {{ _lte: ${QueryVarNameLast2} }}"; + int conField = location == "src" ? 1 : 2; + string nwObjString = $"{{ nwobject_connections: {{connection_field: {{ _eq: {conField} }}, owner_network: {{ {ipFilterString} }} }} }}"; + string nwGrpString = $"{{ nwgroup_connections: {{connection_field: {{ _eq: {conField} }}, nwgroup: {{ nwobject_nwgroups: {{ owner_network: {{ {ipFilterString} }} }} }} }} }}"; + query.ConnectionWhereStatement += $@" _or: [{nwObjString}, {nwGrpString}]"; + } } } diff --git a/roles/lib/files/FWO.Report.Filter/Ast/AstNodeFilterReportType.cs b/roles/lib/files/FWO.Report.Filter/Ast/AstNodeFilterReportType.cs index feb6038589..e57e72f716 100644 --- a/roles/lib/files/FWO.Report.Filter/Ast/AstNodeFilterReportType.cs +++ b/roles/lib/files/FWO.Report.Filter/Ast/AstNodeFilterReportType.cs @@ -1,4 +1,6 @@ -using FWO.Report.Filter.Exceptions; +using FWO.Report.Filter.Exceptions; +using FWO.Basics; + namespace FWO.Report.Filter.Ast { @@ -21,6 +23,10 @@ public override void ConvertToSemanticType() "resolvedchangestech" or "resolvedchangetech" => ReportType.ResolvedChangesTech, "natrules" or "nat_rules" => ReportType.NatRules, "recertifications" or "recertification" => ReportType.Recertification, + "connections" or "connection" => ReportType.Connections, + "apprules" or "apprule" => ReportType.AppRules, + "variances" or "variance" => ReportType.VarianceAnalysis, + "ownerrecertifications" or "ownerrecertification" => ReportType.OwnerRecertification, _ => throw new SemanticException($"Unexpected report type found", Value.Position) }; } @@ -39,17 +45,14 @@ public override void Extract(ref DynGraphqlQuery query, ReportType? reportType) } } - private DynGraphqlQuery ExtractReportTypeFilter(DynGraphqlQuery query) + private void ExtractReportTypeFilter(DynGraphqlQuery query) { query.ReportType = semanticValue; if (query.ReportType == ReportType.Statistics) { - query.ruleWhereStatement += - @$"rule_head_text: {{_is_null: true}}"; + query.RuleWhereStatement += @$"rule_head_text: {{_is_null: true}}"; } - - return query; } } } diff --git a/roles/lib/files/FWO.Report.Filter/Ast/AstNodeFilterString.cs b/roles/lib/files/FWO.Report.Filter/Ast/AstNodeFilterString.cs index bbc56f4ade..056d3f2e79 100644 --- a/roles/lib/files/FWO.Report.Filter/Ast/AstNodeFilterString.cs +++ b/roles/lib/files/FWO.Report.Filter/Ast/AstNodeFilterString.cs @@ -1,8 +1,6 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; +using FWO.Basics; +using FWO.Report.Filter.Exceptions; + namespace FWO.Report.Filter.Ast { @@ -12,7 +10,14 @@ internal class AstNodeFilterString : AstNodeFilter public override void ConvertToSemanticType() { - CheckOperator(Operator, false, TokenKind.EQ, TokenKind.EEQ, TokenKind.NEQ); + if (Name.Kind == TokenKind.OwnerState) + { + CheckOperator(Operator, false, TokenKind.EQ, TokenKind.EEQ, TokenKind.NEQ, TokenKind.LSS, TokenKind.GRT); + } + else + { + CheckOperator(Operator, false, TokenKind.EQ, TokenKind.EEQ, TokenKind.NEQ); + } semanticValue = Value.Text; } @@ -42,35 +47,97 @@ public override void Extract(ref DynGraphqlQuery query, ReportType? reportType) case TokenKind.Gateway: ExtractGatewayFilter(query); break; + case TokenKind.OwnerState: + ExtractOwnerStateFilter(query); + break; + case TokenKind.Criticality: + ExtractOwnerCriticalityFilter(query); + break; default: break; } } - private DynGraphqlQuery ExtractFullTextFilter(DynGraphqlQuery query) + private void ExtractFullTextFilter(DynGraphqlQuery query) { - string queryVarName = AddVariable(query, "fullTextFiler", Operator.Kind, semanticValue!); + string queryVarName = AddVariable(query, "fullTextFilter", Operator.Kind, semanticValue!); string queryOperator = ExtractOperator(); - List ruleFieldNames = new List() { "rule_src", "rule_dst", "rule_svc", "rule_action" }; // TODO: add comment later - List searchParts = new List(); + ExtractToRuleFilter(query, queryVarName, queryOperator); + ExtractToConnFilter(query, queryVarName, queryOperator); + ExtractToOwnerFilter(query, queryVarName, queryOperator); + } + + private static void ExtractToRuleFilter(DynGraphqlQuery query, string queryVarName, string queryOperator) + { + List ruleFieldNames = ["rule_src", "rule_dst", "rule_svc", "rule_action", "rule_name", "rule_comment", "rule_uid"]; + List ruleSearchParts = []; foreach (string field in ruleFieldNames) - searchParts.Add($"{{{field}: {{{queryOperator}: ${queryVarName} }} }} "); - query.ruleWhereStatement += $"_or: [ {string.Join(", ", searchParts)} ]"; - return query; + { + ruleSearchParts.Add($"{{{field}: {{{queryOperator}: ${queryVarName} }} }} "); + } + query.RuleWhereStatement += $"_or: [ {string.Join(", ", ruleSearchParts)} ]"; + } + + private static void ExtractToConnFilter(DynGraphqlQuery query, string queryVarName, string queryOperator) + { + List connFieldNames = ["name", "reason" /*, "creator" */]; + List nwobjFieldNames = ["name" /*, "creator" */]; + List nwGroupFieldNames = ["id_string", "name", "comment" /*, "creator" */]; + List svcFieldNames = ["name"]; + List svcGroupFieldNames = ["name", "comment" /*, "creator" */]; + List connSearchParts = []; + foreach (string field in connFieldNames) + { + connSearchParts.Add($"{{{field}: {{{queryOperator}: ${queryVarName} }} }} "); + } + foreach (string field in nwobjFieldNames) + { + connSearchParts.Add($"{{ nwobject_connections: {{owner_network: {{{field}: {{{queryOperator}: ${queryVarName} }} }} }} }} "); + } + foreach (string field in nwGroupFieldNames) + { + connSearchParts.Add($"{{ nwgroup_connections: {{nwgroup: {{{field}: {{{queryOperator}: ${queryVarName} }} }} }} }} "); + } + foreach (string field in svcFieldNames) + { + connSearchParts.Add($"{{ service_connections: {{service: {{{field}: {{{queryOperator}: ${queryVarName} }} }} }} }} "); + } + foreach (string field in svcGroupFieldNames) + { + connSearchParts.Add($"{{ service_group_connections: {{service_group: {{{field}: {{{queryOperator}: ${queryVarName} }} }} }} }} "); + } + query.ConnectionWhereStatement += $"_or: [ {string.Join(", ", connSearchParts)} ]"; } - private DynGraphqlQuery ExtractGatewayFilter(DynGraphqlQuery query) + private static void ExtractToOwnerFilter(DynGraphqlQuery query, string queryVarName, string queryOperator) + { + List ownerFieldNames = ["name", "last_recertifier_dn"]; + List ownerResponsibleFieldNames = ["dn"]; + List recertFieldNames = ["user_dn", "comment"]; + List ownerSearchParts = []; + foreach (string field in ownerFieldNames) + { + ownerSearchParts.Add($"{{{field}: {{{queryOperator}: ${queryVarName} }} }} "); + } + foreach (string field in ownerResponsibleFieldNames) + { + ownerSearchParts.Add($"{{owner_responsibles: {{{field}: {{{queryOperator}: ${queryVarName} }} }} }} "); + } + foreach (string field in recertFieldNames) + { + ownerSearchParts.Add($"{{owner_recertifications: {{{field}: {{{queryOperator}: ${queryVarName} }} }} }} "); + } + query.OwnerWhereStatement += $"_or: [ {string.Join(", ", ownerSearchParts)} ]"; + } + + private void ExtractGatewayFilter(DynGraphqlQuery query) { string queryVarName = AddVariable(query, "gwName", Operator.Kind, semanticValue); - query.ruleWhereStatement += $"device: {{dev_name : {{{ExtractOperator()}: ${queryVarName} }} }}"; - // query.nwObjWhereStatement += $"device: {{dev_name : {{{QueryOperation}: ${QueryVarName} }} }}"; - // query.svcObjWhereStatement += $"device: {{dev_name : {{{QueryOperation}: ${QueryVarName} }} }}"; - // query.userObjWhereStatement += $"device: {{dev_name : {{{QueryOperation}: ${QueryVarName} }} }}"; - return query; + query.RuleWhereStatement += $"device: {{dev_name : {{{ExtractOperator()}: ${queryVarName} }} }}"; } - private DynGraphqlQuery ExtractManagementFilter(DynGraphqlQuery query) + private void ExtractManagementFilter(DynGraphqlQuery query) { string queryOperation = ExtractOperator(); string queryFilterValue; @@ -86,32 +153,72 @@ private DynGraphqlQuery ExtractManagementFilter(DynGraphqlQuery query) queryVarName = AddVariable(query, "mgmName", Operator.Kind, semanticValue!); queryFilterValue = "mgm_name"; } - query.ruleWhereStatement += $"management: {{{queryFilterValue} : {{{queryOperation}: ${queryVarName} }} }}"; - query.nwObjWhereStatement += $"management: {{{queryFilterValue} : {{{queryOperation}: ${queryVarName} }} }}"; - query.svcObjWhereStatement += $"management: {{{queryFilterValue} : {{{queryOperation}: ${queryVarName} }} }}"; - query.userObjWhereStatement += $"management: {{{queryFilterValue} : {{{queryOperation}: ${queryVarName} }} }}"; - return query; + query.RuleWhereStatement += $"management: {{{queryFilterValue} : {{{queryOperation}: ${queryVarName} }} }}"; + query.NwObjWhereStatement += $"management: {{{queryFilterValue} : {{{queryOperation}: ${queryVarName} }} }}"; + query.SvcObjWhereStatement += $"management: {{{queryFilterValue} : {{{queryOperation}: ${queryVarName} }} }}"; + query.UserObjWhereStatement += $"management: {{{queryFilterValue} : {{{queryOperation}: ${queryVarName} }} }}"; } - private DynGraphqlQuery ExtractProtocolFilter(DynGraphqlQuery query) + private void ExtractProtocolFilter(DynGraphqlQuery query) { string queryVarName = AddVariable(query, "proto", Operator.Kind, semanticValue!); - query.ruleWhereStatement += $"rule_services: {{service: {{stm_ip_proto: {{ip_proto_name: {{ {ExtractOperator()}: ${queryVarName} }} }} }} }}"; - return query; + query.RuleWhereStatement += $"rule_services: {{service: {{stm_ip_proto: {{ip_proto_name: {{ {ExtractOperator()}: ${queryVarName} }} }} }} }}"; + query.ConnectionWhereStatement += $"_or: [ {{ service_connections: {{service: {{stm_ip_proto: {{ip_proto_name: {{ {ExtractOperator()}: ${queryVarName} }} }} }} }} }}, " + + $"{{ service_group_connections: {{service_group: {{ service_service_groups: {{ service: {{ stm_ip_proto: {{ip_proto_name: {{ {ExtractOperator()}: ${queryVarName} }} }} }} }} }} }} }} ]"; } - private DynGraphqlQuery ExtractActionFilter(DynGraphqlQuery query) + private void ExtractActionFilter(DynGraphqlQuery query) { string queryVarName = AddVariable(query, "action", Operator.Kind, semanticValue!); - query.ruleWhereStatement += $"rule_action: {{ {ExtractOperator()}: ${queryVarName} }}"; - return query; + query.RuleWhereStatement += $"rule_action: {{ {ExtractOperator()}: ${queryVarName} }}"; } - private DynGraphqlQuery ExtractServiceFilter(DynGraphqlQuery query) + private void ExtractServiceFilter(DynGraphqlQuery query) { string queryVarName = AddVariable(query, "svc", Operator.Kind, semanticValue!); - query.ruleWhereStatement += $"rule_services: {{service: {{svcgrp_flats: {{serviceBySvcgrpFlatMemberId: {{svc_name: {{ {ExtractOperator()}: ${queryVarName} }} }} }} }} }}"; - return query; + query.RuleWhereStatement += $"rule_services: {{ service: {{ svc_name: {{ {ExtractOperator()}: ${queryVarName} }} }} }} "; + query.ConnectionWhereStatement += $"_or: [ {{ service_connections: {{ service: {{ name: {{ {ExtractOperator()}: ${queryVarName} }} }} }} }}, " + + $"{{ service_group_connections: {{service_group: {{ _or: [ {{ name: {{ {ExtractOperator()}: ${queryVarName} }} }}, " + + $"{{ service_service_groups: {{ service: {{ name: {{ {ExtractOperator()}: ${queryVarName} }} }} }} }} ] }} }} }} ]"; + } + + private void ExtractOwnerCriticalityFilter(DynGraphqlQuery query) + { + string queryVarName = AddVariable(query, "ownerCriticality", Operator.Kind, semanticValue!); + query.OwnerWhereStatement += $"criticality: {{ {ExtractOperator()}: ${queryVarName} }}"; + } + + private void ExtractOwnerStateFilter(DynGraphqlQuery query) + { + if (int.TryParse(semanticValue, out int stateId)) + { + string queryVarName = AddNumericVariable(query, "ownerLifeCycleStateId", stateId); + query.OwnerWhereStatement += $"owner_lifecycle_state_id: {{ {ExtractNumericOperator()}: ${queryVarName} }}"; + return; + } + + string queryVarNameForName = AddVariable(query, "ownerLifeCycleStateName", Operator.Kind, semanticValue!); + query.OwnerWhereStatement += $"owner_lifecycle_state: {{ name: {{ {ExtractOperator()}: ${queryVarNameForName} }} }}"; + } + + private string ExtractNumericOperator() + { + return Operator.Kind switch + { + TokenKind.EQ or TokenKind.EEQ => "_eq", + TokenKind.NEQ => "_neq", + TokenKind.LSS => "_lt", + TokenKind.GRT => "_gt", + _ => throw new SemanticException("Invalid numeric operator.", Operator.Position), + }; + } + + private static string AddNumericVariable(DynGraphqlQuery query, string name, int value) + { + string queryVarName = name + query.parameterCounter++; + query.QueryParameters.Add($"${queryVarName}: Int! "); + query.QueryVariables[queryVarName] = value; + return queryVarName; } } } diff --git a/roles/lib/files/FWO.Report.Filter/Ast/AstNodeFilterWorkflow.cs b/roles/lib/files/FWO.Report.Filter/Ast/AstNodeFilterWorkflow.cs new file mode 100644 index 0000000000..e810aa7e18 --- /dev/null +++ b/roles/lib/files/FWO.Report.Filter/Ast/AstNodeFilterWorkflow.cs @@ -0,0 +1,131 @@ +using FWO.Basics; +using FWO.Data.Report; +using FWO.Data.Workflow; +using FWO.Report.Filter.Exceptions; + +namespace FWO.Report.Filter.Ast +{ + internal class AstNodeFilterWorkflow : AstNodeFilter + { + private static readonly HashSet AllowedPhases = + [ + "closed", + "request", + "approval", + "planning", + "verification", + "implementation", + "review", + "recertification" + ]; + + private List semanticTaskTypes = []; + private List semanticStates = []; + private string semanticPhase = ""; + private WorkflowReferenceDate semanticReferenceDate = WorkflowReferenceDate.AnyActivity; + + public override void ConvertToSemanticType() + { + CheckOperator(Operator, true, TokenKind.EQ, TokenKind.EEQ); + + switch (Name.Kind) + { + case TokenKind.TaskType: + semanticTaskTypes = ParseTaskTypes(Value.Text, Value.Position); + break; + case TokenKind.States: + semanticStates = ParseStates(Value.Text, Value.Position); + break; + case TokenKind.Phase: + semanticPhase = ParsePhase(Value.Text, Value.Position); + break; + case TokenKind.ReferenceDate: + semanticReferenceDate = ParseReferenceDate(Value.Text, Value.Position); + break; + default: + throw new SemanticException($"Unexpected workflow filter token: {Name.Kind}", Name.Position); + } + } + + public override void Extract(ref DynGraphqlQuery query, ReportType? reportType) + { + ConvertToSemanticType(); + + switch (Name.Kind) + { + case TokenKind.TaskType: + query.WorkflowTaskTypes = [.. semanticTaskTypes]; + break; + case TokenKind.States: + query.WorkflowStateIds = [.. semanticStates]; + break; + case TokenKind.Phase: + query.WorkflowPhase = semanticPhase; + break; + case TokenKind.ReferenceDate: + query.WorkflowReferenceDateFilter = semanticReferenceDate; + break; + } + } + + private static List ParseTaskTypes(string valueText, Range position) + { + List taskTypes = []; + foreach (string rawTaskType in SplitCsv(valueText)) + { + if (!Enum.TryParse(rawTaskType, true, out WfTaskType taskType) || taskType == WfTaskType.master) + { + throw new SemanticException($"Unexpected workflow task type found: {rawTaskType}", position); + } + if (!taskTypes.Contains(taskType)) + { + taskTypes.Add(taskType); + } + } + return taskTypes; + } + + private static List ParseStates(string valueText, Range position) + { + List stateIds = []; + foreach (string rawStateId in SplitCsv(valueText)) + { + if (!int.TryParse(rawStateId, out int stateId)) + { + throw new SemanticException($"Unexpected workflow state found: {rawStateId}", position); + } + if (!stateIds.Contains(stateId)) + { + stateIds.Add(stateId); + } + } + return stateIds; + } + + private static string ParsePhase(string valueText, Range position) + { + string normalizedPhase = valueText.Trim().ToLowerInvariant(); + if (!AllowedPhases.Contains(normalizedPhase)) + { + throw new SemanticException($"Unexpected workflow phase found: {valueText}", position); + } + return normalizedPhase; + } + + private static WorkflowReferenceDate ParseReferenceDate(string valueText, Range position) + { + if (!Enum.TryParse(valueText.Trim(), true, out WorkflowReferenceDate referenceDate)) + { + throw new SemanticException($"Unexpected workflow reference date found: {valueText}", position); + } + return referenceDate; + } + + private static IEnumerable SplitCsv(string valueText) + { + return valueText + .Split(',', StringSplitOptions.RemoveEmptyEntries | StringSplitOptions.TrimEntries) + .Where(value => !string.IsNullOrWhiteSpace(value)); + } + } +} diff --git a/roles/lib/files/FWO.Report.Filter/Ast/AstNodeUnary.cs b/roles/lib/files/FWO.Report.Filter/Ast/AstNodeUnary.cs index e205235da9..2b7b2b9643 100644 --- a/roles/lib/files/FWO.Report.Filter/Ast/AstNodeUnary.cs +++ b/roles/lib/files/FWO.Report.Filter/Ast/AstNodeUnary.cs @@ -1,4 +1,7 @@ -namespace FWO.Report.Filter.Ast +using FWO.Basics; + + +namespace FWO.Report.Filter.Ast { class AstNodeUnary : AstNode { @@ -8,13 +11,13 @@ class AstNodeUnary : AstNode public override void Extract(ref DynGraphqlQuery query, ReportType? reportType) { - query.ruleWhereStatement += Operator.Kind switch + query.RuleWhereStatement += Operator.Kind switch { TokenKind.Not => "_not: {", _ => throw new NotSupportedException($"### Compiler Error: Found unexpected and unsupported unary token \"{Operator}\" ###"), }; Value?.Extract(ref query, reportType); - query.ruleWhereStatement += "}"; + query.RuleWhereStatement += "}"; } } } diff --git a/roles/lib/files/FWO.Report.Filter/Compiler.cs b/roles/lib/files/FWO.Report.Filter/Compiler.cs index 0af7c94350..629fecd674 100644 --- a/roles/lib/files/FWO.Report.Filter/Compiler.cs +++ b/roles/lib/files/FWO.Report.Filter/Compiler.cs @@ -1,27 +1,32 @@ -using FWO.Report.Filter.Ast; -using FWO.Api.Data; +using FWO.Data.Report; using FWO.Logging; +using FWO.Report.Filter.Ast; +using FWO.Basics; namespace FWO.Report.Filter { - public class Compiler + public static class Compiler { public static AstNode? CompileToAst(string input) { - Scanner scanner = new Scanner(input); + Scanner scanner = new(input); List tokens = scanner.Scan(); - if(tokens.Count > 0) + if (tokens.Count > 0) { - Parser parser = new Parser(tokens); + Parser parser = new(tokens); return parser.Parse(); } else return null; } - public static DynGraphqlQuery Compile(ReportTemplate filter) + public static DynGraphqlQuery Compile(ReportTemplate template) { - Log.WriteDebug("Filter", $"Input: \"{filter.Filter}\", Report Type: \"${filter.ReportParams.ReportType}\", Device Filter: \"{filter.ReportParams.DeviceFilter}\""); - return DynGraphqlQuery.GenerateQuery(filter, CompileToAst(filter.Filter)); + ReportType reportType = (ReportType)template.ReportParams.ReportType; + string deviceFilterLogPart = reportType.IsDeviceRelatedReport() + ? $", Device Filter: \"{template.ReportParams.DeviceFilter}\"" + : ""; + Log.WriteDebug("Filter", $"Input: \"{template.Filter}\", Report Type: \"${template.ReportParams.ReportType}\"{deviceFilterLogPart}"); + return DynGraphqlQuery.GenerateQuery(template, CompileToAst(template.Filter)); } } } diff --git a/roles/lib/files/FWO.Report.Filter/DynGraphqlQuery.cs b/roles/lib/files/FWO.Report.Filter/DynGraphqlQuery.cs index fc5382cc05..4e3e9843d8 100644 --- a/roles/lib/files/FWO.Report.Filter/DynGraphqlQuery.cs +++ b/roles/lib/files/FWO.Report.Filter/DynGraphqlQuery.cs @@ -1,70 +1,770 @@ using FWO.Report.Filter.Ast; using FWO.Api.Client.Queries; -using FWO.Api.Data; +using FWO.Data; +using FWO.Data.Report; +using FWO.Data.Workflow; using System.Text.RegularExpressions; using FWO.Logging; +using FWO.Basics; + namespace FWO.Report.Filter { - public class DynGraphqlQuery + public class DynGraphqlQuery(string rawInput) { - public string RawFilter { get; private set; } - - public int parameterCounter = 0; - public Dictionary QueryVariables { get; set; } = new Dictionary(); + public string RawFilter { get; private set; } = rawInput; + public int parameterCounter { get; set; } = 0; + public Dictionary QueryVariables { get; set; } = []; public string FullQuery { get; set; } = ""; - public string ruleWhereStatement { get; set; } = ""; - public string nwObjWhereStatement { get; set; } = ""; - public string svcObjWhereStatement { get; set; } = ""; - public string userObjWhereStatement { get; set; } = ""; - public List QueryParameters { get; set; } = new List() - { + public string RulebaseLinkWhereStatement { get; set; } = ""; + public string RuleWhereStatement { get; set; } = ""; + public string NwObjWhereStatement { get; set; } = ""; + public string SvcObjWhereStatement { get; set; } = ""; + public string UserObjWhereStatement { get; set; } = ""; + public string ConnectionWhereStatement { get; set; } = ""; + public string OwnerWhereStatement { get; set; } = ""; + public string OpenRuleBaseTable { get; set; } = $@" rulebase_links ("; + public string OpenRulesTable { get; set; } = $@" rules ("; + public string OpenChangeLogRulesTable { get; set; } = "changelog_rules("; + public List QueryParameters { get; set; } = + [ " $limit: Int ", " $offset: Int ", - " $mgmId: [Int!]" // not needed for change reports?? - }; + " $active: Boolean ", + ]; public string ReportTimeString { get; set; } = ""; - public List RelevantManagementIds { get; set; } = new List(); + public List RelevantManagementIds { get; set; } = []; + public List WorkflowTaskTypes { get; set; } = []; + public List WorkflowStateIds { get; set; } = []; + public string WorkflowPhase { get; set; } = ""; + public WorkflowReferenceDate? WorkflowReferenceDateFilter { get; set; } public ReportType ReportType { get; set; } = ReportType.Rules; + public FwoOwner? SelectedOwner { get; set; } + public const string fullTimeFormat = "yyyy-MM-dd HH:mm:ss"; + public const string dateFormat = "yyyy-MM-dd"; + public const int layerRecursionLevel = 2; + + const string mgmtWhereString = $@"where: {{ hide_in_gui: {{_eq: false }} + mgm_id: {{_in: $mgmId }} + stm_dev_typ: {{dev_typ_is_multi_mgmt: {{_eq: false}} is_pure_routing_device: {{_eq: false}} }} + }} order_by: {{ mgm_name: asc }}"; + + const string devWhereStringStart = $@"where: {{ hide_in_gui: {{_eq: false }}, + stm_dev_typ: {{is_pure_routing_device:{{_eq:false}} }}"; + const string devWhereStringEnd = $@"}} order_by: {{ dev_name: asc }}"; + const string devWhereStringDefault = devWhereStringStart + devWhereStringEnd; + + const string limitOffsetString = $@"limit: $limit + offset: $offset "; + + + public static DynGraphqlQuery GenerateQuery(ReportTemplate filter, AstNode? ast) + { + DynGraphqlQuery query = new(filter.Filter); + ConstructWhereStatements(query, filter, ast); + if (((ReportType)filter.ReportParams.ReportType).IsResolvedReport() || (ReportType)filter.ReportParams.ReportType == ReportType.AppRules) + { + filter.Detailed = true; + } + ConstructFullQuery(query, filter); + OverwriteMissingTenantFilters(ref query, filter); + query.FullQuery = RemoveUnnecessaryWhitespaces(query.FullQuery); + return query; + } + + private static string RemoveUnnecessaryWhitespaces(string queryString) + { + string pattern = @"\n"; + TimeSpan timeout = TimeSpan.FromSeconds(1); + string cleanQuery = Regex.Replace(queryString, pattern, "", RegexOptions.None, timeout); + pattern = @"\s+"; + return Regex.Replace(cleanQuery, pattern, " ", RegexOptions.None, timeout); + } + + private static void ConstructWhereStatements(DynGraphqlQuery query, ReportTemplate filter, AstNode? ast) + { + query.RuleWhereStatement += "_and: ["; + query.ConnectionWhereStatement += "_and: ["; + query.OwnerWhereStatement += "_and: ["; + + SetFixedFilters(ref query, filter); + + query.RuleWhereStatement += "{"; + query.ConnectionWhereStatement += "{"; + query.OwnerWhereStatement += "{"; + + if ((ReportType)filter.ReportParams.ReportType == ReportType.Changes || (ReportType)filter.ReportParams.ReportType == ReportType.ResolvedChanges || (ReportType)filter.ReportParams.ReportType == ReportType.ResolvedChangesTech) + { + query.RuleWhereStatement += "rule: {"; + } + // now we convert the ast into a graphql query: + ast?.Extract(ref query, (ReportType)filter.ReportParams.ReportType); + // TODO: remove rule dev filtering for rework + + if ((ReportType)filter.ReportParams.ReportType == ReportType.Changes || (ReportType)filter.ReportParams.ReportType == ReportType.ResolvedChanges || (ReportType)filter.ReportParams.ReportType == ReportType.ResolvedChangesTech) + { + query.RuleWhereStatement += "}"; + } + + query.RuleWhereStatement += "}] "; + query.ConnectionWhereStatement += "}] "; + query.OwnerWhereStatement += "}] "; + } + + private static string ConstructStatisticsQuery(DynGraphqlQuery query, string paramString) + { + var insertIndex = query.RuleWhereStatement.LastIndexOf(']'); + var unusedRulesWhereStatement = insertIndex >= 0 + ? query.RuleWhereStatement.Insert(insertIndex, ", {rule_metadatum: { rule_last_hit: { _is_null: true }}}") + : query.RuleWhereStatement; + return $@" + query statisticsReport ({paramString}) + {{ + management({mgmtWhereString}) + {{ + name: mgm_name + id: mgm_id + objects_aggregate(where: {{ {query.NwObjWhereStatement} }}) {{ aggregate {{ count }} }} + services_aggregate(where: {{ {query.SvcObjWhereStatement} }}) {{ aggregate {{ count }} }} + usrs_aggregate(where: {{ {query.UserObjWhereStatement} }}) {{ aggregate {{ count }} }} + rules_aggregate(where: {{ {query.RuleWhereStatement} }}) {{ aggregate {{ count }} }} + unusedRules_Count: rules_aggregate(where: {{ {unusedRulesWhereStatement}}}) {{ aggregate {{ count }} }} + devices( {devWhereStringDefault} ) + {{ + name: dev_name + id: dev_id + rules_aggregate: management {{ rules_aggregate(where: {{ {query.RuleWhereStatement} }}) {{ aggregate {{ count }} }} }} + unusedRules_Count: management {{ rules_aggregate(where: {{ {unusedRulesWhereStatement} }}) {{ aggregate {{ count }} }} }} + }} + }} + }}"; + //TODO: show number of rulebase links per gateway ? + } + + private static string ConstructRulesQuery(DynGraphqlQuery query, string paramString, ReportTemplate filter) + { + return $@" + {GetRulesFragmentDef(filter)} + query rulesReport ({paramString}) + {{ + management({mgmtWhereString}) + {{ + id: mgm_id + uid: mgm_uid + name: mgm_name + devices ({GetDevWhereFilter(filter.ReportParams.DeviceFilter)}) + {{ + id: dev_id + name: dev_name + uid: dev_uid + {query.OpenRuleBaseTable} + where: {{ {query.RulebaseLinkWhereStatement} }} + ) {{ + linkType: stm_link_type {{ + name + id + }} + link_type + is_initial + is_global + is_section + gw_id + from_rule_id + from_rulebase_id + to_rulebase_id + created + removed + }} + }} + rulebases {{ + name + uid + id + {query.OpenRulesTable} + {limitOffsetString} + where: {{ access_rule: {{_eq: true}} {query.RuleWhereStatement} }} + order_by: {{ rule_num_numeric: asc }} ) + {{ + mgm_id: mgm_id + {((ReportType)filter.ReportParams.ReportType == ReportType.UnusedRules ? "rule_metadatum { rule_last_hit }" : "")} + ...{GetRulesFragmentCall(filter)} + }} + }} + }} + }}"; + } + + private static string GetRulesFragmentDef(ReportTemplate filter) + { + if ((ReportType)filter.ReportParams.ReportType == ReportType.AppRules) + { + return RuleQueries.ruleDetailsForAppRuleReportFragments; + } + return filter.Detailed ? RuleQueries.ruleDetailsForReportFragments : RuleQueries.ruleOverviewFragments; + } + + private static string GetRulesFragmentCall(ReportTemplate filter) + { + if ((ReportType)filter.ReportParams.ReportType == ReportType.AppRules) + { + return "ruleDetailsForAppRuleReport"; + } + return filter.Detailed ? "ruleDetailsForReport" : "ruleOverview"; + } + + private static string ConstructRecertQuery(DynGraphqlQuery query, string paramString) + { + return $@" + {RecertQueries.ruleOpenRecertFragments} + query rulesCertReport({paramString}) + {{ + management({mgmtWhereString}) + {{ + id: mgm_id + name: mgm_name + devices({devWhereStringDefault}) + {{ + id: dev_id + name: dev_name + rulebase_links(where: {{ {query.RulebaseLinkWhereStatement} }}) + {{ + linkType: stm_link_type {{ + name + id + }} + link_type + is_initial + is_global + is_section + gw_id + from_rule_id + from_rulebase_id + to_rulebase_id + created + removed + }} + }} + rulebases {{ + id + uid + name + {query.OpenRulesTable} + where: {{ + rule_metadatum: {{ recertifications_aggregate: {{ count: {{ filter: {{ _and: [{{owner: $ownerWhere}}, {{recert_date: {{_is_null: true}}}}, {{next_recert_date: {{_lte: $refdate1}}}}]}}, predicate: {{_gt: 0}}}}}}}} + active:{{ _eq:true }} + {query.RuleWhereStatement} + }} + {limitOffsetString} + order_by: {{ rule_num_numeric: asc }} + ) + {{ + mgm_id: mgm_id + ...ruleOpenCertOverview + }} + }} + }} + }}"; + } + + + private static string changelogObjectsBlock = @" + changelog_objects: changelog_objects( + where: { + change_type_id: { _eq: 3 } + security_relevant: { _eq: true } + control_id: { _eq: $import_id_new } + }, + order_by: { control_id: asc } + ) + @include(if: $include_objects_in_changes_report) { + import: import_control { time: stop_time } + change_action + old: objectByOldObjId { + ...networkObjectDetailsChangesOld + } + new: object { + ...networkObjectDetailsChangesNew + } + } + changelog_services: changelog_services( + where: { + change_type_id: { _eq: 3 } + security_relevant: { _eq: true } + control_id: { _eq: $import_id_new } + }, + order_by: { control_id: asc } + ) + @include(if: $include_objects_in_changes_report) { + import: import_control { time: stop_time } + change_action + old: serviceByOldSvcId { + ...networkServiceDetailsChangesOld + } + new: service { + ...networkServiceDetailsChangesNew + } + } + changelog_users: changelog_users( + where: { + change_type_id: { _eq: 3 } + security_relevant: { _eq: true } + control_id: { _eq: $import_id_new } + }, + order_by: { control_id: asc } + ) + @include(if: $include_objects_in_changes_report) { + import: import_control { time: stop_time } + change_action + old: usrByOldUserId { + ...userDetailsChangesOld + } + new: usr { + ...userDetailsChangesNew + } + } + "; + + private static string ConstructChangesQuery(DynGraphqlQuery query, string paramString, ReportTemplate filter) + { + return $@" + {(filter.Detailed ? RuleQueries.ruleDetailsForChangeReportFragments : RuleQueries.ruleOverviewForChangeReportFragments)} + query changeReport({paramString}){{ + management(where: {{ + hide_in_gui: {{_eq: false }} + stm_dev_typ: {{dev_typ_is_multi_mgmt: {{_eq: false}}, is_pure_routing_device: {{_eq: false}} }} + mgm_id: {{_in: $mgmId }} + }} order_by: {{mgm_name: asc}}) + {{ + id: mgm_id + name: mgm_name + import_controls {{ + control_id + start_time + stop_time + successful_import + import_errors + }} + devices {{ + id: dev_id + name: dev_name + }} + changelog_rules: {query.OpenChangeLogRulesTable} + {limitOffsetString} + where: {{ + _or:[ + {{_and: [{{change_action:{{_eq:""I""}}}}, {{rule: {{access_rule:{{_eq:true}}}}}}]}}, + {{_and: [{{change_action:{{_eq:""D""}}}}, {{ruleByOldRuleId: {{access_rule:{{_eq:true}}}}}}]}}, + {{_and: [{{change_action:{{_eq:""C""}}}}, {{rule: {{access_rule:{{_eq:true}}}}}}, {{ruleByOldRuleId: {{access_rule:{{_eq:true}}}}}}]}} + ] + {query.RuleWhereStatement} + }} + order_by: {{ control_id: asc }} + ) + {{ + import: import_control {{ time: stop_time }} + change_action + old: ruleByOldRuleId {{ + ...{(filter.Detailed ? "ruleDetailsChangesOld" : "ruleOverviewChangesOld")} + + }} + new: rule {{ + ...{(filter.Detailed ? "ruleDetailsChangesNew" : "ruleOverviewChangesNew")} + }} + }} + {changelogObjectsBlock} + }} + }}"; + } + + private static string ConstructNatRulesQuery(DynGraphqlQuery query, string paramString, ReportTemplate filter) + { + return $@" + {(filter.Detailed ? RuleQueries.natRuleDetailsForReportFragments : RuleQueries.natRuleOverviewFragments)} + query natRulesReport ({paramString}) + {{ + management({mgmtWhereString}) + {{ + id: mgm_id + name: mgm_name + devices ({devWhereStringDefault}) + {{ + id: dev_id + name: dev_name + rulebase_links(where: {{ {query.RulebaseLinkWhereStatement} }}) + {{ + {query.OpenRulesTable} + {limitOffsetString} + where: {{ nat_rule: {{_eq: true}}, ruleByXlateRule: {{}} {query.RuleWhereStatement} }} + order_by: {{ rule_num_numeric: asc }} ) + {{ + mgm_id: mgm_id + ...{(filter.Detailed ? "natRuleDetails" : "natRuleOverview")} + }} + }} + }} + }} + }}"; + } + + private static string ConstructConnectionsQuery(DynGraphqlQuery query, string paramString) + { + return $@" + {ModellingQueries.connectionResolvedDetailsFragment} + query getConnectionsResolved ({paramString}) + {{ + modelling_connection (where: {{ {query.ConnectionWhereStatement} }} order_by: {{ is_interface: desc, common_service: desc, name: asc }}) + {{ + ...connectionResolvedDetails + }} + }}"; + } + + private static string ConstructOwnerQuery(DynGraphqlQuery query, string paramString, ReportType reportType) + { + string orderBy = reportType == ReportType.OwnerRecertification ? "next_recert_date: desc, name: asc" : "name: asc"; + return $@" + {OwnerQueries.ownerDetailsFragment} + query getOwners ({paramString}) + {{ + owner (where: {{ {query.OwnerWhereStatement} }} order_by: {{ {orderBy} }}) + {{ + ...ownerDetails + }} + }}"; + } + + private static void ConstructFullQuery(DynGraphqlQuery query, ReportTemplate filter) + { + string paramString = string.Join(" ", query.QueryParameters.ToArray()); + + switch ((ReportType)filter.ReportParams.ReportType) + { + case ReportType.Statistics: + query.FullQuery = Queries.Compact(ConstructStatisticsQuery(query, paramString)); + break; + + case ReportType.Rules: + case ReportType.ResolvedRules: + case ReportType.ResolvedRulesTech: + case ReportType.UnusedRules: + case ReportType.AppRules: + case ReportType.ComplianceReport: + case ReportType.ComplianceDiffReport: + case ReportType.RecertEventReport: + query.FullQuery = Queries.Compact(ConstructRulesQuery(query, paramString, filter)); + break; + + case ReportType.Recertification: + query.FullQuery = Queries.Compact(ConstructRecertQuery(query, paramString)); + break; + + case ReportType.Changes: + case ReportType.ResolvedChanges: + case ReportType.ResolvedChangesTech: + query.FullQuery = Queries.Compact(ConstructChangesQuery(query, paramString, filter)); + break; + + case ReportType.TicketReport: + query.FullQuery = Queries.Compact(ConstructTicketQuery(query, filter)); + break; + case ReportType.TicketChangeReport: + query.FullQuery = Queries.Compact(ConstructTicketChangesQuery(query, filter)); + break; + + case ReportType.NatRules: + query.FullQuery = Queries.Compact(ConstructNatRulesQuery(query, paramString, filter)); + break; + + case ReportType.Connections: + case ReportType.VarianceAnalysis: + case ReportType.RecertificationEvent: + query.FullQuery = Queries.Compact(ConstructConnectionsQuery(query, paramString)); + break; + + case ReportType.OwnerRecertification: + case ReportType.Owners: + query.FullQuery = Queries.Compact(ConstructOwnerQuery(query, paramString, (ReportType)filter.ReportParams.ReportType)); + break; + } + } + + private static string ConstructTicketQuery(DynGraphqlQuery query, ReportTemplate filter) + { + InitializeTicketQuery(query, filter); + return BuildTicketReportQuery("ticketReport", query.QueryParameters, BuildTicketFilters(query, filter)); + } + + private static string ConstructTicketChangesQuery(DynGraphqlQuery query, ReportTemplate filter) + { + InitializeTicketQuery(query, filter, true); + List ticketFilters = BuildTicketFilters(query, filter); + ticketFilters.Add(BuildTicketReferenceDateFilter(ResolveWorkflowReferenceDate(query, filter.ReportParams.WorkflowFilter))); + return BuildTicketReportQuery("ticketChangeReport", query.QueryParameters, ticketFilters); + } + + private static void InitializeTicketQuery(DynGraphqlQuery query, ReportTemplate filter, bool includeTimeRange = false) + { + query.QueryParameters = []; + query.QueryVariables = []; + + if (includeTimeRange) + { + query.QueryParameters.Add("$ticket_time_start: timestamp "); + query.QueryParameters.Add("$ticket_time_end: timestamp "); + (string ticketTimeStart, string ticketTimeEnd) = ResolveTimeRange(filter.ReportParams.TimeFilter); + query.QueryVariables["ticket_time_start"] = ticketTimeStart; + query.QueryVariables["ticket_time_end"] = ticketTimeEnd; + } + + query.QueryParameters.Add("$task_types: [String!] "); + query.QueryVariables["task_types"] = ResolveWorkflowTaskTypes(query, filter.ReportParams.WorkflowFilter).Select(taskType => taskType.ToString()).ToList(); + } + + private static List BuildTicketFilters(DynGraphqlQuery query, ReportTemplate filter) + { + List ticketFilters = ["{ reqtasks: { task_type: { _in: $task_types } } }"]; + List stateIds = ResolveWorkflowStateIds(query, filter.ReportParams.WorkflowFilter); + if (stateIds.Count > 0) + { + query.QueryParameters.Add("$state_ids: [Int!] "); + query.QueryVariables["state_ids"] = stateIds; + ticketFilters.Add("{ state_id: { _in: $state_ids } }"); + } + + if (!string.IsNullOrWhiteSpace(ResolveWorkflowPhase(query, filter.ReportParams.WorkflowFilter))) + { + query.QueryParameters.Add("$phase_lowest_input_state: Int! "); + if (string.Equals(ResolveWorkflowPhase(query, filter.ReportParams.WorkflowFilter), GlobalConst.kClosed, StringComparison.OrdinalIgnoreCase)) + { + ticketFilters.Add("{ state_id: { _gte: $phase_lowest_input_state } }"); + } + else + { + query.QueryParameters.Add("$phase_lowest_end_state: Int! "); + ticketFilters.Add("{ state_id: { _gte: $phase_lowest_input_state, _lt: $phase_lowest_end_state } }"); + } + } + + string? labelFilter = BuildTicketLabelFilter(query, filter.ReportParams.WorkflowFilter.LabelFilter); + if (!string.IsNullOrWhiteSpace(labelFilter)) + { + ticketFilters.Add(labelFilter); + } + + return ticketFilters; + } + + private static string BuildTicketReportQuery(string operationName, List queryParameters, List ticketFilters) + { + string paramString = string.Join(" ", queryParameters.ToArray()); + return $@" + {RequestQueries.ticketDetailsReqTaskOverviewFragment} + query {operationName} ({paramString}) + {{ + request_ticket( + where: {{ + _and: [ + {string.Join(",", ticketFilters)} + ] + }}, + order_by: {{ id: desc }} + ) {{ + ...ticketDetailsReqTaskOverview + }} + }}"; + } + + private static string BuildTicketReferenceDateFilter(WorkflowReferenceDate referenceDate) + { + return referenceDate switch + { + WorkflowReferenceDate.TicketCreation => "{ _and: [{ date_created: { _gte: $ticket_time_start } }, { date_created: { _lt: $ticket_time_end } }] }", + WorkflowReferenceDate.TicketClosure => "{ _and: [{ date_completed: { _gte: $ticket_time_start } }, { date_completed: { _lt: $ticket_time_end } }] }", + WorkflowReferenceDate.ApprovalOpened => "{ reqtasks: { approvals: { _and: [{ date_opened: { _gte: $ticket_time_start } }, { date_opened: { _lt: $ticket_time_end } }] } } }", + WorkflowReferenceDate.Approved => "{ reqtasks: { approvals: { _and: [{ approval_date: { _gte: $ticket_time_start } }, { approval_date: { _lt: $ticket_time_end } }] } } }", + WorkflowReferenceDate.TaskStart => "{ reqtasks: { _and: [{ start: { _gte: $ticket_time_start } }, { start: { _lt: $ticket_time_end } }] } }", + WorkflowReferenceDate.TaskEnd => "{ reqtasks: { _and: [{ stop: { _gte: $ticket_time_start } }, { stop: { _lt: $ticket_time_end } }] } }", + WorkflowReferenceDate.ImplementationStart => "{ reqtasks: { impltasks: { _and: [{ start: { _gte: $ticket_time_start } }, { start: { _lt: $ticket_time_end } }] } } }", + WorkflowReferenceDate.ImplementationEnd => "{ reqtasks: { impltasks: { _and: [{ stop: { _gte: $ticket_time_start } }, { stop: { _lt: $ticket_time_end } }] } } }", + WorkflowReferenceDate.AnyActivity => @"{ + _or: [ + { _and: [{ date_created: { _gte: $ticket_time_start } }, { date_created: { _lt: $ticket_time_end } }] }, + { _and: [{ date_completed: { _gte: $ticket_time_start } }, { date_completed: { _lt: $ticket_time_end } }] }, + { reqtasks: { _and: [{ start: { _gte: $ticket_time_start } }, { start: { _lt: $ticket_time_end } }] } }, + { reqtasks: { _and: [{ stop: { _gte: $ticket_time_start } }, { stop: { _lt: $ticket_time_end } }] } }, + { reqtasks: { impltasks: { _and: [{ start: { _gte: $ticket_time_start } }, { start: { _lt: $ticket_time_end } }] } } }, + { reqtasks: { impltasks: { _and: [{ stop: { _gte: $ticket_time_start } }, { stop: { _lt: $ticket_time_end } }] } } }, + { reqtasks: { approvals: { _and: [{ date_opened: { _gte: $ticket_time_start } }, { date_opened: { _lt: $ticket_time_end } }] } } }, + { reqtasks: { approvals: { _and: [{ approval_date: { _gte: $ticket_time_start } }, { approval_date: { _lt: $ticket_time_end } }] } } } + ] + }", + _ => "{ _and: [{ date_created: { _gte: $ticket_time_start } }, { date_created: { _lt: $ticket_time_end } }] }" + }; + } + + private static void SetFixedFilters(ref DynGraphqlQuery query, ReportTemplate reportParams) + { + ReportType reportType = (ReportType)reportParams.ReportParams.ReportType; + if (reportType.IsDeviceRelatedReport()) + { + query.QueryParameters.Add("$mgmId: [Int!] "); + } - public DynGraphqlQuery(string rawInput) { RawFilter = rawInput; } + // leave out all header texts + if (reportType == ReportType.Statistics || + reportType == ReportType.Recertification || + (reportType.IsRuleReport() && !string.IsNullOrWhiteSpace(reportParams.Filter))) + { + query.RuleWhereStatement += "{rule_head_text: {_is_null: true}}, "; + } + SetTenantFilter(ref query, reportParams); + if (reportType.IsDeviceRelatedReport()) + { + SetDeviceFilter(ref query, reportParams.ReportParams.DeviceFilter); + SetTimeFilter(ref query, reportParams.ReportParams.TimeFilter, reportType, reportParams.ReportParams.RecertFilter); + } + if (reportType == ReportType.Recertification) + { + SetRecertFilter(ref query, reportParams.ReportParams.RecertFilter); + } + if (reportType == ReportType.OwnerRecertification) + { + SetOwnerRecertFilter(ref query, reportParams.ReportParams.ModellingFilter, reportParams.ReportParams.RecertFilter); + } + if (reportType == ReportType.Owners) + { + SetOwnerListFilter(ref query, reportParams.ReportParams.OwnerFilter); + } + if (reportType == ReportType.UnusedRules) + { + SetUnusedFilter(ref query, reportParams.ReportParams.UnusedFilter); + } + if (reportType == ReportType.AppRules) + { + SetOwnerFilter(ref query, reportParams.ReportParams.ModellingFilter); + } + if (reportType.IsConnectionRelatedReport()) + { + SetConnectionFilter(ref query, reportParams.ReportParams.ModellingFilter); + } + if (reportType == ReportType.RecertEventReport) + { + SetRuleRecertFilter(ref query, reportParams.ReportParams.ModellingFilter); + } + } - public static string fullTimeFormat = "yyyy-MM-dd HH:mm:ss"; - public static string dateFormat = "yyyy-MM-dd"; + private static List ResolveWorkflowTaskTypes(DynGraphqlQuery query, WorkflowFilter workflowFilter) + { + return query.WorkflowTaskTypes.Count > 0 ? query.WorkflowTaskTypes : workflowFilter.TaskTypes; + } + + private static List ResolveWorkflowStateIds(DynGraphqlQuery query, WorkflowFilter workflowFilter) + { + return query.WorkflowStateIds.Count > 0 ? query.WorkflowStateIds : workflowFilter.StateIds; + } + + private static string ResolveWorkflowPhase(DynGraphqlQuery query, WorkflowFilter workflowFilter) + { + return string.IsNullOrWhiteSpace(query.WorkflowPhase) ? workflowFilter.Phase : query.WorkflowPhase; + } + + private static WorkflowReferenceDate ResolveWorkflowReferenceDate(DynGraphqlQuery query, WorkflowFilter workflowFilter) + { + return query.WorkflowReferenceDateFilter ?? workflowFilter.ReferenceDate; + } + + private static string? BuildTicketLabelFilter(DynGraphqlQuery query, WorkflowLabelFilter labelFilter) + { + if (string.IsNullOrWhiteSpace(labelFilter.Name)) + { + return null; + } + + return labelFilter.Mode switch + { + WorkflowLabelFilterMode.not_existing => BuildTicketLabelExistsFilter(query, labelFilter.Name, negate: true), + WorkflowLabelFilterMode.existing => BuildTicketLabelExistsFilter(query, labelFilter.Name, negate: false), + WorkflowLabelFilterMode.value => BuildTicketLabelValueFilter(query, labelFilter.Name, labelFilter.Value), + _ => null + }; + } + + private static string BuildTicketLabelExistsFilter(DynGraphqlQuery query, string labelName, bool negate) + { + string keyPatternVar = AddQueryVariable(query, "labelKeyPattern", "String", $"%\"{labelName}\":%"); + string filter = $"{{ reqtasks: {{ additional_info: {{ _ilike: ${keyPatternVar} }} }} }}"; + return negate ? $"{{ _not: {filter} }}" : filter; + } + + private static string BuildTicketLabelValueFilter(DynGraphqlQuery query, string labelName, string value) + { + string valuePatternVar = AddQueryVariable(query, "labelValuePattern", "String", $"%\"{labelName}\":\"{value}\"%"); + return $"{{ reqtasks: {{ additional_info: {{ _ilike: ${valuePatternVar} }} }} }}"; + } + + private static string AddQueryVariable(DynGraphqlQuery query, string name, string type, object value) + { + string queryVarName = name + query.parameterCounter++; + query.QueryParameters.Add($"${queryVarName}: {type}! "); + query.QueryVariables[queryVarName] = value; + return queryVarName; + } + + private static void SetRuleRecertFilter(ref DynGraphqlQuery query, ModellingFilter modellingFilter) + { + query.RuleWhereStatement += $" {{ rule_metadatum: {{ recertifications: {{ owner_recert_id: {{_eq: {modellingFilter.OwnerRecertId} }}, recertified: {{ _eq: true }} }} }} }}"; + } private static void SetDeviceFilter(ref DynGraphqlQuery query, DeviceFilter? deviceFilter) { - bool first = true; if (deviceFilter != null) { - query.RelevantManagementIds = deviceFilter.getSelectedManagements(); - query.ruleWhereStatement += "{_or: [{"; - foreach (ManagementSelect mgmt in deviceFilter.Managements) + query.RelevantManagementIds = deviceFilter.GetSelectedManagements(); + } + } + + private static string GetDevWhereFilter(DeviceFilter deviceFilter) + { + if (deviceFilter == null || deviceFilter.Managements == null) + { + return devWhereStringStart + devWhereStringEnd; + } + + string devWhereStatement = devWhereStringStart; + bool first = true; + + devWhereStatement += "_or: [{"; + + foreach (ManagementSelect mgmt in deviceFilter.Managements) + { + if (mgmt.Devices == null) continue; + + foreach (DeviceSelect dev in mgmt.Devices) { - foreach (DeviceSelect dev in mgmt.Devices) + if (dev.Selected) { - if (dev.Selected == true) + if (!first) { - if (first == false) - { - query.ruleWhereStatement += "}, {"; - } - query.ruleWhereStatement += $" device: {{dev_id: {{_eq:{dev.Id}}} }}"; - first = false; + devWhereStatement += "}, {"; } + first = false; + devWhereStatement += $@" dev_id: {{_eq:{dev.Id} }} "; } } - query.ruleWhereStatement += "}]}, "; } + devWhereStatement += "}] "; + devWhereStatement += devWhereStringEnd; + return devWhereStatement; } + private static void SetTimeFilter(ref DynGraphqlQuery query, TimeFilter? timeFilter, ReportType? reportType, RecertFilter recertFilter) { if (timeFilter != null) { - query.ruleWhereStatement += "{"; + query.RuleWhereStatement += "{"; switch (reportType) { case ReportType.Rules: @@ -73,64 +773,71 @@ private static void SetTimeFilter(ref DynGraphqlQuery query, TimeFilter? timeFil case ReportType.Statistics: case ReportType.NatRules: case ReportType.UnusedRules: - query.QueryParameters.Add("$relevantImportId: bigint "); - query.ruleWhereStatement += - $"import_control: {{ control_id: {{_lte: $relevantImportId }} }}, " + - $"importControlByRuleLastSeen: {{ control_id: {{_gte: $relevantImportId }} }}"; - query.nwObjWhereStatement += - $"import_control: {{ control_id: {{_lte: $relevantImportId }} }}, " + - $"importControlByObjLastSeen: {{ control_id: {{_gte: $relevantImportId }} }}"; - query.svcObjWhereStatement += - $"import_control: {{ control_id: {{_lte: $relevantImportId }} }}, " + - $"importControlBySvcLastSeen: {{ control_id: {{_gte: $relevantImportId }} }}"; - query.userObjWhereStatement += - $"import_control: {{ control_id: {{_lte: $relevantImportId }} }}, " + - $"importControlByUserLastSeen: {{ control_id: {{_gte: $relevantImportId }} }}"; - query.ReportTimeString = (timeFilter.IsShortcut ? - DateTime.Now.ToString(fullTimeFormat) : - timeFilter.ReportTime.ToString(fullTimeFormat)); + case ReportType.AppRules: + case ReportType.ComplianceReport: + case ReportType.ComplianceDiffReport: + case ReportType.RecertEventReport: + query.QueryParameters.Add("$import_id_start: bigint "); + query.QueryParameters.Add("$import_id_end: bigint "); + query.RulebaseLinkWhereStatement += + $"created: {{_lte: $import_id_end }}" + + $"_or: [{{removed: {{_gt: $import_id_start}} }}, {{removed: {{_is_null: true}} }}]"; + query.RuleWhereStatement += + $"rule_create: {{_lte: $import_id_end}}" + + $"_or: [{{removed: {{_gt: $import_id_start}} }}, {{removed: {{_is_null: true}} }}]"; + query.NwObjWhereStatement += + $"obj_create: {{_lte: $import_id_end }}" + + $"_or: [{{removed: {{_gt: $import_id_start}} }}, {{removed: {{_is_null: true}} }}]"; + query.SvcObjWhereStatement += + $"svc_create: {{_lte: $import_id_end }}" + + $"_or: [{{removed: {{_gt: $import_id_start}} }}, {{removed: {{_is_null: true}} }}]"; + query.UserObjWhereStatement += + $"user_create: {{_lte: $import_id_end }}" + + $"_or: [{{removed: {{_gt: $import_id_start}} }}, {{removed: {{_is_null: true}} }}]"; + query.ReportTimeString = timeFilter.IsShortcut ? + DateTime.Now.ToString(fullTimeFormat) : timeFilter.ReportTime.ToString(fullTimeFormat); break; case ReportType.Changes: case ReportType.ResolvedChanges: case ReportType.ResolvedChangesTech: - (string start, string stop) = ResolveTimeRange(timeFilter); - query.QueryVariables["start"] = start; - query.QueryVariables["stop"] = stop; - query.QueryParameters.Add("$start: timestamp! "); - query.QueryParameters.Add("$stop: timestamp! "); - query.QueryParameters.Add("$relevantImportId: bigint "); - - query.ruleWhereStatement += $@" - _and: [ - {{ import_control: {{ stop_time: {{ _gte: $start }} }} }} - {{ import_control: {{ stop_time: {{ _lte: $stop }} }} }} - ] + query.QueryParameters.Add("$import_id_old: bigint "); + query.QueryParameters.Add("$import_id_new: bigint "); + query.QueryParameters.Add("$include_objects_in_changes_report: Boolean! "); + + query.RuleWhereStatement += $@" + control_id: {{ _eq: $import_id_new }} change_type_id: {{ _eq: 3 }} security_relevant: {{ _eq: true }}"; break; case ReportType.Recertification: - query.nwObjWhereStatement += "{}"; - query.svcObjWhereStatement += "{}"; - query.userObjWhereStatement += "{}"; + query.QueryParameters.Add("$import_id_start: bigint "); + query.QueryParameters.Add("$import_id_end: bigint "); + query.NwObjWhereStatement += "{}"; + query.SvcObjWhereStatement += "{}"; + query.UserObjWhereStatement += "{}"; query.ReportTimeString = DateTime.Now.AddDays(recertFilter.RecertificationDisplayPeriod).ToString(fullTimeFormat); query.QueryParameters.Add("$refdate1: timestamp! "); query.QueryVariables["refdate1"] = query.ReportTimeString; - query.ruleWhereStatement += $@" rule_metadatum: {{ recertifications: {{ next_recert_date: {{ _lte: $refdate1 }} }} }} "; + query.RuleWhereStatement += $@" rule_metadatum: {{ recertifications: {{ next_recert_date: {{ _lte: $refdate1 }} }} }} "; + break; + case ReportType.Connections: + case ReportType.VarianceAnalysis: + case ReportType.RecertificationEvent: break; default: Log.WriteError("Filter", $"Unexpected report type found: {reportType}"); break; } - query.ruleWhereStatement += "}, "; + query.RuleWhereStatement += "}, "; } } - private static (string, string) ResolveTimeRange(TimeFilter timeFilter) + public static (string, string) ResolveTimeRange(TimeFilter timeFilter) { string start; string stop; - DateTime startOfCurrentYear = new DateTime(DateTime.Now.Year, 1, 1); - DateTime startOfCurrentMonth = new DateTime(DateTime.Now.Year, DateTime.Now.Month, 1); + DateTime startOfCurrentYear = new(DateTime.Now.Year, 1, 1); + DateTime startOfCurrentMonth = new(DateTime.Now.Year, DateTime.Now.Month, 1); DateTime startOfCurrentWeek = DateTime.Now.AddDays(-(int)DateTime.Now.DayOfWeek); switch (timeFilter.TimeRangeType) @@ -159,7 +866,7 @@ private static (string, string) ResolveTimeRange(TimeFilter timeFilter) stop = DateTime.Now.AddDays(1).ToString(dateFormat); break; case "last week": - start = startOfCurrentWeek.AddDays(-7).ToString(dateFormat); + start = startOfCurrentWeek.AddDays(-GlobalConst.kDaysPerWeek).ToString(dateFormat); stop = startOfCurrentWeek.ToString(dateFormat); break; case "today": @@ -171,19 +878,22 @@ private static (string, string) ResolveTimeRange(TimeFilter timeFilter) stop = DateTime.Now.ToString(dateFormat); break; default: - throw new Exception($"Error: wrong time range format:" + timeFilter.TimeRangeShortcut); + throw new NotSupportedException($"Error: wrong time range format:" + timeFilter.TimeRangeShortcut); } break; case TimeRangeType.Interval: + // Relative time window: compute start by subtracting the configured offset from "now". start = timeFilter.Interval switch { - Interval.Days => DateTime.Now.AddDays(-timeFilter.Offset).ToString(fullTimeFormat), - Interval.Weeks => DateTime.Now.AddDays(-7 * timeFilter.Offset).ToString(fullTimeFormat), - Interval.Months => DateTime.Now.AddMonths(-timeFilter.Offset).ToString(fullTimeFormat), - Interval.Years => DateTime.Now.AddYears(-timeFilter.Offset).ToString(fullTimeFormat), - _ => throw new Exception($"Error: wrong time interval format:" + timeFilter.Interval.ToString()), + // Offset is the number of units (days/weeks/months/years) to subtract from "now". + SchedulerInterval.Days => DateTime.Now.AddDays(-timeFilter.Offset).ToString(fullTimeFormat), + SchedulerInterval.Weeks => DateTime.Now.AddDays(-GlobalConst.kDaysPerWeek * timeFilter.Offset).ToString(fullTimeFormat), + SchedulerInterval.Months => DateTime.Now.AddMonths(-timeFilter.Offset).ToString(fullTimeFormat), + SchedulerInterval.Years => DateTime.Now.AddYears(-timeFilter.Offset).ToString(fullTimeFormat), + _ => throw new NotSupportedException($"Error: wrong time interval format:" + timeFilter.Interval.ToString()), }; + // End of the interval is "now". stop = DateTime.Now.ToString(fullTimeFormat); break; @@ -208,21 +918,88 @@ private static void SetRecertFilter(ref DynGraphqlQuery query, RecertFilter? rec { if (recertFilter != null) { - // setting owner filter: - if (recertFilter.RecertOwnerList.Count > 0) + query.QueryParameters.Add("$ownerWhere: owner_bool_exp"); + query.QueryVariables["ownerWhere"] = recertFilter.RecertOwnerList.Count > 0 + ? new { id = new { _in = recertFilter.RecertOwnerList } } + : new { }; + } + } + + private static void SetOwnerRecertFilter(ref DynGraphqlQuery query, ModellingFilter? modellingFilter, RecertFilter? recertFilter) + { + if (modellingFilter != null) + { + query.QueryParameters.Add("$selectedOwners: [Int!]"); + query.QueryVariables["selectedOwners"] = new List(modellingFilter.SelectedOwners.Select(o => o.Id)).ToArray(); + query.OwnerWhereStatement += $@"{{ id: {{ _in: $selectedOwners }} }}"; + + List ownerStateFilters = []; + string activeOwnersFilter = $@"{{ recert_active: {{ _eq: true }} }}"; + if (!modellingFilter.ShowAllOwners) + { + query.QueryParameters.Add("$refDate: timestamp"); + query.QueryVariables["refDate"] = DateTime.Now.AddDays(recertFilter?.RecertificationDisplayPeriod ?? 0); + activeOwnersFilter = $@"{{ _and: [{{ recert_active: {{ _eq: true }} }}, {{ next_recert_date: {{ _lte: $refDate }} }}] }}"; + } + ownerStateFilters.Add(activeOwnersFilter); + + if (modellingFilter.ShowInactiveRecertOwners) { - query.QueryParameters.Add("$ownerWhere: owner_bool_exp"); - query.QueryVariables["ownerWhere"] = new {id = new {_in = recertFilter.RecertOwnerList}}; + ownerStateFilters.Add($@"{{ recert_active: {{ _eq: false }} }}"); + } + + if (ownerStateFilters.Count == 1) + { + query.OwnerWhereStatement += ownerStateFilters[0]; + } + else if (ownerStateFilters.Count > 1) + { + query.OwnerWhereStatement += $@"{{ _or: [{string.Join(", ", ownerStateFilters)}] }}"; } else - { - // if no ownerIds are set in the filter, return all recerts - query.QueryParameters.Add("$ownerWhere: owner_bool_exp"); - query.QueryVariables["ownerWhere"] = new {id = new {}}; + { + query.OwnerWhereStatement += $@"{{ id: {{ _eq: -1 }} }}"; } } } + private static void SetOwnerFilter(ref DynGraphqlQuery query, ModellingFilter? modellingFilter) + { + if (modellingFilter != null) + { + // currently overruling tenant filter!! + query.OpenRulesTable = $@" rules: get_rules_for_owner(args: {{ownerid: {modellingFilter.SelectedOwner.Id} }}, "; + query.SelectedOwner = modellingFilter.SelectedOwner; + } + } + + private static void SetOwnerListFilter(ref DynGraphqlQuery query, OwnerFilter? ownerFilter) + { + query.OwnerWhereStatement += "{ id: { _gt: 0 } }"; + if (ownerFilter?.SelectedOwnerLifeCycleStateId != null) + { + query.QueryParameters.Add("$ownerLifeCycleStateId: Int"); + query.QueryVariables["ownerLifeCycleStateId"] = ownerFilter.SelectedOwnerLifeCycleStateId; + query.OwnerWhereStatement += "{ owner_lifecycle_state_id: { _eq: $ownerLifeCycleStateId } }"; + } + if (!string.IsNullOrWhiteSpace(ownerFilter?.SelectedCriticality)) + { + query.QueryParameters.Add("$ownerCriticality: String"); + query.QueryVariables["ownerCriticality"] = ownerFilter.SelectedCriticality; + query.OwnerWhereStatement += "{ criticality: { _eq: $ownerCriticality } }"; + } + } + + private static void SetConnectionFilter(ref DynGraphqlQuery query, ModellingFilter? modellingFilter) + { + if (modellingFilter != null) + { + query.QueryParameters.Add("$appId: Int!"); + query.QueryVariables["appId"] = modellingFilter.SelectedOwner.Id; + query.ConnectionWhereStatement += $@"{{ _or: [ {{ app_id: {{ _eq: $appId }} }}, {{ proposed_app_id: {{ _eq: $appId }} }} ], removed: {{ _eq: false }} }}"; + } + } + private static void SetUnusedFilter(ref DynGraphqlQuery query, UnusedFilter? unusedFilter) { if (unusedFilter != null) @@ -231,247 +1008,36 @@ private static void SetUnusedFilter(ref DynGraphqlQuery query, UnusedFilter? unu query.QueryParameters.Add("$tolerance: timestamp"); query.QueryVariables["cut"] = DateTime.Now.AddDays(-unusedFilter.UnusedForDays); query.QueryVariables["tolerance"] = DateTime.Now.AddDays(-unusedFilter.CreationTolerance); - query.ruleWhereStatement += $@"{{rule_metadatum: {{_or: [ + query.RuleWhereStatement += $@"{{rule_metadatum: {{_or: [ {{_and: [{{rule_last_hit: {{_is_null: false}} }}, {{rule_last_hit: {{_lte: $cut}} }} ] }}, - {{_and: [{{rule_last_hit: {{_is_null: true}} }}, {{rule_created: {{_lte: $tolerance}} }} ] }} + {{_and: [{{rule_last_hit: {{_is_null: true}} }}, {{created_import: {{ start_time: {{_lte: $tolerance}} }} }} ] }} ]}} }}"; } } - private static void SetFixedFilters(ref DynGraphqlQuery query, ReportTemplate reportParams) + private static void SetTenantFilter(ref DynGraphqlQuery query, ReportTemplate filter) { - // leave out all header texts - if (reportParams.ReportParams.ReportType != null && - (reportParams.ReportParams.ReportType == (int)ReportType.Statistics || - reportParams.ReportParams.ReportType == (int)ReportType.Recertification)) - { - query.ruleWhereStatement += "{rule_head_text: {_is_null: true}}, "; - } - SetDeviceFilter(ref query, reportParams.ReportParams.DeviceFilter); - SetTimeFilter(ref query, reportParams.ReportParams.TimeFilter, (ReportType)(reportParams.ReportParams.ReportType ?? throw new Exception("No report type set")), reportParams.ReportParams.RecertFilter); - if (reportParams.ReportParams.ReportType!= null && (ReportType)reportParams.ReportParams.ReportType==ReportType.Recertification) + if (filter.ReportParams.TenantFilter.IsActive) { - SetRecertFilter(ref query, reportParams.ReportParams.RecertFilter); - } - if (reportParams.ReportParams.ReportType!= null && (ReportType)reportParams.ReportParams.ReportType==ReportType.UnusedRules) - { - SetUnusedFilter(ref query, reportParams.ReportParams.UnusedFilter); + int tenant_id = filter.ReportParams.TenantFilter.TenantId; + query.OpenRulesTable = $"rules: get_rules_for_tenant(args: {{tenant: {tenant_id}}}, "; + query.OpenChangeLogRulesTable = $"changelog_rules: get_changelog_rules_for_tenant(args: {{tenant: {tenant_id}}}, "; } } - public static DynGraphqlQuery GenerateQuery(ReportTemplate filter, AstNode? ast) + private static void OverwriteMissingTenantFilters(ref DynGraphqlQuery query, ReportTemplate filter) { - DynGraphqlQuery query = new DynGraphqlQuery(filter.Filter); - - query.ruleWhereStatement += "_and: ["; - - SetFixedFilters(ref query, filter); - - query.ruleWhereStatement += "{"; - - // now we convert the ast into a graphql query: - if (ast != null) - ast.Extract(ref query, (ReportType)(filter.ReportParams.ReportType ?? throw new Exception("No report type set"))); - - query.ruleWhereStatement += "}] "; - - string paramString = string.Join(" ", query.QueryParameters.ToArray()); - - string mgmtWhereString = $@"where: {{ hide_in_gui: {{_eq: false }} - mgm_id: {{_in: $mgmId }} - stm_dev_typ: {{dev_typ_is_multi_mgmt: {{_eq: false}} is_pure_routing_device: {{_eq: false}} }} - }} order_by: {{ mgm_name: asc }}"; - - string devWhereString = $@"where: {{ hide_in_gui: {{_eq: false }}, - stm_dev_typ: {{is_pure_routing_device:{{_eq:false}} }} - }} order_by: {{ dev_name: asc }}"; - - if (((ReportType)(filter.ReportParams.ReportType ?? throw new Exception("No report type set"))).IsResolvedReport()) - filter.Detailed = true; - - switch ((ReportType)(filter.ReportParams.ReportType ?? throw new Exception("No report type set"))) + // the following additional filters are used for standard and simulated tenant filtering (by admin users) + if (filter.ReportParams.TenantFilter.IsActive) { - case ReportType.Statistics: - query.FullQuery = Queries.compact($@" - query statisticsReport ({paramString}) - {{ - management({mgmtWhereString}) - {{ - name: mgm_name - id: mgm_id - objects_aggregate(where: {{ {query.nwObjWhereStatement} }}) {{ aggregate {{ count }} }} - services_aggregate(where: {{ {query.svcObjWhereStatement} }}) {{ aggregate {{ count }} }} - usrs_aggregate(where: {{ {query.userObjWhereStatement} }}) {{ aggregate {{ count }} }} - rules_aggregate(where: {{ {query.ruleWhereStatement} }}) {{ aggregate {{ count }} }} - devices({devWhereString}) - {{ - name: dev_name - id: dev_id - rules_aggregate(where: {{ {query.ruleWhereStatement} }}) {{ aggregate {{ count }} }} - }} - }} - }} - "); - break; - - case ReportType.Rules: - case ReportType.ResolvedRules: - case ReportType.ResolvedRulesTech: - case ReportType.UnusedRules: - query.FullQuery = Queries.compact($@" - {(filter.Detailed ? RuleQueries.ruleDetailsForReportFragments : RuleQueries.ruleOverviewFragments)} - query rulesReport ({paramString}) - {{ - management({mgmtWhereString}) - {{ - id: mgm_id - name: mgm_name - devices ({devWhereString}) - {{ - id: dev_id - name: dev_name - rules( - limit: $limit - offset: $offset - where: {{ access_rule: {{_eq: true}} {query.ruleWhereStatement} }} - order_by: {{ rule_num_numeric: asc }} ) - {{ - mgm_id: mgm_id - {((ReportType)filter.ReportParams.ReportType == ReportType.UnusedRules ? "rule_metadatum { rule_last_hit }" : "")} - ...{(filter.Detailed ? "ruleDetails" : "ruleOverview")} - }} - }} - }} - }} - "); - break; - - case ReportType.Recertification: - query.FullQuery = Queries.compact($@" - {RecertQueries.ruleOpenRecertFragments} - query rulesCertReport({paramString}) - {{ - management({mgmtWhereString}) - {{ - id: mgm_id - name: mgm_name - devices({devWhereString}) - {{ - id: dev_id - name: dev_name - rules( - where: {{ - rule_metadatum: {{ recertifications_aggregate: {{ count: {{ filter: {{ _and: [{{owner: $ownerWhere}}, {{recert_date: {{_is_null: true}}}}, {{next_recert_date: {{_lte: $refdate1}}}}]}}, predicate: {{_gt: 0}}}}}}}} - active:{{ _eq:true }} - {query.ruleWhereStatement} - }} - limit: $limit - offset: $offset - order_by: {{ rule_num_numeric: asc }} - ) - {{ - mgm_id: mgm_id - ...ruleOpenCertOverview - }} - }} - }} - }} - "); - break; - - case ReportType.Changes: - case ReportType.ResolvedChanges: - case ReportType.ResolvedChangesTech: - query.FullQuery = Queries.compact($@" - {(filter.Detailed ? RuleQueries.ruleDetailsForReportFragments : RuleQueries.ruleOverviewFragments)} - query changeReport({paramString}) - {{ - management(where: {{ hide_in_gui: {{_eq: false }} stm_dev_typ: {{dev_typ_is_multi_mgmt: {{_eq: false}} is_pure_routing_device: {{_eq: false}} }} }} order_by: {{mgm_name: asc}}) - {{ - id: mgm_id - name: mgm_name - devices ({devWhereString}) - {{ - id: dev_id - name: dev_name - changelog_rules( - offset: $offset - limit: $limit - where: {{ - _or:[ - {{_and: [{{change_action:{{_eq:""I""}}}}, {{rule: {{access_rule:{{_eq:true}}}}}}]}}, - {{_and: [{{change_action:{{_eq:""D""}}}}, {{ruleByOldRuleId: {{access_rule:{{_eq:true}}}}}}]}}, - {{_and: [{{change_action:{{_eq:""C""}}}}, {{rule: {{access_rule:{{_eq:true}}}}}}, {{ruleByOldRuleId: {{access_rule:{{_eq:true}}}}}}]}} - ] - {query.ruleWhereStatement} - }} - order_by: {{ control_id: asc }} - ) - {{ - import: import_control {{ time: stop_time }} - change_action - old: ruleByOldRuleId {{ - mgm_id: mgm_id - ...{(filter.Detailed ? "ruleDetails" : "ruleOverview")} - }} - new: rule {{ - mgm_id: mgm_id - ...{(filter.Detailed ? "ruleDetails" : "ruleOverview")} - }} - }} - }} - }} - }} - "); - break; - - case ReportType.NatRules: - query.FullQuery = Queries.compact($@" - {(filter.Detailed ? RuleQueries.natRuleDetailsForReportFragments : RuleQueries.natRuleOverviewFragments)} - query natRulesReport ({paramString}) - {{ - management({mgmtWhereString}) - {{ - id: mgm_id - name: mgm_name - devices ({devWhereString}) - {{ - id: dev_id - name: dev_name - rules( - limit: $limit - offset: $offset - where: {{ nat_rule: {{_eq: true}}, ruleByXlateRule: {{}} {query.ruleWhereStatement} }} - order_by: {{ rule_num_numeric: asc }} ) - {{ - mgm_id: mgm_id - ...{(filter.Detailed ? "natRuleDetails" : "natRuleOverview")} - }} - }} - }} - }} - "); - break; + int tenant_id = filter.ReportParams.TenantFilter.TenantId; + query.FullQuery = Regex.Replace(query.FullQuery, @"\srules\s*\(", $" rules: get_rules_for_tenant(args: {{tenant: {tenant_id}}}, "); + query.FullQuery = Regex.Replace(query.FullQuery, @"changelog_rules\s*\(", $" changelog_rules: get_changelog_rules_for_tenant(args: {{tenant: {tenant_id}}}, "); + query.FullQuery = Regex.Replace(query.FullQuery, @"rule_froms\s*\(", $"rule_froms: get_rule_froms_for_tenant(args: {{tenant: {tenant_id}}}"); + query.FullQuery = Regex.Replace(query.FullQuery, @"rule_froms\s*{", $"rule_froms: get_rule_froms_for_tenant(args: {{tenant: {tenant_id}}}) {{"); + query.FullQuery = Regex.Replace(query.FullQuery, @"rule_tos\s*\(", $"rule_tos: get_rule_tos_for_tenant(args: {{tenant: {tenant_id}}}"); + query.FullQuery = Regex.Replace(query.FullQuery, @"rule_tos\s*{", $"rule_tos: get_rule_tos_for_tenant(args: {{tenant: {tenant_id}}}) {{"); } - - string pattern = ""; - - // remove comment lines (#) before joining lines! - // Regex.Replace("10, 20, 30", @"(\d+)$",match => (int.Parse(match.Value)+1).ToString()) - // Regex.Replace(query.FullQuery, pattern, m => variablesDictionary[m.Value]); - // Regex pattern = new Regex(@"#(.*?)\n"); - - // TODO: get this working - // pattern = @"""[^""\\]*(?:\\[\W\w][^""\\]*)*""|(\#.*)"; - // string pattern = @"(.*?)(#.*?)\n(.*?)"; - // query.FullQuery = Regex.Replace(query.FullQuery, pattern, ""); - - // remove line breaks and duplicate whitespaces - pattern = @"\n"; - query.FullQuery = Regex.Replace(query.FullQuery, pattern, ""); - pattern = @"\s+"; - query.FullQuery = Regex.Replace(query.FullQuery, pattern, " "); - return query; } } } diff --git a/roles/lib/files/FWO.Report.Filter/Exceptions/FilterException.cs b/roles/lib/files/FWO.Report.Filter/Exceptions/FilterException.cs index da1842f694..68d71d416a 100644 --- a/roles/lib/files/FWO.Report.Filter/Exceptions/FilterException.cs +++ b/roles/lib/files/FWO.Report.Filter/Exceptions/FilterException.cs @@ -1,16 +1,7 @@ -using System; -using System.Collections.Generic; -using System.Text; - namespace FWO.Report.Filter.Exceptions { - public class FilterException : Exception + public class FilterException(string message, Range errorPosition) : Exception(message) { - public readonly Range ErrorPosition; - - public FilterException(string message, Range errorPosition) : base(message) - { - ErrorPosition = errorPosition; - } + public readonly Range ErrorPosition = errorPosition; } } diff --git a/roles/lib/files/FWO.Report.Filter/Exceptions/SemanticException.cs b/roles/lib/files/FWO.Report.Filter/Exceptions/SemanticException.cs index a3b4e042ed..93e29b5bf2 100644 --- a/roles/lib/files/FWO.Report.Filter/Exceptions/SemanticException.cs +++ b/roles/lib/files/FWO.Report.Filter/Exceptions/SemanticException.cs @@ -1,14 +1,6 @@ -using System; -using System.Collections.Generic; -using System.Text; - namespace FWO.Report.Filter.Exceptions { - public class SemanticException : FilterException + public class SemanticException(string message, Range errorPosition) : FilterException(message, errorPosition) { - public SemanticException(string message, Range errorPosition) : base(message, errorPosition) - { - - } } } diff --git a/roles/lib/files/FWO.Report.Filter/Exceptions/SyntaxException.cs b/roles/lib/files/FWO.Report.Filter/Exceptions/SyntaxException.cs index 693c756b1b..1c5af3fd99 100644 --- a/roles/lib/files/FWO.Report.Filter/Exceptions/SyntaxException.cs +++ b/roles/lib/files/FWO.Report.Filter/Exceptions/SyntaxException.cs @@ -1,14 +1,6 @@ -using System; -using System.Collections.Generic; -using System.Text; - namespace FWO.Report.Filter.Exceptions { - public class SyntaxException : FilterException + public class SyntaxException(string message, Range errorPosition) : FilterException(message, errorPosition) { - public SyntaxException(string message, Range errorPosition) : base(message, errorPosition) - { - - } } } diff --git a/roles/lib/files/FWO.Report.Filter/FWO.Report.Filter.csproj b/roles/lib/files/FWO.Report.Filter/FWO.Report.Filter.csproj index d21fb051a5..432e7066e5 100644 --- a/roles/lib/files/FWO.Report.Filter/FWO.Report.Filter.csproj +++ b/roles/lib/files/FWO.Report.Filter/FWO.Report.Filter.csproj @@ -1,15 +1,16 @@  - net6.0 + net10.0 enable enable - + - + + diff --git a/roles/lib/files/FWO.Report.Filter/FilterTypes/DateTimeRange.cs b/roles/lib/files/FWO.Report.Filter/FilterTypes/DateTimeRange.cs index d4e3981b85..c8b52846f0 100644 --- a/roles/lib/files/FWO.Report.Filter/FilterTypes/DateTimeRange.cs +++ b/roles/lib/files/FWO.Report.Filter/FilterTypes/DateTimeRange.cs @@ -1,7 +1,7 @@ -using FWO.Report.Filter.Ast; +using FWO.Report.Filter.Ast; using FWO.Report.Filter.Exceptions; -namespace FWO.Report.Filter +namespace FWO.Report.Filter.FilterTypes { class DateTimeRange { diff --git a/roles/lib/files/FWO.Report.Filter/FilterTypes/ReportFilters.cs b/roles/lib/files/FWO.Report.Filter/FilterTypes/ReportFilters.cs new file mode 100644 index 0000000000..678734e260 --- /dev/null +++ b/roles/lib/files/FWO.Report.Filter/FilterTypes/ReportFilters.cs @@ -0,0 +1,250 @@ +using FWO.Data.Report; +using FWO.Config.Api; +using FWO.Basics; +using FWO.Data; + + +namespace FWO.Report.Filter.FilterTypes +{ + public class ReportFilters + { + public ReportType ReportType { get; set; } = ReportType.Rules; + + public DeviceFilter DeviceFilter { get; set; } = new(); + public DeviceFilter ReducedDeviceFilter { get; set; } = new(); + public bool SelectAll = true; + public bool CollapseDevices = false; + + public TimeFilter TimeFilter { get; set; } = new(); + public TimeFilter SavedTimeFilter { get; set; } = new(); + + public TenantFilter TenantFilter { get; set; } = new(); + public Tenant? SelectedTenant = null; + + public RecertFilter RecertFilter { get; set; } = new(); + + public UnusedFilter UnusedFilter { get; set; } = new(); + public int UnusedDays = 0; + + public ModellingFilter ModellingFilter { get; set; } = new(); + public OwnerFilter OwnerFilter { get; set; } = new(); + + public ComplianceFilter ComplianceFilter { get; set; } = new(); + + public WorkflowFilter WorkflowFilter { get; set; } = new(); + + public string DisplayedTimeSelection = ""; + + private UserConfig? userConfig; + + public bool IncludeObjects { get; set; } = false; + + public void Init(UserConfig userConfigIn, bool showRuleRelatedReports) + { + userConfig = userConfigIn; + ReportType = showRuleRelatedReports ? ReportType.Rules : ReportType.Connections; + DisplayedTimeSelection = userConfig.GetText("now"); + UnusedDays = userConfig.UnusedTolerance; + IncludeObjects = userConfig.GlobalConfig?.ImpChangeIncludeObjectChanges ?? false; + + if (DeviceFilter.NumberMgmtDev() > userConfig.MinCollapseAllDevices) + { + CollapseDevices = true; + } + } + + public void SyncFiltersFromTemplate(ReportTemplate template) + { + ReportType = (ReportType)template.ReportParams.ReportType; + IncludeObjects = template.ReportParams.IncludeObjects; + if (template.ReportParams.DeviceFilter != null && template.ReportParams.DeviceFilter.Managements.Count > 0) + { + DeviceFilter.SynchronizeDevFilter(template.ReportParams.DeviceFilter); + } + SelectAll = !DeviceFilter.IsAnyDeviceFilterSet(); + + if (template.ReportParams.TimeFilter != null) + { + TimeFilter = template.ReportParams.TimeFilter; + } + SetDisplayedTimeSelection(); + RecertFilter = new(template.ReportParams.RecertFilter); + UnusedDays = template.ReportParams.UnusedFilter.UnusedForDays; + ModellingFilter = template.ReportParams.ModellingFilter; + OwnerFilter = new(template.ReportParams.OwnerFilter); + ComplianceFilter = new(template.ReportParams.ComplianceFilter); + WorkflowFilter = new(template.ReportParams.WorkflowFilter); + } + + public ReportParams ToReportParams() + { + ReportParams reportParams = new((int)ReportType, ReportType == ReportType.UnusedRules ? ReducedDeviceFilter : DeviceFilter) + { + IncludeObjects = IncludeObjects, + TimeFilter = SavedTimeFilter, + RecertFilter = new RecertFilter(RecertFilter), + UnusedFilter = new UnusedFilter() + { + UnusedForDays = UnusedDays, + CreationTolerance = userConfig?.CreationTolerance ?? 0 + }, + ModellingFilter = new ModellingFilter(ModellingFilter), + OwnerFilter = new OwnerFilter(OwnerFilter), + ComplianceFilter = new ComplianceFilter(ComplianceFilter), + WorkflowFilter = new WorkflowFilter(WorkflowFilter) + }; + if (ReportType != ReportType.Statistics) + { + // also make sure the report a user belonging to a tenant <> 1 sees, gets the additional filters in DynGraphqlQuery.cs + if (SelectedTenant == null && userConfig?.User.Tenant?.Id > 1) + { + SelectedTenant = userConfig.User.Tenant; + // TODO: when admin selects a tenant filter, add the corresponding device filter to make sure only those devices are reported that the tenant is allowed to see + } + reportParams.TenantFilter = new TenantFilter(SelectedTenant); + } + return reportParams; + } + + public bool SetDisplayedTimeSelection() + { + if (ReportType.IsChangeReport() || ReportType == ReportType.TicketChangeReport) + { + switch (TimeFilter.TimeRangeType) + { + case TimeRangeType.Shortcut: + DisplayedTimeSelection = userConfig?.GetText(TimeFilter.TimeRangeShortcut) ?? TimeFilter.TimeRangeShortcut; + break; + case TimeRangeType.Interval: + DisplayedTimeSelection = userConfig?.GetText("last") + " " + + TimeFilter.Offset + " " + userConfig?.GetText(TimeFilter.Interval.ToString()); + break; + case TimeRangeType.Fixeddates: + if (TimeFilter.OpenStart && TimeFilter.OpenEnd) + { + DisplayedTimeSelection = userConfig?.GetText("open") ?? "open"; + } + else if (TimeFilter.OpenStart) + { + DisplayedTimeSelection = userConfig?.GetText("until") + " " + TimeFilter.EndTime.ToString(); + } + else if (TimeFilter.OpenEnd) + { + DisplayedTimeSelection = userConfig?.GetText("from") + " " + TimeFilter.StartTime.ToString(); + } + else + { + DisplayedTimeSelection = TimeFilter.StartTime.ToString() + " - " + TimeFilter.EndTime.ToString(); + } + break; + default: + DisplayedTimeSelection = ""; + break; + } + ; + } + else + { + if (TimeFilter.IsShortcut) + { + DisplayedTimeSelection = userConfig?.GetText(TimeFilter.TimeShortcut) ?? TimeFilter.TimeShortcut; + } + else + { + DisplayedTimeSelection = TimeFilter.ReportTime.ToString(); + } + } + return true; + } + + /// sets deviceFilter.Managements and selectedTenant according to either + /// a) selected tenant for tenant simulation + /// b) tenant of the user logged in (if belonging to tenant <> tenant0) + public void TenantViewChanged(Tenant? newTenantView) + { + SelectedTenant = newTenantView; + + // we must modify the device visibility in the device filter + if (SelectedTenant == null || SelectedTenant.Id == 1) + { + // tenant0 or no tenant selected --> all devices are visible + MarkAllDevicesVisible(DeviceFilter.Managements); + } + else + { + // not all devices are visible + SetDeviceVisibility(SelectedTenant); + } + SelectAll = !DeviceFilter.IsAnyDeviceFilterSet(); + } + + private static void MarkAllDevicesVisible(List mgms) + { + foreach (ManagementSelect management in mgms) + { + management.Visible = true; + management.Shared = false; + foreach (DeviceSelect gw in management.Devices) + { + gw.Visible = true; + gw.Shared = false; + } + } + } + + private void SetDeviceVisibility(Tenant tenantView) + { + if ((userConfig == null || userConfig.User.Tenant == null || userConfig.User.Tenant.Id == 1) && tenantView.Id != 1) + { + // filtering for tenant simulation only done by a tenant0 user + foreach (TenantGateway gw in tenantView.TenantGateways) + { + if (!tenantView.VisibleGatewayIds.Contains(gw.VisibleGateway.Id)) + { + tenantView.VisibleGatewayIds = [.. tenantView.VisibleGatewayIds, gw.VisibleGateway.Id]; + } + } + + // also add all gateways of non-shared managments - necessary for simulated tenant filtering + foreach (TenantManagement mgm in tenantView.TenantManagements) + { + if (!mgm.Shared) + { + foreach (Device gw in mgm.VisibleManagement.Devices) + { + if (!tenantView.VisibleGatewayIds.Contains(gw.Id)) + { + tenantView.VisibleGatewayIds = [.. tenantView.VisibleGatewayIds, gw.Id]; + } + } + } + } + } + + foreach (ManagementSelect mgm in DeviceFilter.Managements) + { + mgm.Shared = false; + bool mgmVisible = false; + foreach (DeviceSelect gw in mgm.Devices) + { + gw.Visible = tenantView.VisibleGatewayIds.Contains(gw.Id); + if (gw.Visible) + { + // one gateway is visible, so the management must be visible + mgmVisible = true; + } + else + { + gw.Selected = false; // make sure invisible devices are not selected + mgm.Shared = true; // if one gateway is not visible, the mgm is shared (filtered) + } + } + mgm.Visible = mgmVisible; + if (!mgm.Visible) + { // make sure invisible managements are not selected + mgm.Selected = false; + } + } + } + } +} diff --git a/roles/lib/files/FWO.Report.Filter/FilterTypes/ReportType.cs b/roles/lib/files/FWO.Report.Filter/FilterTypes/ReportType.cs deleted file mode 100644 index d4d6508099..0000000000 --- a/roles/lib/files/FWO.Report.Filter/FilterTypes/ReportType.cs +++ /dev/null @@ -1,74 +0,0 @@ -namespace FWO.Report.Filter -{ - public enum ReportType - { - Rules = 1, - Changes = 2, - Statistics = 3, - NatRules = 4, - ResolvedRules = 5, - ResolvedRulesTech = 6, - Recertification = 7, - ResolvedChanges = 8, - ResolvedChangesTech = 9, - UnusedRules = 10 - } - - public static class ReportTypeGroups - { - public static bool IsRuleReport(this ReportType reportType) - { - switch(reportType) - { - case ReportType.Rules: - case ReportType.ResolvedRules: - case ReportType.ResolvedRulesTech: - case ReportType.NatRules: - case ReportType.Recertification: - case ReportType.UnusedRules: - return true; - default: - return false; - } - } - - public static bool IsChangeReport(this ReportType reportType) - { - switch(reportType) - { - case ReportType.Changes: - case ReportType.ResolvedChanges: - case ReportType.ResolvedChangesTech: - return true; - default: - return false; - } - } - - public static bool IsResolvedReport(this ReportType reportType) - { - switch(reportType) - { - case ReportType.ResolvedRules: - case ReportType.ResolvedRulesTech: - case ReportType.ResolvedChanges: - case ReportType.ResolvedChangesTech: - return true; - default: - return false; - } - } - - public static bool IsTechReport(this ReportType reportType) - { - switch(reportType) - { - case ReportType.ResolvedRulesTech: - case ReportType.ResolvedChangesTech: - return true; - default: - return false; - } - } - } -} diff --git a/roles/lib/files/FWO.Report.Filter/Parser.cs b/roles/lib/files/FWO.Report.Filter/Parser.cs index 133f64aebd..d4b6df18f4 100644 --- a/roles/lib/files/FWO.Report.Filter/Parser.cs +++ b/roles/lib/files/FWO.Report.Filter/Parser.cs @@ -6,7 +6,7 @@ namespace FWO.Report.Filter public class Parser { int position; - List tokens; + readonly List tokens; public Parser(List tokens) { @@ -138,23 +138,26 @@ private AstNode ParseFilter() Token Value = CheckToken(TokenKind.Value); return Name.Kind switch { - TokenKind.Value or TokenKind.Owner or TokenKind.Service or TokenKind.Action or TokenKind.Management or TokenKind.Gateway or TokenKind.FullText or TokenKind.Protocol + TokenKind.Value or TokenKind.Service or TokenKind.Action or TokenKind.Management or TokenKind.Gateway or TokenKind.FullText or TokenKind.Protocol or TokenKind.Criticality or TokenKind.OwnerState => new AstNodeFilterString() { Name = Name, Operator = Operator, Value = Value }, TokenKind.Disabled or TokenKind.SourceNegated or TokenKind.DestinationNegated or TokenKind.ServiceNegated or TokenKind.Remove => new AstNodeFilterBool() { Name = Name, Operator = Operator, Value = Value }, - TokenKind.Time or TokenKind.LastHit + TokenKind.Time or TokenKind.LastHit => new AstNodeFilterDateTimeRange() { Name = Name, Operator = Operator, Value = Value }, - TokenKind.ReportType + TokenKind.ReportType => new AstNodeFilterReportType() { Name = Name, Operator = Operator, Value = Value }, + TokenKind.TaskType or TokenKind.Phase or TokenKind.States or TokenKind.ReferenceDate + => new AstNodeFilterWorkflow() { Name = Name, Operator = Operator, Value = Value }, + TokenKind.DestinationPort or TokenKind.RecertDisplay or TokenKind.Unused => new AstNodeFilterInt() { Name = Name, Operator = Operator, Value = Value }, TokenKind.Source or TokenKind.Destination - => new AstNodeFilterNetwork() { Name = Name, Operator = Operator, Value = Value}, + => new AstNodeFilterNetwork() { Name = Name, Operator = Operator, Value = Value }, _ => throw new NotSupportedException($"No type found for filter with token kind: {Name.Kind}"), }; @@ -168,9 +171,11 @@ private Token ParseOperator() private Token ParseFilterName() { return CheckToken( - TokenKind.LastHit, TokenKind.Owner, TokenKind.Destination, TokenKind.Source, TokenKind.Service, TokenKind.Protocol, + TokenKind.LastHit, TokenKind.Destination, TokenKind.Source, TokenKind.Service, TokenKind.Protocol, TokenKind.DestinationPort, TokenKind.Action, TokenKind.FullText, TokenKind.Gateway, - TokenKind.Management, TokenKind.Remove, TokenKind.RecertDisplay, TokenKind.Disabled, TokenKind.Unused); + TokenKind.Management, TokenKind.Remove, TokenKind.RecertDisplay, TokenKind.Disabled, TokenKind.Unused, + TokenKind.ReportType, TokenKind.TaskType, TokenKind.Phase, TokenKind.States, TokenKind.OwnerState, + TokenKind.Criticality, TokenKind.ReferenceDate); } private Token CheckToken(params TokenKind[] expectedTokenKinds) diff --git a/roles/lib/files/FWO.Report.Filter/Scanner.cs b/roles/lib/files/FWO.Report.Filter/Scanner.cs index dbf958cdd6..11cd90259a 100644 --- a/roles/lib/files/FWO.Report.Filter/Scanner.cs +++ b/roles/lib/files/FWO.Report.Filter/Scanner.cs @@ -1,20 +1,17 @@ +using FWO.Basics.Exceptions; using FWO.Report.Filter.Exceptions; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Net.Http.Headers; +using System.Text; namespace FWO.Report.Filter { public class Scanner { - private string input; - private int position; - private const int lookAhead = 1; + private readonly string input; + private int position = 0; - private static Dictionary whitespaceTokens = new Dictionary(); - private static Dictionary noWhitespaceTokens = new Dictionary(); - private static int noWhitespaceTokenMaxLength = 0; + private static readonly Dictionary whitespaceTokens = []; + private static readonly Dictionary noWhitespaceTokens = []; + private static readonly int noWhitespaceTokenMaxLength = 0; public Scanner(string input) { @@ -45,49 +42,47 @@ static Scanner() public List Scan() { - List tokens = new List(); + List tokens = []; - for (position = 0; position < input.Length; position++) + while (position < input.Length) { - while ((position < input.Length && (input[position] == ' ' || input[position] == '\t' || input[position] == '\n' || input[position] == '\r')) == true) + if (position < input.Length && IsWhitespace(position)) { position++; + continue; } - tokens.AddRange(ReadTokens()); + position++; } - return tokens; } + private bool IsWhitespace(int currentPosition) + { + return input[currentPosition] == ' ' || input[currentPosition] == '\t' || input[currentPosition] == '\n' || input[currentPosition] == '\r'; + } + private bool IsWhitespaceOrEnd(int currentPosition) { - if (currentPosition >= input.Length || input[currentPosition] == ' ' || input[currentPosition] == '\t' || input[currentPosition] == '\n' || input[currentPosition] == '\r') - { - return true; - } - else - { - return false; - } + return currentPosition >= input.Length || IsWhitespace(currentPosition); } private List ReadTokens() { - List tokens = new List(); + List tokens = []; // Token begin position - int tokenBeginPosition = position; - + int tokenBeginPosition = position; + // Token text - string tokenText = ""; + StringBuilder tokenText = new(); - while (IsWhitespaceOrEnd(position) == false) - { + while (!IsWhitespaceOrEnd(position)) + { switch (input[position]) { case '\\': - tokenText += ScanEscapeSequence(); + tokenText.Append(ScanEscapeSequence()); break; case '\'': @@ -97,27 +92,23 @@ private List ReadTokens() break; default: - tokenText += input[position]; - - List newTokens = TryExtractToken(tokenBeginPosition, tokenText, IsWhitespaceOrEnd(position + 1), 0); - + tokenText.Append(input[position]); + List newTokens = TryExtractToken(tokenBeginPosition, tokenText.ToString(), IsWhitespaceOrEnd(position + 1), 0); if (newTokens.Count > 0) { tokens.AddRange(newTokens); tokenBeginPosition = position + 1; - tokenText = ""; + tokenText = new(); } break; } - position++; } - if (tokenText != "") + if (tokenText.Length > 0) { - tokens.Add(new Token(tokenBeginPosition..position, tokenText, TokenKind.Value)); + tokens.Add(new Token(tokenBeginPosition..position, tokenText.ToString(), TokenKind.Value)); } - return tokens; } @@ -125,84 +116,84 @@ private List TryExtractToken(int beginPosition, string text, bool surroun { if (recusionDepth > 1) { - throw new Exception("Internal error: Stackoverflow. Please report this error."); + throw new InternalException("Internal error: Stackoverflow. Please report this error."); } - List tokens = new List(); - - if (surroundedByWhitespace == true) + List tokens = []; + + if (surroundedByWhitespace && whitespaceTokens.TryGetValue(text.ToLower(), out TokenKind whiteSpaceTokenKind)) { - if (whitespaceTokens.TryGetValue(text.ToLower(), out TokenKind tokenKind)) - { - tokens.Add(new Token(beginPosition..(beginPosition + text.Length), text, tokenKind)); - return tokens; - } + tokens.Add(new Token(beginPosition..(beginPosition + text.Length), text, whiteSpaceTokenKind)); + return tokens; } - for (int tokenLength = 1; tokenLength <= noWhitespaceTokenMaxLength && tokenLength <= text.Length; tokenLength++) + int tokenLength = 1; + while (tokenLength <= noWhitespaceTokenMaxLength && tokenLength <= text.Length) { string tokenText = text[^tokenLength..^0].ToLower(); if (noWhitespaceTokens.TryGetValue(tokenText, out TokenKind tokenKind)) { - if (!IsWhitespaceOrEnd(beginPosition + text.Length) && - noWhitespaceTokens.TryGetValue(tokenText + input[beginPosition + text.Length], out TokenKind realTokenKind)) - { - tokenLength++; - position++; - tokenKind = realTokenKind; - tokenText += input[beginPosition + text.Length]; - text += input[beginPosition + text.Length]; - } + return ExtractTokens(beginPosition, text, tokenText, tokenLength, tokenKind, recusionDepth, tokens); + } + tokenLength++; + } - if (text.Length - tokenLength > 0) - { - List potentialTokens = TryExtractToken(beginPosition, text[..(text.Length - tokenLength)], true, recusionDepth + 1); - if (potentialTokens.Count > 0) - { - tokens.AddRange(potentialTokens); - } - else - { - tokens.Add(new Token(beginPosition..(beginPosition + text.Length - tokenLength), text[..^tokenLength], TokenKind.Value)); - } - } + return tokens; + } - tokens.Add(new Token((beginPosition + text.Length - tokenLength)..(beginPosition + text.Length), tokenText, tokenKind)); - return tokens; + private List ExtractTokens(int beginPosition, string text, string tokenText, int tokenLength, TokenKind tokenKind, int recusionDepth, List tokens) + { + if (!IsWhitespaceOrEnd(beginPosition + text.Length) && + noWhitespaceTokens.TryGetValue(tokenText + input[beginPosition + text.Length], out TokenKind realTokenKind)) + { + tokenLength++; + position++; + tokenKind = realTokenKind; + tokenText += input[beginPosition + text.Length]; + text += input[beginPosition + text.Length]; + } + + if (text.Length - tokenLength > 0) + { + List potentialTokens = TryExtractToken(beginPosition, text[..(text.Length - tokenLength)], true, recusionDepth + 1); + if (potentialTokens.Count > 0) + { + tokens.AddRange(potentialTokens); + } + else + { + tokens.Add(new Token(beginPosition..(beginPosition + text.Length - tokenLength), text[..^tokenLength], TokenKind.Value)); } } + tokens.Add(new Token((beginPosition + text.Length - tokenLength)..(beginPosition + text.Length), tokenText, tokenKind)); return tokens; } private Token ScanQuoted(char quoteChar) { int tokenBeginPosition = position; - string tokenText = ""; + StringBuilder tokenText = new(); position++; - while (position < input.Length) { if (input[position] == '\\') { - tokenText += ScanEscapeSequence(); + tokenText.Append(ScanEscapeSequence()); position++; } - else if (input[position] == quoteChar) { - return new Token(tokenBeginPosition..(position), tokenText, TokenKind.Value); + return new Token(tokenBeginPosition..(position), tokenText.ToString(), TokenKind.Value); } - else { - tokenText += input[position]; + tokenText.Append(input[position]); position++; } } - throw new SyntaxException($"Expected {quoteChar} got end.", (tokenBeginPosition)..(position)); } @@ -224,7 +215,7 @@ private char ScanEscapeSequence() // tab 't' => '\t', // new line - 'n' => '\n', + 'n' => '\n', // carriage return 'r' => '\r', // default case diff --git a/roles/lib/files/FWO.Report.Filter/TokenKind.cs b/roles/lib/files/FWO.Report.Filter/TokenKind.cs index 1ac4c2b2c5..d9c320e7e5 100644 --- a/roles/lib/files/FWO.Report.Filter/TokenKind.cs +++ b/roles/lib/files/FWO.Report.Filter/TokenKind.cs @@ -1,4 +1,4 @@ -namespace FWO.Report.Filter +namespace FWO.Report.Filter { public enum TokenKind { @@ -18,6 +18,12 @@ public enum TokenKind Gateway, Remove, ReportType, + TaskType, + Phase, + States, + OwnerState, + Criticality, + ReferenceDate, Time, RecertDisplay, FullText, @@ -34,4 +40,4 @@ public enum TokenKind LSS, // < GRT, // > } -} \ No newline at end of file +} diff --git a/roles/lib/files/FWO.Report.Filter/TokenSyntax.cs b/roles/lib/files/FWO.Report.Filter/TokenSyntax.cs index 0350b66207..6659c53986 100644 --- a/roles/lib/files/FWO.Report.Filter/TokenSyntax.cs +++ b/roles/lib/files/FWO.Report.Filter/TokenSyntax.cs @@ -1,4 +1,4 @@ -namespace FWO.Report.Filter +namespace FWO.Report.Filter { class TokenSyntax { @@ -17,188 +17,224 @@ public static TokenSyntax Get(TokenKind tokenKind) { TokenKind.Value => new TokenSyntax ( - WhiteSpaceRequiered: new string[] { }, - NoWhiteSpaceRequiered: new string[] { } + WhiteSpaceRequiered: [], + NoWhiteSpaceRequiered: [] ), TokenKind.Disabled => new TokenSyntax ( - WhiteSpaceRequiered: new string[] { "disabled", "inactive" }, - NoWhiteSpaceRequiered: new string[] { } + WhiteSpaceRequiered: ["disabled", "inactive"], + NoWhiteSpaceRequiered: [] ), TokenKind.SourceNegated => new TokenSyntax ( - WhiteSpaceRequiered: new string[] { "sourcenegated", "srcnegate", "sourcenegate", "source-negate", "source-negated" }, - NoWhiteSpaceRequiered: new string[] { } + WhiteSpaceRequiered: ["sourcenegated", "srcnegate", "sourcenegate", "source-negate", "source-negated"], + NoWhiteSpaceRequiered: [] ), TokenKind.DestinationNegated => new TokenSyntax ( - WhiteSpaceRequiered: new string[] { "destinationnegated", "dstnegate", "destinationnegate", "destination-negate", "destination-negated" }, - NoWhiteSpaceRequiered: new string[] { } + WhiteSpaceRequiered: ["destinationnegated", "dstnegate", "destinationnegate", "destination-negate", "destination-negated"], + NoWhiteSpaceRequiered: [] ), TokenKind.ServiceNegated => new TokenSyntax ( - WhiteSpaceRequiered: new string[] { "servicenegated", "svcnegate", "servicenegate", "service-negate", "service-negated" }, - NoWhiteSpaceRequiered: new string[] { } + WhiteSpaceRequiered: ["servicenegated", "svcnegate", "servicenegate", "service-negate", "service-negated"], + NoWhiteSpaceRequiered: [] ), TokenKind.Owner => new TokenSyntax ( - WhiteSpaceRequiered: new string[] { "owner", "application", "app" }, - NoWhiteSpaceRequiered: new string[] { } + WhiteSpaceRequiered: ["owner", "application", "app"], + NoWhiteSpaceRequiered: [] ), TokenKind.LastHit => new TokenSyntax ( - WhiteSpaceRequiered: new string[] { "lasthit", "last-hit", "last-used", "lastused", "last-usage", "lastusage", "last-use", "lastuse" }, - NoWhiteSpaceRequiered: new string[] { } + WhiteSpaceRequiered: ["lasthit", "last-hit", "last-used", "lastused", "last-usage", "lastusage", "last-use", "lastuse"], + NoWhiteSpaceRequiered: [] ), TokenKind.Unused => new TokenSyntax ( - WhiteSpaceRequiered: new string[] { "not-used-for-days", "unused", "unused-days", "not-used" }, - NoWhiteSpaceRequiered: new string[] { } + WhiteSpaceRequiered: ["not-used-for-days", "unused", "unused-days", "not-used"], + NoWhiteSpaceRequiered: [] ), TokenKind.Source => new TokenSyntax ( - WhiteSpaceRequiered: new string[] { "source", "src" }, - NoWhiteSpaceRequiered: new string[] { } + WhiteSpaceRequiered: ["source", "src"], + NoWhiteSpaceRequiered: [] ), TokenKind.Destination => new TokenSyntax ( - WhiteSpaceRequiered: new string[] { "destination", "dst", "dest" }, - NoWhiteSpaceRequiered: new string[] { } + WhiteSpaceRequiered: ["destination", "dst", "dest"], + NoWhiteSpaceRequiered: [] ), TokenKind.Action => new TokenSyntax ( - WhiteSpaceRequiered: new string[] { "action", "act", "enforce" }, - NoWhiteSpaceRequiered: new string[] { } + WhiteSpaceRequiered: ["action", "act", "enforce"], + NoWhiteSpaceRequiered: [] ), TokenKind.Management => new TokenSyntax ( - WhiteSpaceRequiered: new string[] { "management", "mgmt", "manager", "mgm", "mgr" }, - NoWhiteSpaceRequiered: new string[] { } + WhiteSpaceRequiered: ["management", "mgmt", "manager", "mgm", "mgr"], + NoWhiteSpaceRequiered: [] ), TokenKind.Gateway => new TokenSyntax ( - WhiteSpaceRequiered: new string[] { "gateway", "gw", "firewall", "fw", "device", "dev" }, - NoWhiteSpaceRequiered: new string[] { } + WhiteSpaceRequiered: ["gateway", "gw", "firewall", "fw", "device", "dev"], + NoWhiteSpaceRequiered: [] ), TokenKind.FullText => new TokenSyntax ( - WhiteSpaceRequiered: new string[] { "fulltext", "full", "fulltextsearch", "fts", "text", "textsearch" }, - NoWhiteSpaceRequiered: new string[] { } + WhiteSpaceRequiered: ["fulltext", "full", "fulltextsearch", "fts", "text", "textsearch"], + NoWhiteSpaceRequiered: [] ), TokenKind.Service => new TokenSyntax ( - WhiteSpaceRequiered: new string[] { "service", "svc", "srv" }, - NoWhiteSpaceRequiered: new string[] { } + WhiteSpaceRequiered: ["service", "svc", "srv"], + NoWhiteSpaceRequiered: [] ), TokenKind.DestinationPort => new TokenSyntax ( - WhiteSpaceRequiered: new string[] { "destinationport", "port", "dport", "dst_port", "dst-port", "dest-port", "destination-port", "dest_port", "destination_port" }, - NoWhiteSpaceRequiered: new string[] { } + WhiteSpaceRequiered: ["destinationport", "port", "dport", "dst_port", "dst-port", "dest-port", "destination-port", "dest_port", "destination_port"], + NoWhiteSpaceRequiered: [] ), TokenKind.Protocol => new TokenSyntax ( - WhiteSpaceRequiered: new string[] { "protocol", "proto" }, - NoWhiteSpaceRequiered: new string[] { } + WhiteSpaceRequiered: ["protocol", "proto"], + NoWhiteSpaceRequiered: [] ), TokenKind.Remove => new TokenSyntax ( - WhiteSpaceRequiered: new string[] { "remove" }, - NoWhiteSpaceRequiered: new string[] { } + WhiteSpaceRequiered: ["remove"], + NoWhiteSpaceRequiered: [] ), TokenKind.RecertDisplay => new TokenSyntax ( - WhiteSpaceRequiered: new string[] { "recertdisplay", "recertdisp" }, - NoWhiteSpaceRequiered: new string[] { } + WhiteSpaceRequiered: ["recertdisplay", "recertdisp"], + NoWhiteSpaceRequiered: [] ), TokenKind.ReportType => new TokenSyntax ( - WhiteSpaceRequiered: new string[] { "reporttype", "type", "report-type" }, - NoWhiteSpaceRequiered: new string[] { } + WhiteSpaceRequiered: ["reporttype", "type", "report-type"], + NoWhiteSpaceRequiered: [] + ), + + TokenKind.TaskType => new TokenSyntax + ( + WhiteSpaceRequiered: ["tasktype", "task-type", "task_type"], + NoWhiteSpaceRequiered: [] + ), + + TokenKind.Phase => new TokenSyntax + ( + WhiteSpaceRequiered: ["phase"], + NoWhiteSpaceRequiered: [] + ), + + TokenKind.States => new TokenSyntax + ( + WhiteSpaceRequiered: ["states", "state", "state_ids", "state-ids"], + NoWhiteSpaceRequiered: [] + ), + + TokenKind.OwnerState => new TokenSyntax + ( + WhiteSpaceRequiered: ["ownerstate", "owner-state", "owner_state", "owner_lc_state", "owner-lc-state"], + NoWhiteSpaceRequiered: [] + ), + + TokenKind.Criticality => new TokenSyntax + ( + WhiteSpaceRequiered: ["criticality"], + NoWhiteSpaceRequiered: [] + ), + + TokenKind.ReferenceDate => new TokenSyntax + ( + WhiteSpaceRequiered: ["reference_date", "reference-date", "referencedate"], + NoWhiteSpaceRequiered: [] ), TokenKind.Time => new TokenSyntax ( - WhiteSpaceRequiered: new string[] { "time" }, - NoWhiteSpaceRequiered: new string[] { } + WhiteSpaceRequiered: ["time"], + NoWhiteSpaceRequiered: [] ), TokenKind.BL => new TokenSyntax ( - WhiteSpaceRequiered: new string[] { }, - NoWhiteSpaceRequiered: new string[] { "(" } + WhiteSpaceRequiered: [], + NoWhiteSpaceRequiered: ["("] ), TokenKind.BR => new TokenSyntax ( - WhiteSpaceRequiered: new string[] { }, - NoWhiteSpaceRequiered: new string[] { ")" } + WhiteSpaceRequiered: [], + NoWhiteSpaceRequiered: [")"] ), TokenKind.And => new TokenSyntax ( - WhiteSpaceRequiered: new string[] { "and" }, - NoWhiteSpaceRequiered: new string[] { "&", "&&" } + WhiteSpaceRequiered: ["and"], + NoWhiteSpaceRequiered: ["&", "&&"] ), TokenKind.Or => new TokenSyntax ( - WhiteSpaceRequiered: new string[] { "or" }, - NoWhiteSpaceRequiered: new string[] { "|", "||" } + WhiteSpaceRequiered: ["or"], + NoWhiteSpaceRequiered: ["|", "||"] ), TokenKind.Not => new TokenSyntax ( - WhiteSpaceRequiered: new string[] { "not" }, - NoWhiteSpaceRequiered: new string[] { "!" } + WhiteSpaceRequiered: ["not"], + NoWhiteSpaceRequiered: ["!"] ), TokenKind.EQ => new TokenSyntax ( - WhiteSpaceRequiered: new string[] { "eq" }, - NoWhiteSpaceRequiered: new string[] { "=" } + WhiteSpaceRequiered: ["eq"], + NoWhiteSpaceRequiered: ["="] ), TokenKind.EEQ => new TokenSyntax ( - WhiteSpaceRequiered: new string[] { "eeq" }, - NoWhiteSpaceRequiered: new string[] { "==" } + WhiteSpaceRequiered: ["eeq"], + NoWhiteSpaceRequiered: ["=="] ), TokenKind.NEQ => new TokenSyntax ( - WhiteSpaceRequiered: new string[] { "neq" }, - NoWhiteSpaceRequiered: new string[] { "!=" } + WhiteSpaceRequiered: ["neq"], + NoWhiteSpaceRequiered: ["!="] ), TokenKind.LSS => new TokenSyntax ( - WhiteSpaceRequiered: new string[] { "lss" }, - NoWhiteSpaceRequiered: new string[] { "<" } + WhiteSpaceRequiered: ["lss"], + NoWhiteSpaceRequiered: ["<"] ), TokenKind.GRT => new TokenSyntax ( - WhiteSpaceRequiered: new string[] { "grt" }, - NoWhiteSpaceRequiered: new string[] { ">" } + WhiteSpaceRequiered: ["grt"], + NoWhiteSpaceRequiered: [">"] ), _ => throw new NotSupportedException($"No syntax found for token kind: {tokenKind}"), diff --git a/roles/lib/files/FWO.Report/Data/ToCHeader.cs b/roles/lib/files/FWO.Report/Data/ToCHeader.cs new file mode 100644 index 0000000000..2dcf8ba02f --- /dev/null +++ b/roles/lib/files/FWO.Report/Data/ToCHeader.cs @@ -0,0 +1,9 @@ +namespace FWO.Report.Data +{ + public class ToCHeader(string title, string? id = default) + { + public string Title { get; set; } = title; + public string? Id { get; set; } = id; + public List Items = []; + } +} diff --git a/roles/lib/files/FWO.Report/Data/ToCItem.cs b/roles/lib/files/FWO.Report/Data/ToCItem.cs new file mode 100644 index 0000000000..a1947ce266 --- /dev/null +++ b/roles/lib/files/FWO.Report/Data/ToCItem.cs @@ -0,0 +1,9 @@ +namespace FWO.Report.Data +{ + public class ToCItem(string title, string? id = default) + { + public string Title { get; set; } = title; + public string? Id { get; set; } = id; + public List SubItems = []; + } +} diff --git a/roles/lib/files/FWO.Report/Data/ViewData/RuleViewData.cs b/roles/lib/files/FWO.Report/Data/ViewData/RuleViewData.cs new file mode 100644 index 0000000000..96ff9f3e52 --- /dev/null +++ b/roles/lib/files/FWO.Report/Data/ViewData/RuleViewData.cs @@ -0,0 +1,151 @@ +using FWO.Basics; +using FWO.Basics.Interfaces; +using FWO.Data; +using FWO.Logging; +using FWO.Ui.Display; +using System.Text.Json; + +namespace FWO.Report.Data.ViewData +{ + public class RuleViewData : IRuleViewData + { + public string MgmtId { get; set; } = ""; + public string MgmtName { get; set; } = ""; + public string Uid { get; set; } = ""; + public string Name { get; set; } = ""; + public string Source { get; set; } = ""; + public string SourceShort { get; set; } = ""; + public string Destination { get; set; } = ""; + public string DestinationShort { get; set; } = ""; + public string Services { get; set; } = ""; + public string ServicesShort { get; set; } = ""; + public string Action { get; set; } = ""; + public string InstallOn { get; set; } = ""; + public string Compliance { get; set; } = ""; + public string ViolationDetails { get; set; } = ""; + public string ChangeID { get; set; } = ""; + public string AdoITID { get; set; } = ""; + public string Comment { get; set; } = ""; + public string LastModified { get; set; } = ""; + public string RulebaseId { get; set; } = ""; + public string RulebaseName { get; set; } = ""; + public string Enabled { get; set; } = ""; + public string RuleTime { get; set; } = ""; + public string ExpirationTime + { + get => RuleTime; + set => RuleTime = value; + } + + public Rule? DataObject { get; set; } + public bool Show { get; set; } = true; + public ILogger Logger { get; set; } = new Logger(); + + public RuleViewData() + { + + } + + public RuleViewData(Rule rule, NatRuleDisplayHtml natRuleDisplayHtml, OutputLocation outputLocation, bool show, List? devices = null, List? managements = null, ComplianceViolationType? complianceViolationType = null) + { + DataObject = rule; + Show = show; + + MgmtId = SafeCall(rule, "MgmtId", () => rule.MgmtId.ToString()); + MgmtName = SafeCall(rule, "MgmtName", () => managements?.FirstOrDefault(m => m.Id == rule.MgmtId)?.Name ?? ""); + Uid = SafeCall(rule, "Uid", () => rule.Uid ?? ""); + Name = SafeCall(rule, "Name", () => rule.Name ?? ""); + Source = SafeCall(rule, "Source", () => natRuleDisplayHtml.DisplaySource(rule, outputLocation, ReportType.ComplianceReport)); + SourceShort = SafeCall(rule, "Source (Short)", () => natRuleDisplayHtml.DisplaySource(rule, outputLocation, ReportType.ComplianceReport, overwriteIsResolvedReport: true)); + Destination = SafeCall(rule, "Destination", () => natRuleDisplayHtml.DisplayDestination(rule, outputLocation, ReportType.ComplianceReport)); + DestinationShort = SafeCall(rule, "Destination (Short)", () => natRuleDisplayHtml.DisplayDestination(rule, outputLocation, ReportType.ComplianceReport, overwriteIsResolvedReport: true)); + Services = SafeCall(rule, "Services", () => natRuleDisplayHtml.DisplayServices(rule, outputLocation, ReportType.ComplianceReport)); + ServicesShort = SafeCall(rule, "Services (Short)", () => natRuleDisplayHtml.DisplayServices(rule, outputLocation, ReportType.ComplianceReport, overwriteIsResolvedReport: true)); + Action = SafeCall(rule, "Action", () => rule.Action); + InstallOn = SafeCall(rule, "InstallOn", () => ResolveInstallOn(rule, devices ?? [])); + Compliance = SafeCall(rule, "Compliance", () => ResolveCompliance(rule, complianceViolationType)); + ViolationDetails = SafeCall(rule, "ViolationDetails", () => rule.ViolationDetails); + ChangeID = SafeCall(rule, "ChangeID", () => { var value = CustomFieldResolver.ExtractCustomFieldValue(rule, "[\"field-2\",\"Datum-Regelpruefung\"]", out var errorMessage); return value ?? errorMessage ?? ""; }); + AdoITID = SafeCall(rule, "AdoITID", () => { var value = CustomFieldResolver.ExtractCustomFieldValue(rule, "[\"field-3\",\"AdoIT\"]", out var errorMessage); return value ?? errorMessage ?? ""; }); + Comment = SafeCall(rule, "Comment", () => rule.Comment ?? ""); + LastModified = SafeCall(rule, "LastModified", () => RuleDisplayBase.DisplayLastModified(rule)); + RuleTime = SafeCall(rule, "RuleTime", () => natRuleDisplayHtml.DisplayRuleTime(rule)); + RulebaseId = SafeCall(rule, "RulebaseId", () => rule.RulebaseId.ToString()); + RulebaseName = SafeCall(rule, "RulebaseName", () => rule.Rulebase?.Name ?? ""); + Enabled = SafeCall(rule, "Enabled", () => RuleDisplayBase.DisplayEnabled(rule, outputLocation)); + } + + private string ResolveCompliance(Rule rule, ComplianceViolationType? complianceViolationType) + { + return (complianceViolationType ?? rule.Compliance) switch + { + ComplianceViolationType.NotAssessable => "NOT ASSESSABLE", + ComplianceViolationType.None => "TRUE", + _ => "FALSE" + }; + } + + private string ResolveInstallOn(Rule rule, List devices) + { + string installOn = ""; + + if (!string.IsNullOrWhiteSpace(rule.InstallOn)) + { + if (rule.InstallOn.Contains("|")) + { + List uids = rule.InstallOn.Split("|").Select(s => s.Trim()).ToList(); + + foreach (string uid in uids) + { + if (installOn.Length > 0) + { + installOn += " | "; + } + + string deviceName = devices.FirstOrDefault(device => device.Uid == uid)?.Name ?? uid; + installOn += deviceName; + } + } + else + { + installOn = devices.FirstOrDefault(device => device.Uid == rule.InstallOn)?.Name ?? rule.InstallOn; + } + } + + return installOn; + } + + private string SafeCall(Rule rule, string column, Func func) + { + try + { + string displayString = func(); + + if (string.IsNullOrWhiteSpace(displayString) && (column == "Source" || column == "Destination")) + { + string objects = ""; + + if (column == "Source") + { + objects = rule.Source; + } + else if (column == "Destination") + { + objects = rule.Destination; + } + + displayString = $"Silent error while resolving objects: {objects}"; + } + + return displayString; + + } + catch (Exception ex) + { + Log.WriteError($"Creating rule view data - Displayerror in rule {rule.Id} column {column}: {ex.Message}"); + return "Displayerror. Check log for details."; + } + } + + } +} diff --git a/roles/lib/files/FWO.Report/Display/NatRuleDisplayHtml.cs b/roles/lib/files/FWO.Report/Display/NatRuleDisplayHtml.cs index 3a73385f75..97aa2e7d4b 100644 --- a/roles/lib/files/FWO.Report/Display/NatRuleDisplayHtml.cs +++ b/roles/lib/files/FWO.Report/Display/NatRuleDisplayHtml.cs @@ -1,6 +1,8 @@ -using FWO.Api.Data; +using FWO.Basics; +using FWO.Data; using FWO.Config.Api; using System.Text; +using FWO.Report; using FWO.Report.Filter; namespace FWO.Ui.Display @@ -8,37 +10,37 @@ namespace FWO.Ui.Display public class NatRuleDisplayHtml : RuleDisplayHtml { public NatRuleDisplayHtml(UserConfig userConfig) : base(userConfig) - {} + { } - public string DisplayTranslatedSource(Rule rule, OutputLocation location, string style = "") + public string DisplayTranslatedSource(Rule rule, OutputLocation location, int chapterNumber = 0, string style = "") { - return DisplayTranslatedSourceOrDestination(rule, location, style, true); + return DisplayTranslatedSourceOrDestination(rule, chapterNumber, location, style, true); } - public string DisplayTranslatedDestination(Rule rule, OutputLocation location, string style = "") + public string DisplayTranslatedDestination(Rule rule, OutputLocation location, int chapterNumber = 0, string style = "") { - return DisplayTranslatedSourceOrDestination(rule, location, style, false); + return DisplayTranslatedSourceOrDestination(rule, chapterNumber, location, style, false); } - public string DisplayTranslatedService(Rule rule, OutputLocation location, string style = "") + public string DisplayTranslatedService(Rule rule, OutputLocation location, int chapterNumber = 0, string style = "") { - StringBuilder result = new StringBuilder(); + StringBuilder result = new(); if (rule.NatData.TranslatedServiceNegated) { result.AppendLine(userConfig.GetText("negated") + "
                      "); } - result.AppendJoin("
                      ", Array.ConvertAll(rule.NatData.TranslatedServices, service => ServiceToHtml(service.Content, rule.MgmtId, location, style, ReportType.NatRules))); + result.AppendJoin("
                      ", Array.ConvertAll(rule.NatData.TranslatedServices, service => ServiceToHtml(service.Content, rule.MgmtId, chapterNumber, location, style, ReportType.NatRules))); return result.ToString(); } - private string DisplayTranslatedSourceOrDestination(Rule rule, OutputLocation location, string style, bool isSource) + private string DisplayTranslatedSourceOrDestination(Rule rule, int chapterNumber, OutputLocation location, string style, bool isSource) { - StringBuilder result = new StringBuilder(); - if ((isSource && rule.NatData.TranslatedSourceNegated) ||(!isSource && rule.NatData.TranslatedDestinationNegated)) + StringBuilder result = new(); + if ((isSource && rule.NatData.TranslatedSourceNegated) || (!isSource && rule.NatData.TranslatedDestinationNegated)) { result.AppendLine(userConfig.GetText("negated") + "
                      "); } - result.AppendJoin("
                      ", Array.ConvertAll(isSource ? rule.NatData.TranslatedFroms : rule.NatData.TranslatedTos, networkLocation => NetworkLocationToHtml(networkLocation, rule.MgmtId, location, style, ReportType.NatRules))); + result.AppendJoin("
                      ", Array.ConvertAll(isSource ? rule.NatData.TranslatedFroms : rule.NatData.TranslatedTos, networkLocation => NetworkLocationToHtml(networkLocation, rule.MgmtId, chapterNumber, location, style, ReportType.NatRules))); return result.ToString(); } } diff --git a/roles/lib/files/FWO.Report/Display/NwObjDisplay.cs b/roles/lib/files/FWO.Report/Display/NwObjDisplay.cs new file mode 100644 index 0000000000..e4d39cccb9 --- /dev/null +++ b/roles/lib/files/FWO.Report/Display/NwObjDisplay.cs @@ -0,0 +1,18 @@ +using FWO.Basics; +using FWO.Data; + +namespace FWO.Ui.Display +{ + public static class NwObjDisplay + { + public static string DisplayIp(string ip1, string ip2, bool inBrackets = false) + { + return DisplayBase.DisplayIp(ip1, ip2, inBrackets); + } + + public static string DisplayIp(string ip1, string ip2, string nwObjType, bool inBrackets = false) + { + return DisplayBase.DisplayIp(ip1, ip2, nwObjType, inBrackets); + } + } +} diff --git a/roles/lib/files/FWO.Report/Display/RuleChangeDisplayCsv.cs b/roles/lib/files/FWO.Report/Display/RuleChangeDisplayCsv.cs index 01b2b14270..bd9d86d603 100644 --- a/roles/lib/files/FWO.Report/Display/RuleChangeDisplayCsv.cs +++ b/roles/lib/files/FWO.Report/Display/RuleChangeDisplayCsv.cs @@ -1,4 +1,5 @@ -using FWO.Api.Data; +using FWO.Basics; +using FWO.Data; using FWO.Config.Api; using FWO.Report.Filter; @@ -14,6 +15,19 @@ public string DisplayChangeTime(RuleChange ruleChange) return OutputCsv(ruleChange.ChangeImport.Time.ToString()); } + public string DisplayChangeTime(ObjectChange objectChange) + { + return OutputCsv(objectChange.ChangeImport.Time.ToString()); + } + public string DisplayChangeTime(ServiceChange serviceChange) + { + return OutputCsv(serviceChange.ChangeImport.Time.ToString()); + } + public string DisplayChangeTime(UserChange userChange) + { + return OutputCsv(userChange.ChangeImport.Time.ToString()); + } + public string DisplayChangeAction(RuleChange ruleChange) { switch (ruleChange.ChangeAction) @@ -24,6 +38,38 @@ public string DisplayChangeAction(RuleChange ruleChange) default: return ","; } } + public string DisplayChangeAction(ObjectChange objectChange) + { + switch (objectChange.ChangeAction) + { + case 'I': return OutputCsv(userConfig.GetText("network_object_added")); + case 'D': return OutputCsv(userConfig.GetText("network_object_deleted")); + case 'C': return OutputCsv(userConfig.GetText("network_object_modified")); + default: return ","; + } + } + + public string DisplayChangeAction(ServiceChange serviceChange) + { + switch (serviceChange.ChangeAction) + { + case 'I': return OutputCsv(userConfig.GetText("service_added")); + case 'D': return OutputCsv(userConfig.GetText("service_deleted")); + case 'C': return OutputCsv(userConfig.GetText("service_modified")); + default: return ","; + } + } + + public string DisplayChangeAction(UserChange userChange) + { + switch (userChange.ChangeAction) + { + case 'I': return OutputCsv(userConfig.GetText("user_added")); + case 'D': return OutputCsv(userConfig.GetText("user_deleted")); + case 'C': return OutputCsv(userConfig.GetText("user_modified")); + default: return ","; + } + } public string DisplayName(RuleChange ruleChange) { @@ -36,13 +82,44 @@ public string DisplayName(RuleChange ruleChange) } } + public string DisplayName(ObjectChange objectChange) + { + switch (objectChange.ChangeAction) + { + case 'D': return OutputCsv(DisplayName(objectChange.OldObject)); + case 'I': return OutputCsv(DisplayName(objectChange.NewObject)); + case 'C': return OutputCsv(DisplayDiff(DisplayName(objectChange.OldObject), DisplayName(objectChange.NewObject))); + default: return ","; + } + } + public string DisplayName(ServiceChange serviceChange) + { + switch (serviceChange.ChangeAction) + { + case 'D': return OutputCsv(DisplayName(serviceChange.OldService)); + case 'I': return OutputCsv(DisplayName(serviceChange.NewService)); + case 'C': return OutputCsv(DisplayDiff(DisplayName(serviceChange.OldService), DisplayName(serviceChange.NewService))); + default: return ","; + } + } + public string DisplayName(UserChange userChange) + { + switch (userChange.ChangeAction) + { + case 'D': return OutputCsv(DisplayName(userChange.OldUser)); + case 'I': return OutputCsv(DisplayName(userChange.NewUser)); + case 'C': return OutputCsv(DisplayDiff(DisplayName(userChange.OldUser), DisplayName(userChange.NewUser))); + default: return ","; + } + } + public string DisplaySourceZone(RuleChange ruleChange) { switch (ruleChange.ChangeAction) { - case 'D': return OutputCsv(DisplaySourceZone(ruleChange.OldRule)); - case 'I': return OutputCsv(DisplaySourceZone(ruleChange.NewRule)); - case 'C': return OutputCsv(DisplayDiff(DisplaySourceZone(ruleChange.OldRule), DisplaySourceZone(ruleChange.NewRule))); + case 'D': return OutputCsv(ListNetworkZones(ruleChange.OldRule.RuleFromZones.Select(z => z.Content).ToArray())); + case 'I': return OutputCsv(ListNetworkZones(ruleChange.NewRule.RuleFromZones.Select(z => z.Content).ToArray())); + case 'C': return OutputCsv(DisplayDiff(ListNetworkZones(ruleChange.OldRule.RuleFromZones.Select(z => z.Content).ToArray()), ListNetworkZones(ruleChange.NewRule.RuleFromZones.Select(z => z.Content).ToArray()))); default: return ","; } } @@ -62,9 +139,9 @@ public string DisplayDestinationZone(RuleChange ruleChange) { switch (ruleChange.ChangeAction) { - case 'D': return OutputCsv(DisplayDestinationZone(ruleChange.OldRule)); - case 'I': return OutputCsv(DisplayDestinationZone(ruleChange.NewRule)); - case 'C': return OutputCsv(DisplayDiff(DisplayDestinationZone(ruleChange.OldRule), DisplayDestinationZone(ruleChange.NewRule))); + case 'D': return OutputCsv(ListNetworkZones(ruleChange.OldRule.RuleToZones.Select(z => z.Content).ToArray())); + case 'I': return OutputCsv(ListNetworkZones(ruleChange.NewRule.RuleToZones.Select(z => z.Content).ToArray())); + case 'C': return OutputCsv(DisplayDiff(ListNetworkZones(ruleChange.OldRule.RuleToZones.Select(z => z.Content).ToArray()), ListNetworkZones(ruleChange.NewRule.RuleToZones.Select(z => z.Content).ToArray()))); default: return ","; } } @@ -124,6 +201,17 @@ public string DisplayEnabled(RuleChange ruleChange) } } + public string DisplayenforcingDevice(RuleChange ruleChange) + { + switch (ruleChange.ChangeAction) + { + case 'D': return OutputCsv(DisplayEnforcingGateways(ruleChange.OldRule)); + case 'I': return OutputCsv(DisplayEnforcingGateways(ruleChange.NewRule)); + case 'C': return OutputCsv(DisplayDiff(DisplayEnforcingGateways(ruleChange.OldRule), DisplayEnforcingGateways(ruleChange.NewRule))); + default: return ","; + } + } + public string DisplayUid(RuleChange ruleChange) { switch (ruleChange.ChangeAction) @@ -134,6 +222,26 @@ public string DisplayUid(RuleChange ruleChange) default: return ","; } } + public string DisplayUid(ObjectChange objectChange) + { + switch (objectChange.ChangeAction) + { + case 'D': return OutputCsv(DisplayUid(objectChange.OldObject)); + case 'I': return OutputCsv(DisplayUid(objectChange.NewObject)); + case 'C': return OutputCsv(DisplayDiff(DisplayUid(objectChange.OldObject), DisplayUid(objectChange.NewObject))); + default: return ","; + } + } + public string DisplayUid(ServiceChange serviceChange) + { + switch (serviceChange.ChangeAction) + { + case 'D': return OutputCsv(DisplayUid(serviceChange.OldService)); + case 'I': return OutputCsv(DisplayUid(serviceChange.NewService)); + case 'C': return OutputCsv(DisplayDiff(DisplayUid(serviceChange.OldService), DisplayUid(serviceChange.NewService))); + default: return ","; + } + } public string DisplayComment(RuleChange ruleChange) { @@ -146,6 +254,114 @@ public string DisplayComment(RuleChange ruleChange) } } + public string DisplayComment(ObjectChange objectChange) + { + switch (objectChange.ChangeAction) + { + case 'D': return OutputCsv(DisplayComment(objectChange.OldObject)); + case 'I': return OutputCsv(DisplayComment(objectChange.NewObject)); + case 'C': return OutputCsv(DisplayDiff(DisplayComment(objectChange.OldObject), DisplayComment(objectChange.NewObject))); + default: return ""; + } + } + public string DisplayComment(ServiceChange serviceChange) + { + switch (serviceChange.ChangeAction) + { + case 'D': return OutputCsv(DisplayComment(serviceChange.OldService)); + case 'I': return OutputCsv(DisplayComment(serviceChange.NewService)); + case 'C': return OutputCsv(DisplayDiff(DisplayComment(serviceChange.OldService), DisplayComment(serviceChange.NewService))); + default: return ""; + } + } + + public string DisplayComment(UserChange userChange) + { + switch (userChange.ChangeAction) + { + case 'D': return OutputCsv(DisplayComment(userChange.OldUser)); + case 'I': return OutputCsv(DisplayComment(userChange.NewUser)); + case 'C': return OutputCsv(DisplayDiff(DisplayComment(userChange.OldUser), DisplayComment(userChange.NewUser))); + default: return ""; + } + } + + public string DisplayObjectType(ObjectChange objectChange) + { + switch (objectChange.ChangeAction) + { + case 'D': return OutputCsv(objectChange.OldObject.Type.Name); + case 'I': return OutputCsv(objectChange.NewObject.Type.Name); + case 'C': return OutputCsv(DisplayDiff(objectChange.OldObject.Type.Name, objectChange.NewObject.Type.Name)); + default: return ""; + } + } + + public string DisplayObjectIp(ObjectChange objectChange) + { + switch (objectChange.ChangeAction) + { + case 'D': return OutputCsv(NwObjDisplay.DisplayIp(objectChange.OldObject.IP, objectChange.OldObject.IpEnd, true)); + case 'I': return OutputCsv(NwObjDisplay.DisplayIp(objectChange.NewObject.IP, objectChange.NewObject.IpEnd, true)); + case 'C': return OutputCsv(DisplayDiff(NwObjDisplay.DisplayIp(objectChange.OldObject.IP, objectChange.OldObject.IpEnd, true), NwObjDisplay.DisplayIp(objectChange.NewObject.IP, objectChange.NewObject.IpEnd, true))); + default: return ""; + } + } + public string DisplayObjectMemberNames(ObjectChange objectChange) + { + switch (objectChange.ChangeAction) + { + case 'D': return OutputCsv(DisplayBase.MemberNamesAsCSV(objectChange.OldObject.MemberNames)); + case 'I': return OutputCsv(DisplayBase.MemberNamesAsCSV(objectChange.NewObject.MemberNames)); + case 'C': return OutputCsv(DisplayDiff(DisplayBase.MemberNamesAsCSV(objectChange.OldObject.MemberNames), DisplayBase.MemberNamesAsCSV(objectChange.NewObject.MemberNames))); + default: return ""; + } + } + + public string DisplayServiceMemberNames(ServiceChange serviceChange) + { + switch (serviceChange.ChangeAction) + { + case 'D': return OutputCsv(DisplayBase.MemberNamesAsCSV(serviceChange.OldService.MemberNames)); + case 'I': return OutputCsv(DisplayBase.MemberNamesAsCSV(serviceChange.NewService.MemberNames)); + case 'C': return OutputCsv(DisplayDiff(DisplayBase.MemberNamesAsCSV(serviceChange.OldService.MemberNames), DisplayBase.MemberNamesAsCSV(serviceChange.NewService.MemberNames))); + default: return ""; + } + } + + public string DisplayServiceType(ServiceChange serviceChange) + { + switch (serviceChange.ChangeAction) + { + case 'D': return OutputCsv(serviceChange.OldService.Type.Name); + case 'I': return OutputCsv(serviceChange.NewService.Type.Name); + case 'C': return OutputCsv(DisplayDiff(serviceChange.OldService.Type.Name, serviceChange.NewService.Type.Name)); + default: return ""; + } + } + + public string DisplayServiceProtocol(ServiceChange serviceChange) + { + switch (serviceChange.ChangeAction) + { + case 'D': return OutputCsv(serviceChange.OldService.Protocol?.Name ?? ""); + case 'I': return OutputCsv(serviceChange.NewService.Protocol?.Name ?? ""); + case 'C': return OutputCsv(DisplayDiff(serviceChange.OldService.Protocol?.Name ?? "", serviceChange.NewService.Protocol?.Name ?? "")); + default: return ""; + } + } + + public string DisplayServicePort(ServiceChange serviceChange) + { + switch (serviceChange.ChangeAction) + { + case 'D': return OutputCsv(DisplayBase.DisplayPort(serviceChange.OldService.DestinationPort, serviceChange.OldService.DestinationPortEnd, true)); + case 'I': return OutputCsv(DisplayBase.DisplayPort(serviceChange.NewService.DestinationPort, serviceChange.NewService.DestinationPortEnd, true)); + case 'C': return OutputCsv(DisplayDiff(DisplayBase.DisplayPort(serviceChange.OldService.DestinationPort, serviceChange.OldService.DestinationPortEnd, true), (DisplayBase.DisplayPort(serviceChange.NewService.DestinationPort, serviceChange.NewService.DestinationPortEnd, true)))); + default: return ""; + } + } + private string DisplayDiff(string oldElement, string newElement) { if (oldElement == newElement) @@ -173,7 +389,7 @@ private string DisplayArrayDiff(string oldElement, string newElement, bool oldNe oldElement = oldElement.Replace("\"", ""); newElement = newElement.Replace("\"", ""); - if(oldNegated != newNegated) + if (oldNegated != newNegated) { deleted.Add(oldElement); added.Add(newElement); @@ -183,7 +399,7 @@ private string DisplayArrayDiff(string oldElement, string newElement, bool oldNe AnalyzeElements(oldElement, newElement, ref unchanged, ref deleted, ref added); } - return string.Join(" ", unchanged) + return string.Join(" ", unchanged) + (deleted.Count > 0 ? $" {userConfig.GetText("deleted")}: {string.Join(",", deleted)}" : "") + (added.Count > 0 ? $" {userConfig.GetText("added")}: {string.Join(",", added)}" : ""); } diff --git a/roles/lib/files/FWO.Report/Display/RuleChangeDisplayHtml.cs b/roles/lib/files/FWO.Report/Display/RuleChangeDisplayHtml.cs index 6ebd167e48..418bff72b8 100644 --- a/roles/lib/files/FWO.Report/Display/RuleChangeDisplayHtml.cs +++ b/roles/lib/files/FWO.Report/Display/RuleChangeDisplayHtml.cs @@ -1,15 +1,16 @@ -using FWO.Api.Data; -using FWO.Logging; +using FWO.Basics; using FWO.Config.Api; -using FWO.Report.Filter; +using FWO.Data; +using FWO.Logging; +using FWO.Report; +using Microsoft.AspNetCore.Components; +using System.Data; +using System.Data.Common; namespace FWO.Ui.Display { public class RuleChangeDisplayHtml : RuleDisplayHtml { - static string addedStyle = "color: green; text-decoration: bold;"; - static string deletedStyle = "color: red; text-decoration: line-through red;"; - public RuleChangeDisplayHtml(UserConfig userConfig) : base(userConfig) { } @@ -18,6 +19,20 @@ public string DisplayChangeTime(RuleChange ruleChange) return ruleChange.ChangeImport.Time.ToString(); } + public string DisplayChangeTime(ObjectChange objectChange) + { + return objectChange.ChangeImport.Time.ToString(); + } + + public string DisplayChangeTime(ServiceChange serviceChange) + { + return serviceChange.ChangeImport.Time.ToString(); + } + public string DisplayChangeTime(UserChange userChange) + { + return userChange.ChangeImport.Time.ToString(); + } + public string DisplayChangeAction(RuleChange ruleChange) { switch (ruleChange.ChangeAction) @@ -29,6 +44,39 @@ public string DisplayChangeAction(RuleChange ruleChange) } } + public string DisplayChangeAction(ObjectChange objectChange) + { + switch (objectChange.ChangeAction) + { + case 'I': return userConfig.GetText("network_object_added"); + case 'D': return userConfig.GetText("network_object_deleted"); + case 'C': return userConfig.GetText("network_object_modified"); + default: ThrowErrorUnknowChangeAction(objectChange.ChangeAction); return ""; + } + } + + public string DisplayChangeAction(ServiceChange serviceChange) + { + switch (serviceChange.ChangeAction) + { + case 'I': return userConfig.GetText("service_added"); + case 'D': return userConfig.GetText("service_deleted"); + case 'C': return userConfig.GetText("service_modified"); + default: ThrowErrorUnknowChangeAction(serviceChange.ChangeAction); return ""; + } + } + + public string DisplayChangeAction(UserChange userChange) + { + switch (userChange.ChangeAction) + { + case 'I': return userConfig.GetText("user_added"); + case 'D': return userConfig.GetText("user_deleted"); + case 'C': return userConfig.GetText("user_modified"); + default: ThrowErrorUnknowChangeAction(userChange.ChangeAction); return ""; + } + } + public string DisplayName(RuleChange ruleChange) { switch (ruleChange.ChangeAction) @@ -40,13 +88,46 @@ public string DisplayName(RuleChange ruleChange) } } + public string DisplayName(ObjectChange objectChange) + { + switch (objectChange.ChangeAction) + { + case 'D': return OutputHtmlDeleted(DisplayName(objectChange.OldObject)); + case 'I': return OutputHtmlAdded(DisplayName(objectChange.NewObject)); + case 'C': return DisplayDiff(DisplayName(objectChange.OldObject), DisplayName(objectChange.NewObject)); + default: ThrowErrorUnknowChangeAction(objectChange.ChangeAction); return ""; + } + } + + public string DisplayName(ServiceChange serviceChange) + { + switch (serviceChange.ChangeAction) + { + case 'D': return OutputHtmlDeleted(DisplayName(serviceChange.OldService)); + case 'I': return OutputHtmlAdded(DisplayName(serviceChange.NewService)); + case 'C': return DisplayDiff(DisplayName(serviceChange.OldService), DisplayName(serviceChange.NewService)); + default: ThrowErrorUnknowChangeAction(serviceChange.ChangeAction); return ""; + } + } + + public string DisplayName(UserChange userChange) + { + switch (userChange.ChangeAction) + { + case 'D': return OutputHtmlDeleted(DisplayName(userChange.NewUser)); + case 'I': return OutputHtmlAdded(DisplayName(userChange.NewUser)); + case 'C': return DisplayDiff(DisplayName(userChange.OldUser), DisplayName(userChange.NewUser)); + default: ThrowErrorUnknowChangeAction(userChange.ChangeAction); return ""; + } + } + public string DisplaySourceZone(RuleChange ruleChange) { switch (ruleChange.ChangeAction) { - case 'D': return OutputHtmlDeleted(DisplaySourceZone(ruleChange.OldRule)); - case 'I': return OutputHtmlAdded(DisplaySourceZone(ruleChange.NewRule)); - case 'C': return DisplayDiff(DisplaySourceZone(ruleChange.OldRule), DisplaySourceZone(ruleChange.NewRule)); + case 'D': return OutputHtmlDeleted(DisplaySourceZones(ruleChange.OldRule)); + case 'I': return OutputHtmlAdded(DisplaySourceZones(ruleChange.NewRule)); + case 'C': return DisplayDiff(DisplaySourceZones(ruleChange.OldRule), DisplaySourceZones(ruleChange.NewRule)); default: ThrowErrorUnknowChangeAction(ruleChange.ChangeAction); return ""; } } @@ -55,9 +136,10 @@ public string DisplaySource(RuleChange ruleChange, OutputLocation location, Repo { switch (ruleChange.ChangeAction) { - case 'D': return OutputHtmlDeleted(DisplaySource(ruleChange.OldRule, location, reportType, deletedStyle)); - case 'I': return OutputHtmlAdded(DisplaySource(ruleChange.NewRule, location, reportType, addedStyle)); - case 'C': return DisplayArrayDiff(DisplaySource(ruleChange.OldRule, location, reportType), + case 'D': return OutputHtmlDeleted(DisplaySource(ruleChange.OldRule, location, reportType, 0, GlobalConst.kStyleDeleted)); + case 'I': return OutputHtmlAdded(DisplaySource(ruleChange.NewRule, location, reportType, 0, GlobalConst.kStyleAdded)); + case 'C': + return DisplayArrayDiff(DisplaySource(ruleChange.OldRule, location, reportType), DisplaySource(ruleChange.NewRule, location, reportType), ruleChange.OldRule.SourceNegated, ruleChange.NewRule.SourceNegated); default: ThrowErrorUnknowChangeAction(ruleChange.ChangeAction); return ""; @@ -68,9 +150,9 @@ public string DisplayDestinationZone(RuleChange ruleChange) { switch (ruleChange.ChangeAction) { - case 'D': return OutputHtmlDeleted(DisplayDestinationZone(ruleChange.OldRule)); - case 'I': return OutputHtmlAdded(DisplayDestinationZone(ruleChange.NewRule)); - case 'C': return DisplayDiff(DisplayDestinationZone(ruleChange.OldRule), DisplayDestinationZone(ruleChange.NewRule)); + case 'D': return OutputHtmlDeleted(DisplayDestinationZones(ruleChange.OldRule)); + case 'I': return OutputHtmlAdded(DisplayDestinationZones(ruleChange.NewRule)); + case 'C': return DisplayDiff(DisplayDestinationZones(ruleChange.OldRule), DisplayDestinationZones(ruleChange.NewRule)); default: ThrowErrorUnknowChangeAction(ruleChange.ChangeAction); return ""; } } @@ -79,9 +161,10 @@ public string DisplayDestination(RuleChange ruleChange, OutputLocation location, { switch (ruleChange.ChangeAction) { - case 'D': return OutputHtmlDeleted(DisplayDestination(ruleChange.OldRule, location, reportType, deletedStyle)); - case 'I': return OutputHtmlAdded(DisplayDestination(ruleChange.NewRule, location, reportType, addedStyle)); - case 'C': return DisplayArrayDiff(DisplayDestination(ruleChange.OldRule, location, reportType), + case 'D': return OutputHtmlDeleted(DisplayDestination(ruleChange.OldRule, location, reportType, 0, GlobalConst.kStyleDeleted)); + case 'I': return OutputHtmlAdded(DisplayDestination(ruleChange.NewRule, location, reportType, 0, GlobalConst.kStyleAdded)); + case 'C': + return DisplayArrayDiff(DisplayDestination(ruleChange.OldRule, location, reportType), DisplayDestination(ruleChange.NewRule, location, reportType), ruleChange.OldRule.DestinationNegated, ruleChange.NewRule.DestinationNegated); default: ThrowErrorUnknowChangeAction(ruleChange.ChangeAction); return ""; @@ -92,9 +175,10 @@ public string DisplayServices(RuleChange ruleChange, OutputLocation location, Re { switch (ruleChange.ChangeAction) { - case 'D': return OutputHtmlDeleted(DisplayServices(ruleChange.OldRule, location, reportType, deletedStyle)); - case 'I': return OutputHtmlAdded(DisplayServices(ruleChange.NewRule, location, reportType, addedStyle)); - case 'C': return DisplayArrayDiff(DisplayServices(ruleChange.OldRule, location, reportType), + case 'D': return OutputHtmlDeleted(DisplayServices(ruleChange.OldRule, location, reportType, 0, GlobalConst.kStyleDeleted)); + case 'I': return OutputHtmlAdded(DisplayServices(ruleChange.NewRule, location, reportType, 0, GlobalConst.kStyleAdded)); + case 'C': + return DisplayArrayDiff(DisplayServices(ruleChange.OldRule, location, reportType), DisplayServices(ruleChange.NewRule, location, reportType), ruleChange.OldRule.ServiceNegated, ruleChange.NewRule.ServiceNegated); default: ThrowErrorUnknowChangeAction(ruleChange.ChangeAction); return ""; @@ -145,6 +229,39 @@ public string DisplayUid(RuleChange ruleChange) } } + public string DisplayUid(ObjectChange objectChange) + { + switch (objectChange.ChangeAction) + { + case 'D': return OutputHtmlDeleted(objectChange.OldObject.Uid); + case 'I': return OutputHtmlAdded(objectChange.NewObject.Uid); + case 'C': return DisplayDiff(objectChange.OldObject.Uid, objectChange.NewObject.Uid); + default: ThrowErrorUnknowChangeAction(objectChange.ChangeAction); return ""; + } + } + + public string DisplayUid(ServiceChange serviceChange) + { + switch (serviceChange.ChangeAction) + { + case 'D': return OutputHtmlDeleted(serviceChange.OldService.Uid); + case 'I': return OutputHtmlAdded(serviceChange.NewService.Uid); + case 'C': return DisplayDiff(serviceChange.OldService.Uid, serviceChange.NewService.Uid); + default: ThrowErrorUnknowChangeAction(serviceChange.ChangeAction); return ""; + } + } + + public string DisplayEnforcingGateways(RuleChange ruleChange, OutputLocation location, ReportType reportType) + { + switch (ruleChange.ChangeAction) + { + case 'D': return OutputHtmlDeleted(DisplayEnforcingGateways(ruleChange.OldRule, location, reportType)); + case 'I': return OutputHtmlAdded(DisplayEnforcingGateways(ruleChange.NewRule, location, reportType)); + case 'C': return DisplayDiff(DisplayEnforcingGateways(ruleChange.OldRule, location, reportType), DisplayEnforcingGateways(ruleChange.NewRule, location, reportType)); + default: ThrowErrorUnknowChangeAction(ruleChange.ChangeAction); return ""; + } + } + public string DisplayComment(RuleChange ruleChange) { switch (ruleChange.ChangeAction) @@ -156,17 +273,160 @@ public string DisplayComment(RuleChange ruleChange) } } + public string DisplayComment(ObjectChange objectChange) + { + switch (objectChange.ChangeAction) + { + case 'D': return OutputHtmlDeleted(objectChange.OldObject.Comment); + case 'I': return OutputHtmlAdded(objectChange.NewObject.Comment); + case 'C': return DisplayDiff(objectChange.OldObject.Comment, objectChange.NewObject.Comment); + default: ThrowErrorUnknowChangeAction(objectChange.ChangeAction); return ""; + } + } + + public string DisplayComment(ServiceChange serviceChange) + { + switch (serviceChange.ChangeAction) + { + case 'D': return OutputHtmlDeleted(serviceChange.OldService.Comment); + case 'I': return OutputHtmlAdded(serviceChange.NewService.Comment); + case 'C': return DisplayDiff(serviceChange.OldService.Comment, serviceChange.NewService.Comment); + default: ThrowErrorUnknowChangeAction(serviceChange.ChangeAction); return ""; + } + } + + public string DisplayComment(UserChange userChange) + { + switch (userChange.ChangeAction) + { + case 'D': return OutputHtmlDeleted(userChange.OldUser.Comment); + case 'I': return OutputHtmlAdded(userChange.NewUser.Comment); + case 'C': return DisplayDiff(userChange.OldUser.Comment, userChange.NewUser.Comment); + default: ThrowErrorUnknowChangeAction(userChange.ChangeAction); return ""; + } + } + public string DisplayStyle(RuleChange ruleChange) { switch (ruleChange.ChangeAction) { - case 'D': return deletedStyle; - case 'I': return addedStyle; + case 'D': return GlobalConst.kStyleDeleted; + case 'I': return GlobalConst.kStyleAdded; case 'C': return ""; default: ThrowErrorUnknowChangeAction(ruleChange.ChangeAction); return ""; } } + public string DisplayStyle(ObjectChange objectChange) + { + switch (objectChange.ChangeAction) + { + case 'D': return GlobalConst.kStyleDeleted; + case 'I': return GlobalConst.kStyleAdded; + case 'C': return ""; + default: ThrowErrorUnknowChangeAction(objectChange.ChangeAction); return ""; + } + } + + public string DisplayStyle(ServiceChange serviceChange) + { + switch (serviceChange.ChangeAction) + { + case 'D': return GlobalConst.kStyleDeleted; + case 'I': return GlobalConst.kStyleAdded; + case 'C': return ""; + default: ThrowErrorUnknowChangeAction(serviceChange.ChangeAction); return ""; + } + } + + public string DisplayStyle(UserChange userChange) + { + switch (userChange.ChangeAction) + { + case 'D': return GlobalConst.kStyleDeleted; + case 'I': return GlobalConst.kStyleAdded; + case 'C': return ""; + default: ThrowErrorUnknowChangeAction(userChange.ChangeAction); return ""; + } + } + + public string DisplayObjectIP(ObjectChange objectChange) + { + switch (objectChange.ChangeAction) + { + case 'D': return OutputHtmlDeleted(NwObjDisplay.DisplayIp(objectChange.OldObject.IP, objectChange.OldObject.IpEnd, true)); + case 'I': return OutputHtmlAdded(NwObjDisplay.DisplayIp(objectChange.NewObject.IP, objectChange.NewObject.IpEnd, true)); + case 'C': return DisplayDiff(NwObjDisplay.DisplayIp(objectChange.OldObject.IP, objectChange.OldObject.IpEnd, true), NwObjDisplay.DisplayIp(objectChange.NewObject.IP, objectChange.NewObject.IpEnd, true)); + default: ThrowErrorUnknowChangeAction(objectChange.ChangeAction); return ""; + } + } + + public string DisplayObjectType(ObjectChange objectChange) + { + switch (objectChange.ChangeAction) + { + case 'D': return OutputHtmlDeleted(objectChange.OldObject.Type.Name); + case 'I': return OutputHtmlAdded(objectChange.NewObject.Type.Name); + case 'C': return DisplayDiff(objectChange.OldObject.Type.Name, objectChange.NewObject.Type.Name); + default: ThrowErrorUnknowChangeAction(objectChange.ChangeAction); return ""; + } + } + + public string DisplayServiceType(ServiceChange serviceChange) + { + switch (serviceChange.ChangeAction) + { + case 'D': return OutputHtmlDeleted(serviceChange.OldService.Type.Name); + case 'I': return OutputHtmlAdded(serviceChange.NewService.Type.Name); + case 'C': return DisplayDiff(serviceChange.OldService.Type.Name, serviceChange.NewService.Type.Name); + default: ThrowErrorUnknowChangeAction(serviceChange.ChangeAction); return ""; + } + } + + public string DisplayObjectMemberNames(ObjectChange objectChange) + { + switch (objectChange.ChangeAction) + { + case 'D': return OutputHtmlDeleted(DisplayBase.MemberNamesWithoutHtml(objectChange.OldObject.MemberNames)); + case 'I': return OutputHtmlAdded(DisplayBase.MemberNamesWithoutHtml(objectChange.NewObject.MemberNames)); + case 'C': return DisplayDiff(DisplayBase.MemberNamesWithoutHtml(objectChange.OldObject.MemberNames), DisplayBase.MemberNamesWithoutHtml(objectChange.NewObject.MemberNames)); + default: ThrowErrorUnknowChangeAction(objectChange.ChangeAction); return ""; + } + } + + public string DisplayServiceMemberNames(ServiceChange serviceChange) + { + switch (serviceChange.ChangeAction) + { + case 'D': return OutputHtmlDeleted(DisplayBase.MemberNamesWithoutHtml(serviceChange.OldService.MemberNames)); + case 'I': return OutputHtmlAdded(DisplayBase.MemberNamesWithoutHtml(serviceChange.NewService.MemberNames)); + case 'C': return DisplayDiff(DisplayBase.MemberNamesWithoutHtml(serviceChange.OldService.MemberNames), DisplayBase.MemberNamesWithoutHtml(serviceChange.NewService.MemberNames)); + default: ThrowErrorUnknowChangeAction(serviceChange.ChangeAction); return ""; + } + } + + public string DisplayServiceProtocol(ServiceChange serviceChange) + { + switch (serviceChange.ChangeAction) + { + case 'D': return OutputHtmlDeleted(serviceChange.OldService.Protocol?.Name ?? ""); + case 'I': return OutputHtmlAdded(serviceChange.NewService.Protocol?.Name ?? ""); + case 'C': return DisplayDiff(serviceChange.OldService.Protocol?.Name ?? "", serviceChange.NewService.Protocol?.Name ?? ""); + default: ThrowErrorUnknowChangeAction(serviceChange.ChangeAction); return ""; + } + } + + public string DisplayServicePort(ServiceChange serviceChange) + { + switch (serviceChange.ChangeAction) + { + case 'D': return OutputHtmlDeleted(DisplayBase.DisplayPort(serviceChange.OldService.DestinationPort, serviceChange.OldService.DestinationPortEnd, true)); + case 'I': return OutputHtmlAdded(DisplayBase.DisplayPort(serviceChange.NewService.DestinationPort, serviceChange.NewService.DestinationPortEnd, true)); + case 'C': return DisplayDiff(DisplayBase.DisplayPort(serviceChange.OldService.DestinationPort, serviceChange.OldService.DestinationPortEnd, true), (DisplayBase.DisplayPort(serviceChange.NewService.DestinationPort, serviceChange.NewService.DestinationPortEnd, true))); + default: ThrowErrorUnknowChangeAction(serviceChange.ChangeAction); return ""; + } + } + private string DisplayDiff(string oldElement, string newElement) { if (oldElement == newElement) @@ -175,15 +435,17 @@ private string DisplayDiff(string oldElement, string newElement) } else { - return (oldElement.Length > 0 ? $"{userConfig.GetText("deleted")}:

                      {oldElement}

                      " : "") - + (newElement.Length > 0 ? $"{userConfig.GetText("added")}:

                      {newElement}

                      " : ""); + return (oldElement.Length > 0 ? $"{userConfig.GetText("deleted")}:

                      {oldElement}

                      " : "") + + (newElement.Length > 0 ? $"{userConfig.GetText("added")}:

                      {newElement}

                      " : ""); } } private string DisplayArrayDiff(string oldElement, string newElement, bool oldNegated, bool newNegated) { if (oldElement == newElement) + { return oldElement; + } else { oldElement = oldElement.Replace("

                      ", ""); @@ -192,18 +454,18 @@ private string DisplayArrayDiff(string oldElement, string newElement, bool oldNe newElement = newElement.Replace("

                      ", ""); newElement = newElement.Replace("

                      ", ""); newElement = newElement.Replace("\r\n", ""); - List unchanged = new List(); - List added = new List(); - List deleted = new List(); + List unchanged = []; + List added = []; + List deleted = []; - if(oldNegated != newNegated) + if (oldNegated != newNegated) { - deleted.Add(setStyle(oldElement, deletedStyle)); - added.Add(setStyle(newElement, addedStyle)); + deleted.Add(SetStyle(oldElement, GlobalConst.kStyleDeleted)); + added.Add(SetStyle(newElement, GlobalConst.kStyleAdded)); } else { - string[] separatingStrings = { "
                      " }; + string[] separatingStrings = ["
                      "]; string[] oldAr = oldElement.Split(separatingStrings, System.StringSplitOptions.RemoveEmptyEntries); string[] newAr = newElement.Split(separatingStrings, System.StringSplitOptions.RemoveEmptyEntries); @@ -215,40 +477,40 @@ private string DisplayArrayDiff(string oldElement, string newElement, bool oldNe } else { - deleted.Add(setStyle(item, deletedStyle)); + deleted.Add(SetStyle(item, GlobalConst.kStyleDeleted)); } } foreach (var item in newAr) { if (!oldAr.Contains(item)) { - added.Add(setStyle(item, addedStyle)); + added.Add(SetStyle(item, GlobalConst.kStyleAdded)); } } } return (unchanged.Count > 0 ? $"

                      {string.Join("
                      ", unchanged)}

                      " : "") - + (deleted.Count > 0 ? $"{userConfig.GetText("deleted")}:

                      {string.Join("
                      ", deleted)}

                      " : "") - + (added.Count > 0 ? $"{userConfig.GetText("added")}:

                      {string.Join("
                      ", added)}

                      " : ""); + + (deleted.Count > 0 ? $"{userConfig.GetText("deleted")}:

                      {string.Join("
                      ", deleted)}

                      " : "") + + (added.Count > 0 ? $"{userConfig.GetText("added")}:

                      {string.Join("
                      ", added)}

                      " : ""); } } - - private string OutputHtmlDeleted(string? input) + + private static string OutputHtmlDeleted(string? input) { - return input != null && input != "" ? $"

                      {input}

                      " : ""; + return input != null && input != "" ? $"

                      {input}

                      " : ""; } - private string OutputHtmlAdded(string? input) + private static string OutputHtmlAdded(string? input) { - return input != null && input != "" ? $"

                      {input}

                      " : ""; + return input != null && input != "" ? $"

                      {input}

                      " : ""; } - private string setStyle(string input, string style) + private static string SetStyle(string input, string style) { return input.Replace("style=\"\"", $"style=\"{style}\""); } - private void ThrowErrorUnknowChangeAction(char action) + private static void ThrowErrorUnknowChangeAction(char action) { Log.WriteError("Unknown Change Action", $"found an unexpected change action [{action}]"); } diff --git a/roles/lib/files/FWO.Report/Display/RuleChangeDisplayJson.cs b/roles/lib/files/FWO.Report/Display/RuleChangeDisplayJson.cs index 6ff73cc6e8..584bdf7907 100644 --- a/roles/lib/files/FWO.Report/Display/RuleChangeDisplayJson.cs +++ b/roles/lib/files/FWO.Report/Display/RuleChangeDisplayJson.cs @@ -1,6 +1,9 @@ -using FWO.Api.Data; +using FWO.Basics; using FWO.Config.Api; +using FWO.Data; +using FWO.Report; using FWO.Report.Filter; +using System.Text; namespace FWO.Ui.Display { @@ -13,6 +16,18 @@ public string DisplayChangeTime(RuleChange ruleChange) { return DisplayJsonString("change time", ruleChange.ChangeImport.Time.ToString()); } + public string DisplayChangeTime(ObjectChange objectChange) + { + return DisplayJsonString("change time", objectChange.ChangeImport.Time.ToString()); + } + public string DisplayChangeTime(ServiceChange serviceChange) + { + return DisplayJsonString("change time", serviceChange.ChangeImport.Time.ToString()); + } + public string DisplayChangeTime(UserChange userChange) + { + return DisplayJsonString("change time", userChange.ChangeImport.Time.ToString()); + } public string DisplayChangeAction(RuleChange ruleChange) { @@ -24,6 +39,36 @@ public string DisplayChangeAction(RuleChange ruleChange) default: return ""; } } + public string DisplayChangeAction(ObjectChange objectChange) + { + switch (objectChange.ChangeAction) + { + case 'I': return DisplayJsonString("change action", userConfig.GetText("network_object_added")); + case 'D': return DisplayJsonString("change action", userConfig.GetText("network_object_deleted")); + case 'C': return DisplayJsonString("change action", userConfig.GetText("network_object_modified")); + default: return ""; + } + } + public string DisplayChangeAction(ServiceChange serviceChange) + { + switch (serviceChange.ChangeAction) + { + case 'I': return DisplayJsonString("change action", userConfig.GetText("service_added")); + case 'D': return DisplayJsonString("change action", userConfig.GetText("service_deleted")); + case 'C': return DisplayJsonString("change action", userConfig.GetText("service_modified")); + default: return ""; + } + } + public string DisplayChangeAction(UserChange userChange) + { + switch (userChange.ChangeAction) + { + case 'I': return DisplayJsonString("change action", userConfig.GetText("user_added")); + case 'D': return DisplayJsonString("change action", userConfig.GetText("user_deleted")); + case 'C': return DisplayJsonString("change action", userConfig.GetText("user_modified")); + default: return ""; + } + } public string DisplayName(RuleChange ruleChange) { @@ -35,14 +80,44 @@ public string DisplayName(RuleChange ruleChange) default: return ""; } } + public string DisplayName(ObjectChange objectChange) + { + switch (objectChange.ChangeAction) + { + case 'D': return DisplayName(objectChange.OldObject.Name); + case 'I': return DisplayName(objectChange.NewObject.Name); + case 'C': return DisplayName(DisplayDiff(objectChange.OldObject.Name, objectChange.NewObject.Name)); + default: return ""; + } + } + public string DisplayName(ServiceChange serviceChange) + { + switch (serviceChange.ChangeAction) + { + case 'D': return DisplayName(serviceChange.OldService.Name); + case 'I': return DisplayName(serviceChange.NewService.Name); + case 'C': return DisplayName(DisplayDiff(serviceChange.OldService.Name, serviceChange.NewService.Name)); + default: return ""; + } + } + public string DisplayName(UserChange userChange) + { + switch (userChange.ChangeAction) + { + case 'D': return DisplayName(userChange.OldUser.Name); + case 'I': return DisplayName(userChange.NewUser.Name); + case 'C': return DisplayName(DisplayDiff(userChange.OldUser.Name, userChange.NewUser.Name)); + default: return ""; + } + } - public string DisplaySourceZone(RuleChange ruleChange) + public string DisplaySourceZones(RuleChange ruleChange) { switch (ruleChange.ChangeAction) { - case 'D': return DisplaySourceZone(ruleChange.OldRule.SourceZone?.Name); - case 'I': return DisplaySourceZone(ruleChange.NewRule.SourceZone?.Name); - case 'C': return DisplaySourceZone(DisplayDiff(ruleChange.OldRule.SourceZone?.Name, ruleChange.NewRule.SourceZone?.Name)); + case 'D': return DisplayRuleSourceZones(ruleChange.OldRule.RuleFromZones.Select(z => z.Content).ToArray()); + case 'I': return DisplayRuleSourceZones(ruleChange.NewRule.RuleFromZones.Select(z => z.Content).ToArray()); + case 'C': return DisplayJsonArray("source zones", DisplayArrayDiff(ListNetworkZones(ruleChange.OldRule.RuleFromZones.Select(z => z.Content).ToArray()), ListNetworkZones(ruleChange.NewRule.RuleFromZones.Select(z => z.Content).ToArray()))); default: return ""; } } @@ -53,7 +128,8 @@ public string DisplaySourceNegated(RuleChange ruleChange) { case 'D': return DisplaySourceNegated(ruleChange.OldRule.SourceNegated); case 'I': return DisplaySourceNegated(ruleChange.NewRule.SourceNegated); - case 'C': return ruleChange.OldRule.SourceNegated == ruleChange.NewRule.SourceNegated ? + case 'C': + return ruleChange.OldRule.SourceNegated == ruleChange.NewRule.SourceNegated ? DisplaySourceNegated(ruleChange.NewRule.SourceNegated) : DisplayJsonString("source negated", DisplayDiff(ruleChange.OldRule.SourceNegated.ToString().ToLower(), ruleChange.NewRule.SourceNegated.ToString().ToLower())); default: return ""; @@ -66,19 +142,20 @@ public string DisplaySource(RuleChange ruleChange, ReportType reportType) { case 'D': return DisplaySource(ruleChange.OldRule, reportType); case 'I': return DisplaySource(ruleChange.NewRule, reportType); - case 'C': return DisplayJsonArray("source", DisplayArrayDiff(ListNetworkLocations(ruleChange.OldRule, reportType, true), + case 'C': + return DisplayJsonArray("source", DisplayArrayDiff(ListNetworkLocations(ruleChange.OldRule, reportType, true), ListNetworkLocations(ruleChange.NewRule, reportType, true))); default: return ""; } } - public string DisplayDestinationZone(RuleChange ruleChange) + public string DisplayDestinationZones(RuleChange ruleChange) { switch (ruleChange.ChangeAction) { - case 'D': return DisplayDestinationZone(ruleChange.OldRule.DestinationZone?.Name); - case 'I': return DisplayDestinationZone(ruleChange.NewRule.DestinationZone?.Name); - case 'C': return DisplayDestinationZone(DisplayDiff(ruleChange.OldRule.DestinationZone?.Name, ruleChange.NewRule.DestinationZone?.Name)); + case 'D': return DisplayRuleDestinationZones(ruleChange.OldRule.RuleToZones.Select(z => z.Content).ToArray()); + case 'I': return DisplayRuleDestinationZones(ruleChange.NewRule.RuleToZones.Select(z => z.Content).ToArray()); + case 'C': return DisplayJsonArray("destination zones", DisplayArrayDiff(ListNetworkZones(ruleChange.OldRule.RuleToZones.Select(z => z.Content).ToArray()), ListNetworkZones(ruleChange.NewRule.RuleToZones.Select(z => z.Content).ToArray()))); default: return ""; } } @@ -89,7 +166,8 @@ public string DisplayDestinationNegated(RuleChange ruleChange) { case 'D': return DisplayDestinationNegated(ruleChange.OldRule.DestinationNegated); case 'I': return DisplayDestinationNegated(ruleChange.NewRule.DestinationNegated); - case 'C': return ruleChange.OldRule.DestinationNegated == ruleChange.NewRule.DestinationNegated ? + case 'C': + return ruleChange.OldRule.DestinationNegated == ruleChange.NewRule.DestinationNegated ? DisplayDestinationNegated(ruleChange.NewRule.DestinationNegated) : DisplayJsonString("destination negated", DisplayDiff(ruleChange.OldRule.DestinationNegated.ToString().ToLower(), ruleChange.NewRule.DestinationNegated.ToString().ToLower())); default: return ""; @@ -102,7 +180,8 @@ public string DisplayDestination(RuleChange ruleChange, ReportType reportType) { case 'D': return DisplayDestination(ruleChange.OldRule, reportType); case 'I': return DisplayDestination(ruleChange.NewRule, reportType); - case 'C': return DisplayJsonArray("destination", DisplayArrayDiff(ListNetworkLocations(ruleChange.OldRule, reportType, false), + case 'C': + return DisplayJsonArray("destination", DisplayArrayDiff(ListNetworkLocations(ruleChange.OldRule, reportType, false), ListNetworkLocations(ruleChange.NewRule, reportType, false))); default: return ""; } @@ -114,7 +193,8 @@ public string DisplayServiceNegated(RuleChange ruleChange) { case 'D': return DisplayServiceNegated(ruleChange.OldRule.ServiceNegated); case 'I': return DisplayServiceNegated(ruleChange.NewRule.ServiceNegated); - case 'C': return ruleChange.OldRule.ServiceNegated == ruleChange.NewRule.ServiceNegated ? + case 'C': + return ruleChange.OldRule.ServiceNegated == ruleChange.NewRule.ServiceNegated ? DisplayServiceNegated(ruleChange.NewRule.ServiceNegated) : DisplayJsonString("service negated", DisplayDiff(ruleChange.OldRule.ServiceNegated.ToString().ToLower(), ruleChange.NewRule.ServiceNegated.ToString().ToLower())); default: return ""; @@ -127,7 +207,8 @@ public string DisplayServices(RuleChange ruleChange, ReportType reportType) { case 'D': return DisplayServices(ruleChange.OldRule, reportType); case 'I': return DisplayServices(ruleChange.NewRule, reportType); - case 'C': return DisplayJsonArray("service", DisplayArrayDiff(ListServices(ruleChange.OldRule, reportType), + case 'C': + return DisplayJsonArray("service", DisplayArrayDiff(ListServices(ruleChange.OldRule, reportType), ListServices(ruleChange.NewRule, reportType))); default: return ""; } @@ -161,13 +242,27 @@ public string DisplayEnabled(RuleChange ruleChange) { case 'D': return DisplayEnabled(ruleChange.OldRule.Disabled); case 'I': return DisplayEnabled(ruleChange.NewRule.Disabled); - case 'C': return ruleChange.OldRule.Disabled == ruleChange.NewRule.Disabled ? + case 'C': + return ruleChange.OldRule.Disabled == ruleChange.NewRule.Disabled ? DisplayEnabled(ruleChange.NewRule.Disabled) : DisplayJsonString("disabled", DisplayDiff(ruleChange.OldRule.Disabled.ToString().ToLower(), ruleChange.NewRule.Disabled.ToString().ToLower())); default: return ""; } } + public string DisplayEnforcingGateways(RuleChange ruleChange) + { + switch (ruleChange.ChangeAction) + { + case 'D': return DisplayEnforcingGateways(ruleChange.OldRule.EnforcingGateways); + case 'I': return DisplayEnforcingGateways(ruleChange.NewRule.EnforcingGateways); + case 'C': + return DisplayJsonArray("EnforcingGateways", DisplayArrayDiff(ListEnforcingGateways(ruleChange.OldRule.EnforcingGateways), + ListEnforcingGateways(ruleChange.NewRule.EnforcingGateways))); + default: return ""; + } + } + public string DisplayUid(RuleChange ruleChange) { switch (ruleChange.ChangeAction) @@ -178,6 +273,26 @@ public string DisplayUid(RuleChange ruleChange) default: return ""; } } + public string DisplayUid(ObjectChange objectChange) + { + switch (objectChange.ChangeAction) + { + case 'D': return DisplayUid(objectChange.OldObject.Uid); + case 'I': return DisplayUid(objectChange.NewObject.Uid); + case 'C': return DisplayUid(DisplayDiff(objectChange.OldObject.Uid, objectChange.NewObject.Uid)); + default: return ""; + } + } + public string DisplayUid(ServiceChange serviceChange) + { + switch (serviceChange.ChangeAction) + { + case 'D': return DisplayUid(serviceChange.OldService.Uid); + case 'I': return DisplayUid(serviceChange.NewService.Uid); + case 'C': return DisplayUid(DisplayDiff(serviceChange.OldService.Uid, serviceChange.NewService.Uid)); + default: return ""; + } + } public string DisplayComment(RuleChange ruleChange) { @@ -189,6 +304,110 @@ public string DisplayComment(RuleChange ruleChange) default: return ""; } } + public string DisplayComment(ObjectChange objectChange) + { + switch (objectChange.ChangeAction) + { + case 'D': return DisplayComment(objectChange.OldObject.Comment); + case 'I': return DisplayComment(objectChange.NewObject.Comment); + case 'C': return DisplayComment(DisplayDiff(objectChange.OldObject.Comment, objectChange.NewObject.Comment)); + default: return ""; + } + } + public string DisplayComment(ServiceChange serviceChange) + { + switch (serviceChange.ChangeAction) + { + case 'D': return DisplayComment(serviceChange.OldService.Comment); + case 'I': return DisplayComment(serviceChange.NewService.Comment); + case 'C': return DisplayComment(DisplayDiff(serviceChange.OldService.Comment, serviceChange.NewService.Comment)); + default: return ""; + } + } + public string DisplayComment(UserChange userChange) + { + switch (userChange.ChangeAction) + { + case 'D': return DisplayComment(userChange.OldUser.Comment); + case 'I': return DisplayComment(userChange.NewUser.Comment); + case 'C': return DisplayComment(DisplayDiff(userChange.OldUser.Comment, userChange.NewUser.Comment)); + default: return ""; + } + } + + public string DisplayObjectType(ObjectChange objectChange) + { + switch (objectChange.ChangeAction) + { + case 'D': return DisplayObjectType(objectChange.OldObject.Type.Name); + case 'I': return DisplayObjectType(objectChange.NewObject.Type.Name); + case 'C': return DisplayObjectType(DisplayDiff(objectChange.OldObject.Type.Name, objectChange.NewObject.Type.Name)); + default: return ""; + } + } + public string DisplayObjectType(ServiceChange serviceChange) + { + switch (serviceChange.ChangeAction) + { + case 'D': return DisplayObjectType(serviceChange.OldService.Type.Name); + case 'I': return DisplayObjectType(serviceChange.NewService.Type.Name); + case 'C': return DisplayObjectType(DisplayDiff(serviceChange.OldService.Type.Name, serviceChange.NewService.Type.Name)); + default: return ""; + } + } + + public string DisplayObjectIP(ObjectChange objectChange) + { + switch (objectChange.ChangeAction) + { + case 'D': return DisplayObjectIP(NwObjDisplay.DisplayIp(objectChange.OldObject.IP, objectChange.OldObject.IpEnd, true)); + case 'I': return DisplayObjectIP(NwObjDisplay.DisplayIp(objectChange.NewObject.IP, objectChange.NewObject.IpEnd, true)); + case 'C': return DisplayObjectIP(DisplayDiff(NwObjDisplay.DisplayIp(objectChange.OldObject.IP, objectChange.OldObject.IpEnd, true), NwObjDisplay.DisplayIp(objectChange.NewObject.IP, objectChange.NewObject.IpEnd, true))); + default: return ""; + } + } + + public string DisplayServiceProtocol(ServiceChange serviceChange) + { + switch (serviceChange.ChangeAction) + { + case 'D': return DisplayServiceProtocol(serviceChange.OldService.Protocol?.Name ?? ""); + case 'I': return DisplayServiceProtocol(serviceChange.NewService.Protocol?.Name ?? ""); + case 'C': return DisplayServiceProtocol(DisplayDiff(serviceChange.OldService.Protocol?.Name ?? "", serviceChange.NewService.Protocol?.Name ?? "")); + default: return ""; + } + } + public string DisplayServicePort(ServiceChange serviceChange) + { + switch (serviceChange.ChangeAction) + { + case 'D': return DisplayServicePort(DisplayBase.DisplayPort(serviceChange.OldService.DestinationPort, serviceChange.OldService.DestinationPortEnd, true)); + case 'I': return DisplayServicePort(DisplayBase.DisplayPort(serviceChange.NewService.DestinationPort, serviceChange.NewService.DestinationPortEnd, true)); + case 'C': return DisplayServicePort(DisplayDiff(DisplayBase.DisplayPort(serviceChange.OldService.DestinationPort, serviceChange.OldService.DestinationPortEnd, true), DisplayBase.DisplayPort(serviceChange.NewService.DestinationPort, serviceChange.NewService.DestinationPortEnd, true))); + default: return ""; + } + } + + public string DisplayObjectMemberNames(ObjectChange objectChange) + { + switch (objectChange.ChangeAction) + { + case 'D': return DisplayobjectMemberNames(DisplayBase.MemberNamesAsJson(objectChange.OldObject.MemberNames)); + case 'I': return DisplayobjectMemberNames(DisplayBase.MemberNamesAsJson(objectChange.NewObject.MemberNames)); + case 'C': return DisplayobjectMemberNames(DisplayDiff(DisplayBase.MemberNamesAsJson(objectChange.OldObject.MemberNames), DisplayBase.MemberNamesAsJson(objectChange.NewObject.MemberNames))); + default: return ""; + } + } + public string DisplayObjectMemberNames(ServiceChange serviceChange) + { + switch (serviceChange.ChangeAction) + { + case 'D': return DisplayobjectMemberNames(DisplayBase.MemberNamesAsJson(serviceChange.OldService.MemberNames)); + case 'I': return DisplayobjectMemberNames(DisplayBase.MemberNamesAsJson(serviceChange.NewService.MemberNames)); + case 'C': return DisplayobjectMemberNames(DisplayDiff(DisplayBase.MemberNamesAsJson(serviceChange.OldService.MemberNames), DisplayBase.MemberNamesAsJson(serviceChange.NewService.MemberNames))); + default: return ""; + } + } private string? DisplayDiff(string? oldElement, string? newElement) { @@ -199,7 +418,7 @@ public string DisplayComment(RuleChange ruleChange) else { return (oldElement != null && oldElement.Length > 0 ? $"{userConfig.GetText("deleted")}: {oldElement}{(newElement != null && newElement.Length > 0 ? ", " : "")}" : "") - + (newElement != null && newElement.Length > 0 ?$"{userConfig.GetText("added")}: {newElement}" : ""); + + (newElement != null && newElement.Length > 0 ? $"{userConfig.GetText("added")}: {newElement}" : ""); } } @@ -219,7 +438,7 @@ private string DisplayArrayDiff(string oldElement, string newElement) newElement = newElement.Replace("\"", ""); AnalyzeElements(oldElement, newElement, ref unchanged, ref deleted, ref added); - return string.Join(",", Array.ConvertAll(unchanged.ToArray(), elem => Quote(elem))) + (unchanged.Count > 0 && (deleted.Count > 0 || added.Count > 0 ) ? "," : "") + return string.Join(",", Array.ConvertAll(unchanged.ToArray(), elem => Quote(elem))) + (unchanged.Count > 0 && (deleted.Count > 0 || added.Count > 0) ? "," : "") + (deleted.Count > 0 ? string.Join(",", Array.ConvertAll(deleted.ToArray(), elem => Quote($"{userConfig.GetText("deleted")}: {elem}"))) : "") + (deleted.Count > 0 && added.Count > 0 ? "," : "") + (added.Count > 0 ? string.Join(",", Array.ConvertAll(added.ToArray(), elem => Quote($"{userConfig.GetText("added")}: {elem}"))) : ""); } diff --git a/roles/lib/files/FWO.Report/Display/RuleDifferenceDisplayHtml.cs b/roles/lib/files/FWO.Report/Display/RuleDifferenceDisplayHtml.cs new file mode 100644 index 0000000000..223595fa2d --- /dev/null +++ b/roles/lib/files/FWO.Report/Display/RuleDifferenceDisplayHtml.cs @@ -0,0 +1,49 @@ +using FWO.Data; +using FWO.Logging; +using FWO.Config.Api; +using FWO.Report; +using FWO.Basics; + +namespace FWO.Ui.Display +{ + public class RuleDifferenceDisplayHtml : RuleDisplayBase + { + public RuleDifferenceDisplayHtml(UserConfig userConfig) : base(userConfig) + { } + + public string DisplaySourceDiff(Rule rule, OutputLocation location, ReportType reportType) + { + return DisplayDiff( + rule.Froms.Where(f => f.Object.IsSurplus).ToList().ConvertAll(nwLoc => DisplayNetworkLocation(nwLoc, reportType).ToString()), + rule.DisregardedFroms.ToList().ConvertAll(nwLoc => DisplayNetworkLocation(nwLoc, reportType).ToString()), + rule.Froms.Where(f => !f.Object.IsSurplus).ToList().ConvertAll(nwLoc => DisplayNetworkLocation(nwLoc, reportType).ToString()) + ); + } + + public string DisplayDestinationDiff(Rule rule, OutputLocation location, ReportType reportType) + { + return DisplayDiff( + rule.Tos.Where(f => f.Object.IsSurplus).ToList().ConvertAll(nwLoc => DisplayNetworkLocation(nwLoc, reportType).ToString()), + rule.DisregardedTos.ToList().ConvertAll(nwLoc => DisplayNetworkLocation(nwLoc, reportType).ToString()), + rule.Tos.Where(f => !f.Object.IsSurplus).ToList().ConvertAll(nwLoc => DisplayNetworkLocation(nwLoc, reportType).ToString()) + ); + } + + public string DisplayServiceDiff(Rule rule, OutputLocation location, ReportType reportType) + { + return DisplayDiff( + rule.Services.Where(f => f.Content.IsSurplus).ToList().ConvertAll(svc => DisplayService(svc.Content, reportType).ToString()), + rule.DisregardedServices.ToList().ConvertAll(svc => DisplayService(svc, reportType).ToString()), + rule.Services.Where(f => !f.Content.IsSurplus).ToList().ConvertAll(svc => DisplayService(svc.Content, reportType).ToString()) + ); + } + + + private string DisplayDiff(List addedElems, List deletedElems, List unchangedElems) + { + return (unchangedElems.Count > 0 ? $"

                      {string.Join("
                      ", unchangedElems)}

                      " : "") + + (deletedElems.Count > 0 ? $"{userConfig.GetText("missing")}:

                      {string.Join("
                      ", deletedElems)}

                      " : "") + + (addedElems.Count > 0 ? $"{userConfig.GetText("surplus")}:

                      {string.Join("
                      ", addedElems)}

                      " : ""); + } + } +} diff --git a/roles/lib/files/FWO.Report/Display/RuleDisplayBase.cs b/roles/lib/files/FWO.Report/Display/RuleDisplayBase.cs index 0e0dad4b57..f6b6a0e941 100644 --- a/roles/lib/files/FWO.Report/Display/RuleDisplayBase.cs +++ b/roles/lib/files/FWO.Report/Display/RuleDisplayBase.cs @@ -1,69 +1,191 @@ -using FWO.Api.Data; -using FWO.Config.Api; using System.Text; +using FWO.Basics; +using FWO.Data; +using FWO.Config.Api; +using FWO.Report; using FWO.Report.Filter; namespace FWO.Ui.Display { - public class RuleDisplayBase + public class RuleDisplayBase(UserConfig userConfig) { - protected UserConfig userConfig; + protected UserConfig userConfig = userConfig; - public RuleDisplayBase(UserConfig userConfig) + public static string DisplayNumber(Rule rule) { - this.userConfig = userConfig; + return rule.DisplayOrderNumberString; } - public string DisplayNumber(Rule rule) + public static string DisplayEnabled(Rule rule, OutputLocation location) { - return rule.DisplayOrderNumber.ToString(); + if (location == OutputLocation.export) + { + return $"{(rule.Disabled ? "N" : "Y")}"; + } + else + { + return $"
                      "; + } } - public string DisplayName(Rule rule) + public static string DisplayLastModified(Rule rule) { - return (rule.Name != null ? rule.Name : ""); + DateTime? lastModified = rule.LastModified ?? rule.Metadata?.Created; + return lastModified.HasValue + ? DateOnly.FromDateTime(lastModified.Value).ToString("yyyy-MM-dd") + : ""; } - public string DisplaySourceZone(Rule rule) + public static string DisplayIsCompliant(Rule rule, OutputLocation location) { - return (rule.SourceZone != null ? rule.SourceZone.Name : ""); + if (rule.Compliance != ComplianceViolationType.NotAssessable) + { + bool isCompliant = true; + + if (rule.Compliance != ComplianceViolationType.None) + { + isCompliant = false; + } + + if (location == OutputLocation.export) + { + return $"{(isCompliant ? "Y" : "N")}"; + } + else + { + return $"
                      "; + } + } + else + { + return "Not Evaluable"; + } } - public string DisplayDestinationZone(Rule rule) + public static string DisplayViolationDetails(Rule rule) { - return (rule.DestinationZone != null ? rule.DestinationZone.Name : ""); + string violationDetails = "

                      "; + bool notFirst = false; + + foreach (ComplianceViolation violation in rule.Violations) + { + if (notFirst) + { + violationDetails += "
                      "; + } + + violationDetails += violation.Details; + notFirst = true; + } + + violationDetails += "

                      "; + + return violationDetails; + } + + public static string DisplayName(Rule rule) + { + return rule.Name ?? ""; + } + + public static string DisplayName(NetworkObject nto) + { + return nto.Name ?? ""; + } + + public static string DisplayName(NetworkService nts) + { + return nts.Name ?? ""; } - public string DisplayIpRange(string? Ip, string? IpEnd) + public static string DisplayName(NetworkUser ntu) { - return (Ip != null && Ip != "" ? $"{Ip}{(IpEnd != null && IpEnd != "" && IpEnd != Ip ? $"-{IpEnd}" : "")}" : ""); + return ntu.Name ?? ""; } - public string DisplayAction(Rule rule) + public static string DisplaySourceZones(Rule rule) + { + if (rule.RuleFromZones.Length != 0) + { + string ruleZones = ""; + bool notFirst = false; + + foreach (ZoneWrapper zoneWrapper in rule.RuleFromZones) + { + if (notFirst) + { + ruleZones += "
                      "; + } + + ruleZones += zoneWrapper.Content.Name; + notFirst = true; + } + return ruleZones; + } + else + { + return ""; + } + } + + public static string DisplayDestinationZones(Rule rule) + { + if (rule.RuleToZones.Length != 0) + { + string ruleZones = ""; + bool notFirst = false; + + foreach (ZoneWrapper zoneWrapper in rule.RuleToZones) + { + if (notFirst) + { + ruleZones += "
                      "; + } + + ruleZones += zoneWrapper.Content.Name; + notFirst = true; + } + return ruleZones; + } + else + { + return ""; + } + } + + public static string DisplayAction(Rule rule) { return rule.Action; } - public string DisplayTrack(Rule rule) + public static string DisplayTrack(Rule rule) { return rule.Track; } - public string DisplayUid(Rule rule) + public static string DisplayUid(Rule rule) + { + return rule.Uid ?? ""; + } + public static string DisplayUid(NetworkObject nwo) + { + return nwo.Uid ?? ""; + } + public static string DisplayUid(NetworkService nws) { - return (rule.Uid != null ? rule.Uid : ""); + return nws.Uid ?? ""; } - public string DisplayComment(Rule rule) + public static string DisplayComment(Rule rule) { - return (rule.Comment != null ? rule.Comment : ""); + return rule.Comment ?? ""; } - public StringBuilder DisplayNetworkLocation(NetworkLocation userNetworkObject, ReportType reportType, string? userName = null, string? objName = null) + public static StringBuilder DisplayNetworkLocation(NetworkLocation userNetworkObject, ReportType reportType, string? userName = null, string? objName = null) { - StringBuilder result = new StringBuilder(); + StringBuilder result = new(); - if (userNetworkObject.User != null && userNetworkObject.User.Id > 0) + if (userNetworkObject.User != null && userNetworkObject.User.Id > 0) { result.Append($"{userName ?? userNetworkObject.User.Name}@"); } @@ -71,99 +193,96 @@ public StringBuilder DisplayNetworkLocation(NetworkLocation userNetworkObject, R if (!reportType.IsTechReport()) { result.Append($"{objName ?? userNetworkObject.Object.Name}"); - if(userNetworkObject.Object.Type.Name != "group") - { - result.Append(" ("); - } } - result.Append(DisplayIpRange(userNetworkObject.Object.IP, userNetworkObject.Object.IpEnd)); - if (!reportType.IsTechReport() && userNetworkObject.Object.Type.Name != "group") + if (userNetworkObject.Object.Type.Name != ObjectType.Group) { - result.Append(")"); + bool showIpinBrackets = !reportType.IsTechReport(); + result.Append(NwObjDisplay.DisplayIp( + userNetworkObject.Object.IP, + userNetworkObject.Object.IpEnd, + userNetworkObject.Object.Type.Name, + showIpinBrackets)); } - return result; + return reportType == ReportType.VarianceAnalysis ? DisplayWithIcon(result, ObjCategory.nobj, userNetworkObject.Object.Type.Name) : result; } - public StringBuilder DisplayService(NetworkService service, ReportType reportType, string? serviceName = null) + public static StringBuilder DisplayService(NetworkService service, ReportType reportType, string? serviceName = null) { - StringBuilder result = new StringBuilder(); - if (reportType.IsTechReport()) - { - if (service.DestinationPort == null) - { - result.Append($"{service.Name}"); - } - else - { - result.Append(service.DestinationPort == service.DestinationPortEnd ? $"{service.DestinationPort}/{service.Protocol?.Name}" - : $"{service.DestinationPort}-{service.DestinationPortEnd}/{service.Protocol?.Name}"); - } - } - else - { - result.Append($"{serviceName ?? service.Name}"); - if (service.DestinationPort != null) - { - result.Append(service.DestinationPort == service.DestinationPortEnd ? $" ({service.DestinationPort}/{service.Protocol?.Name})" - : $" ({service.DestinationPort}-{service.DestinationPortEnd}/{service.Protocol?.Name})"); - } - } - return result; + StringBuilder result = DisplayBase.DisplayService(service, reportType.IsTechReport(), serviceName); + return reportType == ReportType.VarianceAnalysis ? DisplayWithIcon(result, ObjCategory.nsrv, service.Type.Name) : result; + } + + public static StringBuilder DisplayGateway(Device gateway, ReportType reportType, string? gatewayName = null) + { + return DisplayBase.DisplayGateway(gateway, reportType.IsTechReport(), gatewayName); } - public StringBuilder RemoveLastChars(StringBuilder s, int count) + public static StringBuilder RemoveLastChars(StringBuilder s, int count) { - string x = s.ToString(); + string x = s.ToString(); x = x.Remove(x.ToString().Length - count, count).ToString(); return s.Remove(s.ToString().Length - count, count); } - public string Quote(string? input) + public static string Quote(string? input) { - return $"\"{input ?? ""}\""; + return $"\"{input ?? ""}\""; } - public List getNetworkLocations(NetworkLocation[] locationArray) + public static List GetResolvedNetworkLocations(NetworkLocation[] locationArray) { - HashSet collectedUserNetworkObjects = new HashSet(); + HashSet collectedUserNetworkObjects = []; foreach (NetworkLocation networkObject in locationArray) { - foreach (GroupFlat nwObject in networkObject.Object.ObjectGroupFlats) + if (networkObject.Object.Type.Name == ObjectType.Group) { - if (nwObject.Object != null && nwObject.Object.Type.Name != "group") // leave out group level altogether + foreach (GroupFlat nwObject in networkObject.Object.ObjectGroupFlats) { - collectedUserNetworkObjects.Add(new NetworkLocation(networkObject.User, nwObject.Object)); + if (nwObject.Object != null && nwObject.Object.Type.Name != ObjectType.Group || networkObject.Object.ObjectGroupFlats.Count() == 1) // leave out group level altogether, except for empty groups + { + collectedUserNetworkObjects.Add(new NetworkLocation(networkObject.User, nwObject.Object)); + } } } + else + { + collectedUserNetworkObjects.Add(networkObject); + } } - List userNwObjectList = collectedUserNetworkObjects.ToList(); + List userNwObjectList = [.. collectedUserNetworkObjects]; userNwObjectList.Sort(); return userNwObjectList; } - public List GetNetworkServices(ServiceWrapper[] serviceArray) + public static List GetNetworkServices(ServiceWrapper[] serviceArray) { - HashSet collectedServices = new HashSet(); + HashSet collectedServices = []; foreach (ServiceWrapper service in serviceArray) { foreach (GroupFlat nwService in service.Content.ServiceGroupFlats) { - if (nwService.Object != null && nwService.Object.Type.Name != "group") + if (nwService.Object != null && nwService.Object.Type.Name != ObjectType.Group) { collectedServices.Add(nwService.Object); } } + + if (!service.Content.ServiceGroupFlats.Any()) + { + collectedServices.Add(service.Content); + } + } - List serviceList = collectedServices.ToList(); + List serviceList = [.. collectedServices]; serviceList.Sort(delegate (NetworkService x, NetworkService y) { return x.Name.CompareTo(y.Name); }); return serviceList; } - protected void AnalyzeElements(string oldElement, string newElement, ref List unchanged, ref List deleted, ref List added) + protected static void AnalyzeElements(string oldElement, string newElement, ref List unchanged, ref List deleted, ref List added) { - string[] separatingStrings = { "," }; - string[] oldAr = oldElement.Split(separatingStrings, System.StringSplitOptions.RemoveEmptyEntries); - string[] newAr = newElement.Split(separatingStrings, System.StringSplitOptions.RemoveEmptyEntries); + string[] separatingStrings = [","]; + string[] oldAr = oldElement.Split(separatingStrings, StringSplitOptions.RemoveEmptyEntries); + string[] newAr = newElement.Split(separatingStrings, StringSplitOptions.RemoveEmptyEntries); foreach (var item in oldAr) { @@ -181,10 +300,16 @@ protected void AnalyzeElements(string oldElement, string newElement, ref List{outputString}"); + } } } diff --git a/roles/lib/files/FWO.Report/Display/RuleDisplayCsv.cs b/roles/lib/files/FWO.Report/Display/RuleDisplayCsv.cs index 35152aceda..c7db0f6081 100644 --- a/roles/lib/files/FWO.Report/Display/RuleDisplayCsv.cs +++ b/roles/lib/files/FWO.Report/Display/RuleDisplayCsv.cs @@ -1,7 +1,9 @@ -using FWO.Api.Data; +using FWO.Basics; using FWO.Config.Api; -using System.Text; +using FWO.Data; +using FWO.Report; using FWO.Report.Filter; +using System.Text; using System.Text.RegularExpressions; namespace FWO.Ui.Display @@ -13,7 +15,7 @@ public RuleDisplayCsv(UserConfig userConfig) : base(userConfig) public string OutputCsv(string? input) { - return $"\"{input ?? ""}\","; + return $"\"{input ?? ""}\","; } public string DisplayNumberCsv(Rule rule) @@ -28,7 +30,7 @@ public string DisplayNameCsv(Rule rule) public string DisplaySourceZoneCsv(Rule rule) { - return OutputCsv(DisplaySourceZone(rule)); + return OutputCsv(ListNetworkZones(rule.RuleFromZones.Select(z => z.Content).ToArray())); } public string DisplaySourceCsv(Rule rule, ReportType reportType) @@ -38,7 +40,7 @@ public string DisplaySourceCsv(Rule rule, ReportType reportType) public string DisplayDestinationZoneCsv(Rule rule) { - return OutputCsv(DisplayDestinationZone(rule)); + return OutputCsv(ListNetworkZones(rule.RuleToZones.Select(z => z.Content).ToArray())); } public string DisplayDestinationCsv(Rule rule, ReportType reportType) @@ -75,21 +77,39 @@ public string DisplayCommentCsv(Rule rule) { return OutputCsv(DisplayComment(rule)); } - + + public string DisplayLastModifiedCsv(Rule rule) + { + return OutputCsv(DisplayLastModified(rule)); + } + public new string DisplayName(Rule rule) { - return (rule.Name != null ? SanitizeComment(rule.Name) : ""); + return rule.Name != null ? SanitizeComment(rule.Name) : ""; } public new string DisplayComment(Rule rule) { - return (rule.Comment != null ? SanitizeComment(rule.Comment) : ""); + return rule.Comment != null ? SanitizeComment(rule.Comment) : ""; + } + + public string DisplayComment(NetworkObject nwo) + { + return nwo.Comment != null ? SanitizeComment(nwo.Comment) : ""; + } + public string DisplayComment(NetworkService nws) + { + return nws.Comment != null ? SanitizeComment(nws.Comment) : ""; } - + public string DisplayComment(NetworkUser nwu) + { + return nwu.Comment != null ? SanitizeComment(nwu.Comment) : ""; + } + public string DisplayEnabled(Rule rule) { - return (rule.Disabled) ? "disabled" : "enabled"; + return rule.Disabled ? "disabled" : "enabled"; } public string DisplaySource(Rule rule, ReportType reportType) @@ -113,12 +133,12 @@ public string DisplayServices(Rule rule, ReportType reportType) displayedServices.Add(DisplayService(service, reportType).ToString()); } - if(rule.ServiceNegated) + if (rule.ServiceNegated) { result.Append($"{userConfig.GetText("negated")}("); } result.Append(string.Join(",", displayedServices)); - if(rule.ServiceNegated) + if (rule.ServiceNegated) { result.Append(")"); } @@ -133,14 +153,14 @@ private string SanitizeComment(string inputString) return output; } - private string DisplaySourceOrDestination(Rule rule, ReportType reportType , bool isSource) + private string DisplaySourceOrDestination(Rule rule, ReportType reportType, bool isSource) { StringBuilder result = new StringBuilder(""); if (reportType.IsResolvedReport()) { List displayedLocations = new List(); - foreach (NetworkLocation networkLocation in getNetworkLocations(isSource ? rule.Froms : rule.Tos)) + foreach (NetworkLocation networkLocation in GetResolvedNetworkLocations(isSource ? rule.Froms : rule.Tos)) { displayedLocations.Add(DisplayNetworkLocation(networkLocation, reportType).ToString()); } @@ -158,5 +178,23 @@ private string DisplaySourceOrDestination(Rule rule, ReportType reportType , boo return result.ToString(); } + + public static string DisplayEnforcingGateways(Rule rule) + { + return string.Join(",", + rule.EnforcingGateways? + .Select(g => g.Content?.Name ?? "") + ?? Enumerable.Empty()); + } + + protected string ListNetworkZones(NetworkZone[] networkZones) + { + List displayedZones = new List(); + foreach (NetworkZone networkZone in networkZones) + { + displayedZones.Add(Quote(networkZone.Name)); + } + return string.Join(",", displayedZones); + } } } diff --git a/roles/lib/files/FWO.Report/Display/RuleDisplayHtml.cs b/roles/lib/files/FWO.Report/Display/RuleDisplayHtml.cs index d3151622ee..d98d8c5e3c 100644 --- a/roles/lib/files/FWO.Report/Display/RuleDisplayHtml.cs +++ b/roles/lib/files/FWO.Report/Display/RuleDisplayHtml.cs @@ -1,171 +1,221 @@ -using FWO.Api.Data; +using FWO.Basics; +using FWO.Data; using FWO.Config.Api; using System.Text; using FWO.Report; -using FWO.Report.Filter; namespace FWO.Ui.Display { - public enum OutputLocation + public class RuleDisplayHtml(UserConfig userConfig) : RuleDisplayBase(userConfig) { - export, - report, - certification - } - - public class RuleDisplayHtml: RuleDisplayBase - { - public RuleDisplayHtml(UserConfig userConfig) : base(userConfig) - {} + public string DisplayRuleTime(Rule rule) + { + // Quick implementation to satisfy current requirements: use only the first time object with an EndTime. + DateTimeOffset? firstEndTime = rule.RuleTimes.FirstOrDefault(ruleTime => ruleTime.TimeObj?.EndTime != null)?.TimeObj?.EndTime; + return firstEndTime?.ToString("yyyy-MM-dd HH:mm:ss") ?? ""; + } - public string DisplaySource(Rule rule, OutputLocation location, ReportType reportType, string style = "") + public string DisplaySource(Rule rule, OutputLocation location, ReportType reportType, int chapterNumber = 0, string style = "", bool overwriteIsResolvedReport = false) { - return DisplaySourceOrDestination(rule, location, reportType, style, true); + return DisplaySourceOrDestination(rule, chapterNumber, location, reportType, style, true, overwriteIsResolvedReport); } - public string DisplayDestination(Rule rule, OutputLocation location, ReportType reportType, string style = "") + public string DisplayDestination(Rule rule, OutputLocation location, ReportType reportType, int chapterNumber = 0, string style = "", bool overwriteIsResolvedReport = false) { - return DisplaySourceOrDestination(rule, location, reportType, style, false); + return DisplaySourceOrDestination(rule, chapterNumber, location, reportType, style, false, overwriteIsResolvedReport); } - public string DisplayServices(Rule rule, OutputLocation location, ReportType reportType, string style = "") + public string DisplayServices(Rule rule, OutputLocation location, ReportType reportType, int chapterNumber = 0, string style = "", bool overwriteIsResolvedReport = false) { - StringBuilder result = new StringBuilder(); + StringBuilder result = new(); if (rule.ServiceNegated) { result.AppendLine(userConfig.GetText("negated") + "
                      "); } - if(reportType.IsResolvedReport()) + if (!overwriteIsResolvedReport && reportType.IsResolvedReport()) { NetworkService[] services = GetNetworkServices(rule.Services).ToArray(); - result.AppendJoin("
                      ", Array.ConvertAll(services, service => ServiceToHtml(service, rule.MgmtId, location, style, reportType))); + result.AppendJoin("
                      ", Array.ConvertAll(services, service => ServiceToHtml(service, rule.MgmtId, chapterNumber, location, style, reportType))); } else { - result.AppendJoin("
                      ", Array.ConvertAll(rule.Services, service => ServiceToHtml(service.Content, rule.MgmtId, location, style, reportType))); + result.AppendJoin("
                      ", Array.ConvertAll(rule.Services, service => ServiceToHtml(service.Content, rule.MgmtId, chapterNumber, location, style, reportType))); } + return result.ToString(); } - public string DisplayEnabled(Rule rule, OutputLocation location) + public static string DisplayEnforcingGateways(Rule rule, OutputLocation location, ReportType reportType, int chapterNumber = 0, string style = "") { - if (location == OutputLocation.export) - { - return $"{(rule.Disabled ? "N" : "Y")}"; - } - else - { - return $"
                      "; - } + StringBuilder result = new(); + result.AppendJoin("
                      ", Array.ConvertAll(rule.EnforcingGateways, gw => EnforcingGatewayToHtml(gw.Content, rule.MgmtId, chapterNumber, location, style, reportType))); + return result.ToString(); + } + public static string DisplaySectionHeader(Rule rule, int ColumnCount) + { + return $"{rule.SectionHeader}"; } - public string DisplayNextRecert(Rule rule) + public static string DisplayNextRecert(RuleMetadata ruleMetadata) { int count = 0; - return string.Join("", Array.ConvertAll(rule.Metadata.RuleRecertification.ToArray(), recert => getNextRecertDateString(countString(rule.Metadata.RuleRecertification.Count > 1, ++count), recert).ToString())); + return string.Join("", Array.ConvertAll(ruleMetadata.RuleRecertification.ToArray(), recert => GetNextRecertDateString(CountString(ruleMetadata.RuleRecertification.Count > 1, ++count), recert).ToString())); } - public string DisplayOwner(Rule rule) + public static string DisplayOwner(RuleMetadata ruleMetadata) { int count = 0; - return string.Join("", Array.ConvertAll(rule.Metadata.RuleRecertification.ToArray(), recert => getOwnerDisplayString(countString(rule.Metadata.RuleRecertification.Count > 1, ++count), recert).ToString())); + return string.Join("", Array.ConvertAll(ruleMetadata.RuleRecertification.ToArray(), recert => GetOwnerDisplayString(CountString(ruleMetadata.RuleRecertification.Count > 1, ++count), recert).ToString())); } - public string DisplayRecertIpMatches(Rule rule) + public static string DisplayRecertIpMatches(RuleMetadata ruleMetadata) { int count = 0; - return string.Join("", Array.ConvertAll(rule.Metadata.RuleRecertification.ToArray(), recert => getIpMatchDisplayString(countString(rule.Metadata.RuleRecertification.Count > 1, ++count), recert).ToString())); + return string.Join("", Array.ConvertAll(ruleMetadata.RuleRecertification.ToArray(), recert => GetIpMatchDisplayString(CountString(ruleMetadata.RuleRecertification.Count > 1, ++count), recert).ToString())); } - public string DisplayLastHit(Rule rule) + public static string DisplayLastHit(RuleMetadata ruleMetadata) { - if (rule.Metadata.LastHit == null) + if (ruleMetadata.LastHit == null) return ""; else - return DateOnly.FromDateTime((DateTime)rule.Metadata.LastHit).ToString("yyyy-MM-dd"); //rule.Metadata.LastHit.ToString("yyyy-MM-dd"); + return DateOnly.FromDateTime(ruleMetadata.LastHit.Value).ToString("yyyy-MM-dd"); } - public string DisplayLastRecertifier(Rule rule) + public static string DisplayLastRecertifier(RuleMetadata ruleMetadata) { int count = 0; - return string.Join("", Array.ConvertAll(rule.Metadata.RuleRecertification.ToArray(), recert => getLastRecertifierDisplayString(countString(rule.Metadata.RuleRecertification.Count > 1, ++count), recert).ToString())); + return string.Join("", Array.ConvertAll(ruleMetadata.RuleRecertification.ToArray(), + recert => GetLastRecertifierDisplayString(CountString(ruleMetadata.RuleRecertification.Count > 1, ++count), recert).ToString())); } - protected string constructLink(string type, string symbol, long id, string name, OutputLocation location, int mgmtId, string style) + protected static string NetworkLocationToHtml(NetworkLocation networkLocation, int mgmtId, int chapterNumber, OutputLocation location, string style, ReportType reportType) { - string link = location == OutputLocation.export ? $"#" : $"{location.ToString()}/generation#goto-report-m{mgmtId}-"; - return $" {name}"; + // Determine if links should be constructed + bool isResolved = reportType.IsResolvedReport() || reportType == ReportType.VarianceAnalysis; + + string? userOutput = null; + if (!isResolved && networkLocation.User != null) + { + string userLink = ReportDevicesBase.GetReportDevicesLinkAddress(location, mgmtId, ObjCatString.User, chapterNumber, networkLocation.User.Id, reportType); + userOutput = ReportBase.ConstructLink(ReportBase.GetIconClass(ObjCategory.user, networkLocation.User.Type.Name), networkLocation.User.Name, style, userLink); + } + + string? objectLink = null; + if (!isResolved) + { + string objLink = ReportDevicesBase.GetReportDevicesLinkAddress(location, mgmtId, ObjCatString.NwObj, chapterNumber, networkLocation.Object.Id, reportType); + objectLink = ReportBase.ConstructLink(ReportBase.GetIconClass(ObjCategory.nobj, networkLocation.Object.Type.Name), networkLocation.Object.Name, style, objLink); + } + + string nwLocation = DisplayNetworkLocation(networkLocation, reportType, userOutput, objectLink).ToString(); + + return reportType.IsRuleReport() ? $"{nwLocation}" : nwLocation; } - protected string NetworkLocationToHtml(NetworkLocation networkLocation, int mgmtId, OutputLocation location, string style, ReportType reportType) + protected static string ServiceToHtml(NetworkService service, int mgmtId, int chapterNumber, OutputLocation location, string style, ReportType reportType) { - return DisplayNetworkLocation(networkLocation, reportType, - reportType.IsResolvedReport() || networkLocation.User == null ? null : - constructLink("user", ReportBase.GetIconClass(ObjCategory.user, networkLocation.User?.Type.Name), networkLocation.User!.Id, networkLocation.User.Name, location, mgmtId, style), - reportType.IsResolvedReport() ? null : - constructLink("nwobj", ReportBase.GetIconClass(ObjCategory.nobj, networkLocation.Object.Type.Name), networkLocation.Object.Id, networkLocation.Object.Name, location, mgmtId, style) - ).ToString(); + if (reportType.IsResolvedReport() || reportType == ReportType.VarianceAnalysis) + { + return DisplayService(service, reportType, null).ToString(); + } + else + { + // Construct link for unresolved report types + string serviceLink = ReportDevicesBase.GetReportDevicesLinkAddress(location, mgmtId, ObjCatString.Svc, chapterNumber, service.Id, reportType); + string serviceName = ReportBase.ConstructLink(ReportBase.GetIconClass(ObjCategory.nsrv, service.Type.Name), service.Name, style, serviceLink); + return DisplayService(service, reportType, serviceName).ToString(); + } } - - protected string ServiceToHtml(NetworkService service, int mgmtId, OutputLocation location, string style, ReportType reportType) + protected static string EnforcingGatewayToHtml(Device gateway, int mgmtId, int chapterNumber, OutputLocation location, string style, ReportType reportType) { - return DisplayService(service, reportType, reportType.IsResolvedReport() ? null : - constructLink("svc", ReportBase.GetIconClass(ObjCategory.nsrv, service.Type.Name), service.Id, service.Name, location, mgmtId, style)).ToString(); + string gwLink = ReportDevicesBase.GetReportDevicesLinkAddress(location, mgmtId, ObjCatString.NwObj, chapterNumber, gateway.Id, reportType); + + return DisplayGateway(gateway, reportType, reportType.IsResolvedReport() ? null : + ReportBase.ConstructLink(ReportBase.GetIconClass(ObjCategory.nsrv, "Gateway"), gateway.Name ?? string.Empty, style, gwLink)).ToString(); } - private string DisplaySourceOrDestination(Rule rule, OutputLocation location, ReportType reportType, string style, bool isSource) + private string DisplaySourceOrDestination(Rule rule, int chapterNumber, OutputLocation location, ReportType reportType, string style, bool isSource, bool overwriteIsResolvedReport = false) { - StringBuilder result = new StringBuilder(); - if ((isSource && rule.SourceNegated) ||(!isSource && rule.DestinationNegated)) + StringBuilder result = new(); + if ((isSource && rule.SourceNegated) || (!isSource && rule.DestinationNegated)) { result.AppendLine(userConfig.GetText("negated") + "
                      "); } + string highlightedStyle = style + (reportType == ReportType.AppRules ? " " + GlobalConst.kStyleHighlightedRed : ""); - if(reportType.IsResolvedReport()) + if (!overwriteIsResolvedReport && reportType.IsResolvedReport()) { - NetworkLocation[] userNwObjects = getNetworkLocations(isSource ? rule.Froms : rule.Tos).ToArray(); - result.AppendJoin("
                      ", Array.ConvertAll(userNwObjects, networkLocation => NetworkLocationToHtml(networkLocation, rule.MgmtId, location, style, reportType))); + NetworkLocation[] userNwObjects = [.. GetResolvedNetworkLocations(isSource ? rule.Froms : rule.Tos)]; + result.AppendJoin("
                      ", Array.ConvertAll(userNwObjects, + nwLoc => NetworkLocationToHtml(nwLoc, rule.MgmtId, chapterNumber, location, highlightedStyle, reportType))); } else { - result.AppendJoin("
                      ", Array.ConvertAll(isSource ? rule.Froms : rule.Tos, networkLocation => NetworkLocationToHtml(networkLocation, rule.MgmtId, location, style, reportType))); + result.AppendJoin("
                      ", Array.ConvertAll(isSource ? rule.Froms : rule.Tos, + nwLoc => NetworkLocationToHtml(nwLoc, rule.MgmtId, chapterNumber, location, highlightedStyle, reportType))); + } + if (reportType == ReportType.AppRules) + { + result.Append(DisplayAppRuleSourceOrDestination(rule, chapterNumber, location, reportType, style, highlightedStyle, isSource)); } return result.ToString(); } - private string getNextRecertDateString (string countString, Recertification recert) + private string DisplayAppRuleSourceOrDestination(Rule rule, int chapterNumber, OutputLocation location, ReportType reportType, string style, string highlightedStyle, bool isSource) + { + StringBuilder result = new(); + if (!rule.ShowDisregarded && + ((isSource && rule.Froms.Length > 0 && rule.DisregardedFroms.Length > 0) || + (!isSource && rule.Tos.Length > 0 && rule.DisregardedTos.Length > 0))) + { + result.Append($"
                      ... ({(isSource ? rule.DisregardedFroms.Length : rule.DisregardedTos.Length)} {userConfig.GetText("more")})"); + } + else + { + if (result.Length > 0) + { + result.Append("
                      "); + } + result.AppendJoin("
                      ", Array.ConvertAll(isSource ? rule.DisregardedFroms : rule.DisregardedTos, + nwLoc => NetworkLocationToHtml(nwLoc, rule.MgmtId, chapterNumber, location, nwLoc.Object.IsAnyObject() ? highlightedStyle : style, reportType))); + } + return result.ToString(); + } + + private static string GetNextRecertDateString(string countString, Recertification recert) { string color = ""; string dateOnly = "-"; if (recert.NextRecertDate != null) { dateOnly = DateOnly.FromDateTime((DateTime)recert.NextRecertDate).ToString("yyyy-MM-dd"); - if(recert.NextRecertDate < DateTime.Now) + if (recert.NextRecertDate < DateTime.Now) { - color = " style=\"color: red;\""; + color = $" style=\"{GlobalConst.kStyleHighlightedRed}\""; } } return "" + countString + dateOnly + "

                      "; } - private string getOwnerDisplayString (string countString, Recertification recert) + private static string GetOwnerDisplayString(string countString, Recertification recert) { return "

                      " + countString + (recert.FwoOwner != null && recert.FwoOwner?.Name != null ? recert.FwoOwner.Name : "") + "

                      "; } - private string getIpMatchDisplayString (string countString, Recertification recert) + private static string GetIpMatchDisplayString(string countString, Recertification recert) { return "

                      " + countString + (recert.IpMatch != null && recert.IpMatch != "" ? recert.IpMatch : "‐") + "

                      "; } - private string getLastRecertifierDisplayString (string countString, Recertification recert) + private static string GetLastRecertifierDisplayString(string countString, Recertification recert) { return "

                      " + countString + "

                      "; // TODO: fetch last recertifier } - private string countString(bool multipleOwners, int ownerCounter) + private static string CountString(bool multipleOwners, int ownerCounter) { return multipleOwners ? ownerCounter.ToString() + ". " : ""; } diff --git a/roles/lib/files/FWO.Report/Display/RuleDisplayJson.cs b/roles/lib/files/FWO.Report/Display/RuleDisplayJson.cs index dd9c095c57..4143848b1a 100644 --- a/roles/lib/files/FWO.Report/Display/RuleDisplayJson.cs +++ b/roles/lib/files/FWO.Report/Display/RuleDisplayJson.cs @@ -1,111 +1,191 @@ -using FWO.Api.Data; +using FWO.Basics; using FWO.Config.Api; +using FWO.Data; +using FWO.Report; using FWO.Report.Filter; +using System.Text; namespace FWO.Ui.Display { - public class RuleDisplayJson : RuleDisplayBase + public class RuleDisplayJson(UserConfig userConfig) : RuleDisplayBase(userConfig) { - public RuleDisplayJson(UserConfig userConfig) : base(userConfig) - { } - - public string DisplayJsonPlain(string tag, string? value) + private string DisplayJsonPlain(string tag, string? value) { return (value != null ? $"\"{tag}\": {value}," : ""); } - public string DisplayJsonString(string tag, string? value) + protected string DisplayJsonString(string tag, string? value) { return (value != null ? $"\"{tag}\": \"{value}\"," : ""); } - public string DisplayJsonArray(string tag, string? value) + protected string DisplayJsonArray(string tag, string? value) { return (value != null ? $"\"{tag}\": [{value}]," : ""); } - public new string DisplayNumber(Rule rule) + private new string DisplayNumber(Rule rule) { return DisplayJsonPlain("number", rule.DisplayOrderNumber.ToString()); } - public string DisplayName(string? name) + protected string DisplayName(string? name) { return DisplayJsonString("name", name); } - public string DisplaySourceZone(string? sourceZone) + protected string DisplayRuleSourceZones(NetworkZone[] networkZones) { - return DisplayJsonString("source zone", sourceZone); + return DisplayJsonArray("source zones", ListNetworkZones(networkZones)); } - public string DisplaySourceNegated(bool sourceNegated) + protected string DisplaySourceNegated(bool sourceNegated) { return DisplayJsonPlain("source negated", sourceNegated.ToString().ToLower()); } - public string DisplaySource(Rule rule, ReportType reportType) + protected string DisplaySource(Rule rule, ReportType reportType) { return DisplayJsonArray("source", ListNetworkLocations(rule, reportType, true)); } - public string DisplayDestinationZone(string? destinationZone) + protected string DisplayRuleDestinationZones(NetworkZone[] networkZones) { - return DisplayJsonString("destination zone", destinationZone); + return DisplayJsonArray("destination zones", ListNetworkZones(networkZones)); } - public string DisplayDestinationNegated(bool destinationNegated) + protected string DisplayDestinationNegated(bool destinationNegated) { return DisplayJsonPlain("destination negated", destinationNegated.ToString().ToLower()); } - public string DisplayDestination(Rule rule, ReportType reportType) + protected string DisplayDestination(Rule rule, ReportType reportType) { return DisplayJsonArray("destination", ListNetworkLocations(rule, reportType, false)); } - public string DisplayServiceNegated(bool serviceNegated) + protected string DisplayServiceNegated(bool serviceNegated) { return DisplayJsonPlain("service negated", serviceNegated.ToString().ToLower()); } - public string DisplayServices(Rule rule, ReportType reportType) + protected string DisplayServices(Rule rule, ReportType reportType) { return DisplayJsonArray("service", ListServices(rule, reportType)); } - public string DisplayAction(string? action) + protected string DisplayAction(string? action) { return DisplayJsonString("action", action); } - public string DisplayTrack(string? track) + protected string DisplayTrack(string? track) { return DisplayJsonString("tracking", track); } - public string DisplayUid(string? uid) + protected string DisplayEnforcingGateways(IEnumerable gateways) + { + return DisplayJsonArray("Enforcing Gateway", ListEnforcingGateways(gateways)); + } + + protected string DisplayUid(string? uid) { return DisplayJsonString("rule uid", uid); } - public string DisplayEnabled(bool disabled) + protected string DisplayEnabled(bool disabled) { return DisplayJsonPlain("disabled", disabled.ToString().ToLower()); } - public string DisplayComment(string? comment) + protected string DisplayComment(string? comment) { return DisplayJsonString("comment", comment); } + protected string DisplayObjectType(string? objectType) + { + return DisplayJsonString("ObjectType", objectType); + } + + + protected string DisplayServiceProtocol(string? serviceProtocol) + { + return DisplayJsonString("Protocol", serviceProtocol); + } + + protected string DisplayServicePort(string? servicePort) + { + return DisplayJsonString("Port", servicePort); + } + + protected string DisplayObjectIP(string? objectIP) + { + return DisplayJsonString("Object Type", objectIP); + } + + protected string DisplayobjectMemberNames(string? objectMemberNames) + { + return DisplayJsonString("Member Names", objectMemberNames); + } + + + /// + /// Builds a string representing a JSON object that includes all properties of the supplied . + /// The output comprises formatted JSON fields for the rule, structured for reporting use. + /// If the rule has a SectionHeader, only the section header field is added; otherwise, all rule details are serialized as individual JSON properties. + /// + /// + /// The instance whose data will be serialized into a JSON object string. + /// + /// + /// The used to control formatting or additional field inclusion within the output JSON. + /// + /// + /// A string containing a syntactically valid JSON object with the specified rule’s properties and values, intended for direct use as part of a JSON array or document. + /// + public string DisplayRuleJsonObject(Rule rule, ReportType reportType) + { + StringBuilder stringBuilder = new StringBuilder(); + + stringBuilder.Append('{'); + if (string.IsNullOrEmpty(rule.SectionHeader)) + { + stringBuilder.Append(DisplayNumber(rule)); + stringBuilder.Append(DisplayName(rule.Name)); + stringBuilder.Append(DisplayRuleSourceZones(rule.RuleFromZones + .Select(zoneWrapper => zoneWrapper.Content).ToArray())); + stringBuilder.Append(DisplaySourceNegated(rule.SourceNegated)); + stringBuilder.Append(DisplaySource(rule, reportType)); + stringBuilder.Append(DisplayRuleDestinationZones(rule.RuleToZones + .Select(zoneWrapper => zoneWrapper.Content).ToArray())); + stringBuilder.Append(DisplayDestinationNegated(rule.DestinationNegated)); + stringBuilder.Append(DisplayDestination(rule, reportType)); + stringBuilder.Append(DisplayServiceNegated(rule.ServiceNegated)); + stringBuilder.Append(DisplayServices(rule, reportType)); + stringBuilder.Append(DisplayAction(rule.Action)); + stringBuilder.Append(DisplayTrack(rule.Track)); + stringBuilder.Append(DisplayEnabled(rule.Disabled)); + stringBuilder.Append(DisplayUid(rule.Uid)); + stringBuilder.Append(DisplayComment(rule.Comment)); + RemoveLastChars(stringBuilder, 1).ToString(); + } + else + { + stringBuilder.AppendLine("\"section header\": \"" + rule.SectionHeader + "\""); + } + stringBuilder.Append("},"); + return stringBuilder.ToString(); + } + protected string ListNetworkLocations(Rule rule, ReportType reportType, bool isSource) { if (reportType.IsResolvedReport()) { List displayedLocations = new List(); - foreach (NetworkLocation networkLocation in getNetworkLocations(isSource ? rule.Froms : rule.Tos)) + foreach (NetworkLocation networkLocation in GetResolvedNetworkLocations(isSource ? rule.Froms : rule.Tos)) { displayedLocations.Add(Quote(DisplayNetworkLocation(networkLocation, reportType).ToString())); } @@ -123,9 +203,28 @@ protected string ListServices(Rule rule, ReportType reportType) { displayedServices.Add(Quote(DisplayService(service, reportType).ToString())); } - return(string.Join(",", displayedServices)); + return (string.Join(",", displayedServices)); } return ""; } + + protected string ListEnforcingGateways(IEnumerable gateways) + { + return string.Join(",", + gateways + .Where(gw => gw?.Content?.Name != null) + .Select(gw => Quote(gw.Content.Name)) + ); + } + + protected string ListNetworkZones(NetworkZone[] networkZones) + { + List displayedZones = new List(); + foreach (NetworkZone networkZone in networkZones) + { + displayedZones.Add(Quote(networkZone.Name)); + } + return string.Join(",", displayedZones); + } } } diff --git a/roles/lib/files/FWO.Report/FWO.Report.csproj b/roles/lib/files/FWO.Report/FWO.Report.csproj index 2c447419c7..6f18925a78 100644 --- a/roles/lib/files/FWO.Report/FWO.Report.csproj +++ b/roles/lib/files/FWO.Report/FWO.Report.csproj @@ -1,19 +1,22 @@ - + - net6.0 + net10.0 enable enable - + + + + diff --git a/roles/lib/files/FWO.Report/NormalizedConfigGenerator.cs b/roles/lib/files/FWO.Report/NormalizedConfigGenerator.cs new file mode 100644 index 0000000000..9655b153f8 --- /dev/null +++ b/roles/lib/files/FWO.Report/NormalizedConfigGenerator.cs @@ -0,0 +1,84 @@ +using FWO.Api.Client; +using FWO.Api.Client.Queries; +using FWO.Basics; +using FWO.Config.Api; +using FWO.Data; +using FWO.Data.Report; +using FWO.Logging; +using FWO.Report.Filter; +using Newtonsoft.Json; + +namespace FWO.Report +{ + public static class NormalizedConfigGenerator + { + public static async Task Generate(List managementIds, string? configTime, ApiConnection apiConnection) + { + if (string.IsNullOrEmpty(configTime)) + { + Dictionary queryVars = new() + { + { "mgm_ids", managementIds } + }; + List managementData = await apiConnection.SendQueryAsync>(ReportQueries.getManagementForLatestNormalizedConfig, queryVars); + if (managementData.Count == 0) + { + throw new ArgumentException("No management data found for the given management IDs."); + } + return ParseFromManagementData(managementData[0]); + } + // TODO: Implement configTime handling - see #3645 + throw new NotImplementedException("configTime handling not yet implemented."); + } + + public static async Task> GetRelevantImportId(ApiConnection apiConnection, int managementId, string configTime) + { + DateTime time; + try + { + time = DateTime.ParseExact(configTime, DynGraphqlQuery.fullTimeFormat, System.Globalization.CultureInfo.InvariantCulture); + } + catch (FormatException) + { + Log.WriteError("GetRelevantImportId", $"Invalid timestamp format.", null); + throw new ArgumentException($"Invalid timestamp format. Please use {DynGraphqlQuery.fullTimeFormat}."); + } + Dictionary ImpIdQueryVariables = new() + { + [QueryVar.Time] = time.ToString(DynGraphqlQuery.fullTimeFormat), + [QueryVar.MgmIds] = managementId + }; + return await apiConnection.SendQueryAsync>(ReportQueries.getRelevantImportIdsAtTime, ImpIdQueryVariables); + } + + public static NormalizedConfig ParseFromManagementData(Management managementData) + { + var normalizedConfig = new NormalizedConfig + { + ConfigFormat = "NORMALIZED", + Action = "INSERT", + NetworkObjects = managementData.Objects.ToDictionary( + nwobj => nwobj.Uid, + NormalizedNetworkObject.FromNetworkObject + ), + ServiceObjects = managementData.Services.ToDictionary( + svc => svc.Uid, + NormalizedServiceObject.FromNetworkService + ), + Users = [], // TODO: implement + ZoneObjects = managementData.Zones.ToDictionary( + zone => zone.Name, + NormalizedZoneObject.FromZoneObject + ), + TimeObjects = managementData.TimeObjects.ToDictionary( + timeObj => timeObj.Uid, + NormalizedTimeObject.FromTimeObject + ), + Rulebases = [.. managementData.Rulebases.Select(rb => NormalizedRulebase.FromRulebase(rb, managementData.Uid ?? ""))], + Gateways = [.. managementData.Devices.Select(NormalizedGateway.FromDevice)] + }; + + return normalizedConfig; + } + } +} diff --git a/roles/lib/files/FWO.Report/PaperFormat.cs b/roles/lib/files/FWO.Report/PaperFormat.cs new file mode 100644 index 0000000000..be7bbb685b --- /dev/null +++ b/roles/lib/files/FWO.Report/PaperFormat.cs @@ -0,0 +1,18 @@ +namespace FWO.Report +{ + public enum PaperFormat + { + A0, + A1, + A2, + A3, + A4, + A5, + A6, + Letter, + Legal, + Tabloid, + Ledger, + Custom + } +} diff --git a/roles/lib/files/FWO.Report/RecertificateOwner.cs b/roles/lib/files/FWO.Report/RecertificateOwner.cs new file mode 100644 index 0000000000..45de6f2cc1 --- /dev/null +++ b/roles/lib/files/FWO.Report/RecertificateOwner.cs @@ -0,0 +1,39 @@ +using FWO.Basics; +using FWO.Config.Api; +using FWO.Data; +using FWO.Data.Report; +using FWO.Report.Filter; +using System.Text; + +namespace FWO.Report +{ + public class RecertificateOwner(DynGraphqlQuery query, UserConfig userConfig, ReportType reportType) : ReportConnections(query, userConfig, reportType) + { + public override string ExportToHtml() + { + StringBuilder report = new(); + int chapterNumber = 0; + AppendOwnerData(ref report, ReportData.OwnerData, chapterNumber); + + return GenerateHtmlFrame(userConfig.GetText(ReportType.ToString()), Query.RawFilter, DateTime.Now, report); + } + + public void AppendOwnerData(ref StringBuilder report, List ownerReports, int chapterNumber, int levelshift = 0) + { + Levelshift = levelshift; + foreach (var ownerReport in ownerReports) + { + chapterNumber++; + report.AppendLine(Headline(GetRecertText(ownerReport, userConfig), 2)); + AppendConnDataForOwner(ref report, ownerReport, chapterNumber); + report.AppendLine("
                      "); + } + } + + public static string GetRecertText(OwnerConnectionReport ownerReport, UserConfig userConfig) + { + return $"{userConfig.GetText("recertification")} {ownerReport.Owner.LastRecertified?.ToString("dd.MM.yyyy HH:mm") ?? "-"} " + + (ownerReport.Owner.LastRecertifierDn != null ? $"{userConfig.GetText("by")} {new DistName(ownerReport.Owner.LastRecertifierDn).UserName}" : ""); + } + } +} diff --git a/roles/lib/files/FWO.Report/ReportAppRules.cs b/roles/lib/files/FWO.Report/ReportAppRules.cs new file mode 100644 index 0000000000..f9b023733b --- /dev/null +++ b/roles/lib/files/FWO.Report/ReportAppRules.cs @@ -0,0 +1,279 @@ +using FWO.Api.Client; +using FWO.Api.Client.Queries; +using FWO.Data; +using FWO.Data.Report; +using FWO.Data.Modelling; +using FWO.Report.Filter; +using FWO.Config.Api; +using NetTools; +using System.Net; +using FWO.Basics; + +namespace FWO.Report +{ + public class ReportAppRules : ReportRules + { + private readonly ModellingFilter modellingFilter; + + public ReportAppRules(DynGraphqlQuery query, UserConfig userConfig, ReportType reportType, ModellingFilter modellingFilter) : base(query, userConfig, reportType) + { + this.modellingFilter = modellingFilter; + } + + public ReportAppRules(ReportRules reportRules, ModellingFilter modellingFilter) : base(reportRules.Query, reportRules.userConfig, reportRules.ReportType) + { + this.modellingFilter = modellingFilter; + } + + public override async Task Generate(int elementsPerFetch, ApiConnection apiConnection, Func callback, CancellationToken ct) + { + await base.Generate(elementsPerFetch, apiConnection, callback, ct); + ReportData.ManagementData = await PrepareAppRulesReport(ReportData.ManagementData, modellingFilter, apiConnection, Query.SelectedOwner?.Id); + } + + public override async Task GetObjectsForManagementInReport(Dictionary objQueryVariables, ObjCategory objects, int maxFetchCycles, ApiConnection apiConnection, Func callback) + { + int mid = (int)objQueryVariables.GetValueOrDefault(QueryVar.MgmIds)!; + ManagementReport managementReport = ReportData.ManagementData.FirstOrDefault(m => m.Id == mid) ?? throw new ArgumentException("Given management id does not exist for this report"); + PrepareFilter(managementReport, await GetAppServers(apiConnection, Query.SelectedOwner?.Id)); + UseAdditionalFilter = !modellingFilter.ShowFullRules; + + bool gotAllObjects = await base.GetObjectsForManagementInReport(objQueryVariables, objects, maxFetchCycles, apiConnection, callback); + if (gotAllObjects) + { + PrepareRsbOutput(managementReport); + } + return gotAllObjects; + } + + public static async Task> PrepareAppRulesReport(List managementData, ModellingFilter modellingFilter, ApiConnection apiConnection, int? ownerId) + { + List ownerIps = await GetAppServers(apiConnection, ownerId); + List relevantData = []; + foreach (var mgt in managementData) + { + ManagementReport relevantMgt = new() { Name = mgt.Name, Id = mgt.Id, Import = mgt.Import }; + foreach (var rulebase in mgt.Rulebases) + { + PrepareRulebase(rulebase, modellingFilter, relevantMgt, ownerIps); + } + if (relevantMgt.Rulebases.Length > 0) + { + relevantMgt.ReportedRuleIds = [.. relevantMgt.ReportedRuleIds.Distinct()]; + relevantMgt.Devices = [.. PrepareDevices(mgt.Devices)]; + relevantData.Add(relevantMgt); + } + } + return relevantData; + } + + private static List PrepareDevices(DeviceReport[] deviceReports) + { + List selectedDeviceReports = []; + foreach (var devReport in deviceReports) + { + DeviceReport selectedDevReport = new(devReport); + foreach (var rule in devReport.GetRuleList()) + { + if (selectedDevReport.IsLinked(rule)) + { + selectedDevReport.AddRule(rule); + } + } + if (selectedDevReport.ContainsRules()) + { + selectedDeviceReports.Add(selectedDevReport); + } + } + return selectedDeviceReports; + } + + private static void PrepareRulebase(RulebaseReport rulebase, ModellingFilter modellingFilter, ManagementReport relevantMgt, List ownerIps) + { + RulebaseReport relevantRulebase = new() { Name = rulebase.Name, Id = rulebase.Id }; + foreach (var rule in rulebase.Rules) + { + PrepareRule(rule, modellingFilter, relevantMgt, relevantRulebase, ownerIps); + } + if (relevantRulebase.Rules.Length > 0) + { + relevantMgt.Rulebases = [.. relevantMgt.Rulebases, relevantRulebase]; + } + } + + private static void PrepareRule(Rule rule, ModellingFilter modellingFilter, ManagementReport relevantMgt, RulebaseReport relevantRulebase, List ownerIps) + { + if (modellingFilter.ShowDropRules || !rule.IsDropRule()) + { + List relevantFroms = []; + List disregardedFroms = [.. rule.Froms]; + if (modellingFilter.ShowSourceMatch) + { + (relevantFroms, disregardedFroms) = CheckNetworkObjects(rule.Froms, rule.SourceNegated, modellingFilter, ownerIps); + } + List relevantTos = []; + List disregardedTos = [.. rule.Tos]; + if (modellingFilter.ShowDestinationMatch) + { + (relevantTos, disregardedTos) = CheckNetworkObjects(rule.Tos, rule.DestinationNegated, modellingFilter, ownerIps); + } + + if (relevantFroms.Count > 0 || relevantTos.Count > 0) + { + rule.Froms = [.. relevantFroms]; + rule.Tos = [.. relevantTos]; + rule.DisregardedFroms = [.. disregardedFroms]; + rule.DisregardedTos = [.. disregardedTos]; + rule.ShowDisregarded = modellingFilter.ShowFullRules; + relevantRulebase.Rules = [.. relevantRulebase.Rules, rule]; + relevantMgt.ReportedRuleIds.Add(rule.Id); + } + } + } + + private static async Task> GetAppServers(ApiConnection apiConnection, int? ownerId) + { + List appServers = await apiConnection.SendQueryAsync>(ModellingQueries.getAppServersForOwner, + new { appId = ownerId }); + return [.. appServers.ConvertAll(s => new IPAddressRange(IPAddress.Parse(s.Ip.StripOffNetmask()), + IPAddress.Parse((s.IpEnd != "" ? s.IpEnd : s.Ip).StripOffNetmask())))]; + } + + private static (List, List) CheckNetworkObjects(NetworkLocation[] objList, bool negated, ModellingFilter modellingFilter, List ownerIps) + { + List relevantObjects = []; + List disregardedObjects = []; + foreach (var obj in objList) + { + if (obj.Object.IsAnyObject()) + { + if (modellingFilter.ShowAnyMatch) + { + relevantObjects.Add(obj); + } + else + { + disregardedObjects.Add(obj); + } + } + else + { + CheckSpecificObj(obj, negated, ownerIps, relevantObjects, disregardedObjects); + } + } + return (relevantObjects, disregardedObjects); + } + + private static void CheckSpecificObj(NetworkLocation obj, bool negated, List ownerIps, List relevantObjects, List disregardedObjects) + { + bool found = false; + if (obj.Object.Type.Name == ObjectType.Group) + { + foreach (var grpobj in obj.Object.ObjectGroupFlats.Select(o => o.Object)) + { + if (grpobj != null && CheckObj(grpobj, negated, ownerIps)) + { + relevantObjects.Add(obj); + found = true; + break; + } + } + } + else if (CheckObj(obj.Object, negated, ownerIps)) + { + relevantObjects.Add(obj); + found = true; + } + if (!found) + { + disregardedObjects.Add(obj); + } + } + + private static bool CheckObj(NetworkObject obj, bool negated, List ownerIps) + { + foreach (var ownerIpRange in ownerIps) + { + if (obj.IP == null) + { + continue; + } + + IPAddressRange objRange = new(IPAddress.Parse(obj.IP.StripOffNetmask()), + IPAddress.Parse((obj.IpEnd != null && obj.IpEnd != "" ? obj.IpEnd : obj.IP).StripOffNetmask())); + + if (negated) + { + if (IpOperations.IpToUint(ownerIpRange.Begin) < IpOperations.IpToUint(objRange.Begin) || + (IpOperations.IpToUint(ownerIpRange.End) > IpOperations.IpToUint(objRange.End))) + { + return true; + } + } + else if (IpOperations.RangeOverlapExists(objRange, ownerIpRange)) + { + return true; + } + } + return false; + } + + private static void PrepareFilter(ManagementReport mgt, List ownerIps) + { + mgt.RelevantObjectIds = []; + mgt.HighlightedObjectIds = []; + foreach (var rb in mgt.Rulebases) + { + foreach (var rule in rb.Rules) + { + PrepareObjects(rule.Froms, rule.SourceNegated, rule.DisregardedFroms, mgt, ownerIps); + PrepareObjects(rule.Tos, rule.DestinationNegated, rule.DisregardedTos, mgt, ownerIps); + } + } + mgt.RelevantObjectIds = [.. mgt.RelevantObjectIds.Distinct()]; + mgt.HighlightedObjectIds = [.. mgt.HighlightedObjectIds.Distinct()]; + } + + private static void PrepareObjects(NetworkLocation[] networkLocations, bool negated, NetworkLocation[] disregardedLocations, ManagementReport mgt, List ownerIps) + { + foreach (var from in networkLocations.Select(f => f.Object)) + { + mgt.RelevantObjectIds.Add(from.Id); + mgt.HighlightedObjectIds.Add(from.Id); + if (from.Type.Name == ObjectType.Group) + { + foreach (var grpobj in from.ObjectGroupFlats.Select(g => g.Object).Where(gr => gr != null && CheckObj(gr, negated, ownerIps))) + { + mgt.HighlightedObjectIds.Add(grpobj!.Id); + } + } + } + if (networkLocations.Length == 0) + { + foreach (var from in disregardedLocations) + { + mgt.RelevantObjectIds.Add(from.Object.Id); + } + } + } + + private static void PrepareRsbOutput(ManagementReport mgt) + { + foreach (var obj in mgt.ReportObjects) + { + obj.Highlighted = mgt.HighlightedObjectIds.Contains(obj.Id) || obj.IsAnyObject(); + if (obj.Type.Name == ObjectType.Group) + { + foreach (var grpobj in obj.ObjectGroupFlats.Select(g => g.Object).Where(g => g != null)) + { + grpobj!.Highlighted = mgt.HighlightedObjectIds.Contains(grpobj.Id) || grpobj.IsAnyObject(); + } + foreach (var grpobj in obj.ObjectGroups.Select(g => g.Object).Where(g => g != null)) + { + grpobj!.Highlighted = mgt.HighlightedObjectIds.Contains(grpobj.Id) || grpobj.IsAnyObject(); + } + } + } + } + } +} diff --git a/roles/lib/files/FWO.Report/ReportBase.cs b/roles/lib/files/FWO.Report/ReportBase.cs index 2f4c839dd8..98eb87aeaf 100644 --- a/roles/lib/files/FWO.Report/ReportBase.cs +++ b/roles/lib/files/FWO.Report/ReportBase.cs @@ -1,32 +1,57 @@ -using FWO.Api.Client; -using FWO.Api.Client.Queries; -using FWO.Api.Data; -using FWO.Report.Filter; +using FWO.Api.Client; +using FWO.Basics; +using FWO.Basics.Exceptions; using FWO.Config.Api; -using System.Text.Json; +using FWO.Data.Report; +using FWO.Logging; +using FWO.Report.Data; +using FWO.Report.Filter; +using FWO.Services.RuleTreeBuilder; using System.Text; -using WkHtmlToPdfDotNet; +using System.Reflection; +using PuppeteerSharp; +using PuppeteerSharp.Media; +using PuppeteerSharp.BrowserData; +using HtmlAgilityPack; +using System.Runtime.InteropServices; namespace FWO.Report { public enum RsbTab { - all = 10, - report = 20, - rule = 30 + all = 10, + report = 20, + rule = 30, + + usedObj = 40, + unusedObj = 50 } public enum ObjCategory { all = 0, - nobj = 1, - nsrv = 2, + nobj = 1, + nsrv = 2, user = 3 } + public struct ObjCatString + { + public const string NwObj = "nwobj"; + public const string Svc = "svc"; + public const string User = "user"; + } + + public enum OutputLocation + { + export, + report, + certification + } + public abstract class ReportBase { - protected StringBuilder HtmlTemplate = new StringBuilder($@" + protected StringBuilder HtmlTemplate = new($@" @@ -56,217 +81,534 @@ public abstract class ReportBase

                      ##Title##

                      -

                      Filter: ##Filter##

                      ##Date-of-Config##: ##GeneratedFor## (UTC)

                      ##GeneratedOn##: ##Date## (UTC)

                      -

                      Devices: ##DeviceFilter##

                      +

                      ##OwnerFilters##

                      +

                      ##OtherFilters##

                      +

                      ##Filter##

                      +
                      + ##ToC##
                      ##Body## "); - public Management[] Managements = new Management[] { }; - public readonly DynGraphqlQuery Query; - protected UserConfig userConfig; - public ReportType ReportType; + public UserConfig userConfig; + public ReportType ReportType { get; set; } + public ReportData ReportData { get; set; } = new(); + public int CustomWidth { get; set; } = 0; + public int CustomHeight { get; set; } = 0; + protected int Levelshift = 0; - private string htmlExport = ""; + protected string htmlExport = ""; + + private string TocHTMLTemplate = "

                      ##ToCHeader##

                        ##ToCList##
                      "; + + public bool GotObjectsInReport { get; protected set; } = false; - // Pdf converter - protected static readonly SynchronizedConverter converter = new SynchronizedConverter(new PdfTools()); - public ReportBase(DynGraphqlQuery query, UserConfig UserConfig, ReportType reportType) + protected ReportBase(DynGraphqlQuery query, UserConfig UserConfig, ReportType reportType) { Query = query; userConfig = UserConfig; ReportType = reportType; } - public abstract Task Generate(int rulesPerFetch, ApiConnection apiConnection, Func callback, CancellationToken ct); + public abstract Task Generate(int elementsPerFetch, ApiConnection apiConnection, Func callback, CancellationToken ct); - public bool GotObjectsInReport { get; protected set; } = false; + public virtual async Task GetObjectsInReport(int objectsPerFetch, ApiConnection apiConnection, Func callback) + { + await callback(ReportData); + // currently no further objects to be fetched + GotObjectsInReport = true; + return true; + } - public abstract Task GetObjectsInReport(int objectsPerFetch, ApiConnection apiConnection, Func callback); // to be called when exporting + public virtual Task GetObjectsForManagementInReport(Dictionary objQueryVariables, ObjCategory objects, int maxFetchCycles, ApiConnection apiConnection, Func callback) + { + throw new NotImplementedException(); + } + + public virtual bool NoRuleFound() + { + return true; + } - public abstract Task GetObjectsForManagementInReport(Dictionary objQueryVariables, ObjCategory objects, int maxFetchCycles, ApiConnection apiConnection, Func callback); + public virtual bool NoChangesFound() + { + return true; + } public abstract string ExportToCsv(); - public virtual string ExportToJson() + public abstract string ExportToJson(); + + public abstract string ExportToHtml(); + + public abstract string SetDescription(); + + public static ReportBase ConstructReport(ReportTemplate reportFilter, UserConfig userConfig, IRuleTreeBuilder? ruleTreeBuilder = null) { - return JsonSerializer.Serialize(Managements.Where(mgt => !mgt.Ignore), new JsonSerializerOptions { WriteIndented = true }); + DynGraphqlQuery query = Compiler.Compile(reportFilter); + ReportType repType = (ReportType)reportFilter.ReportParams.ReportType; + WorkflowFilter workflowFilter = BuildEffectiveWorkflowFilter(query, reportFilter.ReportParams.WorkflowFilter); + return repType switch + { + ReportType.Statistics => new ReportStatistics(query, userConfig, repType), + ReportType.Rules => new ReportRules(query, userConfig, repType, ruleTreeBuilder), + ReportType.ResolvedRules => new ReportRules(query, userConfig, repType, ruleTreeBuilder), + ReportType.ResolvedRulesTech => new ReportRules(query, userConfig, repType, ruleTreeBuilder), + ReportType.Changes => new ReportChanges(query, userConfig, repType, reportFilter.ReportParams.TimeFilter, reportFilter.ReportParams.IncludeObjects), + ReportType.ResolvedChanges => new ReportChanges(query, userConfig, repType, reportFilter.ReportParams.TimeFilter, reportFilter.ReportParams.IncludeObjects), + ReportType.ResolvedChangesTech => new ReportChanges(query, userConfig, repType, reportFilter.ReportParams.TimeFilter, reportFilter.ReportParams.IncludeObjects), + ReportType.NatRules => new ReportNatRules(query, userConfig, repType), + ReportType.Recertification => new ReportRules(query, userConfig, repType, ruleTreeBuilder), + ReportType.UnusedRules => new ReportRules(query, userConfig, repType, ruleTreeBuilder), + ReportType.Connections => new ReportConnections(query, userConfig, repType), + ReportType.AppRules => new ReportAppRules(query, userConfig, repType, reportFilter.ReportParams.ModellingFilter), + ReportType.VarianceAnalysis => new ReportVariances(query, userConfig, repType), + ReportType.ComplianceReport => new ReportCompliance(query, userConfig, repType, reportFilter.ReportParams), + ReportType.ComplianceDiffReport => new ReportComplianceDiff(query, userConfig, repType, reportFilter.ReportParams), + ReportType.OwnerRecertification => new ReportOwnerRecerts(query, userConfig, repType), + ReportType.RecertificationEvent => new RecertificateOwner(query, userConfig, repType), + ReportType.RecertEventReport => new ReportRecertEvent(query, userConfig, repType, ruleTreeBuilder), + ReportType.TicketReport => new ReportTickets(query, userConfig, repType, workflowFilter), + ReportType.TicketChangeReport => new ReportTicketChanges(query, userConfig, repType, workflowFilter), + ReportType.Owners => new ReportOwners(query, userConfig, repType), + _ => throw new NotSupportedException("Report Type is not supported."), + }; } - public abstract string ExportToHtml(); + private static WorkflowFilter BuildEffectiveWorkflowFilter(DynGraphqlQuery query, WorkflowFilter workflowFilter) + { + WorkflowFilter effectiveWorkflowFilter = new(workflowFilter); + + if (query.WorkflowTaskTypes.Count > 0) + { + effectiveWorkflowFilter.TaskTypes = [.. query.WorkflowTaskTypes]; + } + + if (query.WorkflowStateIds.Count > 0) + { + effectiveWorkflowFilter.StateIds = [.. query.WorkflowStateIds]; + } + + if (!string.IsNullOrWhiteSpace(query.WorkflowPhase)) + { + effectiveWorkflowFilter.Phase = query.WorkflowPhase; + } + + if (query.WorkflowReferenceDateFilter.HasValue) + { + effectiveWorkflowFilter.ReferenceDate = query.WorkflowReferenceDateFilter.Value; + } - public virtual string SetDescription() + return effectiveWorkflowFilter; + } + + public static string GetLinkAddress(OutputLocation location, string reportId, string type, int chapterNumber, long id, ReportType reportType) { - int managementCounter = 0; - foreach (var management in Managements.Where(mgt => !mgt.Ignore)) + string page = location == OutputLocation.report ? PageName.ReportGeneration : PageName.Certification; + string link; + if (reportType.IsChangeReport()) { - managementCounter++; + link = location == OutputLocation.export ? $"#" : $"{page}#goto-all-{reportId}-"; } - return $"{managementCounter} {userConfig.GetText("managements")}"; + else + { + link = location == OutputLocation.export ? $"#" : $"{page}#goto-report-{reportId}-"; + } + return $"{link}{type}{chapterNumber}x{id}"; } - protected string GenerateHtmlFrame(string title, string filter, DateTime date, StringBuilder htmlReport) + public static string ConstructLink(string symbol, string name, string style, string linkAddress) + { + return $" {name}"; + } + + protected static string OutputCsv(string? input) + { + return $"\"{input?.Replace("\"", "\"\"") ?? ""}\","; + } + + protected string GenerateHtmlFrameBase(string title, string filter, DateTime date, StringBuilder htmlReport, string? otherFilter = null, string? ownerFilter = null, TimeFilter? timeFilter = null) { if (string.IsNullOrEmpty(htmlExport)) { HtmlTemplate = HtmlTemplate.Replace("##Title##", title); - HtmlTemplate = HtmlTemplate.Replace("##Filter##", filter); + ReplaceFilter(filter); HtmlTemplate = HtmlTemplate.Replace("##GeneratedOn##", userConfig.GetText("generated_on")); HtmlTemplate = HtmlTemplate.Replace("##Date##", date.ToUniversalTime().ToString("yyyy-MM-ddTHH:mm:ssK")); - if(ReportType.IsChangeReport()) + ReplaceDateOfConfig(timeFilter); + ReplaceOwnerFilter(ownerFilter); + ReplaceOtherFilter(otherFilter); + + string htmlToC = BuildHTMLToC(htmlReport.ToString()); + HtmlTemplate = HtmlTemplate.Replace("##ToC##", htmlToC); + HtmlTemplate = HtmlTemplate.Replace("##Body##", htmlReport.ToString()); + htmlExport = HtmlTemplate.ToString(); + } + return htmlExport; + } + + private void ReplaceFilter(string filter) + { + if (filter != "") + { + HtmlTemplate = HtmlTemplate.Replace("##Filter##", userConfig.GetText("filter") + ": " + filter); + } + else + { + HtmlTemplate = HtmlTemplate.Replace("

                      ##Filter##

                      ", ""); + } + } + + private void ReplaceDateOfConfig(TimeFilter? timeFilter) + { + if (ReportType.IsChangeReport() || ReportType == ReportType.TicketChangeReport) + { + (string startTime, string stopTime) = ReportType == ReportType.TicketChangeReport && timeFilter == null + ? ((string)Query.QueryVariables["ticket_time_start"], (string)Query.QueryVariables["ticket_time_end"]) + : DynGraphqlQuery.ResolveTimeRange(timeFilter ?? new()); + string timeRange = $"{userConfig.GetText("change_time")}: " + + $"{userConfig.GetText("from")}: {ToUtcString(startTime)}, " + + $"{userConfig.GetText("until")}: {ToUtcString(stopTime)}"; + HtmlTemplate = HtmlTemplate.Replace("##Date-of-Config##: ##GeneratedFor##", timeRange); + } + else if (ReportType.HasTimeFilter()) + { + HtmlTemplate = HtmlTemplate.Replace("##Date-of-Config##", userConfig.GetText("date_of_config")); + HtmlTemplate = HtmlTemplate.Replace("##GeneratedFor##", ToUtcString(Query.ReportTimeString)); + } + else + { + HtmlTemplate = HtmlTemplate.Replace("

                      ##Date-of-Config##: ##GeneratedFor## (UTC)

                      ", ""); + } + } + + private void ReplaceOwnerFilter(string? ownerFilter) + { + if (ownerFilter != null && ownerFilter != "") + { + HtmlTemplate = HtmlTemplate.Replace("##OwnerFilters##", userConfig.GetText("owners") + ": " + ownerFilter); + } + else + { + HtmlTemplate = HtmlTemplate.Replace("

                      ##OwnerFilters##

                      ", ""); + } + } + + private void ReplaceOtherFilter(string? otherFilter) + { + if (otherFilter != null && ReportType != ReportType.RecertEventReport) + { + if (ReportType.IsWorkflowReport()) { - HtmlTemplate = HtmlTemplate.Replace("

                      ##Date-of-Config##: ##GeneratedFor## (UTC)

                      ", ""); + HtmlTemplate = HtmlTemplate.Replace("##OtherFilters##", userConfig.GetText("workflow_filters") + ": " + otherFilter); + } + else if (ReportType.IsRulebaseReport()) + { + HtmlTemplate = HtmlTemplate.Replace("##OtherFilters##", userConfig.GetText("managements") + ": " + otherFilter); } else { - HtmlTemplate = HtmlTemplate.Replace("##Date-of-Config##", userConfig.GetText("date_of_config")); - HtmlTemplate = HtmlTemplate.Replace("##GeneratedFor##", DateTime.Parse(Query.ReportTimeString).ToUniversalTime().ToString("yyyy-MM-ddTHH:mm:ssK")); + HtmlTemplate = HtmlTemplate.Replace("##OtherFilters##", userConfig.GetText("devices") + ": " + otherFilter); } - HtmlTemplate = HtmlTemplate.Replace("##DeviceFilter##", string.Join("; ", Array.ConvertAll(Managements.Where(mgt => !mgt.Ignore).ToArray(), management => management.NameAndDeviceNames()))); - HtmlTemplate = HtmlTemplate.Replace("##Body##", htmlReport.ToString()); - htmlExport = HtmlTemplate.ToString(); } - return htmlExport; + else + { + HtmlTemplate = HtmlTemplate.Replace("

                      ##OtherFilters##

                      ", ""); + } } - public string DisplayReportHeaderCsv() + protected static string ToUtcString(string? timestring) { - StringBuilder report = new StringBuilder(); - report.AppendLine($"# report type: {userConfig.GetText(ReportType.ToString())}"); - report.AppendLine($"# report generation date: {DateTime.Now.ToUniversalTime().ToString("yyyy-MM-ddTHH:mm:ssK")} (UTC)"); - if(!ReportType.IsChangeReport()) - { - report.AppendLine($"# date of configuration shown: {DateTime.Parse(Query.ReportTimeString).ToUniversalTime().ToString("yyyy-MM-ddTHH:mm:ssK")} (UTC)"); - } - report.AppendLine($"# device filter: {string.Join(" ", Array.ConvertAll(Managements.Where(mgt => !mgt.Ignore).ToArray(), management => management.NameAndDeviceNames(" ")))}"); - report.AppendLine($"# other filters: {Query.RawFilter}"); - report.AppendLine($"# report generator: Firewall Orchestrator - https://fwo.cactus.de/en"); - report.AppendLine($"# data protection level: For internal use only"); - report.AppendLine($"#"); - return $"{report.ToString()}"; + try + { + return timestring != null ? DateTime.Parse(timestring).ToUniversalTime().ToString("yyyy-MM-ddTHH:mm:ssK") : ""; + } + catch (Exception) + { + return timestring ?? ""; + } } - public string DisplayReportHeaderJson() + private async Task CreatePDFViaPuppeteer(string html, PaperFormat format) { - StringBuilder report = new StringBuilder(); - report.AppendLine($"\"report type\": \"{userConfig.GetText(ReportType.ToString())}\","); - report.AppendLine($"\"report generation date\": \"{DateTime.Now.ToUniversalTime().ToString("yyyy-MM-ddTHH:mm:ssK")} (UTC)\","); - if(!ReportType.IsChangeReport()) - { - report.AppendLine($"\"date of configuration shown\": \"{DateTime.Parse(Query.ReportTimeString).ToUniversalTime().ToString("yyyy-MM-ddTHH:mm:ssK")} (UTC)\","); - } - report.AppendLine($"\"device filter\": \"{string.Join("; ", Array.ConvertAll(Managements, management => management.NameAndDeviceNames()))}\","); - report.AppendLine($"\"other filters\": \"{Query.RawFilter}\","); - report.AppendLine($"\"report generator\": \"Firewall Orchestrator - https://fwo.cactus.de/en\","); - report.AppendLine($"\"data protection level\": \"For internal use only\","); - return $"{report.ToString()}"; + OperatingSystem? os = Environment.OSVersion; + + string path = ""; + Platform platform = Platform.Unknown; + const SupportedBrowser wantedBrowser = SupportedBrowser.Chrome; + + switch (os.Platform) + { + case PlatformID.Win32NT: + platform = Platform.Win32; + break; + case PlatformID.Unix: + path = GlobalConst.ChromeBinPathLinux; + platform = Platform.Linux; + break; + default: + break; + } + + BrowserFetcher browserFetcher = new(new BrowserFetcherOptions() { Platform = platform, Browser = wantedBrowser, Path = path }); + + IEnumerable? allInstalledBrowsers = browserFetcher.GetInstalledBrowsers().Where(_ => _.Browser == wantedBrowser); + + if (!allInstalledBrowsers.Any()) + { + if (os.Platform == PlatformID.Win32NT) + { + Log.WriteInfo("Browser", $"Browser not found for Windows! Trying to download..."); + await browserFetcher.DownloadAsync(); + allInstalledBrowsers = browserFetcher.GetInstalledBrowsers().Where(_ => _.Browser == wantedBrowser); + } + else + { + throw new EnvironmentException($"Found no installed {wantedBrowser} instances!"); + } + } + + string? newestBuildId = allInstalledBrowsers.Max(_ => _.BuildId); + + if (string.IsNullOrWhiteSpace(newestBuildId)) + { + throw new EnvironmentException($"Invalid build ID!"); + } + + InstalledBrowser? latestInstalledBrowser = allInstalledBrowsers.Single(_ => _.BuildId == newestBuildId) ?? + throw new EnvironmentException($"Found no installed {wantedBrowser} instances with a valid build ID!"); + + Log.WriteInfo("Test Log", $"Selecting latest installed {wantedBrowser}({latestInstalledBrowser.BuildId}) at: {latestInstalledBrowser.GetExecutablePath()}"); + + IBrowser? browser; + + try + { + browser = await Puppeteer.LaunchAsync(new LaunchOptions + { + ExecutablePath = latestInstalledBrowser.GetExecutablePath(), + Headless = true, + }); + } + catch (Exception) + { + Log.WriteAlert("Test Log", $"Couldn't start {wantedBrowser} instance!"); + throw new EnvironmentException($"Couldn't start {wantedBrowser} instance!"); + } + + try + { + using IPage page = await browser.NewPageAsync(); + await page.SetContentAsync(html); + + PuppeteerSharp.Media.PaperFormat? pupformat = GetPuppeteerPaperFormat(format) ?? throw new KeyNotFoundException(); + + PdfOptions pdfOptions = new() { Outline = true, DisplayHeaderFooter = false, Landscape = true, PrintBackground = true, Format = pupformat, MarginOptions = new MarginOptions { Top = "1cm", Bottom = "1cm", Left = "1cm", Right = "1cm" } }; + byte[]? pdfData = await page.PdfDataAsync(pdfOptions); + + return Convert.ToBase64String(pdfData); + } + catch (Exception) + { + throw new NotSupportedException("This paper kind is currently not supported. Please choose another one or \"Custom\" for a custom size."); + } + finally + { + await browser.CloseAsync(); + browser.Dispose(); + } } - public virtual byte[] ToPdf(PaperKind paperKind, int width = -1, int height = -1) + public static List CreateTOCContent(string html) { - // HTML - if (string.IsNullOrEmpty(htmlExport)) - htmlExport = ExportToHtml(); + HtmlDocument doc = new(); + doc.LoadHtml(html); - GlobalSettings globalSettings = new GlobalSettings - { - ColorMode = ColorMode.Color, - Orientation = Orientation.Landscape, - }; + List? headings = [.. doc.DocumentNode.Descendants().Where(n => n.Name.StartsWith('h') && n.Name.Length == 2 && n.Name != "hr")]; + List tocs = []; - if (paperKind == PaperKind.Custom) + int i = 0; + + foreach (HtmlNode heading in headings) { - if (width > 0 && height > 0) + string headText = heading.InnerText.Trim(); + + if (heading.Name == "h4" && tocs.Count > 0) + { + tocs[i - 1].Items.Add(new ToCItem(headText, heading.Id)); + } + else if (heading.Name == "h5" && tocs.Count > 0 && tocs[i - 1].Items.Count > 0) + { + tocs[i - 1].Items[^1].SubItems.Add(new ToCItem(headText, heading.Id)); + } + else if (heading.Name == "h6" && tocs.Count > 0 && tocs[i - 1].Items.Count > 0 && tocs[i - 1].Items[^1].SubItems.Count > 0) { - globalSettings.PaperSize = new PechkinPaperSize(width + "mm", height + "mm"); + tocs[i - 1].Items[^1].SubItems[^1].SubItems.Add(new ToCItem(headText, heading.Id)); } else { - throw new Exception("Custom paper size: width or height <= 0"); + tocs.Add(new(headText, heading.Id)); + i++; } } - else + return tocs; + } + + public string BuildHTMLToC(string html) + { + bool tocTemplateValid = IsValidHTML(TocHTMLTemplate); + + if (!tocTemplateValid) + { + throw new ArgumentException(userConfig.GetText("E9302")); + } + + List? tocHeaders = CreateTOCContent(html); + if (tocHeaders.Count == 0) { - globalSettings.PaperSize = paperKind; + return ""; } - HtmlToPdfDocument doc = new HtmlToPdfDocument() + TocHTMLTemplate = TocHTMLTemplate.Replace("##ToCHeader##", userConfig.GetText("tableofcontent")); + + StringBuilder sb = new(); + foreach (ToCHeader toCHeader in tocHeaders) { - GlobalSettings = globalSettings, - Objects = + AppendHeader(sb, toCHeader); + } + + TocHTMLTemplate = TocHTMLTemplate.Replace("##ToCList##", sb.ToString()); + bool tocValidHTML = IsValidHTML(TocHTMLTemplate); + if (!tocValidHTML) + { + throw new ArgumentException(userConfig.GetText("E9302")); + } + + return TocHTMLTemplate; + } + + private static void AppendHeader(StringBuilder sb, ToCHeader toCHeader) + { + sb.AppendLine($"
                    • {toCHeader.Title}
                    • "); + + if (toCHeader.Items.Count > 0) + { + sb.AppendLine("
                        "); + + foreach (ToCItem tocItem in toCHeader.Items) { - new ObjectSettings() - { - PagesCount = true, - HtmlContent = htmlExport, - WebSettings = { DefaultEncoding = "utf-8" }, - HeaderSettings = { FontSize = 9, Right = "Page [page] of [toPage]", Line = true, Spacing = 2.812 } - } + AppendItem(sb, tocItem); } - }; + sb.AppendLine("
                      "); + } + } - return converter.Convert(doc); + private static void AppendItem(StringBuilder sb, ToCItem tocItem) + { + sb.AppendLine($"
                    • {tocItem.Title}
                    • "); + if (tocItem.SubItems.Count > 0) + { + sb.AppendLine("
                        "); + foreach (ToCItem subItem in tocItem.SubItems) + { + AppendSubItem(sb, subItem); + } + sb.AppendLine("
                      "); + } } - public static ReportBase ConstructReport(ReportTemplate reportFilter, UserConfig userConfig) + private static void AppendSubItem(StringBuilder sb, ToCItem subItem) { - DynGraphqlQuery query = Compiler.Compile(reportFilter); - ReportType repType = (ReportType) (reportFilter.ReportParams.ReportType ?? throw new NotSupportedException("Report Type is not set.")); - return repType switch + sb.AppendLine($"
                    • {subItem.Title}
                    • "); + if (subItem.SubItems.Count > 0) { - ReportType.Statistics => new ReportStatistics(query, userConfig, repType), - ReportType.Rules => new ReportRules(query, userConfig, repType), - ReportType.ResolvedRules => new ReportRules(query, userConfig, repType), - ReportType.ResolvedRulesTech => new ReportRules(query, userConfig, repType), - ReportType.Changes => new ReportChanges(query, userConfig, repType), - ReportType.ResolvedChanges => new ReportChanges(query, userConfig, repType), - ReportType.ResolvedChangesTech => new ReportChanges(query, userConfig, repType), - ReportType.NatRules => new ReportNatRules(query, userConfig, repType), - ReportType.Recertification => new ReportRules(query, userConfig, repType), - ReportType.UnusedRules => new ReportRules(query, userConfig, repType), - _ => throw new NotSupportedException("Report Type is not supported."), - }; + sb.AppendLine("
                        "); + foreach (ToCItem subsubItem in subItem.SubItems) + { + sb.AppendLine($"
                      • {subsubItem.Title}
                      • "); + } + sb.AppendLine("
                      "); + } } - public async Task getRelevantImportIds(ApiConnection apiConnection) + protected string Headline(string? title, int level) { - Dictionary ImpIdQueryVariables = new Dictionary(); - ImpIdQueryVariables["time"] = (Query.ReportTimeString != "" ? Query.ReportTimeString : DateTime.Now.ToString(DynGraphqlQuery.fullTimeFormat)); - ImpIdQueryVariables["mgmIds"] = Query.RelevantManagementIds; - return await apiConnection.SendQueryAsync(ReportQueries.getRelevantImportIdsAtTime, ImpIdQueryVariables); + return $"{title}"; } - public static string GetIconClass(ObjCategory? objCategory, string? objType) + public static bool IsValidHTML(string html) { - switch (objType) - { - case "group" when objCategory == ObjCategory.user: - return "oi oi-people"; - case "group": - return "oi oi-list-rich"; - case "host": - return "oi oi-laptop"; - case "network": - return "oi oi-rss"; - case "ip_range": - return "oi oi-resize-width"; - default: - switch (objCategory) - { - case ObjCategory.nobj: - return "oi oi-laptop"; - case ObjCategory.nsrv: - return "oi oi-wrench"; - case ObjCategory.user: - return "oi oi-person"; - } - return ""; + try + { + HtmlDocument? doc = new(); + doc.LoadHtml(html); + return !doc.ParseErrors.Any(); } + catch (Exception) + { + return false; + } + + } + + public PuppeteerSharp.Media.PaperFormat? GetPuppeteerPaperFormat(PaperFormat format) + { + if (format == PaperFormat.Custom) + return new PuppeteerSharp.Media.PaperFormat(CustomWidth, CustomHeight); + + PropertyInfo[] propertyInfos = typeof(PuppeteerSharp.Media.PaperFormat).GetProperties(BindingFlags.Public | BindingFlags.Static | BindingFlags.Instance | BindingFlags.NonPublic); + + PropertyInfo? prop = propertyInfos.SingleOrDefault(_ => _.Name == format.ToString()); + + if (prop == null) + return default; + + PuppeteerSharp.Media.PaperFormat? propFormat = (PuppeteerSharp.Media.PaperFormat?)prop.GetValue(null); + + if (propFormat is null) + return default; + + return propFormat; + } + + public virtual async Task ToPdf(string html, PaperFormat format) + { + return await CreatePDFViaPuppeteer(html, format); + } + + public virtual async Task ToPdf(string html) + { + return await CreatePDFViaPuppeteer(html, PaperFormat.A4); + } + + public virtual async Task ToPdf(PaperFormat format) + { + return await CreatePDFViaPuppeteer(htmlExport, format); + } + + public static string GetIconClass(ObjCategory? objCategory, string? objType) + { + return objType switch + { + ObjectType.Group when objCategory == ObjCategory.user => Icons.UserGroup, + ObjectType.Group => Icons.ObjGroup, + ObjectType.Host => Icons.Host, + ObjectType.Network => Icons.Network, + ObjectType.IPRange => Icons.Range, + ObjectType.AccessRole => Icons.User, + _ => objCategory switch + { + ObjCategory.nobj => Icons.NwObject, + ObjCategory.nsrv => Icons.Service, + ObjCategory.user => Icons.User, + _ => "", + }, + }; } } } diff --git a/roles/lib/files/FWO.Report/ReportChanges.cs b/roles/lib/files/FWO.Report/ReportChanges.cs index 86cffda2c0..39d769cba3 100644 --- a/roles/lib/files/FWO.Report/ReportChanges.cs +++ b/roles/lib/files/FWO.Report/ReportChanges.cs @@ -1,53 +1,142 @@ -using FWO.Api.Data; -using System.Text; using FWO.Api.Client; -using FWO.Report.Filter; -using FWO.Ui.Display; +using FWO.Api.Client.Queries; +using FWO.Basics; using FWO.Config.Api; +using FWO.Config.Api.Data; +using FWO.Data; +using FWO.Data.Report; using FWO.Logging; -using System.Text.Json; +using FWO.Report.Filter; +using FWO.Ui.Display; using Newtonsoft.Json; +using Org.BouncyCastle.Crypto; +using System.Text; +using System.Text.Json; +using System.Xml.Linq; + namespace FWO.Report { - public class ReportChanges : ReportBase + public class ReportChanges : ReportDevicesBase { - private const int ColumnCount = 13; + private const int ColumnCount = 14; - public ReportChanges(DynGraphqlQuery query, UserConfig userConfig, ReportType reportType) : base(query, userConfig, reportType) { } + private readonly TimeFilter timeFilter; + private readonly bool IncludeObjects; - public override async Task GetObjectsInReport(int objectsPerFetch, ApiConnection apiConnection, Func callback) + public ReportChanges(DynGraphqlQuery query, UserConfig userConfig, ReportType reportType, TimeFilter timeFilter, bool includeObjects) : base(query, userConfig, reportType) { - await callback(Managements); - // currently no further objects to be fetched - GotObjectsInReport = true; - return true; + this.timeFilter = timeFilter; + IncludeObjects = includeObjects; } - public override Task GetObjectsForManagementInReport(Dictionary objQueryVariables, ObjCategory objects, int maxFetchCycles, ApiConnection apiConnection, Func callback) + public override async Task Generate(int elementsPerFetch, ApiConnection apiConnection, Func callback, CancellationToken ct) { - throw new NotImplementedException(); + Query.QueryVariables[QueryVar.Limit] = elementsPerFetch; + Query.QueryVariables[QueryVar.Offset] = 0; + + (string startTime, string stopTime) = DynGraphqlQuery.ResolveTimeRange(timeFilter); + Dictionary> managementImportIds = []; + int queriesNeeded = 0; + + queriesNeeded += await FetchInitialManagementData(apiConnection, startTime, stopTime, managementImportIds); + + queriesNeeded += await FetchAdditionalChanges(apiConnection, managementImportIds, elementsPerFetch, callback, queriesNeeded, ct); + + Log.WriteDebug("Generate Changes Report", $"Finished generating changes report with {queriesNeeded} queries."); } - public override async Task Generate(int changesPerFetch, ApiConnection apiConnection, Func callback, CancellationToken ct) + private async Task FetchInitialManagementData(ApiConnection apiConnection, string startTime, string stopTime, Dictionary> managementImportIds) { - Query.QueryVariables["limit"] = changesPerFetch; - Query.QueryVariables["offset"] = 0; - bool gotNewObjects = true; - Managements = Array.Empty(); + int queriesNeeded = 0; + List managementsWithRelevantImportId = await GetRelevantImportIds(apiConnection, startTime); + List managementsWithImportIds = await GetImportIdsInTimeRange(apiConnection, startTime, stopTime, ruleChangeRequired: true, IncludeObjects); + foreach (var management in managementsWithRelevantImportId) + { + List importIdLastBeforeRange = [management.RelevantImportId ?? -1]; + List importIdsInRange = [.. managementsWithImportIds.Where(m => m.Id == management.Id).SelectMany(m => m.ImportControls).Select(ic => ic.ControlId).DefaultIfEmpty(0)]; + List relevantImportIds = [.. importIdLastBeforeRange, .. importIdsInRange]; + + SetMgtQueryVars(management.Id, relevantImportIds[0], relevantImportIds[1], IncludeObjects); + ManagementReport managementReport = (await apiConnection.SendQueryAsync>(Query.FullQuery, Query.QueryVariables)).First(); + + queriesNeeded += 1; + ReportData.ManagementData.Add(managementReport); + managementImportIds.Add(management.Id, relevantImportIds); + } + return queriesNeeded; + } + + private async Task FetchAdditionalChanges(ApiConnection apiConnection, Dictionary> managementImportIds, int elementsPerFetch, + Func callback, int queriesNeeded, CancellationToken ct) + { + Query.QueryVariables[QueryVar.Offset] = elementsPerFetch; + int maxImports = managementImportIds.Values.Select(v => v.Count).Max(); + + if (maxImports <= 2) // Case last two (changes report - notification mail) + { + return queriesNeeded; + } + + for (int i = 1; i < maxImports; i++) + { + bool continueFetching = true; + while (continueFetching) + { + if (ct.IsCancellationRequested) + { + Log.WriteDebug("Generate Changes Report", "Task cancelled"); + ct.ThrowIfCancellationRequested(); + } + + (bool anyContinue, int queries) = await ProcessManagementsForAdditionalChanges(apiConnection, managementImportIds, i, elementsPerFetch); + queriesNeeded += queries; + continueFetching = anyContinue; - Managements = await apiConnection.SendQueryAsync(Query.FullQuery, Query.QueryVariables); + await callback(ReportData); + Query.QueryVariables[QueryVar.Offset] = (int)Query.QueryVariables[QueryVar.Offset] + elementsPerFetch; + } + Query.QueryVariables[QueryVar.Offset] = 0; + } + return queriesNeeded; + } - while (gotNewObjects) + private async Task<(bool anyContinue, int queries)> ProcessManagementsForAdditionalChanges(ApiConnection apiConnection, Dictionary> managementImportIds, int i, int elementsPerFetch) + { + bool anyContinue = false; + int queries = 0; + + foreach (var management in ReportData.ManagementData) { - if (ct.IsCancellationRequested) + if (managementImportIds.ContainsKey(management.Id) && managementImportIds[management.Id].Count > i) // Null check { - Log.WriteDebug("Generate Changes Report", "Task cancelled"); - ct.ThrowIfCancellationRequested(); + long importIdOld = managementImportIds[management.Id][i - 1]; + long importIdNew = managementImportIds[management.Id][i]; + SetMgtQueryVars(management.Id, importIdOld, importIdNew, IncludeObjects); + + ManagementReport newData = (await apiConnection.SendQueryAsync>(Query.FullQuery, Query.QueryVariables)).First(); // Error + (bool newObjects, Dictionary maxAddedCounts) = management.Merge(newData); + queries++; + + if (newObjects && maxAddedCounts.Values.Any(v => v >= elementsPerFetch)) + { + anyContinue = true; + } } - Query.QueryVariables["offset"] = (int)Query.QueryVariables["offset"] + changesPerFetch; - gotNewObjects = Managements.Merge(await apiConnection.SendQueryAsync(Query.FullQuery, Query.QueryVariables)); - await callback(Managements); } + return (anyContinue, queries); + } + + private void SetMgtQueryVars(int mgmId, long importIdOld, long importIdNew, bool includeObjectsInChangesReport) + { + Query.QueryVariables[QueryVar.MgmId] = mgmId; + Query.QueryVariables[QueryVar.ImportIdOld] = importIdOld; + Query.QueryVariables[QueryVar.ImportIdNew] = importIdNew; + Query.QueryVariables[QueryVar.IncludeObjectsInChangesReport] = includeObjectsInChangesReport; + } + + public override Task GetObjectsForManagementInReport(Dictionary objQueryVariables, ObjCategory objects, int maxFetchCycles, ApiConnection apiConnection, Func callback) + { + throw new NotImplementedException(); } public override string SetDescription() @@ -55,11 +144,11 @@ public override string SetDescription() int managementCounter = 0; int deviceCounter = 0; int ruleChangeCounter = 0; - foreach (Management management in Managements.Where(mgt => !mgt.Ignore && mgt.Devices != null && + foreach (var management in ReportData.ManagementData.Where(mgt => !mgt.Ignore && mgt.Devices != null && Array.Exists(mgt.Devices, device => device.RuleChanges != null && device.RuleChanges.Length > 0))) { managementCounter++; - foreach (Device device in management.Devices.Where(dev => dev.RuleChanges != null && dev.RuleChanges.Length > 0)) + foreach (var device in management.Devices.Where(dev => dev.RuleChanges != null && dev.RuleChanges.Length > 0)) { deviceCounter++; ruleChangeCounter += device.RuleChanges!.Length; @@ -72,40 +161,32 @@ public override string ExportToCsv() { if (ReportType.IsResolvedReport()) { - StringBuilder report = new StringBuilder(); - RuleChangeDisplayCsv ruleChangeDisplayCsv = new RuleChangeDisplayCsv(userConfig); + StringBuilder report = new(); + RuleChangeDisplayCsv ruleChangeDisplayCsv = new(userConfig); report.Append(DisplayReportHeaderCsv()); - report.AppendLine($"\"management-name\",\"device-name\",\"change-time\",\"change-type\",\"rule-name\",\"source-zone\",\"source\",\"destination-zone\",\"destination\",\"service\",\"action\",\"track\",\"rule-enabled\",\"rule-uid\",\"rule-comment\""); + report.AppendLine("\"Rules\""); + report.AppendLine($"\"management-name\",\"change-time\",\"change-type\",\"rule-name\",\"source-zone\",\"source\",\"destination-zone\",\"destination\",\"service\",\"action\",\"track\",\"rule-enabled\",\"enforcing_device\",\"rule-uid\",\"rule-comment\""); - foreach (Management management in Managements.Where(mgt => !mgt.Ignore && mgt.Devices != null && - Array.Exists(mgt.Devices, device => device.RuleChanges != null && device.RuleChanges.Length > 0))) + foreach (var management in ReportData.ManagementData.Where(mgt => !mgt.Ignore)) { - foreach (Device gateway in management.Devices) + AppendRuleChangeRowsCSV(report, management, ruleChangeDisplayCsv); + + if (IncludeObjects) { - if (gateway.RuleChanges != null && gateway.RuleChanges.Length > 0) - { - foreach (RuleChange ruleChange in gateway.RuleChanges) - { - report.Append(ruleChangeDisplayCsv.OutputCsv(management.Name)); - report.Append(ruleChangeDisplayCsv.OutputCsv(gateway.Name)); - report.Append(ruleChangeDisplayCsv.DisplayChangeTime(ruleChange)); - report.Append(ruleChangeDisplayCsv.DisplayChangeAction(ruleChange)); - report.Append(ruleChangeDisplayCsv.DisplayName(ruleChange)); - report.Append(ruleChangeDisplayCsv.DisplaySourceZone(ruleChange)); - report.Append(ruleChangeDisplayCsv.DisplaySource(ruleChange, ReportType)); - report.Append(ruleChangeDisplayCsv.DisplayDestinationZone(ruleChange)); - report.Append(ruleChangeDisplayCsv.DisplayDestination(ruleChange, ReportType)); - report.Append(ruleChangeDisplayCsv.DisplayServices(ruleChange, ReportType)); - report.Append(ruleChangeDisplayCsv.DisplayAction(ruleChange)); - report.Append(ruleChangeDisplayCsv.DisplayTrack(ruleChange)); - report.Append(ruleChangeDisplayCsv.DisplayEnabled(ruleChange)); - report.Append(ruleChangeDisplayCsv.DisplayUid(ruleChange)); - report.Append(ruleChangeDisplayCsv.DisplayComment(ruleChange)); - report = ruleChangeDisplayCsv.RemoveLastChars(report, 1); // remove last chars (comma) - report.AppendLine(""); - } - } + report.AppendLine($"#"); + report.AppendLine("\"Network objects\""); + report.AppendLine($"\"management-name\",\"change-time\",\"change-type\",\"object-name\",\"type\",\"ip_address\",\"members\",\"object-uid\",\"object-comment\""); + + AppendObjectChangeRowsCSV(report, management, ruleChangeDisplayCsv); + + report.AppendLine($"#"); + report.AppendLine("\"Service objects\""); + report.AppendLine($"\"management-name\",\"change-time\",\"change-type\",\"service-name\",\"type\",\"protocol\",\"port\",\"members\",\"service-uid\",\"service-comment\""); + + AppendServiceChangeRowsCSV(report, management, ruleChangeDisplayCsv); + + AppendUserChangeRowsCSV(report, management, ruleChangeDisplayCsv); } } return report.ToString(); @@ -116,84 +197,302 @@ public override string ExportToCsv() } } + private void AppendRuleChangeRowsCSV(StringBuilder report, ManagementReport management, RuleChangeDisplayCsv ruleChangeDisplayCsv) + { + if (management.RuleChanges != null && management.RuleChanges?.Any() == true) + { + foreach (var ruleChange in management.RuleChanges) + { + report.Append(ruleChangeDisplayCsv.OutputCsv(management.Name)); + report.Append(ruleChangeDisplayCsv.DisplayChangeTime(ruleChange)); + report.Append(ruleChangeDisplayCsv.DisplayChangeAction(ruleChange)); + report.Append(ruleChangeDisplayCsv.DisplayName(ruleChange)); + report.Append(ruleChangeDisplayCsv.DisplaySourceZone(ruleChange)); + report.Append(ruleChangeDisplayCsv.DisplaySource(ruleChange, ReportType)); + report.Append(ruleChangeDisplayCsv.DisplayDestinationZone(ruleChange)); + report.Append(ruleChangeDisplayCsv.DisplayDestination(ruleChange, ReportType)); + report.Append(ruleChangeDisplayCsv.DisplayServices(ruleChange, ReportType)); + report.Append(ruleChangeDisplayCsv.DisplayAction(ruleChange)); + report.Append(ruleChangeDisplayCsv.DisplayTrack(ruleChange)); + report.Append(ruleChangeDisplayCsv.DisplayEnabled(ruleChange)); + report.Append(ruleChangeDisplayCsv.DisplayenforcingDevice(ruleChange)); + report.Append(ruleChangeDisplayCsv.DisplayUid(ruleChange)); + report.Append(ruleChangeDisplayCsv.DisplayComment(ruleChange)); + report = RuleDisplayBase.RemoveLastChars(report, 1); // remove last chars (comma) + report.AppendLine(""); + } + } + } + + private static void AppendObjectChangeRowsCSV(StringBuilder report, ManagementReport management, RuleChangeDisplayCsv ruleChangeDisplayCsv) + { + if (management.ObjectChanges != null && management.ObjectChanges?.Any() == true) + { + foreach (var objectChange in management.ObjectChanges) + { + report.Append(ruleChangeDisplayCsv.OutputCsv(management.Name)); + report.Append(ruleChangeDisplayCsv.DisplayChangeTime(objectChange)); + report.Append(ruleChangeDisplayCsv.DisplayChangeAction(objectChange)); + report.Append(ruleChangeDisplayCsv.DisplayName(objectChange)); + report.Append(ruleChangeDisplayCsv.DisplayObjectType(objectChange)); + report.Append(ruleChangeDisplayCsv.DisplayObjectIp(objectChange)); + report.Append(ruleChangeDisplayCsv.DisplayObjectMemberNames(objectChange)); + report.Append(ruleChangeDisplayCsv.DisplayUid(objectChange)); + report.Append(ruleChangeDisplayCsv.DisplayComment(objectChange)); + report = RuleDisplayBase.RemoveLastChars(report, 1); // remove last chars (comma) + report.AppendLine(""); + } + } + } + + private static void AppendServiceChangeRowsCSV(StringBuilder report, ManagementReport management, RuleChangeDisplayCsv ruleChangeDisplayCsv) + { + if (management.ServiceChanges != null && management.ServiceChanges?.Any() == true) + { + foreach (var serviceChange in management.ServiceChanges) + { + report.Append(ruleChangeDisplayCsv.OutputCsv(management.Name)); + report.Append(ruleChangeDisplayCsv.DisplayChangeTime(serviceChange)); + report.Append(ruleChangeDisplayCsv.DisplayChangeAction(serviceChange)); + report.Append(ruleChangeDisplayCsv.DisplayName(serviceChange)); + report.Append(ruleChangeDisplayCsv.DisplayServiceType(serviceChange)); + report.Append(ruleChangeDisplayCsv.DisplayServiceProtocol(serviceChange)); + report.Append(ruleChangeDisplayCsv.DisplayServicePort(serviceChange)); + report.Append(ruleChangeDisplayCsv.DisplayServiceMemberNames(serviceChange)); + report.Append(ruleChangeDisplayCsv.DisplayUid(serviceChange)); + report.Append(ruleChangeDisplayCsv.DisplayComment(serviceChange)); + report = RuleDisplayBase.RemoveLastChars(report, 1); // remove last chars (comma) + report.AppendLine(""); + } + } + } + + private static void AppendUserChangeRowsCSV(StringBuilder report, ManagementReport management, RuleChangeDisplayCsv ruleChangeDisplayCsv) + { + if (management.UserChanges != null && management.UserChanges?.Any() == true) + { + report.AppendLine($"#"); + report.AppendLine("\"User objects\""); + report.AppendLine($"\"management-name\",\"change-time\",\"change-type\",\"user-name\",\"user-comment\""); + + foreach (var userChange in management.UserChanges) + { + report.Append(ruleChangeDisplayCsv.OutputCsv(management.Name)); + report.Append(ruleChangeDisplayCsv.DisplayChangeTime(userChange)); + report.Append(ruleChangeDisplayCsv.DisplayChangeAction(userChange)); + report.Append(ruleChangeDisplayCsv.DisplayName(userChange)); + report.Append(ruleChangeDisplayCsv.DisplayComment(userChange)); + report = RuleDisplayBase.RemoveLastChars(report, 1); // remove last chars (comma) + report.AppendLine(""); + } + } + } + public override string ExportToHtml() { - StringBuilder report = new StringBuilder(); - RuleChangeDisplayHtml ruleChangeDisplayHtml = new RuleChangeDisplayHtml(userConfig); + StringBuilder report = new(); + RuleChangeDisplayHtml ruleChangeDisplayHtml = new(userConfig); - foreach (Management management in Managements.Where(mgt => !mgt.Ignore && mgt.Devices != null && - Array.Exists(mgt.Devices, device => device.RuleChanges != null && device.RuleChanges.Length > 0))) + foreach (var management in ReportData.ManagementData.Where(mgt => !mgt.Ignore)) { - report.AppendLine($"

                      {management.Name}

                      "); + report.AppendLine($"

                      {management.Name}

                      "); report.AppendLine("
                      "); + report.AppendLine($"

                      Rules

                      "); + + report.AppendLine(""); + report.AppendLine(""); + report.AppendLine($""); + report.AppendLine($""); + report.AppendLine($""); + report.AppendLine($""); + report.AppendLine($""); + report.AppendLine($""); + report.AppendLine($""); + report.AppendLine($""); + report.AppendLine($""); + report.AppendLine($""); + report.AppendLine($""); + report.AppendLine($""); + report.AppendLine($""); + report.AppendLine($""); + report.AppendLine(""); - foreach (Device device in management.Devices) + + AppendRuleChangeRowsHTML(report, management, ruleChangeDisplayHtml); + + report.AppendLine("
                      {userConfig.GetText("change_time")}{userConfig.GetText("change_type")}{userConfig.GetText("name")}{userConfig.GetText("source_zone")}{userConfig.GetText("source")}{userConfig.GetText("destination_zone")}{userConfig.GetText("destination")}{userConfig.GetText("services")}{userConfig.GetText("action")}{userConfig.GetText("track")}{userConfig.GetText("enabled")}{userConfig.GetText("enforcing_devices")}{userConfig.GetText("uid")}{userConfig.GetText("comment")}
                      "); + report.AppendLine("
                      "); + + if (IncludeObjects) { - report.AppendLine($"

                      {device.Name}

                      "); + report.AppendLine($"

                      Network objects

                      "); + report.AppendLine(""); + report.AppendLine(""); + report.AppendLine($""); + report.AppendLine($""); + report.AppendLine($""); + report.AppendLine($""); + report.AppendLine($""); + report.AppendLine($""); + report.AppendLine($""); + report.AppendLine($""); + report.AppendLine(""); + + AppendObjectChangeRowsHTML(report, management, ruleChangeDisplayHtml); + + report.AppendLine("
                      {userConfig.GetText("change_time")}{userConfig.GetText("change_type")}{userConfig.GetText("name")}{userConfig.GetText("type")}{userConfig.GetText("ip_address")}{userConfig.GetText("members")}{userConfig.GetText("uid")}{userConfig.GetText("comment")}
                      "); report.AppendLine("
                      "); + report.AppendLine($"

                      Service objects

                      "); report.AppendLine(""); report.AppendLine(""); report.AppendLine($""); report.AppendLine($""); report.AppendLine($""); - report.AppendLine($""); - report.AppendLine($""); - report.AppendLine($""); - report.AppendLine($""); - report.AppendLine($""); - report.AppendLine($""); - report.AppendLine($""); - report.AppendLine($""); + report.AppendLine($""); + report.AppendLine($""); + report.AppendLine($""); + report.AppendLine($""); report.AppendLine($""); report.AppendLine($""); report.AppendLine(""); - if (device.RuleChanges != null) - { - foreach (RuleChange ruleChange in device.RuleChanges) - { - report.AppendLine(""); - report.AppendLine($""); - report.AppendLine($""); - report.AppendLine($""); - report.AppendLine($""); - report.AppendLine($""); - report.AppendLine($""); - report.AppendLine($""); - report.AppendLine($""); - report.AppendLine($""); - report.AppendLine($""); - report.AppendLine($""); - report.AppendLine($""); - report.AppendLine($""); - report.AppendLine(""); - } - } - else + AppendServiceChangeRowsHTML(report, management, ruleChangeDisplayHtml); + + report.AppendLine("
                      {userConfig.GetText("change_time")}{userConfig.GetText("change_type")}{userConfig.GetText("name")}{userConfig.GetText("source_zone")}{userConfig.GetText("source")}{userConfig.GetText("destination_zone")}{userConfig.GetText("destination")}{userConfig.GetText("services")}{userConfig.GetText("action")}{userConfig.GetText("track")}{userConfig.GetText("enabled")}{userConfig.GetText("type")}{userConfig.GetText("protocol")}{userConfig.GetText("port")}{userConfig.GetText("members")}{userConfig.GetText("uid")}{userConfig.GetText("comment")}
                      {ruleChangeDisplayHtml.DisplayChangeTime(ruleChange)}{ruleChangeDisplayHtml.DisplayChangeAction(ruleChange)}{ruleChangeDisplayHtml.DisplayName(ruleChange)}{ruleChangeDisplayHtml.DisplaySourceZone(ruleChange)}{ruleChangeDisplayHtml.DisplaySource(ruleChange, OutputLocation.export, ReportType)}{ruleChangeDisplayHtml.DisplayDestinationZone(ruleChange)}{ruleChangeDisplayHtml.DisplayDestination(ruleChange, OutputLocation.export, ReportType)}{ruleChangeDisplayHtml.DisplayServices(ruleChange, OutputLocation.export, ReportType)}{ruleChangeDisplayHtml.DisplayAction(ruleChange)}{ruleChangeDisplayHtml.DisplayTrack(ruleChange)}{ruleChangeDisplayHtml.DisplayEnabled(ruleChange, OutputLocation.export)}{ruleChangeDisplayHtml.DisplayUid(ruleChange)}{ruleChangeDisplayHtml.DisplayComment(ruleChange)}
                      "); + report.AppendLine("
                      "); + + AppendUserChangeRowsHTML(report, management, ruleChangeDisplayHtml); + } + } + + return GenerateHtmlFrame(userConfig.GetText(ReportType.ToString()), Query.RawFilter, DateTime.Now, report, timeFilter); + } + + private void AppendRuleChangeRowsHTML(StringBuilder report, ManagementReport management, RuleChangeDisplayHtml ruleChangeDisplayHtml) + { + if (management.RuleChanges != null && management.RuleChanges?.Any() == true) + { + foreach (var ruleChange in management.RuleChanges) + { + report.AppendLine(""); + report.AppendLine($"{ruleChangeDisplayHtml.DisplayChangeTime(ruleChange)}"); + report.AppendLine($"{ruleChangeDisplayHtml.DisplayChangeAction(ruleChange)}"); + report.AppendLine($"{ruleChangeDisplayHtml.DisplayName(ruleChange)}"); + report.AppendLine($"{ruleChangeDisplayHtml.DisplaySourceZone(ruleChange)}"); + report.AppendLine($"{ruleChangeDisplayHtml.DisplaySource(ruleChange, OutputLocation.export, ReportType)}"); + report.AppendLine($"{ruleChangeDisplayHtml.DisplayDestinationZone(ruleChange)}"); + report.AppendLine($"{ruleChangeDisplayHtml.DisplayDestination(ruleChange, OutputLocation.export, ReportType)}"); + report.AppendLine($"{ruleChangeDisplayHtml.DisplayServices(ruleChange, OutputLocation.export, ReportType)}"); + report.AppendLine($"{ruleChangeDisplayHtml.DisplayAction(ruleChange)}"); + report.AppendLine($"{ruleChangeDisplayHtml.DisplayTrack(ruleChange)}"); + report.AppendLine($"{ruleChangeDisplayHtml.DisplayEnabled(ruleChange, OutputLocation.export)}"); + report.AppendLine($"{ruleChangeDisplayHtml.DisplayEnforcingGateways(ruleChange, OutputLocation.export, ReportType)}"); + report.AppendLine($"{ruleChangeDisplayHtml.DisplayUid(ruleChange)}"); + report.AppendLine($"{ruleChangeDisplayHtml.DisplayComment(ruleChange)}"); + report.AppendLine(""); + } + } + else + { + report.AppendLine(""); + report.AppendLine($"{userConfig.GetText("no_changes_found")}"); + report.AppendLine(""); + } + } + private void AppendObjectChangeRowsHTML(StringBuilder report, ManagementReport management, RuleChangeDisplayHtml ruleChangeDisplayHtml) + { + if (management.ObjectChanges != null && management.ObjectChanges?.Any() == true) + { + foreach (var objectChange in management.ObjectChanges) + { + report.AppendLine(""); + report.AppendLine($"{ruleChangeDisplayHtml.DisplayChangeTime(objectChange)}"); + report.AppendLine($"{ruleChangeDisplayHtml.DisplayChangeAction(objectChange)}"); + report.AppendLine($"{ruleChangeDisplayHtml.DisplayName(objectChange)}"); + report.AppendLine($"{ruleChangeDisplayHtml.DisplayObjectType(objectChange)}"); + report.AppendLine($"{ruleChangeDisplayHtml.DisplayObjectIP(objectChange)}"); + report.AppendLine($"{ruleChangeDisplayHtml.DisplayObjectMemberNames(objectChange)}"); + report.AppendLine($"{ruleChangeDisplayHtml.DisplayUid(objectChange)}"); + report.AppendLine($"{ruleChangeDisplayHtml.DisplayComment(objectChange)}"); + report.AppendLine(""); + } + } + else + { + report.AppendLine(""); + report.AppendLine($"{userConfig.GetText("no_changes_found")}"); + report.AppendLine(""); + } + } + private void AppendServiceChangeRowsHTML(StringBuilder report, ManagementReport management, RuleChangeDisplayHtml ruleChangeDisplayHtml) + { + if (management.ServiceChanges != null && management.ServiceChanges?.Any() == true) + { + foreach (var serviceChange in management.ServiceChanges) + { + report.AppendLine(""); + report.AppendLine($"{ruleChangeDisplayHtml.DisplayChangeTime(serviceChange)}"); + report.AppendLine($"{ruleChangeDisplayHtml.DisplayChangeAction(serviceChange)}"); + report.AppendLine($"{ruleChangeDisplayHtml.DisplayName(serviceChange)}"); + report.AppendLine($"{ruleChangeDisplayHtml.DisplayServiceType(serviceChange)}"); + report.AppendLine($"{ruleChangeDisplayHtml.DisplayServiceProtocol(serviceChange)}"); + report.AppendLine($"{ruleChangeDisplayHtml.DisplayServicePort(serviceChange)}"); + report.AppendLine($"{ruleChangeDisplayHtml.DisplayServiceMemberNames(serviceChange)}"); + report.AppendLine($"{ruleChangeDisplayHtml.DisplayUid(serviceChange)}"); + report.AppendLine($"{ruleChangeDisplayHtml.DisplayComment(serviceChange)}"); + report.AppendLine(""); + } + } + else + { + report.AppendLine(""); + report.AppendLine($"{userConfig.GetText("no_changes_found")}"); + report.AppendLine(""); + } + } + private void AppendUserChangeRowsHTML(StringBuilder report, ManagementReport management, RuleChangeDisplayHtml ruleChangeDisplayHtml) + { + if (management.UserChanges != null && management.UserChanges?.Any() == true) + { + report.AppendLine($"

                      User objects

                      "); + report.AppendLine(""); + report.AppendLine(""); + report.AppendLine($""); + report.AppendLine($""); + report.AppendLine($""); + report.AppendLine($""); + report.AppendLine(""); + + if (management.UserChanges != null && management.UserChanges?.Any() == true) + { + foreach (var userChange in management.UserChanges) { report.AppendLine(""); - report.AppendLine($""); + report.AppendLine($""); + report.AppendLine($""); + report.AppendLine($""); + report.AppendLine($""); report.AppendLine(""); } - - report.AppendLine("
                      {userConfig.GetText("change_time")}{userConfig.GetText("change_type")}{userConfig.GetText("name")}{userConfig.GetText("comment")}
                      {userConfig.GetText("no_changes_found")}{ruleChangeDisplayHtml.DisplayChangeTime(userChange)}{ruleChangeDisplayHtml.DisplayChangeAction(userChange)}{ruleChangeDisplayHtml.DisplayName(userChange)}{ruleChangeDisplayHtml.DisplayComment(userChange)}
                      "); } + else + { + report.AppendLine(""); + report.AppendLine($"{userConfig.GetText("no_changes_found")}"); + report.AppendLine(""); + } + report.AppendLine(""); + report.AppendLine("
                      "); } - - return GenerateHtmlFrame(userConfig.GetText(ReportType.ToString()), Query.RawFilter, DateTime.Now, report); } public override string ExportToJson() { - if (ReportType.IsResolvedReport()) + if (ReportType.IsResolvedReport() || ReportType.IsChangeReport()) { return ExportResolvedChangesToJson(); } - else if (ReportType.IsChangeReport()) - { - return System.Text.Json.JsonSerializer.Serialize(Managements.Where(mgt => !mgt.Ignore), new JsonSerializerOptions { WriteIndented = true }); - } else { return ""; @@ -202,61 +501,160 @@ public override string ExportToJson() private string ExportResolvedChangesToJson() { - StringBuilder report = new StringBuilder("{"); + RuleChangeDisplayJson ruleChangeDisplayJson = new(userConfig); + StringBuilder report = new("{"); report.Append(DisplayReportHeaderJson()); report.AppendLine("\"managements\": ["); - RuleChangeDisplayJson ruleChangeDisplayJson = new RuleChangeDisplayJson(userConfig); - foreach (Management management in Managements.Where(mgt => !mgt.Ignore && mgt.Devices != null && - Array.Exists(mgt.Devices, device => device.RuleChanges != null && device.RuleChanges.Length > 0))) + + + foreach (var management in ReportData.ManagementData.Where(mgt => !mgt.Ignore)) + { + report.AppendLine($"{{\"{management.Name}\":"); + + report.Append($"{{\n\"rule changes\": ["); + AppendRuleChangeRowsJson(report, management, ruleChangeDisplayJson); + report.Append("],"); + + + if (IncludeObjects) + { + AppendObjectChangeRowsJson(report, management, ruleChangeDisplayJson); + + AppendServiceChangeRowsJson(report, management, ruleChangeDisplayJson); + + AppendUserChangeRowsJson(report, management, ruleChangeDisplayJson); + + } + report.Append("}},"); + } + + RuleDisplayBase.RemoveLastChars(report, 1); // letztes Komma bei Managements entfernen + report.Append("]}"); + + dynamic? json = JsonConvert.DeserializeObject(report.ToString()); + return JsonConvert.SerializeObject(json, new JsonSerializerSettings { - report.AppendLine($"{{\"{management.Name}\": {{"); - report.AppendLine($"\"gateways\": ["); - foreach (Device gateway in management.Devices) + Formatting = Formatting.Indented + }); + } + + private void AppendRuleChangeRowsJson(StringBuilder report, ManagementReport management, RuleChangeDisplayJson ruleChangeDisplayJson) + { + if (management.RuleChanges != null && management.RuleChanges?.Any() == true) + { + var items = management.RuleChanges!.ToList(); + + foreach (var ruleChange in items) { - if (gateway.RuleChanges != null && gateway.RuleChanges.Length > 0) + var sb = new StringBuilder("{"); + sb.Append(ruleChangeDisplayJson.DisplayChangeTime(ruleChange)); + sb.Append(ruleChangeDisplayJson.DisplayChangeAction(ruleChange)); + sb.Append(ruleChangeDisplayJson.DisplayName(ruleChange)); + sb.Append(ruleChangeDisplayJson.DisplaySourceZones(ruleChange)); + sb.Append(ruleChangeDisplayJson.DisplaySourceNegated(ruleChange)); + sb.Append(ruleChangeDisplayJson.DisplaySource(ruleChange, ReportType)); + sb.Append(ruleChangeDisplayJson.DisplayDestinationZones(ruleChange)); + sb.Append(ruleChangeDisplayJson.DisplayDestinationNegated(ruleChange)); + sb.Append(ruleChangeDisplayJson.DisplayDestination(ruleChange, ReportType)); + sb.Append(ruleChangeDisplayJson.DisplayServiceNegated(ruleChange)); + sb.Append(ruleChangeDisplayJson.DisplayServices(ruleChange, ReportType)); + sb.Append(ruleChangeDisplayJson.DisplayAction(ruleChange)); + sb.Append(ruleChangeDisplayJson.DisplayTrack(ruleChange)); + sb.Append(ruleChangeDisplayJson.DisplayEnabled(ruleChange)); + sb.Append(ruleChangeDisplayJson.DisplayEnforcingGateways(ruleChange)); + sb.Append(ruleChangeDisplayJson.DisplayUid(ruleChange)); + sb.Append(ruleChangeDisplayJson.DisplayComment(ruleChange)); + RuleDisplayBase.RemoveLastChars(sb, 1); // letztes Komma entfernen + sb.Append("},"); + report.Append(sb.ToString()); + } + RuleDisplayBase.RemoveLastChars(report, 1); // letztes Komma bei Items entfernen + + } + } + private static void AppendObjectChangeRowsJson(StringBuilder report, ManagementReport management, RuleChangeDisplayJson ruleChangeDisplayJson) + { + if (management.ObjectChanges != null && management.ObjectChanges?.Any() == true) + { + report.Append($"\n\"Network Object changes\": ["); + + var nwos = management.ObjectChanges!.ToList(); + if (nwos.Any()) + { + foreach (var objectChange in nwos) { - report.Append($"{{\"{gateway.Name}\": {{\n\"rule changes\": ["); - foreach (RuleChange ruleChange in gateway.RuleChanges) - { - report.Append("{"); - report.Append(ruleChangeDisplayJson.DisplayChangeTime(ruleChange)); - report.Append(ruleChangeDisplayJson.DisplayChangeAction(ruleChange)); - report.Append(ruleChangeDisplayJson.DisplayName(ruleChange)); - report.Append(ruleChangeDisplayJson.DisplaySourceZone(ruleChange)); - report.Append(ruleChangeDisplayJson.DisplaySourceNegated(ruleChange)); - report.Append(ruleChangeDisplayJson.DisplaySource(ruleChange, ReportType)); - report.Append(ruleChangeDisplayJson.DisplayDestinationZone(ruleChange)); - report.Append(ruleChangeDisplayJson.DisplayDestinationNegated(ruleChange)); - report.Append(ruleChangeDisplayJson.DisplayDestination(ruleChange, ReportType)); - report.Append(ruleChangeDisplayJson.DisplayServiceNegated(ruleChange)); - report.Append(ruleChangeDisplayJson.DisplayServices(ruleChange, ReportType)); - report.Append(ruleChangeDisplayJson.DisplayAction(ruleChange)); - report.Append(ruleChangeDisplayJson.DisplayTrack(ruleChange)); - report.Append(ruleChangeDisplayJson.DisplayEnabled(ruleChange)); - report.Append(ruleChangeDisplayJson.DisplayUid(ruleChange)); - report.Append(ruleChangeDisplayJson.DisplayComment(ruleChange)); - report = ruleChangeDisplayJson.RemoveLastChars(report, 1); // remove last chars (comma) - report.Append("},"); // EO ruleChange - } // rules - report = ruleChangeDisplayJson.RemoveLastChars(report, 1); // remove last char (comma) - report.Append("]"); // EO rules - report.Append("}"); // EO gateway internal - report.Append("},"); // EO gateway external + var sb = new StringBuilder("{"); + sb.Append(ruleChangeDisplayJson.DisplayChangeTime(objectChange)); + sb.Append(ruleChangeDisplayJson.DisplayChangeAction(objectChange)); + sb.Append(ruleChangeDisplayJson.DisplayName(objectChange)); + sb.Append(ruleChangeDisplayJson.DisplayObjectType(objectChange)); + sb.Append(ruleChangeDisplayJson.DisplayObjectIP(objectChange)); + sb.Append(ruleChangeDisplayJson.DisplayObjectMemberNames(objectChange)); + sb.Append(ruleChangeDisplayJson.DisplayUid(objectChange)); + sb.Append(ruleChangeDisplayJson.DisplayComment(objectChange)); + RuleDisplayBase.RemoveLastChars(sb, 1); // letztes Komma entfernen + sb.Append("},"); + report.Append(sb.ToString()); } - } // gateways - report = ruleChangeDisplayJson.RemoveLastChars(report, 1); // remove last char (comma) - report.Append("]"); // EO gateways - report.Append("}"); // EO management internal - report.Append("},"); // EO management external - } // managements - report = ruleChangeDisplayJson.RemoveLastChars(report, 1); // remove last char (comma) - report.Append("]"); // EO managements - report.Append("}"); // EO top + RuleDisplayBase.RemoveLastChars(report, 1); // letztes Komma bei Items entfernen + } + report.Append("],"); + } + } + private static void AppendServiceChangeRowsJson(StringBuilder report, ManagementReport management, RuleChangeDisplayJson ruleChangeDisplayJson) + { + if (management.ServiceChanges != null && management.ServiceChanges?.Any() == true) + { + report.Append($"\n\"Service Object changes\": ["); - dynamic? json = JsonConvert.DeserializeObject(report.ToString()); - JsonSerializerSettings settings = new JsonSerializerSettings(); - settings.Formatting = Formatting.Indented; - return Newtonsoft.Json.JsonConvert.SerializeObject(json, settings); + var svcs = management.ServiceChanges!.ToList(); + if (svcs.Any()) + { + foreach (var serviceChange in svcs) + { + var sb = new StringBuilder("{"); + sb.Append(ruleChangeDisplayJson.DisplayChangeTime(serviceChange)); + sb.Append(ruleChangeDisplayJson.DisplayChangeAction(serviceChange)); + sb.Append(ruleChangeDisplayJson.DisplayName(serviceChange)); + sb.Append(ruleChangeDisplayJson.DisplayObjectType(serviceChange)); + sb.Append(ruleChangeDisplayJson.DisplayServiceProtocol(serviceChange)); + sb.Append(ruleChangeDisplayJson.DisplayServicePort(serviceChange)); + sb.Append(ruleChangeDisplayJson.DisplayObjectMemberNames(serviceChange)); + sb.Append(ruleChangeDisplayJson.DisplayUid(serviceChange)); + sb.Append(ruleChangeDisplayJson.DisplayComment(serviceChange)); + RuleDisplayBase.RemoveLastChars(sb, 1); // letztes Komma entfernen + sb.Append("},"); + report.Append(sb.ToString()); + } + RuleDisplayBase.RemoveLastChars(report, 1); // letztes Komma bei Items entfernen + } + report.Append("]"); + } + } + private static void AppendUserChangeRowsJson(StringBuilder report, ManagementReport management, RuleChangeDisplayJson ruleChangeDisplayJson) + { + if (management.UserChanges != null && management.UserChanges?.Any() == true) + { + report.Append($"\n\"User Object changes\": ["); + + var userc = management.UserChanges!.ToList(); + if (userc.Any()) + { + foreach (var serviceChange in userc) + { + var sb = new StringBuilder("{"); + sb.Append(ruleChangeDisplayJson.DisplayChangeTime(serviceChange)); + sb.Append(ruleChangeDisplayJson.DisplayChangeAction(serviceChange)); + sb.Append(ruleChangeDisplayJson.DisplayName(serviceChange)); + sb.Append(ruleChangeDisplayJson.DisplayComment(serviceChange)); + RuleDisplayBase.RemoveLastChars(sb, 1); // letztes Komma entfernen + sb.Append("},"); + report.Append(sb.ToString()); + } + RuleDisplayBase.RemoveLastChars(report, 1); // letztes Komma bei Items entfernen + } + report.Append("],"); + } } } } diff --git a/roles/lib/files/FWO.Report/ReportCompliance.cs b/roles/lib/files/FWO.Report/ReportCompliance.cs new file mode 100644 index 0000000000..f66025c3c0 --- /dev/null +++ b/roles/lib/files/FWO.Report/ReportCompliance.cs @@ -0,0 +1,628 @@ +using FWO.Api.Client; +using FWO.Api.Client.Queries; +using FWO.Basics; +using FWO.Config.Api; +using FWO.Data; +using FWO.Data.Middleware; +using FWO.Data.Report; +using FWO.Logging; +using FWO.Report.Data.ViewData; +using FWO.Report.Filter; +using FWO.Ui.Display; +using System.Collections.Generic; +using System.Reflection; +using System.Text; +using System.Text.Json; + +namespace FWO.Report +{ + public class ReportCompliance : ReportBase + { + + #region Properties + + public List Rules { get; set; } = []; + public List RuleViewData = []; + public List Violations { get; set; } = []; + public bool ShowNonImpactRules { get; set; } + public List Managements { get; set; } = []; + protected virtual string InternalQuery => RuleQueries.getRulesWithCurrentViolationsByChunk; + protected DebugConfig DebugConfig; + protected readonly GlobalConfig GlobalConfig; + + #endregion + + #region Fields + + private List? _devices; + private readonly int _maxDegreeOfParallelism; + private readonly SemaphoreSlim _semaphore; + private readonly NatRuleDisplayHtml _natRuleDisplayHtml; + private List _columnsToExport = []; + private bool _includeHeaderInExport; + private char _separator; + private int _maxCellSize; + private readonly int _maxPrintedViolations; + private readonly List _relevanteManagementIDs = new(); + + #endregion + + #region Constructors + + public ReportCompliance(DynGraphqlQuery query, UserConfig userConfig, ReportType reportType) : base(query, userConfig, reportType) + { + // Getting config values. + + if (userConfig.GlobalConfig != null) + { + GlobalConfig = userConfig.GlobalConfig; + } + else + { + GlobalConfig = new(); + } + + _maxDegreeOfParallelism = GlobalConfig.ComplianceCheckAvailableProcessors > Environment.ProcessorCount ? Environment.ProcessorCount : GlobalConfig.ComplianceCheckAvailableProcessors; + _semaphore = new SemaphoreSlim(_maxDegreeOfParallelism); + _natRuleDisplayHtml = new NatRuleDisplayHtml(userConfig); + + // CSV export config. + + SetUpCsvExport(); + + _maxPrintedViolations = GlobalConfig.ComplianceCheckMaxPrintedViolations; + + // Apply debug config. + + if (!string.IsNullOrEmpty(GlobalConfig.DebugConfig)) + { + DebugConfig = JsonSerializer.Deserialize(GlobalConfig.DebugConfig) ?? new(); + } + else + { + Log.WriteWarning("Compliance Report", "No debug config found, using default values."); + DebugConfig = new(); + } + + if (!string.IsNullOrEmpty(GlobalConfig.ComplianceCheckRelevantManagements)) + { + try + { + _relevanteManagementIDs = GlobalConfig.ComplianceCheckRelevantManagements + .Split(',', StringSplitOptions.RemoveEmptyEntries) + .Select(s => int.Parse(s.Trim())) + .ToList(); + } + catch (Exception e) + { + Log.TryWriteLog(LogType.Error, "Compliance Report", $"Error while parsing relevant mangement IDs: {e.Message}", DebugConfig.ExtendedLogReportGeneration); + } + } + } + + public ReportCompliance(DynGraphqlQuery query, UserConfig userConfig, ReportType reportType, ReportParams reportParams) : this(query, userConfig, reportType) + { + ShowNonImpactRules = reportParams.ComplianceFilter.ShowNonImpactRules; + } + + #endregion + + #region Methods - Overrides + + public override async Task Generate(int elementsPerFetch, ApiConnection apiConnection, Func callback, CancellationToken ct) + { + // Get management and device info for resolving names. + + await GetManagementAndDevices(apiConnection); + + List managementIds = Managements.Select(mgmt => mgmt.Id).ToList(); + // Get amount of rules to fetch. + + AggregateCount? result = await apiConnection.SendQueryAsync( + RuleQueries.countRules, + new { mgm_ids = managementIds } + ); + int rulesCount = result?.Aggregate?.Count ?? 0; + + // Get data parallelized. + List[]? chunks = await GetDataParallelized(rulesCount, elementsPerFetch, apiConnection, ct, InternalQuery); + + if (chunks != null) + { + RuleViewData.Clear(); + Rules = await ProcessChunksParallelized(chunks, ct, apiConnection); + Log.TryWriteLog(LogType.Debug, "Compliance Report", $"Fetched {Rules.Count} rules for compliance report.", DebugConfig.ExtendedLogReportGeneration); + } + else + { + Log.TryWriteLog(LogType.Error, "Compliance Report", "Failed to fetch rules for compliance report.", DebugConfig.ExtendedLogReportGeneration); + return; + } + + // Set report data. + + ReportData.RuleViewData = RuleViewData; + ReportData.RulesFlat = Rules; + ReportData.ElementsCount = RuleViewData.Count; + } + + public override string ExportToJson() + { + return JsonSerializer.Serialize(ReportData.RuleViewData, new JsonSerializerOptions { WriteIndented = true }); + } + + public override string ExportToCsv() + { + string csvString = ""; + + if (RuleViewData.Count > 0) + { + // Create export string. + + try + { + StringBuilder sb = new StringBuilder(); + Type type = typeof(RuleViewData); + List properties = _columnsToExport + .Select(name => type.GetProperty(name, BindingFlags.Public | BindingFlags.Instance)) + .Where(p => p != null) + .ToList(); + + List propertyNames = []; + + foreach (PropertyInfo? propertyInfo in properties) + { + if (propertyInfo != null) + { + propertyNames.Add(propertyInfo!.Name); + } + } + + TryAppendCsvHeader(sb, propertyNames); + + foreach (RuleViewData ruleViewData in RuleViewData) + { + // Skip marked (i.e. compliant rules) rules if configured. + + if (!ShowNonImpactRules && !ruleViewData.Show) + { + continue; + } + + sb.AppendLine(GetLineForRule(ruleViewData, properties)); + } + + return sb.ToString(); + } + catch (Exception e) + { + Log.TryWriteLog(LogType.Error, "Compliance Report", $"Error while exporting compliance report to CSV: {e.Message}", DebugConfig.ExtendedLogReportGeneration); + } + } + + return csvString; + } + + public override string SetDescription() + { + return "Compliance Report"; + } + + #endregion + + #region Methods - Public + + public async Task[]?> GetDataParallelized(int rulesCount, int elementsPerFetch, ApiConnection apiConnection, CancellationToken ct, string query) + { + List>> tasks = new(); + List> queryVariablesList = new(); + + // Create query variables for fetching rules + + for (int offset = 0; offset < rulesCount; offset += elementsPerFetch) + { + queryVariablesList.Add(CreateQueryVariables(offset, elementsPerFetch, query)); + } + + // Start fetching tasks + + foreach (Dictionary queryVariables in queryVariablesList) + { + await _semaphore.WaitAsync(ct); + + var task = Task.Run(async () => + { + try + { + return await apiConnection.SendQueryAsync>(query, queryVariables); + } + finally + { + _semaphore.Release(); + } + }, ct); + + tasks.Add(task); + } + + // Wait for all tasks to complete and return fetched rules in chunks + + return await Task.WhenAll(tasks); + } + + public async Task> ProcessChunksParallelized(List[] chunks, CancellationToken ct, ApiConnection apiConnection) + { + List processed, List viewData)>> tasks = new(); + + foreach (List chunk in chunks) + { + await _semaphore.WaitAsync(ct); + + Task<(List, List)> task = Task.Run<(List, List)>(async () => + { + List localViewData = new(chunk.Count); + + try + { + foreach (var rule in chunk) + { + SetComplianceDataForRule(rule, apiConnection); + + // Resolve network locations TODO: Move resolving completely to ComplianceCheck or RuleViewData + + NetworkLocation[] networkLocations = rule.Froms.Concat(rule.Tos).ToArray(); + List resolvedNetworkLocations = RuleDisplayBase.GetResolvedNetworkLocations(networkLocations); + + // Add empty groups because display method does not get them + + await GatherEmptyGroups(networkLocations, resolvedNetworkLocations); + RuleViewData ruleViewData = new RuleViewData(rule, _natRuleDisplayHtml, OutputLocation.report, ShowRule(rule), _devices ?? [], Managements, rule.Compliance); + localViewData.Add(ruleViewData); + } + + return (chunk, localViewData); + } + catch (Exception e) + { + Log.TryWriteLog(LogType.Error, "Compliance Report", $"Failed processing chunk: {e.Message}.", DebugConfig.ExtendedLogReportGeneration); + + return (chunk, localViewData); + } + finally + { + _semaphore.Release(); + } + }, ct); + + tasks.Add(task); + } + + (List processed, List viewData)[]? results = await Task.WhenAll(tasks); + + return await GatherReportData(results); + } + + public async Task GetManagementAndDevices(ApiConnection apiConnection) + { + // Get management and device info for resolving names. + + List? managements = await apiConnection.SendQueryAsync>(DeviceQueries.getManagementNames); + + Log.TryWriteLog(LogType.Debug, "Compliance Report", $"Fetched info for {managements?.Count() ?? 0} managements.", DebugConfig.ExtendedLogReportGeneration); + + if (managements != null) + { + Managements = managements.Where(m => _relevanteManagementIDs.Count == 0 || _relevanteManagementIDs.Contains(m.Id)).ToList(); // filter managements by relevant managements config value + + _devices = new(); + + foreach (var management in Managements) + { + if (management.Devices != null && management.Devices.Length > 0) + { + _devices.AddRange(management.Devices); + } + } + } + } + + public void GetViewDataFromRules(List rules) + { + RuleViewData.Clear(); + + for (int i = 0; i < rules.Count; i++) + { + Rule rule = rules.ElementAt(i); + + ComplianceViolationType ruleCompliance = ComplianceViolationType.None; + + if (rule.Violations.Count > 0) + { + if (rule.Violations.Any(violation => violation.Type == ComplianceViolationType.NotAssessable)) + { + ruleCompliance = ComplianceViolationType.NotAssessable; + } + else if (rule.Violations.Count == 1) + { + // TODO: implement + + ruleCompliance = ComplianceViolationType.MultipleViolations; + } + else + { + ruleCompliance = ComplianceViolationType.MultipleViolations; + } + } + + rule.Compliance = ruleCompliance; + + RuleViewData ruleViewData = new RuleViewData(rule, _natRuleDisplayHtml, OutputLocation.report, ShowRule(rule), _devices ?? [], Managements, ruleCompliance); + RuleViewData.Add(ruleViewData); + } + + } + + + #endregion + + #region Methods - Private + + private void SetUpCsvExport() + { + _includeHeaderInExport = true; + _separator = ';'; + _maxCellSize = 32000; // Max size of a cell in Excel is 32,767 characters. + _columnsToExport = + [ + "MgmtId", + "MgmtName", + "Uid", + "Name", + "Source" + ]; + if (GlobalConfig.ShowShortColumnsInComplianceReports) + { + _columnsToExport.Add("SourceShort"); + } + _columnsToExport.Add("Destination"); + if (GlobalConfig.ShowShortColumnsInComplianceReports) + { + _columnsToExport.Add("DestinationShort"); + } + _columnsToExport.Add("Services"); + if (GlobalConfig.ShowShortColumnsInComplianceReports) + { + _columnsToExport.Add("ServicesShort"); + } + _columnsToExport.AddRange( + [ + "Action", + "InstallOn", + "Compliance", + "ViolationDetails", + "ChangeID", + "AdoITID", + "Comment", + "LastModified", + "ExpirationTime", + "RulebaseId", + "RulebaseName", + "Enabled" + ]); + } + + private Task GatherEmptyGroups(NetworkLocation[] networkLocations, List resolvedNetworkLocations) + { + foreach (NetworkLocation networkLocation in networkLocations) + { + foreach (GroupFlat groupFlat in networkLocation.Object.ObjectGroupFlats) + { + if (groupFlat.Object != null && groupFlat.Object.Type.Name == "group" && string.IsNullOrWhiteSpace(groupFlat.Object.MemberRefs)) + { + resolvedNetworkLocations.Add(new NetworkLocation(networkLocation.User, groupFlat.Object)); // adding user only for syntax + } + } + } + + return Task.CompletedTask; + } + + private Task> GatherReportData((List processed, List viewData)[]? results) + { + if (results == null) + { + results = []; + } + RuleViewData.Capacity = results.Sum(r => r.viewData.Count); + List processedRulesFlat = new(results.Sum(r => r.processed.Count)); + + foreach ((List processed, List viewData) result in results) + { + RuleViewData.AddRange(result.viewData); + processedRulesFlat.AddRange(result.processed); + } + + return Task.FromResult(processedRulesFlat); + } + + protected virtual Dictionary CreateQueryVariables(int offset, int limit, string query) + { + Dictionary queryVariables = new(); + + if (query.Contains(QueryVar.ImportIdStart)) + { + queryVariables[QueryVar.ImportIdStart] = int.MaxValue; + } + + if (query.Contains(QueryVar.ImportIdEnd)) + { + queryVariables[QueryVar.ImportIdEnd] = int.MaxValue; + } + + if (query.Contains(QueryVar.Offset)) + { + queryVariables[QueryVar.Offset] = offset; + } + + if (query.Contains(QueryVar.Limit)) + { + queryVariables[QueryVar.Limit] = limit; + } + + if (query.Contains("mgm_ids")) + { + List managementIds = _relevanteManagementIDs; + if (managementIds.Count == 0) + { + managementIds = Managements.Select(mgmt => mgmt.Id).ToList(); + } + queryVariables["mgm_ids"] = managementIds; + } + + return queryVariables; + } + + protected virtual void SetComplianceDataForRule(Rule rule, ApiConnection apiConnection, Func? formatter = null) + { + try + { + rule.ViolationDetails = ""; + rule.Compliance = ComplianceViolationType.None; + int addedViolationDetails = 0; + List violations; + + // If rule is not assessable only display assessability issues in details. + + if (rule.Violations.Any(violation => violation.Type == ComplianceViolationType.NotAssessable)) + { + rule.Compliance = ComplianceViolationType.NotAssessable; + violations = rule.Violations.Where(violation => violation.Type == ComplianceViolationType.NotAssessable).ToList(); + } + else + { + violations = rule.Violations.ToList(); + } + + foreach (ComplianceViolation violation in violations) + { + // Cut violation details when printed violations limit is reached. + + if (_maxPrintedViolations > 0 && addedViolationDetails == _maxPrintedViolations) + { + rule.ViolationDetails += $"
                      Too many violations to display ({rule.Violations.Count}), please check the system for details."; + return; + } + + // Make line breaks in violation details between violations. + + if (rule.ViolationDetails != "") + { + rule.ViolationDetails += "
                      "; + } + + // Set rule compliance. + + if (rule.Compliance != ComplianceViolationType.NotAssessable && addedViolationDetails > 0) + { + rule.Compliance = ComplianceViolationType.MultipleViolations; + } + else + { + rule.Compliance = violation.Type; + } + + // Add to violation details. + + string violationDetails = violation.Details; + + if (formatter != null) + { + violationDetails = formatter(violation); + } + + rule.ViolationDetails += violationDetails; + addedViolationDetails++; + } + } + catch (Exception e) + { + Log.TryWriteLog(LogType.Error, "Compliance Report", $"Error while setting compliance data for rule {rule.Id}: {e.Message}", DebugConfig.ExtendedLogReportGeneration); + return; + } + } + + protected virtual bool ShowRule(Rule rule) + { + bool showRule = true; + + if (rule.Compliance == ComplianceViolationType.None || rule.Action != RuleActions.Accept) + { + showRule = false; + } + + return showRule; + } + + private string GetLineForRule(RuleViewData rule, List properties) + { + IEnumerable values = properties.Select(p => + { + if (p is PropertyInfo propertyInfo) + { + object? value = propertyInfo.GetValue(rule); + + if (value is string str) + { + return TransformHtmlToCsv(p.Name, str); + } + } + + return ""; + }); + + return string.Join(_separator, values.Select(value => $"\"{value}\"")); + } + + private string TransformHtmlToCsv(string propertyName, string htmlInput) + { + if (propertyName == "Enabled") + { + if (htmlInput.Contains(Icons.Check)) + { + htmlInput = "TRUE"; + } + else + { + htmlInput = "FALSE"; + } + } + + htmlInput = htmlInput + .Replace("\r\n", " | ") + .Replace("\n", " | ") + .Replace("
                      ", " | "); + + if (htmlInput.Length > _maxCellSize) + { + htmlInput = htmlInput.Substring(0, _maxCellSize) + " ... (truncated, original length: " + htmlInput.Length + " characters)"; + } + + return htmlInput; + } + + private void TryAppendCsvHeader(StringBuilder sb, List propertyNames) + { + if (_includeHeaderInExport) + { + sb.AppendLine(string.Join(_separator, propertyNames.Select(p => $"\"{p}\""))); + } + } + + public override string ExportToHtml() + { + throw new NotImplementedException(); + } + + #endregion + } +} diff --git a/roles/lib/files/FWO.Report/ReportComplianceDiff.cs b/roles/lib/files/FWO.Report/ReportComplianceDiff.cs new file mode 100644 index 0000000000..a210d9d04c --- /dev/null +++ b/roles/lib/files/FWO.Report/ReportComplianceDiff.cs @@ -0,0 +1,96 @@ +using FWO.Api.Client; +using FWO.Api.Client.Queries; +using FWO.Basics; +using FWO.Config.Api; +using FWO.Data; +using FWO.Data.Report; +using FWO.Logging; +using FWO.Report.Filter; + +namespace FWO.Report +{ + public class ReportComplianceDiff : ReportCompliance + { + public int DiffReferenceInDays { get; set; } = 0; + + protected override string InternalQuery => RuleQueries.getRulesWithViolationsInTimespanByChunk; + + public ReportComplianceDiff(DynGraphqlQuery query, UserConfig userConfig, ReportType reportType) : base(query, userConfig, reportType) + { + + } + + public ReportComplianceDiff(DynGraphqlQuery query, UserConfig userConfig, ReportType reportType, ReportParams reportParams) : base(query, userConfig, reportType, reportParams) + { + DiffReferenceInDays = reportParams.ComplianceFilter.DiffReferenceInDays; + } + + protected override bool ShowRule(Rule rule) + { + bool showRule = base.ShowRule(rule); + + if (rule.ViolationDetails.StartsWith("No changes") || rule.Disabled) + { + showRule = false; + } + + return showRule; + } + + protected override void SetComplianceDataForRule(Rule rule, ApiConnection apiConnection, Func? formatter = null) + { + base.SetComplianceDataForRule(rule, apiConnection, FormatViolationDetails); + } + + + private string FormatViolationDetails(ComplianceViolation violation) + { + return $"Found: ({violation.FoundDate:dd.MM.yyyy - hh:mm}) {violation.Details}"; + } + + protected virtual async Task PostProcessDiffReportsRule(Rule rule, ApiConnection apiConnection) + { + if (rule.ViolationDetails == "") + { + DateTime from = DateTime.Now.AddDays(-DiffReferenceInDays); + rule.ViolationDetails = $"No changes between {from:dd.MM.yyyy} - {from:HH:mm} and {DateTime.Now:dd.MM.yyyy} - {DateTime.Now:HH:mm}"; + } + + string managementUid = Managements?.FirstOrDefault(m => m.Id == rule.MgmtId)?.Uid ?? ""; + + var variables = new { ruleUid = rule.Uid, mgmtUid = managementUid }; + List? violations = await apiConnection.SendQueryAsync>(ComplianceQueries.getViolationsByRuleUid, variables: variables); + + if (violations != null) + { + rule.Compliance = violations.Where(violation => violation.RemovedDate == null).ToList().Count > 0 ? ComplianceViolationType.MultipleViolations : ComplianceViolationType.None; + } + } + + protected override Dictionary CreateQueryVariables(int offset, int limit, string query) + { + Dictionary queryVariables = base.CreateQueryVariables(offset, limit, query); + + if (query.Contains("violations_where")) + { + var violationsWhere = new Dictionary + { + ["found_date"] = new Dictionary + { + ["_gte"] = DateTime.Now.AddDays(-DiffReferenceInDays), + ["_lt"] = DateTime.Now + } + }; + if (GlobalConfig.ComplianceFilterOutInitialViolations) + { + violationsWhere["is_initial"] = new Dictionary + { + ["_eq"] = false + }; + } + queryVariables["violations_where"] = violationsWhere; + } + return queryVariables; + } + } +} diff --git a/roles/lib/files/FWO.Report/ReportConnections.cs b/roles/lib/files/FWO.Report/ReportConnections.cs new file mode 100644 index 0000000000..9cfd5840c7 --- /dev/null +++ b/roles/lib/files/FWO.Report/ReportConnections.cs @@ -0,0 +1,345 @@ +using FWO.Api.Client; +using FWO.Basics; +using FWO.Config.Api; +using FWO.Data; +using FWO.Data.Modelling; +using FWO.Data.Report; +using FWO.Report.Filter; +using FWO.Services.Modelling; +using System.Text; + +namespace FWO.Report +{ + public class ReportConnections(DynGraphqlQuery query, UserConfig userConfig, ReportType reportType) : ReportOwnersBase(query, userConfig, reportType) + { + public struct ConnDisplayFlags + { + public bool IsInterface { get; set; } = false; + public bool IsGlobalComSvc { get; set; } = false; + public bool WithoutLinks { get; set; } = false; + public bool WithoutNumber { get; set; } = false; + + public ConnDisplayFlags() + { } + } + + public override async Task Generate(int elementsPerFetch, ApiConnection apiConnection, Func callback, CancellationToken ct) + { + List conns = await apiConnection.SendQueryAsync>(Query.FullQuery, Query.QueryVariables); + ReportData reportData = new() { OwnerData = [new() { Connections = conns }] }; + await callback(reportData); + + foreach (var owner in ReportData.OwnerData) + { + ReportData.ElementsCount += owner.Connections.Count; + } + } + + public override string SetDescription() + { + int counter = 0; + foreach (var owner in ReportData.OwnerData) + { + counter += owner.Connections.Count; + } + return $"{counter} {userConfig.GetText("connections")}"; + } + + public override string ExportToHtml() + { + StringBuilder report = new(); + int chapterNumber = 0; + foreach (var ownerReport in ReportData.OwnerData) + { + chapterNumber++; + AppendConnDataForOwner(ref report, ownerReport, chapterNumber); + report.AppendLine("
                      "); + } + + if (ReportData.GlobalComSvc.Count > 0 && ReportData.GlobalComSvc[0].GlobalComSvcs.Count > 0) + { + chapterNumber++; + ReportData.GlobalComSvc[0].PrepareObjectData(userConfig.ResolveNetworkAreas); + report.AppendLine(Headline(userConfig.GetText("global_common_services"), 3)); + AppendConnectionsGroupHtml(ReportData.GlobalComSvc[0].GlobalComSvcs, ReportData.GlobalComSvc[0], chapterNumber, ref report, new() { IsGlobalComSvc = true }); + report.AppendLine("
                      "); + AppendNetworkObjectsHtml(ReportData.GlobalComSvc[0].AllObjects, chapterNumber, ref report); + AppendNetworkServicesHtml(ReportData.GlobalComSvc[0].AllServices, chapterNumber, ref report); + } + return GenerateHtmlFrame(userConfig.GetText(ReportType.ToString()), Query.RawFilter, DateTime.Now, report); + } + + public void AppendConnDataForOwner(ref StringBuilder report, OwnerConnectionReport ownerReport, int chapterNumber) + { + report.AppendLine(Headline(ownerReport.Owner.Display(userConfig.GetText("common_service")), 3)); + ownerReport.PrepareObjectData(userConfig.ResolveNetworkAreas); + if (ownerReport.RegularConnections.Count > 0) + { + report.AppendLine(Headline(userConfig.GetText("connections"), 4)); + AppendConnectionsGroupHtml(ownerReport.RegularConnections, ownerReport, chapterNumber, ref report, new()); + report.AppendLine("
                      "); + } + if (ownerReport.Interfaces.Count > 0) + { + report.AppendLine(Headline(userConfig.GetText("interfaces"), 4)); + ownerReport.Interfaces.Sort((ModellingConnection a, ModellingConnection b) => a.CompareTo(b)); + AppendConnectionsGroupHtml(ownerReport.Interfaces, ownerReport, chapterNumber, ref report, new() { IsInterface = true }); + report.AppendLine("
                      "); + } + if (ownerReport.CommonServices.Count > 0) + { + report.AppendLine(Headline(userConfig.GetText("own_common_services"), 4)); + AppendConnectionsGroupHtml(ownerReport.CommonServices, ownerReport, chapterNumber, ref report, new()); + report.AppendLine("
                      "); + } + AppendNetworkObjectsHtml(ownerReport.AllObjects, chapterNumber, ref report); + AppendNetworkServicesHtml(ownerReport.AllServices, chapterNumber, ref report); + } + + protected void AppendConnectionsGroupHtml(List connections, ConnectionReport connReport, int chapterNumber, + ref StringBuilder report, ConnDisplayFlags flags) + { + ConnectionReport.AssignConnectionNumbers(connections); + report.AppendLine(""); + AppendConnectionHeadlineHtml(ref report, flags); + foreach (var connection in connections) + { + AppendConnectionHtml(connection, connReport, chapterNumber, ref report, flags); + } + report.AppendLine("
                      "); + } + + protected void AppendConnectionHtml(ModellingConnection connection, ConnectionReport connReport, int chapterNumber, + ref StringBuilder report, ConnDisplayFlags flags) + { + report.AppendLine(""); + if (!flags.WithoutNumber) + { + report.AppendLine($"{connection.OrderNumber}"); + } + report.AppendLine($"{connection.Id}"); + if (flags.IsInterface) + { + report.AppendLine($"{userConfig.GetText(connection.InterfacePermission)}"); + } + if (flags.IsGlobalComSvc) + { + report.AppendLine($"{connection.App.Name}"); + } + report.AppendLine($"{connection.Name}"); + report.AppendLine($"{connection.Reason}"); + AppendSourcesHtml(connection, connReport, chapterNumber, ref report, flags); + AppendServicesHtml(connection, connReport, chapterNumber, ref report, flags); + AppendDestinationsHtml(connection, connReport, chapterNumber, ref report, flags); + } + + protected void AppendSourcesHtml(ModellingConnection connection, ConnectionReport connReport, int chapterNumber, + ref StringBuilder report, ConnDisplayFlags flags) + { + if (!flags.IsGlobalComSvc && ((connection.InterfaceIsRequested && connection.SrcFromInterface) || (connection.IsRequested && connection.SourceFilled()))) + { + report.AppendLine($"{ModellingHandlerBase.DisplayReqInt(userConfig, connection.TicketId, connection.InterfaceIsRequested, + connection.GetBoolProperty(ConState.Rejected.ToString()) || connection.GetBoolProperty(ConState.InterfaceRejected.ToString()))}"); + } + else if (flags.WithoutLinks) + { + report.AppendLine($"{string.Join("
                      ", GetPlainSrcNames(connection))}"); + } + else + { + report.AppendLine($"{string.Join("
                      ", GetLinkedSrcNames(connReport, connection, chapterNumber))}"); + } + } + + protected void AppendServicesHtml(ModellingConnection connection, ConnectionReport connReport, int chapterNumber, + ref StringBuilder report, ConnDisplayFlags flags) + { + if (!flags.IsGlobalComSvc && (connection.InterfaceIsRequested || connection.IsRequested)) + { + report.AppendLine($"{ModellingHandlerBase.DisplayReqInt(userConfig, connection.TicketId, connection.InterfaceIsRequested, + connection.GetBoolProperty(ConState.Rejected.ToString()) || connection.GetBoolProperty(ConState.InterfaceRejected.ToString()))}"); + } + else if (flags.WithoutLinks) + { + report.AppendLine($"{string.Join("
                      ", GetPlainSvcNames(connection))}"); + } + else + { + report.AppendLine($"{string.Join("
                      ", GetLinkedSvcNames(connReport, connection, chapterNumber))}"); + } + } + + protected void AppendDestinationsHtml(ModellingConnection connection, ConnectionReport connReport, int chapterNumber, + ref StringBuilder report, ConnDisplayFlags flags) + { + if (!flags.IsGlobalComSvc && ((connection.InterfaceIsRequested && connection.DstFromInterface) || (connection.IsRequested && connection.DestinationFilled()))) + { + report.AppendLine($"{ModellingHandlerBase.DisplayReqInt(userConfig, connection.TicketId, connection.InterfaceIsRequested, + connection.GetBoolProperty(ConState.Rejected.ToString()) || connection.GetBoolProperty(ConState.InterfaceRejected.ToString()))}"); + } + else if (flags.WithoutLinks) + { + report.AppendLine($"{string.Join("
                      ", GetPlainDstNames(connection))}"); + } + else + { + report.AppendLine($"{string.Join("
                      ", GetLinkedDstNames(connReport, connection, chapterNumber))}"); + } + } + + private void AppendConnectionHeadlineHtml(ref StringBuilder report, ConnDisplayFlags flags) + { + report.AppendLine(""); + if (!flags.WithoutNumber) + { + report.AppendLine($"{userConfig.GetText("number")}"); + } + report.AppendLine($"{userConfig.GetText("id")}"); + if (flags.IsInterface) + { + report.AppendLine($"{userConfig.GetText("interface_permission")}"); + } + if (flags.IsGlobalComSvc) + { + report.AppendLine($"{userConfig.GetText("owner")}"); + } + report.AppendLine($"{userConfig.GetText("name")}"); + report.AppendLine($"{(flags.IsInterface ? userConfig.GetText("interface_description") : userConfig.GetText("func_reason"))}"); + report.AppendLine($"{userConfig.GetText("source")}"); + report.AppendLine($"{userConfig.GetText("services")}"); + report.AppendLine($"{userConfig.GetText("destination")}"); + report.AppendLine(""); + } + + protected void AppendNetworkObjectsHtml(List networkObjects, int chapterNumber, ref StringBuilder report) + { + if (networkObjects.Count > 0) + { + report.AppendLine(Headline(userConfig.GetText("network_objects"), 4)); + report.AppendLine(""); + AppendNWObjHeadlineHtml(ref report); + foreach (var nwObj in networkObjects) + { + report.AppendLine(""); + report.AppendLine($""); + report.AppendLine($""); + report.AppendLine($""); + report.AppendLine($""); + report.AppendLine(DisplayBase.MemberNamesAsHtml(nwObj.MemberNames)); + } + report.AppendLine("
                      {nwObj.Number}{nwObj.Id}{nwObj.Name}{nwObj.IP}
                      "); + report.AppendLine("
                      "); + } + } + + private void AppendNWObjHeadlineHtml(ref StringBuilder report) + { + report.AppendLine(""); + report.AppendLine($"{userConfig.GetText("number")}"); + report.AppendLine($"{userConfig.GetText("id")}"); + report.AppendLine($"{userConfig.GetText("name")}"); + report.AppendLine($"{userConfig.GetText("ip")}"); + report.AppendLine($"{userConfig.GetText("members")}"); + report.AppendLine(""); + } + + protected void AppendNetworkServicesHtml(List networkServices, int chapterNumber, ref StringBuilder report) + { + if (networkServices.Count > 0) + { + report.AppendLine(Headline(userConfig.GetText("network_services"), 4)); + report.AppendLine(""); + AppendNWSvcHeadlineHtml(ref report); + foreach (var svc in networkServices) + { + report.AppendLine(""); + report.AppendLine($""); + report.AppendLine($""); + report.AppendLine($""); + report.AppendLine($""); + report.AppendLine($""); + report.AppendLine(DisplayBase.MemberNamesAsHtml(svc.MemberNames)); + } + report.AppendLine("
                      {svc.Number}{svc.Id}{svc.Name}{svc.Protocol?.Name}{svc.DestinationPort}
                      "); + report.AppendLine("
                      "); + } + } + + private void AppendNWSvcHeadlineHtml(ref StringBuilder report) + { + report.AppendLine(""); + report.AppendLine($"{userConfig.GetText("number")}"); + report.AppendLine($"{userConfig.GetText("id")}"); + report.AppendLine($"{userConfig.GetText("name")}"); + report.AppendLine($"{userConfig.GetText("protocol")}"); + report.AppendLine($"{userConfig.GetText("port")}"); + report.AppendLine($"{userConfig.GetText("members")}"); + report.AppendLine(""); + } + + private static List GetPlainSrcNames(ModellingConnection conn) + { + List names = ModellingNetworkAreaWrapper.Resolve(conn.SourceAreas).ToList().ConvertAll(s => s.Display()); + names.AddRange(ModellingNwGroupWrapper.Resolve(conn.SourceOtherGroups).ToList().ConvertAll(s => s.Display())); + names.AddRange(ModellingAppRoleWrapper.Resolve(conn.SourceAppRoles).ToList().ConvertAll(s => s.Display())); + names.AddRange(ModellingAppServerWrapper.Resolve(conn.SourceAppServers).ToList().ConvertAll(s => s.Display())); + return names; + } + + private static List GetPlainDstNames(ModellingConnection conn) + { + List names = ModellingNetworkAreaWrapper.Resolve(conn.DestinationAreas).ToList().ConvertAll(s => s.Display()); + names.AddRange(ModellingNwGroupWrapper.Resolve(conn.DestinationOtherGroups).ToList().ConvertAll(s => s.Display())); + names.AddRange(ModellingAppRoleWrapper.Resolve(conn.DestinationAppRoles).ToList().ConvertAll(s => s.Display())); + names.AddRange(ModellingAppServerWrapper.Resolve(conn.DestinationAppServers).ToList().ConvertAll(s => s.Display())); + return names; + } + + private static List GetPlainSvcNames(ModellingConnection conn) + { + List names = ModellingServiceGroupWrapper.Resolve(conn.ServiceGroups).ToList().ConvertAll(s => s.Display()); + names.AddRange(ModellingServiceWrapper.Resolve(conn.Services).ToList().ConvertAll(s => s.Display())); + return names; + } + + private static List GetLinkedSrcNames(ConnectionReport connReport, ModellingConnection conn, int chapterNumber) + { + List names = ModellingNetworkAreaWrapper.Resolve(conn.SourceAreas).ToList().ConvertAll(s => ConstructOutput(s, ObjCatString.NwObj, chapterNumber, connReport.ResolveObjId(s), GetStyle(conn, true))); + names.AddRange(ModellingNwGroupWrapper.Resolve(conn.SourceOtherGroups).ToList().ConvertAll(s => ConstructOutput(s, ObjCatString.NwObj, chapterNumber, connReport.ResolveObjId(s), GetStyle(conn, true)))); + names.AddRange(ModellingAppRoleWrapper.Resolve(conn.SourceAppRoles).ToList().ConvertAll(s => ConstructOutput(s, ObjCatString.NwObj, chapterNumber, connReport.ResolveObjId(s), GetStyle(conn, true)))); + names.AddRange(ModellingAppServerWrapper.Resolve(conn.SourceAppServers).ToList().ConvertAll(s => ConstructOutput(s, ObjCatString.NwObj, chapterNumber, connReport.ResolveObjId(s), GetStyle(conn, true)))); + return names; + } + + private static List GetLinkedDstNames(ConnectionReport connReport, ModellingConnection conn, int chapterNumber) + { + List names = ModellingNetworkAreaWrapper.Resolve(conn.DestinationAreas).ToList().ConvertAll(s => ConstructOutput(s, ObjCatString.NwObj, chapterNumber, connReport.ResolveObjId(s), GetStyle(conn, false))); + names.AddRange(ModellingNwGroupWrapper.Resolve(conn.DestinationOtherGroups).ToList().ConvertAll(s => ConstructOutput(s, ObjCatString.NwObj, chapterNumber, connReport.ResolveObjId(s), GetStyle(conn, false)))); + names.AddRange(ModellingAppRoleWrapper.Resolve(conn.DestinationAppRoles).ToList().ConvertAll(s => ConstructOutput(s, ObjCatString.NwObj, chapterNumber, connReport.ResolveObjId(s), GetStyle(conn, false)))); + names.AddRange(ModellingAppServerWrapper.Resolve(conn.DestinationAppServers).ToList().ConvertAll(s => ConstructOutput(s, ObjCatString.NwObj, chapterNumber, connReport.ResolveObjId(s), GetStyle(conn, false)))); + return names; + } + + private static List GetLinkedSvcNames(ConnectionReport connReport, ModellingConnection conn, int chapterNumber) + { + List names = ModellingServiceGroupWrapper.Resolve(conn.ServiceGroups).ToList().ConvertAll(s => ConstructOutput(s, ObjCatString.Svc, chapterNumber, connReport.ResolveSvcId(s), GetStyle(conn))); + names.AddRange(ModellingServiceWrapper.Resolve(conn.Services).ToList().ConvertAll(s => ConstructOutput(s, ObjCatString.Svc, chapterNumber, connReport.ResolveSvcId(s), GetStyle(conn)))); + return names; + } + + private static string ConstructOutput(ModellingObject inputObj, string type, int chapterNumber, long objId, string style) + { + string linkAddress = GetLinkAddress(OutputLocation.export, $"a{inputObj.AppId}", type, chapterNumber, objId, ReportType.Connections); + return ConstructLink("", inputObj.Display(), style, linkAddress); + } + + private static string GetStyle(ModellingConnection connection, bool? source = null) + { + if (connection.InterfaceIsDecommissioned && (source == null || ((bool)source && connection.SrcFromInterface) || (!(bool)source && connection.DstFromInterface))) + { + return "color: red"; + } + return ""; + } + } +} diff --git a/roles/lib/files/FWO.Report/ReportDevicesBase.cs b/roles/lib/files/FWO.Report/ReportDevicesBase.cs new file mode 100644 index 0000000000..f23a3623ac --- /dev/null +++ b/roles/lib/files/FWO.Report/ReportDevicesBase.cs @@ -0,0 +1,289 @@ +using FWO.Api.Client; +using FWO.Api.Client.Queries; +using FWO.Basics; +using FWO.Config.Api; +using FWO.Data; +using FWO.Data.Middleware; +using FWO.Data.Report; +using FWO.Logging; +using FWO.Report.Filter; +using FWO.Ui.Display; +using Newtonsoft.Json; +using System.Text; +using System.Text.Json; + +namespace FWO.Report +{ + public abstract class ReportDevicesBase : ReportBase + { + private readonly DebugConfig _debugConfig; + + protected ReportDevicesBase(DynGraphqlQuery query, UserConfig UserConfig, ReportType reportType) : base(query, UserConfig, reportType) + { + if (userConfig.GlobalConfig is GlobalConfig globalConfig && !string.IsNullOrEmpty(globalConfig.DebugConfig)) + { + _debugConfig = System.Text.Json.JsonSerializer.Deserialize(globalConfig.DebugConfig) ?? new(); + } + else + { + _debugConfig = new(); + } + } + + public async Task> GetRelevantImportIds(ApiConnection apiConnection, string? timestamp = null) + { + Dictionary ImpIdQueryVariables = new() + { + [QueryVar.Time] = timestamp ?? (Query.ReportTimeString != "" ? Query.ReportTimeString : DateTime.Now.ToString(DynGraphqlQuery.fullTimeFormat)), + [QueryVar.MgmIds] = Query.RelevantManagementIds + }; + List managementReports = await apiConnection.SendQueryAsync>(ReportQueries.getRelevantImportIdsAtTime, ImpIdQueryVariables); + // set max import id as relevant import id + managementReports.ForEach(mgm => mgm.RelevantImportId = mgm.Import.ImportAggregate.ImportAggregateMax.RelevantImportId ?? -1); + + // handle management imported as sub-management as well as part of super management + foreach (var mgm in managementReports) + { + if (mgm.SuperManagerId != null) + { + var superMgmImportId = managementReports.FirstOrDefault(m => m.Id == mgm.SuperManagerId)?.RelevantImportId ?? 0; + if (mgm.RelevantImportId < superMgmImportId) + { + mgm.RelevantImportId = superMgmImportId; + mgm.Import.ImportAggregate.ImportAggregateMax.RelevantImportId = superMgmImportId; //TODO: resolve redundancy + } + } + } + // filter out super managements + managementReports = [.. managementReports.Where(m => m.IsSuperManager == false)]; + + return managementReports; + } + + public async Task> GetImportIdsInTimeRange(ApiConnection apiConnection, string startTime, string stopTime, bool? ruleChangeRequired = null, bool includeObjects = false) + { + var queryVariables = new + { + start_time = startTime, + end_time = stopTime, + mgmIds = Query.RelevantManagementIds, + ruleChangesFound = includeObjects ? null : ruleChangeRequired + }; + List managementReports = await apiConnection.SendQueryAsync>(ReportQueries.getRelevantImportIdsInTimeRange, queryVariables); + + foreach (var mgm in managementReports) + { + mgm.RelevantImportId = mgm.Import.ImportAggregate.ImportAggregateMax.RelevantImportId ?? -1; + if (mgm.SubManagements.Count > 0) + { + foreach (var s in mgm.SubManagements) + { + ManagementReport? subMgm = managementReports.FirstOrDefault(r => r.Id == s.Id); + if (subMgm == null) + continue; + subMgm.ImportControls = [.. subMgm.ImportControls, .. mgm.ImportControls]; + subMgm.ImportControls.Sort((ic1, ic2) => ic1.ControlId.CompareTo(ic2.ControlId)); + } + } + } + managementReports = [.. managementReports.Where(r => r.SubManagements.Count == 0)]; // filter out super managements + + return managementReports; + } + + public static async Task<(List unsupportedList, DeviceFilter reducedDeviceFilter)> GetUsageDataUnsupportedDevices(ApiConnection apiConnection, DeviceFilter deviceFilter) + { + List unsupportedList = []; + DeviceFilter reducedDeviceFilter = new(deviceFilter); + foreach (ManagementSelect management in reducedDeviceFilter.Managements) + { + foreach (DeviceSelect device in management.Devices) + { + if (device.Selected) + { + unsupportedList.Add(device.Name ?? "?"); + device.Selected = false; + } + } + if (!DeviceFilter.IsSelectedManagement(management)) + { + management.Selected = false; + } + } + return (unsupportedList, reducedDeviceFilter); + } + + public override bool NoRuleFound() + { + Log.TryWriteLog(LogType.Info, "Device Report", "Checking if rules were found in device report.", _debugConfig.ExtendedLogReportGeneration); + + foreach (ManagementReport mgmt in ReportData.ManagementData) + { + Log.TryWriteLog(LogType.Info, "Device Report", $"Checking if rules were found in management {mgmt.Id} ({mgmt.Name}).", _debugConfig.ExtendedLogReportGeneration); + + foreach (DeviceReport dev in mgmt.Devices) + { + if (!CheckDeviceHasNoRules(mgmt, dev)) + { + return false; + } + } + } + + Log.TryWriteLog(LogType.Info, "Device Report", "No rules found in any device.", _debugConfig.ExtendedLogReportGeneration); + + return true; + } + + public override bool NoChangesFound() + { + Log.TryWriteLog(LogType.Info, "Management Report", "Checking if changes (rules or objects) were found in management report.", _debugConfig.ExtendedLogReportGeneration); + + foreach (ManagementReport mgmt in ReportData.ManagementData) + { + Log.TryWriteLog(LogType.Info, "Management Report", $"Checking if changes (rules or objects) were found in management {mgmt.Id} ({mgmt.Name}).", _debugConfig.ExtendedLogReportGeneration); + + if (mgmt.RuleChanges != null && mgmt.RuleChanges.Length > 0) + { + return false; + } + } + + Log.TryWriteLog(LogType.Info, "Management Report", "No changes (rules or objects) found in any Management.", _debugConfig.ExtendedLogReportGeneration); + + return true; + } + + private bool CheckDeviceHasNoRules(ManagementReport mgmt, DeviceReport dev) + { + Log.TryWriteLog(LogType.Info, "Device Report", $"Checking if rules were found in device {dev.Id} ({dev.Name}).", _debugConfig.ExtendedLogReportGeneration); + + if (dev.RulebaseLinks.Length > 0) + { + int? nextRulebaseId = dev.RulebaseLinks.FirstOrDefault(_ => _.IsInitial)?.NextRulebaseId; + if (nextRulebaseId != null) + { + Log.TryWriteLog(LogType.Info, "Device Report", "Found initial rulebase", _debugConfig.ExtendedLogReportGeneration); + + foreach (RulebaseLink link in dev.RulebaseLinks) + { + if (mgmt.Rulebases.FirstOrDefault(rulebase => rulebase.Id == link.NextRulebaseId) is RulebaseReport rulebase && rulebase.Rules.Length > 0) + { + Log.TryWriteLog(LogType.Info, "Device Report", $"Found rules in rulebase {rulebase.Id} ({rulebase.Name}) of device {dev.Id} ({dev.Name}).", _debugConfig.ExtendedLogReportGeneration); + return false; + } + } + } + else + { + Log.TryWriteLog(LogType.Info, "Device Report", "No initial rulebase found.", _debugConfig.ExtendedLogReportGeneration); + } + + Log.TryWriteLog(LogType.Info, "Device Report", $"No rules found in device {dev.Id} ({dev.Name}).", _debugConfig.ExtendedLogReportGeneration); + } + else + { + Log.TryWriteLog(LogType.Info, "Device Report", $"No rulebase links found in device {dev.Id} ({dev.Name}).", _debugConfig.ExtendedLogReportGeneration); + } + + return true; + } + + public override string SetDescription() + { + int managementCounter = 0; + foreach (var managementReport in ReportData.ManagementData.Where(mgt => !mgt.Ignore)) + { + managementCounter++; + } + return $"{managementCounter} {userConfig.GetText("managements")}"; + } + + public string DisplayReportHeaderJson() + { + StringBuilder report = new(); + report.AppendLine($"\"report type\": \"{userConfig.GetText(ReportType.ToString())}\","); + report.AppendLine($"\"report generation date\": \"{DateTime.Now.ToUniversalTime().ToString("yyyy-MM-ddTHH:mm:ssK")} (UTC)\","); + if (!ReportType.IsChangeReport()) + { + report.AppendLine($"\"date of configuration shown\": \"{DateTime.Parse(Query.ReportTimeString).ToUniversalTime().ToString("yyyy-MM-ddTHH:mm:ssK")} (UTC)\","); + } + report.AppendLine($"\"device filter\": \"{string.Join(" ", ReportData.ManagementData.Where(mgt => !mgt.Ignore).Select(m => m.NameAndRulebaseNames(" ")))}\","); + report.AppendLine($"\"other filters\": \"{Query.RawFilter}\","); + report.AppendLine($"\"report generator\": \"Firewall Orchestrator - https://fwo.cactus.de/en\","); + report.AppendLine($"\"data protection level\": \"For internal use only\","); + return $"{report}"; + } + + protected string ExportToJson(Func hasItems, Func> getItems, Func renderItem, string itemsPropertyName) + { + StringBuilder report = new("{"); + report.Append(DisplayReportHeaderJson()); + report.AppendLine("\"managements\": ["); + + foreach (var management in ReportData.ManagementData.Where(m => !m.Ignore && m.Devices != null && m.Devices.Any(hasItems))) + { + report.AppendLine($"{{\"{management.Name}\": {{"); + report.AppendLine("\"gateways\": ["); + + foreach (var gateway in management.Devices.Where(hasItems)) + { + report.Append($"{{\"{gateway.Name}\": {{\n\"{itemsPropertyName}\": ["); + + var items = getItems(gateway, management).ToList(); + if (items.Any()) + { + foreach (var item in items) + { + report.Append(renderItem(item)); + } + report = RuleDisplayBase.RemoveLastChars(report, 1); // remove last comma + } + + report.Append("]}},"); + } + + report = RuleDisplayBase.RemoveLastChars(report, 1); + report.Append("]}},"); + } + + report = RuleDisplayBase.RemoveLastChars(report, 1); + report.Append("]}"); + + dynamic? json = JsonConvert.DeserializeObject(report.ToString()); + return JsonConvert.SerializeObject(json, new JsonSerializerSettings + { + Formatting = Formatting.Indented + }); + } + + public string DisplayReportHeaderCsv() + { + StringBuilder report = new(); + report.AppendLine($"# report type: {userConfig.GetText(ReportType.ToString())}"); + report.AppendLine($"# report generation date: {DateTime.Now.ToUniversalTime().ToString("yyyy-MM-ddTHH:mm:ssK")} (UTC)"); + if (!ReportType.IsChangeReport()) + { + report.AppendLine($"# date of configuration shown: {DateTime.Parse(Query.ReportTimeString).ToUniversalTime().ToString("yyyy-MM-ddTHH:mm:ssK")} (UTC)"); + } + report.AppendLine($"# device filter: {string.Join(" ", ReportData.ManagementData.Where(mgt => !mgt.Ignore).Select(m => m.NameAndRulebaseNames(" ")))}"); + report.AppendLine($"# other filters: {Query.RawFilter}"); + report.AppendLine($"# report generator: Firewall Orchestrator - https://fwo.cactus.de/en"); + report.AppendLine($"# data protection level: For internal use only"); + report.AppendLine($"#"); + return $"{report}"; + } + + public static string GetReportDevicesLinkAddress(OutputLocation location, int mgmtId, string type, int chapterNumber, long id, ReportType reportType) + { + return GetLinkAddress(location, $"m{mgmtId}", type, chapterNumber, id, reportType); + } + + + protected string GenerateHtmlFrame(string title, string filter, DateTime date, StringBuilder htmlReport, TimeFilter? timefilter = null) + { + string deviceFilter = string.Join("; ", Array.ConvertAll(ReportData.ManagementData.Where(mgt => !mgt.Ignore).ToArray(), m => ReportType.IsRulebaseReport() ? m.Name : m.NameAndDeviceNames())); + return GenerateHtmlFrameBase(title, filter, date, htmlReport, deviceFilter, Query.SelectedOwner?.Name, timefilter); + } + } +} diff --git a/roles/lib/files/FWO.Report/ReportGenerator.cs b/roles/lib/files/FWO.Report/ReportGenerator.cs new file mode 100644 index 0000000000..ce35074b3f --- /dev/null +++ b/roles/lib/files/FWO.Report/ReportGenerator.cs @@ -0,0 +1,209 @@ +using FWO.Api.Client; +using FWO.Api.Client.Queries; +using FWO.Basics; +using FWO.Config.Api; +using FWO.Data; +using FWO.Data.Modelling; +using FWO.Data.Report; +using FWO.Logging; +using FWO.Services.Modelling; +using FWO.Services.RuleTreeBuilder; +using FWO.Services.Workflow; + +namespace FWO.Report +{ + public static class ReportGenerator + { + private static ReportBase? _currentReport; + + public static async Task GenerateFromTemplate(ReportTemplate reportTemplate, ApiConnection apiConnection, UserConfig userConfig, Action displayMessageInUi, CancellationToken? token = null, IRuleTreeBuilder? ruleTreeBuilder = null) + { + try + { + ReportBase report = ReportBase.ConstructReport(reportTemplate, userConfig, ruleTreeBuilder); + CancellationToken canToken = token == null ? new() : (CancellationToken)token; + await DoGeneration(report, reportTemplate, apiConnection, userConfig, displayMessageInUi, canToken); + return report; + } + catch (Exception exception) + { + Log.WriteError("Report Generator", $"Generating report leads to exception.", exception); + return null; + } + } + + private static async Task DoGeneration(ReportBase report, ReportTemplate reportTemplate, ApiConnection apiConnection, UserConfig userConfig, Action displayMessageInUi, CancellationToken token) + { + try + { + if (report.ReportType.IsConnectionRelatedReport()) + { + await GenerateConnectionRelatedReport(report, reportTemplate, apiConnection, userConfig, displayMessageInUi, token); + } + else if (report.ReportType.IsOwnerReport()) + { + await GenerateOwnerReport(report, reportTemplate, apiConnection, token); + } + else if (report.ReportType == ReportType.Statistics) + { + await GenerateStatisticsReport(report, reportTemplate, apiConnection, token); + } + else + { + await report.Generate(userConfig.ElementsPerFetch, apiConnection, + rep => + { + report.ReportData.ManagementData = rep.ManagementData; + SetRelevantManagements(report.ReportData.ManagementData, reportTemplate.ReportParams.DeviceFilter); + return Task.CompletedTask; + }, token); + if (report.ReportType == ReportType.RecertEventReport) + { + report.ReportData.OwnerData = await ReportRecertEvent.GetRecertification(reportTemplate.ReportParams.ModellingFilter.ReportId, apiConnection); + } + } + } + catch (OperationCanceledException e) + { + Log.WriteDebug("Generate Report", $"Cancelled: {e.Message}"); + } + } + + private static async Task GenerateOwnerReport(ReportBase report, ReportTemplate reportTemplate, ApiConnection apiConnection, CancellationToken token) + { + await report.Generate(0, apiConnection, + rep => + { + report.ReportData.OwnerData.AddRange(rep.OwnerData); + return Task.CompletedTask; + }, token); + report.ReportData.RecertificationDisplayPeriod = reportTemplate.ReportParams.RecertFilter.RecertificationDisplayPeriod; + foreach (var owner in report.ReportData.OwnerData.Select(o => o.Owner)) + { + if (!owner.RecertActive) + { + continue; + } + if (owner.NextRecertDate < DateTime.Now) + { + owner.RecertOverdue = true; + } + else if (owner.NextRecertDate < DateTime.Now.AddDays(reportTemplate.ReportParams.RecertFilter.RecertificationDisplayPeriod)) + { + owner.RecertUpcoming = true; + } + } + } + + private static async Task GenerateConnectionRelatedReport(ReportBase report, ReportTemplate reportTemplate, ApiConnection apiConnection, UserConfig userConfig, Action displayMessageInUi, CancellationToken token) + { + _currentReport = report; + ModellingAppRole dummyAppRole = new(); + List dummyAppRoles = await apiConnection.SendQueryAsync>(ModellingQueries.getDummyAppRole); + if (dummyAppRoles.Count > 0) + { + dummyAppRole = dummyAppRoles[0]; + } + foreach (var selectedOwner in reportTemplate.ReportParams.ModellingFilter.SelectedOwners) + { + OwnerConnectionReport actOwnerData = new(dummyAppRole.Id) { Name = selectedOwner.Display(""), Owner = selectedOwner }; + report.ReportData.OwnerData.Add(actOwnerData); + await report.Generate(userConfig.ElementsPerFetch, apiConnection, + rep => + { + actOwnerData.Connections = rep.OwnerData[0].Connections; + return Task.CompletedTask; + }, token); + await PrepareConnReportData(selectedOwner, actOwnerData, report.ReportType, reportTemplate.ReportParams.ModellingFilter, apiConnection, userConfig, displayMessageInUi); + } + if (report.ReportType == ReportType.Connections) + { + List comSvcs = await apiConnection.SendQueryAsync>(ModellingQueries.getCommonServices); + if (comSvcs.Count > 0) + { + report.ReportData.GlobalComSvc = [new() { GlobalComSvcs = comSvcs, Name = userConfig.GetText("global_common_services") }]; + } + } + } + + private static async Task PrepareConnReportData(FwoOwner selectedOwner, OwnerConnectionReport ownerReport, ReportType reportType, ModellingFilter modellingFilter, + ApiConnection apiConnection, UserConfig userConfig, Action displayMessageInUi) + { + ModellingHandlerBase handlerBase = new(apiConnection, userConfig, new(), false, displayMessageInUi, true, false); + foreach (var conn in ownerReport.Connections) + { + await handlerBase.ExtractUsedInterface(conn); + } + if (reportType == ReportType.VarianceAnalysis) + { + await PrepareVarianceData(ownerReport, modellingFilter, apiConnection, userConfig, displayMessageInUi); + } + ownerReport.Name = selectedOwner.Name; + ownerReport.RegularConnections = [.. ownerReport.Connections.Where(x => !x.IsInterface && !x.IsCommonService && !x.GetBoolProperty(ConState.InterfaceRejected.ToString()))]; + ownerReport.Interfaces = [.. ownerReport.Connections.Where(x => x.IsInterface && !(x.GetBoolProperty(ConState.Rejected.ToString()) || x.GetBoolProperty(ConState.Decommissioned.ToString())))]; + ownerReport.CommonServices = [.. ownerReport.Connections.Where(x => !x.IsInterface && x.IsCommonService && !x.GetBoolProperty(ConState.InterfaceRejected.ToString()))]; + } + + private static async Task PrepareVarianceData(OwnerConnectionReport ownerReport, ModellingFilter modellingFilter, ApiConnection apiConnection, + UserConfig userConfig, Action displayMessageInUi) + { + ownerReport.ExtractConnectionsToAnalyse(); + ExtStateHandler extStateHandler = new(apiConnection); + ModellingVarianceAnalysis varianceAnalysis = new(apiConnection, extStateHandler, userConfig, ownerReport.Owner, displayMessageInUi); + ModellingVarianceResult result = await varianceAnalysis.AnalyseRulesVsModelledConnections(ownerReport.Connections, modellingFilter); + ownerReport.Connections = result.ConnsNotImplemented; + ownerReport.RuleDifferences = result.RuleDifferences; + ownerReport.MissingAppRoles = result.MissingAppRoles; + ownerReport.DifferingAppRoles = result.DifferingAppRoles; + ownerReport.AppRoleStats = result.AppRoleStats; + ownerReport.ImplementationState = await varianceAnalysis.GetSuccessfulRequestState(); + if (modellingFilter.RulesForDeletedConns) + { + ownerReport.RulesForDeletedConns = result.DeletedConnRuleDataToReport(); + } + if (modellingFilter.AnalyseRemainingRules) + { + ownerReport.UnmodelledRules = result.UnmodelledRuleDataToReport(); + ownerReport.UnmodelledRules = await ReportAppRules.PrepareAppRulesReport(ownerReport.UnmodelledRules, modellingFilter, apiConnection, ownerReport.Owner.Id); + } + + if (_currentReport is ReportVariances reportVariances) + { + reportVariances.ReportData.ElementsCount += reportVariances.MissARCounter + reportVariances.DiffARCounter + reportVariances.MissConnCounter + reportVariances.DiffConnCounter; + } + } + + private static async Task GenerateStatisticsReport(ReportBase report, ReportTemplate reportTemplate, ApiConnection apiConnection, CancellationToken token) + { + report.ReportData.GlobalStats = new(); + await report.Generate(0, apiConnection, + rep => + { + report.ReportData.ManagementData = rep.ManagementData; + SetRelevantManagements(report.ReportData.ManagementData, reportTemplate.ReportParams.DeviceFilter); + foreach (var mgm in report.ReportData.ManagementData.Where(mgt => !mgt.Ignore)) + { + mgm.EnforceValidity(); + report.ReportData.GlobalStats.RuleStatistics.ObjectAggregate.ObjectCount += mgm.RuleStatistics.ObjectAggregate.ObjectCount; + report.ReportData.GlobalStats.NetworkObjectStatistics.ObjectAggregate.ObjectCount += mgm.NetworkObjectStatistics.ObjectAggregate.ObjectCount; + report.ReportData.GlobalStats.ServiceObjectStatistics.ObjectAggregate.ObjectCount += mgm.ServiceObjectStatistics.ObjectAggregate.ObjectCount; + report.ReportData.GlobalStats.UserObjectStatistics.ObjectAggregate.ObjectCount += mgm.UserObjectStatistics.ObjectAggregate.ObjectCount; + report.ReportData.GlobalStats.UnusedRulesStatistics.ObjectAggregate.ObjectCount += mgm.UnusedRulesStatistics.ObjectAggregate.ObjectCount; + } + return Task.CompletedTask; + }, token); + } + + private static void SetRelevantManagements(List managementsReport, DeviceFilter deviceFilter) + { + if (deviceFilter.IsAnyDeviceFilterSet()) + { + List relevantManagements = deviceFilter.GetSelectedManagements(); + foreach (var mgm in managementsReport) + { + mgm.Ignore = !relevantManagements.Contains(mgm.Id); + } + } + } + } +} diff --git a/roles/lib/files/FWO.Report/ReportNatRules.cs b/roles/lib/files/FWO.Report/ReportNatRules.cs index 205f08e286..123c3b361b 100644 --- a/roles/lib/files/FWO.Report/ReportNatRules.cs +++ b/roles/lib/files/FWO.Report/ReportNatRules.cs @@ -1,8 +1,9 @@ -using FWO.Api.Data; -using System.Text; +using FWO.Basics; +using FWO.Config.Api; +using FWO.Data; using FWO.Report.Filter; using FWO.Ui.Display; -using FWO.Config.Api; +using System.Text; namespace FWO.Report { @@ -14,178 +15,103 @@ public ReportNatRules(DynGraphqlQuery query, UserConfig userConfig, ReportType r public override string ExportToHtml() { - StringBuilder report = new StringBuilder(); - NatRuleDisplayHtml ruleDisplay = new NatRuleDisplayHtml(userConfig); + StringBuilder report = new(); + NatRuleDisplayHtml ruleDisplay = new(userConfig); + int chapterNumber = 0; - foreach (Management management in Managements.Where(mgt => !mgt.Ignore)) + foreach (var managementReport in ReportData.ManagementData.Where(mgt => !mgt.Ignore)) { - report.AppendLine($"

                      {management.Name}

                      "); + chapterNumber++; + report.AppendLine($"

                      {managementReport.Name}

                      "); report.AppendLine("
                      "); - foreach (Device device in management.Devices) + foreach (var device in managementReport.Devices) { - if (device.Rules != null && device.Rules.Length > 0) + if (device.RulebaseLinks != null) { - report.AppendLine($"

                      {device.Name}

                      "); - report.AppendLine("
                      "); - - report.AppendLine(""); - report.AppendLine(""); - report.AppendLine($""); - report.AppendLine($""); - report.AppendLine($""); - report.AppendLine($""); - report.AppendLine($""); - report.AppendLine($""); - report.AppendLine($""); - report.AppendLine($""); - report.AppendLine($""); - report.AppendLine($""); - report.AppendLine($""); - report.AppendLine($""); - report.AppendLine($""); - report.AppendLine(""); - - foreach (Rule rule in device.Rules) + RulebaseLink? initialRulebaseLink = device.RulebaseLinks.FirstOrDefault(_ => _.IsInitial); + if (initialRulebaseLink != null) { - if (string.IsNullOrEmpty(rule.SectionHeader)) + foreach (var rule in managementReport.Rulebases.FirstOrDefault(rb => rb.Id == initialRulebaseLink.NextRulebaseId)?.Rules ?? []) { - report.AppendLine(""); - report.AppendLine($""); - report.AppendLine($""); - report.AppendLine($""); - report.AppendLine($""); - report.AppendLine($""); - report.AppendLine($""); - report.AppendLine($""); - report.AppendLine($""); - report.AppendLine($""); - report.AppendLine($""); - report.AppendLine($""); - report.AppendLine($""); - report.AppendLine($""); - report.AppendLine(""); - } - else - { - report.AppendLine(""); - report.AppendLine($""); - report.AppendLine(""); + AppendNatRuleHeadlineHtml(ref report, device.Name); + + report.AppendLine(ExportSingleRulebaseToHtml(GetRulesByRulebaseId(initialRulebaseLink.NextRulebaseId, managementReport), ruleDisplay, chapterNumber)); + + report.AppendLine("
                      {userConfig.GetText("number")}{userConfig.GetText("name")}{userConfig.GetText("source_zone")}{userConfig.GetText("source")}{userConfig.GetText("destination_zone")}{userConfig.GetText("destination")}{userConfig.GetText("services")}{userConfig.GetText("trans_source")}{userConfig.GetText("trans_destination")}{userConfig.GetText("trans_services")}{userConfig.GetText("enabled")}{userConfig.GetText("uid")}{userConfig.GetText("comment")}
                      {ruleDisplay.DisplayNumber(rule)}{ruleDisplay.DisplayName(rule)}{ruleDisplay.DisplaySourceZone(rule)}{ruleDisplay.DisplaySource(rule, OutputLocation.export, ReportType)}{ruleDisplay.DisplayDestinationZone(rule)}{ruleDisplay.DisplayDestination(rule, OutputLocation.export, ReportType)}{ruleDisplay.DisplayServices(rule, OutputLocation.export, ReportType)}{ruleDisplay.DisplayTranslatedSource(rule, OutputLocation.export)}{ruleDisplay.DisplayTranslatedDestination(rule, OutputLocation.export)}{ruleDisplay.DisplayTranslatedService(rule, OutputLocation.export)}{ruleDisplay.DisplayEnabled(rule, OutputLocation.export)}{ruleDisplay.DisplayUid(rule)}{ruleDisplay.DisplayComment(rule)}
                      {rule.SectionHeader}
                      "); + report.AppendLine("
                      "); } } - - report.AppendLine(""); } } - // show all objects used in this management's rules + AppendNetworkObjectsForManagementHtml(ref report, chapterNumber, managementReport); + AppendNetworkServicesForManagementHtml(ref report, chapterNumber, managementReport); + AppendUsersForManagementHtml(ref report, chapterNumber, managementReport); + report.AppendLine(""); + } - int objNumber = 1; - if (management.ReportObjects != null) - { - report.AppendLine($"

                      {userConfig.GetText("network_objects")}

                      "); - report.AppendLine("
                      "); - report.AppendLine(""); - report.AppendLine(""); - report.AppendLine($""); - report.AppendLine($""); - report.AppendLine($""); - report.AppendLine($""); - report.AppendLine($""); - report.AppendLine($""); - report.AppendLine($""); - report.AppendLine(""); - foreach (NetworkObject nwobj in management.ReportObjects) - { - report.AppendLine(""); - report.AppendLine($""); - report.AppendLine($""); - report.AppendLine($""); - report.AppendLine($""); - if (nwobj.MemberNames != null && nwobj.MemberNames.Contains("|")) - report.AppendLine($""); - else - report.AppendLine($""); - report.AppendLine($""); - report.AppendLine($""); - report.AppendLine(""); - } - report.AppendLine("
                      {userConfig.GetText("number")}{userConfig.GetText("name")}{userConfig.GetText("type")}{userConfig.GetText("ip_address")}{userConfig.GetText("members")}{userConfig.GetText("uid")}{userConfig.GetText("comment")}
                      {objNumber++}{nwobj.Name}{nwobj.Type.Name}{nwobj.IP}{(nwobj.IpEnd != null && nwobj.IpEnd != "" && nwobj.IpEnd != nwobj.IP ? $"-{nwobj.IpEnd}" : "")}{string.Join("
                      ", nwobj.MemberNames.Split('|'))}
                      {nwobj.MemberNames}{nwobj.Uid}{nwobj.Comment}
                      "); - } + return GenerateHtmlFrame(userConfig.GetText(ReportType.ToString()), Query.RawFilter, DateTime.Now, report); + } - if (management.ReportServices != null) - { - report.AppendLine($"

                      {userConfig.GetText("network_services")}

                      "); - report.AppendLine("
                      "); - report.AppendLine(""); - report.AppendLine(""); - report.AppendLine($""); - report.AppendLine($""); - report.AppendLine($""); - report.AppendLine($""); - report.AppendLine($""); - report.AppendLine($""); - report.AppendLine($""); - report.AppendLine($""); - report.AppendLine(""); - objNumber = 1; - foreach (NetworkService svcobj in management.ReportServices) - { - report.AppendLine(""); - report.AppendLine($""); - report.AppendLine($""); - report.AppendLine($""); - report.AppendLine($""); - if (svcobj.DestinationPortEnd != null && svcobj.DestinationPortEnd != svcobj.DestinationPort) - report.AppendLine($""); - else - report.AppendLine($""); - if (svcobj.MemberNames != null && svcobj.MemberNames.Contains("|")) - report.AppendLine($""); - else - report.AppendLine($""); - report.AppendLine($""); - report.AppendLine($""); - report.AppendLine(""); - } - report.AppendLine("
                      {userConfig.GetText("number")}{userConfig.GetText("name")}{userConfig.GetText("type")}{userConfig.GetText("protocol")}{userConfig.GetText("port")}{userConfig.GetText("members")}{userConfig.GetText("uid")}{userConfig.GetText("comment")}
                      {objNumber++}{svcobj.Name}{svcobj.Name}{((svcobj.Type.Name!="group" && svcobj.Protocol!=null)?svcobj.Protocol.Name:"")}{svcobj.DestinationPort}-{svcobj.DestinationPortEnd}{svcobj.DestinationPort}{string.Join("
                      ", svcobj.MemberNames.Split('|'))}
                      {svcobj.MemberNames}{svcobj.Uid}{svcobj.Comment}
                      "); - } + public string ExportSingleRulebaseToHtml(Rule[] rulebase, NatRuleDisplayHtml ruleDisplay, int chapterNumber) + { + StringBuilder report = new(); + foreach (var rule in rulebase) + { + AppendNatRuleForDeviceHtml(ref report, chapterNumber, rule, ruleDisplay); + } + return report.ToString(); + } - if (management.ReportUsers != null) - { - report.AppendLine($"

                      {userConfig.GetText("users")}

                      "); - report.AppendLine("
                      "); - report.AppendLine(""); - report.AppendLine(""); - report.AppendLine($""); - report.AppendLine($""); - report.AppendLine($""); - report.AppendLine($""); - report.AppendLine($""); - report.AppendLine($""); - report.AppendLine(""); - objNumber = 1; - foreach (NetworkUser userobj in management.ReportUsers) - { - report.AppendLine(""); - report.AppendLine($""); - report.AppendLine($""); - report.AppendLine($""); - if (userobj.MemberNames != null && userobj.MemberNames.Contains("|")) - report.AppendLine($""); - else - report.AppendLine($""); - report.AppendLine($""); - report.AppendLine($""); - report.AppendLine(""); - } - report.AppendLine("
                      {userConfig.GetText("number")}{userConfig.GetText("name")}{userConfig.GetText("type")}{userConfig.GetText("members")}{userConfig.GetText("uid")}{userConfig.GetText("comment")}
                      {objNumber++}{userobj.Name}{userobj.Name}{string.Join("
                      ", userobj.MemberNames.Split('|'))}
                      {userobj.MemberNames}{userobj.Uid}{userobj.Comment}
                      "); - } + private void AppendNatRuleHeadlineHtml(ref StringBuilder report, string? deviceName) + { + report.AppendLine($"

                      {deviceName}

                      "); + report.AppendLine(""); + report.AppendLine(""); + report.AppendLine($""); + report.AppendLine($""); + report.AppendLine($""); + report.AppendLine($""); + report.AppendLine($""); + report.AppendLine($""); + report.AppendLine($""); + report.AppendLine($""); + report.AppendLine($""); + report.AppendLine($""); + report.AppendLine($""); + report.AppendLine($""); + report.AppendLine($""); + report.AppendLine(""); - report.AppendLine("
                      {userConfig.GetText("number")}{userConfig.GetText("name")}{userConfig.GetText("source_zone")}{userConfig.GetText("source")}{userConfig.GetText("destination_zone")}{userConfig.GetText("destination")}{userConfig.GetText("services")}{userConfig.GetText("trans_source")}{userConfig.GetText("trans_destination")}{userConfig.GetText("trans_services")}{userConfig.GetText("enabled")}{userConfig.GetText("uid")}{userConfig.GetText("comment")}
                      "); - } + } - return GenerateHtmlFrame(userConfig.GetText(ReportType.ToString()), Query.RawFilter, DateTime.Now, report); + private void AppendNatRuleForDeviceHtml(ref StringBuilder report, int chapterNumber, Rule rule, NatRuleDisplayHtml ruleDisplay) + { + if (string.IsNullOrEmpty(rule.SectionHeader)) + { + report.AppendLine(""); + report.AppendLine($"{RuleDisplayBase.DisplayNumber(rule)}"); + report.AppendLine($"{RuleDisplayBase.DisplayName(rule)}"); + report.AppendLine($"{RuleDisplayBase.DisplaySourceZones(rule)}"); + report.AppendLine($"{ruleDisplay.DisplaySource(rule, OutputLocation.export, ReportType, chapterNumber)}"); + report.AppendLine($"{RuleDisplayBase.DisplayDestinationZones(rule)}"); + report.AppendLine($"{ruleDisplay.DisplayDestination(rule, OutputLocation.export, ReportType, chapterNumber)}"); + report.AppendLine($"{ruleDisplay.DisplayServices(rule, OutputLocation.export, ReportType, chapterNumber)}"); + report.AppendLine($"{ruleDisplay.DisplayTranslatedSource(rule, OutputLocation.export, chapterNumber)}"); + report.AppendLine($"{ruleDisplay.DisplayTranslatedDestination(rule, OutputLocation.export, chapterNumber)}"); + report.AppendLine($"{ruleDisplay.DisplayTranslatedService(rule, OutputLocation.export, chapterNumber)}"); + report.AppendLine($"{NatRuleDisplayHtml.DisplayEnabled(rule, OutputLocation.export)}"); + report.AppendLine($"{RuleDisplayBase.DisplayUid(rule)}"); + report.AppendLine($"{RuleDisplayBase.DisplayComment(rule)}"); + report.AppendLine(""); + } + else + { + report.AppendLine(""); + report.AppendLine($"{rule.SectionHeader}"); + report.AppendLine(""); + } } } } diff --git a/roles/lib/files/FWO.Report/ReportOwnerRecerts.cs b/roles/lib/files/FWO.Report/ReportOwnerRecerts.cs new file mode 100644 index 0000000000..ebb5d19ad8 --- /dev/null +++ b/roles/lib/files/FWO.Report/ReportOwnerRecerts.cs @@ -0,0 +1,239 @@ +using FWO.Api.Client; +using FWO.Basics; +using FWO.Config.Api; +using FWO.Data; +using FWO.Data.Report; +using FWO.Report.Filter; +using System.Text; + +namespace FWO.Report +{ + public class ReportOwnerRecerts(DynGraphqlQuery query, UserConfig userConfig, ReportType reportType) : ReportOwnersBase(query, userConfig, reportType) + { + public override async Task Generate(int elementsPerFetch, ApiConnection apiConnection, Func callback, CancellationToken ct) + { + List owners = await apiConnection.SendQueryAsync>(Query.FullQuery, Query.QueryVariables); + if (owners.Count > 0) + { + ReportData reportData = new() { OwnerData = [.. owners.ConvertAll(o => new OwnerConnectionReport() { Owner = o })] }; + await callback(reportData); + } + } + + public override string ExportToCsv() + { + List overdueOwners = [.. ReportData.OwnerData.Select(o => o.Owner).Where(ow => ow.RecertOverdue)]; + List upcomingOwners = [.. ReportData.OwnerData.Select(o => o.Owner).Where(ow => ow.RecertUpcoming)]; + List furtherOwners = [.. ReportData.OwnerData.Select(o => o.Owner).Where(ow => ow.RecertActive && !ow.RecertOverdue && !ow.RecertUpcoming)]; + List inactiveOwners = [.. ReportData.OwnerData.Select(o => o.Owner).Where(ow => !ow.RecertActive).OrderBy(ow => ow.Id)]; + + StringBuilder report = new(); + report.AppendLine($"# report type: {userConfig.GetText(ReportType.ToString())}"); + report.AppendLine($"# report generation date: {DateTime.Now.ToUniversalTime():yyyy-MM-ddTHH:mm:ssK} (UTC)"); + if (!string.IsNullOrWhiteSpace(Query.RawFilter)) + { + report.AppendLine($"# other filters: {Query.RawFilter}"); + } + report.AppendLine($"# {userConfig.GetText("statistics")}"); + report.AppendLine($"# {GetOverdueHeadline()}: {overdueOwners.Count}"); + if (ReportData.RecertificationDisplayPeriod > 0) + { + report.AppendLine($"# {GetUpcomingHeadline()}: {upcomingOwners.Count}"); + } + if (furtherOwners.Count > 0) + { + report.AppendLine($"# {GetFurtherHeadline(furtherOwners)}: {furtherOwners.Count}"); + } + if (inactiveOwners.Count > 0) + { + report.AppendLine($"# {GetInactiveHeadline()}: {inactiveOwners.Count}"); + } + report.AppendLine("#"); + + AppendOwnerTableCsv(ref report, GetOverdueHeadline(), overdueOwners, true); + if (ReportData.RecertificationDisplayPeriod > 0) + { + AppendOwnerTableCsv(ref report, GetUpcomingHeadline(), upcomingOwners, true); + } + if (furtherOwners.Count > 0) + { + AppendOwnerTableCsv(ref report, GetFurtherHeadline(furtherOwners), furtherOwners, true); + } + if (inactiveOwners.Count > 0) + { + AppendOwnerTableCsv(ref report, GetInactiveHeadline(), inactiveOwners, false); + } + + return report.ToString(); + } + + public override string ExportToHtml() + { + List overdueOwners = [.. ReportData.OwnerData.Select(o => o.Owner).Where(ow => ow.RecertOverdue)]; + List upcomingOwners = [.. ReportData.OwnerData.Select(o => o.Owner).Where(ow => ow.RecertUpcoming)]; + List furtherOwners = [.. ReportData.OwnerData.Select(o => o.Owner).Where(ow => ow.RecertActive && !ow.RecertOverdue && !ow.RecertUpcoming)]; + List inactiveOwners = [.. ReportData.OwnerData.Select(o => o.Owner).Where(ow => !ow.RecertActive).OrderBy(ow => ow.Id)]; + + StringBuilder report = new(); + report.AppendLine(Headline(userConfig.GetText("statistics"), 3)); + report.AppendLine("
                        "); + report.AppendLine($"
                      • {GetOverdueHeadline()}: {overdueOwners.Count}
                      • "); + if (ReportData.RecertificationDisplayPeriod > 0) + { + report.AppendLine($"
                      • {GetUpcomingHeadline()}: {upcomingOwners.Count}
                      • "); + } + if (furtherOwners.Count > 0) + { + report.AppendLine($"
                      • {GetFurtherHeadline(furtherOwners)}: {furtherOwners.Count}
                      • "); + } + if (inactiveOwners.Count > 0) + { + report.AppendLine($"
                      • {GetInactiveHeadline()}: {inactiveOwners.Count}
                      • "); + } + report.AppendLine("
                      "); + report.AppendLine("
                      "); + if (overdueOwners.Count > 0) + { + report.AppendLine(Headline(GetOverdueHeadline(), 3)); + AppendOwnerTable(ref report, overdueOwners, true); + } + else + { + report.AppendLine(userConfig.GetText("U4004")); + } + report.AppendLine("
                      "); + if (upcomingOwners.Count > 0) + { + report.AppendLine(Headline(GetUpcomingHeadline(), 3)); + AppendOwnerTable(ref report, upcomingOwners, true); + } + else if (ReportData.RecertificationDisplayPeriod > 0) + { + report.AppendLine(userConfig.GetText("U4006").Replace(Placeholder.DAYS, ReportData.RecertificationDisplayPeriod.ToString())); + } + report.AppendLine("
                      "); + if (furtherOwners.Count > 0) + { + report.AppendLine(Headline(GetFurtherHeadline(furtherOwners), 3)); + AppendOwnerTable(ref report, furtherOwners, true); + } + if (inactiveOwners.Count > 0) + { + report.AppendLine("
                      "); + report.AppendLine(Headline(GetInactiveHeadline(), 3)); + AppendOwnerTable(ref report, inactiveOwners, false); + } + + return GenerateHtmlFrame(userConfig.GetText(ReportType.ToString()), Query.RawFilter, DateTime.Now, report); + } + + private void AppendOwnerTable(ref StringBuilder report, List owners, bool includeRecertData) + { + report.AppendLine(""); + AppendOwnerDataHeadlineHtml(ref report, includeRecertData); + foreach (var owner in owners) + { + AppendOwnerDataHtml(ref report, owner, includeRecertData); + } + report.AppendLine("
                      "); + } + + private void AppendOwnerTableCsv(ref StringBuilder report, string headline, List owners, bool includeRecertData) + { + report.AppendLine($"# {headline}"); + AppendOwnerDataHeadlineCsv(ref report, includeRecertData); + foreach (var owner in owners) + { + AppendOwnerDataCsv(ref report, owner, includeRecertData); + } + report.AppendLine("#"); + } + + private static void AppendOwnerDataHtml(ref StringBuilder report, FwoOwner owner, bool includeRecertData) + { + report.AppendLine(""); + if (includeRecertData) + { + report.AppendLine($"{owner.NextRecertDate?.ToString("dd.MM.yyyy")}"); + } + report.AppendLine($"{owner.ExtAppId}"); + report.AppendLine($"{owner.Name}"); + if (includeRecertData) + { + report.AppendLine($"{owner.LastRecertified}"); + report.AppendLine($"{new DistName(owner.LastRecertifierDn).UserName}"); + } + report.AppendLine(""); + } + + private void AppendOwnerDataHeadlineCsv(ref StringBuilder report, bool includeRecertData) + { + if (includeRecertData) + { + report.Append(OutputCsv(userConfig.GetText("next_recert_date"))); + } + report.Append(OutputCsv(userConfig.GetText("id"))); + report.Append(OutputCsv(userConfig.GetText("name"))); + if (includeRecertData) + { + report.Append(OutputCsv(userConfig.GetText("last_recertified"))); + report.Append(OutputCsv(userConfig.GetText("last_recertifier"))); + } + report.AppendLine(); + } + + private static void AppendOwnerDataCsv(ref StringBuilder report, FwoOwner owner, bool includeRecertData) + { + if (includeRecertData) + { + report.Append(OutputCsv(owner.NextRecertDate?.ToString("dd.MM.yyyy"))); + } + report.Append(OutputCsv(owner.ExtAppId)); + report.Append(OutputCsv(owner.Name)); + if (includeRecertData) + { + report.Append(OutputCsv(owner.LastRecertified?.ToString("dd.MM.yyyy"))); + report.Append(OutputCsv(new DistName(owner.LastRecertifierDn).UserName)); + } + report.AppendLine(); + } + + private void AppendOwnerDataHeadlineHtml(ref StringBuilder report, bool includeRecertData) + { + report.AppendLine(""); + if (includeRecertData) + { + report.AppendLine($"{userConfig.GetText("next_recert_date")}"); + } + report.AppendLine($"{userConfig.GetText("id")}"); + report.AppendLine($"{userConfig.GetText("name")}"); + if (includeRecertData) + { + report.AppendLine($"{userConfig.GetText("last_recertified")}"); + report.AppendLine($"{userConfig.GetText("last_recertifier")}"); + } + report.AppendLine(""); + } + + private string GetOverdueHeadline() + { + return userConfig.GetText("U4003"); + } + + private string GetUpcomingHeadline() + { + return userConfig.GetText("U4005").Replace(Placeholder.DAYS, ReportData.RecertificationDisplayPeriod.ToString()); + } + + private string GetFurtherHeadline(List furtherOwners) + { + return userConfig.GetText(!furtherOwners.Any(o => o.NextRecertDate == null) ? "U4007" : "U4008"); + } + + private string GetInactiveHeadline() + { + return userConfig.GetText("U4009"); + } + + } +} diff --git a/roles/lib/files/FWO.Report/ReportOwners.cs b/roles/lib/files/FWO.Report/ReportOwners.cs new file mode 100644 index 0000000000..07ffae2a6d --- /dev/null +++ b/roles/lib/files/FWO.Report/ReportOwners.cs @@ -0,0 +1,174 @@ +using FWO.Api.Client; +using FWO.Api.Client.Queries; +using FWO.Basics; +using FWO.Config.Api; +using FWO.Data; +using FWO.Data.Report; +using FWO.Report.Filter; +using System.Net; +using System.Text; + +namespace FWO.Report +{ + /// + /// Report listing owners and their metadata. + /// + public class ReportOwners(DynGraphqlQuery query, UserConfig userConfig, ReportType reportType) : ReportOwnersBase(query, userConfig, reportType) + { + private Dictionary ownerLifeCycleStates = []; + private List ownerResponsibleTypes = []; + private IEnumerable OrderedOwners => ReportData.OwnerData + .Select(ownerReport => ownerReport.Owner) + .OrderBy(owner => owner.ExtAppId ?? "") + .ThenBy(owner => owner.Name); + + public override async Task Generate(int elementsPerFetch, ApiConnection apiConnection, Func callback, CancellationToken ct) + { + List owners = await apiConnection.SendQueryAsync>(Query.FullQuery, Query.QueryVariables); + List lifeCycleStates = await apiConnection.SendQueryAsync>(OwnerQueries.getOwnerLifeCycleStates); + ownerResponsibleTypes = [.. (await apiConnection.SendQueryAsync>(OwnerQueries.getOwnerResponsibleTypes)) + .Where(type => type.Active) + .OrderBy(type => type.SortOrder) + .ThenBy(type => type.Name, StringComparer.OrdinalIgnoreCase)]; + ownerLifeCycleStates = lifeCycleStates.ToDictionary(state => state.Id, state => state.Display(userConfig.GetText("inactive"))); + ReportData reportData = new() { OwnerData = [.. owners.ConvertAll(owner => new OwnerConnectionReport() { Owner = owner, Name = owner.Display("") })] }; + await callback(reportData); + } + + public override string ExportToCsv() + { + StringBuilder report = new(); + report.AppendLine($"# report type: {userConfig.GetText(ReportType.ToString())}"); + report.AppendLine($"# report generation date: {DateTime.Now.ToUniversalTime():yyyy-MM-ddTHH:mm:ssK} (UTC)"); + if (!string.IsNullOrWhiteSpace(Query.RawFilter)) + { + report.AppendLine($"# filter: {Query.RawFilter}"); + } + AppendOwnerDataHeadlineCsv(ref report); + foreach (FwoOwner owner in OrderedOwners) + { + AppendOwnerDataCsv(ref report, owner); + } + + return report.ToString(); + } + + public override string ExportToHtml() + { + StringBuilder report = new(); + report.AppendLine(""); + AppendOwnerDataHeadlineHtml(ref report); + foreach (FwoOwner owner in OrderedOwners) + { + AppendOwnerDataHtml(ref report, owner); + } + report.AppendLine("
                      "); + return GenerateHtmlFrame(userConfig.GetText(ReportType.ToString()), Query.RawFilter, DateTime.Now, report); + } + + private void AppendOwnerDataHeadlineHtml(ref StringBuilder report) + { + report.AppendLine(""); + report.AppendLine($"{userConfig.GetText("id")}"); + report.AppendLine($"{userConfig.GetText("name")}"); + report.AppendLine($"{userConfig.GetText("criticality")}"); + report.AppendLine($"{userConfig.GetText("state")}"); + foreach (OwnerResponsibleType type in ownerResponsibleTypes) + { + report.AppendLine($"{Encode(type.Name)}"); + } + report.AppendLine($"{userConfig.GetText("additional_info")}"); + report.AppendLine(""); + } + + private void AppendOwnerDataHeadlineCsv(ref StringBuilder report) + { + report.Append(OutputCsv(userConfig.GetText("id"))); + report.Append(OutputCsv(userConfig.GetText("name"))); + report.Append(OutputCsv(userConfig.GetText("criticality"))); + report.Append(OutputCsv(userConfig.GetText("state"))); + foreach (OwnerResponsibleType type in ownerResponsibleTypes) + { + report.Append(OutputCsv(type.Name)); + } + report.Append(OutputCsv(userConfig.GetText("additional_info"))); + report.AppendLine(); + } + + private void AppendOwnerDataHtml(ref StringBuilder report, FwoOwner owner) + { + report.AppendLine(""); + report.AppendLine($"{Encode(owner.ExtAppId)}"); + report.AppendLine($"{Encode(owner.Name)}"); + report.AppendLine($"{Encode(owner.Criticality)}"); + report.AppendLine($"{Encode(GetOwnerState(owner))}"); + foreach (OwnerResponsibleType type in ownerResponsibleTypes) + { + report.AppendLine($"{FormatHtmlCell(GetResponsibles(owner, type.Id))}"); + } + report.AppendLine($"{FormatHtmlCell(GetAdditionalInfo(owner))}"); + report.AppendLine(""); + } + + private void AppendOwnerDataCsv(ref StringBuilder report, FwoOwner owner) + { + report.Append(OutputCsv(owner.ExtAppId)); + report.Append(OutputCsv(owner.Name)); + report.Append(OutputCsv(owner.Criticality)); + report.Append(OutputCsv(GetOwnerState(owner))); + foreach (OwnerResponsibleType type in ownerResponsibleTypes) + { + report.Append(OutputCsv(GetResponsibles(owner, type.Id, "; "))); + } + report.Append(OutputCsv(GetAdditionalInfo(owner, "; "))); + report.AppendLine(); + } + + private string GetOwnerState(FwoOwner owner) + { + if (owner.OwnerLifeCycleStateId.HasValue && ownerLifeCycleStates.TryGetValue(owner.OwnerLifeCycleStateId.Value, out string? state)) + { + return state; + } + + return ""; + } + + private static string Encode(string? value) + { + return WebUtility.HtmlEncode(value ?? ""); + } + + private static string FormatHtmlCell(string value) + { + return string.IsNullOrWhiteSpace(value) + ? "" + : Encode(value) + .Replace("\r\n", "
                      ") + .Replace("\n", "
                      ") + .Replace("\r", "
                      "); + } + + private static string GetAdditionalInfo(FwoOwner owner, string separator = "\n") + { + return owner.AdditionalInfo == null + ? "" + : string.Join(separator, owner.AdditionalInfo.OrderBy(entry => entry.Key).Select(entry => $"{entry.Key}: {entry.Value}")); + } + + private static string GetResponsibles(FwoOwner owner, int responsibleTypeId, string separator = "\n") + { + return string.Join(separator, owner.GetOwnerResponsiblesByType(responsibleTypeId) + .Where(dn => !string.IsNullOrWhiteSpace(dn)) + .OrderBy(dn => dn) + .Select(FormatResponsible)); + } + + private static string FormatResponsible(string dn) + { + DistName distName = new(dn); + string display = !string.IsNullOrWhiteSpace(distName.UserName) ? distName.UserName : distName.Group; + return string.IsNullOrWhiteSpace(display) ? dn : display; + } + } +} diff --git a/roles/lib/files/FWO.Report/ReportOwnersBase.cs b/roles/lib/files/FWO.Report/ReportOwnersBase.cs new file mode 100644 index 0000000000..d9c4c22c37 --- /dev/null +++ b/roles/lib/files/FWO.Report/ReportOwnersBase.cs @@ -0,0 +1,35 @@ +using FWO.Report.Filter; +using FWO.Config.Api; +using FWO.Basics; +using System.Text.Json; +using System.Text; + +namespace FWO.Report +{ + public abstract class ReportOwnersBase : ReportBase + { + protected ReportOwnersBase(DynGraphqlQuery query, UserConfig userConfig, ReportType reportType) : base(query, userConfig, reportType) + { } + + public override string ExportToJson() + { + return JsonSerializer.Serialize(ReportData.OwnerData, new JsonSerializerOptions { WriteIndented = true }); + } + + public override string ExportToCsv() + { + throw new NotImplementedException(); + } + + public override string SetDescription() + { + return $"{ReportData.OwnerData.Count} {userConfig.GetText("owners")}"; + } + + protected string GenerateHtmlFrame(string title, string filter, DateTime date, StringBuilder htmlReport) + { + string? ownerFilter = ReportType.IsOwnerReport() ? null : string.Join("; ", ReportData.OwnerData.ConvertAll(o => o.Name)); + return GenerateHtmlFrameBase(title, filter, date, htmlReport, null, ownerFilter); + } + } +} diff --git a/roles/lib/files/FWO.Report/ReportRecertEvent.cs b/roles/lib/files/FWO.Report/ReportRecertEvent.cs new file mode 100644 index 0000000000..dd2b9b633e --- /dev/null +++ b/roles/lib/files/FWO.Report/ReportRecertEvent.cs @@ -0,0 +1,47 @@ +using FWO.Api.Client; +using FWO.Api.Client.Queries; +using FWO.Basics; +using FWO.Config.Api; +using FWO.Data.Report; +using FWO.Logging; +using FWO.Report.Filter; +using FWO.Services.RuleTreeBuilder; +using System.Text; +using System.Text.Json; + +namespace FWO.Report +{ + public class ReportRecertEvent(DynGraphqlQuery query, UserConfig userConfig, ReportType reportType, IRuleTreeBuilder? ruleTreeBuilder = null) : ReportRules(query, userConfig, reportType, ruleTreeBuilder) + { + public override string ExportToHtml() + { + StringBuilder report = new(); + int chapterNumber = 0; + RecertificateOwner recertOwner = new(Query, userConfig, ReportType); + recertOwner.AppendOwnerData(ref report, ReportData.OwnerData, chapterNumber, 1); + report.AppendLine(Headline(userConfig.GetText("recertified_rules"), 3)); + ConstructHtmlReport(ref report, ReportData.ManagementData, chapterNumber, 1); + return GenerateHtmlFrame(userConfig.GetText(ReportType.ToString()), Query.RawFilter, DateTime.Now, report); + } + + public static async Task> GetRecertification(long? reportId, ApiConnection apiConnection) + { + try + { + if (reportId != null) + { + ReportFile reportFile = (await apiConnection.SendQueryAsync>(ReportQueries.getGeneratedReport, new { report_id = reportId }))[0]; + if (reportFile.Json != null) + { + return JsonSerializer.Deserialize>(reportFile.Json) ?? []; + } + } + } + catch (Exception exception) + { + Log.WriteError("Report Recertification Event", "Fetch generated recertification failed", exception); + } + return []; + } + } +} diff --git a/roles/lib/files/FWO.Report/ReportRules.cs b/roles/lib/files/FWO.Report/ReportRules.cs index 2f929d0038..99af930e94 100644 --- a/roles/lib/files/FWO.Report/ReportRules.cs +++ b/roles/lib/files/FWO.Report/ReportRules.cs @@ -1,44 +1,206 @@ -using FWO.Api.Data; -using System.Text; using FWO.Api.Client; -using FWO.Report.Filter; using FWO.Api.Client.Queries; -using FWO.Ui.Display; -using FWO.Logging; +using FWO.Basics; using FWO.Config.Api; -using System.Text.Json; +using FWO.Data; +using FWO.Data.Report; +using FWO.Services.RuleTreeBuilder; +using FWO.Logging; +using FWO.Report.Filter; +using FWO.Ui.Display; using Newtonsoft.Json; +using System.Text; +using System.Text.Json; +using Microsoft.Extensions.DependencyInjection; +using System.Diagnostics; +using Rule = FWO.Data.Rule; namespace FWO.Report { - public class ReportRules : ReportBase + public static class DeviceReportExtensions { - public ReportRules(DynGraphqlQuery query, UserConfig userConfig, ReportType reportType) : base(query, userConfig, reportType) { } + public static bool ContainsRules(this DeviceReport device) + { + return device.RulebaseLinks != null && device.RulebaseLinks.Any(); + } + + public static bool ContainsRules(this ManagementReport management) + { + return management.Devices != null && management.Devices.Any(d => d.ContainsRules()); + } + } - private const int ColumnCount = 12; + public class ReportRules(DynGraphqlQuery query, UserConfig userConfig, ReportType reportType, IRuleTreeBuilder? ruleTreeBuilder = null) : ReportDevicesBase(query, userConfig, reportType) + { + private const int ColumnCount = 14; + protected bool UseAdditionalFilter = false; + private static Dictionary<(int deviceId, int managementId), Rule[]> _rulesCache = []; + private readonly IRuleTreeBuilder? ruleTreeBuilderFromScope = ruleTreeBuilder; - public override async Task GetObjectsInReport(int objectsPerFetch, ApiConnection apiConnection, Func callback) // to be called when exporting + public override async Task Generate(int elementsPerFetch, ApiConnection apiConnection, Func callback, CancellationToken ct) + { + Log.WriteDebug("Generate Rules Report", "Generating report..."); + + // Prepare execution time logging + + Stopwatch totalStopwatch = Stopwatch.StartNew(); + Stopwatch phaseStopwatch = Stopwatch.StartNew(); + + // Initial fetch + + Query.QueryVariables[QueryVar.Limit] = elementsPerFetch; + Query.QueryVariables[QueryVar.Offset] = 0; + bool keepFetching = true; + + List managementsWithRelevantImportId = await GetRelevantImportIds(apiConnection); + ReportData.ManagementData = []; + foreach (var management in managementsWithRelevantImportId) + { + SetMgtQueryVars(management); // this includes mgm_id AND relevant import ID! + List result = await apiConnection.SendQueryAsync>(Query.FullQuery, Query.QueryVariables); + ManagementReport managementReport = result[0]; + managementReport.Import = management.Import; + ReportData.ManagementData.Add(managementReport); + } + + await LogExecutionTime(phaseStopwatch, "Initial fetch", true); + + // Fill report data + + while (keepFetching) + { + if (ct.IsCancellationRequested) + { + Log.WriteDebug("Generate Rules Report", "Task cancelled"); + ct.ThrowIfCancellationRequested(); + } + keepFetching = false; + Query.QueryVariables[QueryVar.Offset] = (int)Query.QueryVariables[QueryVar.Offset] + elementsPerFetch; + foreach (var management in managementsWithRelevantImportId) + { + SetMgtQueryVars(management); + ManagementReport? mgtToFill = ReportData.ManagementData.FirstOrDefault(m => m.Id == management.Id); + if (mgtToFill != null) + { + (bool newObjects, Dictionary maxAddedCounts) = mgtToFill.Merge((await apiConnection.SendQueryAsync>(Query.FullQuery, Query.QueryVariables))[0]); + // new objects might have been added, but if none reached the limit of elementsPerFetch, we can stop fetching + keepFetching = newObjects && maxAddedCounts["Rules"] >= elementsPerFetch; // limit is only set on rules for rule report query + } + } + await callback(ReportData); + } + + await LogExecutionTime(phaseStopwatch, "Filling report data", true); + + if (!ReportType.IsRulebaseReport()) + { + TryBuildRuleTree(); + } + + await LogExecutionTime(phaseStopwatch, "Building rule tree", false); + await LogExecutionTime(totalStopwatch, "Generating Rules Report", false); + } + + private Task LogExecutionTime(Stopwatch stopwatch, string phaseName, bool reset) + { + stopwatch.Stop(); + TimeSpan elapsed = stopwatch.Elapsed; + Log.WriteDebug("Generate Rules Report", $"{phaseName} completed. Execution times: {double.Round(elapsed.TotalMilliseconds)} milliseconds"); + + if (reset) + { + stopwatch.Reset(); + stopwatch.Start(); + } + + return Task.CompletedTask; + } + + protected void TryBuildRuleTree() + { + // Use scoped IRuleTreeBuilder from the caller when available + + IRuleTreeBuilder? scopedRuleTreeBuilder = ruleTreeBuilderFromScope; + + if (scopedRuleTreeBuilder == null && Services.ServiceProvider.Services == null) + { + Log.WriteError("Generate Rules Report", "Cannot build rule tree: IServiceProvider not set and no scoped IRuleTreeBuilder provided"); + return; + } + + if (scopedRuleTreeBuilder == null) + { + try + { + scopedRuleTreeBuilder = Services.ServiceProvider.Services!.GetRequiredService(); + } + catch (InvalidOperationException exception) + { + Log.WriteError("Generate Rules Report", "Cannot build rule tree: scoped IRuleTreeBuilder must be provided by the caller", exception); + return; + } + } + + if (scopedRuleTreeBuilder == null) + { + Log.WriteError("Generate Rules Report", "Cannot build rule tree: IRuleTreeBuilder service not found"); + return; + } + + // Build rule tree for each device in each management + + int ruleCount = 0; + + foreach (ManagementReport managementReport in ReportData.ManagementData) + { + foreach (DeviceReport deviceReport in managementReport.Devices) + { + scopedRuleTreeBuilder.Reset(managementReport.Rulebases, deviceReport.RulebaseLinks); + + List allRules = scopedRuleTreeBuilder.BuildRuleTree(managementReport.Rulebases, deviceReport.RulebaseLinks, managementReport.Id, deviceReport.Id); + + Rule[] rulesArray = [.. allRules]; + _rulesCache[(deviceReport.Id, managementReport.Id)] = rulesArray; + + // Add all rule ids to ReportedRuleIds of management, that are not already in that list + + managementReport.ReportedRuleIds.AddRange( + rulesArray.Select(r => r.Id).Except(managementReport.ReportedRuleIds) + ); + + ruleCount += rulesArray.Count(rule => string.IsNullOrEmpty(rule.SectionHeader)); + } + } + + ReportData.ElementsCount = ruleCount; + } + + protected virtual void SetMgtQueryVars(ManagementReport management) + { + Query.QueryVariables[QueryVar.MgmId] = management.Id; + Query.QueryVariables[QueryVar.ImportIdStart] = management.RelevantImportId ?? -1; + Query.QueryVariables[QueryVar.ImportIdEnd] = management.RelevantImportId ?? -1; + } + + public override async Task GetObjectsInReport(int objectsPerFetch, ApiConnection apiConnection, Func callback) // to be called when exporting { bool gotAllObjects = true; //whether the fetch count limit was reached during fetching if (!GotObjectsInReport) { - foreach (Management management in Managements) + foreach (var managementReport in ReportData.ManagementData.Where(x => x.Import.ImportAggregate.ImportAggregateMax.RelevantImportId is not null)) { - if (management.Import.ImportAggregate.ImportAggregateMax.RelevantImportId is not null) + // set query variables for object query + var objQueryVariables = new Dictionary { - // set query variables for object query - var objQueryVariables = new Dictionary - { - { "mgmIds", management.Id }, - { "limit", objectsPerFetch }, - { "offset", 0 }, - }; + { QueryVar.MgmIds, managementReport.Id }, + { QueryVar.Limit, objectsPerFetch }, + { QueryVar.Offset, 0 }, + }; - // get objects for this management in the current report - gotAllObjects &= await GetObjectsForManagementInReport(objQueryVariables, ObjCategory.all, int.MaxValue, apiConnection, callback); - } + // get objects for this management in the current report + gotAllObjects &= await GetObjectsForManagementInReport(objQueryVariables, ObjCategory.all, int.MaxValue, apiConnection, callback); } GotObjectsInReport = true; } @@ -46,38 +208,37 @@ public override async Task GetObjectsInReport(int objectsPerFetch, ApiConn return gotAllObjects; } - public override async Task GetObjectsForManagementInReport(Dictionary objQueryVariables, ObjCategory objects, int maxFetchCycles, ApiConnection apiConnection, Func callback) + public override async Task GetObjectsForManagementInReport(Dictionary objQueryVariables, ObjCategory objects, int maxFetchCycles, ApiConnection apiConnection, Func callback) { - if (!objQueryVariables.ContainsKey("mgmIds") || !objQueryVariables.ContainsKey("limit") || !objQueryVariables.ContainsKey("offset")) + if (!objQueryVariables.ContainsKey(QueryVar.MgmIds) || !objQueryVariables.ContainsKey(QueryVar.Limit) || !objQueryVariables.ContainsKey(QueryVar.Offset)) throw new ArgumentException("Given objQueryVariables dictionary does not contain variable for management id, limit or offset"); - int mid = (int)objQueryVariables.GetValueOrDefault("mgmIds")!; - Management management = Managements.FirstOrDefault(m => m.Id == mid) ?? throw new ArgumentException("Given management id does not exist for this report"); + int mid = (int)objQueryVariables.GetValueOrDefault(QueryVar.MgmIds)!; + ManagementReport managementReport = ReportData.ManagementData.FirstOrDefault(m => m.Id == mid) ?? throw new ArgumentException("Given management id does not exist for this report"); - objQueryVariables.Add("ruleIds", "{" + string.Join(", ", management.ReportedRuleIds) + "}"); - objQueryVariables.Add("importId", management.Import.ImportAggregate.ImportAggregateMax.RelevantImportId!); - - string query = ""; - switch (objects) + if (managementReport.ReportedRuleIds.Count == 0) + { + managementReport.ReportedRuleIds.AddRange(managementReport.GetAllRuleIds()); + } + objQueryVariables.Add(QueryVar.RuleIds, "{" + string.Join(", ", managementReport.ReportedRuleIds) + "}"); + if (!objQueryVariables.ContainsKey(QueryVar.ImportIdStart)) + { + objQueryVariables.Add(QueryVar.ImportIdStart, managementReport.Import.ImportAggregate.ImportAggregateMax.RelevantImportId!); + } + if (!objQueryVariables.ContainsKey(QueryVar.ImportIdEnd)) { - case ObjCategory.all: - query = ObjectQueries.getReportFilteredObjectDetails; break; - case ObjCategory.nobj: - query = ObjectQueries.getReportFilteredNetworkObjectDetails; break; - case ObjCategory.nsrv: - query = ObjectQueries.getReportFilteredNetworkServiceObjectDetails; break; - case ObjCategory.user: - query = ObjectQueries.getReportFilteredUserDetails; break; + objQueryVariables.Add(QueryVar.ImportIdEnd, managementReport.Import.ImportAggregate.ImportAggregateMax.RelevantImportId!); } - bool newObjects = true; + string getObjQuery = GetQuery(objects); + bool keepFetching = true; int fetchCount = 0; - int elementsPerFetch = (int)objQueryVariables.GetValueOrDefault("limit")!; - Management filteredObjects; - Management allFilteredObjects = new Management(); - while (newObjects && ++fetchCount <= maxFetchCycles) + int elementsPerFetch = (int)objQueryVariables.GetValueOrDefault(QueryVar.Limit)!; + ManagementReport filteredObjects; + ManagementReport allFilteredObjects = new(); + while (keepFetching && ++fetchCount <= maxFetchCycles) { - filteredObjects = (await apiConnection.SendQueryAsync(query, objQueryVariables))[0]; + filteredObjects = (await apiConnection.SendQueryAsync>(getObjQuery, objQueryVariables))[0]; if (fetchCount == 1) { @@ -85,19 +246,15 @@ public override async Task GetObjectsForManagementInReport(Dictionary maxAddedCounts) = allFilteredObjects.Merge(filteredObjects); + keepFetching = newObjects && maxAddedCounts.Values.Any(v => v >= elementsPerFetch); } - if (objects == ObjCategory.all || objects == ObjCategory.nobj) - management.ReportObjects = allFilteredObjects.ReportObjects; - if (objects == ObjCategory.all || objects == ObjCategory.nsrv) - management.ReportServices = allFilteredObjects.ReportServices; - if (objects == ObjCategory.all || objects == ObjCategory.user) - management.ReportUsers = allFilteredObjects.ReportUsers; + FillReport(allFilteredObjects, managementReport, objects); - objQueryVariables["offset"] = (int)objQueryVariables["offset"] + elementsPerFetch; + objQueryVariables[QueryVar.Offset] = (int)objQueryVariables[QueryVar.Offset] + elementsPerFetch; - await callback(Managements); + await callback(ReportData); } Log.WriteDebug("Lazy Fetch", $"Fetched sidebar objects in {fetchCount - 1} cycle(s) ({elementsPerFetch} at a time)"); @@ -105,45 +262,105 @@ public override async Task GetObjectsForManagementInReport(Dictionary callback, CancellationToken ct) + private void FillReport(ManagementReport allFilteredObjects, ManagementReport managementReport, ObjCategory objects) { - Query.QueryVariables["limit"] = rulesPerFetch; - Query.QueryVariables["offset"] = 0; - bool gotNewObjects = true; + if (UseAdditionalFilter) + { + AdditionalFilter(allFilteredObjects, managementReport.RelevantObjectIds); + } - Management[] managementsWithRelevantImportId = await getRelevantImportIds(apiConnection); + if (objects == ObjCategory.all || objects == ObjCategory.nobj) + { + managementReport.ReportObjects = allFilteredObjects.ReportObjects; + } + if (objects == ObjCategory.all || objects == ObjCategory.nsrv) + { + managementReport.ReportServices = allFilteredObjects.ReportServices; + } + if (objects == ObjCategory.all || objects == ObjCategory.user) + { + managementReport.ReportUsers = allFilteredObjects.ReportUsers; + } + } - Managements = new Management[managementsWithRelevantImportId.Length]; - int i; - for (i = 0; i < managementsWithRelevantImportId.Length; i++) + private static string GetQuery(ObjCategory objects) + { + return objects switch { - // setting mgmt and relevantImporId QueryVariables - Query.QueryVariables["mgmId"] = managementsWithRelevantImportId[i].Id; - if (ReportType != ReportType.Recertification) - Query.QueryVariables["relevantImportId"] = managementsWithRelevantImportId[i].Import.ImportAggregate.ImportAggregateMax.RelevantImportId ?? -1 /* managment was not yet imported at that time */; - Managements[i] = (await apiConnection.SendQueryAsync(Query.FullQuery, Query.QueryVariables))[0]; - Managements[i].Import = managementsWithRelevantImportId[i].Import; + ObjCategory.all => ObjectQueries.getReportFilteredObjectDetails, + ObjCategory.nobj => ObjectQueries.getReportFilteredNetworkObjectDetails, + ObjCategory.nsrv => ObjectQueries.getReportFilteredNetworkServiceDetails, + ObjCategory.user => ObjectQueries.getReportFilteredUserDetails, + _ => "", + }; + } + + private static void AdditionalFilter(ManagementReport mgt, List relevantObjectIds) + { + mgt.ReportObjects = [.. mgt.ReportObjects.Where(o => relevantObjectIds.Contains(o.Id))]; + } + + public static Rule[] GetRulesByRulebaseId(int rulebaseId, ManagementReport managementReport) + { + Rule[]? rules = managementReport.Rulebases.FirstOrDefault(rb => rb.Id == rulebaseId)?.Rules; + if (rules != null) + { + return rules; } + return []; + } - while (gotNewObjects) + public static Rule[] GetInitialRulesOfGateway(DeviceReport deviceReport, ManagementReport managementReport) + { + int? initialRulebaseId = deviceReport.GetInitialRulebaseId(managementReport); + if (initialRulebaseId != null) { - if (ct.IsCancellationRequested) + Rule[]? rules = GetRulesByRulebaseId((int)initialRulebaseId, managementReport); + if (rules != null) { - Log.WriteDebug("Generate Rules Report", "Task cancelled"); - ct.ThrowIfCancellationRequested(); + return rules; + } + } + return []; + } + + public static Rule[] GetAllRulesOfGateway(DeviceReport deviceReport, ManagementReport managementReport, IRuleTreeBuilder ruleTreeBuilder) + { + if (ruleTreeBuilder.RuleTreeCache.TryGetValue((managementReport.Id, deviceReport.Id), out RuleTreeItem? ruleTreeFromCache)) + { + return ruleTreeBuilder.FlattedRules[ruleTreeFromCache]; + } + else + { + return Array.Empty(); + } + } + + public static int GetRuleCount(ManagementReport mgmReport, RulebaseLink? currentRbLink, RulebaseLink[] rulebaseLinks) + { + RulebaseReport? nextRulebase = mgmReport.GetNextRulebase(currentRbLink); + if (nextRulebase == null) + { + return 0; + } + int ruleCount = 0; + foreach (var rule in nextRulebase.Rules) + { + if (!string.IsNullOrEmpty(rule.SectionHeader)) + { + continue; } - gotNewObjects = false; - Query.QueryVariables["offset"] = (int)Query.QueryVariables["offset"] + rulesPerFetch; - for (i = 0; i < managementsWithRelevantImportId.Length; i++) + RulebaseLink? nextRbLink = rulebaseLinks.FirstOrDefault(rbl => rbl.FromRuleId == rule.Id); + if (nextRbLink != null) { - Query.QueryVariables["mgmId"] = managementsWithRelevantImportId[i].Id; - if (ReportType != ReportType.Recertification) - Query.QueryVariables["relevantImportId"] = managementsWithRelevantImportId[i].Import.ImportAggregate.ImportAggregateMax.RelevantImportId ?? -1; /* managment was not yet imported at that time */; - gotNewObjects |= Managements[i].Merge((await apiConnection.SendQueryAsync(Query.FullQuery, Query.QueryVariables))[0]); + ruleCount += 1 + GetRuleCount(mgmReport, nextRbLink, rulebaseLinks); + } + else + { + ruleCount++; } - await callback(Managements); } - SetReportedRuleIds(); + return ruleCount; } public override string SetDescription() @@ -151,87 +368,85 @@ public override string SetDescription() int managementCounter = 0; int deviceCounter = 0; int ruleCounter = 0; - foreach (Management management in Managements.Where(mgt => !mgt.Ignore && mgt.Devices != null && - Array.Exists(mgt.Devices, device => device.Rules != null && device.Rules.Length > 0))) + foreach (var mgt in ReportData.ManagementData.Where(mgt => !mgt.Ignore && mgt.Devices != null && mgt.ContainsRules())) { managementCounter++; - foreach (Device device in management.Devices.Where(dev => dev.Rules != null && dev.Rules.Length > 0)) + foreach (var device in mgt.Devices.Where(dev => dev.ContainsRules()).Select(d => d.RulebaseLinks)) { deviceCounter++; - ruleCounter += device.Rules!.Length; + ruleCounter += GetRuleCount(mgt, device.FirstOrDefault(_ => _.IsInitial), device); } } return $"{managementCounter} {userConfig.GetText("managements")}, {deviceCounter} {userConfig.GetText("gateways")}, {ruleCounter} {userConfig.GetText("rules")}"; } - private void SetReportedRuleIds() + private string ExportSingleRulebaseToCsv(StringBuilder report, RuleDisplayCsv ruleDisplayCsv, ManagementReport managementReport, DeviceReport gateway, RulebaseLink? rbLink) { - foreach (Management mgt in Managements) + if (rbLink == null) + { + return report.ToString(); + } + foreach (var rule in GetRulesByRulebaseId(rbLink.NextRulebaseId, managementReport)) // just dealing with the first rb for starters { - foreach (Device dev in mgt.Devices.Where(d => (d.Rules != null && d.Rules.Length > 0))) + if (string.IsNullOrEmpty(rule.SectionHeader)) { - foreach (Rule rule in dev.Rules) - { - mgt.ReportedRuleIds.Add(rule.Id); - } + report.Append(ruleDisplayCsv.OutputCsv(managementReport.Name)); + report.Append(ruleDisplayCsv.OutputCsv(gateway.Name)); + report.Append(ruleDisplayCsv.DisplayNumberCsv(rule)); + report.Append(ruleDisplayCsv.DisplayNameCsv(rule)); + report.Append(ruleDisplayCsv.DisplaySourceZoneCsv(rule)); + report.Append(ruleDisplayCsv.DisplaySourceCsv(rule, ReportType)); + report.Append(ruleDisplayCsv.DisplayDestinationZoneCsv(rule)); + report.Append(ruleDisplayCsv.DisplayDestinationCsv(rule, ReportType)); + report.Append(ruleDisplayCsv.DisplayServicesCsv(rule, ReportType)); + report.Append(ruleDisplayCsv.DisplayActionCsv(rule)); + report.Append(ruleDisplayCsv.DisplayTrackCsv(rule)); + report.Append(ruleDisplayCsv.DisplayEnabledCsv(rule)); + report.Append(ruleDisplayCsv.DisplayUidCsv(rule)); + report.Append(ruleDisplayCsv.DisplayCommentCsv(rule)); + report.Append(ruleDisplayCsv.DisplayLastModifiedCsv(rule)); + report = RuleDisplayBase.RemoveLastChars(report, 1); // remove last chars (comma) + report.AppendLine(""); // EO rule } - mgt.ReportedRuleIds = mgt.ReportedRuleIds.Distinct().ToList(); + else + { + //NOSONAR - temporarily disabled //report.AppendLine("\"section header\": \"" + rule.SectionHeader + "\""); + } + ExportSingleRulebaseToCsv(report, ruleDisplayCsv, managementReport, gateway, gateway.RulebaseLinks.FirstOrDefault(_ => _.FromRuleId == rule.Id)); } + return report.ToString(); } public override string ExportToCsv() { - if (ReportType.IsResolvedReport()) + if (!ReportType.IsResolvedReport()) { - StringBuilder report = new StringBuilder(); - RuleDisplayCsv ruleDisplayCsv = new RuleDisplayCsv(userConfig); + throw new NotImplementedException(); + } + StringBuilder report = new(); + RuleDisplayCsv ruleDisplayCsv = new(userConfig); - report.Append(DisplayReportHeaderCsv()); - report.AppendLine($"\"management-name\",\"device-name\",\"rule-number\",\"rule-name\",\"source-zone\",\"source\",\"destination-zone\",\"destination\",\"service\",\"action\",\"track\",\"rule-enabled\",\"rule-uid\",\"rule-comment\""); + report.Append(DisplayReportHeaderCsv()); + report.AppendLine( + $"\"management-name\",\"device-name\",\"rule-number\",\"rule-name\",\"source-zone\",\"source\",\"destination-zone\",\"destination\",\"service\",\"action\",\"track\",\"rule-enabled\",\"rule-uid\",\"rule-comment\",\"last-modified\""); - foreach (Management management in Managements.Where(mgt => !mgt.Ignore && mgt.Devices != null && - Array.Exists(mgt.Devices, device => device.Rules != null && device.Rules.Length > 0))) + var managementReports = ReportData.ManagementData.Where(mgt => !mgt.Ignore && Array.Exists(mgt.Devices, device => device.ContainsRules())); + foreach (var managementReport in managementReports) + { + foreach (var gateway in managementReport.Devices) { - foreach (Device gateway in management.Devices) + if (!gateway.ContainsRules()) { - if (gateway.Rules != null && gateway.Rules.Length > 0) - { - foreach (Rule rule in gateway.Rules) - { - if (string.IsNullOrEmpty(rule.SectionHeader)) - { - report.Append(ruleDisplayCsv.OutputCsv(management.Name)); - report.Append(ruleDisplayCsv.OutputCsv(gateway.Name)); - report.Append(ruleDisplayCsv.DisplayNumberCsv(rule)); - report.Append(ruleDisplayCsv.DisplayNameCsv(rule)); - report.Append(ruleDisplayCsv.DisplaySourceZoneCsv(rule)); - report.Append(ruleDisplayCsv.DisplaySourceCsv(rule, ReportType)); - report.Append(ruleDisplayCsv.DisplayDestinationZoneCsv(rule)); - report.Append(ruleDisplayCsv.DisplayDestinationCsv(rule, ReportType)); - report.Append(ruleDisplayCsv.DisplayServicesCsv(rule, ReportType)); - report.Append(ruleDisplayCsv.DisplayActionCsv(rule)); - report.Append(ruleDisplayCsv.DisplayTrackCsv(rule)); - report.Append(ruleDisplayCsv.DisplayEnabledCsv(rule)); - report.Append(ruleDisplayCsv.DisplayUidCsv(rule)); - report.Append(ruleDisplayCsv.DisplayCommentCsv(rule)); - report = ruleDisplayCsv.RemoveLastChars(report, 1); // remove last chars (comma) - report.AppendLine(""); // EO rule - } - else - { - // report.AppendLine("\"section header\": \"" + rule.SectionHeader + "\""); - } - } // rules - } - } // gateways - } // managements - string reportStr = report.ToString(); - return reportStr; - } - else - { - throw new NotImplementedException(); + continue; + } + + if (gateway.RulebaseLinks.FirstOrDefault(rbl => rbl.IsInitial) is { } rbLink) + { + ExportSingleRulebaseToCsv(report, ruleDisplayCsv, managementReport, gateway, rbLink); + } + } } + return report.ToString(); } public override string ExportToJson() @@ -244,7 +459,7 @@ public override string ExportToJson() } else if (ReportType.IsRuleReport()) { - return System.Text.Json.JsonSerializer.Serialize(Managements.Where(mgt => !mgt.Ignore), new JsonSerializerOptions { WriteIndented = true }); + return System.Text.Json.JsonSerializer.Serialize(ReportData.ManagementData.Where(mgt => !mgt.Ignore), new JsonSerializerOptions { WriteIndented = true }); } else { @@ -254,111 +469,78 @@ public override string ExportToJson() private string ExportResolvedRulesToJson() { - StringBuilder report = new StringBuilder("{"); - report.Append(DisplayReportHeaderJson()); - report.AppendLine("\"managements\": ["); - RuleDisplayJson ruleDisplayJson = new RuleDisplayJson(userConfig); - foreach (Management management in Managements.Where(mgt => !mgt.Ignore && mgt.Devices != null && - Array.Exists(mgt.Devices, device => device.Rules != null && device.Rules.Length > 0))) - { - report.AppendLine($"{{\"{management.Name}\": {{"); - report.AppendLine($"\"gateways\": ["); - foreach (Device gateway in management.Devices) - { - if (gateway.Rules != null && gateway.Rules.Length > 0) - { - report.Append($"{{\"{gateway.Name}\": {{\n\"rules\": ["); - foreach (Rule rule in gateway.Rules) - { - report.Append("{"); - if (string.IsNullOrEmpty(rule.SectionHeader)) - { - report.Append(ruleDisplayJson.DisplayNumber(rule)); - report.Append(ruleDisplayJson.DisplayName(rule.Name)); - report.Append(ruleDisplayJson.DisplaySourceZone(rule.SourceZone?.Name)); - report.Append(ruleDisplayJson.DisplaySourceNegated(rule.SourceNegated)); - report.Append(ruleDisplayJson.DisplaySource(rule, ReportType)); - report.Append(ruleDisplayJson.DisplayDestinationZone(rule.DestinationZone?.Name)); - report.Append(ruleDisplayJson.DisplayDestinationNegated(rule.DestinationNegated)); - report.Append(ruleDisplayJson.DisplayDestination(rule, ReportType)); - report.Append(ruleDisplayJson.DisplayServiceNegated(rule.ServiceNegated)); - report.Append(ruleDisplayJson.DisplayServices(rule, ReportType)); - report.Append(ruleDisplayJson.DisplayAction(rule.Action)); - report.Append(ruleDisplayJson.DisplayTrack(rule.Track)); - report.Append(ruleDisplayJson.DisplayEnabled(rule.Disabled)); - report.Append(ruleDisplayJson.DisplayUid(rule.Uid)); - report.Append(ruleDisplayJson.DisplayComment(rule.Comment)); - report = ruleDisplayJson.RemoveLastChars(report, 1); // remove last chars (comma) - } - else - { - report.AppendLine("\"section header\": \"" + rule.SectionHeader + "\""); - } - report.Append("},"); // EO rule - } // rules - report = ruleDisplayJson.RemoveLastChars(report, 1); // remove last char (comma) - report.Append("]"); // EO rules - report.Append("}"); // EO gateway internal - report.Append("},"); // EO gateway external - } - } // gateways - report = ruleDisplayJson.RemoveLastChars(report, 1); // remove last char (comma) - report.Append("]"); // EO gateways - report.Append("}"); // EO management internal - report.Append("},"); // EO management external - } // managements - report = ruleDisplayJson.RemoveLastChars(report, 1); // remove last char (comma) - report.Append("]"); // EO managements - report.Append("}"); // EO top - - dynamic? json = JsonConvert.DeserializeObject(report.ToString()); - JsonSerializerSettings settings = new JsonSerializerSettings(); - settings.Formatting = Formatting.Indented; - return Newtonsoft.Json.JsonConvert.SerializeObject(json, settings); + RuleDisplayJson ruleDisplayJson = new(userConfig); + TryBuildRuleTree(); + + return ExportToJson( + hasItems: dev => dev.ContainsRules(), + getItems: (dev, mgmt) => _rulesCache[(dev.Id, mgmt.Id)], + renderItem: rule => ruleDisplayJson.DisplayRuleJsonObject(rule, ReportType), + itemsPropertyName: "rules" + ); } public override string ExportToHtml() { - StringBuilder report = new StringBuilder(); - RuleDisplayHtml ruleDisplayHtml = new RuleDisplayHtml(userConfig); + StringBuilder report = new(); + int chapterNumber = 0; + ConstructHtmlReport(ref report, ReportData.ManagementData, chapterNumber); + return GenerateHtmlFrame(userConfig.GetText(ReportType.ToString()), Query.RawFilter, DateTime.Now, report); + } - foreach (Management management in Managements.Where(mgt => !mgt.Ignore && mgt.Devices != null && - Array.Exists(mgt.Devices, device => device.Rules != null && device.Rules.Length > 0))) - { - management.AssignRuleNumbers(); + public void ConstructHtmlReport(ref StringBuilder report, List managementData, int chapterNumber, int levelshift = 0) + { + RuleDisplayHtml ruleDisplayHtml = new(userConfig); + Levelshift = levelshift; - report.AppendLine($"

                      {management.Name}

                      "); + foreach (ManagementReport managementReport in managementData.Where(mgt => !mgt.Ignore && mgt.ContainsRules())) + { + chapterNumber++; + report.AppendLine(Headline(managementReport.Name, 3)); report.AppendLine("
                      "); - foreach (Device device in management.Devices) + if (ReportType.IsRulebaseReport()) + { + foreach (var rulebase in managementReport.Rulebases) + { + AppendRulesForRulebaseHtml(ref report, rulebase, chapterNumber, ruleDisplayHtml); + } + } + else { - if (device.Rules != null && device.Rules.Length > 0) + foreach (var device in managementReport.Devices) { - appendRulesForDeviceHtml(ref report, device, ruleDisplayHtml); + if (device.RulebaseLinks != null) + { + AppendRulesForDeviceHtml(ref report, managementReport, device, chapterNumber, ruleDisplayHtml); + } } } // show all objects used in this management's rules - appendObjectsForManagementHtml(ref report, management); + AppendObjectsForManagementHtml(ref report, chapterNumber, managementReport); } - - return GenerateHtmlFrame(userConfig.GetText(ReportType.ToString()), Query.RawFilter, DateTime.Now, report); } - private void appendRuleHeadlineHtml(ref StringBuilder report) + private void AppendRuleHeadlineHtml(ref StringBuilder report) { report.AppendLine(""); - report.AppendLine($"{userConfig.GetText("number")}"); - if(ReportType == ReportType.Recertification) + if (!ReportType.IsRulebaseReport()) { - report.AppendLine($"{userConfig.GetText("next_recert")}"); + report.AppendLine($"{userConfig.GetText("number")}"); + } + if (ReportType == ReportType.Recertification) + { + report.AppendLine($"{userConfig.GetText("next_recert_date")}"); report.AppendLine($"{userConfig.GetText("owner")}"); report.AppendLine($"{userConfig.GetText("ip_matches")}"); report.AppendLine($"{userConfig.GetText("last_hit")}"); + report.AppendLine("LastModified"); } - if(ReportType == ReportType.UnusedRules) + if (ReportType == ReportType.UnusedRules) { report.AppendLine($"{userConfig.GetText("last_hit")}"); + report.AppendLine("LastModified"); } report.AppendLine($"{userConfig.GetText("name")}"); report.AppendLine($"{userConfig.GetText("source_zone")}"); @@ -371,72 +553,104 @@ private void appendRuleHeadlineHtml(ref StringBuilder report) report.AppendLine($"{userConfig.GetText("enabled")}"); report.AppendLine($"{userConfig.GetText("uid")}"); report.AppendLine($"{userConfig.GetText("comment")}"); + if (ReportType != ReportType.Recertification && ReportType != ReportType.UnusedRules) + { + report.AppendLine("LastModified"); + } report.AppendLine(""); } - private void appendRulesForDeviceHtml(ref StringBuilder report, Device device, RuleDisplayHtml ruleDisplayHtml) + private void AppendRulesForDeviceHtml(ref StringBuilder report, ManagementReport managementReport, DeviceReport device, int chapterNumber, RuleDisplayHtml ruleDisplayHtml) { if (device.ContainsRules()) { - report.AppendLine($"

                      {device.Name}

                      "); - report.AppendLine("
                      "); + report.AppendLine(Headline(device.Name, 4)); report.AppendLine(""); - appendRuleHeadlineHtml(ref report); - foreach (Rule rule in device.Rules!) + AppendRuleHeadlineHtml(ref report); + + RulebaseLink? nextRbLink = device.RulebaseLinks.FirstOrDefault(_ => _.IsInitial); + if (nextRbLink != null) { - if (string.IsNullOrEmpty(rule.SectionHeader)) + foreach (var rule in _rulesCache[(device.Id, managementReport.Id)]) { - report.AppendLine(""); - report.AppendLine($""); - if(ReportType == ReportType.Recertification) - { - report.AppendLine($""); - report.AppendLine($""); - report.AppendLine($""); - report.AppendLine($""); - } - if(ReportType == ReportType.UnusedRules) - { - report.AppendLine($""); - } - report.AppendLine($""); - report.AppendLine($""); - report.AppendLine($""); - report.AppendLine($""); - report.AppendLine($""); - report.AppendLine($""); - report.AppendLine($""); - report.AppendLine($""); - report.AppendLine($""); - report.AppendLine($""); - report.AppendLine($""); - report.AppendLine(""); - } - else - { - report.AppendLine(""); - report.AppendLine($""); - report.AppendLine(""); + AppendRuleHtml(ref report, rule, chapterNumber, ruleDisplayHtml); } } report.AppendLine("
                      {ruleDisplayHtml.DisplayNumber(rule)}{ruleDisplayHtml.DisplayNextRecert(rule)}{ruleDisplayHtml.DisplayOwner(rule)}{ruleDisplayHtml.DisplayRecertIpMatches(rule)}{ruleDisplayHtml.DisplayLastHit(rule)}{ruleDisplayHtml.DisplayLastHit(rule)}{ruleDisplayHtml.DisplayName(rule)}{ruleDisplayHtml.DisplaySourceZone(rule)}{ruleDisplayHtml.DisplaySource(rule, OutputLocation.export, ReportType)}{ruleDisplayHtml.DisplayDestinationZone(rule)}{ruleDisplayHtml.DisplayDestination(rule, OutputLocation.export, ReportType)}{ruleDisplayHtml.DisplayServices(rule, OutputLocation.export, ReportType)}{ruleDisplayHtml.DisplayAction(rule)}{ruleDisplayHtml.DisplayTrack(rule)}{ruleDisplayHtml.DisplayEnabled(rule, OutputLocation.export)}{ruleDisplayHtml.DisplayUid(rule)}{ruleDisplayHtml.DisplayComment(rule)}
                      {rule.SectionHeader}
                      "); + report.AppendLine("
                      "); } } - private void appendObjectsForManagementHtml(ref StringBuilder report, Management management) + private void AppendRulesForRulebaseHtml(ref StringBuilder report, RulebaseReport rulebase, int chapterNumber, RuleDisplayHtml ruleDisplayHtml) { - int objNumber = 1; - appendNetworkObjectsForManagementHtml(ref report, ref objNumber, management); - appendNetworkServicesForManagementHtml(ref report, ref objNumber, management); - appendUsersForManagementHtml(ref report, ref objNumber, management); + if (rulebase.Rules.Length > 0) + { + report.AppendLine(Headline(rulebase.Name, 4)); + report.AppendLine(""); + AppendRuleHeadlineHtml(ref report); + foreach (var rule in rulebase.Rules) + { + AppendRuleHtml(ref report, rule, chapterNumber, ruleDisplayHtml); + } + report.AppendLine("
                      "); + report.AppendLine("
                      "); + } } - private void appendNetworkObjectsForManagementHtml(ref StringBuilder report, ref int objNumber, Management management) + private void AppendRuleHtml(ref StringBuilder report, Rule rule, int chapterNumber, RuleDisplayHtml ruleDisplayHtml) { - if (management.ReportObjects != null && !ReportType.IsResolvedReport()) + report.AppendLine(""); + if (!ReportType.IsRulebaseReport()) { - report.AppendLine($"

                      {userConfig.GetText("network_objects")}

                      "); - report.AppendLine("
                      "); + report.AppendLine($"{RuleDisplayBase.DisplayNumber(rule)}"); + } + if (ReportType == ReportType.Recertification) + { + report.AppendLine($"{RuleDisplayHtml.DisplayNextRecert(rule.Metadata)}"); + report.AppendLine($"{RuleDisplayHtml.DisplayOwner(rule.Metadata)}"); + report.AppendLine($"{RuleDisplayHtml.DisplayRecertIpMatches(rule.Metadata)}"); + report.AppendLine($"{RuleDisplayHtml.DisplayLastHit(rule.Metadata)}"); + report.AppendLine($"{RuleDisplayBase.DisplayLastModified(rule)}"); + } + if (ReportType == ReportType.UnusedRules) + { + report.AppendLine($"{RuleDisplayHtml.DisplayLastHit(rule.Metadata)}"); + report.AppendLine($"{RuleDisplayBase.DisplayLastModified(rule)}"); + } + report.AppendLine($"{RuleDisplayBase.DisplayName(rule)}"); + report.AppendLine($"{RuleDisplayBase.DisplaySourceZones(rule)}"); + report.AppendLine($"{ruleDisplayHtml.DisplaySource(rule, OutputLocation.export, ReportType, chapterNumber)}"); + report.AppendLine($"{RuleDisplayBase.DisplayDestinationZones(rule)}"); + report.AppendLine($"{ruleDisplayHtml.DisplayDestination(rule, OutputLocation.export, ReportType, chapterNumber)}"); + report.AppendLine($"{ruleDisplayHtml.DisplayServices(rule, OutputLocation.export, ReportType, chapterNumber)}"); + report.AppendLine($"{RuleDisplayBase.DisplayAction(rule)}"); + report.AppendLine($"{RuleDisplayBase.DisplayTrack(rule)}"); + report.AppendLine($"{RuleDisplayBase.DisplayEnabled(rule, OutputLocation.export)}"); + report.AppendLine($"{RuleDisplayBase.DisplayUid(rule)}"); + report.AppendLine($"{RuleDisplayBase.DisplayComment(rule)}"); + if (ReportType != ReportType.Recertification && ReportType != ReportType.UnusedRules) + { + report.AppendLine($"{RuleDisplayBase.DisplayLastModified(rule)}"); + } + report.AppendLine(""); + if (ReportType == ReportType.UnusedRules) + { + report.AppendLine(RuleDisplayHtml.DisplaySectionHeader(rule, ColumnCount)); + } + } + + private void AppendObjectsForManagementHtml(ref StringBuilder report, int chapterNumber, ManagementReport managementReport) + { + AppendNetworkObjectsForManagementHtml(ref report, chapterNumber, managementReport); + AppendNetworkServicesForManagementHtml(ref report, chapterNumber, managementReport); + AppendUsersForManagementHtml(ref report, chapterNumber, managementReport); + } + + protected void AppendNetworkObjectsForManagementHtml(ref StringBuilder report, int chapterNumber, ManagementReport managementReport) + { + if (managementReport.ReportObjects != null && managementReport.ReportObjects.Length > 0 && !ReportType.IsResolvedReport()) + { + report.AppendLine(Headline(userConfig.GetText("network_objects"), 4)); report.AppendLine(""); report.AppendLine(""); report.AppendLine($""); @@ -447,31 +661,29 @@ private void appendNetworkObjectsForManagementHtml(ref StringBuilder report, ref report.AppendLine($""); report.AppendLine($""); report.AppendLine(""); - foreach (NetworkObject nwobj in management.ReportObjects) + int objNumber = 1; + foreach (var nwobj in managementReport.ReportObjects) { - report.AppendLine(""); + report.AppendLine($""); report.AppendLine($""); - report.AppendLine($""); - report.AppendLine($""); - report.AppendLine($""); - if (nwobj.MemberNames != null && nwobj.MemberNames.Contains('|')) - report.AppendLine($""); - else - report.AppendLine($""); + report.AppendLine($""); + report.AppendLine($""); + report.AppendLine($""); + report.AppendLine(DisplayBase.MemberNamesAsHtml(nwobj.MemberNames)); report.AppendLine($""); report.AppendLine($""); report.AppendLine(""); } report.AppendLine("
                      {userConfig.GetText("number")}{userConfig.GetText("uid")}{userConfig.GetText("comment")}
                      {objNumber++}{nwobj.Name}{nwobj.Type.Name}{nwobj.IP}{(nwobj.IpEnd != null && nwobj.IpEnd != "" && nwobj.IpEnd != nwobj.IP ? $"-{nwobj.IpEnd}" : "")}{string.Join("
                      ", nwobj.MemberNames.Split('|'))}
                      {nwobj.MemberNames}{nwobj.Name}{(nwobj.Type.Name != "" ? userConfig.GetText(nwobj.Type.Name) : "")}{NwObjDisplay.DisplayIp(nwobj.IP, nwobj.IpEnd, nwobj.Type.Name)}{nwobj.Uid}{nwobj.Comment}
                      "); + report.AppendLine("
                      "); } } - private void appendNetworkServicesForManagementHtml(ref StringBuilder report, ref int objNumber, Management management) + protected void AppendNetworkServicesForManagementHtml(ref StringBuilder report, int chapterNumber, ManagementReport managementReport) { - if (management.ReportServices != null && !ReportType.IsResolvedReport()) + if (managementReport.ReportServices != null && managementReport.ReportServices.Length > 0 && !ReportType.IsResolvedReport()) { - report.AppendLine($"

                      {userConfig.GetText("network_services")}

                      "); - report.AppendLine("
                      "); + report.AppendLine(Headline(userConfig.GetText("network_services"), 4)); report.AppendLine(""); report.AppendLine(""); report.AppendLine($""); @@ -483,36 +695,42 @@ private void appendNetworkServicesForManagementHtml(ref StringBuilder report, re report.AppendLine($""); report.AppendLine($""); report.AppendLine(""); - objNumber = 1; - foreach (NetworkService svcobj in management.ReportServices) + int objNumber = 1; + foreach (var svcobj in managementReport.ReportServices) { - report.AppendLine(""); - report.AppendLine($""); - report.AppendLine($""); - report.AppendLine($""); - report.AppendLine($""); - if (svcobj.DestinationPortEnd != null && svcobj.DestinationPortEnd != svcobj.DestinationPort) - report.AppendLine($""); - else - report.AppendLine($""); - if (svcobj.MemberNames != null && svcobj.MemberNames.Contains("|")) - report.AppendLine($""); - else - report.AppendLine($""); - report.AppendLine($""); - report.AppendLine($""); - report.AppendLine(""); + AppendServiceForManagementHtml(ref report, chapterNumber, objNumber++, svcobj); } report.AppendLine("
                      {userConfig.GetText("number")}{userConfig.GetText("uid")}{userConfig.GetText("comment")}
                      {objNumber++}{svcobj.Name}{svcobj.Name}{((svcobj.Type.Name!="group" && svcobj.Protocol != null) ? svcobj.Protocol.Name : "")}{svcobj.DestinationPort}-{svcobj.DestinationPortEnd}{svcobj.DestinationPort}{string.Join("
                      ", svcobj.MemberNames.Split('|'))}
                      {svcobj.MemberNames}{svcobj.Uid}{svcobj.Comment}
                      "); + report.AppendLine("
                      "); } } - private void appendUsersForManagementHtml(ref StringBuilder report, ref int objNumber, Management management) + private void AppendServiceForManagementHtml(ref StringBuilder report, int chapterNumber, int objNumber, NetworkService svcobj) { - if (management.ReportUsers != null && !ReportType.IsResolvedReport()) + report.AppendLine(""); + report.AppendLine($"{objNumber}"); + report.AppendLine($"{svcobj.Name}"); + report.AppendLine($"{(svcobj.Type.Name != "" ? userConfig.GetText(svcobj.Type.Name) : "")}"); + report.AppendLine($"{((svcobj.Type.Name != ServiceType.Group && svcobj.Protocol != null) ? svcobj.Protocol.Name : "")}"); + if (svcobj.DestinationPortEnd != null && svcobj.DestinationPortEnd != svcobj.DestinationPort) { - report.AppendLine($"

                      {userConfig.GetText("users")}

                      "); - report.AppendLine("
                      "); + report.AppendLine($"{svcobj.DestinationPort}-{svcobj.DestinationPortEnd}"); + } + else + { + report.AppendLine($"{svcobj.DestinationPort}"); + } + report.AppendLine(DisplayBase.MemberNamesAsHtml(svcobj.MemberNames)); + report.AppendLine($"{svcobj.Uid}"); + report.AppendLine($"{svcobj.Comment}"); + report.AppendLine(""); + } + + protected void AppendUsersForManagementHtml(ref StringBuilder report, int chapterNumber, ManagementReport managementReport) + { + if (managementReport.ReportUsers != null && managementReport.ReportUsers.Length > 0 && !ReportType.IsResolvedReport()) + { + report.AppendLine(Headline(userConfig.GetText("users"), 4)); report.AppendLine(""); report.AppendLine(""); report.AppendLine($""); @@ -522,22 +740,20 @@ private void appendUsersForManagementHtml(ref StringBuilder report, ref int objN report.AppendLine($""); report.AppendLine($""); report.AppendLine(""); - objNumber = 1; - foreach (NetworkUser userobj in management.ReportUsers) + int objNumber = 1; + foreach (var userobj in managementReport.ReportUsers) { report.AppendLine(""); report.AppendLine($""); - report.AppendLine($""); - report.AppendLine($""); - if (userobj.MemberNames != null && userobj.MemberNames.Contains("|")) - report.AppendLine($""); - else - report.AppendLine($""); + report.AppendLine($""); + report.AppendLine($""); + report.AppendLine(userobj.MemberNamesAsHtml()); report.AppendLine($""); report.AppendLine($""); report.AppendLine(""); } report.AppendLine("
                      {userConfig.GetText("number")}{userConfig.GetText("uid")}{userConfig.GetText("comment")}
                      {objNumber++}{userobj.Name}{userobj.Name}{string.Join("
                      ", userobj.MemberNames.Split('|'))}
                      {userobj.MemberNames}{userobj.Name}{(userobj.Type.Name != "" ? userConfig.GetText(userobj.Type.Name) : "")}{userobj.Uid}{userobj.Comment}
                      "); + report.AppendLine("
                      "); } } } diff --git a/roles/lib/files/FWO.Report/ReportStatistics.cs b/roles/lib/files/FWO.Report/ReportStatistics.cs index 48b2242c33..4ae205a876 100644 --- a/roles/lib/files/FWO.Report/ReportStatistics.cs +++ b/roles/lib/files/FWO.Report/ReportStatistics.cs @@ -1,40 +1,29 @@ -using FWO.Api.Data; -using System.Text; using FWO.Api.Client; -using FWO.Report.Filter; -using System.Text.Json; +using FWO.Basics; using FWO.Config.Api; +using FWO.Data.Report; using FWO.Logging; +using FWO.Report.Filter; +using System.Text; +using System.Text.Json; namespace FWO.Report { - public class ReportStatistics : ReportBase + public class ReportStatistics : ReportDevicesBase { // TODO: Currently generated in Report.razor as well as here, because of export. Remove dupliacte. - private Management globalStatisticsManagement = new Management(); + private readonly ManagementReport globalStatisticsManagement = new(); public ReportStatistics(DynGraphqlQuery query, UserConfig userConfig, ReportType reportType) : base(query, userConfig, reportType) { } - public override async Task GetObjectsInReport(int objectsPerFetch, ApiConnection apiConnection, Func callback) - { - await callback(Managements); - // currently no further objects to be fetched - GotObjectsInReport = true; - return true; - } - public override Task GetObjectsForManagementInReport(Dictionary objQueryVariables, ObjCategory objects, int maxFetchCycles, ApiConnection apiConnection, Func callback) + public override async Task Generate(int _, ApiConnection apiConnection, Func callback, CancellationToken ct) { - return Task.FromResult(true); - } + List managementsWithRelevantImportId = await GetRelevantImportIds(apiConnection); - public override async Task Generate(int _, ApiConnection apiConnection, Func callback, CancellationToken ct) - { - Management[] managementsWithRelevantImportId = await getRelevantImportIds(apiConnection); + ReportData.ManagementData = []; - List resultList = new List(); - - foreach (Management relevantMgmt in managementsWithRelevantImportId) + foreach (var relevantMgmt in managementsWithRelevantImportId) { if (ct.IsCancellationRequested) { @@ -43,49 +32,47 @@ public override async Task Generate(int _, ApiConnection apiConnection, Func(Query.FullQuery, Query.QueryVariables))[0]); + Query.QueryVariables[QueryVar.MgmId] = relevantMgmt.Id; + Query.QueryVariables[QueryVar.ImportIdStart] = relevantMgmt.Import.ImportAggregate.ImportAggregateMax.RelevantImportId ?? -1 /* managment was not yet imported at that time */; + Query.QueryVariables[QueryVar.ImportIdEnd] = relevantMgmt.Import.ImportAggregate.ImportAggregateMax.RelevantImportId ?? -1 /* managment was not yet imported at that time */; + ReportData.ManagementData.Add((await apiConnection.SendQueryAsync>(Query.FullQuery, Query.QueryVariables))[0]); } - Managements = resultList.ToArray(); - await callback(Managements); + await callback(ReportData); - foreach (Management mgm in Managements.Where(mgt => !mgt.Ignore)) + foreach (ManagementReport mgm in ReportData.ManagementData.Where(mgt => !mgt.Ignore)) { + mgm.EnforceValidity(); globalStatisticsManagement.RuleStatistics.ObjectAggregate.ObjectCount += mgm.RuleStatistics.ObjectAggregate.ObjectCount; globalStatisticsManagement.NetworkObjectStatistics.ObjectAggregate.ObjectCount += mgm.NetworkObjectStatistics.ObjectAggregate.ObjectCount; globalStatisticsManagement.ServiceObjectStatistics.ObjectAggregate.ObjectCount += mgm.ServiceObjectStatistics.ObjectAggregate.ObjectCount; globalStatisticsManagement.UserObjectStatistics.ObjectAggregate.ObjectCount += mgm.UserObjectStatistics.ObjectAggregate.ObjectCount; + globalStatisticsManagement.UnusedRulesStatistics.ObjectAggregate.ObjectCount += mgm.UnusedRulesStatistics.ObjectAggregate.ObjectCount; } } + public override Task GetObjectsForManagementInReport(Dictionary objQueryVariables, ObjCategory objects, int maxFetchCycles, ApiConnection apiConnection, Func callback) + { + return Task.FromResult(true); + } + public override string ExportToJson() { globalStatisticsManagement.Name = "global statistics"; - Management[] combinedManagements = (new Management[] { globalStatisticsManagement }).Concat(Managements.Where(mgt => !mgt.Ignore)).ToArray(); + List combinedManagements = new() { globalStatisticsManagement }; + combinedManagements.AddRange(ReportData.ManagementData.Where(mgt => !mgt.Ignore)); return JsonSerializer.Serialize(combinedManagements, new JsonSerializerOptions { WriteIndented = true }); } public override string ExportToCsv() { - StringBuilder csvBuilder = new StringBuilder(); - - foreach (Management management in Managements.Where(mgt => !mgt.Ignore)) - { - //foreach (var item in collection) - //{ - - //} - } - throw new NotImplementedException(); } public override string ExportToHtml() { - StringBuilder report = new StringBuilder(); + StringBuilder report = new(); - report.AppendLine($"

                      {userConfig.GetText("glob_no_obj")}

                      "); + report.AppendLine($"

                      {userConfig.GetText("glob_no_obj")}

                      "); report.AppendLine(""); report.AppendLine(""); report.AppendLine($""); @@ -97,14 +84,14 @@ public override string ExportToHtml() report.AppendLine($""); report.AppendLine($""); report.AppendLine($""); - report.AppendLine($""); + report.AppendLine($""); report.AppendLine(""); report.AppendLine("
                      {userConfig.GetText("network_objects")}{globalStatisticsManagement.NetworkObjectStatistics.ObjectAggregate.ObjectCount}{globalStatisticsManagement.ServiceObjectStatistics.ObjectAggregate.ObjectCount}{globalStatisticsManagement.UserObjectStatistics.ObjectAggregate.ObjectCount}{globalStatisticsManagement.RuleStatistics.ObjectAggregate.ObjectCount }{globalStatisticsManagement.RuleStatistics.ObjectAggregate.ObjectCount}
                      "); report.AppendLine("
                      "); - foreach (Management management in Managements.Where(mgt => !mgt.Ignore)) + foreach (ManagementReport managementReport in ReportData.ManagementData.Where(mgt => !mgt.Ignore)) { - report.AppendLine($"

                      {userConfig.GetText("no_of_obj")} - {management.Name}

                      "); + report.AppendLine($"

                      {userConfig.GetText("no_of_obj")} - {managementReport.Name}

                      "); report.AppendLine(""); report.AppendLine(""); report.AppendLine($""); @@ -113,21 +100,21 @@ public override string ExportToHtml() report.AppendLine($""); report.AppendLine(""); report.AppendLine(""); - report.AppendLine($""); - report.AppendLine($""); - report.AppendLine($""); - report.AppendLine($""); + report.AppendLine($""); + report.AppendLine($""); + report.AppendLine($""); + report.AppendLine($""); report.AppendLine(""); report.AppendLine("
                      {userConfig.GetText("network_objects")}{userConfig.GetText("rules")}
                      {management.NetworkObjectStatistics.ObjectAggregate.ObjectCount}{management.ServiceObjectStatistics.ObjectAggregate.ObjectCount}{management.UserObjectStatistics.ObjectAggregate.ObjectCount}{management.RuleStatistics.ObjectAggregate.ObjectCount }{managementReport.NetworkObjectStatistics.ObjectAggregate.ObjectCount}{managementReport.ServiceObjectStatistics.ObjectAggregate.ObjectCount}{managementReport.UserObjectStatistics.ObjectAggregate.ObjectCount}{managementReport.RuleStatistics.ObjectAggregate.ObjectCount}
                      "); report.AppendLine("
                      "); - report.AppendLine($"

                      {userConfig.GetText("no_rules_gtw")}

                      "); + report.AppendLine($"

                      {userConfig.GetText("no_rules_gtw")}

                      "); report.AppendLine(""); report.AppendLine(""); report.AppendLine($""); report.AppendLine($""); report.AppendLine(""); - foreach (Device device in management.Devices) + foreach (var device in managementReport.Devices) { if (device.RuleStatistics != null) { diff --git a/roles/lib/files/FWO.Report/ReportTicketChanges.cs b/roles/lib/files/FWO.Report/ReportTicketChanges.cs new file mode 100644 index 0000000000..735553cc52 --- /dev/null +++ b/roles/lib/files/FWO.Report/ReportTicketChanges.cs @@ -0,0 +1,180 @@ +using FWO.Basics; +using FWO.Config.Api; +using FWO.Data.Report; +using FWO.Data.Workflow; +using FWO.Report.Filter; + +namespace FWO.Report +{ + /// + /// Generates workflow ticket change reports. + /// + public class ReportTicketChanges(DynGraphqlQuery query, UserConfig userConfig, ReportType reportType, WorkflowFilter workflowFilter) + : ReportTicketsBase(query, userConfig, reportType, workflowFilter) + { + /// + protected override List GetDisplayedTasks(WfTicket ticket) + { + if (!ReportData.WorkflowFilter.DetailedView) + { + return []; + } + + return GetReferenceTasks(ticket); + } + + /// + protected override List GetReferenceTasks(WfTicket ticket) + { + if (ReportData.WorkflowFilter.ShowFullTicket) + { + return FilterTasksByTaskType(ticket.Tasks); + } + + List tasks = ReportData.WorkflowFilter.ReferenceDate switch + { + WorkflowReferenceDate.TicketCreation => ticket.Tasks.ToList(), + WorkflowReferenceDate.TicketClosure => ticket.Tasks.ToList(), + WorkflowReferenceDate.TaskStart => ticket.Tasks.Where(task => WorkflowTicketReferenceHelper.IsInSelectedTimeRange(task.Start, GetTicketTimeStart(), GetTicketTimeEnd())).ToList(), + WorkflowReferenceDate.TaskEnd => ticket.Tasks.Where(task => WorkflowTicketReferenceHelper.IsInSelectedTimeRange(task.Stop, GetTicketTimeStart(), GetTicketTimeEnd())).ToList(), + WorkflowReferenceDate.ApprovalOpened => ticket.Tasks.Where(task => GetReferenceApprovals(task).Count > 0).ToList(), + WorkflowReferenceDate.Approved => ticket.Tasks.Where(task => GetReferenceApprovals(task).Count > 0).ToList(), + WorkflowReferenceDate.ImplementationStart => ticket.Tasks.Where(task => GetReferenceImplementationTasks(task).Count > 0).ToList(), + WorkflowReferenceDate.ImplementationEnd => ticket.Tasks.Where(task => GetReferenceImplementationTasks(task).Count > 0).ToList(), + WorkflowReferenceDate.AnyActivity => ticket.Tasks.Where(task => + WorkflowTicketReferenceHelper.IsInSelectedTimeRange(task.Start, GetTicketTimeStart(), GetTicketTimeEnd()) + || WorkflowTicketReferenceHelper.IsInSelectedTimeRange(task.Stop, GetTicketTimeStart(), GetTicketTimeEnd()) || + GetReferenceImplementationTasks(task).Count > 0 || GetReferenceApprovals(task).Count > 0).ToList(), + _ => [] + }; + + return FilterTasksByTaskType(tasks); + } + + /// + protected override bool ShowImplementationTasks() + { + if (!ReportData.WorkflowFilter.DetailedView) + { + return false; + } + + return ReportData.WorkflowFilter.ShowFullTicket + || ReportData.WorkflowFilter.ReferenceDate == WorkflowReferenceDate.ImplementationStart + || ReportData.WorkflowFilter.ReferenceDate == WorkflowReferenceDate.ImplementationEnd + || ReportData.WorkflowFilter.ReferenceDate == WorkflowReferenceDate.AnyActivity; + } + + /// + protected override bool ShowApprovals() + { + if (!ReportData.WorkflowFilter.DetailedView) + { + return false; + } + + return ReportData.WorkflowFilter.ShowFullTicket + || ReportData.WorkflowFilter.ReferenceDate == WorkflowReferenceDate.ApprovalOpened + || ReportData.WorkflowFilter.ReferenceDate == WorkflowReferenceDate.Approved + || ReportData.WorkflowFilter.ReferenceDate == WorkflowReferenceDate.AnyActivity; + } + + /// + protected override List GetDisplayedImplementationTasks(WfReqTask task) + { + if (!ReportData.WorkflowFilter.DetailedView) + { + return []; + } + + return GetReferenceImplementationTasks(task); + } + + /// + protected override List GetReferenceImplementationTasks(WfReqTask task) + { + if (ReportData.WorkflowFilter.ShowFullTicket) + { + return task.ImplementationTasks.OrderBy(implTask => implTask.Id).ToList(); + } + + List implementationTasks = ReportData.WorkflowFilter.ReferenceDate switch + { + WorkflowReferenceDate.ImplementationStart => task.ImplementationTasks.Where(implTask => WorkflowTicketReferenceHelper.IsInSelectedTimeRange(implTask.Start, GetTicketTimeStart(), GetTicketTimeEnd())).ToList(), + WorkflowReferenceDate.ImplementationEnd => task.ImplementationTasks.Where(implTask => WorkflowTicketReferenceHelper.IsInSelectedTimeRange(implTask.Stop, GetTicketTimeStart(), GetTicketTimeEnd())).ToList(), + WorkflowReferenceDate.AnyActivity => task.ImplementationTasks.Where(implTask => + WorkflowTicketReferenceHelper.IsInSelectedTimeRange(implTask.Start, GetTicketTimeStart(), GetTicketTimeEnd()) + || WorkflowTicketReferenceHelper.IsInSelectedTimeRange(implTask.Stop, GetTicketTimeStart(), GetTicketTimeEnd())).ToList(), + _ => [] + }; + + return implementationTasks.OrderBy(implTask => implTask.Id).ToList(); + } + + /// + protected override List GetDisplayedApprovals(WfReqTask task) + { + if (!ReportData.WorkflowFilter.DetailedView) + { + return []; + } + + return GetReferenceApprovals(task); + } + + /// + protected override List GetReferenceApprovals(WfReqTask task) + { + if (ReportData.WorkflowFilter.ShowFullTicket) + { + return task.Approvals.OrderBy(approval => approval.Id).ToList(); + } + + List approvals = ReportData.WorkflowFilter.ReferenceDate switch + { + WorkflowReferenceDate.ApprovalOpened => task.Approvals.Where(approval => WorkflowTicketReferenceHelper.IsInSelectedTimeRange(approval.DateOpened, GetTicketTimeStart(), GetTicketTimeEnd())).ToList(), + WorkflowReferenceDate.Approved => task.Approvals.Where(approval => WorkflowTicketReferenceHelper.IsInSelectedTimeRange(approval.ApprovalDate, GetTicketTimeStart(), GetTicketTimeEnd())).ToList(), + WorkflowReferenceDate.AnyActivity => task.Approvals.Where(approval => + WorkflowTicketReferenceHelper.IsInSelectedTimeRange(approval.DateOpened, GetTicketTimeStart(), GetTicketTimeEnd()) + || WorkflowTicketReferenceHelper.IsInSelectedTimeRange(approval.ApprovalDate, GetTicketTimeStart(), GetTicketTimeEnd())).ToList(), + _ => [] + }; + + return approvals.OrderBy(approval => approval.Id).ToList(); + } + + /// + protected override IEnumerable GetReferenceActivityDates(WfReqTask task) + { + return WorkflowTicketReferenceHelper.GetActivityDates( + task, + false, + date => WorkflowTicketReferenceHelper.IsInSelectedTimeRange(date, GetTicketTimeStart(), GetTicketTimeEnd())); + } + + /// + protected override IEnumerable GetTicketReferenceActivityDates(WfTicket ticket) + { + return new DateTime?[] { ticket.CreationDate, ticket.CompletionDate } + .Where(date => WorkflowTicketReferenceHelper.IsInSelectedTimeRange(date, GetTicketTimeStart(), GetTicketTimeEnd())); + } + + private string? GetTicketTimeStart() + { + return Query.QueryVariables.TryGetValue("ticket_time_start", out object? startObj) ? startObj?.ToString() : null; + } + + private string? GetTicketTimeEnd() + { + return Query.QueryVariables.TryGetValue("ticket_time_end", out object? endObj) ? endObj?.ToString() : null; + } + + private List FilterTasksByTaskType(IEnumerable tasks) + { + return tasks + .Where(task => ReportData.WorkflowFilter.TaskTypes.Count == 0 || ReportData.WorkflowFilter.TaskTypes.Any(taskType => task.TaskType == taskType.ToString())) + .OrderBy(task => task.Id) + .ToList(); + } + } +} diff --git a/roles/lib/files/FWO.Report/ReportTickets.cs b/roles/lib/files/FWO.Report/ReportTickets.cs new file mode 100644 index 0000000000..2d81aff637 --- /dev/null +++ b/roles/lib/files/FWO.Report/ReportTickets.cs @@ -0,0 +1,58 @@ +using FWO.Basics; +using FWO.Config.Api; +using FWO.Data.Report; +using FWO.Data.Workflow; +using FWO.Report.Filter; + +namespace FWO.Report +{ + /// + /// Generates workflow ticket reports. + /// + public class ReportTickets(DynGraphqlQuery query, UserConfig userConfig, ReportType reportType, WorkflowFilter workflowFilter) + : ReportTicketsBase(query, userConfig, reportType, workflowFilter) + { + /// + protected override List GetDisplayedTasks(WfTicket ticket) + { + if (!ReportData.WorkflowFilter.DetailedView) + { + return []; + } + + if (ReportData.WorkflowFilter.ShowFullTicket) + { + return ticket.Tasks.OrderBy(task => task.Id).ToList(); + } + + return ticket.Tasks + .Where(task => ReportData.WorkflowFilter.TaskTypes.Count == 0 || ReportData.WorkflowFilter.TaskTypes.Any(taskType => task.TaskType == taskType.ToString())) + .OrderBy(task => task.Id) + .ToList(); + } + + /// + protected override bool ShowImplementationTasks() + { + return true; + } + + /// + protected override bool ShowApprovals() + { + return true; + } + + /// + protected override List GetDisplayedImplementationTasks(WfReqTask task) + { + return task.ImplementationTasks.OrderBy(implTask => implTask.Id).ToList(); + } + + /// + protected override List GetDisplayedApprovals(WfReqTask task) + { + return task.Approvals.OrderBy(approval => approval.Id).ToList(); + } + } +} diff --git a/roles/lib/files/FWO.Report/ReportTicketsBase.cs b/roles/lib/files/FWO.Report/ReportTicketsBase.cs new file mode 100644 index 0000000000..9a06a93f26 --- /dev/null +++ b/roles/lib/files/FWO.Report/ReportTicketsBase.cs @@ -0,0 +1,565 @@ +using FWO.Api.Client; +using FWO.Api.Client.Queries; +using FWO.Basics; +using FWO.Config.Api; +using FWO.Data; +using FWO.Data.Report; +using FWO.Data.Workflow; +using FWO.Logging; +using FWO.Report.Filter; +using FWO.Services.Workflow; +using System.Text; +using System.Text.Json; + +namespace FWO.Report +{ + /// + /// Shared base for workflow ticket reports. + /// + public abstract class ReportTicketsBase(DynGraphqlQuery query, UserConfig userConfig, ReportType reportType, WorkflowFilter workflowFilter) + : ReportBase(query, userConfig, reportType) + { + /// + public override async Task Generate(int elementsPerFetch, ApiConnection apiConnection, Func callback, CancellationToken ct) + { + await ResolvePhaseFilterAsync(apiConnection); + List tickets = await apiConnection.SendQueryAsync>(Query.FullQuery, Query.QueryVariables); + tickets = await FilterVisibleTicketsAsync(apiConnection, tickets); + List workflowStates = await apiConnection.SendQueryAsync>(RequestQueries.getStates); + ReportData.WorkflowStateNames = workflowStates.ToDictionary(state => state.Id, state => state.Name); + ReportData.WorkflowFilter = new(workflowFilter); + ReportData.Tickets = tickets; + ReportData.TicketReferenceDates = BuildTicketReferenceDates(tickets); + ReportData.ElementsCount = tickets.Count; + await callback(ReportData); + } + + /// + /// Applies the same owner-based workflow visibility rule used by the request pages. + /// + private async Task> FilterVisibleTicketsAsync(ApiConnection apiConnection, List tickets) + { + int ticketCountBeforeFilter = tickets.Count; + if (!userConfig.ReqOwnerBased + || userConfig.User.Roles.Contains(Roles.Admin) + || userConfig.User.Roles.Contains(Roles.Auditor)) + { + Log.WriteDebug("Workflow Report Filter", $"Skipping owner-based filtering: reqOwnerBased={userConfig.ReqOwnerBased}, userId={userConfig.User.DbId}, roles=[{string.Join(", ", userConfig.User.Roles)}], ticketCount={ticketCountBeforeFilter}"); + return tickets; + } + + if (userConfig.User.Ownerships.Count == 0) + { + Log.WriteDebug("Workflow Report Filter", $"Owner-based filtering removed all tickets because no ownerships were available: reqOwnerBased={userConfig.ReqOwnerBased}, userId={userConfig.User.DbId}, roles=[{string.Join(", ", userConfig.User.Roles)}], ticketCountBefore={ticketCountBeforeFilter}"); + return []; + } + + List registeredTickets = (await apiConnection.SendQueryAsync>( + RequestQueries.getOwnerTicketIds, + new { ownerIds = userConfig.User.Ownerships })) + .ConvertAll(ticket => ticket.Id); + + List visibleTickets = [.. tickets.Where(ticket => ticket.IsVisibleForOwner(registeredTickets, userConfig.User.Ownerships, userConfig.User.DbId))]; + Log.WriteDebug("Workflow Report Filter", $"Applied owner-based filtering: reqOwnerBased={userConfig.ReqOwnerBased}, userId={userConfig.User.DbId}, roles=[{string.Join(", ", userConfig.User.Roles)}], ownershipCount={userConfig.User.Ownerships.Count}, ownerIds=[{string.Join(", ", userConfig.User.Ownerships)}], registeredTicketCount={registeredTickets.Count}, ticketCountBefore={ticketCountBeforeFilter}, ticketCountAfter={visibleTickets.Count}"); + return visibleTickets; + } + + /// + public override string ExportToCsv() + { + if (ReportData.WorkflowFilter.DetailedView) + { + throw new NotImplementedException("CSV export is only supported for workflow reports with detailed view disabled."); + } + + StringBuilder report = new(); + report.Append(DisplayWorkflowReportHeaderCsv()); + report.Append($"\"{userConfig.GetText("id")}\","); + report.Append($"\"{userConfig.GetText("name")}\","); + report.Append($"\"{userConfig.GetText("tasks")}\","); + report.Append($"\"{userConfig.GetText("requester")}\","); + report.Append($"\"{userConfig.GetText("state")}\","); + report.Append($"\"{userConfig.GetText("ticket")} {userConfig.GetText("created")}\","); + report.Append($"\"{userConfig.GetText("ticket")} {userConfig.GetText("closed")}\""); + if (HasReferenceDateColumn()) + { + report.Append($",\"{userConfig.GetText(ReportData.WorkflowFilter.ReferenceDate.ToString())}\""); + } + if (HasLabelColumn()) + { + report.Append($",\"{workflowFilter.LabelFilter.Name}\""); + } + report.AppendLine(""); + + foreach (WfTicket ticket in GetSortedTickets()) + { + report.Append(OutputCsv(ticket.Id.ToString())); + report.Append(OutputCsv(ticket.Title)); + report.Append(OutputCsv(ticket.Tasks.Count.ToString())); + report.Append(OutputCsv(ticket.Requester?.Name)); + report.Append(OutputCsv(ResolveStateName(ticket.StateId))); + report.Append(OutputCsv(ticket.CreationDate.ToString())); + report.Append(OutputCsv(ticket.CompletionDate.ToString())); + if (HasReferenceDateColumn()) + { + report.Append(OutputCsv(GetTicketReferenceDateValue(ticket))); + } + if (HasLabelColumn()) + { + report.Append(OutputCsv(GetLabelValue(ticket))); + } + report.Length--; + report.AppendLine(""); + } + + return report.ToString(); + } + + /// + public override string ExportToJson() + { + return JsonSerializer.Serialize(ReportData.Tickets, new JsonSerializerOptions { WriteIndented = true }); + } + + /// + public override string ExportToHtml() + { + StringBuilder report = new(); + report.AppendLine("
                      {userConfig.GetText("gateway")}{userConfig.GetText("rules")}
                      "); + AppendTicketTableHeader(report); + + foreach (WfTicket ticket in GetSortedTickets()) + { + AppendTicketRow(report, ticket); + AppendTaskDetailsSection(report, ticket); + } + + report.AppendLine("
                      "); + return GenerateHtmlFrameBase(userConfig.GetText(ReportType.ToString()), Query.RawFilter, DateTime.Now, report, BuildWorkflowFilterSummary()); + } + + /// + public override string SetDescription() + { + return $"{ReportData.Tickets.Count} {userConfig.GetText("tickets")}"; + } + + /// + /// Selects the request tasks to display for one ticket. + /// + protected abstract List GetDisplayedTasks(WfTicket ticket); + + /// + /// Indicates whether implementation tasks should be rendered. + /// + protected abstract bool ShowImplementationTasks(); + + /// + /// Indicates whether approvals should be rendered. + /// + protected abstract bool ShowApprovals(); + + /// + /// Selects the implementation tasks to display for one request task. + /// + protected abstract List GetDisplayedImplementationTasks(WfReqTask task); + + /// + /// Selects the approvals to display for one request task. + /// + protected abstract List GetDisplayedApprovals(WfReqTask task); + + /// + /// Selects the request tasks that match the reference-date filter, independent of nested detail visibility. + /// + protected virtual List GetReferenceTasks(WfTicket ticket) + { + return GetDisplayedTasks(ticket); + } + + /// + /// Selects implementation tasks that match the reference-date filter, independent of nested detail visibility. + /// + protected virtual List GetReferenceImplementationTasks(WfReqTask task) + { + return GetDisplayedImplementationTasks(task); + } + + /// + /// Selects approvals that match the reference-date filter, independent of nested detail visibility. + /// + protected virtual List GetReferenceApprovals(WfReqTask task) + { + return GetDisplayedApprovals(task); + } + + private string ResolveStateName(int stateId) + { + return ReportData.WorkflowStateNames.TryGetValue(stateId, out string? stateName) ? stateName : stateId.ToString(); + } + + private void AppendTicketTableHeader(StringBuilder report) + { + report.AppendLine(""); + report.AppendLine($"{userConfig.GetText("id")}"); + report.AppendLine($"{userConfig.GetText("name")}"); + report.AppendLine($"{userConfig.GetText("tasks")}"); + report.AppendLine($"{userConfig.GetText("requester")}"); + report.AppendLine($"{userConfig.GetText("state")}"); + report.AppendLine($"{userConfig.GetText("ticket")} {userConfig.GetText("created")}"); + report.AppendLine($"{userConfig.GetText("ticket")} {userConfig.GetText("closed")}"); + if (HasReferenceDateColumn()) + { + report.AppendLine($"{userConfig.GetText(ReportData.WorkflowFilter.ReferenceDate.ToString())}"); + } + if (HasLabelColumn()) + { + report.AppendLine($"{workflowFilter.LabelFilter.Name}"); + } + report.AppendLine(""); + } + + private void AppendTicketRow(StringBuilder report, WfTicket ticket) + { + report.AppendLine(""); + report.AppendLine($"{ticket.Id}"); + report.AppendLine($"{ticket.Title}"); + report.AppendLine($"{ticket.Tasks.Count}"); + report.AppendLine($"{ticket.Requester?.Name}"); + report.AppendLine($"{ResolveStateName(ticket.StateId)}"); + report.AppendLine($"{ticket.CreationDate}"); + report.AppendLine($"{ticket.CompletionDate}"); + if (HasReferenceDateColumn()) + { + report.AppendLine($"{GetTicketReferenceDateValue(ticket)}"); + } + if (HasLabelColumn()) + { + report.AppendLine($"{GetLabelValue(ticket)}"); + } + report.AppendLine(""); + } + + private void AppendTaskDetailsSection(StringBuilder report, WfTicket ticket) + { + List displayedTasks = GetDisplayedTasks(ticket); + if (displayedTasks.Count == 0) + { + return; + } + + report.AppendLine($""); + report.AppendLine($"{userConfig.GetText("tasks")}"); + report.AppendLine(""); + AppendTaskTableHeader(report); + + foreach (WfReqTask task in displayedTasks) + { + AppendTaskRow(report, task); + AppendImplementationTasks(report, task); + AppendApprovals(report, task); + } + + report.AppendLine("
                      "); + report.AppendLine(""); + } + + private void AppendTaskTableHeader(StringBuilder report) + { + report.AppendLine(""); + report.AppendLine($"{userConfig.GetText("id")}"); + report.AppendLine($"{userConfig.GetText("task_number")}"); + report.AppendLine($"{userConfig.GetText("name")}"); + report.AppendLine($"{userConfig.GetText("state")}"); + report.AppendLine($"{userConfig.GetText("start_time")}"); + report.AppendLine($"{userConfig.GetText("end_time")}"); + report.AppendLine(""); + } + + private void AppendTaskRow(StringBuilder report, WfReqTask task) + { + report.AppendLine(""); + report.AppendLine($"{task.Id}"); + report.AppendLine($"{task.TaskNumber}"); + report.AppendLine($"{task.Title}"); + report.AppendLine($"{ResolveStateName(task.StateId)}"); + report.AppendLine($"{task.Start}"); + report.AppendLine($"{task.Stop}"); + report.AppendLine(""); + } + + private void AppendImplementationTasks(StringBuilder report, WfReqTask task) + { + if (!ShowImplementationTasks()) + { + return; + } + + List implementationTasks = GetDisplayedImplementationTasks(task); + if (implementationTasks.Count == 0) + { + return; + } + + report.AppendLine($"{userConfig.GetText("implementation")}"); + report.AppendLine(""); + report.AppendLine(""); + report.AppendLine($""); + report.AppendLine($""); + report.AppendLine($""); + report.AppendLine($""); + report.AppendLine($""); + report.AppendLine($""); + report.AppendLine(""); + + foreach (WfImplTask implTask in implementationTasks) + { + report.AppendLine(""); + report.AppendLine($""); + report.AppendLine($""); + report.AppendLine($""); + report.AppendLine($""); + report.AppendLine($""); + report.AppendLine($""); + report.AppendLine(""); + } + + report.AppendLine("
                      {userConfig.GetText("id")}{userConfig.GetText("task_number")}{userConfig.GetText("name")}{userConfig.GetText("state")}{userConfig.GetText("start_time")}{userConfig.GetText("end_time")}
                      {implTask.Id}{implTask.TaskNumber}{implTask.Title}{ResolveStateName(implTask.StateId)}{implTask.Start}{implTask.Stop}
                      "); + } + + private void AppendApprovals(StringBuilder report, WfReqTask task) + { + if (!ShowApprovals()) + { + return; + } + + List approvals = GetDisplayedApprovals(task); + if (approvals.Count == 0) + { + return; + } + + report.AppendLine($"{userConfig.GetText("approval")}"); + report.AppendLine(""); + report.AppendLine(""); + report.AppendLine($""); + report.AppendLine($""); + report.AppendLine($""); + report.AppendLine($""); + report.AppendLine($""); + report.AppendLine(""); + + foreach (WfApproval approval in approvals) + { + report.AppendLine(""); + report.AppendLine($""); + report.AppendLine($""); + report.AppendLine($""); + report.AppendLine($""); + report.AppendLine($""); + report.AppendLine(""); + } + + report.AppendLine("
                      {userConfig.GetText("id")}{userConfig.GetText("name")}{userConfig.GetText("state")}{userConfig.GetText("opened")}{userConfig.GetText("approved")}
                      {approval.Id}{approval.ApproverGroup}{ResolveStateName(approval.StateId)}{approval.DateOpened}{approval.ApprovalDate}
                      "); + } + + private bool HasLabelColumn() + { + return !string.IsNullOrWhiteSpace(workflowFilter.LabelFilter.Name); + } + + private bool HasReferenceDateColumn() + { + return ReportType == ReportType.TicketChangeReport; + } + + private string GetTicketReferenceDateValue(WfTicket ticket) + { + DateTime? referenceDate = GetStoredTicketReferenceDate(ticket); + return referenceDate?.ToString() ?? ""; + } + + private IEnumerable GetSortedTickets() + { + if (!HasReferenceDateColumn()) + { + return ReportData.Tickets.OrderBy(ticket => ticket.Id); + } + + return ReportData.Tickets + .OrderByDescending(ticket => GetStoredTicketReferenceDate(ticket).HasValue) + .ThenByDescending(GetStoredTicketReferenceDate) + .ThenByDescending(ticket => ticket.Id); + } + + /// + /// Selects activity timestamps that match the reference-date filter for one ticket. + /// + protected virtual IEnumerable GetTicketReferenceActivityDates(WfTicket ticket) + { + return []; + } + + /// + /// Selects activity timestamps that match the reference-date filter for one request task. + /// + protected virtual IEnumerable GetReferenceActivityDates(WfReqTask task) + { + return []; + } + + private Dictionary BuildTicketReferenceDates(IEnumerable tickets) + { + if (!HasReferenceDateColumn()) + { + return []; + } + + return tickets.ToDictionary(ticket => ticket.Id, ResolveTicketReferenceDate); + } + + private DateTime? ResolveTicketReferenceDate(WfTicket ticket) + { + return WorkflowTicketReferenceHelper.GetTicketReferenceDate( + ticket, + ReportData.WorkflowFilter.ReferenceDate, + GetReferenceTasks, + GetReferenceApprovals, + GetReferenceImplementationTasks, + GetTicketReferenceActivityDates, + GetReferenceActivityDates); + } + + private DateTime? GetStoredTicketReferenceDate(WfTicket ticket) + { + return ReportData.TicketReferenceDates.TryGetValue(ticket.Id, out DateTime? referenceDate) + ? referenceDate + : ResolveTicketReferenceDate(ticket); + } + + private int GetTicketColumnCount() + { + int ticketColumnCount = HasLabelColumn() ? 8 : 7; + return HasReferenceDateColumn() ? ticketColumnCount + 1 : ticketColumnCount; + } + + private string BuildWorkflowFilterSummary() + { + List filterParts = []; + int allRealTaskTypesCount = Enum.GetValues(typeof(WfTaskType)).Cast().Count(taskType => taskType != WfTaskType.master); + + if (ReportType == ReportType.TicketChangeReport && ReportData.WorkflowFilter.ReferenceDate != WorkflowReferenceDate.AnyActivity) + { + filterParts.Add($"{userConfig.GetText("reference_date")}: {userConfig.GetText(ReportData.WorkflowFilter.ReferenceDate.ToString())}"); + } + + if (ReportData.WorkflowFilter.TaskTypes.Count > 0 && ReportData.WorkflowFilter.TaskTypes.Count < allRealTaskTypesCount) + { + string taskTypes = string.Join(", ", ReportData.WorkflowFilter.TaskTypes.Select(taskType => userConfig.GetText(taskType.ToString()))); + filterParts.Add($"{userConfig.GetText("task_type")}: {taskTypes}"); + } + + if (!string.IsNullOrWhiteSpace(ReportData.WorkflowFilter.Phase)) + { + filterParts.Add($"{userConfig.GetText("phase")}: {userConfig.GetText(ReportData.WorkflowFilter.Phase)}"); + } + + if (ReportData.WorkflowFilter.StateIds.Count > 0) + { + string states = string.Join(", ", ReportData.WorkflowFilter.StateIds.Select(ResolveStateName)); + filterParts.Add($"{userConfig.GetText("state")}: {states}"); + } + + if (!string.IsNullOrWhiteSpace(ReportData.WorkflowFilter.LabelFilter.Name)) + { + string labelFilter = ReportData.WorkflowFilter.LabelFilter.Mode == WorkflowLabelFilterMode.value + ? $"{ReportData.WorkflowFilter.LabelFilter.Name}={ReportData.WorkflowFilter.LabelFilter.Value}" + : $"{ReportData.WorkflowFilter.LabelFilter.Name} ({userConfig.GetText(ReportData.WorkflowFilter.LabelFilter.Mode.ToString())})"; + filterParts.Add($"{userConfig.GetText("label")}: {labelFilter}"); + } + + return string.Join("; ", filterParts); + } + + private string DisplayWorkflowReportHeaderCsv() + { + StringBuilder report = new(); + report.AppendLine($"# report type: {userConfig.GetText(ReportType.ToString())}"); + report.AppendLine($"# report generation date: {DateTime.Now.ToUniversalTime():yyyy-MM-ddTHH:mm:ssK} (UTC)"); + if (ReportType == ReportType.TicketChangeReport + && Query.QueryVariables.TryGetValue("ticket_time_start", out object? startObj) + && Query.QueryVariables.TryGetValue("ticket_time_end", out object? endObj)) + { + report.AppendLine($"# change time: from {ToUtcString(startObj?.ToString())}, until {ToUtcString(endObj?.ToString())}"); + } + string workflowFilters = BuildWorkflowFilterSummary(); + if (!string.IsNullOrWhiteSpace(workflowFilters)) + { + report.AppendLine($"# workflow filter: {workflowFilters}"); + } + if (!string.IsNullOrWhiteSpace(Query.RawFilter)) + { + report.AppendLine($"# other filters: {Query.RawFilter}"); + } + report.AppendLine($"# report generator: Firewall Orchestrator - https://fwo.cactus.de/en"); + report.AppendLine($"# data protection level: For internal use only"); + report.AppendLine("#"); + return report.ToString(); + } + + private string GetLabelValue(WfTicket ticket) + { + if (!HasLabelColumn()) + { + return ""; + } + + List labelValues = + [ + .. ticket.Tasks + .Select(task => task.GetAddInfoValue(workflowFilter.LabelFilter.Name)) + .Where(value => !string.IsNullOrWhiteSpace(value)) + .Distinct() + ]; + + return string.Join(", ", labelValues); + } + + /// + /// Resolves the selected workflow phase to the current master ticket state range. + /// + private async Task ResolvePhaseFilterAsync(ApiConnection apiConnection) + { + if ((ReportType != ReportType.TicketReport && ReportType != ReportType.TicketChangeReport) || string.IsNullOrWhiteSpace(workflowFilter.Phase)) + { + return; + } + + string normalizedPhase = workflowFilter.Phase.Trim(); + + if (string.Equals(normalizedPhase, GlobalConst.kClosed, StringComparison.OrdinalIgnoreCase)) + { + StateMatrix stateMatrix = new(); + await stateMatrix.Init(WorkflowPhases.request, apiConnection, WfTaskType.master); + Query.QueryVariables["phase_lowest_input_state"] = stateMatrix.MinTicketCompleted; + return; + } + + if (!Enum.TryParse(normalizedPhase, true, out WorkflowPhases phase)) + { + throw new ArgumentException($"Unknown workflow phase '{normalizedPhase}'."); + } + + GlobalStateMatrix glbStateMatrix = GlobalStateMatrix.Create(); + await glbStateMatrix.Init(apiConnection, WfTaskType.master); + if (!glbStateMatrix.GlobalMatrix.TryGetValue(phase, out StateMatrix? phaseMatrix)) + { + throw new InvalidOperationException($"Workflow phase '{normalizedPhase}' is missing in the master state matrix."); + } + + Query.QueryVariables["phase_lowest_input_state"] = phaseMatrix.LowestInputState; + Query.QueryVariables["phase_lowest_end_state"] = phaseMatrix.LowestEndState; + } + } +} diff --git a/roles/lib/files/FWO.Report/ReportVariances.cs b/roles/lib/files/FWO.Report/ReportVariances.cs new file mode 100644 index 0000000000..705a5f0913 --- /dev/null +++ b/roles/lib/files/FWO.Report/ReportVariances.cs @@ -0,0 +1,288 @@ +using FWO.Basics; +using FWO.Config.Api; +using FWO.Data.Modelling; +using FWO.Data.Report; +using FWO.Report.Filter; +using FWO.Ui.Display; +using System.Text; + +namespace FWO.Report +{ + public class ReportVariances(DynGraphqlQuery query, UserConfig userConfig, ReportType reportType) : ReportConnections(query, userConfig, reportType) + { + public int MissConnCounter { get; private set; } = 0; + public int DiffConnCounter { get; private set; } = 0; + public int MissARCounter { get; private set; } = 0; + public int DiffARCounter { get; private set; } = 0; + + private RuleDifferenceDisplayHtml? ruleDiffDisplay; + + public override string ExportToHtml() + { + StringBuilder report = new(); + ruleDiffDisplay = new(userConfig); + int chapterNumber = 0; + report.AppendLine($"{userConfig.GetText("U1003")}
                      "); + foreach (var ownerReport in ReportData.OwnerData) + { + report.AppendLine($"

                      {ownerReport.Name}

                      "); + if (ownerReport.ImplementationState != "") + { + report.AppendLine($"{ownerReport.ImplementationState}
                      "); + } + AppendStats(ref report, ownerReport); + report.AppendLine("
                      "); + AppendMissingAppRoles(ref report, ownerReport); + AppendAppRoleDiffs(ref report, ownerReport); + AppendMissingConns(ref report, ownerReport, chapterNumber); + AppendConnDiffs(ref report, ownerReport, chapterNumber); + AppendObjects(ref report, ownerReport, chapterNumber); + AppendRulesForDeletedConns(ref report, ownerReport, chapterNumber); + AppendRemainingRules(ref report, ownerReport, chapterNumber); + report.AppendLine("
                      "); + } + return GenerateHtmlFrame(userConfig.GetText(ReportType.ToString()), Query.RawFilter, DateTime.Now, report); + } + + public static OwnerConnectionReport CollectObjectsInReport(OwnerConnectionReport ownerReport) + { + OwnerConnectionReport modifiedOwnerReport = new() { Connections = [.. ownerReport.Connections] }; + modifiedOwnerReport.Connections.AddRange(ownerReport.RuleDifferences.ConvertAll(o => o.ModelledConnection)); + if (ownerReport.MissingAppRoles.Count > 0 || ownerReport.DifferingAppRoles.Count > 0) + { + ModellingConnection diffConn = new(); + foreach (var mgt in ownerReport.MissingAppRoles.Keys) + { + diffConn.SourceAppRoles.AddRange(ownerReport.MissingAppRoles[mgt].ConvertAll(a => new ModellingAppRoleWrapper() { Content = a })); + diffConn.DestinationAppRoles.AddRange(ownerReport.DifferingAppRoles[mgt].ConvertAll(a => new ModellingAppRoleWrapper() { Content = a })); + } + modifiedOwnerReport.Connections.Add(diffConn); + } + return modifiedOwnerReport; + } + + public override string SetDescription() + { + string appRoles = $"{userConfig.GetText("app_roles")}: {MissARCounter} {userConfig.GetText("not_implemented")}, {DiffARCounter} {userConfig.GetText("with_diffs")}, "; + return $"{appRoles}{userConfig.GetText("connections")}.: {MissConnCounter} {userConfig.GetText("not_implemented")}, {DiffConnCounter} {userConfig.GetText("with_diffs")}"; + } + + private void AppendStats(ref StringBuilder report, OwnerConnectionReport ownerReport) + { + report.AppendLine(""); + report.AppendLine(""); + report.AppendLine($""); + report.AppendLine($""); + report.AppendLine($""); + report.AppendLine($""); + report.AppendLine($""); + report.AppendLine(""); + + if (ownerReport.AppRoleStats.ModelledAppRolesCount > 0) + { + report.AppendLine(""); + report.AppendLine($""); + report.AppendLine($""); + report.AppendLine($""); + report.AppendLine($""); + report.AppendLine($""); + report.AppendLine(""); + } + report.AppendLine(""); + report.AppendLine($""); + report.AppendLine($""); + report.AppendLine($""); + report.AppendLine($""); + report.AppendLine($""); + report.AppendLine(""); + report.AppendLine("
                      {userConfig.GetText("fully_modelled")}{userConfig.GetText("implemented")}{userConfig.GetText("not_implemented")}{userConfig.GetText("with_diffs")}
                      {userConfig.GetText("app_roles")}{ownerReport.AppRoleStats.ModelledAppRolesCount}{ownerReport.AppRoleStats.AppRolesOk}{ownerReport.AppRoleStats.AppRolesMissingCount}{ownerReport.AppRoleStats.AppRolesDifferenceCount}
                      {userConfig.GetText("connections")}{ownerReport.ModelledConnectionsCount}{ownerReport.ModelledConnectionsCount - ownerReport.RuleDifferences.Count - ownerReport.Connections.Count}{ownerReport.Connections.Count}{ownerReport.RuleDifferences.Count}
                      "); + } + + private void AppendMissingAppRoles(ref StringBuilder report, OwnerConnectionReport ownerReport) + { + if (ownerReport.AppRoleStats.AppRolesMissingCount > 0) + { + report.AppendLine($"

                      {userConfig.GetText("app_roles_not_implemented")}

                      "); + foreach (var mgt in ownerReport.MissingAppRoles.Keys) + { + if (ownerReport.MissingAppRoles[mgt].Count > 0) + { + report.AppendLine($"
                      {ownerReport.MissingAppRoles[mgt][0].ManagementName}
                      "); + AppendAppRolesHtml(ownerReport.MissingAppRoles[mgt], ref report); + } + } + report.AppendLine("
                      "); + } + } + + private void AppendAppRoleDiffs(ref StringBuilder report, OwnerConnectionReport ownerReport) + { + if (ownerReport.AppRoleStats.AppRolesDifferenceCount > 0) + { + report.AppendLine($"

                      {userConfig.GetText("app_roles_with_diffs")}

                      "); + foreach (var mgt in ownerReport.DifferingAppRoles.Keys) + { + if (ownerReport.DifferingAppRoles[mgt].Count > 0) + { + report.AppendLine($"
                      {ownerReport.DifferingAppRoles[mgt][0].ManagementName}
                      "); + AppendAppRolesHtml(ownerReport.DifferingAppRoles[mgt], ref report, true, true); + } + } + report.AppendLine("
                      "); + } + } + + private void AppendAppRolesHtml(List appRoles, ref StringBuilder report, bool diffMode = false, bool split = false) + { + SetObjectNumbers(appRoles); + report.AppendLine(""); + if (appRoles.Count > 0) + { + AppendAppRoleHeadlineHtml(ref report, split); + } + foreach (var appRole in appRoles) + { + report.AppendLine(""); + report.AppendLine($""); + report.AppendLine($""); + report.AppendLine($""); + if (split) + { + report.AppendLine($""); + report.AppendLine($""); + } + else + { + report.AppendLine($""); + } + } + report.AppendLine("
                      {appRole.Number}{appRole.Id}{appRole.Name}{ConnectionReport.ListAppServers([.. ModellingAppServerWrapper.Resolve(appRole.AppServers)], [])}{ConnectionReport.ListAppServers([.. ModellingAppServerWrapper.Resolve(appRole.SurplusAppServers)], [])}{ConnectionReport.ListAppServers([.. ModellingAppServerWrapper.Resolve(appRole.AppServers)], + [.. ModellingAppServerWrapper.Resolve(appRole.SurplusAppServers)], diffMode, true)}
                      "); + report.AppendLine("
                      "); + } + + private static void SetObjectNumbers(List appRoles) + { + long number = 1; + foreach (var appRole in appRoles) + { + appRole.Number = number++; + } + } + + private void AppendAppRoleHeadlineHtml(ref StringBuilder report, bool split) + { + report.AppendLine(""); + report.AppendLine($"{userConfig.GetText("number")}"); + report.AppendLine($"{userConfig.GetText("id")}"); + report.AppendLine($"{userConfig.GetText("name")}"); + if (split) + { + report.AppendLine($"{userConfig.GetText("missing_app_servers")}"); + report.AppendLine($"{userConfig.GetText("surplus_app_servers")}"); + } + else + { + report.AppendLine($"{userConfig.GetText("members")}"); + } + report.AppendLine(""); + } + + private void AppendMissingConns(ref StringBuilder report, OwnerConnectionReport ownerReport, int chapterNumber) + { + if (ownerReport.RegularConnections.Count > 0) + { + chapterNumber++; + report.AppendLine($"

                      {userConfig.GetText("connections_not_implemented")}

                      "); + if (ownerReport.RegularConnections.Count > 0) + { + report.AppendLine($"
                      {userConfig.GetText("connections")}
                      "); + AppendConnectionsGroupHtml(ownerReport.RegularConnections, ownerReport, chapterNumber, ref report, new() { WithoutLinks = true }); + } + if (ownerReport.CommonServices.Count > 0) + { + report.AppendLine($"
                      {userConfig.GetText("own_common_services")}
                      "); + AppendConnectionsGroupHtml(ownerReport.CommonServices, ownerReport, chapterNumber, ref report, new() { WithoutLinks = true }); + } + report.AppendLine("
                      "); + } + } + + private void AppendConnDiffs(ref StringBuilder report, OwnerConnectionReport ownerReport, int chapterNumber) + { + if (ownerReport.RuleDifferences.Count > 0 && ruleDiffDisplay != null) + { + report.AppendLine($"

                      {userConfig.GetText("connections_with_diffs")}

                      "); + foreach (var difference in ownerReport.RuleDifferences) + { + bool anyUnusedObjects = difference.ImplementedRules.Any(r => r.UnusedSpecialUserObjects.Count > 0 || r.UnusedUpdatableObjects.Count > 0); + report.AppendLine($"
                      {difference.ModelledConnection.Name}
                      "); + AppendConnectionsGroupHtml([difference.ModelledConnection], ownerReport, chapterNumber, ref report, new() { WithoutLinks = true, WithoutNumber = true }); + report.AppendLine(""); + report.AppendLine(""); + report.AppendLine($""); + report.AppendLine($""); + report.AppendLine($""); + report.AppendLine($""); + report.AppendLine($""); + if (anyUnusedObjects) + { + report.AppendLine($""); + } + report.AppendLine(""); + + foreach (var diff in difference.ImplementedRules) + { + report.AppendLine(""); + report.AppendLine($""); + report.AppendLine($""); + report.AppendLine($""); + report.AppendLine($""); + report.AppendLine($""); + if (anyUnusedObjects) + { + List unusedObjects = [.. diff.UnusedSpecialUserObjects, .. diff.UnusedUpdatableObjects]; + report.AppendLine($""); + } + report.AppendLine(""); + } + report.AppendLine("
                      {userConfig.GetText("management")}{userConfig.GetText("gateway")}{userConfig.GetText("source")}{userConfig.GetText("services")}{userConfig.GetText("destination")}{userConfig.GetText("missing_objects")}
                      {diff.ManagementName}{diff.DeviceName}{ruleDiffDisplay.DisplaySourceDiff(diff, OutputLocation.export, ReportType)}{ruleDiffDisplay.DisplayServiceDiff(diff, OutputLocation.export, ReportType)}{ruleDiffDisplay.DisplayDestinationDiff(diff, OutputLocation.export, ReportType)}{string.Join(", ", unusedObjects)}
                      "); + } + report.AppendLine("
                      "); + } + } + + private void AppendObjects(ref StringBuilder report, OwnerConnectionReport ownerReport, int chapterNumber) + { + List relevantConns = CollectObjectsInReport(ownerReport).Connections; + ownerReport.AllObjects = ConnectionReport.GetAllNetworkObjects(relevantConns, true, userConfig.ResolveNetworkAreas); + ConnectionReport.SetObjectNumbers(ownerReport.AllObjects); + ownerReport.AllServices = ConnectionReport.GetAllServices(relevantConns, true); + ConnectionReport.SetSvcNumbers(ownerReport.AllServices); + AppendNetworkObjectsHtml(ownerReport.AllObjects, chapterNumber, ref report); + AppendNetworkServicesHtml(ownerReport.AllServices, chapterNumber, ref report); + } + + private void AppendRulesForDeletedConns(ref StringBuilder report, OwnerConnectionReport ownerReport, int chapterNumber) + { + if (ownerReport.RulesForDeletedConns.Count > 0) + { + ReportRules rulesReport = new(new(""), userConfig, ReportType.Rules); + report.AppendLine($"

                      {userConfig.GetText("rules_for_deleted_conns")}

                      "); + rulesReport.ConstructHtmlReport(ref report, ownerReport.RulesForDeletedConns, chapterNumber, 2); + report.AppendLine("
                      "); + } + } + + private void AppendRemainingRules(ref StringBuilder report, OwnerConnectionReport ownerReport, int chapterNumber) + { + if (ownerReport.UnmodelledRules.Count > 0) + { + ReportRules rulesReport = new(new(""), userConfig, ReportType.AppRules); + report.AppendLine($"

                      {userConfig.GetText("remaining_rules")}

                      "); + rulesReport.ConstructHtmlReport(ref report, ownerReport.UnmodelledRules, chapterNumber, 2); + report.AppendLine("
                      "); + } + } + } +} diff --git a/roles/lib/files/FWO.Report/WorkflowTicketReferenceHelper.cs b/roles/lib/files/FWO.Report/WorkflowTicketReferenceHelper.cs new file mode 100644 index 0000000000..6bc9f71ef6 --- /dev/null +++ b/roles/lib/files/FWO.Report/WorkflowTicketReferenceHelper.cs @@ -0,0 +1,156 @@ +using FWO.Basics; +using FWO.Data.Report; +using FWO.Data.Workflow; +using System.Globalization; + +namespace FWO.Report +{ + /// + /// Resolves workflow ticket reference dates and ordering for ticket change reports. + /// + public static class WorkflowTicketReferenceHelper + { + /// + /// Computes the reference date for one workflow ticket. + /// + public static DateTime? GetTicketReferenceDate( + WfTicket ticket, + WorkflowReferenceDate referenceDate, + Func> getReferenceTasks, + Func> getReferenceApprovals, + Func> getReferenceImplementationTasks, + Func> getTicketReferenceActivityDates, + Func> getReferenceActivityDates) + { + List referenceTasks = getReferenceTasks(ticket); + return referenceDate switch + { + WorkflowReferenceDate.TicketCreation => ticket.CreationDate, + WorkflowReferenceDate.TicketClosure => ticket.CompletionDate, + WorkflowReferenceDate.TaskStart => referenceTasks + .Select(task => task.Start) + .Where(date => date.HasValue) + .Min(), + WorkflowReferenceDate.TaskEnd => referenceTasks + .Select(task => task.Stop) + .Where(date => date.HasValue) + .Min(), + WorkflowReferenceDate.ApprovalOpened => referenceTasks + .SelectMany(task => getReferenceApprovals(task)) + .Select(approval => approval.DateOpened) + .Cast() + .Min(), + WorkflowReferenceDate.Approved => referenceTasks + .SelectMany(task => getReferenceApprovals(task)) + .Select(approval => approval.ApprovalDate) + .Where(date => date.HasValue) + .Min(), + WorkflowReferenceDate.ImplementationStart => referenceTasks + .SelectMany(task => getReferenceImplementationTasks(task)) + .Select(task => task.Start) + .Where(date => date.HasValue) + .Min(), + WorkflowReferenceDate.ImplementationEnd => referenceTasks + .SelectMany(task => getReferenceImplementationTasks(task)) + .Select(task => task.Stop) + .Where(date => date.HasValue) + .Min(), + WorkflowReferenceDate.AnyActivity => GetAnyActivityReferenceDate(ticket, referenceTasks, getTicketReferenceActivityDates, getReferenceActivityDates), + _ => ticket.CompletionDate + }; + } + + /// + /// Sorts tickets by reference date descending and falls back to descending ticket id. + /// + public static IEnumerable SortTicketsByReferenceDate( + IEnumerable tickets, + WorkflowReferenceDate referenceDate, + Func> getReferenceTasks, + Func> getReferenceApprovals, + Func> getReferenceImplementationTasks, + Func> getTicketReferenceActivityDates, + Func> getReferenceActivityDates) + { + return tickets + .Select(ticket => new + { + Ticket = ticket, + ReferenceDate = GetTicketReferenceDate(ticket, referenceDate, getReferenceTasks, getReferenceApprovals, getReferenceImplementationTasks, getTicketReferenceActivityDates, getReferenceActivityDates) + }) + .OrderByDescending(item => item.ReferenceDate.HasValue) + .ThenByDescending(item => item.ReferenceDate) + .ThenByDescending(item => item.Ticket.Id) + .Select(item => item.Ticket); + } + + /// + /// Selects all activity timestamps for one request task, optionally constrained by a date filter. + /// + public static IEnumerable GetActivityDates(WfReqTask task, bool includeAllDates, Func isInSelectedTimeRange) + { + IEnumerable activityDates = + [ + task.Start, + task.Stop, + .. task.ImplementationTasks.SelectMany(implTask => new DateTime?[] { implTask.Start, implTask.Stop }), + .. task.Approvals.SelectMany(approval => new DateTime?[] { approval.DateOpened, approval.ApprovalDate }) + ]; + + return includeAllDates ? activityDates : activityDates.Where(isInSelectedTimeRange); + } + + /// + /// Checks whether a nullable date lies within the given half-open time range. + /// + public static bool IsInSelectedTimeRange(DateTime? date, string? startText, string? endText) + { + return date.HasValue && IsInSelectedTimeRange(date.Value, startText, endText); + } + + /// + /// Checks whether a date lies within the given half-open time range. + /// + public static bool IsInSelectedTimeRange(DateTime date, string? startText, string? endText) + { + if (date == default) + { + return false; + } + + if (!DateTime.TryParse(startText, CultureInfo.InvariantCulture, DateTimeStyles.None, out DateTime start)) + { + return true; + } + + if (!DateTime.TryParse(endText, CultureInfo.InvariantCulture, DateTimeStyles.None, out DateTime end)) + { + return true; + } + + return date >= start && date < end; + } + + /// + /// Computes the latest matching activity date for one workflow ticket. + /// + private static DateTime? GetAnyActivityReferenceDate( + WfTicket ticket, + List referenceTasks, + Func> getTicketReferenceActivityDates, + Func> getReferenceActivityDates) + { + List dates = + [ + .. getTicketReferenceActivityDates(ticket) + .Where(date => date.HasValue) + .Select(date => date!.Value), + .. referenceTasks + .SelectMany(task => getReferenceActivityDates(task)) + .Where(date => date.HasValue) + .Select(date => date!.Value), + ]; + return dates.Count > 0 ? dates.Max() : null; + } + } +} diff --git a/roles/lib/files/FWO.Services/AlertHelper.cs b/roles/lib/files/FWO.Services/AlertHelper.cs new file mode 100644 index 0000000000..355de3565f --- /dev/null +++ b/roles/lib/files/FWO.Services/AlertHelper.cs @@ -0,0 +1,165 @@ +using FWO.Api.Client; +using FWO.Api.Client.Queries; +using FWO.Config.Api; +using FWO.Data; +using FWO.Logging; +using System.Collections.Generic; +using System.Linq; +using System.Text.Json; + +namespace FWO.Services +{ + public static class AlertHelper + { + public struct AdditionalAlertData + { + public int? MgmtId { get; set; } + public object? JsonData { get; set; } + public int? DevId { get; set; } + public long? RefAlertId { get; set; } + public int UserId { get; set; } + public bool CompareDesc { get; set; } + public bool CompareTitle { get; set; } + } + + public static async Task LogErrorsWithAlert(ApiConnection apiConnection, GlobalConfig globalConfig, int severity, string title, string source, AlertCode alertCode, Exception exc) + { + try + { + Log.WriteError(title, "Ran into exception: ", exc); + string titletext = $"Error encountered while trying {title}"; + await AddLogEntry(apiConnection, severity, title, globalConfig.GetText("ran_into_exception") + exc.Message, source); + await SetAlert(apiConnection, title, titletext, source, alertCode, new AdditionalAlertData()); + } + catch (Exception exception) + { + Log.WriteError(title, "something went really wrong", exception); + } + } + + public static async Task AddLogEntry(ApiConnection apiConnection, int severity, string cause, string description, string source, int? mgmtId = null) + { + try + { + var Variables = new + { + source = source, + discoverUser = 0, + severity = severity, + suspectedCause = cause, + description = description, + mgmId = mgmtId, + devId = (int?)null, + importId = (long?)null, + objectType = (string?)null, + objectName = (string?)null, + objectUid = (string?)null, + ruleUid = (string?)null, + ruleId = (long?)null + }; + ReturnId[]? returnIds = (await apiConnection.SendQueryAsync(MonitorQueries.addLogEntry, Variables)).ReturnIds; + if (returnIds == null) + { + Log.WriteError("Write Log", "Log could not be written to database"); + } + } + catch (Exception exc) + { + Log.WriteError("Write Log", "Could not write log: ", exc); + } + } + + public static async Task SetAlert(ApiConnection apiConnection, string title, string description, string source, AlertCode alertCode, + AdditionalAlertData additionalAlertData) + { + long? alertId = null; + try + { + List openAlerts = await apiConnection.SendQueryAsync>(MonitorQueries.getOpenAlerts); + var Variables = new + { + source = source, + userId = additionalAlertData.UserId, + title = title, + description = description, + mgmId = additionalAlertData.MgmtId, + devId = additionalAlertData.DevId, + alertCode = (int)alertCode, + jsonData = additionalAlertData.JsonData, + refAlert = additionalAlertData.RefAlertId + }; + ReturnId[]? returnIds = (await apiConnection.SendQueryAsync(MonitorQueries.addAlert, Variables)).ReturnIds; + if (returnIds != null) + { + // Acknowledge older alert for same problem + alertId = returnIds[0].NewIdLong; + Alert? existingAlert = openAlerts.FirstOrDefault(x => x.AlertCode == alertCode + && (x.ManagementId == additionalAlertData.MgmtId || (x.ManagementId == null && additionalAlertData.MgmtId == null)) + && (additionalAlertData.UserId == 0 || x.UserId == additionalAlertData.UserId) + && (!additionalAlertData.CompareDesc || x.Description == description) + && (!additionalAlertData.CompareTitle || x.Title == title)); + if (existingAlert != null) + { + await AcknowledgeAlert(apiConnection, existingAlert.Id, additionalAlertData.UserId); + } + } + else + { + Log.WriteError("Write Alert", "Log could not be written to database"); + } + LogAlert(title, description, source, alertCode, additionalAlertData.MgmtId, additionalAlertData.JsonData, additionalAlertData.DevId); + } + catch (Exception exc) + { + Log.WriteError("Write Alert", $"Could not write Alert for {source}: ", exc); + LogAlert(title, description, source, alertCode, additionalAlertData.MgmtId, additionalAlertData.JsonData, additionalAlertData.DevId); + } + return alertId; + } + + public static async Task AcknowledgeAlert(ApiConnection apiConnection, long alertId, int ackUser = 0) + { + try + { + var Variables = new + { + id = alertId, + ackUser = ackUser, + ackTime = DateTime.Now + }; + await apiConnection.SendQueryAsync(MonitorQueries.acknowledgeAlert, Variables); + } + catch (Exception exception) + { + Log.WriteError("Acknowledge Alert", $"Could not acknowledge alert for {alertId}: ", exception); + } + } + + public static async Task AcknowledgeAllOpenAlerts(ApiConnection apiConnection, int ackUser = 0) + { + try + { + var Variables = new + { + ackUser = ackUser, + ackTime = DateTime.Now + }; + return (await apiConnection.SendQueryAsync(MonitorQueries.acknowledgeAllOpenAlerts, Variables)).AffectedRows; + } + catch (Exception exception) + { + Log.WriteError("Acknowledge Alerts", $"Could not acknowledge all open alerts: ", exception); + } + return -1; + } + + private static void LogAlert(string title, string description, string source, AlertCode alertCode, int? mgmtId, object? jsonData, int? devId) + { + string? mgmtIdString = mgmtId?.ToString() ?? ""; + string? devIdString = devId?.ToString() ?? ""; + string jsonString = jsonData != null ? JsonSerializer.Serialize(jsonData) : ""; + Log.WriteAlert($"source: \"{source}\"", $"userId: \"0\", title: \"{title}\", description: \"{description}\", " + + $"mgmId: \"{mgmtIdString}\", devId: \"{devIdString}\", jsonData: \"{jsonString}\", alertCode: \"{alertCode}\""); + } + } +} diff --git a/roles/lib/files/FWO.Services/DefaultInit.cs b/roles/lib/files/FWO.Services/DefaultInit.cs new file mode 100644 index 0000000000..16ff7d90fd --- /dev/null +++ b/roles/lib/files/FWO.Services/DefaultInit.cs @@ -0,0 +1,26 @@ +using FWO.Data; +using FWO.Data.Workflow; +using FWO.Data.Modelling; + +namespace FWO.Services +{ + public static class DefaultInit + { + public static void DoNothing(Exception? e, string t, string m, bool E) { } + public static async Task DoNothing() { await Task.CompletedTask; } + public static async Task DoNothing(string _) { await Task.CompletedTask; } + public static async Task DoNothing(WfStatefulObject _) { await Task.CompletedTask; } + public static async Task DoNothing(WfTicket _) { await Task.CompletedTask; } + public static async Task DoNothing(WfReqTask _) { await Task.CompletedTask; } + public static async Task DoNothing(WfImplTask _) { await Task.CompletedTask; } + public static async Task DoNothing(UiUser _) { await Task.CompletedTask; } + public static async Task DoNothing(FwoOwner _) { await Task.CompletedTask; } + public static async Task DoNothing(Device _) { await Task.CompletedTask; } + public static async Task DoNothing(ComplianceCriterion _) { await Task.CompletedTask; } + + + public static bool DoNothingSync() { return false; } + public static bool DoNothingSync(ModellingNwGroup _) { return false; } + public static bool DoNothingSync(FwoOwner _) { return false; } + } +} diff --git a/roles/lib/files/FWO.Services/EmailHelper.cs b/roles/lib/files/FWO.Services/EmailHelper.cs new file mode 100644 index 0000000000..c750efc1d3 --- /dev/null +++ b/roles/lib/files/FWO.Services/EmailHelper.cs @@ -0,0 +1,419 @@ +using FWO.Api.Client; +using FWO.Api.Client.Queries; +using FWO.Config.Api; +using FWO.Data; +using FWO.Data.Middleware; +using FWO.Data.Workflow; +using FWO.Mail; +using FWO.Middleware.Client; +using Newtonsoft.Json; +using System; +using System.Text.Json.Serialization; +using Microsoft.AspNetCore.Http; +using System.Text.RegularExpressions; +using System.Linq; +using FWO.Basics; +using FWO.Logging; + +namespace FWO.Services +{ + public class EmailActionParams + { + [JsonProperty("to"), JsonPropertyName("to")] + public EmailRecipientOption RecipientTo { get; set; } = EmailRecipientOption.None; + + [JsonProperty("cc"), JsonPropertyName("cc")] + public EmailRecipientOption? RecipientCC { get; set; } + + [JsonProperty("subject"), JsonPropertyName("subject")] + public string Subject { get; set; } = ""; + + [JsonProperty("body"), JsonPropertyName("body")] + public string Body { get; set; } = ""; + } + + public class EmailHelper + { + private readonly ApiConnection apiConnection; + private readonly MiddlewareClient? middlewareClient; + private readonly UserConfig userConfig; + private readonly Action displayMessageInUi; + private readonly bool useInMwServer = false; + private List ownerGroups = []; + private List ownerResponsibleTypes = []; + private List uiUsers = []; + private string? ScopedUserTo; + private string? ScopedUserCc; + + + public EmailHelper(ApiConnection apiConnection, MiddlewareClient? middlewareClient, UserConfig userConfig, Action displayMessageInUi, List? ownerGroups = null, bool useInMwServer = false) + { + this.apiConnection = apiConnection; + this.middlewareClient = middlewareClient; + this.userConfig = userConfig; + this.displayMessageInUi = displayMessageInUi; + this.useInMwServer = useInMwServer; + this.ownerGroups = ownerGroups ?? []; + } + + public virtual async Task Init(string? scopedUserTo = null, string? scopedUserCc = null) + { + if (!useInMwServer && middlewareClient != null) + { + ownerGroups = await GroupAccess.GetGroupsFromInternalLdap(middlewareClient, userConfig, displayMessageInUi, true); + } + try + { + ownerResponsibleTypes = await apiConnection.SendQueryAsync>(OwnerQueries.getOwnerResponsibleTypes); + } + catch + { + ownerResponsibleTypes = []; + } + uiUsers = await apiConnection.SendQueryAsync>(AuthQueries.getUserEmails); + ScopedUserTo = scopedUserTo; + ScopedUserCc = scopedUserCc; + } + + public virtual async Task SendEmailToOwnerResponsibles(FwoOwner owner, string subject, string body, EmailRecipientOption recOpt, bool reqInCc = false) + { + List? requester = reqInCc ? new() { GetEmailAddress(userConfig.User.Dn) } : null; + return await SendEmail(await GetRecipients(recOpt, null, owner, null, null), subject, body, requester); + } + + public virtual async Task SendEmailToOwnerResponsibles(FwoOwner owner, string subject, string body, string recipientConfig, bool reqInCc = false, List? otherAddresses = null) + { + List? requester = reqInCc ? new() { GetEmailAddress(userConfig.User.Dn) } : null; + List recipients = await GetRecipients(ModellingEmailRecipientSelection.Parse(recipientConfig, GetActiveOwnerResponsibleTypeIds()), owner, otherAddresses); + return await SendEmail(recipients, subject, body, requester); + } + + public async Task SendOwnerEmailFromAction(EmailActionParams emailActionParams, WfStatefulObject statefulObject, FwoOwner? owner) + { + List tos = await GetRecipients(emailActionParams.RecipientTo, statefulObject, owner, ScopedUserTo, null); + List? ccs = emailActionParams.RecipientCC != null ? await GetRecipients((EmailRecipientOption)emailActionParams.RecipientCC, statefulObject, owner, ScopedUserCc, null) : null; + return await SendEmail(tos, emailActionParams.Subject, emailActionParams.Body, ccs); + } + + public async Task SendUserEmailFromAction(EmailActionParams emailActionParams, WfStatefulObject statefulObject, string userGrpDn) + { + return await SendEmail(await CollectEmailAddressesFromUserOrGroup(userGrpDn), emailActionParams.Subject, emailActionParams.Body); + } + + private async Task SendEmail(List tos, string subject, string body, List? ccs = null) + { + EmailConnection emailConnection = new(userConfig.EmailServerAddress, userConfig.EmailPort, + userConfig.EmailTls, userConfig.EmailUser, userConfig.EmailPassword, userConfig.EmailSenderAddress); + tos = [.. tos.Where(t => t != "")]; + if (tos.Count == 0) + { + return false; + } + ccs = ccs?.Where(c => c != "").ToList(); + return await MailKitMailer.SendAsync(new MailData(tos, subject) { Body = body, Cc = ccs ?? [] }, emailConnection, true, new CancellationToken()); + } + + public async Task> GetRecipients(EmailRecipientOption recipientOption, WfStatefulObject? statefulObject, FwoOwner? owner, string? scopedUser, List? otherAddresses) + { + Dictionary>>> handlers = BuildRecipientHandlers(statefulObject, owner, scopedUser, otherAddresses); + if (handlers.TryGetValue(recipientOption, out Func>>? handler)) + { + return await handler(); + } + return []; + } + + private Dictionary>>> BuildRecipientHandlers( + WfStatefulObject? statefulObject, + FwoOwner? owner, + string? scopedUser, + List? otherAddresses) + { + Func>> scopedUserHandler = () => Task.FromResult(ListWithSingleRecipient(scopedUser)); + return new Dictionary>>> + { + { EmailRecipientOption.CurrentHandler, () => Task.FromResult(ListWithSingleRecipient(statefulObject?.CurrentHandler?.Dn)) }, + { EmailRecipientOption.RecentHandler, () => Task.FromResult(ListWithSingleRecipient(statefulObject?.RecentHandler?.Dn)) }, + { EmailRecipientOption.AssignedGroup, () => CollectEmailAddressesFromUserOrGroup(statefulObject?.AssignedGroup) }, + { EmailRecipientOption.OwnerMainResponsible, () => CollectOwnerAddressesByType(owner, GlobalConst.kOwnerResponsibleTypeMain) }, + { EmailRecipientOption.AllOwnerResponsibles, () => CollectEmailAddressesFromDns(owner?.GetAllOwnerResponsibles()) }, + { EmailRecipientOption.OwnerGroupOnly, () => CollectOwnerAddressesByType(owner, GlobalConst.kOwnerResponsibleTypeSupporting) }, + { EmailRecipientOption.Requester, scopedUserHandler }, + { EmailRecipientOption.Approver, scopedUserHandler }, + { EmailRecipientOption.LastCommenter, scopedUserHandler }, + { EmailRecipientOption.FallbackToMainResponsibleIfOwnerGroupEmpty, () => GetOwnerGroupOrMainResponsibleRecipients(owner) }, + { EmailRecipientOption.OtherAddresses, () => Task.FromResult(GetOtherAddresses(otherAddresses)) } + }; + } + + private List ListWithSingleRecipient(string? dn) + { + return [GetEmailAddress(dn)]; + } + + private async Task> CollectOwnerAddressesByType(FwoOwner? owner, int responsibleType) + { + return await CollectEmailAddressesFromDns(owner?.GetOwnerResponsiblesByType(responsibleType)); + } + + private static List GetOtherAddresses(List? otherAddresses) + { + return otherAddresses != null ? [.. otherAddresses] : []; + } + + private async Task> GetOwnerGroupOrMainResponsibleRecipients(FwoOwner? owner) + { + if (owner is null) + { + return []; + } + + List ownerGroupAddresses = await CollectOwnerAddressesByType(owner, GlobalConst.kOwnerResponsibleTypeSupporting); + List mainResponsibleAddresses = await CollectOwnerAddressesByType(owner, GlobalConst.kOwnerResponsibleTypeMain); + ownerGroupAddresses.AddRange(mainResponsibleAddresses); + if (ownerGroupAddresses.Count > 0) + { + return ownerGroupAddresses; + } + + return mainResponsibleAddresses; + } + + private async Task> GetRecipients(ModellingEmailRecipientSelection selection, FwoOwner owner, List? otherAddresses) + { + if (!selection.HasAnyRecipientOption()) + { + return []; + } + + HashSet recipients = new(StringComparer.OrdinalIgnoreCase); + AddOtherAddresses(selection, otherAddresses, recipients); + await AddOwnerTypeRecipients(owner, selection.OwnerResponsibleTypeIds.Distinct(), recipients); + await AddFallbackRecipients(selection, owner, recipients); + + return recipients.ToList(); + } + + private static void AddOtherAddresses(ModellingEmailRecipientSelection selection, List? otherAddresses, HashSet recipients) + { + if (selection.OtherAddresses && otherAddresses != null) + { + AddAddresses(recipients, otherAddresses); + } + } + + private async Task AddOwnerTypeRecipients(FwoOwner owner, IEnumerable responsibleTypeIds, HashSet recipients) + { + foreach (int responsibleTypeId in responsibleTypeIds) + { + List ownerTypeRecipients = await CollectEmailAddressesFromDns(owner.GetOwnerResponsiblesByType(responsibleTypeId)); + AddAddresses(recipients, ownerTypeRecipients); + } + } + + private async Task AddFallbackRecipients(ModellingEmailRecipientSelection selection, FwoOwner owner, HashSet recipients) + { + if (!selection.EnsureAtLeastOneNotification || recipients.Count > 0) + { + return; + } + + HashSet selectedTypeIds = selection.OwnerResponsibleTypeIds.ToHashSet(); + List fallbackTypeIds = ownerResponsibleTypes + .Where(type => type.Active && !selectedTypeIds.Contains(type.Id)) + .OrderByDescending(type => type.SortOrder) + .ThenByDescending(type => type.Id) + .Select(type => type.Id) + .ToList(); + + foreach (int responsibleTypeId in fallbackTypeIds) + { + List ownerTypeRecipients = await CollectEmailAddressesFromDns(owner.GetOwnerResponsiblesByType(responsibleTypeId)); + if (ownerTypeRecipients.Count > 0) + { + AddAddresses(recipients, ownerTypeRecipients); + break; + } + } + } + + private static void AddAddresses(HashSet recipients, IEnumerable? addresses) + { + if (addresses == null) + { + return; + } + + foreach (string address in addresses) + { + if (!string.IsNullOrWhiteSpace(address)) + { + recipients.Add(address); + } + } + } + + private List GetActiveOwnerResponsibleTypeIds() + { + return ownerResponsibleTypes + .Where(type => type.Active) + .Select(type => type.Id) + .ToList(); + } + + public List GetOwnerMainResponsibleRecipients(List owners) + { + List recipients = []; + + foreach (UserGroup owner in owners) + { + if (owner is null || string.IsNullOrWhiteSpace(owner.Dn)) + { + continue; + } + recipients.Add(GetEmailAddress(owner.Dn)); + } + + return recipients; + } + + /// + /// Split email addresses from string to list + /// + /// + /// + public static List SplitAddresses(string addresslist) + { + string[] separatingStrings = [",", ";", "|"]; + return [.. addresslist.Split(separatingStrings, StringSplitOptions.TrimEntries | StringSplitOptions.RemoveEmptyEntries)]; + } + + private async Task> CollectEmailAddressesFromUserOrGroup(string? dn) + { + return await CollectEmailAddressesFromDns(dn == null ? null : [dn]); + } + + private async Task> CollectEmailAddressesFromDns(IEnumerable? dns) + { + List tos = []; + List resolvedDns = await ResolveUserDns(dns); + foreach (string dn in resolvedDns) + { + tos.Add(GetEmailAddress(dn)); + } + return tos; + } + + private async Task> ResolveUserDns(IEnumerable? dns) + { + List dnsList = dns?.Where(dn => !string.IsNullOrWhiteSpace(dn)).Distinct(StringComparer.OrdinalIgnoreCase).ToList() ?? []; + if (dnsList.Count == 0) + { + return []; + } + + if (middlewareClient != null) + { + try + { + var response = await middlewareClient.ResolveGroupMembers(new GroupResolveParameters { Dns = dnsList }); + if (response.IsSuccessful && response.Data != null) + { + return response.Data.Where(dn => !string.IsNullOrWhiteSpace(dn)).Distinct(StringComparer.OrdinalIgnoreCase).ToList(); + } + + displayMessageInUi(null, userConfig.GetText("fetch_groups"), userConfig.GetText("E5231"), true); + } + catch (Exception exception) + { + displayMessageInUi(exception, userConfig.GetText("fetch_groups"), userConfig.GetText("E5231"), true); + } + } + + HashSet resolved = new(StringComparer.OrdinalIgnoreCase); + foreach (string dn in dnsList) + { + UserGroup? ownerGroup = ownerGroups.FirstOrDefault(x => x.Dn == dn); + if (ownerGroup != null) + { + foreach (var user in ownerGroup.Users) + { + resolved.Add(user.Dn); + } + } + else + { + resolved.Add(dn); + } + } + return resolved.ToList(); + } + + private string GetEmailAddress(string? dn) + { + if (userConfig.UseDummyEmailAddress) + { + return userConfig.DummyEmailAddress; + } + UiUser? uiuser = uiUsers.FirstOrDefault(x => x.Dn == dn); + if (uiuser != null && uiuser.Email != null && uiuser.Email != "") + { + return uiuser.Email; + } + return ""; + } + + public static List CollectRecipientsFromConfig(UserConfig userConfig, string configValue) + { + if (userConfig.UseDummyEmailAddress) + { + return [userConfig.DummyEmailAddress]; + } + string[] separatingStrings = [",", ";", "|"]; + return [.. configValue.Split(separatingStrings, StringSplitOptions.TrimEntries | StringSplitOptions.RemoveEmptyEntries)]; + } + + public static FormFile? CreateAttachment(string? content, string fileFormat, string subject) + { + if (content != null) + { + string fileName = ConstructFileName(subject, fileFormat); + + MemoryStream memoryStream; + string contentType; + + if (fileFormat == GlobalConst.kPdf) + { + memoryStream = new(Convert.FromBase64String(content)); + contentType = "application/octet-stream"; + } + else + { + memoryStream = new(System.Text.Encoding.UTF8.GetBytes(content)); + contentType = $"application/{fileFormat}"; + } + + return new(memoryStream, 0, memoryStream.Length, "FWO-Report-Attachment", fileName) + { + Headers = new HeaderDictionary(), + ContentType = contentType + }; + } + return null; + } + + private static string ConstructFileName(string input, string fileFormat) + { + try + { + Regex regex = new(@"\s", RegexOptions.None, TimeSpan.FromMilliseconds(500)); + return $"{regex.Replace(input, "")}_{DateTime.Now.ToUniversalTime().ToString("yyyy-MM-ddTHH-mm-ssK")}.{fileFormat}"; + } + catch (RegexMatchTimeoutException) + { + Log.WriteWarning("Construct File Name", "Timeout when constructing file name. Taking input."); + return input; + } + } + } +} diff --git a/roles/lib/files/FWO.Services/EventMediator/EventMediator.cs b/roles/lib/files/FWO.Services/EventMediator/EventMediator.cs new file mode 100644 index 0000000000..85ede7f0c2 --- /dev/null +++ b/roles/lib/files/FWO.Services/EventMediator/EventMediator.cs @@ -0,0 +1,65 @@ +using FWO.Services.EventMediator.Interfaces; + +namespace FWO.Services.EventMediator; + +public class EventMediator : IEventMediator +{ + private readonly Dictionary>>> _handlers = []; + + /// + /// Adds the handler as an invokeable action. + /// + /// + /// + /// + public void Subscribe(string name, Action handler) where TEvent : class, IEvent + { + if (!_handlers.ContainsKey(typeof(TEvent))) + { + _handlers[typeof(TEvent)] = []; + } + + if (!_handlers[typeof(TEvent)].TryGetValue(name, out List>? value)) + { + value = []; + _handlers[typeof(TEvent)][name] = value; + } + + value.Add(e => handler((TEvent)e)); + } + + /// + /// If matching subscription handler was found it will be invoked. + /// + /// + /// + /// + public void Publish(string name, TEvent @event) where TEvent : class, IEvent + { + if (_handlers.TryGetValue(typeof(TEvent), out Dictionary>>? actions) + && actions.TryGetValue(name, out List>? handlers)) + { + foreach (Action handler in handlers) + { + handler(@event); + } + } + } + + /// + /// Unsubscribe of ALL events of the given type matching the name. + /// + /// + /// + /// True/False if remove was successfull + public bool Unsubscribe(string name) where TEvent : class, IEvent + { + if (_handlers.ContainsKey(typeof(TEvent)) && _handlers[typeof(TEvent)].ContainsKey(name)) + { + return _handlers[typeof(TEvent)].Remove(name); + } + + return false; + } +} + diff --git a/roles/lib/files/FWO.Services/EventMediator/Events/AppServerImportEvent.cs b/roles/lib/files/FWO.Services/EventMediator/Events/AppServerImportEvent.cs new file mode 100644 index 0000000000..cec5dc0e2a --- /dev/null +++ b/roles/lib/files/FWO.Services/EventMediator/Events/AppServerImportEvent.cs @@ -0,0 +1,15 @@ +using FWO.Services.EventMediator.Interfaces; + +namespace FWO.Services.EventMediator.Events +{ + public class AppServerImportEvent(AppServerImportEventArgs? eventArgs = default) : IEvent + { + public AppServerImportEventArgs? EventArgs { get; set; } = eventArgs ?? new AppServerImportEventArgs(); + + IEventArgs? IEvent.EventArgs + { + get => EventArgs; + set => EventArgs = value as AppServerImportEventArgs; + } + } +} diff --git a/roles/lib/files/FWO.Services/EventMediator/Events/AppServerImportEventArgs.cs b/roles/lib/files/FWO.Services/EventMediator/Events/AppServerImportEventArgs.cs new file mode 100644 index 0000000000..4ca7c1d004 --- /dev/null +++ b/roles/lib/files/FWO.Services/EventMediator/Events/AppServerImportEventArgs.cs @@ -0,0 +1,12 @@ +using FWO.Data; +using FWO.Services.EventMediator.Interfaces; + +namespace FWO.Services.EventMediator.Events +{ + public class AppServerImportEventArgs(bool success = false) : IEventArgs + { + public bool Success { get; set; } = success; + public List Errors { get; set; } = []; + public List Appserver { get; set; } = []; + } +} diff --git a/roles/lib/files/FWO.Services/EventMediator/Events/CollectionChangedEvent.cs b/roles/lib/files/FWO.Services/EventMediator/Events/CollectionChangedEvent.cs new file mode 100644 index 0000000000..4ef349e3f4 --- /dev/null +++ b/roles/lib/files/FWO.Services/EventMediator/Events/CollectionChangedEvent.cs @@ -0,0 +1,11 @@ +using FWO.Services.EventMediator.Interfaces; + +namespace FWO.Services.EventMediator.Events +{ + public class CollectionChangedEvent(CollectionChangedEventArgs? eventArgs = default) : IEvent + { + private readonly CollectionChangedEventArgs? eventArgs = eventArgs; + + IEventArgs? IEvent.EventArgs { get; set; } + } +} diff --git a/roles/lib/files/FWO.Services/EventMediator/Events/CollectionChangedEventArgs.cs b/roles/lib/files/FWO.Services/EventMediator/Events/CollectionChangedEventArgs.cs new file mode 100644 index 0000000000..7e9ba0289c --- /dev/null +++ b/roles/lib/files/FWO.Services/EventMediator/Events/CollectionChangedEventArgs.cs @@ -0,0 +1,11 @@ +using FWO.Data; +using FWO.Services.EventMediator.Interfaces; + +namespace FWO.Services.EventMediator.Events +{ + public class CollectionChangedEventArgs(IEnumerable? collection = default, ErrorBaseModel? error = default) : IEventArgs + { + public ErrorBaseModel? Error { get; set; } = error ?? new ErrorBaseModel(); + IEnumerable Collection { get; } = collection ?? []; + } +} diff --git a/roles/lib/files/FWO.Services/EventMediator/Events/FileUploadEvent.cs b/roles/lib/files/FWO.Services/EventMediator/Events/FileUploadEvent.cs new file mode 100644 index 0000000000..f746e58c63 --- /dev/null +++ b/roles/lib/files/FWO.Services/EventMediator/Events/FileUploadEvent.cs @@ -0,0 +1,15 @@ +using FWO.Services.EventMediator.Interfaces; + +namespace FWO.Services.EventMediator.Events +{ + public class FileUploadEvent(FileUploadEventArgs? eventArgs = default) : IEvent + { + public FileUploadEventArgs? EventArgs { get; set; } = eventArgs ?? new FileUploadEventArgs(); + + IEventArgs? IEvent.EventArgs + { + get => EventArgs; + set => EventArgs = value as FileUploadEventArgs; + } + } +} diff --git a/roles/lib/files/FWO.Services/EventMediator/Events/FileUploadEventArgs.cs b/roles/lib/files/FWO.Services/EventMediator/Events/FileUploadEventArgs.cs new file mode 100644 index 0000000000..04645157fe --- /dev/null +++ b/roles/lib/files/FWO.Services/EventMediator/Events/FileUploadEventArgs.cs @@ -0,0 +1,13 @@ +using FWO.Data; +using FWO.Services.EventMediator.Interfaces; + +namespace FWO.Services.EventMediator.Events +{ + public class FileUploadEventArgs(bool success = false, string? fileName = null, ErrorBaseModel? error = default) : IEventArgs + { + public bool Success { get; set; } = success; + public string? FileName { get; set; } = fileName; + public dynamic? Data { get; set; } + public ErrorBaseModel? Error { get; set; } = error ?? new ErrorBaseModel(); + } +} diff --git a/roles/lib/files/FWO.Services/EventMediator/Events/UpdateRuleOwnerMappingEvent.cs b/roles/lib/files/FWO.Services/EventMediator/Events/UpdateRuleOwnerMappingEvent.cs new file mode 100644 index 0000000000..55e398b725 --- /dev/null +++ b/roles/lib/files/FWO.Services/EventMediator/Events/UpdateRuleOwnerMappingEvent.cs @@ -0,0 +1,24 @@ +using FWO.Services.EventMediator.Interfaces; +using System; +using System.Collections.Generic; +using System.Text; + +namespace FWO.Services.EventMediator.Events +{ + public class UpdateRuleOwnerMappingEvent : IEvent + { + public UpdateRuleOwnerMappingEventArgs EventArgs { get; set; } + + IEventArgs? IEvent.EventArgs + { + get => EventArgs; + set => EventArgs = value as UpdateRuleOwnerMappingEventArgs ?? new UpdateRuleOwnerMappingEventArgs(); + } + + public UpdateRuleOwnerMappingEvent(UpdateRuleOwnerMappingEventArgs? args = null) + { + + EventArgs = args ?? new UpdateRuleOwnerMappingEventArgs(); + } + } +} diff --git a/roles/lib/files/FWO.Services/EventMediator/Events/UpdateRuleOwnerMappingEventArgs.cs b/roles/lib/files/FWO.Services/EventMediator/Events/UpdateRuleOwnerMappingEventArgs.cs new file mode 100644 index 0000000000..e68a3c0226 --- /dev/null +++ b/roles/lib/files/FWO.Services/EventMediator/Events/UpdateRuleOwnerMappingEventArgs.cs @@ -0,0 +1,17 @@ +using FWO.Data; +using FWO.Services.EventMediator.Interfaces; +using System; +using System.Collections.Generic; +using System.Text; + + +namespace FWO.Services.EventMediator.Events +{ + public class UpdateRuleOwnerMappingEventArgs : IEventArgs + { + public bool isFullReInitialize { get; set; } = false; + + public TaskCompletionSource? Completion { get; set; } + + } +} diff --git a/roles/lib/files/FWO.Services/EventMediator/Events/UserSessionClosedEvent.cs b/roles/lib/files/FWO.Services/EventMediator/Events/UserSessionClosedEvent.cs new file mode 100644 index 0000000000..43e7c356ee --- /dev/null +++ b/roles/lib/files/FWO.Services/EventMediator/Events/UserSessionClosedEvent.cs @@ -0,0 +1,15 @@ +using FWO.Services.EventMediator.Interfaces; + +namespace FWO.Services.EventMediator.Events +{ + public class UserSessionClosedEvent(UserSessionClosedEventArgs? eventArgs = default) : IEvent + { + public UserSessionClosedEventArgs? EventArgs { get; set; } = eventArgs ?? new UserSessionClosedEventArgs(); + + IEventArgs? IEvent.EventArgs + { + get => EventArgs; + set => EventArgs = value as UserSessionClosedEventArgs; + } + } +} diff --git a/roles/lib/files/FWO.Services/EventMediator/Events/UserSessionClosedEventArgs.cs b/roles/lib/files/FWO.Services/EventMediator/Events/UserSessionClosedEventArgs.cs new file mode 100644 index 0000000000..430af8d628 --- /dev/null +++ b/roles/lib/files/FWO.Services/EventMediator/Events/UserSessionClosedEventArgs.cs @@ -0,0 +1,11 @@ +using FWO.Data; +using FWO.Services.EventMediator.Interfaces; + +namespace FWO.Services.EventMediator.Events +{ + public class UserSessionClosedEventArgs(string userName = "", string? userDn = "") : IEventArgs + { + public string? UserName { get; set; } = userName; + public string? UserDn { get; set; } = userDn; + } +} diff --git a/roles/lib/files/FWO.Services/EventMediator/Interfaces/IEvent.cs b/roles/lib/files/FWO.Services/EventMediator/Interfaces/IEvent.cs new file mode 100644 index 0000000000..2c2fc120b3 --- /dev/null +++ b/roles/lib/files/FWO.Services/EventMediator/Interfaces/IEvent.cs @@ -0,0 +1,8 @@ +namespace FWO.Services.EventMediator.Interfaces +{ + public interface IEvent + { + public IEventArgs? EventArgs { get; set; } + } +} + diff --git a/roles/lib/files/FWO.Services/EventMediator/Interfaces/IEventArgs.cs b/roles/lib/files/FWO.Services/EventMediator/Interfaces/IEventArgs.cs new file mode 100644 index 0000000000..e433a0d90e --- /dev/null +++ b/roles/lib/files/FWO.Services/EventMediator/Interfaces/IEventArgs.cs @@ -0,0 +1,4 @@ +namespace FWO.Services.EventMediator.Interfaces +{ + public interface IEventArgs { } +} diff --git a/roles/lib/files/FWO.Services/EventMediator/Interfaces/IEventMediator.cs b/roles/lib/files/FWO.Services/EventMediator/Interfaces/IEventMediator.cs new file mode 100644 index 0000000000..74cd5e0310 --- /dev/null +++ b/roles/lib/files/FWO.Services/EventMediator/Interfaces/IEventMediator.cs @@ -0,0 +1,9 @@ +namespace FWO.Services.EventMediator.Interfaces +{ + public interface IEventMediator + { + void Subscribe(string name, Action handler) where TEvent : class, IEvent; + void Publish(string name, TEvent @event) where TEvent : class, IEvent; + bool Unsubscribe(string name) where TEvent : class, IEvent; + } +} diff --git a/roles/lib/files/FWO.Services/FWImportChangesNotifierBase.cs b/roles/lib/files/FWO.Services/FWImportChangesNotifierBase.cs new file mode 100644 index 0000000000..ae98c0c1ff --- /dev/null +++ b/roles/lib/files/FWO.Services/FWImportChangesNotifierBase.cs @@ -0,0 +1,29 @@ +using FWO.Services.EventMediator.Events; +using FWO.Services.EventMediator.Interfaces; +using System.Threading; + +namespace FWO.Services +{ + public abstract class FWImportChangesNotifierBase where TEventArgs : class, IEventArgs + { + private int running = 0; + + public async Task Run(TEventArgs? eventArgs = null) + { + if (Interlocked.Exchange(ref running, 1) == 1) + { + return false; + } + try + { + return await Execute(eventArgs); + } + finally + { + Interlocked.Exchange(ref running, 0); + } + } + + protected abstract Task Execute(TEventArgs? eventArgs = null); + } +} diff --git a/roles/lib/files/FWO.Services/FWO.Services.csproj b/roles/lib/files/FWO.Services/FWO.Services.csproj new file mode 100644 index 0000000000..a33c4ae6fd --- /dev/null +++ b/roles/lib/files/FWO.Services/FWO.Services.csproj @@ -0,0 +1,21 @@ + + + + net10.0 + enable + enable + + + + + + + + + + + + + + + diff --git a/roles/lib/files/FWO.Services/GroupAccess.cs b/roles/lib/files/FWO.Services/GroupAccess.cs new file mode 100644 index 0000000000..86f817ce48 --- /dev/null +++ b/roles/lib/files/FWO.Services/GroupAccess.cs @@ -0,0 +1,84 @@ +using FWO.Config.Api; +using FWO.Data; +using FWO.Data.Middleware; +using FWO.Middleware.Client; +using RestSharp; +using System.Net; + +namespace FWO.Services +{ + public class GroupAccess + { + static public async Task> GetGroupsFromInternalLdap(MiddlewareClient middlewareClient, UserConfig userConfig, + Action DisplayMessageInUi, bool ownerGroupsOnly = false) + { + List groups = []; + RestResponse> middlewareServerGroupsResponse = await middlewareClient.GetInternalGroups(); + if (middlewareServerGroupsResponse.StatusCode != HttpStatusCode.OK || middlewareServerGroupsResponse.Data == null) + { + DisplayMessageInUi(null, userConfig.GetText("fetch_groups"), userConfig.GetText("E5231"), true); + } + else + { + foreach (var ldapUserGroup in middlewareServerGroupsResponse.Data) + { + if (!ownerGroupsOnly || ldapUserGroup.OwnerGroup) + { + UserGroup group = new() + { + Dn = ldapUserGroup.GroupDn, + Name = new DistName(ldapUserGroup.GroupDn).Group, + OwnerGroup = ldapUserGroup.OwnerGroup + }; + foreach (var userDn in ldapUserGroup.Members) + { + UiUser newUser = new() { Dn = userDn, Name = new DistName(userDn).UserName }; + group.Users.Add(newUser); + } + groups.Add(group); + } + } + } + return groups; + } + + static public async Task> GetGroupDnsFromInternalLdap(MiddlewareClient middlewareClient, UserConfig userConfig, Action DisplayMessageInUi) + { + List groupDns = []; + RestResponse> middlewareServerGroupsResponse = await middlewareClient.GetInternalGroups(); + if (middlewareServerGroupsResponse.StatusCode != HttpStatusCode.OK || middlewareServerGroupsResponse.Data == null) + { + DisplayMessageInUi(null, userConfig.GetText("fetch_groups"), userConfig.GetText("E5231"), true); + } + else + { + foreach (var ldapUserGroup in middlewareServerGroupsResponse.Data) + { + groupDns.Add(ldapUserGroup.GroupDn); + } + } + return groupDns; + } + + static public async Task> GetGroupMemberships(MiddlewareClient middlewareClient, UserConfig userConfig, + Action DisplayMessageInUi) + { + List groupDns = []; + GroupMembershipGetParameters parameters = new() + { + UserDn = userConfig.User.Dn, + UserName = userConfig.User.Name + }; + RestResponse> middlewareServerGroupsResponse = await middlewareClient.GetGroupMemberships(parameters); + if (middlewareServerGroupsResponse.StatusCode != HttpStatusCode.OK || middlewareServerGroupsResponse.Data == null) + { + DisplayMessageInUi(null, userConfig.GetText("fetch_groups"), userConfig.GetText("E5231"), true); + } + else + { + groupDns.AddRange(middlewareServerGroupsResponse.Data); + } + return groupDns; + } + } +} diff --git a/roles/lib/files/FWO.Services/Logging/AutodiscoveryLogMapper.cs b/roles/lib/files/FWO.Services/Logging/AutodiscoveryLogMapper.cs new file mode 100644 index 0000000000..2443739248 --- /dev/null +++ b/roles/lib/files/FWO.Services/Logging/AutodiscoveryLogMapper.cs @@ -0,0 +1,120 @@ +using System.Text.Json; +using FWO.Data; + +namespace FWO.Services.Logging; + +public static class AutodiscoveryLogMapper +{ + public sealed class PromptLogData + { + public required ChangeLogObject Object { get; init; } + public required ChangeLogOperation Operation { get; init; } + public (string Key, object? Value)[] Fields { get; init; } = []; + } + + public static bool TryMapPromptAction(ActionItem action, out PromptLogData? logData) + { + logData = action.ActionType switch + { + nameof(ActionCode.AddManagement) => CreateManagementAddLogData(action), + nameof(ActionCode.DeleteManagement) => new PromptLogData + { + Object = ChangeLogObject.Management, + Operation = ChangeLogOperation.Delete, + Fields = + [ + ("Management ID", action.ManagementId) + ] + }, + nameof(ActionCode.ReactivateManagement) => new PromptLogData + { + Object = ChangeLogObject.Management, + Operation = ChangeLogOperation.Activate, + Fields = + [ + ("Management ID", action.ManagementId) + ] + }, + nameof(ActionCode.DeleteGateway) => new PromptLogData + { + Object = ChangeLogObject.Gateway, + Operation = ChangeLogOperation.Delete, + Fields = + [ + ("Device ID", action.DeviceId), + ("Management ID", action.ManagementId) + ] + }, + nameof(ActionCode.AddGatewayToNewManagement) => CreateGatewayAddLogData(action, false), + nameof(ActionCode.AddGatewayToExistingManagement) => CreateGatewayAddLogData(action, true), + nameof(ActionCode.ReactivateGateway) => new PromptLogData + { + Object = ChangeLogObject.Gateway, + Operation = ChangeLogOperation.Activate, + Fields = + [ + ("Device ID", action.DeviceId), + ("Management ID", action.ManagementId) + ] + }, + _ => null + }; + + return logData != null; + } + + private static PromptLogData CreateManagementAddLogData(ActionItem action) + { + Management? management = DeserializeJsonData(action.JsonData); + return new PromptLogData + { + Object = ChangeLogObject.Management, + Operation = ChangeLogOperation.Create, + Fields = + [ + ("Management ID", action.ManagementId), + ("Management Name", management?.Name), + ("Management Hostname", management?.Hostname) + ] + }; + } + + private static PromptLogData? CreateGatewayAddLogData(ActionItem action, bool includeExistingManagementId) + { + Device? device = DeserializeJsonData(action.JsonData); + return new PromptLogData + { + Object = ChangeLogObject.Gateway, + Operation = ChangeLogOperation.Create, + Fields = + [ + ("Device ID", action.DeviceId), + ("Device Name", device?.Name), + ("Management ID", includeExistingManagementId ? action.ManagementId : device?.Management?.Id), + ("Management Name", device?.Management?.Name) + ] + }; + } + + private static T? DeserializeJsonData(object? jsonData) + { + if (jsonData == null) + { + return default; + } + + try + { + return jsonData switch + { + string json => JsonSerializer.Deserialize(json), + JsonElement element => element.Deserialize(), + _ => JsonSerializer.Deserialize(jsonData.ToString() ?? string.Empty) + }; + } + catch + { + return default; + } + } +} diff --git a/roles/lib/files/FWO.Services/Logging/ChangeLogHelper.cs b/roles/lib/files/FWO.Services/Logging/ChangeLogHelper.cs new file mode 100644 index 0000000000..2f3969b8ec --- /dev/null +++ b/roles/lib/files/FWO.Services/Logging/ChangeLogHelper.cs @@ -0,0 +1,122 @@ +using System.Globalization; +using System.Text; +using FWO.Data; +using FWO.Data.Logging; +using FWO.Logging; + +namespace FWO.Services.Logging +{ + public static class ChangeLogHelper + { + public static Task LogChange(ChangeLogRequest request) + { + string title = ComposeChangeLogTitle(request.Family, request.Object, request.Operation); + string text = + $"User ID: {request.UserId}; Date/Time: {request.Timestamp.ToString(CultureInfo.InvariantCulture)}; Origin: {GetOriginName(request.Origin)}; " + + FormatFields(request.Fields); + + switch (request.Family) + { + case ChangeLogFamily.Manual: + Log.WriteAudit(title, text); + break; + case ChangeLogFamily.Import: + Log.WriteInfo(title, text); + break; + default: + Log.WriteWarning(title, $"Unmapped change-log family. {text}"); + break; + } + + return Task.CompletedTask; + } + + public static Task LogMatrixChange(MatrixChangeLogRequest request) + { + return LogChange(request.ToChangeLogRequest()); + } + + public static Task LogManagerChange(ManagementChangeLogRequest request) + { + return LogChange(request.ToChangeLogRequest()); + } + + public static Task LogGatewayChange(GatewayChangeLogRequest request) + { + return LogChange(request.ToChangeLogRequest()); + } + + private static string ComposeChangeLogTitle(ChangeLogFamily family, ChangeLogObject obj, ChangeLogOperation operation) + { + return $"{GetFamilyName(family)} {GetObjectName(obj)} {GetOperationName(operation)}"; + } + + public static string GetOriginName(ChangeLogOrigin origin) + { + return origin switch + { + ChangeLogOrigin.UiSettings => "UI", + ChangeLogOrigin.Autodiscovery => "Autodiscovery", + ChangeLogOrigin.Import => "Import", + _ => origin.ToString() + }; + } + + private static string GetFamilyName(ChangeLogFamily family) + { + return family switch + { + ChangeLogFamily.Manual => "Manual", + ChangeLogFamily.Import => "Import", + _ => family.ToString() + }; + } + + public static string GetObjectName(ChangeLogObject obj) + { + return obj switch + { + ChangeLogObject.Matrix => "Matrix", + ChangeLogObject.Management => "Management", + ChangeLogObject.Gateway => "Gateway", + _ => obj.ToString() + }; + } + + public static string GetOperationName(ChangeLogOperation operation) + { + return operation switch + { + ChangeLogOperation.Create => "Create", + ChangeLogOperation.Update => "Update", + ChangeLogOperation.Delete => "Delete", + ChangeLogOperation.SetRemoved => "Set to removed", + ChangeLogOperation.Disable => "Disable", + ChangeLogOperation.Activate => "Activate", + _ => operation.ToString() + }; + } + + public static string FormatFields(params (string Key, object? Value)[] fields) + { + StringBuilder sb = new(); + + foreach ((string key, object? value) in fields) + { + if (value == null) + { + continue; + } + + if (sb.Length > 0) + { + sb.Append("; "); + } + + sb.Append(key).Append(": ").Append(value); + } + + return sb.Length > 0 ? sb.ToString() : string.Empty; + } + } +} diff --git a/roles/lib/files/FWO.Services/Logging/PromptLogHelper.cs b/roles/lib/files/FWO.Services/Logging/PromptLogHelper.cs new file mode 100644 index 0000000000..08159c6249 --- /dev/null +++ b/roles/lib/files/FWO.Services/Logging/PromptLogHelper.cs @@ -0,0 +1,47 @@ +using System.Globalization; +using FWO.Data; +using FWO.Data.Logging; +using FWO.Logging; + +namespace FWO.Services.Logging +{ + public static class PromptLogHelper + { + public static Task LogPrompt(PromptLogRequest request) + { + string title = ComposePromptLogTitle(request.PromptEvent, request.Object, request.Operation); + string text = + $"User ID: {request.UserId}; Date/Time: {request.Timestamp.ToString(CultureInfo.InvariantCulture)}; Origin: {ChangeLogHelper.GetOriginName(request.Origin)}; " + + ChangeLogHelper.FormatFields(request.Fields); + Log.WriteInfo(title, text); + return Task.CompletedTask; + } + + public static Task LogManagementPrompt(ManagementPromptLogRequest request) + { + return LogPrompt(request.ToPromptLogRequest()); + } + + public static Task LogGatewayPrompt(GatewayPromptLogRequest request) + { + return LogPrompt(request.ToPromptLogRequest()); + } + + private static string GetPromptEventName(PromptLogEvent logEvent) + { + return logEvent switch + { + PromptLogEvent.Completed => "Completed", + PromptLogEvent.Created => "Created", + PromptLogEvent.Dismissed => "Dismissed", + _ => logEvent.ToString() + }; + } + + private static string ComposePromptLogTitle(PromptLogEvent promptEvent, ChangeLogObject obj, + ChangeLogOperation operation) + { + return $"{ChangeLogHelper.GetObjectName(obj)} {ChangeLogHelper.GetOperationName(operation)} Prompt {GetPromptEventName(promptEvent)}"; + } + } +} diff --git a/roles/lib/files/FWO.Services/Modelling/AppRoleComparer.cs b/roles/lib/files/FWO.Services/Modelling/AppRoleComparer.cs new file mode 100644 index 0000000000..3aa20c8b8a --- /dev/null +++ b/roles/lib/files/FWO.Services/Modelling/AppRoleComparer.cs @@ -0,0 +1,27 @@ +using FWO.Data.Modelling; + +namespace FWO.Services.Modelling +{ + public class AppRoleComparer() : IEqualityComparer + { + public bool Equals(ModellingAppRole? appRole1, ModellingAppRole? appRole2) + { + if (ReferenceEquals(appRole1, appRole2)) + { + return true; + } + + if (appRole1 is null || appRole2 is null) + { + return false; + } + + return appRole1.Name == appRole2.Name; + } + + public int GetHashCode(ModellingAppRole appRole) + { + return HashCode.Combine(appRole.Name); + } + } +} diff --git a/roles/lib/files/FWO.Services/Modelling/AppServerComparer.cs b/roles/lib/files/FWO.Services/Modelling/AppServerComparer.cs new file mode 100644 index 0000000000..02dbad6210 --- /dev/null +++ b/roles/lib/files/FWO.Services/Modelling/AppServerComparer.cs @@ -0,0 +1,42 @@ +using FWO.Data.Modelling; + +namespace FWO.Services.Modelling +{ + public class AppServerComparer(ModellingNamingConvention namingConvention) : IEqualityComparer, IEqualityComparer + { + readonly ModellingNamingConvention NamingConvention = namingConvention; + + public bool Equals(ModellingAppServerWrapper? appServerWrapper1, ModellingAppServerWrapper? appServerWrapper2) + { + return appServerWrapper1 is not null && appServerWrapper2 is not null && Equals(appServerWrapper1.Content, appServerWrapper2.Content); + } + + public bool Equals(ModellingAppServer? appServer1, ModellingAppServer? appServer2) + { + if (ReferenceEquals(appServer1, appServer2)) + { + return true; + } + + if (appServer1 is null || appServer2 is null) + { + return false; + } + + string appServer1Name = AppServerHelper.ConstructSanitizedAppServerName(appServer1, NamingConvention); + string appServer2Name = AppServerHelper.ConstructSanitizedAppServerName(appServer2, NamingConvention); + return string.Equals(appServer1Name, appServer2Name, StringComparison.OrdinalIgnoreCase); + } + + public int GetHashCode(ModellingAppServerWrapper appServerWrapper) + { + return appServerWrapper == null ? 0 : GetHashCode(appServerWrapper.Content); + } + + public int GetHashCode(ModellingAppServer appServer) + { + string appServerName = AppServerHelper.ConstructSanitizedAppServerName(appServer, NamingConvention).ToLower().Trim(); + return HashCode.Combine(appServerName); + } + } +} diff --git a/roles/lib/files/FWO.Services/Modelling/AppServerHelper.cs b/roles/lib/files/FWO.Services/Modelling/AppServerHelper.cs new file mode 100644 index 0000000000..3817683de6 --- /dev/null +++ b/roles/lib/files/FWO.Services/Modelling/AppServerHelper.cs @@ -0,0 +1,429 @@ +using FWO.Api.Client; +using FWO.Api.Client.Queries; +using FWO.Basics; +using FWO.Config.Api; +using FWO.Data; +using FWO.Data.Modelling; +using FWO.Logging; +using System.Net; +using System.Text.Json; + +namespace FWO.Services.Modelling +{ + public static class AppServerHelper + { + public static async Task ConstructAppServerNameFromDns(ModellingAppServer appServer, ModellingNamingConvention namingConvention, + bool overwriteExistingNames = false, bool logUnresolvable = false) + { + if ((string.IsNullOrEmpty(appServer.IpEnd) || appServer.IpEnd == appServer.Ip) && IPAddress.TryParse(appServer.Ip.StripOffNetmask(), out IPAddress? ip)) + { + string dnsName = await IpOperations.DnsReverseLookUpPreferredAsync(ip); + if (string.IsNullOrEmpty(dnsName)) + { + if (logUnresolvable) + { + Log.WriteDebug("Import App Server Data", $"Found empty (unresolvable) IP {appServer.Ip}"); + } + } + else + { + appServer.Name = dnsName; + return dnsName; + } + } + if (string.IsNullOrEmpty(appServer.Name) || overwriteExistingNames) + { + appServer.Name = ConstructAppServerName(appServer, namingConvention, overwriteExistingNames); + } + return appServer.Name; + } + + public static string ConstructSanitizedAppServerName(ModellingAppServer appServer, ModellingNamingConvention namingConvention, bool overwriteExistingNames = false) + { + bool shortened = false; + return ConstructAppServerName(appServer, namingConvention, overwriteExistingNames).SanitizeJsonFieldMand(ref shortened); + } + + public static string ConstructAppServerName(ModellingAppServer appServer, ModellingNamingConvention namingConvention, bool overwriteExistingNames = false) + { + if (string.IsNullOrEmpty(appServer.Name) || overwriteExistingNames) + { + return GetPrefix(appServer, namingConvention) + DisplayBase.DisplayIp(appServer.Ip, appServer.IpEnd); + } + return char.IsLetter(appServer.Name[0]) ? appServer.Name : GetPrefix(appServer, namingConvention) + appServer.Name; + } + + public static async Task AdjustAppServerNames(ApiConnection apiConnection, UserConfig userConfig) + { + Log.WriteDebug($"Start adjusting App Server Names", ""); + ModellingNamingConvention namingConvention = JsonSerializer.Deserialize(userConfig.ModNamingConvention) ?? new(); + List AppServers = await apiConnection.SendQueryAsync>(ModellingQueries.getAllAppServers); + int correctedCounter = 0; + int failCounter = 0; + foreach (var appServer in AppServers) + { + string oldName = appServer.Name; + if ((await ConstructAppServerNameFromDns(appServer, namingConvention, userConfig.OverwriteExistingNames)) != oldName) + { + appServer.ImportSource = GlobalConst.kAdjustAppServerNames; + if (await UpdateName(apiConnection, userConfig, appServer, oldName)) + { + correctedCounter++; + } + else + { + failCounter++; + } + } + } + Log.WriteInfo($"Adjusted App Server Names", $"{correctedCounter} out of {AppServers.Count} App Servers have been corrected, {failCounter} failed"); + } + + public static async Task NoHigherPrioActive(ApiConnection apiConnection, ModellingAppServer incomingAppServer) + { + try + { + List ExistingAppServersSameIp = await GetExistingSameIp(apiConnection, incomingAppServer); + return ExistingAppServersSameIp.FirstOrDefault(x => Prio(x.ImportSource) > Prio(incomingAppServer.ImportSource) && !x.IsDeleted) == null; + } + catch (Exception exception) + { + Log.WriteError("Check App Server Prio", $" Check of {incomingAppServer.Name} from {incomingAppServer.ImportSource} to exception:", exception); + } + return true; + } + + public static async Task ReactivateOtherSource(ApiConnection apiConnection, UserConfig userConfig, ModellingAppServer deletedAppServer) + { + try + { + List ExistingOtherAppServersSameIp = [.. (await GetExistingSameIp(apiConnection, deletedAppServer)).Where(x => x.Id != deletedAppServer.Id)]; + if (ExistingOtherAppServersSameIp.Count > 0) + { + int maxPrio = ExistingOtherAppServersSameIp.Max(x => Prio(x.ImportSource)); + List ExistingOtherAppServersMaxPrio = [.. ExistingOtherAppServersSameIp.Where(x => Prio(x.ImportSource) == maxPrio)]; + long reactivatedId = ExistingOtherAppServersMaxPrio.Max(x => x.Id); + ModellingAppServer reactivatedAppServer = ExistingOtherAppServersMaxPrio.First(x => x.Id == reactivatedId); + var Variables = new + { + id = reactivatedId, + deleted = false + }; + await apiConnection.SendQueryAsync(ModellingQueries.setAppServerDeletedState, Variables); + await ModellingHandlerBase.LogChange(new LogChangeRequest + { + ChangeType = ModellingTypes.ChangeType.Reactivate, + ObjectType = ModellingTypes.ModObjectType.AppServer, + ObjectId = reactivatedAppServer.Id, + Text = $"Reactivated App Server: {reactivatedAppServer.Display()}", + ApiConnection = apiConnection, + UserConfig = userConfig, + ApplicationId = reactivatedAppServer.AppId, + DisplayMessageInUi = DefaultInit.DoNothing, + ChangeSource = reactivatedAppServer.ImportSource + }); + if (userConfig.AutoReplaceAppServer) + { + await ReplaceAppServer(apiConnection, deletedAppServer.Id, reactivatedId); + } + } + } + catch (Exception exception) + { + Log.WriteError("Reactivate App Server", $"Reactivation of other than {deletedAppServer.Name} from {deletedAppServer.ImportSource} leads to exception:", exception); + } + } + + public static async Task DeactivateOtherSources(ApiConnection apiConnection, UserConfig userConfig, ModellingAppServer incomingAppServer) + { + try + { + List ExistingActiveAppServersSameIp = [.. (await GetExistingSameIp(apiConnection, incomingAppServer)).Where(x => x.Id != incomingAppServer.Id && !x.IsDeleted)]; + if (ExistingActiveAppServersSameIp.Count > 0) + { + foreach (var activeAppServer in ExistingActiveAppServersSameIp) + { + await DeactivateAppServer(apiConnection, userConfig, activeAppServer, incomingAppServer); + } + } + } + catch (Exception exception) + { + Log.WriteError("Deactivate App Servers", $"Deactivation of {incomingAppServer.Name} from {incomingAppServer.ImportSource} leads to exception:", exception); + } + } + + public static async Task<(long?, string?)> UpsertAppServer(ApiConnection apiConnection, UserConfig userConfig, ModellingAppServer incomingAppServer, bool nameCheck, bool manual = false, bool addMode = false) + { + try + { + if (nameCheck && await CheckNameExisting(apiConnection, incomingAppServer)) + { + return (null, incomingAppServer.Name); + } + + List ExistingAppServersSameIp = await GetExistingSameIp(apiConnection, incomingAppServer); + + long? AppServerId = null; + if (ExistingAppServersSameIp == null || ExistingAppServersSameIp.Count == 0) + { + AppServerId = manual && !addMode ? await UpdateAppServerInDb(apiConnection, userConfig, incomingAppServer) : + await AddAppServerToDb(apiConnection, userConfig, incomingAppServer); + return (AppServerId, null); + } + + ModellingAppServer? higherPrioAppServer = ExistingAppServersSameIp.FirstOrDefault(x => Prio(x.ImportSource) > Prio(incomingAppServer.ImportSource) && !x.IsDeleted); + if (higherPrioAppServer != null) + { + return (null, higherPrioAppServer.Name); + } + + if (manual) + { + ModellingAppServer? otherAppServerSameIp = ExistingAppServersSameIp.FirstOrDefault(x => x.Id != incomingAppServer.Id && !x.IsDeleted); + if (otherAppServerSameIp != null) + { + return (null, otherAppServerSameIp.Name); + } + } + + return await OverwriteAppServer(apiConnection, userConfig, incomingAppServer, ExistingAppServersSameIp); + } + catch (Exception exception) + { + Log.WriteError("Upsert App Server", $"Upsert of {incomingAppServer.Name} leads to exception:", exception); + return (null, null); + } + } + + private static async Task> GetExistingSameIp(ApiConnection apiConnection, ModellingAppServer appServer) + { + try + { + var Variables = new + { + appId = appServer.AppId, + ip = appServer.Ip.IpAsCidr(), + ipEnd = appServer.IpEnd.IpAsCidr() + }; + return await apiConnection.SendQueryAsync>(ModellingQueries.getAppServersByIp, Variables); + } + catch (Exception exception) + { + Log.WriteError("Get Existing App Server", $"leads to exception:", exception); + return []; + } + } + + private static async Task<(long?, string?)> OverwriteAppServer(ApiConnection apiConnection, UserConfig userConfig, ModellingAppServer incomingAppServer, List existingAppServersSameIp) + { + long? AppServerId = null; + string? exAppServerName = null; + ModellingAppServer? existAppServerSameSource = existingAppServersSameIp.FirstOrDefault(x => x.ImportSource == incomingAppServer.ImportSource); + if (existAppServerSameSource != null) + { + incomingAppServer.Id = existAppServerSameSource.Id; + await UpdateAppServerInDb(apiConnection, userConfig, incomingAppServer); + AppServerId = incomingAppServer.Id; + exAppServerName = existAppServerSameSource.Name; + } + else + { + AppServerId = await AddAppServerToDb(apiConnection, userConfig, incomingAppServer); + } + + foreach (var existAppServerOtherSource in existingAppServersSameIp.Where(x => x.ImportSource != incomingAppServer.ImportSource)) + { + if (!existAppServerOtherSource.IsDeleted) + { + await DeactivateAppServer(apiConnection, userConfig, existAppServerOtherSource, incomingAppServer); + } + } + return (AppServerId, exAppServerName); + } + + private static async Task DeactivateAppServer(ApiConnection apiConnection, UserConfig userConfig, ModellingAppServer appServerToDeactivate, ModellingAppServer newAppServer) + { + try + { + await apiConnection.SendQueryAsync(ModellingQueries.setAppServerDeletedState, new { id = appServerToDeactivate.Id, deleted = true }); + await ModellingHandlerBase.LogChange(new LogChangeRequest + { + ChangeType = ModellingTypes.ChangeType.MarkDeleted, + ObjectType = ModellingTypes.ModObjectType.AppServer, + ObjectId = appServerToDeactivate.Id, + Text = $"Deactivated App Server: {appServerToDeactivate.Display()}", + ApiConnection = apiConnection, + UserConfig = userConfig, + ApplicationId = appServerToDeactivate.AppId, + DisplayMessageInUi = DefaultInit.DoNothing, + ChangeSource = appServerToDeactivate.ImportSource + }); + if (userConfig.AutoReplaceAppServer) + { + await ReplaceAppServer(apiConnection, appServerToDeactivate.Id, newAppServer.Id); + } + } + catch (Exception exception) + { + Log.WriteError("Deactivate App Server", $"leads to exception:", exception); + } + } + + private static async Task ReplaceAppServer(ApiConnection apiConnection, long oldAppServerId, long newAppServerId) + { + try + { + await apiConnection.SendQueryAsync(ModellingQueries.updateNwObjectInNwGroup, new { oldObjectId = oldAppServerId, newObjectId = newAppServerId }); + await apiConnection.SendQueryAsync(ModellingQueries.updateNwObjectInConnection, new { oldObjectId = oldAppServerId, newObjectId = newAppServerId }); + } + catch (Exception exception) + { + Log.WriteError("Replace App Server", $"Replacing {oldAppServerId} by {newAppServerId} leads to exception:", exception); + } + } + + private static async Task CheckNameExisting(ApiConnection apiConnection, ModellingAppServer incomingAppServer) + { + try + { + var Variables = new + { + appId = incomingAppServer.AppId, + name = incomingAppServer.Name + }; + List ExistingAppServersSameIp = await apiConnection.SendQueryAsync>(ModellingQueries.getAppServersByName, Variables); + return ExistingAppServersSameIp != null && ExistingAppServersSameIp.Count > 0 && ExistingAppServersSameIp.FirstOrDefault(x => x.Id == incomingAppServer.Id && !x.IsDeleted) == null; + } + catch (Exception exception) + { + Log.WriteError("Upsert App Server", $"leads to exception:", exception); + return false; + } + } + + private static string GetPrefix(ModellingAppServer appServer, ModellingNamingConvention namingConvention) + { + return IpOperations.GetObjectType(appServer.Ip, appServer.IpEnd) switch + { + ObjectType.Host => namingConvention.AppServerPrefix ?? "", + ObjectType.Network => namingConvention.NetworkPrefix ?? "", + ObjectType.IPRange => namingConvention.IpRangePrefix ?? "", + _ => "" + }; + } + + private static async Task UpdateName(ApiConnection apiConnection, UserConfig userConfig, ModellingAppServer appServer, string oldName) + { + try + { + var Variables = new + { + id = appServer.Id, + newName = appServer.Name + }; + await apiConnection.SendQueryAsync(ModellingQueries.setAppServerName, Variables); + await ModellingHandlerBase.LogChange(new LogChangeRequest + { + ChangeType = ModellingTypes.ChangeType.Update, + ObjectType = ModellingTypes.ModObjectType.AppServer, + ObjectId = appServer.Id, + Text = $"Updated App Server Name: {appServer.Display()}", + ApiConnection = apiConnection, + UserConfig = userConfig, + ApplicationId = appServer.AppId, + DisplayMessageInUi = DefaultInit.DoNothing, + ChangeSource = appServer.ImportSource + }); + Log.WriteDebug($"Correct App Server Name", $"Changed {oldName} to {appServer.Name}."); + return true; + } + catch (Exception exception) + { + Log.WriteError("Correct AppServer Name", $"Leads to exception:", exception); + return false; + } + } + + private static int Prio(string importSource) + { + return (importSource == GlobalConst.kManual || importSource.StartsWith(GlobalConst.kCSV_)) ? 0 : 1; + } + + private static async Task AddAppServerToDb(ApiConnection apiConnection, UserConfig userConfig, ModellingAppServer appServer) + { + try + { + var Variables = new + { + name = appServer.Name, + appId = appServer.AppId, + ip = appServer.Ip.IpAsCidr(), + ipEnd = appServer.IpEnd.IpAsCidr(), + importSource = appServer.ImportSource, + customType = appServer.CustomType + }; + ReturnId[]? returnIds = (await apiConnection.SendQueryAsync(ModellingQueries.newAppServer, Variables)).ReturnIds; + if (returnIds != null && returnIds.Length > 0) + { + appServer.Id = returnIds[0].NewIdLong; + await ModellingHandlerBase.LogChange(new LogChangeRequest + { + ChangeType = ModellingTypes.ChangeType.Insert, + ObjectType = ModellingTypes.ModObjectType.AppServer, + ObjectId = appServer.Id, + Text = $"New App Server: {appServer.Display()}", + ApiConnection = apiConnection, + UserConfig = userConfig, + ApplicationId = appServer.AppId, + DisplayMessageInUi = DefaultInit.DoNothing, + ChangeSource = appServer.ImportSource + }); + return appServer.Id; + } + return null; + } + catch (Exception exception) + { + Log.WriteError("Add App Server", $"Leads to exception:", exception); + return null; + } + } + + private static async Task UpdateAppServerInDb(ApiConnection apiConnection, UserConfig userConfig, ModellingAppServer appServer) + { + try + { + var Variables = new + { + id = appServer.Id, + name = appServer.Name, + appId = appServer.AppId, + ip = appServer.Ip.IpAsCidr(), + ipEnd = appServer.IpEnd.IpAsCidr(), + importSource = appServer.ImportSource, + customType = appServer.CustomType + }; + await apiConnection.SendQueryAsync(ModellingQueries.updateAppServer, Variables); + await ModellingHandlerBase.LogChange(new LogChangeRequest + { + ChangeType = ModellingTypes.ChangeType.Update, + ObjectType = ModellingTypes.ModObjectType.AppServer, + ObjectId = appServer.Id, + Text = $"Updated App Server: {appServer.Display()}", + ApiConnection = apiConnection, + UserConfig = userConfig, + ApplicationId = appServer.AppId, + DisplayMessageInUi = DefaultInit.DoNothing, + ChangeSource = appServer.ImportSource + }); + return appServer.Id; + } + catch (Exception exception) + { + Log.WriteError("Add App Server", $"Leads to exception:", exception); + return null; + } + } + } +} diff --git a/roles/lib/files/FWO.Services/Modelling/AppZoneComparer.cs b/roles/lib/files/FWO.Services/Modelling/AppZoneComparer.cs new file mode 100644 index 0000000000..e8e07f61e0 --- /dev/null +++ b/roles/lib/files/FWO.Services/Modelling/AppZoneComparer.cs @@ -0,0 +1,35 @@ +using FWO.Data.Modelling; + +namespace FWO.Services.Modelling +{ + public class AppZoneComparer(ModellingNamingConvention namingConvention) : IEqualityComparer + { + readonly AppServerComparer appServerComparer = new(namingConvention); + + public bool Equals(ModellingAppZone? appZone1, ModellingAppZone? appZone2) + { + if (ReferenceEquals(appZone1, appZone2)) + { + return true; + } + + if (appZone1 is null || appZone2 is null || appZone1.IdString != appZone2.IdString || appZone1.AppServers.Count != appZone2.AppServers.Count) + { + return false; + } + + return appZone1.AppServers.Except([.. appZone2.AppServers], appServerComparer).ToList().Count == 0 + && appZone2.AppServers.Except([.. appZone1.AppServers], appServerComparer).ToList().Count == 0; + } + + public int GetHashCode(ModellingAppZone appZone) + { + int hashCode = 0; + foreach (var appSrv in appZone.AppServers) + { + hashCode ^= appSrv != null ? appServerComparer.GetHashCode(appSrv) : 0; + } + return hashCode ^ HashCode.Combine(appZone.IdString); + } + } +} diff --git a/roles/lib/files/FWO.Services/Modelling/ModellingAppRoleHandler.cs b/roles/lib/files/FWO.Services/Modelling/ModellingAppRoleHandler.cs new file mode 100644 index 0000000000..44161f81e5 --- /dev/null +++ b/roles/lib/files/FWO.Services/Modelling/ModellingAppRoleHandler.cs @@ -0,0 +1,354 @@ +using FWO.Api.Client; +using FWO.Api.Client.Queries; +using FWO.Data; +using FWO.Data.Modelling; +using FWO.Basics; +using FWO.Config.Api; +using NetTools; +using System.Net; +using System.Text.Json; + +namespace FWO.Services.Modelling +{ + public class ModellingAppRoleHandler : ModellingHandlerBase + { + public List AppRoles { get; set; } = []; + public ModellingAppRole ActAppRole { get; set; } = new(); + public List AppServersInArea { get; set; } = []; + public List AppServerToAdd { get; set; } = []; + public List AppServerToDelete { get; set; } = []; + public ModellingNamingConvention NamingConvention = new(); + + private ModellingManagedIdString OrigId = new(); + + public ModellingAppRoleHandler(ApiConnection apiConnection, UserConfig userConfig, FwoOwner application, + List appRoles, ModellingAppRole appRole, List availableAppServers, + List> availableNwElems, bool addMode, Action displayMessageInUi, bool isOwner = true, bool readOnly = false) + : base(apiConnection, userConfig, application, addMode, displayMessageInUi, readOnly, isOwner) + { + AppRoles = appRoles; + AvailableAppServers = availableAppServers; + AvailableNwElems = availableNwElems; + ActAppRole = appRole; + ApplyNamingConvention(application.ExtAppId ?? ""); + } + + private void ApplyNamingConvention(string extAppId) + { + NamingConvention = JsonSerializer.Deserialize(userConfig.ModNamingConvention) ?? new(); + foreach (ModellingAppRole aR in AppRoles) + { + aR.ManagedIdString.NamingConvention = NamingConvention; + } + ActAppRole.ManagedIdString.NamingConvention = NamingConvention; + if (AddMode) + { + ActAppRole.ManagedIdString.SetAppPartFromExtId(extAppId); + } + else + { + ActAppRole.Area = new() { IdString = ModellingManagedIdString.ConvertAppRoleToArea(ActAppRole.IdString, NamingConvention) }; + } + } + + public async Task InitAppRole(ModellingNetworkArea? newArea) + { + ActAppRole.Area = newArea; + if (newArea != null && newArea.IdString.Length >= NamingConvention.FixedPartLength && AddMode) + { + ActAppRole.ManagedIdString.ConvertAreaToAppRoleFixedPart(newArea.IdString); + ActAppRole.ManagedIdString.FreePart = await ProposeFreeAppRoleNumber(ActAppRole.ManagedIdString); + } + OrigId = new(ActAppRole.ManagedIdString); + await SelectAppServersFromArea(newArea); + } + + public void AppServerToAppRole(List appServers) + { + foreach (ModellingAppServer appServer in appServers) + { + if (!appServer.IsDeleted && ActAppRole.AppServers.FirstOrDefault(w => w.Content.Id == appServer.Id) == null && !AppServerToAdd.Contains(appServer)) + { + AppServerToAdd.Add(appServer); + } + } + } + + public async Task GetDummyAppRole() + { + List dummyAppRole = await apiConnection.SendQueryAsync>(ModellingQueries.getDummyAppRole); + if (dummyAppRole.Count > 0) + { + return dummyAppRole.First(); + } + ActAppRole.Name = GlobalConst.kDummyAppRole; + ActAppRole.IdString = GlobalConst.kDummyAppRole; + await AddAppRoleToDb(null); + return ActAppRole; + } + + public async Task Save() + { + try + { + if (ActAppRole.Sanitize()) + { + DisplayMessageInUi(null, userConfig.GetText("save_app_role"), userConfig.GetText("U0001"), true); + } + if (await CheckAppRole()) + { + foreach (ModellingAppServer appServer in AppServerToDelete) + { + ActAppRole.AppServers.Remove(ActAppRole.AppServers.FirstOrDefault(x => x.Content.Id == appServer.Id) ?? throw new KeyNotFoundException("Did not find app server.")); + } + foreach (ModellingAppServer appServer in AppServerToAdd) + { + ActAppRole.AppServers.Add(new ModellingAppServerWrapper() { Content = appServer }); + } + if (AddMode) + { + await AddAppRoleToDb(Application.Id); + } + else + { + await UpdateAppRoleInDb(); + } + CleanUp(); + return true; + } + } + catch (Exception exception) + { + DisplayMessageInUi(exception, userConfig.GetText("edit_app_role"), "", true); + } + return false; + } + + private async Task CheckAppRole() + { + if (ActAppRole.IdString.Length <= NamingConvention.FixedPartLength || ActAppRole.Name == "") + { + DisplayMessageInUi(null, userConfig.GetText("edit_app_role"), userConfig.GetText("E5102"), true); + return false; + } + if ((AddMode || ActAppRole.IdString != OrigId.Whole) && await IdStringAlreadyUsed(ActAppRole.IdString)) + { + // popup for correction? + DisplayMessageInUi(null, userConfig.GetText("edit_app_role"), ActAppRole.IdString.ToString() + ": " + userConfig.GetText("E9003"), true); + ActAppRole.ManagedIdString = new(OrigId); + return false; + } + return true; + } + + private async Task IdStringAlreadyUsed(string appRoleIdString) + { + List? existAR = await apiConnection.SendQueryAsync>(ModellingQueries.getNewestAppRoles, new { pattern = appRoleIdString }); + if (existAR != null) + { + foreach (ModellingAppRole aR in existAR) + { + if (aR.Id != ActAppRole.Id) + { + return true; + } + } + } + return false; + } + + public async Task ProposeFreeAppRoleNumber(ModellingManagedIdString idFixString) + { + int proposedNumber = 1; + List? newestARs = await apiConnection.SendQueryAsync>(ModellingQueries.getNewestAppRoles, new { pattern = idFixString.CombinedFixPart + "%" }); + if (newestARs != null && newestARs.Count > 0) + { + newestARs[0].ManagedIdString.NamingConvention = NamingConvention; + if (int.TryParse(newestARs[0].ManagedIdString.FreePart, out int newestARNumber)) + { + proposedNumber = await SearchFrom(idFixString, newestARNumber + 1); + if (proposedNumber == 0) + { + proposedNumber = await SearchFrom(idFixString, 1); + } + } + } + return ProposedString(proposedNumber); + } + + private async Task SearchFrom(ModellingManagedIdString idFixString, int aRNumber) + { + double maxNumbers = Math.Pow(10, NamingConvention.FreePartLength) - 1; + while (aRNumber <= maxNumbers) + { + if (!await IdStringAlreadyUsed(idFixString.CombinedFixPart + idFixString.Separator + ProposedString(aRNumber))) + { + return aRNumber; + } + aRNumber++; + } + return 0; + } + + private string ProposedString(int aRNumber) + { + return aRNumber.ToString($"D{NamingConvention.FreePartLength}"); + } + + private async Task AddAppRoleToDb(int? appId) + { + try + { + var Variables = new + { + name = ActAppRole.Name, + idString = ActAppRole.IdString, + appId = appId, + comment = ActAppRole.Comment, + creator = userConfig.User.Name + }; + ReturnId[]? returnIds = (await apiConnection.SendQueryAsync(ModellingQueries.newAppRole, Variables)).ReturnIds; + if (returnIds != null) + { + ActAppRole.Id = returnIds[0].NewIdLong; + await LogChange(ModellingTypes.ChangeType.Insert, ModellingTypes.ModObjectType.AppRole, ActAppRole.Id, + $"New App Role: {ActAppRole.Display()}", Application.Id); + foreach (ModellingAppServerWrapper appServer in ActAppRole.AppServers) + { + var Vars = new + { + nwObjectId = appServer.Content.Id, + nwGroupId = ActAppRole.Id + }; + await apiConnection.SendQueryAsync(ModellingQueries.addNwObjectToNwGroup, Vars); + await LogChange(ModellingTypes.ChangeType.Assign, ModellingTypes.ModObjectType.AppRole, ActAppRole.Id, + $"Added App Server {appServer.Content.Display()} to App Role: {ActAppRole.Display()}", Application.Id); + } + ActAppRole.Creator = userConfig.User.Name; + ActAppRole.CreationDate = DateTime.Now; + AppRoles.Add(ActAppRole); + AvailableNwElems.Add(new KeyValuePair((int)ModellingTypes.ModObjectType.AppRole, ActAppRole.Id)); + } + } + catch (Exception exception) + { + DisplayMessageInUi(exception, userConfig.GetText("add_app_role"), "", true); + } + } + + private async Task UpdateAppRoleInDb() + { + try + { + var Variables = new + { + id = ActAppRole.Id, + name = ActAppRole.Name, + idString = ActAppRole.IdString, + appId = Application.Id, + comment = ActAppRole.Comment + }; + await apiConnection.SendQueryAsync(ModellingQueries.updateAppRole, Variables); + await LogChange(ModellingTypes.ChangeType.Update, ModellingTypes.ModObjectType.AppRole, ActAppRole.Id, + $"Updated App Role: {ActAppRole.Display()}", Application.Id); + foreach (ModellingAppServer appServer in AppServerToDelete) + { + var Vars = new + { + nwObjectId = appServer.Id, + nwGroupId = ActAppRole.Id + }; + await apiConnection.SendQueryAsync(ModellingQueries.removeNwObjectFromNwGroup, Vars); + await LogChange(ModellingTypes.ChangeType.Unassign, ModellingTypes.ModObjectType.AppRole, ActAppRole.Id, + $"Removed App Server {appServer.Display()} from App Role: {ActAppRole.Display()}", Application.Id); + } + foreach (ModellingAppServer appServer in AppServerToAdd) + { + var Vars = new + { + nwObjectId = appServer.Id, + nwGroupId = ActAppRole.Id + }; + await apiConnection.SendQueryAsync(ModellingQueries.addNwObjectToNwGroup, Vars); + await LogChange(ModellingTypes.ChangeType.Assign, ModellingTypes.ModObjectType.AppRole, ActAppRole.Id, + $"Added App Server {appServer.Display()} to App Role: {ActAppRole.Display()}", Application.Id); + } + } + catch (Exception exception) + { + DisplayMessageInUi(exception, userConfig.GetText("edit_app_role"), "", true); + } + } + + public void CleanUp() + { + AppServerToAdd = []; + AppServerToDelete = []; + } + + public async Task SelectAppServersFromArea(ModellingNetworkArea? area) + { + AppServersInArea = []; + if (area != null) + { + foreach (ModellingAppServer? server in AvailableAppServers.Where(x => !x.IsDeleted)) + { + if (IsInArea(server, area)) + { + server.InUse = await CheckAppServerInUse(server); + server.TooltipText = userConfig.GetText("C9002"); + AppServersInArea.Add(server); + } + } + } + } + + public void CountMembers(ModellingNetworkArea area) + { + area.MemberCount = 0; + foreach (ModellingAppServer? server in AvailableAppServers.Where(x => !x.IsDeleted)) + { + if (IsInArea(server, area)) + { + area.MemberCount++; + } + } + } + + private static bool IsInArea(ModellingAppServer server, ModellingNetworkArea area) + { + try + { + foreach (NetworkDataWrapper areaIpData in area.IpData) + { + IPAddress serverIpStart = IPAddress.Parse(server.Ip.StripOffNetmask()); + IPAddress serverIpEnd = IPAddress.Parse(server.IpEnd.StripOffNetmask()); + if (areaIpData.Content.Ip == null || areaIpData.Content.IpEnd == null) + { + return false; + } + IPAddress subnetIpStart = IPAddress.Parse(areaIpData.Content.Ip.StripOffNetmask()); + IPAddress subnetIpEnd = IPAddress.Parse(areaIpData.Content.IpEnd.StripOffNetmask()); + + IPAddressRange ipRangeServer = new(serverIpStart, serverIpEnd); + IPAddressRange ipRangeSubnet = new(subnetIpStart, subnetIpEnd); + + if (serverIpStart.AddressFamily != subnetIpStart.AddressFamily) + { + return false; + } + + if (IpOperations.RangeOverlapExists(ipRangeServer, ipRangeSubnet)) + { + return true; + } + } + return false; + } + catch (Exception) + { + return false; + } + } + } +} diff --git a/roles/lib/files/FWO.Services/Modelling/ModellingAppServerHandler.cs b/roles/lib/files/FWO.Services/Modelling/ModellingAppServerHandler.cs new file mode 100644 index 0000000000..e266d07582 --- /dev/null +++ b/roles/lib/files/FWO.Services/Modelling/ModellingAppServerHandler.cs @@ -0,0 +1,118 @@ +using NetTools; +using FWO.Config.Api; +using FWO.Basics; +using FWO.Data; +using FWO.Data.Modelling; +using FWO.Api.Client; + + +namespace FWO.Services.Modelling +{ + public class ModellingAppServerHandler : ModellingHandlerBase + { + public ModellingAppServer ActAppServer { get; set; } = new(); + private ModellingAppServer ActAppServerOrig { get; set; } = new(); + + + public ModellingAppServerHandler(ApiConnection apiConnection, UserConfig userConfig, FwoOwner application, + ModellingAppServer appServer, List availableAppServers, bool addMode, + Action displayMessageInUi, bool readOnly, bool isOwner) + : base(apiConnection, userConfig, application, addMode, displayMessageInUi, readOnly, isOwner) + { + ActAppServer = appServer; + AvailableAppServers = availableAppServers; + ActAppServerOrig = new ModellingAppServer(ActAppServer); + } + + public async Task Save() + { + try + { + ActAppServer.AppId = Application.Id; + ActAppServer.ImportSource = GlobalConst.kManual; + if (ActAppServer.Sanitize()) + { + DisplayMessageInUi(null, userConfig.GetText("save_app_server"), userConfig.GetText("U0001"), true); + } + if (CheckAppServer()) + { + return await apiConnection.RunWithRole(Roles.Admin, async () => + { + (long? appServerId, string? ExistingAppServerName) = await AppServerHelper.UpsertAppServer(apiConnection, userConfig, ActAppServer, !userConfig.DnsLookup, true, AddMode); + + if (appServerId != null) + { + if (AddMode) + { + ActAppServer.Id = (long)appServerId; + AvailableAppServers.Add(ActAppServer); + } + return true; + } + + DisplayErrorMessage(ExistingAppServerName); + return false; + }); + } + } + catch (Exception exception) + { + DisplayMessageInUi(exception, userConfig.GetText("edit_app_server"), "", true); + } + return false; + } + + private void DisplayErrorMessage(string? existingAppServerName) + { + if (!string.IsNullOrEmpty(existingAppServerName)) + { + if (existingAppServerName == ActAppServer.Name) + { + DisplayMessageInUi(null, userConfig.GetText("edit_app_server"), userConfig.GetText("E9018"), true); + } + else + { + DisplayMessageInUi(null, userConfig.GetText("edit_app_server"), $"{userConfig.GetText("E9010")} {DisplayBase.DisplayIp(ActAppServer.Ip, ActAppServer.IpEnd)} in {existingAppServerName}", true); + } + } + else if (string.IsNullOrEmpty(existingAppServerName) && string.IsNullOrEmpty(ActAppServer.Name)) + { + string message = $"{userConfig.GetText("E9018")} Name: \"\""; + DisplayMessageInUi(null, userConfig.GetText("edit_app_server"), message, true); + } + else + { + DisplayMessageInUi(null, userConfig.GetText("edit_app_server"), userConfig.GetText("E0034"), true); + } + } + + public void Reset() + { + ActAppServer = ActAppServerOrig; + if (!AddMode && !ReadOnly) + { + AvailableAppServers[AvailableAppServers.FindIndex(x => x.Id == ActAppServer.Id)] = ActAppServerOrig; + } + } + + private bool CheckAppServer() + { + if (ActAppServer.Ip == null || ActAppServer.Ip == "" || ActAppServer.CustomType == null || ActAppServer.CustomType == 0) + { + DisplayMessageInUi(null, userConfig.GetText("edit_app_server"), userConfig.GetText("E5102"), true); + return false; + } + if (!CheckIpAdress(ActAppServer.Ip)) + { + DisplayMessageInUi(null, userConfig.GetText("edit_app_server"), userConfig.GetText("wrong_ip_address"), true); + return false; + } + return true; + } + + private static bool CheckIpAdress(string ip) + { + return IPAddressRange.TryParse(ip, out _) && ip.TryParseIPStringToRange(out _, strictv4Parse: true); + } + } +} diff --git a/roles/lib/files/FWO.Services/Modelling/ModellingAppServerListHandler.cs b/roles/lib/files/FWO.Services/Modelling/ModellingAppServerListHandler.cs new file mode 100644 index 0000000000..fa4d149ee6 --- /dev/null +++ b/roles/lib/files/FWO.Services/Modelling/ModellingAppServerListHandler.cs @@ -0,0 +1,136 @@ +using FWO.Config.Api; +using FWO.Basics; +using FWO.Data; +using FWO.Data.Modelling; +using FWO.Api.Client; +using FWO.Api.Client.Queries; + + +namespace FWO.Services.Modelling +{ + public class ModellingAppServerListHandler : ModellingHandlerBase + { + public List ManualAppServers { get; set; } = []; + public ModellingAppServerHandler? AppServerHandler; + private ModellingAppServer actAppServer = new(); + public bool AddAppServerMode = false; + public bool EditAppServerMode = false; + public bool DeleteAppServerMode = false; + public bool ReactivateAppServerMode = false; + + + public ModellingAppServerListHandler(ApiConnection apiConnection, UserConfig userConfig, + Action displayMessageInUi, bool readOnly, bool isOwner) + : base(apiConnection, userConfig, new FwoOwner(), false, displayMessageInUi, readOnly, isOwner) + { } + + public async Task Init(FwoOwner application) + { + try + { + Application = application; + ManualAppServers = await apiConnection.SendQueryAsync>(ModellingQueries.getAppServersBySource, new { importSource = GlobalConst.kManual, appId = Application.Id }); + ManualAppServers.AddRange(await apiConnection.SendQueryAsync>(ModellingQueries.getAppServersBySource, new { importSource = GlobalConst.kCSV_ + "%", appId = Application.Id })); + foreach (var appServer in ManualAppServers) + { + appServer.InUse = await CheckAppServerInUse(appServer); + appServer.HighestPrio = await AppServerHelper.NoHigherPrioActive(apiConnection, appServer); + } + } + catch (Exception exception) + { + DisplayMessageInUi(exception, userConfig.GetText("fetch_data"), "", true); + } + } + + public void CreateAppServer() + { + AddAppServerMode = true; + HandleAppServer(new ModellingAppServer() { ImportSource = GlobalConst.kManual, InUse = false }); + } + + public void EditAppServer(ModellingAppServer appServer) + { + AddAppServerMode = false; + HandleAppServer(appServer); + } + + public void HandleAppServer(ModellingAppServer appServer) + { + try + { + AppServerHandler = new ModellingAppServerHandler(apiConnection, userConfig, Application, appServer, ManualAppServers, AddAppServerMode, DisplayMessageInUi, ReadOnly, IsOwner); + EditAppServerMode = true; + } + catch (Exception exception) + { + DisplayMessageInUi(exception, userConfig.GetText("edit_app_server"), "", true); + } + } + + public void RequestDeleteAppServer(ModellingAppServer appServer) + { + actAppServer = appServer; + Message = userConfig.GetText(appServer.InUse ? "U9007" : "U9008") + appServer.Name + "?"; + DeleteAppServerMode = true; + } + + public async Task DeleteAppServer() + { + try + { + await apiConnection.RunWithRole(Roles.Admin, async () => + { + if (await CheckAppServerInUse(actAppServer)) + { + await apiConnection.SendQueryAsync(ModellingQueries.setAppServerDeletedState, new { id = actAppServer.Id, deleted = true }); + await LogChange(ModellingTypes.ChangeType.MarkDeleted, ModellingTypes.ModObjectType.AppServer, actAppServer.Id, + $"Mark App Server as deleted: {actAppServer.Display()}", Application.Id); + } + else if ((await apiConnection.SendQueryAsync(ModellingQueries.deleteAppServer, new { id = actAppServer.Id })).AffectedRows > 0) + { + await LogChange(ModellingTypes.ChangeType.Delete, ModellingTypes.ModObjectType.AppServer, actAppServer.Id, + $"Deleted App Server: {actAppServer.Display()}", Application.Id); + } + await AppServerHelper.ReactivateOtherSource(apiConnection, userConfig, actAppServer); + await Init(Application); + DeleteAppServerMode = false; + }); + } + catch (Exception exception) + { + DisplayMessageInUi(exception, userConfig.GetText("delete_app_server"), "", true); + } + } + + public void RequestReactivateAppServer(ModellingAppServer appServer) + { + actAppServer = appServer; + Message = userConfig.GetText("U9005") + appServer.Name + "?"; + ReactivateAppServerMode = true; + } + + public async Task ReactivateAppServer() + { + try + { + await apiConnection.RunWithRole(Roles.Admin, async () => + { + if (actAppServer.IsDeleted) + { + await apiConnection.SendQueryAsync(ModellingQueries.setAppServerDeletedState, new { id = actAppServer.Id, deleted = false }); + await LogChange(ModellingTypes.ChangeType.Reactivate, ModellingTypes.ModObjectType.AppServer, actAppServer.Id, + $"Reactivate App Server: {actAppServer.Display()}", Application.Id); + await AppServerHelper.DeactivateOtherSources(apiConnection, userConfig, actAppServer); + await Init(Application); + } + ReactivateAppServerMode = false; + }); + } + catch (Exception exception) + { + DisplayMessageInUi(exception, userConfig.GetText("reactivate"), "", true); + } + } + } +} diff --git a/roles/lib/files/FWO.Services/Modelling/ModellingAppZoneHandler.cs b/roles/lib/files/FWO.Services/Modelling/ModellingAppZoneHandler.cs new file mode 100644 index 0000000000..1daa5c39aa --- /dev/null +++ b/roles/lib/files/FWO.Services/Modelling/ModellingAppZoneHandler.cs @@ -0,0 +1,164 @@ +using FWO.Api.Client; +using FWO.Api.Client.Queries; +using FWO.Data; +using FWO.Data.Modelling; +using FWO.Config.Api; +using System.Text.Json; + +namespace FWO.Services.Modelling +{ + public class ModellingAppZoneHandler(ApiConnection apiConnection, UserConfig userConfig, FwoOwner owner, Action displayMessageInUi) : ModellingHandlerBase(apiConnection, userConfig, displayMessageInUi) + { + private readonly ModellingNamingConvention NamingConvention = JsonSerializer.Deserialize(userConfig.ModNamingConvention) ?? new(); + List allAppServers = []; + + public async Task GetExistingModelledAppZone() + { + List? existingAppZones = await apiConnection.SendQueryAsync>(ModellingQueries.getAppZonesByAppId, new { appId = owner.Id }); + return existingAppZones.FirstOrDefault(); + } + + public ModellingAppZone CreateNewAppZone() + { + ModellingAppZone appZone = new(owner.Id); + ApplyNamingConvention(owner.ExtAppId?.ToUpper(), appZone); + appZone.AppServersNew = allAppServers; + appZone.AppServers = allAppServers; + return appZone; + } + + public async Task PlanAppZoneDbUpdate(ModellingAppZone? oldAppZone) + { + allAppServers = await GetAllModelledAppServers(); + ModellingAppZone appZone; + if (oldAppZone == null) + { + appZone = CreateNewAppZone(); + } + else + { + appZone = new(oldAppZone) { AlreadyExistsInDb = true }; + FillDiffLists(appZone, allAppServers); + } + return appZone; + } + + public ModellingAppZone PlanAppZoneRequest(ModellingAppZone prodAppZone) + { + FillDiffLists(prodAppZone, allAppServers); + return prodAppZone; + } + + public async Task UpsertAppZone(ModellingAppZone appZone) + { + if (!appZone.AlreadyExistsInDb) + { + appZone.Id = await AddAppZoneToDb(appZone); + if (appZone.Id > 0) + { + await AddAppServersToAppZone(appZone.Id, appZone.AppServers); + } + } + else + { + if (appZone.AppServersRemoved.Count > 0) + { + await RemoveAppServersFromAppZone(appZone.Id, appZone.AppServersRemoved); + } + + if (appZone.AppServersNew.Count > 0) + { + await AddAppServersToAppZone(appZone.Id, appZone.AppServersNew); + } + } + return appZone; + } + + private async Task> GetAllModelledAppServers() + { + List tempAppServers = await apiConnection.SendQueryAsync>(ModellingQueries.getAppServersForOwner, new { appId = owner.Id }); + List allModelledAppServers = []; + foreach (ModellingAppServer appServer in tempAppServers.Where(a => !a.IsDeleted)) + { + allModelledAppServers.Add(new ModellingAppServerWrapper() { Content = appServer }); + } + return allModelledAppServers; + } + + private void ApplyNamingConvention(string? extAppId, ModellingAppZone appZone) + { + appZone.ManagedIdString.NamingConvention = NamingConvention; + if (extAppId != null) + { + appZone.ManagedIdString.SetAppPartFromExtIdAZ(extAppId); + } + } + + private void FillDiffLists(ModellingAppZone appZone, List allAppServers) + { + AppServerComparer appServerComparer = new(NamingConvention); + List? newAppServers = [.. allAppServers.Except(appZone.AppServers, appServerComparer)]; + List removedAppServers = [.. appZone.AppServers.Except(allAppServers, appServerComparer)]; + List? unchangedAppServers = [.. appZone.AppServers.Except(removedAppServers, appServerComparer)]; + if (newAppServers.Count > 0) + { + appZone.AppServersNew = newAppServers; + appZone.AppServers.AddRange(newAppServers); + } + if (removedAppServers.Count > 0) + { + appZone.AppServersRemoved = removedAppServers; + appZone.AppServers.RemoveAll(_ => removedAppServers.Contains(_)); + } + if (unchangedAppServers.Count > 0) + { + appZone.AppServersUnchanged = unchangedAppServers; + } + } + + private async Task AddAppZoneToDb(ModellingAppZone appZone) + { + var azVars = new + { + appId = appZone.AppId, + name = appZone.Name, + idString = appZone.IdString, + creator = "CreateAZObjects" + }; + + ReturnId[]? returnIds = (await apiConnection.SendQueryAsync(ModellingQueries.newAppZone, azVars)).ReturnIds; + if (returnIds != null && returnIds.Length > 0) + { + await LogChange(ModellingTypes.ChangeType.Insert, ModellingTypes.ModObjectType.AppZone, appZone.Id, $"New App Zone: {appZone.Display()}", null); + return returnIds[0].NewIdLong; + } + return -1; + } + + private async Task AddAppServersToAppZone(long appZoneId, List appServers) + { + foreach (ModellingAppServerWrapper appServer in appServers) + { + var nwobject_nwgroupVars = new + { + nwObjectId = appServer.Content.Id, + nwGroupId = appZoneId + }; + await apiConnection.SendQueryAsync(ModellingQueries.addNwObjectToNwGroup, nwobject_nwgroupVars); + } + } + + private async Task RemoveAppServersFromAppZone(long appZoneId, List appServers) + { + foreach (ModellingAppServer appServer in ModellingAppServerWrapper.Resolve(appServers)) + { + var nwobject_nwgroupVars = new + { + nwObjectId = appServer.Id, + nwGroupId = appZoneId + }; + await apiConnection.SendQueryAsync(ModellingQueries.removeNwObjectFromNwGroup, nwobject_nwgroupVars); + } + } + } +} diff --git a/roles/lib/files/FWO.Services/Modelling/ModellingConnectionHandler.cs b/roles/lib/files/FWO.Services/Modelling/ModellingConnectionHandler.cs new file mode 100644 index 0000000000..61c815aaa4 --- /dev/null +++ b/roles/lib/files/FWO.Services/Modelling/ModellingConnectionHandler.cs @@ -0,0 +1,582 @@ +using FWO.Api.Client; +using FWO.Api.Client.Queries; +using FWO.Basics; +using FWO.Config.Api; +using FWO.Config.Api.Data; +using FWO.Data; +using FWO.Data.Modelling; +using FWO.Middleware.Client; +using Microsoft.AspNetCore.Components; +using Microsoft.AspNetCore.Components.Authorization; +using System.Data; +using System.Text.Json; + + +namespace FWO.Services.Modelling +{ + public partial class ModellingConnectionHandler : ModellingHandlerBase + { + public List AllApps { get; set; } = []; + public List Connections { get; set; } + public ModellingConnection ActConn { get; set; } + + public string InterfaceName { get; set; } = ""; + + public bool SrcReadOnly { get; set; } = false; + public bool DstReadOnly { get; set; } = false; + public bool SvcReadOnly { get; set; } = false; + + public bool AddExtraConfigMode { get; set; } = false; + public bool SearchNWObjectMode { get; set; } = false; + public bool RemoveNwObjectMode { get; set; } = false; + public bool RemovePreselectedInterfaceMode { get; set; } = false; + public bool DisplaySelectedInterfaceMode { get; set; } = false; + public bool ReplaceMode { get; set; } = false; + public ModellingConnectionHandler? IntConnHandler { get; set; } + + public List SrcAppServerToAdd { get; set; } = []; + public List SrcAppServerToDelete { get; set; } = []; + public List DstAppServerToAdd { get; set; } = []; + public List DstAppServerToDelete { get; set; } = []; + public bool DisplayAppServerMode { get; set; } = false; + + public ModellingAppRoleHandler? AppRoleHandler { get; set; } + public List SrcAppRolesToAdd { get; set; } = []; + public List SrcAppRolesToDelete { get; set; } = []; + public List DstAppRolesToAdd { get; set; } = []; + public List DstAppRolesToDelete { get; set; } = []; + public List SrcAreasToAdd { get; set; } = []; + public List SrcAreasToDelete { get; set; } = []; + public List DstAreasToAdd { get; set; } = []; + public List DstAreasToDelete { get; set; } = []; + public List SrcNwGroupsToAdd { get; set; } = []; + public List SrcNwGroupsToDelete { get; set; } = []; + public List DstNwGroupsToAdd { get; set; } = []; + public List DstNwGroupsToDelete { get; set; } = []; + public bool AddAppRoleMode { get; set; } = false; + public bool EditAppRoleMode { get; set; } = false; + public bool DeleteAppRoleMode { get; set; } = false; + public bool DisplayAppRoleMode { get; set; } = false; + + public ModellingServiceHandler? ServiceHandler { get; set; } + public List SvcToDelete { get; set; } = []; + public bool AddServiceMode { get; set; } = false; + public bool EditServiceMode { get; set; } = false; + public bool DeleteServiceMode { get; set; } = false; + + public ModellingServiceGroupHandler? SvcGrpHandler { get; set; } + public List SvcGrpToAdd { get; set; } = []; + public List SvcGrpToDelete { get; set; } = []; + public bool AddSvcGrpMode { get; set; } = false; + public bool EditSvcGrpMode { get; set; } = false; + public bool DeleteSvcGrpMode { get; set; } = false; + public bool DisplaySvcGrpMode { get; set; } = false; + public Func RefreshParent { get; set; } + public ModellingAppRole DummyAppRole { get; set; } = new(); + public int LastWidth { get; set; } = GlobalConst.kGlobLibraryWidth; + public bool LastCollapsed { get; set; } = false; + public bool ActConnNeedsRefresh { get; set; } = true; + + private bool SrcFix = false; + private bool DstFix = false; + private ModellingConnection ActConnOrig { get; set; } + private bool InitOngoing = false; + private const string kConnection = "Connection"; + private const string kInterface = "Interface"; + private readonly string EditConnection = "edit_connection"; + private readonly string InitEnvironment = "init_environment"; + + + public ModellingConnectionHandler(ApiConnection apiConnection, UserConfig userConfig, FwoOwner application, + List connections, ModellingConnection conn, bool addMode, bool readOnly, + Action displayMessageInUi, Func refreshParent, bool isOwner) + : base(apiConnection, userConfig, application, addMode, displayMessageInUi, readOnly, isOwner) + { + Connections = connections; + ActConn = conn; + ActConnOrig = new ModellingConnection(ActConn); + RefreshParent = refreshParent; + } + + // Init + Refresh + + public async Task Init() + { + try + { + if (!InitOngoing) + { + InitOngoing = true; + await RefreshObjects(); + InterfaceName = await ExtractUsedInterface(ActConn); + AllApps = await apiConnection.SendQueryAsync>(OwnerQueries.getOwnersWithConn); + AppRoleHandler = new(apiConnection, userConfig, new(), [], new(), [], [], false, DisplayMessageInUi); + DummyAppRole = await AppRoleHandler.GetDummyAppRole(); + await RefreshInterfaceData(); + InitOngoing = false; + } + } + catch (Exception exception) + { + DisplayMessageInUi(exception, userConfig.GetText(InitEnvironment), "", true); + } + } + + public async Task PartialInit() + { + try + { + if (!InitOngoing) + { + InitOngoing = true; + AppRoleHandler = new(apiConnection, userConfig, new(), [], new(), [], [], false, DisplayMessageInUi); + DummyAppRole = await AppRoleHandler.GetDummyAppRole(); + InitOngoing = false; + } + } + catch (Exception exception) + { + DisplayMessageInUi(exception, userConfig.GetText(InitEnvironment), "", true); + } + } + + public async Task ReInit() + { + try + { + // exclude the cases where ActConn has to be held (e.g. if there is an ui binding) + if (ActConnNeedsRefresh) + { + await RefreshActConn(); + await RefreshInterfaceData(); + } + + await RefreshObjects(); + await RefreshParent(); + } + catch (Exception exception) + { + DisplayMessageInUi(exception, userConfig.GetText(InitEnvironment), "", true); + } + } + + public async Task RefreshObjects() + { + await RefreshPreselectedInterfaces(); + await InitAvailableNWObjects(); + await InitAvailableSvcObjects(); + RefreshSelectableNwObjects(); + } + + private async Task RefreshActConn() + { + try + { + List conns = await apiConnection.SendQueryAsync>(ModellingQueries.getConnectionById, new { id = ActConn.Id }); + if (conns.Count > 0) + { + ActConn = conns[0]; + } + } + catch (Exception exception) + { + DisplayMessageInUi(exception, userConfig.GetText("fetch_data"), "", true); + } + } + + // ExtraConfig + + public void AddExtraConfig() + { + AddExtraConfigMode = true; + } + + public bool SaveExtraConfig(ModellingExtraConfig extraConfig) + { + extraConfig.Id = ActConn.ExtraConfigs.Count > 0 ? ActConn.ExtraConfigs.OrderByDescending(x => x.Id).First().Id + 1 : 1; + List actList = ActConn.ExtraConfigs; + actList.Add(extraConfig); + ActConn.ExtraConfigs = actList; + return true; + } + + public void UpdateExtraConfig(ChangeEventArgs e, ModellingExtraConfig extraConfig) + { + List actList = ActConn.ExtraConfigs; + ModellingExtraConfig? actConfig = actList.FirstOrDefault(x => x.Id == extraConfig.Id); + if (actConfig != null) + { + actConfig.ExtraConfigText = e.Value?.ToString() ?? ""; + actConfig.Sanitize(); + } + ActConn.ExtraConfigs = actList; + } + + public bool DeleteExtraConfig(ModellingExtraConfig extraConfig) + { + List actList = ActConn.ExtraConfigs; + actList.Remove(actList.FirstOrDefault(x => x.Id == extraConfig.Id) ?? throw new KeyNotFoundException("Did not find service group.")); + ActConn.ExtraConfigs = actList; + return true; + } + + // Visibility + + public bool CalcVisibility() + { + if (ActConn.IsInterface) + { + DstReadOnly = SrcFix || SrcFilledInWork(); + SrcReadOnly = DstFix || DstFilledInWork(); + SvcReadOnly = false; + } + else if (ActConn.UsedInterfaceId != null) + { + SrcReadOnly = ActConn.SrcFromInterface; + DstReadOnly = ActConn.DstFromInterface; + SvcReadOnly = true; + } + else + { + SrcReadOnly = false; + DstReadOnly = false; + SvcReadOnly = false; + } + return true; + } + + public bool SrcDropForbidden() + { + return SrcReadOnly || (ActConn.IsInterface && DstFilledInWork()); + } + + public bool DstDropForbidden() + { + return DstReadOnly || (ActConn.IsInterface && SrcFilledInWork()); + } + + public bool SrcFilledInWork(int dummyARCount = 0) + { + return ActConn.SourceAreas.Count - SrcAreasToDelete.Count > 0 || + ActConn.SourceOtherGroups.Count - SrcNwGroupsToDelete.Count > 0 || + ActConn.SourceAppRoles.Count - dummyARCount - SrcAppRolesToDelete.Count > 0 || + ActConn.SourceAppServers.Count - SrcAppServerToDelete.Count > 0 || + SrcAreasToAdd.Count > 0 || + SrcNwGroupsToAdd.Count > 0 || + SrcAppServerToAdd.Count > 0 || + SrcAppRolesToAdd.Count > 0; + } + + public bool DstFilledInWork(int dummyARCount = 0) + { + return ActConn.DestinationAreas.Count - DstAreasToDelete.Count > 0 || + ActConn.DestinationOtherGroups.Count - DstNwGroupsToDelete.Count > 0 || + ActConn.DestinationAppRoles.Count - dummyARCount - DstAppRolesToDelete.Count > 0 || + ActConn.DestinationAppServers.Count - DstAppServerToDelete.Count > 0 || + DstAreasToAdd.Count > 0 || + DstNwGroupsToAdd.Count > 0 || + DstAppServerToAdd.Count > 0 || + DstAppRolesToAdd.Count > 0; + } + + public bool SvcFilledInWork() + { + return ActConn.Services.Count - SvcToDelete.Count > 0 || + ActConn.ServiceGroups.Count - SvcGrpToDelete.Count > 0 || + SvcToAdd != null && SvcToAdd.Count > 0 || + SvcGrpToAdd != null && SvcGrpToAdd.Count > 0; + } + + // Save + + public async Task Save(bool noCheck = false, bool decommInterface = false) + { + if (!IsOwner) + { + DisplayMessageInUi(null, userConfig.GetText("save_connection"), userConfig.GetText("E9104"), true); + return false; + } + + if (ActConn.IsCommonService && ComSvcContainsOnlyCommonNetworkArea()) + { + DisplayMessageInUi(default, userConfig.GetText("edit_common_service"), userConfig.GetText("U9030"), true); + return false; + } + + try + { + if (ActConn.Sanitize()) + { + DisplayMessageInUi(null, userConfig.GetText("save_connection"), userConfig.GetText("U0001"), true); + } + if (noCheck || CheckConn()) + { + ActConn.SyncState(DummyAppRole.Id); + if (decommInterface) + { + await DecommInterface(); + } + else + { + SyncChanges(); + if (AddMode) + { + await AddConnectionToDb(); + } + else + { + await UpdateConnection(); + } + } + await ReInit(); + Close(); + return true; + } + } + catch (Exception exception) + { + DisplayMessageInUi(exception, userConfig.GetText("save_connection"), "", true); + } + return false; + } + + public async Task SavePropertiesOnly() + { + try + { + await apiConnection.SendQueryAsync(ModellingQueries.updateConnectionProperties, new { id = ActConn.Id, connProp = ActConn.Properties }); + int connIndex = Connections.FindIndex(x => x.Id == ActConn.Id); + if (connIndex >= 0) + { + Connections[connIndex].Properties = ActConn.Properties; + } + return true; + } + catch (Exception exception) + { + DisplayMessageInUi(exception, userConfig.GetText("save_connection"), "", true); + return false; + } + } + + private async Task UpdateConnection() + { + if (userConfig.VarianceAnalysisSleepTime == 0 && (userConfig.VarianceAnalysisSync || userConfig.VarianceAnalysisRefresh)) + { + ActConn.CleanUpVarianceResults(); + } + await UpdateConnectionInDb(); + if (ActConn.IsInterface && ActConn.IsPublished) + { + await UpdateStatusInterfaceUsersPublished(); + } + } + + public bool CheckConn() + { + if (ActConn.Name == null || ActConn.Name == "" || ActConn.Reason == null || ActConn.Reason == "") + { + DisplayMessageInUi(null, userConfig.GetText(EditConnection), userConfig.GetText("E5102"), true); + return false; + } + if (ActConn.IsInterface) + { + if (!CheckInterface()) + { + return false; + } + } + else + { + if (!(ActConn.SrcFromInterface || SrcFilledInWork()) || + !(ActConn.DstFromInterface || DstFilledInWork()) || + !(ActConn.UsedInterfaceId != null || SvcFilledInWork())) + { + DisplayMessageInUi(null, userConfig.GetText(EditConnection), userConfig.GetText("E9006"), true); + return false; + } + } + return true; + } + + private void SyncChanges() + { + if (!SrcReadOnly) + { + SyncSrcChanges(); + } + if (!DstReadOnly) + { + SyncDstChanges(); + } + if (!SvcReadOnly) + { + SyncSvcChanges(); + } + SyncPermittedOwnersChanges(); + } + + private async Task AddConnectionToDb(bool propose = false) + { + try + { + ActConn.AppId = propose ? null : Application.Id; + ActConn.ProposedAppId = propose ? Application.Id : null; + ActConn.IsPublished = !propose; + + var Variables = new + { + name = ActConn.Name, + appId = ActConn.AppId, + proposedAppId = ActConn.ProposedAppId, + reason = ActConn.Reason, + isInterface = ActConn.IsInterface, + usedInterfaceId = ActConn.UsedInterfaceId, + isRequested = ActConn.IsRequested, + isPublished = ActConn.IsPublished, + ticketId = ActConn.TicketId, + creator = userConfig.User.Name, + commonSvc = ActConn.IsCommonService, + connProp = ActConn.Properties, + extraParams = ActConn.ExtraParams, + interfacePermission = ActConn.InterfacePermission + }; + ReturnId[]? returnIds = (await apiConnection.SendQueryAsync(ModellingQueries.newConnection, Variables)).ReturnIds; + if (returnIds != null) + { + ActConn.Id = returnIds[0].NewId; + await LogChange(ModellingTypes.ChangeType.Insert, ModellingTypes.ModObjectType.Connection, ActConn.Id, + $"New {(ActConn.IsInterface ? kInterface : kConnection)}: {ActConn.Name}", ActConn.AppId); + if (ActConn.UsedInterfaceId == null || ActConn.DstFromInterface) + { + await AddNwObjects(ModellingAppServerWrapper.Resolve(ActConn.SourceAppServers).ToList(), + ModellingAppRoleWrapper.Resolve(ActConn.SourceAppRoles).ToList(), + ModellingNetworkAreaWrapper.Resolve(ActConn.SourceAreas).ToList(), + ModellingNwGroupWrapper.Resolve(ActConn.SourceOtherGroups).ToList(), + ModellingTypes.ConnectionField.Source); + } + if (ActConn.UsedInterfaceId == null || ActConn.SrcFromInterface) + { + await AddNwObjects(ModellingAppServerWrapper.Resolve(ActConn.DestinationAppServers).ToList(), + ModellingAppRoleWrapper.Resolve(ActConn.DestinationAppRoles).ToList(), + ModellingNetworkAreaWrapper.Resolve(ActConn.DestinationAreas).ToList(), + ModellingNwGroupWrapper.Resolve(ActConn.DestinationOtherGroups).ToList(), + ModellingTypes.ConnectionField.Destination); + } + if (ActConn.UsedInterfaceId == null) + { + await AddSvcObjects(ModellingServiceWrapper.Resolve(ActConn.Services).ToList(), + ModellingServiceGroupWrapper.Resolve(ActConn.ServiceGroups).ToList()); + } + await ApplyPermittedOwnersOnInsert(); + ActConn.Creator = userConfig.User.Name; + ActConn.CreationDate = DateTime.Now; + Connections.Add(ActConn); + Connections.Sort((ModellingConnection a, ModellingConnection b) => a?.CompareTo(b) ?? -1); + } + } + catch (Exception exception) + { + DisplayMessageInUi(exception, userConfig.GetText("add_connection"), "", true); + } + } + + private async Task UpdateConnectionInDb() + { + try + { + var Variables = new + { + id = ActConn.Id, + name = ActConn.Name, + appId = ActConn.AppId, + proposedAppId = ActConn.ProposedAppId, + reason = ActConn.Reason, + isInterface = ActConn.IsInterface, + usedInterfaceId = ActConn.UsedInterfaceId, + isRequested = ActConn.IsRequested, + isPublished = ActConn.IsPublished, + commonSvc = ActConn.IsCommonService, + connProp = ActConn.Properties, + extraParams = ActConn.ExtraParams, + interfacePermission = ActConn.InterfacePermission + }; + await apiConnection.SendQueryAsync(ModellingQueries.updateConnection, Variables); + await LogChange(ModellingTypes.ChangeType.Update, ModellingTypes.ModObjectType.Connection, ActConn.Id, + $"Updated {(ActConn.IsInterface ? kInterface : kConnection)}: {ActConn.Name}", Application.Id); + + await RemoveNwObjects(SrcAppServerToDelete, SrcAppRolesToDelete, SrcAreasToDelete, SrcNwGroupsToDelete, ModellingTypes.ConnectionField.Source); + await AddNwObjects(SrcAppServerToAdd, SrcAppRolesToAdd, SrcAreasToAdd, SrcNwGroupsToAdd, ModellingTypes.ConnectionField.Source); + await RemoveNwObjects(DstAppServerToDelete, DstAppRolesToDelete, DstAreasToDelete, DstNwGroupsToDelete, ModellingTypes.ConnectionField.Destination); + await AddNwObjects(DstAppServerToAdd, DstAppRolesToAdd, DstAreasToAdd, DstNwGroupsToAdd, ModellingTypes.ConnectionField.Destination); + await RemoveSvcObjects(); + await AddSvcObjects(SvcToAdd, SvcGrpToAdd); + await EnsureUsingAppsPermittedIfRestricted(); + await ApplyPermittedOwnersOnUpdate(); + + Connections[Connections.FindIndex(x => x.Id == ActConn.Id)] = ActConn; + foreach (var conn in Connections.Where(x => x.UsedInterfaceId == ActConn.Id)) + { + await ExtractUsedInterface(conn); + } + } + catch (Exception exception) + { + DisplayMessageInUi(exception, userConfig.GetText(EditConnection), "", true); + } + } + + public void Reset() + { + ActConn = ActConnOrig; + if (!AddMode) + { + Connections[Connections.FindIndex(x => x.Id == ActConn.Id)] = ActConnOrig; + } + } + + public void Close() + { + SrcAppServerToAdd = []; + SrcAppServerToDelete = []; + DstAppServerToAdd = []; + DstAppServerToDelete = []; + SrcAppRolesToAdd = []; + SrcAppRolesToDelete = []; + DstAppRolesToAdd = []; + DstAppRolesToDelete = []; + SrcAreasToAdd = []; + SrcAreasToDelete = []; + DstAreasToAdd = []; + DstAreasToDelete = []; + SrcNwGroupsToAdd = []; + SrcNwGroupsToDelete = []; + DstNwGroupsToAdd = []; + DstNwGroupsToDelete = []; + SvcToAdd = []; + SvcToDelete = []; + SvcGrpToAdd = []; + SvcGrpToDelete = []; + PermittedOwnersToAdd = []; + PermittedOwnersToDelete = []; + SearchNWObjectMode = false; + AddExtraConfigMode = false; + RemoveNwObjectMode = false; + RemovePreselectedInterfaceMode = false; + DisplaySelectedInterfaceMode = false; + ReplaceMode = false; + DisplayAppServerMode = false; + AddAppRoleMode = false; + EditAppRoleMode = false; + DeleteAppRoleMode = false; + DisplayAppRoleMode = false; + AddSvcGrpMode = false; + EditSvcGrpMode = false; + DeleteSvcGrpMode = false; + DisplaySvcGrpMode = false; + AddServiceMode = false; + EditServiceMode = false; + DeleteServiceMode = false; + } + } +} diff --git a/roles/lib/files/FWO.Services/Modelling/ModellingConnectionHandlerInterfHandling.cs b/roles/lib/files/FWO.Services/Modelling/ModellingConnectionHandlerInterfHandling.cs new file mode 100644 index 0000000000..2439c0aa4a --- /dev/null +++ b/roles/lib/files/FWO.Services/Modelling/ModellingConnectionHandlerInterfHandling.cs @@ -0,0 +1,554 @@ +using FWO.Api.Client.Queries; +using FWO.Basics; +using FWO.Data; +using FWO.Data.Modelling; +using FWO.Logging; +using FWO.Middleware.Client; +using FWO.Services.Workflow; +using Microsoft.AspNetCore.Components.Authorization; + + +namespace FWO.Services.Modelling +{ + public partial class ModellingConnectionHandler + { + public List PreselectedInterfaces { get; set; } = []; + public int RequesterId { get; set; } = 0; + private ModellingConnection actInterface = new(); + + + public async Task RefreshPreselectedInterfaces() + { + try + { + PreselectedInterfaces = ModellingConnectionWrapper.Resolve( + await apiConnection.SendQueryAsync>(ModellingQueries.getSelectedConnections, new { appId = Application.Id })).ToList(); + } + catch (Exception exception) + { + DisplayMessageInUi(exception, userConfig.GetText("fetch_data"), "", true); + } + } + + private async Task RefreshInterfaceData() + { + try + { + if (ActConn.IsInterface) + { + ActConn.PermittedOwners = await apiConnection.SendQueryAsync>(ModellingQueries.getPermittedOwnersForConnection, new { connectionId = ActConn.Id }); + PermittedOwnersToAdd.Clear(); + PermittedOwnersToDelete.Clear(); + await InitUsingConnections(ActConn.Id); + if (!AddMode && !ReadOnly) + { + SrcFix = ActConn.SourceFilled(); + DstFix = ActConn.DestinationFilled(); + } + } + } + catch (Exception exception) + { + DisplayMessageInUi(exception, userConfig.GetText("fetch_data"), "", true); + } + } + + private bool CheckInterface() + { + if (string.IsNullOrWhiteSpace(ActConn.InterfacePermission)) + { + DisplayMessageInUi(null, userConfig.GetText(EditConnection), userConfig.GetText("E9021"), true); + return false; + } + int srcDummyARCount = ActConn.SourceAppRoles.Count(x => x.Content.Id == DummyAppRole.Id); + int dstDummyARCount = ActConn.DestinationAppRoles.Count(x => x.Content.Id == DummyAppRole.Id); + if (!(SrcFilledInWork(srcDummyARCount) || DstFilledInWork(dstDummyARCount)) || !SvcFilledInWork()) + { + DisplayMessageInUi(null, userConfig.GetText(EditConnection), userConfig.GetText("E9004"), true); + return false; + } + if (!AddMode && (SrcFilledInWork(srcDummyARCount) != ActConnOrig.SourceFilled() || DstFilledInWork(dstDummyARCount) != ActConnOrig.DestinationFilled())) + { + DisplayMessageInUi(null, userConfig.GetText(EditConnection), userConfig.GetText("E9005"), true); + return false; + } + if (ActConn.InterfacePermission == InterfacePermissions.Private.ToString() && + ActConnOrig.InterfacePermission != InterfacePermissions.Private.ToString() && + UsingConnections.Any(c => c.AppId != ActConn.AppId)) + { + DisplayMessageInUi(null, userConfig.GetText(EditConnection), userConfig.GetText("E9020"), true); + return false; + } + return true; + } + + public async Task DecommissionInterface(string reason, bool proposeAlternative, ModellingConnection? proposedInterface, + MiddlewareClient middlewareClient) + { + ActConn.Removed = true; + ActConn.Reason += $"
                      {DateTime.Now:dd.MM.yyyy} {userConfig.User.Name}: {userConfig.GetText("decomm_interface")}: {reason}"; + await Save(true, true); + await RemoveFromAllSelections(); + + List appsToNotify = []; + if (!string.IsNullOrWhiteSpace(userConfig.ModDecommEmailReceiver) + && !userConfig.ModDecommEmailReceiver.Equals(nameof(EmailRecipientOption.None), StringComparison.Ordinal)) + { + appsToNotify = UsingConnections.Where(c => c.AppId != null && c.AppId != ActConn.AppId).Select(c => c.App).Distinct().ToList(); + await NotifyUsers(appsToNotify, reason, proposedInterface, middlewareClient); + } + + await AddPermittedOwnersIfMissing(proposedInterface, appsToNotify); + await AddToSelections(proposeAlternative, proposedInterface, appsToNotify); + } + + protected virtual async Task NotifyUsers(List appsToNotify, string reason, ModellingConnection? proposedInterface, MiddlewareClient middlewareClient) + { + try + { + EmailHelper emailHelper = CreateEmailHelper(middlewareClient); + await emailHelper.Init(); + + string subject = userConfig.ModDecommEmailSubject.Replace(Placeholder.INTERFACE_NAME, ActConn.Name); + + int successCount = 0; + int failCount = 0; + foreach (var app in appsToNotify) + { + if (await emailHelper.SendEmailToOwnerResponsibles(app, subject, ConstructBody(app, reason, proposedInterface), userConfig.ModDecommEmailReceiver)) + { + successCount++; + } + else + { + failCount++; + } + } + if (successCount > 0) + { + string msgText = userConfig.GetText("U9033").Replace(Placeholder.OK_NUMBER, successCount.ToString()); + DisplayMessageInUi(null, userConfig.GetText("send_email"), msgText, false); + } + if (failCount > 0) + { + string msgText = userConfig.GetText("E9019").Replace(Placeholder.FAIL_NUMBER, failCount.ToString()); + DisplayMessageInUi(null, userConfig.GetText("send_email"), msgText, true); + } + } + catch (Exception exception) + { + DisplayMessageInUi(exception, userConfig.GetText("notification"), "", true); + } + } + + protected virtual EmailHelper CreateEmailHelper(MiddlewareClient middlewareClient) + { + return new EmailHelper(apiConnection, middlewareClient, userConfig, DisplayMessageInUi); + } + + private string ConstructBody(FwoOwner app, string reason, ModellingConnection? proposedInterface) + { + string interfaceUrl = $"{userConfig.UiHostName}/{PageName.Modelling}/{proposedInterface?.App.ExtAppId}/{proposedInterface?.Id}"; + string interfacelink = $"{userConfig.GetText("interface")}: {proposedInterface?.Name}
                      "; + string body = userConfig.ModDecommEmailBody + .Replace(Placeholder.INTERFACE_NAME, $"{ActConn.Name}") + .Replace(Placeholder.NEW_INTERFACE_NAME, $"{proposedInterface?.Name}") + .Replace(Placeholder.NEW_INTERFACE_LINK, $"{interfacelink}") + .Replace(Placeholder.REASON, $"{reason}") + .Replace(Placeholder.USER_NAME, $"{userConfig.User.Name}"); + string connList = string.Join("
                      ", UsingConnections.Where(c => c.AppId != null && c.AppId == app.Id).Select(a => a.Name)); + return $"{body}
                      {connList}"; + } + + private async Task AddToSelections(bool proposeAlternative, ModellingConnection? proposedInterface, List appsToNotify) + { + if (!proposeAlternative || proposedInterface == null) + { + return; + } + + foreach (var app in appsToNotify) + { + try + { + var variables = new + { + appId = app.Id, + connectionId = proposedInterface.Id + }; + await apiConnection.SendQueryAsync(ModellingQueries.addSelectedConnection, variables); + } + catch (Exception) + { + Log.WriteDebug(userConfig.GetText("add_interface"), "Interface was already selected"); + } + } + } + + /// + /// Checks the given interface object if it can be used with network areas that are added to the connection. + /// + /// + /// + public bool InterfaceAllowedWithNetworkArea(ModellingConnection interf) + { + return ActConn.IsInterface || ActConn.IsCommonService || interf.AppId == ActConn.AppId || + (ActConn.DestinationAreas.Count == 0 && DstAreasToAdd.Count == 0 && ActConn.SourceAreas.Count == 0 && SrcAreasToAdd.Count == 0); + } + + /// + /// Checks the selected interface if it is foreign to the modelled connection + /// + /// + public bool IsNotInterfaceForeignToApp() + { + if (!ActConn.IsInterface && !ActConn.IsCommonService && ActConn.UsedInterfaceId != null && + ActConn.UsedInterfaceId > 0 && PreselectedInterfaces.FirstOrDefault(_ => _.Id == ActConn.UsedInterfaceId)?.AppId != ActConn.AppId) + { + return false; + } + return true; + } + + public async Task CreateNewRequestedInterface(long ticketId, bool asSource, string name, string reason) + { + ActConn.TicketId = ticketId; + ActConn.Name = name + " (Ticket: " + ActConn.TicketId.ToString() + ")"; + ActConn.Reason = $"{userConfig.GetText("from_ticket")} {ticketId} ({userConfig.GetText("U9012")}): \r\n{reason}"; + ActConn.IsInterface = true; + ActConn.IsRequested = true; + if (asSource) + { + ActConn.SourceAppRoles.Add(new() { Content = DummyAppRole }); + } + else + { + ActConn.DestinationAppRoles.Add(new() { Content = DummyAppRole }); + } + await AddConnectionToDb(true); + + ActConn.AppId = RequesterId; + await AddToPreselectedList(ActConn); + return ActConn.Id; + } + + public string DisplayInterface(ModellingConnection? inter) + { + if (inter != null) + { + FwoOwner? app = AllApps.FirstOrDefault(x => x.Id == inter.AppId); + if (app != null) + { + return inter.DisplayNameWithOwner(app); + } + return inter.Name ?? ""; + } + return ""; + } + + public async Task RequestReplaceInterface(ModellingConnection interf) + { + if (interf.SourceFilled() != ActConn.SourceFilled() || interf.DestinationFilled() != ActConn.DestinationFilled()) + { + DisplayMessageInUi(null, userConfig.GetText("replace"), userConfig.GetText("E9017"), true); + return; + } + ReplaceMode = true; + await DisplaySelectedInterface(interf); + } + + public async Task ReplaceInterface(Task authenticationStateTask, MiddlewareClient middlewareClient, + IRequestedRulePolicyChecker? requestedRulePolicyChecker = null) + { + try + { + if (IntConnHandler != null) + { + await ReplaceLinks(); + await RemoveFromAllSelections(); + if (await DeleteRequestedInterface()) + { + await UpdateTicket(authenticationStateTask, middlewareClient, requestedRulePolicyChecker); + } + await RefreshParent(); + Close(); + } + } + catch (Exception exception) + { + DisplayMessageInUi(exception, userConfig.GetText("replace"), "", true); + } + } + + private async Task ReplaceLinks() + { + if (UsingConnections.Count > 0) + { + var Variables = new + { + usedInterfaceIdOld = ActConn.Id, + usedInterfaceIdNew = IntConnHandler?.ActConn.Id + }; + int replacedConns = (await apiConnection.SendQueryAsync(ModellingQueries.replaceUsedInterface, Variables)).AffectedRows; + await LogChange(ModellingTypes.ChangeType.Replace, ModellingTypes.ModObjectType.Connection, ActConn.Id, + $"Replaced Used Interface: {ActConn.Name} by: {IntConnHandler?.ActConn.Name} for {replacedConns} Connections", Application.Id); + } + } + + public async Task RemoveFromAllSelections() + { + await apiConnection.SendQueryAsync(ModellingQueries.removeSelectedConnection, new { connectionId = ActConn.Id }); + } + + private async Task DeleteRequestedInterface() + { + if (UsingConnections.Count > 0) + { + DisplayMessageInUi(null, userConfig.GetText("delete_interface"), userConfig.GetText("E9016"), true); + return false; + } + if (await DeleteConnection(ActConn)) + { + await LogChange(ModellingTypes.ChangeType.Delete, ModellingTypes.ModObjectType.Connection, ActConn.Id, + $"Deleted Interface: {ActConn.Name}", Application.Id); + Connections.Remove(ActConn); + } + return true; + } + + private async Task UpdateTicket(Task authenticationStateTask, MiddlewareClient middlewareClient, + IRequestedRulePolicyChecker? requestedRulePolicyChecker = null) + { + if (ActConn.TicketId != null) + { + try + { + // change referred connId ? + string comment = $"{userConfig.GetText("U9016")}: {IntConnHandler?.ActConn.Name}"; + TicketCreator ticketCreator = new(apiConnection, userConfig, authenticationStateTask!.Result.User, middlewareClient, WorkflowPhases.implementation, requestedRulePolicyChecker); + if (await ticketCreator.PromoteNewInterfaceImplTask((long)ActConn.TicketId, ExtStates.Done, comment)) + { + DisplayMessageInUi(null, comment, userConfig.GetText("U9013"), false); + } + } + catch (Exception exception) + { + DisplayMessageInUi(exception, userConfig.GetText("update_ticket"), "", true); + } + } + } + + public void InterfaceToConn(ModellingConnection interf) + { + InterfaceName = interf.Name ?? ""; + SrcReadOnly = interf.SourceFilled(); + DstReadOnly = interf.DestinationFilled(); + SvcReadOnly = true; + ActConn.IsInterface = false; + ActConn.UsedInterfaceId = interf.Id; + ActConn.InterfaceIsRequested = interf.IsRequested; + ActConn.InterfaceIsRejected = interf.GetBoolProperty(ConState.Rejected.ToString()); + ActConn.InterfaceIsDecommissioned = interf.GetBoolProperty(ConState.Decommissioned.ToString()); + ActConn.InterfaceNoPermission = EvaluateInterfaceNoPermission(interf, ActConn.AppId ?? Application.Id); + ActConn.TicketId = interf.TicketId; + if (SrcReadOnly) + { + SrcAppServerToDelete.AddRange([.. ModellingAppServerWrapper.Resolve(ActConn.SourceAppServers)]); + ActConn.SourceAppServers = [.. interf.SourceAppServers]; + SrcAppRolesToDelete.AddRange([.. ModellingAppRoleWrapper.Resolve(ActConn.SourceAppRoles)]); + ActConn.SourceAppRoles = [.. interf.SourceAppRoles]; + SrcAreasToDelete.AddRange([.. ModellingNetworkAreaWrapper.Resolve(ActConn.SourceAreas)]); + ActConn.SourceAreas = [.. interf.SourceAreas]; + SrcNwGroupsToDelete.AddRange([.. ModellingNwGroupWrapper.Resolve(ActConn.SourceOtherGroups)]); + ActConn.SourceOtherGroups = [.. interf.SourceOtherGroups]; + ActConn.SrcFromInterface = true; + } + else + { + DstAppServerToDelete.AddRange([.. ModellingAppServerWrapper.Resolve(ActConn.DestinationAppServers)]); + ActConn.DestinationAppServers = [.. interf.DestinationAppServers]; + DstAppRolesToDelete.AddRange([.. ModellingAppRoleWrapper.Resolve(ActConn.DestinationAppRoles)]); + ActConn.DestinationAppRoles = [.. interf.DestinationAppRoles]; + DstAreasToDelete.AddRange([.. ModellingNetworkAreaWrapper.Resolve(ActConn.DestinationAreas)]); + ActConn.DestinationAreas = [.. interf.DestinationAreas]; + DstNwGroupsToDelete.AddRange([.. ModellingNwGroupWrapper.Resolve(ActConn.DestinationOtherGroups)]); + ActConn.DestinationOtherGroups = [.. interf.DestinationOtherGroups]; + ActConn.DstFromInterface = true; + } + SvcToDelete.AddRange([.. ModellingServiceWrapper.Resolve(ActConn.Services)]); + ActConn.Services = [.. interf.Services]; + SvcGrpToDelete.AddRange([.. ModellingServiceGroupWrapper.Resolve(ActConn.ServiceGroups)]); + ActConn.ServiceGroups = [.. interf.ServiceGroups]; + ActConn.ExtraConfigsFromInterface = interf.ExtraConfigs; + } + + public void RemoveInterf() + { + InterfaceName = ""; + if (SrcReadOnly) + { + ActConn.SourceAppServers = []; + ActConn.SourceAppRoles = []; + ActConn.SourceAreas = []; + ActConn.SourceOtherGroups = []; + ActConn.SrcFromInterface = false; + } + if (DstReadOnly) + { + ActConn.DestinationAppServers = []; + ActConn.DestinationAppRoles = []; + ActConn.DestinationAreas = []; + ActConn.DestinationOtherGroups = []; + ActConn.DstFromInterface = false; + } + ActConn.Services = []; + ActConn.ServiceGroups = []; + ActConn.UsedInterfaceId = null; + ActConn.InterfaceIsRequested = false; + ActConn.InterfaceIsRejected = false; + ActConn.InterfaceIsDecommissioned = false; + ActConn.InterfaceNoPermission = false; + ActConn.TicketId = null; + SrcReadOnly = false; + DstReadOnly = false; + SvcReadOnly = false; + ActConn.ExtraConfigsFromInterface = []; + } + + public bool PreparePublishInterface() + { + bool publishRequested = !AddMode && ActConn.IsInterface && ActConn.IsRequested && !ActConn.IsPublished && + ActConn.InterfacePermission != InterfacePermissions.Private.ToString(); + if (publishRequested) + { + ActConn.Creator = userConfig.User.Name; + ActConn.IsRequested = false; + ActConn.IsPublished = true; + if (ActConn.AppId == null) + { + ActConn.AppId = ActConn.ProposedAppId; + ActConn.ProposedAppId = null; + } + } + return publishRequested; + } + + private async Task DecommInterface() + { + await DecommInterfaceInDb(); + await UpdateStatusInterfaceUsersDecomm(); + } + + private async Task DecommInterfaceInDb() + { + try + { + var Variables = new + { + id = ActConn.Id, + reason = ActConn.Reason, + connProp = ActConn.Properties, + removalDate = DateTime.Now + }; + await apiConnection.SendQueryAsync(ModellingQueries.updateConnectionDecommission, Variables); + await LogChange(ModellingTypes.ChangeType.Decommission, ModellingTypes.ModObjectType.Connection, ActConn.Id, + $"Decommissioned {kInterface}: {ActConn.Name}", Application.Id); + + Connections[Connections.FindIndex(x => x.Id == ActConn.Id)] = ActConn; + foreach (var conn in Connections.Where(x => x.UsedInterfaceId == ActConn.Id)) + { + await ExtractUsedInterface(conn); + } + } + catch (Exception exception) + { + DisplayMessageInUi(exception, userConfig.GetText(EditConnection), "", true); + } + } + + private async Task UpdateStatusInterfaceUsersDecomm() + { + try + { + foreach (var conn in UsingConnections.Where(c => !c.GetBoolProperty(ConState.InterfaceDecommissioned.ToString()))) + { + conn.AddProperty(ConState.InterfaceDecommissioned.ToString()); + await apiConnection.SendQueryAsync(ModellingQueries.updateConnectionProperties, new { id = conn.Id, connProp = conn.Properties }); + } + } + catch (Exception exception) + { + DisplayMessageInUi(exception, userConfig.GetText("update_interf_user"), "", true); + } + } + + private async Task UpdateStatusInterfaceUsersPublished() + { + try + { + foreach (var conn in UsingConnections.Where(c => c.GetBoolProperty(ConState.InterfaceRequested.ToString()))) + { + conn.RemoveProperty(ConState.InterfaceRequested.ToString()); + await apiConnection.SendQueryAsync(ModellingQueries.updateConnectionProperties, new { id = conn.Id, connProp = conn.Properties }); + } + } + catch (Exception exception) + { + DisplayMessageInUi(exception, userConfig.GetText("update_interf_user"), "", true); + } + } + + // Preselected Interfaces + public void RequestRemovePreselectedInterface(ModellingConnection interf) + { + actInterface = interf; + Message = userConfig.GetText("U9006") + interf.Name + "?"; + RemovePreselectedInterfaceMode = true; + } + + public async Task RemovePreselectedInterface() + { + try + { + if ((await apiConnection.SendQueryAsync(ModellingQueries.removeSelectedConnectionFromApp, new { appId = Application.Id, connectionId = actInterface.Id })).AffectedRows > 0) + { + PreselectedInterfaces.Remove(PreselectedInterfaces.FirstOrDefault(x => x.Id == actInterface.Id) ?? throw new KeyNotFoundException("Did not find object.")); + RemovePreselectedInterfaceMode = false; + } + } + catch (Exception exception) + { + DisplayMessageInUi(exception, userConfig.GetText("remove_interface"), "", true); + } + } + + public async Task DisplaySelectedInterface(ModellingConnection interf) + { + FwoOwner? app = AllApps.FirstOrDefault(x => x.Id == interf.AppId); + IntConnHandler = new ModellingConnectionHandler(apiConnection, userConfig, app ?? new(), Connections, interf, false, true, DisplayMessageInUi, DefaultInit.DoNothing, false); + await IntConnHandler.Init(); + DisplaySelectedInterfaceMode = true; + } + + private async Task AddToPreselectedList(ModellingConnection? requestedInterface) + { + try + { + if (requestedInterface != null) + { + var Variables = new + { + appId = requestedInterface.AppId, + connectionId = requestedInterface.Id + }; + await apiConnection.SendQueryAsync(ModellingQueries.addSelectedConnection, Variables); + PreselectedInterfaces.Add(requestedInterface); + } + } + catch (Exception exception) + { + DisplayMessageInUi(exception, userConfig.GetText("add_interface"), "", true); + } + } + } +} diff --git a/roles/lib/files/FWO.Services/Modelling/ModellingConnectionHandlerNwObjHandling.cs b/roles/lib/files/FWO.Services/Modelling/ModellingConnectionHandlerNwObjHandling.cs new file mode 100644 index 0000000000..b80bdb8403 --- /dev/null +++ b/roles/lib/files/FWO.Services/Modelling/ModellingConnectionHandlerNwObjHandling.cs @@ -0,0 +1,759 @@ +using FWO.Api.Client; +using FWO.Api.Client.Queries; +using FWO.Basics; +using FWO.Config.Api; +using FWO.Config.Api.Data; +using FWO.Data; +using FWO.Data.Modelling; +using System.Text.Json; + + +namespace FWO.Services.Modelling +{ + public partial class ModellingConnectionHandler + { + public List AvailableAppRoles { get; set; } = []; + public List AvailableSelectedObjects { get; set; } = []; + public List AvailableCommonAreas { get; set; } = []; + public List AvailableNwGroups { get; set; } = []; + public List CommonAreaConfigItems { get; set; } = []; + public ModellingAppServerHandler? AppServerHandler { get; set; } + private readonly string InsertForbidden = "insert_forbidden"; + private ModellingAppRole actAppRole = new(); + private ModellingNwGroup actNwGrpObj = new(); + private List FoundConnectionsForAppRole = []; + + public async Task InitAvailableNWObjects() + { + try + { + AvailableAppServers = await apiConnection.SendQueryAsync>(ModellingQueries.getAppServersForOwner, new { appId = Application.Id }); + AvailableAppRoles = await apiConnection.SendQueryAsync>(ModellingQueries.getAppRoles, new { appId = Application.Id }); + + List allAreas = await apiConnection.SendQueryAsync>(ModellingQueries.getNwGroupObjects, new { grpType = (int)ModellingTypes.ModObjectType.NetworkArea }); + CommonAreaConfigItems = []; + if (userConfig.ModCommonAreas != "") + { + CommonAreaConfigItems = JsonSerializer.Deserialize>(userConfig.ModCommonAreas) ?? new(); + } + AvailableCommonAreas = []; + foreach (var comAreaConfig in CommonAreaConfigItems) + { + ModellingNetworkArea? area = allAreas.FirstOrDefault(a => a.Id == comAreaConfig.AreaId); + if (area != null) + { + AvailableCommonAreas.Add(new() { Content = area }); + } + } + AvailableNwGroups = []; + + AvailableSelectedObjects = await apiConnection.SendQueryAsync>(ModellingQueries.getSelectedNwGroupObjects, new { appId = Application.Id }); + AvailableSelectedObjects = AvailableSelectedObjects.Where(x => AvailableCommonAreas.FirstOrDefault(a => a.Content.Id == x.Content.Id) == null).ToList(); + } + catch (Exception exception) + { + DisplayMessageInUi(exception, userConfig.GetText(InitEnvironment), "", true); + } + } + + public bool RefreshSelectableNwObjects() + { + AvailableNwElems = []; + foreach (var obj in AvailableCommonAreas.Select(o => o.Content)) + { + AvailableNwElems.Add(new KeyValuePair(obj.GroupType, obj.Id)); + } + foreach (var obj in AvailableSelectedObjects.Select(o => o.Content)) + { + AvailableNwElems.Add(new KeyValuePair(obj.GroupType, obj.Id)); + } + foreach (var appRole in AvailableAppRoles) + { + AvailableNwElems.Add(new KeyValuePair((int)ModellingTypes.ModObjectType.AppRole, appRole.Id)); + } + if (userConfig.AllowServerInConn) + { + foreach (var appServer in AvailableAppServers.Where(x => !x.IsDeleted)) + { + AvailableNwElems.Add(new KeyValuePair((int)ModellingTypes.ModObjectType.AppServer, appServer.Id)); + } + } + return true; + } + + private void SyncSrcChanges() + { + if (ActConn.IsInterface && SrcFilledInWork(1)) + { + ModellingAppRoleWrapper? linkedDummyAR = ActConn.SourceAppRoles.FirstOrDefault(x => x.Content.Id == DummyAppRole.Id); + if (linkedDummyAR != null) + { + SrcAppRolesToDelete.Add(linkedDummyAR.Content); + } + } + foreach (var appServer in SrcAppServerToDelete) + { + ActConn.SourceAppServers.Remove(ActConn.SourceAppServers.FirstOrDefault(x => x.Content.Id == appServer.Id) ?? throw new KeyNotFoundException("Did not find app server.")); + } + foreach (var appServer in SrcAppServerToAdd) + { + ActConn.SourceAppServers.Add(new ModellingAppServerWrapper() { Content = appServer }); + } + foreach (var appRole in SrcAppRolesToDelete) + { + ActConn.SourceAppRoles.Remove(ActConn.SourceAppRoles.FirstOrDefault(x => x.Content.Id == appRole.Id) ?? throw new KeyNotFoundException("Did not find app role.")); + } + foreach (var appRole in SrcAppRolesToAdd) + { + ActConn.SourceAppRoles.Add(new ModellingAppRoleWrapper() { Content = appRole }); + } + foreach (var area in SrcAreasToDelete) + { + ActConn.SourceAreas.Remove(ActConn.SourceAreas.FirstOrDefault(x => x.Content.Id == area.Id) ?? throw new KeyNotFoundException("Did not find area.")); + } + foreach (var area in SrcAreasToAdd) + { + ActConn.SourceAreas.Add(new ModellingNetworkAreaWrapper() { Content = area }); + } + foreach (var nwGroup in SrcNwGroupsToDelete) + { + ActConn.SourceOtherGroups.Remove(ActConn.SourceOtherGroups.FirstOrDefault(x => x.Content.Id == nwGroup.Id) ?? throw new KeyNotFoundException("Did not find nwgroup.")); + } + foreach (var nwGroup in SrcNwGroupsToAdd) + { + ActConn.SourceOtherGroups.Add(new ModellingNwGroupWrapper() { Content = nwGroup }); + } + } + + private void SyncDstChanges() + { + if (ActConn.IsInterface && DstFilledInWork(1)) + { + ModellingAppRoleWrapper? linkedDummyAR = ActConn.DestinationAppRoles.FirstOrDefault(x => x.Content.Id == DummyAppRole.Id); + if (linkedDummyAR != null) + { + DstAppRolesToDelete.Add(linkedDummyAR.Content); + } + } + foreach (var appServer in DstAppServerToDelete) + { + ActConn.DestinationAppServers.Remove(ActConn.DestinationAppServers.FirstOrDefault(x => x.Content.Id == appServer.Id) ?? throw new KeyNotFoundException("Did not find app server.")); + } + foreach (var appServer in DstAppServerToAdd) + { + ActConn.DestinationAppServers.Add(new ModellingAppServerWrapper() { Content = appServer }); + } + foreach (var appRole in DstAppRolesToDelete) + { + ActConn.DestinationAppRoles.Remove(ActConn.DestinationAppRoles.FirstOrDefault(x => x.Content.Id == appRole.Id) ?? throw new KeyNotFoundException("Did not find app role.")); + } + foreach (var appRole in DstAppRolesToAdd) + { + ActConn.DestinationAppRoles.Add(new ModellingAppRoleWrapper() { Content = appRole }); + } + foreach (var area in DstAreasToDelete) + { + ActConn.DestinationAreas.Remove(ActConn.DestinationAreas.FirstOrDefault(x => x.Content.Id == area.Id) ?? throw new KeyNotFoundException("Did not find area.")); + } + foreach (var area in DstAreasToAdd) + { + ActConn.DestinationAreas.Add(new ModellingNetworkAreaWrapper() { Content = area }); + } + foreach (var nwGroup in DstNwGroupsToDelete) + { + ActConn.DestinationOtherGroups.Remove(ActConn.DestinationOtherGroups.FirstOrDefault(x => x.Content.Id == nwGroup.Id) ?? throw new KeyNotFoundException("Did not find nwgroup.")); + } + foreach (var nwGroup in DstNwGroupsToAdd) + { + ActConn.DestinationOtherGroups.Add(new ModellingNwGroupWrapper() { Content = nwGroup }); + } + } + + /// + /// Checks if the given network areas are allowed in the current connection/interface/service. + /// + /// The list of network areas to check. + /// Out parameter to give context as a reason why it's not allowed, otherwise is's empty. + public bool NetworkAreaUseAllowed(List networkAreas, Direction direction, out (string Title, string Text) reason) + { + if (ActConn.IsCommonService) + { + reason.Title = userConfig.GetText("edit_common_service"); + } + else if (ActConn.IsInterface) + { + reason.Title = userConfig.GetText("edit_interface"); + } + else + { + reason.Title = userConfig.GetText(EditConnection); + } + + reason.Text = ""; + if (IsAreaForbiddenInDirection(direction)) + { + reason.Text = userConfig.GetText("U9022"); + return false; + } + + if (ActConn.IsInterface) + { + reason.Text = userConfig.GetText("U9021"); + return false; + } + + bool hasCommonNetworkAreas = HasCommonNetworkAreas(networkAreas); + if (!hasCommonNetworkAreas && ActConn.IsCommonService) + { + return true; + } + else if (hasCommonNetworkAreas && (ActConn.IsCommonService || (!ActConn.IsInterface && !ActConn.IsCommonService))) + { + return true; + } + + reason.Text = userConfig.GetText("U9023"); + return false; + } + + /// + /// Checks if a common service contains only common network areas. + /// + /// + private bool ComSvcContainsOnlyCommonNetworkArea() + { + List srcAreas = [.. ModellingNetworkAreaWrapper.Resolve(ActConn.SourceAreas)]; + List destAreas = [.. ModellingNetworkAreaWrapper.Resolve(ActConn.DestinationAreas)]; + + HashSet srcAreasToDeleteIds = [.. SrcAreasToDelete.Select(d => d.Id)]; + srcAreas.RemoveAll(a => srcAreasToDeleteIds.Contains(a.Id)); + + HashSet dstAreasToDeleteIds = [.. DstAreasToDelete.Select(d => d.Id)]; + destAreas.RemoveAll(a => dstAreasToDeleteIds.Contains(a.Id)); + + if (HasOnlyCommonNetworkAreas(srcAreas) && + HasOnlyCommonNetworkAreas(SrcAreasToAdd) && + HasOnlyCommonNetworkAreas(destAreas) && + HasOnlyCommonNetworkAreas(DstAreasToAdd)) + { + return true; + } + + return false; + } + + /// + /// Checks if a common service contains only network areas in the specified direction. + /// + /// The direction to check (Source or Destination). + /// The app roles to be added to the direction. + /// True if only network areas exist. + public bool ComSvcContainsOnlyNetworkAreasInDirection(Direction direction, List selectedAppRoles) + { + return ComSvcContainsOnlyNetworkAreasInDirectionInternal(direction, [], selectedAppRoles); + } + + /// + /// Checks if a common service contains only network areas in the specified direction. + /// + /// The direction to check (Source or Destination). + /// The network areas to be added to the direction. + /// True if only network areas exist. + public bool ComSvcContainsOnlyNetworkAreasInDirection(Direction direction, List selectedNetworkAreas) + { + return ComSvcContainsOnlyNetworkAreasInDirectionInternal(direction, selectedNetworkAreas, []); + } + + /// + /// Internal method that validates whether only network areas (without app roles) exist in the specified direction of a common service. + /// Combines existing areas/appRoles from the connection with items to add, removes items marked for deletion, and checks if the result contains both types. + /// + /// The direction to check (Source or Destination). + /// Network areas to be considered in addition to existing ones. + /// App roles to be considered in addition to existing ones. + /// True if only network areas exist. + private bool ComSvcContainsOnlyNetworkAreasInDirectionInternal(Direction direction, IEnumerable initialAreas, IEnumerable initialRoles) + { + List areas = [.. initialAreas]; + List appRoles = [.. initialRoles]; + + if (direction == Direction.Source) + { + areas.AddRange([.. ModellingNetworkAreaWrapper.Resolve(ActConn.SourceAreas)]); + areas.AddRange(SrcAreasToAdd); + + HashSet srcAreasToDeleteIds = [.. SrcAreasToDelete.Select(d => d.Id)]; + areas.RemoveAll(a => srcAreasToDeleteIds.Contains(a.Id)); + + appRoles.AddRange([.. ModellingAppRoleWrapper.Resolve(ActConn.SourceAppRoles)]); + appRoles.AddRange(SrcAppRolesToAdd); + + HashSet srcAppRolesToDeleteIds = [.. SrcAppRolesToDelete.Select(d => d.Id)]; + appRoles.RemoveAll(r => srcAppRolesToDeleteIds.Contains(r.Id)); + } + else if (direction == Direction.Destination) + { + areas.AddRange([.. ModellingNetworkAreaWrapper.Resolve(ActConn.DestinationAreas)]); + areas.AddRange(DstAreasToAdd); + + HashSet dstAreasToDeleteIds = [.. DstAreasToDelete.Select(d => d.Id)]; + areas.RemoveAll(a => dstAreasToDeleteIds.Contains(a.Id)); + + appRoles.AddRange([.. ModellingAppRoleWrapper.Resolve(ActConn.DestinationAppRoles)]); + appRoles.AddRange(DstAppRolesToAdd); + + HashSet dstAppRolesToDeleteIds = [.. DstAppRolesToDelete.Select(d => d.Id)]; + appRoles.RemoveAll(r => dstAppRolesToDeleteIds.Contains(r.Id)); + } + else + { + throw new ArgumentException($"{nameof(direction)} not implemented"); + } + + return !(areas.Count > 0 && appRoles.Count > 0); + } + + /// + /// Checks the opposite direction if it already contains a network area. + /// + private bool IsAreaForbiddenInDirection(Direction direction) + { + return direction switch + { + Direction.Source => ActConn.DestinationAreas.Count > 0 || DstAreasToAdd.Count > 0, + Direction.Destination => ActConn.SourceAreas.Count > 0 || SrcAreasToAdd.Count > 0, + _ => false, + }; + } + + /// + /// Checks the given list of network areas against common network area settings. + /// + /// + /// + private bool HasCommonNetworkAreas(List networkAreas) + { + return networkAreas.Any(a => CommonAreaConfigItems.Any(_ => _.AreaId == a.Id)); + } + + /// + /// Determines whether all specified network areas are included in the set of common network areas. + /// + /// A list of network areas to check for inclusion in the common network areas. + /// true if every network area in the list is present in the common network areas configuration; otherwise, false. + private bool HasOnlyCommonNetworkAreas(List networkAreas) + { + return networkAreas.All(a => CommonAreaConfigItems.Any(_ => _.AreaId == a.Id)); + } + + + public void DisplayAppServer(ModellingAppServer? appServer) + { + if (appServer != null) + { + try + { + AppServerHandler = new(apiConnection, userConfig, Application, appServer, [], false, DisplayMessageInUi, ReadOnly, IsOwner) { ReadOnly = true }; + DisplayAppServerMode = true; + } + catch (Exception exception) + { + DisplayMessageInUi(exception, userConfig.GetText("display_app_server"), "", true); + } + } + } + + public void AppServerToSource(List srcAppServers) + { + if (!SrcDropForbidden()) + { + foreach (var srcAppServer in srcAppServers) + { + if (!srcAppServer.IsDeleted && ActConn.SourceAppServers.FirstOrDefault(w => w.Content.Id == srcAppServer.Id) == null && !SrcAppServerToAdd.Contains(srcAppServer)) + { + SrcAppServerToAdd.Add(srcAppServer); + } + } + CalcVisibility(); + } + } + + public void AppServerToDestination(List dstAppServers) + { + if (!DstDropForbidden()) + { + foreach (var dstAppServer in dstAppServers) + { + if (!dstAppServer.IsDeleted && ActConn.DestinationAppServers.FirstOrDefault(w => w.Content.Id == dstAppServer.Id) == null && !DstAppServerToAdd.Contains(dstAppServer)) + { + DstAppServerToAdd.Add(dstAppServer); + } + } + CalcVisibility(); + } + } + + public void SearchNWObject() + { + SearchNWObjectMode = true; + } + + public void RequestRemoveNwGrpObject(ModellingNwGroup? nwGrpObj) + { + if (nwGrpObj != null) + { + actNwGrpObj = nwGrpObj; + Message = userConfig.GetText("U9006") + nwGrpObj.Name + "?"; + RemoveNwObjectMode = true; + } + } + + public async Task RemoveNwGrpObject() + { + try + { + if ((await apiConnection.SendQueryAsync(ModellingQueries.removeSelectedNwGroupObject, new { appId = Application.Id, nwGroupId = actNwGrpObj.Id })).AffectedRows > 0) + { + AvailableSelectedObjects.Remove(AvailableSelectedObjects.FirstOrDefault(x => x.Content.Id == actNwGrpObj.Id) ?? throw new KeyNotFoundException("Did not find object.")); + AvailableNwElems.Remove(AvailableNwElems.FirstOrDefault(x => x.Key == actNwGrpObj.GroupType && x.Value == actNwGrpObj.Id)); + RemoveNwObjectMode = false; + } + } + catch (Exception exception) + { + DisplayMessageInUi(exception, userConfig.GetText("remove_nw_object"), "", true); + } + } + + public void AreasToSource(List areas) + { + if (!SrcDropForbidden()) + { + foreach (var area in areas) + { + if (ActConn.SourceAreas.FirstOrDefault(w => w.Content.Id == area.Id) == null && !SrcAreasToAdd.Contains(area) && + (CommonAreaConfigItems.FirstOrDefault(x => x.AreaId == area.Id)?.UseInSrc ?? true)) + { + SrcAreasToAdd.Add(area); + } + else + { + DisplayMessageInUi(null, userConfig.GetText(InsertForbidden), userConfig.GetText("E9015"), true); + } + } + CalcVisibility(); + } + } + + public void AreasToDestination(List areas) + { + if (!DstDropForbidden()) + { + foreach (var area in areas) + { + if (ActConn.DestinationAreas.FirstOrDefault(w => w.Content.Id == area.Id) == null && !DstAreasToAdd.Contains(area) && + (CommonAreaConfigItems.FirstOrDefault(x => x.AreaId == area.Id)?.UseInSrc ?? true)) + { + DstAreasToAdd.Add(area); + } + else + { + DisplayMessageInUi(null, userConfig.GetText(InsertForbidden), userConfig.GetText("E9015"), true); + } + } + CalcVisibility(); + } + } + + public void NwGroupToSource(List nwGroups) + { + if (!SrcDropForbidden()) + { + foreach (var nwGroup in nwGroups) + { + if (ActConn.SourceOtherGroups.FirstOrDefault(w => w.Content.Id == nwGroup.Id) == null && !SrcNwGroupsToAdd.Contains(nwGroup) && + (CommonAreaConfigItems.FirstOrDefault(x => x.AreaId == nwGroup.Id)?.UseInSrc ?? true)) + { + SrcNwGroupsToAdd.Add(nwGroup); + } + else + { + DisplayMessageInUi(null, userConfig.GetText(InsertForbidden), userConfig.GetText("E9015"), true); + } + } + CalcVisibility(); + } + } + + public void NwGroupToDestination(List nwGroups) + { + if (!DstDropForbidden()) + { + foreach (var nwGroup in nwGroups) + { + if (ActConn.DestinationOtherGroups.FirstOrDefault(w => w.Content.Id == nwGroup.Id) == null && !DstNwGroupsToAdd.Contains(nwGroup) && + (CommonAreaConfigItems.FirstOrDefault(x => x.AreaId == nwGroup.Id)?.UseInDst ?? true)) + { + DstNwGroupsToAdd.Add(nwGroup); + } + else + { + DisplayMessageInUi(null, userConfig.GetText(InsertForbidden), userConfig.GetText("E9015"), true); + } + } + CalcVisibility(); + } + } + + public void CreateAppRole() + { + DisplayAppRoleMode = false; + AddAppRoleMode = true; + HandleAppRole(new ModellingAppRole() { }); + } + + public void EditAppRole(ModellingAppRole? appRole) + { + if (appRole != null) + { + DisplayAppRoleMode = false; + AddAppRoleMode = false; + HandleAppRole(appRole); + } + } + + public void DisplayAppRole(ModellingAppRole? appRole) + { + if (appRole != null) + { + DisplayAppRoleMode = true; + AddAppRoleMode = false; + HandleAppRole(appRole); + } + } + + private void HandleAppRole(ModellingAppRole appRole) + { + try + { + AppRoleHandler = new ModellingAppRoleHandler(apiConnection, userConfig, Application, AvailableAppRoles, + appRole, AvailableAppServers, AvailableNwElems, AddAppRoleMode, DisplayMessageInUi, IsOwner, DisplayAppRoleMode); + EditAppRoleMode = true; + } + catch (Exception exception) + { + DisplayMessageInUi(exception, userConfig.GetText("edit_app_role"), "", true); + } + } + + public async Task RequestDeleteAppRole(ModellingAppRole? appRole) + { + if (appRole != null) + { + actAppRole = appRole; + DeleteAllowed = !await CheckAppRoleIsInUse(); + Message = DeleteAllowed ? userConfig.GetText("U9002") + actAppRole.Name + "?" : userConfig.GetText("E9009") + actAppRole.Name; + DeleteAppRoleMode = true; + } + } + + private async Task CheckAppRoleIsInUse() + { + try + { + if (SrcAppRolesToAdd.Any(s => s.Id == actAppRole.Id) || DstAppRolesToAdd.Any(s => s.Id == actAppRole.Id)) + { + return true; + } + FoundConnectionsForAppRole = [.. ModellingConnectionWrapper.Resolve(await apiConnection.SendQueryAsync>(ModellingQueries.getConnectionIdsForNwGroup, new { id = actAppRole.Id }))]; + return FoundConnectionsForAppRole.Any(c => !c.Removed); + } + catch (Exception exception) + { + DisplayMessageInUi(exception, userConfig.GetText("is_in_use"), "", true); + return true; + } + } + + public async Task DeleteAppRole() + { + try + { + bool deleted; + if (FoundConnectionsForAppRole.Count == 0) + { + deleted = (await apiConnection.SendQueryAsync(ModellingQueries.deleteNwGroup, new { id = actAppRole.Id })).AffectedRows > 0; + } + else + { + deleted = (await apiConnection.SendQueryAsync(ModellingQueries.setNwGroupDeletedState, new { id = actAppRole.Id, deleted = true })).UpdatedIdLong > 0; + } + if (deleted) + { + await LogChange(ModellingTypes.ChangeType.Delete, ModellingTypes.ModObjectType.AppRole, actAppRole.Id, + $"Deleted App Role: {actAppRole.Display()}", Application.Id); + AvailableAppRoles.Remove(actAppRole); + AvailableNwElems.Remove(AvailableNwElems.FirstOrDefault(x => x.Key == (int)ModellingTypes.ModObjectType.AppRole && x.Value == actAppRole.Id)); + DeleteAppRoleMode = false; + } + } + catch (Exception exception) + { + DisplayMessageInUi(exception, userConfig.GetText("delete_app_role"), "", true); + } + } + + public void AppRolesToSource(List appRoles) + { + if (!SrcDropForbidden()) + { + foreach (var appRole in appRoles.Where(a => ActConn.SourceAppRoles.FirstOrDefault(w => w.Content.Id == a.Id) == null && !SrcAppRolesToAdd.Contains(a))) + { + SrcAppRolesToAdd.Add(appRole); + } + CalcVisibility(); + } + } + + public void AppRolesToDestination(List appRoles) + { + if (!DstDropForbidden()) + { + foreach (var appRole in appRoles.Where(a => ActConn.DestinationAppRoles.FirstOrDefault(w => w.Content.Id == a.Id) == null && !DstAppRolesToAdd.Contains(a))) + { + DstAppRolesToAdd.Add(appRole); + } + CalcVisibility(); + } + } + + private async Task AddNwObjects(List appServers, List appRoles, + List areas, List nwGroups, ModellingTypes.ConnectionField field) + { + try + { + await AddAppServersToConnection(appServers, field); + await AddAppRolesToConnection(appRoles, field); + await AddAreasToConnection(areas, field); + await AddNwGroupsToConnection(nwGroups, field); + } + catch (Exception exception) + { + DisplayMessageInUi(exception, userConfig.GetText(EditConnection), "", true); + } + } + + private async Task AddAppServersToConnection(List appServers, ModellingTypes.ConnectionField field) + { + foreach (var appServer in appServers) + { + var variables = new { nwObjectId = appServer.Id, connectionId = ActConn.Id, connectionField = (int)field }; + await apiConnection.SendQueryAsync(ModellingQueries.addAppServerToConnection, variables); + await LogChange(ModellingTypes.ChangeType.Assign, ModellingTypes.ModObjectType.Connection, ActConn.Id, + $"Added App Server {appServer.Display()} to {GetTypeAndName()}: {field}", Application.Id); + } + } + + private async Task AddAppRolesToConnection(List appRoles, ModellingTypes.ConnectionField field) + { + foreach (var appRole in appRoles) + { + var variables = new { nwGroupId = appRole.Id, connectionId = ActConn.Id, connectionField = (int)field }; + await apiConnection.SendQueryAsync(ModellingQueries.addNwGroupToConnection, variables); + string text = appRole.Id == DummyAppRole.Id + ? $"Marked requested Interface: {ActConn.Name} as {field}" + : $"Added App Role {appRole.Display()} to {GetTypeAndName()}: {field}"; + await LogChange(ModellingTypes.ChangeType.Assign, ModellingTypes.ModObjectType.Connection, ActConn.Id, text, Application.Id); + } + } + + private async Task AddAreasToConnection(List areas, ModellingTypes.ConnectionField field) + { + foreach (var area in areas) + { + var variables = new { nwGroupId = area.Id, connectionId = ActConn.Id, connectionField = (int)field }; + await apiConnection.SendQueryAsync(ModellingQueries.addNwGroupToConnection, variables); + await LogChange(ModellingTypes.ChangeType.Assign, ModellingTypes.ModObjectType.Connection, ActConn.Id, + $"Added Area {area.Display()} to {GetTypeAndName()}: {field}", Application.Id); + } + } + + private async Task AddNwGroupsToConnection(List nwGroups, ModellingTypes.ConnectionField field) + { + foreach (var nwGroup in nwGroups) + { + var variables = new { nwGroupId = nwGroup.Id, connectionId = ActConn.Id, connectionField = (int)field }; + await apiConnection.SendQueryAsync(ModellingQueries.addNwGroupToConnection, variables); + await LogChange(ModellingTypes.ChangeType.Assign, ModellingTypes.ModObjectType.Connection, ActConn.Id, + $"Added Object {nwGroup.Display()} to {GetTypeAndName()}: {field}", Application.Id); + } + } + + private async Task RemoveNwObjects(List appServers, List appRoles, + List areas, List nwGroups, ModellingTypes.ConnectionField field) + { + try + { + await RemoveAppServersFromConnection(appServers, field); + await RemoveAppRolesFromConnection(appRoles, field); + await RemoveAreasFromConnection(areas, field); + await RemoveNwGroupsFromConnection(nwGroups, field); + } + catch (Exception exception) + { + DisplayMessageInUi(exception, userConfig.GetText(EditConnection), "", true); + } + } + + private async Task RemoveAppServersFromConnection(List appServers, ModellingTypes.ConnectionField field) + { + foreach (var appServer in appServers) + { + var variables = new { nwObjectId = appServer.Id, connectionId = ActConn.Id, connectionField = (int)field }; + await apiConnection.SendQueryAsync(ModellingQueries.removeAppServerFromConnection, variables); + await LogChange(ModellingTypes.ChangeType.Unassign, ModellingTypes.ModObjectType.Connection, ActConn.Id, + $"Removed App Server {appServer.Display()} from {GetTypeAndName()}: {field}", Application.Id); + } + } + + private async Task RemoveAppRolesFromConnection(List appRoles, ModellingTypes.ConnectionField field) + { + foreach (var appRole in appRoles) + { + var variables = new { nwGroupId = appRole.Id, connectionId = ActConn.Id, connectionField = (int)field }; + await apiConnection.SendQueryAsync(ModellingQueries.removeNwGroupFromConnection, variables); + string text = appRole.Id == DummyAppRole.Id + ? $"Removed {field} marker from requested Interface: {ActConn.Name}" + : $"Removed App Role {appRole.Display()} from {GetTypeAndName()}: {field}"; + await LogChange(ModellingTypes.ChangeType.Unassign, ModellingTypes.ModObjectType.Connection, ActConn.Id, text, Application.Id); + } + } + + private async Task RemoveAreasFromConnection(List areas, ModellingTypes.ConnectionField field) + { + foreach (var area in areas) + { + var variables = new { nwGroupId = area.Id, connectionId = ActConn.Id, connectionField = (int)field }; + await apiConnection.SendQueryAsync(ModellingQueries.removeNwGroupFromConnection, variables); + await LogChange(ModellingTypes.ChangeType.Unassign, ModellingTypes.ModObjectType.Connection, ActConn.Id, + $"Removed Area {area.Display()} from {GetTypeAndName()}: {field}", Application.Id); + } + } + + private async Task RemoveNwGroupsFromConnection(List nwGroups, ModellingTypes.ConnectionField field) + { + foreach (var nwGroup in nwGroups) + { + var variables = new { nwGroupId = nwGroup.Id, connectionId = ActConn.Id, connectionField = (int)field }; + await apiConnection.SendQueryAsync(ModellingQueries.removeNwGroupFromConnection, variables); + await LogChange(ModellingTypes.ChangeType.Unassign, ModellingTypes.ModObjectType.Connection, ActConn.Id, + $"Removed Object {nwGroup.Display()} from {GetTypeAndName()}: {field}", Application.Id); + } + } + + private string GetTypeAndName() + { + return $"{(ActConn.IsInterface ? kInterface : kConnection)}: {ActConn.Name}"; + } + } +} diff --git a/roles/lib/files/FWO.Services/Modelling/ModellingConnectionHandlerPermissionHandling.cs b/roles/lib/files/FWO.Services/Modelling/ModellingConnectionHandlerPermissionHandling.cs new file mode 100644 index 0000000000..5090a8ebe7 --- /dev/null +++ b/roles/lib/files/FWO.Services/Modelling/ModellingConnectionHandlerPermissionHandling.cs @@ -0,0 +1,142 @@ +using FWO.Api.Client; +using FWO.Api.Client.Queries; +using FWO.Basics; +using FWO.Data; +using FWO.Data.Modelling; + +namespace FWO.Services.Modelling +{ + public partial class ModellingConnectionHandler + { + public List PermittedOwnersToAdd { get; set; } = []; + public List PermittedOwnersToDelete { get; set; } = []; + + private async Task EnsureUsingAppsPermittedIfRestricted() + { + if (!ActConn.IsInterface || ActConn.InterfacePermission != InterfacePermissions.Restricted.ToString() || + ActConnOrig.InterfacePermission == InterfacePermissions.Restricted.ToString()) + { + return; + } + + HashSet existingIds = ActConn.PermittedOwners.Select(o => o.Id).ToHashSet(); + HashSet pendingIds = PermittedOwnersToAdd.Select(o => o.Id).ToHashSet(); + + List usingConnections = await apiConnection.SendQueryAsync>(ModellingQueries.getInterfaceUsers, new { id = ActConn.Id }); + IEnumerable usingAppIds = usingConnections.Where(c => c.AppId != null).Select(c => c.AppId!.Value).Distinct(); + + foreach (int appId in usingAppIds) + { + if (existingIds.Contains(appId) || pendingIds.Contains(appId)) + { + continue; + } + + FwoOwner? owner = AllApps.FirstOrDefault(o => o.Id == appId); + if (owner != null) + { + PermittedOwnersToAdd.Add(owner); + ActConn.PermittedOwners.Add(owner); + } + } + } + + private async Task ApplyPermittedOwnersOnInsert() + { + if (!ActConn.IsInterface || ActConn.InterfacePermission != InterfacePermissions.Restricted.ToString()) + { + PermittedOwnersToAdd.Clear(); + PermittedOwnersToDelete.Clear(); + return; + } + await AddPermittedOwners(ActConn, PermittedOwnersToAdd); + } + + private async Task ApplyPermittedOwnersOnUpdate() + { + if (!ActConn.IsInterface || ActConn.InterfacePermission != InterfacePermissions.Restricted.ToString()) + { + await RemoveAllPermittedOwners(); + ActConn.PermittedOwners.Clear(); + PermittedOwnersToAdd.Clear(); + PermittedOwnersToDelete.Clear(); + return; + } + await RemovePermittedOwners(PermittedOwnersToDelete); + await AddPermittedOwners(ActConn, PermittedOwnersToAdd); + } + + private void SyncPermittedOwnersChanges() + { + foreach (var owner in PermittedOwnersToDelete) + { + ActConn.PermittedOwners.RemoveAll(o => o.Id == owner.Id); + } + foreach (var owner in PermittedOwnersToAdd) + { + if (!ActConn.PermittedOwners.Any(o => o.Id == owner.Id)) + { + ActConn.PermittedOwners.Add(owner); + } + } + } + + public async Task AddPermittedOwnersIfMissing(ModellingConnection? proposedInterface, List owners) + { + if (proposedInterface == null) + { + return; + } + + await AddPermittedOwners(proposedInterface, [.. owners.Where(own => !proposedInterface.PermittedOwners.Any(o => o.Id == own.Id))]); + } + + private async Task AddPermittedOwners(ModellingConnection conn, List owners) + { + try + { + foreach (int ownerId in owners.Select(o => o.Id).Distinct().Where(id => id > 0)) + { + var variables = new { connectionId = conn.Id, appId = ownerId }; + await apiConnection.SendQueryAsync(ModellingQueries.addPermittedOwner, variables); + FwoOwner? owner = owners.FirstOrDefault(o => o.Id == ownerId); + string ownerLabel = owner != null ? owner.Display(userConfig.GetText("common_service")) : ownerId.ToString(); + await LogChange(ModellingTypes.ChangeType.Assign, ModellingTypes.ModObjectType.Connection, conn.Id, + $"Added permitted owner {ownerLabel} to {kInterface}: {conn.Name}", Application.Id); + } + } + catch (Exception exception) + { + DisplayMessageInUi(exception, userConfig.GetText(EditConnection), "", true); + } + } + + private async Task RemovePermittedOwners(List owners) + { + try + { + foreach (int ownerId in owners.Select(o => o.Id).Distinct().Where(id => id > 0)) + { + var variables = new { connectionId = ActConn.Id, appId = ownerId }; + await apiConnection.SendQueryAsync(ModellingQueries.deletePermittedOwner, variables); + FwoOwner? owner = owners.FirstOrDefault(o => o.Id == ownerId); + string ownerLabel = owner != null ? owner.Display(userConfig.GetText("common_service")) : ownerId.ToString(); + await LogChange(ModellingTypes.ChangeType.Unassign, ModellingTypes.ModObjectType.Connection, ActConn.Id, + $"Removed permitted owner {ownerLabel} from {kInterface}: {ActConn.Name}", Application.Id); + } + } + catch (Exception exception) + { + DisplayMessageInUi(exception, userConfig.GetText(EditConnection), "", true); + } + } + + private async Task RemoveAllPermittedOwners() + { + List existing = await apiConnection.SendQueryAsync>( + ModellingQueries.getPermittedOwnersForConnection, + new { connectionId = ActConn.Id }); + await RemovePermittedOwners(existing); + } + } +} diff --git a/roles/lib/files/FWO.Services/Modelling/ModellingConnectionHandlerSvcHandling.cs b/roles/lib/files/FWO.Services/Modelling/ModellingConnectionHandlerSvcHandling.cs new file mode 100644 index 0000000000..64285e6996 --- /dev/null +++ b/roles/lib/files/FWO.Services/Modelling/ModellingConnectionHandlerSvcHandling.cs @@ -0,0 +1,278 @@ +using FWO.Api.Client; +using FWO.Api.Client.Queries; +using FWO.Basics; +using FWO.Config.Api; +using FWO.Config.Api.Data; +using FWO.Data; +using FWO.Data.Modelling; + +namespace FWO.Services.Modelling +{ + public partial class ModellingConnectionHandler + { + public List AvailableServiceGroups { get; set; } = []; + private ModellingServiceGroup actServiceGroup = new(); + + public async Task InitAvailableSvcObjects() + { + try + { + AvailableSvcElems = []; + AvailableServiceGroups = (await apiConnection.SendQueryAsync>(ModellingQueries.getGlobalServiceGroups)).Where(x => x.AppId != Application.Id).ToList(); + AvailableServiceGroups.AddRange(await apiConnection.SendQueryAsync>(ModellingQueries.getServiceGroupsForApp, new { appId = Application.Id })); + AvailableServices = await apiConnection.SendQueryAsync>(ModellingQueries.getGlobalServices); + AvailableServices.AddRange(await apiConnection.SendQueryAsync>(ModellingQueries.getServicesForApp, new { appId = Application.Id })); + foreach (var svcGrp in AvailableServiceGroups) + { + AvailableSvcElems.Add(new KeyValuePair((int)ModellingTypes.ModObjectType.ServiceGroup, svcGrp.Id)); + } + if (userConfig.AllowServiceInConn) + { + foreach (var svc in AvailableServices) + { + AvailableSvcElems.Add(new KeyValuePair((int)ModellingTypes.ModObjectType.Service, svc.Id)); + } + } + } + catch (Exception exception) + { + DisplayMessageInUi(exception, userConfig.GetText("fetch_data"), "", true); + } + } + + private void SyncSvcChanges() + { + foreach (var svc in SvcToDelete) + { + ActConn.Services.Remove(ActConn.Services.FirstOrDefault(x => x.Content.Id == svc.Id) ?? throw new KeyNotFoundException("Did not find service.")); + } + foreach (var svc in SvcToAdd) + { + ActConn.Services.Add(new ModellingServiceWrapper() { Content = svc }); + } + foreach (var svcGrp in SvcGrpToDelete) + { + ActConn.ServiceGroups.Remove(ActConn.ServiceGroups.FirstOrDefault(x => x.Content.Id == svcGrp.Id) ?? throw new KeyNotFoundException("Did not find service group.")); + } + foreach (var svcGrp in SvcGrpToAdd) + { + ActConn.ServiceGroups.Add(new ModellingServiceGroupWrapper() { Content = svcGrp }); + } + } + + public void CreateServiceGroup() + { + DisplaySvcGrpMode = false; + AddSvcGrpMode = true; + HandleServiceGroup(new ModellingServiceGroup() { }); + } + + public void EditServiceGroup(ModellingServiceGroup? serviceGroup) + { + if (serviceGroup != null) + { + DisplaySvcGrpMode = false; + AddSvcGrpMode = false; + HandleServiceGroup(serviceGroup); + } + } + + public void DisplayServiceGroup(ModellingServiceGroup? serviceGroup) + { + if (serviceGroup != null) + { + DisplaySvcGrpMode = true; + AddSvcGrpMode = false; + HandleServiceGroup(serviceGroup); + } + } + + private void HandleServiceGroup(ModellingServiceGroup serviceGroup) + { + try + { + SvcGrpHandler = new ModellingServiceGroupHandler(apiConnection, userConfig, Application, AvailableServiceGroups, + serviceGroup, AvailableServices, AvailableSvcElems, AddSvcGrpMode, DisplayMessageInUi, ReInit, IsOwner, DisplaySvcGrpMode); + EditSvcGrpMode = true; + } + catch (Exception exception) + { + DisplayMessageInUi(exception, userConfig.GetText("edit_service_group"), "", true); + } + } + + public async Task RequestDeleteServiceGrp(ModellingServiceGroup? serviceGroup) + { + if (serviceGroup != null) + { + actServiceGroup = serviceGroup; + DeleteAllowed = !await CheckServiceGroupIsInUse(); + Message = DeleteAllowed ? userConfig.GetText("U9004") + serviceGroup.Name + "?" : userConfig.GetText("E9008") + serviceGroup.Name; + DeleteSvcGrpMode = true; + } + } + + private async Task CheckServiceGroupIsInUse() + { + try + { + if (SvcGrpToAdd.FirstOrDefault(s => s.Id == actServiceGroup.Id) == null) + { + List foundConnections = await apiConnection.SendQueryAsync>(ModellingQueries.getConnectionIdsForServiceGroup, new { serviceGroupId = actServiceGroup.Id }); + if (foundConnections.Count == 0) + { + return false; + } + } + return true; + } + catch (Exception exception) + { + DisplayMessageInUi(exception, userConfig.GetText("is_in_use"), "", true); + return true; + } + } + + public async Task DeleteServiceGroup() + { + try + { + if ((await apiConnection.SendQueryAsync(ModellingQueries.deleteServiceGroup, new { id = actServiceGroup.Id })).AffectedRows > 0) + { + await LogChange(ModellingTypes.ChangeType.Delete, ModellingTypes.ModObjectType.ServiceGroup, actServiceGroup.Id, + $"Deleted Service Group: {actServiceGroup.Display()}", Application.Id); + AvailableServiceGroups.Remove(actServiceGroup); + AvailableSvcElems.Remove(AvailableSvcElems.FirstOrDefault(x => x.Key == (int)ModellingTypes.ModObjectType.ServiceGroup && x.Value == actServiceGroup.Id)); + DeleteSvcGrpMode = false; + } + } + catch (Exception exception) + { + DisplayMessageInUi(exception, userConfig.GetText("delete_service_group"), "", true); + } + } + + public void ServiceGrpsToConn(List serviceGrps) + { + foreach (var grp in serviceGrps) + { + if ((ActConn.ServiceGroups.FirstOrDefault(w => w.Content.Id == grp.Id) == null) && (SvcGrpToAdd.FirstOrDefault(g => g.Id == grp.Id) == null)) + { + SvcGrpToAdd.Add(grp); + } + } + } + + + public void CreateService() + { + AddServiceMode = true; + HandleService(new ModellingService() { }); + } + + public void EditService(ModellingService? service) + { + if (service != null) + { + AddServiceMode = false; + HandleService(service); + } + } + + private void HandleService(ModellingService service) + { + try + { + ServiceHandler = new ModellingServiceHandler(apiConnection, userConfig, Application, service, + AvailableServices, AvailableSvcElems, AddServiceMode, DisplayMessageInUi, IsOwner); + EditServiceMode = true; + } + catch (Exception exception) + { + DisplayMessageInUi(exception, userConfig.GetText("edit_service"), "", true); + } + } + + public async Task RequestDeleteService(ModellingService? service) + { + if (service != null) + { + await RequestDeleteServiceBase(service); + DeleteServiceMode = true; + } + } + + public async Task DeleteService() + { + try + { + DeleteServiceMode = await DeleteService(AvailableServices, AvailableSvcElems); + } + catch (Exception exception) + { + DisplayMessageInUi(exception, userConfig.GetText("delete_service"), "", true); + } + } + + public void ServicesToConn(List services) + { + foreach (var svc in services) + { + if ((ActConn.Services.FirstOrDefault(w => w.Content.Id == svc.Id) == null) && (SvcToAdd.FirstOrDefault(s => s.Id == svc.Id) == null)) + { + SvcToAdd.Add(svc); + } + } + } + + private async Task AddSvcObjects(List services, List serviceGroups) + { + try + { + foreach (var service in services) + { + var svcParams = new { serviceId = service.Id, connectionId = ActConn.Id }; + await apiConnection.SendQueryAsync(ModellingQueries.addServiceToConnection, svcParams); + await LogChange(ModellingTypes.ChangeType.Assign, ModellingTypes.ModObjectType.Connection, ActConn.Id, + $"Added Service {service.Display()} to {(ActConn.IsInterface ? kInterface : kConnection)}: {ActConn.Name}", Application.Id); + } + foreach (var serviceGrp in serviceGroups) + { + var svcGrpParams = new { serviceGroupId = serviceGrp.Id, connectionId = ActConn.Id }; + await apiConnection.SendQueryAsync(ModellingQueries.addServiceGroupToConnection, svcGrpParams); + await LogChange(ModellingTypes.ChangeType.Assign, ModellingTypes.ModObjectType.Connection, ActConn.Id, + $"Added Service Group {serviceGrp.Display()} to {(ActConn.IsInterface ? kInterface : kConnection)}: {ActConn.Name}", Application.Id); + } + } + catch (Exception exception) + { + DisplayMessageInUi(exception, userConfig.GetText(EditConnection), "", true); + } + } + + private async Task RemoveSvcObjects() + { + try + { + foreach (var service in SvcToDelete) + { + var svcParams = new { serviceId = service.Id, connectionId = ActConn.Id }; + await apiConnection.SendQueryAsync(ModellingQueries.removeServiceFromConnection, svcParams); + await LogChange(ModellingTypes.ChangeType.Unassign, ModellingTypes.ModObjectType.Connection, ActConn.Id, + $"Removed Service {service.Display()} from {(ActConn.IsInterface ? kInterface : kConnection)}: {ActConn.Name}", Application.Id); + } + foreach (var serviceGrp in SvcGrpToDelete) + { + var svcGrpParams = new { serviceGroupId = serviceGrp.Id, connectionId = ActConn.Id }; + await apiConnection.SendQueryAsync(ModellingQueries.removeServiceGroupFromConnection, svcGrpParams); + await LogChange(ModellingTypes.ChangeType.Unassign, ModellingTypes.ModObjectType.Connection, ActConn.Id, + $"Removed Service Group {serviceGrp.Display()} from {(ActConn.IsInterface ? kInterface : kConnection)}: {ActConn.Name}", Application.Id); + } + } + catch (Exception exception) + { + DisplayMessageInUi(exception, userConfig.GetText(EditConnection), "", true); + } + } + } +} diff --git a/roles/lib/files/FWO.Services/Modelling/ModellingHandlerBase.cs b/roles/lib/files/FWO.Services/Modelling/ModellingHandlerBase.cs new file mode 100644 index 0000000000..e32f2af89a --- /dev/null +++ b/roles/lib/files/FWO.Services/Modelling/ModellingHandlerBase.cs @@ -0,0 +1,535 @@ +using FWO.Api.Client; +using FWO.Api.Client.Queries; +using FWO.Basics; +using FWO.Config.Api; +using FWO.Data; +using FWO.Data.Modelling; +using FWO.Logging; +using Microsoft.AspNetCore.Components.Authorization; +using System.Security.Claims; + + +namespace FWO.Services.Modelling +{ + public record LogChangeRequest + { + public ModellingTypes.ChangeType ChangeType { get; init; } + public ModellingTypes.ModObjectType ObjectType { get; init; } + public long ObjectId { get; init; } + public string Text { get; init; } = ""; + public ApiConnection ApiConnection { get; init; } = null!; + public UserConfig UserConfig { get; init; } = null!; + public int? ApplicationId { get; init; } + public Action DisplayMessageInUi { get; init; } = null!; + public string? Requester { get; init; } + public string ChangeSource { get; init; } = GlobalConst.kManual; + } + + public class ModellingHandlerBase + { + public FwoOwner Application { get; set; } = new(); + public bool AddMode { get; set; } = false; + protected readonly ApiConnection apiConnection; + protected readonly UserConfig userConfig; + protected Action DisplayMessageInUi { get; set; } + + public List AvailableAppServers { get; set; } = []; + public List> AvailableNwElems { get; set; } = []; + public List AvailableServices { get; set; } = []; + public List> AvailableSvcElems { get; set; } = []; + public List UsingConnections { get; set; } = []; + + public bool ReadOnly { get; set; } = false; + public bool IsOwner { get; set; } = true; + public string Message { get; set; } = ""; + public bool DeleteAllowed { get; set; } = true; + public List SvcToAdd { get; set; } = []; + private ModellingService actService = new(); + private const string DeactMsg = "C9001"; + + public ModellingHandlerBase(ApiConnection apiConnection, UserConfig userConfig, FwoOwner application, + bool addMode, Action displayMessageInUi, bool readOnly, bool isOwner) + { + this.apiConnection = apiConnection; + this.userConfig = userConfig; + Application = application; + AddMode = addMode; + DisplayMessageInUi = displayMessageInUi; + ReadOnly = readOnly; + IsOwner = isOwner; + } + + public ModellingHandlerBase(ApiConnection apiConnection, UserConfig userConfig, Action displayMessageInUi, bool addMode = false) + { + this.apiConnection = apiConnection; + this.userConfig = userConfig; + this.DisplayMessageInUi = displayMessageInUi; + this.AddMode = addMode; + } + + public string DisplayApp(FwoOwner app) + { + return DisplayApp(userConfig, app); + } + + public static string DisplayApp(UserConfig userConfig, FwoOwner app) + { + string tooltipEmptyApp = app.ConnectionCount.Aggregate.Count > 0 ? "" : $"data-toggle=\"tooltip\" title=\"{userConfig.GetText("C9004")}\""; + string tooltip = app.Active ? tooltipEmptyApp : $"data-toggle=\"tooltip\" title=\"{userConfig.GetText("C9003")}\""; + string textMarkerEmptyApp = app.ConnectionCount.Aggregate.Count > 0 ? "" : "*"; + string textToDisplay = (app.Active ? textMarkerEmptyApp : "!") + app.Display(userConfig.GetText("common_service")); + string classEmptyApp = app.ConnectionCount.Aggregate.Count > 0 ? "" : "text-success"; + string textClass = app.Active ? classEmptyApp : "text-danger"; + return $"{(app.Active ? "" : "")}{textToDisplay}{(app.Active ? "" : "")}"; + } + + public static string DisplayReqInt(UserConfig userConfig, long? ticketId, bool otherOwner, bool rejected = false) + { + string tooltipKey = "C9008"; + { + if (rejected) + { + tooltipKey = "C9011"; + } + else if (otherOwner) + { + tooltipKey = "C9007"; + } + } + string tooltip = $"data-toggle=\"tooltip\" title=\"{userConfig.GetText(tooltipKey)}\""; + string content = $"{userConfig.GetText(rejected ? "InterfaceRejected" : "interface_requested")}: ({userConfig.GetText("ticket")} {ticketId?.ToString()})"; + return $"{content}"; + } + + protected async Task LogChange(ModellingTypes.ChangeType changeType, ModellingTypes.ModObjectType objectType, long objId, string text, int? applicationId, string changeSource = GlobalConst.kManual) + { + await LogChange(new LogChangeRequest + { + ChangeType = changeType, + ObjectType = objectType, + ObjectId = objId, + Text = text, + ApiConnection = apiConnection, + UserConfig = userConfig, + ApplicationId = applicationId, + DisplayMessageInUi = DisplayMessageInUi, + ChangeSource = changeSource + }); + } + + public static async Task LogChange(LogChangeRequest request) + { + try + { + var Variables = new + { + appId = request.ApplicationId, + changeType = (int)request.ChangeType, + objectType = (int)request.ObjectType, + objectId = request.ObjectId, + changeText = request.Text, + changer = request.Requester ?? request.UserConfig.User.Name, + changeSource = request.ChangeSource + }; + await request.ApiConnection.SendQueryAsync(ModellingQueries.addHistoryEntry, Variables); + } + catch (Exception exception) + { + request.DisplayMessageInUi(exception, request.UserConfig.GetText("log_change"), "", true); + } + } + + public async Task RequestDeleteServiceBase(ModellingService service) + { + actService = service; + DeleteAllowed = !await CheckServiceIsInUse(); + Message = DeleteAllowed ? userConfig.GetText("U9003") + service.Name + "?" : userConfig.GetText("E9007") + service.Name; + } + + private async Task CheckServiceIsInUse() + { + try + { + if (SvcToAdd.FirstOrDefault(s => s.Id == actService.Id) == null) + { + List foundServiceGroups = await apiConnection.SendQueryAsync>(ModellingQueries.getServiceGroupIdsForService, new { serviceId = actService.Id }); + if (foundServiceGroups.Count == 0) + { + List foundConnections = await apiConnection.SendQueryAsync>(ModellingQueries.getConnectionIdsForService, new { serviceId = actService.Id }); + if (foundConnections.Count == 0) + { + return false; + } + } + } + return true; + } + catch (Exception exception) + { + DisplayMessageInUi(exception, userConfig.GetText("is_in_use"), "", true); + return true; + } + } + + public async Task DeleteService(List availableServices, List>? availableSvcElems = null) + { + try + { + if ((await apiConnection.SendQueryAsync(ModellingQueries.deleteService, new { id = actService.Id })).AffectedRows > 0) + { + await LogChange(ModellingTypes.ChangeType.Delete, ModellingTypes.ModObjectType.Service, actService.Id, + $"Deleted Service: {actService.Display()}", Application.Id); + availableServices.Remove(actService); + availableSvcElems?.Remove(availableSvcElems.FirstOrDefault(x => x.Key == (int)ModellingTypes.ModObjectType.Service && x.Value == actService.Id)); + return false; + } + } + catch (Exception exception) + { + DisplayMessageInUi(exception, userConfig.GetText("delete_service"), "", true); + } + return true; + } + + protected async Task DeleteConnection(ModellingConnection ConnToDelete, bool removeObjectLinks = false) + { + if (!IsOwner) + { + DisplayMessageInUi(null, userConfig.GetText("delete_connection"), userConfig.GetText("E9104"), true); + return false; + } + + try + { + if (ConnToDelete.RequestedOnFw || ConnToDelete.IsPublished || ConnToDelete.TicketId != null) + { + if ((await apiConnection.SendQueryAsync(ModellingQueries.updateConnectionRemove, new { id = ConnToDelete.Id, removalDate = DateTime.Now })).UpdatedId == ConnToDelete.Id) + { + if (removeObjectLinks) + { + await apiConnection.SendQueryAsync(ModellingQueries.removeAllNwGroupsFromConnection, new { id = ConnToDelete.Id }); + await apiConnection.SendQueryAsync(ModellingQueries.removeAllAppServersFromConnection, new { id = ConnToDelete.Id }); + await apiConnection.SendQueryAsync(ModellingQueries.removeAllServiceGroupsFromConnection, new { id = ConnToDelete.Id }); + await apiConnection.SendQueryAsync(ModellingQueries.removeAllServicesFromConnection, new { id = ConnToDelete.Id }); + } + await apiConnection.SendQueryAsync(ModellingQueries.removeSelectedConnection, new { connectionId = ConnToDelete.Id }); + return true; + } + } + else + { + return (await apiConnection.SendQueryAsync(ModellingQueries.deleteConnection, new { id = ConnToDelete.Id })).DeletedId == ConnToDelete.Id; + } + } + catch (Exception exception) + { + DisplayMessageInUi(exception, userConfig.GetText("delete_connection"), "", true); + } + return false; + } + + public async Task ExtractUsedInterface(ModellingConnection conn) + { + string interfaceName = ""; + try + { + if (conn.UsedInterfaceId != null) + { + List interf = await apiConnection.SendQueryAsync>(ModellingQueries.getConnectionById, new { id = conn.UsedInterfaceId }); + if (interf.Count > 0) + { + conn.SrcFromInterface = interf[0].SourceFilled(); + conn.DstFromInterface = interf[0].DestinationFilled(); + conn.InterfaceIsDecommissioned = interf[0].GetBoolProperty(ConState.Decommissioned.ToString()); + conn.InterfaceNoPermission = EvaluateInterfaceNoPermission(interf[0], conn.AppId ?? Application.Id); + if (interf[0].IsRequested) + { + conn.InterfaceIsRequested = true; + conn.InterfaceIsRejected = interf[0].GetBoolProperty(ConState.Rejected.ToString()); + conn.TicketId = interf[0].TicketId; + } + else + { + interfaceName = ExtractFullInterface(conn, interf[0]); + } + SetRelevantProps(conn, interf[0]); + } + } + } + catch (Exception exception) + { + DisplayMessageInUi(exception, userConfig.GetText("fetch_data"), "", true); + } + return interfaceName; + } + + private static string ExtractFullInterface(ModellingConnection conn, ModellingConnection interf) + { + if (interf.SourceFilled()) + { + conn.SourceAppServers = interf.SourceAppServers; + conn.SourceAppRoles = interf.SourceAppRoles; + conn.SourceAreas = interf.SourceAreas; + conn.SourceOtherGroups = interf.SourceOtherGroups; + } + if (interf.DestinationFilled()) + { + conn.DestinationAppServers = interf.DestinationAppServers; + conn.DestinationAppRoles = interf.DestinationAppRoles; + conn.DestinationAreas = interf.DestinationAreas; + conn.DestinationOtherGroups = interf.DestinationOtherGroups; + } + conn.Services = interf.Services; + conn.ServiceGroups = interf.ServiceGroups; + conn.ExtraConfigsFromInterface = interf.ExtraConfigs; + return interf.Name ?? ""; + } + + protected static bool EvaluateInterfaceNoPermission(ModellingConnection interf, int ownerId) + { + return interf.InterfacePermission switch + { + nameof(InterfacePermissions.Private) => interf.AppId != ownerId, + nameof(InterfacePermissions.Public) => false, + _ => !interf.PermittedOwnerWrappers.Any(w => w.Owner != null && w.Owner.Id == ownerId), + }; + } + + private static void SetRelevantProps(ModellingConnection conn, ModellingConnection interf) + { + if (interf.GetBoolProperty(ConState.Rejected.ToString())) + { + conn.AddProperty(ConState.InterfaceRejected.ToString()); + } + else if (conn.InterfaceIsRequested) + { + conn.AddProperty(ConState.InterfaceRequested.ToString()); + } + else if (conn.InterfaceIsDecommissioned) + { + conn.AddProperty(ConState.InterfaceDecommissioned.ToString()); + } + else if (conn.InterfaceNoPermission) + { + conn.AddProperty(ConState.InterfaceNoPermission.ToString()); + } + } + + public async Task GetUsedInterface(ModellingConnection conn) + { + try + { + if (conn.UsedInterfaceId != null) + { + List interf = await apiConnection.SendQueryAsync>(ModellingQueries.getConnectionById, new { id = conn.UsedInterfaceId }); + if (interf.Count > 0) + { + return interf[0]; + } + } + } + catch (Exception exception) + { + DisplayMessageInUi(exception, userConfig.GetText("fetch_data"), "", true); + } + return null; + } + + protected async Task InitUsingConnections(int connId) + { + try + { + UsingConnections = await apiConnection.SendQueryAsync>(ModellingQueries.getInterfaceUsers, new { id = connId }); + return UsingConnections.Count > 0; + } + catch (Exception exception) + { + DisplayMessageInUi(exception, userConfig.GetText("is_in_use"), "", true); + return true; + } + } + + protected async Task CheckAppServerInUse(ModellingAppServer appServer) + { + try + { + List foundAppRoles = await apiConnection.SendQueryAsync>(ModellingQueries.getAppRolesForAppServer, new { id = appServer.Id }); + if (foundAppRoles.Count == 0) + { + List foundConnections = await apiConnection.SendQueryAsync>(ModellingQueries.getConnectionIdsForAppServer, new { id = appServer.Id }); + if (foundConnections.Count == 0) + { + return false; + } + } + return true; + } + catch (Exception exception) + { + DisplayMessageInUi(exception, userConfig.GetText("is_in_use"), "", true); + return true; + } + } + + public static List GetSrcNames(ModellingConnection conn, UserConfig userConfig) + { + if ((conn.InterfaceIsRequested && conn.SrcFromInterface) || (conn.IsRequested && conn.SourceFilled())) + { + return [DisplayReqInt(userConfig, conn.TicketId, conn.InterfaceIsRequested, + conn.GetBoolProperty(ConState.Rejected.ToString()) || conn.GetBoolProperty(ConState.InterfaceRejected.ToString()))]; + } + + List areas = [.. ModellingNetworkAreaWrapper.Resolve(conn.SourceAreas)]; + foreach (var area in areas) + { + area.TooltipText = userConfig.GetText(DeactMsg); + } + List names = areas.ConvertAll(s => s.DisplayWithIcon(conn.SrcFromInterface, conn.InterfaceIsDecommissioned)); + + List nwGroups = [.. ModellingNwGroupWrapper.Resolve(conn.SourceOtherGroups)]; + foreach (var nwGroup in nwGroups) + { + nwGroup.TooltipText = userConfig.GetText(DeactMsg); + } + names.AddRange(nwGroups.ConvertAll(s => s.DisplayWithIcon(conn.SrcFromInterface, conn.InterfaceIsDecommissioned))); + + foreach (ModellingAppRole appRole in ModellingAppRoleWrapper.Resolve(conn.SourceAppRoles)) + { + if (appRole.AppServers.Count > 0 && !appRole.AppServers.Any(_ => _.Content.IsDeleted)) + { + names.Add(appRole.DisplayWithIcon(conn.SrcFromInterface, conn.InterfaceIsDecommissioned)); + } + else + { + names.Add(appRole.DisplayProblematicWithIcon(conn.SrcFromInterface, conn.InterfaceIsDecommissioned)); + } + } + + List appServers = [.. ModellingAppServerWrapper.Resolve(conn.SourceAppServers)]; + foreach (var appServer in appServers) + { + appServer.TooltipText = userConfig.GetText(DeactMsg); + } + names.AddRange(appServers.ConvertAll(s => s.DisplayWithIcon(conn.SrcFromInterface, conn.InterfaceIsDecommissioned))); + return names; + } + + public static List GetDstNames(ModellingConnection conn, UserConfig userConfig) + { + if ((conn.InterfaceIsRequested && conn.DstFromInterface) || (conn.IsRequested && conn.DestinationFilled())) + { + return [DisplayReqInt(userConfig, conn.TicketId, conn.InterfaceIsRequested, + conn.GetBoolProperty(ConState.Rejected.ToString()) || conn.GetBoolProperty(ConState.InterfaceRejected.ToString()))]; + } + + List areas = [.. ModellingNetworkAreaWrapper.Resolve(conn.DestinationAreas)]; + foreach (var area in areas) + { + area.TooltipText = userConfig.GetText(DeactMsg); + } + List names = areas.ConvertAll(s => s.DisplayWithIcon(conn.DstFromInterface, conn.InterfaceIsDecommissioned)); + + List nwGroups = [.. ModellingNwGroupWrapper.Resolve(conn.DestinationOtherGroups)]; + foreach (var nwGroup in nwGroups) + { + nwGroup.TooltipText = userConfig.GetText(DeactMsg); + } + names.AddRange(nwGroups.ConvertAll(s => s.DisplayWithIcon(conn.DstFromInterface, conn.InterfaceIsDecommissioned))); + + foreach (ModellingAppRole appRole in ModellingAppRoleWrapper.Resolve(conn.DestinationAppRoles)) + { + if (appRole.AppServers.Count > 0 && !appRole.AppServers.Any(_ => _.Content.IsDeleted)) + { + names.Add(appRole.DisplayWithIcon(conn.DstFromInterface, conn.InterfaceIsDecommissioned)); + } + else + { + names.Add(appRole.DisplayProblematicWithIcon(conn.DstFromInterface, conn.InterfaceIsDecommissioned)); + } + } + + List appServers = [.. ModellingAppServerWrapper.Resolve(conn.DestinationAppServers)]; + foreach (var appServer in appServers) + { + appServer.TooltipText = userConfig.GetText(DeactMsg); + } + names.AddRange(appServers.ConvertAll(s => s.DisplayWithIcon(conn.DstFromInterface, conn.InterfaceIsDecommissioned))); + return names; + } + + public static List GetSvcNames(ModellingConnection conn, UserConfig userConfig) + { + if (conn.InterfaceIsRequested || conn.IsRequested) + { + return [DisplayReqInt(userConfig, conn.TicketId, conn.InterfaceIsRequested, + conn.GetBoolProperty(ConState.Rejected.ToString()) || conn.GetBoolProperty(ConState.InterfaceRejected.ToString()))]; + } + + List names = []; + + foreach (ModellingServiceGroup svcGrp in ModellingServiceGroupWrapper.Resolve(conn.ServiceGroups)) + { + if (svcGrp.Services.Count > 0) + { + names.Add(svcGrp.DisplayWithIcon(conn.UsedInterfaceId != null, conn.InterfaceIsDecommissioned)); + } + else + { + names.Add(svcGrp.DisplayProblematicWithIcon(conn.UsedInterfaceId != null, conn.InterfaceIsDecommissioned)); + } + } + + names.AddRange(ModellingServiceWrapper.Resolve(conn.Services).ToList().ConvertAll(s => s.DisplayWithIcon(conn.UsedInterfaceId != null, conn.InterfaceIsDecommissioned))); + + return names; + } + + public static async Task> GetOwnApps(Task authenticationStateTask, UserConfig userConfig, + ApiConnection apiConnection, Action DisplayMessageInUi, bool withConn = false) + { + List apps = []; + try + { + if (authenticationStateTask!.Result.User.IsInRole(Roles.Admin) + || authenticationStateTask!.Result.User.IsInRole(Roles.Auditor) + || authenticationStateTask!.Result.User.IsInRole(Roles.ReporterViewAll)) + { + apps = await apiConnection.SendQueryAsync>(OwnerQueries.getOwnersWithConn); + } + else + { + string? username = authenticationStateTask.Result.User.Identity?.Name; + bool usedClaimFallback = false; + // Prefer ownerships already prepared during login; only fall back to claim parsing if needed. + if (userConfig.User.Ownerships.Count == 0) + { + usedClaimFallback = true; + UpdateOwnerships(authenticationStateTask, userConfig); + if (userConfig.User.Ownerships.Count == 0) + { + // Mitigate timing issues where user config hydration lags behind page initialization. + await Task.Delay(100); + UpdateOwnerships(authenticationStateTask, userConfig); + } + } + Log.WriteDebug("GetOwnApps", $"User={username ?? "unknown"}, usedClaimFallback={usedClaimFallback}, ownershipCount={userConfig.User.Ownerships.Count}, withConn={withConn}"); + + string query = withConn ? OwnerQueries.getEditableOwnersWithConn : OwnerQueries.getEditableOwners; + apps = await apiConnection.SendQueryAsync>(query, new { appIds = userConfig.User.Ownerships.ToArray() }); + Log.WriteDebug("GetOwnApps", $"User={username ?? "unknown"}, editableAppsCount={apps.Count}, withConn={withConn}"); + } + } + catch (Exception exception) + { + DisplayMessageInUi(exception, userConfig.GetText("fetch_data"), "", true); + } + return apps; + } + + private static void UpdateOwnerships(Task authenticationStateTask, UserConfig userConfig) + { + List claims = authenticationStateTask.Result.User.Claims.ToList(); + userConfig.User.Ownerships = JwtClaimParser.ExtractIntClaimValues(claims, "x-hasura-editable-owners"); + } + } +} diff --git a/roles/lib/files/FWO.Services/Modelling/ModellingServiceGroupHandler.cs b/roles/lib/files/FWO.Services/Modelling/ModellingServiceGroupHandler.cs new file mode 100644 index 0000000000..ec80242057 --- /dev/null +++ b/roles/lib/files/FWO.Services/Modelling/ModellingServiceGroupHandler.cs @@ -0,0 +1,247 @@ +using FWO.Config.Api; +using FWO.Data; +using FWO.Data.Modelling; +using FWO.Api.Client; +using FWO.Api.Client.Queries; + + +namespace FWO.Services.Modelling +{ + public class ModellingServiceGroupHandler : ModellingHandlerBase + { + public List ServiceGroups { get; set; } = new(); + public ModellingServiceGroup ActServiceGroup { get; set; } = new(); + public ModellingServiceHandler? ServiceHandler; + public List SvcToDelete { get; set; } = new(); + public bool AddServiceMode = false; + public bool EditServiceMode = false; + public bool DeleteServiceMode = false; + public Func RefreshParent = DefaultInit.DoNothing; + + + public ModellingServiceGroupHandler(ApiConnection apiConnection, UserConfig userConfig, FwoOwner application, + List serviceGroups, ModellingServiceGroup serviceGroup, List availableServices, + List> availableSvcElems, bool addMode, Action displayMessageInUi, + Func refreshParent, bool isOwner = true, bool readOnly = false) + : base(apiConnection, userConfig, application, addMode, displayMessageInUi, readOnly, isOwner) + { + ServiceGroups = serviceGroups; + ActServiceGroup = serviceGroup; + ActServiceGroup.AppId = application.Id; + AvailableServices = availableServices; + AvailableSvcElems = availableSvcElems; + RefreshParent = refreshParent; + } + + public void ServicesToSvcGroup(List services) + { + foreach (var svc in services) + { + if (ActServiceGroup.Services.FirstOrDefault(w => w.Content.Id == svc.Id) == null && !SvcToAdd.Contains(svc)) + { + SvcToAdd.Add(svc); + } + } + } + + public async Task RefreshActServiceGroup() + { + try + { + if (ActServiceGroup.Id > 0) + { + ActServiceGroup = await apiConnection.SendQueryAsync(ModellingQueries.getServiceGroupById, new { id = ActServiceGroup.Id }); + } + await RefreshParent(); + } + catch (Exception exception) + { + DisplayMessageInUi(exception, userConfig.GetText("fetch_data"), "", true); + } + } + + public void CreateService() + { + AddServiceMode = true; + HandleService(new ModellingService() { }); + } + + public void EditService(ModellingService service) + { + AddServiceMode = false; + HandleService(service); + } + + private void HandleService(ModellingService service) + { + try + { + service.IsGlobal = ActServiceGroup.IsGlobal; + ServiceHandler = new ModellingServiceHandler(apiConnection, userConfig, Application, service, + AvailableServices, AvailableSvcElems, AddServiceMode, DisplayMessageInUi, IsOwner); + EditServiceMode = true; + } + catch (Exception exception) + { + DisplayMessageInUi(exception, userConfig.GetText("edit_service"), "", true); + } + } + + public async Task RequestDeleteService(ModellingService service) + { + await RequestDeleteServiceBase(service); + DeleteServiceMode = true; + } + + public async Task DeleteService() + { + try + { + DeleteServiceMode = await DeleteService(AvailableServices); + } + catch (Exception exception) + { + DisplayMessageInUi(exception, userConfig.GetText("delete_service"), "", true); + } + } + + public async Task Save() + { + try + { + if (ActServiceGroup.Sanitize()) + { + DisplayMessageInUi(null, userConfig.GetText("save_service_group"), userConfig.GetText("U0001"), true); + } + if (CheckServiceGroup()) + { + foreach (var svc in SvcToDelete) + { + ActServiceGroup.Services.Remove(ActServiceGroup.Services.FirstOrDefault(x => x.Content.Id == svc.Id) ?? throw new KeyNotFoundException("Did not find app service.")); + } + foreach (var svc in SvcToAdd) + { + ActServiceGroup.Services.Add(new ModellingServiceWrapper() { Content = svc }); + } + if (AddMode) + { + await AddServiceGroupToDb(); + } + else + { + await UpdateServiceGroupInDb(); + await RefreshParent(); + } + Close(); + return true; + } + } + catch (Exception exception) + { + DisplayMessageInUi(exception, userConfig.GetText("edit_service_group"), "", true); + } + return false; + } + + private bool CheckServiceGroup() + { + if (ActServiceGroup.Name == null || ActServiceGroup.Name == "") + { + DisplayMessageInUi(null, userConfig.GetText("edit_service_group"), userConfig.GetText("E5102"), true); + return false; + } + return true; + } + + private async Task AddServiceGroupToDb() + { + try + { + int? applicationId = ActServiceGroup.IsGlobal ? null : Application.Id; + var svcGrpParams = new + { + name = ActServiceGroup.Name, + appId = applicationId, + comment = ActServiceGroup.Comment, + isGlobal = ActServiceGroup.IsGlobal, + creator = userConfig.User.Name + }; + ReturnId[]? returnIds = (await apiConnection.SendQueryAsync(ModellingQueries.newServiceGroup, svcGrpParams)).ReturnIds; + if (returnIds != null) + { + ActServiceGroup.Id = returnIds[0].NewId; + await LogChange(ModellingTypes.ChangeType.Insert, ModellingTypes.ModObjectType.ServiceGroup, ActServiceGroup.Id, + $"New Service Group: {ActServiceGroup.Display()}", Application.Id); + foreach (var service in ActServiceGroup.Services) + { + var svcParams = new + { + serviceId = service.Content.Id, + serviceGroupId = ActServiceGroup.Id + }; + await apiConnection.SendQueryAsync(ModellingQueries.addServiceToServiceGroup, svcParams); + await LogChange(ModellingTypes.ChangeType.Assign, ModellingTypes.ModObjectType.ServiceGroup, ActServiceGroup.Id, + $"Added Service {service.Content.Display()} to Service Group: {ActServiceGroup.Display()}", Application.Id); + } + ActServiceGroup.Creator = userConfig.User.Name; + ActServiceGroup.CreationDate = DateTime.Now; + ServiceGroups.Add(ActServiceGroup); + AvailableSvcElems.Add(new KeyValuePair((int)ModellingTypes.ModObjectType.ServiceGroup, ActServiceGroup.Id)); + } + } + catch (Exception exception) + { + DisplayMessageInUi(exception, userConfig.GetText("add_service_group"), "", true); + } + } + + private async Task UpdateServiceGroupInDb() + { + try + { + var svcGrpParams = new + { + id = ActServiceGroup.Id, + name = ActServiceGroup.Name, + comment = ActServiceGroup.Comment, + }; + await apiConnection.SendQueryAsync(ModellingQueries.updateServiceGroup, svcGrpParams); + await LogChange(ModellingTypes.ChangeType.Update, ModellingTypes.ModObjectType.ServiceGroup, ActServiceGroup.Id, + $"Updated Service Group: {ActServiceGroup.Display()}", Application.Id); + foreach (var service in SvcToDelete) + { + var svcParams = new + { + serviceId = service.Id, + serviceGroupId = ActServiceGroup.Id + }; + await apiConnection.SendQueryAsync(ModellingQueries.removeServiceFromServiceGroup, svcParams); + await LogChange(ModellingTypes.ChangeType.Unassign, ModellingTypes.ModObjectType.ServiceGroup, ActServiceGroup.Id, + $"Removed Service {service.Display()} from Service Group: {ActServiceGroup.Display()}", Application.Id); + } + foreach (var service in SvcToAdd) + { + var svcParams = new + { + serviceId = service.Id, + serviceGroupId = ActServiceGroup.Id + }; + await apiConnection.SendQueryAsync(ModellingQueries.addServiceToServiceGroup, svcParams); + await LogChange(ModellingTypes.ChangeType.Assign, ModellingTypes.ModObjectType.ServiceGroup, ActServiceGroup.Id, + $"Added Service {service.Display()} to Service Group: {ActServiceGroup.Display()}", Application.Id); + } + } + catch (Exception exception) + { + DisplayMessageInUi(exception, userConfig.GetText("edit_service_group"), "", true); + } + } + + public void Close() + { + DeleteServiceMode = false; + SvcToAdd = new List(); + SvcToDelete = new List(); + } + } +} diff --git a/roles/lib/files/FWO.Services/Modelling/ModellingServiceHandler.cs b/roles/lib/files/FWO.Services/Modelling/ModellingServiceHandler.cs new file mode 100644 index 0000000000..64dfe6b161 --- /dev/null +++ b/roles/lib/files/FWO.Services/Modelling/ModellingServiceHandler.cs @@ -0,0 +1,153 @@ +using FWO.Config.Api; +using FWO.Data; +using FWO.Data.Modelling; +using FWO.Api.Client; +using FWO.Api.Client.Queries; +using FWO.Basics; + + +namespace FWO.Services.Modelling +{ + public class ModellingServiceHandler : ModellingHandlerBase + { + public ModellingService ActService { get; set; } + private ModellingService ActServiceOrig { get; set; } + private static readonly string EditService = "edit_service"; + + + public ModellingServiceHandler(ApiConnection apiConnection, UserConfig userConfig, FwoOwner application, + ModellingService service, List availableServices, List> availableSvcElems, bool addMode, Action displayMessageInUi, bool isOwner = true) + : base(apiConnection, userConfig, application, addMode, displayMessageInUi, false, isOwner) + { + ActService = service; + AvailableServices = availableServices; + AvailableSvcElems = availableSvcElems; + ActServiceOrig = new ModellingService(ActService); + } + + public async Task Save() + { + try + { + if (ActService.Sanitize()) + { + DisplayMessageInUi(null, userConfig.GetText("save_service"), userConfig.GetText("U0001"), true); + } + if (CheckService()) + { + if (AddMode) + { + await AddServiceToDb(); + } + else + { + await UpdateServiceInDb(); + } + ActServiceOrig = new ModellingService(ActService); + return true; + } + } + catch (Exception exception) + { + DisplayMessageInUi(exception, userConfig.GetText(EditService), "", true); + } + return false; + } + + public void Reset() + { + ActService = new(ActServiceOrig); + if (!AddMode) + { + AvailableServices[AvailableServices.FindIndex(x => x.Id == ActService.Id)] = ActService; + } + } + + private bool CheckService() + { + if (ActService.Protocol == null || ActService.Protocol.Id == 0) + { + DisplayMessageInUi(null, userConfig.GetText(EditService), userConfig.GetText("E5102"), true); + return false; + } + if (ActService.PortEnd == null) + { + ActService.PortEnd = ActService.Port; + } + if (!ActService.Protocol.HasPorts()) + { + ActService.Port = null; + ActService.PortEnd = null; + } + else if (ActService.Port == null) + { + DisplayMessageInUi(null, userConfig.GetText(EditService), userConfig.GetText("E5102"), true); + return false; + } + if (ActService.Port < 1 || ActService.Port > GlobalConst.kMaxPortNumber || + (ActService.PortEnd != null && (ActService.PortEnd < 1 || ActService.PortEnd > GlobalConst.kMaxPortNumber))) + { + DisplayMessageInUi(null, userConfig.GetText(EditService), userConfig.GetText("E5103"), true); + return false; + } + if (ActService.PortEnd != null && (ActService.PortEnd < ActService.Port)) + { + DisplayMessageInUi(null, userConfig.GetText(EditService), userConfig.GetText("E5118"), true); + return false; + } + return true; + } + + private async Task AddServiceToDb() + { + try + { + int? applicationId = ActService.IsGlobal ? null : Application.Id; + var Variables = new + { + name = ActService.Name, + appId = applicationId, + isGlobal = ActService.IsGlobal, + port = ActService.Port, + portEnd = ActService.PortEnd, + protoId = ActService.Protocol?.Id + }; + ReturnId[]? returnIds = (await apiConnection.SendQueryAsync(ModellingQueries.newService, Variables)).ReturnIds; + if (returnIds != null) + { + ActService.Id = returnIds[0].NewId; + await LogChange(ModellingTypes.ChangeType.Insert, ModellingTypes.ModObjectType.Service, ActService.Id, + $"New Service: {ActService.Display()}", Application.Id); + AvailableServices.Add(ActService); + AvailableSvcElems.Add(new KeyValuePair((int)ModellingTypes.ModObjectType.Service, ActService.Id)); + } + } + catch (Exception exception) + { + DisplayMessageInUi(exception, userConfig.GetText("add_service"), "", true); + } + } + + private async Task UpdateServiceInDb() + { + try + { + var Variables = new + { + id = ActService.Id, + name = ActService.Name, + port = ActService.Port, + portEnd = ActService.PortEnd, + protoId = ActService.Protocol?.Id + }; + await apiConnection.SendQueryAsync(ModellingQueries.updateService, Variables); + await LogChange(ModellingTypes.ChangeType.Update, ModellingTypes.ModObjectType.Service, ActService.Id, + $"Updated Service: {ActService.Display()}", Application.Id); + } + catch (Exception exception) + { + DisplayMessageInUi(exception, userConfig.GetText(EditService), "", true); + } + } + } +} diff --git a/roles/lib/files/FWO.Services/Modelling/ModellingVarianceAnalysis.cs b/roles/lib/files/FWO.Services/Modelling/ModellingVarianceAnalysis.cs new file mode 100644 index 0000000000..e4faa7c1e9 --- /dev/null +++ b/roles/lib/files/FWO.Services/Modelling/ModellingVarianceAnalysis.cs @@ -0,0 +1,354 @@ +using FWO.Api.Client; +using FWO.Api.Client.Queries; +using FWO.Config.Api; +using FWO.Data; +using FWO.Data.Modelling; +using FWO.Data.Report; +using FWO.Data.Workflow; +using FWO.Logging; +using FWO.Services.Workflow; +using System.Text.Json; + + +namespace FWO.Services.Modelling +{ + /// + /// Variance Analysis Class + /// + public partial class ModellingVarianceAnalysis(ApiConnection apiConnection, ExtStateHandler extStateHandler, + UserConfig userConfig, FwoOwner owner, Action displayMessageInUi) + { + private readonly ModellingNamingConvention namingConvention = JsonSerializer.Deserialize(userConfig.ModNamingConvention) ?? new(); + private readonly RuleRecognitionOption ruleRecognitionOption = string.IsNullOrEmpty(userConfig.RuleRecognitionOption) ? new() : + JsonSerializer.Deserialize(userConfig.RuleRecognitionOption) ?? new(); + private readonly ModellingAppZoneHandler AppZoneHandler = new(apiConnection, userConfig, owner, displayMessageInUi); + private AppServerComparer appServerComparer = new(new()); + private List RelevantManagements { get; set; } = []; + + private List TaskList = []; + private List AddAccessTaskList = []; + private List ChangeAccessTaskList = []; + private List DeleteAccessTaskList = []; + private List DeleteObjectTasksList = []; + private int taskNumber = 0; + private List ReqElements = []; + + private ModellingVarianceResult varianceResult = new(); + + private Dictionary> allModelledRules = []; + private List allModelledAppRoles = []; + + private readonly Dictionary> allProdAppRoles = []; + private readonly Dictionary> allExistingAppServersHashes = []; + private readonly Dictionary> alreadyCreatedAppServers = []; + private List DeletedConns = []; + private List AllAreas = []; + + private readonly Dictionary> DeviceRules = []; + + public ModellingAppZone? PlannedAppZoneDbUpdate { get; set; } = default; + + public async Task AnalyseConnsForStatus(List connections) + { + connections = [.. connections.Where(x => !x.IsDocumentationOnly())]; + varianceResult = await AnalyseRulesVsModelledConnections(connections, new(), false); + await GetNwObjectsProductionState(); + foreach (var conn in connections) + { + conn.AddProperty(ConState.VarianceChecked.ToString()); + conn.UpdateProperty(ConState.ForeignNonProdObjects.ToString(), HasForeignNonProdObjects(conn)); + if (varianceResult.ConnsNotImplemented.FirstOrDefault(c => c.Id == conn.Id) != null) + { + conn.AddProperty(ConState.NotImplemented.ToString()); + } + else + { + conn.RemoveProperty(ConState.NotImplemented.ToString()); + } + if (varianceResult.RuleDifferences.FirstOrDefault(c => c.ModelledConnection.Id == conn.Id) != null) + { + conn.AddProperty(ConState.VarianceFound.ToString()); + } + else + { + conn.RemoveProperty(ConState.VarianceFound.ToString()); + } + } + } + + private bool HasForeignNonProdObjects(ModellingConnection conn) + { + if (!userConfig.ModRequestOnlyOwnObjects || conn.IsInterface || conn.UsedInterfaceId == null) + { + return false; + } + + foreach (Management mgt in RelevantManagements) + { + if (HasForeignNonProdObjects(conn, mgt)) + { + return true; + } + } + return false; + } + + private bool HasForeignNonProdObjects(ModellingConnection conn, Management mgt) + { + List foreignAppRoles = + [ + .. ModellingAppRoleWrapper.Resolve(conn.SourceAppRoles).Where(ar => ar.AppId != owner.Id), + .. ModellingAppRoleWrapper.Resolve(conn.DestinationAppRoles).Where(ar => ar.AppId != owner.Id) + ]; + + foreach (ModellingAppRole foreignAppRole in foreignAppRoles) + { + if (ResolveProdAppRole(foreignAppRole, mgt) == null) + { + return true; + } + } + return false; + } + + public async Task AnalyseConnsForStatusAsync(List connections) + { + try + { + await AnalyseConnsForStatus(connections); + foreach (var conn in connections) + { + await UpdateConnectionStatus(conn); + } + } + catch (Exception exc) + { + Log.WriteError("Analyse Conns For Status Async", $" Error: ", exc); + return false; + } + return true; + } + + public async Task AnalyseRulesVsModelledConnections(List connections, + ModellingFilter modellingFilter, bool fullAnalysis = true, bool ignoreGroups = false) + { + await InitManagements(); + await LoadAreas(); + varianceResult = new() { Managements = RelevantManagements }; + if (ruleRecognitionOption.NwSeparateGroupAnalysis && fullAnalysis && !ignoreGroups) + { + await GetNwObjectsProductionState(); + PreAnalyseAllAppRoles(connections); + } + if (await GetModelledRulesProductionState(modellingFilter)) + { + foreach (var conn in connections.Where(c => !c.IsInterface).OrderBy(c => c.Id)) + { + AnalyseRules(conn, fullAnalysis); + } + if (modellingFilter.RulesForDeletedConns) + { + await GetRulesForDeletedConns([.. connections.Where(c => c.IsDocumentationOnly())]); + } + } + varianceResult.DeviceRules = DeviceRules; + return varianceResult; + } + + public async Task> AnalyseModelledConnectionsForRequest(List connections) + { + appServerComparer = new(namingConvention); + await InitManagements(); + await LoadAreas(); + await GetModelledRulesProductionState(new() { AnalyseRemainingRules = false }); + await GetNwObjectsProductionState(); + await GetDeletedConnections(); + + TaskList = []; + AddAccessTaskList = []; + ChangeAccessTaskList = []; + DeleteAccessTaskList = []; + DeleteObjectTasksList = []; + foreach (Management mgt in RelevantManagements) + { + await AnalyseAppZoneForRequest(mgt); + foreach (var conn in connections.Where(c => !c.IsRequested && !c.IsDocumentationOnly()).OrderBy(c => c.Id)) + { + ReqElements = []; + AnalyseNetworkAreasForRequest(conn); + AnalyseAppRolesForRequest(conn, mgt); + AnalyseAppServersForRequest(conn); + AnalyseServiceGroupsForRequest(conn, mgt); + AnalyseServicesForRequest(conn); + if (!conn.IsInterface && ReqElements.Count > 0) // NOSONAR: populated via side effects in Analyse*ForRequest methods + { + AnalyseConnectionForRequest(mgt, conn); + } + } + AnalyseDeletedConnsForRequest(mgt, [.. connections.Where(c => c.IsDocumentationOnly())]); + } + TaskList.AddRange(AddAccessTaskList); + TaskList.AddRange(ChangeAccessTaskList); + TaskList.AddRange(DeleteAccessTaskList); + TaskList.AddRange(DeleteObjectTasksList); + taskNumber = 1; + foreach (WfReqTask task in TaskList) + { + task.TaskNumber = taskNumber++; + task.Owners = [new() { Owner = owner }]; + task.StateId = extStateHandler.GetInternalStateId(ExtStates.ExtReqInitialized) ?? 0; + } + return TaskList; + } + + public async Task GetSuccessfulRequestState() + { + try + { + List ticketIds = await apiConnection.SendQueryAsync>(ExtRequestQueries.getLatestTicketIds, new { ownerId = owner.Id }); + if (ticketIds.Count == 0) + { + return userConfig.GetText("never_requested"); + } + else + { + foreach (var ticketId in ticketIds) + { + WfTicket? intTicket = await apiConnection.SendQueryAsync(RequestQueries.getTicketById, new { ticketId.Id }); + if (extStateHandler.IsDone(intTicket.StateId)) + { + return $"{userConfig.GetText("last_successful")}: {intTicket.CreationDate.ToString("yyyy-MM-dd HH:mm:ss")}, {userConfig.GetText("implemented")}: {intTicket.CompletionDate?.ToString("yyyy-MM-dd HH:mm:ss")}, {intTicket.Requester?.Name}"; + } + } + return userConfig.GetText("never_succ_req"); + } + } + catch (Exception exception) + { + Log.WriteError(userConfig.GetText("impl_state"), exception.Message); + } + return ""; + } + + public async Task<(bool, List)> CheckExistingAppZone() + { + List MgtsWithVariance = []; + ModellingAppZone? modelledAppZone = await AppZoneHandler.GetExistingModelledAppZone(); + if (modelledAppZone != null) + { + AppZoneComparer appZoneComparer = new(namingConvention); + foreach (var mgt in RelevantManagements) + { + await CollectGroupObjects(mgt.Id); + ModellingAppRole? prodAppRole = ResolveProdAppRole(modelledAppZone, mgt); + if (prodAppRole == null) + { + MgtsWithVariance.Add(new() { ManagementName = mgt.Name }); + } + else + { + ModellingAppZone prodAppZone = new(prodAppRole); + if (!appZoneComparer.Equals(prodAppZone, modelledAppZone)) + { + prodAppZone.ManagementName = mgt.Name; + MgtsWithVariance.Add(prodAppZone); + } + } + } + return (true, MgtsWithVariance); + } + return (false, []); + } + + private void PreAnalyseAllAppRoles(List connections) + { + CollectModelledAppRoles(connections); + foreach (Management mgt in RelevantManagements) + { + varianceResult.MissingAppRoles.Add(mgt.Id, []); + varianceResult.DifferingAppRoles.Add(mgt.Id, []); + foreach (var modelledAppRole in allModelledAppRoles) + { + AnalyseAppRole(modelledAppRole, mgt); + } + } + varianceResult.AppRoleStats.ModelledAppRolesCount = allModelledAppRoles.Count; + varianceResult.AppRoleStats.AppRolesOk = allModelledAppRoles.Count(a => !a.IsMissing && !a.HasDifference); + varianceResult.AppRoleStats.AppRolesMissingCount = allModelledAppRoles.Count(a => a.IsMissing); + varianceResult.AppRoleStats.AppRolesDifferenceCount = allModelledAppRoles.Count(a => a.HasDifference); + } + + private void CollectModelledAppRoles(List connections) + { + AppRoleComparer appRoleComparer = new(); + foreach (var conn in connections.Where(c => !c.IsInterface).OrderBy(c => c.Id)) + { + foreach (var modelledAppRole in ModellingAppRoleWrapper.Resolve(conn.SourceAppRoles)) + { + allModelledAppRoles.Add(modelledAppRole); + } + foreach (var modelledAppRole in ModellingAppRoleWrapper.Resolve(conn.DestinationAppRoles)) + { + allModelledAppRoles.Add(modelledAppRole); + } + } + allModelledAppRoles = [.. allModelledAppRoles.Distinct(appRoleComparer).OrderBy(a => a.Id)]; + } + + private void AnalyseAppRole(ModellingAppRole modelledAppRole, Management mgt) + { + if (ResolveProdAppRole(modelledAppRole, mgt) == null) + { + modelledAppRole.IsMissing = true; + varianceResult.MissingAppRoles[mgt.Id].Add(new(modelledAppRole) { ManagementName = mgt.Name }); + } + else if (AppRoleChanged(modelledAppRole)) + { + modelledAppRole.HasDifference = true; + ModellingAppRole changedAppRole = new(modelledAppRole) { ManagementName = mgt.Name, SurplusAppServers = deletedAppServers }; + foreach (var appServer in changedAppRole.AppServers.Select(a => a.Content)) + { + appServer.NotImplemented = newAppServers.FirstOrDefault(a => appServerComparer.Equals(a.Content, appServer)) != null; + } + varianceResult.DifferingAppRoles[mgt.Id].Add(changedAppRole); + } + } + + private string ConstructComment(ModellingConnection conn) + { + string comment = userConfig.ModModelledMarker + conn.Id.ToString(); + if (conn.IsCommonService) + { + comment += ", ComSvc"; + } + if (conn.ExtraConfigs.Count > 0 || conn.ExtraConfigsFromInterface.Count > 0) + { + comment += ", " + userConfig.GetText("impl_instructions") + ": " + + string.Join(", ", conn.ExtraConfigs.ConvertAll(x => x.Display()).Concat(conn.ExtraConfigsFromInterface.ConvertAll(x => x.Display()))); + } + return comment; + } + + private async Task UpdateConnectionStatus(ModellingConnection conn) + { + try + { + var Variables = new + { + id = conn.Id, + connProp = conn.Properties + }; + await apiConnection.SendQueryAsync(ModellingQueries.updateConnectionProperties, Variables); + } + catch (Exception exc) + { + Log.WriteError("Update Connection Properties", $"Could not change state for Connection {conn.Id}: ", exc); + } + } + + private async Task LoadAreas() + { + AllAreas = await apiConnection.SendQueryAsync>(ModellingQueries.getNwGroupObjects, new { grpType = (int)ModellingTypes.ModObjectType.NetworkArea }); + } + } +} diff --git a/roles/lib/files/FWO.Services/Modelling/ModellingVarianceAnalysisGetProd.cs b/roles/lib/files/FWO.Services/Modelling/ModellingVarianceAnalysisGetProd.cs new file mode 100644 index 0000000000..9a815a6b8f --- /dev/null +++ b/roles/lib/files/FWO.Services/Modelling/ModellingVarianceAnalysisGetProd.cs @@ -0,0 +1,290 @@ +using FWO.Api.Client.Queries; +using FWO.Basics; +using FWO.Data; +using FWO.Data.Modelling; +using FWO.Data.Report; +using FWO.Logging; +using System.Text.Json; +using System.Text.RegularExpressions; + +namespace FWO.Services.Modelling +{ + /// + /// Part of Variance Analysis Class getting the production state + /// + public partial class ModellingVarianceAnalysis + { + private async Task InitManagements() + { + try + { + List managements = await apiConnection.SendQueryAsync>(DeviceQueries.getManagementNames); + managements = [.. managements.Where(m => !string.IsNullOrEmpty(m.ExtMgtData))]; + RelevantManagements = []; + foreach (Management mgt in managements) + { + ExtMgtData extMgtData = JsonSerializer.Deserialize(mgt.ExtMgtData ?? ""); + if (!string.IsNullOrEmpty(extMgtData.ExtId) || !string.IsNullOrEmpty(extMgtData.ExtName)) + { + RelevantManagements.Add(mgt); + if (!alreadyCreatedAppServers.ContainsKey(mgt.Id)) + { + alreadyCreatedAppServers.Add(mgt.Id, []); + } + } + } + } + catch (Exception exception) + { + Log.WriteError(userConfig.GetText("managements"), "Init Managements leads to error: ", exception); + } + } + + private async Task GetModelledRulesProductionState(ModellingFilter modellingFilter) + { + try + { + int modelledRulesCount = 0; + int notModelledRulesCount = 0; + allModelledRules = []; + + foreach (Management mgt in RelevantManagements) + { + varianceResult.UnModelledRules.Add(mgt.Id, []); + List? rulesByMgt = await GetRules(mgt.Id, modellingFilter); + if (rulesByMgt != null) + { + IdentifyModelledRules(mgt, rulesByMgt); + modelledRulesCount += allModelledRules[mgt.Id].Count; + notModelledRulesCount += varianceResult.UnModelledRules[mgt.Id].Count; + } + } + Log.WriteDebug("GetModelledRulesProductionState", $"Found {modelledRulesCount} modelled rules, {notModelledRulesCount} others."); + } + catch (Exception exception) + { + Log.WriteError(userConfig.GetText("load_rules"), "Get Production State leads to error: ", exception); + displayMessageInUi(exception, userConfig.GetText("load_rules"), "Get Production State leads to error: ", true); + return false; + } + return true; + } + + private void IdentifyModelledRules(Management mgt, List rulesByMgt) + { + allModelledRules.Add(mgt.Id, []); + foreach (var rule in rulesByMgt) + { + rule.ManagementName = mgt.Name; + string? connRef = FindModelledMarker(rule); + if (connRef != null) + { + if (long.TryParse(connRef, out long connId)) + { + rule.ConnId = connId; + } + allModelledRules[mgt.Id].Add(rule); + } + else + { + varianceResult.UnModelledRules[mgt.Id].Add(rule); + } + } + } + + private string? FindModelledMarker(Rule rule) + { + return userConfig.ModModelledMarkerLocation switch + { + MarkerLocation.Rulename => !string.IsNullOrEmpty(rule.Name) && rule.Name.Contains(userConfig.ModModelledMarker) ? ParseFromString(rule.Name) : null, + MarkerLocation.Comment => !string.IsNullOrEmpty(rule.Comment) && rule.Comment.Contains(userConfig.ModModelledMarker) ? ParseFromString(rule.Comment) : null, + MarkerLocation.Customfields => !string.IsNullOrEmpty(rule.CustomFields) ? GetFromCustomField(rule) : null, + _ => null, + }; + } + + [GeneratedRegex("[^0-9]")] + private static partial Regex NonNumericRegex(); + + private string? ParseFromString(string FieldString) + { + int idx = FieldString.IndexOf(userConfig.ModModelledMarker) + userConfig.ModModelledMarker.Length; + if (idx >= 0 && idx < FieldString.Length) + { + int? contentLength = NonNumericRegex().Match(FieldString[idx..]).Captures.FirstOrDefault()?.Index; + return contentLength != null && contentLength > 0 ? FieldString.Substring(idx, (int)contentLength) : FieldString.Substring(idx); + } + return null; + } + + private string? GetFromCustomField(Rule rule) + { + Dictionary? customFields = JsonSerializer.Deserialize>(rule.CustomFields); + return customFields != null && customFields.TryGetValue(userConfig.ModModelledMarker, out string? value) ? value : null; + } + + private async Task GetDeletedConnections() + { + try + { + DeletedConns = await apiConnection.SendQueryAsync>(ModellingQueries.getDeletedConnections, new { appId = owner.Id }); + } + catch (Exception exception) + { + Log.WriteError(userConfig.GetText("connections"), "Get deleted connections leads to error: ", exception); + displayMessageInUi(exception, userConfig.GetText("connections"), "Get deleted connections leads to error: ", true); + } + } + + private async Task?> GetRules(int mgtId, ModellingFilter modellingFilter) + { + long? relImpId = await GetRelevantImportId(mgtId); + await GetRuleDevices(mgtId, modellingFilter); + if (modellingFilter.AnalyseRemainingRules) + { + var RuleVariables = new + { + mgmId = mgtId, + import_id_start = relImpId, + import_id_end = relImpId + }; + return await apiConnection.SendQueryAsync>(RuleQueries.getRulesByManagement, RuleVariables); + } + else + { + var RuleVariables = new + { + mgmId = mgtId, + import_id_start = relImpId, + import_id_end = relImpId, + marker = $"%{userConfig.ModModelledMarker}%" + }; + + string query = userConfig.ModModelledMarkerLocation switch + { + MarkerLocation.Rulename => RuleQueries.getModelledRulesByManagementName, + MarkerLocation.Comment => RuleQueries.getModelledRulesByManagementComment, + _ => throw new NotSupportedException("invalid or undefined Marker Location") + }; + return await apiConnection.SendQueryAsync>(query, RuleVariables); + } + } + + private async Task GetRuleDevices(int mgtId, ModellingFilter modellingFilter) + { + if (modellingFilter.AnalyseRemainingRules || modellingFilter.RulesForDeletedConns) + { + DeviceRules[mgtId] = await apiConnection.SendQueryAsync>(DeviceQueries.getDevicesWithRulebaseLinks, new { mgmId = mgtId }); + } + } + + private async Task GetNwObjectsProductionState() + { + try + { + int aRCount = 0; + int aSCount = 0; + foreach (var mgtId in RelevantManagements.Select(m => m.Id)) + { + aRCount += await CollectGroupObjects(mgtId); + aSCount += await CollectAppServers(mgtId); + } + Log.WriteDebug("GetNwObjectsProductionState", $"Found {aRCount} AppRoles, {aSCount} AppServer."); + } + catch (Exception exception) + { + Log.WriteError(userConfig.GetText("network_objects"), "Get Production State leads to error: ", exception); + } + } + + private async Task CollectGroupObjects(int mgtId) + { + int aRCount = 0; + List? objGrpByMgt = await GetObjects(mgtId, [2]); + if (objGrpByMgt != null) + { + if (!allProdAppRoles.TryGetValue(mgtId, out List? aRList)) + { + aRList = []; + allProdAppRoles.Add(mgtId, aRList); + } + foreach (NetworkObject objGrp in objGrpByMgt) + { + aRList.Add(new(objGrp, namingConvention)); + aRCount++; + } + } + return aRCount; + } + + private async Task CollectAppServers(int mgtId) + { + int aSCount = 0; + List? objByMgt = await GetObjects(mgtId, [1, 3, 12]); + if (objByMgt != null) + { + if (!allExistingAppServersHashes.TryGetValue(mgtId, out Dictionary? appServerHashes)) + { + appServerHashes = []; + allExistingAppServersHashes.Add(mgtId, appServerHashes); + } + foreach (NetworkObject obj in objByMgt) + { + ModellingAppServer appServer = new(obj); + appServerHashes.TryAdd(appServerComparer.GetHashCode(appServer), appServer.Id); + aSCount++; + } + } + return aSCount; + } + + private async Task?> GetObjects(int mgtId, int[] objTypeIds) + { + try + { + long? relImpId = await GetRelevantImportId(mgtId); + if (relImpId != null) + { + var ObjGroupVariables = new + { + mgmId = mgtId, + objTypeIds = objTypeIds, + import_id_start = relImpId, + import_id_end = relImpId + }; + return await apiConnection.SendQueryAsync>(ObjectQueries.getNetworkObjectsForManagement, ObjGroupVariables); + } + } + catch (Exception exception) + { + Log.WriteError(userConfig.GetText("network_objects"), "Get Production Objects leads to error: ", exception); + } + return []; + } + + private async Task GetRelevantImportId(int mgtId) + { + try + { + var Variables = new + { + time = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"), + mgmIds = mgtId + }; + List managements = (await apiConnection.SendQueryAsync>(ReportQueries.getRelevantImportIdsAtTime, Variables))!; + if (managements.Count == 0) + { + Log.WriteError("GetRelevantImportId", $"No management data found for management ID {mgtId}."); + return null; + } + // we may get multiple results if this management is a submanagement of a multi device manager + return managements.Select(m => m.Import.ImportAggregate.ImportAggregateMax.RelevantImportId ?? -1).Max(); + } + catch (Exception exception) + { + Log.WriteError(userConfig.GetText("import_id"), "Get ImportIds leads to error: ", exception); + } + return null; + } + } +} diff --git a/roles/lib/files/FWO.Services/Modelling/ModellingVarianceAnalysisObjectsForRequest.cs b/roles/lib/files/FWO.Services/Modelling/ModellingVarianceAnalysisObjectsForRequest.cs new file mode 100644 index 0000000000..62612b8858 --- /dev/null +++ b/roles/lib/files/FWO.Services/Modelling/ModellingVarianceAnalysisObjectsForRequest.cs @@ -0,0 +1,595 @@ +using FWO.Basics; +using FWO.Data; +using FWO.Data.Modelling; +using FWO.Data.Workflow; +using FWO.Logging; +using System.Text.Json; + +namespace FWO.Services.Modelling +{ + /// + /// Part of Variance Analysis Class analysing the rules, network and service objects for request + /// + public partial class ModellingVarianceAnalysis + { + private ModellingAppRole? existingAppRole; + private List newAppServers = []; + private List deletedAppServers = []; + private List unchangedAppServers = []; + private List newGroupMembers = []; + private List newCreatedGroupMembers = []; + private List deletedGroupMembers = []; + private List unchangedGroupMembersDuringCreate = []; + private List unchangedGroupMembers = []; + + private void AnalyseConnectionForRequest(Management mgt, ModellingConnection conn) + { + varianceResult = new() { Managements = RelevantManagements }; + AnalyseRules(conn, false); + if (varianceResult.ConnsNotImplemented.Count > 0) + { + AddAccessTaskList.Add(ConstructCreateTask(mgt, conn)); + } + else if (varianceResult.RuleDifferences.Count > 0) + { + foreach (var rule in varianceResult.RuleDifferences[0].ImplementedRules.Where(r => r.MgmtId == mgt.Id)) + { + ChangeAccessTaskList.Add(ConstructRuleTask(mgt, rule, conn, false, ReqElements)); + } + } + } + + private void AnalyseDeletedConnsForRequest(Management mgt, List dokuOnlyConnections) + { + List RegardedAsDeletedConns = [.. DeletedConns, .. dokuOnlyConnections]; + List RegardedDeletedConnectionIds = RegardedAsDeletedConns.ConvertAll(c => c.Id); + foreach (var rule in allModelledRules[mgt.Id].Where(r => !r.ModellFound)) + { + if (int.TryParse(FindModelledMarker(rule), out int connId) && RegardedDeletedConnectionIds.Contains(connId)) + { + ModellingConnection deletedConn = RegardedAsDeletedConns.FirstOrDefault(c => c.Id == connId) ?? throw new KeyNotFoundException("Connection not found."); + DeleteAccessTaskList.Add(ConstructRuleTask(mgt, rule, deletedConn, true, GetElementsFromRule(rule, deletedConn))); + } + } + } + + private List GetElementsFromRule(Rule rule, ModellingConnection deletedConn) + { + List ruleElements = []; + Dictionary specialUserObjects = deletedConn.GetSpecialUserObjectNames(); + Dictionary updatableObjects = deletedConn.GetUpdatableObjectNames(); + if (specialUserObjects.Count > 0 || updatableObjects.Count > 0) + { + // Get from deleted conn as modelled objects are expected instead of specUser (Then deletion of links is suppressed in this case) + ruleElements.AddRange(GetNwObjElementsFromConn(deletedConn)); + } + foreach (var src in rule.Froms.Select(src => src.Object)) + { + ruleElements.Add(new() + { + RequestAction = RequestAction.unchanged.ToString(), + Field = ElemFieldType.source.ToString(), + Name = src.Name, + IpString = src.IP, + IpEnd = src.IpEnd, + GroupName = src.Type.Name == ObjectType.Group ? src.Name : null + }); + } + foreach (var dest in rule.Tos.Select(dest => dest.Object)) + { + ruleElements.Add(new() + { + RequestAction = RequestAction.unchanged.ToString(), + Field = ElemFieldType.destination.ToString(), + Name = dest.Name, + IpString = dest.IP, + IpEnd = dest.IpEnd, + GroupName = dest.Type.Name == ObjectType.Group ? dest.Name : null + }); + } + foreach (var svc in rule.Services.Select(svc => svc.Content)) + { + ruleElements.Add(new() + { + RequestAction = RequestAction.unchanged.ToString(), + Field = ElemFieldType.service.ToString(), + Name = svc.Name, + Port = svc.DestinationPort, + PortEnd = svc.DestinationPortEnd, + ProtoId = svc.ProtoId, + GroupName = svc.Type.Name == ServiceType.Group ? svc.Name : null + }); + } + return ruleElements; + } + + private List GetNwObjElementsFromConn(ModellingConnection deletedConn) + { + ReqElements = []; + AnalyseNetworkAreasForRequest(deletedConn, true); + foreach (ModellingAppRole srcAppRole in ModellingAppRoleWrapper.Resolve(deletedConn.SourceAppRoles)) + { + ReqElements.Add(new() + { + RequestAction = RequestAction.create.ToString(), + Field = ElemFieldType.modelled_source.ToString(), + GroupName = srcAppRole.IdString + }); + } + foreach (ModellingAppRole dstAppRole in ModellingAppRoleWrapper.Resolve(deletedConn.DestinationAppRoles)) + { + ReqElements.Add(new() + { + RequestAction = RequestAction.create.ToString(), + Field = ElemFieldType.modelled_destination.ToString(), + GroupName = dstAppRole.IdString + }); + } + AnalyseAppServersForRequest(deletedConn, true); + return ReqElements.ConvertAll(e => new WfReqElement(e) { RequestAction = RequestAction.unchanged.ToString() }); + } + + private WfReqTask ConstructCreateTask(Management mgt, ModellingConnection conn) + { + Dictionary? addInfo = new() { { AdditionalInfoKeys.ConnId, conn.Id.ToString() } }; + return new() + { + Title = ConstructCreateTaskTitle(conn), + TaskType = WfTaskType.access.ToString(), + ManagementId = mgt.Id, + OnManagement = mgt, + Elements = ReqElements, + RuleAction = 1, // Todo ?? + Tracking = 1, // Todo ?? + AdditionalInfo = JsonSerializer.Serialize(addInfo), + Comments = [new() { Comment = new() { CommentText = ConstructComment(conn) } }] + }; + } + + private string ConstructCreateTaskTitle(ModellingConnection conn) + { + string commentString = $" ({userConfig.ModModelledMarker + conn.Id.ToString()})"; + return (conn.IsCommonService ? userConfig.GetText("new_common_service") : userConfig.GetText("new_connection")) + ": " + (conn.Name ?? "") + commentString; + } + + private WfReqTask ConstructRuleTask(Management mgt, Rule rule, ModellingConnection conn, bool delete, List elements) + { + Dictionary? addInfo = new() { { AdditionalInfoKeys.ConnId, conn.Id.ToString() } }; + List ruleElements = + [ + .. elements, + new() + { + Field = ElemFieldType.rule.ToString(), + RuleUid = rule.Uid, + DeviceId = rule.EnforcingGateways.FirstOrDefault()?.Content?.Id, + Name = rule.Name + } + ]; + WfReqTask ruleTask = new() + { + Title = (delete ? userConfig.GetText("delete_rule") : userConfig.GetText("change_rule")) + ": " + (rule.Name ?? ""), + TaskType = delete ? WfTaskType.rule_delete.ToString() : WfTaskType.rule_modify.ToString(), + RequestAction = delete ? RequestAction.delete.ToString() : RequestAction.modify.ToString(), + ManagementId = mgt.Id, + OnManagement = mgt, + Elements = ruleElements, + RuleAction = 1, // Todo ?? + Tracking = 1, // Todo ?? + AdditionalInfo = JsonSerializer.Serialize(addInfo), + Comments = [new() { Comment = new() { CommentText = ConstructComment(conn) } }] + }; + Device? device = mgt.Devices.FirstOrDefault(d => d.Id == rule.EnforcingGateways.FirstOrDefault()?.Content?.Id); + ruleTask.SetDeviceList(device != null ? [device] : []); + return ruleTask; + } + + private void AnalyseNetworkAreasForRequest(ModellingConnection conn, bool modelled = false) + { + foreach (var area in ModellingNetworkAreaWrapper.Resolve(conn.SourceAreas)) + { + ReqElements.Add(new() + { + RequestAction = RequestAction.create.ToString(), + Field = modelled ? ElemFieldType.modelled_source.ToString() : ElemFieldType.source.ToString(), + GroupName = area.IdString + }); + } + foreach (var area in ModellingNetworkAreaWrapper.Resolve(conn.DestinationAreas)) + { + ReqElements.Add(new() + { + RequestAction = RequestAction.create.ToString(), + Field = modelled ? ElemFieldType.modelled_destination.ToString() : ElemFieldType.destination.ToString(), + GroupName = area.IdString + }); + } + } + + private void AnalyseAppRolesForRequest(ModellingConnection conn, Management mgt) + { + foreach (ModellingAppRole srcAppRole in ModellingAppRoleWrapper.Resolve(conn.SourceAppRoles)) + { + AnalyseAppRoleForRequest(srcAppRole, mgt, true); + } + foreach (ModellingAppRole dstAppRole in ModellingAppRoleWrapper.Resolve(conn.DestinationAppRoles)) + { + AnalyseAppRoleForRequest(dstAppRole, mgt); + } + } + + private void AnalyseAppRoleForRequest(ModellingAppRole appRole, Management mgt, bool isSource = false) + { + if (!userConfig.ModRequestOnlyOwnObjects || appRole.AppId == owner.Id) + { + if (ResolveProdAppRole(appRole, mgt) == null) + { + if (TaskList.FirstOrDefault(x => x.Title == userConfig.GetText("new_app_role") + appRole.IdString && x.OnManagement?.Id == mgt.Id) == null) + { + RequestNewAppRole(appRole, mgt); + } + } + else if (AppRoleChanged(appRole) && + TaskList.FirstOrDefault(x => x.Title == userConfig.GetText("update_app_role") + appRole.IdString + userConfig.GetText("add_members") && x.OnManagement?.Id == mgt.Id) == null && + DeleteObjectTasksList.FirstOrDefault(x => x.Title == userConfig.GetText("update_app_role") + appRole.IdString + userConfig.GetText("remove_members") && x.OnManagement?.Id == mgt.Id) == null) + { + RequestUpdateAppRole(appRole, mgt); + } + } + + ReqElements.Add(new() + { + RequestAction = RequestAction.create.ToString(), + Field = isSource ? ElemFieldType.source.ToString() : ElemFieldType.destination.ToString(), + GroupName = appRole.IdString + }); + } + + private async Task AnalyseAppZoneForRequest(Management mgt) + { + if (!userConfig.CreateAppZones) + { + return; + } + ModellingAppZone? oldAppZone = await AppZoneHandler.GetExistingModelledAppZone(); + PlannedAppZoneDbUpdate = await AppZoneHandler.PlanAppZoneDbUpdate(oldAppZone); + + ModellingAppRole? prodAppZone = oldAppZone == null ? null : ResolveProdAppRole(oldAppZone, mgt); + if (prodAppZone == null) + { + RequestNewAppRole(AppZoneHandler.CreateNewAppZone(), mgt); + } + else + { + ModellingAppZone appZoneToRequest = AppZoneHandler.PlanAppZoneRequest(new ModellingAppZone(prodAppZone)); + if (appZoneToRequest.AppServersNew.Count > 0 || appZoneToRequest.AppServersRemoved.Count > 0) + { + newAppServers = appZoneToRequest.AppServersNew; + deletedAppServers = appZoneToRequest.AppServersRemoved; + unchangedAppServers = appZoneToRequest.AppServersUnchanged; + RequestUpdateAppRole(appZoneToRequest, mgt); + } + } + } + + private ModellingAppRole? ResolveProdAppRole(ModellingAppRole appRole, Management mgt) + { + string nwGroupType = appRole.GetType() == typeof(ModellingAppZone) ? "AppZone" : "AppRole"; + Log.WriteDebug($"Search {nwGroupType}", $"Name: {appRole.Name}, IdString: {appRole.IdString}, Management: {mgt.Name}"); + + bool shortened = false; + string sanitizedARName = appRole.IdString.SanitizeJsonFieldMand(ref shortened); + if (allProdAppRoles.ContainsKey(mgt.Id)) + { + existingAppRole = allProdAppRoles[mgt.Id].FirstOrDefault(a => a.Name == appRole.IdString || a.Name == sanitizedARName); + } + if (existingAppRole != null) + { + Log.WriteDebug($"Search {nwGroupType}", $"Found!!"); + } + return existingAppRole; + } + + private (long?, bool) ResolveAppServerId(ModellingAppServer appServer, Management mgt) + { + Log.WriteDebug("Search AppServer", $"Name: {appServer.Name}, Ip: {appServer.Ip}, Management: {mgt.Name}"); + + if (allExistingAppServersHashes[mgt.Id].TryGetValue(appServerComparer.GetHashCode(appServer), out long existingAppServerId)) + { + Log.WriteDebug("Search AppServer", $"Found!!"); + return (existingAppServerId, true); + } + else if (alreadyCreatedAppServers[mgt.Id].FirstOrDefault(a => appServerComparer.Equals(a, appServer)) != null) + { + return (null, true); + } + else + { + alreadyCreatedAppServers[mgt.Id].Add(appServer); + return (null, false); + } + } + + private bool AppRoleChanged(ModellingAppRole appRole) + { + newAppServers = []; + deletedAppServers = []; + unchangedAppServers = []; + + if (existingAppRole is null) + { + return false; + } + + if (appRole is ModellingAppZone appZone) + { + return appZone.AppServersNew.Count > 0 || appZone.AppServersRemoved.Count > 0; + } + + foreach (ModellingAppServerWrapper appserver in appRole.AppServers) + { + if (existingAppRole.AppServers.FirstOrDefault(a => appServerComparer.Equals(a.Content, appserver.Content)) != null) + { + unchangedAppServers.Add(appserver); + } + else + { + newAppServers.Add(appserver); + } + } + foreach (ModellingAppServerWrapper exAppserver in existingAppRole.AppServers) + { + if (appRole.AppServers.FirstOrDefault(a => appServerComparer.Equals(exAppserver.Content, a.Content)) == null) + { + deletedAppServers.Add(exAppserver); + } + } + return newAppServers.Count > 0 || deletedAppServers.Count > 0; + } + + private void RequestNewAppRole(ModellingAppRole appRole, Management mgt) + { + string title = appRole.GetType() == typeof(ModellingAppZone) ? userConfig.GetText("new_app_zone") : userConfig.GetText("new_app_role"); + List groupMembers = []; + foreach (ModellingAppServer appServer in ModellingAppServerWrapper.Resolve(appRole.AppServers)) + { + (long? networkId, bool alreadyRequested) = ResolveAppServerId(appServer, mgt); + groupMembers.Add(new() + { + RequestAction = alreadyRequested ? RequestAction.addAfterCreation.ToString() : RequestAction.create.ToString(), + Field = ElemFieldType.source.ToString(), + Name = AppServerHelper.ConstructAppServerName(appServer, namingConvention), + IpString = appServer.Ip, + IpEnd = appServer.IpEnd, + GroupName = appRole.IdString, + NetworkId = networkId + }); + } + Dictionary? addInfo = new() { { AdditionalInfoKeys.GrpName, appRole.IdString }, { AdditionalInfoKeys.AppRoleId, appRole.Id.ToString() } }; + TaskList.Add(new() + { + Title = title + appRole.IdString, + TaskType = WfTaskType.group_create.ToString(), + RequestAction = RequestAction.create.ToString(), + ManagementId = mgt.Id, + OnManagement = mgt, + Elements = groupMembers, + AdditionalInfo = JsonSerializer.Serialize(addInfo) + }); + } + + private void RequestUpdateAppRole(ModellingAppRole appRole, Management mgt) + { + string title = appRole.GetType() == typeof(ModellingAppZone) ? userConfig.GetText("update_app_zone") : userConfig.GetText("update_app_role"); + FillGroupMembers(appRole.IdString, mgt); + Dictionary? addInfo = new() { { AdditionalInfoKeys.GrpName, appRole.IdString }, { AdditionalInfoKeys.AppRoleId, appRole.Id.ToString() } }; + if (newGroupMembers.Count > 0) + { + newGroupMembers.AddRange(unchangedGroupMembers); + newGroupMembers.AddRange(unchangedGroupMembersDuringCreate); // will be deleted later + TaskList.Add(new() + { + Title = title + appRole.IdString + userConfig.GetText("add_members"), + TaskType = WfTaskType.group_modify.ToString(), + RequestAction = RequestAction.modify.ToString(), + ManagementId = mgt.Id, + OnManagement = mgt, + Elements = newGroupMembers, + AdditionalInfo = JsonSerializer.Serialize(addInfo) + }); + } + if (deletedGroupMembers.Count > 0) + { + deletedGroupMembers.AddRange(unchangedGroupMembers); + deletedGroupMembers.AddRange(newCreatedGroupMembers); + DeleteObjectTasksList.Add(new() + { + Title = title + appRole.IdString + userConfig.GetText("remove_members"), + TaskType = WfTaskType.group_modify.ToString(), + RequestAction = RequestAction.modify.ToString(), + ManagementId = mgt.Id, + OnManagement = mgt, + Elements = deletedGroupMembers, + AdditionalInfo = JsonSerializer.Serialize(addInfo) + }); + } + } + + private void FillGroupMembers(string idString, Management mgt) + { + newGroupMembers = []; + newCreatedGroupMembers = []; + deletedGroupMembers = []; + unchangedGroupMembers = []; + unchangedGroupMembersDuringCreate = []; + foreach (var appServer in newAppServers.Select(a => a.Content)) + { + (long? networkId, bool alreadyRequested) = ResolveAppServerId(appServer, mgt); + newGroupMembers.Add(new() + { + RequestAction = alreadyRequested ? RequestAction.addAfterCreation.ToString() : RequestAction.create.ToString(), + Field = ElemFieldType.source.ToString(), + Name = AppServerHelper.ConstructAppServerName(appServer, namingConvention), + IpString = appServer.Ip, + IpEnd = appServer.IpEnd, + GroupName = idString, + NetworkId = networkId + }); + newCreatedGroupMembers.Add(new() + { + RequestAction = RequestAction.unchanged.ToString(), + Field = ElemFieldType.source.ToString(), + Name = appServer.Name, + IpString = appServer.Ip, + IpEnd = appServer.IpEnd, + GroupName = idString, + NetworkId = networkId + }); + } + foreach (var appServer in unchangedAppServers.Select(a => a.Content)) + { + unchangedGroupMembers.Add(new() + { + RequestAction = RequestAction.unchanged.ToString(), + Field = ElemFieldType.source.ToString(), + Name = appServer.Name, + IpString = appServer.Ip, + IpEnd = appServer.IpEnd, + GroupName = idString + }); + } + foreach (var appServer in deletedAppServers.Select(a => a.Content)) + { + unchangedGroupMembersDuringCreate.Add(new() + { + RequestAction = RequestAction.unchanged.ToString(), + Field = ElemFieldType.source.ToString(), + Name = appServer.Name, + IpString = appServer.Ip, + IpEnd = appServer.IpEnd, + GroupName = idString + }); + deletedGroupMembers.Add(new() + { + RequestAction = RequestAction.delete.ToString(), + Field = ElemFieldType.source.ToString(), + Name = appServer.Name, + IpString = appServer.Ip, + IpEnd = appServer.IpEnd, + GroupName = idString + }); + } + } + + private void AnalyseAppServersForRequest(ModellingConnection conn, bool modelled = false) + { + foreach (var srcAppServer in conn.SourceAppServers.Select(a => a.Content)) + { + ReqElements.Add(new() + { + RequestAction = RequestAction.create.ToString(), + Field = modelled ? ElemFieldType.modelled_source.ToString() : ElemFieldType.source.ToString(), + Name = srcAppServer.Name, + IpString = srcAppServer.Ip, + IpEnd = srcAppServer.IpEnd + }); + } + foreach (var dstAppServer in conn.DestinationAppServers.Select(a => a.Content)) + { + ReqElements.Add(new() + { + RequestAction = RequestAction.create.ToString(), + Field = modelled ? ElemFieldType.modelled_destination.ToString() : ElemFieldType.destination.ToString(), + Name = dstAppServer.Name, + IpString = dstAppServer.Ip, + IpEnd = dstAppServer.IpEnd + }); + } + } + + private void AnalyseServiceGroupsForRequest(ModellingConnection conn, Management mgt) + { + foreach (ModellingServiceGroup svcGrp in ModellingServiceGroupWrapper.Resolve(conn.ServiceGroups)) + { + if (userConfig.ModRolloutResolveServiceGroups) + { + AddResolvedServiceGroup(svcGrp); + continue; + } + + if ((!userConfig.ModRequestOnlyOwnObjects || svcGrp.AppId == owner.Id) && + TaskList.FirstOrDefault(x => x.Title == userConfig.GetText("new_svc_grp") + svcGrp.Name && x.OnManagement?.Id == mgt.Id) == null) + { + RequestNewServiceGroup(svcGrp, mgt); + } + + ReqElements.Add(new() + { + RequestAction = RequestAction.create.ToString(), + Field = ElemFieldType.service.ToString(), + GroupName = svcGrp.Name + }); + } + } + + private void AddResolvedServiceGroup(ModellingServiceGroup svcGrp) + { + foreach (ModellingService svc in ModellingServiceWrapper.Resolve(svcGrp.Services)) + { + ReqElements.Add(new() + { + RequestAction = RequestAction.create.ToString(), + Field = ElemFieldType.service.ToString(), + Name = svc.Name, + Port = svc.Port, + PortEnd = svc.PortEnd, + ProtoId = svc.ProtoId + }); + } + } + + private void RequestNewServiceGroup(ModellingServiceGroup svcGrp, Management mgt) + { + List groupMembers = []; + foreach (ModellingService svc in ModellingServiceWrapper.Resolve(svcGrp.Services)) + { + groupMembers.Add(new() + { + RequestAction = RequestAction.create.ToString(), + Field = ElemFieldType.service.ToString(), + Name = svc.Name, + Port = svc.Port, + PortEnd = svc.PortEnd, + ProtoId = svc.ProtoId, + GroupName = svcGrp.Name + }); + } + Dictionary? addInfo = new() { { AdditionalInfoKeys.GrpName, svcGrp.Name }, { AdditionalInfoKeys.SvcGrpId, svcGrp.Id.ToString() } }; + TaskList.Add(new() + { + Title = userConfig.GetText("new_svc_grp") + svcGrp.Name, + TaskType = WfTaskType.group_create.ToString(), + ManagementId = mgt.Id, + OnManagement = mgt, + Elements = groupMembers, + AdditionalInfo = JsonSerializer.Serialize(addInfo) + }); + } + + private void AnalyseServicesForRequest(ModellingConnection conn) + { + foreach (ModellingService svc in ModellingServiceWrapper.Resolve(conn.Services)) + { + ReqElements.Add(new() + { + RequestAction = RequestAction.create.ToString(), + Field = ElemFieldType.service.ToString(), + Name = svc.Name, + Port = svc.Port, + PortEnd = svc.PortEnd, + ProtoId = svc.ProtoId + }); + } + } + } +} diff --git a/roles/lib/files/FWO.Services/Modelling/ModellingVarianceAnalysisRules.cs b/roles/lib/files/FWO.Services/Modelling/ModellingVarianceAnalysisRules.cs new file mode 100644 index 0000000000..b1629ea332 --- /dev/null +++ b/roles/lib/files/FWO.Services/Modelling/ModellingVarianceAnalysisRules.cs @@ -0,0 +1,489 @@ +using FWO.Api.Client.Queries; +using FWO.Basics; +using FWO.Config.Api.Data; +using FWO.Data; +using FWO.Data.Modelling; +using System.Text.Json; + +namespace FWO.Services.Modelling +{ + /// + /// Part of Variance Analysis Class analysing the rules + /// + public partial class ModellingVarianceAnalysis + { + private List AllowedSrcSpecUserAreas { get; set; } = []; + private List AllowedDestSpecUserAreas { get; set; } = []; + private List AllowedSrcUpdatableObjAreas { get; set; } = []; + private List AllowedDestUpdatableObjAreas { get; set; } = []; + private NetworkObjectComparer networkObjectComparer = new(new()); + private NetworkObjectGroupFlatComparer networkObjectGroupComparer = new(new()); + private NetworkServiceComparer networkServiceComparer = new(new()); + private NetworkServiceGroupComparer networkServiceGroupComparer = new(new()); + private bool FullAnalysis = false; + + private void AnalyseRules(ModellingConnection conn, bool fullAnalysis) + { + FullAnalysis = fullAnalysis; + GetAllowedSpecUserAreas(); + GetAllowedUpdatableObjAreas(); + networkObjectComparer = new(ruleRecognitionOption); + networkObjectGroupComparer = new(ruleRecognitionOption); + networkServiceComparer = new(ruleRecognitionOption); + networkServiceGroupComparer = new(ruleRecognitionOption); + bool ruleFound = false; + foreach (var mgt in RelevantManagements) + { + foreach (var rule in allModelledRules[mgt.Id].Where(r => CompareRuleToConn(r, conn))) + { + ruleFound = true; + } + } + if (ruleFound) + { + CheckForNAT(conn); + } + else + { + varianceResult.ConnsNotImplemented.Add(conn); + } + } + + private void CheckForNAT(ModellingConnection conn) + { + if (conn.IsNat() && userConfig.ModRolloutNatHeuristic && varianceResult.OkRules.FirstOrDefault(x => x.ModelledConnection.Id == conn.Id) != null) + { + int connSrcObjects = conn.SourceAreas.Count + conn.SourceAppRoles.Count + conn.SourceAppServers.Count + conn.SourceOtherGroups.Count; + int connDstObjects = conn.DestinationAreas.Count + conn.DestinationAppRoles.Count + conn.DestinationAppServers.Count + conn.DestinationOtherGroups.Count; + int connSvcObjects = conn.ServiceGroups.Count + conn.Services.Count; + foreach (var diff in varianceResult.RuleDifferences.Where(x => x.ModelledConnection.Id == conn.Id).Select(d => d.ImplementedRules)) + { + foreach (var rule in diff) + { + if (rule.Froms.Length == connSrcObjects && rule.Tos.Length == connDstObjects && rule.Services.Length == connSvcObjects) + { + rule.ModellOk = true; + } + } + diff.RemoveAll(x => x.ModellOk); + } + varianceResult.RuleDifferences.RemoveAll(x => x.ModelledConnection.Id == conn.Id && x.ImplementedRules.Count == 0); + } + } + + private async Task GetRulesForDeletedConns(List dokuOnlyConnections) + { + await GetDeletedConnections(); + List RegardedAsDeletedConns = [.. DeletedConns, .. dokuOnlyConnections]; + List RegardedDeletedConnectionIds = RegardedAsDeletedConns.ConvertAll(c => c.Id); + foreach (var mgt in allModelledRules.Keys) + { + List rulesForDeletedModels = []; + foreach (var rule in allModelledRules[mgt].Where(r => !r.ModellFound)) + { + if (int.TryParse(FindModelledMarker(rule), out int connId) && RegardedDeletedConnectionIds.Contains(connId)) + { + rulesForDeletedModels.Add(rule); + } + } + if (rulesForDeletedModels.Count > 0) // NOSONAR: false positive, list is built in loop above + { + varianceResult.DeletedModelsRules.Add(mgt, rulesForDeletedModels); + } + } + } + + private void GetAllowedSpecUserAreas() + { + AllowedSrcSpecUserAreas = []; + AllowedDestSpecUserAreas = []; + if (userConfig.ModSpecUserAreas != "" && userConfig.ModSpecUserAreas != "[]") + { + List configItems = JsonSerializer.Deserialize>(userConfig.ModSpecUserAreas) ?? []; + foreach (var configItem in configItems.Where(c => AllAreas.FirstOrDefault(a => a.Id == c.AreaId) != null)) + { + if (configItem.UseInSrc) + { + AllowedSrcSpecUserAreas.Add(configItem.AreaId); + } + if (configItem.UseInDst) + { + AllowedDestSpecUserAreas.Add(configItem.AreaId); + } + } + } + } + + private void GetAllowedUpdatableObjAreas() + { + AllowedSrcUpdatableObjAreas = []; + AllowedDestUpdatableObjAreas = []; + if (userConfig.ModUpdatableObjAreas != "" && userConfig.ModUpdatableObjAreas != "[]") + { + List configItems = JsonSerializer.Deserialize>(userConfig.ModUpdatableObjAreas) ?? []; + foreach (var configItem in configItems.Where(c => AllAreas.FirstOrDefault(a => a.Id == c.AreaId) != null)) + { + if (configItem.UseInSrc) + { + AllowedSrcUpdatableObjAreas.Add(configItem.AreaId); + } + if (configItem.UseInDst) + { + AllowedDestUpdatableObjAreas.Add(configItem.AreaId); + } + } + } + } + + private bool CompareRuleToConn(Rule rule, ModellingConnection conn) + { + if (rule.ConnId == conn.Id) + { + rule.ModellFound = true; + if (IsImplementation(rule, conn)) + { + conn.ProdRuleFound = true; + rule.ModellOk = true; + varianceResult.AddOkRule(conn, rule); + } + else + { + varianceResult.AddDifference(conn, rule); + } + return true; + } + return false; + } + + private bool IsImplementation(Rule rule, ModellingConnection conn) + { + bool isImpl = !rule.IsDropRule() && !rule.Disabled && !rule.SourceNegated && !rule.DestinationNegated; + Dictionary SpecialUserObjects = conn.GetSpecialUserObjectNames(); + Dictionary UpdatableObjects = conn.GetUpdatableObjectNames(); + List disregardedFroms = []; + List disregardedTos = []; + List disregardedServices = []; + (List normConnSvc, List normConnSvcGrp, List normRuleSvc) = NormalizeServices(rule, conn); + bool continueAnalysis = FullAnalysis || SpecialUserObjects.Count > 0 || UpdatableObjects.Count > 0 || conn.IsNat(); + + if (continueAnalysis) + { + isImpl &= IsNwImplementation(rule.Froms, SpecialUserObjects, UpdatableObjects, conn, true, ref disregardedFroms, continueAnalysis); + isImpl &= IsNwImplementation(rule.Tos, SpecialUserObjects, UpdatableObjects, conn, false, ref disregardedTos, continueAnalysis); + bool isSvcImpl = IsSvcImplementation(normRuleSvc, normConnSvc, normConnSvcGrp, disregardedServices); + isImpl &= isSvcImpl; + if (!isSvcImpl && ruleRecognitionOption.SvcSplitPortRanges) + { + disregardedServices = RebundlePortRanges(disregardedServices); + rule.Services = [.. RebundlePortRanges(normRuleSvc).ConvertAll(s => new ServiceWrapper() { Content = s })]; + } + rule.DisregardedFroms = [.. disregardedFroms]; + rule.DisregardedTos = [.. disregardedTos]; + rule.DisregardedServices = [.. disregardedServices]; + rule.UnusedSpecialUserObjects = [.. SpecialUserObjects.Keys.Where(x => !SpecialUserObjects[x])]; + rule.UnusedUpdatableObjects = [.. UpdatableObjects.Keys.Where(x => !UpdatableObjects[x])]; + isImpl &= rule.UnusedSpecialUserObjects.Count == 0 && rule.UnusedUpdatableObjects.Count == 0; + } + else if (isImpl) + { + isImpl = IsNwImplementation(rule.Froms, SpecialUserObjects, UpdatableObjects, conn, true, ref disregardedFroms, continueAnalysis) + && IsNwImplementation(rule.Tos, SpecialUserObjects, UpdatableObjects, conn, false, ref disregardedTos, continueAnalysis) + && IsSvcImplementation(normRuleSvc, normConnSvc, normConnSvcGrp, []) + && !SpecialUserObjects.Any(x => !x.Value); + } + return isImpl; + } + + private (List, List normConnSvcGrp, List normRuleSvc) NormalizeServices(Rule rule, ModellingConnection conn) + { + List normConnSvc = SplitPortRanges(ModellingServiceWrapper.Resolve(conn.Services).ToList().ConvertAll(s => ModellingService.ToNetworkService(s))); + List normConnSvcGrp = SplitPortRanges(ModellingServiceGroupWrapper.Resolve(conn.ServiceGroups).ToList().ConvertAll(a => a.ToNetworkServiceGroup())); + List normRuleSvc = SplitPortRanges([.. rule.Services.ToList().ConvertAll(s => s.Content)]); + return (normConnSvc, normConnSvcGrp, normRuleSvc); + } + + private List SplitPortRanges(List servicesIn) + { + if (!ruleRecognitionOption.SvcSplitPortRanges) + { + return servicesIn; + } + List servicesOut = []; + foreach (var svc in servicesIn) + { + if (svc.Type.Name == ObjectType.Group) + { + List grpMembers = []; + foreach (var member in svc.ServiceGroupFlats.Select(m => m.Object).Where(m => m != null)) + { + grpMembers.AddRange(SplitPortRange(member!)); + } + svc.ServiceGroupFlats = Array.ConvertAll(grpMembers.ToArray(), o => new GroupFlat() { Object = o }); + servicesOut.Add(svc); + } + else + { + servicesOut.AddRange(SplitPortRange(svc)); + } + } + return servicesOut; + } + + private static List SplitPortRange(NetworkService serviceIn) + { + List servicesOut = []; + if (serviceIn.DestinationPort == null || serviceIn.DestinationPortEnd == null || serviceIn.DestinationPortEnd <= serviceIn.DestinationPort) + { + return [serviceIn]; + } + else + { + for (int port = (int)serviceIn.DestinationPort; port <= (int)serviceIn.DestinationPortEnd; port++) + { + NetworkService partialSvc = new(serviceIn) { DestinationPort = port, DestinationPortEnd = port }; + servicesOut.Add(partialSvc); + } + } + return servicesOut; + } + + private static List RebundlePortRanges(List servicesIn) + { + List servicesOut = []; + NetworkService? actSvc = null; + foreach (var svc in servicesIn) + { + if (svc.DestinationPort == null) + { + servicesOut.Add(svc); + } + else if (actSvc == null) + { + actSvc = svc; + } + else if (svc.Id == actSvc.Id && svc.DestinationPort == actSvc.DestinationPortEnd + 1 && svc.IsSurplus == actSvc.IsSurplus) + { + actSvc.DestinationPortEnd++; + } + else + { + servicesOut.Add(actSvc); + actSvc = svc; + } + } + if (actSvc != null) + { + servicesOut.Add(actSvc); + } + return servicesOut; + } + + private bool IsNwImplementation(NetworkLocation[] networkLocations, Dictionary specialUserObjects, + Dictionary updatableObjects, ModellingConnection conn, bool source, ref List disregardedLocations, bool continueAnalysis) + { + List appServers = source ? conn.SourceAppServers : conn.DestinationAppServers; + List appRoles = source ? conn.SourceAppRoles : conn.DestinationAppRoles; + List areas = source ? conn.SourceAreas : conn.DestinationAreas; + List otherGroups = source ? conn.SourceOtherGroups : conn.DestinationOtherGroups; + + foreach (var loc in networkLocations) + { + loc.Object.IsSurplus = false; + } + if (!CompareNwAreas(networkLocations, areas, disregardedLocations, continueAnalysis) && !continueAnalysis) + { + return false; + } + if (!CompareAppServers(networkLocations, appServers, appRoles, disregardedLocations, continueAnalysis) && !continueAnalysis) + { + return false; + } + if (!ruleRecognitionOption.NwResolveGroup && !CompareRemainingNwGroups(networkLocations, appRoles, otherGroups, disregardedLocations, continueAnalysis) && !continueAnalysis) + { + return false; + } + AdjustWithSpecialUserObjects(networkLocations, specialUserObjects, source, ref disregardedLocations); + AdjustWithUpdatableObjects(networkLocations, updatableObjects, source, ref disregardedLocations); + return disregardedLocations.Count == 0 && networkLocations.Where(n => n.Object.IsSurplus).ToList().Count == 0; + } + + private void AdjustWithSpecialUserObjects(NetworkLocation[] networkLocations, Dictionary specialUserObjects, bool source, ref List disregardedLocations) + { + if (specialUserObjects.Count > 0 && disregardedLocations.Count > 0) + { + List surplusSpecUserLocations = [.. networkLocations.Where(n => n.Object.IsSurplus && specialUserObjects.ContainsKey(n.Object.Name.ToLower()))]; + List remainingPossibleSpecObj = GetPossibleSpecObjects(disregardedLocations, source); + if (surplusSpecUserLocations.Count == remainingPossibleSpecObj.Count) + { + foreach (var location in remainingPossibleSpecObj) + { + disregardedLocations.Remove(location); + } + foreach (var specUser in surplusSpecUserLocations.Select(s => s.Object)) + { + specUser.IsSurplus = false; + specialUserObjects[specUser.Name.ToLower()] = true; + } + } + } + } + + private List GetPossibleSpecObjects(List disregardedLocations, bool source) + { + return [.. disregardedLocations.Where(l => l.Object.Type.Name == ObjectType.Group && (source ? AllowedSrcSpecUserAreas.Contains(l.Object.Id) : AllowedDestSpecUserAreas.Contains(l.Object.Id)))]; + } + + private void AdjustWithUpdatableObjects(NetworkLocation[] networkLocations, Dictionary updatableObjects, bool source, ref List disregardedLocations) + { + if (updatableObjects.Count > 0 && disregardedLocations.Count > 0) + { + List surplusUpdObjLocations = [.. networkLocations.Where(n => n.Object.IsSurplus && updatableObjects.ContainsKey(n.Object.Name.ToLower()))]; + List remainingPossibleUpdatableObj = GetPossibleUpdatableObjects(disregardedLocations, source); + if (surplusUpdObjLocations.Count == remainingPossibleUpdatableObj.Count) + { + foreach (var location in remainingPossibleUpdatableObj) + { + disregardedLocations.Remove(location); + } + foreach (var updObj in surplusUpdObjLocations.Select(s => s.Object)) + { + updObj.IsSurplus = false; + updatableObjects[updObj.Name.ToLower()] = true; + } + } + } + } + + private List GetPossibleUpdatableObjects(List disregardedLocations, bool source) + { + return [.. disregardedLocations.Where(l => l.Object.Type.Name == ObjectType.Group && (source ? AllowedSrcUpdatableObjAreas.Contains(l.Object.Id) : AllowedDestUpdatableObjAreas.Contains(l.Object.Id)))]; + } + + private bool CompareNwAreas(NetworkLocation[] networkLocations, List areas, List disregardedLocations, bool continueAnalysis) + { + List allProdNwAreas = networkLocations.Where(n => n.Object.Type.Name == ObjectType.Group && IsArea(n.Object)).ToList().ConvertAll(n => n.Object); + List allModNwAreas = ModellingNetworkAreaWrapper.Resolve(areas).ToList().ConvertAll(a => a.ToNetworkObjectGroup(true)); + NetworkObjectComparer networkAreaComparer = new(new() { NwRegardName = true, NwRegardIp = false }); + return CompareNwObjects(allModNwAreas, allProdNwAreas, networkLocations, disregardedLocations, networkAreaComparer, continueAnalysis); + } + + private bool IsArea(NetworkObject nwGroup) + { + return nwGroup.Name.StartsWith(namingConvention.NetworkAreaPattern); + } + + private bool CompareAppServers(NetworkLocation[] networkLocations, List appServers, + List appRoles, List disregardedLocations, bool continueAnalysis) + { + List allProdNwObjects = networkLocations.Where(n => n.Object.Type.Name != ObjectType.Group).ToList().ConvertAll(n => n.Object); + List allModNwObjects = ModellingAppServerWrapper.Resolve(appServers).ToList().ConvertAll(a => ModellingAppServer.ToNetworkObject(a)); + if (ruleRecognitionOption.NwResolveGroup) + { + foreach (var nwGroup in networkLocations.Where(n => n.Object.Type.Name == ObjectType.Group && !IsArea(n.Object))) + { + allProdNwObjects.AddRange([.. nwGroup.Object.ObjectGroupFlats.Where(g => g.Object != null).ToList().ConvertAll(g => g.Object!)]); + } + foreach (var appRole in ModellingAppRoleWrapper.Resolve(appRoles)) + { + allModNwObjects.AddRange(ModellingAppServerWrapper.Resolve(appRole.AppServers).ToList().ConvertAll(a => ModellingAppServer.ToNetworkObject(a))); + } + } + return CompareNwObjects(allModNwObjects, allProdNwObjects, networkLocations, disregardedLocations, networkObjectComparer, continueAnalysis); + } + + private bool CompareRemainingNwGroups(NetworkLocation[] networkLocations, List appRoles, List otherGroups, List disregardedLocations, bool continueAnalysis) + { + List allProdNwGroups = networkLocations.Where(n => n.Object.Type.Name == ObjectType.Group && !IsArea(n.Object)).ToList().ConvertAll(n => n.Object); + List allModNwGroups = ModellingAppRoleWrapper.Resolve(appRoles).ToList().ConvertAll(a => a.ToNetworkObjectGroup(true)); + allModNwGroups.AddRange(ModellingNwGroupWrapper.Resolve(otherGroups).ToList().ConvertAll(a => a.ToNetworkObjectGroup())); + return CompareNwObjects(allModNwGroups, allProdNwGroups, networkLocations, disregardedLocations, networkObjectGroupComparer, continueAnalysis); + } + + private static bool CompareNwObjects(List allModGroups, List allProdGroups, NetworkLocation[] networkLocations, + List disregardedLocations, IEqualityComparer comparer, bool continueAnalysis = false) + { + if (continueAnalysis) + { + List disregardedGroups = [.. allModGroups.Except(allProdGroups, comparer)]; + List surplusGroups = [.. allProdGroups.Except(allModGroups, comparer)]; + foreach (var obj in surplusGroups) + { + NetworkLocation? extLoc = networkLocations.FirstOrDefault(n => n.Object.Id == obj.Id); + if (extLoc != null) + { + extLoc.Object.IsSurplus = true; + } + } + disregardedLocations.AddRange(disregardedGroups.ConvertAll(o => new NetworkLocation(new(), o))); + return disregardedGroups.Count == 0 && surplusGroups.Count == 0; + } + + return allModGroups.Count == allProdGroups.Count + && allModGroups.Except(allProdGroups, comparer).ToList().Count == 0 + && allProdGroups.Except(allModGroups, comparer).ToList().Count == 0; + } + + private bool IsSvcImplementation(List prodServices, List modServices, List modServiceGroups, List disregardedServices) + { + bool isImpl = true; + if (!CompareServices(prodServices, modServices, modServiceGroups, disregardedServices)) + { + if (!FullAnalysis) + { + return false; + } + isImpl = false; + } + return (ruleRecognitionOption.SvcResolveGroup || CompareSvcGroups(prodServices, modServiceGroups, disregardedServices)) && isImpl; + } + + private bool CompareServices(List prodServices, List modServices, List modServiceGroups, List disregardedServices) + { + List allProdServices = [.. prodServices.Where(s => s.Type.Name != ServiceType.Group)]; + List allModServices = modServices; + if (ruleRecognitionOption.SvcResolveGroup) + { + foreach (var svc in prodServices.Where(n => n.Type.Name == ServiceType.Group)) + { + allProdServices.AddRange([.. svc.ServiceGroupFlats.ToList().ConvertAll(g => g.Object ?? new())]); + } + foreach (var svcGrp in modServiceGroups) + { + allModServices.AddRange([.. svcGrp.ServiceGroupFlats.ToList().ConvertAll(g => g.Object ?? new())]); + } + } + return CompareSvcObjects(allModServices, allProdServices, prodServices, disregardedServices, networkServiceComparer); + } + + private bool CompareSvcGroups(List prodServices, List modServiceGroups, List disregardedServices) + { + List allProdSvcGroups = [.. prodServices.Where(n => n.Type.Name == ServiceType.Group)]; + List allModSvcGroups = modServiceGroups; + return CompareSvcObjects(allModSvcGroups, allProdSvcGroups, prodServices, disregardedServices, networkServiceGroupComparer); + } + + private bool CompareSvcObjects(List allModSvcObjects, List allProdSvcObjects, List prodServices, + List disregardedServices, IEqualityComparer comparer) + { + if (FullAnalysis) + { + List disregardedSvcObjects = [.. allModSvcObjects.Except(allProdSvcObjects, comparer)]; + List surplusSvcObjects = [.. allProdSvcObjects.Except(allModSvcObjects, comparer)]; + foreach (var svc in surplusSvcObjects) + { + NetworkService? exSvc = prodServices.FirstOrDefault(n => n.Id == svc.Id && n.DestinationPort == svc.DestinationPort); + if (exSvc != null) + { + exSvc.IsSurplus = true; + } + } + disregardedServices.AddRange(disregardedSvcObjects); + return disregardedSvcObjects.Count == 0 && surplusSvcObjects.Count == 0; + } + + return allModSvcObjects.Count == allProdSvcObjects.Count + && allModSvcObjects.Except(allProdSvcObjects, comparer).ToList().Count == 0 + && allProdSvcObjects.Except(allModSvcObjects, comparer).ToList().Count == 0; + } + } +} diff --git a/roles/lib/files/FWO.Services/NetworkObjectComparer.cs b/roles/lib/files/FWO.Services/NetworkObjectComparer.cs new file mode 100644 index 0000000000..b14f7c5843 --- /dev/null +++ b/roles/lib/files/FWO.Services/NetworkObjectComparer.cs @@ -0,0 +1,99 @@ +using FWO.Basics; +using FWO.Data; +using FWO.Data.Modelling; + +namespace FWO.Services +{ + public class NetworkObjectComparer(RuleRecognitionOption option) : IEqualityComparer + { + public bool Equals(NetworkObject? nwObject1, NetworkObject? nwObject2) + { + if (ReferenceEquals(nwObject1, nwObject2)) + { + return true; + } + + if (nwObject1 is null || nwObject2 is null) + { + return false; + } + + return (!option.NwRegardIp || (string.Equals(nwObject1.IP, nwObject2.IP, StringComparison.Ordinal) + && string.Equals(nwObject1.IpEnd, nwObject2.IpEnd, StringComparison.Ordinal))) + && (!option.NwRegardName || string.Equals(nwObject1.Name, nwObject2.Name, StringComparison.Ordinal)); + } + + public int GetHashCode(NetworkObject? nwObject) + { + if (nwObject is null) + { + return 0; + } + + return (option.NwRegardIp ? HashCode.Combine(nwObject.IP, nwObject.IpEnd) : 0) + ^ (option.NwRegardName ? HashCode.Combine(nwObject.Name) : 0); + } + } + + public class NetworkObjectGroupFlatComparer(RuleRecognitionOption option) : IEqualityComparer + { + private readonly NetworkObjectComparer networkObjectComparer = new(option); + + public bool Equals(NetworkObject? nwObjectGrp1, NetworkObject? nwObjectGrp2) + { + if (ReferenceEquals(nwObjectGrp1, nwObjectGrp2)) + { + return true; + } + + if (nwObjectGrp1 is null || nwObjectGrp2 is null) + { + return false; + } + + if (option.NwSeparateGroupAnalysis) + { + return !option.NwRegardGroupName || string.Equals(nwObjectGrp1.Name, nwObjectGrp2.Name, StringComparison.Ordinal); + } + + List objectList1 = nwObjectGrp1.ObjectGroupFlats + .Where(o => o.Object != null && !string.Equals(o.Object.Type.Name, ObjectType.Group, StringComparison.Ordinal)) + .Select(o => o.Object!) + .ToList(); + List objectList2 = nwObjectGrp2.ObjectGroupFlats + .Where(o => o.Object != null && !string.Equals(o.Object.Type.Name, ObjectType.Group, StringComparison.Ordinal)) + .Select(o => o.Object!) + .ToList(); + + if (objectList1.Count != objectList2.Count + || (option.NwRegardGroupName && !string.Equals(nwObjectGrp1.Name, nwObjectGrp2.Name, StringComparison.Ordinal))) + { + return false; + } + + return !objectList1.Except(objectList2, networkObjectComparer).Any() + && !objectList2.Except(objectList1, networkObjectComparer).Any(); + } + + public int GetHashCode(NetworkObject? nwObject) + { + if (nwObject is null) + { + return 0; + } + + int hashCode = 0; + + if (!option.NwSeparateGroupAnalysis) + { + foreach (var obj in nwObject.ObjectGroupFlats.Where(o => o.Object != null && !string.Equals(o.Object.Type.Name, ObjectType.Group, StringComparison.Ordinal)).Select(o => o.Object!)) + { + hashCode ^= networkObjectComparer.GetHashCode(obj); + } + } + return hashCode ^ (option.NwRegardGroupName ? + HashCode.Combine(nwObject.Type.Name, nwObject.Name) : + HashCode.Combine(nwObject.Type.Name)); + } + } +} diff --git a/roles/lib/files/FWO.Services/NetworkServiceComparer.cs b/roles/lib/files/FWO.Services/NetworkServiceComparer.cs new file mode 100644 index 0000000000..6ed85394a3 --- /dev/null +++ b/roles/lib/files/FWO.Services/NetworkServiceComparer.cs @@ -0,0 +1,106 @@ +using FWO.Basics; +using FWO.Data; +using FWO.Data.Modelling; + +namespace FWO.Services +{ + public class NetworkServiceComparer(RuleRecognitionOption option) : IEqualityComparer + { + public bool Equals(NetworkService? service1, NetworkService? service2) + { + if (ReferenceEquals(service1, service2)) + { + return true; + } + + if (service1 is null || service2 is null) + { + return false; + } + + if (CompareProtTypes(service1, service2)) + { + return true; + } + + int destPortEnd1 = service1.DestinationPortEnd ?? service1.DestinationPort ?? 0; + int destPortEnd2 = service2.DestinationPortEnd ?? service2.DestinationPort ?? 0; + + return (!option.SvcRegardPortAndProt || (service1.ProtoId == service2.ProtoId && + service1.DestinationPort == service2.DestinationPort && destPortEnd1 == destPortEnd2)) + && (!option.SvcRegardName || service1.Name == service2.Name); + } + + public int GetHashCode(NetworkService service) + { + SyncProtFields(service); + if (IsProtType(service.ProtoId)) + { + return (option.SvcRegardPortAndProt ? HashCode.Combine(service.ProtoId) : 0) + ^ (option.SvcRegardName ? HashCode.Combine(service.Name) : 0); + } + int destPortEnd = service.DestinationPortEnd ?? service.DestinationPort ?? 0; + return (option.SvcRegardPortAndProt ? HashCode.Combine(service.ProtoId, service.DestinationPort, destPortEnd) : 0) + ^ (option.SvcRegardName ? HashCode.Combine(service.Name) : 0); + } + + private static bool IsProtType(int? protoId) + { + return protoId != null && protoId != 6 && protoId != 17; + } + + private static bool CompareProtTypes(NetworkService service1, NetworkService service2) + { + SyncProtFields(service1); + SyncProtFields(service2); + return IsProtType(service1.ProtoId) && IsProtType(service2.ProtoId) && service1.ProtoId == service2.ProtoId; + } + + private static void SyncProtFields(NetworkService service) + { + if (service.ProtoId == null && service.Protocol != null) + { + service.ProtoId = service.Protocol.Id; + } + } + } + + public class NetworkServiceGroupComparer(RuleRecognitionOption option) : IEqualityComparer + { + readonly NetworkServiceComparer networkServiceComparer = new(option); + + public bool Equals(NetworkService? service1, NetworkService? service2) + { + if (ReferenceEquals(service1, service2)) + { + return true; + } + + if (service1 is null || service2 is null) + { + return false; + } + + if (service1.ServiceGroupFlats.Length != service2.ServiceGroupFlats.Length + || (option.SvcRegardGroupName && service1.Name != service2.Name)) + { + return false; + } + + return service1.ServiceGroupFlats.ToList().ConvertAll(g => g.Object) + .Except([.. service2.ServiceGroupFlats.ToList().ConvertAll(g => g.Object)], networkServiceComparer).ToList().Count == 0 + && service2.ServiceGroupFlats.ToList().ConvertAll(g => g.Object) + .Except([.. service1.ServiceGroupFlats.ToList().ConvertAll(g => g.Object)], networkServiceComparer).ToList().Count == 0; + } + + public int GetHashCode(NetworkService serviceGrp) + { + int hashCode = 0; + foreach (var svc in serviceGrp.ServiceGroupFlats.Select(sg => sg.Object).Where(s => s?.Type.Name != ServiceType.Group).ToList()) + { + hashCode ^= svc != null ? networkServiceComparer.GetHashCode(svc) : 0; + } + return hashCode ^ (option.SvcRegardGroupName ? HashCode.Combine(serviceGrp.Name) : 0); + } + } +} diff --git a/roles/lib/files/FWO.Services/NetworkZoneService.cs b/roles/lib/files/FWO.Services/NetworkZoneService.cs new file mode 100644 index 0000000000..728e00032a --- /dev/null +++ b/roles/lib/files/FWO.Services/NetworkZoneService.cs @@ -0,0 +1,413 @@ +using FWO.Api.Client; +using FWO.Api.Client.Queries; +using FWO.Basics; +using FWO.Basics.Comparer; +using FWO.Config.Api; +using FWO.Data; +using FWO.Logging; +using NetTools; + +namespace FWO.Services +{ + public class NetworkZoneService + { + public List NetworkZones { get; set; } = []; + + public delegate void ZoneAddEventArgs(); + public delegate void ZoneModificationEventArgs(ComplianceNetworkZone networkZone); + public event ZoneModificationEventArgs? OnEditZone; + public event ZoneModificationEventArgs? OnDeleteZone; + + public struct AdditionsDeletions + { + public List SourceZonesToAdd = []; + public List SourceZonesToDelete = []; + public List DestinationZonesToAdd = []; + public List DestinationZonesToDelete = []; + public List SubzonesToAdd = []; + public List SubzonesToDelete = []; + public List IpRangesToDelete = []; + public List IpRangesToAdd = []; + + public AdditionsDeletions() { } + } + + public void InvokeOnEditZone(ComplianceNetworkZone networkZone) + { + OnEditZone?.Invoke(networkZone); + } + + public void InvokeOnDeleteZone(ComplianceNetworkZone networkZone) + { + OnDeleteZone?.Invoke(networkZone); + } + + /// + /// Display the IP address range in CIDR notation if possible and it is not a single IP address + /// otherwise display it in the format "first_ip-last_ip". + /// + /// + /// IP address range in CIDR / first-last notation + public static string DisplayIpRange(IPAddressRange ipAddressRange) + { + try + { + int prefixLength = ipAddressRange.GetPrefixLength(); + if (prefixLength != 32) + { + return ipAddressRange.ToCidrString(); + } + } + catch (FormatException) + { + Log.WriteDebug("DisplayIpRange", $"Display as CIDR not possible, so display as range"); + } + return ipAddressRange.ToString(); + } + + public static async Task AddZone(ComplianceNetworkZone networkZone, AdditionsDeletions addDel, ApiConnection apiConnection) + { + var variables = new + { + superNetworkZoneId = networkZone.Superzone?.Id, + name = networkZone.Name, + description = networkZone.Description, + idString = networkZone.IdString, + ipRanges = addDel.IpRangesToAdd.ConvertAll(range => + new + { + ip_range_start = range.Begin.ToString(), + ip_range_end = range.End.ToString(), + criterion_id = networkZone.CriterionId + } + ), + communicationSources = addDel.SourceZonesToAdd.ConvertAll(zone => + new + { + from_network_zone_id = zone.Id, + criterion_id = networkZone.CriterionId + } + ), + communicationDestinations = addDel.DestinationZonesToAdd.ConvertAll(zone => + new + { + to_network_zone_id = zone.Id, + criterion_id = networkZone.CriterionId + } + ), + subNetworkZones = addDel.SubzonesToAdd.ConvertAll(zone => + new + { + id = zone.Id + } + ), + criterionId = networkZone.CriterionId, + isAutoCalculatedInternetZone = networkZone.IsAutoCalculatedInternetZone, + isAutoCalculatedUndefinedInternalZone = networkZone.IsAutoCalculatedUndefinedInternalZone + }; + + await apiConnection.SendQueryAsync(ComplianceQueries.addNetworkZone, variables); + } + + public static async Task UpdateZone(ComplianceNetworkZone networkZone, AdditionsDeletions addDel, ApiConnection apiConnection) + { + var addZoneCommunication = addDel.SourceZonesToAdd.ConvertAll(zone => + new + { + from_network_zone_id = zone.Id, + to_network_zone_id = networkZone.Id, + criterion_id = networkZone.CriterionId + } + ); + addZoneCommunication.AddRange(addDel.DestinationZonesToAdd.ConvertAll(zone => + new + { + from_network_zone_id = networkZone.Id, + to_network_zone_id = zone.Id, + criterion_id = networkZone.CriterionId + } + )); + + var deleteZoneCommunicationExp = addDel.SourceZonesToDelete.ConvertAll(zone => + new + { + from_network_zone_id = new { _eq = zone.Id }, + to_network_zone_id = new { _eq = networkZone.Id }, + criterion_id = new { _eq = networkZone.CriterionId } + } + ); + deleteZoneCommunicationExp.AddRange(addDel.DestinationZonesToDelete.ConvertAll(zone => + new + { + from_network_zone_id = new { _eq = networkZone.Id }, + to_network_zone_id = new { _eq = zone.Id }, + criterion_id = new { _eq = networkZone.CriterionId } + } + )); + + var variables = new + { + networkZoneId = networkZone.Id, + superNetworkZoneId = networkZone.Superzone?.Id, + name = networkZone.Name, + description = networkZone.Description, + addIpRanges = addDel.IpRangesToAdd.ConvertAll(range => + new + { + network_zone_id = networkZone.Id, + ip_range_start = range.Begin.ToString(), + ip_range_end = range.End.ToString(), + criterion_id = networkZone.CriterionId + } + ), + deleteIpRangesExp = addDel.IpRangesToDelete.ConvertAll(range => + new + { + ip_range_start = new { _eq = range.Begin.ToString() }, + ip_range_end = new { _eq = range.End.ToString() }, + criterion_id = new { _eq = networkZone.CriterionId } + } + ), + addSubZonesExp = addDel.SubzonesToAdd.ConvertAll(zone => + new + { + id = new { _eq = zone.Id } + } + ), + deleteSubZonesExp = addDel.SubzonesToDelete.ConvertAll(zone => + new + { + id = new { _eq = zone.Id } + } + ), + addZoneCommunication = addZoneCommunication, + deleteZoneCommunicationExp = deleteZoneCommunicationExp, + removed = DateTime.UtcNow, + isAutoCalculatedInternetZone = networkZone.IsAutoCalculatedInternetZone + }; + + await apiConnection.SendQueryAsync(ComplianceQueries.updateNetworkZone, variables); + } + + public static async Task RemoveZone(ComplianceNetworkZone networkZone, ApiConnection apiConnection) + { + var deleteZoneCommunicationExp = networkZone.AllowedCommunicationSources.ToList().ConvertAll(zone => + new + { + from_network_zone_id = new { _eq = zone.Id }, + to_network_zone_id = new { _eq = networkZone.Id } + } + ); + deleteZoneCommunicationExp.AddRange(networkZone.AllowedCommunicationDestinations.ToList().ConvertAll(zone => + new + { + from_network_zone_id = new { _eq = networkZone.Id }, + to_network_zone_id = new { _eq = zone.Id } + } + )); + var variables = new + { + deleteZoneCommunicationExp = deleteZoneCommunicationExp, + deleteIpRangesExp = networkZone.IPRanges.ToList().ConvertAll(range => + new + { + ip_range_start = new { _eq = range.Begin.ToString() }, + ip_range_end = new { _eq = range.End.ToString() } + } + ), + id = networkZone.Id, + removed = DateTime.UtcNow + }; + await apiConnection.SendQueryAsync(ComplianceQueries.removeNetworkZone, variables); + } + + public static async Task UpdateSpecialZones(int matrixId, ApiConnection apiConnection, GlobalConfig globalConfig) + { + // Get all zones of the matrix. + + List existingZones = await apiConnection.SendQueryAsync>(ComplianceQueries.getNetworkZonesForMatrix, new { criterionId = matrixId }); + + // Remove existing special zones. + + foreach (ComplianceNetworkZone specialZone in existingZones.Where(zone => zone.IsAutoCalculatedInternetZone || zone.IsAutoCalculatedUndefinedInternalZone).ToList()) + { + await RemoveZone(specialZone, apiConnection); + existingZones.Remove(specialZone); + } + + if (globalConfig.AutoCalculateInternetZone) + { + + // Create new undefined-internal zone + + ComplianceNetworkZone undefinedInternalZone = new() + { + IdString = "AUTO_CALCULATED_ZONE_UNDEFINED_INTERNAL", + Name = "Auto-calculated Undefined-internal Zone", + IsAutoCalculatedUndefinedInternalZone = true, + CriterionId = matrixId, + }; + + CalculateUndefinedInternalZone(undefinedInternalZone, GetInternalZoneRanges(globalConfig), existingZones); + + AdditionsDeletions undefinedInternalZoneAddDel = new() + { + IpRangesToAdd = undefinedInternalZone.IPRanges.ToList() + }; + + // Write undefined-internal zone to db if configured + + if (globalConfig.AutoCalculateUndefinedInternalZone) + { + await AddZone(undefinedInternalZone, undefinedInternalZoneAddDel, apiConnection); + } + + // Add undefined-internal zone to reference object (even if AutoCalculatedUndefinedInternalZone is false, because we need it to exclude the reserved ranges from internet zone) + + existingZones.Add(undefinedInternalZone); + + // Add new internet zone + + bool dummyInternetZoneExists = TryUpdateInternetZoneObject(existingZones, matrixId, out ComplianceNetworkZone internetZone); + + CalculateInternetZone(internetZone, existingZones); + + AdditionsDeletions internetZoneAddDel = new() + { + IpRangesToAdd = internetZone.IPRanges.ToList() + }; + + if (dummyInternetZoneExists) + { + await UpdateZone(internetZone, internetZoneAddDel, apiConnection); + } + else + { + await AddZone(internetZone, internetZoneAddDel, apiConnection); + } + + } + } + + private static bool TryUpdateInternetZoneObject(List existingZones, int matrixId, out ComplianceNetworkZone internetZone) + { + bool updated = false; + ComplianceNetworkZone? dummyInternetZone = existingZones.FirstOrDefault(zone => zone.IdString == "AUTO_CALCULATED_ZONE_INTERNET"); + + if (dummyInternetZone == null) + { + internetZone = new() { IdString = "AUTO_CALCULATED_ZONE_INTERNET" }; + } + else + { + updated = true; + internetZone = dummyInternetZone; + } + + internetZone.CriterionId = matrixId; + internetZone.IsAutoCalculatedInternetZone = true; + + if (string.IsNullOrWhiteSpace(internetZone.Name)) + { + internetZone.Name = "Auto-calculated Internet Zone"; + } + + return updated; + } + + public static void CalculateInternetZone(ComplianceNetworkZone internetZone, List excludedZones) + { + IPAddressRange fullRangeIPv4 = IPAddressRange.Parse("0.0.0.0/0"); + + List excludedZonesIPRanges = ParseNetworkZoneToListOfRanges(excludedZones, true); + List internetZoneIPRanges = fullRangeIPv4.Subtract(excludedZonesIPRanges); + + internetZone.IPRanges = internetZoneIPRanges.ToArray(); + } + + public static void CalculateUndefinedInternalZone(ComplianceNetworkZone undefinedInternalZone, List internalZoneRanges, List definedZones) + { + List definedZonesRanges = ParseNetworkZoneToListOfRanges(definedZones, true); + List undefinedInternalZoneRanges = new(); + + foreach (IPAddressRange range in internalZoneRanges) + { + List ranges = range.Subtract(definedZonesRanges); + + foreach (IPAddressRange newRange in ranges) + { + bool add = + // Dont add if exactly this range is already in undefinedInternalZoneRanges + !undefinedInternalZoneRanges.Any(r => r.Begin.Equals(newRange.Begin) && r.End.Equals(newRange.End)) + // Dont add if new range is completely within an existing range + && !undefinedInternalZoneRanges.Any(r => r.Contains(newRange)); + + if (add) + { + undefinedInternalZoneRanges.Add(newRange); + } + } + + } + + undefinedInternalZone.IPRanges = undefinedInternalZoneRanges.ToArray(); + } + + private static List ParseNetworkZoneToListOfRanges(List networkZones, bool sort) + { + List listOfRanges = new(); + + + // Gather ip ranges from excluded network zone list + + foreach (ComplianceNetworkZone networkZone in networkZones) + { + if (networkZone.IPRanges != null) + { + listOfRanges.AddRange(networkZone.IPRanges); + } + } + + // Sort + + if (sort) + { + listOfRanges.Sort(new IPAddressRangeComparer()); + } + + return listOfRanges; + } + + private static List GetInternalZoneRanges(GlobalConfig globalConfig) + { + List internalZoneRanges = new(); + + TryAddToInternalZone(globalConfig.InternalZoneRange_10_0_0_0_8, IpOperations.GetIPAdressRange("10.0.0.0/8"), internalZoneRanges); + TryAddToInternalZone(globalConfig.InternalZoneRange_172_16_0_0_12, IpOperations.GetIPAdressRange("172.16.0.0/12"), internalZoneRanges); + TryAddToInternalZone(globalConfig.InternalZoneRange_192_168_0_0_16, IpOperations.GetIPAdressRange("192.168.0.0/16"), internalZoneRanges); + TryAddToInternalZone(globalConfig.InternalZoneRange_0_0_0_0_8, IpOperations.GetIPAdressRange("0.0.0.0/8"), internalZoneRanges); + TryAddToInternalZone(globalConfig.InternalZoneRange_127_0_0_0_8, IpOperations.GetIPAdressRange("127.0.0.0/8"), internalZoneRanges); + TryAddToInternalZone(globalConfig.InternalZoneRange_169_254_0_0_16, IpOperations.GetIPAdressRange("169.254.0.0/16"), internalZoneRanges); + TryAddToInternalZone(globalConfig.InternalZoneRange_224_0_0_0_4, IpOperations.GetIPAdressRange("224.0.0.0/4"), internalZoneRanges); + TryAddToInternalZone(globalConfig.InternalZoneRange_240_0_0_0_4, IpOperations.GetIPAdressRange("240.0.0.0/4"), internalZoneRanges); + TryAddToInternalZone(globalConfig.InternalZoneRange_255_255_255_255_32, IpOperations.GetIPAdressRange("255.255.255.255/32"), internalZoneRanges); + TryAddToInternalZone(globalConfig.InternalZoneRange_192_0_2_0_24, IpOperations.GetIPAdressRange("192.0.2.0/24"), internalZoneRanges); + TryAddToInternalZone(globalConfig.InternalZoneRange_198_51_100_0_24, IpOperations.GetIPAdressRange("198.51.100.0/24"), internalZoneRanges); + TryAddToInternalZone(globalConfig.InternalZoneRange_203_0_113_0_24, IpOperations.GetIPAdressRange("203.0.113.0/24"), internalZoneRanges); + TryAddToInternalZone(globalConfig.InternalZoneRange_100_64_0_0_10, IpOperations.GetIPAdressRange("100.64.0.0/10"), internalZoneRanges); + TryAddToInternalZone(globalConfig.InternalZoneRange_192_0_0_0_24, IpOperations.GetIPAdressRange("192.0.0.0/24"), internalZoneRanges); + TryAddToInternalZone(globalConfig.InternalZoneRange_192_88_99_0_24, IpOperations.GetIPAdressRange("192.88.99.0/24"), internalZoneRanges); + TryAddToInternalZone(globalConfig.InternalZoneRange_198_18_0_0_15, IpOperations.GetIPAdressRange("198.18.0.0/15"), internalZoneRanges); + + return internalZoneRanges; + } + + private static void TryAddToInternalZone(bool configParameter, IPAddressRange range, List internalZoneRanges) + { + if (configParameter) + { + internalZoneRanges.Add(range); + } + } + } +} diff --git a/roles/lib/files/FWO.Services/ParallelProcessor.cs b/roles/lib/files/FWO.Services/ParallelProcessor.cs new file mode 100644 index 0000000000..4d7a8c81f7 --- /dev/null +++ b/roles/lib/files/FWO.Services/ParallelProcessor.cs @@ -0,0 +1,147 @@ +using FWO.Api.Client; +using FWO.Basics; +using FWO.Basics.Interfaces; + +namespace FWO.Services +{ + public class ParallelProcessor(ApiConnection apiConnection, ILogger logger) + { + private int _elementsCount = 0; + private int _elementsPerFetch = 0; + private int _parallelismLevel = 0; + + public void SetUp(int elementsCount, int parallelismLevel, int elementsPerFetch) + { + _elementsCount = elementsCount; + _parallelismLevel = parallelismLevel; + _elementsPerFetch = elementsPerFetch; + } + + /// + /// Executes a GraphQL query in multiple chunks while respecting a configurable parallelism level. + /// The method throttles concurrency via a semaphore and optionally post-processes each chunk. + /// + /// Element type of each chunk in the result set. + /// GraphQL query to execute. + /// Optional callback invoked for each chunk before returning. + /// Management identifiers passed to the GraphQL query when required. + /// Import identifier that scopes the requested data. + /// Token used to cancel the work, if necessary. + /// All chunk results ordered by their chunk number. + public virtual async Task[]> SendParallelizedQueriesAsync( + string query, + Func, Task>>? postProcessAsync = null, + List? managementIds = null, + long? importId = 0, + CancellationToken cancellationToken = default) + { + if (string.IsNullOrWhiteSpace(query)) + { + throw new ArgumentException("GraphQL query must be provided.", nameof(query)); + } + + if (_elementsCount == 0) + { + return Array.Empty>(); + } + + using SemaphoreSlim semaphore = new(_parallelismLevel, _parallelismLevel); + int chunkCount = (int)Math.Ceiling(_elementsCount / (double)_elementsPerFetch); + List>> tasks = new(chunkCount); + int chunkNumber = 0; + + for (int offset = 0; offset < _elementsCount; offset += _elementsPerFetch) + { + chunkNumber++; + + // Prepare the GraphQL variables for the batch and queue its execution. + + var queryVariables = CreateQueryVariables(offset, _elementsPerFetch, query, managementIds, importId); + tasks.Add(FetchChunkAsync(query, queryVariables, semaphore, chunkNumber, postProcessAsync, cancellationToken)); + } + + return await Task.WhenAll(tasks); + } + + /// + /// Fetches a chunk from the API, optionally post-processes it and enforces the semaphore limit. + /// + public virtual async Task> FetchChunkAsync( + string query, + Dictionary queryVariables, + SemaphoreSlim semaphore, + int chunkNumber, + Func, Task>>? postProcessAsync, + CancellationToken cancellationToken = default) + { + // Limit concurrent requests to the configured parallelism. + + await semaphore.WaitAsync(cancellationToken); + + try + { + cancellationToken.ThrowIfCancellationRequested(); + + // Get chunk data from API. + + List? data = await apiConnection.SendQueryAsync>(query, queryVariables); + data ??= []; + + // Optionally post-process chunk data. + + if (postProcessAsync != null) + { + logger.TryWriteInfo("Parallel Processing", $"Processing chunk {chunkNumber}.", LocalSettings.ComplianceCheckVerbose); + data = await postProcessAsync(data) ?? data; + logger.TryWriteInfo("Parallel Processing", $"Processed chunk {chunkNumber}.", LocalSettings.ComplianceCheckVerbose); + } + + return data; + } + finally + { + semaphore.Release(); + } + } + + /// + /// Creates GraphQL query variables for parallelized queries. + /// + /// Offset used for the chunk. + /// Chunk size. + /// GraphQL query under construction. + /// Management identifiers relevant for the chunk. + /// Import identifier that scopes the data. + protected virtual Dictionary CreateQueryVariables(int offset, int limit, string query, List? relevantManagementIDs = null, long? importId = null) + { + Dictionary queryVariables = new(); + + if (query.Contains(QueryVar.ImportIdStart)) + { + queryVariables[QueryVar.ImportIdStart] = importId ?? 0; + } + + if (query.Contains(QueryVar.ImportIdEnd)) + { + queryVariables[QueryVar.ImportIdEnd] = importId ?? int.MaxValue; + } + + if (query.Contains(QueryVar.Offset)) + { + queryVariables[QueryVar.Offset] = offset; + } + + if (query.Contains(QueryVar.Limit)) + { + queryVariables[QueryVar.Limit] = limit; + } + + if (query.Contains("mgm_ids")) + { + queryVariables["mgm_ids"] = relevantManagementIDs ?? []; + } + + return queryVariables; + } + } +} diff --git a/roles/lib/files/FWO.Services/PathAnalysis.cs b/roles/lib/files/FWO.Services/PathAnalysis.cs new file mode 100644 index 0000000000..24db14386f --- /dev/null +++ b/roles/lib/files/FWO.Services/PathAnalysis.cs @@ -0,0 +1,119 @@ +using FWO.Data; +using FWO.Data.Workflow; +using FWO.Api.Client; +using FWO.Api.Client.Queries; +using FWO.Logging; +using NetTools; +using System.Text.Json.Serialization; +using Newtonsoft.Json; + + +namespace FWO.Services +{ + public enum PathAnalysisOptions + { + WriteToDeviceList, + DisplayFoundDevices + } + + public class PathAnalysisActionParams + { + [JsonProperty("option"), JsonPropertyName("option")] + public PathAnalysisOptions Option { get; set; } = PathAnalysisOptions.DisplayFoundDevices; + } + + + public class PathAnalysis + { + public static async Task GetDeviceNamesForSinglePath(string source, string destination, ApiConnection apiConnection) + { + List deviceList = await AnalyzeSinglePath(source, destination, apiConnection); + + List devNames = []; + foreach (Device dev in deviceList) + { + devNames.Add(dev.Name ?? ""); + } + return string.Join(", ", devNames); + } + + public static async Task> GetAllDevices(List elements, ApiConnection apiConnection) + { + List DevList = []; + + try + { + foreach (var elemPair in AnalyseElements(elements)) + { + List actDevList = []; + actDevList = await AnalyzeSinglePath(elemPair.Key, elemPair.Value, apiConnection); + foreach (var dev in actDevList) + { + if (DevList.FirstOrDefault(x => x.Id == dev.Id) == null) + { + DevList.Add(dev); + } + } + } + } + catch (Exception e) + { + Log.WriteError("Path Analysis", $"error while analysing paths", e); + } + return DevList; + } + + private static List> AnalyseElements(List elements) + { + List> elementPairs = []; + List sources = []; + List destinations = []; + + foreach (var elem in elements) + { + if (elem.Field == ElemFieldType.source.ToString() && elem.Cidr?.CidrString != null) + { + sources.Add(elem.Cidr.CidrString); + } + else if (elem.Field == ElemFieldType.destination.ToString() && elem.Cidr?.CidrString != null) + { + destinations.Add(elem.Cidr.CidrString); + } + } + + foreach (var src in sources) + { + foreach (var dst in destinations) + { + elementPairs.Add(new KeyValuePair(src, dst)); + } + } + return elementPairs; + } + + private static async Task> AnalyzeSinglePath(string source, string destination, ApiConnection apiConnection) + { + List DevList = []; + try + { + IPAddressRange routingSource = IPAddressRange.Parse(source); + IPAddressRange routingDestination = IPAddressRange.Parse(destination); + // we only want cidr + try + { + var Variables = new { src = routingSource.Begin.ToString(), dst = routingDestination.Begin.ToString() }; + DevList = await apiConnection.SendQueryAsync>(NetworkAnalysisQueries.pathAnalysis, Variables); + } + catch (Exception exeption) + { + Log.WriteError("Path Analysis", $"error while analysing path", exeption); + } + } + catch (Exception e) + { + Log.WriteError("Path Analysis", $"no valid ip address", e); + } + return DevList; + } + } +} diff --git a/roles/lib/files/FWO.Services/RuleTreeBuilder/IRuleTreeBuilder.cs b/roles/lib/files/FWO.Services/RuleTreeBuilder/IRuleTreeBuilder.cs new file mode 100644 index 0000000000..9a2d0a098b --- /dev/null +++ b/roles/lib/files/FWO.Services/RuleTreeBuilder/IRuleTreeBuilder.cs @@ -0,0 +1,22 @@ +using FWO.Basics; +using FWO.Data; +using FWO.Data.Report; + +namespace FWO.Services.RuleTreeBuilder +{ + public interface IRuleTreeBuilder + { + RuleTreeItem RuleTree { get; set; } + int CreatedOrderNumbersCount { get; set; } + int OrderedLayerCount { get; set; } + List RemainingLinks { get; set; } + List Rulebases { get; set; } + Dictionary<(int managementId, int deviceId), RuleTreeItem> RuleTreeCache { get; set; } + List BuildRuleTree(RulebaseReport[] rulebases, RulebaseLink[] links, int managementId, int deviceId); + RulebaseLink? GetNextLink(); + List ProcessLink(RulebaseLink link, List? trail = null); + void Reset(RulebaseReport[] rulebases, RulebaseLink[] links); + Dictionary FlattedRules { get; set; } + } +} + diff --git a/roles/lib/files/FWO.Services/RuleTreeBuilder/RuleTreeBuilder.cs b/roles/lib/files/FWO.Services/RuleTreeBuilder/RuleTreeBuilder.cs new file mode 100644 index 0000000000..ae69c506c8 --- /dev/null +++ b/roles/lib/files/FWO.Services/RuleTreeBuilder/RuleTreeBuilder.cs @@ -0,0 +1,443 @@ +using System.Data; +using System.Diagnostics; +using FWO.Basics; +using FWO.Data; +using FWO.Data.Report; +using Rule = FWO.Data.Rule; + +namespace FWO.Services.RuleTreeBuilder +{ + /// + /// Builds a rule tree and order numbers from rulebases and their links. + /// + public class RuleTreeBuilder : IRuleTreeBuilder + { + #region Properties & fields + + /// + /// The root item for the tree structure. + /// + public RuleTreeItem RuleTree { get; set; } = new(); + + /// + /// Cache for generated rule trees. + /// + public Dictionary<(int managementId, int deviceId), RuleTreeItem> RuleTreeCache { get; set; } = new(); + + /// + /// Lookup for flat rule lists of rule tree items + /// + public Dictionary FlattedRules { get; set; } = new(); + + /// + /// The number of order numbers that were created during the process. + /// + public int CreatedOrderNumbersCount { get; set; } + + /// + /// A counter to easily create the order number for the ordered layers on the top level. + /// + public int OrderedLayerCount { get; set; } + + /// + /// Links that are still available to be processed. + /// + public List RemainingLinks { get; set; } = new(); + + /// + /// Rulebases available to the current build. + /// + public List Rulebases { get; set; } = new(); + + /// + /// Inline layer links that are still available to be processed. + /// + public List RemainingInlineLayerLinks { get; set; } = new(); + + #endregion + + #region Constructor + + /// + /// Creates a new builder with an initialized root node. + /// + public RuleTreeBuilder() + { + RuleTree.IsRoot = true; + } + + #endregion + + #region Methods - Public + + /// + /// Builds the rule tree and returns the flattened list of rule data. + /// + public List BuildRuleTree(RulebaseReport[] rulebases, RulebaseLink[] links, int managementId, int deviceId) + { + Reset(rulebases, links); + List? trail = null; + + // Iterate links in processing order to build the tree and order numbers. + + while (GetNextLink() is RulebaseLink nextLink) + { + trail = ProcessLink(nextLink, trail); + } + + // Returns the Rule objects of the flattened rule tree. Will be deprecated as soon as we have the TreeView component. + + List allRules = new(); + + for (int i = 0; i < RuleTree.ElementsFlat.Count; i++) + { + RuleTreeItem treeItem = RuleTree.ElementsFlat[i]; + + if ((treeItem.IsRule || treeItem.IsSectionHeader || treeItem.IsOrderedLayerHeader) && treeItem.Data != null) + { + allRules.Add(treeItem.Data); + } + } + + RuleTreeCache[(managementId, deviceId)] = RuleTree; + FlattedRules[RuleTree] = allRules.ToArray(); + + return allRules; + } + + /// + /// Processes a single link and its rulebase, returning the updated trail. + /// + public List ProcessLink(RulebaseLink link, List? trail = null) + { + // Initialize trail if no trail is provided. + + if (trail == null || link.LinkType == 2) + { + trail = new(); + } + + // Get next rulebase. + + RulebaseReport? rulebase = Rulebases.FirstOrDefault(rb => rb.Id == link.NextRulebaseId); + + if (rulebase == null) + { + throw new InvalidOperationException("Rulebase for link could not be found."); + } + + // Create tree item for the rulebase link type. + + if (link.LinkType == 2) + { + trail = ProcessOrderedLayerLink(link, rulebase, trail); + } + else if (RemainingInlineLayerLinks.Contains(link)) + { + trail = ProcessInlineLayerLink(link, rulebase, trail); + } + else if (link.IsSection) + { + trail = ProcessSectionLink(link, rulebase, trail); + } + else if (link.LinkType == 4) + { + trail = ProcessConcatenationLink(link, rulebase, trail); + } + + // Create tree items for rules and then process inline layers. + + trail = ProcessRulebase(rulebase, link, trail); + + return trail; + } + + /// + /// Processes an inline layer link by adding its root item to the tree. + /// + public List ProcessInlineLayerLink(RulebaseLink link, RulebaseReport rulebase, List trail) + { + RuleTreeItem inlineLayerItem = new RuleTreeItem(); + + inlineLayerItem.Header = rulebase.Name ?? ""; + inlineLayerItem.IsInlineLayerRoot = true; + SetParentForTreeItem(inlineLayerItem, link); + RuleTree.LastAddedItem = inlineLayerItem; + + return trail; + } + + /// + /// Processes a section link by adding a section header rule to the tree. + /// + public List ProcessSectionLink(RulebaseLink link, RulebaseReport rulebase, List trail) + { + RuleTreeItem sectionLinkItem = new(); + + sectionLinkItem.Header = rulebase.Name ?? ""; + sectionLinkItem.IsSectionHeader = true; + SetParentForTreeItem(sectionLinkItem, link); + Rule newRule = new(); + CreatedOrderNumbersCount++; + newRule.OrderNumber = CreatedOrderNumbersCount; + newRule.SectionHeader = rulebase.Name; + sectionLinkItem.Data = newRule; + RuleTree.LastAddedItem = sectionLinkItem; + RuleTree.ElementsFlat.Add(sectionLinkItem); + + return trail; + } + + /// + /// Processes an ordered layer link and adds its header to the tree. + /// + public List ProcessOrderedLayerLink(RulebaseLink link, RulebaseReport rulebase, List trail) + { + RuleTreeItem orderedLayerItem = new(); + + orderedLayerItem.Header = rulebase.Name ?? ""; + orderedLayerItem.IsOrderedLayerHeader = true; + SetParentForTreeItem(orderedLayerItem, link); + Rule newRule = new(); + CreatedOrderNumbersCount++; + newRule.OrderNumber = CreatedOrderNumbersCount; + newRule.SectionHeader = rulebase.Name; + orderedLayerItem.Data = newRule; + trail.Add(GetOrderLayerCount()); + orderedLayerItem.Position = trail.ToList(); + RuleTree.LastAddedItem = orderedLayerItem; + RuleTree.ElementsFlat.Add(orderedLayerItem); + + return trail; + } + + /// + /// Processes a concatenation link (currently handled like a section link). + /// + public List ProcessConcatenationLink(RulebaseLink link, RulebaseReport rulebase, List trail) + { + return ProcessSectionLink(link, rulebase, trail); // TODO: Differentiate between concatenation and section if needed + } + + /// + /// Processes all rules of the rulebase and attaches them to the tree. + /// + public List ProcessRulebase(RulebaseReport rulebase, RulebaseLink link, List trail) + { + if (RuleTree.LastAddedItem != null) + { + RuleTreeItem lastAddedItem = RuleTree.LastAddedItem; + + lastAddedItem.IsExpanded = true; + lastAddedItem.IsVisible = true; + + for (int i = 0; i < rulebase.Rules.Count(); i++) + { + Rule newRule = GetUniqueRuleObject(rulebase.Rules[i]); + + RuleTreeItem ruleItem = new() + { + IsRule = true, + Data = newRule, + IsExpanded = true, + IsVisible = true + }; + + SetParentForTreeItem(ruleItem, link, lastAddedItem); + + trail = EnsureTrailStartsWithZeroForFirstRule(link, lastAddedItem, trail, i); + + // Increment the lowest level for the next rule order number. + + int bottomLevelNumber = trail.Last() + 1; + trail[trail.Count - 1] = bottomLevelNumber; + + newRule.DisplayOrderNumberString = string.Join(".", trail); + ruleItem.Position = trail.ToList(); + CreatedOrderNumbersCount++; + newRule.OrderNumber = CreatedOrderNumbersCount; + + RuleTree.ElementsFlat.Add(ruleItem); + RuleTree.LastAddedItem = ruleItem; + + ProcessInlineLayerLinksForRule(rulebase, i, trail); + } + + RuleTree.LastAddedItem = lastAddedItem; + } + + return trail; + } + + /// + /// Returns the next link to process, preferring initial links. + /// + public RulebaseLink? GetNextLink() + { + // Get initial first + + if (RemainingLinks.Any(link => link.IsInitial)) + { + RulebaseLink initialLink = RemainingLinks.First(link => link.IsInitial); + RemainingLinks.Remove(initialLink); + return initialLink; + } + + // Get next link in line + + RulebaseLink? nextLink = RemainingLinks.FirstOrDefault(); + + if (nextLink != null) + { + RemainingLinks.Remove(nextLink); + } + + return nextLink; + } + + /// + /// Resets all state for a new build. + /// + public void Reset(RulebaseReport[] rulebases, RulebaseLink[] links) + { + RemainingLinks = links.ToList(); + Rulebases = rulebases.ToList(); + RemainingInlineLayerLinks = links.Where(link => link.LinkType == 3).ToList(); + RuleTree = new RuleTreeItem() { IsRoot = true }; + RuleTree.LastAddedItem = RuleTree; + CreatedOrderNumbersCount = 0; + OrderedLayerCount = 0; + FlattedRules.Clear(); + } + + + #endregion + + #region Methods - Private + + /// + /// Ensures a rule with a duplicate ID gets cloned instead of reused. + /// + private Rule GetUniqueRuleObject(Rule rule) + { + if (RuleTree.ElementsFlat.FirstOrDefault(treeItem => treeItem.Data != null && treeItem.Data.Id == rule.Id)?.Data is Rule existingRule) + { + return rule.CreateClone(); + } + else + { + return rule; + } + } + + /// + /// Ensures the trail starts with a zero for the first rule in a sequence. + /// + private List EnsureTrailStartsWithZeroForFirstRule(RulebaseLink link, RuleTreeItem lastAddedItem, List trail, int index) + { + if (index == 0 + && (!(link.LinkType == 4) + || lastAddedItem.Parent?.Children.Count() == 1)) + { + trail = trail.ToList(); + trail.Add(0); + } + + return trail; + } + + /// + /// Processes any inline layer link that starts from the current rule. + /// + private void ProcessInlineLayerLinksForRule(RulebaseReport rulebase, int ruleIndex, List trail) + { + if (RemainingInlineLayerLinks.Any(l => l.LinkType == 3 && l.FromRuleId == rulebase.Rules[ruleIndex].Id)) + { + RulebaseLink inlineLayerLink = RemainingInlineLayerLinks.First(l => l.LinkType == 3 && l.FromRuleId == rulebase.Rules[ruleIndex].Id); + RemainingInlineLayerLinks.Remove(inlineLayerLink); + RemainingLinks.Remove(inlineLayerLink); + List innerTrail = ProcessLink(inlineLayerLink, trail); + + if (RemainingLinks.FirstOrDefault(x => inlineLayerLink.NextRulebaseId == x.FromRulebaseId) != null) + { + RulebaseLink? nextLink = GetNextLink(); + if (nextLink != null) + { + ProcessLink(nextLink, innerTrail); + } + } + } + } + + /// + /// Determines the correct parent for a tree item based on the link type. + /// + private void SetParentForTreeItem(RuleTreeItem item, RulebaseLink link, RuleTreeItem? parentOverride = null) + { + if (item.IsRule && parentOverride != null) + { + SetParentForTreeItem(parentOverride, item); + return; + } + + if (RuleTree.LastAddedItem is RuleTreeItem lastAddedItem && (lastAddedItem.Parent is RuleTreeItem parent || lastAddedItem.IsRoot)) + { + if (RemainingInlineLayerLinks.Contains(link)) + { + SetParentForTreeItem(lastAddedItem, item); + } + else if (link.IsSection) + { + SetParentForSectionTreeItem(lastAddedItem, item); + } + else if (link.LinkType == 2) + { + SetParentForTreeItem(RuleTree, item); + } + else if (link.LinkType == 4 && lastAddedItem.Parent != null) + { + SetParentForTreeItem((RuleTreeItem)lastAddedItem.Parent, item); + } + } + } + + /// + /// Sets the parent for a section item, handling root and section headers. + /// + private void SetParentForSectionTreeItem(RuleTreeItem lastAddedItem, RuleTreeItem item) + { + if (lastAddedItem.IsRoot) + { + SetParentForTreeItem(RuleTree, item); + } + else if (lastAddedItem.IsSectionHeader == true && lastAddedItem.Parent != null) + { + SetParentForTreeItem((RuleTreeItem)lastAddedItem.Parent, item); + } + else + { + SetParentForTreeItem(lastAddedItem, item); + } + } + + /// + /// Assigns parent-child relationship and updates last-added pointer. + /// + private void SetParentForTreeItem(RuleTreeItem parent, RuleTreeItem item) + { + item.Parent = parent; + parent.Children.Add(item); + parent.LastAddedItem = item; + } + + /// + /// Counts top-level ordered layer headers to build their order number. + /// + private int GetOrderLayerCount() + { + return RuleTree.Children.Count(treeItem => ((RuleTreeItem)treeItem).IsOrderedLayerHeader); + } + + #endregion + } +} diff --git a/roles/lib/files/FWO.Services/RuleTreeBuilder/RuleTreeItem.cs b/roles/lib/files/FWO.Services/RuleTreeBuilder/RuleTreeItem.cs new file mode 100644 index 0000000000..b2b18a3ae2 --- /dev/null +++ b/roles/lib/files/FWO.Services/RuleTreeBuilder/RuleTreeItem.cs @@ -0,0 +1,166 @@ +using FWO.Basics; +using FWO.Data; +namespace FWO.Services.RuleTreeBuilder +{ + public class RuleTreeItem : TreeItem + { + #region Properties & fields + + /// + /// Direct Children of this tree item. + /// + new public List Children { get; set; } = new(); + /// + /// The object that is organized with its kins in the tree structure + /// + new public Rule Data { get; set; } = new(); + /// + /// A flat list of every tree item that is somewhere in the tree. + /// + new public List ElementsFlat { get; set; } = new(); + /// + /// Flag to mark items that act as roots of section headers + /// + public bool IsSectionHeader { get; set; } = false; + /// + /// Flag to mark items that are representatives of rules. + /// + public bool IsRule { get; set; } = false; + /// + /// Flag to mark items that act as roots of inline layer + /// + public bool IsInlineLayerRoot { get; set; } = false; + /// + /// Flag to mark items that act as roots of ordered layer headers + /// + public bool IsOrderedLayerHeader { get; set; } = false; + /// + /// Flag to mark items that act as roots of concatenations + /// + public bool IsConcatenationRoot { get; set; } = false; + /// + /// Flag to mark tree items that are expanded + /// + public bool IsExpanded + { + get => _isExpanded; + set + { + _isExpanded = value; + OnIsExpandedChanged(); + } + } + /// + /// Backing field for IsExpanded. + /// + private bool _isExpanded = false; + /// + /// Flag to mark tree items that are visible + /// + public bool IsVisible { get; set; } = true; + /// + /// The last item that was added to the tree. + /// + new public RuleTreeItem? LastAddedItem { get; set; } + /// + /// Direct parent of this tree item. + /// + new public RuleTreeItem? Parent { get; set; } + /// + /// Tree items without children that were reached during the last traversal down. + /// + public List SelectedRuleTreeLeafs { get; set; } = new(); + + #endregion + + #region Methods - Public + + /// + /// A strongly typed version of the generic AddItem method. + /// + public RuleTreeItem AddItem(RuleTreeItem? item = null, List? position = null, string header = "", bool isRoot = false, bool addToFlatList = false, bool addToChildren = false, bool setLastAddedItem = false) + { + return base.AddItem(item ?? new RuleTreeItem(), position, header, isRoot, addToFlatList, addToChildren, + setLastAddedItem) as RuleTreeItem ?? new RuleTreeItem(); + } + + #endregion + + #region Methods - Private + + private void OnIsExpandedChanged() + { + SelectedRuleTreeLeafs.Clear(); + + foreach (RuleTreeItem item in TraverseDown(this)) + { + if (item != this) + { + if (!item.Children.Any()) + { + SelectedRuleTreeLeafs.Add(item); + } + + if (IsExpanded) + { + ExpandItem(item); + } + else + { + item.IsVisible = false; + } + } + } + } + + private void ExpandItem(RuleTreeItem item) + { + if (item != this && item.Parent != null && !item.Parent.IsExpanded) + { + item.IsVisible = false; + } + else + { + item.IsVisible = true; + } + } + + private IEnumerable TraverseDown(RuleTreeItem item, Action? action = null) + { + if (action != null) + { + action(item); + } + + yield return item; + + foreach (RuleTreeItem child in item.Children) + { + foreach (RuleTreeItem descendant in TraverseDown(child)) + { + if (action != null) + { + action(descendant); + } + + yield return descendant; + } + } + } + + private IEnumerable TraverseUp(RuleTreeItem item, Action? action = null) + { + var current = item; + + while (current != null) + { + action?.Invoke(current); + yield return current; + + current = current.Parent; + } + } + + #endregion + } +} diff --git a/roles/lib/files/FWO.Services/ServiceProvider.cs b/roles/lib/files/FWO.Services/ServiceProvider.cs new file mode 100644 index 0000000000..94be8ca5a5 --- /dev/null +++ b/roles/lib/files/FWO.Services/ServiceProvider.cs @@ -0,0 +1,10 @@ +namespace FWO.Services +{ + /// + /// A container for service provider objects to make them accesible globally and facilitate injecting them without using constructors for that. + /// + public static class ServiceProvider + { + public static IServiceProvider? Services { get; set; } + } +} diff --git a/roles/lib/files/FWO.Services/UpdateRuleOwnerMapping.cs b/roles/lib/files/FWO.Services/UpdateRuleOwnerMapping.cs new file mode 100644 index 0000000000..7ac8f341bd --- /dev/null +++ b/roles/lib/files/FWO.Services/UpdateRuleOwnerMapping.cs @@ -0,0 +1,889 @@ +using FWO.Api.Client; +using FWO.Api.Client.Queries; +using FWO.Basics; +using FWO.Config.Api; +using FWO.Data; +using FWO.Logging; +using FWO.Services.EventMediator.Events; +using NetTools; +using System.Net; +using System.Net.Sockets; +using System.Text.Json; + +namespace FWO.Services +{ + public class UpdateRuleOwnerMapping : FWImportChangesNotifierBase + { + private const string LogMessageTitle = "Update rule_owner Notifier"; + protected readonly ApiConnection apiConnection; + protected GlobalConfig globalConfig; + + public UpdateRuleOwnerMapping(ApiConnection apiConnection, GlobalConfig globalConfig) + { + this.apiConnection = apiConnection; + this.globalConfig = globalConfig; + } + + protected override async Task Execute(UpdateRuleOwnerMappingEventArgs? eventArgs = null) + { + await Task.Delay(1000); + + switch ((OwnerMappingSourceStm)globalConfig.OwnerSoruceMappingID) + { + case OwnerMappingSourceStm.IpBased: + return await UpdateRuleOwnersIpBased(eventArgs); + case OwnerMappingSourceStm.CustomField: + return await UpdateRuleOwnersCustomField(eventArgs); + case OwnerMappingSourceStm.NameField: + return false; + case OwnerMappingSourceStm.Manual: + return false; + default: + return false; + } + } + + public async Task HandleEvent(UpdateRuleOwnerMappingEvent evt) + { + try + { + bool success = await Run(evt.EventArgs); + evt.EventArgs.Completion?.SetResult(success); + } + catch (Exception ex) + { + Log.WriteError("UpdateOwnerRuleMappings failed", ex.ToString()); + evt.EventArgs.Completion?.SetException(ex); + } + } + + private static async Task UpdateRuleOwners(Func> fullReinitFunc, Func> incrementalFunc, bool isFullReInitialize) + { + return isFullReInitialize ? await fullReinitFunc() : await incrementalFunc(); + } + + public async Task UpdateRuleOwnersCustomField(UpdateRuleOwnerMappingEventArgs? eventArgs = null) + { + bool isFullReInitialize = eventArgs?.isFullReInitialize ?? false; + return await UpdateRuleOwners(RunFullReinitializeCustomField, RunIncrementalCustomField, isFullReInitialize); + } + + public async Task UpdateRuleOwnersIpBased(UpdateRuleOwnerMappingEventArgs? eventArgs = null) + { + bool isFullReInitialize = eventArgs?.isFullReInitialize ?? false; + return await UpdateRuleOwners(RunFullReinitializeIpBased, RunIncrementalIpBased, isFullReInitialize); + } + + private async Task RunFullReinitializeCustomField() + { + var rulesTask = apiConnection.SendQueryAsync>(RuleQueries.getRulesForOwnerMappingCustomField); + var ownersTask = apiConnection.SendQueryAsync>(OwnerQueries.getOwnersForRuleOwnerCustomField); + await Task.WhenAll(rulesTask, ownersTask); + var rules = rulesTask.Result; + var owners = ownersTask.Result; + + var newRuleOwners = BuildNewRuleOwnersCustomField(rules, owners); + + if (!newRuleOwners.Any()) + { + Log.WriteInfo(LogMessageTitle, "No new rule owners to insert. Aborting import."); + return false; + } + + long importControlId = await CreateImportControl(); + + foreach (RuleOwner ruleOwner in newRuleOwners) + { + ruleOwner.Created = importControlId; + } + + await SetAllActiveRuleOwnersRemoved(importControlId); + await InsertNewRuleOwners(newRuleOwners); + await CompleteImportControlFullReInit(importControlId); + + Log.WriteInfo(LogMessageTitle, "FULL rule_owner reinitialize completed."); + return true; + } + + private async Task RunFullReinitializeIpBased() + { + var rulesTask = apiConnection.SendQueryAsync>(RuleQueries.getRulesForOwnerMappingIpBased); + var ownersTask = apiConnection.SendQueryAsync>(OwnerQueries.getOwnersForRuleOwnerIpBased); + await Task.WhenAll(rulesTask, ownersTask); + var rules = rulesTask.Result; + var owners = ownersTask.Result; + + var newRuleOwners = BuildNewRuleOwnersIpBased(rules, owners); + + if (!newRuleOwners.Any()) + { + Log.WriteInfo(LogMessageTitle, "No new rule owners to insert. Aborting import."); + return false; + } + + long importControlId = await CreateImportControl(); + + foreach (RuleOwner ruleOwner in newRuleOwners) + { + ruleOwner.Created = importControlId; + } + + await SetAllActiveRuleOwnersRemoved(importControlId); + await InsertNewRuleOwners(newRuleOwners); + await CompleteImportControlFullReInit(importControlId); + + Log.WriteInfo(LogMessageTitle, "FULL rule_owner reinitialize completed."); + return true; + } + private async Task RunIncrementalCustomField() + { + var pendingImports = await apiConnection.SendQueryAsync>(ImportQueries.getPendingRuleOwnerImports); + + if (pendingImports == null || !pendingImports.Any()) + { + return false; + } + + foreach (var import in pendingImports.OrderBy(i => i.ControlId)) + { + try + { + await ProcessIncrementalImportCustomField(import); + } + catch (Exception ex) + { + Log.WriteError(LogMessageTitle, $"Error while processing import_control {import.ControlId}. ", ex); + break; + } + } + + return true; + } + private async Task RunIncrementalIpBased() + { + var pendingImports = await apiConnection.SendQueryAsync>(ImportQueries.getPendingRuleOwnerImports); + + if (pendingImports == null || !pendingImports.Any()) + { + return false; + } + + foreach (var import in pendingImports.OrderBy(i => i.ControlId)) + { + try + { + await ProcessIncrementalImportIpBased(import); + } + catch (Exception ex) + { + Log.WriteError(LogMessageTitle, $"Error while processing import_control {import.ControlId}. ", ex); + break; + } + } + + return true; + } + private async Task ProcessIncrementalImportCustomField(ImportControl import) + { + List rulesToMap = new List(); + List owners = new List(); + List ruleOwnersToRemove = new List(); + + switch (import.ImportTypeId) + { + case ImportType.RULE: + { + (rulesToMap, owners, ruleOwnersToRemove) = await HandleRuleImportCustomField(import); + break; + } + case ImportType.OWNER: + { + (rulesToMap, owners, ruleOwnersToRemove) = await HandleOwnerImportCustomField(import); + break; + } + + default: + { + throw new NotSupportedException($"ImportType '{import.ImportTypeId}' is not supported in LoadRulesAndOwnersAsync."); + } + } + + var newRuleOwners = BuildNewRuleOwnersCustomField(rulesToMap, owners); + + foreach (RuleOwner ruleOwner in newRuleOwners) + { + ruleOwner.Created = import.ControlId; + } + + await SetAffectedRuleOwnersRemoved(ruleOwnersToRemove, import.ControlId); + + await InsertNewRuleOwners(newRuleOwners); + + await CompleteImportControl(import.ControlId); + } + + private async Task ProcessIncrementalImportIpBased(ImportControl import) + { + List rulesToMap = new List(); + List owners = new List(); + List ruleOwnersToRemove = new List(); + + switch (import.ImportTypeId) + { + case ImportType.RULE: + { + (rulesToMap, owners, ruleOwnersToRemove) = await HandleRuleImportIpBased(import); + break; + } + case ImportType.OWNER: + { + (rulesToMap, owners, ruleOwnersToRemove) = await HandleOwnerImportIpBased(import); + break; + } + + default: + { + throw new NotSupportedException($"ImportType '{import.ImportTypeId}' is not supported in LoadRulesAndOwnersAsync."); + } + } + + var newRuleOwners = BuildNewRuleOwnersIpBased(rulesToMap, owners); + + foreach (RuleOwner ruleOwner in newRuleOwners) + { + ruleOwner.Created = import.ControlId; + } + + await SetAffectedRuleOwnersRemoved(ruleOwnersToRemove, import.ControlId); + + await InsertNewRuleOwners(newRuleOwners); + + await CompleteImportControl(import.ControlId); + } + + private async Task CreateImportControl() + { + try + { + var result = await apiConnection.SendQueryAsync(ImportQueries.addImportForRuleOwner, new { importTypeId = ImportType.ADMIN_VIA_REINITIALIZE_BTN }); + + var firstControl = result.Returning.FirstOrDefault(); + + if (firstControl == null) + { + Log.WriteError(LogMessageTitle, "No ImportControl returned. Mutation may have failed."); + throw new InvalidOperationException("Failed to create ImportControl. Returning list empty."); + } + + Log.WriteInfo(LogMessageTitle, $"Created new import control with ID {firstControl.ControlId}."); + return firstControl.ControlId; + } + catch (Exception exception) + { + Log.WriteError(LogMessageTitle, "Error while creating a new import control.", exception); + throw; + } + } + + private async Task SetAllActiveRuleOwnersRemoved(long controlId) + { + try + { + await apiConnection.SendQueryAsync(OwnerQueries.setAllActiveRuleOwnersRemoved, new { controlId }); + } + catch (Exception ex) + { + Log.WriteError(LogMessageTitle, "Error while marking all active rule owners as removed.", ex); + throw; + } + } + + private async Task SetAffectedRuleOwnersRemoved(List ruleOwnersToSetRemoved, long importControlId) + { + try + { + if (!ruleOwnersToSetRemoved.Any()) return; + + var listRuleOwnersToRemove = ruleOwnersToSetRemoved + .Select(r => new + { + rule_id = new { _eq = r.RuleId }, + owner_id = new { _eq = r.OwnerId }, + created = new { _eq = r.Created } + }) + .ToList(); + + await apiConnection.SendQueryAsync(OwnerQueries.setAffectedRuleOwnersRemoved, + new + { + objects = listRuleOwnersToRemove, + removed = importControlId + }); + } + catch (Exception ex) + { + Log.WriteError(LogMessageTitle, + "Error while marking affected rule owners as removed.", ex); + throw; + } + } + + public List BuildNewRuleOwnersCustomField(List rulesToMap, List ownersToMap) + { + // create a dictionary for owner name to id mapping for faster lookup + var ownerNameToIdMap = ownersToMap.Where(o => !string.IsNullOrWhiteSpace(o.ExtAppId)) + .ToDictionary(o => o.ExtAppId!, o => o.Id); + var newRuleOwners = new List(); + + // iterate through rules and create new mappings based on CustomFields + foreach (Rule rule in rulesToMap) + { + try + { + var customFieldValue = CustomFieldResolver.ExtractCustomFieldValue(rule, globalConfig.CustomFieldOwnerKey, out _); + + if (!string.IsNullOrWhiteSpace(customFieldValue) && ownerNameToIdMap.TryGetValue(customFieldValue, out var ownerId)) + { + newRuleOwners.Add(new RuleOwner + { + RuleId = rule.Id, + OwnerId = ownerId, + RuleMetadataId = rule.Metadata.Id, + OwnerMappingSourceId = (int)OwnerMappingSourceStm.CustomField + }); + } + } + catch (Exception ex) + { + Log.WriteWarning(LogMessageTitle, $"Rule {rule.Id} has invalid CustomFields: {ex.Message}"); + } + } + return newRuleOwners; + } + + public List BuildNewRuleOwnersIpBased(List rulesToMap, List ownersToMap) + { + var newRuleOwners = new List(); + var ownerNetworksPrepared = PrepareOwnerNetworks(ownersToMap); + + foreach (var rule in rulesToMap) + { + var matchesByOwner = GetMatchingOwnerIds(rule, ownerNetworksPrepared); + + foreach (var matchByOwner in matchesByOwner) + { + var minimalMatchedObjectsForOwner = matchByOwner.Value.ToDictionary( + dirKvp => dirKvp.Key, + dirKvp => dirKvp.Value.Select(o => new + { + o.Id, + o.Name, + o.IP, + o.IpEnd, + OverlappingRanges = o.OverlappingRanges?.Select(r => new + { + Begin = r.Begin.ToString(), + End = r.End.ToString() + }).ToList() + }).ToList() + ); + + newRuleOwners.Add(new RuleOwner + { + RuleId = rule.Id, + OwnerId = matchByOwner.Key, + RuleMetadataId = rule.Metadata.Id, + OwnerMappingSourceId = (int)OwnerMappingSourceStm.IpBased, + MatchedObjects = JsonSerializer.Serialize(minimalMatchedObjectsForOwner) + }); + } + } + + return newRuleOwners; + } + + private async Task InsertNewRuleOwners(List ruleOwners) + { + if (!ruleOwners.Any()) + { + Log.WriteInfo(LogMessageTitle, "No new rule owners to insert."); + return; + } + + try + { + await apiConnection.SendQueryAsync(OwnerQueries.insertRuleOwners, new { objects = ruleOwners }); + Log.WriteInfo(LogMessageTitle, $"{ruleOwners.Count} rule owners inserted successfully."); + } + catch (Exception ex) + { + Log.WriteError(LogMessageTitle, "Error while inserting new rule owners.", ex); + throw; + } + } + + private async Task<(List rulesToMap, List owners, List RuleOwnersToRemove)> HandleRuleImportCustomField(ImportControl import) + { + var changelogRules = await apiConnection.SendQueryAsync>(RuleQueries.getChangedRulesForRuleOwnerMappingCustomField, new { controlId = import.ControlId }); + if (changelogRules == null || !changelogRules.Any()) + { + Log.WriteInfo(LogMessageTitle, "No changed rules found. Aborting incremental import."); + return (new List(), new List(), new List()); + } + + var relevantChanges = changelogRules + .Where(IsOwnerSourceFieldChanged) + .ToList(); + + var rulesToMap = relevantChanges + .Select(c => c.NewRule) + .Where(r => r != null) + .ToList(); + + var rulesToRemove = relevantChanges + .Select(c => c.OldRule) + .Where(r => r != null) + .ToList(); + + var owners = await apiConnection.SendQueryAsync>(OwnerQueries.getOwnersForRuleOwnerCustomField); + + var ruleOwnersToRemove = await apiConnection.SendQueryAsync>(OwnerQueries.getRuleOwnerToRemoveByRule, new { ruleIds = rulesToRemove.Select(r => r.Id).ToList() }); + + return (rulesToMap, owners, ruleOwnersToRemove); + } + private async Task<(List rulesToMap, List owners, List RuleOwnersToRemove)> HandleRuleImportIpBased(ImportControl import) + { + var changelogRules = await apiConnection.SendQueryAsync>(RuleQueries.getChangedRulesForRuleOwnerMappingIpBased, new { controlId = import.ControlId }); + if (changelogRules == null || !changelogRules.Any()) + { + Log.WriteInfo(LogMessageTitle, "No changed rules found. Aborting incremental import."); + return (new List(), new List(), new List()); + } + + var relevantChanges = changelogRules + .Where(IsIpBasedObjectChanged) + .ToList(); + + var rulesToMap = relevantChanges + .Select(c => c.NewRule) + .Where(r => r != null) + .ToList(); + + var rulesToRemove = relevantChanges + .Select(c => c.OldRule) + .Where(r => r != null) + .ToList(); + + var owners = await apiConnection.SendQueryAsync>(OwnerQueries.getOwnersForRuleOwnerIpBased); + + var ruleOwnersToRemove = await apiConnection.SendQueryAsync>(OwnerQueries.getRuleOwnerToRemoveByRule, new { ruleIds = rulesToRemove.Select(r => r.Id).ToList() }); + + return (rulesToMap, owners, ruleOwnersToRemove); + } + + private static bool IsIpBasedObjectChanged(RuleChange ruleChange) + { + var oldRule = ruleChange.OldRule; + var newRule = ruleChange.NewRule; + + if (IsObjectListChanged(oldRule?.Tos, newRule?.Tos)) + { + return true; + } + + if (IsObjectListChanged(oldRule?.Froms, newRule?.Froms)) + { + return true; + } + return false; + } + + private static bool IsObjectListChanged(NetworkLocation[]? oldList, NetworkLocation[]? newList) + { + oldList ??= Array.Empty(); + newList ??= Array.Empty(); + + if (oldList.Length != newList.Length) + { + return true; + } + + return oldList + .Where(o => o.Object != null) + .Any(oldEntry => !newList + .Any(n => n.Object != null && + n.Object.Id == oldEntry.Object.Id && + n.Object.IP == oldEntry.Object.IP && + n.Object.IpEnd == oldEntry.Object.IpEnd)); + } + + public bool IsOwnerSourceFieldChanged(RuleChange ruleChange) + { + var oldFields = DeserializeCustomFields(ruleChange.OldRule?.CustomFields); + var newFields = DeserializeCustomFields(ruleChange.NewRule?.CustomFields); + + var ownerKeys = JsonSerializer.Deserialize(globalConfig.CustomFieldOwnerKey) ?? Array.Empty(); + + foreach (var key in ownerKeys) + { + oldFields.TryGetValue(key, out var oldValue); + newFields.TryGetValue(key, out var newValue); + + if (!string.Equals(oldValue, newValue, StringComparison.Ordinal)) + return true; + } + + return false; + } + + public static Dictionary DeserializeCustomFields(string? raw) + { + if (string.IsNullOrWhiteSpace(raw)) + { + return new(); + } + + try + { + return JsonSerializer.Deserialize>(raw.Replace("'", "\"")) ?? new(); + } + catch (JsonException) + { + return new(); + } + } + + private async Task<(List RulesToMap, List owners, List RuleOwnersToRemove)> HandleOwnerImportCustomField(ImportControl import) + { + var changelogOwners = await apiConnection.SendQueryAsync>(OwnerQueries.getChangedOwnersForRuleOwnerMappingCustomField, new { controlId = import.ControlId }); + + var ownersToAdd = new List(); + var ownersToRemove = new List(); + var ownersToUpdate = new List(); + + var rulesToMap = new List(); + var ruleOwnersToRemove = new List(); + + if (!ProcessOwnerChanges(changelogOwners, ownersToAdd, ownersToRemove, ownersToUpdate)) + { + return (new List(), new List(), new List()); + } + + if (ownersToAdd.Any()) + { + rulesToMap = await apiConnection.SendQueryAsync>(RuleQueries.getRulesForRuleOwnerCustomField); + } + else if (ownersToUpdate.Any()) + { + rulesToMap = await apiConnection.SendQueryAsync>(RuleQueries.getRulesForRuleOwnerByOwnerToUpdateCustomField, new { ownerIds = ownersToUpdate.Select(o => o.Id).ToList() }); + } + if (ownersToRemove.Any()) + { + ruleOwnersToRemove = await apiConnection.SendQueryAsync>(OwnerQueries.getRuleOwnerToRemoveByOwner, new { ownerIds = ownersToRemove.Select(o => o.Id).ToList() }); + } + return (rulesToMap, ownersToAdd.Concat(ownersToUpdate).ToList(), ruleOwnersToRemove); + } + + private async Task<(List RulesToMap, List owners, List RuleOwnersToRemove)> HandleOwnerImportIpBased(ImportControl import) + { + var changelogOwners = await apiConnection.SendQueryAsync>(OwnerQueries.getChangedOwnersForRuleOwnerMappingIpBased, new { controlId = import.ControlId }); + var ownersToAdd = new List(); + var ownersToRemove = new List(); + var ruleOwnersToRemove = new List(); + var rulesToMap = new List(); + + if (!ProcessOwnerChanges(changelogOwners, ownersToAdd, ownersToRemove, new List(), true)) + { + return (new List(), new List(), new List()); + } + + if (ownersToAdd.Any()) + { + rulesToMap = await apiConnection.SendQueryAsync>(RuleQueries.getRulesForRuleOwnerIpBased); + } + + if (ownersToRemove.Any()) + { + ruleOwnersToRemove = await apiConnection.SendQueryAsync>(OwnerQueries.getRuleOwnerToRemoveByOwner, new { ownerIds = ownersToRemove.Select(o => o.Id).ToList() }); + } + return (rulesToMap, ownersToAdd, ruleOwnersToRemove); + } + + private static bool ProcessOwnerChanges(List changelogOwners, List ownersToAdd, List ownersToRemove, List ownersToUpdate, bool changeMeansAddAndRemove = false) + { + if (changelogOwners == null || !changelogOwners.Any()) + { + Log.WriteInfo(LogMessageTitle, "No changed rules found. Aborting incremental import."); + return false; + } + foreach (var change in changelogOwners) + { + switch (change.ChangeAction) + { + case ChangelogActionType.INSERT: + case ChangelogActionType.REACTIVATE: + ownersToAdd.Add(change.NewOwner); + break; + + case ChangelogActionType.DELETE: + case ChangelogActionType.DEACTIVATE: + ownersToRemove.Add(change.OldOwner); + break; + + case ChangelogActionType.CHANGE: + if (changeMeansAddAndRemove) + { + ownersToAdd.Add(change.NewOwner); + ownersToRemove.Add(change.NewOwner); + } + else + { + ownersToUpdate.Add(change.NewOwner); + } + break; + } + } + + return true; + } + + private async Task CompleteImportControl(long importControlId) + { + try + { + await apiConnection.SendQueryAsync(ImportQueries.updateImportControlForRuleOwnerInc, + new + { + controlId = importControlId, + rule_owner_mapping_done = true + } + ); + Log.WriteInfo(LogMessageTitle, $"Import control {importControlId} completed successfully."); + } + catch (Exception ex) + { + Log.WriteError(LogMessageTitle, "Error while updating import control completion status.", ex); + } + } + + private async Task CompleteImportControlFullReInit(long importControlId) + { + try + { + await apiConnection.SendQueryAsync(ImportQueries.updateImportControlForRuleOwnerFull, + new + { + controlId = importControlId, + stopTime = DateTime.UtcNow, + successful = true, + rule_owner_mapping_done = true + }); + + Log.WriteInfo(LogMessageTitle, $"Import control {importControlId} completed successfully."); + + await CompleteOlderPendingImports(importControlId); + } + catch (Exception ex) + { + Log.WriteError(LogMessageTitle, "Error while updating import control completion status.", ex); + } + } + + private async Task CompleteOlderPendingImports(long referenceControlId) + { + var pendingImports = await apiConnection.SendQueryAsync>(ImportQueries.getPendingRuleOwnerImports); + + if (pendingImports == null || !pendingImports.Any()) + { + return; + } + + var olderImports = pendingImports.Where(i => i.ControlId < referenceControlId); + + foreach (var import in olderImports) + { + try + { + await apiConnection.SendQueryAsync(ImportQueries.updateImportControlForRuleOwnerInc, + new + { + controlId = import.ControlId, + rule_owner_mapping_done = true + }); + + Log.WriteInfo(LogMessageTitle, $"Older import control {import.ControlId} marked as rule_owner_mapping_done."); + } + catch (Exception ex) + { + Log.WriteError(LogMessageTitle, $"Error while updating older import_control {import.ControlId}.", ex); + } + } + } + + public static (IPAddressRange? range, AddressFamily? ipVersion) GetIpRangeAndVersion(string ipStart, string ipEnd) + { + var start = ipStart.StripOffUnnecessaryNetmask(); + var end = ipEnd.StripOffUnnecessaryNetmask(); + + if (!IPAddress.TryParse(start, out var startIp)) + { + Log.WriteError(LogMessageTitle, $"Invalid start IP: {start}"); + return (null, null); + } + + if (!IPAddress.TryParse(end, out var endIp)) + { + Log.WriteError(LogMessageTitle, $"Invalid end IP: {end}"); + return (null, null); + } + + if (startIp.AddressFamily != endIp.AddressFamily) + { + Log.WriteError(LogMessageTitle, $"IP families do not match: {start}-{end}"); + return (null, null); + } + + // compare start and end IPs to ensure start is less than or equal to end + int cmp = 0; + if (startIp.AddressFamily == AddressFamily.InterNetwork) + { + cmp = IpOperations.IpToUint(startIp).CompareTo(IpOperations.IpToUint(endIp)); + } + else if (startIp.AddressFamily == AddressFamily.InterNetworkV6) + { + cmp = IpOperations.ToBigInteger(startIp).CompareTo(IpOperations.ToBigInteger(endIp)); + } + else + { + Log.WriteError(LogMessageTitle, "Unsupported AddressFamily"); + return (null, null); + } + + if (cmp > 0) + { + Log.WriteError(LogMessageTitle, $"Invalid range: {start}-{end} (start > end)"); + return (null, null); + } + + var range = IpOperations.GetIPAdressRange($"{start}-{end}"); + return (range, range.Begin.AddressFamily); + } + + public List PrepareOwnerNetworks(List ownersToMap) + { + return ownersToMap + .Where(o => o.OwnerNetworks != null && o.OwnerNetworks.Any()) + .Select(o => new OwnerNetworkPrepared + { + OwnerId = o.Id, + Ranges = o.OwnerNetworks + .Where(nw => !string.IsNullOrWhiteSpace(nw.IP) && !string.IsNullOrWhiteSpace(nw.IpEnd)) + .Select(nw => + { + if (!nw.IP.TryParseIPStringToRange(out var _)) + { + Console.WriteLine($"Ungueltige IP in Regel {o.Id}: {nw.IP} - {nw.IpEnd}"); + } + + var (range, version) = GetIpRangeAndVersion(nw.IP, nw.IpEnd); + + if (range == null || version == null) + { + Log.WriteWarning(LogMessageTitle, $"Skipping invalid owner network: {nw.IP}-{nw.IpEnd} for Owner {o.Id}"); + return null; + } + + return new OwnerRange + { + Range = range, + IpVersion = version + }; + }) + .Where(x => x != null) + .ToList() + }) + .ToList(); + } + + public static Dictionary>> GetMatchingOwnerIds(Rule rule, List ownerNetworksPrepared) + { + var matchesByOwner = new Dictionary>>(); + + var ruleNetworksWithDirections = rule.Froms.Where(n => n?.Object != null).Select(n => (Obj: n.Object!, Direction: "From")) + .Concat + (rule.Tos.Where(n => n?.Object != null).Select(n => (Obj: n.Object!, Direction: "To"))).ToList(); + + if (!ruleNetworksWithDirections.Any()) + { + Log.WriteWarning(LogMessageTitle, $"Rule {rule.Id} has no network locations and will be skipped."); + return matchesByOwner; + } + + // Iterate through each network location of the rule + foreach (var (obj, direction) in ruleNetworksWithDirections) + { + if (obj == null || string.IsNullOrWhiteSpace(obj.IP) || string.IsNullOrWhiteSpace(obj.IpEnd)) + { + continue; + } + + var (ruleRange, ruleIpVersion) = GetIpRangeAndVersion(obj.IP, obj.IpEnd); + + if (ruleRange == null || ruleIpVersion == null) + { + continue; + } + + foreach (var owner in ownerNetworksPrepared) + { + var overlappingRanges = owner.Ranges + .Where(r => r != null && r.IpVersion == ruleIpVersion) + .Select(r => IpOperations.GetIntersection(ruleRange, r!.Range)) + .Where(intersection => intersection != null) + .ToList(); + + if (!overlappingRanges.Any()) + { + continue; + } + + if (!matchesByOwner.TryGetValue(owner.OwnerId, out var dictForOwner)) + { + dictForOwner = new Dictionary>(); + matchesByOwner[owner.OwnerId] = dictForOwner; + } + + if (!dictForOwner.ContainsKey(direction)) + { + dictForOwner[direction] = new List(); + } + + dictForOwner[direction].Add(new NetworkObject + { + Id = obj.Id, + Name = obj.Name, + IP = obj.IP, + IpEnd = obj.IpEnd, + OverlappingRanges = overlappingRanges + .Where(r => r != null) + .Select(r => r!) + .ToList() + }); + } + } + return matchesByOwner; + } + + public class OwnerNetworkPrepared + { + public int OwnerId { get; set; } + public List Ranges { get; set; } = new List(); + } + + public class OwnerRange + { + public IPAddressRange Range { get; set; } = default!; + public AddressFamily? IpVersion { get; set; } + } + } +} diff --git a/roles/lib/files/FWO.Services/Workflow/ActionHandler.cs b/roles/lib/files/FWO.Services/Workflow/ActionHandler.cs new file mode 100644 index 0000000000..b3be148e63 --- /dev/null +++ b/roles/lib/files/FWO.Services/Workflow/ActionHandler.cs @@ -0,0 +1,545 @@ +using FWO.Api.Client; +using FWO.Api.Client.Queries; +using FWO.Basics; +using FWO.Data; +using FWO.Data.Modelling; +using FWO.Data.Workflow; +using FWO.Logging; +using FWO.Services.Modelling; +using System.Text.Json; + + +namespace FWO.Services.Workflow +{ + public class ActionHandler + { + private List states = []; + private readonly ApiConnection apiConnection; + private readonly WfHandler wfHandler; + private readonly bool useInMwServer = false; + private readonly IRequestedRulePolicyChecker? requestedRulePolicyChecker; + private string? ScopedUserTo { get; set; } = ""; + private string? ScopedUserCc { get; set; } = ""; + public bool DisplayConnectionMode = false; + public ModellingConnectionHandler? ConnHandler { get; set; } + private readonly List? UserGroups = []; + private readonly string NoAuthUser = "No Auth User"; + + + public ActionHandler(ApiConnection apiConnection, WfHandler wfHandler, List? userGroups = null, bool useInMwServer = false, + IRequestedRulePolicyChecker? requestedRulePolicyChecker = null) + { + this.apiConnection = apiConnection; + this.wfHandler = wfHandler; + this.useInMwServer = useInMwServer; + UserGroups = userGroups; + this.requestedRulePolicyChecker = requestedRulePolicyChecker ?? wfHandler.RequestedRulePolicyChecker; + } + + public async Task Init() + { + states = await apiConnection.SendQueryAsync>(RequestQueries.getStates); + } + + public List GetOfferedActions(WfStatefulObject statefulObject, WfObjectScopes scope, WorkflowPhases phase) + { + List offeredActions = []; + List stateActions = GetRelevantActions(statefulObject, scope); + foreach (var action in stateActions.Where(x => x.Event == StateActionEvents.OfferButton.ToString())) + { + if (action.Phase == "" || action.Phase == phase.ToString()) + { + offeredActions.Add(action); + } + } + return offeredActions; + } + + public async Task DoStateChangeActions(WfStatefulObject statefulObject, WfObjectScopes scope, FwoOwner? owner = null, long? ticketId = null, string? userGrpDn = null) + { + if (statefulObject.StateChanged()) + { + List stateActions = GetRelevantActions(statefulObject, scope); + foreach (var action in stateActions.Where(x => x.Event == StateActionEvents.OnSet.ToString())) + { + if (action.Phase == "" || action.Phase == wfHandler.Phase.ToString()) + { + await PerformAction(action, statefulObject, scope, owner, ticketId, userGrpDn); + } + } + List fromStateActions = GetRelevantActions(statefulObject, scope, false); + foreach (var action in fromStateActions.Where(x => x.Event == StateActionEvents.OnLeave.ToString())) + { + if (action.Phase == "" || action.Phase == wfHandler.Phase.ToString()) + { + await PerformAction(action, statefulObject, scope, owner, ticketId, userGrpDn); + } + } + statefulObject.ResetStateChanged(); + } + } + + public async Task DoOwnerChangeActions(WfStatefulObject statefulObject, FwoOwner? owner, long ticketId) + { + List ownerChangeActions = GetRelevantActions(statefulObject, WfObjectScopes.None); + foreach (var action in ownerChangeActions.Where(x => x.Event == StateActionEvents.OwnerChange.ToString())) + { + await PerformAction(action, statefulObject, WfObjectScopes.None, owner, ticketId); + } + } + + public async Task DoOnAssignmentActions(WfStatefulObject statefulObject, string? userGrpDn) + { + List assignmentActions = GetRelevantActions(statefulObject, WfObjectScopes.None); + foreach (var action in assignmentActions.Where(x => x.Event == StateActionEvents.OnAssignment.ToString())) + { + await PerformAction(action, statefulObject, WfObjectScopes.None, null, null, userGrpDn); + } + } + + public async Task PerformAction(WfStateAction action, WfStatefulObject statefulObject, WfObjectScopes scope, + FwoOwner? owner = null, long? ticketId = null, string? userGrpDn = null) + { + switch (action.ActionType) + { + case nameof(StateActionTypes.AutoPromote): + int? toState = await GetAutoPromoteTargetState(action.ExternalParams, statefulObject, scope); + if (toState == null || states.FirstOrDefault(x => x.Id == toState) != null) + { + await wfHandler.AutoPromote(statefulObject, scope, toState); + } + break; + case nameof(StateActionTypes.AddApproval): + await SetScope(statefulObject, scope); + await wfHandler.AddApproval(action.ExternalParams); + break; + case nameof(StateActionTypes.SetAlert): + await SetAlert(action.ExternalParams); + break; + case nameof(StateActionTypes.TrafficPathAnalysis): + await SetScope(statefulObject, scope); + await wfHandler.HandlePathAnalysisAction(action.ExternalParams); + break; + case nameof(StateActionTypes.ExternalCall): + await CallExternal(action); + break; + case nameof(StateActionTypes.SendEmail): + await SendEmail(action, statefulObject, scope, owner, userGrpDn); + break; + case nameof(StateActionTypes.UpdateConnectionOwner): + await UpdateConnectionOwner(owner, ticketId); + break; + case nameof(StateActionTypes.UpdateConnectionRelease): + await UpdateConnectionPublish(owner, ticketId); + break; + case nameof(StateActionTypes.UpdateConnectionReject): + await UpdateConnectionReject(owner, ticketId); + break; + case nameof(StateActionTypes.DisplayConnection): + await DisplayConnection(statefulObject, scope); + break; + default: + break; + } + } + + public async Task CallExternal(WfStateAction action) + { + // call external APIs with ExternalParams, e.g. for Compliance Check + } + + public async Task SendEmail(WfStateAction action, WfStatefulObject statefulObject, WfObjectScopes scope, FwoOwner? owner, string? userGrpDn = null) + { + Log.WriteDebug("SendEmail", "Perform Action"); + try + { + EmailActionParams emailActionParams = System.Text.Json.JsonSerializer.Deserialize(action.ExternalParams) ?? throw new JsonException("Extparams could not be parsed."); + await SetScope(statefulObject, scope, emailActionParams); + EmailHelper emailHelper = new(apiConnection, wfHandler.MiddlewareClient, wfHandler.userConfig, DefaultInit.DoNothing, UserGroups, useInMwServer); + await emailHelper.Init(ScopedUserTo, ScopedUserCc); + if (owner != null) + { + await emailHelper.SendOwnerEmailFromAction(emailActionParams, statefulObject, owner); + } + else if (userGrpDn != null) + { + await emailHelper.SendUserEmailFromAction(emailActionParams, statefulObject, userGrpDn); + } + } + catch (Exception exc) + { + Log.WriteError("Send Email", $"Could not send email: ", exc); + } + } + + public async Task UpdateConnectionOwner(FwoOwner? owner, long? ticketId) + { + Log.WriteDebug("UpdateConnectionOwner", "Perform Action"); + try + { + if (owner != null && ticketId != null) // todo: role check + { + await apiConnection.RunWithProperRole(wfHandler.AuthUser ?? throw new ArgumentException(NoAuthUser), [Roles.Modeller, Roles.Admin], async () => + { + List Connections = await apiConnection.SendQueryAsync>(ModellingQueries.getConnectionsByTicketId, new { ticketId }); + foreach (var conn in Connections) + { + if (conn.IsRequested) + { + var Variables = new + { + id = conn.Id, + propAppId = owner.Id + }; + await apiConnection.SendQueryAsync(ModellingQueries.updateProposedConnectionOwner, Variables); + await ModellingHandlerBase.LogChange(new LogChangeRequest + { + ChangeType = ModellingTypes.ChangeType.Update, + ObjectType = ModellingTypes.ModObjectType.Connection, + ObjectId = conn.Id, + Text = $"Updated {(conn.IsInterface ? "Interface" : "Connection")}: {conn.Name}", + ApiConnection = apiConnection, + UserConfig = wfHandler.userConfig, + ApplicationId = owner.Id, + DisplayMessageInUi = DefaultInit.DoNothing + }); + } + } + }); + } + } + catch (Exception exc) + { + Log.WriteError("Update Connection Owner", $"Could not change owner: ", exc); + } + } + + public async Task UpdateConnectionPublish(FwoOwner? owner, long? ticketId) + { + Log.WriteDebug("UpdateConnectionPublish", "Perform Action"); + try + { + if (owner != null && ticketId != null) // todo: role check + { + await apiConnection.RunWithProperRole(wfHandler.AuthUser ?? throw new ArgumentException(NoAuthUser), [Roles.Modeller, Roles.Admin], async () => + { + List Connections = await apiConnection.SendQueryAsync>(ModellingQueries.getConnectionsByTicketId, new { ticketId }); + foreach (var conn in Connections) + { + if (conn.IsRequested && !conn.IsPublished) + { + await PublishInterface(conn, owner); + } + } + }); + } + } + catch (Exception exc) + { + Log.WriteError("Update Connection Publish", $"Could not publish connection: ", exc); + } + } + + private async Task PublishInterface(ModellingConnection conn, FwoOwner owner) + { + if (conn.AppId == null && conn.ProposedAppId != null) + { + conn.AppId = conn.ProposedAppId; + conn.ProposedAppId = null; + } + var Variables = new + { + id = conn.Id, + isRequested = false, + isPublished = true, + appId = conn.AppId, + proposedAppId = conn.ProposedAppId + }; + await apiConnection.SendQueryAsync(ModellingQueries.updateConnectionPublish, Variables); + await ModellingHandlerBase.LogChange(new LogChangeRequest + { + ChangeType = ModellingTypes.ChangeType.Publish, + ObjectType = ModellingTypes.ModObjectType.Connection, + ObjectId = conn.Id, + Text = $"Published {(conn.IsInterface ? "Interface" : "Connection")}: {conn.Name}", + ApiConnection = apiConnection, + UserConfig = wfHandler.userConfig, + ApplicationId = owner.Id, + DisplayMessageInUi = DefaultInit.DoNothing + }); + } + + public async Task UpdateConnectionReject(FwoOwner? owner, long? ticketId) + { + Log.WriteDebug("UpdateConnectionReject", "Perform Action"); + try + { + if (owner != null && ticketId != null) + { + await apiConnection.RunWithProperRole(wfHandler.AuthUser ?? throw new ArgumentException(NoAuthUser), [Roles.Modeller, Roles.Admin], async () => + { + List Connections = await apiConnection.SendQueryAsync>(ModellingQueries.getConnectionsByTicketId, new { ticketId }); + foreach (var conn in Connections) + { + if (conn.IsRequested) + { + conn.AddProperty(ConState.Rejected.ToString()); + var Variables = new + { + id = conn.Id, + connProp = conn.Properties + }; + await apiConnection.SendQueryAsync(ModellingQueries.updateConnectionProperties, Variables); + await ModellingHandlerBase.LogChange(new LogChangeRequest + { + ChangeType = ModellingTypes.ChangeType.Reject, + ObjectType = ModellingTypes.ModObjectType.Connection, + ObjectId = conn.Id, + Text = $"Rejected {(conn.IsInterface ? "Interface" : "Connection")}: {conn.Name}", + ApiConnection = apiConnection, + UserConfig = wfHandler.userConfig, + ApplicationId = owner.Id, + DisplayMessageInUi = DefaultInit.DoNothing + }); + } + } + }); + } + } + catch (Exception exc) + { + Log.WriteError("Reject Connection", $"Could not change state: ", exc); + } + } + + public async Task DisplayConnection(WfStatefulObject statefulObject, WfObjectScopes scope) + { + try + { + Log.WriteDebug("DisplayConnection", "Perform Action"); + await SetScope(statefulObject, scope); + WfReqTask? reqTask = wfHandler.ActTicket.Tasks.FirstOrDefault(x => x.TaskType == WfTaskType.new_interface.ToString()); + if (reqTask != null) + { + wfHandler.SetReqTaskEnv(reqTask); + } + FwoOwner? owner = wfHandler.ActReqTask.Owners?.FirstOrDefault()?.Owner; + if (owner != null && wfHandler.ActReqTask.GetAddInfoIntValue(AdditionalInfoKeys.ConnId) != null) + { + await apiConnection.RunWithProperRole(wfHandler.AuthUser ?? throw new ArgumentException(NoAuthUser), [Roles.Modeller, Roles.Admin, Roles.Auditor], async () => + { + List Connections = await apiConnection.SendQueryAsync>(ModellingQueries.getConnections, new { appId = owner.Id }); + ModellingConnection? conn = Connections.FirstOrDefault(c => c.Id == wfHandler.ActReqTask.GetAddInfoIntValue(AdditionalInfoKeys.ConnId)); + if (conn != null) + { + ConnHandler = new ModellingConnectionHandler(apiConnection, wfHandler.userConfig, owner, Connections, conn, false, true, DefaultInit.DoNothing, DefaultInit.DoNothing, false); + await ConnHandler.Init(); + DisplayConnectionMode = true; + } + }); + } + } + catch (Exception exc) + { + Log.WriteError("Display Connection", $"Could not display: ", exc); + } + } + + public async Task SetAlert(string? description) + { + try + { + var Variables = new + { + source = "workflow", + userId = 0, + title = "Workflow state alert", + description = description, + alertCode = (int)AlertCode.WorkflowAlert + }; + await apiConnection.SendQueryAsync(MonitorQueries.addAlert, Variables); + Log.WriteAlert($"source: \"workflow\"", + $"userId: \"0\", title: \"Workflow state alert\", description: \"{description}\", " + + $"alertCode: \"{AlertCode.WorkflowAlert}\""); + } + catch (Exception exc) + { + Log.WriteError("Write Alert", $"Could not write Alert for Workflow: ", exc); + } + } + + private async Task GetAutoPromoteTargetState(string externalParams, WfStatefulObject statefulObject, WfObjectScopes scope) + { + if (!WfStateAction.TryParseAutoPromoteParams(externalParams, out int? toState, out ConditionalAutoPromoteParams? conditionalParams)) + { + throw new JsonException("Extparams could not be parsed."); + } + + if (conditionalParams == null) + { + return toState; + } + + return await EvaluateConditionalAutoPromote(conditionalParams, statefulObject, scope) ? conditionalParams.IfCompliantState : conditionalParams.IfNotCompliantState; + } + + private Task EvaluateConditionalAutoPromote(ConditionalAutoPromoteParams conditionalParams, WfStatefulObject statefulObject, WfObjectScopes scope) + { + return conditionalParams.ToBeCalled switch + { + ToBeCalled.PolicyCheck => ExecutePolicyCheck(conditionalParams.PolicyIds, conditionalParams.CheckResultLabel, statefulObject, scope), + _ => Task.FromResult(false) + }; + } + + private async Task ExecutePolicyCheck(IEnumerable selectedPolicyIds, string checkResultLabel, WfStatefulObject statefulObject, WfObjectScopes scope) + { + try + { + List requestedRuleTasks = GetRequestedRuleTasksForCallingTicket(statefulObject, scope); + if (requestedRuleTasks.Count == 0) + { + return false; + } + + if (requestedRulePolicyChecker == null) + { + return false; + } + + bool isCompliant = await requestedRulePolicyChecker.AreRequestTasksCompliant(selectedPolicyIds, requestedRuleTasks); + await AttachPolicyCheckResultLabel(requestedRuleTasks, checkResultLabel, isCompliant); + return isCompliant; + } + catch (Exception exc) + { + Log.WriteError("Policy Check", "Conditional compliance evaluation failed.", exc); + return false; + } + } + + private async Task AttachPolicyCheckResultLabel(IEnumerable requestTasks, string checkResultLabel, bool isCompliant) + { + if (string.IsNullOrWhiteSpace(checkResultLabel)) + { + return; + } + + foreach (WfReqTask requestTask in requestTasks) + { + await wfHandler.SetAddInfoInReqTask(requestTask, checkResultLabel.Trim(), isCompliant.ToString().ToLowerInvariant()); + } + } + + private List GetRequestedRuleTasksForCallingTicket(WfStatefulObject statefulObject, WfObjectScopes scope) + { + WfTicket? ticket = GetCallingTicket(statefulObject, scope); + if (ticket == null) + { + return []; + } + + return ticket.Tasks + .Where(task => task.ManagementId != null) + .Where(task => task.GetNwObjectElements(ElemFieldType.source).Count > 0) + .Where(task => task.GetNwObjectElements(ElemFieldType.destination).Count > 0) + .Where(task => task.GetServiceElements().Count > 0) + .ToList(); + } + + private WfTicket? GetCallingTicket(WfStatefulObject statefulObject, WfObjectScopes scope) + { + if (scope == WfObjectScopes.Ticket && statefulObject is WfTicket ticket) + { + return ticket; + } + + if (wfHandler.ActTicket.Tasks.Count > 0) + { + return wfHandler.ActTicket; + } + + return scope switch + { + WfObjectScopes.RequestTask when statefulObject is WfReqTask reqTask => new WfTicket { Tasks = [reqTask] }, + WfObjectScopes.ImplementationTask when wfHandler.ActReqTask.Id > 0 => new WfTicket { Tasks = [wfHandler.ActReqTask] }, + WfObjectScopes.Approval when wfHandler.ActReqTask.Id > 0 => new WfTicket { Tasks = [wfHandler.ActReqTask] }, + _ => null + }; + } + + private List GetRelevantActions(WfStatefulObject statefulObject, WfObjectScopes scope, bool toState = true) + { + List stateActions = []; + try + { + int searchedStateId = toState ? statefulObject.StateId : statefulObject.ChangedFrom(); + foreach (var action in states.FirstOrDefault(x => x.Id == searchedStateId)?.Actions.Select(a => a.Action) ?? throw new KeyNotFoundException("Unknown stateId:" + searchedStateId)) + { + if (action.Scope == scope.ToString() + && (!(action.Scope == WfObjectScopes.RequestTask.ToString() || action.Scope == WfObjectScopes.ImplementationTask.ToString()) + || action.TaskType == "" || action.TaskType == ((WfTaskBase)statefulObject).TaskType)) + { + stateActions.Add(action); + } + } + } + catch (Exception exc) + { + // unknown stateId probably by misconfiguration + Log.WriteError("Get relevant actions", $"Exception thrown and ignored: ", exc); + } + return stateActions; + } + + private async Task SetScope(WfStatefulObject statefulObject, WfObjectScopes scope, EmailActionParams? emailActionParams = null) + { + switch (scope) + { + case WfObjectScopes.Ticket: + wfHandler.SetTicketEnv((WfTicket)statefulObject); + SetCommenter(emailActionParams, wfHandler.ActTicket.Comments); + if (emailActionParams?.RecipientTo == EmailRecipientOption.Requester) + { + ScopedUserTo = wfHandler.ActTicket.Requester?.Dn; + } + if (emailActionParams?.RecipientCC == EmailRecipientOption.Requester) + { + ScopedUserCc = wfHandler.ActTicket.Requester?.Dn; + } + break; + case WfObjectScopes.RequestTask: + wfHandler.SetReqTaskEnv((WfReqTask)statefulObject); + SetCommenter(emailActionParams, wfHandler.ActReqTask.Comments); + break; + case WfObjectScopes.ImplementationTask: + wfHandler.SetImplTaskEnv((WfImplTask)statefulObject); + SetCommenter(emailActionParams, wfHandler.ActImplTask.Comments); + break; + case WfObjectScopes.Approval: + if (wfHandler.SetReqTaskEnv(((WfApproval)statefulObject).TaskId)) + { + await wfHandler.SetApprovalEnv(null, false); + SetCommenter(emailActionParams, wfHandler.ActApproval.Comments); + if (emailActionParams?.RecipientTo == EmailRecipientOption.Approver) + { + ScopedUserTo = wfHandler.ActApproval.ApproverDn; + } + if (emailActionParams?.RecipientCC == EmailRecipientOption.Approver) + { + ScopedUserCc = wfHandler.ActApproval.ApproverDn; + } + } + break; + default: + break; + } + } + + private void SetCommenter(EmailActionParams? emailActionParams, List comments) + { + ScopedUserTo = emailActionParams?.RecipientTo == EmailRecipientOption.LastCommenter ? comments.Last().Comment.Creator.Dn : null; + ScopedUserCc = emailActionParams?.RecipientCC == EmailRecipientOption.LastCommenter ? comments.Last().Comment.Creator.Dn : null; + } + } +} diff --git a/roles/lib/files/FWO.Services/Workflow/ExtStateHandler.cs b/roles/lib/files/FWO.Services/Workflow/ExtStateHandler.cs new file mode 100644 index 0000000000..789a6034a9 --- /dev/null +++ b/roles/lib/files/FWO.Services/Workflow/ExtStateHandler.cs @@ -0,0 +1,62 @@ +using FWO.Data; +using FWO.Data.Workflow; +using FWO.Api.Client; +using FWO.Api.Client.Queries; + +namespace FWO.Services.Workflow +{ + public class ExtStateHandler + { + private readonly ApiConnection apiConnection; + private List extStates = []; + + public ExtStateHandler(ApiConnection apiConnection) + { + this.apiConnection = apiConnection; + Task.Run(Init).Wait(); + } + + public async Task Init() + { + ApiResponse> extStateResponse = await apiConnection.SendQuerySafeAsync>(RequestQueries.getExtStates); + if (!extStateResponse.HasErrors && extStateResponse.Result != null) + { + extStates = extStateResponse.Result; + return; + } + + throw new InvalidOperationException($"Could not fetch external states: {BuildErrorMessage(extStateResponse.Errors)}"); + } + + public int? GetInternalStateId(ExtStates extState) + { + return extStates.FirstOrDefault(e => e.Name == extState.ToString())?.StateId; + } + + public int? GetInternalStateId(string extState) + { + return extStates.FirstOrDefault(e => e.Name == extState)?.StateId; + } + + public bool IsInProgress(int stateId) + { + int doneStateId = GetInternalStateId(ExtStates.ExtReqDone) ?? 999; + int rejectedStateId = GetInternalStateId(ExtStates.ExtReqRejected) ?? 999; + return stateId < doneStateId && stateId < rejectedStateId; + } + + public bool IsDone(int stateId) + { + return stateId == GetInternalStateId(ExtStates.ExtReqDone); + } + + private static string BuildErrorMessage(string[]? errors) + { + if (errors == null || errors.Length == 0) + { + return "unknown error"; + } + return string.Join(" | ", errors); + } + } +} diff --git a/roles/lib/files/FWO.Services/Workflow/RequestedRulePolicyChecker.cs b/roles/lib/files/FWO.Services/Workflow/RequestedRulePolicyChecker.cs new file mode 100644 index 0000000000..d41ce493f1 --- /dev/null +++ b/roles/lib/files/FWO.Services/Workflow/RequestedRulePolicyChecker.cs @@ -0,0 +1,9 @@ +using FWO.Data.Workflow; + +namespace FWO.Services.Workflow +{ + public interface IRequestedRulePolicyChecker + { + Task AreRequestTasksCompliant(IEnumerable policyIds, IEnumerable requestTasks); + } +} diff --git a/roles/lib/files/FWO.Services/Workflow/StateMatrix.cs b/roles/lib/files/FWO.Services/Workflow/StateMatrix.cs new file mode 100644 index 0000000000..f7f29ca6f0 --- /dev/null +++ b/roles/lib/files/FWO.Services/Workflow/StateMatrix.cs @@ -0,0 +1,237 @@ +using FWO.Api.Client; +using FWO.Api.Client.Queries; +using FWO.Data.Workflow; +using System.Text.Json.Serialization; +using Newtonsoft.Json; + +namespace FWO.Services.Workflow +{ + public enum WorkflowPhases + { + request = 0, + approval = 1, + planning = 2, + verification = 3, + implementation = 4, + review = 5, + recertification = 6 + } + + public class StateMatrix + { + [JsonProperty("matrix"), JsonPropertyName("matrix")] + public Dictionary> Matrix { get; set; } = []; + + [JsonProperty("derived_states"), JsonPropertyName("derived_states")] + public Dictionary DerivedStates { get; set; } = []; + + [JsonProperty("lowest_input_state"), JsonPropertyName("lowest_input_state")] + public int LowestInputState { get; set; } + + [JsonProperty("lowest_start_state"), JsonPropertyName("lowest_start_state")] + public int LowestStartedState { get; set; } + + [JsonProperty("lowest_end_state"), JsonPropertyName("lowest_end_state")] + public int LowestEndState { get; set; } + + [JsonProperty("active"), JsonPropertyName("active")] + public bool Active { get; set; } + + public HashSet AutomaticOnlyStates { get; set; } = []; + public Dictionary PhaseActive = []; + public bool IsLastActivePhase = true; + public int MinImplTasksNeeded; + public int MinTicketCompleted; + public int ApprovalLowestEndState; + + public async Task Init(WorkflowPhases phase, ApiConnection apiConnection, WfTaskType taskType = WfTaskType.master) + { + GlobalStateMatrix glbStateMatrix = new(); + await glbStateMatrix.Init(apiConnection, taskType); + List states = await apiConnection.SendQueryAsync>(RequestQueries.getStates); + Matrix = glbStateMatrix.GlobalMatrix[phase].Matrix; + DerivedStates = glbStateMatrix.GlobalMatrix[phase].DerivedStates; + LowestInputState = glbStateMatrix.GlobalMatrix[phase].LowestInputState; + LowestStartedState = glbStateMatrix.GlobalMatrix[phase].LowestStartedState; + LowestEndState = glbStateMatrix.GlobalMatrix[phase].LowestEndState; + Active = glbStateMatrix.GlobalMatrix[phase].Active; + AutomaticOnlyStates = states.Where(state => state.AutomaticOnly).Select(state => state.Id).ToHashSet(); + ApprovalLowestEndState = glbStateMatrix.GlobalMatrix[WorkflowPhases.approval].LowestEndState; + foreach (var phas in glbStateMatrix.GlobalMatrix) + { + PhaseActive.Add(phas.Key, glbStateMatrix.GlobalMatrix[phas.Key].Active); + if (glbStateMatrix.GlobalMatrix[phas.Key].Active && phas.Key > phase) + { + IsLastActivePhase = false; + } + } + MinImplTasksNeeded = glbStateMatrix.GlobalMatrix[WorkflowPhases.implementation].LowestInputState; + MinTicketCompleted = glbStateMatrix.GlobalMatrix[PhaseActive.LastOrDefault(p => p.Value == true).Key].LowestEndState; + } + + public bool getNextActivePhase(ref WorkflowPhases phase) + { + foreach (var tmpPhase in PhaseActive) + { + if (tmpPhase.Key > phase && tmpPhase.Value) + { + phase = tmpPhase.Key; + return true; + } + } + return false; + } + + public List getAllowedTransitions(int stateIn, bool allowAutomaticOnlyStates = false) + { + if (!Matrix.TryGetValue(stateIn, out List? value)) + { + return []; + } + + if (allowAutomaticOnlyStates) + { + return value; + } + + return value.Where(stateId => !AutomaticOnlyStates.Contains(stateId)).ToList(); + } + + public int getDerivedStateFromSubStates(List statesIn) + { + if (statesIn.Count == 0) + { + return 0; + } + int stateOut; + DerivedStateTracking tracking = new(LowestInputState, 0, LowestEndState, 999); + TaskCounters counters = new(); + foreach (int state in statesIn) + { + UpdateDerivedStateTracking(state, ref tracking, ref counters); + } + + if (counters.BackAssignedTasks > 0) + { + stateOut = tracking.BackAssignedState; + } + else if (counters.InWorkTasks > 0) + { + stateOut = tracking.InWorkState; + } + else if (counters.FinishedTasks == statesIn.Count) + { + stateOut = tracking.MinFinishedState; + } + else if (counters.OpenTasks == statesIn.Count) + { + stateOut = tracking.InitState; + } + else + { + stateOut = LowestStartedState; + } + + if (DerivedStates.ContainsKey(stateOut)) + { + return DerivedStates[stateOut]; + } + return stateOut; + } + + private readonly record struct DerivedStateTracking(int BackAssignedState, int InitState, int InWorkState, int MinFinishedState); + + private struct TaskCounters + { + public int BackAssignedTasks; + public int OpenTasks; + public int InWorkTasks; + public int FinishedTasks; + } + + private void UpdateDerivedStateTracking(int state, ref DerivedStateTracking tracking, ref TaskCounters counters) + { + if (state < LowestInputState) + { + counters.BackAssignedTasks++; + tracking = tracking with { BackAssignedState = Math.Min(state, tracking.BackAssignedState) }; + } + else if (state < LowestStartedState) + { + counters.OpenTasks++; + tracking = tracking with { InitState = state }; + } + else if (state < LowestEndState) + { + counters.InWorkTasks++; + tracking = tracking with { InWorkState = Math.Min(state, tracking.InWorkState) }; + } + else + { + counters.FinishedTasks++; + tracking = tracking with { MinFinishedState = Math.Min(state, tracking.MinFinishedState) }; + } + } + } + + public class GlobalStateMatrix + { + public static Func Factory { get; set; } = () => new GlobalStateMatrix(); + + public static GlobalStateMatrix Create() + { + return Factory(); + } + + [JsonProperty("config_value"), JsonPropertyName("config_value")] + public Dictionary GlobalMatrix { get; set; } = []; + + + public virtual async Task Init(ApiConnection apiConnection, WfTaskType taskType = WfTaskType.master, bool reset = false) + { + string matrixKey = taskType switch + { + WfTaskType.master => "reqMasterStateMatrix", + WfTaskType.generic => "reqGenStateMatrix", + WfTaskType.access => "reqAccStateMatrix", + WfTaskType.rule_delete => "reqRulDelStateMatrix", + WfTaskType.rule_modify => "reqRulModStateMatrix", + WfTaskType.group_create => "reqGrpCreStateMatrix", + WfTaskType.group_modify => "reqGrpModStateMatrix", + WfTaskType.group_delete => "reqGrpDelStateMatrix", + WfTaskType.new_interface => "reqNewIntStateMatrix", + _ => throw new NotSupportedException($"Error: wrong task type:" + taskType.ToString()), + }; + + if (reset) + { + matrixKey += "Default"; + } + + List confData = await apiConnection.SendQueryAsync>(ConfigQueries.getConfigItemByKey, new { key = matrixKey }); + GlobalStateMatrix glbStateMatrix = System.Text.Json.JsonSerializer.Deserialize(confData[0].ConfData) ?? throw new JsonException("Config data could not be parsed."); + GlobalMatrix = glbStateMatrix.GlobalMatrix; + } + } + + public class GlobalStateMatrixHelper + { + [JsonProperty("config_value"), JsonPropertyName("config_value")] + public string ConfData = ""; + } + + public class StateMatrixDict + { + public Dictionary Matrices { get; set; } = []; + + public async Task Init(WorkflowPhases phase, ApiConnection apiConnection) + { + Matrices = []; + foreach (WfTaskType taskType in Enum.GetValues(typeof(WfTaskType))) + { + Matrices.Add(taskType.ToString(), new StateMatrix()); + await Matrices[taskType.ToString()].Init(phase, apiConnection, taskType); + } + } + } +} diff --git a/roles/lib/files/FWO.Services/Workflow/TicketCreator.cs b/roles/lib/files/FWO.Services/Workflow/TicketCreator.cs new file mode 100644 index 0000000000..f6ec90a672 --- /dev/null +++ b/roles/lib/files/FWO.Services/Workflow/TicketCreator.cs @@ -0,0 +1,280 @@ +using System.Text.Json; +using FWO.Data; +using FWO.Data.Workflow; +using FWO.Config.Api; +using FWO.Api.Client; +using FWO.Logging; +using FWO.Middleware.Client; + +namespace FWO.Services.Workflow +{ + public class TicketCreator + { + private readonly WfHandler wfHandler; + private readonly UserConfig userConfig; + private readonly ApiConnection apiConnection; + private int stateId; + private string ticketTitle = ""; + private string ticketReason = ""; + private string taskTitle = ""; + private string taskReason = ""; + private int priority; + + + public TicketCreator(ApiConnection apiConnection, UserConfig userConfig, System.Security.Claims.ClaimsPrincipal authUser, MiddlewareClient middlewareClient, + WorkflowPhases phase = WorkflowPhases.request, IRequestedRulePolicyChecker? requestedRulePolicyChecker = null) + { + wfHandler = new(LogMessage, userConfig, authUser, apiConnection, middlewareClient, phase, requestedRulePolicyChecker); + this.userConfig = userConfig; + this.apiConnection = apiConnection; + } + + public async Task CreateTicket(FwoOwner owner, List reqTasks, string title, int? stateId, string reason = "") + { + await wfHandler.Init(); + stateId ??= wfHandler.MasterStateMatrix.LowestEndState; + await wfHandler.SelectTicket(new WfTicket() + { + StateId = (int)stateId, + Title = title, + Requester = userConfig.User, + Reason = reason + }, + ObjAction.add); + foreach (var reqTask in reqTasks) + { + wfHandler.SelectReqTask(new WfReqTask() + { + StateId = (int)stateId, + Title = reqTask.Title, + TaskNumber = reqTask.TaskNumber, + TaskType = reqTask.TaskType, + Owners = [new() { Owner = owner }], + Reason = reqTask.Reason, + ManagementId = reqTask.ManagementId, + OnManagement = reqTask.OnManagement, + Elements = reqTask.Elements, + Comments = reqTask.Comments, + AdditionalInfo = reqTask.AdditionalInfo + }, + ObjAction.add); + await wfHandler.AddApproval(JsonSerializer.Serialize(new ApprovalParams() { StateId = (int)stateId })); + wfHandler.ActTicket.Tasks.Add(wfHandler.ActReqTask); + } + wfHandler.AddTicketMode = true; + wfHandler.ActTicket.UpdateCidrsInTaskElements(); + long ticketId = await wfHandler.SaveTicket(wfHandler.ActTicket); + if (ticketId > 0) + { + foreach (var reqtask in reqTasks.Where(t => t.Comments.Count > 0)) + { + WfReqTask? reqTaskToChange = wfHandler.ActTicket.Tasks.FirstOrDefault(x => x.TaskType == reqtask.TaskType && + x.ManagementId == reqtask.ManagementId && x.Title == reqtask.Title && x.TaskNumber == reqtask.TaskNumber); + if (reqTaskToChange != null) + { + wfHandler.SetReqTaskEnv(reqTaskToChange); + await wfHandler.ConfAddCommentToReqTask(reqtask.Comments[0].Comment.CommentText); + } + } + } + return wfHandler.ActTicket; + } + + public async Task PromoteTicket(long ticketId, string extReqState) + { + try + { + await wfHandler.Init(); + WfTicket? ticket = await wfHandler.ResolveTicket(ticketId); + if (ticket != null) + { + ExtStateHandler extStateHandler = new(apiConnection); + ticket.StateId = extStateHandler.GetInternalStateId(extReqState) ?? throw new ArgumentException($"No translation defined for external state {extReqState}."); + return await wfHandler.PromoteTicketAndTasks(ticket); + } + } + catch (Exception exception) + { + Log.WriteError(userConfig.GetText("promote_ticket"), "leads to exception: ", exception); + } + return false; + } + + public async Task CreateRequestNewInterfaceTicket(FwoOwner owner, FwoOwner requestingOwner, string interfaceName, string reason = "") + { + await wfHandler.Init(); + stateId = wfHandler.MasterStateMatrix.LowestEndState; + await wfHandler.SelectTicket(new WfTicket() + { + StateId = stateId, + Title = userConfig.ModReqTicketTitle + ": " + interfaceName, + Requester = userConfig.User, + Reason = reason + }, + ObjAction.add); + Dictionary? addInfo = new() { { AdditionalInfoKeys.ReqOwner, requestingOwner.Id.ToString() } }; + wfHandler.SelectReqTask(new WfReqTask() + { + StateId = stateId, + Title = userConfig.ModReqTaskTitle + ": " + interfaceName, + TaskType = WfTaskType.new_interface.ToString(), + Owners = [new() { Owner = owner }], + Reason = reason, + AdditionalInfo = JsonSerializer.Serialize(addInfo) + }, + ObjAction.add); + await wfHandler.AddApproval(JsonSerializer.Serialize(new ApprovalParams() { StateId = wfHandler.MasterStateMatrix.LowestEndState })); + wfHandler.ActTicket.Tasks.Add(wfHandler.ActReqTask); + wfHandler.AddTicketMode = true; + long ticketId = await wfHandler.SaveTicket(wfHandler.ActTicket); + if (ticketId > 0) + { + await AddRequesterInfoToImplTask(ticketId); + } + return ticketId; + } + + public async Task SetInterfaceId(long ticketId, long connId) + { + await wfHandler.Init(); + WfTicket? ticket = await wfHandler.ResolveTicket(ticketId); + if (ticket != null) + { + WfReqTask? reqTask = ticket.Tasks.FirstOrDefault(x => x.TaskType == WfTaskType.new_interface.ToString()); + if (reqTask != null) + { + await wfHandler.SetAddInfoInReqTask(reqTask, AdditionalInfoKeys.ConnId, connId.ToString()); + } + } + } + + public async Task PromoteNewInterfaceImplTask(long ticketId, ExtStates extState, string comment = "") + { + ExtStateHandler extStateHandler = new(apiConnection); + await wfHandler.Init(); + WfImplTask? implTask = await FindNewInterfaceImplTask(ticketId); + if (implTask != null) + { + await wfHandler.ContinueImplPhase(implTask); + if (comment != "") + { + await wfHandler.ConfAddCommentToImplTask(comment); + } + int? newState = extStateHandler.GetInternalStateId(extState); + if (newState != null) + { + await wfHandler.PromoteImplTask(new() { StateId = (int)newState }); + return true; + } + } + return false; + } + + public async Task CreateDecertRuleDeleteTicket(int deviceId, List ruleUids, string comment = "", DateTime? deadline = null) + { + stateId = userConfig.RecDeleteRuleInitState; + ticketTitle = userConfig.RecDeleteRuleTicketTitle + " "; + ticketReason = userConfig.RecDeleteRuleTicketReason + " " + comment; + taskTitle = userConfig.RecDeleteRuleReqTaskTitle; + taskReason = userConfig.RecDeleteRuleReqTaskReason; + priority = userConfig.RecDeleteRuleTicketPriority; + await CreateRuleDeleteTicket(deviceId, ruleUids, comment, deadline); + } + + public async Task CreateUnusedRuleDeleteTicket(int deviceId, List ruleUids, string comment = "", DateTime? deadline = null) + { + stateId = userConfig.RecDeleteRuleInitState; + ticketTitle = userConfig.GetText("delete_unused_rules") + ": "; + ticketReason = comment; + taskTitle = userConfig.GetText("delete_unused_rule"); + taskReason = ""; + priority = userConfig.RecDeleteRuleTicketPriority; + await CreateRuleDeleteTicket(deviceId, ruleUids, comment, deadline); + } + + private async Task CreateRuleDeleteTicket(int deviceId, List ruleUids, string comment = "", DateTime? deadline = null) + { + await wfHandler.Init(); + wfHandler.ActTicket = new WfTicket() + { + StateId = stateId, + Title = ticketTitle + wfHandler.Devices.FirstOrDefault(x => x.Id == deviceId)?.Name ?? "", + Requester = userConfig.User, + Reason = ticketReason, + Priority = priority, + Deadline = deadline + }; + foreach (var ruleUid in ruleUids) + { + wfHandler.ActReqTask = new WfReqTask() + { + StateId = stateId, + Title = taskTitle + " " + ruleUid, + TaskType = WfTaskType.rule_delete.ToString(), + RequestAction = RequestAction.delete.ToString(), + Reason = taskReason + }; + wfHandler.ActReqTask.Elements.Add(new WfReqElement() + { + Field = ElemFieldType.rule.ToString(), + RequestAction = RequestAction.delete.ToString(), + DeviceId = deviceId, + RuleUid = ruleUid + }); + await wfHandler.AddApproval(JsonSerializer.Serialize(new ApprovalParams() { StateId = wfHandler.MasterStateMatrix.LowestEndState })); + wfHandler.ActTicket.Tasks.Add(wfHandler.ActReqTask); + } + wfHandler.AddTicketMode = true; + long ticketId = await wfHandler.SaveTicket(wfHandler.ActTicket); + if (ticketId > 0 && !string.IsNullOrWhiteSpace(comment)) + { + await wfHandler.ConfAddCommentToTicket(comment); + } + } + + private async Task AddRequesterInfoToImplTask(long ticketId) + { + WfImplTask? implTask = await FindNewInterfaceImplTask(ticketId); + if (implTask != null) + { + wfHandler.SetImplTaskEnv(implTask); + string comment = $"{userConfig.GetText("requested_by")}: {userConfig.User.Name}"; + await wfHandler.ConfAddCommentToImplTask(comment); + } + } + + private async Task FindNewInterfaceImplTask(long ticketId) + { + WfTicket? ticket = await wfHandler.ResolveTicket(ticketId); + if (ticket != null) + { + WfReqTask? reqTask = ticket.Tasks.FirstOrDefault(x => x.TaskType == WfTaskType.new_interface.ToString()); + if (reqTask != null) + { + wfHandler.SetReqTaskEnv(reqTask); + return reqTask.ImplementationTasks.FirstOrDefault(x => x.ReqTaskId == reqTask.Id); + } + } + return null; + } + + private static void LogMessage(Exception? exception = null, string title = "", string message = "", bool ErrorFlag = false) + { + if (exception == null) + { + if (ErrorFlag) + { + Log.WriteWarning(title, message); + } + else + { + Log.WriteInfo(title, message); + } + } + else + { + Log.WriteError(title, message, exception); + } + } + } +} diff --git a/roles/lib/files/FWO.Services/Workflow/WfDbAccess.cs b/roles/lib/files/FWO.Services/Workflow/WfDbAccess.cs new file mode 100644 index 0000000000..2184e51653 --- /dev/null +++ b/roles/lib/files/FWO.Services/Workflow/WfDbAccess.cs @@ -0,0 +1,929 @@ +using FWO.Data; +using FWO.Data.Workflow; +using FWO.Config.Api; +using FWO.Api.Client; +using FWO.Api.Client.Queries; +using System.Collections.Generic; + +namespace FWO.Services.Workflow +{ + public class WfDbAccess(Action DisplayMessageInUi, UserConfig UserConfig, ApiConnection ApiConnection, ActionHandler ActionHandler, bool AsAdmin) + { + public async Task> FetchTickets(StateMatrix stateMatrix, List? ownerIds = null, bool allStates = false, bool fullTickets = false) + { + List tickets = []; + try + { + // todo: filter own approvals, plannings... + int fromState = allStates ? 0 : stateMatrix.LowestInputState; + int toState = allStates ? 999 : stateMatrix.LowestEndState; + + var Variables = new { fromState, toState }; + tickets = await ApiConnection.SendQueryAsync>(fullTickets ? RequestQueries.getFullTickets : RequestQueries.getTickets, Variables); + if (UserConfig.ReqOwnerBased && !AsAdmin) + { + tickets = await FilterWrongOwnersOut(tickets, ownerIds); + } + if (fullTickets) + { + foreach (var ticket in tickets) + { + ticket.UpdateCidrsInTaskElements(); + } + } + } + catch (Exception exception) + { + DisplayMessageInUi(exception, UserConfig.GetText("fetch_requests"), "", true); + } + return tickets; + } + + public async Task FetchTicket(long ticketId, List? ownerIds = null) + { + WfTicket? ticket = null; + try + { + ticket = await GetTicket(ticketId); + if (UserConfig.ReqOwnerBased && !AsAdmin) + { + ticket = (await FilterWrongOwnersOut([ticket], ownerIds)).FirstOrDefault(); + } + } + catch (Exception exception) + { + DisplayMessageInUi(exception, UserConfig.GetText("fetch_requests"), "", true); + } + return ticket; + } + + private async Task> FilterWrongOwnersOut(List ticketsIn, List? ownerIds) + { + if (ownerIds == null || ownerIds.Count == 0) + { + return []; + } + List registeredTickets = (await ApiConnection.SendQueryAsync>(RequestQueries.getOwnerTicketIds, new { ownerIds })).ConvertAll(t => t.Id); + foreach (var ticket in ticketsIn.Where(ti => !ti.IsEditableForOwner(registeredTickets, ownerIds, UserConfig.UserId))) + { + ticket.Editable = false; + } + return [.. ticketsIn.Where(ti => ti.IsVisibleForOwner(registeredTickets, ownerIds, UserConfig.UserId))]; + } + + public async Task GetTicket(long id) + { + WfTicket ticket = new(); + try + { + var Variables = new { id }; + ticket = await ApiConnection.SendQueryAsync(RequestQueries.getTicketById, Variables); + ticket.UpdateCidrsInTaskElements(); + } + catch (Exception exception) + { + DisplayMessageInUi(exception, UserConfig.GetText("fetch_requests"), "", true); + } + return ticket; + } + + public async Task> GetTicketsByParameters(string taskType, int startState, int endState, DateTime cutOffDate) + { + List tickets = []; + try + { + var Variables = new + { + cutOffDate = cutOffDate, + taskType = taskType, + fromState = startState, + toState = endState + }; + tickets = await ApiConnection.SendQueryAsync>(RequestQueries.getTicketsByParameters, Variables); + } + catch (Exception exception) + { + DisplayMessageInUi(exception, UserConfig.GetText("fetch_requests"), "", true); + } + return tickets; + } + + + // Tickets + + public async Task AddTicketToDb(WfTicket ticket) + { + try + { + ticket.UpdateIpStringsFromCidrInTaskElements(); + var Variables = BuildTicketVariables(ticket); + Variables["requesterId"] = ticket.Requester?.DbId; + Variables["requestTasks"] = new WfTicketWriter(ticket); + ReturnId[]? returnIds = (await ApiConnection.SendQueryAsync(RequestQueries.newTicket, Variables)).ReturnIds; + if (returnIds == null) + { + DisplayMessageInUi(null, UserConfig.GetText("save_request"), UserConfig.GetText("E8001"), true); + } + else + { + ticket = await GetTicket(returnIds[0].NewIdLong); + await ActionHandler.DoStateChangeActions(ticket, WfObjectScopes.Ticket, null, ticket.Id, ticket.Requester?.Dn); + } + } + catch (Exception exception) + { + DisplayMessageInUi(exception, UserConfig.GetText("save_request"), "", true); + } + return ticket; + } + + public async Task UpdateTicketInDb(WfTicket ticket) + { + try + { + var Variables = BuildTicketVariables(ticket); + Variables["id"] = ticket.Id; + long udId = (await ApiConnection.SendQueryAsync(RequestQueries.updateTicket, Variables)).UpdatedIdLong; + if (udId != ticket.Id) + { + DisplayMessageInUi(null, UserConfig.GetText("save_request"), UserConfig.GetText("E8002"), true); + } + else + { + await ActionHandler.DoStateChangeActions(ticket, WfObjectScopes.Ticket, null, ticket.Id, ticket.Requester?.Dn); + } + } + catch (Exception exception) + { + DisplayMessageInUi(exception, UserConfig.GetText("save_request"), "", true); + } + return ticket; + } + + private static Dictionary BuildTicketVariables(WfTicket ticket) + { + return new Dictionary + { + ["title"] = ticket.Title, + ["state"] = ticket.StateId, + ["reason"] = ticket.Reason, + ["deadline"] = ticket.Deadline, + ["priority"] = ticket.Priority + }; + } + + + // Request Tasks + + public async Task AddReqTaskToDb(WfReqTask reqtask) + { + long returnId = 0; + try + { + var Variables = BuildReqTaskInsertVariables(reqtask); + Variables["ticketId"] = reqtask.TicketId; + ReturnId[]? returnIds = (await ApiConnection.SendQueryAsync(RequestQueries.newRequestTask, Variables)).ReturnIds; + if (returnIds == null) + { + DisplayMessageInUi(null, UserConfig.GetText("add_task"), UserConfig.GetText("E8003"), true); + } + else + { + returnId = returnIds[0].NewIdLong; + reqtask.Id = returnId; + foreach (var element in reqtask.Elements) + { + element.TaskId = returnId; + element.Id = await AddReqElementToDb(element); + } + foreach (var approval in reqtask.Approvals) + { + approval.TaskId = returnId; + await AddApprovalToDb(approval); + } + foreach (var owner in reqtask.Owners) + { + await AssignOwnerInDb(returnId, owner.Owner.Id); + } + await ActionHandler.DoStateChangeActions(reqtask, WfObjectScopes.RequestTask, reqtask.Owners.Count > 0 ? reqtask.Owners.First().Owner : null, reqtask.TicketId); + } + } + catch (Exception exception) + { + DisplayMessageInUi(exception, UserConfig.GetText("add_task"), "", true); + } + return returnId; + } + + public async Task UpdateReqTaskInDb(WfReqTask reqtask) + { + try + { + var Variables = BuildReqTaskUpdateVariables(reqtask); + Variables["id"] = reqtask.Id; + Variables["devices"] = reqtask.SelectedDevices; + long udId = (await ApiConnection.SendQueryAsync(RequestQueries.updateRequestTask, Variables)).UpdatedIdLong; + if (udId != reqtask.Id) + { + DisplayMessageInUi(null, UserConfig.GetText("save_task"), UserConfig.GetText("E8004"), true); + } + else + { + await UpdateReqElementsInDb(reqtask); + await UpdateOwnersInDb(reqtask); + await ActionHandler.DoStateChangeActions(reqtask, WfObjectScopes.RequestTask, reqtask.Owners.Count > 0 ? reqtask.Owners.First().Owner : null, reqtask.TicketId); + } + } + catch (Exception exception) + { + DisplayMessageInUi(exception, UserConfig.GetText("save_task"), "", true); + } + } + + public async Task UpdateReqTaskAdditionalInfo(WfReqTask reqtask) + { + try + { + var Variables = new + { + id = reqtask.Id, + additionalInfo = reqtask.AdditionalInfo + }; + long udId = (await ApiConnection.SendQueryAsync(RequestQueries.updateRequestTaskAdditionalInfo, Variables)).UpdatedIdLong; + if (udId != reqtask.Id) + { + DisplayMessageInUi(null, UserConfig.GetText("save_task"), UserConfig.GetText("E8004"), true); + } + } + catch (Exception exception) + { + DisplayMessageInUi(exception, UserConfig.GetText("save_task"), "", true); + } + } + + public async Task DeleteReqTaskFromDb(WfReqTask reqtask) + { + try + { + long delId = (await ApiConnection.SendQueryAsync(RequestQueries.deleteRequestTask, new { id = reqtask.Id })).DeletedIdLong; + if (delId != reqtask.Id) + { + DisplayMessageInUi(null, UserConfig.GetText("delete_task"), UserConfig.GetText("E8005"), true); + } + } + catch (Exception exception) + { + DisplayMessageInUi(exception, UserConfig.GetText("delete_task"), "", true); + } + } + + private static Dictionary BuildReqTaskInsertVariables(WfReqTask reqtask) + { + Dictionary variables = BuildReqTaskUpdateVariables(reqtask); + variables["taskType"] = reqtask.TaskType; + return variables; + } + + private static Dictionary BuildReqTaskUpdateVariables(WfReqTask reqtask) + { + return new Dictionary + { + ["title"] = reqtask.Title, + ["taskNumber"] = reqtask.TaskNumber, + ["state"] = reqtask.StateId, + ["requestAction"] = reqtask.RequestAction, + ["ruleAction"] = reqtask.RuleAction, + ["tracking"] = reqtask.Tracking, + ["validFrom"] = reqtask.TargetBeginDate, + ["validTo"] = reqtask.TargetEndDate, + ["reason"] = reqtask.Reason, + ["additionalInfo"] = reqtask.AdditionalInfo, + ["freeText"] = reqtask.FreeText, + ["managementId"] = reqtask.ManagementId + }; + } + + + // Request Elements + + private async Task UpdateReqElementsInDb(WfReqTask reqtask) + { + try + { + foreach (var elem in reqtask.RemovedElements) + { + await DeleteReqElementFromDb(elem.Id); + } + reqtask.RemovedElements = []; + + foreach (var element in reqtask.Elements) + { + if (element.Id == 0) + { + element.Id = await AddReqElementToDb(element); + } + else + { + await UpdateReqElementInDb(element); + } + } + } + catch (Exception exception) + { + DisplayMessageInUi(exception, UserConfig.GetText("save_element"), "", true); + } + } + + private async Task AddReqElementToDb(WfReqElement element) + { + long returnId = 0; + try + { + var Variables = BuildReqElementVariables(element); + ReturnId[]? returnIds = (await ApiConnection.SendQueryAsync(RequestQueries.newRequestElement, Variables)).ReturnIds; + if (returnIds == null) + { + DisplayMessageInUi(null, UserConfig.GetText("add_element"), UserConfig.GetText("E8006"), true); + } + else + { + returnId = returnIds[0].NewIdLong; + } + } + catch (Exception exception) + { + DisplayMessageInUi(exception, UserConfig.GetText("add_element"), "", true); + } + return returnId; + } + + private async Task UpdateReqElementInDb(WfReqElement element) + { + try + { + var Variables = BuildReqElementVariables(element); + Variables["id"] = element.Id; + long udId = (await ApiConnection.SendQueryAsync(RequestQueries.updateRequestElement, Variables)).UpdatedIdLong; + if (udId != element.Id) + { + DisplayMessageInUi(null, UserConfig.GetText("save_element"), UserConfig.GetText("E8007"), true); + } + } + catch (Exception exception) + { + DisplayMessageInUi(exception, UserConfig.GetText("save_element"), "", true); + } + } + + private async Task DeleteReqElementFromDb(long elementId) + { + try + { + long delId = (await ApiConnection.SendQueryAsync(RequestQueries.deleteRequestElement, new { id = elementId })).DeletedIdLong; + if (delId != elementId) + { + DisplayMessageInUi(null, UserConfig.GetText("delete_element"), UserConfig.GetText("E8008"), true); + } + } + catch (Exception exception) + { + DisplayMessageInUi(exception, UserConfig.GetText("delete_element"), "", true); + } + } + + private static Dictionary BuildReqElementVariables(WfReqElement element) + { + var variables = BuildElementBaseVariables(element, element.Cidr, element.CidrEnd); + variables["requestAction"] = element.RequestAction; + variables["taskId"] = element.TaskId; + variables["deviceId"] = element.DeviceId; + return variables; + } + + + // Approvals + + public async Task AddApprovalToDb(WfApproval approval) + { + long returnId = 0; + try + { + var Variables = new + { + taskId = approval.TaskId, + state = approval.StateId, + approverGroup = approval.ApproverGroup, + tenant = approval.TenantId, + deadline = approval.Deadline, + initialApproval = approval.InitialApproval + }; + ReturnId[]? returnIds = (await ApiConnection.SendQueryAsync(RequestQueries.newApproval, Variables)).ReturnIds; + if (returnIds == null) + { + DisplayMessageInUi(null, UserConfig.GetText("add_approval"), UserConfig.GetText("E8009"), true); + } + else + { + returnId = returnIds[0].NewIdLong; + approval.Id = returnId; + await ActionHandler.DoStateChangeActions(approval, WfObjectScopes.Approval); + } + } + catch (Exception exception) + { + DisplayMessageInUi(exception, UserConfig.GetText("add_approval"), "", true); + } + return returnId; + } + + public async Task UpdateApprovalInDb(WfApproval approval) + { + try + { + var Variables = new + { + id = approval.Id, + state = approval.StateId, + approvalDate = approval.ApprovalDate, + approver = approval.ApproverDn, // todo: Dn or uiuser?? + assignedGroup = approval.AssignedGroup + }; + long udId = (await ApiConnection.SendQueryAsync(RequestQueries.updateApproval, Variables)).UpdatedIdLong; + if (udId != approval.Id) + { + DisplayMessageInUi(null, UserConfig.GetText("save_approval"), UserConfig.GetText("E8004"), true); + } + else + { + await ActionHandler.DoStateChangeActions(approval, WfObjectScopes.Approval); + } + } + catch (Exception exception) + { + DisplayMessageInUi(exception, UserConfig.GetText("save_approval"), "", true); + } + } + + + // implementation tasks + + public async Task AddImplTaskToDb(WfImplTask impltask) + { + long returnId = 0; + try + { + var Variables = BuildImplTaskInsertVariables(impltask); + ReturnId[]? returnIds = (await ApiConnection.SendQueryAsync(RequestQueries.newImplementationTask, Variables)).ReturnIds; + if (returnIds == null) + { + DisplayMessageInUi(null, UserConfig.GetText("add_task"), UserConfig.GetText("E8003"), true); + } + else + { + returnId = returnIds[0].NewIdLong; + impltask.Id = returnId; + foreach (var element in impltask.ImplElements) + { + element.ImplTaskId = returnId; + element.Id = await AddImplElementToDb(element); + } + foreach (var comment in impltask.Comments) + { + comment.Comment.Id = await AddCommentToDb(comment.Comment); + if (comment.Comment.Id != 0) + { + await AssignCommentToImplTaskInDb(returnId, comment.Comment.Id); + } + } + await ActionHandler.DoStateChangeActions(impltask, WfObjectScopes.ImplementationTask); + } + } + catch (Exception exception) + { + DisplayMessageInUi(exception, UserConfig.GetText("add_task"), "", true); + } + return returnId; + } + + public async Task UpdateImplTaskInDb(WfImplTask impltask, WfReqTask reqtask) + { + try + { + var Variables = BuildImplTaskUpdateVariables(impltask); + Variables["id"] = impltask.Id; + long udId = (await ApiConnection.SendQueryAsync(RequestQueries.updateImplementationTask, Variables)).UpdatedIdLong; + if (udId != impltask.Id) + { + DisplayMessageInUi(null, UserConfig.GetText("save_task"), UserConfig.GetText("E8004"), true); + } + else + { + await UpdateImplElementsInDb(impltask); + await UpdateOwnersInDb(reqtask); + await ActionHandler.DoStateChangeActions(impltask, WfObjectScopes.ImplementationTask); + } + } + catch (Exception exception) + { + DisplayMessageInUi(exception, UserConfig.GetText("save_task"), "", true); + } + } + + public async Task DeleteImplTaskFromDb(WfImplTask impltask) + { + try + { + long delId = (await ApiConnection.SendQueryAsync(RequestQueries.deleteImplementationTask, new { id = impltask.Id })).DeletedIdLong; + if (delId != impltask.Id) + { + DisplayMessageInUi(null, UserConfig.GetText("delete_task"), UserConfig.GetText("E8005"), true); + } + } + catch (Exception exception) + { + DisplayMessageInUi(exception, UserConfig.GetText("delete_task"), "", true); + } + } + + private static Dictionary BuildImplTaskInsertVariables(WfImplTask impltask) + { + Dictionary variables = BuildImplTaskUpdateVariables(impltask); + variables["taskType"] = impltask.TaskType; + return variables; + } + + private static Dictionary BuildImplTaskUpdateVariables(WfImplTask impltask) + { + return new Dictionary + { + ["title"] = impltask.Title, + ["reqTaskId"] = impltask.ReqTaskId, + ["implIaskNumber"] = impltask.TaskNumber, + ["state"] = impltask.StateId, + ["device"] = impltask.DeviceId, + ["implAction"] = impltask.ImplAction, + ["ruleAction"] = impltask.RuleAction, + ["tracking"] = impltask.Tracking, + ["handler"] = impltask.CurrentHandler?.DbId, + ["validFrom"] = impltask.TargetBeginDate, + ["validTo"] = impltask.TargetEndDate, + ["freeText"] = impltask.FreeText + }; + } + + + // implementation elements + + private async Task UpdateImplElementsInDb(WfImplTask impltask) + { + try + { + foreach (var elem in impltask.RemovedElements) + { + await DeleteImplElementFromDb(elem.Id); + } + impltask.RemovedElements = []; + + foreach (var element in impltask.ImplElements) + { + if (element.Id == 0) + { + element.Id = await AddImplElementToDb(element); + } + else + { + await UpdateImplElementInDb(element); + } + } + } + catch (Exception exception) + { + DisplayMessageInUi(exception, UserConfig.GetText("save_element"), "", true); + } + } + + private async Task AddImplElementToDb(WfImplElement element) + { + long returnId = 0; + try + { + var Variables = BuildImplElementVariables(element); + ReturnId[]? returnIds = (await ApiConnection.SendQueryAsync(RequestQueries.newImplementationElement, Variables)).ReturnIds; + if (returnIds == null) + { + DisplayMessageInUi(null, UserConfig.GetText("add_element"), UserConfig.GetText("E8006"), true); + } + else + { + returnId = returnIds[0].NewIdLong; + } + } + catch (Exception exception) + { + DisplayMessageInUi(exception, UserConfig.GetText("add_element"), "", true); + } + return returnId; + } + + private async Task UpdateImplElementInDb(WfImplElement element) + { + try + { + var Variables = BuildImplElementVariables(element); + Variables["id"] = element.Id; + long udId = (await ApiConnection.SendQueryAsync(RequestQueries.updateImplementationElement, Variables)).UpdatedIdLong; + if (udId != element.Id) + { + DisplayMessageInUi(null, UserConfig.GetText("save_element"), UserConfig.GetText("E8007"), true); + } + } + catch (Exception exception) + { + DisplayMessageInUi(exception, UserConfig.GetText("save_element"), "", true); + } + } + + private async Task DeleteImplElementFromDb(long elementId) + { + try + { + long delId = (await ApiConnection.SendQueryAsync(RequestQueries.deleteImplementationElement, new { id = elementId })).DeletedIdLong; + if (delId != elementId) + { + DisplayMessageInUi(null, UserConfig.GetText("delete_element"), UserConfig.GetText("E8008"), true); + } + } + catch (Exception exception) + { + DisplayMessageInUi(exception, UserConfig.GetText("delete_element"), "", true); + } + } + + private static Dictionary BuildImplElementVariables(WfImplElement element) + { + var variables = BuildElementBaseVariables(element, element.Cidr, element.CidrEnd); + variables["implementationAction"] = element.ImplAction; + variables["implTaskId"] = element.ImplTaskId; + return variables; + } + + private static Dictionary BuildElementBaseVariables(WfElementBase element, Cidr? cidr, Cidr? cidrEnd) + { + return new Dictionary + { + ["ip"] = cidr != null && cidr.Valid ? cidr.CidrString : null, + ["ipEnd"] = cidrEnd != null && cidrEnd.Valid ? cidrEnd.CidrString : null, + ["port"] = element.Port, + ["portEnd"] = element.PortEnd, + ["proto"] = element.ProtoId, + ["networkObjId"] = element.NetworkId, + ["serviceId"] = element.ServiceId, + ["field"] = element.Field, + ["userId"] = element.UserId, + ["originalNatId"] = element.OriginalNatId, + ["ruleUid"] = element.RuleUid, + ["groupName"] = element.GroupName, + ["name"] = element.Name + }; + } + + + // Comments + + public async Task AddCommentToDb(WfComment comment) + { + long returnId = 0; + try + { + var Variables = new + { + refId = comment.RefId, + scope = comment.Scope, + creationDate = comment.CreationDate, + creator = comment.Creator.DbId, + text = comment.CommentText + }; + ReturnId[]? returnIds = (await ApiConnection.SendQueryAsync(RequestQueries.newComment, Variables)).ReturnIds; + if (returnIds == null) + { + DisplayMessageInUi(null, UserConfig.GetText("add_comment"), UserConfig.GetText("E8012"), true); + } + else + { + returnId = returnIds[0].NewIdLong; + } + } + catch (Exception exception) + { + DisplayMessageInUi(exception, UserConfig.GetText("add_comment"), "", true); + } + return returnId; + } + + public async Task AssignCommentToTicketInDb(long ticketId, long commentId) + { + await AssignCommentToDb(RequestQueries.addCommentToTicket, new { ticketId, commentId }); + } + + public async Task AssignCommentToReqTaskInDb(long taskId, long commentId) + { + await AssignCommentToDb(RequestQueries.addCommentToReqTask, new { taskId, commentId }); + } + + public async Task AssignCommentToImplTaskInDb(long taskId, long commentId) + { + await AssignCommentToDb(RequestQueries.addCommentToImplTask, new { taskId, commentId }); + } + + public async Task AssignCommentToApprovalInDb(long approvalId, long commentId) + { + await AssignCommentToDb(RequestQueries.addCommentToApproval, new { approvalId, commentId }); + } + + private async Task AssignCommentToDb(string query, object variables) + { + try + { + ReturnId[]? returnIds = (await ApiConnection.SendQueryAsync(query, variables)).ReturnIds; + if (returnIds == null) + { + DisplayMessageInUi(null, UserConfig.GetText("add_comment"), UserConfig.GetText("E8012"), true); + } + } + catch (Exception exception) + { + DisplayMessageInUi(exception, UserConfig.GetText("add_comment"), "", true); + } + } + + + // Owners + + public async Task UpdateOwnersInDb(WfReqTask reqtask) + { + try + { + foreach (var owner in reqtask.RemovedOwners) + { + await RemoveOwnerInDb(reqtask.Id, owner.Id); + FwoOwnerDataHelper? oldOwner = reqtask.Owners.FirstOrDefault(x => x.Owner.Id == owner.Id); + if (oldOwner != null) + { + reqtask.Owners.Remove(oldOwner); + } + } + reqtask.RemovedOwners = []; + + foreach (var owner in reqtask.NewOwners) + { + await AssignOwnerInDb(reqtask.Id, owner.Id); + reqtask.Owners.Add(new() { Owner = owner }); + await ActionHandler.DoOwnerChangeActions(reqtask, owner, reqtask.TicketId); + } + } + catch (Exception exception) + { + DisplayMessageInUi(exception, UserConfig.GetText("save_element"), "", true); + } + } + + private async Task AssignOwnerInDb(long reqTaskId, long ownerId) + { + try + { + var Variables = new { reqTaskId, ownerId }; + ReturnId[]? returnIds = (await ApiConnection.SendQueryAsync(RequestQueries.addOwnerToReqTask, Variables)).ReturnIds; + if (returnIds == null) + { + DisplayMessageInUi(null, UserConfig.GetText("assign_owner"), UserConfig.GetText("E8015"), true); + } + } + catch (Exception exception) + { + DisplayMessageInUi(exception, UserConfig.GetText("assign_owner"), "", true); + } + } + + private async Task RemoveOwnerInDb(long reqTaskId, long ownerId) + { + try + { + var Variables = new { reqTaskId, ownerId }; + if ((await ApiConnection.SendQueryAsync(RequestQueries.removeOwnerFromReqTask, Variables)).AffectedRows == 0) + { + DisplayMessageInUi(null, UserConfig.GetText("assign_owner"), UserConfig.GetText("E8016"), true); + } + } + catch (Exception exception) + { + DisplayMessageInUi(exception, UserConfig.GetText("assign_owner"), "", true); + } + } + + + // State changes + + public async Task UpdateTicketStateInDb(WfTicket ticket) + { + try + { + var Variables = new + { + id = ticket.Id, + state = ticket.StateId, + closed = ticket.CompletionDate, + deadline = ticket.Deadline, + priority = ticket.Priority + }; + long udId = (await ApiConnection.SendQueryAsync(RequestQueries.updateTicketState, Variables)).UpdatedIdLong; + if (udId != ticket.Id) + { + DisplayMessageInUi(null, UserConfig.GetText("save_request"), UserConfig.GetText("E8002"), true); + } + else + { + await ActionHandler.DoStateChangeActions(ticket, WfObjectScopes.Ticket, null, ticket.Id, ticket.Requester?.Dn); + } + } + catch (Exception exception) + { + DisplayMessageInUi(exception, UserConfig.GetText("save_request"), "", true); + } + } + + public async Task UpdateReqTaskStateInDb(WfReqTask reqtask) + { + try + { + var Variables = new + { + id = reqtask.Id, + state = reqtask.StateId, + start = reqtask.Start, + stop = reqtask.Stop, + handler = reqtask.CurrentHandler?.DbId, + recentHandler = reqtask.RecentHandler?.DbId, + assignedGroup = reqtask.AssignedGroup + }; + long udId = (await ApiConnection.SendQueryAsync(RequestQueries.updateRequestTaskState, Variables)).UpdatedIdLong; + if (udId != reqtask.Id) + { + DisplayMessageInUi(null, UserConfig.GetText("save_task"), UserConfig.GetText("E8004"), true); + } + else + { + await ActionHandler.DoStateChangeActions(reqtask, WfObjectScopes.RequestTask, reqtask.Owners.Count > 0 ? reqtask.Owners.First().Owner : null, reqtask.TicketId); + } + } + catch (Exception exception) + { + DisplayMessageInUi(exception, UserConfig.GetText("save_task"), "", true); + } + } + + public async Task UpdateImplTaskStateInDb(WfImplTask impltask) + { + try + { + var Variables = new + { + id = impltask.Id, + state = impltask.StateId, + start = impltask.Start, + stop = impltask.Stop, + handler = impltask.CurrentHandler?.DbId, + recentHandler = impltask.RecentHandler?.DbId, + assignedGroup = impltask.AssignedGroup, + }; + long udId = (await ApiConnection.SendQueryAsync(RequestQueries.updateImplementationTaskState, Variables)).UpdatedIdLong; + if (udId != impltask.Id) + { + DisplayMessageInUi(null, UserConfig.GetText("save_task"), UserConfig.GetText("E8004"), true); + } + else + { + await ActionHandler.DoStateChangeActions(impltask, WfObjectScopes.ImplementationTask); + } + } + catch (Exception exception) + { + DisplayMessageInUi(exception, UserConfig.GetText("save_task"), "", true); + } + } + + public async Task FindRuleUid(int? deviceId, string? ruleUid) + { + bool ruleFound = false; + try + { + var Variables = new { deviceId, ruleUid }; + ruleFound = (await ApiConnection.SendQueryAsync>(RuleQueries.getRuleByUid, Variables)).Count > 0; + } + catch (Exception exception) + { + DisplayMessageInUi(exception, UserConfig.GetText("fetch_data"), "", true); + } + return ruleFound; + } + } +} diff --git a/roles/lib/files/FWO.Services/Workflow/WfHandler.cs b/roles/lib/files/FWO.Services/Workflow/WfHandler.cs new file mode 100644 index 0000000000..dc42237620 --- /dev/null +++ b/roles/lib/files/FWO.Services/Workflow/WfHandler.cs @@ -0,0 +1,216 @@ +using FWO.Api.Client; +using FWO.Api.Client.Queries; +using FWO.Basics; +using FWO.Config.Api; +using FWO.Data; +using FWO.Data.Workflow; +using FWO.Logging; +using FWO.Middleware.Client; +using System.Security.Authentication; +using System.Text.Json; + +namespace FWO.Services.Workflow +{ + public enum ObjAction + { + display, + edit, + add, + approve, + plan, + implement, + review, + displayAssign, + displayApprovals, + displayApprove, + displayPromote, + displayDelete, + displaySaveTicket, + displayComment, + displayCleanup, + displayPathAnalysis + } + + public partial class WfHandler + { + public List TicketList { get; set; } = []; + public WfTicket ActTicket { get; set; } = new(); + public WfReqTask ActReqTask { get; set; } = new(); + public WfImplTask ActImplTask { get; set; } = new(); + public WfApproval ActApproval { get; set; } = new(); + + public WorkflowPhases Phase = WorkflowPhases.request; + public List Devices = []; + public List AllOwners { get; set; } = []; + public List PrioList = []; + public List AllTicketImplTasks = []; + public List AllVisibleImplTasks = []; + public StateMatrix ActStateMatrix = new(); + public StateMatrix MasterStateMatrix = new(); + public ActionHandler? ActionHandler; + public bool ReadOnlyMode = false; + public bool ApproveReqTaskMode = false; + public bool DisplayApproveMode = false; + public bool DisplayPromoteReqTaskMode = false; + public bool DisplayPromoteImplTaskMode = false; + + public bool InitDone = false; + private Action DisplayMessageInUi { get; set; } = DefaultInit.DoNothing; + public UserConfig userConfig; + public System.Security.Claims.ClaimsPrincipal? AuthUser; + private readonly ApiConnection? apiConnection; + public readonly MiddlewareClient? MiddlewareClient; + public readonly IRequestedRulePolicyChecker? RequestedRulePolicyChecker; + private readonly StateMatrixDict stateMatrixDict = new(); + private WfDbAccess? dbAcc; + + private ObjAction contOption = ObjAction.display; + private bool InitOngoing = false; + private readonly bool usedInMwServer = false; + private readonly List? UserGroups = null; + private bool ReloadTasks = false; + + + public WfHandler() + { + userConfig = new(); + } + + /// + /// constructor for use in UI + /// + public WfHandler(Action displayMessageInUi, UserConfig userConfig, + System.Security.Claims.ClaimsPrincipal authUser, ApiConnection apiConnection, MiddlewareClient middlewareClient, WorkflowPhases phase, + IRequestedRulePolicyChecker? requestedRulePolicyChecker = null) + { + DisplayMessageInUi = displayMessageInUi; + this.userConfig = userConfig; + this.apiConnection = apiConnection; + Phase = phase; + MiddlewareClient = middlewareClient; + RequestedRulePolicyChecker = requestedRulePolicyChecker; + AuthUser = authUser; + } + + /// + /// constructor for use in middleware server + /// + public WfHandler(UserConfig userConfig, ApiConnection apiConnection, WorkflowPhases phase, List? userGroups, + IRequestedRulePolicyChecker? requestedRulePolicyChecker = null) + { + DisplayMessageInUi = LogMessage; + this.userConfig = userConfig; + this.apiConnection = apiConnection; + Phase = phase; + UserGroups = userGroups; + RequestedRulePolicyChecker = requestedRulePolicyChecker; + usedInMwServer = true; + } + + public async Task Init(bool fetchData = false, List? ownerIds = null, bool allStates = false, bool fullTickets = false) + { + try + { + if (!InitOngoing && apiConnection != null) + { + Log.WriteDebug("Init start: ", $"{DateTime.Now:hh:mm:ss,fff}"); + InitOngoing = true; + if (usedInMwServer) + { + apiConnection.SetRole(Roles.MiddlewareServer); + } + else if (AuthUser != null) + { + apiConnection.SetProperRole(AuthUser, [Roles.Admin, Roles.FwAdmin, Roles.Requester, Roles.Approver, Roles.Planner, Roles.Implementer, Roles.Reviewer, Roles.Modeller, Roles.Auditor]); + } + else + { + throw new AuthenticationException("No AuthUser set"); + } + ActionHandler = new(apiConnection, this, UserGroups, usedInMwServer, RequestedRulePolicyChecker); + await ActionHandler.Init(); + dbAcc = new WfDbAccess(DisplayMessageInUi, userConfig, apiConnection, ActionHandler, AuthUser == null || AuthUser.IsInRole(Roles.Admin) || AuthUser.IsInRole(Roles.Auditor)) { }; + Devices = await apiConnection.SendQueryAsync>(DeviceQueries.getDeviceDetails); + AllOwners = await apiConnection.SendQueryAsync>(OwnerQueries.getOwners); + await stateMatrixDict.Init(Phase, apiConnection); + MasterStateMatrix = stateMatrixDict.Matrices[WfTaskType.master.ToString()]; + if (fetchData) + { + TicketList = await dbAcc.FetchTickets(MasterStateMatrix, ownerIds, allStates, fullTickets); + } + ReloadTasks = !fullTickets; + PrioList = System.Text.Json.JsonSerializer.Deserialize>(userConfig.ReqPriorities) ?? throw new JsonException("Config data could not be parsed."); + apiConnection.SwitchBack(); + Log.WriteDebug("Init stop: ", $"{DateTime.Now:hh:mm:ss,fff}"); + InitOngoing = false; + InitDone = true; + return true; + } + } + catch (Exception exception) + { + DisplayMessageInUi(exception, userConfig.GetText("init_environment"), "", true); + } + return false; + } + + public void FilterForRequester() + { + List filteredTicketList = []; + foreach (var ticket in TicketList) + { + if (userConfig.User.DbId == ticket.Requester?.DbId) + { + filteredTicketList.Add(ticket); + } + } + TicketList = filteredTicketList; + } + + public StateMatrix StateMatrix(string taskType) + { + try + { + return stateMatrixDict.Matrices[taskType]; + } + catch (Exception exception) + { + DisplayMessageInUi(exception, userConfig.GetText("state_matrix"), "", true); + return new(); + } + } + + public void SetContinueEnv(ObjAction action) + { + contOption = action; + } + + public async Task CheckRuleUid(int? deviceId, string? ruleUid) + { + if (dbAcc != null) + { + return await dbAcc.FindRuleUid(deviceId, ruleUid); + } + return false; + } + + private static void LogMessage(Exception? exception = null, string title = "", string message = "", bool ErrorFlag = false) + { + if (exception == null) + { + if (ErrorFlag) + { + Log.WriteWarning(title, message); + } + else + { + Log.WriteInfo(title, message); + } + } + else + { + Log.WriteError(title, message, exception); + } + } + } +} diff --git a/roles/lib/files/FWO.Services/Workflow/WfHandlerApprovals.cs b/roles/lib/files/FWO.Services/Workflow/WfHandlerApprovals.cs new file mode 100644 index 0000000000..e17edda53b --- /dev/null +++ b/roles/lib/files/FWO.Services/Workflow/WfHandlerApprovals.cs @@ -0,0 +1,195 @@ +using FWO.Data; +using FWO.Data.Workflow; +using System.Text.Json; + +namespace FWO.Services.Workflow +{ + public partial class WfHandler + { + public bool DisplayAssignApprovalMode = false; + public bool DisplayApprovalCommentMode = false; + + // approvals + + public async Task SetApprovalEnv(WfApproval? approval = null, bool createIfMissing = true) + { + if (approval != null) + { + ActApproval = new WfApproval(approval); + } + else + { + if (ActReqTask.Approvals.Count == 0 && createIfMissing) + { + await AddApproval(); + } + ActApproval = ActReqTask.Approvals.FirstOrDefault(x => x.StateId < ActStateMatrix.LowestEndState) + ?? ActReqTask.Approvals.Last() ?? new(); // todo: select own approvals + } + } + + public void SetApprovalPopUpOpt(ObjAction action) + { + DisplayAssignApprovalMode = action == ObjAction.displayAssign; + DisplayApprovalCommentMode = action == ObjAction.displayComment; + } + + public async Task SelectApprovalPopUp(WfApproval approval, ObjAction action) + { + await SetApprovalEnv(approval); + SetApprovalPopUpOpt(action); + } + + public void ResetApprovalActions() + { + DisplayAssignApprovalMode = false; + DisplayApprovalCommentMode = false; + } + + public async Task AddApproval(string extParams = "") + { + ApprovalParams approvalParams = new(); + if (extParams != "") + { + approvalParams = JsonSerializer.Deserialize(extParams) ?? throw new JsonException("Extparams could not be parsed."); + } + + DateTime? deadline = null; + if (extParams != "") + { + deadline = approvalParams.Deadline > 0 ? DateTime.Now.AddDays(approvalParams.Deadline) : null; + } + else + { + int? appDeadline = PrioList.FirstOrDefault(x => x.NumPrio == ActTicket.Priority)?.ApprovalDeadline; + deadline = appDeadline != null && appDeadline > 0 ? DateTime.Now.AddDays((int)appDeadline) : null; + } + + WfApproval approval = new() + { + TaskId = ActReqTask.Id, + StateId = extParams != "" ? approvalParams.StateId : ActStateMatrix.LowestInputState, + ApproverGroup = extParams != "" ? approvalParams.ApproverGroup : "", // todo: get from owner ???, + TenantId = ActTicket.TenantId, // ?? + Deadline = deadline, + InitialApproval = ActReqTask.Approvals.Count == 0 + }; + if (!approval.InitialApproval && dbAcc != null) + { + // todo: checks if new approval allowed (only one open per group?, ...) + approval.Id = await dbAcc.AddApprovalToDb(approval); + DisplayMessageInUi(null, userConfig.GetText("add_approval"), userConfig.GetText("U8002"), false); + } + ActReqTask.Approvals.Add(approval); + } + + public async Task ApproveTask(WfStatefulObject approval) + { + try + { + ActApproval.StateId = approval.StateId; + if (ActApproval.StateId >= ActStateMatrix.LowestEndState) + { + ActApproval.ApprovalDate = DateTime.Now; + ActApproval.ApproverDn = userConfig.User.Dn; + } + if (approval.OptComment() != null && approval.OptComment() != "") + { + await ConfAddCommentToApproval(approval.OptComment()!); + } + + if (ActApproval.Sanitize()) + { + DisplayMessageInUi(null, userConfig.GetText("save_approval"), userConfig.GetText("U0001"), true); + } + await UpdateActApproval(); + await UpdateActReqTaskStateFromApprovals(); + SyncActTicketFromReqTask(ActReqTask); + await UpdateActTicketStateFromReqTasks(); + ApproveReqTaskMode = false; + DisplayApproveMode = false; + } + catch (Exception exception) + { + DisplayMessageInUi(exception, userConfig.GetText("save_approval"), "", true); + } + } + + public async Task AssignApprovalGroup(WfStatefulObject statefulObject) + { + ActApproval.AssignedGroup = statefulObject.AssignedGroup; + await AssignApproval(statefulObject); + } + + public async Task AssignApprovalBack() // Todo: implement callers + { + ActApproval.AssignedGroup = ActApproval.RecentHandler?.Dn; + await AssignApproval(ActApproval); + } + + public async Task ConfAddCommentToApproval(string commentText) + { + WfComment comment = new() + { + Scope = WfObjectScopes.Approval.ToString(), + CreationDate = DateTime.Now, + Creator = userConfig.User, + CommentText = commentText + }; + if (dbAcc != null) + { + long commentId = await dbAcc.AddCommentToDb(comment); + if (commentId != 0) + { + await dbAcc.AssignCommentToApprovalInDb(ActApproval.Id, commentId); + } + } + ActApproval.Comments.Add(new WfCommentDataHelper(comment) { }); + DisplayApprovalCommentMode = false; + } + + private async Task AssignApproval(WfStatefulObject statefulObject) + { + ActApproval.RecentHandler = ActApproval.CurrentHandler; + await UpdateActApproval(); + if (ActionHandler != null) + { + await ActionHandler.DoOnAssignmentActions(statefulObject, ActApproval.AssignedGroup); + } + DisplayAssignApprovalMode = false; + } + + private async Task UpdateActApproval() + { + if (dbAcc != null) + { + await dbAcc.UpdateApprovalInDb(ActApproval); + } + ActReqTask.Approvals[ActReqTask.Approvals.FindIndex(x => x.Id == ActApproval.Id)] = ActApproval; + } + + private async Task UpdateActReqTaskStateFromApprovals() + { + if (ActReqTask.Approvals.Count > 0) + { + List approvalStates = []; + foreach (var approval in ActReqTask.Approvals) + { + approvalStates.Add(approval.StateId); + } + ActReqTask.StateId = ActStateMatrix.getDerivedStateFromSubStates(approvalStates); + } + await UpdateActReqTaskState(); + + // in the case impl tasks are already existing + foreach (var implTask in ActReqTask.ImplementationTasks) + { + implTask.StateId = ActReqTask.StateId; + if (dbAcc != null) + { + await dbAcc.UpdateImplTaskStateInDb(implTask); + } + } + } + } +} diff --git a/roles/lib/files/FWO.Services/Workflow/WfHandlerImplTasks.cs b/roles/lib/files/FWO.Services/Workflow/WfHandlerImplTasks.cs new file mode 100644 index 0000000000..4f8f732251 --- /dev/null +++ b/roles/lib/files/FWO.Services/Workflow/WfHandlerImplTasks.cs @@ -0,0 +1,424 @@ +using FWO.Basics; +using FWO.Data; +using FWO.Data.Workflow; + +namespace FWO.Services.Workflow +{ + public partial class WfHandler + { + public bool DisplayImplTaskMode = false; + public bool EditImplTaskMode = false; + public bool AddImplTaskMode = false; + public bool ImplementImplTaskMode = false; + public bool ReviewImplTaskMode = false; + public bool DisplayAssignImplTaskMode = false; + public bool DisplayApprovalImplMode = false; + public bool DisplayDeleteImplTaskMode = false; + public bool DisplayCleanupMode = false; + public bool DisplayImplTaskCommentMode = false; + + // Implementation Tasks + + public void SelectImplTask(WfImplTask implTask, ObjAction action) + { + SetImplTaskEnv(implTask); + SetImplTaskOpt(action); + } + + public void SelectImplTaskPopUp(WfImplTask implTask, ObjAction action) + { + SetImplTaskEnv(implTask); + SetImplTaskPopUpOpt(action); + } + + public void SetImplTaskEnv(WfImplTask implTask) + { + ActImplTask = new WfImplTask(implTask); + WfTicket? tick = TicketList.FirstOrDefault(x => x.Id == ActImplTask.TicketId); + if (tick != null) + { + ActTicket = tick; + WfReqTask? reqTask = ActTicket.Tasks.FirstOrDefault(x => x.Id == ActImplTask.ReqTaskId); + if (reqTask != null) + { + ActReqTask = reqTask; + } + } + ActStateMatrix = stateMatrixDict.Matrices[implTask.TaskType]; + } + + public void SetImplTaskOpt(ObjAction action) + { + ResetImplTaskActions(); + DisplayImplTaskMode = action == ObjAction.display || action == ObjAction.edit || action == ObjAction.add || action == ObjAction.implement || action == ObjAction.review; + EditImplTaskMode = action == ObjAction.edit || action == ObjAction.add; + AddImplTaskMode = action == ObjAction.add; + ImplementImplTaskMode = action == ObjAction.implement; + ReviewImplTaskMode = action == ObjAction.review; + } + + public void SetImplTaskPopUpOpt(ObjAction action) + { + DisplayPromoteImplTaskMode = action == ObjAction.displayPromote; + DisplayDeleteImplTaskMode = action == ObjAction.displayDelete; + DisplayCleanupMode = action == ObjAction.displayCleanup; + DisplayAssignImplTaskMode = action == ObjAction.displayAssign; + DisplayImplTaskCommentMode = action == ObjAction.displayComment; + DisplayApprovalImplMode = action == ObjAction.displayApprovals; + } + + public void ResetImplTaskActions() + { + DisplayImplTaskMode = false; + EditImplTaskMode = false; + AddImplTaskMode = false; + ImplementImplTaskMode = false; + ReviewImplTaskMode = false; + + DisplayPromoteImplTaskMode = false; + DisplayDeleteImplTaskMode = false; + DisplayCleanupMode = false; + DisplayAssignImplTaskMode = false; + DisplayImplTaskCommentMode = false; + DisplayApprovalImplMode = false; + } + + public async Task StartWorkOnImplTask(WfImplTask implTask, ObjAction action) + { + SetImplTaskEnv(implTask); + ActImplTask.CurrentHandler = userConfig.User; + List actPossibleStates = ActStateMatrix.getAllowedTransitions(ActImplTask.StateId); + if (actPossibleStates.Count == 1 && actPossibleStates[0] >= ActStateMatrix.LowestStartedState && actPossibleStates[0] < ActStateMatrix.LowestEndState) + { + ActImplTask.StateId = actPossibleStates[0]; + } + await UpdateActImplTaskState(); + if (!ActStateMatrix.PhaseActive[WorkflowPhases.planning] && ActReqTask.Start == null) + { + ActReqTask.Start = ActImplTask.Start; + } + await UpdateActTicketStateFromImplTasks(); + SetImplTaskOpt(action); + } + + public async Task ContinueImplPhase(WfImplTask implTask) + { + SelectImplTask(implTask, contOption); + if (ActImplTask.CurrentHandler != userConfig.User) + { + ActImplTask.CurrentHandler = userConfig.User; + await UpdateActImplTaskState(); + } + } + + public bool SelectOwnerImplTasks(FwoOwner selectedOwnerOpt) + { + try + { + AllVisibleImplTasks = []; + if (selectedOwnerOpt.Id != -3) + { + foreach (var ticket in TicketList) + { + SelectFromTicketByOwner(ticket, selectedOwnerOpt); + } + } + return selectedOwnerOpt.Id == -3; + } + catch (Exception exception) + { + DisplayMessageInUi(exception, userConfig.GetText("select_owner"), "", true); + } + return true; + } + + public bool SelectDeviceImplTasks(Device selectedDeviceOpt) + { + try + { + AllVisibleImplTasks = []; + if (selectedDeviceOpt.Id != -1) + { + foreach (var ticket in TicketList) + { + SelectFromTicketByDevice(ticket, selectedDeviceOpt); + } + } + return selectedDeviceOpt.Id == -1; + } + catch (Exception exception) + { + DisplayMessageInUi(exception, userConfig.GetText("select_device"), "", true); + } + return true; + } + + public async Task AssignImplTaskGroup(WfStatefulObject statefulObject) + { + ActImplTask.RecentHandler = ActImplTask.CurrentHandler ?? userConfig.User; + if (ActionHandler != null) + { + await UpdateActImplTaskState(); + await ActionHandler.DoOnAssignmentActions(statefulObject, ActImplTask.AssignedGroup); + } + DisplayAssignImplTaskMode = false; + } + + public async Task AssignImplTaskBack() + { + ActImplTask.AssignedGroup = ActImplTask.RecentHandler?.Dn; + ActImplTask.RecentHandler = ActImplTask.CurrentHandler ?? userConfig.User; + await UpdateActImplTaskState(); + if (ActionHandler != null) + { + await ActionHandler.DoOnAssignmentActions(ActImplTask, ActImplTask.AssignedGroup); + } + DisplayAssignImplTaskMode = false; + } + + public async Task AddImplTask() + { + if (dbAcc != null) + { + ActImplTask.Id = await dbAcc.AddImplTaskToDb(ActImplTask); + } + ActReqTask.ImplementationTasks.Add(ActImplTask); + } + + public async Task ChangeImplTask() + { + if (dbAcc != null) + { + await dbAcc.UpdateImplTaskInDb(ActImplTask, ActReqTask); + } + ActReqTask.ImplementationTasks[ActReqTask.ImplementationTasks.FindIndex(x => x.TaskNumber == ActImplTask.TaskNumber)] = ActImplTask; + } + + public async Task ConfAddCommentToImplTask(string commentText) + { + WfComment comment = new() + { + Scope = WfObjectScopes.ImplementationTask.ToString(), + CreationDate = DateTime.Now, + Creator = userConfig.User, + CommentText = commentText + }; + if (dbAcc != null) + { + long commentId = await dbAcc.AddCommentToDb(comment); + if (commentId != 0) + { + await dbAcc.AssignCommentToImplTaskInDb(ActImplTask.Id, commentId); + } + } + ActImplTask.Comments.Add(new WfCommentDataHelper(comment) { }); + DisplayImplTaskCommentMode = false; + } + + public async Task ConfDeleteImplTask() + { + if (dbAcc != null) + { + await dbAcc.DeleteImplTaskFromDb(ActImplTask); + } + ActReqTask.ImplementationTasks.RemoveAt(ActReqTask.ImplementationTasks.FindIndex(x => x.Id == ActImplTask.Id)); + DisplayDeleteImplTaskMode = false; + } + + public async Task ConfCleanupImplTasks() + { + if (dbAcc != null) + { + foreach (var impltask in ActReqTask.ImplementationTasks) + { + await dbAcc.DeleteImplTaskFromDb(impltask); + } + } + ActReqTask.ImplementationTasks.Clear(); + DisplayCleanupMode = false; + } + + public async Task CreateAccessImplTasksFromPathAnalysis(WfReqTask reqTask) + { + if (apiConnection != null) + { + foreach (var device in await PathAnalysis.GetAllDevices(reqTask.Elements, apiConnection)) + { + if (reqTask.ImplementationTasks.FirstOrDefault(x => x.DeviceId == device.Id) == null) + { + await CreateAccessImplTask(reqTask, device.Id); + } + } + } + } + + private async Task AutoCreateOrUpdateImplTasks() + { + if (Phase <= WorkflowPhases.approval && !MasterStateMatrix.PhaseActive[WorkflowPhases.planning] + && ActTicket.StateId >= MasterStateMatrix.LowestEndState) + { + foreach (var reqTask in ActTicket.Tasks) + { + // Todo: further analysis how many impl tasks currently have to be there and create or update where needed + if (reqTask.ImplementationTasks.Count == 0 + && reqTask.StateId >= stateMatrixDict.Matrices[reqTask.TaskType].MinImplTasksNeeded) + { + await AutoCreateImplTasks(reqTask); + } + else + { + await UpgradeImplTaskStatesToReqTask(reqTask); + } + } + } + } + + private async Task AutoCreateImplTasks(WfReqTask reqTask) + { + if (reqTask.TaskType == WfTaskType.access.ToString()) + { + await AutoCreateAccessImplTasks(reqTask); + return; + } + + await CreateGenericImplTask(reqTask); + } + + private async Task AutoCreateAccessImplTasks(WfReqTask reqTask) + { + switch (userConfig.ReqAutoCreateImplTasks) + { + case AutoCreateImplTaskOptions.never: + return; + case AutoCreateImplTaskOptions.onlyForOneDevice: + await CreateImplTaskForFirstDevice(reqTask); + return; + case AutoCreateImplTaskOptions.forEachDevice: + await CreateImplTasksForDevices(reqTask, [.. Devices.Select(device => device.Id)]); + return; + case AutoCreateImplTaskOptions.enterInReqTask: + await CreateImplTasksForDevices(reqTask, reqTask.GetResolvedDeviceList(Devices)); + return; + case AutoCreateImplTaskOptions.oneTaskForAllDevices: + await CreateImplTasksForCombinedOrSelectedDevices(reqTask); + return; + case AutoCreateImplTaskOptions.afterPathAnalysis: + await CreateAccessImplTasksFromPathAnalysis(reqTask); + return; + default: + return; + } + } + + private async Task CreateImplTaskForFirstDevice(WfReqTask reqTask) + { + if (Devices.Count > 0) + { + await CreateAccessImplTask(reqTask, Devices[0].Id, false); + } + } + + private async Task CreateImplTasksForCombinedOrSelectedDevices(WfReqTask reqTask) + { + List deviceIds = reqTask.GetDeviceList(); + if (deviceIds.Count == 0) + { + return; + } + + if (reqTask.HasAllDevicesSelected()) + { + await CreateAccessImplTask(reqTask, null, false); + return; + } + + await CreateImplTasksForDevices(reqTask, deviceIds); + } + + private async Task CreateImplTasksForDevices(WfReqTask reqTask, List deviceIds) + { + foreach (int deviceId in deviceIds) + { + await CreateAccessImplTask(reqTask, deviceId); + } + } + + private async Task CreateGenericImplTask(WfReqTask reqTask) + { + WfImplTask newImplTask = new(reqTask) { TaskNumber = reqTask.HighestImplTaskNumber() + 1, StateId = reqTask.StateId }; + if (dbAcc != null) + { + newImplTask.Id = await dbAcc.AddImplTaskToDb(newImplTask); + } + reqTask.ImplementationTasks.Add(newImplTask); + } + + private async Task CreateAccessImplTask(WfReqTask reqTask, int? deviceId, bool adaptTitle = true) + { + WfImplTask newImplTask; + newImplTask = new WfImplTask(reqTask) + { TaskNumber = reqTask.HighestImplTaskNumber() + 1, DeviceId = deviceId, StateId = reqTask.StateId }; + if (adaptTitle && deviceId != null) + { + Device? device = Devices.FirstOrDefault(x => x.Id == deviceId); + if (device != null) + { + newImplTask.Title += ": " + device.Name; + } + } + if (dbAcc != null) + { + newImplTask.Id = await dbAcc.AddImplTaskToDb(newImplTask); + } + reqTask.ImplementationTasks.Add(newImplTask); + } + + private void SelectFromTicketByDevice(WfTicket ticket, Device selectedDeviceOpt) + { + foreach (var reqTask in ticket.Tasks) + { + foreach (var implTask in reqTask.ImplementationTasks) + { + if (selectedDeviceOpt.Id == 0 || implTask.DeviceId == selectedDeviceOpt.Id) + { + implTask.TicketId = ticket.Id; + implTask.ReqTaskId = reqTask.Id; + AllVisibleImplTasks.Add(implTask); + } + } + } + } + + private void SelectFromTicketByOwner(WfTicket ticket, FwoOwner selectedOwnerOpt) + { + foreach (var reqTask in ticket.Tasks) + { + foreach (var implTask in reqTask.ImplementationTasks) + { + bool assignedToMe = implTask.CurrentHandler?.DbId == userConfig.User.DbId || implTask.AssignedGroup == userConfig.User.Dn; // todo: resolve group membership? + if (selectedOwnerOpt.Id == -1 || (selectedOwnerOpt.Id == -2 && assignedToMe) + || (selectedOwnerOpt.Id > 0 && reqTask.Owners.FirstOrDefault(o => o.Owner.Id == selectedOwnerOpt.Id) != null)) + { + implTask.TicketId = ticket.Id; + implTask.ReqTaskId = reqTask.Id; + AllVisibleImplTasks.Add(implTask); + } + } + } + } + + private void ResetImplTaskList() + { + AllTicketImplTasks = []; + foreach (var reqTask in ActTicket.Tasks) + { + foreach (var implTask in reqTask.ImplementationTasks) + { + implTask.TicketId = ActTicket.Id; + implTask.ReqTaskId = reqTask.Id; + AllTicketImplTasks.Add(implTask); + } + } + } + } +} diff --git a/roles/lib/files/FWO.Services/Workflow/WfHandlerReqTasks.cs b/roles/lib/files/FWO.Services/Workflow/WfHandlerReqTasks.cs new file mode 100644 index 0000000000..b780508294 --- /dev/null +++ b/roles/lib/files/FWO.Services/Workflow/WfHandlerReqTasks.cs @@ -0,0 +1,297 @@ +using FWO.Basics; +using FWO.Api.Client.Queries; +using FWO.Data; +using FWO.Data.Workflow; +using System.Text.Json; + +namespace FWO.Services.Workflow +{ + public partial class WfHandler + { + public bool DisplayReqTaskMode = false; + public bool EditReqTaskMode = false; + public bool AddReqTaskMode = false; + public bool PlanReqTaskMode = false; + public bool DisplayAssignReqTaskMode = false; + public bool DisplayApprovalReqMode = false; + public bool DisplayDeleteReqTaskMode = false; + public bool DisplayReqTaskCommentMode = false; + public bool DisplayPathAnalysisMode = false; + + // Request Tasks + + public async Task> LoadRequestTasks(IEnumerable reqTaskIds) + { + if (apiConnection == null) + { + return []; + } + + List taskIds = reqTaskIds.Where(id => id > 0).Distinct().ToList(); + + if (taskIds.Count == 0) + { + return []; + } + + List requestTasks = await apiConnection.SendQueryAsync>(RequestQueries.getRequestTasksByIds, new { task_ids = taskIds }); + new WfTicket() { Tasks = requestTasks }.UpdateCidrsInTaskElements(); + return requestTasks; + } + + public void SelectReqTask(WfReqTask reqTask, ObjAction action) + { + SetReqTaskEnv(reqTask); + SetReqTaskMode(action); + } + + public void SelectReqTaskPopUp(WfReqTask reqTask, ObjAction action) + { + SetReqTaskEnv(reqTask); + SetReqTaskPopUpOpt(action); + } + + public bool SetReqTaskEnv(long reqTaskId) + { + WfReqTask? reqTask; + foreach (var ticket in TicketList) + { + reqTask = ticket.Tasks.FirstOrDefault(x => x.Id == reqTaskId); + if (reqTask != null) + { + SetReqTaskEnv(reqTask); + return true; + } + } + return false; + } + + public void SetReqTaskEnv(WfReqTask reqTask) + { + ActReqTask = new(reqTask); + WfTicket? tick = TicketList.FirstOrDefault(x => x.Id == ActReqTask.TicketId); + if (tick != null) + { + ActTicket = tick; + } + ActStateMatrix = stateMatrixDict.Matrices[reqTask.TaskType]; + } + + public void SetReqTaskMode(ObjAction action) + { + ResetReqTaskActions(); + DisplayReqTaskMode = action == ObjAction.display || action == ObjAction.edit || action == ObjAction.add || action == ObjAction.approve || action == ObjAction.plan; + EditReqTaskMode = action == ObjAction.edit || action == ObjAction.add; + AddReqTaskMode = action == ObjAction.add; + PlanReqTaskMode = action == ObjAction.plan; + ApproveReqTaskMode = action == ObjAction.approve; + } + + public void SetReqTaskPopUpOpt(ObjAction action) + { + DisplayAssignReqTaskMode = action == ObjAction.displayAssign; + DisplayApprovalReqMode = action == ObjAction.displayApprovals; + DisplayApproveMode = action == ObjAction.displayApprove; + DisplayPromoteReqTaskMode = action == ObjAction.displayPromote; + DisplayDeleteReqTaskMode = action == ObjAction.displayDelete; + DisplayReqTaskCommentMode = action == ObjAction.displayComment; + DisplayPathAnalysisMode = action == ObjAction.displayPathAnalysis; + } + + public void ResetReqTaskActions() + { + DisplayReqTaskMode = false; + EditReqTaskMode = false; + AddReqTaskMode = false; + PlanReqTaskMode = false; + ApproveReqTaskMode = false; + + DisplayAssignReqTaskMode = false; + DisplayApprovalReqMode = false; + DisplayApproveMode = false; + DisplayPromoteReqTaskMode = false; + DisplayDeleteReqTaskMode = false; + DisplayReqTaskCommentMode = false; + DisplayPathAnalysisMode = false; + } + + public async Task StartWorkOnReqTask(WfReqTask reqTask, ObjAction action) + { + SetReqTaskEnv(reqTask); + ActReqTask.CurrentHandler = userConfig.User; + List actPossibleStates = ActStateMatrix.getAllowedTransitions(ActReqTask.StateId); + if (actPossibleStates.Count == 1 && actPossibleStates[0] >= ActStateMatrix.LowestStartedState && actPossibleStates[0] < ActStateMatrix.LowestEndState) + { + ActReqTask.StateId = actPossibleStates[0]; + if (Phase == WorkflowPhases.approval) + { + await SetApprovalEnv(); + List nextApprovalState = ActStateMatrix.getAllowedTransitions(ActApproval.StateId); + if (nextApprovalState.Count == 1 && nextApprovalState[0] >= ActStateMatrix.LowestStartedState && nextApprovalState[0] < ActStateMatrix.LowestEndState) + { + ActApproval.StateId = nextApprovalState[0]; + await UpdateActApproval(); + } + } + } + await UpdateActReqTaskState(); + await UpdateActTicketStateFromReqTasks(); + SetReqTaskMode(action); + } + + public async Task ContinuePhase(WfReqTask reqTask) + { + SelectReqTask(reqTask, contOption); + if (ActReqTask.CurrentHandler != userConfig.User) + { + ActReqTask.CurrentHandler = userConfig.User; + await UpdateActReqTaskState(); + } + } + + public async Task AssignReqTaskGroup(WfStatefulObject statefulObject) + { + ActReqTask.AssignedGroup = statefulObject.AssignedGroup; + ActReqTask.RecentHandler = ActReqTask.CurrentHandler ?? userConfig.User; + if (ActionHandler != null) + { + await UpdateActReqTaskState(); + await ActionHandler.DoOnAssignmentActions(statefulObject, ActReqTask.AssignedGroup); + } + DisplayAssignReqTaskMode = false; + } + + public async Task AssignReqTaskBack() + { + ActReqTask.AssignedGroup = ActReqTask.RecentHandler?.Dn; + ActReqTask.RecentHandler = ActReqTask.CurrentHandler ?? userConfig.User; + await UpdateActReqTaskState(); + if (ActionHandler != null) + { + await ActionHandler.DoOnAssignmentActions(ActReqTask, ActReqTask.AssignedGroup); + } + DisplayAssignReqTaskMode = false; + } + + public async Task AddReqTask() + { + if (ActTicket.Id > 0) // ticket already created -> write directly to db + { + ActReqTask.TicketId = ActTicket.Id; + if (dbAcc != null) + { + ActReqTask.Id = await dbAcc.AddReqTaskToDb(ActReqTask); + } + } + ActTicket.Tasks.Add(ActReqTask); + } + + public async Task ChangeReqTask() + { + if (ActReqTask.Id > 0 && dbAcc != null) + { + await dbAcc.UpdateReqTaskInDb(ActReqTask); + } + ActTicket.Tasks[ActTicket.Tasks.FindIndex(x => x.TaskNumber == ActReqTask.TaskNumber)] = ActReqTask; + } + + public async Task ChangeOwner() + { + if (ActReqTask.Id > 0 && dbAcc != null) + { + await dbAcc.UpdateOwnersInDb(ActReqTask); + } + ActTicket.Tasks[ActTicket.Tasks.FindIndex(x => x.TaskNumber == ActReqTask.TaskNumber)] = ActReqTask; + } + + public async Task ConfDeleteReqTask() + { + if (ActReqTask.Id > 0 && dbAcc != null) + { + await dbAcc.DeleteReqTaskFromDb(ActReqTask); + } + + ActTicket.Tasks.RemoveAll(x => x.Id == ActReqTask.Id); + // todo: adapt TaskNumbers of following tasks? + DisplayDeleteReqTaskMode = false; + } + + public async Task ConfAddCommentToReqTask(string commentText) + { + WfComment comment = new() + { + Scope = WfObjectScopes.RequestTask.ToString(), + CreationDate = DateTime.Now, + Creator = userConfig.User, + CommentText = commentText + }; + if (dbAcc != null) + { + long commentId = await dbAcc.AddCommentToDb(comment); + if (commentId != 0) + { + await dbAcc.AssignCommentToReqTaskInDb(ActReqTask.Id, commentId); + } + } + ActReqTask.Comments.Add(new WfCommentDataHelper(comment) { }); + DisplayReqTaskCommentMode = false; + } + + public string GetRequestingOwner() + { + int? ownerId = ActReqTask.GetAddInfoIntValue(AdditionalInfoKeys.ReqOwner); + if (ownerId != null) + { + return AllOwners.FirstOrDefault(x => x.Id == ownerId)?.Display() ?? ""; + } + return ""; + } + + public async Task SetAddInfoInReqTask(WfReqTask reqTask, string key, string newValue) + { + try + { + reqTask.SetAddInfo(key, newValue); + if (dbAcc != null) + { + await dbAcc.UpdateReqTaskAdditionalInfo(reqTask); + } + } + catch (Exception exception) + { + DisplayMessageInUi(exception, userConfig.GetText("promote_task"), "", true); + } + } + + public async Task HandlePathAnalysisAction(string extParams = "") + { + try + { + PathAnalysisActionParams pathAnalysisParams = new(); + if (extParams != "") + { + pathAnalysisParams = System.Text.Json.JsonSerializer.Deserialize(extParams) ?? throw new JsonException("Extparams could not be parsed."); + } + + switch (pathAnalysisParams.Option) + { + case PathAnalysisOptions.WriteToDeviceList: + if (apiConnection != null) + { + ActReqTask.SetDeviceList(await PathAnalysis.GetAllDevices(ActReqTask.Elements, apiConnection)); + } + break; + case PathAnalysisOptions.DisplayFoundDevices: + SetReqTaskPopUpOpt(ObjAction.displayPathAnalysis); + break; + default: + break; + } + } + catch (Exception exception) + { + DisplayMessageInUi(exception, userConfig.GetText("path_analysis"), "", true); + } + } + } +} diff --git a/roles/lib/files/FWO.Services/Workflow/WfHandlerStateChanges.cs b/roles/lib/files/FWO.Services/Workflow/WfHandlerStateChanges.cs new file mode 100644 index 0000000000..de273c180d --- /dev/null +++ b/roles/lib/files/FWO.Services/Workflow/WfHandlerStateChanges.cs @@ -0,0 +1,312 @@ +using FWO.Basics; +using FWO.Data.Workflow; + +namespace FWO.Services.Workflow +{ + public partial class WfHandler + { + // promote the different objects + + public async Task PromoteTicket(WfStatefulObject ticket) + { + try + { + ActTicket.StateId = ticket.StateId; + await UpdateActTicketState(); + ResetTicketActions(); + return true; + } + catch (Exception exception) + { + DisplayMessageInUi(exception, userConfig.GetText("promote_ticket"), "", true); + } + return false; + } + + public async Task PromoteTicketAndTasks(WfStatefulObject ticket) + { + try + { + if (await PromoteTicket(ticket)) + { + await UpdateRequestTasksFromTicket(false); + } + return true; + } + catch (Exception exception) + { + DisplayMessageInUi(exception, userConfig.GetText("promote_ticket"), "", true); + } + return false; + } + + public async Task PromoteReqTask(WfStatefulObject reqTask) + { + try + { + ActReqTask.StateId = reqTask.StateId; + if (ActReqTask.Start == null && ActReqTask.StateId >= ActStateMatrix.LowestStartedState) + { + ActReqTask.Start = DateTime.Now; + ActReqTask.CurrentHandler = userConfig.User; + } + await UpdateActReqTaskState(); + + if (Phase == WorkflowPhases.planning) + { + await UpgradeImplTaskStatesToReqTask(ActReqTask); + } + + await UpdateActTicketStateFromReqTasks(); + DisplayPromoteReqTaskMode = false; + } + catch (Exception exception) + { + DisplayMessageInUi(exception, userConfig.GetText("promote_task"), "", true); + } + } + + public async Task PromoteImplTask(WfStatefulObject implTask) + { + try + { + ActImplTask.StateId = implTask.StateId; + ActImplTask.CurrentHandler = userConfig.User; + if (Phase == WorkflowPhases.implementation && ActImplTask.Stop == null && ActImplTask.StateId >= ActStateMatrix.LowestEndState) + { + ActImplTask.Stop = DateTime.Now; + } + await UpdateActImplTaskState(); + ResetImplTaskList(); + SyncReqTaskStopTime(); + await UpdateReqTaskStateFromImplTasks(ActReqTask); + await UpdateActTicketStateFromReqTasks(); + DisplayPromoteImplTaskMode = false; + } + catch (Exception exception) + { + DisplayMessageInUi(exception, userConfig.GetText("save_task"), "", true); + } + } + + public async Task AutoPromote(WfStatefulObject statefulObject, WfObjectScopes scope, int? toStateId) + { + bool promotePossible = false; + if (toStateId != null) + { + statefulObject.StateId = (int)toStateId; + promotePossible = true; + } + else + { + List possibleStates = ActStateMatrix.getAllowedTransitions(statefulObject.StateId, true); + if (possibleStates.Count >= 1) + { + statefulObject.StateId = possibleStates[0]; + promotePossible = true; + } + } + + if (promotePossible) + { + switch (scope) + { + case WfObjectScopes.Ticket: + SetTicketEnv((WfTicket)statefulObject); + await PromoteTicket(statefulObject); + break; + case WfObjectScopes.RequestTask: + SetReqTaskEnv((WfReqTask)statefulObject); + ActReqTask.StateId = statefulObject.StateId; + ActReqTask.CurrentHandler = statefulObject.CurrentHandler; + await UpdateActReqTaskState(); + break; + case WfObjectScopes.ImplementationTask: + SetImplTaskEnv((WfImplTask)statefulObject); + ActImplTask.StateId = statefulObject.StateId; + ActImplTask.CurrentHandler = statefulObject.CurrentHandler; + await UpdateActImplTaskState(); + break; + case WfObjectScopes.Approval: + if (SetReqTaskEnv(((WfApproval)statefulObject).TaskId)) + { + await SetApprovalEnv(); + await ApproveTask(statefulObject); + } + break; + default: + break; + } + } + } + + + // synchronization between the different objects + + private async Task UpdateActTicketState() + { + if (ActTicket.StateId >= MasterStateMatrix.MinTicketCompleted) + { + ActTicket.CompletionDate = DateTime.Now; + } + await AutoCreateOrUpdateImplTasks(); + if (dbAcc != null) + { + await dbAcc.UpdateTicketStateInDb(ActTicket); + } + int idx = TicketList.FindIndex(x => x.Id == ActTicket.Id); + if (idx >= 0) + { + TicketList[idx] = ActTicket; + } + } + + private void SyncActTicketFromReqTask(WfReqTask reqTask) + { + int idx = ActTicket.Tasks.FindIndex(x => x.Id == reqTask.Id); + if (idx >= 0) + { + ActTicket.Tasks[idx] = reqTask; + } + } + + private async Task UpdateActTicketStateFromReqTasks() + { + if (ActTicket.Tasks.Count > 0) + { + List taskStates = []; + foreach (WfReqTask tsk in ActTicket.Tasks) + { + taskStates.Add(tsk.StateId); + } + ActTicket.StateId = MasterStateMatrix.getDerivedStateFromSubStates(taskStates); + } + await UpdateActTicketState(); + } + + private async Task UpdateActTicketStateFromImplTasks() + { + List tasks = [.. ActTicket.Tasks]; + foreach (WfReqTask reqTask in tasks) + { + await UpdateReqTaskStateFromImplTasks(reqTask); + } + await UpdateActTicketStateFromReqTasks(); + } + + public async Task UpdateActReqTaskState() + { + if (dbAcc != null) + { + await dbAcc.UpdateReqTaskStateInDb(ActReqTask); + } + SyncActTicketFromReqTask(ActReqTask); + } + + private async Task UpdateRequestTasksFromTicket(bool createImplTasks = true) + { + List requestTasks = [.. ActTicket.Tasks]; + foreach (WfReqTask reqtask in requestTasks) + { + if (reqtask.StateId <= ActTicket.StateId) + { + await UpdateReqTaskAndApprovalStatesFromTicket(reqtask); + } + if (createImplTasks && reqtask.ImplementationTasks.Count == 0 && !stateMatrixDict.Matrices[reqtask.TaskType].PhaseActive[WorkflowPhases.planning] + && reqtask.StateId >= stateMatrixDict.Matrices[reqtask.TaskType].MinImplTasksNeeded) + { + await AutoCreateImplTasks(reqtask); + } + } + } + + private async Task UpdateReqTaskAndApprovalStatesFromTicket(WfReqTask reqTask) + { + List ticketStateList = [ActTicket.StateId]; + StateMatrix reqTaskMatrix = stateMatrixDict.Matrices[reqTask.TaskType]; + reqTask.StateId = reqTaskMatrix.getDerivedStateFromSubStates(ticketStateList); + List approvalsToUpdate = reqTask.Approvals + .Where(x => x.StateId < reqTaskMatrix.ApprovalLowestEndState && x.StateId <= reqTask.StateId).ToList(); + foreach (WfApproval approval in approvalsToUpdate) + { + approval.StateId = reqTask.StateId; + } + + if (dbAcc != null) + { + await dbAcc.UpdateReqTaskStateInDb(reqTask); + foreach (WfApproval approval in approvalsToUpdate) + { + await dbAcc.UpdateApprovalInDb(approval); + } + } + } + + private async Task UpdateReqTaskStateFromImplTasks(WfReqTask reqTask) + { + if (reqTask.ImplementationTasks.Count > 0) + { + List implTaskStates = []; + foreach (var implTask in reqTask.ImplementationTasks) + { + implTaskStates.Add(implTask.StateId); + } + reqTask.StateId = ActStateMatrix.getDerivedStateFromSubStates(implTaskStates); + } + if (dbAcc != null) + { + await dbAcc.UpdateReqTaskStateInDb(reqTask); + } + SyncActTicketFromReqTask(reqTask); + } + + private async Task UpdateActImplTaskState() + { + if (dbAcc != null) + { + await dbAcc.UpdateImplTaskStateInDb(ActImplTask); + } + int index = ActReqTask.ImplementationTasks.FindIndex(x => x.Id == ActImplTask.Id); + if (index >= 0) + { + ActReqTask.ImplementationTasks[index] = ActImplTask; + } + else + { + // due to actions the impl task may not be assigned + ActReqTask.ImplementationTasks.Add(ActImplTask); + } + } + + private async Task UpgradeImplTaskStatesToReqTask(WfReqTask reqTask) + { + if (dbAcc != null) + { + foreach (var impltask in reqTask.ImplementationTasks) + { + if (impltask.StateId < reqTask.StateId) + { + impltask.StateId = reqTask.StateId; + await dbAcc.UpdateImplTaskStateInDb(impltask); + } + } + } + } + + private void SyncReqTaskStopTime() + { + bool openImplTask = false; + foreach (var impltask in ActReqTask.ImplementationTasks) + { + if (impltask.Stop == null) + { + openImplTask = true; + } + } + if (!openImplTask && ActReqTask.Stop == null) + { + ActReqTask.Stop = ActImplTask.Stop; + } + } + } +} diff --git a/roles/lib/files/FWO.Services/Workflow/WfHandlerTickets.cs b/roles/lib/files/FWO.Services/Workflow/WfHandlerTickets.cs new file mode 100644 index 0000000000..6204f38b50 --- /dev/null +++ b/roles/lib/files/FWO.Services/Workflow/WfHandlerTickets.cs @@ -0,0 +1,216 @@ +using FWO.Basics; +using FWO.Data; +using FWO.Data.Workflow; + +namespace FWO.Services.Workflow +{ + public partial class WfHandler + { + public bool DisplayTicketMode = false; + public bool EditTicketMode = false; + public bool AddTicketMode = false; + public bool DisplayPromoteTicketMode = false; + public bool DisplaySaveTicketMode = false; + + // Tickets + + public async Task ResolveTicket(long ticketId) + { + WfTicket? ticket = null; + if (dbAcc != null) + { + ticket = await dbAcc.FetchTicket(ticketId, userConfig.ReqOwnerBased ? AllOwners.ConvertAll(x => x.Id) : null); + if (ticket != null) + { + SetTicketEnv(ticket); + } + } + return ticket; + } + + public async Task HandleInjectedTicketId(WorkflowPhases phase, long ticketId) + { + WfTicket? ticket = await ResolveTicket(ticketId); + if (ticket != null) + { + if (ticket.StateId < MasterStateMatrix.LowestEndState) + { + await SelectTicket(ticket, ObjAction.edit, true); + } + else if (MasterStateMatrix.IsLastActivePhase) + { + await SelectTicket(ticket, ObjAction.display, true); + } + else + { + (WorkflowPhases newPhase, bool foundNewPhase) = await FindNewPhase(phase, ticket.StateId); + if (foundNewPhase) + { + return newPhase.ToString(); + } + } + } + return ""; + } + + public async Task> GetOpenTickets(string taskType, int cutOffPeriod = 0, SchedulerInterval interval = SchedulerInterval.Days) + { + if (dbAcc != null) + { + DateTime cutOffDate = interval switch + { + SchedulerInterval.Days => DateTime.Now.AddDays(-cutOffPeriod), + SchedulerInterval.Weeks => DateTime.Now.AddDays(-cutOffPeriod * GlobalConst.kDaysPerWeek), + SchedulerInterval.Months => DateTime.Now.AddMonths(-cutOffPeriod), + _ => throw new NotSupportedException("Time interval is not supported."), + }; + return await dbAcc.GetTicketsByParameters(taskType, StateMatrix(taskType).LowestInputState, StateMatrix(taskType).LowestEndState, cutOffDate); + } + return []; + } + + public async Task SelectTicket(WfTicket ticket, ObjAction action, bool reload = false) + { + if (ReloadTasks && reload && dbAcc != null) + { + ticket = await dbAcc.FetchTicket(ticket.Id) ?? ticket; + TicketList[TicketList.FindIndex(x => x.Id == ticket.Id)] = ticket; + } + SetTicketEnv(ticket); + SetTicketOpt(action); + } + + public void SetTicketEnv(WfTicket ticket) + { + ActTicket = ticket; + ResetImplTaskList(); + ActStateMatrix = MasterStateMatrix; + } + + public void SetTicketOpt(ObjAction action) + { + ResetTicketActions(); + DisplayTicketMode = action == ObjAction.display || action == ObjAction.edit || action == ObjAction.add; + EditTicketMode = action == ObjAction.edit || action == ObjAction.add; + AddTicketMode = action == ObjAction.add; + } + + public void SetTicketPopUpOpt(ObjAction action) + { + DisplayPromoteTicketMode = action == ObjAction.displayPromote; + DisplaySaveTicketMode = action == ObjAction.displaySaveTicket; + } + + public void ResetTicketActions() + { + DisplayTicketMode = false; + EditTicketMode = false; + AddTicketMode = false; + DisplayPromoteTicketMode = false; + DisplaySaveTicketMode = false; + } + + public async Task SaveTicket(WfStatefulObject ticket) + { + try + { + if (dbAcc != null) + { + ActTicket.StateId = ticket.StateId; + PrepareTicketData(); + + if (AddTicketMode) + { + // insert new ticket + ActTicket.CreationDate = DateTime.Now; + ActTicket.Requester = userConfig.User; + ActTicket = await dbAcc.AddTicketToDb(ActTicket); + TicketList.Add(ActTicket); + } + else + { + // Update existing ticket + ActTicket = await dbAcc.UpdateTicketInDb(ActTicket); + TicketList[TicketList.FindIndex(x => x.Id == ActTicket.Id)] = ActTicket; + } + + // update of request tasks and creation of impl tasks may be necessary + await UpdateRequestTasksFromTicket(); + + //check for further promotion (req tasks may be promoted) + await UpdateActTicketStateFromReqTasks(); + + ResetTicketActions(); + return ActTicket.Id; + } + } + catch (Exception exception) + { + DisplayMessageInUi(exception, userConfig.GetText("save_request"), "", true); + } + return 0; + } + + public async Task ConfAddCommentToTicket(string commentText) + { + WfComment comment = new() + { + Scope = WfObjectScopes.Ticket.ToString(), + CreationDate = DateTime.Now, + Creator = userConfig.User, + CommentText = commentText + }; + if (dbAcc != null) + { + long commentId = await dbAcc.AddCommentToDb(comment); + if (commentId != 0) + { + await dbAcc.AssignCommentToTicketInDb(ActTicket.Id, commentId); + } + } + ActTicket.Comments.Add(new WfCommentDataHelper(comment) { }); + } + + private async Task<(WorkflowPhases, bool)> FindNewPhase(WorkflowPhases phase, int stateId) + { + bool foundNewPhase = false; + if (apiConnection != null) + { + GlobalStateMatrix glbStateMatrix = GlobalStateMatrix.Create(); + await glbStateMatrix.Init(apiConnection, WfTaskType.master); + bool cont = true; + while (cont) + { + bool newPhase = MasterStateMatrix.getNextActivePhase(ref phase); + if (newPhase) + { + foundNewPhase = true; + } + cont = stateId >= glbStateMatrix.GlobalMatrix[phase].LowestEndState && newPhase; + } + } + return (phase, foundNewPhase); + } + + private void PrepareTicketData() + { + if (ActTicket.Sanitize()) + { + DisplayMessageInUi(null, userConfig.GetText("save_request"), userConfig.GetText("U0001"), true); + } + foreach (WfReqTask reqTask in ActTicket.Tasks) + { + if (reqTask.StateId < ActTicket.StateId) + { + reqTask.StateId = ActTicket.StateId; + } + } + + if (ActTicket.Deadline == null) + { + int? tickDeadline = PrioList.FirstOrDefault(x => x.NumPrio == ActTicket.Priority)?.TicketDeadline; + ActTicket.Deadline = tickDeadline != null && tickDeadline > 0 ? DateTime.Now.AddDays((int)tickDeadline) : null; + } + } + } +} diff --git a/roles/lib/files/FWO.Services/Workflow/WfStateDict.cs b/roles/lib/files/FWO.Services/Workflow/WfStateDict.cs new file mode 100644 index 0000000000..dec26d51be --- /dev/null +++ b/roles/lib/files/FWO.Services/Workflow/WfStateDict.cs @@ -0,0 +1,31 @@ +using FWO.Api.Client; +using FWO.Api.Client.Queries; +using FWO.Data.Workflow; + +namespace FWO.Services.Workflow +{ + public class WfStateDict + { + public Dictionary Name = []; + + /// + /// Returns the workflow state name for a state id or the numeric id as fallback. + /// + public string GetName(int stateId) + { + return Name.TryGetValue(stateId, out string? stateName) && !string.IsNullOrWhiteSpace(stateName) + ? stateName + : stateId.ToString(); + } + + public async Task Init(ApiConnection apiConnection) + { + List states = await apiConnection.SendQueryAsync>(RequestQueries.getStates); + Name = []; + foreach (var state in states) + { + Name.Add(state.Id, state.Name); + } + } + } +} diff --git a/roles/lib/files/chrome/last-known-good-versions-with-downloads.json b/roles/lib/files/chrome/last-known-good-versions-with-downloads.json new file mode 100644 index 0000000000..604f35744f --- /dev/null +++ b/roles/lib/files/chrome/last-known-good-versions-with-downloads.json @@ -0,0 +1,19 @@ +{ + "timestamp": "2024-11-15T00:00:00Z", + "channels": { + "Stable": { + "channel": "Stable", + "version": "128.0.6613.137", + "revision": "1188749", + "downloads": { + "chrome": [ + { + "platform": "linux64", + "url": "https://storage.googleapis.com/chrome-for-testing-public/128.0.6613.137/linux64/chrome-linux64.zip", + "revision": "1188749" + } + ] + } + } + } +} diff --git a/roles/lib/handlers/main.yml b/roles/lib/handlers/main.yml index 1160a3436a..73fd1380fc 100644 --- a/roles/lib/handlers/main.yml +++ b/roles/lib/handlers/main.yml @@ -24,3 +24,9 @@ - "Try to upgrade {{ product_name }} later or contact the support support@cactus.de" listen: "lib handler" when: lib_handler_guard == "start" + +- name: Reload Chrome AppArmor profile + command: + cmd: apparmor_parser --replace --write-cache /etc/apparmor.d/chrome + changed_when: false + become: true diff --git a/roles/lib/tasks/install_dot_net.yml b/roles/lib/tasks/install_dot_net.yml index 8f21d2dc54..b5cb36aefd 100644 --- a/roles/lib/tasks/install_dot_net.yml +++ b/roles/lib/tasks/install_dot_net.yml @@ -9,6 +9,14 @@ - set_fact: distribution_version="{{ debian_testing_version }}" when: ansible_facts['distribution_release']|lower == debian_testing_release_name + - name: set dotnet package name + set_fact: + dotnet_package_name: "dotnet-sdk-{{ dotnet_version }}" + + - name: decide whether dotnet script fallback is required + set_fact: + use_dotnet_install_script: "{{ ansible_facts['distribution']|lower == 'debian' and (ansible_facts['distribution_release']|lower == debian_testing_release_name or ansible_facts['distribution_major_version'] | int >= 13) }}" + # for all distros except ubuntu >=22.04 we need to include a package source - block: @@ -17,10 +25,21 @@ url: "https://packages.microsoft.com/config/{{ ansible_facts['distribution']|lower }}/{{ distribution_version }}/{{ dotnet_deb_name }}" dest: "{{ lib_tmp_dir }}/{{ dotnet_deb_name }}" mode: "0644" + register: dotnet_ms_repo_download + until: dotnet_ms_repo_download is succeeded + retries: 3 + delay: 5 + + - name: check ms package list status + command: dpkg-query -W -f='${Status}' packages-microsoft-prod + register: dotnet_ms_repo_pkg_status + changed_when: false + failed_when: false - name: install ms package list apt: deb: "{{ lib_tmp_dir }}/{{ dotnet_deb_name }}" + when: "'install ok installed' not in dotnet_ms_repo_pkg_status.stdout" - name: remove package list file file: @@ -28,38 +47,170 @@ state: absent - name: apt update - apt: update_cache=true - - when: ansible_facts['distribution']|lower != 'ubuntu' or - (ansible_facts['distribution']|lower == 'ubuntu' and ansible_facts['distribution_major_version'] is version('22', '<')) - - # - name: update /etc/apt/preferences for ubuntu >=22 (https://github.com/dotnet/sdk/issues/27129) - # blockinfile: - # path: /etc/apt/preferences - # create: true - # block: | - # Package: *net* - # Pin: origin packages.microsoft.com - # Pin-Priority: 1001 - # when: ansible_facts['distribution'] == "Ubuntu" and ansible_facts['distribution_major_version'] is version('22', '>=') - - # - name: make sure to use the ubuntu version of dotnet sdk on ubuntu >=22 - # file: - # path: /etc/apt/sources.list.d/{{ item }} - # state: absent - # loop: - # - "{{ dotnet_deb_name }}" - # - microsoft-prod.list - # when: ansible_facts['distribution'] == "Ubuntu" and ansible_facts['distribution_major_version'] is version('22', '>=') + apt: + update_cache: true + + when: + - not use_dotnet_install_script + - ansible_facts['distribution']|lower != 'ubuntu' or + (ansible_facts['distribution']|lower == 'ubuntu' and ansible_facts['distribution_major_version'] is version('22', '<')) - name: Install apt-transport-https package: name=apt-transport-https state=present + when: not use_dotnet_install_script - name: apt update - apt: update_cache=true + apt: + update_cache: true + when: not use_dotnet_install_script + + - block: + - name: Install {{ dotnet_package_name }} from current apt sources + package: + name: "{{ dotnet_package_name }}" + state: present + rescue: + - name: get package list from ms {{ dotnet_deb_name }} (ubuntu fallback) + get_url: + url: "https://packages.microsoft.com/config/{{ ansible_facts['distribution']|lower }}/{{ distribution_version }}/{{ dotnet_deb_name }}" + dest: "{{ lib_tmp_dir }}/{{ dotnet_deb_name }}" + mode: "0644" + register: dotnet_ms_repo_download_ubuntu_fallback + until: dotnet_ms_repo_download_ubuntu_fallback is succeeded + retries: 3 + delay: 5 + + - name: check ms package list status (ubuntu fallback) + command: dpkg-query -W -f='${Status}' packages-microsoft-prod + register: dotnet_ms_repo_pkg_status_ubuntu_fallback + changed_when: false + failed_when: false + + - name: install ms package list (ubuntu fallback) + apt: + deb: "{{ lib_tmp_dir }}/{{ dotnet_deb_name }}" + when: "'install ok installed' not in dotnet_ms_repo_pkg_status_ubuntu_fallback.stdout" + + - name: check for microsoft apt signing keyring (ubuntu fallback) + stat: + path: /usr/share/keyrings/microsoft-prod.gpg + register: dotnet_ms_keyring_ubuntu_fallback + + - name: ensure microsoft apt repo for dotnet on ubuntu fallback + apt_repository: + repo: "deb [arch={{ linux_architecture }} signed-by=/usr/share/keyrings/microsoft-prod.gpg] https://packages.microsoft.com/ubuntu/{{ distribution_version }}/prod {{ ansible_facts['distribution_release'] | lower }} main" + filename: microsoft-prod + state: present + when: dotnet_ms_keyring_ubuntu_fallback.stat.exists + + - name: ensure microsoft apt repo for dotnet on ubuntu fallback (no keyring path) + apt_repository: + repo: "deb [arch={{ linux_architecture }}] https://packages.microsoft.com/ubuntu/{{ distribution_version }}/prod {{ ansible_facts['distribution_release'] | lower }} main" + filename: microsoft-prod + state: present + when: not dotnet_ms_keyring_ubuntu_fallback.stat.exists + + - name: remove package list file (ubuntu fallback) + file: + dest: "{{ lib_tmp_dir }}/{{ dotnet_deb_name }}" + state: absent + + - name: prefer microsoft packages for dotnet on ubuntu fallback + blockinfile: + path: /etc/apt/preferences.d/fworch-dotnet + create: true + mode: "0644" + block: | + Package: dotnet-* aspnetcore-* netstandard-* + Pin: origin packages.microsoft.com + Pin-Priority: 999 + + - name: apt update after microsoft repo fallback + apt: + update_cache: true + + - block: + - name: Install {{ dotnet_package_name }} after microsoft repo fallback + package: + name: "{{ dotnet_package_name }}" + state: present + rescue: + - name: download dotnet-install script (ubuntu fallback) + get_url: + url: https://dot.net/v1/dotnet-install.sh + dest: "{{ lib_tmp_dir }}/dotnet-install.sh" + mode: "0755" + register: dotnet_install_script_download + until: dotnet_install_script_download is succeeded + retries: 3 + delay: 5 + + - name: install dotnet sdk {{ dotnet_version }} with dotnet-install script (ubuntu fallback) + command: "{{ lib_tmp_dir }}/dotnet-install.sh --channel {{ dotnet_version }} --quality ga --install-dir /usr/share/dotnet" + + - name: ensure dotnet symlink exists (ubuntu fallback) + file: + src: /usr/share/dotnet/dotnet + dest: /usr/bin/dotnet + state: link + force: true + + - name: verify dotnet sdk {{ dotnet_version }} is installed (ubuntu fallback) + command: /usr/share/dotnet/dotnet --list-sdks + register: dotnet_sdks_after_script_install + changed_when: false + failed_when: dotnet_version not in dotnet_sdks_after_script_install.stdout + when: + - ansible_facts['distribution']|lower == 'ubuntu' + - ansible_facts['distribution_major_version'] is version('22', '>=') + - ansible_architecture == "x86_64" + - not use_dotnet_install_script + + - name: Install dotnet-sdk-{{ dotnet_version }} on distro defaults + package: + name: "{{ dotnet_package_name }}" + state: present + when: + - ansible_architecture == "x86_64" + - not use_dotnet_install_script + - ansible_facts['distribution']|lower != 'ubuntu' or + (ansible_facts['distribution']|lower == 'ubuntu' and ansible_facts['distribution_major_version'] is version('22', '<')) + + - name: Install dotnet sdk {{ dotnet_version }} with dotnet-install script on Debian testing + block: + - name: download dotnet-install script for Debian testing + get_url: + url: https://dot.net/v1/dotnet-install.sh + dest: "{{ lib_tmp_dir }}/dotnet-install.sh" + mode: "0755" + register: dotnet_install_script_download_debian + until: dotnet_install_script_download_debian is succeeded + retries: 3 + delay: 5 + + - name: install dotnet sdk {{ dotnet_version }} with dotnet-install script on Debian testing + command: "{{ lib_tmp_dir }}/dotnet-install.sh --channel {{ dotnet_version }} --quality ga --install-dir /usr/share/dotnet" + + - name: ensure dotnet symlink exists on Debian testing + file: + src: /usr/share/dotnet/dotnet + dest: /usr/bin/dotnet + state: link + force: true + + - name: verify dotnet sdk {{ dotnet_version }} is installed on Debian testing + command: /usr/share/dotnet/dotnet --list-sdks + register: dotnet_sdks_after_script_install_debian + changed_when: false + failed_when: dotnet_version not in dotnet_sdks_after_script_install_debian.stdout + when: + - ansible_architecture == "x86_64" + - use_dotnet_install_script - - name: Install dotnet-sdk-{{ dotnet_version }} - package: "name=dotnet-sdk-{{ dotnet_version }} state=present" + - debug: + msg: + - "NOTE: you need to install dotnet yourself for architectures other than x86_64 before running FWO installer" + when: ansible_architecture != "x86_64" become: true - environment: "{{ proxy_env }}" \ No newline at end of file + environment: "{{ proxy_env }}" diff --git a/roles/lib/tasks/install_puppeteer.yml b/roles/lib/tasks/install_puppeteer.yml new file mode 100644 index 0000000000..826964a64f --- /dev/null +++ b/roles/lib/tasks/install_puppeteer.yml @@ -0,0 +1,283 @@ +- block: + # install libs needed for nuget package PuppeteerSharp + - name: Define core packages + set_fact: + core_packages: + - ca-certificates + - fonts-liberation + - libappindicator3-1 + - libatk-bridge2.0-0 + - libatk1.0-0 + - libcups2 + - libdbus-1-3 + - libdrm2 + - libgbm1 + - libnspr4 + - libnss3 + - libx11-xcb1 + - libxcomposite1 + - libxdamage1 + - libxrandr2 + - xdg-utils + + - name: Define default platform-specific library names + set_fact: + glib_library: libglib2.0-0 + sound_library: libasound2 + + - name: Define new library names based on newer OS versions + set_fact: + glib_library: libglib2.0-0t64 + sound_library: libasound2t64 + when: > + ansible_facts['distribution'] == "Ubuntu" and ansible_facts['distribution_version'] | float >= 24.04 + or ansible_facts['distribution'] == "Debian" and ansible_facts['distribution_version'] | float >= 13 + or ansible_facts['distribution'] == "Debian" and ansible_lsb.codename == "trixie" + + - block: # only use apparmor for ubuntu 24.04ff + - name: Ensure the /etc/apparmor.d directory exists + file: + path: /etc/apparmor.d + state: directory + mode: "0755" + + - name: Create /etc/apparmor.d/chrome + copy: + dest: /etc/apparmor.d/chrome + content: | + include + + profile /usr/local/fworch/bin/**/chrome flags=(unconfined) { + userns, + + # Site-specific additions and overrides. See local/README for details. + # Include the local overrides only if the file exists. + # This is a common best practice to avoid parser errors. + include if exists + } + mode: "0644" + notify: + - Reload Chrome AppArmor profile + + when: ansible_facts['distribution'] == "Ubuntu" and ansible_facts['distribution_version'] | float >= 24.04 + + - name: Install additional libraries for old Debian 11 + apt: + name: + - libpangocairo-1.0-0 + - libpangoft2-1.0-0 + state: present + update_cache: yes + when: ansible_facts['distribution'] == "Debian" and ansible_facts['distribution_version'] == "11" + + - name: Combine all packages + set_fact: + platform_packages: "{{ core_packages + [sound_library, glib_library] }}" + + - name: Install all combined dependencies + apt: + name: "{{ platform_packages }}" + state: present + update_cache: yes + + become: true + environment: "{{ proxy_env }}" + +# get google chrome for pdf generation +- name: get last known good versions (primary) + uri: + url: https://googlechromelabs.github.io/chrome-for-testing/last-known-good-versions-with-downloads.json + return_content: true + register: chrome_versions_primary + failed_when: false + become: false + environment: "{{ proxy_env }}" + +- name: get last known good versions (github api raw) + uri: + url: https://api.github.com/repos/GoogleChromeLabs/chrome-for-testing/contents/data/last-known-good-versions-with-downloads.json?ref=main + headers: + Accept: application/vnd.github.v3.raw + return_content: true + register: chrome_versions_github_api + failed_when: false + become: false + environment: "{{ proxy_env }}" + +- name: pick chrome metadata source (primary -> github api) + set_fact: + chrome_versions: >- + {{ + chrome_versions_primary + if (chrome_versions_primary.status | default(-1)) == 200 else + chrome_versions_github_api + }} + +- name: fail when no chrome metadata available + fail: + msg: "Could not fetch Chrome for Testing version metadata via primary URL or GitHub API." + when: chrome_versions.status | default(-1) != 200 + +# Parse once, regardless of Content-Type +- name: normalize/parse JSON response + set_fact: + chrome_versions_parsed: >- + {{ + chrome_versions.json + if (chrome_versions.json is defined) + else (chrome_versions.content | trim | from_json) + }} + +# Pick the Stable channel (some users accidentally use 'stable', so be flexible) +- name: select Stable channel + set_fact: + chrome_for_testing_stable: "{{ chrome_versions_parsed.channels.Stable | default(chrome_versions_parsed.channels.stable) }}" # Chrome for Testing feed + +# Base path for all Chrome installs +- name: set chrome root dir + set_fact: + chrome_root_dir: "/usr/local/fworch/bin/Chrome" + +# Extract downloads + version from Stable +- name: parse latest stable versions for chrome #and headless shell + set_fact: + stable_chrome_versions: "{{ chrome_for_testing_stable.downloads }}" + chrome_dest: "{{ chrome_root_dir }}/Linux-{{ chrome_for_testing_stable.version }}" + +# (Optional) sanity checks to fail early with a clear message +- name: validate parsed data + assert: + that: + - chrome_versions_parsed is mapping + - chrome_for_testing_stable is mapping + - chrome_for_testing_stable.version is defined + - chrome_for_testing_stable.downloads is defined + fail_msg: "Failed to parse Chrome for Testing JSON or locate the Stable channel." + +- block: + - name: ensure chrome root directory exists + file: + path: "{{ chrome_root_dir }}" + state: directory + mode: "0755" + + - name: find existing chrome installations + find: + paths: "{{ chrome_root_dir }}" + file_type: directory + patterns: "Linux-*" + recurse: false + register: chrome_installs + + - name: remove outdated chrome versions + file: + path: "{{ item.path }}" + state: absent + loop: "{{ chrome_installs.files | default([]) }}" + when: item.path != chrome_dest + loop_control: + label: "{{ item.path }}" + + become: true + +- block: + - name: install unzip + package: + name: unzip + state: present + + - name: create chrome install path + file: + path: "{{ chrome_dest }}" + state: directory + mode: "0755" + + # Figure out the target (remote) Chrome URL and MAJOR version + - name: set chrome URL and archive path + set_fact: + chrome_url: >- + {{ stable_chrome_versions['chrome'] + | selectattr('platform', 'match', 'linux64') + | map(attribute='url') | first }} + chrome_archive: >- + {{ chrome_dest }}/{{ ( + stable_chrome_versions['chrome'] + | selectattr('platform','match','linux64') + | map(attribute='url') | first + ) | urlsplit('path') | basename }} + + # If your data has an explicit 'version' attribute, prefer that. + # Otherwise, fall back to parsing the version from the URL. + - name: derive target chrome major version + set_fact: + target_version_full: >- + {{ (stable_chrome_versions['chrome'] + | selectattr('platform','match','linux64') + | map(attribute='version') | first) | default('', true) }} + target_major_fallback: "{{ chrome_url | regex_search('\\d+') }}" + - name: finalize target major version + set_fact: + target_major: >- + {{ (target_version_full | regex_search('\\d+')) + | default(target_major_fallback, true) | int }} + + # Detect currently installed Chrome major version (if present) + - name: check if chrome is installed (via symlinked bin) + stat: + path: "{{ fworch_home }}/bin/chrome" + register: chrome_bin + + - name: read installed chrome version + command: "{{ fworch_home }}/bin/chrome --version" + register: installed_ver + changed_when: false + failed_when: false + when: chrome_bin.stat.exists + + - name: parse installed major version (defaults to 0 when absent) + set_fact: + installed_major: >- + {{ (installed_ver.stdout | default('') | regex_search('\\d+')) + | default(0, true) | int }} + + - name: decide if update is needed (only on major bump) + set_fact: + chrome_major_update_needed: "{{ target_major != installed_major }}" + + # Only download when the MAJOR version changed or Chrome isn't installed + - name: download google chrome archive (only on major change) + get_url: + url: "{{ chrome_url }}" + dest: "{{ chrome_archive }}" + mode: "0644" + force: no + timeout: 60 + register: chrome_pkg + when: chrome_major_update_needed or (not chrome_bin.stat.exists) + + - name: unpack chrome when archive downloaded + unarchive: + src: "{{ chrome_archive }}" + dest: "{{ chrome_dest }}" + remote_src: yes + when: chrome_pkg is defined and chrome_pkg.changed + + - name: create symlinks {{ chrome_dest }}/chrome-linux64 to {{ fworch_home }}/bin/* + file: + src: "{{ chrome_dest }}/chrome-linux64/{{ item }}" + dest: "{{ fworch_home }}/bin/{{ item }}" + state: link + loop: + - chrome + - chrome-wrapper + - chrome_crashpad_handler + - chrome_sandbox + + - name: add {{ fworch_home }}/bin to every users path + copy: + dest: /etc/profile.d/custom_path.sh + content: 'export PATH="{{ fworch_home }}/bin:$PATH"' + mode: "0644" + + become: true + environment: "{{ proxy_env }}" diff --git a/roles/lib/tasks/install_wkhtml_pdf.yml b/roles/lib/tasks/install_wkhtml_pdf.yml deleted file mode 100644 index 77863b0632..0000000000 --- a/roles/lib/tasks/install_wkhtml_pdf.yml +++ /dev/null @@ -1,39 +0,0 @@ - -- block: - - - name: install libs needed for pdf creator nuget packet HakanL/WkHtmlToPdf-DotNet - package: - name: "{{ item }}" - state: present - loop: - - libgdiplus - - libc6-dev - - libjpeg62 - - fontconfig - - xfonts-base - - xfonts-75dpi - - libssl-dev - - - block: - - name: download wkhtmltox for ubuntu 22.04 only - get_url: - url: https://github.com/wkhtmltopdf/packaging/releases/download/0.12.6.1-2/wkhtmltox_0.12.6.1-2.jammy_amd64.deb - dest: "{{ lib_tmp_dir }}/wkhtmltox_0.12.6.1-2.jammy_amd64.deb" - force: true - mode: "0644" - owner: "{{ fworch_user }}" - group: "{{ fworch_group }}" - environment: "{{ proxy_env }}" - - - name: install wkhtmltox for ubuntu 22.04 only - command: dpkg -i {{ lib_tmp_dir }}/wkhtmltox_0.12.6.1-2.jammy_amd64.deb - - - name: remove wkhtmltox package file after installation (for ubuntu 22.04 only) - file: - path: "{{ lib_tmp_dir }}/wkhtmltox_0.12.6.1-2.jammy_amd64.deb" - state: absent - when: ansible_facts['distribution'] == "Ubuntu" and ansible_facts['distribution_version'] == '22.04' - - become: true - environment: "{{ proxy_env }}" - \ No newline at end of file diff --git a/roles/lib/tasks/main.yml b/roles/lib/tasks/main.yml index 5aa55cc628..fc190e9d9d 100644 --- a/roles/lib/tasks/main.yml +++ b/roles/lib/tasks/main.yml @@ -1,12 +1,10 @@ - - block: - - name: initialize handler for datarecovery set_fact: lib_handler_guard: start changed_when: true notify: - - lib handler + - lib handler when: installation_mode == "upgrade" - name: check for lib dir @@ -21,12 +19,6 @@ delegate_to: "{{ inventory_hostname }}" when: lib_dir_check.stat.exists and installation_mode == "upgrade" - - name: remove lib dir - file: - state: absent - path: "{{ fworch_home }}/lib" - - - name: create {{ lib_tmp_dir }} including lib dir file: dest: "{{ lib_tmp_dir }}" @@ -37,28 +29,21 @@ - name: install dotnet needed for both ui and middleware servers include_tasks: install_dot_net.yml - - name: install wkhtml pdf library needed for both ui and middleware servers - include_tasks: install_wkhtml_pdf.yml + # this is still buggy: + # - name: remove dotnet packages older than target version + # include_tasks: remove-old-dotnet-versions.yml + + - name: install puppeteer needed for both ui and middleware servers PDF creation + include_tasks: install_puppeteer.yml - name: copy {{ product_name }} dotnet lib files to lib target - copy: - src: "{{ item }}" + synchronize: + src: "./" dest: "{{ lib_dir }}" - owner: "{{ fworch_user }}" - group: "{{ fworch_group }}" - loop: - - FWO.Api.Client - - FWO.Middleware - - FWO.Middleware.Client - - FWO.Logging - - FWO.Config.Api - - FWO.Config.File - - FWO.Recert - - FWO.Report - - FWO.Report.Filter - - FWO.DeviceAutoDiscovery - - FWO.Mail - tags: [ 'test' ] + rsync_opts: + - "--delete" + - "--chown={{ fworch_user }}:{{ fworch_group }}" + tags: ["test"] - name: finalize handler for datarecovery set_fact: diff --git a/roles/lib/tasks/remove-old-dotnet-versions.yml b/roles/lib/tasks/remove-old-dotnet-versions.yml new file mode 100644 index 0000000000..e1e62e8bd3 --- /dev/null +++ b/roles/lib/tasks/remove-old-dotnet-versions.yml @@ -0,0 +1,28 @@ +- name: gather installed package facts + package_facts: + manager: auto + +- name: set target dotnet major version + set_fact: + dotnet_version_major: "{{ dotnet_version.split('.')[0] | int }}" + +- name: initialize dotnet package removal list + set_fact: + dotnet_packages_to_remove: [] + +- name: collect dotnet packages older than target version + set_fact: + dotnet_packages_to_remove: "{{ (dotnet_packages_to_remove | default([])) + [item] }}" + loop: "{{ ansible_facts.packages.keys() | list }}" + when: + - item is match('^(dotnet|aspnetcore)-.*-\\d+\\.\\d+$') + - (item | regex_search('-(\\d+)\\.\\d+$', '\\1') | int) < (dotnet_version_major | int) + +- name: remove dotnet packages older than target version + package: + name: "{{ dotnet_packages_to_remove }}" + state: absent + when: + - installation_mode == "upgrade" + - dotnet_packages_to_remove is defined + - dotnet_packages_to_remove | length > 0 diff --git a/roles/middleware/files/FWO.Middleware.Server/AppDataImport.cs b/roles/middleware/files/FWO.Middleware.Server/AppDataImport.cs new file mode 100644 index 0000000000..edccacfd20 --- /dev/null +++ b/roles/middleware/files/FWO.Middleware.Server/AppDataImport.cs @@ -0,0 +1,1291 @@ +using FWO.Api.Client; +using FWO.Api.Client.Queries; +using FWO.Basics; +using FWO.Config.Api; +using FWO.Data; +using FWO.Data.Modelling; +using FWO.Logging; +using FWO.Recert; +using FWO.Services; +using FWO.Services.Modelling; +using Novell.Directory.Ldap; +using System.Data; +using System.Text.Json; + +namespace FWO.Middleware.Server +{ + /// + /// Class handling the App Data Import + /// + public class AppDataImport : DataImportBase + { + private List ImportedApps = []; + private List ExistingApps = []; + private List ExistingAppServers = []; + + private Ldap internalLdap = new(); + + private List connectedLdaps = []; + private Dictionary> rolesToSetByType = []; + private Dictionary ownerResponsibleTypeById = []; + private Dictionary ownerResponsibleTypeIdByName = new(StringComparer.OrdinalIgnoreCase); + private Dictionary ownerLifeCycleStateIdsByName = new(StringComparer.OrdinalIgnoreCase); + private Dictionary ownerLifeCycleStateActiveById = []; + private bool hasImmediateAppDecommNotificationForImport; + private ModellingNamingConvention NamingConvention = new(); + private UserConfig userConfig = new(); + private const string LogMessageTitle = "Import App Data"; + private const string LevelFile = "Import File"; + private const string LevelApp = "App"; + private const string LevelAppServer = "App Server"; + + /// + /// Constructor for App Data Import + /// + public AppDataImport(ApiConnection apiConnection, GlobalConfig globalConfig) : base(apiConnection, globalConfig) + { } + + /// + /// Run the App Data Import + /// + public async Task> Run() + { + NamingConvention = JsonSerializer.Deserialize(globalConfig.ModNamingConvention) ?? new(); + List importfilePathAndNames = JsonSerializer.Deserialize>(globalConfig.ImportAppDataPath) ?? throw new JsonException("Config Data could not be deserialized."); + userConfig = new(globalConfig); + userConfig.User.Name = Roles.MiddlewareServer; + userConfig.AutoReplaceAppServer = globalConfig.AutoReplaceAppServer; + await InitLdap(); + await InitResponsibleTypes(); + await InitOwnerLifeCycleStates(); + hasImmediateAppDecommNotificationForImport = await LoadHasImmediateAppDecommNotification(); + List failedImports = []; + var ownerChangeTracker = new OwnerChangeImportTracker(apiConnection); + + foreach (var importfilePathAndName in importfilePathAndNames) + { + if (!RunImportScript(importfilePathAndName + ".py", globalConfig.ImportAppDataScriptArgs)) + { + Log.WriteInfo(LogMessageTitle, $"Script {importfilePathAndName}.py failed but trying to import from existing file."); + } + await ImportSingleSource(importfilePathAndName + ".json", failedImports, ownerChangeTracker); + } + + await ownerChangeTracker.CompleteImport(failedImports.Count == 0); + return failedImports; + } + + private async Task InitLdap() + { + connectedLdaps = await apiConnection.SendQueryAsync>(AuthQueries.getLdapConnections); + internalLdap = connectedLdaps.FirstOrDefault(x => x.IsInternal() && x.HasGroupHandling()) ?? throw new KeyNotFoundException("No internal Ldap with group handling found."); + rolesToSetByType = ParseRolesWithImport(globalConfig.RolesWithAppDataImport); + } + + private async Task InitResponsibleTypes() + { + List responsibleTypes = (await apiConnection.SendQueryAsync>(OwnerQueries.getOwnerResponsibleTypes)) + .Where(type => type.Active).ToList(); + ownerResponsibleTypeById = responsibleTypes.ToDictionary(type => type.Id, type => type); + ownerResponsibleTypeIdByName = new(StringComparer.OrdinalIgnoreCase); + foreach (OwnerResponsibleType type in responsibleTypes) + { + if (!string.IsNullOrWhiteSpace(type.Name)) + { + ownerResponsibleTypeIdByName[type.Name.Trim()] = type.Id; + } + } + } + + private async Task InitOwnerLifeCycleStates() + { + List lifeCycleStates = await apiConnection.SendQueryAsync>(OwnerQueries.getOwnerLifeCycleStates); + ownerLifeCycleStateIdsByName = new(StringComparer.OrdinalIgnoreCase); + ownerLifeCycleStateActiveById = []; + foreach (OwnerLifeCycleState state in lifeCycleStates) + { + if (!string.IsNullOrWhiteSpace(state.Name)) + { + ownerLifeCycleStateIdsByName[state.Name.Trim()] = state.Id; + ownerLifeCycleStateActiveById[state.Id] = state.ActiveState; + } + } + } + + private async Task ImportSingleSource(string importfileName, List failedImports, OwnerChangeImportTracker ownerChangeTracker) + { + try + { + ReadFile(importfileName); + ModellingImportOwnerData? importedOwnerData = JsonSerializer.Deserialize(importFile) ?? throw new JsonException("File could not be parsed."); + if (importedOwnerData != null && importedOwnerData.Owners != null) + { + ImportedApps = importedOwnerData.Owners; + await ImportApps(importfileName, ownerChangeTracker); + } + } + catch (Exception exc) + { + string errorText = $"File {importfileName} could not be processed."; + Log.WriteError(LogMessageTitle, errorText, exc); + await AddLogEntry(2, LevelFile, errorText); + failedImports.Add(importfileName); + } + } + + private async Task ImportApps(string importfileName, OwnerChangeImportTracker ownerChangeTracker) + { + int successCounter = 0; + int failCounter = 0; + int deleteCounter = 0; + int deleteFailCounter = 0; + + ExistingApps = await apiConnection.SendQueryAsync>(OwnerQueries.getOwnersWithNetworks); + foreach (var incomingApp in ImportedApps) + { + if (await SaveApp(incomingApp, ownerChangeTracker)) + { + ++successCounter; + } + else + { + ++failCounter; + } + } + string? importSource = ImportedApps.FirstOrDefault()?.ImportSource; + if (importSource != null) + { + (deleteCounter, deleteFailCounter) = await DeactivateMissingApps(importSource, ownerChangeTracker); + } + string messageText = $"Imported from {importfileName}: {successCounter} apps, {failCounter} failed. Deactivated {deleteCounter} apps, {deleteFailCounter} failed."; + Log.WriteInfo(LogMessageTitle, messageText); + await AddLogEntry(0, LevelFile, messageText); + } + + private async Task SaveApp(ModellingImportAppData incomingApp, OwnerChangeImportTracker ownerChangeTracker) + { + try + { + incomingApp = await NormalizeImportedUserReferences(incomingApp); + int appId; + if (!TryResolveOwnerLifeCycleStateId(incomingApp, out int? ownerLifeCycleStateId)) + { + string errorText = $"App {incomingApp.Name} could not be processed because owner lifecycle state \"{incomingApp.OwnerLifecycleState}\" is missing."; + Log.WriteWarning(LogMessageTitle, errorText); + await AddLogEntry(1, LevelApp, errorText); + return false; + } + List responsibles = BuildOwnerResponsibles(incomingApp); + + FwoOwner? existingApp = ExistingApps.FirstOrDefault(x => x.ExtAppId == incomingApp.ExtAppId); + + if (existingApp == null) + { + appId = await NewApp(incomingApp, ownerLifeCycleStateId, responsibles); + await ownerChangeTracker.AddOwnerChange(null, appId, ChangelogActionType.INSERT, incomingApp.ImportSource); + } + else + { + appId = existingApp.Id; + await UpdateApp(incomingApp, existingApp, ownerLifeCycleStateId, responsibles); + await AddOwnerChangeIfNeeded(existingApp, incomingApp, ownerChangeTracker); + await AddOwnerLifeCycleStateActiveChangeIfNeeded(existingApp, ownerLifeCycleStateId, incomingApp.ImportSource, ownerChangeTracker); + } + if (!string.IsNullOrWhiteSpace(incomingApp.MainUser) && IsResponsibleTypeActive(GlobalConst.kOwnerResponsibleTypeMain)) + { + await UpdateRoles(incomingApp.MainUser, GetRolesForType(GlobalConst.kOwnerResponsibleTypeMain)); + } + // Store users from all imported responsibles in uiuser for email notifications. + await AddAllResponsiblesToUiUser(responsibles); + await InitRecert(incomingApp, existingApp, appId); + } + catch (Exception exc) + { + string errorText = $"App {incomingApp.Name} could not be processed."; + Log.WriteError(LogMessageTitle, errorText, exc); + await AddLogEntry(2, LevelApp, errorText); + return false; + } + return true; + } + + private async Task NormalizeImportedUserReferences(ModellingImportAppData incomingApp) + { + ModellingImportAppData normalizedApp = new() + { + Name = incomingApp.Name, + ExtAppId = incomingApp.ExtAppId, + MainUser = await NormalizeImportedUserReference(incomingApp, incomingApp.MainUser, "main_user"), + Criticality = incomingApp.Criticality, + AdditionalInformation = incomingApp.AdditionalInformation, + OwnerLifecycleState = incomingApp.OwnerLifecycleState, + ImportSource = incomingApp.ImportSource, + RecertInterval = incomingApp.RecertInterval, + FirstRecertInterval = incomingApp.FirstRecertInterval, + RecertActive = incomingApp.RecertActive, + AppServers = [.. incomingApp.AppServers] + }; + + if (incomingApp.Responsibles == null) + { + normalizedApp.Responsibles = null; + return normalizedApp; + } + + normalizedApp.Responsibles = []; + foreach ((string typeKey, List identifiers) in incomingApp.Responsibles) + { + List normalizedIdentifiers = []; + foreach (string identifier in identifiers) + { + string? normalizedIdentifier = await NormalizeImportedUserReference(incomingApp, identifier, $"responsibles[{typeKey}]"); + if (!string.IsNullOrWhiteSpace(normalizedIdentifier)) + { + normalizedIdentifiers.Add(normalizedIdentifier); + } + } + normalizedApp.Responsibles[typeKey] = normalizedIdentifiers; + } + return normalizedApp; + } + + private async Task AddOwnerLifeCycleStateActiveChangeIfNeeded( + FwoOwner existingApp, + int? ownerLifeCycleStateId, + string? importSource, + OwnerChangeImportTracker ownerChangeTracker) + { + if (!TryGetOwnerLifeCycleStateActive(existingApp.OwnerLifeCycleStateId, out bool oldActiveState) + || !TryGetOwnerLifeCycleStateActive(ownerLifeCycleStateId, out bool newActiveState) + || oldActiveState == newActiveState) + { + return; + } + + await ownerChangeTracker.AddOwnerChange( + existingApp.Id, + existingApp.Id, + newActiveState ? ChangelogActionType.REACTIVATE : ChangelogActionType.DEACTIVATE, + importSource); + + if (!newActiveState && hasImmediateAppDecommNotificationForImport) + { + await CheckActiveRulesSync(existingApp); + } + } + + private async Task AddOwnerChangeIfNeeded( + FwoOwner existingApp, + ModellingImportAppData incomingApp, + OwnerChangeImportTracker ownerChangeTracker) + { + if (!existingApp.Active || HaveAppServerChanges(incomingApp)) + { + await ownerChangeTracker.AddOwnerChange(existingApp.Id, existingApp.Id, ChangelogActionType.CHANGE, incomingApp.ImportSource); + } + } + + private bool HaveAppServerChanges(ModellingImportAppData incomingApp) + { + HashSet existing = BuildAppServerKeys(ExistingAppServers); + HashSet incoming = BuildAppServerKeys(incomingApp.AppServers.Select(appServer => appServer.ToModellingAppServer())); + return !existing.SetEquals(incoming); + } + + private static HashSet BuildAppServerKeys(IEnumerable appServers) + { + HashSet keys = new(StringComparer.OrdinalIgnoreCase); + foreach (ModellingAppServer appServer in appServers.Where(appServer => !appServer.IsDeleted)) + { + string ip = string.IsNullOrWhiteSpace(appServer.Ip) ? "" : appServer.Ip.Trim().IpAsCidr(); + string ipEnd = string.IsNullOrWhiteSpace(appServer.IpEnd) ? ip : appServer.IpEnd.Trim().IpAsCidr(); + string name = string.IsNullOrWhiteSpace(appServer.Name) ? "" : appServer.Name.Trim(); + keys.Add($"{ip}|{ipEnd}|{name}"); + } + return keys; + } + + private bool TryGetOwnerLifeCycleStateActive(int? ownerLifeCycleStateId, out bool activeState) + { + if (ownerLifeCycleStateId.HasValue && ownerLifeCycleStateActiveById.TryGetValue(ownerLifeCycleStateId.Value, out bool resolvedActiveState)) + { + activeState = resolvedActiveState; + return true; + } + + activeState = false; + return false; + } + + private OwnerLifeCycleState? GetOwnerLifeCycleState(int? ownerLifeCycleStateId) + { + if (ownerLifeCycleStateId.HasValue && ownerLifeCycleStateActiveById.TryGetValue(ownerLifeCycleStateId.Value, out bool activeState)) + { + return new OwnerLifeCycleState + { + Id = ownerLifeCycleStateId.Value, + ActiveState = activeState + }; + } + + return null; + } + + private DateTime? GetDecommDateAfterLifecycleChange(FwoOwner existingApp, int? ownerLifeCycleStateId) + { + return OwnerLifeCycleState.GetDecommDate( + existingApp.DecommDate, + GetOwnerLifeCycleState(existingApp.OwnerLifeCycleStateId), + GetOwnerLifeCycleState(ownerLifeCycleStateId), + DateTime.UtcNow); + } + + private DateTime? GetDecommDateForNewOwner(int? ownerLifeCycleStateId) + { + return OwnerLifeCycleState.GetDecommDate( + null, + null, + GetOwnerLifeCycleState(ownerLifeCycleStateId), + DateTime.UtcNow); + } + + private async Task NormalizeImportedUserReference(ModellingImportAppData incomingApp, string? importedIdentifier, string fieldName) + { + if (string.IsNullOrWhiteSpace(importedIdentifier)) + { + return importedIdentifier; + } + + string trimmedIdentifier = importedIdentifier.Trim(); + if (LooksLikeDistinguishedName(trimmedIdentifier)) + { + return trimmedIdentifier; + } + + string? resolvedDn = await ResolveImportedResponsibleIdentifierToDn(trimmedIdentifier); + if (!string.IsNullOrWhiteSpace(resolvedDn)) + { + return resolvedDn.Trim(); + } + + string appLabel = string.IsNullOrWhiteSpace(incomingApp.Name) + ? incomingApp.ExtAppId + : $"{incomingApp.Name} ({incomingApp.ExtAppId})"; + string warningText = $"App \"{appLabel}\": could not resolve imported user id \"{trimmedIdentifier}\" from field \"{fieldName}\". Skipping entry."; + Log.WriteWarning(LogMessageTitle, warningText); + await AddLogEntry(1, LevelApp, warningText); + return null; + } + + /// + /// Resolves a plain imported responsible identifier to a distinguished name. + /// User identifiers are tried first, then group identifiers. + /// + /// Imported user or group identifier from the source system. + /// Resolved distinguished name if found; otherwise null. + protected virtual async Task ResolveImportedResponsibleIdentifierToDn(string identifier) + { + string? userDn = await ResolveImportedUserIdentifierToDn(identifier); + if (!string.IsNullOrWhiteSpace(userDn)) + { + return userDn; + } + return await ResolveImportedGroupIdentifierToDn(identifier); + } + + /// + /// Resolves a plain imported user identifier to a distinguished name. + /// + /// Imported user identifier such as uid, cn, or login name. + /// Resolved user distinguished name if found in any connected LDAP; otherwise null. + protected virtual async Task ResolveImportedUserIdentifierToDn(string userIdentifier) + { + UiUser userToResolve = new() { Name = userIdentifier }; + foreach (Ldap ldap in connectedLdaps) + { + if (string.IsNullOrWhiteSpace(ldap.UserSearchPath)) + { + continue; + } + + LdapEntry? ldapUser = await ldap.GetLdapEntry(userToResolve, false); + if (!string.IsNullOrWhiteSpace(ldapUser?.Dn)) + { + return ldapUser.Dn; + } + } + return null; + } + + /// + /// Resolves a plain imported group identifier to a distinguished name. + /// + /// Imported group identifier from the source system. + /// Resolved group distinguished name if found; otherwise null. + protected virtual async Task ResolveImportedGroupIdentifierToDn(string groupIdentifier) + { + foreach (Ldap ldap in connectedLdaps) + { + List matches = await ldap.GetAllGroups(groupIdentifier); + if (matches.Count > 0) + { + return matches[0]; + } + } + return null; + } + + /// + /// Checks whether the owner still has active rules after a lifecycle transition to an inactive state. + /// + /// Owner to check. + protected virtual async Task CheckActiveRulesSync(FwoOwner owner) + { + await new OwnerActiveRuleCheck(apiConnection, globalConfig).CheckActiveRulesSync(owner); + } + + /// + /// Loads whether an immediate owner decommission notification exists. + /// This is intended to be called once per whole import run. + /// + protected virtual async Task LoadHasImmediateAppDecommNotification() + { + List notifications = await apiConnection.SendQueryAsync>( + NotificationQueries.getNotifications, + new { client = NotificationClient.AppDecomm.ToString() }); + return notifications.Any(notification => notification.Deadline == NotificationDeadline.None); + } + + private static bool LooksLikeDistinguishedName(string identifier) + { + return identifier.Contains('=') && identifier.Contains(','); + } + + private async Task NewApp(ModellingImportAppData incomingApp, int? ownerLifeCycleStateId, List responsibles) + { + int appId = 0; + var variables = new + { + name = incomingApp.Name, + appIdExternal = incomingApp.ExtAppId, + criticality = incomingApp.Criticality, + additionalInfo = incomingApp.AdditionalInformation, + recertInterval = incomingApp.RecertInterval ?? globalConfig.RecertificationPeriod, + ownerLifeCycleStateId, + importSource = incomingApp.ImportSource, + commSvcPossible = false, + recertActive = false, + decommDate = GetDecommDateForNewOwner(ownerLifeCycleStateId) + }; + ReturnId[]? returnIds = (await apiConnection.SendQueryAsync(OwnerQueries.newOwner, variables)).ReturnIds; + if (returnIds != null) + { + appId = returnIds[0].NewId; + await UpdateOwnerResponsibles(appId, responsibles, []); + await ApplyRolesToResponsibles(responsibles, rolesToSetByType); + foreach (var appServer in incomingApp.AppServers) + { + await NewAppServer(appServer, appId, incomingApp.ImportSource); + } + } + return appId; + } + + private async Task UpdateApp(ModellingImportAppData incomingApp, FwoOwner existingApp, int? ownerLifeCycleStateId, List responsibles) + { + var Variables = new + { + id = existingApp.Id, + name = incomingApp.Name, + appIdExternal = string.IsNullOrEmpty(incomingApp.ExtAppId) ? null : incomingApp.ExtAppId, + criticality = incomingApp.Criticality, + additionalInfo = incomingApp.AdditionalInformation, + recertInterval = incomingApp.RecertInterval ?? globalConfig.RecertificationPeriod, + ownerLifeCycleStateId, + decommDate = GetDecommDateAfterLifecycleChange(existingApp, ownerLifeCycleStateId), + commSvcPossible = existingApp.CommSvcPossible, + recertActive = incomingApp.RecertActive || existingApp.RecertActive + }; + await apiConnection.SendQueryAsync(OwnerQueries.updateOwner, Variables); + await UpdateOwnerResponsibles(existingApp.Id, responsibles, existingApp.OwnerResponsibles ?? []); + await ApplyRolesToResponsibles(responsibles, rolesToSetByType); + await ImportAppServers(incomingApp, existingApp.Id); + } + + private async Task<(int deleted, int failed)> DeactivateMissingApps(string importSource, OwnerChangeImportTracker ownerChangeTracker) + { + int deletedCounter = 0, deleteFailCounter = 0; + foreach (var existingApp in ExistingApps.Where(x => x.ImportSource == importSource && x.Active)) + { + if (ImportedApps.FirstOrDefault(x => x.ExtAppId == existingApp.ExtAppId) == null) + { + if (await DeactivateApp(existingApp, ownerChangeTracker)) + { + ++deletedCounter; + } + else + { + ++deleteFailCounter; + } + } + } + return (deletedCounter, deleteFailCounter); + } + + private async Task DeactivateApp(FwoOwner app, OwnerChangeImportTracker ownerChangeTracker) + { + try + { + await apiConnection.SendQueryAsync(OwnerQueries.deactivateOwner, new { id = app.Id }); + await ownerChangeTracker.AddOwnerChange(app.Id, null, ChangelogActionType.DELETE, app.ImportSource); + } + catch (Exception exc) + { + string errorText = $"Outdated App {app.Name} could not be deactivated."; + Log.WriteError(LogMessageTitle, errorText, exc); + await AddLogEntry(1, LevelApp, errorText); + return false; + } + return true; + } + + private List BuildOwnerResponsibles(ModellingImportAppData incomingApp) + { + List responsibles = []; + HashSet seenTypeDn = new(StringComparer.OrdinalIgnoreCase); + + if (incomingApp.Responsibles != null && incomingApp.Responsibles.Count > 0) + { + if (!AreResponsibleKeysNumeric(incomingApp.Responsibles)) + { + Log.WriteWarning(LogMessageTitle, + $"Skipping responsibles import for app \"{incomingApp.Name}\" ({incomingApp.ExtAppId}) because at least one responsible key is non-numeric."); + } + else + { + Dictionary responsibleTypeIdByKey = BuildResponsibleTypeIdByIncomingKey(incomingApp.Responsibles); + foreach ((string rawTypeKey, List dns) in incomingApp.Responsibles) + { + string typeKey = string.IsNullOrWhiteSpace(rawTypeKey) ? "" : rawTypeKey.Trim(); + if (!responsibleTypeIdByKey.TryGetValue(typeKey, out int responsibleTypeId)) + { + Log.WriteWarning(LogMessageTitle, + $"Unknown owner responsible key \"{typeKey}\" (key \"{rawTypeKey}\") for app \"{incomingApp.Name}\" ({incomingApp.ExtAppId}). Skipping responsibles of this type."); + continue; + } + foreach (string dn in dns.Where(dn => !string.IsNullOrWhiteSpace(dn))) + { + TryAddResponsible(responsibles, seenTypeDn, dn, responsibleTypeId); + } + } + } + } + if (IsResponsibleTypeActive(GlobalConst.kOwnerResponsibleTypeMain)) + { + TryAddResponsible(responsibles, seenTypeDn, incomingApp.MainUser ?? "", GlobalConst.kOwnerResponsibleTypeMain); + } + return responsibles; + } + + private static void TryAddResponsible(List responsibles, HashSet seenTypeDn, string dn, int responsibleTypeId) + { + if (string.IsNullOrWhiteSpace(dn)) + { + return; + } + string normalizedDn = dn.Trim(); + string dedupKey = $"{responsibleTypeId}|{normalizedDn}"; + if (seenTypeDn.Add(dedupKey)) + { + responsibles.Add(new OwnerResponsible + { + Dn = normalizedDn, + ResponsibleTypeId = responsibleTypeId + }); + } + } + + private static bool AreResponsibleKeysNumeric(Dictionary> incomingResponsibles) + { + return incomingResponsibles.Keys + .Select(rawKey => string.IsNullOrWhiteSpace(rawKey) ? "" : rawKey.Trim()) + .All(key => int.TryParse(key, out _)); + } + + private Dictionary BuildResponsibleTypeIdByIncomingKey(Dictionary> incomingResponsibles) + { + Dictionary result = []; + List typeIdsBySortOrder = [.. ownerResponsibleTypeById.Values + .Where(type => type.Active) + .OrderBy(type => type.SortOrder).ThenBy(type => type.Id).Select(type => type.Id)]; + List<(string key, int keyNumber)> numericKeys = [.. incomingResponsibles.Keys + .Select(rawKey => string.IsNullOrWhiteSpace(rawKey) ? "" : rawKey.Trim()) + .Select(key => (key, int.Parse(key))) + .OrderBy(entry => entry.Item2) + .ThenBy(entry => entry.Item1, StringComparer.Ordinal)]; + + for (int i = 0; i < numericKeys.Count && i < typeIdsBySortOrder.Count; ++i) + { + result[numericKeys[i].key] = typeIdsBySortOrder[i]; + } + return result; + } + + private bool IsResponsibleTypeActive(int typeId) + { + return ownerResponsibleTypeById.TryGetValue(typeId, out OwnerResponsibleType? type) && type.Active; + } + + private async Task UpdateOwnerResponsibles(int ownerId, List responsibles, List existingResponsibles) + { + (List responsiblesToInsert, List responsiblesToDelete) = + CheckResponsibles(existingResponsibles, responsibles); + + if (responsiblesToDelete.Count > 0) + { + var deletionObjects = responsiblesToDelete.ConvertAll(responsible => new + { + dn = new { _eq = responsible.Dn }, + responsible_type = new { _eq = responsible.ResponsibleTypeId } + }); + await apiConnection.SendQueryAsync(OwnerQueries.deleteSpecificOwnerResponsibles, new { ownerId, objects = deletionObjects }); + await RemoveRolesFromResponsibles(responsiblesToDelete, rolesToSetByType); + } + + if (responsiblesToInsert.Count == 0) + { + return; + } + + var objects = responsiblesToInsert.ConvertAll(responsible => new + { + owner_id = ownerId, + dn = responsible.Dn, + responsible_type = responsible.ResponsibleTypeId + }); + await apiConnection.SendQueryAsync(OwnerQueries.newOwnerResponsibles, new { responsibles = objects }); + } + + private (List toInsert, List toDelete) CheckResponsibles(List existingResponsibles, List incomingResponsibles) + { + Dictionary existingByKey = BuildResponsiblesByKey(existingResponsibles); + Dictionary incomingByKey = BuildResponsiblesByKey(incomingResponsibles); + + List responsiblesToInsert = incomingByKey + .Where(entry => !existingByKey.ContainsKey(entry.Key)) + .Select(entry => new OwnerResponsible(entry.Value)).ToList(); + + List responsiblesToDelete = existingByKey + .Where(entry => !incomingByKey.ContainsKey(entry.Key) && globalConfig.OwnerDataImportSyncUsers) + .Select(entry => new OwnerResponsible(entry.Value)).ToList(); + + return (responsiblesToInsert, responsiblesToDelete); + } + + private static Dictionary BuildResponsiblesByKey(List responsibles) + { + Dictionary responsiblesByKey = new(StringComparer.Ordinal); + foreach (OwnerResponsible responsible in responsibles) + { + if (string.IsNullOrWhiteSpace(responsible.Dn)) + { + continue; + } + + string key = BuildResponsibleKey(responsible); + if (!responsiblesByKey.ContainsKey(key)) + { + responsiblesByKey[key] = responsible; + } + } + return responsiblesByKey; + } + + private static string BuildResponsibleKey(OwnerResponsible responsible) + { + return $"{responsible.ResponsibleTypeId}|{NormalizeDn(responsible.Dn)}"; + } + + private static string NormalizeDn(string dn) + { + return dn.Trim().ToUpperInvariant(); + } + + private async Task ApplyRolesToResponsibles(List responsibles, Dictionary> rolesByType) + { + await ForEachResponsibleRoleAssignment(responsibles, rolesByType, UpdateRoles); + } + + private async Task RemoveRolesFromResponsibles(List responsibles, Dictionary> rolesByType) + { + await ForEachResponsibleRoleAssignment(responsibles, rolesByType, RemoveRoles); + } + + private async Task ForEachResponsibleRoleAssignment( + List responsibles, + Dictionary> rolesByType, + Func, Task> roleHandler) + { + foreach (OwnerResponsible responsible in responsibles) + { + if (!rolesByType.TryGetValue(responsible.ResponsibleTypeId, out List? roles) || roles.Count == 0) + { + continue; + } + bool allowModelling = ownerResponsibleTypeById.TryGetValue(responsible.ResponsibleTypeId, out OwnerResponsibleType? type) && type.AllowModelling; + bool allowRecertification = ownerResponsibleTypeById.TryGetValue(responsible.ResponsibleTypeId, out type) && type.AllowRecertification; + List filteredRoles = OwnerResponsibleRoleHelper.FilterRoles(roles, allowModelling, allowRecertification); + if (filteredRoles.Count == 0) + { + continue; + } + await roleHandler(responsible.Dn, filteredRoles); + } + } + + private bool TryResolveOwnerLifeCycleStateId(ModellingImportAppData incomingApp, out int? ownerLifeCycleStateId) + { + ownerLifeCycleStateId = null; + if (string.IsNullOrWhiteSpace(incomingApp.OwnerLifecycleState)) + { + return true; + } + string stateKey = incomingApp.OwnerLifecycleState.Trim(); + if (ownerLifeCycleStateIdsByName.TryGetValue(stateKey, out int resolvedId)) + { + ownerLifeCycleStateId = resolvedId; + return true; + } + return false; + } + + private string GetRoleDn(string role) + { + return $"cn={role},{internalLdap.RoleSearchPath}"; + } + + private List GetRolesForType(int typeId) + { + return rolesToSetByType.TryGetValue(typeId, out List? roles) ? roles : []; + } + + private static Dictionary> ParseRolesWithImport(string rolesJson) + { + Dictionary> rolesByType = []; + if (string.IsNullOrWhiteSpace(rolesJson)) + { + return rolesByType; + } + + string trimmed = rolesJson.TrimStart(); + if (trimmed.StartsWith("[")) + { + List roles = JsonSerializer.Deserialize>(rolesJson) ?? []; + rolesByType[GlobalConst.kOwnerResponsibleTypeSupporting] = roles; + return rolesByType; + } + + Dictionary>? parsed = JsonSerializer.Deserialize>>(rolesJson); + if (parsed != null) + { + foreach (var entry in parsed) + { + if (int.TryParse(entry.Key, out int typeId)) + { + rolesByType[typeId] = entry.Value; + } + } + } + return rolesByType; + } + + /// + /// For every imported responsible DN (user or group), ensure all referenced users exist in uiuser. + /// This is necessary to resolve email addresses for users who have never logged in. + /// + private async Task AddAllResponsiblesToUiUser(IEnumerable responsibles) + { + HashSet handledUserDns = new(StringComparer.OrdinalIgnoreCase); + HashSet handledGroupDnsByLdap = new(StringComparer.OrdinalIgnoreCase); + + foreach (string responsibleDn in responsibles + .Where(responsible => !string.IsNullOrWhiteSpace(responsible.Dn)) + .Select(responsible => responsible.Dn.Trim()) + .Distinct(StringComparer.OrdinalIgnoreCase)) + { + await AddResponsibleDnToUiUser(responsibleDn, handledUserDns, handledGroupDnsByLdap); + } + } + + private async Task AddResponsibleDnToUiUser(string responsibleDn, HashSet handledUserDns, HashSet handledGroupDnsByLdap) + { + string normalizedResponsibleDn = responsibleDn.Trim(); + if (await TryResolveAndUpsertImportedUiUser(normalizedResponsibleDn, handledUserDns)) + { + return; + } + + foreach (Ldap ldap in connectedLdaps) + { + string groupKey = $"{ldap.Id}|{normalizedResponsibleDn}"; + if (!handledGroupDnsByLdap.Add(groupKey)) + { + continue; + } + foreach (string memberDn in await ResolveImportedGroupMembers(ldap, normalizedResponsibleDn)) + { + if (!string.IsNullOrWhiteSpace(memberDn)) + { + await AddResponsibleDnToUiUser(memberDn.Trim(), handledUserDns, handledGroupDnsByLdap); + } + } + } + } + + private async Task TryResolveAndUpsertImportedUiUser(string responsibleDn, HashSet handledUserDns) + { + UiUser? uiUser = await ResolveImportedUiUser(responsibleDn); + if (uiUser == null || string.IsNullOrWhiteSpace(uiUser.Dn)) + { + return false; + } + if (!handledUserDns.Add(uiUser.Dn)) + { + return true; + } + await UiUserHandler.UpsertUiUser(apiConnection, uiUser, false); + if (uiUser.DbId <= 0) + { + Log.WriteWarning(LogMessageTitle, $"Resolved imported user \"{uiUser.Dn}\" could not be written to uiuser."); + } + return true; + } + + private async Task ConvertLdapToUiUser(string userDn) + { + // add the modelling user to local uiuser table for later ref to email address + // find the user in all connected ldaps + bool inputLooksLikeDn = LooksLikeDistinguishedName(userDn); + foreach (Ldap ldap in connectedLdaps) + { + if (!inputLooksLikeDn + && (string.IsNullOrEmpty(ldap.UserSearchPath) + || !userDn.Contains(ldap.UserSearchPath, StringComparison.OrdinalIgnoreCase))) + { + continue; + } + + LdapEntry? ldapUser = await ldap.GetUserDetailsFromLdap(userDn); + if (ldapUser != null && !Ldap.IsGroupEntry(ldapUser)) + { + // add data from ldap entry to uiUser + return new() + { + LdapConnection = new UiLdapConnection() { Id = ldap.Id }, + Dn = ldapUser.Dn, + Name = Ldap.GetName(ldapUser), + Firstname = Ldap.GetFirstName(ldapUser), + Lastname = Ldap.GetLastName(ldapUser), + Email = Ldap.GetEmail(ldapUser), + Tenant = await DeriveTenantFromLdap(ldap, ldapUser) + }; + } + } + return null; + } + + /// + /// Resolves an imported responsible DN to a UI user if it references a user entry. + /// + /// Imported responsible distinguished name. + /// UI user when the DN is a user entry; otherwise null. + protected virtual async Task ResolveImportedUiUser(string responsibleDn) + { + return await ConvertLdapToUiUser(responsibleDn); + } + + /// + /// Resolves members of an imported group DN, including groups from non-standard LDAP paths. + /// + /// LDAP connection to query. + /// Imported group distinguished name. + /// List of member user or group DNs. + protected virtual async Task> ResolveImportedGroupMembers(Ldap ldap, string groupDn) + { + return await ldap.GetGroupMembers(groupDn); + } + + private async Task DeriveTenantFromLdap(Ldap ldap, LdapEntry ldapUser) + { + // try to derive the the user's tenant from the ldap settings + Tenant tenant = new() + { + Id = GlobalConst.kTenant0Id // default: tenant0 (id=1) + }; + + string tenantName = ""; + + // can we derive the users tenant purely from its ldap? + if (!string.IsNullOrEmpty(ldap.GlobalTenantName) || ldap.TenantLevel > 0) + { + if (ldap.TenantLevel > 0) + { + // getting tenant via tenant level setting from distinguished name + tenantName = ldap.GetTenantName(ldapUser); + } + else if (!string.IsNullOrEmpty(ldap.GlobalTenantName)) + { + tenantName = ldap.GlobalTenantName ?? ""; + } + + var variables = new { tenant_name = tenantName }; + Tenant[] tenants = await apiConnection.SendQueryAsync(AuthQueries.getTenantId, variables, "getTenantId"); + if (tenants.Length == 1) + { + tenant.Id = tenants[0].Id; + } + } + return tenant; + } + + private async Task UpdateRoles(string dn, List rolesToApply) + { + List roles = await internalLdap.GetRoles([dn]); + foreach (var role in rolesToApply) + { + if (!roles.Contains(role, StringComparer.OrdinalIgnoreCase)) + { + await internalLdap.AddUserToEntry(dn, GetRoleDn(role)); + } + } + } + + private async Task RemoveRoles(string dn, List rolesToRemove) + { + foreach (string role in rolesToRemove) + { + await RemoveRoleFromDn(dn, role); + } + } + + /// + /// Removes a role assignment from a user DN. + /// + /// User distinguished name. + /// Role name. + protected virtual async Task RemoveRoleFromDn(string dn, string role) + { + await internalLdap.RemoveUserFromEntry(dn, GetRoleDn(role)); + } + + private async Task ImportAppServers(ModellingImportAppData incomingApp, int applId) + { + int successCounter = 0; + int failCounter = 0; + int deleteCounter = 0; + int deleteFailCounter = 0; + + var Variables = new + { + importSource = incomingApp.ImportSource, + appId = applId + }; + ExistingAppServers = await apiConnection.SendQueryAsync>(ModellingQueries.getAppServersBySource, Variables); + foreach (var incomingAppServer in incomingApp.AppServers) + { + if (await SaveAppServer(incomingAppServer, applId, incomingApp.ImportSource)) + { + ++successCounter; + } + else + { + ++failCounter; + } + } + foreach (var existingAppServer in ExistingAppServers.Where(e => !e.IsDeleted).ToList()) + { + if (incomingApp.AppServers.FirstOrDefault(x => x.Ip.IpAsCidr() == existingAppServer.Ip.IpAsCidr() && x.IpEnd.IpAsCidr() == existingAppServer.IpEnd.IpAsCidr()) == null) + { + if (await MarkDeletedAppServer(existingAppServer)) + { + ++deleteCounter; + } + else + { + ++deleteFailCounter; + } + } + } + Log.WriteDebug(LogMessageTitle, $"for App {incomingApp.Name}: Imported {successCounter} app servers, {failCounter} failed. {deleteCounter} app servers marked as deleted, {deleteFailCounter} failed."); + } + + private async Task SaveAppServer(ModellingImportAppServer incomingAppServer, int appID, string impSource) + { + try + { + if (incomingAppServer.IpEnd == "") + { + incomingAppServer.IpEnd = incomingAppServer.Ip; + } + if (globalConfig.DnsLookup) + { + incomingAppServer.Name = await BuildAppServerName(incomingAppServer); + } + ModellingAppServer? existingAppServer = ExistingAppServers.FirstOrDefault(x => x.Ip.IpAsCidr() == incomingAppServer.Ip.IpAsCidr() && x.IpEnd.IpAsCidr() == incomingAppServer.IpEnd.IpAsCidr()); + if (existingAppServer == null) + { + return await NewAppServer(incomingAppServer, appID, impSource); + } + + if (existingAppServer.IsDeleted) + { + if (!await ReactivateAppServer(existingAppServer)) + { + return false; + } + } + else + { + // in case there are still active appservers from other sources (resulting e.g. from older revisions) + await AppServerHelper.DeactivateOtherSources(apiConnection, userConfig, existingAppServer); + } + if (!existingAppServer.Name.Equals(incomingAppServer.Name)) + { + if (!await UpdateAppServerName(existingAppServer, incomingAppServer.Name)) + { + return false; + } + } + if (existingAppServer.CustomType == null) + { + if (!await UpdateAppServerType(existingAppServer)) + { + return false; + } + } + return true; + } + catch (Exception exc) + { + string errorText = $"App Server {incomingAppServer.Name} could not be processed."; + Log.WriteError(LogMessageTitle, errorText, exc); + await AddLogEntry(1, LevelAppServer, errorText); + return false; + } + } + + private async Task BuildAppServerName(ModellingImportAppServer appServer) + { + try + { + return await AppServerHelper.ConstructAppServerNameFromDns(appServer.ToModellingAppServer(), NamingConvention, globalConfig.OverwriteExistingNames, true); + } + catch (Exception exc) + { + string errorText = $"App Server name {appServer.Name} could not be set according to naming conventions."; + Log.WriteError(LogMessageTitle, errorText, exc); + await AddLogEntry(1, LevelAppServer, errorText); + } + return appServer.Name; + } + + private async Task NewAppServer(ModellingImportAppServer incomingAppServer, int appID, string impSource) + { + try + { + var Variables = new + { + name = incomingAppServer.Name, + appId = appID, + ip = incomingAppServer.Ip.IpAsCidr(), + ipEnd = incomingAppServer.IpEnd != "" ? incomingAppServer.IpEnd.IpAsCidr() : incomingAppServer.Ip.IpAsCidr(), + importSource = impSource, + customType = 0 + }; + ReturnId[]? returnIds = (await apiConnection.SendQueryAsync(ModellingQueries.newAppServer, Variables)).ReturnIds; + if (returnIds != null && returnIds.Length > 0) + { + ModellingAppServer newModAppServer = new(incomingAppServer.ToModellingAppServer()) { Id = returnIds[0].NewIdLong, ImportSource = impSource, AppId = appID }; + await ModellingHandlerBase.LogChange(new LogChangeRequest + { + ChangeType = ModellingTypes.ChangeType.Insert, + ObjectType = ModellingTypes.ModObjectType.AppServer, + ObjectId = newModAppServer.Id, + Text = $"New App Server: {newModAppServer.Display()}", + ApiConnection = apiConnection, + UserConfig = userConfig, + ApplicationId = newModAppServer.AppId, + DisplayMessageInUi = DefaultInit.DoNothing, + ChangeSource = newModAppServer.ImportSource + }); + await AppServerHelper.DeactivateOtherSources(apiConnection, userConfig, newModAppServer); + } + } + catch (Exception exc) + { + string errorText = $"App Server {incomingAppServer.Name} could not be processed."; + Log.WriteError(LogMessageTitle, errorText, exc); + await AddLogEntry(1, LevelAppServer, errorText); + return false; + } + return true; + } + + private async Task ReactivateAppServer(ModellingAppServer appServer) + { + try + { + var Variables = new + { + id = appServer.Id, + deleted = false + }; + await apiConnection.SendQueryAsync(ModellingQueries.setAppServerDeletedState, Variables); + await ModellingHandlerBase.LogChange(new LogChangeRequest + { + ChangeType = ModellingTypes.ChangeType.Reactivate, + ObjectType = ModellingTypes.ModObjectType.AppServer, + ObjectId = appServer.Id, + Text = $"Reactivate App Server: {appServer.Display()}", + ApiConnection = apiConnection, + UserConfig = userConfig, + ApplicationId = appServer.AppId, + DisplayMessageInUi = DefaultInit.DoNothing, + ChangeSource = appServer.ImportSource + }); + await AppServerHelper.DeactivateOtherSources(apiConnection, userConfig, appServer); + } + catch (Exception exc) + { + string errorText = $"App Server {appServer.Name} could not be reactivated."; + Log.WriteError(LogMessageTitle, errorText, exc); + await AddLogEntry(1, LevelAppServer, errorText); + return false; + } + return true; + } + + private async Task UpdateAppServerType(ModellingAppServer appServer) + { + try + { + var Variables = new + { + id = appServer.Id, + customType = 0 + }; + await apiConnection.SendQueryAsync(ModellingQueries.setAppServerType, Variables); + await ModellingHandlerBase.LogChange(new LogChangeRequest + { + ChangeType = ModellingTypes.ChangeType.Update, + ObjectType = ModellingTypes.ModObjectType.AppServer, + ObjectId = appServer.Id, + Text = $"Update App Server Type: {appServer.Display()}", + ApiConnection = apiConnection, + UserConfig = userConfig, + ApplicationId = appServer.AppId, + DisplayMessageInUi = DefaultInit.DoNothing, + ChangeSource = appServer.ImportSource + }); + } + catch (Exception exc) + { + string errorText = $"Type of App Server {appServer.Name} could not be set."; + Log.WriteError(LogMessageTitle, errorText, exc); + await AddLogEntry(1, LevelAppServer, errorText); + return false; + } + return true; + } + + private async Task UpdateAppServerName(ModellingAppServer appServer, string newName) + { + if (appServer.Name != newName) + { + try + { + var Variables = new + { + newName, + id = appServer.Id, + }; + await apiConnection.SendQueryAsync(ModellingQueries.setAppServerName, Variables); + await ModellingHandlerBase.LogChange(new LogChangeRequest + { + ChangeType = ModellingTypes.ChangeType.Update, + ObjectType = ModellingTypes.ModObjectType.AppServer, + ObjectId = appServer.Id, + Text = $"Update App Server Name: {appServer.Display()}", + ApiConnection = apiConnection, + UserConfig = userConfig, + ApplicationId = appServer.AppId, + DisplayMessageInUi = DefaultInit.DoNothing, + ChangeSource = appServer.ImportSource + }); + Log.WriteWarning(LogMessageTitle, $"Name of App Server changed from {appServer.Name} changed to {newName}"); + } + catch (Exception exc) + { + string errorText = $"Name of App Server {appServer.Name} could not be set to {newName}."; + Log.WriteError(LogMessageTitle, errorText, exc); + await AddLogEntry(1, LevelAppServer, errorText); + return false; + } + } + return true; + } + + private async Task MarkDeletedAppServer(ModellingAppServer appServer) + { + try + { + var Variables = new + { + id = appServer.Id, + deleted = true + }; + await apiConnection.SendQueryAsync(ModellingQueries.setAppServerDeletedState, Variables); + await ModellingHandlerBase.LogChange(new LogChangeRequest + { + ChangeType = ModellingTypes.ChangeType.Update, + ObjectType = ModellingTypes.ModObjectType.AppServer, + ObjectId = appServer.Id, + Text = $"Deactivate App Server: {appServer.Display()}", + ApiConnection = apiConnection, + UserConfig = userConfig, + ApplicationId = appServer.AppId, + DisplayMessageInUi = DefaultInit.DoNothing, + ChangeSource = appServer.ImportSource + }); + await AppServerHelper.ReactivateOtherSource(apiConnection, userConfig, appServer); + } + catch (Exception exc) + { + string errorText = $"Outdated AppServer {appServer.Name} could not be marked as deleted."; + Log.WriteError(LogMessageTitle, errorText, exc); + await AddLogEntry(1, LevelAppServer, errorText); + return false; + } + return true; + } + + private async Task InitRecert(ModellingImportAppData incomingApp, FwoOwner? existingApp, int appId) + { + if (userConfig.RecertificationMode == RecertificationMode.OwnersAndRules && + incomingApp.RecertActive && (existingApp == null || !existingApp.RecertActive)) + { + RecertHandler recertHandler = new(apiConnection, userConfig); + await recertHandler.InitOwnerRecert(new() + { + Id = appId, + RecertInterval = incomingApp.RecertInterval + }); + } + } + + private async Task AddLogEntry(int severity, string level, string description) + { + await AddLogEntry(GlobalConst.kImportAppData, severity, level, description); + } + } +} diff --git a/roles/middleware/files/FWO.Middleware.Server/AreaIpDataImport.cs b/roles/middleware/files/FWO.Middleware.Server/AreaIpDataImport.cs new file mode 100644 index 0000000000..e451f54012 --- /dev/null +++ b/roles/middleware/files/FWO.Middleware.Server/AreaIpDataImport.cs @@ -0,0 +1,343 @@ +using FWO.Basics; +using FWO.Logging; +using FWO.Api.Client; +using FWO.Api.Client.Queries; +using FWO.Data; +using FWO.Data.Modelling; +using FWO.Config.Api; +using System.Text.Json; + +namespace FWO.Middleware.Server +{ + /// + /// Class handling the Area IP Data Import + /// + public class AreaIpDataImport(ApiConnection apiConnection, GlobalConfig globalConfig) : DataImportBase(apiConnection, globalConfig) + { + private List existingAreas = []; + private const string LogMessageTitle = "Import Area IP Data"; + private const string LevelFile = "Import File"; + private const string LevelArea = "Area"; + + /// + /// Run the Area IP Data Import + /// + public async Task> Run() + { + List importfilePathAndNames = JsonSerializer.Deserialize>(globalConfig.ImportSubnetDataPath) ?? throw new JsonException("Config Data could not be deserialized."); + List AllNwData = []; + List FailedImports = []; + + // iterate over all files + foreach (var importfilePathAndName in importfilePathAndNames) + { + await ImportSingleFile(importfilePathAndName, AllNwData, FailedImports); + } + + // merge all data into a single list of areas + ModellingImportNwData mergedNwData = MergeNetworkData(AllNwData); + + if (mergedNwData.Areas.Count > 0) + { + await SaveMergedNwData(mergedNwData); + } + else + { + string messageText = $"No valid network data found in any of the following import files {string.Join(", ", importfilePathAndNames)}. No changes were made."; + Log.WriteInfo(LogMessageTitle, messageText); + await AddLogEntry(GlobalConst.kImportAreaSubnetData, 2, LevelFile, messageText); + } + return FailedImports; + } + + private async Task ImportSingleFile(string importfilePathAndName, List allNwData, List failedImports) + { + if (!RunImportScript(importfilePathAndName + ".py", null)) + { + Log.WriteInfo(LogMessageTitle, $"Script {importfilePathAndName}.py failed but trying to import from existing file."); + } + + try + { + Log.WriteInfo(LogMessageTitle, $"Importing Area Network Data from file {importfilePathAndName}.json"); + ReadFile(importfilePathAndName + ".json"); + ModellingImportNwData nwData = JsonSerializer.Deserialize(importFile) ?? throw new JsonException("File could not be parsed."); + if (nwData.Areas.Count > 0) + { + allNwData.Add(ConvertNwDataToRanges(nwData)); + } + else + { + Log.WriteInfo(LogMessageTitle, $"Nothing found to import in file {importfilePathAndName}.json"); + } + } + catch (Exception ex) + { + string errorText = $"Import from file {importfilePathAndName}.json could not be processed."; + Log.WriteError(LogMessageTitle, errorText, ex); + await AddLogEntry(GlobalConst.kImportAreaSubnetData, 2, LevelFile, errorText); + failedImports.Add(importfilePathAndName); + } + } + + private async Task SaveMergedNwData(ModellingImportNwData mergedNwData) + { + int successCounter = 0; + int failCounter = 0; + int deleteCounter = 0; + int deleteFailCounter = 0; + + existingAreas = await apiConnection.SendQueryAsync>(ModellingQueries.getAreas); + + foreach (ModellingImportAreaData incomingArea in mergedNwData.Areas) + { + if (await SaveArea(incomingArea)) + { + ++successCounter; + } + else + { + ++failCounter; + } + } + foreach (ModellingNetworkArea existingArea in existingAreas) + { + if (mergedNwData.Areas.FirstOrDefault(x => x.IdString == existingArea.IdString) == null) + { + if (await DeleteArea(existingArea)) + { + ++deleteCounter; + } + else + { + ++deleteFailCounter; + } + } + } + + string messageText = $"Imported {successCounter} areas successfully, {failCounter} areas failed. Deleted {deleteCounter} areas, {deleteFailCounter} failed."; + Log.WriteInfo(LogMessageTitle, messageText); + await AddLogEntry(GlobalConst.kImportAreaSubnetData, 0, LevelFile, messageText); + } + + private static ModellingImportNwData ConvertNwDataToRanges(ModellingImportNwData nwData) + { + ModellingImportNwData result = new(); + + foreach (ModellingImportAreaData area in nwData.Areas) + { + result.Areas.Add(ConvertAreaToRanges(area)); + } + + return result; + } + + private static ModellingImportAreaData ConvertAreaToRanges(ModellingImportAreaData area) + { + ModellingImportAreaData newArea = new(area.Name, area.IdString); + foreach (ModellingImportAreaIpData ipData in area.IpData) + { + newArea.IpData.Add(ConvertIpDataToRange(ipData)); + } + return newArea; + } + + // convert arbitrary IP data contained in .Ip (1.2.3.4/32 | 1.2.3.0/24) to a range + private static ModellingImportAreaIpData ConvertIpDataToRange(ModellingImportAreaIpData importAreaIpData) + { + ModellingImportAreaIpData ipData = new() + { + Name = importAreaIpData.Name, + }; + (ipData.Ip, ipData.IpEnd) = IpOperations.SplitIpToRange(importAreaIpData.Ip); + return ipData; + } + + private static ModellingImportAreaData MergeArea(ModellingImportAreaData area1, ModellingImportAreaData area2) + { + List deepCopyIpData = area1.IpData.Select(item => item.Clone()).ToList(); + ModellingImportAreaData resultArea = new(area1.Name, area1.IdString, deepCopyIpData); // make a copy of area1 including all IP data in the list + + foreach (ModellingImportAreaIpData ipRange in area2.IpData) + { + bool found = false; + foreach (var existingIpRange in area1.IpData) + { + if (ipRange.Ip == existingIpRange.Ip && ipRange.IpEnd == existingIpRange.IpEnd) + { + found = true; + break; + } + } + if (!found) + { + resultArea.IpData.Add(ipRange); + } + } + return resultArea; + } + + private static ModellingImportNwData MergeNetworkData(List AllNwData) + { + ModellingImportNwData mergedNwData = new(); + + foreach (ModellingImportNwData nwData in AllNwData) + { + foreach (ModellingImportAreaData area in nwData.Areas) + { + // find the current area in the merged data + ModellingImportAreaData? existingArea = mergedNwData.Areas.FirstOrDefault(_ => _.IdString == area.IdString); + if (existingArea is null) + { + mergedNwData.Areas.Add(area); + } + else + { + // replace the existing area with a merge of existing and newly found + mergedNwData.Areas.Remove(existingArea); + mergedNwData.Areas.Add(MergeArea(existingArea, area)); + } + } + } + return mergedNwData; + } + + private async Task SaveArea(ModellingImportAreaData incomingArea) + { + try + { + ModellingNetworkArea? existingArea = existingAreas.FirstOrDefault(x => x.IdString == incomingArea.IdString); + if (existingArea == null) + { + await NewArea(incomingArea); + } + else + { + await UpdateArea(incomingArea, existingArea); + } + } + catch (Exception exc) + { + string errorText = $"Area {incomingArea.Name}({incomingArea.IdString}) could not be processed."; + Log.WriteError(LogMessageTitle, errorText, exc); + await AddLogEntry(GlobalConst.kImportAreaSubnetData, 1, LevelArea, errorText); + return false; + } + return true; + } + + private async Task NewArea(ModellingImportAreaData incomingArea) + { + var AreaVar = new + { + name = incomingArea.Name, + idString = incomingArea.IdString, + creator = GlobalConst.kImportAreaSubnetData + }; + ReturnId[]? areaIds = (await apiConnection.SendQueryAsync(ModellingQueries.newArea, AreaVar)).ReturnIds; + if (areaIds != null) + { + foreach (var ipData in incomingArea.IpData) + { + var ipDataVar = new + { + name = ipData.Name, + ip = ipData.Ip, + ipEnd = ipData.IpEnd, + importSource = GlobalConst.kImportAreaSubnetData + }; + + ReturnId[]? ipDataIds = (await apiConnection.SendQueryAsync(ModellingQueries.newAreaIpData, ipDataVar)).ReturnIds; + if (ipDataIds != null) + { + var Vars = new + { + nwObjectId = ipDataIds[0].NewIdLong, + nwGroupId = areaIds[0].NewIdLong + }; + await apiConnection.SendQueryAsync(ModellingQueries.addNwObjectToNwGroup, Vars); + } + } + } + } + + private async Task UpdateArea(ModellingImportAreaData incomingArea, ModellingNetworkArea existingArea) + { + if (existingArea.IsDeleted) + { + await ReactivateArea(existingArea); + } + List ipDataToAdd = [.. incomingArea.IpData]; + List ipDataToDelete = [.. existingArea.IpData]; + foreach (var existingSubnet in existingArea.IpData) + { + foreach (var incomingSubnet in incomingArea.IpData) + { + if (incomingSubnet.Name == existingSubnet.Content.Name && incomingSubnet.Ip == existingSubnet.Content.Ip?.StripOffNetmask() && + (incomingSubnet.IpEnd == existingSubnet.Content.IpEnd?.StripOffNetmask())) + { + existingSubnet.Content.Ip = existingSubnet.Content.Ip.StripOffNetmask(); + existingSubnet.Content.IpEnd = existingSubnet.Content.IpEnd?.StripOffNetmask(); + ipDataToAdd.Remove(incomingSubnet); + ipDataToDelete.Remove(existingSubnet); + } + } + } + foreach (var ipData in ipDataToDelete) + { + await apiConnection.SendQueryAsync(OwnerQueries.deleteAreaIpData, new { id = ipData.Content.Id }); + } + foreach (var subnet in ipDataToAdd) + { + var SubnetVar = new + { + name = subnet.Name, + ip = subnet.Ip, + ipEnd = subnet.IpEnd, + importSource = GlobalConst.kImportAreaSubnetData + }; + ReturnId[]? ipData = (await apiConnection.SendQueryAsync(ModellingQueries.newAreaIpData, SubnetVar)).ReturnIds; + if (ipData != null) + { + var Vars = new + { + nwObjectId = ipData[0].NewIdLong, + nwGroupId = existingArea.Id, + }; + await apiConnection.SendQueryAsync(ModellingQueries.addNwObjectToNwGroup, Vars); + } + } + } + + private async Task DeleteArea(ModellingNetworkArea area) + { + try + { + await apiConnection.SendQueryAsync(ModellingQueries.setNwGroupDeletedState, new { id = area.Id, deleted = true }); + await apiConnection.SendQueryAsync(ModellingQueries.removeSelectedNwGroupObjectFromAllApps, new { nwGroupId = area.Id }); + } + catch (Exception exc) + { + string errorText = $"Outdated Area {area.Name} could not be deleted."; + Log.WriteError(LogMessageTitle, errorText, exc); + await AddLogEntry(GlobalConst.kImportAreaSubnetData, 1, LevelArea, errorText); + return false; + } + return true; + } + + private async Task ReactivateArea(ModellingNetworkArea area) + { + try + { + await apiConnection.SendQueryAsync(ModellingQueries.setNwGroupDeletedState, new { id = area.Id, deleted = false }); + } + catch (Exception exc) + { + string errorText = $"Area {area.Name}({area.IdString}) could not be reactivated."; + Log.WriteError(LogMessageTitle, errorText, exc); + await AddLogEntry(GlobalConst.kImportAreaSubnetData, 1, LevelArea, errorText); + } + } + } +} diff --git a/roles/middleware/files/FWO.Middleware.Server/AuthLdapSelection.cs b/roles/middleware/files/FWO.Middleware.Server/AuthLdapSelection.cs new file mode 100644 index 0000000000..e7081db8eb --- /dev/null +++ b/roles/middleware/files/FWO.Middleware.Server/AuthLdapSelection.cs @@ -0,0 +1,31 @@ +namespace FWO.Middleware.Server +{ + /// + /// Helper for deterministic LDAP login source selection. + /// + public static class AuthLdapSelection + { + /// + /// Selects the first successful LDAP index based on configured order. + /// + /// Login results in LDAP configuration order. + /// Index of preferred LDAP or -1 if none succeeded. + public static int GetPreferredLdapIndex(IReadOnlyList? loginSuccessByOrder) + { + if (loginSuccessByOrder == null || loginSuccessByOrder.Count == 0) + { + return -1; + } + + for (int index = 0; index < loginSuccessByOrder.Count; index++) + { + if (loginSuccessByOrder[index]) + { + return index; + } + } + + return -1; + } + } +} diff --git a/roles/middleware/files/FWO.Middleware.Server/AuthLoggingHelper.cs b/roles/middleware/files/FWO.Middleware.Server/AuthLoggingHelper.cs new file mode 100644 index 0000000000..8d2f250893 --- /dev/null +++ b/roles/middleware/files/FWO.Middleware.Server/AuthLoggingHelper.cs @@ -0,0 +1,54 @@ +using FWO.Data; + +namespace FWO.Middleware.Server +{ + /// + /// Helper methods for consistent authentication logging. + /// + public static class AuthLoggingHelper + { + private const int kMaxGroupDnsToLog = 50; + + /// + /// Formats selected LDAP connection information for login logs. + /// + /// LDAP connection object. + /// Single-line LDAP descriptor for logs. + public static string FormatSelectedLdap(LdapConnectionBase? ldap) + { + if (ldap == null) + { + return "ldap="; + } + + string tenantInfo = ldap.TenantId.HasValue ? ldap.TenantId.Value.ToString() : ""; + return $"id={ldap.Id}, host={ldap.Host()}, type={ldap.Type}, tenant={tenantInfo}"; + } + + /// + /// Formats resolved group DNs for login logs. + /// + /// Resolved group DNs. + /// Single-line group summary for logs. + public static string FormatResolvedGroups(IEnumerable? groups) + { + if (groups == null) + { + return "count=0, groups=[]"; + } + + List normalizedGroups = groups + .Where(groupDn => !string.IsNullOrWhiteSpace(groupDn)) + .Distinct(StringComparer.OrdinalIgnoreCase) + .OrderBy(groupDn => groupDn, StringComparer.OrdinalIgnoreCase) + .ToList(); + int totalGroups = normalizedGroups.Count; + if (totalGroups > kMaxGroupDnsToLog) + { + normalizedGroups = normalizedGroups.Take(kMaxGroupDnsToLog).ToList(); + } + + return $"count={totalGroups}, groups=[{string.Join("; ", normalizedGroups)}]"; + } + } +} diff --git a/roles/middleware/files/FWO.Middleware.Server/AutoDiscoverScheduler.cs b/roles/middleware/files/FWO.Middleware.Server/AutoDiscoverScheduler.cs deleted file mode 100644 index c9cf58ccc8..0000000000 --- a/roles/middleware/files/FWO.Middleware.Server/AutoDiscoverScheduler.cs +++ /dev/null @@ -1,232 +0,0 @@ -using FWO.Api.Client; -using FWO.Api.Client.Queries; -using FWO.Api.Data; -using FWO.Config.Api; -using FWO.Config.Api.Data; -using FWO.Logging; -using System.Timers; -using FWO.DeviceAutoDiscovery; - -namespace FWO.Middleware.Server -{ - /// - /// Class handling the scheduler for the autodiscovery - /// - public class AutoDiscoverScheduler - { - private readonly ApiConnection apiConnection; - private GlobalConfig globalConfig; - private long? lastMgmtAlertId; - private List openAlerts = new List(); - - private System.Timers.Timer ScheduleTimer = new(); - private System.Timers.Timer AutoDiscoverTimer = new(); - - /// - /// Async Constructor needing the connection - /// - public static async Task CreateAsync(ApiConnection apiConnection) - { - GlobalConfig globalConfig = await GlobalConfig.ConstructAsync(apiConnection, true); - return new AutoDiscoverScheduler(apiConnection, globalConfig); - } - - private AutoDiscoverScheduler(ApiConnection apiConnection, GlobalConfig globalConfig) - { - this.apiConnection = apiConnection; - this.globalConfig = globalConfig; - globalConfig.OnChange += GlobalConfig_OnChange; - startScheduleTimer(); - } - - private void GlobalConfig_OnChange(Config.Api.Config globalConfig, ConfigItem[] _) - { - AutoDiscoverTimer.Interval = globalConfig.AutoDiscoverSleepTime * 3600000; // convert hours to milliseconds - ScheduleTimer.Stop(); - startScheduleTimer(); - } - - private void startScheduleTimer() - { - if (globalConfig.AutoDiscoverSleepTime > 0) - { - DateTime startTime = DateTime.Now; - try - { - startTime = globalConfig.AutoDiscoverStartAt; - while (startTime < DateTime.Now) - { - startTime = startTime.AddHours(globalConfig.AutoDiscoverSleepTime); - } - } - catch (Exception exception) - { - Log.WriteError("Autodiscover scheduler", "Could not calculate start time.", exception); - } - TimeSpan interval = startTime - DateTime.Now; - - ScheduleTimer = new(); - ScheduleTimer.Elapsed += AutoDiscover; - ScheduleTimer.Elapsed += StartAutoDiscoverTimer; - ScheduleTimer.Interval = interval.TotalMilliseconds; - ScheduleTimer.AutoReset = false; - ScheduleTimer.Start(); - Log.WriteDebug("Autodiscover scheduler", "AutodiscoverScheduleTimer started."); - } - } - - private void StartAutoDiscoverTimer(object? _, ElapsedEventArgs __) - { - AutoDiscoverTimer.Stop(); - AutoDiscoverTimer = new(); - AutoDiscoverTimer.Elapsed += AutoDiscover; - AutoDiscoverTimer.Interval = globalConfig.AutoDiscoverSleepTime * 3600000; // convert hours to milliseconds - AutoDiscoverTimer.AutoReset = true; - AutoDiscoverTimer.Start(); - Log.WriteDebug("Autodiscover scheduler", "AutoDiscoverTimer started."); - } - - private async void AutoDiscover(object? _, ElapsedEventArgs __) - { - try - { - openAlerts = await apiConnection.SendQueryAsync>(MonitorQueries.getOpenAlerts); - List managements = await apiConnection.SendQueryAsync>(DeviceQueries.getManagementsDetails); - foreach (Management superManagement in managements.Where(x => x.DeviceType.CanBeSupermanager() || x.DeviceType.CanBeAutodiscovered(x))) - { - try - { - AutoDiscoveryBase autodiscovery = new AutoDiscoveryBase(superManagement, apiConnection); - - List diffList = await autodiscovery.Run(); - List actions = autodiscovery.ConvertToActions(diffList); - // List actions = autodiscovery.ConvertToActions(await autodiscovery.Run()); - - int ChangeCounter = 0; - - foreach (ActionItem action in actions) - { - if (action.ActionType == ActionCode.AddGatewayToNewManagement.ToString()) - { - action.RefAlertId = lastMgmtAlertId; - } - action.AlertId = await setAlert(action); - ChangeCounter++; - } - await AddAutoDiscoverLogEntry(0, globalConfig.GetText("scheduled_autodiscovery"), (ChangeCounter > 0 ? ChangeCounter + globalConfig.GetText("changes_found") : globalConfig.GetText("found_no_changes")), superManagement.Id); - } - catch (Exception excMgm) - { - Log.WriteError("Autodiscovery", $"Ran into exception while auto-discovering management {superManagement.Name} (id: {superManagement.Id}) ", excMgm); - ActionItem actionException = new ActionItem(); - actionException.Number = 0; - actionException.ActionType = ActionCode.WaitForTempLoginFailureToPass.ToString(); - actionException.ManagementId = superManagement.Id; - actionException.Supermanager = superManagement.Name; - actionException.JsonData = excMgm.Message; - await setAlert(actionException); - await AddAutoDiscoverLogEntry(1, globalConfig.GetText("scheduled_autodiscovery"), $"Ran into exception while handling management {superManagement.Name} (id: {superManagement.Id}): " + excMgm.Message, superManagement.Id); - } - } - } - catch (Exception exc) - { - Log.WriteError("Autodiscovery", $"Ran into exception: ", exc); - Log.WriteAlert($"source: \"{GlobalConfig.kAutodiscovery}\"", - $"userId: \"0\", title: \"Error encountered while trying to autodiscover\", description: \"{exc}\", alertCode: \"{AlertCode.Autodiscovery}\""); - await AddAutoDiscoverLogEntry(1, globalConfig.GetText("scheduled_autodiscovery"), globalConfig.GetText("ran_into_exception") + exc.Message); - } - } - - private async Task setAlert(ActionItem action) - { - long? alertId = null; - try - { - string title = "Supermanagement: " + action.Supermanager; - Log.WriteAlert($"source: \"{GlobalConfig.kAutodiscovery}\"", - $"userId: \"0\", title: \"{title}\", type: \"{action.ActionType}\", " + - $"mgmId: \"{action.ManagementId}\", devId: \"{action.DeviceId}\", jsonData: \"{action.JsonData?.ToString()}\", refAlert: \"{action.RefAlertId}\", alertCode: \"{AlertCode.Autodiscovery}\""); - var Variables = new - { - source = GlobalConfig.kAutodiscovery, - userId = 0, - title = title, - description = action.ActionType, - mgmId = action.ManagementId, - devId = action.DeviceId, - jsonData = action.JsonData, - refAlert = action.RefAlertId, - alertCode = (int)AlertCode.Autodiscovery - }; - ReturnId[]? returnIds = (await apiConnection.SendQueryAsync(MonitorQueries.addAlert, Variables)).ReturnIds; - if (returnIds != null) - { - alertId = returnIds[0].NewId; - if (action.ActionType == ActionCode.AddManagement.ToString()) - { - lastMgmtAlertId = alertId; - } - // Acknowledge older alert for same problem - Alert? existingAlert = openAlerts.FirstOrDefault(x => x.AlertCode == AlertCode.Autodiscovery - && x.Description == action.ActionType && x.ManagementId == action.ManagementId); - if (existingAlert != null) - { - await AcknowledgeAlert(existingAlert.Id); - } - } - else - { - Log.WriteError("Write Alert", "Log could not be written to database"); - } - } - catch (Exception exc) - { - Log.WriteError("Write Alert", $"Could not write Alert for autodiscovery: ", exc); - } - return alertId; - } - - private async Task AcknowledgeAlert(long alertId) - { - try - { - var Variables = new - { - id = alertId, - ackUser = 0, - ackTime = DateTime.Now - }; - await apiConnection.SendQueryAsync(MonitorQueries.acknowledgeAlert, Variables); - } - catch (Exception exception) - { - Log.WriteError("Acknowledge Alert", $"Could not acknowledge alert for autodiscovery: ", exception); - } - } - - private async Task AddAutoDiscoverLogEntry(int severity, string cause, string description, int? mgmtId = null) - { - try - { - var Variables = new - { - discoverUser = 0, - severity = severity, - suspectedCause = cause, - description = description, - mgmId = mgmtId - }; - ReturnId[]? returnIds = (await apiConnection.SendQueryAsync(MonitorQueries.addAutodiscoveryLogEntry, Variables)).ReturnIds; - if (returnIds == null) - { - Log.WriteError("Write Log", "Log could not be written to database"); - } - } - catch (Exception exc) - { - Log.WriteError("Write Log", $"Could not write log: ", exc); - } - } - } -} diff --git a/roles/middleware/files/FWO.Middleware.Server/Controllers/AuthenticationServerController.cs b/roles/middleware/files/FWO.Middleware.Server/Controllers/AuthenticationServerController.cs index 73f51b4c6e..35226da292 100644 --- a/roles/middleware/files/FWO.Middleware.Server/Controllers/AuthenticationServerController.cs +++ b/roles/middleware/files/FWO.Middleware.Server/Controllers/AuthenticationServerController.cs @@ -1,15 +1,15 @@ -using FWO.Api.Client.Queries; using FWO.Api.Client; -using FWO.Api.Data; +using FWO.Api.Client.Queries; +using FWO.Basics; +using FWO.Data; +using FWO.Data.Middleware; using FWO.Logging; -using FWO.Middleware.Server; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; -using FWO.Middleware.RequestParameters; // For more information on enabling Web API for empty projects, visit https://go.microsoft.com/fwlink/?LinkID=397860 -namespace FWO.Middleware.Controllers +namespace FWO.Middleware.Server.Controllers { /// /// Controller for Ldap administration @@ -22,9 +22,9 @@ public class AuthenticationServerController : ControllerBase private List ldaps; private readonly ApiConnection apiConnection; - /// - /// Constructor needing connection and ldap list - /// + /// + /// Constructor needing connection and ldap list + /// public AuthenticationServerController(ApiConnection apiConnection, List ldaps) { this.apiConnection = apiConnection; @@ -43,13 +43,13 @@ public AuthenticationServerController(ApiConnection apiConnection, List ld /// Ldap connection parameters /// [HttpGet("TestConnection")] - [Authorize(Roles = "admin, auditor")] - public ActionResult TestConnection([FromBody] LdapGetUpdateParameters parameters) + [Authorize(Roles = $"{Roles.Admin}, {Roles.Auditor}")] + public async Task> TestConnection([FromBody] LdapGetUpdateParameters parameters) { try { Ldap ldapToTest = new Ldap(parameters); - ldapToTest.TestConnection(); + await ldapToTest.TestConnection(); } catch (Exception e) { @@ -64,11 +64,11 @@ public ActionResult TestConnection([FromBody] LdapGetUpdateParameters pa /// /// List of all connected Ldaps [HttpGet] - [Authorize(Roles = "admin, auditor")] + [Authorize(Roles = $"{Roles.Admin}, {Roles.Auditor}")] public async Task> Get() { - UiLdapConnection[] ldapConnections = (await apiConnection.SendQueryAsync(AuthQueries.getAllLdapConnections)); - List ldapList = new List(); + UiLdapConnection[] ldapConnections = await apiConnection.SendQueryAsync(AuthQueries.getAllLdapConnections); + List ldapList = []; foreach (UiLdapConnection conn in ldapConnections) { ldapList.Add(conn.ToApiParams()); @@ -93,6 +93,7 @@ public async Task> Get() /// SearchpathForUsers (required) /// SearchpathForRoles (optional) /// SearchpathForGroups (optional) + /// WritepathForGroups (optional) /// WriteUser (optional) /// WriteUserPwd (optional) /// TenantId (optional) @@ -102,16 +103,16 @@ public async Task> Get() /// LdapAddParameters /// Id of new ldap, 0 if no ldap could be added [HttpPost] - [Authorize(Roles = "admin")] + [Authorize(Roles = $"{Roles.Admin}")] public async Task PostAsync([FromBody] LdapAddParameters ldapData)//, [FromHeader] string bearer) { // Add ldap to DB and to middleware ldap list - ReturnId[]? returnIds = (await apiConnection.SendQueryAsync(AuthQueries.newLdapConnection, ldapData)).ReturnIds; + ReturnId[]? returnIds = (await apiConnection.SendQueryAsync(AuthQueries.newLdapConnection, ldapData)).ReturnIds; int ldapId = 0; if (returnIds != null) { ldapId = returnIds[0].NewId; - ldaps.Add(new Ldap(new LdapGetUpdateParameters (ldapData, ldapId) {})); + ldaps.Add(new Ldap(new LdapGetUpdateParameters(ldapData, ldapId) { })); Log.WriteAudit("AddLdap", $"LDAP server {ldapData.Address}:{ldapData.Port} successfully added"); } @@ -137,6 +138,7 @@ public async Task PostAsync([FromBody] LdapAddParameters ldapData)//, [From /// SearchpathForUsers (required) /// SearchpathForRoles (optional) /// SearchpathForGroups (optional) + /// WritepathForGroups (optional) /// WriteUser (optional) /// WriteUserPwd (optional) /// TenantId (optional) @@ -146,7 +148,7 @@ public async Task PostAsync([FromBody] LdapAddParameters ldapData)//, [From /// LdapGetUpdateParameters /// Id of updated ldap [HttpPut] - [Authorize(Roles = "admin")] + [Authorize(Roles = $"{Roles.Admin}")] public async Task Update([FromBody] LdapGetUpdateParameters ldapData) { // Update ldap in DB and in middleware ldap list @@ -171,7 +173,7 @@ public async Task Update([FromBody] LdapGetUpdateParameters ldapData) /// LdapDeleteParameters /// Id of deleted ldap connection [HttpDelete] - [Authorize(Roles = "admin")] + [Authorize(Roles = $"{Roles.Admin}")] public async Task Delete([FromBody] LdapDeleteParameters ldapData) { // Delete ldap in DB and in middleware ldap list diff --git a/roles/middleware/files/FWO.Middleware.Server/Controllers/AuthenticationTokenController.cs b/roles/middleware/files/FWO.Middleware.Server/Controllers/AuthenticationTokenController.cs index dbdb474226..fa4a49119a 100644 --- a/roles/middleware/files/FWO.Middleware.Server/Controllers/AuthenticationTokenController.cs +++ b/roles/middleware/files/FWO.Middleware.Server/Controllers/AuthenticationTokenController.cs @@ -1,18 +1,15 @@ -using FWO.Api.Data; using FWO.Api.Client; using FWO.Api.Client.Queries; +using FWO.Basics; +using FWO.Data; +using FWO.Data.Middleware; using FWO.Logging; -using FWO.Middleware.Server; using Microsoft.AspNetCore.Mvc; -using FWO.Middleware.RequestParameters; -using System.Security.Authentication; -using Microsoft.AspNetCore.Authentication.OAuth; using Novell.Directory.Ldap; -using Microsoft.IdentityModel.Tokens; -using Microsoft.AspNetCore.Authorization; using System.Data; +using System.Security.Authentication; -namespace FWO.Middleware.Controllers +namespace FWO.Middleware.Server.Controllers { /// /// Authentication token generation. Token is of type JSON web token (JWT). @@ -25,9 +22,9 @@ public class AuthenticationTokenController : ControllerBase private readonly List ldaps; private readonly ApiConnection apiConnection; - /// - /// Constructor needing jwt writer, ldap list and connection - /// + /// + /// Constructor needing jwt writer, ldap list and connection + /// public AuthenticationTokenController(JwtWriter jwtWriter, List ldaps, ApiConnection apiConnection) { this.jwtWriter = jwtWriter; @@ -61,7 +58,7 @@ public async Task> GetAsync([FromBody] AuthenticationTokenG user = new UiUser { Name = username, Password = password }; } - AuthManager authManager = new AuthManager(jwtWriter, ldaps, apiConnection); + AuthManager authManager = new(jwtWriter, ldaps, apiConnection); // Authenticate user string jwt = await authManager.AuthorizeUserAsync(user, validatePassword: true); @@ -96,13 +93,13 @@ public async Task> GetAsyncForUser([FromBody] Authenticatio string targetUserName = parameters.TargetUserName; string targetUserDn = parameters.TargetUserDn; - AuthManager authManager = new AuthManager(jwtWriter, ldaps, apiConnection); - UiUser adminUser = new UiUser() { Name = adminUsername, Password = adminPassword }; + AuthManager authManager = new(jwtWriter, ldaps, apiConnection); + UiUser adminUser = new() { Name = adminUsername, Password = adminPassword }; // Check if admin valids are valid try { await authManager.AuthorizeUserAsync(adminUser, validatePassword: true); - if (!adminUser.Roles.Contains("admin")) + if (!adminUser.Roles.Contains(Roles.Admin)) { throw new AuthenticationException("Provided credentials do not belong to a user with role admin."); } @@ -114,7 +111,7 @@ public async Task> GetAsyncForUser([FromBody] Authenticatio // Check if username is valid and generate jwt try { - UiUser targetUser = new UiUser { Name = targetUserName, Dn = targetUserDn }; + UiUser targetUser = new() { Name = targetUserName, Dn = targetUserDn }; string jwt = await authManager.AuthorizeUserAsync(targetUser, validatePassword: false, lifetime); return Ok(jwt); } @@ -135,6 +132,7 @@ class AuthManager private readonly JwtWriter jwtWriter; private readonly List ldaps; private readonly ApiConnection apiConnection; + private readonly string UserAuthentication = "User Authentication"; public AuthManager(JwtWriter jwtWriter, List ldaps, ApiConnection apiConnection) { @@ -157,22 +155,29 @@ public async Task AuthorizeUserAsync(UiUser? user, bool validatePassword return await jwtWriter.CreateJWT(); // Retrieve ldap entry for user (throws exception if credentials are invalid) - (LdapEntry ldapUser, Ldap ldap) = await GetLdapEntry(user, validatePassword); + (LdapEntry ldapUser, Ldap ldap) = await AuthenticateInAnyLdap(user, validatePassword); // Get dn of user user.Dn = ldapUser.Dn; + Log.WriteInfo(UserAuthentication, + $"User {user.Name} authenticated with dn={user.Dn}, selected_ldap=({AuthLoggingHelper.FormatSelectedLdap(ldap)})"); // Get email of user - user.Email = ldap.GetEmail(ldapUser); + user.Email = Ldap.GetEmail(ldapUser); + user.Firstname = Ldap.GetFirstName(ldapUser); + user.Lastname = Ldap.GetLastName(ldapUser); // Get groups of user - user.Groups = ldap.GetGroups(ldapUser); + user.Groups = await GetGroups(ldapUser, ldap); + Log.WriteInfo(UserAuthentication, + $"Resolved groups for user dn={user.Dn}: {AuthLoggingHelper.FormatResolvedGroups(user.Groups)}"); // Get roles of user user.Roles = await GetRoles(user); // Get tenant of user user.Tenant = await GetTenantAsync(ldapUser, ldap); + Log.WriteDebug("Get Tenants", $"Found tenant for user: {user.Tenant?.Name ?? ""}"); // Remember the hosting ldap user.LdapConnection.Id = ldap.Id; @@ -181,108 +186,147 @@ public async Task AuthorizeUserAsync(UiUser? user, bool validatePassword return await jwtWriter.CreateJWT(user, lifetime); } - public async Task<(LdapEntry, Ldap)> GetLdapEntry(UiUser user, bool validatePassword) + public async Task> GetGroups(LdapEntry ldapUser, Ldap ldap) { - Log.WriteDebug("User Authentication", $"Trying to ldap entry for user: {user.Name + " " + user.Dn}..."); - - if (user.Dn == "" && user.Name == "") + HashSet userGroups = new(StringComparer.OrdinalIgnoreCase); + userGroups.UnionWith(ldap.GetGroups(ldapUser)); + if (userGroups.Count == 0) { - throw new Exception("A0001 Invalid credentials. Username / User DN must not be empty."); + string? groupPath = !string.IsNullOrWhiteSpace(ldap.GroupSearchPath) ? ldap.GroupSearchPath : ldap.GroupWritePath; + List groupNames = await ldap.GetGroups([ldapUser.Dn]); + userGroups.UnionWith(Ldap.BuildGroupDns(groupNames, groupPath)); } - - else + if (!ldap.IsInternal()) { - LdapEntry? ldapEntry = null; - Ldap? ldap = null; - List ldapValidationRequests = new List(); - object dnLock = new object(); - bool ldapFound = false; + object groupsLock = new(); + List ldapRoleRequests = []; - foreach (Ldap currentLdap in ldaps.Where(x => x.Active)) + foreach (Ldap currentLdap in ldaps.Where(l => l.IsInternal())) { - ldapValidationRequests.Add(Task.Run(() => + ldapRoleRequests.Add(Task.Run(async () => { - Log.WriteDebug("User Authentication", $"Trying to authenticate {user.Name + " " + user.Dn} against LDAP {currentLdap.Address}:{currentLdap.Port} ..."); - - try - { - LdapEntry? currentLdapEntry = currentLdap.GetLdapEntry(user, validatePassword); - - if (currentLdapEntry != null) - { - // User was successfully authenticated via this LDAP - if(user.Name == "importer") - { - Log.WriteDebug("User Authentication", $"User {user.Name + " " + currentLdapEntry.Dn} found."); - } - else - { - Log.WriteInfo("User Authentication", $"User {user.Name + " " + currentLdapEntry.Dn} found."); - } - - lock (dnLock) - { - if (!ldapFound) - { - ldapEntry = currentLdapEntry; - ldap = currentLdap; - ldapFound = true; - } - } - } - } - catch + // Get groups from current Ldap + List currentGroups = await currentLdap.GetGroups([ldapUser.Dn]); + lock (groupsLock) { - // this Ldap can't validate user, but maybe another one can + string? groupPath = !string.IsNullOrWhiteSpace(currentLdap.GroupSearchPath) ? currentLdap.GroupSearchPath : currentLdap.GroupWritePath; + userGroups.UnionWith(Ldap.BuildGroupDns(currentGroups, groupPath)); } })); } + await Task.WhenAll(ldapRoleRequests); + } + return userGroups.ToList(); + } + + public async Task<(LdapEntry, Ldap)> AuthenticateInAnyLdap(UiUser user, bool validatePassword) + { + Log.WriteDebug(UserAuthentication, $"Trying to get ldap entry for user: {user.Name + " " + user.Dn}..."); + + if (user.Dn == "" && user.Name == "") + { + throw new AuthenticationException("A0001 Invalid credentials. Username / User DN must not be empty."); + } + else + { + (LdapEntry? ldapEntry, Ldap? ldap) = await TryLoginAnywhere(user, validatePassword); + if (ldapEntry != null && ldap != null) + { + return (ldapEntry, ldap); + } + Log.WriteInfo(UserAuthentication, $"User {user.Name} not found in any connected LDAP."); + } + + // Invalid User Credentials + throw new AuthenticationException("A0002 Invalid credentials"); + } + + private async Task<(LdapEntry?, Ldap?)> TryLoginAnywhere(UiUser user, bool validatePassword) + { + List activeLdaps = ldaps.Where(x => x.Active).ToList(); + if (activeLdaps.Count == 0) + { + return (null, null); + } + + (LdapEntry? Entry, Ldap? Ldap)[] ldapResults = new (LdapEntry?, Ldap?)[activeLdaps.Count]; + List ldapValidationRequests = []; - while (ldapValidationRequests.Count > 0) + for (int ldapIndex = 0; ldapIndex < activeLdaps.Count; ldapIndex++) + { + int currentIndex = ldapIndex; + Ldap currentLdap = activeLdaps[currentIndex]; + ldapValidationRequests.Add(Task.Run(async () => { - Task finishedDnRequest = await Task.WhenAny(ldapValidationRequests); + Log.WriteDebug(UserAuthentication, $"Trying to authenticate {user.Name + " " + user.Dn} against LDAP {currentLdap.Address}:{currentLdap.Port} ..."); + LdapEntry? currentLdapEntry = await TryLogin(currentLdap, user, validatePassword); + ldapResults[currentIndex] = (currentLdapEntry, currentLdapEntry != null ? currentLdap : null); + })); + } + + await Task.WhenAll(ldapValidationRequests); + + int preferredLdapIndex = AuthLdapSelection.GetPreferredLdapIndex( + ldapResults.Select(result => result.Entry != null).ToList()); + if (preferredLdapIndex >= 0) + { + return ldapResults[preferredLdapIndex]; + } + return (null, null); + } - if (ldapEntry != null && ldap != null) + private async Task TryLogin(Ldap currentLdap, UiUser user, bool validatePassword) + { + LdapEntry? currentLdapEntry = null; + try + { + currentLdapEntry = await currentLdap.GetLdapEntry(user, validatePassword); + if (currentLdapEntry != null) + { + // User was successfully authenticated via this LDAP + if (user.Name == Roles.Importer) { - return (ldapEntry, ldap); + Log.WriteDebug(UserAuthentication, $"User {user.Name + " " + currentLdapEntry.Dn} found."); + } + else + { + Log.WriteInfo(UserAuthentication, $"User {user.Name + " " + currentLdapEntry.Dn} found."); } - - ldapValidationRequests.Remove(finishedDnRequest); } - Log.WriteInfo("User Authentication", $"User {user.Name} not found in any connected LDAP."); } - - // Invalid User Credentials - throw new Exception("A0002 Invalid credentials"); + catch + { + // this Ldap can't validate user, but maybe another one can + } + return currentLdapEntry; } public async Task> GetRoles(UiUser user) { - List dnList = new() { user.Dn }; - // search all groups where user is member for group associated roles - dnList.AddRange(user.Groups); + List dnList = + [ + user.Dn, + .. user.Groups, // search all groups where user is member for group associated roles + ]; - List userRoles = new List(); - object rolesLock = new object(); + List userRoles = []; + object rolesLock = new(); - List ldapRoleRequests = new List(); + List ldapRoleRequests = []; - foreach (Ldap currentLdap in ldaps) + foreach (Ldap currentLdap in ldaps.Where(l => l.HasRoleHandling())) { // if current Ldap has roles stored - if (currentLdap.HasRoleHandling()) + ldapRoleRequests.Add(Task.Run(async () => { - ldapRoleRequests.Add(Task.Run(() => - { - // Get roles from current Ldap - List currentRoles = currentLdap.GetRoles(dnList); + // Get roles from current Ldap + List currentRoles = await currentLdap.GetRoles(dnList); - lock (rolesLock) - { - userRoles.AddRange(currentRoles); - } - })); - } + lock (rolesLock) + { + userRoles.AddRange(currentRoles); + } + })); } await Task.WhenAll(ldapRoleRequests); @@ -292,7 +336,7 @@ public async Task> GetRoles(UiUser user) { // Use anonymous role Log.WriteWarning("Missing roles", $"No roles for user \"{user.Dn}\" could be found. Using anonymous role."); - userRoles.Add("anonymous"); + userRoles.Add(Roles.Anonymous); } return userRoles; @@ -300,7 +344,7 @@ public async Task> GetRoles(UiUser user) public async Task GetTenantAsync(LdapEntry user, Ldap ldap) { - Tenant tenant = new Tenant(); + Tenant tenant = new(); if (ldap.TenantId != null) { Log.WriteDebug("Get Tenant", $"This LDAP has the fixed tenant {ldap.TenantId.Value}"); @@ -308,7 +352,7 @@ public async Task> GetRoles(UiUser user) } else { - tenant.Name = new DistName(user.Dn).getTenant(ldap.TenantLevel); + tenant.Name = new DistName(user.Dn).GetTenantNameViaLdapTenantLevel(ldap.TenantLevel); if (tenant.Name == "") { return null; @@ -316,7 +360,7 @@ public async Task> GetRoles(UiUser user) Log.WriteDebug("Get Tenant", $"extracting TenantName as: {tenant.Name} from {user.Dn}"); if (tenant.Name == ldap.GlobalTenantName) { - tenant.Id = 1; + tenant.Id = GlobalConst.kTenant0Id; } else { @@ -329,46 +373,56 @@ public async Task> GetRoles(UiUser user) else { // tenant unknown: create in db. This should only happen for users from external Ldaps - try - { - var Variables = new - { - name = tenant.Name, - project = "", - comment = "", - viewAllDevices = false, - create = DateTime.Now - }; - ReturnId[]? returnIds = (await apiConnection.SendQueryAsync(AuthQueries.addTenant, Variables)).ReturnIds; - if (returnIds != null) - { - tenant.Id = returnIds[0].NewId; - // no further search for devices etc necessary - return tenant; - } - else - { - return null; - } - } - catch (Exception exception) - { - Log.WriteError("AddTenant", $"Adding Tenant {tenant.Name} locally failed: {exception.Message}"); - return null; - } + // no further search for devices etc necessary + return await CreateTenantInDb(tenant); } } } + await AddDevices(apiConnection, tenant); - var tenIdObj = new { tenantId = tenant.Id }; + return tenant; + } + + private async Task CreateTenantInDb(Tenant tenant) + { + try + { + var Variables = new + { + name = tenant.Name, + project = "", + comment = "", + viewAllDevices = false, + create = DateTime.Now + }; + ReturnId[]? returnIds = (await apiConnection.SendQueryAsync(AuthQueries.addTenant, Variables)).ReturnIds; + if (returnIds != null) + { + tenant.Id = returnIds[0].NewId; + return tenant; + } + else + { + return null; + } + } + catch (Exception exception) + { + Log.WriteError("AddTenant", $"Adding Tenant {tenant.Name} locally failed: {exception.Message}"); + return null; + } + } - Device[] deviceIds = await apiConnection.SendQueryAsync(AuthQueries.getVisibleDeviceIdsPerTenant, tenIdObj, "getVisibleDeviceIdsPerTenant"); - tenant.VisibleDevices = Array.ConvertAll(deviceIds, device => device.Id); + // the following method adds device visibility information to a tenant (fetched from API) + private static async Task AddDevices(ApiConnection conn, Tenant tenant) + { + var tenIdObj = new { tenantId = tenant.Id }; - Management[] managementIds = await apiConnection.SendQueryAsync(AuthQueries.getVisibleManagementIdsPerTenant, tenIdObj, "getVisibleManagementIdsPerTenant"); - tenant.VisibleManagements = Array.ConvertAll(managementIds, management => management.Id); + Device[] deviceIds = await conn.SendQueryAsync(AuthQueries.getVisibleDeviceIdsPerTenant, tenIdObj, "getVisibleDeviceIdsPerTenant"); + tenant.VisibleGatewayIds = Array.ConvertAll(deviceIds, device => device.Id); - return tenant; + Management[] managementIds = await conn.SendQueryAsync(AuthQueries.getVisibleManagementIdsPerTenant, tenIdObj, "getVisibleManagementIdsPerTenant"); + tenant.VisibleManagementIds = Array.ConvertAll(managementIds, management => management.Id); } } } diff --git a/roles/middleware/files/FWO.Middleware.Server/Controllers/ComplianceController.cs b/roles/middleware/files/FWO.Middleware.Server/Controllers/ComplianceController.cs new file mode 100644 index 0000000000..430944b222 --- /dev/null +++ b/roles/middleware/files/FWO.Middleware.Server/Controllers/ComplianceController.cs @@ -0,0 +1,105 @@ +using FWO.Api.Client; +using FWO.Basics; +using FWO.Config.Api; +using FWO.Compliance; +using FWO.Data; +using FWO.Data.Middleware; +using FWO.Logging; +using Microsoft.AspNetCore.Authorization; +using Microsoft.AspNetCore.Mvc; +using System.Text.Json; +using FWO.Report; + +namespace FWO.Middleware.Server.Controllers +{ + /// + /// Controller class for compliance api + /// + [Authorize] + [ApiController] + [Route("api/[controller]")] + public class ComplianceController(ApiConnection apiConnection) : ControllerBase + { + /// + /// Import Compliance Matrix + /// + /// ComplianceImportMatrixParameters + /// Failed import filenames + [HttpPost("ImportMatrix")] + [Authorize(Roles = $"{Roles.Admin}")] + public async Task Post([FromBody] ComplianceImportMatrixParameters parameters) + { + try + { + GlobalConfig GlobalConfig = await GlobalConfig.ConstructAsync(apiConnection, true); + ZoneMatrixDataImport matrixDataImport = new(apiConnection, GlobalConfig); + return await matrixDataImport.Run(parameters.FileName, parameters.Data, parameters.UserName, parameters.UserDn); + } + catch (Exception exception) + { + Log.WriteError("Import Compliance Matrix", "Error while importing matrix.", exception); + return exception.Message; + } + } + + /// + /// Get Compliance Report + /// + /// ComplianceReportParameters + /// Report as json string + [HttpPost("Report")] + [Authorize(Roles = $"{Roles.Admin}, {Roles.Auditor}, {Roles.Reporter}, {Roles.ReporterViewAll}, {Roles.FwAdmin}, {Roles.Recertifier}")] + public async Task Get([FromBody] ComplianceReportParameters parameters) + { + try + { + GlobalConfig globalConfig = await GlobalConfig.ConstructAsync(apiConnection, true); + UserConfig userConfig = new(globalConfig, apiConnection, new() { Language = GlobalConst.kEnglish }); + + ComplianceCheck complianceCheck = new(userConfig, apiConnection); + await complianceCheck.RunComplianceCheck(ComplianceCheckType.Standard); + + ReportCompliance reportCompliance = new(new(""), userConfig, ReportType.ComplianceReport); + await reportCompliance.GetManagementAndDevices(apiConnection); + List relevantManagements = ComplianceCheck.GetRelevantManagements(globalConfig, reportCompliance.Managements!); + reportCompliance.Managements = relevantManagements; + reportCompliance.GetViewDataFromRules(complianceCheck.RulesInCheck!); + string reportString = reportCompliance.ExportToCsv(); + return reportString; + } + catch (Exception exception) + { + Log.WriteError("Get Compliance Report", "Error while getting report.", exception); + } + return ""; + } + + /// + /// Compliance Check + /// + /// + [HttpGet("ComplianceCheck")] + [Authorize(Roles = $"{Roles.Admin}")] + public async Task InitialComplianceCheck() + { + try + { + GlobalConfig globalConfig = await GlobalConfig.ConstructAsync(apiConnection, true); + UserConfig userConfig = new(globalConfig, apiConnection, new() { Language = GlobalConst.kEnglish }); + ComplianceCheck complianceCheck = new(userConfig, apiConnection); + await complianceCheck.RunComplianceCheck(ComplianceCheckType.Variable); + await complianceCheck.PersistDataAsync(); + return true; + } + catch (Exception) + { + return false; + } + } + + private static string ConvertOutput(List<(Rule, (ComplianceNetworkZone, ComplianceNetworkZone))> forbiddenCommunicationsOutput) + { + return JsonSerializer.Serialize(forbiddenCommunicationsOutput); + } + } +} diff --git a/roles/middleware/files/FWO.Middleware.Server/Controllers/ExternalRequestController.cs b/roles/middleware/files/FWO.Middleware.Server/Controllers/ExternalRequestController.cs new file mode 100644 index 0000000000..7bc78860e0 --- /dev/null +++ b/roles/middleware/files/FWO.Middleware.Server/Controllers/ExternalRequestController.cs @@ -0,0 +1,91 @@ +using FWO.Api.Client; +using FWO.Basics; +using FWO.Config.Api; +using FWO.Data; +using FWO.Data.Middleware; +using Microsoft.AspNetCore.Authorization; +using Microsoft.AspNetCore.Mvc; + +namespace FWO.Middleware.Server.Controllers +{ + /// + /// Controller class for role api + /// + [Authorize] + [ApiController] + [Route("api/[controller]")] + public class ExternalRequestController : ControllerBase + { + private readonly ApiConnection apiConnection; + + /// + /// Constructor needing jwt writer, ldap list and connection + /// + public ExternalRequestController(ApiConnection apiConnection) + { + this.apiConnection = apiConnection; + } + + /// + /// Add new ExternalRequest + /// + /// + /// TicketId (required) + /// + /// ExternalRequestAddParameters + /// true if external request could be added + [HttpPost] + [Authorize(Roles = $"{Roles.Modeller}, {Roles.Admin}")] + public async Task Post([FromBody] ExternalRequestAddParameters parameters) + { + if (parameters.TicketId > 0) + { + using GlobalConfig GlobalConfig = await GlobalConfig.ConstructAsync(apiConnection, true); + using UserConfig userConfig = new(GlobalConfig, apiConnection, new() { Language = GlobalConst.kEnglish }); + using ExternalRequestHandler extRequestHandler = new(userConfig, apiConnection); + return await extRequestHandler.SendFirstRequest(parameters.TicketId); + } + else + { + return false; + } + } + + /// + /// Patch ExternalRequest state + /// + /// + /// ExtRequestId (required) + /// TicketId (required) + /// TaskNumber (required) + /// ExtQueryVariables (optional) + /// ExtRequestState (required) + /// + /// ExternalRequestPatchStateParameters + /// true if external request state could be patched + [HttpPatch("PatchState")] + [Authorize(Roles = $"{Roles.Admin}")] + public async Task Change([FromBody] ExternalRequestPatchStateParameters parameters) + { + if (parameters.ExtRequestId > 0) + { + using GlobalConfig GlobalConfig = await GlobalConfig.ConstructAsync(apiConnection, true); + using UserConfig userConfig = new(GlobalConfig, apiConnection, new() { Language = GlobalConst.kEnglish }); + using ExternalRequestHandler extRequestHandler = new(userConfig, apiConnection); + ExternalRequest extRequest = new() + { + Id = parameters.ExtRequestId, + TicketId = parameters.TicketId, + TaskNumber = parameters.TaskNumber, + ExtQueryVariables = parameters.ExtQueryVariables, + ExtRequestState = parameters.ExtRequestState + }; + return await extRequestHandler.PatchState(extRequest); + } + else + { + return false; + } + } + } +} diff --git a/roles/middleware/files/FWO.Middleware.Server/Controllers/GroupController.cs b/roles/middleware/files/FWO.Middleware.Server/Controllers/GroupController.cs index aba96d5620..bdf2fbf1d1 100644 --- a/roles/middleware/files/FWO.Middleware.Server/Controllers/GroupController.cs +++ b/roles/middleware/files/FWO.Middleware.Server/Controllers/GroupController.cs @@ -1,11 +1,15 @@ -using FWO.Logging; -using FWO.Middleware.RequestParameters; -using FWO.Middleware.Server; +using FWO.Basics; +using FWO.Data; +using FWO.Data.Middleware; +using FWO.Logging; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; +using Novell.Directory.Ldap; +using System; using System.Collections.Concurrent; +using System.Linq; -namespace FWO.Middleware.Controllers +namespace FWO.Middleware.Server.Controllers { /// /// Controller class for tenant api @@ -17,9 +21,9 @@ public class GroupController : ControllerBase { private readonly List ldaps; - /// - /// Constructor needing ldap list - /// + /// + /// Constructor needing ldap list + /// public GroupController(List ldaps) { this.ldaps = ldaps; @@ -30,22 +34,22 @@ public GroupController(List ldaps) /// /// List of groups [HttpGet] - [Authorize(Roles = "admin, auditor, recertifier")] + [Authorize(Roles = $"{Roles.Admin}, {Roles.Auditor}, {Roles.Recertifier}, {Roles.Modeller}")] public async Task>> Get() { try { - ConcurrentBag allGroups = new ConcurrentBag(); - List ldapGroupRequests = new List(); + ConcurrentBag allGroups = []; + List ldapGroupRequests = []; foreach (Ldap currentLdap in ldaps) { if (currentLdap.IsInternal() && currentLdap.HasGroupHandling()) { - ldapGroupRequests.Add(Task.Run(() => + ldapGroupRequests.Add(Task.Run(async () => { // Get all groups from internal Ldap - List currentGroups = currentLdap.GetAllInternalGroups(); + List currentGroups = await currentLdap.GetAllInternalGroups(); foreach (GroupGetReturnParameters currentGroup in currentGroups) allGroups.Add(currentGroup); })); @@ -73,21 +77,21 @@ public async Task>> Get() /// GroupAddDeleteParameters /// Dn of new group, empty string if no group could be created [HttpPost] - [Authorize(Roles = "admin")] + [Authorize(Roles = $"{Roles.Admin}")] public async Task Create([FromBody] GroupAddDeleteParameters parameters) { string groupDn = ""; - List workers = new List(); + List workers = []; foreach (Ldap currentLdap in ldaps) { // Try to add group to current Ldap if (currentLdap.IsInternal() && currentLdap.IsWritable() && currentLdap.HasGroupHandling()) { - workers.Add(Task.Run(() => + workers.Add(Task.Run(async () => { - string actDn = currentLdap.AddGroup(parameters.GroupName, parameters.OwnerGroup); - if(actDn != "") + string actDn = await currentLdap.AddGroup(parameters.GroupName, parameters.OwnerGroup); + if (actDn != "") { groupDn = actDn; Log.WriteAudit("AddGroup", $"group {parameters.GroupName} successfully added to {currentLdap.Host()}"); @@ -112,20 +116,20 @@ public async Task Create([FromBody] GroupAddDeleteParameters parameters) /// GroupAddDeleteParameters /// true if group deleted [HttpDelete] - [Authorize(Roles = "admin")] + [Authorize(Roles = $"{Roles.Admin}")] public async Task Delete([FromBody] GroupAddDeleteParameters parameters) { bool groupDeleted = false; - List workers = new List(); + List workers = []; foreach (Ldap currentLdap in ldaps) { // Try to delete group in current Ldap if (currentLdap.IsInternal() && currentLdap.IsWritable() && currentLdap.HasGroupHandling()) { - workers.Add(Task.Run(() => + workers.Add(Task.Run(async () => { - if(currentLdap.DeleteGroup(parameters.GroupName)) + if (await currentLdap.DeleteGroup(parameters.GroupName)) { groupDeleted = true; Log.WriteAudit("DeleteGroup", $"Group {parameters.GroupName} deleted from {currentLdap.Host()}"); @@ -150,20 +154,20 @@ public async Task Delete([FromBody] GroupAddDeleteParameters parameters) /// GroupEditParameters /// Dn of updated group [HttpPut] - [Authorize(Roles = "admin")] + [Authorize(Roles = $"{Roles.Admin}")] public async Task Edit([FromBody] GroupEditParameters parameters) { string groupUpdatedDn = ""; - List workers = new List(); + List workers = []; foreach (Ldap currentLdap in ldaps) { // Try to update group in current Ldap if (currentLdap.IsInternal() && currentLdap.IsWritable() && currentLdap.HasGroupHandling()) { - workers.Add(Task.Run(() => + workers.Add(Task.Run(async () => { - string newDn = currentLdap.UpdateGroup(parameters.OldGroupName, parameters.NewGroupName); + string newDn = await currentLdap.UpdateGroup(parameters.OldGroupName, parameters.NewGroupName); if (newDn != "") { groupUpdatedDn = newDn; @@ -188,19 +192,19 @@ public async Task Edit([FromBody] GroupEditParameters parameters) /// GroupGetParameters /// List of groups [HttpPost("Get")] - [Authorize(Roles = "admin, auditor")] + [Authorize(Roles = $"{Roles.Admin}, {Roles.Auditor}")] public async Task> Get([FromBody] GroupGetParameters parameters) { - List allGroups = new List(); + List allGroups = []; foreach (Ldap currentLdap in ldaps) { if ((currentLdap.Id == parameters.LdapId || parameters.LdapId == 0) && currentLdap.HasGroupHandling()) { - await Task.Run(() => + await Task.Run(async () => { // Get all groups from current Ldap - allGroups = currentLdap.GetAllGroups(parameters.SearchPattern); + allGroups = await currentLdap.GetAllGroups(parameters.SearchPattern); }); } } @@ -209,6 +213,226 @@ await Task.Run(() => return allGroups; } + /// + /// Get members of a group by dn if ldap supports group handling + /// + /// GroupMemberGetParameters + /// List of member dns + [HttpPost("Members")] + [Authorize(Roles = $"{Roles.Admin}, {Roles.Auditor}, {Roles.Recertifier}, {Roles.Modeller}")] + public async Task> GetMembers([FromBody] GroupMemberGetParameters parameters) + { + List members = []; + + if (string.IsNullOrWhiteSpace(parameters.GroupDn)) + { + return members; + } + + foreach (Ldap currentLdap in ldaps) + { + if (currentLdap.HasGroupHandling() && !string.IsNullOrWhiteSpace(currentLdap.GroupSearchPath) + && parameters.GroupDn.EndsWith(currentLdap.GroupSearchPath!, StringComparison.OrdinalIgnoreCase)) + { + members = await currentLdap.GetGroupMembers(parameters.GroupDn); + break; + } + } + + return members; + } + + /// + /// Get all group memberships for a user across connected ldaps + /// + /// GroupMembershipGetParameters + /// List of group dns + [HttpPost("Memberships")] + [Authorize(Roles = $"{Roles.Admin}, {Roles.Auditor}, {Roles.Recertifier}, {Roles.Modeller}")] + public async Task> GetMemberships([FromBody] GroupMembershipGetParameters parameters) + { + HashSet memberships = new(StringComparer.OrdinalIgnoreCase); + if (string.IsNullOrWhiteSpace(parameters.UserDn) && string.IsNullOrWhiteSpace(parameters.UserName)) + { + return []; + } + + object membershipsLock = new(); + List ldapRequests = []; + + foreach (Ldap currentLdap in ldaps) + { + string? groupPath = !string.IsNullOrWhiteSpace(currentLdap.GroupSearchPath) + ? currentLdap.GroupSearchPath + : currentLdap.GroupWritePath; + if (!currentLdap.HasGroupHandling() || string.IsNullOrWhiteSpace(groupPath)) + { + continue; + } + + ldapRequests.Add(Task.Run(async () => + { + List currentGroups = await GetMembershipsFromLdap(currentLdap, parameters); + if (currentGroups.Count == 0) + { + return; + } + + lock (membershipsLock) + { + foreach (string groupDn in currentGroups) + { + memberships.Add(groupDn); + } + } + })); + } + + await Task.WhenAll(ldapRequests); + return new List(memberships); + } + + /// + /// Resolve user dns from a list of user or group dns across connected ldaps + /// + /// GroupResolveParameters + /// List of user dns + [HttpPost("Resolve")] + [Authorize(Roles = $"{Roles.Admin}, {Roles.Auditor}, {Roles.Recertifier}, {Roles.Modeller}")] + public async Task> ResolveMembers([FromBody] GroupResolveParameters parameters) + { + if (parameters == null || parameters.Dns.Count == 0) + { + return []; + } + + HashSet resolved = new(StringComparer.OrdinalIgnoreCase); + object resolvedLock = new(); + await ResolveFromLdaps(parameters.Dns, resolved, resolvedLock); + AddDirectDns(parameters.Dns, resolved, GetGroupSearchPaths()); + + return resolved.ToList(); + } + + private async Task ResolveFromLdaps(List dns, HashSet resolved, object resolvedLock) + { + List ldapRequests = []; + + foreach (Ldap currentLdap in ldaps) + { + if (!currentLdap.HasGroupHandling()) + { + continue; + } + + ldapRequests.Add(Task.Run(async () => + { + List currentResolved = await currentLdap.ResolveUsersFromDns(dns); + if (currentResolved.Count == 0) + { + return; + } + + lock (resolvedLock) + { + foreach (string dn in currentResolved) + { + if (!string.IsNullOrWhiteSpace(dn)) + { + resolved.Add(dn); + } + } + } + })); + } + + await Task.WhenAll(ldapRequests); + } + + private List GetGroupSearchPaths() + { + return ldaps + .Where(ldap => ldap.HasGroupHandling() && !string.IsNullOrWhiteSpace(ldap.GroupSearchPath)) + .Select(ldap => ldap.GroupSearchPath!) + .ToList(); + } + + private static void AddDirectDns(List dns, HashSet resolved, List groupSearchPaths) + { + foreach (string dn in dns) + { + if (string.IsNullOrWhiteSpace(dn)) + { + continue; + } + + bool isGroupDn = groupSearchPaths.Any(path => dn.EndsWith(path, StringComparison.OrdinalIgnoreCase)); + if (!isGroupDn) + { + resolved.Add(dn); + } + } + } + + private async Task> GetMembershipsFromLdap(Ldap currentLdap, GroupMembershipGetParameters parameters) + { + List memberships = []; + UiUser userToSearch = new() { Dn = parameters.UserDn, Name = parameters.UserName }; + LdapEntry? ldapUser = null; + + if (!string.IsNullOrWhiteSpace(parameters.UserDn) + && !string.IsNullOrWhiteSpace(currentLdap.UserSearchPath) + && parameters.UserDn.EndsWith(currentLdap.UserSearchPath, StringComparison.OrdinalIgnoreCase)) + { + ldapUser = await currentLdap.GetLdapEntry(userToSearch, false); + } + else if (!string.IsNullOrWhiteSpace(parameters.UserName)) + { + userToSearch.Dn = ""; + ldapUser = await currentLdap.GetLdapEntry(userToSearch, false); + } + + if (ldapUser != null) + { + memberships = currentLdap.GetGroups(ldapUser); + if (memberships.Count == 0) + { + memberships = await GetMembershipsByMemberDn(currentLdap, ldapUser.Dn); + } + } + else if (!string.IsNullOrWhiteSpace(parameters.UserDn)) + { + memberships = await GetMembershipsByMemberDn(currentLdap, parameters.UserDn); + } + + return memberships; + } + + private async Task> GetMembershipsByMemberDn(Ldap currentLdap, string userDn) + { + List memberships = []; + string? groupPath = !string.IsNullOrWhiteSpace(currentLdap.GroupSearchPath) + ? currentLdap.GroupSearchPath + : currentLdap.GroupWritePath; + if (string.IsNullOrWhiteSpace(userDn) || string.IsNullOrWhiteSpace(groupPath)) + { + return memberships; + } + + List groupNames = await currentLdap.GetGroups([userDn]); + foreach (string groupName in groupNames) + { + memberships.Add($"cn={groupName},{groupPath}"); + if (!string.IsNullOrWhiteSpace(currentLdap.GroupSearchPath) + && !string.IsNullOrWhiteSpace(currentLdap.GroupWritePath) + && !currentLdap.GroupSearchPath.Equals(currentLdap.GroupWritePath, StringComparison.OrdinalIgnoreCase)) + { + memberships.Add($"cn={groupName},{currentLdap.GroupWritePath}"); + } + } + return memberships; + } + // GET: GroupController/ /// /// Add user to group @@ -220,20 +444,20 @@ await Task.Run(() => /// GroupAddDeleteUserParameters /// true if user could be added to group [HttpPost("User")] - [Authorize(Roles = "admin")] + [Authorize(Roles = $"{Roles.Admin}")] public async Task AddUser([FromBody] GroupAddDeleteUserParameters parameters) { bool userAdded = false; - List workers = new List(); + List workers = []; foreach (Ldap currentLdap in ldaps) { // Try to add user to group in current Ldap if (currentLdap.IsInternal() && currentLdap.IsWritable() && currentLdap.HasGroupHandling()) { - workers.Add(Task.Run(() => + workers.Add(Task.Run(async () => { - if(currentLdap.AddUserToEntry(parameters.UserDn, parameters.GroupDn)) + if (await currentLdap.AddUserToEntry(parameters.UserDn, parameters.GroupDn)) { userAdded = true; Log.WriteAudit("AddUserToGroup", $"user {parameters.UserDn} successfully added to group {parameters.GroupDn} in {currentLdap.Host()}"); @@ -258,20 +482,20 @@ public async Task AddUser([FromBody] GroupAddDeleteUserParameters paramete /// GroupAddDeleteUserParameters /// true if user could be removed from group [HttpDelete("User")] [HttpDelete("User")] - [Authorize(Roles = "admin")] + [Authorize(Roles = $"{Roles.Admin}")] public async Task RemoveUser([FromBody] GroupAddDeleteUserParameters parameters) { bool userRemoved = false; - List workers = new List(); + List workers = []; foreach (Ldap currentLdap in ldaps) { // Try to remove user from group in current Ldap if (currentLdap.IsInternal() && currentLdap.IsWritable() && currentLdap.HasGroupHandling()) { - workers.Add(Task.Run(() => + workers.Add(Task.Run(async () => { - if(currentLdap.RemoveUserFromEntry(parameters.UserDn, parameters.GroupDn)) + if (await currentLdap.RemoveUserFromEntry(parameters.UserDn, parameters.GroupDn)) { userRemoved = true; Log.WriteAudit("RemoveUserFromGroup", $"Removed user {parameters.UserDn} from {parameters.GroupDn} in {currentLdap.Host()}"); diff --git a/roles/middleware/files/FWO.Middleware.Server/Controllers/NormalizedConfigController.cs b/roles/middleware/files/FWO.Middleware.Server/Controllers/NormalizedConfigController.cs new file mode 100644 index 0000000000..fd3263dbd1 --- /dev/null +++ b/roles/middleware/files/FWO.Middleware.Server/Controllers/NormalizedConfigController.cs @@ -0,0 +1,57 @@ +using FWO.Api.Client; +using FWO.Basics; +using FWO.Config.Api; +using FWO.Config.File; +using FWO.Data; +using FWO.Data.Middleware; +using FWO.Logging; +using FWO.Report; +using Microsoft.AspNetCore.Authorization; +using Microsoft.AspNetCore.Mvc; +using Newtonsoft.Json; +using System.Security.Claims; + +namespace FWO.Middleware.Server.Controllers +{ + /// + /// Controller class for role api + /// + [Authorize] + [ApiController] + [Route("api/[controller]")] + public class NormalizedConfigController(JwtWriter jwtWriter, List ldaps, ApiConnection apiConnection) : ControllerBase + { + private readonly ApiConnection apiConnection = apiConnection; + private readonly JwtWriter jwtWriter = jwtWriter; + private readonly List ldaps = ldaps; + + /// + /// Get NormalizedConfig + /// + /// NormalizedConfigGetParameters + /// NormalizedConfig as json string + [HttpPost("Get")] + [Authorize(Roles = $"{Roles.Admin}, {Roles.Auditor}, {Roles.Reporter}, {Roles.ReporterViewAll}, {Roles.Modeller}, {Roles.Recertifier}, {Roles.Importer}")] + public async Task Get([FromBody] NormalizedConfigGetParameters parameters) + { + try + { + AuthManager authManager = new(jwtWriter, ldaps, apiConnection); + UiUser targetUser = new() { Name = User.FindFirstValue("unique_name") ?? "", Dn = User.FindFirstValue("x-hasura-uuid") ?? "" }; + string jwt = await authManager.AuthorizeUserAsync(targetUser, validatePassword: false); + using ApiConnection apiConnectionUserContext = new GraphQlApiConnection(ConfigFile.ApiServerUri, jwt); + apiConnectionUserContext.SetProperRole(User, [Roles.Admin, Roles.Auditor, Roles.Reporter, Roles.ReporterViewAll, Roles.Modeller, Roles.Recertifier, Roles.Importer]); + + NormalizedConfig normalizedConfig = await NormalizedConfigGenerator.Generate([.. parameters.ManagementIds], parameters.ConfigTime, apiConnectionUserContext); + + return Ok(JsonConvert.SerializeObject(normalizedConfig)); + } + catch (Exception exception) + { + string errorString = $"Error while getting normalized config: {exception.Message}."; + Log.WriteError("Get NormalizedConfig", errorString, exception); + return StatusCode(500, errorString); + } + } + } +} diff --git a/roles/middleware/files/FWO.Middleware.Server/Controllers/ReportController.cs b/roles/middleware/files/FWO.Middleware.Server/Controllers/ReportController.cs new file mode 100644 index 0000000000..4295d682a3 --- /dev/null +++ b/roles/middleware/files/FWO.Middleware.Server/Controllers/ReportController.cs @@ -0,0 +1,190 @@ +using FWO.Api.Client; +using FWO.Api.Client.Queries; +using FWO.Basics; +using FWO.Config.Api; +using FWO.Config.File; +using FWO.Data; +using FWO.Data.Middleware; +using FWO.Data.Report; +using FWO.Logging; +using FWO.Report; +using FWO.Services; +using Microsoft.AspNetCore.Authorization; +using Microsoft.AspNetCore.Mvc; +using System.Security.Claims; + +namespace FWO.Middleware.Server.Controllers +{ + /// + /// Controller class for role api + /// + [Authorize] + [ApiController] + [Route("api/[controller]")] + public class ReportController(JwtWriter jwtWriter, List ldaps, ApiConnection apiConnection) : ControllerBase + { + private readonly ApiConnection apiConnection = apiConnection; + private readonly JwtWriter jwtWriter = jwtWriter; + private readonly List ldaps = ldaps; + + /// + /// Get Report + /// + /// ReportGetParameters + /// Report as json string + [HttpPost("Get")] + [Authorize(Roles = $"{Roles.Admin}, {Roles.Auditor}, {Roles.Reporter}, {Roles.ReporterViewAll}, {Roles.Modeller}, {Roles.Recertifier}")] + public async Task Get([FromBody] ReportGetParameters parameters) + { + try + { + AuthManager authManager = new(jwtWriter, ldaps, apiConnection); + UiUser targetUser = new() { Name = User.FindFirstValue("unique_name") ?? "", Dn = User.FindFirstValue("x-hasura-uuid") ?? "" }; + string jwt = await authManager.AuthorizeUserAsync(targetUser, validatePassword: false); + using ApiConnection apiConnectionUserContext = new GraphQlApiConnection(ConfigFile.ApiServerUri, jwt); + apiConnectionUserContext.SetProperRole(User, [Roles.Admin, Roles.Auditor, Roles.Reporter, Roles.ReporterViewAll, Roles.Modeller, Roles.Recertifier]); + + using GlobalConfig globalConfig = await GlobalConfig.ConstructAsync(jwt); + using UserConfig userConfig = await UserConfig.ConstructAsync(globalConfig, apiConnectionUserContext, targetUser.DbId); + + ReportBase? report = await ReportGenerator.GenerateFromTemplate(await ConvertParameters(parameters), apiConnectionUserContext, userConfig, DefaultInit.DoNothing); + + return report?.ExportToJson() ?? ""; + } + catch (Exception exception) + { + Log.WriteError("Get Report", "Error while getting report.", exception); + } + return ""; + } + + private async Task ConvertParameters(ReportGetParameters reportApiParams) + { + ReportTemplate template = new(); + if (reportApiParams != null) + { + template.ReportParams.ReportType = ConstructReportType(reportApiParams.ApiReportType, reportApiParams.ApiReportView); + template.ReportParams.DeviceFilter = await ConstructDeviceFilter(reportApiParams.ApiDeviceFilter); + template.Filter = await ConstructFilter(reportApiParams.ApiRuleFilter, reportApiParams.Action, reportApiParams.Active); + } + return template; + } + + private static int ConstructReportType(string apiReportType, List apiReportView) + { + return apiReportType.ToLower().Trim() switch + { + "rules" => apiReportView.FirstOrDefault(x => x.ToLower() == "resolved") == null ? 1 : apiReportView.FirstOrDefault(x => x.ToLower() == "technical") == null ? 5 : 6, + "changes" => apiReportView.FirstOrDefault(x => x.ToLower() == "resolved") == null ? 2 : apiReportView.FirstOrDefault(x => x.ToLower() == "technical") == null ? 8 : 9, + "statistics" => 3, + "natrules" => 4, + "recertification" => 7, + "unusedrules" => 10, + "connections" => 21, + "apprules" => 22, + "variance" => 23, + "owners" => 51, + _ => 1, + }; + } + + private async Task ConstructDeviceFilter(ApiDeviceFilter apiDeviceFilter) + { + DeviceFilter deviceFilter = new(); + if (apiDeviceFilter.ManagementIds.Count > 0 || apiDeviceFilter.DeviceIds.Count > 0) + { + try + { + List managements = await apiConnection.SendQueryAsync>(DeviceQueries.getDevicesByManagement); + foreach (ManagementSelect mgt in managements) + { + foreach (DeviceSelect device in mgt.Devices.Where(d => apiDeviceFilter.ManagementIds.Contains(mgt.Id) || apiDeviceFilter.DeviceIds.Contains(d.Id))) + { + mgt.Selected = mgt.Visible; + device.Selected = device.Visible; + } + if (mgt.Selected) + { + deviceFilter.Managements.Add(mgt); + } + } + } + catch (Exception exception) + { + Log.WriteError("Construct Device Filters", $" leads to exception: {exception.Message}"); + } + } + return deviceFilter; + } + + private async Task ConstructFilter(ApiRuleFilter apiRuleFilter, string? action, bool? active) + { + List allAndFilters = []; + List ipOrFilters = apiRuleFilter.SourceIps.ConvertAll(s => "src=" + s); + ipOrFilters.AddRange(apiRuleFilter.DestinationIps.ConvertAll(d => "dst=" + d)); + ipOrFilters.AddRange(apiRuleFilter.Ips.ConvertAll(i => "src=" + i)); + ipOrFilters.AddRange(apiRuleFilter.Ips.ConvertAll(i => "dst=" + i)); + if (ipOrFilters.Count > 0) + { + allAndFilters.Add("(" + string.Join(" or ", ipOrFilters) + ")"); + } + + if (apiRuleFilter.Services.Count > 0) + { + List serviceOrFilters = await ConstructServiceFilters(apiRuleFilter.Services); + if (serviceOrFilters.Count > 0) + { + allAndFilters.Add("(" + string.Join(" or ", serviceOrFilters) + ")"); + } + } + + if (!string.IsNullOrEmpty(action)) + { + allAndFilters.Add($"action={action}"); + } + if (active != null) + { + allAndFilters.Add($"disabled={!active}"); + } + return string.Join(" and ", allAndFilters); + } + + private async Task> ConstructServiceFilters(List apiServices) + { + List serviceOrFilters = []; + try + { + List ipProtos = await apiConnection.SendQueryAsync>(StmQueries.getIpProtocols); + foreach (ApiService service in apiServices) + { + List serviceSubFilters = []; + if (!string.IsNullOrEmpty(service.Name)) + { + serviceSubFilters.Add($"svc={service.Name}"); + } + if (service.Protocol != null) + { + string? protoNameFromId = ipProtos.FirstOrDefault(p => p.Id == service.Protocol)?.Name; + if (!string.IsNullOrEmpty(protoNameFromId)) + { + serviceSubFilters.Add($"protocol={protoNameFromId}"); + } + } + if (service.Port != null) + { + serviceSubFilters.Add($"port={service.Port}"); + } + if (serviceSubFilters.Count > 0) + { + serviceOrFilters.Add(string.Join(" and ", serviceSubFilters)); + } + } + } + catch (Exception exception) + { + Log.WriteError("Construct Service Filters", $" leads to exception: {exception.Message}"); + } + return serviceOrFilters; + } + } +} diff --git a/roles/middleware/files/FWO.Middleware.Server/Controllers/RoleController.cs b/roles/middleware/files/FWO.Middleware.Server/Controllers/RoleController.cs index 39f12a11ce..981489c8fd 100644 --- a/roles/middleware/files/FWO.Middleware.Server/Controllers/RoleController.cs +++ b/roles/middleware/files/FWO.Middleware.Server/Controllers/RoleController.cs @@ -1,11 +1,12 @@ -using FWO.Logging; -using FWO.Middleware.RequestParameters; -using FWO.Middleware.Server; +using FWO.Basics; +using FWO.Data; +using FWO.Data.Middleware; +using FWO.Logging; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; using System.Collections.Concurrent; -namespace FWO.Middleware.Controllers +namespace FWO.Middleware.Server.Controllers { /// /// Controller class for role api @@ -17,9 +18,9 @@ public class RoleController : ControllerBase { private readonly List ldaps; - /// - /// Constructor needing ldap list - /// + /// + /// Constructor needing ldap list + /// public RoleController(List ldaps) { this.ldaps = ldaps; @@ -31,21 +32,21 @@ public RoleController(List ldaps) /// /// List of roles [HttpGet] - [Authorize(Roles = "admin, auditor, fw-admin, requester, approver, planner, implementer, reviewer")] + [Authorize(Roles = $"{Roles.Admin}, {Roles.Auditor}, {Roles.FwAdmin}, {Roles.WorkflowRolesList}")] public async Task> Get() { // No parameters - ConcurrentBag allRoles = new ConcurrentBag(); - ConcurrentBag ldapRoleRequests = new ConcurrentBag(); + ConcurrentBag allRoles = []; + ConcurrentBag ldapRoleRequests = []; foreach (Ldap currentLdap in ldaps) { if (currentLdap.HasRoleHandling()) { - ldapRoleRequests.Add(Task.Run(() => + ldapRoleRequests.Add(Task.Run(async () => { // if current Ldap has roles stored: Get all roles from current Ldap - List currentRoles = currentLdap.GetAllRoles(); + List currentRoles = await currentLdap.GetAllRoles(); foreach (RoleGetReturnParameters role in currentRoles) allRoles.Add(role); })); @@ -55,7 +56,7 @@ public async Task> Get() await Task.WhenAll(ldapRoleRequests); // Return status and result - return allRoles.ToList(); + return [.. allRoles]; } /// @@ -68,20 +69,20 @@ public async Task> Get() /// RoleAddDeleteUserParameters /// true if user could be added to role [HttpPost("User")] - [Authorize(Roles = "admin")] + [Authorize(Roles = $"{Roles.Admin}")] public async Task AddUser([FromBody] RoleAddDeleteUserParameters parameters) { bool userAdded = false; - List ldapRoleRequests = new List(); + List ldapRoleRequests = []; foreach (Ldap currentLdap in ldaps) { // Try to add user to role in current Ldap if (currentLdap.IsWritable() && currentLdap.HasRoleHandling()) { - ldapRoleRequests.Add(Task.Run(() => + ldapRoleRequests.Add(Task.Run(async () => { - if (currentLdap.AddUserToEntry(parameters.UserDn, parameters.Role)) + if (await currentLdap.AddUserToEntry(parameters.UserDn, parameters.Role)) { userAdded = true; Log.WriteAudit("AddUserToRole", $"user {parameters.UserDn} successfully added to role {parameters.Role} in {currentLdap.Host()}"); @@ -106,20 +107,20 @@ public async Task AddUser([FromBody] RoleAddDeleteUserParameters parameter /// RoleAddDeleteUserParameters /// true if user could be removed from role [HttpDelete("User")] - [Authorize(Roles = "admin")] + [Authorize(Roles = $"{Roles.Admin}")] public async Task RemoveUser([FromBody] RoleAddDeleteUserParameters parameters) { bool userRemoved = false; - List ldapRoleRequests = new List(); + List ldapRoleRequests = []; foreach (Ldap currentLdap in ldaps) { // Try to remove user from role in current Ldap if (currentLdap.IsWritable() && currentLdap.HasRoleHandling()) { - ldapRoleRequests.Add(Task.Run(() => + ldapRoleRequests.Add(Task.Run(async () => { - if (currentLdap.RemoveUserFromEntry(parameters.UserDn, parameters.Role)) + if (await currentLdap.RemoveUserFromEntry(parameters.UserDn, parameters.Role)) { userRemoved = true; Log.WriteAudit("RemoveUserFromRole", $"Removed user {parameters.UserDn} from {parameters.Role} in {currentLdap.Host()}"); diff --git a/roles/middleware/files/FWO.Middleware.Server/Controllers/RuleController.cs b/roles/middleware/files/FWO.Middleware.Server/Controllers/RuleController.cs new file mode 100644 index 0000000000..5c83774a8a --- /dev/null +++ b/roles/middleware/files/FWO.Middleware.Server/Controllers/RuleController.cs @@ -0,0 +1,545 @@ +using System.Buffers.Binary; +using System.Net; +using System.Numerics; +using System.Text; +using FWO.Api.Client; +using FWO.Api.Client.Queries; +using FWO.Basics; +using FWO.Basics.Comparer; +using FWO.Config.Api; +using FWO.Data; +using FWO.Logging; +using FWO.Ui.Display; +using Microsoft.AspNetCore.Authorization; +using Microsoft.AspNetCore.Mvc; +using Newtonsoft.Json; + +namespace FWO.Middleware.Server.Controllers; + +/// +/// Provides endpoints for retrieving firewall rules filtered by owner or IP-related criteria. +/// +/// +/// This controller uses the central API connection to expose a filtered rule search meant for administrative overview of existing rules. +/// +[Authorize] +[ApiController] +[Route("api/[controller]")] +public class RuleController(ApiConnection apiConnection) : ControllerBase +{ + private const int OwnerMappingIdCustomField = 2; + + /// + /// Returns firewall rules that match the specified filtering options. + /// + /// + /// Exactly one of OwnerId or IpAddress must be provided in the request query. + /// When OwnerId is set, all rules mapped to the given owner are returned. + /// When IpAddress is set, rules are filtered by IP range using the supplied Filter fields: + /// + /// + /// An containing a on success, + /// or a suitable error result on failure. + /// + [HttpPost("GetRulesByFilter")] + [Authorize(Roles = $"{Roles.Admin}, {Roles.Auditor}")] + public async Task> GetRulesByFilter( + [FromBody] RulesByFilterRequest request) + { + try + { + GlobalConfig globalConfig = await GlobalConfig.ConstructAsync(apiConnection); + UserConfig userConfig = new(globalConfig, apiConnection, new() { Language = GlobalConst.kEnglish }); + + string requestId = HttpContext.Request.Headers["X-Request-Id"].FirstOrDefault() + ?? Guid.NewGuid().ToString(); + + LogSiemEntry(request, requestId); + + List rules; + + if (request.Query.OwnerId is not null) + { + rules = await FetchRulesByOwnerId(request.Query.OwnerId ?? -1, userConfig); + } + else if (!string.IsNullOrWhiteSpace(request.Query.IpAddress)) + { + if (!IPAddress.TryParse(request.Query.IpAddress, out IPAddress? ipAddress)) + { + return BadRequest( + "The IPAddress must be a valid IPv4 address."); + } + + RuleFilter queryFilter = request.Query.Filter ?? new RuleFilter(); + if (string.IsNullOrEmpty(queryFilter.Action)) + { + return BadRequest( + "The field Action must be filled with either \"accept\", \"deny\" or \"any\"."); + } + + if (queryFilter.MinPrefixLength < 0 || queryFilter.MinPrefixLength > 32) + { + return BadRequest( + $"The value for MinPrefixLength {queryFilter.MinPrefixLength} must be between 0 and 32."); + } + + if (string.IsNullOrEmpty(queryFilter.InField)) + { + return BadRequest( + $"The field InField must be filled with either \"{FilterFields.Source}\", \"{FilterFields.Destination}\" or \"{FilterFields.Both}\"."); + } + + rules = await FilterRules( + ipAddress, + queryFilter.Action, + queryFilter.MinPrefixLength, + queryFilter.InField, + userConfig + ); + } + else + { + return BadRequest("Either OwnerId or IpAddress must be provided."); + } + + var response = new RulesByFilterResponse + { + Request_Id = requestId, + Result = new RuleResult + { + Count = rules.Count, + Rules = rules + } + }; + + return Ok(response); + } + catch (Exception exception) + { + Log.WriteError("Get Rules By Filter", "Error while fetching rules.", exception); + return StatusCode(500, "Internal server error"); + } + } + + private void LogSiemEntry(RulesByFilterRequest request, string requestId) + { + var info = $"DateTime: {DateTime.UtcNow:O}, " + + $"RequestId: {requestId}, " + + $"UserID: {request.RequestContext.UserID}, " + + $"UserName: {request.RequestContext.UserName}, "; + if (request.Query.OwnerId is not null) + { + info += $"OwnerId: {request.Query.OwnerId}"; + } + else if (request.Query.IpAddress is not null && request.Query.Filter is not null) + { + info += $"IpAddress: {request.Query.IpAddress}" + + "Filter: {" + + $"MinPrefixLength: {request.Query.Filter.MinPrefixLength}" + + $"InField: {request.Query.Filter.InField}" + + $"Action: {request.Query.Filter.Action}" + + "}"; + } + + Log.WriteInfo("Log type: portal-application", info); + } + + private async Task> FetchRulesByOwnerId(int ownerId, + UserConfig userConfig) + { + var ruleIDs = await GetRuleIdsByOwnerId(ownerId); + return await GetRulesByIdsAsync(ruleIDs, userConfig); + } + + private async Task> GetRulesByIdsAsync(List ruleIds, UserConfig userConfig) + { + if (ruleIds.Count == 0) + return new List(); + + var query = RuleQueries.getRuleDetailsById; + + var variables = new + { + rule_ids = ruleIds + }; + + var result = await apiConnection.SendQueryAsync>(query, variables); + return ConvertRuleList(result, userConfig); + } + + private async Task> GetRuleIdsByOwnerId(int ownerId) + { + var query = RuleQueries.getRuleIdsByRuleOwner; + + var variables = new + { + ownerId, + owner_mapping_source = OwnerMappingIdCustomField + }; + + var result = await apiConnection.SendQueryAsync>(query, variables); + + return result + .Select(r => r.RuleId) + .ToList(); + } + + private async Task> FilterRules(IPAddress ipAddress, string action, int minPrefix, + string inField, UserConfig userConfig) + { + IpFilterHelper ipHelper = new IpFilterHelper(); + + var query = RuleQueries.getRuleDetailsById; + string? ruleAction = SanitizeRuleAction(action); + var variables = new { rule_action = ruleAction }; + + var result = await apiConnection.SendQueryAsync>(query, variables); + List ruleItems = []; + + foreach (var rule in result) + { + var sourceObjects = FlattenRuleNetworkObjects( + rule.Froms.Select(source => source.Object).ToList()); + var destObjects = FlattenRuleNetworkObjects( + rule.Tos.Select(dest => dest.Object).ToList()); + + bool isInRange = inField switch + { + FilterFields.Source => ipHelper.IsInRange(ipAddress, minPrefix, sourceObjects), + FilterFields.Destination => ipHelper.IsInRange(ipAddress, minPrefix, destObjects), + FilterFields.Both => ipHelper.IsInRange(ipAddress, minPrefix, sourceObjects) || + ipHelper.IsInRange(ipAddress, minPrefix, destObjects), + _ => throw new ArgumentException($"Invalid InField: {inField}") + }; + + if (isInRange) + { + ruleItems.Add(rule); + } + } + + return ConvertRuleList(ruleItems, userConfig); + } + + private static List ConvertRuleList(List inputList, UserConfig userConfig) + { + const string notFound = "Not Found in Database"; + + return inputList.Select(item => new RuleDetail + { + Uid = item.Uid ?? notFound, + Manager = item.MgmtId.ToString(), + Source = FlattenRuleNetworkObjects(item.Froms.Select(r => r.Object).ToList()) + .Select(s => new NetworkObjectCopy + { + Name = s.Name, + Type = s.Type.Name, + Ip = DisplayBase.DisplayIp(s.IP, s.IpEnd) + }) + .ToList(), + SourceShort = DisplaySourceOrDestinationPlain(item, isSource: true, userConfig), + Destination = FlattenRuleNetworkObjects(item.Tos.Select(r => r.Object).ToList()) + .Select(d => new NetworkObjectCopy + { + Name = d.Name, + Type = d.Type.Name, + Ip = DisplayBase.DisplayIp(d.IP, d.IpEnd) + }) + .ToList(), + DestinationShort = DisplaySourceOrDestinationPlain(item, isSource: false, userConfig), + Service = item.Services + .Select(s => new ServiceObject + { + Name = s.Content.Name, + Protocol = s.Content.Protocol?.Name ?? notFound, + Port = s.Content.SourcePort ?? -1 + }) + .ToList(), + ServiceShort = DisplayServicesPlain(item, userConfig), + ChangeID = CustomFieldResolver.ExtractCustomFieldValue(item, userConfig.GlobalConfig?.CustomFieldChangeIdKey ?? "", out _) ?? notFound, + Name = item.Name ?? notFound, + CreationDate = item.CreatedImport?.StartTime?.ToString() ?? notFound, + LastHitDate = item.Metadata.LastHit?.ToString() ?? notFound, + Action = item.Action, + AdoIT = item.RuleOwner.FirstOrDefault()?.OwnerId.ToString() ?? notFound, + Comment = item.Comment ?? notFound, + Time = item.RuleTimes.Where(ruleTimeObject => ruleTimeObject.TimeObj is not null).Select(ruleTimeObject => ruleTimeObject.TimeObj!.Name).ToList() + }).ToList(); + } + + private static string DisplaySourceOrDestinationPlain(Rule rule, bool isSource, UserConfig userConfig) + { + var result = new StringBuilder(); + + if ((isSource && rule.SourceNegated) || (!isSource && rule.DestinationNegated)) + { + result.AppendLine(userConfig.GetText("negated")); + } + + var networkLocations = isSource ? rule.Froms : rule.Tos; + + string joined = string.Join(Environment.NewLine, + Array.ConvertAll(networkLocations, NetworkLocationToPlainText)); + + result.Append(joined); + + return result.ToString(); + } + + private static string NetworkLocationToPlainText(NetworkLocation networkLocation) + { + string userOutput = networkLocation.User?.Name ?? string.Empty; + + string objectOutput = networkLocation.Object?.Name ?? string.Empty; + + + string nwLocation = DisplayNetworkLocationPlain( + networkLocation, + userOutput, + objectOutput).ToString(); + + return nwLocation; + } + + private static StringBuilder DisplayNetworkLocationPlain(NetworkLocation userNetworkObject, string userName, + string objName) + { + var result = new StringBuilder(); + + if (userNetworkObject.User?.Id > 0) + { + result.Append($"{userName}@"); + } + + result.Append(objName); + + if (userNetworkObject.Object.Type.Name != ObjectType.Group) + { + bool showIpInBrackets = true; + + result.Append( + NwObjDisplay.DisplayIp( + userNetworkObject.Object.IP, + userNetworkObject.Object.IpEnd, + userNetworkObject.Object.Type.Name, + showIpInBrackets)); + } + + return result; + } + + private static string DisplayServicesPlain(Rule rule, UserConfig userConfig) + { + StringBuilder result = new(); + if (rule.ServiceNegated) + { + result.AppendLine(userConfig.GetText("negated") + "
                      "); + } + + string joined = string.Join(Environment.NewLine, + Array.ConvertAll(rule.Services, + service => DisplayBase.DisplayService(service.Content, false, service.Content.Name).ToString())); + result.Append(joined); + + return result.ToString(); + } + + private static List FlattenRuleNetworkObjects(List list) + { + return list + .SelectMany(obj => + new[] { obj } + .Concat(obj.ObjectGroupFlats + .Select(g => g.Object) + ) + ).OfType().ToList(); + } + + private static string? SanitizeRuleAction(string action) + { + string? ruleAction = null; + switch (action) + { + case RuleActions.Accept: + case RuleActions.Deny: + ruleAction = action; + break; + case RuleActions.Any: + default: break; + } + + return ruleAction; + } + + private static class FilterFields + { + public const string Source = "source"; + public const string Destination = "destination"; + public const string Both = "both"; + } +} + +#pragma warning disable CS1591 +public sealed class IpFilterHelper +{ + private readonly Dictionary _parseCache = new(); + + public bool IsInRange(IPAddress ipAddress, int minPrefix, List objects) + { + var cleanedObjects = objects.Where(obj => obj.Type.Name != "group"); + + foreach (var ipObject in cleanedObjects) + { + var start = ParseAndCache(ipObject.IP); + var end = ParseAndCache(ipObject.IpEnd); + + if (start is null) + { + continue; + } + + int rangePrefix = CommonPrefixLength(start, end); + + if (rangePrefix < minPrefix) + { + break; + } + + if (IsInRange(ipAddress, start, end)) + { + return true; + } + + } + + return false; + } + + private IPAddress? ParseAndCache(string? ipString) + { + if (string.IsNullOrWhiteSpace(ipString)) return null; + + var sanitized = SanitizeIpString(ipString); + if (_parseCache.TryGetValue(sanitized, out var cached)) + return cached; + + IPAddress.TryParse(sanitized, out var parsed); + _parseCache[sanitized] = parsed; + + return parsed; + } + + private static string SanitizeIpString(string? ipString) + { + if (string.IsNullOrWhiteSpace(ipString)) return string.Empty; + + var trimmed = ipString.AsSpan().Trim(); + var slashIndex = trimmed.IndexOf('/'); + + return (slashIndex >= 0 ? trimmed[..slashIndex] : trimmed).Trim().ToString(); + } + + private static bool IsInRange(IPAddress ip, IPAddress? startIp, IPAddress? endIp) + { + if (startIp is null) return false; + if (endIp is null) return startIp.Equals(ip); + + var comparer = new IPAdressComparer(); + if (comparer.Compare(startIp, endIp) > 0) + (startIp, endIp) = (endIp, startIp); + + return comparer.Compare(startIp, ip) <= 0 && + comparer.Compare(endIp, ip) >= 0; + } + + private static int CommonPrefixLength(IPAddress? ipA, IPAddress? ipB) + { + if (ipA is null) return -1; + if (ipB is null) return 32; + + uint a = BinaryPrimitives.ReadUInt32BigEndian(ipA.GetAddressBytes()); + uint b = BinaryPrimitives.ReadUInt32BigEndian(ipB.GetAddressBytes()); + uint diff = a ^ b; + + return diff == 0 ? 32 : BitOperations.LeadingZeroCount(diff); + } +} + +public class RulesByFilterRequest +{ + public RequestContext RequestContext { get; set; } = new(); + public RulesByFilterQuery Query { get; set; } = new(); +} + +public class RulesByFilterQuery +{ + public int? OwnerId { get; set; } + public string? IpAddress { get; set; } + + public RuleFilter? Filter { get; set; } +} + +public class RulesByFilterResponse +{ + public string Request_Id { get; set; } = ""; + public RuleResult Result { get; set; } = new(); +} + +public class RuleFilter +{ + public int MinPrefixLength { get; set; } + public string InField { get; set; } = ""; + public string Action { get; set; } = ""; +} + +public class RuleResult +{ + public int Count { get; set; } + public List Rules { get; set; } = new(); +} + +public class RuleDetail +{ + public string Uid { get; set; } = ""; + public string Manager { get; set; } = ""; + public List Source { get; set; } = new(); + public string SourceShort { get; set; } = ""; + public List Destination { get; set; } = new(); + public string DestinationShort { get; set; } = ""; + public List Service { get; set; } = new(); + public string ServiceShort { get; set; } = ""; + public string ChangeID { get; set; } = ""; + public string AdoIT { get; set; } = ""; + public string Name { get; set; } = ""; + public List Time { get; set; } = []; + public string Comment { get; set; } = ""; + public string CreationDate { get; set; } = ""; + public string LastHitDate { get; set; } = ""; + public string Action { get; set; } = ""; +} + +public class NetworkObjectCopy +{ + public string Name { get; set; } = ""; + public string? Ip { get; set; } = ""; + public string? Type { get; set; } = ""; +} + +public class ServiceObject +{ + public string Name { get; set; } = ""; + public string Protocol { get; set; } = ""; + public int Port { get; set; } +} + +public class RequestContext +{ + public string UserName { get; set; } = ""; + public string UserID { get; set; } = ""; +} + +public class RuleOwnerItem +{ + [JsonProperty("rule_id")] public int RuleId { get; set; } +} +#pragma warning restore CS1591 diff --git a/roles/middleware/files/FWO.Middleware.Server/Controllers/SchedulerController.cs b/roles/middleware/files/FWO.Middleware.Server/Controllers/SchedulerController.cs new file mode 100644 index 0000000000..345ca0008d --- /dev/null +++ b/roles/middleware/files/FWO.Middleware.Server/Controllers/SchedulerController.cs @@ -0,0 +1,155 @@ +using FWO.Basics; +using FWO.Data; +using FWO.Data.Middleware; +using FWO.Logging; +using FWO.Middleware.Server.Services; +using Microsoft.AspNetCore.Authorization; +using Microsoft.AspNetCore.Mvc; +using Quartz; +using Quartz.Impl.Matchers; + +namespace FWO.Middleware.Server.Controllers +{ + /// Controller exposing Quartz jobs for manual triggering. + [Authorize] + [ApiController] + [Route("api/[controller]")] + public class SchedulerController : ControllerBase + { + private readonly ISchedulerFactory schedulerFactory; + private readonly JobExecutionTracker executionTracker; + + /// + /// Initializes a new instance of the SchedulerController class. + /// + /// The scheduler factory for accessing Quartz jobs. + /// The tracker for job execution results. + public SchedulerController(ISchedulerFactory schedulerFactory, JobExecutionTracker executionTracker) + { + this.schedulerFactory = schedulerFactory; + this.executionTracker = executionTracker; + } + + /// + /// Retrieves information about all scheduled jobs. + /// + /// A collection of scheduler job information. + [HttpGet] + [Authorize(Roles = $"{Roles.Admin}")] + public async Task> GetJobs() + { + IScheduler scheduler = await schedulerFactory.GetScheduler(); + IReadOnlyCollection jobKeys = await scheduler.GetJobKeys(GroupMatcher.AnyGroup()); + + List jobs = []; + foreach (JobKey jobKey in jobKeys.OrderBy(jk => jk.Name)) + { + IReadOnlyCollection triggers = await scheduler.GetTriggersOfJob(jobKey); + DateTimeOffset? nextFire = triggers + .Select(trigger => trigger.GetNextFireTimeUtc()) + .Where(fireTime => fireTime.HasValue) + .Select(fireTime => (DateTimeOffset?)fireTime!.Value) + .OrderBy(fireTime => fireTime) + .FirstOrDefault(); + + DateTimeOffset? lastFire = triggers + .Select(trigger => trigger.GetPreviousFireTimeUtc()) + .Where(fireTime => fireTime.HasValue) + .Select(fireTime => (DateTimeOffset?)fireTime!.Value) + .OrderByDescending(fireTime => fireTime) + .FirstOrDefault(); + + string intervalDescription = DescribeTriggers(triggers); + + JobExecutionResult? lastResult = executionTracker.GetLastResult(jobKey.Name); + + DateTimeOffset? actualLastFire = lastResult?.ExecutedAt ?? lastFire; + + SchedulerJobExecutionStatus jobExecutionStatus = new(); + string jobError = ""; + + if (lastResult is not null) + { + jobExecutionStatus = lastResult.Success ? SchedulerJobExecutionStatus.Success : SchedulerJobExecutionStatus.Failed; + jobError = lastResult.ErrorMessage; + } + + jobs.Add(new SchedulerJobInfo + { + JobName = jobKey.Name, + Group = jobKey.Group, + NextFireTimeUtc = nextFire, + LastFireTimeUtc = actualLastFire, + IntervalDescription = intervalDescription, + LastExecutionStatus = jobExecutionStatus, + LastExecutionError = jobError + }); + } + + return jobs; + } + + /// + /// Manually triggers a scheduled job. + /// + /// The parameters specifying which job to run. + /// True if the job was triggered successfully; otherwise, an error response. + [HttpPost("Run")] + [Authorize(Roles = $"{Roles.Admin}")] + public async Task> Run([FromBody] SchedulerJobTriggerParameters parameters) + { + if (string.IsNullOrWhiteSpace(parameters.JobName)) + { + return BadRequest("Job name missing."); + } + + IScheduler scheduler = await schedulerFactory.GetScheduler(); + JobKey jobKey = new(parameters.JobName); + + if (!await scheduler.CheckExists(jobKey)) + { + return NotFound("Job not found."); + } + + await scheduler.TriggerJob(jobKey); + + Log.WriteAudit("Scheduler", $"Manual trigger for {jobKey.Name}."); + return true; + } + + private static string DescribeTriggers(IEnumerable triggers) + { + foreach (ITrigger trigger in triggers) + { + if (trigger is ISimpleTrigger simple && simple.RepeatInterval > TimeSpan.Zero) + { + return FormatInterval(simple.RepeatInterval); + } + + if (trigger is ICronTrigger cron) + { + return cron.CronExpressionString ?? ""; + } + } + + return ""; + } + + private static string FormatInterval(TimeSpan interval) + { + if (interval.TotalDays >= 1) + { + return $"{interval.TotalDays:g}d"; + } + if (interval.TotalHours >= 1) + { + return $"{interval.TotalHours:g}h"; + } + if (interval.TotalMinutes >= 1) + { + return $"{interval.TotalMinutes:g}m"; + } + return $"{interval.TotalSeconds:g}s"; + } + } +} diff --git a/roles/middleware/files/FWO.Middleware.Server/Controllers/TenantController.cs b/roles/middleware/files/FWO.Middleware.Server/Controllers/TenantController.cs index fe174624c0..70c776c8c8 100644 --- a/roles/middleware/files/FWO.Middleware.Server/Controllers/TenantController.cs +++ b/roles/middleware/files/FWO.Middleware.Server/Controllers/TenantController.cs @@ -1,14 +1,15 @@ -using FWO.Api.Data; using FWO.Api.Client; +using FWO.Api.Client.Queries; +using FWO.Basics; +using FWO.Data; +using FWO.Data.Middleware; using FWO.Logging; -using FWO.Middleware.RequestParameters; -using FWO.Middleware.Server; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; // For more information on enabling Web API for empty projects, visit https://go.microsoft.com/fwlink/?LinkID=397860 -namespace FWO.Middleware.Controllers +namespace FWO.Middleware.Server.Controllers { /// /// Controller class for tenant api @@ -20,9 +21,9 @@ public class TenantController : ControllerBase private readonly List ldaps; private readonly ApiConnection apiConnection; - /// - /// Constructor needing ldap list and connection - /// + /// + /// Constructor needing ldap list and connection + /// public TenantController(List ldaps, ApiConnection apiConnection) { this.ldaps = ldaps; @@ -35,11 +36,11 @@ public TenantController(List ldaps, ApiConnection apiConnection) /// /// List of tenants [HttpGet] - [Authorize(Roles = "admin, auditor")] + [Authorize(Roles = $"{Roles.Admin}, {Roles.Auditor}, {Roles.FwAdmin}")] public async Task> Get() { - Tenant[] tenants = (await apiConnection.SendQueryAsync(FWO.Api.Client.Queries.AuthQueries.getTenants)); - List tenantList = new List(); + Tenant[] tenants = await apiConnection.SendQueryAsync(AuthQueries.getTenants); + List tenantList = []; foreach (Tenant tenant in tenants) { tenantList.Add(tenant.ToApiParams()); @@ -60,7 +61,7 @@ public async Task> Get() /// TenantAddParameters /// Id of new tenant, 0 if no tenant could be created [HttpPost] - [Authorize(Roles = "admin")] + [Authorize(Roles = $"{Roles.Admin}")] public async Task Post([FromBody] TenantAddParameters tenant) { bool tenantAdded = false; @@ -72,9 +73,9 @@ public async Task Post([FromBody] TenantAddParameters tenant) // Try to add tenant in current Ldap if (currentLdap.IsInternal() && currentLdap.IsWritable()) { - await Task.Run(() => + await Task.Run(async () => { - if (currentLdap.AddTenant(tenantName)) + if (await currentLdap.AddTenant(tenantName)) { tenantAdded = true; Log.WriteAudit("AddTenant", $"Tenant {tenantName} successfully added to {currentLdap.Host()}"); @@ -83,21 +84,20 @@ await Task.Run(() => } } - if (tenantAdded) + if (tenantAdded) { // Add also to local database table try { - var Variables = new - { + var Variables = new + { name = tenant.Name, project = tenant.Project, comment = tenant.Comment, viewAllDevices = tenant.ViewAllDevices, - // superAdmin = tenant.Superadmin, create = DateTime.Now }; - ReturnId[]? returnIds = (await apiConnection.SendQueryAsync(FWO.Api.Client.Queries.AuthQueries.addTenant, Variables)).ReturnIds; + ReturnId[]? returnIds = (await apiConnection.SendQueryAsync(AuthQueries.addTenant, Variables)).ReturnIds; if (returnIds != null) { tenantId = returnIds[0].NewId; @@ -128,7 +128,7 @@ await Task.Run(() => /// TenantEditParameters /// true if updated [HttpPut] - [Authorize(Roles = "admin")] + [Authorize(Roles = $"{Roles.Admin}, {Roles.FwAdmin}")] public async Task Change([FromBody] TenantEditParameters parameters) { bool tenantUpdated = false; @@ -143,7 +143,7 @@ public async Task Change([FromBody] TenantEditParameters parameters) comment = parameters.Comment, viewAllDevices = parameters.ViewAllDevices }; - ReturnId returnId = await apiConnection.SendQueryAsync(FWO.Api.Client.Queries.AuthQueries.updateTenant, Variables); + ReturnId returnId = await apiConnection.SendQueryAsync(AuthQueries.updateTenant, Variables); if (returnId.UpdatedId == parameters.Id) { tenantUpdated = true; @@ -168,7 +168,7 @@ public async Task Change([FromBody] TenantEditParameters parameters) /// TenantDeleteParameters /// true if tenant deleted [HttpDelete] - [Authorize(Roles = "admin")] + [Authorize(Roles = $"{Roles.Admin}")] public async Task Delete([FromBody] TenantDeleteParameters tenant) { bool tenantDeleted = false; @@ -178,9 +178,9 @@ public async Task Delete([FromBody] TenantDeleteParameters tenant) // Try to delete tenant in current Ldap if (currentLdap.IsInternal() && currentLdap.IsWritable()) { - await Task.Run(() => + await Task.Run(async () => { - if(currentLdap.DeleteTenant(tenant.Name)) + if (await currentLdap.DeleteTenant(tenant.Name)) { Log.WriteAudit("DeleteTenant", $"Tenant {tenant.Name} deleted from {currentLdap.Host()}"); } @@ -192,7 +192,7 @@ await Task.Run(() => { // Delete also from local database table var Variables = new { id = tenant.Id }; - int delId = (await apiConnection.SendQueryAsync(FWO.Api.Client.Queries.AuthQueries.deleteTenant, Variables)).DeletedId; + int delId = (await apiConnection.SendQueryAsync(AuthQueries.deleteTenant, Variables)).DeletedId; if (delId == tenant.Id) { tenantDeleted = true; diff --git a/roles/middleware/files/FWO.Middleware.Server/Controllers/UserController.cs b/roles/middleware/files/FWO.Middleware.Server/Controllers/UserController.cs index 5344c0f861..281b85a806 100644 --- a/roles/middleware/files/FWO.Middleware.Server/Controllers/UserController.cs +++ b/roles/middleware/files/FWO.Middleware.Server/Controllers/UserController.cs @@ -1,17 +1,17 @@ -using FWO.Api.Data; using FWO.Api.Client; using FWO.Api.Client.Queries; +using FWO.Basics; +using FWO.Data; +using FWO.Data.Middleware; using FWO.Logging; -using FWO.Middleware.RequestParameters; -using FWO.Middleware.Server; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; -namespace FWO.Middleware.Controllers +namespace FWO.Middleware.Server.Controllers { /// - /// Controller class for user api - /// + /// Controller class for user api + ///
                      //[Authorize] [ApiController] @@ -20,10 +20,11 @@ public class UserController : ControllerBase { private readonly List ldaps; private readonly ApiConnection apiConnection; + private readonly string WrongUserId = "Wrong UserId"; - /// - /// Constructor needing ldap list and connection - /// + /// + /// Constructor needing ldap list and connection + /// public UserController(List ldaps, ApiConnection apiConnection) { this.ldaps = ldaps; @@ -36,11 +37,11 @@ public UserController(List ldaps, ApiConnection apiConnection) ///
                      /// List of all locally known users [HttpGet] - [Authorize(Roles = "admin, auditor")] + [Authorize(Roles = $"{Roles.Admin}, {Roles.Auditor}")] public async Task> Get() { - List users = (await apiConnection.SendQueryAsync(FWO.Api.Client.Queries.AuthQueries.getUsers)).ToList(); - List userList = new List(); + List users = (await apiConnection.SendQueryAsync(AuthQueries.getUsers)).ToList(); + List userList = []; foreach (UiUser user in users) { if (user.DbId != 0) @@ -62,19 +63,19 @@ public async Task> Get() /// LdapUserGetParameters /// List of users [HttpPost("Get")] - [Authorize(Roles = "admin, auditor")] + [Authorize(Roles = $"{Roles.Admin}, {Roles.Auditor}")] public async Task> Get([FromBody] LdapUserGetParameters parameters) { - List allUsers = new List(); + List allUsers = []; foreach (Ldap currentLdap in ldaps) { if (currentLdap.Id == parameters.LdapId) { - await Task.Run(() => + await Task.Run(async () => { // Get all users from current Ldap - allUsers = currentLdap.GetAllUsers(parameters.SearchPattern); + allUsers = await currentLdap.GetAllUsers(parameters.SearchPattern); }); } } @@ -98,7 +99,7 @@ await Task.Run(() => /// UserAddParameters /// Id of new user, 0 if no user could be created [HttpPost] - [Authorize(Roles = "admin")] + [Authorize(Roles = $"{Roles.Admin}")] public async Task Add([FromBody] UserAddParameters parameters) { string email = parameters.Email ?? ""; @@ -111,9 +112,9 @@ public async Task Add([FromBody] UserAddParameters parameters) // Try to add user to current Ldap if ((currentLdap.Id == parameters.LdapId || parameters.LdapId == 0) && currentLdap.IsWritable()) { - await Task.Run(() => + await Task.Run(async () => { - if(currentLdap.AddUser(parameters.UserDn, parameters.Password, email)) + if (await currentLdap.AddUser(parameters.UserDn, parameters.Password, email)) { userAdded = true; Log.WriteAudit("AddUser", $"user {parameters.UserDn} successfully added to Ldap Id: {parameters.LdapId} Name: {currentLdap.Host()}"); @@ -121,7 +122,7 @@ await Task.Run(() => }); } } - if(userAdded) + if (userAdded) { // Try to add user to local db try @@ -129,14 +130,16 @@ await Task.Run(() => var Variables = new { uuid = parameters.UserDn, - uiuser_username = (new FWO.Api.Data.DistName(parameters.UserDn)).UserName, + uiuser_username = new DistName(parameters.UserDn).UserName, email = email, + uiuser_first_name = parameters.Firstname, + uiuser_last_name = parameters.Lastname, tenant = parameters.TenantId, passwordMustBeChanged = parameters.PwChangeRequired, - ldapConnectionId = (parameters.LdapId != 0 ? parameters.LdapId : (int?)null) + ldapConnectionId = parameters.LdapId != 0 ? parameters.LdapId : (int?)null }; - ReturnId[]? returnIds = (await apiConnection.SendQueryAsync(FWO.Api.Client.Queries.AuthQueries.addUser, Variables)).ReturnIds; - if(returnIds != null) + ReturnId[]? returnIds = (await apiConnection.SendQueryAsync(AuthQueries.upsertUiUser, Variables)).ReturnIds; + if (returnIds != null) { userId = returnIds[0].NewId; } @@ -162,11 +165,11 @@ await Task.Run(() => /// UserEditParameters /// true, if user could be updated [HttpPut] - [Authorize(Roles = "admin")] + [Authorize(Roles = $"{Roles.Admin}")] public async Task Change([FromBody] UserEditParameters parameters) { string email = parameters.Email ?? ""; - UiUser user = await resolveUser(parameters.UserId) ?? throw new Exception("Wrong UserId"); + UiUser user = await ResolveUser(parameters.UserId) ?? throw new ArgumentException(WrongUserId); bool userUpdated = false; foreach (Ldap currentLdap in ldaps) @@ -174,9 +177,9 @@ public async Task Change([FromBody] UserEditParameters parameters) // Try to update user in current Ldap if ((currentLdap.Id == parameters.LdapId || parameters.LdapId == 0) && currentLdap.IsWritable()) { - await Task.Run(() => + await Task.Run(async () => { - if(currentLdap.UpdateUser(user.Dn, email)) + if (await currentLdap.UpdateUser(user.Dn, email)) { userUpdated = true; Log.WriteAudit("UpdateUser", $"User {user.Dn} updated in Ldap Id: {parameters.LdapId} Name: {currentLdap.Host()}"); @@ -184,7 +187,7 @@ await Task.Run(() => }); } } - if (userUpdated) + if (userUpdated) { // Try to update user in local db try @@ -194,7 +197,7 @@ await Task.Run(() => id = parameters.UserId, email = email }; - await apiConnection.SendQueryAsync(FWO.Api.Client.Queries.AuthQueries.updateUserEmail, Variables); + await apiConnection.SendQueryAsync(AuthQueries.updateUserEmail, Variables); } catch (Exception exception) { @@ -221,10 +224,10 @@ await Task.Run(() => public async Task> ChangePassword([FromBody] UserChangePasswordParameters parameters) { // the demo user (currently auditor) can't change his password - if (User.IsInRole("auditor")) + if (User.IsInRole(Roles.Auditor)) return Unauthorized(); - UiUser user = await resolveUser(parameters.UserId) ?? throw new Exception("Wrong UserId"); + UiUser user = await ResolveUser(parameters.UserId) ?? throw new ArgumentException(WrongUserId); string errorMsg = ""; @@ -233,11 +236,9 @@ public async Task> ChangePassword([FromBody] UserChangePass // if current Ldap is writable: Try to change password in current Ldap if ((currentLdap.Id == parameters.LdapId || parameters.LdapId == 0) && currentLdap.IsWritable()) { - bool passwordMustBeChanged = (await apiConnection.SendQueryAsync(AuthQueries.getUserByDn, new { dn = user.Dn }))[0].PasswordMustBeChanged; - await Task.Run(async () => { - errorMsg = currentLdap.ChangePassword(user.Dn, parameters.OldPassword, parameters.NewPassword); + errorMsg = await currentLdap.ChangePassword(user.Dn, parameters.OldPassword, parameters.NewPassword); if (errorMsg == "") { await UiUserHandler.UpdateUserPasswordChanged(apiConnection, user.Dn); @@ -262,10 +263,10 @@ await Task.Run(async () => /// UserResetPasswordParameters /// error message or Ok [HttpPatch("ResetPassword")] - [Authorize(Roles = "admin")] + [Authorize(Roles = $"{Roles.Admin}")] public async Task> ResetPassword([FromBody] UserResetPasswordParameters parameters) { - UiUser user = await resolveUser(parameters.UserId) ?? throw new Exception("Wrong UserId"); + UiUser user = await ResolveUser(parameters.UserId) ?? throw new ArgumentException(WrongUserId); string errorMsg = ""; foreach (Ldap currentLdap in ldaps) @@ -275,12 +276,12 @@ public async Task> ResetPassword([FromBody] UserResetPasswo { await Task.Run(async () => { - errorMsg = currentLdap.SetPassword(user.Dn, parameters.NewPassword); + errorMsg = await currentLdap.SetPassword(user.Dn, parameters.NewPassword); if (errorMsg == "") { - List roles = currentLdap.GetRoles(new List() { user.Dn }).ToList(); // TODO: Group roles are not included - // the demo user (currently auditor) can't be forced to change password as he is not allowed to do it. Everyone else has to change it though - bool passwordMustBeChanged = !roles.Contains("auditor"); + List roles = [.. await currentLdap.GetRoles([user.Dn])]; // TODO: Group roles are not included + // the demo user (currently auditor) can't be forced to change password as he is not allowed to do it. Everyone else has to change it though + bool passwordMustBeChanged = !roles.Contains(Roles.Auditor); await UiUserHandler.UpdateUserPasswordChanged(apiConnection, user.Dn, passwordMustBeChanged); } }); @@ -301,22 +302,22 @@ await Task.Run(async () => /// UserDeleteAllEntriesParameters /// true if user removed from all entries [HttpDelete("AllGroupsAndRoles")] - [Authorize(Roles = "admin")] + [Authorize(Roles = $"{Roles.Admin}")] public async Task DeleteAllGroupsAndRoles([FromBody] UserDeleteAllEntriesParameters parameters) { - UiUser user = await resolveUser(parameters.UserId) ?? throw new Exception("Wrong UserId"); + UiUser user = await ResolveUser(parameters.UserId) ?? throw new ArgumentException(WrongUserId); bool userRemoved = false; - List ldapRoleRequests = new List(); + List ldapRoleRequests = []; foreach (Ldap currentLdap in ldaps) { // Try to remove user from all roles and groups in current Ldap if (currentLdap.IsWritable() && (currentLdap.HasRoleHandling() || currentLdap.HasGroupHandling())) { - ldapRoleRequests.Add(Task.Run(() => + ldapRoleRequests.Add(Task.Run(async () => { - if (currentLdap.RemoveUserFromAllEntries(user.Dn)) + if (await currentLdap.RemoveUserFromAllEntries(user.Dn)) { userRemoved = true; } @@ -341,10 +342,10 @@ public async Task DeleteAllGroupsAndRoles([FromBody] UserDeleteAllEntriesP /// UserDeleteParameters /// true if user deleted [HttpDelete] - [Authorize(Roles = "admin")] + [Authorize(Roles = $"{Roles.Admin}")] public async Task Delete([FromBody] UserDeleteParameters parameters) { - UiUser user = await resolveUser(parameters.UserId) ?? throw new Exception("Wrong UserId"); + UiUser user = await ResolveUser(parameters.UserId) ?? throw new ArgumentException(WrongUserId); bool userDeleted = false; foreach (Ldap currentLdap in ldaps) @@ -354,9 +355,9 @@ public async Task Delete([FromBody] UserDeleteParameters parameters) { if (currentLdap.IsWritable()) { - await Task.Run(() => + await Task.Run(async () => { - if(currentLdap.DeleteUser(user.Dn)) + if (await currentLdap.DeleteUser(user.Dn)) { userDeleted = true; Log.WriteAudit("DeleteUser", $"User {user.Dn} deleted from Ldap Id: {parameters.LdapId} Name: {currentLdap.Host()}"); @@ -376,7 +377,7 @@ await Task.Run(() => try { var Variables = new { id = user.DbId }; - await apiConnection.SendQueryAsync(FWO.Api.Client.Queries.AuthQueries.deleteUser, Variables); + await apiConnection.SendQueryAsync(AuthQueries.deleteUser, Variables); } catch (Exception exception) { @@ -387,12 +388,12 @@ await Task.Run(() => return userDeleted; } - private async Task resolveUser(int id) + private async Task ResolveUser(int id) { List uiUsers; try { - uiUsers = (await apiConnection.SendQueryAsync(FWO.Api.Client.Queries.AuthQueries.getUsers)).ToList(); + uiUsers = [.. (await apiConnection.SendQueryAsync(AuthQueries.getUsers))]; return uiUsers.FirstOrDefault(x => x.DbId == id); } catch (Exception exception) diff --git a/roles/middleware/files/FWO.Middleware.Server/DailyCheckScheduler.cs b/roles/middleware/files/FWO.Middleware.Server/DailyCheckScheduler.cs deleted file mode 100644 index c1a360f06a..0000000000 --- a/roles/middleware/files/FWO.Middleware.Server/DailyCheckScheduler.cs +++ /dev/null @@ -1,349 +0,0 @@ -using FWO.Api.Client; -using FWO.Api.Client.Queries; -using FWO.Api.Data; -using FWO.Config.Api; -using FWO.Config.Api.Data; -using FWO.Logging; -using System.Timers; -using System.Text.Json; -using FWO.Middleware.RequestParameters; -using FWO.Recert; - -namespace FWO.Middleware.Server -{ - /// - /// Class handling the scheduler for the daily checks - /// - public class DailyCheckScheduler - { - private readonly ApiConnection apiConnection; - private GlobalConfig globalConfig; - private int DailyCheckSleepTime = 86400000; // 24 hours in milliseconds - - private System.Timers.Timer DailyCheckScheduleTimer = new(); - private System.Timers.Timer DailyCheckTimer = new(); - - private List openAlerts = new List(); - - /// - /// Async Constructor needing the connection - /// - public static async Task CreateAsync(ApiConnection apiConnection) - { - GlobalConfig config = await GlobalConfig.ConstructAsync(apiConnection, true); - return new DailyCheckScheduler(apiConnection, config); - } - - private DailyCheckScheduler(ApiConnection apiConnection, GlobalConfig globalConfig) - { - this.apiConnection = apiConnection; - this.globalConfig = globalConfig; - globalConfig.OnChange += GlobalConfig_OnChange; - - startDailyCheckScheduleTimer(); - if(globalConfig.RecRefreshStartup) - { - RefreshRecert(); // no need to wait - } - } - - private void GlobalConfig_OnChange(Config.Api.Config globalConfig, ConfigItem[] _) - { - DailyCheckTimer.Interval = DailyCheckSleepTime; - DailyCheckScheduleTimer.Stop(); - startDailyCheckScheduleTimer(); - } - - private void startDailyCheckScheduleTimer() - { - DateTime? startTime = null; - try - { - startTime = DateTime.Now.Date.Add(globalConfig.DailyCheckStartAt.TimeOfDay); - if(startTime < DateTime.Now) - { - startTime = ((DateTime)startTime).AddDays(1); - } - } - catch (Exception exception) - { - Log.WriteError("DailyCheck scheduler", "Could not calculate start time.", exception); - } - TimeSpan interval = (startTime ?? DateTime.Now.AddMilliseconds(1)) - DateTime.Now; - - DailyCheckScheduleTimer = new(); - DailyCheckScheduleTimer.Elapsed += DailyCheck; - DailyCheckScheduleTimer.Elapsed += StartDailyCheckTimer; - DailyCheckScheduleTimer.Interval = interval.TotalMilliseconds; - DailyCheckScheduleTimer.AutoReset = false; - DailyCheckScheduleTimer.Start(); - Log.WriteDebug("DailyCheck scheduler", "DailyCheckScheduleTimer started."); - } - - private void StartDailyCheckTimer(object? _, ElapsedEventArgs __) - { - DailyCheckTimer.Stop(); - DailyCheckTimer = new(); - DailyCheckTimer.Elapsed += DailyCheck; - DailyCheckTimer.Interval = DailyCheckSleepTime; - DailyCheckTimer.AutoReset = true; - DailyCheckTimer.Start(); - Log.WriteDebug("DailyCheck scheduler", "DailyCheckTimer started."); - } - - private async void DailyCheck(object? _, ElapsedEventArgs __) - { - try - { - openAlerts = await apiConnection.SendQueryAsync>(MonitorQueries.getOpenAlerts); - await CheckDemoData(); - await CheckImports(); - if(globalConfig.RecRefreshDaily) - { - await RefreshRecert(); - } - await CheckRecerts(); - } - catch(Exception exc) - { - Log.WriteError("DailyCheck", $"Ran into exception: ", exc); - await AddDailyCheckLogEntry(2, globalConfig.GetText("daily_checks"), globalConfig.GetText("ran_into_exception") + exc.Message); - await setAlert(GlobalConfig.kDailyCheck, AlertCode.DailyCheckError, globalConfig.GetText("daily_checks"), globalConfig.GetText("ran_into_exception") + exc.Message); - } - } - - private async Task RefreshRecert() - { - Log.WriteDebug("DailyCheck scheduler", "Refresh recert ownerships"); - RecertRefresh recertRefresh = new RecertRefresh(apiConnection); - await recertRefresh.RecalcRecerts(); - } - - private async Task CheckRecerts() - { - if(globalConfig.RecCheckActive) - { - RecertCheck recertCheck = new RecertCheck(apiConnection, globalConfig); - int emailsSent = await recertCheck.CheckRecertifications(); - await AddDailyCheckLogEntry(0, globalConfig.GetText("daily_recert_check"), emailsSent + globalConfig.GetText("emails_sent")); - } - } - - private async Task CheckDemoData() - { - List managements = await apiConnection.SendQueryAsync>(FWO.Api.Client.Queries.DeviceQueries.getManagementsDetails); - bool sampleManagementExisting = false; - foreach (var management in managements) - { - if (management.Name.EndsWith("_demo")) - { - sampleManagementExisting = true; - } - } - - List credentials = await apiConnection.SendQueryAsync>(FWO.Api.Client.Queries.DeviceQueries.getCredentials); - bool sampleCredentialExisting = false; - foreach (var credential in credentials) - { - if (credential.Name.EndsWith("_demo")) - { - sampleCredentialExisting = true; - } - } - - List users = await apiConnection.SendQueryAsync>(FWO.Api.Client.Queries.AuthQueries.getUsers); - bool sampleUserExisting = false; - foreach (var user in users) - { - if (user.Name.EndsWith("_demo")) - { - sampleUserExisting = true; - } - } - - List tenants = await apiConnection.SendQueryAsync>(FWO.Api.Client.Queries.AuthQueries.getTenants); - bool sampleTenantExisting = false; - foreach (var tenant in tenants) - { - if (tenant.Name.EndsWith("_demo")) - { - sampleTenantExisting = true; - } - } - - bool sampleGroupExisting = false; - List connectedLdaps = apiConnection.SendQueryAsync>(AuthQueries.getLdapConnections).Result; - foreach (Ldap currentLdap in connectedLdaps) - { - if (currentLdap.IsInternal() && currentLdap.HasGroupHandling()) - { - List groups = currentLdap.GetAllInternalGroups(); - foreach (var ldapUserGroup in groups) - { - if ((new DistName(ldapUserGroup.GroupDn)).Group.EndsWith("_demo")) - { - sampleGroupExisting = true; - } - } - } - } - - List owners = await apiConnection.SendQueryAsync>(FWO.Api.Client.Queries.OwnerQueries.getOwners); - bool sampleOwnerExisting = false; - foreach (var owner in owners) - { - if (owner.Name.EndsWith("_demo")) - { - sampleOwnerExisting = true; - } - } - - string description = ""; - if(sampleManagementExisting || sampleCredentialExisting || sampleUserExisting || sampleTenantExisting || sampleGroupExisting || sampleOwnerExisting) - { - description = globalConfig.GetText("sample_data_found_in") + (sampleManagementExisting ? globalConfig.GetText("managements") + " " : "") + - (sampleCredentialExisting ? globalConfig.GetText("import_credential") + " " : "") + - (sampleUserExisting ? globalConfig.GetText("users") + " " : "") + - (sampleTenantExisting ? globalConfig.GetText("tenants") + " " : "") + - (sampleGroupExisting ? globalConfig.GetText("groups") + " " : "") + - (sampleOwnerExisting ? globalConfig.GetText("owners") : ""); - await setAlert(GlobalConfig.kDailyCheck, AlertCode.SampleDataExisting, globalConfig.GetText("sample_data"), description); - } - await AddDailyCheckLogEntry((description != "" ? 1 : 0), globalConfig.GetText("daily_sample_data_check"), (description != "" ? description : globalConfig.GetText("no_sample_data_found"))); - } - - private async Task CheckImports() - { - List importStati = await apiConnection.SendQueryAsync>(FWO.Api.Client.Queries.MonitorQueries.getImportStatus); - int importIssues = 0; - object jsonData; - foreach(ImportStatus imp in importStati.Where(x => !x.ImportDisabled)) - { - if (imp.LastIncompleteImport != null && imp.LastIncompleteImport.Length > 0) // import running - { - if (imp.LastIncompleteImport[0].StartTime < DateTime.Now.AddHours(-globalConfig.MaxImportDuration)) // too long - { - jsonData = imp.LastIncompleteImport; - await setAlert(GlobalConfig.kDailyCheck, AlertCode.ImportRunningTooLong, globalConfig.GetText("import"), globalConfig.GetText("E7011"), imp.MgmId, jsonData); - importIssues++; - } - } - else if (imp.LastImport == null || imp.LastImport.Length == 0) // no import at all - { - jsonData = imp; - await setAlert(GlobalConfig.kDailyCheck, AlertCode.NoImport, globalConfig.GetText("import"), globalConfig.GetText("E7012"), imp.MgmId, jsonData); - importIssues++; - } - else if (imp.LastImportAttempt != null && imp.LastImportAttempt < DateTime.Now.AddHours(-globalConfig.MaxImportInterval)) // too long ago (not working for legacy devices as LastImportAttempt is not written) - { - jsonData = imp; - await setAlert(GlobalConfig.kDailyCheck, AlertCode.SuccessfulImportOverdue, globalConfig.GetText("import"), globalConfig.GetText("E7013"), imp.MgmId, jsonData); - importIssues++; - } - } - await AddDailyCheckLogEntry((importIssues != 0 ? 1 : 0), globalConfig.GetText("daily_importer_check"), (importIssues != 0 ? importIssues + globalConfig.GetText("import_issues_found") : globalConfig.GetText("no_import_issues_found"))); - } - - private async Task setAlert(string source, AlertCode alertCode, string title, string description, int? mgmtId = null, object? JsonData = null, int? devId = null) - { - try - { - var Variables = new - { - source = source, - userId = 0, - title = title, - description = description, - mgmId = mgmtId, - devId = devId, - alertCode = (int)alertCode, - jsonData = JsonData, - }; - ReturnId[]? returnIds = (await apiConnection.SendQueryAsync(MonitorQueries.addAlert, Variables)).ReturnIds; - if (returnIds != null) - { - // Acknowledge older alert for same problem - Alert? existingAlert = openAlerts.FirstOrDefault(x => x.AlertCode == alertCode && x.ManagementId == mgmtId); - if(existingAlert != null) - { - await AcknowledgeAlert(existingAlert.Id); - } - } - else - { - Log.WriteError("Write Alert", "Log could not be written to database"); - } - string? mgmtIdString = ""; - if (mgmtId != null) - { - mgmtIdString = mgmtId.ToString(); - } - string? devIdString = ""; - if (devId != null) - { - devIdString = devId.ToString(); - } - string jsonString = ""; - if (JsonData != null) - jsonString = JsonSerializer.Serialize(JsonData); - Log.WriteAlert ($"source: \"{source}\"", - $"userId: \"0\", title: \"{title}\", description: \"{description}\", " + - $"mgmId: \"{mgmtIdString}\", devId: \"{devIdString}\", jsonData: \"{jsonString}\", alertCode: \"{alertCode.ToString()}\""); - } - catch(Exception exc) - { - Log.WriteError("Write Alert", $"Could not write Alert for Daily Check: ", exc); - } - } - - private async Task AcknowledgeAlert(long alertId) - { - try - { - var Variables = new - { - id = alertId, - ackUser = 0, - ackTime = DateTime.Now - }; - await apiConnection.SendQueryAsync(MonitorQueries.acknowledgeAlert, Variables); - } - catch (Exception exception) - { - Log.WriteError("Acknowledge Alert", $"Could not acknowledge alert for Daily Check: ", exception); - } - } - - private async Task AddDailyCheckLogEntry(int severity, string cause, string description) - { - try - { - var Variables = new - { - source = GlobalConfig.kDailyCheck, - discoverUser = 0, - severity = severity, - suspectedCause = cause, - description = description, - mgmId = (int?)null, - devId = (int?)null, - importId = (long?)null, - objectType = (string?)null, - objectName = (string?)null, - objectUid = (string?)null, - ruleUid = (string?)null, - ruleId = (long?)null - }; - ReturnId[]? returnIds = (await apiConnection.SendQueryAsync(MonitorQueries.addLogEntry, Variables)).ReturnIds; - if (returnIds == null) - { - Log.WriteError("Write Log", "Log could not be written to database"); - } - } - catch(Exception exc) - { - Log.WriteError("Write Log", $"Could not write daily check log to db: ", exc); - } - } - } -} diff --git a/roles/middleware/files/FWO.Middleware.Server/DataImportBase.cs b/roles/middleware/files/FWO.Middleware.Server/DataImportBase.cs new file mode 100644 index 0000000000..0107c1ae1e --- /dev/null +++ b/roles/middleware/files/FWO.Middleware.Server/DataImportBase.cs @@ -0,0 +1,258 @@ +using FWO.Api.Client; +using FWO.Api.Client.Queries; +using FWO.Data; +using FWO.Config.Api; +using FWO.Logging; +using System.Diagnostics; +using System.Text; + +namespace FWO.Middleware.Server +{ + /// + /// Class handling the Data Import + /// + public class DataImportBase + { + /// + /// Api Connection + /// + protected readonly ApiConnection apiConnection; + + /// + /// Global Config + /// + protected GlobalConfig globalConfig; + + /// + /// Import File + /// + protected string importFile { get; set; } = ""; + + + /// + /// Constructor for Data Import + /// + public DataImportBase(ApiConnection apiConnection, GlobalConfig globalConfig) + { + this.apiConnection = apiConnection; + this.globalConfig = globalConfig; + } + + /// + /// Read the Import Data File + /// + protected void ReadFile(string filepath) + { + try + { + importFile = File.ReadAllText(filepath).Trim(); + } + catch (Exception) + { + Log.WriteError("Read file", $"File could not be read from {filepath}."); + throw; + } + } + + /// + /// Execute the Data Import Script + /// + protected bool RunImportScript(string importScriptFile, string? scriptArguments = null) + { + try + { + if (File.Exists(importScriptFile)) + { + ProcessStartInfo start = new() + { + FileName = importScriptFile, + UseShellExecute = false, + RedirectStandardOutput = true + }; + AddScriptArguments(start, scriptArguments); + Process? process = Process.Start(start); + StreamReader? reader = process?.StandardOutput; + string? result = reader?.ReadToEnd(); + process?.WaitForExit(); + process?.Close(); + Log.WriteInfo("Run Import Script", $"Executed Import Script {importScriptFile}. Result: {result ?? ""}"); + return true; + } + } + catch (Exception Exception) + { + Log.WriteError("Run Import Script", $"File {importScriptFile} could not be executed.", Exception); + } + return false; + } + + /// + /// Parse a configured command line into discrete process arguments. + /// + protected static void AddScriptArguments(ProcessStartInfo start, string? scriptArguments) + { + foreach (string argument in ParseCommandLineArguments(scriptArguments)) + { + start.ArgumentList.Add(argument); + } + } + + /// + /// Split a command line string while preserving quoted values. + /// + protected static List ParseCommandLineArguments(string? commandLine) + { + List arguments = []; + if (string.IsNullOrWhiteSpace(commandLine)) + { + return arguments; + } + + StringBuilder currentArgument = new(); + bool inQuotes = false; + char quoteCharacter = '\0'; + bool isEscaped = false; + + foreach (char currentCharacter in commandLine) + { + if (TryAppendEscapedCharacter(currentCharacter, currentArgument, ref isEscaped)) + { + continue; + } + + if (TryStartEscapeSequence(currentCharacter, ref isEscaped)) + { + continue; + } + + if (TryHandleQuotedCharacter(currentCharacter, currentArgument, ref inQuotes, quoteCharacter)) + { + continue; + } + + if (TryStartQuotedArgument(currentCharacter, ref inQuotes, ref quoteCharacter)) + { + continue; + } + + if (char.IsWhiteSpace(currentCharacter)) + { + AppendCompletedArgument(arguments, currentArgument); + continue; + } + + currentArgument.Append(currentCharacter); + } + + if (isEscaped) + { + currentArgument.Append('\\'); + } + + AppendCompletedArgument(arguments, currentArgument); + return arguments; + } + + private static bool TryAppendEscapedCharacter( + char currentCharacter, + StringBuilder currentArgument, + ref bool isEscaped) + { + if (!isEscaped) + { + return false; + } + + currentArgument.Append(currentCharacter); + isEscaped = false; + return true; + } + + private static bool TryStartEscapeSequence(char currentCharacter, ref bool isEscaped) + { + if (currentCharacter != '\\') + { + return false; + } + + isEscaped = true; + return true; + } + + private static bool TryHandleQuotedCharacter( + char currentCharacter, + StringBuilder currentArgument, + ref bool inQuotes, + char quoteCharacter) + { + if (!inQuotes) + { + return false; + } + + if (currentCharacter == quoteCharacter) + { + inQuotes = false; + } + else + { + currentArgument.Append(currentCharacter); + } + + return true; + } + + private static bool TryStartQuotedArgument(char currentCharacter, ref bool inQuotes, ref char quoteCharacter) + { + if (currentCharacter != '"' && currentCharacter != '\'') + { + return false; + } + + inQuotes = true; + quoteCharacter = currentCharacter; + return true; + } + + private static void AppendCompletedArgument(List arguments, StringBuilder currentArgument) + { + if (currentArgument.Length > 0) + { + arguments.Add(currentArgument.ToString()); + currentArgument.Clear(); + } + } + + /// + /// Add a log entry + /// + /// + /// + /// + /// + /// + public async Task AddLogEntry(string source, int severity, string level, string description) + { + try + { + var Variables = new + { + user = 0, + source = source, + severity = severity, + suspectedCause = level, + description = description + }; + ReturnId[]? returnIds = (await apiConnection.SendQueryAsync(MonitorQueries.addDataImportLogEntry, Variables)).ReturnIds; + if (returnIds == null) + { + Log.WriteError("Write Log", "Log could not be written to database"); + } + } + catch (Exception exc) + { + Log.WriteError("Write Log", $"Could not write log: ", exc); + } + } + } +} diff --git a/roles/middleware/files/FWO.Middleware.Server/ExternalRequestHandler.cs b/roles/middleware/files/FWO.Middleware.Server/ExternalRequestHandler.cs new file mode 100644 index 0000000000..f9e4427c16 --- /dev/null +++ b/roles/middleware/files/FWO.Middleware.Server/ExternalRequestHandler.cs @@ -0,0 +1,570 @@ +using FWO.Api.Client; +using FWO.Api.Client.Queries; +using FWO.Compliance; +using FWO.Config.Api; +using FWO.Data; +using FWO.Data.Modelling; +using FWO.Data.Workflow; +using FWO.ExternalSystems; +using FWO.ExternalSystems.Tufin.SecureChange; +using FWO.Logging; +using FWO.Services; +using FWO.Services.Modelling; +using FWO.Services.Workflow; +using System.Text.Json; + + +namespace FWO.Middleware.Server +{ + /// + /// Class to execute handling of external requests + /// + public class ExternalRequestHandler : IDisposable + { + private readonly ApiConnection ApiConnection; + private readonly ExtStateHandler? extStateHandler; + private readonly WfHandler wfHandler; + private readonly UserConfig UserConfig; + private bool disposed = false; + private ExternalTicketSystemType extSystemType = ExternalTicketSystemType.Generic; + private ExternalTicketSystem actSystem = new(); + private string actTaskType = ""; + private List ipProtos = []; + private List? ownerGroups = []; + + + /// + /// constructor for object with all data necessary for request handling + /// + public ExternalRequestHandler(UserConfig userConfig, ApiConnection apiConnection) + { + ApiConnection = apiConnection; + UserConfig = userConfig; + extStateHandler = new(apiConnection); + Task.Run(GetInternalGroups).Wait(); + wfHandler = new(userConfig, apiConnection, WorkflowPhases.request, ownerGroups, new ComplianceRequestedRulePolicyChecker(userConfig, apiConnection)); + } + + /// + /// constructor only for unit testing + /// + public ExternalRequestHandler(UserConfig userConfig, ApiConnection apiConnection, List? userGroups) + { + ApiConnection = apiConnection; + UserConfig = userConfig; + extStateHandler = new(apiConnection); + wfHandler = new(userConfig, apiConnection, WorkflowPhases.request, userGroups, new ComplianceRequestedRulePolicyChecker(userConfig, apiConnection)); + } + + /// + /// send the first request from ticket (called by UI via middleware client) + /// may also be a higher task number in case of a reinit + /// + public async Task SendFirstRequest(long ticketId) + { + try + { + WfTicket? intTicket = await InitAndResolve(ticketId); + if (intTicket == null || intTicket.Tasks.Count == 0) + { + return false; + } + int lastFinishedTask = 0; + foreach (WfReqTask? task in intTicket.Tasks.OrderBy(t => t.TaskNumber)) + { + if (task.StateId > wfHandler.StateMatrix(task.TaskType).LowestEndState) + { + lastFinishedTask = task.TaskNumber; + } + } + return await CreateNextRequest(intTicket, lastFinishedTask); + } + catch (Exception exception) + { + Log.WriteError("External Request Creation", $"Runs into exception: ", exception); + return false; + } + } + + /// + /// send the next request from ticket if last is done and not rejected + /// (called by scheduler after state change) + /// + public async Task HandleStateChange(ExternalRequest externalRequest) + { + WfTicket? intTicket = await InitAndResolve(externalRequest.TicketId); + if (intTicket == null) + { + Log.WriteError("External Request Update", $"Ticket not found."); + } + else + { + wfHandler.SetTicketEnv(intTicket); + await UpdateTicket(intTicket, externalRequest); + if (extStateHandler != null && extStateHandler.GetInternalStateId(externalRequest.ExtRequestState) >= wfHandler.ActStateMatrix.LowestEndState) + { + await Acknowledge(externalRequest); + if (externalRequest.ExtRequestState == ExtStates.ExtReqRejected.ToString()) + { + await RejectFollowingTasks(intTicket, externalRequest.TaskNumber); + Log.WriteInfo($"External Request {externalRequest.Id} rejected", $"Reject Following Tasks for internal ticket {intTicket.Id}"); + } + else + { + await CreateNextRequest(intTicket, externalRequest.TaskNumber, externalRequest); + } + } + } + } + + /// + /// patch the external request state (called by admin in UI via middleware client) + /// + public async Task PatchState(ExternalRequest externalRequest) + { + try + { + await UpdateRequestState(externalRequest); + if (externalRequest.ExtRequestState == ExtStates.ExtReqRejected.ToString() || + externalRequest.ExtRequestState == ExtStates.ExtReqDone.ToString()) + { + await HandleStateChange(externalRequest); + } + return true; + } + catch (Exception exception) + { + Log.WriteError("Patch External Request State", $"Runs into exception: ", exception); + return false; + } + } + + private async Task UpdateRequestState(ExternalRequest request) + { + try + { + var Variables = new + { + id = request.Id, + extRequestState = request.ExtRequestState + }; + await ApiConnection.SendQueryAsync(ExtRequestQueries.updateExtRequestProcess, Variables); + } + catch (Exception exception) + { + Log.WriteError("External Request Handler", $"State update failed: ", exception); + } + } + + private async Task InitAndResolve(long ticketId) + { + GetExtSystemFromConfig(); + ipProtos = await ApiConnection.SendQueryAsync>(StmQueries.getIpProtocols); + return await wfHandler.Init() ? await wfHandler.ResolveTicket(ticketId) : null; + } + + private async Task GetInternalGroups() + { + ownerGroups = await MiddlewareServerServices.GetInternalGroups(ApiConnection); + } + + /// + /// get number of last processed request task (public only for unit testing) + /// + /// + /// + /// + public static int GetLastTaskNumber(string extQueryVars, int oldTaskNumber) + { + List? taskNumbers = null; + Dictionary>? extQueryVarDict = JsonSerializer.Deserialize>?>(extQueryVars); + extQueryVarDict?.TryGetValue(ExternalVarKeys.BundledTasks, out taskNumbers); + if (taskNumbers != null && taskNumbers.Count > 0) + { + return taskNumbers[^1]; + } + else + { + return oldTaskNumber; + } + } + + /// + /// create next external request from internal ticket task list (public only for unit testing) + /// + /// + /// + /// + /// + + public async Task CreateNextRequest(WfTicket ticket, int oldTaskNumber, ExternalRequest? oldRequest = null) + { + int lastTaskNumber = UserConfig.ModRolloutBundleTasks && oldRequest != null && oldRequest.ExtQueryVariables != "" ? + GetLastTaskNumber(oldRequest.ExtQueryVariables, oldTaskNumber) : oldTaskNumber; + WfReqTask? nextTask = ticket.Tasks.FirstOrDefault(ta => ta.TaskNumber == lastTaskNumber + 1); + if (nextTask == null) + { + Log.WriteDebug("CreateNextRequest", "No more task found."); + return false; + } + else + { + int waitCycles = GetWaitCycles(nextTask.TaskType, oldRequest); + if (nextTask.TaskType == WfTaskType.access.ToString() || nextTask.TaskType == WfTaskType.rule_modify.ToString() || nextTask.TaskType == WfTaskType.rule_delete.ToString()) + { + List bundledTasks = []; + List handledTasks = [nextTask]; + BundleTasks(ticket, lastTaskNumber, nextTask, bundledTasks, handledTasks); + await CreateExtRequest(ticket, bundledTasks, handledTasks, waitCycles); + } + else + { + await CreateExtRequest(ticket, [nextTask], [nextTask], waitCycles); + } + } + Log.WriteInfo("CreateNextRequest", $"Created Request for ticket {ticket.Id}."); + return true; + } + + private void BundleTasks(WfTicket ticket, int lastTaskNumber, WfReqTask nextTask, List bundledTasks, List handledTasks) + { + int actTaskNumber = lastTaskNumber + 2; + bool taskFound = true; + WfReqTask actBundledTask = nextTask; + while (taskFound && bundledTasks.Count < actSystem.MaxBundledTasks()) + { + WfReqTask? furtherTask = ticket.Tasks.FirstOrDefault(ta => ta.TaskNumber == actTaskNumber); + if (furtherTask != null && furtherTask.TaskType == nextTask.TaskType) + { + taskFound = HandleFurtherTask(furtherTask, nextTask.TaskType, ref actBundledTask, bundledTasks, handledTasks); + actTaskNumber++; + } + else + { + bundledTasks.Add(actBundledTask); + taskFound = false; + } + } + } + + private bool HandleFurtherTask(WfReqTask furtherTask, string actTaskType, ref WfReqTask actBundledTask, List bundledTasks, List handledTasks) + { + if (actSystem.BundleGateways() && actSystem.TaskTypesToBundleGateways().Contains(actTaskType) && IsSameRuleOnDiffGw(actBundledTask, furtherTask)) + { + actBundledTask.Elements.AddRange(furtherTask.GetRuleElements().ConvertAll(e => e.ToReqElement())); + handledTasks.Add(furtherTask); + } + else + { + bundledTasks.Add(actBundledTask); + if (UserConfig.ModRolloutBundleTasks) + { + actBundledTask = new(furtherTask); + handledTasks.Add(furtherTask); + } + else + { + return false; + } + } + return true; + } + + /// + /// qad heuristic for Tufin SC (public only for unit testing) + /// + /// + /// + /// + public int GetWaitCycles(string taskType, ExternalRequest? oldRequest) + { + // TODO: to be refined + if (oldRequest != null && UserConfig.ExternalRequestWaitCycles > 0 && + // last request handled group + (oldRequest.ExtRequestType == "(NetworkObjectModify, CREATE)" || oldRequest.ExtRequestType == "(NetworkObjectModify, UPDATE)") && + // now access request + (taskType == WfTaskType.access.ToString() || + // or last request created new objects in group + ContainsNewObj(oldRequest.ExtRequestContent))) + { + return UserConfig.ExternalRequestWaitCycles; + } + return 0; + } + + private static bool IsSameRuleOnDiffGw(WfReqTask? task1, WfReqTask? task2) + { + return task1 != null && task2 != null && task1.ManagementId == task2.ManagementId && + task1.GetAddInfoIntValue(AdditionalInfoKeys.ConnId) == task2.GetAddInfoIntValue(AdditionalInfoKeys.ConnId); + } + + private static bool ContainsNewObj(string contentString) + { + return contentString.Contains("\"object_updated_status\": \"NEW\"") || contentString.Contains("object_updated_status\\u0022: \\u0022NEW\\u0022") || + contentString.Contains("\"object_updated_status\":\"NEW\"") || contentString.Contains("object_updated_status\\u0022:\\u0022NEW\\u0022"); + } + + private async Task CreateExtRequest(WfTicket ticket, List tasks, List handledTasks, int waitCycles) + { + string taskContent = await ConstructContent(tasks, ticket.Requester); + Dictionary>? handledTaskNumbers; + string? extQueryVars = null; + if (handledTasks.Count > 1) + { + handledTaskNumbers = new() { { ExternalVarKeys.BundledTasks, handledTasks.ConvertAll(t => t.TaskNumber) } }; + extQueryVars = JsonSerializer.Serialize(handledTaskNumbers); + } + + var Variables = new + { + ownerId = ticket.Tasks.FirstOrDefault()?.Owners.FirstOrDefault()?.Owner.Id, + ticketId = ticket.Id, + taskNumber = tasks.FirstOrDefault()?.TaskNumber ?? 0, + extTicketSystem = JsonSerializer.Serialize(actSystem), + extTaskType = actTaskType, + extTaskContent = taskContent, + extQueryVariables = extQueryVars ?? "", + extRequestState = ExtStates.ExtReqInitialized.ToString(), + waitCycles = waitCycles + }; + await ApiConnection.SendQueryAsync(ExtRequestQueries.addExtRequest, Variables); + await LogRequestTasks(handledTasks, ticket.Requester?.Name, ModellingTypes.ChangeType.Request); + } + + private async Task RejectFollowingTasks(WfTicket ticket, int lastTaskNumber) + { + int actTaskNumber = lastTaskNumber + 1; + bool taskFound = true; + while (taskFound) + { + WfReqTask? furtherTask = ticket.Tasks.FirstOrDefault(ta => ta.TaskNumber == actTaskNumber); + if (furtherTask != null) + { + await UpdateTaskState(furtherTask, ExtStates.ExtReqRejected.ToString()); + actTaskNumber++; + } + else + { + taskFound = false; + } + } + } + + private void GetExtSystemFromConfig() + { + // Todo: logic for multiple systems + List extTicketSystems = JsonSerializer.Deserialize>(UserConfig.ExtTicketSystems) ?? []; + if (extTicketSystems.Count > 0) + { + extSystemType = extTicketSystems[0].Type; + actSystem = extTicketSystems[0]; + } + else + { + throw new InvalidOperationException("No external ticket system defined."); + } + } + + private async Task ConstructContent(List reqTasks, UiUser? requester) + { + ExternalTicket? ticket; + if (extSystemType == ExternalTicketSystemType.TufinSecureChange) + { + ticket = new SCTicket(actSystem) + { + Subject = ConstructSubject(reqTasks.Count > 0 ? reqTasks[0] : throw new ArgumentException("No Task given")), + Priority = SCTicketPriority.Low.ToString(), // todo: handling for manually handled requests (e.g. access) + Requester = requester?.Name ?? "" + }; + } + else + { + throw new NotSupportedException("Ticket system not supported yet"); + } + if (ticket != null) + { + ModellingNamingConvention? namingConvention = JsonSerializer.Deserialize(UserConfig.ModNamingConvention); + await ticket.CreateRequestString(reqTasks, ipProtos, namingConvention); + actTaskType = ticket.GetTaskTypeAsString(reqTasks[0]); + return ticket.TicketText; + } + return ""; + } + + private string ConstructSubject(WfReqTask reqTask) + { + string appId = reqTask.Owners.Count > 0 ? (reqTask.Owners.FirstOrDefault()?.Owner.ExtAppId ?? "") : ""; + string onMgt = UserConfig.GetText("on") + reqTask.OnManagement?.Name + "(" + reqTask.OnManagement?.Id + ")"; + string grpName = " " + reqTask.GetAddInfoValue(AdditionalInfoKeys.GrpName); + return (appId != "" ? appId + ": " : "") + reqTask.TaskType switch + { + nameof(WfTaskType.access) => UserConfig.GetText("create_rule") + onMgt, + nameof(WfTaskType.rule_modify) => UserConfig.GetText("modify_rule") + onMgt, + nameof(WfTaskType.rule_delete) => UserConfig.GetText("remove_rule") + onMgt, + nameof(WfTaskType.group_create) => UserConfig.GetText("create_group") + grpName + onMgt, + nameof(WfTaskType.group_modify) => UserConfig.GetText("modify_group") + grpName + onMgt, + nameof(WfTaskType.group_delete) => UserConfig.GetText("delete_group") + grpName + onMgt, + _ => "Request something" + }; + } + + private async Task UpdateTicket(WfTicket ticket, ExternalRequest extReq) + { + List? taskNumbers = null; + if (!string.IsNullOrEmpty(extReq.ExtQueryVariables)) + { + Dictionary>? extQueryVars = JsonSerializer.Deserialize>>(extReq.ExtQueryVariables); + extQueryVars?.TryGetValue(ExternalVarKeys.BundledTasks, out taskNumbers); + } + taskNumbers ??= [extReq.TaskNumber]; + foreach (var taskNumber in taskNumbers) + { + WfReqTask? updatedTask = ticket.Tasks.FirstOrDefault(ta => ta.TaskNumber == taskNumber); + if (updatedTask != null) + { + string? extTicketIdInTask = updatedTask.GetAddInfoValue(AdditionalInfoKeys.ExtIcketId); + if (extReq.ExtTicketId != null && extReq.ExtTicketId != extTicketIdInTask) + { + await wfHandler.SetAddInfoInReqTask(updatedTask, AdditionalInfoKeys.ExtIcketId, extReq.ExtTicketId); + } + await UpdateTaskState(updatedTask, extReq.ExtRequestState); + + if (extReq.ExtRequestState == ExtStates.ExtReqDone.ToString()) + { + await LogRequestTasks([updatedTask], actSystem.Name, ModellingTypes.ChangeType.Implement); + } + else if (extReq.ExtRequestState == ExtStates.ExtReqRejected.ToString()) + { + await LogRequestTasks([updatedTask], actSystem.Name, ModellingTypes.ChangeType.Reject, extReq.LastProcessingResponse ?? extReq.LastCreationResponse ?? ""); + } + } + else + { + Log.WriteError("UpdateTicket", $"Task not found in Ticket {ticket.Id}: {taskNumber}"); + } + } + } + + private async Task UpdateTaskState(WfReqTask reqTask, string extReqState) + { + if (extStateHandler != null && reqTask.StateId != extStateHandler.GetInternalStateId(extReqState)) + { + wfHandler.SetReqTaskEnv(reqTask); + reqTask.StateId = extStateHandler.GetInternalStateId(extReqState) ?? throw new ArgumentException("No translation defined for external state."); + await wfHandler.PromoteReqTask(reqTask); + } + } + + private async Task Acknowledge(ExternalRequest extRequest) + { + try + { + var Variables = new + { + id = extRequest.Id, + extRequestState = extRequest.ExtRequestState == ExtStates.ExtReqRejected.ToString() ? + ExtStates.ExtReqAckRejected.ToString() : + ExtStates.ExtReqAcknowledged.ToString(), + finishDate = DateTime.Now + }; + await ApiConnection.SendQueryAsync(ExtRequestQueries.updateExtRequestFinal, Variables); + } + catch (Exception exception) + { + Log.WriteError("Acknowledge External Request", $"Runs into exception: ", exception); + } + } + + private async Task LogRequestTasks(List tasks, string? requester, ModellingTypes.ChangeType changeType, string? comment = null) + { + foreach (WfReqTask task in tasks) + { + (long objId, ModellingTypes.ModObjectType objType) = GetObject(task); + await ModellingHandlerBase.LogChange(new LogChangeRequest + { + ChangeType = changeType, + ObjectType = objType, + ObjectId = objId, + Text = $"{ConstructLogMessageText(changeType)} {task.Title} on {task.OnManagement?.Name}{(comment != null ? ", " + comment : "")}", + ApiConnection = ApiConnection, + UserConfig = UserConfig, + ApplicationId = task.Owners.FirstOrDefault()?.Owner.Id, + DisplayMessageInUi = DefaultInit.DoNothing, + Requester = requester + }); + } + } + + private static (long, ModellingTypes.ModObjectType) GetObject(WfReqTask task) + { + if (task.GetAddInfoLongValue(AdditionalInfoKeys.ConnId) != null) + { + return (task.GetAddInfoIntValue(AdditionalInfoKeys.ConnId) ?? 0, ModellingTypes.ModObjectType.Connection); + } + else if (task.GetAddInfoLongValue(AdditionalInfoKeys.AppRoleId) != null) + { + return (task.GetAddInfoIntValue(AdditionalInfoKeys.AppRoleId) ?? 0, ModellingTypes.ModObjectType.AppRole); + } + else if (task.GetAddInfoIntValue(AdditionalInfoKeys.SvcGrpId) != null) + { + return (task.GetAddInfoIntValue(AdditionalInfoKeys.SvcGrpId) ?? 0, ModellingTypes.ModObjectType.ServiceGroup); + } + return (0, ModellingTypes.ModObjectType.Connection); + } + + private static string ConstructLogMessageText(ModellingTypes.ChangeType changeType) + { + return changeType switch + { + ModellingTypes.ChangeType.Request => "Requested", + ModellingTypes.ChangeType.Implement => "Implemented", + ModellingTypes.ChangeType.Reject => "Rejected", + _ => "", + }; + } + + private static void LogMessage(Exception? exception = null, string title = "", string message = "", bool ErrorFlag = false) + { + if (exception == null) + { + if (ErrorFlag) + { + Log.WriteWarning(title, message); + } + else + { + Log.WriteInfo(title, message); + } + } + else + { + Log.WriteError(title, message, exception); + } + } + + /// + /// Dispose method to clean up resources + /// + public void Dispose() + { + Dispose(true); + GC.SuppressFinalize(this); + } + + /// + /// Protected dispose method + /// + protected virtual void Dispose(bool disposing) + { + if (!disposed) + { + if (disposing) + { + // UserConfig is caller-owned and can be reused across multiple request handling steps. + // Disposing it here breaks subsequent handler instances that receive the same config. + } + disposed = true; + } + } + } +} diff --git a/roles/middleware/files/FWO.Middleware.Server/ExternalRequestSender.cs b/roles/middleware/files/FWO.Middleware.Server/ExternalRequestSender.cs new file mode 100644 index 0000000000..fe1bd060bd --- /dev/null +++ b/roles/middleware/files/FWO.Middleware.Server/ExternalRequestSender.cs @@ -0,0 +1,346 @@ +using FWO.Api.Client; +using FWO.Api.Client.Queries; +using FWO.Basics; +using FWO.Basics.Exceptions; +using FWO.Config.Api; +using FWO.Data; +using FWO.Logging; +using FWO.ExternalSystems; +using FWO.ExternalSystems.Tufin.SecureChange; +using RestSharp; +using System.Net; +using System.Text.Json; + +namespace FWO.Middleware.Server +{ + /// + /// Class handling the sending of external requests + /// + public class ExternalRequestSender : IDisposable + { + /// + /// Api Connection + /// + protected readonly ApiConnection apiConnection; + + /// + /// Global Config + /// + protected GlobalConfig globalConfig; + + private readonly UserConfig userConfig; + private readonly SCClient? InjScClient; + ExternalTicketSystem? ExtTicketSystem; + private bool disposed = false; + + + // todo: map to internal states to use "lowest_end_state" setting ? + private static readonly List openRequestStates = + [ + ExtStates.ExtReqInitialized.ToString(), + ExtStates.ExtReqFailed.ToString(), + ExtStates.ExtReqRequested.ToString(), + ExtStates.ExtReqInProgress.ToString() + ]; + + private const string LogMessageTitle = "External Request Sender"; + + + /// + /// Constructor for External Request Sender + /// + public ExternalRequestSender(ApiConnection apiConnection, GlobalConfig globalConfig, SCClient? injScClient = null) + { + this.apiConnection = apiConnection; + this.globalConfig = globalConfig; + userConfig = new(globalConfig, apiConnection, new() { Language = GlobalConst.kEnglish }); + InjScClient = injScClient; + } + + /// + /// Run the External Request Sender + /// + public async Task> Run() + { + List FailedRequests = []; + ExternalRequestDataHelper openRequests = await apiConnection.SendQueryAsync(ExtRequestQueries.getAndLockOpenRequests, new { states = openRequestStates }); + foreach (ExternalRequest request in openRequests.ExternalRequests) + { + await HandleRequest(request, FailedRequests); + } + await ReleaseRemainingLocks(openRequests.ExternalRequests); + return FailedRequests; + } + + private async Task HandleRequest(ExternalRequest request, List FailedRequests) + { + try + { + ExtTicketSystem = JsonSerializer.Deserialize(request.ExtTicketSystem) ?? throw new JsonException("No Ticket System"); + if (request.ExtRequestState == ExtStates.ExtReqInitialized.ToString() || + request.ExtRequestState == ExtStates.ExtReqFailed.ToString()) // try again + { + if (request.WaitCycles > 0) + { + await CountDownWaitCycle(request); + } + else + { + await SendRequest(request); + } + } + else + { + await RefreshState(request); + } + if ((await apiConnection.SendQueryAsync(ExtRequestQueries.updateExternalRequestLock, new { id = request.Id, locked = false })).UpdatedIdLong == request.Id) + { + request.Locked = false; + } + } + catch (Exception exception) + { + Log.WriteError(LogMessageTitle, "Runs into exception: ", exception); + FailedRequests.Add(RequestInfo(request)); + } + } + + private static string RequestInfo(ExternalRequest request) + { + return $"Request Id: {request.Id}, Internal TicketId: {request.TicketId}, TaskNo: {request.TaskNumber}"; + } + + private async Task ReleaseRemainingLocks(List requests) + { + try + { + foreach (ExternalRequest? request in requests.Where(r => r.Locked)) + { + await apiConnection.SendQueryAsync(ExtRequestQueries.updateExternalRequestLock, new { id = request.Id, locked = false }); + } + } + catch (Exception exception) + { + Log.WriteError(LogMessageTitle, "Release Lock runs into exception: ", exception); + } + } + + private async Task SendRequest(ExternalRequest request) + { + ExternalTicket? ticket = ConstructTicket(request); + try + { + Log.WriteInfo(LogMessageTitle, $"Sending {RequestInfo(request)}"); + request.Attempts++; + RestResponse ticketIdResponse = await ticket.CreateExternalTicket(); + request.LastMessage = ticketIdResponse.Content; + if (ticketIdResponse.StatusCode == HttpStatusCode.OK || ticketIdResponse.StatusCode == HttpStatusCode.Created) + { + var locationHeader = ticketIdResponse.Headers?.FirstOrDefault(h => h.Name.Equals("location", StringComparison.OrdinalIgnoreCase))?.Value?.ToString(); + if (!string.IsNullOrEmpty(locationHeader)) + { + Uri locationUri = new(locationHeader); + request.ExtTicketId = locationUri.Segments[^1]; + } + request.ExtRequestState = ExtStates.ExtReqRequested.ToString(); + await UpdateRequestCreation(request); + Log.WriteDebug(LogMessageTitle, $"{RequestInfo(request)}. Success Message: " + ticketIdResponse.Content); + } + else + { + Log.WriteError(LogMessageTitle, $"{RequestInfo(request)}. Error Message: " + ticketIdResponse.StatusDescription + ", " + ticketIdResponse.Content); + if (AnalyseForRejected(ticketIdResponse)) + { + await RejectRequest(request); + } + else + { + request.ExtRequestState = ExtStates.ExtReqFailed.ToString(); + await UpdateRequestCreation(request); + } + throw new ProcessingFailedException("RestResponse: HttpStatusCode not OK"); + } + } + catch (ProcessingFailedException) + { + throw; + } + catch (Exception) + { + if (!await HandleTimeOut(request, ticket)) + { + throw; + } + } + } + + private ExternalTicket ConstructTicket(ExternalRequest request) + { + ExternalTicket ticket; + + if (ExtTicketSystem?.Type == ExternalTicketSystemType.TufinSecureChange) + { + ticket = new SCTicket(ExtTicketSystem, InjScClient) + { + TicketSystem = ExtTicketSystem, + TicketText = request.ExtRequestContent + }; + } + else + { + throw new NotSupportedException("Ticket system not supported yet"); + } + return ticket; + } + + private async Task RejectRequest(ExternalRequest request) + { + request.ExtRequestState = ExtStates.ExtReqRejected.ToString(); + await UpdateRequestCreation(request); + using ExternalRequestHandler extReqHandler = new(userConfig, apiConnection); + await extReqHandler.HandleStateChange(request); + } + + private async Task HandleTimeOut(ExternalRequest request, ExternalTicket? ticket) + { + if (ticket != null && request.Attempts > 0) + { + try + { + if (request.Attempts >= ticket.TicketSystem.MaxAttempts) + { + await RejectRequest(request); + } + else + { + request.ExtRequestState = ExtStates.ExtReqFailed.ToString(); + request.WaitCycles = request.Attempts * ticket.TicketSystem.CyclesBetweenAttempts; + await UpdateRequestCreation(request); + return true; + } + } + catch (Exception exception) + { + Log.WriteError(LogMessageTitle, "Timeout handling failed: ", exception); + } + } + return false; + } + + private static bool AnalyseForRejected(RestResponse? ticketIdResponse) + { + return ticketIdResponse != null && ticketIdResponse.Content != null && + ((ticketIdResponse.Content.Contains("GENERAL_ERROR") && !TryAgain(ticketIdResponse)) || + ticketIdResponse.Content.Contains("ILLEGAL_ARGUMENT_ERROR") || + ticketIdResponse.Content.Contains("FIELD_VALIDATION_ERROR") || + ticketIdResponse.Content.Contains("WEB_APPLICATION_ERROR") || + ticketIdResponse.Content.Contains("implementation failure")); + } + + private static bool TryAgain(RestResponse ticketIdResponse) + { + return ticketIdResponse.Content != null && + ticketIdResponse.Content.Contains("Unable to rollback against JDBC Connection"); + } + + private async Task RefreshState(ExternalRequest request) + { + (request.ExtRequestState, request.LastMessage) = await PollState(request); + await UpdateRequestProcess(request); + using ExternalRequestHandler extReqHandler = new(userConfig, apiConnection); + await extReqHandler.HandleStateChange(request); + } + + private async Task<(string, string?)> PollState(ExternalRequest request) + { + try + { + ExternalTicket ticket; + if (ExtTicketSystem?.Type == ExternalTicketSystemType.TufinSecureChange) + { + ticket = new SCTicket(ExtTicketSystem, InjScClient) + { + TicketId = request.ExtTicketId + }; + } + else + { + throw new NotSupportedException("Ticket system not supported yet"); + } + return await ticket.GetNewState(request.ExtRequestState); + } + catch (Exception exc) + { + request.LastMessage = exc.Message; + await UpdateRequestProcess(request); + throw; + } + } + + private async Task UpdateRequestCreation(ExternalRequest request) + { + var Variables = new + { + id = request.Id, + extRequestState = request.ExtRequestState, + extTicketId = request.ExtTicketId, + creationResponse = request.LastMessage, + waitCycles = request.WaitCycles, + attempts = request.Attempts + }; + await apiConnection.SendQueryAsync(ExtRequestQueries.updateExtRequestCreation, Variables); + } + + private async Task UpdateRequestProcess(ExternalRequest request) + { + try + { + var Variables = new + { + id = request.Id, + extRequestState = request.ExtRequestState, + processingResponse = request.LastMessage + }; + await apiConnection.SendQueryAsync(ExtRequestQueries.updateExtRequestProcess, Variables); + } + catch (Exception exception) + { + Log.WriteError(LogMessageTitle, "UpdateRequestProcess failed: ", exception); + } + } + + private async Task CountDownWaitCycle(ExternalRequest request) + { + var Variables = new + { + id = request.Id, + waitCycles = --request.WaitCycles + }; + await apiConnection.SendQueryAsync(ExtRequestQueries.updateExternalRequestWaitCycles, Variables); + } + + /// + /// Dispose method to clean up resources + /// + public void Dispose() + { + Dispose(true); + GC.SuppressFinalize(this); + } + + /// + /// Protected dispose method + /// + protected virtual void Dispose(bool disposing) + { + if (!disposed) + { + if (disposing) + { + userConfig?.Dispose(); + } + disposed = true; + } + } + } +} diff --git a/roles/middleware/files/FWO.Middleware.Server/FWO.Middleware.Server.csproj b/roles/middleware/files/FWO.Middleware.Server/FWO.Middleware.Server.csproj index 895bfbe2a3..ea802a9285 100644 --- a/roles/middleware/files/FWO.Middleware.Server/FWO.Middleware.Server.csproj +++ b/roles/middleware/files/FWO.Middleware.Server/FWO.Middleware.Server.csproj @@ -1,26 +1,34 @@ - + - net6.0 + net10.0 enable enable True - - - + + + + + + + - + + + + + diff --git a/roles/middleware/files/FWO.Middleware.Server/ImportChangeNotifier.cs b/roles/middleware/files/FWO.Middleware.Server/ImportChangeNotifier.cs new file mode 100644 index 0000000000..1e9ec9f43a --- /dev/null +++ b/roles/middleware/files/FWO.Middleware.Server/ImportChangeNotifier.cs @@ -0,0 +1,276 @@ +using FWO.Api.Client; +using FWO.Api.Client.Queries; +using FWO.Basics; +using FWO.Basics.Exceptions; +using FWO.Data; +using FWO.Data.Report; +using FWO.Config.Api; +using FWO.Logging; +using FWO.Mail; +using FWO.Encryption; +using FWO.Report; +using FWO.Services; +using Newtonsoft.Json; +using System.Text.Json.Serialization; +using System.Text; +using System.Text.RegularExpressions; + +namespace FWO.Middleware.Server +{ + /// + /// Class handling the Import Change Notification + /// + public class ImportChangeNotifier + { + /// + /// Api Connection + /// + protected readonly ApiConnection apiConnection; + + /// + /// Global Config + /// + protected GlobalConfig globalConfig; + + private ReportBase? changeReport; + + private struct ImportToNotify + { + [JsonProperty("control_id"), JsonPropertyName("control_id")] + public long ControlId { get; set; } + + [JsonProperty("mgm_id"), JsonPropertyName("mgm_id")] + public int MgmtId { get; set; } + + [JsonProperty("management"), JsonPropertyName("management")] + public ImportManagement Mgmt { get; set; } + + [JsonProperty("stop_time"), JsonPropertyName("stop_time")] + public DateTime StopTime { get; set; } + + [JsonProperty("security_relevant_changes_counter"), JsonPropertyName("security_relevant_changes_counter")] + public int RelevantChanges { get; set; } + }; + private struct ImportManagement + { + [JsonProperty("mgm_name"), JsonPropertyName("mgm_name")] + public string MgmtName { get; set; } + } + + private List importsToNotify = []; + + private bool WorkInProgress = false; + private readonly DeviceFilter deviceFilter = new(); + private List importedManagements = []; + private readonly UserConfig userConfig; + private const string LogMessageTitle = "Import Change Notifier"; + + + /// + /// Constructor for Import Change Notifier + /// + public ImportChangeNotifier(ApiConnection apiConnection, GlobalConfig globalConfig) + { + this.apiConnection = apiConnection; + this.globalConfig = globalConfig; + userConfig = new(globalConfig); + } + + /// + /// Run the Import Change Notifier + /// + public async Task Run() + { + try + { + if (!WorkInProgress) + { + WorkInProgress = true; + if (await NewImportFound()) + { + if (globalConfig.ImpChangeNotifyType != (int)NotificationLayout.SimpleText) + { + await GenerateChangeReport(); + } + await SendEmail(); + await SetImportsNotified(); + } + WorkInProgress = false; + } + } + catch (Exception) + { + WorkInProgress = false; + throw; + } + } + + private async Task NewImportFound() + { + if (userConfig.GlobalConfig!.ImpChangeIncludeObjectChanges) + { + importsToNotify = await apiConnection.SendQueryAsync>(ReportQueries.getImportsToNotifyForAnyChanges); + } + else + { + importsToNotify = await apiConnection.SendQueryAsync>(ReportQueries.getImportsToNotify); + } + + importedManagements = []; + foreach (var impMgt in importsToNotify.Select(i => i.MgmtId).Where(m => !importedManagements.Contains(m))) + { + importedManagements.Add(impMgt); + } + return importsToNotify.Count > 0; + } + + private async Task GenerateChangeReport() + { + try + { + changeReport = await ReportGenerator.GenerateFromTemplate(new ReportTemplate("", await SetFilters()), apiConnection, userConfig, DefaultInit.DoNothing); + } + catch (Exception exception) + { + Log.WriteError(LogMessageTitle, $"Report generation leads to exception.", exception); + } + } + + private async Task SetFilters() + { + deviceFilter.Managements = [.. (await apiConnection.SendQueryAsync>(DeviceQueries.getDevicesByManagement)).Where(x => importedManagements.Contains(x.Id))]; + deviceFilter.ApplyFullDeviceSelection(true); + + return new((int)ReportType.Changes, deviceFilter) + { + TimeFilter = new() + { + TimeRangeType = TimeRangeType.Fixeddates, + StartTime = importsToNotify[0].StopTime, + EndTime = importsToNotify[^1].StopTime.AddSeconds(1) + } + }; + } + + private async Task SendEmail() + { + string decryptedSecret = AesEnc.TryDecrypt(globalConfig.EmailPassword, false, LogMessageTitle, "Could not decrypt mailserver password."); + EmailConnection emailConnection = new(globalConfig.EmailServerAddress, globalConfig.EmailPort, + globalConfig.EmailTls, globalConfig.EmailUser, decryptedSecret, globalConfig.EmailSenderAddress); + + MailData? mail = await PrepareEmail(); + + await MailKitMailer.SendAsync(mail, emailConnection, + globalConfig.ImpChangeNotifyType == (int)NotificationLayout.HtmlInBody, new()); + } + + private async Task PrepareEmail() + { + string subject = globalConfig.ImpChangeNotifySubject; + string body = CreateBody(); + FormFile? attachment = null; + if (changeReport != null) + { + switch (globalConfig.ImpChangeNotifyType) + { + case (int)NotificationLayout.HtmlInBody: + body += changeReport.ExportToHtml(); + break; + case (int)NotificationLayout.PdfAsAttachment: + string html = changeReport.ExportToHtml(); + string? pdfData = await changeReport.ToPdf(html); + + if (string.IsNullOrWhiteSpace(pdfData)) + throw new ProcessingFailedException("No Pdf generated."); + + attachment = CreateAttachment(pdfData, GlobalConst.kPdf); + break; + case (int)NotificationLayout.HtmlAsAttachment: + attachment = CreateAttachment(changeReport.ExportToHtml(), GlobalConst.kHtml); + break; + case (int)NotificationLayout.CsvAsAttachment: + attachment = CreateAttachment(changeReport.ExportToCsv(), GlobalConst.kCsv); + break; + case (int)NotificationLayout.JsonAsAttachment: + attachment = CreateAttachment(changeReport.ExportToJson(), GlobalConst.kJson); + break; + default: + break; + } + } + MailData mailData = new(CollectRecipients(), subject) { Body = body }; + if (attachment != null) + { + mailData.Attachments = new FormFileCollection() { attachment }; + } + return mailData; + } + + private string CreateBody() + { + StringBuilder body = new(globalConfig.ImpChangeNotifyBody); + foreach (var mgmtId in importedManagements) + { + int mgmtCounter = 0; + foreach (var imp in importsToNotify.Where(x => x.MgmtId == mgmtId)) + { + mgmtCounter += imp.RelevantChanges; + } + body.Append(globalConfig.ImpChangeNotifyType == (int)NotificationLayout.HtmlInBody ? "
                      " : "\r\n\r\n"); + body.Append($"{importsToNotify.FirstOrDefault(x => x.MgmtId == mgmtId).Mgmt.MgmtName} (id={mgmtId}): {mgmtCounter} {userConfig.GetText("changes")}"); + } + return body.ToString(); + } + + private FormFile? CreateAttachment(string? content, string fileFormat) + { + if (content != null) + { + string fileName = $"{Regex.Replace(globalConfig.ImpChangeNotifySubject, @"\s", "")}_{DateTime.Now.ToUniversalTime().ToString("yyyy-MM-ddTHH-mm-ssK")}.{fileFormat}"; + + MemoryStream memoryStream; + string contentType; + + if (fileFormat == GlobalConst.kPdf) + { + memoryStream = new(Convert.FromBase64String(content)); + contentType = "application/octet-stream"; + } + else + { + memoryStream = new(System.Text.Encoding.UTF8.GetBytes(content)); + contentType = $"application/{fileFormat}"; + } + + return new(memoryStream, 0, memoryStream.Length, "FWO-Report-Attachment", fileName) + { + Headers = new HeaderDictionary(), + ContentType = contentType + }; + } + return null; + } + + private List CollectRecipients() + { + if (globalConfig.UseDummyEmailAddress) + { + return [globalConfig.DummyEmailAddress]; + } + string[] separatingStrings = [",", ";", "|"]; + return globalConfig.ImpChangeNotifyRecipients.Split(separatingStrings, StringSplitOptions.TrimEntries | StringSplitOptions.RemoveEmptyEntries).ToList(); + } + + private async Task SetImportsNotified() + { + try + { + await apiConnection.SendQueryAsync(ReportQueries.setImportsNotified, new { ids = importsToNotify.ConvertAll(x => x.ControlId) }); + } + catch (Exception exception) + { + Log.WriteError(LogMessageTitle, $"Could not mark imports as notified.", exception); + } + } + } +} diff --git a/roles/middleware/files/FWO.Middleware.Server/ImportNwZoneMatrixData.cs b/roles/middleware/files/FWO.Middleware.Server/ImportNwZoneMatrixData.cs new file mode 100644 index 0000000000..f9db4649a3 --- /dev/null +++ b/roles/middleware/files/FWO.Middleware.Server/ImportNwZoneMatrixData.cs @@ -0,0 +1,53 @@ +using System.Text.Json.Serialization; + + +namespace FWO.Middleware.Server +{ + /// + /// Structure for imported Network Zones matrix data + /// + public class ImportNwZoneMatrixData + { + /// + /// Matrix Name + /// + [JsonPropertyName("name")] + public string Name { get; set; } = ""; + + /// + /// Matrix Comment + /// + [JsonPropertyName("comment")] + public string Comment { get; set; } = ""; + + /// + /// List of all Network Zones + /// + [JsonPropertyName("areas")] + public List NetworkZones { get; set; } = []; + } + + /// + /// Structure for imported Network Zones data + /// + public class NetworkZoneData : ModellingImportAreaData + { + /// + /// List of all associated communication data + /// + [JsonPropertyName("communication_to")] + public List CommData { get; set; } = []; + } + + /// + /// Structure for communication Data + /// + public class CommunicationData + { + /// + /// Reference to other Network Zone as destination + /// + [JsonPropertyName("id_string")] + public string IdString { get; set; } = ""; + } +} diff --git a/roles/middleware/files/FWO.Middleware.Server/Jobs/AutoDiscoverJob.cs b/roles/middleware/files/FWO.Middleware.Server/Jobs/AutoDiscoverJob.cs new file mode 100644 index 0000000000..9b6a3b82ef --- /dev/null +++ b/roles/middleware/files/FWO.Middleware.Server/Jobs/AutoDiscoverJob.cs @@ -0,0 +1,125 @@ +using FWO.Api.Client; +using FWO.Api.Client.Queries; +using FWO.Basics; +using FWO.Config.Api; +using FWO.Data; +using FWO.Data.Logging; +using FWO.DeviceAutoDiscovery; +using FWO.Logging; +using FWO.Services; +using Quartz; +using System.Linq; +using FWO.Services.Logging; + +namespace FWO.Middleware.Server.Jobs +{ + /// + /// Quartz Job for autodiscovery + /// + [DisallowConcurrentExecution] + public class AutoDiscoverJob : IJob + { + private const string LogMessageTitle = "Autodiscovery"; + private readonly ApiConnection apiConnection; + private readonly GlobalConfig globalConfig; + private long? lastMgmtAlertId; + + /// + /// Creates a new autodiscovery job. + /// + /// GraphQL API connection. + /// Global configuration. + public AutoDiscoverJob(ApiConnection apiConnection, GlobalConfig globalConfig) + { + this.apiConnection = apiConnection; + this.globalConfig = globalConfig; + } + + /// + public async Task Execute(IJobExecutionContext context) + { + try + { + List managements = await apiConnection.SendQueryAsync>(DeviceQueries.getManagementsDetails); + foreach (Management superManagement in managements.Where(x => x.DeviceType.CanBeSupermanager() || x.DeviceType.CanBeAutodiscovered(x))) + { + try + { + AutoDiscoveryBase autodiscovery = new(superManagement, apiConnection); + + List diffList = await autodiscovery.Run(); + List actions = autodiscovery.ConvertToActions(diffList); + + int changeCounter = 0; + + foreach (ActionItem action in actions) + { + if (action.ActionType == ActionCode.AddGatewayToNewManagement.ToString()) + { + action.RefAlertId = lastMgmtAlertId; + } + action.AlertId = await SetAlert(action); + changeCounter++; + } + await AlertHelper.AddLogEntry(apiConnection, 0, globalConfig.GetText("scheduled_autodiscovery"), + changeCounter > 0 ? changeCounter + globalConfig.GetText("changes_found") : globalConfig.GetText("found_no_changes"), + GlobalConst.kAutodiscovery, superManagement.Id); + } + catch (Exception excMgm) + { + Log.WriteError(LogMessageTitle, $"Ran into exception while auto-discovering management {superManagement.Name} (id: {superManagement.Id}) ", excMgm); + ActionItem actionException = new() + { + Number = 0, + ActionType = ActionCode.WaitForTempLoginFailureToPass.ToString(), + ManagementId = superManagement.Id, + Supermanager = superManagement.Name, + JsonData = excMgm.Message + }; + await SetAlert(actionException); + await AlertHelper.AddLogEntry(apiConnection, 1, globalConfig.GetText("scheduled_autodiscovery"), + $"Ran into exception while handling management {superManagement.Name} (id: {superManagement.Id}): " + excMgm.Message, + GlobalConst.kAutodiscovery, superManagement.Id); + } + } + } + catch (Exception exc) + { + await AlertHelper.LogErrorsWithAlert(apiConnection, globalConfig, 1, LogMessageTitle, GlobalConst.kAutodiscovery, AlertCode.Autodiscovery, exc); + } + } + + private async Task SetAlert(ActionItem action) + { + string title = "Supermanagement: " + action.Supermanager; + lastMgmtAlertId = await AlertHelper.SetAlert(apiConnection, title, action.ActionType ?? "", GlobalConst.kAutodiscovery, AlertCode.Autodiscovery, + new AlertHelper.AdditionalAlertData + { + MgmtId = action.ManagementId, + JsonData = action.JsonData?.ToString(), + DevId = action.DeviceId, + RefAlertId = action.RefAlertId, + CompareDesc = true + }); + if (!AutodiscoveryLogMapper.TryMapPromptAction(action, out AutodiscoveryLogMapper.PromptLogData? logData)) + { + Log.WriteWarning("Logging", $"Unmapped autodiscovery action type: {action.ActionType}"); + return lastMgmtAlertId; + } + if (logData != null) + { + await PromptLogHelper.LogPrompt(new PromptLogRequest + { + PromptEvent = PromptLogEvent.Created, + Object = logData.Object, + Operation = logData.Operation, + UserId = "AutodiscoveryJob", + Timestamp = DateTime.UtcNow, + Origin = ChangeLogOrigin.Autodiscovery, + Fields = logData.Fields + }); + } + return lastMgmtAlertId; + } + } +} diff --git a/roles/middleware/files/FWO.Middleware.Server/Jobs/ComplianceJob.cs b/roles/middleware/files/FWO.Middleware.Server/Jobs/ComplianceJob.cs new file mode 100644 index 0000000000..026e34c546 --- /dev/null +++ b/roles/middleware/files/FWO.Middleware.Server/Jobs/ComplianceJob.cs @@ -0,0 +1,50 @@ +using FWO.Api.Client; +using FWO.Basics; +using FWO.Compliance; +using FWO.Config.Api; +using FWO.Data; +using FWO.Logging; +using Quartz; +using FWO.Services; + +namespace FWO.Middleware.Server.Jobs +{ + /// + /// Quartz Job for Compliance + /// + [DisallowConcurrentExecution] + public class ComplianceJob : IJob + { + private const string LogMessageTitle = "Compliance"; + private readonly ApiConnection apiConnection; + private readonly GlobalConfig globalConfig; + + /// + /// Creates a new compliance job. + /// + /// GraphQL API connection. + /// Global configuration. + public ComplianceJob(ApiConnection apiConnection, GlobalConfig globalConfig) + { + this.apiConnection = apiConnection; + this.globalConfig = globalConfig; + } + + /// + public async Task Execute(IJobExecutionContext context) + { + try + { + UserConfig userConfig = new(globalConfig); + ComplianceCheck complianceCheck = new(userConfig, apiConnection); + + await complianceCheck.RunComplianceCheck(ComplianceCheckType.Standard); + await complianceCheck.PersistDataAsync(); + } + catch (Exception exc) + { + await AlertHelper.LogErrorsWithAlert(apiConnection, globalConfig, 1, LogMessageTitle, GlobalConst.kComplianceCheck, AlertCode.ComplianceCheck, exc); + } + } + } +} diff --git a/roles/middleware/files/FWO.Middleware.Server/Jobs/DailyCheckJob.cs b/roles/middleware/files/FWO.Middleware.Server/Jobs/DailyCheckJob.cs new file mode 100644 index 0000000000..41479c3edc --- /dev/null +++ b/roles/middleware/files/FWO.Middleware.Server/Jobs/DailyCheckJob.cs @@ -0,0 +1,296 @@ +using FWO.Api.Client; +using FWO.Api.Client.Queries; +using FWO.Basics; +using FWO.Compliance; +using FWO.Config.Api; +using FWO.Data; +using FWO.Data.Middleware; +using FWO.Data.Workflow; +using FWO.Logging; +using FWO.Recert; +using FWO.Services; +using FWO.Services.Workflow; +using Quartz; + +namespace FWO.Middleware.Server.Jobs +{ + /// + /// Quartz Job for daily checks + /// + [DisallowConcurrentExecution] + public class DailyCheckJob : IJob + { + private const string LogMessageTitle = "Daily Check"; + private readonly ApiConnection apiConnection; + private readonly GlobalConfig globalConfig; + + /// + /// Creates a new daily check job. + /// + /// GraphQL API connection. + /// Global configuration. + public DailyCheckJob(ApiConnection apiConnection, GlobalConfig globalConfig) + { + this.apiConnection = apiConnection; + this.globalConfig = globalConfig; + } + + /// + public async Task Execute(IJobExecutionContext context) + { + try + { + HashSet enabledModules = LoadEnabledModules(); + + if (enabledModules.Contains(DailyCheckModule.DemoData)) + { + await CheckDemoData(); + } + if (enabledModules.Contains(DailyCheckModule.Imports)) + { + await CheckImports(); + } + if (enabledModules.Contains(DailyCheckModule.RecertRefresh) && globalConfig.RecRefreshDaily) + { + await RefreshRecert(); + } + if (enabledModules.Contains(DailyCheckModule.RecertCheck)) + { + await CheckRecerts(); + } + if (enabledModules.Contains(DailyCheckModule.UnansweredInterfaceRequests)) + { + await CheckUnansweredInterfaceRequests(); + } + if (enabledModules.Contains(DailyCheckModule.RuleExpiryCheck)) + { + await CheckRuleExpiry(); + } + if (enabledModules.Contains(DailyCheckModule.OwnerActiveRules)) + { + await CheckOwnerActiveRules(); + } + } + catch (Exception exc) + { + await AlertHelper.LogErrorsWithAlert(apiConnection, globalConfig, 2, LogMessageTitle, GlobalConst.kDailyCheck, AlertCode.DailyCheckError, exc); + } + } + + private HashSet LoadEnabledModules() + { + if (string.IsNullOrWhiteSpace(globalConfig.DailyCheckModules)) + { + return [.. Enum.GetValues(typeof(DailyCheckModule)).Cast()]; + } + + try + { + List? modules = System.Text.Json.JsonSerializer.Deserialize>(globalConfig.DailyCheckModules); + return modules == null + ? [.. Enum.GetValues(typeof(DailyCheckModule)).Cast()] + : [.. modules]; + } + catch (System.Text.Json.JsonException) + { + Log.WriteError(LogMessageTitle, $"Could not parse daily check modules config \"{globalConfig.DailyCheckModules}\". Using all modules."); + return [.. Enum.GetValues(typeof(DailyCheckModule)).Cast()]; + } + } + + private async Task RefreshRecert() + { + Log.WriteDebug(LogMessageTitle, "Refresh recert ownerships"); + await RecertRefresh.RecalcRecerts(apiConnection); + } + + private async Task CheckRecerts() + { + if (globalConfig.RecCheckActive) + { + RecertCheck recertCheck = new(apiConnection, globalConfig); + int emailsSent = await recertCheck.CheckRecertifications(); + Log.WriteDebug(LogMessageTitle, $"Recert Check: Sent {emailsSent} emails."); + await AlertHelper.AddLogEntry(apiConnection, 0, globalConfig.GetText("daily_recert_check"), emailsSent + globalConfig.GetText("emails_sent"), GlobalConst.kDailyCheck); + } + } + + private async Task CheckRuleExpiry() + { + RuleExpiryCheck ruleExpiryCheck = new(apiConnection, globalConfig); + int ruleExpiryEmailsSent = await ruleExpiryCheck.CheckRuleExpiry(); + Log.WriteDebug(LogMessageTitle, $"Rule Expiry Check: Sent {ruleExpiryEmailsSent} emails."); + await AlertHelper.AddLogEntry(apiConnection, 0, "Scheduled Daily Rule Expiry Check", ruleExpiryEmailsSent + globalConfig.GetText("emails_sent"), GlobalConst.kDailyCheck); + } + + private async Task CheckOwnerActiveRules() + { + OwnerActiveRuleCheck ownerActiveRuleCheck = new(apiConnection, globalConfig); + int ownerActiveRuleEmailsSent = await ownerActiveRuleCheck.CheckActiveRulesByScheduler(); + Log.WriteDebug(LogMessageTitle, $"Owner Active Rule Check: Sent {ownerActiveRuleEmailsSent} emails."); + await AlertHelper.AddLogEntry(apiConnection, 0, "Scheduled Daily Owner Active Rule Check", ownerActiveRuleEmailsSent + globalConfig.GetText("emails_sent"), GlobalConst.kDailyCheck); + } + + private struct DemoDataFlags + { + public bool SampleManagementExisting; + public bool SampleCredentialExisting; + public bool SampleUserExisting; + public bool SampleTenantExisting; + public bool SampleGroupExisting; + public bool SampleOwnerExisting; + + public readonly bool AnyFlagSet() + { + return SampleManagementExisting || SampleCredentialExisting || SampleUserExisting + || SampleTenantExisting || SampleGroupExisting || SampleOwnerExisting; + } + } + + private async Task CheckDemoData() + { + DemoDataFlags demoDataFlags = await CheckDemoDataExisting(); + + if (demoDataFlags.AnyFlagSet()) + { + string description = globalConfig.GetText("sample_data_found_in") + (demoDataFlags.SampleManagementExisting ? globalConfig.GetText("managements") + " " : "") + + (demoDataFlags.SampleCredentialExisting ? globalConfig.GetText("import_credential") + " " : "") + + (demoDataFlags.SampleUserExisting ? globalConfig.GetText("users") + " " : "") + + (demoDataFlags.SampleTenantExisting ? globalConfig.GetText("tenants") + " " : "") + + (demoDataFlags.SampleGroupExisting ? globalConfig.GetText("groups") + " " : "") + + (demoDataFlags.SampleOwnerExisting ? globalConfig.GetText("owners") : ""); + await AlertHelper.SetAlert(apiConnection, globalConfig.GetText("sample_data"), description, GlobalConst.kDailyCheck, AlertCode.SampleDataExisting, new AlertHelper.AdditionalAlertData()); + await AlertHelper.AddLogEntry(apiConnection, 1, globalConfig.GetText("daily_sample_data_check"), description, GlobalConst.kDailyCheck); + } + else + { + await AlertHelper.AddLogEntry(apiConnection, 0, globalConfig.GetText("daily_sample_data_check"), globalConfig.GetText("no_sample_data_found"), GlobalConst.kDailyCheck); + } + } + + private async Task CheckDemoDataExisting() + { + List managements = await apiConnection.SendQueryAsync>(DeviceQueries.getManagementsDetails); + List credentials = await apiConnection.SendQueryAsync>(DeviceQueries.getCredentialsWithoutSecrets); + List users = await apiConnection.SendQueryAsync>(AuthQueries.getUsers); + List tenants = await apiConnection.SendQueryAsync>(AuthQueries.getTenants); + bool sampleGroupExisting = false; + List connectedLdaps = apiConnection.SendQueryAsync>(AuthQueries.getLdapConnections).Result; + foreach (Ldap currentLdap in connectedLdaps.Where(l => l.IsInternal() && l.HasGroupHandling())) + { + List groups = await currentLdap.GetAllInternalGroups(); + sampleGroupExisting |= groups.Exists(g => new DistName(g.GroupDn).Group.EndsWith(GlobalConst.k_demo)); + } + List owners = await apiConnection.SendQueryAsync>(OwnerQueries.getOwners); + + return new() + { + SampleManagementExisting = managements.Exists(m => m.Name.EndsWith(GlobalConst.k_demo)), + SampleCredentialExisting = credentials.Exists(c => c.Name.EndsWith(GlobalConst.k_demo)), + SampleUserExisting = users.Exists(u => u.Name.EndsWith(GlobalConst.k_demo)), + SampleTenantExisting = tenants.Exists(t => t.Name.EndsWith(GlobalConst.k_demo)), + SampleGroupExisting = sampleGroupExisting, + SampleOwnerExisting = owners.Exists(o => o.Name.EndsWith(GlobalConst.k_demo)) + }; + } + + private async Task CheckImports() + { + List importStati = await apiConnection.SendQueryAsync>(MonitorQueries.getImportStatus); + int importIssues = 0; + object jsonData; + foreach (ImportStatus imp in importStati.Where(x => !x.ImportDisabled)) + { + if (imp.LastIncompleteImport != null && imp.LastIncompleteImport.Length > 0) + { + if (imp.LastIncompleteImport[0].StartTime < DateTime.Now.AddHours(-globalConfig.MaxImportDuration)) + { + jsonData = imp.LastIncompleteImport; + await AlertHelper.SetAlert(apiConnection, globalConfig.GetText("import"), globalConfig.GetText("E7011"), GlobalConst.kDailyCheck, AlertCode.ImportRunningTooLong, new AlertHelper.AdditionalAlertData { MgmtId = imp.MgmId, JsonData = jsonData }); + importIssues++; + } + } + else if (imp.LastImport == null || imp.LastImport.Length == 0) + { + jsonData = imp; + await AlertHelper.SetAlert(apiConnection, globalConfig.GetText("import"), globalConfig.GetText("E7012"), GlobalConst.kDailyCheck, AlertCode.NoImport, new AlertHelper.AdditionalAlertData { MgmtId = imp.MgmId, JsonData = jsonData }); + importIssues++; + } + else if (imp.LastImportAttempt != null && imp.LastImportAttempt < DateTime.Now.AddHours(-globalConfig.MaxImportInterval)) + { + jsonData = imp; + await AlertHelper.SetAlert(apiConnection, globalConfig.GetText("import"), globalConfig.GetText("E7013"), GlobalConst.kDailyCheck, AlertCode.SuccessfulImportOverdue, new AlertHelper.AdditionalAlertData { MgmtId = imp.MgmId, JsonData = jsonData }); + importIssues++; + } + } + await AlertHelper.AddLogEntry(apiConnection, importIssues != 0 ? 1 : 0, globalConfig.GetText("daily_importer_check"), + importIssues != 0 ? importIssues + globalConfig.GetText("import_issues_found") : globalConfig.GetText("no_import_issues_found"), GlobalConst.kDailyCheck); + } + + private async Task CheckUnansweredInterfaceRequests() + { + int emailsSent = 0; + List OwnerGroups = await MiddlewareServerServices.GetInternalGroups(apiConnection); + UserConfig userConfig = new(globalConfig); + WfHandler wfHandler = new(userConfig, apiConnection, WorkflowPhases.implementation, OwnerGroups, new ComplianceRequestedRulePolicyChecker(userConfig, apiConnection)); + await wfHandler.Init(); + NotificationService notificationService = await NotificationService.CreateAsync(NotificationClient.InterfaceRequest, globalConfig, apiConnection, OwnerGroups); + + foreach (var notification in notificationService.Notifications) + { + List? unansweredTickets = await wfHandler.GetOpenTickets(WfTaskType.new_interface.ToString(), + (notification.RepeatOffsetAfterDeadline ?? 0) + (notification.InitialOffsetAfterDeadline ?? 0), + notification.RepeatIntervalAfterDeadline ?? SchedulerInterval.Days); + foreach (var ticket in unansweredTickets) + { + FwoOwner? owner = ticket.Tasks.FirstOrDefault(r => r.TaskType == WfTaskType.new_interface.ToString())?.Owners.FirstOrDefault()?.Owner; + if (owner != null) + { + emailsSent += await notificationService.SendNotificationIfDue(notification, owner, ticket.CreationDate, await PrepareBody(ticket, owner)); + } + } + } + await notificationService.UpdateNotificationsLastSent(); + Log.WriteDebug(LogMessageTitle, $"Unanswered Interface Requests Check: Sent {emailsSent} emails."); + } + + private async Task PrepareBody(WfTicket ticket, FwoOwner owner) + { + WfReqTask? reqTask = ticket.Tasks.FirstOrDefault(r => r.TaskType == WfTaskType.new_interface.ToString()); + FwoOwner? requestingOwner = await GetRequestingOwner(reqTask?.GetAddInfoIntValue(AdditionalInfoKeys.ReqOwner)); + + return globalConfig.ModUnansweredReqEmailBody + .Replace(Placeholder.REQUESTER, ticket.Requester?.Name) + .Replace(Placeholder.REQUESTDATE, ticket.CreationDate.ToString("dd.MM.yyyy")) + .Replace(Placeholder.REQUESTING_APPNAME, requestingOwner?.Name) + .Replace(Placeholder.REQUESTING_APPID, requestingOwner?.ExtAppId) + .Replace(Placeholder.APPNAME, owner.Name) + .Replace(Placeholder.APPID, owner.ExtAppId) + .Replace(Placeholder.INTERFACE_LINK, ConstructLink(owner, reqTask)); + } + + private async Task GetRequestingOwner(int? ownerId) + { + FwoOwner? reqOwner = null; + if (ownerId != null) + { + try + { + reqOwner = await apiConnection.SendQueryAsync(OwnerQueries.getOwnerById, new { id = ownerId }); + } + catch (Exception exc) + { + await AlertHelper.LogErrorsWithAlert(apiConnection, globalConfig, 2, LogMessageTitle, GlobalConst.kDailyCheck, AlertCode.DailyCheckError, exc); + } + } + return reqOwner; + } + + private string ConstructLink(FwoOwner owner, WfReqTask? reqTask) + { + int? connId = reqTask?.GetAddInfoIntValue(AdditionalInfoKeys.ConnId); + string interfaceUrl = $"{globalConfig.UiHostName}/{PageName.Modelling}/{owner.ExtAppId}/{connId}"; + return $"{reqTask?.Title ?? globalConfig.GetText("interface")}"; + } + } +} diff --git a/roles/middleware/files/FWO.Middleware.Server/Jobs/ExternalRequestJob.cs b/roles/middleware/files/FWO.Middleware.Server/Jobs/ExternalRequestJob.cs new file mode 100644 index 0000000000..6225908a7c --- /dev/null +++ b/roles/middleware/files/FWO.Middleware.Server/Jobs/ExternalRequestJob.cs @@ -0,0 +1,63 @@ +using FWO.Api.Client; +using FWO.Basics; +using FWO.Basics.Exceptions; +using FWO.Config.Api; +using FWO.Data; +using FWO.Logging; +using FWO.Services; +using Quartz; + +namespace FWO.Middleware.Server.Jobs +{ + /// + /// Quartz Job for sending external requests + /// + [DisallowConcurrentExecution] + public class ExternalRequestJob : IJob + { + private const string LogMessageTitle = "External Request Job"; + private readonly ApiConnection apiConnection; + private readonly GlobalConfig globalConfig; + + /// + /// Constructor with DI + /// + public ExternalRequestJob(ApiConnection apiConnection, GlobalConfig globalConfig) + { + this.apiConnection = apiConnection; + this.globalConfig = globalConfig; + } + + /// + /// Execute the job + /// + public async Task Execute(IJobExecutionContext context) + { + Log.WriteDebug(LogMessageTitle, "Job started"); + + try + { + using (ExternalRequestSender externalRequestSender = new(apiConnection, globalConfig)) + { + List failedRequests = await externalRequestSender.Run(); + + if (failedRequests.Count > 0) + { + throw new ProcessingFailedException($"{failedRequests.Count} External Request(s) failed: {string.Join(". ", failedRequests)}."); + } + + Log.WriteDebug(LogMessageTitle, "Job completed successfully"); + } + } + catch (Exception exc) + { + Log.WriteError(LogMessageTitle, "Job failed", exc); + await AlertHelper.LogErrorsWithAlert(apiConnection, globalConfig, 1, "External Request", GlobalConst.kExternalRequest, AlertCode.ExternalRequest, exc); + + // Mark job as failed but don't refire immediately + throw new JobExecutionException(exc, refireImmediately: false); + } + } + + } +} diff --git a/roles/middleware/files/FWO.Middleware.Server/Jobs/ImportAppDataJob.cs b/roles/middleware/files/FWO.Middleware.Server/Jobs/ImportAppDataJob.cs new file mode 100644 index 0000000000..6b6776b8e7 --- /dev/null +++ b/roles/middleware/files/FWO.Middleware.Server/Jobs/ImportAppDataJob.cs @@ -0,0 +1,78 @@ +using FWO.Api.Client; +using FWO.Basics; +using FWO.Basics.Exceptions; +using FWO.Config.Api; +using FWO.Data; +using FWO.Logging; +using FWO.Services.Modelling; +using Quartz; +using FWO.Services; + +namespace FWO.Middleware.Server.Jobs +{ + /// + /// Quartz Job for importing app data and adjusting app server names + /// + [DisallowConcurrentExecution] + public class ImportAppDataJob : IJob + { + private const string LogMessageTitleImport = "Import App Data"; + private const string LogMessageTitleAdjust = "Adjust App Server Names"; + private readonly ApiConnection apiConnection; + private readonly GlobalConfig globalConfig; + + /// + /// Creates a new job for importing app data and adjusting app server names. + /// + /// GraphQL API connection. + /// Global configuration. + public ImportAppDataJob(ApiConnection apiConnection, GlobalConfig globalConfig) + { + this.apiConnection = apiConnection; + this.globalConfig = globalConfig; + } + + /// + public async Task Execute(IJobExecutionContext context) + { + Log.WriteDebug(LogMessageTitleImport, "Process started"); + + await ImportAppData(); + await AdjustAppServerNames(); + } + + private async Task ImportAppData() + { + try + { + AppDataImport import = new(apiConnection, globalConfig); + List failedImports = await import.Run(); + if (failedImports.Count > 0) + { + throw new ProcessingFailedException($"{LogMessageTitleImport} failed for {string.Join(", ", failedImports)}."); + } + } + catch (Exception exc) + { + await AlertHelper.LogErrorsWithAlert(apiConnection, globalConfig, 2, LogMessageTitleImport, GlobalConst.kImportAppData, AlertCode.ImportAppData, exc); + } + } + + private async Task AdjustAppServerNames() + { + try + { + if (globalConfig.DnsLookup) + { + UserConfig userConfig = new(globalConfig, apiConnection, new() { Language = GlobalConst.kEnglish }); + userConfig.User.Name = Roles.MiddlewareServer; + await AppServerHelper.AdjustAppServerNames(apiConnection, userConfig); + } + } + catch (Exception exc) + { + await AlertHelper.LogErrorsWithAlert(apiConnection, globalConfig, 1, LogMessageTitleAdjust, GlobalConst.kAdjustAppServerNames, AlertCode.AdjustAppServerNames, exc); + } + } + } +} diff --git a/roles/middleware/files/FWO.Middleware.Server/Jobs/ImportChangeNotifyJob.cs b/roles/middleware/files/FWO.Middleware.Server/Jobs/ImportChangeNotifyJob.cs new file mode 100644 index 0000000000..5f3a6b27f1 --- /dev/null +++ b/roles/middleware/files/FWO.Middleware.Server/Jobs/ImportChangeNotifyJob.cs @@ -0,0 +1,46 @@ +using FWO.Api.Client; +using FWO.Basics; +using FWO.Config.Api; +using FWO.Data; +using FWO.Logging; +using FWO.Services; +using Quartz; + +namespace FWO.Middleware.Server.Jobs +{ + /// + /// Quartz Job for import change notifications + /// + [DisallowConcurrentExecution] + public class ImportChangeNotifyJob : IJob + { + private const string LogMessageTitle = "Import Change Notify"; + private readonly ApiConnection apiConnection; + private readonly GlobalConfig globalConfig; + + /// + /// Creates a new job for import change notifications. + /// + /// GraphQL API connection. + /// Global configuration. + public ImportChangeNotifyJob(ApiConnection apiConnection, GlobalConfig globalConfig) + { + this.apiConnection = apiConnection; + this.globalConfig = globalConfig; + } + + /// + public async Task Execute(IJobExecutionContext context) + { + try + { + ImportChangeNotifier notifyImportChanges = new(apiConnection, globalConfig); + await notifyImportChanges.Run(); + } + catch (Exception exc) + { + await AlertHelper.LogErrorsWithAlert(apiConnection, globalConfig, 1, LogMessageTitle, GlobalConst.kImportChangeNotify, AlertCode.ImportChangeNotify, exc); + } + } + } +} diff --git a/roles/middleware/files/FWO.Middleware.Server/Jobs/ImportIpDataJob.cs b/roles/middleware/files/FWO.Middleware.Server/Jobs/ImportIpDataJob.cs new file mode 100644 index 0000000000..f4873e5575 --- /dev/null +++ b/roles/middleware/files/FWO.Middleware.Server/Jobs/ImportIpDataJob.cs @@ -0,0 +1,53 @@ +using FWO.Api.Client; +using FWO.Basics; +using FWO.Basics.Exceptions; +using FWO.Config.Api; +using FWO.Data; +using FWO.Logging; +using FWO.Services; +using Quartz; + +namespace FWO.Middleware.Server.Jobs +{ + /// + /// Quartz Job for importing area IP data + /// + [DisallowConcurrentExecution] + public class ImportIpDataJob : IJob + { + private const string LogMessageTitle = "Import Area IP Data"; + private readonly ApiConnection apiConnection; + private readonly GlobalConfig globalConfig; + + /// + /// Creates a new job for importing area IP data. + /// + /// GraphQL API connection. + /// Global configuration. + public ImportIpDataJob(ApiConnection apiConnection, GlobalConfig globalConfig) + { + this.apiConnection = apiConnection; + this.globalConfig = globalConfig; + } + + /// + public async Task Execute(IJobExecutionContext context) + { + Log.WriteDebug(LogMessageTitle, "Process started"); + + try + { + AreaIpDataImport import = new(apiConnection, globalConfig); + List failedImports = await import.Run(); + if (failedImports.Count > 0) + { + throw new ProcessingFailedException($"{LogMessageTitle} failed for {string.Join(", ", failedImports)}."); + } + } + catch (Exception exc) + { + await AlertHelper.LogErrorsWithAlert(apiConnection, globalConfig, 2, LogMessageTitle, GlobalConst.kImportAreaSubnetData, AlertCode.ImportAreaSubnetData, exc); + } + } + } +} diff --git a/roles/middleware/files/FWO.Middleware.Server/Jobs/ReportJob.cs b/roles/middleware/files/FWO.Middleware.Server/Jobs/ReportJob.cs new file mode 100644 index 0000000000..4a85c156ec --- /dev/null +++ b/roles/middleware/files/FWO.Middleware.Server/Jobs/ReportJob.cs @@ -0,0 +1,306 @@ +using FWO.Api.Client; +using FWO.Api.Client.Queries; +using FWO.Basics; +using FWO.Config.Api; +using FWO.Config.File; +using FWO.Data; +using FWO.Data.Report; +using FWO.Logging; +using FWO.Middleware.Server.Controllers; +using FWO.Report; +using FWO.Services; +using Quartz; + +namespace FWO.Middleware.Server.Jobs +{ + /// + /// Quartz job that checks report schedules and generates reports when due. + /// + [DisallowConcurrentExecution] + public class ReportJob : IJob + { + private const string LogMessageTitle = "Report Scheduling"; + private static readonly TimeSpan CheckScheduleInterval = TimeSpan.FromMinutes(1); + + private readonly ApiConnection apiConnectionScheduler; + private readonly JwtWriter jwtWriter; + private readonly string apiServerUri; + + /// + /// Creates a new report scheduling job. + /// + /// API connection used by the scheduler. + /// JWT writer to authorize users. + public ReportJob(ApiConnection apiConnectionScheduler, JwtWriter jwtWriter) + { + this.apiConnectionScheduler = apiConnectionScheduler; + this.jwtWriter = jwtWriter; + apiServerUri = ConfigFile.ApiServerUri ?? throw new ArgumentException("Missing api server url on startup."); + } + + /// + public async Task Execute(IJobExecutionContext context) + { + Log.WriteDebug(LogMessageTitle, "Process started"); + DateTime dateTimeNowRounded = RoundDown(DateTime.Now, CheckScheduleInterval); + List scheduledReports = await apiConnectionScheduler.SendQueryAsync>(ReportQueries.getReportSchedules); + + if (scheduledReports is null || scheduledReports.Count == 0) + { + return; + } + + await Parallel.ForEachAsync(scheduledReports, new ParallelOptions { MaxDegreeOfParallelism = Environment.ProcessorCount }, + async (reportSchedule, ct) => await ProcessScheduledReport(reportSchedule, dateTimeNowRounded, ct)); + } + + private async Task ProcessScheduledReport(ReportSchedule reportSchedule, DateTime dateTimeNowRounded, CancellationToken ct) + { + try + { + if (reportSchedule.Active) + { + // Add schedule interval as long as schedule time is smaller than current time + while (RoundDown(reportSchedule.StartTime, CheckScheduleInterval) < dateTimeNowRounded) + { + reportSchedule.StartTime = reportSchedule.RepeatInterval switch + { + SchedulerInterval.Days => reportSchedule.StartTime.AddDays(reportSchedule.RepeatOffset), + SchedulerInterval.Weeks => reportSchedule.StartTime.AddDays(reportSchedule.RepeatOffset * GlobalConst.kDaysPerWeek), + SchedulerInterval.Months => reportSchedule.StartTime.AddMonths(reportSchedule.RepeatOffset), + SchedulerInterval.Years => reportSchedule.StartTime.AddYears(reportSchedule.RepeatOffset), + SchedulerInterval.Never => reportSchedule.StartTime.AddYears(42_42), + _ => throw new NotSupportedException("Time interval is not supported."), + }; + } + + if (RoundDown(reportSchedule.StartTime, CheckScheduleInterval) == dateTimeNowRounded) + { + await GenerateReport(reportSchedule, dateTimeNowRounded, ct); + } + } + } + catch (Exception exception) + { + Log.WriteError(LogMessageTitle, "Checking scheduled reports lead to exception.", exception); + } + } + + private async Task GenerateReport(ReportSchedule reportSchedule, DateTime dateTimeNowRounded, CancellationToken token) + { + ApiConnection? apiConnectionUserContext = null; + UserConfig? userConfig = null; + + try + { + Log.WriteInfo(LogMessageTitle, $"Generating scheduled report \"{reportSchedule.Name}\" with id \"{reportSchedule.Id}\" for user \"{reportSchedule.ScheduleOwningUser.Name}\" with id \"{reportSchedule.ScheduleOwningUser.DbId}\" ..."); + + (apiConnectionUserContext, userConfig) = await InitUserEnvironment(reportSchedule); + if (apiConnectionUserContext == null || userConfig == null) + { + return; + } + + ReportFile reportFile = new() + { + Name = $"{reportSchedule.Name}_{dateTimeNowRounded.ToShortDateString()}", + GenerationDateStart = DateTime.Now, + TemplateId = reportSchedule.Template.Id, + OwningUserId = reportSchedule.ScheduleOwningUser.DbId, + Type = reportSchedule.Template.ReportParams.ReportType, + }; + + await apiConnectionUserContext.SendQueryAsync(ReportQueries.countReportSchedule, new { report_schedule_id = reportSchedule.Id }); + await AdaptDeviceFilter(reportSchedule.Template.ReportParams, apiConnectionUserContext); + + ReportBase? report = await ReportGenerator.GenerateFromTemplate(reportSchedule.Template, apiConnectionUserContext, userConfig, DefaultInit.DoNothing, token); + if (report != null) + { + await report.GetObjectsInReport(int.MaxValue, apiConnectionUserContext, _ => Task.CompletedTask); + + await WriteReportFile(report, reportSchedule.OutputFormat, reportFile); + + Log.WriteInfo(LogMessageTitle, $"Scheduled report \"{reportSchedule.Name}\" with id \"{reportSchedule.Id}\" for user \"{reportSchedule.ScheduleOwningUser.Name}\" with id \"{reportSchedule.ScheduleOwningUser.DbId}\" successfully generated."); + + if (reportSchedule.Archive) + { + await SaveReportToArchive(reportFile, report.SetDescription(), apiConnectionUserContext); + } + + if (reportSchedule.Notifications.Any()) + { + await TrySendReportViaEmail(reportSchedule, report, userConfig); + } + } + else + { + Log.WriteInfo(LogMessageTitle, $"Scheduled report \"{reportSchedule.Name}\" with id \"{reportSchedule.Id}\" for user \"{reportSchedule.ScheduleOwningUser.Name}\" with id \"{reportSchedule.ScheduleOwningUser.DbId}\" was empty."); + } + } + catch (TaskCanceledException) + { + Log.WriteWarning(LogMessageTitle, $"Generating scheduled report \"{reportSchedule.Name}\" was cancelled"); + } + catch (Exception exception) + { + Log.WriteError(LogMessageTitle, $"Generating scheduled report \"{reportSchedule.Name}\" with id \"{reportSchedule.Id}\" lead to exception.", exception); + } + finally + { + userConfig?.Dispose(); + userConfig = null; // Clear reference to prevent memory leak through exception stack traces + apiConnectionUserContext?.Dispose(); + apiConnectionUserContext = null; // Clear reference to prevent memory leak through exception stack traces + } + } + + private async Task<(ApiConnection?, UserConfig?)> InitUserEnvironment(ReportSchedule reportSchedule) + { + List connectedLdaps = await apiConnectionScheduler.SendQueryAsync>(AuthQueries.getLdapConnections); + AuthManager authManager = new(jwtWriter, connectedLdaps, apiConnectionScheduler); + string jwt = await authManager.AuthorizeUserAsync(reportSchedule.ScheduleOwningUser, validatePassword: false, lifetime: TimeSpan.FromDays(365)); + ApiConnection apiConnectionUserContext = new GraphQlApiConnection(apiServerUri, jwt); + GlobalConfig globalConfig = await GlobalConfig.ConstructAsync(jwt); + UserConfig userConfig = await UserConfig.ConstructAsync(globalConfig, apiConnectionUserContext, reportSchedule.ScheduleOwningUser.DbId); + + ReportType reportType = (ReportType)reportSchedule.Template.ReportParams.ReportType; + if (reportType.IsModellingReport() || reportType.IsWorkflowReport()) + { + userConfig.User.Roles = reportSchedule.ScheduleOwningUser.Roles; + userConfig.User.Groups = reportSchedule.ScheduleOwningUser.Groups; + await UiUserHandler.GetOwnershipsFromOwnerLdap(apiConnectionScheduler, userConfig.User); + Log.WriteDebug(LogMessageTitle, $"Scheduled report context: reportType={reportType}, reqOwnerBased={userConfig.ReqOwnerBased}, userId={userConfig.User.DbId}, roles=[{string.Join(", ", userConfig.User.Roles)}], groupCount={userConfig.User.Groups.Count}, ownershipCount={userConfig.User.Ownerships.Count}, ownerIds=[{string.Join(", ", userConfig.User.Ownerships)}]"); + } + + if (reportType.IsModellingReport()) + { + bool canAccessAllOwners = reportSchedule.ScheduleOwningUser.Roles.Contains(Roles.Admin) + || reportSchedule.ScheduleOwningUser.Roles.Contains(Roles.Auditor); + if (!canAccessAllOwners + && !userConfig.User.Ownerships.Contains(reportSchedule.Template.ReportParams.ModellingFilter.SelectedOwner.Id) + && !userConfig.User.Ownerships.Contains(0)) + { + Log.WriteInfo(LogMessageTitle, "Report not generated as owner is not valid anymore."); + return (null, null); + } + } + + return (apiConnectionUserContext, userConfig); + } + + private static async Task AdaptDeviceFilter(ReportParams reportParams, ApiConnection apiConnectionUser) + { + try + { + if (!reportParams.DeviceFilter.IsAnyDeviceFilterSet()) + { + // For scheduling no device selection means "all". + reportParams.DeviceFilter.Managements = await apiConnectionUser.SendQueryAsync>(DeviceQueries.getDevicesByManagement); + reportParams.DeviceFilter.ApplyFullDeviceSelection(true); + } + + if (reportParams.ReportType == (int)ReportType.UnusedRules) + { + reportParams.DeviceFilter = (await ReportDevicesBase.GetUsageDataUnsupportedDevices(apiConnectionUser, reportParams.DeviceFilter)).reducedDeviceFilter; + } + } + catch (Exception) + { + Log.WriteError(LogMessageTitle, "Could not adapt device filter."); + throw; + } + } + + private static async Task WriteReportFile(ReportBase report, List fileFormats, ReportFile reportFile) + { + reportFile.Json = report.ExportToJson(); + foreach (FileFormat format in fileFormats) + { + switch (format.Name) + { + case GlobalConst.kCsv: + if (report.ReportType.SupportsCsvExport(report.ReportData.WorkflowFilter.DetailedView)) + { + reportFile.Csv = report.ExportToCsv(); + } + else + { + Log.WriteInfo(LogMessageTitle, $"Skipping CSV export for report schedule output because report type {report.ReportType} does not support CSV in the current configuration."); + } + break; + + case GlobalConst.kHtml: + reportFile.Html = report.ExportToHtml(); + break; + + case GlobalConst.kPdf: + string html = report.ExportToHtml(); + reportFile.Pdf = await report.ToPdf(html); + break; + + case GlobalConst.kJson: + break; + + default: + throw new NotSupportedException("Output format is not supported."); + } + } + + reportFile.GenerationDateEnd = DateTime.Now; + } + + private static async Task SaveReportToArchive(ReportFile reportFile, string desc, ApiConnection apiConnectionUser) + { + try + { + var queryVariables = new + { + report_name = reportFile.Name, + report_start_time = reportFile.GenerationDateStart, + report_end_time = reportFile.GenerationDateEnd, + report_owner_id = reportFile.OwningUserId, + report_template_id = reportFile.TemplateId, + report_pdf = reportFile.Pdf, + report_csv = reportFile.Csv, + report_html = reportFile.Html, + report_json = reportFile.Json, + report_type = reportFile.Type, + description = desc, + read_only = false, + }; + + await apiConnectionUser.SendQueryAsync(ReportQueries.addGeneratedReport, queryVariables); + } + catch (Exception) + { + Log.WriteError(LogMessageTitle, $"Could not save report \"{reportFile.Name}\"."); + throw; + } + } + + /// + /// Sends report emails via the notification service for all persisted report notifications on the schedule. + /// + public async Task TrySendReportViaEmail(ReportSchedule reportSchedule, ReportBase report, UserConfig? userConfig = null) + { + if (userConfig?.GlobalConfig is GlobalConfig globalConfig) + { + NotificationService notificationService = await NotificationService.CreateAsync(NotificationClient.Report, globalConfig, apiConnectionScheduler, []); + await notificationService.SendBundledNotifications(reportSchedule.Notifications, null, null, report); + + int updatedNotifications = await notificationService.UpdateNotificationsLastSent(); + if (updatedNotifications > 0) + { + Log.WriteInfo(LogMessageTitle, "Report email notifications sent successfully."); + } + } + } + + + private static DateTime RoundDown(DateTime dateTime, TimeSpan roundInterval) + { + long delta = dateTime.Ticks % roundInterval.Ticks; + return new DateTime(dateTime.Ticks - delta, dateTime.Kind); + } + } +} diff --git a/roles/middleware/files/FWO.Middleware.Server/Jobs/UpdateRuleOwnerMappingJob.cs b/roles/middleware/files/FWO.Middleware.Server/Jobs/UpdateRuleOwnerMappingJob.cs new file mode 100644 index 0000000000..4cd3bfd4aa --- /dev/null +++ b/roles/middleware/files/FWO.Middleware.Server/Jobs/UpdateRuleOwnerMappingJob.cs @@ -0,0 +1,45 @@ +using FWO.Api.Client; +using FWO.Basics; +using FWO.Config.Api; +using FWO.Data; +using FWO.Services; +using Quartz; + +namespace FWO.Middleware.Server.Jobs +{ + /// + /// Quartz Job for update Rule Owner Mappings + /// + [DisallowConcurrentExecution] + public class UpdateRuleOwnerMappingJob : IJob + { + private const string LogMessageTitle = "Update rule_owner Notify"; + private readonly ApiConnection apiConnection; + private readonly GlobalConfig globalConfig; + + /// + /// Creates a new job for update Rule Owner Mappings. + /// + /// GraphQL API connection. + /// Global configuration. + public UpdateRuleOwnerMappingJob(ApiConnection apiConnection, GlobalConfig globalConfig) + { + this.apiConnection = apiConnection; + this.globalConfig = globalConfig; + } + + /// + public async Task Execute(IJobExecutionContext context) + { + try + { + UpdateRuleOwnerMapping updateRuleOwnerMapping = new(apiConnection, globalConfig); + await updateRuleOwnerMapping.Run(); + } + catch (Exception exc) + { + await AlertHelper.LogErrorsWithAlert(apiConnection, globalConfig, 1, LogMessageTitle, GlobalConst.kImportChangeNotify, AlertCode.ImportChangeNotify, exc); + } + } + } +} diff --git a/roles/middleware/files/FWO.Middleware.Server/Jobs/VarianceAnalysisJob.cs b/roles/middleware/files/FWO.Middleware.Server/Jobs/VarianceAnalysisJob.cs new file mode 100644 index 0000000000..148f076f22 --- /dev/null +++ b/roles/middleware/files/FWO.Middleware.Server/Jobs/VarianceAnalysisJob.cs @@ -0,0 +1,79 @@ +using FWO.Api.Client; +using FWO.Api.Client.Queries; +using FWO.Basics; +using FWO.Config.Api; +using FWO.Data; +using FWO.Data.Report; +using FWO.Logging; +using FWO.Report; +using FWO.Services; +using FWO.Services.Modelling; +using FWO.Services.Workflow; +using Quartz; + +namespace FWO.Middleware.Server.Jobs +{ + /// + /// Quartz Job for variance analysis + /// + [DisallowConcurrentExecution] + public class VarianceAnalysisJob : IJob + { + private const string LogMessageTitle = "Scheduled Variance Analysis"; + private readonly ApiConnection apiConnection; + private readonly GlobalConfig globalConfig; + + /// + /// Creates a new variance analysis job. + /// + /// GraphQL API connection. + /// Global configuration. + public VarianceAnalysisJob(ApiConnection apiConnection, GlobalConfig globalConfig) + { + this.apiConnection = apiConnection; + this.globalConfig = globalConfig; + } + + /// + public async Task Execute(IJobExecutionContext context) + { + await VarianceAnalysis(); + } + + private async Task VarianceAnalysis() + { + try + { + ExtStateHandler extStateHandler = new(apiConnection); + ModellingVarianceAnalysis? varianceAnalysis = null; + UserConfig userConfig = new(globalConfig) + { + RuleRecognitionOption = globalConfig.RuleRecognitionOption, + ModNamingConvention = globalConfig.ModNamingConvention, + ModModelledMarkerLocation = globalConfig.ModModelledMarkerLocation, + ModModelledMarker = globalConfig.ModModelledMarker + }; + + List owners = await apiConnection.SendQueryAsync>(OwnerQueries.getOwners); + ReportBase? report = await ReportGenerator.GenerateFromTemplate(new ReportTemplate("", new() { ReportType = (int)ReportType.Connections, ModellingFilter = new() { SelectedOwners = owners } }), apiConnection, userConfig, DefaultInit.DoNothing); + if (report == null || report.ReportData.OwnerData.Count == 0) + { + Log.WriteInfo(LogMessageTitle, "No data found."); + return; + } + foreach (OwnerConnectionReport owner in report.ReportData.OwnerData) + { + varianceAnalysis = new(apiConnection, extStateHandler, userConfig, owner.Owner, DefaultInit.DoNothing); + if (!await varianceAnalysis.AnalyseConnsForStatusAsync(owner.Connections)) + { + Log.WriteError(LogMessageTitle, $"Variance Analysis failed for owner {owner.Name}."); + } + } + } + catch (Exception exc) + { + await AlertHelper.LogErrorsWithAlert(apiConnection, globalConfig, 1, LogMessageTitle, GlobalConst.kVarianceAnalysis, AlertCode.VarianceAnalysis, exc); + } + } + } +} diff --git a/roles/middleware/files/FWO.Middleware.Server/JwtWriter.cs b/roles/middleware/files/FWO.Middleware.Server/JwtWriter.cs index cd5d01103b..273fe14536 100644 --- a/roles/middleware/files/FWO.Middleware.Server/JwtWriter.cs +++ b/roles/middleware/files/FWO.Middleware.Server/JwtWriter.cs @@ -1,32 +1,36 @@ -using FWO.Logging; +using FWO.Api.Client; +using FWO.Basics; +using FWO.Config.File; +using FWO.Data; +using FWO.Logging; +using Microsoft.IdentityModel.JsonWebTokens; using Microsoft.IdentityModel.Tokens; using System.IdentityModel.Tokens.Jwt; using System.Security.Claims; using System.Text.Json; -using FWO.Api.Data; namespace FWO.Middleware.Server { - /// - /// Class for jwt creation - /// + /// + /// Class for jwt creation + /// public class JwtWriter { private readonly RsaSecurityKey jwtPrivateKey; - /// - /// Constructor needing the private key - /// + /// + /// Constructor needing the private key + /// public JwtWriter(RsaSecurityKey jwtPrivateKey) { this.jwtPrivateKey = jwtPrivateKey; - JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Clear(); + JsonWebTokenHandler.DefaultInboundClaimTypeMap.Clear(); } - /// - /// create jwt for given user - /// - /// generated token + /// + /// create jwt for given user + /// + /// generated token public async Task CreateJWT(UiUser? user = null, TimeSpan? lifetime = null) { if (user != null) @@ -34,24 +38,27 @@ public async Task CreateJWT(UiUser? user = null, TimeSpan? lifetime = nu else Log.WriteDebug("Jwt generation", "Generating empty JWT (startup)"); - JwtSecurityTokenHandler tokenHandler = new JwtSecurityTokenHandler(); + JwtSecurityTokenHandler tokenHandler = new(); - UiUserHandler uiUserHandler = new UiUserHandler(CreateJWTMiddlewareServer()); + GraphQlApiConnection apiConnection = new(ConfigFile.ApiServerUri, CreateJWTMiddlewareServer()); // if lifetime was speciefied use it, otherwise use standard lifetime - int jwtMinutesValid = (int)(lifetime?.TotalMinutes ?? await uiUserHandler.GetExpirationTime()); + int jwtMinutesValid = (int)(lifetime?.TotalMinutes ?? await UiUserHandler.GetExpirationTime(apiConnection)); ClaimsIdentity subject; if (user != null) - subject = SetClaims(await uiUserHandler.HandleUiUserAtLogin(user)); + subject = SetClaims(await UiUserHandler.HandleUiUserAtLogin(apiConnection, user)); else - subject = SetClaims(new UiUser() { Name = "", Password = "", Dn = "anonymous", Roles = new List { "anonymous" } }); + subject = SetClaims(new UiUser() { Name = "", Password = "", Dn = Roles.Anonymous, Roles = [Roles.Anonymous] }); // adding uiuser.uiuser_id as x-hasura-user-id to JWT + // Dispose Api Connection + apiConnection.Dispose(); + // Create JWToken JwtSecurityToken token = tokenHandler.CreateJwtSecurityToken ( - issuer: JwtConstants.Issuer, - audience: JwtConstants.Audience, + issuer: FWO.Basics.JwtConstants.Issuer, + audience: FWO.Basics.JwtConstants.Audience, subject: subject, notBefore: DateTime.UtcNow.AddMinutes(-1), // we currently allow for some deviation in timing of the systems issuedAt: DateTime.UtcNow.AddMinutes(-1), @@ -62,9 +69,9 @@ public async Task CreateJWT(UiUser? user = null, TimeSpan? lifetime = nu string GeneratedToken = tokenHandler.WriteToken(token); if (user != null) - Log.WriteDebug("Jwt generation", $"Generated JWT {GeneratedToken} for User {user.Name}"); + Log.WriteDebug("Jwt generation", $"Generated JWT {token.RawData} for User {user.Name}"); else - Log.WriteDebug("Jwt generation", $"Generated JWT {GeneratedToken}"); + Log.WriteDebug("Jwt generation", $"Generated JWT {token.RawData}"); return GeneratedToken; } @@ -75,7 +82,7 @@ public async Task CreateJWT(UiUser? user = null, TimeSpan? lifetime = nu /// JWT for middleware-server role. public string CreateJWTMiddlewareServer() { - return CreateJWTInternal("middleware-server"); + return CreateJWTInternal(Roles.MiddlewareServer); } /// @@ -85,21 +92,21 @@ public string CreateJWTMiddlewareServer() /// JWT for reporter-viewall role. public string CreateJWTReporterViewall() { - return CreateJWTInternal("reporter-viewall"); + return CreateJWTInternal(Roles.ReporterViewAll); } private string CreateJWTInternal(string role) { - JwtSecurityTokenHandler tokenHandler = new JwtSecurityTokenHandler(); - ClaimsIdentity subject = new ClaimsIdentity(); + JwtSecurityTokenHandler tokenHandler = new(); + ClaimsIdentity subject = new(); subject.AddClaim(new Claim("unique_name", role)); - subject.AddClaim(new Claim("x-hasura-allowed-roles", JsonSerializer.Serialize(new string[] { role }), JsonClaimValueTypes.JsonArray)); + subject.AddClaim(new Claim("x-hasura-allowed-roles", JsonSerializer.Serialize(new string[] { role }), System.IdentityModel.Tokens.Jwt.JsonClaimValueTypes.JsonArray)); subject.AddClaim(new Claim("x-hasura-default-role", role)); JwtSecurityToken token = tokenHandler.CreateJwtSecurityToken ( - issuer: JwtConstants.Issuer, - audience: JwtConstants.Audience, + issuer: FWO.Basics.JwtConstants.Issuer, + audience: FWO.Basics.JwtConstants.Audience, subject: subject, notBefore: DateTime.UtcNow.AddMinutes(-1), // we currently allow for some deviation in timing of the systems issuedAt: DateTime.UtcNow.AddMinutes(-1), @@ -111,50 +118,70 @@ private string CreateJWTInternal(string role) return GeneratedToken; } - private ClaimsIdentity SetClaims(UiUser user) + private static ClaimsIdentity SetClaims(UiUser user) { - ClaimsIdentity claimsIdentity = new ClaimsIdentity(); + ClaimsIdentity claimsIdentity = new(); claimsIdentity.AddClaim(new Claim(ClaimTypes.Name, user.Name)); claimsIdentity.AddClaim(new Claim("x-hasura-user-id", user.DbId.ToString())); if (user.Dn != null && user.Dn.Length > 0) claimsIdentity.AddClaim(new Claim("x-hasura-uuid", user.Dn)); // UUID used for access to reports via API - - if (user.Tenant != null && user.Tenant.VisibleDevices != null && user.Tenant.VisibleManagements != null) - { - // Hasura needs object {} instead of array [] notation (TODO: Changable?) + + int[] visibleManagementIds = user.Tenant?.VisibleManagementIds ?? []; + int[] visibleGatewayIds = user.Tenant?.VisibleGatewayIds ?? []; + + if (user.Tenant != null) + { claimsIdentity.AddClaim(new Claim("x-hasura-tenant-id", user.Tenant.Id.ToString())); - claimsIdentity.AddClaim(new Claim("x-hasura-visible-managements", $"{{ {string.Join(",", user.Tenant.VisibleManagements)} }}")); - claimsIdentity.AddClaim(new Claim("x-hasura-visible-devices", $"{{ {string.Join(",", user.Tenant.VisibleDevices)} }}")); } + // Hasura role permissions reference these session variables. Always provide them, + // even when tenant resolution fails, to avoid runtime "missing session variable" errors. + claimsIdentity.AddClaim(new Claim("x-hasura-visible-managements", ToHasuraIdSet(visibleManagementIds))); + claimsIdentity.AddClaim(new Claim("x-hasura-visible-devices", ToHasuraIdSet(visibleGatewayIds))); + claimsIdentity.AddClaim(new Claim("x-hasura-editable-owners", $"{{ {string.Join(",", user.Ownerships)} }}")); + claimsIdentity.AddClaim(new Claim("x-hasura-recertifiable-owners", $"{{ {string.Join(",", user.RecertOwnerships)} }}")); + AddRoleClaims(claimsIdentity, user); + return claimsIdentity; + } - // we need to create an extra list because hasura only accepts an array of roles even if there is only one - List hasuraRolesList = new List(); + private static string ToHasuraIdSet(IEnumerable ids) + { + int[] idList = ids.ToArray(); + return idList.Length > 0 ? $"{{{string.Join(",", idList)}}}" : "{}"; + } + private static void AddRoleClaims(ClaimsIdentity claimsIdentity, UiUser user) + { + // we need to create an extra list because hasura only accepts an array of roles even if there is only one + List hasuraRolesList = []; foreach (string role in user.Roles) { claimsIdentity.AddClaim(new Claim(ClaimTypes.Role, role)); // Frontend Roles hasuraRolesList.Add(role); // Hasura Roles } - // add hasura roles claim as array - claimsIdentity.AddClaim(new Claim("x-hasura-allowed-roles", JsonSerializer.Serialize(hasuraRolesList.ToArray()), JsonClaimValueTypes.JsonArray)); // Convert Hasura Roles to Array + claimsIdentity.AddClaim(new Claim("x-hasura-allowed-roles", JsonSerializer.Serialize(hasuraRolesList.ToArray()), System.IdentityModel.Tokens.Jwt.JsonClaimValueTypes.JsonArray)); // Convert Hasura Roles to Array + claimsIdentity.AddClaim(new Claim("x-hasura-default-role", GetDefaultRole(user, hasuraRolesList))); + } - // deciding on default-role + private static string GetDefaultRole(UiUser user, List hasuraRolesList) + { string defaultRole = ""; if (user.Roles.Count > 0) { - if (hasuraRolesList.Contains("admin")) - defaultRole = "admin"; - else if (hasuraRolesList.Contains("auditor")) - defaultRole = "auditor"; - else if (hasuraRolesList.Contains("fw-admin")) - defaultRole = "fw-admin"; - else if (hasuraRolesList.Contains("reporter-viewall")) - defaultRole = "reporter-viewall"; - else if (hasuraRolesList.Contains("reporter")) - defaultRole = "reporter"; - else if (hasuraRolesList.Contains("recertifier")) - defaultRole = "recertifier"; + if (hasuraRolesList.Contains(Roles.Admin)) + defaultRole = Roles.Admin; + else if (hasuraRolesList.Contains(Roles.Auditor)) + defaultRole = Roles.Auditor; + else if (hasuraRolesList.Contains(Roles.FwAdmin)) + defaultRole = Roles.FwAdmin; + else if (hasuraRolesList.Contains(Roles.ReporterViewAll)) + defaultRole = Roles.ReporterViewAll; + else if (hasuraRolesList.Contains(Roles.Reporter)) + defaultRole = Roles.Reporter; + else if (hasuraRolesList.Contains(Roles.Recertifier)) + defaultRole = Roles.Recertifier; + else if (hasuraRolesList.Contains(Roles.Modeller)) + defaultRole = Roles.Modeller; else defaultRole = user.Roles[0]; // pick first role at random (todo: might need to be changed) } @@ -162,9 +189,7 @@ private ClaimsIdentity SetClaims(UiUser user) { Log.WriteError("User roles", $"User {user.Name} does not have any assigned roles."); } - - claimsIdentity.AddClaim(new Claim("x-hasura-default-role", defaultRole)); - return claimsIdentity; + return defaultRole; } } } diff --git a/roles/middleware/files/FWO.Middleware.Server/Ldap.cs b/roles/middleware/files/FWO.Middleware.Server/Ldap.cs deleted file mode 100644 index 9d4dec208d..0000000000 --- a/roles/middleware/files/FWO.Middleware.Server/Ldap.cs +++ /dev/null @@ -1,996 +0,0 @@ -using FWO.Logging; -using Novell.Directory.Ldap; -using System.Net.Security; -using System.Security.Cryptography.X509Certificates; -using FWO.Api.Data; -using FWO.Middleware.RequestParameters; -using Microsoft.IdentityModel.Tokens; - -namespace FWO.Middleware.Server -{ - /// - /// Class handling the ldap transactions - /// - public class Ldap : LdapConnectionBase - { - // The following properties are retrieved from the database api: - // ldap_server ldap_port ldap_search_user ldap_tls ldap_tenant_level ldap_connection_id ldap_search_user_pwd ldap_searchpath_for_users ldap_searchpath_for_roles - private const int timeOutInMs = 3000; - - /// - /// Default constructor - /// - public Ldap() - {} - - /// - /// Constructor from parameter struct - /// - public Ldap(LdapGetUpdateParameters ldapGetUpdateParameters) : base(ldapGetUpdateParameters) - {} - - /// - /// Builds a connection to the specified Ldap server. - /// - /// Connection to the specified Ldap server. - private LdapConnection Connect() - { - try - { - LdapConnectionOptions ldapOptions = new LdapConnectionOptions(); - if (Tls) ldapOptions.ConfigureRemoteCertificateValidationCallback((object sen, X509Certificate? cer, X509Chain? cha, SslPolicyErrors err) => true); // todo: allow real cert validation - LdapConnection connection = new LdapConnection(ldapOptions) { SecureSocketLayer = Tls, ConnectionTimeout = timeOutInMs }; - connection.Connect(Address, Port); - - return connection; - } - - catch (Exception exception) - { - Log.WriteDebug($"Could not connect to LDAP server {Address}:{Port}: ", exception.Message); - throw new Exception($"Error while trying to reach LDAP server {Address}:{Port}", exception); - } - } - - /// - /// Test a connection to the specified Ldap server. - /// Throws exception if not successful - /// - public void TestConnection() - { - using (LdapConnection connection = Connect()) - { - if (!string.IsNullOrEmpty(SearchUser)) - { - connection.Bind(SearchUser, SearchUserPwd); - if (!connection.Bound) throw new Exception("Binding failed for search user"); - } - if (!string.IsNullOrEmpty(WriteUser)) - { - connection.Bind(WriteUser, WriteUserPwd); - if (!connection.Bound) throw new Exception("Binding failed for write user"); - } - } - } - - private string getUserSearchFilter(string searchPattern) - { - string userFilter; - string searchFilter; - if(Type == (int)LdapType.ActiveDirectory) - { - userFilter = "(&(objectclass=user)(!(objectclass=computer)))"; - searchFilter = $"(|(cn={searchPattern})(sAMAccountName={searchPattern}))"; - } - else if(Type == (int)LdapType.OpenLdap) - { - userFilter = "(|(objectclass=user)(objectclass=person)(objectclass=inetOrgPerson)(objectclass=organizationalPerson))"; - searchFilter = $"(|(cn={searchPattern})(uid={searchPattern}))"; - } - else // LdapType.Default - { - userFilter = "(&(|(objectclass=user)(objectclass=person)(objectclass=inetOrgPerson)(objectclass=organizationalPerson))(!(objectclass=computer)))"; - searchFilter = $"(|(cn={searchPattern})(uid={searchPattern})(userPrincipalName={searchPattern})(mail={searchPattern}))"; - } - return ((searchPattern == null || searchPattern == "") ? userFilter : $"(&{userFilter}{searchFilter})"); - } - - private string getGroupSearchFilter(string searchPattern) - { - string groupFilter; - string searchFilter; - if(Type == (int)LdapType.ActiveDirectory) - { - groupFilter = "(objectClass=group)"; - searchFilter = $"(|(cn={searchPattern})(name={searchPattern}))"; - } - else if(Type == (int)LdapType.OpenLdap) - { - groupFilter = "(|(objectclass=group)(objectclass=groupofnames)(objectclass=groupofuniquenames))"; - searchFilter = $"(cn={searchPattern})"; - } - else // LdapType.Default - { - groupFilter = "(|(objectclass=group)(objectclass=groupofnames)(objectclass=groupofuniquenames))"; - searchFilter = $"(|(dc={searchPattern})(o={searchPattern})(ou={searchPattern})(cn={searchPattern})(uid={searchPattern})(mail={searchPattern}))"; - } - return ((searchPattern == null || searchPattern == "") ? groupFilter : $"(&{groupFilter}{searchFilter})"); - } - - /// - /// Get the LdapEntry for the given user with option to validate credentials - /// - /// LdapEntry for the given user if found - public LdapEntry? GetLdapEntry(UiUser user, bool validateCredentials) - { - Log.WriteDebug("User Validation", $"Validating User: \"{user.Name}\" ..."); - try - { - // Connecting to Ldap - using (LdapConnection connection = Connect()) - { - // Authenticate as search user - connection.Bind(SearchUser, SearchUserPwd); - - LdapSearchConstraints cons = connection.SearchConstraints; - cons.ReferralFollowing = true; - connection.Constraints = cons; - - List possibleUserEntries = new List(); - - // If dn was already provided - if (!user.Dn.IsNullOrEmpty()) - { - // Try to read user entry directly - LdapEntry? userEntry = connection.Read(user.Dn); - if (userEntry != null) - { - possibleUserEntries.Add(userEntry); - } - } - else // Dn was not provided, search for user name - { - string[] attrList = new string[] { "*", "memberof" }; - string userSearchFilter = getUserSearchFilter(user.Name); - - // Search for users in ldap with same name as user to validate - possibleUserEntries = ((LdapSearchResults)connection.Search( - UserSearchPath, // top-level path under which to search for user - LdapConnection.ScopeSub, // search all levels beneath - userSearchFilter, - attrList, - typesOnly: false - )).ToList(); - } - - // If credentials are not checked return user that was found first - // It could happen that multiple users with the same name were found (impossible if dn was provided) - if (!validateCredentials && possibleUserEntries.Count > 0) - { - return possibleUserEntries.First(); - } - // If credentials should be checked - else if (validateCredentials) - { - // Multiple users with the same name could have been found (impossible if dn was provided) - foreach (LdapEntry possibleUserEntry in possibleUserEntries) - { - // Check credentials - if multiple users were found and the credentials are valid this is most definitely the correct user - if (CredentialsValid(connection, possibleUserEntry.Dn, user.Password)) - { - return possibleUserEntry; - } - } - } - } - } - catch (LdapException ldapException) - { - Log.WriteInfo("Ldap entry exception", $"Ldap entry search at \"{Address}:{Port}\" lead to exception: {ldapException.Message}"); - } - catch (Exception exception) - { - Log.WriteError($"Non-LDAP exception \"{Address}:{Port}\"", "Unexpected error while trying to validate user", exception); - } - - Log.WriteDebug("Invalid Credentials", $"Invalid login credentials - could not authenticate user \"{ user.Name}\" on {Address}:{Port}."); - return null; - } - - private bool CredentialsValid(LdapConnection connection, string dn, string password) - { - try - { - Log.WriteDebug("User Validation", $"Trying to validate user with distinguished name: \"{dn}\" ..."); - - // Try to authenticate as user with given password - connection.Bind(dn, password); - - // If authentication was successful (user is bound) - if (connection.Bound) - { - // Return ldap dn - Log.WriteDebug("User Validation", $"\"{dn}\" successfully authenticated in {Address}:{Port}."); - return true; - } - else - { - // this will probably never be reached as an error is thrown before - // Incorrect password - do nothing, assume its another user with the same username - Log.WriteDebug($"User Validation {Address}:{Port}", $"Found user with matching uid but different pwd: \"{dn}\"."); - } - } - catch (LdapException exc) - { - if (exc.ResultCode == 49) // 49 = InvalidCredentials - Log.WriteDebug($"Duplicate user {Address}:{Port}", $"Found user with matching uid but different pwd: \"{dn}\"."); - else - Log.WriteError($"Ldap exception {Address}:{Port}", $"Unexpected error while trying to validate user \"{dn}\"."); - } - return false; - } - - /// - /// Get the EmailAddress for the given user - /// - /// EmailAddress of the given user - public string GetEmail(LdapEntry user) - { - return user.GetAttributeSet().ContainsKey("mail") ? user.GetAttribute("mail").StringValue : ""; - } - - /// - /// Get the groups for the given user - /// - /// list of groups for the given user - public List GetGroups(LdapEntry user) - { - // Simplest way as most ldap types should provide the memberof attribute. - // - Probably this doesn't work for nested groups. - // - Some systems may only save the "primaryGroupID", then we would have to resolve the name. - // - Some others may force us to look into all groups to find the membership. - List groups = new List(); - foreach (var attribute in user.GetAttributeSet()) - { - if (attribute.Name.ToLower() == "memberof") - { - foreach (string membership in attribute.StringValueArray) - { - if (GroupSearchPath != null && membership.EndsWith(GroupSearchPath)) - { - groups.Add(membership); - } - } - } - } - return groups; - } - - /// - /// Change the password of the given user - /// - /// error message if not successful - public string ChangePassword(string userDn, string oldPassword, string newPassword) - { - try - { - // Connecting to Ldap - using (LdapConnection connection = Connect()) - { - // Try to authenticate as user with old password - connection.Bind(userDn, oldPassword); - - if (connection.Bound) - { - // authentication was successful (user is bound): set new password - LdapAttribute attribute = new LdapAttribute("userPassword", newPassword); - LdapModification[] mods = { new LdapModification(LdapModification.Replace, attribute) }; - - connection.Modify(userDn, mods); - Log.WriteDebug("Change password", $"Password for user {userDn} changed in {Address}:{Port}"); - } - else - { - return "wrong old password"; - } - } - } - catch (Exception exception) - { - return exception.Message; - } - return ""; - } - - /// - /// Set the password of the given user - /// - /// error message if not successful - public string SetPassword(string userDn, string newPassword) - { - try - { - // Connecting to Ldap - using (LdapConnection connection = Connect()) - { - // Authenticate as write user - connection.Bind(WriteUser, WriteUserPwd); - if (connection.Bound) - { - // authentication was successful: set new password - LdapAttribute attribute = new LdapAttribute("userPassword", newPassword); - LdapModification[] mods = { new LdapModification(LdapModification.Replace, attribute) }; - - connection.Modify(userDn, mods); - Log.WriteDebug("Change password", $"Password for user {userDn} changed in {Address}:{Port}"); - } - else - { - return "error in write user authentication"; - } - } - } - catch (Exception exception) - { - return exception.Message; - } - return ""; - } - - /// - /// Get the roles for the given DN list - /// - /// list of roles for the given DN list - public List GetRoles(List dnList) - { - return GetMemberships(dnList, RoleSearchPath); - } - - /// - /// Get the groups for the given DN list - /// - /// list of groups for the given DN list - public List GetGroups(List dnList) - { - return GetMemberships(dnList, GroupSearchPath); - } - - private List GetMemberships(List dnList, string? searchPath) - { - List userMemberships = new List(); - - // If this Ldap is containing roles / groups - if (searchPath != null && searchPath != "") - { - try - { - // Connect to Ldap - using (LdapConnection connection = Connect()) - { - // Authenticate as search user - connection.Bind(SearchUser, SearchUserPwd); - - // Search for Ldap roles / groups in given directory - int searchScope = LdapConnection.ScopeSub; // TODO: Correct search scope? - string searchFilter = $"(&(objectClass=groupOfUniqueNames)(cn=*))"; - LdapSearchResults searchResults = (LdapSearchResults)connection.Search(searchPath, searchScope, searchFilter, null, false); - - // convert dnList to lower case to avoid case problems - dnList = dnList.ConvertAll(dn => dn.ToLower()); - - // Foreach found role / group - foreach (LdapEntry entry in searchResults) - { - Log.WriteDebug("Ldap Roles/Groups", $"Try to get roles / groups from ldap entry {entry.GetAttribute("cn").StringValue}"); - - // Get dn of users having current role / group - LdapAttribute members = entry.GetAttribute("uniqueMember"); - string[] memberDn = members.StringValueArray; - - // Foreach user - foreach (string currentDn in memberDn) - { - Log.WriteDebug("Ldap Roles/Groups", $"Checking if current Dn: \"{currentDn}\" is user Dn. Then user has current role / group."); - - // Check if current user dn is matching with given user dn => Given user has current role / group - if (dnList.Contains(currentDn.ToLower())) - { - // Get name and add it to list of roles / groups of given user - string name = entry.GetAttribute("cn").StringValue; - userMemberships.Add(name); - break; - } - } - } - } - } - catch (Exception exception) - { - Log.WriteError($"Non-LDAP exception {Address}:{Port}", "Unexpected error while trying to get memberships", exception); - } - } - - Log.WriteDebug($"Found the following roles / groups for user {dnList.FirstOrDefault()} in {Address}:{Port}:", string.Join("\n", userMemberships)); - return userMemberships; - } - - /// - /// Get all roles - /// - /// list of roles - public List GetAllRoles() - { - List roleUsers = new List(); - - // If this Ldap is containing roles - if (HasRoleHandling()) - { - try - { - // Connect to Ldap - using (LdapConnection connection = Connect()) - { - // Authenticate as search user - connection.Bind(SearchUser, SearchUserPwd); - - // Search for Ldap roles in given directory - int searchScope = LdapConnection.ScopeSub; // TODO: Correct search scope? - string searchFilter = $"(&(objectClass=groupOfUniqueNames)(cn=*))"; - LdapSearchResults searchResults = (LdapSearchResults)connection.Search(RoleSearchPath, searchScope, searchFilter, null, false); - - // Foreach found role - foreach (LdapEntry entry in searchResults) - { - List attributes = new List(); - string roleDesc = entry.GetAttribute("description").StringValue; - attributes.Add(new RoleAttribute(){ Key = "description", Value = roleDesc }); - - string[] roleMemberDn = entry.GetAttribute("uniqueMember").StringValueArray; - foreach (string currentDn in roleMemberDn) - { - if (currentDn != "") - { - attributes.Add(new RoleAttribute(){ Key = "user", Value = currentDn }); - } - } - roleUsers.Add(new RoleGetReturnParameters(){ Role = entry.Dn, Attributes = attributes}); - } - } - } - catch (Exception exception) - { - Log.WriteError($"Non-LDAP exception {Address}:{Port}", "Unexpected error while trying to get all roles", exception); - } - } - return roleUsers; - } - - /// - /// Search all groups with search pattern - /// - /// list of groups - public List GetAllGroups(string searchPattern) - { - List allGroups = new List(); - try - { - // Connect to Ldap - using (LdapConnection connection = Connect()) - { - // Authenticate as search user - connection.Bind(SearchUser, SearchUserPwd); - - // Search for Ldap groups in given directory - int searchScope = LdapConnection.ScopeSub; - LdapSearchResults searchResults = (LdapSearchResults)connection.Search(GroupSearchPath, searchScope, getGroupSearchFilter(searchPattern), null, false); - - foreach (LdapEntry entry in searchResults) - { - allGroups.Add(entry.Dn); - } - } - } - catch (Exception exception) - { - Log.WriteError($"Non-LDAP exception {Address}:{Port}", "Unexpected error while trying to get all groups", exception); - } - return allGroups; - } - - /// - /// Get all internal groups - /// - /// list of groups - public List GetAllInternalGroups() - { - List allGroups = new List(); - - try - { - // Connect to Ldap - using (LdapConnection connection = Connect()) - { - // Authenticate as search user - connection.Bind(SearchUser, SearchUserPwd); - - // Search for Ldap groups in given directory - int searchScope = LdapConnection.ScopeSub; - LdapSearchResults searchResults = (LdapSearchResults)connection.Search(GroupSearchPath, searchScope, getGroupSearchFilter(""), null, false); - - foreach (LdapEntry entry in searchResults) - { - List members = new List(); - string[] groupMemberDn = entry.GetAttribute("uniqueMember").StringValueArray; - foreach (string currentDn in groupMemberDn) - { - if (currentDn != "") - { - members.Add(currentDn); - } - } - allGroups.Add(new GroupGetReturnParameters() - { - GroupDn = entry.Dn, - Members = members, - OwnerGroup = (entry.GetAttributeSet().ContainsKey("businessCategory") ? (entry.GetAttribute("businessCategory").StringValue.ToLower() == "ownergroup") : false) - }); - } - } - } - catch (Exception exception) - { - Log.WriteError($"Non-LDAP exception {Address}:{Port}", "Unexpected error while trying to get all internal groups", exception); - } - return allGroups; - } - - /// - /// Search all users with search pattern - /// - /// list of users - public List GetAllUsers(string searchPattern) - { - Log.WriteDebug("GetAllUsers", $"Looking for users with pattern {searchPattern} in {Address}:{Port}"); - List allUsers = new List(); - - try - { - // Connect to Ldap - using (LdapConnection connection = Connect()) - { - // Authenticate as search user - connection.Bind(SearchUser, SearchUserPwd); - - // Search for Ldap users in given directory - int searchScope = LdapConnection.ScopeSub; - - LdapSearchConstraints cons = connection.SearchConstraints; - cons.ReferralFollowing = true; - connection.Constraints = cons; - - LdapSearchResults searchResults = (LdapSearchResults)connection.Search(UserSearchPath, searchScope, getUserSearchFilter(searchPattern), null, false); - - foreach (LdapEntry entry in searchResults) - { - allUsers.Add(new LdapUserGetReturnParameters() - { - UserDn = entry.Dn, - Email = (entry.GetAttributeSet().ContainsKey("mail") ? entry.GetAttribute("mail").StringValue : null) - }); - } - } - } - catch (Exception exception) - { - Log.WriteError($"Non-LDAP exception {Address}:{Port}", "Unexpected error while trying to get all users", exception); - } - return allUsers; - } - - /// - /// Add new user - /// - /// true if user added - public bool AddUser(string userDn , string password, string email) - { - Log.WriteInfo("Add User", $"Trying to add User: \"{userDn}\""); - bool userAdded = false; - try - { - // Connecting to Ldap - using (LdapConnection connection = Connect()) - { - // Authenticate as write user - connection.Bind(WriteUser, WriteUserPwd); - - string userName = (new FWO.Api.Data.DistName(userDn)).UserName; - LdapAttributeSet attributeSet = new LdapAttributeSet - { - new LdapAttribute("objectclass", "inetOrgPerson"), - new LdapAttribute("sn", userName), - new LdapAttribute("cn", userName), - new LdapAttribute("uid", userName), - new LdapAttribute("userPassword", password), - new LdapAttribute("mail", email) - }; - - LdapEntry newEntry = new LdapEntry( userDn, attributeSet ); - - try - { - //Add the entry to the directory - connection.Add(newEntry); - userAdded = true; - Log.WriteDebug("Add user", $"User {userName} added in {Address}:{Port}"); - } - catch(Exception exception) - { - Log.WriteInfo("Add User", $"couldn't add user to LDAP {Address}:{Port}: {exception.ToString()}"); - } - } - } - catch (Exception exception) - { - Log.WriteError($"Non-LDAP exception {Address}:{Port}", "Unexpected error while trying to add user", exception); - } - return userAdded; - } - - /// - /// Update user - /// - /// true if user updated - public bool UpdateUser(string userDn, string email) - { - Log.WriteInfo("Update User", $"Trying to update User: \"{userDn}\""); - bool userUpdated = false; - try - { - // Connecting to Ldap - using (LdapConnection connection = Connect()) - { - // Authenticate as write user - connection.Bind(WriteUser, WriteUserPwd); - - LdapAttribute attribute = new LdapAttribute("mail", email); - LdapModification[] mods = { new LdapModification(LdapModification.Replace, attribute) }; - - try - { - //Add the entry to the directory - connection.Modify(userDn, mods); - userUpdated = true; - Log.WriteDebug("Update user", $"User {userDn} updated in {Address}:{Port}"); - } - catch(Exception exception) - { - Log.WriteInfo("Update User", $"couldn't update user in LDAP {Address}:{Port}: {exception.ToString()}"); - } - } - } - catch (Exception exception) - { - Log.WriteError($"Non-LDAP exception {Address}:{Port}", "Unexpected error while trying to update user", exception); - } - return userUpdated; - } - - /// - /// Delete user - /// - /// true if user deleted - public bool DeleteUser(string userDn) - { - Log.WriteInfo("Delete User", $"Trying to delete User: \"{userDn}\""); - bool userDeleted = false; - try - { - // Connecting to Ldap - using (LdapConnection connection = Connect()) - { - // Authenticate as write user - connection.Bind(WriteUser, WriteUserPwd); - - try - { - //Delete the entry in the directory - connection.Delete(userDn); - userDeleted = true; - Log.WriteDebug("Delete user", $"User {userDn} deleted in {Address}:{Port}"); - } - catch(Exception exception) - { - Log.WriteInfo("Delete User", $"couldn't delete user in LDAP {Address}:{Port}: {exception.ToString()}"); - } - } - } - catch (Exception exception) - { - Log.WriteError($"Non-LDAP exception {Address}:{Port}", "Unexpected error while trying to delete user", exception); - } - return userDeleted; - } - - /// - /// Add new group - /// - /// group DN if user added - public string AddGroup(string groupName, bool ownerGroup) - { - Log.WriteInfo("Add Group", $"Trying to add Group: \"{groupName}\""); - bool groupAdded = false; - string groupDn = ""; - try - { - // Connecting to Ldap - using (LdapConnection connection = Connect()) - { - // Authenticate as write user - connection.Bind(WriteUser, WriteUserPwd); - - groupDn = $"cn={groupName},{GroupSearchPath}"; - LdapAttributeSet attributeSet = new LdapAttributeSet(); - attributeSet.Add( new LdapAttribute("objectclass", "groupofuniquenames")); - attributeSet.Add( new LdapAttribute("uniqueMember", "")); - if (ownerGroup) - { - attributeSet.Add( new LdapAttribute("businessCategory", "ownergroup")); - } - - LdapEntry newEntry = new LdapEntry( groupDn, attributeSet ); - - try - { - //Add the entry to the directory - connection.Add(newEntry); - groupAdded = true; - Log.WriteDebug("Add group", $"Group {groupName} added in {Address}:{Port}"); - } - catch(Exception exception) - { - Log.WriteInfo("Add Group", $"couldn't add group to LDAP {Address}:{Port}: {exception.ToString()}"); - } - } - } - catch (Exception exception) - { - Log.WriteError($"Non-LDAP exception {Address}:{Port}", "Unexpected error while trying to add group", exception); - } - return (groupAdded ? groupDn : ""); - } - - /// - /// Update group name - /// - /// new group DN if group updated - public string UpdateGroup(string oldName, string newName) - { - Log.WriteInfo("Update Group", $"Trying to update Group: \"{oldName}\""); - bool groupUpdated = false; - string oldGroupDn = $"cn={oldName},{GroupSearchPath}"; - string newGroupRdn = $"cn={newName}"; - - try - { - // Connecting to Ldap - using (LdapConnection connection = Connect()) - { - // Authenticate as write user - connection.Bind(WriteUser, WriteUserPwd); - - try - { - //Add the entry to the directory - connection.Rename(oldGroupDn, newGroupRdn, true); - groupUpdated = true; - Log.WriteDebug("Update group", $"Group {oldName} renamed to {newName} in {Address}:{Port}"); - } - catch(Exception exception) - { - Log.WriteInfo("Update Group", $"couldn't update group in LDAP {Address}:{Port}: {exception.ToString()}"); - } - } - } - catch (Exception exception) - { - Log.WriteError($"Non-LDAP exception {Address}:{Port}", "Unexpected error while trying to update group", exception); - } - return (groupUpdated ? $"{newGroupRdn},{GroupSearchPath}" : ""); - } - - /// - /// Delete group - /// - /// true if group deleted - public bool DeleteGroup(string groupName) - { - Log.WriteInfo("Delete Group", $"Trying to delete Group: \"{groupName}\""); - bool groupDeleted = false; - try - { - // Connecting to Ldap - using (LdapConnection connection = Connect()) - { - // Authenticate as write user - connection.Bind(WriteUser, WriteUserPwd); - - try - { - //Delete the entry in the directory - string groupDn = $"cn={groupName},{GroupSearchPath}"; - connection.Delete(groupDn); - groupDeleted = true; - Log.WriteDebug("Delete group", $"Group {groupName} deleted in {Address}:{Port}"); - } - catch(Exception exception) - { - Log.WriteInfo("Delete Group", $"couldn't delete group in LDAP {Address}:{Port}: {exception.ToString()}"); - } - } - } - catch (Exception exception) - { - Log.WriteError($"Non-LDAP exception {Address}:{Port}", "Unexpected error while trying to delete group", exception); - } - return groupDeleted; - } - - /// - /// Add user to entry - /// - /// true if user added - public bool AddUserToEntry(string userDn, string entry) - { - Log.WriteInfo("Add User to Entry", $"Trying to add User: \"{userDn}\" to Entry: \"{entry}\""); - return ModifyUserInEntry(userDn, entry, LdapModification.Add); - } - - /// - /// Remove user from entry - /// - /// true if user removed - public bool RemoveUserFromEntry(string userDn, string entry) - { - Log.WriteInfo("Remove User from Entry", $"Trying to remove User: \"{userDn}\" from Entry: \"{entry}\""); - return ModifyUserInEntry(userDn, entry, LdapModification.Delete); - } - - /// - /// Remove user from all entries - /// - /// true if user removed from all entries - public bool RemoveUserFromAllEntries(string userDn) - { - List dnList = new List(); - dnList.Add(userDn); // group memberships do not need to be regarded here - List roles = GetRoles(dnList); - bool allRemoved = true; - foreach(var role in roles) - { - allRemoved &= RemoveUserFromEntry(userDn, $"cn={role},{RoleSearchPath}"); - } - List groups = GetGroups(dnList); - foreach(var group in groups) - { - allRemoved &= RemoveUserFromEntry(userDn, $"cn={group},{GroupSearchPath}"); - } - return allRemoved; - } - - private bool ModifyUserInEntry(string userDn, string entry, int LdapModification) - { - bool userModified = false; - try - { - // Connecting to Ldap - using (LdapConnection connection = Connect()) - { - // Authenticate as write user - connection.Bind(WriteUser, WriteUserPwd); - - // Add a new value to the description attribute - LdapAttribute attribute = new LdapAttribute("uniquemember", userDn); - LdapModification[] mods = { new LdapModification(LdapModification, attribute) }; - - try - { - //Modify the entry in the directory - connection.Modify(entry, mods); - userModified = true; - Log.WriteDebug("Modify Entry", $"Entry {entry} modified in {Address}:{Port}"); - } - catch(Exception exception) - { - Log.WriteInfo("Modify Entry", $"maybe entry doesn't exist in this LDAP {Address}:{Port}: {exception.ToString()}"); - } - } - } - catch (Exception exception) - { - Log.WriteError($"Non-LDAP exception {Address}:{Port}", "Unexpected error while trying to modify user", exception); - } - return userModified; - } - - /// - /// Add new tenant - /// - /// true if tenant added - public bool AddTenant(string tenantName) - { - Log.WriteInfo("Add Tenant", $"Trying to add Tenant: \"{tenantName}\""); - bool tenantAdded = false; - string tenantDn = ""; - try - { - // Connecting to Ldap - using (LdapConnection connection = Connect()) - { - // Authenticate as write user - connection.Bind(WriteUser, WriteUserPwd); - - tenantDn = $"ou={tenantName},{UserSearchPath}"; - LdapAttributeSet attributeSet = new LdapAttributeSet(); - attributeSet.Add( new LdapAttribute("objectclass", "organizationalUnit")); - - LdapEntry newEntry = new LdapEntry( tenantDn, attributeSet ); - - try - { - //Add the entry to the directory - connection.Add(newEntry); - tenantAdded = true; - Log.WriteDebug("Add tenant", $"Tenant {tenantName} added in {Address}:{Port}"); - } - catch(Exception exception) - { - Log.WriteInfo("Add Tenant", $"couldn't add tenant to LDAP {Address}:{Port}: {exception.ToString()}"); - } - } - } - catch (Exception exception) - { - Log.WriteError($"Non-LDAP exception {Address}:{Port}", "Unexpected error while trying to add tenant", exception); - } - return tenantAdded; - } - - /// - /// Delete tenant - /// - /// true if tenant deleted - public bool DeleteTenant(string tenantName) - { - Log.WriteDebug("Delete Tenant", $"Trying to delete Tenant: \"{tenantName}\" from Ldap"); - bool tenantDeleted = false; - try - { - // Connecting to Ldap - using (LdapConnection connection = Connect()) - { - // Authenticate as write user - connection.Bind(WriteUser, WriteUserPwd); - - try - { - string tenantDn = "ou=" + tenantName + "," + UserSearchPath; - - //Delete the entry in the directory - connection.Delete(tenantDn); - tenantDeleted = true; - Log.WriteDebug("Delete Tenant", $"tenant {tenantDn} deleted in {Address}:{Port}"); - } - catch(Exception exception) - { - Log.WriteInfo("Delete Tenant", $"couldn't delete tenant in LDAP {Address}:{Port}: {exception.ToString()}"); - } - } - } - catch (Exception exception) - { - Log.WriteError($"Non-LDAP exception {Address}:{Port}", "Unexpected error while trying to delete tenant", exception); - } - return tenantDeleted; - } - } -} diff --git a/roles/middleware/files/FWO.Middleware.Server/LdapBasic.cs b/roles/middleware/files/FWO.Middleware.Server/LdapBasic.cs new file mode 100644 index 0000000000..f2f920e137 --- /dev/null +++ b/roles/middleware/files/FWO.Middleware.Server/LdapBasic.cs @@ -0,0 +1,757 @@ +using FWO.Basics.Exceptions; +using FWO.Data; +using FWO.Data.Middleware; +using FWO.Encryption; +using FWO.Logging; +using Novell.Directory.Ldap; +using System.Net.Security; +using System.Security.Cryptography.X509Certificates; + +namespace FWO.Middleware.Server +{ + /// + /// Class handling the ldap transactions + /// + public partial class Ldap : LdapConnectionBase + { + // The following properties are retrieved from the database api: + // ldap_server ldap_port ldap_search_user ldap_tls ldap_tenant_level ldap_connection_id ldap_search_user_pwd ldap_searchpath_for_users ldap_searchpath_for_roles + private const int timeOutInMs = 3000; + + // some ldap keywords + private readonly string UniqueMember = "uniqueMember"; + private readonly string UniqueMemberLowerCase = "uniquemember"; + private readonly string BusinessCategory = "businessCategory"; + private readonly string MemberOf = "memberOf"; + private readonly string MemberOfLowerCase = "memberof"; + private readonly string OwnerGroupLowerCase = "ownergroup"; + + + /// + /// Default constructor + /// + public Ldap() + { } + + /// + /// Constructor from parameter struct + /// + public Ldap(LdapGetUpdateParameters ldapGetUpdateParameters) : base(ldapGetUpdateParameters) + { } + + /// + /// Builds a connection to the specified Ldap server. + /// + /// Connection to the specified Ldap server. + private async Task Connect() + { + try + { + LdapConnectionOptions ldapOptions = new(); + if (Tls) ldapOptions.ConfigureRemoteCertificateValidationCallback((object sen, X509Certificate? cer, X509Chain? cha, SslPolicyErrors err) => true); // todo: allow real cert validation + LdapConnection connection = new(ldapOptions) { SecureSocketLayer = Tls, ConnectionTimeout = timeOutInMs }; + await connection.ConnectAsync(Address, Port); + + return connection; + } + + catch (Exception exception) + { + Log.WriteDebug($"Could not connect to LDAP server {Address}:{Port}: ", exception.Message); + throw new LdapConnectionException($"Error while trying to reach LDAP server {Address}:{Port}", exception); + } + } + + /// + /// Builds a connection and attempts an LDAP bind with the provided user. + /// + /// LDAP user name to bind with. + /// LDAP password to bind with. + /// Whether LDAP referrals should be followed. + /// Connected LDAP connection that has attempted the bind. + private async Task GetBoundConnection(string? user, string? password, bool followReferrals = false) + { + LdapConnection connection = await Connect(); + await TryBind(connection, user, password); + + if (followReferrals) + { + EnableReferralFollowing(connection); + } + + return connection; + } + + /// + /// Enables LDAP referral following for the given connection. + /// + /// LDAP connection to configure. + private static void EnableReferralFollowing(LdapConnection connection) + { + LdapSearchConstraints constraints = connection.SearchConstraints; + constraints.ReferralFollowing = true; + connection.Constraints = constraints; + } + + /// + /// try an ldap bind, decrypting pwd before bind; using pwd as is if it cannot be decrypted + /// false if bind fails + /// + private static async Task TryBind(LdapConnection connection, string? user, string? password) + { + if (string.IsNullOrEmpty(user) || string.IsNullOrEmpty(password)) + { + Log.WriteDebug("TryBind", $"found empty ldap user name or password"); + return false; + } + else + { + await connection.BindAsync(user, AesEnc.TryDecrypt(password, true)); + } + return connection.Bound; + } + + /// + /// Test a connection to the specified Ldap server. + /// Throws exception if not successful + /// + public async Task TestConnection() + { + using LdapConnection connection = await Connect(); + if (!string.IsNullOrEmpty(SearchUser) && !string.IsNullOrEmpty(SearchUserPwd) && !await TryBind(connection, SearchUser, SearchUserPwd!)) + { + throw new LdapConnectionException("Binding failed for search user"); + } + if (!string.IsNullOrEmpty(WriteUser) && !string.IsNullOrEmpty(WriteUserPwd) && !await TryBind(connection, WriteUser, WriteUserPwd!)) + { + throw new LdapConnectionException("Binding failed for write user"); + } + } + + private string GetUserSearchFilter(string searchPattern) + { + string userFilter; + string searchFilter; + if (Type == (int)LdapType.ActiveDirectory) + { + userFilter = "(&(objectclass=user)(!(objectclass=computer)))"; + searchFilter = $"(|(cn={searchPattern})(sAMAccountName={searchPattern}))"; + } + else if (Type == (int)LdapType.OpenLdap) + { + userFilter = "(|(objectclass=user)(objectclass=person)(objectclass=inetOrgPerson)(objectclass=organizationalPerson))"; + searchFilter = $"(|(cn={searchPattern})(uid={searchPattern}))"; + } + else // LdapType.Default + { + userFilter = "(&(|(objectclass=user)(objectclass=person)(objectclass=inetOrgPerson)(objectclass=organizationalPerson))(!(objectclass=computer)))"; + searchFilter = $"(|(cn={searchPattern})(uid={searchPattern})(userPrincipalName={searchPattern})(mail={searchPattern}))"; + } + return (searchPattern == null || searchPattern == "") ? userFilter : $"(&{userFilter}{searchFilter})"; + } + + private string GetGroupSearchFilter(string searchPattern) + { + string groupFilter; + string searchFilter; + if (Type == (int)LdapType.ActiveDirectory) + { + groupFilter = "(objectClass=group)"; + searchFilter = $"(|(cn={searchPattern})(name={searchPattern}))"; + } + else if (Type == (int)LdapType.OpenLdap) + { + groupFilter = "(|(objectclass=group)(objectclass=groupofnames)(objectclass=groupofuniquenames))"; + searchFilter = $"(cn={searchPattern})"; + } + else // LdapType.Default + { + groupFilter = "(|(objectclass=group)(objectclass=groupofnames)(objectclass=groupofuniquenames))"; + searchFilter = $"(|(dc={searchPattern})(o={searchPattern})(ou={searchPattern})(cn={searchPattern})(uid={searchPattern})(mail={searchPattern}))"; + } + return (searchPattern == null || searchPattern == "") ? groupFilter : $"(&{groupFilter}{searchFilter})"; + } + + /// + /// Get the LdapEntry for the given user with option to validate credentials + /// + /// LdapEntry for the given user if found + public async Task GetLdapEntry(UiUser user, bool validateCredentials) + { + Log.WriteDebug("User Validation", $"Validating User: \"{user.Name}\" ..."); + try + { + using LdapConnection connection = await GetBoundConnection(SearchUser, SearchUserPwd, followReferrals: true); + + List possibleUserEntries = []; + + // If dn was already provided + if (!string.IsNullOrEmpty(user.Dn)) + { + // Try to read user entry directly + LdapEntry? userEntry = await connection.ReadAsync(user.Dn); + if (userEntry != null) + { + possibleUserEntries.Add(userEntry); + } + } + else // Dn was not provided, search for user name + { + await SearchUserName(user.Name, possibleUserEntries, connection); + } + + // If credentials are not checked return user that was found first + // It could happen that multiple users with the same name were found (impossible if dn was provided) + if (!validateCredentials) + { + return possibleUserEntries.Count > 0 ? possibleUserEntries[0] : null; + } + // If credentials should be checked + else + { + // Multiple users with the same name could have been found (impossible if dn was provided) + foreach (LdapEntry possibleUserEntry in possibleUserEntries) + { + // Check credentials - if multiple users were found and the credentials are valid this is most definitely the correct user + if (await CredentialsValid(connection, possibleUserEntry.Dn, user.Password)) + { + return possibleUserEntry; + } + } + } + } + catch (LdapException ldapException) + { + Log.WriteInfo("Ldap entry exception", $"Ldap entry search at \"{Address}:{Port}\" lead to exception: {ldapException.Message}"); + } + catch (Exception exception) + { + Log.WriteError($"Non-LDAP exception \"{Address}:{Port}\"", "Unexpected error while trying to validate user", exception); + } + + Log.WriteDebug("Invalid Credentials", $"Invalid login credentials - could not authenticate user \"{user.Name}\" on {Address}:{Port}."); + return null; + } + + private async Task SearchUserName(string userName, List possibleUserEntries, LdapConnection connection) + { + string[] attrList = ["*", MemberOfLowerCase]; + string userSearchFilter = GetUserSearchFilter(userName); + + // Search for users in ldap with same name as user to validate + ILdapSearchResults? searchResults = await connection.SearchAsync( + UserSearchPath, // top-level path under which to search for user + LdapConnection.ScopeSub, // search all levels beneath + userSearchFilter, + attrList, + typesOnly: false + ); + + while (await searchResults.HasMoreAsync()) + { + LdapEntry? result = await searchResults.NextAsync(); + possibleUserEntries.Add(result); + } + } + + /// + /// Get the LdapEntry for the given user by Dn + /// + /// LdapEntry for the given user if found + public async Task GetUserDetailsFromLdap(string distinguishedName) + { + try + { + using LdapConnection connection = await GetBoundConnection(SearchUser, SearchUserPwd, followReferrals: true); + + // Try to read user entry directly + return await connection.ReadAsync(distinguishedName); + } + catch (LdapException ldapException) + { + Log.WriteInfo("Ldap entry exception", $"Ldap entry search at \"{Address}:{Port}\" lead to exception: {ldapException.Message}"); + } + catch (Exception exception) + { + Log.WriteError($"Non-LDAP exception \"{Address}:{Port}\"", "Unexpected error while trying to validate user", exception); + } + return null; + } + + private async Task CredentialsValid(LdapConnection connection, string dn, string password) + { + try + { + Log.WriteDebug("User Validation", $"Trying to validate user with distinguished name: \"{dn}\" ..."); + + // Try to authenticate as user with given password + if (await TryBind(connection, dn, password)) + { + // Return ldap dn + Log.WriteDebug("User Validation", $"\"{dn}\" successfully authenticated in {Address}:{Port}."); + return true; + } + else + { + // this will probably never be reached as an error is thrown before + // Incorrect password - do nothing, assume its another user with the same username + Log.WriteDebug($"User Validation {Address}:{Port}", $"Found user with matching uid but different pwd: \"{dn}\"."); + } + } + catch (LdapException exc) + { + if (exc.ResultCode == 49) // 49 = InvalidCredentials + Log.WriteDebug($"Duplicate user {Address}:{Port}", $"Found user with matching uid but different pwd: \"{dn}\"."); + else + Log.WriteError($"Ldap exception {Address}:{Port}", $"Unexpected error while trying to validate user \"{dn}\"."); + } + return false; + } + + /// + /// Get the EmailAddress for the given user + /// + /// EmailAddress of the given user + public static string GetEmail(LdapEntry user) + { + return user.GetAttributeSet().ContainsKey("mail") ? user.Get("mail").StringValue : ""; + } + + /// + /// Get the first name for the given user + /// + /// first name of the given user + public static string GetFirstName(LdapEntry user) + { + return user.GetAttributeSet().ContainsKey("givenName") ? user.Get("givenName").StringValue : ""; + } + + /// + /// Get the last name for the given user + /// + /// last name of the given user + public static string GetLastName(LdapEntry user) + { + return user.GetAttributeSet().ContainsKey("sn") ? user.Get("sn").StringValue : ""; + } + + /// + /// Get the user name for the given user + /// + /// username of the given user + public static string GetName(LdapEntry user) + { + // active directory: + if (user.GetAttributeSet().ContainsKey("sAMAccountName")) + { + return user.Get("sAMAccountName").StringValue; + } + + // openldap: + if (user.GetAttributeSet().ContainsKey("uid")) + { + return user.Get("uid").StringValue; + } + return ""; + } + + /// + /// Determines whether the given LDAP entry represents a group object. + /// + /// LDAP entry to classify. + /// True if the entry is a group; otherwise false. + public static bool IsGroupEntry(LdapEntry entry) + { + return HasAttribute(entry, "member") + || HasAttribute(entry, "uniqueMember") + || HasAttribute(entry, "uniquemember") + || GetAttributeValues(entry, "objectClass").Any(value => + value.Equals("group", StringComparison.OrdinalIgnoreCase) + || value.Equals("groupOfNames", StringComparison.OrdinalIgnoreCase) + || value.Equals("groupOfUniqueNames", StringComparison.OrdinalIgnoreCase)); + } + + private static bool HasAttribute(LdapEntry entry, string attributeName) + { + return entry.GetAttributeSet().ContainsKey(attributeName); + } + + private static IEnumerable GetAttributeValues(LdapEntry entry, string attributeName) + { + if (entry.GetAttributeSet().ContainsKey(attributeName)) + { + return entry.Get(attributeName).StringValueArray; + } + return []; + } + + /// + /// Get the tenant name for the given user + /// + /// tenant name of the given user + public string GetTenantName(LdapEntry user) + { + DistName dn = new(user.Dn); + return dn.GetTenantNameViaLdapTenantLevel(TenantLevel); + } + + /// + /// Get the groups for the given user + /// + /// list of groups for the given user + public List GetGroups(LdapEntry user) + { + // Simplest way as most ldap types should provide the memberof attribute. + // - Probably this doesn't work for nested groups. + // - Some systems may only save the "primaryGroupID", then we would have to resolve the name. + // - Some others may force us to look into all groups to find the membership. + List groups = []; + foreach (var attribute in user.GetAttributeSet()) + { + if (attribute.Name.ToLower() == MemberOfLowerCase) + { + groups.AddRange(attribute.StringValueArray.Where(membership => + (!string.IsNullOrWhiteSpace(GroupSearchPath) && membership.EndsWith(GroupSearchPath)) + || (!string.IsNullOrWhiteSpace(GroupWritePath) && membership.EndsWith(GroupWritePath)))); + } + } + return groups; + } + + /// + /// Change the password of the given user + /// + /// error message if not successful + public async Task ChangePassword(string userDn, string oldPassword, string newPassword) + { + try + { + using LdapConnection connection = await Connect(); + // Try to authenticate as user with old password + if (await TryBind(connection, userDn, oldPassword)) + { + // authentication was successful (user is bound): set new password + LdapAttribute attribute = new("userPassword", newPassword); + LdapModification[] mods = [new LdapModification(LdapModification.Replace, attribute)]; + + await connection.ModifyAsync(userDn, mods); + Log.WriteDebug("Change password", $"Password for user {userDn} changed in {Address}:{Port}"); + } + else + { + return "wrong old password"; + } + } + catch (Exception exception) + { + return exception.Message; + } + return ""; + } + + /// + /// Set the password of the given user + /// + /// error message if not successful + public async Task SetPassword(string userDn, string newPassword) + { + try + { + using LdapConnection connection = await GetBoundConnection(WriteUser, WriteUserPwd); + if (connection.Bound) + { + // authentication was successful: set new password + LdapAttribute attribute = new("userPassword", newPassword); + LdapModification[] mods = [new LdapModification(LdapModification.Replace, attribute)]; + + await connection.ModifyAsync(userDn, mods); + Log.WriteDebug("Change password", $"Password for user {userDn} changed in {Address}:{Port}"); + } + else + { + return "error in write user authentication"; + } + } + catch (Exception exception) + { + return exception.Message; + } + return ""; + } + + /// + /// Search all users with search pattern + /// + /// list of users + public async Task> GetAllUsers(string searchPattern) + { + Log.WriteDebug("GetAllUsers", $"Looking for users with pattern {searchPattern} in {Address}:{Port}"); + List allUsers = []; + + try + { + using LdapConnection connection = await GetBoundConnection(SearchUser, SearchUserPwd, followReferrals: true); + + // Search for Ldap users in given directory + int searchScope = LdapConnection.ScopeSub; + + ILdapSearchResults? searchResults = await connection.SearchAsync(UserSearchPath, searchScope, GetUserSearchFilter(searchPattern), null, false); + + while (await searchResults.HasMoreAsync()) + { + LdapEntry? entry = await searchResults.NextAsync(); + allUsers.Add(new LdapUserGetReturnParameters() + { + UserDn = entry.Dn, + Email = entry.GetAttributeSet().ContainsKey("mail") ? entry.Get("mail").StringValue : null + // add first and last name of user + }); + } + } + catch (Exception exception) + { + Log.WriteError($"Non-LDAP exception {Address}:{Port}", "Unexpected error while trying to get all users", exception); + } + return allUsers; + } + + /// + /// Add new user + /// + /// true if user added + public async Task AddUser(string userDn, string password, string email) + { + Log.WriteInfo("Add User", $"Trying to add User: \"{userDn}\""); + bool userAdded = false; + try + { + using LdapConnection connection = await GetBoundConnection(WriteUser, WriteUserPwd); + + string userName = new DistName(userDn).UserName; + LdapAttributeSet attributeSet = new() + { + new LdapAttribute("objectclass", "inetOrgPerson"), + new LdapAttribute("sn", userName), + new LdapAttribute("cn", userName), + new LdapAttribute("uid", userName), + new LdapAttribute("userPassword", password), + new LdapAttribute("mail", email) + }; + + LdapEntry newEntry = new(userDn, attributeSet); + + try + { + //Add the entry to the directory + await connection.AddAsync(newEntry); + userAdded = true; + Log.WriteDebug("Add user", $"User {userName} added in {Address}:{Port}"); + } + catch (Exception exception) + { + Log.WriteInfo("Add User", $"couldn't add user to LDAP {Address}:{Port}: {exception}"); + } + } + catch (Exception exception) + { + Log.WriteError($"Non-LDAP exception {Address}:{Port}", "Unexpected error while trying to add user", exception); + } + return userAdded; + } + + /// + /// Update user + /// + /// true if user updated + public async Task UpdateUser(string userDn, string email) + { + Log.WriteInfo("Update User", $"Trying to update User: \"{userDn}\""); + bool userUpdated = false; + try + { + using LdapConnection connection = await GetBoundConnection(WriteUser, WriteUserPwd); + LdapAttribute attribute = new("mail", email); + LdapModification[] mods = [new(LdapModification.Replace, attribute)]; + + try + { + //Add the entry to the directory + await connection.ModifyAsync(userDn, mods); + userUpdated = true; + Log.WriteDebug("Update user", $"User {userDn} updated in {Address}:{Port}"); + } + catch (Exception exception) + { + Log.WriteInfo("Update User", $"couldn't update user in LDAP {Address}:{Port}: {exception}"); + } + } + catch (Exception exception) + { + Log.WriteError($"Non-LDAP exception {Address}:{Port}", "Unexpected error while trying to update user", exception); + } + return userUpdated; + } + + /// + /// Delete user + /// + /// true if user deleted + public async Task DeleteUser(string userDn) + { + Log.WriteInfo("Delete User", $"Trying to delete User: \"{userDn}\""); + bool userDeleted = false; + try + { + using LdapConnection connection = await GetBoundConnection(WriteUser, WriteUserPwd); + + try + { + //Delete the entry in the directory + await connection.DeleteAsync(userDn); + userDeleted = true; + Log.WriteDebug("Delete user", $"User {userDn} deleted in {Address}:{Port}"); + } + catch (Exception exception) + { + Log.WriteInfo("Delete User", $"couldn't delete user in LDAP {Address}:{Port}: {exception}"); + } + } + catch (Exception exception) + { + Log.WriteError($"Non-LDAP exception {Address}:{Port}", "Unexpected error while trying to delete user", exception); + } + return userDeleted; + } + + private static bool IsFullyQualifiedDn(string name) + { + name = name.ToLower(); + return name.Contains(',') && (name.StartsWith("cn=") || name.StartsWith("uid=")); + } + + /// + /// Add user to entry + /// + /// true if user added + public async Task AddUserToEntry(string userDn, string entry) + { + Log.WriteDebug("Add User to Entry", $"Trying to add User: \"{userDn}\" to Entry: \"{entry}\""); + return await ModifyUserInEntry(userDn, entry, LdapModification.Add); + } + + /// + /// Remove user from entry + /// + /// true if user removed + public async Task RemoveUserFromEntry(string userDn, string entry) + { + Log.WriteInfo("Remove User from Entry", $"Trying to remove User: \"{userDn}\" from Entry: \"{entry}\""); + return await ModifyUserInEntry(userDn, entry, LdapModification.Delete); + } + + /// + /// Remove user from all entries + /// + /// true if user removed from all entries + public async Task RemoveUserFromAllEntries(string userDn) + { + List dnList = [userDn]; // group memberships do not need to be regarded here + List roles = await GetRoles(dnList); + bool allRemoved = true; + foreach (var role in roles) + { + allRemoved &= await RemoveUserFromEntry(userDn, $"cn={role},{RoleSearchPath}"); + } + List groups = await GetGroups(dnList); + foreach (var group in groups) + { + allRemoved &= await RemoveUserFromEntry(userDn, $"cn={group},{GroupWritePath}"); + } + return allRemoved; + } + + /// + /// Decide if a membership change should be applied based on current state. + /// + public static bool ShouldModifyMembership(bool memberExists, int ldapModification) + { + return ldapModification switch + { + LdapModification.Add => !memberExists, + LdapModification.Delete => memberExists, + _ => true + }; + } + + /// + /// Normalizes a distinguished name for safe membership comparisons across equivalent escaped forms. + /// + public static string NormalizeDnForComparison(string? dn) + { + return DistName.NormalizeDnForComparison(dn); + } + + private async Task ModifyUserInEntry(string userDn, string entry, int ldapModification) + { + bool userModified = false; + try + { + using LdapConnection connection = await GetBoundConnection(WriteUser, WriteUserPwd); + + LdapEntry? entryData; + try + { + entryData = await connection.ReadAsync(entry); + if (entryData == null) + { + Log.WriteDebug("Modify Entry", $"Entry not found: {entry}"); + return false; + } + } + catch (LdapException ex) when (ex.ResultCode == LdapException.NoSuchObject) + { + Log.WriteDebug("Modify Entry", $"Entry not found: {entry}"); + return false; + } + + string[] existingMembers = entryData.GetAttributeSet().ContainsKey(UniqueMemberLowerCase) + ? entryData.Get(UniqueMemberLowerCase).StringValueArray + : []; + string normalizedRequestedDn = NormalizeDnForComparison(userDn); + string? matchingStoredMemberDn = existingMembers.FirstOrDefault(memberDn => + NormalizeDnForComparison(memberDn).Equals(normalizedRequestedDn, StringComparison.Ordinal)); + bool memberExists = !string.IsNullOrWhiteSpace(matchingStoredMemberDn); + + if (!ShouldModifyMembership(memberExists, ldapModification)) + { + if (ldapModification == LdapModification.Add) + { + Log.WriteDebug("Modify Entry", $"User {userDn} already member of {entry}"); + } + else if (ldapModification == LdapModification.Delete) + { + Log.WriteDebug("Modify Entry", $"User {userDn} not member of {entry}"); + } + // Treat no-op membership changes as success so callers can use add/remove idempotently. + return true; + } + + string memberDnForModification = ldapModification == LdapModification.Delete + ? matchingStoredMemberDn ?? userDn + : userDn; + LdapAttribute attribute = new(UniqueMemberLowerCase, memberDnForModification); + LdapModification[] mods = [new(ldapModification, attribute)]; + + await connection.ModifyAsync(entry, mods); + userModified = true; + + Log.WriteDebug("Modify Entry", $"User {memberDnForModification} modified in {entry}"); + } + catch (Exception ex) + { + Log.WriteError($"Non-LDAP exception {Address}:{Port}", $"Unexpected error while modifying user {userDn}", ex); + } + return userModified; + } + } +} diff --git a/roles/middleware/files/FWO.Middleware.Server/LdapGroupHandling.cs b/roles/middleware/files/FWO.Middleware.Server/LdapGroupHandling.cs new file mode 100644 index 0000000000..82592c71a6 --- /dev/null +++ b/roles/middleware/files/FWO.Middleware.Server/LdapGroupHandling.cs @@ -0,0 +1,605 @@ +using FWO.Data; +using FWO.Data.Middleware; +using FWO.Encryption; +using FWO.Logging; +using Novell.Directory.Ldap; +using System; +using System.Text.RegularExpressions; + +namespace FWO.Middleware.Server +{ + /// + /// Class handling the ldap transactions + /// + public partial class Ldap : LdapConnectionBase + { + /// + /// Get the roles for the given DN list + /// + /// list of roles for the given DN list + public async Task> GetRoles(List dnList) + { + return await GetMemberships(dnList, RoleSearchPath); + } + + /// + /// Get the groups for the given DN list + /// + /// list of groups for the given DN list + public async Task> GetGroups(List dnList) + { + string? groupPath = !string.IsNullOrWhiteSpace(GroupSearchPath) ? GroupSearchPath : GroupWritePath; + return await GetMemberships(dnList, groupPath); + } + + [GeneratedRegex(@"(\bcn|\bou|\bdc|\bo|\bc|\bst|\bl)=(.*?)(?=,[A-Za-z]+=|$)", RegexOptions.IgnoreCase, "en-US")] + private static partial Regex MyRegex(); + + private static string ConvertHexCommaToComma(string dn) + { + return MyRegex().Replace(dn, match => + { + string attribute = match.Groups[1].Value; // RDN type (e.g., CN, OU, DC) + string value = match.Groups[2].Value; // RDN value + + // Convert hex-escaped commas to commas + value = Regex.Replace(value, @"\\2c", "\\,", RegexOptions.None, TimeSpan.FromMilliseconds(100)); + + return $"{attribute}={value}"; + }); + } + + /// + /// Build group DNs from group names and a group path. + /// + /// List of group names or DNs. + /// LDAP path where groups are located. + /// Distinct list of group DNs. + public static List BuildGroupDns(IEnumerable groupNames, string? groupPath) + { + if (string.IsNullOrWhiteSpace(groupPath)) + { + return []; + } + HashSet dns = new(StringComparer.OrdinalIgnoreCase); + foreach (string name in groupNames) + { + if (string.IsNullOrWhiteSpace(name)) + { + continue; + } + if (name.Contains('=')) + { + dns.Add(name); + } + else + { + dns.Add($"cn={name},{groupPath}"); + } + } + return dns.ToList(); + } + + private async Task> GetMemberships(List dnList, string? searchPath) + { + List userMemberships = []; + + // If this Ldap is containing roles / groups + if (searchPath != null && searchPath != "") + { + try + { + using LdapConnection connection = await Connect(); + // Authenticate as search user + string mainKey = AesEnc.GetMainKey(); + if (!AesEnc.TryDecrypt(SearchUserPwd, mainKey, out string decryptedSearchUserPwd)) + { + Log.WriteError($"LDAP decrypt {Address}:{Port}", "Failed to decrypt LDAP search user password."); + return userMemberships; + } + await TryBind(connection, SearchUser, decryptedSearchUserPwd); + + // Search for Ldap roles / groups in given directory + int searchScope = LdapConnection.ScopeSub; // TODO: Correct search scope? + string searchFilter = $"(&(objectClass=groupOfUniqueNames)(cn=*))"; + ILdapSearchResults? allExistingGroupsAndRoles = await connection.SearchAsync(searchPath, searchScope, searchFilter, null, false); + + // convert dnList to lower case to avoid case problems + dnList = dnList.ConvertAll(dn => dn.ToLower()); + + Log.WriteDebug("Ldap Roles/Groups", $"Try to get roles / groups from ldap"); + + // Iterate found role / group + while (await allExistingGroupsAndRoles.HasMoreAsync()) + { + LdapEntry? entry = await allExistingGroupsAndRoles.NextAsync(); + + // Get dn of users having current role / group + LdapAttribute members = entry.Get(UniqueMember); + string[] memberDn = members.StringValueArray; + + // Foreach user (member) of the current role/group: + foreach (string currentDn in memberDn.Where(dn => dn != "")) // ignore empty dn (could be caused by empty lines in LDAP) + { + string currentUserDnEscapedLower = ConvertHexCommaToComma(currentDn.ToLower()); + + // Check if current user dn is matching with given user dn => Given user has current role / group + if (dnList.Contains(currentUserDnEscapedLower)) + { + // Get name and add it to list of roles / groups of given user + string name = entry.Get("cn").StringValue; + userMemberships.Add(name); + break; + } + } + } + } + catch (Exception exception) + { + Log.WriteError($"Non-LDAP exception {Address}:{Port}", "Unexpected error while trying to get memberships", exception); + } + } + + Log.WriteDebug($"Found the following roles / groups for user {dnList.FirstOrDefault()} in {Address}:{Port}:", string.Join("\n", userMemberships)); + return userMemberships; + } + + /// + /// Get all roles + /// + /// list of roles + public async Task> GetAllRoles() + { + List roleUsers = []; + + // If this Ldap is containing roles + if (HasRoleHandling()) + { + try + { + using LdapConnection connection = await GetBoundConnection(SearchUser, SearchUserPwd); + + // Search for Ldap roles in given directory + int searchScope = LdapConnection.ScopeSub; // TODO: Correct search scope? + string searchFilter = $"(&(objectClass=groupOfUniqueNames)(cn=*))"; + ILdapSearchResults? searchResults = await connection.SearchAsync(RoleSearchPath, searchScope, searchFilter, null, false); + + // Iterate found role + while (await searchResults.HasMoreAsync()) + { + LdapEntry entry = await searchResults.NextAsync(); + + List attributes = []; + string roleDesc = entry.Get("description").StringValue; + attributes.Add(new() { Key = "description", Value = roleDesc }); + + string[] roleMemberDn = entry.Get(UniqueMember).StringValueArray; + foreach (var currentDn in roleMemberDn.Where(dn => dn != "")) + { + attributes.Add(new() { Key = "user", Value = currentDn }); + } + roleUsers.Add(new RoleGetReturnParameters() { Role = entry.Dn, Attributes = attributes }); + } + } + catch (Exception exception) + { + Log.WriteError($"Non-LDAP exception {Address}:{Port}", "Unexpected error while trying to get all roles", exception); + } + } + return roleUsers; + } + + /// + /// Search all groups with search pattern + /// + /// list of groups + public async Task> GetAllGroups(string searchPattern) + { + List allGroups = []; + try + { + using LdapConnection connection = await GetBoundConnection(SearchUser, SearchUserPwd); + + // Search for Ldap groups in given directory + int searchScope = LdapConnection.ScopeSub; + ILdapSearchResults? searchResults = await connection.SearchAsync(GroupSearchPath, searchScope, GetGroupSearchFilter(searchPattern), null, false); + + while (await searchResults.HasMoreAsync()) + { + LdapEntry entry = await searchResults.NextAsync(); + + allGroups.Add(entry.Dn); + } + } + catch (Exception exception) + { + Log.WriteError($"Non-LDAP exception {Address}:{Port}", "Unexpected error while trying to get all groups", exception); + } + return allGroups; + } + + /// + /// Get all internal groups + /// + /// list of groups + public async Task> GetAllInternalGroups() + { + List allGroups = []; + + try + { + using LdapConnection connection = await GetBoundConnection(SearchUser, SearchUserPwd); + + // Search for Ldap groups in given directory + int searchScope = LdapConnection.ScopeSub; + ILdapSearchResults? searchResults = await connection.SearchAsync(GroupSearchPath, searchScope, GetGroupSearchFilter(""), null, false); + + while (await searchResults.HasMoreAsync()) + { + LdapEntry entry = await searchResults.NextAsync(); + + List members = []; + string[] groupMemberDn = entry.Get(UniqueMember).StringValueArray; + members.AddRange(groupMemberDn.Where(currentDn => currentDn != "")); + allGroups.Add(new GroupGetReturnParameters() + { + GroupDn = entry.Dn, + Members = members, + OwnerGroup = entry.GetAttributeSet().ContainsKey(BusinessCategory) && entry.Get(BusinessCategory).StringValue.Equals(OwnerGroupLowerCase, StringComparison.OrdinalIgnoreCase) + }); + } + } + catch (Exception exception) + { + Log.WriteError($"Non-LDAP exception {Address}:{Port}", "Unexpected error while trying to get all internal groups", exception); + } + return allGroups; + } + + /// + /// Get all groups of an LDAP server matching a specific pattern + /// + /// list of groups + public async Task> GetAllGroupObjects(string groupPattern) + { + List allGroups = []; + + try + { + using LdapConnection connection = await GetBoundConnection(SearchUser, SearchUserPwd); + + // Search for Ldap groups in given directory + int searchScope = LdapConnection.ScopeSub; + string searchFilter = GetGroupSearchFilter(groupPattern); + ILdapSearchResults? searchResults = await connection.SearchAsync(GroupSearchPath, searchScope, searchFilter, null, false); + + while (await searchResults.HasMoreAsync()) + { + LdapEntry entry = await searchResults.NextAsync(); + + List members = []; + if (entry.GetAttributeSet().ContainsKey(GetMemberKey())) + { + string[] groupMemberDn = entry.Get(GetMemberKey()).StringValueArray; + members.AddRange(groupMemberDn.Where(currentDn => currentDn != "")); + } + allGroups.Add(new GroupGetReturnParameters() + { + GroupDn = entry.Dn, + Members = members, + OwnerGroup = entry.GetAttributeSet().ContainsKey(BusinessCategory) && entry.Get(BusinessCategory).StringValue.Equals(OwnerGroupLowerCase, StringComparison.OrdinalIgnoreCase) + }); + } + } + catch (Exception exception) + { + Log.WriteError($"Non-LDAP exception {Address}:{Port}", "Unexpected error while trying to get all internal groups", exception); + } + return allGroups; + } + + /// + /// Get member key depending on the LDAP type + /// + /// string with member key + private string GetMemberKey() + { + string memberKey = UniqueMember; + if ((LdapType)Type == LdapType.ActiveDirectory) + { + memberKey = "member"; + } + return memberKey; + } + + /// + /// Get members of an ldap group + /// + /// list of members + public async Task> GetGroupMembers(string groupDn) + { + List allMembers = []; + + if (string.IsNullOrWhiteSpace(groupDn)) + { + return allMembers; + } + + try + { + using LdapConnection connection = await GetBoundConnection(SearchUser, SearchUserPwd); + + LdapEntry? entry = await connection.ReadAsync(groupDn); + if (entry == null) + { + Log.WriteDebug("GetGroupMembers", $"Group not found: {groupDn}"); + return allMembers; + } + + string memberKey = GetMemberKey(); + if (!entry.GetAttributeSet().ContainsKey(memberKey)) + { + Log.WriteDebug("GetGroupMembers", $"Group has no members: {groupDn}"); + return allMembers; + } + + string[] groupMemberDn = entry.Get(memberKey).StringValueArray; + allMembers.AddRange(groupMemberDn.Where(m => !string.IsNullOrWhiteSpace(m))); + } + catch (LdapException ex) when (ex.ResultCode == LdapException.NoSuchObject) + { + Log.WriteDebug("GetGroupMembers", $"Group not found: {groupDn}"); + } + catch (Exception ex) + { + Log.WriteError($"Non-LDAP exception {Address}:{Port}", $"Unexpected error while reading members of group {groupDn}", ex); + } + + return allMembers; + } + + /// + /// Resolve user DNs from a list of user or group DNs, expanding group members recursively. + /// + /// DNs to resolve. + /// List of resolved user DNs. + public async Task> ResolveUsersFromDns(IEnumerable dns) + { + HashSet resolvedUsers = new(StringComparer.OrdinalIgnoreCase); + if (dns == null) + { + return resolvedUsers.ToList(); + } + + Queue groupQueue = new(); + HashSet visitedGroups = new(StringComparer.OrdinalIgnoreCase); + + foreach (string dn in dns) + { + EnqueueGroupOrAddUser(dn, groupQueue, resolvedUsers); + } + + while (groupQueue.Count > 0) + { + string groupDn = groupQueue.Dequeue(); + if (!visitedGroups.Add(groupDn)) + { + continue; + } + + List members = await GetGroupMembers(groupDn); + foreach (string memberDn in members) + { + EnqueueGroupOrAddUser(memberDn, groupQueue, resolvedUsers); + } + } + + return resolvedUsers.ToList(); + } + + private void EnqueueGroupOrAddUser(string dn, Queue groupQueue, HashSet resolvedUsers) + { + if (string.IsNullOrWhiteSpace(dn)) + { + return; + } + if (IsGroupDn(dn)) + { + groupQueue.Enqueue(dn); + return; + } + if (IsUserDn(dn) || string.IsNullOrWhiteSpace(UserSearchPath)) + { + resolvedUsers.Add(dn); + } + } + + private bool IsGroupDn(string dn) + { + return !string.IsNullOrWhiteSpace(GroupSearchPath) + && dn.EndsWith(GroupSearchPath, StringComparison.OrdinalIgnoreCase); + } + + private bool IsUserDn(string dn) + { + return !string.IsNullOrWhiteSpace(UserSearchPath) + && dn.EndsWith(UserSearchPath, StringComparison.OrdinalIgnoreCase); + } + + /// + /// Get all groups, the user is member of + /// + /// user to search + /// list of groups + /// + /// This method is used to get the groups of a user in the LDAP directory. + /// It connects to the LDAP server, binds with the search user, and searches for the user in the specified search path. + /// If the user is found, it retrieves the "memberOf" attribute, which contains the groups the user is a member of. + /// The method returns a list of group names that the user belongs to. + /// + public async Task> GetGroupsOfUser(string userToSearch) + { + List userGroups = []; + try + { + using LdapConnection connection = await GetBoundConnection(SearchUser, SearchUserPwd); + + // searchfilter for users + string searchFilter = $"(|(cn={userToSearch})(sAMAccountName={userToSearch}))"; + + var searchResults = await connection.SearchAsync( + UserSearchPath, + LdapConnection.ScopeSub, + searchFilter, + [MemberOf], + false + ); + + if (await searchResults.HasMoreAsync()) + { + var entry = await searchResults.NextAsync(); + var memberOfAttrs = entry.Get(MemberOf); + + if (memberOfAttrs != null) + { + foreach (var group in memberOfAttrs.StringValueArray) + { + userGroups.Add(group); + } + } + else + { + Log.WriteWarning("GetGroupsOfUser", $"User does not have any groups \"{userToSearch}\""); + } + } + else + { + Log.WriteWarning("GetGroupsOfUser", $"Could not find user \"{userToSearch}\""); + } + } + catch (LdapException e) + { + Log.WriteError("GetGroupsOfUser LDAP error", e.LdapErrorMessage); + } + catch (Exception ex) + { + Log.WriteError("GetGroupsOfUser error", ex.Message); + } + return userGroups; + } + + + + /// + /// Add new group + /// + /// group DN if user added + public async Task AddGroup(string groupName, bool ownerGroup) + { + Log.WriteInfo("Add Group", $"Trying to add Group: \"{groupName}\""); + bool groupAdded = false; + string groupDn = groupName; + try + { + using LdapConnection connection = await GetBoundConnection(WriteUser, WriteUserPwd); + + if (!IsFullyQualifiedDn(groupDn)) + { + groupDn = $"cn={groupName},{GroupWritePath}"; + } + LdapAttributeSet attributeSet = new(); + attributeSet.Add(new LdapAttribute("objectclass", "groupofuniquenames")); + attributeSet.Add(new LdapAttribute(UniqueMember, "")); + if (ownerGroup) + { + attributeSet.Add(new LdapAttribute(BusinessCategory, OwnerGroupLowerCase)); + } + + LdapEntry newEntry = new(groupDn, attributeSet); + + try + { + //Add the entry to the directory + await connection.AddAsync(newEntry); + groupAdded = true; + Log.WriteDebug("Add group", $"Group {groupName} added in {Address}:{Port}"); + } + catch (Exception exception) + { + Log.WriteInfo("Add Group", $"couldn't add group to LDAP {Address}:{Port}: {exception}"); + } + } + catch (Exception exception) + { + Log.WriteError($"Non-LDAP exception {Address}:{Port}", "Unexpected error while trying to add group", exception); + } + return groupAdded ? groupDn : ""; + } + + /// + /// Update group name + /// + /// new group DN if group updated + public async Task UpdateGroup(string oldName, string newName) + { + Log.WriteInfo("Update Group", $"Trying to update Group: \"{oldName}\""); + bool groupUpdated = false; + string oldGroupDn = $"cn={oldName},{GroupWritePath}"; + string newGroupRdn = $"cn={newName}"; + + try + { + using LdapConnection connection = await GetBoundConnection(WriteUser, WriteUserPwd); + + try + { + //Add the entry to the directory + await connection.RenameAsync(oldGroupDn, newGroupRdn, true); + groupUpdated = true; + Log.WriteDebug("Update group", $"Group {oldName} renamed to {newName} in {Address}:{Port}"); + } + catch (Exception exception) + { + Log.WriteInfo("Update Group", $"couldn't update group in LDAP {Address}:{Port}: {exception}"); + } + } + catch (Exception exception) + { + Log.WriteError($"Non-LDAP exception {Address}:{Port}", "Unexpected error while trying to update group", exception); + } + return groupUpdated ? $"{newGroupRdn},{GroupWritePath}" : ""; + } + + /// + /// Delete group + /// + /// true if group deleted + public async Task DeleteGroup(string groupName) + { + Log.WriteInfo("Delete Group", $"Trying to delete Group: \"{groupName}\""); + bool groupDeleted = false; + try + { + using LdapConnection connection = await GetBoundConnection(WriteUser, WriteUserPwd); + + try + { + //Delete the entry in the directory + string groupDn = $"cn={groupName},{GroupWritePath}"; + await connection.DeleteAsync(groupDn); + groupDeleted = true; + Log.WriteDebug("Delete group", $"Group {groupName} deleted in {Address}:{Port}"); + } + catch (Exception exception) + { + Log.WriteInfo("Delete Group", $"couldn't delete group in LDAP {Address}:{Port}: {exception}"); + } + } + catch (Exception exception) + { + Log.WriteError($"Non-LDAP exception {Address}:{Port}", "Unexpected error while trying to delete group", exception); + } + return groupDeleted; + } + } +} diff --git a/roles/middleware/files/FWO.Middleware.Server/LdapTenantHandling.cs b/roles/middleware/files/FWO.Middleware.Server/LdapTenantHandling.cs new file mode 100644 index 0000000000..ffb554435a --- /dev/null +++ b/roles/middleware/files/FWO.Middleware.Server/LdapTenantHandling.cs @@ -0,0 +1,89 @@ +using FWO.Data; +using FWO.Logging; +using Novell.Directory.Ldap; + +namespace FWO.Middleware.Server +{ + /// + /// Class handling the ldap transactions + /// + public partial class Ldap : LdapConnectionBase + { + + /// + /// Add new tenant + /// + /// true if tenant added + public async Task AddTenant(string tenantName) + { + Log.WriteInfo("Add Tenant", $"Trying to add Tenant: \"{tenantName}\""); + bool tenantAdded = false; + try + { + using LdapConnection connection = await GetBoundConnection(WriteUser, WriteUserPwd); + + LdapAttributeSet attributeSet = new() + { + new LdapAttribute("objectclass", "organizationalUnit") + }; + + LdapEntry newEntry = new(TenantNameToDn(tenantName), attributeSet); + + try + { + //Add the entry to the directory + await connection.AddAsync(newEntry); + tenantAdded = true; + Log.WriteDebug("Add tenant", $"Tenant {tenantName} added in {Address}:{Port}"); + } + catch (Exception exception) + { + Log.WriteInfo("Add Tenant", $"couldn't add tenant to LDAP {Address}:{Port}: {exception}"); + } + } + catch (Exception exception) + { + Log.WriteError($"Non-LDAP exception {Address}:{Port}", "Unexpected error while trying to add tenant", exception); + } + return tenantAdded; + } + + /// + /// Delete tenant + /// + /// true if tenant deleted + public async Task DeleteTenant(string tenantName) + { + Log.WriteDebug("Delete Tenant", $"Trying to delete Tenant: \"{tenantName}\" from Ldap"); + bool tenantDeleted = false; + try + { + using LdapConnection connection = await GetBoundConnection(WriteUser, WriteUserPwd); + + try + { + string tenantDn = TenantNameToDn(tenantName); + //Delete the entry in the directory + await connection.DeleteAsync(tenantDn); + tenantDeleted = true; + Log.WriteDebug("Delete Tenant", $"tenant {tenantDn} deleted in {Address}:{Port}"); + } + catch (Exception exception) + { + Log.WriteInfo("Delete Tenant", $"couldn't delete tenant in LDAP {Address}:{Port}: {exception}"); + } + } + catch (Exception exception) + { + Log.WriteError($"Non-LDAP exception {Address}:{Port}", "Unexpected error while trying to delete tenant", exception); + } + return tenantDeleted; + } + + private string TenantNameToDn(string tenantName) + { + return $"ou={tenantName},{UserSearchPath}"; + } + + } +} diff --git a/roles/middleware/files/FWO.Middleware.Server/MiddlewareServerServices.cs b/roles/middleware/files/FWO.Middleware.Server/MiddlewareServerServices.cs new file mode 100644 index 0000000000..d4ed73a393 --- /dev/null +++ b/roles/middleware/files/FWO.Middleware.Server/MiddlewareServerServices.cs @@ -0,0 +1,48 @@ +using FWO.Api.Client; +using FWO.Api.Client.Queries; +using FWO.Data; +using FWO.Data.Middleware; + + +namespace FWO.Middleware.Server +{ + /// + /// Class to execute handling of external requests + /// + public static class MiddlewareServerServices + { + /// + /// get user groups from ldap + /// + /// + /// + /// + public static async Task> GetInternalGroups(ApiConnection ApiConnection) + { + List connectedLdaps = await ApiConnection.SendQueryAsync>(AuthQueries.getLdapConnections); + Ldap internalLdap = connectedLdaps.FirstOrDefault(x => x.IsInternal() && x.HasGroupHandling()) ?? throw new KeyNotFoundException("No internal Ldap with group handling found."); + + List allGroups = await internalLdap.GetAllInternalGroups(); + List ownerGroups = []; + foreach (var ldapUserGroup in allGroups) + { + if (ldapUserGroup.OwnerGroup) + { + UserGroup group = new() + { + Dn = ldapUserGroup.GroupDn, + Name = new DistName(ldapUserGroup.GroupDn).Group, + OwnerGroup = ldapUserGroup.OwnerGroup + }; + foreach (var userDn in ldapUserGroup.Members) + { + UiUser newUser = new() { Dn = userDn, Name = new DistName(userDn).UserName }; + group.Users.Add(newUser); + } + ownerGroups.Add(group); + } + } + return ownerGroups; + } + } +} diff --git a/roles/middleware/files/FWO.Middleware.Server/ModellingImportAppData.cs b/roles/middleware/files/FWO.Middleware.Server/ModellingImportAppData.cs new file mode 100644 index 0000000000..e3eaf9d2e6 --- /dev/null +++ b/roles/middleware/files/FWO.Middleware.Server/ModellingImportAppData.cs @@ -0,0 +1,145 @@ +using System.Text.Json.Serialization; +using FWO.Data.Modelling; +using Newtonsoft.Json; + + +namespace FWO.Middleware.Server +{ + /// + /// Structure for imported owner data + /// + public class ModellingImportOwnerData + { + /// + /// List of all Owners + /// + [JsonProperty("owners"), JsonPropertyName("owners")] + public List? Owners { get; set; } + } + + /// + /// Structure for imported app data + /// + public class ModellingImportAppData + { + /// + /// App Name + /// + [JsonProperty("name"), JsonPropertyName("name")] + public string Name { get; set; } = ""; + + /// + /// External Id of App + /// + [JsonProperty("app_id_external"), JsonPropertyName("app_id_external")] + public string ExtAppId { get; set; } = ""; + + /// + /// Main user identifier from import. + /// The import source should provide its own user identifier, which is resolved by middleware. + /// Legacy: is now imported as responsible with type MainUser. + /// + [JsonProperty("main_user"), JsonPropertyName("main_user")] + public string? MainUser { get; set; } = ""; + + /// + /// Criticality of App + /// + [JsonProperty("criticality"), JsonPropertyName("criticality")] + public string? Criticality { get; set; } + + /// + /// Owner lifecycle state name + /// + [JsonProperty("owner_lifecycle_state"), JsonPropertyName("owner_lifecycle_state")] + public string? OwnerLifecycleState { get; set; } + + /// + /// Owner responsibles grouped by responsible type key. + /// Values may be user or group identifiers from the source system. + /// Keys must be numeric. + /// Incoming keys are sorted numerically and assigned to responsible types + /// sorted by sort_order (lowest key -> first type by sort_order, next key -> next type). + /// Example: + /// "responsibles": { + /// "1": ["user1"], + /// "2": [] + /// } + /// + [JsonProperty("responsibles"), JsonPropertyName("responsibles")] + public Dictionary>? Responsibles { get; set; } = []; + + /// + /// Additional owner metadata imported from customization sources. + /// + [JsonProperty("additional_information"), JsonPropertyName("additional_information")] + public Dictionary? AdditionalInformation { get; set; } + + /// + /// Source of App import + /// + [JsonProperty("import_source"), JsonPropertyName("import_source")] + public string ImportSource { get; set; } = ""; + + /// + /// Recertification interval + /// + [JsonProperty("recert_period_days"), JsonPropertyName("recert_period_days")] + public int? RecertInterval { get; set; } + + /// + /// First Recertification interval (currently not regarded) + /// + [JsonProperty("days_until_first_recert"), JsonPropertyName("days_until_first_recert")] + public int? FirstRecertInterval { get; set; } + + /// + /// Recertification active + /// + [JsonProperty("recert_active"), JsonPropertyName("recert_active")] + public bool RecertActive { get; set; } = false; + + /// + /// App Servers of App + /// + [JsonProperty("app_servers"), JsonPropertyName("app_servers")] + public List AppServers { get; set; } = []; + } + + /// + /// Structure for imported app server + /// + public class ModellingImportAppServer + { + /// + /// App Server Name + /// + [JsonProperty("name"), JsonPropertyName("name")] + public string Name { get; set; } = ""; + + /// + /// App Server Ip + /// + [JsonProperty("ip"), JsonPropertyName("ip")] + public string Ip { get; set; } = ""; + + /// + /// App Server IpEnd + /// + [JsonProperty("ip_end"), JsonPropertyName("ip_end")] + public string IpEnd { get; set; } = ""; + + /// + /// Conversion to ModellingAppServer + /// + public ModellingAppServer ToModellingAppServer() + { + return new ModellingAppServer() + { + Name = Name, + Ip = Ip, + IpEnd = IpEnd + }; + } + } +} diff --git a/roles/middleware/files/FWO.Middleware.Server/ModellingImportNwData.cs b/roles/middleware/files/FWO.Middleware.Server/ModellingImportNwData.cs new file mode 100644 index 0000000000..66dcc891b1 --- /dev/null +++ b/roles/middleware/files/FWO.Middleware.Server/ModellingImportNwData.cs @@ -0,0 +1,104 @@ +using System.Text.Json.Serialization; +// using Newtonsoft.Json; + + +namespace FWO.Middleware.Server +{ + /// + /// Structure for imported network data + /// + public class ModellingImportNwData + { + /// + /// List of all Areas + /// + // [JsonProperty("areas"), JsonPropertyName("areas")] + [JsonPropertyName("areas")] + public List Areas { get; set; } = []; + } + + /// + /// Structure for imported area data + /// + public class ModellingImportAreaData + { + /// + /// Area Name + /// + [JsonPropertyName("name")] + public string Name { get; set; } = ""; + + /// + /// Area Id String + /// + [JsonPropertyName("id_string")] + public string IdString { get; set; } = ""; + + /// + /// List of all associated ip data + /// + [JsonPropertyName("subnets")] + public List IpData { get; set; } = []; + + + /// + /// Default Constructor + /// + public ModellingImportAreaData() { } + + /// + /// Overloaded constructor with an empty list as default + /// + public ModellingImportAreaData(string name, string idString) + : this(name, idString, []) { } + + /// + /// Constructor for initializing an object + /// + [JsonConstructor] + public ModellingImportAreaData(string name, string idString, List ipData) + { + IdString = idString; + Name = name; + IpData = ipData; + } + } + + /// + /// Structure for imported Area Ip Data + /// + public class ModellingImportAreaIpData + { + /// + /// Area Subnet Name + /// + [JsonPropertyName("name")] + public string Name { get; set; } = ""; + + /// + /// Area Subnet Network Start IP (in cidr notation) + /// + [JsonPropertyName("ip")] + public string Ip { get; set; } = ""; + + /// + /// Area Subnet Network End IP (in cidr notation) + /// + [JsonPropertyName("ip_end")] + public string? IpEnd { get; set; } = ""; + + + /// + /// Clone an IP Object + /// + public ModellingImportAreaIpData Clone() + { + return new ModellingImportAreaIpData + { + Name = this.Name, + Ip = this.Ip, + IpEnd = this.IpEnd + }; + } + } +} diff --git a/roles/middleware/files/FWO.Middleware.Server/NotificationService.cs b/roles/middleware/files/FWO.Middleware.Server/NotificationService.cs new file mode 100644 index 0000000000..a0c188698d --- /dev/null +++ b/roles/middleware/files/FWO.Middleware.Server/NotificationService.cs @@ -0,0 +1,379 @@ +using FWO.Api.Client; +using FWO.Api.Client.Queries; +using FWO.Basics; +using FWO.Basics.Exceptions; +using FWO.Data; +using FWO.Config.Api; +using FWO.Mail; +using FWO.Encryption; +using FWO.Logging; +using FWO.Report; +using FWO.Services; + +namespace FWO.Middleware.Server +{ + /// + /// Class to administrate and send Notifications + /// + public class NotificationService + { + /// + /// Notifications for current NotificationClient + /// + public readonly List Notifications; + private List CheckedNotificationIds = []; + private readonly ApiConnection ApiConnection; + private readonly GlobalConfig GlobalConfig; + private readonly List OwnerGroups; + + + NotificationService(List notifications, GlobalConfig globalConfig, ApiConnection apiConnection, List ownerGroups) + { + ApiConnection = apiConnection; + GlobalConfig = globalConfig; + Notifications = notifications; + OwnerGroups = ownerGroups; + } + + /// + /// async Constructor + /// + /// + /// + /// + /// + /// + public static async Task CreateAsync(NotificationClient notificationClient, GlobalConfig globalConfig, ApiConnection apiConnection, List ownerGroups) + { + List notifications = await LoadNotifications(notificationClient, apiConnection); + return new NotificationService(notifications, globalConfig, apiConnection, ownerGroups); + } + + /// + /// Analyse and send all Notifications if due, restricted to owner if given + /// + /// Owner for whom the notification is done + /// Deadline date e.g. from ticket, if not defined by owner (only for InterfaceClient) + /// Text for notification (e.g. email body) + /// Optional report to be sent as attachment + /// Optional resolved time interval text for placeholder replacement. + /// number of emails sent + public async Task SendNotificationsIfDue(FwoOwner? owner, DateTime? extDeadline, string? content, ReportBase? report = null, string timeIntervalText = "") + { + int emailsSent = 0; + foreach (var notification in Notifications.Where(n => n.OwnerId == null || n.OwnerId == owner?.Id)) + { + emailsSent += await SendNotificationIfDue(notification, owner, extDeadline, content, report, timeIntervalText); + } + return emailsSent; + } + + /// + /// Sends a single notification without checking if it is currently due. + /// + /// Notification to send. + /// Owner for whom the notification is sent. + /// Text for notification (e.g. email body). + /// Optional report to be sent as attachment. + /// Optional resolved time interval text for placeholder replacement. + /// number of emails sent + public async Task SendNotification(FwoNotification notification, FwoOwner? owner, string? content = null, ReportBase? report = null, string timeIntervalText = "") + { + // Later: Handle other channels here when implemented + await SendEmail(notification, content, owner, report, timeIntervalText); + if (!CheckedNotificationIds.Contains(notification.Id)) + { + CheckedNotificationIds.Add(notification.Id); + } + return 1; + } + + /// + /// Sends notifications grouped by bundle information. Notifications without bundle settings are sent individually. + /// + /// Notifications to send. + /// Owner for whom the notifications are sent. + /// Text for notification (e.g. email body). + /// Optional report to be sent as attachment. + /// Optional resolved time interval text for placeholder replacement. + /// number of emails sent + public async Task SendBundledNotifications(List notifications, FwoOwner? owner, string? content = null, ReportBase? report = null, string timeIntervalText = "") + { + int emailsSent = 0; + foreach (IGrouping notificationGroup in notifications.GroupBy(GetBundleGroupKey)) + { + List groupedNotifications = [.. notificationGroup]; + if (groupedNotifications.Count == 1 || groupedNotifications[0].BundleType == null) + { + emailsSent += await SendNotification(groupedNotifications[0], owner, content, report, timeIntervalText); + continue; + } + + await SendBundledEmail(groupedNotifications, content, owner, report, timeIntervalText); + foreach (FwoNotification notification in groupedNotifications) + { + if (!CheckedNotificationIds.Contains(notification.Id)) + { + CheckedNotificationIds.Add(notification.Id); + } + } + emailsSent++; + } + return emailsSent; + } + + /// + /// Analyse and send single Notification if due + /// + /// Notification to be handled + /// Owner for whom the notification is done + /// Deadline date e.g. from ticket, if not defined by owner (only for InterfaceClient) + /// Text for notification (e.g. email body) + /// Optional report to be sent as attachment + /// Optional resolved time interval text for placeholder replacement. + /// number of emails sent + public async Task SendNotificationIfDue(FwoNotification notification, FwoOwner? owner, DateTime? extDeadline, string? content = null, ReportBase? report = null, string timeIntervalText = "") + { + if (IsNotificationDue(owner, extDeadline, notification)) + { + return await SendNotification(notification, owner, content, report, timeIntervalText); + } + return 0; + } + + /// + /// Set the last sent date for all notifications used so far + /// + /// + public async Task UpdateNotificationsLastSent() + { + int updatedNotifications = (await ApiConnection.SendQueryAsync(NotificationQueries.updateNotificationsLastSent, new { ids = CheckedNotificationIds, lastSent = DateTime.Now })).AffectedRows; + CheckedNotificationIds = []; + return updatedNotifications; + } + + /// + /// Checks whether a notification is currently due for sending. + /// + /// Owner context used for owner-based deadlines. + /// External deadline (e.g. request date, rule expiry date). + /// Notification configuration to evaluate. + /// True if the notification should be sent now; otherwise false. + public static bool IsNotificationDue(FwoOwner? owner, DateTime? extDeadline, FwoNotification notification) + { + if (notification.Deadline == NotificationDeadline.None) + { + return true; + } + + DateTime deadline = GetDeadlineDate(notification.Deadline, owner, extDeadline); + + return deadline >= DateTime.Now + ? IsNotificationDueBeforeDeadline(deadline, notification) + : IsNotificationDueAfterDeadline(deadline, notification); + } + + private static bool IsTimeToSend(DateTime? lastSent, DateTime notifDate) + { + return (lastSent == null || ((DateTime)lastSent).Date < notifDate.Date) && notifDate.Date <= DateTime.Now.Date; + } + + private static bool TryGetConfiguredInterval(SchedulerInterval? interval, string propertyName, out SchedulerInterval configuredInterval) + { + if (interval != null) + { + configuredInterval = (SchedulerInterval)interval; + return true; + } + + Log.WriteWarning("Notifications", $"Notification interval '{propertyName}' is not configured. Skipping due evaluation."); + configuredInterval = default; + return false; + } + + private static bool IsNotificationDueBeforeDeadline(DateTime deadline, FwoNotification notification) + { + if (!TryGetConfiguredInterval(notification.IntervalBeforeDeadline, nameof(notification.IntervalBeforeDeadline), out SchedulerInterval intervalBeforeDeadline)) + { + return false; + } + + DateTime notifDate = ApplyIntervalOffset(deadline, intervalBeforeDeadline, -notification.OffsetBeforeDeadline ?? 0); + return IsTimeToSend(notification.LastSent, notifDate); + } + + private static bool IsNotificationDueAfterDeadline(DateTime deadline, FwoNotification notification) + { + if (!TryGetConfiguredInterval(notification.RepeatIntervalAfterDeadline, nameof(notification.RepeatIntervalAfterDeadline), out SchedulerInterval repeatIntervalAfterDeadline)) + { + return false; + } + + DateTime nextNotifDate = ApplyIntervalOffset(deadline.Date, repeatIntervalAfterDeadline, notification.InitialOffsetAfterDeadline ?? 0); + DateTime currentNotifDate = nextNotifDate; + int counter = -1; + while (nextNotifDate <= DateTime.Now.Date && counter++ <= notification.RepetitionsAfterDeadline) + { + currentNotifDate = nextNotifDate; + nextNotifDate = ApplyIntervalOffset(nextNotifDate, repeatIntervalAfterDeadline, notification.RepeatOffsetAfterDeadline ?? 0); + } + + return counter <= notification.RepetitionsAfterDeadline && IsTimeToSend(notification.LastSent, currentNotifDate); + } + + private static DateTime ApplyIntervalOffset(DateTime value, SchedulerInterval interval, int offset) + { + return interval switch + { + SchedulerInterval.Days => value.AddDays(offset), + SchedulerInterval.Weeks => value.AddDays(offset * GlobalConst.kDaysPerWeek), + SchedulerInterval.Months => value.AddMonths(offset), + _ => throw new NotSupportedException("Time interval is not supported.") + }; + } + + private static DateTime GetDeadlineDate(NotificationDeadline deadline, FwoOwner? owner, DateTime? extDeadline) + { + if (deadline == NotificationDeadline.RecertDate && owner?.NextRecertDate != null) + { + return (DateTime)owner.NextRecertDate; + } + else if (deadline == NotificationDeadline.RequestDate && extDeadline != null) + { + return (DateTime)extDeadline; + } + else if (deadline == NotificationDeadline.RuleExpiry && extDeadline != null) + { + return (DateTime)extDeadline; + } + else if (deadline == NotificationDeadline.DecommissionDate && owner?.DecommDate != null) + { + return (DateTime)owner.DecommDate; + } + return DateTime.Now; + } + + private static async Task> LoadNotifications(NotificationClient notificationClient, ApiConnection apiConnection) + { + return await apiConnection.SendQueryAsync>(NotificationQueries.getNotifications, new { client = notificationClient.ToString() }); + } + + private async Task SendEmail(FwoNotification notification, string? content, FwoOwner? owner, ReportBase? report = null, string timeIntervalText = "") + { + string decryptedSecret = AesEnc.TryDecrypt(GlobalConfig.EmailPassword, false, "NotificationService", "Could not decrypt mailserver password."); + EmailConnection emailConnection = new(GlobalConfig.EmailServerAddress, GlobalConfig.EmailPort, + GlobalConfig.EmailTls, GlobalConfig.EmailUser, decryptedSecret, GlobalConfig.EmailSenderAddress); + + MailData? mail = await PrepareEmail(notification, content, owner, report, timeIntervalText); + + await MailKitMailer.SendAsync(mail, emailConnection, notification.Layout == NotificationLayout.HtmlInBody, new()); + } + + private async Task SendBundledEmail(List notifications, string? content, FwoOwner? owner, ReportBase? report = null, string timeIntervalText = "") + { + string decryptedSecret = AesEnc.TryDecrypt(GlobalConfig.EmailPassword, false, "NotificationService", "Could not decrypt mailserver password."); + EmailConnection emailConnection = new(GlobalConfig.EmailServerAddress, GlobalConfig.EmailPort, + GlobalConfig.EmailTls, GlobalConfig.EmailUser, decryptedSecret, GlobalConfig.EmailSenderAddress); + + MailData mail = await PrepareBundledEmail(notifications, content, owner, report, timeIntervalText); + await MailKitMailer.SendAsync(mail, emailConnection, false, new()); + } + + private async Task PrepareEmail(FwoNotification notification, string? content, FwoOwner? owner, ReportBase? report = null, string timeIntervalText = "") + { + string subject = (notification.EmailSubject ?? "") + .Replace(Placeholder.APPNAME, owner?.Name ?? "") + .Replace(Placeholder.APPID, owner?.ExtAppId ?? "") + .Replace(Placeholder.TIME_INTERVAL, timeIntervalText); + string body = string.IsNullOrEmpty(content) ? notification.EmailBody ?? "" : content; + body = body.Replace(Placeholder.TIME_INTERVAL, timeIntervalText); + FormFile? attachment = report != null ? await BuildAttachment(notification, report, subject) : null; + if (report != null && notification.Layout == NotificationLayout.HtmlInBody) + { + body += report.ExportToHtml(); + } + MailData mailData = new(await CollectRecipients(notification, owner), subject) { Body = body, Cc = await CollectRecipients(notification, owner, true) }; + if (attachment != null) + { + mailData.Attachments = new FormFileCollection() { attachment }; + } + return mailData; + } + + private async Task PrepareBundledEmail(List notifications, string? content, FwoOwner? owner, ReportBase? report = null, string timeIntervalText = "") + { + FwoNotification baseNotification = notifications.First(); + MailData mailData = await PrepareEmail(baseNotification, content, owner, null, timeIntervalText); + if (report == null || baseNotification.BundleType == null) + { + return mailData; + } + + switch (baseNotification.BundleType) + { + case BundleType.Attachments: + FormFileCollection attachments = []; + foreach (FwoNotification notification in notifications) + { + FormFile? attachment = await BuildAttachment(notification, report, mailData.Subject); + if (attachment != null) + { + attachments.Add(attachment); + } + } + + if (attachments.Count > 0) + { + mailData.Attachments = attachments; + } + break; + default: + throw new NotSupportedException($"Bundle type {baseNotification.BundleType} is not supported."); + } + + return mailData; + } + + private static string GetBundleGroupKey(FwoNotification notification) + { + return notification.BundleType == null || string.IsNullOrWhiteSpace(notification.BundleId) + ? $"single:{notification.Id}" + : $"{notification.BundleType}:{notification.BundleId}"; + } + + private static async Task BuildAttachment(FwoNotification notification, ReportBase report, string subject) + { + switch (notification.Layout) + { + case NotificationLayout.PdfAsAttachment: + string html = report.ExportToHtml(); + string? pdfData = await report.ToPdf(html); + if (string.IsNullOrWhiteSpace(pdfData)) + { + throw new ProcessingFailedException("No Pdf generated."); + } + return EmailHelper.CreateAttachment(pdfData, GlobalConst.kPdf, subject); + case NotificationLayout.HtmlAsAttachment: + return EmailHelper.CreateAttachment(report.ExportToHtml(), GlobalConst.kHtml, subject); + case NotificationLayout.JsonAsAttachment: + return EmailHelper.CreateAttachment(report.ExportToJson(), GlobalConst.kJson, subject); + case NotificationLayout.CsvAsAttachment: + return EmailHelper.CreateAttachment(report.ExportToCsv(), GlobalConst.kCsv, subject); + default: + return null; + } + } + + private async Task> CollectRecipients(FwoNotification notification, FwoOwner? owner, bool cc = false) + { + if (GlobalConfig.UseDummyEmailAddress) + { + return [GlobalConfig.DummyEmailAddress]; + } + EmailHelper emailHelper = new(ApiConnection, null, new(), DefaultInit.DoNothing, OwnerGroups); + await emailHelper.Init(); + return await emailHelper.GetRecipients(cc ? notification.RecipientCc : notification.RecipientTo, null, owner, null, + EmailHelper.SplitAddresses(cc ? notification.EmailAddressCc : notification.EmailAddressTo)); + } + } +} diff --git a/roles/middleware/files/FWO.Middleware.Server/OwnerActiveRuleCheck.cs b/roles/middleware/files/FWO.Middleware.Server/OwnerActiveRuleCheck.cs new file mode 100644 index 0000000000..242351b42b --- /dev/null +++ b/roles/middleware/files/FWO.Middleware.Server/OwnerActiveRuleCheck.cs @@ -0,0 +1,79 @@ +using FWO.Api.Client; +using FWO.Api.Client.Queries; +using FWO.Config.Api; +using FWO.Data; + +namespace FWO.Middleware.Server +{ + /// + /// Checks whether an owner still has active rule-owner assignments and sends notifications when needed. + /// + public class OwnerActiveRuleCheck(ApiConnection apiConnection, GlobalConfig globalConfig) : RuleNotificationBodyBase(globalConfig) + { + /// + /// Fetches owners with a decommission date and sends due decommission notifications for each of them. + /// + /// The number of sent notifications. + public async Task CheckActiveRulesByScheduler() + { + List owners = await apiConnection.SendQueryAsync>(OwnerQueries.getOwners); + int emailsSent = 0; + + foreach (FwoOwner owner in owners.Where(o => o.DecommDate != null)) + { + emailsSent += await CheckActiveRules(owner, NotificationDeadline.DecommissionDate); + } + + return emailsSent; + } + + /// + /// Fetches all active rules for an owner and sends immediate decommission notifications for them. + /// + /// Owner whose active rules should be checked. + /// The number of sent notifications. + public async Task CheckActiveRulesSync(FwoOwner owner) + { + return await CheckActiveRules(owner, NotificationDeadline.None); + } + + /// + /// Fetches all active rules for an owner and sends matching notifications. + /// + /// Owner whose active rules should be checked. + /// Notification deadline to handle. + /// The number of sent notifications. + private async Task CheckActiveRules(FwoOwner owner, NotificationDeadline deadline) + { + if (owner.Id <= 0) + { + return 0; + } + + List activeRules = await apiConnection.SendQueryAsync>(RuleQueries.getActiveRulesByOwner, new { ownerId = owner.Id }); + if (activeRules.Count == 0) + { + return 0; + } + + List ownerGroups = await MiddlewareServerServices.GetInternalGroups(apiConnection); + NotificationService notificationService = await NotificationService.CreateAsync( + NotificationClient.AppDecomm, GlobalConfig, apiConnection, ownerGroups); + + IOrderedEnumerable orderedRules = activeRules.OrderBy(rule => rule.Uid, StringComparer.OrdinalIgnoreCase); + string textBody = BuildRuleTextBody(owner, GlobalConfig.OwnerActiveRuleEmailBody, "", orderedRules); + string htmlBody = BuildRuleHtmlBody(owner, GlobalConfig.OwnerActiveRuleEmailBody, "", orderedRules); + int emailsSent = 0; + foreach (FwoNotification notification in notificationService.Notifications.Where(n => (n.OwnerId == null || n.OwnerId == owner.Id) && n.Deadline == deadline)) + { + string body = notification.Layout == NotificationLayout.HtmlInBody ? htmlBody : textBody; + emailsSent += deadline == NotificationDeadline.None + ? await notificationService.SendNotification(notification, owner, body) + : await notificationService.SendNotificationIfDue(notification, owner, null, body); + } + + await notificationService.UpdateNotificationsLastSent(); + return emailsSent; + } + } +} diff --git a/roles/middleware/files/FWO.Middleware.Server/OwnerChangeImportTracker.cs b/roles/middleware/files/FWO.Middleware.Server/OwnerChangeImportTracker.cs new file mode 100644 index 0000000000..56f7ac8d04 --- /dev/null +++ b/roles/middleware/files/FWO.Middleware.Server/OwnerChangeImportTracker.cs @@ -0,0 +1,87 @@ +using FWO.Api.Client; +using FWO.Api.Client.Queries; +using FWO.Basics; +using FWO.Data; +using FWO.Logging; + +namespace FWO.Middleware.Server +{ + /// + /// Class handling the OwnerChange Data Import and tracking the import process in the database + /// + public class OwnerChangeImportTracker + { + private readonly ApiConnection apiConnection; + private long _importControlId = 0; + + /// + /// Constructor for OwngerChange Data Import Tracker + /// + public OwnerChangeImportTracker(ApiConnection apiConnection) + { + this.apiConnection = apiConnection; + } + + + /// + /// Ensure create Import_control when there are OwnerChanges + /// + public async Task EnsureAnCreateImportControl() + { + if (_importControlId != 0) + { + return _importControlId; + } + + var result = await apiConnection.SendQueryAsync(ImportQueries.addImportForOwner, new { importTypeId = ImportType.OWNER }); + + var firstControl = result.Returning.FirstOrDefault(); + if (firstControl == null) + { + throw new InvalidOperationException("Failed to create ImportControl. Returning list empty."); + } + + _importControlId = firstControl.ControlId; + + return _importControlId; + } + + /// + /// create changelog_owner entrie when there are OwnerChanges + /// + public async Task AddOwnerChange(long? oldOwnerId, long? newOwnerId, char action, string? importSource) + { + var controlId = await EnsureAnCreateImportControl(); + + var variables = new + { + control_id = controlId, + old_owner_id = oldOwnerId, + new_owner_id = newOwnerId, + change_action = action, + source_id = importSource + }; + + await apiConnection.SendQueryAsync(OwnerQueries.updateChangelogOwner, variables); + } + + /// + /// Ensure Import_control closes with success or failure after the import process is finished + /// + public async Task CompleteImport(bool successful) + { + if (_importControlId == 0) return; + + await apiConnection.SendQueryAsync(ImportQueries.updateImportControlForRuleOwnerFull, + new + { + controlId = _importControlId, + stopTime = DateTime.UtcNow, + successful = successful, + rule_owner_mapping_done = false + }); + + _importControlId = 0; + } + } +} diff --git a/roles/middleware/files/FWO.Middleware.Server/Program.cs b/roles/middleware/files/FWO.Middleware.Server/Program.cs index 9ac3c2dc86..597a5dbba2 100644 --- a/roles/middleware/files/FWO.Middleware.Server/Program.cs +++ b/roles/middleware/files/FWO.Middleware.Server/Program.cs @@ -1,34 +1,32 @@ using FWO.Api.Client; using FWO.Api.Client.Queries; +using FWO.Config.Api; using FWO.Config.File; using FWO.Logging; using FWO.Middleware.Server; +using FWO.Middleware.Server.Services; using Microsoft.AspNetCore.Authentication.JwtBearer; using Microsoft.IdentityModel.Tokens; -using Microsoft.OpenApi.Models; +using Microsoft.OpenApi; +using Quartz; using System.Reflection; -// Implicitly call static constructor so backround lock process is started +// Implicitly call static constructor so background lock process is started // (static constructor is only called after class is used in any way) Log.WriteInfo("Startup", "Starting FWO Middleware Server..."); -object changesLock = new object(); // LOCK - -ReportScheduler reportScheduler; -AutoDiscoverScheduler autoDiscoverScheduler; -DailyCheckScheduler dailyCheckScheduler; +object changesLock = new(); // LOCK WebApplicationBuilder builder = WebApplication.CreateBuilder(args); -builder.WebHost.UseUrls(ConfigFile.MiddlewareServerNativeUri ?? throw new Exception("Missing middleware server url on startup.")); +builder.WebHost.UseUrls(ConfigFile.MiddlewareServerNativeUri ?? throw new ArgumentException("Missing middleware server url on startup.")); // Create Token Generator -JwtWriter jwtWriter = new JwtWriter(ConfigFile.JwtPrivateKey); +JwtWriter jwtWriter = new(ConfigFile.JwtPrivateKey); // Create JWT for middleware-server API calls (relevant part is the role middleware-server) and add it to the Api connection header. -ApiConnection apiConnection = new GraphQlApiConnection(ConfigFile.ApiServerUri ?? throw new Exception("Missing api server url on startup."), jwtWriter.CreateJWTMiddlewareServer()); +ApiConnection apiConnection = new GraphQlApiConnection(ConfigFile.ApiServerUri ?? throw new ArgumentException("Missing api server url on startup."), jwtWriter.CreateJWTMiddlewareServer()); -// Fetch all connectedLdaps via API (blocking). -List connectedLdaps = new List(); +List connectedLdaps = []; int connectionAttemptsCount = 1; while (true) { @@ -45,40 +43,47 @@ } } -Action handleSubscriptionException = (Exception exception) => Log.WriteError("Subscription", "Subscription lead to exception.", exception); +Action handleSubscriptionException = exception => Log.WriteError("Subscription", "Subscription lead to exception.", exception); GraphQlApiSubscription>.SubscriptionUpdate connectedLdapsSubscriptionUpdate = (List ldapsChanges) => { lock (changesLock) { connectedLdaps = ldapsChanges; } }; GraphQlApiSubscription> connectedLdapsSubscription = apiConnection.GetSubscription>(handleSubscriptionException, connectedLdapsSubscriptionUpdate, AuthQueries.getLdapConnectionsSubscription); Log.WriteInfo("Found ldap connection to server", string.Join("\n", connectedLdaps.ConvertAll(ldap => $"{ldap.Address}:{ldap.Port}"))); -// Create and start report scheduler -Task.Factory.StartNew(() => -{ - reportScheduler = new ReportScheduler(apiConnection, jwtWriter, connectedLdapsSubscription); -}, TaskCreationOptions.LongRunning); +// GlobalConfig for Quartz DI +GlobalConfig globalConfig = await GlobalConfig.ConstructAsync(apiConnection, true); -// Create and start auto disovery scheduler -Task.Factory.StartNew(async() => +builder.Services.AddQuartz(); +builder.Services.AddQuartzHostedService(options => { - autoDiscoverScheduler = await AutoDiscoverScheduler.CreateAsync(apiConnection); -}, TaskCreationOptions.LongRunning); + options.WaitForJobsToComplete = true; +}); -// Create and start daily check scheduler -Task.Factory.StartNew(async() => -{ - dailyCheckScheduler = await DailyCheckScheduler.CreateAsync(apiConnection); -}, TaskCreationOptions.LongRunning); +// Register singletons for DI +builder.Services.AddSingleton(apiConnection); +builder.Services.AddSingleton(globalConfig); +builder.Services.AddSingleton(); + +// Register config listeners as singletons (activated at startup) +builder.Services.AddSingleton(); +builder.Services.AddSingleton(); +builder.Services.AddSingleton(); +builder.Services.AddSingleton(); +builder.Services.AddSingleton(); +builder.Services.AddSingleton(); +builder.Services.AddSingleton(); +builder.Services.AddSingleton(); +builder.Services.AddSingleton(); +builder.Services.AddSingleton(); // Add services to the container. builder.Services.AddControllers() .AddJsonOptions(jsonOptions => { - //jsonOptions.JsonSerializerOptions.PropertyNameCaseInsensitive = true; - jsonOptions.JsonSerializerOptions.PropertyNamingPolicy = null; + //jsonOptions.JsonSerializerOptions.PropertyNameCaseInsensitive = true; + jsonOptions.JsonSerializerOptions.PropertyNamingPolicy = null; }); builder.Services.AddSingleton(jwtWriter); builder.Services.AddSingleton>(connectedLdaps); -builder.Services.AddScoped(_ => new GraphQlApiConnection(ConfigFile.ApiServerUri, jwtWriter.CreateJWTMiddlewareServer())); builder.Services.AddAuthentication(confOptions => { @@ -91,8 +96,10 @@ { RequireExpirationTime = true, RequireSignedTokens = true, - ValidateAudience = false, - ValidateIssuer = false, + ValidateAudience = true, + ValidAudiences = [FWO.Basics.JwtConstants.Audience], + ValidateIssuer = true, + ValidIssuers = [FWO.Basics.JwtConstants.Issuer], ValidateLifetime = true, RoleClaimType = "role", IssuerSigningKey = ConfigFile.JwtPublicKey @@ -110,7 +117,7 @@ c.IncludeXmlComments(documentationPath); }); -var app = builder.Build(); +WebApplication app = builder.Build(); // Configure the HTTP request pipeline. if (app.Environment.IsDevelopment()) @@ -128,9 +135,24 @@ app.UseAuthentication(); app.UseAuthorization(); -app.UseEndpoints(endpoints => -{ - endpoints.MapControllers(); -}); - -app.Run(); +app.MapControllers(); + +//Register JobExecutionTracker with scheduler +ISchedulerFactory schedulerFactory = app.Services.GetRequiredService(); +JobExecutionTracker executionTracker = app.Services.GetRequiredService(); +IScheduler scheduler = await schedulerFactory.GetScheduler(); +scheduler.ListenerManager.AddJobListener(executionTracker); + +// Activate config listeners so they attach subscriptions after startup +app.Services.GetRequiredService(); +app.Services.GetRequiredService(); +app.Services.GetRequiredService(); +app.Services.GetRequiredService(); +app.Services.GetRequiredService(); +app.Services.GetRequiredService(); +app.Services.GetRequiredService(); +app.Services.GetRequiredService(); +app.Services.GetRequiredService(); +app.Services.GetRequiredService(); + +await app.RunAsync(); diff --git a/roles/middleware/files/FWO.Middleware.Server/Properties/launchSettings.json b/roles/middleware/files/FWO.Middleware.Server/Properties/launchSettings.json index aa08d78d52..31a046d0d2 100644 --- a/roles/middleware/files/FWO.Middleware.Server/Properties/launchSettings.json +++ b/roles/middleware/files/FWO.Middleware.Server/Properties/launchSettings.json @@ -1,9 +1,9 @@ -{ +{ "$schema": "http://json.schemastore.org/launchsettings.json", "profiles": { "FWO.Middleware": { "commandName": "Project", - "dotnetRunMessages": "true", + "dotnetRunMessages": true, "launchBrowser": true, "launchUrl": "swagger", "applicationUrl": "http://localhost:8880", diff --git a/roles/middleware/files/FWO.Middleware.Server/RecertCheck.cs b/roles/middleware/files/FWO.Middleware.Server/RecertCheck.cs index b20acfb7c2..efbb1bc68b 100644 --- a/roles/middleware/files/FWO.Middleware.Server/RecertCheck.cs +++ b/roles/middleware/files/FWO.Middleware.Server/RecertCheck.cs @@ -1,15 +1,20 @@ -using FWO.Api.Client; +using FWO.Api.Client; using FWO.Api.Client.Queries; -using FWO.Api.Data; -using FWO.Config.File; +using FWO.Basics; using FWO.Config.Api; using FWO.Config.Api.Data; +using FWO.Config.File; +using FWO.Data; +using FWO.Data.Middleware; +using FWO.Data.Report; +using FWO.Encryption; using FWO.Logging; using FWO.Mail; -using FWO.Middleware.RequestParameters; using FWO.Report; -using FWO.Report.Filter; - +using FWO.Services; +using System; +using System.Linq; +using System.Text; namespace FWO.Middleware.Server { @@ -19,11 +24,12 @@ namespace FWO.Middleware.Server public class RecertCheck { private readonly ApiConnection apiConnectionMiddlewareServer; - private GlobalConfig globalConfig; - private List groups = new List(); - private List uiUsers = new List(); + private readonly GlobalConfig globalConfig; + private List connectedLdaps = []; + private List uiUsers = []; private RecertCheckParams? globCheckParams; - private List owners = new List(); + private List owners = []; + private const string LogMessageTitle = "Recertification Check"; /// /// Constructor for Recertification check class @@ -43,32 +49,34 @@ public async Task CheckRecertifications() try { await InitEnv(); - EmailConnection emailConnection = new EmailConnection(globalConfig.EmailServerAddress, globalConfig.EmailPort, - globalConfig.EmailTls, globalConfig.EmailUser, globalConfig.EmailPassword, globalConfig.EmailSenderAddress); - MailKitMailer mailer = new MailKitMailer(emailConnection); - JwtWriter jwtWriter = new JwtWriter(ConfigFile.JwtPrivateKey); - ApiConnection apiConnectionReporter = new GraphQlApiConnection(ConfigFile.ApiServerUri ?? throw new Exception("Missing api server url on startup."), jwtWriter.CreateJWTReporterViewall()); - - foreach(var owner in owners) + if (globalConfig.RecertificationMode == RecertificationMode.RuleByRule) { - if(isCheckTime(owner)) + string decryptedSecret = AesEnc.TryDecrypt(globalConfig.EmailPassword, false, LogMessageTitle, "Could not decrypt mailserver password."); + EmailConnection emailConnection = new(globalConfig.EmailServerAddress, globalConfig.EmailPort, + globalConfig.EmailTls, globalConfig.EmailUser, decryptedSecret, globalConfig.EmailSenderAddress); + JwtWriter jwtWriter = new(ConfigFile.JwtPrivateKey); + ApiConnection apiConnectionReporter = new GraphQlApiConnection(ConfigFile.ApiServerUri ?? throw new ArgumentException("Missing api server url on startup."), jwtWriter.CreateJWTReporterViewall()); + foreach (FwoOwner owner in owners) { - // todo: refine handling - List upcomingRecerts = await generateRecertificationReport(apiConnectionReporter, owner, false); - List overdueRecerts = new List(); // await generateRecertificationReport(apiConnectionReporter, owner, true); - - if(upcomingRecerts.Count > 0 || overdueRecerts.Count > 0) - { - await mailer.SendAsync(prepareEmail(owner, upcomingRecerts, overdueRecerts), emailConnection, new CancellationToken()); - emailsSent++; - } - await setOwnerLastCheck(owner); + emailsSent += await CheckRuleByRule(owner, apiConnectionReporter, emailConnection); + await SetOwnerLastCheck(owner); } } + else + { + List OwnerGroups = await MiddlewareServerServices.GetInternalGroups(apiConnectionMiddlewareServer); + NotificationService notificationService = await NotificationService.CreateAsync(NotificationClient.Recertification, globalConfig, apiConnectionMiddlewareServer, OwnerGroups); + foreach (FwoOwner? owner in owners.Where(o => IsRecertCheckTime(o))) + { + emailsSent += await notificationService.SendNotificationsIfDue(owner, null, PrepareOwnerBody(owner), await PrepareOwnerReport(owner)); + await SetOwnerLastCheck(owner); + } + await notificationService.UpdateNotificationsLastSent(); + } } - catch(Exception exception) + catch (Exception exception) { - Log.WriteError("Recertification Check", $"Checking owners for upcoming recertifications leads to exception.", exception); + Log.WriteError(LogMessageTitle, $"Checking owners for upcoming recertifications leads to exception.", exception); } return emailsSent; } @@ -76,180 +84,195 @@ public async Task CheckRecertifications() private async Task InitEnv() { globCheckParams = System.Text.Json.JsonSerializer.Deserialize(globalConfig.RecCheckParams); - List connectedLdaps = apiConnectionMiddlewareServer.SendQueryAsync>(AuthQueries.getLdapConnections).Result; - foreach (Ldap currentLdap in connectedLdaps) + connectedLdaps = apiConnectionMiddlewareServer.SendQueryAsync>(AuthQueries.getLdapConnections).Result; + uiUsers = await apiConnectionMiddlewareServer.SendQueryAsync>(AuthQueries.getUsers); + owners = await apiConnectionMiddlewareServer.SendQueryAsync>(OwnerQueries.getOwners); + } + + private bool IsRecertCheckTime(FwoOwner owner) + { + if (!owner.RecertActive) + { + return false; + } + RecertCheckParams checkParams = (owner.RecertCheckParamString != null && owner.RecertCheckParamString != "" ? + System.Text.Json.JsonSerializer.Deserialize(owner.RecertCheckParamString) : + globCheckParams) ?? throw new ArgumentException("Config Parameters not set."); + DateTime lastCheck = owner.LastRecertCheck ?? DateTime.MinValue; + DateTime nextCheck = checkParams.RecertCheckInterval switch + { + SchedulerInterval.Days => lastCheck.AddDays(checkParams.RecertCheckOffset), + SchedulerInterval.Weeks => CalcForWeeks(lastCheck, checkParams), + SchedulerInterval.Months => CalcForMonths(lastCheck, checkParams), + _ => throw new NotSupportedException("Time interval is not supported.") + }; + if (nextCheck <= DateTime.Today) + { + return true; + } + return false; + } + + private static DateTime CalcForWeeks(DateTime lastCheck, RecertCheckParams checkParams) + { + DateTime nextCheck; + if (checkParams.RecertCheckWeekday == null) { - if (currentLdap.IsInternal() && currentLdap.HasGroupHandling()) + nextCheck = lastCheck.AddDays(checkParams.RecertCheckOffset * GlobalConst.kDaysPerWeek); + } + else + { + nextCheck = lastCheck.AddDays((checkParams.RecertCheckOffset - 1) * GlobalConst.kDaysPerWeek + 1); + int count = 0; + while (nextCheck.DayOfWeek != (DayOfWeek)checkParams.RecertCheckWeekday && count < 6) { - groups.AddRange(currentLdap.GetAllInternalGroups()); + nextCheck = nextCheck.AddDays(1); + count++; } } - uiUsers = await apiConnectionMiddlewareServer.SendQueryAsync>(FWO.Api.Client.Queries.AuthQueries.getUsers); - owners = await apiConnectionMiddlewareServer.SendQueryAsync>(FWO.Api.Client.Queries.OwnerQueries.getOwners); + return nextCheck; } - private bool isCheckTime(FwoOwner owner) + private static DateTime CalcForMonths(DateTime lastCheck, RecertCheckParams checkParams) { - RecertCheckParams checkParams = (owner.RecertCheckParamString != null && owner.RecertCheckParamString != "" ? - System.Text.Json.JsonSerializer.Deserialize(owner.RecertCheckParamString) : - globCheckParams) ?? throw new Exception("Config Parameters not set."); - DateTime lastCheck = owner.LastRecertCheck ?? DateTime.MinValue; DateTime nextCheck; - - switch (checkParams.RecertCheckInterval) + if (checkParams.RecertCheckDayOfMonth == null) { - case Interval.Days: - nextCheck = lastCheck.AddDays(checkParams.RecertCheckOffset); - break; - case Interval.Weeks: - if(checkParams.RecertCheckWeekday == null) - { - nextCheck = lastCheck.AddDays(checkParams.RecertCheckOffset * 7); - } - else - { - nextCheck = lastCheck.AddDays((checkParams.RecertCheckOffset - 1) * 7 + 1); - int count = 0; - while(nextCheck.DayOfWeek != (DayOfWeek)checkParams.RecertCheckWeekday && count < 6) - { - nextCheck = nextCheck.AddDays(1); - count++; - } - } - break; - case Interval.Months: - if(checkParams.RecertCheckDayOfMonth == null) - { - nextCheck = lastCheck.AddMonths(checkParams.RecertCheckOffset); - } - else - { - nextCheck = lastCheck.AddMonths(checkParams.RecertCheckOffset - 1); - nextCheck = nextCheck.AddDays(1); - int count = 0; - while(nextCheck.Day != (int)checkParams.RecertCheckDayOfMonth && count < 30) - { - nextCheck = nextCheck.AddDays(1); - count++; - } - if(nextCheck.Day != (int)checkParams.RecertCheckDayOfMonth) - { - // missed the day because or month change: set to first of following month - nextCheck = nextCheck.AddDays(1 - nextCheck.Day); - } - } - break; - default: - throw new NotSupportedException("Time interval is not supported."); + nextCheck = lastCheck.AddMonths(checkParams.RecertCheckOffset); } + else + { + nextCheck = lastCheck.AddMonths(checkParams.RecertCheckOffset - 1); + nextCheck = nextCheck.AddDays(1); + int count = 0; + while (nextCheck.Day != (int)checkParams.RecertCheckDayOfMonth && count < 30) + { + nextCheck = nextCheck.AddDays(1); + count++; + } + if (nextCheck.Day != (int)checkParams.RecertCheckDayOfMonth) + { + // missed the day because or month change: set to first of following month + nextCheck = nextCheck.AddDays(1 - nextCheck.Day); + } + } + return nextCheck; + } - if(nextCheck <= DateTime.Today) + private async Task CheckRuleByRule(FwoOwner owner, ApiConnection apiConnection, EmailConnection emailConnection) + { + List openRecerts = await GenerateRulesRecertificationReport(apiConnection, owner); + List upcomingRecerts = []; + List overdueRecerts = []; + foreach (Rule rule in openRecerts) { - return true; + if (rule.Metadata.RuleRecertification.Count > 0 && rule.Metadata.RuleRecertification[0].NextRecertDate >= DateTime.Now) + { + upcomingRecerts.Add(rule); + } + else + { + overdueRecerts.Add(rule); + } } - return false; + if (upcomingRecerts.Count > 0 || overdueRecerts.Count > 0) + { + await MailKitMailer.SendAsync(await PrepareRulesEmail(owner, upcomingRecerts, overdueRecerts), emailConnection, false, new()); + return 1; + } + return 0; } - private async Task> generateRecertificationReport(ApiConnection apiConnection, FwoOwner owner, bool overdueOnly) + private async Task> GenerateRulesRecertificationReport(ApiConnection apiConnection, FwoOwner owner) { - List rules = new List(); + List rules = []; try { - CancellationToken token = new CancellationToken(); - UserConfig userConfig = new UserConfig(globalConfig); + UserConfig userConfig = new(globalConfig); - DeviceFilter deviceFilter = new DeviceFilter(); - deviceFilter.Managements = await apiConnection.SendQueryAsync>(DeviceQueries.getDevicesByManagements); - deviceFilter.applyFullDeviceSelection(true); - - RecertFilter recertFilter = new RecertFilter() + DeviceFilter deviceFilter = new() { - RecertOwnerList = new List() { owner.Id }, - RecertOverdueOnly = overdueOnly, - RecertificationDisplayPeriod = globalConfig.RecertificationNoticePeriod + Managements = await apiConnection.SendQueryAsync>(DeviceQueries.getDevicesByManagement) }; - ReportTemplate reportParams = new ReportTemplate("", deviceFilter, (int) ReportType.Recertification, new TimeFilter(), recertFilter, null); - ReportBase? currentReport = ReportBase.ConstructReport(reportParams, userConfig); - - Management[] managements = new Management[0]; + deviceFilter.ApplyFullDeviceSelection(true); - await currentReport.Generate(int.MaxValue, apiConnection, - managementsReportIntermediate => + ReportParams reportParams = new((int)ReportType.Recertification, deviceFilter) { - managements = managementsReportIntermediate; - return Task.CompletedTask; - }, token); + RecertFilter = new() + { + RecertOwnerList = [owner.Id], + RecertificationDisplayPeriod = globalConfig.RecertificationNoticePeriod + } + }; + + ReportData reportData = (await ReportGenerator.GenerateFromTemplate(new ReportTemplate("", reportParams), apiConnection, userConfig, DefaultInit.DoNothing))?.ReportData ?? new(); - foreach (Management management in managements) + foreach (ManagementReport management in reportData.ManagementData) { - foreach (Device device in management.Devices) + foreach (var rulebase in management.Rulebases) { - if (device.ContainsRules()) + foreach (var rule in rulebase.Rules) { - foreach (Rule rule in device.Rules!) - { - rule.Metadata.UpdateRecertPeriods(owner.RecertInterval ?? globalConfig.RecertificationPeriod, 0); - rule.DeviceName = device.Name ?? ""; - rules.Add(rule); - } + rules.Add(rule); } } } } catch (Exception exception) { - Log.WriteError("Recertification Check", $"Report for owner {owner.Name} leads to exception.", exception); + Log.WriteError(LogMessageTitle, $"Report for owner {owner.Name} leads to exception.", exception); } return rules; } - private MailData prepareEmail(FwoOwner owner, List upcomingRecerts, List overdueRecerts) + private async Task PrepareRulesEmail(FwoOwner owner, List upcomingRecerts, List overdueRecerts) { string subject = globalConfig.RecCheckEmailSubject + " " + owner.Name; - string body = ""; - if(upcomingRecerts.Count > 0) + return new MailData(await CollectEmailAddresses(owner), subject) { Body = PrepareRulesBody(upcomingRecerts, overdueRecerts, owner.Name) }; + } + + private string PrepareRulesBody(List upcomingRecerts, List overdueRecerts, string ownerName) + { + StringBuilder body = new(); + if (upcomingRecerts.Count > 0) { - body += globalConfig.RecCheckEmailUpcomingText + "\r\n\r\n"; - foreach(var rule in upcomingRecerts) + body.AppendLine(globalConfig.RecCheckEmailUpcomingText.Replace(Placeholder.APPNAME, ownerName) + "\r\n\r\n"); + foreach (var rule in upcomingRecerts) { - body += prepareLine(rule); + body.AppendLine(PrepareLine(rule)); } } - if(overdueRecerts.Count > 0) + body.AppendLine("\r\n\r\n"); + if (overdueRecerts.Count > 0) { - body += globalConfig.RecCheckEmailOverdueText + "\r\n\r\n"; - foreach(var rule in overdueRecerts) + body.AppendLine(globalConfig.RecCheckEmailOverdueText.Replace(Placeholder.APPNAME, ownerName) + "\r\n\r\n"); + foreach (Rule rule in overdueRecerts) { - body += prepareLine(rule); + body.AppendLine(PrepareLine(rule)); } } - return new MailData(collectEmailAddresses(owner), subject, body); + return body.ToString(); } - private string prepareLine(Rule rule) + private static string PrepareLine(Rule rule) { Recertification? nextRecert = rule.Metadata.RuleRecertification.FirstOrDefault(x => x.RecertDate == null); - return (nextRecert != null && nextRecert.NextRecertDate != null ? DateOnly.FromDateTime((DateTime)nextRecert.NextRecertDate) : "") + ": " + return (nextRecert != null && nextRecert.NextRecertDate != null ? DateOnly.FromDateTime((DateTime)nextRecert.NextRecertDate) : "") + ": " + rule.DeviceName + ": " + rule.Name + ":" + rule.Uid + "\r\n\r\n"; // link ? } - private List collectEmailAddresses(FwoOwner owner) + private async Task> CollectEmailAddresses(FwoOwner owner) { - List tos = new List(); - List userDns = new List(); - if(owner.Dn != "") - { - userDns.Add(owner.Dn); - } - GroupGetReturnParameters? ownerGroup = groups.FirstOrDefault(x => x.GroupDn == owner.GroupDn); - if(ownerGroup != null) + if (globalConfig.UseDummyEmailAddress) { - userDns.AddRange(ownerGroup.Members); + return [globalConfig.DummyEmailAddress]; } - foreach(var userDn in userDns) + List tos = []; + List userDns = await ResolveOwnerUserDns(owner); + foreach (var userDn in userDns) { UiUser? uiuser = uiUsers.FirstOrDefault(x => x.Dn == userDn); - if(uiuser != null && uiuser.Email != null && uiuser.Email != "") + if (uiuser != null && uiuser.Email != null && uiuser.Email != "") { tos.Add(uiuser.Email); } @@ -257,14 +280,85 @@ private List collectEmailAddresses(FwoOwner owner) return tos; } - private async Task setOwnerLastCheck(FwoOwner owner) + private async Task> ResolveOwnerUserDns(FwoOwner owner) + { + List ownerDns = owner.GetAllOwnerResponsibles(); + if (ownerDns.Count == 0) + { + return []; + } + + HashSet resolvedUsers = new(StringComparer.OrdinalIgnoreCase); + object resolvedLock = new(); + List ldapRequests = []; + + foreach (Ldap currentLdap in connectedLdaps.Where(ldap => ldap.HasGroupHandling())) + { + ldapRequests.Add(Task.Run(async () => + { + List currentResolved = await currentLdap.ResolveUsersFromDns(ownerDns); + if (currentResolved.Count == 0) + { + return; + } + + lock (resolvedLock) + { + foreach (string dn in currentResolved) + { + resolvedUsers.Add(dn); + } + } + })); + } + + await Task.WhenAll(ldapRequests); + + foreach (string dn in ownerDns) + { + if (string.IsNullOrWhiteSpace(dn)) + { + continue; + } + bool isGroupDn = connectedLdaps.Any(ldap => ldap.HasGroupHandling() + && !string.IsNullOrWhiteSpace(ldap.GroupSearchPath) + && dn.EndsWith(ldap.GroupSearchPath, StringComparison.OrdinalIgnoreCase)); + if (!isGroupDn) + { + resolvedUsers.Add(dn); + } + } + + return resolvedUsers.ToList(); + } + + private string PrepareOwnerBody(FwoOwner owner) + { + string msgText = owner.NextRecertDate >= DateTime.Today ? globalConfig.RecCheckEmailUpcomingText : globalConfig.RecCheckEmailOverdueText; + return msgText.Replace(Placeholder.APPNAME, owner.Name); + } + + private async Task PrepareOwnerReport(FwoOwner owner) + { + ReportParams reportParams = new((int)ReportType.OwnerRecertification, new()) + { + ModellingFilter = new() + { + SelectedOwner = owner + } + }; + using UserConfig userConfig = new(globalConfig); + return await ReportGenerator.GenerateFromTemplate(new ReportTemplate("", reportParams), apiConnectionMiddlewareServer, userConfig, DefaultInit.DoNothing); + } + + private async Task SetOwnerLastCheck(FwoOwner owner) { var Variables = new { id = owner.Id, lastRecertCheck = DateTime.Now }; - await apiConnectionMiddlewareServer.SendQueryAsync(FWO.Api.Client.Queries.OwnerQueries.setOwnerLastCheck, Variables); + await apiConnectionMiddlewareServer.SendQueryAsync(OwnerQueries.setOwnerLastCheck, Variables); } } } diff --git a/roles/middleware/files/FWO.Middleware.Server/ReportScheduler.cs b/roles/middleware/files/FWO.Middleware.Server/ReportScheduler.cs deleted file mode 100644 index 5e9e4edc56..0000000000 --- a/roles/middleware/files/FWO.Middleware.Server/ReportScheduler.cs +++ /dev/null @@ -1,240 +0,0 @@ -using FWO.Api.Data; -using FWO.Api.Client; -using FWO.Api.Client.Queries; -using FWO.Config.Api; -using FWO.Logging; -using FWO.Middleware.Controllers; -using FWO.Report; -using FWO.Report.Filter; -using System.Timers; -using WkHtmlToPdfDotNet; -using FWO.Config.File; - -namespace FWO.Middleware.Server -{ - /// - /// Report scheduler class - /// - public class ReportScheduler - { - private readonly object scheduledReportsLock = new object(); - private List scheduledReports = new List(); - private readonly TimeSpan CheckScheduleInterval = TimeSpan.FromMinutes(1); - - private readonly string apiServerUri; - private readonly ApiConnection apiConnection; - private readonly GraphQlApiSubscription scheduledReportsSubscription; - private readonly JwtWriter jwtWriter; - - private readonly object ldapLock = new object(); - private List connectedLdaps; - - /// - /// Constructor needing connection, jwtWriter and subscription to connected ldaps - /// - public ReportScheduler(ApiConnection apiConnection, JwtWriter jwtWriter, GraphQlApiSubscription> connectedLdapsSubscription) - { - this.jwtWriter = jwtWriter; - this.apiConnection = apiConnection; - apiServerUri = ConfigFile.ApiServerUri; - - connectedLdaps = apiConnection.SendQueryAsync>(AuthQueries.getLdapConnections).Result; - connectedLdapsSubscription.OnUpdate += OnLdapUpdate; - - //scheduledReports = apiConnection.SendQueryAsync(ReportQueries.getReportSchedules).Result.ToList(); - scheduledReportsSubscription = apiConnection.GetSubscription(ApiExceptionHandler, OnScheduleUpdate, ReportQueries.subscribeReportScheduleChanges); - - System.Timers.Timer checkScheduleTimer = new(); - checkScheduleTimer.Elapsed += CheckSchedule; - checkScheduleTimer.Interval = CheckScheduleInterval.TotalMilliseconds; - checkScheduleTimer.AutoReset = true; - checkScheduleTimer.Start(); - } - - private void OnLdapUpdate(List connectedLdaps) - { - lock(ldapLock) - { - this.connectedLdaps = connectedLdaps; - } - } - - private void OnScheduleUpdate(ScheduledReport[] scheduledReports) - { - lock (scheduledReportsLock) - { - this.scheduledReports = scheduledReports.ToList(); - } - } - - private void ApiExceptionHandler(Exception exception) - { - Log.WriteError("Report scheduler", "Api subscription lead to exception. Retry subscription.", exception); - // Subscription will be restored if no exception is thrown here - } - - private async void CheckSchedule(object? _, ElapsedEventArgs __) - { - List reportGeneratorTasks = new List(); - - DateTime dateTimeNowRounded = RoundDown(DateTime.Now, CheckScheduleInterval); - - lock (scheduledReports) - { - foreach (ScheduledReport scheduledReport in scheduledReports) - { - try - { - if (scheduledReport.Active) - { - // Add schedule interval as long as schedule time is smaller then current time - while (RoundDown(scheduledReport.StartTime, CheckScheduleInterval) < dateTimeNowRounded) - { - scheduledReport.StartTime = scheduledReport.RepeatInterval switch - { - Interval.Days => scheduledReport.StartTime.AddDays(scheduledReport.RepeatOffset), - Interval.Weeks => scheduledReport.StartTime.AddDays(scheduledReport.RepeatOffset * 7), - Interval.Months => scheduledReport.StartTime.AddMonths(scheduledReport.RepeatOffset), - Interval.Years => scheduledReport.StartTime.AddYears(scheduledReport.RepeatOffset), - Interval.Never => scheduledReport.StartTime.AddYears(42_42), - _ => throw new NotSupportedException("Time interval is not supported.") - }; - } - - if (RoundDown(scheduledReport.StartTime, CheckScheduleInterval) == dateTimeNowRounded) - { - reportGeneratorTasks.Add(GenerateReport(scheduledReport, dateTimeNowRounded)); - } - } - } - catch (Exception exception) - { - Log.WriteError("Report Scheduling", "Checking scheduled reports lead to exception.", exception); - } - } - } - - await Task.WhenAll(reportGeneratorTasks); - } - - private Task GenerateReport(ScheduledReport report, DateTime dateTimeNowRounded) - { - CancellationToken token = new CancellationToken(); - return Task.Run(async () => - { - try - { - Log.WriteInfo("Report Scheduling", $"Generating scheduled report \"{report.Name}\" with id \"{report.Id}\" for user \"{report.Owner.Name}\" with id \"{report.Owner.DbId}\" ..."); - - ReportFile reportFile = new ReportFile - { - Name = $"{report.Name}_{dateTimeNowRounded.ToShortDateString()}", - GenerationDateStart = DateTime.Now, - TemplateId = report.Template.Id, - OwnerId = report.Owner.DbId, - Type = report.Template.ReportParams.ReportType - }; - - DateTime reportGenerationStartDate = DateTime.Now; - - // get uiuser roles + tenant - AuthManager authManager = new AuthManager(jwtWriter, connectedLdaps, apiConnection); - //AuthenticationRequestHandler authHandler = new AuthenticationRequestHandler(connectedLdaps, jwtWriter, apiConnection); - string jwt = await authManager.AuthorizeUserAsync(report.Owner, validatePassword: false, lifetime: TimeSpan.FromDays(365)); - ApiConnection apiConnectionUserContext = new GraphQlApiConnection(apiServerUri, jwt); - GlobalConfig globalConfig = await GlobalConfig.ConstructAsync(jwt); - UserConfig userConfig = await UserConfig.ConstructAsync(globalConfig, apiConnection, report.Owner.DbId); - - await apiConnectionUserContext.SendQueryAsync(ReportQueries.countReportSchedule, new { report_schedule_id = report.Id }); - - if(!report.Template.ReportParams.DeviceFilter.isAnyDeviceFilterSet()) - { - // for scheduling no device selection means "all" - report.Template.ReportParams.DeviceFilter.Managements = await apiConnectionUserContext.SendQueryAsync>(DeviceQueries.getDevicesByManagements); - report.Template.ReportParams.DeviceFilter.applyFullDeviceSelection(true); - } - - ReportBase reportRules = ReportBase.ConstructReport(report.Template, userConfig); - Management[] managementsReport = Array.Empty(); - await reportRules.Generate(int.MaxValue, apiConnectionUserContext, - managementsReportIntermediate => - { - managementsReport = managementsReportIntermediate; - setRelevantManagements(ref managementsReport, report.Template.ReportParams.DeviceFilter); - return Task.CompletedTask; - }, token); - await reportRules.GetObjectsInReport(int.MaxValue, apiConnectionUserContext, _ => Task.CompletedTask); - - reportFile.Json = reportRules.ExportToJson(); - - foreach (FileFormat format in report.OutputFormat) - { - switch (format.Name) - { - case "csv": - reportFile.Csv = reportRules.ExportToCsv(); - break; - - case "html": - reportFile.Html = reportRules.ExportToHtml(); - break; - - case "pdf": - reportFile.Pdf = Convert.ToBase64String(reportRules.ToPdf(PaperKind.A4)); - break; - - case "json": - break; - - default: - throw new NotSupportedException("Output format is not supported."); - } - } - - reportFile.GenerationDateEnd = DateTime.Now; - - var queryVariables = new - { - report_name = reportFile.Name, - report_start_time = reportFile.GenerationDateStart, - report_end_time = reportFile.GenerationDateEnd, - report_owner_id = reportFile.OwnerId, - report_template_id = reportFile.TemplateId, - report_pdf = reportFile.Pdf, - report_csv = reportFile.Csv, - report_html = reportFile.Html, - report_json = reportFile.Json, - report_type = reportFile.Type, - description = reportRules.SetDescription() - }; - - await apiConnectionUserContext.SendQueryAsync(ReportQueries.addGeneratedReport, queryVariables); - - Log.WriteInfo("Report Scheduling", $"Scheduled report \"{report.Name}\" with id \"{report.Id}\" for user \"{report.Owner.Name}\" with id \"{report.Owner.DbId}\" successfully generated."); - } - catch (Exception exception) - { - Log.WriteError("Report Scheduling", $"Generating scheduled report \"{report.Name}\" with id \"{report.Id}\" lead to exception.", exception); - } - }, token); - } - - private void setRelevantManagements(ref Management[] managementsReport, DeviceFilter deviceFilter) - { - if (deviceFilter.isAnyDeviceFilterSet()) - { - List relevantManagements = deviceFilter.getSelectedManagements(); - foreach (Management mgm in managementsReport) - { - mgm.Ignore = !relevantManagements.Contains(mgm.Id); - } - } - } - - private static DateTime RoundDown(DateTime dateTime, TimeSpan roundInterval) - { - long delta = dateTime.Ticks % roundInterval.Ticks; - return new DateTime(dateTime.Ticks - delta); - } - } -} diff --git a/roles/middleware/files/FWO.Middleware.Server/RuleExpiryCheck.cs b/roles/middleware/files/FWO.Middleware.Server/RuleExpiryCheck.cs new file mode 100644 index 0000000000..b46779baf6 --- /dev/null +++ b/roles/middleware/files/FWO.Middleware.Server/RuleExpiryCheck.cs @@ -0,0 +1,208 @@ +using FWO.Api.Client; +using FWO.Api.Client.Queries; +using FWO.Basics; +using FWO.Config.Api; +using FWO.Data; +using FWO.Report; +using Newtonsoft.Json; +using System.Text.Json.Serialization; + +namespace FWO.Middleware.Server +{ + /// + /// Rule expiry check class + /// + public class RuleExpiryCheck : RuleNotificationBodyBase + { + private readonly ApiConnection apiConnection; + + /// + /// Constructor for rule expiry check class + /// + public RuleExpiryCheck(ApiConnection apiConnection, GlobalConfig globalConfig) : base(globalConfig) + { + this.apiConnection = apiConnection; + } + + /// + /// Rule expiry check + /// + public async Task CheckRuleExpiry() + { + int emailsSent = 0; + Dictionary ruleExpiryInitiatorKeys = ParseRuleExpiryInitiatorKeys(GlobalConfig.RuleExpiryInitiatorKeys); + List ownerGroups = await MiddlewareServerServices.GetInternalGroups(apiConnection); + NotificationService notificationService = await NotificationService.CreateAsync(NotificationClient.RuleTimer, GlobalConfig, apiConnection, ownerGroups); + List rulesByOwner = await apiConnection.SendQueryAsync>( + RuleQueries.getTimeBasedRulesByOwner); + + var ownerBuckets = rulesByOwner + .Where(item => item.Owner != null && item.Rule != null) + .GroupBy(item => item.Owner.Id); + + foreach (var ownerBucket in ownerBuckets) + { + FwoOwner owner = ownerBucket.First().Owner; + List timedEntries = ownerBucket + .SelectMany(item => item.Rule.GetRuleTimesWithEndDate(ruleExpiryInitiatorKeys)) + .DistinctBy(item => $"{item.Id}:{item.TimeObjectId}") + .OrderBy(item => item.EndTime) + .ToList(); + + if (timedEntries.Count == 0) + { + continue; + } + + foreach (var notification in notificationService.Notifications.Where(n => n.OwnerId == null || n.OwnerId == owner.Id)) + { + List dueEntries = timedEntries + .Where(entry => NotificationService.IsNotificationDue(owner, entry.EndTime, notification)) + .ToList(); + + if (dueEntries.Count == 0) + { + continue; + } + + string timeIntervalText = BuildTimeIntervalText(notification); + string body = notification.Layout == NotificationLayout.HtmlInBody + ? BuildRuleHtmlBody( + owner, + GlobalConfig.RuleExpiryEmailBody, + timeIntervalText, + dueEntries.OrderBy(item => item.EndTime), + [GlobalConfig.GetText("deadline"), GlobalConfig.GetText("ruleExpiryInitiator")], + expiryInfo => [expiryInfo.EndTime.ToString("yyyy-MM-dd"), expiryInfo.ExpiryInitiator]) + : BuildRuleTextBody( + owner, + GlobalConfig.RuleExpiryEmailBody, + timeIntervalText, + dueEntries.OrderBy(item => item.EndTime), + [GlobalConfig.GetText("deadline"), GlobalConfig.GetText("ruleExpiryInitiator")], + expiryInfo => [expiryInfo.EndTime.ToString("yyyy-MM-dd"), expiryInfo.ExpiryInitiator]); + emailsSent += await notificationService.SendNotification(notification, owner, body, null, timeIntervalText); + } + } + + await notificationService.UpdateNotificationsLastSent(); + return emailsSent; + } + + private static Dictionary ParseRuleExpiryInitiatorKeys(string serializedKeys) + { + if (string.IsNullOrWhiteSpace(serializedKeys)) + { + return []; + } + + try + { + Dictionary? parsedKeys = System.Text.Json.JsonSerializer.Deserialize>(serializedKeys); + if (parsedKeys == null) + { + return []; + } + + return parsedKeys + .Where(pair => !string.IsNullOrWhiteSpace(pair.Key)) + .ToDictionary( + pair => pair.Key.Trim().ToLowerInvariant(), + pair => pair.Value?.Trim() ?? "", + StringComparer.Ordinal); + } + catch (System.Text.Json.JsonException) + { + return []; + } + } + + private string BuildTimeIntervalText(FwoNotification notification) + { + int intervalValue; + SchedulerInterval intervalUnit; + + if ((notification.InitialOffsetAfterDeadline ?? 0) > 0) + { + intervalValue = notification.InitialOffsetAfterDeadline ?? 0; + intervalUnit = notification.RepeatIntervalAfterDeadline ?? SchedulerInterval.Days; + } + else + { + intervalValue = notification.OffsetBeforeDeadline ?? 0; + intervalUnit = notification.IntervalBeforeDeadline ?? SchedulerInterval.Days; + } + + if (intervalValue <= 0) + { + return "0"; + } + + return $"{intervalValue} {GetLocalizedIntervalUnit(intervalUnit)}"; + } + + private string GetLocalizedIntervalUnit(SchedulerInterval intervalUnit) + { + string intervalTextKey = intervalUnit switch + { + SchedulerInterval.Days => "Days", + SchedulerInterval.Weeks => "Weeks", + SchedulerInterval.Months => "Months", + _ => "Days" + }; + return GlobalConfig.GetNotificationText(intervalTextKey); + } + + private sealed class RuleOwnerWithRuleTimes + { + [JsonProperty("owner"), JsonPropertyName("owner")] + public FwoOwner Owner { get; set; } = new(); + + [JsonProperty("rule"), JsonPropertyName("rule")] + public RuleWithExpiry Rule { get; set; } = new(); + } + + private sealed class RuleWithExpiry : Rule + { + public List GetRuleTimesWithEndDate(IReadOnlyDictionary initiatorTexts) + { + return RuleTimes + .Select(ruleTime => new RuleExpiryInfo(this) + { + TimeObjectId = ruleTime.TimeObjId, + EndTime = ruleTime.TimeObj!.EndTime!.Value, + ExpiryInitiator = DetermineExpiryInitiator(ruleTime.TimeObj.Name, initiatorTexts) + }) + .ToList(); + } + + private static string DetermineExpiryInitiator(string? timeObjectName, IReadOnlyDictionary initiatorTexts) + { + if (string.IsNullOrWhiteSpace(timeObjectName) || initiatorTexts.Count == 0) + { + return ""; + } + + string normalizedName = timeObjectName.Trim().ToLowerInvariant(); + foreach (KeyValuePair initiatorText in initiatorTexts) + { + if (normalizedName.EndsWith(initiatorText.Key, StringComparison.Ordinal)) + { + return initiatorText.Value; + } + } + return ""; + } + } + + private sealed class RuleExpiryInfo : Rule + { + public RuleExpiryInfo(Rule rule) : base(rule) + { } + + public long TimeObjectId { get; set; } + public DateTime EndTime { get; set; } + public string ExpiryInitiator { get; set; } = ""; + } + } +} diff --git a/roles/middleware/files/FWO.Middleware.Server/RuleNotificationBodyBase.cs b/roles/middleware/files/FWO.Middleware.Server/RuleNotificationBodyBase.cs new file mode 100644 index 0000000000..3e68aad886 --- /dev/null +++ b/roles/middleware/files/FWO.Middleware.Server/RuleNotificationBodyBase.cs @@ -0,0 +1,423 @@ +using FWO.Basics; +using FWO.Config.Api; +using FWO.Data; +using FWO.Report; +using FWO.Ui.Display; +using System.Net; +using System.Text; +using System.Text.RegularExpressions; + +namespace FWO.Middleware.Server +{ + /// + /// Shared HTML body helpers for rule-based notifications. + /// + public abstract class RuleNotificationBodyBase(GlobalConfig globalConfig) + { + private const string kTextColumnSeparator = " | "; + + /// + /// Holds the shared display values for a single rule row. + /// + /// Cell values rendered for the HTML table. + /// Cell values rendered for the plain-text table. + private sealed record RuleNotificationRow(List HtmlCells, List TextCells); + + /// + /// Builds a plain-text rule notification body with the standard rule columns and optional extra columns. + /// + /// Owner used for placeholder replacement. + /// Configured mail body template. + /// Resolved notification interval text. + /// Rules to render. + /// Optional extra header texts. + /// Optional extra cell values per row. + /// Plain-text mail body. + protected string BuildRuleTextBody( + FwoOwner owner, + string bodyTemplate, + string timeIntervalText, + IEnumerable rules, + IEnumerable? extraHeaders = null, + Func>? getExtraCellValues = null) + where TRule : Rule + { + List headerTexts = BuildHeaderTexts(extraHeaders); + string introText = BuildIntroText(owner, bodyTemplate, timeIntervalText); + List rows = BuildNotificationRows(rules, getExtraCellValues); + string textRuleTable = BuildTextRuleTable(headerTexts, rows); + + return BuildTextBody(introText, textRuleTable); + } + + /// + /// Builds an HTML rule notification body with the standard rule columns and optional extra columns. + /// + /// Owner used for placeholder replacement. + /// Configured mail body template. + /// Resolved notification interval text. + /// Rules to render. + /// Optional extra header texts. + /// Optional extra cell values per row. + /// Optional localized title for a framed HTML report section. + /// HTML mail body. + protected string BuildRuleHtmlBody( + FwoOwner owner, + string bodyTemplate, + string timeIntervalText, + IEnumerable rules, + IEnumerable? extraHeaders = null, + Func>? getExtraCellValues = null, + string? frameTitle = null) + where TRule : Rule + { + List headerTexts = BuildHeaderTexts(extraHeaders); + string introText = BuildIntroText(owner, bodyTemplate, timeIntervalText); + List rows = BuildNotificationRows(rules, getExtraCellValues); + string htmlRuleTable = BuildHtmlRuleTable(headerTexts, rows); + + if (!string.IsNullOrWhiteSpace(frameTitle)) + { + htmlRuleTable = BuildHtmlReportSection(frameTitle, htmlRuleTable, owner); + } + + return BuildHtmlDocument(BuildHtmlBody(introText, htmlRuleTable)); + } + + /// + /// Extracts a change identifier from rule custom fields. + /// + /// Serialized rule custom fields. + /// The extracted change identifier or an empty string. + private static string ExtractChangeId(string customFieldsString) + { + if (string.IsNullOrWhiteSpace(customFieldsString)) + { + return ""; + } + + string? field2 = TryExtractCustomFieldValue(customFieldsString, GlobalConst.kField2); + if (!string.IsNullOrWhiteSpace(field2)) + { + return field2; + } + + string? fallback = TryExtractCustomFieldValue(customFieldsString, GlobalConst.kDatumRegelpr); + if (!string.IsNullOrWhiteSpace(fallback)) + { + return fallback; + } + + return ""; + } + + private static string? TryExtractCustomFieldValue(string customFieldsString, string key) + { + Match match = Regex.Match( + customFieldsString, + $@"['""]{Regex.Escape(key)}['""]\s*:\s*['""](?(?:\\.|[^'""])*)['""]", + RegexOptions.CultureInvariant); + + return match.Success ? Regex.Unescape(match.Groups["value"].Value) : null; + } + + /// + /// Builds an HTML table cell with escaped text. + /// + /// Cell value. + /// HTML table cell. + private static string HtmlCell(string? value) + { + return $"{WebUtility.HtmlEncode(value ?? "")}"; + } + + /// + /// Builds an HTML table cell without escaping the value. + /// + /// Cell value. + /// HTML table cell. + private static string HtmlRawCell(string? value) + { + return $"{value ?? ""}"; + } + + /// + /// Appends a paragraph with HTML-encoded text if content is present. + /// + /// Target builder. + /// Text content to append. + private static void AppendEncodedParagraph(StringBuilder builder, string? text) + { + if (string.IsNullOrWhiteSpace(text)) + { + return; + } + + builder.Append("

                      ") + .Append(WebUtility.HtmlEncode(text).Replace(Environment.NewLine, "
                      ").Replace("\n", "
                      ")) + .Append("

                      "); + } + + private static RuleNotificationRow CreateNotificationRow( + TRule rule, + RuleDisplayHtml ruleDisplayHtml, + Func>? getExtraCellValues) + where TRule : Rule + { + string? sourceHtml = ruleDisplayHtml.DisplaySource(rule, OutputLocation.export, ReportType.ResolvedRules); + string? destinationHtml = ruleDisplayHtml.DisplayDestination(rule, OutputLocation.export, ReportType.ResolvedRules); + string? servicesHtml = ruleDisplayHtml.DisplayServices(rule, OutputLocation.export, ReportType.ResolvedRules); + string changeId = ExtractChangeId(rule.CustomFields); + string lastHit = rule.Metadata.LastHit?.ToString("yyyy-MM-dd") ?? ""; + + List htmlCells = + [ + rule.Uid, + rule.Name, + sourceHtml, + destinationHtml, + servicesHtml, + changeId, + lastHit + ]; + + List textCells = + [ + NormalizeTextCell(rule.Uid), + NormalizeTextCell(rule.Name), + NormalizeTextCell(sourceHtml), + NormalizeTextCell(destinationHtml), + NormalizeTextCell(servicesHtml), + NormalizeTextCell(changeId), + NormalizeTextCell(lastHit) + ]; + + if (getExtraCellValues != null) + { + foreach (string? extraCellValue in getExtraCellValues(rule)) + { + htmlCells.Add(extraCellValue); + textCells.Add(NormalizeTextCell(extraCellValue)); + } + } + + return new RuleNotificationRow(htmlCells, textCells); + } + + private List BuildHeaderTexts(IEnumerable? extraHeaders) + { + List headerTexts = + [ + GlobalConfig.GetNotificationText("uid"), + GlobalConfig.GetNotificationText("name"), + GlobalConfig.GetNotificationText("source"), + GlobalConfig.GetNotificationText("destination"), + GlobalConfig.GetNotificationText("service"), + GlobalConfig.GetNotificationText("change_id"), + GlobalConfig.GetNotificationText("last_hit") + ]; + + if (extraHeaders != null) + { + headerTexts.AddRange(extraHeaders); + } + + return headerTexts; + } + + private static string BuildIntroText(FwoOwner owner, string bodyTemplate, string timeIntervalText) + { + return bodyTemplate + .Replace(Placeholder.APPNAME, owner.Name) + .Replace(Placeholder.APPID, owner.ExtAppId ?? "") + .Replace(Placeholder.TIME_INTERVAL, timeIntervalText); + } + + private List BuildNotificationRows( + IEnumerable rules, + Func>? getExtraCellValues) + where TRule : Rule + { + RuleDisplayHtml ruleDisplayHtml = CreateRuleDisplayHtml(); + return rules + .Select(rule => CreateNotificationRow(rule, ruleDisplayHtml, getExtraCellValues)) + .ToList(); + } + + private static string BuildHtmlRuleTable(IEnumerable headerTexts, IEnumerable rows) + { + StringBuilder builder = new(); + builder.Append("") + .Append(""); + + foreach (string headerText in headerTexts) + { + builder.Append(""); + } + + builder.Append(""); + foreach (RuleNotificationRow row in rows) + { + builder.Append(""); + for (int index = 0; index < row.HtmlCells.Count; ++index) + { + builder.Append(index is 2 or 3 or 4 ? HtmlRawCell(row.HtmlCells[index]) : HtmlCell(row.HtmlCells[index])); + } + builder.Append(""); + } + + builder.Append("
                      ") + .Append(WebUtility.HtmlEncode(headerText)) + .Append("
                      "); + return builder.ToString(); + } + + private static string BuildTextRuleTable(IEnumerable headerTexts, IEnumerable rows) + { + StringBuilder builder = new(); + builder.AppendLine(string.Join(kTextColumnSeparator, headerTexts.Select(NormalizeTextCell))); + foreach (RuleNotificationRow row in rows) + { + builder.AppendLine(string.Join(kTextColumnSeparator, row.TextCells)); + } + return builder.ToString().TrimEnd(); + } + + private static string BuildHtmlBody(string introText, string htmlRuleTable) + { + StringBuilder builder = new(); + string[] bodyParts = introText.Split(Placeholder.RULE_TABLE, StringSplitOptions.None); + for (int index = 0; index < bodyParts.Length; ++index) + { + AppendEncodedParagraph(builder, bodyParts[index]); + if (index < bodyParts.Length - 1) + { + builder.Append(htmlRuleTable); + } + } + return builder.ToString(); + } + + private string BuildHtmlDocument(string body) + { + StringBuilder html = new(); + html.AppendLine("") + .AppendLine("") + .AppendLine("") + .AppendLine(" ") + .AppendLine(" ") + .AppendLine("") + .AppendLine("") + .Append(body) + .AppendLine() + .AppendLine("") + .Append(""); + + return html.ToString(); + } + + private string BuildHtmlReportSection(string title, string body, FwoOwner? owner) + { + StringBuilder html = new(); + + html.Append("

                      ") + .Append(WebUtility.HtmlEncode(title)) + .AppendLine("

                      ") + .Append("

                      ") + .Append(WebUtility.HtmlEncode(GlobalConfig.GetNotificationText("generated_on"))) + .Append(": ") + .Append(DateTime.UtcNow.ToString("yyyy-MM-ddTHH:mm:ssK")) + .AppendLine(" (UTC)

                      "); + + if (owner != null) + { + html.Append("

                      ") + .Append(WebUtility.HtmlEncode(GlobalConfig.GetNotificationText("owners"))) + .Append(": ") + .Append(WebUtility.HtmlEncode(owner.Name)) + .AppendLine("

                      "); + } + + html.AppendLine("
                      ") + .Append(body); + + return html.ToString(); + } + + private static string BuildTextBody(string introText, string textRuleTable) + { + StringBuilder builder = new(); + string[] bodyParts = introText.Split(Placeholder.RULE_TABLE, StringSplitOptions.None); + for (int index = 0; index < bodyParts.Length; ++index) + { + AppendTextSection(builder, bodyParts[index]); + if (index < bodyParts.Length - 1) + { + AppendTextSection(builder, textRuleTable); + } + } + return builder.ToString().Trim(); + } + + private static void AppendTextSection(StringBuilder builder, string? text) + { + if (string.IsNullOrWhiteSpace(text)) + { + return; + } + + if (builder.Length > 0) + { + builder.AppendLine().AppendLine(); + } + + builder.Append(text.Trim()); + } + + private static string NormalizeTextCell(string? value) + { + if (string.IsNullOrWhiteSpace(value)) + { + return ""; + } + + string normalized = Regex.Replace(value, @"", ", ", RegexOptions.IgnoreCase | RegexOptions.CultureInvariant); + normalized = Regex.Replace(normalized, "<.*?>", string.Empty, RegexOptions.CultureInvariant); + normalized = WebUtility.HtmlDecode(normalized); + normalized = Regex.Replace(normalized, @"\s+", " ", RegexOptions.CultureInvariant); + return normalized.Trim(); + } + + /// + /// Returns the global configuration used by the notification body helpers. + /// + protected GlobalConfig GlobalConfig { get; } = globalConfig; + + private RuleDisplayHtml CreateRuleDisplayHtml() + { + UserConfig displayUserConfig = new(GlobalConfig, false); + return new RuleDisplayHtml(displayUserConfig); + } + + } +} diff --git a/roles/middleware/files/FWO.Middleware.Server/SchedulerBase.cs b/roles/middleware/files/FWO.Middleware.Server/SchedulerBase.cs new file mode 100644 index 0000000000..331923757d --- /dev/null +++ b/roles/middleware/files/FWO.Middleware.Server/SchedulerBase.cs @@ -0,0 +1,160 @@ +using FWO.Api.Client; +using FWO.Basics; +using FWO.Data; +using FWO.Config.Api; +using FWO.Config.Api.Data; +using FWO.Logging; +using FWO.Services; +using System.Timers; + +namespace FWO.Middleware.Server +{ + /// + /// Class handling the scheduler base processing + /// + public abstract class SchedulerBase + { + /// + /// API connection + /// + protected readonly ApiConnection apiConnection; + + /// + /// Global config + /// + protected GlobalConfig globalConfig; + + /// + /// Global config change subscription + /// + protected GraphQlApiSubscription>? ConfigDataSubscription; + + /// + /// Schedule Timer + /// + protected System.Timers.Timer ScheduleTimer = new(); + private System.Timers.Timer RecurringTimer = new(); + private readonly string SchedulerText; + private readonly SchedulerInterval SchedulerInterval; + private int SleepTime; + + + /// + /// Constructor starting the Schedule timer + /// + protected SchedulerBase(ApiConnection apiConnection, GlobalConfig globalConfig, string configDataSubscription, SchedulerInterval schedulerInterval, string schedulerName) + { + this.apiConnection = apiConnection; + this.globalConfig = globalConfig; + ConfigDataSubscription = apiConnection.GetSubscription>(ApiExceptionHandler, OnGlobalConfigChange, configDataSubscription); + SchedulerText = "Scheduler-" + schedulerName; + SchedulerInterval = schedulerInterval; + } + + /// + /// set scheduling timer from config values, to be overwritten for specific scheduler + /// + protected abstract void OnGlobalConfigChange(List config); + + /// + /// subscription exception handling + /// + protected void ApiExceptionHandler(Exception exception) + { + Log.WriteError(SchedulerText, "Api subscription lead to exception. Retry subscription.", exception); + // Subscription will be restored if no exception is thrown here + } + + /// + /// define the processing to be done, to be overwritten for specific schedule + /// + protected abstract void Process(object? _, ElapsedEventArgs __); + + /// + /// start the scheduling timer, to be called by specific scheduler + /// + protected void StartScheduleTimer(int sleepTime, DateTime startTime) + { + SleepTime = sleepTime; + if (SleepTime > 0) + { + try + { + // Dispose old timer if existant + ScheduleTimer.Stop(); + ScheduleTimer.Elapsed -= Process; + ScheduleTimer.Dispose(); + + ScheduleTimer = new(); + ScheduleTimer.Elapsed += Process; + ScheduleTimer.Elapsed += StartRecurringTimer; + ScheduleTimer.Interval = (CalculateStartTime(startTime) - DateTime.Now).TotalMilliseconds; + ScheduleTimer.AutoReset = false; + ScheduleTimer.Start(); + Log.WriteInfo(SchedulerText, "ScheduleTimer started."); + } + catch (Exception exception) + { + Log.WriteError(SchedulerText, "Could not start ScheduleTimer.", exception); + } + } + } + + private void StartRecurringTimer(object? _, ElapsedEventArgs __) + { + try + { + // Dispose old timer if existant + RecurringTimer.Stop(); + RecurringTimer.Elapsed -= Process; + RecurringTimer.Dispose(); + + RecurringTimer = new(); + RecurringTimer.Elapsed += Process; + RecurringTimer.Interval = SleepTimeToMilliseconds(); + RecurringTimer.AutoReset = true; + RecurringTimer.Start(); + Log.WriteInfo(SchedulerText, "RecurringTimer started."); + } + catch (Exception exception) + { + Log.WriteError(SchedulerText, "Could not start RecurringTimer.", exception); + } + } + + private DateTime CalculateStartTime(DateTime startTime) + { + try + { + while (startTime < DateTime.Now) + { + startTime = SchedulerInterval switch + { + SchedulerInterval.Days => startTime.AddDays(SleepTime), + SchedulerInterval.Hours => startTime.AddHours(SleepTime), + SchedulerInterval.Minutes => startTime.AddMinutes(SleepTime), + SchedulerInterval.Seconds => startTime.AddSeconds(SleepTime), + _ => throw new NotSupportedException($"Error: wrong time interval format:" + SchedulerInterval.ToString()) + }; + } + } + catch (Exception exception) + { + Log.WriteError(SchedulerText, "Could not calculate start time.", exception); + } + return startTime; + } + + private int SleepTimeToMilliseconds() + { + return SchedulerInterval switch + { + SchedulerInterval.Days => SleepTime * GlobalConst.kDaysToMilliseconds, + SchedulerInterval.Hours => SleepTime * GlobalConst.kHoursToMilliseconds, + SchedulerInterval.Minutes => SleepTime * GlobalConst.kMinutesToMilliseconds, + SchedulerInterval.Seconds => SleepTime * GlobalConst.kSecondsToMilliseconds, + _ => throw new NotSupportedException($"Error: wrong time interval format:" + SchedulerInterval.ToString()) + }; + } + } +} diff --git a/roles/middleware/files/FWO.Middleware.Server/Services/AutoDiscoverSchedulerService.cs b/roles/middleware/files/FWO.Middleware.Server/Services/AutoDiscoverSchedulerService.cs new file mode 100644 index 0000000000..cd3a8d89ee --- /dev/null +++ b/roles/middleware/files/FWO.Middleware.Server/Services/AutoDiscoverSchedulerService.cs @@ -0,0 +1,54 @@ +using FWO.Api.Client; +using FWO.Api.Client.Queries; +using FWO.Config.Api; +using FWO.Middleware.Server.Jobs; +using Quartz; + +namespace FWO.Middleware.Server.Services +{ + /// + /// Config listener and rescheduler for autodiscovery (no BackgroundService) + /// + public class AutoDiscoverSchedulerService : QuartzSchedulerServiceBase + { + private const string JobKeyName = "AutoDiscoverJob"; + private const string TriggerKeyName = "AutoDiscoverTrigger"; + private const string SchedulerName = "AutoDiscoverScheduler"; + + /// + /// Initializes the autodiscovery scheduler service. + /// + /// Quartz scheduler factory. + /// GraphQL API connection. + /// Global configuration. + /// Application lifetime for startup hook. + public AutoDiscoverSchedulerService( + ISchedulerFactory schedulerFactory, + ApiConnection apiConnection, + GlobalConfig globalConfig, + IHostApplicationLifetime appLifetime) + : base( + schedulerFactory, + apiConnection, + globalConfig, + appLifetime, + new QuartzSchedulerOptions( + SchedulerName, + JobKeyName, + TriggerKeyName, + ConfigQueries.subscribeAutodiscoveryConfigChanges)) + { } + + /// + protected override int SleepTime => globalConfig.AutoDiscoverSleepTime; + + /// + protected override DateTime StartAt => globalConfig.AutoDiscoverStartAt; + + /// + protected override TimeSpan Interval => TimeSpan.FromHours(globalConfig.AutoDiscoverSleepTime); + + /// + protected override string IntervalLogSuffix => "h"; + } +} diff --git a/roles/middleware/files/FWO.Middleware.Server/Services/ComplianceSchedulerService.cs b/roles/middleware/files/FWO.Middleware.Server/Services/ComplianceSchedulerService.cs new file mode 100644 index 0000000000..eb03f0bcc3 --- /dev/null +++ b/roles/middleware/files/FWO.Middleware.Server/Services/ComplianceSchedulerService.cs @@ -0,0 +1,54 @@ +using FWO.Api.Client; +using FWO.Api.Client.Queries; +using FWO.Config.Api; +using FWO.Middleware.Server.Jobs; +using Quartz; + +namespace FWO.Middleware.Server.Services +{ + /// + /// Config listener and rescheduler for compliance check (no BackgroundService) + /// + public class ComplianceSchedulerService : QuartzSchedulerServiceBase + { + private const string JobKeyName = "ComplianceJob"; + private const string TriggerKeyName = "ComplianceTrigger"; + private const string SchedulerName = "ComplianceScheduler"; + + /// + /// Initializes the compliance scheduler service. + /// + /// Quartz scheduler factory. + /// GraphQL API connection. + /// Global configuration. + /// Application lifetime for startup hook. + public ComplianceSchedulerService( + ISchedulerFactory schedulerFactory, + ApiConnection apiConnection, + GlobalConfig globalConfig, + IHostApplicationLifetime appLifetime) + : base( + schedulerFactory, + apiConnection, + globalConfig, + appLifetime, + new QuartzSchedulerOptions( + SchedulerName, + JobKeyName, + TriggerKeyName, + ConfigQueries.subscribeComplianceCheckConfigChanges)) + { } + + /// + protected override int SleepTime => globalConfig.ComplianceCheckSleepTime; + + /// + protected override DateTime StartAt => globalConfig.ComplianceCheckStartAt; + + /// + protected override TimeSpan Interval => TimeSpan.FromMinutes(globalConfig.ComplianceCheckSleepTime); + + /// + protected override string IntervalLogSuffix => " m"; + } +} diff --git a/roles/middleware/files/FWO.Middleware.Server/Services/DailyCheckSchedulerService.cs b/roles/middleware/files/FWO.Middleware.Server/Services/DailyCheckSchedulerService.cs new file mode 100644 index 0000000000..4f7ba184a7 --- /dev/null +++ b/roles/middleware/files/FWO.Middleware.Server/Services/DailyCheckSchedulerService.cs @@ -0,0 +1,145 @@ +using FWO.Api.Client; +using FWO.Api.Client.Queries; +using FWO.Config.Api; +using FWO.Config.Api.Data; +using FWO.Logging; +using FWO.Middleware.Server.Jobs; +using Quartz; + +namespace FWO.Middleware.Server.Services +{ + /// + /// Config listener and rescheduler for daily checks (no BackgroundService) + /// + public class DailyCheckSchedulerService : IAsyncDisposable + { + private readonly ISchedulerFactory schedulerFactory; + private readonly ApiConnection apiConnection; + private readonly GlobalConfig globalConfig; + private GraphQlApiSubscription>? configSubscription; + private IScheduler? scheduler; + private bool disposed = false; + + private const string JobKeyName = "DailyCheckJob"; + private const string TriggerKeyName = "DailyCheckTrigger"; + private const string SchedulerName = "DailyCheckScheduler"; + + /// + /// Initializes the daily check scheduler service. + /// + /// Quartz scheduler factory. + /// GraphQL API connection. + /// Global configuration. + /// Application lifetime for startup hook. + public DailyCheckSchedulerService(ISchedulerFactory schedulerFactory, ApiConnection apiConnection, GlobalConfig globalConfig, IHostApplicationLifetime appLifetime) + { + this.schedulerFactory = schedulerFactory; + this.apiConnection = apiConnection; + this.globalConfig = globalConfig; + + // Attach after application started + appLifetime.ApplicationStarted.Register(OnStarted); + } + + private async void OnStarted() + { + try + { + scheduler = await schedulerFactory.GetScheduler(); + configSubscription = apiConnection.GetSubscription>(ApiExceptionHandler, OnGlobalConfigChange, ConfigQueries.subscribeDailyCheckConfigChanges); + Log.WriteInfo(SchedulerName, "Listener started"); + } + catch (Exception ex) + { + Log.WriteError(SchedulerName, "Startup failed", ex); + } + } + + private async void OnGlobalConfigChange(List config) + { + try + { + globalConfig.SubscriptionUpdateHandler([.. config]); + await ScheduleJob(); + Log.WriteInfo(SchedulerName, "Job rescheduled due to config change"); + } + catch (Exception ex) + { + Log.WriteError(SchedulerName, "Failed to reschedule job", ex); + } + } + + private async Task ScheduleJob() + { + if (scheduler == null) + { + Log.WriteWarning(SchedulerName, "Scheduler not initialized"); + return; + } + + var jobKey = new JobKey(JobKeyName); + var triggerKey = new TriggerKey(TriggerKeyName); + + if (await scheduler.CheckExists(jobKey)) + { + await scheduler.DeleteJob(jobKey); + Log.WriteInfo(SchedulerName, "Removed existing job"); + } + + IJobDetail job = JobBuilder.Create() + .WithIdentity(jobKey) + .Build(); + + DateTimeOffset startTime = CalculateStartTime(globalConfig.DailyCheckStartAt, TimeSpan.FromDays(1)); + + ITrigger trigger = TriggerBuilder.Create() + .WithIdentity(triggerKey) + .StartAt(startTime) + .WithSimpleSchedule(x => x + .WithInterval(TimeSpan.FromDays(1)) + .RepeatForever()) + .Build(); + + await scheduler.ScheduleJob(job, trigger); + + Log.WriteInfo(SchedulerName, $"Job scheduled. Start: {startTime:yyyy-MM-dd HH:mm:ss}, Interval: 1d"); + } + + private static DateTimeOffset CalculateStartTime(DateTime configuredStartTime, TimeSpan interval) + { + DateTime startTime = configuredStartTime; + DateTime now = DateTime.Now; + while (startTime < now) + { + startTime = startTime.Add(interval); + } + return new DateTimeOffset(startTime); + } + + private static void ApiExceptionHandler(Exception exception) + { + Log.WriteError(SchedulerName, "Config subscription lead to exception. Retry subscription.", exception); + } + + /// + /// Releases resources used by the service. + /// Disposes the scheduler and configuration subscription. + /// + public async ValueTask DisposeAsync() + { + if (!disposed) + { + try + { + configSubscription?.Dispose(); + // Scheduler lifecycle is managed by QuartzHostedService + disposed = true; + } + catch (Exception ex) + { + Log.WriteError(SchedulerName, "Error during disposal", ex); + } + } + } + } +} diff --git a/roles/middleware/files/FWO.Middleware.Server/Services/ExternalRequestSchedulerService.cs b/roles/middleware/files/FWO.Middleware.Server/Services/ExternalRequestSchedulerService.cs new file mode 100644 index 0000000000..011b6275de --- /dev/null +++ b/roles/middleware/files/FWO.Middleware.Server/Services/ExternalRequestSchedulerService.cs @@ -0,0 +1,56 @@ +using FWO.Api.Client; +using FWO.Api.Client.Queries; +using FWO.Config.Api; +using Quartz; + +namespace FWO.Middleware.Server.Services +{ + /// + /// Config listener and rescheduler for External Requests (no BackgroundService) + /// + public class ExternalRequestSchedulerService : QuartzSchedulerServiceBase + { + private const string JobKeyName = "ExternalRequestJob"; + private const string TriggerKeyName = "ExternalRequestTrigger"; + private const string SchedulerName = "ExternalRequestScheduler"; + + /// + /// Constructor + /// + /// + /// Initializes the external request scheduler service. + /// + /// Quartz scheduler factory. + /// GraphQL API connection. + /// Global configuration. + /// + public ExternalRequestSchedulerService( + ISchedulerFactory schedulerFactory, + ApiConnection apiConnection, + GlobalConfig globalConfig, + IHostApplicationLifetime appLifetime) + : base( + schedulerFactory, + apiConnection, + globalConfig, + appLifetime, + new QuartzSchedulerOptions( + SchedulerName, + JobKeyName, + TriggerKeyName, + ConfigQueries.subscribeExternalRequestConfigChanges)) + { } + + /// + protected override int SleepTime => globalConfig.ExternalRequestSleepTime; + + /// + protected override DateTime StartAt => globalConfig.ExternalRequestStartAt; + + /// + protected override TimeSpan Interval => TimeSpan.FromSeconds(globalConfig.ExternalRequestSleepTime); + + /// + protected override string IntervalLogSuffix => "s"; + } +} diff --git a/roles/middleware/files/FWO.Middleware.Server/Services/ImportAppDataSchedulerService.cs b/roles/middleware/files/FWO.Middleware.Server/Services/ImportAppDataSchedulerService.cs new file mode 100644 index 0000000000..844d80a8c9 --- /dev/null +++ b/roles/middleware/files/FWO.Middleware.Server/Services/ImportAppDataSchedulerService.cs @@ -0,0 +1,54 @@ +using FWO.Api.Client; +using FWO.Api.Client.Queries; +using FWO.Config.Api; +using FWO.Middleware.Server.Jobs; +using Quartz; + +namespace FWO.Middleware.Server.Services +{ + /// + /// Config listener and rescheduler for app data imports (no BackgroundService) + /// + public class ImportAppDataSchedulerService : QuartzSchedulerServiceBase + { + private const string JobKeyName = "ImportAppDataJob"; + private const string TriggerKeyName = "ImportAppDataTrigger"; + private const string SchedulerName = "ImportAppDataScheduler"; + + /// + /// Initializes the import app data scheduler service. + /// + /// Quartz scheduler factory. + /// GraphQL API connection. + /// Global configuration. + /// Application lifetime for startup hook. + public ImportAppDataSchedulerService( + ISchedulerFactory schedulerFactory, + ApiConnection apiConnection, + GlobalConfig globalConfig, + IHostApplicationLifetime appLifetime) + : base( + schedulerFactory, + apiConnection, + globalConfig, + appLifetime, + new QuartzSchedulerOptions( + SchedulerName, + JobKeyName, + TriggerKeyName, + ConfigQueries.subscribeImportAppDataConfigChanges)) + { } + + /// + protected override int SleepTime => globalConfig.ImportAppDataSleepTime; + + /// + protected override DateTime StartAt => globalConfig.ImportAppDataStartAt; + + /// + protected override TimeSpan Interval => TimeSpan.FromHours(globalConfig.ImportAppDataSleepTime); + + /// + protected override string IntervalLogSuffix => "h"; + } +} diff --git a/roles/middleware/files/FWO.Middleware.Server/Services/ImportChangeNotifySchedulerService.cs b/roles/middleware/files/FWO.Middleware.Server/Services/ImportChangeNotifySchedulerService.cs new file mode 100644 index 0000000000..71d6a2d276 --- /dev/null +++ b/roles/middleware/files/FWO.Middleware.Server/Services/ImportChangeNotifySchedulerService.cs @@ -0,0 +1,61 @@ +using FWO.Api.Client; +using FWO.Api.Client.Queries; +using FWO.Config.Api; +using FWO.Middleware.Server.Jobs; +using Quartz; + +namespace FWO.Middleware.Server.Services +{ + /// + /// Config listener and rescheduler for import change notifications (no BackgroundService) + /// + public class ImportChangeNotifySchedulerService : QuartzSchedulerServiceBase + { + private const string JobKeyName = "ImportChangeNotifyJob"; + private const string TriggerKeyName = "ImportChangeNotifyTrigger"; + private const string SchedulerName = "ImportChangeNotifyScheduler"; + + /// + /// Initializes the import change notify scheduler service. + /// + /// Quartz scheduler factory. + /// GraphQL API connection. + /// Global configuration. + /// Application lifetime for startup hook. + public ImportChangeNotifySchedulerService( + ISchedulerFactory schedulerFactory, + ApiConnection apiConnection, + GlobalConfig globalConfig, + IHostApplicationLifetime appLifetime) + : base( + schedulerFactory, + apiConnection, + globalConfig, + appLifetime, + new QuartzSchedulerOptions( + SchedulerName, + JobKeyName, + TriggerKeyName, + ConfigQueries.subscribeImportNotifyConfigChanges)) + { } + + /// + protected override int SleepTime => globalConfig.ImpChangeNotifySleepTime; + + /// + protected override DateTime StartAt => globalConfig.ImpChangeNotifyStartAt; + + /// + protected override TimeSpan Interval => TimeSpan.FromSeconds(globalConfig.ImpChangeNotifySleepTime); + + /// + protected override bool IsActive => globalConfig.ImpChangeNotifyActive; + + /// + protected override string IntervalLogSuffix => "s"; + + /// + protected override string DisabledLogMessage => + "Job disabled (inactive or sleep time <= 0) - job kept without trigger for manual runs"; + } +} diff --git a/roles/middleware/files/FWO.Middleware.Server/Services/ImportIpDataSchedulerService.cs b/roles/middleware/files/FWO.Middleware.Server/Services/ImportIpDataSchedulerService.cs new file mode 100644 index 0000000000..5611e7fdb7 --- /dev/null +++ b/roles/middleware/files/FWO.Middleware.Server/Services/ImportIpDataSchedulerService.cs @@ -0,0 +1,54 @@ +using FWO.Api.Client; +using FWO.Api.Client.Queries; +using FWO.Config.Api; +using FWO.Middleware.Server.Jobs; +using Quartz; + +namespace FWO.Middleware.Server.Services +{ + /// + /// Config listener and rescheduler for area IP data imports (no BackgroundService) + /// + public class ImportIpDataSchedulerService : QuartzSchedulerServiceBase + { + private const string JobKeyName = "ImportIpDataJob"; + private const string TriggerKeyName = "ImportIpDataTrigger"; + private const string SchedulerName = "ImportIpDataScheduler"; + + /// + /// Initializes the import IP data scheduler service. + /// + /// Quartz scheduler factory. + /// GraphQL API connection. + /// Global configuration. + /// Application lifetime for startup hook. + public ImportIpDataSchedulerService( + ISchedulerFactory schedulerFactory, + ApiConnection apiConnection, + GlobalConfig globalConfig, + IHostApplicationLifetime appLifetime) + : base( + schedulerFactory, + apiConnection, + globalConfig, + appLifetime, + new QuartzSchedulerOptions( + SchedulerName, + JobKeyName, + TriggerKeyName, + ConfigQueries.subscribeImportIpDataConfigChanges)) + { } + + /// + protected override int SleepTime => globalConfig.ImportSubnetDataSleepTime; + + /// + protected override DateTime StartAt => globalConfig.ImportSubnetDataStartAt; + + /// + protected override TimeSpan Interval => TimeSpan.FromHours(globalConfig.ImportSubnetDataSleepTime); + + /// + protected override string IntervalLogSuffix => "h"; + } +} diff --git a/roles/middleware/files/FWO.Middleware.Server/Services/JobExecutionTracker.cs b/roles/middleware/files/FWO.Middleware.Server/Services/JobExecutionTracker.cs new file mode 100644 index 0000000000..8a2360619d --- /dev/null +++ b/roles/middleware/files/FWO.Middleware.Server/Services/JobExecutionTracker.cs @@ -0,0 +1,101 @@ +using FWO.Logging; +using Quartz; +using System.Collections.Concurrent; + +namespace FWO.Middleware.Server.Services +{ + /// + /// Tracks last execution result for each job. + /// + public class JobExecutionTracker : IJobListener + { + private readonly ConcurrentDictionary executionResults = new(); + + /// + /// Gets the name of the job listener. + /// + public string Name => "JobExecutionTracker"; + + /// + /// Called by the scheduler when a job is about to be executed. + /// + /// The job execution context. + /// The cancellation token. + /// A completed task. + public Task JobToBeExecuted(IJobExecutionContext context, CancellationToken cancellationToken = default) + { + return Task.CompletedTask; + } + + /// + /// Called by the scheduler when a job execution was vetoed by a trigger listener. + /// + /// The job execution context. + /// The cancellation token. + /// A completed task. + public Task JobExecutionVetoed(IJobExecutionContext context, CancellationToken cancellationToken = default) + { + return Task.CompletedTask; + } + + /// + /// Called by the scheduler after a job has been executed. + /// + /// The job execution context. + /// The exception thrown by the job, if any. + /// The cancellation token. + /// A completed task. + public Task JobWasExecuted(IJobExecutionContext context, JobExecutionException? jobException, CancellationToken cancellationToken = default) + { + string jobKey = context.JobDetail.Key.Name; + bool success = jobException == null; + string? errorMessage = jobException?.Message; + + executionResults[jobKey] = new JobExecutionResult + { + Success = success, + ErrorMessage = errorMessage ?? "", + ExecutedAt = DateTimeOffset.Now + }; + + if (!success) + { + Log.WriteWarning("Job Execution", $"Job {jobKey} failed: {errorMessage}"); + } + + return Task.CompletedTask; + } + + /// + /// Gets the last execution result for a given job. + /// + /// The name of the job. + /// The last execution result, or null if the job hasn't been executed yet. + public JobExecutionResult? GetLastResult(string jobName) + { + executionResults.TryGetValue(jobName, out JobExecutionResult? result); + return result; + } + } + + /// + /// Represents the result of a job execution. + /// + public class JobExecutionResult + { + /// + /// Gets or sets a value indicating whether the job execution was successful. + /// + public bool Success { get; set; } + + /// + /// Gets or sets the error message if the job execution failed. + /// + public string ErrorMessage { get; set; } = ""; + + /// + /// Gets or sets the timestamp when the job was executed. + /// + public DateTimeOffset ExecutedAt { get; set; } + } +} diff --git a/roles/middleware/files/FWO.Middleware.Server/Services/QuartzSchedulerOptions.cs b/roles/middleware/files/FWO.Middleware.Server/Services/QuartzSchedulerOptions.cs new file mode 100644 index 0000000000..cd69c96e08 --- /dev/null +++ b/roles/middleware/files/FWO.Middleware.Server/Services/QuartzSchedulerOptions.cs @@ -0,0 +1,11 @@ +namespace FWO.Middleware.Server.Services +{ + /// + /// Options for configuring Quartz scheduler service metadata. + /// + public sealed record QuartzSchedulerOptions( + string SchedulerName, + string JobKeyName, + string TriggerKeyName, + string ConfigSubscriptionQuery); +} diff --git a/roles/middleware/files/FWO.Middleware.Server/Services/QuartzSchedulerServiceBase.cs b/roles/middleware/files/FWO.Middleware.Server/Services/QuartzSchedulerServiceBase.cs new file mode 100644 index 0000000000..b567569b12 --- /dev/null +++ b/roles/middleware/files/FWO.Middleware.Server/Services/QuartzSchedulerServiceBase.cs @@ -0,0 +1,247 @@ +using FWO.Api.Client; +using FWO.Config.Api; +using FWO.Config.Api.Data; +using FWO.Logging; +using Quartz; + +namespace FWO.Middleware.Server.Services +{ + /// + /// Shared Quartz scheduler service logic for config-driven jobs. + /// + public abstract class QuartzSchedulerServiceBase : IAsyncDisposable where TJob : IJob + { + private readonly ISchedulerFactory schedulerFactory; + private readonly ApiConnection apiConnection; + /// + /// Global configuration for scheduler settings. + /// + protected readonly GlobalConfig globalConfig; + private readonly QuartzSchedulerOptions options; + private GraphQlApiSubscription>? configSubscription; + private IScheduler? scheduler; + private bool disposed; + + /// + /// Initializes the scheduler service base. + /// + /// Quartz scheduler factory. + /// GraphQL API connection. + /// Global configuration. + /// Application lifetime for startup hook. + /// Options for scheduler identifiers and subscription. + protected QuartzSchedulerServiceBase( + ISchedulerFactory schedulerFactory, + ApiConnection apiConnection, + GlobalConfig globalConfig, + IHostApplicationLifetime appLifetime, + QuartzSchedulerOptions options) + { + this.schedulerFactory = schedulerFactory; + this.apiConnection = apiConnection; + this.globalConfig = globalConfig; + this.options = options; + + // Attach after application started + appLifetime.ApplicationStarted.Register(OnStarted); + } + + /// + /// Configured sleep time for this scheduler. + /// + protected abstract int SleepTime { get; } + + /// + /// Configured start time for this scheduler. + /// + protected abstract DateTime StartAt { get; } + + /// + /// Interval for this scheduler based on configuration. + /// + protected abstract TimeSpan Interval { get; } + + /// + /// Flag to decide whether the scheduler is active. + /// + protected virtual bool IsActive => true; + + /// + /// Log suffix for the interval (e.g., "h", "m", "s"). + /// + protected virtual string IntervalLogSuffix => "h"; + + /// + /// Log message when scheduler is disabled. + /// + protected virtual string DisabledLogMessage => + "Job disabled (sleep time <= 0) - job kept without trigger for manual runs"; + + private void OnStarted() + { + FireAndForget(HandleStartedAsync(), "Startup failed"); + } + + private async Task HandleStartedAsync() + { + try + { + scheduler = await schedulerFactory.GetScheduler(); + configSubscription = apiConnection.GetSubscription>( + ApiExceptionHandler, + OnGlobalConfigChange, + options.ConfigSubscriptionQuery); + Log.WriteInfo(options.SchedulerName, "Listener started"); + } + catch (Exception ex) + { + Log.WriteError(options.SchedulerName, "Startup failed", ex); + } + } + + private void OnGlobalConfigChange(List config) + { + FireAndForget(HandleGlobalConfigChangeAsync(config), "Failed to reschedule job"); + } + + private async Task HandleGlobalConfigChangeAsync(List config) + { + try + { + globalConfig.SubscriptionUpdateHandler([.. config]); + await ScheduleJob(); + Log.WriteInfo(options.SchedulerName, "Job rescheduled due to config change"); + } + catch (Exception ex) + { + Log.WriteError(options.SchedulerName, "Failed to reschedule job", ex); + } + } + + private async Task ScheduleJob() + { + if (scheduler == null) + { + Log.WriteWarning(options.SchedulerName, "Scheduler not initialized"); + return; + } + + var jobKey = new JobKey(options.JobKeyName); + var triggerKey = new TriggerKey(options.TriggerKeyName); + + // Ensure durable job exists for manual triggering + if (!await scheduler.CheckExists(jobKey)) + { + IJobDetail durableJob = JobBuilder.Create() + .WithIdentity(jobKey) + .StoreDurably() + .Build(); + await scheduler.AddJob(durableJob, replace: true); + Log.WriteInfo(options.SchedulerName, "Added durable job for manual triggering"); + } + + // Remove existing trigger (if any) but keep the job + bool unscheduled = await scheduler.UnscheduleJob(triggerKey); + if (unscheduled) + { + Log.WriteInfo(options.SchedulerName, "Removed existing trigger"); + } + + if (!IsActive || SleepTime <= 0) + { + Log.WriteInfo(options.SchedulerName, DisabledLogMessage); + return; + } + + DateTimeOffset startTime = CalculateStartTime(StartAt, Interval); + + ITrigger trigger = TriggerBuilder.Create() + .WithIdentity(triggerKey) + .ForJob(jobKey) + .StartAt(startTime) + .WithSimpleSchedule(x => x + .WithInterval(Interval) + .RepeatForever()) + .Build(); + + await scheduler.ScheduleJob(trigger); + + Log.WriteInfo( + options.SchedulerName, + $"Trigger scheduled. Start: {startTime:yyyy-MM-dd HH:mm:ss}, Interval: {SleepTime}{IntervalLogSuffix}"); + } + + /// + /// Calculates the next start time in the future from a configured start time. + /// + /// Configured start time. + /// Schedule interval. + /// Next start time in the future. + protected static DateTimeOffset CalculateStartTime(DateTime configuredStartTime, TimeSpan interval) + { + return CalculateStartTime(configuredStartTime, interval, DateTime.Now); + } + + /// + /// Calculates the next start time in the future relative to a fixed point in time. + /// + /// Configured start time. + /// Schedule interval. + /// Reference time. + /// Next start time in the future. + protected static DateTimeOffset CalculateStartTime(DateTime configuredStartTime, TimeSpan interval, DateTime now) + { + if (interval <= TimeSpan.Zero) + { + throw new ArgumentOutOfRangeException(nameof(interval), "Interval must be greater than zero."); + } + + DateTime startTime = configuredStartTime; + while (startTime < now) + { + startTime = startTime.Add(interval); + } + return new DateTimeOffset(startTime); + } + + private void ApiExceptionHandler(Exception exception) + { + Log.WriteError(options.SchedulerName, "Config subscription lead to exception. Retry subscription.", exception); + } + + private void FireAndForget(Task task, string failureMessage) + { + _ = task.ContinueWith( + continuation => + { + if (continuation.Exception != null) + { + Log.WriteError(options.SchedulerName, failureMessage, continuation.Exception); + } + }, + TaskContinuationOptions.OnlyOnFaulted); + } + + /// + /// Releases resources used by the service. + /// Disposes the scheduler and configuration subscription. + /// + public virtual ValueTask DisposeAsync() + { + if (!disposed) + { + try + { + configSubscription?.Dispose(); + // Scheduler lifecycle is managed by QuartzHostedService + disposed = true; + } + catch (Exception ex) + { + Log.WriteError(options.SchedulerName, "Error during disposal", ex); + } + } + return ValueTask.CompletedTask; + } + } +} diff --git a/roles/middleware/files/FWO.Middleware.Server/Services/ReportSchedulerService.cs b/roles/middleware/files/FWO.Middleware.Server/Services/ReportSchedulerService.cs new file mode 100644 index 0000000000..628982bd51 --- /dev/null +++ b/roles/middleware/files/FWO.Middleware.Server/Services/ReportSchedulerService.cs @@ -0,0 +1,94 @@ +using FWO.Logging; +using FWO.Middleware.Server.Jobs; +using Quartz; + +namespace FWO.Middleware.Server.Services +{ + /// + /// Config/state listener for report generation + /// + public class ReportSchedulerService + { + private readonly ISchedulerFactory schedulerFactory; + private IScheduler? scheduler; + private const string JobKeyName = "ReportJob"; + private const string TriggerKeyName = "ReportTrigger"; + private const string SchedulerName = "ReportScheduler"; + private const int DefaultIntervalSeconds = 60; + + /// + /// Initializes the report scheduler service. + /// + /// Quartz scheduler factory. + /// + public ReportSchedulerService(ISchedulerFactory schedulerFactory, IHostApplicationLifetime appLifetime) + { + this.schedulerFactory = schedulerFactory; + + // Attach after application started + appLifetime.ApplicationStarted.Register(OnStarted); + } + + private async void OnStarted() + { + try + { + scheduler = await schedulerFactory.GetScheduler(); + await ScheduleJob(); + + Log.WriteInfo(SchedulerName, "Listener started"); + } + catch (Exception ex) + { + Log.WriteError(SchedulerName, "Startup failed", ex); + } + } + + private async Task ScheduleJob() + { + if (scheduler == null) + { + Log.WriteWarning(SchedulerName, "Scheduler not initialized"); + return; + } + + var jobKey = new JobKey(JobKeyName); + var triggerKey = new TriggerKey(TriggerKeyName); + + // Ensure the job exists as a durable job (so it can be manually triggered) + if (!await scheduler.CheckExists(jobKey)) + { + IJobDetail durableJob = JobBuilder.Create() + .WithIdentity(jobKey) + .StoreDurably() + .Build(); + + await scheduler.AddJob(durableJob, replace: true); + + Log.WriteInfo(SchedulerName, "Added durable job for manual triggering"); + } + + // Remove existing trigger (if any) but keep the job + bool unscheduled = await scheduler.UnscheduleJob(triggerKey); + if (unscheduled) + { + Log.WriteInfo(SchedulerName, "Removed existing trigger"); + } + + // Create trigger with recurring schedule for existing job + ITrigger trigger = TriggerBuilder.Create() + .WithIdentity(triggerKey) + .ForJob(jobKey) + .StartNow() + .WithSimpleSchedule(x => x + .WithIntervalInSeconds(DefaultIntervalSeconds) + .RepeatForever()) + .Build(); + + await scheduler.ScheduleJob(trigger); + + Log.WriteInfo(SchedulerName, + $"Trigger scheduled, Start: {DateTime.Now:yyyy-MM-dd HH:mm:ss}, Interval: {DefaultIntervalSeconds}s"); + } + } +} diff --git a/roles/middleware/files/FWO.Middleware.Server/Services/UpdateRuleOwnerMappingSchedulerService.cs b/roles/middleware/files/FWO.Middleware.Server/Services/UpdateRuleOwnerMappingSchedulerService.cs new file mode 100644 index 0000000000..5bde8aa2f0 --- /dev/null +++ b/roles/middleware/files/FWO.Middleware.Server/Services/UpdateRuleOwnerMappingSchedulerService.cs @@ -0,0 +1,61 @@ +using FWO.Api.Client; +using FWO.Api.Client.Queries; +using FWO.Config.Api; +using FWO.Middleware.Server.Jobs; +using Quartz; + +namespace FWO.Middleware.Server.Services +{ + /// + /// Config listener and rescheduler for rule owner mapping (no BackgroundService) + /// + public class UpdateRuleOwnerMappingSchedulerService : QuartzSchedulerServiceBase + { + private const string JobKeyName = "UpdateRuleOwnerMappingNotifyJob"; + private const string TriggerKeyName = "UpdateRuleOwnerMappingTrigger"; + private const string SchedulerName = "UpdateRuleOwnerMappingScheduler"; + + /// + /// Initializes the import change notify scheduler service. + /// + /// Quartz scheduler factory. + /// GraphQL API connection. + /// Global configuration. + /// Application lifetime for startup hook. + public UpdateRuleOwnerMappingSchedulerService( + ISchedulerFactory schedulerFactory, + ApiConnection apiConnection, + GlobalConfig globalConfig, + IHostApplicationLifetime appLifetime) + : base( + schedulerFactory, + apiConnection, + globalConfig, + appLifetime, + new QuartzSchedulerOptions( + SchedulerName, + JobKeyName, + TriggerKeyName, + ConfigQueries.subscribeUpdateRuleOwnerMappingConfigChanges)) + { } + + /// + protected override int SleepTime => globalConfig.UpdateRuleOwnerMappingSleepTime; + + /// + protected override DateTime StartAt => globalConfig.UpdateRuleOwnerMappingStartAt; + + /// + protected override TimeSpan Interval => TimeSpan.FromSeconds(globalConfig.UpdateRuleOwnerMappingSleepTime); + + /// + protected override bool IsActive => globalConfig.UpdateRuleOwnerMappingActive; + + /// + protected override string IntervalLogSuffix => "s"; + + /// + protected override string DisabledLogMessage => + "Job disabled (inactive or sleep time <= 0) - job kept without trigger for manual runs"; + } +} diff --git a/roles/middleware/files/FWO.Middleware.Server/Services/VarianceAnalysisSchedulerService.cs b/roles/middleware/files/FWO.Middleware.Server/Services/VarianceAnalysisSchedulerService.cs new file mode 100644 index 0000000000..508a27de54 --- /dev/null +++ b/roles/middleware/files/FWO.Middleware.Server/Services/VarianceAnalysisSchedulerService.cs @@ -0,0 +1,54 @@ +using FWO.Api.Client; +using FWO.Api.Client.Queries; +using FWO.Config.Api; +using FWO.Middleware.Server.Jobs; +using Quartz; + +namespace FWO.Middleware.Server.Services +{ + /// + /// Config listener and rescheduler for variance analysis (no BackgroundService) + /// + public class VarianceAnalysisSchedulerService : QuartzSchedulerServiceBase + { + private const string JobKeyName = "VarianceAnalysisJob"; + private const string TriggerKeyName = "VarianceAnalysisTrigger"; + private const string SchedulerName = "VarianceAnalysisScheduler"; + + /// + /// Initializes the variance analysis scheduler service. + /// + /// Quartz scheduler factory. + /// GraphQL API connection. + /// Global configuration. + /// Application lifetime for startup hook. + public VarianceAnalysisSchedulerService( + ISchedulerFactory schedulerFactory, + ApiConnection apiConnection, + GlobalConfig globalConfig, + IHostApplicationLifetime appLifetime) + : base( + schedulerFactory, + apiConnection, + globalConfig, + appLifetime, + new QuartzSchedulerOptions( + SchedulerName, + JobKeyName, + TriggerKeyName, + ConfigQueries.subscribeVarianceAnalysisConfigChanges)) + { } + + /// + protected override int SleepTime => globalConfig.VarianceAnalysisSleepTime; + + /// + protected override DateTime StartAt => globalConfig.VarianceAnalysisStartAt; + + /// + protected override TimeSpan Interval => TimeSpan.FromMinutes(globalConfig.VarianceAnalysisSleepTime); + + /// + protected override string IntervalLogSuffix => "m"; + } +} diff --git a/roles/middleware/files/FWO.Middleware.Server/UiUserHandler.cs b/roles/middleware/files/FWO.Middleware.Server/UiUserHandler.cs index 36191294e9..ba6716b7b8 100644 --- a/roles/middleware/files/FWO.Middleware.Server/UiUserHandler.cs +++ b/roles/middleware/files/FWO.Middleware.Server/UiUserHandler.cs @@ -1,16 +1,20 @@ -using FWO.Api.Client; +using FWO.Api.Client; using FWO.Api.Client.Queries; using FWO.Logging; using FWO.Config.File; -using FWO.Api.Data; -using System.Text.Json.Serialization; -using Newtonsoft.Json; +using FWO.Basics; +using FWO.Data; +using System.Text.Json.Serialization; +using Newtonsoft.Json; +using FWO.Config.Api.Data; +using System; +using System.Text.RegularExpressions; namespace FWO.Middleware.Server { - /// - /// Helper class to read config value for expiration time - /// + /// + /// Helper class to read config value for expiration time + /// public class ConfExpirationTime { /// @@ -20,39 +24,30 @@ public class ConfExpirationTime public int ExpirationValue { get; set; } } - /// - /// Handler class for local Ui user - /// - public class UiUserHandler + /// + /// Handler class for local Ui user + /// + /// + /// Constructor needing the jwt token + /// + public static class UiUserHandler { - private readonly string jwtToken; - private ApiConnection apiConn; - - /// - /// Constructor needing the jwt token - /// - public UiUserHandler(string jwtToken) - { - this.jwtToken = jwtToken; - apiConn = new GraphQlApiConnection(ConfigFile.ApiServerUri, jwtToken); - } - - /// - /// Get the configurated value for the session timeout. - /// - /// session timeout value in minutes - public async Task GetExpirationTime() + /// + /// Get the configurated value for the session timeout. + /// + /// session timeout value in minutes + public static async Task GetExpirationTime(ApiConnection apiConnection) { - int expirationTime = 60 * 12; + int expirationTime = GlobalConst.kSessionExpirationTimeDefault; try { - List resultList = await apiConn.SendQueryAsync>(ConfigQueries.getConfigItemByKey, new { key = "sessionTimeout" }); + List resultList = await apiConnection.SendQueryAsync>(ConfigQueries.getConfigItemByKey, new { key = "sessionTimeout" }); if (resultList.Count > 0) { expirationTime = resultList[0].ExpirationValue; } } - catch(Exception exeption) + catch (Exception exeption) { Log.WriteError("Get ExpirationTime Error", $"Error while trying to find config value in database. Taking default value", exeption); } @@ -65,57 +60,225 @@ public async Task GetExpirationTime() /// the user id is needed for allowing access to report_templates /// /// user including its db id - public async Task HandleUiUserAtLogin(UiUser user) + public static async Task HandleUiUserAtLogin(ApiConnection apiConnection, UiUser user) { - ApiConnection apiConn = new GraphQlApiConnection(ConfigFile.ApiServerUri, jwtToken); bool userSetInDb = false; try { - UiUser[] existingUsers = await apiConn.SendQueryAsync(AuthQueries.getUserByDn, new { dn = user.Dn }); + UiUser[] existingUsers = await apiConnection.SendQueryAsync(AuthQueries.getUserByDn, new { dn = user.Dn }); if (existingUsers.Length > 0) { user.DbId = existingUsers[0].DbId; - user.PasswordMustBeChanged = await UpdateLastLogin(apiConn, user.DbId); + user.PasswordMustBeChanged = await UpdateLastLogin(apiConnection, user.DbId); userSetInDb = true; } else { Log.WriteDebug("User not found", $"Couldn't find {user.Name} in internal database"); } + await GetOwnershipsFromOwnerLdap(apiConnection, user); } - catch(Exception exeption) + catch (Exception exeption) { Log.WriteError("Get User Error", $"Error while trying to find {user.Name} in database.", exeption); } - if(!userSetInDb) + if (!userSetInDb) { Log.WriteInfo("New User", $"User {user.Name} first time log in - adding to internal database."); - await AddUiUserToDb(apiConn, user); + await UpsertUiUser(apiConnection, user, true); } return user; } - private static async Task AddUiUserToDb(ApiConnection apiConn, UiUser user) + + + /// + /// add the ownerships to the given user + /// + public static async Task GetOwnershipsFromOwnerLdap(ApiConnection apiConn, UiUser user) + { + try + { + user.Ownerships.Clear(); + user.RecertOwnerships.Clear(); + + // if the user logging in is the main user for an application, add the ownerships + List directOwnerships = await apiConn.SendQueryAsync>(OwnerQueries.getOwnersForUser, new { userDns = new List { user.Dn } }); + foreach (var owner in directOwnerships) + { + user.Ownerships.Add(owner.Id); + } + + // now handle memberships via groups + List allOwners = await apiConn.SendQueryAsync>(OwnerQueries.getOwners); + List configResult; + configResult = await apiConn.SendQueryAsync>(ConfigQueries.getConfigItemByKey, + new { key = "ownerLdapGroupNames" }); + string? namingConvention = configResult.Count > 0 ? configResult[0].Value : string.Empty; + + + List groupsOfUser = user.Groups ?? []; + if (groupsOfUser.Count > 0) + { + List groupOwnerships = await apiConn.SendQueryAsync>( + OwnerQueries.getOwnersFromGroups, + new { groupDns = groupsOfUser }); + foreach (var owner in groupOwnerships) + { + user.Ownerships.Add(owner.Id); + } + } + + foreach (var group in groupsOfUser) + { + string groupName = new DistName(group).Group; + if (!MatchesNamingConvention(groupName, namingConvention)) + { + continue; // skip groups that do not match the naming convention + } + FwoOwner? owner = FindOwnerWithMatchingGroupName(groupName, allOwners); + + if (owner != null) + { + user.Ownerships.Add(owner.Id); + } + } + + List ownerDns = [user.Dn]; + ownerDns.AddRange(groupsOfUser); + ownerDns = ownerDns + .Where(dn => !string.IsNullOrWhiteSpace(dn)) + .Distinct(StringComparer.OrdinalIgnoreCase) + .ToList(); + List recertOwnerships = ownerDns.Count == 0 + ? [] + : await apiConn.SendQueryAsync>( + OwnerQueries.getOwnersForDnsWithRecertification, + new { dns = ownerDns }); + user.RecertOwnerships.AddRange(recertOwnerships.Select(owner => owner.Id)); + + user.Ownerships = user.Ownerships.Distinct().ToList(); + user.RecertOwnerships = user.RecertOwnerships.Distinct().ToList(); + } + catch (Exception exeption) + { + Log.WriteError("Get ownerships", $"Ownerships could not be detemined for User {user.Name}.", exeption); + } + } + + private static bool MatchesNamingConvention(string userIn, string? namingConvention) + { + if (string.IsNullOrEmpty(namingConvention)) + { + return true; // no naming convention defined, so all cn match + } + string regexPattern = ReplacePlaceholdersWithPattern(namingConvention); + string cn = userIn; + + if (userIn.Contains(',')) + { + // the userIn is a DN, so extract the CN part + cn = userIn.ExtractCommonNameFromDn(); + } + + // turn naming convention into a regex pattern + if (Regex.IsMatch(cn, regexPattern, RegexOptions.IgnoreCase, TimeSpan.FromMilliseconds(100))) + { + return true; // cn matches the naming convention + } + return false; // cn does not match the naming convention + } + + private static string ReplacePlaceholdersWithPattern(string input) + { + // Pattern: finds @@...@@ – non-greedy + string pattern = "@@(.*?)@@"; + + // Replaces each match with the regex expression + string replaced = Regex.Replace(input, pattern, "(.*?)", RegexOptions.IgnoreCase, TimeSpan.FromMilliseconds(100)); + + return replaced; + } + private static FwoOwner? FindOwnerWithMatchingGroupName(string groupName, List apps) + { + foreach (var app in apps) + { + foreach (string dn in app.GetAllOwnerResponsibles()) + { + if (MatchesGroupName(dn, groupName)) + { + return app; + } + } + } + return null; + } + + private static bool MatchesGroupName(string dn, string groupName) + { + if (string.IsNullOrWhiteSpace(dn)) + { + return false; + } + string[] groupDnParts = dn.Split(',', StringSplitOptions.RemoveEmptyEntries); + if (groupDnParts.Length == 0) + { + return false; + } + string[] cnParts = groupDnParts[0].Split('=', StringSplitOptions.RemoveEmptyEntries); + // note: this only works for flat groups! TODO: make this universal by checking group membership + return cnParts.Length == 2 && cnParts[1].Equals(groupName, StringComparison.OrdinalIgnoreCase); + } + + /// + /// add user to uiuser - either with or without current login time + /// + /// void + public static async Task UpsertUiUser(ApiConnection apiConn, UiUser user, bool loginHappened = false) { try { // add new user to uiuser - var Variables = new + if (loginHappened) { - uuid = user.Dn, - uiuser_username = user.Name, - email = user.Email, - tenant = (user.Tenant != null ? user.Tenant.Id : (int?)null), - loginTime = DateTime.UtcNow, - passwordMustBeChanged = false, - ldapConnectionId = user.LdapConnection.Id - }; - ReturnId[]? returnIds = (await apiConn.SendQueryAsync(AuthQueries.addUser, Variables)).ReturnIds; - if(returnIds != null) + var VariablesWithLogin = new + { + uuid = user.Dn, + uiuser_username = user.Name, + uiuser_first_name = user.Firstname, + uiuser_last_name = user.Lastname, + email = user.Email, + tenant = user.Tenant != null ? user.Tenant.Id : (int?)null, + passwordMustBeChanged = false, + ldapConnectionId = user.LdapConnection.Id, + loginTime = DateTime.UtcNow + }; + ReturnId[]? returnIds = (await apiConn.SendQueryAsync(AuthQueries.upsertUiUser, VariablesWithLogin)).ReturnIds; + if (returnIds != null) + { + user.DbId = returnIds[0].NewId; + } + } + else { - user.DbId = returnIds[0].NewId; + var VariablesWithoutLogin = new + { + uuid = user.Dn, + uiuser_username = user.Name, + uiuser_first_name = user.Firstname, + uiuser_last_name = user.Lastname, + email = user.Email, + tenant = user.Tenant != null ? user.Tenant.Id : (int?)null, + passwordMustBeChanged = false, + ldapConnectionId = user.LdapConnection.Id + }; + ReturnId[]? returnIds = (await apiConn.SendQueryAsync(AuthQueries.upsertUiUser, VariablesWithoutLogin)).ReturnIds; + if (returnIds != null) + { + user.DbId = returnIds[0].NewId; + } } } catch (Exception exeption) @@ -130,34 +293,34 @@ private static async Task UpdateLastLogin(ApiConnection apiConn, int id) { var Variables = new { - id = id, + id = id, loginTime = DateTime.UtcNow }; return (await apiConn.SendQueryAsync(AuthQueries.updateUserLastLogin, Variables)).PasswordMustBeChanged; } - catch(Exception exeption) + catch (Exception exeption) { Log.WriteError("Update User Error", $"User {id} could not be updated in database.", exeption); } return true; } - /// - /// Update the passwordMustBeChanged flag. - /// + /// + /// Update the passwordMustBeChanged flag. + /// public static async Task UpdateUserPasswordChanged(ApiConnection apiConn, string userDn, bool passwordMustBeChanged = false) { try { var Variables = new { - dn = userDn, + dn = userDn, passwordMustBeChanged = passwordMustBeChanged, changeTime = DateTime.UtcNow }; await apiConn.SendQueryAsync(AuthQueries.updateUserPasswordChange, Variables); } - catch(Exception exeption) + catch (Exception exeption) { Log.WriteError("Update User Error", $"User {userDn} could not be updated in database.", exeption); } diff --git a/roles/middleware/files/FWO.Middleware.Server/ZoneMatrixDataImport.cs b/roles/middleware/files/FWO.Middleware.Server/ZoneMatrixDataImport.cs new file mode 100644 index 0000000000..f15f2c9dae --- /dev/null +++ b/roles/middleware/files/FWO.Middleware.Server/ZoneMatrixDataImport.cs @@ -0,0 +1,304 @@ +using FWO.Basics; +using FWO.Logging; +using FWO.Api.Client; +using FWO.Api.Client.Queries; +using FWO.Config.Api; +using FWO.Data; +using FWO.Data.Logging; +using FWO.Services; +using FWO.Services.Logging; +using System.Text.Json; +using FWO.Basics.Exceptions; +using NetTools; +using System.Net; + +namespace FWO.Middleware.Server +{ + /// + /// Class handling the Network Zone Matrix Data Import + /// + public class ZoneMatrixDataImport(ApiConnection apiConnection, GlobalConfig globalConfig) : DataImportBase(apiConnection, globalConfig) + { + List ExistingZones = []; + readonly Dictionary ZoneIds = []; + int MatrixId = 0; + private const string LogMessageTitle = "Import Network Zone Matrix Data"; + private const string LevelFile = "Import File"; + private const string LevelZone = "Zone"; + private struct Counters + { + public int AllZones = 0; + public int NewZoneSuccess = 0; + public int UpdateZoneSuccess = 0; + public int ZoneFail = 0; + public int DeleteZoneSuccess = 0; + public int DeleteZoneFail = 0; + public int InsertConnection = 0; + public int RemoveConnection = 0; + + public Counters() { } + } + Counters counters = new(); + + /// + /// Run a single Network Zone Matrix Data Import with uploaded data + /// + public async Task Run(string importFileName, string importedData, string userName, string userDn) + { + List FailedImports = []; + importFile = importedData; + Log.WriteAudit( + Title: $"Compliance Matrix Import", + Text: $"Run import from {importFileName}", + UserName: userName, + UserDN: userDn); + + return await ImportSingleMatrix(importFileName, FailedImports); + } + + private async Task ImportSingleMatrix(string importfileName, List failedImports) + { + string responsMessage; + try + { + ImportNwZoneMatrixData importedZoneMatrixData = JsonSerializer.Deserialize(importFile) ?? throw new JsonException("File could not be parsed."); + CheckData(importedZoneMatrixData); + (MatrixId, ExistingZones) = await GetExistingMatrixWithZones(importedZoneMatrixData.Name); + responsMessage = await ImportMatrix(importedZoneMatrixData, importfileName); + } + catch (Exception exc) + { + responsMessage = $"File {importfileName} could not be processed: {exc.Message}"; + Log.WriteError(LogMessageTitle, responsMessage); + await AddLogEntry(GlobalConst.kImportZoneMatrixData, 2, LevelFile, responsMessage); + failedImports.Add(importfileName); + } + return responsMessage; + } + + private static void CheckData(ImportNwZoneMatrixData importedZoneMatrixData) + { + if (string.IsNullOrEmpty(importedZoneMatrixData.Name)) + { + throw new ArgumentException("No Matrix Name"); + } + if (importedZoneMatrixData.NetworkZones.Select(z => z.Name).Distinct().ToList().Count != importedZoneMatrixData.NetworkZones.Count) + { + throw new ArgumentException("Duplicate Zone Names"); + } + if (importedZoneMatrixData.NetworkZones.Select(z => z.IdString).Distinct().ToList().Count != importedZoneMatrixData.NetworkZones.Count) + { + throw new ArgumentException("Duplicate Zone IdStrings"); + } + } + + private async Task ImportMatrix(ImportNwZoneMatrixData importedMatrix, string importfileName) + { + counters = new() { AllZones = importedMatrix.NetworkZones.Count }; + if (MatrixId == 0) + { + await CreateMatrix(importedMatrix.Name, importfileName, importedMatrix.Comment); + } + else + { + await UpdateMatrix(importfileName, importedMatrix.Comment); + } + + foreach (var incomingZone in importedMatrix.NetworkZones) + { + await SaveZone(incomingZone); + } + + foreach (var existingZone in ExistingZones.Where(z => importedMatrix.NetworkZones.FirstOrDefault(i => i.IdString == z.IdString) == null)) + { + await DeactivateZone(existingZone); + } + + await NetworkZoneService.UpdateSpecialZones(MatrixId, apiConnection, globalConfig); + + // Reload existing zones with all Ids + ExistingZones = await apiConnection.SendQueryAsync>(ComplianceQueries.getNetworkZonesForMatrix, new { criterionId = MatrixId }); + foreach (var zone in ExistingZones) + { + ZoneIds.Add(zone.IdString, zone.Id); + } + foreach (var incomingZone in importedMatrix.NetworkZones) + { + (int inserts, int removes) = await SaveZoneConnections(incomingZone); + counters.InsertConnection += inserts; + counters.RemoveConnection += removes; + } + + string messageText = ConstructMessageText(importfileName); + Log.WriteInfo(LogMessageTitle, messageText); + await AddLogEntry(GlobalConst.kImportZoneMatrixData, 0, LevelFile, messageText); + return messageText; + } + + private string ConstructMessageText(string importfileName) + { + return $"Ok: Imported from {importfileName}: Total number of network zones: {counters.AllZones}, " + + $"new: {counters.NewZoneSuccess}, updated: {counters.UpdateZoneSuccess}, failed: {counters.ZoneFail}. " + + $"Deleted: {counters.DeleteZoneSuccess}, failed deletions: {counters.DeleteZoneFail}. " + + $"Inserted connections: {counters.InsertConnection}, removed connections: {counters.RemoveConnection}."; + } + + private async Task<(int, List)> GetExistingMatrixWithZones(string matrixName) + { + List existingMatrices = await apiConnection.SendQueryAsync>(ComplianceQueries.getMatrixByName, new { name = matrixName }); + if (existingMatrices.Count > 0) + { + if (string.IsNullOrEmpty(existingMatrices[0].ImportSource)) + { + throw new ArgumentException("Manually created matrix existing with same Name"); + } + int matrixId = existingMatrices[0].Id; + return (matrixId, await apiConnection.SendQueryAsync>(ComplianceQueries.getNetworkZonesForMatrix, new { criterionId = matrixId })); + } + return (0, []); + } + + private async Task CreateMatrix(string MatrixName, string importfileName, string? comment) + { + ReturnId[]? returnIds = (await apiConnection.SendQueryAsync(ComplianceQueries.addCriterion, + new { name = MatrixName, importSource = importfileName, comment = comment, criterionType = CriterionType.Matrix.ToString() })).ReturnIds; + if (returnIds != null && returnIds.Length > 0) + { + MatrixId = returnIds[0].InsertedId; + await ChangeLogHelper.LogMatrixChange(new MatrixChangeLogRequest + { + Family = ChangeLogFamily.Import, + Operation = ChangeLogOperation.Create, + UserId = "Importer", + MatrixId = MatrixId, + MatrixName = MatrixName, + Origin = ChangeLogOrigin.Import + }); + } + else + { + throw new InternalException("Could not create Matrix"); + } + } + + private async Task UpdateMatrix(string importfileName, string? comment) + { + await apiConnection.SendQueryAsync(ComplianceQueries.updateCriterionMetadata, + new { id = MatrixId, importSource = importfileName, comment = comment }); + } + + private async Task SaveZone(NetworkZoneData incomingZone) + { + try + { + ComplianceNetworkZone? existingZone = ExistingZones.FirstOrDefault(x => x.IdString == incomingZone.IdString); + if (existingZone == null) + { + await NewZone(incomingZone); + } + else + { + await UpdateZone(incomingZone, existingZone); + } + } + catch (Exception exc) + { + string errorText = $"Zone {incomingZone.Name}({incomingZone.IdString}) could not be processed."; + Log.WriteError(LogMessageTitle, errorText, exc); + await AddLogEntry(GlobalConst.kImportZoneMatrixData, 1, LevelZone, errorText); + counters.ZoneFail++; + return false; + } + return true; + } + + private async Task NewZone(NetworkZoneData incomingZoneData) + { + ComplianceNetworkZone incomingZone = new() + { + CriterionId = MatrixId, + Name = incomingZoneData.Name, + IdString = incomingZoneData.IdString + }; + NetworkZoneService.AdditionsDeletions addDel = new() + { + IpRangesToAdd = incomingZoneData.IpData.ConvertAll(i => ConvertIpDataToAddressRange(i)) + }; + await NetworkZoneService.AddZone(incomingZone, addDel, apiConnection); + counters.NewZoneSuccess++; + } + + private async Task UpdateZone(NetworkZoneData incomingZoneData, ComplianceNetworkZone existingZone) + { + List incomingRanges = incomingZoneData.IpData.ConvertAll(i => ConvertIpDataToAddressRange(i)); + NetworkZoneService.AdditionsDeletions addDel = new() + { + IpRangesToAdd = [.. incomingRanges.Except(existingZone.IPRanges)], + IpRangesToDelete = [.. existingZone.IPRanges.Except(incomingRanges)] + }; + if (addDel.IpRangesToAdd.Count > 0 || addDel.IpRangesToDelete.Count > 0 || existingZone.Name != incomingZoneData.Name) + { + existingZone.Name = incomingZoneData.Name; + await NetworkZoneService.UpdateZone(existingZone, addDel, apiConnection); + counters.UpdateZoneSuccess++; + } + } + + private async Task DeactivateZone(ComplianceNetworkZone zone) + { + try + { + await NetworkZoneService.RemoveZone(zone, apiConnection); + counters.DeleteZoneSuccess++; + } + catch (Exception exc) + { + string errorText = $"Outdated Zone {zone.Name} could not be deleted."; + Log.WriteError(LogMessageTitle, errorText, exc); + await AddLogEntry(GlobalConst.kImportZoneMatrixData, 1, LevelZone, errorText); + counters.DeleteZoneFail++; + return false; + } + return true; + } + + private async Task<(int, int)> SaveZoneConnections(NetworkZoneData incomingZoneData) + { + ComplianceNetworkZone? existingZone = ExistingZones.FirstOrDefault(x => x.IdString == incomingZoneData.IdString); + if (existingZone != null) + { + // Dont allow auto-calculated undefine-internal to have allowed communications. + + if (globalConfig.AutoCalculateInternetZone + && globalConfig.AutoCalculateUndefinedInternalZone + && incomingZoneData.CommData.Any(communication => communication.IdString == "AUTO_CALCULATED_ZONE_UNDEFINED_INTERNAL")) + { + throw new ArgumentException("Matrix contains allowed communication data for readonly auto-calculated undefined-internal zone."); + } + + List existDestZoneIds = [.. existingZone.AllowedCommunicationDestinations.Select(x => x.Id)]; + List incomingDestZoneIds = [.. incomingZoneData.CommData.Select(x => ZoneIds[x.IdString])]; + + NetworkZoneService.AdditionsDeletions addDel = new() + { + DestinationZonesToAdd = incomingDestZoneIds.Except(existDestZoneIds).ToList().ConvertAll(i => new ComplianceNetworkZone() { Id = i }), + DestinationZonesToDelete = existDestZoneIds.Except(incomingDestZoneIds).ToList().ConvertAll(i => new ComplianceNetworkZone() { Id = i }) + }; + await NetworkZoneService.UpdateZone(existingZone, addDel, apiConnection); + return (addDel.DestinationZonesToAdd.Count, addDel.DestinationZonesToDelete.Count); + } + return (0, 0); + } + + private static IPAddressRange ConvertIpDataToAddressRange(ModellingImportAreaIpData importAreaIpData) + { + string Ip = importAreaIpData.Ip; + string? IpEnd = importAreaIpData.IpEnd; + if (string.IsNullOrEmpty(importAreaIpData.IpEnd)) + { + (Ip, IpEnd) = IpOperations.SplitIpToRange(importAreaIpData.Ip); + } + return new(IPAddress.Parse(Ip), IPAddress.Parse(IpEnd ?? Ip)); + } + } +} diff --git a/roles/middleware/files/get_pg_version.sh b/roles/middleware/files/get_pg_version.sh index 092d037a5e..784a574ae3 100644 --- a/roles/middleware/files/get_pg_version.sh +++ b/roles/middleware/files/get_pg_version.sh @@ -3,7 +3,7 @@ ver=$(psql --version | cut -d " " -f 3) major_ver=$(echo "$ver" | cut -d "." -f 1) minor_ver=$(echo "$ver" | cut -d "." -f 2) # return only major version from pg 10 onwards -if [ $((major_ver * 1)) -gt 9 ] +if [[ $((major_ver * 1)) -gt 9 ]] then ver=$major_ver fi diff --git a/roles/middleware/tasks/create_auth_secrets.yml b/roles/middleware/tasks/create_auth_secrets.yml index 12079bc046..c1c8069e62 100644 --- a/roles/middleware/tasks/create_auth_secrets.yml +++ b/roles/middleware/tasks/create_auth_secrets.yml @@ -3,9 +3,9 @@ file: path: "{{ fworch_home }}/etc/secrets" state: directory - mode: "0700" + mode: "0750" owner: "{{ fworch_user }}" - group: "{{ fworch_group }}" + group: "{{ postgres_group }}" - name: read ldap manager pwd from file slurp: @@ -19,18 +19,29 @@ # we need the public key during api install # private key needed only on the middleware server, public key on ui & api + - name: check for existing JWT private key + stat: + path: "{{ jwt_private_key_file }}" + register: jwt_private_key_stat + + - name: check for existing JWT public key + stat: + path: "{{ jwt_public_key_file }}" + register: jwt_public_key_stat + # creates a .pem keyfile including both private and public key in base64 - - name: Generate JWT private key + - name: Generate JWT private key openssl_privatekey: path: "{{ jwt_private_key_file }}" size: 2048 - force: true + force: false type: RSA owner: "{{ fworch_user }}" group: "{{ fworch_group }}" mode: "0600" backup: true become: true + when: not testkeys | bool - name: Generate JWT public key in PEM format openssl_publickey: @@ -40,6 +51,9 @@ group: "{{ fworch_group }}" mode: "0644" become: true + when: + - not testkeys | bool + - not jwt_private_key_stat.stat.exists or not jwt_public_key_stat.stat.exists - name: overwrite random private key with fixed test key copy: diff --git a/roles/middleware/tasks/install_and_run_mw_service.yml b/roles/middleware/tasks/install_and_run_mw_service.yml index 5241f6117e..8df46a6378 100644 --- a/roles/middleware/tasks/install_and_run_mw_service.yml +++ b/roles/middleware/tasks/install_and_run_mw_service.yml @@ -5,9 +5,14 @@ backup: true mode: "0644" owner: "root" + register: mw_service_template become: true environment: "{{ proxy_env }}" +- name: track middleware deployment changes from systemd template + set_fact: + mw_deploy_changed: "{{ (mw_deploy_changed | default(false)) or mw_service_template.changed }}" + - name: publish middlewareserver command: "dotnet publish --no-self-contained -c {{ dotnet_mode }} -o {{ middleware_server_start_dir }}/bin/{{ dotnet_mode }}/net{{ dotnet_version }}" args: @@ -15,6 +20,13 @@ become: true become_user: "{{ fworch_user }}" environment: "{{ proxy_env }}" + register: publish_result + when: mw_deploy_changed | default(false) + +- name: fail if publish returned an error + fail: + msg: "could not publish middleware server successfully: {{ publish_result }}" + when: publish_result is defined and publish_result.rc != 0 - name: make middleware service run at host startup systemd: diff --git a/roles/middleware/tasks/main.yml b/roles/middleware/tasks/main.yml index 24e952a9d0..d21bfb7e97 100644 --- a/roles/middleware/tasks/main.yml +++ b/roles/middleware/tasks/main.yml @@ -34,11 +34,12 @@ group: "{{ fworch_group }}" - name: copy middleware module files to middlewareserver - copy: + synchronize: src: "{{ middleware_path_rel }}" dest: "{{ middleware_server_base_dir }}" - owner: "{{ fworch_user }}" - group: "{{ fworch_group }}" + rsync_opts: + - "--chown={{ fworch_user }}:{{ fworch_group }}" + register: middleware_sync_result tags: [ 'test' ] - name: install python3-openssl for openssl key generation and unprivileged user @@ -49,6 +50,10 @@ - python3-cryptography - python3-openssl + - name: track middleware deployment changes + set_fact: + mw_deploy_changed: "{{ middleware_sync_result.changed or installation_mode == 'new' }}" + become: true - name: create auth secrets (jwt key, ldap) @@ -75,8 +80,8 @@ path: "{{ fworch_secrets_dir }}" state: directory owner: "{{ fworch_user }}" - group: "{{ fworch_group }}" - mode: "0700" + group: "{{ postgres_group }}" + mode: "0750" become: true - name: set UI admin password for testing @@ -106,31 +111,21 @@ server_uri: "{{ openldap_url }}" bind_dn: "{{ openldap_superuser_dn }}" bind_pw: "{{ ldap_manager_pwd }}" + validate_certs: "{{ openldap_server_enable_ssl | ternary(false, omit) }}" + ca_path: "{{ openldap_server_enable_ssl | ternary(openldap_server_cert, omit) }}" when: installation_mode == 'new' -- name: set importer user password randomly - set_fact: - importer_password: "{{ randomly_generated_pwd }}" - when: not testkeys|bool and installation_mode == 'new' - -- name: write importer_password to secrets directory - copy: - content: "{{ importer_password }}\n" - dest: "{{ importer_password_file }}" - mode: '0600' - owner: "{{ fworch_user }}" - group: "{{ fworch_group }}" +- name: read importer password from secrets directory + slurp: + src: "{{ importer_password_file }}" + register: importer_password_slurp become: true when: installation_mode == 'new' -# the local copy of the import pwd will be used by the importer role to copy it to the importer host(s) -- name: fetch importer pwd to installer machine for distribution to importer machines - fetch: - src: "{{ importer_password_file }}" - dest: "{{ importer_password_file_on_installer }}" - flat: true - mode: '0600' - become: true +- name: set importer password fact from secrets directory + set_fact: + importer_password: "{{ importer_password_slurp.content | b64decode | trim }}" + when: installation_mode == 'new' - name: Set importer password in ldap ldap_passwd: @@ -139,6 +134,8 @@ server_uri: "{{ openldap_url }}" bind_dn: "{{ openldap_superuser_dn }}" bind_pw: "{{ ldap_manager_pwd }}" + validate_certs: "{{ openldap_server_enable_ssl | ternary(false, omit) }}" + ca_path: "{{ openldap_server_enable_ssl | ternary(openldap_server_cert, omit) }}" when: installation_mode == 'new' - name: Set {{ openldap_readonly_user_name }} password in ldap @@ -148,6 +145,8 @@ server_uri: "{{ openldap_url }}" bind_dn: "{{ openldap_superuser_dn }}" bind_pw: "{{ ldap_manager_pwd }}" + validate_certs: "{{ openldap_server_enable_ssl | ternary(false, omit) }}" + ca_path: "{{ openldap_server_enable_ssl | ternary(openldap_server_cert, omit) }}" when: installation_mode == "new" - name: Set "{{ openldap_writer_name }}" password in ldap @@ -157,6 +156,8 @@ server_uri: "{{ openldap_url }}" bind_dn: "{{ openldap_superuser_dn }}" bind_pw: "{{ ldap_manager_pwd }}" + validate_certs: "{{ openldap_server_enable_ssl | ternary(false, omit) }}" + ca_path: "{{ openldap_server_enable_ssl | ternary(openldap_server_cert, omit) }}" when: installation_mode == "new" - name: Set {{ audit_user }} password in ldap @@ -166,6 +167,8 @@ server_uri: "{{ openldap_url }}" bind_dn: "{{ openldap_superuser_dn }}" bind_pw: "{{ ldap_manager_pwd }}" + validate_certs: "{{ openldap_server_enable_ssl | ternary(false, omit) }}" + ca_path: "{{ openldap_server_enable_ssl | ternary(openldap_server_cert, omit) }}" when: audit_user is defined and auditor_initial_pwd is defined and installation_mode=='new' - name: insert admin tenant0 to database @@ -181,20 +184,16 @@ become_user: postgres when: installation_mode == "new" -- name: add connection for internal ldap +- name: add connection for internal ldap with encrypted passwords postgresql_query: db: "{{ fworch_db_name }}" query: > - DO $do$ BEGIN IF NOT EXISTS - (SELECT * FROM ldap_connection WHERE ldap_server = '{{ openldap_server }}') - THEN INSERT INTO ldap_connection - (ldap_server, ldap_port, ldap_searchpath_for_users, ldap_searchpath_for_roles, ldap_searchpath_for_groups, - ldap_tenant_level, ldap_search_user, ldap_search_user_pwd, ldap_write_user, ldap_write_user_pwd, ldap_type) - VALUES ('{{ openldap_server }}', {{ openldap_port }}, - '{{ openldap_std_user_dn }}', '{{ openldap_std_role_dn }}', '{{ openldap_std_group_dn }}', + DO $do$ BEGIN + PERFORM insertLocalLdapWithEncryptedPasswords ('{{ openldap_server }}', {{ openldap_port }}, + '{{ openldap_std_user_dn }}', '{{ openldap_std_role_dn }}', '{{ openldap_std_group_dn }}', '{{ openldap_std_group_dn }}', 5, '{{ openldap_readonly_user_dn }}', '{{ ldap_inspector_pw }}', '{{ openldap_writer_dn }}', '{{ ldap_writer_pw }}', 2); - END IF; END $do$ + END $do$ become: true become_user: postgres when: installation_mode == "new" diff --git a/roles/middleware/tasks/mw_apache_install_and_setup.yml b/roles/middleware/tasks/mw_apache_install_and_setup.yml index 3546a4e39d..1d6db60dde 100644 --- a/roles/middleware/tasks/mw_apache_install_and_setup.yml +++ b/roles/middleware/tasks/mw_apache_install_and_setup.yml @@ -14,6 +14,12 @@ owner: root group: root + - name: enable apache modules proxy proxy_http ssl + apache2_module: + state: present + name: "{{ item }}" + loop: "{{ apache2_required_modules }}" + - name: create apache certificates include_role: name: openssl-cert @@ -37,15 +43,6 @@ remote_src: true when: installation_mode == "new" - - name: enable apache modules proxy proxy_http ssl - apache2_module: state=present name={{ item }} - loop: - - rewrite - - proxy - - proxy_http - - ssl - - proxy_wstunnel - - name: enable {{ product_name }} middleware apache site command: "a2ensite {{ product_name }}-mw" register: testoutput @@ -54,6 +51,7 @@ lineinfile: path: "/etc/apache2/ports.conf" line: "Listen {{ middleware_web_listener_port }}" + regexp: '^\s*Listen {{ middleware_web_listener_port }}\s*$' insertafter: "" - name: restart apache diff --git a/roles/middleware/tasks/set_initial_ldap_tree.yml b/roles/middleware/tasks/set_initial_ldap_tree.yml index 43ea55cbfe..4703d2792d 100644 --- a/roles/middleware/tasks/set_initial_ldap_tree.yml +++ b/roles/middleware/tasks/set_initial_ldap_tree.yml @@ -2,6 +2,27 @@ set_fact: ldif_changetype: add +- name: build ldap tls options + set_fact: + ldap_tls_opts: >- + {% if openldap_server_enable_ssl | default(false) -%} + -o TLS_REQCERT=never{% if openldap_server_cert is defined %} -o TLS_CACERT={{ openldap_server_cert }}{% endif %} + {%- endif %} + ldap_cmd_url: >- + {% if openldap_server_enable_ssl | default(false) -%} + ldaps://{{ openldap_server }}:{{ openldap_port | default(636) }} + {%- else -%} + ldap://{{ openldap_server }}:{{ (openldap_port | default(389) | int == 636) | ternary(389, openldap_port | default(389)) }} + {%- endif %} + +- name: create middleware ldif directory + file: + path: "{{ middleware_ldif_dir }}" + state: directory + owner: "{{ fworch_user }}" + group: "{{ fworch_group }}" + become: true + - name: copy the ldif templates to system template: src: "{{ item }}" @@ -14,7 +35,7 @@ become: true - name: add tree - command: "ldapmodify -H {{ openldap_url }} -D {{ openldap_superuser_dn }} -w {{ ldap_manager_pwd }} -x -f {{ middleware_ldif_dir }}/tree_{{ item }}.ldif" + command: "ldapmodify {{ ldap_tls_opts }} -H {{ ldap_cmd_url }} -D {{ openldap_superuser_dn }} -w {{ ldap_manager_pwd }} -x -f {{ middleware_ldif_dir }}/tree_{{ item }}.ldif" loop: - level_0 - level_1 diff --git a/roles/middleware/tasks/upgrade/5.4.1.yml b/roles/middleware/tasks/upgrade/5.4.1.yml index 33a5995e63..88bae99b5d 100644 --- a/roles/middleware/tasks/upgrade/5.4.1.yml +++ b/roles/middleware/tasks/upgrade/5.4.1.yml @@ -21,3 +21,5 @@ server_uri: "{{ openldap_url }}" bind_dn: "{{ openldap_superuser_dn }}" bind_pw: "{{ ldap_manager_pwd }}" + validate_certs: "{{ openldap_server_enable_ssl | ternary(false, omit) }}" + ca_path: "{{ openldap_server_enable_ssl | ternary(openldap_server_cert, omit) }}" diff --git a/roles/middleware/tasks/upgrade_ldap_tree.yml b/roles/middleware/tasks/upgrade_ldap_tree.yml index 363fc33cb2..603fdab7b7 100644 --- a/roles/middleware/tasks/upgrade_ldap_tree.yml +++ b/roles/middleware/tasks/upgrade_ldap_tree.yml @@ -17,6 +17,14 @@ with_fileglob: - "../templates/upgrade/*.ldif.j2" +- name: create middleware ldif directory + file: + path: "{{ middleware_ldif_dir }}" + state: directory + owner: "{{ fworch_user }}" + group: "{{ fworch_group }}" + become: true + - name: copy the upgrade ldif templates to target template: src: "../templates/upgrade/{{ item }}.ldif.j2" diff --git a/roles/middleware/tasks/upgrade_ldif_file.yml b/roles/middleware/tasks/upgrade_ldif_file.yml index ce44c4308d..ef6ea4f577 100644 --- a/roles/middleware/tasks/upgrade_ldif_file.yml +++ b/roles/middleware/tasks/upgrade_ldif_file.yml @@ -11,6 +11,7 @@ set_fact: ldif_list: "{{ big_ldif_file.split('dn: ') }}" -- name: +- name: calling upgrade_modify_routine include_tasks: upgrade_modify_routine.yml loop: "{{ ldif_list[1:] }}" + # ignoring first lines before first dn (TODO: make this more robust for files that start with dn: line) diff --git a/roles/middleware/tasks/upgrade_modify_routine.yml b/roles/middleware/tasks/upgrade_modify_routine.yml index 355343e16f..6aa59e8b6d 100644 --- a/roles/middleware/tasks/upgrade_modify_routine.yml +++ b/roles/middleware/tasks/upgrade_modify_routine.yml @@ -5,6 +5,20 @@ force: true owner: "{{ fworch_user }}" group: "{{ fworch_group }}" + become: true + +- name: build ldap tls options + set_fact: + ldap_tls_opts: >- + {% if openldap_server_enable_ssl | default(false) -%} + -o TLS_REQCERT=never{% if openldap_server_cert is defined %} -o TLS_CACERT={{ openldap_server_cert }}{% endif %} + {%- endif %} + ldap_cmd_url: >- + {% if openldap_server_enable_ssl | default(false) -%} + ldaps://{{ openldap_server }}:{{ openldap_port | default(636) }} + {%- else -%} + ldap://{{ openldap_server }}:{{ (openldap_port | default(389) | int == 636) | ternary(389, openldap_port | default(389)) }} + {%- endif %} - name: determine distinguished name and changetype set_fact: @@ -13,25 +27,25 @@ - name: test if distinguished name exists # error code 32, when searchbase not existing - command: "ldapsearch -H {{ openldap_url }} -D {{ openldap_superuser_dn }} -w {{ ldap_manager_pwd }} -b {{ distinguished_name }}" + command: "ldapsearch {{ ldap_tls_opts }} -H {{ ldap_cmd_url }} -D {{ openldap_superuser_dn }} -w {{ ldap_manager_pwd }} -b {{ distinguished_name }}" #become: true register: search_existence failed_when: (search_existence.rc != 0) and (search_existence.rc != 32) - name: add ldap entry if not existing - command: "ldapmodify -H {{ openldap_url }} -D {{ openldap_superuser_dn }} -w {{ ldap_manager_pwd }} -x -f {{ middleware_ldif_dir }}/{{ outer_item }}_{{ item.split(',')[0] }}.ldif" + command: "ldapmodify {{ ldap_tls_opts }} -H {{ ldap_cmd_url }} -D {{ openldap_superuser_dn }} -w {{ ldap_manager_pwd }} -x -f {{ middleware_ldif_dir }}/{{ outer_item }}_{{ item.split(',')[0] }}.ldif" when: (changetype == 'add') and (search_existence.stdout.split('result:')[1].splitlines()[0] is match('.*No such object')) #become: true - name: delete ldap entry if existing # dont delete in case numEntries > 1, otherwise ldap nodes are disconected - command: "ldapmodify -H {{ openldap_url }} -D {{ openldap_superuser_dn }} -w {{ ldap_manager_pwd }} -x -f {{ middleware_ldif_dir }}/{{ outer_item }}_{{ item.split(',')[0] }}.ldif" + command: "ldapmodify {{ ldap_tls_opts }} -H {{ ldap_cmd_url }} -D {{ openldap_superuser_dn }} -w {{ ldap_manager_pwd }} -x -f {{ middleware_ldif_dir }}/{{ outer_item }}_{{ item.split(',')[0] }}.ldif" when: (changetype == 'delete') and (search_existence.stdout.split('# numEntries:')[1].splitlines()[0] is match('\s1')) #become: true - name: modify ldap entry if existing # error code 20, when attribute already exists - command: "ldapmodify -H {{ openldap_url }} -D {{ openldap_superuser_dn }} -w {{ ldap_manager_pwd }} -x -f {{ middleware_ldif_dir }}/{{ outer_item }}_{{ item.split(',')[0] }}.ldif" + command: "ldapmodify {{ ldap_tls_opts }} -H {{ ldap_cmd_url }} -D {{ openldap_superuser_dn }} -w {{ ldap_manager_pwd }} -x -f {{ middleware_ldif_dir }}/{{ outer_item }}_{{ item.split(',')[0] }}.ldif" register: modify_out when: (changetype == 'modify') and (search_existence.stdout.split('# numEntries:')[1].splitlines()[0] is match('\s1')) #become: true diff --git a/roles/middleware/templates/fworch-middleware.service.j2 b/roles/middleware/templates/fworch-middleware.service.j2 index e7fd745f13..b64f6c5d8b 100644 --- a/roles/middleware/templates/fworch-middleware.service.j2 +++ b/roles/middleware/templates/fworch-middleware.service.j2 @@ -9,10 +9,9 @@ After=network.target remote-fs.target nss-lookup.target slapd.service WorkingDirectory={{ middleware_server_start_dir }} ExecStartPre=/bin/sleep 10 ExecStart={{ middleware_server_start_dir }}/bin/{{ dotnet_mode }}/net{{ dotnet_version }}/FWO.Middleware.Server -#StandardOutput=syslog -#StandardError=syslog +Restart=on-failure SyslogIdentifier={{ middleware_server_syslog_id }} User={{ fworch_user }} -Environment= +Environment="PYTHONPATH={{ fworch_home }}" [Install] WantedBy=multi-user.target diff --git a/roles/middleware/templates/httpd.conf b/roles/middleware/templates/httpd.conf index ea487dedbe..257c4108c6 100644 --- a/roles/middleware/templates/httpd.conf +++ b/roles/middleware/templates/httpd.conf @@ -4,12 +4,23 @@ Timeout {{ apache_mw_timeout }} ProxyPass / http://127.0.0.1:{{ middleware_internal_port }}/ + ProxyPassReverse / http://127.0.0.1:{{ middleware_internal_port }}/ ErrorLog /var/log/{{ webserver_package_name }}/error.log TransferLog /var/log/{{ webserver_package_name }}/access.log CustomLog /var/log/{{ webserver_package_name }}/ssl_request_log "%t %h %{SSL_PROTOCOL}x %{SSL_CIPHER}x \"%r\" %b" + SSLEngine on - SSLCipherSuite RSA:!EXP:!NULL:+HIGH:+MEDIUM:-LOW + {{ apache_ssl_protocol }} + {{ apache_ssl_cipher_suite }} SSLCertificateFile /etc/{{ webserver_package_name }}/ssl/server.crt SSLCertificateKeyFile /etc/{{ webserver_package_name }}/ssl/server.key + + # --- Security Headers --- + +{% for header in apache_security_headers %} + {{ header }} +{% endfor %} + + diff --git a/roles/middleware/templates/ldif_files/tree_roles.ldif.j2 b/roles/middleware/templates/ldif_files/tree_roles.ldif.j2 index a655be2451..a4bf0174b7 100644 --- a/roles/middleware/templates/ldif_files/tree_roles.ldif.j2 +++ b/roles/middleware/templates/ldif_files/tree_roles.ldif.j2 @@ -161,3 +161,14 @@ cn: reviewer uniqueMember: description: T0017 {%- endif %} + + +dn: cn=modeller,ou=role,{{ openldap_path }} +changetype: {{ ldif_changetype }} +{% if ldif_changetype != 'delete' -%} +objectClass: top +objectClass: groupofuniquenames +cn: modeller +uniqueMember: +description: T0018 +{%- endif %} diff --git a/roles/middleware/templates/upgrade/7.2.4.ldif.j2 b/roles/middleware/templates/upgrade/7.2.4.ldif.j2 new file mode 100644 index 0000000000..e171c1dea9 --- /dev/null +++ b/roles/middleware/templates/upgrade/7.2.4.ldif.j2 @@ -0,0 +1,9 @@ + +dn: cn=modeller,ou=role,{{ openldap_path }} +changetype: add +objectClass: top +objectClass: groupofuniquenames +cn: modeller +uniqueMember: +description: T0018 + diff --git a/roles/openldap-server/README.md b/roles/openldap-server/README.md index 5cb5e67a33..b4d101bfd5 100644 --- a/roles/openldap-server/README.md +++ b/roles/openldap-server/README.md @@ -3,6 +3,9 @@ This roles installs the OpenLDAP server on the target machine. It has the option to enable/disable SSL by setting it in defaults or overriding it. +For FWO installer use, Debian-family targets are expected to be Debian >= 12 +or Ubuntu >= 20.04. + ## Requirements This role requires Ansible 1.4 or higher, and platform requirements are listed @@ -21,6 +24,7 @@ openldap_servercountry: US # The self signed ssl certificate openldap_serverstate: Oregon openldap_serverlocation: Portland openldap_serverorganization: IT +openldap_serverservices: ldap://127.0.0.1/ ldaps:/// # Derived from SSL setting ``` ## Example: Configure an OpenLDAP server with SSL @@ -43,6 +47,14 @@ openldap_serverorganization: IT None +## Notes + +- The role writes `SLAPD_SERVICES` to `/etc/default/slapd`. +- The systemd drop-in consumes that value so the listener configuration is + defined in one place. +- When `openldap_server_enable_ssl` is `false`, the role starts `slapd` + without `ldaps:///`. + ## License BSD diff --git a/roles/openldap-server/defaults/main.yml b/roles/openldap-server/defaults/main.yml index 6204b1966e..ec2feea9a3 100644 --- a/roles/openldap-server/defaults/main.yml +++ b/roles/openldap-server/defaults/main.yml @@ -19,9 +19,12 @@ openldap_server_organization: IT openldap_server_email_address: "{{ product_name }}@cactus.de" openldap_server_enable_ssl: true +openldap_server_services: >- + {{ "ldap://" ~ openldap_server ~ "/ ldaps:///" if openldap_server_enable_ssl + else "ldap://" ~ openldap_server ~ "/" }} #The path to the pw dir fworch_secrets_dir: /tmp #The current ansible user -fworch_user: openldap \ No newline at end of file +fworch_user: openldap diff --git a/roles/openldap-server/tasks/main.yml b/roles/openldap-server/tasks/main.yml index d8a7234fd5..3c8b5cc88d 100644 --- a/roles/openldap-server/tasks/main.yml +++ b/roles/openldap-server/tasks/main.yml @@ -1,142 +1,180 @@ --- - name: Create universal ldif directory file: - path: "{{ middleware_ldif_dir }}" - state: directory - owner: "{{ fworch_user }}" - group: "{{ fworch_group }}" - become: true - tags: [ 'test', 'unittest' ] - -- block: -### OS basics - - name: Add the OS specific varibles - include_vars: "{{ ansible_os_family }}.yml" - - - name: Install the openldap and required Packages - package: - name: "{{ item }}" - state: present - loop: "{{ openldap_server_pkgs }}" - -### Clean up slapd.d - - - name: Create the empty configuration directory - file: - path: "{{ openldap_server_app_path }}/slapd.d" - state: "{{ item }}" - with_items: - - absent - - directory - - - name: Create directory for ldap pid - file: - path: "/var/run/slapd" + path: "{{ middleware_ldif_dir }}" state: directory - owner: "{{ openldap_server_user }}" - group: "{{ openldap_server_user }}" - -### Root password - - name: Check if manager password exist - stat: - path: "{{ ldap_manager_pwd_file }}" - register: is_manger_pw_present_flag - - - name: Decide on random manager password - set_fact: - openldap_server_random_rootpw: "{{ randomly_generated_pwd }}" - when: not is_manger_pw_present_flag.stat.exists - - - name: Write random manager password to file - copy: - content: "{{ openldap_server_random_rootpw }}" - dest: "{{ ldap_manager_pwd_file }}" - mode: '0600' owner: "{{ fworch_user }}" group: "{{ fworch_group }}" - when: not is_manger_pw_present_flag.stat.exists - tags: [ 'test' ] - - - name: Generate the root password hash for the config - command: "slappasswd -T {{ ldap_manager_pwd_file }}" - register: root_password - -### TLS - - name: Create ldap certificates - include_role: - name: openssl-cert - vars: - openssl_cert_path: "{{ openldap_server_cert_path }}" - openssl_user: "{{ openldap_server_user }}" - openssl_private_key: "{{ openldap_server_private_key }}" - openssl_csr: "{{ openldap_server_csr }}" - openssl_country: "{{ openldap_server_country }}" - openssl_state: "{{ openldap_server_state }}" - openssl_location: "{{ openldap_server_location }}" - openssl_organization: "{{ openldap_server_organization }}" - openssl_email_address: "{{ openldap_server_email_address }}" - openssl_cert: "{{ openldap_server_cert }}" - -### Config files - - name: Create the directory for ldap database - file: - path: "/var/lib/ldap/{{ openldap_server_domain_name }}/" - state: directory - owner: "{{ openldap_server_user }}" - group: "{{ openldap_server_user }}" - - - name: Create the DB_CONFIG file - copy: - src: DB_CONFIG - dest: /var/lib/ldap/{{ openldap_server_domain_name }}/DB_CONFIG - owner: "{{ openldap_server_user }}" - group: "{{ openldap_server_user }}" - - - name: Copy the ldap.conf configuration file - template: - src: ldap.conf.j2 - dest: "{{ openldap_server_app_path }}/ldap.conf" - - - name: Copy slapd.d initial file to system if not present - template: - src: config.ldif.j2 - dest: "{{ openldap_server_app_path }}/slapd.d/config.ldif" - force: false - mode: 0640 - - - name: Configure LDAP protocol, URI and port - lineinfile: - path: /etc/default/slapd - regexp: '^SLAPD_SERVICES=' - line: SLAPD_SERVICES="ldap://{{ openldap_server }}/ ldaps:///" - - - name: Initialize ldap config - command: slapadd -F {{ openldap_server_app_path }}/slapd.d -n 0 -l {{ openldap_server_app_path }}/slapd.d/config.ldif - - - name: Change slapd files permissions to openldap - file: - path: "{{ openldap_server_app_path }}/slapd.d" - state: directory - recurse: true - owner: openldap - -### systemctl - - name: Create dir to enable TLS for slapd service - file: - path: /etc/systemd/system/slapd.service.d - recurse: true - - - name: Enable TLS for slapd service - template: - src: override.conf.j2 - dest: /etc/systemd/system/slapd.service.d/override.conf - - - name: Start the slapd service - systemd: - name: slapd - state: restarted - enabled: true - daemon_reload: true + become: true + tags: ["test", "integrationtests"] + +- block: + ### OS basics + - name: Add the OS specific varibles + include_vars: "{{ ansible_os_family }}.yml" + + - name: Install the openldap and required Packages + package: + name: "{{ item }}" + state: present + loop: "{{ openldap_server_pkgs }}" + + ### Clean up slapd.d + + - name: Create the empty configuration directory + file: + path: "{{ openldap_server_app_path }}/slapd.d" + state: "{{ item }}" + with_items: + - absent + - directory + + - name: Create directory for ldap pid + file: + path: "/var/run/slapd" + state: directory + owner: "{{ openldap_server_user }}" + group: "{{ openldap_server_user }}" + + ### Root password + - name: Check if manager password exist + stat: + path: "{{ ldap_manager_pwd_file }}" + register: is_manger_pw_present_flag + + - name: Decide on random manager password + set_fact: + openldap_server_random_rootpw: "{{ randomly_generated_pwd }}" + when: not is_manger_pw_present_flag.stat.exists + + - name: Write random manager password to file + copy: + content: "{{ openldap_server_random_rootpw }}" + dest: "{{ ldap_manager_pwd_file }}" + mode: "0600" + owner: "{{ fworch_user }}" + group: "{{ fworch_group }}" + when: not is_manger_pw_present_flag.stat.exists + tags: ["test"] + + - name: Generate the root password hash for the config + command: "slappasswd -T {{ ldap_manager_pwd_file }}" + register: root_password + + ### TLS + - name: Create ldap certificates + include_role: + name: openssl-cert + vars: + openssl_cert_path: "{{ openldap_server_cert_path }}" + openssl_user: "{{ openldap_server_user }}" + openssl_private_key: "{{ openldap_server_private_key }}" + openssl_csr: "{{ openldap_server_csr }}" + openssl_country: "{{ openldap_server_country }}" + openssl_state: "{{ openldap_server_state }}" + openssl_location: "{{ openldap_server_location }}" + openssl_organization: "{{ openldap_server_organization }}" + openssl_email_address: "{{ openldap_server_email_address }}" + openssl_cert: "{{ openldap_server_cert }}" + + ### Config files + - name: Create the directory for ldap database + file: + path: "/var/lib/ldap/{{ openldap_server_domain_name }}/" + state: directory + owner: "{{ openldap_server_user }}" + group: "{{ openldap_server_user }}" + + - name: Create the DB_CONFIG file + copy: + src: DB_CONFIG + dest: /var/lib/ldap/{{ openldap_server_domain_name }}/DB_CONFIG + owner: "{{ openldap_server_user }}" + group: "{{ openldap_server_user }}" + + - name: Copy slapd.d initial file to system if not present + template: + src: config.ldif.j2 + dest: "{{ openldap_server_app_path }}/slapd.d/config.ldif" + force: false + mode: 0640 + + - name: Configure LDAP protocol, URI and port + lineinfile: + path: /etc/default/slapd + regexp: "^SLAPD_SERVICES=" + line: 'SLAPD_SERVICES="{{ openldap_server_services }}"' + + - name: Initialize ldap config + command: slapadd -F {{ openldap_server_app_path }}/slapd.d -n 0 -l {{ openldap_server_app_path }}/slapd.d/config.ldif + + - name: Change slapd files permissions to openldap + file: + path: "{{ openldap_server_app_path }}/slapd.d" + state: directory + recurse: true + owner: openldap + + ### systemctl + - name: Remove Debian slapd override + file: + path: /etc/systemd/system/slapd.service.d/override.conf + state: absent + when: ansible_facts['distribution'] == "Debian" + + - name: Create dir to enable TLS for slapd service + file: + path: /etc/systemd/system/slapd.service.d + recurse: true + when: ansible_facts['distribution'] != "Debian" + + - name: Enable TLS for slapd service + template: + src: override.conf.j2 + dest: /etc/systemd/system/slapd.service.d/override.conf + when: ansible_facts['distribution'] != "Debian" + + - name: Start the slapd service + block: + - name: Restart and enable slapd + systemd: + name: slapd + state: restarted + enabled: true + daemon_reload: true + rescue: + - name: Read rendered slapd unit + command: systemctl cat slapd + register: slapd_unit + changed_when: false + failed_when: false + + - name: Read slapd systemd status + command: systemctl status slapd --no-pager -l + register: slapd_status + changed_when: false + failed_when: false + + - name: Read slapd journal + command: journalctl -xeu slapd.service --no-pager -n 100 + register: slapd_journal + changed_when: false + failed_when: false + + - name: Validate slapd config with slaptest + command: slaptest -F {{ openldap_server_app_path }}/slapd.d -u + register: slapd_slaptest + changed_when: false + failed_when: false + + - name: Fail with slapd diagnostics + fail: + msg: + - "slapd failed to start" + - "systemctl cat slapd: {{ slapd_unit.stdout | default('') }}" + - "systemctl status slapd: {{ slapd_status.stdout | default('') }}" + - "journalctl -xeu slapd.service: {{ slapd_journal.stdout | default('') }}" + - "slaptest -F {{ openldap_server_app_path }}/slapd.d -u: {{ slapd_slaptest.stdout | default('') }} {{ slapd_slaptest.stderr | default('') }}" become: true when: installation_mode == "new" diff --git a/roles/openldap-server/tasks/upgrade/5.4.1.yml b/roles/openldap-server/tasks/upgrade/5.4.1.yml index f3f4d3fe44..6c4c5c842f 100644 --- a/roles/openldap-server/tasks/upgrade/5.4.1.yml +++ b/roles/openldap-server/tasks/upgrade/5.4.1.yml @@ -5,6 +5,19 @@ force: true become: true +- name: build ldap tls options + set_fact: + ldap_tls_opts: >- + {% if openldap_server_enable_ssl | default(false) -%} + -o TLS_REQCERT=never{% if openldap_server_cert is defined %} -o TLS_CACERT={{ openldap_server_cert }}{% endif %} + {%- endif %} + ldap_cmd_url: >- + {% if openldap_server_enable_ssl | default(false) -%} + ldaps://{{ openldap_server }}:{{ openldap_port | default(636) }} + {%- else -%} + ldap://{{ openldap_server }}:{{ (openldap_port | default(389) | int == 636) | ternary(389, openldap_port | default(389)) }} + {%- endif %} + - name: upgrade olcAccess policy - command: "ldapmodify -H {{ openldap_url }} -D cn=config -y {{ ldap_manager_pwd_file }} -x -f {{ middleware_ldif_dir }}/5.4.1.ldif" + command: "ldapmodify {{ ldap_tls_opts }} -H {{ ldap_cmd_url }} -D cn=config -y {{ ldap_manager_pwd_file }} -x -f {{ middleware_ldif_dir }}/5.4.1.ldif" become: true diff --git a/roles/openldap-server/tasks/upgrade/6.4.9.yml b/roles/openldap-server/tasks/upgrade/6.4.9.yml index 6210c6b270..fd7a39ea86 100644 --- a/roles/openldap-server/tasks/upgrade/6.4.9.yml +++ b/roles/openldap-server/tasks/upgrade/6.4.9.yml @@ -5,7 +5,20 @@ force: true become: true +- name: build ldap tls options + set_fact: + ldap_tls_opts: >- + {% if openldap_server_enable_ssl | default(false) -%} + -o TLS_REQCERT=never{% if openldap_server_cert is defined %} -o TLS_CACERT={{ openldap_server_cert }}{% endif %} + {%- endif %} + ldap_cmd_url: >- + {% if openldap_server_enable_ssl | default(false) -%} + ldaps://{{ openldap_server }}:{{ openldap_port | default(636) }} + {%- else -%} + ldap://{{ openldap_server }}:{{ (openldap_port | default(389) | int == 636) | ternary(389, openldap_port | default(389)) }} + {%- endif %} + - name: upgrade sample group roles - command: "ldapmodify -H {{ openldap_url }} -D {{ openldap_superuser_dn }} -y {{ ldap_manager_pwd_file }} -x -f {{ middleware_ldif_dir }}/6.4.9.ldif -c" + command: "ldapmodify {{ ldap_tls_opts }} -H {{ ldap_cmd_url }} -D {{ openldap_superuser_dn }} -y {{ ldap_manager_pwd_file }} -x -f {{ middleware_ldif_dir }}/6.4.9.ldif -c" become: true ignore_errors: true diff --git a/roles/openldap-server/templates/config.ldif.j2 b/roles/openldap-server/templates/config.ldif.j2 index 2322c8ee10..d09f8351a9 100644 --- a/roles/openldap-server/templates/config.ldif.j2 +++ b/roles/openldap-server/templates/config.ldif.j2 @@ -13,9 +13,9 @@ dn: cn=module{0},cn=config objectClass: olcModuleList cn: module{0} olcModulePath: /usr/lib/ldap -olcModuleLoad: {0}back_mdb.la -olcModuleLoad: {1}memberof.la -olcModuleLoad: {2}refint.la +olcModuleLoad: {0}back_mdb +olcModuleLoad: {1}memberof +olcModuleLoad: {2}refint # internal schema dn: cn=schema,cn=config diff --git a/roles/openldap-server/templates/override.conf.j2 b/roles/openldap-server/templates/override.conf.j2 index 193fc43b01..873f70c9ca 100644 --- a/roles/openldap-server/templates/override.conf.j2 +++ b/roles/openldap-server/templates/override.conf.j2 @@ -1,5 +1,6 @@ [Service] +EnvironmentFile=-/etc/default/slapd ExecStartPre=/bin/mkdir -p /run/slapd -ExecStartPre=/bin/chown openldap:openldap /run/slapd +ExecStartPre=/bin/chown {{ openldap_server_user }}:{{ openldap_server_user }} /run/slapd ExecStart= -ExecStart=/usr/sbin/slapd -u {{ openldap_server_user }} -g {{ openldap_server_user }} -h "ldap://{{ openldap_server }} ldaps:///" +ExecStart=/usr/sbin/slapd -u {{ openldap_server_user }} -g {{ openldap_server_user }} -h "${SLAPD_SERVICES}" diff --git a/roles/podman/tasks/main.yml b/roles/podman/tasks/main.yml new file mode 100644 index 0000000000..2369700ba1 --- /dev/null +++ b/roles/podman/tasks/main.yml @@ -0,0 +1,11 @@ +--- +- name: install Podman runtime + package: + name: podman + state: present + become: true + +- name: warn that docker_network is ignored with Podman host networking + debug: + msg: "Ignoring docker_network={{ docker_network }} because the Hasura container now runs with Podman host networking." + when: docker_network is defined and docker_network | length > 0 diff --git a/roles/sample-auth-data/tasks/auth_sample_data.yml b/roles/sample-auth-data/tasks/auth_sample_data.yml index 5f988befc2..3eef294910 100644 --- a/roles/sample-auth-data/tasks/auth_sample_data.yml +++ b/roles/sample-auth-data/tasks/auth_sample_data.yml @@ -11,14 +11,29 @@ END IF; END $do$ - - name: add devices for tenant tenant1{{ sample_postfix }} + - name: add device mapping for tenant tenant1{{ sample_postfix }} postgresql_query: db: "{{ fworch_db_name }}" query: > - DO $do$ BEGIN + DO $do$ BEGIN IF NOT EXISTS (SELECT * FROM tenant_to_device LEFT JOIN tenant USING (tenant_id) WHERE tenant_name='tenant1{{ sample_postfix }}') THEN INSERT INTO tenant_to_device (tenant_id, device_id) - SELECT tenant_id, (select dev_id FROM device where device.dev_name='fortigate{{ sample_postfix }}') from tenant WHERE tenant.tenant_name='tenant1{{ sample_postfix }}'; + SELECT tenant_id, (select dev_id FROM device where device.dev_name='{{ sample_fortigate_basename }}{{ sample_postfix }}') from tenant WHERE tenant.tenant_name='tenant1{{ sample_postfix }}'; + END IF; + END $do$ + + - name: add management mapping for tenant tenant1{{ sample_postfix }} + postgresql_query: + db: "{{ fworch_db_name }}" + query: > + DO $do$ BEGIN + IF NOT EXISTS (SELECT * FROM tenant_to_management LEFT JOIN tenant USING (tenant_id) WHERE tenant_name='tenant1{{ sample_postfix }}') THEN + INSERT INTO tenant_to_management (tenant_id, management_id, shared) + SELECT + tenant_id, + (select mgm_id FROM management where management.mgm_name='{{ sample_fortigate_basename }}{{ sample_postfix }}'), + TRUE + FROM tenant WHERE tenant.tenant_name='tenant1{{ sample_postfix }}'; END IF; END $do$ @@ -33,7 +48,7 @@ END IF; END $do$ - - name: add devices for tenant tenant2{{ sample_postfix }} + - name: add device mapping for tenant tenant2{{ sample_postfix }} postgresql_query: db: "{{ fworch_db_name }}" query: > @@ -41,30 +56,44 @@ IF NOT EXISTS (SELECT * FROM tenant_to_device LEFT JOIN tenant USING (tenant_id) WHERE tenant_name='tenant2{{ sample_postfix }}') THEN INSERT INTO tenant_to_device (tenant_id, device_id) - SELECT tenant_id, (select dev_id FROM device where device.dev_name='checkpoint{{ sample_postfix }}') from tenant WHERE tenant.tenant_name='tenant2{{ sample_postfix }}'; + SELECT tenant_id, (select dev_id FROM device where device.dev_name='{{ sample_fortigate_basename }}{{ sample_postfix }}') from tenant WHERE tenant.tenant_name='tenant2{{ sample_postfix }}'; END IF; END $do$ when: sample_role_purpose is not match('test') + - name: add management mapping for tenant tenant2{{ sample_postfix }} + postgresql_query: + db: "{{ fworch_db_name }}" + query: > + DO $do$ BEGIN + IF NOT EXISTS (SELECT * FROM tenant_to_management LEFT JOIN tenant USING (tenant_id) WHERE tenant_name='tenant2{{ sample_postfix }}') THEN + INSERT INTO tenant_to_management (tenant_id, management_id, shared) + SELECT + tenant_id, + (select mgm_id FROM management where management.mgm_name='{{ sample_fortigate_basename }}{{ sample_postfix }}'), + FALSE + FROM tenant WHERE tenant.tenant_name='tenant2{{ sample_postfix }}'; + END IF; + END $do$ + - name: insert demo tenant network data postgresql_query: db: "{{ fworch_db_name }}" query: > DO $do$ BEGIN IF EXISTS (SELECT tenant_id FROM tenant WHERE tenant_name='tenant1_demo') THEN - IF NOT EXISTS (SELECT * FROM tenant_network LEFT JOIN tenant USING (tenant_id) WHERE tenant_name='tenant1_demo' and tenant_net_ip='10.222.0.32/27') THEN - insert into tenant_network (tenant_id, tenant_net_ip, tenant_net_comment) - VALUES ((SELECT tenant_id FROM tenant WHERE tenant_name='tenant1_demo'), '10.222.0.32/27', 'demo network for tenant 1') ON CONFLICT DO NOTHING; + IF NOT EXISTS (SELECT * FROM tenant_network LEFT JOIN tenant USING (tenant_id) WHERE tenant_name='tenant1_demo' and tenant_net_ip='10.10.0.0/32' AND tenant_net_ip_end='10.10.255.255/32') THEN + insert into tenant_network (tenant_id, tenant_net_ip, tenant_net_ip_end, tenant_net_comment) + VALUES ((SELECT tenant_id FROM tenant WHERE tenant_name='tenant1{{ sample_postfix }}'), '10.10.0.0/32', '10.10.255.255/32', 'demo network for tenant 1') ON CONFLICT DO NOTHING; END IF; END IF; IF EXISTS (SELECT tenant_id FROM tenant WHERE tenant_name='tenant2_demo') THEN - IF NOT EXISTS (SELECT * FROM tenant_network LEFT JOIN tenant USING (tenant_id) WHERE tenant_name='tenant2_demo' and tenant_net_ip='10.0.0.48/29') THEN - insert into tenant_network (tenant_id, tenant_net_ip, tenant_net_comment) - VALUES ((SELECT tenant_id FROM tenant WHERE tenant_name='tenant2_demo'), '10.0.0.48/29', 'demo network for tenant 2') ON CONFLICT DO NOTHING; + IF NOT EXISTS (SELECT * FROM tenant_network LEFT JOIN tenant USING (tenant_id) WHERE tenant_name='tenant2_demo' and tenant_net_ip='10.0.0.48/32' and tenant_net_ip_end='10.0.0.55/32') THEN + insert into tenant_network (tenant_id, tenant_net_ip, tenant_net_ip_end, tenant_net_comment) + VALUES ((SELECT tenant_id FROM tenant WHERE tenant_name='tenant2{{ sample_postfix }}'), '10.0.0.48/32', '10.0.0.55/32', 'demo network for tenant 2') ON CONFLICT DO NOTHING; END IF; END IF; END $do$ - become: true become_user: postgres diff --git a/roles/sample-auth-data/tasks/main.yml b/roles/sample-auth-data/tasks/main.yml index 08ffa18e53..c29a7301a6 100644 --- a/roles/sample-auth-data/tasks/main.yml +++ b/roles/sample-auth-data/tasks/main.yml @@ -2,15 +2,15 @@ - name: add auth test data to database include_tasks: auth_sample_data.yml - when: installation_mode is not match('upgrade') or sample_role_purpose is match('test') + when: installation_mode is match('new') or sample_role_purpose is match('test') - name: include ldif driven changes import_tasks: modify_ldap_tree.yml - when: installation_mode is not match('upgrade') or sample_role_purpose is match('test') + when: installation_mode is match('new') or sample_role_purpose is match('test') - name: include owner sample data import_tasks: sample_owner_data.yml - when: installation_mode is not match('upgrade') or sample_role_purpose is match('test') + when: installation_mode is match('new') or sample_role_purpose is match('test') - name: restart middleware server in case any changes to ldap_connections were made systemd: diff --git a/roles/sample-auth-data/tasks/modify_ldap_tree.yml b/roles/sample-auth-data/tasks/modify_ldap_tree.yml index 9a2a362d5f..bcdec85989 100644 --- a/roles/sample-auth-data/tasks/modify_ldap_tree.yml +++ b/roles/sample-auth-data/tasks/modify_ldap_tree.yml @@ -7,8 +7,21 @@ - ../templates/tree_*.j2 become: true +- name: build ldap tls options + set_fact: + ldap_tls_opts: >- + {% if openldap_server_enable_ssl | default(false) -%} + -o TLS_REQCERT=never{% if openldap_server_cert is defined %} -o TLS_CACERT={{ openldap_server_cert }}{% endif %} + {%- endif %} + ldap_cmd_url: >- + {% if openldap_server_enable_ssl | default(false) -%} + ldaps://{{ openldap_server }}:{{ openldap_port | default(636) }} + {%- else -%} + ldap://{{ openldap_server }}:{{ (openldap_port | default(389) | int == 636) | ternary(389, openldap_port | default(389)) }} + {%- endif %} + - name: add tree - command: "ldapmodify -H {{ openldap_url }} -D {{ openldap_superuser_dn }} -y {{ ldap_manager_pwd_file }} -x -f {{ middleware_ldif_dir }}/tree_{{ item }}.ldif" + command: "ldapmodify {{ ldap_tls_opts }} -H {{ ldap_cmd_url }} -D {{ openldap_superuser_dn }} -y {{ ldap_manager_pwd_file }} -x -f {{ middleware_ldif_dir }}/tree_{{ item }}.ldif" loop: - sample_tenants - sample_operators @@ -17,7 +30,7 @@ # only add roles and groups when not testing to avoid resudue from tests - name: add tree - command: "ldapmodify -H {{ openldap_url }} -D {{ openldap_superuser_dn }} -y {{ ldap_manager_pwd_file }} -x -f {{ middleware_ldif_dir }}/tree_{{ item }}.ldif" + command: "ldapmodify {{ ldap_tls_opts }} -H {{ ldap_cmd_url }} -D {{ openldap_superuser_dn }} -y {{ ldap_manager_pwd_file }} -x -f {{ middleware_ldif_dir }}/tree_{{ item }}.ldif" loop: - roles_for_sample_operators - groups_for_sample_operators diff --git a/roles/sample-auth-data/tasks/sample_owner_data.yml b/roles/sample-auth-data/tasks/sample_owner_data.yml index 567faecf43..0eebb79566 100644 --- a/roles/sample-auth-data/tasks/sample_owner_data.yml +++ b/roles/sample-auth-data/tasks/sample_owner_data.yml @@ -4,27 +4,41 @@ db: "{{ fworch_db_name }}" query: > DO $do$ BEGIN - INSERT INTO owner (name, dn, group_dn, is_default, tenant_id, recert_interval, app_id_external) - VALUES ('ownerF_demo', 'uid=user1_demo,ou=tenant1_demo,ou=operator,ou=user,dc=fworch,dc=internal', 'cn=ownergroup_F_demo,ou=group,dc=fworch,dc=internal', false, 2, 30, '123') + INSERT INTO owner (name, is_default, tenant_id, recert_interval, app_id_external) + VALUES ('ownerF_demo', false, 2, 30, '123') ON CONFLICT DO NOTHING; - INSERT INTO owner (name, dn, group_dn, is_default, tenant_id, recert_interval, app_id_external) - VALUES ('ownerD_demo', 'uid=user2_demo,ou=tenant2_demo,ou=operator,ou=user,dc=fworch,dc=internal', 'cn=ownergroup_D_demo,ou=group,dc=fworch,dc=internal', false, 3, 30, '234') + INSERT INTO owner (name, is_default, tenant_id, recert_interval, app_id_external) + VALUES ('ownerD_demo', false, 3, 30, '234') ON CONFLICT DO NOTHING; - INSERT INTO owner_network (owner_id, ip) - VALUES ((SELECT id FROM owner WHERE name='ownerF_demo'), '10.222.0.0/27') + INSERT INTO owner_responsible (owner_id, dn, responsible_type) + VALUES ((SELECT id FROM owner WHERE name='ownerF_demo'), 'uid=user1_demo,ou=tenant1_demo,ou=operator,ou=user,dc=fworch,dc=internal', 1) + ON CONFLICT DO NOTHING; + INSERT INTO owner_responsible (owner_id, dn, responsible_type) + VALUES ((SELECT id FROM owner WHERE name='ownerF_demo'), 'cn=ownergroup_F_demo,ou=group,dc=fworch,dc=internal', 2) + ON CONFLICT DO NOTHING; + + INSERT INTO owner_responsible (owner_id, dn, responsible_type) + VALUES ((SELECT id FROM owner WHERE name='ownerD_demo'), 'uid=user2_demo,ou=tenant2_demo,ou=operator,ou=user,dc=fworch,dc=internal', 1) + ON CONFLICT DO NOTHING; + INSERT INTO owner_responsible (owner_id, dn, responsible_type) + VALUES ((SELECT id FROM owner WHERE name='ownerD_demo'), 'cn=ownergroup_D_demo,ou=group,dc=fworch,dc=internal', 2) + ON CONFLICT DO NOTHING; + + INSERT INTO owner_network (owner_id, ip, ip_end) + VALUES ((SELECT id FROM owner WHERE name='ownerF_demo'), '10.222.0.0', '10.222.0.31') ON CONFLICT DO NOTHING; - INSERT INTO owner_network (owner_id, ip) - VALUES ((SELECT id FROM owner WHERE name='ownerD_demo'), '10.222.0.32/27') + INSERT INTO owner_network (owner_id, ip, ip_end) + VALUES ((SELECT id FROM owner WHERE name='ownerD_demo'), '10.222.0.32', '10.222.0.63') ON CONFLICT DO NOTHING; - INSERT INTO owner_network (owner_id, ip) - VALUES ((SELECT id FROM owner WHERE name='ownerF_demo'), '10.0.0.0/27') + INSERT INTO owner_network (owner_id, ip, ip_end) + VALUES ((SELECT id FROM owner WHERE name='ownerF_demo'), '10.0.0.0', '10.0.0.31') ON CONFLICT DO NOTHING; - INSERT INTO owner_network (owner_id, ip) - VALUES ((SELECT id FROM owner WHERE name='ownerD_demo'), '10.0.0.32/27') + INSERT INTO owner_network (owner_id, ip, ip_end) + VALUES ((SELECT id FROM owner WHERE name='ownerD_demo'), '10.0.0.32', '10.0.0.63') ON CONFLICT DO NOTHING; END $do$ diff --git a/roles/sample-auth-data/templates/tree_roles_for_sample_operators.ldif.j2 b/roles/sample-auth-data/templates/tree_roles_for_sample_operators.ldif.j2 index a3eb758d48..29acc66b09 100644 --- a/roles/sample-auth-data/templates/tree_roles_for_sample_operators.ldif.j2 +++ b/roles/sample-auth-data/templates/tree_roles_for_sample_operators.ldif.j2 @@ -21,3 +21,15 @@ dn: cn=recertifier,ou=role,{{ openldap_path }} changetype: modify add: uniquemember uniquemember: cn=ownergroup_D{{ sample_postfix }},ou=group,{{ openldap_path }} + + +dn: cn=modeller,ou=role,{{ openldap_path }} +changetype: modify +add: uniquemember +uniquemember: cn=ownergroup_F{{ sample_postfix }},ou=group,{{ openldap_path }} + + +dn: cn=modeller,ou=role,{{ openldap_path }} +changetype: modify +add: uniquemember +uniquemember: cn=ownergroup_D{{ sample_postfix }},ou=group,{{ openldap_path }} diff --git a/roles/sample-data/files/config_changes/enlarge_rule.py b/roles/sample-data/files/config_changes/enlarge_rule.py deleted file mode 100644 index e60af3f23a..0000000000 --- a/roles/sample-data/files/config_changes/enlarge_rule.py +++ /dev/null @@ -1,129 +0,0 @@ -# Created by alf -# Enlarges rule 60 by a random srcadress in fortigate.cfg - -import random -import string -import fnmatch -import os -import sys -import re - -# Define global variables that may be passed on the command line and their defaults if not -# example$ python3 enlarge_rule.py uid "path" - -input_index = sys.argv[1] if len(sys.argv) >= 2 else 0 -input_index = int(input_index) % 59 -config_path = sys.argv[2] if len(sys.argv) >= 3 else "/home/fworchsample/sample-configs/fortinet_demo/fortigate.cfg" -uid = -1 - -# First step: create functions that build a random ip address and uuid - - -def random_octet(): - return str(random.randrange(0, 255)) - - -def random_ip(): - return random_octet() + '.' + random_octet() + '.' + random_octet() + '.' + random_octet() - - -def random_uuid(): - s = ''.join(random.choices(string.ascii_lowercase + string.digits, k=32)) - return s[:8] + '-' + s[8:12] + '-' + s[12:16] + '-' + s[16:20] + '-' + s[20:] - - -# Second step: extract rule uid using the input_index - -with open(config_path, "r") as fin: - data = fin.readlines() - -rule_area_flag = False -rule_mapping_count = 0 - -for line in data: - if fnmatch.filter([line], 'config firewall policy\n'): - rule_area_flag = True - elif fnmatch.filter([line], ' edit *\n') and rule_area_flag: - uid = int(re.findall(r'\d+', line)[0]) - if rule_mapping_count == input_index: - break - else: - rule_mapping_count = rule_mapping_count + 1 - elif fnmatch.filter([line], 'end\n') and rule_area_flag: - break - - -# Third step: build new network object in "config firewall address" - -ip_address = random_ip() -uuid = random_uuid() -count = 1 -line_to_insert_at = -1 - -for line in data: - if fnmatch.filter([line], 'config firewall address\n'): - line_to_insert_at = count - break - else: - count = count + 1 - -if line_to_insert_at > -1: - data.insert(line_to_insert_at, '# start recognition comment for auto-delete function, ID={}\n'.format(uid)) - data.insert(line_to_insert_at + 1, ' edit "{}"\n'.format(ip_address)) - data.insert(line_to_insert_at + 2, ' set uuid {}\n'.format(uuid)) - data.insert(line_to_insert_at + 3, ' set subnet {} 255.255.255.255\n'.format(ip_address)) - data.insert(line_to_insert_at + 4, ' set comment "Automatically built for test purposes"\n') - data.insert(line_to_insert_at + 5, ' next\n') - data.insert(line_to_insert_at + 6, '# end recognition comment for auto-delete function, ID={}\n'.format(uid)) - -# Fourth step: add new object to source address of rule uid - -rule_area_flag = False -uid_flag = False -delete_unused_network_objects = False -replace_counter = 0 - -for line in data: - if fnmatch.filter([line], 'config firewall policy\n'): - rule_area_flag = True - if fnmatch.filter([line], ' edit {}\n'.format(uid)): - uid_flag = True - if fnmatch.filter([line], ' set srcaddr*') and rule_area_flag and uid_flag: - if fnmatch.filter([line], ' set srcaddr "all"\n'): - data[replace_counter] = ' set srcaddr "{}"\n'.format(ip_address) - else: - data[replace_counter] = line.rstrip() + ' "{}"\n'.format(ip_address) - if len(data[replace_counter]) > 95: - data[replace_counter] = ' set srcaddr "{}"\n'.format(ip_address) - delete_unused_network_objects = True - break - if fnmatch.filter([line], ' next\n'.format(uid)): - uid_flag = False - if fnmatch.filter([line], 'end\n'): - rule_area_flag = False - replace_counter = replace_counter + 1 - -# Last step: write everything back to the config file -# If delete_unused_network_objects is set delete all new objects except for the most recent - -with open(config_path + ".tmp", "w") as fout: - if delete_unused_network_objects: - delete_flag = False - object_count = 0 - for line in data: - last_comment_line_flag = False - if line == '# start recognition comment for auto-delete function, ID={}\n'.format(uid): - delete_flag = True - object_count = object_count + 1 - if line == '# end recognition comment for auto-delete function, ID={}\n'.format(uid): - delete_flag = False - last_comment_line_flag = True - if object_count < 2: - fout.write(line) - elif not (delete_flag or last_comment_line_flag): - fout.write(line) - else: - for line in data: - fout.write(line) - -os.rename(config_path + ".tmp", config_path) diff --git a/roles/sample-data/files/sample-configs/checkpoint_demo/fwauth.NDB b/roles/sample-data/files/sample-configs/checkpoint_demo/fwauth.NDB deleted file mode 100644 index c08307db44..0000000000 Binary files a/roles/sample-data/files/sample-configs/checkpoint_demo/fwauth.NDB and /dev/null differ diff --git a/roles/sample-data/files/sample-configs/checkpoint_demo/objects_5_0.C b/roles/sample-data/files/sample-configs/checkpoint_demo/objects_5_0.C deleted file mode 100644 index 11d3f643d3..0000000000 --- a/roles/sample-data/files/sample-configs/checkpoint_demo/objects_5_0.C +++ /dev/null @@ -1,25894 +0,0 @@ -( - :anyobj (Any - :color (Blue) - ) - :superanyobj ( - : (Any - :color (Blue) - ) - ) - :sofaware_gw_types ( - : (IP40 - :AdminInfo ( - :LastModified ( - :Time ("Sun Jul 21 12:24:13 2002") - :By (CheckPoint) - :From (CheckPoint) - ) - :chkpf_uid ("{1FF5E2C5-43E1-4A1B-9E20-376ACB0BA683}") - :ClassName (sofaware_product_type) - :table (sofaware_gw_types) - :Deleteable (false) - :Renameable (false) - ) - :default_package () - :firmware_type (nokia_ip40) - :type (sofaware_product_type_obj) - ) - : (SBox-200 - :AdminInfo ( - :LastModified ( - :Time ("Sun Jul 21 12:24:13 2002") - :By (CheckPoint) - :From (CheckPoint) - ) - :chkpf_uid ("{3A8F3574-D510-4FA9-8467-1AC488A0CEF0}") - :ClassName (sofaware_product_type) - :table (sofaware_gw_types) - :Deleteable (false) - :Renameable (false) - ) - :default_package () - :firmware_type (generic2_safe@) - :type (sofaware_product_type_obj) - ) - : (SecureBlade300 - :AdminInfo ( - :LastModified ( - :Time ("Sun Jul 21 12:24:27 2002") - :By (CheckPoint) - :From (CheckPoint) - ) - :chkpf_uid ("{D554FE57-BAFB-410B-9708-71BA81052FBA}") - :ClassName (sofaware_product_type) - :table (sofaware_gw_types) - :Deleteable (false) - :Renameable (false) - ) - :default_package () - :firmware_type (generic_safe@) - :type (sofaware_product_type_obj) - ) - : (SBox-100 - :AdminInfo ( - :LastModified ( - :Time ("Sun Jul 21 12:23:49 2002") - :By (CheckPoint) - :From (CheckPoint) - ) - :chkpf_uid ("{EC1B649A-7485-4039-B6FC-56EBA3BE59BC}") - :ClassName (sofaware_product_type) - :table (sofaware_gw_types) - :Deleteable (false) - :Renameable (false) - ) - :default_package () - :firmware_type (generic_safe@) - :type (sofaware_product_type_obj) - ) - : (IP30 - :AdminInfo ( - :LastModified ( - :Time ("Sun Jul 21 12:24:13 2002") - :By (CheckPoint) - :From (CheckPoint) - ) - :chkpf_uid ("{7C65EB3E-CF01-4816-948E-0799A3804FC6}") - :ClassName (sofaware_product_type) - :table (sofaware_gw_types) - :Deleteable (false) - :Renameable (false) - ) - :default_package () - :firmware_type (nokia_ip30) - :type (sofaware_product_type_obj) - ) - : (SecureBlade - :AdminInfo ( - :LastModified ( - :Time ("Sun Jul 21 12:24:27 2002") - :By (CheckPoint) - :From (CheckPoint) - ) - :chkpf_uid ("{F7B25443-282D-4D90-AB96-91A082AEB5B1}") - :ClassName (sofaware_product_type) - :table (sofaware_gw_types) - :Deleteable (false) - :Renameable (false) - ) - :default_package () - :firmware_type (generic_safe@) - :type (sofaware_product_type_obj) - ) - ) - :atlas_gateway_properties ( - : (SW - :AdminInfo ( - :chkpf_uid ("{5E6B7A8C-81F5-4B10-8069-03A85BBF4D21}") - :ClassName (atlas_gateway_property) - :table (atlas_gateway_properties) - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :firmwares () - :versions () - :default_profile (sofaware_gw_default_profile) - :gw_type_displayed_name ("Safe@ ROBO") - :is_default (false) - :profile_type (gw_profile_lsm_sofaware) - :type (atlas_gateway_property) - ) - : (CP - :AdminInfo ( - :chkpf_uid ("{F5DF4B54-2FE4-4BFE-8AF1-D5925E240F5D}") - :ClassName (atlas_gateway_property) - :table (atlas_gateway_properties) - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :firmwares () - :versions ( - : ("NG FP3") - ) - :default_profile () - :gw_type_displayed_name ("Check Point ROBO") - :is_default (true) - :profile_type (gw_profile_cp) - :type (atlas_gateway_property) - ) - ) - :atlas_general_properties ( - : (general - :AdminInfo ( - :chkpf_uid ("{7D2D8989-C348-4126-B551-0AF4222217CD}") - :ClassName (atlas_general_property) - :table (atlas_general_properties) - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :statuses ( - : ( - :AdminInfo ( - :chkpf_uid ("{97AEB36C-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (status_properties) - ) - :is_critical (false) - :status_name (OK) - :status_value (0) - :type (status_properties) - ) - : ( - :AdminInfo ( - :chkpf_uid ("{E10C00B2-B7E7-47F0-9D1D-B6274CDF620D}") - :ClassName (status_properties) - ) - :is_critical (false) - :status_name (Unknown) - :status_value (1) - :type (status_properties) - ) - : ( - :AdminInfo ( - :chkpf_uid ("{36C16215-80C6-4C44-A963-E94263AF46CC}") - :ClassName (status_properties) - ) - :is_critical (false) - :status_name (Untrusted) - :status_value (2) - :type (status_properties) - ) - : ( - :AdminInfo ( - :chkpf_uid ("{030973CA-77D5-4CE6-B907-11E6F8801A23}") - :ClassName (status_properties) - ) - :is_critical (true) - :status_name ("Not Responding") - :status_value (3) - :type (status_properties) - ) - : ( - :AdminInfo ( - :chkpf_uid ("{80FFC1F0-4591-4DC2-AFFC-10162D947179}") - :ClassName (status_properties) - ) - :is_critical (true) - :status_name ("Needs Attention") - :status_value (4) - :type (status_properties) - ) - : ( - :AdminInfo ( - :chkpf_uid ("{1D94C5C9-961E-47C5-81B3-8306D898957B}") - :ClassName (status_properties) - ) - :is_critical (false) - :status_name ("Not Installed") - :status_value (5) - :type (status_properties) - ) - : ( - :AdminInfo ( - :chkpf_uid ("{F30E6621-205D-43DA-BFD7-9BDAC5F2ACDB}") - :ClassName (status_properties) - ) - :is_critical (true) - :status_name ("Not Updated") - :status_value (6) - :type (status_properties) - ) - : ( - :AdminInfo ( - :chkpf_uid ("{3BBD2FB3-F19E-4AB7-859A-E2614E8F5DEE}") - :ClassName (status_properties) - ) - :is_critical (false) - :status_name ("May be out of date") - :status_value (7) - :type (status_properties) - ) - ) - :type (atlas_general_property) - ) - ) - :policies_collections ( - : (Standard - :AdminInfo ( - :chkpf_uid ("{2E49485A-61E2-4F55-A71C-85B9BF5CD9E1}") - :ClassName (policies_collection) - :object_permissions ( - :AdminInfo ( - :chkpf_uid ("{711F7FC2-4ADA-4AE2-AC0B-95421F5A9949}") - :ClassName (object_permissions) - ) - :manage ( - : (ReferenceObject - :Table (globals) - :Name (Any) - ) - ) - :read ( - : (any) - ) - :use ( - : (any) - ) - :write ( - : () - ) - :owner () - ) - :table (policies_collections) - :Wiznum (-1) - :LastModified ( - :Time ("Sun Feb 16 01:21:31 2003") - :By (tim) - :From (STICHLING) - ) - ) - :installable_targets () - :all_internal_modules (true) - :color (black) - :comments () - :default (0) - :type (policies_collection) - ) - : (IsoAAAA-traditional - :AdminInfo ( - :chkpf_uid ("{8EA5AF0F-7640-4BF9-8E5B-577091884205}") - :ClassName (policies_collection) - :table (policies_collections) - :Wiznum (-1) - :LastModified ( - :Time ("Tue Jul 27 19:39:19 2004") - :By (IsoAAAF) - :From (scratchy) - ) - ) - :default (0) - :installable_targets () - :all_internal_modules (true) - :color (black) - :comments () - :type (policies_collection) - ) - : (IsoAAAA_Simplified - :AdminInfo ( - :chkpf_uid ("{26FF70B8-9599-49B4-B6F6-84B7AE0D2EBB}") - :ClassName (policies_collection) - :table (policies_collections) - :Wiznum (-1) - :LastModified ( - :Time ("Sat Nov 20 21:55:27 2004") - :By (tim) - :From (gateway) - ) - ) - :comments () - :default (0) - :installable_targets () - :all_internal_modules (true) - :color (black) - :type (policies_collection) - ) - : (IsoAAAA - :AdminInfo ( - :chkpf_uid ("{462FD47E-BB4B-4DC4-95D6-E25D7E6C1E41}") - :ClassName (policies_collection) - :object_permissions ( - :AdminInfo ( - :chkpf_uid ("{98264DAA-4862-46E3-AE64-BB8A15BB9CCC}") - :ClassName (object_permissions) - ) - :manage ( - : (ReferenceObject - :Table (globals) - :Name (Any) - ) - ) - :read ( - : (any) - ) - :use ( - : (any) - ) - :write ( - : () - ) - :owner () - ) - :table (policies_collections) - :Wiznum (-1) - :LastModified ( - :Time ("Sat Nov 20 21:55:27 2004") - :By (tim) - :From (gateway) - ) - ) - :installable_targets () - :all_internal_modules (true) - :color (black) - :comments () - :default (1) - :type (policies_collection) - ) - ) - :network_objects (network_objects - : (InternalNet - :AdminInfo ( - :LastModified ( - :Time ("Sun May 12 10:37:48 2002") - :By (CheckPoint) - :From (CheckPoint) - ) - :chkpf_uid ("{5E414BEC-4A61-4675-A980-4841A1F5A0BE}") - :ClassName (dynamic_object) - :table (network_objects) - :Deleteable (false) - :Renameable (false) - :name (InternalNet) - ) - :bogus_ip (10.222.0.1) - :color (black) - :comments () - :track (none) - :type (dynamic_net_obj) - ) - : (DMZNet - :AdminInfo ( - :LastModified ( - :Time ("Sun May 12 10:38:03 2002") - :By (CheckPoint) - :From (CheckPoint) - ) - :chkpf_uid ("{8A883654-CDD4-45A8-B079-D4E476A70AD6}") - :ClassName (dynamic_object) - :table (network_objects) - :Deleteable (false) - :Renameable (false) - :name (DMZNet) - ) - :bogus_ip (10.222.0.2) - :color (black) - :comments () - :track (none) - :type (dynamic_net_obj) - ) - : (AuxiliaryNet - :AdminInfo ( - :LastModified ( - :Time ("Thu Jul 11 14:11:54 2002") - :By (CheckPoint) - :From (CheckPoint) - ) - :chkpf_uid ("{CAC127FB-24F5-4079-9404-BE5C00D11393}") - :ClassName (dynamic_object) - :table (network_objects) - :Deleteable (false) - :Renameable (false) - :name (AuxiliaryNet) - ) - :bogus_ip (10.222.0.3) - :color (black) - :comments () - :track (none) - :type (dynamic_net_obj) - ) - : (Low - :AdminInfo ( - :LastModified ( - :Time ("Thu Jul 11 14:11:54 2002") - :By (CheckPoint) - :From (CheckPoint) - ) - :chkpf_uid ("{0F147E90-C23D-432C-9294-DEEFD31A1E56}") - :ClassName (sofaware_profiles_security_level) - :table (network_objects) - :Deleteable (false) - :Renameable (false) - :name (Low) - ) - :color (black) - :comments () - :ipaddr (10.222.0.4) - :level (low) - :type (sofaware_profiles_security_level) - ) - : (Medium - :AdminInfo ( - :LastModified ( - :Time ("Thu Jul 11 14:11:54 2002") - :By (CheckPoint) - :From (CheckPoint) - ) - :chkpf_uid ("{7DF4722A-0B57-4906-8E0C-699EC278B6FA}") - :ClassName (sofaware_profiles_security_level) - :table (network_objects) - :Deleteable (false) - :Renameable (false) - :name (Medium) - ) - :color (black) - :comments () - :ipaddr (10.222.0.5) - :level (med) - :type (sofaware_profiles_security_level) - ) - : (High - :AdminInfo ( - :LastModified ( - :Time ("Thu Jul 11 14:11:54 2002") - :By (CheckPoint) - :From (CheckPoint) - ) - :chkpf_uid ("{C8460A52-CEE1-4A85-BBAA-0097C0401CAE}") - :ClassName (sofaware_profiles_security_level) - :table (network_objects) - :Deleteable (false) - :Renameable (false) - :name (High) - ) - :color (black) - :comments () - :ipaddr (10.222.0.6) - :level (high) - :type (sofaware_profiles_security_level) - ) - : (LocalMachine - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:07 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB36B-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (dynamic_object) - :table (network_objects) - :name (LocalMachine) - :Deleteable (false) - :Renameable (false) - ) - :bogus_ip (10.222.0.7) - :color (black) - :comments ("Check Point Local Machine") - :track (none) - :type (dynamic_net_obj) - ) - : (DAG_range - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:07 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB36C-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (address_range) - :table (network_objects) - :Hidden (true) - :Deleteable (false) - :Renameable (false) - :name (DAG_range) - ) - :edges () - :NAT () - :add_adtr_rule (false) - :color (black) - :comments () - :ipaddr_first (10.222.0.1) - :ipaddr_last (10.222.0.8) - :type (machines_range) - ) - : (wasp - :AdminInfo ( - :chkpf_uid ("{098B2A74-E220-4AE8-A164-340FED79C9D5}") - :ClassName (host_plain) - :table (network_objects) - :Wiznum (-1) - :LastModified ( - :Time ("Sat May 10 18:55:57 2003") - :By (IsoAAAF) - :From (scratchy) - ) - :name (wasp) - ) - :certificates () - :edges () - :interfaces () - :NAT () - :read_community () - :sysContact () - :sysDescr () - :sysLocation () - :sysName () - :write_community () - :SNMP ( - :AdminInfo ( - :chkpf_uid ("{098B2A74-E220-4AE8-A164-340FED79C9D5}") - :ClassName (SNMP) - ) - ) - :VPN () - :add_adtr_rule (false) - :color (blue) - :comments (timeserver) - :cp_products_installed (false) - :enforce_gtp_rate_limit (false) - :firewall (not-installed) - :floodgate (not-installed) - :gtp_rate_limit (2048) - :ipaddr (10.222.0.9) - :operating_system ( - :AdminInfo ( - :chkpf_uid ("{CCB732A7-07A1-43DA-920D-1BE2566CEF93}") - :ClassName (operating_system) - ) - :name () - :sp () - :version () - ) - :type (host) - ) - : (itchy - :AdminInfo ( - :chkpf_uid ("{3B4DF852-5064-4957-B95F-D469C5656467}") - :ClassName (host_plain) - :table (network_objects) - :Wiznum (-1) - :LastModified ( - :Time ("Sat May 10 18:59:46 2003") - :By (IsoAAAF) - :From (scratchy) - ) - :name (itchy) - ) - :certificates () - :edges () - :interfaces () - :NAT () - :read_community () - :sysContact () - :sysDescr () - :sysLocation () - :sysName () - :write_community () - :SNMP ( - :AdminInfo ( - :chkpf_uid ("{3B4DF852-5064-4957-B95F-D469C5656467}") - :ClassName (SNMP) - ) - ) - :VPN () - :add_adtr_rule (false) - :color (gold) - :comments (dns) - :cp_products_installed (false) - :enforce_gtp_rate_limit (false) - :firewall (not-installed) - :floodgate (not-installed) - :gtp_rate_limit (2048) - :ipaddr (10.222.0.10) - :operating_system ( - :AdminInfo ( - :chkpf_uid ("{A69EA138-D19E-4AE9-BBAD-4693DA3C2124}") - :ClassName (operating_system) - ) - :name () - :sp () - :version () - ) - :type (host) - ) - : (mg.IsoAAAA-es.com - :AdminInfo ( - :chkpf_uid ("{E5BF8260-3615-4476-B638-53CA3A24FEF1}") - :ClassName (host_plain) - :table (network_objects) - :Wiznum (-1) - :LastModified ( - :Time ("Sun May 18 16:27:49 2003") - :By (IsoAAAF) - :From (scratchy) - ) - :name (mg.IsoAAAA-es.com) - ) - :certificates () - :edges () - :interfaces () - :NAT () - :read_community () - :sysContact () - :sysDescr () - :sysLocation () - :sysName () - :write_community () - :SNMP ( - :AdminInfo ( - :chkpf_uid ("{E5BF8260-3615-4476-B638-53CA3A24FEF1}") - :ClassName (SNMP) - ) - ) - :VPN () - :add_adtr_rule (false) - :color ("forest green") - :comments (spike) - :cp_products_installed (false) - :enforce_gtp_rate_limit (false) - :firewall (not-installed) - :floodgate (not-installed) - :gtp_rate_limit (2048) - :ipaddr (10.222.0.11) - :operating_system ( - :AdminInfo ( - :chkpf_uid ("{EB6C11C9-CF82-4F05-A5F8-F505D9CB9280}") - :ClassName (operating_system) - ) - :name () - :sp () - :version () - ) - :type (host) - ) - : (heag_off_supper - :AdminInfo ( - :chkpf_uid ("{858E3E67-0517-485F-AA04-97A12BC119C3}") - :ClassName (network) - :table (network_objects) - :Wiznum (-1) - :LastModified ( - :Time ("Tue Jul 15 16:08:08 2003") - :By (stephan) - :From (vaio) - ) - :name (heag_off_supper) - ) - :edges () - :NAT () - :add_adtr_rule (false) - :broadcast (allow) - :color (black) - :comments ("obere Heag Netz H�lfte") - :ipaddr (10.222.0.12) - :location (internal) - :netmask (255.255.255.255) - :operating_system ( - :AdminInfo ( - :chkpf_uid ("{D0BDE3B1-1AF8-45E1-95FB-3E047BB5709D}") - :ClassName (operating_system) - ) - :name () - :sp () - :version () - ) - :type (network) - ) - : (heag_off_upper - :AdminInfo ( - :chkpf_uid ("{A58E3E67-0517-485F-AA04-97A12BC119C3}") - :ClassName (network) - :table (network_objects) - :Wiznum (-1) - :LastModified ( - :Time ("Tue Jul 15 16:08:08 2003") - :By (stephan) - :From (vaio) - ) - :name (heag_off_upper) - ) - :edges () - :NAT () - :add_adtr_rule (false) - :broadcast (allow) - :color (black) - :comments ("obere Heag Netz H�lfte") - :ipaddr (10.222.0.13) - :location (internal) - :netmask (255.255.255.255) - :operating_system ( - :AdminInfo ( - :chkpf_uid ("{D0BDE3B1-1AF8-45E1-95FB-3E047BB5709D}") - :ClassName (operating_system) - ) - :name () - :sp () - :version () - ) - :type (network) - ) - : (thorn - :AdminInfo ( - :chkpf_uid ("{32A2BEEF-3078-4B23-A9D9-5B0BDBDB08C3}") - :ClassName (host_plain) - :table (network_objects) - :Wiznum (-1) - :LastModified ( - :Time ("Tue Jul 15 16:09:30 2003") - :By (stephan) - :From (vaio) - ) - :name (thorn) - ) - :certificates () - :edges () - :interfaces () - :NAT () - :read_community () - :sysContact () - :sysDescr () - :sysLocation () - :sysName () - :write_community () - :SNMP ( - :AdminInfo ( - :chkpf_uid ("{32A2BEEF-3078-4B23-A9D9-5B0BDBDB08C3}") - :ClassName (SNMP) - ) - ) - :VPN () - :add_adtr_rule (false) - :color (black) - :comments (thorn) - :cp_products_installed (false) - :enforce_gtp_rate_limit (false) - :firewall (not-installed) - :floodgate (not-installed) - :gtp_rate_limit (2048) - :ipaddr (10.222.0.14) - :operating_system ( - :AdminInfo ( - :chkpf_uid ("{09C26953-217D-4923-80E8-E13B538C5616}") - :ClassName (operating_system) - ) - :name () - :sp () - :version () - ) - :type (host) - ) - : (IsoAAADray.local - :AdminInfo ( - :chkpf_uid ("{75EDBC62-7EB1-4D37-8295-684903FDA75A}") - :ClassName (host_plain) - :table (network_objects) - :Wiznum (-1) - :LastModified ( - :Time ("Fri Nov 21 12:52:52 2003") - :By (IsoAAAF) - :From (scratchy) - ) - :name (IsoAAADray.local) - ) - :certificates () - :edges () - :interfaces () - :NAT () - :read_community () - :sysContact () - :sysDescr () - :sysLocation () - :sysName () - :write_community () - :SNMP ( - :AdminInfo ( - :chkpf_uid ("{75EDBC62-7EB1-4D37-8295-684903FDA75A}") - :ClassName (SNMP) - ) - ) - :VPN () - :add_adtr_rule (false) - :color (gold) - :comments () - :cp_products_installed (false) - :enforce_gtp_rate_limit (false) - :firewall (not-installed) - :floodgate (not-installed) - :gtp_rate_limit (2048) - :ipaddr (10.222.0.15) - :operating_system ( - :AdminInfo ( - :chkpf_uid ("{EE89D4EB-6706-4A6D-98A9-4EC4604186B7}") - :ClassName (operating_system) - ) - :name () - :sp () - :version () - ) - :type (host) - ) - : (scratchy.local - :AdminInfo ( - :chkpf_uid ("{CFABE50C-C1F6-4FF1-8AC3-3161A3779708}") - :ClassName (host_plain) - :table (network_objects) - :Wiznum (-1) - :LastModified ( - :Time ("Sun Nov 30 19:34:35 2003") - :By (IsoAAAF) - :From (scratchy) - ) - :name (scratchy.local) - ) - :certificates () - :edges () - :interfaces () - :NAT () - :read_community () - :sysContact () - :sysDescr () - :sysLocation () - :sysName () - :write_community () - :SNMP ( - :AdminInfo ( - :chkpf_uid ("{CFABE50C-C1F6-4FF1-8AC3-3161A3779708}") - :ClassName (SNMP) - ) - ) - :VPN () - :add_adtr_rule (false) - :color (gold) - :comments () - :cp_products_installed (false) - :enforce_gtp_rate_limit (false) - :firewall (not-installed) - :floodgate (not-installed) - :gtp_rate_limit (2048) - :ipaddr (10.222.0.16) - :operating_system ( - :AdminInfo ( - :chkpf_uid ("{27703391-81D0-4189-AE45-96F1931504E8}") - :ClassName (operating_system) - ) - :name () - :sp () - :version () - ) - :type (host) - ) - : (wlan-router - :AdminInfo ( - :chkpf_uid ("{426CC3AD-BE7D-45B6-AAAB-22BA0680EE21}") - :ClassName (host_plain) - :table (network_objects) - :Wiznum (-1) - :LastModified ( - :Time ("Fri Dec 5 20:01:42 2003") - :By (IsoAAAF) - :From (scratchy) - ) - :name (wlan-router) - ) - :certificates () - :edges () - :interfaces () - :NAT () - :read_community () - :sysContact () - :sysDescr () - :sysLocation () - :sysName () - :write_community () - :SNMP ( - :AdminInfo ( - :chkpf_uid ("{426CC3AD-BE7D-45B6-AAAB-22BA0680EE21}") - :ClassName (SNMP) - ) - ) - :VPN () - :add_adtr_rule (false) - :color ("deep pink") - :comments () - :cp_products_installed (false) - :enforce_gtp_rate_limit (false) - :firewall (not-installed) - :floodgate (not-installed) - :gtp_rate_limit (2048) - :ipaddr (10.222.0.17) - :operating_system ( - :AdminInfo ( - :chkpf_uid ("{50E99C71-A042-439A-B5ED-B8F5F93BE3CA}") - :ClassName (operating_system) - ) - :name () - :sp () - :version () - ) - :type (host) - ) - : (wlan-sources - :AdminInfo ( - :chkpf_uid ("{7592504D-3B32-4F86-BC38-3F6D9EF8BFA7}") - :ClassName (network_object_group) - :table (network_objects) - :Wiznum (-1) - :LastModified ( - :Time ("Fri Dec 5 21:31:42 2003") - :By (IsoAAAF) - :From (scratchy) - ) - :name (wlan-sources) - ) - : (ReferenceObject - :Name (IsoAAAA-100) - :Table (network_objects) - :Uid ("{BF1C6029-8D5D-4A05-A3AD-4B67E6E7A7AA}") - ) - : (ReferenceObject - :Name (Cactus-Wlan) - :Table (network_objects) - :Uid ("{FFB3BAC5-FD79-4D0B-911A-7413DA524723}") - ) - : (ReferenceObject - :Name (wlan-router) - :Table (network_objects) - :Uid ("{426CC3AD-BE7D-45B6-AAAB-22BA0680EE21}") - ) - :color (black) - :comments () - :member_class (network_object) - :members_query () - :type (group) - ) - : (IsoAAAA-internal-wlan - :AdminInfo ( - :chkpf_uid ("{8A25E764-4E9E-4BAD-A56C-81B80488E392}") - :ClassName (network) - :table (network_objects) - :Wiznum (-1) - :LastModified ( - :Time ("Fri Dec 5 21:40:52 2003") - :By (IsoAAAF) - :From (scratchy) - ) - :name (IsoAAAA-internal-wlan) - ) - :edges () - :NAT () - :add_adtr_rule (false) - :broadcast (allow) - :color (blue) - :comments () - :ipaddr (10.222.0.18) - :location (internal) - :netmask (255.255.255.255) - :operating_system ( - :AdminInfo ( - :chkpf_uid ("{5097D84E-F91D-4A79-BD6A-B6A94CC900B3}") - :ClassName (operating_system) - ) - :name () - :sp () - :version () - ) - :type (network) - ) - : (gateway.local - :AdminInfo ( - :chkpf_uid ("{7ED7EF12-A13E-4303-8A6E-C6CC28755C80}") - :ClassName (host_plain) - :table (network_objects) - :Wiznum (-1) - :LastModified ( - :Time ("Fri Dec 5 23:09:16 2003") - :By (IsoAAAF) - :From (scratchy) - ) - :name (gateway.local) - ) - :certificates () - :edges () - :interfaces () - :NAT () - :read_community () - :sysContact () - :sysDescr () - :sysLocation () - :sysName () - :write_community () - :SNMP ( - :AdminInfo ( - :chkpf_uid ("{7ED7EF12-A13E-4303-8A6E-C6CC28755C80}") - :ClassName (SNMP) - ) - ) - :VPN () - :add_adtr_rule (false) - :color (black) - :comments () - :cp_products_installed (false) - :enforce_gtp_rate_limit (false) - :firewall (not-installed) - :floodgate (not-installed) - :gtp_rate_limit (2048) - :ipaddr (10.222.0.19) - :operating_system ( - :AdminInfo ( - :chkpf_uid ("{40E084FD-FB2F-40AC-AD74-D82956846BDA}") - :ClassName (operating_system) - ) - :name () - :sp () - :version () - ) - :type (host) - ) - : (www.t-online.de - :AdminInfo ( - :chkpf_uid ("{2F2418CB-D1AF-4470-AB97-4D6058666A71}") - :ClassName (host_plain) - :table (network_objects) - :Wiznum (-1) - :LastModified ( - :Time ("Wed Dec 17 21:54:39 2003") - :By (IsoAAAF) - :From (scratchy) - ) - :name (www.t-online.de) - ) - :certificates () - :edges () - :interfaces () - :NAT () - :read_community () - :sysContact () - :sysDescr () - :sysLocation () - :sysName () - :write_community () - :SNMP ( - :AdminInfo ( - :chkpf_uid ("{2F2418CB-D1AF-4470-AB97-4D6058666A71}") - :ClassName (SNMP) - ) - ) - :VPN () - :add_adtr_rule (false) - :color ("deep pink") - :comments () - :cp_products_installed (false) - :enforce_gtp_rate_limit (false) - :firewall (not-installed) - :floodgate (not-installed) - :gtp_rate_limit (2048) - :ipaddr (10.222.0.20) - :operating_system ( - :AdminInfo ( - :chkpf_uid ("{69011F4C-61A3-4695-82C4-25AC0C726615}") - :ClassName (operating_system) - ) - :name () - :sp () - :version () - ) - :type (host) - ) - : (Heag-DSL-ext - :AdminInfo ( - :chkpf_uid ("{27F77C5F-9C50-486D-8003-AA7178B2F6FB}") - :ClassName (host_plain) - :table (network_objects) - :Wiznum (-1) - :LastModified ( - :Time ("Wed Feb 25 19:34:32 2004") - :By (IsoAAAF) - :From (scratchy) - ) - :name (Heag-DSL-ext) - ) - :certificates () - :edges () - :interfaces () - :NAT () - :read_community () - :sysContact () - :sysDescr () - :sysLocation () - :sysName () - :write_community () - :SNMP ( - :AdminInfo ( - :chkpf_uid ("{27F77C5F-9C50-486D-8003-AA7178B2F6FB}") - :ClassName (SNMP) - ) - ) - :VPN () - :add_adtr_rule (false) - :color (gold) - :comments ("external IP of Heag DSL Router") - :cp_products_installed (false) - :enforce_gtp_rate_limit (false) - :firewall (not-installed) - :floodgate (not-installed) - :gtp_rate_limit (2048) - :ipaddr (10.222.0.21) - :operating_system ( - :AdminInfo ( - :chkpf_uid ("{DDDE838A-A815-42D9-AC5D-927510B8148A}") - :ClassName (operating_system) - ) - :name () - :sp () - :version () - ) - :type (host) - ) - : (Cactus-Telefonica - :AdminInfo ( - :chkpf_uid ("{1F2B8DAD-46AD-4E8B-8B94-D7524713EB39}") - :ClassName (network) - :table (network_objects) - :Wiznum (-1) - :LastModified ( - :Time ("Wed Feb 25 19:46:14 2004") - :By (IsoAAAF) - :From (scratchy) - ) - :name (Cactus-Telefonica) - ) - :edges () - :NAT () - :add_adtr_rule (false) - :broadcast (allow) - :color ("forest green") - :comments ("Cactus Official IPs") - :ipaddr (10.222.0.22) - :location (internal) - :netmask (255.255.255.255) - :operating_system ( - :AdminInfo ( - :chkpf_uid ("{4EE2803A-C1AA-4951-B802-D2CF7C587BB9}") - :ClassName (operating_system) - ) - :name () - :sp () - :version () - ) - :type (network) - ) - : (Cactus-Heag - :AdminInfo ( - :chkpf_uid ("{83B5E8DA-0AC8-4B27-9EB4-750F7521EB61}") - :ClassName (network) - :table (network_objects) - :Wiznum (-1) - :LastModified ( - :Time ("Wed Feb 25 19:47:42 2004") - :By (IsoAAAF) - :From (scratchy) - ) - :name (Cactus-Heag) - ) - :edges () - :NAT () - :add_adtr_rule (false) - :broadcast (allow) - :color ("forest green") - :comments ("Cactus Official IPs") - :ipaddr (10.222.0.23) - :location (internal) - :netmask (255.255.255.255) - :operating_system ( - :AdminInfo ( - :chkpf_uid ("{8D0684BB-A091-45F1-90D7-35AC66F6CE2E}") - :ClassName (operating_system) - ) - :name () - :sp () - :version () - ) - :type (network) - ) - : (Cactus-InternetTransfer - :AdminInfo ( - :chkpf_uid ("{408C820D-33A1-4E25-B576-EC826F525DCD}") - :ClassName (network) - :table (network_objects) - :Wiznum (-1) - :LastModified ( - :Time ("Wed Feb 25 20:49:59 2004") - :By (IsoAAAF) - :From (scratchy) - ) - :name (Cactus-InternetTransfer) - ) - :edges () - :NAT () - :add_adtr_rule (false) - :broadcast (allow) - :color (black) - :comments () - :ipaddr (10.222.0.24) - :location (internal) - :netmask (255.255.255.255) - :operating_system ( - :AdminInfo ( - :chkpf_uid ("{019385B1-7834-4C96-A99D-EA1BC5F3B1F3}") - :ClassName (operating_system) - ) - :name () - :sp () - :version () - ) - :type (network) - ) - : (CactusDSL-DHCP - :AdminInfo ( - :chkpf_uid ("{4F363EC1-417F-4F6D-B8DC-21875B3E4AC6}") - :ClassName (address_range) - :table (network_objects) - :Wiznum (-1) - :LastModified ( - :Time ("Wed Feb 25 20:54:55 2004") - :By (IsoAAAF) - :From (scratchy) - ) - :name (CactusDSL-DHCP) - ) - :edges () - :NAT () - :add_adtr_rule (false) - :color (black) - :comments () - :ipaddr_first (10.222.0.25) - :ipaddr_last (10.222.0.26) - :type (machines_range) - ) - : (paybox-10.222.0.27 - :AdminInfo ( - :chkpf_uid ("{2EF7EE27-EB4A-447A-B8FE-8A367BCD19E0}") - :ClassName (network) - :table (network_objects) - :Wiznum (-1) - :object_permissions ( - :AdminInfo ( - :chkpf_uid ("{63E2E2DB-2D24-4B23-9A04-D003371692BE}") - :ClassName (object_permissions) - ) - :manage ( - : (ReferenceObject - :Table (globals) - :Name (Any) - ) - ) - :read ( - : (any) - ) - :use ( - : (any) - ) - :write ( - : () - ) - :owner () - ) - :LastModified ( - :Time ("Sat Feb 15 20:40:34 2003") - :By (tim) - :From (STICHLING) - ) - :name (paybox-10.222.0.27) - ) - :edges () - :NAT () - :add_adtr_rule (false) - :broadcast (allow) - :color (black) - :comments () - :ipaddr (10.222.0.27) - :location (internal) - :netmask (255.255.255.255) - :operating_system ( - :AdminInfo ( - :chkpf_uid ("{D1455603-2D6E-40DE-AACA-B19DA884C309}") - :ClassName (operating_system) - ) - :name () - :sp () - :version () - ) - :type (network) - ) - : (paybox-10.222.0.28 - :AdminInfo ( - :chkpf_uid ("{7BDD2C1E-B632-4342-A7FA-055FB7790AFC}") - :ClassName (network) - :table (network_objects) - :Wiznum (-1) - :object_permissions ( - :AdminInfo ( - :chkpf_uid ("{4C8AAF89-DDF6-4D95-9A6F-76755563FEB7}") - :ClassName (object_permissions) - ) - :manage ( - : (ReferenceObject - :Table (globals) - :Name (Any) - ) - ) - :read ( - : (any) - ) - :use ( - : (any) - ) - :write ( - : () - ) - :owner () - ) - :LastModified ( - :Time ("Sat Feb 15 20:41:12 2003") - :By (tim) - :From (STICHLING) - ) - :name (paybox-10.222.0.28) - ) - :edges () - :NAT () - :add_adtr_rule (false) - :broadcast (allow) - :color (black) - :comments () - :ipaddr (10.222.0.28) - :location (internal) - :netmask (255.255.255.255) - :operating_system ( - :AdminInfo ( - :chkpf_uid ("{79D5131C-B9CF-49FC-BDFF-E57213796A88}") - :ClassName (operating_system) - ) - :name () - :sp () - :version () - ) - :type (network) - ) - : (paybox-10.222.0.29 - :AdminInfo ( - :chkpf_uid ("{30E9FBBC-84F2-4AA5-8E83-3D2FBE17B82B}") - :ClassName (network) - :table (network_objects) - :Wiznum (-1) - :object_permissions ( - :AdminInfo ( - :chkpf_uid ("{3EBAAF92-00D6-41FF-BD92-B00F146CC85A}") - :ClassName (object_permissions) - ) - :manage ( - : (ReferenceObject - :Table (globals) - :Name (Any) - ) - ) - :read ( - : (any) - ) - :use ( - : (any) - ) - :write ( - : () - ) - :owner () - ) - :LastModified ( - :Time ("Sat Feb 15 20:41:50 2003") - :By (tim) - :From (STICHLING) - ) - :name (paybox-10.222.0.29) - ) - :edges () - :NAT () - :add_adtr_rule (false) - :broadcast (allow) - :color (black) - :comments () - :ipaddr (10.222.0.29) - :location (internal) - :netmask (255.255.255.255) - :operating_system ( - :AdminInfo ( - :chkpf_uid ("{8BD04057-F288-44C9-815B-0C6C30BFECD3}") - :ClassName (operating_system) - ) - :name () - :sp () - :version () - ) - :type (network) - ) - : (paybox-10.222.0.30 - :AdminInfo ( - :chkpf_uid ("{A915A86D-0ADD-4FF3-9986-27D96FFB0EAE}") - :ClassName (network) - :table (network_objects) - :Wiznum (-1) - :object_permissions ( - :AdminInfo ( - :chkpf_uid ("{23CB3782-4AD4-44CE-8E17-DA87B28CAA78}") - :ClassName (object_permissions) - ) - :manage ( - : (ReferenceObject - :Table (globals) - :Name (Any) - ) - ) - :read ( - : (any) - ) - :use ( - : (any) - ) - :write ( - : () - ) - :owner () - ) - :LastModified ( - :Time ("Sat Feb 15 20:42:17 2003") - :By (tim) - :From (STICHLING) - ) - :name (paybox-10.222.0.30) - ) - :edges () - :NAT () - :add_adtr_rule (false) - :broadcast (allow) - :color (black) - :comments () - :ipaddr (10.222.0.30) - :location (internal) - :netmask (255.255.255.255) - :operating_system ( - :AdminInfo ( - :chkpf_uid ("{1ADD6F6C-BC1D-4E8C-B82F-71C079A91DAA}") - :ClassName (operating_system) - ) - :name () - :sp () - :version () - ) - :type (network) - ) - : (paybox-10.222.0.31 - :AdminInfo ( - :chkpf_uid ("{40032AA5-60A7-4F1B-AB53-96695880ED25}") - :ClassName (network) - :table (network_objects) - :Wiznum (-1) - :object_permissions ( - :AdminInfo ( - :chkpf_uid ("{4A88E9A8-AAE3-45D1-B703-DAB2DB5582D0}") - :ClassName (object_permissions) - ) - :manage ( - : (ReferenceObject - :Table (globals) - :Name (Any) - ) - ) - :read ( - : (any) - ) - :use ( - : (any) - ) - :write ( - : () - ) - :owner () - ) - :LastModified ( - :Time ("Sat Feb 15 20:42:51 2003") - :By (tim) - :From (STICHLING) - ) - :name (paybox-10.222.0.31) - ) - :edges () - :NAT () - :add_adtr_rule (false) - :broadcast (allow) - :color (black) - :comments (gateway) - :ipaddr (10.222.0.31) - :location (internal) - :netmask (255.255.255.255) - :operating_system ( - :AdminInfo ( - :chkpf_uid ("{40D1A5E5-DB0C-457E-AC81-70F174E54B36}") - :ClassName (operating_system) - ) - :name () - :sp () - :version () - ) - :type (network) - ) - : (paybox-alle-netze - :AdminInfo ( - :chkpf_uid ("{17EB75CC-2538-48EF-809F-C5C5D808214A}") - :ClassName (network_object_group) - :table (network_objects) - :Wiznum (-1) - :object_permissions ( - :AdminInfo ( - :chkpf_uid ("{502DBDBD-EE2E-4729-9294-B6A8C75861F3}") - :ClassName (object_permissions) - ) - :manage ( - : (ReferenceObject - :Table (globals) - :Name (Any) - ) - ) - :read ( - : (any) - ) - :use ( - : (any) - ) - :write ( - : () - ) - :owner () - ) - :LastModified ( - :Time ("Sat Feb 15 20:51:53 2003") - :By (tim) - :From (STICHLING) - ) - :name (paybox-alle-netze) - ) - : (ReferenceObject - :Table (network_objects) - :Name (paybox-raunheim) - :Uid ("{0A1725B4-534D-46F1-A8C0-02C3351C8312}") - ) - :color (black) - :comments () - :member_class (network_object) - :members_query () - :type (group) - ) - : (paybox-10.30.0 - :AdminInfo ( - :chkpf_uid ("{D4C16451-2329-4472-A5B7-57B81057B2C8}") - :ClassName (network) - :object_permissions ( - :AdminInfo ( - :chkpf_uid ("{F033472D-1808-46FA-BE3E-611CAD75F23E}") - :ClassName (object_permissions) - ) - :manage ( - : (ReferenceObject - :Table (globals) - :Name (Any) - ) - ) - :read ( - : (any) - ) - :use ( - : (any) - ) - :write ( - : () - ) - :owner () - ) - :table (network_objects) - :Wiznum (-1) - :LastModified ( - :Time ("Sat Feb 22 20:39:16 2003") - :By (IsoAAAF) - :From (scratchy) - ) - :name (paybox-10.30.0) - ) - :edges () - :NAT () - :add_adtr_rule (false) - :broadcast (allow) - :color (black) - :comments () - :ipaddr (10.222.0.32) - :location (internal) - :netmask (255.255.255.255) - :operating_system ( - :AdminInfo ( - :chkpf_uid ("{E3E0DB32-3359-476D-A635-32007BD47E1D}") - :ClassName (operating_system) - ) - :name () - :sp () - :version () - ) - :type (network) - ) - : (paybox-frankfurt - :AdminInfo ( - :chkpf_uid ("{463C45CA-0C86-42DC-9B02-E83E28764370}") - :ClassName (network_object_group) - :table (network_objects) - :Wiznum (-1) - :object_permissions ( - :AdminInfo ( - :chkpf_uid ("{80AFD32D-59B8-43A3-A3A7-C3EA05E23367}") - :ClassName (object_permissions) - ) - :manage ( - : (ReferenceObject - :Table (globals) - :Name (Any) - ) - ) - :read ( - : (any) - ) - :use ( - : (any) - ) - :write ( - : () - ) - :owner () - ) - :LastModified ( - :Time ("Sat Feb 22 20:39:52 2003") - :By (IsoAAAF) - :From (scratchy) - ) - :name (paybox-frankfurt) - ) - : (ReferenceObject - :Name (paybox-10.30.0) - :Table (network_objects) - :Uid ("{D4C16451-2329-4472-A5B7-57B81057B2C8}") - ) - : (ReferenceObject - :Name (paybox-213.70.103) - :Table (network_objects) - :Uid ("{C5AE7301-030D-4C4E-9E63-AB4053BEB2AC}") - ) - :color (black) - :comments () - :member_class (network_object) - :members_query () - :type (group) - ) - : (paybox-213.69.149 - :AdminInfo ( - :chkpf_uid ("{E9026D53-F670-4739-B9C3-1AE97B9FBE15}") - :ClassName (network) - :table (network_objects) - :Wiznum (-1) - :object_permissions ( - :AdminInfo ( - :chkpf_uid ("{7B26CCF6-E04E-4B55-95E0-D8C29A5AE5A5}") - :ClassName (object_permissions) - ) - :manage ( - : (ReferenceObject - :Table (globals) - :Name (Any) - ) - ) - :read ( - : (any) - ) - :use ( - : (any) - ) - :write ( - : () - ) - :owner () - ) - :LastModified ( - :Time ("Tue Jul 15 16:27:21 2003") - :By (stephan) - :From (vaio) - ) - :name (paybox-213.69.149) - ) - :edges () - :NAT () - :add_adtr_rule (false) - :broadcast (allow) - :color (black) - :comments ("10.222.0.33/32") - :ipaddr (10.222.0.33) - :location (internal) - :netmask (255.255.255.255) - :operating_system ( - :AdminInfo ( - :chkpf_uid ("{3CBBF669-133A-4808-B3E7-B4C94DBF081C}") - :ClassName (operating_system) - ) - :name () - :sp () - :version () - ) - :type (network) - ) - : (paybox-213.70.103 - :AdminInfo ( - :chkpf_uid ("{C5AE7301-030D-4C4E-9E63-AB4053BEB2AC}") - :ClassName (network) - :table (network_objects) - :Wiznum (-1) - :object_permissions ( - :AdminInfo ( - :chkpf_uid ("{A3E49847-44E5-4C29-A011-B710399F1881}") - :ClassName (object_permissions) - ) - :manage ( - : (ReferenceObject - :Table (globals) - :Name (Any) - ) - ) - :read ( - : (any) - ) - :use ( - : (any) - ) - :write ( - : () - ) - :owner () - ) - :LastModified ( - :Time ("Tue Jul 15 16:27:21 2003") - :By (stephan) - :From (vaio) - ) - :name (paybox-213.70.103) - ) - :edges () - :NAT () - :add_adtr_rule (false) - :broadcast (allow) - :color (black) - :comments ("10.222.0.34/32") - :ipaddr (10.222.0.34) - :location (internal) - :netmask (255.255.255.255) - :operating_system ( - :AdminInfo ( - :chkpf_uid ("{114183D4-4482-4D60-894D-EFD8222BD4E8}") - :ClassName (operating_system) - ) - :name () - :sp () - :version () - ) - :type (network) - ) - : (paybox-raunheim - :AdminInfo ( - :chkpf_uid ("{0A1725B4-534D-46F1-A8C0-02C3351C8312}") - :ClassName (network_object_group) - :object_permissions ( - :AdminInfo ( - :chkpf_uid ("{94774A3C-1D92-412B-A220-6AAB0D9EEF51}") - :ClassName (object_permissions) - ) - :manage ( - : (ReferenceObject - :Table (globals) - :Name (Any) - ) - ) - :read ( - : (any) - ) - :use ( - : (any) - ) - :write ( - : () - ) - :owner () - ) - :table (network_objects) - :Wiznum (-1) - :LastModified ( - :Time ("Mon Jul 21 19:28:32 2003") - :By (IsoAAAF) - :From (scratchy) - ) - :name (paybox-raunheim) - ) - : (ReferenceObject - :Name (paybox-10.222.0.27) - :Table (network_objects) - :Uid ("{2EF7EE27-EB4A-447A-B8FE-8A367BCD19E0}") - ) - : (ReferenceObject - :Name (paybox-10.222.0.28) - :Table (network_objects) - :Uid ("{7BDD2C1E-B632-4342-A7FA-055FB7790AFC}") - ) - : (ReferenceObject - :Name (paybox-10.222.0.29) - :Table (network_objects) - :Uid ("{30E9FBBC-84F2-4AA5-8E83-3D2FBE17B82B}") - ) - : (ReferenceObject - :Name (paybox-10.222.0.31) - :Table (network_objects) - :Uid ("{40032AA5-60A7-4F1B-AB53-96695880ED25}") - ) - : (ReferenceObject - :Name (paybox-10.222.0.30) - :Table (network_objects) - :Uid ("{A915A86D-0ADD-4FF3-9986-27D96FFB0EAE}") - ) - : (ReferenceObject - :Name (paybox-213.70.103) - :Table (network_objects) - :Uid ("{C5AE7301-030D-4C4E-9E63-AB4053BEB2AC}") - ) - :color (black) - :comments () - :member_class (network_object) - :members_query () - :type (group) - ) - : (IsoAAAD_eth1 - :AdminInfo ( - :chkpf_uid ("{932BDE10-E9C1-4DD6-AB1D-11D57CE91F00}") - :ClassName (network_object_group) - :table (network_objects) - :Wiznum (-1) - :LastModified ( - :Time ("Thu Apr 1 17:11:35 2004") - :By (holger) - :From (dragonfly) - ) - :name (IsoAAAD_eth1) - ) - : (ReferenceObject - :Name (IsoAAAA-100) - :Table (network_objects) - :Uid ("{BF1C6029-8D5D-4A05-A3AD-4B67E6E7A7AA}") - ) - : (ReferenceObject - :Name (t-online) - :Table (network_objects) - :Uid ("{C3D65C4B-6498-4E00-9BAF-15539231E8EE}") - ) - :color (Foreground) - :comments () - :member_class (network_object) - :members_query () - :type (group) - ) - : (IsoAAAA-100 - :AdminInfo ( - :chkpf_uid ("{BF1C6029-8D5D-4A05-A3AD-4B67E6E7A7AA}") - :ClassName (network) - :object_permissions ( - :AdminInfo ( - :chkpf_uid ("{0461DB3A-AC66-4603-9264-9646289CDFF0}") - :ClassName (object_permissions) - ) - :manage ( - : (ReferenceObject - :Table (globals) - :Name (Any) - ) - ) - :read ( - : (any) - ) - :use ( - : (any) - ) - :write ( - : () - ) - :owner () - ) - :table (network_objects) - :Wiznum (-1) - :LastModified ( - :Time ("Thu May 6 12:15:56 2004") - :By (andre) - :From (gateway) - ) - :name (IsoAAAA-100) - ) - :edges () - :NAT () - :add_adtr_rule (false) - :broadcast (disallow) - :color (black) - :comments () - :ipaddr (10.222.0.35) - :location (internal) - :netmask (255.255.255.255) - :operating_system ( - :AdminInfo ( - :chkpf_uid ("{392661F1-45BC-4F78-AD42-B6A199EFB38D}") - :ClassName (operating_system) - ) - :name () - :sp () - :version () - ) - :type (network) - ) - : (daba - :AdminInfo ( - :chkpf_uid ("{94817CDB-EA8C-4213-B38D-F4417EA620C6}") - :ClassName (host_plain) - :table (network_objects) - :Wiznum (-1) - :LastModified ( - :Time ("Sun Aug 1 12:48:13 2004") - :By (tim) - :From (pieks) - ) - :name (daba) - ) - :read_community () - :sysContact () - :sysDescr () - :sysLocation () - :sysName () - :write_community () - :add_adtr_rule (false) - :certificates () - :edges () - :enforce_gtp_rate_limit (false) - :gtp_rate_limit (2048) - :interfaces () - :operating_system ( - :AdminInfo ( - :chkpf_uid ("{87E22239-B653-4FFC-AEBF-05E54A5FAC2B}") - :ClassName (operating_system) - ) - :name () - :sp () - :version () - ) - :NAT () - :SNMP () - :VPN () - :additional_products () - :color (black) - :comments ("database server") - :cp_products_installed (false) - :firewall (not-installed) - :floodgate (not-installed) - :ipaddr (10.222.0.36) - :type (host) - ) - : (allNet - :AdminInfo ( - :chkpf_uid ("{8C20ECB8-A6DB-4C35-B79A-D12ECE559C77}") - :ClassName (address_range) - :table (network_objects) - :Wiznum (-1) - :LastModified ( - :Time ("Tue Aug 17 21:33:42 2004") - :By (IsoAAAF) - :From (IsoAAADray) - ) - :name (allNet) - ) - :add_adtr_rule (false) - :edges () - :NAT () - :color (black) - :comments (everything) - :ipaddr_first (0.0.0.0) - :ipaddr_last (255.255.255.255) - :type (machines_range) - ) - : (IsoAAAA_home_stephan - :AdminInfo ( - :chkpf_uid ("{B86B46D5-DCB5-4A25-A0B6-766D78D30780}") - :ClassName (network) - :table (network_objects) - :Wiznum (-1) - :LastModified ( - :Time ("Thu Sep 16 16:38:51 2004") - :By (stephan) - :From (gateway) - ) - :name (IsoAAAA_home_stephan) - ) - :add_adtr_rule (false) - :edges () - :location (internal) - :operating_system ( - :AdminInfo ( - :chkpf_uid ("{F1BDDF41-0018-425A-BC22-16B4152381BF}") - :ClassName (operating_system) - ) - :name () - :sp () - :version () - ) - :NAT () - :broadcast (allow) - :color (black) - :comments ("Stephan's Netze") - :ipaddr (10.222.0.37) - :netmask (255.255.255.255) - :type (network) - ) - : (IsoAAAA_home_tim - :AdminInfo ( - :chkpf_uid ("{BF8F69B9-87C2-464A-9404-239AE8DF66B3}") - :ClassName (network) - :table (network_objects) - :Wiznum (-1) - :LastModified ( - :Time ("Thu Sep 16 16:39:22 2004") - :By (stephan) - :From (gateway) - ) - :name (IsoAAAA_home_tim) - ) - :edges () - :NAT () - :add_adtr_rule (false) - :broadcast (allow) - :color (green) - :comments ("10.222.0.38/32") - :ipaddr (10.222.0.38) - :location (internal) - :netmask (255.255.255.255) - :operating_system ( - :AdminInfo ( - :chkpf_uid ("{E9B5F7A4-CC68-41C2-BE23-DF0A2D54E0D7}") - :ClassName (operating_system) - ) - :name () - :sp () - :version () - ) - :type (network) - ) - : (Cactus_home_test_2 - :AdminInfo ( - :chkpf_uid ("{3CB93962-2930-41A7-8067-FC373151BB91}") - :ClassName (host_plain) - :table (network_objects) - :Wiznum (-1) - :LastModified ( - :Time ("Wed Sep 22 13:27:12 2004") - :By (stephan) - :From (gateway) - ) - :name (Cactus_home_test_2) - ) - :read_community () - :sysContact () - :sysDescr () - :sysLocation () - :sysName () - :write_community () - :add_adtr_rule (false) - :certificates () - :edges () - :enforce_gtp_rate_limit (false) - :gtp_rate_limit (2048) - :interfaces () - :operating_system ( - :AdminInfo ( - :chkpf_uid ("{90366C6B-50ED-4AD3-AB1E-73DDD97F0C32}") - :ClassName (operating_system) - ) - :name () - :sp () - :version () - ) - :NAT () - :SNMP () - :VPN () - :additional_products () - :color (black) - :comments ("nat, war frei f�r test") - :cp_products_installed (false) - :firewall (not-installed) - :floodgate (not-installed) - :ipaddr (10.222.0.39) - :type (host) - ) - : (IsoAAAA_home_test_3 - :AdminInfo ( - :chkpf_uid ("{3B37A3DE-4411-4FFC-9E54-3ABC5C4F693B}") - :ClassName (host_plain) - :table (network_objects) - :Wiznum (-1) - :LastModified ( - :Time ("Wed Sep 22 13:29:00 2004") - :By (stephan) - :From (gateway) - ) - :name (IsoAAAA_home_test_3) - ) - :read_community () - :sysContact () - :sysDescr () - :sysLocation () - :sysName () - :write_community () - :add_adtr_rule (false) - :certificates () - :edges () - :enforce_gtp_rate_limit (false) - :gtp_rate_limit (2048) - :interfaces () - :operating_system ( - :AdminInfo ( - :chkpf_uid ("{615B2573-914D-483E-94BF-88142A4E938D}") - :ClassName (operating_system) - ) - :name () - :sp () - :version () - ) - :NAT () - :SNMP () - :VPN () - :additional_products () - :color (black) - :comments (orig_source) - :cp_products_installed (false) - :firewall (not-installed) - :floodgate (not-installed) - :ipaddr (10.222.0.40) - :type (host) - ) - : (hpux - :AdminInfo ( - :chkpf_uid ("{BF00A847-A0D6-4A75-BE1C-27E7D91EDB55}") - :ClassName (host_plain) - :table (network_objects) - :Wiznum (-1) - :LastModified ( - :Time ("Mon Sep 27 07:52:27 2004") - :By (tim) - :From (pieks) - ) - :name (hpux) - ) - :read_community () - :sysContact () - :sysDescr () - :sysLocation () - :sysName () - :write_community () - :add_adtr_rule (false) - :certificates () - :edges () - :enforce_gtp_rate_limit (false) - :gtp_rate_limit (2048) - :interfaces () - :operating_system ( - :AdminInfo ( - :chkpf_uid ("{2607915D-F3D5-43F8-B6C3-599AA00195B3}") - :ClassName (operating_system) - ) - :name () - :sp () - :version () - ) - :NAT () - :SNMP () - :VPN () - :additional_products () - :color (black) - :comments ("hp-ux-test for hardening") - :cp_products_installed (false) - :firewall (not-installed) - :floodgate (not-installed) - :ipaddr (10.222.0.41) - :type (host) - ) - : (Cactus-Official - :AdminInfo ( - :chkpf_uid ("{2136B4E8-3ABF-4931-BDB9-12CDF457D4A4}") - :ClassName (network_object_group) - :table (network_objects) - :Wiznum (-1) - :LastModified ( - :Time ("Wed Sep 29 20:26:37 2004") - :By (IsoAAAF) - :From (IsoAAADray) - ) - :name (Cactus-Official) - ) - :members_query () - : (ReferenceObject - :Name (Cactus-Heag) - :Table (network_objects) - :Uid ("{83B5E8DA-0AC8-4B27-9EB4-750F7521EB61}") - ) - : (ReferenceObject - :Name (Cactus-Telefonica) - :Table (network_objects) - :Uid ("{1F2B8DAD-46AD-4E8B-8B94-D7524713EB39}") - ) - :color (black) - :comments () - :member_class (network_object) - :type (group) - ) - : (IsoAAAD_extern - :AdminInfo ( - :chkpf_uid ("{DB456CE7-0DCA-423F-A5E4-9FA976C0B594}") - :ClassName (host_plain) - :table (network_objects) - :Wiznum (-1) - :LastModified ( - :Time ("Wed Sep 29 20:28:11 2004") - :By (IsoAAAF) - :From (IsoAAADray) - ) - :name (IsoAAAD_extern) - ) - :read_community () - :sysContact () - :sysDescr () - :sysLocation () - :sysName () - :write_community () - :add_adtr_rule (false) - :certificates () - :edges () - :enforce_gtp_rate_limit (false) - :gtp_rate_limit (2048) - :interfaces () - :operating_system ( - :AdminInfo ( - :chkpf_uid ("{E10D68CF-49A0-49E2-BD41-F3501F9AC613}") - :ClassName (operating_system) - ) - :name () - :sp () - :version () - ) - :NAT () - :SNMP () - :VPN () - :additional_products () - :color (green) - :comments () - :cp_products_installed (false) - :firewall (not-installed) - :floodgate (not-installed) - :ipaddr (10.222.0.42) - :type (host) - ) - : (Cactus-DMZ1 - :AdminInfo ( - :chkpf_uid ("{62523F8E-9AE0-4CC0-82C6-BB41846BA2B7}") - :ClassName (network) - :table (network_objects) - :Wiznum (-1) - :LastModified ( - :Time ("Wed Sep 29 20:30:05 2004") - :By (IsoAAAF) - :From (IsoAAADray) - ) - :name (Cactus-DMZ1) - ) - :add_adtr_rule (false) - :edges () - :location (internal) - :operating_system ( - :AdminInfo ( - :chkpf_uid ("{A36075C6-6E18-44CD-AA68-156B28425E7C}") - :ClassName (operating_system) - ) - :name () - :sp () - :version () - ) - :NAT () - :broadcast (allow) - :color ("forest green") - :comments ("10.222.0.22/32") - :ipaddr (10.222.0.22) - :netmask (255.255.255.255) - :type (network) - ) - : (Cactus-DMZ2 - :AdminInfo ( - :chkpf_uid ("{61AB70E0-5514-43CF-9194-B37A13EC102D}") - :ClassName (network) - :table (network_objects) - :Wiznum (-1) - :LastModified ( - :Time ("Wed Sep 29 20:30:56 2004") - :By (IsoAAAF) - :From (IsoAAADray) - ) - :name (Cactus-DMZ2) - ) - :add_adtr_rule (false) - :edges () - :location (internal) - :operating_system ( - :AdminInfo ( - :chkpf_uid ("{9560D37A-C58D-4BED-9BA7-012AFD867887}") - :ClassName (operating_system) - ) - :name () - :sp () - :version () - ) - :NAT () - :broadcast (allow) - :color ("forest green") - :comments ("10.222.0.43/32") - :ipaddr (10.222.0.43) - :netmask (255.255.255.255) - :type (network) - ) - : (Cactus-DMZ3 - :AdminInfo ( - :chkpf_uid ("{DE80C48A-20E5-4396-BBA2-9E0AE9B95383}") - :ClassName (network) - :table (network_objects) - :Wiznum (-1) - :LastModified ( - :Time ("Wed Sep 29 20:32:05 2004") - :By (IsoAAAF) - :From (IsoAAADray) - ) - :name (Cactus-DMZ3) - ) - :add_adtr_rule (false) - :edges () - :location (internal) - :operating_system ( - :AdminInfo ( - :chkpf_uid ("{C6B94E29-F2A7-44C9-B730-F5B6757F6C63}") - :ClassName (operating_system) - ) - :name () - :sp () - :version () - ) - :NAT () - :broadcast (allow) - :color ("forest green") - :comments ("10.222.0.23/32") - :ipaddr (10.222.0.23) - :netmask (255.255.255.255) - :type (network) - ) - : (speedy2 - :AdminInfo ( - :chkpf_uid ("{B4DB2EF5-42D8-41DC-9A1C-33310FDFB184}") - :ClassName (host_plain) - :table (network_objects) - :Wiznum (-1) - :LastModified ( - :Time ("Wed Sep 29 20:39:12 2004") - :By (IsoAAAF) - :From (IsoAAADray) - ) - :name (speedy2) - ) - :read_community () - :sysContact () - :sysDescr () - :sysLocation () - :sysName () - :write_community () - :add_adtr_rule (false) - :certificates () - :edges () - :enforce_gtp_rate_limit (false) - :gtp_rate_limit (2048) - :interfaces () - :operating_system ( - :AdminInfo ( - :chkpf_uid ("{57F30020-0328-467D-8FBE-0B565E807D9F}") - :ClassName (operating_system) - ) - :name () - :sp () - :version () - ) - :NAT () - :SNMP () - :VPN () - :additional_products () - :color (orange) - :comments ("Silkes Rechner") - :cp_products_installed (false) - :firewall (not-installed) - :floodgate (not-installed) - :ipaddr (10.222.0.44) - :type (host) - ) - : (www.t-update.de - :AdminInfo ( - :chkpf_uid ("{8F3990BA-9B98-4260-888D-100CA19D688F}") - :ClassName (host_plain) - :table (network_objects) - :Wiznum (-1) - :LastModified ( - :Time ("Wed Sep 29 21:19:50 2004") - :By (IsoAAAF) - :From (scratchy) - ) - :name (www.t-update.de) - ) - :read_community () - :sysContact () - :sysDescr () - :sysLocation () - :sysName () - :write_community () - :add_adtr_rule (false) - :certificates () - :edges () - :enforce_gtp_rate_limit (false) - :gtp_rate_limit (2048) - :interfaces () - :operating_system ( - :AdminInfo ( - :chkpf_uid ("{47B256C1-6339-44A4-A5B3-814C177025F1}") - :ClassName (operating_system) - ) - :name () - :sp () - :version () - ) - :NAT () - :SNMP () - :VPN () - :additional_products () - :color ("deep pink") - :comments () - :cp_products_installed (false) - :firewall (not-installed) - :floodgate (not-installed) - :ipaddr (10.222.0.45) - :type (host) - ) - : (www1.sda.t-online.de - :AdminInfo ( - :chkpf_uid ("{01ADF4A6-6639-4CD9-9336-A3D2CC0182B9}") - :ClassName (host_plain) - :table (network_objects) - :Wiznum (-1) - :LastModified ( - :Time ("Wed Sep 29 21:22:15 2004") - :By (IsoAAAF) - :From (scratchy) - ) - :name (www1.sda.t-online.de) - ) - :read_community () - :sysContact () - :sysDescr () - :sysLocation () - :sysName () - :write_community () - :add_adtr_rule (false) - :certificates () - :edges () - :enforce_gtp_rate_limit (false) - :gtp_rate_limit (2048) - :interfaces () - :operating_system ( - :AdminInfo ( - :chkpf_uid ("{738A5B60-ADE1-4631-8861-E4DB4453DD30}") - :ClassName (operating_system) - ) - :name () - :sp () - :version () - ) - :NAT () - :SNMP () - :VPN () - :additional_products () - :color ("deep pink") - :comments () - :cp_products_installed (false) - :firewall (not-installed) - :floodgate (not-installed) - :ipaddr (10.222.0.46) - :type (host) - ) - : (update2.t-online - :AdminInfo ( - :chkpf_uid ("{DFBF3C44-7C42-4FA0-A73F-2DA57B106127}") - :ClassName (host_plain) - :table (network_objects) - :Wiznum (-1) - :LastModified ( - :Time ("Wed Sep 29 21:24:02 2004") - :By (IsoAAAF) - :From (scratchy) - ) - :name (update2.t-online) - ) - :read_community () - :sysContact () - :sysDescr () - :sysLocation () - :sysName () - :write_community () - :add_adtr_rule (false) - :certificates () - :edges () - :enforce_gtp_rate_limit (false) - :gtp_rate_limit (2048) - :interfaces () - :operating_system ( - :AdminInfo ( - :chkpf_uid ("{F377E73F-A48F-4286-9305-E505B1C4B79F}") - :ClassName (operating_system) - ) - :name () - :sp () - :version () - ) - :NAT () - :SNMP () - :VPN () - :additional_products () - :color ("deep pink") - :comments () - :cp_products_installed (false) - :firewall (not-installed) - :floodgate (not-installed) - :ipaddr (10.222.0.47) - :type (host) - ) - : (t-onlineUpdate - :AdminInfo ( - :chkpf_uid ("{99089D97-0EB3-4CE6-8C78-79BC61ECE307}") - :ClassName (network_object_group) - :table (network_objects) - :Wiznum (-1) - :LastModified ( - :Time ("Wed Sep 29 21:25:01 2004") - :By (IsoAAAF) - :From (scratchy) - ) - :name (t-onlineUpdate) - ) - :members_query () - : (ReferenceObject - :Name (update2.t-online) - :Table (network_objects) - :Uid ("{DFBF3C44-7C42-4FA0-A73F-2DA57B106127}") - ) - : (ReferenceObject - :Name (www.t-update.de) - :Table (network_objects) - :Uid ("{8F3990BA-9B98-4260-888D-100CA19D688F}") - ) - : (ReferenceObject - :Name (www1.sda.t-online.de) - :Table (network_objects) - :Uid ("{01ADF4A6-6639-4CD9-9336-A3D2CC0182B9}") - ) - :color ("deep pink") - :comments () - :member_class (network_object) - :type (group) - ) - : (auth1.lhsystems.com - :AdminInfo ( - :chkpf_uid ("{D60E902E-4BE8-43E0-95DC-BFE60E86965F}") - :ClassName (host_plain) - :table (network_objects) - :Wiznum (-1) - :LastModified ( - :Time ("Thu Sep 30 07:20:12 2004") - :By (IsoAAAF) - :From (scratchy) - ) - :name (auth1.lhsystems.com) - ) - :read_community () - :sysContact () - :sysDescr () - :sysLocation () - :sysName () - :write_community () - :add_adtr_rule (false) - :certificates () - :edges () - :enforce_gtp_rate_limit (false) - :gtp_rate_limit (2048) - :interfaces () - :operating_system ( - :AdminInfo ( - :chkpf_uid ("{5296EABE-CD28-417D-B3F6-26D44B7A6929}") - :ClassName (operating_system) - ) - :name () - :sp () - :version () - ) - :NAT () - :SNMP () - :VPN () - :additional_products () - :color (firebrick) - :comments () - :cp_products_installed (false) - :firewall (not-installed) - :floodgate (not-installed) - :ipaddr (10.222.0.48) - :type (host) - ) - : (LSYI-pptp - :AdminInfo ( - :chkpf_uid ("{DF2F1A45-9938-4006-A550-0421F3DAA3E2}") - :ClassName (network) - :table (network_objects) - :Wiznum (-1) - :LastModified ( - :Time ("Thu Sep 30 07:22:17 2004") - :By (IsoAAAF) - :From (scratchy) - ) - :name (LSYI-pptp) - ) - :add_adtr_rule (false) - :edges () - :location (internal) - :operating_system ( - :AdminInfo ( - :chkpf_uid ("{808DE519-4384-40CA-A3B4-1C12A22D03A9}") - :ClassName (operating_system) - ) - :name () - :sp () - :version () - ) - :NAT () - :broadcast (allow) - :color (gold) - :comments ("10.222.0.49/32") - :ipaddr (10.222.0.49) - :netmask (255.255.255.255) - :type (network) - ) - : (IP-255 - :AdminInfo ( - :chkpf_uid ("{589C570C-0905-4946-9736-9BD05B95FBF6}") - :ClassName (host_plain) - :table (network_objects) - :Wiznum (-1) - :LastModified ( - :Time ("Thu Sep 30 07:29:36 2004") - :By (IsoAAAF) - :From (scratchy) - ) - :name (IP-255) - ) - :read_community () - :sysContact () - :sysDescr () - :sysLocation () - :sysName () - :write_community () - :add_adtr_rule (false) - :certificates () - :edges () - :enforce_gtp_rate_limit (false) - :gtp_rate_limit (2048) - :interfaces () - :operating_system ( - :AdminInfo ( - :chkpf_uid ("{554786B0-07BA-4411-BF5C-F110F4CDF47C}") - :ClassName (operating_system) - ) - :name () - :sp () - :version () - ) - :NAT () - :SNMP () - :VPN () - :additional_products () - :color (black) - :comments () - :cp_products_installed (false) - :firewall (not-installed) - :floodgate (not-installed) - :ipaddr (255.255.255.255) - :type (host) - ) - : (Drop_nologDest - :AdminInfo ( - :chkpf_uid ("{79369987-B128-4B3F-827C-3C936F7C3F53}") - :ClassName (network_object_group) - :table (network_objects) - :Wiznum (-1) - :LastModified ( - :Time ("Thu Sep 30 07:29:41 2004") - :By (IsoAAAF) - :From (scratchy) - ) - :name (Drop_nologDest) - ) - :members_query () - : (ReferenceObject - :Name (IP-255) - :Table (network_objects) - :Uid ("{589C570C-0905-4946-9736-9BD05B95FBF6}") - ) - :color (black) - :comments () - :member_class (network_object) - :type (group) - ) - : (spike.local - :AdminInfo ( - :chkpf_uid ("{4ABDD8DE-0DA2-46E5-B129-85E3977CBD18}") - :ClassName (host_plain) - :table (network_objects) - :Wiznum (-1) - :LastModified ( - :Time ("Thu Sep 30 08:43:06 2004") - :By (IsoAAAF) - :From (scratchy) - ) - :name (spike.local) - ) - :certificates () - :edges () - :interfaces () - :NAT () - :read_community () - :sysContact () - :sysDescr () - :sysLocation () - :sysName () - :write_community () - :SNMP ( - :AdminInfo ( - :chkpf_uid ("{4ABDD8DE-0DA2-46E5-B129-85E3977CBD18}") - :ClassName (SNMP) - ) - ) - :VPN () - :add_adtr_rule (false) - :additional_products () - :color (black) - :comments () - :cp_products_installed (false) - :enforce_gtp_rate_limit (false) - :firewall (not-installed) - :floodgate (not-installed) - :gtp_rate_limit (2048) - :ipaddr (10.222.0.50) - :operating_system ( - :AdminInfo ( - :chkpf_uid ("{80CBD075-13E9-4F84-BCA5-32D480915D3B}") - :ClassName (operating_system) - ) - :name () - :sp () - :version () - ) - :type (host) - ) - : (LSYI-WWA - :AdminInfo ( - :chkpf_uid ("{3ECB1B79-1A26-41A3-90F9-71BE179A7211}") - :ClassName (network_object_group) - :table (network_objects) - :Wiznum (-1) - :LastModified ( - :Time ("Thu Sep 30 10:09:48 2004") - :By (IsoAAAF) - :From (scratchy) - ) - :name (LSYI-WWA) - ) - :members_query () - : (ReferenceObject - :Name (auth1.lhsystems.com) - :Table (network_objects) - :Uid ("{D60E902E-4BE8-43E0-95DC-BFE60E86965F}") - ) - : (ReferenceObject - :Name (LSYI-pptp) - :Table (network_objects) - :Uid ("{DF2F1A45-9938-4006-A550-0421F3DAA3E2}") - ) - :color (gold) - :comments () - :member_class (network_object) - :type (group) - ) - : (mail.hayn.de - :AdminInfo ( - :chkpf_uid ("{741A5834-3EA7-4899-92F4-3B365DDBCD98}") - :ClassName (host_plain) - :table (network_objects) - :Wiznum (-1) - :LastModified ( - :Time ("Thu Sep 30 16:34:01 2004") - :By (IsoAAAF) - :From (IsoAAADray) - ) - :name (mail.hayn.de) - ) - :read_community () - :sysContact () - :sysDescr () - :sysLocation () - :sysName () - :write_community () - :add_adtr_rule (false) - :certificates () - :edges () - :enforce_gtp_rate_limit (false) - :gtp_rate_limit (2048) - :interfaces () - :operating_system ( - :AdminInfo ( - :chkpf_uid ("{2581BB20-10CA-4806-8E36-0020A5BE895B}") - :ClassName (operating_system) - ) - :name () - :sp () - :version () - ) - :NAT () - :SNMP () - :VPN () - :additional_products () - :color (blue) - :comments () - :cp_products_installed (false) - :firewall (not-installed) - :floodgate (not-installed) - :ipaddr (10.222.0.51) - :type (host) - ) - : (mail.purschke.de - :AdminInfo ( - :chkpf_uid ("{8EFADE68-A4E4-4BF3-B2C4-EDBD81769700}") - :ClassName (host_plain) - :table (network_objects) - :Wiznum (-1) - :LastModified ( - :Time ("Thu Sep 30 16:34:18 2004") - :By (IsoAAAF) - :From (IsoAAADray) - ) - :name (mail.purschke.de) - ) - :read_community () - :sysContact () - :sysDescr () - :sysLocation () - :sysName () - :write_community () - :add_adtr_rule (false) - :certificates () - :edges () - :enforce_gtp_rate_limit (false) - :gtp_rate_limit (2048) - :interfaces () - :operating_system ( - :AdminInfo ( - :chkpf_uid ("{A4BD025C-525F-4C40-86BF-A4F93BC60B4C}") - :ClassName (operating_system) - ) - :name () - :sp () - :version () - ) - :NAT () - :SNMP () - :VPN () - :additional_products () - :color (blue) - :comments () - :cp_products_installed (false) - :firewall (not-installed) - :floodgate (not-installed) - :ipaddr (10.222.0.52) - :type (host) - ) - : (mail.IsoAAAA.de - :AdminInfo ( - :chkpf_uid ("{98537EEE-D16C-4C24-940F-6880836A7350}") - :ClassName (host_plain) - :table (network_objects) - :Wiznum (-1) - :LastModified ( - :Time ("Thu Sep 30 16:34:41 2004") - :By (IsoAAAF) - :From (IsoAAADray) - ) - :name (mail.IsoAAAA.de) - ) - :read_community () - :sysContact () - :sysDescr () - :sysLocation () - :sysName () - :write_community () - :add_adtr_rule (false) - :certificates () - :edges () - :enforce_gtp_rate_limit (false) - :gtp_rate_limit (2048) - :interfaces () - :operating_system ( - :AdminInfo ( - :chkpf_uid ("{11B9ACD9-8F60-4611-A33D-D79FFE94455C}") - :ClassName (operating_system) - ) - :name () - :sp () - :version () - ) - :NAT () - :SNMP () - :VPN () - :additional_products () - :color (blue) - :comments () - :cp_products_installed (false) - :firewall (not-installed) - :floodgate (not-installed) - :ipaddr (10.222.0.53) - :type (host) - ) - : (mail.IsoAAAA-es.com - :AdminInfo ( - :chkpf_uid ("{B096EA6A-9B9D-4804-ADF0-E9D196210EDE}") - :ClassName (host_plain) - :table (network_objects) - :Wiznum (-1) - :LastModified ( - :Time ("Thu Sep 30 16:35:03 2004") - :By (IsoAAAF) - :From (IsoAAADray) - ) - :name (mail.IsoAAAA-es.com) - ) - :read_community () - :sysContact () - :sysDescr () - :sysLocation () - :sysName () - :write_community () - :add_adtr_rule (false) - :certificates () - :edges () - :enforce_gtp_rate_limit (false) - :gtp_rate_limit (2048) - :interfaces () - :operating_system ( - :AdminInfo ( - :chkpf_uid ("{96AAF8C1-2F91-4581-B3A3-9E259D51D7FC}") - :ClassName (operating_system) - ) - :name () - :sp () - :version () - ) - :NAT () - :SNMP () - :VPN () - :additional_products () - :color (blue) - :comments () - :cp_products_installed (false) - :firewall (not-installed) - :floodgate (not-installed) - :ipaddr (10.222.0.54) - :type (host) - ) - : (MailServer - :AdminInfo ( - :chkpf_uid ("{17935795-6ADC-4B45-8E2B-BEC361E6CAB1}") - :ClassName (network_object_group) - :table (network_objects) - :Wiznum (-1) - :LastModified ( - :Time ("Thu Sep 30 16:35:07 2004") - :By (IsoAAAF) - :From (IsoAAADray) - ) - :name (MailServer) - ) - :members_query () - : (ReferenceObject - :Name (mail.IsoAAAA.de) - :Table (network_objects) - :Uid ("{98537EEE-D16C-4C24-940F-6880836A7350}") - ) - : (ReferenceObject - :Name (mail.IsoAAAA-es.com) - :Table (network_objects) - :Uid ("{B096EA6A-9B9D-4804-ADF0-E9D196210EDE}") - ) - : (ReferenceObject - :Name (mail.hayn.de) - :Table (network_objects) - :Uid ("{741A5834-3EA7-4899-92F4-3B365DDBCD98}") - ) - : (ReferenceObject - :Name (mail.purschke.de) - :Table (network_objects) - :Uid ("{8EFADE68-A4E4-4BF3-B2C4-EDBD81769700}") - ) - :color (blue1) - :comments ("all Maildomains") - :member_class (network_object) - :type (group) - ) - : (sol8 - :AdminInfo ( - :chkpf_uid ("{86F22190-7D8D-435D-8906-A346CA12A17C}") - :ClassName (host_plain) - :table (network_objects) - :Wiznum (-1) - :LastModified ( - :Time ("Sat Oct 2 16:28:42 2004") - :By (tim) - :From (pieks) - ) - :name (sol8) - ) - :read_community () - :sysContact () - :sysDescr () - :sysLocation () - :sysName () - :write_community () - :add_adtr_rule (false) - :certificates () - :edges () - :enforce_gtp_rate_limit (false) - :gtp_rate_limit (2048) - :interfaces () - :operating_system ( - :AdminInfo ( - :chkpf_uid ("{CC64DA48-EF9D-41E6-862A-BC87E9AEDB2F}") - :ClassName (operating_system) - ) - :name () - :sp () - :version () - ) - :NAT () - :SNMP () - :VPN () - :additional_products () - :color (black) - :comments () - :cp_products_installed (false) - :firewall (not-installed) - :floodgate (not-installed) - :ipaddr (10.222.0.55) - :type (host) - ) - : (t-online - :AdminInfo ( - :chkpf_uid ("{C3D65C4B-6498-4E00-9BAF-15539231E8EE}") - :ClassName (network) - :table (network_objects) - :Wiznum (-1) - :LastModified ( - :Time ("Sun Oct 3 14:33:10 2004") - :By (IsoAAAF) - :From (IsoAAADray) - ) - :name (t-online) - ) - :edges () - :NAT () - :add_adtr_rule (false) - :broadcast (allow) - :color ("deep pink") - :comments () - :ipaddr (10.222.0.56) - :location (internal) - :netmask (255.255.255.255) - :operating_system ( - :AdminInfo ( - :chkpf_uid ("{D7BABA12-EB8B-4603-81A3-02DD65E162B4}") - :ClassName (operating_system) - ) - :name () - :sp () - :version () - ) - :type (network) - ) - : (ras.IsoAAAA-es.com - :AdminInfo ( - :chkpf_uid ("{23B1E779-B8D5-4384-AD60-80E498B77196}") - :ClassName (host_plain) - :table (network_objects) - :Wiznum (-1) - :LastModified ( - :Time ("Mon Oct 4 19:53:42 2004") - :By (IsoAAAF) - :From (IsoAAADray) - ) - :name (ras.IsoAAAA-es.com) - ) - :read_community () - :sysContact () - :sysDescr () - :sysLocation () - :sysName () - :write_community () - :add_adtr_rule (false) - :certificates () - :edges () - :enforce_gtp_rate_limit (false) - :gtp_rate_limit (2048) - :interfaces () - :operating_system ( - :AdminInfo ( - :chkpf_uid ("{04E9B794-BC12-4F6F-B9AE-C0A08A74FF4A}") - :ClassName (operating_system) - ) - :name () - :sp () - :version () - ) - :NAT () - :SNMP () - :VPN () - :additional_products () - :color (cyan) - :comments () - :cp_products_installed (false) - :firewall (not-installed) - :floodgate (not-installed) - :ipaddr (10.222.0.57) - :type (host) - ) - : (Premier_Access - :AdminInfo ( - :chkpf_uid ("{B2BB20AA-B685-426B-96B6-1FB4D8D05135}") - :ClassName (host_plain) - :table (network_objects) - :Wiznum (-1) - :LastModified ( - :Time ("Thu Oct 7 13:35:32 2004") - :By (andre) - :From (Roadrunner) - ) - :name (Premier_Access) - ) - :certificates () - :edges () - :interfaces () - :NAT () - :read_community () - :sysContact () - :sysDescr () - :sysLocation () - :sysName () - :write_community () - :SNMP ( - :AdminInfo ( - :chkpf_uid ("{B2BB20AA-B685-426B-96B6-1FB4D8D05135}") - :ClassName (SNMP) - ) - ) - :VPN () - :add_adtr_rule (false) - :additional_products () - :color ("medium slate blue") - :comments () - :cp_products_installed (false) - :enforce_gtp_rate_limit (false) - :firewall (not-installed) - :floodgate (not-installed) - :gtp_rate_limit (2048) - :ipaddr (10.222.0.58) - :operating_system ( - :AdminInfo ( - :chkpf_uid ("{38EF5369-2EDF-4CAA-BE8E-155605B4C87D}") - :ClassName (operating_system) - ) - :name () - :sp () - :version () - ) - :type (host) - ) - : (vpn-sources-IsoAAAA - :AdminInfo ( - :chkpf_uid ("{26405A41-425C-4053-8002-497BB82D76B1}") - :ClassName (network_object_group) - :table (network_objects) - :Wiznum (-1) - :LastModified ( - :Time ("Sat Nov 6 14:38:57 2004") - :By (IsoAAAF) - :From (IsoAAADray) - ) - :name (vpn-sources-IsoAAAA) - ) - : (ReferenceObject - :Name (IsoAAAA_home_stephan) - :Table (network_objects) - :Uid ("{B86B46D5-DCB5-4A25-A0B6-766D78D30780}") - ) - : (ReferenceObject - :Name (IsoAAAA_home_tim) - :Table (network_objects) - :Uid ("{BF8F69B9-87C2-464A-9404-239AE8DF66B3}") - ) - : (ReferenceObject - :Name (IsoAAAA-100) - :Table (network_objects) - :Uid ("{BF1C6029-8D5D-4A05-A3AD-4B67E6E7A7AA}") - ) - : (ReferenceObject - :Name (CactusDSL-DHCP) - :Table (network_objects) - :Uid ("{4F363EC1-417F-4F6D-B8DC-21875B3E4AC6}") - ) - : (ReferenceObject - :Name (Cactus-InternetTransfer) - :Table (network_objects) - :Uid ("{408C820D-33A1-4E25-B576-EC826F525DCD}") - ) - : (ReferenceObject - :Name (Cactus-Wlan) - :Table (network_objects) - :Uid ("{FFB3BAC5-FD79-4D0B-911A-7413DA524723}") - ) - : (ReferenceObject - :Name (wlan-router) - :Table (network_objects) - :Uid ("{426CC3AD-BE7D-45B6-AAAB-22BA0680EE21}") - ) - :color (black) - :comments () - :member_class (network_object) - :members_query () - :type (group) - ) - : (Cactus10.222.0.1 - :AdminInfo ( - :chkpf_uid ("{6CD51061-638B-4B2F-9092-7E1E4A5F0ADD}") - :ClassName (host_plain) - :table (network_objects) - :Wiznum (-1) - :LastModified ( - :Time ("Sat Nov 6 16:10:22 2004") - :By (IsoAAAF) - :From (IsoAAADray) - ) - :name (Cactus10.222.0.1) - ) - :certificates () - :edges () - :interfaces () - :NAT () - :read_community () - :sysContact () - :sysDescr () - :sysLocation () - :sysName () - :write_community () - :SNMP ( - :AdminInfo ( - :chkpf_uid ("{6CD51061-638B-4B2F-9092-7E1E4A5F0ADD}") - :ClassName (SNMP) - ) - ) - :VPN () - :add_adtr_rule (false) - :additional_products () - :color (blue) - :comments ("IBM Laptop with VMWare 6.11.2004") - :cp_products_installed (false) - :enforce_gtp_rate_limit (false) - :firewall (not-installed) - :floodgate (not-installed) - :gtp_rate_limit (2048) - :ipaddr (10.222.0.1) - :operating_system ( - :AdminInfo ( - :chkpf_uid ("{D2AFE9A3-FE6E-47EC-8A3D-93104C67F9B3}") - :ClassName (operating_system) - ) - :name () - :sp () - :version () - ) - :type (host) - ) - : (Cactus10.222.0.59 - :AdminInfo ( - :chkpf_uid ("{B0D01C29-857D-4A0A-BC23-66A08FCD094D}") - :ClassName (host_plain) - :table (network_objects) - :Wiznum (-1) - :LastModified ( - :Time ("Sat Nov 6 16:10:29 2004") - :By (IsoAAAF) - :From (IsoAAADray) - ) - :name (Cactus10.222.0.59) - ) - :certificates () - :edges () - :interfaces () - :NAT () - :read_community () - :sysContact () - :sysDescr () - :sysLocation () - :sysName () - :write_community () - :SNMP ( - :AdminInfo ( - :chkpf_uid ("{B0D01C29-857D-4A0A-BC23-66A08FCD094D}") - :ClassName (SNMP) - ) - ) - :VPN () - :add_adtr_rule (false) - :additional_products () - :color (black) - :comments ("VIP-Net Koordinator auf VM-Ware IBM Laptop 5.11.2004") - :cp_products_installed (false) - :enforce_gtp_rate_limit (false) - :firewall (not-installed) - :floodgate (not-installed) - :gtp_rate_limit (2048) - :ipaddr (10.222.0.59) - :operating_system ( - :AdminInfo ( - :chkpf_uid ("{52322F92-8A93-488B-93D3-6C8350FC9A52}") - :ClassName (operating_system) - ) - :name () - :sp () - :version () - ) - :type (host) - ) - : (SecOVID_Authserver - :AdminInfo ( - :chkpf_uid ("{DB220C3D-763C-46AB-A7D1-1F9C7C45910E}") - :ClassName (host_plain) - :table (network_objects) - :Wiznum (-1) - :LastModified ( - :Time ("Thu Dec 2 15:56:31 2004") - :By (IsoAAAF) - :From (IsoAAADray) - ) - :name (SecOVID_Authserver) - ) - :certificates () - :edges () - :interfaces () - :NAT () - :read_community () - :sysContact () - :sysDescr () - :sysLocation () - :sysName () - :write_community () - :SNMP ( - :AdminInfo ( - :chkpf_uid ("{DB220C3D-763C-46AB-A7D1-1F9C7C45910E}") - :ClassName (SNMP) - ) - ) - :VPN () - :add_adtr_rule (false) - :additional_products () - :color (green) - :comments () - :cp_products_installed (false) - :enforce_gtp_rate_limit (false) - :firewall (not-installed) - :floodgate (not-installed) - :gtp_rate_limit (2048) - :ipaddr (10.222.0.60) - :operating_system ( - :AdminInfo ( - :chkpf_uid ("{24962D03-284E-4ECD-AD98-86D19C8271B4}") - :ClassName (operating_system) - ) - :name () - :sp () - :version () - ) - :type (host) - ) - : (mail.light-life.netOld - :AdminInfo ( - :chkpf_uid ("{DF004F13-7986-4569-811C-6EC7391A8764}") - :ClassName (host_plain) - :table (network_objects) - :Wiznum (-1) - :LastModified ( - :Time ("Mon Jan 24 13:50:53 2005") - :By (IsoAAAF) - :From (IsoAAADray) - ) - :name (mail.light-life.netOld) - ) - :certificates () - :edges () - :interfaces () - :NAT () - :read_community () - :sysContact () - :sysDescr () - :sysLocation () - :sysName () - :write_community () - :SNMP ( - :AdminInfo ( - :chkpf_uid ("{DF004F13-7986-4569-811C-6EC7391A8764}") - :ClassName (SNMP) - ) - ) - :VPN () - :add_adtr_rule (false) - :additional_products () - :color (orange) - :comments ("Silkes Mail") - :cp_products_installed (false) - :enforce_gtp_rate_limit (false) - :firewall (not-installed) - :floodgate (not-installed) - :gtp_rate_limit (2048) - :ipaddr (10.222.0.61) - :operating_system ( - :AdminInfo ( - :chkpf_uid ("{2E52BC89-F624-44E8-B100-A39B0AB9B399}") - :ClassName (operating_system) - ) - :name () - :sp () - :version () - ) - :type (host) - ) - : (mail.light-life.net - :AdminInfo ( - :chkpf_uid ("{C534904C-317E-431D-BF6C-03977CC08203}") - :ClassName (host_plain) - :table (network_objects) - :Wiznum (-1) - :LastModified ( - :Time ("Mon Jan 24 13:50:58 2005") - :By (IsoAAAF) - :From (IsoAAADray) - ) - :name (mail.light-life.net) - ) - :certificates () - :edges () - :interfaces () - :NAT () - :read_community () - :sysContact () - :sysDescr () - :sysLocation () - :sysName () - :write_community () - :SNMP ( - :AdminInfo ( - :chkpf_uid ("{C534904C-317E-431D-BF6C-03977CC08203}") - :ClassName (SNMP) - ) - ) - :VPN () - :add_adtr_rule (false) - :additional_products () - :color (blue) - :comments () - :cp_products_installed (false) - :enforce_gtp_rate_limit (false) - :firewall (not-installed) - :floodgate (not-installed) - :gtp_rate_limit (2048) - :ipaddr (10.222.0.62) - :operating_system ( - :AdminInfo ( - :chkpf_uid ("{59E4FEAD-7108-4E23-B865-7C7A401F382A}") - :ClassName (operating_system) - ) - :name () - :sp () - :version () - ) - :type (host) - ) - : (IsoAAAD_intern - :AdminInfo ( - :chkpf_uid ("{40831AE2-CB84-46D2-9522-F987BC10BDB9}") - :ClassName (host_plain) - :table (network_objects) - :Wiznum (-1) - :LastModified ( - :Time ("Mon Jan 24 13:57:02 2005") - :By (IsoAAAF) - :From (IsoAAADray) - ) - :name (IsoAAAD_intern) - ) - :certificates () - :edges () - :interfaces () - :NAT () - :read_community () - :sysContact () - :sysDescr () - :sysLocation () - :sysName () - :write_community () - :SNMP ( - :AdminInfo ( - :chkpf_uid ("{40831AE2-CB84-46D2-9522-F987BC10BDB9}") - :ClassName (SNMP) - ) - ) - :VPN () - :add_adtr_rule (false) - :additional_products () - :color (red) - :comments (10.222.0.63) - :cp_products_installed (false) - :enforce_gtp_rate_limit (false) - :firewall (not-installed) - :floodgate (not-installed) - :gtp_rate_limit (2048) - :ipaddr (10.222.0.63) - :operating_system ( - :AdminInfo ( - :chkpf_uid ("{F32BCF76-B27C-4087-AC45-A7A6DCB70413}") - :ClassName (operating_system) - ) - :name () - :sp () - :version () - ) - :type (host) - ) - : (IsoAAAA-office-mode-range - :AdminInfo ( - :chkpf_uid ("{AF3BE336-00D5-4975-B0C9-F759300D42D8}") - :ClassName (network) - :table (network_objects) - :Wiznum (-1) - :LastModified ( - :Time ("Tue Feb 1 14:12:41 2005") - :By (tim) - :From (pieks) - ) - :name (IsoAAAA-office-mode-range) - ) - :add_adtr_rule (false) - :edges () - :location (internal) - :operating_system ( - :AdminInfo ( - :chkpf_uid ("{669DDE9F-A4D3-4F79-AB66-6D46F1710730}") - :ClassName (operating_system) - ) - :name () - :sp () - :version () - ) - :NAT () - :broadcast (allow) - :color (black) - :comments () - :ipaddr (10.222.0.64) - :netmask (255.255.255.255) - :type (network) - ) - : (Cactus-DMZ4 - :AdminInfo ( - :chkpf_uid ("{9C2C49CE-5100-423C-BECB-08951751059F}") - :ClassName (network) - :table (network_objects) - :Wiznum (-1) - :LastModified ( - :Time ("Thu Mar 31 20:38:45 2005") - :By (IsoAAAF) - :From (IsoAAADray) - ) - :name (Cactus-DMZ4) - ) - :add_adtr_rule (false) - :edges () - :location (internal) - :operating_system ( - :AdminInfo ( - :chkpf_uid ("{BB469654-D760-4C34-8DED-EDB208914A3F}") - :ClassName (operating_system) - ) - :name () - :sp () - :version () - ) - :NAT () - :broadcast (allow) - :color ("forest green") - :comments ("10.222.0.65/32") - :ipaddr (10.222.0.65) - :netmask (255.255.255.255) - :type (network) - ) - : (ITSecOrg-dev - :AdminInfo ( - :chkpf_uid ("{18122B8C-51F8-4102-B143-72DA4E57367D}") - :ClassName (host_plain) - :table (network_objects) - :Wiznum (-1) - :LastModified ( - :Time ("Thu Apr 28 14:17:13 2005") - :By (IsoAAAF) - :From (IsoAAADray) - ) - :name (ITSecOrg-dev) - ) - :read_community () - :sysContact () - :sysDescr () - :sysLocation () - :sysName () - :write_community () - :add_adtr_rule (false) - :certificates () - :edges () - :enforce_gtp_rate_limit (false) - :gtp_rate_limit (2048) - :interfaces () - :operating_system ( - :AdminInfo ( - :chkpf_uid ("{9295DAEC-8C37-4E45-816D-977184D54CA4}") - :ClassName (operating_system) - ) - :name () - :sp () - :version () - ) - :NAT () - :SNMP () - :VPN () - :additional_products () - :color (blue1) - :comments ("development 4 ITSecOrg") - :cp_products_installed (false) - :firewall (not-installed) - :floodgate (not-installed) - :ipaddr (10.222.0.66) - :type (host) - ) - : (SonicLAN - :AdminInfo ( - :chkpf_uid ("{587A029D-04EA-49A0-9DB2-93ADC651B7BF}") - :ClassName (network) - :table (network_objects) - :Wiznum (-1) - :LastModified ( - :Time ("Tue May 24 11:53:28 2005") - :By (IsoAAAF) - :From (IsoAAADray) - ) - :name (SonicLAN) - ) - :add_adtr_rule (false) - :edges () - :location (internal) - :operating_system ( - :AdminInfo ( - :chkpf_uid ("{82672588-DA60-4678-BCFE-9855BBA7B813}") - :ClassName (operating_system) - ) - :name () - :sp () - :version () - ) - :NAT () - :broadcast (allow) - :color ("light coral") - :comments ("4 VPN-Test") - :ipaddr (10.222.0.67) - :netmask (255.255.255.255) - :type (network) - ) - : (Cactus-Wlan - :AdminInfo ( - :chkpf_uid ("{FFB3BAC5-FD79-4D0B-911A-7413DA524723}") - :ClassName (address_range) - :table (network_objects) - :Wiznum (-1) - :LastModified ( - :Time ("Tue May 24 15:51:05 2005") - :By (IsoAAAF) - :From (IsoAAADray) - ) - :name (Cactus-Wlan) - ) - :edges () - :NAT () - :add_adtr_rule (false) - :color (black) - :comments ("net for wlan") - :ipaddr_first (10.222.0.68) - :ipaddr_last (10.222.0.69) - :type (machines_range) - ) - : (CactusDA - :AdminInfo ( - :chkpf_uid ("{69DBB75C-7E6D-49AD-A814-96F1BAFF12F7}") - :ClassName (network_object_group) - :table (network_objects) - :Wiznum (-1) - :LastModified ( - :Time ("Mon Jun 6 11:27:32 2005") - :By (andre) - :From (andres-laptop) - ) - :name (CactusDA) - ) - : (ReferenceObject - :Name (IsoAAAA-100) - :Table (network_objects) - :Uid ("{BF1C6029-8D5D-4A05-A3AD-4B67E6E7A7AA}") - ) - : (ReferenceObject - :Name (Cactus-Official) - :Table (network_objects) - :Uid ("{2136B4E8-3ABF-4931-BDB9-12CDF457D4A4}") - ) - : (ReferenceObject - :Name (Sonic1) - :Table (network_objects) - :Uid ("{B2EBD57B-C94C-42E7-8F1A-17C861697403}") - ) - : (ReferenceObject - :Name (IsoAAAD) - :Table (network_objects) - :Uid ("{29C40B0A-414C-11D7-AEB8-7F0000013C3C}") - ) - :color (black) - :comments () - :member_class (network_object) - :members_query () - :type (group) - ) - : (Sonic1 - :AdminInfo ( - :chkpf_uid ("{B2EBD57B-C94C-42E7-8F1A-17C861697403}") - :ClassName (gateway_plain) - :table (network_objects) - :Wiznum (-1) - :LastModified ( - :Time ("Thu Jun 23 14:32:41 2005") - :By (IsoAAAF) - :From (IsoAAADray) - ) - ) - :certificates () - :edges () - :interfaces () - :NAT () - :read_community () - :sysContact () - :sysDescr () - :sysLocation () - :sysName () - :write_community () - :SNMP ( - :AdminInfo ( - :chkpf_uid ("{B2EBD57B-C94C-42E7-8F1A-17C861697403}") - :ClassName (SNMP) - ) - ) - :isakmp.authmethods ( - : (pre-shared) - ) - :isakmp.matchpeer () - :FWZ () - :isakmp.encmethods ( - : (3DES) - : (DES) - ) - :isakmp.hashmethods ( - : (MD5) - : (SHA1) - ) - :isakmp.phase1_DH_groups ( - : (ReferenceObject - :Name ("Group 5 (1536 bit)") - :Table (encryption) - :Uid ("{97AEB62E-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :isakmpsharedkey () - :ISAKMP_aggressive_support (true) - :ike.empty_udp_socket (false) - :isakmp.crlreq (false) - :isakmp.phase1_rekeying_time (60) - :isakmp.phase2_rekeying_kbytes (50000) - :isakmp.phase2_rekeying_time (3600) - :isakmp.phase2_use_rekeying_kbytes (false) - :isakmpkeymanager () - :IKE ( - :AdminInfo ( - :chkpf_uid ("{B2EBD57B-C94C-42E7-8F1A-17C861697403}") - :ClassName (IKE) - ) - ) - :ISAKMP_subnet_support (true) - :accept_3des_for_clientless_vpn (true) - :clientless_VPN_ask_user_for_certificate (none) - :clientless_proc_num (1) - :enable_internet_routing (false) - :enable_routing (true) - :ipsec.copy_TOS_to_inner (false) - :ipsec.copy_TOS_to_outer (true) - :ipsec_dont_fragment (true) - :isakmp.allowed_ca () - :isakmp.allowed_cert () - :isakmp.dn () - :isakmp.dns_name () - :isakmp.do_dns_resolve (false) - :isakmp.email () - :isakmp.ipcomp_support (false) - :isakmp.udpencapsulation ( - :AdminInfo ( - :chkpf_uid ("{7B561E2F-3476-4F65-B808-B887605A9F7C}") - :ClassName (IKE_UDP_encapsulation) - ) - :active (true) - :resource (ReferenceObject - :Table (services) - :Name (VPN1_IPSEC_encapsulation) - :Uid ("{97AEB390-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :tcpt ( - :AdminInfo ( - :chkpf_uid ("{32763E96-70C9-4186-B5D8-F99AEEC93FE1}") - :ClassName (TCP_TUNNELING) - ) - :active (false) - :interface ("All IPs") - :resource (ReferenceObject - :Name (https) - :Table (services) - :Uid ("{97AEB443-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :third_party_encryption (true) - :use_cert () - :use_clientless_vpn (false) - :use_service (ReferenceObject - :Table (services) - :Name (https) - :Uid ("{97AEB443-9AEA-11D5-BD16-0090272CCB30}") - ) - :vpn_comp_level (2) - :VPN ( - :AdminInfo ( - :chkpf_uid ("{B2EBD57B-C94C-42E7-8F1A-17C861697403}") - :ClassName (VPN) - ) - ) - :VPN_allow_relay (false) - :VPN_relay_if_name () - :add_adtr_rule (false) - :additional_products () - :backup_gateway () - :backup_gw (false) - :color (black) - :comments ("VPN Test") - :cp_products_installed (false) - :encdomain (manual) - :enforce_gtp_rate_limit (false) - :firewall (not-installed) - :floodgate (not-installed) - :gtp_rate_limit (2048) - :interface_resolving_ha_primary_if_GW () - :ip_pool_exhaust_ret_interval (30) - :ip_pool_gw2gw (false) - :ip_pool_securemote (false) - :ip_pool_securemote_allocation_name () - :ip_pool_unused_return_interval (60) - :ipaddr (10.222.0.59) - :manual_encdomain (ReferenceObject - :Name (SonicLAN) - :Table (network_objects) - :Uid ("{587A029D-04EA-49A0-9DB2-93ADC651B7BF}") - ) - :operating_system ( - :AdminInfo ( - :chkpf_uid ("{FDEAA053-4C49-4838-A711-7C0DEB9E0AB0}") - :ClassName (operating_system) - ) - :name () - :sp () - :version () - ) - :perform_encryption (true) - :range_encdomain () - :type (gateway) - ) - : (IsoAAAD - :AdminInfo ( - :chkpf_uid ("{29C40B0A-414C-11D7-AEB8-7F0000013C3C}") - :ClassName (gateway_ckp) - :object_permissions ( - :AdminInfo ( - :chkpf_uid ("{EB6FC940-52CD-4BD6-904C-EB31739BDA15}") - :ClassName (object_permissions) - ) - :manage ( - : (ReferenceObject - :Table (globals) - :Name (Any) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :read ( - : (any) - ) - :use ( - : (any) - ) - :write ( - : () - ) - :owner () - ) - :table (network_objects) - :Deleteable (false) - :Renameable (false) - :Wiznum (-1) - :LastModified ( - :Time ("Thu Jun 23 14:32:41 2005") - :By (IsoAAAF) - :From (IsoAAADray) - ) - ) - :backup_gateway () - :certificates ( - : (defaultCert - :AdminInfo ( - :chkpf_uid ("{C1CADC7F-56D0-42CB-9EE4-CBCBFE50930A}") - :ClassName (certificate) - ) - :"#certreq-pki-gen" (false) - :"#pki-host-cert-set" (false) - :ca (ReferenceObject - :Name (internal_ca) - :Table (servers) - :Uid ("{29DD801C-414C-11D7-AEB8-7F0000013C3C}") - ) - :dn ("CN=IsoAAAD VPN Certificate,O=IsoAAAD.IsoAAAA-es.de..jnbkhk") - :pkisignkey (c9b51d2a6789df31ea72d712) - :status (signed) - :stored.at (management_server) - ) - ) - :edges () - :free_fields () - :interfaces ( - :0 ( - :AdminInfo ( - :chkpf_uid ("{29C486E8-414C-11D7-AEB8-7F0000013C3C}") - :ClassName (interface) - ) - :edges () - :diff_serv_values () - :diff_serv (false) - :fg_inbound_active (false) - :fg_inbound_rate (5898240) - :fg_outbound_active (false) - :fg_outbound_rate (5898240) - :bandwidth ( - :AdminInfo ( - :chkpf_uid ("{29C486E8-414C-11D7-AEB8-7F0000013C3C}") - :ClassName (interface_bandwidth) - ) - ) - :comments () - :description () - :dynamic_ip (false) - :ifindex (0) - :ipaddr (10.222.0.63) - :netmask (255.255.255.255) - :officialname (eth0) - :antispoof (true) - :netaccess ( - :AdminInfo ( - :chkpf_uid ("{29C47BDA-414C-11D7-AEB8-7F0000013C3C}") - :ClassName (netaccess) - ) - :access (undefined) - :allowed () - :enable_overlapping_nat (false) - :force_policy (true) - :leads_to_internet (false) - :log (alert) - :overlap_nat_dst_ipaddr () - :overlap_nat_netmask (255.255.255.255) - :overlap_nat_src_ipaddr () - :perform_anti_spoofing (false) - ) - :security ( - :AdminInfo ( - :chkpf_uid ("{29C486E8-414C-11D7-AEB8-7F0000013C3C}") - :ClassName (interface_security) - ) - ) - :shared (true) - ) - :1 ( - :AdminInfo ( - :chkpf_uid ("{BE1E514B-74C7-4EA3-B375-A0752C2C9F9A}") - :ClassName (interface) - ) - :edges () - :bandwidth () - :comments () - :description () - :dynamic_ip (false) - :ifindex (1) - :ipaddr (10.222.0.42) - :netmask (255.255.255.255) - :officialname (eth1) - :antispoof (true) - :netaccess ( - :AdminInfo ( - :chkpf_uid ("{8602D66D-CE3F-428D-9A10-F9D5112DCF93}") - :ClassName (netaccess) - ) - :access (undefined) - :allowed () - :enable_overlapping_nat (false) - :force_policy (true) - :leads_to_internet (true) - :log (log) - :overlap_nat_dst_ipaddr () - :overlap_nat_netmask (255.255.255.255) - :overlap_nat_src_ipaddr () - :perform_anti_spoofing (true) - ) - :security ( - :AdminInfo ( - :chkpf_uid ("{BE1E514B-74C7-4EA3-B375-A0752C2C9F9A}") - :ClassName (interface_security) - ) - ) - :shared (true) - ) - ) - :masters () - :Enable_CPSyslogD (false) - :Everest (false) - :IPSec_orig_if_nat (true) - :MetaIP_Admin_Server (false) - :MetaIP_DHCP_Server (false) - :MetaIP_DNS_Server (false) - :MetaIP_RADIUS_Server (false) - :MetaIP_UAT (false) - :NAT () - :read_community () - :sysContact () - :sysDescr () - :sysLocation () - :sysName () - :write_community () - :SNMP ( - :AdminInfo ( - :chkpf_uid ("{29C40B0A-414C-11D7-AEB8-7F0000013C3C}") - :ClassName (SNMP) - ) - ) - :SmallOffice (false) - :UA_WebAccess (false) - :UA_gateway (false) - :UA_server (false) - :isakmp.authmethods ( - : (pre-shared) - ) - :isakmp.matchpeer () - :FWZ () - :isakmp.encmethods ( - : (3DES) - : (AES-256) - : (CAST) - ) - :isakmp.hashmethods ( - : (MD5) - : (SHA1) - ) - :isakmp.phase1_DH_groups ( - : (ReferenceObject - :Name ("Group 2 (1024 bit)") - :Table (encryption) - :Uid ("{97AEB629-9AEA-11D5-BD16-0090272CCB30}") - ) - : (ReferenceObject - :Name ("Group 5 (1536 bit)") - :Table (encryption) - :Uid ("{97AEB62E-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :isakmpsharedkey ( - : (tmp-IsoAAAA.mine.nu) - : (IsoAAAA-ffm) - ) - :ISAKMP_aggressive_support (true) - :ike.empty_udp_socket (false) - :isakmp.crlreq (false) - :isakmp.phase1_rekeying_time (60) - :isakmp.phase2_rekeying_kbytes (50000) - :isakmp.phase2_rekeying_time (3600) - :isakmp.phase2_use_rekeying_kbytes (false) - :isakmpkeymanager () - :IKE ( - :AdminInfo ( - :chkpf_uid ("{29C40B0A-414C-11D7-AEB8-7F0000013C3C}") - :ClassName (IKE) - ) - ) - :ISAKMP_subnet_support (true) - :accept_3des_for_clientless_vpn (false) - :clientless_VPN_ask_user_for_certificate (ask) - :clientless_proc_num (1) - :enable_internet_routing (false) - :enable_routing (true) - :ipsec.copy_TOS_to_inner (false) - :ipsec.copy_TOS_to_outer (true) - :ipsec_dont_fragment (true) - :isakmp.allowed_ca () - :isakmp.allowed_cert () - :isakmp.dn () - :isakmp.dns_name () - :isakmp.do_dns_resolve (false) - :isakmp.email () - :isakmp.ipcomp_support (false) - :isakmp.udpencapsulation ( - :AdminInfo ( - :chkpf_uid ("{3D18AC86-B15C-46DA-8C2B-4A8549E5B3DF}") - :ClassName (IKE_UDP_encapsulation) - ) - :active (true) - :resource (ReferenceObject - :Name (VPN1_IPSEC_encapsulation) - :Table (services) - :Uid ("{97AEB390-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :tcpt ( - :AdminInfo ( - :chkpf_uid ("{C0FB535C-83FE-11D8-AF49-C0A8645AD0D0}") - :ClassName (TCP_TUNNELING) - ) - :active (false) - :interface ("All IPs") - :resource (ReferenceObject - :Table (services) - :Name (https) - :Uid ("{97AEB443-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :third_party_encryption (false) - :use_cert () - :use_clientless_vpn (false) - :use_service (ReferenceObject - :Table (services) - :Name (https) - :Uid ("{97AEB443-9AEA-11D5-BD16-0090272CCB30}") - ) - :vpn_comp_level (2) - :VPN ( - :AdminInfo ( - :chkpf_uid ("{29C40B0A-414C-11D7-AEB8-7F0000013C3C}") - :ClassName (VPN) - ) - ) - :VPN_1 (true) - :VPN_allow_relay (false) - :VPN_relay_if_name () - :WAM (false) - :add_adtr_rule (false) - :additional_products () - :allow_extranet (false) - :amazonas_machine (false) - :apply_nat_for_cp_conns (false) - :asm_synatk (false) - :asm_synatk_external_only (false) - :asm_synatk_log (none) - :asm_synatk_log_level (1) - :asm_synatk_threshold (200) - :asm_synatk_timeout (10) - :au_timeout (15) - :backup_gw (false) - :ca_wait_mode (false) - :color (black) - :comments () - :connection_state (communicating) - :copy_DF_flag_SR (false) - :cp_products_installed (true) - :cp_suite_type (pro) - :cpver (5.0) - :default_track (alert) - :define_logging_servers (false) - :disable_replay_check (false) - :display_name_for_sr_sc () - :enable_rtm_counters_report (true) - :enable_rtm_traffic_report (false) - :enable_rtm_traffic_report_per_connection (false) - :encdomain (manual) - :enforce_gtp_rate_limit (false) - :event_analyzer (false) - :exportable (true) - :firewall (installed) - :auth_user_groups (ReferenceObject - :Table (globals) - :Name ("All Users") - :Uid ("{97AEB36A-9AEB-11D5-BD16-0090272CCB30}") - ) - :custom_multi_server_au_list () - :misp_dns_entries () - :misp_isps () - :DAG (false) - :DAG_manual_fetch (false) - :DAG_schedule_interval () - :IPSec_main_if_nat (false) - :NAT_cache_expiration (30) - :NAT_cache_nentries (10000) - :SDS (not-installed) - :allow_VPN_routing_from_SR (false) - :calculation_type (partially_automatic) - :connections_hashsize (32768) - :connections_limit (25000) - :disable_outgoing_tcpt (false) - :display_au_list (false) - :ftp_transparent_server_connection (true) - :fw_hmem_maxsize (30) - :fw_hmem_size (6) - :fw_keep_old_conns (false) - :fw_rst_expired_conn (false) - :fwver (5.0) - :generic_transparent_server_connection (true) - :host_schemes_val (122) - :http_next_proxy_defined (false) - :http_transparent_server_connection (true) - :ip_assignment_group () - :ip_assignment_offer (never) - :ip_assignment_settings () - :l2tp_auth_method (MD5) - :max_concurrent_gw_tunnels (200) - :max_concurrent_vpn_tunnels (10000) - :max_num_negs (200) - :misp_active (false) - :misp_cache_hashsize (4096) - :misp_cache_limit (10000) - :misp_cache_timeout (300) - :misp_cache_use_cln (true) - :misp_cache_use_srv (false) - :misp_dns_active (false) - :misp_dns_ttl (15) - :misp_host_is_dead_after (15) - :misp_load_sharing (true) - :misp_ping_interval (5) - :misp_ping_wait_time (3) - :misp_pings_per_interval (1) - :misp_track_isp_went_down (alert) - :misp_track_isp_went_up (log) - :netso () - :non_tcp_quota_enable (false) - :non_tcp_quota_percentage (50) - :policy_server (not-installed) - :remote_access_nrules (4) - :rlogin_transparent_server_connection (true) - :save_control_conns (false) - :save_data_conns (false) - :smtp ( - :AdminInfo ( - :chkpf_uid ("{29C42F18-414C-11D7-AEB8-7F0000013C3C}") - :ClassName (smtp_module) - ) - :abandon_time (43200) - :detailed_av_err_mail (false) - :detailed_rb_err_mail (false) - :detailed_smtp_err_mail (false) - :max_conns (40) - :max_conns_per_site (6) - :max_ips_per_mx_node (1) - :max_mail_size (1000) - :max_mails_per_conn (20) - :max_mx_node_per_mail (5) - :maxrecipients (50) - :postmaster () - :resend_period (600) - :rundir () - :scan_period (2) - :spool_limit (20000) - :spool_limit_scan_period (20) - :timeout (90) - ) - :smtp_transparent_server_connection (false) - :support_l2tp (false) - :telnet_transparent_server_connection (true) - :use_cert_for_l2tp () - :use_custom_au_list (false) - :use_sequential_au_lookup (false) - :xrs (false) - :firewall_setting ( - :AdminInfo ( - :chkpf_uid ("{29C40B0A-414C-11D7-AEB8-7F0000013C3C}") - :ClassName (firewall) - ) - ) - :floodgate (not-installed) - :fgver (5.0) - :floodgate_setting ( - :AdminInfo ( - :chkpf_uid ("{29C40B0A-414C-11D7-AEB8-7F0000013C3C}") - :ClassName (floodgate) - ) - ) - :fwldap_RequestTimeout (20) - :fwsynatk_max (5000) - :fwsynatk_method (0) - :fwsynatk_timeout (10) - :fwsynatk_warning (1) - :gtp_rate_limit (2048) - :gx_version (2.0) - :hosted_by_mds () - :http_next_proxy_host () - :http_next_proxy_port () - :ike_support_crash_recovery_sr (true) - :interface_resolving_ha (false) - :interface_resolving_ha_GW (false) - :interface_resolving_ha_primary_if_GW () - :ip_pool_exhaust_ret_interval (30) - :ip_pool_gw2gw (false) - :ip_pool_securemote (false) - :ip_pool_securemote_allocation_name () - :ip_pool_unused_return_interval (60) - :ipaddr (10.222.0.63) - :keep_DF_flag (false) - :keep_DF_flag_SR (false) - :location (internal) - :log_consolidator (false) - :log_policy ( - :AdminInfo ( - :chkpf_uid ("{29C3E8F0-414C-11D7-AEB8-7F0000013C3C}") - :ClassName (log_policy) - ) - :Citrix_ICA_application_detection (false) - :acct_update_interval (3600) - :alert_free_disk_space (20) - :alert_free_disk_space_metrics (mbytes) - :alert_on_disk_space (true) - :alert_type (alert) - :etm_logging (true) - :forward_event (false) - :forward_logs (false) - :log_delete_below_metrics (mbytes) - :log_delete_below_value (45) - :log_delete_on_below (false) - :log_delete_on_run_script (false) - :log_delete_script_command () - :log_forward_schedule () - :log_forward_target () - :log_keep_days_value (0) - :log_keep_on_days (false) - :log_switch_before_forwarding (false) - :log_switch_on_file_size (true) - :log_switch_schedule () - :log_switch_size (100) - :min_free_disk_space (15) - :reject_connections (true) - :scheduled_switch (false) - :stop_free_disk_space_metrics (mbytes) - :stop_logging_on_free_disk_space (true) - ) - :log_server (true) - :log_servers ( - :AdminInfo ( - :chkpf_uid ("{BB06EAAB-D151-444E-BAC8-98C29198FED4}") - :ClassName (log_servers) - ) - :backup_log_servers () - :send_alerts_to () - :send_logs_to () - :self_log_server (false) - ) - :management (true) - :manual_encdomain (ReferenceObject - :Name (CactusDA) - :Table (network_objects) - :Uid ("{69DBB75C-7E6D-49AD-A814-96F1BAFF12F7}") - ) - :mds () - :operating_system ( - :AdminInfo ( - :chkpf_uid ("{29C3F3D6-414C-11D7-AEB8-7F0000013C3C}") - :ClassName (operating_system) - ) - :name (secureplatform) - :sp ("#1 Wed Nov 19 19:54:48 GMT 2003") - :version (2.4.9-42cp) - ) - :option_pack (4) - :owner () - :perform_encryption (true) - :performancepack (false) - :primary_management (true) - :radius_server (ReferenceObject - :Table (globals) - :Name (None) - :Uid ("{97AEB36A-9AEA-11D5-BD16-0090272CCB30}") - ) - :range_encdomain () - :real_time_monitor (false) - :reporting_server (false) - :resolve_multiple_interfaces (false) - :resolve_multiple_interfaces_GW (false) - :sam_allow_remote_request (true) - :sam_enable_purge_history_file (false) - :sam_proxy_backwards_compatibility_security_method () - :sam_purge_file_start_size (100) - :sic_name ("cn=cp_mgmt,o=IsoAAAD.IsoAAAA-es.de..jnbkhk") - :support_sr_ike_mm (true) - :supports_tcp_ike (use_site_default) - :type (gateway) - :upload_logs (true) - :use_loggers_and_masters (true) - :used_globaly (false) - :user_friendly () - :vpnddcate (false) - :web_auth () - ) - ) - :servers (servers - : (internal_ca - :AdminInfo ( - :LastModified ( - :Time ("Sun Feb 16 01:15:40 2003") - :By ("Firewall Management Process") - :From (IsoAAAD) - ) - :chkpf_uid ("{29DD801C-414C-11D7-AEB8-7F0000013C3C}") - :ClassName (internal_ca_server) - :Deleteable (false) - :table (servers) - :name (internal_ca) - ) - :permissions_strings () - :use_cn_to_fetch_user (false) - :ca_type (internal) - :cacertificate () - :cacertsignkey (dd743a1f4010fadb90d0d8ad) - :color (black) - :comments () - :crl_cache_timeout (86400) - :crl_cache_type (Timeout) - :crl_http (true) - :crl_ldap (false) - :dn ("O=IsoAAAD.IsoAAAA-es.de..jnbkhk") - :internal_CA_check_CRL (true) - :permissions_type (None) - :type (ca) - ) - : (PremierAccess - :AdminInfo ( - :chkpf_uid ("{9484F12B-7004-4574-8BF1-306A4836D397}") - :ClassName (radius_server) - :table (servers) - :Wiznum (-1) - :LastModified ( - :Time ("Thu Oct 7 14:00:42 2004") - :By (andre) - :From (Roadrunner) - ) - ) - :color (blue) - :comments (Radius) - :new_shared_secret (e855fbb32a) - :priority (1) - :server (ReferenceObject - :Name (Premier_Access) - :Table (network_objects) - :Uid ("{B2BB20AA-B685-426B-96B6-1FB4D8D05135}") - ) - :service (ReferenceObject - :Name (NEW-RADIUS) - :Table (services) - :Uid ("{97AEB41E-9AEA-11D5-BD16-0090272CCB30}") - ) - :type (radius) - :version ("RADIUS Ver. 2.0") - ) - : (SecOVID - :AdminInfo ( - :chkpf_uid ("{9F7FBB97-1E72-4A3C-9FF7-08D5B5A4FAFF}") - :ClassName (radius_server) - :table (servers) - :Wiznum (-1) - :LastModified ( - :Time ("Thu Oct 7 15:20:35 2004") - :By (stephan) - :From (Pegasus) - ) - ) - :color (green) - :comments (testinstall) - :new_shared_secret (e1e053fda323) - :priority (2) - :server (ReferenceObject - :Name (SecOVID_Authserver) - :Table (network_objects) - :Uid ("{DB220C3D-763C-46AB-A7D1-1F9C7C45910E}") - ) - :service (ReferenceObject - :Name (NEW-RADIUS) - :Table (services) - :Uid ("{97AEB41E-9AEA-11D5-BD16-0090272CCB30}") - ) - :type (radius) - :version ("RADIUS Ver. 2.0") - ) - ) - :resources_types (resources_types - : ("CIFS spec" - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB36D-9AEA-11D5-BD16-0090272CCB31}") - :ClassName (resource_type) - :table (resources_types) - ) - :type (cifs) - ) - : ("URI spec" - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB36D-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (resource_type) - :table (resources_types) - :name ("URI spec") - ) - :type (uri) - ) - : ("SMTP spec" - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB36E-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (resource_type) - :table (resources_types) - :name ("SMTP spec") - ) - :type (smtp) - ) - : ("FTP spec" - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB36F-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (resource_type) - :table (resources_types) - :name ("FTP spec") - ) - :type (ftp) - ) - ) - :protocols (protocols - : (ENC-HTTP - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By (CheckPoint) - :From (CheckPoint) - ) - :chkpf_uid ("{8294399D-9333-4774-B3DA-C00EACEF3211}") - :ClassName (tcp_protocol) - :table (protocols) - ) - :handler () - :res_type (ReferenceObject - :Name ("URI spec") - :Table (resources_types) - :Uid ("{97AEB36D-9AEA-11D5-BD16-0090272CCB30}") - ) - :type (tcp_protocol) - ) - : (SSL_V3 - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By (CheckPoint) - :From (CheckPoint) - ) - :chkpf_uid ("{16A704F7-7BD7-49BD-A52A-525AAEDAE7AB}") - :ClassName (tcp_protocol) - :table (protocols) - ) - :handler (ssl_v3_code) - :res_type (none) - :type (tcp_protocol) - ) - : (FTP_BASIC - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By (CheckPoint) - :From (CheckPoint) - ) - :chkpf_uid ("{DE35C446-D028-4451-9095-84597C97B78A}") - :ClassName (tcp_protocol) - :table (protocols) - ) - :handler (ftp_reduced) - :res_type (ReferenceObject - :Name ("FTP spec") - :Table (resources_types) - :Uid ("{97AEB36F-9AEA-11D5-BD16-0090272CCB30}") - ) - :type (tcp_protocol) - ) - : (SSH2 - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By (CheckPoint) - :From (CheckPoint) - ) - :chkpf_uid ("{55F4C5D7-60D9-44B3-9BD4-C3F76B7C8360}") - :ClassName (tcp_protocol) - :table (protocols) - ) - :handler (ssh2_code) - :res_type (none) - :type (tcp_protocol) - ) - : (CitrixICA - :AdminInfo ( - :LastModified ( - :Time ("Thu Apr 10 17:36:34 2003") - :By (CheckPoint) - :From (CheckPoint) - ) - :chkpf_uid ("{C59AA9F5-FF06-4A15-BB4F-945D7DAB69B7}") - :ClassName (tcp_protocol) - :table (protocols) - ) - :handler (citrix_ica_code) - :res_type (none) - :type (tcp_protocol) - ) - : (SQL_SLAMMER - :AdminInfo ( - :LastModified ( - :Time ("Thu Apr 10 17:36:34 2003") - :By (CheckPoint) - :From (CheckPoint) - ) - :chkpf_uid ("{A9B88863-0786-4961-B1E9-DDC2FA723135}") - :ClassName (udp_protocol) - :table (protocols) - ) - :handler (sql_worm_slammer) - :res_type (none) - :type (udp_protocol) - ) - : (FTP-BIDIR - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By (CheckPoint) - :From (CheckPoint) - ) - :chkpf_uid ("{8026ECE8-E867-4c4c-9E10-08AC73B709B1}") - :ClassName (tcp_protocol) - :table (protocols) - ) - :handler (ftp_bidir_code) - :res_type (ReferenceObject - :Name ("FTP spec") - :Table (resources_types) - :Uid ("{97AEB36F-9AEA-11D5-BD16-0090272CCB30}") - ) - :type (tcp_protocol) - ) - : (CIFS - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB373-9AEA-11D5-BD16-0090272CCB31}") - :ClassName (tcp_protocol) - :table (protocols) - ) - :handler () - :res_type (ReferenceObject - :Name ("CIFS spec") - :Table (resources_types) - :Uid ("{97AEB36D-9AEA-11D5-BD16-0090272CCB31}") - ) - :type (tcp_protocol) - ) - : (H.323_ANY - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By (CheckPoint) - :From (CheckPoint) - ) - :chkpf_uid ("{97AEB377-9AEA-11D5-BD16-0090272CCB35}") - :ClassName (tcp_protocol) - :table (protocols) - :name (H.323_ANY) - ) - :handler (h323_h225_code_any) - :res_type (none) - :type (tcp_protocol) - ) - : (H.323_RAS - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By (CheckPoint) - :From (CheckPoint) - ) - :chkpf_uid ("{97AEB378-9AEA-11D5-BD16-0090272CCB31}") - :ClassName (udp_protocol) - :table (protocols) - :name (H.323_RAS) - ) - :handler (h323_ras_code) - :res_type (none) - :type (udp_protocol) - ) - : (SIP_UDP - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By (CheckPoint) - :From (CheckPoint) - ) - :chkpf_uid ("{97AEB378-9AEA-11D5-BD16-0090272CCB37}") - :ClassName (udp_protocol) - :table (protocols) - :name (SIP_UDP) - ) - :handler (sip_manager) - :res_type (none) - :type (udp_protocol) - ) - : (SIP_UDP_ANY - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By (CheckPoint) - :From (CheckPoint) - ) - :chkpf_uid ("{97AEB378-9AEA-11D5-BD16-0090272CCB38}") - :ClassName (udp_protocol) - :table (protocols) - :name (SIP_UDP_ANY) - ) - :handler (sip_manager_any) - :res_type (none) - :type (udp_protocol) - ) - : (FTP - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB370-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (tcp_protocol) - :table (protocols) - :name (FTP) - ) - :handler (ftp_code) - :res_type (ReferenceObject - :Name ("FTP spec") - :Table (resources_types) - :Uid ("{97AEB36F-9AEA-11D5-BD16-0090272CCB30}") - ) - :type (tcp_protocol) - ) - : (FTP-PORT - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB371-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (tcp_protocol) - :table (protocols) - :name (FTP-PORT) - ) - :handler (ftp_port_code) - :res_type (ReferenceObject - :Name ("FTP spec") - :Table (resources_types) - :Uid ("{97AEB36F-9AEA-11D5-BD16-0090272CCB30}") - ) - :type (tcp_protocol) - ) - : (FTP-PASV - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB372-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (tcp_protocol) - :table (protocols) - :name (FTP-PASV) - ) - :handler (ftp_pasv_code) - :res_type (ReferenceObject - :Name ("FTP spec") - :Table (resources_types) - :Uid ("{97AEB36F-9AEA-11D5-BD16-0090272CCB30}") - ) - :type (tcp_protocol) - ) - : (HTTP - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB373-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (tcp_protocol) - :table (protocols) - :name (HTTP) - ) - :handler () - :res_type (ReferenceObject - :Name ("URI spec") - :Table (resources_types) - :Uid ("{97AEB36D-9AEA-11D5-BD16-0090272CCB30}") - ) - :type (tcp_protocol) - ) - : (SMTP - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB374-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (tcp_protocol) - :table (protocols) - :name (SMTP) - ) - :handler () - :res_type (ReferenceObject - :Name ("SMTP spec") - :Table (resources_types) - :Uid ("{97AEB36E-9AEA-11D5-BD16-0090272CCB30}") - ) - :type (tcp_protocol) - ) - : (RSHELL - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB375-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (tcp_protocol) - :table (protocols) - :name (RSHELL) - ) - :handler (rshstderr_code) - :res_type (none) - :type (tcp_protocol) - ) - : (SQLNET2 - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB376-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (tcp_protocol) - :table (protocols) - :name (SQLNET2) - ) - :handler (sqlnet_code) - :res_type (none) - :type (tcp_protocol) - ) - : (H.323 - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB377-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (tcp_protocol) - :table (protocols) - :name (H.323) - ) - :handler (h323_h225_code) - :res_type (none) - :type (tcp_protocol) - ) - : (DNS_UDP - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB378-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (udp_protocol) - :table (protocols) - :name (DNS_UDP) - ) - :handler (dns_verification_code) - :res_type (none) - :type (udp_protocol) - ) - : (DNS_TCP - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB379-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (tcp_protocol) - :table (protocols) - :name (DNS_TCP) - ) - :handler (dns_verification_code) - :res_type (none) - :type (tcp_protocol) - ) - : (PNA - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB37A-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (tcp_protocol) - :table (protocols) - :name (PNA) - ) - :handler (raudio_code) - :res_type (none) - :type (tcp_protocol) - ) - : (RTSP - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB37B-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (tcp_protocol) - :table (protocols) - :name (RTSP) - ) - :handler (rtsp_code) - :res_type (none) - :type (tcp_protocol) - ) - : (NetShow - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB37C-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (tcp_protocol) - :table (protocols) - :name (NetShow) - ) - :handler (netshow_code) - :res_type (none) - :type (tcp_protocol) - ) - : (CP-DHCP-request - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{71878CD2-B8A9-11D5-BB1D-D496C1818686}") - :ClassName (udp_protocol) - :table (protocols) - :name (CP-DHCP-request) - ) - :handler (dhcp_request_code) - :res_type (none) - :type (udp_protocol) - ) - : (CP-DHCP-reply - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{71879F1A-B8A9-11D5-BB1D-D496C1818686}") - :ClassName (udp_protocol) - :table (protocols) - :name (CP-DHCP-reply) - ) - :handler (dhcp_reply_code) - :res_type (none) - :type (udp_protocol) - ) - : (FreeTel - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB37E-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (udp_protocol) - :table (protocols) - :name (FreeTel) - ) - :handler (freetel_code) - :res_type (none) - :type (udp_protocol) - ) - : (BackWeb - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB37F-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (other_protocol) - :table (protocols) - :name (BackWeb) - ) - :handler (backweb_code) - :res_type (none) - :type (other_protocol) - ) - : (WinFrame - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB380-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (tcp_protocol) - :table (protocols) - :name (WinFrame) - ) - :handler (winframe_code) - :res_type (none) - :type (tcp_protocol) - ) - : (FW1_CVP - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB381-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (tcp_protocol) - :table (protocols) - :name (FW1_CVP) - ) - :handler (cvp_code) - :res_type (none) - :type (tcp_protocol) - ) - : (MSEXCHANGE - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB382-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (dcerpc_protocol) - :table (protocols) - :name (MSEXCHANGE) - ) - :handler (exchange_code) - :res_type (none) - :type (dcerpc_protocol) - ) - : (Snmp-Read - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB383-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (udp_protocol) - :table (protocols) - :name (Snmp-Read) - ) - :handler (snmp_ro_code) - :res_type (none) - :type (udp_protocol) - ) - : (NBNAME - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB384-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (udp_protocol) - :table (protocols) - :name (NBNAME) - ) - :handler (nbname_code) - :res_type (none) - :type (udp_protocol) - ) - : (NBDATAGRAM - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB385-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (udp_protocol) - :table (protocols) - :name (NBDATAGRAM) - ) - :handler (nbdatagram_code) - :res_type (none) - :type (udp_protocol) - ) - : (IIOP - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB386-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (tcp_protocol) - :table (protocols) - :name (IIOP) - ) - :handler (iiop_code) - :res_type (none) - :type (tcp_protocol) - ) - : (INSPECT - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB387-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (tcp_protocol) - :table (protocols) - :name (INSPECT) - ) - :handler (INSPECT) - :res_type (none) - :type (tcp_protocol) - ) - ) - :services (services - : (FW1_ica_mgmt_tools - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:07 2001") - :By (CheckPoint) - :From (CheckPoint) - ) - :chkpf_uid ("{97AEB44E-9AEA-11D5-BD16-0090272CCB31}") - :ClassName (tcp_service) - :table (services) - ) - :delayed_sync_value (30) - :reload_proof (false) - :sync_on_cluster (true) - :use_delayed_sync (false) - :color (FireBrick) - :comments ("Check Point Internal CA Management Tools") - :enable_tcp_resource (false) - :etm_enabled (false) - :include_in_any (true) - :port (18265) - :proto_type () - :src_port () - :timeout (0) - :type (tcp) - ) - : (IPSO_Clustering_Mgmt_Protocol - :AdminInfo ( - :LastModified ( - :Time ("Thu Feb 13 07:43:26 2003") - :By (CheckPoint) - :From (CheckPoint) - ) - :chkpf_uid ("{BD824B60-5C5A-42E8-A8E6-348A35CEF8C4}") - :ClassName (tcp_service) - :table (services) - :Wiznum (-1) - ) - :color (black) - :comments ("used for distributing configuration changes among cluster members and cluster wide monitoring") - :delayed_sync_value (0) - :enable_tcp_resource (false) - :etm_enabled (false) - :include_in_any (true) - :port (1111) - :proto_type () - :reload_proof (true) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (Tcp) - :use_delayed_sync (false) - ) - : (microsoft-ds-udp - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:07 2001") - :By (CheckPoint) - :From (CheckPoint) - ) - :chkpf_uid ("{97AEB390-9AEA-11D5-BD16-0090272CCB31}") - :ClassName (udp_service) - :table (services) - ) - :delete_on_reply (false) - :reload_proof (false) - :sync_on_cluster (true) - :color (FireBrick) - :comments ("Microsoft CIFS over UDP") - :etm_enabled (false) - :include_in_any (true) - :port (445) - :proto_type () - :replies (true) - :replies_from_any_port (false) - :src_port () - :timeout (0) - :type (udp) - ) - : (ssh_version_2 - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By (CheckPoint) - :From (CheckPoint) - ) - :chkpf_uid ("{CD082D9A-44A6-4CEF-A17D-5541029ADFB3}") - :ClassName (tcp_service) - :table (services) - ) - :delayed_sync_value (30) - :reload_proof (false) - :sync_on_cluster (true) - :use_delayed_sync (false) - :color (Blue) - :comments ("Secure Shell, version 1.x block") - :enable_tcp_resource (false) - :etm_enabled (false) - :include_in_any (false) - :port (22) - :proto_type (ReferenceObject - :Name (SSH2) - :Table (protocols) - :Uid ("{55F4C5D7-60D9-44B3-9BD4-C3F76B7C8360}") - ) - :src_port () - :timeout (0) - :type (tcp) - ) - : (Citrix_ICA_printing - :AdminInfo ( - :chkpf_uid ("{0A3667B6-800B-49A9-A655-087CD970AC27}") - :ClassName (tcp_citrix_service) - :table (services) - :Deleteable (false) - :Renameable (false) - :Wiznum (-1) - :LastModified ( - :Time ("Sun Mar 30 14:42:57 2003") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :citrix_application_name (All_citrix_ICA_printing) - :color (black) - :comments ("Citrix ICA printing traffic") - :etm_enabled (false) - :is_printing (true) - :port (1494) - :proto_type () - :reload_proof (false) - :type (tcp_citrix) - ) - : (Citrix_ICA_Browsing - :AdminInfo ( - :chkpf_uid ("{E8C5AB78-F08D-437C-A9B1-BE4A8679D766}") - :ClassName (udp_service) - :table (services) - :Wiznum (-1) - :LastModified ( - :Time ("Sun Mar 30 14:49:31 2003") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :color (black) - :comments ("Tcp Service for general Citrix browsing") - :delete_on_reply (false) - :etm_enabled (false) - :include_in_any (false) - :port (1604) - :proto_type () - :reload_proof (false) - :replies (true) - :replies_from_any_port (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (Udp) - ) - : (GTPv0 - :AdminInfo ( - :chkpf_uid ("{3A5AD81B-3BFA-4396-97B2-2581B33790B5}") - :ClassName (udp_service) - :table (services) - :Wiznum (-1) - :Deleteable (false) - :Hidden (true) - :LastModified ( - :Time ("Tue Dec 24 12:37:31 2002") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :color (black) - :delete_on_reply (false) - :etm_enabled (false) - :proto_type () - :reload_proof (false) - :replies (true) - :replies_from_any_port (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :comments ("used only for log resolving") - :include_in_any (false) - :port (3386) - :type (Udp) - ) - : (GTPv1-C - :AdminInfo ( - :chkpf_uid ("{0A95FEAA-A655-484D-BE5E-E6D38A6937A5}") - :ClassName (udp_service) - :table (services) - :Wiznum (-1) - :Deleteable (false) - :Hidden (true) - :LastModified ( - :Time ("Tue Dec 24 10:47:41 2002") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :color (black) - :delete_on_reply (false) - :etm_enabled (false) - :proto_type () - :reload_proof (false) - :replies (true) - :replies_from_any_port (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :comments ("used only for log resolving") - :include_in_any (false) - :port (2123) - :type (Udp) - ) - : (GTPv1-U - :AdminInfo ( - :chkpf_uid ("{A1B5DB0A-FA8D-4821-B4DE-B7A8E9435EF6}") - :ClassName (udp_service) - :table (services) - :Wiznum (-1) - :Deleteable (false) - :Hidden (true) - :LastModified ( - :Time ("Tue Dec 24 10:48:43 2002") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :color (black) - :delete_on_reply (false) - :etm_enabled (false) - :proto_type () - :reload_proof (false) - :replies (true) - :replies_from_any_port (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :comments ("used only for log resolving") - :include_in_any (false) - :port (2152) - :type (Udp) - ) - : (Citrix_ICA - :AdminInfo ( - :chkpf_uid ("{986BAD5A-94D2-4A8C-81AA-DE98D3ECB5C6}") - :ClassName (tcp_service) - :table (services) - :Wiznum (-1) - :LastModified ( - :Time ("Sun Mar 30 14:48:11 2003") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :color (black) - :comments ("Citrix ICA general Service.") - :delayed_sync_value (30) - :enable_tcp_resource (false) - :etm_enabled (false) - :include_in_any (false) - :port (1494) - :proto_type (ReferenceObject - :Name (CitrixICA) - :Table (protocols) - :Uid ("{C59AA9F5-FF06-4A15-BB4F-945D7DAB69B7}") - ) - :reload_proof (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (Tcp) - :use_delayed_sync (false) - ) - : (Kerberos_v5_TCP - :AdminInfo ( - :chkpf_uid ("{8D807250-57EB-4051-9AEC-E6128260261B}") - :ClassName (tcp_service) - :table (services) - :Wiznum (-1) - :LastModified ( - :Time ("Thu Jan 09 15:58:26 2003") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :color (black) - :comments ("Kerberos authentication protocol (version 5)") - :delayed_sync_value (0) - :enable_tcp_resource (false) - :etm_enabled (false) - :include_in_any (true) - :port (88) - :proto_type () - :reload_proof (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (Tcp) - :use_delayed_sync (false) - ) - : (Kerberos_v5_UDP - :AdminInfo ( - :chkpf_uid ("{8C137030-A995-4E96-AAAE-5F5BC74E7B4E}") - :ClassName (udp_service) - :table (services) - :Wiznum (-1) - :LastModified ( - :Time ("Thu Jan 09 15:58:37 2003") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :color (black) - :comments ("Kerberos authentication protocol (version 5)") - :delete_on_reply (false) - :etm_enabled (false) - :include_in_any (true) - :port (88) - :proto_type () - :reload_proof (false) - :replies (true) - :replies_from_any_port (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (Udp) - ) - : (ssl_v3 - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By (CheckPoint) - :From (CheckPoint) - ) - :chkpf_uid ("{69815F35-2A03-4121-8335-23A337DCE927}") - :ClassName (tcp_service) - :table (services) - ) - :delayed_sync_value (30) - :reload_proof (false) - :sync_on_cluster (true) - :use_delayed_sync (false) - :color (Blue) - :comments ("SSL version 3, droping anything else.") - :enable_tcp_resource (false) - :etm_enabled (false) - :include_in_any (false) - :port (443) - :proto_type (ReferenceObject - :Name (SSL_V3) - :Table (protocols) - :Uid ("{16A704F7-7BD7-49BD-A52A-525AAEDAE7AB}") - ) - :src_port () - :timeout (0) - :type (tcp) - ) - : (SWTP_SMS - :AdminInfo ( - :chkpf_uid ("{6A40F044-296B-4611-8105-FE83284BAF03}") - :ClassName (udp_service) - :table (services) - :Wiznum (-1) - :LastModified ( - :Time ("Wed Apr 09 22:29:17 2003") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :color (black) - :comments ("VPN-1 embedded / SofaWare Management Server (SMS)") - :delete_on_reply (false) - :etm_enabled (false) - :include_in_any (true) - :port (9282) - :proto_type () - :reload_proof (false) - :replies (true) - :replies_from_any_port (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (Udp) - ) - : (SWTP_Gateway - :AdminInfo ( - :chkpf_uid ("{1649FC50-B2B3-4A95-9839-802DA7108629}") - :ClassName (udp_service) - :table (services) - :Wiznum (-1) - :LastModified ( - :Time ("Mon Oct 13 10:23:43 2003") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :color (black) - :comments ("VPN-1 Embedded/SofaWare commands") - :delete_on_reply (false) - :etm_enabled (false) - :include_in_any (true) - :port (9281) - :proto_type () - :reload_proof (false) - :replies (true) - :replies_from_any_port (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (Udp) - ) - : (DCOM-RemoteActivation - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 15 14:54:08 2003") - :By (CheckPoint) - :From (CheckPoint) - ) - :chkpf_uid ("{5C66B970-E289-4B39-89EA-4F0F19A389D7}") - :ClassName (dcerpc_service) - :table (services) - ) - :color (black) - :comments ("DCOM Remote Activation") - :etm_enabled (false) - :proto_type () - :reload_proof (false) - :type (dcerpc) - :uuid (4d9f4ab8-7d1c-11cf-861e-0020af6e7c57) - ) - : (ALL_DCE_RPC - :AdminInfo ( - :chkpf_uid ("{3D0D46B6-4DDB-43E0-9FAA-C969DBC3E19F}") - :ClassName (dcerpc_service) - :table (services) - :Wiznum (-1) - :LastModified ( - :Time ("Thu May 1 08:34:11 2003") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :color (red) - :comments ("Special Service For Allowing All DCE-RPC Services") - :etm_enabled (false) - :proto_type () - :reload_proof (false) - :type (DceRpc) - :uuid (00000000-0000-0000-0000-000000000000) - ) - : (MSNP - :AdminInfo ( - :chkpf_uid ("{D18F244B-0B13-4FB8-AA2F-D966EEFFB6B3}") - :ClassName (tcp_service) - :table (services) - :LastModified ( - :Time ("Tue Oct 22 13:25:25 2002") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :delayed_sync_value (30) - :use_delayed_sync (false) - :color (black) - :comments ("MSN Messenger") - :enable_tcp_resource (false) - :etm_enabled (false) - :include_in_any (true) - :port (1863) - :proto_type () - :reload_proof (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (tcp) - ) - : (ttdbserverd - :AdminInfo ( - :chkpf_uid ("{320ADBC3-F4F0-4254-A7A4-79DEE1726B8C}") - :ClassName (rpc_service) - :table (services) - :Wiznum (-1) - :LastModified ( - :Time ("Mon Oct 14 15:45:43 2002") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :color (black) - :comments ("ToolTalk database server") - :etm_enabled (false) - :port (100083) - :proto_type () - :reload_proof (false) - :type (Rpc) - ) - : (cmsd - :AdminInfo ( - :chkpf_uid ("{968C527C-2191-4BEA-ABF3-F41DA07F20DC}") - :ClassName (rpc_service) - :table (services) - :Wiznum (-1) - :LastModified ( - :Time ("Mon Oct 14 15:46:27 2002") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :color (black) - :comments ("Calendar Manager Service Daemon") - :etm_enabled (false) - :port (100068) - :proto_type () - :reload_proof (false) - :type (Rpc) - ) - : (statd - :AdminInfo ( - :chkpf_uid ("{FC4E8697-6C1F-4152-94F1-C9A2AE21EF6E}") - :ClassName (rpc_service) - :table (services) - :Wiznum (-1) - :LastModified ( - :Time ("Mon Oct 14 15:46:44 2002") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :color (black) - :comments ("Network status monitor daemon") - :etm_enabled (false) - :port (100024) - :proto_type () - :reload_proof (false) - :type (Rpc) - ) - : (sadmind - :AdminInfo ( - :chkpf_uid ("{5FF55D69-74F8-46E0-9D21-A2163A906D76}") - :ClassName (rpc_service) - :table (services) - :Wiznum (-1) - :LastModified ( - :Time ("Mon Oct 14 15:47:08 2002") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :color (black) - :comments ("Solstice AdminSuite") - :etm_enabled (false) - :port (100232) - :proto_type () - :reload_proof (false) - :type (Rpc) - ) - : (cachefsd - :AdminInfo ( - :chkpf_uid ("{F4C95E3E-A820-4B35-B35E-0AFB703EB11E}") - :ClassName (rpc_service) - :table (services) - :Wiznum (-1) - :LastModified ( - :Time ("Mon Oct 14 15:47:36 2002") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :color (burlywood4) - :comments ("SUN NFS/RPC file system cachefs daemon") - :etm_enabled (false) - :port (100235) - :proto_type () - :reload_proof (false) - :type (Rpc) - ) - : (snmpXdmid - :AdminInfo ( - :chkpf_uid ("{953DFC46-7EAD-4D97-9ADE-6560D79DB563}") - :ClassName (rpc_service) - :table (services) - :Wiznum (-1) - :LastModified ( - :Time ("Mon Oct 14 15:48:02 2002") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :color (burlywood4) - :comments ("SUN SNMP to DMI mapper daemon") - :etm_enabled (false) - :port (100249) - :proto_type () - :reload_proof (false) - :type (Rpc) - ) - : (ICQ_locator - :AdminInfo ( - :chkpf_uid ("{BBEC6807-808D-49B7-B8DC-54C5A655D392}") - :ClassName (udp_service) - :table (services) - :Wiznum (-1) - :LastModified ( - :Time ("Sun Dec 08 12:36:19 2002") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :color (black) - :comments ("Mirabilis ICQ versions") - :delete_on_reply (false) - :etm_enabled (false) - :include_in_any (true) - :port (4000) - :proto_type () - :reload_proof (false) - :replies (true) - :replies_from_any_port (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (Udp) - ) - : (MSN_Messenger_1863_UDP - :AdminInfo ( - :chkpf_uid ("{0094AAC2-A29E-4D04-B86C-F31F63DFFAE2}") - :ClassName (udp_service) - :table (services) - :Wiznum (-1) - :LastModified ( - :Time ("Sun Dec 08 12:37:27 2002") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :color (black) - :comments ("Microsoft Network Messenger UDP") - :delete_on_reply (false) - :etm_enabled (false) - :include_in_any (true) - :port (1863) - :proto_type () - :reload_proof (false) - :replies (true) - :replies_from_any_port (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (Udp) - ) - : (MSN_Messenger_5190 - :AdminInfo ( - :chkpf_uid ("{0AC39B6A-701A-4C33-A88D-9EB0FECF9EF6}") - :ClassName (udp_service) - :table (services) - :Wiznum (-1) - :LastModified ( - :Time ("Sun Dec 08 12:38:08 2002") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :color (black) - :comments ("Microsoft Network Messenger") - :delete_on_reply (false) - :etm_enabled (false) - :include_in_any (true) - :port (5190) - :proto_type () - :reload_proof (false) - :replies (true) - :replies_from_any_port (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (Udp) - ) - : (MSN_Messenger_File_Transfer - :AdminInfo ( - :chkpf_uid ("{505BADAD-AE57-4584-9A4C-15987C093A32}") - :ClassName (tcp_service) - :table (services) - :Wiznum (-1) - :LastModified ( - :Time ("Sun Dec 08 12:39:01 2002") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :color (black) - :comments ("Microsoft Network Messenger File Transfer") - :delayed_sync_value (0) - :enable_tcp_resource (false) - :etm_enabled (false) - :include_in_any (true) - :port (6891-6900) - :proto_type () - :reload_proof (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (Tcp) - :use_delayed_sync (false) - ) - : (MSN_Messenger_Voice - :AdminInfo ( - :chkpf_uid ("{E3E6D587-3212-4FF4-86A1-D16093689E19}") - :ClassName (udp_service) - :table (services) - :Wiznum (-1) - :LastModified ( - :Time ("Sun Dec 08 12:39:30 2002") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :color (black) - :comments ("Microsoft Network Messenger Voice communication") - :delete_on_reply (false) - :etm_enabled (false) - :include_in_any (true) - :port (6901) - :proto_type () - :reload_proof (false) - :replies (true) - :replies_from_any_port (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (Udp) - ) - : (Yahoo_Messenger_messages - :AdminInfo ( - :chkpf_uid ("{24CD3A7C-AA2C-43D4-8EB6-FF1F070143EA}") - :ClassName (tcp_service) - :table (services) - :Wiznum (-1) - :LastModified ( - :Time ("Sun Dec 08 12:40:02 2002") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :color (black) - :comments ("Yahoo Messenger messages") - :delayed_sync_value (0) - :enable_tcp_resource (false) - :etm_enabled (false) - :include_in_any (true) - :port (5050) - :proto_type () - :reload_proof (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (Tcp) - :use_delayed_sync (false) - ) - : (Yahoo_Messenger_Voice_Chat_TCP - :AdminInfo ( - :chkpf_uid ("{C2639E22-FD63-4520-99F7-A70215B95874}") - :ClassName (tcp_service) - :table (services) - :Wiznum (-1) - :LastModified ( - :Time ("Thu Dec 12 14:03:50 2002") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :color (black) - :comments ("Yahoo Messenger Voice Chat") - :delayed_sync_value (0) - :enable_tcp_resource (false) - :etm_enabled (false) - :include_in_any (false) - :port (5000-5001) - :proto_type () - :reload_proof (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (Tcp) - :use_delayed_sync (false) - ) - : (Yahoo_Messenger_Voice_Chat_UDP - :AdminInfo ( - :chkpf_uid ("{C98BB09A-B04F-437C-AD1A-6C8261831B87}") - :ClassName (udp_service) - :table (services) - :Wiznum (-1) - :LastModified ( - :Time ("Sun Dec 08 12:41:22 2002") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :color (black) - :comments ("Yahoo Messenger Voice Chat") - :delete_on_reply (false) - :etm_enabled (false) - :include_in_any (true) - :port (5000-5010) - :proto_type () - :reload_proof (false) - :replies (true) - :replies_from_any_port (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (Udp) - ) - : (Yahoo_Messenger_Webcams - :AdminInfo ( - :chkpf_uid ("{910F509F-8F2A-452D-BC15-E51F8CC1694C}") - :ClassName (tcp_service) - :table (services) - :Wiznum (-1) - :LastModified ( - :Time ("Sun Dec 08 12:41:53 2002") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :color (black) - :comments ("Yahoo Messenger Webcams video") - :delayed_sync_value (0) - :enable_tcp_resource (false) - :etm_enabled (false) - :include_in_any (true) - :port (5100) - :proto_type () - :reload_proof (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (Tcp) - :use_delayed_sync (false) - ) - : (Direct_Connect_TCP - :AdminInfo ( - :chkpf_uid ("{D02080C1-B225-4DA0-987B-28B3A551B8C9}") - :ClassName (tcp_service) - :table (services) - :Wiznum (-1) - :LastModified ( - :Time ("Sun Dec 08 12:42:27 2002") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :color (black) - :comments ("Direct Connect P2P application. Used also by other clients") - :delayed_sync_value (0) - :enable_tcp_resource (false) - :etm_enabled (false) - :include_in_any (true) - :port (411-412) - :proto_type () - :reload_proof (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (Tcp) - :use_delayed_sync (false) - ) - : (Direct_Connect_UDP - :AdminInfo ( - :chkpf_uid ("{64C3AD3F-69D2-4EC1-B843-5DF030C70ABF}") - :ClassName (udp_service) - :table (services) - :Wiznum (-1) - :LastModified ( - :Time ("Sun Dec 08 12:42:59 2002") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :color (black) - :comments ("Direct Connect P2P application. Used also by other clients") - :delete_on_reply (false) - :etm_enabled (false) - :include_in_any (true) - :port (411-412) - :proto_type () - :reload_proof (false) - :replies (true) - :replies_from_any_port (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (Udp) - ) - : (eDonkey_4661 - :AdminInfo ( - :chkpf_uid ("{760D9035-1C76-4C5C-B929-BA1DC6685D6F}") - :ClassName (tcp_service) - :table (services) - :Wiznum (-1) - :LastModified ( - :Time ("Sun Dec 08 12:43:26 2002") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :color (black) - :comments ("eDonkey protocol. Used also by other clients.") - :delayed_sync_value (0) - :enable_tcp_resource (false) - :etm_enabled (false) - :include_in_any (true) - :port (4661) - :proto_type () - :reload_proof (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (Tcp) - :use_delayed_sync (false) - ) - : (eDonkey_4662 - :AdminInfo ( - :chkpf_uid ("{7115E261-185C-4487-AA18-84F8C275D186}") - :ClassName (tcp_service) - :table (services) - :Wiznum (-1) - :LastModified ( - :Time ("Sun Dec 08 12:43:49 2002") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :color (black) - :comments ("eDonkey protocol. Used also by other clients.") - :delayed_sync_value (0) - :enable_tcp_resource (false) - :etm_enabled (false) - :include_in_any (true) - :port (4662) - :proto_type () - :reload_proof (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (Tcp) - :use_delayed_sync (false) - ) - : (GNUtella_rtr_TCP - :AdminInfo ( - :chkpf_uid ("{B1189907-B9EB-4A21-8B38-1D3E5C6C06D0}") - :ClassName (tcp_service) - :table (services) - :Wiznum (-1) - :LastModified ( - :Time ("Sun Dec 08 12:44:57 2002") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :color (black) - :comments ("Also used by: BearShare, ToadNode, Gnucleus, Xolox, LimeWire") - :delayed_sync_value (0) - :enable_tcp_resource (false) - :etm_enabled (false) - :include_in_any (true) - :port (6347) - :proto_type () - :reload_proof (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (Tcp) - :use_delayed_sync (false) - ) - : (GNUtella_rtr_UDP - :AdminInfo ( - :chkpf_uid ("{1B4543A3-579E-4CC7-8F57-4387C37A6815}") - :ClassName (udp_service) - :table (services) - :Wiznum (-1) - :LastModified ( - :Time ("Sun Dec 08 12:45:16 2002") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :color (black) - :comments ("Also used by: BearShare, ToadNode, Gnucleus, Xolox, LimeWire") - :delete_on_reply (false) - :etm_enabled (false) - :include_in_any (true) - :port (6347) - :proto_type () - :reload_proof (false) - :replies (true) - :replies_from_any_port (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (Udp) - ) - : (GNUtella_TCP - :AdminInfo ( - :chkpf_uid ("{CDEF1FEB-485E-4929-942E-011DE8318E56}") - :ClassName (tcp_service) - :table (services) - :Wiznum (-1) - :LastModified ( - :Time ("Sun Dec 08 12:45:56 2002") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :color (black) - :comments ("Also used by: BearShare, ToadNode, Gnucleus, Xolox, LimeWire") - :delayed_sync_value (0) - :enable_tcp_resource (false) - :etm_enabled (false) - :include_in_any (true) - :port (6346) - :proto_type () - :reload_proof (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (Tcp) - :use_delayed_sync (false) - ) - : (GNUtella_UDP - :AdminInfo ( - :chkpf_uid ("{8EB18480-2690-4520-AE88-412BF5CE94E3}") - :ClassName (udp_service) - :table (services) - :Wiznum (-1) - :LastModified ( - :Time ("Sun Dec 08 12:46:33 2002") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :color (black) - :comments ("Also used by: BearShare, ToadNode, Gnucleus, Xolox, LimeWire") - :delete_on_reply (false) - :etm_enabled (false) - :include_in_any (true) - :port (6346) - :proto_type () - :reload_proof (false) - :replies (true) - :replies_from_any_port (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (Udp) - ) - : (Hotline_client - :AdminInfo ( - :chkpf_uid ("{B45556D9-5E0B-46F4-9C35-ED7D82BEC43D}") - :ClassName (tcp_service) - :table (services) - :Wiznum (-1) - :LastModified ( - :Time ("Sun Dec 08 12:47:07 2002") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :color (black) - :comments ("Hotline client connections") - :delayed_sync_value (0) - :enable_tcp_resource (false) - :etm_enabled (false) - :include_in_any (true) - :port (5500-5503) - :proto_type () - :reload_proof (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (Tcp) - :use_delayed_sync (false) - ) - : (Hotline_tracker - :AdminInfo ( - :chkpf_uid ("{D6B64DF2-4803-4D79-9794-793D18B277D8}") - :ClassName (udp_service) - :table (services) - :Wiznum (-1) - :LastModified ( - :Time ("Sun Dec 08 12:47:41 2002") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :color (black) - :comments ("Hotline tracker connections") - :delete_on_reply (false) - :etm_enabled (false) - :include_in_any (true) - :port (5499) - :proto_type () - :reload_proof (false) - :replies (true) - :replies_from_any_port (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (Udp) - ) - : (Napster_Client_6600-6699 - :AdminInfo ( - :chkpf_uid ("{3BB26988-E0A5-45D6-8018-D4D4DE8B96FA}") - :ClassName (tcp_service) - :table (services) - :Wiznum (-1) - :LastModified ( - :Time ("Sun Dec 08 12:48:46 2002") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :color (black) - :comments ("Napster clients. Also used by: WinMX") - :delayed_sync_value (0) - :enable_tcp_resource (false) - :etm_enabled (false) - :include_in_any (false) - :port (6600-6699) - :proto_type () - :reload_proof (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (Tcp) - :use_delayed_sync (false) - ) - : (Napster_directory_4444 - :AdminInfo ( - :chkpf_uid ("{741A5B0E-3788-4284-91A1-819E99D9ED96}") - :ClassName (tcp_service) - :table (services) - :Wiznum (-1) - :LastModified ( - :Time ("Sun Dec 08 12:49:50 2002") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :color (black) - :comments ("Napster directory connections") - :delayed_sync_value (0) - :enable_tcp_resource (false) - :etm_enabled (false) - :include_in_any (true) - :port (4444) - :proto_type () - :reload_proof (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (Tcp) - :use_delayed_sync (false) - ) - : (Napster_directory_5555 - :AdminInfo ( - :chkpf_uid ("{8287D6D8-3B6B-4824-8F2D-18BC570EC9B2}") - :ClassName (tcp_service) - :table (services) - :Wiznum (-1) - :LastModified ( - :Time ("Sun Dec 08 12:50:15 2002") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :color (black) - :comments ("Napster directory connections") - :delayed_sync_value (0) - :enable_tcp_resource (false) - :etm_enabled (false) - :include_in_any (true) - :port (5555) - :proto_type () - :reload_proof (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (Tcp) - :use_delayed_sync (false) - ) - : (Napster_directory_6666 - :AdminInfo ( - :chkpf_uid ("{1EF8FC95-FF10-414B-AF76-C0BCC2CD711E}") - :ClassName (tcp_service) - :table (services) - :Wiznum (-1) - :LastModified ( - :Time ("Sun Dec 08 12:50:49 2002") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :color (black) - :comments ("Napster directory connections") - :delayed_sync_value (0) - :enable_tcp_resource (false) - :etm_enabled (false) - :include_in_any (false) - :port (6666) - :proto_type () - :reload_proof (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (Tcp) - :use_delayed_sync (false) - ) - : (Napster_directory_7777 - :AdminInfo ( - :chkpf_uid ("{182B1D39-54B6-4E2F-BAE8-2D8021D52206}") - :ClassName (tcp_service) - :table (services) - :Wiznum (-1) - :LastModified ( - :Time ("Sun Dec 08 12:51:15 2002") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :color (black) - :comments ("Napster directory connections") - :delayed_sync_value (0) - :enable_tcp_resource (false) - :etm_enabled (false) - :include_in_any (true) - :port (7777) - :proto_type () - :reload_proof (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (Tcp) - :use_delayed_sync (false) - ) - : (Napster_directory_8888_primary - :AdminInfo ( - :chkpf_uid ("{BE51561E-7876-4C70-9546-0914AE737F6E}") - :ClassName (tcp_service) - :table (services) - :Wiznum (-1) - :LastModified ( - :Time ("Sun Dec 08 12:51:47 2002") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :color (black) - :comments ("Napster directory connections (Primary)") - :delayed_sync_value (0) - :enable_tcp_resource (false) - :etm_enabled (false) - :include_in_any (true) - :port (8888) - :proto_type () - :reload_proof (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (Tcp) - :use_delayed_sync (false) - ) - : (Napster_redirector - :AdminInfo ( - :chkpf_uid ("{3FD0D58A-9759-4686-B103-D177ADFC7193}") - :ClassName (tcp_service) - :table (services) - :Wiznum (-1) - :LastModified ( - :Time ("Sun Dec 08 12:52:06 2002") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :color (black) - :comments () - :delayed_sync_value (0) - :enable_tcp_resource (false) - :etm_enabled (false) - :include_in_any (true) - :port (8875) - :proto_type () - :reload_proof (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (Tcp) - :use_delayed_sync (false) - ) - : (Blubster - :AdminInfo ( - :chkpf_uid ("{C86F055D-31AD-4430-B12C-1094A86C673C}") - :ClassName (udp_service) - :table (services) - :Wiznum (-1) - :LastModified ( - :Time ("Sun Dec 08 12:52:35 2002") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :color (black) - :comments ("Uses MANOLITO protocol") - :delete_on_reply (false) - :etm_enabled (false) - :include_in_any (true) - :port (41170) - :proto_type () - :reload_proof (false) - :replies (true) - :replies_from_any_port (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (Udp) - ) - : (GoToMyPC - :AdminInfo ( - :chkpf_uid ("{2D89310C-5761-4213-BEF5-C81BB5677E44}") - :ClassName (tcp_service) - :table (services) - :Wiznum (-1) - :LastModified ( - :Time ("Sun Dec 08 12:52:59 2002") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :color (black) - :comments ("Remote Computer Access & Sharing application, also uses HTTP and HTTPS") - :delayed_sync_value (0) - :enable_tcp_resource (false) - :etm_enabled (false) - :include_in_any (true) - :port (8200) - :proto_type () - :reload_proof (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (Tcp) - :use_delayed_sync (false) - ) - : (iMesh - :AdminInfo ( - :chkpf_uid ("{01E9FC32-73DF-43D5-9CD4-4F91B6A5C711}") - :ClassName (tcp_service) - :table (services) - :Wiznum (-1) - :LastModified ( - :Time ("Sun Dec 08 12:53:25 2002") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :color (black) - :comments ("This port also used by many trojans and the upnp service") - :delayed_sync_value (0) - :enable_tcp_resource (false) - :etm_enabled (false) - :include_in_any (true) - :port (5000) - :proto_type () - :reload_proof (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (Tcp) - :use_delayed_sync (false) - ) - : (Madster - :AdminInfo ( - :chkpf_uid ("{B863EC35-604F-4DA1-8E63-82A7903D2C1C}") - :ClassName (tcp_service) - :table (services) - :Wiznum (-1) - :LastModified ( - :Time ("Sun Dec 08 12:54:13 2002") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :color (black) - :comments ("Formerly called Aimster") - :delayed_sync_value (0) - :enable_tcp_resource (false) - :etm_enabled (false) - :include_in_any (true) - :port (5025) - :proto_type () - :reload_proof (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (Tcp) - :use_delayed_sync (false) - ) - : (RAT - :AdminInfo ( - :chkpf_uid ("{B236D830-9615-4578-B6E2-B0B44C45FDA0}") - :ClassName (tcp_service) - :table (services) - :Wiznum (-1) - :LastModified ( - :Time ("Tue Jan 07 18:21:52 2003") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :color ("deep pink") - :comments ("RAT trojan (Remote Administration Tool)") - :delayed_sync_value (0) - :enable_tcp_resource (false) - :etm_enabled (false) - :include_in_any (true) - :port (1097-1098) - :proto_type () - :reload_proof (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (Tcp) - :use_delayed_sync (false) - ) - : (Multidropper - :AdminInfo ( - :chkpf_uid ("{E38E4DEA-A610-4416-BF44-6F4E45E95E70}") - :ClassName (tcp_service) - :table (services) - :Wiznum (-1) - :LastModified ( - :Time ("Tue Jan 07 18:28:06 2003") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :color ("deep pink") - :comments ("Multidropper trojan") - :delayed_sync_value (0) - :enable_tcp_resource (false) - :etm_enabled (false) - :include_in_any (true) - :port (1035) - :proto_type () - :reload_proof (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (Tcp) - :use_delayed_sync (false) - ) - : (Kaos - :AdminInfo ( - :chkpf_uid ("{10F56849-2E03-40DD-9CF7-56AEE2CFA57F}") - :ClassName (tcp_service) - :table (services) - :Wiznum (-1) - :LastModified ( - :Time ("Tue Jan 07 18:29:24 2003") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :color ("deep pink") - :comments ("Kaos trojan") - :delayed_sync_value (0) - :enable_tcp_resource (false) - :etm_enabled (false) - :include_in_any (true) - :port (1212) - :proto_type () - :reload_proof (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (Tcp) - :use_delayed_sync (false) - ) - : (Connect-Back_Backdoor - :AdminInfo ( - :chkpf_uid ("{E0C17142-433D-40A7-9EAA-E1D5EBA40D2E}") - :ClassName (tcp_service) - :table (services) - :Wiznum (-1) - :LastModified ( - :Time ("Tue Jan 07 18:32:26 2003") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :color (magenta) - :comments ("Also used by SkyDance trojan") - :delayed_sync_value (0) - :enable_tcp_resource (false) - :etm_enabled (false) - :include_in_any (true) - :port (4000) - :proto_type () - :reload_proof (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (Tcp) - :use_delayed_sync (false) - ) - : (DerSphere - :AdminInfo ( - :chkpf_uid ("{8055B0DE-DACE-4D18-91F4-F39915B7ABA8}") - :ClassName (tcp_service) - :table (services) - :Wiznum (-1) - :LastModified ( - :Time ("Tue Jan 07 18:34:45 2003") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :color (magenta) - :comments ("Also used by: Direct Connection,Connecter,Insane Network trojans") - :delayed_sync_value (0) - :enable_tcp_resource (false) - :etm_enabled (false) - :include_in_any (true) - :port (1000) - :proto_type () - :reload_proof (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (Tcp) - :use_delayed_sync (false) - ) - : (Freak2k - :AdminInfo ( - :chkpf_uid ("{08DA33FF-BC5F-402A-9865-BEE8FEE69422}") - :ClassName (tcp_service) - :table (services) - :Wiznum (-1) - :LastModified ( - :Time ("Tue Jan 07 18:36:23 2003") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :color (magenta) - :comments ("Also used by: Freak88,NetSnooper Gold trojans") - :delayed_sync_value (0) - :enable_tcp_resource (false) - :etm_enabled (false) - :include_in_any (true) - :port (7001) - :proto_type () - :reload_proof (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (Tcp) - :use_delayed_sync (false) - ) - : (Jade - :AdminInfo ( - :chkpf_uid ("{C2F963B0-DB3C-42D5-B0F2-A2A7BC0D378D}") - :ClassName (tcp_service) - :table (services) - :Wiznum (-1) - :LastModified ( - :Time ("Tue Jan 07 18:40:18 2003") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :color (magenta) - :comments ("Also used by: Latinus,NetSpy,RAT trojans and K Display Manager") - :delayed_sync_value (0) - :enable_tcp_resource (false) - :etm_enabled (false) - :include_in_any (true) - :port (1024) - :proto_type () - :reload_proof (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (Tcp) - :use_delayed_sync (false) - ) - : (GateCrasher - :AdminInfo ( - :chkpf_uid ("{81B90130-2A31-45CD-8092-DC492B116CA9}") - :ClassName (tcp_service) - :table (services) - :Wiznum (-1) - :LastModified ( - :Time ("Tue Jan 07 18:41:23 2003") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :color ("deep pink") - :comments ("GateCrasher trojan") - :delayed_sync_value (0) - :enable_tcp_resource (false) - :etm_enabled (false) - :include_in_any (true) - :port (6970) - :proto_type () - :reload_proof (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (Tcp) - :use_delayed_sync (false) - ) - : (Kuang2 - :AdminInfo ( - :chkpf_uid ("{CE29B597-76B9-48AA-AC24-AE7E23C438ED}") - :ClassName (tcp_service) - :table (services) - :Wiznum (-1) - :LastModified ( - :Time ("Tue Jan 07 18:49:08 2003") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :color (magenta) - :comments ("Kuang2 trojan") - :delayed_sync_value (0) - :enable_tcp_resource (false) - :etm_enabled (false) - :include_in_any (true) - :port (17300) - :proto_type () - :reload_proof (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (Tcp) - :use_delayed_sync (false) - ) - : (WinHole - :AdminInfo ( - :chkpf_uid ("{25AC306E-1FC9-4E3E-BF66-4A48473CAF3F}") - :ClassName (tcp_service) - :table (services) - :Wiznum (-1) - :LastModified ( - :Time ("Tue Jan 07 18:50:10 2003") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :color ("deep pink") - :comments ("WinHole trojan") - :delayed_sync_value (0) - :enable_tcp_resource (false) - :etm_enabled (false) - :include_in_any (true) - :port (1081) - :proto_type () - :reload_proof (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (Tcp) - :use_delayed_sync (false) - ) - : (RexxRave - :AdminInfo ( - :chkpf_uid ("{637B7F26-C4B2-4510-872E-5A10DE046CB4}") - :ClassName (udp_service) - :table (services) - :Wiznum (-1) - :LastModified ( - :Time ("Tue Jan 07 18:51:04 2003") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :color (magenta) - :comments ("RexxRave trojan") - :delete_on_reply (false) - :etm_enabled (false) - :include_in_any (true) - :port (1104) - :proto_type () - :reload_proof (false) - :replies (true) - :replies_from_any_port (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (Udp) - ) - : (ICKiller - :AdminInfo ( - :chkpf_uid ("{06233377-3454-489A-B9FB-2F2CA14B895B}") - :ClassName (tcp_service) - :table (services) - :Wiznum (-1) - :LastModified ( - :Time ("Tue Jan 07 18:52:06 2003") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :color (magenta) - :comments (ICKiller) - :delayed_sync_value (0) - :enable_tcp_resource (false) - :etm_enabled (false) - :include_in_any (true) - :port (1027) - :proto_type () - :reload_proof (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (Tcp) - :use_delayed_sync (false) - ) - : (HackaTack_31785 - :AdminInfo ( - :chkpf_uid ("{82BA0DD2-42E6-472D-8877-57F519175C14}") - :ClassName (tcp_service) - :table (services) - :Wiznum (-1) - :LastModified ( - :Time ("Tue Jan 07 18:59:17 2003") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :color ("deep pink") - :comments (HackaTack) - :delayed_sync_value (0) - :enable_tcp_resource (false) - :etm_enabled (false) - :include_in_any (true) - :port (31785) - :proto_type () - :reload_proof (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (Tcp) - :use_delayed_sync (false) - ) - : (HackaTack_31787 - :AdminInfo ( - :chkpf_uid ("{C693C8C1-78E3-450D-936E-AA3278190633}") - :ClassName (tcp_service) - :table (services) - :Wiznum (-1) - :LastModified ( - :Time ("Tue Jan 07 19:00:30 2003") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :color (magenta) - :comments ("HackaTack trojan") - :delayed_sync_value (0) - :enable_tcp_resource (false) - :etm_enabled (false) - :include_in_any (true) - :port (31787) - :proto_type () - :reload_proof (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (Tcp) - :use_delayed_sync (false) - ) - : (HackaTack_31788 - :AdminInfo ( - :chkpf_uid ("{B8D159DC-AA70-4CC5-9C5A-8C2AD3AA977E}") - :ClassName (tcp_service) - :table (services) - :Wiznum (-1) - :LastModified ( - :Time ("Tue Jan 07 19:02:02 2003") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :color ("deep pink") - :comments ("HackaTack trojan") - :delayed_sync_value (0) - :enable_tcp_resource (false) - :etm_enabled (false) - :include_in_any (true) - :port (31788) - :proto_type () - :reload_proof (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (Tcp) - :use_delayed_sync (false) - ) - : (HackaTack_31789 - :AdminInfo ( - :chkpf_uid ("{FF8EA038-34FD-4B7B-8A8A-8D6BF0A599FE}") - :ClassName (udp_service) - :table (services) - :Wiznum (-1) - :LastModified ( - :Time ("Tue Jan 07 19:03:49 2003") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :color (magenta) - :comments ("HackaTack trojan") - :delete_on_reply (false) - :etm_enabled (false) - :include_in_any (true) - :port (31789) - :proto_type () - :reload_proof (false) - :replies (true) - :replies_from_any_port (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (Udp) - ) - : (HackaTack_31792 - :AdminInfo ( - :chkpf_uid ("{26339B33-1C42-4E49-96E9-55770F6AF0CE}") - :ClassName (tcp_service) - :table (services) - :Wiznum (-1) - :LastModified ( - :Time ("Tue Jan 07 19:06:41 2003") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :color ("deep pink") - :comments ("HackaTack trojan") - :delayed_sync_value (0) - :enable_tcp_resource (false) - :etm_enabled (false) - :include_in_any (true) - :port (31792) - :proto_type () - :reload_proof (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (Tcp) - :use_delayed_sync (false) - ) - : (UltorsTrojan - :AdminInfo ( - :chkpf_uid ("{6E745536-B8C9-4DF5-BFD5-043E62013956}") - :ClassName (tcp_service) - :table (services) - :Wiznum (-1) - :LastModified ( - :Time ("Tue Jan 07 19:08:55 2003") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :color ("deep pink") - :comments ("Also used by: SubSeven Java client") - :delayed_sync_value (0) - :enable_tcp_resource (false) - :etm_enabled (false) - :include_in_any (true) - :port (1234) - :proto_type () - :reload_proof (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (Tcp) - :use_delayed_sync (false) - ) - : (NoBackO - :AdminInfo ( - :chkpf_uid ("{AA02E546-80D1-453A-91DC-49F606764451}") - :ClassName (udp_service) - :table (services) - :Wiznum (-1) - :LastModified ( - :Time ("Tue Jan 07 19:10:06 2003") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :color (magenta) - :comments ("NoBackO trojan") - :delete_on_reply (false) - :etm_enabled (false) - :include_in_any (true) - :port (1201) - :proto_type () - :reload_proof (false) - :replies (true) - :replies_from_any_port (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (Udp) - ) - : (InCommand - :AdminInfo ( - :chkpf_uid ("{230B24DF-1EFA-4A28-B7A4-87DFB79AFBA7}") - :ClassName (tcp_service) - :table (services) - :Wiznum (-1) - :LastModified ( - :Time ("Tue Jan 07 19:11:57 2003") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :color ("deep pink") - :comments ("Also used by: ICQ Nuke 98 trojan") - :delayed_sync_value (0) - :enable_tcp_resource (false) - :etm_enabled (false) - :include_in_any (true) - :port (1029) - :proto_type () - :reload_proof (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (Tcp) - :use_delayed_sync (false) - ) - : (Xanadu - :AdminInfo ( - :chkpf_uid ("{24DE2CDE-DFCD-4C9B-9124-492AC4BEDBA7}") - :ClassName (tcp_service) - :table (services) - :Wiznum (-1) - :LastModified ( - :Time ("Tue Jan 07 19:12:59 2003") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :color ("deep pink") - :comments ("Xanadu trojan") - :delayed_sync_value (0) - :enable_tcp_resource (false) - :etm_enabled (false) - :include_in_any (true) - :port (1031) - :proto_type () - :reload_proof (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (Tcp) - :use_delayed_sync (false) - ) - : (SubSeven - :AdminInfo ( - :chkpf_uid ("{E926E948-FAE7-4140-8FED-11426B1A32B9}") - :ClassName (tcp_service) - :table (services) - :Wiznum (-1) - :LastModified ( - :Time ("Tue Jan 07 19:16:01 2003") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :color (magenta) - :comments ("Also used by:Bad Blood,EGO,Lion,Ramen,Seeker,The Saint,Tftloader,Webhead trojans") - :delayed_sync_value (0) - :enable_tcp_resource (false) - :etm_enabled (false) - :include_in_any (true) - :port (27374) - :proto_type () - :reload_proof (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (Tcp) - :use_delayed_sync (false) - ) - : (HackaTack_31790 - :AdminInfo ( - :chkpf_uid ("{2176F91C-5FB4-4111-98BD-7D5D5B358FE0}") - :ClassName (tcp_service) - :table (services) - :Wiznum (-1) - :LastModified ( - :Time ("Tue Jan 07 19:16:21 2003") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :color ("deep pink") - :comments ("HackaTack trojan") - :delayed_sync_value (0) - :enable_tcp_resource (false) - :etm_enabled (false) - :include_in_any (true) - :port (31790) - :proto_type () - :reload_proof (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (Tcp) - :use_delayed_sync (false) - ) - : (Terrortrojan - :AdminInfo ( - :chkpf_uid ("{CC1D78CC-5FCE-4496-A78B-C37AA0622F7A}") - :ClassName (tcp_service) - :table (services) - :Wiznum (-1) - :LastModified ( - :Time ("Tue Jan 07 19:18:18 2003") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :color (magenta) - :comments ("Terror trojan") - :delayed_sync_value (0) - :enable_tcp_resource (false) - :etm_enabled (false) - :include_in_any (true) - :port (3456) - :proto_type () - :reload_proof (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (Tcp) - :use_delayed_sync (false) - ) - : (CrackDown - :AdminInfo ( - :chkpf_uid ("{88AAA643-BF12-4D40-A02D-E98A8159358A}") - :ClassName (tcp_service) - :table (services) - :Wiznum (-1) - :LastModified ( - :Time ("Tue Jan 07 19:19:38 2003") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :color ("deep pink") - :comments ("CrackDown trojan") - :delayed_sync_value (0) - :enable_tcp_resource (false) - :etm_enabled (false) - :include_in_any (false) - :port (4444) - :proto_type () - :reload_proof (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (Tcp) - :use_delayed_sync (false) - ) - : (lpdw0rm - :AdminInfo ( - :chkpf_uid ("{73BFBF75-EB13-42C0-BA69-58B8F026B4D6}") - :ClassName (tcp_service) - :table (services) - :Wiznum (-1) - :LastModified ( - :Time ("Tue Jan 07 19:22:38 2003") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :color ("deep pink") - :comments ("Also used by: Ramen trojan and printer service.") - :delayed_sync_value (0) - :enable_tcp_resource (false) - :etm_enabled (false) - :include_in_any (true) - :port (515) - :proto_type () - :reload_proof (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (Tcp) - :use_delayed_sync (false) - ) - : (TheFlu - :AdminInfo ( - :chkpf_uid ("{02F708DD-0337-485F-A04B-3B931971B93A}") - :ClassName (tcp_service) - :table (services) - :Wiznum (-1) - :LastModified ( - :Time ("Tue Jan 07 19:23:32 2003") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :color (magenta) - :comments ("TheFlu trojan") - :delayed_sync_value (0) - :enable_tcp_resource (false) - :etm_enabled (false) - :include_in_any (true) - :port (5534) - :proto_type () - :reload_proof (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (Tcp) - :use_delayed_sync (false) - ) - : (Shadyshell - :AdminInfo ( - :chkpf_uid ("{41C4DF08-DBF9-4576-9114-B8F1DC4DC8D7}") - :ClassName (tcp_service) - :table (services) - :Wiznum (-1) - :LastModified ( - :Time ("Tue Jan 07 19:26:02 2003") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :color (magenta) - :comments ("Shadyshell trojan") - :delayed_sync_value (0) - :enable_tcp_resource (false) - :etm_enabled (false) - :include_in_any (true) - :port (1337) - :proto_type () - :reload_proof (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (Tcp) - :use_delayed_sync (false) - ) - : (TransScout - :AdminInfo ( - :chkpf_uid ("{16AEE006-0F79-407E-B6A4-F3CC5A7A31D5}") - :ClassName (tcp_service) - :table (services) - :Wiznum (-1) - :LastModified ( - :Time ("Tue Jan 07 19:27:16 2003") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :color ("deep pink") - :comments ("TransScout trojan") - :delayed_sync_value (0) - :enable_tcp_resource (false) - :etm_enabled (false) - :include_in_any (true) - :port (2004-2005) - :proto_type () - :reload_proof (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (Tcp) - :use_delayed_sync (false) - ) - : (Trinoo - :AdminInfo ( - :chkpf_uid ("{3CF4DA8B-576E-47EC-903E-91F155BD0CD9}") - :ClassName (tcp_service) - :table (services) - :Wiznum (-1) - :LastModified ( - :Time ("Tue Jan 07 19:28:12 2003") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :color (magenta) - :comments ("Trinoo trojan") - :delayed_sync_value (0) - :enable_tcp_resource (false) - :etm_enabled (false) - :include_in_any (true) - :port (1524) - :proto_type () - :reload_proof (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (Tcp) - :use_delayed_sync (false) - ) - : (SocketsdesTroie - :AdminInfo ( - :chkpf_uid ("{69CA7583-1FD4-4C86-AC1A-680697A9AF93}") - :ClassName (tcp_service) - :table (services) - :Wiznum (-1) - :LastModified ( - :Time ("Tue Jan 07 19:29:16 2003") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :color ("deep pink") - :comments ("Also used by the: tcpmux service") - :delayed_sync_value (0) - :enable_tcp_resource (false) - :etm_enabled (false) - :include_in_any (true) - :port (1) - :proto_type () - :reload_proof (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (Tcp) - :use_delayed_sync (false) - ) - : (Remote_Storm - :AdminInfo ( - :chkpf_uid ("{D4B1F3B0-C606-4B6B-8118-EE61303F8E19}") - :ClassName (tcp_service) - :table (services) - :Wiznum (-1) - :LastModified ( - :Time ("Tue Jan 07 19:31:06 2003") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :color ("deep pink") - :comments ("Also used by: Fraggle Rock,NetSpy,md5 Backdoor trojans") - :delayed_sync_value (0) - :enable_tcp_resource (false) - :etm_enabled (false) - :include_in_any (true) - :port (1025) - :proto_type () - :reload_proof (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (Tcp) - :use_delayed_sync (false) - ) - : (BackDoor-G - :AdminInfo ( - :chkpf_uid ("{A651F18C-1C7C-4BD2-9FFE-790C29E3CCD9}") - :ClassName (tcp_service) - :table (services) - :Wiznum (-1) - :LastModified ( - :Time ("Tue Jan 07 19:32:22 2003") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :color (magenta) - :comments ("Also used by:SubSeven,Tiles trojans") - :delayed_sync_value (0) - :enable_tcp_resource (false) - :etm_enabled (false) - :include_in_any (true) - :port (1243) - :proto_type () - :reload_proof (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (Tcp) - :use_delayed_sync (false) - ) - : (Back_Door_Setup - :AdminInfo ( - :chkpf_uid ("{86077A7D-A8DA-4B5B-919C-366FE91AD1DA}") - :ClassName (tcp_service) - :table (services) - :Wiznum (-1) - :LastModified ( - :Time ("Tue Jan 07 19:34:29 2003") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :color (magenta) - :comments ("Also used by:BioNet Lite,Blazer5,Bubbel trojans") - :delayed_sync_value (0) - :enable_tcp_resource (false) - :etm_enabled (false) - :include_in_any (false) - :port (5000) - :proto_type () - :reload_proof (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (Tcp) - :use_delayed_sync (false) - ) - : (DaCryptic - :AdminInfo ( - :chkpf_uid ("{C13E3031-02D6-4341-A307-3DAF10735078}") - :ClassName (tcp_service) - :table (services) - :Wiznum (-1) - :LastModified ( - :Time ("Tue Jan 07 19:38:01 2003") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :color (magenta) - :comments ("DaCryptic trojan") - :delayed_sync_value (0) - :enable_tcp_resource (false) - :etm_enabled (false) - :include_in_any (true) - :port (1074) - :proto_type () - :reload_proof (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (Tcp) - :use_delayed_sync (false) - ) - : (HackaTack_31791 - :AdminInfo ( - :chkpf_uid ("{05647A8C-F0E7-4354-ADBD-C685EE7742F0}") - :ClassName (udp_service) - :table (services) - :Wiznum (-1) - :LastModified ( - :Time ("Tue Jan 07 19:39:11 2003") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :color ("deep pink") - :comments ("HackaTack trojan") - :delete_on_reply (false) - :etm_enabled (false) - :include_in_any (true) - :port (31791) - :proto_type () - :reload_proof (false) - :replies (true) - :replies_from_any_port (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (Udp) - ) - : (Mneah - :AdminInfo ( - :chkpf_uid ("{E43B7817-DBB6-4C74-A95A-C424DC47999C}") - :ClassName (tcp_service) - :table (services) - :Wiznum (-1) - :LastModified ( - :Time ("Tue Jan 07 19:39:48 2003") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :color (magenta) - :comments ("Mneah trojan") - :delayed_sync_value (0) - :enable_tcp_resource (false) - :etm_enabled (false) - :include_in_any (true) - :port (4666) - :proto_type () - :reload_proof (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (Tcp) - :use_delayed_sync (false) - ) - : (Port_6667_trojans - :AdminInfo ( - :chkpf_uid ("{AEAA6C77-E87E-4581-AD73-06417391DFAD}") - :ClassName (tcp_service) - :table (services) - :Wiznum (-1) - :LastModified ( - :Time ("Tue Jan 07 19:42:26 2003") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :color (magenta) - :comments ("Used by: Dark FTP,EGO,Maniac rootkit,Moses,ScheduleAgent,SubSeven,Trinity,The thing,Kaitex,WinSatan trojans.") - :delayed_sync_value (0) - :enable_tcp_resource (false) - :etm_enabled (false) - :include_in_any (false) - :port (6667) - :proto_type () - :reload_proof (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (Tcp) - :use_delayed_sync (false) - ) - : (DerSphere_II - :AdminInfo ( - :chkpf_uid ("{8D971C42-17DE-49A0-A646-A8E0057AEBBD}") - :ClassName (tcp_service) - :table (services) - :Wiznum (-1) - :LastModified ( - :Time ("Tue Jan 07 19:42:53 2003") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :color ("deep pink") - :comments ("Also used by:Insane Network,Last 2000,Remote Explorer 2000,Senna Spy Trojan Generator trojans") - :delayed_sync_value (0) - :enable_tcp_resource (false) - :etm_enabled (false) - :include_in_any (false) - :port (2000) - :proto_type () - :reload_proof (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (Tcp) - :use_delayed_sync (false) - ) - : (Backage - :AdminInfo ( - :chkpf_uid ("{96759A8D-AAB8-43D9-BBFC-B459CE66AC87}") - :ClassName (tcp_service) - :table (services) - :Wiznum (-1) - :LastModified ( - :Time ("Tue Jan 07 19:43:17 2003") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :color ("deep pink") - :comments ("Backage trojan") - :delayed_sync_value (0) - :enable_tcp_resource (false) - :etm_enabled (false) - :include_in_any (false) - :port (411) - :proto_type () - :reload_proof (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (Tcp) - :use_delayed_sync (false) - ) - : (RIPng - :AdminInfo ( - :chkpf_uid ("{B854AB7B-C8C0-448F-9DD5-491212097C3B}") - :ClassName (udp_service) - :table (services) - :Wiznum (-1) - :LastModified ( - :Time ("Thu Jan 09 15:26:43 2003") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :color (blue1) - :comments ("Routing Information Protocol for IPv6") - :delete_on_reply (false) - :etm_enabled (false) - :include_in_any (true) - :port (521) - :proto_type () - :reload_proof (false) - :replies (true) - :replies_from_any_port (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (Udp) - ) - : (MS-SQL-Server_UDP - :AdminInfo ( - :chkpf_uid ("{BFD72CD2-8E5F-4EDE-BDB2-6DFC016AFCCD}") - :ClassName (udp_service) - :table (services) - :Wiznum (-1) - :LastModified ( - :Time ("Thu Feb 20 17:53:57 2003") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :color (gold3) - :comments ("Microsoft SQL Server") - :delete_on_reply (false) - :etm_enabled (false) - :include_in_any (true) - :port (1433) - :proto_type () - :reload_proof (false) - :replies (true) - :replies_from_any_port (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (Udp) - ) - : (MS-SQL-Monitor_UDP - :AdminInfo ( - :chkpf_uid ("{5AD1A14C-647C-41DE-9F84-D1C34F09D63B}") - :ClassName (udp_service) - :table (services) - :Wiznum (-1) - :LastModified ( - :Time ("Thu Feb 20 17:55:14 2003") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :color ("dark khaki") - :comments (Microsoft-SQL-Monitor_UDP) - :delete_on_reply (false) - :etm_enabled (false) - :include_in_any (true) - :port (1434) - :proto_type () - :reload_proof (false) - :replies (true) - :replies_from_any_port (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (Udp) - ) - : (DameWare - :AdminInfo ( - :chkpf_uid ("{F8A15DFE-8C58-407A-BA18-D92AD5B33966}") - :ClassName (tcp_service) - :table (services) - :Wiznum (-1) - :LastModified ( - :Time ("Thu Feb 20 18:00:28 2003") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :color ("dark orchid") - :comments ("DameWare Mini Remote Control Protocol") - :delayed_sync_value (30) - :enable_tcp_resource (false) - :etm_enabled (false) - :include_in_any (true) - :port (6129) - :proto_type () - :reload_proof (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (Tcp) - :use_delayed_sync (false) - ) - : (WinMX - :AdminInfo ( - :chkpf_uid ("{6414F98E-6883-44DB-8EE2-DEBD443C7714}") - :ClassName (udp_service) - :table (services) - :Wiznum (-1) - :LastModified ( - :Time ("Sun Dec 08 12:54:40 2002") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :color (black) - :comments ("Also uses Napster ports") - :delete_on_reply (false) - :etm_enabled (false) - :include_in_any (true) - :port (6257) - :proto_type () - :reload_proof (false) - :replies (true) - :replies_from_any_port (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (Udp) - ) - : (eDonkey_4665 - :AdminInfo ( - :chkpf_uid ("{D3CAA92A-1032-41AE-A1A1-2274F3AB9F45}") - :ClassName (udp_service) - :table (services) - :Wiznum (-1) - :LastModified ( - :Time ("Sun Dec 08 13:21:41 2002") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :color (black) - :comments ("eDonkey protocol. Used also by other clients.") - :delete_on_reply (false) - :etm_enabled (false) - :include_in_any (true) - :port (4665) - :proto_type () - :reload_proof (false) - :replies (true) - :replies_from_any_port (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (Udp) - ) - : (MSSQL_resolver - :AdminInfo ( - :chkpf_uid ("{7E7CE9B0-8631-4EC3-A7EE-6EB084782A66}") - :ClassName (udp_service) - :table (services) - :Wiznum (-1) - :LastModified ( - :Time ("Wed Sep 03 17:18:55 2003") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :color (black) - :comments ("MS SQL Sapphire /SQL Slammer Worm") - :delete_on_reply (false) - :etm_enabled (false) - :include_in_any (false) - :port (1434) - :proto_type (ReferenceObject - :Name (SQL_SLAMMER) - :Table (protocols) - :Uid ("{A9B88863-0786-4961-B1E9-DDC2FA723135}") - ) - :reload_proof (false) - :replies (true) - :replies_from_any_port (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (Udp) - ) - : (gtp_path_mgmt - :AdminInfo ( - :chkpf_uid ("{2801A9E7-2983-4106-BD3D-4D46B686868C}") - :ClassName (other_service) - :table (services) - :Deleteable (false) - :Hidden (false) - :LastModified ( - :Time ("Mon Aug 27 14:54:07 2001") - :By ("Upgrade Process") - :From (keepme) - ) - ) - :color ("Forest Green") - :comments ("GTP Path Management") - :etm_enabled (false) - :exp (gtp_path_match) - :include_in_any (true) - :needruleinfo (false) - :proto_type () - :protocol (17) - :reload_proof (false) - :replies (true) - :sync_on_cluster (true) - :timeout (0) - :type (other) - :weight (100) - ) - : (Kazaa - :AdminInfo ( - :LastModified ( - :Time ("Tue May 7 14:54:07 2002") - :By (CheckPoint) - :From (CheckPoint) - ) - :chkpf_uid ("{BE146201-61B2-11d6-B5E0-0002B316D24E}") - :ClassName (tcp_service) - :table (services) - ) - :color ("Forest Green") - :comments ("FastTrack (Kazaa/Morpheus) P2P Protocol") - :delayed_sync_value (0) - :enable_tcp_resource (false) - :etm_enabled (false) - :include_in_any (true) - :port (1214) - :proto_type () - :reload_proof (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (Tcp) - :use_delayed_sync (false) - ) - : (ftp-bidir - :AdminInfo ( - :LastModified ( - :Time ("Tue May 21 17:54:08 2002") - :By (CheckPoint) - :From (CheckPoint) - ) - :chkpf_uid ("{16A6AAA2-8449-11D6-A9C5-3E5A6FDB3434}") - :ClassName (tcp_service) - :table (services) - ) - :delayed_sync_value (30) - :use_delayed_sync (false) - :color ("Forest Green") - :comments ("File Transfer Protocol with bi-directional data transfer") - :enable_tcp_resource (false) - :etm_enabled (false) - :include_in_any (false) - :port (21) - :proto_type (ReferenceObject - :Name (FTP-BIDIR) - :Table (protocols) - :Uid ("{8026ECE8-E867-4c4c-9E10-08AC73B709B1}") - ) - :reload_proof (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (Tcp) - ) - : (L2TP - :AdminInfo ( - :chkpf_uid ("{7D452F42-CE34-442F-A023-FBC755DDF3D4}") - :ClassName (udp_service) - :table (services) - :LastModified ( - :Time ("Wed May 15 13:45:31 2002") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :delete_on_reply (false) - :color (red) - :comments ("Layer 2 Tunneling Protocol") - :etm_enabled (false) - :include_in_any (true) - :port (1701) - :proto_type () - :reload_proof (false) - :replies (true) - :replies_from_any_port (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (Udp) - ) - : (MSExchangeDirRef - :AdminInfo ( - :LastModified ( - :Time ("Wed Jul 24 14:54:08 2002") - :By (CheckPoint) - :From (CheckPoint) - ) - :chkpf_uid ("{01693eed-3f81-44d3-b498-51696722cc32}") - :ClassName (dcerpc_service) - :table (services) - ) - :color (Blue) - :comments ("Microsoft Exchange 2000 Directory Reference") - :etm_enabled (false) - :proto_type () - :reload_proof (false) - :type (dcerpc) - :uuid (1544f5e0-613c-11d1-93df-00c04fd7bd09) - ) - : (microsoft-ds - :AdminInfo ( - :chkpf_uid ("{CFBCACE4-7C6F-11D6-BF0E-3E5A6FE83232}") - :ClassName (tcp_service) - :table (services) - :LastModified ( - :Time ("Wed Jun 12 11:56:36 2002") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :delayed_sync_value (30) - :use_delayed_sync (false) - :color (magenta) - :comments ("Microsoft CIFS over TCP") - :enable_tcp_resource (false) - :etm_enabled (false) - :include_in_any (true) - :port (445) - :proto_type (ReferenceObject - :Name (CIFS) - :Table (protocols) - :Uid ("{97AEB373-9AEA-11D5-BD16-0090272CCB31}") - ) - :reload_proof (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (Tcp) - ) - : (CP_SecureAgent-udp - :AdminInfo ( - :chkpf_uid ("{D8CB6ABC-1A8B-4FC0-8BE1-3255E51DECD1}") - :ClassName (udp_service) - :table (services) - :LastModified ( - :Time ("Sun Jun 16 15:56:08 2002") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :delete_on_reply (false) - :color (black) - :comments ("SecureAgent Authentication service") - :etm_enabled (false) - :include_in_any (false) - :port (19194-19195) - :proto_type () - :reload_proof (false) - :replies (true) - :replies_from_any_port (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (Udp) - ) - : (FW1_sds_logon_NG - :AdminInfo ( - :LastModified ( - :Time ("Mon Jun 17 17:54:08 2002") - :By (CheckPoint) - :From (CheckPoint) - ) - :chkpf_uid ("{B61424B4-81E4-11D6-BCEC-3E5A6FDDCECE}") - :ClassName (tcp_service) - :table (services) - ) - :delayed_sync_value (30) - :use_delayed_sync (false) - :color (firebrick) - :comments ("SecuRemote Distribution Server Protocol (VC and higher)") - :enable_tcp_resource (false) - :etm_enabled (false) - :include_in_any (true) - :port (65524) - :proto_type () - :reload_proof (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (Tcp) - ) - : (MS-SQL-Server - :AdminInfo ( - :LastModified ( - :Time ("Thu Jul 18 17:54:08 2002") - :By (CheckPoint) - :From (CheckPoint) - ) - :chkpf_uid ("{DFF4F7BA-9A3D-11D6-91C1-3E5A6FDD5151}") - :ClassName (tcp_service) - :table (services) - ) - :delayed_sync_value (30) - :use_delayed_sync (false) - :color (Magenta) - :comments ("Microsoft SQL Server") - :enable_tcp_resource (false) - :etm_enabled (false) - :include_in_any (true) - :port (1433) - :proto_type () - :reload_proof (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (Tcp) - ) - : (MS-SQL-Monitor - :AdminInfo ( - :LastModified ( - :Time ("Thu Jul 18 17:54:08 2002") - :By (CheckPoint) - :From (CheckPoint) - ) - :chkpf_uid ("{EF245528-9A3D-11D6-9EAA-3E5A6FDD6A6A}") - :ClassName (tcp_service) - :table (services) - ) - :delayed_sync_value (30) - :use_delayed_sync (false) - :color (Magenta) - :comments ("Microsoft SQL Monitor") - :enable_tcp_resource (false) - :etm_enabled (false) - :include_in_any (true) - :port (1434) - :proto_type () - :reload_proof (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (Tcp) - ) - : (FW1 - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:07 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB388-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (tcp_service) - :table (services) - :name (FW1) - ) - :delayed_sync_value (30) - :use_delayed_sync (false) - :color (FireBrick) - :comments ("Check Point VPN-1 & FireWall-1 Service") - :enable_tcp_resource (false) - :etm_enabled (false) - :include_in_any (true) - :port (256) - :proto_type () - :reload_proof (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (Tcp) - ) - : (FW1_log - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:07 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB389-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (tcp_service) - :table (services) - :name (FW1_log) - ) - :delayed_sync_value (30) - :use_delayed_sync (false) - :color (FireBrick) - :comments ("Check Point VPN-1 & FireWall-1 Logs") - :enable_tcp_resource (false) - :etm_enabled (false) - :include_in_any (true) - :port (257) - :proto_type () - :reload_proof (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (tcp) - ) - : (FW1_mgmt - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:07 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB38A-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (tcp_service) - :table (services) - :name (FW1_mgmt) - ) - :delayed_sync_value (30) - :use_delayed_sync (false) - :color (FireBrick) - :comments ("Check Point Management (Version 4.x)") - :enable_tcp_resource (false) - :etm_enabled (false) - :include_in_any (true) - :port (258) - :proto_type () - :reload_proof (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (tcp) - ) - : (FW1_clntauth_telnet - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:07 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB38B-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (tcp_service) - :table (services) - :name (FW1_clntauth_telnet) - ) - :delayed_sync_value (30) - :use_delayed_sync (false) - :color (FireBrick) - :comments ("Check Point VPN-1 & FireWall-1 Client Authentication (Telnet)") - :enable_tcp_resource (false) - :etm_enabled (false) - :include_in_any (true) - :port (259) - :proto_type () - :reload_proof (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (tcp) - ) - : (FW1_clntauth_http - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:07 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB38C-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (tcp_service) - :table (services) - :name (FW1_clntauth_http) - ) - :delayed_sync_value (30) - :use_delayed_sync (false) - :color (FireBrick) - :comments ("Check Point VPN-1 & FireWall-1 Client Authentication (HTTP)") - :enable_tcp_resource (false) - :etm_enabled (false) - :include_in_any (true) - :port (900) - :proto_type () - :reload_proof (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (tcp) - ) - : (FW1_snauth - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:07 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB38E-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (tcp_service) - :table (services) - :name (FW1_snauth) - ) - :delayed_sync_value (30) - :use_delayed_sync (false) - :color (FireBrick) - :comments ("Check Point VPN-1 & FireWall-1 Session Authentication") - :enable_tcp_resource (false) - :etm_enabled (false) - :include_in_any (true) - :port (261) - :proto_type () - :reload_proof (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (tcp) - ) - : (FW1_topo - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:07 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB38F-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (tcp_service) - :table (services) - :name (FW1_topo) - ) - :delayed_sync_value (30) - :use_delayed_sync (false) - :color (FireBrick) - :comments ("Check Point VPN-1 SecuRemote Topology Requests") - :enable_tcp_resource (false) - :etm_enabled (false) - :include_in_any (true) - :port (264) - :proto_type () - :reload_proof (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (tcp) - ) - : (VPN1_IPSEC_encapsulation - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:07 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB390-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (udp_service) - :table (services) - :name (VPN1_IPSEC_encapsulation) - ) - :delete_on_reply (false) - :color (FireBrick) - :comments ("Check Point VPN-1 SecuRemote IPSEC Transport Encapsulation Protocol") - :etm_enabled (false) - :include_in_any (true) - :port (2746) - :proto_type () - :reload_proof (false) - :replies (true) - :replies_from_any_port (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (udp) - ) - : (FW1_key - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:07 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB391-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (tcp_service) - :table (services) - :name (FW1_key) - ) - :delayed_sync_value (30) - :use_delayed_sync (false) - :color (FireBrick) - :comments ("Check Point VPN-1 Public Key Transfer Protocol") - :enable_tcp_resource (false) - :etm_enabled (false) - :include_in_any (true) - :port (265) - :proto_type () - :reload_proof (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (tcp) - ) - : (FW1_cvp - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:07 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB392-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (tcp_service) - :table (services) - :Deleteable (false) - :Renameable (false) - :name (FW1_cvp) - ) - :delayed_sync_value (30) - :use_delayed_sync (false) - :color (FireBrick) - :comments ("Check Point OPSEC Content Vectoring Protocol") - :enable_tcp_resource (false) - :etm_enabled (false) - :include_in_any (true) - :port (18181) - :proto_type (ReferenceObject - :Name (FW1_CVP) - :Table (protocols) - :Uid ("{97AEB381-9AEA-11D5-BD16-0090272CCB30}") - ) - :reload_proof (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (tcp) - ) - : (FW1_ufp - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:07 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB393-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (tcp_service) - :table (services) - :Deleteable (false) - :Renameable (false) - :name (FW1_ufp) - ) - :delayed_sync_value (30) - :use_delayed_sync (false) - :color (FireBrick) - :comments ("Check Point OPSEC URL Filtering Protocol") - :enable_tcp_resource (false) - :etm_enabled (false) - :include_in_any (true) - :port (18182) - :proto_type () - :reload_proof (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (tcp) - ) - : (FW1_amon - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:07 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB394-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (tcp_service) - :table (services) - :Deleteable (false) - :Renameable (false) - :name (FW1_amon) - ) - :delayed_sync_value (30) - :use_delayed_sync (false) - :color (FireBrick) - :comments ("Check Point OPSEC Application Monitoring") - :enable_tcp_resource (false) - :etm_enabled (false) - :include_in_any (true) - :port (18193) - :proto_type () - :reload_proof (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (tcp) - ) - : (FW1_omi - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:07 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB395-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (tcp_service) - :table (services) - :name (FW1_omi) - ) - :delayed_sync_value (30) - :use_delayed_sync (false) - :color (FireBrick) - :comments ("Check Point OPSEC Objects Management Interface") - :enable_tcp_resource (false) - :etm_enabled (false) - :include_in_any (true) - :port (18185) - :proto_type () - :reload_proof (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (tcp) - ) - : (FW1_omi-sic - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:07 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB396-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (tcp_service) - :table (services) - :name (FW1_omi-sic) - ) - :delayed_sync_value (30) - :use_delayed_sync (false) - :color (FireBrick) - :comments ("Check Point OPSEC Objects Management Interface with Secure Internal Communication") - :enable_tcp_resource (false) - :etm_enabled (false) - :include_in_any (true) - :port (18186) - :proto_type () - :reload_proof (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (tcp) - ) - : (CP_reporting - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:07 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB397-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (tcp_service) - :table (services) - :name (CP_reporting) - ) - :delayed_sync_value (30) - :use_delayed_sync (false) - :color (FireBrick) - :comments ("Check Point Reporting Client Protocol") - :enable_tcp_resource (false) - :etm_enabled (false) - :include_in_any (true) - :port (18205) - :proto_type () - :reload_proof (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (tcp) - ) - : (FW1_CPRID - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:07 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB398-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (tcp_service) - :table (services) - :name (FW1_CPRID) - :Deleteable (false) - :Renameable (false) - ) - :delayed_sync_value (30) - :use_delayed_sync (false) - :color (FireBrick) - :comments ("Check Point Remote Installation Protocol") - :enable_tcp_resource (false) - :etm_enabled (false) - :include_in_any (true) - :port (18208) - :proto_type () - :reload_proof (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (tcp) - ) - : (FW1_netso - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:07 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB399-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (tcp_service) - :table (services) - :name (FW1_netso) - ) - :delayed_sync_value (30) - :use_delayed_sync (false) - :color (firebrick) - :comments ("Check Point User Authority simple protocol") - :enable_tcp_resource (false) - :etm_enabled (false) - :include_in_any (true) - :port (19190) - :proto_type () - :reload_proof (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (Tcp) - ) - : (FW1_uaa - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:07 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB39A-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (tcp_service) - :table (services) - :name (FW1_uaa) - :Deleteable (false) - :Renameable (false) - ) - :delayed_sync_value (30) - :use_delayed_sync (false) - :color (firebrick) - :comments ("Check Point OPSEC User Authority API") - :enable_tcp_resource (false) - :etm_enabled (false) - :include_in_any (true) - :port (19191) - :proto_type () - :reload_proof (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (Tcp) - ) - : (FW1_pslogon - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:07 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB39B-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (tcp_service) - :table (services) - :name (FW1_pslogon) - ) - :delayed_sync_value (30) - :use_delayed_sync (false) - :color (firebrick) - :comments ("Check Point Policy Server Logon protocol") - :enable_tcp_resource (false) - :etm_enabled (false) - :include_in_any (true) - :port (18207) - :proto_type () - :reload_proof (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (Tcp) - ) - : (FW1_pslogon_NG - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:07 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB39C-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (tcp_service) - :table (services) - :name (FW1_pslogon_NG) - ) - :delayed_sync_value (30) - :use_delayed_sync (false) - :color (firebrick) - :comments ("Check Point NG Policy Server Logon protocol") - :enable_tcp_resource (false) - :etm_enabled (false) - :include_in_any (true) - :port (18231) - :proto_type () - :reload_proof (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (Tcp) - ) - : (FW1_sds_logon - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:07 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB39D-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (tcp_service) - :table (services) - :name (FW1_sds_logon) - ) - :delayed_sync_value (30) - :use_delayed_sync (false) - :color (firebrick) - :comments ("Check Point SecuRemote Distribution Server Protocol") - :enable_tcp_resource (false) - :etm_enabled (false) - :include_in_any (true) - :port (18232) - :proto_type () - :reload_proof (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (Tcp) - ) - : (FW1_scv_keep_alive - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:07 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB39E-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (udp_service) - :table (services) - :name (FW1_scv_keep_alive) - ) - :delete_on_reply (false) - :color (FireBrick) - :comments ("Check Point SecureClient Verification Keepalive Protocol") - :etm_enabled (false) - :include_in_any (true) - :port (18233) - :proto_type () - :reload_proof (false) - :replies (true) - :replies_from_any_port (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (udp) - ) - : (RDP - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:07 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB39F-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (udp_service) - :table (services) - :name (RDP) - ) - :delete_on_reply (false) - :color (FireBrick) - :comments ("Check Point VPN-1 FWZ Key Negotiations - Reliable Datagram Protocol") - :etm_enabled (false) - :include_in_any (true) - :port (259) - :proto_type () - :reload_proof (false) - :replies (true) - :replies_from_any_port (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (udp) - ) - : (FW1_lea - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:07 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB3A0-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (tcp_service) - :table (services) - :name (FW1_lea) - ) - :delayed_sync_value (30) - :use_delayed_sync (false) - :color (FireBrick) - :comments ("Check Point OPSEC Log Export API") - :enable_tcp_resource (false) - :etm_enabled (false) - :include_in_any (true) - :port (18184) - :proto_type () - :reload_proof (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (tcp) - ) - : (FW1_ela - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:07 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB3A1-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (tcp_service) - :table (services) - :Deleteable (false) - :Renameable (false) - :name (FW1_ela) - ) - :delayed_sync_value (30) - :use_delayed_sync (false) - :color (FireBrick) - :comments ("Check Point OPSEC Event Logging API") - :enable_tcp_resource (false) - :etm_enabled (false) - :include_in_any (true) - :port (18187) - :proto_type () - :reload_proof (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (tcp) - ) - : (CP_rtm - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:07 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB3A2-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (tcp_service) - :table (services) - :name (CP_rtm) - ) - :delayed_sync_value (30) - :use_delayed_sync (false) - :color (FireBrick) - :comments ("Check Point Real Time Monitoring") - :enable_tcp_resource (false) - :etm_enabled (false) - :include_in_any (true) - :port (18202) - :proto_type () - :reload_proof (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (tcp) - ) - : (FW1_sam - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:07 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB3A3-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (tcp_service) - :table (services) - :name (FW1_sam) - ) - :delayed_sync_value (30) - :use_delayed_sync (false) - :color (FireBrick) - :comments ("Check Point OPSEC Suspicious Activity Monitor API") - :enable_tcp_resource (false) - :etm_enabled (false) - :include_in_any (true) - :port (18183) - :proto_type () - :reload_proof (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (tcp) - ) - : (FW1_ica_pull - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:07 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB3A4-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (tcp_service) - :table (services) - :name (FW1_ica_pull) - ) - :delayed_sync_value (30) - :use_delayed_sync (false) - :color (FireBrick) - :comments ("Check Point Internal CA Pull Certificate Service") - :enable_tcp_resource (false) - :etm_enabled (false) - :include_in_any (true) - :port (18210) - :proto_type () - :reload_proof (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (tcp) - ) - : (FW1_ica_push - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:07 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB3A5-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (tcp_service) - :table (services) - :name (FW1_ica_push) - ) - :delayed_sync_value (30) - :use_delayed_sync (false) - :color (FireBrick) - :comments ("Check Point Internal CA Push Certificate Service") - :enable_tcp_resource (false) - :etm_enabled (false) - :include_in_any (true) - :port (18211) - :proto_type () - :reload_proof (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (tcp) - ) - : (FW1_ica_services - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:07 2001") - :By (CheckPoint) - :From (CheckPoint) - ) - :chkpf_uid ("{97AEB44E-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (tcp_service) - :table (services) - :name (FW1_ica_services) - ) - :delayed_sync_value (30) - :use_delayed_sync (false) - :color (FireBrick) - :comments ("Check Point Internal CA Fetch CRL and User Registration Services") - :enable_tcp_resource (false) - :etm_enabled (false) - :include_in_any (true) - :port (18264) - :proto_type () - :reload_proof (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (tcp) - ) - : (FW1_load_agent - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:07 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB3A6-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (udp_service) - :table (services) - :name (FW1_load_agent) - ) - :delete_on_reply (false) - :color (FireBrick) - :comments ("Check Point ConnectControl Load Agent") - :etm_enabled (false) - :include_in_any (true) - :port (18212) - :proto_type () - :reload_proof (false) - :replies (true) - :replies_from_any_port (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (udp) - ) - : (E2ECP - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:07 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB3A7-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (udp_service) - :table (services) - :name (E2ECP) - ) - :delete_on_reply (false) - :color (FireBrick) - :comments ("Check Point End to End Control Protocol") - :etm_enabled (false) - :include_in_any (true) - :port (18241) - :proto_type () - :reload_proof (false) - :replies (true) - :replies_from_any_port (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (udp) - ) - : (tunnel_test - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:07 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB3A8-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (udp_service) - :table (services) - :name (tunnel_test) - ) - :delete_on_reply (false) - :color (FireBrick) - :comments ("Check Point tunnel teIsoAAAD application") - :etm_enabled (false) - :include_in_any (true) - :port (18234) - :proto_type () - :reload_proof (false) - :replies (true) - :replies_from_any_port (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (udp) - ) - : (CP_redundant - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:07 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB3A9-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (tcp_service) - :table (services) - :name (CP_redundant) - ) - :delayed_sync_value (30) - :use_delayed_sync (false) - :color (FireBrick) - :comments ("Check Point Redundant Management Protocol") - :enable_tcp_resource (false) - :etm_enabled (false) - :include_in_any (true) - :port (18221) - :proto_type () - :reload_proof (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (tcp) - ) - : (CPMI - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:07 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB3AA-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (tcp_service) - :table (services) - :name (CPMI) - ) - :delayed_sync_value (30) - :use_delayed_sync (false) - :color (FireBrick) - :comments ("Check Point Management Interface") - :enable_tcp_resource (false) - :etm_enabled (false) - :include_in_any (true) - :port (18190) - :proto_type () - :reload_proof (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (tcp) - ) - : (CPD - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:07 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB3AB-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (tcp_service) - :table (services) - :name (CPD) - ) - :delayed_sync_value (30) - :use_delayed_sync (false) - :color (FireBrick) - :comments ("Check Point Daemon Protocol") - :enable_tcp_resource (false) - :etm_enabled (false) - :include_in_any (true) - :port (18191) - :proto_type () - :reload_proof (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (tcp) - ) - : (CPD_amon - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:07 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB3AC-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (tcp_service) - :table (services) - :Deleteable (false) - :Renameable (false) - :name (CPD_amon) - ) - :delayed_sync_value (30) - :use_delayed_sync (false) - :color (FireBrick) - :comments ("Check Point Internal Application Monitoring") - :enable_tcp_resource (false) - :etm_enabled (false) - :include_in_any (true) - :port (18192) - :proto_type () - :reload_proof (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (tcp) - ) - : (CP_Exnet_PK - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:07 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB3AD-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (tcp_service) - :table (services) - :name (CP_Exnet_PK) - ) - :delayed_sync_value (30) - :use_delayed_sync (false) - :color (FireBrick) - :comments ("Check Point Extrnet public key advertisement") - :enable_tcp_resource (false) - :etm_enabled (false) - :include_in_any (true) - :port (18262) - :proto_type () - :reload_proof (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (tcp) - ) - : (CP_Exnet_resolve - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:07 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB3AE-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (tcp_service) - :table (services) - :name (CP_Exnet_resolve) - ) - :delayed_sync_value (30) - :use_delayed_sync (false) - :color (FireBrick) - :comments ("Check Point Extranet remote objects resolution") - :enable_tcp_resource (false) - :etm_enabled (false) - :include_in_any (true) - :port (18263) - :proto_type () - :reload_proof (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (tcp) - ) - : (IKE_tcp - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:07 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB3AF-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (tcp_service) - :table (services) - :name (IKE_tcp) - ) - :delayed_sync_value (30) - :use_delayed_sync (false) - :color (Cyan) - :comments ("IPSEC Internet Key Exchange Protocol over TCP") - :enable_tcp_resource (false) - :etm_enabled (false) - :include_in_any (true) - :port (500) - :proto_type () - :reload_proof (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (tcp) - ) - : (IKE - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:07 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB3B0-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (udp_service) - :table (services) - :name (IKE) - ) - :delete_on_reply (false) - :color (Cyan) - :comments ("IPSEC Internet Key Exchange Protocol (formerly ISAKMP/Oakley)") - :etm_enabled (false) - :include_in_any (true) - :port (500) - :proto_type () - :reload_proof (false) - :replies (true) - :replies_from_any_port (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (udp) - ) - : (FW1_snmp - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:07 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB3B1-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (udp_service) - :table (services) - :name (FW1_snmp) - ) - :delete_on_reply (false) - :color (FireBrick) - :comments ("Check Point VPN-1 & FireWall-1 SNMP Agent") - :etm_enabled (false) - :include_in_any (true) - :port (260) - :proto_type () - :reload_proof (false) - :replies (true) - :replies_from_any_port (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (udp) - ) - : (snmp - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:07 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB3B2-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (udp_service) - :table (services) - :name (snmp) - ) - :delete_on_reply (false) - :color (FireBrick) - :comments ("Simple Network Management Protocol") - :etm_enabled (false) - :include_in_any (true) - :port (161) - :proto_type () - :reload_proof (false) - :replies (true) - :replies_from_any_port (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (udp) - ) - : (snmp-trap - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:07 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB3B3-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (udp_service) - :table (services) - :name (snmp-trap) - ) - :delete_on_reply (false) - :color (FireBrick) - :comments ("Simple Network Management Protocol Traps") - :etm_enabled (false) - :include_in_any (true) - :port (162) - :proto_type () - :reload_proof (false) - :replies (false) - :replies_from_any_port (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (udp) - ) - : (snmp-read - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:07 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB3B4-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (udp_service) - :table (services) - :name (snmp-read) - ) - :delete_on_reply (false) - :color (FireBrick) - :comments ("Simple Network Management Protocol - Read Only") - :etm_enabled (false) - :include_in_any (false) - :port (161) - :proto_type (ReferenceObject - :Name (Snmp-Read) - :Table (protocols) - :Uid ("{97AEB383-9AEA-11D5-BD16-0090272CCB30}") - ) - :reload_proof (false) - :replies (true) - :replies_from_any_port (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (udp) - ) - : (X11 - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:07 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB3B5-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (tcp_service) - :table (services) - :name (X11) - ) - :delayed_sync_value (30) - :use_delayed_sync (false) - :color (Red) - :comments ("X Window System") - :enable_tcp_resource (false) - :etm_enabled (false) - :include_in_any (true) - :port (6000-6063) - :proto_type () - :reload_proof (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (Tcp) - ) - : (OpenWindows - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:07 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB3B6-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (tcp_service) - :table (services) - :name (OpenWindows) - ) - :delayed_sync_value (30) - :use_delayed_sync (false) - :color (Red) - :comments () - :enable_tcp_resource (false) - :etm_enabled (false) - :include_in_any (true) - :port (2000) - :proto_type () - :reload_proof (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (Tcp) - ) - : (nfsprog - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:07 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB3B7-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (rpc_service) - :table (services) - :name (nfsprog) - ) - :color (Red) - :comments ("RPCs Network File System (Ordinary)") - :etm_enabled (false) - :port (100003) - :proto_type () - :reload_proof (false) - :type (Rpc) - ) - : (nfsd - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:07 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB3B8-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (udp_service) - :table (services) - :name (nfsd) - ) - :delete_on_reply (false) - :color (Red) - :comments ("Network File System Daemon over UDP (earlier versions of NFS)") - :etm_enabled (false) - :include_in_any (true) - :port (2049) - :proto_type () - :reload_proof (false) - :replies (true) - :replies_from_any_port (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (Udp) - ) - : (nfsd-tcp - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:07 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB3B9-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (tcp_service) - :table (services) - :name (nfsd-tcp) - ) - :delayed_sync_value (30) - :use_delayed_sync (false) - :color (Red) - :comments ("Network File System Daemon over TCP") - :enable_tcp_resource (false) - :etm_enabled (false) - :include_in_any (true) - :port (2049) - :proto_type () - :reload_proof (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (Tcp) - ) - : (mountd - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:07 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB3BA-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (rpc_service) - :table (services) - :name (mountd) - ) - :color (Red) - :comments ("Initiate client access to NFS application") - :etm_enabled (false) - :port (100005) - :proto_type () - :reload_proof (false) - :type (Rpc) - ) - : (pcnfsd - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:07 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB3BB-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (rpc_service) - :table (services) - :name (pcnfsd) - ) - :color (Red) - :comments ("PCs (windows client) password authorization") - :etm_enabled (false) - :port (150001) - :proto_type () - :reload_proof (false) - :type (Rpc) - ) - : (nlockmgr - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:07 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB3BC-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (rpc_service) - :table (services) - :name (nlockmgr) - ) - :color (Red) - :comments ("RPC, Network Lock Manager") - :etm_enabled (false) - :port (100021) - :proto_type () - :reload_proof (false) - :type (Rpc) - ) - : (tftp - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:07 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB3BD-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (udp_service) - :table (services) - :name (tftp) - ) - :delete_on_reply (false) - :color (Red) - :comments ("Trivial File Transfer Protocol") - :etm_enabled (false) - :include_in_any (true) - :port (69) - :proto_type () - :reload_proof (false) - :replies (true) - :replies_from_any_port (true) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (Udp) - ) - : (sip_any - :AdminInfo ( - :LastModified ( - :Time ("Tue Nov 6 14:16:27 2001") - :By (CheckPoint) - :From (CheckPoint) - ) - :chkpf_uid ("{BD8B98D4-D2C0-11D5-A329-00D0B7D41431}") - :ClassName (udp_service) - :table (services) - :name (sip_any) - ) - :delete_on_reply (false) - :color (black) - :comments ("Session Initiation Protocol") - :etm_enabled (false) - :include_in_any (false) - :port (5060) - :proto_type (ReferenceObject - :Name (SIP_UDP_ANY) - :Table (protocols) - :Uid ("{97AEB378-9AEA-11D5-BD16-0090272CCB38}") - ) - :reload_proof (false) - :replies (true) - :replies_from_any_port (true) - :src_port () - :sync_on_cluster (true) - :timeout (40) - :type (Udp) - ) - : (sip - :AdminInfo ( - :LastModified ( - :Time ("Tue Nov 6 14:16:27 2001") - :By (CheckPoint) - :From (CheckPoint) - ) - :chkpf_uid ("{BD8B98D4-D2C0-11D5-A329-00D0B7D4143F}") - :ClassName (udp_service) - :table (services) - :name (sip) - ) - :delete_on_reply (false) - :color (black) - :comments ("Session Initiation Protocol") - :etm_enabled (false) - :include_in_any (false) - :port (5060) - :proto_type (ReferenceObject - :Name (SIP_UDP) - :Table (protocols) - :Uid ("{97AEB378-9AEA-11D5-BD16-0090272CCB37}") - ) - :reload_proof (false) - :replies (true) - :replies_from_any_port (true) - :src_port () - :sync_on_cluster (true) - :timeout (40) - :type (Udp) - ) - : (login - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:07 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB3BE-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (tcp_service) - :table (services) - :name (login) - ) - :delayed_sync_value (30) - :use_delayed_sync (false) - :color (Red) - :comments ("Remote login (rlogin)") - :enable_tcp_resource (false) - :etm_enabled (false) - :include_in_any (true) - :port (513) - :proto_type () - :reload_proof (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (Tcp) - ) - : (exec - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:07 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB3BF-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (tcp_service) - :table (services) - :name (exec) - ) - :delayed_sync_value (30) - :use_delayed_sync (false) - :color (Red) - :comments ("Remote execution (rexec)") - :enable_tcp_resource (false) - :etm_enabled (false) - :include_in_any (true) - :port (512) - :proto_type (ReferenceObject - :Name (RSHELL) - :Table (protocols) - :Uid ("{97AEB375-9AEA-11D5-BD16-0090272CCB30}") - ) - :reload_proof (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (Tcp) - ) - : (shell - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:07 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB3C0-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (tcp_service) - :table (services) - :name (shell) - ) - :delayed_sync_value (30) - :use_delayed_sync (false) - :color (Red) - :comments ("Remote shell (rsh)") - :enable_tcp_resource (false) - :etm_enabled (false) - :include_in_any (true) - :port (514) - :proto_type (ReferenceObject - :Name (RSHELL) - :Table (protocols) - :Uid ("{97AEB375-9AEA-11D5-BD16-0090272CCB30}") - ) - :reload_proof (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (Tcp) - ) - : (ssh - :AdminInfo ( - :LastModified ( - :Time ("Thu Dec 20 09:48:23 2001") - :By (CheckPoint) - :From (CheckPoint) - ) - :chkpf_uid ("{18EC9EAA-1657-4240-AB97-5F234623336B}") - :ClassName (tcp_service) - :table (services) - :name (ssh) - ) - :delayed_sync_value (30) - :use_delayed_sync (false) - :color (Red) - :comments ("secure shell, encrypted and authenticated rsh") - :enable_tcp_resource (false) - :etm_enabled (false) - :include_in_any (true) - :port (22) - :proto_type () - :reload_proof (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (Tcp) - ) - : (ypserv - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:07 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB3C1-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (rpc_service) - :table (services) - :name (ypserv) - ) - :color ("Navy Blue") - :comments ("Sun Yellow Pages directory service (YP) protocol, now known as NIS") - :etm_enabled (false) - :port (100004) - :proto_type () - :reload_proof (false) - :type (Rpc) - ) - : (ypbind - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:07 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB3C2-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (rpc_service) - :table (services) - :name (ypbind) - ) - :color ("Navy Blue") - :comments ("Sun Yellow Pages binder (NIS), provide servers addressing information") - :etm_enabled (false) - :port (100007) - :proto_type () - :reload_proof (false) - :type (Rpc) - ) - : (yppasswd - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:07 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB3C3-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (rpc_service) - :table (services) - :name (yppasswd) - ) - :color ("Navy Blue") - :comments ("Sun Yellow Pages protocol (NIS), password server") - :etm_enabled (false) - :port (100009) - :proto_type () - :reload_proof (false) - :type (Rpc) - ) - : (ypupdated - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:07 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB3C4-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (rpc_service) - :table (services) - :name (ypupdated) - ) - :color ("Navy Blue") - :comments ("Sun Yellow Pages protocol (NIS), update service") - :etm_enabled (false) - :port (100028) - :proto_type () - :reload_proof (false) - :type (Rpc) - ) - : (ypxfrd - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:07 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB3C5-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (rpc_service) - :table (services) - :name (ypxfrd) - ) - :color ("Navy Blue") - :comments ("Sun Yellow Pages protocol (NIS), transfers NIS maps") - :etm_enabled (false) - :port (100069) - :proto_type () - :reload_proof (false) - :type (Rpc) - ) - : (nisplus - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:07 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB3C6-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (rpc_service) - :table (services) - :name (nisplus) - ) - :color ("Navy Blue") - :comments ("NIS+ later version provides additional security and other facilities") - :etm_enabled (false) - :port (100300) - :proto_type () - :reload_proof (false) - :type (Rpc) - ) - : (ospf - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:07 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB3C7-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (other_service) - :table (services) - :name (ospf) - ) - :color ("Medium Slate Blue") - :comments ("Open Shortest Path First Interior GW Protocol") - :etm_enabled (false) - :exp () - :include_in_any (true) - :needruleinfo (false) - :proto_type () - :protocol (89) - :reload_proof (false) - :replies (false) - :sync_on_cluster (true) - :timeout (0) - :type (other) - :weight (0) - ) - : (ggp - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:07 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB3C8-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (other_service) - :table (services) - :name (ggp) - ) - :color ("Medium Slate Blue") - :comments ("Gateway-to-Gateway protocol") - :etm_enabled (false) - :exp () - :include_in_any (true) - :needruleinfo (false) - :proto_type () - :protocol (3) - :reload_proof (false) - :replies (false) - :sync_on_cluster (true) - :timeout (0) - :type (other) - :weight (0) - ) - : (igrp - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:07 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB3C9-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (other_service) - :table (services) - :name (igrp) - ) - :color ("Medium Slate Blue") - :comments ("Cisco Interior Gateway Routing Protocol") - :etm_enabled (false) - :exp () - :include_in_any (true) - :needruleinfo (false) - :proto_type () - :protocol (9) - :reload_proof (false) - :replies (false) - :sync_on_cluster (true) - :timeout (0) - :type (Other) - :weight (0) - ) - : (egp - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:07 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB3CA-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (other_service) - :table (services) - :name (egp) - ) - :color ("Medium Slate Blue") - :comments ("Exterior Gateway Protocol, convey net-reachability information between gateways") - :etm_enabled (false) - :exp () - :include_in_any (true) - :needruleinfo (false) - :proto_type () - :protocol (8) - :reload_proof (false) - :replies (false) - :sync_on_cluster (true) - :timeout (0) - :type (other) - :weight (0) - ) - : (igmp - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:07 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB3CB-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (other_service) - :table (services) - :name (igmp) - ) - :color ("Medium Slate Blue") - :comments ("Internet Group Management Protocol") - :etm_enabled (false) - :exp () - :include_in_any (true) - :needruleinfo (false) - :proto_type () - :protocol (2) - :reload_proof (false) - :replies (false) - :sync_on_cluster (false) - :timeout (0) - :type (other) - :weight (0) - ) - : (vrrp - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:07 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB3CC-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (other_service) - :table (services) - :name (vrrp) - ) - :color ("Medium Slate Blue") - :comments ("Virtual Router Redundancy Protocol") - :etm_enabled (false) - :exp () - :include_in_any (true) - :needruleinfo (false) - :proto_type () - :protocol (112) - :reload_proof (false) - :replies (false) - :sync_on_cluster (false) - :timeout (0) - :type (other) - :weight (0) - ) - : (gtp_default - :AdminInfo ( - :chkpf_uid ("{ACB96D00-A1F9-11D5-A414-00D0B7BE171D}") - :ClassName (gtp_service) - :table (services) - :Deleteable (false) - :LastModified ( - :Time ("Mon Aug 27 14:54:07 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :name (gtp_default) - ) - :apn_obj () - :port (3386) - :apn_any (true) - :color ("Forest Green") - :comments ("GPRS Tunnelling Protocol") - :data_packet (true) - :etm_enabled (false) - :imsi () - :imsi_any (true) - :include_in_any (true) - :ms_isdn (1) - :ms_isdn_any (true) - :proto_type () - :reload_proof (false) - :sel_mode (0) - :sel_mode_any (false) - :signaling_packet (true) - :static_eua (false) - :timeout (600) - :type (gtp) - :weight (100) - ) - : (gtp_reverse - :AdminInfo ( - :chkpf_uid ("{ACB96D01-A1F9-11D5-A414-00D0B7BE171D}") - :ClassName (other_service) - :table (services) - :Deleteable (false) - :Hidden (true) - :LastModified ( - :Time ("Mon Aug 27 14:54:07 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :name (gtp_reverse) - ) - :color ("Forest Green") - :comments ("GTP Reverse Connections") - :etm_enabled (false) - :exp (gtp_rev_match) - :include_in_any (true) - :needruleinfo (false) - :proto_type () - :protocol (17) - :reload_proof (false) - :replies (true) - :sync_on_cluster (true) - :timeout (0) - :type (other) - :weight (0) - ) - : (http_mapped - :AdminInfo ( - :chkpf_uid ("{DA123892-B250-11D5-A47A-0006294583C7}") - :ClassName (other_service) - :table (services) - :LastModified ( - :Time ("Mon Aug 27 14:54:07 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :name (http_mapped) - ) - :color (orange) - :comments ("HTTP Port Mapping Service") - :etm_enabled (false) - :exp ("SRV_REDIRECT(80,0.0.0.0,80) ") - :include_in_any (false) - :needruleinfo (false) - :proto_type () - :protocol (6) - :reload_proof (false) - :replies (false) - :sync_on_cluster (true) - :timeout (0) - :type (Other) - :weight (100) - ) - : (ftp_mapped - :AdminInfo ( - :chkpf_uid ("{DA123897-B250-11D5-A47A-0006294583C7}") - :ClassName (other_service) - :table (services) - :LastModified ( - :Time ("Mon Aug 27 14:54:07 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :name (ftp_mapped) - ) - :color (orange) - :comments ("FTP Port Mapping Service") - :etm_enabled (false) - :exp ("SRV_REDIRECT(21,0.0.0.0,21), set r_mhandler &ftp_code") - :include_in_any (false) - :needruleinfo (false) - :proto_type () - :protocol (6) - :reload_proof (false) - :replies (false) - :sync_on_cluster (true) - :timeout (0) - :type (Other) - :weight (100) - ) - : (smtp_mapped - :AdminInfo ( - :chkpf_uid ("{DA12389A-B250-11D5-A47A-0006294583C7}") - :ClassName (other_service) - :table (services) - :LastModified ( - :Time ("Mon Aug 27 14:54:07 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :name (smtp_mapped) - ) - :color (orange) - :comments ("SMTP Port Mapping Service") - :etm_enabled (false) - :exp ("SRV_REDIRECT(25,0.0.0.0,25) ") - :include_in_any (false) - :needruleinfo (false) - :proto_type () - :protocol (6) - :reload_proof (false) - :replies (false) - :sync_on_cluster (true) - :timeout (0) - :type (Other) - :weight (100) - ) - : (tunnel_test_mapped - :AdminInfo ( - :chkpf_uid ("{38A8AF07-D990-4178-AA8C-82E32066959C}") - :ClassName (other_service) - :table (services) - :LastModified ( - :Time ("Mon Aug 27 14:54:07 2001") - :By (CheckPoint) - :From (CheckPoint) - ) - :name (tunnel_test_mapped) - ) - :color (black) - :comments ("tunnel teIsoAAAD for a module performing the tunnel test") - :etm_enabled (false) - :exp ("SRV_REDIRECT_LOCAL_UDP(CP_TUNNEL_TEST_PORT, FP2_VER)") - :include_in_any (false) - :needruleinfo (false) - :proto_type () - :protocol (17) - :reload_proof (false) - :replies (false) - :sync_on_cluster (true) - :timeout (0) - :type (Other) - :weight (100) - ) - : (rip - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:07 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB3CD-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (udp_service) - :table (services) - :name (rip) - ) - :delete_on_reply (false) - :color ("Medium Slate Blue") - :comments ("Routing Information Protocol") - :etm_enabled (false) - :include_in_any (true) - :port (520) - :proto_type () - :reload_proof (false) - :replies (true) - :replies_from_any_port (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (Udp) - ) - : (rip-response - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:07 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB3CE-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (other_service) - :table (services) - :name (rip-response) - ) - :color ("Medium Slate Blue") - :comments ("Routing Information Protocol - response") - :etm_enabled (false) - :exp ("dport=520,rip_cmd=RIPCMD_RESPONSE") - :include_in_any (true) - :needruleinfo (false) - :proto_type () - :protocol (17) - :reload_proof (false) - :replies (true) - :sync_on_cluster (true) - :timeout (0) - :type (other) - :weight (0) - ) - : (telnet - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:07 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB3CF-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (tcp_service) - :table (services) - :name (telnet) - ) - :delayed_sync_value (30) - :use_delayed_sync (false) - :color ("Forest Green") - :comments ("Telnet Protocol") - :enable_tcp_resource (false) - :etm_enabled (false) - :include_in_any (true) - :port (23) - :proto_type () - :reload_proof (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (Tcp) - ) - : (ftp-port - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:07 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB3D1-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (tcp_service) - :table (services) - :name (ftp-port) - ) - :delayed_sync_value (30) - :use_delayed_sync (false) - :color ("Forest Green") - :comments ("File Transfer Protocol - PORT mode only") - :enable_tcp_resource (false) - :etm_enabled (false) - :include_in_any (false) - :port (21) - :proto_type (ReferenceObject - :Name (FTP-PORT) - :Table (protocols) - :Uid ("{97AEB371-9AEA-11D5-BD16-0090272CCB30}") - ) - :reload_proof (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (Tcp) - ) - : (ftp-pasv - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:07 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB3D2-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (tcp_service) - :table (services) - :name (ftp-pasv) - ) - :delayed_sync_value (30) - :use_delayed_sync (false) - :color ("Forest Green") - :comments ("File Transfer Protocol - PASV mode only") - :enable_tcp_resource (false) - :etm_enabled (false) - :include_in_any (false) - :port (21) - :proto_type (ReferenceObject - :Name (FTP-PASV) - :Table (protocols) - :Uid ("{97AEB372-9AEA-11D5-BD16-0090272CCB30}") - ) - :reload_proof (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (Tcp) - ) - : (ftp - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:07 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB3D0-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (tcp_service) - :table (services) - :name (ftp) - ) - :delayed_sync_value (30) - :use_delayed_sync (false) - :color ("Forest Green") - :comments ("File Transfer Protocol") - :enable_tcp_resource (false) - :etm_enabled (false) - :include_in_any (true) - :port (21) - :proto_type (ReferenceObject - :Name (FTP) - :Table (protocols) - :Uid ("{97AEB370-9AEA-11D5-BD16-0090272CCB30}") - ) - :reload_proof (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (Tcp) - ) - : (uucp - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:07 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB3D3-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (tcp_service) - :table (services) - :name (uucp) - ) - :delayed_sync_value (30) - :use_delayed_sync (false) - :color ("Forest Green") - :comments ("Unix-to-Unix Copy Program") - :enable_tcp_resource (false) - :etm_enabled (false) - :include_in_any (true) - :port (540) - :proto_type () - :reload_proof (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (Tcp) - ) - : (gopher - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:07 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB3D5-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (tcp_service) - :table (services) - :name (gopher) - ) - :delayed_sync_value (30) - :use_delayed_sync (false) - :color ("Forest Green") - :comments ("The Internet Gopher Protocol") - :enable_tcp_resource (false) - :etm_enabled (false) - :include_in_any (true) - :port (70) - :proto_type () - :reload_proof (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (Tcp) - ) - : (archie - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:07 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB3D6-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (udp_service) - :table (services) - :name (archie) - ) - :delete_on_reply (false) - :color ("Forest Green") - :comments ("Archie Internet Protocol, search for files over FTP servers") - :etm_enabled (false) - :include_in_any (true) - :port (1525) - :proto_type () - :reload_proof (false) - :replies (true) - :replies_from_any_port (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (Udp) - ) - : (wais - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:07 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB3D7-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (tcp_service) - :table (services) - :name (wais) - ) - :delayed_sync_value (30) - :use_delayed_sync (false) - :color ("Forest Green") - :comments ("Wide Area Information Servers") - :enable_tcp_resource (false) - :etm_enabled (false) - :include_in_any (true) - :port (210) - :proto_type () - :reload_proof (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (Tcp) - ) - : (X11-verify - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:07 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB3D8-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (other_service) - :table (services) - :name (X11-verify) - ) - :color (Red) - :comments ("X Window System With Authorization") - :etm_enabled (false) - :exp (x11verify_code) - :include_in_any (true) - :needruleinfo (true) - :proto_type () - :protocol (6) - :reload_proof (false) - :replies (false) - :sync_on_cluster (true) - :timeout (0) - :type (Other) - :weight (100) - ) - : (smtp - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:07 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB3D9-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (tcp_service) - :table (services) - :name (smtp) - ) - :delayed_sync_value (30) - :use_delayed_sync (false) - :color (Magenta) - :comments ("Simple Mail Transfer Protocol") - :enable_tcp_resource (false) - :etm_enabled (false) - :include_in_any (true) - :port (25) - :proto_type (ReferenceObject - :Name (SMTP) - :Table (protocols) - :Uid ("{97AEB374-9AEA-11D5-BD16-0090272CCB30}") - ) - :reload_proof (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (Tcp) - ) - : (pop-2 - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:07 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB3DA-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (tcp_service) - :table (services) - :name (pop-2) - ) - :delayed_sync_value (30) - :use_delayed_sync (false) - :color (Magenta) - :comments ("Post Office Protocol - Version 2") - :enable_tcp_resource (false) - :etm_enabled (false) - :include_in_any (true) - :port (109) - :proto_type () - :reload_proof (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (Tcp) - ) - : (pop-3 - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:07 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB3DB-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (tcp_service) - :table (services) - :name (pop-3) - ) - :delayed_sync_value (30) - :use_delayed_sync (false) - :color (Magenta) - :comments ("Post Office Protocol - Version 3") - :enable_tcp_resource (false) - :etm_enabled (false) - :include_in_any (true) - :port (110) - :proto_type () - :reload_proof (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (Tcp) - ) - : (nntp - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:07 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB3DC-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (tcp_service) - :table (services) - :name (nntp) - ) - :delayed_sync_value (30) - :use_delayed_sync (false) - :color (Magenta) - :comments ("Network News Transfer Protocol") - :enable_tcp_resource (false) - :etm_enabled (false) - :include_in_any (true) - :port (119) - :proto_type () - :reload_proof (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (Tcp) - ) - : (tcp-high-ports - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:07 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB3DD-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (tcp_service) - :table (services) - :name (tcp-high-ports) - ) - :delayed_sync_value (30) - :use_delayed_sync (false) - :color (Yellow) - :comments ("TCP Ports 1024-65535") - :enable_tcp_resource (false) - :etm_enabled (false) - :include_in_any (false) - :port (">1023") - :proto_type () - :reload_proof (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (tcp) - ) - : (udp-high-ports - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:07 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB3DE-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (udp_service) - :table (services) - :name (udp-high-ports) - ) - :delete_on_reply (false) - :color (Yellow) - :comments ("UDP Ports 1024-65535") - :etm_enabled (false) - :include_in_any (false) - :port (">1023") - :proto_type () - :reload_proof (false) - :replies (true) - :replies_from_any_port (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (udp) - ) - : (who - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:07 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB3DF-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (udp_service) - :table (services) - :name (who) - ) - :delete_on_reply (false) - :color (Blue) - :comments ("UNIX who Protocol, who is on the system") - :etm_enabled (false) - :include_in_any (true) - :port (513) - :proto_type () - :reload_proof (false) - :replies (true) - :replies_from_any_port (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (Udp) - ) - : (syslog - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:07 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB3E0-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (udp_service) - :table (services) - :name (syslog) - ) - :delete_on_reply (false) - :color (Blue) - :comments ("UNIX syslog Protocol, control system log") - :etm_enabled (false) - :include_in_any (true) - :port (514) - :proto_type () - :reload_proof (false) - :replies (false) - :replies_from_any_port (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (Udp) - ) - : (netstat - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:07 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB3E1-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (tcp_service) - :table (services) - :name (netstat) - ) - :delayed_sync_value (30) - :use_delayed_sync (false) - :color (Blue) - :comments ("UNIX netstat Protocol, show network status") - :enable_tcp_resource (false) - :etm_enabled (false) - :include_in_any (true) - :port (15) - :proto_type () - :reload_proof (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (Tcp) - ) - : (finger - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:07 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB3E2-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (tcp_service) - :table (services) - :name (finger) - ) - :delayed_sync_value (30) - :use_delayed_sync (false) - :color (Blue) - :comments ("UNIX, Finger Protocol") - :enable_tcp_resource (false) - :etm_enabled (false) - :include_in_any (true) - :port (79) - :proto_type () - :reload_proof (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (Tcp) - ) - : (rwall - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:07 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB3E3-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (rpc_service) - :table (services) - :name (rwall) - ) - :color (Blue) - :comments ("RPC, Shutdown messages") - :etm_enabled (false) - :port (100008) - :proto_type () - :reload_proof (false) - :type (Rpc) - ) - : (rstat - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:07 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB3E4-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (rpc_service) - :table (services) - :name (rstat) - ) - :color (Blue) - :comments ("RPC, Remote statistics") - :etm_enabled (false) - :port (100001) - :proto_type () - :reload_proof (false) - :type (Rpc) - ) - : (name - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:07 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB3E5-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (udp_service) - :table (services) - :name (name) - ) - :delete_on_reply (false) - :color (Black) - :comments ("Host Name Server") - :etm_enabled (false) - :include_in_any (true) - :port (42) - :proto_type () - :reload_proof (false) - :replies (true) - :replies_from_any_port (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (Udp) - ) - : (biff - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:07 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB3E6-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (udp_service) - :table (services) - :name (biff) - ) - :delete_on_reply (false) - :color (Black) - :comments ("UNIX biff Protocol, give notice of incoming mail messages") - :etm_enabled (false) - :include_in_any (true) - :port (512) - :proto_type () - :reload_proof (false) - :replies (true) - :replies_from_any_port (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (Udp) - ) - : (traceroute - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:07 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB3E7-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (other_service) - :table (services) - :name (traceroute) - ) - :color (Black) - :comments ("UNIX Traceroute, print the route packets take to network host") - :etm_enabled (false) - :exp ("uh_dport > 33000, ip_ttl < 30") - :include_in_any (true) - :needruleinfo (false) - :proto_type () - :protocol (17) - :reload_proof (false) - :replies (false) - :sync_on_cluster (true) - :timeout (0) - :type (other) - :weight (0) - ) - : (ident - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:07 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB3E8-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (tcp_service) - :table (services) - :name (ident) - ) - :delayed_sync_value (30) - :use_delayed_sync (false) - :color (Black) - :comments ("Identify RCS keyword strings in files") - :enable_tcp_resource (false) - :etm_enabled (false) - :include_in_any (true) - :port (113) - :proto_type () - :reload_proof (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (tcp) - ) - : (AP-Defender - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:07 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB3E9-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (tcp_service) - :table (services) - :name (AP-Defender) - ) - :delayed_sync_value (30) - :use_delayed_sync (false) - :color (FireBrick) - :comments ("Defender Authentication service") - :enable_tcp_resource (false) - :etm_enabled (false) - :include_in_any (true) - :port (2626) - :proto_type () - :reload_proof (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (tcp) - ) - : (AT-Defender - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:07 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB3EA-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (tcp_service) - :table (services) - :name (AT-Defender) - ) - :delayed_sync_value (30) - :use_delayed_sync (false) - :color (FireBrick) - :comments ("Defender Authentication service") - :enable_tcp_resource (false) - :etm_enabled (false) - :include_in_any (false) - :port (2626) - :proto_type () - :reload_proof (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (tcp) - ) - : (bootp - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:07 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB3EB-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (udp_service) - :table (services) - :name (bootp) - ) - :delete_on_reply (false) - :color (Black) - :comments ("Bootstrap Protocol Server, users automatically configured ") - :etm_enabled (false) - :include_in_any (true) - :port (67) - :proto_type () - :reload_proof (false) - :replies (true) - :replies_from_any_port (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (udp) - ) - : (dhcp-req-localmodule - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:07 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{22725520-8E10-4A91-98AC-DCD1F6C4A4DD}") - :ClassName (udp_service) - :table (services) - :name (dhcp-req-localmodule) - ) - :delete_on_reply (false) - :color (black) - :comments ("DHCP request from enforcement module only") - :etm_enabled (false) - :include_in_any (false) - :port (67) - :proto_type (ReferenceObject - :Name (CP-DHCP-request) - :Table (protocols) - :Uid ("{71878CD2-B8A9-11D5-BB1D-D496C1818686}") - ) - :reload_proof (false) - :replies (false) - :replies_from_any_port (false) - :src_port (68) - :sync_on_cluster (true) - :timeout (10) - :type (Udp) - ) - : (dhcp-rep-localmodule - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:07 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{FCA646B5-EF34-4DF1-895D-7639E181501A}") - :ClassName (udp_service) - :table (services) - :name (dhcp-rep-localmodule) - ) - :delete_on_reply (false) - :color (black) - :comments ("DHCP reply to enforcement module only") - :etm_enabled (false) - :include_in_any (false) - :port (68) - :proto_type (ReferenceObject - :Name (CP-DHCP-reply) - :Table (protocols) - :Uid ("{71879F1A-B8A9-11D5-BB1D-D496C1818686}") - ) - :reload_proof (false) - :replies (false) - :replies_from_any_port (false) - :src_port (67) - :sync_on_cluster (true) - :timeout (10) - :type (Udp) - ) - : (securid-udp - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:07 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB3EC-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (udp_service) - :table (services) - :name (securid-udp) - ) - :delete_on_reply (false) - :color (FireBrick) - :comments ("Token based Authentication service (UDP)") - :etm_enabled (false) - :include_in_any (true) - :port (5500) - :proto_type () - :reload_proof (false) - :replies (true) - :replies_from_any_port (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (Udp) - ) - : (securidprop - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:07 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB3ED-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (tcp_service) - :table (services) - :name (securidprop) - ) - :delayed_sync_value (30) - :use_delayed_sync (false) - :color (FireBrick) - :comments ("Token based Authentication service (TCP)") - :enable_tcp_resource (false) - :etm_enabled (false) - :include_in_any (true) - :port (5510) - :proto_type () - :reload_proof (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (Tcp) - ) - : (sqlnet1 - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:07 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB3EE-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (tcp_service) - :table (services) - :name (sqlnet1) - ) - :delayed_sync_value (30) - :use_delayed_sync (false) - :color (Foreground) - :comments ("Oracle SQL*Net Version 1") - :enable_tcp_resource (false) - :etm_enabled (false) - :include_in_any (true) - :port (1521) - :proto_type () - :reload_proof (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (tcp) - ) - : (sqlnet2-1521 - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:07 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB3EF-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (tcp_service) - :table (services) - :name (sqlnet2-1521) - ) - :delayed_sync_value (30) - :use_delayed_sync (false) - :color (Foreground) - :comments ("part of Oracle SQL*Net Version 2 Services") - :enable_tcp_resource (false) - :etm_enabled (false) - :include_in_any (false) - :port (1521) - :proto_type (ReferenceObject - :Name (SQLNET2) - :Table (protocols) - :Uid ("{97AEB376-9AEA-11D5-BD16-0090272CCB30}") - ) - :reload_proof (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (tcp) - ) - : (sqlnet2-1525 - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:07 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB3F0-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (tcp_service) - :table (services) - :name (sqlnet2-1525) - ) - :delayed_sync_value (30) - :use_delayed_sync (false) - :color (Foreground) - :comments ("part of Oracle SQL*Net Version 2 Services") - :enable_tcp_resource (false) - :etm_enabled (false) - :include_in_any (true) - :port (1525) - :proto_type (ReferenceObject - :Name (SQLNET2) - :Table (protocols) - :Uid ("{97AEB376-9AEA-11D5-BD16-0090272CCB30}") - ) - :reload_proof (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (tcp) - ) - : (sqlnet2-1526 - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:07 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB3F1-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (tcp_service) - :table (services) - :name (sqlnet2-1526) - ) - :delayed_sync_value (30) - :use_delayed_sync (false) - :color (Foreground) - :comments ("part of Oracle SQL*Net Version 2 Services") - :enable_tcp_resource (false) - :etm_enabled (false) - :include_in_any (true) - :port (1526) - :proto_type (ReferenceObject - :Name (SQLNET2) - :Table (protocols) - :Uid ("{97AEB376-9AEA-11D5-BD16-0090272CCB30}") - ) - :reload_proof (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (tcp) - ) - : (FreeTel-outgoing-server - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:07 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB3F3-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (udp_service) - :table (services) - :name (FreeTel-outgoing-server) - ) - :delete_on_reply (false) - :color (Foreground) - :comments ("real-time full-duplex voice communication via the Internet-server") - :etm_enabled (false) - :include_in_any (false) - :port (21300) - :proto_type (ReferenceObject - :Name (FreeTel) - :Table (protocols) - :Uid ("{97AEB37E-9AEA-11D5-BD16-0090272CCB30}") - ) - :reload_proof (false) - :replies (true) - :replies_from_any_port (false) - :src_port (21301-21305) - :sync_on_cluster (true) - :timeout (0) - :type (Udp) - ) - : (FreeTel-outgoing-client - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:07 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB3F4-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (other_service) - :table (services) - :name (FreeTel-outgoing-client) - ) - :color (Foreground) - :comments ("real-time full-duplex voice communication via the Internet-client") - :etm_enabled (false) - :exp (freetel_outgoing) - :include_in_any (true) - :needruleinfo (false) - :proto_type () - :protocol (17) - :reload_proof (false) - :replies (false) - :sync_on_cluster (true) - :timeout (0) - :type (other) - :weight (0) - ) - : (FreeTel-incoming - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:07 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB3F6-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (other_service) - :table (services) - :name (FreeTel-incoming) - ) - :color (Foreground) - :comments ("FreeTel Incoming Connections") - :etm_enabled (false) - :exp (freetel_incoming) - :include_in_any (true) - :needruleinfo (false) - :proto_type () - :protocol (17) - :reload_proof (false) - :replies (false) - :sync_on_cluster (true) - :timeout (0) - :type (other) - :weight (0) - ) - : (echo-tcp - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:07 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB3F7-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (tcp_service) - :table (services) - :name (echo-tcp) - ) - :delayed_sync_value (30) - :use_delayed_sync (false) - :color (Black) - :comments ("Echo Protocol (TCP)") - :enable_tcp_resource (false) - :etm_enabled (false) - :include_in_any (true) - :port (7) - :proto_type () - :reload_proof (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (Tcp) - ) - : (echo-udp - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:07 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB3F8-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (udp_service) - :table (services) - :name (echo-udp) - ) - :delete_on_reply (false) - :color (Black) - :comments ("Echo Protocol (UDP)") - :etm_enabled (false) - :include_in_any (true) - :port (7) - :proto_type () - :reload_proof (false) - :replies (true) - :replies_from_any_port (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (Udp) - ) - : (domain-tcp - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:07 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB3F9-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (tcp_service) - :table (services) - :name (domain-tcp) - ) - :delayed_sync_value (30) - :use_delayed_sync (false) - :color (Black) - :comments ("Domain Name System Download") - :enable_tcp_resource (false) - :etm_enabled (false) - :include_in_any (true) - :port (53) - :proto_type () - :reload_proof (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (Tcp) - ) - : (domain-udp - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:07 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB3FA-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (udp_service) - :table (services) - :name (domain-udp) - ) - :delete_on_reply (false) - :color (Black) - :comments ("Domain Name System Queries") - :etm_enabled (false) - :include_in_any (true) - :port (53) - :proto_type () - :reload_proof (false) - :replies (true) - :replies_from_any_port (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (Udp) - ) - : (kerberos-tcp - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:07 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB3FB-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (tcp_service) - :table (services) - :name (kerberos-tcp) - ) - :delayed_sync_value (30) - :use_delayed_sync (false) - :color (Black) - :comments ("secure method for authenticating a request for service") - :enable_tcp_resource (false) - :etm_enabled (false) - :include_in_any (true) - :port (750) - :proto_type () - :reload_proof (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (Tcp) - ) - : (kerberos-udp - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:07 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB3FC-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (udp_service) - :table (services) - :name (kerberos-udp) - ) - :delete_on_reply (false) - :color (Black) - :comments ("secure method for authenticating a request for service") - :etm_enabled (false) - :include_in_any (true) - :port (750) - :proto_type () - :reload_proof (false) - :replies (true) - :replies_from_any_port (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (Udp) - ) - : (discard-tcp - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:07 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB3FD-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (tcp_service) - :table (services) - :name (discard-tcp) - ) - :delayed_sync_value (30) - :use_delayed_sync (false) - :color (Black) - :comments ("Discard Server Protocol (TCP)") - :enable_tcp_resource (false) - :etm_enabled (false) - :include_in_any (true) - :port (9) - :proto_type () - :reload_proof (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (Tcp) - ) - : (discard-udp - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:07 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB3FE-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (udp_service) - :table (services) - :name (discard-udp) - ) - :delete_on_reply (false) - :color (Black) - :comments ("Discard Server Protocol (UDP)") - :etm_enabled (false) - :include_in_any (true) - :port (9) - :proto_type () - :reload_proof (false) - :replies (false) - :replies_from_any_port (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (Udp) - ) - : (time-tcp - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:07 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB3FF-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (tcp_service) - :table (services) - :name (time-tcp) - ) - :delayed_sync_value (30) - :use_delayed_sync (false) - :color (Black) - :comments ("Time Server Protocol (TCP)") - :enable_tcp_resource (false) - :etm_enabled (false) - :include_in_any (true) - :port (37) - :proto_type () - :reload_proof (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (Tcp) - ) - : (time-udp - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:07 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB400-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (udp_service) - :table (services) - :name (time-udp) - ) - :delete_on_reply (false) - :color (Black) - :comments ("Time Server Protocol (UDP)") - :etm_enabled (false) - :include_in_any (true) - :port (37) - :proto_type () - :reload_proof (false) - :replies (true) - :replies_from_any_port (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (Udp) - ) - : (daytime-tcp - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:07 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB401-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (tcp_service) - :table (services) - :name (daytime-tcp) - ) - :delayed_sync_value (30) - :use_delayed_sync (false) - :color (Black) - :comments ("Daytime Server Protocol (TCP)") - :enable_tcp_resource (false) - :etm_enabled (false) - :include_in_any (true) - :port (13) - :proto_type () - :reload_proof (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (Tcp) - ) - : (daytime-udp - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:07 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB402-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (udp_service) - :table (services) - :name (daytime-udp) - ) - :delete_on_reply (false) - :color (Black) - :comments ("Daytime Server Protocol (UDP)") - :etm_enabled (false) - :include_in_any (true) - :port (13) - :proto_type () - :reload_proof (false) - :replies (true) - :replies_from_any_port (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (Udp) - ) - : (ntp-tcp - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:07 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB403-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (tcp_service) - :table (services) - :name (ntp-tcp) - ) - :delayed_sync_value (30) - :use_delayed_sync (false) - :color (Black) - :comments ("Network Time Protocol (TCP)") - :enable_tcp_resource (false) - :etm_enabled (false) - :include_in_any (true) - :port (123) - :proto_type () - :reload_proof (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (Tcp) - ) - : (ntp-udp - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:07 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB404-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (udp_service) - :table (services) - :name (ntp-udp) - ) - :delete_on_reply (false) - :color (Black) - :comments ("Network Time Protocol (UDP)") - :etm_enabled (false) - :include_in_any (true) - :port (123) - :proto_type () - :reload_proof (false) - :replies (true) - :replies_from_any_port (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (Udp) - ) - : (icmp-proto - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:07 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB405-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (other_service) - :table (services) - :name (icmp-proto) - ) - :color ("Dark Orchid") - :comments ("Internet Control Message Protocol") - :etm_enabled (false) - :exp () - :include_in_any (true) - :needruleinfo (false) - :proto_type () - :protocol (1) - :reload_proof (false) - :replies (false) - :sync_on_cluster (true) - :timeout (0) - :type (other) - :weight (0) - ) - : (echo-reply - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:07 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB406-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (icmp_service) - :table (services) - :name (echo-reply) - ) - :color ("Dark Orchid") - :comments ("ICMP, echo reply") - :etm_enabled (true) - :icmp_code () - :icmp_type (0) - :proto_type () - :reload_proof (false) - :type (Icmp) - ) - : (dest-unreach - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB407-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (icmp_service) - :table (services) - :name (dest-unreach) - ) - :color ("Dark Orchid") - :comments ("ICMP, destination unreach") - :etm_enabled (false) - :icmp_code () - :icmp_type (3) - :proto_type () - :reload_proof (false) - :type (Icmp) - ) - : (source-quench - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB408-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (icmp_service) - :table (services) - :name (source-quench) - ) - :color ("Dark Orchid") - :comments ("ICMP, source quench") - :etm_enabled (false) - :icmp_code () - :icmp_type (4) - :proto_type () - :reload_proof (false) - :type (Icmp) - ) - : (redirect - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB409-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (icmp_service) - :table (services) - :name (redirect) - ) - :color ("Dark Orchid") - :comments ("ICMP, route redirect") - :etm_enabled (true) - :icmp_code () - :icmp_type (5) - :proto_type () - :reload_proof (false) - :type (Icmp) - ) - : (echo-request - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB40A-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (icmp_service) - :table (services) - :name (echo-request) - ) - :color ("Dark Orchid") - :comments ("ICMP, echo request") - :etm_enabled (true) - :icmp_code () - :icmp_type (8) - :proto_type () - :reload_proof (false) - :type (Icmp) - ) - : (time-exceeded - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB40B-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (icmp_service) - :table (services) - :name (time-exceeded) - ) - :color ("Dark Orchid") - :comments ("ICMP, time to live exceeded") - :etm_enabled (false) - :icmp_code () - :icmp_type (11) - :proto_type () - :reload_proof (false) - :type (Icmp) - ) - : (param-prblm - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB40C-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (icmp_service) - :table (services) - :name (param-prblm) - ) - :color ("Dark Orchid") - :comments ("ICMP, parameters problem") - :etm_enabled (false) - :icmp_code () - :icmp_type (12) - :proto_type () - :reload_proof (false) - :type (Icmp) - ) - : (timestamp - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB40D-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (icmp_service) - :table (services) - :name (timestamp) - ) - :color ("Dark Orchid") - :comments ("ICMP, timestamp request") - :etm_enabled (true) - :icmp_code () - :icmp_type (13) - :proto_type () - :reload_proof (false) - :type (Icmp) - ) - : (timestamp-reply - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB40E-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (icmp_service) - :table (services) - :name (timestamp-reply) - ) - :color ("Dark Orchid") - :comments ("ICMP, timestamp reply") - :etm_enabled (true) - :icmp_code () - :icmp_type (14) - :proto_type () - :reload_proof (false) - :type (Icmp) - ) - : (info-req - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB40F-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (icmp_service) - :table (services) - :name (info-req) - ) - :color ("Dark Orchid") - :comments ("ICMP, info request") - :etm_enabled (true) - :icmp_code () - :icmp_type (15) - :proto_type () - :reload_proof (false) - :type (Icmp) - ) - : (info-reply - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB410-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (icmp_service) - :table (services) - :name (info-reply) - ) - :color ("Dark Orchid") - :comments ("ICMP, info reply") - :etm_enabled (true) - :icmp_code () - :icmp_type (16) - :proto_type () - :reload_proof (false) - :type (Icmp) - ) - : (mask-request - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB411-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (icmp_service) - :table (services) - :name (mask-request) - ) - :color ("Dark Orchid") - :comments ("ICMP, mask request") - :etm_enabled (true) - :icmp_code () - :icmp_type (17) - :proto_type () - :reload_proof (false) - :type (Icmp) - ) - : (mask-reply - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB412-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (icmp_service) - :table (services) - :name (mask-reply) - ) - :color ("Dark Orchid") - :comments ("ICMP, mask reply") - :etm_enabled (true) - :icmp_code () - :icmp_type (18) - :proto_type () - :reload_proof (false) - :type (Icmp) - ) - : (nbname - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB414-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (udp_service) - :table (services) - :name (nbname) - ) - :delete_on_reply (false) - :color (Magenta) - :comments ("NetBios Name Service") - :etm_enabled (false) - :include_in_any (true) - :port (137) - :proto_type (ReferenceObject - :Name (NBNAME) - :Table (protocols) - :Uid ("{97AEB384-9AEA-11D5-BD16-0090272CCB30}") - ) - :reload_proof (false) - :replies (true) - :replies_from_any_port (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (Udp) - ) - : (nbdatagram - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB415-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (udp_service) - :table (services) - :name (nbdatagram) - ) - :delete_on_reply (false) - :color (Magenta) - :comments ("NetBios Datagram Service") - :etm_enabled (false) - :include_in_any (true) - :port (138) - :proto_type (ReferenceObject - :Name (NBDATAGRAM) - :Table (protocols) - :Uid ("{97AEB385-9AEA-11D5-BD16-0090272CCB30}") - ) - :reload_proof (false) - :replies (true) - :replies_from_any_port (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (Udp) - ) - : (nbsession - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB416-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (tcp_service) - :table (services) - :name (nbsession) - ) - :delayed_sync_value (30) - :use_delayed_sync (false) - :color (Magenta) - :comments ("NetBios Session Service") - :enable_tcp_resource (false) - :etm_enabled (false) - :include_in_any (true) - :port (139) - :proto_type (ReferenceObject - :Name (CIFS) - :Table (protocols) - :Uid ("{97AEB373-9AEA-11D5-BD16-0090272CCB31}") - ) - :reload_proof (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (Tcp) - ) - : (irc1 - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB417-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (tcp_service) - :table (services) - :name (irc1) - ) - :delayed_sync_value (30) - :use_delayed_sync (false) - :color (Black) - :comments ("Internet Relay Chat Protocol") - :enable_tcp_resource (false) - :etm_enabled (false) - :include_in_any (true) - :port (6660-6670) - :proto_type () - :reload_proof (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (Tcp) - ) - : (lotus - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB419-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (tcp_service) - :table (services) - :name (lotus) - ) - :delayed_sync_value (30) - :use_delayed_sync (false) - :color (Black) - :comments ("Lotus iNotes Web Access Protocol") - :enable_tcp_resource (false) - :etm_enabled (false) - :include_in_any (true) - :port (1352) - :proto_type () - :reload_proof (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (Tcp) - ) - : (interphone - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB41A-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (udp_service) - :table (services) - :name (interphone) - ) - :delete_on_reply (false) - :color (Blue) - :comments ("Vocaltec Internet Phone") - :etm_enabled (false) - :include_in_any (true) - :port (22555) - :proto_type () - :reload_proof (false) - :replies (true) - :replies_from_any_port (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (Udp) - ) - : (Real-Audio - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB41B-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (tcp_service) - :table (services) - :name (Real-Audio) - ) - :delayed_sync_value (30) - :use_delayed_sync (false) - :color (Blue) - :comments ("RealNetworks PNA Protocol") - :enable_tcp_resource (false) - :etm_enabled (false) - :include_in_any (true) - :port (7070) - :proto_type (ReferenceObject - :Name (PNA) - :Table (protocols) - :Uid ("{97AEB37A-9AEA-11D5-BD16-0090272CCB30}") - ) - :reload_proof (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (tcp) - ) - : (rtsp - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB41C-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (tcp_service) - :table (services) - :name (rtsp) - ) - :delayed_sync_value (30) - :use_delayed_sync (false) - :color (Blue) - :comments ("Real Time Streaming Protocol") - :enable_tcp_resource (false) - :etm_enabled (false) - :include_in_any (true) - :port (554) - :proto_type (ReferenceObject - :Name (RTSP) - :Table (protocols) - :Uid ("{97AEB37B-9AEA-11D5-BD16-0090272CCB30}") - ) - :reload_proof (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (tcp) - ) - : (TACACS - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB41F-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (udp_service) - :table (services) - :name (TACACS) - ) - :delete_on_reply (false) - :color (FireBrick) - :comments ("Terminal Access Controller Access Control System over UDP") - :etm_enabled (false) - :include_in_any (true) - :port (49) - :proto_type () - :reload_proof (false) - :replies (true) - :replies_from_any_port (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (udp) - ) - : (TACACSplus - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB420-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (tcp_service) - :table (services) - :name (TACACSplus) - ) - :delayed_sync_value (30) - :use_delayed_sync (false) - :color (Black) - :comments ("Terminal Access Controller Access Control System over TCP") - :enable_tcp_resource (false) - :etm_enabled (false) - :include_in_any (true) - :port (49) - :proto_type () - :reload_proof (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (tcp) - ) - : (SKIP - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB421-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (other_service) - :table (services) - :name (SKIP) - ) - :color (Cyan) - :comments ("IPSEC Simple Key Management for Internet Protocols") - :etm_enabled (false) - :exp () - :include_in_any (true) - :needruleinfo (false) - :proto_type () - :protocol (57) - :reload_proof (false) - :replies (true) - :sync_on_cluster (true) - :timeout (600) - :type (other) - :weight (0) - ) - : (AH - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB422-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (other_service) - :table (services) - :name (AH) - ) - :color (Cyan) - :comments ("IPSEC Authentication Header Protocol") - :etm_enabled (false) - :exp () - :include_in_any (true) - :needruleinfo (false) - :proto_type () - :protocol (51) - :reload_proof (false) - :replies (true) - :sync_on_cluster (true) - :timeout (600) - :type (other) - :weight (0) - ) - : (ESP - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB423-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (other_service) - :table (services) - :name (ESP) - ) - :color (cyan) - :comments ("IPSEC Encapsulating Security Payload Protocol") - :etm_enabled (false) - :exp () - :include_in_any (true) - :needruleinfo (false) - :proto_type () - :protocol (50) - :reload_proof (false) - :replies (true) - :sync_on_cluster (true) - :timeout (600) - :type (other) - :weight (0) - ) - : (gre - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB424-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (other_service) - :table (services) - :name (gre) - ) - :color (Red) - :comments () - :etm_enabled (false) - :exp () - :include_in_any (true) - :needruleinfo (false) - :proto_type () - :protocol (47) - :reload_proof (false) - :replies (true) - :sync_on_cluster (true) - :timeout (600) - :type (other) - :weight (0) - ) - : (pptp-tcp - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB425-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (tcp_service) - :table (services) - :name (pptp-tcp) - ) - :delayed_sync_value (30) - :use_delayed_sync (false) - :color (Red) - :comments ("Point-to-Point Tunneling Protocol, extension of PPP") - :enable_tcp_resource (false) - :etm_enabled (false) - :include_in_any (true) - :port (1723) - :proto_type () - :reload_proof (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (Tcp) - ) - : (H323_ras - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By (CheckPoint) - :From (CheckPoint) - ) - :chkpf_uid ("{97AEB378-9AEA-11D5-BD16-0090272CCB32}") - :ClassName (udp_service) - :table (services) - :name (H323_ras) - ) - :delete_on_reply (false) - :color (Cyan) - :comments ("RAS and associated connections (H.323 protocols)") - :etm_enabled (false) - :include_in_any (false) - :port (1719) - :proto_type (ReferenceObject - :Name (H.323_RAS) - :Table (protocols) - :Uid ("{97AEB378-9AEA-11D5-BD16-0090272CCB31}") - ) - :reload_proof (false) - :replies (true) - :replies_from_any_port (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (udp) - ) - : (H323_ras_only - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By (CheckPoint) - :From (CheckPoint) - ) - :chkpf_uid ("{97AEB432-9AEA-11D5-BD16-0090272CCB31}") - :ClassName (udp_service) - :table (services) - :name (H323_ras_only) - ) - :delete_on_reply (false) - :color (Cyan) - :comments ("Endpoint to Gatekeeper and Gatekeeper to Gatekeeper communication") - :etm_enabled (false) - :include_in_any (true) - :port (1719) - :proto_type () - :reload_proof (false) - :replies (true) - :replies_from_any_port (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (udp) - ) - : (T.120 - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB428-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (tcp_service) - :table (services) - :name (T.120) - ) - :delayed_sync_value (30) - :use_delayed_sync (false) - :color (Cyan) - :comments ("H323, Application sharing protocol") - :enable_tcp_resource (false) - :etm_enabled (false) - :include_in_any (true) - :port (1503) - :proto_type () - :reload_proof (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (Tcp) - ) - : (NCP - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB429-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (tcp_service) - :table (services) - :name (NCP) - ) - :delayed_sync_value (30) - :use_delayed_sync (false) - :color (Magenta) - :comments ("Novell NetWare Core Protocol") - :enable_tcp_resource (false) - :etm_enabled (false) - :include_in_any (true) - :port (524) - :proto_type () - :reload_proof (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (Tcp) - ) - : (Orbix-1570 - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB42A-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (tcp_service) - :table (services) - :name (Orbix-1570) - ) - :delayed_sync_value (30) - :use_delayed_sync (false) - :color (black) - :comments ("IONA Orbix Daemon (IIOP) Port 1570") - :enable_tcp_resource (false) - :etm_enabled (false) - :include_in_any (true) - :port (1570) - :proto_type (ReferenceObject - :Name (IIOP) - :Table (protocols) - :Uid ("{97AEB386-9AEA-11D5-BD16-0090272CCB30}") - ) - :reload_proof (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (tcp) - ) - : (Orbix-1571 - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB42B-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (tcp_service) - :table (services) - :name (Orbix-1571) - ) - :delayed_sync_value (30) - :use_delayed_sync (false) - :color (black) - :comments ("IONA Orbix Daemon (IIOP) Port 1571") - :enable_tcp_resource (false) - :etm_enabled (false) - :include_in_any (true) - :port (1571) - :proto_type (ReferenceObject - :Name (IIOP) - :Table (protocols) - :Uid ("{97AEB386-9AEA-11D5-BD16-0090272CCB30}") - ) - :reload_proof (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (tcp) - ) - : (OAS-NameServer - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB42D-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (tcp_service) - :table (services) - :name (OAS-NameServer) - ) - :delayed_sync_value (30) - :use_delayed_sync (false) - :color (black) - :comments ("Oracle Application Server (IIOP) NameServer") - :enable_tcp_resource (false) - :etm_enabled (false) - :include_in_any (true) - :port (2649) - :proto_type (ReferenceObject - :Name (IIOP) - :Table (protocols) - :Uid ("{97AEB386-9AEA-11D5-BD16-0090272CCB30}") - ) - :reload_proof (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (tcp) - ) - : (OAS-ORB - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB42E-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (tcp_service) - :table (services) - :name (OAS-ORB) - ) - :delayed_sync_value (30) - :use_delayed_sync (false) - :color (black) - :comments ("Oracle Application Server (IIOP) ORB") - :enable_tcp_resource (false) - :etm_enabled (false) - :include_in_any (true) - :port (2651) - :proto_type (ReferenceObject - :Name (IIOP) - :Table (protocols) - :Uid ("{97AEB386-9AEA-11D5-BD16-0090272CCB30}") - ) - :reload_proof (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (tcp) - ) - : (Sitara - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB430-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (other_service) - :table (services) - :name (Sitara) - ) - :color (Red) - :comments ("Sitara Networks Protocol (SpeedSeeker)") - :etm_enabled (false) - :exp () - :include_in_any (true) - :needruleinfo (false) - :proto_type () - :protocol (109) - :reload_proof (false) - :replies (true) - :sync_on_cluster (true) - :timeout (0) - :type (other) - :weight (0) - ) - : (IS411-srvr - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB431-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (tcp_service) - :table (services) - :name (IS411-srvr) - ) - :delayed_sync_value (30) - :use_delayed_sync (false) - :color (Blue) - :comments () - :enable_tcp_resource (false) - :etm_enabled (false) - :include_in_any (true) - :port (6499) - :proto_type () - :reload_proof (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (tcp) - ) - : (Streamworks - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB432-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (udp_service) - :table (services) - :name (Streamworks) - ) - :delete_on_reply (false) - :color (Red) - :comments () - :etm_enabled (false) - :include_in_any (true) - :port (1558) - :proto_type () - :reload_proof (false) - :replies (true) - :replies_from_any_port (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (udp) - ) - : (ldap - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB433-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (tcp_service) - :table (services) - :name (ldap) - ) - :delayed_sync_value (30) - :use_delayed_sync (false) - :color (Foreground) - :comments ("Lightweight Directory Access Protocol") - :enable_tcp_resource (false) - :etm_enabled (true) - :include_in_any (true) - :port (389) - :proto_type () - :reload_proof (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (tcp) - ) - : (ldap-ssl - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB434-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (tcp_service) - :table (services) - :name (ldap-ssl) - ) - :delayed_sync_value (30) - :use_delayed_sync (false) - :color (Foreground) - :comments ("Lightweight Directory Access Protocol over TLS/SSL") - :enable_tcp_resource (false) - :etm_enabled (false) - :include_in_any (true) - :port (636) - :proto_type () - :reload_proof (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (tcp) - ) - : (Entrust-Admin - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB435-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (tcp_service) - :table (services) - :name (Entrust-Admin) - ) - :delayed_sync_value (30) - :use_delayed_sync (false) - :color (FireBrick) - :comments ("Entrust CA Administration Service") - :enable_tcp_resource (false) - :etm_enabled (false) - :include_in_any (true) - :port (710) - :proto_type () - :reload_proof (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (tcp) - ) - : (Entrust-KeyMgmt - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB436-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (tcp_service) - :table (services) - :name (Entrust-KeyMgmt) - ) - :delayed_sync_value (30) - :use_delayed_sync (false) - :color (FireBrick) - :comments ("Entrust CA Key Management Service") - :enable_tcp_resource (false) - :etm_enabled (false) - :include_in_any (true) - :port (709) - :proto_type () - :reload_proof (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (tcp) - ) - : (MetaIP-UAT - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB437-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (udp_service) - :table (services) - :name (MetaIP-UAT) - ) - :delete_on_reply (false) - :color (FireBrick) - :comments ("Check Point Meta IP UAM Client-Server Communication") - :etm_enabled (false) - :include_in_any (false) - :port (5004) - :proto_type () - :reload_proof (false) - :replies (true) - :replies_from_any_port (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (udp) - ) - : (RainWall_Command - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By (CheckPoint) - :From (CheckPoint) - ) - :chkpf_uid ("{B9BBEEBA-B639-41A3-97D5-1F9D982D7E44}") - :ClassName (tcp_service) - :table (services) - :name (RainWall_Command) - ) - :delayed_sync_value (30) - :use_delayed_sync (false) - :color (black) - :comments ("RainWall higu availability daemon") - :enable_tcp_resource (false) - :etm_enabled (false) - :include_in_any (true) - :port (6374) - :proto_type () - :reload_proof (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (Tcp) - ) - : (RainWall_Daemon - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By (CheckPoint) - :From (CheckPoint) - ) - :chkpf_uid ("{21CC3F85-E6DF-443D-9846-BD39BD015B85}") - :ClassName (udp_service) - :table (services) - :name (RainWall_Daemon) - ) - :delete_on_reply (false) - :color (black) - :comments ("RainWall daemons communication") - :etm_enabled (false) - :include_in_any (true) - :port (6372) - :proto_type () - :reload_proof (false) - :replies (true) - :replies_from_any_port (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (Udp) - ) - : (RainWall_Status - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By (CheckPoint) - :From (CheckPoint) - ) - :chkpf_uid ("{4FBD29C5-06DB-4912-B23D-1BD50D693185}") - :ClassName (udp_service) - :table (services) - :name (RainWall_Status) - ) - :delete_on_reply (false) - :color (black) - :comments ("RainWall remote management status") - :etm_enabled (false) - :include_in_any (true) - :port (6374) - :proto_type () - :reload_proof (false) - :replies (true) - :replies_from_any_port (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (Udp) - ) - : (RainWall_Stop - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By (CheckPoint) - :From (CheckPoint) - ) - :chkpf_uid ("{5FF8E3F0-F9E7-47C0-A8CE-FABCCCDB7755}") - :ClassName (udp_service) - :table (services) - :name (RainWall_Stop) - ) - :delete_on_reply (false) - :color (black) - :comments ("RainWall monitoring") - :etm_enabled (false) - :include_in_any (true) - :port (6373) - :proto_type () - :reload_proof (false) - :replies (true) - :replies_from_any_port (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (Udp) - ) - : (StoneBeat-Control - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB438-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (tcp_service) - :table (services) - :name (StoneBeat-Control) - ) - :delayed_sync_value (30) - :use_delayed_sync (false) - :color (Black) - :comments ("Stonesoft StoneBeat Control") - :enable_tcp_resource (false) - :etm_enabled (false) - :include_in_any (true) - :port (3002) - :proto_type () - :reload_proof (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (tcp) - ) - : (StoneBeat-Daemon - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB439-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (tcp_service) - :table (services) - :name (StoneBeat-Daemon) - ) - :delayed_sync_value (30) - :use_delayed_sync (false) - :color (Black) - :comments ("Stonesoft StoneBeat Daemon Heartbeat") - :enable_tcp_resource (false) - :etm_enabled (false) - :include_in_any (true) - :port (3001) - :proto_type () - :reload_proof (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (tcp) - ) - : (RealSecure - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB43B-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (tcp_service) - :table (services) - :name (RealSecure) - ) - :delayed_sync_value (30) - :use_delayed_sync (false) - :color ("Forest Green") - :comments ("Automatic 'Suspicious Activity Monitoring' activator") - :enable_tcp_resource (false) - :etm_enabled (false) - :include_in_any (true) - :port (2998) - :proto_type () - :reload_proof (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (Tcp) - ) - : (pcANYWHERE-data - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB43E-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (tcp_service) - :table (services) - :name (pcANYWHERE-data) - ) - :delayed_sync_value (30) - :use_delayed_sync (false) - :color (Blue) - :comments ("PCs remote access security software, data") - :enable_tcp_resource (false) - :etm_enabled (false) - :include_in_any (true) - :port (5631) - :proto_type () - :reload_proof (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (Tcp) - ) - : (pcANYWHERE-stat - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB43F-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (udp_service) - :table (services) - :name (pcANYWHERE-stat) - ) - :delete_on_reply (false) - :color (Blue) - :comments ("PCs remote access security software, status") - :etm_enabled (false) - :include_in_any (true) - :port (5632) - :proto_type () - :reload_proof (false) - :replies (true) - :replies_from_any_port (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (Udp) - ) - : (pcTELECOMMUTE-FileSync - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB441-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (tcp_service) - :table (services) - :name (pcTELECOMMUTE-FileSync) - ) - :delayed_sync_value (30) - :use_delayed_sync (false) - :color (Blue) - :comments ("Symantec pcTELECOMMUTE File Synchronization") - :enable_tcp_resource (false) - :etm_enabled (false) - :include_in_any (true) - :port (2299) - :proto_type () - :reload_proof (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (Tcp) - ) - : (vosaic-data - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB444-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (udp_service) - :table (services) - :name (vosaic-data) - ) - :delete_on_reply (false) - :color (Blue) - :comments () - :etm_enabled (false) - :include_in_any (true) - :port (20000-20300) - :proto_type () - :reload_proof (false) - :replies (true) - :replies_from_any_port (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (udp) - ) - : (vosaic-ctrl - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB445-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (tcp_service) - :table (services) - :name (vosaic-ctrl) - ) - :delayed_sync_value (30) - :use_delayed_sync (false) - :color (Blue) - :comments () - :enable_tcp_resource (false) - :etm_enabled (false) - :include_in_any (true) - :port (1235) - :proto_type () - :reload_proof (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (tcp) - ) - : (imap - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB446-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (tcp_service) - :table (services) - :name (imap) - ) - :delayed_sync_value (30) - :use_delayed_sync (false) - :color (Yellow) - :comments ("Interactive Mail Access Protocol") - :enable_tcp_resource (false) - :etm_enabled (false) - :include_in_any (true) - :port (143) - :proto_type () - :reload_proof (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (tcp) - ) - : (FW1_Encapsulation - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB447-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (other_service) - :table (services) - :name (FW1_Encapsulation) - ) - :color (Firebrick) - :comments ("Check Point VPN-1 SecuRemote FWZ Encapsulation Protocol") - :etm_enabled (false) - :exp () - :include_in_any (true) - :needruleinfo (false) - :proto_type () - :protocol (94) - :reload_proof (false) - :replies (true) - :sync_on_cluster (true) - :timeout (600) - :type (other) - :weight (0) - ) - : (netshow - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB448-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (tcp_service) - :table (services) - :name (netshow) - ) - :delayed_sync_value (30) - :use_delayed_sync (false) - :color (Blue) - :comments ("Microsoft NetShow (Windows Media Player)") - :enable_tcp_resource (false) - :etm_enabled (false) - :include_in_any (true) - :port (1755) - :proto_type (ReferenceObject - :Name (NetShow) - :Table (protocols) - :Uid ("{97AEB37C-9AEA-11D5-BD16-0090272CCB30}") - ) - :reload_proof (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (Tcp) - ) - : (backweb - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB449-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (other_service) - :table (services) - :name (backweb) - ) - :color (Blue) - :comments ("PUSH Web applications, send information directly to desktops. over the Internet") - :etm_enabled (false) - :exp (backweb_match) - :include_in_any (true) - :needruleinfo (false) - :proto_type (ReferenceObject - :Name (BackWeb) - :Table (protocols) - :Uid ("{97AEB37F-9AEA-11D5-BD16-0090272CCB30}") - ) - :protocol (17) - :reload_proof (false) - :replies (false) - :sync_on_cluster (true) - :timeout (0) - :type (other) - :weight (0) - ) - : (winframe - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB44A-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (tcp_service) - :table (services) - :name (winframe) - ) - :delayed_sync_value (30) - :use_delayed_sync (false) - :color (Blue) - :comments ("Allows servers to provide applications and data for attached computer workstations (Windows)") - :enable_tcp_resource (false) - :etm_enabled (false) - :include_in_any (true) - :port (1494) - :proto_type (ReferenceObject - :Name (WinFrame) - :Table (protocols) - :Uid ("{97AEB380-9AEA-11D5-BD16-0090272CCB30}") - ) - :reload_proof (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (Tcp) - ) - : (CU-SeeMe - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB44B-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (udp_service) - :table (services) - :name (CU-SeeMe) - ) - :delete_on_reply (false) - :color (Blue) - :comments ("person-to-person or group discussions videoconference") - :etm_enabled (false) - :include_in_any (true) - :port (7648-7652) - :proto_type () - :reload_proof (false) - :replies (true) - :replies_from_any_port (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (udp) - ) - : (CreativePartnerSrvr - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB44C-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (tcp_service) - :table (services) - :name (CreativePartnerSrvr) - ) - :delayed_sync_value (30) - :use_delayed_sync (false) - :color (Red) - :comments ("The Server listening port") - :enable_tcp_resource (false) - :etm_enabled (false) - :include_in_any (true) - :port (453) - :proto_type () - :reload_proof (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (tcp) - ) - : (CreativePartnerClnt - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB44D-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (tcp_service) - :table (services) - :name (CreativePartnerClnt) - ) - :delayed_sync_value (30) - :use_delayed_sync (false) - :color (Red) - :comments ("The Client listening port") - :enable_tcp_resource (false) - :etm_enabled (false) - :include_in_any (true) - :port (455) - :proto_type () - :reload_proof (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (tcp) - ) - : (AOL - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB44F-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (tcp_service) - :table (services) - :name (AOL) - ) - :delayed_sync_value (30) - :use_delayed_sync (false) - :color (Red) - :comments ("America-Online client service (TCP)") - :enable_tcp_resource (false) - :etm_enabled (false) - :include_in_any (true) - :port (5190) - :proto_type () - :reload_proof (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (tcp) - ) - : (OnTime - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB450-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (udp_service) - :table (services) - :name (OnTime) - ) - :delete_on_reply (false) - :color (Foreground) - :comments () - :etm_enabled (false) - :include_in_any (true) - :port (1622) - :proto_type () - :reload_proof (false) - :replies (true) - :replies_from_any_port (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (udp) - ) - : (ConnectedOnLine - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB451-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (tcp_service) - :table (services) - :name (ConnectedOnLine) - ) - :delayed_sync_value (30) - :use_delayed_sync (false) - :color (Foreground) - :comments () - :enable_tcp_resource (false) - :etm_enabled (false) - :include_in_any (true) - :port (16384) - :proto_type () - :reload_proof (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (tcp) - ) - : (MSExchangeDSNSPI - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB452-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (dcerpc_service) - :table (services) - :name (MSExchangeDSNSPI) - ) - :color (Blue) - :comments ("Microsoft Exchange Directory Services (NSPI)") - :etm_enabled (false) - :proto_type () - :reload_proof (false) - :type (dcerpc) - :uuid (f5cc5a18-4264-101a-8c59-08002b2f8426) - ) - : (MSExchangeDSRep - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB453-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (dcerpc_service) - :table (services) - :name (MSExchangeDSRep) - ) - :color (Blue) - :comments ("Microsoft Exchange Directory Replication Services") - :etm_enabled (false) - :proto_type () - :reload_proof (false) - :type (dcerpc) - :uuid (f5cc59b4-4264-101a-8c59-08002b2f8426) - ) - : (MSExchangeDSXDS - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB454-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (dcerpc_service) - :table (services) - :name (MSExchangeDSXDS) - ) - :color (Blue) - :comments ("Microsoft Exchange Directory Services XDS") - :etm_enabled (false) - :proto_type () - :reload_proof (false) - :type (dcerpc) - :uuid (f5cc5a7c-4264-101a-8c59-08002b2f8426) - ) - : (MSExchangeIS - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB455-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (dcerpc_service) - :table (services) - :name (MSExchangeIS) - ) - :color (Blue) - :comments ("Microsoft Exchange Information Store") - :etm_enabled (false) - :proto_type (ReferenceObject - :Name (MSEXCHANGE) - :Table (protocols) - :Uid ("{97AEB382-9AEA-11D5-BD16-0090272CCB30}") - ) - :reload_proof (false) - :type (dcerpc) - :uuid (a4f1db00-ca47-1067-b31f-00dd010662da) - ) - : (MSExchangeMTA - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB456-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (dcerpc_service) - :table (services) - :name (MSExchangeMTA) - ) - :color (Blue) - :comments ("Microsoft Exchange Message Transfer Agent") - :etm_enabled (false) - :proto_type () - :reload_proof (false) - :type (dcerpc) - :uuid (9e8ee830-4459-11ce-979b-00aa005ffebe) - ) - : (MSExchangeADL - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB457-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (dcerpc_service) - :table (services) - :name (MSExchangeADL) - ) - :color (Blue) - :comments ("Microsoft Exchange 2000 Active Directory Logon") - :etm_enabled (false) - :proto_type () - :reload_proof (false) - :type (dcerpc) - :uuid (12345678-1234-abcd-ef00-01234567cffb) - ) - : (MSExchangeDirRep - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB458-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (dcerpc_service) - :table (services) - :name (MSExchangeDirRep) - ) - :color (Blue) - :comments ("Microsoft Exchange 2000 Directory Replication") - :etm_enabled (false) - :proto_type () - :reload_proof (false) - :type (dcerpc) - :uuid (e3514235-4b06-11d1-ab04-00c04fc2dcd2) - ) - : (MSExchangeSysAtt - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB459-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (dcerpc_service) - :table (services) - :name (MSExchangeSysAtt) - ) - :color (Blue) - :comments ("Microsoft Exchange System Attendant") - :etm_enabled (false) - :proto_type () - :reload_proof (false) - :type (dcerpc) - :uuid (469d6ec0-0d87-11ce-b13f-00aa003bac6c) - ) - : (MSExchangeSysAttPriv - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB45A-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (dcerpc_service) - :table (services) - :name (MSExchangeSysAttPriv) - ) - :color (Blue) - :comments ("Microsoft Exchange System Attendant Private") - :etm_enabled (false) - :proto_type () - :reload_proof (false) - :type (dcerpc) - :uuid (83d72bf0-0d89-11ce-b13f-00aa003bac6c) - ) - : (MSExchangeStoreAdm - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB45B-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (dcerpc_service) - :table (services) - :name (MSExchangeStoreAdm) - ) - :color (Blue) - :comments ("Microsoft Exchange Store Administration") - :etm_enabled (false) - :proto_type () - :reload_proof (false) - :type (dcerpc) - :uuid (89742ace-a9ed-11cf-9c0c-08002be7ae86) - ) - : (HP-OpCdistm - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB460-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (dcerpc_service) - :table (services) - :name (HP-OpCdistm) - ) - :color (Blue) - :comments ("HP-OV OpC Distribution Manager") - :etm_enabled (false) - :proto_type () - :reload_proof (false) - :type (dcerpc) - :uuid (5df3dc6f-a568-0000-020f-887805000000) - ) - : (HP-OpCmsgrd-std - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB461-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (dcerpc_service) - :table (services) - :name (HP-OpCmsgrd-std) - ) - :color (Blue) - :comments ("HP-OV OpC Message Receiver") - :etm_enabled (false) - :proto_type () - :reload_proof (false) - :type (dcerpc) - :uuid (6d63f833-c0a0-0000-020f-887818000000) - ) - : (HP-OpCmsgrd-m2m - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB462-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (dcerpc_service) - :table (services) - :name (HP-OpCmsgrd-m2m) - ) - :color (Blue) - :comments ("HP-OV OpC Message Receiver (M2M)") - :etm_enabled (false) - :proto_type () - :reload_proof (false) - :type (dcerpc) - :uuid (6e0b494b-d551-0000-020f-88781a000000) - ) - : (HP-OpCmsgrd-coa - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB463-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (dcerpc_service) - :table (services) - :name (HP-OpCmsgrd-coa) - ) - :color (Blue) - :comments ("HP-OV OpC Message receiver (COA)") - :etm_enabled (false) - :proto_type () - :reload_proof (false) - :type (dcerpc) - :uuid (e0c92330-3ba9-0000-a38b-0800096df3a6) - ) - : (HP-OpCctla - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB464-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (dcerpc_service) - :table (services) - :name (HP-OpCctla) - ) - :color (Blue) - :comments ("HP-OV OpC Control Agent") - :etm_enabled (false) - :proto_type () - :reload_proof (false) - :type (dcerpc) - :uuid (9e0c0224-3654-0000-9a8d-08000949ab4c) - ) - : (HP-OpCctla-cfgpush - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB465-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (dcerpc_service) - :table (services) - :name (HP-OpCctla-cfgpush) - ) - :color (Blue) - :comments ("HP-OV OpC Control Agent (cfgpush)") - :etm_enabled (false) - :proto_type () - :reload_proof (false) - :type (dcerpc) - :uuid (0d8fe322-d6ee-11d2-b858-0800096df3a6) - ) - : (HP-OpCctla-bulk - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB466-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (dcerpc_service) - :table (services) - :name (HP-OpCctla-bulk) - ) - :color (Blue) - :comments ("HP-OV OpC Control Agent (Bulk)") - :etm_enabled (false) - :proto_type () - :reload_proof (false) - :type (dcerpc) - :uuid (8d5cae88-43c9-0000-94f1-0800096df3a6) - ) - : (Pointcast - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB477-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (compound_tcp_service) - :table (services) - :name (Pointcast) - ) - :color ("Forest Green") - :comments ("http subservice for FloodGate use, push web content") - :etm_enabled (false) - :port (80) - :proto_type () - :reload_proof (false) - :svc_type (pointcast) - :type (Tcp_subservice) - ) - : (Cdf - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB478-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (compound_tcp_service) - :table (services) - :name (Cdf) - ) - :color ("Forest Green") - :comments ("http subservice for FloodGate use,Channel Definition Format") - :etm_enabled (false) - :port (80) - :proto_type () - :reload_proof (false) - :svc_type (Cdf) - :type (Tcp_subservice) - ) - : (Marimba_Netcaster - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB479-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (compound_tcp_service) - :table (services) - :name (Marimba_Netcaster) - ) - :color (black) - :comments ("http subservice for FloodGate use, Marimba Castanet Tuner product") - :etm_enabled (false) - :port (80) - :proto_type () - :reload_proof (false) - :svc_type (NetCaster) - :type (Tcp_subservice) - ) - : (Microsoft_Channels - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB47A-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (compound_tcp_service) - :table (services) - :name (Microsoft_Channels) - ) - :color (black) - :comments ("http subservice for FloodGate use, Microsoft Channels") - :etm_enabled (false) - :port (80) - :proto_type () - :reload_proof (false) - :svc_type (CDF) - :type (Tcp_subservice) - ) - : (squid - :AdminInfo ( - :chkpf_uid ("{91C0454D-F70C-44B3-8F2D-70C4A68E9594}") - :ClassName (tcp_service) - :table (services) - :Wiznum (-1) - :LastModified ( - :Time ("Sun Nov 30 19:21:23 2003") - :By (IsoAAAF) - :From (scratchy) - ) - ) - :delayed_sync_value (30) - :use_delayed_sync (false) - :color ("forest green") - :comments () - :enable_tcp_resource (false) - :etm_enabled (false) - :include_in_any (true) - :port (3128) - :proto_type () - :reload_proof (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (Tcp) - ) - : (RAdmin-custom - :AdminInfo ( - :chkpf_uid ("{4FB59153-8212-4A12-BC08-0297AA5F0815}") - :ClassName (tcp_service) - :table (services) - :Wiznum (-1) - :LastModified ( - :Time ("Sun Nov 30 19:36:18 2003") - :By (IsoAAAF) - :From (scratchy) - ) - ) - :delayed_sync_value (30) - :use_delayed_sync (false) - :color (gold) - :comments () - :enable_tcp_resource (false) - :etm_enabled (false) - :include_in_any (true) - :port (60000) - :proto_type () - :reload_proof (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (Tcp) - ) - : (apcupsd - :AdminInfo ( - :chkpf_uid ("{A1044CB4-439C-40C9-8489-FA5086134886}") - :ClassName (tcp_service) - :table (services) - :Wiznum (-1) - :LastModified ( - :Time ("Fri Dec 5 20:06:52 2003") - :By (IsoAAAF) - :From (scratchy) - ) - ) - :delayed_sync_value (30) - :use_delayed_sync (false) - :color (gold) - :comments () - :enable_tcp_resource (false) - :etm_enabled (false) - :include_in_any (false) - :port (6666) - :proto_type () - :reload_proof (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (Tcp) - ) - : (T-online-classic - :AdminInfo ( - :chkpf_uid ("{738B04E5-09F7-44BF-9FEC-AEA0F15B7E9A}") - :ClassName (tcp_service) - :table (services) - :Wiznum (-1) - :LastModified ( - :Time ("Wed Dec 17 21:34:22 2003") - :By (IsoAAAF) - :From (scratchy) - ) - ) - :delayed_sync_value (30) - :use_delayed_sync (false) - :color ("deep pink") - :comments () - :enable_tcp_resource (false) - :etm_enabled (false) - :include_in_any (true) - :port (866) - :proto_type () - :reload_proof (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (Tcp) - ) - : (H323 - :AdminInfo ( - :chkpf_uid ("{97AEB427-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (tcp_service) - :table (services) - :Wiznum (-1) - :LastModified ( - :Time ("Fri Jan 30 21:58:29 2004") - :By (IsoAAAF) - :From (scratchy) - ) - ) - :delayed_sync_value (30) - :use_delayed_sync (false) - :color (cyan) - :comments ("videoconference transmissions over IP networks") - :enable_tcp_resource (false) - :etm_enabled (true) - :include_in_any (false) - :port (1720) - :proto_type (ReferenceObject - :Name (H.323) - :Table (protocols) - :Uid ("{97AEB377-9AEA-11D5-BD16-0090272CCB30}") - ) - :reload_proof (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (tcp) - ) - : (H323_any - :AdminInfo ( - :chkpf_uid ("{97AEB427-9AEA-11D5-BD16-0090272CCB33}") - :ClassName (tcp_service) - :table (services) - :Wiznum (-1) - :LastModified ( - :Time ("Fri Jan 30 21:59:04 2004") - :By (IsoAAAF) - :From (scratchy) - ) - ) - :delayed_sync_value (30) - :use_delayed_sync (false) - :color (cyan) - :comments ("videoconference transmissions over IP networks") - :enable_tcp_resource (false) - :etm_enabled (true) - :include_in_any (false) - :port (1720) - :proto_type (ReferenceObject - :Name (H.323_ANY) - :Table (protocols) - :Uid ("{97AEB377-9AEA-11D5-BD16-0090272CCB35}") - ) - :reload_proof (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (tcp) - ) - : (Citrix_metaFrame - :AdminInfo ( - :chkpf_uid ("{13D7904E-334B-4549-8FBD-6B4D6B8B80B2}") - :ClassName (service_group) - :table (services) - :Wiznum (-1) - :LastModified ( - :Time ("Sun Mar 30 14:50:57 2003") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - : (ReferenceObject - :Name (Citrix_ICA) - :Table (services) - :Uid ("{986BAD5A-94D2-4A8C-81AA-DE98D3ECB5C6}") - ) - : (ReferenceObject - :Name (Citrix_ICA_Browsing) - :Table (services) - :Uid ("{E8C5AB78-F08D-437C-A9B1-BE4A8679D766}") - ) - :color (black) - :comments ("group for citrix communication") - :etm_enabled (false) - :member_class (service) - :members_query () - :type (group) - ) - : (Trojan_Services - :AdminInfo ( - :chkpf_uid ("{F956089C-6DD8-4FF4-9FB1-E13969CDADFF}") - :ClassName (service_group) - :table (services) - :Wiznum (-1) - :LastModified ( - :Time ("Tue Jan 07 19:44:37 2003") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - : (ReferenceObject - :Name (Back_Door_Setup) - :Table (services) - :Uid ("{86077A7D-A8DA-4B5B-919C-366FE91AD1DA}") - ) - : (ReferenceObject - :Name (Backage) - :Table (services) - :Uid ("{96759A8D-AAB8-43D9-BBFC-B459CE66AC87}") - ) - : (ReferenceObject - :Name (BackDoor-G) - :Table (services) - :Uid ("{A651F18C-1C7C-4BD2-9FFE-790C29E3CCD9}") - ) - : (ReferenceObject - :Name (Connect-Back_Backdoor) - :Table (services) - :Uid ("{E0C17142-433D-40A7-9EAA-E1D5EBA40D2E}") - ) - : (ReferenceObject - :Name (CrackDown) - :Table (services) - :Uid ("{88AAA643-BF12-4D40-A02D-E98A8159358A}") - ) - : (ReferenceObject - :Name (DaCryptic) - :Table (services) - :Uid ("{C13E3031-02D6-4341-A307-3DAF10735078}") - ) - : (ReferenceObject - :Name (DerSphere) - :Table (services) - :Uid ("{8055B0DE-DACE-4D18-91F4-F39915B7ABA8}") - ) - : (ReferenceObject - :Name (DerSphere_II) - :Table (services) - :Uid ("{8D971C42-17DE-49A0-A646-A8E0057AEBBD}") - ) - : (ReferenceObject - :Name (Freak2k) - :Table (services) - :Uid ("{08DA33FF-BC5F-402A-9865-BEE8FEE69422}") - ) - : (ReferenceObject - :Name (GateCrasher) - :Table (services) - :Uid ("{81B90130-2A31-45CD-8092-DC492B116CA9}") - ) - : (ReferenceObject - :Name (HackaTack_31785) - :Table (services) - :Uid ("{82BA0DD2-42E6-472D-8877-57F519175C14}") - ) - : (ReferenceObject - :Name (HackaTack_31787) - :Table (services) - :Uid ("{C693C8C1-78E3-450D-936E-AA3278190633}") - ) - : (ReferenceObject - :Name (HackaTack_31788) - :Table (services) - :Uid ("{B8D159DC-AA70-4CC5-9C5A-8C2AD3AA977E}") - ) - : (ReferenceObject - :Name (HackaTack_31789) - :Table (services) - :Uid ("{FF8EA038-34FD-4B7B-8A8A-8D6BF0A599FE}") - ) - : (ReferenceObject - :Name (HackaTack_31790) - :Table (services) - :Uid ("{2176F91C-5FB4-4111-98BD-7D5D5B358FE0}") - ) - : (ReferenceObject - :Name (HackaTack_31791) - :Table (services) - :Uid ("{05647A8C-F0E7-4354-ADBD-C685EE7742F0}") - ) - : (ReferenceObject - :Name (HackaTack_31792) - :Table (services) - :Uid ("{26339B33-1C42-4E49-96E9-55770F6AF0CE}") - ) - : (ReferenceObject - :Name (ICKiller) - :Table (services) - :Uid ("{06233377-3454-489A-B9FB-2F2CA14B895B}") - ) - : (ReferenceObject - :Name (InCommand) - :Table (services) - :Uid ("{230B24DF-1EFA-4A28-B7A4-87DFB79AFBA7}") - ) - : (ReferenceObject - :Name (Jade) - :Table (services) - :Uid ("{C2F963B0-DB3C-42D5-B0F2-A2A7BC0D378D}") - ) - : (ReferenceObject - :Name (Kaos) - :Table (services) - :Uid ("{10F56849-2E03-40DD-9CF7-56AEE2CFA57F}") - ) - : (ReferenceObject - :Name (Kuang2) - :Table (services) - :Uid ("{CE29B597-76B9-48AA-AC24-AE7E23C438ED}") - ) - : (ReferenceObject - :Name (lpdw0rm) - :Table (services) - :Uid ("{73BFBF75-EB13-42C0-BA69-58B8F026B4D6}") - ) - : (ReferenceObject - :Name (Mneah) - :Table (services) - :Uid ("{E43B7817-DBB6-4C74-A95A-C424DC47999C}") - ) - : (ReferenceObject - :Name (Multidropper) - :Table (services) - :Uid ("{E38E4DEA-A610-4416-BF44-6F4E45E95E70}") - ) - : (ReferenceObject - :Name (NoBackO) - :Table (services) - :Uid ("{AA02E546-80D1-453A-91DC-49F606764451}") - ) - : (ReferenceObject - :Name (Port_6667_trojans) - :Table (services) - :Uid ("{AEAA6C77-E87E-4581-AD73-06417391DFAD}") - ) - : (ReferenceObject - :Name (RAT) - :Table (services) - :Uid ("{B236D830-9615-4578-B6E2-B0B44C45FDA0}") - ) - : (ReferenceObject - :Name (Remote_Storm) - :Table (services) - :Uid ("{D4B1F3B0-C606-4B6B-8118-EE61303F8E19}") - ) - : (ReferenceObject - :Name (RexxRave) - :Table (services) - :Uid ("{637B7F26-C4B2-4510-872E-5A10DE046CB4}") - ) - : (ReferenceObject - :Name (Shadyshell) - :Table (services) - :Uid ("{41C4DF08-DBF9-4576-9114-B8F1DC4DC8D7}") - ) - : (ReferenceObject - :Name (SocketsdesTroie) - :Table (services) - :Uid ("{69CA7583-1FD4-4C86-AC1A-680697A9AF93}") - ) - : (ReferenceObject - :Name (SubSeven) - :Table (services) - :Uid ("{E926E948-FAE7-4140-8FED-11426B1A32B9}") - ) - : (ReferenceObject - :Name (Terrortrojan) - :Table (services) - :Uid ("{CC1D78CC-5FCE-4496-A78B-C37AA0622F7A}") - ) - : (ReferenceObject - :Name (TheFlu) - :Table (services) - :Uid ("{02F708DD-0337-485F-A04B-3B931971B93A}") - ) - : (ReferenceObject - :Name (TransScout) - :Table (services) - :Uid ("{16AEE006-0F79-407E-B6A4-F3CC5A7A31D5}") - ) - : (ReferenceObject - :Name (Trinoo) - :Table (services) - :Uid ("{3CF4DA8B-576E-47EC-903E-91F155BD0CD9}") - ) - : (ReferenceObject - :Name (UltorsTrojan) - :Table (services) - :Uid ("{6E745536-B8C9-4DF5-BFD5-043E62013956}") - ) - : (ReferenceObject - :Name (WinHole) - :Table (services) - :Uid ("{25AC306E-1FC9-4E3E-BF66-4A48473CAF3F}") - ) - : (ReferenceObject - :Name (Xanadu) - :Table (services) - :Uid ("{24DE2CDE-DFCD-4C9B-9124-492AC4BEDBA7}") - ) - :color (magenta) - :comments ("Common ports used by trojan applications.") - :etm_enabled (false) - :member_class (service) - :members_query () - :type (group) - ) - : (MS-SQL - :AdminInfo ( - :chkpf_uid ("{68A602A2-28DA-4425-B566-86A537A3BCA3}") - :ClassName (service_group) - :table (services) - :Wiznum (-1) - :LastModified ( - :Time ("Thu Feb 20 18:15:39 2003") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - : (ReferenceObject - :Name (MS-SQL-Monitor) - :Table (services) - :Uid ("{EF245528-9A3D-11D6-9EAA-3E5A6FDD6A6A}") - ) - : (ReferenceObject - :Name (MS-SQL-Monitor_UDP) - :Table (services) - :Uid ("{5AD1A14C-647C-41DE-9F84-D1C34F09D63B}") - ) - : (ReferenceObject - :Name (MS-SQL-Server) - :Table (services) - :Uid ("{DFF4F7BA-9A3D-11D6-91C1-3E5A6FDD5151}") - ) - : (ReferenceObject - :Name (MS-SQL-Server_UDP) - :Table (services) - :Uid ("{BFD72CD2-8E5F-4EDE-BDB2-6DFC016AFCCD}") - ) - :color (black) - :comments ("MS-SQL Server Protocols") - :etm_enabled (false) - :member_class (service) - :members_query () - :type (group) - ) - : (AOL_Messenger - :AdminInfo ( - :chkpf_uid ("{2C970C2B-84A3-40B5-AB0E-83244DD47BCD}") - :ClassName (service_group) - :table (services) - :Wiznum (-1) - :LastModified ( - :Time ("Thu Dec 12 14:19:56 2002") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - : (ReferenceObject - :Name (AOL) - :Table (services) - :Uid ("{97AEB44F-9AEA-11D5-BD16-0090272CCB30}") - ) - : (ReferenceObject - :Name (ICQ_locator) - :Table (services) - :Uid ("{BBEC6807-808D-49B7-B8DC-54C5A655D392}") - ) - :color (black) - :comments ("AOL Instant Messenger. Also used by: ICQ & Apple iChat") - :etm_enabled (false) - :member_class (service) - :members_query () - :type (group) - ) - : (MSN_Messenger - :AdminInfo ( - :chkpf_uid ("{5693ACA1-316D-410E-A8F3-BA5D2F97E5B7}") - :ClassName (service_group) - :table (services) - :Wiznum (-1) - :LastModified ( - :Time ("Thu Dec 12 14:24:19 2002") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - : (ReferenceObject - :Name (MSN_Messenger_1863_UDP) - :Table (services) - :Uid ("{0094AAC2-A29E-4D04-B86C-F31F63DFFAE2}") - ) - : (ReferenceObject - :Name (MSN_Messenger_5190) - :Table (services) - :Uid ("{0AC39B6A-701A-4C33-A88D-9EB0FECF9EF6}") - ) - : (ReferenceObject - :Name (MSN_Messenger_File_Transfer) - :Table (services) - :Uid ("{505BADAD-AE57-4584-9A4C-15987C093A32}") - ) - : (ReferenceObject - :Name (MSN_Messenger_Voice) - :Table (services) - :Uid ("{E3E6D587-3212-4FF4-86A1-D16093689E19}") - ) - : (ReferenceObject - :Name (MSNP) - :Table (services) - :Uid ("{D18F244B-0B13-4FB8-AA2F-D966EEFFB6B3}") - ) - :color (black) - :comments ("MSN Messenger") - :etm_enabled (false) - :member_class (service) - :members_query () - :type (group) - ) - : (Yahoo_Messenger - :AdminInfo ( - :chkpf_uid ("{8E3ED837-81C6-43EF-BADA-7C330C57D891}") - :ClassName (service_group) - :table (services) - :Wiznum (-1) - :LastModified ( - :Time ("Thu Dec 12 14:25:36 2002") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - : (ReferenceObject - :Name (Yahoo_Messenger_messages) - :Table (services) - :Uid ("{24CD3A7C-AA2C-43D4-8EB6-FF1F070143EA}") - ) - : (ReferenceObject - :Name (Yahoo_Messenger_Voice_Chat_TCP) - :Table (services) - :Uid ("{C2639E22-FD63-4520-99F7-A70215B95874}") - ) - : (ReferenceObject - :Name (Yahoo_Messenger_Voice_Chat_UDP) - :Table (services) - :Uid ("{C98BB09A-B04F-437C-AD1A-6C8261831B87}") - ) - : (ReferenceObject - :Name (Yahoo_Messenger_Webcams) - :Table (services) - :Uid ("{910F509F-8F2A-452D-BC15-E51F8CC1694C}") - ) - :color (blue) - :comments ("Yahoo Messenger") - :etm_enabled (false) - :member_class (service) - :members_query () - :type (group) - ) - : (Messenger_Applications - :AdminInfo ( - :chkpf_uid ("{CD7C1A5F-6268-40B6-A8C7-2727B8036CB1}") - :ClassName (service_group) - :table (services) - :Wiznum (-1) - :LastModified ( - :Time ("Thu Dec 12 14:28:17 2002") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - : (ReferenceObject - :Name (AOL_Messenger) - :Table (services) - :Uid ("{2C970C2B-84A3-40B5-AB0E-83244DD47BCD}") - ) - : (ReferenceObject - :Name (MSN_Messenger) - :Table (services) - :Uid ("{5693ACA1-316D-410E-A8F3-BA5D2F97E5B7}") - ) - : (ReferenceObject - :Name (Yahoo_Messenger) - :Table (services) - :Uid ("{8E3ED837-81C6-43EF-BADA-7C330C57D891}") - ) - :color (black) - :comments () - :etm_enabled (false) - :member_class (service) - :members_query () - :type (group) - ) - : (Direct_Connect - :AdminInfo ( - :chkpf_uid ("{5CFC76C2-B743-4B68-9FBF-E901EAA3698D}") - :ClassName (service_group) - :table (services) - :Wiznum (-1) - :LastModified ( - :Time ("Thu Dec 12 14:29:23 2002") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - : (ReferenceObject - :Name (Direct_Connect_TCP) - :Table (services) - :Uid ("{D02080C1-B225-4DA0-987B-28B3A551B8C9}") - ) - : (ReferenceObject - :Name (Direct_Connect_UDP) - :Table (services) - :Uid ("{64C3AD3F-69D2-4EC1-B843-5DF030C70ABF}") - ) - :color (black) - :comments ("Direct Connect P2P application. Used also by other clients") - :etm_enabled (false) - :member_class (service) - :members_query () - :type (group) - ) - : (eDonkey - :AdminInfo ( - :chkpf_uid ("{42929FB0-C8DD-465E-BE01-3E484F4299F6}") - :ClassName (service_group) - :table (services) - :Wiznum (-1) - :LastModified ( - :Time ("Thu Dec 12 14:33:32 2002") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - : (ReferenceObject - :Name (eDonkey_4661) - :Table (services) - :Uid ("{760D9035-1C76-4C5C-B929-BA1DC6685D6F}") - ) - : (ReferenceObject - :Name (eDonkey_4662) - :Table (services) - :Uid ("{7115E261-185C-4487-AA18-84F8C275D186}") - ) - : (ReferenceObject - :Name (eDonkey_4665) - :Table (services) - :Uid ("{D3CAA92A-1032-41AE-A1A1-2274F3AB9F45}") - ) - :color (black) - :comments ("eDonkey protocol. Used also by other clients.") - :etm_enabled (false) - :member_class (service) - :members_query () - :type (group) - ) - : (GNUtella - :AdminInfo ( - :chkpf_uid ("{F0059B62-E18E-478F-A3BD-18595D53D3E1}") - :ClassName (service_group) - :table (services) - :Wiznum (-1) - :LastModified ( - :Time ("Thu Dec 12 14:35:10 2002") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - : (ReferenceObject - :Name (GNUtella_rtr_TCP) - :Table (services) - :Uid ("{B1189907-B9EB-4A21-8B38-1D3E5C6C06D0}") - ) - : (ReferenceObject - :Name (GNUtella_rtr_UDP) - :Table (services) - :Uid ("{1B4543A3-579E-4CC7-8F57-4387C37A6815}") - ) - : (ReferenceObject - :Name (GNUtella_TCP) - :Table (services) - :Uid ("{CDEF1FEB-485E-4929-942E-011DE8318E56}") - ) - : (ReferenceObject - :Name (GNUtella_UDP) - :Table (services) - :Uid ("{8EB18480-2690-4520-AE88-412BF5CE94E3}") - ) - :color (black) - :comments ("GNUtella P2P protocol (used by: BearShare, ToadNode, Gnucleus, Xolox, LimeWire)") - :etm_enabled (false) - :member_class (service) - :members_query () - :type (group) - ) - : (Hotline - :AdminInfo ( - :chkpf_uid ("{4C3E148F-BCC4-4C97-9955-09DA850FB9A6}") - :ClassName (service_group) - :table (services) - :Wiznum (-1) - :LastModified ( - :Time ("Thu Dec 12 14:37:42 2002") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - : (ReferenceObject - :Name (Hotline_client) - :Table (services) - :Uid ("{B45556D9-5E0B-46F4-9C35-ED7D82BEC43D}") - ) - : (ReferenceObject - :Name (Hotline_tracker) - :Table (services) - :Uid ("{D6B64DF2-4803-4D79-9794-793D18B277D8}") - ) - :color (black) - :comments ("Hotline P2P protocol") - :etm_enabled (false) - :member_class (service) - :members_query () - :type (group) - ) - : (DAIP_Control_services - :AdminInfo ( - :chkpf_uid ("{77C21EA4-9DB4-40FE-86E0-58252C3759D8}") - :ClassName (service_group) - :table (services) - :Wiznum (-1) - :LastModified ( - :Time ("Thu Apr 03 09:38:32 2003") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - : (ReferenceObject - :Name (CPD) - :Table (services) - :Uid ("{97AEB3AB-9AEA-11D5-BD16-0090272CCB30}") - ) - : (ReferenceObject - :Name (FW1) - :Table (services) - :Uid ("{97AEB388-9AEA-11D5-BD16-0090272CCB30}") - ) - : (ReferenceObject - :Name (FW1_ica_pull) - :Table (services) - :Uid ("{97AEB3A4-9AEA-11D5-BD16-0090272CCB30}") - ) - : (ReferenceObject - :Name (FW1_log) - :Table (services) - :Uid ("{97AEB389-9AEA-11D5-BD16-0090272CCB30}") - ) - :color (black) - :comments () - :etm_enabled (false) - :member_class (service) - :members_query () - :type (group) - ) - : (Napster - :AdminInfo ( - :chkpf_uid ("{5EE3CA5B-35A2-4988-859C-7157E8CFFEAD}") - :ClassName (service_group) - :table (services) - :Wiznum (-1) - :LastModified ( - :Time ("Thu Dec 12 14:38:38 2002") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - : (ReferenceObject - :Name (Napster_Client_6600-6699) - :Table (services) - :Uid ("{3BB26988-E0A5-45D6-8018-D4D4DE8B96FA}") - ) - : (ReferenceObject - :Name (Napster_directory_4444) - :Table (services) - :Uid ("{741A5B0E-3788-4284-91A1-819E99D9ED96}") - ) - : (ReferenceObject - :Name (Napster_directory_5555) - :Table (services) - :Uid ("{8287D6D8-3B6B-4824-8F2D-18BC570EC9B2}") - ) - : (ReferenceObject - :Name (Napster_directory_6666) - :Table (services) - :Uid ("{1EF8FC95-FF10-414B-AF76-C0BCC2CD711E}") - ) - : (ReferenceObject - :Name (Napster_directory_7777) - :Table (services) - :Uid ("{182B1D39-54B6-4E2F-BAE8-2D8021D52206}") - ) - : (ReferenceObject - :Name (Napster_directory_8888_primary) - :Table (services) - :Uid ("{BE51561E-7876-4C70-9546-0914AE737F6E}") - ) - : (ReferenceObject - :Name (Napster_redirector) - :Table (services) - :Uid ("{3FD0D58A-9759-4686-B103-D177ADFC7193}") - ) - :color (black) - :comments ("Napster P2P protocol") - :etm_enabled (false) - :member_class (service) - :members_query () - :type (group) - ) - : (CIFS - :AdminInfo ( - :chkpf_uid ("{2A469820-B502-434C-9340-A377677A6A60}") - :ClassName (service_group) - :table (services) - :LastModified ( - :Time ("Wed Jun 12 12:11:06 2002") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - : (ReferenceObject - :Name (microsoft-ds) - :Table (services) - :Uid ("{CFBCACE4-7C6F-11D6-BF0E-3E5A6FE83232}") - ) - : (ReferenceObject - :Name (NBT) - :Table (services) - :Uid ("{97AEB471-9AEA-11D5-BD16-0090272CCB30}") - ) - :color (black) - :comments ("Common Internet File System Services") - :etm_enabled (false) - :member_class (service) - :members_query () - :type (group) - ) - : (FW1_clntauth - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:07 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB38D-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (service_group) - :table (services) - :name (FW1_clntauth) - ) - : (ReferenceObject - :Name (FW1_clntauth_telnet) - :Table (services) - :Uid ("{97AEB38B-9AEA-11D5-BD16-0090272CCB30}") - ) - : (ReferenceObject - :Name (FW1_clntauth_http) - :Table (services) - :Uid ("{97AEB38C-9AEA-11D5-BD16-0090272CCB30}") - ) - :color (FireBrick) - :comments ("Check Point VPN-1 & FireWall-1 Client Authentication") - :etm_enabled (false) - :member_class (service) - :members_query () - :type (group) - ) - : (sqlnet2 - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:07 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB3F2-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (service_group) - :table (services) - :name (sqlnet2) - ) - : (ReferenceObject - :Name (sqlnet2-1521) - :Table (services) - :Uid ("{97AEB3EF-9AEA-11D5-BD16-0090272CCB30}") - ) - : (ReferenceObject - :Name (sqlnet2-1525) - :Table (services) - :Uid ("{97AEB3F0-9AEA-11D5-BD16-0090272CCB30}") - ) - : (ReferenceObject - :Name (sqlnet2-1526) - :Table (services) - :Uid ("{97AEB3F1-9AEA-11D5-BD16-0090272CCB30}") - ) - :color (Foreground) - :comments ("Oracle SQL*Net Version 2 Services") - :etm_enabled (false) - :member_class (service) - :members_query () - :type (group) - ) - : (FreeTel-outgoing - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:07 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB3F5-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (service_group) - :table (services) - :name (FreeTel-outgoing) - ) - : (ReferenceObject - :Name (FreeTel-outgoing-server) - :Table (services) - :Uid ("{97AEB3F3-9AEA-11D5-BD16-0090272CCB30}") - ) - : (ReferenceObject - :Name (FreeTel-outgoing-client) - :Table (services) - :Uid ("{97AEB3F4-9AEA-11D5-BD16-0090272CCB30}") - ) - :color (Foreground) - :comments ("FreeTel Outgoing Connections") - :etm_enabled (false) - :member_class (service) - :members_query () - :type (group) - ) - : (icmp-requests - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB413-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (service_group) - :table (services) - :name (icmp-requests) - ) - : (ReferenceObject - :Name (echo-request) - :Table (services) - :Uid ("{97AEB40A-9AEA-11D5-BD16-0090272CCB30}") - ) - : (ReferenceObject - :Name (info-req) - :Table (services) - :Uid ("{97AEB40F-9AEA-11D5-BD16-0090272CCB30}") - ) - : (ReferenceObject - :Name (timestamp) - :Table (services) - :Uid ("{97AEB40D-9AEA-11D5-BD16-0090272CCB30}") - ) - : (ReferenceObject - :Name (mask-request) - :Table (services) - :Uid ("{97AEB411-9AEA-11D5-BD16-0090272CCB30}") - ) - :color ("Dark Orchid") - :comments ("ICMP, requests group") - :etm_enabled (false) - :member_class (service) - :members_query () - :type (group) - ) - : (Orbix - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB42C-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (service_group) - :table (services) - :name (Orbix) - ) - : (ReferenceObject - :Name (Orbix-1570) - :Table (services) - :Uid ("{97AEB42A-9AEA-11D5-BD16-0090272CCB30}") - ) - : (ReferenceObject - :Name (Orbix-1571) - :Table (services) - :Uid ("{97AEB42B-9AEA-11D5-BD16-0090272CCB30}") - ) - :color (black) - :comments ("IONA Orbix Daemon (IIOP)") - :etm_enabled (false) - :member_class (service) - :members_query () - :type (group) - ) - : (OAS - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB42F-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (service_group) - :table (services) - :name (OAS) - ) - : (ReferenceObject - :Name (OAS-NameServer) - :Table (services) - :Uid ("{97AEB42D-9AEA-11D5-BD16-0090272CCB30}") - ) - : (ReferenceObject - :Name (OAS-ORB) - :Table (services) - :Uid ("{97AEB42E-9AEA-11D5-BD16-0090272CCB30}") - ) - :color (black) - :comments ("Oracle Application Server (IIOP)") - :etm_enabled (false) - :member_class (service) - :members_query () - :type (group) - ) - : (StoneBeat - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB43A-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (service_group) - :table (services) - :name (StoneBeat) - ) - : (ReferenceObject - :Name (StoneBeat-Control) - :Table (services) - :Uid ("{97AEB438-9AEA-11D5-BD16-0090272CCB30}") - ) - : (ReferenceObject - :Name (StoneBeat-Daemon) - :Table (services) - :Uid ("{97AEB439-9AEA-11D5-BD16-0090272CCB30}") - ) - : (ReferenceObject - :Name (snmp) - :Table (services) - :Uid ("{97AEB3B2-9AEA-11D5-BD16-0090272CCB30}") - ) - :color (Black) - :comments ("Stonesoft StoneBeat") - :etm_enabled (false) - :member_class (service) - :members_query () - :type (group) - ) - : (RealPlayer - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB43C-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (service_group) - :table (services) - :name (RealPlayer) - ) - : (ReferenceObject - :Name (Real-Audio) - :Table (services) - :Uid ("{97AEB41B-9AEA-11D5-BD16-0090272CCB30}") - ) - : (ReferenceObject - :Name (rtsp) - :Table (services) - :Uid ("{97AEB41C-9AEA-11D5-BD16-0090272CCB30}") - ) - :color (Blue) - :comments ("RealNetworks RealPlayer Services") - :etm_enabled (false) - :member_class (service) - :members_query () - :type (group) - ) - : (NetMeeting - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB43D-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (service_group) - :table (services) - :name (NetMeeting) - ) - : (ReferenceObject - :Name (H323) - :Table (services) - :Uid ("{97AEB427-9AEA-11D5-BD16-0090272CCB30}") - ) - : (ReferenceObject - :Name (ldap) - :Table (services) - :Uid ("{97AEB433-9AEA-11D5-BD16-0090272CCB30}") - ) - :color ("Dark Green") - :comments ("Netmeeting group (H323 & Ldap)") - :etm_enabled (true) - :member_class (service) - :members_query () - :type (group) - ) - : (pcANYWHERE - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB440-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (service_group) - :table (services) - :name (pcANYWHERE) - ) - : (ReferenceObject - :Name (pcANYWHERE-data) - :Table (services) - :Uid ("{97AEB43E-9AEA-11D5-BD16-0090272CCB30}") - ) - : (ReferenceObject - :Name (pcANYWHERE-stat) - :Table (services) - :Uid ("{97AEB43F-9AEA-11D5-BD16-0090272CCB30}") - ) - :color (Blue) - :comments ("Symantec pcANYWHERE") - :etm_enabled (false) - :member_class (service) - :members_query () - :type (group) - ) - : (pcTELECOMMUTE - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB442-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (service_group) - :table (services) - :name (pcTELECOMMUTE) - ) - : (ReferenceObject - :Name (pcANYWHERE) - :Table (services) - :Uid ("{97AEB440-9AEA-11D5-BD16-0090272CCB30}") - ) - : (ReferenceObject - :Name (pcTELECOMMUTE-FileSync) - :Table (services) - :Uid ("{97AEB441-9AEA-11D5-BD16-0090272CCB30}") - ) - :color (Blue) - :comments ("Symantec pcTELECOMMUTE") - :etm_enabled (false) - :member_class (service) - :members_query () - :type (group) - ) - : (MSExchange - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB45C-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (service_group) - :table (services) - :name (MSExchange) - ) - : (ReferenceObject - :Name (MSExchangeDSNSPI) - :Table (services) - :Uid ("{97AEB452-9AEA-11D5-BD16-0090272CCB30}") - ) - : (ReferenceObject - :Name (MSExchangeIS) - :Table (services) - :Uid ("{97AEB455-9AEA-11D5-BD16-0090272CCB30}") - ) - : (ReferenceObject - :Name (MSExchangeDirRef) - :Table (services) - :Uid ("{01693eed-3f81-44d3-b498-51696722cc32}") - ) - :color (Blue) - :comments ("Microsoft Exchange Client-Server over MAPI") - :etm_enabled (false) - :member_class (service) - :members_query () - :type (group) - ) - : (MSExchange-SiteConnector - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB45D-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (service_group) - :table (services) - :name (MSExchange-SiteConnector) - ) - : (ReferenceObject - :Name (MSExchangeDSNSPI) - :Table (services) - :Uid ("{97AEB452-9AEA-11D5-BD16-0090272CCB30}") - ) - : (ReferenceObject - :Name (MSExchangeDSRep) - :Table (services) - :Uid ("{97AEB453-9AEA-11D5-BD16-0090272CCB30}") - ) - : (ReferenceObject - :Name (MSExchangeMTA) - :Table (services) - :Uid ("{97AEB456-9AEA-11D5-BD16-0090272CCB30}") - ) - :color (Blue) - :comments ("Microsoft Exchange MAPI Site Connector") - :etm_enabled (false) - :member_class (service) - :members_query () - :type (group) - ) - : (MSExchange-RemoteAdmin - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB45E-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (service_group) - :table (services) - :name (MSExchange-RemoteAdmin) - ) - : (ReferenceObject - :Name (MSExchangeDSXDS) - :Table (services) - :Uid ("{97AEB454-9AEA-11D5-BD16-0090272CCB30}") - ) - : (ReferenceObject - :Name (MSExchangeSysAtt) - :Table (services) - :Uid ("{97AEB459-9AEA-11D5-BD16-0090272CCB30}") - ) - : (ReferenceObject - :Name (MSExchangeSysAttPriv) - :Table (services) - :Uid ("{97AEB45A-9AEA-11D5-BD16-0090272CCB30}") - ) - : (ReferenceObject - :Name (MSExchangeStoreAdm) - :Table (services) - :Uid ("{97AEB45B-9AEA-11D5-BD16-0090272CCB30}") - ) - :color (Blue) - :comments ("Microsoft Exchange Remote Administration") - :etm_enabled (false) - :member_class (service) - :members_query () - :type (group) - ) - : (MSExchange-2000 - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB45F-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (service_group) - :table (services) - :name (MSExchange-2000) - ) - : (ReferenceObject - :Name (MSExchangeADL) - :Table (services) - :Uid ("{97AEB457-9AEA-11D5-BD16-0090272CCB30}") - ) - : (ReferenceObject - :Name (MSExchangeDirRep) - :Table (services) - :Uid ("{97AEB458-9AEA-11D5-BD16-0090272CCB30}") - ) - : (ReferenceObject - :Name (MSExchangeDirRef) - :Table (services) - :Uid ("{01693eed-3f81-44d3-b498-51696722cc32}") - ) - :color (Blue) - :comments ("Microsoft Exchange 2000 Extensions") - :etm_enabled (false) - :member_class (service) - :members_query () - :type (group) - ) - : (securid - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB467-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (service_group) - :table (services) - :name (securid) - ) - : (ReferenceObject - :Name (securid-udp) - :Table (services) - :Uid ("{97AEB3EC-9AEA-11D5-BD16-0090272CCB30}") - ) - : (ReferenceObject - :Name (securidprop) - :Table (services) - :Uid ("{97AEB3ED-9AEA-11D5-BD16-0090272CCB30}") - ) - :color (FireBrick) - :comments ("Secure ID group") - :etm_enabled (false) - :member_class (service) - :members_query () - :type (group) - ) - : (Authenticated - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB468-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (service_group) - :table (services) - :name (Authenticated) - ) - : (ReferenceObject - :Name (telnet) - :Table (services) - :Uid ("{97AEB3CF-9AEA-11D5-BD16-0090272CCB30}") - ) - : (ReferenceObject - :Name (ftp) - :Table (services) - :Uid ("{97AEB3D0-9AEA-11D5-BD16-0090272CCB30}") - ) - : (ReferenceObject - :Name (http) - :Table (services) - :Uid ("{97AEB3D4-9AEA-11D5-BD16-0090272CCB30}") - ) - : (ReferenceObject - :Name (login) - :Table (services) - :Uid ("{97AEB3BE-9AEA-11D5-BD16-0090272CCB30}") - ) - :color ("Forest Green") - :comments ("Authenticated group") - :etm_enabled (false) - :member_class (service) - :members_query () - :type (group) - ) - : (mosaic - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB469-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (service_group) - :table (services) - :name (mosaic) - ) - : (ReferenceObject - :Name (http) - :Table (services) - :Uid ("{97AEB3D4-9AEA-11D5-BD16-0090272CCB30}") - ) - : (ReferenceObject - :Name (gopher) - :Table (services) - :Uid ("{97AEB3D5-9AEA-11D5-BD16-0090272CCB30}") - ) - : (ReferenceObject - :Name (ftp) - :Table (services) - :Uid ("{97AEB3D0-9AEA-11D5-BD16-0090272CCB30}") - ) - : (ReferenceObject - :Name (archie) - :Table (services) - :Uid ("{97AEB3D6-9AEA-11D5-BD16-0090272CCB30}") - ) - :color ("Forest Green") - :comments ("Mosaic group") - :etm_enabled (false) - :member_class (service) - :members_query () - :type (group) - ) - : (echo - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB46A-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (service_group) - :table (services) - :name (echo) - ) - : (ReferenceObject - :Name (echo-tcp) - :Table (services) - :Uid ("{97AEB3F7-9AEA-11D5-BD16-0090272CCB30}") - ) - : (ReferenceObject - :Name (echo-udp) - :Table (services) - :Uid ("{97AEB3F8-9AEA-11D5-BD16-0090272CCB30}") - ) - :color (Black) - :comments ("Echo Protocol group (TCP/UDP)") - :etm_enabled (false) - :member_class (service) - :members_query () - :type (group) - ) - : (dns - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB46B-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (service_group) - :table (services) - :name (dns) - ) - : (ReferenceObject - :Name (domain-tcp) - :Table (services) - :Uid ("{97AEB3F9-9AEA-11D5-BD16-0090272CCB30}") - ) - : (ReferenceObject - :Name (domain-udp) - :Table (services) - :Uid ("{97AEB3FA-9AEA-11D5-BD16-0090272CCB30}") - ) - :color (Black) - :comments ("Domain Name System (TCP/UDP)") - :etm_enabled (false) - :member_class (service) - :members_query () - :type (group) - ) - : (kerberos - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB46C-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (service_group) - :table (services) - :name (kerberos) - ) - : (ReferenceObject - :Name (kerberos-tcp) - :Table (services) - :Uid ("{97AEB3FB-9AEA-11D5-BD16-0090272CCB30}") - ) - : (ReferenceObject - :Name (kerberos-udp) - :Table (services) - :Uid ("{97AEB3FC-9AEA-11D5-BD16-0090272CCB30}") - ) - :color (Black) - :comments ("Kerberos Protocol group (TCP/UDP)") - :etm_enabled (false) - :member_class (service) - :members_query () - :type (group) - ) - : (discard - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB46D-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (service_group) - :table (services) - :name (discard) - ) - : (ReferenceObject - :Name (discard-tcp) - :Table (services) - :Uid ("{97AEB3FD-9AEA-11D5-BD16-0090272CCB30}") - ) - : (ReferenceObject - :Name (discard-udp) - :Table (services) - :Uid ("{97AEB3FE-9AEA-11D5-BD16-0090272CCB30}") - ) - :color (Black) - :comments ("Discard Protocol group (TCP/UDP)") - :etm_enabled (false) - :member_class (service) - :members_query () - :type (group) - ) - : (time - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB46E-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (service_group) - :table (services) - :name (time) - ) - : (ReferenceObject - :Name (time-tcp) - :Table (services) - :Uid ("{97AEB3FF-9AEA-11D5-BD16-0090272CCB30}") - ) - : (ReferenceObject - :Name (time-udp) - :Table (services) - :Uid ("{97AEB400-9AEA-11D5-BD16-0090272CCB30}") - ) - :color (Black) - :comments ("Time Server Protocol") - :etm_enabled (false) - :member_class (service) - :members_query () - :type (group) - ) - : (daytime - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB46F-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (service_group) - :table (services) - :name (daytime) - ) - : (ReferenceObject - :Name (daytime-tcp) - :Table (services) - :Uid ("{97AEB401-9AEA-11D5-BD16-0090272CCB30}") - ) - : (ReferenceObject - :Name (daytime-udp) - :Table (services) - :Uid ("{97AEB402-9AEA-11D5-BD16-0090272CCB30}") - ) - :color (Black) - :comments ("Daytime Protocol group (TCP/UDP)") - :etm_enabled (false) - :member_class (service) - :members_query () - :type (group) - ) - : (ntp - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB470-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (service_group) - :table (services) - :name (ntp) - ) - : (ReferenceObject - :Name (ntp-tcp) - :Table (services) - :Uid ("{97AEB403-9AEA-11D5-BD16-0090272CCB30}") - ) - : (ReferenceObject - :Name (ntp-udp) - :Table (services) - :Uid ("{97AEB404-9AEA-11D5-BD16-0090272CCB30}") - ) - :color (Black) - :comments ("Network Time Protocol group (TCP/UDP)") - :etm_enabled (false) - :member_class (service) - :members_query () - :type (group) - ) - : (NBT - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB471-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (service_group) - :table (services) - :name (NBT) - ) - : (ReferenceObject - :Name (nbname) - :Table (services) - :Uid ("{97AEB414-9AEA-11D5-BD16-0090272CCB30}") - ) - : (ReferenceObject - :Name (nbdatagram) - :Table (services) - :Uid ("{97AEB415-9AEA-11D5-BD16-0090272CCB30}") - ) - : (ReferenceObject - :Name (nbsession) - :Table (services) - :Uid ("{97AEB416-9AEA-11D5-BD16-0090272CCB30}") - ) - :color (Magenta) - :comments ("NetBios Services") - :etm_enabled (false) - :member_class (service) - :members_query () - :type (Group) - ) - : (NIS - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB472-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (service_group) - :table (services) - :name (NIS) - ) - : (ReferenceObject - :Name (ypbind) - :Table (services) - :Uid ("{97AEB3C2-9AEA-11D5-BD16-0090272CCB30}") - ) - : (ReferenceObject - :Name (yppasswd) - :Table (services) - :Uid ("{97AEB3C3-9AEA-11D5-BD16-0090272CCB30}") - ) - : (ReferenceObject - :Name (ypserv) - :Table (services) - :Uid ("{97AEB3C1-9AEA-11D5-BD16-0090272CCB30}") - ) - : (ReferenceObject - :Name (ypupdated) - :Table (services) - :Uid ("{97AEB3C4-9AEA-11D5-BD16-0090272CCB30}") - ) - : (ReferenceObject - :Name (ypxfrd) - :Table (services) - :Uid ("{97AEB3C5-9AEA-11D5-BD16-0090272CCB30}") - ) - :color ("Navy Blue") - :comments ("Network Information Services (YP)") - :etm_enabled (false) - :member_class (service) - :members_query () - :type (Group) - ) - : (NFS - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB473-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (service_group) - :table (services) - :name (NFS) - ) - : (ReferenceObject - :Name (mountd) - :Table (services) - :Uid ("{97AEB3BA-9AEA-11D5-BD16-0090272CCB30}") - ) - : (ReferenceObject - :Name (nfsd) - :Table (services) - :Uid ("{97AEB3B8-9AEA-11D5-BD16-0090272CCB30}") - ) - : (ReferenceObject - :Name (nfsd-tcp) - :Table (services) - :Uid ("{97AEB3B9-9AEA-11D5-BD16-0090272CCB30}") - ) - : (ReferenceObject - :Name (nfsprog) - :Table (services) - :Uid ("{97AEB3B7-9AEA-11D5-BD16-0090272CCB30}") - ) - : (ReferenceObject - :Name (nlockmgr) - :Table (services) - :Uid ("{97AEB3BC-9AEA-11D5-BD16-0090272CCB30}") - ) - : (ReferenceObject - :Name (pcnfsd) - :Table (services) - :Uid ("{97AEB3BB-9AEA-11D5-BD16-0090272CCB30}") - ) - :color (Red) - :comments ("Network File System Services") - :etm_enabled (false) - :member_class (service) - :members_query () - :type (Group) - ) - : (irc - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB474-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (service_group) - :table (services) - :name (irc) - ) - : (ReferenceObject - :Name (irc1) - :Table (services) - :Uid ("{97AEB417-9AEA-11D5-BD16-0090272CCB30}") - ) - : (ReferenceObject - :Name (irc2) - :Table (services) - :Uid ("{97AEB418-9AEA-11D5-BD16-0090272CCB30}") - ) - :color (Black) - :comments ("Internet Relay Chat Protocol") - :etm_enabled (false) - :member_class (service) - :members_query () - :type (Group) - ) - : (IPSEC - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB475-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (service_group) - :table (services) - :name (IPSEC) - ) - : (ReferenceObject - :Name (AH) - :Table (services) - :Uid ("{97AEB422-9AEA-11D5-BD16-0090272CCB30}") - ) - : (ReferenceObject - :Name (ESP) - :Table (services) - :Uid ("{97AEB423-9AEA-11D5-BD16-0090272CCB30}") - ) - : (ReferenceObject - :Name (SKIP) - :Table (services) - :Uid ("{97AEB421-9AEA-11D5-BD16-0090272CCB30}") - ) - : (ReferenceObject - :Name (IKE) - :Table (services) - :Uid ("{97AEB3B0-9AEA-11D5-BD16-0090272CCB30}") - ) - :color (Cyan) - :comments ("IPSEC Services") - :etm_enabled (false) - :member_class (service) - :members_query () - :type (group) - ) - : (Entrust-CA - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB476-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (service_group) - :table (services) - :name (Entrust-CA) - ) - : (ReferenceObject - :Name (Entrust-Admin) - :Table (services) - :Uid ("{97AEB435-9AEA-11D5-BD16-0090272CCB30}") - ) - : (ReferenceObject - :Name (Entrust-KeyMgmt) - :Table (services) - :Uid ("{97AEB436-9AEA-11D5-BD16-0090272CCB30}") - ) - :color (FireBrick) - :comments ("Entrust CA Services") - :etm_enabled (false) - :member_class (service) - :members_query () - :type (Group) - ) - : (RainWall-Control - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By (CheckPoint) - :From (CheckPoint) - ) - :chkpf_uid ("{04ECA4D1-E4B7-4EC3-A86F-9BB56765519E}") - :ClassName (service_group) - :table (services) - :name (RainWall-Control) - ) - : (ReferenceObject - :Name (RainWall_Command) - :Table (services) - :Uid ("{B9BBEEBA-B639-41A3-97D5-1F9D982D7E44}") - ) - : (ReferenceObject - :Name (RainWall_Daemon) - :Table (services) - :Uid ("{21CC3F85-E6DF-443D-9846-BD39BD015B85}") - ) - : (ReferenceObject - :Name (RainWall_Status) - :Table (services) - :Uid ("{4FBD29C5-06DB-4912-B23D-1BD50D693185}") - ) - :color (black) - :comments ("RainWall higu availability") - :etm_enabled (false) - :member_class (service) - :members_query () - :type (group) - ) - : (ICMPgute - :AdminInfo ( - :chkpf_uid ("{418C7C0A-956A-41FF-9BC1-5867B2265090}") - :ClassName (service_group) - :table (services) - :Wiznum (-1) - :LastModified ( - :Time ("Tue Mar 4 15:28:05 2003") - :By (tim) - :From (STICHLING) - ) - ) - : (ReferenceObject - :Name (dest-unreach) - :Table (services) - :Uid ("{97AEB407-9AEA-11D5-BD16-0090272CCB30}") - ) - : (ReferenceObject - :Name (echo-reply) - :Table (services) - :Uid ("{97AEB406-9AEA-11D5-BD16-0090272CCB30}") - ) - : (ReferenceObject - :Name (echo-request) - :Table (services) - :Uid ("{97AEB40A-9AEA-11D5-BD16-0090272CCB30}") - ) - : (ReferenceObject - :Name (time-exceeded) - :Table (services) - :Uid ("{97AEB40B-9AEA-11D5-BD16-0090272CCB30}") - ) - :color (black) - :comments () - :etm_enabled (false) - :member_class (service) - :members_query () - :type (group) - ) - : (gtp_v0_default - :AdminInfo ( - :chkpf_uid ("{D9531700-F8BB-4E3B-983D-10D69906A028}") - :ClassName (gtp_service) - :object_permissions ( - :AdminInfo ( - :chkpf_uid ("{B0160177-1F41-4B9F-803B-B58D93988C24}") - :ClassName (object_permissions) - ) - :manage ( - : (ReferenceObject - :Table (globals) - :Name (Any) - ) - ) - :read ( - : (any) - ) - :use ( - : (any) - ) - :write ( - : () - ) - :owner () - ) - :table (services) - :Deleteable (false) - :Wiznum (-1) - :LastModified ( - :Time ("Wed Aug 14 12:20:51 2002") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :apn_obj () - :reload_proof (false) - :weight (100) - :apn_any (true) - :color ("forest green") - :comments ("GPRS Tunneling Protocol version 0") - :data_packet (true) - :etm_enabled (false) - :imsi () - :imsi_any (true) - :include_in_any (false) - :ms_isdn (1) - :ms_isdn_any (true) - :port (3386) - :proto_type () - :sel_mode (0) - :sel_mode_any (false) - :signaling_packet (true) - :static_eua (false) - :timeout (600) - :type (gtp) - ) - : (gtp_v1_default - :AdminInfo ( - :chkpf_uid ("{AFF26F18-B9B0-4E7C-BC4D-D6749E0487B2}") - :ClassName (gtp_v1_service) - :table (services) - :Deleteable (false) - :Wiznum (-1) - :object_permissions ( - :AdminInfo ( - :chkpf_uid ("{E61F7C69-C165-4A73-ACCC-E2A7A6F69500}") - :ClassName (object_permissions) - ) - :manage ( - : (ReferenceObject - :Table (globals) - :Name (Any) - ) - ) - :read ( - : (any) - ) - :use ( - : (any) - ) - :write ( - : () - ) - :owner () - ) - :LastModified ( - :Time ("Wed Aug 14 12:44:28 2002") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :apn_obj () - :reload_proof (false) - :weight (100) - :apn_any (true) - :color ("forest green") - :comments ("GPRS Tunneling Protocol version 1") - :control_port (2123) - :data_packet (true) - :etm_enabled (false) - :imsi () - :imsi_any (true) - :include_in_any (false) - :ms_isdn (1) - :ms_isdn_any (true) - :proto_type () - :sel_mode (0) - :sel_mode_any (false) - :signaling_packet (true) - :static_eua (false) - :timeout (600) - :type (gtp_v1) - :user_port (2152) - ) - : (gtp_v0_path_mgmt - :AdminInfo ( - :chkpf_uid ("{35029B62-16B1-4D34-8004-410710DFD492}") - :ClassName (other_service) - :table (services) - :Wiznum (-1) - :object_permissions ( - :AdminInfo ( - :chkpf_uid ("{6B50E6B6-7FA8-42DB-AEB6-45C57EB6DA39}") - :ClassName (object_permissions) - ) - :manage ( - : (ReferenceObject - :Table (globals) - :Name (Any) - ) - ) - :read ( - : (any) - ) - :use ( - : (any) - ) - :write ( - : () - ) - :owner () - ) - :LastModified ( - :Time ("Wed Aug 14 16:33:40 2002") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :reload_proof (false) - :color ("forest green") - :comments ("GTP version 0 path management") - :etm_enabled (false) - :exp (gtp_path_match_v0) - :include_in_any (true) - :needruleinfo (false) - :proto_type () - :protocol (17) - :replies (true) - :sync_on_cluster (true) - :timeout (0) - :type (Other) - :weight (0) - ) - : (gtp_v1_path_mgmt - :AdminInfo ( - :chkpf_uid ("{6106FFDD-A8FE-4B2E-8270-CB3435217427}") - :ClassName (other_service) - :object_permissions ( - :AdminInfo ( - :chkpf_uid ("{DA40F0A4-D596-4339-B84D-1AF50B0BDD13}") - :ClassName (object_permissions) - ) - :manage ( - : (ReferenceObject - :Table (globals) - :Name (Any) - ) - ) - :read ( - : (any) - ) - :use ( - : (any) - ) - :write ( - : () - ) - :owner () - ) - :table (services) - :Wiznum (-1) - :LastModified ( - :Time ("Wed Aug 14 16:19:19 2002") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :reload_proof (false) - :color ("forest green") - :comments ("GTP version 1 path management") - :etm_enabled (false) - :exp (gtp_path_match_v1) - :include_in_any (true) - :needruleinfo (false) - :proto_type () - :protocol (17) - :replies (true) - :sync_on_cluster (true) - :timeout (0) - :type (Other) - :weight (0) - ) - : (https - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB443-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (tcp_service) - :table (services) - :name (https) - :Deleteable (false) - :Renameable (false) - ) - :delayed_sync_value (30) - :use_delayed_sync (false) - :color (Red) - :comments ("HTTP protocol over TLS/SSL") - :enable_tcp_resource (false) - :etm_enabled (false) - :include_in_any (true) - :port (443) - :proto_type (ReferenceObject - :Table (protocols) - :Name (ENC-HTTP) - :Uid ("{8294399D-9333-4774-B3DA-C00EACEF3211}") - ) - :reload_proof (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (tcp) - ) - : (TCP_135 - :AdminInfo ( - :chkpf_uid ("{C748295C-99D9-474C-8136-7959A5A98E30}") - :ClassName (tcp_service) - :table (services) - :Wiznum (-1) - :object_permissions ( - :AdminInfo ( - :chkpf_uid ("{9E3FE282-81AB-4032-B803-8CDAB5917CC0}") - :ClassName (object_permissions) - ) - :manage ( - : (ReferenceObject - :Table (globals) - :Name (Any) - ) - ) - :read ( - : (any) - ) - :use ( - : (any) - ) - :write ( - : () - ) - :owner () - ) - :LastModified ( - :Time ("Sun Feb 16 16:51:51 2003") - :By (IsoAAAF) - :From (scratchy) - ) - :name (TCP_135) - ) - :delayed_sync_value (30) - :use_delayed_sync (false) - :color (magenta) - :comments () - :enable_tcp_resource (false) - :etm_enabled (false) - :include_in_any (true) - :port (135) - :proto_type () - :reload_proof (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (Tcp) - ) - : (ldap-udp - :AdminInfo ( - :chkpf_uid ("{DE59BD94-9610-4C6C-B667-97B79EB2EBAA}") - :ClassName (udp_service) - :table (services) - :Wiznum (-1) - :object_permissions ( - :AdminInfo ( - :chkpf_uid ("{8C4728BD-72A1-44FF-9328-D17430D20776}") - :ClassName (object_permissions) - ) - :manage ( - : (ReferenceObject - :Table (globals) - :Name (Any) - ) - ) - :read ( - : (any) - ) - :use ( - : (any) - ) - :write ( - : () - ) - :owner () - ) - :LastModified ( - :Time ("Sun Feb 16 16:54:14 2003") - :By (IsoAAAF) - :From (scratchy) - ) - :name (ldap-udp) - ) - :delete_on_reply (false) - :color (black) - :comments () - :etm_enabled (false) - :include_in_any (true) - :port (389) - :proto_type () - :reload_proof (false) - :replies (true) - :replies_from_any_port (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (Udp) - ) - : (P2P_File_Sharing_Applications - :AdminInfo ( - :chkpf_uid ("{D138E7DA-3BF1-4D7C-AE35-D551416E8DB3}") - :ClassName (service_group) - :table (services) - :Wiznum (-1) - :LastModified ( - :Time ("Thu Dec 12 14:44:07 2002") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - : (ReferenceObject - :Name (Blubster) - :Table (services) - :Uid ("{C86F055D-31AD-4430-B12C-1094A86C673C}") - ) - : (ReferenceObject - :Name (Direct_Connect) - :Table (services) - :Uid ("{5CFC76C2-B743-4B68-9FBF-E901EAA3698D}") - ) - : (ReferenceObject - :Name (eDonkey) - :Table (services) - :Uid ("{42929FB0-C8DD-465E-BE01-3E484F4299F6}") - ) - : (ReferenceObject - :Name (GNUtella) - :Table (services) - :Uid ("{F0059B62-E18E-478F-A3BD-18595D53D3E1}") - ) - : (ReferenceObject - :Name (GoToMyPC) - :Table (services) - :Uid ("{2D89310C-5761-4213-BEF5-C81BB5677E44}") - ) - : (ReferenceObject - :Name (Hotline) - :Table (services) - :Uid ("{4C3E148F-BCC4-4C97-9955-09DA850FB9A6}") - ) - : (ReferenceObject - :Name (iMesh) - :Table (services) - :Uid ("{01E9FC32-73DF-43D5-9CD4-4F91B6A5C711}") - ) - : (ReferenceObject - :Table (services) - :Name (Kazaa) - :Uid ("{BE146201-61B2-11d6-B5E0-0002B316D24E}") - ) - : (ReferenceObject - :Name (Madster) - :Table (services) - :Uid ("{B863EC35-604F-4DA1-8E63-82A7903D2C1C}") - ) - : (ReferenceObject - :Name (Napster) - :Table (services) - :Uid ("{5EE3CA5B-35A2-4988-859C-7157E8CFFEAD}") - ) - : (ReferenceObject - :Name (WinMX) - :Table (services) - :Uid ("{6414F98E-6883-44DB-8EE2-DEBD443C7714}") - ) - :color (black) - :comments () - :etm_enabled (false) - :member_class (service) - :members_query () - :type (group) - ) - : (NEW-RADIUS - :AdminInfo ( - :chkpf_uid ("{97AEB41E-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (udp_service) - :table (services) - :Wiznum (-1) - :LastModified ( - :Time ("Thu May 6 14:03:23 2004") - :By (andre) - :From (gateway) - ) - ) - :color (firebrick) - :comments ("NEW - Remote Authentication Dial-In User Service") - :delete_on_reply (false) - :etm_enabled (false) - :include_in_any (true) - :port (1812) - :proto_type () - :reload_proof (false) - :replies (true) - :replies_from_any_port (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (Udp) - ) - : (premier_access_5010 - :AdminInfo ( - :chkpf_uid ("{A1489778-CD8C-41F2-BCC1-0C60B89C822F}") - :ClassName (tcp_service) - :table (services) - :Wiznum (-1) - :LastModified ( - :Time ("Thu May 6 14:47:35 2004") - :By (andre) - :From (gateway) - ) - ) - :etm_enabled (false) - :proto_type () - :timeout (0) - :color (black) - :comments () - :delayed_sync_value (30) - :enable_tcp_resource (false) - :include_in_any (true) - :port (5010) - :reload_proof (false) - :src_port () - :sync_on_cluster (true) - :type (Tcp) - :use_delayed_sync (false) - ) - : (premier_access_5029 - :AdminInfo ( - :chkpf_uid ("{CCF60486-D5C2-4D26-B4D6-8CFBF7BC63A5}") - :ClassName (tcp_service) - :table (services) - :Wiznum (-1) - :LastModified ( - :Time ("Thu May 6 14:50:36 2004") - :By (andre) - :From (gateway) - ) - ) - :etm_enabled (false) - :proto_type () - :sync_on_cluster (true) - :timeout (0) - :use_delayed_sync (false) - :color (blue1) - :comments () - :delayed_sync_value (30) - :enable_tcp_resource (false) - :include_in_any (true) - :port (5029) - :reload_proof (false) - :src_port () - :type (Tcp) - ) - : (premier_access_5031 - :AdminInfo ( - :chkpf_uid ("{6668A65E-65C1-4BE1-BBA7-9F18D8DE169C}") - :ClassName (tcp_service) - :table (services) - :Wiznum (-1) - :LastModified ( - :Time ("Thu May 6 14:51:15 2004") - :By (andre) - :From (gateway) - ) - ) - :etm_enabled (false) - :proto_type () - :sync_on_cluster (true) - :timeout (0) - :use_delayed_sync (false) - :color (blue1) - :comments () - :delayed_sync_value (30) - :enable_tcp_resource (false) - :include_in_any (true) - :port (5031) - :reload_proof (false) - :src_port () - :type (Tcp) - ) - : (http - :AdminInfo ( - :chkpf_uid ("{97AEB3D4-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (tcp_service) - :table (services) - :Wiznum (-1) - :LastModified ( - :Time ("Tue Jun 8 12:58:02 2004") - :By (tim) - :From (pieks) - ) - ) - :color ("forest green") - :comments ("Hypertext Transfer Protocol") - :delayed_sync_value (30) - :enable_tcp_resource (false) - :etm_enabled (false) - :include_in_any (true) - :port (80) - :proto_type (ReferenceObject - :Name (HTTP) - :Table (protocols) - :Uid ("{97AEB373-9AEA-11D5-BD16-0090272CCB30}") - ) - :reload_proof (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (Tcp) - :use_delayed_sync (false) - ) - : (mysql - :AdminInfo ( - :chkpf_uid ("{08A07607-EAAA-4A45-AD6E-6020770BD519}") - :ClassName (tcp_service) - :table (services) - :Wiznum (-1) - :LastModified ( - :Time ("Sun Aug 1 12:49:09 2004") - :By (tim) - :From (pieks) - ) - ) - :etm_enabled (false) - :proto_type () - :sync_on_cluster (true) - :timeout (0) - :use_delayed_sync (false) - :color (black) - :comments ("3306/tcp") - :delayed_sync_value (30) - :enable_tcp_resource (false) - :include_in_any (true) - :port (3306) - :reload_proof (false) - :src_port () - :type (Tcp) - ) - : (PremierAccess_udp - :AdminInfo ( - :chkpf_uid ("{0AE4AA4A-30BB-41D3-9113-3C0A41901F0E}") - :ClassName (udp_service) - :table (services) - :Wiznum (-1) - :LastModified ( - :Time ("Thu Aug 5 14:15:43 2004") - :By (andre) - :From (gateway) - ) - ) - :delete_on_reply (false) - :etm_enabled (false) - :proto_type () - :timeout (0) - :color (blue) - :comments () - :include_in_any (true) - :port (5030) - :reload_proof (false) - :replies (true) - :replies_from_any_port (true) - :src_port () - :sync_on_cluster (true) - :type (Udp) - ) - : (rdp - :AdminInfo ( - :chkpf_uid ("{5BA0C83F-8D91-465B-9CF6-7DC6AEB84689}") - :ClassName (tcp_service) - :table (services) - :Wiznum (-1) - :LastModified ( - :Time ("Wed Sep 29 20:43:11 2004") - :By (IsoAAAF) - :From (IsoAAADray) - ) - ) - :color (cyan) - :comments (rdp_new) - :delayed_sync_value (30) - :enable_tcp_resource (false) - :etm_enabled (false) - :include_in_any (true) - :port (3389) - :proto_type () - :reload_proof (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (Tcp) - :use_delayed_sync (false) - ) - : (PPTP - :AdminInfo ( - :chkpf_uid ("{97AEB426-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (service_group) - :table (services) - :Wiznum (-1) - :LastModified ( - :Time ("Thu Sep 30 07:20:55 2004") - :By (IsoAAAF) - :From (scratchy) - ) - ) - : (ReferenceObject - :Name (gre) - :Table (services) - :Uid ("{97AEB424-9AEA-11D5-BD16-0090272CCB30}") - ) - : (ReferenceObject - :Name (pptp-tcp) - :Table (services) - :Uid ("{97AEB425-9AEA-11D5-BD16-0090272CCB30}") - ) - :color (red) - :comments ("Point-to-Point Tunneling group, (pptp & gre)") - :etm_enabled (false) - :member_class (service) - :members_query () - :type (group) - ) - : (Drop_nologServices - :AdminInfo ( - :chkpf_uid ("{495E1A16-2612-49D9-8F69-B00EB33699E8}") - :ClassName (service_group) - :object_permissions ( - :AdminInfo ( - :chkpf_uid ("{61465BAC-5B02-4B46-9186-82DDFB8A898F}") - :ClassName (object_permissions) - ) - :manage ( - : (ReferenceObject - :Table (globals) - :Name (Any) - ) - ) - :read ( - : (any) - ) - :use ( - : (any) - ) - :write ( - : () - ) - :owner () - ) - :table (services) - :Wiznum (-1) - :LastModified ( - :Time ("Thu Sep 30 07:28:52 2004") - :By (IsoAAAF) - :From (scratchy) - ) - ) - : (ReferenceObject - :Name (dhcp-rep-localmodule) - :Table (services) - :Uid ("{FCA646B5-EF34-4DF1-895D-7639E181501A}") - ) - : (ReferenceObject - :Name (dhcp-req-localmodule) - :Table (services) - :Uid ("{22725520-8E10-4A91-98AC-DCD1F6C4A4DD}") - ) - : (ReferenceObject - :Name (ldap-udp) - :Table (services) - :Uid ("{DE59BD94-9610-4C6C-B667-97B79EB2EBAA}") - ) - : (ReferenceObject - :Name (nbdatagram) - :Table (services) - :Uid ("{97AEB415-9AEA-11D5-BD16-0090272CCB30}") - ) - : (ReferenceObject - :Name (nbname) - :Table (services) - :Uid ("{97AEB414-9AEA-11D5-BD16-0090272CCB30}") - ) - :color (black) - :comments () - :etm_enabled (false) - :member_class (service) - :members_query () - :type (group) - ) - : (HBCI - :AdminInfo ( - :chkpf_uid ("{336C93F8-5CC2-48BE-9328-2E92F61EFCF1}") - :ClassName (tcp_service) - :table (services) - :Wiznum (-1) - :LastModified ( - :Time ("Thu Sep 30 09:43:31 2004") - :By (IsoAAAF) - :From (scratchy) - ) - ) - :etm_enabled (false) - :proto_type () - :sync_on_cluster (true) - :timeout (0) - :use_delayed_sync (false) - :color (black) - :comments () - :delayed_sync_value (30) - :enable_tcp_resource (false) - :include_in_any (true) - :port (3000) - :reload_proof (false) - :src_port () - :type (Tcp) - ) - : (sshv2-24 - :AdminInfo ( - :chkpf_uid ("{1DA78BCE-7ABC-4DBB-82AF-FDBE6B853493}") - :ClassName (tcp_service) - :table (services) - :Wiznum (-1) - :LastModified ( - :Time ("Mon Oct 4 19:52:06 2004") - :By (IsoAAAF) - :From (IsoAAADray) - ) - ) - :etm_enabled (false) - :timeout (0) - :use_delayed_sync (false) - :color (black) - :comments ("ssh on port24") - :delayed_sync_value (30) - :enable_tcp_resource (false) - :include_in_any (true) - :port (24) - :proto_type (ReferenceObject - :Name (SSH2) - :Table (protocols) - :Uid ("{55F4C5D7-60D9-44B3-9BD4-C3F76B7C8360}") - ) - :reload_proof (false) - :src_port () - :sync_on_cluster (true) - :type (Tcp) - ) - : (irc2 - :AdminInfo ( - :chkpf_uid ("{97AEB418-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (tcp_service) - :table (services) - :Wiznum (-1) - :LastModified ( - :Time ("Thu Oct 7 13:39:51 2004") - :By (andre) - :From (Roadrunner) - ) - ) - :proto_type () - :timeout (0) - :color (black) - :comments ("Internet Relay Chat Protocol") - :delayed_sync_value (30) - :enable_tcp_resource (false) - :etm_enabled (false) - :include_in_any (false) - :port (7000) - :reload_proof (false) - :src_port () - :sync_on_cluster (true) - :type (Tcp) - :use_delayed_sync (false) - ) - : (UPS-Monitor - :AdminInfo ( - :chkpf_uid ("{8C8DED7E-F3C9-4964-B9D3-063C23997020}") - :ClassName (tcp_service) - :table (services) - :Wiznum (-1) - :LastModified ( - :Time ("Thu Oct 7 13:40:06 2004") - :By (andre) - :From (Roadrunner) - ) - ) - :proto_type () - :timeout (0) - :color (black) - :comments () - :delayed_sync_value (30) - :enable_tcp_resource (false) - :etm_enabled (false) - :include_in_any (false) - :port (7000) - :reload_proof (false) - :src_port () - :sync_on_cluster (true) - :type (Tcp) - :use_delayed_sync (false) - ) - : (VNC-neu - :AdminInfo ( - :chkpf_uid ("{00000006-735E-4158-A169-8701B9624E47}") - :ClassName (tcp_service) - :table (services) - :Wiznum (-1) - :LastModified ( - :Time ("Sat Nov 6 14:40:14 2004") - :By (IsoAAAF) - :From (IsoAAADray) - ) - ) - :etm_enabled (false) - :proto_type () - :sync_on_cluster (true) - :timeout (0) - :use_delayed_sync (false) - :color (gold) - :comments ("standard VNC") - :delayed_sync_value (30) - :enable_tcp_resource (false) - :include_in_any (true) - :port (55901) - :reload_proof (false) - :src_port () - :type (Tcp) - ) - : (VNC - :AdminInfo ( - :chkpf_uid ("{9788B566-735E-4158-A169-8701B9624E47}") - :ClassName (tcp_service) - :table (services) - :Wiznum (-1) - :LastModified ( - :Time ("Sat Nov 6 14:40:14 2004") - :By (IsoAAAF) - :From (IsoAAADray) - ) - ) - :etm_enabled (false) - :proto_type () - :sync_on_cluster (true) - :timeout (0) - :use_delayed_sync (false) - :color (gold) - :comments ("standard VNC") - :delayed_sync_value (30) - :enable_tcp_resource (false) - :include_in_any (true) - :port (5900) - :reload_proof (false) - :src_port () - :type (Tcp) - ) - : (RAdmin - :AdminInfo ( - :chkpf_uid ("{8888DA95-4E43-4F96-95FF-F5B41410BDBD}") - :ClassName (tcp_service) - :table (services) - :Wiznum (-1) - :LastModified ( - :Time ("Sun Nov 7 14:43:43 2004") - :By (IsoAAAF) - :From (IsoAAADray) - ) - ) - :etm_enabled (false) - :proto_type () - :sync_on_cluster (true) - :timeout (0) - :use_delayed_sync (false) - :color (black) - :comments (default) - :delayed_sync_value (30) - :enable_tcp_resource (false) - :include_in_any (true) - :port (44899) - :reload_proof (false) - :src_port () - :type (Tcp) - ) - : (RADIUS - :AdminInfo ( - :chkpf_uid ("{97AEB41D-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (udp_service) - :table (services) - :Wiznum (-1) - :LastModified ( - :Time ("Tue Jan 4 22:09:25 2005") - :By (IsoAAAF) - :From (IsoAAADray) - ) - ) - :color (firebrick) - :comments ("Remote Authentication Dial-In User Service") - :delete_on_reply (false) - :etm_enabled (false) - :include_in_any (true) - :port (1645) - :proto_type () - :reload_proof (false) - :replies (true) - :replies_from_any_port (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (Udp) - ) - : (SpikeServices - :AdminInfo ( - :chkpf_uid ("{9D35FACE-289F-49A6-95C7-13417959BC9D}") - :ClassName (service_group) - :table (services) - :Wiznum (-1) - :LastModified ( - :Time ("Thu Jan 6 16:41:59 2005") - :By (IsoAAAF) - :From (IsoAAADray) - ) - ) - : (ReferenceObject - :Name (apcupsd) - :Table (services) - :Uid ("{A1044CB4-439C-40C9-8489-FA5086134886}") - ) - : (ReferenceObject - :Name (CIFS) - :Table (services) - :Uid ("{2A469820-B502-434C-9340-A377677A6A60}") - ) - : (ReferenceObject - :Name (domain-udp) - :Table (services) - :Uid ("{97AEB3FA-9AEA-11D5-BD16-0090272CCB30}") - ) - : (ReferenceObject - :Name (echo-request) - :Table (services) - :Uid ("{97AEB40A-9AEA-11D5-BD16-0090272CCB30}") - ) - : (ReferenceObject - :Name (imap) - :Table (services) - :Uid ("{97AEB446-9AEA-11D5-BD16-0090272CCB30}") - ) - : (ReferenceObject - :Name (smtp) - :Table (services) - :Uid ("{97AEB3D9-9AEA-11D5-BD16-0090272CCB30}") - ) - : (ReferenceObject - :Name (squid) - :Table (services) - :Uid ("{91C0454D-F70C-44B3-8F2D-70C4A68E9594}") - ) - : (ReferenceObject - :Name (sshv2-24) - :Table (services) - :Uid ("{1DA78BCE-7ABC-4DBB-82AF-FDBE6B853493}") - ) - : (ReferenceObject - :Name (syslog) - :Table (services) - :Uid ("{97AEB3E0-9AEA-11D5-BD16-0090272CCB30}") - ) - :color (black) - :comments () - :etm_enabled (false) - :member_class (service) - :members_query () - :type (group) - : (ReferenceObject - :Table (services) - :Name (imaps) - :Uid ("{B760A869-04DF-43E2-91F9-414C58F86F16}") - ) - ) - : (imaps - :AdminInfo ( - :chkpf_uid ("{B760A869-04DF-43E2-91F9-414C58F86F16}") - :ClassName (tcp_service) - :table (services) - :Wiznum (-1) - :LastModified ( - :Time ("Thu Jan 6 16:41:59 2005") - :By (IsoAAAF) - :From (IsoAAADray) - ) - ) - :etm_enabled (false) - :proto_type () - :sync_on_cluster (true) - :timeout (0) - :use_delayed_sync (false) - :color (black) - :comments () - :delayed_sync_value (30) - :enable_tcp_resource (false) - :include_in_any (true) - :port (993) - :reload_proof (false) - :src_port () - :type (Tcp) - ) - : (TeamSpeak - :AdminInfo ( - :chkpf_uid ("{D2BBEFB3-8450-4301-9040-2D305887A748}") - :ClassName (udp_service) - :table (services) - :Wiznum (-1) - :LastModified ( - :Time ("Tue Apr 12 08:48:10 2005") - :By (IsoAAAF) - :From (IsoAAADray) - ) - ) - :delete_on_reply (false) - :etm_enabled (false) - :proto_type () - :replies (true) - :replies_from_any_port (false) - :sync_on_cluster (true) - :timeout (0) - :color (blue) - :comments () - :include_in_any (true) - :port (8767) - :reload_proof (false) - :src_port () - :type (Udp) - ) - ) - :times (times - : (Midnight - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB47B-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (scheduled_event) - :table (times) - :name (Midnight) - ) - :day_of_month () - :day_of_week () - :month () - :color (black) - :comments () - :days_specification (daily) - :every_seconds (0) - :hour (23) - :minutes (59) - :type (scheduled_event) - ) - : (Fetch_Inter - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB47C-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (scheduled_event) - :table (times) - :Deleteable (false) - :Renameable (false) - :name (Fetch_Inter) - ) - :day_of_month () - :day_of_week () - :month () - :color (black) - :comments ("Check Point policy fetching interval for Dynamic IP Address Machines") - :days_specification (seconds) - :every_seconds (14400) - :hour (0) - :minutes (0) - :type (scheduled_event) - ) - ) - :products ( - : (AirWave_AMP_1.5 - :AdminInfo ( - :chkpf_uid ("{EC04E1E1-6B83-419E-9241-EA20DFE40A04}") - :ClassName (OPSEC_product) - :table (products) - :LastModified ( - :Time ("Sun Nov 17 14:47:47 2002") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :NT_commands () - :commands () - :solaris_commands () - :AMON (false) - :AMON_class_name (default_opsec_status_object) - :CPMI (false) - :CVP (false) - :ELA (false) - :LEA (false) - :OMI (false) - :RTM (false) - :SAM (false) - :UAC (true) - :UFP (false) - :color (black) - :comments () - :product_info ( - :AdminInfo ( - :chkpf_uid ("{514CB955-084F-47DF-9C4F-BDB3CFA8E3DE}") - :ClassName (OPSEC_product_info) - ) - :certification_info () - :certified (true) - :product (AMP) - :vendor (AirWave) - :version (1.5) - ) - :type (OPSEC_product) - ) - : (ArcSight_1.0 - :AdminInfo ( - :chkpf_uid ("{5ABDFE5C-4A62-4D67-BC7E-79E5F56EAFD5}") - :ClassName (OPSEC_product) - :table (products) - :LastModified ( - :Time ("Sun Nov 17 14:47:48 2002") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :NT_commands () - :commands () - :solaris_commands () - :AMON (false) - :AMON_class_name (default_opsec_status_object) - :CPMI (false) - :CVP (false) - :ELA (false) - :LEA (true) - :OMI (false) - :RTM (false) - :SAM (false) - :UAC (false) - :UFP (false) - :color (black) - :comments () - :product_info ( - :AdminInfo ( - :chkpf_uid ("{1E6C4B1C-8FCF-486E-8504-BA240244BB82}") - :ClassName (OPSEC_product_info) - ) - :certification_info () - :certified (true) - :product (ArcSight) - :vendor (ArcSight) - :version (1.0) - ) - :type (OPSEC_product) - ) - : (Avivasolutions_HostSheild_1.0 - :AdminInfo ( - :chkpf_uid ("{21582C3A-9696-47A1-B15D-E2A117393148}") - :ClassName (OPSEC_product) - :table (products) - :LastModified ( - :Time ("Sun Nov 17 14:47:48 2002") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :NT_commands () - :commands () - :solaris_commands () - :AMON (false) - :AMON_class_name (default_opsec_status_object) - :CPMI (false) - :CVP (true) - :ELA (true) - :LEA (false) - :OMI (false) - :RTM (false) - :SAM (true) - :UAC (false) - :UFP (false) - :color (black) - :comments () - :product_info ( - :AdminInfo ( - :chkpf_uid ("{56D49EC7-1614-44AC-86AE-5D3041519DFF}") - :ClassName (OPSEC_product_info) - ) - :certification_info () - :certified (true) - :product (HostShield) - :vendor ("Aviva Inc.") - :version (1.0) - ) - :type (OPSEC_product) - ) - : (Baltimore_MAILSweeper_3.8 - :AdminInfo ( - :chkpf_uid ("{CE8E3346-8544-4224-AD22-99E37F91ED7C}") - :ClassName (OPSEC_product) - :table (products) - :LastModified ( - :Time ("Sun Nov 17 14:47:48 2002") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :NT_commands () - :commands () - :solaris_commands () - :AMON (false) - :AMON_class_name (default_opsec_status_object) - :CPMI (false) - :CVP (false) - :ELA (true) - :LEA (false) - :OMI (false) - :RTM (false) - :SAM (false) - :UAC (false) - :UFP (false) - :color (black) - :comments () - :product_info ( - :AdminInfo ( - :chkpf_uid ("{BA2F9666-90C4-48C4-AD11-E85128BA70C2}") - :ClassName (OPSEC_product_info) - ) - :certification_info () - :certified (true) - :product (MAILSweeper_OPSECAlerter) - :vendor ("Baltimore Technologies") - :version (3.8) - ) - :type (OPSEC_product) - ) - : (Columbitech_Event_Log_1.0 - :AdminInfo ( - :chkpf_uid ("{F47602F3-A2DD-409C-A9EE-A7A66B4242BF}") - :ClassName (OPSEC_product) - :table (products) - :LastModified ( - :Time ("Sun Nov 17 14:47:49 2002") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :NT_commands () - :commands () - :solaris_commands () - :AMON (false) - :AMON_class_name (default_opsec_status_object) - :CPMI (false) - :CVP (false) - :ELA (true) - :LEA (false) - :OMI (false) - :RTM (false) - :SAM (false) - :UAC (false) - :UFP (false) - :color (black) - :comments () - :product_info ( - :AdminInfo ( - :chkpf_uid ("{9FAED062-CCDC-47B0-916F-48105A612B07}") - :ClassName (OPSEC_product_info) - ) - :certification_info () - :certified (true) - :product (Event_Log_Extension_Service) - :vendor (Columbitech) - :version (1.0) - ) - :type (OPSEC_product) - ) - : (e-Security_e-Wizard_3.1 - :AdminInfo ( - :chkpf_uid ("{266E0FAB-4BF3-4368-9B9F-9141B2C76CA4}") - :ClassName (OPSEC_product) - :table (products) - :LastModified ( - :Time ("Sun Nov 17 14:47:49 2002") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :NT_commands () - :commands () - :solaris_commands () - :AMON (false) - :AMON_class_name (default_opsec_status_object) - :CPMI (false) - :CVP (false) - :ELA (false) - :LEA (true) - :OMI (false) - :RTM (false) - :SAM (false) - :UAC (false) - :UFP (false) - :color (black) - :comments () - :product_info ( - :AdminInfo ( - :chkpf_uid ("{F4B28A64-FE25-476E-AD4E-D5793BE16893}") - :ClassName (OPSEC_product_info) - ) - :certification_info () - :certified (true) - :product (eWizard) - :vendor (e-Security) - :version (3.1) - ) - :type (OPSEC_product) - ) - : (ForeScout_ActiveScout_2.1 - :AdminInfo ( - :chkpf_uid ("{46EE3C54-A144-4D5E-BDE0-D8445ADA3BBB}") - :ClassName (OPSEC_product) - :table (products) - :LastModified ( - :Time ("Sun Nov 17 14:47:50 2002") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :NT_commands () - :commands () - :solaris_commands () - :AMON (false) - :AMON_class_name (default_opsec_status_object) - :CPMI (false) - :CVP (false) - :ELA (false) - :LEA (false) - :OMI (false) - :RTM (false) - :SAM (true) - :UAC (false) - :UFP (false) - :color (black) - :comments () - :product_info ( - :AdminInfo ( - :chkpf_uid ("{A7A45782-B3D3-4B10-AA8C-B26651F3858D}") - :ClassName (OPSEC_product_info) - ) - :certification_info () - :certified (true) - :product (ActiveScout) - :vendor (ForeScout) - :version (2.1) - ) - :type (OPSEC_product) - ) - : (FSecure_AV_FireWall_6.01 - :AdminInfo ( - :chkpf_uid ("{8C5BE8C6-C05A-4E9E-B66E-B9BEC089369B}") - :ClassName (OPSEC_product) - :table (products) - :LastModified ( - :Time ("Sun Nov 17 14:47:50 2002") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :NT_commands () - :commands () - :solaris_commands () - :AMON (false) - :AMON_class_name (default_opsec_status_object) - :CPMI (false) - :CVP (true) - :ELA (false) - :LEA (false) - :OMI (false) - :RTM (false) - :SAM (false) - :UAC (false) - :UFP (false) - :color (black) - :comments () - :product_info ( - :AdminInfo ( - :chkpf_uid ("{0CC4CDC9-5A4E-4709-8841-9B128FABA503}") - :ClassName (OPSEC_product_info) - ) - :certification_info () - :certified (true) - :product (Anti_Virus_For_FireWall) - :vendor (F-Secure) - :version (6.01) - ) - :type (OPSEC_product) - ) - : (iCognito_PureSight_3.6 - :AdminInfo ( - :chkpf_uid ("{3B743BA2-84C7-4D30-804A-00AD1FC9234D}") - :ClassName (OPSEC_product) - :table (products) - :LastModified ( - :Time ("Sun Nov 17 14:47:50 2002") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :NT_commands () - :commands () - :solaris_commands () - :AMON (false) - :AMON_class_name (default_opsec_status_object) - :CPMI (false) - :CVP (true) - :ELA (false) - :LEA (false) - :OMI (false) - :RTM (false) - :SAM (false) - :UAC (false) - :UFP (true) - :color (black) - :comments () - :product_info ( - :AdminInfo ( - :chkpf_uid ("{20675293-747A-4F42-B193-49B12EE0646A}") - :ClassName (OPSEC_product_info) - ) - :certification_info () - :certified (true) - :product (PureSight) - :vendor ("iCognito Technologies Ltd") - :version (3.6) - ) - :type (OPSEC_product) - ) - : (Intrusion_ELA_Bridge_1.0 - :AdminInfo ( - :chkpf_uid ("{990D5111-5271-4BD2-A548-0ED5903648B1}") - :ClassName (OPSEC_product) - :table (products) - :LastModified ( - :Time ("Sun Nov 17 14:47:51 2002") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :NT_commands () - :commands () - :solaris_commands () - :AMON (false) - :AMON_class_name (default_opsec_status_object) - :CPMI (false) - :CVP (false) - :ELA (true) - :LEA (false) - :OMI (false) - :RTM (false) - :SAM (false) - :UAC (false) - :UFP (false) - :color (black) - :comments () - :product_info ( - :AdminInfo ( - :chkpf_uid ("{7AD97E26-C1E6-449A-83DA-58F911CB7498}") - :ClassName (OPSEC_product_info) - ) - :certification_info () - :certified (true) - :product (SecureNet_Provider_ELA_Bridge) - :vendor (Intrusion) - :version (1.0) - ) - :type (OPSEC_product) - ) - : (IntruVert_IntruShield_IDS_1.1 - :AdminInfo ( - :chkpf_uid ("{2B22AC72-6A6B-4C14-805A-9A0D5215792A}") - :ClassName (OPSEC_product) - :table (products) - :LastModified ( - :Time ("Sun Nov 17 14:47:51 2002") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :NT_commands () - :commands () - :solaris_commands () - :AMON (false) - :AMON_class_name (default_opsec_status_object) - :CPMI (false) - :CVP (false) - :ELA (false) - :LEA (false) - :OMI (false) - :RTM (false) - :SAM (true) - :UAC (false) - :UFP (false) - :color (black) - :comments () - :product_info ( - :AdminInfo ( - :chkpf_uid ("{EE1220EA-F8F5-4BB6-8816-A85165707FC8}") - :ClassName (OPSEC_product_info) - ) - :certification_info () - :certified (true) - :product (IntruShield_IDS) - :vendor ("IntruVert Networks") - :version (1.1) - ) - :type (OPSEC_product) - ) - : (KaVaDo_InterDo_2.5 - :AdminInfo ( - :chkpf_uid ("{144CFFB1-0280-490F-9CEE-AE3BDD368B21}") - :ClassName (OPSEC_product) - :table (products) - :LastModified ( - :Time ("Sun Nov 17 14:47:51 2002") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :NT_commands () - :commands () - :solaris_commands () - :AMON (false) - :AMON_class_name (default_opsec_status_object) - :CPMI (false) - :CVP (false) - :ELA (false) - :LEA (false) - :OMI (false) - :RTM (false) - :SAM (true) - :UAC (false) - :UFP (false) - :color (black) - :comments () - :product_info ( - :AdminInfo ( - :chkpf_uid ("{6BEBC5CE-0101-4710-897F-779537481B0F}") - :ClassName (OPSEC_product_info) - ) - :certification_info () - :certified (true) - :product (InterDo) - :vendor (KaVaDo) - :version (2.5) - ) - :type (OPSEC_product) - ) - : (Latis_StillSecure_2.0 - :AdminInfo ( - :chkpf_uid ("{2399873E-177B-4AF7-AC6E-7845A0954862}") - :ClassName (OPSEC_product) - :table (products) - :LastModified ( - :Time ("Sun Nov 17 14:47:52 2002") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :NT_commands () - :commands () - :solaris_commands () - :AMON (false) - :AMON_class_name (default_opsec_status_object) - :CPMI (false) - :CVP (false) - :ELA (false) - :LEA (false) - :OMI (false) - :RTM (false) - :SAM (true) - :UAC (false) - :UFP (false) - :color (black) - :comments () - :product_info ( - :AdminInfo ( - :chkpf_uid ("{BAC1DA63-5F78-4799-B59A-EB9A64F5CA85}") - :ClassName (OPSEC_product_info) - ) - :certification_info () - :certified (true) - :product (StillSecure_Perimeter) - :vendor ("Latis Networks") - :version (2.0) - ) - :type (OPSEC_product) - ) - : (LogOn_SQLGuard_2.01 - :AdminInfo ( - :chkpf_uid ("{1ACBD3A6-68E6-412E-8E07-44BBAA8BDF5F}") - :ClassName (OPSEC_product) - :table (products) - :LastModified ( - :Time ("Sun Nov 17 14:47:52 2002") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :NT_commands () - :commands () - :solaris_commands () - :AMON (false) - :AMON_class_name (default_opsec_status_object) - :CPMI (false) - :CVP (true) - :ELA (true) - :LEA (false) - :OMI (false) - :RTM (false) - :SAM (false) - :UAC (false) - :UFP (false) - :color (black) - :comments () - :product_info ( - :AdminInfo ( - :chkpf_uid ("{C87A1D0B-A8D6-4DAF-9AB8-995462460978}") - :ClassName (OPSEC_product_info) - ) - :certification_info () - :certified (true) - :product (SQL_Guard) - :vendor ("LogOn Software") - :version (2.01) - ) - :type (OPSEC_product) - ) - : (nCircle_IP360 - :AdminInfo ( - :chkpf_uid ("{D0A4C84D-82ED-4392-B204-D629E94BC7E4}") - :ClassName (OPSEC_product) - :table (products) - :LastModified ( - :Time ("Sun Nov 17 14:47:52 2002") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :NT_commands () - :commands () - :solaris_commands () - :AMON (false) - :AMON_class_name (default_opsec_status_object) - :CPMI (false) - :CVP (false) - :ELA (false) - :LEA (false) - :OMI (false) - :RTM (false) - :SAM (true) - :UAC (false) - :UFP (false) - :color (black) - :comments () - :product_info ( - :AdminInfo ( - :chkpf_uid ("{5DBDFBB4-6BEC-49EF-AA6B-F255E0B750E5}") - :ClassName (OPSEC_product_info) - ) - :certification_info () - :certified (true) - :product (IP360) - :vendor ("nCircle Network Security") - :version (360) - ) - :type (OPSEC_product) - ) - : (NEC_CLUSTERPRO_FW_1.0 - :AdminInfo ( - :chkpf_uid ("{5B33026B-6D05-4339-BD69-F3ABA12FF288}") - :ClassName (OPSEC_product) - :table (products) - :LastModified ( - :Time ("Sun Nov 17 14:47:53 2002") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :NT_commands () - :commands () - :solaris_commands () - :AMON (false) - :AMON_class_name (default_opsec_status_object) - :CPMI (false) - :CVP (false) - :ELA (true) - :LEA (false) - :OMI (false) - :RTM (false) - :SAM (false) - :UAC (false) - :UFP (false) - :color (black) - :comments () - :product_info ( - :AdminInfo ( - :chkpf_uid ("{EE9AE544-5D34-465C-9D6D-FF28FD7DB74E}") - :ClassName (OPSEC_product_info) - ) - :certification_info () - :certified (true) - :product (CLUSTERPRO_FW) - :vendor (NEC) - :version (1.0) - ) - :type (OPSEC_product) - ) - : (NetIQ_SecurityManager_3.51 - :AdminInfo ( - :chkpf_uid ("{CAD16706-7ACE-4479-920A-8A9EB0790812}") - :ClassName (OPSEC_product) - :table (products) - :LastModified ( - :Time ("Sun Nov 17 14:47:53 2002") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :NT_commands () - :commands () - :solaris_commands () - :AMON (false) - :AMON_class_name (default_opsec_status_object) - :CPMI (false) - :CVP (false) - :ELA (false) - :LEA (true) - :OMI (false) - :RTM (false) - :SAM (false) - :UAC (false) - :UFP (false) - :color (black) - :comments () - :product_info ( - :AdminInfo ( - :chkpf_uid ("{CEA85410-9DC8-45EC-BE66-C7B2DA28E786}") - :ClassName (OPSEC_product_info) - ) - :certification_info () - :certified (true) - :product (SecurityManager) - :vendor (NetIQ) - :version (3.51) - ) - :type (OPSEC_product) - ) - : (netVmg_Flow_Analyzer_2.0 - :AdminInfo ( - :chkpf_uid ("{237FD389-CC08-47CA-A42C-FF62CBA22D06}") - :ClassName (OPSEC_product) - :table (products) - :LastModified ( - :Time ("Sun Nov 17 14:47:54 2002") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :NT_commands () - :commands () - :solaris_commands () - :AMON (false) - :AMON_class_name (default_opsec_status_object) - :CPMI (false) - :CVP (false) - :ELA (false) - :LEA (true) - :OMI (false) - :RTM (false) - :SAM (false) - :UAC (false) - :UFP (false) - :color (black) - :comments () - :product_info ( - :AdminInfo ( - :chkpf_uid ("{E00EC2B1-E27A-4C96-84CA-DE18198E750E}") - :ClassName (OPSEC_product_info) - ) - :certification_info () - :certified (true) - :product (Flow_Analyzer_FCP) - :vendor (netVmg) - :version (2.0) - ) - :type (OPSEC_product) - ) - : (OpenService_SystemWatch_2.7 - :AdminInfo ( - :chkpf_uid ("{43D8E678-3FDF-42ED-AD5E-D07340ACA9ED}") - :ClassName (OPSEC_product) - :table (products) - :LastModified ( - :Time ("Sun Nov 17 14:47:54 2002") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :NT_commands () - :commands () - :solaris_commands () - :AMON (false) - :AMON_class_name (default_opsec_status_object) - :CPMI (false) - :CVP (false) - :ELA (false) - :LEA (true) - :OMI (false) - :RTM (false) - :SAM (false) - :UAC (false) - :UFP (false) - :color (black) - :comments () - :product_info ( - :AdminInfo ( - :chkpf_uid ("{317645D2-91AC-4C3D-983B-FB53604719E8}") - :ClassName (OPSEC_product_info) - ) - :certification_info () - :certified (true) - :product (SystemWatch) - :vendor (OpenService) - :version (2.7) - ) - :type (OPSEC_product) - ) - : (QualysGuard_1.7 - :AdminInfo ( - :chkpf_uid ("{AD3BB362-2949-4F52-9EF6-66267EA09606}") - :ClassName (OPSEC_product) - :table (products) - :LastModified ( - :Time ("Sun Nov 17 14:47:55 2002") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :NT_commands () - :commands () - :solaris_commands () - :AMON (false) - :AMON_class_name (default_opsec_status_object) - :CPMI (true) - :CVP (false) - :ELA (true) - :LEA (false) - :OMI (false) - :RTM (false) - :SAM (false) - :UAC (false) - :UFP (false) - :color (black) - :comments () - :product_info ( - :AdminInfo ( - :chkpf_uid ("{A11EBA5E-4B2F-44B1-85F8-CA4C9490294A}") - :ClassName (OPSEC_product_info) - ) - :certification_info () - :certified (true) - :product (QualysGuard) - :vendor (Qualys) - :version (1.7) - ) - :type (OPSEC_product) - ) - : (Rainwall_3.0 - :AdminInfo ( - :chkpf_uid ("{8F2C6D6D-8475-4D1D-882B-A6A73B03ED69}") - :ClassName (OPSEC_product) - :table (products) - :LastModified ( - :Time ("Sun Nov 17 14:47:55 2002") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :NT_commands () - :commands () - :solaris_commands () - :AMON (true) - :AMON_class_name (default_opsec_status_object) - :CPMI (true) - :CVP (false) - :ELA (true) - :LEA (false) - :OMI (false) - :RTM (false) - :SAM (false) - :UAC (false) - :UFP (false) - :color (black) - :comments () - :product_info ( - :AdminInfo ( - :chkpf_uid ("{C1E8A9A9-2313-40C4-BED7-BDEE7523EA3F}") - :ClassName (OPSEC_product_info) - ) - :certification_info () - :certified (true) - :product (Rainwall) - :vendor (Rainfinity) - :version (3.0) - ) - :type (OPSEC_product) - ) - : (Rainwall_3.0_SP2 - :AdminInfo ( - :chkpf_uid ("{36263BBB-C30B-4DC7-B6E1-7E3B614F106D}") - :ClassName (OPSEC_product) - :table (products) - :LastModified ( - :Time ("Sun Nov 17 14:47:55 2002") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :NT_commands () - :commands () - :solaris_commands () - :AMON (true) - :AMON_class_name (default_opsec_status_object) - :CPMI (true) - :CVP (false) - :ELA (true) - :LEA (false) - :OMI (false) - :RTM (false) - :SAM (false) - :UAC (false) - :UFP (false) - :color (black) - :comments () - :product_info ( - :AdminInfo ( - :chkpf_uid ("{69B7508E-5363-49B4-8202-199C5BCCDF19}") - :ClassName (OPSEC_product_info) - ) - :certification_info () - :certified (true) - :product (Rainwall) - :vendor (Rainfinity) - :version ("3.0 SP2") - ) - :type (OPSEC_product) - ) - : (Recourse_ManHunt_MSA_2.1 - :AdminInfo ( - :chkpf_uid ("{68E38A62-5F3D-4BA4-B7A7-A1F27A577DBB}") - :ClassName (OPSEC_product) - :table (products) - :LastModified ( - :Time ("Sun Nov 17 14:47:56 2002") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :NT_commands () - :commands () - :solaris_commands () - :AMON (false) - :AMON_class_name (default_opsec_status_object) - :CPMI (false) - :CVP (false) - :ELA (false) - :LEA (true) - :OMI (false) - :RTM (false) - :SAM (false) - :UAC (false) - :UFP (false) - :color (black) - :comments () - :product_info ( - :AdminInfo ( - :chkpf_uid ("{4D9D1236-FF5A-42CC-8619-2BEB69E5476D}") - :ClassName (OPSEC_product_info) - ) - :certification_info () - :certified (true) - :product (ManHunt_Smart_Agent) - :vendor ("Recourse Technologies") - :version (2.1) - ) - :type (OPSEC_product) - ) - : (RiscManager_4.1 - :AdminInfo ( - :chkpf_uid ("{00EB61E3-C6A3-432E-8BC0-855659B09BEE}") - :ClassName (OPSEC_product) - :table (products) - :LastModified ( - :Time ("Sun Nov 17 14:47:56 2002") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :NT_commands () - :commands () - :solaris_commands () - :AMON (false) - :AMON_class_name (default_opsec_status_object) - :CPMI (false) - :CVP (false) - :ELA (false) - :LEA (true) - :OMI (false) - :RTM (false) - :SAM (true) - :UAC (false) - :UFP (false) - :color (black) - :comments () - :product_info ( - :AdminInfo ( - :chkpf_uid ("{EF2BB489-5E4A-40FA-85AE-0028FE27D337}") - :ClassName (OPSEC_product_info) - ) - :certification_info () - :certified (true) - :product (RiscManager) - :vendor ("Risc Solutions") - :version (4.1) - ) - :type (OPSEC_product) - ) - : (RouteScience_PathControl_2.0 - :AdminInfo ( - :chkpf_uid ("{3E077F18-923D-4FA9-8F8A-AD42DDEB8577}") - :ClassName (OPSEC_product) - :table (products) - :LastModified ( - :Time ("Sun Nov 17 14:47:56 2002") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :NT_commands () - :commands () - :solaris_commands () - :AMON (false) - :AMON_class_name (default_opsec_status_object) - :CPMI (true) - :CVP (false) - :ELA (false) - :LEA (false) - :OMI (false) - :RTM (false) - :SAM (false) - :UAC (false) - :UFP (false) - :color (black) - :comments () - :product_info ( - :AdminInfo ( - :chkpf_uid ("{A3E3AE18-C0D7-491F-899F-37B0CF81C9C7}") - :ClassName (OPSEC_product_info) - ) - :certification_info () - :certified (true) - :product (PathControl) - :vendor (RouteScience) - :version (2.0) - ) - :type (OPSEC_product) - ) - : (RSF-1_2.1 - :AdminInfo ( - :chkpf_uid ("{962C136F-A152-4A70-896C-B5255E38100E}") - :ClassName (OPSEC_product) - :table (products) - :LastModified ( - :Time ("Sun Nov 17 14:47:57 2002") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :NT_commands () - :commands () - :solaris_commands () - :AMON (false) - :AMON_class_name (default_opsec_status_object) - :CPMI (false) - :CVP (false) - :ELA (true) - :LEA (false) - :OMI (false) - :RTM (false) - :SAM (false) - :UAC (false) - :UFP (false) - :color (black) - :comments () - :product_info ( - :AdminInfo ( - :chkpf_uid ("{213E59BB-B78D-40B4-AD2E-E04A72C24A55}") - :ClassName (OPSEC_product_info) - ) - :certification_info () - :certified (true) - :product (RSF-1) - :vendor ("High Availability.com") - :version (2.1) - ) - :type (OPSEC_product) - ) - : (SecoShield_3.1 - :AdminInfo ( - :chkpf_uid ("{DA16BDEE-AB1A-42B5-AF7B-F9CEDED44C56}") - :ClassName (OPSEC_product) - :table (products) - :LastModified ( - :Time ("Sun Nov 17 14:47:58 2002") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :NT_commands () - :commands () - :solaris_commands () - :AMON (true) - :AMON_class_name (default_opsec_status_object) - :CPMI (true) - :CVP (false) - :ELA (true) - :LEA (false) - :OMI (false) - :RTM (false) - :SAM (true) - :UAC (false) - :UFP (false) - :color (black) - :comments () - :product_info ( - :AdminInfo ( - :chkpf_uid ("{E1F03A62-6DF6-4159-AC8F-6D89669D4DC8}") - :ClassName (OPSEC_product_info) - ) - :certification_info () - :certified (true) - :product (SecoShield_3.1) - :vendor (INFOSEC_Technologies) - :version (3.1) - ) - :type (OPSEC_product) - ) - : (StoneBeat_FullCluster_3.0 - :AdminInfo ( - :chkpf_uid ("{0CDB568E-F4AC-4E4F-913F-5563993374F1}") - :ClassName (OPSEC_product) - :table (products) - :LastModified ( - :Time ("Sun Nov 17 14:47:58 2002") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :NT_commands () - :commands () - :solaris_commands () - :AMON (false) - :AMON_class_name (default_opsec_status_object) - :CPMI (true) - :CVP (false) - :ELA (true) - :LEA (false) - :OMI (false) - :RTM (false) - :SAM (false) - :UAC (false) - :UFP (false) - :color (black) - :comments () - :product_info ( - :AdminInfo ( - :chkpf_uid ("{BC989FF9-70E8-4BDC-8EF1-164E8F913B52}") - :ClassName (OPSEC_product_info) - ) - :certification_info () - :certified (true) - :product (StoneBeat_FullCluster) - :vendor (StoneSoft) - :version (3.0) - ) - :type (OPSEC_product) - ) - : (Symantec_Web_Security_2.5 - :AdminInfo ( - :chkpf_uid ("{CAA1846F-E365-4D28-9D97-CFF832118A3B}") - :ClassName (OPSEC_product) - :table (products) - :LastModified ( - :Time ("Sun Nov 17 14:47:58 2002") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :NT_commands () - :commands () - :solaris_commands () - :AMON (false) - :AMON_class_name (default_opsec_status_object) - :CPMI (false) - :CVP (true) - :ELA (false) - :LEA (false) - :OMI (false) - :RTM (false) - :SAM (false) - :UAC (false) - :UFP (false) - :color (black) - :comments () - :product_info ( - :AdminInfo ( - :chkpf_uid ("{A8557DE2-054D-4398-A350-EEFEDEBD6E1F}") - :ClassName (OPSEC_product_info) - ) - :certification_info () - :certified (true) - :product (Symantec_Web_Security) - :vendor (Symantec) - :version (2.5) - ) - :type (OPSEC_product) - ) - : (Tripwire_For_Servers_3.0 - :AdminInfo ( - :chkpf_uid ("{9C167955-001C-49CD-81C8-E7663735FF48}") - :ClassName (OPSEC_product) - :table (products) - :LastModified ( - :Time ("Sun Nov 17 14:47:59 2002") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :NT_commands () - :commands () - :solaris_commands () - :AMON (false) - :AMON_class_name (default_opsec_status_object) - :CPMI (false) - :CVP (false) - :ELA (true) - :LEA (false) - :OMI (false) - :RTM (false) - :SAM (false) - :UAC (false) - :UFP (false) - :color (black) - :comments () - :product_info ( - :AdminInfo ( - :chkpf_uid ("{65423D8E-21F1-4972-A4B9-BC0E2474018D}") - :ClassName (OPSEC_product_info) - ) - :certification_info () - :certified (true) - :product (Tripwire_For_Servers) - :vendor (Tripwire) - :version (3.0) - ) - :type (OPSEC_product) - ) - : (Trustworks_GSM_3.3.2 - :AdminInfo ( - :chkpf_uid ("{53437B06-A258-4A76-92C1-CFC3D7B85384}") - :ClassName (OPSEC_product) - :table (products) - :LastModified ( - :Time ("Sun Nov 17 14:47:59 2002") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :NT_commands () - :commands () - :solaris_commands () - :AMON (false) - :AMON_class_name (default_opsec_status_object) - :CPMI (true) - :CVP (false) - :ELA (false) - :LEA (false) - :OMI (false) - :RTM (false) - :SAM (false) - :UAC (false) - :UFP (false) - :color (black) - :comments () - :product_info ( - :AdminInfo ( - :chkpf_uid ("{8BE4E5A1-C142-48DC-BCF8-A0E9D39D054D}") - :ClassName (OPSEC_product_info) - ) - :certification_info () - :certified (true) - :product (Global_Security_Manager) - :vendor (Trustworks) - :version (3.3.2) - ) - :type (OPSEC_product) - ) - : (WebSense_Enterprise_4.4 - :AdminInfo ( - :chkpf_uid ("{5CD0E11A-7658-4158-B313-C310E5D14E21}") - :ClassName (OPSEC_product) - :table (products) - :LastModified ( - :Time ("Sun Nov 17 14:48:00 2002") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :NT_commands () - :commands () - :solaris_commands () - :AMON (false) - :AMON_class_name (default_opsec_status_object) - :CPMI (false) - :CVP (false) - :ELA (false) - :LEA (false) - :OMI (false) - :RTM (false) - :SAM (false) - :UAC (false) - :UFP (true) - :color (black) - :comments () - :product_info ( - :AdminInfo ( - :chkpf_uid ("{4471126F-C2FA-411F-A459-9C4ACC501A67}") - :ClassName (OPSEC_product_info) - ) - :certification_info () - :certified (true) - :product (WebSense_for_FireWall-1) - :vendor (WebSense) - :version (4.4) - ) - :type (OPSEC_product) - ) - : (TM_IMSS_5.1 - :AdminInfo ( - :chkpf_uid ("{B8177692-19D5-4746-AD58-D9C46E4F00A0}") - :ClassName (OPSEC_product) - :table (products) - :LastModified ( - :Time ("Sun Nov 17 14:48:00 2002") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :NT_commands () - :commands () - :solaris_commands () - :AMON (true) - :AMON_class_name (default_opsec_status_object) - :CPMI (false) - :CVP (false) - :ELA (false) - :LEA (false) - :OMI (false) - :RTM (false) - :SAM (false) - :UAC (false) - :UFP (false) - :color (black) - :comments () - :product_info ( - :AdminInfo ( - :chkpf_uid ("{5185B9D6-D1E2-4181-95A1-0FA095D2E4B2}") - :ClassName (OPSEC_product_info) - ) - :certification_info () - :certified (true) - :product (IMSS) - :vendor (Trend_Micro) - :version (5.1) - ) - :type (OPSEC_product) - ) - : (NetIQ_Security_Manager_4.0 - :AdminInfo ( - :chkpf_uid ("{F41306EC-F711-4A31-B662-FC7FD9668891}") - :ClassName (OPSEC_product) - :table (products) - :LastModified ( - :Time ("Sun Nov 17 14:48:01 2002") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :NT_commands () - :commands () - :solaris_commands () - :AMON (false) - :AMON_class_name (default_opsec_status_object) - :CPMI (false) - :CVP (false) - :ELA (false) - :LEA (true) - :OMI (false) - :RTM (false) - :SAM (false) - :UAC (false) - :UFP (false) - :color (black) - :comments () - :product_info ( - :AdminInfo ( - :chkpf_uid ("{9311BC4D-291F-42F9-85B4-223BBB5D5FBB}") - :ClassName (OPSEC_product_info) - ) - :certification_info () - :certified (true) - :product (SecurityManager) - :vendor (NetIQ) - :version (4.0) - ) - :type (OPSEC_product) - ) - : (Akonix_L7_1.0 - :AdminInfo ( - :chkpf_uid ("{510B55DC-06E8-4615-AFE5-35648B79E433}") - :ClassName (OPSEC_product) - :table (products) - :LastModified ( - :Time ("Sun Nov 17 14:55:27 2002") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :NT_commands () - :commands () - :solaris_commands () - :AMON (false) - :AMON_class_name (default_opsec_status_object) - :CPMI (false) - :CVP (true) - :ELA (false) - :LEA (false) - :OMI (false) - :RTM (false) - :SAM (false) - :UAC (false) - :UFP (false) - :color (black) - :comments () - :product_info ( - :AdminInfo ( - :chkpf_uid ("{49E1EC41-3764-42B5-BB07-6307CD981126}") - :ClassName (OPSEC_product_info) - ) - :certification_info () - :certified (true) - :product (L7) - :vendor (Akonix) - :version (1.0) - ) - :type (OPSEC_product) - ) - : (Aladdin_ESafe_Gateway_3.1 - :AdminInfo ( - :chkpf_uid ("{8A7D0327-7578-4055-A615-2AB7AC4AD39D}") - :ClassName (OPSEC_product) - :table (products) - :LastModified ( - :Time ("Sun Nov 17 14:57:22 2002") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :NT_commands () - :commands () - :solaris_commands () - :AMON (false) - :AMON_class_name (default_opsec_status_object) - :CPMI (false) - :CVP (true) - :ELA (false) - :LEA (false) - :OMI (false) - :RTM (false) - :SAM (false) - :UAC (false) - :UFP (false) - :color (black) - :comments () - :product_info ( - :AdminInfo ( - :chkpf_uid ("{50FC2B4C-A41F-42B7-A844-50E87B242B5C}") - :ClassName (OPSEC_product_info) - ) - :certification_info () - :certified (true) - :product (ESafe_Protect_Gateway) - :vendor (Aladdin_Knowledge_Systems) - :version (3.1) - ) - :type (OPSEC_product) - ) - : (Bind_View_bv-Control_7.2 - :AdminInfo ( - :chkpf_uid ("{B544740E-DCC8-4BDC-B37C-5CA1E4C0ED0E}") - :ClassName (OPSEC_product) - :table (products) - :LastModified ( - :Time ("Sun Nov 17 15:00:04 2002") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :NT_commands () - :commands () - :solaris_commands () - :AMON (false) - :AMON_class_name (default_opsec_status_object) - :CPMI (false) - :CVP (false) - :ELA (false) - :LEA (true) - :OMI (false) - :RTM (false) - :SAM (false) - :UAC (false) - :UFP (false) - :color (black) - :comments () - :product_info ( - :AdminInfo ( - :chkpf_uid ("{B308FF29-A6B2-4715-9230-2C1E1FD8D2BA}") - :ClassName (OPSEC_product_info) - ) - :certification_info () - :certified (true) - :product (bv-Control_for_Check_Point_FW-1) - :vendor (BindView) - :version (7.2) - ) - :type (OPSEC_product) - ) - : (NFR_Security_CMS_2.1 - :AdminInfo ( - :chkpf_uid ("{9C629DA4-D45E-4D12-9BF9-6F7991C58852}") - :ClassName (OPSEC_product) - :table (products) - :LastModified ( - :Time ("Sun Nov 17 15:03:31 2002") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :NT_commands () - :commands () - :solaris_commands () - :AMON (false) - :AMON_class_name (default_opsec_status_object) - :CPMI (false) - :CVP (false) - :ELA (false) - :LEA (false) - :OMI (false) - :RTM (false) - :SAM (true) - :UAC (false) - :UFP (false) - :color (black) - :comments () - :product_info ( - :AdminInfo ( - :chkpf_uid ("{7DCC5BDA-E8DA-4B6C-847E-D421730BCBD4}") - :ClassName (OPSEC_product_info) - ) - :certification_info () - :certified (true) - :product (CMS) - :vendor ("NFR Security Inc.") - :version (2.1) - ) - :type (OPSEC_product) - ) - : (Sanctum_AppShield_3.0 - :AdminInfo ( - :chkpf_uid ("{C900DCF0-FCC4-45E7-9E29-EFD0F8D5FD3A}") - :ClassName (OPSEC_product) - :table (products) - :LastModified ( - :Time ("Sun Nov 17 15:09:02 2002") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :NT_commands () - :commands () - :solaris_commands () - :AMON (false) - :AMON_class_name (default_opsec_status_object) - :CPMI (false) - :CVP (false) - :ELA (true) - :LEA (false) - :OMI (false) - :RTM (false) - :SAM (false) - :UAC (false) - :UFP (false) - :color (black) - :comments () - :product_info ( - :AdminInfo ( - :chkpf_uid ("{B83C4359-4890-49A7-AECB-0DD4B4F689CF}") - :ClassName (OPSEC_product_info) - ) - :certification_info () - :certified (true) - :product (AppShield) - :vendor ("Sanctum Inc.") - :version (3.0) - ) - :type (OPSEC_product) - ) - : (Lucid_Security_ipAngel_1.0 - :AdminInfo ( - :chkpf_uid ("{10CD6D53-3FF5-4722-BB68-E10652AEB4AC}") - :ClassName (OPSEC_product) - :table (products) - :LastModified ( - :Time ("Sun Nov 17 15:11:33 2002") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :NT_commands () - :commands () - :solaris_commands () - :AMON (false) - :AMON_class_name (default_opsec_status_object) - :CPMI (true) - :CVP (false) - :ELA (false) - :LEA (false) - :OMI (false) - :RTM (false) - :SAM (true) - :UAC (false) - :UFP (false) - :color (black) - :comments () - :product_info ( - :AdminInfo ( - :chkpf_uid ("{418A3011-4E22-4946-9B6D-55A5EB88FCD3}") - :ClassName (OPSEC_product_info) - ) - :certification_info () - :certified (true) - :product (ipAngel) - :vendor ("Lucid Security") - :version (1.0) - ) - :type (OPSEC_product) - ) - : (Ikarus_Content_Wall_2.25 - :AdminInfo ( - :chkpf_uid ("{8C48300C-3289-4DC7-985B-4E8C6C32709C}") - :ClassName (OPSEC_product) - :table (products) - :LastModified ( - :Time ("Sun Nov 17 15:18:14 2002") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :NT_commands () - :commands () - :solaris_commands () - :AMON (true) - :AMON_class_name (default_opsec_status_object) - :CPMI (false) - :CVP (true) - :ELA (true) - :LEA (false) - :OMI (false) - :RTM (false) - :SAM (false) - :UAC (false) - :UFP (true) - :color (black) - :comments () - :product_info ( - :AdminInfo ( - :chkpf_uid ("{64C3E29F-AEBE-4E19-B46D-7B141DDF8D99}") - :ClassName (OPSEC_product_info) - ) - :certification_info () - :certified (true) - :product (Content_Wall) - :vendor (Ikarus) - :version (2.25) - ) - :type (OPSEC_product) - ) - : (AirWave_AMP_1.1 - :AdminInfo ( - :chkpf_uid ("{F52E30B3-EF5F-411A-AE83-1063D39506C4}") - :ClassName (OPSEC_product) - :table (products) - :LastModified ( - :Time ("Sun Nov 17 17:10:45 2002") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :NT_commands () - :commands () - :solaris_commands () - :AMON (false) - :AMON_class_name (default_opsec_status_object) - :CPMI (false) - :CVP (false) - :ELA (false) - :LEA (true) - :OMI (false) - :RTM (false) - :SAM (false) - :UAC (false) - :UFP (false) - :color (black) - :comments () - :product_info ( - :AdminInfo ( - :chkpf_uid ("{A168D04B-589F-48F1-B49D-E5E0DF7F0E29}") - :ClassName (OPSEC_product_info) - ) - :certification_info () - :certified (true) - :product (AMP) - :vendor (AirWave) - :version (1.1) - ) - :type (OPSEC_product) - ) - : (Aladdin_eSafe_Gateway_3.5 - :AdminInfo ( - :chkpf_uid ("{1C1AFCE6-1DBB-4CD9-BE8A-403C84ED1944}") - :ClassName (OPSEC_product) - :table (products) - :LastModified ( - :Time ("Mon Sep 15 07:32:08 2003") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :NT_commands () - :commands () - :solaris_commands () - :AMON (false) - :AMON_class_name (default_opsec_status_object) - :CPMI (false) - :CVP (true) - :ELA (false) - :LEA (false) - :OMI (false) - :RTM (false) - :SAM (false) - :UAC (false) - :UFP (false) - :color (black) - :comments () - :product_info ( - :AdminInfo ( - :chkpf_uid ("{70DAC38B-14C8-4DEE-9556-0EF42BB91747}") - :ClassName (OPSEC_product_info) - ) - :certification_info () - :certified (true) - :product (eSafe_Gateway) - :vendor (Aladdin_Knowledge_Systems) - :version (3.5) - ) - :type (OPSEC_product) - ) - : (Business_Layers_eProvision_Module_3.0 - :AdminInfo ( - :chkpf_uid ("{BD248D30-B489-4C70-A9FA-3A74B10AABA9}") - :ClassName (OPSEC_product) - :table (products) - :LastModified ( - :Time ("Mon Sep 15 07:45:11 2003") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :NT_commands () - :commands () - :solaris_commands () - :AMON (false) - :AMON_class_name (default_opsec_status_object) - :CPMI (false) - :CVP (false) - :ELA (false) - :LEA (false) - :OMI (false) - :RTM (false) - :SAM (false) - :UAC (true) - :UFP (false) - :color (black) - :comments () - :product_info ( - :AdminInfo ( - :chkpf_uid ("{38EE5F2D-3285-4457-B17D-67D666728119}") - :ClassName (OPSEC_product_info) - ) - :certification_info () - :certified (true) - :product (eProvision_Module) - :vendor (Business_Layers) - :version (3.0) - ) - :type (OPSEC_product) - ) - : (Citrix_MetaFrame_XP - :AdminInfo ( - :chkpf_uid ("{B6A4EAFE-A167-4EE3-BDDA-FEA9437DF8D2}") - :ClassName (OPSEC_product) - :table (products) - :LastModified ( - :Time ("Mon Sep 15 07:49:04 2003") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :NT_commands () - :commands () - :solaris_commands () - :AMON (false) - :AMON_class_name (default_opsec_status_object) - :CPMI (false) - :CVP (false) - :ELA (false) - :LEA (false) - :OMI (false) - :RTM (false) - :SAM (false) - :UAC (true) - :UFP (false) - :color (black) - :comments () - :product_info ( - :AdminInfo ( - :chkpf_uid ("{3A6CE35E-BAFB-4DBF-928A-ABD6A5DB4DA1}") - :ClassName (OPSEC_product_info) - ) - :certification_info () - :certified (true) - :product (MetaFrame) - :vendor (Citrix) - :version (XP) - ) - :type (OPSEC_product) - ) - : (Computer_Associate_eTrust_Antivirus_7.0 - :AdminInfo ( - :chkpf_uid ("{D92F77E0-57F8-4CBF-B0DE-76C1FF309196}") - :ClassName (OPSEC_product) - :table (products) - :LastModified ( - :Time ("Mon Sep 15 07:55:18 2003") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :NT_commands () - :commands () - :solaris_commands () - :AMON (false) - :AMON_class_name (default_opsec_status_object) - :CPMI (false) - :CVP (true) - :ELA (false) - :LEA (false) - :OMI (false) - :RTM (false) - :SAM (false) - :UAC (false) - :UFP (false) - :color (black) - :comments () - :product_info ( - :AdminInfo ( - :chkpf_uid ("{0396E466-6ECE-47DC-8090-4FF589D2092C}") - :ClassName (OPSEC_product_info) - ) - :certification_info () - :certified (true) - :product (eTrust_Antivirus) - :vendor (Computer_Associates) - :version (7.0) - ) - :type (OPSEC_product) - ) - : (Lucid_Security_ipANGEL_2.0 - :AdminInfo ( - :chkpf_uid ("{136A989A-4087-4E20-8B6F-D253F54C80E4}") - :ClassName (OPSEC_product) - :table (products) - :LastModified ( - :Time ("Mon Sep 15 07:59:12 2003") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :NT_commands () - :commands () - :solaris_commands () - :AMON (false) - :AMON_class_name (default_opsec_status_object) - :CPMI (true) - :CVP (false) - :ELA (false) - :LEA (false) - :OMI (false) - :RTM (false) - :SAM (true) - :UAC (false) - :UFP (false) - :color (black) - :comments () - :product_info ( - :AdminInfo ( - :chkpf_uid ("{3707BE37-699F-4F0B-95E2-5F012D352BD6}") - :ClassName (OPSEC_product_info) - ) - :certification_info () - :certified (true) - :product (ipANGEL) - :vendor ("Lucid Security") - :version (2.0) - ) - :type (OPSEC_product) - ) - : (ProactiveNet_Monitor_for_FireWall-1_3.1 - :AdminInfo ( - :chkpf_uid ("{3A254832-21E2-4952-8729-120CF0B2915C}") - :ClassName (OPSEC_product) - :table (products) - :LastModified ( - :Time ("Mon Sep 15 08:03:27 2003") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :NT_commands () - :commands () - :solaris_commands () - :AMON (false) - :AMON_class_name (default_opsec_status_object) - :CPMI (false) - :CVP (false) - :ELA (false) - :LEA (true) - :OMI (false) - :RTM (false) - :SAM (false) - :UAC (false) - :UFP (false) - :color (black) - :comments () - :product_info ( - :AdminInfo ( - :chkpf_uid ("{C7DD1EDC-B16A-470A-ABF5-D1B03EF97BB0}") - :ClassName (OPSEC_product_info) - ) - :certification_info () - :certified (true) - :product (Monitor_for_FireWall-1) - :vendor (ProactiveNet) - :version (3.1) - ) - :type (OPSEC_product) - ) - : (NetIQ_Security_Reporting_Center_2.0 - :AdminInfo ( - :chkpf_uid ("{4F7AFBF3-C02E-4416-AF7F-5A4651A2E48B}") - :ClassName (OPSEC_product) - :table (products) - :LastModified ( - :Time ("Mon Sep 15 08:06:28 2003") - :By (ChackPoint) - :From (CheckPoint) - ) - ) - :NT_commands () - :commands () - :solaris_commands () - :AMON (false) - :AMON_class_name (default_opsec_status_object) - :CPMI (false) - :CVP (false) - :ELA (false) - :LEA (true) - :OMI (false) - :RTM (false) - :SAM (false) - :UAC (false) - :UFP (false) - :color (black) - :comments () - :product_info ( - :AdminInfo ( - :chkpf_uid ("{6316A47A-91A9-40B5-AA42-D4DB602B8D41}") - :ClassName (OPSEC_product_info) - ) - :certification_info () - :certified (true) - :product (Security_Reporting_Center) - :vendor (NetIQ) - :version (2.0) - ) - :type (OPSEC_product) - ) - : (Sanctum_AppShield_4.0 - :AdminInfo ( - :chkpf_uid ("{2E9FE302-3DC2-4E79-AF86-C67B48E1443E}") - :ClassName (OPSEC_product) - :table (products) - :LastModified ( - :Time ("Mon Sep 15 08:10:50 2003") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :NT_commands () - :commands () - :solaris_commands () - :AMON (false) - :AMON_class_name (default_opsec_status_object) - :CPMI (false) - :CVP (false) - :ELA (true) - :LEA (false) - :OMI (false) - :RTM (false) - :SAM (true) - :UAC (false) - :UFP (false) - :color (black) - :comments () - :product_info ( - :AdminInfo ( - :chkpf_uid ("{C75B7FC4-4E1A-42AC-8020-878ABCCE5BBF}") - :ClassName (OPSEC_product_info) - ) - :certification_info () - :certified (true) - :product (AppShield) - :vendor ("Sanctum Inc.") - :version (4.0) - ) - :type (OPSEC_product) - ) - : (TowerView_Security_HighTower_1.5 - :AdminInfo ( - :chkpf_uid ("{E885A37B-817D-469F-B118-CA226D9F4175}") - :ClassName (OPSEC_product) - :table (products) - :LastModified ( - :Time ("Mon Sep 15 08:15:00 2003") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :NT_commands () - :commands () - :solaris_commands () - :AMON (false) - :AMON_class_name (default_opsec_status_object) - :CPMI (false) - :CVP (false) - :ELA (false) - :LEA (true) - :OMI (false) - :RTM (false) - :SAM (false) - :UAC (false) - :UFP (false) - :color (black) - :comments () - :product_info ( - :AdminInfo ( - :chkpf_uid ("{28B69705-28C6-45D7-8BF7-904C979156E2}") - :ClassName (OPSEC_product_info) - ) - :certification_info () - :certified (true) - :product (HighTower) - :vendor (TowerView_Security) - :version (1.5) - ) - :type (OPSEC_product) - ) - : (Network_Intelligence_enVision_1100 - :AdminInfo ( - :chkpf_uid ("{ABE2AB14-520E-4731-8078-B4FE56B5DE77}") - :ClassName (OPSEC_product) - :table (products) - :LastModified ( - :Time ("Mon Sep 15 08:17:24 2003") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :NT_commands () - :commands () - :solaris_commands () - :AMON (false) - :AMON_class_name (default_opsec_status_object) - :CPMI (false) - :CVP (false) - :ELA (false) - :LEA (true) - :OMI (false) - :RTM (false) - :SAM (false) - :UAC (false) - :UFP (false) - :color (black) - :comments () - :product_info ( - :AdminInfo ( - :chkpf_uid ("{450B818C-C024-4F91-87C4-1998E5BA24D4}") - :ClassName (OPSEC_product_info) - ) - :certification_info () - :certified (true) - :product (enVision) - :vendor (Network_Intelligence) - :version (1100) - ) - :type (OPSEC_product) - ) - : (FishNet_Security_FireMon_2.5 - :AdminInfo ( - :chkpf_uid ("{CA2D620E-74C6-4ECB-B9C7-86CE53A7D707}") - :ClassName (OPSEC_product) - :table (products) - :LastModified ( - :Time ("Mon Sep 15 08:30:03 2003") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :NT_commands () - :commands () - :solaris_commands () - :AMON (true) - :AMON_class_name (default_opsec_status_object) - :CPMI (true) - :CVP (false) - :ELA (true) - :LEA (false) - :OMI (false) - :RTM (false) - :SAM (false) - :UAC (false) - :UFP (false) - :color (black) - :comments () - :product_info ( - :AdminInfo ( - :chkpf_uid ("{F921C2BE-68A6-4A08-80D9-47E995BC92EA}") - :ClassName (OPSEC_product_info) - ) - :certification_info () - :certified (true) - :product (FireMon) - :vendor ("FishNet Security") - :version (2.5) - ) - :type (OPSEC_product) - ) - : (Secure_Computing_Smart_Filter_3.2 - :AdminInfo ( - :chkpf_uid ("{114F1E7F-DC18-4F2F-83D7-61B60A69BFBA}") - :ClassName (OPSEC_product) - :table (products) - :LastModified ( - :Time ("Mon Sep 15 08:34:09 2003") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :NT_commands () - :commands () - :solaris_commands () - :AMON (true) - :AMON_class_name (default_opsec_status_object) - :CPMI (false) - :CVP (false) - :ELA (false) - :LEA (false) - :OMI (false) - :RTM (false) - :SAM (false) - :UAC (false) - :UFP (true) - :color (black) - :comments () - :product_info ( - :AdminInfo ( - :chkpf_uid ("{3DCF6EEE-46C4-45C2-AD85-B0AD5CAF3FA7}") - :ClassName (OPSEC_product_info) - ) - :certification_info () - :certified (true) - :product (Smart_Filter) - :vendor (Secure_Computing) - :version (3.2) - ) - :type (OPSEC_product) - ) - : (Bindview_bv-Control_7.25 - :AdminInfo ( - :chkpf_uid ("{00DF0C36-DD39-4472-8144-74A62E060134}") - :ClassName (OPSEC_product) - :table (products) - :LastModified ( - :Time ("Mon Sep 15 08:37:17 2003") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :NT_commands () - :commands () - :solaris_commands () - :AMON (false) - :AMON_class_name (default_opsec_status_object) - :CPMI (true) - :CVP (false) - :ELA (false) - :LEA (true) - :OMI (false) - :RTM (false) - :SAM (false) - :UAC (false) - :UFP (false) - :color (black) - :comments () - :product_info ( - :AdminInfo ( - :chkpf_uid ("{C34E2DA4-ECF8-4F10-AE5F-D9DE79468E25}") - :ClassName (OPSEC_product_info) - ) - :certification_info () - :certified (true) - :product (bv-Control) - :vendor (BindView) - :version (7.25) - ) - :type (OPSEC_product) - ) - : (Proficient_Networks_Network_Policy_Engine_2.2 - :AdminInfo ( - :chkpf_uid ("{D0FD2531-1933-46C7-87CC-DBB691CB1B6E}") - :ClassName (OPSEC_product) - :table (products) - :LastModified ( - :Time ("Mon Sep 15 08:40:22 2003") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :NT_commands () - :commands () - :solaris_commands () - :AMON (true) - :AMON_class_name (default_opsec_status_object) - :CPMI (false) - :CVP (false) - :ELA (true) - :LEA (false) - :OMI (false) - :RTM (false) - :SAM (false) - :UAC (false) - :UFP (false) - :color (black) - :comments () - :product_info ( - :AdminInfo ( - :chkpf_uid ("{28F2187E-B387-4246-AF8D-C46A26DB75D2}") - :ClassName (OPSEC_product_info) - ) - :certification_info () - :certified (true) - :product (Network_Policy_Engine) - :vendor (Proficient_Networks) - :version (2.2) - ) - :type (OPSEC_product) - ) - : (Micromuse_NetCool_2.2 - :AdminInfo ( - :chkpf_uid ("{AF936F3A-87BE-4E98-9E6E-C85559D9E127}") - :ClassName (OPSEC_product) - :table (products) - :LastModified ( - :Time ("Mon Sep 15 08:43:04 2003") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :NT_commands () - :commands () - :solaris_commands () - :AMON (false) - :AMON_class_name (default_opsec_status_object) - :CPMI (false) - :CVP (false) - :ELA (false) - :LEA (true) - :OMI (false) - :RTM (false) - :SAM (false) - :UAC (false) - :UFP (false) - :color (black) - :comments () - :product_info ( - :AdminInfo ( - :chkpf_uid ("{661C391B-10C6-46FE-B22D-EF0393EF654B}") - :ClassName (OPSEC_product_info) - ) - :certification_info () - :certified (true) - :product (NetCool) - :vendor (Micromuse) - :version (2.2) - ) - :type (OPSEC_product) - ) - : (Websense_Enterprise_for_FireWall-1_5.0 - :AdminInfo ( - :chkpf_uid ("{708269B3-0DA5-4550-8CE5-E715F4C4D3B4}") - :ClassName (OPSEC_product) - :table (products) - :LastModified ( - :Time ("Mon Sep 15 08:45:26 2003") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :NT_commands () - :commands () - :solaris_commands () - :AMON (false) - :AMON_class_name (default_opsec_status_object) - :CPMI (false) - :CVP (false) - :ELA (false) - :LEA (false) - :OMI (false) - :RTM (false) - :SAM (false) - :UAC (false) - :UFP (true) - :color (black) - :comments () - :product_info ( - :AdminInfo ( - :chkpf_uid ("{28116254-C132-4EC1-8E49-84FE1E829DD4}") - :ClassName (OPSEC_product_info) - ) - :certification_info () - :certified (true) - :product (Enterprise_for_FireWall-1) - :vendor (Websense) - :version (5.0) - ) - :type (OPSEC_product) - ) - : (ForeScout_ActiveScout_2.7 - :AdminInfo ( - :chkpf_uid ("{315BCBAA-1D35-40BD-902C-3FFDE190FBCB}") - :ClassName (OPSEC_product) - :table (products) - :LastModified ( - :Time ("Mon Sep 15 08:49:17 2003") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :NT_commands () - :commands () - :solaris_commands () - :AMON (true) - :AMON_class_name (default_opsec_status_object) - :CPMI (false) - :CVP (false) - :ELA (true) - :LEA (false) - :OMI (false) - :RTM (false) - :SAM (true) - :UAC (false) - :UFP (false) - :color (black) - :comments () - :product_info ( - :AdminInfo ( - :chkpf_uid ("{175B4203-FE14-4AE7-B016-B2078FFB826E}") - :ClassName (OPSEC_product_info) - ) - :certification_info () - :certified (true) - :product (ActiveScout) - :vendor (ForeScout) - :version (2.7) - ) - :type (OPSEC_product) - ) - : (Rainfintiy_Rainwall_3.1 - :AdminInfo ( - :chkpf_uid ("{BA568194-BEF4-40FA-883A-388AFDB6CBF9}") - :ClassName (OPSEC_product) - :table (products) - :LastModified ( - :Time ("Mon Sep 15 08:52:02 2003") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :NT_commands () - :commands () - :solaris_commands () - :AMON (true) - :AMON_class_name (default_opsec_status_object) - :CPMI (true) - :CVP (false) - :ELA (true) - :LEA (false) - :OMI (false) - :RTM (false) - :SAM (false) - :UAC (false) - :UFP (false) - :color (black) - :comments () - :product_info ( - :AdminInfo ( - :chkpf_uid ("{A26B3A19-396C-4FEA-A4CD-B2AEAFAF14E7}") - :ClassName (OPSEC_product_info) - ) - :certification_info () - :certified (true) - :product (Rainwall) - :vendor (Rainfinity) - :version (3.1) - ) - :type (OPSEC_product) - ) - : (Sourcefire_Network_Sensor_2.5 - :AdminInfo ( - :chkpf_uid ("{86BC6AD3-097D-4F6D-8E2F-8E5BACA98F52}") - :ClassName (OPSEC_product) - :table (products) - :LastModified ( - :Time ("Mon Sep 15 08:54:44 2003") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :NT_commands () - :commands () - :solaris_commands () - :AMON (false) - :AMON_class_name (default_opsec_status_object) - :CPMI (false) - :CVP (false) - :ELA (false) - :LEA (false) - :OMI (false) - :RTM (false) - :SAM (true) - :UAC (false) - :UFP (false) - :color (black) - :comments () - :product_info ( - :AdminInfo ( - :chkpf_uid ("{6AC5B4CD-C4DA-4658-AFE6-5607F55B6EA7}") - :ClassName (OPSEC_product_info) - ) - :certification_info () - :certified (true) - :product (Network_Sensor) - :vendor (Sourcefire) - :version (2.5) - ) - :type (OPSEC_product) - ) - : (Aladdin_ESafe_Gateway_3.0 - :AdminInfo ( - :chkpf_uid ("{4BB6349F-A175-4E3F-8EE3-F81BB8B3E834}") - :ClassName (OPSEC_product) - :table (products) - :LastModified ( - :Time ("Sun Dec 30 11:36:41 2001") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :NT_commands () - :commands () - :solaris_commands () - :AMON (false) - :AMON_class_name (default_opsec_status_object) - :CPMI (false) - :CVP (true) - :ELA (false) - :LEA (false) - :OMI (false) - :RTM (false) - :SAM (false) - :UAC (false) - :UFP (false) - :color (black) - :comments () - :product_info ( - :AdminInfo ( - :chkpf_uid ("{CAC071E3-8788-4ACF-95F1-F9115142E871}") - :ClassName (OPSEC_product_info) - ) - :certification_info () - :certified (true) - :product (ESafe_Protect_Gateway) - :vendor (Aladdin_Knowledge_Systems) - :version (3.0) - ) - :type (OPSEC_product) - ) - : (Finjan_SurfinGate_5.6_NT - :AdminInfo ( - :chkpf_uid ("{581E4A3D-C37D-4C9F-8070-0E7BBFDED473}") - :ClassName (OPSEC_product) - :table (products) - :LastModified ( - :Time ("Sun Dec 30 11:36:41 2001") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :NT_commands () - :commands () - :solaris_commands () - :AMON (false) - :AMON_class_name (default_opsec_status_object) - :CPMI (false) - :CVP (true) - :ELA (false) - :LEA (false) - :OMI (false) - :RTM (false) - :SAM (false) - :UAC (false) - :UFP (false) - :color (black) - :comments () - :product_info ( - :AdminInfo ( - :chkpf_uid ("{3A847D56-AC20-438E-9EF1-B29045D58527}") - :ClassName (OPSEC_product_info) - ) - :certification_info () - :certified (true) - :product (SurfinGate) - :vendor (Finjan_Software) - :version (5.6) - ) - :type (OPSEC_product) - ) - : (TM_VirusWall_NT_3.5 - :AdminInfo ( - :chkpf_uid ("{28ED5FB8-B8BA-4623-943B-3764F248A55E}") - :ClassName (OPSEC_product) - :table (products) - :LastModified ( - :Time ("Sun Dec 30 11:36:41 2001") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :NT_commands () - :commands () - :solaris_commands () - :AMON (false) - :AMON_class_name (default_opsec_status_object) - :CPMI (false) - :CVP (true) - :ELA (false) - :LEA (false) - :OMI (false) - :RTM (false) - :SAM (false) - :UAC (false) - :UFP (false) - :color (black) - :comments () - :product_info ( - :AdminInfo ( - :chkpf_uid ("{59DD615D-4C31-4897-93E8-00466E9ED42F}") - :ClassName (OPSEC_product_info) - ) - :certification_info () - :certified (true) - :product (InterScan_VirusWall_for_NT) - :vendor (Trend_Micro) - :version (3.5) - ) - :type (OPSEC_product) - ) - : (TM_VirusWall_Solaris_3.6 - :AdminInfo ( - :chkpf_uid ("{80CDD43D-F7F8-475C-958D-D3CCF7BCEEFB}") - :ClassName (OPSEC_product) - :table (products) - :LastModified ( - :Time ("Sun Dec 30 11:36:41 2001") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :NT_commands () - :commands () - :solaris_commands () - :AMON (false) - :AMON_class_name (default_opsec_status_object) - :CPMI (false) - :CVP (true) - :ELA (false) - :LEA (false) - :OMI (false) - :RTM (false) - :SAM (false) - :UAC (false) - :UFP (false) - :color (black) - :comments () - :product_info ( - :AdminInfo ( - :chkpf_uid ("{1CB5277A-F5A4-4F8D-AC60-B6F3D67BAF3B}") - :ClassName (OPSEC_product_info) - ) - :certification_info () - :certified (true) - :product (InterScan_VirusWall_for_Solaris) - :vendor (Trend_Micro) - :version (3.6) - ) - :type (OPSEC_product) - ) - : (WebWasher_EE_Linux_3.1 - :AdminInfo ( - :chkpf_uid ("{B8954622-E780-46DB-8E0B-50DA720721E1}") - :ClassName (OPSEC_product) - :table (products) - :LastModified ( - :Time ("Sun Dec 30 11:36:41 2001") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :NT_commands () - :commands () - :solaris_commands () - :AMON (false) - :AMON_class_name (default_opsec_status_object) - :CPMI (false) - :CVP (true) - :ELA (false) - :LEA (false) - :OMI (false) - :RTM (false) - :SAM (false) - :UAC (false) - :UFP (true) - :color (black) - :comments () - :product_info ( - :AdminInfo ( - :chkpf_uid ("{F05C21CD-6929-425B-AEB0-5E6F97E8C0AE}") - :ClassName (OPSEC_product_info) - ) - :certification_info () - :certified (true) - :product (WebWasher_EE_Linux) - :vendor (WebWasher) - :version (3.1) - ) - :type (OPSEC_product) - ) - : (SecureWatch - :AdminInfo ( - :chkpf_uid ("{DF11985A-C890-48D3-ADE2-1F60A5DEEAC4}") - :ClassName (OPSEC_product) - :table (products) - :LastModified ( - :Time ("Sun Dec 30 11:36:41 2001") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :NT_commands () - :commands () - :solaris_commands () - :AMON (false) - :AMON_class_name (default_opsec_status_object) - :CPMI (false) - :CVP (false) - :ELA (true) - :LEA (false) - :OMI (false) - :RTM (false) - :SAM (false) - :UAC (false) - :UFP (false) - :color (black) - :comments () - :product_info ( - :AdminInfo ( - :chkpf_uid ("{B7CABFFA-EF0A-4C62-8878-3D27791B43AA}") - :ClassName (OPSEC_product_info) - ) - :certification_info () - :certified (true) - :product (SecureWatchfor_W2K) - :vendor (TopLayer_Networks) - :version (1.11) - ) - :type (OPSEC_product) - ) - : (Entercept_Integrator_1.03 - :AdminInfo ( - :chkpf_uid ("{05F22C3A-F03E-490A-BC64-DA2B88596D92}") - :ClassName (OPSEC_product) - :table (products) - :LastModified ( - :Time ("Sun Dec 30 11:36:42 2001") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :NT_commands () - :commands () - :solaris_commands () - :AMON (false) - :AMON_class_name (default_opsec_status_object) - :CPMI (false) - :CVP (false) - :ELA (true) - :LEA (false) - :OMI (false) - :RTM (false) - :SAM (false) - :UAC (false) - :UFP (false) - :color (black) - :comments () - :product_info ( - :AdminInfo ( - :chkpf_uid ("{2CBABE45-6A56-48FB-A844-3C86D4E4080F}") - :ClassName (OPSEC_product_info) - ) - :certification_info () - :certified (true) - :product (Integrator_for_Check_Point) - :vendor (Entercept_Security_Technologies) - :version (1.03) - ) - :type (OPSEC_product) - ) - : (VigilEnt_Security_Agent_for_FW1 - :AdminInfo ( - :chkpf_uid ("{EDA9A2A2-E238-44F0-8C4F-50FECB4245AA}") - :ClassName (OPSEC_product) - :table (products) - :LastModified ( - :Time ("Sun Dec 30 11:36:42 2001") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :NT_commands () - :commands () - :solaris_commands () - :AMON (false) - :AMON_class_name (default_opsec_status_object) - :CPMI (false) - :CVP (false) - :ELA (true) - :LEA (false) - :OMI (false) - :RTM (false) - :SAM (true) - :UAC (false) - :UFP (false) - :color (black) - :comments () - :product_info ( - :AdminInfo ( - :chkpf_uid ("{8F748A3B-A7D4-4D9B-9570-B8C7514B00F4}") - :ClassName (OPSEC_product_info) - ) - :certification_info () - :certified (true) - :product (VigilEnt_Security_Agent) - :vendor (PentaSafe_Security_Technologies) - :version (1.0) - ) - :type (OPSEC_product) - ) - : (SecoShield_2.0 - :AdminInfo ( - :chkpf_uid ("{8FCB396C-8F37-4AF1-A771-F79C20A734FC}") - :ClassName (OPSEC_product) - :table (products) - :LastModified ( - :Time ("Sun Dec 30 11:36:42 2001") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :NT_commands () - :commands () - :solaris_commands () - :AMON (false) - :AMON_class_name (default_opsec_status_object) - :CPMI (false) - :CVP (false) - :ELA (false) - :LEA (false) - :OMI (false) - :RTM (false) - :SAM (true) - :UAC (false) - :UFP (false) - :color (black) - :comments () - :product_info ( - :AdminInfo ( - :chkpf_uid ("{D23690F2-1004-4050-91C3-13684C56626F}") - :ClassName (OPSEC_product_info) - ) - :certification_info () - :certified (true) - :product (SecoShield_2.0) - :vendor (INFOSEC_Technologies) - :version (2.0) - ) - :type (OPSEC_product) - ) - : (N2H2_Filtering_FW1 - :AdminInfo ( - :chkpf_uid ("{6313C1EB-AEA2-4923-A310-E5E018D0CB0C}") - :ClassName (OPSEC_product) - :table (products) - :LastModified ( - :Time ("Sun Dec 30 11:36:42 2001") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :NT_commands () - :commands () - :solaris_commands () - :AMON (false) - :AMON_class_name (default_opsec_status_object) - :CPMI (false) - :CVP (false) - :ELA (false) - :LEA (false) - :OMI (false) - :RTM (false) - :SAM (false) - :UAC (false) - :UFP (true) - :color (black) - :comments () - :product_info ( - :AdminInfo ( - :chkpf_uid ("{D1D8E27B-6B13-4961-9F2B-0CB800AE04EB}") - :ClassName (OPSEC_product_info) - ) - :certification_info () - :certified (true) - :product (N2H2_Filtering_NT) - :vendor (N2H2) - :version (1.0) - ) - :type (OPSEC_product) - ) - : (SecureComputing_SmartFilter_2.1 - :AdminInfo ( - :chkpf_uid ("{406D3171-2CF2-4FFA-8C32-3A9DB53D0690}") - :ClassName (OPSEC_product) - :table (products) - :LastModified ( - :Time ("Sun Dec 30 11:36:43 2001") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :NT_commands () - :commands () - :solaris_commands () - :AMON (false) - :AMON_class_name (default_opsec_status_object) - :CPMI (false) - :CVP (false) - :ELA (false) - :LEA (false) - :OMI (false) - :RTM (false) - :SAM (false) - :UAC (false) - :UFP (true) - :color (black) - :comments () - :product_info ( - :AdminInfo ( - :chkpf_uid ("{7ED208A5-8DF4-47A0-A70A-E5DA135718D4}") - :ClassName (OPSEC_product_info) - ) - :certification_info () - :certified (true) - :product (Smart_Filter) - :vendor (Secure_Computing) - :version (2.1) - ) - :type (OPSEC_product) - ) - : (SurfControl_SuperScout_FW1_2.1 - :AdminInfo ( - :chkpf_uid ("{DFB6904F-584B-4FDC-9048-B6EFC2C47AD2}") - :ClassName (OPSEC_product) - :table (products) - :LastModified ( - :Time ("Sun Dec 30 11:36:43 2001") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :NT_commands () - :commands () - :solaris_commands () - :AMON (false) - :AMON_class_name (default_opsec_status_object) - :CPMI (false) - :CVP (false) - :ELA (false) - :LEA (false) - :OMI (false) - :RTM (false) - :SAM (false) - :UAC (false) - :UFP (true) - :color (black) - :comments () - :product_info ( - :AdminInfo ( - :chkpf_uid ("{77AE98F8-845F-4BE1-90F5-04A09C12040A}") - :ClassName (OPSEC_product_info) - ) - :certification_info () - :certified (true) - :product (SuperScout_for_FireWall) - :vendor (SurfControl) - :version (2.1) - ) - :type (OPSEC_product) - ) - : (WebSense_FW1_4.3 - :AdminInfo ( - :chkpf_uid ("{D2E3E730-EA2E-4A31-B689-436B5D0494DB}") - :ClassName (OPSEC_product) - :table (products) - :LastModified ( - :Time ("Sun Dec 30 11:36:43 2001") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :NT_commands () - :commands () - :solaris_commands () - :AMON (false) - :AMON_class_name (default_opsec_status_object) - :CPMI (false) - :CVP (false) - :ELA (false) - :LEA (false) - :OMI (false) - :RTM (false) - :SAM (false) - :UAC (false) - :UFP (true) - :color (black) - :comments () - :product_info ( - :AdminInfo ( - :chkpf_uid ("{A09058AD-B5A9-4E51-902D-18CCC8356D88}") - :ClassName (OPSEC_product_info) - ) - :certification_info () - :certified (true) - :product (WebSense_for_FireWall-1) - :vendor (WebSense) - :version (4.3) - ) - :type (OPSEC_product) - ) - : (OpenService_SystemWatch_2.63 - :AdminInfo ( - :chkpf_uid ("{C0BDCDCD-3FB6-4FA3-9156-A018891014E4}") - :ClassName (OPSEC_product) - :table (products) - :LastModified ( - :Time ("Sun Dec 30 11:36:43 2001") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :NT_commands () - :commands () - :solaris_commands () - :AMON (false) - :AMON_class_name (default_opsec_status_object) - :CPMI (false) - :CVP (false) - :ELA (false) - :LEA (true) - :OMI (false) - :RTM (false) - :SAM (false) - :UAC (false) - :UFP (false) - :color (black) - :comments () - :product_info ( - :AdminInfo ( - :chkpf_uid ("{0165BA91-6330-496C-A49A-CA8BE943069A}") - :ClassName (OPSEC_product_info) - ) - :certification_info () - :certified (true) - :product (SystemWatch) - :vendor (OpenService) - :version (2.63) - ) - :type (OPSEC_product) - ) - : (OpenSystems_Private_I_6420 - :AdminInfo ( - :chkpf_uid ("{73C6C1FF-5DFF-4F59-AB9D-8529A8C0F87F}") - :ClassName (OPSEC_product) - :table (products) - :LastModified ( - :Time ("Sun Dec 30 11:36:43 2001") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :NT_commands () - :commands () - :solaris_commands () - :AMON (false) - :AMON_class_name (default_opsec_status_object) - :CPMI (false) - :CVP (false) - :ELA (false) - :LEA (true) - :OMI (false) - :RTM (false) - :SAM (false) - :UAC (false) - :UFP (false) - :color (black) - :comments () - :product_info ( - :AdminInfo ( - :chkpf_uid ("{28BDF40C-8959-4DA1-B885-F4A2FBAD1AF8}") - :ClassName (OPSEC_product_info) - ) - :certification_info (NG-Compatible) - :certified (true) - :product (Private_I_Intelligence_Suite) - :vendor (OpenSystems.com) - :version (6420) - ) - :type (OPSEC_product) - ) - : (WebTrends_Firewall_3.0 - :AdminInfo ( - :chkpf_uid ("{518896A3-7E38-4FB6-9EEE-3FA990AC8763}") - :ClassName (OPSEC_product) - :table (products) - :LastModified ( - :Time ("Sun Dec 30 11:36:43 2001") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :NT_commands () - :commands () - :solaris_commands () - :AMON (false) - :AMON_class_name (default_opsec_status_object) - :CPMI (false) - :CVP (false) - :ELA (false) - :LEA (true) - :OMI (false) - :RTM (false) - :SAM (false) - :UAC (false) - :UFP (false) - :color (black) - :comments () - :product_info ( - :AdminInfo ( - :chkpf_uid ("{622728CE-F3A5-4242-B50A-641279B43867}") - :ClassName (OPSEC_product_info) - ) - :certification_info () - :certified (true) - :product (WebTrends_Firewall_Suite) - :vendor (NetIQ) - :version (3.0a) - ) - :type (OPSEC_product) - ) - : (G_Server_ELA_Module_1.51 - :AdminInfo ( - :chkpf_uid ("{F6EC787D-C321-41BC-BFF9-9DB0A5984472}") - :ClassName (OPSEC_product) - :table (products) - :LastModified ( - :Time ("Sun Dec 30 11:36:44 2001") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :NT_commands () - :commands () - :solaris_commands () - :AMON (false) - :AMON_class_name (default_opsec_status_object) - :CPMI (false) - :CVP (false) - :ELA (true) - :LEA (false) - :OMI (false) - :RTM (false) - :SAM (false) - :UAC (false) - :UFP (false) - :color (black) - :comments () - :product_info ( - :AdminInfo ( - :chkpf_uid ("{3645A004-C3C0-4804-800A-C31096DCB83A}") - :ClassName (OPSEC_product_info) - ) - :certification_info () - :certified (true) - :product (G_Server_Appliance) - :vendor (Gilian) - :version (1.51) - ) - :type (OPSEC_product) - ) - : (SPiDER-1_for_FireWall-1_1.5 - :AdminInfo ( - :chkpf_uid ("{7410F783-733E-47F3-BE86-F75762A013B1}") - :ClassName (OPSEC_product) - :table (products) - :LastModified ( - :Time ("Sun Dec 30 11:36:44 2001") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :NT_commands () - :commands () - :solaris_commands () - :AMON (false) - :AMON_class_name (default_opsec_status_object) - :CPMI (false) - :CVP (false) - :ELA (false) - :LEA (true) - :OMI (false) - :RTM (false) - :SAM (false) - :UAC (false) - :UFP (false) - :color (black) - :comments () - :product_info ( - :AdminInfo ( - :chkpf_uid ("{511EE6E0-062A-42AE-9BB5-8112C9A086B0}") - :ClassName (OPSEC_product_info) - ) - :certification_info () - :certified (true) - :product (SPiDER-1) - :vendor ("Igloo Security") - :version (1.5) - ) - :type (OPSEC_product) - ) - : (netForensics_agent_for_FireWall-1_2.3 - :AdminInfo ( - :chkpf_uid ("{1408C2EC-55E1-48E4-B30F-FA57B9A9A296}") - :ClassName (OPSEC_product) - :table (products) - :LastModified ( - :Time ("Sun Dec 30 11:36:44 2001") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :NT_commands () - :commands () - :solaris_commands () - :AMON (false) - :AMON_class_name (default_opsec_status_object) - :CPMI (false) - :CVP (false) - :ELA (false) - :LEA (true) - :OMI (false) - :RTM (false) - :SAM (false) - :UAC (false) - :UFP (false) - :color (black) - :comments () - :product_info ( - :AdminInfo ( - :chkpf_uid ("{4735633B-A973-4063-8275-2A368974FDF3}") - :ClassName (OPSEC_product_info) - ) - :certification_info () - :certified (true) - :product (netForensics) - :vendor (netForensics) - :version (2.3) - ) - :type (OPSEC_product) - ) - : (AppManager_for_FireWall-1 - :AdminInfo ( - :chkpf_uid ("{DB381B83-1437-49DF-9D31-FF09AA4C7AD3}") - :ClassName (OPSEC_product) - :table (products) - :LastModified ( - :Time ("Sun Dec 30 11:36:44 2001") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :NT_commands () - :commands () - :solaris_commands () - :AMON (false) - :AMON_class_name (default_opsec_status_object) - :CPMI (false) - :CVP (false) - :ELA (false) - :LEA (true) - :OMI (true) - :RTM (false) - :SAM (false) - :UAC (false) - :UFP (false) - :color (black) - :comments () - :product_info ( - :AdminInfo ( - :chkpf_uid ("{9398256E-B09C-4EC3-9058-7F224456D415}") - :ClassName (OPSEC_product_info) - ) - :certification_info () - :certified (true) - :product (NetIQ) - :vendor (NetIQ) - :version (1.0) - ) - :type (OPSEC_product) - ) - : (FireMon_1.0 - :AdminInfo ( - :chkpf_uid ("{EB771FBB-70FC-4F68-8152-D8B8460D5C6F}") - :ClassName (OPSEC_product) - :table (products) - :LastModified ( - :Time ("Sun Dec 30 11:36:44 2001") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :NT_commands () - :commands () - :solaris_commands () - :AMON (false) - :AMON_class_name (default_opsec_status_object) - :CPMI (false) - :CVP (false) - :ELA (false) - :LEA (false) - :OMI (true) - :RTM (false) - :SAM (false) - :UAC (false) - :UFP (false) - :color (black) - :comments () - :product_info ( - :AdminInfo ( - :chkpf_uid ("{35F9775B-3553-45EA-AD18-26771CF94F08}") - :ClassName (OPSEC_product_info) - ) - :certification_info () - :certified (true) - :product (FireMon) - :vendor ("FishNet Security") - :version (1.0) - ) - :type (OPSEC_product) - ) - : (Oblix_NetPoint_4.6 - :AdminInfo ( - :chkpf_uid ("{DFAB534E-6BC0-463D-B579-E69B5FC61240}") - :ClassName (OPSEC_product) - :table (products) - :LastModified ( - :Time ("Sun Dec 30 11:36:45 2001") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :NT_commands () - :commands () - :solaris_commands () - :AMON (false) - :AMON_class_name (default_opsec_status_object) - :CPMI (false) - :CVP (false) - :ELA (false) - :LEA (false) - :OMI (false) - :RTM (false) - :SAM (false) - :UAC (true) - :UFP (false) - :color (black) - :comments () - :product_info ( - :AdminInfo ( - :chkpf_uid ("{57410EA9-7C70-465B-A44C-99E03876E9F3}") - :ClassName (OPSEC_product_info) - ) - :certification_info () - :certified (true) - :product (NetPoint_Authentication_Adapter) - :vendor (Oblix) - :version (4.6) - ) - :type (OPSEC_product) - ) - : (Protegrity_Secure.Data_10.222.0.70 - :AdminInfo ( - :chkpf_uid ("{D8366FEB-B48F-47C6-99E8-15A2D9670F89}") - :ClassName (OPSEC_product) - :table (products) - :LastModified ( - :Time ("Sun Dec 30 11:36:45 2001") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :NT_commands () - :commands () - :solaris_commands () - :AMON (false) - :AMON_class_name (default_opsec_status_object) - :CPMI (false) - :CVP (false) - :ELA (false) - :LEA (false) - :OMI (false) - :RTM (false) - :SAM (false) - :UAC (true) - :UFP (false) - :color (black) - :comments () - :product_info ( - :AdminInfo ( - :chkpf_uid ("{C5059AA0-8F27-43FC-B430-23D47DB03218}") - :ClassName (OPSEC_product_info) - ) - :certification_info (NT-Version) - :certified (true) - :product (Secure.Data) - :vendor (Protegrity) - :version (10.222.0.70) - ) - :type (OPSEC_product) - ) - : (Protegrity_Secure.Data_10.222.0.71 - :AdminInfo ( - :chkpf_uid ("{4EE7B65C-3574-4EE6-A9F3-91602909F8C9}") - :ClassName (OPSEC_product) - :table (products) - :LastModified ( - :Time ("Sun Dec 30 11:36:45 2001") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :NT_commands () - :commands () - :solaris_commands () - :AMON (false) - :AMON_class_name (default_opsec_status_object) - :CPMI (false) - :CVP (false) - :ELA (false) - :LEA (false) - :OMI (false) - :RTM (false) - :SAM (false) - :UAC (true) - :UFP (false) - :color (black) - :comments () - :product_info ( - :AdminInfo ( - :chkpf_uid ("{E6998505-4126-4A3E-AC5C-297804808410}") - :ClassName (OPSEC_product_info) - ) - :certification_info (Solaris-Version) - :certified (true) - :product (Secure.Data) - :vendor (Protegrity) - :version (10.222.0.71) - ) - :type (OPSEC_product) - ) - : (ACESwitch_ACEDirector - :AdminInfo ( - :chkpf_uid ("{811545CB-804A-4BA7-942B-75211682D4C3}") - :ClassName (OPSEC_product) - :table (products) - :LastModified ( - :Time ("Sun Dec 30 11:36:45 2001") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :NT_commands () - :commands () - :solaris_commands () - :AMON (false) - :AMON_class_name (default_opsec_status_object) - :CPMI (false) - :CVP (false) - :ELA (true) - :LEA (false) - :OMI (false) - :RTM (false) - :SAM (false) - :UAC (false) - :UFP (false) - :color (black) - :comments () - :product_info ( - :AdminInfo ( - :chkpf_uid ("{6242753E-9464-47E6-A05E-4A9980A60EFA}") - :ClassName (OPSEC_product_info) - ) - :certification_info () - :certified (true) - :product ("ACESwitch & ACEDirector") - :vendor (Nortel) - :version ("Web OS 8.3 (firmware)") - ) - :type (OPSEC_product) - ) - : (Internet_Ironware - :AdminInfo ( - :chkpf_uid ("{3229CD03-370D-4C91-B6E7-74534768EEB9}") - :ClassName (OPSEC_product) - :table (products) - :LastModified ( - :Time ("Sun Dec 30 11:36:45 2001") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :NT_commands () - :commands () - :solaris_commands () - :AMON (false) - :AMON_class_name (default_opsec_status_object) - :CPMI (false) - :CVP (false) - :ELA (true) - :LEA (false) - :OMI (false) - :RTM (false) - :SAM (false) - :UAC (false) - :UFP (false) - :color (black) - :comments () - :product_info ( - :AdminInfo ( - :chkpf_uid ("{B5EEB358-4DE3-4DAB-B4EF-BC63ED1D8931}") - :ClassName (OPSEC_product_info) - ) - :certification_info (4.1) - :certified (true) - :product (ServerIron) - :vendor ("Foundry Networks") - :version ("7.1 (firmware)") - ) - :type (OPSEC_product) - ) - : (FireProof_2.0 - :AdminInfo ( - :chkpf_uid ("{5350D161-61B1-4343-A938-34D2CDD80EEB}") - :ClassName (OPSEC_product) - :table (products) - :LastModified ( - :Time ("Sun Dec 30 11:36:45 2001") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :NT_commands () - :commands () - :solaris_commands () - :AMON (false) - :AMON_class_name (default_opsec_status_object) - :CPMI (false) - :CVP (false) - :ELA (true) - :LEA (false) - :OMI (false) - :RTM (false) - :SAM (false) - :UAC (false) - :UFP (false) - :color (black) - :comments () - :product_info ( - :AdminInfo ( - :chkpf_uid ("{F6B045C9-A796-48D7-B749-95DB577E3D9A}") - :ClassName (OPSEC_product_info) - ) - :certification_info (4.1) - :certified (true) - :product (FireProof) - :vendor (Radware) - :version (2.0) - ) - :type (OPSEC_product) - ) - : (FireProof_2.3 - :AdminInfo ( - :chkpf_uid ("{504E8A0D-2F89-471C-9F66-F32547CBE3F7}") - :ClassName (OPSEC_product) - :table (products) - :LastModified ( - :Time ("Sun Dec 30 11:36:46 2001") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :NT_commands () - :commands () - :solaris_commands () - :AMON (false) - :AMON_class_name (default_opsec_status_object) - :CPMI (false) - :CVP (false) - :ELA (true) - :LEA (false) - :OMI (false) - :RTM (false) - :SAM (false) - :UAC (false) - :UFP (false) - :color (black) - :comments () - :product_info ( - :AdminInfo ( - :chkpf_uid ("{06B4CA81-C14B-4C05-ACFB-A50CB599BF79}") - :ClassName (OPSEC_product_info) - ) - :certification_info (NG) - :certified (true) - :product (FireProof) - :vendor (Radware) - :version (2.3) - ) - :type (OPSEC_product) - ) - : (Rainwall_E_1.6 - :AdminInfo ( - :chkpf_uid ("{E8AE9F2F-5613-4B88-B376-F8FFCE0EF08B}") - :ClassName (OPSEC_product) - :table (products) - :LastModified ( - :Time ("Sun Dec 30 11:36:46 2001") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :NT_commands () - :commands () - :solaris_commands () - :AMON (false) - :AMON_class_name (default_opsec_status_object) - :CPMI (false) - :CVP (false) - :ELA (true) - :LEA (false) - :OMI (false) - :RTM (false) - :SAM (false) - :UAC (false) - :UFP (false) - :color (black) - :comments () - :product_info ( - :AdminInfo ( - :chkpf_uid ("{76587B88-1D16-405B-B28F-16E74B8968C8}") - :ClassName (OPSEC_product_info) - ) - :certification_info ("NG - Solaris") - :certified (true) - :product ("Rainwall E") - :vendor (Rainfinity) - :version (1.6) - ) - :type (OPSEC_product) - ) - : (Rainwall_E_1.5.1B30 - :AdminInfo ( - :chkpf_uid ("{731F7841-A16A-4221-BB44-DDDC9E64432F}") - :ClassName (OPSEC_product) - :table (products) - :LastModified ( - :Time ("Sun Dec 30 11:36:46 2001") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :NT_commands () - :commands () - :solaris_commands () - :AMON (false) - :AMON_class_name (default_opsec_status_object) - :CPMI (false) - :CVP (false) - :ELA (true) - :LEA (false) - :OMI (false) - :RTM (false) - :SAM (false) - :UAC (false) - :UFP (false) - :color (black) - :comments () - :product_info ( - :AdminInfo ( - :chkpf_uid ("{2311F091-0329-406B-BE92-93F13AC351DD}") - :ClassName (OPSEC_product_info) - ) - :certification_info ("4.1 - Solaris") - :certified (true) - :product ("Rainwall E") - :vendor (Rainfinity) - :version ("1.5.1 bld_30") - ) - :type (OPSEC_product) - ) - : (Rainwall_E_1.5SP3 - :AdminInfo ( - :chkpf_uid ("{FBEA2DB3-5FA0-4E09-96A8-150F404B52D9}") - :ClassName (OPSEC_product) - :table (products) - :LastModified ( - :Time ("Sun Dec 30 11:36:46 2001") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :NT_commands () - :commands () - :solaris_commands () - :AMON (false) - :AMON_class_name (default_opsec_status_object) - :CPMI (false) - :CVP (false) - :ELA (true) - :LEA (false) - :OMI (false) - :RTM (false) - :SAM (false) - :UAC (false) - :UFP (false) - :color (black) - :comments () - :product_info ( - :AdminInfo ( - :chkpf_uid ("{78D963B6-0668-4159-BB1F-ACC287C55949}") - :ClassName (OPSEC_product_info) - ) - :certification_info ("4.1 - Linux") - :certified (true) - :product ("Rainwall E") - :vendor (Rainfinity) - :version ("1.5 SP3") - ) - :type (OPSEC_product) - ) - : (StoneBeat_FullCluster_1.0SP4 - :AdminInfo ( - :chkpf_uid ("{3FA44973-4658-459A-8665-234474316BF9}") - :ClassName (OPSEC_product) - :table (products) - :LastModified ( - :Time ("Sun Dec 30 11:36:46 2001") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :NT_commands () - :commands () - :solaris_commands () - :AMON (false) - :AMON_class_name (default_opsec_status_object) - :CPMI (false) - :CVP (false) - :ELA (true) - :LEA (false) - :OMI (false) - :RTM (false) - :SAM (false) - :UAC (false) - :UFP (false) - :color (black) - :comments () - :product_info ( - :AdminInfo ( - :chkpf_uid ("{B8A93E68-E662-4FD1-BA90-098D50FC3131}") - :ClassName (OPSEC_product_info) - ) - :certification_info ("4.1 - NT") - :certified (true) - :product ("StoneBeat FullCluster") - :vendor (StoneSoft) - :version ("1.0 SP4") - ) - :type (OPSEC_product) - ) - : (StoneBeat_FullCluster_2.0SP1a - :AdminInfo ( - :chkpf_uid ("{9034BDEC-687B-4EF4-8BAB-CAA1A68CD94C}") - :ClassName (OPSEC_product) - :table (products) - :LastModified ( - :Time ("Sun Dec 30 11:36:47 2001") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :NT_commands () - :commands () - :solaris_commands () - :AMON (false) - :AMON_class_name (default_opsec_status_object) - :CPMI (false) - :CVP (false) - :ELA (true) - :LEA (false) - :OMI (false) - :RTM (false) - :SAM (false) - :UAC (false) - :UFP (false) - :color (black) - :comments () - :product_info ( - :AdminInfo ( - :chkpf_uid ("{EB1EC9B3-2391-43F8-A82B-5E348A860A36}") - :ClassName (OPSEC_product_info) - ) - :certification_info ("4.1 - Solaris") - :certified (true) - :product ("StoneBeat FullCluster") - :vendor (StoneSoft) - :version ("2.0 SP1a") - ) - :type (OPSEC_product) - ) - : (StoneBeat_FullCluster_2.0SP3a - :AdminInfo ( - :chkpf_uid ("{2AA5E5B8-1A6F-48FA-887E-89FA4F415013}") - :ClassName (OPSEC_product) - :table (products) - :LastModified ( - :Time ("Sun Dec 30 11:36:47 2001") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :NT_commands () - :commands () - :solaris_commands () - :AMON (false) - :AMON_class_name (default_opsec_status_object) - :CPMI (false) - :CVP (false) - :ELA (true) - :LEA (false) - :OMI (false) - :RTM (false) - :SAM (false) - :UAC (false) - :UFP (false) - :color (black) - :comments () - :product_info ( - :AdminInfo ( - :chkpf_uid ("{25E4373E-366C-403F-BE37-A9966E229B4A}") - :ClassName (OPSEC_product_info) - ) - :certification_info ("4.1 - Linux") - :certified (true) - :product ("StoneBeat FullCluster") - :vendor (StoneSoft) - :version ("2.0 SP3a") - ) - :type (OPSEC_product) - ) - : (Cluster_Module - :AdminInfo ( - :chkpf_uid ("{35B03287-3CFE-490D-AF3F-021C81290C0F}") - :ClassName (OPSEC_product) - :table (products) - :LastModified ( - :Time ("Sun Dec 30 11:36:47 2001") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :NT_commands () - :commands () - :solaris_commands () - :AMON (false) - :AMON_class_name (default_opsec_status_object) - :CPMI (false) - :CVP (false) - :ELA (true) - :LEA (false) - :OMI (false) - :RTM (false) - :SAM (false) - :UAC (false) - :UFP (false) - :color (black) - :comments () - :product_info ( - :AdminInfo ( - :chkpf_uid ("{5351C8A6-729A-4218-88C3-71F8DFFD3BD9}") - :ClassName (OPSEC_product_info) - ) - :certification_info ("4.1 - Solaris") - :certified (true) - :product ("Cluster Module") - :vendor (Legato) - :version (4.5.1) - ) - :type (OPSEC_product) - ) - : (Rainwall_S_1.5SP3 - :AdminInfo ( - :chkpf_uid ("{5669559C-9DDE-47A6-8B7C-2C25B7AF1369}") - :ClassName (OPSEC_product) - :table (products) - :LastModified ( - :Time ("Sun Dec 30 11:36:47 2001") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :NT_commands () - :commands () - :solaris_commands () - :AMON (false) - :AMON_class_name (default_opsec_status_object) - :CPMI (false) - :CVP (false) - :ELA (true) - :LEA (false) - :OMI (false) - :RTM (false) - :SAM (false) - :UAC (false) - :UFP (false) - :color (black) - :comments () - :product_info ( - :AdminInfo ( - :chkpf_uid ("{FAA94964-72A8-4A07-8CBF-36BEB80567A5}") - :ClassName (OPSEC_product_info) - ) - :certification_info ("4.1 - Linux") - :certified (true) - :product ("Rainwall S") - :vendor (Rainfinity) - :version ("1.5 SP3") - ) - :type (OPSEC_product) - ) - : (Rainwall_S_1.6 - :AdminInfo ( - :chkpf_uid ("{E7805555-6AC4-415A-A52C-5136CD615825}") - :ClassName (OPSEC_product) - :table (products) - :LastModified ( - :Time ("Sun Dec 30 11:36:47 2001") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :NT_commands () - :commands () - :solaris_commands () - :AMON (false) - :AMON_class_name (default_opsec_status_object) - :CPMI (false) - :CVP (false) - :ELA (true) - :LEA (false) - :OMI (false) - :RTM (false) - :SAM (false) - :UAC (false) - :UFP (false) - :color (black) - :comments () - :product_info ( - :AdminInfo ( - :chkpf_uid ("{62B33292-8DEA-4E1A-B00D-B2E8256454EA}") - :ClassName (OPSEC_product_info) - ) - :certification_info ("4.1 - Solaris") - :certified (true) - :product ("Rainwall S") - :vendor (Rainfinity) - :version ("1.6 (B17)") - ) - :type (OPSEC_product) - ) - : (StoneBeat_3.1.5 - :AdminInfo ( - :chkpf_uid ("{A3D052A0-6B29-4F16-84AC-FAEF14EE3032}") - :ClassName (OPSEC_product) - :table (products) - :LastModified ( - :Time ("Sun Dec 30 11:36:47 2001") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :NT_commands () - :commands () - :solaris_commands () - :AMON (false) - :AMON_class_name (default_opsec_status_object) - :CPMI (false) - :CVP (false) - :ELA (true) - :LEA (false) - :OMI (false) - :RTM (false) - :SAM (false) - :UAC (false) - :UFP (false) - :color (black) - :comments () - :product_info ( - :AdminInfo ( - :chkpf_uid ("{E15026F1-B13D-4AC0-818E-D2647B9990E1}") - :ClassName (OPSEC_product_info) - ) - :certification_info (4.1) - :certified (true) - :product (StoneBeat) - :vendor (StoneSoft) - :version (3.1.5) - ) - :type (OPSEC_product) - ) - : (Enterprise_Agent_for_CP_FW-1 - :AdminInfo ( - :chkpf_uid ("{20299E8D-B931-4419-BAC7-0C24CC4EFF8F}") - :ClassName (OPSEC_product) - :table (products) - :LastModified ( - :Time ("Sun Dec 30 11:36:48 2001") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :NT_commands () - :commands () - :solaris_commands () - :AMON (false) - :AMON_class_name (default_opsec_status_object) - :CPMI (false) - :CVP (false) - :ELA (true) - :LEA (false) - :OMI (false) - :RTM (false) - :SAM (false) - :UAC (false) - :UFP (false) - :color (black) - :comments () - :product_info ( - :AdminInfo ( - :chkpf_uid ("{3E4FB236-21BF-495E-A34F-F88E23F5E5C9}") - :ClassName (OPSEC_product_info) - ) - :certification_info (4.1) - :certified (true) - :product ("Enterprise Agent for CP FW-1") - :vendor ("Veritas Software Corp") - :version (1.3) - ) - :type (OPSEC_product) - ) - : (UserDefinedProduct - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB58D-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (OPSEC_product) - :table (products) - ) - :NT_commands () - :commands () - :solaris_commands () - :AMON (false) - :AMON_class_name (default_opsec_status_object) - :CPMI (false) - :CVP (false) - :ELA (false) - :LEA (false) - :OMI (false) - :RTM (false) - :SAM (false) - :UAC (false) - :UFP (false) - :color (black) - :comments () - :product_info ( - :AdminInfo ( - :chkpf_uid ("{97AEB58E-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (OPSEC_product_info) - ) - :certification_info () - :certified (false) - :product () - :vendor ("User defined") - :version () - ) - :type (OPSEC_product) - ) - : (Aladdin_ESafe_Gateway_2.1 - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB590-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (OPSEC_product) - :table (products) - ) - :NT_commands () - :commands () - :solaris_commands () - :AMON (false) - :AMON_class_name (default_opsec_status_object) - :CPMI (false) - :CVP (true) - :ELA (false) - :LEA (false) - :OMI (false) - :RTM (false) - :SAM (false) - :UAC (false) - :UFP (false) - :color (black) - :comments () - :product_info ( - :AdminInfo ( - :chkpf_uid ("{97AEB591-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (OPSEC_product_info) - ) - :certification_info () - :certified (true) - :product (ESafe_Protect_Gateway) - :vendor (Aladdin_Knowledge_Systems) - :version (2.1) - ) - :type (OPSEC_product) - ) - : (Aliroo_PrivaWall_1.1 - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB593-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (OPSEC_product) - :table (products) - ) - :NT_commands () - :commands () - :solaris_commands () - :AMON (false) - :AMON_class_name (default_opsec_status_object) - :CPMI (false) - :CVP (true) - :ELA (false) - :LEA (false) - :OMI (false) - :RTM (false) - :SAM (false) - :UAC (false) - :UFP (false) - :color (black) - :comments () - :product_info ( - :AdminInfo ( - :chkpf_uid ("{97AEB594-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (OPSEC_product_info) - ) - :certification_info () - :certified (true) - :product (PrivaWALL) - :vendor (Aliroo) - :version (1.1) - ) - :type (OPSEC_product) - ) - : (CA_SafeGate_2.2 - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB596-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (OPSEC_product) - :table (products) - ) - :NT_commands () - :commands () - :solaris_commands () - :AMON (false) - :AMON_class_name (default_opsec_status_object) - :CPMI (false) - :CVP (true) - :ELA (false) - :LEA (false) - :OMI (false) - :RTM (false) - :SAM (false) - :UAC (false) - :UFP (false) - :color (black) - :comments () - :product_info ( - :AdminInfo ( - :chkpf_uid ("{97AEB597-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (OPSEC_product_info) - ) - :certification_info () - :certified (true) - :product (SafeGate) - :vendor (Computer_Associates) - :version (2.2) - ) - :type (OPSEC_product) - ) - : (Finjan_SurfinGate_4.03_NT - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB599-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (OPSEC_product) - :table (products) - ) - :NT_commands () - :commands () - :solaris_commands () - :AMON (false) - :AMON_class_name (default_opsec_status_object) - :CPMI (false) - :CVP (true) - :ELA (false) - :LEA (false) - :OMI (false) - :RTM (false) - :SAM (false) - :UAC (false) - :UFP (false) - :color (black) - :comments () - :product_info ( - :AdminInfo ( - :chkpf_uid ("{97AEB59A-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (OPSEC_product_info) - ) - :certification_info () - :certified (true) - :product (SurfinGate) - :vendor (Finjan_Software) - :version (4.03) - ) - :type (OPSEC_product) - ) - : (FSecure_AV_FireWall_4.01 - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB59C-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (OPSEC_product) - :table (products) - ) - :NT_commands () - :commands () - :solaris_commands () - :AMON (false) - :AMON_class_name (default_opsec_status_object) - :CPMI (false) - :CVP (true) - :ELA (false) - :LEA (false) - :OMI (false) - :RTM (false) - :SAM (false) - :UAC (false) - :UFP (false) - :color (black) - :comments () - :product_info ( - :AdminInfo ( - :chkpf_uid ("{97AEB59D-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (OPSEC_product_info) - ) - :certification_info () - :certified (true) - :product (Anti_Virus_For_FireWall) - :vendor (F-Secure) - :version (4.01) - ) - :type (OPSEC_product) - ) - : (TM_AppletTrap_2.0 - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB59F-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (OPSEC_product) - :table (products) - ) - :NT_commands () - :commands () - :solaris_commands () - :AMON (false) - :AMON_class_name (default_opsec_status_object) - :CPMI (false) - :CVP (true) - :ELA (false) - :LEA (false) - :OMI (false) - :RTM (false) - :SAM (false) - :UAC (false) - :UFP (false) - :color (black) - :comments () - :product_info ( - :AdminInfo ( - :chkpf_uid ("{97AEB5A0-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (OPSEC_product_info) - ) - :certification_info () - :certified (true) - :product (InterScan_AppletTrap) - :vendor (Trend_Micro) - :version (2.0) - ) - :type (OPSEC_product) - ) - : (TM_VirusWall_FTP_3.5 - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB5A2-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (OPSEC_product) - :table (products) - ) - :NT_commands () - :commands () - :solaris_commands () - :AMON (false) - :AMON_class_name (default_opsec_status_object) - :CPMI (false) - :CVP (true) - :ELA (false) - :LEA (false) - :OMI (false) - :RTM (false) - :SAM (false) - :UAC (false) - :UFP (false) - :color (black) - :comments () - :product_info ( - :AdminInfo ( - :chkpf_uid ("{97AEB5A3-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (OPSEC_product_info) - ) - :certification_info () - :certified (true) - :product (InterScan_VirusWall_for_FTP) - :vendor (Trend_Micro) - :version (3.5) - ) - :type (OPSEC_product) - ) - : (TM_VirusWall_HTTP_3.5 - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB5A5-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (OPSEC_product) - :table (products) - ) - :NT_commands () - :commands () - :solaris_commands () - :AMON (false) - :AMON_class_name (default_opsec_status_object) - :CPMI (false) - :CVP (true) - :ELA (false) - :LEA (false) - :OMI (false) - :RTM (false) - :SAM (false) - :UAC (false) - :UFP (false) - :color (black) - :comments () - :product_info ( - :AdminInfo ( - :chkpf_uid ("{97AEB5A6-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (OPSEC_product_info) - ) - :certification_info () - :certified (true) - :product (InterScan_VirusWall_for_HTTP) - :vendor (Trend_Micro) - :version (3.5) - ) - :type (OPSEC_product) - ) - : (TM_VirusWall_SMTP_3.5 - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB5A8-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (OPSEC_product) - :table (products) - ) - :NT_commands () - :commands () - :solaris_commands () - :AMON (false) - :AMON_class_name (default_opsec_status_object) - :CPMI (false) - :CVP (true) - :ELA (false) - :LEA (false) - :OMI (false) - :RTM (false) - :SAM (false) - :UAC (false) - :UFP (false) - :color (black) - :comments () - :product_info ( - :AdminInfo ( - :chkpf_uid ("{97AEB5A9-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (OPSEC_product_info) - ) - :certification_info () - :certified (true) - :product (InterScan_VirusWall_for_SMTP) - :vendor (Trend_Micro) - :version (3.5) - ) - :type (OPSEC_product) - ) - : (CPRS_NS_5.0 - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB5AB-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (OPSEC_product) - :table (products) - ) - :NT_commands () - :commands () - :solaris_commands () - :AMON (false) - :AMON_class_name (default_opsec_status_object) - :CPMI (false) - :CVP (false) - :ELA (false) - :LEA (false) - :OMI (false) - :RTM (false) - :SAM (true) - :UAC (false) - :UFP (false) - :color (black) - :comments () - :product_info ( - :AdminInfo ( - :chkpf_uid ("{97AEB5AC-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (OPSEC_product_info) - ) - :certification_info () - :certified (true) - :product (Real_Secure_Network_Sensor) - :vendor (Check_Point) - :version (5.0) - ) - :type (OPSEC_product) - ) - : (CPRSM_5.0 - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB5AE-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (OPSEC_product) - :table (products) - ) - :NT_commands () - :commands () - :solaris_commands () - :AMON (false) - :AMON_class_name (default_opsec_status_object) - :CPMI (false) - :CVP (false) - :ELA (true) - :LEA (false) - :OMI (true) - :RTM (false) - :SAM (true) - :UAC (false) - :UFP (false) - :color (black) - :comments () - :product_info ( - :AdminInfo ( - :chkpf_uid ("{97AEB5AF-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (OPSEC_product_info) - ) - :certification_info () - :certified (true) - :product (Real_Secure_Manager) - :vendor (Check_Point) - :version (5.0) - ) - :type (OPSEC_product) - ) - : (CA_SessionWall3_1.4 - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB5B1-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (OPSEC_product) - :table (products) - ) - :NT_commands () - :commands () - :solaris_commands () - :AMON (false) - :AMON_class_name (default_opsec_status_object) - :CPMI (false) - :CVP (false) - :ELA (true) - :LEA (false) - :OMI (false) - :RTM (false) - :SAM (true) - :UAC (false) - :UFP (false) - :color (black) - :comments () - :product_info ( - :AdminInfo ( - :chkpf_uid ("{97AEB5B2-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (OPSEC_product_info) - ) - :certification_info () - :certified (true) - :product (SessionWall_3) - :vendor (Computer_Associates) - :version (1.4) - ) - :type (OPSEC_product) - ) - : (Securant_ClearTrust_SecureDetector_4.5 - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB5B4-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (OPSEC_product) - :table (products) - ) - :NT_commands () - :commands () - :solaris_commands () - :AMON (false) - :AMON_class_name (default_opsec_status_object) - :CPMI (false) - :CVP (false) - :ELA (false) - :LEA (false) - :OMI (false) - :RTM (false) - :SAM (true) - :UAC (false) - :UFP (false) - :color (black) - :comments () - :product_info ( - :AdminInfo ( - :chkpf_uid ("{97AEB5B5-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (OPSEC_product_info) - ) - :certification_info () - :certified (true) - :product (ClearTrust_SecureDetector) - :vendor (Securant_Technologies) - :version (4.5) - ) - :type (OPSEC_product) - ) - : (8e6_XStop_FW1_1.0 - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB5B7-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (OPSEC_product) - :table (products) - ) - :NT_commands () - :commands () - :solaris_commands () - :AMON (false) - :AMON_class_name (default_opsec_status_object) - :CPMI (false) - :CVP (false) - :ELA (false) - :LEA (false) - :OMI (false) - :RTM (false) - :SAM (false) - :UAC (false) - :UFP (true) - :color (black) - :comments () - :product_info ( - :AdminInfo ( - :chkpf_uid ("{97AEB5B8-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (OPSEC_product_info) - ) - :certification_info () - :certified (true) - :product (X-Stop_For_FireWall-1) - :vendor (8e6_Technologies) - :version (1.0) - ) - :type (OPSEC_product) - ) - : (SecureComputing_SmartFilter_1.0 - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB5BA-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (OPSEC_product) - :table (products) - ) - :NT_commands () - :commands () - :solaris_commands () - :AMON (false) - :AMON_class_name (default_opsec_status_object) - :CPMI (false) - :CVP (false) - :ELA (false) - :LEA (false) - :OMI (false) - :RTM (false) - :SAM (false) - :UAC (false) - :UFP (true) - :color (black) - :comments () - :product_info ( - :AdminInfo ( - :chkpf_uid ("{97AEB5BB-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (OPSEC_product_info) - ) - :certification_info () - :certified (true) - :product (Smart_Filter) - :vendor (Secure_Computing) - :version (1.0) - ) - :type (OPSEC_product) - ) - : (SurfControl_SuperScout_FW1_2.0 - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB5BD-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (OPSEC_product) - :table (products) - ) - :NT_commands () - :commands () - :solaris_commands () - :AMON (false) - :AMON_class_name (default_opsec_status_object) - :CPMI (false) - :CVP (false) - :ELA (false) - :LEA (false) - :OMI (false) - :RTM (false) - :SAM (false) - :UAC (false) - :UFP (true) - :color (black) - :comments () - :product_info ( - :AdminInfo ( - :chkpf_uid ("{97AEB5BE-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (OPSEC_product_info) - ) - :certification_info () - :certified (true) - :product (SuperScout_for_FireWall-1) - :vendor (SurfControl) - :version (2.0) - ) - :type (OPSEC_product) - ) - : (Symantec_IGear_FW1_3.02 - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB5C0-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (OPSEC_product) - :table (products) - ) - :NT_commands () - :commands () - :solaris_commands () - :AMON (false) - :AMON_class_name (default_opsec_status_object) - :CPMI (false) - :CVP (false) - :ELA (false) - :LEA (false) - :OMI (false) - :RTM (false) - :SAM (false) - :UAC (false) - :UFP (true) - :color (black) - :comments () - :product_info ( - :AdminInfo ( - :chkpf_uid ("{97AEB5C1-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (OPSEC_product_info) - ) - :certification_info () - :certified (true) - :product (I-Gear_for_FireWall-1) - :vendor (Symantec) - :version (3.02) - ) - :type (OPSEC_product) - ) - : (WebSense_FW1_4.24 - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB5C3-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (OPSEC_product) - :table (products) - ) - :NT_commands () - :commands () - :solaris_commands () - :AMON (false) - :AMON_class_name (default_opsec_status_object) - :CPMI (false) - :CVP (false) - :ELA (false) - :LEA (false) - :OMI (false) - :RTM (false) - :SAM (false) - :UAC (false) - :UFP (true) - :color (black) - :comments () - :product_info ( - :AdminInfo ( - :chkpf_uid ("{97AEB5C4-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (OPSEC_product_info) - ) - :certification_info () - :certified (true) - :product (WebSense_for_FireWall-1) - :vendor (WebSense) - :version (4.24) - ) - :type (OPSEC_product) - ) - : (BMC_Patrol_FW_1.1 - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB5C6-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (OPSEC_product) - :table (products) - ) - :NT_commands () - :commands () - :solaris_commands () - :AMON (false) - :AMON_class_name (default_opsec_status_object) - :CPMI (false) - :CVP (false) - :ELA (false) - :LEA (true) - :OMI (false) - :RTM (false) - :SAM (false) - :UAC (false) - :UFP (false) - :color (black) - :comments () - :product_info ( - :AdminInfo ( - :chkpf_uid ("{97AEB5C7-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (OPSEC_product_info) - ) - :certification_info () - :certified (true) - :product (Patrol_for_Firewalls) - :vendor (BMC_Software) - :version (1.1) - ) - :type (OPSEC_product) - ) - : (BusinessLayers_eProvisionDayOne_1.1 - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB5C9-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (OPSEC_product) - :table (products) - ) - :NT_commands () - :commands () - :solaris_commands () - :AMON (false) - :AMON_class_name (default_opsec_status_object) - :CPMI (false) - :CVP (false) - :ELA (true) - :LEA (false) - :OMI (false) - :RTM (false) - :SAM (false) - :UAC (false) - :UFP (false) - :color (black) - :comments () - :product_info ( - :AdminInfo ( - :chkpf_uid ("{97AEB5CA-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (OPSEC_product_info) - ) - :certification_info () - :certified (true) - :product (eProvision_Day_One) - :vendor (Business_Layers) - :version (1.1) - ) - :type (OPSEC_product) - ) - : (Micromuse_Netcool_FW1_1.0 - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB5CC-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (OPSEC_product) - :table (products) - ) - :NT_commands () - :commands () - :solaris_commands () - :AMON (false) - :AMON_class_name (default_opsec_status_object) - :CPMI (false) - :CVP (false) - :ELA (true) - :LEA (true) - :OMI (false) - :RTM (false) - :SAM (true) - :UAC (false) - :UFP (false) - :color (black) - :comments () - :product_info ( - :AdminInfo ( - :chkpf_uid ("{97AEB5CD-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (OPSEC_product_info) - ) - :certification_info () - :certified (true) - :product (NetCool_for_FireWall-1) - :vendor (Micromuse) - :version (1.0) - ) - :type (OPSEC_product) - ) - : (OpenService_System_Watch_2.5 - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB5CF-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (OPSEC_product) - :table (products) - ) - :NT_commands () - :commands () - :solaris_commands () - :AMON (false) - :AMON_class_name (default_opsec_status_object) - :CPMI (false) - :CVP (false) - :ELA (false) - :LEA (true) - :OMI (false) - :RTM (false) - :SAM (false) - :UAC (false) - :UFP (false) - :color (black) - :comments () - :product_info ( - :AdminInfo ( - :chkpf_uid ("{97AEB5D0-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (OPSEC_product_info) - ) - :certification_info () - :certified (true) - :product (SystemWatch) - :vendor (OpenService) - :version (2.5) - ) - :type (OPSEC_product) - ) - : (ProactiveNet_Intelliscope_3.6 - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB5D2-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (OPSEC_product) - :table (products) - ) - :NT_commands () - :commands () - :solaris_commands () - :AMON (false) - :AMON_class_name (default_opsec_status_object) - :CPMI (false) - :CVP (false) - :ELA (false) - :LEA (true) - :OMI (false) - :RTM (false) - :SAM (false) - :UAC (false) - :UFP (false) - :color (black) - :comments () - :product_info ( - :AdminInfo ( - :chkpf_uid ("{97AEB5D3-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (OPSEC_product_info) - ) - :certification_info () - :certified (true) - :product (Intelliscope) - :vendor (ProactiveNet) - :version (3.6) - ) - :type (OPSEC_product) - ) - : (CP_Reporting_4.1 - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB5D5-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (OPSEC_product) - :table (products) - ) - :NT_commands () - :commands () - :solaris_commands () - :AMON (false) - :AMON_class_name (default_opsec_status_object) - :CPMI (false) - :CVP (false) - :ELA (false) - :LEA (true) - :OMI (true) - :RTM (false) - :SAM (false) - :UAC (false) - :UFP (false) - :color (black) - :comments () - :product_info ( - :AdminInfo ( - :chkpf_uid ("{97AEB5D6-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (OPSEC_product_info) - ) - :certification_info () - :certified (true) - :product (Reporting_Module) - :vendor (Check_Point) - :version (4.1) - ) - :type (OPSEC_product) - ) - : (OpenSystems_PrivateI_6.1 - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB5D8-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (OPSEC_product) - :table (products) - ) - :NT_commands () - :commands () - :solaris_commands () - :AMON (false) - :AMON_class_name (default_opsec_status_object) - :CPMI (false) - :CVP (false) - :ELA (false) - :LEA (true) - :OMI (false) - :RTM (false) - :SAM (false) - :UAC (false) - :UFP (false) - :color (black) - :comments () - :product_info ( - :AdminInfo ( - :chkpf_uid ("{97AEB5D9-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (OPSEC_product_info) - ) - :certification_info () - :certified (true) - :product (Private_I_Intelligence_Suite) - :vendor (OpenSystems.com) - :version (6.1) - ) - :type (OPSEC_product) - ) - : (SameSolutions_NetTracker_1.1 - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB5DB-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (OPSEC_product) - :table (products) - ) - :NT_commands () - :commands () - :solaris_commands () - :AMON (false) - :AMON_class_name (default_opsec_status_object) - :CPMI (false) - :CVP (false) - :ELA (false) - :LEA (true) - :OMI (false) - :RTM (false) - :SAM (false) - :UAC (false) - :UFP (false) - :color (black) - :comments () - :product_info ( - :AdminInfo ( - :chkpf_uid ("{97AEB5DC-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (OPSEC_product_info) - ) - :certification_info () - :certified (true) - :product (NetTracker_Enterprise) - :vendor ("Sane Solutions") - :version (1.1) - ) - :type (OPSEC_product) - ) - : (Telemate.Net_4.4 - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB5DE-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (OPSEC_product) - :table (products) - ) - :NT_commands () - :commands () - :solaris_commands () - :AMON (false) - :AMON_class_name (default_opsec_status_object) - :CPMI (false) - :CVP (false) - :ELA (false) - :LEA (true) - :OMI (false) - :RTM (false) - :SAM (false) - :UAC (false) - :UFP (false) - :color (black) - :comments () - :product_info ( - :AdminInfo ( - :chkpf_uid ("{97AEB5DF-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (OPSEC_product_info) - ) - :certification_info () - :certified (true) - :product (TELEMATE.Net) - :vendor (Telemate.Net_Software) - :version (4.4) - ) - :type (OPSEC_product) - ) - : (VeriSign_Firewall_HealthCHECK_1.5 - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB5E1-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (OPSEC_product) - :table (products) - ) - :NT_commands () - :commands () - :solaris_commands () - :AMON (false) - :AMON_class_name (default_opsec_status_object) - :CPMI (false) - :CVP (false) - :ELA (false) - :LEA (false) - :OMI (true) - :RTM (false) - :SAM (false) - :UAC (false) - :UFP (false) - :color (black) - :comments () - :product_info ( - :AdminInfo ( - :chkpf_uid ("{97AEB5E2-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (OPSEC_product_info) - ) - :certification_info () - :certified (true) - :product (Firewall_HealthCHECK) - :vendor (VeriSign) - :version (1.5) - ) - :type (OPSEC_product) - ) - : (VeriSign_SecureVIEW_3.0.28 - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB5E4-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (OPSEC_product) - :table (products) - ) - :NT_commands () - :commands () - :solaris_commands () - :AMON (false) - :AMON_class_name (default_opsec_status_object) - :CPMI (false) - :CVP (false) - :ELA (false) - :LEA (true) - :OMI (false) - :RTM (false) - :SAM (false) - :UAC (false) - :UFP (false) - :color (black) - :comments () - :product_info ( - :AdminInfo ( - :chkpf_uid ("{97AEB5E5-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (OPSEC_product_info) - ) - :certification_info () - :certified (true) - :product (SecureVIEW) - :vendor (VeriSign) - :version (3.0.28) - ) - :type (OPSEC_product) - ) - : (WebTrends_Firewall_2.0 - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB5E7-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (OPSEC_product) - :table (products) - ) - :NT_commands () - :commands () - :solaris_commands () - :AMON (false) - :AMON_class_name (default_opsec_status_object) - :CPMI (false) - :CVP (false) - :ELA (false) - :LEA (true) - :OMI (false) - :RTM (false) - :SAM (false) - :UAC (false) - :UFP (false) - :color (black) - :comments () - :product_info ( - :AdminInfo ( - :chkpf_uid ("{97AEB5E8-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (OPSEC_product_info) - ) - :certification_info () - :certified (true) - :product (WebTrends_Firewall_Suite) - :vendor (WebTrends) - :version (2.0) - ) - :type (OPSEC_product) - ) - ) - :serverobj (serverobj) - :resources (resources) - :translations (translations) - :tracks (tracks - : ("UserDefined 2" - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:09 2001") - :By (CheckPoint) - :From (CheckPoint) - ) - :chkpf_uid ("{97AEB485-9AEA-21D5-BD16-0090272CCB30}") - :ClassName (alert) - :table (tracks) - :name ("UserDefined 2") - ) - :Name () - :alert (useralert2) - :color ("Dark Orchid") - :format (long) - :icon () - :icon-name (icon-user) - :text-rid (61470) - :type (alert) - ) - : ("UserDefined 3" - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:09 2001") - :By (CheckPoint) - :From (CheckPoint) - ) - :chkpf_uid ("{97AEB485-9AEA-31D5-BD16-0090272CCB30}") - :ClassName (alert) - :table (tracks) - :name ("UserDefined 3") - ) - :Name () - :alert (useralert3) - :color ("Dark Orchid") - :format (long) - :icon () - :icon-name (icon-user) - :text-rid (61470) - :type (alert) - ) - : (VPNddcateDropLog - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By (CheckPoint) - :From (CheckPoint) - ) - :chkpf_uid ("{97AEB496-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (log) - :table (tracks) - :name (VPNddcateDropLog) - ) - :Name () - :color ("Navy Blue") - :format (long) - :icon-name (icon-log-long) - :macro (VPN_DEDICATED_DROP_LOG) - :text-rid (0) - :type (log) - ) - : (VPNddcateAcceptLog - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By (CheckPoint) - :From (CheckPoint) - ) - :chkpf_uid ("{97AEB497-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (log) - :table (tracks) - :name (VPNddcateAcceptLog) - ) - :Name () - :color ("Navy Blue") - :format (long) - :icon-name (icon-log-long) - :macro (VPN_DEDICATED_ACCEPT_LOG) - :text-rid (0) - :type (log) - ) - : (None - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB47D-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (empty_track) - :table (tracks) - :name (None) - ) - :icon (empty) - :icon-name (icon-empty) - ) - : (Short - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB47E-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (log) - :table (tracks) - :name (Short) - ) - :Name () - :color (Blue) - :format () - :icon-name (icon-log-short) - :macro () - :text-rid (61467) - :type (log) - ) - : (Long - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB47F-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (log) - :table (tracks) - :name (Long) - ) - :Name () - :color ("Navy Blue") - :format () - :icon-name (icon-log-long) - :macro () - :text-rid (61466) - :type (log) - ) - : (Log - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB480-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (log) - :table (tracks) - :name (Log) - ) - :Name () - :color ("Navy Blue") - :format (long) - :icon-name (icon-log-long) - :macro () - :text-rid (61466) - :type (log) - ) - : (Account - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB481-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (account) - :table (tracks) - :name (Account) - ) - :Name () - :color (Magenta) - :format (long) - :icon-name (icon-account) - :macro (ACCOUNT) - :type (account) - ) - : (Alert - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:09 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB482-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (alert) - :table (tracks) - :name (Alert) - ) - :Name () - :alert (alert) - :color (Red) - :format (long) - :icon () - :icon-name (icon-alert) - :text-rid (61469) - :type (alert) - ) - : (SnmpTrap - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:09 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB483-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (alert) - :table (tracks) - :name (SnmpTrap) - ) - :Name () - :alert (snmptrap) - :color ("Medium Slate Blue") - :format (long) - :icon () - :icon-name (icon-snmp-trap) - :text-rid (61467) - :type (alert) - ) - : (Mail - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:09 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB484-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (alert) - :table (tracks) - :name (Mail) - ) - :Name () - :alert (mail) - :color (FireBrick) - :format (long) - :icon () - :icon-name (icon-mail) - :text-rid (61468) - :type (alert) - ) - : (UserDefined - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:09 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB485-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (alert) - :table (tracks) - :name (UserDefined) - ) - :Name () - :alert (useralert) - :color ("Dark Orchid") - :format (long) - :icon () - :icon-name (icon-user) - :text-rid (61470) - :type (alert) - ) - : (spoof - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:09 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB486-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (log) - :table (tracks) - :name (spoof) - ) - :Name () - :color ("Navy Blue") - :format (long) - :icon-name () - :macro () - :text-rid (0) - :type (log) - ) - : (spoofalert - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:09 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB487-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (alert) - :table (tracks) - :name (spoofalert) - ) - :Name () - :alert (spoofalert) - :color (red) - :format (long) - :icon (alert.pr) - :icon-name () - :text-rid (0) - :type (alert) - ) - : ("IP Options" - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:09 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB488-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (log) - :table (tracks) - :name ("IP Options") - ) - :Name () - :color ("Dark Orchid") - :format (badip_form) - :icon-name () - :macro () - :text-rid (0) - :type (log) - ) - : ("IP Options Alert" - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:09 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB489-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (alert) - :table (tracks) - :name ("IP Options Alert") - ) - :Name () - :alert (alert) - :color (Red) - :format (badip_form) - :icon (alert.pr) - :icon-name () - :text-rid (0) - :type (alert) - ) - : (Auth - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:09 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB48A-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (log) - :table (tracks) - :name (Auth) - ) - :Name (Auth) - :color (Blue) - :format () - :icon-name () - :macro () - :text-rid (0) - :type (log) - ) - : (AuthAlert - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:09 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB48B-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (alert) - :table (tracks) - :name (AuthAlert) - ) - :Name (AuthAlert) - :alert (userauthalert) - :color (Red) - :format (auth) - :icon (alert.pr) - :icon-name () - :text-rid (0) - :type (alert) - ) - : (Duplicate - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:09 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB48C-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (log) - :table (tracks) - :name (Duplicate) - ) - :Name () - :color ("Navy Blue") - :format () - :icon-name (icon-log-long) - :macro (DUP_LOG) - :text-rid (61466) - :type (log) - ) - : ("Exception Log" - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:09 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB48D-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (log) - :table (tracks) - :name ("Exception Log") - ) - :Name () - :color (Blue) - :format (long) - :icon-name () - :macro () - :text-rid (0) - :type (log) - ) - : ("Exception Alert" - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:09 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB48E-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (alert) - :table (tracks) - :name ("Exception Alert") - ) - :Name () - :alert (alert) - :color (Red) - :format (long) - :icon (alert.pr) - :icon-name () - :text-rid (0) - :type (alert) - ) - ) - :qos ( - : (Best_Effort - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:09 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB658-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (class_of_service) - :table (qos) - :Deleteable (false) - :Renameable (false) - ) - :class_of_service_type (best_effort) - :color (black) - :comments () - :dscp (0) - :type (fg_class_of_service) - ) - ) - :servgen () - :log-props () - :state-act ( - :comannd_notinst2inst () - :command_notinst2dis () - :command_ins2notinst (status_alert) - :command_inst2dis (status_alert) - :command_dis2inst () - :command_dis2notinst () - ) - :SPIobj () - :userdefaults (Default - :name (Default) - :type (template) - :auth_method (Undefined) - :fromhour ("00:00") - :tohour ("23:59") - :expiration_date (31-dec-2003) - :groups () - :SKEY_number (100) - :days (127) - :destinations ( - : (Any - :color (Blue) - ) - ) - :sources ( - : (Any - :color (Blue) - ) - ) - ) - :ldap ( - : (OPSEC_DS - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:09 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB639-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (LDAP_policy) - :table (ldap) - ) - :Common ( - :AdminInfo ( - :chkpf_uid ("{97AEB63A-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (LDAP_policy_common) - ) - :AttributesTranslationMap ( - : ("uid=uid") - ) - :DateFormat (yyyymmdd) - :ListOfAttrsToAvoid () - :TemplateObjectClass ( - : (fw1template) - ) - :BadPwdCountAttr (fw1BadPwdCount) - :ClientSideCrypt (0) - :CryptedPasswordPrefix ("{CRYPT}") - :DefaultCryptAlgorithm (PLAIN) - :ExpirationDateAttr (fw1expiration-date) - :ExpirationDateFormat (CP) - :FetchBranchesEnabled (1) - :MainVersion (4) - :PhoneNumberAttr (internationalisdnnumber) - :PsswdDateAttr (fw1pwdLastMod) - :PsswdDateFormat (CP) - :ReadOnly (0) - :StrongAuthSupported (1) - :SubVersion (1) - :SupportOldSchema (0) - :UnbindMode (0) - :UserLoginAttr (uid) - :UserPasswordAttr (userPassword) - :Vendor (Other) - ) - :Read ( - :AdminInfo ( - :chkpf_uid ("{97AEB63B-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (LDAP_policy_read) - ) - :BranchObjectClass ( - : (Organization) - : (OrganizationalUnit) - ) - :DomainObjectClass () - :GroupMembershipAttr ( - : (member) - : (uniqueMember) - ) - :GroupObjectClass ( - : (groupOfNames) - : (groupOfUniqueNames) - ) - :OrgUnitObjectClass ( - : (OrganizationalUnit) - ) - :OrganizationObjectClass ( - : (Organization) - ) - :TemplateMembershipAttr ( - : (member) - ) - :TemplateObjectClass ( - : (Organization) - ) - :UserMembershipAttr ( - : (memberOf) - ) - :UserObjectClass ( - : (person) - : (organizationalPerson) - : (inetOrgPerson) - : (fw1Person) - ) - :BranchOCOperator (One) - :FetchBranchesFrom () - :GroupMembership (Member) - :GroupOCOperator (One) - :Scope (sub) - :SizeLimit (2000) - :TemplateMembership (Member) - :TimeLimit (50) - :UserOCOperator (One) - :UserTemplateMembershipAttr (memberoftemplate) - ) - :Write ( - :AdminInfo ( - :chkpf_uid ("{97AEB63C-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (LDAP_policy_write) - ) - :AutomaticAttrs () - :DomainObjectClass () - :DomainRDN (dc) - :GroupObjectClass ( - : ("groupOfNames:member") - : ("groupOfUniqueNames:uniqueMember") - ) - :OrgUnitObjectClass ( - : (OrganizationalUnit) - ) - :OrganizationObjectClass ( - : (Organization) - ) - :TemplateMembershipAttr ( - : (member) - ) - :UserObjectClass ( - : (person) - : (organizationalPerson) - : (inetOrgPerson) - : (fw1Person) - ) - :AllowReplaceOperation (1) - :DefaultGroupObjectClass (groupOfNames) - :GroupRDN (cn) - :OrgUnitRDN (ou) - :OrganizationRDN (o) - :SupportEmptyGroups (1) - :TemplateMembership (Member) - :UserMembershipAttr (memberOf) - :UserRDN (cn) - :UserTemplateMembershipAttr (memberoftemplate) - ) - :color (Black) - :comments ("Default Directory Server") - :type (ldap_policy) - ) - : (Novell_DS - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:09 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB640-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (LDAP_policy) - :table (ldap) - ) - :Common ( - :AdminInfo ( - :chkpf_uid ("{97AEB641-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (LDAP_policy_common) - ) - :AttributesTranslationMap ( - : ("uid=uid") - ) - :DateFormat (yyyymmdd) - :ListOfAttrsToAvoid () - :TemplateObjectClass ( - : (fw1template) - ) - :BadPwdCountAttr (fw1BadPwdCount) - :ClientSideCrypt (0) - :CryptedPasswordPrefix ("{CRYPT}") - :DefaultCryptAlgorithm (PLAIN) - :ExpirationDateAttr (fw1expiration-date) - :ExpirationDateFormat (CP) - :FetchBranchesEnabled (1) - :MainVersion (4) - :PhoneNumberAttr (internationalisdnnumber) - :PsswdDateAttr (fw1pwdLastMod) - :PsswdDateFormat (CP) - :ReadOnly (0) - :StrongAuthSupported (1) - :SubVersion (1) - :SupportOldSchema (0) - :UnbindMode (0) - :UserLoginAttr (uid) - :UserPasswordAttr (userPassword) - :Vendor (Novell) - ) - :Read ( - :AdminInfo ( - :chkpf_uid ("{97AEB642-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (LDAP_policy_read) - ) - :BranchObjectClass ( - : (Organization) - : (OrganizationalUnit) - ) - :DomainObjectClass () - :GroupMembershipAttr ( - : (member) - : (uniqueMember) - ) - :GroupObjectClass ( - : (groupOfNames) - : (groupOfUniqueNames) - ) - :OrgUnitObjectClass ( - : (OrganizationalUnit) - ) - :OrganizationObjectClass ( - : (Organization) - ) - :TemplateMembershipAttr ( - : (member) - ) - :TemplateObjectClass ( - : (Organization) - ) - :UserMembershipAttr ( - : (memberOf) - ) - :UserObjectClass ( - : (person) - : (organizationalPerson) - : (inetOrgPerson) - : (fw1Person) - ) - :BranchOCOperator (One) - :FetchBranchesFrom () - :GroupMembership (Member) - :GroupOCOperator (One) - :Scope (sub) - :SizeLimit (2000) - :TemplateMembership (Member) - :TimeLimit (50) - :UserOCOperator (One) - :UserTemplateMembershipAttr (memberoftemplate) - ) - :Write ( - :AdminInfo ( - :chkpf_uid ("{97AEB643-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (LDAP_policy_write) - ) - :AutomaticAttrs () - :DomainObjectClass () - :DomainRDN (dc) - :GroupObjectClass ( - : ("groupOfNames:member") - : ("groupOfUniqueNames:uniqueMember") - ) - :OrgUnitObjectClass ( - : (OrganizationalUnit) - ) - :OrganizationObjectClass ( - : (Organization) - ) - :TemplateMembershipAttr ( - : (member) - ) - :UserObjectClass ( - : (person) - : (organizationalPerson) - : (inetOrgPerson) - : (fw1Person) - ) - :AllowReplaceOperation (1) - :DefaultGroupObjectClass (groupOfNames) - :GroupRDN (cn) - :OrgUnitRDN (ou) - :OrganizationRDN (o) - :SupportEmptyGroups (1) - :TemplateMembership (Member) - :UserMembershipAttr (memberOf) - :UserRDN (cn) - :UserTemplateMembershipAttr (memberoftemplate) - ) - :color (Black) - :comments ("Novell Directory Server") - :type (ldap_policy) - ) - : (Netscape_DS - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:09 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB647-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (LDAP_policy) - :table (ldap) - ) - :Common ( - :AdminInfo ( - :chkpf_uid ("{97AEB648-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (LDAP_policy_common) - ) - :AttributesTranslationMap ( - : ("uid=uid") - ) - :DateFormat (yyyymmdd) - :ListOfAttrsToAvoid () - :TemplateObjectClass ( - : (fw1template) - ) - :BadPwdCountAttr (fw1BadPwdCount) - :ClientSideCrypt (1) - :CryptedPasswordPrefix ("{CRYPT}") - :DefaultCryptAlgorithm (CRYPT) - :ExpirationDateAttr (fw1expiration-date) - :ExpirationDateFormat (CP) - :FetchBranchesEnabled (1) - :MainVersion (4) - :PhoneNumberAttr (internationalisdnnumber) - :PsswdDateAttr (fw1pwdLastMod) - :PsswdDateFormat (CP) - :ReadOnly (0) - :StrongAuthSupported (1) - :SubVersion (1) - :SupportOldSchema (0) - :UnbindMode (0) - :UserLoginAttr (uid) - :UserPasswordAttr (userPassword) - :Vendor (Netscape) - ) - :Read ( - :AdminInfo ( - :chkpf_uid ("{97AEB649-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (LDAP_policy_read) - ) - :BranchObjectClass ( - : (Organization) - : (OrganizationalUnit) - : (Domain) - ) - :DomainObjectClass () - :GroupMembershipAttr ( - : (member) - : (uniqueMember) - ) - :GroupObjectClass ( - : (groupOfNames) - : (groupOfUniqueNames) - ) - :OrgUnitObjectClass ( - : (OrganizationalUnit) - ) - :OrganizationObjectClass ( - : (Organization) - ) - :TemplateMembershipAttr ( - : (member) - ) - :TemplateObjectClass ( - : (Organization) - ) - :UserMembershipAttr ( - : (memberOf) - ) - :UserObjectClass ( - : (person) - : (organizationalPerson) - : (inetOrgPerson) - : (fw1Person) - ) - :BranchOCOperator (One) - :FetchBranchesFrom () - :GroupMembership (Member) - :GroupOCOperator (One) - :Scope (sub) - :SizeLimit (2000) - :TemplateMembership (Member) - :TimeLimit (50) - :UserOCOperator (One) - :UserTemplateMembershipAttr (memberoftemplate) - ) - :Write ( - :AdminInfo ( - :chkpf_uid ("{97AEB64A-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (LDAP_policy_write) - ) - :AutomaticAttrs () - :DomainObjectClass ( - : (domain) - : (top) - ) - :DomainRDN (dc) - :GroupObjectClass ( - : ("groupOfNames:member") - : ("groupOfUniqueNames:uniqueMember") - ) - :OrgUnitObjectClass ( - : (OrganizationalUnit) - ) - :OrganizationObjectClass ( - : (Organization) - ) - :TemplateMembershipAttr ( - : (member) - ) - :UserObjectClass ( - : (person) - : (organizationalPerson) - : (inetOrgPerson) - : (fw1Person) - ) - :AllowReplaceOperation (1) - :DefaultGroupObjectClass (groupOfNames) - :GroupRDN (cn) - :OrgUnitRDN (ou) - :OrganizationRDN (o) - :SupportEmptyGroups (1) - :TemplateMembership (Member) - :UserMembershipAttr (memberOf) - :UserRDN (cn) - :UserTemplateMembershipAttr (memberoftemplate) - ) - :color (Black) - :comments ("Netscape Directory Server") - :type (ldap_policy) - ) - : (Microsoft_AD - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:09 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB64E-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (LDAP_policy) - :table (ldap) - ) - :Common ( - :AdminInfo ( - :chkpf_uid ("{97AEB64F-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (LDAP_policy_common) - ) - :AttributesTranslationMap ( - : ("uid=uid") - ) - :DateFormat (yyyymmdd) - :ListOfAttrsToAvoid () - :TemplateObjectClass ( - : (fw1template) - ) - :BadPwdCountAttr (fw1BadPwdCount) - :ClientSideCrypt (0) - :CryptedPasswordPrefix ("{CRYPT}") - :DefaultCryptAlgorithm (PLAIN) - :ExpirationDateAttr (accountExpires) - :ExpirationDateFormat (MS) - :FetchBranchesEnabled (1) - :MainVersion (5) - :PhoneNumberAttr (internationalisdnnumber) - :PsswdDateAttr (pwdLastSet) - :PsswdDateFormat (MS) - :ReadOnly (0) - :StrongAuthSupported (1) - :SubVersion (0) - :SupportOldSchema (0) - :UnbindMode (0) - :UserLoginAttr (sAMAccountName) - :UserPasswordAttr (unicodePwd) - :Vendor (Microsoft) - ) - :Read ( - :AdminInfo ( - :chkpf_uid ("{97AEB650-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (LDAP_policy_read) - ) - :BranchObjectClass ( - : (Organization) - : (OrganizationalUnit) - : (Container) - ) - :DomainObjectClass () - :GroupMembershipAttr ( - : (member) - ) - :GroupObjectClass ( - : (group) - : (groupOfNames) - ) - :OrgUnitObjectClass ( - : (OrganizationalUnit) - : (Container) - ) - :OrganizationObjectClass ( - : (Organization) - ) - :TemplateMembershipAttr ( - : (member) - ) - :TemplateObjectClass ( - : (Organization) - ) - :UserMembershipAttr ( - : (memberOf) - ) - :UserObjectClass ( - : (user) - ) - :BranchOCOperator (One) - :FetchBranchesFrom () - :GroupMembership (MemberOf) - :GroupOCOperator (One) - :Scope (sub) - :SizeLimit (2000) - :TemplateMembership (MemberOf) - :TimeLimit (50) - :UserOCOperator (One) - :UserTemplateMembershipAttr (memberoftemplate) - ) - :Write ( - :AdminInfo ( - :chkpf_uid ("{97AEB651-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (LDAP_policy_write) - ) - :AutomaticAttrs ( - : ("user:userAccountControl:66048") - ) - :DomainObjectClass () - :DomainRDN (dc) - :GroupObjectClass ( - : ("group:member") - ) - :OrgUnitObjectClass ( - : (OrganizationalUnit) - ) - :OrganizationObjectClass ( - : (Organization) - ) - :TemplateMembershipAttr ( - : (member) - ) - :UserObjectClass ( - : (user) - ) - :AllowReplaceOperation (1) - :DefaultGroupObjectClass (group) - :GroupRDN (cn) - :OrgUnitRDN (ou) - :OrganizationRDN (o) - :SupportEmptyGroups (0) - :TemplateMembership (MemberOf) - :UserMembershipAttr (memberOf) - :UserRDN (cn) - :UserTemplateMembershipAttr (memberoftemplate) - ) - :color (Black) - :comments ("Microsoft Active Directory") - :type (ldap_policy) - ) - ) - :encryption ( - : (skip512 - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:09 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB61A-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (SKIP_Diffie_Hellman_parameters_object) - :table (encryption) - ) - :color (black) - :comments () - :mod ( - :AdminInfo ( - :chkpf_uid ("{97AEB61B-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (key_value) - ) - :value (F52AFF3CE1B1294018118D7C84A70A72D686C40319C807297ACA950CD9969FABD00A509B0246D3083D66A45D419F9C7CBD894B221926BAABA25EC355E92A055F) - ) - :modsize (0) - :root ( - :AdminInfo ( - :chkpf_uid ("{97AEB61C-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (key_value) - ) - :value (02) - ) - :rootsize (0) - :type (SKIP_DH_parameters) - ) - : (skip1024 - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:09 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB61F-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (SKIP_Diffie_Hellman_parameters_object) - :table (encryption) - ) - :color (black) - :comments () - :mod ( - :AdminInfo ( - :chkpf_uid ("{97AEB620-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (key_value) - ) - :value (f488fd584e49dbcd20b49de49107366b336c380d451d0f7c88b31c7c5b2d8ef6f3c923c043f0a55b188d8ebb558cb85d38d334fd7c175743a31d186cde33212cb52aff3ce1b1294018118d7c84a70a72d686c40319c807297aca950cd9969fabd00a509b0246d3083d66a45d419f9c7cbd894b221926baaba25ec355e92f78c7) - ) - :modsize (0) - :root ( - :AdminInfo ( - :chkpf_uid ("{97AEB621-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (key_value) - ) - :value (02) - ) - :rootsize (0) - :type (SKIP_DH_parameters) - ) - : ("Group 1 (768 bit)" - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:09 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB624-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (IKE_Diffie_Hellman_parameters_object) - :table (encryption) - ) - :DH_group_number (1) - :color (black) - :comments () - :mod ( - :AdminInfo ( - :chkpf_uid ("{97AEB625-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (key_value) - ) - :value (ffffffffffffffffc90fdaa22168c234c4c6628b80dc1cd129024e088a67cc74020bbea63b139b22514a08798e3404ddef9519b3cd3a431b302b0a6df25f14374fe1356d6d51c245e485b576625e7ec6f44c42e9a63a3620ffffffffffffffff) - ) - :modsize (768) - :private_key_length (160) - :root ( - :AdminInfo ( - :chkpf_uid ("{97AEB626-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (key_value) - ) - :value (02) - ) - :rootsize (2) - :type (IKE_DH_parameters) - ) - : ("Group 2 (1024 bit)" - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:09 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB629-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (IKE_Diffie_Hellman_parameters_object) - :table (encryption) - ) - :DH_group_number (2) - :color (black) - :comments () - :mod ( - :AdminInfo ( - :chkpf_uid ("{97AEB62A-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (key_value) - ) - :value (ffffffffffffffffc90fdaa22168c234c4c6628b80dc1cd129024e088a67cc74020bbea63b139b22514a08798e3404ddef9519b3cd3a431b302b0a6df25f14374fe1356d6d51c245e485b576625e7ec6f44c42e9a637ed6b0bff5cb6f406b7edee386bfb5a899fa5ae9f24117c4b1fe649286651ece65381ffffffffffffffff) - ) - :modsize (1024) - :private_key_length (192) - :root ( - :AdminInfo ( - :chkpf_uid ("{97AEB62B-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (key_value) - ) - :value (02) - ) - :rootsize (2) - :type (IKE_DH_parameters) - ) - : ("Group 5 (1536 bit)" - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:09 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB62E-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (IKE_Diffie_Hellman_parameters_object) - :table (encryption) - ) - :DH_group_number (5) - :color (black) - :comments () - :mod ( - :AdminInfo ( - :chkpf_uid ("{97AEB62F-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (key_value) - ) - :value (FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7EDEE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3DC2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F83655D23DCA3AD961C62F356208552BB9ED529077096966D670C354E4ABC9804F1746C08CA237327FFFFFFFFFFFFFFFF) - ) - :modsize (1536) - :private_key_length (256) - :root ( - :AdminInfo ( - :chkpf_uid ("{97AEB630-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (key_value) - ) - :value (02) - ) - :rootsize (2) - :type (IKE_DH_parameters) - ) - : (fwz512 - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:09 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB633-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (FWZ_Diffie_Hellman_parameters_object) - :table (encryption) - ) - :color (black) - :comments () - :mod ( - :AdminInfo ( - :chkpf_uid ("{97AEB634-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (key_value) - ) - :value (9f57f60c98ba4f11468dfb4c2ecfd15b8861f48a88bd32cb2cb954c06cc01e25578102905691631266306444b1ef31de0c0091f468ecbccd70170b2d84fa637f) - ) - :modsize (0) - :root ( - :AdminInfo ( - :chkpf_uid ("{97AEB635-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (key_value) - ) - :value (0a552ee379202b40e79dca100dfb6501346307533c3ebef5e3ee0727e260489377981ae7c8b6124128437d4892fd632aafde6df3744f0351ec05f83130f74cfb) - ) - :rootsize (0) - :type (FWZ_DH_parameters) - ) - ) - :communities ( - : (MyExtranet - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:09 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB676-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (extranet_community) - :table (communities) - ) - :extranet_partners () - :extranet_resources () - :color (black) - :comments () - :type (extranet_community) - ) - : (RemoteAccess - :AdminInfo ( - :chkpf_uid ("{97AEB677-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (sr_community) - :table (communities) - :Deleteable (false) - :Wiznum (-1) - :LastModified ( - :Time ("Thu May 6 14:28:35 2004") - :By (andre) - :From (gateway) - ) - ) - :participant_gateways ( - : (ReferenceObject - :Name (IsoAAAD) - :Table (network_objects) - :Uid ("{29C40B0A-414C-11D7-AEB8-7F0000013C3C}") - ) - ) - :participant_users_groups ( - : (ReferenceObject - :Name (Cactus-extern) - :Table (users) - :Uid ("{227D1A80-CC1E-4CD4-9576-4D46F271402F}") - ) - : (ReferenceObject - :Name (RAS-Test) - :Table (users) - :Uid ("{895BBAA2-096E-4DC6-A621-4A98B44EB63E}") - ) - : (ReferenceObject - :Name (vpn_user) - :Table (users) - :Uid ("{82847E1A-EF2C-4A75-9A9E-0034D70978DB}") - ) - ) - :ID (2) - :color (black) - :comments () - :ike_p1 ( - :AdminInfo ( - :chkpf_uid ("{64C9347A-414A-11D7-B538-7F0000014646}") - :ClassName (ike_p1) - ) - :ike_p1_dh_grp (ReferenceObject - :Table (encryption) - :Name ("Group 2 (1024 bit)") - :Uid ("{97AEB629-9AEA-11D5-BD16-0090272CCB30}") - ) - :ike_p1_enc_alg (3DES) - :ike_p1_hash_alg (MD5) - :ike_p1_rekey_time (1440) - :ike_p1_use_aggressive (false) - :ike_p1_use_shared_secret (false) - ) - :ike_p2 ( - :AdminInfo ( - :chkpf_uid ("{64C93A60-414A-11D7-B538-7F0000014646}") - :ClassName (ike_p2) - ) - :ike_p2_enc_alg (3DES) - :ike_p2_hash_alg (MD5) - :ike_p2_ipcomp (None) - :ike_p2_pfs_dh_grp (ReferenceObject - :Table (encryption) - :Name ("Group 2 (1024 bit)") - :Uid ("{97AEB629-9AEA-11D5-BD16-0090272CCB30}") - ) - :ike_p2_rekey_kbytes (50000) - :ike_p2_rekey_time (3600) - :ike_p2_use_pfs (false) - :ike_p2_use_rekey_kbytes (false) - :ike_p2_use_subnets (true) - ) - :type (sr_community) - ) - :next_number (7) - : (IsoAAAE-VPN - :AdminInfo ( - :chkpf_uid ("{3C7F216B-3FD1-4E6D-A65F-0EF3C500F865}") - :ClassName (intranet_community) - :table (communities) - :Wiznum (-1) - :LastModified ( - :Time ("Sat Nov 20 22:20:26 2004") - :By (tim) - :From (gateway) - ) - ) - :exclude_srv () - :participant_gateways ( - : (ReferenceObject - :Name (IsoAAAD) - :Table (network_objects) - :Uid ("{29C40B0A-414C-11D7-AEB8-7F0000013C3C}") - ) - ) - :satellite_gateways () - :ID (5) - :allow_all_encrypted_traffic (false) - :color (black) - :comments () - :disable_NAT (false) - :ike_p1 ( - :AdminInfo ( - :chkpf_uid ("{CD67359F-4B08-41BD-8F72-E35BA5BCEA1E}") - :ClassName (ike_p1) - ) - :ike_p1_dh_grp (ReferenceObject - :Name ("Group 2 (1024 bit)") - :Table (encryption) - :Uid ("{97AEB629-9AEA-11D5-BD16-0090272CCB30}") - ) - :ike_p1_enc_alg (3DES) - :ike_p1_hash_alg (SHA1) - :ike_p1_rekey_time (1440) - :ike_p1_use_aggressive (false) - :ike_p1_use_shared_secret (false) - ) - :ike_p2 ( - :AdminInfo ( - :chkpf_uid ("{FB40B39A-590A-404E-A70D-A47D18DF4081}") - :ClassName (ike_p2) - ) - :ike_p2_enc_alg (3DES) - :ike_p2_hash_alg (SHA1) - :ike_p2_ipcomp (None) - :ike_p2_pfs_dh_grp (ReferenceObject - :Table (encryption) - :Name ("Group 2 (1024 bit)") - :Uid ("{97AEB629-9AEA-11D5-BD16-0090272CCB30}") - ) - :ike_p2_rekey_kbytes (50000) - :ike_p2_rekey_time (3600) - :ike_p2_use_pfs (false) - :ike_p2_use_rekey_kbytes (false) - :ike_p2_use_subnets (true) - ) - :meshed_in_center (false) - :route_through_center (none) - :topology (star) - :type (intranet_community) - ) - ) - :setup ( - : ("Single Sign On" - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:09 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB48F-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (Impersonation) - :table (setup) - :name ("Single Sign On") - ) - :color (Blue) - :icon-name (ICON_WC_SSO) - :menu (true) - :sso_setting ( - :AdminInfo ( - :chkpf_uid ("{97AEB65A-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (sso_setting) - ) - :application_name () - :authentication_domain () - :html_sso ( - :AdminInfo ( - :chkpf_uid ("{97AEB659-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (html_sso) - ) - :html_sso_type (logoff) - :login_url () - :logoff_url () - :submit_url () - ) - :sso_type (basic) - ) - :type (Impersonation) - ) - : (Redirection - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:09 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB490-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (Redirection) - :table (setup) - :name (Redirection) - ) - :color (Blue) - :icon-name (ICON_WC_REDIRECTION) - :menu (true) - :redirect_setting () - :type (Redirection) - ) - : ("Insert Header" - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:09 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB491-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (ModifyHeader) - :table (setup) - :name ("Insert Header") - ) - :header_settings () - :color ("Navy Blue") - :icon-name (ICON_WC_MODIFY_HEADER) - :menu (true) - :type (ModifyHeader) - ) - : ("Delete Header" - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:09 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB492-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (DeleteHeader) - :table (setup) - :name ("Delete Header") - ) - :header_settings () - :color ("Navy Blue") - :icon-name (ICON_WC_DELETE_HEADER) - :menu (true) - :type (DeleteHeader) - ) - : (Apply_To_Sub_Folders - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:09 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB493-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (outer_inheritance) - :table (setup) - :name (Apply_To_Sub_Folders) - ) - : (Yes - :AdminInfo ( - :chkpf_uid ("{97AEB660-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (inner_inheritance) - :table (setup) - ) - :color (Black) - :icon-name (ICON_WC_APPLY_TO_SF) - :type (RuleApplied) - ) - :nested_menu (true) - :type (RuleApplied) - ) - : (Do_Not_Apply_To_Sub_Folders - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:09 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB494-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (outer_inheritance) - :table (setup) - :name (Do_Not_Apply_To_Sub_Folders) - ) - : (No - :AdminInfo ( - :chkpf_uid ("{97AEB662-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (inner_inheritance) - :table (setup) - ) - :color (Black) - :icon-name (ICON_WC_NOT_APPLY_TO_SF) - :type (RuleNotApplied) - ) - :nested_menu (true) - :type (RuleNotApplied) - ) - : (RuleInherited - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:09 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB495-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (outer_inheritance) - :table (setup) - :name (RuleInherited) - ) - : (Inherited - :AdminInfo ( - :chkpf_uid ("{97AEB664-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (inner_inheritance) - :table (setup) - ) - :color (Black) - :icon-name (ICON_WC_INHERITED) - :type (RuleInherited) - ) - :nested_menu (true) - :type (RuleInherited) - ) - : (accept - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:09 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB360-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (accept_action) - :table (setup) - :name (accept) - ) - :action () - :macro (RECORD_CONN) - :type (accept) - ) - : (drop - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:09 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB361-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (drop_action) - :table (setup) - :name (drop) - ) - :action () - :macro () - :type (drop) - ) - : (reject - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:09 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB362-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (reject_action) - :table (setup) - :name (reject) - ) - :action () - :macro () - :type (reject) - ) - : ("User Auth" - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:09 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB363-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (user_authenticate) - :table (setup) - :name ("User Auth") - ) - :action () - :dst_options ("Intersect with User Database") - :macro () - :src_options ("Intersect with User Database") - :type (auth_user) - ) - : ("Client Auth" - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:09 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB364-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (client_authenticate) - :table (setup) - :name ("Client Auth") - ) - :accept_track (ReferenceObject - :Table (tracks) - :Name (None) - :Uid ("{97AEB47D-9AEA-11D5-BD16-0090272CCB30}") - ) - :action () - :clauth_refreshable (false) - :clauth_to_hours (0) - :clauth_to_infinite (false) - :clauth_to_minutes (30) - :clauth_track (ReferenceObject - :Table (tracks) - :Name (None) - :Uid ("{97AEB47D-9AEA-11D5-BD16-0090272CCB30}") - ) - :dst_options ("Intersect with User Database") - :enforce_desktop_config (false) - :macro (PASS_CLNTAUTH) - :ruletype ("standard sign on") - :sessions (5) - :sessions_infinite (false) - :signon_method ("manual sign-on") - :src_options ("Intersect with User Database") - :type (auth_client) - ) - : ("Session Auth" - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:09 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB365-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (session_authenticate) - :table (setup) - :name ("Session Auth") - ) - :accept_iff_encrypted (false) - :accept_track (ReferenceObject - :Table (tracks) - :Name (None) - :Uid ("{97AEB47D-9AEA-11D5-BD16-0090272CCB30}") - ) - :action () - :authenticate_with_UA (false) - :dst_options ("Intersect with User Database") - :macro (PASS_SESSION_AUTH) - :ruletype () - :sessions (1) - :sessions_infinite (false) - :snauth.agent (Src) - :src_options ("Intersect with User Database") - :type (auth_session) - ) - : (encrypt - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:09 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB366-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (encrypt) - :table (setup) - :name (encrypt) - ) - :action () - :datam (DES) - :diagnostics-track ( - :AdminInfo ( - :chkpf_uid ("{97AEB66B-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (empty_track) - :table (tracks) - ) - :icon (empty) - :icon-name (icon-empty) - ) - :gateway () - :isakmp.compression (None) - :isakmp.crlreq (false) - :isakmp.data.integrity (MD5) - :isakmp.encryption (3DES) - :isakmp.gateway () - :isakmp.phase2_DH_group (ReferenceObject - :Table (encryption) - :Name ("Group 2 (1024 bit)") - :Uid ("{97AEB629-9AEA-11D5-BD16-0090272CCB30}") - ) - :isakmp.transform (ESP) - :isakmp.use_pfs (false) - :isakmp.useippools (false) - :keym (DES) - :macro (ENCRYPTION) - :mdm (MD5) - :menu_inactive (false) - :scheme (ISAKMP) - :type (encrypt) - ) - : ("Client Encrypt" - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:09 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB367-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (client_encrypt) - :table (setup) - :name ("Client Encrypt") - ) - :action () - :dst_options ("Intersect with User Database") - :enforce_desktop_config (false) - :macro (USER_CLIENT_ENCRYPTION) - :src_options ("Intersect with User Database") - :type (userc) - ) - : (Gateways - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:09 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{1C1F246F-E707-11D4-A32B-0002B3168CEA}") - :ClassName (install_gateways) - :table (setup) - :name (Gateways) - ) - :type (gateways) - ) - : (Dst - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:09 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{1C1F2470-E707-11D4-A32B-0002B3168CEA}") - :ClassName (install_no_gateways) - :table (setup) - :name (Dst) - ) - :type (dst) - ) - : (Src - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:09 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{1C1F2471-E707-11D4-A32B-0002B3168CEA}") - :ClassName (install_no_gateways) - :table (setup) - :name (Src) - ) - :type (src) - ) - : ("OSE Devices" - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:09 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{1C1F2472-E707-11D4-A32B-0002B3168CEA}") - :ClassName (install_no_gateways) - :table (setup) - :name ("OSE Devices") - ) - :type (routers) - ) - : ("Embedded Devices" - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:09 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{1C1F2473-E707-11D4-A32B-0002B3168CEA}") - :ClassName (install_no_gateways) - :table (setup) - :name ("Embedded Devices") - ) - :type (blackboxes) - ) - ) - :methods ( - : (Read_GET - :AdminInfo ( - :chkpf_uid ("{FF4E493B-0014-4E7F-8B3B-7DA92C75041B}") - :ClassName (method) - :table (methods) - :Wiznum (-1) - :object_permissions ( - :AdminInfo ( - :chkpf_uid ("{5397AE69-D63B-4A3A-8861-5FD3CE7E5A34}") - :ClassName (object_permissions) - ) - :manage ( - : (ReferenceObject - :Table (globals) - :Name (Any) - ) - ) - :read ( - : (any) - ) - :use ( - : (any) - ) - :write ( - : () - ) - :owner () - ) - :LastModified ( - :Time ("Sun Dec 16 16:11:27 2001") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :extensions ( - : () - ) - :http_methods ( - : (GET) - ) - :parameters ( - : () - ) - :color (blue) - :comments () - :headers () - :type (method) - ) - : (Write_POST - :AdminInfo ( - :chkpf_uid ("{93AE6EF6-37A8-4ED3-8914-BAE0BCD22935}") - :ClassName (method) - :table (methods) - :Wiznum (-1) - :object_permissions ( - :AdminInfo ( - :chkpf_uid ("{B5DAD06B-8FDC-4BC5-B92D-CEC27B725051}") - :ClassName (object_permissions) - ) - :manage ( - : (ReferenceObject - :Table (globals) - :Name (Any) - ) - ) - :read ( - : (any) - ) - :use ( - : (any) - ) - :write ( - : () - ) - :owner () - ) - :LastModified ( - :Time ("Sun Dec 16 16:11:44 2001") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :extensions ( - : () - ) - :http_methods ( - : (POST) - ) - :parameters ( - : () - ) - :color ("dark green") - :comments () - :headers () - :type (method) - ) - : (Read_HEAD - :AdminInfo ( - :chkpf_uid ("{C5935CBF-2620-4102-9FFC-C28CB02AFC5D}") - :ClassName (method) - :table (methods) - :Wiznum (-1) - :object_permissions ( - :AdminInfo ( - :chkpf_uid ("{D4ABA21C-0EC1-4EC5-A3A3-8E92EA404705}") - :ClassName (object_permissions) - ) - :manage ( - : (ReferenceObject - :Table (globals) - :Name (Any) - ) - ) - :read ( - : (any) - ) - :use ( - : (any) - ) - :write ( - : () - ) - :owner () - ) - :LastModified ( - :Time ("Sun Dec 16 16:11:32 2001") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :extensions ( - : () - ) - :http_methods ( - : (HEAD) - ) - :parameters ( - : () - ) - :color (blue1) - :comments () - :headers () - :type (method) - ) - : (Write_PUT - :AdminInfo ( - :chkpf_uid ("{C19254EF-93B0-451E-B272-D9BCE0F1239B}") - :ClassName (method) - :table (methods) - :Wiznum (-1) - :object_permissions ( - :AdminInfo ( - :chkpf_uid ("{92593670-3E10-4095-A719-407D61AA020D}") - :ClassName (object_permissions) - ) - :manage ( - : (ReferenceObject - :Table (globals) - :Name (Any) - ) - ) - :read ( - : (any) - ) - :use ( - : (any) - ) - :write ( - : () - ) - :owner () - ) - :LastModified ( - :Time ("Sun Dec 16 16:11:56 2001") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :extensions ( - : () - ) - :http_methods ( - : (PUT) - ) - :parameters ( - : () - ) - :color (gold) - :comments () - :headers () - :type (method) - ) - : (Write_DELETE - :AdminInfo ( - :chkpf_uid ("{F1084137-B25B-4BCF-B8AB-A584D75DAA81}") - :ClassName (method) - :table (methods) - :Wiznum (-1) - :object_permissions ( - :AdminInfo ( - :chkpf_uid ("{92B3E91B-DF55-4AD9-A509-8C0D07801DF8}") - :ClassName (object_permissions) - ) - :manage ( - : (ReferenceObject - :Table (globals) - :Name (Any) - ) - ) - :read ( - : (any) - ) - :use ( - : (any) - ) - :write ( - : () - ) - :owner () - ) - :LastModified ( - :Time ("Sun Dec 16 16:11:50 2001") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :extensions ( - : () - ) - :http_methods ( - : (DELETE) - ) - :parameters ( - : () - ) - :color ("dark orchid") - :comments () - :headers () - :type (method) - ) - : (Read - :AdminInfo ( - :chkpf_uid ("{096BE591-0965-4554-A6C0-699304E494A3}") - :ClassName (method_group) - :table (methods) - :Wiznum (-1) - :object_permissions ( - :AdminInfo ( - :chkpf_uid ("{51E29EA5-F068-420E-A6D4-30D5EFE0A4D7}") - :ClassName (object_permissions) - ) - :manage ( - : (ReferenceObject - :Table (globals) - :Name (Any) - ) - ) - :read ( - : (any) - ) - :use ( - : (any) - ) - :write ( - : () - ) - :owner () - ) - :LastModified ( - :Time ("Sun Dec 16 16:11:03 2001") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - : (ReferenceObject - :Name (Read_GET) - :Table (methods) - :Uid ("{FF4E493B-0014-4E7F-8B3B-7DA92C75041B}") - ) - : (ReferenceObject - :Name (Read_HEAD) - :Table (methods) - :Uid ("{C5935CBF-2620-4102-9FFC-C28CB02AFC5D}") - ) - :color (black) - :comments () - :member_class (method) - :members_query () - :type (group) - ) - : (Write - :AdminInfo ( - :chkpf_uid ("{8597BE82-E4B9-4528-B5CA-8F636B028164}") - :ClassName (method_group) - :table (methods) - :Wiznum (-1) - :object_permissions ( - :AdminInfo ( - :chkpf_uid ("{95212127-F192-4BBB-8807-5692FA4466B5}") - :ClassName (object_permissions) - ) - :manage ( - : (ReferenceObject - :Table (globals) - :Name (Any) - ) - ) - :read ( - : (any) - ) - :use ( - : (any) - ) - :write ( - : () - ) - :owner () - ) - :LastModified ( - :Time ("Sun Dec 16 16:11:39 2001") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - : (ReferenceObject - :Name (Write_DELETE) - :Table (methods) - :Uid ("{F1084137-B25B-4BCF-B8AB-A584D75DAA81}") - ) - : (ReferenceObject - :Name (Write_POST) - :Table (methods) - :Uid ("{93AE6EF6-37A8-4ED3-8914-BAE0BCD22935}") - ) - : (ReferenceObject - :Name (Write_PUT) - :Table (methods) - :Uid ("{C19254EF-93B0-451E-B272-D9BCE0F1239B}") - ) - :color (cyan) - :comments () - :member_class (method) - :members_query () - :type (group) - ) - ) - :globals ( - : (VPN1NetLocalModule - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:09 2001") - :By (CheckPoint) - :From (CheckPoint) - ) - :chkpf_uid ("{97AEB36A-9ADF-11D5-BD16-0090272CCB30}") - :ClassName (any_object) - :table (globals) - :name (VPN1NetLocalModule) - ) - :color (black) - ) - : ("VPN-1 Embedded devices defined as Remote Access" - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:09 2001") - :By (CheckPoint) - :From (CheckPoint) - ) - :chkpf_uid ("{DDEDE17A-CC11-4710-9E0D-47CE7F9B7368}") - :ClassName (any_object) - :table (globals) - :name ("VPN-1 Embedded devices defined as Remote Access") - ) - :color (black) - ) - : ("All Users" - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:09 2001") - :By (CheckPoint) - :From (CheckPoint) - ) - :chkpf_uid ("{97AEB36A-9AEB-11D5-BD16-0090272CCB30}") - :ClassName (any_object) - :table (globals) - :name ("All Users") - ) - :color (black) - ) - : (All_Communities - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:09 2001") - :By (CheckPoint) - :From (CheckPoint) - ) - :chkpf_uid ("{97AEB36A-9AEC-11D5-BD16-0090272CCB30}") - :ClassName (any_object) - :table (globals) - :name (All_Communities) - ) - :color (black) - ) - : (All_GwToGw - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:09 2001") - :By (CheckPoint) - :From (CheckPoint) - ) - :chkpf_uid ("{97AEB36A-9AED-11D5-BD16-0090272CCB30}") - :ClassName (any_object) - :table (globals) - :name (All_GwToGw) - ) - :color (black) - ) - : (All_SR - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:09 2001") - :By (CheckPoint) - :From (CheckPoint) - ) - :chkpf_uid ("{97AEB36A-9AEE-11D5-BD16-0090272CCB30}") - :ClassName (any_object) - :table (globals) - :name (All_SR) - ) - :color (black) - ) - : (LocalVpnDomain - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:09 2001") - :By (CheckPoint) - :From (CheckPoint) - ) - :chkpf_uid ("{97AEB36A-9ADD-11D5-BD16-0090272CCB30}") - :ClassName (any_object) - :table (globals) - :name (LocalVpnDomain) - ) - :color (black) - ) - : (All - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:09 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB368-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (any_object) - :table (globals) - :name (All) - ) - :color (black) - ) - : (Any - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:09 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (any_object) - :table (globals) - :name (Any) - ) - :color (black) - ) - : (None - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:09 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB36A-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (any_object) - :table (globals) - :name (None) - ) - :color (black) - ) - ) - :version (5.41) - :properties ( - : (firewall_properties - :AdminInfo ( - :chkpf_uid ("{97AEB653-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (firewall_properties) - :object_permissions ( - :AdminInfo ( - :chkpf_uid ("{7FBC9AD1-0BBA-4CD0-8C0D-14FF5A81EA14}") - :ClassName (object_permissions) - ) - :manage ( - : (ReferenceObject - :Table (globals) - :Name (Any) - ) - ) - :read ( - : (any) - ) - :use ( - : (any) - ) - :write ( - : () - ) - :owner () - ) - :table (properties) - :Wiznum (-1) - :LastModified ( - :Time ("Mon Jun 6 11:36:25 2005") - :By (andre) - :From (andres-laptop) - ) - ) - :desktop_active_test ( - :0 ( - :AdminInfo ( - :chkpf_uid ("{29C2307A-4E51-11D7-A39D-7F0000011616}") - :ClassName (active_test) - ) - :test_name (ping_loopback) - :test_parameters () - ) - :1 ( - :AdminInfo ( - :chkpf_uid ("{29C234DA-4E51-11D7-A39D-7F0000011616}") - :ClassName (active_test) - ) - :test_name (ping_def_gw) - :test_parameters () - ) - :2 ( - :AdminInfo ( - :chkpf_uid ("{29C238E0-4E51-11D7-A39D-7F0000011616}") - :ClassName (active_test) - ) - :test_name (dttunneltest) - :test_parameters () - ) - ) - :desktop_ike_p1_enc_algs ( - : (DES) - : (3DES) - : (AES-256) - ) - :desktop_ike_p1_hash_algs ( - : (SHA1) - : (MD5) - ) - :desktop_ike_p1_supported_dh_groups ( - : (ReferenceObject - :Name ("Group 2 (1024 bit)") - :Table (encryption) - :Uid ("{97AEB629-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :http_netso_client () - :netso_selected_trusted_domains_list () - :private_ip_ranges ( - : ( - :AdminInfo ( - :chkpf_uid ("{64BC9ED6-414A-11D7-B538-7F0000014646}") - :ClassName (first_and_last_IP) - ) - :ipaddr_first (10.222.0.27) - :ipaddr_last (10.222.0.72) - ) - : ( - :AdminInfo ( - :chkpf_uid ("{64BCA2BE-414A-11D7-B538-7F0000014646}") - :ClassName (first_and_last_IP) - ) - :ipaddr_first (10.222.0.73) - :ipaddr_last (10.222.0.74) - ) - : ( - :AdminInfo ( - :chkpf_uid ("{64BCA660-414A-11D7-B538-7F0000014646}") - :ClassName (first_and_last_IP) - ) - :ipaddr_first (10.222.0.75) - :ipaddr_last (10.222.0.76) - ) - ) - :EnableUserMonitoring (false) - :GW_route_traffic_for_OM_address (false) - :IKE_wait4sync (2) - :IPSEC_SPI_alloc_max (ffff) - :IPSEC_SPI_alloc_min (100) - :PDU_sequence (16) - :SofawareLoader (SofawareLoader) - :VPN_configuration_mode (per_policy) - :accept_domain_tcp (false) - :accept_domain_udp (false) - :accept_fw1_connections (false) - :accept_icmp (false) - :accept_outgoing (false) - :accept_rip (false) - :acceptdecrypt (true) - :active_resolver (true) - :add_nt_groups (false) - :add_radius_groups (false) - :addresstrans (false) - :admin_lock_after_bad_attempts (3) - :admin_lock_after_bad_attempts_enable (false) - :admin_lock_auto_release_timeout (30) - :admin_lock_auto_release_timeout_enable (true) - :admin_lock_send_friendly_error_msg (true) - :adtr_skip_routing_msg (true) - :ahttpclientd_redirected_port () - :ahttpclientd_redirected_protocol () - :ahttpclientd_redirected_url () - :alertcertexpiry (432000) - :alertcmd () - :alertcmd_send_to_system_status (true) - :allow_PDU_sequence (false) - :allow_all_options (false) - :allow_clear_gettopo (false) - :allow_clear_traffic_while_disconnected (false) - :allow_encryption_outgoing_first (false) - :allow_h323_h245_tunneling (false) - :allow_h323_t120 (false) - :allow_h323_through_ras (false) - :allow_install_users_db_on_module (false) - :allow_remote_ra (false) - :allowed_suffix_for_internal_users ("OU=users,O=IsoAAAD.IsoAAAA-es.de..jnbkhk") - :as_failure_limit (5) - :as_radius_free_type (40) - :asm_synatk (false) - :asm_synatk_external_only (true) - :asm_synatk_log (log) - :asm_synatk_log_level (1) - :asm_synatk_threshold (200) - :asm_synatk_timeout (5) - :au_connect_timeout (10) - :au_timeout (15) - :auth_validity_days (14) - :auto_sync_on_install (true) - :auto_sync_on_save (false) - :auto_sync_scheduled (false) - :automatic_policy_update_frequency (10080) - :automatically_open_ca_rules (false) - :block_gtp_in_gtp (true) - :block_reverse_tcp (false) - :block_reverse_tcp_p (first) - :block_reverse_udp (false) - :block_reverse_udp_p (first) - :ca_matchbyname (false) - :ca_wait_mode (false) - :cert_req_ext_key_usage (0) - :cert_start_grace (7200) - :check_flow_labels (false) - :check_length (false) - :clauth_no_log_errors (false) - :clauth_no_resolve (false) - :clauth_tolower_users (false) - :client_max_auth_allowed (3) - :clnt_auth_msg () - :cluster_id_counter (7796) - :cluster_nburst (50) - :conn_limit_notify_interval (3600) - :conn_limit_reached_log (true) - :connections_hashsize (65536) - :connections_limit (25000) - :control_back_compatibility (false) - :cp_gw_default_profile () - :cpcufp_dont_clean_cache (false) - :cpcufp_hash_size (2048) - :cpcufp_timeout (300) - :cpridenable (true) - :cpridenable_p (first) - :create_version_on_install_policy (false) - :crl_end_grace (1800) - :crl_start_grace (1800) - :crlcache_timeout (86400) - :cvp_keep_alive (true) - :dagdhcpenable (true) - :dagdhcpenable_p (first) - :dataconn_pendingtimeout (60) - :dbload_program () - :default_installation (true) - :default_track (ReferenceObject - :Table (tracks) - :Name (AuthAlert) - :Uid ("{97AEB48B-9AEA-11D5-BD16-0090272CCB30}") - ) - :desktop_PS_HA (true) - :desktop_PS_LB (false) - :desktop_activate_ckp_scv (true) - :desktop_application_interception (true) - :desktop_authentication_timeout (60) - :desktop_build_number (0) - :desktop_build_number_9x (0) - :desktop_build_number_nt (0) - :desktop_build_number_w2k (0) - :desktop_cache_fwz_passwords (false) - :desktop_ike_hybrid_support (true) - :desktop_ike_ipcomp_support (true) - :desktop_ike_p2_prop (large) - :desktop_ike_p2_prop_size (small) - :desktop_ike_phase1_use_DH_group (ReferenceObject - :Name ("Group 2 (1024 bit)") - :Table (encryption) - :Uid ("{97AEB629-9AEA-11D5-BD16-0090272CCB30}") - ) - :desktop_ike_preshared_support (true) - :desktop_install_id_9x (0) - :desktop_install_id_nt (0) - :desktop_install_id_w2k (0) - :desktop_keep_alive (true) - :desktop_keep_alive_interval (20) - :desktop_password_expiry (120) - :desktop_perform_ckp_scv_merge (true) - :desktop_pol_frequency (0) - :desktop_policy_expire (60) - :desktop_post_connect_script () - :desktop_post_connect_script_show_window (false) - :desktop_retry_frequency (0) - :desktop_revert_to_backup (500) - :desktop_sda_implicit (false) - :desktop_sda_implicit_frequency (10080) - :desktop_security_non_ip_protocols (true) - :desktop_security_policy_code (2) - :desktop_security_policy_installed (true) - :desktop_security_protect_all_ifc (true) - :desktop_security_send_log (true) - :desktop_security_send_warning (true) - :desktop_silent_topo_update (false) - :desktop_site_default_tcp_ike (false) - :desktop_sw_url_path () - :desktop_sw_url_path_9x () - :desktop_sw_url_path_nt () - :desktop_sw_url_path_w2k () - :desktop_sw_version () - :desktop_to_expire_passwords (false) - :desktop_topology_over_IKE (true) - :desktop_update_at_start (false) - :desktop_update_frequency (0) - :disconnect_on_token_removal (false) - :domain_tcp (false) - :domain_tcp_p (first) - :domain_tcp_router (true) - :domain_tcp_router_p (first) - :domain_udp (false) - :domain_udp_p (first) - :domain_udp_router (true) - :domain_udp_router_p (first) - :dont_popup_hidden_folders_message (false) - :dontvalidatemycerts (false) - :download_community_properties_to_sbox (false) - :dynamic_objects_track (none) - :e2e_measure_interval (3000) - :e2e_poll_interval (5000) - :e2e_session_retrial_period (900) - :e2e_session_timeout (60000) - :e2e_sla_alert (log) - :e2e_statistics_interval (60) - :enable_active_conn_view (true) - :enable_automatic_policy_update (false) - :enable_if_resolving_third_party_clusters (false) - :enable_ip_options (true) - :enable_ip_pool (false) - :enable_ldap_queries (false) - :enable_mep_configuration (false) - :enable_objects_check (true) - :enable_propfind_method (false) - :enable_radius_queries (false) - :enable_remote_user_connect_logs (true) - :enable_reverse_connections (false) - :enable_ssh_conn_to_vpn1_net (false) - :enable_ssl_conn_to_vpn1_net (false) - :enable_tacacs_queries (false) - :enable_tcprpc (false) - :encrypt_dns (true) - :encryption_kernel_logging (true) - :encryption_rule_supports_ippool (false) - :enforce_desktop_config (false) - :enforce_install_on_all_cluster_objects (false) - :enforce_install_on_all_selected_objects (false) - :enforce_suffix_for_internal_users (true) - :entrustProtocolType (cms) - :entrust_renewal_limit (75) - :entrust_renewal_scan_period (0) - :established (true) - :established_p (first) - :established_router (true) - :established_router_p (first) - :export_pkg_on_install_policy (false) - :extranet_check_partners_status_interval (60) - :extranet_crl_grace_period (9000) - :fg_enable_multi_match (false) - :floodgate_preferences ( - :AdminInfo ( - :chkpf_uid ("{3E6FDEB4-414A-11D7-B738-7F0000010606}") - :ClassName (floodgate_properties) - ) - :auth_false_timeout (5) - :auth_query_timeout (3) - :auth_true_timeout (15) - :default_interface_rate (5898240) - :default_max_weight (1000) - :default_weight (10) - :llq_max_percent (20) - :rate_units (Bps) - :turn_on_logging (false) - ) - :flush_crl_cache_file_on_install (false) - :flush_crl_cache_on_install (true) - :force_encryption_on_all_users (false) - :force_udp_encapsulation_gw (false) - :ftp_allow_cmds_before_user (false) - :ftp_dont_accept_site_on_login (false) - :ftp_listen_timeout (3600) - :ftp_msg () - :ftp_msg_max_lines (100) - :ftp_use_cvp_reply_safe (false) - :ftp_use_fwnetso (true) - :ftpdata (true) - :ftppasv (true) - :fw1_enable_p (first) - :fw1enable (true) - :fw_allow_out_of_state_tcp (0) - :fw_clamp_tcp_mss (false) - :fw_dns_xlation (false) - :fw_drop_out_of_state_icmp (true) - :fw_drop_out_of_state_udp (true) - :fw_hmem_maxsize (30) - :fw_hmem_size (6) - :fw_ignore_session_rules (false) - :fw_light_verify (false) - :fw_listen_queue (200) - :fw_log_out_of_seq_tcp (true) - :fw_log_out_of_state_icmp (1) - :fw_log_out_of_state_other (0) - :fw_log_out_of_state_tcp (1) - :fw_log_out_of_state_udp (0) - :fw_salloc_total_alloc_limit (0) - :fwd_wait_for_child_up (true) - :fwfrag_limit (200) - :fwfrag_minsize (0) - :fwfrag_timeout (1) - :fwh323_allow_redirect (false) - :fwh323_force_src_phone (true) - :fwha_sync_outbound_sa (false) - :fwldap_ApplyPwdRulesOnMgmt (false) - :fwldap_CacheSize (1000) - :fwldap_CacheTimeout (900) - :fwldap_DisplayDN (display) - :fwldap_PasswordCheckMethod (1) - :fwldap_PasswordExpiration (90) - :fwldap_RequestTimeout (20) - :fwldap_SizeLimit (10000) - :fwldap_TemplateCacheSize (1000) - :fwldap_UseLDAP (false) - :fwldap_is_PasswordExpiration (false) - :fwldap_max_concurrent_queries (25) - :fwldap_num_of_retry (3) - :fwldap_server_down_time (60) - :fwldap_single_server_conf (false) - :fwldap_support_new_ObscureAuPw (false) - :fwsynatk_max (5000) - :fwsynatk_method (0) - :fwsynatk_timeout (10) - :fwsynatk_warning (1) - :fwurl_filter_pattern (".ida?") - :fwurl_filter_search_depth (0) - :fwurl_filter_url_left_len (0) - :fwurl_filter_url_total_len (0) - :fwz_encap_mtu (1) - :gatewaydir (eitherbound) - :generate_nat_log (true) - :genericd_use_fwnetso (true) - :gp_name () - :gp_type (none) - :gtp_allow_multi_if_ggsn (false) - :gtp_allow_recreate_pdpc (open) - :gtp_anti_spoofing (true) - :gtp_chk_hdr_len (true) - :gtp_code_alert (true) - :gtp_code_alert_p ("before last") - :gtp_delete_upon_error (false) - :gtp_echo_frequency (60) - :gtp_echo_requires_path_in_use (false) - :gtp_loggrace (10) - :gtp_match_any (true) - :gtp_max_req_retransmit (5) - :gtp_rate_limit_alert (true) - :gtp_rate_limit_drop (true) - :gtp_sam_close_upon_delete (false) - :gtp_sequence_deviation_alert (true) - :gtp_sequence_deviation_drop (false) - :gtp_track (log) - :h323_enforce_setup (false) - :h323_init_mem (true) - :h323_log_conn (true) - :h323_t120_timeout (3600) - :hclient_enable_new_interface (false) - :hide_alloc_attempts (50000) - :hide_ldap_size_limit_msg (false) - :hide_max_high_port (60000) - :hide_min_high_port (10000) - :hide_use_CP_GW_wizard (false) - :hide_wac_message (false) - :host_certs_key_size (1024) - :http_add_prev_connection_header (false) - :http_allow_content_disposition (false) - :http_allow_double_slash (false) - :http_allow_ranges (false) - :http_allow_store_reply (false) - :http_avoid_keep_alive (false) - :http_block_java_allow_chunked (false) - :http_block_non_http_response (false) - :http_buffers_size (4096) - :http_connection_method_proxy (false) - :http_connection_method_transparent (true) - :http_connection_method_tunneling (false) - :http_cvp_allow_chunked (false) - :http_disable_ahttpdhtml (false) - :http_disable_automatic_client_auth_redirect (false) - :http_disable_cab_check (false) - :http_disable_content_enc (false) - :http_disable_content_type (false) - :http_dns_cache_timeout (86400) - :http_dont_dns_when_star_port (false) - :http_dont_handle_next_proxy_pw (false) - :http_enable_resolve_by_ip (false) - :http_enable_uri_queries (true) - :http_failed_resolve_timeout (900) - :http_force_down_to_10 (0) - :http_handle_proxy_pw (true) - :http_header_detection ( - :AdminInfo ( - :chkpf_uid ("{29C31148-4E51-11D7-A39D-7F0000011616}") - :ClassName (http_header_detection) - ) - :http_header_names ( - : ( - :AdminInfo ( - :chkpf_uid ("{29C3142C-4E51-11D7-A39D-7F0000011616}") - :ClassName (http_header_pattern) - ) - :log_info () - :match_string (X-kazaa) - :pattern_mode (true) - :regular_exp (X-Kazaa) - ) - : ( - :AdminInfo ( - :chkpf_uid ("{29C31828-4E51-11D7-A39D-7F0000011616}") - :ClassName (http_header_pattern) - ) - :log_info () - :match_string (X-MSN-MESSENGER) - :pattern_mode (true) - :regular_exp (X-MSN-MESSENGER) - ) - ) - :http_header_names_values ( - : ( - :AdminInfo ( - :chkpf_uid ("{29C31C56-4E51-11D7-A39D-7F0000011616}") - :ClassName (http_header_pattern) - ) - :log_info (KaZaA) - :match_string (Server) - :pattern_mode (true) - :regular_exp ("[kK]a[zZ]a[aA]") - ) - : ( - :AdminInfo ( - :chkpf_uid ("{29C32034-4E51-11D7-A39D-7F0000011616}") - :ClassName (http_header_pattern) - ) - :log_info (KaZaA) - :match_string (Host) - :pattern_mode (true) - :regular_exp ("[kK]azaa") - ) - : ( - :AdminInfo ( - :chkpf_uid ("{29C32408-4E51-11D7-A39D-7F0000011616}") - :ClassName (http_header_pattern) - ) - :log_info (Gnutella) - :match_string (User-Agent) - :pattern_mode (true) - :regular_exp ("[gG]nu") - ) - : ( - :AdminInfo ( - :chkpf_uid ("{29C327E6-4E51-11D7-A39D-7F0000011616}") - :ClassName (http_header_pattern) - ) - :log_info ("AOL Messenger \ ICQ") - :match_string (User-Agent) - :pattern_mode (true) - :regular_exp ("Mozilla\/4\.08") - ) - : ( - :AdminInfo ( - :chkpf_uid ("{29C32BC4-4E51-11D7-A39D-7F0000011616}") - :ClassName (http_header_pattern) - ) - :log_info ("AOL Messenger \ ICQ") - :match_string (Server) - :pattern_mode (true) - :regular_exp (AIM) - ) - : ( - :AdminInfo ( - :chkpf_uid ("{29C32FA2-4E51-11D7-A39D-7F0000011616}") - :ClassName (http_header_pattern) - ) - :log_info ("ICQ \ AIM") - :match_string (Content-Type) - :pattern_mode (true) - :regular_exp (AIM) - ) - : ( - :AdminInfo ( - :chkpf_uid ("{29C33376-4E51-11D7-A39D-7F0000011616}") - :ClassName (http_header_pattern) - ) - :log_info ("Msn Messenger") - :match_string (User-Agent) - :pattern_mode (true) - :regular_exp (MSMSGS) - ) - : ( - :AdminInfo ( - :chkpf_uid ("{29C33740-4E51-11D7-A39D-7F0000011616}") - :ClassName (http_header_pattern) - ) - :log_info ("Yahoo Messenger") - :match_string (User-Agent) - :pattern_mode (true) - :regular_exp ("Mozilla\/4\.01") - ) - : ( - :AdminInfo ( - :chkpf_uid ("{29C33B14-4E51-11D7-A39D-7F0000011616}") - :ClassName (http_header_pattern) - ) - :log_info ("Msn Messenger") - :match_string (Content-Type) - :pattern_mode (true) - :regular_exp (x-msn-messenger) - ) - ) - :http_detect_header_pattern_log (alert) - :http_detect_header_pattern_mode (false) - ) - :http_log_every_connection (false) - :http_match_with_host_header (false) - :http_max_auth_password_num (1000) - :http_max_auth_redirect_num (1000) - :http_max_connection_num (4000) - :http_max_held_session_num (1000) - :http_max_realm_num (1000) - :http_max_server_num (10000) - :http_max_session_num (0) - :http_max_url_length (2048) - :http_next_proxy_host () - :http_next_proxy_port () - :http_no_content_length (false) - :http_old_auth_timeout (0) - :http_process_timeout (43200) - :http_proxied_connections_allowed (true) - :http_query_server_for_authorization (false) - :http_redirect_timeout (300) - :http_servers ( - :AdminInfo ( - :chkpf_uid ("{3E71410A-414A-11D7-B738-7F0000010606}") - :ClassName (http_servers) - ) - :ers () - ) - :http_session_timeout (300) - :http_skip_redirect_free (true) - :http_strict_url_parsing (true) - :http_use_cache_hdr (true) - :http_use_cvp_reply_safe (false) - :http_use_default_schemes (false) - :http_use_fwnetso (true) - :http_use_host_h_as_dst (false) - :http_use_proxy_auth_for_other (true) - :http_web_encoding (false) - :http_weeding_allow_chunked (false) - :ica_cert_op_timeout (120000) - :icmpcryptver (1) - :icmpenable (false) - :icmpenable_p ("before last") - :icmpenable_router (true) - :icmpenable_router_p ("before last") - :icmperrors (true) - :icmpreply (true) - :icmptimeout (30) - :ie_proxy_replacement (false) - :ie_proxy_replacement_limit_to_tcpt (true) - :ike_allow_unusual_id_types (false) - :ike_crash_recovery_dag (true) - :ike_crash_recovery_sr (true) - :ike_dos_max_puzzle_time_daip (500) - :ike_dos_max_puzzle_time_gw (500) - :ike_dos_max_puzzle_time_sr (5000) - :ike_dos_protection_identified_initiator (stateless) - :ike_dos_protection_unidentified_initiator (puzzles) - :ike_dos_puzzle_level_identified_initiator (19) - :ike_dos_puzzle_level_unidentified_initiator (19) - :ike_dos_supported_protection_sr (puzzles) - :ike_dos_threshold (70) - :ike_enable_dos_protection (false) - :ike_handle_initial_contact (true) - :ike_hybrid_force_preshared (false) - :ike_hybrid_user_timeout (0) - :ike_log_match_failure (true) - :ike_log_sr_match_failure (false) - :ike_negotiation_timeout (36) - :ike_nokia_crack_user_timeout (0) - :ike_send_initial_contact (false) - :ike_support_aes_128_p1 (false) - :ike_support_dos_protection (true) - :ike_support_nokia_crack (false) - :ike_support_nokia_internal_addr (false) - :ike_support_nokia_nat_traversal (false) - :ike_support_transport_mode (true) - :ike_use_largest_possible_subnets (true) - :imap_msg () - :implied_rule_for_gui_client_range (true) - :increase_hide_capacity (true) - :inform_site_changes (false) - :install_db_on_localhost (mgmt_only) - :interface_addr_anti_spoofing (true) - :ip_pool_log ("IP Exhaustion Log") - :ip_pool_securemote (false) - :ip_pool_unused_return_interval (60) - :ipoptslog (none) - :ipsec_disable_use_orig_if (false) - :isakmp.crlmaxsize (10000) - :isakmp.data.integrity (SHA1) - :isakmp.encryption (3DES) - :isakmp_buffer_recorder_size (256) - :isakmp_dh_exp (300) - :isakmp_force_sr_dh (false) - :isakmp_logging (true) - :isakmpphase1reneg (1440) - :isakmpphase2reneg (3600) - :isakmpphase2renegkbytes (0) - :keep_IKE_SAs (false) - :last_selected_community () - :lbalanced_load_history_percent (0) - :lbalanced_load_period_wakeup_sec (20) - :lbalanced_max_idle_measure_period (1200) - :lbalanced_period_wakeup_sec (30) - :lbalanced_roundtrip_history_percent (85) - :limited_broadcast_anti_spoofing (true) - :liveconns (false) - :load_program () - :load_service_port (18212) - :log_data_conns (false) - :log_default_rule (log) - :log_droped_non_ssl_v3 (true) - :log_established_tcp (true) - :log_implied_rules (true) - :log_ip_pool_allocation (none) - :log_keepalive_minute_to (300) - :log_scv_drops (log) - :log_ssh2_version (true) - :log_switch_size (10) - :loggrace (62) - :logical_servers_persistent_limit (25000) - :logical_servers_persistent_timeout (1800) - :logical_servers_resolve_redirect_url (false) - :logviewer_max_open_sessions_per_admin (5) - :logviewer_max_open_sessions_total (10) - :loopback_anti_spoofing (true) - :looptcp (true) - :looptcp_p (first) - :loopudp (true) - :loopudp_p (first) - :mail_disable_sendmail_CA2003_07 (false) - :mailcmd ("internal_sendmail -s alert -t mailer root") - :mailcmd_send_to_system_status (false) - :maintenance_notification (log) - :max_detail_view_community (7) - :max_num_negs (200) - :maxprocess (256) - :mdl_mismatch_action (ask) - :mdl_per_admin (false) - :mdq_error_mail_send_body (false) - :mdq_mx_ignore_nonauth_response (false) - :mdq_qp_encode_f (true) - :mdq_run_multi_threaded (true) - :mgmtha_active_management_check_period (60) - :mgmtha_alert_type (alert) - :multicast_anti_spoofing (true) - :nat_automatic_arp (true) - :nat_automatic_rules_merge (true) - :nat_dst_client_side (true) - :nat_dst_client_side_manual (false) - :nat_hashsize (16384) - :nat_limit (25000) - :netbios_nat (true) - :netso_trust_win_domains (all) - :network_addr_anti_spoofing (true) - :network_broadcast_anti_spoofing (true) - :new_ftp_interface (false) - :old_fwm_getkey_port (0) - :olderalertcmd () - :olderalertcmd_send_to_system_status (false) - :otherreply (false) - :othertimeout (60) - :outgoing (false) - :outgoing_p ("before last") - :page_timeout () - :pagetimeout (20) - :physical_server_availability_check_interval (20) - :physical_server_check_retries (3) - :pmap_connect_timeout (30) - :pop3_daemon () - :pop3_server () - :prefetch_crls_duration (7200) - :prefetch_crls_if_used_in_the_last_hours (24) - :prefetch_crls_if_used_more_then (1) - :prefetch_crls_on_install (true) - :problem_status_level (29) - :prompt_for_destination (false) - :psswd_min_length (6) - :psswd_min_num_of_lowercase (false) - :psswd_min_num_of_numbers (false) - :psswd_min_num_of_symbols (false) - :psswd_min_num_of_uppercase (false) - :r_access_enable_p (first) - :raccessenable (true) - :radius_connect_timeout (120) - :radius_groups_attr (25) - :radius_retrant_num (2) - :radius_retrant_timeout (5) - :radius_send_framed (false) - :radius_user_timeout (600) - :rate_limit_sampling_interval (1) - :reject_x11_in_any (true) - :remote_auth_group () - :remote_auth_server () - :renew_users_ica_cert (true) - :renew_users_ica_cert_days_before (60) - :resolve_interface_ranges (true) - :resolve_interface_ranges_GW (true) - :resolve_interface_ranges_nated_gw (false) - :resolver_1 ("sys (current system settings)") - :resolver_2 (none) - :resolver_3 (none) - :resolver_4 (none) - :resolver_session_interval (30) - :resolver_ttl (10) - :respawn_process_forever (true) - :respawn_process_interval (3600) - :restrict_fwm_to_gui_clients (true) - :retries (1) - :rip (false) - :rip_p (first) - :rip_router (true) - :rip_router_p (first) - :rlogin_max_auth_allowed (3) - :rlogin_msg () - :rlogin_use_fwnetso (true) - :rpcenable (true) - :rshstderr (false) - :rulebase_uids_in_log (false) - :sam_track (alert) - :save_as_assurance (false) - :save_assurance (false) - :scv_allow_4_1_clients (true) - :scv_client_connection_fail_on_notification (true) - :scv_client_diconnect_on_not_verified (true) - :scv_client_state_notification (silent) - :scv_gw_verify_only_mode (false) - :sdl_netlogon_timeout (0) - :secondary_auto_sync (true) - :secondary_sync_schedule () - :secure_update_package_sessions (10) - :securid_timeout (300) - :send_clear_except_for_address_group () - :send_clear_except_for_non_unique (false) - :send_clear_except_for_specific_addresses (false) - :send_clear_traffic_between_encryption_domains (false) - :session_max_auth_allowed (3) - :show_comm_rules (false) - :show_default_policy_message (false) - :show_old_install_policy (false) - :show_rule_column_through (false) - :show_wac_tab (false) - :show_what_is_new (true) - :silent_policy_update (false) - :silent_update_on_connect (false) - :sip_accept_unknown_messages (false) - :sip_allow_instant_messages (false) - :sip_allow_redirect (true) - :sip_allow_two_media_conns (false) - :sip_enforce_security_reinvite (true) - :sip_max_reinvite (3) - :skey_mdmethod (md4) - :skip_automatic_policy_update_if_authentication_required (true) - :smtp_allow_extended_relay (false) - :smtp_encoded_content_field (false) - :smtp_enforce_hex_encoding (true) - :smtp_exact_str_match (false) - :smtp_force_no_uu_begin_after_decode (true) - :smtp_force_no_uu_begin_before_decode (true) - :smtp_force_no_uu_begin_in_prolog_epilog (true) - :smtp_force_sender_domain (false) - :smtp_force_uu_syntax_check (true) - :smtp_limit_content_buf_size (true) - :smtp_mail_encoding (false) - :smtp_max_file_name_length (512) - :smtp_max_global_headers_size (32768) - :smtp_max_user_name_length (400) - :smtp_msg () - :smtp_rfc821 (true) - :smtp_rfc822 (true) - :smtp_strict_mime_header (true) - :sn_connect_timeout (10) - :sn_timeout (120) - :snauth_old_clients_message () - :snauth_protocol () - :snk_agent_id () - :snk_agent_key () - :snk_server_bkp_ip () - :snk_server_ip () - :snk_timeout (20) - :snmptrapcmd ("internal_snmp_trap localhost") - :snmptrapcmd_send_to_system_status (false) - :sofaware_gw_default_profile () - :spoofalertcmd () - :spoofalertcmd_send_to_system_status (true) - :sr_dont_check_crl (false) - :sr_grace_period (3600) - :sr_same_ip_block (false) - :sr_same_ip_log (true) - :stack_size (0) - :status_mgr_interval_seconds (60) - :stop_connect_when_silent_update_fails (false) - :strip_java (false) - :support_sofaware_HML (false) - :support_sofaware_profiles (true) - :suppress_dont_echo (false) - :sync_archive_timeout (1800) - :sync_outbound_sa_pkt_count (200000) - :tcp_reject (true) - :tcpendtimeout (50) - :tcpestb_grace_period (0) - :tcpstarttimeout (60) - :tcpt_outgoing_port (443) - :tcptimeout (3600) - :telnet_max_auth_allowed (3) - :telnet_msg () - :telnet_use_fwnetso (true) - :timeout (10) - :totally_disable_VPE (false) - :trust_all_capi_trusted_root_cas (false) - :type (firewall_properties) - :udp_encapsulation_by_qm_id (true) - :udp_reject (true) - :udpreply (true) - :udpreply_from_any_port (false) - :udptimeout (40) - :ufp_stat_log_time_interval (10) - :undo_msg (false) - :unify_ctl_data_acct_logs (false) - :upgrade_fp1_and_below_users_ica_cert (true) - :use_CP_GW_wizard (false) - :use_default_gw_profiles (false) - :use_desktop_profile (true) - :use_sites (false) - :use_zero_buf_len (false) - :user_certs_key_size (1024) - :useralert2cmd () - :useralert2cmd_send_to_system_status (true) - :useralert3cmd () - :useralert3cmd_send_to_system_status (true) - :useralertcmd () - :useralertcmd_send_to_system_status (true) - :userc_IKE_NAT (true) - :userc_NAT (true) - :userc_bind_user_to_IP (false) - :userc_crypt_ver (1) - :validate_desktop_security (false) - :version_directory_clear_internal (360) - :version_directory_keep_open (4320) - :vlog_switch_size (10) - :voip_allow_no_from (false) - :vpn_conf_n_key_exch_prob (log) - :vpn_log_spi_release (false) - :vpn_packet_handle_prob (log) - :vpn_peer_ls (false) - :vpn_peer_ls_GW (false) - :vpn_restrict_client_phase2_id (none) - :vpn_success_key_exch (log) - :vpn_tables_early_def (false) - :vpnddcate_nat (none) - :vpnddcate_policy (outbound_and_encrypted) - :vpnddcate_track_accept (log) - :vpnddcate_track_drop (log) - :warn_install_fg_pre_ng (false) - :warn_install_pseudo_rules (true) - :warncertexpiry (2592000) - :write_acct_to_db (false) - ) - ) - :opsec () - :graph_objects ( - : (internet - :AdminInfo ( - :chkpf_uid ("{3A201FF7-D304-4AB4-8913-9F6F86599A64}") - :ClassName (internet_cloud) - :table (graph_objects) - :Wiznum (-1) - :object_permissions ( - :AdminInfo ( - :chkpf_uid ("{C19017E4-6B08-4129-9332-00F269C88EC6}") - :ClassName (object_permissions) - ) - :manage ( - : (ReferenceObject - :Table (globals) - :Name (Any) - ) - ) - :read ( - : (any) - ) - :use ( - : (any) - ) - :write ( - : () - ) - :owner () - ) - :LastModified ( - :Time ("Sun Feb 16 01:18:13 2003") - :By (IsoAAAF) - :From (scratchy) - ) - ) - :color (blue) - :comments () - :type (internet_cloud) - ) - : (Implied - :AdminInfo ( - :chkpf_uid ("{3ACFA416-22F8-4429-8721-D1CF97E3E3E0}") - :ClassName (provisory_network) - :table (graph_objects) - :Wiznum (-1) - :object_permissions ( - :AdminInfo ( - :chkpf_uid ("{81B5D575-621B-4DCA-BBC9-17B6804317D6}") - :ClassName (object_permissions) - ) - :manage ( - : (ReferenceObject - :Table (globals) - :Name (Any) - ) - ) - :read ( - : (any) - ) - :use ( - : (any) - ) - :write ( - : () - ) - :owner () - ) - :LastModified ( - :Time ("Sun Feb 16 01:18:13 2003") - :By (IsoAAAF) - :From (scratchy) - ) - ) - :edges () - :NAT () - :add_adtr_rule (false) - :broadcast (allow) - :color (black) - :comments ("Created by Topology View") - :ipaddr (10.222.0.43) - :location (internal) - :netmask (255.255.255.255) - :operating_system ( - :AdminInfo ( - :chkpf_uid ("{D53BBC4E-3283-4015-9CE4-FFB9586C5970}") - :ClassName (operating_system) - ) - :name () - :sp () - :version () - ) - :type (provisory_network) - ) - : (Disconnected_Objects - :AdminInfo ( - :chkpf_uid ("{305AEB18-78DA-4726-952B-2E6F8088291B}") - :ClassName (folder) - :table (graph_objects) - :Wiznum (-1) - :LastModified ( - :Time ("Thu Apr 1 17:09:19 2004") - :By (holger) - :From (dragonfly) - ) - ) - :color (40) - :comments () - :displayname ("Disconnected Objects") - :foldtype () - :source () - :type (folder) - ) - : (IsoAAAD_locale - :AdminInfo ( - :chkpf_uid ("{FC938747-B0AF-43CA-9406-1877F73AF477}") - :ClassName (folder) - :table (graph_objects) - :Wiznum (-1) - :LastModified ( - :Time ("Fri Apr 9 11:56:31 2004") - :By (IsoAAAF) - :From (scratchy) - ) - ) - :color (40) - :comments () - :displayname ("IsoAAAD locale") - :foldtype ("Fold all") - :source (ReferenceObject - :Name (IsoAAAD) - :Table (network_objects) - :Uid ("{29C40B0A-414C-11D7-AEB8-7F0000013C3C}") - ) - :type (folder) - ) - ) - :keys () - :svn () - :ce_properties () - :customers () - :accounting_schemes () - :statuses () - :securemote () - :credentials_manager () - :desktop_profiles () - :cp_administrators ( - : (guitest - :AdminInfo ( - :chkpf_uid ("{37594F54-C38A-4C4F-969D-6911FC311ECD}") - :ClassName (administrator_profile) - :table (cp_administrators) - :Wiznum (-1) - :LastModified ( - :Time ("Tue Jul 15 16:01:38 2003") - :By (stephan) - :From (vaio) - ) - ) - :LDAP_users_database (true) - :LDAP_users_database_permissions (read_and_write) - :QoS_policy (true) - :QoS_policy_permissions (read_and_write) - :check_point_users_database (true) - :check_point_users_database_permissions (read_and_write) - :color (black) - :comments ("zum wegwerfen") - :gateway_profiles (true) - :gateway_profiles_permissions (read_and_write) - :log_consolidator (true) - :log_consolidator_permissions (read_and_write) - :manage_administrators (true) - :monitoring (true) - :monitoring_permissions (read_and_write) - :objects_database (true) - :objects_database_permissions (read_and_write) - :permissions (read_and_write_all) - :reporting_tool (true) - :reporting_tool_permissions (read_and_write) - :secure_update (true) - :secure_update_permissions (read_and_write) - :security_policies (true) - :security_policies_permissions (read_and_write) - :type (administrator_profile) - :web_access (true) - :web_access_permissions (read_and_write) - :web_security (true) - :web_security_permissions (read_and_write) - ) - : (remotezugriff - :AdminInfo ( - :chkpf_uid ("{562674AF-B351-4239-9EBF-EA556F511C12}") - :ClassName (administrator_profile) - :table (cp_administrators) - :Wiznum (-1) - :LastModified ( - :Time ("Tue Jul 15 16:03:47 2003") - :By (stephan) - :From (vaio) - ) - ) - :LDAP_users_database (true) - :LDAP_users_database_permissions (read_and_write) - :QoS_policy (true) - :QoS_policy_permissions (read_and_write) - :check_point_users_database (true) - :check_point_users_database_permissions (read_and_write) - :color (black) - :comments () - :gateway_profiles (true) - :gateway_profiles_permissions (read_and_write) - :log_consolidator (true) - :log_consolidator_permissions (read_and_write) - :manage_administrators (true) - :monitoring (true) - :monitoring_permissions (read_and_write) - :objects_database (true) - :objects_database_permissions (read_and_write) - :permissions (read_and_write_all) - :reporting_tool (true) - :reporting_tool_permissions (read_and_write) - :secure_update (true) - :secure_update_permissions (read_and_write) - :security_policies (true) - :security_policies_permissions (read_and_write) - :type (administrator_profile) - :web_access (true) - :web_access_permissions (read_and_write) - :web_security (true) - :web_security_permissions (read_and_write) - ) - ) - :trusts () - :web_authority_must_rules () - :web_authority_allow_rules () - :web_authority_effect_rules () - :web_authority_URLs () - :web_sites () - :external_exported_domains () -) diff --git a/roles/sample-data/files/sample-configs/checkpoint_demo/rulebases_5_0.fws b/roles/sample-data/files/sample-configs/checkpoint_demo/rulebases_5_0.fws deleted file mode 100644 index a8d57dbfa6..0000000000 --- a/roles/sample-data/files/sample-configs/checkpoint_demo/rulebases_5_0.fws +++ /dev/null @@ -1,14750 +0,0 @@ -( - :version (5.41) - :rule-base ("##Standard" - :AdminInfo ( - :chkpf_uid ("{2E31C33C-79BB-43EF-AF63-BAEBD8BDEAED}") - :ClassName (firewall_policy) - :table (fw_policies) - :object_permissions ( - :AdminInfo ( - :chkpf_uid ("{16F8DFA4-A2B9-4B94-ADD0-66B7AD44210F}") - :ClassName (object_permissions) - ) - :manage ( - : (ReferenceObject - :Table (globals) - :Name (Any) - ) - ) - :read ( - : (any) - ) - :use ( - : (any) - ) - :write ( - : () - ) - :owner () - ) - :LastModified ( - :Time ("Sun Feb 16 01:18:23 2003") - :By (IsoAAAF) - :From (scratchy) - ) - ) - :queries () - :queries_adtr () - :collection (ReferenceObject - :Name (Standard) - :Table (policies_collections) - :Uid ("{2E49485A-61E2-4F55-A71C-85B9BF5CD9E1}") - ) - :default (0) - :use_VPN_communities (true) - ) - :rule-base ("##IsoAAAA_Simplified" - :AdminInfo ( - :chkpf_uid ("{3FABC5DB-B9FF-4100-BD75-FBC1DD43AF93}") - :ClassName (firewall_policy) - :table (fw_policies) - :LastModified ( - :Time ("Mon Jan 24 13:50:53 2005") - :By (IsoAAAF) - :From (IsoAAADray) - ) - ) - :default (0) - :queries () - :queries_adtr () - :collection (ReferenceObject - :Name (IsoAAAA_Simplified) - :Table (policies_collections) - :Uid ("{26FF70B8-9599-49B4-B6F6-84B7AE0D2EBB}") - ) - :rule ( - :AdminInfo ( - :chkpf_uid ("{A4029F61-9672-4AA3-B1D9-0FF4E8979971}") - :ClassName (security_header_rule) - ) - :action ( - : (drop - :AdminInfo ( - :chkpf_uid ("{5EE13032-A1E1-4538-90BC-6295FD3DFE04}") - :ClassName (drop_action) - :table (setup) - ) - :action () - :macro () - :type (drop) - ) - ) - :comments () - :global_location (middle) - :through ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :time ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :track ( - : (ReferenceObject - :Name (None) - :Table (tracks) - :Uid ("{97AEB47D-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :disabled (true) - :dst ( - :AdminInfo ( - :chkpf_uid ("{5560B804-6408-442F-903B-2B279AE6D9C2}") - :ClassName (rule_destination) - ) - :compound () - :op () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :header_text (test-rules) - :install ( - :AdminInfo ( - :chkpf_uid ("{0B1EB683-1A59-44FF-901C-5FDB9EA65A5E}") - :ClassName (rule_install) - ) - :compound () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :services ( - :AdminInfo ( - :chkpf_uid ("{F8D6F7F5-4582-4256-A0A5-EBFDDB2EF590}") - :ClassName (rule_services) - ) - :compound () - :op () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :src ( - :AdminInfo ( - :chkpf_uid ("{AF27380F-6548-4B83-81FD-1B5EAECAA8F6}") - :ClassName (rule_source) - ) - :compound () - :op () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :state (expanded) - ) - :rule ( - :AdminInfo ( - :chkpf_uid ("{ABC6E209-A440-42E2-A896-CF27A1CA2744}") - :ClassName (security_rule) - ) - :action ( - : (accept - :AdminInfo ( - :chkpf_uid ("{F09D1F04-CBE0-4E12-9454-54CCECE01A9B}") - :ClassName (accept_action) - :table (setup) - ) - :action () - :macro (RECORD_CONN) - :type (accept) - ) - ) - :global_location (middle) - :through ( - : (ReferenceObject - :Name (RemoteAccess) - :Table (communities) - :Uid ("{97AEB677-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :time ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :track ( - : (ReferenceObject - :Name (Log) - :Table (tracks) - :Uid ("{97AEB480-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :comments (vpn_test) - :disabled (true) - :dst ( - :AdminInfo ( - :chkpf_uid ("{65F39402-76F2-45CC-A99C-0903FE70DF4C}") - :ClassName (rule_destination) - ) - :compound () - :op () - : (ReferenceObject - :Name (IsoAAADray.local) - :Table (network_objects) - :Uid ("{75EDBC62-7EB1-4D37-8295-684903FDA75A}") - ) - ) - :install ( - :AdminInfo ( - :chkpf_uid ("{C6DE2209-1A7B-4FCC-B7A7-A1D4EDD793D7}") - :ClassName (rule_install) - ) - :compound () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :services ( - :AdminInfo ( - :chkpf_uid ("{91BC0FDA-33F0-49D8-BC63-FFA85CBAFD40}") - :ClassName (rule_services) - ) - :compound () - :op () - : (ReferenceObject - :Name (NBT) - :Table (services) - :Uid ("{97AEB471-9AEA-11D5-BD16-0090272CCB30}") - ) - : (ReferenceObject - :Name (icmp-requests) - :Table (services) - :Uid ("{97AEB413-9AEA-11D5-BD16-0090272CCB30}") - ) - : (ReferenceObject - :Name (CIFS) - :Table (services) - :Uid ("{2A469820-B502-434C-9340-A377677A6A60}") - ) - : (ReferenceObject - :Name (rdp) - :Table (services) - :Uid ("{5BA0C83F-8D91-465B-9CF6-7DC6AEB84689}") - ) - ) - :src ( - :AdminInfo ( - :chkpf_uid ("{28C21DCF-D0A0-4F40-8017-BCD946EFF41D}") - :ClassName (rule_source) - ) - :compound ( - : (vpn_user@heag_off_upper - :AdminInfo ( - :chkpf_uid ("{ABBA5C5D-AE07-4CF6-A00E-3649064D0BDB}") - :ClassName (rule_user_group) - ) - :at (ReferenceObject - :Name (heag_off_upper) - :Table (network_objects) - :Uid ("{A58E3E67-0517-485F-AA04-97A12BC119C3}") - ) - :color (black) - :type (usrgroup) - ) - ) - :op () - ) - ) - :rule ( - :AdminInfo ( - :chkpf_uid ("{5AFB86A5-E247-411F-AAD7-A8EFDE97A0F5}") - :ClassName (security_rule) - ) - :action ( - : (accept - :AdminInfo ( - :chkpf_uid ("{150ABA94-098B-4CC3-AF8A-BDFED81FC20E}") - :ClassName (accept_action) - :table (setup) - ) - :action () - :macro (RECORD_CONN) - :type (accept) - ) - ) - :comments () - :global_location (middle) - :through ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :time ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :track ( - : (ReferenceObject - :Name (Log) - :Table (tracks) - :Uid ("{97AEB480-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :disabled (true) - :dst ( - :AdminInfo ( - :chkpf_uid ("{5526AF1C-6E4F-4F71-A58E-A1E5F88B62DB}") - :ClassName (rule_destination) - ) - :compound () - :op () - : (ReferenceObject - :Name (Premier_Access) - :Table (network_objects) - :Uid ("{B2BB20AA-B685-426B-96B6-1FB4D8D05135}") - ) - : (ReferenceObject - :Name (IsoAAAD) - :Table (network_objects) - :Uid ("{29C40B0A-414C-11D7-AEB8-7F0000013C3C}") - ) - ) - :install ( - :AdminInfo ( - :chkpf_uid ("{7F41F235-2373-4F38-9141-29AB9CEAD2D8}") - :ClassName (rule_install) - ) - :compound () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :services ( - :AdminInfo ( - :chkpf_uid ("{C2DE3BB7-C1B7-49C9-BC21-97AB3CE81521}") - :ClassName (rule_services) - ) - :compound () - :op () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :src ( - :AdminInfo ( - :chkpf_uid ("{F8ECC436-D19B-4124-9BC3-31C1E3945A36}") - :ClassName (rule_source) - ) - :compound () - :op () - : (ReferenceObject - :Name (IsoAAAD) - :Table (network_objects) - :Uid ("{29C40B0A-414C-11D7-AEB8-7F0000013C3C}") - ) - : (ReferenceObject - :Name (Premier_Access) - :Table (network_objects) - :Uid ("{B2BB20AA-B685-426B-96B6-1FB4D8D05135}") - ) - ) - ) - :rule ( - :AdminInfo ( - :chkpf_uid ("{38429C3B-05FE-49C8-9D8C-83F0AC9661CD}") - :ClassName (security_rule) - ) - :action ( - : (accept - :AdminInfo ( - :chkpf_uid ("{10F8BCF5-D4DD-4ACA-BEC3-1058298A9015}") - :ClassName (accept_action) - :table (setup) - ) - :action () - :macro (RECORD_CONN) - :type (accept) - ) - ) - :global_location (middle) - :through ( - : (ReferenceObject - :Name (RemoteAccess) - :Table (communities) - :Uid ("{97AEB677-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :time ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :track ( - : (ReferenceObject - :Name (Log) - :Table (tracks) - :Uid ("{97AEB480-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :comments ("RAS - Test mit Premier-Access - Tokens") - :disabled (true) - :dst ( - :AdminInfo ( - :chkpf_uid ("{FEABA989-54EB-4D53-96C9-6841B9BBEB4B}") - :ClassName (rule_destination) - ) - :compound () - :op () - : (ReferenceObject - :Name (IsoAAAA-100) - :Table (network_objects) - :Uid ("{BF1C6029-8D5D-4A05-A3AD-4B67E6E7A7AA}") - ) - : (ReferenceObject - :Name (IsoAAAD) - :Table (network_objects) - :Uid ("{29C40B0A-414C-11D7-AEB8-7F0000013C3C}") - ) - ) - :install ( - :AdminInfo ( - :chkpf_uid ("{162F84EF-286D-4D55-B03F-8DC9F535553A}") - :ClassName (rule_install) - ) - :compound () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :services ( - :AdminInfo ( - :chkpf_uid ("{130A495D-1435-441B-98CE-993791EBDA7A}") - :ClassName (rule_services) - ) - :compound () - :op () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :src ( - :AdminInfo ( - :chkpf_uid ("{766EEA30-3B32-455D-A951-52D75F93E1D9}") - :ClassName (rule_source) - ) - :compound ( - : (test@Any - :AdminInfo ( - :chkpf_uid ("{C8439795-0347-401E-9663-4EBE924B0F4B}") - :ClassName (rule_user_group) - ) - :at (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - :color (black) - :type (usrgroup) - ) - ) - :op () - ) - ) - :rule ( - :AdminInfo ( - :chkpf_uid ("{24DC38E2-D64D-40EC-B81B-BE3B27A12CED}") - :ClassName (security_header_rule) - ) - :action ( - : (drop - :AdminInfo ( - :chkpf_uid ("{23D057DA-D1AB-4FFD-B61A-806648650D75}") - :ClassName (drop_action) - :table (setup) - ) - :action () - :macro () - :type (drop) - ) - ) - :comments () - :global_location (middle) - :through ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :time ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :track ( - : (ReferenceObject - :Name (None) - :Table (tracks) - :Uid ("{97AEB47D-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :disabled (true) - :dst ( - :AdminInfo ( - :chkpf_uid ("{690BE832-509A-4F4D-A0A2-C9E665129607}") - :ClassName (rule_destination) - ) - :compound () - :op () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :header_text ("IsoAAAE SecuRemote") - :install ( - :AdminInfo ( - :chkpf_uid ("{67EE9042-BF3D-4971-8346-FA36156A5F74}") - :ClassName (rule_install) - ) - :compound () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :services ( - :AdminInfo ( - :chkpf_uid ("{4C231AF1-095C-4CAA-A12C-2EA5B88E76B9}") - :ClassName (rule_services) - ) - :compound () - :op () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :src ( - :AdminInfo ( - :chkpf_uid ("{F23B90BB-44A6-4F7D-8573-48E730D231EE}") - :ClassName (rule_source) - ) - :compound () - :op () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :state (expanded) - ) - :rule ( - :AdminInfo ( - :chkpf_uid ("{4D877153-65A8-48A9-9D11-B30CA56946EF}") - :ClassName (security_rule) - ) - :action ( - : (accept - :AdminInfo ( - :chkpf_uid ("{D47EFCCA-13C6-4057-A28A-42DD438E32E4}") - :ClassName (accept_action) - :table (setup) - ) - :action () - :macro (RECORD_CONN) - :type (accept) - ) - ) - :comments () - :disabled (false) - :global_location (middle) - :through ( - : (ReferenceObject - :Name (RemoteAccess) - :Table (communities) - :Uid ("{97AEB677-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :time ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :track ( - : (ReferenceObject - :Name (Log) - :Table (tracks) - :Uid ("{97AEB480-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :dst ( - :AdminInfo ( - :chkpf_uid ("{C2778755-3B4C-491C-85A7-E4523035CD2B}") - :ClassName (rule_destination) - ) - :compound () - :op () - : (ReferenceObject - :Name (IsoAAADray.local) - :Table (network_objects) - :Uid ("{75EDBC62-7EB1-4D37-8295-684903FDA75A}") - ) - : (ReferenceObject - :Name (gateway.local) - :Table (network_objects) - :Uid ("{7ED7EF12-A13E-4303-8A6E-C6CC28755C80}") - ) - ) - :install ( - :AdminInfo ( - :chkpf_uid ("{CA2D51EE-4A3F-4FE8-B21C-6532E9E7D2C6}") - :ClassName (rule_install) - ) - :compound () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :services ( - :AdminInfo ( - :chkpf_uid ("{5D51CCD0-95A5-408B-83C0-6F18D2B9A460}") - :ClassName (rule_services) - ) - :compound () - :op () - : (ReferenceObject - :Name (CIFS) - :Table (services) - :Uid ("{2A469820-B502-434C-9340-A377677A6A60}") - ) - : (ReferenceObject - :Name (rdp) - :Table (services) - :Uid ("{5BA0C83F-8D91-465B-9CF6-7DC6AEB84689}") - ) - : (ReferenceObject - :Name (ntp-udp) - :Table (services) - :Uid ("{97AEB404-9AEA-11D5-BD16-0090272CCB30}") - ) - : (ReferenceObject - :Name (domain-udp) - :Table (services) - :Uid ("{97AEB3FA-9AEA-11D5-BD16-0090272CCB30}") - ) - : (ReferenceObject - :Name (http) - :Table (services) - :Uid ("{97AEB3D4-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :src ( - :AdminInfo ( - :chkpf_uid ("{3B379A82-34F3-4A23-B77C-B50EAD80BD53}") - :ClassName (rule_source) - ) - :compound ( - : (Cactus-extern@vpn-sources-IsoAAAA - :AdminInfo ( - :chkpf_uid ("{C7F9820A-4EDD-4187-98D9-CC655885E0D6}") - :ClassName (rule_user_group) - ) - :at (ReferenceObject - :Name (vpn-sources-IsoAAAA) - :Table (network_objects) - :Uid ("{26405A41-425C-4053-8002-497BB82D76B1}") - ) - :color (black) - :type (usrgroup) - ) - ) - :op () - ) - ) - :rule ( - :AdminInfo ( - :chkpf_uid ("{AC6B21DA-86AF-4EB3-B294-3387F815E66E}") - :ClassName (security_rule) - ) - :action ( - : (accept - :AdminInfo ( - :chkpf_uid ("{145513B1-FB45-4B30-9B14-5C07AF404141}") - :ClassName (accept_action) - :table (setup) - ) - :action () - :macro (RECORD_CONN) - :type (accept) - ) - ) - :comments () - :disabled (false) - :global_location (middle) - :through ( - : (ReferenceObject - :Name (RemoteAccess) - :Table (communities) - :Uid ("{97AEB677-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :time ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :track ( - : (ReferenceObject - :Name (Log) - :Table (tracks) - :Uid ("{97AEB480-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :dst ( - :AdminInfo ( - :chkpf_uid ("{B7130E5B-C62A-4BEF-A2B3-3A2306AE0E5A}") - :ClassName (rule_destination) - ) - :compound () - :op () - : (ReferenceObject - :Name (scratchy.local) - :Table (network_objects) - :Uid ("{CFABE50C-C1F6-4FF1-8AC3-3161A3779708}") - ) - ) - :install ( - :AdminInfo ( - :chkpf_uid ("{58B74533-737D-4182-B405-F3EAC537960A}") - :ClassName (rule_install) - ) - :compound () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :services ( - :AdminInfo ( - :chkpf_uid ("{115D6863-5E76-4339-B76F-8AF7B421C12F}") - :ClassName (rule_services) - ) - :compound () - :op () - : (ReferenceObject - :Name (RAdmin-custom) - :Table (services) - :Uid ("{4FB59153-8212-4A12-BC08-0297AA5F0815}") - ) - ) - :src ( - :AdminInfo ( - :chkpf_uid ("{4400E028-7BB5-405F-AE2C-CE84535C3D32}") - :ClassName (rule_source) - ) - :compound ( - : (IsoAAAG-g@vpn-sources-IsoAAAA - :AdminInfo ( - :chkpf_uid ("{23622C19-C400-4C6D-9BCA-E69C2217DE8E}") - :ClassName (rule_user_group) - ) - :at (ReferenceObject - :Name (vpn-sources-IsoAAAA) - :Table (network_objects) - :Uid ("{26405A41-425C-4053-8002-497BB82D76B1}") - ) - :color (black) - :type (usrgroup) - ) - ) - :op () - ) - ) - :rule ( - :AdminInfo ( - :chkpf_uid ("{73F2144F-4C58-4361-94B5-459B469A6541}") - :ClassName (security_rule) - ) - :action ( - : (accept - :AdminInfo ( - :chkpf_uid ("{C72BC9F4-E1B5-4701-AA37-780742F76043}") - :ClassName (accept_action) - :table (setup) - ) - :action () - :macro (RECORD_CONN) - :type (accept) - ) - ) - :comments () - :disabled (false) - :global_location (middle) - :through ( - : (ReferenceObject - :Name (RemoteAccess) - :Table (communities) - :Uid ("{97AEB677-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :time ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :track ( - : (ReferenceObject - :Name (Log) - :Table (tracks) - :Uid ("{97AEB480-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :dst ( - :AdminInfo ( - :chkpf_uid ("{8D75B038-29A6-4DFC-99BE-77BB50F0248D}") - :ClassName (rule_destination) - ) - :compound () - :op () - : (ReferenceObject - :Name (spike.local) - :Table (network_objects) - :Uid ("{4ABDD8DE-0DA2-46E5-B129-85E3977CBD18}") - ) - : (ReferenceObject - :Name (mg.IsoAAAA-es.com) - :Table (network_objects) - :Uid ("{E5BF8260-3615-4476-B638-53CA3A24FEF1}") - ) - ) - :install ( - :AdminInfo ( - :chkpf_uid ("{64D010BF-D0CB-4F9F-9B7A-DBAD17892364}") - :ClassName (rule_install) - ) - :compound () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :services ( - :AdminInfo ( - :chkpf_uid ("{A9590BAB-F46F-4EB7-8125-A4EE6791DD5F}") - :ClassName (rule_services) - ) - :compound () - :op () - : (ReferenceObject - :Name (squid) - :Table (services) - :Uid ("{91C0454D-F70C-44B3-8F2D-70C4A68E9594}") - ) - : (ReferenceObject - :Name (imap) - :Table (services) - :Uid ("{97AEB446-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :src ( - :AdminInfo ( - :chkpf_uid ("{32C8D43F-D47D-4477-9217-8E249CBA8F9E}") - :ClassName (rule_source) - ) - :compound ( - : (Cactus-extern@vpn-sources-IsoAAAA - :AdminInfo ( - :chkpf_uid ("{93AC11B4-FFD0-4DBB-BA60-321FE5E9AD32}") - :ClassName (rule_user_group) - ) - :at (ReferenceObject - :Name (vpn-sources-IsoAAAA) - :Table (network_objects) - :Uid ("{26405A41-425C-4053-8002-497BB82D76B1}") - ) - :color (black) - :type (usrgroup) - ) - ) - :op () - ) - ) - :rule ( - :AdminInfo ( - :chkpf_uid ("{6ADC5431-5B24-47FC-A9A6-F8DC912B0515}") - :ClassName (security_rule) - ) - :action ( - : (accept - :AdminInfo ( - :chkpf_uid ("{BE23F2AE-BA4F-443C-9F3C-8742F71262A5}") - :ClassName (accept_action) - :table (setup) - ) - :action () - :macro (RECORD_CONN) - :type (accept) - ) - ) - :comments () - :disabled (false) - :global_location (middle) - :through ( - : (ReferenceObject - :Name (RemoteAccess) - :Table (communities) - :Uid ("{97AEB677-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :time ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :track ( - : (ReferenceObject - :Name (Log) - :Table (tracks) - :Uid ("{97AEB480-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :dst ( - :AdminInfo ( - :chkpf_uid ("{586E9FDE-3504-4C3C-B1B3-A73F6D3F379B}") - :ClassName (rule_destination) - ) - :compound () - :op () - : (ReferenceObject - :Name (itchy) - :Table (network_objects) - :Uid ("{3B4DF852-5064-4957-B95F-D469C5656467}") - ) - ) - :install ( - :AdminInfo ( - :chkpf_uid ("{067D0452-9D33-44EA-8433-DF53F0333503}") - :ClassName (rule_install) - ) - :compound () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :services ( - :AdminInfo ( - :chkpf_uid ("{656EA975-486E-43AA-B73C-209ED71366BC}") - :ClassName (rule_services) - ) - :compound () - :op () - : (ReferenceObject - :Name (smtp) - :Table (services) - :Uid ("{97AEB3D9-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :src ( - :AdminInfo ( - :chkpf_uid ("{028E2317-59C3-4783-AFA3-8121A808F9D8}") - :ClassName (rule_source) - ) - :compound ( - : (Cactus-extern@vpn-sources-IsoAAAA - :AdminInfo ( - :chkpf_uid ("{3D633953-A379-43C2-BCD5-CFCE90A8F60D}") - :ClassName (rule_user_group) - ) - :at (ReferenceObject - :Name (vpn-sources-IsoAAAA) - :Table (network_objects) - :Uid ("{26405A41-425C-4053-8002-497BB82D76B1}") - ) - :color (black) - :type (usrgroup) - ) - ) - :op () - ) - ) - :rule ( - :AdminInfo ( - :chkpf_uid ("{09847FA8-6AD8-4196-A6BA-C2E5A4380CAF}") - :ClassName (security_rule) - ) - :action ( - : (accept - :AdminInfo ( - :chkpf_uid ("{A98C137A-E74F-4C98-8654-234FBD65C912}") - :ClassName (accept_action) - :table (setup) - ) - :action () - :macro (RECORD_CONN) - :type (accept) - ) - ) - :comments () - :disabled (false) - :global_location (middle) - :through ( - : (ReferenceObject - :Name (RemoteAccess) - :Table (communities) - :Uid ("{97AEB677-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :time ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :track ( - : (ReferenceObject - :Name (Log) - :Table (tracks) - :Uid ("{97AEB480-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :dst ( - :AdminInfo ( - :chkpf_uid ("{AE09F8C4-EE69-4874-A359-DE443685FA10}") - :ClassName (rule_destination) - ) - :compound () - :op () - : (ReferenceObject - :Name (wasp) - :Table (network_objects) - :Uid ("{098B2A74-E220-4AE8-A164-340FED79C9D5}") - ) - ) - :install ( - :AdminInfo ( - :chkpf_uid ("{88454436-C062-4605-BADB-73FD6F534D0F}") - :ClassName (rule_install) - ) - :compound () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :services ( - :AdminInfo ( - :chkpf_uid ("{79BEA1F5-E14E-4C55-B7B2-4765F608CEC4}") - :ClassName (rule_services) - ) - :compound () - :op () - : (ReferenceObject - :Name (ntp-udp) - :Table (services) - :Uid ("{97AEB404-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :src ( - :AdminInfo ( - :chkpf_uid ("{7851EA21-542A-4587-B676-F7DD371446C5}") - :ClassName (rule_source) - ) - :compound ( - : (Cactus-extern@vpn-sources-IsoAAAA - :AdminInfo ( - :chkpf_uid ("{4BC9D4D1-5EE4-45A3-9EE3-77D2B97D21EF}") - :ClassName (rule_user_group) - ) - :at (ReferenceObject - :Name (vpn-sources-IsoAAAA) - :Table (network_objects) - :Uid ("{26405A41-425C-4053-8002-497BB82D76B1}") - ) - :color (black) - :type (usrgroup) - ) - ) - :op () - ) - ) - :rule ( - :AdminInfo ( - :chkpf_uid ("{67784DF8-6440-4F4A-891C-C7062E0F32B0}") - :ClassName (security_rule) - ) - :action ( - : (accept - :AdminInfo ( - :chkpf_uid ("{DE137218-858A-4F21-8F15-2D8D7E4A2595}") - :ClassName (accept_action) - :table (setup) - ) - :action () - :macro (RECORD_CONN) - :type (accept) - ) - ) - :comments () - :disabled (false) - :global_location (middle) - :through ( - : (ReferenceObject - :Name (RemoteAccess) - :Table (communities) - :Uid ("{97AEB677-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :time ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :track ( - : (ReferenceObject - :Name (Log) - :Table (tracks) - :Uid ("{97AEB480-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :dst ( - :AdminInfo ( - :chkpf_uid ("{D29D3530-277E-4D41-86B8-CDFD1640107F}") - :ClassName (rule_destination) - ) - :compound () - :op () - : (ReferenceObject - :Name (wasp) - :Table (network_objects) - :Uid ("{098B2A74-E220-4AE8-A164-340FED79C9D5}") - ) - : (ReferenceObject - :Name (hpux) - :Table (network_objects) - :Uid ("{BF00A847-A0D6-4A75-BE1C-27E7D91EDB55}") - ) - : (ReferenceObject - :Name (sol8) - :Table (network_objects) - :Uid ("{86F22190-7D8D-435D-8906-A346CA12A17C}") - ) - ) - :install ( - :AdminInfo ( - :chkpf_uid ("{35771DD3-A725-4A30-B8D1-2D4DE471A8AA}") - :ClassName (rule_install) - ) - :compound () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :services ( - :AdminInfo ( - :chkpf_uid ("{65CD16B1-1526-40F3-9D70-2C6DE0FD27B8}") - :ClassName (rule_services) - ) - :compound () - :op () - : (ReferenceObject - :Name (telnet) - :Table (services) - :Uid ("{97AEB3CF-9AEA-11D5-BD16-0090272CCB30}") - ) - : (ReferenceObject - :Name (ssh) - :Table (services) - :Uid ("{18EC9EAA-1657-4240-AB97-5F234623336B}") - ) - : (ReferenceObject - :Name (ftp) - :Table (services) - :Uid ("{97AEB3D0-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :src ( - :AdminInfo ( - :chkpf_uid ("{3E20C184-B0AC-458B-AB58-17C5E8D0CB58}") - :ClassName (rule_source) - ) - :compound ( - : (Cactus-extern@vpn-sources-IsoAAAA - :AdminInfo ( - :chkpf_uid ("{4BC9D4D1-5EE4-45A3-9EE3-77D2B97D21EF}") - :ClassName (rule_user_group) - ) - :at (ReferenceObject - :Name (vpn-sources-IsoAAAA) - :Table (network_objects) - :Uid ("{26405A41-425C-4053-8002-497BB82D76B1}") - ) - :color (black) - :type (usrgroup) - ) - ) - :op () - ) - ) - :rule ( - :AdminInfo ( - :chkpf_uid ("{C6951C02-A10A-4757-A85F-5C197D6B95EB}") - :ClassName (security_rule) - ) - :action ( - : (accept - :AdminInfo ( - :chkpf_uid ("{565F4F4F-72D3-42A6-A633-369FEFEF44AF}") - :ClassName (accept_action) - :table (setup) - ) - :action () - :macro (RECORD_CONN) - :type (accept) - ) - ) - :comments () - :disabled (false) - :global_location (middle) - :through ( - : (ReferenceObject - :Name (RemoteAccess) - :Table (communities) - :Uid ("{97AEB677-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :time ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :track ( - : (ReferenceObject - :Name (Log) - :Table (tracks) - :Uid ("{97AEB480-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :dst ( - :AdminInfo ( - :chkpf_uid ("{953252BD-3073-4D69-B49A-86B012FEF76D}") - :ClassName (rule_destination) - ) - :compound () - :op () - : (ReferenceObject - :Name (IsoAAAA-100) - :Table (network_objects) - :Uid ("{BF1C6029-8D5D-4A05-A3AD-4B67E6E7A7AA}") - ) - ) - :install ( - :AdminInfo ( - :chkpf_uid ("{019A9168-EF95-46C7-AFB5-B0788EBDAB4B}") - :ClassName (rule_install) - ) - :compound () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :services ( - :AdminInfo ( - :chkpf_uid ("{63D8350C-2432-4909-91D6-4459C3054B4E}") - :ClassName (rule_services) - ) - :compound () - :op () - : (ReferenceObject - :Name (icmp-requests) - :Table (services) - :Uid ("{97AEB413-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :src ( - :AdminInfo ( - :chkpf_uid ("{D6818DB3-CC9E-498A-B47D-DA9204F004F4}") - :ClassName (rule_source) - ) - :compound ( - : (Cactus-extern@vpn-sources-IsoAAAA - :AdminInfo ( - :chkpf_uid ("{970C0D68-3CEC-47CA-B2C0-EB23C9B56AC8}") - :ClassName (rule_user_group) - ) - :at (ReferenceObject - :Name (vpn-sources-IsoAAAA) - :Table (network_objects) - :Uid ("{26405A41-425C-4053-8002-497BB82D76B1}") - ) - :color (black) - :type (usrgroup) - ) - ) - :op () - ) - ) - :rule ( - :AdminInfo ( - :chkpf_uid ("{84087B02-E15A-4E97-9204-F0F866206B75}") - :ClassName (security_header_rule) - ) - :action ( - : (drop - :AdminInfo ( - :chkpf_uid ("{C1A1378F-A974-41CF-BB10-A3F1D8205A3A}") - :ClassName (drop_action) - :table (setup) - ) - :action () - :macro () - :type (drop) - ) - ) - :comments () - :global_location (middle) - :through ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :time ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :track ( - : (ReferenceObject - :Name (None) - :Table (tracks) - :Uid ("{97AEB47D-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :disabled (true) - :dst ( - :AdminInfo ( - :chkpf_uid ("{6CF2DE51-FF05-4F78-A967-BA8F290325BF}") - :ClassName (rule_destination) - ) - :compound () - :op () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :header_text ("IsoAAAE VPN-GW2GW") - :install ( - :AdminInfo ( - :chkpf_uid ("{478AEC09-B131-41B8-8756-A059E1E43421}") - :ClassName (rule_install) - ) - :compound () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :services ( - :AdminInfo ( - :chkpf_uid ("{8F76A99B-E1AD-4595-B528-588D82877DDE}") - :ClassName (rule_services) - ) - :compound () - :op () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :src ( - :AdminInfo ( - :chkpf_uid ("{E356D6BD-676A-4587-90E7-C31B293579C1}") - :ClassName (rule_source) - ) - :compound () - :op () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :state (expanded) - ) - :rule ( - :AdminInfo ( - :chkpf_uid ("{9BC6A630-0169-4289-962F-8E65E0503D01}") - :ClassName (security_rule) - ) - :action ( - : (accept - :AdminInfo ( - :chkpf_uid ("{B8BB89E7-6B1B-40B6-A600-D2B0066DFF00}") - :ClassName (accept_action) - :table (setup) - ) - :action () - :macro (RECORD_CONN) - :type (accept) - ) - ) - :comments () - :disabled (false) - :global_location (middle) - :through ( - : (ReferenceObject - :Name (All_GwToGw) - :Table (globals) - :Uid ("{97AEB36A-9AED-11D5-BD16-0090272CCB30}") - ) - ) - :time ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :track ( - : (ReferenceObject - :Name (Log) - :Table (tracks) - :Uid ("{97AEB480-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :dst ( - :AdminInfo ( - :chkpf_uid ("{83858D79-EC2C-4812-9B9B-2346DFC72654}") - :ClassName (rule_destination) - ) - :compound () - :op () - : (ReferenceObject - :Name (IsoAAAA-100) - :Table (network_objects) - :Uid ("{BF1C6029-8D5D-4A05-A3AD-4B67E6E7A7AA}") - ) - ) - :install ( - :AdminInfo ( - :chkpf_uid ("{50CB20E0-39A1-42D5-9495-BA814B304829}") - :ClassName (rule_install) - ) - :compound () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :services ( - :AdminInfo ( - :chkpf_uid ("{938E9BAA-A4E0-42DE-B985-4FC332A0008A}") - :ClassName (rule_services) - ) - :compound () - :op () - : (ReferenceObject - :Name (icmp-requests) - :Table (services) - :Uid ("{97AEB413-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :src ( - :AdminInfo ( - :chkpf_uid ("{288657B3-E155-44B2-9023-5BDBB46EF52F}") - :ClassName (rule_source) - ) - :compound () - :op () - : (ReferenceObject - :Name (IsoAAAA_home_tim) - :Table (network_objects) - :Uid ("{BF8F69B9-87C2-464A-9404-239AE8DF66B3}") - ) - ) - ) - :rule ( - :AdminInfo ( - :chkpf_uid ("{B1C875B9-8C29-46BA-AECD-FF8869A04D9B}") - :ClassName (security_rule) - ) - :action ( - : (drop - :AdminInfo ( - :chkpf_uid ("{E8DEC8BB-827E-4253-9F56-CBCB1F0341F4}") - :ClassName (drop_action) - :table (setup) - ) - :action () - :macro () - :type (drop) - ) - ) - :disabled (false) - :global_location (middle) - :through ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :time ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :track ( - : (ReferenceObject - :Name (Log) - :Table (tracks) - :Uid ("{97AEB480-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :comments ("Block unencrypted traffic") - :dst ( - :AdminInfo ( - :chkpf_uid ("{29A8CC60-5F3D-4DD8-9F99-B46580505665}") - :ClassName (rule_destination) - ) - :compound () - :op () - : (ReferenceObject - :Name (IsoAAAA-100) - :Table (network_objects) - :Uid ("{BF1C6029-8D5D-4A05-A3AD-4B67E6E7A7AA}") - ) - ) - :install ( - :AdminInfo ( - :chkpf_uid ("{BA0E4CAF-31C0-45AE-A5AC-BD9DF0BD8FC0}") - :ClassName (rule_install) - ) - :compound () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :services ( - :AdminInfo ( - :chkpf_uid ("{0A5CA41F-1516-447A-AFED-B41AB1BD4637}") - :ClassName (rule_services) - ) - :compound () - :op () - : (ReferenceObject - :Name (icmp-requests) - :Table (services) - :Uid ("{97AEB413-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :src ( - :AdminInfo ( - :chkpf_uid ("{2CF51880-2CD3-4553-9772-807B521B0EC2}") - :ClassName (rule_source) - ) - :compound () - :op () - : (ReferenceObject - :Name (IsoAAAA_home_tim) - :Table (network_objects) - :Uid ("{BF8F69B9-87C2-464A-9404-239AE8DF66B3}") - ) - ) - ) - :rule ( - :AdminInfo ( - :chkpf_uid ("{6607FF6B-96E1-482D-BA53-0BF5182A7090}") - :ClassName (security_header_rule) - ) - :action ( - : (drop - :AdminInfo ( - :chkpf_uid ("{8577970A-781C-48C3-BE45-3E40A2CB5057}") - :ClassName (drop_action) - :table (setup) - ) - :action () - :macro () - :type (drop) - ) - ) - :comments () - :global_location (middle) - :through ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :time ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :track ( - : (ReferenceObject - :Name (None) - :Table (tracks) - :Uid ("{97AEB47D-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :disabled (true) - :dst ( - :AdminInfo ( - :chkpf_uid ("{18B51CA6-7E67-4152-8DD6-9618130738CD}") - :ClassName (rule_destination) - ) - :compound () - :op () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :header_text (Paybox) - :install ( - :AdminInfo ( - :chkpf_uid ("{CA5F1199-9F32-41DD-AD63-A613DC51AD11}") - :ClassName (rule_install) - ) - :compound () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :services ( - :AdminInfo ( - :chkpf_uid ("{F22C4535-8983-42E8-A57D-302F96334404}") - :ClassName (rule_services) - ) - :compound () - :op () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :src ( - :AdminInfo ( - :chkpf_uid ("{C58BFEC0-22AA-43E3-B5AA-A390065EDDE4}") - :ClassName (rule_source) - ) - :compound () - :op () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :state (expanded) - ) - :rule ( - :AdminInfo ( - :chkpf_uid ("{3B7F9B93-E229-49E0-B93C-87797CB2445E}") - :ClassName (security_rule) - ) - :action ( - : (accept - :AdminInfo ( - :chkpf_uid ("{74F856AC-BB86-4DBA-89A6-7F5F3A688179}") - :ClassName (accept_action) - :table (setup) - ) - :action () - :macro (RECORD_CONN) - :type (accept) - ) - ) - :comments () - :disabled (false) - :global_location (middle) - :through ( - : (ReferenceObject - :Name (All_GwToGw) - :Table (globals) - :Uid ("{97AEB36A-9AED-11D5-BD16-0090272CCB30}") - ) - ) - :time ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :track ( - : (ReferenceObject - :Name (Log) - :Table (tracks) - :Uid ("{97AEB480-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :dst ( - :AdminInfo ( - :chkpf_uid ("{FDB351D4-FAF2-46AD-A039-1F0074C8F532}") - :ClassName (rule_destination) - ) - :compound () - :op () - : (ReferenceObject - :Name (paybox-raunheim) - :Table (network_objects) - :Uid ("{0A1725B4-534D-46F1-A8C0-02C3351C8312}") - ) - ) - :install ( - :AdminInfo ( - :chkpf_uid ("{F376EC61-0B15-4184-9B7C-42665CF487FA}") - :ClassName (rule_install) - ) - :compound () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :services ( - :AdminInfo ( - :chkpf_uid ("{D7EAE07F-E937-4414-935E-4992058348A3}") - :ClassName (rule_services) - ) - :compound () - :op () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :src ( - :AdminInfo ( - :chkpf_uid ("{8A44B6BE-A911-435B-918F-FDEF668BDC0F}") - :ClassName (rule_source) - ) - :compound () - :op () - : (ReferenceObject - :Name (IsoAAAA-100) - :Table (network_objects) - :Uid ("{BF1C6029-8D5D-4A05-A3AD-4B67E6E7A7AA}") - ) - ) - ) - :rule ( - :AdminInfo ( - :chkpf_uid ("{0FC24606-8AB3-4136-9D11-AE640332B633}") - :ClassName (security_rule) - ) - :action ( - : (drop - :AdminInfo ( - :chkpf_uid ("{979F3CB1-04B9-429E-9B98-3FD1E474BDB5}") - :ClassName (drop_action) - :table (setup) - ) - :action () - :macro () - :type (drop) - ) - ) - :disabled (false) - :global_location (middle) - :through ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :time ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :track ( - : (ReferenceObject - :Name (Log) - :Table (tracks) - :Uid ("{97AEB480-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :comments ("Block unencrypted traffic") - :dst ( - :AdminInfo ( - :chkpf_uid ("{C9F76D81-A3CD-4EA3-980E-AB19B84A9816}") - :ClassName (rule_destination) - ) - :compound () - :op () - : (ReferenceObject - :Name (paybox-raunheim) - :Table (network_objects) - :Uid ("{0A1725B4-534D-46F1-A8C0-02C3351C8312}") - ) - ) - :install ( - :AdminInfo ( - :chkpf_uid ("{CB49F41A-7DB3-484E-85D0-760FE4933517}") - :ClassName (rule_install) - ) - :compound () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :services ( - :AdminInfo ( - :chkpf_uid ("{57FEBAF2-A9A2-4738-B311-1A980A23FA23}") - :ClassName (rule_services) - ) - :compound () - :op () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :src ( - :AdminInfo ( - :chkpf_uid ("{6F09B75D-4982-49B2-BDEF-89456CA71A33}") - :ClassName (rule_source) - ) - :compound () - :op () - : (ReferenceObject - :Name (IsoAAAA-100) - :Table (network_objects) - :Uid ("{BF1C6029-8D5D-4A05-A3AD-4B67E6E7A7AA}") - ) - ) - ) - :rule ( - :AdminInfo ( - :chkpf_uid ("{01253F2A-C645-4A01-BE58-718F56FA3042}") - :ClassName (security_rule) - ) - :action ( - : (accept - :AdminInfo ( - :chkpf_uid ("{89C021CB-2CFF-42DB-81C0-E9C445E96219}") - :ClassName (accept_action) - :table (setup) - ) - :action () - :macro (RECORD_CONN) - :type (accept) - ) - ) - :comments () - :global_location (middle) - :through ( - : (ReferenceObject - :Name (All_GwToGw) - :Table (globals) - :Uid ("{97AEB36A-9AED-11D5-BD16-0090272CCB30}") - ) - ) - :time ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :track ( - : (ReferenceObject - :Name (Log) - :Table (tracks) - :Uid ("{97AEB480-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :disabled (true) - :dst ( - :AdminInfo ( - :chkpf_uid ("{40845CD1-003B-4E2A-B3CE-268AADDFB0C3}") - :ClassName (rule_destination) - ) - :compound () - :op () - : (ReferenceObject - :Name (paybox-frankfurt) - :Table (network_objects) - :Uid ("{463C45CA-0C86-42DC-9B02-E83E28764370}") - ) - ) - :install ( - :AdminInfo ( - :chkpf_uid ("{B9A528D6-C1C5-4BDB-A503-D1A75758AA29}") - :ClassName (rule_install) - ) - :compound () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :services ( - :AdminInfo ( - :chkpf_uid ("{6C61EA28-FE67-48D0-A2E8-2731F0A34C88}") - :ClassName (rule_services) - ) - :compound () - :op () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :src ( - :AdminInfo ( - :chkpf_uid ("{AF6C276C-BA70-4D17-8940-210D00681C90}") - :ClassName (rule_source) - ) - :compound () - :op () - : (ReferenceObject - :Name (IsoAAAA-100) - :Table (network_objects) - :Uid ("{BF1C6029-8D5D-4A05-A3AD-4B67E6E7A7AA}") - ) - ) - ) - :rule ( - :AdminInfo ( - :chkpf_uid ("{6CE90A16-2A7D-4447-B9B6-DB6C365BEEE0}") - :ClassName (security_rule) - ) - :action ( - : (drop - :AdminInfo ( - :chkpf_uid ("{5FCD7357-7092-482B-9E11-4CEF1BC13361}") - :ClassName (drop_action) - :table (setup) - ) - :action () - :macro () - :type (drop) - ) - ) - :global_location (middle) - :through ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :time ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :track ( - : (ReferenceObject - :Name (Log) - :Table (tracks) - :Uid ("{97AEB480-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :comments ("Block unencrypted traffic") - :disabled (true) - :dst ( - :AdminInfo ( - :chkpf_uid ("{3D5ACDF1-4FEC-4064-A909-23877F7B69C3}") - :ClassName (rule_destination) - ) - :compound () - :op () - : (ReferenceObject - :Name (paybox-frankfurt) - :Table (network_objects) - :Uid ("{463C45CA-0C86-42DC-9B02-E83E28764370}") - ) - ) - :install ( - :AdminInfo ( - :chkpf_uid ("{45F24052-D79F-4CA3-B198-ED301E6F360E}") - :ClassName (rule_install) - ) - :compound () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :services ( - :AdminInfo ( - :chkpf_uid ("{E3DB1CE8-A31E-4F3A-95D8-E0141027E617}") - :ClassName (rule_services) - ) - :compound () - :op () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :src ( - :AdminInfo ( - :chkpf_uid ("{9B286C56-F6B8-4AE8-93B5-7003DC58F959}") - :ClassName (rule_source) - ) - :compound () - :op () - : (ReferenceObject - :Name (IsoAAAA-100) - :Table (network_objects) - :Uid ("{BF1C6029-8D5D-4A05-A3AD-4B67E6E7A7AA}") - ) - ) - ) - :rule ( - :AdminInfo ( - :chkpf_uid ("{7D822D25-45D2-4906-8C8E-72652A4E9C7C}") - :ClassName (security_header_rule) - ) - :action ( - : (drop - :AdminInfo ( - :chkpf_uid ("{8AEAF6EF-1859-4E89-A58F-4F275BF154AA}") - :ClassName (drop_action) - :table (setup) - ) - :action () - :macro () - :type (drop) - ) - ) - :comments () - :global_location (middle) - :through ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :time ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :track ( - : (ReferenceObject - :Name (None) - :Table (tracks) - :Uid ("{97AEB47D-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :disabled (true) - :dst ( - :AdminInfo ( - :chkpf_uid ("{08B3D275-0F89-4C3F-B53E-1E3ECA583C23}") - :ClassName (rule_destination) - ) - :compound () - :op () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :header_text (Internal-Connections) - :install ( - :AdminInfo ( - :chkpf_uid ("{CA6C0AAF-DBCE-4020-B529-4E4449A1EFAA}") - :ClassName (rule_install) - ) - :compound () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :services ( - :AdminInfo ( - :chkpf_uid ("{6FB76A7B-3073-434B-ADDA-81C99060AEBA}") - :ClassName (rule_services) - ) - :compound () - :op () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :src ( - :AdminInfo ( - :chkpf_uid ("{79B42650-50CC-4AD9-A13E-A0E4AB4D7383}") - :ClassName (rule_source) - ) - :compound () - :op () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :state (collapsed) - ) - :rule ( - :AdminInfo ( - :chkpf_uid ("{EACACDFF-02E7-4014-9DA7-1A5487AB8481}") - :ClassName (security_rule) - ) - :action ( - : (accept - :AdminInfo ( - :chkpf_uid ("{87CA79FF-466D-4BCF-B6C4-42FE6346885F}") - :ClassName (accept_action) - :table (setup) - ) - :action () - :macro (RECORD_CONN) - :type (accept) - ) - ) - :comments () - :disabled (false) - :global_location (middle) - :through ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :time ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :track ( - : (ReferenceObject - :Name (Log) - :Table (tracks) - :Uid ("{97AEB480-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :dst ( - :AdminInfo ( - :chkpf_uid ("{38233DD1-F39A-42F7-80B7-74A2F3C959BE}") - :ClassName (rule_destination) - ) - :compound () - :op () - : (ReferenceObject - :Name (IsoAAAD) - :Table (network_objects) - :Uid ("{29C40B0A-414C-11D7-AEB8-7F0000013C3C}") - ) - ) - :install ( - :AdminInfo ( - :chkpf_uid ("{D4207D0B-4AA6-4438-A102-EAF2E08BCABC}") - :ClassName (rule_install) - ) - :compound () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :services ( - :AdminInfo ( - :chkpf_uid ("{0D51549F-279B-4544-97E7-672C85874699}") - :ClassName (rule_services) - ) - :compound () - :op () - : (ReferenceObject - :Name (ssh) - :Table (services) - :Uid ("{18EC9EAA-1657-4240-AB97-5F234623336B}") - ) - : (ReferenceObject - :Name (https) - :Table (services) - :Uid ("{97AEB443-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :src ( - :AdminInfo ( - :chkpf_uid ("{C0F53557-6630-4779-8F85-30AA74C8BB3F}") - :ClassName (rule_source) - ) - :compound () - :op () - : (ReferenceObject - :Name (IsoAAAA-100) - :Table (network_objects) - :Uid ("{BF1C6029-8D5D-4A05-A3AD-4B67E6E7A7AA}") - ) - : (ReferenceObject - :Name (IsoAAAA_home_tim) - :Table (network_objects) - :Uid ("{BF8F69B9-87C2-464A-9404-239AE8DF66B3}") - ) - : (ReferenceObject - :Name (mg.IsoAAAA-es.com) - :Table (network_objects) - :Uid ("{E5BF8260-3615-4476-B638-53CA3A24FEF1}") - ) - ) - ) - :rule ( - :AdminInfo ( - :chkpf_uid ("{C5F973E3-CBB2-4C15-A735-52B51AC9DAE7}") - :ClassName (security_rule) - ) - :action ( - : (accept - :AdminInfo ( - :chkpf_uid ("{396BFDCC-A290-408E-9F92-791EA8CF3616}") - :ClassName (accept_action) - :table (setup) - ) - :action () - :macro (RECORD_CONN) - :type (accept) - ) - ) - :comments () - :disabled (false) - :global_location (middle) - :through ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :time ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :track ( - : (ReferenceObject - :Name (Log) - :Table (tracks) - :Uid ("{97AEB480-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :dst ( - :AdminInfo ( - :chkpf_uid ("{389DDDD2-29F4-4D0F-A969-726529DF0919}") - :ClassName (rule_destination) - ) - :compound () - :op () - : (ReferenceObject - :Name (daba) - :Table (network_objects) - :Uid ("{94817CDB-EA8C-4213-B38D-F4417EA620C6}") - ) - ) - :install ( - :AdminInfo ( - :chkpf_uid ("{D76410C0-68C5-40EA-A75A-9FFB9B0EF2E8}") - :ClassName (rule_install) - ) - :compound () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :services ( - :AdminInfo ( - :chkpf_uid ("{FCA57859-3422-4495-954F-E7D746378008}") - :ClassName (rule_services) - ) - :compound () - :op () - : (ReferenceObject - :Name (ssh) - :Table (services) - :Uid ("{18EC9EAA-1657-4240-AB97-5F234623336B}") - ) - : (ReferenceObject - :Name (mysql) - :Table (services) - :Uid ("{08A07607-EAAA-4A45-AD6E-6020770BD519}") - ) - ) - :src ( - :AdminInfo ( - :chkpf_uid ("{B98DA2C1-079F-4EF2-A67D-5FCEC98B1FE8}") - :ClassName (rule_source) - ) - :compound () - :op () - : (ReferenceObject - :Name (IsoAAAA-100) - :Table (network_objects) - :Uid ("{BF1C6029-8D5D-4A05-A3AD-4B67E6E7A7AA}") - ) - : (ReferenceObject - :Name (IsoAAAA_home_tim) - :Table (network_objects) - :Uid ("{BF8F69B9-87C2-464A-9404-239AE8DF66B3}") - ) - ) - ) - :rule ( - :AdminInfo ( - :chkpf_uid ("{0D4D75A0-8203-453F-9C3E-F68E1995DE88}") - :ClassName (security_rule) - ) - :action ( - : (accept - :AdminInfo ( - :chkpf_uid ("{317B8552-195E-4E2A-8EA7-CEE52B732C38}") - :ClassName (accept_action) - :table (setup) - ) - :action () - :macro (RECORD_CONN) - :type (accept) - ) - ) - :comments () - :disabled (false) - :global_location (middle) - :through ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :time ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :track ( - : (ReferenceObject - :Name (None) - :Table (tracks) - :Uid ("{97AEB47D-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :dst ( - :AdminInfo ( - :chkpf_uid ("{C80F45A6-E7AD-4F87-89A8-31CC7D5A5E53}") - :ClassName (rule_destination) - ) - :compound () - :op () - : (ReferenceObject - :Name (wasp) - :Table (network_objects) - :Uid ("{098B2A74-E220-4AE8-A164-340FED79C9D5}") - ) - ) - :install ( - :AdminInfo ( - :chkpf_uid ("{9D97B55B-160C-46D2-ADFA-6D235D7D9733}") - :ClassName (rule_install) - ) - :compound () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :services ( - :AdminInfo ( - :chkpf_uid ("{8305714C-A6BA-4B6C-A1A9-2E54349BB3ED}") - :ClassName (rule_services) - ) - :compound () - :op () - : (ReferenceObject - :Name (ntp-udp) - :Table (services) - :Uid ("{97AEB404-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :src ( - :AdminInfo ( - :chkpf_uid ("{398C5E6F-5E01-4646-ABAB-BF775B461AE6}") - :ClassName (rule_source) - ) - :compound () - :op () - : (ReferenceObject - :Name (IsoAAAD) - :Table (network_objects) - :Uid ("{29C40B0A-414C-11D7-AEB8-7F0000013C3C}") - ) - ) - ) - :rule ( - :AdminInfo ( - :chkpf_uid ("{A1ACBE88-9F38-4947-B497-B34A2F3878B3}") - :ClassName (security_rule) - ) - :action ( - : (accept - :AdminInfo ( - :chkpf_uid ("{F8FE4FD5-50BE-4D6E-93FE-93071473FFF0}") - :ClassName (accept_action) - :table (setup) - ) - :action () - :macro (RECORD_CONN) - :type (accept) - ) - ) - :comments () - :disabled (false) - :global_location (middle) - :through ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :time ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :track ( - : (ReferenceObject - :Name (None) - :Table (tracks) - :Uid ("{97AEB47D-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :dst ( - :AdminInfo ( - :chkpf_uid ("{442DA9A3-9028-4077-88ED-F676CC39EA6A}") - :ClassName (rule_destination) - ) - :compound () - :op () - : (ReferenceObject - :Name (IsoAAADray.local) - :Table (network_objects) - :Uid ("{75EDBC62-7EB1-4D37-8295-684903FDA75A}") - ) - ) - :install ( - :AdminInfo ( - :chkpf_uid ("{22AF536A-CE60-42B9-8D92-B2B84B1B849A}") - :ClassName (rule_install) - ) - :compound () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :services ( - :AdminInfo ( - :chkpf_uid ("{FE031AD5-4408-419D-9CAC-E33FD47B4872}") - :ClassName (rule_services) - ) - :compound () - :op () - : (ReferenceObject - :Name (domain-udp) - :Table (services) - :Uid ("{97AEB3FA-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :src ( - :AdminInfo ( - :chkpf_uid ("{EA42965D-38DF-4E67-8A06-6BF107BEC1BE}") - :ClassName (rule_source) - ) - :compound () - :op () - : (ReferenceObject - :Name (IsoAAAD) - :Table (network_objects) - :Uid ("{29C40B0A-414C-11D7-AEB8-7F0000013C3C}") - ) - ) - ) - :rule ( - :AdminInfo ( - :chkpf_uid ("{321D1155-8DB8-48D3-8F89-789456335EA5}") - :ClassName (security_rule) - ) - :action ( - : (accept - :AdminInfo ( - :chkpf_uid ("{EF61D86E-D8BD-4E00-83C7-D4D6413AA826}") - :ClassName (accept_action) - :table (setup) - ) - :action () - :macro (RECORD_CONN) - :type (accept) - ) - ) - :comments () - :disabled (false) - :global_location (middle) - :through ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :time ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :track ( - : (ReferenceObject - :Name (Log) - :Table (tracks) - :Uid ("{97AEB480-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :dst ( - :AdminInfo ( - :chkpf_uid ("{6ECE3813-9B88-4B95-8F48-35760521161D}") - :ClassName (rule_destination) - ) - :compound () - :op () - : (ReferenceObject - :Name (spike.local) - :Table (network_objects) - :Uid ("{4ABDD8DE-0DA2-46E5-B129-85E3977CBD18}") - ) - : (ReferenceObject - :Name (mg.IsoAAAA-es.com) - :Table (network_objects) - :Uid ("{E5BF8260-3615-4476-B638-53CA3A24FEF1}") - ) - ) - :install ( - :AdminInfo ( - :chkpf_uid ("{B6B3B97E-55C4-41CA-B951-91FBA42AD24D}") - :ClassName (rule_install) - ) - :compound () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :services ( - :AdminInfo ( - :chkpf_uid ("{E4826F35-742D-4BE5-814E-5ECE6741D719}") - :ClassName (rule_services) - ) - :compound () - :op () - : (ReferenceObject - :Name (syslog) - :Table (services) - :Uid ("{97AEB3E0-9AEA-11D5-BD16-0090272CCB30}") - ) - : (ReferenceObject - :Name (ssh_version_2) - :Table (services) - :Uid ("{CD082D9A-44A6-4CEF-A17D-5541029ADFB3}") - ) - : (ReferenceObject - :Name (domain-udp) - :Table (services) - :Uid ("{97AEB3FA-9AEA-11D5-BD16-0090272CCB30}") - ) - : (ReferenceObject - :Name (smtp) - :Table (services) - :Uid ("{97AEB3D9-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :src ( - :AdminInfo ( - :chkpf_uid ("{CBCA552F-5195-4594-8FCD-DB44E1E54E08}") - :ClassName (rule_source) - ) - :compound () - :op () - : (ReferenceObject - :Name (IsoAAAD) - :Table (network_objects) - :Uid ("{29C40B0A-414C-11D7-AEB8-7F0000013C3C}") - ) - ) - ) - :rule ( - :AdminInfo ( - :chkpf_uid ("{479DFC1D-FE51-4CFB-9A99-4FD1A532B7B4}") - :ClassName (security_header_rule) - ) - :action ( - : (drop - :AdminInfo ( - :chkpf_uid ("{575C62B8-634C-4115-9DF5-3C75BBFBFDEE}") - :ClassName (drop_action) - :table (setup) - ) - :action () - :macro () - :type (drop) - ) - ) - :comments () - :global_location (middle) - :through ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :time ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :track ( - : (ReferenceObject - :Name (None) - :Table (tracks) - :Uid ("{97AEB47D-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :disabled (true) - :dst ( - :AdminInfo ( - :chkpf_uid ("{EF6C7FE7-9266-491E-8933-CC4429B97209}") - :ClassName (rule_destination) - ) - :compound () - :op () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :header_text ("Intern to Spike") - :install ( - :AdminInfo ( - :chkpf_uid ("{CA20EBCF-96AC-402F-87BB-25C0EC09879B}") - :ClassName (rule_install) - ) - :compound () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :services ( - :AdminInfo ( - :chkpf_uid ("{5505712A-4BAB-46F8-BFAF-62A682802247}") - :ClassName (rule_services) - ) - :compound () - :op () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :src ( - :AdminInfo ( - :chkpf_uid ("{3B75D561-22D8-4C61-9CA7-A843272AA499}") - :ClassName (rule_source) - ) - :compound () - :op () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :state (expanded) - ) - :rule ( - :AdminInfo ( - :chkpf_uid ("{F18D892E-EED1-488B-A0D9-832B742CE27B}") - :ClassName (security_rule) - ) - :action ( - : (accept - :AdminInfo ( - :chkpf_uid ("{BD096130-776F-4884-A5E3-66951FEDCAA1}") - :ClassName (accept_action) - :table (setup) - ) - :action () - :macro (RECORD_CONN) - :type (accept) - ) - ) - :comments () - :disabled (false) - :global_location (middle) - :through ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :time ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :track ( - : (ReferenceObject - :Name (Log) - :Table (tracks) - :Uid ("{97AEB480-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :dst ( - :AdminInfo ( - :chkpf_uid ("{69FBBF03-9653-4708-95E4-A3085DA3502E}") - :ClassName (rule_destination) - ) - :compound () - :op () - : (ReferenceObject - :Name (spike.local) - :Table (network_objects) - :Uid ("{4ABDD8DE-0DA2-46E5-B129-85E3977CBD18}") - ) - : (ReferenceObject - :Name (mg.IsoAAAA-es.com) - :Table (network_objects) - :Uid ("{E5BF8260-3615-4476-B638-53CA3A24FEF1}") - ) - : (ReferenceObject - :Name (ras.IsoAAAA-es.com) - :Table (network_objects) - :Uid ("{23B1E779-B8D5-4384-AD60-80E498B77196}") - ) - ) - :install ( - :AdminInfo ( - :chkpf_uid ("{58BE428C-CA30-4DD6-8D0C-DD21E8D5716A}") - :ClassName (rule_install) - ) - :compound () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :services ( - :AdminInfo ( - :chkpf_uid ("{D45CFA85-C7A9-4770-BBA5-38DC95DE2E39}") - :ClassName (rule_services) - ) - :compound () - :op () - : (ReferenceObject - :Name (SpikeServices) - :Table (services) - :Uid ("{9D35FACE-289F-49A6-95C7-13417959BC9D}") - ) - ) - :src ( - :AdminInfo ( - :chkpf_uid ("{CEAC96CA-4B08-4E15-B8E5-F555868B9B9D}") - :ClassName (rule_source) - ) - :compound () - :op () - : (ReferenceObject - :Name (IsoAAAA-100) - :Table (network_objects) - :Uid ("{BF1C6029-8D5D-4A05-A3AD-4B67E6E7A7AA}") - ) - ) - ) - :rule ( - :AdminInfo ( - :chkpf_uid ("{001AA0F0-DFE8-4CAD-9B62-C26E1A5CB9A0}") - :ClassName (security_header_rule) - ) - :action ( - : (drop - :AdminInfo ( - :chkpf_uid ("{339E1791-EB7E-4985-8B54-EBE0E6097CCB}") - :ClassName (drop_action) - :table (setup) - ) - :action () - :macro () - :type (drop) - ) - ) - :comments () - :global_location (middle) - :through ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :time ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :track ( - : (ReferenceObject - :Name (None) - :Table (tracks) - :Uid ("{97AEB47D-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :disabled (true) - :dst ( - :AdminInfo ( - :chkpf_uid ("{A78DD97F-4A53-4494-8F90-EABA9B30D6B5}") - :ClassName (rule_destination) - ) - :compound () - :op () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :header_text ("Intern to DMZ") - :install ( - :AdminInfo ( - :chkpf_uid ("{209BE460-BB82-44DD-817D-FF2E22395B31}") - :ClassName (rule_install) - ) - :compound () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :services ( - :AdminInfo ( - :chkpf_uid ("{E0D91B63-F2A0-4973-B07E-AEDD817454E5}") - :ClassName (rule_services) - ) - :compound () - :op () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :src ( - :AdminInfo ( - :chkpf_uid ("{9BD55163-1255-4D94-BE33-13A5569A02ED}") - :ClassName (rule_source) - ) - :compound () - :op () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :state (expanded) - ) - :rule ( - :AdminInfo ( - :chkpf_uid ("{00477CC9-4940-4C79-B2E6-A137781B1C25}") - :ClassName (security_rule) - ) - :action ( - : (accept - :AdminInfo ( - :chkpf_uid ("{47ACCCC4-3B42-4BE4-8E43-AF61E4E0FB86}") - :ClassName (accept_action) - :table (setup) - ) - :action () - :macro (RECORD_CONN) - :type (accept) - ) - ) - :comments () - :disabled (false) - :global_location (middle) - :through ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :time ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :track ( - : (ReferenceObject - :Name (Log) - :Table (tracks) - :Uid ("{97AEB480-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :dst ( - :AdminInfo ( - :chkpf_uid ("{F16C6F8C-1F05-4B70-87D9-CECE46630C0C}") - :ClassName (rule_destination) - ) - :compound () - :op () - : (ReferenceObject - :Name (Cactus-DMZ1) - :Table (network_objects) - :Uid ("{62523F8E-9AE0-4CC0-82C6-BB41846BA2B7}") - ) - : (ReferenceObject - :Name (Cactus-DMZ2) - :Table (network_objects) - :Uid ("{61AB70E0-5514-43CF-9194-B37A13EC102D}") - ) - ) - :install ( - :AdminInfo ( - :chkpf_uid ("{E18116F6-2DF8-42C8-8F65-D00C902B23AB}") - :ClassName (rule_install) - ) - :compound () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :services ( - :AdminInfo ( - :chkpf_uid ("{FFEF9B1D-B59B-4A07-AEDE-63918094EDB8}") - :ClassName (rule_services) - ) - :compound () - :op () - : (ReferenceObject - :Name (ssh_version_2) - :Table (services) - :Uid ("{CD082D9A-44A6-4CEF-A17D-5541029ADFB3}") - ) - ) - :src ( - :AdminInfo ( - :chkpf_uid ("{2D6919C8-EBF0-46B2-95CE-7FD2AFF8DBF0}") - :ClassName (rule_source) - ) - :compound () - :op () - : (ReferenceObject - :Name (IsoAAAA-100) - :Table (network_objects) - :Uid ("{BF1C6029-8D5D-4A05-A3AD-4B67E6E7A7AA}") - ) - ) - ) - :rule ( - :AdminInfo ( - :chkpf_uid ("{2CDC82FD-6292-45D7-A4B8-6794C378A47B}") - :ClassName (security_rule) - ) - :action ( - : (accept - :AdminInfo ( - :chkpf_uid ("{DBFD040E-D17D-481F-B6E2-D9E5AE306BBD}") - :ClassName (accept_action) - :table (setup) - ) - :action () - :macro (RECORD_CONN) - :type (accept) - ) - ) - :comments () - :disabled (false) - :global_location (middle) - :through ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :time ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :track ( - : (ReferenceObject - :Name (Log) - :Table (tracks) - :Uid ("{97AEB480-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :dst ( - :AdminInfo ( - :chkpf_uid ("{AAADBB03-1A01-4136-8104-91B265E567A3}") - :ClassName (rule_destination) - ) - :compound () - :op () - : (ReferenceObject - :Name (Cactus10.222.0.1) - :Table (network_objects) - :Uid ("{6CD51061-638B-4B2F-9092-7E1E4A5F0ADD}") - ) - ) - :install ( - :AdminInfo ( - :chkpf_uid ("{77D96FA7-8F8F-4F17-9F1C-868F1472C870}") - :ClassName (rule_install) - ) - :compound () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :services ( - :AdminInfo ( - :chkpf_uid ("{A042A0B6-6CD8-4A84-90A5-B39B35590148}") - :ClassName (rule_services) - ) - :compound () - :op () - : (ReferenceObject - :Name (VNC) - :Table (services) - :Uid ("{9788B566-735E-4158-A169-8701B9624E47}") - ) - ) - :src ( - :AdminInfo ( - :chkpf_uid ("{2F62C069-51CA-424D-A3EB-235DD9728611}") - :ClassName (rule_source) - ) - :compound () - :op () - : (ReferenceObject - :Name (IsoAAAA-100) - :Table (network_objects) - :Uid ("{BF1C6029-8D5D-4A05-A3AD-4B67E6E7A7AA}") - ) - ) - ) - :rule ( - :AdminInfo ( - :chkpf_uid ("{8EDEBE48-F02B-4AEA-8337-FBE1E2079BE0}") - :ClassName (security_rule) - ) - :action ( - : (accept - :AdminInfo ( - :chkpf_uid ("{47CF3B75-BE35-45E1-B56E-B8A61ECE885B}") - :ClassName (accept_action) - :table (setup) - ) - :action () - :macro (RECORD_CONN) - :type (accept) - ) - ) - :comments () - :disabled (false) - :global_location (middle) - :through ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :time ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :track ( - : (ReferenceObject - :Name (Log) - :Table (tracks) - :Uid ("{97AEB480-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :dst ( - :AdminInfo ( - :chkpf_uid ("{7149B69F-E170-4FCC-B958-76AE0F704EA0}") - :ClassName (rule_destination) - ) - :compound () - :op () - : (ReferenceObject - :Name (itchy) - :Table (network_objects) - :Uid ("{3B4DF852-5064-4957-B95F-D469C5656467}") - ) - ) - :install ( - :AdminInfo ( - :chkpf_uid ("{50C640DC-6413-458C-BD30-9E947F408315}") - :ClassName (rule_install) - ) - :compound () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :services ( - :AdminInfo ( - :chkpf_uid ("{3F4AF5D6-72D0-4C52-A1BD-29AB242927D0}") - :ClassName (rule_services) - ) - :compound () - :op () - : (ReferenceObject - :Name (domain-udp) - :Table (services) - :Uid ("{97AEB3FA-9AEA-11D5-BD16-0090272CCB30}") - ) - : (ReferenceObject - :Name (CIFS) - :Table (services) - :Uid ("{2A469820-B502-434C-9340-A377677A6A60}") - ) - ) - :src ( - :AdminInfo ( - :chkpf_uid ("{EA36998F-4F7C-4250-BECC-4CEBB36E9EAE}") - :ClassName (rule_source) - ) - :compound () - :op () - : (ReferenceObject - :Name (IsoAAAA-100) - :Table (network_objects) - :Uid ("{BF1C6029-8D5D-4A05-A3AD-4B67E6E7A7AA}") - ) - ) - ) - :rule ( - :AdminInfo ( - :chkpf_uid ("{0F6D252E-7562-457F-81A3-60192F3EC815}") - :ClassName (security_rule) - ) - :action ( - : (accept - :AdminInfo ( - :chkpf_uid ("{0CEE5A08-F53C-439A-8180-A62450938BA6}") - :ClassName (accept_action) - :table (setup) - ) - :action () - :macro (RECORD_CONN) - :type (accept) - ) - ) - :comments () - :disabled (false) - :global_location (middle) - :through ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :time ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :track ( - : (ReferenceObject - :Name (Log) - :Table (tracks) - :Uid ("{97AEB480-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :dst ( - :AdminInfo ( - :chkpf_uid ("{C414C09F-B8D2-4DD6-8DD1-B5044B787753}") - :ClassName (rule_destination) - ) - :compound () - :op () - : (ReferenceObject - :Name (MailServer) - :Table (network_objects) - :Uid ("{17935795-6ADC-4B45-8E2B-BEC361E6CAB1}") - ) - ) - :install ( - :AdminInfo ( - :chkpf_uid ("{1ADD0F50-D00E-463E-AF4B-5F7B9602F8FB}") - :ClassName (rule_install) - ) - :compound () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :services ( - :AdminInfo ( - :chkpf_uid ("{F89128E4-058B-45CC-8BE9-62261DDB22A0}") - :ClassName (rule_services) - ) - :compound () - :op () - : (ReferenceObject - :Name (smtp) - :Table (services) - :Uid ("{97AEB3D9-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :src ( - :AdminInfo ( - :chkpf_uid ("{1265804A-4F79-416E-ABDC-2BC3BC6E9513}") - :ClassName (rule_source) - ) - :compound () - :op () - : (ReferenceObject - :Name (IsoAAAA-100) - :Table (network_objects) - :Uid ("{BF1C6029-8D5D-4A05-A3AD-4B67E6E7A7AA}") - ) - ) - ) - :rule ( - :AdminInfo ( - :chkpf_uid ("{A3B9D85B-AD6D-4991-8A9D-960939C491C2}") - :ClassName (security_rule) - ) - :action ( - : (accept - :AdminInfo ( - :chkpf_uid ("{C8749F14-4AE2-4544-B239-7CC349656359}") - :ClassName (accept_action) - :table (setup) - ) - :action () - :macro (RECORD_CONN) - :type (accept) - ) - ) - :comments () - :disabled (false) - :global_location (middle) - :through ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :time ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :track ( - : (ReferenceObject - :Name (None) - :Table (tracks) - :Uid ("{97AEB47D-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :dst ( - :AdminInfo ( - :chkpf_uid ("{A7BD46F5-7D1D-424F-BBB4-CCE8564D68C7}") - :ClassName (rule_destination) - ) - :compound () - :op () - : (ReferenceObject - :Name (wasp) - :Table (network_objects) - :Uid ("{098B2A74-E220-4AE8-A164-340FED79C9D5}") - ) - ) - :install ( - :AdminInfo ( - :chkpf_uid ("{E6AF42B5-C12E-4E59-8C3E-5D231C5B0D34}") - :ClassName (rule_install) - ) - :compound () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :services ( - :AdminInfo ( - :chkpf_uid ("{A22EE9B9-C603-4998-B273-1568DE4BB27A}") - :ClassName (rule_services) - ) - :compound () - :op () - : (ReferenceObject - :Name (ntp-udp) - :Table (services) - :Uid ("{97AEB404-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :src ( - :AdminInfo ( - :chkpf_uid ("{D0402416-F879-4AD4-88E6-A1DBFEA44546}") - :ClassName (rule_source) - ) - :compound () - :op () - : (ReferenceObject - :Name (IsoAAAA-100) - :Table (network_objects) - :Uid ("{BF1C6029-8D5D-4A05-A3AD-4B67E6E7A7AA}") - ) - ) - ) - :rule ( - :AdminInfo ( - :chkpf_uid ("{7C9A68ED-6420-4D5E-BE91-F7ACE4B90AA5}") - :ClassName (security_header_rule) - ) - :action ( - : (drop - :AdminInfo ( - :chkpf_uid ("{D4BF36D5-49FA-49BD-ADE1-87E488A684D6}") - :ClassName (drop_action) - :table (setup) - ) - :action () - :macro () - :type (drop) - ) - ) - :comments () - :global_location (middle) - :through ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :time ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :track ( - : (ReferenceObject - :Name (None) - :Table (tracks) - :Uid ("{97AEB47D-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :disabled (true) - :dst ( - :AdminInfo ( - :chkpf_uid ("{251B6C16-21CB-4CCE-9B3B-62B66C6F6390}") - :ClassName (rule_destination) - ) - :compound () - :op () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :header_text ("Intern to Internet") - :install ( - :AdminInfo ( - :chkpf_uid ("{A9221EAB-A00F-4E3F-83DF-D44CBC08AFBD}") - :ClassName (rule_install) - ) - :compound () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :services ( - :AdminInfo ( - :chkpf_uid ("{AECCDBA3-A006-464E-9BD9-691255CA5841}") - :ClassName (rule_services) - ) - :compound () - :op () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :src ( - :AdminInfo ( - :chkpf_uid ("{5B2CFCAD-0A44-4BA9-BFF7-6734B5644C85}") - :ClassName (rule_source) - ) - :compound () - :op () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :state (collapsed) - ) - :rule ( - :AdminInfo ( - :chkpf_uid ("{E6AB0ADC-7E23-4B1D-B568-E47FF7B3D4F5}") - :ClassName (security_rule) - ) - :action ( - : (accept - :AdminInfo ( - :chkpf_uid ("{5B685C0A-3095-483A-8DE1-F539677A7707}") - :ClassName (accept_action) - :table (setup) - ) - :action () - :macro (RECORD_CONN) - :type (accept) - ) - ) - :comments () - :disabled (false) - :global_location (middle) - :through ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :time ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :track ( - : (ReferenceObject - :Name (Log) - :Table (tracks) - :Uid ("{97AEB480-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :dst ( - :AdminInfo ( - :chkpf_uid ("{2C9F2F69-7532-4711-A950-C884E1AFD3F5}") - :ClassName (rule_destination) - ) - :compound () - :op () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :install ( - :AdminInfo ( - :chkpf_uid ("{EACA5120-76C3-48CE-AB41-59266A354E0A}") - :ClassName (rule_install) - ) - :compound () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :services ( - :AdminInfo ( - :chkpf_uid ("{DB45ABD4-20F0-4BC8-BD73-294945142FB8}") - :ClassName (rule_services) - ) - :compound () - :op () - : (ReferenceObject - :Name (T-online-classic) - :Table (services) - :Uid ("{738B04E5-09F7-44BF-9FEC-AEA0F15B7E9A}") - ) - : (ReferenceObject - :Name (HBCI) - :Table (services) - :Uid ("{336C93F8-5CC2-48BE-9328-2E92F61EFCF1}") - ) - ) - :src ( - :AdminInfo ( - :chkpf_uid ("{85CAFABE-730E-4DDB-A878-219BD2893B63}") - :ClassName (rule_source) - ) - :compound () - :op () - : (ReferenceObject - :Name (IsoAAAA-100) - :Table (network_objects) - :Uid ("{BF1C6029-8D5D-4A05-A3AD-4B67E6E7A7AA}") - ) - ) - ) - :rule ( - :AdminInfo ( - :chkpf_uid ("{1F4E5C97-C290-48AF-84A5-C1A13178FDB7}") - :ClassName (security_rule) - ) - :action ( - : (accept - :AdminInfo ( - :chkpf_uid ("{DCDCFD96-219D-49B7-B817-8BB52C598AB8}") - :ClassName (accept_action) - :table (setup) - ) - :action () - :macro (RECORD_CONN) - :type (accept) - ) - ) - :comments () - :disabled (false) - :global_location (middle) - :through ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :time ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :track ( - : (ReferenceObject - :Name (Log) - :Table (tracks) - :Uid ("{97AEB480-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :dst ( - :AdminInfo ( - :chkpf_uid ("{3A1A50EC-0F20-4C79-80D7-FDCBEDAF50AF}") - :ClassName (rule_destination) - ) - :compound () - :op () - : (ReferenceObject - :Name (t-onlineUpdate) - :Table (network_objects) - :Uid ("{99089D97-0EB3-4CE6-8C78-79BC61ECE307}") - ) - ) - :install ( - :AdminInfo ( - :chkpf_uid ("{4D0B21D7-8DA0-49D5-9AD2-3F7BBA001C56}") - :ClassName (rule_install) - ) - :compound () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :services ( - :AdminInfo ( - :chkpf_uid ("{0C60636A-9D3B-44D2-9742-966C92ED77A2}") - :ClassName (rule_services) - ) - :compound () - :op () - : (ReferenceObject - :Name (http) - :Table (services) - :Uid ("{97AEB3D4-9AEA-11D5-BD16-0090272CCB30}") - ) - : (ReferenceObject - :Name (https) - :Table (services) - :Uid ("{97AEB443-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :src ( - :AdminInfo ( - :chkpf_uid ("{C9F5FA9C-6AE5-4A04-B68F-E3CFBE3C1043}") - :ClassName (rule_source) - ) - :compound () - :op () - : (ReferenceObject - :Name (IsoAAAA-100) - :Table (network_objects) - :Uid ("{BF1C6029-8D5D-4A05-A3AD-4B67E6E7A7AA}") - ) - ) - ) - :rule ( - :AdminInfo ( - :chkpf_uid ("{8D43F752-841E-4B9E-B610-635F7C17D4D9}") - :ClassName (security_rule) - ) - :action ( - : (accept - :AdminInfo ( - :chkpf_uid ("{7A10F249-7751-407A-A390-A6B878A85D56}") - :ClassName (accept_action) - :table (setup) - ) - :action () - :macro (RECORD_CONN) - :type (accept) - ) - ) - :comments () - :disabled (false) - :global_location (middle) - :through ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :time ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :track ( - : (ReferenceObject - :Name (Log) - :Table (tracks) - :Uid ("{97AEB480-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :dst ( - :AdminInfo ( - :chkpf_uid ("{B42E38C5-299A-4B0E-A7BE-6D87D1206A3C}") - :ClassName (rule_destination) - ) - :compound () - :op () - : (ReferenceObject - :Name (auth1.lhsystems.com) - :Table (network_objects) - :Uid ("{D60E902E-4BE8-43E0-95DC-BFE60E86965F}") - ) - : (ReferenceObject - :Name (LSYI-pptp) - :Table (network_objects) - :Uid ("{DF2F1A45-9938-4006-A550-0421F3DAA3E2}") - ) - ) - :install ( - :AdminInfo ( - :chkpf_uid ("{42DAAE37-A625-47E5-AC05-72E3E3A9F3FE}") - :ClassName (rule_install) - ) - :compound () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :services ( - :AdminInfo ( - :chkpf_uid ("{F8D3DE95-02BB-43E8-B759-01E5AE00233C}") - :ClassName (rule_services) - ) - :compound () - :op () - : (ReferenceObject - :Name (FW1_clntauth_telnet) - :Table (services) - :Uid ("{97AEB38B-9AEA-11D5-BD16-0090272CCB30}") - ) - : (ReferenceObject - :Name (PPTP) - :Table (services) - :Uid ("{97AEB426-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :src ( - :AdminInfo ( - :chkpf_uid ("{B2C3E31C-B79E-49A9-B7A8-2F38E3C21DCF}") - :ClassName (rule_source) - ) - :compound () - :op () - : (ReferenceObject - :Name (IsoAAAA-100) - :Table (network_objects) - :Uid ("{BF1C6029-8D5D-4A05-A3AD-4B67E6E7A7AA}") - ) - ) - ) - :rule ( - :AdminInfo ( - :chkpf_uid ("{167BC623-43EB-405D-BC29-442298C96DC9}") - :ClassName (security_rule) - ) - :action ( - : (accept - :AdminInfo ( - :chkpf_uid ("{BB10481F-21F5-4244-A6BB-29318E780DF1}") - :ClassName (accept_action) - :table (setup) - ) - :action () - :macro (RECORD_CONN) - :type (accept) - ) - ) - :comments () - :disabled (false) - :global_location (middle) - :through ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :time ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :track ( - : (ReferenceObject - :Name (Log) - :Table (tracks) - :Uid ("{97AEB480-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :dst ( - :AdminInfo ( - :chkpf_uid ("{E9BE5C8E-9CAE-4D88-9235-F5AC9030CF0F}") - :ClassName (rule_destination) - ) - :compound () - :op () - : (ReferenceObject - :Table (network_objects) - :Name (mail.light-life.netOld) - :Uid ("{DF004F13-7986-4569-811C-6EC7391A8764}") - ) - ) - :install ( - :AdminInfo ( - :chkpf_uid ("{CDBC19FF-C00F-4304-9D1D-B5BBDAA5D15A}") - :ClassName (rule_install) - ) - :compound () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :services ( - :AdminInfo ( - :chkpf_uid ("{4BE203D0-3DE8-44FE-B942-E5E26C62E861}") - :ClassName (rule_services) - ) - :compound () - :op () - : (ReferenceObject - :Name (smtp) - :Table (services) - :Uid ("{97AEB3D9-9AEA-11D5-BD16-0090272CCB30}") - ) - : (ReferenceObject - :Name (pop-3) - :Table (services) - :Uid ("{97AEB3DB-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :src ( - :AdminInfo ( - :chkpf_uid ("{C3E9CE29-9F23-4857-B88F-E9949FAF2D5D}") - :ClassName (rule_source) - ) - :compound () - :op () - : (ReferenceObject - :Name (speedy2) - :Table (network_objects) - :Uid ("{B4DB2EF5-42D8-41DC-9A1C-33310FDFB184}") - ) - ) - ) - :rule ( - :AdminInfo ( - :chkpf_uid ("{11C81B0A-4266-4801-8858-E4D9AB54A830}") - :ClassName (security_header_rule) - ) - :action ( - : (drop - :AdminInfo ( - :chkpf_uid ("{5E568AEF-0F52-4A93-AFA3-18E73A0D066A}") - :ClassName (drop_action) - :table (setup) - ) - :action () - :macro () - :type (drop) - ) - ) - :comments () - :global_location (middle) - :through ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :time ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :track ( - : (ReferenceObject - :Name (None) - :Table (tracks) - :Uid ("{97AEB47D-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :disabled (true) - :dst ( - :AdminInfo ( - :chkpf_uid ("{366C4CAD-81FB-4025-8D13-601F4A6C8FF7}") - :ClassName (rule_destination) - ) - :compound () - :op () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :header_text ("Access from Spike & DMZ to Internal") - :install ( - :AdminInfo ( - :chkpf_uid ("{47C0018E-3514-4540-A4EA-659755890D6B}") - :ClassName (rule_install) - ) - :compound () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :services ( - :AdminInfo ( - :chkpf_uid ("{0073E27C-28E5-4EC1-9A4A-BD686F700281}") - :ClassName (rule_services) - ) - :compound () - :op () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :src ( - :AdminInfo ( - :chkpf_uid ("{BD3EBBCD-06DF-4313-A347-7097F5105671}") - :ClassName (rule_source) - ) - :compound () - :op () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :state (expanded) - ) - :rule ( - :AdminInfo ( - :chkpf_uid ("{A8A57015-68D5-4341-ADD1-895EC21419DB}") - :ClassName (security_rule) - ) - :action ( - : (accept - :AdminInfo ( - :chkpf_uid ("{BECC33F6-C362-41A4-BBD3-CBFA34A7C4E8}") - :ClassName (accept_action) - :table (setup) - ) - :action () - :macro (RECORD_CONN) - :type (accept) - ) - ) - :comments () - :disabled (false) - :global_location (middle) - :through ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :time ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :track ( - : (ReferenceObject - :Name (Log) - :Table (tracks) - :Uid ("{97AEB480-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :dst ( - :AdminInfo ( - :chkpf_uid ("{193E4DB4-BE9D-4444-BC95-C04C10D26D25}") - :ClassName (rule_destination) - ) - :compound () - :op () - : (ReferenceObject - :Name (IsoAAADray.local) - :Table (network_objects) - :Uid ("{75EDBC62-7EB1-4D37-8295-684903FDA75A}") - ) - : (ReferenceObject - :Name (gateway.local) - :Table (network_objects) - :Uid ("{7ED7EF12-A13E-4303-8A6E-C6CC28755C80}") - ) - ) - :install ( - :AdminInfo ( - :chkpf_uid ("{42CD50F6-AA17-4271-B684-DFF6E86E5649}") - :ClassName (rule_install) - ) - :compound () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :services ( - :AdminInfo ( - :chkpf_uid ("{0B65BDFF-A77E-498D-8F6D-8B77068701D6}") - :ClassName (rule_services) - ) - :compound () - :op () - : (ReferenceObject - :Name (rdp) - :Table (services) - :Uid ("{5BA0C83F-8D91-465B-9CF6-7DC6AEB84689}") - ) - : (ReferenceObject - :Name (http) - :Table (services) - :Uid ("{97AEB3D4-9AEA-11D5-BD16-0090272CCB30}") - ) - : (ReferenceObject - :Name (CIFS) - :Table (services) - :Uid ("{2A469820-B502-434C-9340-A377677A6A60}") - ) - : (ReferenceObject - :Name (UPS-Monitor) - :Table (services) - :Uid ("{8C8DED7E-F3C9-4964-B9D3-063C23997020}") - ) - ) - :src ( - :AdminInfo ( - :chkpf_uid ("{5C3E75D6-41C1-4D28-A34C-D9F0C316599F}") - :ClassName (rule_source) - ) - :compound () - :op () - : (ReferenceObject - :Name (mg.IsoAAAA-es.com) - :Table (network_objects) - :Uid ("{E5BF8260-3615-4476-B638-53CA3A24FEF1}") - ) - ) - ) - :rule ( - :AdminInfo ( - :chkpf_uid ("{5DEBDFAA-F691-4041-8E3A-EAF002F8B690}") - :ClassName (security_rule) - ) - :action ( - : (accept - :AdminInfo ( - :chkpf_uid ("{69531784-EAAE-4C1C-B792-86B14F8D015E}") - :ClassName (accept_action) - :table (setup) - ) - :action () - :macro (RECORD_CONN) - :type (accept) - ) - ) - :comments () - :disabled (false) - :global_location (middle) - :through ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :time ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :track ( - : (ReferenceObject - :Name (Log) - :Table (tracks) - :Uid ("{97AEB480-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :dst ( - :AdminInfo ( - :chkpf_uid ("{FA61FCF6-FF1E-42C6-B329-B8E23A0EB35D}") - :ClassName (rule_destination) - ) - :compound () - :op () - : (ReferenceObject - :Name (scratchy.local) - :Table (network_objects) - :Uid ("{CFABE50C-C1F6-4FF1-8AC3-3161A3779708}") - ) - ) - :install ( - :AdminInfo ( - :chkpf_uid ("{21457A88-FFC3-45C2-A6AD-7ABC8CDD0232}") - :ClassName (rule_install) - ) - :compound () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :services ( - :AdminInfo ( - :chkpf_uid ("{7990665E-448A-420C-BF7D-3616ED9ECB53}") - :ClassName (rule_services) - ) - :compound () - :op () - : (ReferenceObject - :Name (RAdmin-custom) - :Table (services) - :Uid ("{4FB59153-8212-4A12-BC08-0297AA5F0815}") - ) - ) - :src ( - :AdminInfo ( - :chkpf_uid ("{7A4BC3A5-EAB4-4CC3-8F06-5B3681A6A814}") - :ClassName (rule_source) - ) - :compound () - :op () - : (ReferenceObject - :Name (mg.IsoAAAA-es.com) - :Table (network_objects) - :Uid ("{E5BF8260-3615-4476-B638-53CA3A24FEF1}") - ) - ) - ) - :rule ( - :AdminInfo ( - :chkpf_uid ("{DC9D47B1-CEB2-43AB-B32E-5BFACD49181F}") - :ClassName (security_rule) - ) - :action ( - : (accept - :AdminInfo ( - :chkpf_uid ("{841A245A-0BBC-40D6-AFCD-FC0956945DFB}") - :ClassName (accept_action) - :table (setup) - ) - :action () - :macro (RECORD_CONN) - :type (accept) - ) - ) - :comments () - :disabled (false) - :global_location (middle) - :through ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :time ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :track ( - : (ReferenceObject - :Name (Log) - :Table (tracks) - :Uid ("{97AEB480-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :dst ( - :AdminInfo ( - :chkpf_uid ("{940B351D-CBB3-457B-AA5E-BF8EE4721229}") - :ClassName (rule_destination) - ) - :compound () - :op () - : (ReferenceObject - :Name (daba) - :Table (network_objects) - :Uid ("{94817CDB-EA8C-4213-B38D-F4417EA620C6}") - ) - ) - :install ( - :AdminInfo ( - :chkpf_uid ("{6F3DCA16-ECC8-4DAE-8729-3D07CD35A492}") - :ClassName (rule_install) - ) - :compound () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :services ( - :AdminInfo ( - :chkpf_uid ("{6A906112-E832-480B-98E6-7C88D5768449}") - :ClassName (rule_services) - ) - :compound () - :op () - : (ReferenceObject - :Name (mysql) - :Table (services) - :Uid ("{08A07607-EAAA-4A45-AD6E-6020770BD519}") - ) - : (ReferenceObject - :Name (ssh_version_2) - :Table (services) - :Uid ("{CD082D9A-44A6-4CEF-A17D-5541029ADFB3}") - ) - ) - :src ( - :AdminInfo ( - :chkpf_uid ("{124122B3-1A04-4980-AA2E-18B01C4BA2A1}") - :ClassName (rule_source) - ) - :compound () - :op () - : (ReferenceObject - :Name (mg.IsoAAAA-es.com) - :Table (network_objects) - :Uid ("{E5BF8260-3615-4476-B638-53CA3A24FEF1}") - ) - ) - ) - :rule ( - :AdminInfo ( - :chkpf_uid ("{B706F7FA-C0AA-41E6-9BE1-99FAA2073339}") - :ClassName (security_rule) - ) - :action ( - : (accept - :AdminInfo ( - :chkpf_uid ("{23C4BFFE-0F58-4C89-9AC6-EE8475E30FB2}") - :ClassName (accept_action) - :table (setup) - ) - :action () - :macro (RECORD_CONN) - :type (accept) - ) - ) - :comments () - :disabled (false) - :global_location (middle) - :through ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :time ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :track ( - : (ReferenceObject - :Name (Log) - :Table (tracks) - :Uid ("{97AEB480-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :dst ( - :AdminInfo ( - :chkpf_uid ("{3DEE2329-18AC-4C21-95A5-49D3F42BC058}") - :ClassName (rule_destination) - ) - :compound () - :op () - : (ReferenceObject - :Name (hpux) - :Table (network_objects) - :Uid ("{BF00A847-A0D6-4A75-BE1C-27E7D91EDB55}") - ) - ) - :install ( - :AdminInfo ( - :chkpf_uid ("{31E7DAD2-17B6-484F-87B3-A9817437F6C3}") - :ClassName (rule_install) - ) - :compound () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :services ( - :AdminInfo ( - :chkpf_uid ("{645119AD-FF40-4617-BB77-CE2B7679B804}") - :ClassName (rule_services) - ) - :compound () - :op () - : (ReferenceObject - :Name (telnet) - :Table (services) - :Uid ("{97AEB3CF-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :src ( - :AdminInfo ( - :chkpf_uid ("{A15D212E-0F94-4C31-82C3-83292476F567}") - :ClassName (rule_source) - ) - :compound () - :op () - : (ReferenceObject - :Name (mg.IsoAAAA-es.com) - :Table (network_objects) - :Uid ("{E5BF8260-3615-4476-B638-53CA3A24FEF1}") - ) - ) - ) - :rule ( - :AdminInfo ( - :chkpf_uid ("{2B48CB5C-959B-4212-83BA-D0C31C9E81FD}") - :ClassName (security_rule) - ) - :action ( - : (accept - :AdminInfo ( - :chkpf_uid ("{23DAD50B-1BFA-4B5A-BD07-91F594590169}") - :ClassName (accept_action) - :table (setup) - ) - :action () - :macro (RECORD_CONN) - :type (accept) - ) - ) - :disabled (false) - :global_location (middle) - :through ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :time ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :track ( - : (ReferenceObject - :Name (Log) - :Table (tracks) - :Uid ("{97AEB480-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :comments ("SUS-Access 4 Stichling") - :dst ( - :AdminInfo ( - :chkpf_uid ("{401D98F2-0790-42A8-A27B-4CEF1B409D62}") - :ClassName (rule_destination) - ) - :compound () - :op () - : (ReferenceObject - :Name (IsoAAADray.local) - :Table (network_objects) - :Uid ("{75EDBC62-7EB1-4D37-8295-684903FDA75A}") - ) - ) - :install ( - :AdminInfo ( - :chkpf_uid ("{C607E30B-AD42-4EB9-861C-3E1F17B01A58}") - :ClassName (rule_install) - ) - :compound () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :services ( - :AdminInfo ( - :chkpf_uid ("{F70D3F8A-F47F-4E46-AC7C-6439659AD77F}") - :ClassName (rule_services) - ) - :compound () - :op () - : (ReferenceObject - :Name (http) - :Table (services) - :Uid ("{97AEB3D4-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :src ( - :AdminInfo ( - :chkpf_uid ("{66A8B48D-384B-47C2-AE14-EFA8C5BD981F}") - :ClassName (rule_source) - ) - :compound () - :op () - : (ReferenceObject - :Name (Cactus10.222.0.1) - :Table (network_objects) - :Uid ("{6CD51061-638B-4B2F-9092-7E1E4A5F0ADD}") - ) - ) - ) - :rule ( - :AdminInfo ( - :chkpf_uid ("{B63983F0-BF08-44F7-88EA-5DF0FA381C45}") - :ClassName (security_header_rule) - ) - :action ( - : (drop - :AdminInfo ( - :chkpf_uid ("{D47409A0-8070-4258-802B-E234DE03D219}") - :ClassName (drop_action) - :table (setup) - ) - :action () - :macro () - :type (drop) - ) - ) - :comments () - :global_location (middle) - :through ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :time ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :track ( - : (ReferenceObject - :Name (None) - :Table (tracks) - :Uid ("{97AEB47D-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :disabled (true) - :dst ( - :AdminInfo ( - :chkpf_uid ("{34E31CD9-5F62-46B6-A5A2-2A25A3381BFF}") - :ClassName (rule_destination) - ) - :compound () - :op () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :header_text (Final-rules) - :install ( - :AdminInfo ( - :chkpf_uid ("{97A07F1F-7C42-469E-8976-4694BEA0C05F}") - :ClassName (rule_install) - ) - :compound () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :services ( - :AdminInfo ( - :chkpf_uid ("{AE52657F-1C63-427D-899A-2739B143874D}") - :ClassName (rule_services) - ) - :compound () - :op () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :src ( - :AdminInfo ( - :chkpf_uid ("{7D15F5BF-41C8-4674-A2A5-96AC297EB840}") - :ClassName (rule_source) - ) - :compound () - :op () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :state (expanded) - ) - :rule ( - :AdminInfo ( - :chkpf_uid ("{E079D5BF-271E-4004-B4C5-8372C37B4661}") - :ClassName (security_rule) - ) - :action ( - : (accept - :AdminInfo ( - :chkpf_uid ("{EBF89D8A-D923-4469-9179-4209815688BC}") - :ClassName (accept_action) - :table (setup) - ) - :action () - :macro (RECORD_CONN) - :type (accept) - ) - ) - :comments () - :disabled (false) - :global_location (middle) - :through ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :time ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :track ( - : (ReferenceObject - :Name (Log) - :Table (tracks) - :Uid ("{97AEB480-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :dst ( - :AdminInfo ( - :chkpf_uid ("{93E9E478-F918-450E-8D36-280C86415DB8}") - :ClassName (rule_destination) - ) - :compound () - :op () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :install ( - :AdminInfo ( - :chkpf_uid ("{F546BB1C-8E90-4AEA-9C17-188FDA697E98}") - :ClassName (rule_install) - ) - :compound () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :services ( - :AdminInfo ( - :chkpf_uid ("{5576A25C-181D-40DB-8978-F8E8B6D19C4E}") - :ClassName (rule_services) - ) - :compound () - :op () - : (ReferenceObject - :Name (ICMPgute) - :Table (services) - :Uid ("{418C7C0A-956A-41FF-9BC1-5867B2265090}") - ) - ) - :src ( - :AdminInfo ( - :chkpf_uid ("{4B989FE8-BC56-4B8C-BD37-C6050AAC2B28}") - :ClassName (rule_source) - ) - :compound () - :op () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - ) - :rule ( - :AdminInfo ( - :chkpf_uid ("{89F7C56B-1A5F-4C4A-BC98-F777664BBEC9}") - :ClassName (security_rule) - ) - :action ( - : (accept - :AdminInfo ( - :chkpf_uid ("{BD3A43B7-179B-4A44-9E8E-BDA3C4D74428}") - :ClassName (accept_action) - :table (setup) - ) - :action () - :macro (RECORD_CONN) - :type (accept) - ) - ) - :comments () - :disabled (false) - :global_location (middle) - :through ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :time ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :track ( - : (ReferenceObject - :Name (Log) - :Table (tracks) - :Uid ("{97AEB480-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :dst ( - :AdminInfo ( - :chkpf_uid ("{787E51C4-3375-4608-A83C-CFF3D08628B5}") - :ClassName (rule_destination) - ) - :compound () - :op () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :install ( - :AdminInfo ( - :chkpf_uid ("{C67E7D9D-F7A6-4B80-AB31-589BDF22583D}") - :ClassName (rule_install) - ) - :compound () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :services ( - :AdminInfo ( - :chkpf_uid ("{E732300C-E9E8-4CC7-B0B1-1566947A92A0}") - :ClassName (rule_services) - ) - :compound () - :op () - : (ReferenceObject - :Name (redirect) - :Table (services) - :Uid ("{97AEB409-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :src ( - :AdminInfo ( - :chkpf_uid ("{DB1AE486-D8A3-44F0-AA73-AE22B0BA4A32}") - :ClassName (rule_source) - ) - :compound () - :op () - : (ReferenceObject - :Name (IsoAAAD) - :Table (network_objects) - :Uid ("{29C40B0A-414C-11D7-AEB8-7F0000013C3C}") - ) - ) - ) - :rule ( - :AdminInfo ( - :chkpf_uid ("{F134ED1C-8FC1-4ED1-9751-39EE88C79BAA}") - :ClassName (security_rule) - ) - :action ( - : (reject - :AdminInfo ( - :chkpf_uid ("{619449DF-3B19-42EF-A640-40BF30E1E398}") - :ClassName (reject_action) - :table (setup) - ) - :action () - :macro () - :type (reject) - ) - ) - :comments () - :disabled (false) - :global_location (middle) - :through ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :time ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :track ( - : (ReferenceObject - :Name (None) - :Table (tracks) - :Uid ("{97AEB47D-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :dst ( - :AdminInfo ( - :chkpf_uid ("{F3772580-72F8-47FD-BEEF-64F0C4AE29AC}") - :ClassName (rule_destination) - ) - :compound () - :op () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :install ( - :AdminInfo ( - :chkpf_uid ("{FF327589-E587-4324-B33B-EAEA6BF3D977}") - :ClassName (rule_install) - ) - :compound () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :services ( - :AdminInfo ( - :chkpf_uid ("{367A55E3-5596-40A1-A0C9-63CEA70F42C3}") - :ClassName (rule_services) - ) - :compound () - :op () - : (ReferenceObject - :Name (Drop_nologServices) - :Table (services) - :Uid ("{495E1A16-2612-49D9-8F69-B00EB33699E8}") - ) - ) - :src ( - :AdminInfo ( - :chkpf_uid ("{AFD6C077-CA8E-4C7D-A834-F781B7821B96}") - :ClassName (rule_source) - ) - :compound () - :op () - : (ReferenceObject - :Name (IsoAAAA-100) - :Table (network_objects) - :Uid ("{BF1C6029-8D5D-4A05-A3AD-4B67E6E7A7AA}") - ) - ) - ) - :rule ( - :AdminInfo ( - :chkpf_uid ("{7067EE72-61D1-4555-9832-8E9279772BCA}") - :ClassName (security_rule) - ) - :action ( - : (reject - :AdminInfo ( - :chkpf_uid ("{D06A4524-1DCA-4DD5-BCC2-54EE451C1777}") - :ClassName (reject_action) - :table (setup) - ) - :action () - :macro () - :type (reject) - ) - ) - :comments () - :disabled (false) - :global_location (middle) - :through ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :time ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :track ( - : (ReferenceObject - :Name (None) - :Table (tracks) - :Uid ("{97AEB47D-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :dst ( - :AdminInfo ( - :chkpf_uid ("{FFD672A3-65E6-4B19-B686-D40AC4299BCD}") - :ClassName (rule_destination) - ) - :compound () - :op () - : (ReferenceObject - :Name (Drop_nologDest) - :Table (network_objects) - :Uid ("{79369987-B128-4B3F-827C-3C936F7C3F53}") - ) - ) - :install ( - :AdminInfo ( - :chkpf_uid ("{0581A769-6452-42CD-9718-F226767D0287}") - :ClassName (rule_install) - ) - :compound () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :services ( - :AdminInfo ( - :chkpf_uid ("{F037BEDF-CC8F-4792-9A21-103C9F5C2A51}") - :ClassName (rule_services) - ) - :compound () - :op () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :src ( - :AdminInfo ( - :chkpf_uid ("{7B4EF795-BE09-45A2-86B9-1CE030756ECB}") - :ClassName (rule_source) - ) - :compound () - :op () - : (ReferenceObject - :Name (IsoAAAA-100) - :Table (network_objects) - :Uid ("{BF1C6029-8D5D-4A05-A3AD-4B67E6E7A7AA}") - ) - ) - ) - :rule ( - :AdminInfo ( - :chkpf_uid ("{A6F53BCD-748C-4585-B8FB-1DF23129F085}") - :ClassName (security_rule) - ) - :action ( - : (reject - :AdminInfo ( - :chkpf_uid ("{4F089C9B-C148-4A8A-8ED5-38618067B567}") - :ClassName (reject_action) - :table (setup) - ) - :action () - :macro () - :type (reject) - ) - ) - :comments () - :disabled (false) - :global_location (middle) - :through ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :time ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :track ( - : (ReferenceObject - :Name (Log) - :Table (tracks) - :Uid ("{97AEB480-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :dst ( - :AdminInfo ( - :chkpf_uid ("{34CE5F02-44F0-4180-BE48-5CB31E82D728}") - :ClassName (rule_destination) - ) - :compound () - :op () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :install ( - :AdminInfo ( - :chkpf_uid ("{7AD6114F-E8FF-4AE9-BAA8-6B72CA08F552}") - :ClassName (rule_install) - ) - :compound () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :services ( - :AdminInfo ( - :chkpf_uid ("{33DEA2EB-F713-400E-96E1-AACE576E28AB}") - :ClassName (rule_services) - ) - :compound () - :op () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :src ( - :AdminInfo ( - :chkpf_uid ("{4F305BBD-E049-4054-BCEC-A0D4F832CD80}") - :ClassName (rule_source) - ) - :compound () - :op () - : (ReferenceObject - :Name (CactusDA) - :Table (network_objects) - :Uid ("{69DBB75C-7E6D-49AD-A814-96F1BAFF12F7}") - ) - ) - ) - :rule ( - :AdminInfo ( - :chkpf_uid ("{9CD8CE05-32DB-483A-A44A-0C9131CCA022}") - :ClassName (security_rule) - ) - :action ( - : (drop - :AdminInfo ( - :chkpf_uid ("{ED025D2F-5D51-4310-AEF3-67A075F171EB}") - :ClassName (drop_action) - :table (setup) - ) - :action () - :macro () - :type (drop) - ) - ) - :comments () - :disabled (false) - :global_location (middle) - :through ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :time ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :track ( - : (ReferenceObject - :Name (Log) - :Table (tracks) - :Uid ("{97AEB480-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :dst ( - :AdminInfo ( - :chkpf_uid ("{92629D3F-DD0B-4864-A91A-9809A211E481}") - :ClassName (rule_destination) - ) - :compound () - :op () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :install ( - :AdminInfo ( - :chkpf_uid ("{92064B95-86EE-43B6-9410-C38676F3D964}") - :ClassName (rule_install) - ) - :compound () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :services ( - :AdminInfo ( - :chkpf_uid ("{C0176725-D8C5-412D-A5C3-65BA48662B1D}") - :ClassName (rule_services) - ) - :compound () - :op () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :src ( - :AdminInfo ( - :chkpf_uid ("{FB79D7A9-F91C-40F7-8DA7-303B39A7DC33}") - :ClassName (rule_source) - ) - :compound () - :op () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - ) - :rule_adtr ( - :AdminInfo ( - :chkpf_uid ("{795A2E9C-E2BD-4674-AB77-023F50036168}") - :ClassName (address_translation_rule) - ) - :comments () - :dst_adtr ( - : (ReferenceObject - :Name (IsoAAAA-100) - :Table (network_objects) - :Uid ("{BF1C6029-8D5D-4A05-A3AD-4B67E6E7A7AA}") - ) - ) - :global_location (middle) - :install ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :rule_block_number (1) - :services_adtr ( - : (ReferenceObject - :Name (CIFS) - :Table (services) - :Uid ("{2A469820-B502-434C-9340-A377677A6A60}") - ) - ) - :src_adtr ( - : (ReferenceObject - :Name (IsoAAAA_home_test_3) - :Table (network_objects) - :Uid ("{3B37A3DE-4411-4FFC-9E54-3ABC5C4F693B}") - ) - ) - :disabled (true) - :dst_adtr_translated ( - :AdminInfo ( - :chkpf_uid ("{A735AA42-250D-4EA5-B52A-05685A6124C3}") - :ClassName (translate_static) - ) - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - :adtr_method (adtr_method_static) - ) - :services_adtr_translated ( - :AdminInfo ( - :chkpf_uid ("{12B449F6-1F99-4060-BCB0-4A9DB5B463B3}") - :ClassName (service_translate) - ) - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - :adtr_method (adtr_method_static) - ) - :src_adtr_translated ( - :AdminInfo ( - :chkpf_uid ("{55591259-4F5C-498E-BF64-59C9C7E941A1}") - :ClassName (translate_static) - ) - : (ReferenceObject - :Name (Cactus_home_test_2) - :Table (network_objects) - :Uid ("{3CB93962-2930-41A7-8067-FC373151BB91}") - ) - :adtr_method (adtr_method_static) - ) - ) - :rule_adtr ( - :AdminInfo ( - :chkpf_uid ("{BBC0B2D9-0852-4DE8-AFB2-C27B6049C3AE}") - :ClassName (address_translation_rule) - ) - :comments () - :disabled (false) - :dst_adtr ( - : (ReferenceObject - :Name (IsoAAAA-100) - :Table (network_objects) - :Uid ("{BF1C6029-8D5D-4A05-A3AD-4B67E6E7A7AA}") - ) - ) - :global_location (middle) - :install ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :rule_block_number (1) - :services_adtr ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :src_adtr ( - : (ReferenceObject - :Name (Cactus-InternetTransfer) - :Table (network_objects) - :Uid ("{408C820D-33A1-4E25-B576-EC826F525DCD}") - ) - ) - :dst_adtr_translated ( - :AdminInfo ( - :chkpf_uid ("{5DD7A06F-C26F-47A8-AFBC-2649EE40DAAF}") - :ClassName (translate_static) - ) - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - :adtr_method (adtr_method_static) - ) - :services_adtr_translated ( - :AdminInfo ( - :chkpf_uid ("{D9D74C97-AC50-4633-A4BE-AD9DF32ED7B8}") - :ClassName (service_translate) - ) - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - :adtr_method (adtr_method_static) - ) - :src_adtr_translated ( - :AdminInfo ( - :chkpf_uid ("{404CEBC7-55D9-4A9A-98AC-10A264BC9F08}") - :ClassName (translate_hide) - ) - : (ReferenceObject - :Name (IsoAAAD_intern) - :Table (network_objects) - :Uid ("{40831AE2-CB84-46D2-9522-F987BC10BDB9}") - ) - :adtr_method (adtr_method_hide) - ) - ) - :rule_adtr ( - :AdminInfo ( - :chkpf_uid ("{795A2E9C-E2BD-4674-AB77-023F50036168}") - :ClassName (address_translation_rule) - ) - :comments () - :disabled (false) - :dst_adtr ( - : (ReferenceObject - :Name (IsoAAADray.local) - :Table (network_objects) - :Uid ("{75EDBC62-7EB1-4D37-8295-684903FDA75A}") - ) - ) - :global_location (middle) - :install ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :rule_block_number (1) - :services_adtr ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :src_adtr ( - : (ReferenceObject - :Name (heag_off_upper) - :Table (network_objects) - :Uid ("{A58E3E67-0517-485F-AA04-97A12BC119C3}") - ) - ) - :dst_adtr_translated ( - :AdminInfo ( - :chkpf_uid ("{5C6895F5-E9DC-4A23-8A54-0DFAB2B7BE72}") - :ClassName (translate_static) - ) - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - :adtr_method (adtr_method_static) - ) - :services_adtr_translated ( - :AdminInfo ( - :chkpf_uid ("{4C474EB4-0463-4982-B6CE-2B5AF7708E63}") - :ClassName (service_translate) - ) - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - :adtr_method (adtr_method_static) - ) - :src_adtr_translated ( - :AdminInfo ( - :chkpf_uid ("{50C50462-F4F4-4619-B04A-5C4DB56D0F6A}") - :ClassName (translate_hide) - ) - : (ReferenceObject - :Name (IsoAAAD_intern) - :Table (network_objects) - :Uid ("{40831AE2-CB84-46D2-9522-F987BC10BDB9}") - ) - :adtr_method (adtr_method_hide) - ) - ) - :rule_adtr ( - :AdminInfo ( - :chkpf_uid ("{1D294F6F-03B3-4CAB-B5FF-5CAEB867C8D0}") - :ClassName (address_translation_rule) - ) - :comments () - :disabled (false) - :dst_adtr ( - : (ReferenceObject - :Name (LSYI-WWA) - :Table (network_objects) - :Uid ("{3ECB1B79-1A26-41A3-90F9-71BE179A7211}") - ) - ) - :global_location (middle) - :install ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :rule_block_number (1) - :services_adtr ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :src_adtr ( - : (ReferenceObject - :Name (IsoAAAA-100) - :Table (network_objects) - :Uid ("{BF1C6029-8D5D-4A05-A3AD-4B67E6E7A7AA}") - ) - ) - :dst_adtr_translated ( - :AdminInfo ( - :chkpf_uid ("{8E14CB91-D19B-40A6-8784-8554E1B86BE4}") - :ClassName (translate_static) - ) - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - :adtr_method (adtr_method_static) - ) - :services_adtr_translated ( - :AdminInfo ( - :chkpf_uid ("{5E8C8FCF-5707-4638-81A3-B20DFB9C42C9}") - :ClassName (service_translate) - ) - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - :adtr_method (adtr_method_static) - ) - :src_adtr_translated ( - :AdminInfo ( - :chkpf_uid ("{6A960E2C-D9AD-44BC-B3B2-F5F3DC5992DA}") - :ClassName (translate_static) - ) - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - :adtr_method (adtr_method_static) - ) - ) - :rule_adtr ( - :AdminInfo ( - :chkpf_uid ("{434891D2-F2AE-4B89-88AD-540EB2A0C83A}") - :ClassName (address_translation_rule) - ) - :comments () - :dst_adtr ( - : (ReferenceObject - :Name (t-online) - :Table (network_objects) - :Uid ("{C3D65C4B-6498-4E00-9BAF-15539231E8EE}") - ) - ) - :global_location (middle) - :install ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :rule_block_number (1) - :services_adtr ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :src_adtr ( - : (ReferenceObject - :Name (IsoAAAA-100) - :Table (network_objects) - :Uid ("{BF1C6029-8D5D-4A05-A3AD-4B67E6E7A7AA}") - ) - ) - :disabled (true) - :dst_adtr_translated ( - :AdminInfo ( - :chkpf_uid ("{02FA831E-4B9C-4943-9EDA-AEA384241460}") - :ClassName (translate_static) - ) - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - :adtr_method (adtr_method_static) - ) - :services_adtr_translated ( - :AdminInfo ( - :chkpf_uid ("{6DC1B358-0DE4-49CF-B496-D0006744DA88}") - :ClassName (service_translate) - ) - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - :adtr_method (adtr_method_static) - ) - :src_adtr_translated ( - :AdminInfo ( - :chkpf_uid ("{F1DC8420-40C4-4CAE-A612-C9EC4518BBCA}") - :ClassName (translate_static) - ) - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - :adtr_method (adtr_method_static) - ) - ) - :rule_adtr ( - :AdminInfo ( - :chkpf_uid ("{4BBFC8B5-8B70-4AE2-BC71-6BCF4B17F7B6}") - :ClassName (address_translation_rule) - ) - :comments () - :disabled (false) - :dst_adtr ( - : (ReferenceObject - :Name (spike.local) - :Table (network_objects) - :Uid ("{4ABDD8DE-0DA2-46E5-B129-85E3977CBD18}") - ) - ) - :global_location (middle) - :install ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :rule_block_number (1) - :services_adtr ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :src_adtr ( - : (ReferenceObject - :Name (IsoAAAA-100) - :Table (network_objects) - :Uid ("{BF1C6029-8D5D-4A05-A3AD-4B67E6E7A7AA}") - ) - ) - :dst_adtr_translated ( - :AdminInfo ( - :chkpf_uid ("{7AA3058F-6816-45D2-A6DE-B54CBB46BD08}") - :ClassName (translate_static) - ) - : (ReferenceObject - :Name (mg.IsoAAAA-es.com) - :Table (network_objects) - :Uid ("{E5BF8260-3615-4476-B638-53CA3A24FEF1}") - ) - :adtr_method (adtr_method_static) - ) - :services_adtr_translated ( - :AdminInfo ( - :chkpf_uid ("{ED35E27D-FA79-48B3-8AC5-27502A7FDB71}") - :ClassName (service_translate) - ) - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - :adtr_method (adtr_method_static) - ) - :src_adtr_translated ( - :AdminInfo ( - :chkpf_uid ("{800AC60D-FE78-47F3-B9F1-8F8F468708C1}") - :ClassName (translate_static) - ) - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - :adtr_method (adtr_method_static) - ) - ) - :rule_adtr ( - :AdminInfo ( - :chkpf_uid ("{5CF61260-14E3-42BB-81E6-EBE8EFE8AF4A}") - :ClassName (address_translation_rule) - ) - :comments () - :disabled (false) - :dst_adtr ( - : (ReferenceObject - :Name (mg.IsoAAAA-es.com) - :Table (network_objects) - :Uid ("{E5BF8260-3615-4476-B638-53CA3A24FEF1}") - ) - ) - :global_location (middle) - :install ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :rule_block_number (1) - :services_adtr ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :src_adtr ( - : (ReferenceObject - :Name (IsoAAAA-100) - :Table (network_objects) - :Uid ("{BF1C6029-8D5D-4A05-A3AD-4B67E6E7A7AA}") - ) - ) - :dst_adtr_translated ( - :AdminInfo ( - :chkpf_uid ("{098ADCE5-568E-4F27-ABF9-682BBE442FE7}") - :ClassName (translate_static) - ) - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - :adtr_method (adtr_method_static) - ) - :services_adtr_translated ( - :AdminInfo ( - :chkpf_uid ("{36B74AF0-631F-40BD-B592-5ED305639070}") - :ClassName (service_translate) - ) - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - :adtr_method (adtr_method_static) - ) - :src_adtr_translated ( - :AdminInfo ( - :chkpf_uid ("{41B82ACB-215E-4320-B02C-A86A08EEEFC9}") - :ClassName (translate_static) - ) - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - :adtr_method (adtr_method_static) - ) - ) - :rule_adtr ( - :AdminInfo ( - :chkpf_uid ("{44B823A7-B08B-4A9F-BF4E-F895E1BAE762}") - :ClassName (address_translation_rule) - ) - :comments () - :disabled (false) - :dst_adtr ( - : (ReferenceObject - :Name (IsoAAAA-100) - :Table (network_objects) - :Uid ("{BF1C6029-8D5D-4A05-A3AD-4B67E6E7A7AA}") - ) - ) - :global_location (middle) - :install ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :rule_block_number (1) - :services_adtr ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :src_adtr ( - : (ReferenceObject - :Name (Cactus-Official) - :Table (network_objects) - :Uid ("{2136B4E8-3ABF-4931-BDB9-12CDF457D4A4}") - ) - ) - :dst_adtr_translated ( - :AdminInfo ( - :chkpf_uid ("{F9494163-1D8B-45BE-A547-0786801699CD}") - :ClassName (translate_static) - ) - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - :adtr_method (adtr_method_static) - ) - :services_adtr_translated ( - :AdminInfo ( - :chkpf_uid ("{13C447D5-A284-4282-B584-A1B7ED1DE70C}") - :ClassName (service_translate) - ) - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - :adtr_method (adtr_method_static) - ) - :src_adtr_translated ( - :AdminInfo ( - :chkpf_uid ("{007B4C50-EC16-45E9-8CD5-A3C71764175C}") - :ClassName (translate_static) - ) - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - :adtr_method (adtr_method_static) - ) - ) - :rule_adtr ( - :AdminInfo ( - :chkpf_uid ("{05A4371B-C62D-4CE9-AD5F-9818F9D852BE}") - :ClassName (address_translation_rule) - ) - :comments () - :disabled (false) - :dst_adtr ( - : (ReferenceObject - :Name (IsoAAAA-100) - :Table (network_objects) - :Uid ("{BF1C6029-8D5D-4A05-A3AD-4B67E6E7A7AA}") - ) - ) - :global_location (middle) - :install ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :rule_block_number (1) - :services_adtr ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :src_adtr ( - : (ReferenceObject - :Name (allNet) - :Table (network_objects) - :Uid ("{8C20ECB8-A6DB-4C35-B79A-D12ECE559C77}") - ) - ) - :dst_adtr_translated ( - :AdminInfo ( - :chkpf_uid ("{39606C16-F893-466A-9D38-B01857A51FEB}") - :ClassName (translate_static) - ) - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - :adtr_method (adtr_method_static) - ) - :services_adtr_translated ( - :AdminInfo ( - :chkpf_uid ("{19200950-6F5C-4AA2-939A-3CE7D6ACA81D}") - :ClassName (service_translate) - ) - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - :adtr_method (adtr_method_static) - ) - :src_adtr_translated ( - :AdminInfo ( - :chkpf_uid ("{C74080E8-0E7B-4D2E-8FAA-346607D856EC}") - :ClassName (translate_hide) - ) - : (ReferenceObject - :Name (IsoAAAD_intern) - :Table (network_objects) - :Uid ("{40831AE2-CB84-46D2-9522-F987BC10BDB9}") - ) - :adtr_method (adtr_method_hide) - ) - ) - :rule_adtr ( - :AdminInfo ( - :chkpf_uid ("{770C7861-8D4D-45BD-9A08-6D7412464847}") - :ClassName (address_translation_rule) - ) - :comments () - :disabled (false) - :dst_adtr ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :global_location (middle) - :install ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :rule_block_number (1) - :services_adtr ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :src_adtr ( - : (ReferenceObject - :Name (IsoAAAA-100) - :Table (network_objects) - :Uid ("{BF1C6029-8D5D-4A05-A3AD-4B67E6E7A7AA}") - ) - ) - :dst_adtr_translated ( - :AdminInfo ( - :chkpf_uid ("{323C02BB-1CA8-4AF0-B778-CE65AB57FDA1}") - :ClassName (translate_static) - ) - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - :adtr_method (adtr_method_static) - ) - :services_adtr_translated ( - :AdminInfo ( - :chkpf_uid ("{26E182C6-DB5F-462F-BD1B-8C37735E86F7}") - :ClassName (service_translate) - ) - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - :adtr_method (adtr_method_static) - ) - :src_adtr_translated ( - :AdminInfo ( - :chkpf_uid ("{8FA593D7-47A4-4AAC-BA66-34C93515C7F0}") - :ClassName (translate_hide) - ) - : (ReferenceObject - :Name (IsoAAAD_extern) - :Table (network_objects) - :Uid ("{DB456CE7-0DCA-423F-A5E4-9FA976C0B594}") - ) - :adtr_method (adtr_method_hide) - ) - ) - :use_VPN_communities (true) - ) - :rule-base ("##IsoAAAA-traditional" - :AdminInfo ( - :chkpf_uid ("{83E0AC16-D70B-4E9F-8694-9C50BA2DAE92}") - :ClassName (firewall_policy) - :table (fw_policies) - :LastModified ( - :Time ("Thu Jun 23 14:33:36 2005") - :By (IsoAAAF) - :From (IsoAAADray) - ) - ) - :default (0) - :queries () - :queries_adtr () - :collection (ReferenceObject - :Name (IsoAAAA-traditional) - :Table (policies_collections) - :Uid ("{8EA5AF0F-7640-4BF9-8E5B-577091884205}") - ) - :rule ( - :AdminInfo ( - :chkpf_uid ("{55AED8D2-A87C-4234-8F39-3E462469A75E}") - :ClassName (security_header_rule) - ) - :action ( - : (drop - :AdminInfo ( - :chkpf_uid ("{A80DF4EA-A769-4C2F-AFFA-437000BAABF3}") - :ClassName (drop_action) - :table (setup) - ) - :action () - :macro () - :type (drop) - ) - ) - :comments () - :global_location (middle) - :through ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :time ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :track ( - : (ReferenceObject - :Name (None) - :Table (tracks) - :Uid ("{97AEB47D-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :disabled (true) - :dst ( - :AdminInfo ( - :chkpf_uid ("{4AC2A92C-B41D-475E-BD2B-46F614A14D53}") - :ClassName (rule_destination) - ) - :compound () - :op () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :header_text ("IsoAAAE SecuRemote") - :install ( - :AdminInfo ( - :chkpf_uid ("{D2F4F31B-A96B-4CC3-AC8F-E42E4B0C6E38}") - :ClassName (rule_install) - ) - :compound () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :services ( - :AdminInfo ( - :chkpf_uid ("{28DCAD14-2A26-4980-A1EA-A328C525AA6D}") - :ClassName (rule_services) - ) - :compound () - :op () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :src ( - :AdminInfo ( - :chkpf_uid ("{11AE059A-0887-4864-A96E-573D0AB9B8D1}") - :ClassName (rule_source) - ) - :compound () - :op () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :state (expanded) - ) - :rule ( - :AdminInfo ( - :chkpf_uid ("{6E78B459-91E5-4755-B4BF-CD7E19BFFF69}") - :ClassName (security_rule) - ) - :action ( - : ("Client Encrypt" - :AdminInfo ( - :chkpf_uid ("{2AFD1828-E320-4ED5-BAC4-7B8B6977CD41}") - :ClassName (client_encrypt) - :table (setup) - ) - :action (accept) - :dst_options ("Intersect with User Database") - :enforce_desktop_config (false) - :macro (USER_CLIENT_ENCRYPTION) - :src_options ("Intersect with User Database") - :type (userc) - ) - ) - :comments () - :disabled (false) - :global_location (middle) - :through ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :time ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :track ( - : (ReferenceObject - :Name (Log) - :Table (tracks) - :Uid ("{97AEB480-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :dst ( - :AdminInfo ( - :chkpf_uid ("{E71C16B9-A6B6-408C-80BA-5CF08A1F46CA}") - :ClassName (rule_destination) - ) - :compound () - :op () - : (ReferenceObject - :Name (IsoAAADray.local) - :Table (network_objects) - :Uid ("{75EDBC62-7EB1-4D37-8295-684903FDA75A}") - ) - : (ReferenceObject - :Name (gateway.local) - :Table (network_objects) - :Uid ("{7ED7EF12-A13E-4303-8A6E-C6CC28755C80}") - ) - ) - :install ( - :AdminInfo ( - :chkpf_uid ("{C920DC45-AC36-4E6C-AE40-7D36535BCA8C}") - :ClassName (rule_install) - ) - :compound () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :services ( - :AdminInfo ( - :chkpf_uid ("{C01056E7-2861-40A0-B8B8-CFD83C4503E3}") - :ClassName (rule_services) - ) - :compound () - :op () - : (ReferenceObject - :Name (NBT) - :Table (services) - :Uid ("{97AEB471-9AEA-11D5-BD16-0090272CCB30}") - ) - : (ReferenceObject - :Name (CIFS) - :Table (services) - :Uid ("{2A469820-B502-434C-9340-A377677A6A60}") - ) - : (ReferenceObject - :Name (rdp) - :Table (services) - :Uid ("{5BA0C83F-8D91-465B-9CF6-7DC6AEB84689}") - ) - : (ReferenceObject - :Name (domain-udp) - :Table (services) - :Uid ("{97AEB3FA-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :src ( - :AdminInfo ( - :chkpf_uid ("{54B4C9AE-D0A0-44CC-9966-6D3430A02560}") - :ClassName (rule_source) - ) - :compound ( - : (Cactus-extern@vpn-sources-IsoAAAA - :AdminInfo ( - :chkpf_uid ("{06662A22-288E-4636-9C57-B2299E99F54C}") - :ClassName (rule_user_group) - ) - :at (ReferenceObject - :Name (vpn-sources-IsoAAAA) - :Table (network_objects) - :Uid ("{26405A41-425C-4053-8002-497BB82D76B1}") - ) - :color (black) - :type (usrgroup) - ) - ) - :op () - ) - ) - :rule ( - :AdminInfo ( - :chkpf_uid ("{9691C5DE-A661-40D5-9755-E268DDE0F823}") - :ClassName (security_rule) - ) - :action ( - : ("Client Encrypt" - :AdminInfo ( - :chkpf_uid ("{21A87FBC-F2C6-4847-8FC3-7ABC71306B80}") - :ClassName (client_encrypt) - :table (setup) - ) - :action (accept) - :dst_options ("Intersect with User Database") - :enforce_desktop_config (false) - :macro (USER_CLIENT_ENCRYPTION) - :src_options ("Intersect with User Database") - :type (userc) - ) - ) - :comments () - :disabled (false) - :global_location (middle) - :through ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :time ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :track ( - : (ReferenceObject - :Name (Log) - :Table (tracks) - :Uid ("{97AEB480-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :dst ( - :AdminInfo ( - :chkpf_uid ("{3109A085-1921-401A-BE72-8E7FE51BA775}") - :ClassName (rule_destination) - ) - :compound () - :op () - : (ReferenceObject - :Name (scratchy.local) - :Table (network_objects) - :Uid ("{CFABE50C-C1F6-4FF1-8AC3-3161A3779708}") - ) - ) - :install ( - :AdminInfo ( - :chkpf_uid ("{1D278C64-5680-473F-B522-7F856EF2C114}") - :ClassName (rule_install) - ) - :compound () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :services ( - :AdminInfo ( - :chkpf_uid ("{F7A6A2A3-6586-4954-9981-F5E206B1CC09}") - :ClassName (rule_services) - ) - :compound () - :op () - : (ReferenceObject - :Name (RAdmin-custom) - :Table (services) - :Uid ("{4FB59153-8212-4A12-BC08-0297AA5F0815}") - ) - ) - :src ( - :AdminInfo ( - :chkpf_uid ("{6BF46A79-3FF3-4F3B-BC85-9D71E0E932D6}") - :ClassName (rule_source) - ) - :compound ( - : (IsoAAAG-g@vpn-sources-IsoAAAA - :AdminInfo ( - :chkpf_uid ("{A304617F-CDA0-490D-A621-B62BB65F1C51}") - :ClassName (rule_user_group) - ) - :at (ReferenceObject - :Name (vpn-sources-IsoAAAA) - :Table (network_objects) - :Uid ("{26405A41-425C-4053-8002-497BB82D76B1}") - ) - :color (black) - :type (usrgroup) - ) - ) - :op () - ) - ) - :rule ( - :AdminInfo ( - :chkpf_uid ("{920B2304-B254-46E4-A051-F46580B0189A}") - :ClassName (security_rule) - ) - :action ( - : ("Client Encrypt" - :AdminInfo ( - :chkpf_uid ("{9CA5DD8C-0AD0-4505-8782-69FDE2254C70}") - :ClassName (client_encrypt) - :table (setup) - ) - :action (accept) - :dst_options ("Intersect with User Database") - :enforce_desktop_config (false) - :macro (USER_CLIENT_ENCRYPTION) - :src_options ("Intersect with User Database") - :type (userc) - ) - ) - :comments () - :disabled (false) - :global_location (middle) - :through ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :time ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :track ( - : (ReferenceObject - :Name (Log) - :Table (tracks) - :Uid ("{97AEB480-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :dst ( - :AdminInfo ( - :chkpf_uid ("{89FE302D-ED85-4024-892C-84457F49EF44}") - :ClassName (rule_destination) - ) - :compound () - :op () - : (ReferenceObject - :Name (spike.local) - :Table (network_objects) - :Uid ("{4ABDD8DE-0DA2-46E5-B129-85E3977CBD18}") - ) - ) - :install ( - :AdminInfo ( - :chkpf_uid ("{239E405F-12E7-4910-B44F-F3C59A3191B6}") - :ClassName (rule_install) - ) - :compound () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :services ( - :AdminInfo ( - :chkpf_uid ("{960A7691-DDC5-4F48-B5D0-7A7305561B32}") - :ClassName (rule_services) - ) - :compound () - :op () - : (ReferenceObject - :Name (squid) - :Table (services) - :Uid ("{91C0454D-F70C-44B3-8F2D-70C4A68E9594}") - ) - : (ReferenceObject - :Name (imap) - :Table (services) - :Uid ("{97AEB446-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :src ( - :AdminInfo ( - :chkpf_uid ("{1625B6AD-2434-4325-8BE6-AE20F7C2C3CB}") - :ClassName (rule_source) - ) - :compound ( - : (Cactus-extern@vpn-sources-IsoAAAA - :AdminInfo ( - :chkpf_uid ("{848CBF00-3FFF-47A2-8D54-5B7B8170EDAD}") - :ClassName (rule_user_group) - ) - :at (ReferenceObject - :Name (vpn-sources-IsoAAAA) - :Table (network_objects) - :Uid ("{26405A41-425C-4053-8002-497BB82D76B1}") - ) - :color (black) - :type (usrgroup) - ) - ) - :op () - ) - ) - :rule ( - :AdminInfo ( - :chkpf_uid ("{1BDEDFF9-7C57-4628-B09E-DAFFA27B0DAF}") - :ClassName (security_rule) - ) - :action ( - : ("Client Encrypt" - :AdminInfo ( - :chkpf_uid ("{01B16C58-99BF-4C2A-9AA0-BF151981D6A8}") - :ClassName (client_encrypt) - :table (setup) - ) - :action (accept) - :dst_options ("Intersect with User Database") - :enforce_desktop_config (false) - :macro (USER_CLIENT_ENCRYPTION) - :src_options ("Intersect with User Database") - :type (userc) - ) - ) - :comments () - :disabled (false) - :global_location (middle) - :through ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :time ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :track ( - : (ReferenceObject - :Name (Log) - :Table (tracks) - :Uid ("{97AEB480-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :dst ( - :AdminInfo ( - :chkpf_uid ("{55339727-6FEF-4B99-A17E-5890279876A6}") - :ClassName (rule_destination) - ) - :compound () - :op () - : (ReferenceObject - :Name (itchy) - :Table (network_objects) - :Uid ("{3B4DF852-5064-4957-B95F-D469C5656467}") - ) - ) - :install ( - :AdminInfo ( - :chkpf_uid ("{58C83086-B23C-494C-AFBD-FF71DDE6D90B}") - :ClassName (rule_install) - ) - :compound () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :services ( - :AdminInfo ( - :chkpf_uid ("{35745013-A0CF-4878-A5E5-60BFDD09DD4D}") - :ClassName (rule_services) - ) - :compound () - :op () - : (ReferenceObject - :Name (smtp) - :Table (services) - :Uid ("{97AEB3D9-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :src ( - :AdminInfo ( - :chkpf_uid ("{4A953FC6-7A97-4CF8-ADD2-8F557A1991E1}") - :ClassName (rule_source) - ) - :compound ( - : (Cactus-extern@vpn-sources-IsoAAAA - :AdminInfo ( - :chkpf_uid ("{95BDA256-F40B-4BF0-9A9A-9647C2D4E758}") - :ClassName (rule_user_group) - ) - :at (ReferenceObject - :Name (vpn-sources-IsoAAAA) - :Table (network_objects) - :Uid ("{26405A41-425C-4053-8002-497BB82D76B1}") - ) - :color (black) - :type (usrgroup) - ) - ) - :op () - ) - ) - :rule ( - :AdminInfo ( - :chkpf_uid ("{70B5DC4A-1616-4047-AC26-5ED448A2CF00}") - :ClassName (security_rule) - ) - :action ( - : ("Client Encrypt" - :AdminInfo ( - :chkpf_uid ("{F0786A55-1A99-404A-BDD6-9334E32B292C}") - :ClassName (client_encrypt) - :table (setup) - ) - :action (accept) - :dst_options ("Intersect with User Database") - :enforce_desktop_config (false) - :macro (USER_CLIENT_ENCRYPTION) - :src_options ("Intersect with User Database") - :type (userc) - ) - ) - :comments () - :disabled (false) - :global_location (middle) - :through ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :time ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :track ( - : (ReferenceObject - :Name (Log) - :Table (tracks) - :Uid ("{97AEB480-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :dst ( - :AdminInfo ( - :chkpf_uid ("{0FDC8337-7A9D-47B2-8754-378FEB66B2ED}") - :ClassName (rule_destination) - ) - :compound () - :op () - : (ReferenceObject - :Name (wasp) - :Table (network_objects) - :Uid ("{098B2A74-E220-4AE8-A164-340FED79C9D5}") - ) - ) - :install ( - :AdminInfo ( - :chkpf_uid ("{9D51C8CC-BC8E-441F-88E7-60CFB459EAE1}") - :ClassName (rule_install) - ) - :compound () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :services ( - :AdminInfo ( - :chkpf_uid ("{4D81B00D-E763-4153-9338-1BFB8A9453EA}") - :ClassName (rule_services) - ) - :compound () - :op () - : (ReferenceObject - :Name (ntp-udp) - :Table (services) - :Uid ("{97AEB404-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :src ( - :AdminInfo ( - :chkpf_uid ("{BFDF7F38-B703-4397-8CC9-1B544AEBA20D}") - :ClassName (rule_source) - ) - :compound ( - : (Cactus-extern@vpn-sources-IsoAAAA - :AdminInfo ( - :chkpf_uid ("{4F5A4882-D84F-4250-B3BF-B1A3C5B468E4}") - :ClassName (rule_user_group) - ) - :at (ReferenceObject - :Name (vpn-sources-IsoAAAA) - :Table (network_objects) - :Uid ("{26405A41-425C-4053-8002-497BB82D76B1}") - ) - :color (black) - :type (usrgroup) - ) - ) - :op () - ) - ) - :rule ( - :AdminInfo ( - :chkpf_uid ("{F5BDCBD0-AE0E-4DDD-BA77-488A126E9759}") - :ClassName (security_rule) - ) - :action ( - : ("Client Encrypt" - :AdminInfo ( - :chkpf_uid ("{4910EDC7-E295-4B62-A57B-119D75B36211}") - :ClassName (client_encrypt) - :table (setup) - ) - :action (accept) - :dst_options ("Intersect with User Database") - :enforce_desktop_config (false) - :macro (USER_CLIENT_ENCRYPTION) - :src_options ("Intersect with User Database") - :type (userc) - ) - ) - :comments () - :disabled (false) - :global_location (middle) - :through ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :time ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :track ( - : (ReferenceObject - :Name (Log) - :Table (tracks) - :Uid ("{97AEB480-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :dst ( - :AdminInfo ( - :chkpf_uid ("{F1BC9B8B-757D-41B5-B5F2-6CF53E313CE1}") - :ClassName (rule_destination) - ) - :compound () - :op () - : (ReferenceObject - :Name (IsoAAAA-100) - :Table (network_objects) - :Uid ("{BF1C6029-8D5D-4A05-A3AD-4B67E6E7A7AA}") - ) - ) - :install ( - :AdminInfo ( - :chkpf_uid ("{EFEA2745-10C4-435C-8F75-3B02CAD44A1E}") - :ClassName (rule_install) - ) - :compound () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :services ( - :AdminInfo ( - :chkpf_uid ("{B0A24846-9037-4DB4-8A0E-6D154A3C446C}") - :ClassName (rule_services) - ) - :compound () - :op () - : (ReferenceObject - :Name (icmp-requests) - :Table (services) - :Uid ("{97AEB413-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :src ( - :AdminInfo ( - :chkpf_uid ("{478016ED-E6A8-4C48-AAA0-0E48BB328C94}") - :ClassName (rule_source) - ) - :compound ( - : (Cactus-extern@vpn-sources-IsoAAAA - :AdminInfo ( - :chkpf_uid ("{22D34F4D-CE34-4570-82C3-8264E061361C}") - :ClassName (rule_user_group) - ) - :at (ReferenceObject - :Name (vpn-sources-IsoAAAA) - :Table (network_objects) - :Uid ("{26405A41-425C-4053-8002-497BB82D76B1}") - ) - :color (black) - :type (usrgroup) - ) - ) - :op () - ) - ) - :rule ( - :AdminInfo ( - :chkpf_uid ("{E50EEFDD-9C20-4905-AC8B-6DD27D72792C}") - :ClassName (security_header_rule) - ) - :action ( - : (drop - :AdminInfo ( - :chkpf_uid ("{6E8942C2-E8EF-4C95-BC20-0AAFF144F063}") - :ClassName (drop_action) - :table (setup) - ) - :action () - :macro () - :type (drop) - ) - ) - :comments () - :global_location (middle) - :through ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :time ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :track ( - : (ReferenceObject - :Name (None) - :Table (tracks) - :Uid ("{97AEB47D-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :disabled (true) - :dst ( - :AdminInfo ( - :chkpf_uid ("{80AD2FC1-9597-4DDB-89D1-EBB676C19FAB}") - :ClassName (rule_destination) - ) - :compound () - :op () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :header_text ("IsoAAAE VPN-GW2GW") - :install ( - :AdminInfo ( - :chkpf_uid ("{AA5B5D3B-09DC-4BF0-B844-2284691CE560}") - :ClassName (rule_install) - ) - :compound () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :services ( - :AdminInfo ( - :chkpf_uid ("{75EFCECD-5B98-4D68-90A8-993EBEB1D1AE}") - :ClassName (rule_services) - ) - :compound () - :op () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :src ( - :AdminInfo ( - :chkpf_uid ("{5DA88645-AB06-4001-8DDF-1D9F3C73AD4F}") - :ClassName (rule_source) - ) - :compound () - :op () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :state (expanded) - ) - :rule ( - :AdminInfo ( - :chkpf_uid ("{328999EC-FEB5-48C3-B967-95F52EFEC462}") - :ClassName (security_rule) - ) - :action ( - : (Encrypt - :AdminInfo ( - :chkpf_uid ("{033ED469-3968-422B-9F61-B859EAEF33A9}") - :ClassName (encrypt) - :table (setup) - ) - :action (accept) - :datam () - :diagnostics-track (CryptLog - :AdminInfo ( - :chkpf_uid ("{AA60725C-E01D-4383-9841-5DA71CD58498}") - :ClassName (account) - :table (tracks) - ) - :Name () - :color ("Navy Blue") - :format (crypt) - :icon-name () - :macro () - :type (account) - ) - :gateway (ReferenceObject - :Table (globals) - :Name (Any) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - :isakmp.compression (None) - :isakmp.crlreq (false) - :isakmp.data.integrity (MD5) - :isakmp.encryption (3DES) - :isakmp.gateway (ReferenceObject - :Table (globals) - :Name (Any) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - :isakmp.phase2_DH_group (ReferenceObject - :Table (encryption) - :Name ("Group 2 (1024 bit)") - :Uid ("{97AEB629-9AEA-11D5-BD16-0090272CCB30}") - ) - :isakmp.transform (ESP) - :isakmp.use_pfs (false) - :isakmp.useippools (false) - :keym () - :macro (ENCRYPTION) - :mdm (MD5) - :menu_inactive (false) - :scheme (ISAKMP) - :type (encrypt) - ) - ) - :comments () - :disabled (false) - :global_location (middle) - :through ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :time ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :track ( - : (ReferenceObject - :Name (Log) - :Table (tracks) - :Uid ("{97AEB480-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :dst ( - :AdminInfo ( - :chkpf_uid ("{75DEA9A3-F776-46C2-AE83-708A874972DA}") - :ClassName (rule_destination) - ) - :compound () - :op () - : (ReferenceObject - :Name (IsoAAAA-100) - :Table (network_objects) - :Uid ("{BF1C6029-8D5D-4A05-A3AD-4B67E6E7A7AA}") - ) - ) - :install ( - :AdminInfo ( - :chkpf_uid ("{49CA8DBE-E6C1-41FE-960B-CD80875BD987}") - :ClassName (rule_install) - ) - :compound () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :services ( - :AdminInfo ( - :chkpf_uid ("{70722DA2-F39D-4785-B360-AE025E55A90F}") - :ClassName (rule_services) - ) - :compound () - :op () - : (ReferenceObject - :Name (icmp-requests) - :Table (services) - :Uid ("{97AEB413-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :src ( - :AdminInfo ( - :chkpf_uid ("{AFFDB11C-0016-459C-B945-5B7C26F707A6}") - :ClassName (rule_source) - ) - :compound () - :op () - : (ReferenceObject - :Table (network_objects) - :Name (IsoAAAA_home_tim) - :Uid ("{BF8F69B9-87C2-464A-9404-239AE8DF66B3}") - ) - ) - ) - :rule ( - :AdminInfo ( - :chkpf_uid ("{4D25D596-31EB-463C-9AB3-D22A92AE4033}") - :ClassName (security_header_rule) - ) - :action ( - : (drop - :AdminInfo ( - :chkpf_uid ("{C80121D8-276E-46C7-912F-1ED756DD47A9}") - :ClassName (drop_action) - :table (setup) - ) - :action () - :macro () - :type (drop) - ) - ) - :comments () - :global_location (middle) - :through ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :time ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :track ( - : (ReferenceObject - :Name (None) - :Table (tracks) - :Uid ("{97AEB47D-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :disabled (true) - :dst ( - :AdminInfo ( - :chkpf_uid ("{6ADFAB36-2054-4BD4-9709-778A6D5CE14C}") - :ClassName (rule_destination) - ) - :compound () - :op () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :header_text (Paybox) - :install ( - :AdminInfo ( - :chkpf_uid ("{0D085BFB-9570-4635-ABC3-962C2E75BB5F}") - :ClassName (rule_install) - ) - :compound () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :services ( - :AdminInfo ( - :chkpf_uid ("{5A631F4C-07E4-4AC9-A8E8-95CDBB5301A8}") - :ClassName (rule_services) - ) - :compound () - :op () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :src ( - :AdminInfo ( - :chkpf_uid ("{E46AD7A5-D087-4086-925D-110926B6D8BE}") - :ClassName (rule_source) - ) - :compound () - :op () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :state (expanded) - ) - :rule ( - :AdminInfo ( - :chkpf_uid ("{C008C4CF-6F9D-42D6-A4AE-E187E2C52B9B}") - :ClassName (security_rule) - ) - :action ( - : (Encrypt - :AdminInfo ( - :chkpf_uid ("{32F49A92-BCEF-4C40-9C82-A8DECB8B205F}") - :ClassName (encrypt) - :table (setup) - ) - :action (accept) - :datam () - :diagnostics-track (CryptLog - :AdminInfo ( - :chkpf_uid ("{E6CE55C2-2363-40C3-8497-78C64EAC556E}") - :ClassName (account) - :table (tracks) - ) - :Name () - :color ("Navy Blue") - :format (crypt) - :icon-name () - :macro () - :type (account) - ) - :gateway (ReferenceObject - :Table (globals) - :Name (Any) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - :isakmp.compression (None) - :isakmp.crlreq (false) - :isakmp.data.integrity (MD5) - :isakmp.encryption (3DES) - :isakmp.gateway () - :isakmp.phase2_DH_group (ReferenceObject - :Name ("Group 1 (768 bit)") - :Table (encryption) - :Uid ("{97AEB624-9AEA-11D5-BD16-0090272CCB30}") - ) - :isakmp.transform (ESP) - :isakmp.use_pfs (true) - :isakmp.useippools (false) - :keym () - :macro (ENCRYPTION) - :mdm (MD5) - :menu_inactive (false) - :scheme (ISAKMP) - :type (encrypt) - ) - ) - :comments () - :disabled (false) - :global_location (middle) - :through ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :time ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :track ( - : (ReferenceObject - :Name (Log) - :Table (tracks) - :Uid ("{97AEB480-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :dst ( - :AdminInfo ( - :chkpf_uid ("{29ACE304-9241-458B-AAF2-FC1081354711}") - :ClassName (rule_destination) - ) - :compound () - :op () - : (ReferenceObject - :Name (paybox-raunheim) - :Table (network_objects) - :Uid ("{0A1725B4-534D-46F1-A8C0-02C3351C8312}") - ) - ) - :install ( - :AdminInfo ( - :chkpf_uid ("{AAC7238A-9B77-463C-93BB-F09881B9D900}") - :ClassName (rule_install) - ) - :compound () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :services ( - :AdminInfo ( - :chkpf_uid ("{43D4BFFE-96B2-4921-8DE3-8B0B9C3ACC3D}") - :ClassName (rule_services) - ) - :compound () - :op () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :src ( - :AdminInfo ( - :chkpf_uid ("{1763B2EE-C7D8-44ED-A686-583DDB672508}") - :ClassName (rule_source) - ) - :compound () - :op () - : (ReferenceObject - :Name (IsoAAAA-100) - :Table (network_objects) - :Uid ("{BF1C6029-8D5D-4A05-A3AD-4B67E6E7A7AA}") - ) - ) - ) - :rule ( - :AdminInfo ( - :chkpf_uid ("{C64B3DE1-B85C-4902-B966-2BEA60840772}") - :ClassName (security_rule) - ) - :action ( - : (Encrypt - :AdminInfo ( - :chkpf_uid ("{7F5A6984-04DC-43A4-AC1F-A6C3BD195426}") - :ClassName (encrypt) - :table (setup) - ) - :action (accept) - :datam () - :diagnostics-track (CryptLog - :AdminInfo ( - :chkpf_uid ("{F52E7C26-DF59-4818-B00C-B32AD2ABE2B3}") - :ClassName (account) - :table (tracks) - ) - :Name () - :color ("Navy Blue") - :format (crypt) - :icon-name () - :macro () - :type (account) - ) - :gateway (ReferenceObject - :Table (globals) - :Name (Any) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - :isakmp.compression (None) - :isakmp.crlreq (false) - :isakmp.data.integrity (MD5) - :isakmp.encryption (3DES) - :isakmp.gateway () - :isakmp.phase2_DH_group (ReferenceObject - :Name ("Group 1 (768 bit)") - :Table (encryption) - :Uid ("{97AEB624-9AEA-11D5-BD16-0090272CCB30}") - ) - :isakmp.transform (ESP) - :isakmp.use_pfs (true) - :isakmp.useippools (false) - :keym () - :macro (ENCRYPTION) - :mdm (MD5) - :menu_inactive (false) - :scheme (ISAKMP) - :type (encrypt) - ) - ) - :comments () - :global_location (middle) - :through ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :time ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :track ( - : (ReferenceObject - :Name (Log) - :Table (tracks) - :Uid ("{97AEB480-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :disabled (true) - :dst ( - :AdminInfo ( - :chkpf_uid ("{313A1B80-4748-40BC-A463-FA115C9A6410}") - :ClassName (rule_destination) - ) - :compound () - :op () - : (ReferenceObject - :Name (paybox-frankfurt) - :Table (network_objects) - :Uid ("{463C45CA-0C86-42DC-9B02-E83E28764370}") - ) - ) - :install ( - :AdminInfo ( - :chkpf_uid ("{C70D24DD-D5D5-4D6F-85C2-0A69F0EE5F48}") - :ClassName (rule_install) - ) - :compound () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :services ( - :AdminInfo ( - :chkpf_uid ("{8AB172A4-28B0-4DA2-8028-6AD4F7DAE979}") - :ClassName (rule_services) - ) - :compound () - :op () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :src ( - :AdminInfo ( - :chkpf_uid ("{8119E980-7EFF-414E-810A-1368B4059E52}") - :ClassName (rule_source) - ) - :compound () - :op () - : (ReferenceObject - :Name (IsoAAAA-100) - :Table (network_objects) - :Uid ("{BF1C6029-8D5D-4A05-A3AD-4B67E6E7A7AA}") - ) - ) - ) - :rule ( - :AdminInfo ( - :chkpf_uid ("{85A07116-6165-46A2-B646-BC65159C8498}") - :ClassName (security_header_rule) - ) - :action ( - : (drop - :AdminInfo ( - :chkpf_uid ("{0974D2A7-69A9-40E1-9150-87FF94433363}") - :ClassName (drop_action) - :table (setup) - ) - :action () - :macro () - :type (drop) - ) - ) - :comments () - :global_location (middle) - :through ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :time ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :track ( - : (ReferenceObject - :Name (None) - :Table (tracks) - :Uid ("{97AEB47D-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :disabled (true) - :dst ( - :AdminInfo ( - :chkpf_uid ("{80880ABC-AA36-4ABB-8E93-72459383731B}") - :ClassName (rule_destination) - ) - :compound () - :op () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :header_text ("Sting Internal-Connections") - :install ( - :AdminInfo ( - :chkpf_uid ("{D236CF92-C3A6-4139-9D74-836408A0AC42}") - :ClassName (rule_install) - ) - :compound () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :services ( - :AdminInfo ( - :chkpf_uid ("{8213C158-8D6A-4146-8383-6B1BA2CDFFF7}") - :ClassName (rule_services) - ) - :compound () - :op () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :src ( - :AdminInfo ( - :chkpf_uid ("{6AED35BE-4E23-415A-BA81-8969B9E1DDEC}") - :ClassName (rule_source) - ) - :compound () - :op () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :state (collapsed) - ) - :rule ( - :AdminInfo ( - :chkpf_uid ("{CF0994CE-EC9F-4A3A-90E0-42655C2D25A1}") - :ClassName (security_rule) - ) - :action ( - : (accept - :AdminInfo ( - :chkpf_uid ("{292BDC57-FA47-4464-B83C-7636555FB0E1}") - :ClassName (accept_action) - :table (setup) - ) - :action () - :macro (RECORD_CONN) - :type (accept) - ) - ) - :comments () - :disabled (false) - :global_location (middle) - :through ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :time ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :track ( - : (ReferenceObject - :Name (Log) - :Table (tracks) - :Uid ("{97AEB480-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :dst ( - :AdminInfo ( - :chkpf_uid ("{A71F1087-BFC1-414B-BAC9-5097E8FAA94F}") - :ClassName (rule_destination) - ) - :compound () - :op () - : (ReferenceObject - :Name (IsoAAAD) - :Table (network_objects) - :Uid ("{29C40B0A-414C-11D7-AEB8-7F0000013C3C}") - ) - ) - :install ( - :AdminInfo ( - :chkpf_uid ("{9698EE11-9DFF-4C54-9166-7B6E9A35BF4B}") - :ClassName (rule_install) - ) - :compound () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :services ( - :AdminInfo ( - :chkpf_uid ("{F41085C4-3418-4B30-AB6E-5804AA7F8B4D}") - :ClassName (rule_services) - ) - :compound () - :op () - : (ReferenceObject - :Name (ssh) - :Table (services) - :Uid ("{18EC9EAA-1657-4240-AB97-5F234623336B}") - ) - : (ReferenceObject - :Name (https) - :Table (services) - :Uid ("{97AEB443-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :src ( - :AdminInfo ( - :chkpf_uid ("{2D0924EE-FE00-4354-ADC1-033783E6AEBC}") - :ClassName (rule_source) - ) - :compound () - :op () - : (ReferenceObject - :Name (IsoAAAA-100) - :Table (network_objects) - :Uid ("{BF1C6029-8D5D-4A05-A3AD-4B67E6E7A7AA}") - ) - : (ReferenceObject - :Table (network_objects) - :Name (IsoAAAA_home_tim) - :Uid ("{BF8F69B9-87C2-464A-9404-239AE8DF66B3}") - ) - ) - ) - :rule ( - :AdminInfo ( - :chkpf_uid ("{113537AD-71C4-4CE4-BA28-679030EEA145}") - :ClassName (security_rule) - ) - :action ( - : (accept - :AdminInfo ( - :chkpf_uid ("{B772878E-BC0F-4DA3-8BEA-29B7E1F78BD0}") - :ClassName (accept_action) - :table (setup) - ) - :action () - :macro (RECORD_CONN) - :type (accept) - ) - ) - :comments () - :disabled (false) - :global_location (middle) - :through ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :time ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :track ( - : (ReferenceObject - :Name (Log) - :Table (tracks) - :Uid ("{97AEB480-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :dst ( - :AdminInfo ( - :chkpf_uid ("{17D6C85E-1919-4FDD-9AB6-17A7F06D6559}") - :ClassName (rule_destination) - ) - :compound () - :op () - : (ReferenceObject - :Name (IsoAAAD) - :Table (network_objects) - :Uid ("{29C40B0A-414C-11D7-AEB8-7F0000013C3C}") - ) - ) - :install ( - :AdminInfo ( - :chkpf_uid ("{59E0D2EA-BD99-48FC-BA29-34C757D6C14C}") - :ClassName (rule_install) - ) - :compound () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :services ( - :AdminInfo ( - :chkpf_uid ("{A9833372-0864-427C-B2CB-6A0F59DAF2F0}") - :ClassName (rule_services) - ) - :compound () - :op () - : (ReferenceObject - :Name (apcupsd) - :Table (services) - :Uid ("{A1044CB4-439C-40C9-8489-FA5086134886}") - ) - ) - :src ( - :AdminInfo ( - :chkpf_uid ("{20AB74D2-BC69-440B-8B69-77C6F598D603}") - :ClassName (rule_source) - ) - :compound () - :op () - : (ReferenceObject - :Name (IsoAAADray.local) - :Table (network_objects) - :Uid ("{75EDBC62-7EB1-4D37-8295-684903FDA75A}") - ) - ) - ) - :rule ( - :AdminInfo ( - :chkpf_uid ("{8D008C53-8D55-4C95-93FB-26FB028D1914}") - :ClassName (security_rule) - ) - :action ( - : (accept - :AdminInfo ( - :chkpf_uid ("{55DB4364-CA94-47E2-9C78-5874293C28DE}") - :ClassName (accept_action) - :table (setup) - ) - :action () - :macro (RECORD_CONN) - :type (accept) - ) - ) - :comments () - :disabled (false) - :global_location (middle) - :through ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :time ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :track ( - : (ReferenceObject - :Name (Log) - :Table (tracks) - :Uid ("{97AEB480-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :dst ( - :AdminInfo ( - :chkpf_uid ("{6EC07E89-6359-4D43-959E-8834F1E1DC59}") - :ClassName (rule_destination) - ) - :compound () - :op () - : (ReferenceObject - :Name (wasp) - :Table (network_objects) - :Uid ("{098B2A74-E220-4AE8-A164-340FED79C9D5}") - ) - ) - :install ( - :AdminInfo ( - :chkpf_uid ("{135B3221-B41A-49BA-A6A3-BF4A7662A2B4}") - :ClassName (rule_install) - ) - :compound () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :services ( - :AdminInfo ( - :chkpf_uid ("{11F787A5-B7C9-435C-AB4F-0851D2695778}") - :ClassName (rule_services) - ) - :compound () - :op () - : (ReferenceObject - :Name (ntp-udp) - :Table (services) - :Uid ("{97AEB404-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :src ( - :AdminInfo ( - :chkpf_uid ("{1431CA26-6106-4592-B29A-5DB903350FBF}") - :ClassName (rule_source) - ) - :compound () - :op () - : (ReferenceObject - :Name (IsoAAAD) - :Table (network_objects) - :Uid ("{29C40B0A-414C-11D7-AEB8-7F0000013C3C}") - ) - ) - ) - :rule ( - :AdminInfo ( - :chkpf_uid ("{D81E3077-3930-4FF3-A15B-21B8B5398143}") - :ClassName (security_rule) - ) - :action ( - : (accept - :AdminInfo ( - :chkpf_uid ("{5BEBEB39-FED4-40D5-93A4-926D136985DF}") - :ClassName (accept_action) - :table (setup) - ) - :action () - :macro (RECORD_CONN) - :type (accept) - ) - ) - :comments () - :disabled (false) - :global_location (middle) - :through ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :time ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :track ( - : (ReferenceObject - :Name (Log) - :Table (tracks) - :Uid ("{97AEB480-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :dst ( - :AdminInfo ( - :chkpf_uid ("{AF0A8FB4-C470-4CF9-80A4-A02D65F17CB4}") - :ClassName (rule_destination) - ) - :compound () - :op () - : (ReferenceObject - :Name (itchy) - :Table (network_objects) - :Uid ("{3B4DF852-5064-4957-B95F-D469C5656467}") - ) - ) - :install ( - :AdminInfo ( - :chkpf_uid ("{47FD7FA4-3EF7-494A-AFCC-A1175C1B7CB3}") - :ClassName (rule_install) - ) - :compound () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :services ( - :AdminInfo ( - :chkpf_uid ("{D6303579-2AD2-4EBA-BA32-3ED6EF192609}") - :ClassName (rule_services) - ) - :compound () - :op () - : (ReferenceObject - :Name (domain-udp) - :Table (services) - :Uid ("{97AEB3FA-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :src ( - :AdminInfo ( - :chkpf_uid ("{2AB872E9-0292-4B06-8D86-6960AA66787F}") - :ClassName (rule_source) - ) - :compound () - :op () - : (ReferenceObject - :Name (IsoAAAD) - :Table (network_objects) - :Uid ("{29C40B0A-414C-11D7-AEB8-7F0000013C3C}") - ) - ) - ) - :rule ( - :AdminInfo ( - :chkpf_uid ("{30829944-2BE4-46F0-A0A9-30E2DB0D85CF}") - :ClassName (security_rule) - ) - :action ( - : (accept - :AdminInfo ( - :chkpf_uid ("{BEB334AD-F3D7-44EB-95DB-360CBA080106}") - :ClassName (accept_action) - :table (setup) - ) - :action () - :macro (RECORD_CONN) - :type (accept) - ) - ) - :comments () - :disabled (false) - :global_location (middle) - :through ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :time ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :track ( - : (ReferenceObject - :Name (Log) - :Table (tracks) - :Uid ("{97AEB480-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :dst ( - :AdminInfo ( - :chkpf_uid ("{DDF30249-4842-4453-9FF3-AA14C76B632C}") - :ClassName (rule_destination) - ) - :compound () - :op () - : (ReferenceObject - :Name (spike.local) - :Table (network_objects) - :Uid ("{4ABDD8DE-0DA2-46E5-B129-85E3977CBD18}") - ) - ) - :install ( - :AdminInfo ( - :chkpf_uid ("{53000D56-F73A-45A8-8EA4-43F7DB7A16BB}") - :ClassName (rule_install) - ) - :compound () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :services ( - :AdminInfo ( - :chkpf_uid ("{5587D19B-EB61-42ED-9531-F1F13E89FF99}") - :ClassName (rule_services) - ) - :compound () - :op () - : (ReferenceObject - :Name (syslog) - :Table (services) - :Uid ("{97AEB3E0-9AEA-11D5-BD16-0090272CCB30}") - ) - : (ReferenceObject - :Name (ssh_version_2) - :Table (services) - :Uid ("{CD082D9A-44A6-4CEF-A17D-5541029ADFB3}") - ) - ) - :src ( - :AdminInfo ( - :chkpf_uid ("{CDBA6A5A-086E-4591-9FF0-87515BF4BD2E}") - :ClassName (rule_source) - ) - :compound () - :op () - : (ReferenceObject - :Name (IsoAAAD) - :Table (network_objects) - :Uid ("{29C40B0A-414C-11D7-AEB8-7F0000013C3C}") - ) - ) - ) - :rule ( - :AdminInfo ( - :chkpf_uid ("{77835D71-6333-4D9A-8DF4-CB427F59026F}") - :ClassName (security_header_rule) - ) - :action ( - : (drop - :AdminInfo ( - :chkpf_uid ("{FB12625B-C5FD-4D0C-9286-ABBD3F5D67D5}") - :ClassName (drop_action) - :table (setup) - ) - :action () - :macro () - :type (drop) - ) - ) - :comments () - :global_location (middle) - :through ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :time ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :track ( - : (ReferenceObject - :Name (None) - :Table (tracks) - :Uid ("{97AEB47D-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :disabled (true) - :dst ( - :AdminInfo ( - :chkpf_uid ("{C6EED839-1703-48FC-BAB5-CD26627C4E33}") - :ClassName (rule_destination) - ) - :compound () - :op () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :header_text (Final-rules) - :install ( - :AdminInfo ( - :chkpf_uid ("{6A78BE94-D68A-4E5D-9D5C-7794E65BDA91}") - :ClassName (rule_install) - ) - :compound () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :services ( - :AdminInfo ( - :chkpf_uid ("{9B9BDA74-31AB-443E-B101-37DAB5C8363A}") - :ClassName (rule_services) - ) - :compound () - :op () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :src ( - :AdminInfo ( - :chkpf_uid ("{FC4224DC-3D3E-4EFE-BD48-403FFD7EDEEF}") - :ClassName (rule_source) - ) - :compound () - :op () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :state (collapsed) - ) - :rule ( - :AdminInfo ( - :chkpf_uid ("{7D32EB1D-9DA2-479C-8E05-80A48B4D49B8}") - :ClassName (security_rule) - ) - :action ( - : (accept - :AdminInfo ( - :chkpf_uid ("{2664067C-FBB5-436C-9569-87F241215125}") - :ClassName (accept_action) - :table (setup) - ) - :action () - :macro (RECORD_CONN) - :type (accept) - ) - ) - :comments () - :disabled (false) - :global_location (middle) - :through ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :time ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :track ( - : (ReferenceObject - :Name (Log) - :Table (tracks) - :Uid ("{97AEB480-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :dst ( - :AdminInfo ( - :chkpf_uid ("{5AC35870-BE14-4BA8-B152-AAAD919EB93A}") - :ClassName (rule_destination) - ) - :compound () - :op () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :install ( - :AdminInfo ( - :chkpf_uid ("{EE6F2F3F-B123-4BB0-9AA6-EA670224A920}") - :ClassName (rule_install) - ) - :compound () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :services ( - :AdminInfo ( - :chkpf_uid ("{711FD2F4-7BDC-4667-8F9B-37EA46D21468}") - :ClassName (rule_services) - ) - :compound () - :op () - : (ReferenceObject - :Name (ICMPgute) - :Table (services) - :Uid ("{418C7C0A-956A-41FF-9BC1-5867B2265090}") - ) - ) - :src ( - :AdminInfo ( - :chkpf_uid ("{02294F3B-AF87-4FBE-9CE1-A3BB3434F19C}") - :ClassName (rule_source) - ) - :compound () - :op () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - ) - :rule ( - :AdminInfo ( - :chkpf_uid ("{9676DC19-81AB-4901-B03B-2B86DC876712}") - :ClassName (security_rule) - ) - :action ( - : (reject - :AdminInfo ( - :chkpf_uid ("{DFE03595-95BA-483C-B76C-14F842885448}") - :ClassName (reject_action) - :table (setup) - ) - :action () - :macro () - :type (reject) - ) - ) - :comments () - :disabled (false) - :global_location (middle) - :through ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :time ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :track ( - : (ReferenceObject - :Name (None) - :Table (tracks) - :Uid ("{97AEB47D-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :dst ( - :AdminInfo ( - :chkpf_uid ("{3EFDE682-11BD-4F54-B2CB-1E191C71351E}") - :ClassName (rule_destination) - ) - :compound () - :op () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :install ( - :AdminInfo ( - :chkpf_uid ("{A5CD71BD-98D8-43C7-8FB0-1C43B1D63F18}") - :ClassName (rule_install) - ) - :compound () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :services ( - :AdminInfo ( - :chkpf_uid ("{679E7E39-AAC3-484E-977F-403FBC9A3701}") - :ClassName (rule_services) - ) - :compound () - :op () - : (ReferenceObject - :Table (services) - :Name (Drop_nologServices) - :Uid ("{495E1A16-2612-49D9-8F69-B00EB33699E8}") - ) - ) - :src ( - :AdminInfo ( - :chkpf_uid ("{9E442067-FFAB-4B9B-8CA4-FD5FF240416A}") - :ClassName (rule_source) - ) - :compound () - :op () - : (ReferenceObject - :Name (IsoAAAA-100) - :Table (network_objects) - :Uid ("{BF1C6029-8D5D-4A05-A3AD-4B67E6E7A7AA}") - ) - ) - ) - :rule ( - :AdminInfo ( - :chkpf_uid ("{650D3396-E5C8-4FCD-AB0E-B2D867C631EC}") - :ClassName (security_rule) - ) - :action ( - : (drop - :AdminInfo ( - :chkpf_uid ("{5A63985D-9381-4F03-8F35-5A6FA61836CD}") - :ClassName (drop_action) - :table (setup) - ) - :action () - :macro () - :type (drop) - ) - ) - :comments () - :disabled (false) - :global_location (middle) - :through ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :time ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :track ( - : (ReferenceObject - :Name (Log) - :Table (tracks) - :Uid ("{97AEB480-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :dst ( - :AdminInfo ( - :chkpf_uid ("{F0A383D4-E033-445F-87F7-679987F289F8}") - :ClassName (rule_destination) - ) - :compound () - :op () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :install ( - :AdminInfo ( - :chkpf_uid ("{CBAF3D5E-4D05-4D90-9278-B74D854765E4}") - :ClassName (rule_install) - ) - :compound () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :services ( - :AdminInfo ( - :chkpf_uid ("{55A4F666-58D1-4D21-97F0-6A66BE8A9A4E}") - :ClassName (rule_services) - ) - :compound () - :op () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :src ( - :AdminInfo ( - :chkpf_uid ("{D38D5022-5541-47F6-BEC1-D34D577D5B31}") - :ClassName (rule_source) - ) - :compound () - :op () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - ) - :rule_adtr ( - :AdminInfo ( - :chkpf_uid ("{AEB9F3D3-F756-4622-8279-546EB4AEDA6D}") - :ClassName (address_translation_rule) - ) - :comments () - :disabled (false) - :dst_adtr ( - : (ReferenceObject - :Name (IsoAAAA-100) - :Table (network_objects) - :Uid ("{BF1C6029-8D5D-4A05-A3AD-4B67E6E7A7AA}") - ) - ) - :global_location (middle) - :install ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :rule_block_number (1) - :services_adtr ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :src_adtr ( - : (ReferenceObject - :Name (vpn-sources-IsoAAAA) - :Table (network_objects) - :Uid ("{26405A41-425C-4053-8002-497BB82D76B1}") - ) - ) - :dst_adtr_translated ( - :AdminInfo ( - :chkpf_uid ("{27CFFB17-E049-4E32-BCCD-D8140703E33E}") - :ClassName (translate_static) - ) - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - :adtr_method (adtr_method_static) - ) - :services_adtr_translated ( - :AdminInfo ( - :chkpf_uid ("{7236D86D-A66E-4FFA-8C32-BF31AA649665}") - :ClassName (service_translate) - ) - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - :adtr_method (adtr_method_static) - ) - :src_adtr_translated ( - :AdminInfo ( - :chkpf_uid ("{D12593A4-D593-4DC7-A241-19915862D874}") - :ClassName (translate_hide) - ) - : (ReferenceObject - :Name (IsoAAAD_intern) - :Table (network_objects) - :Uid ("{40831AE2-CB84-46D2-9522-F987BC10BDB9}") - ) - :adtr_method (adtr_method_hide) - ) - ) - :rule_adtr ( - :AdminInfo ( - :chkpf_uid ("{CE9E192B-7125-4C9B-9923-3CC0851ECF86}") - :ClassName (address_translation_rule) - ) - :comments () - :disabled (false) - :dst_adtr ( - : (ReferenceObject - :Name (IsoAAAA-100) - :Table (network_objects) - :Uid ("{BF1C6029-8D5D-4A05-A3AD-4B67E6E7A7AA}") - ) - ) - :global_location (middle) - :install ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :rule_block_number (1) - :services_adtr ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :src_adtr ( - : (ReferenceObject - :Name (Cactus-InternetTransfer) - :Table (network_objects) - :Uid ("{408C820D-33A1-4E25-B576-EC826F525DCD}") - ) - ) - :dst_adtr_translated ( - :AdminInfo ( - :chkpf_uid ("{5B4D59AD-51B2-4FF4-BBE4-6004FDC2B0EB}") - :ClassName (translate_static) - ) - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - :adtr_method (adtr_method_static) - ) - :services_adtr_translated ( - :AdminInfo ( - :chkpf_uid ("{5AC7492C-C631-4E37-BCD5-AA50435F5477}") - :ClassName (service_translate) - ) - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - :adtr_method (adtr_method_static) - ) - :src_adtr_translated ( - :AdminInfo ( - :chkpf_uid ("{0671F784-E9CC-423F-82E0-AC645A80560B}") - :ClassName (translate_hide) - ) - : (ReferenceObject - :Name (IsoAAAD_intern) - :Table (network_objects) - :Uid ("{40831AE2-CB84-46D2-9522-F987BC10BDB9}") - ) - :adtr_method (adtr_method_hide) - ) - ) - :rule_adtr ( - :AdminInfo ( - :chkpf_uid ("{BC27101C-9BC5-4E5A-96FB-9C745A716EC6}") - :ClassName (address_translation_rule) - ) - :comments () - :disabled (false) - :dst_adtr ( - : (ReferenceObject - :Name (IsoAAADray.local) - :Table (network_objects) - :Uid ("{75EDBC62-7EB1-4D37-8295-684903FDA75A}") - ) - ) - :global_location (middle) - :install ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :rule_block_number (1) - :services_adtr ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :src_adtr ( - : (ReferenceObject - :Name (heag_off_upper) - :Table (network_objects) - :Uid ("{A58E3E67-0517-485F-AA04-97A12BC119C3}") - ) - ) - :dst_adtr_translated ( - :AdminInfo ( - :chkpf_uid ("{FCA2AE6C-5BD9-43B0-BC7D-E0CA44B623D1}") - :ClassName (translate_static) - ) - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - :adtr_method (adtr_method_static) - ) - :services_adtr_translated ( - :AdminInfo ( - :chkpf_uid ("{CC48C8B8-7D7A-4958-964F-3CF28847B3B3}") - :ClassName (service_translate) - ) - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - :adtr_method (adtr_method_static) - ) - :src_adtr_translated ( - :AdminInfo ( - :chkpf_uid ("{B11BD765-AEC0-4BF9-A63E-E8D829A3BC8C}") - :ClassName (translate_hide) - ) - : (ReferenceObject - :Name (IsoAAAD_intern) - :Table (network_objects) - :Uid ("{40831AE2-CB84-46D2-9522-F987BC10BDB9}") - ) - :adtr_method (adtr_method_hide) - ) - ) - :use_VPN_communities (false) - ) - :rule-base ("##IsoAAAA" - :AdminInfo ( - :chkpf_uid ("{4DFA246F-BCB1-4283-B3D6-685FBF8DB89B}") - :ClassName (firewall_policy) - :table (fw_policies) - :LastModified ( - :Time ("Wed Jul 27 15:32:20 2005") - :By (IsoAAAF) - :From (IsoAAADray) - ) - ) - :default (0) - :queries () - :queries_adtr () - :collection (ReferenceObject - :Name (IsoAAAA) - :Table (policies_collections) - :Uid ("{462FD47E-BB4B-4DC4-95D6-E25D7E6C1E41}") - ) - :rule ( - :AdminInfo ( - :chkpf_uid ("{A4029F61-9672-4AA3-B1D9-0FF4E8979971}") - :ClassName (security_header_rule) - ) - :action ( - : (drop - :AdminInfo ( - :chkpf_uid ("{5EE13032-A1E1-4538-90BC-6295FD3DFE04}") - :ClassName (drop_action) - :table (setup) - ) - :action () - :macro () - :type (drop) - ) - ) - :comments () - :global_location (middle) - :through ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :time ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :track ( - : (ReferenceObject - :Name (None) - :Table (tracks) - :Uid ("{97AEB47D-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :disabled (true) - :dst ( - :AdminInfo ( - :chkpf_uid ("{5560B804-6408-442F-903B-2B279AE6D9C2}") - :ClassName (rule_destination) - ) - :compound () - :op () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :header_text (test-rules) - :install ( - :AdminInfo ( - :chkpf_uid ("{0B1EB683-1A59-44FF-901C-5FDB9EA65A5E}") - :ClassName (rule_install) - ) - :compound () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :services ( - :AdminInfo ( - :chkpf_uid ("{F8D6F7F5-4582-4256-A0A5-EBFDDB2EF590}") - :ClassName (rule_services) - ) - :compound () - :op () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :src ( - :AdminInfo ( - :chkpf_uid ("{AF27380F-6548-4B83-81FD-1B5EAECAA8F6}") - :ClassName (rule_source) - ) - :compound () - :op () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :state (expanded) - ) - :rule ( - :AdminInfo ( - :chkpf_uid ("{ABC6E209-A440-42E2-A896-CF27A1CA2744}") - :ClassName (security_rule) - ) - :action ( - : ("Client Encrypt" - :AdminInfo ( - :chkpf_uid ("{E9CD394B-3A31-4AA4-A8F5-D2120F53E780}") - :ClassName (client_encrypt) - :table (setup) - ) - :action (accept) - :dst_options ("intersect with user database") - :enforce_desktop_config (false) - :macro (USER_CLIENT_ENCRYPTION) - :src_options ("intersect with user database") - :type (userc) - ) - ) - :global_location (middle) - :through ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :time ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :track ( - : (ReferenceObject - :Name (Log) - :Table (tracks) - :Uid ("{97AEB480-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :comments (vpn_test) - :disabled (true) - :dst ( - :AdminInfo ( - :chkpf_uid ("{65F39402-76F2-45CC-A99C-0903FE70DF4C}") - :ClassName (rule_destination) - ) - :compound () - :op () - : (ReferenceObject - :Name (IsoAAADray.local) - :Table (network_objects) - :Uid ("{75EDBC62-7EB1-4D37-8295-684903FDA75A}") - ) - ) - :install ( - :AdminInfo ( - :chkpf_uid ("{C6DE2209-1A7B-4FCC-B7A7-A1D4EDD793D7}") - :ClassName (rule_install) - ) - :compound () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :services ( - :AdminInfo ( - :chkpf_uid ("{91BC0FDA-33F0-49D8-BC63-FFA85CBAFD40}") - :ClassName (rule_services) - ) - :compound () - :op () - : (ReferenceObject - :Name (NBT) - :Table (services) - :Uid ("{97AEB471-9AEA-11D5-BD16-0090272CCB30}") - ) - : (ReferenceObject - :Name (icmp-requests) - :Table (services) - :Uid ("{97AEB413-9AEA-11D5-BD16-0090272CCB30}") - ) - : (ReferenceObject - :Name (CIFS) - :Table (services) - :Uid ("{2A469820-B502-434C-9340-A377677A6A60}") - ) - : (ReferenceObject - :Name (rdp) - :Table (services) - :Uid ("{5BA0C83F-8D91-465B-9CF6-7DC6AEB84689}") - ) - ) - :src ( - :AdminInfo ( - :chkpf_uid ("{28C21DCF-D0A0-4F40-8017-BCD946EFF41D}") - :ClassName (rule_source) - ) - :compound ( - : (vpn_user@heag_off_upper - :AdminInfo ( - :chkpf_uid ("{ABBA5C5D-AE07-4CF6-A00E-3649064D0BDB}") - :ClassName (rule_user_group) - ) - :at (ReferenceObject - :Name (heag_off_upper) - :Table (network_objects) - :Uid ("{A58E3E67-0517-485F-AA04-97A12BC119C3}") - ) - :color (black) - :type (usrgroup) - ) - ) - :op () - ) - ) - :rule ( - :AdminInfo ( - :chkpf_uid ("{5AFB86A5-E247-411F-AAD7-A8EFDE97A0F5}") - :ClassName (security_rule) - ) - :action ( - : (accept - :AdminInfo ( - :chkpf_uid ("{150ABA94-098B-4CC3-AF8A-BDFED81FC20E}") - :ClassName (accept_action) - :table (setup) - ) - :action () - :macro (RECORD_CONN) - :type (accept) - ) - ) - :comments () - :global_location (middle) - :through ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :time ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :track ( - : (ReferenceObject - :Name (Log) - :Table (tracks) - :Uid ("{97AEB480-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :disabled (true) - :dst ( - :AdminInfo ( - :chkpf_uid ("{5526AF1C-6E4F-4F71-A58E-A1E5F88B62DB}") - :ClassName (rule_destination) - ) - :compound () - :op () - : (ReferenceObject - :Name (Premier_Access) - :Table (network_objects) - :Uid ("{B2BB20AA-B685-426B-96B6-1FB4D8D05135}") - ) - : (ReferenceObject - :Name (IsoAAAD) - :Table (network_objects) - :Uid ("{29C40B0A-414C-11D7-AEB8-7F0000013C3C}") - ) - ) - :install ( - :AdminInfo ( - :chkpf_uid ("{7F41F235-2373-4F38-9141-29AB9CEAD2D8}") - :ClassName (rule_install) - ) - :compound () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :services ( - :AdminInfo ( - :chkpf_uid ("{C2DE3BB7-C1B7-49C9-BC21-97AB3CE81521}") - :ClassName (rule_services) - ) - :compound () - :op () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :src ( - :AdminInfo ( - :chkpf_uid ("{F8ECC436-D19B-4124-9BC3-31C1E3945A36}") - :ClassName (rule_source) - ) - :compound () - :op () - : (ReferenceObject - :Name (IsoAAAD) - :Table (network_objects) - :Uid ("{29C40B0A-414C-11D7-AEB8-7F0000013C3C}") - ) - : (ReferenceObject - :Name (Premier_Access) - :Table (network_objects) - :Uid ("{B2BB20AA-B685-426B-96B6-1FB4D8D05135}") - ) - ) - ) - :rule ( - :AdminInfo ( - :chkpf_uid ("{38429C3B-05FE-49C8-9D8C-83F0AC9661CD}") - :ClassName (security_rule) - ) - :action ( - : ("Client Encrypt" - :AdminInfo ( - :chkpf_uid ("{5F145F42-1609-4937-A766-0D8B67710BCC}") - :ClassName (client_encrypt) - :table (setup) - ) - :action (accept) - :dst_options ("intersect with user database") - :enforce_desktop_config (false) - :macro (USER_CLIENT_ENCRYPTION) - :src_options ("intersect with user database") - :type (userc) - ) - ) - :global_location (middle) - :through ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :time ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :track ( - : (ReferenceObject - :Name (Log) - :Table (tracks) - :Uid ("{97AEB480-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :comments ("RAS - Test mit Premier-Access - Tokens") - :disabled (true) - :dst ( - :AdminInfo ( - :chkpf_uid ("{FEABA989-54EB-4D53-96C9-6841B9BBEB4B}") - :ClassName (rule_destination) - ) - :compound () - :op () - : (ReferenceObject - :Name (IsoAAAA-100) - :Table (network_objects) - :Uid ("{BF1C6029-8D5D-4A05-A3AD-4B67E6E7A7AA}") - ) - : (ReferenceObject - :Name (IsoAAAD) - :Table (network_objects) - :Uid ("{29C40B0A-414C-11D7-AEB8-7F0000013C3C}") - ) - ) - :install ( - :AdminInfo ( - :chkpf_uid ("{162F84EF-286D-4D55-B03F-8DC9F535553A}") - :ClassName (rule_install) - ) - :compound () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :services ( - :AdminInfo ( - :chkpf_uid ("{130A495D-1435-441B-98CE-993791EBDA7A}") - :ClassName (rule_services) - ) - :compound () - :op () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :src ( - :AdminInfo ( - :chkpf_uid ("{766EEA30-3B32-455D-A951-52D75F93E1D9}") - :ClassName (rule_source) - ) - :compound ( - : (test@Any - :AdminInfo ( - :chkpf_uid ("{C8439795-0347-401E-9663-4EBE924B0F4B}") - :ClassName (rule_user_group) - ) - :at (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - :color (black) - :type (usrgroup) - ) - ) - :op () - ) - ) - :rule ( - :AdminInfo ( - :chkpf_uid ("{24DC38E2-D64D-40EC-B81B-BE3B27A12CED}") - :ClassName (security_header_rule) - ) - :action ( - : (drop - :AdminInfo ( - :chkpf_uid ("{23D057DA-D1AB-4FFD-B61A-806648650D75}") - :ClassName (drop_action) - :table (setup) - ) - :action () - :macro () - :type (drop) - ) - ) - :comments () - :global_location (middle) - :through ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :time ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :track ( - : (ReferenceObject - :Name (None) - :Table (tracks) - :Uid ("{97AEB47D-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :disabled (true) - :dst ( - :AdminInfo ( - :chkpf_uid ("{690BE832-509A-4F4D-A0A2-C9E665129607}") - :ClassName (rule_destination) - ) - :compound () - :op () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :header_text ("IsoAAAE SecuRemote") - :install ( - :AdminInfo ( - :chkpf_uid ("{67EE9042-BF3D-4971-8346-FA36156A5F74}") - :ClassName (rule_install) - ) - :compound () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :services ( - :AdminInfo ( - :chkpf_uid ("{4C231AF1-095C-4CAA-A12C-2EA5B88E76B9}") - :ClassName (rule_services) - ) - :compound () - :op () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :src ( - :AdminInfo ( - :chkpf_uid ("{F23B90BB-44A6-4F7D-8573-48E730D231EE}") - :ClassName (rule_source) - ) - :compound () - :op () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :state (expanded) - ) - :rule ( - :AdminInfo ( - :chkpf_uid ("{4D877153-65A8-48A9-9D11-B30CA56946EF}") - :ClassName (security_rule) - ) - :action ( - : ("Client Encrypt" - :AdminInfo ( - :chkpf_uid ("{13A8B02C-F3C2-473D-A9E9-E49EA1DF3434}") - :ClassName (client_encrypt) - :table (setup) - ) - :action (accept) - :dst_options ("Intersect with User Database") - :enforce_desktop_config (false) - :macro (USER_CLIENT_ENCRYPTION) - :src_options ("Intersect with User Database") - :type (userc) - ) - ) - :comments () - :disabled (false) - :global_location (middle) - :through ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :time ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :track ( - : (ReferenceObject - :Name (Log) - :Table (tracks) - :Uid ("{97AEB480-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :dst ( - :AdminInfo ( - :chkpf_uid ("{C2778755-3B4C-491C-85A7-E4523035CD2B}") - :ClassName (rule_destination) - ) - :compound () - :op () - : (ReferenceObject - :Name (IsoAAADray.local) - :Table (network_objects) - :Uid ("{75EDBC62-7EB1-4D37-8295-684903FDA75A}") - ) - : (ReferenceObject - :Name (gateway.local) - :Table (network_objects) - :Uid ("{7ED7EF12-A13E-4303-8A6E-C6CC28755C80}") - ) - ) - :install ( - :AdminInfo ( - :chkpf_uid ("{CA2D51EE-4A3F-4FE8-B21C-6532E9E7D2C6}") - :ClassName (rule_install) - ) - :compound () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :services ( - :AdminInfo ( - :chkpf_uid ("{5D51CCD0-95A5-408B-83C0-6F18D2B9A460}") - :ClassName (rule_services) - ) - :compound () - :op () - : (ReferenceObject - :Name (CIFS) - :Table (services) - :Uid ("{2A469820-B502-434C-9340-A377677A6A60}") - ) - : (ReferenceObject - :Name (rdp) - :Table (services) - :Uid ("{5BA0C83F-8D91-465B-9CF6-7DC6AEB84689}") - ) - : (ReferenceObject - :Name (ntp-udp) - :Table (services) - :Uid ("{97AEB404-9AEA-11D5-BD16-0090272CCB30}") - ) - : (ReferenceObject - :Name (domain-udp) - :Table (services) - :Uid ("{97AEB3FA-9AEA-11D5-BD16-0090272CCB30}") - ) - : (ReferenceObject - :Name (http) - :Table (services) - :Uid ("{97AEB3D4-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :src ( - :AdminInfo ( - :chkpf_uid ("{3B379A82-34F3-4A23-B77C-B50EAD80BD53}") - :ClassName (rule_source) - ) - :compound ( - : (Cactus-extern@vpn-sources-IsoAAAA - :AdminInfo ( - :chkpf_uid ("{C7F9820A-4EDD-4187-98D9-CC655885E0D6}") - :ClassName (rule_user_group) - ) - :at (ReferenceObject - :Name (vpn-sources-IsoAAAA) - :Table (network_objects) - :Uid ("{26405A41-425C-4053-8002-497BB82D76B1}") - ) - :color (black) - :type (usrgroup) - ) - ) - :op () - ) - ) - :rule ( - :AdminInfo ( - :chkpf_uid ("{AC6B21DA-86AF-4EB3-B294-3387F815E66E}") - :ClassName (security_rule) - ) - :action ( - : ("Client Encrypt" - :AdminInfo ( - :chkpf_uid ("{557B0552-8CDC-40D8-8B63-00E30DC9681A}") - :ClassName (client_encrypt) - :table (setup) - ) - :action (accept) - :dst_options ("intersect with user database") - :enforce_desktop_config (false) - :macro (USER_CLIENT_ENCRYPTION) - :src_options ("intersect with user database") - :type (userc) - ) - ) - :comments () - :disabled (false) - :global_location (middle) - :through ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :time ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :track ( - : (ReferenceObject - :Name (Log) - :Table (tracks) - :Uid ("{97AEB480-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :dst ( - :AdminInfo ( - :chkpf_uid ("{B7130E5B-C62A-4BEF-A2B3-3A2306AE0E5A}") - :ClassName (rule_destination) - ) - :compound () - :op () - : (ReferenceObject - :Name (scratchy.local) - :Table (network_objects) - :Uid ("{CFABE50C-C1F6-4FF1-8AC3-3161A3779708}") - ) - ) - :install ( - :AdminInfo ( - :chkpf_uid ("{58B74533-737D-4182-B405-F3EAC537960A}") - :ClassName (rule_install) - ) - :compound () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :services ( - :AdminInfo ( - :chkpf_uid ("{115D6863-5E76-4339-B76F-8AF7B421C12F}") - :ClassName (rule_services) - ) - :compound () - :op () - : (ReferenceObject - :Name (RAdmin-custom) - :Table (services) - :Uid ("{4FB59153-8212-4A12-BC08-0297AA5F0815}") - ) - ) - :src ( - :AdminInfo ( - :chkpf_uid ("{4400E028-7BB5-405F-AE2C-CE84535C3D32}") - :ClassName (rule_source) - ) - :compound ( - : (IsoAAAG-g@vpn-sources-IsoAAAA - :AdminInfo ( - :chkpf_uid ("{23622C19-C400-4C6D-9BCA-E69C2217DE8E}") - :ClassName (rule_user_group) - ) - :at (ReferenceObject - :Name (vpn-sources-IsoAAAA) - :Table (network_objects) - :Uid ("{26405A41-425C-4053-8002-497BB82D76B1}") - ) - :color (black) - :type (usrgroup) - ) - ) - :op () - ) - ) - :rule ( - :AdminInfo ( - :chkpf_uid ("{5289C1E3-9679-4537-AFD3-AA8663CA5F39}") - :ClassName (security_rule) - ) - :action ( - : ("Client Encrypt" - :AdminInfo ( - :chkpf_uid ("{4572A69E-C640-4125-B38D-1EBEA7F257F0}") - :ClassName (client_encrypt) - :table (setup) - ) - :action (accept) - :dst_options ("Intersect with User Database") - :enforce_desktop_config (false) - :macro (USER_CLIENT_ENCRYPTION) - :src_options ("Intersect with User Database") - :type (userc) - ) - ) - :comments () - :disabled (false) - :global_location (middle) - :through ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :time ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :track ( - : (ReferenceObject - :Name (Log) - :Table (tracks) - :Uid ("{97AEB480-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :dst ( - :AdminInfo ( - :chkpf_uid ("{68ABBD00-BD78-4112-A679-DC94A8CDB47B}") - :ClassName (rule_destination) - ) - :compound () - :op () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :install ( - :AdminInfo ( - :chkpf_uid ("{D26ADD37-6C0A-4402-BAC8-92A4CA9B11CA}") - :ClassName (rule_install) - ) - :compound () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :services ( - :AdminInfo ( - :chkpf_uid ("{99E348A7-72A0-43EC-B728-58DED1B0ED1F}") - :ClassName (rule_services) - ) - :compound () - :op () - : (ReferenceObject - :Name (T-online-classic) - :Table (services) - :Uid ("{738B04E5-09F7-44BF-9FEC-AEA0F15B7E9A}") - ) - : (ReferenceObject - :Name (HBCI) - :Table (services) - :Uid ("{336C93F8-5CC2-48BE-9328-2E92F61EFCF1}") - ) - ) - :src ( - :AdminInfo ( - :chkpf_uid ("{040245DC-1E6B-44D2-A0C5-C7D1A9FAFAF0}") - :ClassName (rule_source) - ) - :compound ( - : (IsoAAAG-g@vpn-sources-IsoAAAA - :AdminInfo ( - :chkpf_uid ("{23622C19-C400-4C6D-9BCA-E69C2217DE8E}") - :ClassName (rule_user_group) - ) - :at (ReferenceObject - :Name (vpn-sources-IsoAAAA) - :Table (network_objects) - :Uid ("{26405A41-425C-4053-8002-497BB82D76B1}") - ) - :color (black) - :type (usrgroup) - ) - ) - :op () - ) - ) - :rule ( - :AdminInfo ( - :chkpf_uid ("{73F2144F-4C58-4361-94B5-459B469A6541}") - :ClassName (security_rule) - ) - :action ( - : ("Client Encrypt" - :AdminInfo ( - :chkpf_uid ("{79C1343A-9B8B-4AB8-8F0C-795A3C6985F8}") - :ClassName (client_encrypt) - :table (setup) - ) - :action (accept) - :dst_options ("Intersect with User Database") - :enforce_desktop_config (false) - :macro (USER_CLIENT_ENCRYPTION) - :src_options ("Intersect with User Database") - :type (userc) - ) - ) - :comments () - :disabled (false) - :global_location (middle) - :through ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :time ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :track ( - : (ReferenceObject - :Name (Log) - :Table (tracks) - :Uid ("{97AEB480-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :dst ( - :AdminInfo ( - :chkpf_uid ("{8D75B038-29A6-4DFC-99BE-77BB50F0248D}") - :ClassName (rule_destination) - ) - :compound () - :op () - : (ReferenceObject - :Name (spike.local) - :Table (network_objects) - :Uid ("{4ABDD8DE-0DA2-46E5-B129-85E3977CBD18}") - ) - : (ReferenceObject - :Name (mg.IsoAAAA-es.com) - :Table (network_objects) - :Uid ("{E5BF8260-3615-4476-B638-53CA3A24FEF1}") - ) - ) - :install ( - :AdminInfo ( - :chkpf_uid ("{64D010BF-D0CB-4F9F-9B7A-DBAD17892364}") - :ClassName (rule_install) - ) - :compound () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :services ( - :AdminInfo ( - :chkpf_uid ("{A9590BAB-F46F-4EB7-8125-A4EE6791DD5F}") - :ClassName (rule_services) - ) - :compound () - :op () - : (ReferenceObject - :Name (squid) - :Table (services) - :Uid ("{91C0454D-F70C-44B3-8F2D-70C4A68E9594}") - ) - : (ReferenceObject - :Name (imap) - :Table (services) - :Uid ("{97AEB446-9AEA-11D5-BD16-0090272CCB30}") - ) - : (ReferenceObject - :Name (imaps) - :Table (services) - :Uid ("{B760A869-04DF-43E2-91F9-414C58F86F16}") - ) - ) - :src ( - :AdminInfo ( - :chkpf_uid ("{32C8D43F-D47D-4477-9217-8E249CBA8F9E}") - :ClassName (rule_source) - ) - :compound ( - : (Cactus-extern@vpn-sources-IsoAAAA - :AdminInfo ( - :chkpf_uid ("{93AC11B4-FFD0-4DBB-BA60-321FE5E9AD32}") - :ClassName (rule_user_group) - ) - :at (ReferenceObject - :Name (vpn-sources-IsoAAAA) - :Table (network_objects) - :Uid ("{26405A41-425C-4053-8002-497BB82D76B1}") - ) - :color (black) - :type (usrgroup) - ) - ) - :op () - ) - ) - :rule ( - :AdminInfo ( - :chkpf_uid ("{6ADC5431-5B24-47FC-A9A6-F8DC912B0515}") - :ClassName (security_rule) - ) - :action ( - : ("Client Encrypt" - :AdminInfo ( - :chkpf_uid ("{6CA48465-23C7-4B10-AAA3-AD9A9E4F8588}") - :ClassName (client_encrypt) - :table (setup) - ) - :action (accept) - :dst_options ("Intersect with User Database") - :enforce_desktop_config (false) - :macro (USER_CLIENT_ENCRYPTION) - :src_options ("Intersect with User Database") - :type (userc) - ) - ) - :comments () - :disabled (false) - :global_location (middle) - :through ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :time ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :track ( - : (ReferenceObject - :Name (Log) - :Table (tracks) - :Uid ("{97AEB480-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :dst ( - :AdminInfo ( - :chkpf_uid ("{586E9FDE-3504-4C3C-B1B3-A73F6D3F379B}") - :ClassName (rule_destination) - ) - :compound () - :op () - : (ReferenceObject - :Name (itchy) - :Table (network_objects) - :Uid ("{3B4DF852-5064-4957-B95F-D469C5656467}") - ) - ) - :install ( - :AdminInfo ( - :chkpf_uid ("{067D0452-9D33-44EA-8433-DF53F0333503}") - :ClassName (rule_install) - ) - :compound () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :services ( - :AdminInfo ( - :chkpf_uid ("{656EA975-486E-43AA-B73C-209ED71366BC}") - :ClassName (rule_services) - ) - :compound () - :op () - : (ReferenceObject - :Name (smtp) - :Table (services) - :Uid ("{97AEB3D9-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :src ( - :AdminInfo ( - :chkpf_uid ("{028E2317-59C3-4783-AFA3-8121A808F9D8}") - :ClassName (rule_source) - ) - :compound ( - : (Cactus-extern@vpn-sources-IsoAAAA - :AdminInfo ( - :chkpf_uid ("{3D633953-A379-43C2-BCD5-CFCE90A8F60D}") - :ClassName (rule_user_group) - ) - :at (ReferenceObject - :Name (vpn-sources-IsoAAAA) - :Table (network_objects) - :Uid ("{26405A41-425C-4053-8002-497BB82D76B1}") - ) - :color (black) - :type (usrgroup) - ) - ) - :op () - ) - ) - :rule ( - :AdminInfo ( - :chkpf_uid ("{09847FA8-6AD8-4196-A6BA-C2E5A4380CAF}") - :ClassName (security_rule) - ) - :action ( - : ("Client Encrypt" - :AdminInfo ( - :chkpf_uid ("{EFBB77A2-67A2-45E9-8D82-5DE40E64C792}") - :ClassName (client_encrypt) - :table (setup) - ) - :action (accept) - :dst_options ("Intersect with User Database") - :enforce_desktop_config (false) - :macro (USER_CLIENT_ENCRYPTION) - :src_options ("Intersect with User Database") - :type (userc) - ) - ) - :comments () - :disabled (false) - :global_location (middle) - :through ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :time ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :track ( - : (ReferenceObject - :Name (Log) - :Table (tracks) - :Uid ("{97AEB480-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :dst ( - :AdminInfo ( - :chkpf_uid ("{AE09F8C4-EE69-4874-A359-DE443685FA10}") - :ClassName (rule_destination) - ) - :compound () - :op () - : (ReferenceObject - :Name (wasp) - :Table (network_objects) - :Uid ("{098B2A74-E220-4AE8-A164-340FED79C9D5}") - ) - ) - :install ( - :AdminInfo ( - :chkpf_uid ("{88454436-C062-4605-BADB-73FD6F534D0F}") - :ClassName (rule_install) - ) - :compound () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :services ( - :AdminInfo ( - :chkpf_uid ("{79BEA1F5-E14E-4C55-B7B2-4765F608CEC4}") - :ClassName (rule_services) - ) - :compound () - :op () - : (ReferenceObject - :Name (ntp-udp) - :Table (services) - :Uid ("{97AEB404-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :src ( - :AdminInfo ( - :chkpf_uid ("{7851EA21-542A-4587-B676-F7DD371446C5}") - :ClassName (rule_source) - ) - :compound ( - : (Cactus-extern@vpn-sources-IsoAAAA - :AdminInfo ( - :chkpf_uid ("{4BC9D4D1-5EE4-45A3-9EE3-77D2B97D21EF}") - :ClassName (rule_user_group) - ) - :at (ReferenceObject - :Name (vpn-sources-IsoAAAA) - :Table (network_objects) - :Uid ("{26405A41-425C-4053-8002-497BB82D76B1}") - ) - :color (black) - :type (usrgroup) - ) - ) - :op () - ) - ) - :rule ( - :AdminInfo ( - :chkpf_uid ("{67784DF8-6440-4F4A-891C-C7062E0F32B0}") - :ClassName (security_rule) - ) - :action ( - : ("Client Encrypt" - :AdminInfo ( - :chkpf_uid ("{CD454805-68CD-42E4-98C3-0DBF82CB9BE6}") - :ClassName (client_encrypt) - :table (setup) - ) - :action (accept) - :dst_options ("Intersect with User Database") - :enforce_desktop_config (false) - :macro (USER_CLIENT_ENCRYPTION) - :src_options ("Intersect with User Database") - :type (userc) - ) - ) - :comments () - :disabled (false) - :global_location (middle) - :through ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :time ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :track ( - : (ReferenceObject - :Name (Log) - :Table (tracks) - :Uid ("{97AEB480-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :dst ( - :AdminInfo ( - :chkpf_uid ("{D29D3530-277E-4D41-86B8-CDFD1640107F}") - :ClassName (rule_destination) - ) - :compound () - :op () - : (ReferenceObject - :Name (wasp) - :Table (network_objects) - :Uid ("{098B2A74-E220-4AE8-A164-340FED79C9D5}") - ) - : (ReferenceObject - :Name (hpux) - :Table (network_objects) - :Uid ("{BF00A847-A0D6-4A75-BE1C-27E7D91EDB55}") - ) - : (ReferenceObject - :Name (sol8) - :Table (network_objects) - :Uid ("{86F22190-7D8D-435D-8906-A346CA12A17C}") - ) - ) - :install ( - :AdminInfo ( - :chkpf_uid ("{35771DD3-A725-4A30-B8D1-2D4DE471A8AA}") - :ClassName (rule_install) - ) - :compound () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :services ( - :AdminInfo ( - :chkpf_uid ("{65CD16B1-1526-40F3-9D70-2C6DE0FD27B8}") - :ClassName (rule_services) - ) - :compound () - :op () - : (ReferenceObject - :Name (telnet) - :Table (services) - :Uid ("{97AEB3CF-9AEA-11D5-BD16-0090272CCB30}") - ) - : (ReferenceObject - :Name (ssh) - :Table (services) - :Uid ("{18EC9EAA-1657-4240-AB97-5F234623336B}") - ) - : (ReferenceObject - :Name (ftp) - :Table (services) - :Uid ("{97AEB3D0-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :src ( - :AdminInfo ( - :chkpf_uid ("{3E20C184-B0AC-458B-AB58-17C5E8D0CB58}") - :ClassName (rule_source) - ) - :compound ( - : (Cactus-extern@vpn-sources-IsoAAAA - :AdminInfo ( - :chkpf_uid ("{4BC9D4D1-5EE4-45A3-9EE3-77D2B97D21EF}") - :ClassName (rule_user_group) - ) - :at (ReferenceObject - :Name (vpn-sources-IsoAAAA) - :Table (network_objects) - :Uid ("{26405A41-425C-4053-8002-497BB82D76B1}") - ) - :color (black) - :type (usrgroup) - ) - ) - :op () - ) - ) - :rule ( - :AdminInfo ( - :chkpf_uid ("{C6951C02-A10A-4757-A85F-5C197D6B95EB}") - :ClassName (security_rule) - ) - :action ( - : ("Client Encrypt" - :AdminInfo ( - :chkpf_uid ("{8EFD07B3-1AE9-4498-A0EA-FFF0CAEC9824}") - :ClassName (client_encrypt) - :table (setup) - ) - :action (accept) - :dst_options ("Intersect with User Database") - :enforce_desktop_config (false) - :macro (USER_CLIENT_ENCRYPTION) - :src_options ("Intersect with User Database") - :type (userc) - ) - ) - :comments () - :disabled (false) - :global_location (middle) - :through ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :time ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :track ( - : (ReferenceObject - :Name (Log) - :Table (tracks) - :Uid ("{97AEB480-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :dst ( - :AdminInfo ( - :chkpf_uid ("{953252BD-3073-4D69-B49A-86B012FEF76D}") - :ClassName (rule_destination) - ) - :compound () - :op () - : (ReferenceObject - :Name (IsoAAAA-100) - :Table (network_objects) - :Uid ("{BF1C6029-8D5D-4A05-A3AD-4B67E6E7A7AA}") - ) - ) - :install ( - :AdminInfo ( - :chkpf_uid ("{019A9168-EF95-46C7-AFB5-B0788EBDAB4B}") - :ClassName (rule_install) - ) - :compound () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :services ( - :AdminInfo ( - :chkpf_uid ("{63D8350C-2432-4909-91D6-4459C3054B4E}") - :ClassName (rule_services) - ) - :compound () - :op () - : (ReferenceObject - :Name (icmp-requests) - :Table (services) - :Uid ("{97AEB413-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :src ( - :AdminInfo ( - :chkpf_uid ("{D6818DB3-CC9E-498A-B47D-DA9204F004F4}") - :ClassName (rule_source) - ) - :compound ( - : (Cactus-extern@vpn-sources-IsoAAAA - :AdminInfo ( - :chkpf_uid ("{970C0D68-3CEC-47CA-B2C0-EB23C9B56AC8}") - :ClassName (rule_user_group) - ) - :at (ReferenceObject - :Name (vpn-sources-IsoAAAA) - :Table (network_objects) - :Uid ("{26405A41-425C-4053-8002-497BB82D76B1}") - ) - :color (black) - :type (usrgroup) - ) - ) - :op () - ) - ) - :rule ( - :AdminInfo ( - :chkpf_uid ("{84087B02-E15A-4E97-9204-F0F866206B75}") - :ClassName (security_header_rule) - ) - :action ( - : (drop - :AdminInfo ( - :chkpf_uid ("{C1A1378F-A974-41CF-BB10-A3F1D8205A3A}") - :ClassName (drop_action) - :table (setup) - ) - :action () - :macro () - :type (drop) - ) - ) - :comments () - :global_location (middle) - :through ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :time ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :track ( - : (ReferenceObject - :Name (None) - :Table (tracks) - :Uid ("{97AEB47D-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :disabled (true) - :dst ( - :AdminInfo ( - :chkpf_uid ("{6CF2DE51-FF05-4F78-A967-BA8F290325BF}") - :ClassName (rule_destination) - ) - :compound () - :op () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :header_text ("IsoAAAE VPN-GW2GW") - :install ( - :AdminInfo ( - :chkpf_uid ("{478AEC09-B131-41B8-8756-A059E1E43421}") - :ClassName (rule_install) - ) - :compound () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :services ( - :AdminInfo ( - :chkpf_uid ("{8F76A99B-E1AD-4595-B528-588D82877DDE}") - :ClassName (rule_services) - ) - :compound () - :op () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :src ( - :AdminInfo ( - :chkpf_uid ("{E356D6BD-676A-4587-90E7-C31B293579C1}") - :ClassName (rule_source) - ) - :compound () - :op () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :state (expanded) - ) - :rule ( - :AdminInfo ( - :chkpf_uid ("{9BC6A630-0169-4289-962F-8E65E0503D01}") - :ClassName (security_rule) - ) - :action ( - : (Encrypt - :AdminInfo ( - :chkpf_uid ("{0B19DE28-8BEC-4290-812D-9B5D4289D12D}") - :ClassName (encrypt) - :table (setup) - ) - :action (accept) - :datam () - :diagnostics-track (CryptLog - :AdminInfo ( - :chkpf_uid ("{4302BEE6-7E9D-46BE-A30A-7D5F42B951D0}") - :ClassName (account) - :table (tracks) - ) - :Name () - :color ("Navy Blue") - :format (crypt) - :icon-name () - :macro () - :type (account) - ) - :gateway (ReferenceObject - :Table (globals) - :Name (Any) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - :isakmp.compression (None) - :isakmp.crlreq (false) - :isakmp.data.integrity (MD5) - :isakmp.encryption (3DES) - :isakmp.gateway (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - :isakmp.phase2_DH_group (ReferenceObject - :Name ("Group 2 (1024 bit)") - :Table (encryption) - :Uid ("{97AEB629-9AEA-11D5-BD16-0090272CCB30}") - ) - :isakmp.transform (ESP) - :isakmp.use_pfs (false) - :isakmp.useippools (false) - :keym () - :macro (ENCRYPTION) - :mdm (MD5) - :menu_inactive (false) - :scheme (ISAKMP) - :type (encrypt) - ) - ) - :comments () - :global_location (middle) - :through ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :time ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :track ( - : (ReferenceObject - :Name (Log) - :Table (tracks) - :Uid ("{97AEB480-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :disabled (true) - :dst ( - :AdminInfo ( - :chkpf_uid ("{83858D79-EC2C-4812-9B9B-2346DFC72654}") - :ClassName (rule_destination) - ) - :compound () - :op () - : (ReferenceObject - :Name (IsoAAAA-100) - :Table (network_objects) - :Uid ("{BF1C6029-8D5D-4A05-A3AD-4B67E6E7A7AA}") - ) - ) - :install ( - :AdminInfo ( - :chkpf_uid ("{50CB20E0-39A1-42D5-9495-BA814B304829}") - :ClassName (rule_install) - ) - :compound () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :services ( - :AdminInfo ( - :chkpf_uid ("{938E9BAA-A4E0-42DE-B985-4FC332A0008A}") - :ClassName (rule_services) - ) - :compound () - :op () - : (ReferenceObject - :Name (icmp-requests) - :Table (services) - :Uid ("{97AEB413-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :src ( - :AdminInfo ( - :chkpf_uid ("{288657B3-E155-44B2-9023-5BDBB46EF52F}") - :ClassName (rule_source) - ) - :compound () - :op () - : (ReferenceObject - :Name (IsoAAAA_home_tim) - :Table (network_objects) - :Uid ("{BF8F69B9-87C2-464A-9404-239AE8DF66B3}") - ) - ) - ) - :rule ( - :AdminInfo ( - :chkpf_uid ("{1B421F3A-CCFB-4816-B5D0-2D69F5D98DC3}") - :ClassName (security_rule) - ) - :action ( - : (Encrypt - :AdminInfo ( - :chkpf_uid ("{7B2AB0CD-8E90-4AED-B40D-57919CC85E3E}") - :ClassName (encrypt) - :table (setup) - ) - :action (accept) - :datam () - :diagnostics-track (CryptLog - :AdminInfo ( - :chkpf_uid ("{88330614-2043-4829-BE4E-9849E3E56931}") - :ClassName (account) - :table (tracks) - ) - :Name () - :color ("Navy Blue") - :format (crypt) - :icon-name () - :macro () - :type (account) - ) - :gateway (ReferenceObject - :Table (globals) - :Name (Any) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - :isakmp.compression (None) - :isakmp.crlreq (false) - :isakmp.data.integrity (MD5) - :isakmp.encryption (3DES) - :isakmp.gateway (ReferenceObject - :Name (IsoAAAD) - :Table (network_objects) - :Uid ("{29C40B0A-414C-11D7-AEB8-7F0000013C3C}") - ) - :isakmp.phase2_DH_group (ReferenceObject - :Table (encryption) - :Name ("Group 2 (1024 bit)") - :Uid ("{97AEB629-9AEA-11D5-BD16-0090272CCB30}") - ) - :isakmp.transform (ESP) - :isakmp.use_pfs (false) - :isakmp.useippools (false) - :keym () - :macro (ENCRYPTION) - :mdm (MD5) - :menu_inactive (false) - :scheme (ISAKMP) - :type (encrypt) - ) - ) - :comments () - :disabled (false) - :global_location (middle) - :through ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :time ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :track ( - : (ReferenceObject - :Name (Log) - :Table (tracks) - :Uid ("{97AEB480-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :dst ( - :AdminInfo ( - :chkpf_uid ("{2E07BEF2-A8D2-420C-B73A-97F71499CF78}") - :ClassName (rule_destination) - ) - :compound () - :op () - : (ReferenceObject - :Name (IsoAAAA-100) - :Table (network_objects) - :Uid ("{BF1C6029-8D5D-4A05-A3AD-4B67E6E7A7AA}") - ) - ) - :install ( - :AdminInfo ( - :chkpf_uid ("{E4654732-4C19-4B16-B48E-9045187B0E7D}") - :ClassName (rule_install) - ) - :compound () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :services ( - :AdminInfo ( - :chkpf_uid ("{56D6CE5A-FD31-4622-BCD4-14B2B79E9831}") - :ClassName (rule_services) - ) - :compound () - :op () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :src ( - :AdminInfo ( - :chkpf_uid ("{C698A8A9-97D7-477E-98FA-1A67C583F157}") - :ClassName (rule_source) - ) - :compound () - :op () - : (ReferenceObject - :Name (SonicLAN) - :Table (network_objects) - :Uid ("{587A029D-04EA-49A0-9DB2-93ADC651B7BF}") - ) - ) - ) - :rule ( - :AdminInfo ( - :chkpf_uid ("{7F7BEC1D-4972-4E6B-9F74-2808D5D82A44}") - :ClassName (security_rule) - ) - :action ( - : (Encrypt - :AdminInfo ( - :chkpf_uid ("{DE69F779-E476-4D83-A45D-01E7AE697727}") - :ClassName (encrypt) - :table (setup) - ) - :action (accept) - :datam () - :diagnostics-track (CryptLog - :AdminInfo ( - :chkpf_uid ("{7B3D6F79-64C4-4E84-B374-D3F4FF4F6646}") - :ClassName (account) - :table (tracks) - ) - :Name () - :color ("Navy Blue") - :format (crypt) - :icon-name () - :macro () - :type (account) - ) - :gateway (ReferenceObject - :Table (globals) - :Name (Any) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - :isakmp.compression (None) - :isakmp.crlreq (false) - :isakmp.data.integrity (MD5) - :isakmp.encryption (3DES) - :isakmp.gateway (ReferenceObject - :Name (Sonic1) - :Table (network_objects) - :Uid ("{B2EBD57B-C94C-42E7-8F1A-17C861697403}") - ) - :isakmp.phase2_DH_group (ReferenceObject - :Table (encryption) - :Name ("Group 2 (1024 bit)") - :Uid ("{97AEB629-9AEA-11D5-BD16-0090272CCB30}") - ) - :isakmp.transform (ESP) - :isakmp.use_pfs (false) - :isakmp.useippools (false) - :keym () - :macro (ENCRYPTION) - :mdm (MD5) - :menu_inactive (false) - :scheme (ISAKMP) - :type (encrypt) - ) - ) - :comments () - :disabled (false) - :global_location (middle) - :through ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :time ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :track ( - : (ReferenceObject - :Name (Log) - :Table (tracks) - :Uid ("{97AEB480-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :dst ( - :AdminInfo ( - :chkpf_uid ("{B08B1D30-7A98-4EB1-A10F-8A5EA4E5751D}") - :ClassName (rule_destination) - ) - :compound () - :op () - : (ReferenceObject - :Name (SonicLAN) - :Table (network_objects) - :Uid ("{587A029D-04EA-49A0-9DB2-93ADC651B7BF}") - ) - : (ReferenceObject - :Name (Sonic1) - :Table (network_objects) - :Uid ("{B2EBD57B-C94C-42E7-8F1A-17C861697403}") - ) - ) - :install ( - :AdminInfo ( - :chkpf_uid ("{A4D22342-EAE3-42F9-96A9-AA42177E4662}") - :ClassName (rule_install) - ) - :compound () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :services ( - :AdminInfo ( - :chkpf_uid ("{4171D4D8-3AEE-4503-889B-2F2BB38E7E6B}") - :ClassName (rule_services) - ) - :compound () - :op () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :src ( - :AdminInfo ( - :chkpf_uid ("{2E872EC3-8CCF-4263-92F7-5C0DFCF66ED7}") - :ClassName (rule_source) - ) - :compound () - :op () - : (ReferenceObject - :Name (IsoAAAA-100) - :Table (network_objects) - :Uid ("{BF1C6029-8D5D-4A05-A3AD-4B67E6E7A7AA}") - ) - ) - ) - :rule ( - :AdminInfo ( - :chkpf_uid ("{7D822D25-45D2-4906-8C8E-72652A4E9C7C}") - :ClassName (security_header_rule) - ) - :action ( - : (drop - :AdminInfo ( - :chkpf_uid ("{8AEAF6EF-1859-4E89-A58F-4F275BF154AA}") - :ClassName (drop_action) - :table (setup) - ) - :action () - :macro () - :type (drop) - ) - ) - :comments () - :global_location (middle) - :through ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :time ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :track ( - : (ReferenceObject - :Name (None) - :Table (tracks) - :Uid ("{97AEB47D-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :disabled (true) - :dst ( - :AdminInfo ( - :chkpf_uid ("{08B3D275-0F89-4C3F-B53E-1E3ECA583C23}") - :ClassName (rule_destination) - ) - :compound () - :op () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :header_text (Internal-Connections) - :install ( - :AdminInfo ( - :chkpf_uid ("{CA6C0AAF-DBCE-4020-B529-4E4449A1EFAA}") - :ClassName (rule_install) - ) - :compound () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :services ( - :AdminInfo ( - :chkpf_uid ("{6FB76A7B-3073-434B-ADDA-81C99060AEBA}") - :ClassName (rule_services) - ) - :compound () - :op () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :src ( - :AdminInfo ( - :chkpf_uid ("{79B42650-50CC-4AD9-A13E-A0E4AB4D7383}") - :ClassName (rule_source) - ) - :compound () - :op () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :state (expanded) - ) - :rule ( - :AdminInfo ( - :chkpf_uid ("{EACACDFF-02E7-4014-9DA7-1A5487AB8481}") - :ClassName (security_rule) - ) - :action ( - : (accept - :AdminInfo ( - :chkpf_uid ("{87CA79FF-466D-4BCF-B6C4-42FE6346885F}") - :ClassName (accept_action) - :table (setup) - ) - :action () - :macro (RECORD_CONN) - :type (accept) - ) - ) - :comments () - :disabled (false) - :global_location (middle) - :through ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :time ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :track ( - : (ReferenceObject - :Name (Log) - :Table (tracks) - :Uid ("{97AEB480-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :dst ( - :AdminInfo ( - :chkpf_uid ("{38233DD1-F39A-42F7-80B7-74A2F3C959BE}") - :ClassName (rule_destination) - ) - :compound () - :op () - : (ReferenceObject - :Name (IsoAAAD) - :Table (network_objects) - :Uid ("{29C40B0A-414C-11D7-AEB8-7F0000013C3C}") - ) - ) - :install ( - :AdminInfo ( - :chkpf_uid ("{D4207D0B-4AA6-4438-A102-EAF2E08BCABC}") - :ClassName (rule_install) - ) - :compound () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :services ( - :AdminInfo ( - :chkpf_uid ("{0D51549F-279B-4544-97E7-672C85874699}") - :ClassName (rule_services) - ) - :compound () - :op () - : (ReferenceObject - :Name (ssh) - :Table (services) - :Uid ("{18EC9EAA-1657-4240-AB97-5F234623336B}") - ) - : (ReferenceObject - :Name (https) - :Table (services) - :Uid ("{97AEB443-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :src ( - :AdminInfo ( - :chkpf_uid ("{C0F53557-6630-4779-8F85-30AA74C8BB3F}") - :ClassName (rule_source) - ) - :compound () - :op () - : (ReferenceObject - :Name (IsoAAAA-100) - :Table (network_objects) - :Uid ("{BF1C6029-8D5D-4A05-A3AD-4B67E6E7A7AA}") - ) - : (ReferenceObject - :Name (IsoAAAA_home_tim) - :Table (network_objects) - :Uid ("{BF8F69B9-87C2-464A-9404-239AE8DF66B3}") - ) - : (ReferenceObject - :Name (mg.IsoAAAA-es.com) - :Table (network_objects) - :Uid ("{E5BF8260-3615-4476-B638-53CA3A24FEF1}") - ) - ) - ) - :rule ( - :AdminInfo ( - :chkpf_uid ("{C5F973E3-CBB2-4C15-A735-52B51AC9DAE7}") - :ClassName (security_rule) - ) - :action ( - : (accept - :AdminInfo ( - :chkpf_uid ("{396BFDCC-A290-408E-9F92-791EA8CF3616}") - :ClassName (accept_action) - :table (setup) - ) - :action () - :macro (RECORD_CONN) - :type (accept) - ) - ) - :comments () - :disabled (false) - :global_location (middle) - :through ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :time ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :track ( - : (ReferenceObject - :Name (Log) - :Table (tracks) - :Uid ("{97AEB480-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :dst ( - :AdminInfo ( - :chkpf_uid ("{389DDDD2-29F4-4D0F-A969-726529DF0919}") - :ClassName (rule_destination) - ) - :compound () - :op () - : (ReferenceObject - :Name (daba) - :Table (network_objects) - :Uid ("{94817CDB-EA8C-4213-B38D-F4417EA620C6}") - ) - ) - :install ( - :AdminInfo ( - :chkpf_uid ("{D76410C0-68C5-40EA-A75A-9FFB9B0EF2E8}") - :ClassName (rule_install) - ) - :compound () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :services ( - :AdminInfo ( - :chkpf_uid ("{FCA57859-3422-4495-954F-E7D746378008}") - :ClassName (rule_services) - ) - :compound () - :op () - : (ReferenceObject - :Name (ssh) - :Table (services) - :Uid ("{18EC9EAA-1657-4240-AB97-5F234623336B}") - ) - : (ReferenceObject - :Name (mysql) - :Table (services) - :Uid ("{08A07607-EAAA-4A45-AD6E-6020770BD519}") - ) - ) - :src ( - :AdminInfo ( - :chkpf_uid ("{B98DA2C1-079F-4EF2-A67D-5FCEC98B1FE8}") - :ClassName (rule_source) - ) - :compound () - :op () - : (ReferenceObject - :Name (IsoAAAA-100) - :Table (network_objects) - :Uid ("{BF1C6029-8D5D-4A05-A3AD-4B67E6E7A7AA}") - ) - : (ReferenceObject - :Name (IsoAAAA_home_tim) - :Table (network_objects) - :Uid ("{BF8F69B9-87C2-464A-9404-239AE8DF66B3}") - ) - ) - ) - :rule ( - :AdminInfo ( - :chkpf_uid ("{0D4D75A0-8203-453F-9C3E-F68E1995DE88}") - :ClassName (security_rule) - ) - :action ( - : (accept - :AdminInfo ( - :chkpf_uid ("{317B8552-195E-4E2A-8EA7-CEE52B732C38}") - :ClassName (accept_action) - :table (setup) - ) - :action () - :macro (RECORD_CONN) - :type (accept) - ) - ) - :comments () - :disabled (false) - :global_location (middle) - :through ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :time ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :track ( - : (ReferenceObject - :Name (None) - :Table (tracks) - :Uid ("{97AEB47D-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :dst ( - :AdminInfo ( - :chkpf_uid ("{C80F45A6-E7AD-4F87-89A8-31CC7D5A5E53}") - :ClassName (rule_destination) - ) - :compound () - :op () - : (ReferenceObject - :Name (wasp) - :Table (network_objects) - :Uid ("{098B2A74-E220-4AE8-A164-340FED79C9D5}") - ) - : (ReferenceObject - :Name (mg.IsoAAAA-es.com) - :Table (network_objects) - :Uid ("{E5BF8260-3615-4476-B638-53CA3A24FEF1}") - ) - ) - :install ( - :AdminInfo ( - :chkpf_uid ("{9D97B55B-160C-46D2-ADFA-6D235D7D9733}") - :ClassName (rule_install) - ) - :compound () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :services ( - :AdminInfo ( - :chkpf_uid ("{8305714C-A6BA-4B6C-A1A9-2E54349BB3ED}") - :ClassName (rule_services) - ) - :compound () - :op () - : (ReferenceObject - :Name (ntp-udp) - :Table (services) - :Uid ("{97AEB404-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :src ( - :AdminInfo ( - :chkpf_uid ("{398C5E6F-5E01-4646-ABAB-BF775B461AE6}") - :ClassName (rule_source) - ) - :compound () - :op () - : (ReferenceObject - :Name (IsoAAAD) - :Table (network_objects) - :Uid ("{29C40B0A-414C-11D7-AEB8-7F0000013C3C}") - ) - ) - ) - :rule ( - :AdminInfo ( - :chkpf_uid ("{A1ACBE88-9F38-4947-B497-B34A2F3878B3}") - :ClassName (security_rule) - ) - :action ( - : (accept - :AdminInfo ( - :chkpf_uid ("{F8FE4FD5-50BE-4D6E-93FE-93071473FFF0}") - :ClassName (accept_action) - :table (setup) - ) - :action () - :macro (RECORD_CONN) - :type (accept) - ) - ) - :comments () - :disabled (false) - :global_location (middle) - :through ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :time ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :track ( - : (ReferenceObject - :Name (None) - :Table (tracks) - :Uid ("{97AEB47D-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :dst ( - :AdminInfo ( - :chkpf_uid ("{442DA9A3-9028-4077-88ED-F676CC39EA6A}") - :ClassName (rule_destination) - ) - :compound () - :op () - : (ReferenceObject - :Name (IsoAAADray.local) - :Table (network_objects) - :Uid ("{75EDBC62-7EB1-4D37-8295-684903FDA75A}") - ) - ) - :install ( - :AdminInfo ( - :chkpf_uid ("{22AF536A-CE60-42B9-8D92-B2B84B1B849A}") - :ClassName (rule_install) - ) - :compound () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :services ( - :AdminInfo ( - :chkpf_uid ("{FE031AD5-4408-419D-9CAC-E33FD47B4872}") - :ClassName (rule_services) - ) - :compound () - :op () - : (ReferenceObject - :Name (domain-udp) - :Table (services) - :Uid ("{97AEB3FA-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :src ( - :AdminInfo ( - :chkpf_uid ("{EA42965D-38DF-4E67-8A06-6BF107BEC1BE}") - :ClassName (rule_source) - ) - :compound () - :op () - : (ReferenceObject - :Name (IsoAAAD) - :Table (network_objects) - :Uid ("{29C40B0A-414C-11D7-AEB8-7F0000013C3C}") - ) - ) - ) - :rule ( - :AdminInfo ( - :chkpf_uid ("{321D1155-8DB8-48D3-8F89-789456335EA5}") - :ClassName (security_rule) - ) - :action ( - : (accept - :AdminInfo ( - :chkpf_uid ("{EF61D86E-D8BD-4E00-83C7-D4D6413AA826}") - :ClassName (accept_action) - :table (setup) - ) - :action () - :macro (RECORD_CONN) - :type (accept) - ) - ) - :comments () - :disabled (false) - :global_location (middle) - :through ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :time ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :track ( - : (ReferenceObject - :Name (Log) - :Table (tracks) - :Uid ("{97AEB480-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :dst ( - :AdminInfo ( - :chkpf_uid ("{6ECE3813-9B88-4B95-8F48-35760521161D}") - :ClassName (rule_destination) - ) - :compound () - :op () - : (ReferenceObject - :Name (spike.local) - :Table (network_objects) - :Uid ("{4ABDD8DE-0DA2-46E5-B129-85E3977CBD18}") - ) - : (ReferenceObject - :Name (mg.IsoAAAA-es.com) - :Table (network_objects) - :Uid ("{E5BF8260-3615-4476-B638-53CA3A24FEF1}") - ) - ) - :install ( - :AdminInfo ( - :chkpf_uid ("{B6B3B97E-55C4-41CA-B951-91FBA42AD24D}") - :ClassName (rule_install) - ) - :compound () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :services ( - :AdminInfo ( - :chkpf_uid ("{E4826F35-742D-4BE5-814E-5ECE6741D719}") - :ClassName (rule_services) - ) - :compound () - :op () - : (ReferenceObject - :Name (syslog) - :Table (services) - :Uid ("{97AEB3E0-9AEA-11D5-BD16-0090272CCB30}") - ) - : (ReferenceObject - :Name (ssh_version_2) - :Table (services) - :Uid ("{CD082D9A-44A6-4CEF-A17D-5541029ADFB3}") - ) - : (ReferenceObject - :Name (domain-udp) - :Table (services) - :Uid ("{97AEB3FA-9AEA-11D5-BD16-0090272CCB30}") - ) - : (ReferenceObject - :Name (smtp) - :Table (services) - :Uid ("{97AEB3D9-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :src ( - :AdminInfo ( - :chkpf_uid ("{CBCA552F-5195-4594-8FCD-DB44E1E54E08}") - :ClassName (rule_source) - ) - :compound () - :op () - : (ReferenceObject - :Name (IsoAAAD) - :Table (network_objects) - :Uid ("{29C40B0A-414C-11D7-AEB8-7F0000013C3C}") - ) - ) - ) - :rule ( - :AdminInfo ( - :chkpf_uid ("{479DFC1D-FE51-4CFB-9A99-4FD1A532B7B4}") - :ClassName (security_header_rule) - ) - :action ( - : (drop - :AdminInfo ( - :chkpf_uid ("{575C62B8-634C-4115-9DF5-3C75BBFBFDEE}") - :ClassName (drop_action) - :table (setup) - ) - :action () - :macro () - :type (drop) - ) - ) - :comments () - :global_location (middle) - :through ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :time ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :track ( - : (ReferenceObject - :Name (None) - :Table (tracks) - :Uid ("{97AEB47D-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :disabled (true) - :dst ( - :AdminInfo ( - :chkpf_uid ("{EF6C7FE7-9266-491E-8933-CC4429B97209}") - :ClassName (rule_destination) - ) - :compound () - :op () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :header_text ("Intern to Spike") - :install ( - :AdminInfo ( - :chkpf_uid ("{CA20EBCF-96AC-402F-87BB-25C0EC09879B}") - :ClassName (rule_install) - ) - :compound () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :services ( - :AdminInfo ( - :chkpf_uid ("{5505712A-4BAB-46F8-BFAF-62A682802247}") - :ClassName (rule_services) - ) - :compound () - :op () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :src ( - :AdminInfo ( - :chkpf_uid ("{3B75D561-22D8-4C61-9CA7-A843272AA499}") - :ClassName (rule_source) - ) - :compound () - :op () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :state (collapsed) - ) - :rule ( - :AdminInfo ( - :chkpf_uid ("{F18D892E-EED1-488B-A0D9-832B742CE27B}") - :ClassName (security_rule) - ) - :action ( - : (accept - :AdminInfo ( - :chkpf_uid ("{BD096130-776F-4884-A5E3-66951FEDCAA1}") - :ClassName (accept_action) - :table (setup) - ) - :action () - :macro (RECORD_CONN) - :type (accept) - ) - ) - :comments () - :disabled (false) - :global_location (middle) - :through ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :time ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :track ( - : (ReferenceObject - :Name (Log) - :Table (tracks) - :Uid ("{97AEB480-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :dst ( - :AdminInfo ( - :chkpf_uid ("{69FBBF03-9653-4708-95E4-A3085DA3502E}") - :ClassName (rule_destination) - ) - :compound () - :op () - : (ReferenceObject - :Name (spike.local) - :Table (network_objects) - :Uid ("{4ABDD8DE-0DA2-46E5-B129-85E3977CBD18}") - ) - : (ReferenceObject - :Name (mg.IsoAAAA-es.com) - :Table (network_objects) - :Uid ("{E5BF8260-3615-4476-B638-53CA3A24FEF1}") - ) - : (ReferenceObject - :Name (ras.IsoAAAA-es.com) - :Table (network_objects) - :Uid ("{23B1E779-B8D5-4384-AD60-80E498B77196}") - ) - ) - :install ( - :AdminInfo ( - :chkpf_uid ("{58BE428C-CA30-4DD6-8D0C-DD21E8D5716A}") - :ClassName (rule_install) - ) - :compound () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :services ( - :AdminInfo ( - :chkpf_uid ("{D45CFA85-C7A9-4770-BBA5-38DC95DE2E39}") - :ClassName (rule_services) - ) - :compound () - :op () - : (ReferenceObject - :Name (SpikeServices) - :Table (services) - :Uid ("{9D35FACE-289F-49A6-95C7-13417959BC9D}") - ) - ) - :src ( - :AdminInfo ( - :chkpf_uid ("{CEAC96CA-4B08-4E15-B8E5-F555868B9B9D}") - :ClassName (rule_source) - ) - :compound () - :op () - : (ReferenceObject - :Name (IsoAAAA-100) - :Table (network_objects) - :Uid ("{BF1C6029-8D5D-4A05-A3AD-4B67E6E7A7AA}") - ) - ) - ) - :rule ( - :AdminInfo ( - :chkpf_uid ("{001AA0F0-DFE8-4CAD-9B62-C26E1A5CB9A0}") - :ClassName (security_header_rule) - ) - :action ( - : (drop - :AdminInfo ( - :chkpf_uid ("{339E1791-EB7E-4985-8B54-EBE0E6097CCB}") - :ClassName (drop_action) - :table (setup) - ) - :action () - :macro () - :type (drop) - ) - ) - :comments () - :global_location (middle) - :through ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :time ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :track ( - : (ReferenceObject - :Name (None) - :Table (tracks) - :Uid ("{97AEB47D-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :disabled (true) - :dst ( - :AdminInfo ( - :chkpf_uid ("{A78DD97F-4A53-4494-8F90-EABA9B30D6B5}") - :ClassName (rule_destination) - ) - :compound () - :op () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :header_text ("Intern to DMZ") - :install ( - :AdminInfo ( - :chkpf_uid ("{209BE460-BB82-44DD-817D-FF2E22395B31}") - :ClassName (rule_install) - ) - :compound () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :services ( - :AdminInfo ( - :chkpf_uid ("{E0D91B63-F2A0-4973-B07E-AEDD817454E5}") - :ClassName (rule_services) - ) - :compound () - :op () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :src ( - :AdminInfo ( - :chkpf_uid ("{9BD55163-1255-4D94-BE33-13A5569A02ED}") - :ClassName (rule_source) - ) - :compound () - :op () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :state (expanded) - ) - :rule ( - :AdminInfo ( - :chkpf_uid ("{00477CC9-4940-4C79-B2E6-A137781B1C25}") - :ClassName (security_rule) - ) - :action ( - : (accept - :AdminInfo ( - :chkpf_uid ("{47ACCCC4-3B42-4BE4-8E43-AF61E4E0FB86}") - :ClassName (accept_action) - :table (setup) - ) - :action () - :macro (RECORD_CONN) - :type (accept) - ) - ) - :comments () - :disabled (false) - :global_location (middle) - :through ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :time ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :track ( - : (ReferenceObject - :Name (Log) - :Table (tracks) - :Uid ("{97AEB480-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :dst ( - :AdminInfo ( - :chkpf_uid ("{F16C6F8C-1F05-4B70-87D9-CECE46630C0C}") - :ClassName (rule_destination) - ) - :compound () - :op () - : (ReferenceObject - :Name (Cactus-DMZ1) - :Table (network_objects) - :Uid ("{62523F8E-9AE0-4CC0-82C6-BB41846BA2B7}") - ) - : (ReferenceObject - :Name (Cactus-DMZ2) - :Table (network_objects) - :Uid ("{61AB70E0-5514-43CF-9194-B37A13EC102D}") - ) - : (ReferenceObject - :Name (Cactus-DMZ4) - :Table (network_objects) - :Uid ("{9C2C49CE-5100-423C-BECB-08951751059F}") - ) - ) - :install ( - :AdminInfo ( - :chkpf_uid ("{E18116F6-2DF8-42C8-8F65-D00C902B23AB}") - :ClassName (rule_install) - ) - :compound () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :services ( - :AdminInfo ( - :chkpf_uid ("{FFEF9B1D-B59B-4A07-AEDE-63918094EDB8}") - :ClassName (rule_services) - ) - :compound () - :op () - : (ReferenceObject - :Name (ssh_version_2) - :Table (services) - :Uid ("{CD082D9A-44A6-4CEF-A17D-5541029ADFB3}") - ) - : (ReferenceObject - :Name (sshv2-24) - :Table (services) - :Uid ("{1DA78BCE-7ABC-4DBB-82AF-FDBE6B853493}") - ) - ) - :src ( - :AdminInfo ( - :chkpf_uid ("{2D6919C8-EBF0-46B2-95CE-7FD2AFF8DBF0}") - :ClassName (rule_source) - ) - :compound () - :op () - : (ReferenceObject - :Name (IsoAAAA-100) - :Table (network_objects) - :Uid ("{BF1C6029-8D5D-4A05-A3AD-4B67E6E7A7AA}") - ) - ) - ) - :rule ( - :AdminInfo ( - :chkpf_uid ("{2CDC82FD-6292-45D7-A4B8-6794C378A47B}") - :ClassName (security_rule) - ) - :action ( - : (accept - :AdminInfo ( - :chkpf_uid ("{DBFD040E-D17D-481F-B6E2-D9E5AE306BBD}") - :ClassName (accept_action) - :table (setup) - ) - :action () - :macro (RECORD_CONN) - :type (accept) - ) - ) - :comments () - :disabled (false) - :global_location (middle) - :through ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :time ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :track ( - : (ReferenceObject - :Name (Log) - :Table (tracks) - :Uid ("{97AEB480-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :dst ( - :AdminInfo ( - :chkpf_uid ("{AAADBB03-1A01-4136-8104-91B265E567A3}") - :ClassName (rule_destination) - ) - :compound () - :op () - : (ReferenceObject - :Name (Cactus10.222.0.1) - :Table (network_objects) - :Uid ("{6CD51061-638B-4B2F-9092-7E1E4A5F0ADD}") - ) - ) - :install ( - :AdminInfo ( - :chkpf_uid ("{77D96FA7-8F8F-4F17-9F1C-868F1472C870}") - :ClassName (rule_install) - ) - :compound () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :services ( - :AdminInfo ( - :chkpf_uid ("{A042A0B6-6CD8-4A84-90A5-B39B35590148}") - :ClassName (rule_services) - ) - :compound () - :op () - : (ReferenceObject - :Name (VNC) - :Table (services) - :Uid ("{9788B566-735E-4158-A169-8701B9624E47}") - ) - ) - :src ( - :AdminInfo ( - :chkpf_uid ("{2F62C069-51CA-424D-A3EB-235DD9728611}") - :ClassName (rule_source) - ) - :compound () - :op () - : (ReferenceObject - :Name (IsoAAAA-100) - :Table (network_objects) - :Uid ("{BF1C6029-8D5D-4A05-A3AD-4B67E6E7A7AA}") - ) - ) - ) - :rule ( - :AdminInfo ( - :chkpf_uid ("{8EDEBE48-F02B-4AEA-8337-FBE1E2079BE0}") - :ClassName (security_rule) - ) - :action ( - : (accept - :AdminInfo ( - :chkpf_uid ("{47CF3B75-BE35-45E1-B56E-B8A61ECE885B}") - :ClassName (accept_action) - :table (setup) - ) - :action () - :macro (RECORD_CONN) - :type (accept) - ) - ) - :comments () - :disabled (false) - :global_location (middle) - :through ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :time ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :track ( - : (ReferenceObject - :Name (Log) - :Table (tracks) - :Uid ("{97AEB480-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :dst ( - :AdminInfo ( - :chkpf_uid ("{7149B69F-E170-4FCC-B958-76AE0F704EA0}") - :ClassName (rule_destination) - ) - :compound () - :op () - : (ReferenceObject - :Name (itchy) - :Table (network_objects) - :Uid ("{3B4DF852-5064-4957-B95F-D469C5656467}") - ) - ) - :install ( - :AdminInfo ( - :chkpf_uid ("{50C640DC-6413-458C-BD30-9E947F408315}") - :ClassName (rule_install) - ) - :compound () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :services ( - :AdminInfo ( - :chkpf_uid ("{3F4AF5D6-72D0-4C52-A1BD-29AB242927D0}") - :ClassName (rule_services) - ) - :compound () - :op () - : (ReferenceObject - :Name (domain-udp) - :Table (services) - :Uid ("{97AEB3FA-9AEA-11D5-BD16-0090272CCB30}") - ) - : (ReferenceObject - :Name (CIFS) - :Table (services) - :Uid ("{2A469820-B502-434C-9340-A377677A6A60}") - ) - ) - :src ( - :AdminInfo ( - :chkpf_uid ("{EA36998F-4F7C-4250-BECC-4CEBB36E9EAE}") - :ClassName (rule_source) - ) - :compound () - :op () - : (ReferenceObject - :Name (IsoAAAA-100) - :Table (network_objects) - :Uid ("{BF1C6029-8D5D-4A05-A3AD-4B67E6E7A7AA}") - ) - ) - ) - :rule ( - :AdminInfo ( - :chkpf_uid ("{0F6D252E-7562-457F-81A3-60192F3EC815}") - :ClassName (security_rule) - ) - :action ( - : (accept - :AdminInfo ( - :chkpf_uid ("{0CEE5A08-F53C-439A-8180-A62450938BA6}") - :ClassName (accept_action) - :table (setup) - ) - :action () - :macro (RECORD_CONN) - :type (accept) - ) - ) - :comments () - :disabled (false) - :global_location (middle) - :through ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :time ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :track ( - : (ReferenceObject - :Name (Log) - :Table (tracks) - :Uid ("{97AEB480-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :dst ( - :AdminInfo ( - :chkpf_uid ("{C414C09F-B8D2-4DD6-8DD1-B5044B787753}") - :ClassName (rule_destination) - ) - :compound () - :op () - : (ReferenceObject - :Name (MailServer) - :Table (network_objects) - :Uid ("{17935795-6ADC-4B45-8E2B-BEC361E6CAB1}") - ) - ) - :install ( - :AdminInfo ( - :chkpf_uid ("{1ADD0F50-D00E-463E-AF4B-5F7B9602F8FB}") - :ClassName (rule_install) - ) - :compound () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :services ( - :AdminInfo ( - :chkpf_uid ("{F89128E4-058B-45CC-8BE9-62261DDB22A0}") - :ClassName (rule_services) - ) - :compound () - :op () - : (ReferenceObject - :Name (smtp) - :Table (services) - :Uid ("{97AEB3D9-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :src ( - :AdminInfo ( - :chkpf_uid ("{1265804A-4F79-416E-ABDC-2BC3BC6E9513}") - :ClassName (rule_source) - ) - :compound () - :op () - : (ReferenceObject - :Name (IsoAAAA-100) - :Table (network_objects) - :Uid ("{BF1C6029-8D5D-4A05-A3AD-4B67E6E7A7AA}") - ) - ) - ) - :rule ( - :AdminInfo ( - :chkpf_uid ("{A3B9D85B-AD6D-4991-8A9D-960939C491C2}") - :ClassName (security_rule) - ) - :action ( - : (accept - :AdminInfo ( - :chkpf_uid ("{C8749F14-4AE2-4544-B239-7CC349656359}") - :ClassName (accept_action) - :table (setup) - ) - :action () - :macro (RECORD_CONN) - :type (accept) - ) - ) - :comments () - :disabled (false) - :global_location (middle) - :through ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :time ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :track ( - : (ReferenceObject - :Name (None) - :Table (tracks) - :Uid ("{97AEB47D-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :dst ( - :AdminInfo ( - :chkpf_uid ("{A7BD46F5-7D1D-424F-BBB4-CCE8564D68C7}") - :ClassName (rule_destination) - ) - :compound () - :op () - : (ReferenceObject - :Name (wasp) - :Table (network_objects) - :Uid ("{098B2A74-E220-4AE8-A164-340FED79C9D5}") - ) - : (ReferenceObject - :Name (mg.IsoAAAA-es.com) - :Table (network_objects) - :Uid ("{E5BF8260-3615-4476-B638-53CA3A24FEF1}") - ) - ) - :install ( - :AdminInfo ( - :chkpf_uid ("{E6AF42B5-C12E-4E59-8C3E-5D231C5B0D34}") - :ClassName (rule_install) - ) - :compound () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :services ( - :AdminInfo ( - :chkpf_uid ("{A22EE9B9-C603-4998-B273-1568DE4BB27A}") - :ClassName (rule_services) - ) - :compound () - :op () - : (ReferenceObject - :Name (ntp-udp) - :Table (services) - :Uid ("{97AEB404-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :src ( - :AdminInfo ( - :chkpf_uid ("{D0402416-F879-4AD4-88E6-A1DBFEA44546}") - :ClassName (rule_source) - ) - :compound () - :op () - : (ReferenceObject - :Name (IsoAAAA-100) - :Table (network_objects) - :Uid ("{BF1C6029-8D5D-4A05-A3AD-4B67E6E7A7AA}") - ) - ) - ) - :rule ( - :AdminInfo ( - :chkpf_uid ("{7C9A68ED-6420-4D5E-BE91-F7ACE4B90AA5}") - :ClassName (security_header_rule) - ) - :action ( - : (drop - :AdminInfo ( - :chkpf_uid ("{D4BF36D5-49FA-49BD-ADE1-87E488A684D6}") - :ClassName (drop_action) - :table (setup) - ) - :action () - :macro () - :type (drop) - ) - ) - :comments () - :global_location (middle) - :through ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :time ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :track ( - : (ReferenceObject - :Name (None) - :Table (tracks) - :Uid ("{97AEB47D-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :disabled (true) - :dst ( - :AdminInfo ( - :chkpf_uid ("{251B6C16-21CB-4CCE-9B3B-62B66C6F6390}") - :ClassName (rule_destination) - ) - :compound () - :op () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :header_text ("Intern to Internet") - :install ( - :AdminInfo ( - :chkpf_uid ("{A9221EAB-A00F-4E3F-83DF-D44CBC08AFBD}") - :ClassName (rule_install) - ) - :compound () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :services ( - :AdminInfo ( - :chkpf_uid ("{AECCDBA3-A006-464E-9BD9-691255CA5841}") - :ClassName (rule_services) - ) - :compound () - :op () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :src ( - :AdminInfo ( - :chkpf_uid ("{5B2CFCAD-0A44-4BA9-BFF7-6734B5644C85}") - :ClassName (rule_source) - ) - :compound () - :op () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :state (collapsed) - ) - :rule ( - :AdminInfo ( - :chkpf_uid ("{E6AB0ADC-7E23-4B1D-B568-E47FF7B3D4F5}") - :ClassName (security_rule) - ) - :action ( - : (accept - :AdminInfo ( - :chkpf_uid ("{5B685C0A-3095-483A-8DE1-F539677A7707}") - :ClassName (accept_action) - :table (setup) - ) - :action () - :macro (RECORD_CONN) - :type (accept) - ) - ) - :comments () - :disabled (false) - :global_location (middle) - :through ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :time ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :track ( - : (ReferenceObject - :Name (Log) - :Table (tracks) - :Uid ("{97AEB480-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :dst ( - :AdminInfo ( - :chkpf_uid ("{2C9F2F69-7532-4711-A950-C884E1AFD3F5}") - :ClassName (rule_destination) - ) - :compound () - :op () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :install ( - :AdminInfo ( - :chkpf_uid ("{EACA5120-76C3-48CE-AB41-59266A354E0A}") - :ClassName (rule_install) - ) - :compound () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :services ( - :AdminInfo ( - :chkpf_uid ("{DB45ABD4-20F0-4BC8-BD73-294945142FB8}") - :ClassName (rule_services) - ) - :compound () - :op () - : (ReferenceObject - :Name (T-online-classic) - :Table (services) - :Uid ("{738B04E5-09F7-44BF-9FEC-AEA0F15B7E9A}") - ) - : (ReferenceObject - :Name (HBCI) - :Table (services) - :Uid ("{336C93F8-5CC2-48BE-9328-2E92F61EFCF1}") - ) - ) - :src ( - :AdminInfo ( - :chkpf_uid ("{85CAFABE-730E-4DDB-A878-219BD2893B63}") - :ClassName (rule_source) - ) - :compound () - :op () - : (ReferenceObject - :Name (IsoAAAA-100) - :Table (network_objects) - :Uid ("{BF1C6029-8D5D-4A05-A3AD-4B67E6E7A7AA}") - ) - ) - ) - :rule ( - :AdminInfo ( - :chkpf_uid ("{F2D50B88-90A6-4BF1-A0F9-724F4FF20600}") - :ClassName (security_rule) - ) - :action ( - : ("Client Auth" - :AdminInfo ( - :chkpf_uid ("{E7112614-F673-492F-B41A-FA577FB7E844}") - :ClassName (client_authenticate) - :table (setup) - ) - :accept_track (ReferenceObject - :Name (Auth) - :Table (tracks) - :Uid ("{97AEB48A-9AEA-11D5-BD16-0090272CCB30}") - ) - :action (accept) - :clauth_refreshable (false) - :clauth_to_hours (6) - :clauth_to_infinite (false) - :clauth_to_minutes (30) - :clauth_track (ReferenceObject - :Table (tracks) - :Name (Auth) - :Uid ("{97AEB48A-9AEA-11D5-BD16-0090272CCB30}") - ) - :dst_options ("ignore user database") - :enforce_desktop_config (false) - :macro (PASS_CLNTAUTH) - :ruletype ("standard sign on") - :sessions (5) - :sessions_infinite (true) - :signon_method ("manual sign-on") - :src_options ("intersect with user database") - :type (auth_client) - ) - ) - :comments () - :disabled (false) - :global_location (middle) - :through ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :time ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :track ( - : (ReferenceObject - :Name (Log) - :Table (tracks) - :Uid ("{97AEB480-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :dst ( - :AdminInfo ( - :chkpf_uid ("{D9DB10FC-4DA0-4922-B0B0-5F8C87FE0135}") - :ClassName (rule_destination) - ) - :compound () - :op () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :install ( - :AdminInfo ( - :chkpf_uid ("{62EE86DF-01FC-4628-8A25-70D69D61F7A9}") - :ClassName (rule_install) - ) - :compound () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :services ( - :AdminInfo ( - :chkpf_uid ("{4C8E3C25-1695-4552-858C-90BA25E860CC}") - :ClassName (rule_services) - ) - :compound () - :op () - : (ReferenceObject - :Name (ssh_version_2) - :Table (services) - :Uid ("{CD082D9A-44A6-4CEF-A17D-5541029ADFB3}") - ) - : (ReferenceObject - :Name (TeamSpeak) - :Table (services) - :Uid ("{D2BBEFB3-8450-4301-9040-2D305887A748}") - ) - ) - :src ( - :AdminInfo ( - :chkpf_uid ("{7049EFF1-4FF7-42B0-B5EE-8F44579C07CB}") - :ClassName (rule_source) - ) - :compound ( - : (Cactus-extern@IsoAAAA-100 - :AdminInfo ( - :chkpf_uid ("{A376F981-E37A-4611-B925-1A141DC89FD8}") - :ClassName (rule_user_group) - ) - :at (ReferenceObject - :Name (IsoAAAA-100) - :Table (network_objects) - :Uid ("{BF1C6029-8D5D-4A05-A3AD-4B67E6E7A7AA}") - ) - :color (black) - :type (usrgroup) - ) - ) - :op () - ) - ) - :rule ( - :AdminInfo ( - :chkpf_uid ("{1F4E5C97-C290-48AF-84A5-C1A13178FDB7}") - :ClassName (security_rule) - ) - :action ( - : (accept - :AdminInfo ( - :chkpf_uid ("{DCDCFD96-219D-49B7-B817-8BB52C598AB8}") - :ClassName (accept_action) - :table (setup) - ) - :action () - :macro (RECORD_CONN) - :type (accept) - ) - ) - :comments () - :disabled (false) - :global_location (middle) - :through ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :time ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :track ( - : (ReferenceObject - :Name (Log) - :Table (tracks) - :Uid ("{97AEB480-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :dst ( - :AdminInfo ( - :chkpf_uid ("{3A1A50EC-0F20-4C79-80D7-FDCBEDAF50AF}") - :ClassName (rule_destination) - ) - :compound () - :op () - : (ReferenceObject - :Name (t-onlineUpdate) - :Table (network_objects) - :Uid ("{99089D97-0EB3-4CE6-8C78-79BC61ECE307}") - ) - ) - :install ( - :AdminInfo ( - :chkpf_uid ("{4D0B21D7-8DA0-49D5-9AD2-3F7BBA001C56}") - :ClassName (rule_install) - ) - :compound () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :services ( - :AdminInfo ( - :chkpf_uid ("{0C60636A-9D3B-44D2-9742-966C92ED77A2}") - :ClassName (rule_services) - ) - :compound () - :op () - : (ReferenceObject - :Name (http) - :Table (services) - :Uid ("{97AEB3D4-9AEA-11D5-BD16-0090272CCB30}") - ) - : (ReferenceObject - :Name (https) - :Table (services) - :Uid ("{97AEB443-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :src ( - :AdminInfo ( - :chkpf_uid ("{C9F5FA9C-6AE5-4A04-B68F-E3CFBE3C1043}") - :ClassName (rule_source) - ) - :compound () - :op () - : (ReferenceObject - :Name (IsoAAAA-100) - :Table (network_objects) - :Uid ("{BF1C6029-8D5D-4A05-A3AD-4B67E6E7A7AA}") - ) - ) - ) - :rule ( - :AdminInfo ( - :chkpf_uid ("{8D43F752-841E-4B9E-B610-635F7C17D4D9}") - :ClassName (security_rule) - ) - :action ( - : (accept - :AdminInfo ( - :chkpf_uid ("{7A10F249-7751-407A-A390-A6B878A85D56}") - :ClassName (accept_action) - :table (setup) - ) - :action () - :macro (RECORD_CONN) - :type (accept) - ) - ) - :comments () - :disabled (false) - :global_location (middle) - :through ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :time ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :track ( - : (ReferenceObject - :Name (Log) - :Table (tracks) - :Uid ("{97AEB480-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :dst ( - :AdminInfo ( - :chkpf_uid ("{B42E38C5-299A-4B0E-A7BE-6D87D1206A3C}") - :ClassName (rule_destination) - ) - :compound () - :op () - : (ReferenceObject - :Name (auth1.lhsystems.com) - :Table (network_objects) - :Uid ("{D60E902E-4BE8-43E0-95DC-BFE60E86965F}") - ) - : (ReferenceObject - :Name (LSYI-pptp) - :Table (network_objects) - :Uid ("{DF2F1A45-9938-4006-A550-0421F3DAA3E2}") - ) - ) - :install ( - :AdminInfo ( - :chkpf_uid ("{42DAAE37-A625-47E5-AC05-72E3E3A9F3FE}") - :ClassName (rule_install) - ) - :compound () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :services ( - :AdminInfo ( - :chkpf_uid ("{F8D3DE95-02BB-43E8-B759-01E5AE00233C}") - :ClassName (rule_services) - ) - :compound () - :op () - : (ReferenceObject - :Name (FW1_clntauth_telnet) - :Table (services) - :Uid ("{97AEB38B-9AEA-11D5-BD16-0090272CCB30}") - ) - : (ReferenceObject - :Name (PPTP) - :Table (services) - :Uid ("{97AEB426-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :src ( - :AdminInfo ( - :chkpf_uid ("{B2C3E31C-B79E-49A9-B7A8-2F38E3C21DCF}") - :ClassName (rule_source) - ) - :compound () - :op () - : (ReferenceObject - :Name (IsoAAAA-100) - :Table (network_objects) - :Uid ("{BF1C6029-8D5D-4A05-A3AD-4B67E6E7A7AA}") - ) - ) - ) - :rule ( - :AdminInfo ( - :chkpf_uid ("{167BC623-43EB-405D-BC29-442298C96DC9}") - :ClassName (security_rule) - ) - :action ( - : (accept - :AdminInfo ( - :chkpf_uid ("{BB10481F-21F5-4244-A6BB-29318E780DF1}") - :ClassName (accept_action) - :table (setup) - ) - :action () - :macro (RECORD_CONN) - :type (accept) - ) - ) - :comments () - :disabled (false) - :global_location (middle) - :through ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :time ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :track ( - : (ReferenceObject - :Name (Log) - :Table (tracks) - :Uid ("{97AEB480-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :dst ( - :AdminInfo ( - :chkpf_uid ("{E9BE5C8E-9CAE-4D88-9235-F5AC9030CF0F}") - :ClassName (rule_destination) - ) - :compound () - :op () - : (ReferenceObject - :Name (mail.light-life.netOld) - :Table (network_objects) - :Uid ("{DF004F13-7986-4569-811C-6EC7391A8764}") - ) - : (ReferenceObject - :Name (mail.light-life.net) - :Table (network_objects) - :Uid ("{C534904C-317E-431D-BF6C-03977CC08203}") - ) - ) - :install ( - :AdminInfo ( - :chkpf_uid ("{CDBC19FF-C00F-4304-9D1D-B5BBDAA5D15A}") - :ClassName (rule_install) - ) - :compound () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :services ( - :AdminInfo ( - :chkpf_uid ("{4BE203D0-3DE8-44FE-B942-E5E26C62E861}") - :ClassName (rule_services) - ) - :compound () - :op () - : (ReferenceObject - :Name (smtp) - :Table (services) - :Uid ("{97AEB3D9-9AEA-11D5-BD16-0090272CCB30}") - ) - : (ReferenceObject - :Name (pop-3) - :Table (services) - :Uid ("{97AEB3DB-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :src ( - :AdminInfo ( - :chkpf_uid ("{C3E9CE29-9F23-4857-B88F-E9949FAF2D5D}") - :ClassName (rule_source) - ) - :compound () - :op () - : (ReferenceObject - :Name (speedy2) - :Table (network_objects) - :Uid ("{B4DB2EF5-42D8-41DC-9A1C-33310FDFB184}") - ) - ) - ) - :rule ( - :AdminInfo ( - :chkpf_uid ("{11C81B0A-4266-4801-8858-E4D9AB54A830}") - :ClassName (security_header_rule) - ) - :action ( - : (drop - :AdminInfo ( - :chkpf_uid ("{5E568AEF-0F52-4A93-AFA3-18E73A0D066A}") - :ClassName (drop_action) - :table (setup) - ) - :action () - :macro () - :type (drop) - ) - ) - :comments () - :global_location (middle) - :through ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :time ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :track ( - : (ReferenceObject - :Name (None) - :Table (tracks) - :Uid ("{97AEB47D-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :disabled (true) - :dst ( - :AdminInfo ( - :chkpf_uid ("{366C4CAD-81FB-4025-8D13-601F4A6C8FF7}") - :ClassName (rule_destination) - ) - :compound () - :op () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :header_text ("Access from Spike & DMZ to Internal") - :install ( - :AdminInfo ( - :chkpf_uid ("{47C0018E-3514-4540-A4EA-659755890D6B}") - :ClassName (rule_install) - ) - :compound () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :services ( - :AdminInfo ( - :chkpf_uid ("{0073E27C-28E5-4EC1-9A4A-BD686F700281}") - :ClassName (rule_services) - ) - :compound () - :op () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :src ( - :AdminInfo ( - :chkpf_uid ("{BD3EBBCD-06DF-4313-A347-7097F5105671}") - :ClassName (rule_source) - ) - :compound () - :op () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :state (collapsed) - ) - :rule ( - :AdminInfo ( - :chkpf_uid ("{A8A57015-68D5-4341-ADD1-895EC21419DB}") - :ClassName (security_rule) - ) - :action ( - : (accept - :AdminInfo ( - :chkpf_uid ("{BECC33F6-C362-41A4-BBD3-CBFA34A7C4E8}") - :ClassName (accept_action) - :table (setup) - ) - :action () - :macro (RECORD_CONN) - :type (accept) - ) - ) - :comments () - :disabled (false) - :global_location (middle) - :through ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :time ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :track ( - : (ReferenceObject - :Name (Log) - :Table (tracks) - :Uid ("{97AEB480-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :dst ( - :AdminInfo ( - :chkpf_uid ("{193E4DB4-BE9D-4444-BC95-C04C10D26D25}") - :ClassName (rule_destination) - ) - :compound () - :op () - : (ReferenceObject - :Name (IsoAAADray.local) - :Table (network_objects) - :Uid ("{75EDBC62-7EB1-4D37-8295-684903FDA75A}") - ) - : (ReferenceObject - :Name (gateway.local) - :Table (network_objects) - :Uid ("{7ED7EF12-A13E-4303-8A6E-C6CC28755C80}") - ) - ) - :install ( - :AdminInfo ( - :chkpf_uid ("{42CD50F6-AA17-4271-B684-DFF6E86E5649}") - :ClassName (rule_install) - ) - :compound () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :services ( - :AdminInfo ( - :chkpf_uid ("{0B65BDFF-A77E-498D-8F6D-8B77068701D6}") - :ClassName (rule_services) - ) - :compound () - :op () - : (ReferenceObject - :Name (rdp) - :Table (services) - :Uid ("{5BA0C83F-8D91-465B-9CF6-7DC6AEB84689}") - ) - : (ReferenceObject - :Name (http) - :Table (services) - :Uid ("{97AEB3D4-9AEA-11D5-BD16-0090272CCB30}") - ) - : (ReferenceObject - :Name (CIFS) - :Table (services) - :Uid ("{2A469820-B502-434C-9340-A377677A6A60}") - ) - : (ReferenceObject - :Name (UPS-Monitor) - :Table (services) - :Uid ("{8C8DED7E-F3C9-4964-B9D3-063C23997020}") - ) - ) - :src ( - :AdminInfo ( - :chkpf_uid ("{5C3E75D6-41C1-4D28-A34C-D9F0C316599F}") - :ClassName (rule_source) - ) - :compound () - :op () - : (ReferenceObject - :Name (mg.IsoAAAA-es.com) - :Table (network_objects) - :Uid ("{E5BF8260-3615-4476-B638-53CA3A24FEF1}") - ) - ) - ) - :rule ( - :AdminInfo ( - :chkpf_uid ("{5DEBDFAA-F691-4041-8E3A-EAF002F8B690}") - :ClassName (security_rule) - ) - :action ( - : (accept - :AdminInfo ( - :chkpf_uid ("{69531784-EAAE-4C1C-B792-86B14F8D015E}") - :ClassName (accept_action) - :table (setup) - ) - :action () - :macro (RECORD_CONN) - :type (accept) - ) - ) - :comments () - :disabled (false) - :global_location (middle) - :through ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :time ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :track ( - : (ReferenceObject - :Name (Log) - :Table (tracks) - :Uid ("{97AEB480-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :dst ( - :AdminInfo ( - :chkpf_uid ("{FA61FCF6-FF1E-42C6-B329-B8E23A0EB35D}") - :ClassName (rule_destination) - ) - :compound () - :op () - : (ReferenceObject - :Name (scratchy.local) - :Table (network_objects) - :Uid ("{CFABE50C-C1F6-4FF1-8AC3-3161A3779708}") - ) - ) - :install ( - :AdminInfo ( - :chkpf_uid ("{21457A88-FFC3-45C2-A6AD-7ABC8CDD0232}") - :ClassName (rule_install) - ) - :compound () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :services ( - :AdminInfo ( - :chkpf_uid ("{7990665E-448A-420C-BF7D-3616ED9ECB53}") - :ClassName (rule_services) - ) - :compound () - :op () - : (ReferenceObject - :Name (RAdmin-custom) - :Table (services) - :Uid ("{4FB59153-8212-4A12-BC08-0297AA5F0815}") - ) - ) - :src ( - :AdminInfo ( - :chkpf_uid ("{7A4BC3A5-EAB4-4CC3-8F06-5B3681A6A814}") - :ClassName (rule_source) - ) - :compound () - :op () - : (ReferenceObject - :Name (mg.IsoAAAA-es.com) - :Table (network_objects) - :Uid ("{E5BF8260-3615-4476-B638-53CA3A24FEF1}") - ) - ) - ) - :rule ( - :AdminInfo ( - :chkpf_uid ("{DC9D47B1-CEB2-43AB-B32E-5BFACD49181F}") - :ClassName (security_rule) - ) - :action ( - : (accept - :AdminInfo ( - :chkpf_uid ("{841A245A-0BBC-40D6-AFCD-FC0956945DFB}") - :ClassName (accept_action) - :table (setup) - ) - :action () - :macro (RECORD_CONN) - :type (accept) - ) - ) - :comments () - :disabled (false) - :global_location (middle) - :through ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :time ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :track ( - : (ReferenceObject - :Name (Log) - :Table (tracks) - :Uid ("{97AEB480-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :dst ( - :AdminInfo ( - :chkpf_uid ("{940B351D-CBB3-457B-AA5E-BF8EE4721229}") - :ClassName (rule_destination) - ) - :compound () - :op () - : (ReferenceObject - :Name (daba) - :Table (network_objects) - :Uid ("{94817CDB-EA8C-4213-B38D-F4417EA620C6}") - ) - ) - :install ( - :AdminInfo ( - :chkpf_uid ("{6F3DCA16-ECC8-4DAE-8729-3D07CD35A492}") - :ClassName (rule_install) - ) - :compound () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :services ( - :AdminInfo ( - :chkpf_uid ("{6A906112-E832-480B-98E6-7C88D5768449}") - :ClassName (rule_services) - ) - :compound () - :op () - : (ReferenceObject - :Name (mysql) - :Table (services) - :Uid ("{08A07607-EAAA-4A45-AD6E-6020770BD519}") - ) - : (ReferenceObject - :Name (ssh_version_2) - :Table (services) - :Uid ("{CD082D9A-44A6-4CEF-A17D-5541029ADFB3}") - ) - ) - :src ( - :AdminInfo ( - :chkpf_uid ("{124122B3-1A04-4980-AA2E-18B01C4BA2A1}") - :ClassName (rule_source) - ) - :compound () - :op () - : (ReferenceObject - :Name (mg.IsoAAAA-es.com) - :Table (network_objects) - :Uid ("{E5BF8260-3615-4476-B638-53CA3A24FEF1}") - ) - ) - ) - :rule ( - :AdminInfo ( - :chkpf_uid ("{B706F7FA-C0AA-41E6-9BE1-99FAA2073339}") - :ClassName (security_rule) - ) - :action ( - : (accept - :AdminInfo ( - :chkpf_uid ("{23C4BFFE-0F58-4C89-9AC6-EE8475E30FB2}") - :ClassName (accept_action) - :table (setup) - ) - :action () - :macro (RECORD_CONN) - :type (accept) - ) - ) - :comments () - :disabled (false) - :global_location (middle) - :through ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :time ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :track ( - : (ReferenceObject - :Name (Log) - :Table (tracks) - :Uid ("{97AEB480-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :dst ( - :AdminInfo ( - :chkpf_uid ("{3DEE2329-18AC-4C21-95A5-49D3F42BC058}") - :ClassName (rule_destination) - ) - :compound () - :op () - : (ReferenceObject - :Name (hpux) - :Table (network_objects) - :Uid ("{BF00A847-A0D6-4A75-BE1C-27E7D91EDB55}") - ) - ) - :install ( - :AdminInfo ( - :chkpf_uid ("{31E7DAD2-17B6-484F-87B3-A9817437F6C3}") - :ClassName (rule_install) - ) - :compound () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :services ( - :AdminInfo ( - :chkpf_uid ("{645119AD-FF40-4617-BB77-CE2B7679B804}") - :ClassName (rule_services) - ) - :compound () - :op () - : (ReferenceObject - :Name (telnet) - :Table (services) - :Uid ("{97AEB3CF-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :src ( - :AdminInfo ( - :chkpf_uid ("{A15D212E-0F94-4C31-82C3-83292476F567}") - :ClassName (rule_source) - ) - :compound () - :op () - : (ReferenceObject - :Name (mg.IsoAAAA-es.com) - :Table (network_objects) - :Uid ("{E5BF8260-3615-4476-B638-53CA3A24FEF1}") - ) - ) - ) - :rule ( - :AdminInfo ( - :chkpf_uid ("{FFAB5EA6-1C92-49CA-B971-6739815B346B}") - :ClassName (security_rule) - ) - :action ( - : (accept - :AdminInfo ( - :chkpf_uid ("{45995732-1869-4EBC-A799-5684F4266AF3}") - :ClassName (accept_action) - :table (setup) - ) - :action () - :macro (RECORD_CONN) - :type (accept) - ) - ) - :comments () - :disabled (false) - :global_location (middle) - :through ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :time ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :track ( - : (ReferenceObject - :Name (Log) - :Table (tracks) - :Uid ("{97AEB480-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :dst ( - :AdminInfo ( - :chkpf_uid ("{9C8B3BB2-5681-413A-855A-C8409935AA08}") - :ClassName (rule_destination) - ) - :compound () - :op () - : (ReferenceObject - :Name (SecOVID_Authserver) - :Table (network_objects) - :Uid ("{DB220C3D-763C-46AB-A7D1-1F9C7C45910E}") - ) - ) - :install ( - :AdminInfo ( - :chkpf_uid ("{121D0209-7E3D-40C0-AFD1-E5F45BC9728E}") - :ClassName (rule_install) - ) - :compound () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :services ( - :AdminInfo ( - :chkpf_uid ("{2EFB1265-AB14-401F-8157-1F4FD814C850}") - :ClassName (rule_services) - ) - :compound () - :op () - : (ReferenceObject - :Name (NEW-RADIUS) - :Table (services) - :Uid ("{97AEB41E-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :src ( - :AdminInfo ( - :chkpf_uid ("{6CA9E964-C64D-470B-B2F5-C8D9481E1309}") - :ClassName (rule_source) - ) - :compound () - :op () - : (ReferenceObject - :Name (mg.IsoAAAA-es.com) - :Table (network_objects) - :Uid ("{E5BF8260-3615-4476-B638-53CA3A24FEF1}") - ) - : (ReferenceObject - :Name (ITSecOrg-dev) - :Table (network_objects) - :Uid ("{18122B8C-51F8-4102-B143-72DA4E57367D}") - ) - ) - ) - :rule ( - :AdminInfo ( - :chkpf_uid ("{2B48CB5C-959B-4212-83BA-D0C31C9E81FD}") - :ClassName (security_rule) - ) - :action ( - : (accept - :AdminInfo ( - :chkpf_uid ("{23DAD50B-1BFA-4B5A-BD07-91F594590169}") - :ClassName (accept_action) - :table (setup) - ) - :action () - :macro (RECORD_CONN) - :type (accept) - ) - ) - :disabled (false) - :global_location (middle) - :through ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :time ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :track ( - : (ReferenceObject - :Name (Log) - :Table (tracks) - :Uid ("{97AEB480-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :comments ("SUS-Access 4 Stichling") - :dst ( - :AdminInfo ( - :chkpf_uid ("{401D98F2-0790-42A8-A27B-4CEF1B409D62}") - :ClassName (rule_destination) - ) - :compound () - :op () - : (ReferenceObject - :Name (IsoAAADray.local) - :Table (network_objects) - :Uid ("{75EDBC62-7EB1-4D37-8295-684903FDA75A}") - ) - ) - :install ( - :AdminInfo ( - :chkpf_uid ("{C607E30B-AD42-4EB9-861C-3E1F17B01A58}") - :ClassName (rule_install) - ) - :compound () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :services ( - :AdminInfo ( - :chkpf_uid ("{F70D3F8A-F47F-4E46-AC7C-6439659AD77F}") - :ClassName (rule_services) - ) - :compound () - :op () - : (ReferenceObject - :Name (http) - :Table (services) - :Uid ("{97AEB3D4-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :src ( - :AdminInfo ( - :chkpf_uid ("{66A8B48D-384B-47C2-AE14-EFA8C5BD981F}") - :ClassName (rule_source) - ) - :compound () - :op () - : (ReferenceObject - :Name (Cactus10.222.0.1) - :Table (network_objects) - :Uid ("{6CD51061-638B-4B2F-9092-7E1E4A5F0ADD}") - ) - ) - ) - :rule ( - :AdminInfo ( - :chkpf_uid ("{A4D7B2E7-4461-41FD-BBFB-F7A4738CE081}") - :ClassName (security_rule) - ) - :action ( - : (accept - :AdminInfo ( - :chkpf_uid ("{7BE16ABA-CEF4-4B95-9BC0-8753FE0D3DC5}") - :ClassName (accept_action) - :table (setup) - ) - :action () - :macro (RECORD_CONN) - :type (accept) - ) - ) - :disabled (false) - :global_location (middle) - :through ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :time ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :track ( - : (ReferenceObject - :Name (Log) - :Table (tracks) - :Uid ("{97AEB480-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :comments (WLAN-DNS) - :dst ( - :AdminInfo ( - :chkpf_uid ("{7E03AA57-58BE-42C9-8861-8395F9879960}") - :ClassName (rule_destination) - ) - :compound () - :op () - : (ReferenceObject - :Name (IsoAAADray.local) - :Table (network_objects) - :Uid ("{75EDBC62-7EB1-4D37-8295-684903FDA75A}") - ) - ) - :install ( - :AdminInfo ( - :chkpf_uid ("{BC2EEAE6-2829-44CE-99E2-1A86D9EBCE52}") - :ClassName (rule_install) - ) - :compound () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :services ( - :AdminInfo ( - :chkpf_uid ("{A109C25F-2754-404D-966B-FA7DB64E670C}") - :ClassName (rule_services) - ) - :compound () - :op () - : (ReferenceObject - :Name (domain-udp) - :Table (services) - :Uid ("{97AEB3FA-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :src ( - :AdminInfo ( - :chkpf_uid ("{612801AE-42D3-4B29-9305-AE3BC60D7C1E}") - :ClassName (rule_source) - ) - :compound () - :op () - : (ReferenceObject - :Name (wlan-router) - :Table (network_objects) - :Uid ("{426CC3AD-BE7D-45B6-AAAB-22BA0680EE21}") - ) - ) - ) - :rule ( - :AdminInfo ( - :chkpf_uid ("{B63983F0-BF08-44F7-88EA-5DF0FA381C45}") - :ClassName (security_header_rule) - ) - :action ( - : (drop - :AdminInfo ( - :chkpf_uid ("{D47409A0-8070-4258-802B-E234DE03D219}") - :ClassName (drop_action) - :table (setup) - ) - :action () - :macro () - :type (drop) - ) - ) - :comments () - :global_location (middle) - :through ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :time ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :track ( - : (ReferenceObject - :Name (None) - :Table (tracks) - :Uid ("{97AEB47D-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :disabled (true) - :dst ( - :AdminInfo ( - :chkpf_uid ("{34E31CD9-5F62-46B6-A5A2-2A25A3381BFF}") - :ClassName (rule_destination) - ) - :compound () - :op () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :header_text (Final-rules) - :install ( - :AdminInfo ( - :chkpf_uid ("{97A07F1F-7C42-469E-8976-4694BEA0C05F}") - :ClassName (rule_install) - ) - :compound () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :services ( - :AdminInfo ( - :chkpf_uid ("{AE52657F-1C63-427D-899A-2739B143874D}") - :ClassName (rule_services) - ) - :compound () - :op () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :src ( - :AdminInfo ( - :chkpf_uid ("{7D15F5BF-41C8-4674-A2A5-96AC297EB840}") - :ClassName (rule_source) - ) - :compound () - :op () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :state (collapsed) - ) - :rule ( - :AdminInfo ( - :chkpf_uid ("{E079D5BF-271E-4004-B4C5-8372C37B4661}") - :ClassName (security_rule) - ) - :action ( - : (accept - :AdminInfo ( - :chkpf_uid ("{EBF89D8A-D923-4469-9179-4209815688BC}") - :ClassName (accept_action) - :table (setup) - ) - :action () - :macro (RECORD_CONN) - :type (accept) - ) - ) - :comments () - :disabled (false) - :global_location (middle) - :through ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :time ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :track ( - : (ReferenceObject - :Name (Log) - :Table (tracks) - :Uid ("{97AEB480-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :dst ( - :AdminInfo ( - :chkpf_uid ("{93E9E478-F918-450E-8D36-280C86415DB8}") - :ClassName (rule_destination) - ) - :compound () - :op () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :install ( - :AdminInfo ( - :chkpf_uid ("{F546BB1C-8E90-4AEA-9C17-188FDA697E98}") - :ClassName (rule_install) - ) - :compound () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :services ( - :AdminInfo ( - :chkpf_uid ("{5576A25C-181D-40DB-8978-F8E8B6D19C4E}") - :ClassName (rule_services) - ) - :compound () - :op () - : (ReferenceObject - :Name (ICMPgute) - :Table (services) - :Uid ("{418C7C0A-956A-41FF-9BC1-5867B2265090}") - ) - ) - :src ( - :AdminInfo ( - :chkpf_uid ("{4B989FE8-BC56-4B8C-BD37-C6050AAC2B28}") - :ClassName (rule_source) - ) - :compound () - :op () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - ) - :rule ( - :AdminInfo ( - :chkpf_uid ("{89F7C56B-1A5F-4C4A-BC98-F777664BBEC9}") - :ClassName (security_rule) - ) - :action ( - : (accept - :AdminInfo ( - :chkpf_uid ("{BD3A43B7-179B-4A44-9E8E-BDA3C4D74428}") - :ClassName (accept_action) - :table (setup) - ) - :action () - :macro (RECORD_CONN) - :type (accept) - ) - ) - :comments () - :disabled (false) - :global_location (middle) - :through ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :time ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :track ( - : (ReferenceObject - :Name (Log) - :Table (tracks) - :Uid ("{97AEB480-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :dst ( - :AdminInfo ( - :chkpf_uid ("{787E51C4-3375-4608-A83C-CFF3D08628B5}") - :ClassName (rule_destination) - ) - :compound () - :op () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :install ( - :AdminInfo ( - :chkpf_uid ("{C67E7D9D-F7A6-4B80-AB31-589BDF22583D}") - :ClassName (rule_install) - ) - :compound () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :services ( - :AdminInfo ( - :chkpf_uid ("{E732300C-E9E8-4CC7-B0B1-1566947A92A0}") - :ClassName (rule_services) - ) - :compound () - :op () - : (ReferenceObject - :Name (redirect) - :Table (services) - :Uid ("{97AEB409-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :src ( - :AdminInfo ( - :chkpf_uid ("{DB1AE486-D8A3-44F0-AA73-AE22B0BA4A32}") - :ClassName (rule_source) - ) - :compound () - :op () - : (ReferenceObject - :Name (IsoAAAD) - :Table (network_objects) - :Uid ("{29C40B0A-414C-11D7-AEB8-7F0000013C3C}") - ) - ) - ) - :rule ( - :AdminInfo ( - :chkpf_uid ("{F134ED1C-8FC1-4ED1-9751-39EE88C79BAA}") - :ClassName (security_rule) - ) - :action ( - : (reject - :AdminInfo ( - :chkpf_uid ("{619449DF-3B19-42EF-A640-40BF30E1E398}") - :ClassName (reject_action) - :table (setup) - ) - :action () - :macro () - :type (reject) - ) - ) - :comments () - :disabled (false) - :global_location (middle) - :through ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :time ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :track ( - : (ReferenceObject - :Name (None) - :Table (tracks) - :Uid ("{97AEB47D-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :dst ( - :AdminInfo ( - :chkpf_uid ("{F3772580-72F8-47FD-BEEF-64F0C4AE29AC}") - :ClassName (rule_destination) - ) - :compound () - :op () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :install ( - :AdminInfo ( - :chkpf_uid ("{FF327589-E587-4324-B33B-EAEA6BF3D977}") - :ClassName (rule_install) - ) - :compound () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :services ( - :AdminInfo ( - :chkpf_uid ("{367A55E3-5596-40A1-A0C9-63CEA70F42C3}") - :ClassName (rule_services) - ) - :compound () - :op () - : (ReferenceObject - :Name (Drop_nologServices) - :Table (services) - :Uid ("{495E1A16-2612-49D9-8F69-B00EB33699E8}") - ) - ) - :src ( - :AdminInfo ( - :chkpf_uid ("{AFD6C077-CA8E-4C7D-A834-F781B7821B96}") - :ClassName (rule_source) - ) - :compound () - :op () - : (ReferenceObject - :Name (IsoAAAA-100) - :Table (network_objects) - :Uid ("{BF1C6029-8D5D-4A05-A3AD-4B67E6E7A7AA}") - ) - ) - ) - :rule ( - :AdminInfo ( - :chkpf_uid ("{7067EE72-61D1-4555-9832-8E9279772BCA}") - :ClassName (security_rule) - ) - :action ( - : (reject - :AdminInfo ( - :chkpf_uid ("{D06A4524-1DCA-4DD5-BCC2-54EE451C1777}") - :ClassName (reject_action) - :table (setup) - ) - :action () - :macro () - :type (reject) - ) - ) - :comments () - :disabled (false) - :global_location (middle) - :through ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :time ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :track ( - : (ReferenceObject - :Name (None) - :Table (tracks) - :Uid ("{97AEB47D-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :dst ( - :AdminInfo ( - :chkpf_uid ("{FFD672A3-65E6-4B19-B686-D40AC4299BCD}") - :ClassName (rule_destination) - ) - :compound () - :op () - : (ReferenceObject - :Name (Drop_nologDest) - :Table (network_objects) - :Uid ("{79369987-B128-4B3F-827C-3C936F7C3F53}") - ) - ) - :install ( - :AdminInfo ( - :chkpf_uid ("{0581A769-6452-42CD-9718-F226767D0287}") - :ClassName (rule_install) - ) - :compound () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :services ( - :AdminInfo ( - :chkpf_uid ("{F037BEDF-CC8F-4792-9A21-103C9F5C2A51}") - :ClassName (rule_services) - ) - :compound () - :op () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :src ( - :AdminInfo ( - :chkpf_uid ("{7B4EF795-BE09-45A2-86B9-1CE030756ECB}") - :ClassName (rule_source) - ) - :compound () - :op () - : (ReferenceObject - :Name (IsoAAAA-100) - :Table (network_objects) - :Uid ("{BF1C6029-8D5D-4A05-A3AD-4B67E6E7A7AA}") - ) - ) - ) - :rule ( - :AdminInfo ( - :chkpf_uid ("{A6F53BCD-748C-4585-B8FB-1DF23129F085}") - :ClassName (security_rule) - ) - :action ( - : (reject - :AdminInfo ( - :chkpf_uid ("{4F089C9B-C148-4A8A-8ED5-38618067B567}") - :ClassName (reject_action) - :table (setup) - ) - :action () - :macro () - :type (reject) - ) - ) - :comments () - :disabled (false) - :global_location (middle) - :through ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :time ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :track ( - : (ReferenceObject - :Name (Log) - :Table (tracks) - :Uid ("{97AEB480-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :dst ( - :AdminInfo ( - :chkpf_uid ("{34CE5F02-44F0-4180-BE48-5CB31E82D728}") - :ClassName (rule_destination) - ) - :compound () - :op () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :install ( - :AdminInfo ( - :chkpf_uid ("{7AD6114F-E8FF-4AE9-BAA8-6B72CA08F552}") - :ClassName (rule_install) - ) - :compound () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :services ( - :AdminInfo ( - :chkpf_uid ("{33DEA2EB-F713-400E-96E1-AACE576E28AB}") - :ClassName (rule_services) - ) - :compound () - :op () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :src ( - :AdminInfo ( - :chkpf_uid ("{4F305BBD-E049-4054-BCEC-A0D4F832CD80}") - :ClassName (rule_source) - ) - :compound () - :op () - : (ReferenceObject - :Name (CactusDA) - :Table (network_objects) - :Uid ("{69DBB75C-7E6D-49AD-A814-96F1BAFF12F7}") - ) - ) - ) - :rule ( - :AdminInfo ( - :chkpf_uid ("{9CD8CE05-32DB-483A-A44A-0C9131CCA022}") - :ClassName (security_rule) - ) - :action ( - : (drop - :AdminInfo ( - :chkpf_uid ("{ED025D2F-5D51-4310-AEF3-67A075F171EB}") - :ClassName (drop_action) - :table (setup) - ) - :action () - :macro () - :type (drop) - ) - ) - :comments () - :disabled (false) - :global_location (middle) - :through ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :time ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :track ( - : (ReferenceObject - :Name (Log) - :Table (tracks) - :Uid ("{97AEB480-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :dst ( - :AdminInfo ( - :chkpf_uid ("{92629D3F-DD0B-4864-A91A-9809A211E481}") - :ClassName (rule_destination) - ) - :compound () - :op () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :install ( - :AdminInfo ( - :chkpf_uid ("{92064B95-86EE-43B6-9410-C38676F3D964}") - :ClassName (rule_install) - ) - :compound () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :services ( - :AdminInfo ( - :chkpf_uid ("{C0176725-D8C5-412D-A5C3-65BA48662B1D}") - :ClassName (rule_services) - ) - :compound () - :op () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :src ( - :AdminInfo ( - :chkpf_uid ("{FB79D7A9-F91C-40F7-8DA7-303B39A7DC33}") - :ClassName (rule_source) - ) - :compound () - :op () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - ) - :rule_adtr ( - :AdminInfo ( - :chkpf_uid ("{795A2E9C-E2BD-4674-AB77-023F50036168}") - :ClassName (address_translation_rule) - ) - :comments () - :dst_adtr ( - : (ReferenceObject - :Name (IsoAAAA-100) - :Table (network_objects) - :Uid ("{BF1C6029-8D5D-4A05-A3AD-4B67E6E7A7AA}") - ) - ) - :global_location (middle) - :install ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :rule_block_number (1) - :services_adtr ( - : (ReferenceObject - :Name (CIFS) - :Table (services) - :Uid ("{2A469820-B502-434C-9340-A377677A6A60}") - ) - ) - :src_adtr ( - : (ReferenceObject - :Name (IsoAAAA_home_test_3) - :Table (network_objects) - :Uid ("{3B37A3DE-4411-4FFC-9E54-3ABC5C4F693B}") - ) - ) - :disabled (true) - :dst_adtr_translated ( - :AdminInfo ( - :chkpf_uid ("{A735AA42-250D-4EA5-B52A-05685A6124C3}") - :ClassName (translate_static) - ) - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - :adtr_method (adtr_method_static) - ) - :services_adtr_translated ( - :AdminInfo ( - :chkpf_uid ("{12B449F6-1F99-4060-BCB0-4A9DB5B463B3}") - :ClassName (service_translate) - ) - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - :adtr_method (adtr_method_static) - ) - :src_adtr_translated ( - :AdminInfo ( - :chkpf_uid ("{55591259-4F5C-498E-BF64-59C9C7E941A1}") - :ClassName (translate_static) - ) - : (ReferenceObject - :Name (Cactus_home_test_2) - :Table (network_objects) - :Uid ("{3CB93962-2930-41A7-8067-FC373151BB91}") - ) - :adtr_method (adtr_method_static) - ) - ) - :rule_adtr ( - :AdminInfo ( - :chkpf_uid ("{BBC0B2D9-0852-4DE8-AFB2-C27B6049C3AE}") - :ClassName (address_translation_rule) - ) - :comments () - :disabled (false) - :dst_adtr ( - : (ReferenceObject - :Name (IsoAAAA-100) - :Table (network_objects) - :Uid ("{BF1C6029-8D5D-4A05-A3AD-4B67E6E7A7AA}") - ) - ) - :global_location (middle) - :install ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :rule_block_number (1) - :services_adtr ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :src_adtr ( - : (ReferenceObject - :Name (Cactus-InternetTransfer) - :Table (network_objects) - :Uid ("{408C820D-33A1-4E25-B576-EC826F525DCD}") - ) - ) - :dst_adtr_translated ( - :AdminInfo ( - :chkpf_uid ("{5DD7A06F-C26F-47A8-AFBC-2649EE40DAAF}") - :ClassName (translate_static) - ) - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - :adtr_method (adtr_method_static) - ) - :services_adtr_translated ( - :AdminInfo ( - :chkpf_uid ("{D9D74C97-AC50-4633-A4BE-AD9DF32ED7B8}") - :ClassName (service_translate) - ) - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - :adtr_method (adtr_method_static) - ) - :src_adtr_translated ( - :AdminInfo ( - :chkpf_uid ("{404CEBC7-55D9-4A9A-98AC-10A264BC9F08}") - :ClassName (translate_hide) - ) - : (ReferenceObject - :Name (IsoAAAD_intern) - :Table (network_objects) - :Uid ("{40831AE2-CB84-46D2-9522-F987BC10BDB9}") - ) - :adtr_method (adtr_method_hide) - ) - ) - :rule_adtr ( - :AdminInfo ( - :chkpf_uid ("{795A2E9C-E2BD-4674-AB77-023F50036168}") - :ClassName (address_translation_rule) - ) - :comments () - :disabled (false) - :dst_adtr ( - : (ReferenceObject - :Name (IsoAAADray.local) - :Table (network_objects) - :Uid ("{75EDBC62-7EB1-4D37-8295-684903FDA75A}") - ) - ) - :global_location (middle) - :install ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :rule_block_number (1) - :services_adtr ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :src_adtr ( - : (ReferenceObject - :Name (heag_off_upper) - :Table (network_objects) - :Uid ("{A58E3E67-0517-485F-AA04-97A12BC119C3}") - ) - ) - :dst_adtr_translated ( - :AdminInfo ( - :chkpf_uid ("{5C6895F5-E9DC-4A23-8A54-0DFAB2B7BE72}") - :ClassName (translate_static) - ) - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - :adtr_method (adtr_method_static) - ) - :services_adtr_translated ( - :AdminInfo ( - :chkpf_uid ("{4C474EB4-0463-4982-B6CE-2B5AF7708E63}") - :ClassName (service_translate) - ) - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - :adtr_method (adtr_method_static) - ) - :src_adtr_translated ( - :AdminInfo ( - :chkpf_uid ("{50C50462-F4F4-4619-B04A-5C4DB56D0F6A}") - :ClassName (translate_hide) - ) - : (ReferenceObject - :Name (IsoAAAD_intern) - :Table (network_objects) - :Uid ("{40831AE2-CB84-46D2-9522-F987BC10BDB9}") - ) - :adtr_method (adtr_method_hide) - ) - ) - :rule_adtr ( - :AdminInfo ( - :chkpf_uid ("{1D294F6F-03B3-4CAB-B5FF-5CAEB867C8D0}") - :ClassName (address_translation_rule) - ) - :comments () - :disabled (false) - :dst_adtr ( - : (ReferenceObject - :Name (LSYI-WWA) - :Table (network_objects) - :Uid ("{3ECB1B79-1A26-41A3-90F9-71BE179A7211}") - ) - ) - :global_location (middle) - :install ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :rule_block_number (1) - :services_adtr ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :src_adtr ( - : (ReferenceObject - :Name (IsoAAAA-100) - :Table (network_objects) - :Uid ("{BF1C6029-8D5D-4A05-A3AD-4B67E6E7A7AA}") - ) - ) - :dst_adtr_translated ( - :AdminInfo ( - :chkpf_uid ("{8E14CB91-D19B-40A6-8784-8554E1B86BE4}") - :ClassName (translate_static) - ) - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - :adtr_method (adtr_method_static) - ) - :services_adtr_translated ( - :AdminInfo ( - :chkpf_uid ("{5E8C8FCF-5707-4638-81A3-B20DFB9C42C9}") - :ClassName (service_translate) - ) - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - :adtr_method (adtr_method_static) - ) - :src_adtr_translated ( - :AdminInfo ( - :chkpf_uid ("{6A960E2C-D9AD-44BC-B3B2-F5F3DC5992DA}") - :ClassName (translate_static) - ) - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - :adtr_method (adtr_method_static) - ) - ) - :rule_adtr ( - :AdminInfo ( - :chkpf_uid ("{434891D2-F2AE-4B89-88AD-540EB2A0C83A}") - :ClassName (address_translation_rule) - ) - :comments () - :dst_adtr ( - : (ReferenceObject - :Name (t-online) - :Table (network_objects) - :Uid ("{C3D65C4B-6498-4E00-9BAF-15539231E8EE}") - ) - ) - :global_location (middle) - :install ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :rule_block_number (1) - :services_adtr ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :src_adtr ( - : (ReferenceObject - :Name (IsoAAAA-100) - :Table (network_objects) - :Uid ("{BF1C6029-8D5D-4A05-A3AD-4B67E6E7A7AA}") - ) - ) - :disabled (true) - :dst_adtr_translated ( - :AdminInfo ( - :chkpf_uid ("{02FA831E-4B9C-4943-9EDA-AEA384241460}") - :ClassName (translate_static) - ) - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - :adtr_method (adtr_method_static) - ) - :services_adtr_translated ( - :AdminInfo ( - :chkpf_uid ("{6DC1B358-0DE4-49CF-B496-D0006744DA88}") - :ClassName (service_translate) - ) - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - :adtr_method (adtr_method_static) - ) - :src_adtr_translated ( - :AdminInfo ( - :chkpf_uid ("{F1DC8420-40C4-4CAE-A612-C9EC4518BBCA}") - :ClassName (translate_static) - ) - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - :adtr_method (adtr_method_static) - ) - ) - :rule_adtr ( - :AdminInfo ( - :chkpf_uid ("{4BBFC8B5-8B70-4AE2-BC71-6BCF4B17F7B6}") - :ClassName (address_translation_rule) - ) - :comments () - :disabled (false) - :dst_adtr ( - : (ReferenceObject - :Name (spike.local) - :Table (network_objects) - :Uid ("{4ABDD8DE-0DA2-46E5-B129-85E3977CBD18}") - ) - ) - :global_location (middle) - :install ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :rule_block_number (1) - :services_adtr ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :src_adtr ( - : (ReferenceObject - :Name (IsoAAAA-100) - :Table (network_objects) - :Uid ("{BF1C6029-8D5D-4A05-A3AD-4B67E6E7A7AA}") - ) - ) - :dst_adtr_translated ( - :AdminInfo ( - :chkpf_uid ("{7AA3058F-6816-45D2-A6DE-B54CBB46BD08}") - :ClassName (translate_static) - ) - : (ReferenceObject - :Name (mg.IsoAAAA-es.com) - :Table (network_objects) - :Uid ("{E5BF8260-3615-4476-B638-53CA3A24FEF1}") - ) - :adtr_method (adtr_method_static) - ) - :services_adtr_translated ( - :AdminInfo ( - :chkpf_uid ("{ED35E27D-FA79-48B3-8AC5-27502A7FDB71}") - :ClassName (service_translate) - ) - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - :adtr_method (adtr_method_static) - ) - :src_adtr_translated ( - :AdminInfo ( - :chkpf_uid ("{800AC60D-FE78-47F3-B9F1-8F8F468708C1}") - :ClassName (translate_static) - ) - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - :adtr_method (adtr_method_static) - ) - ) - :rule_adtr ( - :AdminInfo ( - :chkpf_uid ("{5CF61260-14E3-42BB-81E6-EBE8EFE8AF4A}") - :ClassName (address_translation_rule) - ) - :comments () - :disabled (false) - :dst_adtr ( - : (ReferenceObject - :Name (mg.IsoAAAA-es.com) - :Table (network_objects) - :Uid ("{E5BF8260-3615-4476-B638-53CA3A24FEF1}") - ) - ) - :global_location (middle) - :install ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :rule_block_number (1) - :services_adtr ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :src_adtr ( - : (ReferenceObject - :Name (IsoAAAA-100) - :Table (network_objects) - :Uid ("{BF1C6029-8D5D-4A05-A3AD-4B67E6E7A7AA}") - ) - ) - :dst_adtr_translated ( - :AdminInfo ( - :chkpf_uid ("{098ADCE5-568E-4F27-ABF9-682BBE442FE7}") - :ClassName (translate_static) - ) - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - :adtr_method (adtr_method_static) - ) - :services_adtr_translated ( - :AdminInfo ( - :chkpf_uid ("{36B74AF0-631F-40BD-B592-5ED305639070}") - :ClassName (service_translate) - ) - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - :adtr_method (adtr_method_static) - ) - :src_adtr_translated ( - :AdminInfo ( - :chkpf_uid ("{41B82ACB-215E-4320-B02C-A86A08EEEFC9}") - :ClassName (translate_static) - ) - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - :adtr_method (adtr_method_static) - ) - ) - :rule_adtr ( - :AdminInfo ( - :chkpf_uid ("{32620515-7BA6-4223-8C0A-83C23601451E}") - :ClassName (address_translation_rule) - ) - :comments () - :disabled (false) - :dst_adtr ( - : (ReferenceObject - :Name (scratchy.local) - :Table (network_objects) - :Uid ("{CFABE50C-C1F6-4FF1-8AC3-3161A3779708}") - ) - ) - :global_location (middle) - :install ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :rule_block_number (1) - :services_adtr ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :src_adtr ( - : (ReferenceObject - :Name (mg.IsoAAAA-es.com) - :Table (network_objects) - :Uid ("{E5BF8260-3615-4476-B638-53CA3A24FEF1}") - ) - ) - :dst_adtr_translated ( - :AdminInfo ( - :chkpf_uid ("{5C1D3DFD-A07D-49DA-B3B5-B6927EC4E8FA}") - :ClassName (translate_static) - ) - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - :adtr_method (adtr_method_static) - ) - :services_adtr_translated ( - :AdminInfo ( - :chkpf_uid ("{D670057B-5491-4A66-93BB-6FA84BA374AC}") - :ClassName (service_translate) - ) - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - :adtr_method (adtr_method_static) - ) - :src_adtr_translated ( - :AdminInfo ( - :chkpf_uid ("{B06D37B0-374A-4D36-847F-360C802BF268}") - :ClassName (translate_hide) - ) - : (ReferenceObject - :Name (IsoAAAD_intern) - :Table (network_objects) - :Uid ("{40831AE2-CB84-46D2-9522-F987BC10BDB9}") - ) - :adtr_method (adtr_method_hide) - ) - ) - :rule_adtr ( - :AdminInfo ( - :chkpf_uid ("{44B823A7-B08B-4A9F-BF4E-F895E1BAE762}") - :ClassName (address_translation_rule) - ) - :comments () - :disabled (false) - :dst_adtr ( - : (ReferenceObject - :Name (IsoAAAA-100) - :Table (network_objects) - :Uid ("{BF1C6029-8D5D-4A05-A3AD-4B67E6E7A7AA}") - ) - ) - :global_location (middle) - :install ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :rule_block_number (1) - :services_adtr ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :src_adtr ( - : (ReferenceObject - :Name (Cactus-Official) - :Table (network_objects) - :Uid ("{2136B4E8-3ABF-4931-BDB9-12CDF457D4A4}") - ) - ) - :dst_adtr_translated ( - :AdminInfo ( - :chkpf_uid ("{F9494163-1D8B-45BE-A547-0786801699CD}") - :ClassName (translate_static) - ) - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - :adtr_method (adtr_method_static) - ) - :services_adtr_translated ( - :AdminInfo ( - :chkpf_uid ("{13C447D5-A284-4282-B584-A1B7ED1DE70C}") - :ClassName (service_translate) - ) - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - :adtr_method (adtr_method_static) - ) - :src_adtr_translated ( - :AdminInfo ( - :chkpf_uid ("{007B4C50-EC16-45E9-8CD5-A3C71764175C}") - :ClassName (translate_static) - ) - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - :adtr_method (adtr_method_static) - ) - ) - :rule_adtr ( - :AdminInfo ( - :chkpf_uid ("{05A4371B-C62D-4CE9-AD5F-9818F9D852BE}") - :ClassName (address_translation_rule) - ) - :comments () - :disabled (false) - :dst_adtr ( - : (ReferenceObject - :Name (IsoAAAA-100) - :Table (network_objects) - :Uid ("{BF1C6029-8D5D-4A05-A3AD-4B67E6E7A7AA}") - ) - ) - :global_location (middle) - :install ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :rule_block_number (1) - :services_adtr ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :src_adtr ( - : (ReferenceObject - :Name (allNet) - :Table (network_objects) - :Uid ("{8C20ECB8-A6DB-4C35-B79A-D12ECE559C77}") - ) - ) - :dst_adtr_translated ( - :AdminInfo ( - :chkpf_uid ("{39606C16-F893-466A-9D38-B01857A51FEB}") - :ClassName (translate_static) - ) - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - :adtr_method (adtr_method_static) - ) - :services_adtr_translated ( - :AdminInfo ( - :chkpf_uid ("{19200950-6F5C-4AA2-939A-3CE7D6ACA81D}") - :ClassName (service_translate) - ) - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - :adtr_method (adtr_method_static) - ) - :src_adtr_translated ( - :AdminInfo ( - :chkpf_uid ("{C74080E8-0E7B-4D2E-8FAA-346607D856EC}") - :ClassName (translate_hide) - ) - : (ReferenceObject - :Name (IsoAAAD_intern) - :Table (network_objects) - :Uid ("{40831AE2-CB84-46D2-9522-F987BC10BDB9}") - ) - :adtr_method (adtr_method_hide) - ) - ) - :rule_adtr ( - :AdminInfo ( - :chkpf_uid ("{D980F7C0-D2FA-4ACA-904E-34D328EF1C19}") - :ClassName (address_translation_rule) - ) - :comments () - :disabled (false) - :dst_adtr ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :global_location (middle) - :install ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :rule_block_number (1) - :services_adtr ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :src_adtr ( - : (ReferenceObject - :Name (Cactus-Wlan) - :Table (network_objects) - :Uid ("{FFB3BAC5-FD79-4D0B-911A-7413DA524723}") - ) - ) - :dst_adtr_translated ( - :AdminInfo ( - :chkpf_uid ("{EA2291B3-5DED-41D9-9AC1-E7E98C8A7157}") - :ClassName (translate_static) - ) - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - :adtr_method (adtr_method_static) - ) - :services_adtr_translated ( - :AdminInfo ( - :chkpf_uid ("{0427645F-6265-4CD1-9E5D-918261EF1A8A}") - :ClassName (service_translate) - ) - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - :adtr_method (adtr_method_static) - ) - :src_adtr_translated ( - :AdminInfo ( - :chkpf_uid ("{DB4F178F-D470-4EB9-BE8D-98EC3DCAA267}") - :ClassName (translate_hide) - ) - : (ReferenceObject - :Name (IsoAAAD_extern) - :Table (network_objects) - :Uid ("{DB456CE7-0DCA-423F-A5E4-9FA976C0B594}") - ) - :adtr_method (adtr_method_hide) - ) - ) - :rule_adtr ( - :AdminInfo ( - :chkpf_uid ("{770C7861-8D4D-45BD-9A08-6D7412464847}") - :ClassName (address_translation_rule) - ) - :comments () - :disabled (false) - :dst_adtr ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :global_location (middle) - :install ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :rule_block_number (1) - :services_adtr ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :src_adtr ( - : (ReferenceObject - :Name (IsoAAAA-100) - :Table (network_objects) - :Uid ("{BF1C6029-8D5D-4A05-A3AD-4B67E6E7A7AA}") - ) - ) - :dst_adtr_translated ( - :AdminInfo ( - :chkpf_uid ("{323C02BB-1CA8-4AF0-B778-CE65AB57FDA1}") - :ClassName (translate_static) - ) - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - :adtr_method (adtr_method_static) - ) - :services_adtr_translated ( - :AdminInfo ( - :chkpf_uid ("{26E182C6-DB5F-462F-BD1B-8C37735E86F7}") - :ClassName (service_translate) - ) - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - :adtr_method (adtr_method_static) - ) - :src_adtr_translated ( - :AdminInfo ( - :chkpf_uid ("{8FA593D7-47A4-4AAC-BA66-34C93515C7F0}") - :ClassName (translate_hide) - ) - : (ReferenceObject - :Name (IsoAAAD_extern) - :Table (network_objects) - :Uid ("{DB456CE7-0DCA-423F-A5E4-9FA976C0B594}") - ) - :adtr_method (adtr_method_hide) - ) - ) - :use_VPN_communities (false) - ) -) diff --git a/roles/sample-data/files/sample-configs/fortinet_demo/fortigate.cfg b/roles/sample-data/files/sample-configs/fortinet_demo/fortigate.cfg deleted file mode 100644 index 62a2bf0e6b..0000000000 --- a/roles/sample-data/files/sample-configs/fortinet_demo/fortigate.cfg +++ /dev/null @@ -1,6048 +0,0 @@ -#config-version=FWF60E-5.04-FW-build1111-161216:opmode=0:vdom=0:user=tim -#conf_file_ver=0 -#buildno=5873 -#global_vdom=1 -config system global - set admin-scp enable - set admintimeout 480 - set alias "FGT60D4615073961" - set fgd-alert-subscription advisory latest-threat - set gui-certificates enable - set gui-ipv6 enable - set hostname "fg60e" - set switch-controller enable - set timezone 26 -end -config system accprofile - edit "prof_admin" - set mntgrp read-write - set admingrp read-write - set updategrp read-write - set authgrp read-write - set sysgrp read-write - set netgrp read-write - set loggrp read-write - set routegrp read-write - set fwgrp read-write - set vpngrp read-write - set utmgrp read-write - set endpoint-control-grp read-write - set wifi read-write - next - edit "config_reader" - set comments "read-only" - set mntgrp read - set admingrp read - set updategrp read - set authgrp read - set sysgrp read - set netgrp read - set loggrp read - set routegrp read - set fwgrp read - set vpngrp read - set utmgrp read - set endpoint-control-grp read - set wifi read - next -end -config wireless-controller vap - edit "wlan0" - set vdom "root" - set ssid "wch60e" - set schedule "always" - set passphrase ENC MwT7qzDW4UeSHEbobSoaaK8K4cvCZUKd4HC35zlxyuiWcxmaFlp0H6LzZXpt12dHBW2tLsNl3leiRa71BJNl5SYF2r/qKhItybJJPTo262YEFf2DBgX8HHysA79p49FbjX+UTQJC+CIVVNrVjKi86wBHIoZNyG1jnUWR6Zd5ib1us3iKd6t2liRfoVhLJ5PNSR5FxA== - next - edit "kids-wifi" - set vdom "root" - set max-clients 4 - set ssid "nfm" - set security wpa2-only-personal+captive-portal - set portal-message-override-group "captive-portal-kids-wifi" - set selected-usergroups "Kinder-group" - set security-exempt-list "kids-wifi-exempt-list" - set schedule "always" - set passphrase ENC MnT0ZIwJyRBgfyKIYpgQUbyrPkWPUGMUgzBwwBXrhnZDAfutxqryXfJGfrGZnbOy9cOpCny/wplhCuaHapxxIc4+LROepDNgITwFSq8NeOWfyV5KapLSBa/V6aFJztI609UUVb7dS6HLic9iYYCvrqoUvbd6TXxZ1knElT7lPclyQ6a5j4X2phEjkzHAHf9yP8phNw== - next - edit "gpunkt" - set vdom "root" - set ssid "gpoint" - set security wpa2-only-personal+captive-portal - set selected-usergroups "gastgruppe" - set intra-vap-privacy enable - set schedule "always" - set passphrase ENC DDTtFNHZXJQk9tLy4h0bDUDriEp2araA+JTVqa+E1nEJPgNm2xK0zaCxljEF591wRmcXUBGXjW/zxqsI3wW4Kvr3y2PMwd8GQPWubcSQPNs9jLkITD6guROTxp5Y0U4Muw4NcG7OHgRcHJBP+IMqiG7ToiIzNMqNsHlj6rkWyxU8sR6MyLRcMWSF7+LHQljp1x25xw== - next - edit "GWS" - set vdom "root" - set ssid "GWS" - set intra-vap-privacy enable - set schedule "always" - set passphrase ENC iblG3LP6Qex6jozN/MXDTZCLJZkhv3msWDEEDwfSgwG5o0ScpsxMNFjuTBkHpCX/rMigYgM0KI6KaEeqZQAO0Oddby5TwHdD0aftbwx28DRRcwl6aenEH+F0b4cXpCyfB1Vd9kAGcxZmkla0nRA+0lkeyPg+y1P1qd9TOaIJ4ZhhMtBzLgRXQHHvW63+qXwTYlcmRw== - next -end -config system interface - edit "wan1" - set vdom "root" - set ip 10.0.0.1 255.255.255.255 - set allowaccess ping - set type physical - set scan-botnet-connections block - set role wan - set snmp-index 2 - config ipv6 - set ip6-allowaccess capwap - end - next - edit "wan2" - set vdom "root" - set mode dhcp - set status down - set type physical - set snmp-index 3 - config ipv6 - set ip6-allowaccess capwap - end - next - edit "dmz" - set vdom "root" - set ip 10.0.0.2 255.255.255.255 - set allowaccess ping - set type physical - set scan-botnet-connections block - set description "gameserver lan" - set role dmz - set snmp-index 1 - config ipv6 - set ip6-allowaccess capwap - end - next - edit "internal5" - set vdom "root" - set ip 10.0.0.3 255.255.255.255 - set allowaccess ping https ssh - set type physical - set scan-botnet-connections block - set alias "eltern-keller" - set device-identification enable - set role lan - set snmp-index 5 - next - edit "npu0_vlink0" - set vdom "root" - set type physical - set snmp-index 11 - next - edit "npu0_vlink1" - set vdom "root" - set type physical - set snmp-index 12 - next - edit "modem" - set vdom "root" - set mode pppoe - set type physical - set snmp-index 4 - next - edit "ssl.root" - set vdom "root" - set type tunnel - set alias "SSL VPN interface" - set snmp-index 7 - next - edit "wlan0" - set vdom "root" - set ip 10.0.0.4 255.255.255.255 - set allowaccess ping https ssh fgfm - set type vap-switch - set scan-botnet-connections block - set device-identification enable - set snmp-index 13 - next - edit "kids-wifi" - set vdom "root" - set ip 10.0.0.5 255.255.255.255 - set allowaccess ping - set type vap-switch - set scan-botnet-connections block - set device-identification enable - set snmp-index 14 - next - edit "gpunkt" - set vdom "root" - set ip 10.0.0.6 255.255.255.255 - set type vap-switch - set scan-botnet-connections block - set device-identification enable - set snmp-index 15 - next - edit "internal" - set vdom "root" - set ip 10.0.0.7 255.255.255.255 - set allowaccess ping https ssh http fgfm capwap - set type hard-switch - set scan-botnet-connections block - set device-identification enable - set role lan - set snmp-index 8 - config ipv6 - set ip6-allowaccess capwap - end - next - edit "server-lan2" - set vdom "root" - set ip 10.0.0.8 255.255.255.255 - set allowaccess ping - set type hard-switch - set scan-botnet-connections block - set description "for knappe and printer" - set device-identification enable - set role lan - set snmp-index 6 - config ipv6 - set ip6-allowaccess capwap - end - next - edit "Forticlient-VPN" - set vdom "root" - set ip 10.0.0.9 255.255.255.255 - set type tunnel - set remote-ip 10.0.0.9 - set snmp-index 9 - set interface "wan1" - next - edit "Cactus-DA" - set vdom "root" - set type tunnel - set snmp-index 10 - set interface "wan1" - next - edit "GWS" - set vdom "root" - set ip 10.0.0.10 255.255.255.255 - set allowaccess ping - set type vap-switch - set scan-botnet-connections block - set device-identification enable - set snmp-index 16 - config ipv6 - set ip6-allowaccess ping - end - next -end -config system physical-switch - edit "sw0" - set age-val 0 - next -end -config system virtual-switch - edit "internal" - set physical-switch "sw0" - config port - edit "internal1" - next - edit "internal2" - next - edit "internal3" - next - edit "internal4" - next - end - next - edit "server-lan2" - set physical-switch "sw0" - config port - edit "internal6" - next - edit "internal7" - next - end - next -end -config system password-policy - set status enable - set apply-to admin-password ipsec-preshared-key - set min-lower-case-letter 1 - set min-upper-case-letter 1 - set min-number 1 -end -config system custom-language - edit "en" - set filename "en" - next - edit "fr" - set filename "fr" - next - edit "sp" - set filename "sp" - next - edit "pg" - set filename "pg" - next - edit "x-sjis" - set filename "x-sjis" - next - edit "big5" - set filename "big5" - next - edit "GB2312" - set filename "GB2312" - next - edit "euc-kr" - set filename "euc-kr" - next -end -config system admin - edit "admin" - set accprofile "super_admin" - set vdom "root" - set ssh-public-key1 "" - config dashboard - edit 1 - set column 1 - next - edit 2 - set widget-type licinfo - set column 1 - next - edit 3 - set widget-type jsconsole - set column 1 - next - edit 4 - set widget-type sysres - set column 2 - next - edit 6 - set widget-type alert - set column 2 - set top-n 10 - next - end - set password ENC AK1HBkKGj1Gm/kNrRfKuC6gfgxO9UtB0rq9RXcytAn34EY= - next - edit "tim" - set accprofile "super_admin" - set vdom "root" - config dashboard - edit 2 - set widget-type licinfo - set column 1 - next - edit 4 - set widget-type sysres - set column 1 - next - edit 10 - set widget-type sysop - set column 1 - next - edit 1 - set column 1 - next - edit 6 - set widget-type alert - set column 1 - set top-n 10 - next - edit 9 - set widget-type jsconsole - set column 1 - next - edit 8 - set widget-type tr-history - set column 1 - set interface "wan1" - set refresh enable - next - end - set email-to "tmp@cactus.de" - set password ENC AK1+SCz+Sd9qAuxaPTCowdDopQdGMAclzQeAs8D51/QboY= - next - edit "fmanager" - set accprofile "super_admin" - set vdom "root" - set password ENC SH2l0MdIF/9Zwhx76DxPrsdVXZp9LdIZtdAZ69uBjCmvwQm2WuqWSvujAWF3wo= - next - edit "fworch" - set accprofile "config_reader" - set vdom "root" - set ssh-public-key1 "" - set ssh-public-key2 "" - set ssh-public-key3 "" - set password ENC xxxxxxxx+Cx0dY= - next -end -config system ha - set override disable -end -config system dns - set primary 10.0.0.11 - set secondary 10.0.0.12 - set domain "ffm.cactus.de" -end -config system ddns - edit 1 - set ddns-server FortiGuardDDNS - set ddns-domain "hier.float-zone.com" - set use-public-ip enable - set monitor-interface "wan1" - next -end -config system replacemsg-image - edit "logo_fnet" - set image-type gif - set image-base64 '' - next - edit "logo_fguard_wf" - set image-type gif - set image-base64 '' - next - edit "logo_fw_auth" - set image-type png - set image-base64 '' - next - edit "logo_v2_fnet" - set image-type png - set image-base64 '' - next - edit "logo_v2_fguard_wf" - set image-type png - set image-base64 '' - next - edit "logo_v2_fguard_app" - set image-type png - set image-base64 '' - next -end -config system replacemsg mail "email-block" -end -config system replacemsg mail "email-dlp-subject" -end -config system replacemsg mail "email-dlp-ban" -end -config system replacemsg mail "email-filesize" -end -config system replacemsg mail "partial" -end -config system replacemsg mail "smtp-block" -end -config system replacemsg mail "smtp-filesize" -end -config system replacemsg http "bannedword" -end -config system replacemsg http "url-block" -end -config system replacemsg http "urlfilter-err" -end -config system replacemsg http "infcache-block" -end -config system replacemsg http "http-block" -end -config system replacemsg http "http-filesize" -end -config system replacemsg http "http-dlp-ban" -end -config system replacemsg http "http-archive-block" -end -config system replacemsg http "http-contenttypeblock" -end -config system replacemsg http "https-invalid-cert-block" -end -config system replacemsg http "http-client-block" -end -config system replacemsg http "http-client-filesize" -end -config system replacemsg http "http-client-bannedword" -end -config system replacemsg http "http-post-block" -end -config system replacemsg http "http-client-archive-block" -end -config system replacemsg http "switching-protocols-block" -end -config system replacemsg webproxy "deny" -end -config system replacemsg webproxy "user-limit" -end -config system replacemsg webproxy "auth-challenge" -end -config system replacemsg webproxy "auth-login-fail" -end -config system replacemsg webproxy "auth-authorization-fail" -end -config system replacemsg webproxy "http-err" -end -config system replacemsg webproxy "auth-ip-blackout" -end -config system replacemsg ftp "ftp-dl-blocked" -end -config system replacemsg ftp "ftp-dl-filesize" -end -config system replacemsg ftp "ftp-dl-dlp-ban" -end -config system replacemsg ftp "ftp-explicit-banner" -end -config system replacemsg ftp "ftp-dl-archive-block" -end -config system replacemsg nntp "nntp-dl-blocked" -end -config system replacemsg nntp "nntp-dl-filesize" -end -config system replacemsg nntp "nntp-dlp-subject" -end -config system replacemsg nntp "nntp-dlp-ban" -end -config system replacemsg fortiguard-wf "ftgd-block" -end -config system replacemsg fortiguard-wf "http-err" -end -config system replacemsg fortiguard-wf "ftgd-ovrd" -end -config system replacemsg fortiguard-wf "ftgd-quota" -end -config system replacemsg fortiguard-wf "ftgd-warning" -end -config system replacemsg spam "ipblocklist" -end -config system replacemsg spam "smtp-spam-dnsbl" -end -config system replacemsg spam "smtp-spam-feip" -end -config system replacemsg spam "smtp-spam-helo" -end -config system replacemsg spam "smtp-spam-emailblack" -end -config system replacemsg spam "smtp-spam-mimeheader" -end -config system replacemsg spam "reversedns" -end -config system replacemsg spam "smtp-spam-bannedword" -end -config system replacemsg spam "smtp-spam-ase" -end -config system replacemsg spam "submit" -end -config system replacemsg alertmail "alertmail-virus" -end -config system replacemsg alertmail "alertmail-block" -end -config system replacemsg alertmail "alertmail-nids-event" -end -config system replacemsg alertmail "alertmail-crit-event" -end -config system replacemsg alertmail "alertmail-disk-full" -end -config system replacemsg admin "pre_admin-disclaimer-text" -end -config system replacemsg admin "post_admin-disclaimer-text" -end -config system replacemsg auth "auth-disclaimer-page-1" -end -config system replacemsg auth "auth-disclaimer-page-2" -end -config system replacemsg auth "auth-disclaimer-page-3" -end -config system replacemsg auth "auth-reject-page" -end -config system replacemsg auth "auth-login-page" - set buffer " - - - - - - Firewall Authentication - - - -
                      -
                      -
                      - - - -

                      - Papa: Authentication Required -

                      -

                      - %%QUESTION%% -

                      -
                      - - - -
                      -
                      -
                      - - - -
                      -
                      - -
                      -
                      -
                      -
                      - -" -end -config system replacemsg auth "auth-login-failed-page" -end -config system replacemsg auth "auth-token-login-page" -end -config system replacemsg auth "auth-token-login-failed-page" -end -config system replacemsg auth "auth-success-msg" -end -config system replacemsg auth "auth-challenge-page" -end -config system replacemsg auth "auth-keepalive-page" -end -config system replacemsg auth "auth-portal-page" -end -config system replacemsg auth "auth-password-page" -end -config system replacemsg auth "auth-fortitoken-page" -end -config system replacemsg auth "auth-next-fortitoken-page" -end -config system replacemsg auth "auth-email-token-page" -end -config system replacemsg auth "auth-sms-token-page" -end -config system replacemsg auth "auth-email-harvesting-page" -end -config system replacemsg auth "auth-email-failed-page" -end -config system replacemsg auth "auth-cert-passwd-page" -end -config system replacemsg auth "auth-guest-print-page" -end -config system replacemsg auth "auth-guest-email-page" -end -config system replacemsg auth "auth-success-page" -end -config system replacemsg auth "auth-block-notification-page" -end -config system replacemsg sslvpn "sslvpn-login" -end -config system replacemsg sslvpn "sslvpn-header" -end -config system replacemsg sslvpn "sslvpn-limit" -end -config system replacemsg sslvpn "hostcheck-error" -end -config system replacemsg ec "endpt-download-portal" -end -config system replacemsg ec "endpt-download-portal-mac" -end -config system replacemsg ec "endpt-download-portal-ios" -end -config system replacemsg ec "endpt-download-portal-aos" -end -config system replacemsg ec "endpt-download-portal-other" -end -config system replacemsg ec "endpt-quarantine-portal" -end -config system replacemsg device-detection-portal "device-detection-failure" -end -config system replacemsg nac-quar "nac-quar-virus" -end -config system replacemsg nac-quar "nac-quar-dos" -end -config system replacemsg nac-quar "nac-quar-ips" -end -config system replacemsg nac-quar "nac-quar-dlp" -end -config system replacemsg nac-quar "nac-quar-admin" -end -config system replacemsg nac-quar "nac-quar-app" -end -config system replacemsg traffic-quota "per-ip-shaper-block" -end -config system replacemsg utm "virus-html" -end -config system replacemsg utm "client-virus-html" -end -config system replacemsg utm "virus-text" -end -config system replacemsg utm "dlp-html" -end -config system replacemsg utm "dlp-text" -end -config system replacemsg utm "appblk-html" -end -config system replacemsg utm "ipsblk-html" -end -config system replacemsg utm "exe-text" -end -config system replacemsg utm "waf-html" -end -config system autoupdate push-update - set status enable -end -config system autoupdate schedule - set time 01:60 -end -config system central-management - set type fortimanager - set serial-number "FMG-VM0000000000" - set fmg "10.0.0.13" -end -config user device-category - edit "android-phone" - next - edit "android-tablet" - next - edit "blackberry-phone" - next - edit "blackberry-playbook" - next - edit "forticam" - next - edit "fortifone" - next - edit "fortinet-device" - next - edit "gaming-console" - next - edit "ip-phone" - next - edit "ipad" - next - edit "iphone" - next - edit "linux-pc" - next - edit "mac" - next - edit "media-streaming" - next - edit "printer" - next - edit "router-nat-device" - next - edit "windows-pc" - next - edit "windows-phone" - next - edit "windows-tablet" - next - edit "other-network-device" - next - edit "collected-emails" - next - edit "all" - next -end -config system cluster-sync -end -config system fortiguard - set sdns-server-ip "10.0.0.14" -end -config ips global - set database extended - set traffic-submit enable - set default-app-cat-mask 18446744073642442751 -end -config ips dbinfo - set version 1 -end -config log syslogd setting - set status enable - set server "10.0.0.15" -end -config system email-server - set reply-to "tim@cactus.de" - set server "gware.cactus.de" - set port 465 - set security smtps -end -config gui console - unset preferences -end -config system session-helper - edit 1 - set name pptp - set protocol 6 - set port 1723 - next - edit 2 - set name h323 - set protocol 6 - set port 1720 - next - edit 3 - set name ras - set protocol 17 - set port 1719 - next - edit 4 - set name tns - set protocol 6 - set port 1521 - next - edit 5 - set name tftp - set protocol 17 - set port 69 - next - edit 6 - set name rtsp - set protocol 6 - set port 554 - next - edit 7 - set name rtsp - set protocol 6 - set port 7070 - next - edit 8 - set name rtsp - set protocol 6 - set port 8554 - next - edit 9 - set name ftp - set protocol 6 - set port 21 - next - edit 10 - set name mms - set protocol 6 - set port 1863 - next - edit 11 - set name pmap - set protocol 6 - set port 111 - next - edit 12 - set name pmap - set protocol 17 - set port 111 - next - edit 13 - set name sip - set protocol 17 - set port 5060 - next - edit 14 - set name dns-udp - set protocol 17 - set port 53 - next - edit 15 - set name rsh - set protocol 6 - set port 514 - next - edit 16 - set name rsh - set protocol 6 - set port 512 - next - edit 17 - set name dcerpc - set protocol 6 - set port 135 - next - edit 18 - set name dcerpc - set protocol 17 - set port 135 - next - edit 19 - set name mgcp - set protocol 17 - set port 2427 - next - edit 20 - set name mgcp - set protocol 17 - set port 2727 - next -end -config system auto-install - set auto-install-config enable - set auto-install-image enable -end -config system console - set mode batch - set output standard -end -config system ntp - set ntpsync enable - set syncinterval 60 -end -config system settings - set inspection-mode flow - set gui-dns-database enable - set gui-dos-policy enable - set gui-local-in-policy enable - set gui-sslvpn-personal-bookmarks enable - set gui-sslvpn-realms enable - set gui-ips enable - set gui-switch-controller disable - set gui-traffic-shaping disable - set gui-wan-load-balancing disable - set gui-domain-ip-reputation enable - set compliance-check enable -end -config system replacemsg-group - edit "web-filter-undefined" - set comment "System Generated" - set group-type utm - next - edit "captive-portal-kids-wifi" - set comment "System Generated" - set group-type auth - config auth - edit "auth-login-page" - set buffer " - - - - - - Firewall Authentication - - - -
                      -
                      -
                      - - - -

                      - Papa: bitte anmelden für 2h Internet -

                      -

                      - %%QUESTION%% -

                      -
                      - - - -
                      -
                      -
                      - - - -
                      -
                      - -
                      -
                      -
                      -
                      - -" - set header http - set format html - next - end - next -end -config system dhcp server - edit 1 - set dns-service local - set ntp-service default - set default-gateway 10.0.0.7 - set netmask 255.255.255.255 - set interface "internal" - config ip-range - edit 1 - set start-ip 10.0.0.16 - set end-ip 10.0.0.17 - next - end - set timezone-option default - config reserved-address - edit 1 - set ip 10.0.0.16 - set mac c8:2a:14:14:f1:eb - next - edit 2 - set ip 10.0.0.18 - set mac 9c:c7:a6:23:18:58 - next - edit 3 - set mac 3c:bd:d8:fa:d8:d4 - set action assign - set description "Fernseher" - next - edit 4 - set mac 00:24:fe:b9:18:42 - set action assign - set description "10.0.0.19" - next - end - next - edit 2 - set dns-service default - set ntp-service default - set default-gateway 10.0.0.4 - set netmask 255.255.255.255 - set interface "wlan0" - config ip-range - edit 1 - set start-ip 10.0.0.20 - set end-ip 10.0.0.21 - next - end - set timezone-option default - next - edit 3 - set ntp-service default - set default-gateway 10.0.0.5 - set netmask 255.255.255.255 - set interface "kids-wifi" - config ip-range - edit 1 - set start-ip 10.0.0.22 - set end-ip 10.0.0.23 - next - end - set timezone-option default - set dns-server1 10.0.0.24 - next - edit 4 - set dns-service default - set default-gateway 10.0.0.6 - set netmask 255.255.255.255 - set interface "gpunkt" - config ip-range - edit 1 - set start-ip 10.0.0.25 - set end-ip 10.0.0.26 - next - end - set timezone-option default - next - edit 5 - set dns-service default - set ntp-service default - set default-gateway 10.0.0.8 - set netmask 255.255.255.255 - set interface "server-lan2" - config ip-range - edit 1 - set start-ip 10.0.0.27 - set end-ip 10.0.0.28 - next - end - set timezone-option default - next - edit 6 - set dns-service default - set default-gateway 10.0.0.10 - set netmask 255.255.255.255 - set interface "GWS" - config ip-range - edit 1 - set start-ip 10.0.0.29 - set end-ip 10.0.0.30 - next - end - set timezone-option default - next - edit 7 - set dns-service default - set ntp-service default - set default-gateway 10.0.0.3 - set netmask 255.255.255.255 - set interface "internal5" - config ip-range - edit 1 - set start-ip 10.0.0.31 - set end-ip 10.0.0.32 - next - end - set timezone-option default - next -end -config firewall address - edit "SSLVPN_TUNNEL_ADDR1" - set uuid b7647270-5975-51e5-6f5a-65cd955669b6 - set type iprange - set start-ip 10.0.0.33 - set end-ip 10.0.0.34 - next - edit "all" - set uuid 72cdb5ba-d63c-51e5-c303-5835388f9b9a - next - edit "apple" - set uuid b7ce5f8c-5975-51e5-5bc3-0449fdc61391 - set type wildcard-fqdn - set wildcard-fqdn "*.apple.com" - next - edit "dropbox.com" - set uuid b7ced89a-5975-51e5-ea5b-6b089bbeb104 - set type wildcard-fqdn - set wildcard-fqdn "*.dropbox.com" - next - edit "Gotomeeting" - set uuid b7cf43a2-5975-51e5-dc5f-944da5f662b2 - set type wildcard-fqdn - set wildcard-fqdn "*.gotomeeting.com" - next - edit "icloud" - set uuid b7cfbb5c-5975-51e5-be59-10e7bed404b1 - set type wildcard-fqdn - set wildcard-fqdn "*.icloud.com" - next - edit "itunes" - set uuid b7d03244-5975-51e5-aaea-3ca78f34fc64 - set type wildcard-fqdn - set wildcard-fqdn "*itunes.apple.com" - next - edit "android" - set uuid b7d09b94-5975-51e5-806e-e3caa907c2dd - set type wildcard-fqdn - set wildcard-fqdn "*.android.com" - next - edit "skype" - set uuid b7d112e0-5975-51e5-35a3-d3c6055900b5 - set type wildcard-fqdn - set wildcard-fqdn "*.messenger.live.com" - next - edit "swscan.apple.com" - set uuid b7d18a72-5975-51e5-5589-182f772d273c - set type fqdn - set fqdn "swscan.apple.com" - next - edit "update.microsoft.com" - set uuid b7d1f408-5975-51e5-0442-6fd89994de88 - set type fqdn - set fqdn "update.microsoft.com" - next - edit "appstore" - set uuid b7d26c1c-5975-51e5-e889-443c320f8ee7 - set type wildcard-fqdn - set wildcard-fqdn "*.appstore.com" - next - edit "eease" - set uuid b7d2e35e-5975-51e5-9ff8-986220853d7e - set type wildcard-fqdn - set wildcard-fqdn "*.eease.com" - next - edit "google-drive" - set uuid b7d35aa0-5975-51e5-e4fc-f07aa20f53c4 - set type wildcard-fqdn - set wildcard-fqdn "*drive.google.com" - next - edit "google-play" - set uuid b7d3c7b0-5975-51e5-07d2-490a00ed247f - set type fqdn - set fqdn "play.google.com" - next - edit "google-play2" - set uuid b7d43f06-5975-51e5-45aa-3a5031794d4d - set type wildcard-fqdn - set wildcard-fqdn "*.ggpht.com" - next - edit "google-play3" - set uuid b7d4b6ca-5975-51e5-a49c-de545ced1d59 - set type wildcard-fqdn - set wildcard-fqdn "*.books.google.com" - next - edit "microsoft" - set uuid b7d5207e-5975-51e5-3e6b-fb39bc646ae4 - set type wildcard-fqdn - set wildcard-fqdn "*.microsoft.com" - next - edit "adobe" - set uuid b7d5977a-5975-51e5-b7e2-6e8952d82c87 - set type wildcard-fqdn - set wildcard-fqdn "*.adobe.com" - next - edit "Adobe Login" - set uuid b7d60e80-5975-51e5-9ccb-162cd8863fc9 - set type wildcard-fqdn - set wildcard-fqdn "*.adobelogin.com" - next - edit "fortinet" - set uuid b7d685f4-5975-51e5-a4f4-5e14a67b9a1d - set type wildcard-fqdn - set wildcard-fqdn "*.fortinet.com" - next - edit "googleapis.com" - set uuid b7d6f002-5975-51e5-9c23-99858226b9f8 - set type wildcard-fqdn - set wildcard-fqdn "*.googleapis.com" - next - edit "citrix" - set uuid b7d7674e-5975-51e5-3d04-893f33ecea8b - set type wildcard-fqdn - set wildcard-fqdn "*.citrixonline.com" - next - edit "verisign" - set uuid b7d7deb8-5975-51e5-9da3-39752ce8c999 - set type wildcard-fqdn - set wildcard-fqdn "*.verisign.com" - next - edit "Windows update 2" - set uuid b7d84880-5975-51e5-1f81-7f4b3d7a106f - set type wildcard-fqdn - set wildcard-fqdn "*.windowsupdate.com" - next - edit "*.live.com" - set uuid b7d8c076-5975-51e5-5fcd-0dcc80626a45 - set type wildcard-fqdn - set wildcard-fqdn "*.live.com" - next - edit "auth.gfx.ms" - set uuid b7d937c2-5975-51e5-7e01-cd153118d73b - set type fqdn - set fqdn "auth.gfx.ms" - next - edit "autoupdate.opera.com" - set uuid b7d9a1bc-5975-51e5-aebe-4d6e1f702411 - set type fqdn - set fqdn "autoupdate.opera.com" - next - edit "softwareupdate.vmware.com" - set uuid b7da199e-5975-51e5-610a-b85801cb3a41 - set type fqdn - set fqdn "softwareupdate.vmware.com" - next - edit "firefox update server" - set uuid b7da91bc-5975-51e5-ff76-9b8ba864bbc9 - set type wildcard-fqdn - set wildcard-fqdn "aus*.mozilla.org" - next - edit "klaut.cactus.de" - set uuid 80150e34-743b-51e5-321f-e0721eb97511 - set type fqdn - set associated-interface "wan1" - set fqdn "klaut.cactus.de" - next - edit "internal-10.0.0.35_24" - set uuid f0e86136-a9c1-51e5-162a-4ddd2614c9e1 - set subnet 10.0.0.35 255.255.255.255 - next - edit "knappe_10.0.0.15" - set uuid 3f815a8c-a9c2-51e5-52a8-f990f6a6ee9c - set subnet 10.0.0.15 255.255.255.255 - next - edit "tims-macbook" - set uuid 76ca1c2c-aa3f-51e5-e338-6004940e36d1 - set associated-interface "internal" - set subnet 10.0.0.16 255.255.255.255 - next - edit "fritzbox_inet_10.0.0.24" - set uuid aa4c4f1c-bc7c-51e5-cdc6-92416c4f0f96 - set associated-interface "wan1" - set subnet 10.0.0.24 255.255.255.255 - next - edit "wlan_10.0.0.36_24" - set uuid 7d34e11e-bc7d-51e5-4ff4-a8dbfcf4d69d - set associated-interface "internal" - set subnet 10.0.0.36 255.255.255.255 - next - edit "macantha_wlan_10.0.0.37" - set uuid acff38a0-bc81-51e5-fa5d-c38d9414dcc9 - set associated-interface "internal" - set subnet 10.0.0.37 255.255.255.255 - next - edit "fritzbox_oben_nat_10.0.0.18" - set uuid 628f0ddc-bc85-51e5-3066-8de8550bc50b - set associated-interface "internal" - set subnet 10.0.0.18 255.255.255.255 - next - edit "drucker-10.0.0.38" - set uuid 69748926-bc88-51e5-b230-ffb853253374 - set associated-interface "server-lan2" - set subnet 10.0.0.38 255.255.255.255 - next - edit "security.ubuntu.com" - set uuid 1f96dc4e-bcf3-51e5-4cf6-06f71acd88fd - set type fqdn - set associated-interface "wan1" - set fqdn "security.ubuntu.com" - next - edit "de.archive.ubuntu.com" - set uuid 44871eca-bd10-51e5-733c-52c7e5419906 - set type fqdn - set fqdn "de.archive.ubuntu.com" - next - edit "extras.ubuntu.com" - set uuid 8ac0c012-bd10-51e5-c5a7-fc8cd9abba09 - set type fqdn - set associated-interface "wan1" - set fqdn "extras.ubuntu.com" - next - edit "qnap_update_net_10.0.0.39/32" - set uuid 99bd890e-bd2b-51e5-668e-184a9fa02ae4 - set associated-interface "wan1" - set subnet 10.0.0.39 255.255.255.255 - next - edit "www.avm.de" - set uuid e8773fda-bd59-51e5-9feb-d8846d9e9d76 - set type fqdn - set associated-interface "wan1" - set fqdn "www.avm.de" - next - edit "SSl-VPN-10.0.0.40_24" - set uuid 0a8d295c-be1a-51e5-4d4a-e7ff7f94edba - set type iprange - set associated-interface "ssl.root" - set start-ip 10.0.0.40 - set end-ip 10.0.0.41 - next - edit "qnap-update-akamai-10.0.0.42_24" - set uuid 9e1330be-bee6-51e5-4dd2-1a08a875c08f - set associated-interface "wan1" - set subnet 10.0.0.42 255.255.255.255 - next - edit "FG_10.0.0.1" - set uuid f02bb98a-bfa8-51e5-dac7-3e56e1ffe165 - set subnet 10.0.0.1 255.255.255.255 - next - edit "gware.cactus.de_10.0.0.43" - set uuid 201b269e-c1ca-51e5-1e34-7606a8d04098 - set comment "mailserver cactus" - set associated-interface "wan1" - set subnet 10.0.0.43 255.255.255.255 - next - edit "geo-china" - set uuid 2516f030-c204-51e5-9841-1f4a0d2396d7 - set type geography - set associated-interface "wan1" - set country "CN" - next - edit "geo-russia" - set uuid 384a0e76-c204-51e5-05a3-07d31ab3dcb8 - set type geography - set associated-interface "wan1" - set country "RU" - next - edit "fg_internal_10.0.0.7" - set uuid e0650d98-c283-51e5-0279-0c7e5576c87a - set subnet 10.0.0.7 255.255.255.255 - next - edit "LG Fernseher 10.0.0.44" - set uuid d679f9f4-cb5e-51e5-5ec6-6997b7ebd9c4 - set associated-interface "internal" - set subnet 10.0.0.44 255.255.255.255 - next - edit "LG Server 10.0.0.45_24" - set uuid fcb90146-cb5e-51e5-6dae-65477abe574e - set associated-interface "wan1" - set subnet 10.0.0.45 255.255.255.255 - next - edit "google-dns-10.0.0.46" - set uuid 59e13f02-cc1b-51e5-951d-08418456a672 - set associated-interface "wan1" - set subnet 10.0.0.46 255.255.255.255 - next - edit "google-dns-10.0.0.47" - set uuid 62c2caaa-cc1b-51e5-8ee1-d9833983d0fa - set associated-interface "wan1" - set subnet 10.0.0.47 255.255.255.255 - next - edit "opendns_10.0.0.48" - set uuid 518ff984-cdb4-51e5-a65e-a6fbf1dfb098 - set associated-interface "wan1" - set subnet 10.0.0.48 255.255.255.255 - next - edit "broadcast" - set uuid 50c335a0-d09a-51e5-3a94-eba077948081 - set subnet 255.255.255.255 255.255.255.255 - next - edit "valve_10.0.0.49" - set uuid f2de672c-d583-51e5-fff6-ebceb1d50599 - set comment "steam" - set associated-interface "wan1" - set subnet 10.0.0.49 255.255.255.255 - next - edit "valve_10.0.0.50" - set uuid bf3d3b5c-d58b-51e5-4524-7bf9fcb1bb9b - set associated-interface "wan1" - set subnet 10.0.0.50 255.255.255.255 - next - edit "ubuntu-gameserver-10.0.0.51" - set uuid 8b52bd5a-dccd-51e5-8d64-a044e5227624 - set comment "kinder gameserver" - set associated-interface "dmz" - set subnet 10.0.0.51 255.255.255.255 - next - edit "pi_10.0.0.52" - set uuid 914b073a-e218-51e5-a581-faea5587417f - set associated-interface "internal" - set subnet 10.0.0.52 255.255.255.255 - next - edit "wlan_pi_10.0.0.53_24" - set uuid bf3f1222-e235-51e5-88c8-03433bdb0cf2 - set associated-interface "internal" - set subnet 10.0.0.53 255.255.255.255 - next - edit "macantha_at_pi_10.0.0.54" - set uuid b04dffc2-e23e-51e5-4b8d-67cc608d58a5 - set associated-interface "internal" - set subnet 10.0.0.54 255.255.255.255 - next - edit "fb7240_10.0.0.55" - set uuid 7dc2a46c-e852-51e5-84b8-38d00387c72a - set associated-interface "internal" - set subnet 10.0.0.55 255.255.255.255 - next - edit "fritzbox_10.0.0.24_global" - set uuid 8c33963c-0b89-51e6-1241-f0b862831862 - set subnet 10.0.0.24 255.255.255.255 - next - edit "www.cactus.de" - set uuid 11f62ee6-1072-51e6-04aa-7a7606d08773 - set associated-interface "wan1" - set subnet 10.0.0.56 255.255.255.255 - next - edit "gast-wlan-10.0.0.57/32" - set uuid 34991480-3008-51e6-6c11-a6617dbfd69e - set associated-interface "internal" - set subnet 10.0.0.57 255.255.255.255 - next - edit "10.0.0.58_local_subnet_1" - set uuid acee9a08-be0c-51e6-ff4c-d05b94eb2810 - set subnet 10.0.0.35 255.255.255.255 - next - edit "10.0.0.58_remote_subnet_1" - set uuid ad2cbf0e-be0c-51e6-fb9f-d6d0d8c44063 - set subnet 10.0.0.59 255.255.255.255 - next - edit "Cactus-DA_local_subnet_1" - set uuid 8d985a16-be27-51e6-7b4d-a68a60e625af - set subnet 10.0.0.35 255.255.255.255 - next - edit "Cactus-DA_remote_subnet_1" - set uuid 8dadea7a-be27-51e6-06b7-37fa239b17b7 - set subnet 10.0.0.60 255.255.255.255 - next - edit "fwf60-wlan-client-net" - set uuid 7a836eae-be57-51e6-6cd9-57a7bcb8a8ad - set associated-interface "wlan0" - set subnet 10.0.0.61 255.255.255.255 - next - edit "wlan-kids" - set uuid b95fc070-bf0e-51e6-ba04-52463c963ff7 - set associated-interface "kids-wifi" - set subnet 10.0.0.62 255.255.255.255 - next - edit "wifi-kids-wlan-router-ip" - set uuid d80a7804-bfa8-51e6-9012-2be19829673e - set associated-interface "kids-wifi" - set subnet 10.0.0.5 255.255.255.255 - next - edit "wikipedia.org" - set uuid 0018303a-bfad-51e6-3d63-8e86b91e8ce4 - set type fqdn - set comment "for allowing access to wikipedia" - set associated-interface "wan1" - set fqdn "wikipedia.org" - next - edit "google.de" - set uuid 8a9e357c-bfb4-51e6-6ac3-81356d5bb0b5 - set type fqdn - set associated-interface "wan1" - set fqdn "google.de" - next - edit "woehlerschule.de" - set uuid b0128b5a-bfb4-51e6-b707-a0ea0e397828 - set type fqdn - set associated-interface "wan1" - set fqdn "woehlerschule.de" - next - edit "windowsupdate.com" - set uuid e71eadfe-bfb4-51e6-3b29-9df418a8f2bf - set type fqdn - set associated-interface "wan1" - set fqdn "windowsupdate.com" - next - edit "whatsapp.com" - set uuid 10d3e9b6-bfb5-51e6-e599-37b91de688b5 - set type fqdn - set associated-interface "wan1" - set fqdn "whatsapp.com" - next - edit "VPN_local_10.0.0.61" - set uuid 62637d14-c159-51e6-c58c-5f47d2fc035b - set subnet 10.0.0.61 255.255.255.255 - next - edit "VPN_local_10.0.0.63" - set uuid 750b9b40-c159-51e6-0e2c-cae0351e0f4e - set subnet 10.0.0.63 255.255.255.255 - next - edit "net_10.0.0.64_24" - set uuid 7966a47a-c38c-51e6-e4cd-9ef79b13ca72 - set subnet 10.0.0.64 255.255.255.255 - next - edit "vpn-gw-cactus-ffm" - set uuid fcfebd16-f3a9-51e6-9ba2-0a591dd3ff21 - set associated-interface "wan1" - set subnet 10.0.0.65 255.255.255.255 - next - edit "eltern-keller-10.0.0.66_24" - set uuid a36086c4-fa6e-51e6-54c2-7854906b1e8e - set associated-interface "internal5" - set subnet 10.0.0.66 255.255.255.255 - next -end -config firewall multicast-address - edit "all" - set start-ip 10.0.0.67 - set end-ip 10.0.0.68 - next -end -config firewall address6 - edit "SSLVPN_TUNNEL_IPv6_ADDR1" - set uuid b76480a8-5975-51e5-f0d1-b5b0ba854ec4 - set ip6 fdff:ffff::/120 - next - edit "all" - set uuid 72cef204-d63c-51e5-8746-4c0140b699b5 - next - edit "test-ipv6addr" - set uuid ce3a1a84-1065-51e6-fa4a-86517298a194 - set ip6 1::/128 - next - edit "www.cactus.de" - set uuid 2827ec4a-1072-51e6-fd76-346058c066b4 - set ip6 1::3/128 - next -end -config firewall multicast-address6 - edit "all" - set ip6 ff00::/8 - set visibility disable - next -end -config firewall addrgrp - edit "G-google-dns-srv" - set uuid 8c9785c8-cc1b-51e5-dfd9-d129f0df2cf1 - set member "google-dns-10.0.0.47" "google-dns-10.0.0.46" - next - edit "group1test" - set uuid 9510100e-0fa4-51e6-af2b-a73f820b7ef3 - set member "android" "de.archive.ubuntu.com" - set comment "test comment" - next - edit "10.0.0.58_local" - set uuid ad22f6ae-be0c-51e6-f919-40cbf9bfaa1c - set member "10.0.0.58_local_subnet_1" - set comment "VPN: 10.0.0.58 (Created by VPN wizard)" - next - edit "10.0.0.58_remote" - set uuid ad5f2110-be0c-51e6-7669-02c657a3f5ac - set member "10.0.0.58_remote_subnet_1" - set comment "VPN: 10.0.0.58 (Created by VPN wizard)" - next - edit "Cactus-DA_local" - set uuid 8da653fa-be27-51e6-905a-d2c47472178f - set member "Cactus-DA_local_subnet_1" "VPN_local_10.0.0.63" "VPN_local_10.0.0.61" - set comment "VPN: Cactus-DA (Created by VPN wizard)" - next - edit "Cactus-DA_remote" - set uuid 8dbce926-be27-51e6-ce37-835cb6d31f1e - set member "Cactus-DA_remote_subnet_1" - set comment "VPN: Cactus-DA (Created by VPN wizard)" - next - edit "kids-allowed-internet" - set uuid b5c63d9e-bfb4-51e6-c815-aee3bb9739e7 - set member "google.de" "wikipedia.org" "woehlerschule.de" - next -end -config firewall addrgrp6 - edit "ipv6-testgroup" - set uuid d8d64e08-1066-51e6-1721-60ca3eb7141a - set comment "commentar334" - set member "SSLVPN_TUNNEL_IPv6_ADDR1" "test-ipv6addr" - next -end -config firewall service category - edit "General" - set comment "General services." - next - edit "Web Access" - set comment "Web access." - next - edit "File Access" - set comment "File access." - next - edit "Email" - set comment "Email services." - next - edit "Network Services" - set comment "Network services." - next - edit "Authentication" - set comment "Authentication service." - next - edit "Remote Access" - set comment "Remote access." - next - edit "Tunneling" - set comment "Tunneling service." - next - edit "VoIP, Messaging & Other Applications" - set comment "VoIP, messaging, and other applications." - next - edit "Web Proxy" - set comment "Explicit web proxy." - next -end -config firewall service custom - edit "ALL" - set category "General" - set protocol IP - next - edit "DNS" - set category "Network Services" - set tcp-portrange 53 - set udp-portrange 53 - next - edit "HTTP" - set category "Web Access" - set tcp-portrange 80 - next - edit "HTTPS" - set category "Web Access" - set tcp-portrange 443 - next - edit "IMAP" - set category "Email" - set tcp-portrange 143 - next - edit "IMAPS" - set category "Email" - set tcp-portrange 993 - next - edit "LDAP" - set category "Authentication" - set tcp-portrange 389 - next - edit "NTP" - set category "Network Services" - set tcp-portrange 123 - set udp-portrange 123 - next - edit "PING" - set category "Network Services" - set protocol ICMP - set icmptype 8 - unset icmpcode - next - edit "DCE-RPC" - set category "Remote Access" - set tcp-portrange 135 - set udp-portrange 135 - next - edit "POP3" - set category "Email" - set tcp-portrange 110 - next - edit "POP3S" - set category "Email" - set tcp-portrange 995 - next - edit "SAMBA" - set category "File Access" - set tcp-portrange 139 - next - edit "SMTP" - set category "Email" - set tcp-portrange 25 - next - edit "SMTPS" - set category "Email" - set tcp-portrange 465 - next - edit "SSH" - set category "Remote Access" - set tcp-portrange 22 - next - edit "SQUID" - set category "Tunneling" - set tcp-portrange 3128 - next - edit "KERBEROS" - set category "Authentication" - set tcp-portrange 88 464 - set udp-portrange 88 464 - next - edit "LDAP_UDP" - set category "Authentication" - set udp-portrange 389 - next - edit "SMB" - set category "File Access" - set tcp-portrange 445 - next - edit "webproxy" - set explicit-proxy enable - set category "Web Proxy" - set protocol ALL - set tcp-portrange 0-65535:0-65535 - next - edit "ARK-7777-7778-udp" - set comment "ark beta main ports" - set udp-portrange 7777-7778 - next - edit "minecraft-25565" - set tcp-portrange 25565 - next - edit "afp_548_tcp" - set tcp-portrange 548 - next - edit "bittorrent" - set category "General" - set udp-portrange 6881 - next - edit "tcp-8011-to-avm" - set fqdn "www.avm.de" - set tcp-portrange 8011 - next - edit "tcp_40000_up" - set tcp-portrange 40000-40100 - next - edit "tcp_8081_phpfreechat" - set category "VoIP, Messaging & Other Applications" - set tcp-portrange 8081 - next - edit "steam-udp-27000-27050" - set udp-portrange 27000-27050 - next - edit "valve_udp_52626-52627" - set udp-portrange 52626-52627 - next - edit "valve_udp_45993" - set udp-portrange 45993 - next - edit "valve_udp_45433" - set udp-portrange 45433 - next - edit "valve_udp_3478-3480" - set udp-portrange 3478-3480 - next - edit "udp-high-ports" - set comment "1024-65535" - set udp-portrange 1024-65535 - next - edit "ark-udp-32768-65535" - set comment "dynamic port used for user session to ark server" - set color 1 - set udp-portrange 32768-65535 - next - edit "steam-tcp-27015-27020" - set comment "steam update?" - set color 1 - set tcp-portrange 27015-27020 - next - edit "test_service_multi-port" - set comment "test comment1123" - set tcp-portrange 22:1024-65535 143:100-200 22123 - set udp-portrange 68 889 789-891 - next - edit "apple-netscan" - set category "Network Services" - set udp-portrange 192 - next - edit "fortinet-captive-portal-auth" - set tcp-portrange 1003 - next - edit "tcp14013-fb" - set comment "fritzbox parental stuff" - set tcp-portrange 14013 - next - edit "tcp_5357_samsung_printer" - set tcp-portrange 5357 - next - edit "ARK-7777-7778-tcp" - set tcp-portrange 7777-7778 - next -end -config firewall service group - edit "Email Access" - set member "DNS" "IMAP" "IMAPS" "POP3" "POP3S" "SMTP" "SMTPS" - next - edit "Web Access" - set member "DNS" "HTTP" "HTTPS" - next - edit "Windows AD" - set member "DCE-RPC" "DNS" "KERBEROS" "LDAP" "LDAP_UDP" "SAMBA" "SMB" - next - edit "Exchange Server" - set member "DCE-RPC" "DNS" "HTTPS" - next - edit "valve_ports" - set member "valve_udp_3478-3480" "valve_udp_45433" "valve_udp_45993" "valve_udp_52626-52627" - set comment "valve game download plattform" - next -end -config webfilter ftgd-local-cat - edit "custom1" - set id 140 - next - edit "custom2" - set id 141 - next -end -config ips sensor - edit "sniffer-profile" - set comment "Monitor IPS attacks." - config entries - edit 1 - set severity high critical - next - end - next - edit "default" - set comment "Prevent critical attacks." - config entries - edit 2 - set rule 29519 - set status enable - set action block - set rate-count 1000 - set rate-duration 10 - next - edit 3 - set rule 20940 - set status enable - set action block - set rate-count 60 - next - edit 4 - set rule 35662 - set status enable - set action block - set rate-count 200 - set rate-duration 10 - next - edit 5 - set rule 12090 - set status enable - set action block - set rate-count 500 - next - edit 6 - set rule 42016 - set status enable - set action block - set rate-count 35 - set rate-duration 10 - next - edit 7 - set rule 20954 - set status enable - set action block - set rate-count 60 - next - edit 8 - set rule 20946 - set status enable - set action block - set rate-count 60 - set rate-duration 10 - next - edit 9 - set rule 22909 - set status enable - set action block - set rate-count 200 - set rate-duration 10 - next - edit 10 - set rule 17991 - set status enable - set action block - set rate-count 275 - set rate-duration 1 - next - edit 11 - set rule 38273 - set status enable - set action block - set rate-count 20 - set rate-duration 1 - next - edit 12 - set rule 31464 - set status enable - set log disable - set action pass - next - edit 13 - set rule 29707 - set status enable - set log disable - set action pass - next - edit 14 - set rule 31101 - set status enable - set log disable - set action pass - next - edit 15 - set rule 29020 - set status enable - set log disable - set action pass - next - edit 16 - set rule 29695 - set status enable - set log disable - set action pass - next - edit 17 - set rule 31433 - set status enable - set log disable - set action pass - next - edit 18 - set rule 29808 - set status enable - set log disable - set action pass - next - edit 19 - set rule 14558 - set status enable - set log disable - set action pass - next - edit 20 - set rule 29929 - set status enable - set log disable - set action pass - next - edit 21 - set rule 24608 - set status enable - set log disable - set action pass - next - edit 22 - set rule 29651 - set status enable - set log disable - set action pass - next - edit 23 - set rule 32130 - set status enable - set log disable - set action pass - next - edit 24 - set rule 32852 - set status enable - set log disable - set action pass - next - edit 25 - set rule 28070 - set status enable - set log disable - set action pass - next - edit 1 - set severity medium high critical - next - end - next -end -config web-proxy global - set proxy-fqdn "proxy.gelbeshaus" -end -config application list - edit "sniffer-profile" - set comment "Monitor all applications." - unset options - config entries - edit 1 - set action pass - next - end - next - edit "default" - set comment "Monitor all applications." - config entries - edit 1 - set application 17459 17244 - set action pass - set log disable - next - edit 2 - set category 2 19 - next - edit 3 - set category 6 22 - set action pass - next - end - next -end -config application casi profile - edit "default" - set comment "Monitor all applications." - config entries - edit 1 - set action pass - next - end - next - edit "sniffer-profile" - set comment "Monitor all applications." - config entries - edit 1 - set action pass - next - end - next -end -config dlp sensor - edit "sniffer-profile" - set comment "Log a summary of email and web traffic." - set flow-based enable - set summary-proto smtp pop3 imap http-get http-post - next - edit "default" - set comment "Log a summary of email and web traffic." - set summary-proto smtp pop3 imap http-get http-post - next -end -config webfilter urlfilter - edit 1 - set name "default" - config entries - edit 1 - set url "r.adc-srv.net" - set action allow - next - edit 2 - set url "mzstatic.com" - set action allow - next - end - next -end -config log threat-weight - config web - edit 1 - set category 26 - set level high - next - edit 2 - set category 61 - set level high - next - edit 3 - set category 86 - set level high - next - edit 4 - set category 1 - set level medium - next - edit 5 - set category 3 - next - edit 6 - set category 4 - set level medium - next - edit 7 - set category 5 - set level medium - next - edit 8 - set category 6 - set level medium - next - edit 9 - set category 12 - set level high - next - edit 10 - set category 59 - set level high - next - edit 11 - set category 62 - set level medium - next - edit 12 - set category 83 - set level high - next - edit 13 - set category 72 - next - edit 14 - set category 14 - next - end - config application - edit 1 - set category 2 - next - edit 2 - set category 6 - set level medium - next - edit 3 - set category 19 - set level critical - next - end -end -config icap profile - edit "default" - next -end -config vpn certificate ca - edit "CA_Cert_1" - set ca "-----BEGIN CERTIFICATE----- -MIIC0jCCAbqgAwIBAgIEalWQfzANBgkqhkiG9w0BAQUFADAaMRgwFgYDVQQDEw9j -YS5jcC5jYWN0dXMuZGUwHhcNMTUxMjAzMTAzMTI1WhcNMjIxMjAzMTAzMTI1WjAa -MRgwFgYDVQQDEw9jYS5jcC5jYWN0dXMuZGUwggEiMA0GCSqGSIb3DQEBAQUAA4IB -DwAwggEKAoIBAQCP1TLAqe2zZ3kc5QMQZw0sztoXtGBU7910QdQReiuEDjN+Mlbg -/2COaMPcZH5nhaSib2+R/LNdWhfJvw6zObgrRjhMcWoivOXmnQH52fkPrvJtIBBx -VWvtrI6/M4uU4meOm/4F2JeBA6JAuaLnMAIjF+DPtmABGmn4ntufGUg9Y78QI3cE -22etSR0uNFs13xx1JOtSwY2MjcyPDOedxEyJBR8f1MsMqZhWCUArWkb18VmGhSz1 -EYHya4FYx+o6IBU8ysuFvs8fjUBW+7EYaBbcqLZD9wHCdb+VKxXn+eO+z4IlO+al -XlChLXbZbTRlVp32WoY/ZdhCQuPspmT9vwh7AgMBAAGjIDAeMA8GA1UdEwEB/wQF -MAMBAf8wCwYDVR0PBAQDAgGGMA0GCSqGSIb3DQEBBQUAA4IBAQAbBA2jqOIaTQsq -eIUUtpXz5wYlUkfDwlOEhwWlvAlGAnlvYP6f3ZqCMYal4cNgpAUfDI7YHJ4L0Uoy -uhi5Mj5wQ7tVVaNZvNsBc73Q9c5gD2YBmtObO2GVDPqSMR8g4aTSqPb7QDBOO1yI -U3u5H2FlVB1+h/YpRFqm1AdlgdbzlwOvVdH7/5uOB5+DwGK73pZ5mwh2Dkm3fNzk -eRqd3SwmJReK771UWU8tSS6PNzw6WupA+SdLWlRvWiqDkoXB8jkPcOGrWHepYb5D -F3DMYVbmp+ivB465+N8a4BJ06MytEaJAPj0sDM9R88xNPt4ss90AKIEWGKgLb66p -cvJH+/AS ------END CERTIFICATE-----" - set range global - next - edit "CA_Cert_2" - set ca "-----BEGIN CERTIFICATE----- -MIIFtjCCA56gAwIBAgIIbO9Gi4dAwVQwDQYJKoZIhvcNAQELBQAwcjELMAkGA1UE -BhMCREUxDzANBgNVBAgMBkhlc3NlbjEeMBwGA1UECgwVQ2FjdHVzIGVTZWN1cml0 -eSBHbWJIMRUwEwYDVQQDDAxjYS5jYWN0dXMuZGUxGzAZBgkqhkiG9w0BCQEWDGNh -QGNhY3R1cy5kZTAeFw0xNDA5MDgxNTQ1MTlaFw0yOTA5MDQxNTQ1MTlaMHIxCzAJ -BgNVBAYTAkRFMQ8wDQYDVQQIDAZIZXNzZW4xHjAcBgNVBAoMFUNhY3R1cyBlU2Vj -dXJpdHkgR21iSDEVMBMGA1UEAwwMY2EuY2FjdHVzLmRlMRswGQYJKoZIhvcNAQkB -FgxjYUBjYWN0dXMuZGUwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDV -KexJ4XeQTxPDNEPMKmu6ahgJIc8BPlCdV9zWskGcgvSxlNY43lOZGBYuu5Kb3y8T -TC/ikGFcHccmC0xaGwpZcxhFyElKgFbKVf8BrjKBgSVoHE7yMDI03NGipxcAZw94 -SX96Ys8QlxpV7xfGVloVMgKxmEZTE6oR2IGmG7JZMDGGs4j773kzkkCgTzgSbp4B -TJsiZFOmL81x7Bf9KCuPT7Yb+OQmo2F8sPHr6ucxW21Z2Xe1WJVmuNoSShlFrwWE -RaMlGt3+Db3NxFQetWIrTrjKbqDJLCXhcK3Rmdy86zBTrPMhscT1lQb3Dvm+YC7a -ZBXnagZhogPeTT7Gx05THTsDZtWoPyFTkgIMvMXy26sBcfq9VnBD/o2kxIi3Aqs9 -0tDgiQAsb/jci4yH7VGJT/TAo10HiBthqEDPYk60ro1w7oniDsxAA3acUaA+R/4F -mJ/BSfIvaRFGwMUCy80/qnxY3IwoVTpeuJysGHG6rbjPkjJUvtmmYTSeF3RmYJnK -fbchO0tc4Ug8VFuK4k2quNvAAR3FJIOxXNbr3I7RKNKMeGtF/HixeM0htylN9euM -0myw1IqsaHrnuNwsNvyfuL9NncdAOwkG/iVdAC+FFDodFWoR0+KlJoAZ801KNf7L -JBp+eStkQsQE5DuvS+Mcf6+BxhNBWuyICPIlUcFEkQIDAQABo1AwTjAdBgNVHQ4E -FgQUfh8NIoEhiLCObeE3WPZ3iUSo6kYwHwYDVR0jBBgwFoAUfh8NIoEhiLCObeE3 -WPZ3iUSo6kYwDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAgEAsVigHPVq -jc+vipxME7p4GZbHYDaURMBdKRhngvgY9K+04VdP4c8quhgJAZYtTkiWKkl4vB98 -7M8K3vlShJSTqkqJ4Fu7iuotBuircqk+ALGvSOeTdnt4hXf9t0OxjDRY+lCI2dx3 -PH/aa5TMLJ/ZAvHf13o041wLa1pzvDDt7u2RbRy62GqRHXuuA82QAtdYznJ221Rq -QalD7+XORU20jmLW9muS9Khre9IELOnyE+m9XzfttD8bjgGEi/coxBVZ/rYTrvIG -USdQge2vYY3+d3+49vh9tKP/Gd0amiTfs1LyabQtQK9lJviOob4g+/zVbu26Aymy -LZ295T4+uzTYow2+IKRMjnhOVwufqPz5Ooo5ZZ1QgCevSne0392TPveXkGiskIXr -T1e1Pqh2zXBgeHUkbSbJ7/YqrZGqE7mxYc+yGnQAacqxBoMnvLTZVjW9rHkZT6Ad -l57RoG95v0AEAGqcoP9NJ7hidevSYxY6AQ4Fz5ec9kS+qmsXB4kQzk+pYH2dSFv9 -ieM8bSPXYSKRgISS9m2VMItaZ/YQKGdE4OpAaYIAMkfOTrRXdU8cphUnb2/dUwAF -IQisaaSrn+XCkOB1c5kEnFSw/B/HJRPoxIw6gbD3i9cq7YrcAFg54rm/CS6s4CMd -iaqgMESu2NxnaC7tpme/G4lpI63vKtGO1nk= ------END CERTIFICATE-----" - set range global - next -end -config vpn certificate local - edit "Fortinet_CA_SSL" - set password ENC WsTjIWD+q5eqie5SnqV07g6Ut0/KI8al3XS292qN2xd0in3dGS+pks8w+N4MrBW9TitbAuc3q2MHWtfIAKflvwRlnKpwSaaWsJ+lQjDPOZ9dO7Dymzn+wp6JOClcUcQVLDTwBFPFfvYe0UUNIsZBEaNWuEtgyYJrNPDkpR5dP8ETM/2NSykQV7g8D1DxSDsJL23Whg== - set comments "This is the default CA certificate the SSL Inspection will use when generating new server certificates." - set private-key "-----BEGIN ENCRYPTED PRIVATE KEY----- -MIIFDjBABgkqhkiG9w0BBQ0wMzAbBgkqhkiG9w0BBQwwDgQIqxPd/BHhF4ECAggA -MBQGCCqGSIb3DQMHBAi5wpLR+Ve1hwSCBMiPBW0sp/HIZpAVX5ITik2mHwlpE+CO -aF6qlaCyWLpI566u/syZgOQ/JRuEDzddyo9vsTILRNCJwlrWFlSFHPrFCql/hrXG -MwbhsCWa/56mqcyyUAY73niPAvcmBNATueHe2RNWDYEJWDTghfQatbaKhhUDKojz -OYv1PDjibFcUNNnyu/26ud9Ad8vzxH/oD0uI3jOadEr9YLubWioFeahel9qidOPi -QDT0fqD8skaRIXSVQrpwLguFrtNANPOBVoRAOiKcWlBRSPuaQ4obfmrL3eAVUr3U -LCMIDBSJfd0v62bMGa9VZFf3XF+7giN9tg7OWV6yGtSdnsnF/6imtnb6bUuGzdUO -Y/8XrWjZE5a5vyQwqTn0kI6wsVLx6JVMthyZkaOXll8F88Qkjuw8h8cmZvIcv6k8 -CrYU41LXezTHDCD3pq8inQVA6VKpdKiKOmsD0qH/wfAGBKdUIfo8p5tmpJrdhA92 -MDJrmjmulvg+CTbb6g3ovuHrJY6hGk0o+RV/bTneNwj2wPMclF/t1tjX7b8pwgoq -zLPuk72UuC6C/4p3MjiMEItCynIOPsALFBSQ9kvnhPXTdXfrh6L8Qn0Tn+FRTpC7 -pNt4hDO4PReUrOtFousswOnuqoV9XiXLppEGrX20soip24TDsLS+W6haiO14T8/h -cR/Uts9Uy/AXeKeH7D6agde4LHPvfpMizRrlDHx3OBQ4aJ7AasTz8vEsyfQ498cV -iy2bMIBp7yUCFzzomu5rrik3QZgoTIDgkKl6O1CUTUlMMeNDJYyAAqSN+9O6VL+b -mLyFNZ9BO3Xth+KWypeqrCDsa/PJi3bhjJ7pIuNgt87av2I/5E9B1kNmkXlloOvk -UpQAoMcwVJuYoqTWtaCxVcMrUr6x+08qiWqh309pp4RLQnCHDshhaCuMQ4YZyD8X -kYp7frX55RAwyXdAyQWk2sT8x74qUWF6aigPSESzFji45UmrgxQMAMm7KRDSxGG2 -xt9OJuDCipCC6CP4dCNQRfT7mzshg6QTGdemJBbNBAqbjukMFbXutmEdtazwh+fX -ZkfNqT29IoceXdb/p3apGO9OZAXzw0Nwzj3UU8iCFu4y9DGQ0LfwovvdGCaCDx7y -LBpMMRhhBQxnuiHHt0WfBOp5Z/bK4KL+4Fgo3oUg29sDI+KBegS7b/s6+7d0201e -IdavbTWLjwzizaAvf9mUvyCZ5HWHzS25QHm6xCSFSUvxOJWl1YJ46CjftFH3c8qv -56gu62Ycsm2h4FojP5ASOKxCEQv3WweDvF1iieeZnm1SWv/1zn2WBo86N8W12hhx -h7dkjfRJ5304w/Tx0wLXGTQ8c8iPclElR5rXfCydnHz8NhTuP689OOx3iEIyJN62 -dsonSsvB7NEWpHSwqcL33iG4FUCqoQrtAhmstxrV+0EQY4ZvWWU8qqATUKS/n/hh -g3sinr8EGWxCDiefJVuR3yc6QkDYCaRFXBorb7uZGJEDadxmqJN2TIg+9g4OY9eQ -v/BbdFjnmuwTPzF6euKW7YAosVM8Dm6hhHOZG2bu9JLIvZ27fsgFKuHUoNHAVg7x -jEs0NdPh8y8QwDkS+ld5ev7sT499jeyJetZC+ZtUj0Db77VmUdBPGPrf7iyY5eqW -op4= ------END ENCRYPTED PRIVATE KEY-----" - set certificate "-----BEGIN CERTIFICATE----- -MIID4TCCAsmgAwIBAgIDTFGwMA0GCSqGSIb3DQEBCwUAMIGpMQswCQYDVQQGEwJV -UzETMBEGA1UECAwKQ2FsaWZvcm5pYTESMBAGA1UEBwwJU3Vubnl2YWxlMREwDwYD -VQQKDAhGb3J0aW5ldDEeMBwGA1UECwwVQ2VydGlmaWNhdGUgQXV0aG9yaXR5MRkw -FwYDVQQDDBBGR1Q2MEQ0NjE1MDczOTYxMSMwIQYJKoZIhvcNAQkBFhRzdXBwb3J0 -QGZvcnRpbmV0LmNvbTAeFw0xNjAxMzAwNzQ4NTZaFw0yNjAxMzAwNzQ4NTZaMIGp -MQswCQYDVQQGEwJVUzETMBEGA1UECAwKQ2FsaWZvcm5pYTESMBAGA1UEBwwJU3Vu -bnl2YWxlMREwDwYDVQQKDAhGb3J0aW5ldDEeMBwGA1UECwwVQ2VydGlmaWNhdGUg -QXV0aG9yaXR5MRkwFwYDVQQDDBBGR1Q2MEQ0NjE1MDczOTYxMSMwIQYJKoZIhvcN -AQkBFhRzdXBwb3J0QGZvcnRpbmV0LmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEP -ADCCAQoCggEBANj9KNZIvtds0RW3A9EaUXjW4HWNKbN0J/zdQVyGID0GNezz9Gnl -wTpCV9o8rXc6g2Us/5ZrXY3tSUU9wkpMs0wSiqbSNutq/Xci2957JEw7Lp7D+MpG -tkkmqxK/ZLGjhHVrYQgzH1p74KK6jqtCvJ9My/vj4t8YHWHVh4fxV3M+/NdgVwRI -7+FqXQHpuHoV5P7/tSMLQts7JEXujeBKO1eFGTNItUoayeWdq9bUM3hdiadHLfdO -SrpudtO2wc4TQ5qvaC/nDzMjBq8tP+t99r8A0veyXbdG2jEtIFNJfg38Kj3fQ/5/ -ZNhtrJ3LgyrbC9bgeKIkQ0Nwr+sHUFmWmlsCAwEAAaMQMA4wDAYDVR0TBAUwAwEB -/zANBgkqhkiG9w0BAQsFAAOCAQEAzljgZ5CmiIAlNuuFnjCdDDZZTgTobweNxtPl -qVxUWSefR9NeQ/WC9sZVd0+rp1QCfZYJacrISdpwXfROmjALJve8cSS0ovqPw/ZB -XAVsDXfQ55SASIy9fsXOiemJJHSbXG9amZmbwCCcZPeTqZb4gmHnWxrZsJ2hzWh2 -soxsquPagZg+3bvxJQlkl3Gxo1dyTDzzEe46DVTYVPhbADyvFYwooXc4EUMZ+EIA -nz3k3pfXTnITDESWqQa/Vv2xlHuyqYrniwW4oyQyo90syVsDBP5QCsXL7IuwJ771 -LSaT4apGhhgPqvzPi8Pi4kWEcNQKgvARHh2L+oSssVMtzvc0xA== ------END CERTIFICATE-----" - set range global - set source factory - next - edit "Fortinet_CA_Untrusted" - set password ENC PixT+x8i3Z8Mbf9PJ6cXSnP6SZax2wrpiAS37c352bOJk8IJIbC2bpB7WDeR80hibXI9QBmr0lS2m1Dh0oqE5sNZWMzGfHCy99wN/QihFaaobpS3NkTs35xqMcr0zKc6ktdRo2N3+SHjKwUp1wCT3kIBJZ+PDa3uFd6hOlF4MsZg4EiAvY54+9HdPE7fhTsz4Hc9hA== - set comments "This is the default CA certificate the SSL Inspection will use when generating new server certificates." - set private-key "-----BEGIN ENCRYPTED PRIVATE KEY----- -MIIFDjBABgkqhkiG9w0BBQ0wMzAbBgkqhkiG9w0BBQwwDgQIM7p4tJeK7xwCAggA -MBQGCCqGSIb3DQMHBAjtkT/PqvBKmwSCBMiVMM7QB4tdRG9sBcrO+xoEKA+3oLCH -MLHIt2fzm2zp8KHacS6hAAzH6D0kKHmh9aviTPVT3E+gLmeyjJio4OehtuIiWV+f -Cv8eWuqsi1XjuX8QFwZblXRBJeQORLIEWM+Yc1JTN+aGDLpEVrb2eRns6N/vKWmB -4kjgObazsTuDld5vzOZyoScmrXEOBqBVbeYDRFnKjbIDk47hD6p8ufXkdipONgu+ -B3G11CZ6AVguy7ZutJNJW8qJpE4GzX7NBIqcLkDzW5AQl8ncBOP5ya5OsG+MEDQh -3pTBJkNiqpODoeqDQxiUGHWHDSEBtj2tKLC8mGJ7Lyz0s7kzj0cYDPITzYAB9N7t -lTGfoIV4f8Hv6ExoNP+dlkHnwu/ZWK41M/U3ehfHnyqj6rqKtnSB2H5AaEyajn+q -mMCUuEw9o9DMGlYOHfJC6eRYVqrMO8FGNFDQIB0GBka3rOapnb3bsfqIVu1kwyMe -YKWbu+GbAoLBKDcylg1JLdSoWOSnEU3d/VxX9isJOlBQ0IqsjjYesFDDWjfJZinm -OeCY8eg/AKINdBoVOLvmdItDQvD9UAaqMRcL9Zu18hucF57422Mz/x8kBdYKjRdY -7VkXeJEXcM/8niSgzDT/AClPUYM1Oe/k1tMgYiBZ6IB8HpU/AnlN9nl+LgbcRCS1 -ykcxOAVoBySffsKOy5P2jYvkA7j+5iAjX6UuCxt4/XRL0wwBhbdrbrWqVD2svl59 -Ri+8wTChBP9HjWIP+jvO0OJbaWTqy3IBX9Yooo7jY1MIHYf+smxgklmfEwB1jv7Y -+wxH8RE+3YZU7nxpD5Ew12QKAlstMBKr5uj/XPSF3GB8FlnBgrdFKK/OI0copRZX -44ShcPqtTVqg+YQw8/eEhDVZAd5SMEO/K7q2lTi4EI612RyLP1h66JMK46rwv+fU -L4VBsS5h/9NEgB0bp/hVGCStXOadxrhFe7vsVzWhQ1Q0OhWHMwq19qQksrbMvn0v -NyeT+6p++/uUxEbe9IHq1jdEXNLs+hyz0pPccUcGehKbSIdS0pbCK1Z0cerWh6g5 -jyO4ZEYtchcHl/DJyS3BfdiGRWYsb5yD33WSMXhZ+sYecAN5NhN+Bg23j2fF7P25 -fHHAB6VW7XqnqOuVqA2h+4BqrmBz3yzr7DxjvVSncVwd/m4xby1F6tGnSYNvIqeG -8Tyi2x1aqDd2qepjBEqsRjyZsyDoESz4FohBdoufgkHDuG+8GKqjIc040cUnD9NU -umjKpnPAuw7XcHkYHnGI9Sy+RZE+fEp8n4lZ59L/Hi1thIS4aEhvf2lAQaoT3PqV -GLxR0fkOhwIhZXK8ph85SpAHCT2qZy7R+GLLfXqtN1Eb4TCJkPCtDC5etXprkf83 -rV9QopafgoekYHLY+8hRCbzfQ117Q3VphFsL8f7c5q97Tu5h40YkGveML1N+oNdz -0G45JV/i8uOMq8TNdVNacS+VFctyUV4U7LjbU+5MzbYXYQ9UEAEooRUSDHKMtlYh -nmEJ+xzXQyJjEp30/fDvC2mMCRpjQczuL1E3Ta5mbDvEJcjXxRAr1Wv9YZsZjfL1 -NBaJvHOLFITZN7kSa9FOUIna9WfphsDrLyeW72rkdvl1fjaNM46srt+LtlT2g9rT -VPE= ------END ENCRYPTED PRIVATE KEY-----" - set certificate "-----BEGIN CERTIFICATE----- -MIID7DCCAtSgAwIBAgIEHuEGzzANBgkqhkiG9w0BAQsFADCBrjELMAkGA1UEBhMC -VVMxEzARBgNVBAgMCkNhbGlmb3JuaWExEjAQBgNVBAcMCVN1bm55dmFsZTERMA8G -A1UECgwIRm9ydGluZXQxHjAcBgNVBAsMFUNlcnRpZmljYXRlIEF1dGhvcml0eTEe -MBwGA1UEAwwVRm9ydGluZXQgVW50cnVzdGVkIENBMSMwIQYJKoZIhvcNAQkBFhRz -dXBwb3J0QGZvcnRpbmV0LmNvbTAeFw0xNjAxMzAwNzQ5MDNaFw0yNjAxMzAwNzQ5 -MDNaMIGuMQswCQYDVQQGEwJVUzETMBEGA1UECAwKQ2FsaWZvcm5pYTESMBAGA1UE -BwwJU3Vubnl2YWxlMREwDwYDVQQKDAhGb3J0aW5ldDEeMBwGA1UECwwVQ2VydGlm -aWNhdGUgQXV0aG9yaXR5MR4wHAYDVQQDDBVGb3J0aW5ldCBVbnRydXN0ZWQgQ0Ex -IzAhBgkqhkiG9w0BCQEWFHN1cHBvcnRAZm9ydGluZXQuY29tMIIBIjANBgkqhkiG -9w0BAQEFAAOCAQ8AMIIBCgKCAQEA0jqUKDC7Zl7pw+Sq6aYUIzONSsOAd+V4B3rS -WeBoJWu57BiabRwf3eXeNpyFVvKWvUECUNdG92fJJHX9p9yW/+EjMUhwFX85cC1O -b78O/n4Y2N8jr318Wl8GGtdoCSsXVvJuUm3DIF8BexkjSYoIqzPgSAutH+ZaMssx -lw5u328YWq9VTTJCi1jZMkfSIMAdIerJtvnX4gwSLATJ2Z9Ganav/9+/iyzgUiD8 -395z5hCxLh8Kgn23jGV/V3AXZgQ2tBCsZ0dH4YswzFSs9CpMbYOIy57AGUaiMPeo -0/kDOybSHeFfLN2IQXil0kwcYCQX8lCrsA6F9ER5XVuJ5XpDywIDAQABoxAwDjAM -BgNVHRMEBTADAQH/MA0GCSqGSIb3DQEBCwUAA4IBAQAItgnIjTXno8Z8ilLP2+db -e2tAL/mpNjfHIG/Na/Kx+T8Wou3iswP+AapBXx/kD5mPpylGcozHpBD62V7XK/V+ -Grgfa3bhosBof8CZtQyiTdj0+ZCiXbAOlcyoxZTxcfmzCZXAKu0QVCjvbBbAOUf0 -KEVzzIeG5QkS1v5nINqDVxAiEuYS/B1ky4UwgbEQAKNxKypBg+yCczRAY/99RbCu -qt2ikwgMFAhY4esGlb3Eb1UYcqqdweXroWcnPm55v+XeQi6fI05UU3UwUuldAytW -75lX+KFW/+TV6MQPf0SziWET/jB+tOOkhZzqpbJABdXH4NNHAxngKVAE30dFcZAt ------END CERTIFICATE-----" - set range global - set source factory - next - edit "Fortinet_SSL" - set password ENC P9hD2nZ/Kf4eA8aFylZyFOPEZf+fqR6ae3Hsc3fRjws/sicBxq7BozMNlM+Zi9OQQdCrLgqqyvYIo10ksqyiISSrWgCSLwRJEAMrbFy8UiafrgC/34+RtAWcDjCUPcinSEnF7VPunlAfFlOHFjXO+shnweI0GcgSko3M4C0yhd/7W6rEcZePld+oKlHUDoC3HQRz3Q== - set comments "This certificate is embedded in the hardware at the factory and is unique to this unit. " - set private-key "-----BEGIN ENCRYPTED PRIVATE KEY----- -MIIFDjBABgkqhkiG9w0BBQ0wMzAbBgkqhkiG9w0BBQwwDgQIy19/6owCFSgCAggA -MBQGCCqGSIb3DQMHBAihRF7XfH0WEASCBMhQQYcF7oZEw1GTvWHYBgnR7MaD/vsX -VjRBDDhaY5Z9F9AN/y7zWrpUau/qkswAGfzirH1eHXBpnTLpc8L5dQvEyddN4Amn -PBXEy6iX3iK6S93bzmgHhaj+CWSGkeoNcwAm20jbWnrN0eUzkZm5eX0s48IeO7Kx -cGHBd5HkqHbIHJR97UYD+L1aTPgIR1V9Ejp7Fd2x29dCkknfKXU4oG2Jw2o4D0dM -tmk0yqSLtTYDfOvlKCIK1GyKfNOOAS0AzPF630wKk3q353dpza6pbDETqaNu4Nt4 -Le3WqiJ2pNwJvAcowoshraOsB6uY1botwoT6bHnYuILLeP6+cMtRJEYi2NoaPhIu -Ga89vPzNdHlge6qSaDmRY+4xpoxXnV0Q0wa2sOWooWcpwH/3LwwkeZn0g3ZbMESs -lUu9x1U3Qcn4eOAzsA66XuvxITSq760hOYtaCmE9vXTIPJOfjnmpo67elwfzavj+ -UWtZ0QHChCu1p9Tt1BA73byrlqLUHIxHU774qh/ObvhkOqfVZGz/g688wvlh8/p4 -5M23HIpf4swOiS/d31iV9r3i7hvEDh86o9LQv3355wnPAYD7v0XzkPwcIy5+YW06 -Yt2qdbITGlrHyDnpDHcK7rorsV0WPATykoOqDOd5cg7vwtM6O90vxNxTaWe/rlEi -3JmltWV4eczW3hNls2MV5dNrlXCT5RZ/g+HmyDiMGdc9se3QAPN2uxJ86Gm6/xN4 -pKfwZ5/RUeD6sJ2p7NOTbz0Yud7j3Vr4DusRoPnwY1on8T9YTMjckodKdDxFUnGr -uzqU1GPiJSLVvvH5Jy9xCSjPGCSnDS/Pq+vR1WBW9ppJ12mBLeYZgQiQpKHplZ2m -NvAKEIzRNtsyawkN9CwnA9koIKpNT4HqOu9k7fT2bgNgLMFpRXolNXtm7C4xOkDm -rKef3PE2jPeZUfEoF8u7gsdZoJ7o22zw8VWmLrkXgesR7fxkydHf/uUXtqooktJZ -PQ+qFXP3EJXPkCcqz/lGO/uvM2w6fOQw4BeEL//+KsqihDXVm+4cr9RpB3nTBCPY -lJM2nylOgQpbuKOAnUuaTT8sfucIXNqk1/6Q6MwTM5W2oPNxMaeYRt7yYWaYk6Uj -tjEPUn0ezv1q/8DcPtVOMOZ5a6y8glw7GAUbs8uDzkfpQMoihW+8wR4Z5N5b+STS -4pzl8NLTl44F730dnPqo1J6wKcx44N5/GiA8FZbGGkWVBMBHRYOvoESbpgiT/X6i -ct735lbWYI864s3uITLl2mBOh8lBp65V/1BZEucJiK3cGLfVOCJUGnT4sF0CNgIL -kWIo/qq2j2YhEQTgV1ob2CXei8PfChmgMCBgolugnQnvXW2yFLL4T/edA5fqkjp6 -I1LM8xWnyTIB37bWfbEzrzCfb+Fq2CShBuVtfWMWp3GwPwbsA349YcNnQhDEqkEy -JOrQog4+rPijaYnOqnyIl9XcyzGs+BISYbHbIYc6FwhfSh4UVCdlbuScQ0fKTvey -na6p8IkAFzReGA61lwTFcsZ+s3ii8u0VTJhJj03NKvwQnDwgWl6tKd95KpNFu+Th -P+r2QY/3JQ0Rvb4hGNLTJ+TPGGmxY+ORPuz1DIiF021hTRtlRGDVqXVOulNNca3I -pYU= ------END ENCRYPTED PRIVATE KEY-----" - set certificate "-----BEGIN CERTIFICATE----- -MIIDxzCCAq+gAwIBAgIERFx4ojANBgkqhkiG9w0BAQsFADCBnTELMAkGA1UEBhMC -VVMxEzARBgNVBAgMCkNhbGlmb3JuaWExEjAQBgNVBAcMCVN1bm55dmFsZTERMA8G -A1UECgwIRm9ydGluZXQxEjAQBgNVBAsMCUZvcnRpR2F0ZTEZMBcGA1UEAwwQRkdU -NjBENDYxNTA3Mzk2MTEjMCEGCSqGSIb3DQEJARYUc3VwcG9ydEBmb3J0aW5ldC5j -b20wHhcNMTYwMTMwMDc0OTE1WhcNMjYwMTMwMDc0OTE1WjCBnTELMAkGA1UEBhMC -VVMxEzARBgNVBAgMCkNhbGlmb3JuaWExEjAQBgNVBAcMCVN1bm55dmFsZTERMA8G -A1UECgwIRm9ydGluZXQxEjAQBgNVBAsMCUZvcnRpR2F0ZTEZMBcGA1UEAwwQRkdU -NjBENDYxNTA3Mzk2MTEjMCEGCSqGSIb3DQEJARYUc3VwcG9ydEBmb3J0aW5ldC5j -b20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDFNki7okrg0rYLvQd1 -IUaW1cPdlbzkYVrU56xA9S1HeQfb0u7AAoukwP9oL4qWzeQaywF6/XM/6UurtEZ8 -JjKZ9z1NxbfFmWnBQL7U2z8EnBgz/LS57c5sstbHau+c/RxO5fM+Tg3Jo32S1yu+ -ahihH41YLMDOKG2rCrqeW+Tlrp5vyHM9kFT+AGsrCzO1dGBS8cHpBFhiUqk145zD -qP6L5S+bh9ON0b4e2fkDdx2O3fNUmVswwYVSSgKXqrCtKViirWIRQ2ey4uIXqFw9 -FzLRbqUUOq2qYC/vLz7tYig/OYt/GXze5zM/bxKA0ls43s9xPo8NOlvSBD6jRX9g -wDfbAgMBAAGjDTALMAkGA1UdEwQCMAAwDQYJKoZIhvcNAQELBQADggEBAJ9x2m/c -cePINfGCc6KDwpmDQp+2iibM2MLU6HSzZjsEBVhIa1nxWt+Z33IUS5d+ctHVdNUR -WX9U2Q7SB2P/KPSnwigBhgI0bOP8ovS+ZP6r5f2lLGrRrq20GPEO35TQQDocBljg -090Mdu9z/40aaGHk7iyMOd9Q7UrmzEJvN3TNr4A8rLcauakzN4wosi8zxq4l2ks8 -300BViatR52qis0AT8p5mYVO1J7TtWRUp2LgxP25+pEQRH0x8lKrIXTfX5Q3QKh1 -OF7RFW0URqz0mf6lhoXSAaejz6EtgxeAXtz542H7/6HVhjc8eTPpQyilhNrKuNGx -Ho3i2nIZIWJ1RJg= ------END CERTIFICATE-----" - set range global - set source factory - next - edit "Fortinet_CA_SSLProxy" - set password ENC m6TdlpCFptM4uvBmJFUCaH84GImxIEFw/qmpWl4s5Mmv7MmUjDvoCklNhXrd7r9PXe5BzW132Ybn0DllaQO0wsOybVC0JEWU1NTvt+3bwl800779+Gfn9dOj6LdyjbBKcEvB+a4GFSzU0IKShN6lYsku1KPdkMK8X3b3sjW0bj0UwDrXdY81gtzh5It+WVYxD4w7qw== - set comments "This is the default CA certificate the SSL Inspection will use when generating new server certificates." - set private-key "-----BEGIN ENCRYPTED PRIVATE KEY----- -MIIFDjBABgkqhkiG9w0BBQ0wMzAbBgkqhkiG9w0BBQwwDgQIBP2rB5RxmaACAggA -MBQGCCqGSIb3DQMHBAjy6HWtzSM4mgSCBMjegRXb2qew1cB3Yzj3VyrE8eMNXBC6 -83qOoI3tOSdYjfSaxGl2AA59PaEM6GslLtj0rC3unjzTk0qiVG2Irv5JGaKrxCJ/ -i4hAcVDEdlrmFSJ3AwULn14Ia6XiPmyy4Hs2gex/LQKBmETKbSpEUu/b0PwJkyqI -V2jJclYWzoPIBGeNU7F1KjYMZu504LiswhxqIHttdye+I9JtmKbCJlRpdln5FMM6 -NOKbc/xby4Wdyyl1bityo85t8UOG9nI9SRHct3GET7sWoiZg2Az65CRvMLS3o5// -3uk9qEatfszUpnmZWTODO23B9g6tCrf57So0LjYE3m4PniW9LYxVWVOiQdqNsVWx -7V8IrscykoxhsdIuhosdFkscsi4wXMWhNopD1gN/cRKCx0yaU0h5fhvSGILuG/Zx -lId7KAIrBnuMHLGdBrhPlIOszghRPPcqiRUGbt1Qr2VkYG3WwYZDvhpdKT67TJid -+zZQOEzr9nhOIcw57xdRUjjcAAINsWa/3cduR1RYWxyyg/xeNHDr5+1SFhL4FPV6 -B9dt7grgTKZ69/1a32ticfh22dhv6FzoeQQqDdOpquvvdOJOScGl/IdO8vZH+2+E -sanwRiFj5eO9tTZkYxU7gY8VY2PLC8FE33yEvxarUj1DE2dV5cUMYXBkslylKwqi -NXHOPinRkDTb9X51tZlbssqbjFUOahcwcR/g1VRjV5AAOEvpsisSYyAx+HDrcPsq -JeGbr5fVhTIQGVMOld4EETsqrSIWQ6gZmFqr7BYXD70OeS8xnFJZ4mfxFHwVB0Gq -6jvvhnB+q/VqMYuohJuo9i7lQPJGcSM824JaEG2sdmt5BJekm5nqybd8KFMuwhzV -CDhDtyaWzZnm6dHqEHnXp7P5ohmb6BRYW0KIEQkwbyB8/pQTmtv6m+Qjb4NiJbl8 -/xcCZS1t/n0MngmQHnOZysQ0yxlEegRCNcHGxaWMJJJ0w3cAldy7VTHMbOqvWAtd -jHrhep6GA6wgqLRYfrY08kZV2wpzaRyIMqE7MKlw3UnOBAVHwMoVtLhDAS89Y+bR -JBwZ7k5in652gAO+bGxnNSkmZJJJRt0Z8ngjKR4Ez6iaicz0NlLE2J4Ku+6LfgI4 -A+nBYzA/6ybntm4PvBLDo9ZPoZfuCKPLmvmywV61FprRNdebhxk8btlTSzeguVng -bMjgyYp791coe9HV00HzETe5EWl8s38DrsSZ7U26oYIoYBolgaFLENdFNJn1i3/j -CkXYaHtVj2BsVMPKu5zqzF83THX6LY+RDGUcQWboO1fbu+L83B7/P4DtLCotHabA -iXO9EP97D4o126nSe9lc0xVg3NQFXk9ngHchEKZabpUDFPY0wPz/GPhL+mtz5zqb -IHZfdvooJ1JLHdLt8tOBOmBhSy5SrpXfQSvx/VmL4+AnSp98a5gGgbIvxsU/5NbQ -zgwT8lCtTtuAZm1oM2O+wkBYnrjR6MpYu7XD9Au9NC++amXdknlCHgTmNJHdFv7S -AN/Uv4BpTUtEm0ZCzTb106sUBSmUOsV6LaoSjvsdql9gyPtFfEnIpf80y1v6TaKX -uqCSIaVPaw+m5QAiAmB1gti2z5RWBS3yJU+W6Ybb7Aw9FWQN7c0YiKjfz/QZhdWk -21o= ------END ENCRYPTED PRIVATE KEY-----" - set certificate "-----BEGIN CERTIFICATE----- -MIID2jCCAsKgAwIBAgIEDokOXTANBgkqhkiG9w0BAQUFADCBpTELMAkGA1UEBhMC -VVMxEzARBgNVBAgMCkNhbGlmb3JuaWExEjAQBgNVBAcMCVN1bm55dmFsZTERMA8G -A1UECgwIRm9ydGluZXQxHjAcBgNVBAsMFUNlcnRpZmljYXRlIEF1dGhvcml0eTEV -MBMGA1UEAwwMRm9ydGlHYXRlIENBMSMwIQYJKoZIhvcNAQkBFhRzdXBwb3J0QGZv -cnRpbmV0LmNvbTAeFw0xNTA5MTIxNzQzMjJaFw0yNTA5MTIxNzQzMjJaMIGlMQsw -CQYDVQQGEwJVUzETMBEGA1UECAwKQ2FsaWZvcm5pYTESMBAGA1UEBwwJU3Vubnl2 -YWxlMREwDwYDVQQKDAhGb3J0aW5ldDEeMBwGA1UECwwVQ2VydGlmaWNhdGUgQXV0 -aG9yaXR5MRUwEwYDVQQDDAxGb3J0aUdhdGUgQ0ExIzAhBgkqhkiG9w0BCQEWFHN1 -cHBvcnRAZm9ydGluZXQuY29tMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC -AQEAv1BkGNu1LqeNzbZOYubi6hKstJQgVQuIE1EWsd3luzEnyz6lGefbf65Xad6c -gH4zN17QtDy2JSS9Ccmt8KxQjtdMQeHvFvXXvKEXzfwyIrTrFAbyCp2S42AQ0tHK -+NRaRE/HOjx4kV/vLMqDHgWocuJWPPKfSkKtn1+chn4/sLbuygSXtGjDsiFd+wSu -MnLrpEPSOEVQtU3M5HZZKDdT7HG1sP7gnHsg/kHr1+8PXna6rKktBq59geCu0XCd -uNSFM+wU954dKrYS21XO3fyHLIy6tHP+P3+qg6/dmHjX8LXRBTJX2eRirq+NLSis -tG7ZZeIHGv9SVl1B0yk8HbK0IwIDAQABoxAwDjAMBgNVHRMEBTADAQH/MA0GCSqG -SIb3DQEBBQUAA4IBAQAOQdcBqZlQ9QabxwRK56bFfy8Kyv9MStkFrMG/bqaXEeTY -AIcDOZidGihTjH127kGOIA4Rl6dzC/ck1z8ylqRhMi0MkX8VdyY1vxFAKmu8buN/ -HhQA0fJptGDaYScGFDb0wOnyoo80dwosaZvXVrvl4WLbDek4et/knhe8TohsqfuZ -sEwh4uatiemQWFjPcqRJSa3UiJjQGqr9ufbP8dsGT8kCsoZPED/H9Ot1P6RFrZiC -wsfiXWX2XWPSft594qnv349oPjzyLmQh1E4BWVIhMqk92k73abZszG0fGFrEY2i+ -HG/8qCkgnGAbA3rZuQGd6ElRa+cET73+VNemXabr ------END CERTIFICATE-----" - set range global - next - edit "Fortinet_SSLProxy" - set password ENC zDbw3CZpYvJ5oI2l88MhOicytFx8v01Trhs6qpH+pnN89BPNcTSLRnJVJQopwi00yYka/1qr0+52h2mTRovzpAp7ucZdMnOe0HKcnW3t6+JzilkuU6b+N301JVmQ5EWc6wb6ai4DH8J8a7s5rat+GsXcENbnfAFrD7+LRvj9GGsJBsy+YO6g3zf1mpQrZM3nz/AaSA== - set private-key "-----BEGIN ENCRYPTED PRIVATE KEY----- -MIIFDjBABgkqhkiG9w0BBQ0wMzAbBgkqhkiG9w0BBQwwDgQIi5rGNa43QmACAggA -MBQGCCqGSIb3DQMHBAh7pmECUoPrCASCBMhPH0QROOPNoVhjSMmYrLt+zm3oW2Jh -QpyoO/w8jV1r4GY0qFI0dp+T6ZyfBqwMl3jdSqjSgghb1tlKsFcr1dQ4NdKGYt6v -RCT02+S0TxD94JPcyPlEK4FjkBdE3bXII9nxTGTXg3Nkbam90cUYOw6JW84BkxUH -Q72jksM95VpFfNz+ib0X4yyBy39wFxdQHic+uU36nRf0qf5E9ndTUO8vNHNP9Pow -vnXZLIp4Qpv9DnTMjwCIwfU1iIP+2fNXd6BWHYbIsmnlkIYgJi3KOgwN5c7L6wmA -nzZwo15lX5ivvgyryzVdmzCboDfb50Bk3kLVLRn1b0uppFqYA8Gfild5Rl70m+wC -N5btmNZ2PRdW8eRsPGRXbTyoEZacYeFPT/fNMUUJFKo3EEOgVKMIczaKrdARd4jX -FcnZP20W7ThR7AlZsHeooiM2/PRIx53eRtRohfXFCT+D0QZ4iTXx5CPPCKsvHTrX -ZFg9s7zYXtEIcGe0n3SUe7Xz8e7zngBQPub21LtpF6pH8kRFOnrUCR3yr0W+5B/O -nz2S8s6yieWckEiyODP3V2jELVoczzAlI4lWxsF8Iu5JG5qVOawH+ruUxFZp9Q80 -8AsT4geaYO+IBNcCTXescp7RxoQIc2n3BxC+GteZ0SEbjAFiIqSlEhh6Bn/fPgib -iiXeeiwL2ypvPb6NWmS3lFNnruX0g6pAUNRrPLkXqIP1g+gE479wWYzFRoJG2W+r -BWxcn3w5B+MlURQfejCbGPBw4z1CqgmgHqhsXIimyNtG5yORaXHQjjssHOiZKujA -bwjUtavydZLeoSQAurIoUUqOPSDMQ6Ijuc+nnpGyEIyr/9ryDaqMBH0zAaDn05sb -PhSHlYNlSboD0onPIQ4Yle6IBTH8ORsZuzhb7GJzNku3dYY70iXl3FcIdZy6LDbV -TVdWEiKCU5CR1z3t2LE/+J6jsLhLmxlAYEo9DsMWiAP4nAnfuDKoRCSKDkavxCNK -LjAe3vPsLz01BuL4/9r8yfjAWwyJrto939RMHprzIyocXcJPCVUajc5g9ylbFoiT -DPr8Wb/26kAazKQj+2zBhgQO/aJiwp/Iw+mK6smm9ifIvhi1vTeYa/sTkOElCz2o -Vf5Rzdp0L48jmpVkEWQpwkd6RRclyQDUtrE81C+ok6XHqZ0TSww1rr8Mxx+aAWT1 -cvP4bp0nymK+xrGN2TgbfW/SCVoYeH6MxWnn6VfnazR/mbnFzg2ULm4lYnNUoLxV -0Br/rqlufMzIa0owGzPtDhb497PBiBvhvHjE5IkPUic88c285BKuvX9GbrbH2EiQ -ZNEYJQ5CkJWTW1m5tBINzO30fMpC/oqpojdmSEKZ1wP/Aq1T+caEZn0QDe9qN6Tu -oWemDalTfXt947fUCC2vpNAE4+zt8AiinqevO0zgtsEcwAzKpUmwFXI90wEyMjsk -LphgMJE04zCgLS7YWSw0snAgAhv00ucCKGUNhC78Uk1hL2h4KB64aaKNl7GwfjnQ -y3XpNGjOKWJDMCGmN9w50mWo+28gu2CCiVE2aY8wp5oUzH4MlyprbsefJJLFugDi -zDe0xJ/InvTYUXrM2E0ukyTTaBBT4IGz2pLoTTlKZxNUcdhWLXfIvd5FjiuJ9MTr -B8w= ------END ENCRYPTED PRIVATE KEY-----" - set certificate "-----BEGIN CERTIFICATE----- -MIIDxzCCAq+gAwIBAgIEHLWG5zANBgkqhkiG9w0BAQUFADCBnTELMAkGA1UEBhMC -VVMxEzARBgNVBAgMCkNhbGlmb3JuaWExEjAQBgNVBAcMCVN1bm55dmFsZTERMA8G -A1UECgwIRm9ydGluZXQxEjAQBgNVBAsMCUZvcnRpR2F0ZTEZMBcGA1UEAwwQRm9y -dGlHYXRlIFNlcnZlcjEjMCEGCSqGSIb3DQEJARYUc3VwcG9ydEBmb3J0aW5ldC5j -b20wHhcNMTUwOTEyMTc0MzMxWhcNMjUwOTEyMTc0MzMxWjCBnTELMAkGA1UEBhMC -VVMxEzARBgNVBAgMCkNhbGlmb3JuaWExEjAQBgNVBAcMCVN1bm55dmFsZTERMA8G -A1UECgwIRm9ydGluZXQxEjAQBgNVBAsMCUZvcnRpR2F0ZTEZMBcGA1UEAwwQRm9y -dGlHYXRlIFNlcnZlcjEjMCEGCSqGSIb3DQEJARYUc3VwcG9ydEBmb3J0aW5ldC5j -b20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDbdA1aeDvH1lx+81bi -oBn5s4J0w95jAKCt+E1BsFnFMEO4uXpbN9RC49OU277X0an5o0oCbZ1kERp/23Qs -VkAGX6Y8rjzWCHc+Uuw/2b3WdjEqcQnDbIEQnl9N57F4EAc/wX60BN08jng5n8lW -SYZbgECdCq6frFdRGCa1oHKd8fHgyzEC0lcsLJnSu+A51oINfcqV3Ggsl/sgZahC -mP4L8OkHbcpD+mJio+8bZ+DG490+oPaN05WSPQ3kjw6B50f3yrXSYsjPoLBlOlah -GSz3bXZc7uZZyBPXsd/CaA5ivEPUNmh9HNq6alu3rjM1UPB1VfuMhRS2TOJ/ljpt -/LUDAgMBAAGjDTALMAkGA1UdEwQCMAAwDQYJKoZIhvcNAQEFBQADggEBABJetvs4 -hk44A5rCbg6Cq3l+Vf+dxgqDTyC2Yt3TMIW8RQYqYDDvRJIGND4G12cmuE6w4mxB -GcS7K+nCcFk/fvSnHc7Ec0RSxUoDqiOlspAi3NNcyCw/dekOXIjnEdgSY8gNt+eS -lAw65pjSBBbUpLYXQEEpx7oxQZv2Sv/LopdLu6mJ4a3xOS7jYMFf6ienb9upxKzz -xTptBUNelN30G4YDFMUQANVZ+o6MyjaJIo7RgpuJb1HQwTcb+hANK2SIzHxcok3B -3I6ndjJ4xZwYROIYcVv9MKMYj47XTqVdVJNncrU1M9u4fjCVuVB5wTTgzdr5XJ8I -qJsp2d+xby5kqc0= ------END CERTIFICATE-----" - set range global - next - edit "fg60d.ffm.cactus.de" - set password ENC oe4jR7h4vdsf42sgI0Tp9Zir68hqWLA4CQg1jxrqJzyusHNY6+KQSz5S5ZkFKLeNyLWtPWIdHw1F64Q0GPfuqIa3X1T3vhgYAeU6KUHddMAoO2gYPJyIS9r9BZpVIk/xnvK9OTJ9hldHKic+Fj3pO/Wjuy1fYtsV3XkTigDDDDr417+hH8xPuYi7xpZL4gomRzPSUw== - set private-key "-----BEGIN ENCRYPTED PRIVATE KEY----- -MIIJjjBABgkqhkiG9w0BBQ0wMzAbBgkqhkiG9w0BBQwwDgQIhSBPRUCeXD8CAggA -MBQGCCqGSIb3DQMHBAieKjGDjC24iwSCCUhmUuR1rCvczjIuyDBVgdAifltipnPF -DXD446RtwywSFws1jYSDMXNRx4E73TWPJxR7LD5wME6fXhiDCu2Js/qJS/FefAnh -GKkg02UwQs/pewvyEq1SXCjdXBHapBGi+sSuACpvS833bJi8qxeB9PWKhqwrvyyt -LRyToZjcnOYtjwN8NCTUr2vG68MZ+Hp2k8DsffQEr2k6dteFtMaNHJj86l0frYhA -2JIEhFHo9qPjlK1nvSoojUdPQy0CWSZPOscwOXMCGmvy++RxmqqDOwLHO3CKToTg -BRsnDUTckS2S7pos5CXilLv294yzGcxywvR5urTvp10IXE5ssrgfKE0yll+XquKZ -7Qhni1Mqear5oLKF/iZFEgSICJT13wfzmWvFY9motGAu/Hr4/izFS2Lcd1nIRZua -1JaTdqJnOOiBlmjdAEfV3uE2RfioqBWvEp1NJB1WkNx+lCXfGpVyiIVuoFSKkmQz -sPIcuHPnE2F1nxPiZEsziHCYD+V1mwMsW5CNr8Hs+Saw/nsqKWzk+iHRC9FAzvtN -T1zrJ6aBx3efOHHs/ZU+7smwVZA46nbqEk/gVTND+1f8jfDUIdn0RQRkLv0ENT4I -tRFPLP0oi/IM3bNLUPPwSrSVTt1fuFxP0C62z9md/cBT8hOjHmMMrdn8kf0BsGXU -1XLgNIhOIr82cBxxZ2hwBg0zXo5fDHR+1ytC/Ox72zLmIT79uC+1vWeugPr/gm5P -zHMPnlv97XBJqOrvQbYODp1GWcHx9brUmD3665AhcGaCtfBJhd0bZjS/Ze+QyCwe -CLEY6LKXkgPbgNkNR43iJFmB7LY04/3JQ4PNLAz+LJCv925aPQMGXZzgzWR7me3q -Fvcbrrb6u3IO8LSQ1ojJCltG/WEM/pLV1g0mktflCtoH7sgToMRMNCYSf8WU9b/b -B5LI9Or3jpYdJklUM7rKGXq0vi2to6K8nJi/DFKaPDq0iXv7QSY8YgT+wzNO4Ejv -GdbAIEWwWVftjs8GoihYsnBqzcqvxcP7WWhK1hQ/k1/kihcvtlsecp3zWXFg8heb -8Dn5xreMui0oe4/sKAw/57HJjxByW7FxlIKszaLxYGqZ8eRrLVJKSkssYd55pdV+ -gzz04cIgK5z09DxdDFI7DCS2CAilhPiDnHyLjD0ts3wOPAJvtO0Bvq2Xqodu+FMa -RqCcdtFBWTuY60jPcsgOnsp7iMmzjcCL7CALJvapybBoCHyGL51n1o/Yg4NbMGAA -ZatThpB3egw3G4sV95tPE+rjrDbxgdfjUDeDkBZl8gUanSBuOZpiJ4rLrut2qsgw -xREN/W9rTm51TWjOmBmxLJU2Z3ym+IArURQNoYM1MN1DpROY5sWf42HXNIhad2Zf -fnhWfai+LpvIy/mYuvGB+6So/+2DiGha7ltmXiUTkDgsM/ir8WbJ4kWpRzjQ5kIn -F/TCUTRF580zMqJXh/fKLCXnncgkxBE5YwO/xUuvgszsstcsgT50qB8oPw/12M5F -Ncnd7NBJvQulM9MD2fnx0eyAnYSp9mw7BlDFTNpXL/QLaG5p3t++Lnr+rJ+rwGL2 -EuFdcN/q9RL3kWGICWtGBRJN1H4dGXlGelnqIKbkgNH/80koV32yjdXPgdgqs0R3 -RZNbxazskfgeyAT6hOkNNxv+C0bG+JNY6PNveV1q5kzy/KsHV//l4V6iN1VbiZEu -T/TPR81RgbiJScfOjQ+L3EsyAvLJW5kVnTWsChfFnJyIPHboYG6K32C7KcKDLNB6 -3fKNfgOLieFhfmc5gIBE85C0QX5Z7q5vz8VqjHx8Z2P43PrA0ujWPUl0BOt2Bfj4 -+nbDTj4p+Tu4sjHTLJO+3LlzHxUQu+G75KdgNsOsPI6hO+WUPNaSvF9HoG/eWpJN -0RiBxg62LdRauoeFBt78QN8qW84c+gnxk/QUkjbon02hTL+1MSjZIt11bdrXXbBP -djgFquzulwoCJDBOWbZyVkZ+tHhrMm43CLCh3sBqy8Va23B7nLoc5yvXZ8KoPLCM -wk4Fxc9eWE7ZRo7gUolIcj38UDcRvyRa1rMc5SZP+3JaY/QhDD5id4kwToW+TVSP -ayDCrY1L+PjjZIWKMNbd+D19ndLJOhs2f2KvzQCDZ+Q4t+KkJqF3ULqmV+yICVzS -xUEZUJMMRItpPh5VCSnPYusXUo2ycYNwH1kcjXuAU3jJcOmVwRidr6FA9UshG0hH -F6Wxrtqpw0onTm0HEvtQd/LkjhplNpriZW40w+T79ytXWdLgTQzIeFrQtNXm/Lfc -uCWsnPbDtMcD+7icAZhubikaCfgkVdtVFQWcm0e1C353ZAsFZKD0NTe67QqoLcaL -3uke+dt1ysuGHXD75zqIfFrZUuT45ICKprOotL9tLM6cBLHZ5NONTBIsOAJ/2XvT -tjNAU3PQeQGaE9LTab5RWXZ7Lpjd1lU9kpdFhOIE7rA/b8GsD3N/7Q3AnRtZ/hIl -FYWAaMKsrbZBksYXVfUcCJ3CHU9Fo2bD/hA4ClGNo1pdfyf/yLchBUj4vCOKeILD -NP/8vIu4+B6MoNou98n1lMfFpmj1yalJ6NHB/vba5gXlzWHGJ+QUaYS4PNr9Z8gB -8SAckgAwb4wbi9yiQ+vJWBc/1EgDHqhZUm6RHWsNy3YphBqllRTLJbB6bSdS1lvn -+42jUWYxA7Z5droRfdXdPSwYNsODyHkyFlfDDWw+o9PeFcDZdXmdr8s5k+IXUUIW -KSlLdKMdKznYsOmcv0vRb0AhaWniOnyRC5SAl+AoKVPJrcQbF+8t9atgy9ldp2mq -5M51FXoHoQuLf6orQtMBiycoZ/Jgv60/aNZEdkE2kVltLYY2C+9xhBtzQAC93kg4 -Rq4Ao8LSocARl4zjl7i3/STozQLkzSisIPxioPcnIJMIMWnXpBrXiHg49TPBZ+SP -clDht7aoXAtA12P32ITNG4Kdh+fO4E7XlcGizTHO0Rtg7vjnkqcfFsKoG4R75Wyg -xztcgrlYLov5l/0XDh0O1baTaDtJHN0QswOI658/IlGTrnouZsvpxejAKM64yPcL -dH5bm2GOuduptwXnKYiZNgbUu/U+/Y4eMxrfykMH/GuK4Q/FaF/2sxhI0rNX8BxO -F9e9j2rZjOnF/SjB+k+Ph5OTQEYT6Wb3Oi6UQgoo8Wtqxs4DoiuqsExUgo0EePku -hNc= ------END ENCRYPTED PRIVATE KEY-----" - set certificate "-----BEGIN CERTIFICATE----- -MIIGGjCCBAKgAwIBAgIIbO9Gi4dAwWIwDQYJKoZIhvcNAQELBQAwcjELMAkGA1UE -BhMCREUxDzANBgNVBAgMBkhlc3NlbjEeMBwGA1UECgwVQ2FjdHVzIGVTZWN1cml0 -eSBHbWJIMRUwEwYDVQQDDAxjYS5jYWN0dXMuZGUxGzAZBgkqhkiG9w0BCQEWDGNh -QGNhY3R1cy5kZTAeFw0xNjAxMjkyMzQ2MTFaFw0xOTAxMjgyMzQ2MTFaMIGVMQsw -CQYDVQQGEwJERTEPMA0GA1UECAwGSGVzc2VuMRowGAYDVQQHDBFGcmFua2Z1cnQg -YS4gTWFpbjEeMBwGA1UECgwVQ2FjdHVzIGVTZWN1cml0eSBHbWJIMRwwGgYDVQQD -DBNmZzYwZC5mZm0uY2FjdHVzLmRlMRswGQYJKoZIhvcNAQkBFgxjYUBjYWN0dXMu -ZGUwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDLPrjx1WlQ0v0thXjd -r92CCAfO/3GTr3O/NM4gAwSQil1Qd/lP6/t09wZk3Jwsw7uqCyRRmHF7xb2zH7VL -rvAKjWKjuuw5oT/ze1yPqubMf9ONcyx7jW2m+GycpokqjiYs7sIxELaHRoiwtS2w -jzq/Sc4OrEMZROUPhn7FQ6nhaxd88CN7D0TzRgg1A4O8/snyNNuKc25UYQtQmH4h -tIKqwoVSET1m3tHD7w/gKgcx1P7mW3dmTYJJ4HkIeHqC8QjixEl/v0vZw4acTFps -o49QyDENn9X3rZs9fOlKr+79a8/kURDjzeE/6a8GvmfY7tw1yq7zHmbBhCBCVME3 -ZtIW00aEfUFoJwPFM3ZJRTDUXwW9vPLl74QzSCE0CjDdIrNnoH2J5CzdMcKQbzmx -4MWOJ3ilwTxHq1mzaIa/5vTjowzWN6tN8udERaWJf88Z3T/7TKqoI/KLxdR387/Y -EmtHnXlg4wcFqEtF+9d41t6Ks1etMWAA4xzynda9oltWcD39otrsPGSVyxQJ8soV -jq5sltk+guvm153QviXcBPxXE3Fm6XGYxwUihna0xrDXWD74gZ8d2ofd2RitMqxe -vMX3HJbkWxUYnWGNPPboa/J9780BlKVREGQyuoeXZP3MUZi+uKKXC2sqqoxbPlAr -gwRCHBGmqbgSxH3enFC3UK63PQIDAQABo4GPMIGMMAkGA1UdEwQCMAAwEQYJYIZI -AYb4QgEBBAQDAgZAMDMGCWCGSAGG+EIBDQQmFiRPcGVuU1NMIEdlbmVyYXRlZCBT -ZXJ2ZXIgQ2VydGlmaWNhdGUwKgYDVR0lBCMwIQYIKwYBBQUHAwEGCWCGSAGG+EIE -AQYKKwYBBAGCNwoDAzALBgNVHQ8EBAMCBaAwDQYJKoZIhvcNAQELBQADggIBAG5d -PzEgwm4oyrFemE0FYsL9YBZ0wVSpTcbDAcgozD2huudaZDop1MVAN4rf2onRQNOA -WooQOk3cufG4CbRg+I3LLCqUJnVgsADx4SwdFXaKucu214I1UvmGRTItFMgXNLLT -ONGPyDe/BObYNrt2UZqqRGrJV/1ZXzFjF8U0AoORm4c5ueT99NhbHdcZRQ+WCgrs -Q7HWfjIgYXiaIr7gMiBMJBbVOwgIuuaC2dTv7uAtbPKWOM3rowOOv7GxupJFhtnv -AnLcwV8jHFnmVO5CqLFF6NnkaSppnaTK1yvjHM/S2JoMyUtKw7SrjYvnDd+mZwuD -incaKq0XduuraKEDmuBvWg2zgg0tr1niVJu16R2mwPJN+0jF5Q3upcQsDPM8NOOh -mnzPYTbdJI+oda0zo1mdYgmzTPnxLD11YHMTjDgO/RdRLojB5L2i5BgpZ0LpeHat -b9M4iiGDCWIC8JmYdYrQCh5gQDALGwb4lX1bonzlrYJU72yG6cL82gi1HsHgzOeF -EYQ6htRZ7Z1rUelsF+mqPyu6Y3KtsJVqjMoyY7ROto4PwN+Gv69E3P8tmRZrBa9Y -HeOEbOGxUir/NYxDHw5RIwX+DJ0LwGM1HUkRPFtORDwgv9L5Uj7qACYa6mSDhmfm -BcUdOQYaR10psPNtFd9LT7HY72JyCy33BtWsD5gq ------END CERTIFICATE-----" - set range global - next - edit "tim-4tinet-ssl1" - set password ENC eZUz9j9Nvu0I2FNWAZ9K8h8cKAmKia6ghWsWMfdeBX/JMLUwQD+9C8cNPGJqjkH2Fk8F2DiceIXDm7vfNXQ7CmB5j9mINol7qscJJwEiBub3bfWU9lNkcpsYIwXbmzkI6D43HOky0IQ5uO3OmbWhxDpNO6kVeV+3h/mHEQdbzACUoP81APPxPZl8C35Sm4Cf73NKzg== - set private-key "-----BEGIN ENCRYPTED PRIVATE KEY----- -MIIFDjBABgkqhkiG9w0BBQ0wMzAbBgkqhkiG9w0BBQwwDgQIuHyL33KIHU8CAggA -MBQGCCqGSIb3DQMHBAirZnW2LXL5WASCBMgKsGd5Gvf0Weeo8yuMQsOEuaawcXj6 -RLkNRqlT48NYcTG6zD97tGhtI1shPnXNq/KqNHVMPoF9QQbyw5/iXdYCrlZT6e0e -g+/UfiaMWwSfloiuF8Yz+MWxNSiUoEt857Dz2PTeib8ERMuxdXKHrLizHPWMxbKT -KCuvUlHCecNi0yDQ9eFd9qVb1fZdqybiDHvdxres4Ikl+wW4sA90kqRRbJBZu66x -bwhjqAFWjHOC+d6FLapqorXx3eCtarjmTDQN5G6m41HY74atWpcdOfS9Z9ZdMvR4 -52fKnfvOuzMccmnJaGXBZlh/aELbgYObtHVBLMvcT3yVAs/yXA5ltUzTaGkO56DY -5ANZ/g2UPzhd6nuxd00xC2ZWJd33D6uPxnlk3C9wcFrPTcIqePExuYWqg6lNbKfZ -eXrR0Cj9gOVT9gVSuh7uNUoqxQYtXFroBuwypOnxKBYDFo0VB5SZAopSZpi1m/Mo -SUEYER/TKURFwMFdRkJR5TR6Zl6YZpu0MDwTDiGOv4lQHI1HxhqLshcWRpT75CZ8 -jNEKp0YfiipXCbYf4ygqqBJDfdUqBHzob4QGuWyX+SYMexugLBoCsQW8cb57Me1h -viF73KGTM27CNJoe+ICoA5j4QmpDG+dw/6BeKlbn7xmrizvGcqcKtS0nk/+MKJVy -GZN1osalXSeRkIh7iWK1Bb9HRaCCcfkRdF78KGX065SCHa/0GVRv9t7DmoCfbjes -WgqhvUR2ZpwOLcnFYRKud5g8yne3PtSjLZ9uAIRCbCP8TucXLPhyDuzR+VLi35OW -8J3VSOBPhOZMP8iWTpcriDJJ83ZiCl8ZPnvjWnAcS9qAoTUp+L9/AOKdh5asz7h0 -70uxGZ8nNjafCPZJsBzYBniB1YhiiIOCe0IPYkF4c06s7EEXu3FzvNq1GKVQPx8E -0lFjEawiDhk8vqLCA9pbRMlN/bNNnPVxiAkkaLytiSDPeK8QjuiCg3r1+aDkkA3O -5Pbutn4ZrPiUIu2g0qJ+p0l4gL0rMP1Jhjcwlh1t3Fk4Exuh5VhlWeURkkIqJdcE -RuyW/LbyYyqDm0Wm+pnxjmqUO3tsBEggjuMAMEOzoqQJenRws4z9jPYHt/n9iutN -UiYLZ+xV5nQ5N7wIgQC6Ub6wi3UhPdHjrLWGKuPZzCxnHQwLWszw+SAYGLn/Qb41 -473vBXPZIXZV7IkerKCrjtxDWyg/dOvaxLODrr+7nSW6W3Dd20c17M+5EpqcdQg+ -UBI6l52faBP9CVCQOY44i/sSwaG0dca5eZDKMdEoVKSZjAj4gpsY1x4naFysKGJ6 -ilTQsGznqd95Txg8VWOITNcAnNkxmVe2a6YYRNf3+M1+bnALiv/CuIfns57HriZ+ -kS9wbU78olazGZ2tZUFl9vBmJC48gsuiX8mdgp4b8g2uJ0ACEaXjn8aVKHF3iOEZ -34+6q0SMu3OuN/kXm+BVyBNXdnOSkyZtE//eZYPrlTbYdDlb5nHJVC+t3+C2Z1/0 -3Iy8iBW8Jycb7xbR48zdOjI3IJUccblXlgvWIb2pMbdZ8V298IYlsv+lkXcIah5k -KOprIQgyDgegd5rN+oQkUDEeHfM2N9mkXNihPG3uIASCAjy7S4O44CopFvEM39ZU -4uU= ------END ENCRYPTED PRIVATE KEY-----" - set csr "-----BEGIN CERTIFICATE REQUEST----- -MIIC8TCCAdkCAQAwgYIxCzAJBgNVBAYTAkRFMQ4wDAYDVQQIEwVIZXNzZTESMBAG -A1UEBxMJRnJhbmtmdXJ0MRkwFwYDVQQKExBDYWN0dXMgZVNlY3VyaXR5MRYwFAYD -VQQDFA10bXBAY2FjdHVzLmRlMRwwGgYJKoZIhvcNAQkBFg10bXBAY2FjdHVzLmRl -MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAt6pScH267ei/D0n1OtTX -U7kufbnz4tgPer3sDFyr/PuNkNG6Vd1YSQG3wa5SVAMwvmOuuRaEPMaYAao7NlYp -ZRXHY4oVgEIfnEIp8u/N5duLgssy/go1p8bRp0szcfHAtP9j8aQPzAAwKD5YFUlw -IqnvF/fpqW/e3pDTqrj8hYTy7oD3TGjf8JXLFXPSNaB7UCDf04nRGBW61ww+gn7A -85OvK/E/smUjps0GTo5vFBe3h3nqvnUUSRnNpibW1PKpDuPKr0DwbZvbbTpYoWR2 -qcnhqFXkoR84HaITxzj9r0WfIWaG1inJ0iIhfRg1kx3f/9tvLNRb/0/fZUV/FDC6 -jQIDAQABoCkwJwYJKoZIhvcNAQkOMRowGDAJBgNVHRMEAjAAMAsGA1UdDwQEAwIF -oDANBgkqhkiG9w0BAQsFAAOCAQEAPo0HtKAD1U6B+wG9PsEsGuRGQ95ze5Y6XUlT -1UsJK6idiXNhETRVu2RbGUJqP6Exq3cXoQZp9Y9uMEirg+fQvF05ijYqlAIoyqci -aPjkBvunmrwqcXsCgd1igxypCRv/8snhO9Jh6URL/gVo/uS0xvbnTc5TsfDP3yJx -XSL+FofPTptPviSnN6dR9Ytsc2lg5v2oJLiUhGZqZJnXTJzeBQLjC4KQYG5Tj2mX -BLmY6CoblZXcvPJ3I3StxX4oRZDHqwpnAxFTlKJpwbHWEdU/gDYl6MdH9bF3uPDB -mG8My7ERT4QvQPdZV3aPbDTVVx2RFQcNRmO+hRvj2ACioUlasQ== ------END CERTIFICATE REQUEST-----" - set range global - next -end -config user fortitoken - edit "FTKMOB5C9735814C" - set seed "b4sEIgq5IpWpq54cspZ7m8giOaIShxjmzxPkyVDOg1UK8nykvCpkq2e+e8DmM0d3cc2GLKe6RNCO93YE+PfE7H8Gk8ZE87U/K3etCj8hZLRqVq/qAnlI8WOrAwr+AxXDDIfvpPfSd0S6BIJR3WMc3Pa+Q+pST0X1/A/C376VZgQmb2Hd" - set comments "test" - set license "FTMTRIAL00728937" - set activation-code "DEIHMHRHYOP23OL2" - set activation-expire 1451220873 - next -end -config user local - edit "tim" - set type password - set email-to "tim@purschke.de" - set sms-phone "+4901715047437" - set passwd-time 2015-12-24 14:54:50 - set passwd ENC uPYS5M2jJe3r+9xUZ6hCiHCVlPIQOuGFAxUfz7IAa2dpyQCkxxe1Aygm5fDSLNQ6la02d3Gd8OwKD95ooXPS3oZFiCu8W+PdQJ8gU8kvfYZhiquP9FIWQbxBWCirvfw7Wv4Y8RznwCp2LZgEpnFjF4cdTSscdn3t+7DCjIYGTt3H3mKffhA4zJSHAjn+yGfhM7MoHA== - next - edit "finn" - set type password - set email-to "finn@purschke.de" - set passwd-time 2016-01-13 19:38:14 - set passwd ENC U0w6SfXwm57pSLh81hgtcZP2zsiW47HCygV6Af8mOsfd3z0czuTfrr/CC/C0HteqCGPQ4F3r9pewwjoQc81APQdq7QjqMnsgcyKcmwZ2FTMRNLynmrWCUEDHnWOMfn33evfYQmyMt5Jnu7FyjLUNY7HHQ2g/zHZ7PZK2bKjdEHLviLjR/V/MTFCtkDki2e6jaE1sGw== - next - edit "tadmin" - set type password - set email-to "tim@cactus.de" - set passwd-time 2016-09-19 15:00:38 - set passwd ENC gZ5x6oIzP7HCpiHhrlaoqGMdb8FVrK2g+7jdZOqb/ceRiu2iTO7i1PEQkoX5UYaJMPtKL7ScjwxIiLG0AP8/LoLLae92a8tN2c2Nt+MWmJZH5XjWNkFaSy0rNVKiUSnRLktEwQealickyQFLmwBLcCE58ISMFHzNOfZUZ3dxeI8547ivEgZzQntBdYjFaqfv5+z5xQ== - next - edit "nils" - set type password - set email-to "nils@purschke.de" - set passwd-time 2016-12-10 20:09:33 - set passwd ENC 6ye5I6kJr6VIYCa83l+CEiKFpA3FbKyVlIFA/2RTPceVs6op0UpSTsV0J0JV0BzT6WizRqgjWekzWXxygiKz1HgmmSSorHl6nSiTntu6WpuWnGkC97AU+Y6TSPF4AUuGXgo9r2TcBrttyrdhPh+Hk+ZQmmnkXVxaW/kEC4W1LNwJ7ZhzEtO7ymQOCwKanTBJ4BYNIA== - next - edit "mia" - set type password - set passwd-time 2016-12-10 20:09:49 - set passwd ENC KvuSh9QZS6A4yXCHh+n+X8KMBEV8f2HYeuu0vSyjT1SxZyuSu79UtqK43Zwn0TE0ehQb6c2hBgRJSx4j4rF8wi/MIVTFXB+8A4/5iNM28Xjg2fUOgJ6GTfOgDr+WfwLVgchMJ3fgARIdlYHbVWT65nfG0LaQSs0uaOAe/msAIu1PfcM6x4OnbC1xiI9ia+0HOFjRHw== - next - edit "timk" - set type password - set email-to "tim@purschke.de" - set sms-phone "+491715047437" - set passwd-time 2016-12-11 15:13:11 - set passwd ENC 29uOZR4WUGY3FK2pSLmYtZxiEsIRDaqQ3rFvQLVtKotGt2VY6ZoZnl2M4nnWEWK0nGWm7xWpSOAWv627rd4tTP4keDLSW3wUih0NJAiBJcyKMCBDKMkFCdxMMkouwxyp/htz92unwZlftmaa0olF7MzyBcPcwTRCENjWYTGx84NPOuEYlkKXYryvP9LXTVKnNS2axQ== - next -end -config user setting - set auth-type http https - set auth-cert "Fortinet_Factory" - set auth-secure-http enable -end -config user group - edit "SSO_Guest_Users" - next - edit "Admins" - set member "tim" - next - edit "Kinder-group" - set member "finn" "nils" "mia" "timk" - next - edit "gast" - set group-type guest - set expire 7200 - set multiple-guest-add enable - next - edit "gastgruppe" - set group-type guest - set expire 7200 - next -end -config user device - edit "tims-macbook-lan" - set mac c8:2a:14:14:f1:eb - set type mac - next - edit "macantha-wlan" - set mac e0:f8:47:03:c2:9a - next - edit "PI" - set mac b8:27:eb:5b:f4:3b - set type linux-pc - next - edit "fb7240" - set mac 00:24:fe:b9:18:42 - next - edit "Drucker" - set mac 00:15:99:b3:5e:fd - next - edit "QNAP Knappe" - set mac 00:08:9b:c4:ac:c1 - next -end -config user device-group - edit "Eltern-Device" - set member "tims-macbook-lan" "macantha-wlan" "PI" - next -end -config user security-exempt-list - edit "kids-wifi-exempt-list" - config rule - edit 1 - set dstaddr "drucker-10.0.0.38" - next - edit 2 - set dstaddr "fritzbox_inet_10.0.0.24" - next - edit 3 - set dstaddr "knappe_10.0.0.15" - next - edit 4 - set dstaddr "wlan-kids" - next - edit 5 - set dstaddr "kids-allowed-internet" - next - edit 6 - set service "PING" - next - end - next -end -config vpn ssl web realm - edit "test" - set login-page " - - - - - - - - Please Login - - - -
                      -
                      -
                      -
                      - - -
                      - Cactus FFM Login -
                      -
                      -
                      -
                      - %%SSL_LOGIN%% -
                      -
                      - -
                      -
                      -
                      -
                      -
                      - - %%SSL_HIDDEN%% - -" - next -end -config vpn ssl web portal - edit "tunnel-access" - set tunnel-mode enable - set ip-pools "SSl-VPN-10.0.0.40_24" - set split-tunneling-routing-address "knappe_10.0.0.15" "internal-10.0.0.35_24" - next - edit "test-token-auth-vpn-profile" - set tunnel-mode enable - set ip-pools "SSl-VPN-10.0.0.40_24" - set split-tunneling-routing-address "knappe_10.0.0.15" - next -end -config vpn ssl settings - set servercert "fg60d.ffm.cactus.de" - set idle-timeout 0 - set tunnel-ip-pools "SSl-VPN-10.0.0.40_24" - set port 60320 - set source-interface "wan1" - set source-address "all" - set source-address6 "all" - set default-portal "tunnel-access" -end -config voip profile - edit "default" - set comment "Default VoIP profile." - next -end -config webfilter profile - edit "sniffer-profile" - set comment "Monitor web traffic." - set inspection-mode flow-based - config ftgd-wf - config filters - edit 1 - next - edit 2 - set category 1 - next - edit 3 - set category 2 - next - edit 4 - set category 3 - next - edit 5 - set category 4 - next - edit 6 - set category 5 - next - edit 7 - set category 6 - next - edit 8 - set category 7 - next - edit 9 - set category 8 - next - edit 10 - set category 9 - next - edit 11 - set category 11 - next - edit 12 - set category 12 - next - edit 13 - set category 13 - next - edit 14 - set category 14 - next - edit 15 - set category 15 - next - edit 16 - set category 16 - next - edit 17 - set category 17 - next - edit 18 - set category 18 - next - edit 19 - set category 19 - next - edit 20 - set category 20 - next - edit 21 - set category 23 - next - edit 22 - set category 24 - next - edit 23 - set category 25 - next - edit 24 - set category 26 - next - edit 25 - set category 28 - next - edit 26 - set category 29 - next - edit 27 - set category 30 - next - edit 28 - set category 31 - next - edit 29 - set category 33 - next - edit 30 - set category 34 - next - edit 31 - set category 35 - next - edit 32 - set category 36 - next - edit 33 - set category 37 - next - edit 34 - set category 38 - next - edit 35 - set category 39 - next - edit 36 - set category 40 - next - edit 37 - set category 41 - next - edit 38 - set category 42 - next - edit 39 - set category 43 - next - edit 40 - set category 44 - next - edit 41 - set category 46 - next - edit 42 - set category 47 - next - edit 43 - set category 48 - next - edit 44 - set category 49 - next - edit 45 - set category 50 - next - edit 46 - set category 51 - next - edit 47 - set category 52 - next - edit 48 - set category 53 - next - edit 49 - set category 54 - next - edit 50 - set category 55 - next - edit 51 - set category 56 - next - edit 52 - set category 57 - next - edit 53 - set category 58 - next - edit 54 - set category 59 - next - edit 55 - set category 61 - next - edit 56 - set category 62 - next - edit 57 - set category 63 - next - edit 58 - set category 64 - next - edit 59 - set category 65 - next - edit 60 - set category 66 - next - edit 61 - set category 67 - next - edit 62 - set category 68 - next - edit 63 - set category 69 - next - edit 64 - set category 70 - next - edit 65 - set category 71 - next - edit 66 - set category 72 - next - edit 67 - set category 75 - next - edit 68 - set category 76 - next - edit 69 - set category 77 - next - edit 70 - set category 78 - next - edit 71 - set category 79 - next - edit 72 - set category 80 - next - edit 73 - set category 81 - next - edit 74 - set category 82 - next - edit 75 - set category 83 - next - edit 76 - set category 84 - next - edit 77 - set category 85 - next - edit 78 - set category 86 - next - edit 79 - set category 87 - next - edit 80 - set category 88 - next - edit 81 - set category 89 - next - end - end - next - edit "default" - set comment "Default web filtering." - set inspection-mode flow-based - set ovrd-perm bannedword-override urlfilter-override fortiguard-wf-override contenttype-check-override - config override - set ovrd-user-group "Admins" - set profile "flow-monitor-all" - end - config web - set urlfilter-table 1 - set blacklist enable - set safe-search url header - end - config ftgd-wf - set options error-allow http-err-detail rate-server-ip - set category-override 140 141 - set ovrd 1 4 5 6 12 59 62 83 14 15 16 67 72 26 61 86 - config filters - edit 3 - set category 8 - next - edit 6 - set category 12 - set action block - next - edit 7 - set category 13 - next - edit 8 - set category 14 - set action block - next - edit 9 - set category 15 - set action block - next - edit 10 - set category 16 - set action block - next - edit 11 - next - edit 14 - set category 64 - next - edit 17 - set category 67 - set action block - next - edit 18 - set category 26 - set action block - next - edit 19 - set category 61 - set action block - next - edit 20 - set category 86 - set action block - next - edit 47 - set category 1 - set action block - next - edit 49 - set category 4 - set action block - next - edit 50 - set category 5 - set action block - next - edit 51 - set category 6 - set action block - next - edit 52 - set category 59 - set action block - next - edit 53 - set category 62 - set action block - next - edit 55 - set category 83 - set action block - next - edit 56 - set category 72 - set action block - next - edit 57 - set category 140 - next - edit 58 - set category 141 - next - end - end - next - edit "flow-monitor-all" - set comment "Monitor and log all visited URLs, flow-based." - set inspection-mode flow-based - config ftgd-wf - unset options - config filters - edit 1 - set category 1 - next - edit 2 - set category 3 - next - edit 3 - set category 4 - next - edit 4 - set category 5 - next - edit 5 - set category 6 - next - edit 6 - set category 12 - next - edit 7 - set category 59 - next - edit 8 - set category 62 - next - edit 9 - set category 83 - next - edit 10 - set category 2 - next - edit 11 - set category 7 - next - edit 12 - set category 8 - next - edit 13 - set category 9 - next - edit 14 - set category 11 - next - edit 15 - set category 13 - next - edit 16 - set category 14 - next - edit 17 - set category 15 - next - edit 18 - set category 16 - next - edit 19 - set category 57 - next - edit 20 - set category 63 - next - edit 21 - set category 64 - next - edit 22 - set category 65 - next - edit 23 - set category 66 - next - edit 24 - set category 67 - next - edit 25 - set category 19 - next - edit 26 - set category 24 - next - edit 27 - set category 25 - next - edit 28 - set category 72 - next - edit 29 - set category 75 - next - edit 30 - set category 76 - next - edit 31 - set category 26 - next - edit 32 - set category 61 - next - edit 33 - set category 86 - next - edit 34 - set category 17 - next - edit 35 - set category 18 - next - edit 36 - set category 20 - next - edit 37 - set category 23 - next - edit 38 - set category 28 - next - edit 39 - set category 29 - next - edit 40 - set category 30 - next - edit 41 - set category 33 - next - edit 42 - set category 34 - next - edit 43 - set category 35 - next - edit 44 - set category 36 - next - edit 45 - set category 37 - next - edit 46 - set category 38 - next - edit 47 - set category 39 - next - edit 48 - set category 40 - next - edit 49 - set category 42 - next - edit 50 - set category 44 - next - edit 51 - set category 46 - next - edit 52 - set category 47 - next - edit 53 - set category 48 - next - edit 54 - set category 54 - next - edit 55 - set category 55 - next - edit 56 - set category 58 - next - edit 57 - set category 68 - next - edit 58 - set category 69 - next - edit 59 - set category 70 - next - edit 60 - set category 71 - next - edit 61 - set category 77 - next - edit 62 - set category 78 - next - edit 63 - set category 79 - next - edit 64 - set category 80 - next - edit 65 - set category 82 - next - edit 66 - set category 85 - next - edit 67 - set category 87 - next - edit 68 - set category 31 - next - edit 69 - set category 41 - next - edit 70 - set category 43 - next - edit 71 - set category 49 - next - edit 72 - set category 50 - next - edit 73 - set category 51 - next - edit 74 - set category 52 - next - edit 75 - set category 53 - next - edit 76 - set category 56 - next - edit 77 - set category 81 - next - edit 78 - set category 84 - next - edit 79 - next - edit 80 - set category 89 - next - end - end - set log-all-url enable - set web-content-log disable - set web-filter-activex-log disable - set web-filter-command-block-log disable - set web-filter-cookie-log disable - set web-filter-applet-log disable - set web-filter-jscript-log disable - set web-filter-js-log disable - set web-filter-vbs-log disable - set web-filter-unknown-log disable - set web-filter-referer-log disable - set web-filter-cookie-removal-log disable - set web-url-log disable - set web-invalid-domain-log disable - set web-ftgd-err-log disable - set web-ftgd-quota-usage disable - next -end -config webfilter ftgd-local-rating - edit "10.0.0.24" - set rating 81 - next - edit "r.adc-srv.net" - set rating 0 - next -end -config webfilter search-engine - edit "google" - set hostname ".*\\.google\\..*" - set url "^\\/((custom|search|images|videosearch|webhp)\\?)" - set query "q=" - set safesearch url - set safesearch-str "&safe=active" - next - edit "yahoo" - set hostname ".*\\.yahoo\\..*" - set url "^\\/search(\\/video|\\/images){0,1}(\\?|;)" - set query "p=" - set safesearch url - set safesearch-str "&vm=r" - next - edit "bing" - set hostname ".*\\.bing\\..*" - set url "^(\\/images|\\/videos)?(\\/search|\\/async|\\/asyncv2)\\?" - set query "q=" - set safesearch header - next - edit "yandex" - set hostname ".*\\.yandex\\..*" - set url "^\\/((yand|images\\/|video\\/)(search)|search\\/)\\?" - set query "text=" - set safesearch url - set safesearch-str "&family=yes" - next - edit "youtube" - set hostname ".*\\.youtube\\..*" - set safesearch header - next - edit "baidu" - set hostname ".*\\.baidu\\.com" - set url "^\\/s?\\?" - set query "wd=" - next - edit "baidu2" - set hostname ".*\\.baidu\\.com" - set url "^\\/(ns|q|m|i|v)\\?" - set query "word=" - next - edit "baidu3" - set hostname "tieba\\.baidu\\.com" - set url "^\\/f\\?" - set query "kw=" - next -end -config vpn ipsec phase1-interface - edit "Cactus-DA" - set interface "wan1" - set peertype any - set proposal aes256-sha384 - set comments "VPN: Cactus-DA (Created by VPN wizard)" - set dhgrp 20 - set remote-gw 10.0.0.69 - set psksecret ENC vl9TmbxHqUB+b9MrAk312iitWlVPYXT//JQxCwYKGmll+4tbvwwa1BS1jxwSJiAcwiN+lI6agSytyTMSNqwvskfVyHp37ypmwTWvbodHlR5U8cfjpw8qtmSFoAGum6eyJqYePce0iWvqyjaOgz370qQAdSlFBQHQ5PwNegC11nSfr2oeSmosF+4R1x+h/kh1t7PJYQ== - next -end -config vpn ipsec phase2-interface - edit "Cactus-DA" - set phase1name "Cactus-DA" - set proposal aes256-sha384 - set dhgrp 20 - set auto-negotiate enable - set comments "VPN: Cactus-DA (Created by VPN wizard)" - set src-subnet 10.0.0.35 255.255.255.255 - set dst-subnet 10.0.0.60 255.255.255.255 - next - edit "DA-LAN 2 FFM-Server" - set phase1name "Cactus-DA" - set proposal aes256-sha384 - set dhgrp 20 - set auto-negotiate enable - set src-subnet 10.0.0.63 255.255.255.255 - set dst-subnet 10.0.0.60 255.255.255.255 - next - edit "wch60" - set phase1name "Cactus-DA" - set proposal aes256-sha384 - set dhgrp 20 - set auto-negotiate enable - set src-subnet 10.0.0.61 255.255.255.255 - set dst-subnet 10.0.0.60 255.255.255.255 - next - edit "fg2splunk" - set phase1name "Cactus-DA" - set proposal aes256-sha384 - set dhgrp 20 - set auto-negotiate enable - set comments "allow fortigate to log to splunk" - set src-addr-type ip - set src-start-ip 10.0.0.1 - set dst-subnet 10.0.0.70 255.255.255.255 - next -end -config system dns-database - edit "ffm.cactus.de" - set domain "ffm.cactus.de" - set view public - set ttl 86000 - config dns-entry - edit 1 - set hostname "proxy" - set ip 10.0.0.7 - next - edit 2 - set hostname "fg60d" - set ip 10.0.0.7 - next - end - set primary-name "fg60d" - set contact "tmp@cactus.de" - next -end -config system dns-server - edit "server-lan2" - next - edit "internal" - next -end -config antivirus settings - set grayware enable -end -config antivirus profile - edit "sniffer-profile" - set comment "Scan files and monitor viruses." - config http - set options scan - end - config ftp - set options scan - end - config imap - set options scan - set executables virus - end - config pop3 - set options scan - set executables virus - end - config smtp - set options scan - set executables virus - end - next - edit "default" - set comment "Scan files and block viruses." - config http - set options scan - end - config ftp - set options scan - end - config imap - set options scan - end - config pop3 - set options scan - end - config smtp - set options scan - end - next -end -config spamfilter profile - edit "sniffer-profile" - set comment "Malware and phishing URL monitoring." - set flow-based enable - next - edit "default" - set comment "Malware and phishing URL filtering." - set flow-based enable - set spam-filtering enable - set options spamfsip spamfssubmit spamfschksum spamfsurl spamhelodns spamraddrdns spamfsphish - next -end -config firewall schedule recurring - edit "always" - set day sunday monday tuesday wednesday thursday friday saturday - next - edit "kids-all-day" - set start 11:00 - set end 23:00 - set day sunday monday tuesday wednesday thursday friday saturday - next - edit "kids-late" - set start 07:00 - set end 23:00 - set day friday saturday - next -end -config firewall schedule group - edit "Kids-all-times-group" - set member "kids-all-day" "kids-late" - next -end -config firewall ippool - edit "test-v4-pool" - set startip 10.0.0.71 - set endip 10.0.0.72 - set comments "afasd fasd f" - next -end -config firewall ippool6 - edit "test-v6-pool" - set startip ::34 - set endip ::45 - set comments "asdfa sdf" - next -end -config firewall vip - edit "test-virtual-ip-v4" - set uuid e27fe466-17ad-51e6-6f8c-9c54c678584e - set comment "tasdfas dasd fas" - set extip 10.0.0.73-10.0.0.74 - set extintf "internal" - set portforward enable - set mappedip "10.0.0.75-10.0.0.76" - set extport 1-23 - set mappedport 23-45 - next -end -config firewall vip6 - edit "test-virtual-ip-v6" - set uuid 2b50ee56-17ae-51e6-a950-ff8c65749b11 - set comment "df asdfasdf" - set extip 13::-14:: - set mappedip 18::-19:: - set portforward enable - set extport 234-2388 - set mappedport 33-2187 - next -end -config firewall vipgrp - edit "test-virtual-ip-v4-group" - set uuid f89dde92-17ad-51e6-ac5d-be107e1fca94 - set interface "internal" - set comments "asd f" - set member "test-virtual-ip-v4" - next -end -config firewall vipgrp6 - edit "test-virtual-ip-v6-group" - set uuid 3b76459c-17ae-51e6-202d-ed3c29bd3e7b - set comments "asdf asdfasdf" - set member "test-virtual-ip-v6" - next -end -config firewall profile-protocol-options - edit "default" - set comment "All default services." - set oversize-log enable - config http - set ports 80 - set options clientcomfort - unset post-lang - end - config ftp - set ports 21 - set options clientcomfort splice - end - config imap - set ports 143 - set options fragmail - end - config mapi - set ports 135 - set options fragmail - end - config pop3 - set ports 110 - set options fragmail - end - config smtp - set ports 25 - set options fragmail splice - end - config nntp - set ports 119 - set options splice - end - config dns - set ports 53 - end - next - edit "default_default_sc" - set comment "All default services." - set oversize-log enable - config http - set ports 80 - set options clientcomfort servercomfort - unset post-lang - end - config ftp - set ports 21 - set options clientcomfort splice - end - config imap - set ports 143 - set options fragmail - end - config mapi - set ports 135 - set options fragmail - end - config pop3 - set ports 110 - set options fragmail - end - config smtp - set ports 25 - set options fragmail splice - end - config nntp - set ports 119 - set options splice - end - config dns - set ports 53 - end - next -end -config firewall ssl-ssh-profile - edit "deep-inspection" - set comment "Deep inspection." - config https - set ports 443 - end - config ftps - set ports 990 - end - config imaps - set ports 993 - end - config pop3s - set ports 995 - end - config smtps - set ports 465 - end - config ssl-exempt - edit 1 - set fortiguard-category 31 - next - edit 2 - set fortiguard-category 33 - next - edit 3 - set fortiguard-category 87 - next - edit 4 - set type address - set address "apple" - next - edit 5 - set type address - set address "appstore" - next - edit 6 - set type address - set address "dropbox.com" - next - edit 7 - set type address - set address "Gotomeeting" - next - edit 8 - set type address - set address "icloud" - next - edit 9 - set type address - set address "itunes" - next - edit 10 - set type address - set address "android" - next - edit 11 - set type address - set address "skype" - next - edit 12 - set type address - set address "swscan.apple.com" - next - edit 13 - set type address - set address "update.microsoft.com" - next - edit 14 - set type address - set address "eease" - next - edit 15 - set type address - set address "google-drive" - next - edit 16 - set type address - set address "google-play" - next - edit 17 - set type address - set address "google-play2" - next - edit 18 - set type address - set address "google-play3" - next - edit 19 - set type address - set address "microsoft" - next - edit 20 - set type address - set address "adobe" - next - edit 21 - set type address - set address "Adobe Login" - next - edit 22 - set type address - set address "fortinet" - next - edit 23 - set type address - set address "googleapis.com" - next - edit 24 - set type address - set address "citrix" - next - edit 25 - set type address - set address "verisign" - next - edit 26 - set type address - set address "Windows update 2" - next - edit 27 - set type address - set address "*.live.com" - next - edit 28 - set type address - set address "auth.gfx.ms" - next - edit 29 - set type address - set address "autoupdate.opera.com" - next - edit 30 - set type address - set address "softwareupdate.vmware.com" - next - edit 31 - set type address - set address "firefox update server" - next - end - set caname "Fortinet_CA_SSLProxy" - set certname "Fortinet_SSLProxy" - next - edit "certificate-inspection" - set comment "SSL handshake inspection." - config https - set ports 443 - set status certificate-inspection - set allow-invalid-server-cert enable - end - config ftps - set ports 990 - set status disable - set allow-invalid-server-cert enable - end - config imaps - set ports 993 - set status disable - set allow-invalid-server-cert enable - end - config pop3s - set ports 995 - set status disable - set allow-invalid-server-cert enable - end - config smtps - set ports 465 - set status disable - set allow-invalid-server-cert enable - end - set caname "Fortinet_CA_SSLProxy" - set certname "Fortinet_SSLProxy" - set ssl-invalid-server-cert-log enable - next -end -config firewall policy - edit 76 - set name "eltern keller to inet1" - set uuid 1a3b9474-fa6e-51e6-8066-477298fe055a - set srcintf "internal5" - set dstintf "wan1" - set srcaddr "all" - set dstaddr "gware.cactus.de_10.0.0.43" - set action accept - set schedule "always" - set service "PING" "SMTPS" "HTTPS" "IMAPS" - set comments "Clone of quiet mail gware" - next - edit 78 - set name "keller2inet-main" - set uuid 7b405f16-fa6e-51e6-b6fe-4bc9d0cd9ac7 - set srcintf "internal5" - set dstintf "wan1" - set srcaddr "eltern-keller-10.0.0.66_24" - set dstaddr "all" - set action accept - set schedule "always" - set service "ALL" - set utm-status enable - set logtraffic all - set comments "Clone of WLAN to Internet" - set scan-botnet-connections block - set av-profile "default" - set webfilter-profile "default" - set ips-sensor "default" - set application-list "default" - set profile-protocol-options "default" - next - edit 77 - set name "eltern2klautquiet" - set uuid 579b6b6e-fa6e-51e6-bace-9e8914986ac0 - set srcintf "internal5" - set dstintf "wan1" - set srcaddr "all" - set dstaddr "klaut.cactus.de" - set action accept - set schedule "always" - set service "PING" "HTTPS" - set comments "Clone of 37" - next - edit 33 - set name "quiet mail gware" - set uuid 0298a2ea-c1ca-51e5-5da8-61bf55ac3079 - set srcintf "internal" - set dstintf "wan1" - set srcaddr "all" - set dstaddr "gware.cactus.de_10.0.0.43" - set action accept - set schedule "always" - set service "PING" "SMTPS" "HTTPS" "IMAPS" - set comments "silent mail@cactus" - next - edit 37 - set uuid 546461e8-c299-51e5-c788-1ccacb1fbacc - set srcintf "internal" - set dstintf "wan1" - set srcaddr "all" - set dstaddr "klaut.cactus.de" - set action accept - set schedule "always" - set service "PING" "HTTPS" - set comments "silent klaut.cactus.de" - next - edit 32 - set name "internal 2 dns" - set uuid b875cb0c-c1c9-51e5-9179-bfb5080a3d9e - set srcintf "internal" - set dstintf "wan1" - set srcaddr "all" - set dstaddr "fritzbox_inet_10.0.0.24" "opendns_10.0.0.48" - set action accept - set schedule "always" - set service "DNS" "PING" - set comments "silent dns" - next - edit 16 - set uuid e2416cd8-bc7f-51e5-2708-ccfa8b1e4480 - set srcintf "internal" - set dstintf "wan1" - set srcaddr "tims-macbook" "macantha_wlan_10.0.0.37" - set dstaddr "fritzbox_inet_10.0.0.24" - set action accept - set status disable - set schedule "always" - set service "ALL" - set logtraffic all - set devices "Eltern-Device" - next - edit 14 - set uuid 95493190-bc7f-51e5-ca8b-5cd7f064f885 - set srcintf "internal" - set dstintf "wan1" - set srcaddr "all" - set dstaddr "fritzbox_inet_10.0.0.24" - set status disable - set schedule "always" - set service "ALL" - set logtraffic all - next - edit 6 - set name "eltern internal LAN to Inet" - set uuid d8d71542-aa3e-51e5-49bc-a1d2b82d27cc - set srcintf "internal" - set dstintf "wan1" - set srcaddr "tims-macbook" "pi_10.0.0.52" "macantha_at_pi_10.0.0.54" - set dstaddr "all" - set action accept - set status disable - set schedule "always" - set service "ALL" - set utm-status enable - set logtraffic all - set devices "Eltern-Device" - set comments "disabled - exploited by mac spoofing" - set scan-botnet-connections block - set av-profile "default" - set profile-protocol-options "default" - next - edit 40 - set name "LG Fernseher to LG" - set uuid 44675e94-cb5e-51e5-3c6c-ff29dda7aeae - set srcintf "internal" - set dstintf "wan1" - set srcaddr "LG Fernseher 10.0.0.44" - set dstaddr "LG Server 10.0.0.45_24" - set action accept - set schedule "always" - set service "HTTP" - set utm-status enable - set logtraffic all - set scan-botnet-connections block - set av-profile "default" - set webfilter-profile "default" - set ips-sensor "default" - set application-list "default" - set casi-profile "default" - set profile-protocol-options "default" - next - edit 41 - set name "LG Fernseher to Mediatheken" - set uuid 28e57196-cb5f-51e5-679f-b8e1d3460fce - set srcintf "internal" - set dstintf "wan1" - set srcaddr "LG Fernseher 10.0.0.44" - set dstaddr "all" - set action accept - set schedule "always" - set service "HTTP" "HTTPS" "PING" "NTP" - set utm-status enable - set logtraffic all - set scan-botnet-connections block - set av-profile "default" - set webfilter-profile "default" - set ips-sensor "default" - set application-list "default" - set casi-profile "default" - set profile-protocol-options "default" - next - edit 39 - set name "WLAN to Internet" - set uuid 499260b4-ca85-51e5-9aa1-d9124b6595db - set srcintf "internal" - set dstintf "wan1" - set srcaddr "fritzbox_oben_nat_10.0.0.18" "wlan_pi_10.0.0.53_24" "fb7240_10.0.0.55" - set dstaddr "all" - set action accept - set schedule "always" - set service "ALL" - set utm-status enable - set logtraffic all - set comments "Standard Access from wlan to internet" - set scan-botnet-connections block - set av-profile "default" - set webfilter-profile "default" - set ips-sensor "default" - set application-list "default" - set profile-protocol-options "default" - next - edit 38 - set name "drop kids without fritzbox" - set uuid 3acce722-ca79-51e5-baa1-994c1a43ac1d - set srcintf "internal" - set dstintf "wan1" - set srcaddr "internal-10.0.0.35_24" - set dstaddr "all" - set schedule "always" - set service "ALL" - set logtraffic all - set comments "drop all traffic not passing fritzbox checks" - set scan-botnet-connections block - next - edit 10 - set uuid 518c99fa-ba23-51e5-d393-45d387149eec - set srcintf "internal" - set dstintf "wan1" - set srcaddr "internal-10.0.0.35_24" - set dstaddr "all" - set action accept - set status disable - set schedule "Kids-all-times-group" - set service "ALL" - set utm-status enable - set logtraffic all - set groups "Kinder-group" - set scan-botnet-connections block - set av-profile "default" - set webfilter-profile "default" - set ips-sensor "default" - set application-list "default" - set casi-profile "default" - set profile-protocol-options "default_default_sc" - next - edit 1 - set uuid 77e8dc72-86c9-51e5-9dc3-544dc707dc81 - set srcintf "internal" - set dstintf "wan1" - set srcaddr "all" - set dstaddr "all" - set action accept - set status disable - set schedule "always" - set service "ALL" - set utm-status enable - set logtraffic all - set comments "with tls break-up" - set scan-botnet-connections block - set av-profile "default" - set webfilter-profile "default" - set ips-sensor "default" - set application-list "default" - set casi-profile "default" - set profile-protocol-options "default_default_sc" - set ssl-ssh-profile "certificate-inspection" - next - edit 25 - set uuid c9d3562c-bd59-51e5-5f2a-1698c0490655 - set srcintf "internal" - set dstintf "wan1" - set srcaddr "fritzbox_oben_nat_10.0.0.18" - set dstaddr "www.avm.de" - set action accept - set schedule "always" - set service "tcp-8011-to-avm" - set logtraffic disable - set comments "8011 to avm, nolog" - set label "test sect" - next - edit 35 - set uuid 199cc77e-c205-51e5-9d2f-765affac991a - set srcintf "internal" - set dstintf "wan1" - set srcaddr "all" - set dstaddr "all" - set schedule "always" - set service "tcp_40000_up" - set logtraffic all - set comments "block suspicious ports" - set label "test sect" - next - edit 34 - set name "block traffic to russia and india" - set uuid f32caa9c-c203-51e5-e204-71228e45c9b2 - set srcintf "internal" - set dstintf "wan1" - set srcaddr "all" - set dstaddr "geo-china" "geo-russia" - set schedule "always" - set service "ALL" - set logtraffic all - set comments "block suspicious geo dest" - set label "test sect" - next - edit 15 - set name "standard internet out" - set uuid bc18243e-bc7f-51e5-e874-cdd9e86159a7 - set srcintf "internal" - set dstintf "wan1" - set srcaddr "all" - set dstaddr "all" - set action accept - set status disable - set schedule "always" - set service "ALL" - set utm-status enable - set logtraffic all - set comments "standard internet outbound" - set label "test sect" - set scan-botnet-connections block - set av-profile "default" - set webfilter-profile "default" - set ips-sensor "default" - set application-list "default" - set casi-profile "default" - set profile-protocol-options "default" - next - edit 3 - set name "internet to gameserver" - set uuid af3df160-a9c1-51e5-07b7-2d57727326f2 - set srcintf "wan1" - set dstintf "dmz" - set srcaddr "all" - set dstaddr "ubuntu-gameserver-10.0.0.51" - set action accept - set schedule "always" - set service "ARK-7777-7778-udp" "minecraft-25565" "PING" "steam-udp-27000-27050" "ark-udp-32768-65535" - set utm-status enable - set logtraffic all - set comments "internet to gameserver" - set ips-sensor "default" - set application-list "default" - set casi-profile "default" - set profile-protocol-options "default" - next - edit 70 - set name "fb drop scans" - set uuid 22b0b712-e0c2-51e6-330e-d42a4bb3d9ed - set srcintf "wan1" - set dstintf "dmz" - set srcaddr "fritzbox_inet_10.0.0.24" - set dstaddr "ubuntu-gameserver-10.0.0.51" - set schedule "always" - set service "HTTP" "tcp14013-fb" - set logtraffic disable - set comments "silent drop fb2internal" - next - edit 4 - set name "game server access" - set uuid bbfddc4e-a9c1-51e5-2694-d0f5c44275a0 - set srcintf "internal" - set dstintf "dmz" - set srcaddr "internal-10.0.0.35_24" "wlan_pi_10.0.0.53_24" - set dstaddr "ubuntu-gameserver-10.0.0.51" - set action accept - set schedule "always" - set service "ARK-7777-7778-udp" "minecraft-25565" "SSH" "PING" "steam-udp-27000-27050" "ark-udp-32768-65535" - set logtraffic all - set comments "internal to gameserver" - next - edit 48 - set name "udp high ports to ark" - set uuid de60d372-d58b-51e5-8fd3-93e18d731cea - set srcintf "internal" - set dstintf "dmz" - set srcaddr "internal-10.0.0.35_24" "wlan_pi_10.0.0.53_24" - set dstaddr "ubuntu-gameserver-10.0.0.51" - set action accept - set schedule "always" - set service "udp-high-ports" - set logtraffic all - set comments "fucking ark server using dynamic ports for user sessions" - next - edit 20 - set name "gameserver ubuntu updates" - set uuid 419fb5c8-bcf2-51e5-303a-950b2339b9f4 - set srcintf "dmz" - set dstintf "wan1" - set srcaddr "ubuntu-gameserver-10.0.0.51" - set dstaddr "security.ubuntu.com" "de.archive.ubuntu.com" "extras.ubuntu.com" - set action accept - set schedule "always" - set service "HTTP" "HTTPS" "PING" - set logtraffic disable - set comments "ubuntu updates" - next - edit 42 - set name "temp steam update" - set uuid 1902acca-cc19-51e5-3ae2-d6508fed8fbb - set srcintf "dmz" - set dstintf "wan1" - set srcaddr "ubuntu-gameserver-10.0.0.51" - set dstaddr "all" - set action accept - set schedule "always" - set service "HTTP" "HTTPS" "PING" "steam-udp-27000-27050" "valve_ports" "steam-tcp-27015-27020" - set utm-status enable - set logtraffic disable - set comments "temp rule" - set av-profile "default" - set webfilter-profile "default" - set ips-sensor "default" - set application-list "default" - set casi-profile "default" - set profile-protocol-options "default" - set ssl-ssh-profile "certificate-inspection" - next - edit 75 - set name "ARK - temp test 2017-02-17" - set uuid d42e9a08-f53b-51e6-2a32-589092093ffe - set srcintf "dmz" - set dstintf "wan1" - set srcaddr "ubuntu-gameserver-10.0.0.51" - set dstaddr "all" - set action accept - set schedule "always" - set service "udp-high-ports" "ARK-7777-7778-tcp" "ARK-7777-7778-udp" - set utm-status enable - set comments "Clone of temp steam update" - set av-profile "default" - set webfilter-profile "default" - set ips-sensor "default" - set application-list "default" - set casi-profile "default" - set profile-protocol-options "default" - set ssl-ssh-profile "certificate-inspection" - next - edit 46 - set name "outbound 2 10.0.0.49" - set uuid c9502a94-d583-51e5-cd09-9c9887ffafbc - set srcintf "dmz" - set dstintf "wan1" - set srcaddr "ubuntu-gameserver-10.0.0.51" - set dstaddr "valve_10.0.0.49" - set action accept - set status disable - set schedule "always" - set service "PING" "valve_ports" - set utm-status enable - set logtraffic disable - set comments "Clone of temp ubuntu steam update" - set av-profile "default" - set webfilter-profile "default" - set ips-sensor "default" - set application-list "default" - set casi-profile "default" - set profile-protocol-options "default" - set ssl-ssh-profile "certificate-inspection" - next - edit 47 - set name "temp outbound all to valve" - set uuid 84e03cde-d58b-51e5-7e5a-5562db3da154 - set srcintf "dmz" - set dstintf "wan1" - set srcaddr "ubuntu-gameserver-10.0.0.51" - set dstaddr "valve_10.0.0.49" "valve_10.0.0.50" - set action accept - set status disable - set schedule "always" - set service "ALL" - set utm-status enable - set logtraffic disable - set comments "Clone of outbound 2 10.0.0.49" - set av-profile "default" - set webfilter-profile "default" - set ips-sensor "default" - set application-list "default" - set casi-profile "default" - set profile-protocol-options "default" - set ssl-ssh-profile "certificate-inspection" - next - edit 21 - set name "game-server to dns-inet" - set uuid bdefc324-bd0c-51e5-16af-8449c799c4e2 - set srcintf "dmz" - set dstintf "wan1" - set srcaddr "ubuntu-gameserver-10.0.0.51" - set dstaddr "fritzbox_10.0.0.24_global" "G-google-dns-srv" - set action accept - set schedule "always" - set service "DNS" - set logtraffic disable - set comments "dns" - next - edit 83 - set name "gameserver ntp" - set uuid 4d9e56b2-00b8-51e7-1680-479939b2ed12 - set srcintf "dmz" - set dstintf "wan1" - set srcaddr "ubuntu-gameserver-10.0.0.51" - set dstaddr "all" - set action accept - set schedule "always" - set service "NTP" - set logtraffic disable - set comments "Clone of game-server to dns-inet" - next - edit 54 - set name "wlan2serverlan" - set uuid 4f83d548-be63-51e6-a06a-b589fa6823c4 - set srcintf "wlan0" - set dstintf "server-lan2" - set srcaddr "fwf60-wlan-client-net" - set dstaddr "knappe_10.0.0.15" - set action accept - set schedule "always" - set service "HTTPS" "SMB" "afp_548_tcp" "PING" "tcp_8081_phpfreechat" "SQUID" "SSH" "HTTP" - set utm-status enable - set logtraffic all - set comments "Clone of internal to knappe" - set scan-botnet-connections block - next - edit 80 - set name "eltern-keller-2-knappe" - set uuid fd4eed4c-fa6e-51e6-e6a3-05d4b593e7d6 - set srcintf "internal5" - set dstintf "server-lan2" - set srcaddr "eltern-keller-10.0.0.66_24" - set dstaddr "knappe_10.0.0.15" - set action accept - set schedule "always" - set service "HTTPS" "SMB" "afp_548_tcp" "PING" "tcp_8081_phpfreechat" "SQUID" "SSH" "HTTP" - set utm-status enable - set logtraffic all - set comments "Clone of internal to knappe" - set scan-botnet-connections block - next - edit 5 - set name "internal to knappe" - set uuid 5fd8bdb6-a9c2-51e5-5169-46ffaf0999b8 - set srcintf "internal" - set dstintf "server-lan2" - set srcaddr "internal-10.0.0.35_24" "wlan_10.0.0.36_24" "wlan_pi_10.0.0.53_24" - set dstaddr "knappe_10.0.0.15" - set action accept - set schedule "always" - set service "HTTPS" "SMB" "afp_548_tcp" "PING" "tcp_8081_phpfreechat" "SQUID" "SSH" "HTTP" - set utm-status enable - set logtraffic all - set comments "knappe standard access" - set scan-botnet-connections block - next - edit 65 - set name "silently drop 139/tcp" - set uuid f977fcdc-c381-51e6-c875-ee13adc7114e - set srcintf "internal" - set dstintf "server-lan2" - set srcaddr "internal-10.0.0.35_24" - set dstaddr "knappe_10.0.0.15" - set schedule "always" - set service "SAMBA" - set logtraffic disable - set comments "Clone of internal to knappe" - set scan-botnet-connections block - next - edit 66 - set name "drop 139/tcp from wch60e2knappe" - set uuid 26d1beac-c382-51e6-1bc5-81fee87dfd6b - set srcintf "wlan0" - set dstintf "server-lan2" - set srcaddr "fwf60-wlan-client-net" - set dstaddr "knappe_10.0.0.15" - set schedule "always" - set service "SAMBA" - set logtraffic disable - set comments "Clone of silently drop 139/tcp" - set scan-botnet-connections block - next - edit 55 - set name "wlan2printer" - set uuid 75eee1e6-be63-51e6-42cc-9973ac16e83e - set srcintf "wlan0" - set dstintf "server-lan2" - set srcaddr "fwf60-wlan-client-net" - set dstaddr "drucker-10.0.0.38" - set action accept - set schedule "always" - set service "ALL" - set logtraffic all - set comments "wlan to printer" - next - edit 63 - set name "drop internal cross-nw traffic" - set uuid 32265eac-c2a1-51e6-6acd-4193bb50eb00 - set srcintf "wlan0" - set dstintf "internal" - set srcaddr "fwf60-wlan-client-net" - set dstaddr "all" - set schedule "always" - set service "ALL" - set logtraffic disable - set comments "silent ignore" - next - edit 81 - set name "keller-printing" - set uuid 408dbad4-fa6f-51e6-b648-29f7127d0276 - set srcintf "internal5" - set dstintf "server-lan2" - set srcaddr "eltern-keller-10.0.0.66_24" - set dstaddr "drucker-10.0.0.38" - set action accept - set schedule "always" - set service "ALL" - set logtraffic all - set comments "Clone of internal to printer" - next - edit 19 - set name "internal to printer" - set uuid 488528d8-bc88-51e5-b8b9-3d9ff009fc03 - set srcintf "internal" - set dstintf "server-lan2" - set srcaddr "internal-10.0.0.35_24" "wlan_10.0.0.36_24" "wlan_pi_10.0.0.53_24" - set dstaddr "drucker-10.0.0.38" - set action accept - set schedule "always" - set service "ALL" - set logtraffic all - set comments "printing" - next - edit 51 - set name "test ssl vpn portal" - set uuid 452d358e-7e4a-51e6-6a15-c4a5e43ebd4e - set srcintf "ssl.root" - set dstintf "server-lan2" - set srcaddr "SSl-VPN-10.0.0.40_24" - set dstaddr "knappe_10.0.0.15" - set action accept - set status disable - set schedule "always" - set service "HTTPS" "tcp_8081_phpfreechat" - set utm-status enable - set groups "Admins" - set comments "Clone of SSL VPN access to knappe" - set scan-botnet-connections block - set av-profile "default" - set ips-sensor "default" - set application-list "default" - set casi-profile "default" - set profile-protocol-options "default" - set ssl-ssh-profile "certificate-inspection" - next - edit 26 - set name "SSL VPN access to knappe" - set uuid 509b3f4c-be1a-51e5-b177-86d105e69d94 - set srcintf "ssl.root" - set dstintf "server-lan2" - set srcaddr "SSl-VPN-10.0.0.40_24" - set dstaddr "knappe_10.0.0.15" - set action accept - set schedule "always" - set service "SAMBA" "HTTPS" "SMB" "afp_548_tcp" "PING" - set utm-status enable - set groups "Admins" - set comments "knappe vpn access" - set scan-botnet-connections block - set av-profile "default" - set ips-sensor "default" - set application-list "default" - set casi-profile "default" - set profile-protocol-options "default" - set ssl-ssh-profile "certificate-inspection" - next - edit 45 - set name "silently drop broadcasts" - set uuid dcf4ed44-d099-51e5-2b6e-a1c0f2a25ef1 - set srcintf "ssl.root" - set dstintf "server-lan2" - set srcaddr "all" - set dstaddr "broadcast" - set schedule "always" - set service "ALL" - set logtraffic disable - set groups "Admins" - set scan-botnet-connections block - next - edit 69 - set name "silently drop http" - set uuid 22fe7418-d8af-51e6-fd9e-d11227f5d41e - set srcintf "ssl.root" - set dstintf "server-lan2" - set srcaddr "all" - set dstaddr "all" - set schedule "always" - set service "HTTP" - set logtraffic disable - set groups "Admins" - set comments "silently drop http" - set scan-botnet-connections block - next - edit 36 - set name "admin FG and FB via ssl-VPN" - set uuid c29c9b50-c283-51e5-a66f-5c69302e8a3f - set srcintf "ssl.root" - set dstintf "internal" - set srcaddr "SSl-VPN-10.0.0.40_24" - set dstaddr "fg_internal_10.0.0.7" "pi_10.0.0.52" - set action accept - set schedule "always" - set service "HTTPS" "PING" "SSH" - set groups "Admins" - set comments "fw admin via ssl vpn" - next - edit 71 - set name "access to gameserver via ssl" - set uuid 254fae5e-e14b-51e6-c5e7-f5b61bc26a77 - set srcintf "ssl.root" - set dstintf "dmz" - set srcaddr "SSl-VPN-10.0.0.40_24" - set dstaddr "ubuntu-gameserver-10.0.0.51" - set action accept - set schedule "always" - set service "HTTPS" "PING" "SSH" - set groups "Admins" - set comments "Clone of admin FG and FB via ssl-VPN" - next - edit 44 - set name "admin fb internet via vpn" - set uuid 876f8672-ce69-51e5-8cb4-ff22dce238d9 - set srcintf "ssl.root" - set dstintf "wan1" - set srcaddr "SSl-VPN-10.0.0.40_24" - set dstaddr "fritzbox_inet_10.0.0.24" - set action accept - set schedule "always" - set service "HTTPS" "PING" "HTTP" - set groups "Admins" - set comments "Clone of admin FG and FB via ssl-VPN" - set nat enable - next - edit 79 - set name "ping-back-connect-keller" - set uuid c08bfb52-fa6e-51e6-4b24-f50c7c651800 - set srcintf "server-lan2" - set dstintf "internal5" - set srcaddr "drucker-10.0.0.38" - set dstaddr "eltern-keller-10.0.0.66_24" - set action accept - set schedule "always" - set service "PING" "tcp_5357_samsung_printer" - set logtraffic disable - set comments "Clone of samsung to print clients" - next - edit 64 - set name "samsung to print clients" - set uuid 9403e594-c360-51e6-683c-bb3cf21f60bb - set srcintf "server-lan2" - set dstintf "wlan0" - set srcaddr "drucker-10.0.0.38" - set dstaddr "fwf60-wlan-client-net" - set action accept - set schedule "always" - set service "PING" "tcp_5357_samsung_printer" - set logtraffic disable - next - edit 13 - set uuid c9d19496-bc7c-51e5-8f38-9fcc5d3e92e3 - set srcintf "server-lan2" - set dstintf "wan1" - set srcaddr "knappe_10.0.0.15" "drucker-10.0.0.38" - set dstaddr "fritzbox_inet_10.0.0.24" - set action accept - set schedule "always" - set service "PING" "DNS" - set logtraffic disable - set comments "dns" - next - edit 22 - set uuid fe25aff8-bd2a-51e5-b3a5-c967c81fe1b8 - set srcintf "server-lan2" - set dstintf "wan1" - set srcaddr "knappe_10.0.0.15" "drucker-10.0.0.38" - set dstaddr "all" - set action accept - set schedule "always" - set service "PING" "NTP" - set comments "get time" - next - edit 23 - set uuid 0369314c-bd2b-51e5-8216-09ca5ec33f19 - set srcintf "server-lan2" - set dstintf "wan1" - set srcaddr "knappe_10.0.0.15" - set dstaddr "qnap_update_net_10.0.0.39/32" "qnap-update-akamai-10.0.0.42_24" - set action accept - set schedule "always" - set service "PING" "HTTP" - set comments "qnap update" - next - edit 43 - set name "drop strange printer traffic" - set uuid 33097a18-cda4-51e5-543e-58f6ff7c576f - set srcintf "server-lan2" - set dstintf "wan1" - set srcaddr "drucker-10.0.0.38" - set dstaddr "net_10.0.0.64_24" - set schedule "always" - set service "ALL" - set logtraffic disable - set comments "strange printer requests" - next - edit 68 - set name "drop printer2google https" - set uuid c330df82-c475-51e6-fdba-5704cc720bbd - set srcintf "server-lan2" - set dstintf "wan1" - set srcaddr "drucker-10.0.0.38" - set dstaddr "all" - set schedule "always" - set service "HTTPS" - set logtraffic disable - set comments "2. drop strange printer traffic" - next - edit 49 - set name "qnap apps download" - set uuid a186a968-de0a-51e5-5de3-0806a9cf06c0 - set srcintf "server-lan2" - set dstintf "wan1" - set srcaddr "knappe_10.0.0.15" - set dstaddr "all" - set action accept - set schedule "always" - set service "HTTP" "HTTPS" "PING" - set utm-status enable - set av-profile "default" - set webfilter-profile "default" - set ips-sensor "default" - set application-list "default" - set casi-profile "default" - set profile-protocol-options "default" - set ssl-ssh-profile "certificate-inspection" - next - edit 67 - set name "knappe2gware" - set uuid 840c4934-c44a-51e6-a848-1016a845713e - set srcintf "server-lan2" - set dstintf "wan1" - set srcaddr "knappe_10.0.0.15" - set dstaddr "gware.cactus.de_10.0.0.43" - set action accept - set schedule "always" - set service "SMTPS" - set utm-status enable - set comments "Clone of qnap apps download" - next - edit 24 - set uuid 29f14b50-bd2c-51e5-d55d-25bb38896c90 - set srcintf "server-lan2" - set dstintf "wan1" - set srcaddr "knappe_10.0.0.15" - set dstaddr "all" - set schedule "always" - set service "bittorrent" - set logtraffic disable - set comments "silently drop bittorent" - next - edit 27 - set name "drop fb http scan" - set uuid edf5ef38-be1c-51e5-e704-8d8feddecfea - set srcintf "wan1" - set dstintf "server-lan2" - set srcaddr "fritzbox_inet_10.0.0.24" - set dstaddr "knappe_10.0.0.15" "drucker-10.0.0.38" - set schedule "always" - set service "HTTP" "tcp14013-fb" - set logtraffic disable - set comments "fritzbox http autodiscover" - next - edit 62 - set name "silent drop fb 2 wch60e" - set uuid ec4b0c5e-c104-51e6-7075-2f0318f1675d - set srcintf "wan1" - set dstintf "wlan0" - set srcaddr "fritzbox_inet_10.0.0.24" - set dstaddr "fwf60-wlan-client-net" - set schedule "always" - set service "HTTP" "tcp14013-fb" - set logtraffic disable - set comments "Clone of silent drop fb2wlan" - next - edit 82 - set name "drop fb probes to keller" - set uuid 9a17bfd2-fa74-51e6-bdc6-69e5d816dc51 - set srcintf "wan1" - set dstintf "internal5" - set srcaddr "fritzbox_inet_10.0.0.24" - set dstaddr "eltern-keller-10.0.0.66_24" - set schedule "always" - set service "HTTP" "tcp14013-fb" - set logtraffic disable - set comments "Clone of silent drop fb2internal" - next - edit 61 - set name "silent drop fb2internal" - set uuid a5683b72-c104-51e6-7dc7-b8b399b077a2 - set srcintf "wan1" - set dstintf "internal" - set srcaddr "fritzbox_inet_10.0.0.24" - set dstaddr "internal-10.0.0.35_24" - set schedule "always" - set service "HTTP" "tcp14013-fb" - set logtraffic disable - set comments "Clone of drop fritzbox http scan" - next - edit 74 - set name "ipsec-vpn-cactus" - set uuid 8aa3bfbe-f3a9-51e6-d7c1-130d2eaf52f8 - set srcintf "wan1" - set dstintf "wan1" - set srcaddr "vpn-gw-cactus-ffm" - set dstaddr "FG_10.0.0.1" - set action accept - set schedule "always" - set service "ALL" - set logtraffic all - set comments "allow ipsec vpn cactus" - next - edit 73 - set name "stealth-rule" - set uuid 1e8401d6-f3a9-51e6-b504-978dc345a496 - set srcintf "wan1" - set dstintf "wan1" - set srcaddr "all" - set dstaddr "FG_10.0.0.1" - set schedule "always" - set service "ALL" - set logtraffic all - set comments "Clone of silent drop fb2internal" - next - edit 28 - set name "drop fritzbox 2 nfm" - set uuid 55633b3e-be1e-51e5-83c5-f350309e6012 - set srcintf "wan1" - set dstintf "kids-wifi" - set srcaddr "fritzbox_inet_10.0.0.24" - set dstaddr "wlan-kids" - set schedule "always" - set service "HTTP" "tcp14013-fb" - set logtraffic disable - set comments "fritzbox autodiscover and parental filter stuff" - next - edit 50 - set name "vpn_Cactus-DA_local" - set uuid 8dcf255a-be27-51e6-2623-209817195490 - set srcintf "internal" - set dstintf "Cactus-DA" - set srcaddr "Cactus-DA_local" - set dstaddr "Cactus-DA_remote" - set action accept - set schedule "always" - set service "ALL" - set comments "VPN: Cactus-DA (Created by VPN wizard)" - next - edit 52 - set name "vpn_Cactus-DA_remote" - set uuid 8ded7e92-be27-51e6-6666-fda6a84b25c3 - set srcintf "Cactus-DA" - set dstintf "internal" - set srcaddr "Cactus-DA_remote" - set dstaddr "Cactus-DA_local" - set action accept - set schedule "always" - set service "PING" - set logtraffic all - set comments "VPN: Cactus-DA (Created by VPN wizard)" - next - edit 53 - set name "fwf-wlan-to-internet" - set uuid bef31b02-be57-51e6-fce6-4c8e659c802e - set srcintf "wlan0" - set dstintf "wan1" - set srcaddr "fwf60-wlan-client-net" - set dstaddr "all" - set action accept - set schedule "always" - set service "ALL" - set utm-status enable - set comments "test" - set av-profile "default" - set webfilter-profile "default" - set ips-sensor "default" - set application-list "default" - set profile-protocol-options "default" - set ssl-ssh-profile "certificate-inspection" - next - edit 72 - set name "guest2inet" - set uuid 8231abd6-e533-51e6-7d55-652097c7e4c8 - set srcintf "GWS" - set dstintf "wan1" - set srcaddr "all" - set dstaddr "all" - set action accept - set schedule "always" - set service "ALL" - set utm-status enable - set comments "guest2internet" - set av-profile "default" - set webfilter-profile "default" - set ips-sensor "default" - set application-list "default" - set profile-protocol-options "default" - set nat enable - next - edit 60 - set name "wlan-kids auth" - set uuid b5c55e30-bfa8-51e6-f6e8-f97ba63319ab - set srcintf "kids-wifi" - set dstintf "kids-wifi" - set srcaddr "all" - set dstaddr "wifi-kids-wlan-router-ip" - set action accept - set schedule "always" - set service "fortinet-captive-portal-auth" - set utm-status enable - set comments "auth kids" - set av-profile "default" - set webfilter-profile "default" - set ips-sensor "default" - set application-list "default" - set profile-protocol-options "default" - next - edit 56 - set name "kids2internet" - set uuid 71756a8a-bf0e-51e6-81ae-a93b64520de6 - set srcintf "kids-wifi" - set dstintf "wan1" - set srcaddr "all" - set dstaddr "all" - set action accept - set schedule "always" - set service "ALL" - set utm-status enable - set av-profile "default" - set webfilter-profile "default" - set ips-sensor "default" - set application-list "default" - set casi-profile "default" - set profile-protocol-options "default" - set ssl-ssh-profile "certificate-inspection" - next - edit 57 - set name "wifikids2knappe" - set uuid 1934cdba-bf0f-51e6-e0d3-e5656c281c1a - set srcintf "kids-wifi" - set dstintf "server-lan2" - set srcaddr "wlan-kids" - set dstaddr "knappe_10.0.0.15" - set action accept - set schedule "always" - set service "PING" "SMB" - set utm-status enable - set av-profile "default" - set ips-sensor "default" - set profile-protocol-options "default" - next - edit 58 - set name "wlankids2printer" - set uuid 349f6d44-bf0f-51e6-2de4-2b77a9a17a03 - set srcintf "kids-wifi" - set dstintf "server-lan2" - set srcaddr "wlan-kids" - set dstaddr "drucker-10.0.0.38" - set action accept - set schedule "always" - set service "ALL" - set utm-status enable - set comments "Clone of wifikids2serverlan" - set av-profile "default" - set ips-sensor "default" - set profile-protocol-options "default" - next - edit 59 - set name "wlan-kids 2 dns" - set uuid 90cb4230-bfa7-51e6-4d22-23886941b8d4 - set srcintf "kids-wifi" - set dstintf "wan1" - set srcaddr "all" - set dstaddr "fritzbox_inet_10.0.0.24" - set action accept - set schedule "always" - set service "DNS" - next -end -config firewall policy6 - edit 1 - set name "test ipv6 policy1" - set uuid ae80e358-1065-51e6-a820-06154a13edca - set srcintf "internal" - set dstintf "wan1" - set srcaddr "all" - set dstaddr "all" - set action accept - set schedule "always" - set service "HTTP" "HTTPS" "PING" "test_service_multi-port" - set utm-status enable - set logtraffic all - set comments "v6 comment" - set av-profile "default" - set webfilter-profile "default" - set ips-sensor "default" - set profile-protocol-options "default" - next - edit 2 - set name "test-v6-nw-obj:1" - set uuid 003ece9e-1066-51e6-0540-15d6d9e4a6a8 - set srcintf "server-lan2" - set dstintf "wan1" - set srcaddr "ipv6-testgroup" - set dstaddr "test-ipv6addr" - set action accept - set schedule "always" - set service "PING" - set comments "comment33" - next - edit 3 - set name "test virtual ipv6 ips" - set uuid 81a3a9d8-17ae-51e6-1f16-38db7b448fd5 - set srcintf "internal" - set dstintf "wan1" - set srcaddr "test-ipv6addr" - set dstaddr "test-ipv6addr" - set action accept - set status disable - set schedule "kids-all-day" - set service "ARK-7777-7778-udp" - set devices "macantha-wlan" - set nat enable - set ippool enable - set poolname "test-v6-pool" - next -end -config firewall DoS-policy - edit 1 - set interface "wan1" - set srcaddr "all" - set dstaddr "FG_10.0.0.1" - set service "ALL" - config anomaly - edit "tcp_syn_flood" - set status enable - set log enable - set threshold 2000 - next - edit "tcp_port_scan" - set status enable - set log enable - set threshold 1000 - next - edit "tcp_src_session" - set status enable - set log enable - set threshold 5000 - next - edit "tcp_dst_session" - set status enable - set log enable - set threshold 5000 - next - edit "udp_flood" - set status enable - set log enable - set threshold 2000 - next - edit "udp_scan" - set status enable - set log enable - set threshold 2000 - next - edit "udp_src_session" - set status enable - set log enable - set threshold 5000 - next - edit "udp_dst_session" - set status enable - set log enable - set threshold 5000 - next - edit "icmp_flood" - set status enable - set log enable - set threshold 250 - next - edit "icmp_sweep" - set status enable - set log enable - set threshold 100 - next - edit "icmp_src_session" - set status enable - set log enable - set threshold 300 - next - edit "icmp_dst_session" - set status enable - set log enable - set threshold 1000 - next - edit "ip_src_session" - set status enable - set log enable - set threshold 5000 - next - edit "ip_dst_session" - set status enable - set log enable - set threshold 5000 - next - edit "sctp_flood" - set status enable - set log enable - set threshold 2000 - next - edit "sctp_scan" - set status enable - set log enable - set threshold 1000 - next - edit "sctp_src_session" - set status enable - set log enable - set threshold 5000 - next - edit "sctp_dst_session" - set status enable - set log enable - set threshold 5000 - next - end - next - edit 2 - set interface "wan1" - set srcaddr "all" - set dstaddr "all" - set service "ALL" - config anomaly - edit "tcp_syn_flood" - set status enable - set log enable - set action block - set threshold 2000 - next - edit "tcp_port_scan" - set status enable - set log enable - set action block - set threshold 1000 - next - edit "tcp_src_session" - set status enable - set log enable - set action block - set threshold 5000 - next - edit "tcp_dst_session" - set status enable - set log enable - set action block - set threshold 5000 - next - edit "udp_flood" - set status enable - set log enable - set action block - set threshold 2000 - next - edit "udp_scan" - set status enable - set log enable - set action block - set threshold 2000 - next - edit "udp_src_session" - set status enable - set log enable - set action block - set threshold 5000 - next - edit "udp_dst_session" - set status enable - set log enable - set action block - set threshold 5000 - next - edit "icmp_flood" - set status enable - set log enable - set action block - set threshold 250 - next - edit "icmp_sweep" - set status enable - set log enable - set action block - set threshold 100 - next - edit "icmp_src_session" - set status enable - set log enable - set action block - set threshold 300 - next - edit "icmp_dst_session" - set status enable - set log enable - set action block - set threshold 1000 - next - edit "ip_src_session" - set status enable - set log enable - set action block - set threshold 5000 - next - edit "ip_dst_session" - set status enable - set log enable - set action block - set threshold 5000 - next - edit "sctp_flood" - set status enable - set log enable - set action block - set threshold 2000 - next - edit "sctp_scan" - set status enable - set log enable - set action block - set threshold 1000 - next - edit "sctp_src_session" - set status enable - set log enable - set action block - set threshold 5000 - next - edit "sctp_dst_session" - set status enable - set log enable - set action block - set threshold 5000 - next - end - next -end -config endpoint-control profile - edit "default" - config forticlient-winmac-settings - set forticlient-av enable - set av-realtime-protection enable - set forticlient-application-firewall enable - set forticlient-application-firewall-list "default" - set forticlient-log-upload disable - set forticlient-wf enable - set forticlient-wf-profile "default" - end - config forticlient-android-settings - end - config forticlient-ios-settings - end - next -end -config switch-controller switch-profile - edit "default" - next -end -config wireless-controller wids-profile - edit "default" - set comment "Default WIDS profile." - set ap-scan enable - set wireless-bridge enable - set deauth-broadcast enable - set null-ssid-probe-resp enable - set long-duration-attack enable - set invalid-mac-oui enable - set weak-wep-iv enable - set auth-frame-flood enable - set assoc-frame-flood enable - set spoofed-deauth enable - set asleap-attack enable - set eapol-start-flood enable - set eapol-logoff-flood enable - set eapol-succ-flood enable - set eapol-fail-flood enable - set eapol-pre-succ-flood enable - set eapol-pre-fail-flood enable - next - edit "default-wids-apscan-enabled" - set ap-scan enable - next -end -config wireless-controller wtp-profile - edit "FAP423E-default" - config platform - set type 423E - end - set ap-country US - config radio-1 - set band 802.11n - end - config radio-2 - set band 802.11ac - end - next - edit "FAP421E-default" - config platform - set type 421E - end - set ap-country US - config radio-1 - set band 802.11n - end - config radio-2 - set band 802.11ac - end - next - edit "FAPS423E-default" - config platform - set type S423E - end - set ap-country US - config radio-1 - set band 802.11n - end - config radio-2 - set band 802.11ac - end - next - edit "FAPS422E-default" - config platform - set type S422E - end - set ap-country US - config radio-1 - set band 802.11n - end - config radio-2 - set band 802.11ac - end - next - edit "FAPS421E-default" - config platform - set type S421E - end - set ap-country US - config radio-1 - set band 802.11n - end - config radio-2 - set band 802.11ac - end - next - edit "FAPS323CR-default" - config platform - set type S323CR - end - set ap-country US - config radio-1 - set band 802.11n - end - config radio-2 - set band 802.11ac - end - next - edit "FAPS322CR-default" - config platform - set type S322CR - end - set ap-country US - config radio-1 - set band 802.11n - end - config radio-2 - set band 802.11ac - end - next - edit "FAPS321CR-default" - config platform - set type S321CR - end - set ap-country US - config radio-1 - set band 802.11n - end - config radio-2 - set band 802.11ac - end - next - edit "FAPS313C-default" - config platform - set type S313C - end - set ap-country US - config radio-1 - set band 802.11ac - end - config radio-2 - set mode disabled - end - next - edit "FAPS311C-default" - config platform - set type S311C - end - set ap-country US - config radio-1 - set band 802.11ac - end - config radio-2 - set mode disabled - end - next - edit "FAPS323C-default" - config platform - set type S323C - end - set ap-country US - config radio-1 - set band 802.11n - end - config radio-2 - set band 802.11ac - end - next - edit "FAPS322C-default" - config platform - set type S322C - end - set ap-country US - config radio-1 - set band 802.11n - end - config radio-2 - set band 802.11ac - end - next - edit "FAPS321C-default" - config platform - set type S321C - end - set ap-country US - config radio-1 - set band 802.11n - end - config radio-2 - set band 802.11ac - end - next - edit "FAP321C-default" - config platform - set type 321C - end - set ap-country US - config radio-1 - set band 802.11n - set vap-all disable - end - config radio-2 - set band 802.11ac - set vap-all disable - end - next - edit "FAP223C-default" - config platform - set type 223C - end - set ap-country US - config radio-1 - set band 802.11n - set vap-all disable - end - config radio-2 - set band 802.11ac - set vap-all disable - end - next - edit "FAP112D-default" - config platform - set type 112D - end - set ap-country US - config radio-1 - set band 802.11n - set vap-all disable - end - config radio-2 - set mode disabled - end - next - edit "FAP24D-default" - config platform - set type 24D - end - set ap-country US - config radio-1 - set band 802.11n - set vap-all disable - end - config radio-2 - set mode disabled - end - next - edit "FAP21D-default" - config platform - set type 21D - end - set ap-country US - config radio-1 - set band 802.11n - set vap-all disable - end - config radio-2 - set mode disabled - end - next - edit "FK214B-default" - config platform - set type 214B - end - set ap-country US - config radio-1 - set band 802.11n - set vap-all disable - end - config radio-2 - set mode disabled - end - next - edit "FAP224D-default" - config platform - set type 224D - end - set ap-country US - config radio-1 - set band 802.11n-5G - set vap-all disable - end - config radio-2 - set band 802.11n - set vap-all disable - end - next - edit "FAP222C-default" - config platform - set type 222C - end - set ap-country US - config radio-1 - set band 802.11n - set vap-all disable - end - config radio-2 - set band 802.11ac - set vap-all disable - end - next - edit "FAP25D-default" - config platform - set type 25D - end - set ap-country US - config radio-1 - set band 802.11n - set vap-all disable - end - config radio-2 - set mode disabled - end - next - edit "FAP221C-default" - config platform - set type 221C - end - set ap-country US - config radio-1 - set band 802.11n - set vap-all disable - end - config radio-2 - set band 802.11ac - set vap-all disable - end - next - edit "FAP320C-default" - config platform - set type 320C - end - set ap-country US - config radio-1 - set band 802.11n - set vap-all disable - end - config radio-2 - set band 802.11ac - set vap-all disable - end - next - edit "FAP28C-default" - config platform - set type 28C - end - set ap-country US - config radio-1 - set band 802.11n - set vap-all disable - end - config radio-2 - set mode disabled - end - next - edit "FAP223B-default" - config platform - set type 223B - end - set ap-country US - config radio-1 - set band 802.11n-5G - set vap-all disable - end - config radio-2 - set band 802.11n - set vap-all disable - end - next - edit "FAP14C-default" - config platform - set type 14C - end - set ap-country US - config radio-1 - set band 802.11n - set vap-all disable - end - config radio-2 - set mode disabled - end - next - edit "FAP11C-default" - config platform - set type 11C - end - set ap-country US - config radio-1 - set band 802.11n - set vap-all disable - end - config radio-2 - set mode disabled - end - next - edit "FAP320B-default" - config platform - set type 320B - end - set ap-country US - config radio-1 - set band 802.11n-5G - set vap-all disable - end - config radio-2 - set band 802.11n - set vap-all disable - end - next - edit "FAP112B-default" - config platform - set type 112B - end - set ap-country US - config radio-1 - set band 802.11n - set vap-all disable - end - config radio-2 - set mode disabled - end - next - edit "FAP222B-default" - config platform - set type 222B - end - set ap-country US - config radio-1 - set band 802.11n - set vap-all disable - end - config radio-2 - set band 802.11n-5G - set vap-all disable - end - next - edit "FAP210B-default" - config platform - set type 210B - end - set ap-country US - config radio-1 - set band 802.11n - set vap-all disable - end - config radio-2 - set mode disabled - end - next - edit "FAP220B-default" - set ap-country US - config radio-1 - set band 802.11n-5G - set vap-all disable - end - config radio-2 - set band 802.11n - set vap-all disable - end - next - edit "AP-11N-default" - config platform - set type AP-11N - end - set ap-country US - config radio-1 - set band 802.11n - end - config radio-2 - set mode disabled - end - next - edit "11n-only" - config platform - set type FWF - end - set ap-country US - config radio-1 - set band 802.11ac - end - config radio-2 - set mode disabled - end - next - edit "all-wifi-5ghz" - config platform - set type FWF - end - set ap-country US - config radio-1 - set band 802.11ac - set channel "36" "44" "149" "157" "165" - end - config radio-2 - set mode disabled - end - next - edit "2.4GHz-all" - config platform - set type FWF - end - set ap-country US - config radio-1 - set band 802.11n - set channel "1" "2" "3" "4" "5" "6" "7" "8" "9" "10" "11" - end - config radio-2 - set mode disabled - end - next -end -config wireless-controller wtp - edit "FWF60E-WIFI0" - set wtp-profile "2.4GHz-all" - config radio-1 - set override-channel enable - set channel "1" "2" "6" "10" "11" - end - next -end -config log memory setting - set status enable -end -config log null-device setting - set status disable -end -config log setting - set fwpolicy-implicit-log enable - set local-in-allow enable - set local-in-deny-unicast enable - set local-in-deny-broadcast enable - set local-out enable -end -config log gui-display - set fortiview-unscanned-apps enable - set fortiview-local-traffic enable -end -config alertemail setting - set username "fg60d@ff.cactus.de" - set mailto1 "tmp@cactus.de" - set IPS-logs enable - set IPsec-errors-logs enable - set sslvpn-authentication-errors-logs enable - set webfilter-logs enable - set violation-traffic-logs enable - set admin-login-logs enable - set FDS-license-expiring-warning enable -end -config router rip - config redistribute "connected" - end - config redistribute "static" - end - config redistribute "ospf" - end - config redistribute "bgp" - end - config redistribute "isis" - end -end -config router ripng - config redistribute "connected" - end - config redistribute "static" - end - config redistribute "ospf" - end - config redistribute "bgp" - end - config redistribute "isis" - end -end -config router static - edit 1 - set gateway 10.0.0.24 - set device "wan1" - next - edit 2 - set dst 10.0.0.36 255.255.255.255 - set gateway 10.0.0.18 - set device "internal" - next - edit 3 - set dst 10.0.0.53 255.255.255.255 - set gateway 10.0.0.52 - set device "internal" - set comment "wlan pi" - next - edit 4 - set dst 10.0.0.60 255.255.255.255 - set device "Cactus-DA" - set comment "VPN: Cactus-DA (Created by VPN wizard)" - next -end -config router ospf - config redistribute "connected" - end - config redistribute "static" - end - config redistribute "rip" - end - config redistribute "bgp" - end - config redistribute "isis" - end -end -config router ospf6 - config redistribute "connected" - end - config redistribute "static" - end - config redistribute "rip" - end - config redistribute "bgp" - end - config redistribute "isis" - end -end -config router bgp - config redistribute "connected" - end - config redistribute "rip" - end - config redistribute "ospf" - end - config redistribute "static" - end - config redistribute "isis" - end - config redistribute6 "connected" - end - config redistribute6 "rip" - end - config redistribute6 "ospf" - end - config redistribute6 "static" - end - config redistribute6 "isis" - end -end -config router isis - config redistribute "connected" - end - config redistribute "rip" - end - config redistribute "ospf" - end - config redistribute "bgp" - end - config redistribute "static" - end -end -config router multicast -end diff --git a/roles/sample-data/files/sample-configs/screenos_demo/ns_sys_config b/roles/sample-data/files/sample-configs/screenos_demo/ns_sys_config deleted file mode 100644 index 0a4cb00872..0000000000 --- a/roles/sample-data/files/sample-configs/screenos_demo/ns_sys_config +++ /dev/null @@ -1,164 +0,0 @@ -set clock timezone 1 -set vrouter trust-vr sharable -unset vrouter "trust-vr" auto-route-export -set service "GRE" protocol 47 src-port 0-65535 dst-port 0-65535 -set service "PIM" protocol 103 src-port 0-65535 dst-port 0-65535 -set service "SQL*Net V1" timeout 480 -set service "SQL*Net V2" timeout 480 -set service "SSH" timeout 480 -set service "tcp" protocol tcp src-port 1-65535 dst-port 1-1023 timeout 480 -set service "TCP_10000" protocol tcp src-port 0-65535 dst-port 10000-10000 -set service "TELNET" timeout 480 -set service "UDP_520" protocol udp src-port 0-65535 dst-port 520-520 -set service "UDP_53" protocol udp src-port 0-65535 dst-port 53-53 -set service "UDP_ALL" protocol udp src-port 0-65535 dst-port 0-65535 -set service "group_of_svcs" protocol tcp src-port 0-65535 dst-port 12-12 -set service "group_of_svcs" + tcp src-port 0-65535 dst-port 15-15 -set auth-server "Local" id 0 -set auth-server "Local" server-name "Local" -set auth default auth server "Local" -set admin name "cactus" -set admin password "nJvMCvrRKkuJcGRFrsEPAQCttjDIMn" -set admin user "fwcp" password "nO9FCHr2ASPJcl+FgsJKTGDtyPFcPn" privilege "all" -set admin user "readonly" password "nO7dB9rQOh7JcRABQs0DBeFt3CCp2n" privilege "read-only" -set admin manager-ip 192.168.1.0 255.255.255.0 -set admin auth timeout 60 -set admin auth server "Local" -set admin format unix -set zone "Trust" vrouter "trust-vr" -set zone "Untrust" vrouter "untrust-vr" -set zone "DMZ" vrouter "trust-vr" -set zone "VLAN" vrouter "trust-vr" -set zone "Trust" tcp-rst -set zone "Untrust" block -unset zone "Untrust" tcp-rst -set zone "MGT" block -set zone "DMZ" tcp-rst -set zone "VLAN" block -set zone "VLAN" tcp-rst -set zone "Untrust" screen tear-drop -set zone "Untrust" screen syn-flood -set zone "Untrust" screen ping-death -set zone "Untrust" screen ip-filter-src -set zone "Untrust" screen land -set zone "V1-Untrust" screen tear-drop -set zone "V1-Untrust" screen syn-flood -set zone "V1-Untrust" screen ping-death -set zone "V1-Untrust" screen ip-filter-src -set zone "V1-Untrust" screen land -set interface ethernet1 phy half 100mb -set interface ethernet2 phy full 100mb -set interface ethernet3 phy full 100mb -set interface ethernet4 phy full 100mb -set interface "ethernet1" zone "Trust" -set interface "ethernet2" zone "DMZ" -set interface "ethernet3" zone "Untrust" -set interface "ethernet4" zone "Trust" -unset interface vlan1 ip -set interface ethernet1 ip 192.168.1.3/24 -set interface ethernet1 route -set interface ethernet1 mtu 1500 -set interface ethernet3 mtu 1500 -unset interface vlan1 bypass-others-ipsec -unset interface vlan1 bypass-non-ip -set interface ethernet1 manage-ip 192.168.1.6 -set interface ethernet1 ip manageable -set interface ethernet3 manage ping -unset flow tcp-syn-check -set console page 20 -set hostname screenos_demo -set address "Trust" "1.1.1.1/32" 1.1.1.1 255.255.255.255 -set address "Trust" "10.1.1.4/30" 10.1.1.4 255.255.255.252 -set address "Trust" "Trust_1.2.3.0-24" 1.2.3.0 255.255.255.0 -set address "Trust" "Trust_1.2.3.4_hugo" 1.2.3.4 255.255.255.255 -set address "Trust" "Trust_1.2.3.6" 1.2.3.6 255.255.255.255 -set address "Trust" "Trust_1.2.3.8" 1.2.3.8 255.255.255.255 -set address "Trust" "Trust_1.2.3.9" 1.2.3.9 255.255.255.255 -set address "Untrust" "212.1.1.0/24" 212.1.1.0 255.255.255.0 -set address "Untrust" "47.11.47.11/32" 47.11.47.11 255.255.255.255 -set address "Untrust" "27.11.47.11/32" 27.11.47.11 255.255.255.255 -set address "Untrust" "Untrust_9.8.8.0-24" 9.8.8.0 255.255.255.0 -set address "Global" "211.0.0.0/8" 211.0.0.0 255.0.0.0 -set address "DMZ" "222.4.4.4/32" 222.4.4.4 255.255.255.255 -set address "DMZ" "DMZ_222.1.0.0-16_Webserver_Farm" 222.1.0.0 255.255.0.0 -set user "tim" uid 1 -set user "tim" type auth -set user "tim" hash-password "02HD1uCmBKnju9gbb+LZQ5hrydbuBZdVaJv0k=" -set user "tim" "enable" -set user-group "testgroup1" id 1 -set user-group "testgroup1" user "tim" -set ike respond-bad-spi 1 -set pki authority default scep mode "auto" -set pki x509 default cert-path partial -set pki x509 dn state-name "Germany" -set pki x509 dn local-name "Hesse" -set pki x509 dn org-name "FischkoppAG" -set pki x509 dn org-unit-name "oe666" -set pki x509 dn name "firewall1" -set pki x509 dn phone "+494711-0" -set group address "Trust" "Trust_group_intern_all" -set group address "Trust" "Trust_group_intern_all" add "Trust_1.2.3.6" -set group address "Trust" "Trust_group_intern_all" add "Trust_1.2.3.8" -set group address "Trust" "Trust_group_intern_all" add "Trust_1.2.3.9" -set group service "new-group" -set group service "new-group" add "GRE" -set url protocol sc-cpa -exit -set policy id 2 name "Access to web server" from "Untrust" to "DMZ" "Any" "DMZ_222.1.0.0-16_Webserver_Farm" "HTTP" permit log -set policy id 2 -set service "HTTPS" -exit -set policy id 1 name "von innen nach aussen" from "Trust" to "Untrust" "Trust_group_intern_all" "Any" "DNS" permit log -set policy id 1 -set service "FTP" -set service "H.323" -set service "HTTP" -set service "HTTPS" -set service "ICMP-ANY" -exit -set policy id 3 name "intern zu den webservern" from "Trust" to "DMZ" "Trust_group_intern_all" "DMZ_222.1.0.0-16_Webserver_Farm" "FTP" permit log -set policy id 3 -set service "HTTP" -set service "HTTPS" -set service "ICMP-ANY" -exit -set policy id 4 name "Access to mail server" from "Untrust" to "DMZ" "27.11.47.11/32" "222.4.4.4/32" "SMTP" permit log -set policy id 5 name "sending mail from internal net" from "Trust" to "DMZ" "Trust_group_intern_all" "222.4.4.4/32" "SMTP" permit -set policy id 6 name "getting time" from "DMZ" to "Untrust" "Any" "Any" "NTP" permit -set policy id 7 from "Trust" to "Global" "Trust_group_intern_all" "Any" "GRE" permit log -set policy id 8 from "DMZ" to "Trust" "DMZ_222.1.0.0-16_Webserver_Farm" "10.1.1.4/30" "SQL*Net V2" permit log -set policy id 9 name "news feed" from "Trust" to "Untrust" "Trust_group_intern_all" "212.1.1.0/24" "NNTP" permit log -set policy id 10 name "cheffe" from "Trust" to "Untrust" "1.1.1.1/32" "47.11.47.11/32" "GNUTELLA" permit -set policy id 11 name "stealth" from "Untrust" to "Global" "Any" "211.0.0.0/8" "ANY" deny log -set nsmgmt report alarm traffic enable -set nsmgmt report alarm attack enable -set nsmgmt report alarm other enable -set nsmgmt report alarm di enable -set nsmgmt report log config enable -set nsmgmt report log info enable -set nsmgmt report log self enable -set nsmgmt report log traffic enable -set nsmgmt init id D617233021D082F8C9D3AE9CE43E29EAF684283A00 -set nsmgmt server primary 192.168.1.1 port 7800 -set nsmgmt bulkcli reboot-timeout 60 -set nsmgmt hb-interval 20 -set nsmgmt hb-threshold 5 -set nsmgmt enable -set ssh version v2 -set ssh enable -set ssh pka-dsa user-name fwcp pka-key-id F817A719179A3CCB0C68 -set scp enable -set config lock timeout 5 -set dl-buf size 4718592 -set snmp port listen 161 -set snmp port trap 162 -set vrouter "untrust-vr" -exit -set vrouter "trust-vr" -unset add-default-route -exit -set vrouter "untrust-vr" -exit -set vrouter "trust-vr" -exit - diff --git a/roles/sample-data/files/ssh-keyscan.sh b/roles/sample-data/files/ssh-keyscan.sh deleted file mode 100644 index 8e90c01b7d..0000000000 --- a/roles/sample-data/files/ssh-keyscan.sh +++ /dev/null @@ -1,11 +0,0 @@ -#!/bin/sh -# run as fworch -SERVER_LIST="127.0.0.1" -#SERVER_LIST="admsrv websrvffm chatsrv test3 opnsense11 dnssrvffm alpsrvtest daba nagios sting-gw isodev isoback2 spiegel admsrvda iso-test-importer klaut gware wasp howto itchy mailin proxy proxylan spike vpn-gateway wwwprivat" -for h in $SERVER_LIST; do - ip=$(dig +search +short $h) - #ssh-keygen -R $h - #ssh-keygen -R "$ip" - ssh-keyscan -H "$ip" >> ~/.ssh/known_hosts - ssh-keyscan -H $h >> ~/.ssh/known_hosts -done diff --git a/roles/sample-data/tasks/add_second_ldap_db.yml b/roles/sample-data/tasks/add_second_ldap_db.yml index 2d2aaab850..e35c949477 100644 --- a/roles/sample-data/tasks/add_second_ldap_db.yml +++ b/roles/sample-data/tasks/add_second_ldap_db.yml @@ -22,15 +22,28 @@ with_fileglob: - ../templates/*.j2 + - name: build ldap tls options + set_fact: + ldap_tls_opts: >- + {% if openldap_server_enable_ssl | default(false) -%} + -o TLS_REQCERT=never{% if openldap_server_cert is defined %} -o TLS_CACERT={{ openldap_server_cert }}{% endif %} + {%- endif %} + ldap_cmd_url: >- + {% if openldap_server_enable_ssl | default(false) -%} + ldaps://{{ openldap_server }}:{{ openldap_port | default(636) }} + {%- else -%} + ldap://{{ openldap_server }}:{{ (openldap_port | default(389) | int == 636) | ternary(389, openldap_port | default(389)) }} + {%- endif %} + - name: add new sample database to ldap - command: "ldapmodify -H {{ openldap_url }} -D cn=config -w {{ ldap_manager_pwd }} -x -f {{ middleware_ldif_dir }}/second_db.ldif" + command: "ldapmodify {{ ldap_tls_opts }} -H {{ ldap_cmd_url }} -D cn=config -w {{ ldap_manager_pwd }} -x -f {{ middleware_ldif_dir }}/second_db.ldif" - name: enhance sample ldap with test users and groups - command: "ldapmodify -H {{ openldap_url }} -D {{ openldap_superuser_dn }} -w {{ ldap_manager_pwd }} -x -f {{ middleware_ldif_dir }}/{{ item }}.ldif" + command: "ldapmodify {{ ldap_tls_opts }} -H {{ ldap_cmd_url }} -D {{ openldap_superuser_dn }} -w {{ ldap_manager_pwd }} -x -f {{ middleware_ldif_dir }}/{{ item }}.ldif" loop: - ext_role - ext_user - ext_roles - ext_add_user - become: true \ No newline at end of file + become: true diff --git a/roles/sample-data/tasks/create-demo-credentials.yml b/roles/sample-data/tasks/create-demo-credentials.yml new file mode 100644 index 0000000000..11fb34f50e --- /dev/null +++ b/roles/sample-data/tasks/create-demo-credentials.yml @@ -0,0 +1,13 @@ +- name: insert demo import credentials + postgresql_query: + db: "{{ fworch_db_name }}" + query: > + DO $do$ BEGIN + IF NOT EXISTS (SELECT * FROM import_credential WHERE credential_name='credential01_demo') THEN + insert into import_credential + (id,credential_name,username,secret,is_key_pair) + VALUES (0,'credential01_demo','{{ sample_config_user }}','dummy secret',false); + END IF; END $do$ + become: true + become_user: postgres + \ No newline at end of file diff --git a/roles/sample-data/tasks/create-devices.yml b/roles/sample-data/tasks/create-devices.yml index 82289fb075..4f1ab6b188 100644 --- a/roles/sample-data/tasks/create-devices.yml +++ b/roles/sample-data/tasks/create-devices.yml @@ -1,109 +1,120 @@ # this playbook sets up some sample devices with configs to play around with -- name: read ssh_priv_key into var - slurp: - src: "{{ sample_config_user_home }}/.ssh/id_rsa.{{ sample_config_user }}" - register: sample_ssh_priv_key_dict - become: true - -- name: decode key - set_fact: - sample_ssh_priv_key: "{{ sample_ssh_priv_key_dict['content'] | b64decode }}" - - name: change importer hostname when it is localhost set_fact: importer_hostname: "{{ hostvars[inventory_hostname].ansible_hostname }}" when: importer_hostname == 'localhost' -- block: +- name: default credential id = -1 (test) + set_fact: + credential_id: -1 + +- name: set do_not_import + set_fact: + do_not_import: false + +- name: set do_not_import to false for all tests to prevent lock due to simultaneous import attempts + set_fact: + do_not_import: true + when: sample_role_purpose is match('test') + +- name: pick the correct credential id + set_fact: + credential_id: 0 + when: sample_role_purpose is not match('test') - - name: insert demo import credentials +- block: # demo & test + - name: insert sample fortiOS management postgresql_query: db: "{{ fworch_db_name }}" query: > - DO $do$ BEGIN - IF NOT EXISTS (SELECT * FROM import_credential WHERE credential_name='credential01_demo') THEN - insert into import_credential - (id,credential_name,username,secret,is_key_pair) - VALUES (0,'credential01_demo','{{ sample_config_user }}','{{ sample_ssh_priv_key }}',true); - END IF; END $do$ - - - name: insert test fortinet management + DO $do$ BEGIN + IF NOT EXISTS (SELECT * FROM management WHERE mgm_name='{{ sample_fortigate_name }}') THEN + insert into management (dev_typ_id,mgm_name,import_credential_id,ssh_hostname,do_not_import,importer_hostname) + VALUES (24,'{{ sample_fortigate_name }}',{{ credential_id }},'{{ demo_fos_uri }}',{{ do_not_import }},'{{ importer_hostname }}'); + END IF; END $do$ + + - name: insert sample fortiOS gateway postgresql_query: db: "{{ fworch_db_name }}" query: > - DO $do$ BEGIN - IF NOT EXISTS (SELECT * FROM management WHERE mgm_name='{{ sample_fortigate_name }}') THEN - insert into management - (dev_typ_id,mgm_name,import_credential_id,ssh_hostname,do_not_import,config_path,importer_hostname) - VALUES (4,'{{ sample_fortigate_name }}',0,'{{ importer_hostname }}',false,'sample-configs/fortinet_demo/','{{ importer_hostname }}'); - END IF; END $do$ + DO $do$ BEGIN + IF NOT EXISTS (SELECT * FROM device WHERE dev_name='{{ sample_fortigate_name }}') THEN + insert into device (mgm_id,dev_name,dev_typ_id,dev_uid) + VALUES ((select mgm_id from management where mgm_name='{{ sample_fortigate_name }}'),'{{ sample_fortigate_name }}',25,'{{ sample_fortigate_dev_uid }}'); + END IF; END $do$ - - name: insert test fortinet gateway + become: true + become_user: postgres + +- block: # demo only + - name: insert demo check point R8x management {{ sample_checkpoint_name }} postgresql_query: db: "{{ fworch_db_name }}" query: > DO $do$ BEGIN - IF NOT EXISTS (SELECT * FROM device WHERE dev_name='{{ sample_fortigate_name }}') THEN - insert into device (mgm_id,dev_name,local_rulebase_name,dev_typ_id) - VALUES ((select mgm_id from management where mgm_name='{{ sample_fortigate_name }}'),'{{ sample_fortigate_name }}','{{ sample_fortigate_name }}',10); - END IF; END $do$ + IF NOT EXISTS (SELECT * FROM management WHERE mgm_name='{{ sample_checkpoint_name }}') THEN + insert into management + (dev_typ_id,mgm_name,import_credential_id,ssh_hostname,do_not_import,importer_hostname, mgm_uid) + VALUES (9,'{{ sample_checkpoint_name }}',{{ credential_id }},'{{ demo_cpr8x_uri }}',{{ do_not_import }},'{{ importer_hostname }}','{{ demo_cpr8x_mgm_uid }}'); + END IF; + END $do$ - - name: insert test check point R7x management + - name: insert demo check point R8x gateway1 {{ sample_checkpoint_name }} postgresql_query: db: "{{ fworch_db_name }}" query: > DO $do$ BEGIN - IF NOT EXISTS (SELECT * FROM management WHERE mgm_name='checkpoint_demo') THEN - insert into management (dev_typ_id,mgm_name,import_credential_id,ssh_hostname,do_not_import,config_path,importer_hostname) - VALUES (7,'checkpoint_demo',0,'{{ importer_hostname }}',false, 'sample-configs/checkpoint_demo/','{{ importer_hostname }}'); - END IF; END $do$ - when: sample_role_purpose is not match('test') + IF NOT EXISTS (SELECT * FROM device WHERE dev_name='{{ demo_cpr8x_name }}1') THEN + insert into device (mgm_id,dev_name,dev_uid,dev_typ_id) + VALUES ((select mgm_id from management where mgm_name='{{ sample_checkpoint_name }}'),'{{ demo_cpr8x_name }}1','{{ demo_cpr8x_dev1_uid }}',9); + END IF; END $do$ - - name: insert test CPR7x gateway + - name: insert demo check point R8x gateway2 {{ sample_checkpoint_name }} postgresql_query: db: "{{ fworch_db_name }}" query: > DO $do$ BEGIN - IF NOT EXISTS (SELECT * FROM device WHERE dev_name='checkpoint_demo') THEN - insert into device (mgm_id,dev_name,local_rulebase_name,dev_typ_id) - VALUES ((select mgm_id from management where mgm_name='checkpoint_demo'),'checkpoint_demo','IsoAAAA',7); - END IF; END $do$ - when: sample_role_purpose is not match('test') + IF NOT EXISTS (SELECT * FROM device WHERE dev_name='{{ demo_cpr8x_name }}2') THEN + insert into device (mgm_id,dev_name,dev_uid,dev_typ_id) + VALUES ((select mgm_id from management where mgm_name='{{ sample_checkpoint_name }}'),'{{ demo_cpr8x_name }}2','{{ demo_cpr8x_dev2_uid }}',9); + END IF; END $do$ + + become: true + become_user: postgres + when: sample_role_purpose is not match('test') - - name: insert dummy test import credentials +- block: # testing only + - name: insert test check point R8x management {{ sample_checkpoint_name }} postgresql_query: db: "{{ fworch_db_name }}" query: > - DO $do$ BEGIN - IF NOT EXISTS (SELECT * FROM import_credential WHERE credential_name='{{ test_credential_name }}') THEN - insert into import_credential - (id,credential_name,username,secret,is_key_pair) - VALUES (-1,'{{ test_credential_name }}','{{ sample_config_user }}','{{ sample_ssh_priv_key }}',true); - END IF; END $do$ - when: sample_role_purpose is match('test') - - - name: insert test check point R8x management + DO $do$ BEGIN + IF NOT EXISTS (SELECT * FROM management WHERE mgm_name='{{ sample_checkpoint_name }}') THEN + insert into management (dev_typ_id,mgm_name,import_credential_id,ssh_hostname,do_not_import,importer_hostname,mgm_uid) + VALUES (9,'{{ sample_checkpoint_name }}',{{ credential_id }},'{{ sample_checkpoint_uri }}',{{ do_not_import }},'dummy importer hostname','{{ demo_cpr8x_mgm_uid }}'); + END IF; END $do$ + + - name: insert test check point R8x gateway1 {{ sample_checkpoint_name }} postgresql_query: db: "{{ fworch_db_name }}" query: > DO $do$ BEGIN - IF NOT EXISTS (SELECT * FROM management WHERE mgm_name='{{ sample_checkpoint_name }}') THEN - insert into management (dev_typ_id,mgm_name,import_credential_id,ssh_hostname,do_not_import,importer_hostname) - VALUES (9,'{{ sample_checkpoint_name }}',-1,'{{ importer_hostname }}',false,'{{ importer_hostname }}'); - END IF; END $do$ - when: sample_role_purpose is match('test') + IF NOT EXISTS (SELECT * FROM device WHERE dev_name='{{ sample_checkpoint_name }}1') THEN + insert into device (mgm_id,dev_name,dev_uid,dev_typ_id) + VALUES ((select mgm_id from management where mgm_name='{{ sample_checkpoint_name }}'),'{{ sample_checkpoint_name }}1','{{ demo_cpr8x_dev1_uid }}',9); + END IF; END $do$ - - name: insert test check point R8x gateway + - name: insert test check point R8x gateway2 {{ sample_checkpoint_name }} postgresql_query: db: "{{ fworch_db_name }}" query: > DO $do$ BEGIN - IF NOT EXISTS (SELECT * FROM device WHERE dev_name='{{ sample_checkpoint_name }}') THEN - insert into device (mgm_id,dev_name,local_rulebase_name,dev_typ_id,package_name) - VALUES ((select mgm_id from management where mgm_name='{{ sample_checkpoint_name }}'),'{{ sample_checkpoint_name }}','FirstLayer shared with inline layer',9,'TestPolicyWithLayers'); - END IF; END $do$ - when: sample_role_purpose is match('test') + IF NOT EXISTS (SELECT * FROM device WHERE dev_name='{{ sample_checkpoint_name }}2') THEN + insert into device (mgm_id,dev_name,dev_uid,dev_typ_id) + VALUES ((select mgm_id from management where mgm_name='{{ sample_checkpoint_name }}'),'{{ sample_checkpoint_name }}2','{{ demo_cpr8x_dev2_uid }}',9); + END IF; END $do$ become: true become_user: postgres + when: sample_role_purpose is match('test') diff --git a/roles/sample-data/tasks/create-test-credentials.yml b/roles/sample-data/tasks/create-test-credentials.yml new file mode 100644 index 0000000000..f07fa59f77 --- /dev/null +++ b/roles/sample-data/tasks/create-test-credentials.yml @@ -0,0 +1,13 @@ +- name: insert dummy test import credentials + postgresql_query: + db: "{{ fworch_db_name }}" + query: > + DO $do$ BEGIN + IF NOT EXISTS (SELECT * FROM import_credential WHERE credential_name='{{ test_credential_name }}') THEN + insert into import_credential + (id,credential_name,username,secret,is_key_pair) + VALUES (-1,'{{ test_credential_name }}','{{ sample_config_user }}','dummy secret',true); + END IF; END $do$ + become: true + become_user: postgres + \ No newline at end of file diff --git a/roles/sample-data/tasks/main.yml b/roles/sample-data/tasks/main.yml index b438c6306c..baafdce9dc 100644 --- a/roles/sample-data/tasks/main.yml +++ b/roles/sample-data/tasks/main.yml @@ -1,45 +1,17 @@ # this playbook sets up some sample devices with configs to play around with -- name: create import sample user and copy configs - include_tasks: setup-sample-import.yml - when: "installation_mode=='new' or sample_role_purpose is match('test')" +- name: create demo credentials + include_tasks: create-demo-credentials.yml + when: add_demo_data|bool and (installation_mode=='new' or sample_role_purpose is match('test')) -- name: install package postgresql-client for adding sample devices to db - package: - name: "{{ item }}" - state: present - loop: - - postgresql-client - - cron - become: true - -- name: add localhost hostkey to known_hosts - known_hosts: - name: localhost - key: "{{ lookup('pipe', 'ssh-keyscan localhost') }}" - become: true - become_user: "{{ fworch_user }}" +- name: create test credentials + include_tasks: create-test-credentials.yml + when: installation_mode=='new' or sample_role_purpose is match('test') - name: create sample devices in database include_tasks: create-devices.yml when: installation_mode=='new' or sample_role_purpose is match('test') -- name: scan and add ssh keys to known_hosts automatically to avoid ssh connections issues for sample imports - known_hosts: - name: "{{ item }}" - key: "{{ lookup('pipe', 'ssh-keyscan -H ' + item) }}" - become: true - become_user: "{{ fworch_user }}" - loop: - - "127.0.0.1" - - "localhost" - - "{{ sample_hostname }}" - - "{{ importer_hostname }}" - -- name: establish cron job to simulate changes to configs (only demo and new installation) - include_tasks: setup-config-changes.yml - when: installation_mode=='new' and sample_role_purpose is not match('test') - - name: add second ldap database include_tasks: add_second_ldap_db.yml when: (second_ldap_db | bool) and (sample_role_purpose is not match('test')) diff --git a/roles/sample-data/tasks/setup-config-changes.yml b/roles/sample-data/tasks/unused_setup-config-changes.yml similarity index 100% rename from roles/sample-data/tasks/setup-config-changes.yml rename to roles/sample-data/tasks/unused_setup-config-changes.yml diff --git a/roles/test/files/FWO.Test/ApiConfigTest.cs b/roles/test/files/FWO.Test/ApiConfigTest.cs deleted file mode 100644 index 2e95237e1d..0000000000 --- a/roles/test/files/FWO.Test/ApiConfigTest.cs +++ /dev/null @@ -1,54 +0,0 @@ -using FWO.Api.Client; -using FWO.Config.Api; -using NUnit.Framework; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace FWO.Test -{ - [TestFixture] - internal class ApiConfigTest - { - public ApiConfigTest() - { - - } - - /// - /// Run before EACH test. - /// - [SetUp] - public void Setup() - { - - } - - [Test] - public async Task ReadGlobalConfig() - { - //ApiConnection apiConnection = new GraphQlApiConnection(""); - //GlobalConfig globalConfig = await GlobalConfig.ConstructAsync(); - } - - [Test] - public void ReadUserConfig() - { - //UserConfig userConfig = new UserConfig() - } - - [Test] - public void WriteGlobalConfig() - { - - } - - [Test] - public void WriteUserConfig() - { - - } - } -} diff --git a/roles/test/files/FWO.Test/ApiTest.cs b/roles/test/files/FWO.Test/ApiTest.cs deleted file mode 100644 index 00d21b5add..0000000000 --- a/roles/test/files/FWO.Test/ApiTest.cs +++ /dev/null @@ -1,69 +0,0 @@ -using System; -using System.Threading.Tasks; -using FWO.Api.Client; -using NUnit.Framework; -using FWO.Api.Data; -using FWO.Config.File; -using FWO.Middleware.Client; -using Microsoft.IdentityModel.Tokens; -using FWO.Middleware.RequestParameters; -using FWO.Logging; - -namespace FWO.Test -{ - [TestFixture] - [Parallelizable] - public class ApiTest - { - ApiConnection apiConnection; - - public ApiTest() - { - // ConfigFile configConnection = new ConfigFile(); - // Dictionary apiTestUserCredentials = configConnection.ReadAdditionalConfigFile("secrets/TestUserCreds.json", new List { "user", "password" }); - // string ApiUri = configConnection.ApiServerUri; - // string MiddlewareUri = configConnection.MiddlewareServerUri; - // string ProductVersion = configConnection.ProductVersion; - // RsaSecurityKey jwtPublicKey = configConnection.JwtPublicKey; - // string middlewareServerUri = configConnection.MiddlewareServerUri; - // string apiServerUri = configConnection.ApiServerUri; - // MiddlewareClient middlewareClient = new MiddlewareClient(MiddlewareUri); - // AuthenticationTokenGetParameters authenticationParameters = new AuthenticationTokenGetParameters - // { - // Password = apiTestUserCredentials["password"], - // Username = apiTestUserCredentials["user"] - // }; - // string jwt = middlewareClient.AuthenticateUser(authenticationParameters).Result.Data; - // apiConnection = new APIConnection(apiServerUri); - // apiConnection.SetAuthHeader(jwt); - return; - } - - /// - /// Run before EACH test. - /// - [SetUp] - public void Setup() - { - - } - - [Test] - public async Task QueryTestIpProto() - { - // string query = @" - // query ipProtoTest - // { - // stm_ip_proto (where: {ip_proto_id: {_eq: 6 } }) - // { - // id: ip_proto_id - // name: ip_proto_name - // } - // }"; - - // NetworkProtocol networkProtocol = new NetworkProtocol(); - // networkProtocol = (await apiConnection.SendQueryAsync(query, new { }))[0]; - // Assert.AreEqual(networkProtocol.Name, "TCP", "wrong result of protocol API query"); - } - } -} diff --git a/roles/test/files/FWO.Test/ExportTest.cs b/roles/test/files/FWO.Test/ExportTest.cs deleted file mode 100644 index 34b5916ba0..0000000000 --- a/roles/test/files/FWO.Test/ExportTest.cs +++ /dev/null @@ -1,1180 +0,0 @@ -using NUnit.Framework; -using FWO.Logging; -using FWO.Report; -using FWO.Report.Filter; -using FWO.Api.Data; - - -namespace FWO.Test -{ - [TestFixture] - [Parallelizable] - internal class ExportTest - { - static NetworkObject TestIp1 = new NetworkObject(){ Id = 1, Name = "TestIp1", IP = "1.2.3.4/32", IpEnd = "", Type = new NetworkObjectType(){ Name = "network" }}; - static NetworkObject TestIp2 = new NetworkObject(){ Id = 2, Name = "TestIp2", IP = "127.0.0.1/32", IpEnd = "", Type = new NetworkObjectType(){ Name = "network" }}; - static NetworkObject TestIpRange = new NetworkObject(){ Id = 3, Name = "TestIpRange", IP = "1.2.3.4/32", IpEnd = "1.2.3.5/32", Type = new NetworkObjectType(){ Name = "ip_range" }}; - static NetworkObject TestIpNew = new NetworkObject(){ Id = 4, Name = "TestIpNew", IP = "10.0.6.1/32", Type = new NetworkObjectType(){ Name = "network" }}; - static NetworkObject TestIp1Changed = new NetworkObject(){ Id = 5, Name = "TestIp1Changed", IP = "2.3.4.5/32", IpEnd = "", Type = new NetworkObjectType(){ Name = "network" }}; - - static NetworkService TestService1 = new NetworkService(){ Id = 1, DestinationPort = 443, DestinationPortEnd = 443, Name = "TestService1", Protocol = new NetworkProtocol { Name = "TCP" }}; - static NetworkService TestService2 = new NetworkService(){ Id = 2, DestinationPort = 6666, DestinationPortEnd = 7777, Name = "TestService2", Protocol = new NetworkProtocol { Name = "UDP" }}; - - static NetworkUser TestUser1 = new NetworkUser(){ Id = 1, Name = "TestUser1" }; - static NetworkUser TestUser2 = new NetworkUser(){ Id = 2, Name = "TestUser2", Type = new NetworkUserType() { Name = "group"} }; - - static Rule Rule1 = new Rule(); - static Rule Rule1Changed = new Rule(); - static Rule Rule2 = new Rule(); - static Rule Rule2Changed = new Rule(); - static Rule NatRule = new Rule(); - static Rule RecertRule1 = new Rule(); - static Rule RecertRule2 = new Rule(); - - SimulatedUserConfig userConfig = new SimulatedUserConfig(); - DynGraphqlQuery query = new DynGraphqlQuery("TestFilter"){ ReportTimeString = "2023-04-20T17:50:04" }; - - [SetUp] - public void Initialize() - { - } - - - [Test] - public void RulesGenerateHtml() - { - Log.WriteInfo("Test Log", "starting rules report html generation"); - ReportRules reportRules = new ReportRules(query, userConfig, ReportType.Rules); - reportRules.Managements = ConstructRuleReport(false); - - string expectedHtmlResult = "Rules Report" + - "" + - "" + - "

                      Rules Report

                      " + - "

                      Filter: TestFilter

                      " + - "

                      Time of configuration: 2023-04-20T15:50:04Z (UTC)

                      " + - "

                      Generated on: Z (UTC)

                      " + - "

                      Devices: TestMgt [TestDev]


                      " + - "

                      TestMgt


                      " + - "

                      TestDev


                      " + - "" + - "" + - "" + - "" + - "" + - "" + - "" + - "" + - "" + - "" + - "" + - "" + - "
                      No.NameSource ZoneSourceDestination ZoneDestinationServicesActionTrackEnabledUidComment
                      1TestRule1srczn TestIp1 (1.2.3.4/32)
                       TestIp2 (127.0.0.1/32)
                      dstzn TestIpRange (1.2.3.4/32-1.2.3.5/32) TestService1 (443/TCP)acceptnoneYuid1comment1
                      2TestRule2not
                       TestUser1@ TestIp1 (1.2.3.4/32)
                       TestUser1@ TestIp2 (127.0.0.1/32)
                      not
                       TestUser2@ TestIpRange (1.2.3.4/32-1.2.3.5/32)
                      not
                       TestService2 (6666-7777/UDP)
                      denynoneYuid2:123comment2
                      " + - "

                      Network Objects


                      " + - "" + - "" + - "" + - "" + - "
                      No.NameTypeIP AddressMembersUidComment
                      1TestIp1network1.2.3.4/32
                      2TestIp2network127.0.0.1/32
                      3TestIpRangeip_range1.2.3.4/32-1.2.3.5/32
                      " + - "

                      Network Services


                      " + - "" + - "" + - "" + - "
                      No.NameTypeProtocolPortMembersUidComment
                      1TestService1TestService1TCP443
                      2TestService2TestService2UDP6666-7777
                      " + - "

                      Users


                      " + - "" + - "" + - "" + - "
                      No.NameTypeMembersUidComment
                      1TestUser1TestUser1
                      2TestUser2TestUser2
                      "; - Assert.AreEqual(expectedHtmlResult, removeLinebreaks((removeGenDate(reportRules.ExportToHtml(), true)))); - } - - [Test] - public void ResolvedRulesGenerateHtml() - { - Log.WriteInfo("Test Log", "starting rules report resolved html generation"); - ReportRules reportRules = new ReportRules(query, userConfig, ReportType.ResolvedRules); - reportRules.Managements = ConstructRuleReport(true); - - string expectedHtmlResult = "Rules Report (resolved)" + - "" + - "" + - "

                      Rules Report (resolved)

                      " + - "

                      Filter: TestFilter

                      " + - "

                      Time of configuration: 2023-04-20T15:50:04Z (UTC)

                      " + - "

                      Generated on: Z (UTC)

                      " + - "

                      Devices: TestMgt [TestDev]


                      " + - "

                      TestMgt


                      " + - "

                      TestDev


                      " + - "" + - "" + - "" + - "" + - "" + - "" + - "" + - "" + - "" + - "" + - "" + - "" + - "
                      No.NameSource ZoneSourceDestination ZoneDestinationServicesActionTrackEnabledUidComment
                      1TestRule1srcznTestIp1 (1.2.3.4/32)
                      TestIp2 (127.0.0.1/32)
                      dstznTestIpRange (1.2.3.4/32-1.2.3.5/32)TestService1 (443/TCP)acceptnoneYuid1comment1
                      2TestRule2not
                      TestUser1@TestIp1 (1.2.3.4/32)
                      TestUser1@TestIp2 (127.0.0.1/32)
                      not
                      TestUser2@TestIpRange (1.2.3.4/32-1.2.3.5/32)
                      not
                      TestService2 (6666-7777/UDP)
                      denynoneYuid2:123comment2
                      " + - ""; - Assert.AreEqual(expectedHtmlResult, removeLinebreaks((removeGenDate(reportRules.ExportToHtml(), true)))); - } - - [Test] - public void ResolvedRulesTechGenerateHtml() - { - Log.WriteInfo("Test Log", "starting rules report resolved html generation"); - ReportRules reportRules = new ReportRules(query, userConfig, ReportType.ResolvedRulesTech); - reportRules.Managements = ConstructRuleReport(true); - - string expectedHtmlResult = "Rules Report (technical)" + - "" + - "" + - "

                      Rules Report (technical)

                      " + - "

                      Filter: TestFilter

                      " + - "

                      Time of configuration: 2023-04-20T15:50:04Z (UTC)

                      " + - "

                      Generated on: Z (UTC)

                      " + - "

                      Devices: TestMgt [TestDev]


                      " + - "

                      TestMgt


                      " + - "

                      TestDev


                      " + - "" + - "" + - "" + - "" + - "" + - "" + - "" + - "" + - "" + - "" + - "" + - "" + - "
                      No.NameSource ZoneSourceDestination ZoneDestinationServicesActionTrackEnabledUidComment
                      1TestRule1srczn1.2.3.4/32
                      127.0.0.1/32
                      dstzn1.2.3.4/32-1.2.3.5/32443/TCPacceptnoneYuid1comment1
                      2TestRule2not
                      TestUser1@1.2.3.4/32
                      TestUser1@127.0.0.1/32
                      not
                      TestUser2@1.2.3.4/32-1.2.3.5/32
                      not
                      6666-7777/UDP
                      denynoneYuid2:123comment2
                      " + - ""; - Assert.AreEqual(expectedHtmlResult, removeLinebreaks((removeGenDate(reportRules.ExportToHtml(), true)))); - } - - [Test] - public void UnusedRulesGenerateHtml() - { - Log.WriteInfo("Test Log", "starting unused rules report html generation"); - ReportRules reportRules = new ReportRules(query, userConfig, ReportType.UnusedRules); - reportRules.Managements = ConstructRuleReport(false); - - string expectedHtmlResult = "Unused Rules Report" + - "" + - "" + - "

                      Unused Rules Report

                      " + - "

                      Filter: TestFilter

                      " + - "

                      Time of configuration: 2023-04-20T15:50:04Z (UTC)

                      " + - "

                      Generated on: Z (UTC)

                      " + - "

                      Devices: TestMgt [TestDev]


                      " + - "

                      TestMgt


                      " + - "

                      TestDev


                      " + - "" + - "" + - "" + - "" + - "" + - "" + - "" + - "" + - "" + - "" + - "" + - "" + - "
                      No.Last HitNameSource ZoneSourceDestination ZoneDestinationServicesActionTrackEnabledUidComment
                      12022-04-19TestRule1srczn TestIp1 (1.2.3.4/32)
                       TestIp2 (127.0.0.1/32)
                      dstzn TestIpRange (1.2.3.4/32-1.2.3.5/32) TestService1 (443/TCP)acceptnoneYuid1comment1
                      2TestRule2not
                       TestUser1@ TestIp1 (1.2.3.4/32)
                       TestUser1@ TestIp2 (127.0.0.1/32)
                      not
                       TestUser2@ TestIpRange (1.2.3.4/32-1.2.3.5/32)
                      not
                       TestService2 (6666-7777/UDP)
                      denynoneYuid2:123comment2
                      " + - "

                      Network Objects


                      " + - "" + - "" + - "" + - "" + - "
                      No.NameTypeIP AddressMembersUidComment
                      1TestIp1network1.2.3.4/32
                      2TestIp2network127.0.0.1/32
                      3TestIpRangeip_range1.2.3.4/32-1.2.3.5/32
                      " + - "

                      Network Services


                      " + - "" + - "" + - "" + - "
                      No.NameTypeProtocolPortMembersUidComment
                      1TestService1TestService1TCP443
                      2TestService2TestService2UDP6666-7777
                      " + - "

                      Users


                      " + - "" + - "" + - "" + - "
                      No.NameTypeMembersUidComment
                      1TestUser1TestUser1
                      2TestUser2TestUser2
                      "; - Assert.AreEqual(expectedHtmlResult, removeLinebreaks((removeGenDate(reportRules.ExportToHtml(), true)))); - } - - [Test] - public void RecertReportGenerateHtml() - { - Log.WriteInfo("Test Log", "starting recert report html generation"); - ReportRules reportRecerts = new ReportRules(query, userConfig, ReportType.Recertification); - reportRecerts.Managements = ConstructRecertReport(); - - string expectedHtmlResult = "Recertification Report" + - "" + - "" + - "

                      Recertification Report

                      " + - "

                      Filter: TestFilter

                      " + - "

                      Time of configuration: 2023-04-20T15:50:04Z (UTC)

                      " + - "

                      Generated on: Z (UTC)

                      " + - "

                      Devices: TestMgt [TestDev]


                      " + - "

                      TestMgt


                      " + - "

                      TestDev


                      " + - "" + - "" + - $"" + - "" + - "" + - "" + - "" + - "" + - "" + - "" + - "" + - "" + - "" + - "" + - "" + - "" + - "" + - "" + - $"" + - "" + - "" + - "" + - "" + - "" + - "" + - "" + - "" + - "" + - "" + - "" + - "" + - "" + - "
                      No.Next Recertification DateOwnerIP address matchLast HitNameSource ZoneSourceDestination ZoneDestinationServicesActionTrackEnabledUidComment
                      1

                      1. {DateOnly.FromDateTime(DateTime.Now.AddDays(5)).ToString("yyyy-MM-dd")}

                      2. {DateOnly.FromDateTime(DateTime.Now.AddDays(-5)).ToString("yyyy-MM-dd")}

                      1. TestOwner1

                      2. TestOwner2

                      1. TestIp1

                      2. TestIp2

                      2022-04-19TestRule1srczn TestIp1 (1.2.3.4/32)
                       TestIp2 (127.0.0.1/32)
                      dstzn TestIpRange (1.2.3.4/32-1.2.3.5/32) TestService1 (443/TCP)acceptnoneYuid1comment1
                      2

                      {DateOnly.FromDateTime(DateTime.Now).ToString("yyyy-MM-dd")}

                      TestOwner1

                      TestIpRange

                      TestRule2not
                       TestUser1@ TestIp1 (1.2.3.4/32)
                       TestUser1@ TestIp2 (127.0.0.1/32)
                      not
                       TestUser2@ TestIpRange (1.2.3.4/32-1.2.3.5/32)
                      not
                       TestService2 (6666-7777/UDP)
                      denynoneYuid2:123comment2
                      " + - "

                      Network Objects


                      " + - "" + - "" + - "" + - "
                      No.NameTypeIP AddressMembersUidComment
                      1TestIp1network1.2.3.4/32
                      2TestIp2network127.0.0.1/32
                      3TestIpRangeip_range1.2.3.4/32-1.2.3.5/32
                      " + - "

                      Network Services


                      " + - "" + - "" + - "
                      No.NameTypeProtocolPortMembersUidComment
                      1TestService1TestService1TCP443
                      2TestService2TestService2UDP6666-7777
                      " + - "

                      Users


                      " + - "" + - "" + - "
                      No.NameTypeMembersUidComment
                      1TestUser1TestUser1
                      2TestUser2TestUser2
                      "; - Assert.AreEqual(expectedHtmlResult, removeLinebreaks((removeGenDate(reportRecerts.ExportToHtml(), true)))); - } - - [Test] - public void NatRulesGenerateHtml() - { - Log.WriteInfo("Test Log", "starting nat rules report html generation"); - ReportNatRules reportNatRules = new ReportNatRules(query, userConfig, ReportType.NatRules); - reportNatRules.Managements = ConstructNatRuleReport(); - - string expectedHtmlResult = "NAT Rules Report" + - "" + - "" + - "

                      NAT Rules Report

                      " + - "

                      Filter: TestFilter

                      " + - "

                      Time of configuration: 2023-04-20T15:50:04Z (UTC)

                      " + - "

                      Generated on: Z (UTC)

                      " + - "

                      Devices: TestMgt [TestDev]


                      " + - "

                      TestMgt


                      " + - "

                      TestDev


                      " + - "" + - "" + - "" + - "" + - "" + - "" + - "" + - "" + - "" + - "" + - "" + - "" + - "" + - "
                      No.NameSource ZoneSourceDestination ZoneDestinationServicesTranslated SourceTranslated DestinationTranslated ServicesEnabledUidComment
                      1TestRule1srczn TestIp1 (1.2.3.4/32)
                       TestIp2 (127.0.0.1/32)
                      dstzn TestIpRange (1.2.3.4/32-1.2.3.5/32) TestService1 (443/TCP) TestUser2@ TestIp1Changed (2.3.4.5/32)not
                       TestIp1Changed (2.3.4.5/32)
                       TestIpNew (10.0.6.1/32)
                       TestService1 (443/TCP)
                       TestService2 (6666-7777/UDP)
                      Yuid1comment1
                      " + - "

                      Network Objects


                      " + - "" + - "" + - "" + - "" + - "" + - "
                      No.NameTypeIP AddressMembersUidComment
                      1TestIp1network1.2.3.4/32
                      2TestIp2network127.0.0.1/32
                      3TestIpRangeip_range1.2.3.4/32-1.2.3.5/32
                      4TestIpNewnetwork10.0.6.1/32
                      5TestIp1Changednetwork2.3.4.5/32
                      " + - "

                      Network Services


                      " + - "" + - "" + - "
                      No.NameTypeProtocolPortMembersUidComment
                      1TestService1TestService1TCP443
                      2TestService2TestService2UDP6666-7777
                      " + - "

                      Users


                      " + - "" + - "
                      No.NameTypeMembersUidComment
                      1TestUser2TestUser2
                      "; - Assert.AreEqual(expectedHtmlResult, removeLinebreaks((removeGenDate(reportNatRules.ExportToHtml(), true)))); - } - - [Test] - public void ChangesGenerateHtml() - { - Log.WriteInfo("Test Log", "starting changes report html generation"); - ReportChanges reportChanges = new ReportChanges(query, userConfig, ReportType.Changes); - reportChanges.Managements = ConstructChangeReport(false); - - string expectedHtmlResult = "Changes Report" + - "" + - "" + - "

                      Changes Report

                      " + - "

                      Filter: TestFilter

                      " + - "

                      Generated on: Z (UTC)

                      " + - "

                      Devices: TestMgt [TestDev]


                      " + - "

                      TestMgt


                      " + - "

                      TestDev


                      " + - "" + - "" + - "" + - "" + - "" + - "" + - "" + - "" + - "" + - "" + - "" + - "" + - "" + - "" + - "" + - "" + - "" + - "" + - "" + - "" + - "" + - "" + - "" + - "" + - "" + - "" + - "" + - "" + - "" + - "" + - "" + - "" + - "" + - "" + - "
                      Change TimeChange TypeNameSource ZoneSourceDestination ZoneDestinationServicesActionTrackEnabledUidComment
                      05.04.2023 12:00:00Rule added

                      TestRule1

                      srczn

                       TestIp1 (1.2.3.4/32)
                       TestIp2 (127.0.0.1/32)

                      dstzn

                       TestIpRange (1.2.3.4/32-1.2.3.5/32)

                       TestService1 (443/TCP)

                      accept

                      none

                      Y

                      uid1

                      comment1

                      05.04.2023 12:00:00Rule modifiedTestRule1srczn

                       TestIp2 (127.0.0.1/32)

                      " + - "deleted:

                       TestIp1 (1.2.3.4/32)

                      " + - "added:

                       TestIp1Changed (2.3.4.5/32)

                      dstzn

                       TestIpRange (1.2.3.4/32-1.2.3.5/32)

                      " + - "added:

                       TestIpNew (10.0.6.1/32)

                      deleted:

                       TestService1 (443/TCP)

                      " + - "added:

                      not
                       TestService1 (443/TCP)

                      acceptnoneYdeleted:

                      uid1

                      deleted:

                      comment1

                      added:

                      new comment

                      05.04.2023 12:00:00Rule modifiedTestRule2not
                       TestUser1@ TestIp1 (1.2.3.4/32)
                      " + - " TestUser1@ TestIp2 (127.0.0.1/32)
                      deleted:

                      not
                       TestUser2@ TestIpRange (1.2.3.4/32-1.2.3.5/32)

                      " + - "added:

                       TestUser2@ TestIpRange (1.2.3.4/32-1.2.3.5/32)

                      deleted:

                      not
                       TestService2 (6666-7777/UDP)

                      " + - "added:

                       TestService2 (6666-7777/UDP)

                      denynonedeleted:

                      Y

                      added:

                      N

                      uid2:123comment2
                      05.04.2023 12:00:00Rule deleted

                      TestRule2

                      not
                       TestUser1@ TestIp1 (1.2.3.4/32)
                      " + - " TestUser1@ TestIp2 (127.0.0.1/32)

                      not
                       TestUser2@ TestIpRange (1.2.3.4/32-1.2.3.5/32)

                      not
                       TestService2 (6666-7777/UDP)

                      deny

                      none

                      Y

                      uid2:123

                      comment2

                      " + - ""; - Assert.AreEqual(expectedHtmlResult, removeLinebreaks((removeGenDate(reportChanges.ExportToHtml(), true)))); - } - - [Test] - public void ResolvedChangesGenerateHtml() - { - Log.WriteInfo("Test Log", "starting changes report resolved html generation"); - ReportChanges reportChanges = new ReportChanges(query, userConfig, ReportType.ResolvedChanges); - reportChanges.Managements = ConstructChangeReport(true); - - string expectedHtmlResult = "Changes Report (resolved)" + - "" + - "" + - "

                      Changes Report (resolved)

                      " + - "

                      Filter: TestFilter

                      " + - "

                      Generated on: Z (UTC)

                      " + - "

                      Devices: TestMgt [TestDev]


                      " + - "

                      TestMgt


                      " + - "

                      TestDev


                      " + - "" + - "" + - "" + - "" + - "" + - "" + - "" + - "" + - "" + - "" + - "" + - "" + - "" + - "" + - "" + - "" + - "" + - "" + - "" + - "" + - "" + - "" + - "" + - "" + - "" + - "" + - "" + - "" + - "" + - "" + - "" + - "" + - "" + - "" + - "" + - "" + - "
                      Change TimeChange TypeNameSource ZoneSourceDestination ZoneDestinationServicesActionTrackEnabledUidComment
                      05.04.2023 12:00:00Rule added

                      TestRule1

                      srczn

                      TestIp1 (1.2.3.4/32)
                      TestIp2 (127.0.0.1/32)

                      dstzn

                      TestIpRange (1.2.3.4/32-1.2.3.5/32)

                      TestService1 (443/TCP)

                      accept

                      none

                      Y

                      uid1

                      comment1

                      05.04.2023 12:00:00Rule modifiedTestRule1srczn

                      TestIp2 (127.0.0.1/32)

                      deleted:

                      TestIp1 (1.2.3.4/32)

                      " + - "added:

                      TestIp1Changed (2.3.4.5/32)

                      dstzn

                      TestIpRange (1.2.3.4/32-1.2.3.5/32)

                      added:

                      TestIpNew (10.0.6.1/32)

                      deleted:

                      TestService1 (443/TCP)

                      " + - "added:

                      not
                      TestService1 (443/TCP)

                      acceptnoneYdeleted:

                      uid1

                      deleted:

                      comment1

                      added:

                      new comment

                      05.04.2023 12:00:00Rule modifiedTestRule2not
                      TestUser1@TestIp1 (1.2.3.4/32)
                      TestUser1@TestIp2 (127.0.0.1/32)
                      deleted:

                      not
                      TestUser2@TestIpRange (1.2.3.4/32-1.2.3.5/32)

                      added:

                      TestUser2@TestIpRange (1.2.3.4/32-1.2.3.5/32)

                      deleted:

                      not
                      TestService2 (6666-7777/UDP)

                      added:

                      TestService2 (6666-7777/UDP)

                      denynonedeleted:

                      Y

                      added:

                      N

                      uid2:123comment2
                      05.04.2023 12:00:00Rule deleted

                      TestRule2

                      not
                      TestUser1@TestIp1 (1.2.3.4/32)
                      TestUser1@TestIp2 (127.0.0.1/32)

                      not
                      TestUser2@TestIpRange (1.2.3.4/32-1.2.3.5/32)

                      not
                      TestService2 (6666-7777/UDP)

                      deny

                      none

                      Y

                      uid2:123

                      comment2

                      " + - ""; - Assert.AreEqual(expectedHtmlResult, removeLinebreaks((removeGenDate(reportChanges.ExportToHtml(), true)))); - } - - [Test] - public void ResolvedChangesTechGenerateHtml() - { - Log.WriteInfo("Test Log", "starting changes report tech html generation"); - ReportChanges reportChanges = new ReportChanges(query, userConfig, ReportType.ResolvedChangesTech); - reportChanges.Managements = ConstructChangeReport(true); - - string expectedHtmlResult = "Changes Report (technical)" + - "" + - "" + - "

                      Changes Report (technical)

                      " + - "

                      Filter: TestFilter

                      " + - "

                      Generated on: Z (UTC)

                      " + - "

                      Devices: TestMgt [TestDev]


                      " + - "

                      TestMgt


                      " + - "

                      TestDev


                      " + - "" + - "" + - "" + - "" + - "" + - "" + - "" + - "" + - "" + - "" + - "" + - "" + - "" + - "" + - "" + - "" + - "" + - "" + - "" + - "" + - "" + - "" + - "" + - "" + - "" + - "" + - "" + - "" + - "" + - "" + - "" + - "" + - "" + - "" + - "" + - "" + - "
                      Change TimeChange TypeNameSource ZoneSourceDestination ZoneDestinationServicesActionTrackEnabledUidComment
                      05.04.2023 12:00:00Rule added

                      TestRule1

                      srczn

                      1.2.3.4/32
                      127.0.0.1/32

                      dstzn

                      1.2.3.4/32-1.2.3.5/32

                      443/TCP

                      accept

                      none

                      Y

                      uid1

                      comment1

                      05.04.2023 12:00:00Rule modifiedTestRule1srczn

                      127.0.0.1/32

                      " + - "deleted:

                      1.2.3.4/32

                      " + - "added:

                      2.3.4.5/32

                      dstzn

                      1.2.3.4/32-1.2.3.5/32

                      added:

                      10.0.6.1/32

                      deleted:

                      443/TCP

                      " + - "added:

                      not
                      443/TCP

                      acceptnoneYdeleted:

                      uid1

                      deleted:

                      comment1

                      added:

                      new comment

                      05.04.2023 12:00:00Rule modifiedTestRule2not
                      TestUser1@1.2.3.4/32
                      TestUser1@127.0.0.1/32
                      deleted:

                      not
                      TestUser2@1.2.3.4/32-1.2.3.5/32

                      added:

                      TestUser2@1.2.3.4/32-1.2.3.5/32

                      deleted:

                      not
                      6666-7777/UDP

                      added:

                      6666-7777/UDP

                      denynonedeleted:

                      Y

                      added:

                      N

                      uid2:123comment2
                      05.04.2023 12:00:00Rule deleted

                      TestRule2

                      not
                      TestUser1@1.2.3.4/32
                      TestUser1@127.0.0.1/32

                      not
                      TestUser2@1.2.3.4/32-1.2.3.5/32

                      not
                      6666-7777/UDP

                      deny

                      none

                      Y

                      uid2:123

                      comment2

                      " + - ""; - Assert.AreEqual(expectedHtmlResult, removeLinebreaks((removeGenDate(reportChanges.ExportToHtml(), true)))); - } - - - [Test] - public void ResolvedRulesGenerateCsv() - { - Log.WriteInfo("Test Log", "starting rules report resolved csv generation"); - ReportRules reportRules = new ReportRules(query, userConfig, ReportType.ResolvedRules); - reportRules.Managements = ConstructRuleReport(true); - - string expectedCsvResult = "# report type: Rules Report (resolved)" + - "# report generation date: Z (UTC)" + - "# date of configuration shown: 2023-04-20T15:50:04Z (UTC)" + - "# device filter: TestMgt [TestDev]" + - "# other filters: TestFilter" + - "# report generator: Firewall Orchestrator - https://fwo.cactus.de/en" + - "# data protection level: For internal use only#" + - "\"management-name\",\"device-name\",\"rule-number\",\"rule-name\",\"source-zone\",\"source\",\"destination-zone\",\"destination\",\"service\",\"action\",\"track\",\"rule-enabled\",\"rule-uid\",\"rule-comment\"" + - "\"TestMgt\",\"TestDev\",\"1\",\"TestRule1\",\"srczn\",\"TestIp1 (1.2.3.4/32),TestIp2 (127.0.0.1/32)\",\"dstzn\",\"TestIpRange (1.2.3.4/32-1.2.3.5/32)\",\"TestService1 (443/TCP)\",\"accept\",\"none\",\"enabled\",\"uid1\",\"comment1\"" + - "\"TestMgt\",\"TestDev\",\"2\",\"TestRule2\",\"\",\"not(TestUser1@TestIp1 (1.2.3.4/32),TestUser1@TestIp2 (127.0.0.1/32))\",\"\",\"not(TestUser2@TestIpRange (1.2.3.4/32-1.2.3.5/32))\",\"not(TestService2 (6666-7777/UDP))\",\"deny\",\"none\",\"enabled\",\"uid2:123\",\"comment2\""; - Assert.AreEqual(expectedCsvResult, removeLinebreaks(removeGenDate(reportRules.ExportToCsv()))); - } - - [Test] - public void ResolvedRulesTechGenerateCsv() - { - Log.WriteInfo("Test Log", "starting rules report tech csv generation"); - ReportRules reportRules = new ReportRules(query, userConfig, ReportType.ResolvedRulesTech); - reportRules.Managements = ConstructRuleReport(true); - - string expectedCsvResult = "# report type: Rules Report (technical)" + - "# report generation date: Z (UTC)" + - "# date of configuration shown: 2023-04-20T15:50:04Z (UTC)" + - "# device filter: TestMgt [TestDev]" + - "# other filters: TestFilter" + - "# report generator: Firewall Orchestrator - https://fwo.cactus.de/en" + - "# data protection level: For internal use only#" + - "\"management-name\",\"device-name\",\"rule-number\",\"rule-name\",\"source-zone\",\"source\",\"destination-zone\",\"destination\",\"service\",\"action\",\"track\",\"rule-enabled\",\"rule-uid\",\"rule-comment\"" + - "\"TestMgt\",\"TestDev\",\"1\",\"TestRule1\",\"srczn\",\"1.2.3.4/32,127.0.0.1/32\",\"dstzn\",\"1.2.3.4/32-1.2.3.5/32\",\"443/TCP\",\"accept\",\"none\",\"enabled\",\"uid1\",\"comment1\"" + - "\"TestMgt\",\"TestDev\",\"2\",\"TestRule2\",\"\",\"not(TestUser1@1.2.3.4/32,TestUser1@127.0.0.1/32)\",\"\",\"not(TestUser2@1.2.3.4/32-1.2.3.5/32)\",\"not(6666-7777/UDP)\",\"deny\",\"none\",\"enabled\",\"uid2:123\",\"comment2\""; - Assert.AreEqual(expectedCsvResult, removeLinebreaks(removeGenDate(reportRules.ExportToCsv()))); - } - - [Test] - public void ResolvedChangesGenerateCsv() - { - Log.WriteInfo("Test Log", "starting changes report resolved csv generation"); - ReportChanges reportChanges = new ReportChanges(query, userConfig, ReportType.ResolvedChanges); - reportChanges.Managements = ConstructChangeReport(true); - - string expectedCsvResult = "# report type: Changes Report (resolved)" + - "# report generation date: Z (UTC)" + - "# device filter: TestMgt [TestDev]" + - "# other filters: TestFilter" + - "# report generator: Firewall Orchestrator - https://fwo.cactus.de/en" + - "# data protection level: For internal use only#" + - "\"management-name\",\"device-name\",\"change-time\",\"change-type\",\"rule-name\",\"source-zone\",\"source\",\"destination-zone\",\"destination\",\"service\",\"action\",\"track\",\"rule-enabled\",\"rule-uid\",\"rule-comment\"" + - "\"TestMgt\",\"TestDev\",\"05.04.2023 12:00:00\",\"Rule added\",\"TestRule1\",\"srczn\",\"TestIp1 (1.2.3.4/32),TestIp2 (127.0.0.1/32)\"," + - "\"dstzn\",\"TestIpRange (1.2.3.4/32-1.2.3.5/32)\",\"TestService1 (443/TCP)\",\"accept\",\"none\",\"enabled\",\"uid1\",\"comment1\"" + - "\"TestMgt\",\"TestDev\",\"05.04.2023 12:00:00\",\"Rule modified\",\"TestRule1\",\"srczn\",\"TestIp2 (127.0.0.1/32) deleted: TestIp1 (1.2.3.4/32) added: TestIp1Changed (2.3.4.5/32)\"," + - "\"dstzn\",\"TestIpRange (1.2.3.4/32-1.2.3.5/32) added: TestIpNew (10.0.6.1/32)\"," + - "\" deleted: TestService1 (443/TCP) added: not(TestService1 (443/TCP))\",\"accept\",\"none\",\"enabled\",\" deleted: uid1\",\" deleted: comment1 added: new comment\"" + - "\"TestMgt\",\"TestDev\",\"05.04.2023 12:00:00\",\"Rule modified\",\"TestRule2\",\"\",\"not(TestUser1@TestIp1 (1.2.3.4/32),TestUser1@TestIp2 (127.0.0.1/32))\"," + - "\"\",\" deleted: not(TestUser2@TestIpRange (1.2.3.4/32-1.2.3.5/32)) added: TestUser2@TestIpRange (1.2.3.4/32-1.2.3.5/32)\"," + - "\" deleted: not(TestService2 (6666-7777/UDP)) added: TestService2 (6666-7777/UDP)\",\"deny\",\"none\",\" deleted: enabled added: disabled\",\"uid2:123\",\"comment2\"" + - "\"TestMgt\",\"TestDev\",\"05.04.2023 12:00:00\",\"Rule deleted\",\"TestRule2\",\"\",\"not(TestUser1@TestIp1 (1.2.3.4/32),TestUser1@TestIp2 (127.0.0.1/32))\"," + - "\"\",\"not(TestUser2@TestIpRange (1.2.3.4/32-1.2.3.5/32))\",\"not(TestService2 (6666-7777/UDP))\",\"deny\",\"none\",\"enabled\",\"uid2:123\",\"comment2\""; - Assert.AreEqual(expectedCsvResult, removeLinebreaks(removeGenDate(reportChanges.ExportToCsv()))); - } - - [Test] - public void ResolvedChangesTechGenerateCsv() - { - Log.WriteInfo("Test Log", "starting changes report tech csv generation"); - ReportChanges reportChanges = new ReportChanges(query, userConfig, ReportType.ResolvedChangesTech); - reportChanges.Managements = ConstructChangeReport(true); - - string expectedCsvResult = "# report type: Changes Report (technical)" + - "# report generation date: Z (UTC)" + - "# device filter: TestMgt [TestDev]" + - "# other filters: TestFilter" + - "# report generator: Firewall Orchestrator - https://fwo.cactus.de/en" + - "# data protection level: For internal use only#" + - "\"management-name\",\"device-name\",\"change-time\",\"change-type\",\"rule-name\",\"source-zone\",\"source\",\"destination-zone\",\"destination\",\"service\",\"action\",\"track\",\"rule-enabled\",\"rule-uid\",\"rule-comment\"" + - "\"TestMgt\",\"TestDev\",\"05.04.2023 12:00:00\",\"Rule added\",\"TestRule1\",\"srczn\",\"1.2.3.4/32,127.0.0.1/32\",\"dstzn\",\"1.2.3.4/32-1.2.3.5/32\",\"443/TCP\",\"accept\",\"none\",\"enabled\",\"uid1\",\"comment1\"" + - "\"TestMgt\",\"TestDev\",\"05.04.2023 12:00:00\",\"Rule modified\",\"TestRule1\",\"srczn\",\"127.0.0.1/32 deleted: 1.2.3.4/32 added: 2.3.4.5/32\",\"dstzn\",\"1.2.3.4/32-1.2.3.5/32 added: 10.0.6.1/32\",\" deleted: 443/TCP added: not(443/TCP)\",\"accept\",\"none\",\"enabled\",\" deleted: uid1\",\" deleted: comment1 added: new comment\"" + - "\"TestMgt\",\"TestDev\",\"05.04.2023 12:00:00\",\"Rule modified\",\"TestRule2\",\"\",\"not(TestUser1@1.2.3.4/32,TestUser1@127.0.0.1/32)\",\"\",\" deleted: not(TestUser2@1.2.3.4/32-1.2.3.5/32) added: TestUser2@1.2.3.4/32-1.2.3.5/32\",\" deleted: not(6666-7777/UDP) added: 6666-7777/UDP\",\"deny\",\"none\",\" deleted: enabled added: disabled\",\"uid2:123\",\"comment2\"" + - "\"TestMgt\",\"TestDev\",\"05.04.2023 12:00:00\",\"Rule deleted\",\"TestRule2\",\"\",\"not(TestUser1@1.2.3.4/32,TestUser1@127.0.0.1/32)\",\"\",\"not(TestUser2@1.2.3.4/32-1.2.3.5/32)\",\"not(6666-7777/UDP)\",\"deny\",\"none\",\"enabled\",\"uid2:123\",\"comment2\""; - Assert.AreEqual(expectedCsvResult, removeLinebreaks(removeGenDate(reportChanges.ExportToCsv()))); - } - - - [Test] - public void RulesGenerateJson() - { - Log.WriteInfo("Test Log", "starting rules report json generation"); - ReportRules reportRules = new ReportRules(query, userConfig, ReportType.Rules); - reportRules.Managements = ConstructRuleReport(false); - - string expectedJsonResult = - "[{\"id\": 0,\"name\": \"TestMgt\",\"hostname\": \"\"," + - "\"import_credential\": {\"id\": 0,\"credential_name\": \"\",\"is_key_pair\": false,\"user\": null,\"secret\": \"\",\"sshPublicKey\": null,\"cloud_client_id\": null,\"cloud_client_secret\": null}," + - "\"configPath\": \"\",\"domainUid\": \"\",\"cloudSubscriptionId\": \"\",\"cloudTenantId\": \"\",\"superManager\": null,\"importerHostname\": \"\",\"port\": 0,\"importDisabled\": false,\"forceInitialImport\": false,\"hideInUi\": false,\"comment\": null,\"debugLevel\": null,\"tenant_id\": 0," + - "\"devices\": [{\"id\": 0,\"name\": \"TestDev\",\"deviceType\": {\"id\": 0,\"name\": \"\",\"version\": \"\",\"manufacturer\": \"\",\"isPureRoutingDevice\": false,\"isManagement\": false}," + - "\"management\": {\"id\": 0,\"name\": \"\",\"hostname\": \"\"," + - "\"import_credential\": {\"id\": 0,\"credential_name\": \"\",\"is_key_pair\": false,\"user\": null,\"secret\": \"\",\"sshPublicKey\": null,\"cloud_client_id\": null,\"cloud_client_secret\": null}," + - "\"configPath\": \"\",\"domainUid\": \"\",\"cloudSubscriptionId\": \"\",\"cloudTenantId\": \"\",\"superManager\": null,\"importerHostname\": \"\",\"port\": 0,\"importDisabled\": false,\"forceInitialImport\": false,\"hideInUi\": false,\"comment\": null,\"debugLevel\": null,\"tenant_id\": 0," + - "\"devices\": [],\"networkObjects\": [],\"serviceObjects\": [],\"userObjects\": [],\"reportNetworkObjects\": [],\"reportServiceObjects\": [],\"reportUserObjects\": []," + - "\"deviceType\": {\"id\": 0,\"name\": \"\",\"version\": \"\",\"manufacturer\": \"\",\"isPureRoutingDevice\": false,\"isManagement\": false}," + - "\"import\": {\"aggregate\": {\"max\": {\"id\": null}}},\"RelevantImportId\": null,\"Ignore\": false,\"AwaitDevice\": false,\"Delete\": false,\"ActionId\": 0,\"ReportedRuleIds\": [],\"ReportedNetworkServiceIds\": [],\"objects_aggregate\": {\"aggregate\": {\"count\": 0}}," + - "\"services_aggregate\": {\"aggregate\": {\"count\": 0}},\"usrs_aggregate\": {\"aggregate\": {\"count\": 0}},\"rules_aggregate\": {\"aggregate\": {\"count\": 0}}},\"local_rulebase_name\": null,\"global_rulebase_name\": null,\"package_name\": null,\"importDisabled\": false,\"hideInUi\": false,\"comment\": null," + - "\"rules\": [{\"rule_id\": 0,\"rule_uid\": \"uid1\",\"mgm_id\": 0,\"rule_num_numeric\": 0,\"rule_name\": \"TestRule1\",\"rule_comment\": \"comment1\",\"rule_disabled\": false," + - "\"rule_services\": [{\"service\": {\"svc_id\": 1,\"svc_name\": \"TestService1\",\"svc_uid\": \"\",\"svc_port\": 443,\"svc_port_end\": 443,\"svc_source_port\": null,\"svc_source_port_end\": null,\"svc_code\": \"\",\"svc_timeout\": null,\"svc_typ_id\": null,\"active\": false,\"svc_create\": 0," + - "\"svc_create_time\": {\"time\": \"0001-01-01T00:00:00\"},\"svc_last_seen\": 0," + - "\"service_type\": {\"name\": \"\"},\"svc_comment\": \"\",\"svc_color_id\": null,\"ip_proto_id\": null,\"protocol_name\": {\"id\": 0,\"name\": \"TCP\"},\"svc_member_names\": \"\",\"svc_member_refs\": \"\",\"svcgrps\": [],\"svcgrp_flats\": []}}]," + - "\"rule_svc_neg\": false,\"rule_svc\": \"\",\"rule_src_neg\": false,\"rule_src\": \"\",\"src_zone\": {\"zone_id\": 0,\"zone_name\": \"srczn\"}," + - "\"rule_froms\": [{\"object\": {\"obj_id\": 1,\"obj_name\": \"TestIp1\",\"obj_ip\": \"1.2.3.4/32\",\"obj_ip_end\": \"\",\"obj_uid\": \"\",\"zone\": {\"zone_id\": 0,\"zone_name\": \"\"},\"active\": false,\"obj_create\": 0,\"obj_create_time\": {\"time\": \"0001-01-01T00:00:00\"},\"obj_last_seen\": 0,\"type\": {\"name\": \"network\"},\"obj_comment\": \"\",\"obj_member_names\": \"\",\"obj_member_refs\": \"\",\"objgrps\": [],\"objgrp_flats\": []}," + - "\"usr\": {\"user_id\": 0,\"user_uid\": \"\",\"user_name\": \"\",\"user_comment\": \"\",\"user_lastname\": \"\",\"user_firstname\": \"\",\"usr_typ_id\": 0,\"type\": {\"usr_typ_name\": \"\"},\"user_create\": 0,\"user_create_time\": {\"time\": \"0001-01-01T00:00:00\"},\"user_last_seen\": 0,\"user_member_names\": \"\",\"user_member_refs\": \"\",\"usergrps\": [],\"usergrp_flats\": []}}," + - "{\"object\": {\"obj_id\": 2,\"obj_name\": \"TestIp2\",\"obj_ip\": \"127.0.0.1/32\",\"obj_ip_end\": \"\",\"obj_uid\": \"\",\"zone\": {\"zone_id\": 0,\"zone_name\": \"\"},\"active\": false,\"obj_create\": 0,\"obj_create_time\": {\"time\": \"0001-01-01T00:00:00\"},\"obj_last_seen\": 0,\"type\": {\"name\": \"network\"},\"obj_comment\": \"\",\"obj_member_names\": \"\",\"obj_member_refs\": \"\",\"objgrps\": [],\"objgrp_flats\": []}," + - "\"usr\": {\"user_id\": 0,\"user_uid\": \"\",\"user_name\": \"\",\"user_comment\": \"\",\"user_lastname\": \"\",\"user_firstname\": \"\",\"usr_typ_id\": 0,\"type\": {\"usr_typ_name\": \"\"},\"user_create\": 0,\"user_create_time\": {\"time\": \"0001-01-01T00:00:00\"},\"user_last_seen\": 0,\"user_member_names\": \"\",\"user_member_refs\": \"\",\"usergrps\": [],\"usergrp_flats\": []}}]," + - "\"rule_dst_neg\": false,\"rule_dst\": \"\",\"dst_zone\": {\"zone_id\": 0,\"zone_name\": \"dstzn\"}," + - "\"rule_tos\": [{\"object\": {\"obj_id\": 3,\"obj_name\": \"TestIpRange\",\"obj_ip\": \"1.2.3.4/32\",\"obj_ip_end\": \"1.2.3.5/32\",\"obj_uid\": \"\",\"zone\": {\"zone_id\": 0,\"zone_name\": \"\"},\"active\": false,\"obj_create\": 0,\"obj_create_time\": {\"time\": \"0001-01-01T00:00:00\"},\"obj_last_seen\": 0,\"type\": {\"name\": \"ip_range\"},\"obj_comment\": \"\",\"obj_member_names\": \"\",\"obj_member_refs\": \"\",\"objgrps\": [],\"objgrp_flats\": []}," + - "\"usr\": {\"user_id\": 0,\"user_uid\": \"\",\"user_name\": \"\",\"user_comment\": \"\",\"user_lastname\": \"\",\"user_firstname\": \"\",\"usr_typ_id\": 0,\"type\": {\"usr_typ_name\": \"\"},\"user_create\": 0,\"user_create_time\": {\"time\": \"0001-01-01T00:00:00\"},\"user_last_seen\": 0,\"user_member_names\": \"\",\"user_member_refs\": \"\",\"usergrps\": [],\"usergrp_flats\": []}}]," + - "\"rule_action\": \"accept\",\"rule_track\": \"none\",\"section_header\": \"\"," + - "\"rule_metadatum\": {\"rule_metadata_id\": 0,\"rule_created\": null,\"rule_last_modified\": null,\"rule_first_hit\": null,\"rule_last_hit\": \"2022-04-19T00:00:00\",\"rule_last_certified\": null,\"rule_last_certifier_dn\": \"\",\"rule_to_be_removed\": false,\"rule_decert_date\": null,\"rule_recertification_comment\": \"\",\"recertification\": [],\"recert_history\": [],\"NextRecert\": \"0001-01-01T00:00:00\",\"LastCertifierName\": \"\",\"Recert\": false,\"Style\": \"\"}," + - "\"translate\": {\"rule_svc_neg\": false,\"rule_svc\": \"\",\"rule_services\": [],\"rule_src_neg\": false,\"rule_src\": \"\",\"rule_froms\": [],\"rule_dst_neg\": false,\"rule_dst\": \"\",\"rule_tos\": []},\"owner_name\": \"\",\"owner_id\": null,\"matches\": \"\",\"dev_id\": 0,\"DisplayOrderNumber\": 1,\"Certified\": false,\"DeviceName\": \"\"}," + - "{\"rule_id\": 0,\"rule_uid\": \"uid2:123\",\"mgm_id\": 0,\"rule_num_numeric\": 0,\"rule_name\": \"TestRule2\",\"rule_comment\": \"comment2\",\"rule_disabled\": false," + - "\"rule_services\": [{\"service\": {\"svc_id\": 2,\"svc_name\": \"TestService2\",\"svc_uid\": \"\",\"svc_port\": 6666,\"svc_port_end\": 7777,\"svc_source_port\": null,\"svc_source_port_end\": null,\"svc_code\": \"\",\"svc_timeout\": null,\"svc_typ_id\": null,\"active\": false,\"svc_create\": 0,\"svc_create_time\": {\"time\": \"0001-01-01T00:00:00\"},\"svc_last_seen\": 0," + - "\"service_type\": {\"name\": \"\"},\"svc_comment\": \"\",\"svc_color_id\": null,\"ip_proto_id\": null,\"protocol_name\": {\"id\": 0,\"name\": \"UDP\"},\"svc_member_names\": \"\",\"svc_member_refs\": \"\",\"svcgrps\": [],\"svcgrp_flats\": []}}]," + - "\"rule_svc_neg\": true,\"rule_svc\": \"\",\"rule_src_neg\": true,\"rule_src\": \"\",\"src_zone\": {\"zone_id\": 0,\"zone_name\": \"\"}," + - "\"rule_froms\": [{\"object\": {\"obj_id\": 1,\"obj_name\": \"TestIp1\",\"obj_ip\": \"1.2.3.4/32\",\"obj_ip_end\": \"\",\"obj_uid\": \"\",\"zone\": {\"zone_id\": 0,\"zone_name\": \"\"},\"active\": false,\"obj_create\": 0,\"obj_create_time\": {\"time\": \"0001-01-01T00:00:00\"},\"obj_last_seen\": 0,\"type\": {\"name\": \"network\"},\"obj_comment\": \"\",\"obj_member_names\": \"\",\"obj_member_refs\": \"\",\"objgrps\": [],\"objgrp_flats\": []}," + - "\"usr\": {\"user_id\": 1,\"user_uid\": \"\",\"user_name\": \"TestUser1\",\"user_comment\": \"\",\"user_lastname\": \"\",\"user_firstname\": \"\",\"usr_typ_id\": 0,\"type\": {\"usr_typ_name\": \"\"},\"user_create\": 0,\"user_create_time\": {\"time\": \"0001-01-01T00:00:00\"},\"user_last_seen\": 0,\"user_member_names\": \"\",\"user_member_refs\": \"\",\"usergrps\": [],\"usergrp_flats\": []}}," + - "{\"object\": {\"obj_id\": 2,\"obj_name\": \"TestIp2\",\"obj_ip\": \"127.0.0.1/32\",\"obj_ip_end\": \"\",\"obj_uid\": \"\",\"zone\": {\"zone_id\": 0,\"zone_name\": \"\"},\"active\": false,\"obj_create\": 0,\"obj_create_time\": {\"time\": \"0001-01-01T00:00:00\"},\"obj_last_seen\": 0,\"type\": {\"name\": \"network\"},\"obj_comment\": \"\",\"obj_member_names\": \"\",\"obj_member_refs\": \"\",\"objgrps\": [],\"objgrp_flats\": []}," + - "\"usr\": {\"user_id\": 1,\"user_uid\": \"\",\"user_name\": \"TestUser1\",\"user_comment\": \"\",\"user_lastname\": \"\",\"user_firstname\": \"\",\"usr_typ_id\": 0,\"type\": {\"usr_typ_name\": \"\"},\"user_create\": 0,\"user_create_time\": {\"time\": \"0001-01-01T00:00:00\"},\"user_last_seen\": 0,\"user_member_names\": \"\",\"user_member_refs\": \"\",\"usergrps\": [],\"usergrp_flats\": []}}]," + - "\"rule_dst_neg\": true,\"rule_dst\": \"\",\"dst_zone\": {\"zone_id\": 0,\"zone_name\": \"\"}," + - "\"rule_tos\": [{\"object\": {\"obj_id\": 3,\"obj_name\": \"TestIpRange\",\"obj_ip\": \"1.2.3.4/32\",\"obj_ip_end\": \"1.2.3.5/32\",\"obj_uid\": \"\",\"zone\": {\"zone_id\": 0,\"zone_name\": \"\"},\"active\": false,\"obj_create\": 0,\"obj_create_time\": {\"time\": \"0001-01-01T00:00:00\"},\"obj_last_seen\": 0,\"type\": {\"name\": \"ip_range\"},\"obj_comment\": \"\",\"obj_member_names\": \"\",\"obj_member_refs\": \"\",\"objgrps\": [],\"objgrp_flats\": []}," + - "\"usr\": {\"user_id\": 2,\"user_uid\": \"\",\"user_name\": \"TestUser2\",\"user_comment\": \"\",\"user_lastname\": \"\",\"user_firstname\": \"\",\"usr_typ_id\": 0,\"type\": {\"usr_typ_name\": \"group\"},\"user_create\": 0,\"user_create_time\": {\"time\": \"0001-01-01T00:00:00\"},\"user_last_seen\": 0,\"user_member_names\": \"\",\"user_member_refs\": \"\",\"usergrps\": [],\"usergrp_flats\": []}}]," + - "\"rule_action\": \"deny\",\"rule_track\": \"none\",\"section_header\": \"\"," + - "\"rule_metadatum\": {\"rule_metadata_id\": 0,\"rule_created\": null,\"rule_last_modified\": null,\"rule_first_hit\": null,\"rule_last_hit\": null,\"rule_last_certified\": null,\"rule_last_certifier_dn\": \"\",\"rule_to_be_removed\": false,\"rule_decert_date\": null,\"rule_recertification_comment\": \"\",\"recertification\": [],\"recert_history\": [],\"NextRecert\": \"0001-01-01T00:00:00\",\"LastCertifierName\": \"\",\"Recert\": false,\"Style\": \"\"}," + - "\"translate\": {\"rule_svc_neg\": false,\"rule_svc\": \"\",\"rule_services\": [],\"rule_src_neg\": false,\"rule_src\": \"\",\"rule_froms\": [],\"rule_dst_neg\": false,\"rule_dst\": \"\",\"rule_tos\": []},\"owner_name\": \"\",\"owner_id\": null,\"matches\": \"\",\"dev_id\": 0,\"DisplayOrderNumber\": 2,\"Certified\": false,\"DeviceName\": \"\"}],\"changelog_rules\": null,\"rules_aggregate\": {\"aggregate\": {\"count\": 0}}," + - "\"Selected\": false,\"Relevant\": false,\"AwaitMgmt\": false,\"Delete\": false,\"ActionId\": 0}],\"networkObjects\": [],\"serviceObjects\": [],\"userObjects\": []," + - "\"reportNetworkObjects\": [{\"obj_id\": 1,\"obj_name\": \"TestIp1\",\"obj_ip\": \"1.2.3.4/32\",\"obj_ip_end\": \"\",\"obj_uid\": \"\",\"zone\": {\"zone_id\": 0,\"zone_name\": \"\"},\"active\": false,\"obj_create\": 0,\"obj_create_time\": {\"time\": \"0001-01-01T00:00:00\"},\"obj_last_seen\": 0,\"type\": {\"name\": \"network\"},\"obj_comment\": \"\",\"obj_member_names\": \"\",\"obj_member_refs\": \"\",\"objgrps\": [],\"objgrp_flats\": []}," + - "{\"obj_id\": 2,\"obj_name\": \"TestIp2\",\"obj_ip\": \"127.0.0.1/32\",\"obj_ip_end\": \"\",\"obj_uid\": \"\",\"zone\": {\"zone_id\": 0,\"zone_name\": \"\"},\"active\": false,\"obj_create\": 0,\"obj_create_time\": {\"time\": \"0001-01-01T00:00:00\"},\"obj_last_seen\": 0,\"type\": {\"name\": \"network\"},\"obj_comment\": \"\",\"obj_member_names\": \"\",\"obj_member_refs\": \"\",\"objgrps\": [],\"objgrp_flats\": []}," + - "{\"obj_id\": 3,\"obj_name\": \"TestIpRange\",\"obj_ip\": \"1.2.3.4/32\",\"obj_ip_end\": \"1.2.3.5/32\",\"obj_uid\": \"\",\"zone\": {\"zone_id\": 0,\"zone_name\": \"\"},\"active\": false,\"obj_create\": 0,\"obj_create_time\": {\"time\": \"0001-01-01T00:00:00\"},\"obj_last_seen\": 0,\"type\": {\"name\": \"ip_range\"},\"obj_comment\": \"\",\"obj_member_names\": \"\",\"obj_member_refs\": \"\",\"objgrps\": [],\"objgrp_flats\": []}]," + - "\"reportServiceObjects\": [{\"svc_id\": 1,\"svc_name\": \"TestService1\",\"svc_uid\": \"\",\"svc_port\": 443,\"svc_port_end\": 443,\"svc_source_port\": null,\"svc_source_port_end\": null,\"svc_code\": \"\",\"svc_timeout\": null,\"svc_typ_id\": null,\"active\": false,\"svc_create\": 0,\"svc_create_time\": {\"time\": \"0001-01-01T00:00:00\"},\"svc_last_seen\": 0," + - "\"service_type\": {\"name\": \"\"},\"svc_comment\": \"\",\"svc_color_id\": null,\"ip_proto_id\": null,\"protocol_name\": {\"id\": 0,\"name\": \"TCP\"},\"svc_member_names\": \"\",\"svc_member_refs\": \"\",\"svcgrps\": [],\"svcgrp_flats\": []}," + - "{\"svc_id\": 2,\"svc_name\": \"TestService2\",\"svc_uid\": \"\",\"svc_port\": 6666,\"svc_port_end\": 7777,\"svc_source_port\": null,\"svc_source_port_end\": null,\"svc_code\": \"\",\"svc_timeout\": null,\"svc_typ_id\": null,\"active\": false,\"svc_create\": 0,\"svc_create_time\": {\"time\": \"0001-01-01T00:00:00\"},\"svc_last_seen\": 0," + - "\"service_type\": {\"name\": \"\"},\"svc_comment\": \"\",\"svc_color_id\": null,\"ip_proto_id\": null,\"protocol_name\": {\"id\": 0,\"name\": \"UDP\"},\"svc_member_names\": \"\",\"svc_member_refs\": \"\",\"svcgrps\": [],\"svcgrp_flats\": []}]," + - "\"reportUserObjects\": [{\"user_id\": 1,\"user_uid\": \"\",\"user_name\": \"TestUser1\",\"user_comment\": \"\",\"user_lastname\": \"\",\"user_firstname\": \"\",\"usr_typ_id\": 0,\"type\": {\"usr_typ_name\": \"\"},\"user_create\": 0,\"user_create_time\": {\"time\": \"0001-01-01T00:00:00\"},\"user_last_seen\": 0,\"user_member_names\": \"\",\"user_member_refs\": \"\",\"usergrps\": [],\"usergrp_flats\": []}," + - "{\"user_id\": 2,\"user_uid\": \"\",\"user_name\": \"TestUser2\",\"user_comment\": \"\",\"user_lastname\": \"\",\"user_firstname\": \"\",\"usr_typ_id\": 0,\"type\": {\"usr_typ_name\": \"group\"},\"user_create\": 0,\"user_create_time\": {\"time\": \"0001-01-01T00:00:00\"},\"user_last_seen\": 0,\"user_member_names\": \"\",\"user_member_refs\": \"\",\"usergrps\": [],\"usergrp_flats\": []}]," + - "\"deviceType\": {\"id\": 0,\"name\": \"\",\"version\": \"\",\"manufacturer\": \"\",\"isPureRoutingDevice\": false,\"isManagement\": false}," + - "\"import\": {\"aggregate\": {\"max\": {\"id\": null}}},\"RelevantImportId\": null,\"Ignore\": false,\"AwaitDevice\": false,\"Delete\": false,\"ActionId\": 0,\"ReportedRuleIds\": [],\"ReportedNetworkServiceIds\": []," + - "\"objects_aggregate\": {\"aggregate\": {\"count\": 0}},\"services_aggregate\": {\"aggregate\": {\"count\": 0}},\"usrs_aggregate\": {\"aggregate\": {\"count\": 0}},\"rules_aggregate\": {\"aggregate\": {\"count\": 0}}}]"; - // Log.WriteInfo("Test Log", removeLinebreaks((removeGenDate(reportRules.ExportToJson(), true, true)))); - Assert.AreEqual(expectedJsonResult, removeLinebreaks((removeGenDate(reportRules.ExportToJson(), false, true)))); - } - - [Test] - public void ResolvedRulesGenerateJson() - { - Log.WriteInfo("Test Log", "starting resolved rules report json generation"); - ReportRules reportRules = new ReportRules(query, userConfig, ReportType.ResolvedRules); - reportRules.Managements = ConstructRuleReport(true); - - string expectedJsonResult = - "{\"report type\": \"Rules Report (resolved)\",\"report generation date\": \"Z (UTC)\"," + - "\"date of configuration shown\": \"2023-04-20T15:50:04Z (UTC)\",\"device filter\": \"TestMgt [TestDev]\",\"other filters\": \"TestFilter\"," + - "\"report generator\": \"Firewall Orchestrator - https://fwo.cactus.de/en\",\"data protection level\": \"For internal use only\"," + - "\"managements\": [{\"TestMgt\": {\"gateways\": [{\"TestDev\": {" + - "\"rules\": [{\"number\": 1,\"name\": \"TestRule1\",\"source zone\": \"srczn\",\"source negated\": false," + - "\"source\": [\"TestIp1 (1.2.3.4/32)\",\"TestIp2 (127.0.0.1/32)\"],\"destination zone\": \"dstzn\",\"destination negated\": false," + - "\"destination\": [\"TestIpRange (1.2.3.4/32-1.2.3.5/32)\"],\"service negated\": false," + - "\"service\": [\"TestService1 (443/TCP)\"],\"action\": \"accept\",\"tracking\": \"none\",\"disabled\": false,\"rule uid\": \"uid1\",\"comment\": \"comment1\"}," + - "{\"number\": 2,\"name\": \"TestRule2\",\"source zone\": \"\",\"source negated\": true," + - "\"source\": [\"TestUser1@TestIp1 (1.2.3.4/32)\",\"TestUser1@TestIp2 (127.0.0.1/32)\"],\"destination zone\": \"\",\"destination negated\": true," + - "\"destination\": [\"TestUser2@TestIpRange (1.2.3.4/32-1.2.3.5/32)\"],\"service negated\": true," + - "\"service\": [\"TestService2 (6666-7777/UDP)\"],\"action\": \"deny\",\"tracking\": \"none\",\"disabled\": false,\"rule uid\": \"uid2:123\",\"comment\": \"comment2\"}]}}]}}]}"; - Assert.AreEqual(expectedJsonResult, removeLinebreaks((removeGenDate(reportRules.ExportToJson(), false, true)))); - } - - [Test] - public void ResolvedRulesTechGenerateJson() - { - Log.WriteInfo("Test Log", "starting resolved rules report tech json generation"); - ReportRules reportRules = new ReportRules(query, userConfig, ReportType.ResolvedRulesTech); - reportRules.Managements = ConstructRuleReport(true); - - string expectedJsonResult = - "{\"report type\": \"Rules Report (technical)\",\"report generation date\": \"Z (UTC)\"," + - "\"date of configuration shown\": \"2023-04-20T15:50:04Z (UTC)\"," + - "\"device filter\": \"TestMgt [TestDev]\",\"other filters\": \"TestFilter\"," + - "\"report generator\": \"Firewall Orchestrator - https://fwo.cactus.de/en\",\"data protection level\": \"For internal use only\"," + - "\"managements\": [{\"TestMgt\": {\"gateways\": [{\"TestDev\": {" + - "\"rules\": [{\"number\": 1,\"name\": \"TestRule1\",\"source zone\": \"srczn\",\"source negated\": false," + - "\"source\": [\"1.2.3.4/32\",\"127.0.0.1/32\"],\"destination zone\": \"dstzn\",\"destination negated\": false," + - "\"destination\": [\"1.2.3.4/32-1.2.3.5/32\"],\"service negated\": false," + - "\"service\": [\"443/TCP\"],\"action\": \"accept\",\"tracking\": \"none\",\"disabled\": false,\"rule uid\": \"uid1\",\"comment\": \"comment1\"}," + - "{\"number\": 2,\"name\": \"TestRule2\",\"source zone\": \"\",\"source negated\": true," + - "\"source\": [\"TestUser1@1.2.3.4/32\",\"TestUser1@127.0.0.1/32\"],\"destination zone\": \"\"," + - "\"destination negated\": true,\"destination\": [\"TestUser2@1.2.3.4/32-1.2.3.5/32\"],\"service negated\": true," + - "\"service\": [\"6666-7777/UDP\"],\"action\": \"deny\",\"tracking\": \"none\",\"disabled\": false,\"rule uid\": \"uid2:123\",\"comment\": \"comment2\"}]}}]}}]}"; - Assert.AreEqual(expectedJsonResult, removeLinebreaks((removeGenDate(reportRules.ExportToJson(), false, true)))); - } - - [Test] - public void ChangesGenerateJson() - { - Log.WriteInfo("Test Log", "starting changes report json generation"); - ReportChanges reportChanges = new ReportChanges(query, userConfig, ReportType.Changes); - reportChanges.Managements = ConstructChangeReport(false); - - string expectedJsonResult = - "[{\"id\": 0,\"name\": \"TestMgt\",\"hostname\": \"\"," + - "\"import_credential\": {\"id\": 0,\"credential_name\": \"\",\"is_key_pair\": false,\"user\": null,\"secret\": \"\",\"sshPublicKey\": null,\"cloud_client_id\": null,\"cloud_client_secret\": null}," + - "\"configPath\": \"\",\"domainUid\": \"\",\"cloudSubscriptionId\": \"\",\"cloudTenantId\": \"\",\"superManager\": null,\"importerHostname\": \"\",\"port\": 0,\"importDisabled\": false,\"forceInitialImport\": false,\"hideInUi\": false,\"comment\": null,\"debugLevel\": null,\"tenant_id\": 0," + - "\"devices\": [{\"id\": 0,\"name\": \"TestDev\",\"deviceType\": {\"id\": 0,\"name\": \"\",\"version\": \"\",\"manufacturer\": \"\",\"isPureRoutingDevice\": false,\"isManagement\": false}," + - "\"management\": {\"id\": 0,\"name\": \"\",\"hostname\": \"\"," + - "\"import_credential\": {\"id\": 0,\"credential_name\": \"\",\"is_key_pair\": false,\"user\": null,\"secret\": \"\",\"sshPublicKey\": null,\"cloud_client_id\": null,\"cloud_client_secret\": null}," + - "\"configPath\": \"\",\"domainUid\": \"\",\"cloudSubscriptionId\": \"\",\"cloudTenantId\": \"\",\"superManager\": null,\"importerHostname\": \"\",\"port\": 0,\"importDisabled\": false,\"forceInitialImport\": false,\"hideInUi\": false,\"comment\": null,\"debugLevel\": null,\"tenant_id\": 0," + - "\"devices\": [],\"networkObjects\": [],\"serviceObjects\": [],\"userObjects\": [],\"reportNetworkObjects\": [],\"reportServiceObjects\": [],\"reportUserObjects\": []," + - "\"deviceType\": {\"id\": 0,\"name\": \"\",\"version\": \"\",\"manufacturer\": \"\",\"isPureRoutingDevice\": false,\"isManagement\": false}," + - "\"import\": {\"aggregate\": {\"max\": {\"id\": null}}},\"RelevantImportId\": null,\"Ignore\": false,\"AwaitDevice\": false,\"Delete\": false,\"ActionId\": 0,\"ReportedRuleIds\": [],\"ReportedNetworkServiceIds\": [],\"objects_aggregate\": {\"aggregate\": {\"count\": 0}}," + - "\"services_aggregate\": {\"aggregate\": {\"count\": 0}},\"usrs_aggregate\": {\"aggregate\": {\"count\": 0}},\"rules_aggregate\": {\"aggregate\": {\"count\": 0}}}," + - "\"local_rulebase_name\": null,\"global_rulebase_name\": null,\"package_name\": null,\"importDisabled\": false,\"hideInUi\": false,\"comment\": null,\"rules\": null," + - "\"changelog_rules\": [{\"import\": {\"time\": \"2023-04-05T12:00:00\"},\"change_action\": \"I\"," + - "\"old\": {\"rule_id\": 0,\"rule_uid\": \"\",\"mgm_id\": 0,\"rule_num_numeric\": 0,\"rule_name\": \"\",\"rule_comment\": \"\",\"rule_disabled\": false," + - "\"rule_services\": [],\"rule_svc_neg\": false,\"rule_svc\": \"\",\"rule_src_neg\": false,\"rule_src\": \"\",\"src_zone\": {\"zone_id\": 0,\"zone_name\": \"\"},\"rule_froms\": [],\"rule_dst_neg\": false,\"rule_dst\": \"\",\"dst_zone\": {\"zone_id\": 0,\"zone_name\": \"\"},\"rule_tos\": [],\"rule_action\": \"\",\"rule_track\": \"\",\"section_header\": \"\"," + - "\"rule_metadatum\": {\"rule_metadata_id\": 0,\"rule_created\": null,\"rule_last_modified\": null,\"rule_first_hit\": null,\"rule_last_hit\": null,\"rule_last_certified\": null,\"rule_last_certifier_dn\": \"\",\"rule_to_be_removed\": false,\"rule_decert_date\": null,\"rule_recertification_comment\": \"\",\"recertification\": [],\"recert_history\": [],\"NextRecert\": \"0001-01-01T00:00:00\",\"LastCertifierName\": \"\",\"Recert\": false,\"Style\": \"\"}," + - "\"translate\": {\"rule_svc_neg\": false,\"rule_svc\": \"\",\"rule_services\": [],\"rule_src_neg\": false,\"rule_src\": \"\",\"rule_froms\": [],\"rule_dst_neg\": false,\"rule_dst\": \"\",\"rule_tos\": []}," + - "\"owner_name\": \"\",\"owner_id\": null,\"matches\": \"\",\"dev_id\": 0,\"DisplayOrderNumber\": 0,\"Certified\": false,\"DeviceName\": \"\"},\"new\": {\"rule_id\": 0,\"rule_uid\": \"uid1\",\"mgm_id\": 0,\"rule_num_numeric\": 0,\"rule_name\": \"TestRule1\",\"rule_comment\": \"comment1\",\"rule_disabled\": false," + - "\"rule_services\": [{\"service\": {\"svc_id\": 1,\"svc_name\": \"TestService1\",\"svc_uid\": \"\",\"svc_port\": 443,\"svc_port_end\": 443,\"svc_source_port\": null,\"svc_source_port_end\": null,\"svc_code\": \"\",\"svc_timeout\": null,\"svc_typ_id\": null,\"active\": false,\"svc_create\": 0,\"svc_create_time\": {\"time\": \"0001-01-01T00:00:00\"},\"svc_last_seen\": 0,\"service_type\": {\"name\": \"\"},\"svc_comment\": \"\",\"svc_color_id\": null,\"ip_proto_id\": null,\"protocol_name\": {\"id\": 0,\"name\": \"TCP\"},\"svc_member_names\": \"\",\"svc_member_refs\": \"\",\"svcgrps\": [],\"svcgrp_flats\": []}}]," + - "\"rule_svc_neg\": false,\"rule_svc\": \"\",\"rule_src_neg\": false,\"rule_src\": \"\",\"src_zone\": {\"zone_id\": 0,\"zone_name\": \"srczn\"}," + - "\"rule_froms\": [{\"object\": {\"obj_id\": 1,\"obj_name\": \"TestIp1\",\"obj_ip\": \"1.2.3.4/32\",\"obj_ip_end\": \"\",\"obj_uid\": \"\",\"zone\": {\"zone_id\": 0,\"zone_name\": \"\"},\"active\": false,\"obj_create\": 0,\"obj_create_time\": {\"time\": \"0001-01-01T00:00:00\"},\"obj_last_seen\": 0,\"type\": {\"name\": \"network\"},\"obj_comment\": \"\",\"obj_member_names\": \"\",\"obj_member_refs\": \"\",\"objgrps\": [],\"objgrp_flats\": []}," + - "\"usr\": {\"user_id\": 0,\"user_uid\": \"\",\"user_name\": \"\",\"user_comment\": \"\",\"user_lastname\": \"\",\"user_firstname\": \"\",\"usr_typ_id\": 0,\"type\": {\"usr_typ_name\": \"\"},\"user_create\": 0,\"user_create_time\": {\"time\": \"0001-01-01T00:00:00\"},\"user_last_seen\": 0,\"user_member_names\": \"\",\"user_member_refs\": \"\",\"usergrps\": [],\"usergrp_flats\": []}}," + - "{\"object\": {\"obj_id\": 2,\"obj_name\": \"TestIp2\",\"obj_ip\": \"127.0.0.1/32\",\"obj_ip_end\": \"\",\"obj_uid\": \"\",\"zone\": {\"zone_id\": 0,\"zone_name\": \"\"},\"active\": false,\"obj_create\": 0,\"obj_create_time\": {\"time\": \"0001-01-01T00:00:00\"},\"obj_last_seen\": 0,\"type\": {\"name\": \"network\"},\"obj_comment\": \"\",\"obj_member_names\": \"\",\"obj_member_refs\": \"\",\"objgrps\": [],\"objgrp_flats\": []}," + - "\"usr\": {\"user_id\": 0,\"user_uid\": \"\",\"user_name\": \"\",\"user_comment\": \"\",\"user_lastname\": \"\",\"user_firstname\": \"\",\"usr_typ_id\": 0,\"type\": {\"usr_typ_name\": \"\"},\"user_create\": 0,\"user_create_time\": {\"time\": \"0001-01-01T00:00:00\"},\"user_last_seen\": 0,\"user_member_names\": \"\",\"user_member_refs\": \"\",\"usergrps\": [],\"usergrp_flats\": []}}]," + - "\"rule_dst_neg\": false,\"rule_dst\": \"\",\"dst_zone\": {\"zone_id\": 0,\"zone_name\": \"dstzn\"},\"rule_tos\": [{\"object\": {\"obj_id\": 3,\"obj_name\": \"TestIpRange\",\"obj_ip\": \"1.2.3.4/32\",\"obj_ip_end\": \"1.2.3.5/32\",\"obj_uid\": \"\",\"zone\": {\"zone_id\": 0,\"zone_name\": \"\"},\"active\": false,\"obj_create\": 0,\"obj_create_time\": {\"time\": \"0001-01-01T00:00:00\"},\"obj_last_seen\": 0,\"type\": {\"name\": \"ip_range\"},\"obj_comment\": \"\",\"obj_member_names\": \"\",\"obj_member_refs\": \"\",\"objgrps\": [],\"objgrp_flats\": []}," + - "\"usr\": {\"user_id\": 0,\"user_uid\": \"\",\"user_name\": \"\",\"user_comment\": \"\",\"user_lastname\": \"\",\"user_firstname\": \"\",\"usr_typ_id\": 0,\"type\": {\"usr_typ_name\": \"\"},\"user_create\": 0,\"user_create_time\": {\"time\": \"0001-01-01T00:00:00\"},\"user_last_seen\": 0,\"user_member_names\": \"\",\"user_member_refs\": \"\",\"usergrps\": [],\"usergrp_flats\": []}}]," + - "\"rule_action\": \"accept\",\"rule_track\": \"none\",\"section_header\": \"\",\"rule_metadatum\": {\"rule_metadata_id\": 0,\"rule_created\": null,\"rule_last_modified\": null,\"rule_first_hit\": null,\"rule_last_hit\": \"2022-04-19T00:00:00\",\"rule_last_certified\": null,\"rule_last_certifier_dn\": \"\",\"rule_to_be_removed\": false,\"rule_decert_date\": null,\"rule_recertification_comment\": \"\",\"recertification\": [],\"recert_history\": [],\"NextRecert\": \"0001-01-01T00:00:00\",\"LastCertifierName\": \"\",\"Recert\": false,\"Style\": \"\"}," + - "\"translate\": {\"rule_svc_neg\": false,\"rule_svc\": \"\",\"rule_services\": [],\"rule_src_neg\": false,\"rule_src\": \"\",\"rule_froms\": [],\"rule_dst_neg\": false,\"rule_dst\": \"\",\"rule_tos\": []}," + - "\"owner_name\": \"\",\"owner_id\": null,\"matches\": \"\",\"dev_id\": 0,\"DisplayOrderNumber\": 1,\"Certified\": false,\"DeviceName\": \"\"},\"DeviceName\": \"\"}," + - "{\"import\": {\"time\": \"2023-04-05T12:00:00\"},\"change_action\": \"C\",\"old\": {\"rule_id\": 0,\"rule_uid\": \"uid1\",\"mgm_id\": 0,\"rule_num_numeric\": 0,\"rule_name\": \"TestRule1\",\"rule_comment\": \"comment1\",\"rule_disabled\": false," + - "\"rule_services\": [{\"service\": {\"svc_id\": 1,\"svc_name\": \"TestService1\",\"svc_uid\": \"\",\"svc_port\": 443,\"svc_port_end\": 443,\"svc_source_port\": null,\"svc_source_port_end\": null,\"svc_code\": \"\",\"svc_timeout\": null,\"svc_typ_id\": null,\"active\": false,\"svc_create\": 0,\"svc_create_time\": {\"time\": \"0001-01-01T00:00:00\"},\"svc_last_seen\": 0,\"service_type\": {\"name\": \"\"},\"svc_comment\": \"\",\"svc_color_id\": null,\"ip_proto_id\": null,\"protocol_name\": {\"id\": 0,\"name\": \"TCP\"},\"svc_member_names\": \"\",\"svc_member_refs\": \"\",\"svcgrps\": [],\"svcgrp_flats\": []}}]," + - "\"rule_svc_neg\": false,\"rule_svc\": \"\",\"rule_src_neg\": false,\"rule_src\": \"\",\"src_zone\": {\"zone_id\": 0,\"zone_name\": \"srczn\"}," + - "\"rule_froms\": [{\"object\": {\"obj_id\": 1,\"obj_name\": \"TestIp1\",\"obj_ip\": \"1.2.3.4/32\",\"obj_ip_end\": \"\",\"obj_uid\": \"\",\"zone\": {\"zone_id\": 0,\"zone_name\": \"\"},\"active\": false,\"obj_create\": 0,\"obj_create_time\": {\"time\": \"0001-01-01T00:00:00\"},\"obj_last_seen\": 0,\"type\": {\"name\": \"network\"},\"obj_comment\": \"\",\"obj_member_names\": \"\",\"obj_member_refs\": \"\",\"objgrps\": [],\"objgrp_flats\": []}," + - "\"usr\": {\"user_id\": 0,\"user_uid\": \"\",\"user_name\": \"\",\"user_comment\": \"\",\"user_lastname\": \"\",\"user_firstname\": \"\",\"usr_typ_id\": 0,\"type\": {\"usr_typ_name\": \"\"},\"user_create\": 0,\"user_create_time\": {\"time\": \"0001-01-01T00:00:00\"},\"user_last_seen\": 0,\"user_member_names\": \"\",\"user_member_refs\": \"\",\"usergrps\": [],\"usergrp_flats\": []}},{\"object\": {\"obj_id\": 2,\"obj_name\": \"TestIp2\",\"obj_ip\": \"127.0.0.1/32\",\"obj_ip_end\": \"\",\"obj_uid\": \"\",\"zone\": {\"zone_id\": 0,\"zone_name\": \"\"},\"active\": false,\"obj_create\": 0,\"obj_create_time\": {\"time\": \"0001-01-01T00:00:00\"},\"obj_last_seen\": 0,\"type\": {\"name\": \"network\"},\"obj_comment\": \"\",\"obj_member_names\": \"\",\"obj_member_refs\": \"\",\"objgrps\": [],\"objgrp_flats\": []}," + - "\"usr\": {\"user_id\": 0,\"user_uid\": \"\",\"user_name\": \"\",\"user_comment\": \"\",\"user_lastname\": \"\",\"user_firstname\": \"\",\"usr_typ_id\": 0,\"type\": {\"usr_typ_name\": \"\"},\"user_create\": 0,\"user_create_time\": {\"time\": \"0001-01-01T00:00:00\"},\"user_last_seen\": 0,\"user_member_names\": \"\",\"user_member_refs\": \"\",\"usergrps\": [],\"usergrp_flats\": []}}]," + - "\"rule_dst_neg\": false,\"rule_dst\": \"\",\"dst_zone\": {\"zone_id\": 0,\"zone_name\": \"dstzn\"},\"rule_tos\": [{\"object\": {\"obj_id\": 3,\"obj_name\": \"TestIpRange\",\"obj_ip\": \"1.2.3.4/32\",\"obj_ip_end\": \"1.2.3.5/32\",\"obj_uid\": \"\",\"zone\": {\"zone_id\": 0,\"zone_name\": \"\"},\"active\": false,\"obj_create\": 0,\"obj_create_time\": {\"time\": \"0001-01-01T00:00:00\"},\"obj_last_seen\": 0,\"type\": {\"name\": \"ip_range\"},\"obj_comment\": \"\",\"obj_member_names\": \"\",\"obj_member_refs\": \"\",\"objgrps\": [],\"objgrp_flats\": []}," + - "\"usr\": {\"user_id\": 0,\"user_uid\": \"\",\"user_name\": \"\",\"user_comment\": \"\",\"user_lastname\": \"\",\"user_firstname\": \"\",\"usr_typ_id\": 0,\"type\": {\"usr_typ_name\": \"\"},\"user_create\": 0,\"user_create_time\": {\"time\": \"0001-01-01T00:00:00\"},\"user_last_seen\": 0,\"user_member_names\": \"\",\"user_member_refs\": \"\",\"usergrps\": [],\"usergrp_flats\": []}}]," + - "\"rule_action\": \"accept\",\"rule_track\": \"none\",\"section_header\": \"\",\"rule_metadatum\": {\"rule_metadata_id\": 0,\"rule_created\": null,\"rule_last_modified\": null,\"rule_first_hit\": null,\"rule_last_hit\": \"2022-04-19T00:00:00\",\"rule_last_certified\": null,\"rule_last_certifier_dn\": \"\",\"rule_to_be_removed\": false,\"rule_decert_date\": null,\"rule_recertification_comment\": \"\",\"recertification\": [],\"recert_history\": [],\"NextRecert\": \"0001-01-01T00:00:00\",\"LastCertifierName\": \"\",\"Recert\": false,\"Style\": \"\"}," + - "\"translate\": {\"rule_svc_neg\": false,\"rule_svc\": \"\",\"rule_services\": [],\"rule_src_neg\": false,\"rule_src\": \"\",\"rule_froms\": [],\"rule_dst_neg\": false,\"rule_dst\": \"\",\"rule_tos\": []}," + - "\"owner_name\": \"\",\"owner_id\": null,\"matches\": \"\",\"dev_id\": 0,\"DisplayOrderNumber\": 1,\"Certified\": false,\"DeviceName\": \"\"},\"new\": {\"rule_id\": 0,\"rule_uid\": \"\",\"mgm_id\": 0,\"rule_num_numeric\": 0,\"rule_name\": \"TestRule1\",\"rule_comment\": \"new comment\",\"rule_disabled\": false," + - "\"rule_services\": [{\"service\": {\"svc_id\": 1,\"svc_name\": \"TestService1\",\"svc_uid\": \"\",\"svc_port\": 443,\"svc_port_end\": 443,\"svc_source_port\": null,\"svc_source_port_end\": null,\"svc_code\": \"\",\"svc_timeout\": null,\"svc_typ_id\": null,\"active\": false,\"svc_create\": 0,\"svc_create_time\": {\"time\": \"0001-01-01T00:00:00\"},\"svc_last_seen\": 0,\"service_type\": {\"name\": \"\"},\"svc_comment\": \"\",\"svc_color_id\": null,\"ip_proto_id\": null,\"protocol_name\": {\"id\": 0,\"name\": \"TCP\"},\"svc_member_names\": \"\",\"svc_member_refs\": \"\",\"svcgrps\": [],\"svcgrp_flats\": []}}]," + - "\"rule_svc_neg\": true,\"rule_svc\": \"\",\"rule_src_neg\": false,\"rule_src\": \"\",\"src_zone\": {\"zone_id\": 0,\"zone_name\": \"srczn\"},\"rule_froms\": [{\"object\": {\"obj_id\": 5,\"obj_name\": \"TestIp1Changed\",\"obj_ip\": \"2.3.4.5/32\",\"obj_ip_end\": \"\",\"obj_uid\": \"\",\"zone\": {\"zone_id\": 0,\"zone_name\": \"\"},\"active\": false,\"obj_create\": 0,\"obj_create_time\": {\"time\": \"0001-01-01T00:00:00\"},\"obj_last_seen\": 0,\"type\": {\"name\": \"network\"},\"obj_comment\": \"\",\"obj_member_names\": \"\",\"obj_member_refs\": \"\",\"objgrps\": [],\"objgrp_flats\": []}," + - "\"usr\": {\"user_id\": 0,\"user_uid\": \"\",\"user_name\": \"\",\"user_comment\": \"\",\"user_lastname\": \"\",\"user_firstname\": \"\",\"usr_typ_id\": 0,\"type\": {\"usr_typ_name\": \"\"},\"user_create\": 0,\"user_create_time\": {\"time\": \"0001-01-01T00:00:00\"},\"user_last_seen\": 0,\"user_member_names\": \"\",\"user_member_refs\": \"\",\"usergrps\": [],\"usergrp_flats\": []}},{\"object\": {\"obj_id\": 2,\"obj_name\": \"TestIp2\",\"obj_ip\": \"127.0.0.1/32\",\"obj_ip_end\": \"\",\"obj_uid\": \"\",\"zone\": {\"zone_id\": 0,\"zone_name\": \"\"},\"active\": false,\"obj_create\": 0,\"obj_create_time\": {\"time\": \"0001-01-01T00:00:00\"},\"obj_last_seen\": 0,\"type\": {\"name\": \"network\"},\"obj_comment\": \"\",\"obj_member_names\": \"\",\"obj_member_refs\": \"\",\"objgrps\": [],\"objgrp_flats\": []}," + - "\"usr\": {\"user_id\": 0,\"user_uid\": \"\",\"user_name\": \"\",\"user_comment\": \"\",\"user_lastname\": \"\",\"user_firstname\": \"\",\"usr_typ_id\": 0,\"type\": {\"usr_typ_name\": \"\"},\"user_create\": 0,\"user_create_time\": {\"time\": \"0001-01-01T00:00:00\"},\"user_last_seen\": 0,\"user_member_names\": \"\",\"user_member_refs\": \"\",\"usergrps\": [],\"usergrp_flats\": []}}]," + - "\"rule_dst_neg\": false,\"rule_dst\": \"\",\"dst_zone\": {\"zone_id\": 0,\"zone_name\": \"dstzn\"},\"rule_tos\": [{\"object\": {\"obj_id\": 3,\"obj_name\": \"TestIpRange\",\"obj_ip\": \"1.2.3.4/32\",\"obj_ip_end\": \"1.2.3.5/32\",\"obj_uid\": \"\",\"zone\": {\"zone_id\": 0,\"zone_name\": \"\"},\"active\": false,\"obj_create\": 0,\"obj_create_time\": {\"time\": \"0001-01-01T00:00:00\"},\"obj_last_seen\": 0,\"type\": {\"name\": \"ip_range\"},\"obj_comment\": \"\",\"obj_member_names\": \"\",\"obj_member_refs\": \"\",\"objgrps\": [],\"objgrp_flats\": []}," + - "\"usr\": {\"user_id\": 0,\"user_uid\": \"\",\"user_name\": \"\",\"user_comment\": \"\",\"user_lastname\": \"\",\"user_firstname\": \"\",\"usr_typ_id\": 0,\"type\": {\"usr_typ_name\": \"\"},\"user_create\": 0,\"user_create_time\": {\"time\": \"0001-01-01T00:00:00\"},\"user_last_seen\": 0,\"user_member_names\": \"\",\"user_member_refs\": \"\",\"usergrps\": [],\"usergrp_flats\": []}},{\"object\": {\"obj_id\": 4,\"obj_name\": \"TestIpNew\",\"obj_ip\": \"10.0.6.1/32\",\"obj_ip_end\": \"\",\"obj_uid\": \"\",\"zone\": {\"zone_id\": 0,\"zone_name\": \"\"},\"active\": false,\"obj_create\": 0,\"obj_create_time\": {\"time\": \"0001-01-01T00:00:00\"},\"obj_last_seen\": 0,\"type\": {\"name\": \"network\"},\"obj_comment\": \"\",\"obj_member_names\": \"\",\"obj_member_refs\": \"\",\"objgrps\": [],\"objgrp_flats\": []}," + - "\"usr\": {\"user_id\": 0,\"user_uid\": \"\",\"user_name\": \"\",\"user_comment\": \"\",\"user_lastname\": \"\",\"user_firstname\": \"\",\"usr_typ_id\": 0,\"type\": {\"usr_typ_name\": \"\"},\"user_create\": 0,\"user_create_time\": {\"time\": \"0001-01-01T00:00:00\"},\"user_last_seen\": 0,\"user_member_names\": \"\",\"user_member_refs\": \"\",\"usergrps\": [],\"usergrp_flats\": []}}]," + - "\"rule_action\": \"accept\",\"rule_track\": \"none\",\"section_header\": \"\",\"rule_metadatum\": {\"rule_metadata_id\": 0,\"rule_created\": null,\"rule_last_modified\": null,\"rule_first_hit\": null,\"rule_last_hit\": \"2022-04-19T00:00:00\",\"rule_last_certified\": null,\"rule_last_certifier_dn\": \"\",\"rule_to_be_removed\": false,\"rule_decert_date\": null,\"rule_recertification_comment\": \"\",\"recertification\": [],\"recert_history\": [],\"NextRecert\": \"0001-01-01T00:00:00\",\"LastCertifierName\": \"\",\"Recert\": false,\"Style\": \"\"}," + - "\"translate\": {\"rule_svc_neg\": false,\"rule_svc\": \"\",\"rule_services\": [],\"rule_src_neg\": false,\"rule_src\": \"\",\"rule_froms\": [],\"rule_dst_neg\": false,\"rule_dst\": \"\",\"rule_tos\": []}," + - "\"owner_name\": \"\",\"owner_id\": null,\"matches\": \"\",\"dev_id\": 0,\"DisplayOrderNumber\": 1,\"Certified\": false,\"DeviceName\": \"\"},\"DeviceName\": \"\"}," + - "{\"import\": {\"time\": \"2023-04-05T12:00:00\"},\"change_action\": \"C\",\"old\": {\"rule_id\": 0,\"rule_uid\": \"uid2:123\",\"mgm_id\": 0,\"rule_num_numeric\": 0,\"rule_name\": \"TestRule2\",\"rule_comment\": \"comment2\",\"rule_disabled\": false," + - "\"rule_services\": [{\"service\": {\"svc_id\": 2,\"svc_name\": \"TestService2\",\"svc_uid\": \"\",\"svc_port\": 6666,\"svc_port_end\": 7777,\"svc_source_port\": null,\"svc_source_port_end\": null,\"svc_code\": \"\",\"svc_timeout\": null,\"svc_typ_id\": null,\"active\": false,\"svc_create\": 0,\"svc_create_time\": {\"time\": \"0001-01-01T00:00:00\"},\"svc_last_seen\": 0,\"service_type\": {\"name\": \"\"},\"svc_comment\": \"\",\"svc_color_id\": null,\"ip_proto_id\": null,\"protocol_name\": {\"id\": 0,\"name\": \"UDP\"},\"svc_member_names\": \"\",\"svc_member_refs\": \"\",\"svcgrps\": [],\"svcgrp_flats\": []}}]," + - "\"rule_svc_neg\": true,\"rule_svc\": \"\",\"rule_src_neg\": true,\"rule_src\": \"\",\"src_zone\": {\"zone_id\": 0,\"zone_name\": \"\"}," + - "\"rule_froms\": [{\"object\": {\"obj_id\": 1,\"obj_name\": \"TestIp1\",\"obj_ip\": \"1.2.3.4/32\",\"obj_ip_end\": \"\",\"obj_uid\": \"\",\"zone\": {\"zone_id\": 0,\"zone_name\": \"\"},\"active\": false,\"obj_create\": 0,\"obj_create_time\": {\"time\": \"0001-01-01T00:00:00\"},\"obj_last_seen\": 0,\"type\": {\"name\": \"network\"},\"obj_comment\": \"\",\"obj_member_names\": \"\",\"obj_member_refs\": \"\",\"objgrps\": [],\"objgrp_flats\": []}," + - "\"usr\": {\"user_id\": 1,\"user_uid\": \"\",\"user_name\": \"TestUser1\",\"user_comment\": \"\",\"user_lastname\": \"\",\"user_firstname\": \"\",\"usr_typ_id\": 0,\"type\": {\"usr_typ_name\": \"\"},\"user_create\": 0,\"user_create_time\": {\"time\": \"0001-01-01T00:00:00\"},\"user_last_seen\": 0,\"user_member_names\": \"\",\"user_member_refs\": \"\",\"usergrps\": [],\"usergrp_flats\": []}},{\"object\": {\"obj_id\": 2,\"obj_name\": \"TestIp2\",\"obj_ip\": \"127.0.0.1/32\",\"obj_ip_end\": \"\",\"obj_uid\": \"\",\"zone\": {\"zone_id\": 0,\"zone_name\": \"\"},\"active\": false,\"obj_create\": 0,\"obj_create_time\": {\"time\": \"0001-01-01T00:00:00\"},\"obj_last_seen\": 0,\"type\": {\"name\": \"network\"},\"obj_comment\": \"\",\"obj_member_names\": \"\",\"obj_member_refs\": \"\",\"objgrps\": [],\"objgrp_flats\": []}," + - "\"usr\": {\"user_id\": 1,\"user_uid\": \"\",\"user_name\": \"TestUser1\",\"user_comment\": \"\",\"user_lastname\": \"\",\"user_firstname\": \"\",\"usr_typ_id\": 0,\"type\": {\"usr_typ_name\": \"\"},\"user_create\": 0,\"user_create_time\": {\"time\": \"0001-01-01T00:00:00\"},\"user_last_seen\": 0,\"user_member_names\": \"\",\"user_member_refs\": \"\",\"usergrps\": [],\"usergrp_flats\": []}}]," + - "\"rule_dst_neg\": true,\"rule_dst\": \"\",\"dst_zone\": {\"zone_id\": 0,\"zone_name\": \"\"},\"rule_tos\": [{\"object\": {\"obj_id\": 3,\"obj_name\": \"TestIpRange\",\"obj_ip\": \"1.2.3.4/32\",\"obj_ip_end\": \"1.2.3.5/32\",\"obj_uid\": \"\",\"zone\": {\"zone_id\": 0,\"zone_name\": \"\"},\"active\": false,\"obj_create\": 0,\"obj_create_time\": {\"time\": \"0001-01-01T00:00:00\"},\"obj_last_seen\": 0,\"type\": {\"name\": \"ip_range\"},\"obj_comment\": \"\",\"obj_member_names\": \"\",\"obj_member_refs\": \"\",\"objgrps\": [],\"objgrp_flats\": []}," + - "\"usr\": {\"user_id\": 2,\"user_uid\": \"\",\"user_name\": \"TestUser2\",\"user_comment\": \"\",\"user_lastname\": \"\",\"user_firstname\": \"\",\"usr_typ_id\": 0,\"type\": {\"usr_typ_name\": \"group\"},\"user_create\": 0,\"user_create_time\": {\"time\": \"0001-01-01T00:00:00\"},\"user_last_seen\": 0,\"user_member_names\": \"\",\"user_member_refs\": \"\",\"usergrps\": [],\"usergrp_flats\": []}}]," + - "\"rule_action\": \"deny\",\"rule_track\": \"none\",\"section_header\": \"\",\"rule_metadatum\": {\"rule_metadata_id\": 0,\"rule_created\": null,\"rule_last_modified\": null,\"rule_first_hit\": null,\"rule_last_hit\": null,\"rule_last_certified\": null,\"rule_last_certifier_dn\": \"\",\"rule_to_be_removed\": false,\"rule_decert_date\": null,\"rule_recertification_comment\": \"\",\"recertification\": [],\"recert_history\": [],\"NextRecert\": \"0001-01-01T00:00:00\",\"LastCertifierName\": \"\",\"Recert\": false,\"Style\": \"\"}," + - "\"translate\": {\"rule_svc_neg\": false,\"rule_svc\": \"\",\"rule_services\": [],\"rule_src_neg\": false,\"rule_src\": \"\",\"rule_froms\": [],\"rule_dst_neg\": false,\"rule_dst\": \"\",\"rule_tos\": []}," + - "\"owner_name\": \"\",\"owner_id\": null,\"matches\": \"\",\"dev_id\": 0,\"DisplayOrderNumber\": 2,\"Certified\": false,\"DeviceName\": \"\"},\"new\": {\"rule_id\": 0,\"rule_uid\": \"uid2:123\",\"mgm_id\": 0,\"rule_num_numeric\": 0,\"rule_name\": \"TestRule2\",\"rule_comment\": \"comment2\",\"rule_disabled\": true," + - "\"rule_services\": [{\"service\": {\"svc_id\": 2,\"svc_name\": \"TestService2\",\"svc_uid\": \"\",\"svc_port\": 6666,\"svc_port_end\": 7777,\"svc_source_port\": null,\"svc_source_port_end\": null,\"svc_code\": \"\",\"svc_timeout\": null,\"svc_typ_id\": null,\"active\": false,\"svc_create\": 0,\"svc_create_time\": {\"time\": \"0001-01-01T00:00:00\"},\"svc_last_seen\": 0,\"service_type\": {\"name\": \"\"},\"svc_comment\": \"\",\"svc_color_id\": null,\"ip_proto_id\": null,\"protocol_name\": {\"id\": 0,\"name\": \"UDP\"},\"svc_member_names\": \"\",\"svc_member_refs\": \"\",\"svcgrps\": [],\"svcgrp_flats\": []}}]," + - "\"rule_svc_neg\": false,\"rule_svc\": \"\",\"rule_src_neg\": true,\"rule_src\": \"\",\"src_zone\": {\"zone_id\": 0,\"zone_name\": \"\"}," + - "\"rule_froms\": [{\"object\": {\"obj_id\": 1,\"obj_name\": \"TestIp1\",\"obj_ip\": \"1.2.3.4/32\",\"obj_ip_end\": \"\",\"obj_uid\": \"\",\"zone\": {\"zone_id\": 0,\"zone_name\": \"\"},\"active\": false,\"obj_create\": 0,\"obj_create_time\": {\"time\": \"0001-01-01T00:00:00\"},\"obj_last_seen\": 0,\"type\": {\"name\": \"network\"},\"obj_comment\": \"\",\"obj_member_names\": \"\",\"obj_member_refs\": \"\",\"objgrps\": [],\"objgrp_flats\": []}," + - "\"usr\": {\"user_id\": 1,\"user_uid\": \"\",\"user_name\": \"TestUser1\",\"user_comment\": \"\",\"user_lastname\": \"\",\"user_firstname\": \"\",\"usr_typ_id\": 0,\"type\": {\"usr_typ_name\": \"\"},\"user_create\": 0,\"user_create_time\": {\"time\": \"0001-01-01T00:00:00\"},\"user_last_seen\": 0,\"user_member_names\": \"\",\"user_member_refs\": \"\",\"usergrps\": [],\"usergrp_flats\": []}},{\"object\": {\"obj_id\": 2,\"obj_name\": \"TestIp2\",\"obj_ip\": \"127.0.0.1/32\",\"obj_ip_end\": \"\",\"obj_uid\": \"\",\"zone\": {\"zone_id\": 0,\"zone_name\": \"\"},\"active\": false,\"obj_create\": 0,\"obj_create_time\": {\"time\": \"0001-01-01T00:00:00\"},\"obj_last_seen\": 0,\"type\": {\"name\": \"network\"},\"obj_comment\": \"\",\"obj_member_names\": \"\",\"obj_member_refs\": \"\",\"objgrps\": [],\"objgrp_flats\": []}," + - "\"usr\": {\"user_id\": 1,\"user_uid\": \"\",\"user_name\": \"TestUser1\",\"user_comment\": \"\",\"user_lastname\": \"\",\"user_firstname\": \"\",\"usr_typ_id\": 0,\"type\": {\"usr_typ_name\": \"\"},\"user_create\": 0,\"user_create_time\": {\"time\": \"0001-01-01T00:00:00\"},\"user_last_seen\": 0,\"user_member_names\": \"\",\"user_member_refs\": \"\",\"usergrps\": [],\"usergrp_flats\": []}}]," + - "\"rule_dst_neg\": false,\"rule_dst\": \"\",\"dst_zone\": {\"zone_id\": 0,\"zone_name\": \"\"},\"rule_tos\": [{\"object\": {\"obj_id\": 3,\"obj_name\": \"TestIpRange\",\"obj_ip\": \"1.2.3.4/32\",\"obj_ip_end\": \"1.2.3.5/32\",\"obj_uid\": \"\",\"zone\": {\"zone_id\": 0,\"zone_name\": \"\"},\"active\": false,\"obj_create\": 0,\"obj_create_time\": {\"time\": \"0001-01-01T00:00:00\"},\"obj_last_seen\": 0,\"type\": {\"name\": \"ip_range\"},\"obj_comment\": \"\",\"obj_member_names\": \"\",\"obj_member_refs\": \"\",\"objgrps\": [],\"objgrp_flats\": []}," + - "\"usr\": {\"user_id\": 2,\"user_uid\": \"\",\"user_name\": \"TestUser2\",\"user_comment\": \"\",\"user_lastname\": \"\",\"user_firstname\": \"\",\"usr_typ_id\": 0,\"type\": {\"usr_typ_name\": \"group\"},\"user_create\": 0,\"user_create_time\": {\"time\": \"0001-01-01T00:00:00\"},\"user_last_seen\": 0,\"user_member_names\": \"\",\"user_member_refs\": \"\",\"usergrps\": [],\"usergrp_flats\": []}}]," + - "\"rule_action\": \"deny\",\"rule_track\": \"none\",\"section_header\": \"\",\"rule_metadatum\": {\"rule_metadata_id\": 0,\"rule_created\": null,\"rule_last_modified\": null,\"rule_first_hit\": null,\"rule_last_hit\": null,\"rule_last_certified\": null,\"rule_last_certifier_dn\": \"\",\"rule_to_be_removed\": false,\"rule_decert_date\": null,\"rule_recertification_comment\": \"\",\"recertification\": [],\"recert_history\": [],\"NextRecert\": \"0001-01-01T00:00:00\",\"LastCertifierName\": \"\",\"Recert\": false,\"Style\": \"\"}," + - "\"translate\": {\"rule_svc_neg\": false,\"rule_svc\": \"\",\"rule_services\": [],\"rule_src_neg\": false,\"rule_src\": \"\",\"rule_froms\": [],\"rule_dst_neg\": false,\"rule_dst\": \"\",\"rule_tos\": []}," + - "\"owner_name\": \"\",\"owner_id\": null,\"matches\": \"\",\"dev_id\": 0,\"DisplayOrderNumber\": 2,\"Certified\": false,\"DeviceName\": \"\"},\"DeviceName\": \"\"}," + - "{\"import\": {\"time\": \"2023-04-05T12:00:00\"},\"change_action\": \"D\",\"old\": {\"rule_id\": 0,\"rule_uid\": \"uid2:123\",\"mgm_id\": 0,\"rule_num_numeric\": 0,\"rule_name\": \"TestRule2\",\"rule_comment\": \"comment2\",\"rule_disabled\": false," + - "\"rule_services\": [{\"service\": {\"svc_id\": 2,\"svc_name\": \"TestService2\",\"svc_uid\": \"\",\"svc_port\": 6666,\"svc_port_end\": 7777,\"svc_source_port\": null,\"svc_source_port_end\": null,\"svc_code\": \"\",\"svc_timeout\": null,\"svc_typ_id\": null,\"active\": false,\"svc_create\": 0,\"svc_create_time\": {\"time\": \"0001-01-01T00:00:00\"},\"svc_last_seen\": 0,\"service_type\": {\"name\": \"\"},\"svc_comment\": \"\",\"svc_color_id\": null,\"ip_proto_id\": null,\"protocol_name\": {\"id\": 0,\"name\": \"UDP\"},\"svc_member_names\": \"\",\"svc_member_refs\": \"\",\"svcgrps\": [],\"svcgrp_flats\": []}}]," + - "\"rule_svc_neg\": true,\"rule_svc\": \"\",\"rule_src_neg\": true,\"rule_src\": \"\",\"src_zone\": {\"zone_id\": 0,\"zone_name\": \"\"}," + - "\"rule_froms\": [{\"object\": {\"obj_id\": 1,\"obj_name\": \"TestIp1\",\"obj_ip\": \"1.2.3.4/32\",\"obj_ip_end\": \"\",\"obj_uid\": \"\",\"zone\": {\"zone_id\": 0,\"zone_name\": \"\"},\"active\": false,\"obj_create\": 0,\"obj_create_time\": {\"time\": \"0001-01-01T00:00:00\"},\"obj_last_seen\": 0,\"type\": {\"name\": \"network\"},\"obj_comment\": \"\",\"obj_member_names\": \"\",\"obj_member_refs\": \"\",\"objgrps\": [],\"objgrp_flats\": []}," + - "\"usr\": {\"user_id\": 1,\"user_uid\": \"\",\"user_name\": \"TestUser1\",\"user_comment\": \"\",\"user_lastname\": \"\",\"user_firstname\": \"\",\"usr_typ_id\": 0,\"type\": {\"usr_typ_name\": \"\"},\"user_create\": 0,\"user_create_time\": {\"time\": \"0001-01-01T00:00:00\"},\"user_last_seen\": 0,\"user_member_names\": \"\",\"user_member_refs\": \"\",\"usergrps\": [],\"usergrp_flats\": []}},{\"object\": {\"obj_id\": 2,\"obj_name\": \"TestIp2\",\"obj_ip\": \"127.0.0.1/32\",\"obj_ip_end\": \"\",\"obj_uid\": \"\",\"zone\": {\"zone_id\": 0,\"zone_name\": \"\"},\"active\": false,\"obj_create\": 0,\"obj_create_time\": {\"time\": \"0001-01-01T00:00:00\"},\"obj_last_seen\": 0,\"type\": {\"name\": \"network\"},\"obj_comment\": \"\",\"obj_member_names\": \"\",\"obj_member_refs\": \"\",\"objgrps\": [],\"objgrp_flats\": []}," + - "\"usr\": {\"user_id\": 1,\"user_uid\": \"\",\"user_name\": \"TestUser1\",\"user_comment\": \"\",\"user_lastname\": \"\",\"user_firstname\": \"\",\"usr_typ_id\": 0,\"type\": {\"usr_typ_name\": \"\"},\"user_create\": 0,\"user_create_time\": {\"time\": \"0001-01-01T00:00:00\"},\"user_last_seen\": 0,\"user_member_names\": \"\",\"user_member_refs\": \"\",\"usergrps\": [],\"usergrp_flats\": []}}]," + - "\"rule_dst_neg\": true,\"rule_dst\": \"\",\"dst_zone\": {\"zone_id\": 0,\"zone_name\": \"\"},\"rule_tos\": [{\"object\": {\"obj_id\": 3,\"obj_name\": \"TestIpRange\",\"obj_ip\": \"1.2.3.4/32\",\"obj_ip_end\": \"1.2.3.5/32\",\"obj_uid\": \"\",\"zone\": {\"zone_id\": 0,\"zone_name\": \"\"},\"active\": false,\"obj_create\": 0,\"obj_create_time\": {\"time\": \"0001-01-01T00:00:00\"},\"obj_last_seen\": 0,\"type\": {\"name\": \"ip_range\"},\"obj_comment\": \"\",\"obj_member_names\": \"\",\"obj_member_refs\": \"\",\"objgrps\": [],\"objgrp_flats\": []}," + - "\"usr\": {\"user_id\": 2,\"user_uid\": \"\",\"user_name\": \"TestUser2\",\"user_comment\": \"\",\"user_lastname\": \"\",\"user_firstname\": \"\",\"usr_typ_id\": 0,\"type\": {\"usr_typ_name\": \"group\"},\"user_create\": 0,\"user_create_time\": {\"time\": \"0001-01-01T00:00:00\"},\"user_last_seen\": 0,\"user_member_names\": \"\",\"user_member_refs\": \"\",\"usergrps\": [],\"usergrp_flats\": []}}]," + - "\"rule_action\": \"deny\",\"rule_track\": \"none\",\"section_header\": \"\",\"rule_metadatum\": {\"rule_metadata_id\": 0,\"rule_created\": null,\"rule_last_modified\": null,\"rule_first_hit\": null,\"rule_last_hit\": null,\"rule_last_certified\": null,\"rule_last_certifier_dn\": \"\",\"rule_to_be_removed\": false,\"rule_decert_date\": null,\"rule_recertification_comment\": \"\",\"recertification\": [],\"recert_history\": [],\"NextRecert\": \"0001-01-01T00:00:00\",\"LastCertifierName\": \"\",\"Recert\": false,\"Style\": \"\"}," + - "\"translate\": {\"rule_svc_neg\": false,\"rule_svc\": \"\",\"rule_services\": [],\"rule_src_neg\": false,\"rule_src\": \"\",\"rule_froms\": [],\"rule_dst_neg\": false,\"rule_dst\": \"\",\"rule_tos\": []}," + - "\"owner_name\": \"\",\"owner_id\": null,\"matches\": \"\",\"dev_id\": 0,\"DisplayOrderNumber\": 2,\"Certified\": false,\"DeviceName\": \"\"},\"new\": {\"rule_id\": 0,\"rule_uid\": \"\",\"mgm_id\": 0,\"rule_num_numeric\": 0,\"rule_name\": \"\",\"rule_comment\": \"\",\"rule_disabled\": false," + - "\"rule_services\": [],\"rule_svc_neg\": false,\"rule_svc\": \"\",\"rule_src_neg\": false,\"rule_src\": \"\",\"src_zone\": {\"zone_id\": 0,\"zone_name\": \"\"},\"rule_froms\": [],\"rule_dst_neg\": false,\"rule_dst\": \"\",\"dst_zone\": {\"zone_id\": 0,\"zone_name\": \"\"},\"rule_tos\": [],\"rule_action\": \"\",\"rule_track\": \"\",\"section_header\": \"\"," + - "\"rule_metadatum\": {\"rule_metadata_id\": 0,\"rule_created\": null,\"rule_last_modified\": null,\"rule_first_hit\": null,\"rule_last_hit\": null,\"rule_last_certified\": null,\"rule_last_certifier_dn\": \"\",\"rule_to_be_removed\": false,\"rule_decert_date\": null,\"rule_recertification_comment\": \"\",\"recertification\": [],\"recert_history\": [],\"NextRecert\": \"0001-01-01T00:00:00\",\"LastCertifierName\": \"\",\"Recert\": false,\"Style\": \"\"}," + - "\"translate\": {\"rule_svc_neg\": false,\"rule_svc\": \"\",\"rule_services\": [],\"rule_src_neg\": false,\"rule_src\": \"\",\"rule_froms\": [],\"rule_dst_neg\": false,\"rule_dst\": \"\",\"rule_tos\": []}," + - "\"owner_name\": \"\",\"owner_id\": null,\"matches\": \"\",\"dev_id\": 0,\"DisplayOrderNumber\": 0,\"Certified\": false,\"DeviceName\": \"\"},\"DeviceName\": \"\"}],\"rules_aggregate\": {\"aggregate\": {\"count\": 0}},\"Selected\": false,\"Relevant\": false,\"AwaitMgmt\": false,\"Delete\": false,\"ActionId\": 0}]," + - "\"networkObjects\": [],\"serviceObjects\": [],\"userObjects\": [],\"reportNetworkObjects\": [],\"reportServiceObjects\": [],\"reportUserObjects\": [],\"deviceType\": {\"id\": 0,\"name\": \"\",\"version\": \"\",\"manufacturer\": \"\",\"isPureRoutingDevice\": false,\"isManagement\": false}," + - "\"import\": {\"aggregate\": {\"max\": {\"id\": null}}},\"RelevantImportId\": null,\"Ignore\": false,\"AwaitDevice\": false,\"Delete\": false,\"ActionId\": 0,\"ReportedRuleIds\": [],\"ReportedNetworkServiceIds\": [],\"objects_aggregate\": {\"aggregate\": {\"count\": 0}},\"services_aggregate\": {\"aggregate\": {\"count\": 0}},\"usrs_aggregate\": {\"aggregate\": {\"count\": 0}},\"rules_aggregate\": {\"aggregate\": {\"count\": 0}}}]"; - Assert.AreEqual(expectedJsonResult, removeLinebreaks((removeGenDate(reportChanges.ExportToJson(), false, true)))); - } - - [Test] - public void ResolvedChangesGenerateJson() - { - Log.WriteInfo("Test Log", "starting resolved changes report json generation"); - ReportChanges reportChanges = new ReportChanges(query, userConfig, ReportType.ResolvedChanges); - reportChanges.Managements = ConstructChangeReport(true); - - string expectedJsonResult = - "{\"report type\": \"Changes Report (resolved)\",\"report generation date\": \"Z (UTC)\",\"device filter\": \"TestMgt [TestDev]\",\"other filters\": \"TestFilter\",\"report generator\": \"Firewall Orchestrator - https://fwo.cactus.de/en\",\"data protection level\": \"For internal use only\"," + - "\"managements\": [{\"TestMgt\": {\"gateways\": [{\"TestDev\": {\"rule changes\": [" + - "{\"change time\": \"05.04.2023 12:00:00\",\"change action\": \"Rule added\",\"name\": \"TestRule1\"," + - "\"source zone\": \"srczn\",\"source negated\": false,\"source\": [\"TestIp1 (1.2.3.4/32)\",\"TestIp2 (127.0.0.1/32)\"]," + - "\"destination zone\": \"dstzn\",\"destination negated\": false,\"destination\": [\"TestIpRange (1.2.3.4/32-1.2.3.5/32)\"]," + - "\"service negated\": false,\"service\": [\"TestService1 (443/TCP)\"],\"action\": \"accept\",\"tracking\": \"none\",\"disabled\": false,\"rule uid\": \"uid1\",\"comment\": \"comment1\"}," + - "{\"change time\": \"05.04.2023 12:00:00\",\"change action\": \"Rule modified\",\"name\": \"TestRule1\"," + - "\"source zone\": \"srczn\",\"source negated\": false,\"source\": [\"TestIp2 (127.0.0.1/32)\",\"deleted: TestIp1 (1.2.3.4/32)\",\"added: TestIp1Changed (2.3.4.5/32)\"]," + - "\"destination zone\": \"dstzn\",\"destination negated\": false,\"destination\": [\"TestIpRange (1.2.3.4/32-1.2.3.5/32)\",\"added: TestIpNew (10.0.6.1/32)\"]," + - "\"service negated\": \"deleted: false, added: true\",\"service\": [\"TestService1 (443/TCP)\"],\"action\": \"accept\",\"tracking\": \"none\",\"disabled\": false,\"rule uid\": \"deleted: uid1\",\"comment\": \"deleted: comment1, added: new comment\"}," + - "{\"change time\": \"05.04.2023 12:00:00\",\"change action\": \"Rule modified\",\"name\": \"TestRule2\"," + - "\"source zone\": \"\",\"source negated\": true,\"source\": [\"TestUser1@TestIp1 (1.2.3.4/32)\",\"TestUser1@TestIp2 (127.0.0.1/32)\"]," + - "\"destination zone\": \"\",\"destination negated\": \"deleted: true, added: false\",\"destination\": [\"TestUser2@TestIpRange (1.2.3.4/32-1.2.3.5/32)\"]," + - "\"service negated\": \"deleted: true, added: false\",\"service\": [\"TestService2 (6666-7777/UDP)\"],\"action\": \"deny\",\"tracking\": \"none\",\"disabled\": \"deleted: false, added: true\",\"rule uid\": \"uid2:123\",\"comment\": \"comment2\"}," + - "{\"change time\": \"05.04.2023 12:00:00\",\"change action\": \"Rule deleted\",\"name\": \"TestRule2\"," + - "\"source zone\": \"\",\"source negated\": true,\"source\": [\"TestUser1@TestIp1 (1.2.3.4/32)\",\"TestUser1@TestIp2 (127.0.0.1/32)\"]," + - "\"destination zone\": \"\",\"destination negated\": true,\"destination\": [\"TestUser2@TestIpRange (1.2.3.4/32-1.2.3.5/32)\"]," + - "\"service negated\": true,\"service\": [\"TestService2 (6666-7777/UDP)\"],\"action\": \"deny\",\"tracking\": \"none\",\"disabled\": false,\"rule uid\": \"uid2:123\",\"comment\": \"comment2\"}]}}]}}]}"; - // Log.WriteInfo("Test Log", removeLinebreaks((removeGenDate(reportChanges.ExportToJson(), false, true)))); - Assert.AreEqual(expectedJsonResult, removeLinebreaks((removeGenDate(reportChanges.ExportToJson(), false, true)))); - } - - [Test] - public void ResolvedChangesTechGenerateJson() - { - Log.WriteInfo("Test Log", "starting resolved changes report json generation"); - ReportChanges reportChanges = new ReportChanges(query, userConfig, ReportType.ResolvedChangesTech); - reportChanges.Managements = ConstructChangeReport(true); - - string expectedJsonResult = - "{\"report type\": \"Changes Report (technical)\",\"report generation date\": \"Z (UTC)\",\"device filter\": \"TestMgt [TestDev]\",\"other filters\": \"TestFilter\",\"report generator\": \"Firewall Orchestrator - https://fwo.cactus.de/en\",\"data protection level\": \"For internal use only\"," + - "\"managements\": [{\"TestMgt\": {\"gateways\": [{\"TestDev\": {\"rule changes\": [" + - "{\"change time\": \"05.04.2023 12:00:00\",\"change action\": \"Rule added\",\"name\": \"TestRule1\"," + - "\"source zone\": \"srczn\",\"source negated\": false,\"source\": [\"1.2.3.4/32\",\"127.0.0.1/32\"]," + - "\"destination zone\": \"dstzn\",\"destination negated\": false,\"destination\": [\"1.2.3.4/32-1.2.3.5/32\"]," + - "\"service negated\": false,\"service\": [\"443/TCP\"],\"action\": \"accept\",\"tracking\": \"none\",\"disabled\": false,\"rule uid\": \"uid1\",\"comment\": \"comment1\"}," + - "{\"change time\": \"05.04.2023 12:00:00\",\"change action\": \"Rule modified\",\"name\": \"TestRule1\"," + - "\"source zone\": \"srczn\",\"source negated\": false,\"source\": [\"127.0.0.1/32\",\"deleted: 1.2.3.4/32\",\"added: 2.3.4.5/32\"]," + - "\"destination zone\": \"dstzn\",\"destination negated\": false,\"destination\": [\"1.2.3.4/32-1.2.3.5/32\",\"added: 10.0.6.1/32\"]," + - "\"service negated\": \"deleted: false, added: true\",\"service\": [\"443/TCP\"],\"action\": \"accept\",\"tracking\": \"none\",\"disabled\": false,\"rule uid\": \"deleted: uid1\",\"comment\": \"deleted: comment1, added: new comment\"}," + - "{\"change time\": \"05.04.2023 12:00:00\",\"change action\": \"Rule modified\",\"name\": \"TestRule2\"," + - "\"source zone\": \"\",\"source negated\": true,\"source\": [\"TestUser1@1.2.3.4/32\",\"TestUser1@127.0.0.1/32\"]," + - "\"destination zone\": \"\",\"destination negated\": \"deleted: true, added: false\",\"destination\": [\"TestUser2@1.2.3.4/32-1.2.3.5/32\"]," + - "\"service negated\": \"deleted: true, added: false\",\"service\": [\"6666-7777/UDP\"],\"action\": \"deny\",\"tracking\": \"none\",\"disabled\": \"deleted: false, added: true\",\"rule uid\": \"uid2:123\",\"comment\": \"comment2\"}," + - "{\"change time\": \"05.04.2023 12:00:00\",\"change action\": \"Rule deleted\",\"name\": \"TestRule2\"," + - "\"source zone\": \"\",\"source negated\": true,\"source\": [\"TestUser1@1.2.3.4/32\",\"TestUser1@127.0.0.1/32\"]," + - "\"destination zone\": \"\",\"destination negated\": true,\"destination\": [\"TestUser2@1.2.3.4/32-1.2.3.5/32\"]," + - "\"service negated\": true,\"service\": [\"6666-7777/UDP\"],\"action\": \"deny\",\"tracking\": \"none\",\"disabled\": false,\"rule uid\": \"uid2:123\",\"comment\": \"comment2\"}]}}]}}]}"; - Assert.AreEqual(expectedJsonResult, removeLinebreaks((removeGenDate(reportChanges.ExportToJson(), false, true)))); - } - - - private NetworkLocation[] InitFroms(bool resolved, bool user = false) - { - if(resolved) - { - return new NetworkLocation[]{ new NetworkLocation(user ? TestUser1 : new NetworkUser(), new NetworkObject(){ ObjectGroupFlats = new GroupFlat[] - { - new GroupFlat(){ Object = TestIp1 }, - new GroupFlat(){ Object = TestIp2 } - }})}; - } - else - { - return new NetworkLocation[] - { - new NetworkLocation(user ? TestUser1 : new NetworkUser(), TestIp1), - new NetworkLocation(user ? TestUser1 : new NetworkUser(), TestIp2) - }; - } - } - - private NetworkLocation[] InitTos(bool resolved, bool user = false) - { - if(resolved) - { - return new NetworkLocation[]{ new NetworkLocation(user ? TestUser2 : new NetworkUser(), new NetworkObject(){ ObjectGroupFlats = new GroupFlat[] - { - new GroupFlat(){ Object = TestIpRange } - }})}; - } - else - { - return new NetworkLocation[] - { - new NetworkLocation(user ? TestUser2 : new NetworkUser(), TestIpRange), - }; - } - } - - private ServiceWrapper[] InitServices(NetworkService service, bool resolved) - { - if(resolved) - { - return new ServiceWrapper[]{new ServiceWrapper(){ Content = new NetworkService(){ServiceGroupFlats = new GroupFlat[] - { - new GroupFlat(){ Object = service } - }}}}; - } - else - { - return new ServiceWrapper[] - { - new ServiceWrapper(){ Content = service }, - }; - } - } - - private Rule InitRule1(bool resolved) - { - return new Rule() - { - Name = "TestRule1", - Action = "accept", - Comment = "comment1", - Disabled = false, - DisplayOrderNumber = 1, - Track = "none", - Uid = "uid1", - SourceZone = new NetworkZone(){ Name = "srczn" }, - SourceNegated = false, - Froms = InitFroms(resolved), - DestinationZone = new NetworkZone(){ Name = "dstzn" }, - DestinationNegated = false, - Tos = InitTos(resolved), - ServiceNegated = false, - Services = InitServices(TestService1, resolved), - Metadata = new RuleMetadata(){ LastHit = new DateTime(2022,04,19) } - }; - } - - private Rule InitRule2(bool resolved) - { - return new Rule() - { - Name = "TestRule2", - Action = "deny", - Comment = "comment2", - Disabled = false, - DisplayOrderNumber = 2, - Track = "none", - Uid = "uid2:123", - SourceNegated = true, - Froms = InitFroms(resolved, true), - DestinationNegated = true, - Tos = InitTos(resolved, true), - ServiceNegated = true, - Services = InitServices(TestService2, resolved) - }; - } - - private Management[] ConstructRuleReport(bool resolved) - { - Rule1 = InitRule1(resolved); - Rule2 = InitRule2(resolved); - return new List() - { - new Management() - { - Name = "TestMgt", - ReportObjects = new NetworkObject[]{ TestIp1, TestIp2, TestIpRange }, - ReportServices = new NetworkService[]{ TestService1, TestService2 }, - ReportUsers = new NetworkUser[]{ TestUser1, TestUser2 }, - Devices = new Device[] - { - new Device() - { - Name = "TestDev", - Rules = new Rule[]{ Rule1, Rule2 } - } - } - } - }.ToArray(); - } - - private Management[] ConstructRecertReport() - { - RecertRule1 = InitRule1(false); - RecertRule1.Metadata.RuleRecertification = new List() - { - new Recertification() - { - NextRecertDate = DateTime.Now.AddDays(5), - FwoOwner = new FwoOwner(){ Name = "TestOwner1" }, - IpMatch = TestIp1.Name - }, - new Recertification() - { - NextRecertDate = DateTime.Now.AddDays(-5), - FwoOwner = new FwoOwner(){ Name = "TestOwner2" }, - IpMatch = TestIp2.Name - } - }; - RecertRule2 = InitRule2(false); - RecertRule2.Metadata.RuleRecertification = new List() - { - new Recertification() - { - NextRecertDate = DateTime.Now, - FwoOwner = new FwoOwner(){ Name = "TestOwner1" }, - IpMatch = TestIpRange.Name - } - }; - return new List() - { - new Management() - { - Name = "TestMgt", - ReportObjects = new NetworkObject[]{ TestIp1, TestIp2, TestIpRange }, - ReportServices = new NetworkService[]{ TestService1, TestService2 }, - ReportUsers = new NetworkUser[]{ TestUser1, TestUser2 }, - Devices = new Device[] - { - new Device() - { - Name = "TestDev", - Rules = new Rule[]{ RecertRule1, RecertRule2 } - } - } - } - }.ToArray(); - } - - private Management[] ConstructNatRuleReport() - { - NatRule = InitRule1(false); - NatRule.NatData = new NatData() - { - TranslatedSourceNegated = false, - TranslatedFroms = new NetworkLocation[] - { - new NetworkLocation(TestUser2, TestIp1Changed) - }, - TranslatedDestinationNegated = true, - TranslatedTos = new NetworkLocation[] - { - new NetworkLocation(new NetworkUser(), TestIp1Changed), - new NetworkLocation(new NetworkUser(), TestIpNew) - }, - TranslatedServiceNegated = false, - TranslatedServices = new ServiceWrapper[] - { - new ServiceWrapper(){ Content = TestService1 }, - new ServiceWrapper(){ Content = TestService2 } - } - }; - return new List() - { - new Management() - { - Name = "TestMgt", - ReportObjects = new NetworkObject[]{ TestIp1, TestIp2, TestIpRange, TestIpNew, TestIp1Changed }, - ReportServices = new NetworkService[]{ TestService1, TestService2 }, - ReportUsers = new NetworkUser[]{ TestUser2 }, - Devices = new Device[] - { - new Device(){ Name = "TestDev", Rules = new Rule[]{ NatRule }} - } - } - }.ToArray(); - } - - private Management[] ConstructChangeReport(bool resolved) - { - Rule1 = InitRule1(resolved); - Rule1Changed = InitRule1(resolved); - Rule2 = InitRule2(resolved); - Rule2Changed = InitRule2(resolved); - if(resolved) - { - Rule1Changed.Froms[0].Object.ObjectGroupFlats[0].Object = TestIp1Changed; - Rule1Changed.Tos = new NetworkLocation[]{new NetworkLocation(new NetworkUser(), new NetworkObject(){ObjectGroupFlats = new GroupFlat[] - { - new GroupFlat(){ Object = TestIpRange }, - new GroupFlat(){ Object = TestIpNew } - }})}; - } - else - { - Rule1Changed.Froms[0].Object = TestIp1Changed; - Rule1Changed.Tos = new NetworkLocation[] - { - new NetworkLocation(new NetworkUser(), TestIpRange), - new NetworkLocation(new NetworkUser(), TestIpNew) - }; - } - Rule1Changed.Uid = ""; - Rule1Changed.ServiceNegated = true; - Rule1Changed.Comment = "new comment"; - - Rule2Changed.DestinationNegated = false; - Rule2Changed.ServiceNegated = false; - Rule2Changed.Disabled = true; - - RuleChange ruleChange1 = new RuleChange() - { - ChangeAction = 'I', - ChangeImport = new ChangeImport(){ Time = new DateTime(2023,04,05,12,0,0) }, - NewRule = Rule1 - }; - RuleChange ruleChange2 = new RuleChange() - { - ChangeAction = 'C', - ChangeImport = new ChangeImport(){ Time = new DateTime(2023,04,05,12,0,0) }, - OldRule = Rule1, - NewRule = Rule1Changed - }; - RuleChange ruleChange3 = new RuleChange() - { - ChangeAction = 'C', - ChangeImport = new ChangeImport(){ Time = new DateTime(2023,04,05,12,0,0) }, - OldRule = Rule2, - NewRule = Rule2Changed - }; - RuleChange ruleChange4 = new RuleChange() - { - ChangeAction = 'D', - ChangeImport = new ChangeImport(){ Time = new DateTime(2023,04,05,12,0,0) }, - OldRule = Rule2 - }; - return new List() - { - new Management() - { - Name = "TestMgt", - Devices = new Device[] - { - new Device() - { - Name = "TestDev", - RuleChanges = new RuleChange[]{ ruleChange1, ruleChange2, ruleChange3, ruleChange4 } - } - } - } - }.ToArray(); - } - - private string removeGenDate(string exportString, bool html = false, bool json = false) - { - string dateText = html ? "

                      Generated on: " : "report generation date" + (json ? "\"" : "") + ": " + (json ? "\"" : ""); - int startGenTime = exportString.IndexOf(dateText); - if(startGenTime > 0) - { - return exportString.Remove(startGenTime + dateText.Length, 19); - } - return exportString; - } - - private string removeLinebreaks(string exportString) - { - while(exportString.Contains("\n ")) - { - exportString = exportString.Replace("\n ","\n"); - } - while(exportString.Contains(" \n")) - { - exportString = exportString.Replace(" \n","\n"); - } - while(exportString.Contains(" \r")) - { - exportString = exportString.Replace(" \r","\r"); - } - exportString = exportString.Replace("\r",""); - return exportString.Replace("\n",""); - } - } -} diff --git a/roles/test/files/FWO.Test/FWO.Test.csproj b/roles/test/files/FWO.Test/FWO.Test.csproj deleted file mode 100644 index 78a60d9660..0000000000 --- a/roles/test/files/FWO.Test/FWO.Test.csproj +++ /dev/null @@ -1,28 +0,0 @@ - - - - net6.0 - false - enable - enable - - - - - - - - - - - - - - - - - - - - - diff --git a/roles/test/files/FWO.Test/FakeLocalTimeZone.cs b/roles/test/files/FWO.Test/FakeLocalTimeZone.cs deleted file mode 100644 index c461e71a4a..0000000000 --- a/roles/test/files/FWO.Test/FakeLocalTimeZone.cs +++ /dev/null @@ -1,29 +0,0 @@ -using System.Reflection; - -namespace FWO.Test -{ - public class FakeLocalTimeZone : IDisposable - { - private readonly TimeZoneInfo _actualLocalTimeZoneInfo; - - private static void SetLocalTimeZone(TimeZoneInfo timeZoneInfo) - { - var info = typeof(TimeZoneInfo).GetField("s_cachedData", BindingFlags.NonPublic | BindingFlags.Static); - object cachedData = info.GetValue(null); - - var field = cachedData.GetType().GetField("_localTimeZone", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static | BindingFlags.Instance); - field.SetValue(cachedData, timeZoneInfo); - } - - public FakeLocalTimeZone(TimeZoneInfo timeZoneInfo) - { - _actualLocalTimeZoneInfo = TimeZoneInfo.Local; - SetLocalTimeZone(timeZoneInfo); - } - - public void Dispose() - { - SetLocalTimeZone(_actualLocalTimeZoneInfo); - } - } -} diff --git a/roles/test/files/FWO.Test/FilterTest.cs b/roles/test/files/FWO.Test/FilterTest.cs deleted file mode 100644 index b8fef1e0bd..0000000000 --- a/roles/test/files/FWO.Test/FilterTest.cs +++ /dev/null @@ -1,141 +0,0 @@ -using FWO.Report.Filter; -using FWO.Report.Filter.Ast; -using FWO.Report.Filter.Exceptions; -using NUnit.Framework; -using System; -using System.Collections.Generic; -using System.Text; -using FWO.Api.Data; -namespace FWO.Test -{ - [TestFixture] - [Parallelizable] - public class FilterTest - { - [SetUp] - public void Initialize() - { - - } - - [Test] - [Parallelizable] - public void EmptySearch() - { - ReportTemplate t = new ReportTemplate(); - t.Filter = ""; - t.ReportParams.ReportType = (int) ReportType.Rules; - Compiler.Compile(t); - } - - [Test] - [Parallelizable] - public void WhitespaceSearch() - { - ReportTemplate t = new ReportTemplate(); - t.Filter = "\t\n \r \t \n"; - t.ReportParams.ReportType = (int) ReportType.Rules; - Compiler.Compile(t); - } - - [Test] - [Parallelizable] - public void TextOnlySearch() - { - ReportTemplate t = new ReportTemplate(); - t.Filter = "teststring"; - t.ReportParams.ReportType = (int) ReportType.Rules; - AstNode? ast = Compiler.CompileToAst("teststring"); - DynGraphqlQuery query = Compiler.Compile(t); - } - - [Test] - [Parallelizable] - public void AndOr() - { - ReportTemplate t = new ReportTemplate(); - t.Filter = "((src=hi) & (dst=test)) | (src = a)"; - t.ReportParams.ReportType = (int) ReportType.Rules; - var res = Compiler.Compile(t); - } - - [Test] - [Parallelizable] - public void TripleOr() - { - ReportTemplate t = new ReportTemplate(); - t.Filter = "(src=cactus or dst=cactus or svc=smtps)"; - t.ReportParams.ReportType = (int) ReportType.Rules; - var res = Compiler.Compile(t); - } - - [Test] - [Parallelizable] - public void NotEquals() - { - ReportTemplate t = new ReportTemplate(); - t.Filter = "(text!=cactus)"; - t.ReportParams.ReportType = (int) ReportType.Rules; - var res = Compiler.Compile(t); - } - - [Test] - [Parallelizable] - public void ExactEquals() - { - ReportTemplate t = new ReportTemplate(); - t.Filter = "(text==cactus)"; - t.ReportParams.ReportType = (int) ReportType.Rules; - var res = Compiler.Compile(t); - } - - [Test] - [Parallelizable] - public void ExactEquals2() - { - ReportTemplate t = new ReportTemplate(); - t.Filter = "(gateway = \"checkpoint_demo\" or gateway = \"fortigate_demo\") & dst == IsoAAADray.local"; - t.ReportParams.ReportType = (int) ReportType.Rules; - var res = Compiler.Compile(t); - } - - [Test] - [Parallelizable] - public void ExactEquals3() - { - try - { - ReportTemplate t = new ReportTemplate(); - t.Filter = "(gateway=\"checkpoint_demo\" or gateway = \"fortigate_demo\") & dst =="; - t.ReportParams.ReportType = (int) ReportType.Rules; - var res = Compiler.Compile(t); - Assert.Fail("Exception should have been thrown"); - } - catch (SyntaxException exception) - { - Assert.AreEqual("No token but one was expected", exception.Message); - } - } - - [Test] - [Parallelizable] - public void Disabled() - { - ReportTemplate t = new ReportTemplate(); - t.Filter = "disabled == true"; - t.ReportParams.ReportType = (int) ReportType.Rules; - var res = Compiler.Compile(t); - } - - [Test] - [Parallelizable] - public void Brackets() - { - ReportTemplate t = new ReportTemplate(); - t.Filter = "src=a&(dst=c)"; - t.ReportParams.ReportType = (int) ReportType.Rules; - var res = Compiler.Compile(t); - } - - } -} diff --git a/roles/test/files/FWO.Test/HtmlToPdfTest.cs b/roles/test/files/FWO.Test/HtmlToPdfTest.cs deleted file mode 100644 index 97c6ecea8c..0000000000 --- a/roles/test/files/FWO.Test/HtmlToPdfTest.cs +++ /dev/null @@ -1,70 +0,0 @@ -using NUnit.Framework; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using WkHtmlToPdfDotNet; -using FWO.Logging; - -namespace FWO.Test -{ - [TestFixture] - [Parallelizable] - internal class HtmlToPdfTest - { - // Pdf converter - protected readonly SynchronizedConverter converter; - - public HtmlToPdfTest() - { - converter = new SynchronizedConverter(new PdfTools()); - } - - [Test] - [Parallelizable] - public void GeneratePdf() - { - Log.WriteInfo("Test Log", "starting PDF generation"); - // HTML - string html = "

                      test

                      test "; - - GlobalSettings globalSettings = new GlobalSettings - { - ColorMode = ColorMode.Color, - Orientation = Orientation.Landscape, - PaperSize = PaperKind.A4 - }; - - HtmlToPdfDocument doc = new HtmlToPdfDocument() - { - GlobalSettings = globalSettings, - Objects = - { - new ObjectSettings() - { - PagesCount = true, - HtmlContent = html, - WebSettings = { DefaultEncoding = "utf-8" }, - HeaderSettings = { FontSize = 9, Right = "Page [page] of [toPage]", Line = true, Spacing = 2.812 } - } - } - }; - - byte[] pdf = converter.Convert(doc); - string filePath = "test.pdf"; - using (var s = File.OpenWrite(filePath)) { - var bw = new BinaryWriter(s); - bw.Write(pdf); - } - Assert.That(filePath, Does.Exist); - Assert.Greater(new System.IO.FileInfo(filePath).Length, 5000); - } - - [OneTimeTearDown] - public void OnFinished() - { - File.Delete("test.pdf"); - } - } -} diff --git a/roles/test/files/FWO.Test/LockTest.cs b/roles/test/files/FWO.Test/LockTest.cs deleted file mode 100644 index 789b97be85..0000000000 --- a/roles/test/files/FWO.Test/LockTest.cs +++ /dev/null @@ -1,139 +0,0 @@ -using FWO.Logging; -using NUnit.Framework; -using System; -using System.Reflection; - -namespace FWO.Test -{ - [TestFixture] - [Parallelizable] - public class LockTest - { - private string lockFilePath = $"/var/fworch/lock/{Assembly.GetEntryAssembly()?.GetName().Name}_log.lock"; - private static Random random = new Random(); - - [SetUp] - public async Task SetUp() - { - await ExecuteFileAction(() => - { - if (File.Exists(lockFilePath)) - { - File.Delete(lockFilePath); - } - return Task.CompletedTask; - }); - - // Implicitly call static constructor so backround lock process is started - Log.WriteInfo("Startup", "Starting Lock Tests..."); - } - - [TearDown] - public async Task TearDown() - { - await ExecuteFileAction(() => - { - if (File.Exists(lockFilePath)) - { - File.Delete(lockFilePath); - } - return Task.CompletedTask; - }); - } - - [Test] - public async Task LogLock() - { - // Request lock - await ExecuteFileAction(async () => - { - using (var writer = new StreamWriter(lockFilePath)) - { - await writer.WriteLineAsync("REQUESTED"); - } - }); - - await Task.Delay(2000); - - // Assure lock is granted after request - await ExecuteFileAction(async () => - { - using (var reader = new StreamReader(lockFilePath)) - { - Assert.That((await reader.ReadToEndAsync()).Trim().EndsWith("GRANTED")); - } - }); - - // Assure write is NOT possible after lock was granted - Task logWriter = Task.Run(() => - { - Log.WriteDebug("TEST_TITLE", "TEST_TEXT"); - }); - - await Task.Delay(500); - - Assert.That(logWriter.IsCompleted, Is.False); - - // Release lock - await ExecuteFileAction(async () => - { - using (var writer = new StreamWriter(lockFilePath)) - { - await writer.WriteLineAsync("RELEASED"); - } - }); - - await Task.Delay(2000); - - // Assure write IS possible after lock was released - Assert.That(logWriter.IsCompletedSuccessfully, Is.True); - - // Request lock - await ExecuteFileAction(async () => - { - using (var writer = new StreamWriter(lockFilePath)) - { - await writer.WriteLineAsync("REQUESTED"); - } - }); - - await Task.Delay(12_000); - - // If not release in time make sure that the lock will be forcefully released - await ExecuteFileAction(async () => - { - using (var reader = new StreamReader(lockFilePath)) - { - Assert.That((await reader.ReadToEndAsync()).Trim().EndsWith("FORCEFULLY RELEASED")); - } - }); - } - - private static async Task ExecuteFileAction(Func action) - { - bool success = false; - int maxRetryAttempts = 50; - int retryCount = 0; - - // Handle IO Exception like file blocking from another process by retrying with a random delay - while (!success && retryCount < maxRetryAttempts) - { - try - { - await action(); - success = true; - } - catch (IOException) - { - retryCount++; - } - await Task.Delay(random.Next(50, 100)); - } - - if (!success) - { - Assert.Fail($"Lock file access failed after {maxRetryAttempts} retries."); - } - } - } -} diff --git a/roles/test/files/FWO.Test/SimulatedApiConnection.cs b/roles/test/files/FWO.Test/SimulatedApiConnection.cs deleted file mode 100644 index 8bc699ff8a..0000000000 --- a/roles/test/files/FWO.Test/SimulatedApiConnection.cs +++ /dev/null @@ -1,47 +0,0 @@ -using FWO.Api.Client; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace FWO.Test -{ - internal class SimulatedApiConnection : ApiConnection - { - public override GraphQlApiSubscription GetSubscription(Action exceptionHandler, GraphQlApiSubscription.SubscriptionUpdate subscriptionUpdateHandler, string subscription, object? variables = null, string? operationName = null) - { - throw new NotImplementedException(); - } - - public override Task SendQueryAsync(string query, object? variables = null, string? operationName = null) - { - throw new NotImplementedException(); - } - - public override void SetAuthHeader(string jwt) - { - throw new NotImplementedException(); - } - - public override void SetRole(string role) - { - throw new NotImplementedException(); - } - - public override void SetProperRole(System.Security.Claims.ClaimsPrincipal user, List targetRoleList) - { - throw new NotImplementedException(); - } - - public override void SwitchBack() - { - throw new NotImplementedException(); - } - - protected override void Dispose(bool disposing) - { - throw new NotImplementedException(); - } - } -} diff --git a/roles/test/files/FWO.Test/SimulatedUserConfig.cs b/roles/test/files/FWO.Test/SimulatedUserConfig.cs deleted file mode 100644 index 16438aa6d1..0000000000 --- a/roles/test/files/FWO.Test/SimulatedUserConfig.cs +++ /dev/null @@ -1,62 +0,0 @@ -using FWO.Config.Api; - -namespace FWO.Test -{ - internal class SimulatedUserConfig : UserConfig - { - public Dictionary DummyTranslate = new Dictionary() - { - {"Rules","Rules Report"}, - {"ResolvedRules","Rules Report (resolved)"}, - {"ResolvedRulesTech","Rules Report (technical)"}, - {"UnusedRules","Unused Rules Report"}, - {"Recertification","Recertification Report"}, - {"NatRules","NAT Rules Report"}, - {"Changes","Changes Report"}, - {"ResolvedChanges","Changes Report (resolved)"}, - {"ResolvedChangesTech","Changes Report (technical)"}, - {"date_of_config","Time of configuration"}, - {"generated_on","Generated on"}, - {"negated","not"}, - {"users","Users"}, - {"rule_added","Rule added"}, - {"rule_deleted","Rule deleted"}, - {"rule_modified","Rule modified"}, - {"deleted","deleted"}, - {"added","added"}, - {"change_time","Change Time"}, - {"change_type","Change Type"}, - {"number","No."}, - {"name","Name"}, - {"source_zone","Source Zone"}, - {"source","Source"}, - {"destination_zone","Destination Zone"}, - {"destination","Destination"}, - {"services","Services"}, - {"action","Action"}, - {"track","Track"}, - {"enabled","Enabled"}, - {"uid","Uid"}, - {"comment","Comment"}, - {"type","Type"}, - {"ip_address","IP Address"}, - {"members","Members"}, - {"network_objects","Network Objects"}, - {"network_services","Network Services"}, - {"protocol","Protocol"}, - {"port","Port"}, - {"next_recert","Next Recertification Date"}, - {"owner","Owner"}, - {"ip_matches","IP address match"}, - {"last_hit","Last Hit"}, - {"trans_source","Translated Source"}, - {"trans_destination","Translated Destination"}, - {"trans_services","Translated Services"} - }; - - public override string GetText(string key) - { - return DummyTranslate[key]; - } - } -} diff --git a/roles/test/files/FWO.Test/TestInitializer.cs b/roles/test/files/FWO.Test/TestInitializer.cs deleted file mode 100644 index 028b32d73e..0000000000 --- a/roles/test/files/FWO.Test/TestInitializer.cs +++ /dev/null @@ -1,37 +0,0 @@ -using NUnit.Framework; -using System.Globalization; - - -namespace FWO.Test -{ - [SetUpFixture] - class TestInitializer - { - private FakeLocalTimeZone? fakeLocalTimeZone; - - [OneTimeSetUp] - public void OnStart() - { - SetGermanCultureOnAllUnitTest(); - SetGermanTimeZoneOnAllUnitTest(); - } - - [OneTimeTearDown] - public void OnFinish() - { - fakeLocalTimeZone?.Dispose(); - } - - - public static void SetGermanCultureOnAllUnitTest() - { - Thread.CurrentThread.CurrentCulture = new CultureInfo("de-DE"); - Thread.CurrentThread.CurrentUICulture = new CultureInfo("de-DE"); - } - - public void SetGermanTimeZoneOnAllUnitTest() - { - fakeLocalTimeZone = new FakeLocalTimeZone(TimeZoneInfo.FindSystemTimeZoneById("Europe/Berlin")){}; - } - } -} diff --git a/roles/test/files/importer/CP-R8x/unused_create_csv_sting.sh b/roles/test/files/importer/CP-R8x/unused_create_csv_sting.sh deleted file mode 100644 index d50b0241cb..0000000000 --- a/roles/test/files/importer/CP-R8x/unused_create_csv_sting.sh +++ /dev/null @@ -1,15 +0,0 @@ -#!/bin/bash - -Targetdir=/tmp/isotmp/1111 -Sourcecfg=/home/tim/sting-manager.cfg -Dstcfg=/tmp/isotmp/1111/cfg/sting-manager.cfg -Bindir=/usr/local/fworch/importer -cd $Bindir || exit -mkdir -p $Targetdir/cfg -cp $Sourcecfg $Dstcfg -#python fworch_parse_config_cp_r8x_api.py -i 123 -f $Sourcecfg -u > $Targetdir/sting_users.csv -#python fworch_parse_config_cp_r8x_api.py -i 123 -f $Sourcecfg -s > $Targetdir/sting_services.csv -#python fworch_parse_config_cp_r8x_api.py -i 123 -f $Sourcecfg -n > $Targetdir/sting_netzobjekte.csv -#python fworch_parse_config_cp_r8x_api.py -i 123 -f $Sourcecfg -r 'cactus_Security' > $Targetdir/sting_rulebase.csv - -./fworch-importer-single.pl mgm_name=sting-manager -parse-only diff --git a/roles/test/files/importer/anonymizer/strings-customer-003.txt b/roles/test/files/importer/anonymizer/strings-customer-003.txt deleted file mode 100644 index 7fa255f1c8..0000000000 --- a/roles/test/files/importer/anonymizer/strings-customer-003.txt +++ /dev/null @@ -1,8 +0,0 @@ -cactus -CACTUS -lhystems -sting -ralf -Ralf -kids -ubuntu diff --git a/roles/test/files/importer/config_changes/write_date_to_comment.py b/roles/test/files/importer/config_changes/write_date_to_comment.py deleted file mode 100644 index db9e2087d0..0000000000 --- a/roles/test/files/importer/config_changes/write_date_to_comment.py +++ /dev/null @@ -1,43 +0,0 @@ -# Changes the comment in rule x to the current date in fortigate.cfg -# x = 52 by default, can be changed in ansible -# Created by alf - -import fnmatch -import datetime -import os -import sys - -# Define global variables that may be passed on the command line and their defaults if not -# example$ python3 write_date_to_comment.py uid "path" - -uid = sys.argv[1] if len(sys.argv) >= 2 else 52 -config_path = sys.argv[2] if len(sys.argv) >= 3 else "/home/fworchsample/sample-configs/fortinet_demo/fortigate.cfg" - -with open(config_path, "r") as fin: - data = fin.readlines() - -rule_area_flag = False -uid_flag = False -current_line = 0 -for line in data: - if fnmatch.filter([line], 'config firewall policy\n'): - rule_area_flag = True - if fnmatch.filter([line], ' edit {}\n'.format(uid)): - uid_flag = True - if fnmatch.filter([line], ' set comments*') and uid_flag and rule_area_flag: - data[current_line] = ' set comments "{}"\n'.format(datetime.datetime.now()) - break - if fnmatch.filter([line], ' next\n') and uid_flag and rule_area_flag: - data.insert(current_line, ' set comments "{}"\n'.format(datetime.datetime.now())) - break - if fnmatch.filter([line], ' next\n'): - uid_flag = False - if fnmatch.filter([line], 'end\n'): - rule_area_flag = False - current_line = current_line + 1 - -with open(config_path + "2.tmp", "w") as fout: - data = "".join(data) - fout.write(data) - -os.rename(config_path + '2.tmp', config_path) diff --git a/roles/test/files/importer/sample-configs/checkpoint_demo/fwauth.NDB b/roles/test/files/importer/sample-configs/checkpoint_demo/fwauth.NDB deleted file mode 100644 index c08307db44..0000000000 Binary files a/roles/test/files/importer/sample-configs/checkpoint_demo/fwauth.NDB and /dev/null differ diff --git a/roles/test/files/importer/sample-configs/checkpoint_demo/objects_5_0.C b/roles/test/files/importer/sample-configs/checkpoint_demo/objects_5_0.C deleted file mode 100644 index 11d3f643d3..0000000000 --- a/roles/test/files/importer/sample-configs/checkpoint_demo/objects_5_0.C +++ /dev/null @@ -1,25894 +0,0 @@ -( - :anyobj (Any - :color (Blue) - ) - :superanyobj ( - : (Any - :color (Blue) - ) - ) - :sofaware_gw_types ( - : (IP40 - :AdminInfo ( - :LastModified ( - :Time ("Sun Jul 21 12:24:13 2002") - :By (CheckPoint) - :From (CheckPoint) - ) - :chkpf_uid ("{1FF5E2C5-43E1-4A1B-9E20-376ACB0BA683}") - :ClassName (sofaware_product_type) - :table (sofaware_gw_types) - :Deleteable (false) - :Renameable (false) - ) - :default_package () - :firmware_type (nokia_ip40) - :type (sofaware_product_type_obj) - ) - : (SBox-200 - :AdminInfo ( - :LastModified ( - :Time ("Sun Jul 21 12:24:13 2002") - :By (CheckPoint) - :From (CheckPoint) - ) - :chkpf_uid ("{3A8F3574-D510-4FA9-8467-1AC488A0CEF0}") - :ClassName (sofaware_product_type) - :table (sofaware_gw_types) - :Deleteable (false) - :Renameable (false) - ) - :default_package () - :firmware_type (generic2_safe@) - :type (sofaware_product_type_obj) - ) - : (SecureBlade300 - :AdminInfo ( - :LastModified ( - :Time ("Sun Jul 21 12:24:27 2002") - :By (CheckPoint) - :From (CheckPoint) - ) - :chkpf_uid ("{D554FE57-BAFB-410B-9708-71BA81052FBA}") - :ClassName (sofaware_product_type) - :table (sofaware_gw_types) - :Deleteable (false) - :Renameable (false) - ) - :default_package () - :firmware_type (generic_safe@) - :type (sofaware_product_type_obj) - ) - : (SBox-100 - :AdminInfo ( - :LastModified ( - :Time ("Sun Jul 21 12:23:49 2002") - :By (CheckPoint) - :From (CheckPoint) - ) - :chkpf_uid ("{EC1B649A-7485-4039-B6FC-56EBA3BE59BC}") - :ClassName (sofaware_product_type) - :table (sofaware_gw_types) - :Deleteable (false) - :Renameable (false) - ) - :default_package () - :firmware_type (generic_safe@) - :type (sofaware_product_type_obj) - ) - : (IP30 - :AdminInfo ( - :LastModified ( - :Time ("Sun Jul 21 12:24:13 2002") - :By (CheckPoint) - :From (CheckPoint) - ) - :chkpf_uid ("{7C65EB3E-CF01-4816-948E-0799A3804FC6}") - :ClassName (sofaware_product_type) - :table (sofaware_gw_types) - :Deleteable (false) - :Renameable (false) - ) - :default_package () - :firmware_type (nokia_ip30) - :type (sofaware_product_type_obj) - ) - : (SecureBlade - :AdminInfo ( - :LastModified ( - :Time ("Sun Jul 21 12:24:27 2002") - :By (CheckPoint) - :From (CheckPoint) - ) - :chkpf_uid ("{F7B25443-282D-4D90-AB96-91A082AEB5B1}") - :ClassName (sofaware_product_type) - :table (sofaware_gw_types) - :Deleteable (false) - :Renameable (false) - ) - :default_package () - :firmware_type (generic_safe@) - :type (sofaware_product_type_obj) - ) - ) - :atlas_gateway_properties ( - : (SW - :AdminInfo ( - :chkpf_uid ("{5E6B7A8C-81F5-4B10-8069-03A85BBF4D21}") - :ClassName (atlas_gateway_property) - :table (atlas_gateway_properties) - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :firmwares () - :versions () - :default_profile (sofaware_gw_default_profile) - :gw_type_displayed_name ("Safe@ ROBO") - :is_default (false) - :profile_type (gw_profile_lsm_sofaware) - :type (atlas_gateway_property) - ) - : (CP - :AdminInfo ( - :chkpf_uid ("{F5DF4B54-2FE4-4BFE-8AF1-D5925E240F5D}") - :ClassName (atlas_gateway_property) - :table (atlas_gateway_properties) - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :firmwares () - :versions ( - : ("NG FP3") - ) - :default_profile () - :gw_type_displayed_name ("Check Point ROBO") - :is_default (true) - :profile_type (gw_profile_cp) - :type (atlas_gateway_property) - ) - ) - :atlas_general_properties ( - : (general - :AdminInfo ( - :chkpf_uid ("{7D2D8989-C348-4126-B551-0AF4222217CD}") - :ClassName (atlas_general_property) - :table (atlas_general_properties) - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :statuses ( - : ( - :AdminInfo ( - :chkpf_uid ("{97AEB36C-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (status_properties) - ) - :is_critical (false) - :status_name (OK) - :status_value (0) - :type (status_properties) - ) - : ( - :AdminInfo ( - :chkpf_uid ("{E10C00B2-B7E7-47F0-9D1D-B6274CDF620D}") - :ClassName (status_properties) - ) - :is_critical (false) - :status_name (Unknown) - :status_value (1) - :type (status_properties) - ) - : ( - :AdminInfo ( - :chkpf_uid ("{36C16215-80C6-4C44-A963-E94263AF46CC}") - :ClassName (status_properties) - ) - :is_critical (false) - :status_name (Untrusted) - :status_value (2) - :type (status_properties) - ) - : ( - :AdminInfo ( - :chkpf_uid ("{030973CA-77D5-4CE6-B907-11E6F8801A23}") - :ClassName (status_properties) - ) - :is_critical (true) - :status_name ("Not Responding") - :status_value (3) - :type (status_properties) - ) - : ( - :AdminInfo ( - :chkpf_uid ("{80FFC1F0-4591-4DC2-AFFC-10162D947179}") - :ClassName (status_properties) - ) - :is_critical (true) - :status_name ("Needs Attention") - :status_value (4) - :type (status_properties) - ) - : ( - :AdminInfo ( - :chkpf_uid ("{1D94C5C9-961E-47C5-81B3-8306D898957B}") - :ClassName (status_properties) - ) - :is_critical (false) - :status_name ("Not Installed") - :status_value (5) - :type (status_properties) - ) - : ( - :AdminInfo ( - :chkpf_uid ("{F30E6621-205D-43DA-BFD7-9BDAC5F2ACDB}") - :ClassName (status_properties) - ) - :is_critical (true) - :status_name ("Not Updated") - :status_value (6) - :type (status_properties) - ) - : ( - :AdminInfo ( - :chkpf_uid ("{3BBD2FB3-F19E-4AB7-859A-E2614E8F5DEE}") - :ClassName (status_properties) - ) - :is_critical (false) - :status_name ("May be out of date") - :status_value (7) - :type (status_properties) - ) - ) - :type (atlas_general_property) - ) - ) - :policies_collections ( - : (Standard - :AdminInfo ( - :chkpf_uid ("{2E49485A-61E2-4F55-A71C-85B9BF5CD9E1}") - :ClassName (policies_collection) - :object_permissions ( - :AdminInfo ( - :chkpf_uid ("{711F7FC2-4ADA-4AE2-AC0B-95421F5A9949}") - :ClassName (object_permissions) - ) - :manage ( - : (ReferenceObject - :Table (globals) - :Name (Any) - ) - ) - :read ( - : (any) - ) - :use ( - : (any) - ) - :write ( - : () - ) - :owner () - ) - :table (policies_collections) - :Wiznum (-1) - :LastModified ( - :Time ("Sun Feb 16 01:21:31 2003") - :By (tim) - :From (STICHLING) - ) - ) - :installable_targets () - :all_internal_modules (true) - :color (black) - :comments () - :default (0) - :type (policies_collection) - ) - : (IsoAAAA-traditional - :AdminInfo ( - :chkpf_uid ("{8EA5AF0F-7640-4BF9-8E5B-577091884205}") - :ClassName (policies_collection) - :table (policies_collections) - :Wiznum (-1) - :LastModified ( - :Time ("Tue Jul 27 19:39:19 2004") - :By (IsoAAAF) - :From (scratchy) - ) - ) - :default (0) - :installable_targets () - :all_internal_modules (true) - :color (black) - :comments () - :type (policies_collection) - ) - : (IsoAAAA_Simplified - :AdminInfo ( - :chkpf_uid ("{26FF70B8-9599-49B4-B6F6-84B7AE0D2EBB}") - :ClassName (policies_collection) - :table (policies_collections) - :Wiznum (-1) - :LastModified ( - :Time ("Sat Nov 20 21:55:27 2004") - :By (tim) - :From (gateway) - ) - ) - :comments () - :default (0) - :installable_targets () - :all_internal_modules (true) - :color (black) - :type (policies_collection) - ) - : (IsoAAAA - :AdminInfo ( - :chkpf_uid ("{462FD47E-BB4B-4DC4-95D6-E25D7E6C1E41}") - :ClassName (policies_collection) - :object_permissions ( - :AdminInfo ( - :chkpf_uid ("{98264DAA-4862-46E3-AE64-BB8A15BB9CCC}") - :ClassName (object_permissions) - ) - :manage ( - : (ReferenceObject - :Table (globals) - :Name (Any) - ) - ) - :read ( - : (any) - ) - :use ( - : (any) - ) - :write ( - : () - ) - :owner () - ) - :table (policies_collections) - :Wiznum (-1) - :LastModified ( - :Time ("Sat Nov 20 21:55:27 2004") - :By (tim) - :From (gateway) - ) - ) - :installable_targets () - :all_internal_modules (true) - :color (black) - :comments () - :default (1) - :type (policies_collection) - ) - ) - :network_objects (network_objects - : (InternalNet - :AdminInfo ( - :LastModified ( - :Time ("Sun May 12 10:37:48 2002") - :By (CheckPoint) - :From (CheckPoint) - ) - :chkpf_uid ("{5E414BEC-4A61-4675-A980-4841A1F5A0BE}") - :ClassName (dynamic_object) - :table (network_objects) - :Deleteable (false) - :Renameable (false) - :name (InternalNet) - ) - :bogus_ip (10.222.0.1) - :color (black) - :comments () - :track (none) - :type (dynamic_net_obj) - ) - : (DMZNet - :AdminInfo ( - :LastModified ( - :Time ("Sun May 12 10:38:03 2002") - :By (CheckPoint) - :From (CheckPoint) - ) - :chkpf_uid ("{8A883654-CDD4-45A8-B079-D4E476A70AD6}") - :ClassName (dynamic_object) - :table (network_objects) - :Deleteable (false) - :Renameable (false) - :name (DMZNet) - ) - :bogus_ip (10.222.0.2) - :color (black) - :comments () - :track (none) - :type (dynamic_net_obj) - ) - : (AuxiliaryNet - :AdminInfo ( - :LastModified ( - :Time ("Thu Jul 11 14:11:54 2002") - :By (CheckPoint) - :From (CheckPoint) - ) - :chkpf_uid ("{CAC127FB-24F5-4079-9404-BE5C00D11393}") - :ClassName (dynamic_object) - :table (network_objects) - :Deleteable (false) - :Renameable (false) - :name (AuxiliaryNet) - ) - :bogus_ip (10.222.0.3) - :color (black) - :comments () - :track (none) - :type (dynamic_net_obj) - ) - : (Low - :AdminInfo ( - :LastModified ( - :Time ("Thu Jul 11 14:11:54 2002") - :By (CheckPoint) - :From (CheckPoint) - ) - :chkpf_uid ("{0F147E90-C23D-432C-9294-DEEFD31A1E56}") - :ClassName (sofaware_profiles_security_level) - :table (network_objects) - :Deleteable (false) - :Renameable (false) - :name (Low) - ) - :color (black) - :comments () - :ipaddr (10.222.0.4) - :level (low) - :type (sofaware_profiles_security_level) - ) - : (Medium - :AdminInfo ( - :LastModified ( - :Time ("Thu Jul 11 14:11:54 2002") - :By (CheckPoint) - :From (CheckPoint) - ) - :chkpf_uid ("{7DF4722A-0B57-4906-8E0C-699EC278B6FA}") - :ClassName (sofaware_profiles_security_level) - :table (network_objects) - :Deleteable (false) - :Renameable (false) - :name (Medium) - ) - :color (black) - :comments () - :ipaddr (10.222.0.5) - :level (med) - :type (sofaware_profiles_security_level) - ) - : (High - :AdminInfo ( - :LastModified ( - :Time ("Thu Jul 11 14:11:54 2002") - :By (CheckPoint) - :From (CheckPoint) - ) - :chkpf_uid ("{C8460A52-CEE1-4A85-BBAA-0097C0401CAE}") - :ClassName (sofaware_profiles_security_level) - :table (network_objects) - :Deleteable (false) - :Renameable (false) - :name (High) - ) - :color (black) - :comments () - :ipaddr (10.222.0.6) - :level (high) - :type (sofaware_profiles_security_level) - ) - : (LocalMachine - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:07 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB36B-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (dynamic_object) - :table (network_objects) - :name (LocalMachine) - :Deleteable (false) - :Renameable (false) - ) - :bogus_ip (10.222.0.7) - :color (black) - :comments ("Check Point Local Machine") - :track (none) - :type (dynamic_net_obj) - ) - : (DAG_range - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:07 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB36C-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (address_range) - :table (network_objects) - :Hidden (true) - :Deleteable (false) - :Renameable (false) - :name (DAG_range) - ) - :edges () - :NAT () - :add_adtr_rule (false) - :color (black) - :comments () - :ipaddr_first (10.222.0.1) - :ipaddr_last (10.222.0.8) - :type (machines_range) - ) - : (wasp - :AdminInfo ( - :chkpf_uid ("{098B2A74-E220-4AE8-A164-340FED79C9D5}") - :ClassName (host_plain) - :table (network_objects) - :Wiznum (-1) - :LastModified ( - :Time ("Sat May 10 18:55:57 2003") - :By (IsoAAAF) - :From (scratchy) - ) - :name (wasp) - ) - :certificates () - :edges () - :interfaces () - :NAT () - :read_community () - :sysContact () - :sysDescr () - :sysLocation () - :sysName () - :write_community () - :SNMP ( - :AdminInfo ( - :chkpf_uid ("{098B2A74-E220-4AE8-A164-340FED79C9D5}") - :ClassName (SNMP) - ) - ) - :VPN () - :add_adtr_rule (false) - :color (blue) - :comments (timeserver) - :cp_products_installed (false) - :enforce_gtp_rate_limit (false) - :firewall (not-installed) - :floodgate (not-installed) - :gtp_rate_limit (2048) - :ipaddr (10.222.0.9) - :operating_system ( - :AdminInfo ( - :chkpf_uid ("{CCB732A7-07A1-43DA-920D-1BE2566CEF93}") - :ClassName (operating_system) - ) - :name () - :sp () - :version () - ) - :type (host) - ) - : (itchy - :AdminInfo ( - :chkpf_uid ("{3B4DF852-5064-4957-B95F-D469C5656467}") - :ClassName (host_plain) - :table (network_objects) - :Wiznum (-1) - :LastModified ( - :Time ("Sat May 10 18:59:46 2003") - :By (IsoAAAF) - :From (scratchy) - ) - :name (itchy) - ) - :certificates () - :edges () - :interfaces () - :NAT () - :read_community () - :sysContact () - :sysDescr () - :sysLocation () - :sysName () - :write_community () - :SNMP ( - :AdminInfo ( - :chkpf_uid ("{3B4DF852-5064-4957-B95F-D469C5656467}") - :ClassName (SNMP) - ) - ) - :VPN () - :add_adtr_rule (false) - :color (gold) - :comments (dns) - :cp_products_installed (false) - :enforce_gtp_rate_limit (false) - :firewall (not-installed) - :floodgate (not-installed) - :gtp_rate_limit (2048) - :ipaddr (10.222.0.10) - :operating_system ( - :AdminInfo ( - :chkpf_uid ("{A69EA138-D19E-4AE9-BBAD-4693DA3C2124}") - :ClassName (operating_system) - ) - :name () - :sp () - :version () - ) - :type (host) - ) - : (mg.IsoAAAA-es.com - :AdminInfo ( - :chkpf_uid ("{E5BF8260-3615-4476-B638-53CA3A24FEF1}") - :ClassName (host_plain) - :table (network_objects) - :Wiznum (-1) - :LastModified ( - :Time ("Sun May 18 16:27:49 2003") - :By (IsoAAAF) - :From (scratchy) - ) - :name (mg.IsoAAAA-es.com) - ) - :certificates () - :edges () - :interfaces () - :NAT () - :read_community () - :sysContact () - :sysDescr () - :sysLocation () - :sysName () - :write_community () - :SNMP ( - :AdminInfo ( - :chkpf_uid ("{E5BF8260-3615-4476-B638-53CA3A24FEF1}") - :ClassName (SNMP) - ) - ) - :VPN () - :add_adtr_rule (false) - :color ("forest green") - :comments (spike) - :cp_products_installed (false) - :enforce_gtp_rate_limit (false) - :firewall (not-installed) - :floodgate (not-installed) - :gtp_rate_limit (2048) - :ipaddr (10.222.0.11) - :operating_system ( - :AdminInfo ( - :chkpf_uid ("{EB6C11C9-CF82-4F05-A5F8-F505D9CB9280}") - :ClassName (operating_system) - ) - :name () - :sp () - :version () - ) - :type (host) - ) - : (heag_off_supper - :AdminInfo ( - :chkpf_uid ("{858E3E67-0517-485F-AA04-97A12BC119C3}") - :ClassName (network) - :table (network_objects) - :Wiznum (-1) - :LastModified ( - :Time ("Tue Jul 15 16:08:08 2003") - :By (stephan) - :From (vaio) - ) - :name (heag_off_supper) - ) - :edges () - :NAT () - :add_adtr_rule (false) - :broadcast (allow) - :color (black) - :comments ("obere Heag Netz H�lfte") - :ipaddr (10.222.0.12) - :location (internal) - :netmask (255.255.255.255) - :operating_system ( - :AdminInfo ( - :chkpf_uid ("{D0BDE3B1-1AF8-45E1-95FB-3E047BB5709D}") - :ClassName (operating_system) - ) - :name () - :sp () - :version () - ) - :type (network) - ) - : (heag_off_upper - :AdminInfo ( - :chkpf_uid ("{A58E3E67-0517-485F-AA04-97A12BC119C3}") - :ClassName (network) - :table (network_objects) - :Wiznum (-1) - :LastModified ( - :Time ("Tue Jul 15 16:08:08 2003") - :By (stephan) - :From (vaio) - ) - :name (heag_off_upper) - ) - :edges () - :NAT () - :add_adtr_rule (false) - :broadcast (allow) - :color (black) - :comments ("obere Heag Netz H�lfte") - :ipaddr (10.222.0.13) - :location (internal) - :netmask (255.255.255.255) - :operating_system ( - :AdminInfo ( - :chkpf_uid ("{D0BDE3B1-1AF8-45E1-95FB-3E047BB5709D}") - :ClassName (operating_system) - ) - :name () - :sp () - :version () - ) - :type (network) - ) - : (thorn - :AdminInfo ( - :chkpf_uid ("{32A2BEEF-3078-4B23-A9D9-5B0BDBDB08C3}") - :ClassName (host_plain) - :table (network_objects) - :Wiznum (-1) - :LastModified ( - :Time ("Tue Jul 15 16:09:30 2003") - :By (stephan) - :From (vaio) - ) - :name (thorn) - ) - :certificates () - :edges () - :interfaces () - :NAT () - :read_community () - :sysContact () - :sysDescr () - :sysLocation () - :sysName () - :write_community () - :SNMP ( - :AdminInfo ( - :chkpf_uid ("{32A2BEEF-3078-4B23-A9D9-5B0BDBDB08C3}") - :ClassName (SNMP) - ) - ) - :VPN () - :add_adtr_rule (false) - :color (black) - :comments (thorn) - :cp_products_installed (false) - :enforce_gtp_rate_limit (false) - :firewall (not-installed) - :floodgate (not-installed) - :gtp_rate_limit (2048) - :ipaddr (10.222.0.14) - :operating_system ( - :AdminInfo ( - :chkpf_uid ("{09C26953-217D-4923-80E8-E13B538C5616}") - :ClassName (operating_system) - ) - :name () - :sp () - :version () - ) - :type (host) - ) - : (IsoAAADray.local - :AdminInfo ( - :chkpf_uid ("{75EDBC62-7EB1-4D37-8295-684903FDA75A}") - :ClassName (host_plain) - :table (network_objects) - :Wiznum (-1) - :LastModified ( - :Time ("Fri Nov 21 12:52:52 2003") - :By (IsoAAAF) - :From (scratchy) - ) - :name (IsoAAADray.local) - ) - :certificates () - :edges () - :interfaces () - :NAT () - :read_community () - :sysContact () - :sysDescr () - :sysLocation () - :sysName () - :write_community () - :SNMP ( - :AdminInfo ( - :chkpf_uid ("{75EDBC62-7EB1-4D37-8295-684903FDA75A}") - :ClassName (SNMP) - ) - ) - :VPN () - :add_adtr_rule (false) - :color (gold) - :comments () - :cp_products_installed (false) - :enforce_gtp_rate_limit (false) - :firewall (not-installed) - :floodgate (not-installed) - :gtp_rate_limit (2048) - :ipaddr (10.222.0.15) - :operating_system ( - :AdminInfo ( - :chkpf_uid ("{EE89D4EB-6706-4A6D-98A9-4EC4604186B7}") - :ClassName (operating_system) - ) - :name () - :sp () - :version () - ) - :type (host) - ) - : (scratchy.local - :AdminInfo ( - :chkpf_uid ("{CFABE50C-C1F6-4FF1-8AC3-3161A3779708}") - :ClassName (host_plain) - :table (network_objects) - :Wiznum (-1) - :LastModified ( - :Time ("Sun Nov 30 19:34:35 2003") - :By (IsoAAAF) - :From (scratchy) - ) - :name (scratchy.local) - ) - :certificates () - :edges () - :interfaces () - :NAT () - :read_community () - :sysContact () - :sysDescr () - :sysLocation () - :sysName () - :write_community () - :SNMP ( - :AdminInfo ( - :chkpf_uid ("{CFABE50C-C1F6-4FF1-8AC3-3161A3779708}") - :ClassName (SNMP) - ) - ) - :VPN () - :add_adtr_rule (false) - :color (gold) - :comments () - :cp_products_installed (false) - :enforce_gtp_rate_limit (false) - :firewall (not-installed) - :floodgate (not-installed) - :gtp_rate_limit (2048) - :ipaddr (10.222.0.16) - :operating_system ( - :AdminInfo ( - :chkpf_uid ("{27703391-81D0-4189-AE45-96F1931504E8}") - :ClassName (operating_system) - ) - :name () - :sp () - :version () - ) - :type (host) - ) - : (wlan-router - :AdminInfo ( - :chkpf_uid ("{426CC3AD-BE7D-45B6-AAAB-22BA0680EE21}") - :ClassName (host_plain) - :table (network_objects) - :Wiznum (-1) - :LastModified ( - :Time ("Fri Dec 5 20:01:42 2003") - :By (IsoAAAF) - :From (scratchy) - ) - :name (wlan-router) - ) - :certificates () - :edges () - :interfaces () - :NAT () - :read_community () - :sysContact () - :sysDescr () - :sysLocation () - :sysName () - :write_community () - :SNMP ( - :AdminInfo ( - :chkpf_uid ("{426CC3AD-BE7D-45B6-AAAB-22BA0680EE21}") - :ClassName (SNMP) - ) - ) - :VPN () - :add_adtr_rule (false) - :color ("deep pink") - :comments () - :cp_products_installed (false) - :enforce_gtp_rate_limit (false) - :firewall (not-installed) - :floodgate (not-installed) - :gtp_rate_limit (2048) - :ipaddr (10.222.0.17) - :operating_system ( - :AdminInfo ( - :chkpf_uid ("{50E99C71-A042-439A-B5ED-B8F5F93BE3CA}") - :ClassName (operating_system) - ) - :name () - :sp () - :version () - ) - :type (host) - ) - : (wlan-sources - :AdminInfo ( - :chkpf_uid ("{7592504D-3B32-4F86-BC38-3F6D9EF8BFA7}") - :ClassName (network_object_group) - :table (network_objects) - :Wiznum (-1) - :LastModified ( - :Time ("Fri Dec 5 21:31:42 2003") - :By (IsoAAAF) - :From (scratchy) - ) - :name (wlan-sources) - ) - : (ReferenceObject - :Name (IsoAAAA-100) - :Table (network_objects) - :Uid ("{BF1C6029-8D5D-4A05-A3AD-4B67E6E7A7AA}") - ) - : (ReferenceObject - :Name (Cactus-Wlan) - :Table (network_objects) - :Uid ("{FFB3BAC5-FD79-4D0B-911A-7413DA524723}") - ) - : (ReferenceObject - :Name (wlan-router) - :Table (network_objects) - :Uid ("{426CC3AD-BE7D-45B6-AAAB-22BA0680EE21}") - ) - :color (black) - :comments () - :member_class (network_object) - :members_query () - :type (group) - ) - : (IsoAAAA-internal-wlan - :AdminInfo ( - :chkpf_uid ("{8A25E764-4E9E-4BAD-A56C-81B80488E392}") - :ClassName (network) - :table (network_objects) - :Wiznum (-1) - :LastModified ( - :Time ("Fri Dec 5 21:40:52 2003") - :By (IsoAAAF) - :From (scratchy) - ) - :name (IsoAAAA-internal-wlan) - ) - :edges () - :NAT () - :add_adtr_rule (false) - :broadcast (allow) - :color (blue) - :comments () - :ipaddr (10.222.0.18) - :location (internal) - :netmask (255.255.255.255) - :operating_system ( - :AdminInfo ( - :chkpf_uid ("{5097D84E-F91D-4A79-BD6A-B6A94CC900B3}") - :ClassName (operating_system) - ) - :name () - :sp () - :version () - ) - :type (network) - ) - : (gateway.local - :AdminInfo ( - :chkpf_uid ("{7ED7EF12-A13E-4303-8A6E-C6CC28755C80}") - :ClassName (host_plain) - :table (network_objects) - :Wiznum (-1) - :LastModified ( - :Time ("Fri Dec 5 23:09:16 2003") - :By (IsoAAAF) - :From (scratchy) - ) - :name (gateway.local) - ) - :certificates () - :edges () - :interfaces () - :NAT () - :read_community () - :sysContact () - :sysDescr () - :sysLocation () - :sysName () - :write_community () - :SNMP ( - :AdminInfo ( - :chkpf_uid ("{7ED7EF12-A13E-4303-8A6E-C6CC28755C80}") - :ClassName (SNMP) - ) - ) - :VPN () - :add_adtr_rule (false) - :color (black) - :comments () - :cp_products_installed (false) - :enforce_gtp_rate_limit (false) - :firewall (not-installed) - :floodgate (not-installed) - :gtp_rate_limit (2048) - :ipaddr (10.222.0.19) - :operating_system ( - :AdminInfo ( - :chkpf_uid ("{40E084FD-FB2F-40AC-AD74-D82956846BDA}") - :ClassName (operating_system) - ) - :name () - :sp () - :version () - ) - :type (host) - ) - : (www.t-online.de - :AdminInfo ( - :chkpf_uid ("{2F2418CB-D1AF-4470-AB97-4D6058666A71}") - :ClassName (host_plain) - :table (network_objects) - :Wiznum (-1) - :LastModified ( - :Time ("Wed Dec 17 21:54:39 2003") - :By (IsoAAAF) - :From (scratchy) - ) - :name (www.t-online.de) - ) - :certificates () - :edges () - :interfaces () - :NAT () - :read_community () - :sysContact () - :sysDescr () - :sysLocation () - :sysName () - :write_community () - :SNMP ( - :AdminInfo ( - :chkpf_uid ("{2F2418CB-D1AF-4470-AB97-4D6058666A71}") - :ClassName (SNMP) - ) - ) - :VPN () - :add_adtr_rule (false) - :color ("deep pink") - :comments () - :cp_products_installed (false) - :enforce_gtp_rate_limit (false) - :firewall (not-installed) - :floodgate (not-installed) - :gtp_rate_limit (2048) - :ipaddr (10.222.0.20) - :operating_system ( - :AdminInfo ( - :chkpf_uid ("{69011F4C-61A3-4695-82C4-25AC0C726615}") - :ClassName (operating_system) - ) - :name () - :sp () - :version () - ) - :type (host) - ) - : (Heag-DSL-ext - :AdminInfo ( - :chkpf_uid ("{27F77C5F-9C50-486D-8003-AA7178B2F6FB}") - :ClassName (host_plain) - :table (network_objects) - :Wiznum (-1) - :LastModified ( - :Time ("Wed Feb 25 19:34:32 2004") - :By (IsoAAAF) - :From (scratchy) - ) - :name (Heag-DSL-ext) - ) - :certificates () - :edges () - :interfaces () - :NAT () - :read_community () - :sysContact () - :sysDescr () - :sysLocation () - :sysName () - :write_community () - :SNMP ( - :AdminInfo ( - :chkpf_uid ("{27F77C5F-9C50-486D-8003-AA7178B2F6FB}") - :ClassName (SNMP) - ) - ) - :VPN () - :add_adtr_rule (false) - :color (gold) - :comments ("external IP of Heag DSL Router") - :cp_products_installed (false) - :enforce_gtp_rate_limit (false) - :firewall (not-installed) - :floodgate (not-installed) - :gtp_rate_limit (2048) - :ipaddr (10.222.0.21) - :operating_system ( - :AdminInfo ( - :chkpf_uid ("{DDDE838A-A815-42D9-AC5D-927510B8148A}") - :ClassName (operating_system) - ) - :name () - :sp () - :version () - ) - :type (host) - ) - : (Cactus-Telefonica - :AdminInfo ( - :chkpf_uid ("{1F2B8DAD-46AD-4E8B-8B94-D7524713EB39}") - :ClassName (network) - :table (network_objects) - :Wiznum (-1) - :LastModified ( - :Time ("Wed Feb 25 19:46:14 2004") - :By (IsoAAAF) - :From (scratchy) - ) - :name (Cactus-Telefonica) - ) - :edges () - :NAT () - :add_adtr_rule (false) - :broadcast (allow) - :color ("forest green") - :comments ("Cactus Official IPs") - :ipaddr (10.222.0.22) - :location (internal) - :netmask (255.255.255.255) - :operating_system ( - :AdminInfo ( - :chkpf_uid ("{4EE2803A-C1AA-4951-B802-D2CF7C587BB9}") - :ClassName (operating_system) - ) - :name () - :sp () - :version () - ) - :type (network) - ) - : (Cactus-Heag - :AdminInfo ( - :chkpf_uid ("{83B5E8DA-0AC8-4B27-9EB4-750F7521EB61}") - :ClassName (network) - :table (network_objects) - :Wiznum (-1) - :LastModified ( - :Time ("Wed Feb 25 19:47:42 2004") - :By (IsoAAAF) - :From (scratchy) - ) - :name (Cactus-Heag) - ) - :edges () - :NAT () - :add_adtr_rule (false) - :broadcast (allow) - :color ("forest green") - :comments ("Cactus Official IPs") - :ipaddr (10.222.0.23) - :location (internal) - :netmask (255.255.255.255) - :operating_system ( - :AdminInfo ( - :chkpf_uid ("{8D0684BB-A091-45F1-90D7-35AC66F6CE2E}") - :ClassName (operating_system) - ) - :name () - :sp () - :version () - ) - :type (network) - ) - : (Cactus-InternetTransfer - :AdminInfo ( - :chkpf_uid ("{408C820D-33A1-4E25-B576-EC826F525DCD}") - :ClassName (network) - :table (network_objects) - :Wiznum (-1) - :LastModified ( - :Time ("Wed Feb 25 20:49:59 2004") - :By (IsoAAAF) - :From (scratchy) - ) - :name (Cactus-InternetTransfer) - ) - :edges () - :NAT () - :add_adtr_rule (false) - :broadcast (allow) - :color (black) - :comments () - :ipaddr (10.222.0.24) - :location (internal) - :netmask (255.255.255.255) - :operating_system ( - :AdminInfo ( - :chkpf_uid ("{019385B1-7834-4C96-A99D-EA1BC5F3B1F3}") - :ClassName (operating_system) - ) - :name () - :sp () - :version () - ) - :type (network) - ) - : (CactusDSL-DHCP - :AdminInfo ( - :chkpf_uid ("{4F363EC1-417F-4F6D-B8DC-21875B3E4AC6}") - :ClassName (address_range) - :table (network_objects) - :Wiznum (-1) - :LastModified ( - :Time ("Wed Feb 25 20:54:55 2004") - :By (IsoAAAF) - :From (scratchy) - ) - :name (CactusDSL-DHCP) - ) - :edges () - :NAT () - :add_adtr_rule (false) - :color (black) - :comments () - :ipaddr_first (10.222.0.25) - :ipaddr_last (10.222.0.26) - :type (machines_range) - ) - : (paybox-10.222.0.27 - :AdminInfo ( - :chkpf_uid ("{2EF7EE27-EB4A-447A-B8FE-8A367BCD19E0}") - :ClassName (network) - :table (network_objects) - :Wiznum (-1) - :object_permissions ( - :AdminInfo ( - :chkpf_uid ("{63E2E2DB-2D24-4B23-9A04-D003371692BE}") - :ClassName (object_permissions) - ) - :manage ( - : (ReferenceObject - :Table (globals) - :Name (Any) - ) - ) - :read ( - : (any) - ) - :use ( - : (any) - ) - :write ( - : () - ) - :owner () - ) - :LastModified ( - :Time ("Sat Feb 15 20:40:34 2003") - :By (tim) - :From (STICHLING) - ) - :name (paybox-10.222.0.27) - ) - :edges () - :NAT () - :add_adtr_rule (false) - :broadcast (allow) - :color (black) - :comments () - :ipaddr (10.222.0.27) - :location (internal) - :netmask (255.255.255.255) - :operating_system ( - :AdminInfo ( - :chkpf_uid ("{D1455603-2D6E-40DE-AACA-B19DA884C309}") - :ClassName (operating_system) - ) - :name () - :sp () - :version () - ) - :type (network) - ) - : (paybox-10.222.0.28 - :AdminInfo ( - :chkpf_uid ("{7BDD2C1E-B632-4342-A7FA-055FB7790AFC}") - :ClassName (network) - :table (network_objects) - :Wiznum (-1) - :object_permissions ( - :AdminInfo ( - :chkpf_uid ("{4C8AAF89-DDF6-4D95-9A6F-76755563FEB7}") - :ClassName (object_permissions) - ) - :manage ( - : (ReferenceObject - :Table (globals) - :Name (Any) - ) - ) - :read ( - : (any) - ) - :use ( - : (any) - ) - :write ( - : () - ) - :owner () - ) - :LastModified ( - :Time ("Sat Feb 15 20:41:12 2003") - :By (tim) - :From (STICHLING) - ) - :name (paybox-10.222.0.28) - ) - :edges () - :NAT () - :add_adtr_rule (false) - :broadcast (allow) - :color (black) - :comments () - :ipaddr (10.222.0.28) - :location (internal) - :netmask (255.255.255.255) - :operating_system ( - :AdminInfo ( - :chkpf_uid ("{79D5131C-B9CF-49FC-BDFF-E57213796A88}") - :ClassName (operating_system) - ) - :name () - :sp () - :version () - ) - :type (network) - ) - : (paybox-10.222.0.29 - :AdminInfo ( - :chkpf_uid ("{30E9FBBC-84F2-4AA5-8E83-3D2FBE17B82B}") - :ClassName (network) - :table (network_objects) - :Wiznum (-1) - :object_permissions ( - :AdminInfo ( - :chkpf_uid ("{3EBAAF92-00D6-41FF-BD92-B00F146CC85A}") - :ClassName (object_permissions) - ) - :manage ( - : (ReferenceObject - :Table (globals) - :Name (Any) - ) - ) - :read ( - : (any) - ) - :use ( - : (any) - ) - :write ( - : () - ) - :owner () - ) - :LastModified ( - :Time ("Sat Feb 15 20:41:50 2003") - :By (tim) - :From (STICHLING) - ) - :name (paybox-10.222.0.29) - ) - :edges () - :NAT () - :add_adtr_rule (false) - :broadcast (allow) - :color (black) - :comments () - :ipaddr (10.222.0.29) - :location (internal) - :netmask (255.255.255.255) - :operating_system ( - :AdminInfo ( - :chkpf_uid ("{8BD04057-F288-44C9-815B-0C6C30BFECD3}") - :ClassName (operating_system) - ) - :name () - :sp () - :version () - ) - :type (network) - ) - : (paybox-10.222.0.30 - :AdminInfo ( - :chkpf_uid ("{A915A86D-0ADD-4FF3-9986-27D96FFB0EAE}") - :ClassName (network) - :table (network_objects) - :Wiznum (-1) - :object_permissions ( - :AdminInfo ( - :chkpf_uid ("{23CB3782-4AD4-44CE-8E17-DA87B28CAA78}") - :ClassName (object_permissions) - ) - :manage ( - : (ReferenceObject - :Table (globals) - :Name (Any) - ) - ) - :read ( - : (any) - ) - :use ( - : (any) - ) - :write ( - : () - ) - :owner () - ) - :LastModified ( - :Time ("Sat Feb 15 20:42:17 2003") - :By (tim) - :From (STICHLING) - ) - :name (paybox-10.222.0.30) - ) - :edges () - :NAT () - :add_adtr_rule (false) - :broadcast (allow) - :color (black) - :comments () - :ipaddr (10.222.0.30) - :location (internal) - :netmask (255.255.255.255) - :operating_system ( - :AdminInfo ( - :chkpf_uid ("{1ADD6F6C-BC1D-4E8C-B82F-71C079A91DAA}") - :ClassName (operating_system) - ) - :name () - :sp () - :version () - ) - :type (network) - ) - : (paybox-10.222.0.31 - :AdminInfo ( - :chkpf_uid ("{40032AA5-60A7-4F1B-AB53-96695880ED25}") - :ClassName (network) - :table (network_objects) - :Wiznum (-1) - :object_permissions ( - :AdminInfo ( - :chkpf_uid ("{4A88E9A8-AAE3-45D1-B703-DAB2DB5582D0}") - :ClassName (object_permissions) - ) - :manage ( - : (ReferenceObject - :Table (globals) - :Name (Any) - ) - ) - :read ( - : (any) - ) - :use ( - : (any) - ) - :write ( - : () - ) - :owner () - ) - :LastModified ( - :Time ("Sat Feb 15 20:42:51 2003") - :By (tim) - :From (STICHLING) - ) - :name (paybox-10.222.0.31) - ) - :edges () - :NAT () - :add_adtr_rule (false) - :broadcast (allow) - :color (black) - :comments (gateway) - :ipaddr (10.222.0.31) - :location (internal) - :netmask (255.255.255.255) - :operating_system ( - :AdminInfo ( - :chkpf_uid ("{40D1A5E5-DB0C-457E-AC81-70F174E54B36}") - :ClassName (operating_system) - ) - :name () - :sp () - :version () - ) - :type (network) - ) - : (paybox-alle-netze - :AdminInfo ( - :chkpf_uid ("{17EB75CC-2538-48EF-809F-C5C5D808214A}") - :ClassName (network_object_group) - :table (network_objects) - :Wiznum (-1) - :object_permissions ( - :AdminInfo ( - :chkpf_uid ("{502DBDBD-EE2E-4729-9294-B6A8C75861F3}") - :ClassName (object_permissions) - ) - :manage ( - : (ReferenceObject - :Table (globals) - :Name (Any) - ) - ) - :read ( - : (any) - ) - :use ( - : (any) - ) - :write ( - : () - ) - :owner () - ) - :LastModified ( - :Time ("Sat Feb 15 20:51:53 2003") - :By (tim) - :From (STICHLING) - ) - :name (paybox-alle-netze) - ) - : (ReferenceObject - :Table (network_objects) - :Name (paybox-raunheim) - :Uid ("{0A1725B4-534D-46F1-A8C0-02C3351C8312}") - ) - :color (black) - :comments () - :member_class (network_object) - :members_query () - :type (group) - ) - : (paybox-10.30.0 - :AdminInfo ( - :chkpf_uid ("{D4C16451-2329-4472-A5B7-57B81057B2C8}") - :ClassName (network) - :object_permissions ( - :AdminInfo ( - :chkpf_uid ("{F033472D-1808-46FA-BE3E-611CAD75F23E}") - :ClassName (object_permissions) - ) - :manage ( - : (ReferenceObject - :Table (globals) - :Name (Any) - ) - ) - :read ( - : (any) - ) - :use ( - : (any) - ) - :write ( - : () - ) - :owner () - ) - :table (network_objects) - :Wiznum (-1) - :LastModified ( - :Time ("Sat Feb 22 20:39:16 2003") - :By (IsoAAAF) - :From (scratchy) - ) - :name (paybox-10.30.0) - ) - :edges () - :NAT () - :add_adtr_rule (false) - :broadcast (allow) - :color (black) - :comments () - :ipaddr (10.222.0.32) - :location (internal) - :netmask (255.255.255.255) - :operating_system ( - :AdminInfo ( - :chkpf_uid ("{E3E0DB32-3359-476D-A635-32007BD47E1D}") - :ClassName (operating_system) - ) - :name () - :sp () - :version () - ) - :type (network) - ) - : (paybox-frankfurt - :AdminInfo ( - :chkpf_uid ("{463C45CA-0C86-42DC-9B02-E83E28764370}") - :ClassName (network_object_group) - :table (network_objects) - :Wiznum (-1) - :object_permissions ( - :AdminInfo ( - :chkpf_uid ("{80AFD32D-59B8-43A3-A3A7-C3EA05E23367}") - :ClassName (object_permissions) - ) - :manage ( - : (ReferenceObject - :Table (globals) - :Name (Any) - ) - ) - :read ( - : (any) - ) - :use ( - : (any) - ) - :write ( - : () - ) - :owner () - ) - :LastModified ( - :Time ("Sat Feb 22 20:39:52 2003") - :By (IsoAAAF) - :From (scratchy) - ) - :name (paybox-frankfurt) - ) - : (ReferenceObject - :Name (paybox-10.30.0) - :Table (network_objects) - :Uid ("{D4C16451-2329-4472-A5B7-57B81057B2C8}") - ) - : (ReferenceObject - :Name (paybox-213.70.103) - :Table (network_objects) - :Uid ("{C5AE7301-030D-4C4E-9E63-AB4053BEB2AC}") - ) - :color (black) - :comments () - :member_class (network_object) - :members_query () - :type (group) - ) - : (paybox-213.69.149 - :AdminInfo ( - :chkpf_uid ("{E9026D53-F670-4739-B9C3-1AE97B9FBE15}") - :ClassName (network) - :table (network_objects) - :Wiznum (-1) - :object_permissions ( - :AdminInfo ( - :chkpf_uid ("{7B26CCF6-E04E-4B55-95E0-D8C29A5AE5A5}") - :ClassName (object_permissions) - ) - :manage ( - : (ReferenceObject - :Table (globals) - :Name (Any) - ) - ) - :read ( - : (any) - ) - :use ( - : (any) - ) - :write ( - : () - ) - :owner () - ) - :LastModified ( - :Time ("Tue Jul 15 16:27:21 2003") - :By (stephan) - :From (vaio) - ) - :name (paybox-213.69.149) - ) - :edges () - :NAT () - :add_adtr_rule (false) - :broadcast (allow) - :color (black) - :comments ("10.222.0.33/32") - :ipaddr (10.222.0.33) - :location (internal) - :netmask (255.255.255.255) - :operating_system ( - :AdminInfo ( - :chkpf_uid ("{3CBBF669-133A-4808-B3E7-B4C94DBF081C}") - :ClassName (operating_system) - ) - :name () - :sp () - :version () - ) - :type (network) - ) - : (paybox-213.70.103 - :AdminInfo ( - :chkpf_uid ("{C5AE7301-030D-4C4E-9E63-AB4053BEB2AC}") - :ClassName (network) - :table (network_objects) - :Wiznum (-1) - :object_permissions ( - :AdminInfo ( - :chkpf_uid ("{A3E49847-44E5-4C29-A011-B710399F1881}") - :ClassName (object_permissions) - ) - :manage ( - : (ReferenceObject - :Table (globals) - :Name (Any) - ) - ) - :read ( - : (any) - ) - :use ( - : (any) - ) - :write ( - : () - ) - :owner () - ) - :LastModified ( - :Time ("Tue Jul 15 16:27:21 2003") - :By (stephan) - :From (vaio) - ) - :name (paybox-213.70.103) - ) - :edges () - :NAT () - :add_adtr_rule (false) - :broadcast (allow) - :color (black) - :comments ("10.222.0.34/32") - :ipaddr (10.222.0.34) - :location (internal) - :netmask (255.255.255.255) - :operating_system ( - :AdminInfo ( - :chkpf_uid ("{114183D4-4482-4D60-894D-EFD8222BD4E8}") - :ClassName (operating_system) - ) - :name () - :sp () - :version () - ) - :type (network) - ) - : (paybox-raunheim - :AdminInfo ( - :chkpf_uid ("{0A1725B4-534D-46F1-A8C0-02C3351C8312}") - :ClassName (network_object_group) - :object_permissions ( - :AdminInfo ( - :chkpf_uid ("{94774A3C-1D92-412B-A220-6AAB0D9EEF51}") - :ClassName (object_permissions) - ) - :manage ( - : (ReferenceObject - :Table (globals) - :Name (Any) - ) - ) - :read ( - : (any) - ) - :use ( - : (any) - ) - :write ( - : () - ) - :owner () - ) - :table (network_objects) - :Wiznum (-1) - :LastModified ( - :Time ("Mon Jul 21 19:28:32 2003") - :By (IsoAAAF) - :From (scratchy) - ) - :name (paybox-raunheim) - ) - : (ReferenceObject - :Name (paybox-10.222.0.27) - :Table (network_objects) - :Uid ("{2EF7EE27-EB4A-447A-B8FE-8A367BCD19E0}") - ) - : (ReferenceObject - :Name (paybox-10.222.0.28) - :Table (network_objects) - :Uid ("{7BDD2C1E-B632-4342-A7FA-055FB7790AFC}") - ) - : (ReferenceObject - :Name (paybox-10.222.0.29) - :Table (network_objects) - :Uid ("{30E9FBBC-84F2-4AA5-8E83-3D2FBE17B82B}") - ) - : (ReferenceObject - :Name (paybox-10.222.0.31) - :Table (network_objects) - :Uid ("{40032AA5-60A7-4F1B-AB53-96695880ED25}") - ) - : (ReferenceObject - :Name (paybox-10.222.0.30) - :Table (network_objects) - :Uid ("{A915A86D-0ADD-4FF3-9986-27D96FFB0EAE}") - ) - : (ReferenceObject - :Name (paybox-213.70.103) - :Table (network_objects) - :Uid ("{C5AE7301-030D-4C4E-9E63-AB4053BEB2AC}") - ) - :color (black) - :comments () - :member_class (network_object) - :members_query () - :type (group) - ) - : (IsoAAAD_eth1 - :AdminInfo ( - :chkpf_uid ("{932BDE10-E9C1-4DD6-AB1D-11D57CE91F00}") - :ClassName (network_object_group) - :table (network_objects) - :Wiznum (-1) - :LastModified ( - :Time ("Thu Apr 1 17:11:35 2004") - :By (holger) - :From (dragonfly) - ) - :name (IsoAAAD_eth1) - ) - : (ReferenceObject - :Name (IsoAAAA-100) - :Table (network_objects) - :Uid ("{BF1C6029-8D5D-4A05-A3AD-4B67E6E7A7AA}") - ) - : (ReferenceObject - :Name (t-online) - :Table (network_objects) - :Uid ("{C3D65C4B-6498-4E00-9BAF-15539231E8EE}") - ) - :color (Foreground) - :comments () - :member_class (network_object) - :members_query () - :type (group) - ) - : (IsoAAAA-100 - :AdminInfo ( - :chkpf_uid ("{BF1C6029-8D5D-4A05-A3AD-4B67E6E7A7AA}") - :ClassName (network) - :object_permissions ( - :AdminInfo ( - :chkpf_uid ("{0461DB3A-AC66-4603-9264-9646289CDFF0}") - :ClassName (object_permissions) - ) - :manage ( - : (ReferenceObject - :Table (globals) - :Name (Any) - ) - ) - :read ( - : (any) - ) - :use ( - : (any) - ) - :write ( - : () - ) - :owner () - ) - :table (network_objects) - :Wiznum (-1) - :LastModified ( - :Time ("Thu May 6 12:15:56 2004") - :By (andre) - :From (gateway) - ) - :name (IsoAAAA-100) - ) - :edges () - :NAT () - :add_adtr_rule (false) - :broadcast (disallow) - :color (black) - :comments () - :ipaddr (10.222.0.35) - :location (internal) - :netmask (255.255.255.255) - :operating_system ( - :AdminInfo ( - :chkpf_uid ("{392661F1-45BC-4F78-AD42-B6A199EFB38D}") - :ClassName (operating_system) - ) - :name () - :sp () - :version () - ) - :type (network) - ) - : (daba - :AdminInfo ( - :chkpf_uid ("{94817CDB-EA8C-4213-B38D-F4417EA620C6}") - :ClassName (host_plain) - :table (network_objects) - :Wiznum (-1) - :LastModified ( - :Time ("Sun Aug 1 12:48:13 2004") - :By (tim) - :From (pieks) - ) - :name (daba) - ) - :read_community () - :sysContact () - :sysDescr () - :sysLocation () - :sysName () - :write_community () - :add_adtr_rule (false) - :certificates () - :edges () - :enforce_gtp_rate_limit (false) - :gtp_rate_limit (2048) - :interfaces () - :operating_system ( - :AdminInfo ( - :chkpf_uid ("{87E22239-B653-4FFC-AEBF-05E54A5FAC2B}") - :ClassName (operating_system) - ) - :name () - :sp () - :version () - ) - :NAT () - :SNMP () - :VPN () - :additional_products () - :color (black) - :comments ("database server") - :cp_products_installed (false) - :firewall (not-installed) - :floodgate (not-installed) - :ipaddr (10.222.0.36) - :type (host) - ) - : (allNet - :AdminInfo ( - :chkpf_uid ("{8C20ECB8-A6DB-4C35-B79A-D12ECE559C77}") - :ClassName (address_range) - :table (network_objects) - :Wiznum (-1) - :LastModified ( - :Time ("Tue Aug 17 21:33:42 2004") - :By (IsoAAAF) - :From (IsoAAADray) - ) - :name (allNet) - ) - :add_adtr_rule (false) - :edges () - :NAT () - :color (black) - :comments (everything) - :ipaddr_first (0.0.0.0) - :ipaddr_last (255.255.255.255) - :type (machines_range) - ) - : (IsoAAAA_home_stephan - :AdminInfo ( - :chkpf_uid ("{B86B46D5-DCB5-4A25-A0B6-766D78D30780}") - :ClassName (network) - :table (network_objects) - :Wiznum (-1) - :LastModified ( - :Time ("Thu Sep 16 16:38:51 2004") - :By (stephan) - :From (gateway) - ) - :name (IsoAAAA_home_stephan) - ) - :add_adtr_rule (false) - :edges () - :location (internal) - :operating_system ( - :AdminInfo ( - :chkpf_uid ("{F1BDDF41-0018-425A-BC22-16B4152381BF}") - :ClassName (operating_system) - ) - :name () - :sp () - :version () - ) - :NAT () - :broadcast (allow) - :color (black) - :comments ("Stephan's Netze") - :ipaddr (10.222.0.37) - :netmask (255.255.255.255) - :type (network) - ) - : (IsoAAAA_home_tim - :AdminInfo ( - :chkpf_uid ("{BF8F69B9-87C2-464A-9404-239AE8DF66B3}") - :ClassName (network) - :table (network_objects) - :Wiznum (-1) - :LastModified ( - :Time ("Thu Sep 16 16:39:22 2004") - :By (stephan) - :From (gateway) - ) - :name (IsoAAAA_home_tim) - ) - :edges () - :NAT () - :add_adtr_rule (false) - :broadcast (allow) - :color (green) - :comments ("10.222.0.38/32") - :ipaddr (10.222.0.38) - :location (internal) - :netmask (255.255.255.255) - :operating_system ( - :AdminInfo ( - :chkpf_uid ("{E9B5F7A4-CC68-41C2-BE23-DF0A2D54E0D7}") - :ClassName (operating_system) - ) - :name () - :sp () - :version () - ) - :type (network) - ) - : (Cactus_home_test_2 - :AdminInfo ( - :chkpf_uid ("{3CB93962-2930-41A7-8067-FC373151BB91}") - :ClassName (host_plain) - :table (network_objects) - :Wiznum (-1) - :LastModified ( - :Time ("Wed Sep 22 13:27:12 2004") - :By (stephan) - :From (gateway) - ) - :name (Cactus_home_test_2) - ) - :read_community () - :sysContact () - :sysDescr () - :sysLocation () - :sysName () - :write_community () - :add_adtr_rule (false) - :certificates () - :edges () - :enforce_gtp_rate_limit (false) - :gtp_rate_limit (2048) - :interfaces () - :operating_system ( - :AdminInfo ( - :chkpf_uid ("{90366C6B-50ED-4AD3-AB1E-73DDD97F0C32}") - :ClassName (operating_system) - ) - :name () - :sp () - :version () - ) - :NAT () - :SNMP () - :VPN () - :additional_products () - :color (black) - :comments ("nat, war frei f�r test") - :cp_products_installed (false) - :firewall (not-installed) - :floodgate (not-installed) - :ipaddr (10.222.0.39) - :type (host) - ) - : (IsoAAAA_home_test_3 - :AdminInfo ( - :chkpf_uid ("{3B37A3DE-4411-4FFC-9E54-3ABC5C4F693B}") - :ClassName (host_plain) - :table (network_objects) - :Wiznum (-1) - :LastModified ( - :Time ("Wed Sep 22 13:29:00 2004") - :By (stephan) - :From (gateway) - ) - :name (IsoAAAA_home_test_3) - ) - :read_community () - :sysContact () - :sysDescr () - :sysLocation () - :sysName () - :write_community () - :add_adtr_rule (false) - :certificates () - :edges () - :enforce_gtp_rate_limit (false) - :gtp_rate_limit (2048) - :interfaces () - :operating_system ( - :AdminInfo ( - :chkpf_uid ("{615B2573-914D-483E-94BF-88142A4E938D}") - :ClassName (operating_system) - ) - :name () - :sp () - :version () - ) - :NAT () - :SNMP () - :VPN () - :additional_products () - :color (black) - :comments (orig_source) - :cp_products_installed (false) - :firewall (not-installed) - :floodgate (not-installed) - :ipaddr (10.222.0.40) - :type (host) - ) - : (hpux - :AdminInfo ( - :chkpf_uid ("{BF00A847-A0D6-4A75-BE1C-27E7D91EDB55}") - :ClassName (host_plain) - :table (network_objects) - :Wiznum (-1) - :LastModified ( - :Time ("Mon Sep 27 07:52:27 2004") - :By (tim) - :From (pieks) - ) - :name (hpux) - ) - :read_community () - :sysContact () - :sysDescr () - :sysLocation () - :sysName () - :write_community () - :add_adtr_rule (false) - :certificates () - :edges () - :enforce_gtp_rate_limit (false) - :gtp_rate_limit (2048) - :interfaces () - :operating_system ( - :AdminInfo ( - :chkpf_uid ("{2607915D-F3D5-43F8-B6C3-599AA00195B3}") - :ClassName (operating_system) - ) - :name () - :sp () - :version () - ) - :NAT () - :SNMP () - :VPN () - :additional_products () - :color (black) - :comments ("hp-ux-test for hardening") - :cp_products_installed (false) - :firewall (not-installed) - :floodgate (not-installed) - :ipaddr (10.222.0.41) - :type (host) - ) - : (Cactus-Official - :AdminInfo ( - :chkpf_uid ("{2136B4E8-3ABF-4931-BDB9-12CDF457D4A4}") - :ClassName (network_object_group) - :table (network_objects) - :Wiznum (-1) - :LastModified ( - :Time ("Wed Sep 29 20:26:37 2004") - :By (IsoAAAF) - :From (IsoAAADray) - ) - :name (Cactus-Official) - ) - :members_query () - : (ReferenceObject - :Name (Cactus-Heag) - :Table (network_objects) - :Uid ("{83B5E8DA-0AC8-4B27-9EB4-750F7521EB61}") - ) - : (ReferenceObject - :Name (Cactus-Telefonica) - :Table (network_objects) - :Uid ("{1F2B8DAD-46AD-4E8B-8B94-D7524713EB39}") - ) - :color (black) - :comments () - :member_class (network_object) - :type (group) - ) - : (IsoAAAD_extern - :AdminInfo ( - :chkpf_uid ("{DB456CE7-0DCA-423F-A5E4-9FA976C0B594}") - :ClassName (host_plain) - :table (network_objects) - :Wiznum (-1) - :LastModified ( - :Time ("Wed Sep 29 20:28:11 2004") - :By (IsoAAAF) - :From (IsoAAADray) - ) - :name (IsoAAAD_extern) - ) - :read_community () - :sysContact () - :sysDescr () - :sysLocation () - :sysName () - :write_community () - :add_adtr_rule (false) - :certificates () - :edges () - :enforce_gtp_rate_limit (false) - :gtp_rate_limit (2048) - :interfaces () - :operating_system ( - :AdminInfo ( - :chkpf_uid ("{E10D68CF-49A0-49E2-BD41-F3501F9AC613}") - :ClassName (operating_system) - ) - :name () - :sp () - :version () - ) - :NAT () - :SNMP () - :VPN () - :additional_products () - :color (green) - :comments () - :cp_products_installed (false) - :firewall (not-installed) - :floodgate (not-installed) - :ipaddr (10.222.0.42) - :type (host) - ) - : (Cactus-DMZ1 - :AdminInfo ( - :chkpf_uid ("{62523F8E-9AE0-4CC0-82C6-BB41846BA2B7}") - :ClassName (network) - :table (network_objects) - :Wiznum (-1) - :LastModified ( - :Time ("Wed Sep 29 20:30:05 2004") - :By (IsoAAAF) - :From (IsoAAADray) - ) - :name (Cactus-DMZ1) - ) - :add_adtr_rule (false) - :edges () - :location (internal) - :operating_system ( - :AdminInfo ( - :chkpf_uid ("{A36075C6-6E18-44CD-AA68-156B28425E7C}") - :ClassName (operating_system) - ) - :name () - :sp () - :version () - ) - :NAT () - :broadcast (allow) - :color ("forest green") - :comments ("10.222.0.22/32") - :ipaddr (10.222.0.22) - :netmask (255.255.255.255) - :type (network) - ) - : (Cactus-DMZ2 - :AdminInfo ( - :chkpf_uid ("{61AB70E0-5514-43CF-9194-B37A13EC102D}") - :ClassName (network) - :table (network_objects) - :Wiznum (-1) - :LastModified ( - :Time ("Wed Sep 29 20:30:56 2004") - :By (IsoAAAF) - :From (IsoAAADray) - ) - :name (Cactus-DMZ2) - ) - :add_adtr_rule (false) - :edges () - :location (internal) - :operating_system ( - :AdminInfo ( - :chkpf_uid ("{9560D37A-C58D-4BED-9BA7-012AFD867887}") - :ClassName (operating_system) - ) - :name () - :sp () - :version () - ) - :NAT () - :broadcast (allow) - :color ("forest green") - :comments ("10.222.0.43/32") - :ipaddr (10.222.0.43) - :netmask (255.255.255.255) - :type (network) - ) - : (Cactus-DMZ3 - :AdminInfo ( - :chkpf_uid ("{DE80C48A-20E5-4396-BBA2-9E0AE9B95383}") - :ClassName (network) - :table (network_objects) - :Wiznum (-1) - :LastModified ( - :Time ("Wed Sep 29 20:32:05 2004") - :By (IsoAAAF) - :From (IsoAAADray) - ) - :name (Cactus-DMZ3) - ) - :add_adtr_rule (false) - :edges () - :location (internal) - :operating_system ( - :AdminInfo ( - :chkpf_uid ("{C6B94E29-F2A7-44C9-B730-F5B6757F6C63}") - :ClassName (operating_system) - ) - :name () - :sp () - :version () - ) - :NAT () - :broadcast (allow) - :color ("forest green") - :comments ("10.222.0.23/32") - :ipaddr (10.222.0.23) - :netmask (255.255.255.255) - :type (network) - ) - : (speedy2 - :AdminInfo ( - :chkpf_uid ("{B4DB2EF5-42D8-41DC-9A1C-33310FDFB184}") - :ClassName (host_plain) - :table (network_objects) - :Wiznum (-1) - :LastModified ( - :Time ("Wed Sep 29 20:39:12 2004") - :By (IsoAAAF) - :From (IsoAAADray) - ) - :name (speedy2) - ) - :read_community () - :sysContact () - :sysDescr () - :sysLocation () - :sysName () - :write_community () - :add_adtr_rule (false) - :certificates () - :edges () - :enforce_gtp_rate_limit (false) - :gtp_rate_limit (2048) - :interfaces () - :operating_system ( - :AdminInfo ( - :chkpf_uid ("{57F30020-0328-467D-8FBE-0B565E807D9F}") - :ClassName (operating_system) - ) - :name () - :sp () - :version () - ) - :NAT () - :SNMP () - :VPN () - :additional_products () - :color (orange) - :comments ("Silkes Rechner") - :cp_products_installed (false) - :firewall (not-installed) - :floodgate (not-installed) - :ipaddr (10.222.0.44) - :type (host) - ) - : (www.t-update.de - :AdminInfo ( - :chkpf_uid ("{8F3990BA-9B98-4260-888D-100CA19D688F}") - :ClassName (host_plain) - :table (network_objects) - :Wiznum (-1) - :LastModified ( - :Time ("Wed Sep 29 21:19:50 2004") - :By (IsoAAAF) - :From (scratchy) - ) - :name (www.t-update.de) - ) - :read_community () - :sysContact () - :sysDescr () - :sysLocation () - :sysName () - :write_community () - :add_adtr_rule (false) - :certificates () - :edges () - :enforce_gtp_rate_limit (false) - :gtp_rate_limit (2048) - :interfaces () - :operating_system ( - :AdminInfo ( - :chkpf_uid ("{47B256C1-6339-44A4-A5B3-814C177025F1}") - :ClassName (operating_system) - ) - :name () - :sp () - :version () - ) - :NAT () - :SNMP () - :VPN () - :additional_products () - :color ("deep pink") - :comments () - :cp_products_installed (false) - :firewall (not-installed) - :floodgate (not-installed) - :ipaddr (10.222.0.45) - :type (host) - ) - : (www1.sda.t-online.de - :AdminInfo ( - :chkpf_uid ("{01ADF4A6-6639-4CD9-9336-A3D2CC0182B9}") - :ClassName (host_plain) - :table (network_objects) - :Wiznum (-1) - :LastModified ( - :Time ("Wed Sep 29 21:22:15 2004") - :By (IsoAAAF) - :From (scratchy) - ) - :name (www1.sda.t-online.de) - ) - :read_community () - :sysContact () - :sysDescr () - :sysLocation () - :sysName () - :write_community () - :add_adtr_rule (false) - :certificates () - :edges () - :enforce_gtp_rate_limit (false) - :gtp_rate_limit (2048) - :interfaces () - :operating_system ( - :AdminInfo ( - :chkpf_uid ("{738A5B60-ADE1-4631-8861-E4DB4453DD30}") - :ClassName (operating_system) - ) - :name () - :sp () - :version () - ) - :NAT () - :SNMP () - :VPN () - :additional_products () - :color ("deep pink") - :comments () - :cp_products_installed (false) - :firewall (not-installed) - :floodgate (not-installed) - :ipaddr (10.222.0.46) - :type (host) - ) - : (update2.t-online - :AdminInfo ( - :chkpf_uid ("{DFBF3C44-7C42-4FA0-A73F-2DA57B106127}") - :ClassName (host_plain) - :table (network_objects) - :Wiznum (-1) - :LastModified ( - :Time ("Wed Sep 29 21:24:02 2004") - :By (IsoAAAF) - :From (scratchy) - ) - :name (update2.t-online) - ) - :read_community () - :sysContact () - :sysDescr () - :sysLocation () - :sysName () - :write_community () - :add_adtr_rule (false) - :certificates () - :edges () - :enforce_gtp_rate_limit (false) - :gtp_rate_limit (2048) - :interfaces () - :operating_system ( - :AdminInfo ( - :chkpf_uid ("{F377E73F-A48F-4286-9305-E505B1C4B79F}") - :ClassName (operating_system) - ) - :name () - :sp () - :version () - ) - :NAT () - :SNMP () - :VPN () - :additional_products () - :color ("deep pink") - :comments () - :cp_products_installed (false) - :firewall (not-installed) - :floodgate (not-installed) - :ipaddr (10.222.0.47) - :type (host) - ) - : (t-onlineUpdate - :AdminInfo ( - :chkpf_uid ("{99089D97-0EB3-4CE6-8C78-79BC61ECE307}") - :ClassName (network_object_group) - :table (network_objects) - :Wiznum (-1) - :LastModified ( - :Time ("Wed Sep 29 21:25:01 2004") - :By (IsoAAAF) - :From (scratchy) - ) - :name (t-onlineUpdate) - ) - :members_query () - : (ReferenceObject - :Name (update2.t-online) - :Table (network_objects) - :Uid ("{DFBF3C44-7C42-4FA0-A73F-2DA57B106127}") - ) - : (ReferenceObject - :Name (www.t-update.de) - :Table (network_objects) - :Uid ("{8F3990BA-9B98-4260-888D-100CA19D688F}") - ) - : (ReferenceObject - :Name (www1.sda.t-online.de) - :Table (network_objects) - :Uid ("{01ADF4A6-6639-4CD9-9336-A3D2CC0182B9}") - ) - :color ("deep pink") - :comments () - :member_class (network_object) - :type (group) - ) - : (auth1.lhsystems.com - :AdminInfo ( - :chkpf_uid ("{D60E902E-4BE8-43E0-95DC-BFE60E86965F}") - :ClassName (host_plain) - :table (network_objects) - :Wiznum (-1) - :LastModified ( - :Time ("Thu Sep 30 07:20:12 2004") - :By (IsoAAAF) - :From (scratchy) - ) - :name (auth1.lhsystems.com) - ) - :read_community () - :sysContact () - :sysDescr () - :sysLocation () - :sysName () - :write_community () - :add_adtr_rule (false) - :certificates () - :edges () - :enforce_gtp_rate_limit (false) - :gtp_rate_limit (2048) - :interfaces () - :operating_system ( - :AdminInfo ( - :chkpf_uid ("{5296EABE-CD28-417D-B3F6-26D44B7A6929}") - :ClassName (operating_system) - ) - :name () - :sp () - :version () - ) - :NAT () - :SNMP () - :VPN () - :additional_products () - :color (firebrick) - :comments () - :cp_products_installed (false) - :firewall (not-installed) - :floodgate (not-installed) - :ipaddr (10.222.0.48) - :type (host) - ) - : (LSYI-pptp - :AdminInfo ( - :chkpf_uid ("{DF2F1A45-9938-4006-A550-0421F3DAA3E2}") - :ClassName (network) - :table (network_objects) - :Wiznum (-1) - :LastModified ( - :Time ("Thu Sep 30 07:22:17 2004") - :By (IsoAAAF) - :From (scratchy) - ) - :name (LSYI-pptp) - ) - :add_adtr_rule (false) - :edges () - :location (internal) - :operating_system ( - :AdminInfo ( - :chkpf_uid ("{808DE519-4384-40CA-A3B4-1C12A22D03A9}") - :ClassName (operating_system) - ) - :name () - :sp () - :version () - ) - :NAT () - :broadcast (allow) - :color (gold) - :comments ("10.222.0.49/32") - :ipaddr (10.222.0.49) - :netmask (255.255.255.255) - :type (network) - ) - : (IP-255 - :AdminInfo ( - :chkpf_uid ("{589C570C-0905-4946-9736-9BD05B95FBF6}") - :ClassName (host_plain) - :table (network_objects) - :Wiznum (-1) - :LastModified ( - :Time ("Thu Sep 30 07:29:36 2004") - :By (IsoAAAF) - :From (scratchy) - ) - :name (IP-255) - ) - :read_community () - :sysContact () - :sysDescr () - :sysLocation () - :sysName () - :write_community () - :add_adtr_rule (false) - :certificates () - :edges () - :enforce_gtp_rate_limit (false) - :gtp_rate_limit (2048) - :interfaces () - :operating_system ( - :AdminInfo ( - :chkpf_uid ("{554786B0-07BA-4411-BF5C-F110F4CDF47C}") - :ClassName (operating_system) - ) - :name () - :sp () - :version () - ) - :NAT () - :SNMP () - :VPN () - :additional_products () - :color (black) - :comments () - :cp_products_installed (false) - :firewall (not-installed) - :floodgate (not-installed) - :ipaddr (255.255.255.255) - :type (host) - ) - : (Drop_nologDest - :AdminInfo ( - :chkpf_uid ("{79369987-B128-4B3F-827C-3C936F7C3F53}") - :ClassName (network_object_group) - :table (network_objects) - :Wiznum (-1) - :LastModified ( - :Time ("Thu Sep 30 07:29:41 2004") - :By (IsoAAAF) - :From (scratchy) - ) - :name (Drop_nologDest) - ) - :members_query () - : (ReferenceObject - :Name (IP-255) - :Table (network_objects) - :Uid ("{589C570C-0905-4946-9736-9BD05B95FBF6}") - ) - :color (black) - :comments () - :member_class (network_object) - :type (group) - ) - : (spike.local - :AdminInfo ( - :chkpf_uid ("{4ABDD8DE-0DA2-46E5-B129-85E3977CBD18}") - :ClassName (host_plain) - :table (network_objects) - :Wiznum (-1) - :LastModified ( - :Time ("Thu Sep 30 08:43:06 2004") - :By (IsoAAAF) - :From (scratchy) - ) - :name (spike.local) - ) - :certificates () - :edges () - :interfaces () - :NAT () - :read_community () - :sysContact () - :sysDescr () - :sysLocation () - :sysName () - :write_community () - :SNMP ( - :AdminInfo ( - :chkpf_uid ("{4ABDD8DE-0DA2-46E5-B129-85E3977CBD18}") - :ClassName (SNMP) - ) - ) - :VPN () - :add_adtr_rule (false) - :additional_products () - :color (black) - :comments () - :cp_products_installed (false) - :enforce_gtp_rate_limit (false) - :firewall (not-installed) - :floodgate (not-installed) - :gtp_rate_limit (2048) - :ipaddr (10.222.0.50) - :operating_system ( - :AdminInfo ( - :chkpf_uid ("{80CBD075-13E9-4F84-BCA5-32D480915D3B}") - :ClassName (operating_system) - ) - :name () - :sp () - :version () - ) - :type (host) - ) - : (LSYI-WWA - :AdminInfo ( - :chkpf_uid ("{3ECB1B79-1A26-41A3-90F9-71BE179A7211}") - :ClassName (network_object_group) - :table (network_objects) - :Wiznum (-1) - :LastModified ( - :Time ("Thu Sep 30 10:09:48 2004") - :By (IsoAAAF) - :From (scratchy) - ) - :name (LSYI-WWA) - ) - :members_query () - : (ReferenceObject - :Name (auth1.lhsystems.com) - :Table (network_objects) - :Uid ("{D60E902E-4BE8-43E0-95DC-BFE60E86965F}") - ) - : (ReferenceObject - :Name (LSYI-pptp) - :Table (network_objects) - :Uid ("{DF2F1A45-9938-4006-A550-0421F3DAA3E2}") - ) - :color (gold) - :comments () - :member_class (network_object) - :type (group) - ) - : (mail.hayn.de - :AdminInfo ( - :chkpf_uid ("{741A5834-3EA7-4899-92F4-3B365DDBCD98}") - :ClassName (host_plain) - :table (network_objects) - :Wiznum (-1) - :LastModified ( - :Time ("Thu Sep 30 16:34:01 2004") - :By (IsoAAAF) - :From (IsoAAADray) - ) - :name (mail.hayn.de) - ) - :read_community () - :sysContact () - :sysDescr () - :sysLocation () - :sysName () - :write_community () - :add_adtr_rule (false) - :certificates () - :edges () - :enforce_gtp_rate_limit (false) - :gtp_rate_limit (2048) - :interfaces () - :operating_system ( - :AdminInfo ( - :chkpf_uid ("{2581BB20-10CA-4806-8E36-0020A5BE895B}") - :ClassName (operating_system) - ) - :name () - :sp () - :version () - ) - :NAT () - :SNMP () - :VPN () - :additional_products () - :color (blue) - :comments () - :cp_products_installed (false) - :firewall (not-installed) - :floodgate (not-installed) - :ipaddr (10.222.0.51) - :type (host) - ) - : (mail.purschke.de - :AdminInfo ( - :chkpf_uid ("{8EFADE68-A4E4-4BF3-B2C4-EDBD81769700}") - :ClassName (host_plain) - :table (network_objects) - :Wiznum (-1) - :LastModified ( - :Time ("Thu Sep 30 16:34:18 2004") - :By (IsoAAAF) - :From (IsoAAADray) - ) - :name (mail.purschke.de) - ) - :read_community () - :sysContact () - :sysDescr () - :sysLocation () - :sysName () - :write_community () - :add_adtr_rule (false) - :certificates () - :edges () - :enforce_gtp_rate_limit (false) - :gtp_rate_limit (2048) - :interfaces () - :operating_system ( - :AdminInfo ( - :chkpf_uid ("{A4BD025C-525F-4C40-86BF-A4F93BC60B4C}") - :ClassName (operating_system) - ) - :name () - :sp () - :version () - ) - :NAT () - :SNMP () - :VPN () - :additional_products () - :color (blue) - :comments () - :cp_products_installed (false) - :firewall (not-installed) - :floodgate (not-installed) - :ipaddr (10.222.0.52) - :type (host) - ) - : (mail.IsoAAAA.de - :AdminInfo ( - :chkpf_uid ("{98537EEE-D16C-4C24-940F-6880836A7350}") - :ClassName (host_plain) - :table (network_objects) - :Wiznum (-1) - :LastModified ( - :Time ("Thu Sep 30 16:34:41 2004") - :By (IsoAAAF) - :From (IsoAAADray) - ) - :name (mail.IsoAAAA.de) - ) - :read_community () - :sysContact () - :sysDescr () - :sysLocation () - :sysName () - :write_community () - :add_adtr_rule (false) - :certificates () - :edges () - :enforce_gtp_rate_limit (false) - :gtp_rate_limit (2048) - :interfaces () - :operating_system ( - :AdminInfo ( - :chkpf_uid ("{11B9ACD9-8F60-4611-A33D-D79FFE94455C}") - :ClassName (operating_system) - ) - :name () - :sp () - :version () - ) - :NAT () - :SNMP () - :VPN () - :additional_products () - :color (blue) - :comments () - :cp_products_installed (false) - :firewall (not-installed) - :floodgate (not-installed) - :ipaddr (10.222.0.53) - :type (host) - ) - : (mail.IsoAAAA-es.com - :AdminInfo ( - :chkpf_uid ("{B096EA6A-9B9D-4804-ADF0-E9D196210EDE}") - :ClassName (host_plain) - :table (network_objects) - :Wiznum (-1) - :LastModified ( - :Time ("Thu Sep 30 16:35:03 2004") - :By (IsoAAAF) - :From (IsoAAADray) - ) - :name (mail.IsoAAAA-es.com) - ) - :read_community () - :sysContact () - :sysDescr () - :sysLocation () - :sysName () - :write_community () - :add_adtr_rule (false) - :certificates () - :edges () - :enforce_gtp_rate_limit (false) - :gtp_rate_limit (2048) - :interfaces () - :operating_system ( - :AdminInfo ( - :chkpf_uid ("{96AAF8C1-2F91-4581-B3A3-9E259D51D7FC}") - :ClassName (operating_system) - ) - :name () - :sp () - :version () - ) - :NAT () - :SNMP () - :VPN () - :additional_products () - :color (blue) - :comments () - :cp_products_installed (false) - :firewall (not-installed) - :floodgate (not-installed) - :ipaddr (10.222.0.54) - :type (host) - ) - : (MailServer - :AdminInfo ( - :chkpf_uid ("{17935795-6ADC-4B45-8E2B-BEC361E6CAB1}") - :ClassName (network_object_group) - :table (network_objects) - :Wiznum (-1) - :LastModified ( - :Time ("Thu Sep 30 16:35:07 2004") - :By (IsoAAAF) - :From (IsoAAADray) - ) - :name (MailServer) - ) - :members_query () - : (ReferenceObject - :Name (mail.IsoAAAA.de) - :Table (network_objects) - :Uid ("{98537EEE-D16C-4C24-940F-6880836A7350}") - ) - : (ReferenceObject - :Name (mail.IsoAAAA-es.com) - :Table (network_objects) - :Uid ("{B096EA6A-9B9D-4804-ADF0-E9D196210EDE}") - ) - : (ReferenceObject - :Name (mail.hayn.de) - :Table (network_objects) - :Uid ("{741A5834-3EA7-4899-92F4-3B365DDBCD98}") - ) - : (ReferenceObject - :Name (mail.purschke.de) - :Table (network_objects) - :Uid ("{8EFADE68-A4E4-4BF3-B2C4-EDBD81769700}") - ) - :color (blue1) - :comments ("all Maildomains") - :member_class (network_object) - :type (group) - ) - : (sol8 - :AdminInfo ( - :chkpf_uid ("{86F22190-7D8D-435D-8906-A346CA12A17C}") - :ClassName (host_plain) - :table (network_objects) - :Wiznum (-1) - :LastModified ( - :Time ("Sat Oct 2 16:28:42 2004") - :By (tim) - :From (pieks) - ) - :name (sol8) - ) - :read_community () - :sysContact () - :sysDescr () - :sysLocation () - :sysName () - :write_community () - :add_adtr_rule (false) - :certificates () - :edges () - :enforce_gtp_rate_limit (false) - :gtp_rate_limit (2048) - :interfaces () - :operating_system ( - :AdminInfo ( - :chkpf_uid ("{CC64DA48-EF9D-41E6-862A-BC87E9AEDB2F}") - :ClassName (operating_system) - ) - :name () - :sp () - :version () - ) - :NAT () - :SNMP () - :VPN () - :additional_products () - :color (black) - :comments () - :cp_products_installed (false) - :firewall (not-installed) - :floodgate (not-installed) - :ipaddr (10.222.0.55) - :type (host) - ) - : (t-online - :AdminInfo ( - :chkpf_uid ("{C3D65C4B-6498-4E00-9BAF-15539231E8EE}") - :ClassName (network) - :table (network_objects) - :Wiznum (-1) - :LastModified ( - :Time ("Sun Oct 3 14:33:10 2004") - :By (IsoAAAF) - :From (IsoAAADray) - ) - :name (t-online) - ) - :edges () - :NAT () - :add_adtr_rule (false) - :broadcast (allow) - :color ("deep pink") - :comments () - :ipaddr (10.222.0.56) - :location (internal) - :netmask (255.255.255.255) - :operating_system ( - :AdminInfo ( - :chkpf_uid ("{D7BABA12-EB8B-4603-81A3-02DD65E162B4}") - :ClassName (operating_system) - ) - :name () - :sp () - :version () - ) - :type (network) - ) - : (ras.IsoAAAA-es.com - :AdminInfo ( - :chkpf_uid ("{23B1E779-B8D5-4384-AD60-80E498B77196}") - :ClassName (host_plain) - :table (network_objects) - :Wiznum (-1) - :LastModified ( - :Time ("Mon Oct 4 19:53:42 2004") - :By (IsoAAAF) - :From (IsoAAADray) - ) - :name (ras.IsoAAAA-es.com) - ) - :read_community () - :sysContact () - :sysDescr () - :sysLocation () - :sysName () - :write_community () - :add_adtr_rule (false) - :certificates () - :edges () - :enforce_gtp_rate_limit (false) - :gtp_rate_limit (2048) - :interfaces () - :operating_system ( - :AdminInfo ( - :chkpf_uid ("{04E9B794-BC12-4F6F-B9AE-C0A08A74FF4A}") - :ClassName (operating_system) - ) - :name () - :sp () - :version () - ) - :NAT () - :SNMP () - :VPN () - :additional_products () - :color (cyan) - :comments () - :cp_products_installed (false) - :firewall (not-installed) - :floodgate (not-installed) - :ipaddr (10.222.0.57) - :type (host) - ) - : (Premier_Access - :AdminInfo ( - :chkpf_uid ("{B2BB20AA-B685-426B-96B6-1FB4D8D05135}") - :ClassName (host_plain) - :table (network_objects) - :Wiznum (-1) - :LastModified ( - :Time ("Thu Oct 7 13:35:32 2004") - :By (andre) - :From (Roadrunner) - ) - :name (Premier_Access) - ) - :certificates () - :edges () - :interfaces () - :NAT () - :read_community () - :sysContact () - :sysDescr () - :sysLocation () - :sysName () - :write_community () - :SNMP ( - :AdminInfo ( - :chkpf_uid ("{B2BB20AA-B685-426B-96B6-1FB4D8D05135}") - :ClassName (SNMP) - ) - ) - :VPN () - :add_adtr_rule (false) - :additional_products () - :color ("medium slate blue") - :comments () - :cp_products_installed (false) - :enforce_gtp_rate_limit (false) - :firewall (not-installed) - :floodgate (not-installed) - :gtp_rate_limit (2048) - :ipaddr (10.222.0.58) - :operating_system ( - :AdminInfo ( - :chkpf_uid ("{38EF5369-2EDF-4CAA-BE8E-155605B4C87D}") - :ClassName (operating_system) - ) - :name () - :sp () - :version () - ) - :type (host) - ) - : (vpn-sources-IsoAAAA - :AdminInfo ( - :chkpf_uid ("{26405A41-425C-4053-8002-497BB82D76B1}") - :ClassName (network_object_group) - :table (network_objects) - :Wiznum (-1) - :LastModified ( - :Time ("Sat Nov 6 14:38:57 2004") - :By (IsoAAAF) - :From (IsoAAADray) - ) - :name (vpn-sources-IsoAAAA) - ) - : (ReferenceObject - :Name (IsoAAAA_home_stephan) - :Table (network_objects) - :Uid ("{B86B46D5-DCB5-4A25-A0B6-766D78D30780}") - ) - : (ReferenceObject - :Name (IsoAAAA_home_tim) - :Table (network_objects) - :Uid ("{BF8F69B9-87C2-464A-9404-239AE8DF66B3}") - ) - : (ReferenceObject - :Name (IsoAAAA-100) - :Table (network_objects) - :Uid ("{BF1C6029-8D5D-4A05-A3AD-4B67E6E7A7AA}") - ) - : (ReferenceObject - :Name (CactusDSL-DHCP) - :Table (network_objects) - :Uid ("{4F363EC1-417F-4F6D-B8DC-21875B3E4AC6}") - ) - : (ReferenceObject - :Name (Cactus-InternetTransfer) - :Table (network_objects) - :Uid ("{408C820D-33A1-4E25-B576-EC826F525DCD}") - ) - : (ReferenceObject - :Name (Cactus-Wlan) - :Table (network_objects) - :Uid ("{FFB3BAC5-FD79-4D0B-911A-7413DA524723}") - ) - : (ReferenceObject - :Name (wlan-router) - :Table (network_objects) - :Uid ("{426CC3AD-BE7D-45B6-AAAB-22BA0680EE21}") - ) - :color (black) - :comments () - :member_class (network_object) - :members_query () - :type (group) - ) - : (Cactus10.222.0.1 - :AdminInfo ( - :chkpf_uid ("{6CD51061-638B-4B2F-9092-7E1E4A5F0ADD}") - :ClassName (host_plain) - :table (network_objects) - :Wiznum (-1) - :LastModified ( - :Time ("Sat Nov 6 16:10:22 2004") - :By (IsoAAAF) - :From (IsoAAADray) - ) - :name (Cactus10.222.0.1) - ) - :certificates () - :edges () - :interfaces () - :NAT () - :read_community () - :sysContact () - :sysDescr () - :sysLocation () - :sysName () - :write_community () - :SNMP ( - :AdminInfo ( - :chkpf_uid ("{6CD51061-638B-4B2F-9092-7E1E4A5F0ADD}") - :ClassName (SNMP) - ) - ) - :VPN () - :add_adtr_rule (false) - :additional_products () - :color (blue) - :comments ("IBM Laptop with VMWare 6.11.2004") - :cp_products_installed (false) - :enforce_gtp_rate_limit (false) - :firewall (not-installed) - :floodgate (not-installed) - :gtp_rate_limit (2048) - :ipaddr (10.222.0.1) - :operating_system ( - :AdminInfo ( - :chkpf_uid ("{D2AFE9A3-FE6E-47EC-8A3D-93104C67F9B3}") - :ClassName (operating_system) - ) - :name () - :sp () - :version () - ) - :type (host) - ) - : (Cactus10.222.0.59 - :AdminInfo ( - :chkpf_uid ("{B0D01C29-857D-4A0A-BC23-66A08FCD094D}") - :ClassName (host_plain) - :table (network_objects) - :Wiznum (-1) - :LastModified ( - :Time ("Sat Nov 6 16:10:29 2004") - :By (IsoAAAF) - :From (IsoAAADray) - ) - :name (Cactus10.222.0.59) - ) - :certificates () - :edges () - :interfaces () - :NAT () - :read_community () - :sysContact () - :sysDescr () - :sysLocation () - :sysName () - :write_community () - :SNMP ( - :AdminInfo ( - :chkpf_uid ("{B0D01C29-857D-4A0A-BC23-66A08FCD094D}") - :ClassName (SNMP) - ) - ) - :VPN () - :add_adtr_rule (false) - :additional_products () - :color (black) - :comments ("VIP-Net Koordinator auf VM-Ware IBM Laptop 5.11.2004") - :cp_products_installed (false) - :enforce_gtp_rate_limit (false) - :firewall (not-installed) - :floodgate (not-installed) - :gtp_rate_limit (2048) - :ipaddr (10.222.0.59) - :operating_system ( - :AdminInfo ( - :chkpf_uid ("{52322F92-8A93-488B-93D3-6C8350FC9A52}") - :ClassName (operating_system) - ) - :name () - :sp () - :version () - ) - :type (host) - ) - : (SecOVID_Authserver - :AdminInfo ( - :chkpf_uid ("{DB220C3D-763C-46AB-A7D1-1F9C7C45910E}") - :ClassName (host_plain) - :table (network_objects) - :Wiznum (-1) - :LastModified ( - :Time ("Thu Dec 2 15:56:31 2004") - :By (IsoAAAF) - :From (IsoAAADray) - ) - :name (SecOVID_Authserver) - ) - :certificates () - :edges () - :interfaces () - :NAT () - :read_community () - :sysContact () - :sysDescr () - :sysLocation () - :sysName () - :write_community () - :SNMP ( - :AdminInfo ( - :chkpf_uid ("{DB220C3D-763C-46AB-A7D1-1F9C7C45910E}") - :ClassName (SNMP) - ) - ) - :VPN () - :add_adtr_rule (false) - :additional_products () - :color (green) - :comments () - :cp_products_installed (false) - :enforce_gtp_rate_limit (false) - :firewall (not-installed) - :floodgate (not-installed) - :gtp_rate_limit (2048) - :ipaddr (10.222.0.60) - :operating_system ( - :AdminInfo ( - :chkpf_uid ("{24962D03-284E-4ECD-AD98-86D19C8271B4}") - :ClassName (operating_system) - ) - :name () - :sp () - :version () - ) - :type (host) - ) - : (mail.light-life.netOld - :AdminInfo ( - :chkpf_uid ("{DF004F13-7986-4569-811C-6EC7391A8764}") - :ClassName (host_plain) - :table (network_objects) - :Wiznum (-1) - :LastModified ( - :Time ("Mon Jan 24 13:50:53 2005") - :By (IsoAAAF) - :From (IsoAAADray) - ) - :name (mail.light-life.netOld) - ) - :certificates () - :edges () - :interfaces () - :NAT () - :read_community () - :sysContact () - :sysDescr () - :sysLocation () - :sysName () - :write_community () - :SNMP ( - :AdminInfo ( - :chkpf_uid ("{DF004F13-7986-4569-811C-6EC7391A8764}") - :ClassName (SNMP) - ) - ) - :VPN () - :add_adtr_rule (false) - :additional_products () - :color (orange) - :comments ("Silkes Mail") - :cp_products_installed (false) - :enforce_gtp_rate_limit (false) - :firewall (not-installed) - :floodgate (not-installed) - :gtp_rate_limit (2048) - :ipaddr (10.222.0.61) - :operating_system ( - :AdminInfo ( - :chkpf_uid ("{2E52BC89-F624-44E8-B100-A39B0AB9B399}") - :ClassName (operating_system) - ) - :name () - :sp () - :version () - ) - :type (host) - ) - : (mail.light-life.net - :AdminInfo ( - :chkpf_uid ("{C534904C-317E-431D-BF6C-03977CC08203}") - :ClassName (host_plain) - :table (network_objects) - :Wiznum (-1) - :LastModified ( - :Time ("Mon Jan 24 13:50:58 2005") - :By (IsoAAAF) - :From (IsoAAADray) - ) - :name (mail.light-life.net) - ) - :certificates () - :edges () - :interfaces () - :NAT () - :read_community () - :sysContact () - :sysDescr () - :sysLocation () - :sysName () - :write_community () - :SNMP ( - :AdminInfo ( - :chkpf_uid ("{C534904C-317E-431D-BF6C-03977CC08203}") - :ClassName (SNMP) - ) - ) - :VPN () - :add_adtr_rule (false) - :additional_products () - :color (blue) - :comments () - :cp_products_installed (false) - :enforce_gtp_rate_limit (false) - :firewall (not-installed) - :floodgate (not-installed) - :gtp_rate_limit (2048) - :ipaddr (10.222.0.62) - :operating_system ( - :AdminInfo ( - :chkpf_uid ("{59E4FEAD-7108-4E23-B865-7C7A401F382A}") - :ClassName (operating_system) - ) - :name () - :sp () - :version () - ) - :type (host) - ) - : (IsoAAAD_intern - :AdminInfo ( - :chkpf_uid ("{40831AE2-CB84-46D2-9522-F987BC10BDB9}") - :ClassName (host_plain) - :table (network_objects) - :Wiznum (-1) - :LastModified ( - :Time ("Mon Jan 24 13:57:02 2005") - :By (IsoAAAF) - :From (IsoAAADray) - ) - :name (IsoAAAD_intern) - ) - :certificates () - :edges () - :interfaces () - :NAT () - :read_community () - :sysContact () - :sysDescr () - :sysLocation () - :sysName () - :write_community () - :SNMP ( - :AdminInfo ( - :chkpf_uid ("{40831AE2-CB84-46D2-9522-F987BC10BDB9}") - :ClassName (SNMP) - ) - ) - :VPN () - :add_adtr_rule (false) - :additional_products () - :color (red) - :comments (10.222.0.63) - :cp_products_installed (false) - :enforce_gtp_rate_limit (false) - :firewall (not-installed) - :floodgate (not-installed) - :gtp_rate_limit (2048) - :ipaddr (10.222.0.63) - :operating_system ( - :AdminInfo ( - :chkpf_uid ("{F32BCF76-B27C-4087-AC45-A7A6DCB70413}") - :ClassName (operating_system) - ) - :name () - :sp () - :version () - ) - :type (host) - ) - : (IsoAAAA-office-mode-range - :AdminInfo ( - :chkpf_uid ("{AF3BE336-00D5-4975-B0C9-F759300D42D8}") - :ClassName (network) - :table (network_objects) - :Wiznum (-1) - :LastModified ( - :Time ("Tue Feb 1 14:12:41 2005") - :By (tim) - :From (pieks) - ) - :name (IsoAAAA-office-mode-range) - ) - :add_adtr_rule (false) - :edges () - :location (internal) - :operating_system ( - :AdminInfo ( - :chkpf_uid ("{669DDE9F-A4D3-4F79-AB66-6D46F1710730}") - :ClassName (operating_system) - ) - :name () - :sp () - :version () - ) - :NAT () - :broadcast (allow) - :color (black) - :comments () - :ipaddr (10.222.0.64) - :netmask (255.255.255.255) - :type (network) - ) - : (Cactus-DMZ4 - :AdminInfo ( - :chkpf_uid ("{9C2C49CE-5100-423C-BECB-08951751059F}") - :ClassName (network) - :table (network_objects) - :Wiznum (-1) - :LastModified ( - :Time ("Thu Mar 31 20:38:45 2005") - :By (IsoAAAF) - :From (IsoAAADray) - ) - :name (Cactus-DMZ4) - ) - :add_adtr_rule (false) - :edges () - :location (internal) - :operating_system ( - :AdminInfo ( - :chkpf_uid ("{BB469654-D760-4C34-8DED-EDB208914A3F}") - :ClassName (operating_system) - ) - :name () - :sp () - :version () - ) - :NAT () - :broadcast (allow) - :color ("forest green") - :comments ("10.222.0.65/32") - :ipaddr (10.222.0.65) - :netmask (255.255.255.255) - :type (network) - ) - : (ITSecOrg-dev - :AdminInfo ( - :chkpf_uid ("{18122B8C-51F8-4102-B143-72DA4E57367D}") - :ClassName (host_plain) - :table (network_objects) - :Wiznum (-1) - :LastModified ( - :Time ("Thu Apr 28 14:17:13 2005") - :By (IsoAAAF) - :From (IsoAAADray) - ) - :name (ITSecOrg-dev) - ) - :read_community () - :sysContact () - :sysDescr () - :sysLocation () - :sysName () - :write_community () - :add_adtr_rule (false) - :certificates () - :edges () - :enforce_gtp_rate_limit (false) - :gtp_rate_limit (2048) - :interfaces () - :operating_system ( - :AdminInfo ( - :chkpf_uid ("{9295DAEC-8C37-4E45-816D-977184D54CA4}") - :ClassName (operating_system) - ) - :name () - :sp () - :version () - ) - :NAT () - :SNMP () - :VPN () - :additional_products () - :color (blue1) - :comments ("development 4 ITSecOrg") - :cp_products_installed (false) - :firewall (not-installed) - :floodgate (not-installed) - :ipaddr (10.222.0.66) - :type (host) - ) - : (SonicLAN - :AdminInfo ( - :chkpf_uid ("{587A029D-04EA-49A0-9DB2-93ADC651B7BF}") - :ClassName (network) - :table (network_objects) - :Wiznum (-1) - :LastModified ( - :Time ("Tue May 24 11:53:28 2005") - :By (IsoAAAF) - :From (IsoAAADray) - ) - :name (SonicLAN) - ) - :add_adtr_rule (false) - :edges () - :location (internal) - :operating_system ( - :AdminInfo ( - :chkpf_uid ("{82672588-DA60-4678-BCFE-9855BBA7B813}") - :ClassName (operating_system) - ) - :name () - :sp () - :version () - ) - :NAT () - :broadcast (allow) - :color ("light coral") - :comments ("4 VPN-Test") - :ipaddr (10.222.0.67) - :netmask (255.255.255.255) - :type (network) - ) - : (Cactus-Wlan - :AdminInfo ( - :chkpf_uid ("{FFB3BAC5-FD79-4D0B-911A-7413DA524723}") - :ClassName (address_range) - :table (network_objects) - :Wiznum (-1) - :LastModified ( - :Time ("Tue May 24 15:51:05 2005") - :By (IsoAAAF) - :From (IsoAAADray) - ) - :name (Cactus-Wlan) - ) - :edges () - :NAT () - :add_adtr_rule (false) - :color (black) - :comments ("net for wlan") - :ipaddr_first (10.222.0.68) - :ipaddr_last (10.222.0.69) - :type (machines_range) - ) - : (CactusDA - :AdminInfo ( - :chkpf_uid ("{69DBB75C-7E6D-49AD-A814-96F1BAFF12F7}") - :ClassName (network_object_group) - :table (network_objects) - :Wiznum (-1) - :LastModified ( - :Time ("Mon Jun 6 11:27:32 2005") - :By (andre) - :From (andres-laptop) - ) - :name (CactusDA) - ) - : (ReferenceObject - :Name (IsoAAAA-100) - :Table (network_objects) - :Uid ("{BF1C6029-8D5D-4A05-A3AD-4B67E6E7A7AA}") - ) - : (ReferenceObject - :Name (Cactus-Official) - :Table (network_objects) - :Uid ("{2136B4E8-3ABF-4931-BDB9-12CDF457D4A4}") - ) - : (ReferenceObject - :Name (Sonic1) - :Table (network_objects) - :Uid ("{B2EBD57B-C94C-42E7-8F1A-17C861697403}") - ) - : (ReferenceObject - :Name (IsoAAAD) - :Table (network_objects) - :Uid ("{29C40B0A-414C-11D7-AEB8-7F0000013C3C}") - ) - :color (black) - :comments () - :member_class (network_object) - :members_query () - :type (group) - ) - : (Sonic1 - :AdminInfo ( - :chkpf_uid ("{B2EBD57B-C94C-42E7-8F1A-17C861697403}") - :ClassName (gateway_plain) - :table (network_objects) - :Wiznum (-1) - :LastModified ( - :Time ("Thu Jun 23 14:32:41 2005") - :By (IsoAAAF) - :From (IsoAAADray) - ) - ) - :certificates () - :edges () - :interfaces () - :NAT () - :read_community () - :sysContact () - :sysDescr () - :sysLocation () - :sysName () - :write_community () - :SNMP ( - :AdminInfo ( - :chkpf_uid ("{B2EBD57B-C94C-42E7-8F1A-17C861697403}") - :ClassName (SNMP) - ) - ) - :isakmp.authmethods ( - : (pre-shared) - ) - :isakmp.matchpeer () - :FWZ () - :isakmp.encmethods ( - : (3DES) - : (DES) - ) - :isakmp.hashmethods ( - : (MD5) - : (SHA1) - ) - :isakmp.phase1_DH_groups ( - : (ReferenceObject - :Name ("Group 5 (1536 bit)") - :Table (encryption) - :Uid ("{97AEB62E-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :isakmpsharedkey () - :ISAKMP_aggressive_support (true) - :ike.empty_udp_socket (false) - :isakmp.crlreq (false) - :isakmp.phase1_rekeying_time (60) - :isakmp.phase2_rekeying_kbytes (50000) - :isakmp.phase2_rekeying_time (3600) - :isakmp.phase2_use_rekeying_kbytes (false) - :isakmpkeymanager () - :IKE ( - :AdminInfo ( - :chkpf_uid ("{B2EBD57B-C94C-42E7-8F1A-17C861697403}") - :ClassName (IKE) - ) - ) - :ISAKMP_subnet_support (true) - :accept_3des_for_clientless_vpn (true) - :clientless_VPN_ask_user_for_certificate (none) - :clientless_proc_num (1) - :enable_internet_routing (false) - :enable_routing (true) - :ipsec.copy_TOS_to_inner (false) - :ipsec.copy_TOS_to_outer (true) - :ipsec_dont_fragment (true) - :isakmp.allowed_ca () - :isakmp.allowed_cert () - :isakmp.dn () - :isakmp.dns_name () - :isakmp.do_dns_resolve (false) - :isakmp.email () - :isakmp.ipcomp_support (false) - :isakmp.udpencapsulation ( - :AdminInfo ( - :chkpf_uid ("{7B561E2F-3476-4F65-B808-B887605A9F7C}") - :ClassName (IKE_UDP_encapsulation) - ) - :active (true) - :resource (ReferenceObject - :Table (services) - :Name (VPN1_IPSEC_encapsulation) - :Uid ("{97AEB390-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :tcpt ( - :AdminInfo ( - :chkpf_uid ("{32763E96-70C9-4186-B5D8-F99AEEC93FE1}") - :ClassName (TCP_TUNNELING) - ) - :active (false) - :interface ("All IPs") - :resource (ReferenceObject - :Name (https) - :Table (services) - :Uid ("{97AEB443-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :third_party_encryption (true) - :use_cert () - :use_clientless_vpn (false) - :use_service (ReferenceObject - :Table (services) - :Name (https) - :Uid ("{97AEB443-9AEA-11D5-BD16-0090272CCB30}") - ) - :vpn_comp_level (2) - :VPN ( - :AdminInfo ( - :chkpf_uid ("{B2EBD57B-C94C-42E7-8F1A-17C861697403}") - :ClassName (VPN) - ) - ) - :VPN_allow_relay (false) - :VPN_relay_if_name () - :add_adtr_rule (false) - :additional_products () - :backup_gateway () - :backup_gw (false) - :color (black) - :comments ("VPN Test") - :cp_products_installed (false) - :encdomain (manual) - :enforce_gtp_rate_limit (false) - :firewall (not-installed) - :floodgate (not-installed) - :gtp_rate_limit (2048) - :interface_resolving_ha_primary_if_GW () - :ip_pool_exhaust_ret_interval (30) - :ip_pool_gw2gw (false) - :ip_pool_securemote (false) - :ip_pool_securemote_allocation_name () - :ip_pool_unused_return_interval (60) - :ipaddr (10.222.0.59) - :manual_encdomain (ReferenceObject - :Name (SonicLAN) - :Table (network_objects) - :Uid ("{587A029D-04EA-49A0-9DB2-93ADC651B7BF}") - ) - :operating_system ( - :AdminInfo ( - :chkpf_uid ("{FDEAA053-4C49-4838-A711-7C0DEB9E0AB0}") - :ClassName (operating_system) - ) - :name () - :sp () - :version () - ) - :perform_encryption (true) - :range_encdomain () - :type (gateway) - ) - : (IsoAAAD - :AdminInfo ( - :chkpf_uid ("{29C40B0A-414C-11D7-AEB8-7F0000013C3C}") - :ClassName (gateway_ckp) - :object_permissions ( - :AdminInfo ( - :chkpf_uid ("{EB6FC940-52CD-4BD6-904C-EB31739BDA15}") - :ClassName (object_permissions) - ) - :manage ( - : (ReferenceObject - :Table (globals) - :Name (Any) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :read ( - : (any) - ) - :use ( - : (any) - ) - :write ( - : () - ) - :owner () - ) - :table (network_objects) - :Deleteable (false) - :Renameable (false) - :Wiznum (-1) - :LastModified ( - :Time ("Thu Jun 23 14:32:41 2005") - :By (IsoAAAF) - :From (IsoAAADray) - ) - ) - :backup_gateway () - :certificates ( - : (defaultCert - :AdminInfo ( - :chkpf_uid ("{C1CADC7F-56D0-42CB-9EE4-CBCBFE50930A}") - :ClassName (certificate) - ) - :"#certreq-pki-gen" (false) - :"#pki-host-cert-set" (false) - :ca (ReferenceObject - :Name (internal_ca) - :Table (servers) - :Uid ("{29DD801C-414C-11D7-AEB8-7F0000013C3C}") - ) - :dn ("CN=IsoAAAD VPN Certificate,O=IsoAAAD.IsoAAAA-es.de..jnbkhk") - :pkisignkey (c9b51d2a6789df31ea72d712) - :status (signed) - :stored.at (management_server) - ) - ) - :edges () - :free_fields () - :interfaces ( - :0 ( - :AdminInfo ( - :chkpf_uid ("{29C486E8-414C-11D7-AEB8-7F0000013C3C}") - :ClassName (interface) - ) - :edges () - :diff_serv_values () - :diff_serv (false) - :fg_inbound_active (false) - :fg_inbound_rate (5898240) - :fg_outbound_active (false) - :fg_outbound_rate (5898240) - :bandwidth ( - :AdminInfo ( - :chkpf_uid ("{29C486E8-414C-11D7-AEB8-7F0000013C3C}") - :ClassName (interface_bandwidth) - ) - ) - :comments () - :description () - :dynamic_ip (false) - :ifindex (0) - :ipaddr (10.222.0.63) - :netmask (255.255.255.255) - :officialname (eth0) - :antispoof (true) - :netaccess ( - :AdminInfo ( - :chkpf_uid ("{29C47BDA-414C-11D7-AEB8-7F0000013C3C}") - :ClassName (netaccess) - ) - :access (undefined) - :allowed () - :enable_overlapping_nat (false) - :force_policy (true) - :leads_to_internet (false) - :log (alert) - :overlap_nat_dst_ipaddr () - :overlap_nat_netmask (255.255.255.255) - :overlap_nat_src_ipaddr () - :perform_anti_spoofing (false) - ) - :security ( - :AdminInfo ( - :chkpf_uid ("{29C486E8-414C-11D7-AEB8-7F0000013C3C}") - :ClassName (interface_security) - ) - ) - :shared (true) - ) - :1 ( - :AdminInfo ( - :chkpf_uid ("{BE1E514B-74C7-4EA3-B375-A0752C2C9F9A}") - :ClassName (interface) - ) - :edges () - :bandwidth () - :comments () - :description () - :dynamic_ip (false) - :ifindex (1) - :ipaddr (10.222.0.42) - :netmask (255.255.255.255) - :officialname (eth1) - :antispoof (true) - :netaccess ( - :AdminInfo ( - :chkpf_uid ("{8602D66D-CE3F-428D-9A10-F9D5112DCF93}") - :ClassName (netaccess) - ) - :access (undefined) - :allowed () - :enable_overlapping_nat (false) - :force_policy (true) - :leads_to_internet (true) - :log (log) - :overlap_nat_dst_ipaddr () - :overlap_nat_netmask (255.255.255.255) - :overlap_nat_src_ipaddr () - :perform_anti_spoofing (true) - ) - :security ( - :AdminInfo ( - :chkpf_uid ("{BE1E514B-74C7-4EA3-B375-A0752C2C9F9A}") - :ClassName (interface_security) - ) - ) - :shared (true) - ) - ) - :masters () - :Enable_CPSyslogD (false) - :Everest (false) - :IPSec_orig_if_nat (true) - :MetaIP_Admin_Server (false) - :MetaIP_DHCP_Server (false) - :MetaIP_DNS_Server (false) - :MetaIP_RADIUS_Server (false) - :MetaIP_UAT (false) - :NAT () - :read_community () - :sysContact () - :sysDescr () - :sysLocation () - :sysName () - :write_community () - :SNMP ( - :AdminInfo ( - :chkpf_uid ("{29C40B0A-414C-11D7-AEB8-7F0000013C3C}") - :ClassName (SNMP) - ) - ) - :SmallOffice (false) - :UA_WebAccess (false) - :UA_gateway (false) - :UA_server (false) - :isakmp.authmethods ( - : (pre-shared) - ) - :isakmp.matchpeer () - :FWZ () - :isakmp.encmethods ( - : (3DES) - : (AES-256) - : (CAST) - ) - :isakmp.hashmethods ( - : (MD5) - : (SHA1) - ) - :isakmp.phase1_DH_groups ( - : (ReferenceObject - :Name ("Group 2 (1024 bit)") - :Table (encryption) - :Uid ("{97AEB629-9AEA-11D5-BD16-0090272CCB30}") - ) - : (ReferenceObject - :Name ("Group 5 (1536 bit)") - :Table (encryption) - :Uid ("{97AEB62E-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :isakmpsharedkey ( - : (tmp-IsoAAAA.mine.nu) - : (IsoAAAA-ffm) - ) - :ISAKMP_aggressive_support (true) - :ike.empty_udp_socket (false) - :isakmp.crlreq (false) - :isakmp.phase1_rekeying_time (60) - :isakmp.phase2_rekeying_kbytes (50000) - :isakmp.phase2_rekeying_time (3600) - :isakmp.phase2_use_rekeying_kbytes (false) - :isakmpkeymanager () - :IKE ( - :AdminInfo ( - :chkpf_uid ("{29C40B0A-414C-11D7-AEB8-7F0000013C3C}") - :ClassName (IKE) - ) - ) - :ISAKMP_subnet_support (true) - :accept_3des_for_clientless_vpn (false) - :clientless_VPN_ask_user_for_certificate (ask) - :clientless_proc_num (1) - :enable_internet_routing (false) - :enable_routing (true) - :ipsec.copy_TOS_to_inner (false) - :ipsec.copy_TOS_to_outer (true) - :ipsec_dont_fragment (true) - :isakmp.allowed_ca () - :isakmp.allowed_cert () - :isakmp.dn () - :isakmp.dns_name () - :isakmp.do_dns_resolve (false) - :isakmp.email () - :isakmp.ipcomp_support (false) - :isakmp.udpencapsulation ( - :AdminInfo ( - :chkpf_uid ("{3D18AC86-B15C-46DA-8C2B-4A8549E5B3DF}") - :ClassName (IKE_UDP_encapsulation) - ) - :active (true) - :resource (ReferenceObject - :Name (VPN1_IPSEC_encapsulation) - :Table (services) - :Uid ("{97AEB390-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :tcpt ( - :AdminInfo ( - :chkpf_uid ("{C0FB535C-83FE-11D8-AF49-C0A8645AD0D0}") - :ClassName (TCP_TUNNELING) - ) - :active (false) - :interface ("All IPs") - :resource (ReferenceObject - :Table (services) - :Name (https) - :Uid ("{97AEB443-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :third_party_encryption (false) - :use_cert () - :use_clientless_vpn (false) - :use_service (ReferenceObject - :Table (services) - :Name (https) - :Uid ("{97AEB443-9AEA-11D5-BD16-0090272CCB30}") - ) - :vpn_comp_level (2) - :VPN ( - :AdminInfo ( - :chkpf_uid ("{29C40B0A-414C-11D7-AEB8-7F0000013C3C}") - :ClassName (VPN) - ) - ) - :VPN_1 (true) - :VPN_allow_relay (false) - :VPN_relay_if_name () - :WAM (false) - :add_adtr_rule (false) - :additional_products () - :allow_extranet (false) - :amazonas_machine (false) - :apply_nat_for_cp_conns (false) - :asm_synatk (false) - :asm_synatk_external_only (false) - :asm_synatk_log (none) - :asm_synatk_log_level (1) - :asm_synatk_threshold (200) - :asm_synatk_timeout (10) - :au_timeout (15) - :backup_gw (false) - :ca_wait_mode (false) - :color (black) - :comments () - :connection_state (communicating) - :copy_DF_flag_SR (false) - :cp_products_installed (true) - :cp_suite_type (pro) - :cpver (5.0) - :default_track (alert) - :define_logging_servers (false) - :disable_replay_check (false) - :display_name_for_sr_sc () - :enable_rtm_counters_report (true) - :enable_rtm_traffic_report (false) - :enable_rtm_traffic_report_per_connection (false) - :encdomain (manual) - :enforce_gtp_rate_limit (false) - :event_analyzer (false) - :exportable (true) - :firewall (installed) - :auth_user_groups (ReferenceObject - :Table (globals) - :Name ("All Users") - :Uid ("{97AEB36A-9AEB-11D5-BD16-0090272CCB30}") - ) - :custom_multi_server_au_list () - :misp_dns_entries () - :misp_isps () - :DAG (false) - :DAG_manual_fetch (false) - :DAG_schedule_interval () - :IPSec_main_if_nat (false) - :NAT_cache_expiration (30) - :NAT_cache_nentries (10000) - :SDS (not-installed) - :allow_VPN_routing_from_SR (false) - :calculation_type (partially_automatic) - :connections_hashsize (32768) - :connections_limit (25000) - :disable_outgoing_tcpt (false) - :display_au_list (false) - :ftp_transparent_server_connection (true) - :fw_hmem_maxsize (30) - :fw_hmem_size (6) - :fw_keep_old_conns (false) - :fw_rst_expired_conn (false) - :fwver (5.0) - :generic_transparent_server_connection (true) - :host_schemes_val (122) - :http_next_proxy_defined (false) - :http_transparent_server_connection (true) - :ip_assignment_group () - :ip_assignment_offer (never) - :ip_assignment_settings () - :l2tp_auth_method (MD5) - :max_concurrent_gw_tunnels (200) - :max_concurrent_vpn_tunnels (10000) - :max_num_negs (200) - :misp_active (false) - :misp_cache_hashsize (4096) - :misp_cache_limit (10000) - :misp_cache_timeout (300) - :misp_cache_use_cln (true) - :misp_cache_use_srv (false) - :misp_dns_active (false) - :misp_dns_ttl (15) - :misp_host_is_dead_after (15) - :misp_load_sharing (true) - :misp_ping_interval (5) - :misp_ping_wait_time (3) - :misp_pings_per_interval (1) - :misp_track_isp_went_down (alert) - :misp_track_isp_went_up (log) - :netso () - :non_tcp_quota_enable (false) - :non_tcp_quota_percentage (50) - :policy_server (not-installed) - :remote_access_nrules (4) - :rlogin_transparent_server_connection (true) - :save_control_conns (false) - :save_data_conns (false) - :smtp ( - :AdminInfo ( - :chkpf_uid ("{29C42F18-414C-11D7-AEB8-7F0000013C3C}") - :ClassName (smtp_module) - ) - :abandon_time (43200) - :detailed_av_err_mail (false) - :detailed_rb_err_mail (false) - :detailed_smtp_err_mail (false) - :max_conns (40) - :max_conns_per_site (6) - :max_ips_per_mx_node (1) - :max_mail_size (1000) - :max_mails_per_conn (20) - :max_mx_node_per_mail (5) - :maxrecipients (50) - :postmaster () - :resend_period (600) - :rundir () - :scan_period (2) - :spool_limit (20000) - :spool_limit_scan_period (20) - :timeout (90) - ) - :smtp_transparent_server_connection (false) - :support_l2tp (false) - :telnet_transparent_server_connection (true) - :use_cert_for_l2tp () - :use_custom_au_list (false) - :use_sequential_au_lookup (false) - :xrs (false) - :firewall_setting ( - :AdminInfo ( - :chkpf_uid ("{29C40B0A-414C-11D7-AEB8-7F0000013C3C}") - :ClassName (firewall) - ) - ) - :floodgate (not-installed) - :fgver (5.0) - :floodgate_setting ( - :AdminInfo ( - :chkpf_uid ("{29C40B0A-414C-11D7-AEB8-7F0000013C3C}") - :ClassName (floodgate) - ) - ) - :fwldap_RequestTimeout (20) - :fwsynatk_max (5000) - :fwsynatk_method (0) - :fwsynatk_timeout (10) - :fwsynatk_warning (1) - :gtp_rate_limit (2048) - :gx_version (2.0) - :hosted_by_mds () - :http_next_proxy_host () - :http_next_proxy_port () - :ike_support_crash_recovery_sr (true) - :interface_resolving_ha (false) - :interface_resolving_ha_GW (false) - :interface_resolving_ha_primary_if_GW () - :ip_pool_exhaust_ret_interval (30) - :ip_pool_gw2gw (false) - :ip_pool_securemote (false) - :ip_pool_securemote_allocation_name () - :ip_pool_unused_return_interval (60) - :ipaddr (10.222.0.63) - :keep_DF_flag (false) - :keep_DF_flag_SR (false) - :location (internal) - :log_consolidator (false) - :log_policy ( - :AdminInfo ( - :chkpf_uid ("{29C3E8F0-414C-11D7-AEB8-7F0000013C3C}") - :ClassName (log_policy) - ) - :Citrix_ICA_application_detection (false) - :acct_update_interval (3600) - :alert_free_disk_space (20) - :alert_free_disk_space_metrics (mbytes) - :alert_on_disk_space (true) - :alert_type (alert) - :etm_logging (true) - :forward_event (false) - :forward_logs (false) - :log_delete_below_metrics (mbytes) - :log_delete_below_value (45) - :log_delete_on_below (false) - :log_delete_on_run_script (false) - :log_delete_script_command () - :log_forward_schedule () - :log_forward_target () - :log_keep_days_value (0) - :log_keep_on_days (false) - :log_switch_before_forwarding (false) - :log_switch_on_file_size (true) - :log_switch_schedule () - :log_switch_size (100) - :min_free_disk_space (15) - :reject_connections (true) - :scheduled_switch (false) - :stop_free_disk_space_metrics (mbytes) - :stop_logging_on_free_disk_space (true) - ) - :log_server (true) - :log_servers ( - :AdminInfo ( - :chkpf_uid ("{BB06EAAB-D151-444E-BAC8-98C29198FED4}") - :ClassName (log_servers) - ) - :backup_log_servers () - :send_alerts_to () - :send_logs_to () - :self_log_server (false) - ) - :management (true) - :manual_encdomain (ReferenceObject - :Name (CactusDA) - :Table (network_objects) - :Uid ("{69DBB75C-7E6D-49AD-A814-96F1BAFF12F7}") - ) - :mds () - :operating_system ( - :AdminInfo ( - :chkpf_uid ("{29C3F3D6-414C-11D7-AEB8-7F0000013C3C}") - :ClassName (operating_system) - ) - :name (secureplatform) - :sp ("#1 Wed Nov 19 19:54:48 GMT 2003") - :version (2.4.9-42cp) - ) - :option_pack (4) - :owner () - :perform_encryption (true) - :performancepack (false) - :primary_management (true) - :radius_server (ReferenceObject - :Table (globals) - :Name (None) - :Uid ("{97AEB36A-9AEA-11D5-BD16-0090272CCB30}") - ) - :range_encdomain () - :real_time_monitor (false) - :reporting_server (false) - :resolve_multiple_interfaces (false) - :resolve_multiple_interfaces_GW (false) - :sam_allow_remote_request (true) - :sam_enable_purge_history_file (false) - :sam_proxy_backwards_compatibility_security_method () - :sam_purge_file_start_size (100) - :sic_name ("cn=cp_mgmt,o=IsoAAAD.IsoAAAA-es.de..jnbkhk") - :support_sr_ike_mm (true) - :supports_tcp_ike (use_site_default) - :type (gateway) - :upload_logs (true) - :use_loggers_and_masters (true) - :used_globaly (false) - :user_friendly () - :vpnddcate (false) - :web_auth () - ) - ) - :servers (servers - : (internal_ca - :AdminInfo ( - :LastModified ( - :Time ("Sun Feb 16 01:15:40 2003") - :By ("Firewall Management Process") - :From (IsoAAAD) - ) - :chkpf_uid ("{29DD801C-414C-11D7-AEB8-7F0000013C3C}") - :ClassName (internal_ca_server) - :Deleteable (false) - :table (servers) - :name (internal_ca) - ) - :permissions_strings () - :use_cn_to_fetch_user (false) - :ca_type (internal) - :cacertificate () - :cacertsignkey (dd743a1f4010fadb90d0d8ad) - :color (black) - :comments () - :crl_cache_timeout (86400) - :crl_cache_type (Timeout) - :crl_http (true) - :crl_ldap (false) - :dn ("O=IsoAAAD.IsoAAAA-es.de..jnbkhk") - :internal_CA_check_CRL (true) - :permissions_type (None) - :type (ca) - ) - : (PremierAccess - :AdminInfo ( - :chkpf_uid ("{9484F12B-7004-4574-8BF1-306A4836D397}") - :ClassName (radius_server) - :table (servers) - :Wiznum (-1) - :LastModified ( - :Time ("Thu Oct 7 14:00:42 2004") - :By (andre) - :From (Roadrunner) - ) - ) - :color (blue) - :comments (Radius) - :new_shared_secret (e855fbb32a) - :priority (1) - :server (ReferenceObject - :Name (Premier_Access) - :Table (network_objects) - :Uid ("{B2BB20AA-B685-426B-96B6-1FB4D8D05135}") - ) - :service (ReferenceObject - :Name (NEW-RADIUS) - :Table (services) - :Uid ("{97AEB41E-9AEA-11D5-BD16-0090272CCB30}") - ) - :type (radius) - :version ("RADIUS Ver. 2.0") - ) - : (SecOVID - :AdminInfo ( - :chkpf_uid ("{9F7FBB97-1E72-4A3C-9FF7-08D5B5A4FAFF}") - :ClassName (radius_server) - :table (servers) - :Wiznum (-1) - :LastModified ( - :Time ("Thu Oct 7 15:20:35 2004") - :By (stephan) - :From (Pegasus) - ) - ) - :color (green) - :comments (testinstall) - :new_shared_secret (e1e053fda323) - :priority (2) - :server (ReferenceObject - :Name (SecOVID_Authserver) - :Table (network_objects) - :Uid ("{DB220C3D-763C-46AB-A7D1-1F9C7C45910E}") - ) - :service (ReferenceObject - :Name (NEW-RADIUS) - :Table (services) - :Uid ("{97AEB41E-9AEA-11D5-BD16-0090272CCB30}") - ) - :type (radius) - :version ("RADIUS Ver. 2.0") - ) - ) - :resources_types (resources_types - : ("CIFS spec" - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB36D-9AEA-11D5-BD16-0090272CCB31}") - :ClassName (resource_type) - :table (resources_types) - ) - :type (cifs) - ) - : ("URI spec" - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB36D-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (resource_type) - :table (resources_types) - :name ("URI spec") - ) - :type (uri) - ) - : ("SMTP spec" - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB36E-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (resource_type) - :table (resources_types) - :name ("SMTP spec") - ) - :type (smtp) - ) - : ("FTP spec" - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB36F-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (resource_type) - :table (resources_types) - :name ("FTP spec") - ) - :type (ftp) - ) - ) - :protocols (protocols - : (ENC-HTTP - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By (CheckPoint) - :From (CheckPoint) - ) - :chkpf_uid ("{8294399D-9333-4774-B3DA-C00EACEF3211}") - :ClassName (tcp_protocol) - :table (protocols) - ) - :handler () - :res_type (ReferenceObject - :Name ("URI spec") - :Table (resources_types) - :Uid ("{97AEB36D-9AEA-11D5-BD16-0090272CCB30}") - ) - :type (tcp_protocol) - ) - : (SSL_V3 - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By (CheckPoint) - :From (CheckPoint) - ) - :chkpf_uid ("{16A704F7-7BD7-49BD-A52A-525AAEDAE7AB}") - :ClassName (tcp_protocol) - :table (protocols) - ) - :handler (ssl_v3_code) - :res_type (none) - :type (tcp_protocol) - ) - : (FTP_BASIC - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By (CheckPoint) - :From (CheckPoint) - ) - :chkpf_uid ("{DE35C446-D028-4451-9095-84597C97B78A}") - :ClassName (tcp_protocol) - :table (protocols) - ) - :handler (ftp_reduced) - :res_type (ReferenceObject - :Name ("FTP spec") - :Table (resources_types) - :Uid ("{97AEB36F-9AEA-11D5-BD16-0090272CCB30}") - ) - :type (tcp_protocol) - ) - : (SSH2 - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By (CheckPoint) - :From (CheckPoint) - ) - :chkpf_uid ("{55F4C5D7-60D9-44B3-9BD4-C3F76B7C8360}") - :ClassName (tcp_protocol) - :table (protocols) - ) - :handler (ssh2_code) - :res_type (none) - :type (tcp_protocol) - ) - : (CitrixICA - :AdminInfo ( - :LastModified ( - :Time ("Thu Apr 10 17:36:34 2003") - :By (CheckPoint) - :From (CheckPoint) - ) - :chkpf_uid ("{C59AA9F5-FF06-4A15-BB4F-945D7DAB69B7}") - :ClassName (tcp_protocol) - :table (protocols) - ) - :handler (citrix_ica_code) - :res_type (none) - :type (tcp_protocol) - ) - : (SQL_SLAMMER - :AdminInfo ( - :LastModified ( - :Time ("Thu Apr 10 17:36:34 2003") - :By (CheckPoint) - :From (CheckPoint) - ) - :chkpf_uid ("{A9B88863-0786-4961-B1E9-DDC2FA723135}") - :ClassName (udp_protocol) - :table (protocols) - ) - :handler (sql_worm_slammer) - :res_type (none) - :type (udp_protocol) - ) - : (FTP-BIDIR - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By (CheckPoint) - :From (CheckPoint) - ) - :chkpf_uid ("{8026ECE8-E867-4c4c-9E10-08AC73B709B1}") - :ClassName (tcp_protocol) - :table (protocols) - ) - :handler (ftp_bidir_code) - :res_type (ReferenceObject - :Name ("FTP spec") - :Table (resources_types) - :Uid ("{97AEB36F-9AEA-11D5-BD16-0090272CCB30}") - ) - :type (tcp_protocol) - ) - : (CIFS - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB373-9AEA-11D5-BD16-0090272CCB31}") - :ClassName (tcp_protocol) - :table (protocols) - ) - :handler () - :res_type (ReferenceObject - :Name ("CIFS spec") - :Table (resources_types) - :Uid ("{97AEB36D-9AEA-11D5-BD16-0090272CCB31}") - ) - :type (tcp_protocol) - ) - : (H.323_ANY - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By (CheckPoint) - :From (CheckPoint) - ) - :chkpf_uid ("{97AEB377-9AEA-11D5-BD16-0090272CCB35}") - :ClassName (tcp_protocol) - :table (protocols) - :name (H.323_ANY) - ) - :handler (h323_h225_code_any) - :res_type (none) - :type (tcp_protocol) - ) - : (H.323_RAS - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By (CheckPoint) - :From (CheckPoint) - ) - :chkpf_uid ("{97AEB378-9AEA-11D5-BD16-0090272CCB31}") - :ClassName (udp_protocol) - :table (protocols) - :name (H.323_RAS) - ) - :handler (h323_ras_code) - :res_type (none) - :type (udp_protocol) - ) - : (SIP_UDP - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By (CheckPoint) - :From (CheckPoint) - ) - :chkpf_uid ("{97AEB378-9AEA-11D5-BD16-0090272CCB37}") - :ClassName (udp_protocol) - :table (protocols) - :name (SIP_UDP) - ) - :handler (sip_manager) - :res_type (none) - :type (udp_protocol) - ) - : (SIP_UDP_ANY - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By (CheckPoint) - :From (CheckPoint) - ) - :chkpf_uid ("{97AEB378-9AEA-11D5-BD16-0090272CCB38}") - :ClassName (udp_protocol) - :table (protocols) - :name (SIP_UDP_ANY) - ) - :handler (sip_manager_any) - :res_type (none) - :type (udp_protocol) - ) - : (FTP - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB370-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (tcp_protocol) - :table (protocols) - :name (FTP) - ) - :handler (ftp_code) - :res_type (ReferenceObject - :Name ("FTP spec") - :Table (resources_types) - :Uid ("{97AEB36F-9AEA-11D5-BD16-0090272CCB30}") - ) - :type (tcp_protocol) - ) - : (FTP-PORT - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB371-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (tcp_protocol) - :table (protocols) - :name (FTP-PORT) - ) - :handler (ftp_port_code) - :res_type (ReferenceObject - :Name ("FTP spec") - :Table (resources_types) - :Uid ("{97AEB36F-9AEA-11D5-BD16-0090272CCB30}") - ) - :type (tcp_protocol) - ) - : (FTP-PASV - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB372-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (tcp_protocol) - :table (protocols) - :name (FTP-PASV) - ) - :handler (ftp_pasv_code) - :res_type (ReferenceObject - :Name ("FTP spec") - :Table (resources_types) - :Uid ("{97AEB36F-9AEA-11D5-BD16-0090272CCB30}") - ) - :type (tcp_protocol) - ) - : (HTTP - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB373-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (tcp_protocol) - :table (protocols) - :name (HTTP) - ) - :handler () - :res_type (ReferenceObject - :Name ("URI spec") - :Table (resources_types) - :Uid ("{97AEB36D-9AEA-11D5-BD16-0090272CCB30}") - ) - :type (tcp_protocol) - ) - : (SMTP - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB374-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (tcp_protocol) - :table (protocols) - :name (SMTP) - ) - :handler () - :res_type (ReferenceObject - :Name ("SMTP spec") - :Table (resources_types) - :Uid ("{97AEB36E-9AEA-11D5-BD16-0090272CCB30}") - ) - :type (tcp_protocol) - ) - : (RSHELL - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB375-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (tcp_protocol) - :table (protocols) - :name (RSHELL) - ) - :handler (rshstderr_code) - :res_type (none) - :type (tcp_protocol) - ) - : (SQLNET2 - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB376-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (tcp_protocol) - :table (protocols) - :name (SQLNET2) - ) - :handler (sqlnet_code) - :res_type (none) - :type (tcp_protocol) - ) - : (H.323 - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB377-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (tcp_protocol) - :table (protocols) - :name (H.323) - ) - :handler (h323_h225_code) - :res_type (none) - :type (tcp_protocol) - ) - : (DNS_UDP - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB378-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (udp_protocol) - :table (protocols) - :name (DNS_UDP) - ) - :handler (dns_verification_code) - :res_type (none) - :type (udp_protocol) - ) - : (DNS_TCP - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB379-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (tcp_protocol) - :table (protocols) - :name (DNS_TCP) - ) - :handler (dns_verification_code) - :res_type (none) - :type (tcp_protocol) - ) - : (PNA - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB37A-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (tcp_protocol) - :table (protocols) - :name (PNA) - ) - :handler (raudio_code) - :res_type (none) - :type (tcp_protocol) - ) - : (RTSP - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB37B-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (tcp_protocol) - :table (protocols) - :name (RTSP) - ) - :handler (rtsp_code) - :res_type (none) - :type (tcp_protocol) - ) - : (NetShow - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB37C-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (tcp_protocol) - :table (protocols) - :name (NetShow) - ) - :handler (netshow_code) - :res_type (none) - :type (tcp_protocol) - ) - : (CP-DHCP-request - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{71878CD2-B8A9-11D5-BB1D-D496C1818686}") - :ClassName (udp_protocol) - :table (protocols) - :name (CP-DHCP-request) - ) - :handler (dhcp_request_code) - :res_type (none) - :type (udp_protocol) - ) - : (CP-DHCP-reply - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{71879F1A-B8A9-11D5-BB1D-D496C1818686}") - :ClassName (udp_protocol) - :table (protocols) - :name (CP-DHCP-reply) - ) - :handler (dhcp_reply_code) - :res_type (none) - :type (udp_protocol) - ) - : (FreeTel - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB37E-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (udp_protocol) - :table (protocols) - :name (FreeTel) - ) - :handler (freetel_code) - :res_type (none) - :type (udp_protocol) - ) - : (BackWeb - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB37F-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (other_protocol) - :table (protocols) - :name (BackWeb) - ) - :handler (backweb_code) - :res_type (none) - :type (other_protocol) - ) - : (WinFrame - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB380-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (tcp_protocol) - :table (protocols) - :name (WinFrame) - ) - :handler (winframe_code) - :res_type (none) - :type (tcp_protocol) - ) - : (FW1_CVP - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB381-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (tcp_protocol) - :table (protocols) - :name (FW1_CVP) - ) - :handler (cvp_code) - :res_type (none) - :type (tcp_protocol) - ) - : (MSEXCHANGE - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB382-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (dcerpc_protocol) - :table (protocols) - :name (MSEXCHANGE) - ) - :handler (exchange_code) - :res_type (none) - :type (dcerpc_protocol) - ) - : (Snmp-Read - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB383-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (udp_protocol) - :table (protocols) - :name (Snmp-Read) - ) - :handler (snmp_ro_code) - :res_type (none) - :type (udp_protocol) - ) - : (NBNAME - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB384-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (udp_protocol) - :table (protocols) - :name (NBNAME) - ) - :handler (nbname_code) - :res_type (none) - :type (udp_protocol) - ) - : (NBDATAGRAM - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB385-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (udp_protocol) - :table (protocols) - :name (NBDATAGRAM) - ) - :handler (nbdatagram_code) - :res_type (none) - :type (udp_protocol) - ) - : (IIOP - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB386-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (tcp_protocol) - :table (protocols) - :name (IIOP) - ) - :handler (iiop_code) - :res_type (none) - :type (tcp_protocol) - ) - : (INSPECT - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB387-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (tcp_protocol) - :table (protocols) - :name (INSPECT) - ) - :handler (INSPECT) - :res_type (none) - :type (tcp_protocol) - ) - ) - :services (services - : (FW1_ica_mgmt_tools - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:07 2001") - :By (CheckPoint) - :From (CheckPoint) - ) - :chkpf_uid ("{97AEB44E-9AEA-11D5-BD16-0090272CCB31}") - :ClassName (tcp_service) - :table (services) - ) - :delayed_sync_value (30) - :reload_proof (false) - :sync_on_cluster (true) - :use_delayed_sync (false) - :color (FireBrick) - :comments ("Check Point Internal CA Management Tools") - :enable_tcp_resource (false) - :etm_enabled (false) - :include_in_any (true) - :port (18265) - :proto_type () - :src_port () - :timeout (0) - :type (tcp) - ) - : (IPSO_Clustering_Mgmt_Protocol - :AdminInfo ( - :LastModified ( - :Time ("Thu Feb 13 07:43:26 2003") - :By (CheckPoint) - :From (CheckPoint) - ) - :chkpf_uid ("{BD824B60-5C5A-42E8-A8E6-348A35CEF8C4}") - :ClassName (tcp_service) - :table (services) - :Wiznum (-1) - ) - :color (black) - :comments ("used for distributing configuration changes among cluster members and cluster wide monitoring") - :delayed_sync_value (0) - :enable_tcp_resource (false) - :etm_enabled (false) - :include_in_any (true) - :port (1111) - :proto_type () - :reload_proof (true) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (Tcp) - :use_delayed_sync (false) - ) - : (microsoft-ds-udp - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:07 2001") - :By (CheckPoint) - :From (CheckPoint) - ) - :chkpf_uid ("{97AEB390-9AEA-11D5-BD16-0090272CCB31}") - :ClassName (udp_service) - :table (services) - ) - :delete_on_reply (false) - :reload_proof (false) - :sync_on_cluster (true) - :color (FireBrick) - :comments ("Microsoft CIFS over UDP") - :etm_enabled (false) - :include_in_any (true) - :port (445) - :proto_type () - :replies (true) - :replies_from_any_port (false) - :src_port () - :timeout (0) - :type (udp) - ) - : (ssh_version_2 - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By (CheckPoint) - :From (CheckPoint) - ) - :chkpf_uid ("{CD082D9A-44A6-4CEF-A17D-5541029ADFB3}") - :ClassName (tcp_service) - :table (services) - ) - :delayed_sync_value (30) - :reload_proof (false) - :sync_on_cluster (true) - :use_delayed_sync (false) - :color (Blue) - :comments ("Secure Shell, version 1.x block") - :enable_tcp_resource (false) - :etm_enabled (false) - :include_in_any (false) - :port (22) - :proto_type (ReferenceObject - :Name (SSH2) - :Table (protocols) - :Uid ("{55F4C5D7-60D9-44B3-9BD4-C3F76B7C8360}") - ) - :src_port () - :timeout (0) - :type (tcp) - ) - : (Citrix_ICA_printing - :AdminInfo ( - :chkpf_uid ("{0A3667B6-800B-49A9-A655-087CD970AC27}") - :ClassName (tcp_citrix_service) - :table (services) - :Deleteable (false) - :Renameable (false) - :Wiznum (-1) - :LastModified ( - :Time ("Sun Mar 30 14:42:57 2003") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :citrix_application_name (All_citrix_ICA_printing) - :color (black) - :comments ("Citrix ICA printing traffic") - :etm_enabled (false) - :is_printing (true) - :port (1494) - :proto_type () - :reload_proof (false) - :type (tcp_citrix) - ) - : (Citrix_ICA_Browsing - :AdminInfo ( - :chkpf_uid ("{E8C5AB78-F08D-437C-A9B1-BE4A8679D766}") - :ClassName (udp_service) - :table (services) - :Wiznum (-1) - :LastModified ( - :Time ("Sun Mar 30 14:49:31 2003") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :color (black) - :comments ("Tcp Service for general Citrix browsing") - :delete_on_reply (false) - :etm_enabled (false) - :include_in_any (false) - :port (1604) - :proto_type () - :reload_proof (false) - :replies (true) - :replies_from_any_port (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (Udp) - ) - : (GTPv0 - :AdminInfo ( - :chkpf_uid ("{3A5AD81B-3BFA-4396-97B2-2581B33790B5}") - :ClassName (udp_service) - :table (services) - :Wiznum (-1) - :Deleteable (false) - :Hidden (true) - :LastModified ( - :Time ("Tue Dec 24 12:37:31 2002") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :color (black) - :delete_on_reply (false) - :etm_enabled (false) - :proto_type () - :reload_proof (false) - :replies (true) - :replies_from_any_port (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :comments ("used only for log resolving") - :include_in_any (false) - :port (3386) - :type (Udp) - ) - : (GTPv1-C - :AdminInfo ( - :chkpf_uid ("{0A95FEAA-A655-484D-BE5E-E6D38A6937A5}") - :ClassName (udp_service) - :table (services) - :Wiznum (-1) - :Deleteable (false) - :Hidden (true) - :LastModified ( - :Time ("Tue Dec 24 10:47:41 2002") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :color (black) - :delete_on_reply (false) - :etm_enabled (false) - :proto_type () - :reload_proof (false) - :replies (true) - :replies_from_any_port (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :comments ("used only for log resolving") - :include_in_any (false) - :port (2123) - :type (Udp) - ) - : (GTPv1-U - :AdminInfo ( - :chkpf_uid ("{A1B5DB0A-FA8D-4821-B4DE-B7A8E9435EF6}") - :ClassName (udp_service) - :table (services) - :Wiznum (-1) - :Deleteable (false) - :Hidden (true) - :LastModified ( - :Time ("Tue Dec 24 10:48:43 2002") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :color (black) - :delete_on_reply (false) - :etm_enabled (false) - :proto_type () - :reload_proof (false) - :replies (true) - :replies_from_any_port (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :comments ("used only for log resolving") - :include_in_any (false) - :port (2152) - :type (Udp) - ) - : (Citrix_ICA - :AdminInfo ( - :chkpf_uid ("{986BAD5A-94D2-4A8C-81AA-DE98D3ECB5C6}") - :ClassName (tcp_service) - :table (services) - :Wiznum (-1) - :LastModified ( - :Time ("Sun Mar 30 14:48:11 2003") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :color (black) - :comments ("Citrix ICA general Service.") - :delayed_sync_value (30) - :enable_tcp_resource (false) - :etm_enabled (false) - :include_in_any (false) - :port (1494) - :proto_type (ReferenceObject - :Name (CitrixICA) - :Table (protocols) - :Uid ("{C59AA9F5-FF06-4A15-BB4F-945D7DAB69B7}") - ) - :reload_proof (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (Tcp) - :use_delayed_sync (false) - ) - : (Kerberos_v5_TCP - :AdminInfo ( - :chkpf_uid ("{8D807250-57EB-4051-9AEC-E6128260261B}") - :ClassName (tcp_service) - :table (services) - :Wiznum (-1) - :LastModified ( - :Time ("Thu Jan 09 15:58:26 2003") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :color (black) - :comments ("Kerberos authentication protocol (version 5)") - :delayed_sync_value (0) - :enable_tcp_resource (false) - :etm_enabled (false) - :include_in_any (true) - :port (88) - :proto_type () - :reload_proof (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (Tcp) - :use_delayed_sync (false) - ) - : (Kerberos_v5_UDP - :AdminInfo ( - :chkpf_uid ("{8C137030-A995-4E96-AAAE-5F5BC74E7B4E}") - :ClassName (udp_service) - :table (services) - :Wiznum (-1) - :LastModified ( - :Time ("Thu Jan 09 15:58:37 2003") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :color (black) - :comments ("Kerberos authentication protocol (version 5)") - :delete_on_reply (false) - :etm_enabled (false) - :include_in_any (true) - :port (88) - :proto_type () - :reload_proof (false) - :replies (true) - :replies_from_any_port (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (Udp) - ) - : (ssl_v3 - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By (CheckPoint) - :From (CheckPoint) - ) - :chkpf_uid ("{69815F35-2A03-4121-8335-23A337DCE927}") - :ClassName (tcp_service) - :table (services) - ) - :delayed_sync_value (30) - :reload_proof (false) - :sync_on_cluster (true) - :use_delayed_sync (false) - :color (Blue) - :comments ("SSL version 3, droping anything else.") - :enable_tcp_resource (false) - :etm_enabled (false) - :include_in_any (false) - :port (443) - :proto_type (ReferenceObject - :Name (SSL_V3) - :Table (protocols) - :Uid ("{16A704F7-7BD7-49BD-A52A-525AAEDAE7AB}") - ) - :src_port () - :timeout (0) - :type (tcp) - ) - : (SWTP_SMS - :AdminInfo ( - :chkpf_uid ("{6A40F044-296B-4611-8105-FE83284BAF03}") - :ClassName (udp_service) - :table (services) - :Wiznum (-1) - :LastModified ( - :Time ("Wed Apr 09 22:29:17 2003") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :color (black) - :comments ("VPN-1 embedded / SofaWare Management Server (SMS)") - :delete_on_reply (false) - :etm_enabled (false) - :include_in_any (true) - :port (9282) - :proto_type () - :reload_proof (false) - :replies (true) - :replies_from_any_port (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (Udp) - ) - : (SWTP_Gateway - :AdminInfo ( - :chkpf_uid ("{1649FC50-B2B3-4A95-9839-802DA7108629}") - :ClassName (udp_service) - :table (services) - :Wiznum (-1) - :LastModified ( - :Time ("Mon Oct 13 10:23:43 2003") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :color (black) - :comments ("VPN-1 Embedded/SofaWare commands") - :delete_on_reply (false) - :etm_enabled (false) - :include_in_any (true) - :port (9281) - :proto_type () - :reload_proof (false) - :replies (true) - :replies_from_any_port (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (Udp) - ) - : (DCOM-RemoteActivation - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 15 14:54:08 2003") - :By (CheckPoint) - :From (CheckPoint) - ) - :chkpf_uid ("{5C66B970-E289-4B39-89EA-4F0F19A389D7}") - :ClassName (dcerpc_service) - :table (services) - ) - :color (black) - :comments ("DCOM Remote Activation") - :etm_enabled (false) - :proto_type () - :reload_proof (false) - :type (dcerpc) - :uuid (4d9f4ab8-7d1c-11cf-861e-0020af6e7c57) - ) - : (ALL_DCE_RPC - :AdminInfo ( - :chkpf_uid ("{3D0D46B6-4DDB-43E0-9FAA-C969DBC3E19F}") - :ClassName (dcerpc_service) - :table (services) - :Wiznum (-1) - :LastModified ( - :Time ("Thu May 1 08:34:11 2003") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :color (red) - :comments ("Special Service For Allowing All DCE-RPC Services") - :etm_enabled (false) - :proto_type () - :reload_proof (false) - :type (DceRpc) - :uuid (00000000-0000-0000-0000-000000000000) - ) - : (MSNP - :AdminInfo ( - :chkpf_uid ("{D18F244B-0B13-4FB8-AA2F-D966EEFFB6B3}") - :ClassName (tcp_service) - :table (services) - :LastModified ( - :Time ("Tue Oct 22 13:25:25 2002") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :delayed_sync_value (30) - :use_delayed_sync (false) - :color (black) - :comments ("MSN Messenger") - :enable_tcp_resource (false) - :etm_enabled (false) - :include_in_any (true) - :port (1863) - :proto_type () - :reload_proof (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (tcp) - ) - : (ttdbserverd - :AdminInfo ( - :chkpf_uid ("{320ADBC3-F4F0-4254-A7A4-79DEE1726B8C}") - :ClassName (rpc_service) - :table (services) - :Wiznum (-1) - :LastModified ( - :Time ("Mon Oct 14 15:45:43 2002") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :color (black) - :comments ("ToolTalk database server") - :etm_enabled (false) - :port (100083) - :proto_type () - :reload_proof (false) - :type (Rpc) - ) - : (cmsd - :AdminInfo ( - :chkpf_uid ("{968C527C-2191-4BEA-ABF3-F41DA07F20DC}") - :ClassName (rpc_service) - :table (services) - :Wiznum (-1) - :LastModified ( - :Time ("Mon Oct 14 15:46:27 2002") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :color (black) - :comments ("Calendar Manager Service Daemon") - :etm_enabled (false) - :port (100068) - :proto_type () - :reload_proof (false) - :type (Rpc) - ) - : (statd - :AdminInfo ( - :chkpf_uid ("{FC4E8697-6C1F-4152-94F1-C9A2AE21EF6E}") - :ClassName (rpc_service) - :table (services) - :Wiznum (-1) - :LastModified ( - :Time ("Mon Oct 14 15:46:44 2002") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :color (black) - :comments ("Network status monitor daemon") - :etm_enabled (false) - :port (100024) - :proto_type () - :reload_proof (false) - :type (Rpc) - ) - : (sadmind - :AdminInfo ( - :chkpf_uid ("{5FF55D69-74F8-46E0-9D21-A2163A906D76}") - :ClassName (rpc_service) - :table (services) - :Wiznum (-1) - :LastModified ( - :Time ("Mon Oct 14 15:47:08 2002") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :color (black) - :comments ("Solstice AdminSuite") - :etm_enabled (false) - :port (100232) - :proto_type () - :reload_proof (false) - :type (Rpc) - ) - : (cachefsd - :AdminInfo ( - :chkpf_uid ("{F4C95E3E-A820-4B35-B35E-0AFB703EB11E}") - :ClassName (rpc_service) - :table (services) - :Wiznum (-1) - :LastModified ( - :Time ("Mon Oct 14 15:47:36 2002") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :color (burlywood4) - :comments ("SUN NFS/RPC file system cachefs daemon") - :etm_enabled (false) - :port (100235) - :proto_type () - :reload_proof (false) - :type (Rpc) - ) - : (snmpXdmid - :AdminInfo ( - :chkpf_uid ("{953DFC46-7EAD-4D97-9ADE-6560D79DB563}") - :ClassName (rpc_service) - :table (services) - :Wiznum (-1) - :LastModified ( - :Time ("Mon Oct 14 15:48:02 2002") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :color (burlywood4) - :comments ("SUN SNMP to DMI mapper daemon") - :etm_enabled (false) - :port (100249) - :proto_type () - :reload_proof (false) - :type (Rpc) - ) - : (ICQ_locator - :AdminInfo ( - :chkpf_uid ("{BBEC6807-808D-49B7-B8DC-54C5A655D392}") - :ClassName (udp_service) - :table (services) - :Wiznum (-1) - :LastModified ( - :Time ("Sun Dec 08 12:36:19 2002") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :color (black) - :comments ("Mirabilis ICQ versions") - :delete_on_reply (false) - :etm_enabled (false) - :include_in_any (true) - :port (4000) - :proto_type () - :reload_proof (false) - :replies (true) - :replies_from_any_port (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (Udp) - ) - : (MSN_Messenger_1863_UDP - :AdminInfo ( - :chkpf_uid ("{0094AAC2-A29E-4D04-B86C-F31F63DFFAE2}") - :ClassName (udp_service) - :table (services) - :Wiznum (-1) - :LastModified ( - :Time ("Sun Dec 08 12:37:27 2002") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :color (black) - :comments ("Microsoft Network Messenger UDP") - :delete_on_reply (false) - :etm_enabled (false) - :include_in_any (true) - :port (1863) - :proto_type () - :reload_proof (false) - :replies (true) - :replies_from_any_port (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (Udp) - ) - : (MSN_Messenger_5190 - :AdminInfo ( - :chkpf_uid ("{0AC39B6A-701A-4C33-A88D-9EB0FECF9EF6}") - :ClassName (udp_service) - :table (services) - :Wiznum (-1) - :LastModified ( - :Time ("Sun Dec 08 12:38:08 2002") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :color (black) - :comments ("Microsoft Network Messenger") - :delete_on_reply (false) - :etm_enabled (false) - :include_in_any (true) - :port (5190) - :proto_type () - :reload_proof (false) - :replies (true) - :replies_from_any_port (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (Udp) - ) - : (MSN_Messenger_File_Transfer - :AdminInfo ( - :chkpf_uid ("{505BADAD-AE57-4584-9A4C-15987C093A32}") - :ClassName (tcp_service) - :table (services) - :Wiznum (-1) - :LastModified ( - :Time ("Sun Dec 08 12:39:01 2002") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :color (black) - :comments ("Microsoft Network Messenger File Transfer") - :delayed_sync_value (0) - :enable_tcp_resource (false) - :etm_enabled (false) - :include_in_any (true) - :port (6891-6900) - :proto_type () - :reload_proof (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (Tcp) - :use_delayed_sync (false) - ) - : (MSN_Messenger_Voice - :AdminInfo ( - :chkpf_uid ("{E3E6D587-3212-4FF4-86A1-D16093689E19}") - :ClassName (udp_service) - :table (services) - :Wiznum (-1) - :LastModified ( - :Time ("Sun Dec 08 12:39:30 2002") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :color (black) - :comments ("Microsoft Network Messenger Voice communication") - :delete_on_reply (false) - :etm_enabled (false) - :include_in_any (true) - :port (6901) - :proto_type () - :reload_proof (false) - :replies (true) - :replies_from_any_port (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (Udp) - ) - : (Yahoo_Messenger_messages - :AdminInfo ( - :chkpf_uid ("{24CD3A7C-AA2C-43D4-8EB6-FF1F070143EA}") - :ClassName (tcp_service) - :table (services) - :Wiznum (-1) - :LastModified ( - :Time ("Sun Dec 08 12:40:02 2002") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :color (black) - :comments ("Yahoo Messenger messages") - :delayed_sync_value (0) - :enable_tcp_resource (false) - :etm_enabled (false) - :include_in_any (true) - :port (5050) - :proto_type () - :reload_proof (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (Tcp) - :use_delayed_sync (false) - ) - : (Yahoo_Messenger_Voice_Chat_TCP - :AdminInfo ( - :chkpf_uid ("{C2639E22-FD63-4520-99F7-A70215B95874}") - :ClassName (tcp_service) - :table (services) - :Wiznum (-1) - :LastModified ( - :Time ("Thu Dec 12 14:03:50 2002") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :color (black) - :comments ("Yahoo Messenger Voice Chat") - :delayed_sync_value (0) - :enable_tcp_resource (false) - :etm_enabled (false) - :include_in_any (false) - :port (5000-5001) - :proto_type () - :reload_proof (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (Tcp) - :use_delayed_sync (false) - ) - : (Yahoo_Messenger_Voice_Chat_UDP - :AdminInfo ( - :chkpf_uid ("{C98BB09A-B04F-437C-AD1A-6C8261831B87}") - :ClassName (udp_service) - :table (services) - :Wiznum (-1) - :LastModified ( - :Time ("Sun Dec 08 12:41:22 2002") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :color (black) - :comments ("Yahoo Messenger Voice Chat") - :delete_on_reply (false) - :etm_enabled (false) - :include_in_any (true) - :port (5000-5010) - :proto_type () - :reload_proof (false) - :replies (true) - :replies_from_any_port (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (Udp) - ) - : (Yahoo_Messenger_Webcams - :AdminInfo ( - :chkpf_uid ("{910F509F-8F2A-452D-BC15-E51F8CC1694C}") - :ClassName (tcp_service) - :table (services) - :Wiznum (-1) - :LastModified ( - :Time ("Sun Dec 08 12:41:53 2002") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :color (black) - :comments ("Yahoo Messenger Webcams video") - :delayed_sync_value (0) - :enable_tcp_resource (false) - :etm_enabled (false) - :include_in_any (true) - :port (5100) - :proto_type () - :reload_proof (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (Tcp) - :use_delayed_sync (false) - ) - : (Direct_Connect_TCP - :AdminInfo ( - :chkpf_uid ("{D02080C1-B225-4DA0-987B-28B3A551B8C9}") - :ClassName (tcp_service) - :table (services) - :Wiznum (-1) - :LastModified ( - :Time ("Sun Dec 08 12:42:27 2002") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :color (black) - :comments ("Direct Connect P2P application. Used also by other clients") - :delayed_sync_value (0) - :enable_tcp_resource (false) - :etm_enabled (false) - :include_in_any (true) - :port (411-412) - :proto_type () - :reload_proof (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (Tcp) - :use_delayed_sync (false) - ) - : (Direct_Connect_UDP - :AdminInfo ( - :chkpf_uid ("{64C3AD3F-69D2-4EC1-B843-5DF030C70ABF}") - :ClassName (udp_service) - :table (services) - :Wiznum (-1) - :LastModified ( - :Time ("Sun Dec 08 12:42:59 2002") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :color (black) - :comments ("Direct Connect P2P application. Used also by other clients") - :delete_on_reply (false) - :etm_enabled (false) - :include_in_any (true) - :port (411-412) - :proto_type () - :reload_proof (false) - :replies (true) - :replies_from_any_port (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (Udp) - ) - : (eDonkey_4661 - :AdminInfo ( - :chkpf_uid ("{760D9035-1C76-4C5C-B929-BA1DC6685D6F}") - :ClassName (tcp_service) - :table (services) - :Wiznum (-1) - :LastModified ( - :Time ("Sun Dec 08 12:43:26 2002") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :color (black) - :comments ("eDonkey protocol. Used also by other clients.") - :delayed_sync_value (0) - :enable_tcp_resource (false) - :etm_enabled (false) - :include_in_any (true) - :port (4661) - :proto_type () - :reload_proof (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (Tcp) - :use_delayed_sync (false) - ) - : (eDonkey_4662 - :AdminInfo ( - :chkpf_uid ("{7115E261-185C-4487-AA18-84F8C275D186}") - :ClassName (tcp_service) - :table (services) - :Wiznum (-1) - :LastModified ( - :Time ("Sun Dec 08 12:43:49 2002") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :color (black) - :comments ("eDonkey protocol. Used also by other clients.") - :delayed_sync_value (0) - :enable_tcp_resource (false) - :etm_enabled (false) - :include_in_any (true) - :port (4662) - :proto_type () - :reload_proof (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (Tcp) - :use_delayed_sync (false) - ) - : (GNUtella_rtr_TCP - :AdminInfo ( - :chkpf_uid ("{B1189907-B9EB-4A21-8B38-1D3E5C6C06D0}") - :ClassName (tcp_service) - :table (services) - :Wiznum (-1) - :LastModified ( - :Time ("Sun Dec 08 12:44:57 2002") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :color (black) - :comments ("Also used by: BearShare, ToadNode, Gnucleus, Xolox, LimeWire") - :delayed_sync_value (0) - :enable_tcp_resource (false) - :etm_enabled (false) - :include_in_any (true) - :port (6347) - :proto_type () - :reload_proof (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (Tcp) - :use_delayed_sync (false) - ) - : (GNUtella_rtr_UDP - :AdminInfo ( - :chkpf_uid ("{1B4543A3-579E-4CC7-8F57-4387C37A6815}") - :ClassName (udp_service) - :table (services) - :Wiznum (-1) - :LastModified ( - :Time ("Sun Dec 08 12:45:16 2002") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :color (black) - :comments ("Also used by: BearShare, ToadNode, Gnucleus, Xolox, LimeWire") - :delete_on_reply (false) - :etm_enabled (false) - :include_in_any (true) - :port (6347) - :proto_type () - :reload_proof (false) - :replies (true) - :replies_from_any_port (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (Udp) - ) - : (GNUtella_TCP - :AdminInfo ( - :chkpf_uid ("{CDEF1FEB-485E-4929-942E-011DE8318E56}") - :ClassName (tcp_service) - :table (services) - :Wiznum (-1) - :LastModified ( - :Time ("Sun Dec 08 12:45:56 2002") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :color (black) - :comments ("Also used by: BearShare, ToadNode, Gnucleus, Xolox, LimeWire") - :delayed_sync_value (0) - :enable_tcp_resource (false) - :etm_enabled (false) - :include_in_any (true) - :port (6346) - :proto_type () - :reload_proof (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (Tcp) - :use_delayed_sync (false) - ) - : (GNUtella_UDP - :AdminInfo ( - :chkpf_uid ("{8EB18480-2690-4520-AE88-412BF5CE94E3}") - :ClassName (udp_service) - :table (services) - :Wiznum (-1) - :LastModified ( - :Time ("Sun Dec 08 12:46:33 2002") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :color (black) - :comments ("Also used by: BearShare, ToadNode, Gnucleus, Xolox, LimeWire") - :delete_on_reply (false) - :etm_enabled (false) - :include_in_any (true) - :port (6346) - :proto_type () - :reload_proof (false) - :replies (true) - :replies_from_any_port (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (Udp) - ) - : (Hotline_client - :AdminInfo ( - :chkpf_uid ("{B45556D9-5E0B-46F4-9C35-ED7D82BEC43D}") - :ClassName (tcp_service) - :table (services) - :Wiznum (-1) - :LastModified ( - :Time ("Sun Dec 08 12:47:07 2002") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :color (black) - :comments ("Hotline client connections") - :delayed_sync_value (0) - :enable_tcp_resource (false) - :etm_enabled (false) - :include_in_any (true) - :port (5500-5503) - :proto_type () - :reload_proof (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (Tcp) - :use_delayed_sync (false) - ) - : (Hotline_tracker - :AdminInfo ( - :chkpf_uid ("{D6B64DF2-4803-4D79-9794-793D18B277D8}") - :ClassName (udp_service) - :table (services) - :Wiznum (-1) - :LastModified ( - :Time ("Sun Dec 08 12:47:41 2002") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :color (black) - :comments ("Hotline tracker connections") - :delete_on_reply (false) - :etm_enabled (false) - :include_in_any (true) - :port (5499) - :proto_type () - :reload_proof (false) - :replies (true) - :replies_from_any_port (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (Udp) - ) - : (Napster_Client_6600-6699 - :AdminInfo ( - :chkpf_uid ("{3BB26988-E0A5-45D6-8018-D4D4DE8B96FA}") - :ClassName (tcp_service) - :table (services) - :Wiznum (-1) - :LastModified ( - :Time ("Sun Dec 08 12:48:46 2002") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :color (black) - :comments ("Napster clients. Also used by: WinMX") - :delayed_sync_value (0) - :enable_tcp_resource (false) - :etm_enabled (false) - :include_in_any (false) - :port (6600-6699) - :proto_type () - :reload_proof (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (Tcp) - :use_delayed_sync (false) - ) - : (Napster_directory_4444 - :AdminInfo ( - :chkpf_uid ("{741A5B0E-3788-4284-91A1-819E99D9ED96}") - :ClassName (tcp_service) - :table (services) - :Wiznum (-1) - :LastModified ( - :Time ("Sun Dec 08 12:49:50 2002") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :color (black) - :comments ("Napster directory connections") - :delayed_sync_value (0) - :enable_tcp_resource (false) - :etm_enabled (false) - :include_in_any (true) - :port (4444) - :proto_type () - :reload_proof (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (Tcp) - :use_delayed_sync (false) - ) - : (Napster_directory_5555 - :AdminInfo ( - :chkpf_uid ("{8287D6D8-3B6B-4824-8F2D-18BC570EC9B2}") - :ClassName (tcp_service) - :table (services) - :Wiznum (-1) - :LastModified ( - :Time ("Sun Dec 08 12:50:15 2002") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :color (black) - :comments ("Napster directory connections") - :delayed_sync_value (0) - :enable_tcp_resource (false) - :etm_enabled (false) - :include_in_any (true) - :port (5555) - :proto_type () - :reload_proof (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (Tcp) - :use_delayed_sync (false) - ) - : (Napster_directory_6666 - :AdminInfo ( - :chkpf_uid ("{1EF8FC95-FF10-414B-AF76-C0BCC2CD711E}") - :ClassName (tcp_service) - :table (services) - :Wiznum (-1) - :LastModified ( - :Time ("Sun Dec 08 12:50:49 2002") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :color (black) - :comments ("Napster directory connections") - :delayed_sync_value (0) - :enable_tcp_resource (false) - :etm_enabled (false) - :include_in_any (false) - :port (6666) - :proto_type () - :reload_proof (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (Tcp) - :use_delayed_sync (false) - ) - : (Napster_directory_7777 - :AdminInfo ( - :chkpf_uid ("{182B1D39-54B6-4E2F-BAE8-2D8021D52206}") - :ClassName (tcp_service) - :table (services) - :Wiznum (-1) - :LastModified ( - :Time ("Sun Dec 08 12:51:15 2002") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :color (black) - :comments ("Napster directory connections") - :delayed_sync_value (0) - :enable_tcp_resource (false) - :etm_enabled (false) - :include_in_any (true) - :port (7777) - :proto_type () - :reload_proof (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (Tcp) - :use_delayed_sync (false) - ) - : (Napster_directory_8888_primary - :AdminInfo ( - :chkpf_uid ("{BE51561E-7876-4C70-9546-0914AE737F6E}") - :ClassName (tcp_service) - :table (services) - :Wiznum (-1) - :LastModified ( - :Time ("Sun Dec 08 12:51:47 2002") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :color (black) - :comments ("Napster directory connections (Primary)") - :delayed_sync_value (0) - :enable_tcp_resource (false) - :etm_enabled (false) - :include_in_any (true) - :port (8888) - :proto_type () - :reload_proof (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (Tcp) - :use_delayed_sync (false) - ) - : (Napster_redirector - :AdminInfo ( - :chkpf_uid ("{3FD0D58A-9759-4686-B103-D177ADFC7193}") - :ClassName (tcp_service) - :table (services) - :Wiznum (-1) - :LastModified ( - :Time ("Sun Dec 08 12:52:06 2002") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :color (black) - :comments () - :delayed_sync_value (0) - :enable_tcp_resource (false) - :etm_enabled (false) - :include_in_any (true) - :port (8875) - :proto_type () - :reload_proof (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (Tcp) - :use_delayed_sync (false) - ) - : (Blubster - :AdminInfo ( - :chkpf_uid ("{C86F055D-31AD-4430-B12C-1094A86C673C}") - :ClassName (udp_service) - :table (services) - :Wiznum (-1) - :LastModified ( - :Time ("Sun Dec 08 12:52:35 2002") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :color (black) - :comments ("Uses MANOLITO protocol") - :delete_on_reply (false) - :etm_enabled (false) - :include_in_any (true) - :port (41170) - :proto_type () - :reload_proof (false) - :replies (true) - :replies_from_any_port (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (Udp) - ) - : (GoToMyPC - :AdminInfo ( - :chkpf_uid ("{2D89310C-5761-4213-BEF5-C81BB5677E44}") - :ClassName (tcp_service) - :table (services) - :Wiznum (-1) - :LastModified ( - :Time ("Sun Dec 08 12:52:59 2002") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :color (black) - :comments ("Remote Computer Access & Sharing application, also uses HTTP and HTTPS") - :delayed_sync_value (0) - :enable_tcp_resource (false) - :etm_enabled (false) - :include_in_any (true) - :port (8200) - :proto_type () - :reload_proof (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (Tcp) - :use_delayed_sync (false) - ) - : (iMesh - :AdminInfo ( - :chkpf_uid ("{01E9FC32-73DF-43D5-9CD4-4F91B6A5C711}") - :ClassName (tcp_service) - :table (services) - :Wiznum (-1) - :LastModified ( - :Time ("Sun Dec 08 12:53:25 2002") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :color (black) - :comments ("This port also used by many trojans and the upnp service") - :delayed_sync_value (0) - :enable_tcp_resource (false) - :etm_enabled (false) - :include_in_any (true) - :port (5000) - :proto_type () - :reload_proof (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (Tcp) - :use_delayed_sync (false) - ) - : (Madster - :AdminInfo ( - :chkpf_uid ("{B863EC35-604F-4DA1-8E63-82A7903D2C1C}") - :ClassName (tcp_service) - :table (services) - :Wiznum (-1) - :LastModified ( - :Time ("Sun Dec 08 12:54:13 2002") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :color (black) - :comments ("Formerly called Aimster") - :delayed_sync_value (0) - :enable_tcp_resource (false) - :etm_enabled (false) - :include_in_any (true) - :port (5025) - :proto_type () - :reload_proof (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (Tcp) - :use_delayed_sync (false) - ) - : (RAT - :AdminInfo ( - :chkpf_uid ("{B236D830-9615-4578-B6E2-B0B44C45FDA0}") - :ClassName (tcp_service) - :table (services) - :Wiznum (-1) - :LastModified ( - :Time ("Tue Jan 07 18:21:52 2003") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :color ("deep pink") - :comments ("RAT trojan (Remote Administration Tool)") - :delayed_sync_value (0) - :enable_tcp_resource (false) - :etm_enabled (false) - :include_in_any (true) - :port (1097-1098) - :proto_type () - :reload_proof (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (Tcp) - :use_delayed_sync (false) - ) - : (Multidropper - :AdminInfo ( - :chkpf_uid ("{E38E4DEA-A610-4416-BF44-6F4E45E95E70}") - :ClassName (tcp_service) - :table (services) - :Wiznum (-1) - :LastModified ( - :Time ("Tue Jan 07 18:28:06 2003") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :color ("deep pink") - :comments ("Multidropper trojan") - :delayed_sync_value (0) - :enable_tcp_resource (false) - :etm_enabled (false) - :include_in_any (true) - :port (1035) - :proto_type () - :reload_proof (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (Tcp) - :use_delayed_sync (false) - ) - : (Kaos - :AdminInfo ( - :chkpf_uid ("{10F56849-2E03-40DD-9CF7-56AEE2CFA57F}") - :ClassName (tcp_service) - :table (services) - :Wiznum (-1) - :LastModified ( - :Time ("Tue Jan 07 18:29:24 2003") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :color ("deep pink") - :comments ("Kaos trojan") - :delayed_sync_value (0) - :enable_tcp_resource (false) - :etm_enabled (false) - :include_in_any (true) - :port (1212) - :proto_type () - :reload_proof (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (Tcp) - :use_delayed_sync (false) - ) - : (Connect-Back_Backdoor - :AdminInfo ( - :chkpf_uid ("{E0C17142-433D-40A7-9EAA-E1D5EBA40D2E}") - :ClassName (tcp_service) - :table (services) - :Wiznum (-1) - :LastModified ( - :Time ("Tue Jan 07 18:32:26 2003") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :color (magenta) - :comments ("Also used by SkyDance trojan") - :delayed_sync_value (0) - :enable_tcp_resource (false) - :etm_enabled (false) - :include_in_any (true) - :port (4000) - :proto_type () - :reload_proof (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (Tcp) - :use_delayed_sync (false) - ) - : (DerSphere - :AdminInfo ( - :chkpf_uid ("{8055B0DE-DACE-4D18-91F4-F39915B7ABA8}") - :ClassName (tcp_service) - :table (services) - :Wiznum (-1) - :LastModified ( - :Time ("Tue Jan 07 18:34:45 2003") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :color (magenta) - :comments ("Also used by: Direct Connection,Connecter,Insane Network trojans") - :delayed_sync_value (0) - :enable_tcp_resource (false) - :etm_enabled (false) - :include_in_any (true) - :port (1000) - :proto_type () - :reload_proof (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (Tcp) - :use_delayed_sync (false) - ) - : (Freak2k - :AdminInfo ( - :chkpf_uid ("{08DA33FF-BC5F-402A-9865-BEE8FEE69422}") - :ClassName (tcp_service) - :table (services) - :Wiznum (-1) - :LastModified ( - :Time ("Tue Jan 07 18:36:23 2003") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :color (magenta) - :comments ("Also used by: Freak88,NetSnooper Gold trojans") - :delayed_sync_value (0) - :enable_tcp_resource (false) - :etm_enabled (false) - :include_in_any (true) - :port (7001) - :proto_type () - :reload_proof (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (Tcp) - :use_delayed_sync (false) - ) - : (Jade - :AdminInfo ( - :chkpf_uid ("{C2F963B0-DB3C-42D5-B0F2-A2A7BC0D378D}") - :ClassName (tcp_service) - :table (services) - :Wiznum (-1) - :LastModified ( - :Time ("Tue Jan 07 18:40:18 2003") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :color (magenta) - :comments ("Also used by: Latinus,NetSpy,RAT trojans and K Display Manager") - :delayed_sync_value (0) - :enable_tcp_resource (false) - :etm_enabled (false) - :include_in_any (true) - :port (1024) - :proto_type () - :reload_proof (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (Tcp) - :use_delayed_sync (false) - ) - : (GateCrasher - :AdminInfo ( - :chkpf_uid ("{81B90130-2A31-45CD-8092-DC492B116CA9}") - :ClassName (tcp_service) - :table (services) - :Wiznum (-1) - :LastModified ( - :Time ("Tue Jan 07 18:41:23 2003") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :color ("deep pink") - :comments ("GateCrasher trojan") - :delayed_sync_value (0) - :enable_tcp_resource (false) - :etm_enabled (false) - :include_in_any (true) - :port (6970) - :proto_type () - :reload_proof (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (Tcp) - :use_delayed_sync (false) - ) - : (Kuang2 - :AdminInfo ( - :chkpf_uid ("{CE29B597-76B9-48AA-AC24-AE7E23C438ED}") - :ClassName (tcp_service) - :table (services) - :Wiznum (-1) - :LastModified ( - :Time ("Tue Jan 07 18:49:08 2003") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :color (magenta) - :comments ("Kuang2 trojan") - :delayed_sync_value (0) - :enable_tcp_resource (false) - :etm_enabled (false) - :include_in_any (true) - :port (17300) - :proto_type () - :reload_proof (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (Tcp) - :use_delayed_sync (false) - ) - : (WinHole - :AdminInfo ( - :chkpf_uid ("{25AC306E-1FC9-4E3E-BF66-4A48473CAF3F}") - :ClassName (tcp_service) - :table (services) - :Wiznum (-1) - :LastModified ( - :Time ("Tue Jan 07 18:50:10 2003") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :color ("deep pink") - :comments ("WinHole trojan") - :delayed_sync_value (0) - :enable_tcp_resource (false) - :etm_enabled (false) - :include_in_any (true) - :port (1081) - :proto_type () - :reload_proof (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (Tcp) - :use_delayed_sync (false) - ) - : (RexxRave - :AdminInfo ( - :chkpf_uid ("{637B7F26-C4B2-4510-872E-5A10DE046CB4}") - :ClassName (udp_service) - :table (services) - :Wiznum (-1) - :LastModified ( - :Time ("Tue Jan 07 18:51:04 2003") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :color (magenta) - :comments ("RexxRave trojan") - :delete_on_reply (false) - :etm_enabled (false) - :include_in_any (true) - :port (1104) - :proto_type () - :reload_proof (false) - :replies (true) - :replies_from_any_port (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (Udp) - ) - : (ICKiller - :AdminInfo ( - :chkpf_uid ("{06233377-3454-489A-B9FB-2F2CA14B895B}") - :ClassName (tcp_service) - :table (services) - :Wiznum (-1) - :LastModified ( - :Time ("Tue Jan 07 18:52:06 2003") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :color (magenta) - :comments (ICKiller) - :delayed_sync_value (0) - :enable_tcp_resource (false) - :etm_enabled (false) - :include_in_any (true) - :port (1027) - :proto_type () - :reload_proof (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (Tcp) - :use_delayed_sync (false) - ) - : (HackaTack_31785 - :AdminInfo ( - :chkpf_uid ("{82BA0DD2-42E6-472D-8877-57F519175C14}") - :ClassName (tcp_service) - :table (services) - :Wiznum (-1) - :LastModified ( - :Time ("Tue Jan 07 18:59:17 2003") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :color ("deep pink") - :comments (HackaTack) - :delayed_sync_value (0) - :enable_tcp_resource (false) - :etm_enabled (false) - :include_in_any (true) - :port (31785) - :proto_type () - :reload_proof (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (Tcp) - :use_delayed_sync (false) - ) - : (HackaTack_31787 - :AdminInfo ( - :chkpf_uid ("{C693C8C1-78E3-450D-936E-AA3278190633}") - :ClassName (tcp_service) - :table (services) - :Wiznum (-1) - :LastModified ( - :Time ("Tue Jan 07 19:00:30 2003") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :color (magenta) - :comments ("HackaTack trojan") - :delayed_sync_value (0) - :enable_tcp_resource (false) - :etm_enabled (false) - :include_in_any (true) - :port (31787) - :proto_type () - :reload_proof (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (Tcp) - :use_delayed_sync (false) - ) - : (HackaTack_31788 - :AdminInfo ( - :chkpf_uid ("{B8D159DC-AA70-4CC5-9C5A-8C2AD3AA977E}") - :ClassName (tcp_service) - :table (services) - :Wiznum (-1) - :LastModified ( - :Time ("Tue Jan 07 19:02:02 2003") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :color ("deep pink") - :comments ("HackaTack trojan") - :delayed_sync_value (0) - :enable_tcp_resource (false) - :etm_enabled (false) - :include_in_any (true) - :port (31788) - :proto_type () - :reload_proof (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (Tcp) - :use_delayed_sync (false) - ) - : (HackaTack_31789 - :AdminInfo ( - :chkpf_uid ("{FF8EA038-34FD-4B7B-8A8A-8D6BF0A599FE}") - :ClassName (udp_service) - :table (services) - :Wiznum (-1) - :LastModified ( - :Time ("Tue Jan 07 19:03:49 2003") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :color (magenta) - :comments ("HackaTack trojan") - :delete_on_reply (false) - :etm_enabled (false) - :include_in_any (true) - :port (31789) - :proto_type () - :reload_proof (false) - :replies (true) - :replies_from_any_port (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (Udp) - ) - : (HackaTack_31792 - :AdminInfo ( - :chkpf_uid ("{26339B33-1C42-4E49-96E9-55770F6AF0CE}") - :ClassName (tcp_service) - :table (services) - :Wiznum (-1) - :LastModified ( - :Time ("Tue Jan 07 19:06:41 2003") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :color ("deep pink") - :comments ("HackaTack trojan") - :delayed_sync_value (0) - :enable_tcp_resource (false) - :etm_enabled (false) - :include_in_any (true) - :port (31792) - :proto_type () - :reload_proof (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (Tcp) - :use_delayed_sync (false) - ) - : (UltorsTrojan - :AdminInfo ( - :chkpf_uid ("{6E745536-B8C9-4DF5-BFD5-043E62013956}") - :ClassName (tcp_service) - :table (services) - :Wiznum (-1) - :LastModified ( - :Time ("Tue Jan 07 19:08:55 2003") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :color ("deep pink") - :comments ("Also used by: SubSeven Java client") - :delayed_sync_value (0) - :enable_tcp_resource (false) - :etm_enabled (false) - :include_in_any (true) - :port (1234) - :proto_type () - :reload_proof (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (Tcp) - :use_delayed_sync (false) - ) - : (NoBackO - :AdminInfo ( - :chkpf_uid ("{AA02E546-80D1-453A-91DC-49F606764451}") - :ClassName (udp_service) - :table (services) - :Wiznum (-1) - :LastModified ( - :Time ("Tue Jan 07 19:10:06 2003") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :color (magenta) - :comments ("NoBackO trojan") - :delete_on_reply (false) - :etm_enabled (false) - :include_in_any (true) - :port (1201) - :proto_type () - :reload_proof (false) - :replies (true) - :replies_from_any_port (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (Udp) - ) - : (InCommand - :AdminInfo ( - :chkpf_uid ("{230B24DF-1EFA-4A28-B7A4-87DFB79AFBA7}") - :ClassName (tcp_service) - :table (services) - :Wiznum (-1) - :LastModified ( - :Time ("Tue Jan 07 19:11:57 2003") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :color ("deep pink") - :comments ("Also used by: ICQ Nuke 98 trojan") - :delayed_sync_value (0) - :enable_tcp_resource (false) - :etm_enabled (false) - :include_in_any (true) - :port (1029) - :proto_type () - :reload_proof (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (Tcp) - :use_delayed_sync (false) - ) - : (Xanadu - :AdminInfo ( - :chkpf_uid ("{24DE2CDE-DFCD-4C9B-9124-492AC4BEDBA7}") - :ClassName (tcp_service) - :table (services) - :Wiznum (-1) - :LastModified ( - :Time ("Tue Jan 07 19:12:59 2003") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :color ("deep pink") - :comments ("Xanadu trojan") - :delayed_sync_value (0) - :enable_tcp_resource (false) - :etm_enabled (false) - :include_in_any (true) - :port (1031) - :proto_type () - :reload_proof (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (Tcp) - :use_delayed_sync (false) - ) - : (SubSeven - :AdminInfo ( - :chkpf_uid ("{E926E948-FAE7-4140-8FED-11426B1A32B9}") - :ClassName (tcp_service) - :table (services) - :Wiznum (-1) - :LastModified ( - :Time ("Tue Jan 07 19:16:01 2003") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :color (magenta) - :comments ("Also used by:Bad Blood,EGO,Lion,Ramen,Seeker,The Saint,Tftloader,Webhead trojans") - :delayed_sync_value (0) - :enable_tcp_resource (false) - :etm_enabled (false) - :include_in_any (true) - :port (27374) - :proto_type () - :reload_proof (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (Tcp) - :use_delayed_sync (false) - ) - : (HackaTack_31790 - :AdminInfo ( - :chkpf_uid ("{2176F91C-5FB4-4111-98BD-7D5D5B358FE0}") - :ClassName (tcp_service) - :table (services) - :Wiznum (-1) - :LastModified ( - :Time ("Tue Jan 07 19:16:21 2003") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :color ("deep pink") - :comments ("HackaTack trojan") - :delayed_sync_value (0) - :enable_tcp_resource (false) - :etm_enabled (false) - :include_in_any (true) - :port (31790) - :proto_type () - :reload_proof (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (Tcp) - :use_delayed_sync (false) - ) - : (Terrortrojan - :AdminInfo ( - :chkpf_uid ("{CC1D78CC-5FCE-4496-A78B-C37AA0622F7A}") - :ClassName (tcp_service) - :table (services) - :Wiznum (-1) - :LastModified ( - :Time ("Tue Jan 07 19:18:18 2003") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :color (magenta) - :comments ("Terror trojan") - :delayed_sync_value (0) - :enable_tcp_resource (false) - :etm_enabled (false) - :include_in_any (true) - :port (3456) - :proto_type () - :reload_proof (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (Tcp) - :use_delayed_sync (false) - ) - : (CrackDown - :AdminInfo ( - :chkpf_uid ("{88AAA643-BF12-4D40-A02D-E98A8159358A}") - :ClassName (tcp_service) - :table (services) - :Wiznum (-1) - :LastModified ( - :Time ("Tue Jan 07 19:19:38 2003") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :color ("deep pink") - :comments ("CrackDown trojan") - :delayed_sync_value (0) - :enable_tcp_resource (false) - :etm_enabled (false) - :include_in_any (false) - :port (4444) - :proto_type () - :reload_proof (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (Tcp) - :use_delayed_sync (false) - ) - : (lpdw0rm - :AdminInfo ( - :chkpf_uid ("{73BFBF75-EB13-42C0-BA69-58B8F026B4D6}") - :ClassName (tcp_service) - :table (services) - :Wiznum (-1) - :LastModified ( - :Time ("Tue Jan 07 19:22:38 2003") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :color ("deep pink") - :comments ("Also used by: Ramen trojan and printer service.") - :delayed_sync_value (0) - :enable_tcp_resource (false) - :etm_enabled (false) - :include_in_any (true) - :port (515) - :proto_type () - :reload_proof (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (Tcp) - :use_delayed_sync (false) - ) - : (TheFlu - :AdminInfo ( - :chkpf_uid ("{02F708DD-0337-485F-A04B-3B931971B93A}") - :ClassName (tcp_service) - :table (services) - :Wiznum (-1) - :LastModified ( - :Time ("Tue Jan 07 19:23:32 2003") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :color (magenta) - :comments ("TheFlu trojan") - :delayed_sync_value (0) - :enable_tcp_resource (false) - :etm_enabled (false) - :include_in_any (true) - :port (5534) - :proto_type () - :reload_proof (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (Tcp) - :use_delayed_sync (false) - ) - : (Shadyshell - :AdminInfo ( - :chkpf_uid ("{41C4DF08-DBF9-4576-9114-B8F1DC4DC8D7}") - :ClassName (tcp_service) - :table (services) - :Wiznum (-1) - :LastModified ( - :Time ("Tue Jan 07 19:26:02 2003") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :color (magenta) - :comments ("Shadyshell trojan") - :delayed_sync_value (0) - :enable_tcp_resource (false) - :etm_enabled (false) - :include_in_any (true) - :port (1337) - :proto_type () - :reload_proof (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (Tcp) - :use_delayed_sync (false) - ) - : (TransScout - :AdminInfo ( - :chkpf_uid ("{16AEE006-0F79-407E-B6A4-F3CC5A7A31D5}") - :ClassName (tcp_service) - :table (services) - :Wiznum (-1) - :LastModified ( - :Time ("Tue Jan 07 19:27:16 2003") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :color ("deep pink") - :comments ("TransScout trojan") - :delayed_sync_value (0) - :enable_tcp_resource (false) - :etm_enabled (false) - :include_in_any (true) - :port (2004-2005) - :proto_type () - :reload_proof (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (Tcp) - :use_delayed_sync (false) - ) - : (Trinoo - :AdminInfo ( - :chkpf_uid ("{3CF4DA8B-576E-47EC-903E-91F155BD0CD9}") - :ClassName (tcp_service) - :table (services) - :Wiznum (-1) - :LastModified ( - :Time ("Tue Jan 07 19:28:12 2003") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :color (magenta) - :comments ("Trinoo trojan") - :delayed_sync_value (0) - :enable_tcp_resource (false) - :etm_enabled (false) - :include_in_any (true) - :port (1524) - :proto_type () - :reload_proof (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (Tcp) - :use_delayed_sync (false) - ) - : (SocketsdesTroie - :AdminInfo ( - :chkpf_uid ("{69CA7583-1FD4-4C86-AC1A-680697A9AF93}") - :ClassName (tcp_service) - :table (services) - :Wiznum (-1) - :LastModified ( - :Time ("Tue Jan 07 19:29:16 2003") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :color ("deep pink") - :comments ("Also used by the: tcpmux service") - :delayed_sync_value (0) - :enable_tcp_resource (false) - :etm_enabled (false) - :include_in_any (true) - :port (1) - :proto_type () - :reload_proof (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (Tcp) - :use_delayed_sync (false) - ) - : (Remote_Storm - :AdminInfo ( - :chkpf_uid ("{D4B1F3B0-C606-4B6B-8118-EE61303F8E19}") - :ClassName (tcp_service) - :table (services) - :Wiznum (-1) - :LastModified ( - :Time ("Tue Jan 07 19:31:06 2003") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :color ("deep pink") - :comments ("Also used by: Fraggle Rock,NetSpy,md5 Backdoor trojans") - :delayed_sync_value (0) - :enable_tcp_resource (false) - :etm_enabled (false) - :include_in_any (true) - :port (1025) - :proto_type () - :reload_proof (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (Tcp) - :use_delayed_sync (false) - ) - : (BackDoor-G - :AdminInfo ( - :chkpf_uid ("{A651F18C-1C7C-4BD2-9FFE-790C29E3CCD9}") - :ClassName (tcp_service) - :table (services) - :Wiznum (-1) - :LastModified ( - :Time ("Tue Jan 07 19:32:22 2003") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :color (magenta) - :comments ("Also used by:SubSeven,Tiles trojans") - :delayed_sync_value (0) - :enable_tcp_resource (false) - :etm_enabled (false) - :include_in_any (true) - :port (1243) - :proto_type () - :reload_proof (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (Tcp) - :use_delayed_sync (false) - ) - : (Back_Door_Setup - :AdminInfo ( - :chkpf_uid ("{86077A7D-A8DA-4B5B-919C-366FE91AD1DA}") - :ClassName (tcp_service) - :table (services) - :Wiznum (-1) - :LastModified ( - :Time ("Tue Jan 07 19:34:29 2003") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :color (magenta) - :comments ("Also used by:BioNet Lite,Blazer5,Bubbel trojans") - :delayed_sync_value (0) - :enable_tcp_resource (false) - :etm_enabled (false) - :include_in_any (false) - :port (5000) - :proto_type () - :reload_proof (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (Tcp) - :use_delayed_sync (false) - ) - : (DaCryptic - :AdminInfo ( - :chkpf_uid ("{C13E3031-02D6-4341-A307-3DAF10735078}") - :ClassName (tcp_service) - :table (services) - :Wiznum (-1) - :LastModified ( - :Time ("Tue Jan 07 19:38:01 2003") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :color (magenta) - :comments ("DaCryptic trojan") - :delayed_sync_value (0) - :enable_tcp_resource (false) - :etm_enabled (false) - :include_in_any (true) - :port (1074) - :proto_type () - :reload_proof (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (Tcp) - :use_delayed_sync (false) - ) - : (HackaTack_31791 - :AdminInfo ( - :chkpf_uid ("{05647A8C-F0E7-4354-ADBD-C685EE7742F0}") - :ClassName (udp_service) - :table (services) - :Wiznum (-1) - :LastModified ( - :Time ("Tue Jan 07 19:39:11 2003") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :color ("deep pink") - :comments ("HackaTack trojan") - :delete_on_reply (false) - :etm_enabled (false) - :include_in_any (true) - :port (31791) - :proto_type () - :reload_proof (false) - :replies (true) - :replies_from_any_port (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (Udp) - ) - : (Mneah - :AdminInfo ( - :chkpf_uid ("{E43B7817-DBB6-4C74-A95A-C424DC47999C}") - :ClassName (tcp_service) - :table (services) - :Wiznum (-1) - :LastModified ( - :Time ("Tue Jan 07 19:39:48 2003") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :color (magenta) - :comments ("Mneah trojan") - :delayed_sync_value (0) - :enable_tcp_resource (false) - :etm_enabled (false) - :include_in_any (true) - :port (4666) - :proto_type () - :reload_proof (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (Tcp) - :use_delayed_sync (false) - ) - : (Port_6667_trojans - :AdminInfo ( - :chkpf_uid ("{AEAA6C77-E87E-4581-AD73-06417391DFAD}") - :ClassName (tcp_service) - :table (services) - :Wiznum (-1) - :LastModified ( - :Time ("Tue Jan 07 19:42:26 2003") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :color (magenta) - :comments ("Used by: Dark FTP,EGO,Maniac rootkit,Moses,ScheduleAgent,SubSeven,Trinity,The thing,Kaitex,WinSatan trojans.") - :delayed_sync_value (0) - :enable_tcp_resource (false) - :etm_enabled (false) - :include_in_any (false) - :port (6667) - :proto_type () - :reload_proof (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (Tcp) - :use_delayed_sync (false) - ) - : (DerSphere_II - :AdminInfo ( - :chkpf_uid ("{8D971C42-17DE-49A0-A646-A8E0057AEBBD}") - :ClassName (tcp_service) - :table (services) - :Wiznum (-1) - :LastModified ( - :Time ("Tue Jan 07 19:42:53 2003") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :color ("deep pink") - :comments ("Also used by:Insane Network,Last 2000,Remote Explorer 2000,Senna Spy Trojan Generator trojans") - :delayed_sync_value (0) - :enable_tcp_resource (false) - :etm_enabled (false) - :include_in_any (false) - :port (2000) - :proto_type () - :reload_proof (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (Tcp) - :use_delayed_sync (false) - ) - : (Backage - :AdminInfo ( - :chkpf_uid ("{96759A8D-AAB8-43D9-BBFC-B459CE66AC87}") - :ClassName (tcp_service) - :table (services) - :Wiznum (-1) - :LastModified ( - :Time ("Tue Jan 07 19:43:17 2003") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :color ("deep pink") - :comments ("Backage trojan") - :delayed_sync_value (0) - :enable_tcp_resource (false) - :etm_enabled (false) - :include_in_any (false) - :port (411) - :proto_type () - :reload_proof (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (Tcp) - :use_delayed_sync (false) - ) - : (RIPng - :AdminInfo ( - :chkpf_uid ("{B854AB7B-C8C0-448F-9DD5-491212097C3B}") - :ClassName (udp_service) - :table (services) - :Wiznum (-1) - :LastModified ( - :Time ("Thu Jan 09 15:26:43 2003") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :color (blue1) - :comments ("Routing Information Protocol for IPv6") - :delete_on_reply (false) - :etm_enabled (false) - :include_in_any (true) - :port (521) - :proto_type () - :reload_proof (false) - :replies (true) - :replies_from_any_port (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (Udp) - ) - : (MS-SQL-Server_UDP - :AdminInfo ( - :chkpf_uid ("{BFD72CD2-8E5F-4EDE-BDB2-6DFC016AFCCD}") - :ClassName (udp_service) - :table (services) - :Wiznum (-1) - :LastModified ( - :Time ("Thu Feb 20 17:53:57 2003") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :color (gold3) - :comments ("Microsoft SQL Server") - :delete_on_reply (false) - :etm_enabled (false) - :include_in_any (true) - :port (1433) - :proto_type () - :reload_proof (false) - :replies (true) - :replies_from_any_port (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (Udp) - ) - : (MS-SQL-Monitor_UDP - :AdminInfo ( - :chkpf_uid ("{5AD1A14C-647C-41DE-9F84-D1C34F09D63B}") - :ClassName (udp_service) - :table (services) - :Wiznum (-1) - :LastModified ( - :Time ("Thu Feb 20 17:55:14 2003") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :color ("dark khaki") - :comments (Microsoft-SQL-Monitor_UDP) - :delete_on_reply (false) - :etm_enabled (false) - :include_in_any (true) - :port (1434) - :proto_type () - :reload_proof (false) - :replies (true) - :replies_from_any_port (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (Udp) - ) - : (DameWare - :AdminInfo ( - :chkpf_uid ("{F8A15DFE-8C58-407A-BA18-D92AD5B33966}") - :ClassName (tcp_service) - :table (services) - :Wiznum (-1) - :LastModified ( - :Time ("Thu Feb 20 18:00:28 2003") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :color ("dark orchid") - :comments ("DameWare Mini Remote Control Protocol") - :delayed_sync_value (30) - :enable_tcp_resource (false) - :etm_enabled (false) - :include_in_any (true) - :port (6129) - :proto_type () - :reload_proof (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (Tcp) - :use_delayed_sync (false) - ) - : (WinMX - :AdminInfo ( - :chkpf_uid ("{6414F98E-6883-44DB-8EE2-DEBD443C7714}") - :ClassName (udp_service) - :table (services) - :Wiznum (-1) - :LastModified ( - :Time ("Sun Dec 08 12:54:40 2002") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :color (black) - :comments ("Also uses Napster ports") - :delete_on_reply (false) - :etm_enabled (false) - :include_in_any (true) - :port (6257) - :proto_type () - :reload_proof (false) - :replies (true) - :replies_from_any_port (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (Udp) - ) - : (eDonkey_4665 - :AdminInfo ( - :chkpf_uid ("{D3CAA92A-1032-41AE-A1A1-2274F3AB9F45}") - :ClassName (udp_service) - :table (services) - :Wiznum (-1) - :LastModified ( - :Time ("Sun Dec 08 13:21:41 2002") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :color (black) - :comments ("eDonkey protocol. Used also by other clients.") - :delete_on_reply (false) - :etm_enabled (false) - :include_in_any (true) - :port (4665) - :proto_type () - :reload_proof (false) - :replies (true) - :replies_from_any_port (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (Udp) - ) - : (MSSQL_resolver - :AdminInfo ( - :chkpf_uid ("{7E7CE9B0-8631-4EC3-A7EE-6EB084782A66}") - :ClassName (udp_service) - :table (services) - :Wiznum (-1) - :LastModified ( - :Time ("Wed Sep 03 17:18:55 2003") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :color (black) - :comments ("MS SQL Sapphire /SQL Slammer Worm") - :delete_on_reply (false) - :etm_enabled (false) - :include_in_any (false) - :port (1434) - :proto_type (ReferenceObject - :Name (SQL_SLAMMER) - :Table (protocols) - :Uid ("{A9B88863-0786-4961-B1E9-DDC2FA723135}") - ) - :reload_proof (false) - :replies (true) - :replies_from_any_port (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (Udp) - ) - : (gtp_path_mgmt - :AdminInfo ( - :chkpf_uid ("{2801A9E7-2983-4106-BD3D-4D46B686868C}") - :ClassName (other_service) - :table (services) - :Deleteable (false) - :Hidden (false) - :LastModified ( - :Time ("Mon Aug 27 14:54:07 2001") - :By ("Upgrade Process") - :From (keepme) - ) - ) - :color ("Forest Green") - :comments ("GTP Path Management") - :etm_enabled (false) - :exp (gtp_path_match) - :include_in_any (true) - :needruleinfo (false) - :proto_type () - :protocol (17) - :reload_proof (false) - :replies (true) - :sync_on_cluster (true) - :timeout (0) - :type (other) - :weight (100) - ) - : (Kazaa - :AdminInfo ( - :LastModified ( - :Time ("Tue May 7 14:54:07 2002") - :By (CheckPoint) - :From (CheckPoint) - ) - :chkpf_uid ("{BE146201-61B2-11d6-B5E0-0002B316D24E}") - :ClassName (tcp_service) - :table (services) - ) - :color ("Forest Green") - :comments ("FastTrack (Kazaa/Morpheus) P2P Protocol") - :delayed_sync_value (0) - :enable_tcp_resource (false) - :etm_enabled (false) - :include_in_any (true) - :port (1214) - :proto_type () - :reload_proof (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (Tcp) - :use_delayed_sync (false) - ) - : (ftp-bidir - :AdminInfo ( - :LastModified ( - :Time ("Tue May 21 17:54:08 2002") - :By (CheckPoint) - :From (CheckPoint) - ) - :chkpf_uid ("{16A6AAA2-8449-11D6-A9C5-3E5A6FDB3434}") - :ClassName (tcp_service) - :table (services) - ) - :delayed_sync_value (30) - :use_delayed_sync (false) - :color ("Forest Green") - :comments ("File Transfer Protocol with bi-directional data transfer") - :enable_tcp_resource (false) - :etm_enabled (false) - :include_in_any (false) - :port (21) - :proto_type (ReferenceObject - :Name (FTP-BIDIR) - :Table (protocols) - :Uid ("{8026ECE8-E867-4c4c-9E10-08AC73B709B1}") - ) - :reload_proof (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (Tcp) - ) - : (L2TP - :AdminInfo ( - :chkpf_uid ("{7D452F42-CE34-442F-A023-FBC755DDF3D4}") - :ClassName (udp_service) - :table (services) - :LastModified ( - :Time ("Wed May 15 13:45:31 2002") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :delete_on_reply (false) - :color (red) - :comments ("Layer 2 Tunneling Protocol") - :etm_enabled (false) - :include_in_any (true) - :port (1701) - :proto_type () - :reload_proof (false) - :replies (true) - :replies_from_any_port (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (Udp) - ) - : (MSExchangeDirRef - :AdminInfo ( - :LastModified ( - :Time ("Wed Jul 24 14:54:08 2002") - :By (CheckPoint) - :From (CheckPoint) - ) - :chkpf_uid ("{01693eed-3f81-44d3-b498-51696722cc32}") - :ClassName (dcerpc_service) - :table (services) - ) - :color (Blue) - :comments ("Microsoft Exchange 2000 Directory Reference") - :etm_enabled (false) - :proto_type () - :reload_proof (false) - :type (dcerpc) - :uuid (1544f5e0-613c-11d1-93df-00c04fd7bd09) - ) - : (microsoft-ds - :AdminInfo ( - :chkpf_uid ("{CFBCACE4-7C6F-11D6-BF0E-3E5A6FE83232}") - :ClassName (tcp_service) - :table (services) - :LastModified ( - :Time ("Wed Jun 12 11:56:36 2002") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :delayed_sync_value (30) - :use_delayed_sync (false) - :color (magenta) - :comments ("Microsoft CIFS over TCP") - :enable_tcp_resource (false) - :etm_enabled (false) - :include_in_any (true) - :port (445) - :proto_type (ReferenceObject - :Name (CIFS) - :Table (protocols) - :Uid ("{97AEB373-9AEA-11D5-BD16-0090272CCB31}") - ) - :reload_proof (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (Tcp) - ) - : (CP_SecureAgent-udp - :AdminInfo ( - :chkpf_uid ("{D8CB6ABC-1A8B-4FC0-8BE1-3255E51DECD1}") - :ClassName (udp_service) - :table (services) - :LastModified ( - :Time ("Sun Jun 16 15:56:08 2002") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :delete_on_reply (false) - :color (black) - :comments ("SecureAgent Authentication service") - :etm_enabled (false) - :include_in_any (false) - :port (19194-19195) - :proto_type () - :reload_proof (false) - :replies (true) - :replies_from_any_port (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (Udp) - ) - : (FW1_sds_logon_NG - :AdminInfo ( - :LastModified ( - :Time ("Mon Jun 17 17:54:08 2002") - :By (CheckPoint) - :From (CheckPoint) - ) - :chkpf_uid ("{B61424B4-81E4-11D6-BCEC-3E5A6FDDCECE}") - :ClassName (tcp_service) - :table (services) - ) - :delayed_sync_value (30) - :use_delayed_sync (false) - :color (firebrick) - :comments ("SecuRemote Distribution Server Protocol (VC and higher)") - :enable_tcp_resource (false) - :etm_enabled (false) - :include_in_any (true) - :port (65524) - :proto_type () - :reload_proof (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (Tcp) - ) - : (MS-SQL-Server - :AdminInfo ( - :LastModified ( - :Time ("Thu Jul 18 17:54:08 2002") - :By (CheckPoint) - :From (CheckPoint) - ) - :chkpf_uid ("{DFF4F7BA-9A3D-11D6-91C1-3E5A6FDD5151}") - :ClassName (tcp_service) - :table (services) - ) - :delayed_sync_value (30) - :use_delayed_sync (false) - :color (Magenta) - :comments ("Microsoft SQL Server") - :enable_tcp_resource (false) - :etm_enabled (false) - :include_in_any (true) - :port (1433) - :proto_type () - :reload_proof (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (Tcp) - ) - : (MS-SQL-Monitor - :AdminInfo ( - :LastModified ( - :Time ("Thu Jul 18 17:54:08 2002") - :By (CheckPoint) - :From (CheckPoint) - ) - :chkpf_uid ("{EF245528-9A3D-11D6-9EAA-3E5A6FDD6A6A}") - :ClassName (tcp_service) - :table (services) - ) - :delayed_sync_value (30) - :use_delayed_sync (false) - :color (Magenta) - :comments ("Microsoft SQL Monitor") - :enable_tcp_resource (false) - :etm_enabled (false) - :include_in_any (true) - :port (1434) - :proto_type () - :reload_proof (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (Tcp) - ) - : (FW1 - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:07 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB388-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (tcp_service) - :table (services) - :name (FW1) - ) - :delayed_sync_value (30) - :use_delayed_sync (false) - :color (FireBrick) - :comments ("Check Point VPN-1 & FireWall-1 Service") - :enable_tcp_resource (false) - :etm_enabled (false) - :include_in_any (true) - :port (256) - :proto_type () - :reload_proof (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (Tcp) - ) - : (FW1_log - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:07 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB389-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (tcp_service) - :table (services) - :name (FW1_log) - ) - :delayed_sync_value (30) - :use_delayed_sync (false) - :color (FireBrick) - :comments ("Check Point VPN-1 & FireWall-1 Logs") - :enable_tcp_resource (false) - :etm_enabled (false) - :include_in_any (true) - :port (257) - :proto_type () - :reload_proof (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (tcp) - ) - : (FW1_mgmt - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:07 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB38A-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (tcp_service) - :table (services) - :name (FW1_mgmt) - ) - :delayed_sync_value (30) - :use_delayed_sync (false) - :color (FireBrick) - :comments ("Check Point Management (Version 4.x)") - :enable_tcp_resource (false) - :etm_enabled (false) - :include_in_any (true) - :port (258) - :proto_type () - :reload_proof (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (tcp) - ) - : (FW1_clntauth_telnet - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:07 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB38B-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (tcp_service) - :table (services) - :name (FW1_clntauth_telnet) - ) - :delayed_sync_value (30) - :use_delayed_sync (false) - :color (FireBrick) - :comments ("Check Point VPN-1 & FireWall-1 Client Authentication (Telnet)") - :enable_tcp_resource (false) - :etm_enabled (false) - :include_in_any (true) - :port (259) - :proto_type () - :reload_proof (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (tcp) - ) - : (FW1_clntauth_http - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:07 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB38C-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (tcp_service) - :table (services) - :name (FW1_clntauth_http) - ) - :delayed_sync_value (30) - :use_delayed_sync (false) - :color (FireBrick) - :comments ("Check Point VPN-1 & FireWall-1 Client Authentication (HTTP)") - :enable_tcp_resource (false) - :etm_enabled (false) - :include_in_any (true) - :port (900) - :proto_type () - :reload_proof (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (tcp) - ) - : (FW1_snauth - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:07 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB38E-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (tcp_service) - :table (services) - :name (FW1_snauth) - ) - :delayed_sync_value (30) - :use_delayed_sync (false) - :color (FireBrick) - :comments ("Check Point VPN-1 & FireWall-1 Session Authentication") - :enable_tcp_resource (false) - :etm_enabled (false) - :include_in_any (true) - :port (261) - :proto_type () - :reload_proof (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (tcp) - ) - : (FW1_topo - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:07 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB38F-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (tcp_service) - :table (services) - :name (FW1_topo) - ) - :delayed_sync_value (30) - :use_delayed_sync (false) - :color (FireBrick) - :comments ("Check Point VPN-1 SecuRemote Topology Requests") - :enable_tcp_resource (false) - :etm_enabled (false) - :include_in_any (true) - :port (264) - :proto_type () - :reload_proof (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (tcp) - ) - : (VPN1_IPSEC_encapsulation - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:07 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB390-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (udp_service) - :table (services) - :name (VPN1_IPSEC_encapsulation) - ) - :delete_on_reply (false) - :color (FireBrick) - :comments ("Check Point VPN-1 SecuRemote IPSEC Transport Encapsulation Protocol") - :etm_enabled (false) - :include_in_any (true) - :port (2746) - :proto_type () - :reload_proof (false) - :replies (true) - :replies_from_any_port (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (udp) - ) - : (FW1_key - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:07 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB391-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (tcp_service) - :table (services) - :name (FW1_key) - ) - :delayed_sync_value (30) - :use_delayed_sync (false) - :color (FireBrick) - :comments ("Check Point VPN-1 Public Key Transfer Protocol") - :enable_tcp_resource (false) - :etm_enabled (false) - :include_in_any (true) - :port (265) - :proto_type () - :reload_proof (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (tcp) - ) - : (FW1_cvp - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:07 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB392-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (tcp_service) - :table (services) - :Deleteable (false) - :Renameable (false) - :name (FW1_cvp) - ) - :delayed_sync_value (30) - :use_delayed_sync (false) - :color (FireBrick) - :comments ("Check Point OPSEC Content Vectoring Protocol") - :enable_tcp_resource (false) - :etm_enabled (false) - :include_in_any (true) - :port (18181) - :proto_type (ReferenceObject - :Name (FW1_CVP) - :Table (protocols) - :Uid ("{97AEB381-9AEA-11D5-BD16-0090272CCB30}") - ) - :reload_proof (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (tcp) - ) - : (FW1_ufp - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:07 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB393-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (tcp_service) - :table (services) - :Deleteable (false) - :Renameable (false) - :name (FW1_ufp) - ) - :delayed_sync_value (30) - :use_delayed_sync (false) - :color (FireBrick) - :comments ("Check Point OPSEC URL Filtering Protocol") - :enable_tcp_resource (false) - :etm_enabled (false) - :include_in_any (true) - :port (18182) - :proto_type () - :reload_proof (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (tcp) - ) - : (FW1_amon - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:07 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB394-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (tcp_service) - :table (services) - :Deleteable (false) - :Renameable (false) - :name (FW1_amon) - ) - :delayed_sync_value (30) - :use_delayed_sync (false) - :color (FireBrick) - :comments ("Check Point OPSEC Application Monitoring") - :enable_tcp_resource (false) - :etm_enabled (false) - :include_in_any (true) - :port (18193) - :proto_type () - :reload_proof (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (tcp) - ) - : (FW1_omi - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:07 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB395-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (tcp_service) - :table (services) - :name (FW1_omi) - ) - :delayed_sync_value (30) - :use_delayed_sync (false) - :color (FireBrick) - :comments ("Check Point OPSEC Objects Management Interface") - :enable_tcp_resource (false) - :etm_enabled (false) - :include_in_any (true) - :port (18185) - :proto_type () - :reload_proof (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (tcp) - ) - : (FW1_omi-sic - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:07 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB396-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (tcp_service) - :table (services) - :name (FW1_omi-sic) - ) - :delayed_sync_value (30) - :use_delayed_sync (false) - :color (FireBrick) - :comments ("Check Point OPSEC Objects Management Interface with Secure Internal Communication") - :enable_tcp_resource (false) - :etm_enabled (false) - :include_in_any (true) - :port (18186) - :proto_type () - :reload_proof (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (tcp) - ) - : (CP_reporting - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:07 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB397-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (tcp_service) - :table (services) - :name (CP_reporting) - ) - :delayed_sync_value (30) - :use_delayed_sync (false) - :color (FireBrick) - :comments ("Check Point Reporting Client Protocol") - :enable_tcp_resource (false) - :etm_enabled (false) - :include_in_any (true) - :port (18205) - :proto_type () - :reload_proof (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (tcp) - ) - : (FW1_CPRID - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:07 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB398-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (tcp_service) - :table (services) - :name (FW1_CPRID) - :Deleteable (false) - :Renameable (false) - ) - :delayed_sync_value (30) - :use_delayed_sync (false) - :color (FireBrick) - :comments ("Check Point Remote Installation Protocol") - :enable_tcp_resource (false) - :etm_enabled (false) - :include_in_any (true) - :port (18208) - :proto_type () - :reload_proof (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (tcp) - ) - : (FW1_netso - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:07 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB399-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (tcp_service) - :table (services) - :name (FW1_netso) - ) - :delayed_sync_value (30) - :use_delayed_sync (false) - :color (firebrick) - :comments ("Check Point User Authority simple protocol") - :enable_tcp_resource (false) - :etm_enabled (false) - :include_in_any (true) - :port (19190) - :proto_type () - :reload_proof (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (Tcp) - ) - : (FW1_uaa - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:07 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB39A-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (tcp_service) - :table (services) - :name (FW1_uaa) - :Deleteable (false) - :Renameable (false) - ) - :delayed_sync_value (30) - :use_delayed_sync (false) - :color (firebrick) - :comments ("Check Point OPSEC User Authority API") - :enable_tcp_resource (false) - :etm_enabled (false) - :include_in_any (true) - :port (19191) - :proto_type () - :reload_proof (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (Tcp) - ) - : (FW1_pslogon - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:07 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB39B-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (tcp_service) - :table (services) - :name (FW1_pslogon) - ) - :delayed_sync_value (30) - :use_delayed_sync (false) - :color (firebrick) - :comments ("Check Point Policy Server Logon protocol") - :enable_tcp_resource (false) - :etm_enabled (false) - :include_in_any (true) - :port (18207) - :proto_type () - :reload_proof (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (Tcp) - ) - : (FW1_pslogon_NG - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:07 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB39C-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (tcp_service) - :table (services) - :name (FW1_pslogon_NG) - ) - :delayed_sync_value (30) - :use_delayed_sync (false) - :color (firebrick) - :comments ("Check Point NG Policy Server Logon protocol") - :enable_tcp_resource (false) - :etm_enabled (false) - :include_in_any (true) - :port (18231) - :proto_type () - :reload_proof (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (Tcp) - ) - : (FW1_sds_logon - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:07 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB39D-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (tcp_service) - :table (services) - :name (FW1_sds_logon) - ) - :delayed_sync_value (30) - :use_delayed_sync (false) - :color (firebrick) - :comments ("Check Point SecuRemote Distribution Server Protocol") - :enable_tcp_resource (false) - :etm_enabled (false) - :include_in_any (true) - :port (18232) - :proto_type () - :reload_proof (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (Tcp) - ) - : (FW1_scv_keep_alive - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:07 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB39E-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (udp_service) - :table (services) - :name (FW1_scv_keep_alive) - ) - :delete_on_reply (false) - :color (FireBrick) - :comments ("Check Point SecureClient Verification Keepalive Protocol") - :etm_enabled (false) - :include_in_any (true) - :port (18233) - :proto_type () - :reload_proof (false) - :replies (true) - :replies_from_any_port (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (udp) - ) - : (RDP - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:07 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB39F-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (udp_service) - :table (services) - :name (RDP) - ) - :delete_on_reply (false) - :color (FireBrick) - :comments ("Check Point VPN-1 FWZ Key Negotiations - Reliable Datagram Protocol") - :etm_enabled (false) - :include_in_any (true) - :port (259) - :proto_type () - :reload_proof (false) - :replies (true) - :replies_from_any_port (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (udp) - ) - : (FW1_lea - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:07 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB3A0-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (tcp_service) - :table (services) - :name (FW1_lea) - ) - :delayed_sync_value (30) - :use_delayed_sync (false) - :color (FireBrick) - :comments ("Check Point OPSEC Log Export API") - :enable_tcp_resource (false) - :etm_enabled (false) - :include_in_any (true) - :port (18184) - :proto_type () - :reload_proof (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (tcp) - ) - : (FW1_ela - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:07 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB3A1-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (tcp_service) - :table (services) - :Deleteable (false) - :Renameable (false) - :name (FW1_ela) - ) - :delayed_sync_value (30) - :use_delayed_sync (false) - :color (FireBrick) - :comments ("Check Point OPSEC Event Logging API") - :enable_tcp_resource (false) - :etm_enabled (false) - :include_in_any (true) - :port (18187) - :proto_type () - :reload_proof (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (tcp) - ) - : (CP_rtm - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:07 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB3A2-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (tcp_service) - :table (services) - :name (CP_rtm) - ) - :delayed_sync_value (30) - :use_delayed_sync (false) - :color (FireBrick) - :comments ("Check Point Real Time Monitoring") - :enable_tcp_resource (false) - :etm_enabled (false) - :include_in_any (true) - :port (18202) - :proto_type () - :reload_proof (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (tcp) - ) - : (FW1_sam - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:07 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB3A3-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (tcp_service) - :table (services) - :name (FW1_sam) - ) - :delayed_sync_value (30) - :use_delayed_sync (false) - :color (FireBrick) - :comments ("Check Point OPSEC Suspicious Activity Monitor API") - :enable_tcp_resource (false) - :etm_enabled (false) - :include_in_any (true) - :port (18183) - :proto_type () - :reload_proof (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (tcp) - ) - : (FW1_ica_pull - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:07 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB3A4-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (tcp_service) - :table (services) - :name (FW1_ica_pull) - ) - :delayed_sync_value (30) - :use_delayed_sync (false) - :color (FireBrick) - :comments ("Check Point Internal CA Pull Certificate Service") - :enable_tcp_resource (false) - :etm_enabled (false) - :include_in_any (true) - :port (18210) - :proto_type () - :reload_proof (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (tcp) - ) - : (FW1_ica_push - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:07 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB3A5-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (tcp_service) - :table (services) - :name (FW1_ica_push) - ) - :delayed_sync_value (30) - :use_delayed_sync (false) - :color (FireBrick) - :comments ("Check Point Internal CA Push Certificate Service") - :enable_tcp_resource (false) - :etm_enabled (false) - :include_in_any (true) - :port (18211) - :proto_type () - :reload_proof (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (tcp) - ) - : (FW1_ica_services - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:07 2001") - :By (CheckPoint) - :From (CheckPoint) - ) - :chkpf_uid ("{97AEB44E-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (tcp_service) - :table (services) - :name (FW1_ica_services) - ) - :delayed_sync_value (30) - :use_delayed_sync (false) - :color (FireBrick) - :comments ("Check Point Internal CA Fetch CRL and User Registration Services") - :enable_tcp_resource (false) - :etm_enabled (false) - :include_in_any (true) - :port (18264) - :proto_type () - :reload_proof (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (tcp) - ) - : (FW1_load_agent - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:07 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB3A6-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (udp_service) - :table (services) - :name (FW1_load_agent) - ) - :delete_on_reply (false) - :color (FireBrick) - :comments ("Check Point ConnectControl Load Agent") - :etm_enabled (false) - :include_in_any (true) - :port (18212) - :proto_type () - :reload_proof (false) - :replies (true) - :replies_from_any_port (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (udp) - ) - : (E2ECP - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:07 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB3A7-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (udp_service) - :table (services) - :name (E2ECP) - ) - :delete_on_reply (false) - :color (FireBrick) - :comments ("Check Point End to End Control Protocol") - :etm_enabled (false) - :include_in_any (true) - :port (18241) - :proto_type () - :reload_proof (false) - :replies (true) - :replies_from_any_port (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (udp) - ) - : (tunnel_test - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:07 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB3A8-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (udp_service) - :table (services) - :name (tunnel_test) - ) - :delete_on_reply (false) - :color (FireBrick) - :comments ("Check Point tunnel teIsoAAAD application") - :etm_enabled (false) - :include_in_any (true) - :port (18234) - :proto_type () - :reload_proof (false) - :replies (true) - :replies_from_any_port (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (udp) - ) - : (CP_redundant - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:07 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB3A9-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (tcp_service) - :table (services) - :name (CP_redundant) - ) - :delayed_sync_value (30) - :use_delayed_sync (false) - :color (FireBrick) - :comments ("Check Point Redundant Management Protocol") - :enable_tcp_resource (false) - :etm_enabled (false) - :include_in_any (true) - :port (18221) - :proto_type () - :reload_proof (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (tcp) - ) - : (CPMI - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:07 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB3AA-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (tcp_service) - :table (services) - :name (CPMI) - ) - :delayed_sync_value (30) - :use_delayed_sync (false) - :color (FireBrick) - :comments ("Check Point Management Interface") - :enable_tcp_resource (false) - :etm_enabled (false) - :include_in_any (true) - :port (18190) - :proto_type () - :reload_proof (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (tcp) - ) - : (CPD - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:07 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB3AB-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (tcp_service) - :table (services) - :name (CPD) - ) - :delayed_sync_value (30) - :use_delayed_sync (false) - :color (FireBrick) - :comments ("Check Point Daemon Protocol") - :enable_tcp_resource (false) - :etm_enabled (false) - :include_in_any (true) - :port (18191) - :proto_type () - :reload_proof (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (tcp) - ) - : (CPD_amon - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:07 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB3AC-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (tcp_service) - :table (services) - :Deleteable (false) - :Renameable (false) - :name (CPD_amon) - ) - :delayed_sync_value (30) - :use_delayed_sync (false) - :color (FireBrick) - :comments ("Check Point Internal Application Monitoring") - :enable_tcp_resource (false) - :etm_enabled (false) - :include_in_any (true) - :port (18192) - :proto_type () - :reload_proof (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (tcp) - ) - : (CP_Exnet_PK - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:07 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB3AD-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (tcp_service) - :table (services) - :name (CP_Exnet_PK) - ) - :delayed_sync_value (30) - :use_delayed_sync (false) - :color (FireBrick) - :comments ("Check Point Extrnet public key advertisement") - :enable_tcp_resource (false) - :etm_enabled (false) - :include_in_any (true) - :port (18262) - :proto_type () - :reload_proof (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (tcp) - ) - : (CP_Exnet_resolve - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:07 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB3AE-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (tcp_service) - :table (services) - :name (CP_Exnet_resolve) - ) - :delayed_sync_value (30) - :use_delayed_sync (false) - :color (FireBrick) - :comments ("Check Point Extranet remote objects resolution") - :enable_tcp_resource (false) - :etm_enabled (false) - :include_in_any (true) - :port (18263) - :proto_type () - :reload_proof (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (tcp) - ) - : (IKE_tcp - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:07 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB3AF-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (tcp_service) - :table (services) - :name (IKE_tcp) - ) - :delayed_sync_value (30) - :use_delayed_sync (false) - :color (Cyan) - :comments ("IPSEC Internet Key Exchange Protocol over TCP") - :enable_tcp_resource (false) - :etm_enabled (false) - :include_in_any (true) - :port (500) - :proto_type () - :reload_proof (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (tcp) - ) - : (IKE - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:07 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB3B0-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (udp_service) - :table (services) - :name (IKE) - ) - :delete_on_reply (false) - :color (Cyan) - :comments ("IPSEC Internet Key Exchange Protocol (formerly ISAKMP/Oakley)") - :etm_enabled (false) - :include_in_any (true) - :port (500) - :proto_type () - :reload_proof (false) - :replies (true) - :replies_from_any_port (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (udp) - ) - : (FW1_snmp - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:07 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB3B1-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (udp_service) - :table (services) - :name (FW1_snmp) - ) - :delete_on_reply (false) - :color (FireBrick) - :comments ("Check Point VPN-1 & FireWall-1 SNMP Agent") - :etm_enabled (false) - :include_in_any (true) - :port (260) - :proto_type () - :reload_proof (false) - :replies (true) - :replies_from_any_port (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (udp) - ) - : (snmp - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:07 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB3B2-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (udp_service) - :table (services) - :name (snmp) - ) - :delete_on_reply (false) - :color (FireBrick) - :comments ("Simple Network Management Protocol") - :etm_enabled (false) - :include_in_any (true) - :port (161) - :proto_type () - :reload_proof (false) - :replies (true) - :replies_from_any_port (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (udp) - ) - : (snmp-trap - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:07 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB3B3-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (udp_service) - :table (services) - :name (snmp-trap) - ) - :delete_on_reply (false) - :color (FireBrick) - :comments ("Simple Network Management Protocol Traps") - :etm_enabled (false) - :include_in_any (true) - :port (162) - :proto_type () - :reload_proof (false) - :replies (false) - :replies_from_any_port (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (udp) - ) - : (snmp-read - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:07 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB3B4-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (udp_service) - :table (services) - :name (snmp-read) - ) - :delete_on_reply (false) - :color (FireBrick) - :comments ("Simple Network Management Protocol - Read Only") - :etm_enabled (false) - :include_in_any (false) - :port (161) - :proto_type (ReferenceObject - :Name (Snmp-Read) - :Table (protocols) - :Uid ("{97AEB383-9AEA-11D5-BD16-0090272CCB30}") - ) - :reload_proof (false) - :replies (true) - :replies_from_any_port (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (udp) - ) - : (X11 - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:07 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB3B5-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (tcp_service) - :table (services) - :name (X11) - ) - :delayed_sync_value (30) - :use_delayed_sync (false) - :color (Red) - :comments ("X Window System") - :enable_tcp_resource (false) - :etm_enabled (false) - :include_in_any (true) - :port (6000-6063) - :proto_type () - :reload_proof (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (Tcp) - ) - : (OpenWindows - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:07 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB3B6-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (tcp_service) - :table (services) - :name (OpenWindows) - ) - :delayed_sync_value (30) - :use_delayed_sync (false) - :color (Red) - :comments () - :enable_tcp_resource (false) - :etm_enabled (false) - :include_in_any (true) - :port (2000) - :proto_type () - :reload_proof (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (Tcp) - ) - : (nfsprog - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:07 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB3B7-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (rpc_service) - :table (services) - :name (nfsprog) - ) - :color (Red) - :comments ("RPCs Network File System (Ordinary)") - :etm_enabled (false) - :port (100003) - :proto_type () - :reload_proof (false) - :type (Rpc) - ) - : (nfsd - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:07 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB3B8-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (udp_service) - :table (services) - :name (nfsd) - ) - :delete_on_reply (false) - :color (Red) - :comments ("Network File System Daemon over UDP (earlier versions of NFS)") - :etm_enabled (false) - :include_in_any (true) - :port (2049) - :proto_type () - :reload_proof (false) - :replies (true) - :replies_from_any_port (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (Udp) - ) - : (nfsd-tcp - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:07 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB3B9-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (tcp_service) - :table (services) - :name (nfsd-tcp) - ) - :delayed_sync_value (30) - :use_delayed_sync (false) - :color (Red) - :comments ("Network File System Daemon over TCP") - :enable_tcp_resource (false) - :etm_enabled (false) - :include_in_any (true) - :port (2049) - :proto_type () - :reload_proof (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (Tcp) - ) - : (mountd - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:07 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB3BA-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (rpc_service) - :table (services) - :name (mountd) - ) - :color (Red) - :comments ("Initiate client access to NFS application") - :etm_enabled (false) - :port (100005) - :proto_type () - :reload_proof (false) - :type (Rpc) - ) - : (pcnfsd - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:07 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB3BB-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (rpc_service) - :table (services) - :name (pcnfsd) - ) - :color (Red) - :comments ("PCs (windows client) password authorization") - :etm_enabled (false) - :port (150001) - :proto_type () - :reload_proof (false) - :type (Rpc) - ) - : (nlockmgr - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:07 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB3BC-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (rpc_service) - :table (services) - :name (nlockmgr) - ) - :color (Red) - :comments ("RPC, Network Lock Manager") - :etm_enabled (false) - :port (100021) - :proto_type () - :reload_proof (false) - :type (Rpc) - ) - : (tftp - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:07 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB3BD-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (udp_service) - :table (services) - :name (tftp) - ) - :delete_on_reply (false) - :color (Red) - :comments ("Trivial File Transfer Protocol") - :etm_enabled (false) - :include_in_any (true) - :port (69) - :proto_type () - :reload_proof (false) - :replies (true) - :replies_from_any_port (true) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (Udp) - ) - : (sip_any - :AdminInfo ( - :LastModified ( - :Time ("Tue Nov 6 14:16:27 2001") - :By (CheckPoint) - :From (CheckPoint) - ) - :chkpf_uid ("{BD8B98D4-D2C0-11D5-A329-00D0B7D41431}") - :ClassName (udp_service) - :table (services) - :name (sip_any) - ) - :delete_on_reply (false) - :color (black) - :comments ("Session Initiation Protocol") - :etm_enabled (false) - :include_in_any (false) - :port (5060) - :proto_type (ReferenceObject - :Name (SIP_UDP_ANY) - :Table (protocols) - :Uid ("{97AEB378-9AEA-11D5-BD16-0090272CCB38}") - ) - :reload_proof (false) - :replies (true) - :replies_from_any_port (true) - :src_port () - :sync_on_cluster (true) - :timeout (40) - :type (Udp) - ) - : (sip - :AdminInfo ( - :LastModified ( - :Time ("Tue Nov 6 14:16:27 2001") - :By (CheckPoint) - :From (CheckPoint) - ) - :chkpf_uid ("{BD8B98D4-D2C0-11D5-A329-00D0B7D4143F}") - :ClassName (udp_service) - :table (services) - :name (sip) - ) - :delete_on_reply (false) - :color (black) - :comments ("Session Initiation Protocol") - :etm_enabled (false) - :include_in_any (false) - :port (5060) - :proto_type (ReferenceObject - :Name (SIP_UDP) - :Table (protocols) - :Uid ("{97AEB378-9AEA-11D5-BD16-0090272CCB37}") - ) - :reload_proof (false) - :replies (true) - :replies_from_any_port (true) - :src_port () - :sync_on_cluster (true) - :timeout (40) - :type (Udp) - ) - : (login - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:07 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB3BE-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (tcp_service) - :table (services) - :name (login) - ) - :delayed_sync_value (30) - :use_delayed_sync (false) - :color (Red) - :comments ("Remote login (rlogin)") - :enable_tcp_resource (false) - :etm_enabled (false) - :include_in_any (true) - :port (513) - :proto_type () - :reload_proof (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (Tcp) - ) - : (exec - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:07 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB3BF-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (tcp_service) - :table (services) - :name (exec) - ) - :delayed_sync_value (30) - :use_delayed_sync (false) - :color (Red) - :comments ("Remote execution (rexec)") - :enable_tcp_resource (false) - :etm_enabled (false) - :include_in_any (true) - :port (512) - :proto_type (ReferenceObject - :Name (RSHELL) - :Table (protocols) - :Uid ("{97AEB375-9AEA-11D5-BD16-0090272CCB30}") - ) - :reload_proof (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (Tcp) - ) - : (shell - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:07 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB3C0-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (tcp_service) - :table (services) - :name (shell) - ) - :delayed_sync_value (30) - :use_delayed_sync (false) - :color (Red) - :comments ("Remote shell (rsh)") - :enable_tcp_resource (false) - :etm_enabled (false) - :include_in_any (true) - :port (514) - :proto_type (ReferenceObject - :Name (RSHELL) - :Table (protocols) - :Uid ("{97AEB375-9AEA-11D5-BD16-0090272CCB30}") - ) - :reload_proof (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (Tcp) - ) - : (ssh - :AdminInfo ( - :LastModified ( - :Time ("Thu Dec 20 09:48:23 2001") - :By (CheckPoint) - :From (CheckPoint) - ) - :chkpf_uid ("{18EC9EAA-1657-4240-AB97-5F234623336B}") - :ClassName (tcp_service) - :table (services) - :name (ssh) - ) - :delayed_sync_value (30) - :use_delayed_sync (false) - :color (Red) - :comments ("secure shell, encrypted and authenticated rsh") - :enable_tcp_resource (false) - :etm_enabled (false) - :include_in_any (true) - :port (22) - :proto_type () - :reload_proof (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (Tcp) - ) - : (ypserv - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:07 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB3C1-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (rpc_service) - :table (services) - :name (ypserv) - ) - :color ("Navy Blue") - :comments ("Sun Yellow Pages directory service (YP) protocol, now known as NIS") - :etm_enabled (false) - :port (100004) - :proto_type () - :reload_proof (false) - :type (Rpc) - ) - : (ypbind - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:07 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB3C2-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (rpc_service) - :table (services) - :name (ypbind) - ) - :color ("Navy Blue") - :comments ("Sun Yellow Pages binder (NIS), provide servers addressing information") - :etm_enabled (false) - :port (100007) - :proto_type () - :reload_proof (false) - :type (Rpc) - ) - : (yppasswd - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:07 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB3C3-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (rpc_service) - :table (services) - :name (yppasswd) - ) - :color ("Navy Blue") - :comments ("Sun Yellow Pages protocol (NIS), password server") - :etm_enabled (false) - :port (100009) - :proto_type () - :reload_proof (false) - :type (Rpc) - ) - : (ypupdated - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:07 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB3C4-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (rpc_service) - :table (services) - :name (ypupdated) - ) - :color ("Navy Blue") - :comments ("Sun Yellow Pages protocol (NIS), update service") - :etm_enabled (false) - :port (100028) - :proto_type () - :reload_proof (false) - :type (Rpc) - ) - : (ypxfrd - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:07 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB3C5-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (rpc_service) - :table (services) - :name (ypxfrd) - ) - :color ("Navy Blue") - :comments ("Sun Yellow Pages protocol (NIS), transfers NIS maps") - :etm_enabled (false) - :port (100069) - :proto_type () - :reload_proof (false) - :type (Rpc) - ) - : (nisplus - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:07 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB3C6-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (rpc_service) - :table (services) - :name (nisplus) - ) - :color ("Navy Blue") - :comments ("NIS+ later version provides additional security and other facilities") - :etm_enabled (false) - :port (100300) - :proto_type () - :reload_proof (false) - :type (Rpc) - ) - : (ospf - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:07 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB3C7-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (other_service) - :table (services) - :name (ospf) - ) - :color ("Medium Slate Blue") - :comments ("Open Shortest Path First Interior GW Protocol") - :etm_enabled (false) - :exp () - :include_in_any (true) - :needruleinfo (false) - :proto_type () - :protocol (89) - :reload_proof (false) - :replies (false) - :sync_on_cluster (true) - :timeout (0) - :type (other) - :weight (0) - ) - : (ggp - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:07 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB3C8-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (other_service) - :table (services) - :name (ggp) - ) - :color ("Medium Slate Blue") - :comments ("Gateway-to-Gateway protocol") - :etm_enabled (false) - :exp () - :include_in_any (true) - :needruleinfo (false) - :proto_type () - :protocol (3) - :reload_proof (false) - :replies (false) - :sync_on_cluster (true) - :timeout (0) - :type (other) - :weight (0) - ) - : (igrp - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:07 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB3C9-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (other_service) - :table (services) - :name (igrp) - ) - :color ("Medium Slate Blue") - :comments ("Cisco Interior Gateway Routing Protocol") - :etm_enabled (false) - :exp () - :include_in_any (true) - :needruleinfo (false) - :proto_type () - :protocol (9) - :reload_proof (false) - :replies (false) - :sync_on_cluster (true) - :timeout (0) - :type (Other) - :weight (0) - ) - : (egp - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:07 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB3CA-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (other_service) - :table (services) - :name (egp) - ) - :color ("Medium Slate Blue") - :comments ("Exterior Gateway Protocol, convey net-reachability information between gateways") - :etm_enabled (false) - :exp () - :include_in_any (true) - :needruleinfo (false) - :proto_type () - :protocol (8) - :reload_proof (false) - :replies (false) - :sync_on_cluster (true) - :timeout (0) - :type (other) - :weight (0) - ) - : (igmp - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:07 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB3CB-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (other_service) - :table (services) - :name (igmp) - ) - :color ("Medium Slate Blue") - :comments ("Internet Group Management Protocol") - :etm_enabled (false) - :exp () - :include_in_any (true) - :needruleinfo (false) - :proto_type () - :protocol (2) - :reload_proof (false) - :replies (false) - :sync_on_cluster (false) - :timeout (0) - :type (other) - :weight (0) - ) - : (vrrp - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:07 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB3CC-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (other_service) - :table (services) - :name (vrrp) - ) - :color ("Medium Slate Blue") - :comments ("Virtual Router Redundancy Protocol") - :etm_enabled (false) - :exp () - :include_in_any (true) - :needruleinfo (false) - :proto_type () - :protocol (112) - :reload_proof (false) - :replies (false) - :sync_on_cluster (false) - :timeout (0) - :type (other) - :weight (0) - ) - : (gtp_default - :AdminInfo ( - :chkpf_uid ("{ACB96D00-A1F9-11D5-A414-00D0B7BE171D}") - :ClassName (gtp_service) - :table (services) - :Deleteable (false) - :LastModified ( - :Time ("Mon Aug 27 14:54:07 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :name (gtp_default) - ) - :apn_obj () - :port (3386) - :apn_any (true) - :color ("Forest Green") - :comments ("GPRS Tunnelling Protocol") - :data_packet (true) - :etm_enabled (false) - :imsi () - :imsi_any (true) - :include_in_any (true) - :ms_isdn (1) - :ms_isdn_any (true) - :proto_type () - :reload_proof (false) - :sel_mode (0) - :sel_mode_any (false) - :signaling_packet (true) - :static_eua (false) - :timeout (600) - :type (gtp) - :weight (100) - ) - : (gtp_reverse - :AdminInfo ( - :chkpf_uid ("{ACB96D01-A1F9-11D5-A414-00D0B7BE171D}") - :ClassName (other_service) - :table (services) - :Deleteable (false) - :Hidden (true) - :LastModified ( - :Time ("Mon Aug 27 14:54:07 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :name (gtp_reverse) - ) - :color ("Forest Green") - :comments ("GTP Reverse Connections") - :etm_enabled (false) - :exp (gtp_rev_match) - :include_in_any (true) - :needruleinfo (false) - :proto_type () - :protocol (17) - :reload_proof (false) - :replies (true) - :sync_on_cluster (true) - :timeout (0) - :type (other) - :weight (0) - ) - : (http_mapped - :AdminInfo ( - :chkpf_uid ("{DA123892-B250-11D5-A47A-0006294583C7}") - :ClassName (other_service) - :table (services) - :LastModified ( - :Time ("Mon Aug 27 14:54:07 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :name (http_mapped) - ) - :color (orange) - :comments ("HTTP Port Mapping Service") - :etm_enabled (false) - :exp ("SRV_REDIRECT(80,0.0.0.0,80) ") - :include_in_any (false) - :needruleinfo (false) - :proto_type () - :protocol (6) - :reload_proof (false) - :replies (false) - :sync_on_cluster (true) - :timeout (0) - :type (Other) - :weight (100) - ) - : (ftp_mapped - :AdminInfo ( - :chkpf_uid ("{DA123897-B250-11D5-A47A-0006294583C7}") - :ClassName (other_service) - :table (services) - :LastModified ( - :Time ("Mon Aug 27 14:54:07 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :name (ftp_mapped) - ) - :color (orange) - :comments ("FTP Port Mapping Service") - :etm_enabled (false) - :exp ("SRV_REDIRECT(21,0.0.0.0,21), set r_mhandler &ftp_code") - :include_in_any (false) - :needruleinfo (false) - :proto_type () - :protocol (6) - :reload_proof (false) - :replies (false) - :sync_on_cluster (true) - :timeout (0) - :type (Other) - :weight (100) - ) - : (smtp_mapped - :AdminInfo ( - :chkpf_uid ("{DA12389A-B250-11D5-A47A-0006294583C7}") - :ClassName (other_service) - :table (services) - :LastModified ( - :Time ("Mon Aug 27 14:54:07 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :name (smtp_mapped) - ) - :color (orange) - :comments ("SMTP Port Mapping Service") - :etm_enabled (false) - :exp ("SRV_REDIRECT(25,0.0.0.0,25) ") - :include_in_any (false) - :needruleinfo (false) - :proto_type () - :protocol (6) - :reload_proof (false) - :replies (false) - :sync_on_cluster (true) - :timeout (0) - :type (Other) - :weight (100) - ) - : (tunnel_test_mapped - :AdminInfo ( - :chkpf_uid ("{38A8AF07-D990-4178-AA8C-82E32066959C}") - :ClassName (other_service) - :table (services) - :LastModified ( - :Time ("Mon Aug 27 14:54:07 2001") - :By (CheckPoint) - :From (CheckPoint) - ) - :name (tunnel_test_mapped) - ) - :color (black) - :comments ("tunnel teIsoAAAD for a module performing the tunnel test") - :etm_enabled (false) - :exp ("SRV_REDIRECT_LOCAL_UDP(CP_TUNNEL_TEST_PORT, FP2_VER)") - :include_in_any (false) - :needruleinfo (false) - :proto_type () - :protocol (17) - :reload_proof (false) - :replies (false) - :sync_on_cluster (true) - :timeout (0) - :type (Other) - :weight (100) - ) - : (rip - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:07 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB3CD-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (udp_service) - :table (services) - :name (rip) - ) - :delete_on_reply (false) - :color ("Medium Slate Blue") - :comments ("Routing Information Protocol") - :etm_enabled (false) - :include_in_any (true) - :port (520) - :proto_type () - :reload_proof (false) - :replies (true) - :replies_from_any_port (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (Udp) - ) - : (rip-response - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:07 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB3CE-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (other_service) - :table (services) - :name (rip-response) - ) - :color ("Medium Slate Blue") - :comments ("Routing Information Protocol - response") - :etm_enabled (false) - :exp ("dport=520,rip_cmd=RIPCMD_RESPONSE") - :include_in_any (true) - :needruleinfo (false) - :proto_type () - :protocol (17) - :reload_proof (false) - :replies (true) - :sync_on_cluster (true) - :timeout (0) - :type (other) - :weight (0) - ) - : (telnet - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:07 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB3CF-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (tcp_service) - :table (services) - :name (telnet) - ) - :delayed_sync_value (30) - :use_delayed_sync (false) - :color ("Forest Green") - :comments ("Telnet Protocol") - :enable_tcp_resource (false) - :etm_enabled (false) - :include_in_any (true) - :port (23) - :proto_type () - :reload_proof (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (Tcp) - ) - : (ftp-port - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:07 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB3D1-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (tcp_service) - :table (services) - :name (ftp-port) - ) - :delayed_sync_value (30) - :use_delayed_sync (false) - :color ("Forest Green") - :comments ("File Transfer Protocol - PORT mode only") - :enable_tcp_resource (false) - :etm_enabled (false) - :include_in_any (false) - :port (21) - :proto_type (ReferenceObject - :Name (FTP-PORT) - :Table (protocols) - :Uid ("{97AEB371-9AEA-11D5-BD16-0090272CCB30}") - ) - :reload_proof (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (Tcp) - ) - : (ftp-pasv - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:07 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB3D2-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (tcp_service) - :table (services) - :name (ftp-pasv) - ) - :delayed_sync_value (30) - :use_delayed_sync (false) - :color ("Forest Green") - :comments ("File Transfer Protocol - PASV mode only") - :enable_tcp_resource (false) - :etm_enabled (false) - :include_in_any (false) - :port (21) - :proto_type (ReferenceObject - :Name (FTP-PASV) - :Table (protocols) - :Uid ("{97AEB372-9AEA-11D5-BD16-0090272CCB30}") - ) - :reload_proof (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (Tcp) - ) - : (ftp - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:07 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB3D0-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (tcp_service) - :table (services) - :name (ftp) - ) - :delayed_sync_value (30) - :use_delayed_sync (false) - :color ("Forest Green") - :comments ("File Transfer Protocol") - :enable_tcp_resource (false) - :etm_enabled (false) - :include_in_any (true) - :port (21) - :proto_type (ReferenceObject - :Name (FTP) - :Table (protocols) - :Uid ("{97AEB370-9AEA-11D5-BD16-0090272CCB30}") - ) - :reload_proof (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (Tcp) - ) - : (uucp - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:07 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB3D3-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (tcp_service) - :table (services) - :name (uucp) - ) - :delayed_sync_value (30) - :use_delayed_sync (false) - :color ("Forest Green") - :comments ("Unix-to-Unix Copy Program") - :enable_tcp_resource (false) - :etm_enabled (false) - :include_in_any (true) - :port (540) - :proto_type () - :reload_proof (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (Tcp) - ) - : (gopher - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:07 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB3D5-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (tcp_service) - :table (services) - :name (gopher) - ) - :delayed_sync_value (30) - :use_delayed_sync (false) - :color ("Forest Green") - :comments ("The Internet Gopher Protocol") - :enable_tcp_resource (false) - :etm_enabled (false) - :include_in_any (true) - :port (70) - :proto_type () - :reload_proof (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (Tcp) - ) - : (archie - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:07 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB3D6-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (udp_service) - :table (services) - :name (archie) - ) - :delete_on_reply (false) - :color ("Forest Green") - :comments ("Archie Internet Protocol, search for files over FTP servers") - :etm_enabled (false) - :include_in_any (true) - :port (1525) - :proto_type () - :reload_proof (false) - :replies (true) - :replies_from_any_port (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (Udp) - ) - : (wais - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:07 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB3D7-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (tcp_service) - :table (services) - :name (wais) - ) - :delayed_sync_value (30) - :use_delayed_sync (false) - :color ("Forest Green") - :comments ("Wide Area Information Servers") - :enable_tcp_resource (false) - :etm_enabled (false) - :include_in_any (true) - :port (210) - :proto_type () - :reload_proof (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (Tcp) - ) - : (X11-verify - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:07 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB3D8-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (other_service) - :table (services) - :name (X11-verify) - ) - :color (Red) - :comments ("X Window System With Authorization") - :etm_enabled (false) - :exp (x11verify_code) - :include_in_any (true) - :needruleinfo (true) - :proto_type () - :protocol (6) - :reload_proof (false) - :replies (false) - :sync_on_cluster (true) - :timeout (0) - :type (Other) - :weight (100) - ) - : (smtp - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:07 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB3D9-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (tcp_service) - :table (services) - :name (smtp) - ) - :delayed_sync_value (30) - :use_delayed_sync (false) - :color (Magenta) - :comments ("Simple Mail Transfer Protocol") - :enable_tcp_resource (false) - :etm_enabled (false) - :include_in_any (true) - :port (25) - :proto_type (ReferenceObject - :Name (SMTP) - :Table (protocols) - :Uid ("{97AEB374-9AEA-11D5-BD16-0090272CCB30}") - ) - :reload_proof (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (Tcp) - ) - : (pop-2 - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:07 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB3DA-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (tcp_service) - :table (services) - :name (pop-2) - ) - :delayed_sync_value (30) - :use_delayed_sync (false) - :color (Magenta) - :comments ("Post Office Protocol - Version 2") - :enable_tcp_resource (false) - :etm_enabled (false) - :include_in_any (true) - :port (109) - :proto_type () - :reload_proof (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (Tcp) - ) - : (pop-3 - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:07 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB3DB-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (tcp_service) - :table (services) - :name (pop-3) - ) - :delayed_sync_value (30) - :use_delayed_sync (false) - :color (Magenta) - :comments ("Post Office Protocol - Version 3") - :enable_tcp_resource (false) - :etm_enabled (false) - :include_in_any (true) - :port (110) - :proto_type () - :reload_proof (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (Tcp) - ) - : (nntp - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:07 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB3DC-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (tcp_service) - :table (services) - :name (nntp) - ) - :delayed_sync_value (30) - :use_delayed_sync (false) - :color (Magenta) - :comments ("Network News Transfer Protocol") - :enable_tcp_resource (false) - :etm_enabled (false) - :include_in_any (true) - :port (119) - :proto_type () - :reload_proof (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (Tcp) - ) - : (tcp-high-ports - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:07 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB3DD-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (tcp_service) - :table (services) - :name (tcp-high-ports) - ) - :delayed_sync_value (30) - :use_delayed_sync (false) - :color (Yellow) - :comments ("TCP Ports 1024-65535") - :enable_tcp_resource (false) - :etm_enabled (false) - :include_in_any (false) - :port (">1023") - :proto_type () - :reload_proof (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (tcp) - ) - : (udp-high-ports - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:07 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB3DE-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (udp_service) - :table (services) - :name (udp-high-ports) - ) - :delete_on_reply (false) - :color (Yellow) - :comments ("UDP Ports 1024-65535") - :etm_enabled (false) - :include_in_any (false) - :port (">1023") - :proto_type () - :reload_proof (false) - :replies (true) - :replies_from_any_port (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (udp) - ) - : (who - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:07 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB3DF-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (udp_service) - :table (services) - :name (who) - ) - :delete_on_reply (false) - :color (Blue) - :comments ("UNIX who Protocol, who is on the system") - :etm_enabled (false) - :include_in_any (true) - :port (513) - :proto_type () - :reload_proof (false) - :replies (true) - :replies_from_any_port (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (Udp) - ) - : (syslog - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:07 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB3E0-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (udp_service) - :table (services) - :name (syslog) - ) - :delete_on_reply (false) - :color (Blue) - :comments ("UNIX syslog Protocol, control system log") - :etm_enabled (false) - :include_in_any (true) - :port (514) - :proto_type () - :reload_proof (false) - :replies (false) - :replies_from_any_port (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (Udp) - ) - : (netstat - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:07 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB3E1-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (tcp_service) - :table (services) - :name (netstat) - ) - :delayed_sync_value (30) - :use_delayed_sync (false) - :color (Blue) - :comments ("UNIX netstat Protocol, show network status") - :enable_tcp_resource (false) - :etm_enabled (false) - :include_in_any (true) - :port (15) - :proto_type () - :reload_proof (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (Tcp) - ) - : (finger - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:07 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB3E2-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (tcp_service) - :table (services) - :name (finger) - ) - :delayed_sync_value (30) - :use_delayed_sync (false) - :color (Blue) - :comments ("UNIX, Finger Protocol") - :enable_tcp_resource (false) - :etm_enabled (false) - :include_in_any (true) - :port (79) - :proto_type () - :reload_proof (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (Tcp) - ) - : (rwall - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:07 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB3E3-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (rpc_service) - :table (services) - :name (rwall) - ) - :color (Blue) - :comments ("RPC, Shutdown messages") - :etm_enabled (false) - :port (100008) - :proto_type () - :reload_proof (false) - :type (Rpc) - ) - : (rstat - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:07 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB3E4-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (rpc_service) - :table (services) - :name (rstat) - ) - :color (Blue) - :comments ("RPC, Remote statistics") - :etm_enabled (false) - :port (100001) - :proto_type () - :reload_proof (false) - :type (Rpc) - ) - : (name - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:07 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB3E5-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (udp_service) - :table (services) - :name (name) - ) - :delete_on_reply (false) - :color (Black) - :comments ("Host Name Server") - :etm_enabled (false) - :include_in_any (true) - :port (42) - :proto_type () - :reload_proof (false) - :replies (true) - :replies_from_any_port (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (Udp) - ) - : (biff - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:07 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB3E6-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (udp_service) - :table (services) - :name (biff) - ) - :delete_on_reply (false) - :color (Black) - :comments ("UNIX biff Protocol, give notice of incoming mail messages") - :etm_enabled (false) - :include_in_any (true) - :port (512) - :proto_type () - :reload_proof (false) - :replies (true) - :replies_from_any_port (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (Udp) - ) - : (traceroute - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:07 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB3E7-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (other_service) - :table (services) - :name (traceroute) - ) - :color (Black) - :comments ("UNIX Traceroute, print the route packets take to network host") - :etm_enabled (false) - :exp ("uh_dport > 33000, ip_ttl < 30") - :include_in_any (true) - :needruleinfo (false) - :proto_type () - :protocol (17) - :reload_proof (false) - :replies (false) - :sync_on_cluster (true) - :timeout (0) - :type (other) - :weight (0) - ) - : (ident - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:07 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB3E8-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (tcp_service) - :table (services) - :name (ident) - ) - :delayed_sync_value (30) - :use_delayed_sync (false) - :color (Black) - :comments ("Identify RCS keyword strings in files") - :enable_tcp_resource (false) - :etm_enabled (false) - :include_in_any (true) - :port (113) - :proto_type () - :reload_proof (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (tcp) - ) - : (AP-Defender - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:07 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB3E9-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (tcp_service) - :table (services) - :name (AP-Defender) - ) - :delayed_sync_value (30) - :use_delayed_sync (false) - :color (FireBrick) - :comments ("Defender Authentication service") - :enable_tcp_resource (false) - :etm_enabled (false) - :include_in_any (true) - :port (2626) - :proto_type () - :reload_proof (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (tcp) - ) - : (AT-Defender - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:07 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB3EA-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (tcp_service) - :table (services) - :name (AT-Defender) - ) - :delayed_sync_value (30) - :use_delayed_sync (false) - :color (FireBrick) - :comments ("Defender Authentication service") - :enable_tcp_resource (false) - :etm_enabled (false) - :include_in_any (false) - :port (2626) - :proto_type () - :reload_proof (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (tcp) - ) - : (bootp - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:07 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB3EB-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (udp_service) - :table (services) - :name (bootp) - ) - :delete_on_reply (false) - :color (Black) - :comments ("Bootstrap Protocol Server, users automatically configured ") - :etm_enabled (false) - :include_in_any (true) - :port (67) - :proto_type () - :reload_proof (false) - :replies (true) - :replies_from_any_port (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (udp) - ) - : (dhcp-req-localmodule - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:07 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{22725520-8E10-4A91-98AC-DCD1F6C4A4DD}") - :ClassName (udp_service) - :table (services) - :name (dhcp-req-localmodule) - ) - :delete_on_reply (false) - :color (black) - :comments ("DHCP request from enforcement module only") - :etm_enabled (false) - :include_in_any (false) - :port (67) - :proto_type (ReferenceObject - :Name (CP-DHCP-request) - :Table (protocols) - :Uid ("{71878CD2-B8A9-11D5-BB1D-D496C1818686}") - ) - :reload_proof (false) - :replies (false) - :replies_from_any_port (false) - :src_port (68) - :sync_on_cluster (true) - :timeout (10) - :type (Udp) - ) - : (dhcp-rep-localmodule - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:07 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{FCA646B5-EF34-4DF1-895D-7639E181501A}") - :ClassName (udp_service) - :table (services) - :name (dhcp-rep-localmodule) - ) - :delete_on_reply (false) - :color (black) - :comments ("DHCP reply to enforcement module only") - :etm_enabled (false) - :include_in_any (false) - :port (68) - :proto_type (ReferenceObject - :Name (CP-DHCP-reply) - :Table (protocols) - :Uid ("{71879F1A-B8A9-11D5-BB1D-D496C1818686}") - ) - :reload_proof (false) - :replies (false) - :replies_from_any_port (false) - :src_port (67) - :sync_on_cluster (true) - :timeout (10) - :type (Udp) - ) - : (securid-udp - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:07 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB3EC-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (udp_service) - :table (services) - :name (securid-udp) - ) - :delete_on_reply (false) - :color (FireBrick) - :comments ("Token based Authentication service (UDP)") - :etm_enabled (false) - :include_in_any (true) - :port (5500) - :proto_type () - :reload_proof (false) - :replies (true) - :replies_from_any_port (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (Udp) - ) - : (securidprop - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:07 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB3ED-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (tcp_service) - :table (services) - :name (securidprop) - ) - :delayed_sync_value (30) - :use_delayed_sync (false) - :color (FireBrick) - :comments ("Token based Authentication service (TCP)") - :enable_tcp_resource (false) - :etm_enabled (false) - :include_in_any (true) - :port (5510) - :proto_type () - :reload_proof (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (Tcp) - ) - : (sqlnet1 - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:07 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB3EE-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (tcp_service) - :table (services) - :name (sqlnet1) - ) - :delayed_sync_value (30) - :use_delayed_sync (false) - :color (Foreground) - :comments ("Oracle SQL*Net Version 1") - :enable_tcp_resource (false) - :etm_enabled (false) - :include_in_any (true) - :port (1521) - :proto_type () - :reload_proof (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (tcp) - ) - : (sqlnet2-1521 - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:07 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB3EF-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (tcp_service) - :table (services) - :name (sqlnet2-1521) - ) - :delayed_sync_value (30) - :use_delayed_sync (false) - :color (Foreground) - :comments ("part of Oracle SQL*Net Version 2 Services") - :enable_tcp_resource (false) - :etm_enabled (false) - :include_in_any (false) - :port (1521) - :proto_type (ReferenceObject - :Name (SQLNET2) - :Table (protocols) - :Uid ("{97AEB376-9AEA-11D5-BD16-0090272CCB30}") - ) - :reload_proof (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (tcp) - ) - : (sqlnet2-1525 - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:07 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB3F0-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (tcp_service) - :table (services) - :name (sqlnet2-1525) - ) - :delayed_sync_value (30) - :use_delayed_sync (false) - :color (Foreground) - :comments ("part of Oracle SQL*Net Version 2 Services") - :enable_tcp_resource (false) - :etm_enabled (false) - :include_in_any (true) - :port (1525) - :proto_type (ReferenceObject - :Name (SQLNET2) - :Table (protocols) - :Uid ("{97AEB376-9AEA-11D5-BD16-0090272CCB30}") - ) - :reload_proof (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (tcp) - ) - : (sqlnet2-1526 - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:07 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB3F1-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (tcp_service) - :table (services) - :name (sqlnet2-1526) - ) - :delayed_sync_value (30) - :use_delayed_sync (false) - :color (Foreground) - :comments ("part of Oracle SQL*Net Version 2 Services") - :enable_tcp_resource (false) - :etm_enabled (false) - :include_in_any (true) - :port (1526) - :proto_type (ReferenceObject - :Name (SQLNET2) - :Table (protocols) - :Uid ("{97AEB376-9AEA-11D5-BD16-0090272CCB30}") - ) - :reload_proof (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (tcp) - ) - : (FreeTel-outgoing-server - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:07 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB3F3-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (udp_service) - :table (services) - :name (FreeTel-outgoing-server) - ) - :delete_on_reply (false) - :color (Foreground) - :comments ("real-time full-duplex voice communication via the Internet-server") - :etm_enabled (false) - :include_in_any (false) - :port (21300) - :proto_type (ReferenceObject - :Name (FreeTel) - :Table (protocols) - :Uid ("{97AEB37E-9AEA-11D5-BD16-0090272CCB30}") - ) - :reload_proof (false) - :replies (true) - :replies_from_any_port (false) - :src_port (21301-21305) - :sync_on_cluster (true) - :timeout (0) - :type (Udp) - ) - : (FreeTel-outgoing-client - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:07 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB3F4-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (other_service) - :table (services) - :name (FreeTel-outgoing-client) - ) - :color (Foreground) - :comments ("real-time full-duplex voice communication via the Internet-client") - :etm_enabled (false) - :exp (freetel_outgoing) - :include_in_any (true) - :needruleinfo (false) - :proto_type () - :protocol (17) - :reload_proof (false) - :replies (false) - :sync_on_cluster (true) - :timeout (0) - :type (other) - :weight (0) - ) - : (FreeTel-incoming - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:07 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB3F6-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (other_service) - :table (services) - :name (FreeTel-incoming) - ) - :color (Foreground) - :comments ("FreeTel Incoming Connections") - :etm_enabled (false) - :exp (freetel_incoming) - :include_in_any (true) - :needruleinfo (false) - :proto_type () - :protocol (17) - :reload_proof (false) - :replies (false) - :sync_on_cluster (true) - :timeout (0) - :type (other) - :weight (0) - ) - : (echo-tcp - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:07 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB3F7-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (tcp_service) - :table (services) - :name (echo-tcp) - ) - :delayed_sync_value (30) - :use_delayed_sync (false) - :color (Black) - :comments ("Echo Protocol (TCP)") - :enable_tcp_resource (false) - :etm_enabled (false) - :include_in_any (true) - :port (7) - :proto_type () - :reload_proof (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (Tcp) - ) - : (echo-udp - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:07 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB3F8-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (udp_service) - :table (services) - :name (echo-udp) - ) - :delete_on_reply (false) - :color (Black) - :comments ("Echo Protocol (UDP)") - :etm_enabled (false) - :include_in_any (true) - :port (7) - :proto_type () - :reload_proof (false) - :replies (true) - :replies_from_any_port (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (Udp) - ) - : (domain-tcp - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:07 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB3F9-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (tcp_service) - :table (services) - :name (domain-tcp) - ) - :delayed_sync_value (30) - :use_delayed_sync (false) - :color (Black) - :comments ("Domain Name System Download") - :enable_tcp_resource (false) - :etm_enabled (false) - :include_in_any (true) - :port (53) - :proto_type () - :reload_proof (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (Tcp) - ) - : (domain-udp - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:07 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB3FA-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (udp_service) - :table (services) - :name (domain-udp) - ) - :delete_on_reply (false) - :color (Black) - :comments ("Domain Name System Queries") - :etm_enabled (false) - :include_in_any (true) - :port (53) - :proto_type () - :reload_proof (false) - :replies (true) - :replies_from_any_port (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (Udp) - ) - : (kerberos-tcp - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:07 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB3FB-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (tcp_service) - :table (services) - :name (kerberos-tcp) - ) - :delayed_sync_value (30) - :use_delayed_sync (false) - :color (Black) - :comments ("secure method for authenticating a request for service") - :enable_tcp_resource (false) - :etm_enabled (false) - :include_in_any (true) - :port (750) - :proto_type () - :reload_proof (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (Tcp) - ) - : (kerberos-udp - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:07 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB3FC-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (udp_service) - :table (services) - :name (kerberos-udp) - ) - :delete_on_reply (false) - :color (Black) - :comments ("secure method for authenticating a request for service") - :etm_enabled (false) - :include_in_any (true) - :port (750) - :proto_type () - :reload_proof (false) - :replies (true) - :replies_from_any_port (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (Udp) - ) - : (discard-tcp - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:07 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB3FD-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (tcp_service) - :table (services) - :name (discard-tcp) - ) - :delayed_sync_value (30) - :use_delayed_sync (false) - :color (Black) - :comments ("Discard Server Protocol (TCP)") - :enable_tcp_resource (false) - :etm_enabled (false) - :include_in_any (true) - :port (9) - :proto_type () - :reload_proof (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (Tcp) - ) - : (discard-udp - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:07 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB3FE-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (udp_service) - :table (services) - :name (discard-udp) - ) - :delete_on_reply (false) - :color (Black) - :comments ("Discard Server Protocol (UDP)") - :etm_enabled (false) - :include_in_any (true) - :port (9) - :proto_type () - :reload_proof (false) - :replies (false) - :replies_from_any_port (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (Udp) - ) - : (time-tcp - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:07 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB3FF-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (tcp_service) - :table (services) - :name (time-tcp) - ) - :delayed_sync_value (30) - :use_delayed_sync (false) - :color (Black) - :comments ("Time Server Protocol (TCP)") - :enable_tcp_resource (false) - :etm_enabled (false) - :include_in_any (true) - :port (37) - :proto_type () - :reload_proof (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (Tcp) - ) - : (time-udp - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:07 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB400-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (udp_service) - :table (services) - :name (time-udp) - ) - :delete_on_reply (false) - :color (Black) - :comments ("Time Server Protocol (UDP)") - :etm_enabled (false) - :include_in_any (true) - :port (37) - :proto_type () - :reload_proof (false) - :replies (true) - :replies_from_any_port (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (Udp) - ) - : (daytime-tcp - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:07 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB401-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (tcp_service) - :table (services) - :name (daytime-tcp) - ) - :delayed_sync_value (30) - :use_delayed_sync (false) - :color (Black) - :comments ("Daytime Server Protocol (TCP)") - :enable_tcp_resource (false) - :etm_enabled (false) - :include_in_any (true) - :port (13) - :proto_type () - :reload_proof (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (Tcp) - ) - : (daytime-udp - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:07 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB402-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (udp_service) - :table (services) - :name (daytime-udp) - ) - :delete_on_reply (false) - :color (Black) - :comments ("Daytime Server Protocol (UDP)") - :etm_enabled (false) - :include_in_any (true) - :port (13) - :proto_type () - :reload_proof (false) - :replies (true) - :replies_from_any_port (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (Udp) - ) - : (ntp-tcp - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:07 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB403-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (tcp_service) - :table (services) - :name (ntp-tcp) - ) - :delayed_sync_value (30) - :use_delayed_sync (false) - :color (Black) - :comments ("Network Time Protocol (TCP)") - :enable_tcp_resource (false) - :etm_enabled (false) - :include_in_any (true) - :port (123) - :proto_type () - :reload_proof (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (Tcp) - ) - : (ntp-udp - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:07 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB404-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (udp_service) - :table (services) - :name (ntp-udp) - ) - :delete_on_reply (false) - :color (Black) - :comments ("Network Time Protocol (UDP)") - :etm_enabled (false) - :include_in_any (true) - :port (123) - :proto_type () - :reload_proof (false) - :replies (true) - :replies_from_any_port (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (Udp) - ) - : (icmp-proto - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:07 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB405-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (other_service) - :table (services) - :name (icmp-proto) - ) - :color ("Dark Orchid") - :comments ("Internet Control Message Protocol") - :etm_enabled (false) - :exp () - :include_in_any (true) - :needruleinfo (false) - :proto_type () - :protocol (1) - :reload_proof (false) - :replies (false) - :sync_on_cluster (true) - :timeout (0) - :type (other) - :weight (0) - ) - : (echo-reply - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:07 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB406-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (icmp_service) - :table (services) - :name (echo-reply) - ) - :color ("Dark Orchid") - :comments ("ICMP, echo reply") - :etm_enabled (true) - :icmp_code () - :icmp_type (0) - :proto_type () - :reload_proof (false) - :type (Icmp) - ) - : (dest-unreach - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB407-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (icmp_service) - :table (services) - :name (dest-unreach) - ) - :color ("Dark Orchid") - :comments ("ICMP, destination unreach") - :etm_enabled (false) - :icmp_code () - :icmp_type (3) - :proto_type () - :reload_proof (false) - :type (Icmp) - ) - : (source-quench - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB408-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (icmp_service) - :table (services) - :name (source-quench) - ) - :color ("Dark Orchid") - :comments ("ICMP, source quench") - :etm_enabled (false) - :icmp_code () - :icmp_type (4) - :proto_type () - :reload_proof (false) - :type (Icmp) - ) - : (redirect - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB409-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (icmp_service) - :table (services) - :name (redirect) - ) - :color ("Dark Orchid") - :comments ("ICMP, route redirect") - :etm_enabled (true) - :icmp_code () - :icmp_type (5) - :proto_type () - :reload_proof (false) - :type (Icmp) - ) - : (echo-request - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB40A-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (icmp_service) - :table (services) - :name (echo-request) - ) - :color ("Dark Orchid") - :comments ("ICMP, echo request") - :etm_enabled (true) - :icmp_code () - :icmp_type (8) - :proto_type () - :reload_proof (false) - :type (Icmp) - ) - : (time-exceeded - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB40B-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (icmp_service) - :table (services) - :name (time-exceeded) - ) - :color ("Dark Orchid") - :comments ("ICMP, time to live exceeded") - :etm_enabled (false) - :icmp_code () - :icmp_type (11) - :proto_type () - :reload_proof (false) - :type (Icmp) - ) - : (param-prblm - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB40C-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (icmp_service) - :table (services) - :name (param-prblm) - ) - :color ("Dark Orchid") - :comments ("ICMP, parameters problem") - :etm_enabled (false) - :icmp_code () - :icmp_type (12) - :proto_type () - :reload_proof (false) - :type (Icmp) - ) - : (timestamp - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB40D-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (icmp_service) - :table (services) - :name (timestamp) - ) - :color ("Dark Orchid") - :comments ("ICMP, timestamp request") - :etm_enabled (true) - :icmp_code () - :icmp_type (13) - :proto_type () - :reload_proof (false) - :type (Icmp) - ) - : (timestamp-reply - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB40E-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (icmp_service) - :table (services) - :name (timestamp-reply) - ) - :color ("Dark Orchid") - :comments ("ICMP, timestamp reply") - :etm_enabled (true) - :icmp_code () - :icmp_type (14) - :proto_type () - :reload_proof (false) - :type (Icmp) - ) - : (info-req - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB40F-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (icmp_service) - :table (services) - :name (info-req) - ) - :color ("Dark Orchid") - :comments ("ICMP, info request") - :etm_enabled (true) - :icmp_code () - :icmp_type (15) - :proto_type () - :reload_proof (false) - :type (Icmp) - ) - : (info-reply - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB410-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (icmp_service) - :table (services) - :name (info-reply) - ) - :color ("Dark Orchid") - :comments ("ICMP, info reply") - :etm_enabled (true) - :icmp_code () - :icmp_type (16) - :proto_type () - :reload_proof (false) - :type (Icmp) - ) - : (mask-request - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB411-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (icmp_service) - :table (services) - :name (mask-request) - ) - :color ("Dark Orchid") - :comments ("ICMP, mask request") - :etm_enabled (true) - :icmp_code () - :icmp_type (17) - :proto_type () - :reload_proof (false) - :type (Icmp) - ) - : (mask-reply - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB412-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (icmp_service) - :table (services) - :name (mask-reply) - ) - :color ("Dark Orchid") - :comments ("ICMP, mask reply") - :etm_enabled (true) - :icmp_code () - :icmp_type (18) - :proto_type () - :reload_proof (false) - :type (Icmp) - ) - : (nbname - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB414-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (udp_service) - :table (services) - :name (nbname) - ) - :delete_on_reply (false) - :color (Magenta) - :comments ("NetBios Name Service") - :etm_enabled (false) - :include_in_any (true) - :port (137) - :proto_type (ReferenceObject - :Name (NBNAME) - :Table (protocols) - :Uid ("{97AEB384-9AEA-11D5-BD16-0090272CCB30}") - ) - :reload_proof (false) - :replies (true) - :replies_from_any_port (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (Udp) - ) - : (nbdatagram - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB415-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (udp_service) - :table (services) - :name (nbdatagram) - ) - :delete_on_reply (false) - :color (Magenta) - :comments ("NetBios Datagram Service") - :etm_enabled (false) - :include_in_any (true) - :port (138) - :proto_type (ReferenceObject - :Name (NBDATAGRAM) - :Table (protocols) - :Uid ("{97AEB385-9AEA-11D5-BD16-0090272CCB30}") - ) - :reload_proof (false) - :replies (true) - :replies_from_any_port (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (Udp) - ) - : (nbsession - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB416-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (tcp_service) - :table (services) - :name (nbsession) - ) - :delayed_sync_value (30) - :use_delayed_sync (false) - :color (Magenta) - :comments ("NetBios Session Service") - :enable_tcp_resource (false) - :etm_enabled (false) - :include_in_any (true) - :port (139) - :proto_type (ReferenceObject - :Name (CIFS) - :Table (protocols) - :Uid ("{97AEB373-9AEA-11D5-BD16-0090272CCB31}") - ) - :reload_proof (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (Tcp) - ) - : (irc1 - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB417-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (tcp_service) - :table (services) - :name (irc1) - ) - :delayed_sync_value (30) - :use_delayed_sync (false) - :color (Black) - :comments ("Internet Relay Chat Protocol") - :enable_tcp_resource (false) - :etm_enabled (false) - :include_in_any (true) - :port (6660-6670) - :proto_type () - :reload_proof (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (Tcp) - ) - : (lotus - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB419-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (tcp_service) - :table (services) - :name (lotus) - ) - :delayed_sync_value (30) - :use_delayed_sync (false) - :color (Black) - :comments ("Lotus iNotes Web Access Protocol") - :enable_tcp_resource (false) - :etm_enabled (false) - :include_in_any (true) - :port (1352) - :proto_type () - :reload_proof (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (Tcp) - ) - : (interphone - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB41A-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (udp_service) - :table (services) - :name (interphone) - ) - :delete_on_reply (false) - :color (Blue) - :comments ("Vocaltec Internet Phone") - :etm_enabled (false) - :include_in_any (true) - :port (22555) - :proto_type () - :reload_proof (false) - :replies (true) - :replies_from_any_port (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (Udp) - ) - : (Real-Audio - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB41B-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (tcp_service) - :table (services) - :name (Real-Audio) - ) - :delayed_sync_value (30) - :use_delayed_sync (false) - :color (Blue) - :comments ("RealNetworks PNA Protocol") - :enable_tcp_resource (false) - :etm_enabled (false) - :include_in_any (true) - :port (7070) - :proto_type (ReferenceObject - :Name (PNA) - :Table (protocols) - :Uid ("{97AEB37A-9AEA-11D5-BD16-0090272CCB30}") - ) - :reload_proof (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (tcp) - ) - : (rtsp - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB41C-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (tcp_service) - :table (services) - :name (rtsp) - ) - :delayed_sync_value (30) - :use_delayed_sync (false) - :color (Blue) - :comments ("Real Time Streaming Protocol") - :enable_tcp_resource (false) - :etm_enabled (false) - :include_in_any (true) - :port (554) - :proto_type (ReferenceObject - :Name (RTSP) - :Table (protocols) - :Uid ("{97AEB37B-9AEA-11D5-BD16-0090272CCB30}") - ) - :reload_proof (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (tcp) - ) - : (TACACS - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB41F-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (udp_service) - :table (services) - :name (TACACS) - ) - :delete_on_reply (false) - :color (FireBrick) - :comments ("Terminal Access Controller Access Control System over UDP") - :etm_enabled (false) - :include_in_any (true) - :port (49) - :proto_type () - :reload_proof (false) - :replies (true) - :replies_from_any_port (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (udp) - ) - : (TACACSplus - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB420-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (tcp_service) - :table (services) - :name (TACACSplus) - ) - :delayed_sync_value (30) - :use_delayed_sync (false) - :color (Black) - :comments ("Terminal Access Controller Access Control System over TCP") - :enable_tcp_resource (false) - :etm_enabled (false) - :include_in_any (true) - :port (49) - :proto_type () - :reload_proof (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (tcp) - ) - : (SKIP - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB421-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (other_service) - :table (services) - :name (SKIP) - ) - :color (Cyan) - :comments ("IPSEC Simple Key Management for Internet Protocols") - :etm_enabled (false) - :exp () - :include_in_any (true) - :needruleinfo (false) - :proto_type () - :protocol (57) - :reload_proof (false) - :replies (true) - :sync_on_cluster (true) - :timeout (600) - :type (other) - :weight (0) - ) - : (AH - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB422-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (other_service) - :table (services) - :name (AH) - ) - :color (Cyan) - :comments ("IPSEC Authentication Header Protocol") - :etm_enabled (false) - :exp () - :include_in_any (true) - :needruleinfo (false) - :proto_type () - :protocol (51) - :reload_proof (false) - :replies (true) - :sync_on_cluster (true) - :timeout (600) - :type (other) - :weight (0) - ) - : (ESP - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB423-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (other_service) - :table (services) - :name (ESP) - ) - :color (cyan) - :comments ("IPSEC Encapsulating Security Payload Protocol") - :etm_enabled (false) - :exp () - :include_in_any (true) - :needruleinfo (false) - :proto_type () - :protocol (50) - :reload_proof (false) - :replies (true) - :sync_on_cluster (true) - :timeout (600) - :type (other) - :weight (0) - ) - : (gre - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB424-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (other_service) - :table (services) - :name (gre) - ) - :color (Red) - :comments () - :etm_enabled (false) - :exp () - :include_in_any (true) - :needruleinfo (false) - :proto_type () - :protocol (47) - :reload_proof (false) - :replies (true) - :sync_on_cluster (true) - :timeout (600) - :type (other) - :weight (0) - ) - : (pptp-tcp - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB425-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (tcp_service) - :table (services) - :name (pptp-tcp) - ) - :delayed_sync_value (30) - :use_delayed_sync (false) - :color (Red) - :comments ("Point-to-Point Tunneling Protocol, extension of PPP") - :enable_tcp_resource (false) - :etm_enabled (false) - :include_in_any (true) - :port (1723) - :proto_type () - :reload_proof (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (Tcp) - ) - : (H323_ras - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By (CheckPoint) - :From (CheckPoint) - ) - :chkpf_uid ("{97AEB378-9AEA-11D5-BD16-0090272CCB32}") - :ClassName (udp_service) - :table (services) - :name (H323_ras) - ) - :delete_on_reply (false) - :color (Cyan) - :comments ("RAS and associated connections (H.323 protocols)") - :etm_enabled (false) - :include_in_any (false) - :port (1719) - :proto_type (ReferenceObject - :Name (H.323_RAS) - :Table (protocols) - :Uid ("{97AEB378-9AEA-11D5-BD16-0090272CCB31}") - ) - :reload_proof (false) - :replies (true) - :replies_from_any_port (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (udp) - ) - : (H323_ras_only - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By (CheckPoint) - :From (CheckPoint) - ) - :chkpf_uid ("{97AEB432-9AEA-11D5-BD16-0090272CCB31}") - :ClassName (udp_service) - :table (services) - :name (H323_ras_only) - ) - :delete_on_reply (false) - :color (Cyan) - :comments ("Endpoint to Gatekeeper and Gatekeeper to Gatekeeper communication") - :etm_enabled (false) - :include_in_any (true) - :port (1719) - :proto_type () - :reload_proof (false) - :replies (true) - :replies_from_any_port (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (udp) - ) - : (T.120 - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB428-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (tcp_service) - :table (services) - :name (T.120) - ) - :delayed_sync_value (30) - :use_delayed_sync (false) - :color (Cyan) - :comments ("H323, Application sharing protocol") - :enable_tcp_resource (false) - :etm_enabled (false) - :include_in_any (true) - :port (1503) - :proto_type () - :reload_proof (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (Tcp) - ) - : (NCP - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB429-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (tcp_service) - :table (services) - :name (NCP) - ) - :delayed_sync_value (30) - :use_delayed_sync (false) - :color (Magenta) - :comments ("Novell NetWare Core Protocol") - :enable_tcp_resource (false) - :etm_enabled (false) - :include_in_any (true) - :port (524) - :proto_type () - :reload_proof (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (Tcp) - ) - : (Orbix-1570 - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB42A-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (tcp_service) - :table (services) - :name (Orbix-1570) - ) - :delayed_sync_value (30) - :use_delayed_sync (false) - :color (black) - :comments ("IONA Orbix Daemon (IIOP) Port 1570") - :enable_tcp_resource (false) - :etm_enabled (false) - :include_in_any (true) - :port (1570) - :proto_type (ReferenceObject - :Name (IIOP) - :Table (protocols) - :Uid ("{97AEB386-9AEA-11D5-BD16-0090272CCB30}") - ) - :reload_proof (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (tcp) - ) - : (Orbix-1571 - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB42B-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (tcp_service) - :table (services) - :name (Orbix-1571) - ) - :delayed_sync_value (30) - :use_delayed_sync (false) - :color (black) - :comments ("IONA Orbix Daemon (IIOP) Port 1571") - :enable_tcp_resource (false) - :etm_enabled (false) - :include_in_any (true) - :port (1571) - :proto_type (ReferenceObject - :Name (IIOP) - :Table (protocols) - :Uid ("{97AEB386-9AEA-11D5-BD16-0090272CCB30}") - ) - :reload_proof (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (tcp) - ) - : (OAS-NameServer - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB42D-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (tcp_service) - :table (services) - :name (OAS-NameServer) - ) - :delayed_sync_value (30) - :use_delayed_sync (false) - :color (black) - :comments ("Oracle Application Server (IIOP) NameServer") - :enable_tcp_resource (false) - :etm_enabled (false) - :include_in_any (true) - :port (2649) - :proto_type (ReferenceObject - :Name (IIOP) - :Table (protocols) - :Uid ("{97AEB386-9AEA-11D5-BD16-0090272CCB30}") - ) - :reload_proof (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (tcp) - ) - : (OAS-ORB - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB42E-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (tcp_service) - :table (services) - :name (OAS-ORB) - ) - :delayed_sync_value (30) - :use_delayed_sync (false) - :color (black) - :comments ("Oracle Application Server (IIOP) ORB") - :enable_tcp_resource (false) - :etm_enabled (false) - :include_in_any (true) - :port (2651) - :proto_type (ReferenceObject - :Name (IIOP) - :Table (protocols) - :Uid ("{97AEB386-9AEA-11D5-BD16-0090272CCB30}") - ) - :reload_proof (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (tcp) - ) - : (Sitara - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB430-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (other_service) - :table (services) - :name (Sitara) - ) - :color (Red) - :comments ("Sitara Networks Protocol (SpeedSeeker)") - :etm_enabled (false) - :exp () - :include_in_any (true) - :needruleinfo (false) - :proto_type () - :protocol (109) - :reload_proof (false) - :replies (true) - :sync_on_cluster (true) - :timeout (0) - :type (other) - :weight (0) - ) - : (IS411-srvr - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB431-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (tcp_service) - :table (services) - :name (IS411-srvr) - ) - :delayed_sync_value (30) - :use_delayed_sync (false) - :color (Blue) - :comments () - :enable_tcp_resource (false) - :etm_enabled (false) - :include_in_any (true) - :port (6499) - :proto_type () - :reload_proof (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (tcp) - ) - : (Streamworks - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB432-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (udp_service) - :table (services) - :name (Streamworks) - ) - :delete_on_reply (false) - :color (Red) - :comments () - :etm_enabled (false) - :include_in_any (true) - :port (1558) - :proto_type () - :reload_proof (false) - :replies (true) - :replies_from_any_port (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (udp) - ) - : (ldap - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB433-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (tcp_service) - :table (services) - :name (ldap) - ) - :delayed_sync_value (30) - :use_delayed_sync (false) - :color (Foreground) - :comments ("Lightweight Directory Access Protocol") - :enable_tcp_resource (false) - :etm_enabled (true) - :include_in_any (true) - :port (389) - :proto_type () - :reload_proof (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (tcp) - ) - : (ldap-ssl - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB434-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (tcp_service) - :table (services) - :name (ldap-ssl) - ) - :delayed_sync_value (30) - :use_delayed_sync (false) - :color (Foreground) - :comments ("Lightweight Directory Access Protocol over TLS/SSL") - :enable_tcp_resource (false) - :etm_enabled (false) - :include_in_any (true) - :port (636) - :proto_type () - :reload_proof (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (tcp) - ) - : (Entrust-Admin - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB435-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (tcp_service) - :table (services) - :name (Entrust-Admin) - ) - :delayed_sync_value (30) - :use_delayed_sync (false) - :color (FireBrick) - :comments ("Entrust CA Administration Service") - :enable_tcp_resource (false) - :etm_enabled (false) - :include_in_any (true) - :port (710) - :proto_type () - :reload_proof (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (tcp) - ) - : (Entrust-KeyMgmt - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB436-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (tcp_service) - :table (services) - :name (Entrust-KeyMgmt) - ) - :delayed_sync_value (30) - :use_delayed_sync (false) - :color (FireBrick) - :comments ("Entrust CA Key Management Service") - :enable_tcp_resource (false) - :etm_enabled (false) - :include_in_any (true) - :port (709) - :proto_type () - :reload_proof (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (tcp) - ) - : (MetaIP-UAT - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB437-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (udp_service) - :table (services) - :name (MetaIP-UAT) - ) - :delete_on_reply (false) - :color (FireBrick) - :comments ("Check Point Meta IP UAM Client-Server Communication") - :etm_enabled (false) - :include_in_any (false) - :port (5004) - :proto_type () - :reload_proof (false) - :replies (true) - :replies_from_any_port (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (udp) - ) - : (RainWall_Command - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By (CheckPoint) - :From (CheckPoint) - ) - :chkpf_uid ("{B9BBEEBA-B639-41A3-97D5-1F9D982D7E44}") - :ClassName (tcp_service) - :table (services) - :name (RainWall_Command) - ) - :delayed_sync_value (30) - :use_delayed_sync (false) - :color (black) - :comments ("RainWall higu availability daemon") - :enable_tcp_resource (false) - :etm_enabled (false) - :include_in_any (true) - :port (6374) - :proto_type () - :reload_proof (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (Tcp) - ) - : (RainWall_Daemon - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By (CheckPoint) - :From (CheckPoint) - ) - :chkpf_uid ("{21CC3F85-E6DF-443D-9846-BD39BD015B85}") - :ClassName (udp_service) - :table (services) - :name (RainWall_Daemon) - ) - :delete_on_reply (false) - :color (black) - :comments ("RainWall daemons communication") - :etm_enabled (false) - :include_in_any (true) - :port (6372) - :proto_type () - :reload_proof (false) - :replies (true) - :replies_from_any_port (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (Udp) - ) - : (RainWall_Status - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By (CheckPoint) - :From (CheckPoint) - ) - :chkpf_uid ("{4FBD29C5-06DB-4912-B23D-1BD50D693185}") - :ClassName (udp_service) - :table (services) - :name (RainWall_Status) - ) - :delete_on_reply (false) - :color (black) - :comments ("RainWall remote management status") - :etm_enabled (false) - :include_in_any (true) - :port (6374) - :proto_type () - :reload_proof (false) - :replies (true) - :replies_from_any_port (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (Udp) - ) - : (RainWall_Stop - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By (CheckPoint) - :From (CheckPoint) - ) - :chkpf_uid ("{5FF8E3F0-F9E7-47C0-A8CE-FABCCCDB7755}") - :ClassName (udp_service) - :table (services) - :name (RainWall_Stop) - ) - :delete_on_reply (false) - :color (black) - :comments ("RainWall monitoring") - :etm_enabled (false) - :include_in_any (true) - :port (6373) - :proto_type () - :reload_proof (false) - :replies (true) - :replies_from_any_port (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (Udp) - ) - : (StoneBeat-Control - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB438-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (tcp_service) - :table (services) - :name (StoneBeat-Control) - ) - :delayed_sync_value (30) - :use_delayed_sync (false) - :color (Black) - :comments ("Stonesoft StoneBeat Control") - :enable_tcp_resource (false) - :etm_enabled (false) - :include_in_any (true) - :port (3002) - :proto_type () - :reload_proof (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (tcp) - ) - : (StoneBeat-Daemon - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB439-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (tcp_service) - :table (services) - :name (StoneBeat-Daemon) - ) - :delayed_sync_value (30) - :use_delayed_sync (false) - :color (Black) - :comments ("Stonesoft StoneBeat Daemon Heartbeat") - :enable_tcp_resource (false) - :etm_enabled (false) - :include_in_any (true) - :port (3001) - :proto_type () - :reload_proof (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (tcp) - ) - : (RealSecure - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB43B-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (tcp_service) - :table (services) - :name (RealSecure) - ) - :delayed_sync_value (30) - :use_delayed_sync (false) - :color ("Forest Green") - :comments ("Automatic 'Suspicious Activity Monitoring' activator") - :enable_tcp_resource (false) - :etm_enabled (false) - :include_in_any (true) - :port (2998) - :proto_type () - :reload_proof (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (Tcp) - ) - : (pcANYWHERE-data - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB43E-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (tcp_service) - :table (services) - :name (pcANYWHERE-data) - ) - :delayed_sync_value (30) - :use_delayed_sync (false) - :color (Blue) - :comments ("PCs remote access security software, data") - :enable_tcp_resource (false) - :etm_enabled (false) - :include_in_any (true) - :port (5631) - :proto_type () - :reload_proof (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (Tcp) - ) - : (pcANYWHERE-stat - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB43F-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (udp_service) - :table (services) - :name (pcANYWHERE-stat) - ) - :delete_on_reply (false) - :color (Blue) - :comments ("PCs remote access security software, status") - :etm_enabled (false) - :include_in_any (true) - :port (5632) - :proto_type () - :reload_proof (false) - :replies (true) - :replies_from_any_port (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (Udp) - ) - : (pcTELECOMMUTE-FileSync - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB441-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (tcp_service) - :table (services) - :name (pcTELECOMMUTE-FileSync) - ) - :delayed_sync_value (30) - :use_delayed_sync (false) - :color (Blue) - :comments ("Symantec pcTELECOMMUTE File Synchronization") - :enable_tcp_resource (false) - :etm_enabled (false) - :include_in_any (true) - :port (2299) - :proto_type () - :reload_proof (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (Tcp) - ) - : (vosaic-data - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB444-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (udp_service) - :table (services) - :name (vosaic-data) - ) - :delete_on_reply (false) - :color (Blue) - :comments () - :etm_enabled (false) - :include_in_any (true) - :port (20000-20300) - :proto_type () - :reload_proof (false) - :replies (true) - :replies_from_any_port (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (udp) - ) - : (vosaic-ctrl - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB445-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (tcp_service) - :table (services) - :name (vosaic-ctrl) - ) - :delayed_sync_value (30) - :use_delayed_sync (false) - :color (Blue) - :comments () - :enable_tcp_resource (false) - :etm_enabled (false) - :include_in_any (true) - :port (1235) - :proto_type () - :reload_proof (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (tcp) - ) - : (imap - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB446-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (tcp_service) - :table (services) - :name (imap) - ) - :delayed_sync_value (30) - :use_delayed_sync (false) - :color (Yellow) - :comments ("Interactive Mail Access Protocol") - :enable_tcp_resource (false) - :etm_enabled (false) - :include_in_any (true) - :port (143) - :proto_type () - :reload_proof (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (tcp) - ) - : (FW1_Encapsulation - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB447-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (other_service) - :table (services) - :name (FW1_Encapsulation) - ) - :color (Firebrick) - :comments ("Check Point VPN-1 SecuRemote FWZ Encapsulation Protocol") - :etm_enabled (false) - :exp () - :include_in_any (true) - :needruleinfo (false) - :proto_type () - :protocol (94) - :reload_proof (false) - :replies (true) - :sync_on_cluster (true) - :timeout (600) - :type (other) - :weight (0) - ) - : (netshow - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB448-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (tcp_service) - :table (services) - :name (netshow) - ) - :delayed_sync_value (30) - :use_delayed_sync (false) - :color (Blue) - :comments ("Microsoft NetShow (Windows Media Player)") - :enable_tcp_resource (false) - :etm_enabled (false) - :include_in_any (true) - :port (1755) - :proto_type (ReferenceObject - :Name (NetShow) - :Table (protocols) - :Uid ("{97AEB37C-9AEA-11D5-BD16-0090272CCB30}") - ) - :reload_proof (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (Tcp) - ) - : (backweb - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB449-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (other_service) - :table (services) - :name (backweb) - ) - :color (Blue) - :comments ("PUSH Web applications, send information directly to desktops. over the Internet") - :etm_enabled (false) - :exp (backweb_match) - :include_in_any (true) - :needruleinfo (false) - :proto_type (ReferenceObject - :Name (BackWeb) - :Table (protocols) - :Uid ("{97AEB37F-9AEA-11D5-BD16-0090272CCB30}") - ) - :protocol (17) - :reload_proof (false) - :replies (false) - :sync_on_cluster (true) - :timeout (0) - :type (other) - :weight (0) - ) - : (winframe - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB44A-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (tcp_service) - :table (services) - :name (winframe) - ) - :delayed_sync_value (30) - :use_delayed_sync (false) - :color (Blue) - :comments ("Allows servers to provide applications and data for attached computer workstations (Windows)") - :enable_tcp_resource (false) - :etm_enabled (false) - :include_in_any (true) - :port (1494) - :proto_type (ReferenceObject - :Name (WinFrame) - :Table (protocols) - :Uid ("{97AEB380-9AEA-11D5-BD16-0090272CCB30}") - ) - :reload_proof (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (Tcp) - ) - : (CU-SeeMe - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB44B-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (udp_service) - :table (services) - :name (CU-SeeMe) - ) - :delete_on_reply (false) - :color (Blue) - :comments ("person-to-person or group discussions videoconference") - :etm_enabled (false) - :include_in_any (true) - :port (7648-7652) - :proto_type () - :reload_proof (false) - :replies (true) - :replies_from_any_port (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (udp) - ) - : (CreativePartnerSrvr - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB44C-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (tcp_service) - :table (services) - :name (CreativePartnerSrvr) - ) - :delayed_sync_value (30) - :use_delayed_sync (false) - :color (Red) - :comments ("The Server listening port") - :enable_tcp_resource (false) - :etm_enabled (false) - :include_in_any (true) - :port (453) - :proto_type () - :reload_proof (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (tcp) - ) - : (CreativePartnerClnt - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB44D-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (tcp_service) - :table (services) - :name (CreativePartnerClnt) - ) - :delayed_sync_value (30) - :use_delayed_sync (false) - :color (Red) - :comments ("The Client listening port") - :enable_tcp_resource (false) - :etm_enabled (false) - :include_in_any (true) - :port (455) - :proto_type () - :reload_proof (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (tcp) - ) - : (AOL - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB44F-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (tcp_service) - :table (services) - :name (AOL) - ) - :delayed_sync_value (30) - :use_delayed_sync (false) - :color (Red) - :comments ("America-Online client service (TCP)") - :enable_tcp_resource (false) - :etm_enabled (false) - :include_in_any (true) - :port (5190) - :proto_type () - :reload_proof (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (tcp) - ) - : (OnTime - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB450-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (udp_service) - :table (services) - :name (OnTime) - ) - :delete_on_reply (false) - :color (Foreground) - :comments () - :etm_enabled (false) - :include_in_any (true) - :port (1622) - :proto_type () - :reload_proof (false) - :replies (true) - :replies_from_any_port (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (udp) - ) - : (ConnectedOnLine - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB451-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (tcp_service) - :table (services) - :name (ConnectedOnLine) - ) - :delayed_sync_value (30) - :use_delayed_sync (false) - :color (Foreground) - :comments () - :enable_tcp_resource (false) - :etm_enabled (false) - :include_in_any (true) - :port (16384) - :proto_type () - :reload_proof (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (tcp) - ) - : (MSExchangeDSNSPI - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB452-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (dcerpc_service) - :table (services) - :name (MSExchangeDSNSPI) - ) - :color (Blue) - :comments ("Microsoft Exchange Directory Services (NSPI)") - :etm_enabled (false) - :proto_type () - :reload_proof (false) - :type (dcerpc) - :uuid (f5cc5a18-4264-101a-8c59-08002b2f8426) - ) - : (MSExchangeDSRep - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB453-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (dcerpc_service) - :table (services) - :name (MSExchangeDSRep) - ) - :color (Blue) - :comments ("Microsoft Exchange Directory Replication Services") - :etm_enabled (false) - :proto_type () - :reload_proof (false) - :type (dcerpc) - :uuid (f5cc59b4-4264-101a-8c59-08002b2f8426) - ) - : (MSExchangeDSXDS - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB454-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (dcerpc_service) - :table (services) - :name (MSExchangeDSXDS) - ) - :color (Blue) - :comments ("Microsoft Exchange Directory Services XDS") - :etm_enabled (false) - :proto_type () - :reload_proof (false) - :type (dcerpc) - :uuid (f5cc5a7c-4264-101a-8c59-08002b2f8426) - ) - : (MSExchangeIS - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB455-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (dcerpc_service) - :table (services) - :name (MSExchangeIS) - ) - :color (Blue) - :comments ("Microsoft Exchange Information Store") - :etm_enabled (false) - :proto_type (ReferenceObject - :Name (MSEXCHANGE) - :Table (protocols) - :Uid ("{97AEB382-9AEA-11D5-BD16-0090272CCB30}") - ) - :reload_proof (false) - :type (dcerpc) - :uuid (a4f1db00-ca47-1067-b31f-00dd010662da) - ) - : (MSExchangeMTA - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB456-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (dcerpc_service) - :table (services) - :name (MSExchangeMTA) - ) - :color (Blue) - :comments ("Microsoft Exchange Message Transfer Agent") - :etm_enabled (false) - :proto_type () - :reload_proof (false) - :type (dcerpc) - :uuid (9e8ee830-4459-11ce-979b-00aa005ffebe) - ) - : (MSExchangeADL - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB457-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (dcerpc_service) - :table (services) - :name (MSExchangeADL) - ) - :color (Blue) - :comments ("Microsoft Exchange 2000 Active Directory Logon") - :etm_enabled (false) - :proto_type () - :reload_proof (false) - :type (dcerpc) - :uuid (12345678-1234-abcd-ef00-01234567cffb) - ) - : (MSExchangeDirRep - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB458-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (dcerpc_service) - :table (services) - :name (MSExchangeDirRep) - ) - :color (Blue) - :comments ("Microsoft Exchange 2000 Directory Replication") - :etm_enabled (false) - :proto_type () - :reload_proof (false) - :type (dcerpc) - :uuid (e3514235-4b06-11d1-ab04-00c04fc2dcd2) - ) - : (MSExchangeSysAtt - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB459-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (dcerpc_service) - :table (services) - :name (MSExchangeSysAtt) - ) - :color (Blue) - :comments ("Microsoft Exchange System Attendant") - :etm_enabled (false) - :proto_type () - :reload_proof (false) - :type (dcerpc) - :uuid (469d6ec0-0d87-11ce-b13f-00aa003bac6c) - ) - : (MSExchangeSysAttPriv - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB45A-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (dcerpc_service) - :table (services) - :name (MSExchangeSysAttPriv) - ) - :color (Blue) - :comments ("Microsoft Exchange System Attendant Private") - :etm_enabled (false) - :proto_type () - :reload_proof (false) - :type (dcerpc) - :uuid (83d72bf0-0d89-11ce-b13f-00aa003bac6c) - ) - : (MSExchangeStoreAdm - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB45B-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (dcerpc_service) - :table (services) - :name (MSExchangeStoreAdm) - ) - :color (Blue) - :comments ("Microsoft Exchange Store Administration") - :etm_enabled (false) - :proto_type () - :reload_proof (false) - :type (dcerpc) - :uuid (89742ace-a9ed-11cf-9c0c-08002be7ae86) - ) - : (HP-OpCdistm - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB460-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (dcerpc_service) - :table (services) - :name (HP-OpCdistm) - ) - :color (Blue) - :comments ("HP-OV OpC Distribution Manager") - :etm_enabled (false) - :proto_type () - :reload_proof (false) - :type (dcerpc) - :uuid (5df3dc6f-a568-0000-020f-887805000000) - ) - : (HP-OpCmsgrd-std - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB461-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (dcerpc_service) - :table (services) - :name (HP-OpCmsgrd-std) - ) - :color (Blue) - :comments ("HP-OV OpC Message Receiver") - :etm_enabled (false) - :proto_type () - :reload_proof (false) - :type (dcerpc) - :uuid (6d63f833-c0a0-0000-020f-887818000000) - ) - : (HP-OpCmsgrd-m2m - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB462-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (dcerpc_service) - :table (services) - :name (HP-OpCmsgrd-m2m) - ) - :color (Blue) - :comments ("HP-OV OpC Message Receiver (M2M)") - :etm_enabled (false) - :proto_type () - :reload_proof (false) - :type (dcerpc) - :uuid (6e0b494b-d551-0000-020f-88781a000000) - ) - : (HP-OpCmsgrd-coa - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB463-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (dcerpc_service) - :table (services) - :name (HP-OpCmsgrd-coa) - ) - :color (Blue) - :comments ("HP-OV OpC Message receiver (COA)") - :etm_enabled (false) - :proto_type () - :reload_proof (false) - :type (dcerpc) - :uuid (e0c92330-3ba9-0000-a38b-0800096df3a6) - ) - : (HP-OpCctla - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB464-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (dcerpc_service) - :table (services) - :name (HP-OpCctla) - ) - :color (Blue) - :comments ("HP-OV OpC Control Agent") - :etm_enabled (false) - :proto_type () - :reload_proof (false) - :type (dcerpc) - :uuid (9e0c0224-3654-0000-9a8d-08000949ab4c) - ) - : (HP-OpCctla-cfgpush - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB465-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (dcerpc_service) - :table (services) - :name (HP-OpCctla-cfgpush) - ) - :color (Blue) - :comments ("HP-OV OpC Control Agent (cfgpush)") - :etm_enabled (false) - :proto_type () - :reload_proof (false) - :type (dcerpc) - :uuid (0d8fe322-d6ee-11d2-b858-0800096df3a6) - ) - : (HP-OpCctla-bulk - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB466-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (dcerpc_service) - :table (services) - :name (HP-OpCctla-bulk) - ) - :color (Blue) - :comments ("HP-OV OpC Control Agent (Bulk)") - :etm_enabled (false) - :proto_type () - :reload_proof (false) - :type (dcerpc) - :uuid (8d5cae88-43c9-0000-94f1-0800096df3a6) - ) - : (Pointcast - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB477-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (compound_tcp_service) - :table (services) - :name (Pointcast) - ) - :color ("Forest Green") - :comments ("http subservice for FloodGate use, push web content") - :etm_enabled (false) - :port (80) - :proto_type () - :reload_proof (false) - :svc_type (pointcast) - :type (Tcp_subservice) - ) - : (Cdf - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB478-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (compound_tcp_service) - :table (services) - :name (Cdf) - ) - :color ("Forest Green") - :comments ("http subservice for FloodGate use,Channel Definition Format") - :etm_enabled (false) - :port (80) - :proto_type () - :reload_proof (false) - :svc_type (Cdf) - :type (Tcp_subservice) - ) - : (Marimba_Netcaster - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB479-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (compound_tcp_service) - :table (services) - :name (Marimba_Netcaster) - ) - :color (black) - :comments ("http subservice for FloodGate use, Marimba Castanet Tuner product") - :etm_enabled (false) - :port (80) - :proto_type () - :reload_proof (false) - :svc_type (NetCaster) - :type (Tcp_subservice) - ) - : (Microsoft_Channels - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB47A-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (compound_tcp_service) - :table (services) - :name (Microsoft_Channels) - ) - :color (black) - :comments ("http subservice for FloodGate use, Microsoft Channels") - :etm_enabled (false) - :port (80) - :proto_type () - :reload_proof (false) - :svc_type (CDF) - :type (Tcp_subservice) - ) - : (squid - :AdminInfo ( - :chkpf_uid ("{91C0454D-F70C-44B3-8F2D-70C4A68E9594}") - :ClassName (tcp_service) - :table (services) - :Wiznum (-1) - :LastModified ( - :Time ("Sun Nov 30 19:21:23 2003") - :By (IsoAAAF) - :From (scratchy) - ) - ) - :delayed_sync_value (30) - :use_delayed_sync (false) - :color ("forest green") - :comments () - :enable_tcp_resource (false) - :etm_enabled (false) - :include_in_any (true) - :port (3128) - :proto_type () - :reload_proof (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (Tcp) - ) - : (RAdmin-custom - :AdminInfo ( - :chkpf_uid ("{4FB59153-8212-4A12-BC08-0297AA5F0815}") - :ClassName (tcp_service) - :table (services) - :Wiznum (-1) - :LastModified ( - :Time ("Sun Nov 30 19:36:18 2003") - :By (IsoAAAF) - :From (scratchy) - ) - ) - :delayed_sync_value (30) - :use_delayed_sync (false) - :color (gold) - :comments () - :enable_tcp_resource (false) - :etm_enabled (false) - :include_in_any (true) - :port (60000) - :proto_type () - :reload_proof (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (Tcp) - ) - : (apcupsd - :AdminInfo ( - :chkpf_uid ("{A1044CB4-439C-40C9-8489-FA5086134886}") - :ClassName (tcp_service) - :table (services) - :Wiznum (-1) - :LastModified ( - :Time ("Fri Dec 5 20:06:52 2003") - :By (IsoAAAF) - :From (scratchy) - ) - ) - :delayed_sync_value (30) - :use_delayed_sync (false) - :color (gold) - :comments () - :enable_tcp_resource (false) - :etm_enabled (false) - :include_in_any (false) - :port (6666) - :proto_type () - :reload_proof (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (Tcp) - ) - : (T-online-classic - :AdminInfo ( - :chkpf_uid ("{738B04E5-09F7-44BF-9FEC-AEA0F15B7E9A}") - :ClassName (tcp_service) - :table (services) - :Wiznum (-1) - :LastModified ( - :Time ("Wed Dec 17 21:34:22 2003") - :By (IsoAAAF) - :From (scratchy) - ) - ) - :delayed_sync_value (30) - :use_delayed_sync (false) - :color ("deep pink") - :comments () - :enable_tcp_resource (false) - :etm_enabled (false) - :include_in_any (true) - :port (866) - :proto_type () - :reload_proof (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (Tcp) - ) - : (H323 - :AdminInfo ( - :chkpf_uid ("{97AEB427-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (tcp_service) - :table (services) - :Wiznum (-1) - :LastModified ( - :Time ("Fri Jan 30 21:58:29 2004") - :By (IsoAAAF) - :From (scratchy) - ) - ) - :delayed_sync_value (30) - :use_delayed_sync (false) - :color (cyan) - :comments ("videoconference transmissions over IP networks") - :enable_tcp_resource (false) - :etm_enabled (true) - :include_in_any (false) - :port (1720) - :proto_type (ReferenceObject - :Name (H.323) - :Table (protocols) - :Uid ("{97AEB377-9AEA-11D5-BD16-0090272CCB30}") - ) - :reload_proof (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (tcp) - ) - : (H323_any - :AdminInfo ( - :chkpf_uid ("{97AEB427-9AEA-11D5-BD16-0090272CCB33}") - :ClassName (tcp_service) - :table (services) - :Wiznum (-1) - :LastModified ( - :Time ("Fri Jan 30 21:59:04 2004") - :By (IsoAAAF) - :From (scratchy) - ) - ) - :delayed_sync_value (30) - :use_delayed_sync (false) - :color (cyan) - :comments ("videoconference transmissions over IP networks") - :enable_tcp_resource (false) - :etm_enabled (true) - :include_in_any (false) - :port (1720) - :proto_type (ReferenceObject - :Name (H.323_ANY) - :Table (protocols) - :Uid ("{97AEB377-9AEA-11D5-BD16-0090272CCB35}") - ) - :reload_proof (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (tcp) - ) - : (Citrix_metaFrame - :AdminInfo ( - :chkpf_uid ("{13D7904E-334B-4549-8FBD-6B4D6B8B80B2}") - :ClassName (service_group) - :table (services) - :Wiznum (-1) - :LastModified ( - :Time ("Sun Mar 30 14:50:57 2003") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - : (ReferenceObject - :Name (Citrix_ICA) - :Table (services) - :Uid ("{986BAD5A-94D2-4A8C-81AA-DE98D3ECB5C6}") - ) - : (ReferenceObject - :Name (Citrix_ICA_Browsing) - :Table (services) - :Uid ("{E8C5AB78-F08D-437C-A9B1-BE4A8679D766}") - ) - :color (black) - :comments ("group for citrix communication") - :etm_enabled (false) - :member_class (service) - :members_query () - :type (group) - ) - : (Trojan_Services - :AdminInfo ( - :chkpf_uid ("{F956089C-6DD8-4FF4-9FB1-E13969CDADFF}") - :ClassName (service_group) - :table (services) - :Wiznum (-1) - :LastModified ( - :Time ("Tue Jan 07 19:44:37 2003") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - : (ReferenceObject - :Name (Back_Door_Setup) - :Table (services) - :Uid ("{86077A7D-A8DA-4B5B-919C-366FE91AD1DA}") - ) - : (ReferenceObject - :Name (Backage) - :Table (services) - :Uid ("{96759A8D-AAB8-43D9-BBFC-B459CE66AC87}") - ) - : (ReferenceObject - :Name (BackDoor-G) - :Table (services) - :Uid ("{A651F18C-1C7C-4BD2-9FFE-790C29E3CCD9}") - ) - : (ReferenceObject - :Name (Connect-Back_Backdoor) - :Table (services) - :Uid ("{E0C17142-433D-40A7-9EAA-E1D5EBA40D2E}") - ) - : (ReferenceObject - :Name (CrackDown) - :Table (services) - :Uid ("{88AAA643-BF12-4D40-A02D-E98A8159358A}") - ) - : (ReferenceObject - :Name (DaCryptic) - :Table (services) - :Uid ("{C13E3031-02D6-4341-A307-3DAF10735078}") - ) - : (ReferenceObject - :Name (DerSphere) - :Table (services) - :Uid ("{8055B0DE-DACE-4D18-91F4-F39915B7ABA8}") - ) - : (ReferenceObject - :Name (DerSphere_II) - :Table (services) - :Uid ("{8D971C42-17DE-49A0-A646-A8E0057AEBBD}") - ) - : (ReferenceObject - :Name (Freak2k) - :Table (services) - :Uid ("{08DA33FF-BC5F-402A-9865-BEE8FEE69422}") - ) - : (ReferenceObject - :Name (GateCrasher) - :Table (services) - :Uid ("{81B90130-2A31-45CD-8092-DC492B116CA9}") - ) - : (ReferenceObject - :Name (HackaTack_31785) - :Table (services) - :Uid ("{82BA0DD2-42E6-472D-8877-57F519175C14}") - ) - : (ReferenceObject - :Name (HackaTack_31787) - :Table (services) - :Uid ("{C693C8C1-78E3-450D-936E-AA3278190633}") - ) - : (ReferenceObject - :Name (HackaTack_31788) - :Table (services) - :Uid ("{B8D159DC-AA70-4CC5-9C5A-8C2AD3AA977E}") - ) - : (ReferenceObject - :Name (HackaTack_31789) - :Table (services) - :Uid ("{FF8EA038-34FD-4B7B-8A8A-8D6BF0A599FE}") - ) - : (ReferenceObject - :Name (HackaTack_31790) - :Table (services) - :Uid ("{2176F91C-5FB4-4111-98BD-7D5D5B358FE0}") - ) - : (ReferenceObject - :Name (HackaTack_31791) - :Table (services) - :Uid ("{05647A8C-F0E7-4354-ADBD-C685EE7742F0}") - ) - : (ReferenceObject - :Name (HackaTack_31792) - :Table (services) - :Uid ("{26339B33-1C42-4E49-96E9-55770F6AF0CE}") - ) - : (ReferenceObject - :Name (ICKiller) - :Table (services) - :Uid ("{06233377-3454-489A-B9FB-2F2CA14B895B}") - ) - : (ReferenceObject - :Name (InCommand) - :Table (services) - :Uid ("{230B24DF-1EFA-4A28-B7A4-87DFB79AFBA7}") - ) - : (ReferenceObject - :Name (Jade) - :Table (services) - :Uid ("{C2F963B0-DB3C-42D5-B0F2-A2A7BC0D378D}") - ) - : (ReferenceObject - :Name (Kaos) - :Table (services) - :Uid ("{10F56849-2E03-40DD-9CF7-56AEE2CFA57F}") - ) - : (ReferenceObject - :Name (Kuang2) - :Table (services) - :Uid ("{CE29B597-76B9-48AA-AC24-AE7E23C438ED}") - ) - : (ReferenceObject - :Name (lpdw0rm) - :Table (services) - :Uid ("{73BFBF75-EB13-42C0-BA69-58B8F026B4D6}") - ) - : (ReferenceObject - :Name (Mneah) - :Table (services) - :Uid ("{E43B7817-DBB6-4C74-A95A-C424DC47999C}") - ) - : (ReferenceObject - :Name (Multidropper) - :Table (services) - :Uid ("{E38E4DEA-A610-4416-BF44-6F4E45E95E70}") - ) - : (ReferenceObject - :Name (NoBackO) - :Table (services) - :Uid ("{AA02E546-80D1-453A-91DC-49F606764451}") - ) - : (ReferenceObject - :Name (Port_6667_trojans) - :Table (services) - :Uid ("{AEAA6C77-E87E-4581-AD73-06417391DFAD}") - ) - : (ReferenceObject - :Name (RAT) - :Table (services) - :Uid ("{B236D830-9615-4578-B6E2-B0B44C45FDA0}") - ) - : (ReferenceObject - :Name (Remote_Storm) - :Table (services) - :Uid ("{D4B1F3B0-C606-4B6B-8118-EE61303F8E19}") - ) - : (ReferenceObject - :Name (RexxRave) - :Table (services) - :Uid ("{637B7F26-C4B2-4510-872E-5A10DE046CB4}") - ) - : (ReferenceObject - :Name (Shadyshell) - :Table (services) - :Uid ("{41C4DF08-DBF9-4576-9114-B8F1DC4DC8D7}") - ) - : (ReferenceObject - :Name (SocketsdesTroie) - :Table (services) - :Uid ("{69CA7583-1FD4-4C86-AC1A-680697A9AF93}") - ) - : (ReferenceObject - :Name (SubSeven) - :Table (services) - :Uid ("{E926E948-FAE7-4140-8FED-11426B1A32B9}") - ) - : (ReferenceObject - :Name (Terrortrojan) - :Table (services) - :Uid ("{CC1D78CC-5FCE-4496-A78B-C37AA0622F7A}") - ) - : (ReferenceObject - :Name (TheFlu) - :Table (services) - :Uid ("{02F708DD-0337-485F-A04B-3B931971B93A}") - ) - : (ReferenceObject - :Name (TransScout) - :Table (services) - :Uid ("{16AEE006-0F79-407E-B6A4-F3CC5A7A31D5}") - ) - : (ReferenceObject - :Name (Trinoo) - :Table (services) - :Uid ("{3CF4DA8B-576E-47EC-903E-91F155BD0CD9}") - ) - : (ReferenceObject - :Name (UltorsTrojan) - :Table (services) - :Uid ("{6E745536-B8C9-4DF5-BFD5-043E62013956}") - ) - : (ReferenceObject - :Name (WinHole) - :Table (services) - :Uid ("{25AC306E-1FC9-4E3E-BF66-4A48473CAF3F}") - ) - : (ReferenceObject - :Name (Xanadu) - :Table (services) - :Uid ("{24DE2CDE-DFCD-4C9B-9124-492AC4BEDBA7}") - ) - :color (magenta) - :comments ("Common ports used by trojan applications.") - :etm_enabled (false) - :member_class (service) - :members_query () - :type (group) - ) - : (MS-SQL - :AdminInfo ( - :chkpf_uid ("{68A602A2-28DA-4425-B566-86A537A3BCA3}") - :ClassName (service_group) - :table (services) - :Wiznum (-1) - :LastModified ( - :Time ("Thu Feb 20 18:15:39 2003") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - : (ReferenceObject - :Name (MS-SQL-Monitor) - :Table (services) - :Uid ("{EF245528-9A3D-11D6-9EAA-3E5A6FDD6A6A}") - ) - : (ReferenceObject - :Name (MS-SQL-Monitor_UDP) - :Table (services) - :Uid ("{5AD1A14C-647C-41DE-9F84-D1C34F09D63B}") - ) - : (ReferenceObject - :Name (MS-SQL-Server) - :Table (services) - :Uid ("{DFF4F7BA-9A3D-11D6-91C1-3E5A6FDD5151}") - ) - : (ReferenceObject - :Name (MS-SQL-Server_UDP) - :Table (services) - :Uid ("{BFD72CD2-8E5F-4EDE-BDB2-6DFC016AFCCD}") - ) - :color (black) - :comments ("MS-SQL Server Protocols") - :etm_enabled (false) - :member_class (service) - :members_query () - :type (group) - ) - : (AOL_Messenger - :AdminInfo ( - :chkpf_uid ("{2C970C2B-84A3-40B5-AB0E-83244DD47BCD}") - :ClassName (service_group) - :table (services) - :Wiznum (-1) - :LastModified ( - :Time ("Thu Dec 12 14:19:56 2002") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - : (ReferenceObject - :Name (AOL) - :Table (services) - :Uid ("{97AEB44F-9AEA-11D5-BD16-0090272CCB30}") - ) - : (ReferenceObject - :Name (ICQ_locator) - :Table (services) - :Uid ("{BBEC6807-808D-49B7-B8DC-54C5A655D392}") - ) - :color (black) - :comments ("AOL Instant Messenger. Also used by: ICQ & Apple iChat") - :etm_enabled (false) - :member_class (service) - :members_query () - :type (group) - ) - : (MSN_Messenger - :AdminInfo ( - :chkpf_uid ("{5693ACA1-316D-410E-A8F3-BA5D2F97E5B7}") - :ClassName (service_group) - :table (services) - :Wiznum (-1) - :LastModified ( - :Time ("Thu Dec 12 14:24:19 2002") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - : (ReferenceObject - :Name (MSN_Messenger_1863_UDP) - :Table (services) - :Uid ("{0094AAC2-A29E-4D04-B86C-F31F63DFFAE2}") - ) - : (ReferenceObject - :Name (MSN_Messenger_5190) - :Table (services) - :Uid ("{0AC39B6A-701A-4C33-A88D-9EB0FECF9EF6}") - ) - : (ReferenceObject - :Name (MSN_Messenger_File_Transfer) - :Table (services) - :Uid ("{505BADAD-AE57-4584-9A4C-15987C093A32}") - ) - : (ReferenceObject - :Name (MSN_Messenger_Voice) - :Table (services) - :Uid ("{E3E6D587-3212-4FF4-86A1-D16093689E19}") - ) - : (ReferenceObject - :Name (MSNP) - :Table (services) - :Uid ("{D18F244B-0B13-4FB8-AA2F-D966EEFFB6B3}") - ) - :color (black) - :comments ("MSN Messenger") - :etm_enabled (false) - :member_class (service) - :members_query () - :type (group) - ) - : (Yahoo_Messenger - :AdminInfo ( - :chkpf_uid ("{8E3ED837-81C6-43EF-BADA-7C330C57D891}") - :ClassName (service_group) - :table (services) - :Wiznum (-1) - :LastModified ( - :Time ("Thu Dec 12 14:25:36 2002") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - : (ReferenceObject - :Name (Yahoo_Messenger_messages) - :Table (services) - :Uid ("{24CD3A7C-AA2C-43D4-8EB6-FF1F070143EA}") - ) - : (ReferenceObject - :Name (Yahoo_Messenger_Voice_Chat_TCP) - :Table (services) - :Uid ("{C2639E22-FD63-4520-99F7-A70215B95874}") - ) - : (ReferenceObject - :Name (Yahoo_Messenger_Voice_Chat_UDP) - :Table (services) - :Uid ("{C98BB09A-B04F-437C-AD1A-6C8261831B87}") - ) - : (ReferenceObject - :Name (Yahoo_Messenger_Webcams) - :Table (services) - :Uid ("{910F509F-8F2A-452D-BC15-E51F8CC1694C}") - ) - :color (blue) - :comments ("Yahoo Messenger") - :etm_enabled (false) - :member_class (service) - :members_query () - :type (group) - ) - : (Messenger_Applications - :AdminInfo ( - :chkpf_uid ("{CD7C1A5F-6268-40B6-A8C7-2727B8036CB1}") - :ClassName (service_group) - :table (services) - :Wiznum (-1) - :LastModified ( - :Time ("Thu Dec 12 14:28:17 2002") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - : (ReferenceObject - :Name (AOL_Messenger) - :Table (services) - :Uid ("{2C970C2B-84A3-40B5-AB0E-83244DD47BCD}") - ) - : (ReferenceObject - :Name (MSN_Messenger) - :Table (services) - :Uid ("{5693ACA1-316D-410E-A8F3-BA5D2F97E5B7}") - ) - : (ReferenceObject - :Name (Yahoo_Messenger) - :Table (services) - :Uid ("{8E3ED837-81C6-43EF-BADA-7C330C57D891}") - ) - :color (black) - :comments () - :etm_enabled (false) - :member_class (service) - :members_query () - :type (group) - ) - : (Direct_Connect - :AdminInfo ( - :chkpf_uid ("{5CFC76C2-B743-4B68-9FBF-E901EAA3698D}") - :ClassName (service_group) - :table (services) - :Wiznum (-1) - :LastModified ( - :Time ("Thu Dec 12 14:29:23 2002") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - : (ReferenceObject - :Name (Direct_Connect_TCP) - :Table (services) - :Uid ("{D02080C1-B225-4DA0-987B-28B3A551B8C9}") - ) - : (ReferenceObject - :Name (Direct_Connect_UDP) - :Table (services) - :Uid ("{64C3AD3F-69D2-4EC1-B843-5DF030C70ABF}") - ) - :color (black) - :comments ("Direct Connect P2P application. Used also by other clients") - :etm_enabled (false) - :member_class (service) - :members_query () - :type (group) - ) - : (eDonkey - :AdminInfo ( - :chkpf_uid ("{42929FB0-C8DD-465E-BE01-3E484F4299F6}") - :ClassName (service_group) - :table (services) - :Wiznum (-1) - :LastModified ( - :Time ("Thu Dec 12 14:33:32 2002") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - : (ReferenceObject - :Name (eDonkey_4661) - :Table (services) - :Uid ("{760D9035-1C76-4C5C-B929-BA1DC6685D6F}") - ) - : (ReferenceObject - :Name (eDonkey_4662) - :Table (services) - :Uid ("{7115E261-185C-4487-AA18-84F8C275D186}") - ) - : (ReferenceObject - :Name (eDonkey_4665) - :Table (services) - :Uid ("{D3CAA92A-1032-41AE-A1A1-2274F3AB9F45}") - ) - :color (black) - :comments ("eDonkey protocol. Used also by other clients.") - :etm_enabled (false) - :member_class (service) - :members_query () - :type (group) - ) - : (GNUtella - :AdminInfo ( - :chkpf_uid ("{F0059B62-E18E-478F-A3BD-18595D53D3E1}") - :ClassName (service_group) - :table (services) - :Wiznum (-1) - :LastModified ( - :Time ("Thu Dec 12 14:35:10 2002") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - : (ReferenceObject - :Name (GNUtella_rtr_TCP) - :Table (services) - :Uid ("{B1189907-B9EB-4A21-8B38-1D3E5C6C06D0}") - ) - : (ReferenceObject - :Name (GNUtella_rtr_UDP) - :Table (services) - :Uid ("{1B4543A3-579E-4CC7-8F57-4387C37A6815}") - ) - : (ReferenceObject - :Name (GNUtella_TCP) - :Table (services) - :Uid ("{CDEF1FEB-485E-4929-942E-011DE8318E56}") - ) - : (ReferenceObject - :Name (GNUtella_UDP) - :Table (services) - :Uid ("{8EB18480-2690-4520-AE88-412BF5CE94E3}") - ) - :color (black) - :comments ("GNUtella P2P protocol (used by: BearShare, ToadNode, Gnucleus, Xolox, LimeWire)") - :etm_enabled (false) - :member_class (service) - :members_query () - :type (group) - ) - : (Hotline - :AdminInfo ( - :chkpf_uid ("{4C3E148F-BCC4-4C97-9955-09DA850FB9A6}") - :ClassName (service_group) - :table (services) - :Wiznum (-1) - :LastModified ( - :Time ("Thu Dec 12 14:37:42 2002") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - : (ReferenceObject - :Name (Hotline_client) - :Table (services) - :Uid ("{B45556D9-5E0B-46F4-9C35-ED7D82BEC43D}") - ) - : (ReferenceObject - :Name (Hotline_tracker) - :Table (services) - :Uid ("{D6B64DF2-4803-4D79-9794-793D18B277D8}") - ) - :color (black) - :comments ("Hotline P2P protocol") - :etm_enabled (false) - :member_class (service) - :members_query () - :type (group) - ) - : (DAIP_Control_services - :AdminInfo ( - :chkpf_uid ("{77C21EA4-9DB4-40FE-86E0-58252C3759D8}") - :ClassName (service_group) - :table (services) - :Wiznum (-1) - :LastModified ( - :Time ("Thu Apr 03 09:38:32 2003") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - : (ReferenceObject - :Name (CPD) - :Table (services) - :Uid ("{97AEB3AB-9AEA-11D5-BD16-0090272CCB30}") - ) - : (ReferenceObject - :Name (FW1) - :Table (services) - :Uid ("{97AEB388-9AEA-11D5-BD16-0090272CCB30}") - ) - : (ReferenceObject - :Name (FW1_ica_pull) - :Table (services) - :Uid ("{97AEB3A4-9AEA-11D5-BD16-0090272CCB30}") - ) - : (ReferenceObject - :Name (FW1_log) - :Table (services) - :Uid ("{97AEB389-9AEA-11D5-BD16-0090272CCB30}") - ) - :color (black) - :comments () - :etm_enabled (false) - :member_class (service) - :members_query () - :type (group) - ) - : (Napster - :AdminInfo ( - :chkpf_uid ("{5EE3CA5B-35A2-4988-859C-7157E8CFFEAD}") - :ClassName (service_group) - :table (services) - :Wiznum (-1) - :LastModified ( - :Time ("Thu Dec 12 14:38:38 2002") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - : (ReferenceObject - :Name (Napster_Client_6600-6699) - :Table (services) - :Uid ("{3BB26988-E0A5-45D6-8018-D4D4DE8B96FA}") - ) - : (ReferenceObject - :Name (Napster_directory_4444) - :Table (services) - :Uid ("{741A5B0E-3788-4284-91A1-819E99D9ED96}") - ) - : (ReferenceObject - :Name (Napster_directory_5555) - :Table (services) - :Uid ("{8287D6D8-3B6B-4824-8F2D-18BC570EC9B2}") - ) - : (ReferenceObject - :Name (Napster_directory_6666) - :Table (services) - :Uid ("{1EF8FC95-FF10-414B-AF76-C0BCC2CD711E}") - ) - : (ReferenceObject - :Name (Napster_directory_7777) - :Table (services) - :Uid ("{182B1D39-54B6-4E2F-BAE8-2D8021D52206}") - ) - : (ReferenceObject - :Name (Napster_directory_8888_primary) - :Table (services) - :Uid ("{BE51561E-7876-4C70-9546-0914AE737F6E}") - ) - : (ReferenceObject - :Name (Napster_redirector) - :Table (services) - :Uid ("{3FD0D58A-9759-4686-B103-D177ADFC7193}") - ) - :color (black) - :comments ("Napster P2P protocol") - :etm_enabled (false) - :member_class (service) - :members_query () - :type (group) - ) - : (CIFS - :AdminInfo ( - :chkpf_uid ("{2A469820-B502-434C-9340-A377677A6A60}") - :ClassName (service_group) - :table (services) - :LastModified ( - :Time ("Wed Jun 12 12:11:06 2002") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - : (ReferenceObject - :Name (microsoft-ds) - :Table (services) - :Uid ("{CFBCACE4-7C6F-11D6-BF0E-3E5A6FE83232}") - ) - : (ReferenceObject - :Name (NBT) - :Table (services) - :Uid ("{97AEB471-9AEA-11D5-BD16-0090272CCB30}") - ) - :color (black) - :comments ("Common Internet File System Services") - :etm_enabled (false) - :member_class (service) - :members_query () - :type (group) - ) - : (FW1_clntauth - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:07 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB38D-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (service_group) - :table (services) - :name (FW1_clntauth) - ) - : (ReferenceObject - :Name (FW1_clntauth_telnet) - :Table (services) - :Uid ("{97AEB38B-9AEA-11D5-BD16-0090272CCB30}") - ) - : (ReferenceObject - :Name (FW1_clntauth_http) - :Table (services) - :Uid ("{97AEB38C-9AEA-11D5-BD16-0090272CCB30}") - ) - :color (FireBrick) - :comments ("Check Point VPN-1 & FireWall-1 Client Authentication") - :etm_enabled (false) - :member_class (service) - :members_query () - :type (group) - ) - : (sqlnet2 - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:07 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB3F2-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (service_group) - :table (services) - :name (sqlnet2) - ) - : (ReferenceObject - :Name (sqlnet2-1521) - :Table (services) - :Uid ("{97AEB3EF-9AEA-11D5-BD16-0090272CCB30}") - ) - : (ReferenceObject - :Name (sqlnet2-1525) - :Table (services) - :Uid ("{97AEB3F0-9AEA-11D5-BD16-0090272CCB30}") - ) - : (ReferenceObject - :Name (sqlnet2-1526) - :Table (services) - :Uid ("{97AEB3F1-9AEA-11D5-BD16-0090272CCB30}") - ) - :color (Foreground) - :comments ("Oracle SQL*Net Version 2 Services") - :etm_enabled (false) - :member_class (service) - :members_query () - :type (group) - ) - : (FreeTel-outgoing - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:07 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB3F5-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (service_group) - :table (services) - :name (FreeTel-outgoing) - ) - : (ReferenceObject - :Name (FreeTel-outgoing-server) - :Table (services) - :Uid ("{97AEB3F3-9AEA-11D5-BD16-0090272CCB30}") - ) - : (ReferenceObject - :Name (FreeTel-outgoing-client) - :Table (services) - :Uid ("{97AEB3F4-9AEA-11D5-BD16-0090272CCB30}") - ) - :color (Foreground) - :comments ("FreeTel Outgoing Connections") - :etm_enabled (false) - :member_class (service) - :members_query () - :type (group) - ) - : (icmp-requests - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB413-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (service_group) - :table (services) - :name (icmp-requests) - ) - : (ReferenceObject - :Name (echo-request) - :Table (services) - :Uid ("{97AEB40A-9AEA-11D5-BD16-0090272CCB30}") - ) - : (ReferenceObject - :Name (info-req) - :Table (services) - :Uid ("{97AEB40F-9AEA-11D5-BD16-0090272CCB30}") - ) - : (ReferenceObject - :Name (timestamp) - :Table (services) - :Uid ("{97AEB40D-9AEA-11D5-BD16-0090272CCB30}") - ) - : (ReferenceObject - :Name (mask-request) - :Table (services) - :Uid ("{97AEB411-9AEA-11D5-BD16-0090272CCB30}") - ) - :color ("Dark Orchid") - :comments ("ICMP, requests group") - :etm_enabled (false) - :member_class (service) - :members_query () - :type (group) - ) - : (Orbix - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB42C-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (service_group) - :table (services) - :name (Orbix) - ) - : (ReferenceObject - :Name (Orbix-1570) - :Table (services) - :Uid ("{97AEB42A-9AEA-11D5-BD16-0090272CCB30}") - ) - : (ReferenceObject - :Name (Orbix-1571) - :Table (services) - :Uid ("{97AEB42B-9AEA-11D5-BD16-0090272CCB30}") - ) - :color (black) - :comments ("IONA Orbix Daemon (IIOP)") - :etm_enabled (false) - :member_class (service) - :members_query () - :type (group) - ) - : (OAS - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB42F-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (service_group) - :table (services) - :name (OAS) - ) - : (ReferenceObject - :Name (OAS-NameServer) - :Table (services) - :Uid ("{97AEB42D-9AEA-11D5-BD16-0090272CCB30}") - ) - : (ReferenceObject - :Name (OAS-ORB) - :Table (services) - :Uid ("{97AEB42E-9AEA-11D5-BD16-0090272CCB30}") - ) - :color (black) - :comments ("Oracle Application Server (IIOP)") - :etm_enabled (false) - :member_class (service) - :members_query () - :type (group) - ) - : (StoneBeat - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB43A-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (service_group) - :table (services) - :name (StoneBeat) - ) - : (ReferenceObject - :Name (StoneBeat-Control) - :Table (services) - :Uid ("{97AEB438-9AEA-11D5-BD16-0090272CCB30}") - ) - : (ReferenceObject - :Name (StoneBeat-Daemon) - :Table (services) - :Uid ("{97AEB439-9AEA-11D5-BD16-0090272CCB30}") - ) - : (ReferenceObject - :Name (snmp) - :Table (services) - :Uid ("{97AEB3B2-9AEA-11D5-BD16-0090272CCB30}") - ) - :color (Black) - :comments ("Stonesoft StoneBeat") - :etm_enabled (false) - :member_class (service) - :members_query () - :type (group) - ) - : (RealPlayer - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB43C-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (service_group) - :table (services) - :name (RealPlayer) - ) - : (ReferenceObject - :Name (Real-Audio) - :Table (services) - :Uid ("{97AEB41B-9AEA-11D5-BD16-0090272CCB30}") - ) - : (ReferenceObject - :Name (rtsp) - :Table (services) - :Uid ("{97AEB41C-9AEA-11D5-BD16-0090272CCB30}") - ) - :color (Blue) - :comments ("RealNetworks RealPlayer Services") - :etm_enabled (false) - :member_class (service) - :members_query () - :type (group) - ) - : (NetMeeting - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB43D-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (service_group) - :table (services) - :name (NetMeeting) - ) - : (ReferenceObject - :Name (H323) - :Table (services) - :Uid ("{97AEB427-9AEA-11D5-BD16-0090272CCB30}") - ) - : (ReferenceObject - :Name (ldap) - :Table (services) - :Uid ("{97AEB433-9AEA-11D5-BD16-0090272CCB30}") - ) - :color ("Dark Green") - :comments ("Netmeeting group (H323 & Ldap)") - :etm_enabled (true) - :member_class (service) - :members_query () - :type (group) - ) - : (pcANYWHERE - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB440-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (service_group) - :table (services) - :name (pcANYWHERE) - ) - : (ReferenceObject - :Name (pcANYWHERE-data) - :Table (services) - :Uid ("{97AEB43E-9AEA-11D5-BD16-0090272CCB30}") - ) - : (ReferenceObject - :Name (pcANYWHERE-stat) - :Table (services) - :Uid ("{97AEB43F-9AEA-11D5-BD16-0090272CCB30}") - ) - :color (Blue) - :comments ("Symantec pcANYWHERE") - :etm_enabled (false) - :member_class (service) - :members_query () - :type (group) - ) - : (pcTELECOMMUTE - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB442-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (service_group) - :table (services) - :name (pcTELECOMMUTE) - ) - : (ReferenceObject - :Name (pcANYWHERE) - :Table (services) - :Uid ("{97AEB440-9AEA-11D5-BD16-0090272CCB30}") - ) - : (ReferenceObject - :Name (pcTELECOMMUTE-FileSync) - :Table (services) - :Uid ("{97AEB441-9AEA-11D5-BD16-0090272CCB30}") - ) - :color (Blue) - :comments ("Symantec pcTELECOMMUTE") - :etm_enabled (false) - :member_class (service) - :members_query () - :type (group) - ) - : (MSExchange - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB45C-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (service_group) - :table (services) - :name (MSExchange) - ) - : (ReferenceObject - :Name (MSExchangeDSNSPI) - :Table (services) - :Uid ("{97AEB452-9AEA-11D5-BD16-0090272CCB30}") - ) - : (ReferenceObject - :Name (MSExchangeIS) - :Table (services) - :Uid ("{97AEB455-9AEA-11D5-BD16-0090272CCB30}") - ) - : (ReferenceObject - :Name (MSExchangeDirRef) - :Table (services) - :Uid ("{01693eed-3f81-44d3-b498-51696722cc32}") - ) - :color (Blue) - :comments ("Microsoft Exchange Client-Server over MAPI") - :etm_enabled (false) - :member_class (service) - :members_query () - :type (group) - ) - : (MSExchange-SiteConnector - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB45D-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (service_group) - :table (services) - :name (MSExchange-SiteConnector) - ) - : (ReferenceObject - :Name (MSExchangeDSNSPI) - :Table (services) - :Uid ("{97AEB452-9AEA-11D5-BD16-0090272CCB30}") - ) - : (ReferenceObject - :Name (MSExchangeDSRep) - :Table (services) - :Uid ("{97AEB453-9AEA-11D5-BD16-0090272CCB30}") - ) - : (ReferenceObject - :Name (MSExchangeMTA) - :Table (services) - :Uid ("{97AEB456-9AEA-11D5-BD16-0090272CCB30}") - ) - :color (Blue) - :comments ("Microsoft Exchange MAPI Site Connector") - :etm_enabled (false) - :member_class (service) - :members_query () - :type (group) - ) - : (MSExchange-RemoteAdmin - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB45E-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (service_group) - :table (services) - :name (MSExchange-RemoteAdmin) - ) - : (ReferenceObject - :Name (MSExchangeDSXDS) - :Table (services) - :Uid ("{97AEB454-9AEA-11D5-BD16-0090272CCB30}") - ) - : (ReferenceObject - :Name (MSExchangeSysAtt) - :Table (services) - :Uid ("{97AEB459-9AEA-11D5-BD16-0090272CCB30}") - ) - : (ReferenceObject - :Name (MSExchangeSysAttPriv) - :Table (services) - :Uid ("{97AEB45A-9AEA-11D5-BD16-0090272CCB30}") - ) - : (ReferenceObject - :Name (MSExchangeStoreAdm) - :Table (services) - :Uid ("{97AEB45B-9AEA-11D5-BD16-0090272CCB30}") - ) - :color (Blue) - :comments ("Microsoft Exchange Remote Administration") - :etm_enabled (false) - :member_class (service) - :members_query () - :type (group) - ) - : (MSExchange-2000 - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB45F-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (service_group) - :table (services) - :name (MSExchange-2000) - ) - : (ReferenceObject - :Name (MSExchangeADL) - :Table (services) - :Uid ("{97AEB457-9AEA-11D5-BD16-0090272CCB30}") - ) - : (ReferenceObject - :Name (MSExchangeDirRep) - :Table (services) - :Uid ("{97AEB458-9AEA-11D5-BD16-0090272CCB30}") - ) - : (ReferenceObject - :Name (MSExchangeDirRef) - :Table (services) - :Uid ("{01693eed-3f81-44d3-b498-51696722cc32}") - ) - :color (Blue) - :comments ("Microsoft Exchange 2000 Extensions") - :etm_enabled (false) - :member_class (service) - :members_query () - :type (group) - ) - : (securid - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB467-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (service_group) - :table (services) - :name (securid) - ) - : (ReferenceObject - :Name (securid-udp) - :Table (services) - :Uid ("{97AEB3EC-9AEA-11D5-BD16-0090272CCB30}") - ) - : (ReferenceObject - :Name (securidprop) - :Table (services) - :Uid ("{97AEB3ED-9AEA-11D5-BD16-0090272CCB30}") - ) - :color (FireBrick) - :comments ("Secure ID group") - :etm_enabled (false) - :member_class (service) - :members_query () - :type (group) - ) - : (Authenticated - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB468-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (service_group) - :table (services) - :name (Authenticated) - ) - : (ReferenceObject - :Name (telnet) - :Table (services) - :Uid ("{97AEB3CF-9AEA-11D5-BD16-0090272CCB30}") - ) - : (ReferenceObject - :Name (ftp) - :Table (services) - :Uid ("{97AEB3D0-9AEA-11D5-BD16-0090272CCB30}") - ) - : (ReferenceObject - :Name (http) - :Table (services) - :Uid ("{97AEB3D4-9AEA-11D5-BD16-0090272CCB30}") - ) - : (ReferenceObject - :Name (login) - :Table (services) - :Uid ("{97AEB3BE-9AEA-11D5-BD16-0090272CCB30}") - ) - :color ("Forest Green") - :comments ("Authenticated group") - :etm_enabled (false) - :member_class (service) - :members_query () - :type (group) - ) - : (mosaic - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB469-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (service_group) - :table (services) - :name (mosaic) - ) - : (ReferenceObject - :Name (http) - :Table (services) - :Uid ("{97AEB3D4-9AEA-11D5-BD16-0090272CCB30}") - ) - : (ReferenceObject - :Name (gopher) - :Table (services) - :Uid ("{97AEB3D5-9AEA-11D5-BD16-0090272CCB30}") - ) - : (ReferenceObject - :Name (ftp) - :Table (services) - :Uid ("{97AEB3D0-9AEA-11D5-BD16-0090272CCB30}") - ) - : (ReferenceObject - :Name (archie) - :Table (services) - :Uid ("{97AEB3D6-9AEA-11D5-BD16-0090272CCB30}") - ) - :color ("Forest Green") - :comments ("Mosaic group") - :etm_enabled (false) - :member_class (service) - :members_query () - :type (group) - ) - : (echo - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB46A-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (service_group) - :table (services) - :name (echo) - ) - : (ReferenceObject - :Name (echo-tcp) - :Table (services) - :Uid ("{97AEB3F7-9AEA-11D5-BD16-0090272CCB30}") - ) - : (ReferenceObject - :Name (echo-udp) - :Table (services) - :Uid ("{97AEB3F8-9AEA-11D5-BD16-0090272CCB30}") - ) - :color (Black) - :comments ("Echo Protocol group (TCP/UDP)") - :etm_enabled (false) - :member_class (service) - :members_query () - :type (group) - ) - : (dns - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB46B-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (service_group) - :table (services) - :name (dns) - ) - : (ReferenceObject - :Name (domain-tcp) - :Table (services) - :Uid ("{97AEB3F9-9AEA-11D5-BD16-0090272CCB30}") - ) - : (ReferenceObject - :Name (domain-udp) - :Table (services) - :Uid ("{97AEB3FA-9AEA-11D5-BD16-0090272CCB30}") - ) - :color (Black) - :comments ("Domain Name System (TCP/UDP)") - :etm_enabled (false) - :member_class (service) - :members_query () - :type (group) - ) - : (kerberos - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB46C-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (service_group) - :table (services) - :name (kerberos) - ) - : (ReferenceObject - :Name (kerberos-tcp) - :Table (services) - :Uid ("{97AEB3FB-9AEA-11D5-BD16-0090272CCB30}") - ) - : (ReferenceObject - :Name (kerberos-udp) - :Table (services) - :Uid ("{97AEB3FC-9AEA-11D5-BD16-0090272CCB30}") - ) - :color (Black) - :comments ("Kerberos Protocol group (TCP/UDP)") - :etm_enabled (false) - :member_class (service) - :members_query () - :type (group) - ) - : (discard - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB46D-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (service_group) - :table (services) - :name (discard) - ) - : (ReferenceObject - :Name (discard-tcp) - :Table (services) - :Uid ("{97AEB3FD-9AEA-11D5-BD16-0090272CCB30}") - ) - : (ReferenceObject - :Name (discard-udp) - :Table (services) - :Uid ("{97AEB3FE-9AEA-11D5-BD16-0090272CCB30}") - ) - :color (Black) - :comments ("Discard Protocol group (TCP/UDP)") - :etm_enabled (false) - :member_class (service) - :members_query () - :type (group) - ) - : (time - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB46E-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (service_group) - :table (services) - :name (time) - ) - : (ReferenceObject - :Name (time-tcp) - :Table (services) - :Uid ("{97AEB3FF-9AEA-11D5-BD16-0090272CCB30}") - ) - : (ReferenceObject - :Name (time-udp) - :Table (services) - :Uid ("{97AEB400-9AEA-11D5-BD16-0090272CCB30}") - ) - :color (Black) - :comments ("Time Server Protocol") - :etm_enabled (false) - :member_class (service) - :members_query () - :type (group) - ) - : (daytime - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB46F-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (service_group) - :table (services) - :name (daytime) - ) - : (ReferenceObject - :Name (daytime-tcp) - :Table (services) - :Uid ("{97AEB401-9AEA-11D5-BD16-0090272CCB30}") - ) - : (ReferenceObject - :Name (daytime-udp) - :Table (services) - :Uid ("{97AEB402-9AEA-11D5-BD16-0090272CCB30}") - ) - :color (Black) - :comments ("Daytime Protocol group (TCP/UDP)") - :etm_enabled (false) - :member_class (service) - :members_query () - :type (group) - ) - : (ntp - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB470-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (service_group) - :table (services) - :name (ntp) - ) - : (ReferenceObject - :Name (ntp-tcp) - :Table (services) - :Uid ("{97AEB403-9AEA-11D5-BD16-0090272CCB30}") - ) - : (ReferenceObject - :Name (ntp-udp) - :Table (services) - :Uid ("{97AEB404-9AEA-11D5-BD16-0090272CCB30}") - ) - :color (Black) - :comments ("Network Time Protocol group (TCP/UDP)") - :etm_enabled (false) - :member_class (service) - :members_query () - :type (group) - ) - : (NBT - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB471-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (service_group) - :table (services) - :name (NBT) - ) - : (ReferenceObject - :Name (nbname) - :Table (services) - :Uid ("{97AEB414-9AEA-11D5-BD16-0090272CCB30}") - ) - : (ReferenceObject - :Name (nbdatagram) - :Table (services) - :Uid ("{97AEB415-9AEA-11D5-BD16-0090272CCB30}") - ) - : (ReferenceObject - :Name (nbsession) - :Table (services) - :Uid ("{97AEB416-9AEA-11D5-BD16-0090272CCB30}") - ) - :color (Magenta) - :comments ("NetBios Services") - :etm_enabled (false) - :member_class (service) - :members_query () - :type (Group) - ) - : (NIS - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB472-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (service_group) - :table (services) - :name (NIS) - ) - : (ReferenceObject - :Name (ypbind) - :Table (services) - :Uid ("{97AEB3C2-9AEA-11D5-BD16-0090272CCB30}") - ) - : (ReferenceObject - :Name (yppasswd) - :Table (services) - :Uid ("{97AEB3C3-9AEA-11D5-BD16-0090272CCB30}") - ) - : (ReferenceObject - :Name (ypserv) - :Table (services) - :Uid ("{97AEB3C1-9AEA-11D5-BD16-0090272CCB30}") - ) - : (ReferenceObject - :Name (ypupdated) - :Table (services) - :Uid ("{97AEB3C4-9AEA-11D5-BD16-0090272CCB30}") - ) - : (ReferenceObject - :Name (ypxfrd) - :Table (services) - :Uid ("{97AEB3C5-9AEA-11D5-BD16-0090272CCB30}") - ) - :color ("Navy Blue") - :comments ("Network Information Services (YP)") - :etm_enabled (false) - :member_class (service) - :members_query () - :type (Group) - ) - : (NFS - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB473-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (service_group) - :table (services) - :name (NFS) - ) - : (ReferenceObject - :Name (mountd) - :Table (services) - :Uid ("{97AEB3BA-9AEA-11D5-BD16-0090272CCB30}") - ) - : (ReferenceObject - :Name (nfsd) - :Table (services) - :Uid ("{97AEB3B8-9AEA-11D5-BD16-0090272CCB30}") - ) - : (ReferenceObject - :Name (nfsd-tcp) - :Table (services) - :Uid ("{97AEB3B9-9AEA-11D5-BD16-0090272CCB30}") - ) - : (ReferenceObject - :Name (nfsprog) - :Table (services) - :Uid ("{97AEB3B7-9AEA-11D5-BD16-0090272CCB30}") - ) - : (ReferenceObject - :Name (nlockmgr) - :Table (services) - :Uid ("{97AEB3BC-9AEA-11D5-BD16-0090272CCB30}") - ) - : (ReferenceObject - :Name (pcnfsd) - :Table (services) - :Uid ("{97AEB3BB-9AEA-11D5-BD16-0090272CCB30}") - ) - :color (Red) - :comments ("Network File System Services") - :etm_enabled (false) - :member_class (service) - :members_query () - :type (Group) - ) - : (irc - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB474-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (service_group) - :table (services) - :name (irc) - ) - : (ReferenceObject - :Name (irc1) - :Table (services) - :Uid ("{97AEB417-9AEA-11D5-BD16-0090272CCB30}") - ) - : (ReferenceObject - :Name (irc2) - :Table (services) - :Uid ("{97AEB418-9AEA-11D5-BD16-0090272CCB30}") - ) - :color (Black) - :comments ("Internet Relay Chat Protocol") - :etm_enabled (false) - :member_class (service) - :members_query () - :type (Group) - ) - : (IPSEC - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB475-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (service_group) - :table (services) - :name (IPSEC) - ) - : (ReferenceObject - :Name (AH) - :Table (services) - :Uid ("{97AEB422-9AEA-11D5-BD16-0090272CCB30}") - ) - : (ReferenceObject - :Name (ESP) - :Table (services) - :Uid ("{97AEB423-9AEA-11D5-BD16-0090272CCB30}") - ) - : (ReferenceObject - :Name (SKIP) - :Table (services) - :Uid ("{97AEB421-9AEA-11D5-BD16-0090272CCB30}") - ) - : (ReferenceObject - :Name (IKE) - :Table (services) - :Uid ("{97AEB3B0-9AEA-11D5-BD16-0090272CCB30}") - ) - :color (Cyan) - :comments ("IPSEC Services") - :etm_enabled (false) - :member_class (service) - :members_query () - :type (group) - ) - : (Entrust-CA - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB476-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (service_group) - :table (services) - :name (Entrust-CA) - ) - : (ReferenceObject - :Name (Entrust-Admin) - :Table (services) - :Uid ("{97AEB435-9AEA-11D5-BD16-0090272CCB30}") - ) - : (ReferenceObject - :Name (Entrust-KeyMgmt) - :Table (services) - :Uid ("{97AEB436-9AEA-11D5-BD16-0090272CCB30}") - ) - :color (FireBrick) - :comments ("Entrust CA Services") - :etm_enabled (false) - :member_class (service) - :members_query () - :type (Group) - ) - : (RainWall-Control - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By (CheckPoint) - :From (CheckPoint) - ) - :chkpf_uid ("{04ECA4D1-E4B7-4EC3-A86F-9BB56765519E}") - :ClassName (service_group) - :table (services) - :name (RainWall-Control) - ) - : (ReferenceObject - :Name (RainWall_Command) - :Table (services) - :Uid ("{B9BBEEBA-B639-41A3-97D5-1F9D982D7E44}") - ) - : (ReferenceObject - :Name (RainWall_Daemon) - :Table (services) - :Uid ("{21CC3F85-E6DF-443D-9846-BD39BD015B85}") - ) - : (ReferenceObject - :Name (RainWall_Status) - :Table (services) - :Uid ("{4FBD29C5-06DB-4912-B23D-1BD50D693185}") - ) - :color (black) - :comments ("RainWall higu availability") - :etm_enabled (false) - :member_class (service) - :members_query () - :type (group) - ) - : (ICMPgute - :AdminInfo ( - :chkpf_uid ("{418C7C0A-956A-41FF-9BC1-5867B2265090}") - :ClassName (service_group) - :table (services) - :Wiznum (-1) - :LastModified ( - :Time ("Tue Mar 4 15:28:05 2003") - :By (tim) - :From (STICHLING) - ) - ) - : (ReferenceObject - :Name (dest-unreach) - :Table (services) - :Uid ("{97AEB407-9AEA-11D5-BD16-0090272CCB30}") - ) - : (ReferenceObject - :Name (echo-reply) - :Table (services) - :Uid ("{97AEB406-9AEA-11D5-BD16-0090272CCB30}") - ) - : (ReferenceObject - :Name (echo-request) - :Table (services) - :Uid ("{97AEB40A-9AEA-11D5-BD16-0090272CCB30}") - ) - : (ReferenceObject - :Name (time-exceeded) - :Table (services) - :Uid ("{97AEB40B-9AEA-11D5-BD16-0090272CCB30}") - ) - :color (black) - :comments () - :etm_enabled (false) - :member_class (service) - :members_query () - :type (group) - ) - : (gtp_v0_default - :AdminInfo ( - :chkpf_uid ("{D9531700-F8BB-4E3B-983D-10D69906A028}") - :ClassName (gtp_service) - :object_permissions ( - :AdminInfo ( - :chkpf_uid ("{B0160177-1F41-4B9F-803B-B58D93988C24}") - :ClassName (object_permissions) - ) - :manage ( - : (ReferenceObject - :Table (globals) - :Name (Any) - ) - ) - :read ( - : (any) - ) - :use ( - : (any) - ) - :write ( - : () - ) - :owner () - ) - :table (services) - :Deleteable (false) - :Wiznum (-1) - :LastModified ( - :Time ("Wed Aug 14 12:20:51 2002") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :apn_obj () - :reload_proof (false) - :weight (100) - :apn_any (true) - :color ("forest green") - :comments ("GPRS Tunneling Protocol version 0") - :data_packet (true) - :etm_enabled (false) - :imsi () - :imsi_any (true) - :include_in_any (false) - :ms_isdn (1) - :ms_isdn_any (true) - :port (3386) - :proto_type () - :sel_mode (0) - :sel_mode_any (false) - :signaling_packet (true) - :static_eua (false) - :timeout (600) - :type (gtp) - ) - : (gtp_v1_default - :AdminInfo ( - :chkpf_uid ("{AFF26F18-B9B0-4E7C-BC4D-D6749E0487B2}") - :ClassName (gtp_v1_service) - :table (services) - :Deleteable (false) - :Wiznum (-1) - :object_permissions ( - :AdminInfo ( - :chkpf_uid ("{E61F7C69-C165-4A73-ACCC-E2A7A6F69500}") - :ClassName (object_permissions) - ) - :manage ( - : (ReferenceObject - :Table (globals) - :Name (Any) - ) - ) - :read ( - : (any) - ) - :use ( - : (any) - ) - :write ( - : () - ) - :owner () - ) - :LastModified ( - :Time ("Wed Aug 14 12:44:28 2002") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :apn_obj () - :reload_proof (false) - :weight (100) - :apn_any (true) - :color ("forest green") - :comments ("GPRS Tunneling Protocol version 1") - :control_port (2123) - :data_packet (true) - :etm_enabled (false) - :imsi () - :imsi_any (true) - :include_in_any (false) - :ms_isdn (1) - :ms_isdn_any (true) - :proto_type () - :sel_mode (0) - :sel_mode_any (false) - :signaling_packet (true) - :static_eua (false) - :timeout (600) - :type (gtp_v1) - :user_port (2152) - ) - : (gtp_v0_path_mgmt - :AdminInfo ( - :chkpf_uid ("{35029B62-16B1-4D34-8004-410710DFD492}") - :ClassName (other_service) - :table (services) - :Wiznum (-1) - :object_permissions ( - :AdminInfo ( - :chkpf_uid ("{6B50E6B6-7FA8-42DB-AEB6-45C57EB6DA39}") - :ClassName (object_permissions) - ) - :manage ( - : (ReferenceObject - :Table (globals) - :Name (Any) - ) - ) - :read ( - : (any) - ) - :use ( - : (any) - ) - :write ( - : () - ) - :owner () - ) - :LastModified ( - :Time ("Wed Aug 14 16:33:40 2002") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :reload_proof (false) - :color ("forest green") - :comments ("GTP version 0 path management") - :etm_enabled (false) - :exp (gtp_path_match_v0) - :include_in_any (true) - :needruleinfo (false) - :proto_type () - :protocol (17) - :replies (true) - :sync_on_cluster (true) - :timeout (0) - :type (Other) - :weight (0) - ) - : (gtp_v1_path_mgmt - :AdminInfo ( - :chkpf_uid ("{6106FFDD-A8FE-4B2E-8270-CB3435217427}") - :ClassName (other_service) - :object_permissions ( - :AdminInfo ( - :chkpf_uid ("{DA40F0A4-D596-4339-B84D-1AF50B0BDD13}") - :ClassName (object_permissions) - ) - :manage ( - : (ReferenceObject - :Table (globals) - :Name (Any) - ) - ) - :read ( - : (any) - ) - :use ( - : (any) - ) - :write ( - : () - ) - :owner () - ) - :table (services) - :Wiznum (-1) - :LastModified ( - :Time ("Wed Aug 14 16:19:19 2002") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :reload_proof (false) - :color ("forest green") - :comments ("GTP version 1 path management") - :etm_enabled (false) - :exp (gtp_path_match_v1) - :include_in_any (true) - :needruleinfo (false) - :proto_type () - :protocol (17) - :replies (true) - :sync_on_cluster (true) - :timeout (0) - :type (Other) - :weight (0) - ) - : (https - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB443-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (tcp_service) - :table (services) - :name (https) - :Deleteable (false) - :Renameable (false) - ) - :delayed_sync_value (30) - :use_delayed_sync (false) - :color (Red) - :comments ("HTTP protocol over TLS/SSL") - :enable_tcp_resource (false) - :etm_enabled (false) - :include_in_any (true) - :port (443) - :proto_type (ReferenceObject - :Table (protocols) - :Name (ENC-HTTP) - :Uid ("{8294399D-9333-4774-B3DA-C00EACEF3211}") - ) - :reload_proof (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (tcp) - ) - : (TCP_135 - :AdminInfo ( - :chkpf_uid ("{C748295C-99D9-474C-8136-7959A5A98E30}") - :ClassName (tcp_service) - :table (services) - :Wiznum (-1) - :object_permissions ( - :AdminInfo ( - :chkpf_uid ("{9E3FE282-81AB-4032-B803-8CDAB5917CC0}") - :ClassName (object_permissions) - ) - :manage ( - : (ReferenceObject - :Table (globals) - :Name (Any) - ) - ) - :read ( - : (any) - ) - :use ( - : (any) - ) - :write ( - : () - ) - :owner () - ) - :LastModified ( - :Time ("Sun Feb 16 16:51:51 2003") - :By (IsoAAAF) - :From (scratchy) - ) - :name (TCP_135) - ) - :delayed_sync_value (30) - :use_delayed_sync (false) - :color (magenta) - :comments () - :enable_tcp_resource (false) - :etm_enabled (false) - :include_in_any (true) - :port (135) - :proto_type () - :reload_proof (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (Tcp) - ) - : (ldap-udp - :AdminInfo ( - :chkpf_uid ("{DE59BD94-9610-4C6C-B667-97B79EB2EBAA}") - :ClassName (udp_service) - :table (services) - :Wiznum (-1) - :object_permissions ( - :AdminInfo ( - :chkpf_uid ("{8C4728BD-72A1-44FF-9328-D17430D20776}") - :ClassName (object_permissions) - ) - :manage ( - : (ReferenceObject - :Table (globals) - :Name (Any) - ) - ) - :read ( - : (any) - ) - :use ( - : (any) - ) - :write ( - : () - ) - :owner () - ) - :LastModified ( - :Time ("Sun Feb 16 16:54:14 2003") - :By (IsoAAAF) - :From (scratchy) - ) - :name (ldap-udp) - ) - :delete_on_reply (false) - :color (black) - :comments () - :etm_enabled (false) - :include_in_any (true) - :port (389) - :proto_type () - :reload_proof (false) - :replies (true) - :replies_from_any_port (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (Udp) - ) - : (P2P_File_Sharing_Applications - :AdminInfo ( - :chkpf_uid ("{D138E7DA-3BF1-4D7C-AE35-D551416E8DB3}") - :ClassName (service_group) - :table (services) - :Wiznum (-1) - :LastModified ( - :Time ("Thu Dec 12 14:44:07 2002") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - : (ReferenceObject - :Name (Blubster) - :Table (services) - :Uid ("{C86F055D-31AD-4430-B12C-1094A86C673C}") - ) - : (ReferenceObject - :Name (Direct_Connect) - :Table (services) - :Uid ("{5CFC76C2-B743-4B68-9FBF-E901EAA3698D}") - ) - : (ReferenceObject - :Name (eDonkey) - :Table (services) - :Uid ("{42929FB0-C8DD-465E-BE01-3E484F4299F6}") - ) - : (ReferenceObject - :Name (GNUtella) - :Table (services) - :Uid ("{F0059B62-E18E-478F-A3BD-18595D53D3E1}") - ) - : (ReferenceObject - :Name (GoToMyPC) - :Table (services) - :Uid ("{2D89310C-5761-4213-BEF5-C81BB5677E44}") - ) - : (ReferenceObject - :Name (Hotline) - :Table (services) - :Uid ("{4C3E148F-BCC4-4C97-9955-09DA850FB9A6}") - ) - : (ReferenceObject - :Name (iMesh) - :Table (services) - :Uid ("{01E9FC32-73DF-43D5-9CD4-4F91B6A5C711}") - ) - : (ReferenceObject - :Table (services) - :Name (Kazaa) - :Uid ("{BE146201-61B2-11d6-B5E0-0002B316D24E}") - ) - : (ReferenceObject - :Name (Madster) - :Table (services) - :Uid ("{B863EC35-604F-4DA1-8E63-82A7903D2C1C}") - ) - : (ReferenceObject - :Name (Napster) - :Table (services) - :Uid ("{5EE3CA5B-35A2-4988-859C-7157E8CFFEAD}") - ) - : (ReferenceObject - :Name (WinMX) - :Table (services) - :Uid ("{6414F98E-6883-44DB-8EE2-DEBD443C7714}") - ) - :color (black) - :comments () - :etm_enabled (false) - :member_class (service) - :members_query () - :type (group) - ) - : (NEW-RADIUS - :AdminInfo ( - :chkpf_uid ("{97AEB41E-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (udp_service) - :table (services) - :Wiznum (-1) - :LastModified ( - :Time ("Thu May 6 14:03:23 2004") - :By (andre) - :From (gateway) - ) - ) - :color (firebrick) - :comments ("NEW - Remote Authentication Dial-In User Service") - :delete_on_reply (false) - :etm_enabled (false) - :include_in_any (true) - :port (1812) - :proto_type () - :reload_proof (false) - :replies (true) - :replies_from_any_port (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (Udp) - ) - : (premier_access_5010 - :AdminInfo ( - :chkpf_uid ("{A1489778-CD8C-41F2-BCC1-0C60B89C822F}") - :ClassName (tcp_service) - :table (services) - :Wiznum (-1) - :LastModified ( - :Time ("Thu May 6 14:47:35 2004") - :By (andre) - :From (gateway) - ) - ) - :etm_enabled (false) - :proto_type () - :timeout (0) - :color (black) - :comments () - :delayed_sync_value (30) - :enable_tcp_resource (false) - :include_in_any (true) - :port (5010) - :reload_proof (false) - :src_port () - :sync_on_cluster (true) - :type (Tcp) - :use_delayed_sync (false) - ) - : (premier_access_5029 - :AdminInfo ( - :chkpf_uid ("{CCF60486-D5C2-4D26-B4D6-8CFBF7BC63A5}") - :ClassName (tcp_service) - :table (services) - :Wiznum (-1) - :LastModified ( - :Time ("Thu May 6 14:50:36 2004") - :By (andre) - :From (gateway) - ) - ) - :etm_enabled (false) - :proto_type () - :sync_on_cluster (true) - :timeout (0) - :use_delayed_sync (false) - :color (blue1) - :comments () - :delayed_sync_value (30) - :enable_tcp_resource (false) - :include_in_any (true) - :port (5029) - :reload_proof (false) - :src_port () - :type (Tcp) - ) - : (premier_access_5031 - :AdminInfo ( - :chkpf_uid ("{6668A65E-65C1-4BE1-BBA7-9F18D8DE169C}") - :ClassName (tcp_service) - :table (services) - :Wiznum (-1) - :LastModified ( - :Time ("Thu May 6 14:51:15 2004") - :By (andre) - :From (gateway) - ) - ) - :etm_enabled (false) - :proto_type () - :sync_on_cluster (true) - :timeout (0) - :use_delayed_sync (false) - :color (blue1) - :comments () - :delayed_sync_value (30) - :enable_tcp_resource (false) - :include_in_any (true) - :port (5031) - :reload_proof (false) - :src_port () - :type (Tcp) - ) - : (http - :AdminInfo ( - :chkpf_uid ("{97AEB3D4-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (tcp_service) - :table (services) - :Wiznum (-1) - :LastModified ( - :Time ("Tue Jun 8 12:58:02 2004") - :By (tim) - :From (pieks) - ) - ) - :color ("forest green") - :comments ("Hypertext Transfer Protocol") - :delayed_sync_value (30) - :enable_tcp_resource (false) - :etm_enabled (false) - :include_in_any (true) - :port (80) - :proto_type (ReferenceObject - :Name (HTTP) - :Table (protocols) - :Uid ("{97AEB373-9AEA-11D5-BD16-0090272CCB30}") - ) - :reload_proof (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (Tcp) - :use_delayed_sync (false) - ) - : (mysql - :AdminInfo ( - :chkpf_uid ("{08A07607-EAAA-4A45-AD6E-6020770BD519}") - :ClassName (tcp_service) - :table (services) - :Wiznum (-1) - :LastModified ( - :Time ("Sun Aug 1 12:49:09 2004") - :By (tim) - :From (pieks) - ) - ) - :etm_enabled (false) - :proto_type () - :sync_on_cluster (true) - :timeout (0) - :use_delayed_sync (false) - :color (black) - :comments ("3306/tcp") - :delayed_sync_value (30) - :enable_tcp_resource (false) - :include_in_any (true) - :port (3306) - :reload_proof (false) - :src_port () - :type (Tcp) - ) - : (PremierAccess_udp - :AdminInfo ( - :chkpf_uid ("{0AE4AA4A-30BB-41D3-9113-3C0A41901F0E}") - :ClassName (udp_service) - :table (services) - :Wiznum (-1) - :LastModified ( - :Time ("Thu Aug 5 14:15:43 2004") - :By (andre) - :From (gateway) - ) - ) - :delete_on_reply (false) - :etm_enabled (false) - :proto_type () - :timeout (0) - :color (blue) - :comments () - :include_in_any (true) - :port (5030) - :reload_proof (false) - :replies (true) - :replies_from_any_port (true) - :src_port () - :sync_on_cluster (true) - :type (Udp) - ) - : (rdp - :AdminInfo ( - :chkpf_uid ("{5BA0C83F-8D91-465B-9CF6-7DC6AEB84689}") - :ClassName (tcp_service) - :table (services) - :Wiznum (-1) - :LastModified ( - :Time ("Wed Sep 29 20:43:11 2004") - :By (IsoAAAF) - :From (IsoAAADray) - ) - ) - :color (cyan) - :comments (rdp_new) - :delayed_sync_value (30) - :enable_tcp_resource (false) - :etm_enabled (false) - :include_in_any (true) - :port (3389) - :proto_type () - :reload_proof (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (Tcp) - :use_delayed_sync (false) - ) - : (PPTP - :AdminInfo ( - :chkpf_uid ("{97AEB426-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (service_group) - :table (services) - :Wiznum (-1) - :LastModified ( - :Time ("Thu Sep 30 07:20:55 2004") - :By (IsoAAAF) - :From (scratchy) - ) - ) - : (ReferenceObject - :Name (gre) - :Table (services) - :Uid ("{97AEB424-9AEA-11D5-BD16-0090272CCB30}") - ) - : (ReferenceObject - :Name (pptp-tcp) - :Table (services) - :Uid ("{97AEB425-9AEA-11D5-BD16-0090272CCB30}") - ) - :color (red) - :comments ("Point-to-Point Tunneling group, (pptp & gre)") - :etm_enabled (false) - :member_class (service) - :members_query () - :type (group) - ) - : (Drop_nologServices - :AdminInfo ( - :chkpf_uid ("{495E1A16-2612-49D9-8F69-B00EB33699E8}") - :ClassName (service_group) - :object_permissions ( - :AdminInfo ( - :chkpf_uid ("{61465BAC-5B02-4B46-9186-82DDFB8A898F}") - :ClassName (object_permissions) - ) - :manage ( - : (ReferenceObject - :Table (globals) - :Name (Any) - ) - ) - :read ( - : (any) - ) - :use ( - : (any) - ) - :write ( - : () - ) - :owner () - ) - :table (services) - :Wiznum (-1) - :LastModified ( - :Time ("Thu Sep 30 07:28:52 2004") - :By (IsoAAAF) - :From (scratchy) - ) - ) - : (ReferenceObject - :Name (dhcp-rep-localmodule) - :Table (services) - :Uid ("{FCA646B5-EF34-4DF1-895D-7639E181501A}") - ) - : (ReferenceObject - :Name (dhcp-req-localmodule) - :Table (services) - :Uid ("{22725520-8E10-4A91-98AC-DCD1F6C4A4DD}") - ) - : (ReferenceObject - :Name (ldap-udp) - :Table (services) - :Uid ("{DE59BD94-9610-4C6C-B667-97B79EB2EBAA}") - ) - : (ReferenceObject - :Name (nbdatagram) - :Table (services) - :Uid ("{97AEB415-9AEA-11D5-BD16-0090272CCB30}") - ) - : (ReferenceObject - :Name (nbname) - :Table (services) - :Uid ("{97AEB414-9AEA-11D5-BD16-0090272CCB30}") - ) - :color (black) - :comments () - :etm_enabled (false) - :member_class (service) - :members_query () - :type (group) - ) - : (HBCI - :AdminInfo ( - :chkpf_uid ("{336C93F8-5CC2-48BE-9328-2E92F61EFCF1}") - :ClassName (tcp_service) - :table (services) - :Wiznum (-1) - :LastModified ( - :Time ("Thu Sep 30 09:43:31 2004") - :By (IsoAAAF) - :From (scratchy) - ) - ) - :etm_enabled (false) - :proto_type () - :sync_on_cluster (true) - :timeout (0) - :use_delayed_sync (false) - :color (black) - :comments () - :delayed_sync_value (30) - :enable_tcp_resource (false) - :include_in_any (true) - :port (3000) - :reload_proof (false) - :src_port () - :type (Tcp) - ) - : (sshv2-24 - :AdminInfo ( - :chkpf_uid ("{1DA78BCE-7ABC-4DBB-82AF-FDBE6B853493}") - :ClassName (tcp_service) - :table (services) - :Wiznum (-1) - :LastModified ( - :Time ("Mon Oct 4 19:52:06 2004") - :By (IsoAAAF) - :From (IsoAAADray) - ) - ) - :etm_enabled (false) - :timeout (0) - :use_delayed_sync (false) - :color (black) - :comments ("ssh on port24") - :delayed_sync_value (30) - :enable_tcp_resource (false) - :include_in_any (true) - :port (24) - :proto_type (ReferenceObject - :Name (SSH2) - :Table (protocols) - :Uid ("{55F4C5D7-60D9-44B3-9BD4-C3F76B7C8360}") - ) - :reload_proof (false) - :src_port () - :sync_on_cluster (true) - :type (Tcp) - ) - : (irc2 - :AdminInfo ( - :chkpf_uid ("{97AEB418-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (tcp_service) - :table (services) - :Wiznum (-1) - :LastModified ( - :Time ("Thu Oct 7 13:39:51 2004") - :By (andre) - :From (Roadrunner) - ) - ) - :proto_type () - :timeout (0) - :color (black) - :comments ("Internet Relay Chat Protocol") - :delayed_sync_value (30) - :enable_tcp_resource (false) - :etm_enabled (false) - :include_in_any (false) - :port (7000) - :reload_proof (false) - :src_port () - :sync_on_cluster (true) - :type (Tcp) - :use_delayed_sync (false) - ) - : (UPS-Monitor - :AdminInfo ( - :chkpf_uid ("{8C8DED7E-F3C9-4964-B9D3-063C23997020}") - :ClassName (tcp_service) - :table (services) - :Wiznum (-1) - :LastModified ( - :Time ("Thu Oct 7 13:40:06 2004") - :By (andre) - :From (Roadrunner) - ) - ) - :proto_type () - :timeout (0) - :color (black) - :comments () - :delayed_sync_value (30) - :enable_tcp_resource (false) - :etm_enabled (false) - :include_in_any (false) - :port (7000) - :reload_proof (false) - :src_port () - :sync_on_cluster (true) - :type (Tcp) - :use_delayed_sync (false) - ) - : (VNC-neu - :AdminInfo ( - :chkpf_uid ("{00000006-735E-4158-A169-8701B9624E47}") - :ClassName (tcp_service) - :table (services) - :Wiznum (-1) - :LastModified ( - :Time ("Sat Nov 6 14:40:14 2004") - :By (IsoAAAF) - :From (IsoAAADray) - ) - ) - :etm_enabled (false) - :proto_type () - :sync_on_cluster (true) - :timeout (0) - :use_delayed_sync (false) - :color (gold) - :comments ("standard VNC") - :delayed_sync_value (30) - :enable_tcp_resource (false) - :include_in_any (true) - :port (55901) - :reload_proof (false) - :src_port () - :type (Tcp) - ) - : (VNC - :AdminInfo ( - :chkpf_uid ("{9788B566-735E-4158-A169-8701B9624E47}") - :ClassName (tcp_service) - :table (services) - :Wiznum (-1) - :LastModified ( - :Time ("Sat Nov 6 14:40:14 2004") - :By (IsoAAAF) - :From (IsoAAADray) - ) - ) - :etm_enabled (false) - :proto_type () - :sync_on_cluster (true) - :timeout (0) - :use_delayed_sync (false) - :color (gold) - :comments ("standard VNC") - :delayed_sync_value (30) - :enable_tcp_resource (false) - :include_in_any (true) - :port (5900) - :reload_proof (false) - :src_port () - :type (Tcp) - ) - : (RAdmin - :AdminInfo ( - :chkpf_uid ("{8888DA95-4E43-4F96-95FF-F5B41410BDBD}") - :ClassName (tcp_service) - :table (services) - :Wiznum (-1) - :LastModified ( - :Time ("Sun Nov 7 14:43:43 2004") - :By (IsoAAAF) - :From (IsoAAADray) - ) - ) - :etm_enabled (false) - :proto_type () - :sync_on_cluster (true) - :timeout (0) - :use_delayed_sync (false) - :color (black) - :comments (default) - :delayed_sync_value (30) - :enable_tcp_resource (false) - :include_in_any (true) - :port (44899) - :reload_proof (false) - :src_port () - :type (Tcp) - ) - : (RADIUS - :AdminInfo ( - :chkpf_uid ("{97AEB41D-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (udp_service) - :table (services) - :Wiznum (-1) - :LastModified ( - :Time ("Tue Jan 4 22:09:25 2005") - :By (IsoAAAF) - :From (IsoAAADray) - ) - ) - :color (firebrick) - :comments ("Remote Authentication Dial-In User Service") - :delete_on_reply (false) - :etm_enabled (false) - :include_in_any (true) - :port (1645) - :proto_type () - :reload_proof (false) - :replies (true) - :replies_from_any_port (false) - :src_port () - :sync_on_cluster (true) - :timeout (0) - :type (Udp) - ) - : (SpikeServices - :AdminInfo ( - :chkpf_uid ("{9D35FACE-289F-49A6-95C7-13417959BC9D}") - :ClassName (service_group) - :table (services) - :Wiznum (-1) - :LastModified ( - :Time ("Thu Jan 6 16:41:59 2005") - :By (IsoAAAF) - :From (IsoAAADray) - ) - ) - : (ReferenceObject - :Name (apcupsd) - :Table (services) - :Uid ("{A1044CB4-439C-40C9-8489-FA5086134886}") - ) - : (ReferenceObject - :Name (CIFS) - :Table (services) - :Uid ("{2A469820-B502-434C-9340-A377677A6A60}") - ) - : (ReferenceObject - :Name (domain-udp) - :Table (services) - :Uid ("{97AEB3FA-9AEA-11D5-BD16-0090272CCB30}") - ) - : (ReferenceObject - :Name (echo-request) - :Table (services) - :Uid ("{97AEB40A-9AEA-11D5-BD16-0090272CCB30}") - ) - : (ReferenceObject - :Name (imap) - :Table (services) - :Uid ("{97AEB446-9AEA-11D5-BD16-0090272CCB30}") - ) - : (ReferenceObject - :Name (smtp) - :Table (services) - :Uid ("{97AEB3D9-9AEA-11D5-BD16-0090272CCB30}") - ) - : (ReferenceObject - :Name (squid) - :Table (services) - :Uid ("{91C0454D-F70C-44B3-8F2D-70C4A68E9594}") - ) - : (ReferenceObject - :Name (sshv2-24) - :Table (services) - :Uid ("{1DA78BCE-7ABC-4DBB-82AF-FDBE6B853493}") - ) - : (ReferenceObject - :Name (syslog) - :Table (services) - :Uid ("{97AEB3E0-9AEA-11D5-BD16-0090272CCB30}") - ) - :color (black) - :comments () - :etm_enabled (false) - :member_class (service) - :members_query () - :type (group) - : (ReferenceObject - :Table (services) - :Name (imaps) - :Uid ("{B760A869-04DF-43E2-91F9-414C58F86F16}") - ) - ) - : (imaps - :AdminInfo ( - :chkpf_uid ("{B760A869-04DF-43E2-91F9-414C58F86F16}") - :ClassName (tcp_service) - :table (services) - :Wiznum (-1) - :LastModified ( - :Time ("Thu Jan 6 16:41:59 2005") - :By (IsoAAAF) - :From (IsoAAADray) - ) - ) - :etm_enabled (false) - :proto_type () - :sync_on_cluster (true) - :timeout (0) - :use_delayed_sync (false) - :color (black) - :comments () - :delayed_sync_value (30) - :enable_tcp_resource (false) - :include_in_any (true) - :port (993) - :reload_proof (false) - :src_port () - :type (Tcp) - ) - : (TeamSpeak - :AdminInfo ( - :chkpf_uid ("{D2BBEFB3-8450-4301-9040-2D305887A748}") - :ClassName (udp_service) - :table (services) - :Wiznum (-1) - :LastModified ( - :Time ("Tue Apr 12 08:48:10 2005") - :By (IsoAAAF) - :From (IsoAAADray) - ) - ) - :delete_on_reply (false) - :etm_enabled (false) - :proto_type () - :replies (true) - :replies_from_any_port (false) - :sync_on_cluster (true) - :timeout (0) - :color (blue) - :comments () - :include_in_any (true) - :port (8767) - :reload_proof (false) - :src_port () - :type (Udp) - ) - ) - :times (times - : (Midnight - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB47B-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (scheduled_event) - :table (times) - :name (Midnight) - ) - :day_of_month () - :day_of_week () - :month () - :color (black) - :comments () - :days_specification (daily) - :every_seconds (0) - :hour (23) - :minutes (59) - :type (scheduled_event) - ) - : (Fetch_Inter - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB47C-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (scheduled_event) - :table (times) - :Deleteable (false) - :Renameable (false) - :name (Fetch_Inter) - ) - :day_of_month () - :day_of_week () - :month () - :color (black) - :comments ("Check Point policy fetching interval for Dynamic IP Address Machines") - :days_specification (seconds) - :every_seconds (14400) - :hour (0) - :minutes (0) - :type (scheduled_event) - ) - ) - :products ( - : (AirWave_AMP_1.5 - :AdminInfo ( - :chkpf_uid ("{EC04E1E1-6B83-419E-9241-EA20DFE40A04}") - :ClassName (OPSEC_product) - :table (products) - :LastModified ( - :Time ("Sun Nov 17 14:47:47 2002") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :NT_commands () - :commands () - :solaris_commands () - :AMON (false) - :AMON_class_name (default_opsec_status_object) - :CPMI (false) - :CVP (false) - :ELA (false) - :LEA (false) - :OMI (false) - :RTM (false) - :SAM (false) - :UAC (true) - :UFP (false) - :color (black) - :comments () - :product_info ( - :AdminInfo ( - :chkpf_uid ("{514CB955-084F-47DF-9C4F-BDB3CFA8E3DE}") - :ClassName (OPSEC_product_info) - ) - :certification_info () - :certified (true) - :product (AMP) - :vendor (AirWave) - :version (1.5) - ) - :type (OPSEC_product) - ) - : (ArcSight_1.0 - :AdminInfo ( - :chkpf_uid ("{5ABDFE5C-4A62-4D67-BC7E-79E5F56EAFD5}") - :ClassName (OPSEC_product) - :table (products) - :LastModified ( - :Time ("Sun Nov 17 14:47:48 2002") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :NT_commands () - :commands () - :solaris_commands () - :AMON (false) - :AMON_class_name (default_opsec_status_object) - :CPMI (false) - :CVP (false) - :ELA (false) - :LEA (true) - :OMI (false) - :RTM (false) - :SAM (false) - :UAC (false) - :UFP (false) - :color (black) - :comments () - :product_info ( - :AdminInfo ( - :chkpf_uid ("{1E6C4B1C-8FCF-486E-8504-BA240244BB82}") - :ClassName (OPSEC_product_info) - ) - :certification_info () - :certified (true) - :product (ArcSight) - :vendor (ArcSight) - :version (1.0) - ) - :type (OPSEC_product) - ) - : (Avivasolutions_HostSheild_1.0 - :AdminInfo ( - :chkpf_uid ("{21582C3A-9696-47A1-B15D-E2A117393148}") - :ClassName (OPSEC_product) - :table (products) - :LastModified ( - :Time ("Sun Nov 17 14:47:48 2002") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :NT_commands () - :commands () - :solaris_commands () - :AMON (false) - :AMON_class_name (default_opsec_status_object) - :CPMI (false) - :CVP (true) - :ELA (true) - :LEA (false) - :OMI (false) - :RTM (false) - :SAM (true) - :UAC (false) - :UFP (false) - :color (black) - :comments () - :product_info ( - :AdminInfo ( - :chkpf_uid ("{56D49EC7-1614-44AC-86AE-5D3041519DFF}") - :ClassName (OPSEC_product_info) - ) - :certification_info () - :certified (true) - :product (HostShield) - :vendor ("Aviva Inc.") - :version (1.0) - ) - :type (OPSEC_product) - ) - : (Baltimore_MAILSweeper_3.8 - :AdminInfo ( - :chkpf_uid ("{CE8E3346-8544-4224-AD22-99E37F91ED7C}") - :ClassName (OPSEC_product) - :table (products) - :LastModified ( - :Time ("Sun Nov 17 14:47:48 2002") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :NT_commands () - :commands () - :solaris_commands () - :AMON (false) - :AMON_class_name (default_opsec_status_object) - :CPMI (false) - :CVP (false) - :ELA (true) - :LEA (false) - :OMI (false) - :RTM (false) - :SAM (false) - :UAC (false) - :UFP (false) - :color (black) - :comments () - :product_info ( - :AdminInfo ( - :chkpf_uid ("{BA2F9666-90C4-48C4-AD11-E85128BA70C2}") - :ClassName (OPSEC_product_info) - ) - :certification_info () - :certified (true) - :product (MAILSweeper_OPSECAlerter) - :vendor ("Baltimore Technologies") - :version (3.8) - ) - :type (OPSEC_product) - ) - : (Columbitech_Event_Log_1.0 - :AdminInfo ( - :chkpf_uid ("{F47602F3-A2DD-409C-A9EE-A7A66B4242BF}") - :ClassName (OPSEC_product) - :table (products) - :LastModified ( - :Time ("Sun Nov 17 14:47:49 2002") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :NT_commands () - :commands () - :solaris_commands () - :AMON (false) - :AMON_class_name (default_opsec_status_object) - :CPMI (false) - :CVP (false) - :ELA (true) - :LEA (false) - :OMI (false) - :RTM (false) - :SAM (false) - :UAC (false) - :UFP (false) - :color (black) - :comments () - :product_info ( - :AdminInfo ( - :chkpf_uid ("{9FAED062-CCDC-47B0-916F-48105A612B07}") - :ClassName (OPSEC_product_info) - ) - :certification_info () - :certified (true) - :product (Event_Log_Extension_Service) - :vendor (Columbitech) - :version (1.0) - ) - :type (OPSEC_product) - ) - : (e-Security_e-Wizard_3.1 - :AdminInfo ( - :chkpf_uid ("{266E0FAB-4BF3-4368-9B9F-9141B2C76CA4}") - :ClassName (OPSEC_product) - :table (products) - :LastModified ( - :Time ("Sun Nov 17 14:47:49 2002") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :NT_commands () - :commands () - :solaris_commands () - :AMON (false) - :AMON_class_name (default_opsec_status_object) - :CPMI (false) - :CVP (false) - :ELA (false) - :LEA (true) - :OMI (false) - :RTM (false) - :SAM (false) - :UAC (false) - :UFP (false) - :color (black) - :comments () - :product_info ( - :AdminInfo ( - :chkpf_uid ("{F4B28A64-FE25-476E-AD4E-D5793BE16893}") - :ClassName (OPSEC_product_info) - ) - :certification_info () - :certified (true) - :product (eWizard) - :vendor (e-Security) - :version (3.1) - ) - :type (OPSEC_product) - ) - : (ForeScout_ActiveScout_2.1 - :AdminInfo ( - :chkpf_uid ("{46EE3C54-A144-4D5E-BDE0-D8445ADA3BBB}") - :ClassName (OPSEC_product) - :table (products) - :LastModified ( - :Time ("Sun Nov 17 14:47:50 2002") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :NT_commands () - :commands () - :solaris_commands () - :AMON (false) - :AMON_class_name (default_opsec_status_object) - :CPMI (false) - :CVP (false) - :ELA (false) - :LEA (false) - :OMI (false) - :RTM (false) - :SAM (true) - :UAC (false) - :UFP (false) - :color (black) - :comments () - :product_info ( - :AdminInfo ( - :chkpf_uid ("{A7A45782-B3D3-4B10-AA8C-B26651F3858D}") - :ClassName (OPSEC_product_info) - ) - :certification_info () - :certified (true) - :product (ActiveScout) - :vendor (ForeScout) - :version (2.1) - ) - :type (OPSEC_product) - ) - : (FSecure_AV_FireWall_6.01 - :AdminInfo ( - :chkpf_uid ("{8C5BE8C6-C05A-4E9E-B66E-B9BEC089369B}") - :ClassName (OPSEC_product) - :table (products) - :LastModified ( - :Time ("Sun Nov 17 14:47:50 2002") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :NT_commands () - :commands () - :solaris_commands () - :AMON (false) - :AMON_class_name (default_opsec_status_object) - :CPMI (false) - :CVP (true) - :ELA (false) - :LEA (false) - :OMI (false) - :RTM (false) - :SAM (false) - :UAC (false) - :UFP (false) - :color (black) - :comments () - :product_info ( - :AdminInfo ( - :chkpf_uid ("{0CC4CDC9-5A4E-4709-8841-9B128FABA503}") - :ClassName (OPSEC_product_info) - ) - :certification_info () - :certified (true) - :product (Anti_Virus_For_FireWall) - :vendor (F-Secure) - :version (6.01) - ) - :type (OPSEC_product) - ) - : (iCognito_PureSight_3.6 - :AdminInfo ( - :chkpf_uid ("{3B743BA2-84C7-4D30-804A-00AD1FC9234D}") - :ClassName (OPSEC_product) - :table (products) - :LastModified ( - :Time ("Sun Nov 17 14:47:50 2002") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :NT_commands () - :commands () - :solaris_commands () - :AMON (false) - :AMON_class_name (default_opsec_status_object) - :CPMI (false) - :CVP (true) - :ELA (false) - :LEA (false) - :OMI (false) - :RTM (false) - :SAM (false) - :UAC (false) - :UFP (true) - :color (black) - :comments () - :product_info ( - :AdminInfo ( - :chkpf_uid ("{20675293-747A-4F42-B193-49B12EE0646A}") - :ClassName (OPSEC_product_info) - ) - :certification_info () - :certified (true) - :product (PureSight) - :vendor ("iCognito Technologies Ltd") - :version (3.6) - ) - :type (OPSEC_product) - ) - : (Intrusion_ELA_Bridge_1.0 - :AdminInfo ( - :chkpf_uid ("{990D5111-5271-4BD2-A548-0ED5903648B1}") - :ClassName (OPSEC_product) - :table (products) - :LastModified ( - :Time ("Sun Nov 17 14:47:51 2002") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :NT_commands () - :commands () - :solaris_commands () - :AMON (false) - :AMON_class_name (default_opsec_status_object) - :CPMI (false) - :CVP (false) - :ELA (true) - :LEA (false) - :OMI (false) - :RTM (false) - :SAM (false) - :UAC (false) - :UFP (false) - :color (black) - :comments () - :product_info ( - :AdminInfo ( - :chkpf_uid ("{7AD97E26-C1E6-449A-83DA-58F911CB7498}") - :ClassName (OPSEC_product_info) - ) - :certification_info () - :certified (true) - :product (SecureNet_Provider_ELA_Bridge) - :vendor (Intrusion) - :version (1.0) - ) - :type (OPSEC_product) - ) - : (IntruVert_IntruShield_IDS_1.1 - :AdminInfo ( - :chkpf_uid ("{2B22AC72-6A6B-4C14-805A-9A0D5215792A}") - :ClassName (OPSEC_product) - :table (products) - :LastModified ( - :Time ("Sun Nov 17 14:47:51 2002") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :NT_commands () - :commands () - :solaris_commands () - :AMON (false) - :AMON_class_name (default_opsec_status_object) - :CPMI (false) - :CVP (false) - :ELA (false) - :LEA (false) - :OMI (false) - :RTM (false) - :SAM (true) - :UAC (false) - :UFP (false) - :color (black) - :comments () - :product_info ( - :AdminInfo ( - :chkpf_uid ("{EE1220EA-F8F5-4BB6-8816-A85165707FC8}") - :ClassName (OPSEC_product_info) - ) - :certification_info () - :certified (true) - :product (IntruShield_IDS) - :vendor ("IntruVert Networks") - :version (1.1) - ) - :type (OPSEC_product) - ) - : (KaVaDo_InterDo_2.5 - :AdminInfo ( - :chkpf_uid ("{144CFFB1-0280-490F-9CEE-AE3BDD368B21}") - :ClassName (OPSEC_product) - :table (products) - :LastModified ( - :Time ("Sun Nov 17 14:47:51 2002") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :NT_commands () - :commands () - :solaris_commands () - :AMON (false) - :AMON_class_name (default_opsec_status_object) - :CPMI (false) - :CVP (false) - :ELA (false) - :LEA (false) - :OMI (false) - :RTM (false) - :SAM (true) - :UAC (false) - :UFP (false) - :color (black) - :comments () - :product_info ( - :AdminInfo ( - :chkpf_uid ("{6BEBC5CE-0101-4710-897F-779537481B0F}") - :ClassName (OPSEC_product_info) - ) - :certification_info () - :certified (true) - :product (InterDo) - :vendor (KaVaDo) - :version (2.5) - ) - :type (OPSEC_product) - ) - : (Latis_StillSecure_2.0 - :AdminInfo ( - :chkpf_uid ("{2399873E-177B-4AF7-AC6E-7845A0954862}") - :ClassName (OPSEC_product) - :table (products) - :LastModified ( - :Time ("Sun Nov 17 14:47:52 2002") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :NT_commands () - :commands () - :solaris_commands () - :AMON (false) - :AMON_class_name (default_opsec_status_object) - :CPMI (false) - :CVP (false) - :ELA (false) - :LEA (false) - :OMI (false) - :RTM (false) - :SAM (true) - :UAC (false) - :UFP (false) - :color (black) - :comments () - :product_info ( - :AdminInfo ( - :chkpf_uid ("{BAC1DA63-5F78-4799-B59A-EB9A64F5CA85}") - :ClassName (OPSEC_product_info) - ) - :certification_info () - :certified (true) - :product (StillSecure_Perimeter) - :vendor ("Latis Networks") - :version (2.0) - ) - :type (OPSEC_product) - ) - : (LogOn_SQLGuard_2.01 - :AdminInfo ( - :chkpf_uid ("{1ACBD3A6-68E6-412E-8E07-44BBAA8BDF5F}") - :ClassName (OPSEC_product) - :table (products) - :LastModified ( - :Time ("Sun Nov 17 14:47:52 2002") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :NT_commands () - :commands () - :solaris_commands () - :AMON (false) - :AMON_class_name (default_opsec_status_object) - :CPMI (false) - :CVP (true) - :ELA (true) - :LEA (false) - :OMI (false) - :RTM (false) - :SAM (false) - :UAC (false) - :UFP (false) - :color (black) - :comments () - :product_info ( - :AdminInfo ( - :chkpf_uid ("{C87A1D0B-A8D6-4DAF-9AB8-995462460978}") - :ClassName (OPSEC_product_info) - ) - :certification_info () - :certified (true) - :product (SQL_Guard) - :vendor ("LogOn Software") - :version (2.01) - ) - :type (OPSEC_product) - ) - : (nCircle_IP360 - :AdminInfo ( - :chkpf_uid ("{D0A4C84D-82ED-4392-B204-D629E94BC7E4}") - :ClassName (OPSEC_product) - :table (products) - :LastModified ( - :Time ("Sun Nov 17 14:47:52 2002") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :NT_commands () - :commands () - :solaris_commands () - :AMON (false) - :AMON_class_name (default_opsec_status_object) - :CPMI (false) - :CVP (false) - :ELA (false) - :LEA (false) - :OMI (false) - :RTM (false) - :SAM (true) - :UAC (false) - :UFP (false) - :color (black) - :comments () - :product_info ( - :AdminInfo ( - :chkpf_uid ("{5DBDFBB4-6BEC-49EF-AA6B-F255E0B750E5}") - :ClassName (OPSEC_product_info) - ) - :certification_info () - :certified (true) - :product (IP360) - :vendor ("nCircle Network Security") - :version (360) - ) - :type (OPSEC_product) - ) - : (NEC_CLUSTERPRO_FW_1.0 - :AdminInfo ( - :chkpf_uid ("{5B33026B-6D05-4339-BD69-F3ABA12FF288}") - :ClassName (OPSEC_product) - :table (products) - :LastModified ( - :Time ("Sun Nov 17 14:47:53 2002") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :NT_commands () - :commands () - :solaris_commands () - :AMON (false) - :AMON_class_name (default_opsec_status_object) - :CPMI (false) - :CVP (false) - :ELA (true) - :LEA (false) - :OMI (false) - :RTM (false) - :SAM (false) - :UAC (false) - :UFP (false) - :color (black) - :comments () - :product_info ( - :AdminInfo ( - :chkpf_uid ("{EE9AE544-5D34-465C-9D6D-FF28FD7DB74E}") - :ClassName (OPSEC_product_info) - ) - :certification_info () - :certified (true) - :product (CLUSTERPRO_FW) - :vendor (NEC) - :version (1.0) - ) - :type (OPSEC_product) - ) - : (NetIQ_SecurityManager_3.51 - :AdminInfo ( - :chkpf_uid ("{CAD16706-7ACE-4479-920A-8A9EB0790812}") - :ClassName (OPSEC_product) - :table (products) - :LastModified ( - :Time ("Sun Nov 17 14:47:53 2002") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :NT_commands () - :commands () - :solaris_commands () - :AMON (false) - :AMON_class_name (default_opsec_status_object) - :CPMI (false) - :CVP (false) - :ELA (false) - :LEA (true) - :OMI (false) - :RTM (false) - :SAM (false) - :UAC (false) - :UFP (false) - :color (black) - :comments () - :product_info ( - :AdminInfo ( - :chkpf_uid ("{CEA85410-9DC8-45EC-BE66-C7B2DA28E786}") - :ClassName (OPSEC_product_info) - ) - :certification_info () - :certified (true) - :product (SecurityManager) - :vendor (NetIQ) - :version (3.51) - ) - :type (OPSEC_product) - ) - : (netVmg_Flow_Analyzer_2.0 - :AdminInfo ( - :chkpf_uid ("{237FD389-CC08-47CA-A42C-FF62CBA22D06}") - :ClassName (OPSEC_product) - :table (products) - :LastModified ( - :Time ("Sun Nov 17 14:47:54 2002") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :NT_commands () - :commands () - :solaris_commands () - :AMON (false) - :AMON_class_name (default_opsec_status_object) - :CPMI (false) - :CVP (false) - :ELA (false) - :LEA (true) - :OMI (false) - :RTM (false) - :SAM (false) - :UAC (false) - :UFP (false) - :color (black) - :comments () - :product_info ( - :AdminInfo ( - :chkpf_uid ("{E00EC2B1-E27A-4C96-84CA-DE18198E750E}") - :ClassName (OPSEC_product_info) - ) - :certification_info () - :certified (true) - :product (Flow_Analyzer_FCP) - :vendor (netVmg) - :version (2.0) - ) - :type (OPSEC_product) - ) - : (OpenService_SystemWatch_2.7 - :AdminInfo ( - :chkpf_uid ("{43D8E678-3FDF-42ED-AD5E-D07340ACA9ED}") - :ClassName (OPSEC_product) - :table (products) - :LastModified ( - :Time ("Sun Nov 17 14:47:54 2002") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :NT_commands () - :commands () - :solaris_commands () - :AMON (false) - :AMON_class_name (default_opsec_status_object) - :CPMI (false) - :CVP (false) - :ELA (false) - :LEA (true) - :OMI (false) - :RTM (false) - :SAM (false) - :UAC (false) - :UFP (false) - :color (black) - :comments () - :product_info ( - :AdminInfo ( - :chkpf_uid ("{317645D2-91AC-4C3D-983B-FB53604719E8}") - :ClassName (OPSEC_product_info) - ) - :certification_info () - :certified (true) - :product (SystemWatch) - :vendor (OpenService) - :version (2.7) - ) - :type (OPSEC_product) - ) - : (QualysGuard_1.7 - :AdminInfo ( - :chkpf_uid ("{AD3BB362-2949-4F52-9EF6-66267EA09606}") - :ClassName (OPSEC_product) - :table (products) - :LastModified ( - :Time ("Sun Nov 17 14:47:55 2002") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :NT_commands () - :commands () - :solaris_commands () - :AMON (false) - :AMON_class_name (default_opsec_status_object) - :CPMI (true) - :CVP (false) - :ELA (true) - :LEA (false) - :OMI (false) - :RTM (false) - :SAM (false) - :UAC (false) - :UFP (false) - :color (black) - :comments () - :product_info ( - :AdminInfo ( - :chkpf_uid ("{A11EBA5E-4B2F-44B1-85F8-CA4C9490294A}") - :ClassName (OPSEC_product_info) - ) - :certification_info () - :certified (true) - :product (QualysGuard) - :vendor (Qualys) - :version (1.7) - ) - :type (OPSEC_product) - ) - : (Rainwall_3.0 - :AdminInfo ( - :chkpf_uid ("{8F2C6D6D-8475-4D1D-882B-A6A73B03ED69}") - :ClassName (OPSEC_product) - :table (products) - :LastModified ( - :Time ("Sun Nov 17 14:47:55 2002") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :NT_commands () - :commands () - :solaris_commands () - :AMON (true) - :AMON_class_name (default_opsec_status_object) - :CPMI (true) - :CVP (false) - :ELA (true) - :LEA (false) - :OMI (false) - :RTM (false) - :SAM (false) - :UAC (false) - :UFP (false) - :color (black) - :comments () - :product_info ( - :AdminInfo ( - :chkpf_uid ("{C1E8A9A9-2313-40C4-BED7-BDEE7523EA3F}") - :ClassName (OPSEC_product_info) - ) - :certification_info () - :certified (true) - :product (Rainwall) - :vendor (Rainfinity) - :version (3.0) - ) - :type (OPSEC_product) - ) - : (Rainwall_3.0_SP2 - :AdminInfo ( - :chkpf_uid ("{36263BBB-C30B-4DC7-B6E1-7E3B614F106D}") - :ClassName (OPSEC_product) - :table (products) - :LastModified ( - :Time ("Sun Nov 17 14:47:55 2002") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :NT_commands () - :commands () - :solaris_commands () - :AMON (true) - :AMON_class_name (default_opsec_status_object) - :CPMI (true) - :CVP (false) - :ELA (true) - :LEA (false) - :OMI (false) - :RTM (false) - :SAM (false) - :UAC (false) - :UFP (false) - :color (black) - :comments () - :product_info ( - :AdminInfo ( - :chkpf_uid ("{69B7508E-5363-49B4-8202-199C5BCCDF19}") - :ClassName (OPSEC_product_info) - ) - :certification_info () - :certified (true) - :product (Rainwall) - :vendor (Rainfinity) - :version ("3.0 SP2") - ) - :type (OPSEC_product) - ) - : (Recourse_ManHunt_MSA_2.1 - :AdminInfo ( - :chkpf_uid ("{68E38A62-5F3D-4BA4-B7A7-A1F27A577DBB}") - :ClassName (OPSEC_product) - :table (products) - :LastModified ( - :Time ("Sun Nov 17 14:47:56 2002") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :NT_commands () - :commands () - :solaris_commands () - :AMON (false) - :AMON_class_name (default_opsec_status_object) - :CPMI (false) - :CVP (false) - :ELA (false) - :LEA (true) - :OMI (false) - :RTM (false) - :SAM (false) - :UAC (false) - :UFP (false) - :color (black) - :comments () - :product_info ( - :AdminInfo ( - :chkpf_uid ("{4D9D1236-FF5A-42CC-8619-2BEB69E5476D}") - :ClassName (OPSEC_product_info) - ) - :certification_info () - :certified (true) - :product (ManHunt_Smart_Agent) - :vendor ("Recourse Technologies") - :version (2.1) - ) - :type (OPSEC_product) - ) - : (RiscManager_4.1 - :AdminInfo ( - :chkpf_uid ("{00EB61E3-C6A3-432E-8BC0-855659B09BEE}") - :ClassName (OPSEC_product) - :table (products) - :LastModified ( - :Time ("Sun Nov 17 14:47:56 2002") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :NT_commands () - :commands () - :solaris_commands () - :AMON (false) - :AMON_class_name (default_opsec_status_object) - :CPMI (false) - :CVP (false) - :ELA (false) - :LEA (true) - :OMI (false) - :RTM (false) - :SAM (true) - :UAC (false) - :UFP (false) - :color (black) - :comments () - :product_info ( - :AdminInfo ( - :chkpf_uid ("{EF2BB489-5E4A-40FA-85AE-0028FE27D337}") - :ClassName (OPSEC_product_info) - ) - :certification_info () - :certified (true) - :product (RiscManager) - :vendor ("Risc Solutions") - :version (4.1) - ) - :type (OPSEC_product) - ) - : (RouteScience_PathControl_2.0 - :AdminInfo ( - :chkpf_uid ("{3E077F18-923D-4FA9-8F8A-AD42DDEB8577}") - :ClassName (OPSEC_product) - :table (products) - :LastModified ( - :Time ("Sun Nov 17 14:47:56 2002") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :NT_commands () - :commands () - :solaris_commands () - :AMON (false) - :AMON_class_name (default_opsec_status_object) - :CPMI (true) - :CVP (false) - :ELA (false) - :LEA (false) - :OMI (false) - :RTM (false) - :SAM (false) - :UAC (false) - :UFP (false) - :color (black) - :comments () - :product_info ( - :AdminInfo ( - :chkpf_uid ("{A3E3AE18-C0D7-491F-899F-37B0CF81C9C7}") - :ClassName (OPSEC_product_info) - ) - :certification_info () - :certified (true) - :product (PathControl) - :vendor (RouteScience) - :version (2.0) - ) - :type (OPSEC_product) - ) - : (RSF-1_2.1 - :AdminInfo ( - :chkpf_uid ("{962C136F-A152-4A70-896C-B5255E38100E}") - :ClassName (OPSEC_product) - :table (products) - :LastModified ( - :Time ("Sun Nov 17 14:47:57 2002") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :NT_commands () - :commands () - :solaris_commands () - :AMON (false) - :AMON_class_name (default_opsec_status_object) - :CPMI (false) - :CVP (false) - :ELA (true) - :LEA (false) - :OMI (false) - :RTM (false) - :SAM (false) - :UAC (false) - :UFP (false) - :color (black) - :comments () - :product_info ( - :AdminInfo ( - :chkpf_uid ("{213E59BB-B78D-40B4-AD2E-E04A72C24A55}") - :ClassName (OPSEC_product_info) - ) - :certification_info () - :certified (true) - :product (RSF-1) - :vendor ("High Availability.com") - :version (2.1) - ) - :type (OPSEC_product) - ) - : (SecoShield_3.1 - :AdminInfo ( - :chkpf_uid ("{DA16BDEE-AB1A-42B5-AF7B-F9CEDED44C56}") - :ClassName (OPSEC_product) - :table (products) - :LastModified ( - :Time ("Sun Nov 17 14:47:58 2002") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :NT_commands () - :commands () - :solaris_commands () - :AMON (true) - :AMON_class_name (default_opsec_status_object) - :CPMI (true) - :CVP (false) - :ELA (true) - :LEA (false) - :OMI (false) - :RTM (false) - :SAM (true) - :UAC (false) - :UFP (false) - :color (black) - :comments () - :product_info ( - :AdminInfo ( - :chkpf_uid ("{E1F03A62-6DF6-4159-AC8F-6D89669D4DC8}") - :ClassName (OPSEC_product_info) - ) - :certification_info () - :certified (true) - :product (SecoShield_3.1) - :vendor (INFOSEC_Technologies) - :version (3.1) - ) - :type (OPSEC_product) - ) - : (StoneBeat_FullCluster_3.0 - :AdminInfo ( - :chkpf_uid ("{0CDB568E-F4AC-4E4F-913F-5563993374F1}") - :ClassName (OPSEC_product) - :table (products) - :LastModified ( - :Time ("Sun Nov 17 14:47:58 2002") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :NT_commands () - :commands () - :solaris_commands () - :AMON (false) - :AMON_class_name (default_opsec_status_object) - :CPMI (true) - :CVP (false) - :ELA (true) - :LEA (false) - :OMI (false) - :RTM (false) - :SAM (false) - :UAC (false) - :UFP (false) - :color (black) - :comments () - :product_info ( - :AdminInfo ( - :chkpf_uid ("{BC989FF9-70E8-4BDC-8EF1-164E8F913B52}") - :ClassName (OPSEC_product_info) - ) - :certification_info () - :certified (true) - :product (StoneBeat_FullCluster) - :vendor (StoneSoft) - :version (3.0) - ) - :type (OPSEC_product) - ) - : (Symantec_Web_Security_2.5 - :AdminInfo ( - :chkpf_uid ("{CAA1846F-E365-4D28-9D97-CFF832118A3B}") - :ClassName (OPSEC_product) - :table (products) - :LastModified ( - :Time ("Sun Nov 17 14:47:58 2002") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :NT_commands () - :commands () - :solaris_commands () - :AMON (false) - :AMON_class_name (default_opsec_status_object) - :CPMI (false) - :CVP (true) - :ELA (false) - :LEA (false) - :OMI (false) - :RTM (false) - :SAM (false) - :UAC (false) - :UFP (false) - :color (black) - :comments () - :product_info ( - :AdminInfo ( - :chkpf_uid ("{A8557DE2-054D-4398-A350-EEFEDEBD6E1F}") - :ClassName (OPSEC_product_info) - ) - :certification_info () - :certified (true) - :product (Symantec_Web_Security) - :vendor (Symantec) - :version (2.5) - ) - :type (OPSEC_product) - ) - : (Tripwire_For_Servers_3.0 - :AdminInfo ( - :chkpf_uid ("{9C167955-001C-49CD-81C8-E7663735FF48}") - :ClassName (OPSEC_product) - :table (products) - :LastModified ( - :Time ("Sun Nov 17 14:47:59 2002") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :NT_commands () - :commands () - :solaris_commands () - :AMON (false) - :AMON_class_name (default_opsec_status_object) - :CPMI (false) - :CVP (false) - :ELA (true) - :LEA (false) - :OMI (false) - :RTM (false) - :SAM (false) - :UAC (false) - :UFP (false) - :color (black) - :comments () - :product_info ( - :AdminInfo ( - :chkpf_uid ("{65423D8E-21F1-4972-A4B9-BC0E2474018D}") - :ClassName (OPSEC_product_info) - ) - :certification_info () - :certified (true) - :product (Tripwire_For_Servers) - :vendor (Tripwire) - :version (3.0) - ) - :type (OPSEC_product) - ) - : (Trustworks_GSM_3.3.2 - :AdminInfo ( - :chkpf_uid ("{53437B06-A258-4A76-92C1-CFC3D7B85384}") - :ClassName (OPSEC_product) - :table (products) - :LastModified ( - :Time ("Sun Nov 17 14:47:59 2002") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :NT_commands () - :commands () - :solaris_commands () - :AMON (false) - :AMON_class_name (default_opsec_status_object) - :CPMI (true) - :CVP (false) - :ELA (false) - :LEA (false) - :OMI (false) - :RTM (false) - :SAM (false) - :UAC (false) - :UFP (false) - :color (black) - :comments () - :product_info ( - :AdminInfo ( - :chkpf_uid ("{8BE4E5A1-C142-48DC-BCF8-A0E9D39D054D}") - :ClassName (OPSEC_product_info) - ) - :certification_info () - :certified (true) - :product (Global_Security_Manager) - :vendor (Trustworks) - :version (3.3.2) - ) - :type (OPSEC_product) - ) - : (WebSense_Enterprise_4.4 - :AdminInfo ( - :chkpf_uid ("{5CD0E11A-7658-4158-B313-C310E5D14E21}") - :ClassName (OPSEC_product) - :table (products) - :LastModified ( - :Time ("Sun Nov 17 14:48:00 2002") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :NT_commands () - :commands () - :solaris_commands () - :AMON (false) - :AMON_class_name (default_opsec_status_object) - :CPMI (false) - :CVP (false) - :ELA (false) - :LEA (false) - :OMI (false) - :RTM (false) - :SAM (false) - :UAC (false) - :UFP (true) - :color (black) - :comments () - :product_info ( - :AdminInfo ( - :chkpf_uid ("{4471126F-C2FA-411F-A459-9C4ACC501A67}") - :ClassName (OPSEC_product_info) - ) - :certification_info () - :certified (true) - :product (WebSense_for_FireWall-1) - :vendor (WebSense) - :version (4.4) - ) - :type (OPSEC_product) - ) - : (TM_IMSS_5.1 - :AdminInfo ( - :chkpf_uid ("{B8177692-19D5-4746-AD58-D9C46E4F00A0}") - :ClassName (OPSEC_product) - :table (products) - :LastModified ( - :Time ("Sun Nov 17 14:48:00 2002") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :NT_commands () - :commands () - :solaris_commands () - :AMON (true) - :AMON_class_name (default_opsec_status_object) - :CPMI (false) - :CVP (false) - :ELA (false) - :LEA (false) - :OMI (false) - :RTM (false) - :SAM (false) - :UAC (false) - :UFP (false) - :color (black) - :comments () - :product_info ( - :AdminInfo ( - :chkpf_uid ("{5185B9D6-D1E2-4181-95A1-0FA095D2E4B2}") - :ClassName (OPSEC_product_info) - ) - :certification_info () - :certified (true) - :product (IMSS) - :vendor (Trend_Micro) - :version (5.1) - ) - :type (OPSEC_product) - ) - : (NetIQ_Security_Manager_4.0 - :AdminInfo ( - :chkpf_uid ("{F41306EC-F711-4A31-B662-FC7FD9668891}") - :ClassName (OPSEC_product) - :table (products) - :LastModified ( - :Time ("Sun Nov 17 14:48:01 2002") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :NT_commands () - :commands () - :solaris_commands () - :AMON (false) - :AMON_class_name (default_opsec_status_object) - :CPMI (false) - :CVP (false) - :ELA (false) - :LEA (true) - :OMI (false) - :RTM (false) - :SAM (false) - :UAC (false) - :UFP (false) - :color (black) - :comments () - :product_info ( - :AdminInfo ( - :chkpf_uid ("{9311BC4D-291F-42F9-85B4-223BBB5D5FBB}") - :ClassName (OPSEC_product_info) - ) - :certification_info () - :certified (true) - :product (SecurityManager) - :vendor (NetIQ) - :version (4.0) - ) - :type (OPSEC_product) - ) - : (Akonix_L7_1.0 - :AdminInfo ( - :chkpf_uid ("{510B55DC-06E8-4615-AFE5-35648B79E433}") - :ClassName (OPSEC_product) - :table (products) - :LastModified ( - :Time ("Sun Nov 17 14:55:27 2002") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :NT_commands () - :commands () - :solaris_commands () - :AMON (false) - :AMON_class_name (default_opsec_status_object) - :CPMI (false) - :CVP (true) - :ELA (false) - :LEA (false) - :OMI (false) - :RTM (false) - :SAM (false) - :UAC (false) - :UFP (false) - :color (black) - :comments () - :product_info ( - :AdminInfo ( - :chkpf_uid ("{49E1EC41-3764-42B5-BB07-6307CD981126}") - :ClassName (OPSEC_product_info) - ) - :certification_info () - :certified (true) - :product (L7) - :vendor (Akonix) - :version (1.0) - ) - :type (OPSEC_product) - ) - : (Aladdin_ESafe_Gateway_3.1 - :AdminInfo ( - :chkpf_uid ("{8A7D0327-7578-4055-A615-2AB7AC4AD39D}") - :ClassName (OPSEC_product) - :table (products) - :LastModified ( - :Time ("Sun Nov 17 14:57:22 2002") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :NT_commands () - :commands () - :solaris_commands () - :AMON (false) - :AMON_class_name (default_opsec_status_object) - :CPMI (false) - :CVP (true) - :ELA (false) - :LEA (false) - :OMI (false) - :RTM (false) - :SAM (false) - :UAC (false) - :UFP (false) - :color (black) - :comments () - :product_info ( - :AdminInfo ( - :chkpf_uid ("{50FC2B4C-A41F-42B7-A844-50E87B242B5C}") - :ClassName (OPSEC_product_info) - ) - :certification_info () - :certified (true) - :product (ESafe_Protect_Gateway) - :vendor (Aladdin_Knowledge_Systems) - :version (3.1) - ) - :type (OPSEC_product) - ) - : (Bind_View_bv-Control_7.2 - :AdminInfo ( - :chkpf_uid ("{B544740E-DCC8-4BDC-B37C-5CA1E4C0ED0E}") - :ClassName (OPSEC_product) - :table (products) - :LastModified ( - :Time ("Sun Nov 17 15:00:04 2002") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :NT_commands () - :commands () - :solaris_commands () - :AMON (false) - :AMON_class_name (default_opsec_status_object) - :CPMI (false) - :CVP (false) - :ELA (false) - :LEA (true) - :OMI (false) - :RTM (false) - :SAM (false) - :UAC (false) - :UFP (false) - :color (black) - :comments () - :product_info ( - :AdminInfo ( - :chkpf_uid ("{B308FF29-A6B2-4715-9230-2C1E1FD8D2BA}") - :ClassName (OPSEC_product_info) - ) - :certification_info () - :certified (true) - :product (bv-Control_for_Check_Point_FW-1) - :vendor (BindView) - :version (7.2) - ) - :type (OPSEC_product) - ) - : (NFR_Security_CMS_2.1 - :AdminInfo ( - :chkpf_uid ("{9C629DA4-D45E-4D12-9BF9-6F7991C58852}") - :ClassName (OPSEC_product) - :table (products) - :LastModified ( - :Time ("Sun Nov 17 15:03:31 2002") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :NT_commands () - :commands () - :solaris_commands () - :AMON (false) - :AMON_class_name (default_opsec_status_object) - :CPMI (false) - :CVP (false) - :ELA (false) - :LEA (false) - :OMI (false) - :RTM (false) - :SAM (true) - :UAC (false) - :UFP (false) - :color (black) - :comments () - :product_info ( - :AdminInfo ( - :chkpf_uid ("{7DCC5BDA-E8DA-4B6C-847E-D421730BCBD4}") - :ClassName (OPSEC_product_info) - ) - :certification_info () - :certified (true) - :product (CMS) - :vendor ("NFR Security Inc.") - :version (2.1) - ) - :type (OPSEC_product) - ) - : (Sanctum_AppShield_3.0 - :AdminInfo ( - :chkpf_uid ("{C900DCF0-FCC4-45E7-9E29-EFD0F8D5FD3A}") - :ClassName (OPSEC_product) - :table (products) - :LastModified ( - :Time ("Sun Nov 17 15:09:02 2002") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :NT_commands () - :commands () - :solaris_commands () - :AMON (false) - :AMON_class_name (default_opsec_status_object) - :CPMI (false) - :CVP (false) - :ELA (true) - :LEA (false) - :OMI (false) - :RTM (false) - :SAM (false) - :UAC (false) - :UFP (false) - :color (black) - :comments () - :product_info ( - :AdminInfo ( - :chkpf_uid ("{B83C4359-4890-49A7-AECB-0DD4B4F689CF}") - :ClassName (OPSEC_product_info) - ) - :certification_info () - :certified (true) - :product (AppShield) - :vendor ("Sanctum Inc.") - :version (3.0) - ) - :type (OPSEC_product) - ) - : (Lucid_Security_ipAngel_1.0 - :AdminInfo ( - :chkpf_uid ("{10CD6D53-3FF5-4722-BB68-E10652AEB4AC}") - :ClassName (OPSEC_product) - :table (products) - :LastModified ( - :Time ("Sun Nov 17 15:11:33 2002") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :NT_commands () - :commands () - :solaris_commands () - :AMON (false) - :AMON_class_name (default_opsec_status_object) - :CPMI (true) - :CVP (false) - :ELA (false) - :LEA (false) - :OMI (false) - :RTM (false) - :SAM (true) - :UAC (false) - :UFP (false) - :color (black) - :comments () - :product_info ( - :AdminInfo ( - :chkpf_uid ("{418A3011-4E22-4946-9B6D-55A5EB88FCD3}") - :ClassName (OPSEC_product_info) - ) - :certification_info () - :certified (true) - :product (ipAngel) - :vendor ("Lucid Security") - :version (1.0) - ) - :type (OPSEC_product) - ) - : (Ikarus_Content_Wall_2.25 - :AdminInfo ( - :chkpf_uid ("{8C48300C-3289-4DC7-985B-4E8C6C32709C}") - :ClassName (OPSEC_product) - :table (products) - :LastModified ( - :Time ("Sun Nov 17 15:18:14 2002") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :NT_commands () - :commands () - :solaris_commands () - :AMON (true) - :AMON_class_name (default_opsec_status_object) - :CPMI (false) - :CVP (true) - :ELA (true) - :LEA (false) - :OMI (false) - :RTM (false) - :SAM (false) - :UAC (false) - :UFP (true) - :color (black) - :comments () - :product_info ( - :AdminInfo ( - :chkpf_uid ("{64C3E29F-AEBE-4E19-B46D-7B141DDF8D99}") - :ClassName (OPSEC_product_info) - ) - :certification_info () - :certified (true) - :product (Content_Wall) - :vendor (Ikarus) - :version (2.25) - ) - :type (OPSEC_product) - ) - : (AirWave_AMP_1.1 - :AdminInfo ( - :chkpf_uid ("{F52E30B3-EF5F-411A-AE83-1063D39506C4}") - :ClassName (OPSEC_product) - :table (products) - :LastModified ( - :Time ("Sun Nov 17 17:10:45 2002") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :NT_commands () - :commands () - :solaris_commands () - :AMON (false) - :AMON_class_name (default_opsec_status_object) - :CPMI (false) - :CVP (false) - :ELA (false) - :LEA (true) - :OMI (false) - :RTM (false) - :SAM (false) - :UAC (false) - :UFP (false) - :color (black) - :comments () - :product_info ( - :AdminInfo ( - :chkpf_uid ("{A168D04B-589F-48F1-B49D-E5E0DF7F0E29}") - :ClassName (OPSEC_product_info) - ) - :certification_info () - :certified (true) - :product (AMP) - :vendor (AirWave) - :version (1.1) - ) - :type (OPSEC_product) - ) - : (Aladdin_eSafe_Gateway_3.5 - :AdminInfo ( - :chkpf_uid ("{1C1AFCE6-1DBB-4CD9-BE8A-403C84ED1944}") - :ClassName (OPSEC_product) - :table (products) - :LastModified ( - :Time ("Mon Sep 15 07:32:08 2003") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :NT_commands () - :commands () - :solaris_commands () - :AMON (false) - :AMON_class_name (default_opsec_status_object) - :CPMI (false) - :CVP (true) - :ELA (false) - :LEA (false) - :OMI (false) - :RTM (false) - :SAM (false) - :UAC (false) - :UFP (false) - :color (black) - :comments () - :product_info ( - :AdminInfo ( - :chkpf_uid ("{70DAC38B-14C8-4DEE-9556-0EF42BB91747}") - :ClassName (OPSEC_product_info) - ) - :certification_info () - :certified (true) - :product (eSafe_Gateway) - :vendor (Aladdin_Knowledge_Systems) - :version (3.5) - ) - :type (OPSEC_product) - ) - : (Business_Layers_eProvision_Module_3.0 - :AdminInfo ( - :chkpf_uid ("{BD248D30-B489-4C70-A9FA-3A74B10AABA9}") - :ClassName (OPSEC_product) - :table (products) - :LastModified ( - :Time ("Mon Sep 15 07:45:11 2003") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :NT_commands () - :commands () - :solaris_commands () - :AMON (false) - :AMON_class_name (default_opsec_status_object) - :CPMI (false) - :CVP (false) - :ELA (false) - :LEA (false) - :OMI (false) - :RTM (false) - :SAM (false) - :UAC (true) - :UFP (false) - :color (black) - :comments () - :product_info ( - :AdminInfo ( - :chkpf_uid ("{38EE5F2D-3285-4457-B17D-67D666728119}") - :ClassName (OPSEC_product_info) - ) - :certification_info () - :certified (true) - :product (eProvision_Module) - :vendor (Business_Layers) - :version (3.0) - ) - :type (OPSEC_product) - ) - : (Citrix_MetaFrame_XP - :AdminInfo ( - :chkpf_uid ("{B6A4EAFE-A167-4EE3-BDDA-FEA9437DF8D2}") - :ClassName (OPSEC_product) - :table (products) - :LastModified ( - :Time ("Mon Sep 15 07:49:04 2003") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :NT_commands () - :commands () - :solaris_commands () - :AMON (false) - :AMON_class_name (default_opsec_status_object) - :CPMI (false) - :CVP (false) - :ELA (false) - :LEA (false) - :OMI (false) - :RTM (false) - :SAM (false) - :UAC (true) - :UFP (false) - :color (black) - :comments () - :product_info ( - :AdminInfo ( - :chkpf_uid ("{3A6CE35E-BAFB-4DBF-928A-ABD6A5DB4DA1}") - :ClassName (OPSEC_product_info) - ) - :certification_info () - :certified (true) - :product (MetaFrame) - :vendor (Citrix) - :version (XP) - ) - :type (OPSEC_product) - ) - : (Computer_Associate_eTrust_Antivirus_7.0 - :AdminInfo ( - :chkpf_uid ("{D92F77E0-57F8-4CBF-B0DE-76C1FF309196}") - :ClassName (OPSEC_product) - :table (products) - :LastModified ( - :Time ("Mon Sep 15 07:55:18 2003") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :NT_commands () - :commands () - :solaris_commands () - :AMON (false) - :AMON_class_name (default_opsec_status_object) - :CPMI (false) - :CVP (true) - :ELA (false) - :LEA (false) - :OMI (false) - :RTM (false) - :SAM (false) - :UAC (false) - :UFP (false) - :color (black) - :comments () - :product_info ( - :AdminInfo ( - :chkpf_uid ("{0396E466-6ECE-47DC-8090-4FF589D2092C}") - :ClassName (OPSEC_product_info) - ) - :certification_info () - :certified (true) - :product (eTrust_Antivirus) - :vendor (Computer_Associates) - :version (7.0) - ) - :type (OPSEC_product) - ) - : (Lucid_Security_ipANGEL_2.0 - :AdminInfo ( - :chkpf_uid ("{136A989A-4087-4E20-8B6F-D253F54C80E4}") - :ClassName (OPSEC_product) - :table (products) - :LastModified ( - :Time ("Mon Sep 15 07:59:12 2003") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :NT_commands () - :commands () - :solaris_commands () - :AMON (false) - :AMON_class_name (default_opsec_status_object) - :CPMI (true) - :CVP (false) - :ELA (false) - :LEA (false) - :OMI (false) - :RTM (false) - :SAM (true) - :UAC (false) - :UFP (false) - :color (black) - :comments () - :product_info ( - :AdminInfo ( - :chkpf_uid ("{3707BE37-699F-4F0B-95E2-5F012D352BD6}") - :ClassName (OPSEC_product_info) - ) - :certification_info () - :certified (true) - :product (ipANGEL) - :vendor ("Lucid Security") - :version (2.0) - ) - :type (OPSEC_product) - ) - : (ProactiveNet_Monitor_for_FireWall-1_3.1 - :AdminInfo ( - :chkpf_uid ("{3A254832-21E2-4952-8729-120CF0B2915C}") - :ClassName (OPSEC_product) - :table (products) - :LastModified ( - :Time ("Mon Sep 15 08:03:27 2003") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :NT_commands () - :commands () - :solaris_commands () - :AMON (false) - :AMON_class_name (default_opsec_status_object) - :CPMI (false) - :CVP (false) - :ELA (false) - :LEA (true) - :OMI (false) - :RTM (false) - :SAM (false) - :UAC (false) - :UFP (false) - :color (black) - :comments () - :product_info ( - :AdminInfo ( - :chkpf_uid ("{C7DD1EDC-B16A-470A-ABF5-D1B03EF97BB0}") - :ClassName (OPSEC_product_info) - ) - :certification_info () - :certified (true) - :product (Monitor_for_FireWall-1) - :vendor (ProactiveNet) - :version (3.1) - ) - :type (OPSEC_product) - ) - : (NetIQ_Security_Reporting_Center_2.0 - :AdminInfo ( - :chkpf_uid ("{4F7AFBF3-C02E-4416-AF7F-5A4651A2E48B}") - :ClassName (OPSEC_product) - :table (products) - :LastModified ( - :Time ("Mon Sep 15 08:06:28 2003") - :By (ChackPoint) - :From (CheckPoint) - ) - ) - :NT_commands () - :commands () - :solaris_commands () - :AMON (false) - :AMON_class_name (default_opsec_status_object) - :CPMI (false) - :CVP (false) - :ELA (false) - :LEA (true) - :OMI (false) - :RTM (false) - :SAM (false) - :UAC (false) - :UFP (false) - :color (black) - :comments () - :product_info ( - :AdminInfo ( - :chkpf_uid ("{6316A47A-91A9-40B5-AA42-D4DB602B8D41}") - :ClassName (OPSEC_product_info) - ) - :certification_info () - :certified (true) - :product (Security_Reporting_Center) - :vendor (NetIQ) - :version (2.0) - ) - :type (OPSEC_product) - ) - : (Sanctum_AppShield_4.0 - :AdminInfo ( - :chkpf_uid ("{2E9FE302-3DC2-4E79-AF86-C67B48E1443E}") - :ClassName (OPSEC_product) - :table (products) - :LastModified ( - :Time ("Mon Sep 15 08:10:50 2003") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :NT_commands () - :commands () - :solaris_commands () - :AMON (false) - :AMON_class_name (default_opsec_status_object) - :CPMI (false) - :CVP (false) - :ELA (true) - :LEA (false) - :OMI (false) - :RTM (false) - :SAM (true) - :UAC (false) - :UFP (false) - :color (black) - :comments () - :product_info ( - :AdminInfo ( - :chkpf_uid ("{C75B7FC4-4E1A-42AC-8020-878ABCCE5BBF}") - :ClassName (OPSEC_product_info) - ) - :certification_info () - :certified (true) - :product (AppShield) - :vendor ("Sanctum Inc.") - :version (4.0) - ) - :type (OPSEC_product) - ) - : (TowerView_Security_HighTower_1.5 - :AdminInfo ( - :chkpf_uid ("{E885A37B-817D-469F-B118-CA226D9F4175}") - :ClassName (OPSEC_product) - :table (products) - :LastModified ( - :Time ("Mon Sep 15 08:15:00 2003") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :NT_commands () - :commands () - :solaris_commands () - :AMON (false) - :AMON_class_name (default_opsec_status_object) - :CPMI (false) - :CVP (false) - :ELA (false) - :LEA (true) - :OMI (false) - :RTM (false) - :SAM (false) - :UAC (false) - :UFP (false) - :color (black) - :comments () - :product_info ( - :AdminInfo ( - :chkpf_uid ("{28B69705-28C6-45D7-8BF7-904C979156E2}") - :ClassName (OPSEC_product_info) - ) - :certification_info () - :certified (true) - :product (HighTower) - :vendor (TowerView_Security) - :version (1.5) - ) - :type (OPSEC_product) - ) - : (Network_Intelligence_enVision_1100 - :AdminInfo ( - :chkpf_uid ("{ABE2AB14-520E-4731-8078-B4FE56B5DE77}") - :ClassName (OPSEC_product) - :table (products) - :LastModified ( - :Time ("Mon Sep 15 08:17:24 2003") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :NT_commands () - :commands () - :solaris_commands () - :AMON (false) - :AMON_class_name (default_opsec_status_object) - :CPMI (false) - :CVP (false) - :ELA (false) - :LEA (true) - :OMI (false) - :RTM (false) - :SAM (false) - :UAC (false) - :UFP (false) - :color (black) - :comments () - :product_info ( - :AdminInfo ( - :chkpf_uid ("{450B818C-C024-4F91-87C4-1998E5BA24D4}") - :ClassName (OPSEC_product_info) - ) - :certification_info () - :certified (true) - :product (enVision) - :vendor (Network_Intelligence) - :version (1100) - ) - :type (OPSEC_product) - ) - : (FishNet_Security_FireMon_2.5 - :AdminInfo ( - :chkpf_uid ("{CA2D620E-74C6-4ECB-B9C7-86CE53A7D707}") - :ClassName (OPSEC_product) - :table (products) - :LastModified ( - :Time ("Mon Sep 15 08:30:03 2003") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :NT_commands () - :commands () - :solaris_commands () - :AMON (true) - :AMON_class_name (default_opsec_status_object) - :CPMI (true) - :CVP (false) - :ELA (true) - :LEA (false) - :OMI (false) - :RTM (false) - :SAM (false) - :UAC (false) - :UFP (false) - :color (black) - :comments () - :product_info ( - :AdminInfo ( - :chkpf_uid ("{F921C2BE-68A6-4A08-80D9-47E995BC92EA}") - :ClassName (OPSEC_product_info) - ) - :certification_info () - :certified (true) - :product (FireMon) - :vendor ("FishNet Security") - :version (2.5) - ) - :type (OPSEC_product) - ) - : (Secure_Computing_Smart_Filter_3.2 - :AdminInfo ( - :chkpf_uid ("{114F1E7F-DC18-4F2F-83D7-61B60A69BFBA}") - :ClassName (OPSEC_product) - :table (products) - :LastModified ( - :Time ("Mon Sep 15 08:34:09 2003") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :NT_commands () - :commands () - :solaris_commands () - :AMON (true) - :AMON_class_name (default_opsec_status_object) - :CPMI (false) - :CVP (false) - :ELA (false) - :LEA (false) - :OMI (false) - :RTM (false) - :SAM (false) - :UAC (false) - :UFP (true) - :color (black) - :comments () - :product_info ( - :AdminInfo ( - :chkpf_uid ("{3DCF6EEE-46C4-45C2-AD85-B0AD5CAF3FA7}") - :ClassName (OPSEC_product_info) - ) - :certification_info () - :certified (true) - :product (Smart_Filter) - :vendor (Secure_Computing) - :version (3.2) - ) - :type (OPSEC_product) - ) - : (Bindview_bv-Control_7.25 - :AdminInfo ( - :chkpf_uid ("{00DF0C36-DD39-4472-8144-74A62E060134}") - :ClassName (OPSEC_product) - :table (products) - :LastModified ( - :Time ("Mon Sep 15 08:37:17 2003") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :NT_commands () - :commands () - :solaris_commands () - :AMON (false) - :AMON_class_name (default_opsec_status_object) - :CPMI (true) - :CVP (false) - :ELA (false) - :LEA (true) - :OMI (false) - :RTM (false) - :SAM (false) - :UAC (false) - :UFP (false) - :color (black) - :comments () - :product_info ( - :AdminInfo ( - :chkpf_uid ("{C34E2DA4-ECF8-4F10-AE5F-D9DE79468E25}") - :ClassName (OPSEC_product_info) - ) - :certification_info () - :certified (true) - :product (bv-Control) - :vendor (BindView) - :version (7.25) - ) - :type (OPSEC_product) - ) - : (Proficient_Networks_Network_Policy_Engine_2.2 - :AdminInfo ( - :chkpf_uid ("{D0FD2531-1933-46C7-87CC-DBB691CB1B6E}") - :ClassName (OPSEC_product) - :table (products) - :LastModified ( - :Time ("Mon Sep 15 08:40:22 2003") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :NT_commands () - :commands () - :solaris_commands () - :AMON (true) - :AMON_class_name (default_opsec_status_object) - :CPMI (false) - :CVP (false) - :ELA (true) - :LEA (false) - :OMI (false) - :RTM (false) - :SAM (false) - :UAC (false) - :UFP (false) - :color (black) - :comments () - :product_info ( - :AdminInfo ( - :chkpf_uid ("{28F2187E-B387-4246-AF8D-C46A26DB75D2}") - :ClassName (OPSEC_product_info) - ) - :certification_info () - :certified (true) - :product (Network_Policy_Engine) - :vendor (Proficient_Networks) - :version (2.2) - ) - :type (OPSEC_product) - ) - : (Micromuse_NetCool_2.2 - :AdminInfo ( - :chkpf_uid ("{AF936F3A-87BE-4E98-9E6E-C85559D9E127}") - :ClassName (OPSEC_product) - :table (products) - :LastModified ( - :Time ("Mon Sep 15 08:43:04 2003") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :NT_commands () - :commands () - :solaris_commands () - :AMON (false) - :AMON_class_name (default_opsec_status_object) - :CPMI (false) - :CVP (false) - :ELA (false) - :LEA (true) - :OMI (false) - :RTM (false) - :SAM (false) - :UAC (false) - :UFP (false) - :color (black) - :comments () - :product_info ( - :AdminInfo ( - :chkpf_uid ("{661C391B-10C6-46FE-B22D-EF0393EF654B}") - :ClassName (OPSEC_product_info) - ) - :certification_info () - :certified (true) - :product (NetCool) - :vendor (Micromuse) - :version (2.2) - ) - :type (OPSEC_product) - ) - : (Websense_Enterprise_for_FireWall-1_5.0 - :AdminInfo ( - :chkpf_uid ("{708269B3-0DA5-4550-8CE5-E715F4C4D3B4}") - :ClassName (OPSEC_product) - :table (products) - :LastModified ( - :Time ("Mon Sep 15 08:45:26 2003") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :NT_commands () - :commands () - :solaris_commands () - :AMON (false) - :AMON_class_name (default_opsec_status_object) - :CPMI (false) - :CVP (false) - :ELA (false) - :LEA (false) - :OMI (false) - :RTM (false) - :SAM (false) - :UAC (false) - :UFP (true) - :color (black) - :comments () - :product_info ( - :AdminInfo ( - :chkpf_uid ("{28116254-C132-4EC1-8E49-84FE1E829DD4}") - :ClassName (OPSEC_product_info) - ) - :certification_info () - :certified (true) - :product (Enterprise_for_FireWall-1) - :vendor (Websense) - :version (5.0) - ) - :type (OPSEC_product) - ) - : (ForeScout_ActiveScout_2.7 - :AdminInfo ( - :chkpf_uid ("{315BCBAA-1D35-40BD-902C-3FFDE190FBCB}") - :ClassName (OPSEC_product) - :table (products) - :LastModified ( - :Time ("Mon Sep 15 08:49:17 2003") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :NT_commands () - :commands () - :solaris_commands () - :AMON (true) - :AMON_class_name (default_opsec_status_object) - :CPMI (false) - :CVP (false) - :ELA (true) - :LEA (false) - :OMI (false) - :RTM (false) - :SAM (true) - :UAC (false) - :UFP (false) - :color (black) - :comments () - :product_info ( - :AdminInfo ( - :chkpf_uid ("{175B4203-FE14-4AE7-B016-B2078FFB826E}") - :ClassName (OPSEC_product_info) - ) - :certification_info () - :certified (true) - :product (ActiveScout) - :vendor (ForeScout) - :version (2.7) - ) - :type (OPSEC_product) - ) - : (Rainfintiy_Rainwall_3.1 - :AdminInfo ( - :chkpf_uid ("{BA568194-BEF4-40FA-883A-388AFDB6CBF9}") - :ClassName (OPSEC_product) - :table (products) - :LastModified ( - :Time ("Mon Sep 15 08:52:02 2003") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :NT_commands () - :commands () - :solaris_commands () - :AMON (true) - :AMON_class_name (default_opsec_status_object) - :CPMI (true) - :CVP (false) - :ELA (true) - :LEA (false) - :OMI (false) - :RTM (false) - :SAM (false) - :UAC (false) - :UFP (false) - :color (black) - :comments () - :product_info ( - :AdminInfo ( - :chkpf_uid ("{A26B3A19-396C-4FEA-A4CD-B2AEAFAF14E7}") - :ClassName (OPSEC_product_info) - ) - :certification_info () - :certified (true) - :product (Rainwall) - :vendor (Rainfinity) - :version (3.1) - ) - :type (OPSEC_product) - ) - : (Sourcefire_Network_Sensor_2.5 - :AdminInfo ( - :chkpf_uid ("{86BC6AD3-097D-4F6D-8E2F-8E5BACA98F52}") - :ClassName (OPSEC_product) - :table (products) - :LastModified ( - :Time ("Mon Sep 15 08:54:44 2003") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :NT_commands () - :commands () - :solaris_commands () - :AMON (false) - :AMON_class_name (default_opsec_status_object) - :CPMI (false) - :CVP (false) - :ELA (false) - :LEA (false) - :OMI (false) - :RTM (false) - :SAM (true) - :UAC (false) - :UFP (false) - :color (black) - :comments () - :product_info ( - :AdminInfo ( - :chkpf_uid ("{6AC5B4CD-C4DA-4658-AFE6-5607F55B6EA7}") - :ClassName (OPSEC_product_info) - ) - :certification_info () - :certified (true) - :product (Network_Sensor) - :vendor (Sourcefire) - :version (2.5) - ) - :type (OPSEC_product) - ) - : (Aladdin_ESafe_Gateway_3.0 - :AdminInfo ( - :chkpf_uid ("{4BB6349F-A175-4E3F-8EE3-F81BB8B3E834}") - :ClassName (OPSEC_product) - :table (products) - :LastModified ( - :Time ("Sun Dec 30 11:36:41 2001") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :NT_commands () - :commands () - :solaris_commands () - :AMON (false) - :AMON_class_name (default_opsec_status_object) - :CPMI (false) - :CVP (true) - :ELA (false) - :LEA (false) - :OMI (false) - :RTM (false) - :SAM (false) - :UAC (false) - :UFP (false) - :color (black) - :comments () - :product_info ( - :AdminInfo ( - :chkpf_uid ("{CAC071E3-8788-4ACF-95F1-F9115142E871}") - :ClassName (OPSEC_product_info) - ) - :certification_info () - :certified (true) - :product (ESafe_Protect_Gateway) - :vendor (Aladdin_Knowledge_Systems) - :version (3.0) - ) - :type (OPSEC_product) - ) - : (Finjan_SurfinGate_5.6_NT - :AdminInfo ( - :chkpf_uid ("{581E4A3D-C37D-4C9F-8070-0E7BBFDED473}") - :ClassName (OPSEC_product) - :table (products) - :LastModified ( - :Time ("Sun Dec 30 11:36:41 2001") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :NT_commands () - :commands () - :solaris_commands () - :AMON (false) - :AMON_class_name (default_opsec_status_object) - :CPMI (false) - :CVP (true) - :ELA (false) - :LEA (false) - :OMI (false) - :RTM (false) - :SAM (false) - :UAC (false) - :UFP (false) - :color (black) - :comments () - :product_info ( - :AdminInfo ( - :chkpf_uid ("{3A847D56-AC20-438E-9EF1-B29045D58527}") - :ClassName (OPSEC_product_info) - ) - :certification_info () - :certified (true) - :product (SurfinGate) - :vendor (Finjan_Software) - :version (5.6) - ) - :type (OPSEC_product) - ) - : (TM_VirusWall_NT_3.5 - :AdminInfo ( - :chkpf_uid ("{28ED5FB8-B8BA-4623-943B-3764F248A55E}") - :ClassName (OPSEC_product) - :table (products) - :LastModified ( - :Time ("Sun Dec 30 11:36:41 2001") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :NT_commands () - :commands () - :solaris_commands () - :AMON (false) - :AMON_class_name (default_opsec_status_object) - :CPMI (false) - :CVP (true) - :ELA (false) - :LEA (false) - :OMI (false) - :RTM (false) - :SAM (false) - :UAC (false) - :UFP (false) - :color (black) - :comments () - :product_info ( - :AdminInfo ( - :chkpf_uid ("{59DD615D-4C31-4897-93E8-00466E9ED42F}") - :ClassName (OPSEC_product_info) - ) - :certification_info () - :certified (true) - :product (InterScan_VirusWall_for_NT) - :vendor (Trend_Micro) - :version (3.5) - ) - :type (OPSEC_product) - ) - : (TM_VirusWall_Solaris_3.6 - :AdminInfo ( - :chkpf_uid ("{80CDD43D-F7F8-475C-958D-D3CCF7BCEEFB}") - :ClassName (OPSEC_product) - :table (products) - :LastModified ( - :Time ("Sun Dec 30 11:36:41 2001") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :NT_commands () - :commands () - :solaris_commands () - :AMON (false) - :AMON_class_name (default_opsec_status_object) - :CPMI (false) - :CVP (true) - :ELA (false) - :LEA (false) - :OMI (false) - :RTM (false) - :SAM (false) - :UAC (false) - :UFP (false) - :color (black) - :comments () - :product_info ( - :AdminInfo ( - :chkpf_uid ("{1CB5277A-F5A4-4F8D-AC60-B6F3D67BAF3B}") - :ClassName (OPSEC_product_info) - ) - :certification_info () - :certified (true) - :product (InterScan_VirusWall_for_Solaris) - :vendor (Trend_Micro) - :version (3.6) - ) - :type (OPSEC_product) - ) - : (WebWasher_EE_Linux_3.1 - :AdminInfo ( - :chkpf_uid ("{B8954622-E780-46DB-8E0B-50DA720721E1}") - :ClassName (OPSEC_product) - :table (products) - :LastModified ( - :Time ("Sun Dec 30 11:36:41 2001") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :NT_commands () - :commands () - :solaris_commands () - :AMON (false) - :AMON_class_name (default_opsec_status_object) - :CPMI (false) - :CVP (true) - :ELA (false) - :LEA (false) - :OMI (false) - :RTM (false) - :SAM (false) - :UAC (false) - :UFP (true) - :color (black) - :comments () - :product_info ( - :AdminInfo ( - :chkpf_uid ("{F05C21CD-6929-425B-AEB0-5E6F97E8C0AE}") - :ClassName (OPSEC_product_info) - ) - :certification_info () - :certified (true) - :product (WebWasher_EE_Linux) - :vendor (WebWasher) - :version (3.1) - ) - :type (OPSEC_product) - ) - : (SecureWatch - :AdminInfo ( - :chkpf_uid ("{DF11985A-C890-48D3-ADE2-1F60A5DEEAC4}") - :ClassName (OPSEC_product) - :table (products) - :LastModified ( - :Time ("Sun Dec 30 11:36:41 2001") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :NT_commands () - :commands () - :solaris_commands () - :AMON (false) - :AMON_class_name (default_opsec_status_object) - :CPMI (false) - :CVP (false) - :ELA (true) - :LEA (false) - :OMI (false) - :RTM (false) - :SAM (false) - :UAC (false) - :UFP (false) - :color (black) - :comments () - :product_info ( - :AdminInfo ( - :chkpf_uid ("{B7CABFFA-EF0A-4C62-8878-3D27791B43AA}") - :ClassName (OPSEC_product_info) - ) - :certification_info () - :certified (true) - :product (SecureWatchfor_W2K) - :vendor (TopLayer_Networks) - :version (1.11) - ) - :type (OPSEC_product) - ) - : (Entercept_Integrator_1.03 - :AdminInfo ( - :chkpf_uid ("{05F22C3A-F03E-490A-BC64-DA2B88596D92}") - :ClassName (OPSEC_product) - :table (products) - :LastModified ( - :Time ("Sun Dec 30 11:36:42 2001") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :NT_commands () - :commands () - :solaris_commands () - :AMON (false) - :AMON_class_name (default_opsec_status_object) - :CPMI (false) - :CVP (false) - :ELA (true) - :LEA (false) - :OMI (false) - :RTM (false) - :SAM (false) - :UAC (false) - :UFP (false) - :color (black) - :comments () - :product_info ( - :AdminInfo ( - :chkpf_uid ("{2CBABE45-6A56-48FB-A844-3C86D4E4080F}") - :ClassName (OPSEC_product_info) - ) - :certification_info () - :certified (true) - :product (Integrator_for_Check_Point) - :vendor (Entercept_Security_Technologies) - :version (1.03) - ) - :type (OPSEC_product) - ) - : (VigilEnt_Security_Agent_for_FW1 - :AdminInfo ( - :chkpf_uid ("{EDA9A2A2-E238-44F0-8C4F-50FECB4245AA}") - :ClassName (OPSEC_product) - :table (products) - :LastModified ( - :Time ("Sun Dec 30 11:36:42 2001") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :NT_commands () - :commands () - :solaris_commands () - :AMON (false) - :AMON_class_name (default_opsec_status_object) - :CPMI (false) - :CVP (false) - :ELA (true) - :LEA (false) - :OMI (false) - :RTM (false) - :SAM (true) - :UAC (false) - :UFP (false) - :color (black) - :comments () - :product_info ( - :AdminInfo ( - :chkpf_uid ("{8F748A3B-A7D4-4D9B-9570-B8C7514B00F4}") - :ClassName (OPSEC_product_info) - ) - :certification_info () - :certified (true) - :product (VigilEnt_Security_Agent) - :vendor (PentaSafe_Security_Technologies) - :version (1.0) - ) - :type (OPSEC_product) - ) - : (SecoShield_2.0 - :AdminInfo ( - :chkpf_uid ("{8FCB396C-8F37-4AF1-A771-F79C20A734FC}") - :ClassName (OPSEC_product) - :table (products) - :LastModified ( - :Time ("Sun Dec 30 11:36:42 2001") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :NT_commands () - :commands () - :solaris_commands () - :AMON (false) - :AMON_class_name (default_opsec_status_object) - :CPMI (false) - :CVP (false) - :ELA (false) - :LEA (false) - :OMI (false) - :RTM (false) - :SAM (true) - :UAC (false) - :UFP (false) - :color (black) - :comments () - :product_info ( - :AdminInfo ( - :chkpf_uid ("{D23690F2-1004-4050-91C3-13684C56626F}") - :ClassName (OPSEC_product_info) - ) - :certification_info () - :certified (true) - :product (SecoShield_2.0) - :vendor (INFOSEC_Technologies) - :version (2.0) - ) - :type (OPSEC_product) - ) - : (N2H2_Filtering_FW1 - :AdminInfo ( - :chkpf_uid ("{6313C1EB-AEA2-4923-A310-E5E018D0CB0C}") - :ClassName (OPSEC_product) - :table (products) - :LastModified ( - :Time ("Sun Dec 30 11:36:42 2001") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :NT_commands () - :commands () - :solaris_commands () - :AMON (false) - :AMON_class_name (default_opsec_status_object) - :CPMI (false) - :CVP (false) - :ELA (false) - :LEA (false) - :OMI (false) - :RTM (false) - :SAM (false) - :UAC (false) - :UFP (true) - :color (black) - :comments () - :product_info ( - :AdminInfo ( - :chkpf_uid ("{D1D8E27B-6B13-4961-9F2B-0CB800AE04EB}") - :ClassName (OPSEC_product_info) - ) - :certification_info () - :certified (true) - :product (N2H2_Filtering_NT) - :vendor (N2H2) - :version (1.0) - ) - :type (OPSEC_product) - ) - : (SecureComputing_SmartFilter_2.1 - :AdminInfo ( - :chkpf_uid ("{406D3171-2CF2-4FFA-8C32-3A9DB53D0690}") - :ClassName (OPSEC_product) - :table (products) - :LastModified ( - :Time ("Sun Dec 30 11:36:43 2001") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :NT_commands () - :commands () - :solaris_commands () - :AMON (false) - :AMON_class_name (default_opsec_status_object) - :CPMI (false) - :CVP (false) - :ELA (false) - :LEA (false) - :OMI (false) - :RTM (false) - :SAM (false) - :UAC (false) - :UFP (true) - :color (black) - :comments () - :product_info ( - :AdminInfo ( - :chkpf_uid ("{7ED208A5-8DF4-47A0-A70A-E5DA135718D4}") - :ClassName (OPSEC_product_info) - ) - :certification_info () - :certified (true) - :product (Smart_Filter) - :vendor (Secure_Computing) - :version (2.1) - ) - :type (OPSEC_product) - ) - : (SurfControl_SuperScout_FW1_2.1 - :AdminInfo ( - :chkpf_uid ("{DFB6904F-584B-4FDC-9048-B6EFC2C47AD2}") - :ClassName (OPSEC_product) - :table (products) - :LastModified ( - :Time ("Sun Dec 30 11:36:43 2001") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :NT_commands () - :commands () - :solaris_commands () - :AMON (false) - :AMON_class_name (default_opsec_status_object) - :CPMI (false) - :CVP (false) - :ELA (false) - :LEA (false) - :OMI (false) - :RTM (false) - :SAM (false) - :UAC (false) - :UFP (true) - :color (black) - :comments () - :product_info ( - :AdminInfo ( - :chkpf_uid ("{77AE98F8-845F-4BE1-90F5-04A09C12040A}") - :ClassName (OPSEC_product_info) - ) - :certification_info () - :certified (true) - :product (SuperScout_for_FireWall) - :vendor (SurfControl) - :version (2.1) - ) - :type (OPSEC_product) - ) - : (WebSense_FW1_4.3 - :AdminInfo ( - :chkpf_uid ("{D2E3E730-EA2E-4A31-B689-436B5D0494DB}") - :ClassName (OPSEC_product) - :table (products) - :LastModified ( - :Time ("Sun Dec 30 11:36:43 2001") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :NT_commands () - :commands () - :solaris_commands () - :AMON (false) - :AMON_class_name (default_opsec_status_object) - :CPMI (false) - :CVP (false) - :ELA (false) - :LEA (false) - :OMI (false) - :RTM (false) - :SAM (false) - :UAC (false) - :UFP (true) - :color (black) - :comments () - :product_info ( - :AdminInfo ( - :chkpf_uid ("{A09058AD-B5A9-4E51-902D-18CCC8356D88}") - :ClassName (OPSEC_product_info) - ) - :certification_info () - :certified (true) - :product (WebSense_for_FireWall-1) - :vendor (WebSense) - :version (4.3) - ) - :type (OPSEC_product) - ) - : (OpenService_SystemWatch_2.63 - :AdminInfo ( - :chkpf_uid ("{C0BDCDCD-3FB6-4FA3-9156-A018891014E4}") - :ClassName (OPSEC_product) - :table (products) - :LastModified ( - :Time ("Sun Dec 30 11:36:43 2001") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :NT_commands () - :commands () - :solaris_commands () - :AMON (false) - :AMON_class_name (default_opsec_status_object) - :CPMI (false) - :CVP (false) - :ELA (false) - :LEA (true) - :OMI (false) - :RTM (false) - :SAM (false) - :UAC (false) - :UFP (false) - :color (black) - :comments () - :product_info ( - :AdminInfo ( - :chkpf_uid ("{0165BA91-6330-496C-A49A-CA8BE943069A}") - :ClassName (OPSEC_product_info) - ) - :certification_info () - :certified (true) - :product (SystemWatch) - :vendor (OpenService) - :version (2.63) - ) - :type (OPSEC_product) - ) - : (OpenSystems_Private_I_6420 - :AdminInfo ( - :chkpf_uid ("{73C6C1FF-5DFF-4F59-AB9D-8529A8C0F87F}") - :ClassName (OPSEC_product) - :table (products) - :LastModified ( - :Time ("Sun Dec 30 11:36:43 2001") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :NT_commands () - :commands () - :solaris_commands () - :AMON (false) - :AMON_class_name (default_opsec_status_object) - :CPMI (false) - :CVP (false) - :ELA (false) - :LEA (true) - :OMI (false) - :RTM (false) - :SAM (false) - :UAC (false) - :UFP (false) - :color (black) - :comments () - :product_info ( - :AdminInfo ( - :chkpf_uid ("{28BDF40C-8959-4DA1-B885-F4A2FBAD1AF8}") - :ClassName (OPSEC_product_info) - ) - :certification_info (NG-Compatible) - :certified (true) - :product (Private_I_Intelligence_Suite) - :vendor (OpenSystems.com) - :version (6420) - ) - :type (OPSEC_product) - ) - : (WebTrends_Firewall_3.0 - :AdminInfo ( - :chkpf_uid ("{518896A3-7E38-4FB6-9EEE-3FA990AC8763}") - :ClassName (OPSEC_product) - :table (products) - :LastModified ( - :Time ("Sun Dec 30 11:36:43 2001") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :NT_commands () - :commands () - :solaris_commands () - :AMON (false) - :AMON_class_name (default_opsec_status_object) - :CPMI (false) - :CVP (false) - :ELA (false) - :LEA (true) - :OMI (false) - :RTM (false) - :SAM (false) - :UAC (false) - :UFP (false) - :color (black) - :comments () - :product_info ( - :AdminInfo ( - :chkpf_uid ("{622728CE-F3A5-4242-B50A-641279B43867}") - :ClassName (OPSEC_product_info) - ) - :certification_info () - :certified (true) - :product (WebTrends_Firewall_Suite) - :vendor (NetIQ) - :version (3.0a) - ) - :type (OPSEC_product) - ) - : (G_Server_ELA_Module_1.51 - :AdminInfo ( - :chkpf_uid ("{F6EC787D-C321-41BC-BFF9-9DB0A5984472}") - :ClassName (OPSEC_product) - :table (products) - :LastModified ( - :Time ("Sun Dec 30 11:36:44 2001") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :NT_commands () - :commands () - :solaris_commands () - :AMON (false) - :AMON_class_name (default_opsec_status_object) - :CPMI (false) - :CVP (false) - :ELA (true) - :LEA (false) - :OMI (false) - :RTM (false) - :SAM (false) - :UAC (false) - :UFP (false) - :color (black) - :comments () - :product_info ( - :AdminInfo ( - :chkpf_uid ("{3645A004-C3C0-4804-800A-C31096DCB83A}") - :ClassName (OPSEC_product_info) - ) - :certification_info () - :certified (true) - :product (G_Server_Appliance) - :vendor (Gilian) - :version (1.51) - ) - :type (OPSEC_product) - ) - : (SPiDER-1_for_FireWall-1_1.5 - :AdminInfo ( - :chkpf_uid ("{7410F783-733E-47F3-BE86-F75762A013B1}") - :ClassName (OPSEC_product) - :table (products) - :LastModified ( - :Time ("Sun Dec 30 11:36:44 2001") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :NT_commands () - :commands () - :solaris_commands () - :AMON (false) - :AMON_class_name (default_opsec_status_object) - :CPMI (false) - :CVP (false) - :ELA (false) - :LEA (true) - :OMI (false) - :RTM (false) - :SAM (false) - :UAC (false) - :UFP (false) - :color (black) - :comments () - :product_info ( - :AdminInfo ( - :chkpf_uid ("{511EE6E0-062A-42AE-9BB5-8112C9A086B0}") - :ClassName (OPSEC_product_info) - ) - :certification_info () - :certified (true) - :product (SPiDER-1) - :vendor ("Igloo Security") - :version (1.5) - ) - :type (OPSEC_product) - ) - : (netForensics_agent_for_FireWall-1_2.3 - :AdminInfo ( - :chkpf_uid ("{1408C2EC-55E1-48E4-B30F-FA57B9A9A296}") - :ClassName (OPSEC_product) - :table (products) - :LastModified ( - :Time ("Sun Dec 30 11:36:44 2001") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :NT_commands () - :commands () - :solaris_commands () - :AMON (false) - :AMON_class_name (default_opsec_status_object) - :CPMI (false) - :CVP (false) - :ELA (false) - :LEA (true) - :OMI (false) - :RTM (false) - :SAM (false) - :UAC (false) - :UFP (false) - :color (black) - :comments () - :product_info ( - :AdminInfo ( - :chkpf_uid ("{4735633B-A973-4063-8275-2A368974FDF3}") - :ClassName (OPSEC_product_info) - ) - :certification_info () - :certified (true) - :product (netForensics) - :vendor (netForensics) - :version (2.3) - ) - :type (OPSEC_product) - ) - : (AppManager_for_FireWall-1 - :AdminInfo ( - :chkpf_uid ("{DB381B83-1437-49DF-9D31-FF09AA4C7AD3}") - :ClassName (OPSEC_product) - :table (products) - :LastModified ( - :Time ("Sun Dec 30 11:36:44 2001") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :NT_commands () - :commands () - :solaris_commands () - :AMON (false) - :AMON_class_name (default_opsec_status_object) - :CPMI (false) - :CVP (false) - :ELA (false) - :LEA (true) - :OMI (true) - :RTM (false) - :SAM (false) - :UAC (false) - :UFP (false) - :color (black) - :comments () - :product_info ( - :AdminInfo ( - :chkpf_uid ("{9398256E-B09C-4EC3-9058-7F224456D415}") - :ClassName (OPSEC_product_info) - ) - :certification_info () - :certified (true) - :product (NetIQ) - :vendor (NetIQ) - :version (1.0) - ) - :type (OPSEC_product) - ) - : (FireMon_1.0 - :AdminInfo ( - :chkpf_uid ("{EB771FBB-70FC-4F68-8152-D8B8460D5C6F}") - :ClassName (OPSEC_product) - :table (products) - :LastModified ( - :Time ("Sun Dec 30 11:36:44 2001") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :NT_commands () - :commands () - :solaris_commands () - :AMON (false) - :AMON_class_name (default_opsec_status_object) - :CPMI (false) - :CVP (false) - :ELA (false) - :LEA (false) - :OMI (true) - :RTM (false) - :SAM (false) - :UAC (false) - :UFP (false) - :color (black) - :comments () - :product_info ( - :AdminInfo ( - :chkpf_uid ("{35F9775B-3553-45EA-AD18-26771CF94F08}") - :ClassName (OPSEC_product_info) - ) - :certification_info () - :certified (true) - :product (FireMon) - :vendor ("FishNet Security") - :version (1.0) - ) - :type (OPSEC_product) - ) - : (Oblix_NetPoint_4.6 - :AdminInfo ( - :chkpf_uid ("{DFAB534E-6BC0-463D-B579-E69B5FC61240}") - :ClassName (OPSEC_product) - :table (products) - :LastModified ( - :Time ("Sun Dec 30 11:36:45 2001") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :NT_commands () - :commands () - :solaris_commands () - :AMON (false) - :AMON_class_name (default_opsec_status_object) - :CPMI (false) - :CVP (false) - :ELA (false) - :LEA (false) - :OMI (false) - :RTM (false) - :SAM (false) - :UAC (true) - :UFP (false) - :color (black) - :comments () - :product_info ( - :AdminInfo ( - :chkpf_uid ("{57410EA9-7C70-465B-A44C-99E03876E9F3}") - :ClassName (OPSEC_product_info) - ) - :certification_info () - :certified (true) - :product (NetPoint_Authentication_Adapter) - :vendor (Oblix) - :version (4.6) - ) - :type (OPSEC_product) - ) - : (Protegrity_Secure.Data_10.222.0.70 - :AdminInfo ( - :chkpf_uid ("{D8366FEB-B48F-47C6-99E8-15A2D9670F89}") - :ClassName (OPSEC_product) - :table (products) - :LastModified ( - :Time ("Sun Dec 30 11:36:45 2001") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :NT_commands () - :commands () - :solaris_commands () - :AMON (false) - :AMON_class_name (default_opsec_status_object) - :CPMI (false) - :CVP (false) - :ELA (false) - :LEA (false) - :OMI (false) - :RTM (false) - :SAM (false) - :UAC (true) - :UFP (false) - :color (black) - :comments () - :product_info ( - :AdminInfo ( - :chkpf_uid ("{C5059AA0-8F27-43FC-B430-23D47DB03218}") - :ClassName (OPSEC_product_info) - ) - :certification_info (NT-Version) - :certified (true) - :product (Secure.Data) - :vendor (Protegrity) - :version (10.222.0.70) - ) - :type (OPSEC_product) - ) - : (Protegrity_Secure.Data_10.222.0.71 - :AdminInfo ( - :chkpf_uid ("{4EE7B65C-3574-4EE6-A9F3-91602909F8C9}") - :ClassName (OPSEC_product) - :table (products) - :LastModified ( - :Time ("Sun Dec 30 11:36:45 2001") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :NT_commands () - :commands () - :solaris_commands () - :AMON (false) - :AMON_class_name (default_opsec_status_object) - :CPMI (false) - :CVP (false) - :ELA (false) - :LEA (false) - :OMI (false) - :RTM (false) - :SAM (false) - :UAC (true) - :UFP (false) - :color (black) - :comments () - :product_info ( - :AdminInfo ( - :chkpf_uid ("{E6998505-4126-4A3E-AC5C-297804808410}") - :ClassName (OPSEC_product_info) - ) - :certification_info (Solaris-Version) - :certified (true) - :product (Secure.Data) - :vendor (Protegrity) - :version (10.222.0.71) - ) - :type (OPSEC_product) - ) - : (ACESwitch_ACEDirector - :AdminInfo ( - :chkpf_uid ("{811545CB-804A-4BA7-942B-75211682D4C3}") - :ClassName (OPSEC_product) - :table (products) - :LastModified ( - :Time ("Sun Dec 30 11:36:45 2001") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :NT_commands () - :commands () - :solaris_commands () - :AMON (false) - :AMON_class_name (default_opsec_status_object) - :CPMI (false) - :CVP (false) - :ELA (true) - :LEA (false) - :OMI (false) - :RTM (false) - :SAM (false) - :UAC (false) - :UFP (false) - :color (black) - :comments () - :product_info ( - :AdminInfo ( - :chkpf_uid ("{6242753E-9464-47E6-A05E-4A9980A60EFA}") - :ClassName (OPSEC_product_info) - ) - :certification_info () - :certified (true) - :product ("ACESwitch & ACEDirector") - :vendor (Nortel) - :version ("Web OS 8.3 (firmware)") - ) - :type (OPSEC_product) - ) - : (Internet_Ironware - :AdminInfo ( - :chkpf_uid ("{3229CD03-370D-4C91-B6E7-74534768EEB9}") - :ClassName (OPSEC_product) - :table (products) - :LastModified ( - :Time ("Sun Dec 30 11:36:45 2001") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :NT_commands () - :commands () - :solaris_commands () - :AMON (false) - :AMON_class_name (default_opsec_status_object) - :CPMI (false) - :CVP (false) - :ELA (true) - :LEA (false) - :OMI (false) - :RTM (false) - :SAM (false) - :UAC (false) - :UFP (false) - :color (black) - :comments () - :product_info ( - :AdminInfo ( - :chkpf_uid ("{B5EEB358-4DE3-4DAB-B4EF-BC63ED1D8931}") - :ClassName (OPSEC_product_info) - ) - :certification_info (4.1) - :certified (true) - :product (ServerIron) - :vendor ("Foundry Networks") - :version ("7.1 (firmware)") - ) - :type (OPSEC_product) - ) - : (FireProof_2.0 - :AdminInfo ( - :chkpf_uid ("{5350D161-61B1-4343-A938-34D2CDD80EEB}") - :ClassName (OPSEC_product) - :table (products) - :LastModified ( - :Time ("Sun Dec 30 11:36:45 2001") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :NT_commands () - :commands () - :solaris_commands () - :AMON (false) - :AMON_class_name (default_opsec_status_object) - :CPMI (false) - :CVP (false) - :ELA (true) - :LEA (false) - :OMI (false) - :RTM (false) - :SAM (false) - :UAC (false) - :UFP (false) - :color (black) - :comments () - :product_info ( - :AdminInfo ( - :chkpf_uid ("{F6B045C9-A796-48D7-B749-95DB577E3D9A}") - :ClassName (OPSEC_product_info) - ) - :certification_info (4.1) - :certified (true) - :product (FireProof) - :vendor (Radware) - :version (2.0) - ) - :type (OPSEC_product) - ) - : (FireProof_2.3 - :AdminInfo ( - :chkpf_uid ("{504E8A0D-2F89-471C-9F66-F32547CBE3F7}") - :ClassName (OPSEC_product) - :table (products) - :LastModified ( - :Time ("Sun Dec 30 11:36:46 2001") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :NT_commands () - :commands () - :solaris_commands () - :AMON (false) - :AMON_class_name (default_opsec_status_object) - :CPMI (false) - :CVP (false) - :ELA (true) - :LEA (false) - :OMI (false) - :RTM (false) - :SAM (false) - :UAC (false) - :UFP (false) - :color (black) - :comments () - :product_info ( - :AdminInfo ( - :chkpf_uid ("{06B4CA81-C14B-4C05-ACFB-A50CB599BF79}") - :ClassName (OPSEC_product_info) - ) - :certification_info (NG) - :certified (true) - :product (FireProof) - :vendor (Radware) - :version (2.3) - ) - :type (OPSEC_product) - ) - : (Rainwall_E_1.6 - :AdminInfo ( - :chkpf_uid ("{E8AE9F2F-5613-4B88-B376-F8FFCE0EF08B}") - :ClassName (OPSEC_product) - :table (products) - :LastModified ( - :Time ("Sun Dec 30 11:36:46 2001") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :NT_commands () - :commands () - :solaris_commands () - :AMON (false) - :AMON_class_name (default_opsec_status_object) - :CPMI (false) - :CVP (false) - :ELA (true) - :LEA (false) - :OMI (false) - :RTM (false) - :SAM (false) - :UAC (false) - :UFP (false) - :color (black) - :comments () - :product_info ( - :AdminInfo ( - :chkpf_uid ("{76587B88-1D16-405B-B28F-16E74B8968C8}") - :ClassName (OPSEC_product_info) - ) - :certification_info ("NG - Solaris") - :certified (true) - :product ("Rainwall E") - :vendor (Rainfinity) - :version (1.6) - ) - :type (OPSEC_product) - ) - : (Rainwall_E_1.5.1B30 - :AdminInfo ( - :chkpf_uid ("{731F7841-A16A-4221-BB44-DDDC9E64432F}") - :ClassName (OPSEC_product) - :table (products) - :LastModified ( - :Time ("Sun Dec 30 11:36:46 2001") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :NT_commands () - :commands () - :solaris_commands () - :AMON (false) - :AMON_class_name (default_opsec_status_object) - :CPMI (false) - :CVP (false) - :ELA (true) - :LEA (false) - :OMI (false) - :RTM (false) - :SAM (false) - :UAC (false) - :UFP (false) - :color (black) - :comments () - :product_info ( - :AdminInfo ( - :chkpf_uid ("{2311F091-0329-406B-BE92-93F13AC351DD}") - :ClassName (OPSEC_product_info) - ) - :certification_info ("4.1 - Solaris") - :certified (true) - :product ("Rainwall E") - :vendor (Rainfinity) - :version ("1.5.1 bld_30") - ) - :type (OPSEC_product) - ) - : (Rainwall_E_1.5SP3 - :AdminInfo ( - :chkpf_uid ("{FBEA2DB3-5FA0-4E09-96A8-150F404B52D9}") - :ClassName (OPSEC_product) - :table (products) - :LastModified ( - :Time ("Sun Dec 30 11:36:46 2001") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :NT_commands () - :commands () - :solaris_commands () - :AMON (false) - :AMON_class_name (default_opsec_status_object) - :CPMI (false) - :CVP (false) - :ELA (true) - :LEA (false) - :OMI (false) - :RTM (false) - :SAM (false) - :UAC (false) - :UFP (false) - :color (black) - :comments () - :product_info ( - :AdminInfo ( - :chkpf_uid ("{78D963B6-0668-4159-BB1F-ACC287C55949}") - :ClassName (OPSEC_product_info) - ) - :certification_info ("4.1 - Linux") - :certified (true) - :product ("Rainwall E") - :vendor (Rainfinity) - :version ("1.5 SP3") - ) - :type (OPSEC_product) - ) - : (StoneBeat_FullCluster_1.0SP4 - :AdminInfo ( - :chkpf_uid ("{3FA44973-4658-459A-8665-234474316BF9}") - :ClassName (OPSEC_product) - :table (products) - :LastModified ( - :Time ("Sun Dec 30 11:36:46 2001") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :NT_commands () - :commands () - :solaris_commands () - :AMON (false) - :AMON_class_name (default_opsec_status_object) - :CPMI (false) - :CVP (false) - :ELA (true) - :LEA (false) - :OMI (false) - :RTM (false) - :SAM (false) - :UAC (false) - :UFP (false) - :color (black) - :comments () - :product_info ( - :AdminInfo ( - :chkpf_uid ("{B8A93E68-E662-4FD1-BA90-098D50FC3131}") - :ClassName (OPSEC_product_info) - ) - :certification_info ("4.1 - NT") - :certified (true) - :product ("StoneBeat FullCluster") - :vendor (StoneSoft) - :version ("1.0 SP4") - ) - :type (OPSEC_product) - ) - : (StoneBeat_FullCluster_2.0SP1a - :AdminInfo ( - :chkpf_uid ("{9034BDEC-687B-4EF4-8BAB-CAA1A68CD94C}") - :ClassName (OPSEC_product) - :table (products) - :LastModified ( - :Time ("Sun Dec 30 11:36:47 2001") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :NT_commands () - :commands () - :solaris_commands () - :AMON (false) - :AMON_class_name (default_opsec_status_object) - :CPMI (false) - :CVP (false) - :ELA (true) - :LEA (false) - :OMI (false) - :RTM (false) - :SAM (false) - :UAC (false) - :UFP (false) - :color (black) - :comments () - :product_info ( - :AdminInfo ( - :chkpf_uid ("{EB1EC9B3-2391-43F8-A82B-5E348A860A36}") - :ClassName (OPSEC_product_info) - ) - :certification_info ("4.1 - Solaris") - :certified (true) - :product ("StoneBeat FullCluster") - :vendor (StoneSoft) - :version ("2.0 SP1a") - ) - :type (OPSEC_product) - ) - : (StoneBeat_FullCluster_2.0SP3a - :AdminInfo ( - :chkpf_uid ("{2AA5E5B8-1A6F-48FA-887E-89FA4F415013}") - :ClassName (OPSEC_product) - :table (products) - :LastModified ( - :Time ("Sun Dec 30 11:36:47 2001") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :NT_commands () - :commands () - :solaris_commands () - :AMON (false) - :AMON_class_name (default_opsec_status_object) - :CPMI (false) - :CVP (false) - :ELA (true) - :LEA (false) - :OMI (false) - :RTM (false) - :SAM (false) - :UAC (false) - :UFP (false) - :color (black) - :comments () - :product_info ( - :AdminInfo ( - :chkpf_uid ("{25E4373E-366C-403F-BE37-A9966E229B4A}") - :ClassName (OPSEC_product_info) - ) - :certification_info ("4.1 - Linux") - :certified (true) - :product ("StoneBeat FullCluster") - :vendor (StoneSoft) - :version ("2.0 SP3a") - ) - :type (OPSEC_product) - ) - : (Cluster_Module - :AdminInfo ( - :chkpf_uid ("{35B03287-3CFE-490D-AF3F-021C81290C0F}") - :ClassName (OPSEC_product) - :table (products) - :LastModified ( - :Time ("Sun Dec 30 11:36:47 2001") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :NT_commands () - :commands () - :solaris_commands () - :AMON (false) - :AMON_class_name (default_opsec_status_object) - :CPMI (false) - :CVP (false) - :ELA (true) - :LEA (false) - :OMI (false) - :RTM (false) - :SAM (false) - :UAC (false) - :UFP (false) - :color (black) - :comments () - :product_info ( - :AdminInfo ( - :chkpf_uid ("{5351C8A6-729A-4218-88C3-71F8DFFD3BD9}") - :ClassName (OPSEC_product_info) - ) - :certification_info ("4.1 - Solaris") - :certified (true) - :product ("Cluster Module") - :vendor (Legato) - :version (4.5.1) - ) - :type (OPSEC_product) - ) - : (Rainwall_S_1.5SP3 - :AdminInfo ( - :chkpf_uid ("{5669559C-9DDE-47A6-8B7C-2C25B7AF1369}") - :ClassName (OPSEC_product) - :table (products) - :LastModified ( - :Time ("Sun Dec 30 11:36:47 2001") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :NT_commands () - :commands () - :solaris_commands () - :AMON (false) - :AMON_class_name (default_opsec_status_object) - :CPMI (false) - :CVP (false) - :ELA (true) - :LEA (false) - :OMI (false) - :RTM (false) - :SAM (false) - :UAC (false) - :UFP (false) - :color (black) - :comments () - :product_info ( - :AdminInfo ( - :chkpf_uid ("{FAA94964-72A8-4A07-8CBF-36BEB80567A5}") - :ClassName (OPSEC_product_info) - ) - :certification_info ("4.1 - Linux") - :certified (true) - :product ("Rainwall S") - :vendor (Rainfinity) - :version ("1.5 SP3") - ) - :type (OPSEC_product) - ) - : (Rainwall_S_1.6 - :AdminInfo ( - :chkpf_uid ("{E7805555-6AC4-415A-A52C-5136CD615825}") - :ClassName (OPSEC_product) - :table (products) - :LastModified ( - :Time ("Sun Dec 30 11:36:47 2001") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :NT_commands () - :commands () - :solaris_commands () - :AMON (false) - :AMON_class_name (default_opsec_status_object) - :CPMI (false) - :CVP (false) - :ELA (true) - :LEA (false) - :OMI (false) - :RTM (false) - :SAM (false) - :UAC (false) - :UFP (false) - :color (black) - :comments () - :product_info ( - :AdminInfo ( - :chkpf_uid ("{62B33292-8DEA-4E1A-B00D-B2E8256454EA}") - :ClassName (OPSEC_product_info) - ) - :certification_info ("4.1 - Solaris") - :certified (true) - :product ("Rainwall S") - :vendor (Rainfinity) - :version ("1.6 (B17)") - ) - :type (OPSEC_product) - ) - : (StoneBeat_3.1.5 - :AdminInfo ( - :chkpf_uid ("{A3D052A0-6B29-4F16-84AC-FAEF14EE3032}") - :ClassName (OPSEC_product) - :table (products) - :LastModified ( - :Time ("Sun Dec 30 11:36:47 2001") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :NT_commands () - :commands () - :solaris_commands () - :AMON (false) - :AMON_class_name (default_opsec_status_object) - :CPMI (false) - :CVP (false) - :ELA (true) - :LEA (false) - :OMI (false) - :RTM (false) - :SAM (false) - :UAC (false) - :UFP (false) - :color (black) - :comments () - :product_info ( - :AdminInfo ( - :chkpf_uid ("{E15026F1-B13D-4AC0-818E-D2647B9990E1}") - :ClassName (OPSEC_product_info) - ) - :certification_info (4.1) - :certified (true) - :product (StoneBeat) - :vendor (StoneSoft) - :version (3.1.5) - ) - :type (OPSEC_product) - ) - : (Enterprise_Agent_for_CP_FW-1 - :AdminInfo ( - :chkpf_uid ("{20299E8D-B931-4419-BAC7-0C24CC4EFF8F}") - :ClassName (OPSEC_product) - :table (products) - :LastModified ( - :Time ("Sun Dec 30 11:36:48 2001") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :NT_commands () - :commands () - :solaris_commands () - :AMON (false) - :AMON_class_name (default_opsec_status_object) - :CPMI (false) - :CVP (false) - :ELA (true) - :LEA (false) - :OMI (false) - :RTM (false) - :SAM (false) - :UAC (false) - :UFP (false) - :color (black) - :comments () - :product_info ( - :AdminInfo ( - :chkpf_uid ("{3E4FB236-21BF-495E-A34F-F88E23F5E5C9}") - :ClassName (OPSEC_product_info) - ) - :certification_info (4.1) - :certified (true) - :product ("Enterprise Agent for CP FW-1") - :vendor ("Veritas Software Corp") - :version (1.3) - ) - :type (OPSEC_product) - ) - : (UserDefinedProduct - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB58D-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (OPSEC_product) - :table (products) - ) - :NT_commands () - :commands () - :solaris_commands () - :AMON (false) - :AMON_class_name (default_opsec_status_object) - :CPMI (false) - :CVP (false) - :ELA (false) - :LEA (false) - :OMI (false) - :RTM (false) - :SAM (false) - :UAC (false) - :UFP (false) - :color (black) - :comments () - :product_info ( - :AdminInfo ( - :chkpf_uid ("{97AEB58E-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (OPSEC_product_info) - ) - :certification_info () - :certified (false) - :product () - :vendor ("User defined") - :version () - ) - :type (OPSEC_product) - ) - : (Aladdin_ESafe_Gateway_2.1 - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB590-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (OPSEC_product) - :table (products) - ) - :NT_commands () - :commands () - :solaris_commands () - :AMON (false) - :AMON_class_name (default_opsec_status_object) - :CPMI (false) - :CVP (true) - :ELA (false) - :LEA (false) - :OMI (false) - :RTM (false) - :SAM (false) - :UAC (false) - :UFP (false) - :color (black) - :comments () - :product_info ( - :AdminInfo ( - :chkpf_uid ("{97AEB591-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (OPSEC_product_info) - ) - :certification_info () - :certified (true) - :product (ESafe_Protect_Gateway) - :vendor (Aladdin_Knowledge_Systems) - :version (2.1) - ) - :type (OPSEC_product) - ) - : (Aliroo_PrivaWall_1.1 - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB593-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (OPSEC_product) - :table (products) - ) - :NT_commands () - :commands () - :solaris_commands () - :AMON (false) - :AMON_class_name (default_opsec_status_object) - :CPMI (false) - :CVP (true) - :ELA (false) - :LEA (false) - :OMI (false) - :RTM (false) - :SAM (false) - :UAC (false) - :UFP (false) - :color (black) - :comments () - :product_info ( - :AdminInfo ( - :chkpf_uid ("{97AEB594-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (OPSEC_product_info) - ) - :certification_info () - :certified (true) - :product (PrivaWALL) - :vendor (Aliroo) - :version (1.1) - ) - :type (OPSEC_product) - ) - : (CA_SafeGate_2.2 - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB596-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (OPSEC_product) - :table (products) - ) - :NT_commands () - :commands () - :solaris_commands () - :AMON (false) - :AMON_class_name (default_opsec_status_object) - :CPMI (false) - :CVP (true) - :ELA (false) - :LEA (false) - :OMI (false) - :RTM (false) - :SAM (false) - :UAC (false) - :UFP (false) - :color (black) - :comments () - :product_info ( - :AdminInfo ( - :chkpf_uid ("{97AEB597-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (OPSEC_product_info) - ) - :certification_info () - :certified (true) - :product (SafeGate) - :vendor (Computer_Associates) - :version (2.2) - ) - :type (OPSEC_product) - ) - : (Finjan_SurfinGate_4.03_NT - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB599-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (OPSEC_product) - :table (products) - ) - :NT_commands () - :commands () - :solaris_commands () - :AMON (false) - :AMON_class_name (default_opsec_status_object) - :CPMI (false) - :CVP (true) - :ELA (false) - :LEA (false) - :OMI (false) - :RTM (false) - :SAM (false) - :UAC (false) - :UFP (false) - :color (black) - :comments () - :product_info ( - :AdminInfo ( - :chkpf_uid ("{97AEB59A-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (OPSEC_product_info) - ) - :certification_info () - :certified (true) - :product (SurfinGate) - :vendor (Finjan_Software) - :version (4.03) - ) - :type (OPSEC_product) - ) - : (FSecure_AV_FireWall_4.01 - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB59C-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (OPSEC_product) - :table (products) - ) - :NT_commands () - :commands () - :solaris_commands () - :AMON (false) - :AMON_class_name (default_opsec_status_object) - :CPMI (false) - :CVP (true) - :ELA (false) - :LEA (false) - :OMI (false) - :RTM (false) - :SAM (false) - :UAC (false) - :UFP (false) - :color (black) - :comments () - :product_info ( - :AdminInfo ( - :chkpf_uid ("{97AEB59D-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (OPSEC_product_info) - ) - :certification_info () - :certified (true) - :product (Anti_Virus_For_FireWall) - :vendor (F-Secure) - :version (4.01) - ) - :type (OPSEC_product) - ) - : (TM_AppletTrap_2.0 - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB59F-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (OPSEC_product) - :table (products) - ) - :NT_commands () - :commands () - :solaris_commands () - :AMON (false) - :AMON_class_name (default_opsec_status_object) - :CPMI (false) - :CVP (true) - :ELA (false) - :LEA (false) - :OMI (false) - :RTM (false) - :SAM (false) - :UAC (false) - :UFP (false) - :color (black) - :comments () - :product_info ( - :AdminInfo ( - :chkpf_uid ("{97AEB5A0-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (OPSEC_product_info) - ) - :certification_info () - :certified (true) - :product (InterScan_AppletTrap) - :vendor (Trend_Micro) - :version (2.0) - ) - :type (OPSEC_product) - ) - : (TM_VirusWall_FTP_3.5 - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB5A2-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (OPSEC_product) - :table (products) - ) - :NT_commands () - :commands () - :solaris_commands () - :AMON (false) - :AMON_class_name (default_opsec_status_object) - :CPMI (false) - :CVP (true) - :ELA (false) - :LEA (false) - :OMI (false) - :RTM (false) - :SAM (false) - :UAC (false) - :UFP (false) - :color (black) - :comments () - :product_info ( - :AdminInfo ( - :chkpf_uid ("{97AEB5A3-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (OPSEC_product_info) - ) - :certification_info () - :certified (true) - :product (InterScan_VirusWall_for_FTP) - :vendor (Trend_Micro) - :version (3.5) - ) - :type (OPSEC_product) - ) - : (TM_VirusWall_HTTP_3.5 - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB5A5-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (OPSEC_product) - :table (products) - ) - :NT_commands () - :commands () - :solaris_commands () - :AMON (false) - :AMON_class_name (default_opsec_status_object) - :CPMI (false) - :CVP (true) - :ELA (false) - :LEA (false) - :OMI (false) - :RTM (false) - :SAM (false) - :UAC (false) - :UFP (false) - :color (black) - :comments () - :product_info ( - :AdminInfo ( - :chkpf_uid ("{97AEB5A6-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (OPSEC_product_info) - ) - :certification_info () - :certified (true) - :product (InterScan_VirusWall_for_HTTP) - :vendor (Trend_Micro) - :version (3.5) - ) - :type (OPSEC_product) - ) - : (TM_VirusWall_SMTP_3.5 - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB5A8-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (OPSEC_product) - :table (products) - ) - :NT_commands () - :commands () - :solaris_commands () - :AMON (false) - :AMON_class_name (default_opsec_status_object) - :CPMI (false) - :CVP (true) - :ELA (false) - :LEA (false) - :OMI (false) - :RTM (false) - :SAM (false) - :UAC (false) - :UFP (false) - :color (black) - :comments () - :product_info ( - :AdminInfo ( - :chkpf_uid ("{97AEB5A9-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (OPSEC_product_info) - ) - :certification_info () - :certified (true) - :product (InterScan_VirusWall_for_SMTP) - :vendor (Trend_Micro) - :version (3.5) - ) - :type (OPSEC_product) - ) - : (CPRS_NS_5.0 - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB5AB-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (OPSEC_product) - :table (products) - ) - :NT_commands () - :commands () - :solaris_commands () - :AMON (false) - :AMON_class_name (default_opsec_status_object) - :CPMI (false) - :CVP (false) - :ELA (false) - :LEA (false) - :OMI (false) - :RTM (false) - :SAM (true) - :UAC (false) - :UFP (false) - :color (black) - :comments () - :product_info ( - :AdminInfo ( - :chkpf_uid ("{97AEB5AC-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (OPSEC_product_info) - ) - :certification_info () - :certified (true) - :product (Real_Secure_Network_Sensor) - :vendor (Check_Point) - :version (5.0) - ) - :type (OPSEC_product) - ) - : (CPRSM_5.0 - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB5AE-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (OPSEC_product) - :table (products) - ) - :NT_commands () - :commands () - :solaris_commands () - :AMON (false) - :AMON_class_name (default_opsec_status_object) - :CPMI (false) - :CVP (false) - :ELA (true) - :LEA (false) - :OMI (true) - :RTM (false) - :SAM (true) - :UAC (false) - :UFP (false) - :color (black) - :comments () - :product_info ( - :AdminInfo ( - :chkpf_uid ("{97AEB5AF-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (OPSEC_product_info) - ) - :certification_info () - :certified (true) - :product (Real_Secure_Manager) - :vendor (Check_Point) - :version (5.0) - ) - :type (OPSEC_product) - ) - : (CA_SessionWall3_1.4 - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB5B1-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (OPSEC_product) - :table (products) - ) - :NT_commands () - :commands () - :solaris_commands () - :AMON (false) - :AMON_class_name (default_opsec_status_object) - :CPMI (false) - :CVP (false) - :ELA (true) - :LEA (false) - :OMI (false) - :RTM (false) - :SAM (true) - :UAC (false) - :UFP (false) - :color (black) - :comments () - :product_info ( - :AdminInfo ( - :chkpf_uid ("{97AEB5B2-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (OPSEC_product_info) - ) - :certification_info () - :certified (true) - :product (SessionWall_3) - :vendor (Computer_Associates) - :version (1.4) - ) - :type (OPSEC_product) - ) - : (Securant_ClearTrust_SecureDetector_4.5 - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB5B4-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (OPSEC_product) - :table (products) - ) - :NT_commands () - :commands () - :solaris_commands () - :AMON (false) - :AMON_class_name (default_opsec_status_object) - :CPMI (false) - :CVP (false) - :ELA (false) - :LEA (false) - :OMI (false) - :RTM (false) - :SAM (true) - :UAC (false) - :UFP (false) - :color (black) - :comments () - :product_info ( - :AdminInfo ( - :chkpf_uid ("{97AEB5B5-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (OPSEC_product_info) - ) - :certification_info () - :certified (true) - :product (ClearTrust_SecureDetector) - :vendor (Securant_Technologies) - :version (4.5) - ) - :type (OPSEC_product) - ) - : (8e6_XStop_FW1_1.0 - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB5B7-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (OPSEC_product) - :table (products) - ) - :NT_commands () - :commands () - :solaris_commands () - :AMON (false) - :AMON_class_name (default_opsec_status_object) - :CPMI (false) - :CVP (false) - :ELA (false) - :LEA (false) - :OMI (false) - :RTM (false) - :SAM (false) - :UAC (false) - :UFP (true) - :color (black) - :comments () - :product_info ( - :AdminInfo ( - :chkpf_uid ("{97AEB5B8-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (OPSEC_product_info) - ) - :certification_info () - :certified (true) - :product (X-Stop_For_FireWall-1) - :vendor (8e6_Technologies) - :version (1.0) - ) - :type (OPSEC_product) - ) - : (SecureComputing_SmartFilter_1.0 - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB5BA-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (OPSEC_product) - :table (products) - ) - :NT_commands () - :commands () - :solaris_commands () - :AMON (false) - :AMON_class_name (default_opsec_status_object) - :CPMI (false) - :CVP (false) - :ELA (false) - :LEA (false) - :OMI (false) - :RTM (false) - :SAM (false) - :UAC (false) - :UFP (true) - :color (black) - :comments () - :product_info ( - :AdminInfo ( - :chkpf_uid ("{97AEB5BB-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (OPSEC_product_info) - ) - :certification_info () - :certified (true) - :product (Smart_Filter) - :vendor (Secure_Computing) - :version (1.0) - ) - :type (OPSEC_product) - ) - : (SurfControl_SuperScout_FW1_2.0 - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB5BD-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (OPSEC_product) - :table (products) - ) - :NT_commands () - :commands () - :solaris_commands () - :AMON (false) - :AMON_class_name (default_opsec_status_object) - :CPMI (false) - :CVP (false) - :ELA (false) - :LEA (false) - :OMI (false) - :RTM (false) - :SAM (false) - :UAC (false) - :UFP (true) - :color (black) - :comments () - :product_info ( - :AdminInfo ( - :chkpf_uid ("{97AEB5BE-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (OPSEC_product_info) - ) - :certification_info () - :certified (true) - :product (SuperScout_for_FireWall-1) - :vendor (SurfControl) - :version (2.0) - ) - :type (OPSEC_product) - ) - : (Symantec_IGear_FW1_3.02 - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB5C0-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (OPSEC_product) - :table (products) - ) - :NT_commands () - :commands () - :solaris_commands () - :AMON (false) - :AMON_class_name (default_opsec_status_object) - :CPMI (false) - :CVP (false) - :ELA (false) - :LEA (false) - :OMI (false) - :RTM (false) - :SAM (false) - :UAC (false) - :UFP (true) - :color (black) - :comments () - :product_info ( - :AdminInfo ( - :chkpf_uid ("{97AEB5C1-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (OPSEC_product_info) - ) - :certification_info () - :certified (true) - :product (I-Gear_for_FireWall-1) - :vendor (Symantec) - :version (3.02) - ) - :type (OPSEC_product) - ) - : (WebSense_FW1_4.24 - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB5C3-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (OPSEC_product) - :table (products) - ) - :NT_commands () - :commands () - :solaris_commands () - :AMON (false) - :AMON_class_name (default_opsec_status_object) - :CPMI (false) - :CVP (false) - :ELA (false) - :LEA (false) - :OMI (false) - :RTM (false) - :SAM (false) - :UAC (false) - :UFP (true) - :color (black) - :comments () - :product_info ( - :AdminInfo ( - :chkpf_uid ("{97AEB5C4-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (OPSEC_product_info) - ) - :certification_info () - :certified (true) - :product (WebSense_for_FireWall-1) - :vendor (WebSense) - :version (4.24) - ) - :type (OPSEC_product) - ) - : (BMC_Patrol_FW_1.1 - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB5C6-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (OPSEC_product) - :table (products) - ) - :NT_commands () - :commands () - :solaris_commands () - :AMON (false) - :AMON_class_name (default_opsec_status_object) - :CPMI (false) - :CVP (false) - :ELA (false) - :LEA (true) - :OMI (false) - :RTM (false) - :SAM (false) - :UAC (false) - :UFP (false) - :color (black) - :comments () - :product_info ( - :AdminInfo ( - :chkpf_uid ("{97AEB5C7-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (OPSEC_product_info) - ) - :certification_info () - :certified (true) - :product (Patrol_for_Firewalls) - :vendor (BMC_Software) - :version (1.1) - ) - :type (OPSEC_product) - ) - : (BusinessLayers_eProvisionDayOne_1.1 - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB5C9-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (OPSEC_product) - :table (products) - ) - :NT_commands () - :commands () - :solaris_commands () - :AMON (false) - :AMON_class_name (default_opsec_status_object) - :CPMI (false) - :CVP (false) - :ELA (true) - :LEA (false) - :OMI (false) - :RTM (false) - :SAM (false) - :UAC (false) - :UFP (false) - :color (black) - :comments () - :product_info ( - :AdminInfo ( - :chkpf_uid ("{97AEB5CA-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (OPSEC_product_info) - ) - :certification_info () - :certified (true) - :product (eProvision_Day_One) - :vendor (Business_Layers) - :version (1.1) - ) - :type (OPSEC_product) - ) - : (Micromuse_Netcool_FW1_1.0 - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB5CC-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (OPSEC_product) - :table (products) - ) - :NT_commands () - :commands () - :solaris_commands () - :AMON (false) - :AMON_class_name (default_opsec_status_object) - :CPMI (false) - :CVP (false) - :ELA (true) - :LEA (true) - :OMI (false) - :RTM (false) - :SAM (true) - :UAC (false) - :UFP (false) - :color (black) - :comments () - :product_info ( - :AdminInfo ( - :chkpf_uid ("{97AEB5CD-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (OPSEC_product_info) - ) - :certification_info () - :certified (true) - :product (NetCool_for_FireWall-1) - :vendor (Micromuse) - :version (1.0) - ) - :type (OPSEC_product) - ) - : (OpenService_System_Watch_2.5 - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB5CF-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (OPSEC_product) - :table (products) - ) - :NT_commands () - :commands () - :solaris_commands () - :AMON (false) - :AMON_class_name (default_opsec_status_object) - :CPMI (false) - :CVP (false) - :ELA (false) - :LEA (true) - :OMI (false) - :RTM (false) - :SAM (false) - :UAC (false) - :UFP (false) - :color (black) - :comments () - :product_info ( - :AdminInfo ( - :chkpf_uid ("{97AEB5D0-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (OPSEC_product_info) - ) - :certification_info () - :certified (true) - :product (SystemWatch) - :vendor (OpenService) - :version (2.5) - ) - :type (OPSEC_product) - ) - : (ProactiveNet_Intelliscope_3.6 - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB5D2-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (OPSEC_product) - :table (products) - ) - :NT_commands () - :commands () - :solaris_commands () - :AMON (false) - :AMON_class_name (default_opsec_status_object) - :CPMI (false) - :CVP (false) - :ELA (false) - :LEA (true) - :OMI (false) - :RTM (false) - :SAM (false) - :UAC (false) - :UFP (false) - :color (black) - :comments () - :product_info ( - :AdminInfo ( - :chkpf_uid ("{97AEB5D3-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (OPSEC_product_info) - ) - :certification_info () - :certified (true) - :product (Intelliscope) - :vendor (ProactiveNet) - :version (3.6) - ) - :type (OPSEC_product) - ) - : (CP_Reporting_4.1 - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB5D5-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (OPSEC_product) - :table (products) - ) - :NT_commands () - :commands () - :solaris_commands () - :AMON (false) - :AMON_class_name (default_opsec_status_object) - :CPMI (false) - :CVP (false) - :ELA (false) - :LEA (true) - :OMI (true) - :RTM (false) - :SAM (false) - :UAC (false) - :UFP (false) - :color (black) - :comments () - :product_info ( - :AdminInfo ( - :chkpf_uid ("{97AEB5D6-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (OPSEC_product_info) - ) - :certification_info () - :certified (true) - :product (Reporting_Module) - :vendor (Check_Point) - :version (4.1) - ) - :type (OPSEC_product) - ) - : (OpenSystems_PrivateI_6.1 - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB5D8-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (OPSEC_product) - :table (products) - ) - :NT_commands () - :commands () - :solaris_commands () - :AMON (false) - :AMON_class_name (default_opsec_status_object) - :CPMI (false) - :CVP (false) - :ELA (false) - :LEA (true) - :OMI (false) - :RTM (false) - :SAM (false) - :UAC (false) - :UFP (false) - :color (black) - :comments () - :product_info ( - :AdminInfo ( - :chkpf_uid ("{97AEB5D9-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (OPSEC_product_info) - ) - :certification_info () - :certified (true) - :product (Private_I_Intelligence_Suite) - :vendor (OpenSystems.com) - :version (6.1) - ) - :type (OPSEC_product) - ) - : (SameSolutions_NetTracker_1.1 - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB5DB-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (OPSEC_product) - :table (products) - ) - :NT_commands () - :commands () - :solaris_commands () - :AMON (false) - :AMON_class_name (default_opsec_status_object) - :CPMI (false) - :CVP (false) - :ELA (false) - :LEA (true) - :OMI (false) - :RTM (false) - :SAM (false) - :UAC (false) - :UFP (false) - :color (black) - :comments () - :product_info ( - :AdminInfo ( - :chkpf_uid ("{97AEB5DC-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (OPSEC_product_info) - ) - :certification_info () - :certified (true) - :product (NetTracker_Enterprise) - :vendor ("Sane Solutions") - :version (1.1) - ) - :type (OPSEC_product) - ) - : (Telemate.Net_4.4 - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB5DE-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (OPSEC_product) - :table (products) - ) - :NT_commands () - :commands () - :solaris_commands () - :AMON (false) - :AMON_class_name (default_opsec_status_object) - :CPMI (false) - :CVP (false) - :ELA (false) - :LEA (true) - :OMI (false) - :RTM (false) - :SAM (false) - :UAC (false) - :UFP (false) - :color (black) - :comments () - :product_info ( - :AdminInfo ( - :chkpf_uid ("{97AEB5DF-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (OPSEC_product_info) - ) - :certification_info () - :certified (true) - :product (TELEMATE.Net) - :vendor (Telemate.Net_Software) - :version (4.4) - ) - :type (OPSEC_product) - ) - : (VeriSign_Firewall_HealthCHECK_1.5 - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB5E1-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (OPSEC_product) - :table (products) - ) - :NT_commands () - :commands () - :solaris_commands () - :AMON (false) - :AMON_class_name (default_opsec_status_object) - :CPMI (false) - :CVP (false) - :ELA (false) - :LEA (false) - :OMI (true) - :RTM (false) - :SAM (false) - :UAC (false) - :UFP (false) - :color (black) - :comments () - :product_info ( - :AdminInfo ( - :chkpf_uid ("{97AEB5E2-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (OPSEC_product_info) - ) - :certification_info () - :certified (true) - :product (Firewall_HealthCHECK) - :vendor (VeriSign) - :version (1.5) - ) - :type (OPSEC_product) - ) - : (VeriSign_SecureVIEW_3.0.28 - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB5E4-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (OPSEC_product) - :table (products) - ) - :NT_commands () - :commands () - :solaris_commands () - :AMON (false) - :AMON_class_name (default_opsec_status_object) - :CPMI (false) - :CVP (false) - :ELA (false) - :LEA (true) - :OMI (false) - :RTM (false) - :SAM (false) - :UAC (false) - :UFP (false) - :color (black) - :comments () - :product_info ( - :AdminInfo ( - :chkpf_uid ("{97AEB5E5-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (OPSEC_product_info) - ) - :certification_info () - :certified (true) - :product (SecureVIEW) - :vendor (VeriSign) - :version (3.0.28) - ) - :type (OPSEC_product) - ) - : (WebTrends_Firewall_2.0 - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB5E7-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (OPSEC_product) - :table (products) - ) - :NT_commands () - :commands () - :solaris_commands () - :AMON (false) - :AMON_class_name (default_opsec_status_object) - :CPMI (false) - :CVP (false) - :ELA (false) - :LEA (true) - :OMI (false) - :RTM (false) - :SAM (false) - :UAC (false) - :UFP (false) - :color (black) - :comments () - :product_info ( - :AdminInfo ( - :chkpf_uid ("{97AEB5E8-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (OPSEC_product_info) - ) - :certification_info () - :certified (true) - :product (WebTrends_Firewall_Suite) - :vendor (WebTrends) - :version (2.0) - ) - :type (OPSEC_product) - ) - ) - :serverobj (serverobj) - :resources (resources) - :translations (translations) - :tracks (tracks - : ("UserDefined 2" - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:09 2001") - :By (CheckPoint) - :From (CheckPoint) - ) - :chkpf_uid ("{97AEB485-9AEA-21D5-BD16-0090272CCB30}") - :ClassName (alert) - :table (tracks) - :name ("UserDefined 2") - ) - :Name () - :alert (useralert2) - :color ("Dark Orchid") - :format (long) - :icon () - :icon-name (icon-user) - :text-rid (61470) - :type (alert) - ) - : ("UserDefined 3" - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:09 2001") - :By (CheckPoint) - :From (CheckPoint) - ) - :chkpf_uid ("{97AEB485-9AEA-31D5-BD16-0090272CCB30}") - :ClassName (alert) - :table (tracks) - :name ("UserDefined 3") - ) - :Name () - :alert (useralert3) - :color ("Dark Orchid") - :format (long) - :icon () - :icon-name (icon-user) - :text-rid (61470) - :type (alert) - ) - : (VPNddcateDropLog - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By (CheckPoint) - :From (CheckPoint) - ) - :chkpf_uid ("{97AEB496-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (log) - :table (tracks) - :name (VPNddcateDropLog) - ) - :Name () - :color ("Navy Blue") - :format (long) - :icon-name (icon-log-long) - :macro (VPN_DEDICATED_DROP_LOG) - :text-rid (0) - :type (log) - ) - : (VPNddcateAcceptLog - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By (CheckPoint) - :From (CheckPoint) - ) - :chkpf_uid ("{97AEB497-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (log) - :table (tracks) - :name (VPNddcateAcceptLog) - ) - :Name () - :color ("Navy Blue") - :format (long) - :icon-name (icon-log-long) - :macro (VPN_DEDICATED_ACCEPT_LOG) - :text-rid (0) - :type (log) - ) - : (None - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB47D-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (empty_track) - :table (tracks) - :name (None) - ) - :icon (empty) - :icon-name (icon-empty) - ) - : (Short - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB47E-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (log) - :table (tracks) - :name (Short) - ) - :Name () - :color (Blue) - :format () - :icon-name (icon-log-short) - :macro () - :text-rid (61467) - :type (log) - ) - : (Long - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB47F-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (log) - :table (tracks) - :name (Long) - ) - :Name () - :color ("Navy Blue") - :format () - :icon-name (icon-log-long) - :macro () - :text-rid (61466) - :type (log) - ) - : (Log - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB480-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (log) - :table (tracks) - :name (Log) - ) - :Name () - :color ("Navy Blue") - :format (long) - :icon-name (icon-log-long) - :macro () - :text-rid (61466) - :type (log) - ) - : (Account - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:08 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB481-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (account) - :table (tracks) - :name (Account) - ) - :Name () - :color (Magenta) - :format (long) - :icon-name (icon-account) - :macro (ACCOUNT) - :type (account) - ) - : (Alert - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:09 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB482-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (alert) - :table (tracks) - :name (Alert) - ) - :Name () - :alert (alert) - :color (Red) - :format (long) - :icon () - :icon-name (icon-alert) - :text-rid (61469) - :type (alert) - ) - : (SnmpTrap - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:09 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB483-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (alert) - :table (tracks) - :name (SnmpTrap) - ) - :Name () - :alert (snmptrap) - :color ("Medium Slate Blue") - :format (long) - :icon () - :icon-name (icon-snmp-trap) - :text-rid (61467) - :type (alert) - ) - : (Mail - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:09 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB484-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (alert) - :table (tracks) - :name (Mail) - ) - :Name () - :alert (mail) - :color (FireBrick) - :format (long) - :icon () - :icon-name (icon-mail) - :text-rid (61468) - :type (alert) - ) - : (UserDefined - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:09 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB485-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (alert) - :table (tracks) - :name (UserDefined) - ) - :Name () - :alert (useralert) - :color ("Dark Orchid") - :format (long) - :icon () - :icon-name (icon-user) - :text-rid (61470) - :type (alert) - ) - : (spoof - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:09 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB486-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (log) - :table (tracks) - :name (spoof) - ) - :Name () - :color ("Navy Blue") - :format (long) - :icon-name () - :macro () - :text-rid (0) - :type (log) - ) - : (spoofalert - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:09 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB487-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (alert) - :table (tracks) - :name (spoofalert) - ) - :Name () - :alert (spoofalert) - :color (red) - :format (long) - :icon (alert.pr) - :icon-name () - :text-rid (0) - :type (alert) - ) - : ("IP Options" - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:09 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB488-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (log) - :table (tracks) - :name ("IP Options") - ) - :Name () - :color ("Dark Orchid") - :format (badip_form) - :icon-name () - :macro () - :text-rid (0) - :type (log) - ) - : ("IP Options Alert" - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:09 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB489-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (alert) - :table (tracks) - :name ("IP Options Alert") - ) - :Name () - :alert (alert) - :color (Red) - :format (badip_form) - :icon (alert.pr) - :icon-name () - :text-rid (0) - :type (alert) - ) - : (Auth - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:09 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB48A-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (log) - :table (tracks) - :name (Auth) - ) - :Name (Auth) - :color (Blue) - :format () - :icon-name () - :macro () - :text-rid (0) - :type (log) - ) - : (AuthAlert - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:09 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB48B-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (alert) - :table (tracks) - :name (AuthAlert) - ) - :Name (AuthAlert) - :alert (userauthalert) - :color (Red) - :format (auth) - :icon (alert.pr) - :icon-name () - :text-rid (0) - :type (alert) - ) - : (Duplicate - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:09 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB48C-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (log) - :table (tracks) - :name (Duplicate) - ) - :Name () - :color ("Navy Blue") - :format () - :icon-name (icon-log-long) - :macro (DUP_LOG) - :text-rid (61466) - :type (log) - ) - : ("Exception Log" - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:09 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB48D-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (log) - :table (tracks) - :name ("Exception Log") - ) - :Name () - :color (Blue) - :format (long) - :icon-name () - :macro () - :text-rid (0) - :type (log) - ) - : ("Exception Alert" - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:09 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB48E-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (alert) - :table (tracks) - :name ("Exception Alert") - ) - :Name () - :alert (alert) - :color (Red) - :format (long) - :icon (alert.pr) - :icon-name () - :text-rid (0) - :type (alert) - ) - ) - :qos ( - : (Best_Effort - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:09 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB658-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (class_of_service) - :table (qos) - :Deleteable (false) - :Renameable (false) - ) - :class_of_service_type (best_effort) - :color (black) - :comments () - :dscp (0) - :type (fg_class_of_service) - ) - ) - :servgen () - :log-props () - :state-act ( - :comannd_notinst2inst () - :command_notinst2dis () - :command_ins2notinst (status_alert) - :command_inst2dis (status_alert) - :command_dis2inst () - :command_dis2notinst () - ) - :SPIobj () - :userdefaults (Default - :name (Default) - :type (template) - :auth_method (Undefined) - :fromhour ("00:00") - :tohour ("23:59") - :expiration_date (31-dec-2003) - :groups () - :SKEY_number (100) - :days (127) - :destinations ( - : (Any - :color (Blue) - ) - ) - :sources ( - : (Any - :color (Blue) - ) - ) - ) - :ldap ( - : (OPSEC_DS - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:09 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB639-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (LDAP_policy) - :table (ldap) - ) - :Common ( - :AdminInfo ( - :chkpf_uid ("{97AEB63A-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (LDAP_policy_common) - ) - :AttributesTranslationMap ( - : ("uid=uid") - ) - :DateFormat (yyyymmdd) - :ListOfAttrsToAvoid () - :TemplateObjectClass ( - : (fw1template) - ) - :BadPwdCountAttr (fw1BadPwdCount) - :ClientSideCrypt (0) - :CryptedPasswordPrefix ("{CRYPT}") - :DefaultCryptAlgorithm (PLAIN) - :ExpirationDateAttr (fw1expiration-date) - :ExpirationDateFormat (CP) - :FetchBranchesEnabled (1) - :MainVersion (4) - :PhoneNumberAttr (internationalisdnnumber) - :PsswdDateAttr (fw1pwdLastMod) - :PsswdDateFormat (CP) - :ReadOnly (0) - :StrongAuthSupported (1) - :SubVersion (1) - :SupportOldSchema (0) - :UnbindMode (0) - :UserLoginAttr (uid) - :UserPasswordAttr (userPassword) - :Vendor (Other) - ) - :Read ( - :AdminInfo ( - :chkpf_uid ("{97AEB63B-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (LDAP_policy_read) - ) - :BranchObjectClass ( - : (Organization) - : (OrganizationalUnit) - ) - :DomainObjectClass () - :GroupMembershipAttr ( - : (member) - : (uniqueMember) - ) - :GroupObjectClass ( - : (groupOfNames) - : (groupOfUniqueNames) - ) - :OrgUnitObjectClass ( - : (OrganizationalUnit) - ) - :OrganizationObjectClass ( - : (Organization) - ) - :TemplateMembershipAttr ( - : (member) - ) - :TemplateObjectClass ( - : (Organization) - ) - :UserMembershipAttr ( - : (memberOf) - ) - :UserObjectClass ( - : (person) - : (organizationalPerson) - : (inetOrgPerson) - : (fw1Person) - ) - :BranchOCOperator (One) - :FetchBranchesFrom () - :GroupMembership (Member) - :GroupOCOperator (One) - :Scope (sub) - :SizeLimit (2000) - :TemplateMembership (Member) - :TimeLimit (50) - :UserOCOperator (One) - :UserTemplateMembershipAttr (memberoftemplate) - ) - :Write ( - :AdminInfo ( - :chkpf_uid ("{97AEB63C-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (LDAP_policy_write) - ) - :AutomaticAttrs () - :DomainObjectClass () - :DomainRDN (dc) - :GroupObjectClass ( - : ("groupOfNames:member") - : ("groupOfUniqueNames:uniqueMember") - ) - :OrgUnitObjectClass ( - : (OrganizationalUnit) - ) - :OrganizationObjectClass ( - : (Organization) - ) - :TemplateMembershipAttr ( - : (member) - ) - :UserObjectClass ( - : (person) - : (organizationalPerson) - : (inetOrgPerson) - : (fw1Person) - ) - :AllowReplaceOperation (1) - :DefaultGroupObjectClass (groupOfNames) - :GroupRDN (cn) - :OrgUnitRDN (ou) - :OrganizationRDN (o) - :SupportEmptyGroups (1) - :TemplateMembership (Member) - :UserMembershipAttr (memberOf) - :UserRDN (cn) - :UserTemplateMembershipAttr (memberoftemplate) - ) - :color (Black) - :comments ("Default Directory Server") - :type (ldap_policy) - ) - : (Novell_DS - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:09 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB640-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (LDAP_policy) - :table (ldap) - ) - :Common ( - :AdminInfo ( - :chkpf_uid ("{97AEB641-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (LDAP_policy_common) - ) - :AttributesTranslationMap ( - : ("uid=uid") - ) - :DateFormat (yyyymmdd) - :ListOfAttrsToAvoid () - :TemplateObjectClass ( - : (fw1template) - ) - :BadPwdCountAttr (fw1BadPwdCount) - :ClientSideCrypt (0) - :CryptedPasswordPrefix ("{CRYPT}") - :DefaultCryptAlgorithm (PLAIN) - :ExpirationDateAttr (fw1expiration-date) - :ExpirationDateFormat (CP) - :FetchBranchesEnabled (1) - :MainVersion (4) - :PhoneNumberAttr (internationalisdnnumber) - :PsswdDateAttr (fw1pwdLastMod) - :PsswdDateFormat (CP) - :ReadOnly (0) - :StrongAuthSupported (1) - :SubVersion (1) - :SupportOldSchema (0) - :UnbindMode (0) - :UserLoginAttr (uid) - :UserPasswordAttr (userPassword) - :Vendor (Novell) - ) - :Read ( - :AdminInfo ( - :chkpf_uid ("{97AEB642-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (LDAP_policy_read) - ) - :BranchObjectClass ( - : (Organization) - : (OrganizationalUnit) - ) - :DomainObjectClass () - :GroupMembershipAttr ( - : (member) - : (uniqueMember) - ) - :GroupObjectClass ( - : (groupOfNames) - : (groupOfUniqueNames) - ) - :OrgUnitObjectClass ( - : (OrganizationalUnit) - ) - :OrganizationObjectClass ( - : (Organization) - ) - :TemplateMembershipAttr ( - : (member) - ) - :TemplateObjectClass ( - : (Organization) - ) - :UserMembershipAttr ( - : (memberOf) - ) - :UserObjectClass ( - : (person) - : (organizationalPerson) - : (inetOrgPerson) - : (fw1Person) - ) - :BranchOCOperator (One) - :FetchBranchesFrom () - :GroupMembership (Member) - :GroupOCOperator (One) - :Scope (sub) - :SizeLimit (2000) - :TemplateMembership (Member) - :TimeLimit (50) - :UserOCOperator (One) - :UserTemplateMembershipAttr (memberoftemplate) - ) - :Write ( - :AdminInfo ( - :chkpf_uid ("{97AEB643-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (LDAP_policy_write) - ) - :AutomaticAttrs () - :DomainObjectClass () - :DomainRDN (dc) - :GroupObjectClass ( - : ("groupOfNames:member") - : ("groupOfUniqueNames:uniqueMember") - ) - :OrgUnitObjectClass ( - : (OrganizationalUnit) - ) - :OrganizationObjectClass ( - : (Organization) - ) - :TemplateMembershipAttr ( - : (member) - ) - :UserObjectClass ( - : (person) - : (organizationalPerson) - : (inetOrgPerson) - : (fw1Person) - ) - :AllowReplaceOperation (1) - :DefaultGroupObjectClass (groupOfNames) - :GroupRDN (cn) - :OrgUnitRDN (ou) - :OrganizationRDN (o) - :SupportEmptyGroups (1) - :TemplateMembership (Member) - :UserMembershipAttr (memberOf) - :UserRDN (cn) - :UserTemplateMembershipAttr (memberoftemplate) - ) - :color (Black) - :comments ("Novell Directory Server") - :type (ldap_policy) - ) - : (Netscape_DS - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:09 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB647-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (LDAP_policy) - :table (ldap) - ) - :Common ( - :AdminInfo ( - :chkpf_uid ("{97AEB648-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (LDAP_policy_common) - ) - :AttributesTranslationMap ( - : ("uid=uid") - ) - :DateFormat (yyyymmdd) - :ListOfAttrsToAvoid () - :TemplateObjectClass ( - : (fw1template) - ) - :BadPwdCountAttr (fw1BadPwdCount) - :ClientSideCrypt (1) - :CryptedPasswordPrefix ("{CRYPT}") - :DefaultCryptAlgorithm (CRYPT) - :ExpirationDateAttr (fw1expiration-date) - :ExpirationDateFormat (CP) - :FetchBranchesEnabled (1) - :MainVersion (4) - :PhoneNumberAttr (internationalisdnnumber) - :PsswdDateAttr (fw1pwdLastMod) - :PsswdDateFormat (CP) - :ReadOnly (0) - :StrongAuthSupported (1) - :SubVersion (1) - :SupportOldSchema (0) - :UnbindMode (0) - :UserLoginAttr (uid) - :UserPasswordAttr (userPassword) - :Vendor (Netscape) - ) - :Read ( - :AdminInfo ( - :chkpf_uid ("{97AEB649-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (LDAP_policy_read) - ) - :BranchObjectClass ( - : (Organization) - : (OrganizationalUnit) - : (Domain) - ) - :DomainObjectClass () - :GroupMembershipAttr ( - : (member) - : (uniqueMember) - ) - :GroupObjectClass ( - : (groupOfNames) - : (groupOfUniqueNames) - ) - :OrgUnitObjectClass ( - : (OrganizationalUnit) - ) - :OrganizationObjectClass ( - : (Organization) - ) - :TemplateMembershipAttr ( - : (member) - ) - :TemplateObjectClass ( - : (Organization) - ) - :UserMembershipAttr ( - : (memberOf) - ) - :UserObjectClass ( - : (person) - : (organizationalPerson) - : (inetOrgPerson) - : (fw1Person) - ) - :BranchOCOperator (One) - :FetchBranchesFrom () - :GroupMembership (Member) - :GroupOCOperator (One) - :Scope (sub) - :SizeLimit (2000) - :TemplateMembership (Member) - :TimeLimit (50) - :UserOCOperator (One) - :UserTemplateMembershipAttr (memberoftemplate) - ) - :Write ( - :AdminInfo ( - :chkpf_uid ("{97AEB64A-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (LDAP_policy_write) - ) - :AutomaticAttrs () - :DomainObjectClass ( - : (domain) - : (top) - ) - :DomainRDN (dc) - :GroupObjectClass ( - : ("groupOfNames:member") - : ("groupOfUniqueNames:uniqueMember") - ) - :OrgUnitObjectClass ( - : (OrganizationalUnit) - ) - :OrganizationObjectClass ( - : (Organization) - ) - :TemplateMembershipAttr ( - : (member) - ) - :UserObjectClass ( - : (person) - : (organizationalPerson) - : (inetOrgPerson) - : (fw1Person) - ) - :AllowReplaceOperation (1) - :DefaultGroupObjectClass (groupOfNames) - :GroupRDN (cn) - :OrgUnitRDN (ou) - :OrganizationRDN (o) - :SupportEmptyGroups (1) - :TemplateMembership (Member) - :UserMembershipAttr (memberOf) - :UserRDN (cn) - :UserTemplateMembershipAttr (memberoftemplate) - ) - :color (Black) - :comments ("Netscape Directory Server") - :type (ldap_policy) - ) - : (Microsoft_AD - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:09 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB64E-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (LDAP_policy) - :table (ldap) - ) - :Common ( - :AdminInfo ( - :chkpf_uid ("{97AEB64F-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (LDAP_policy_common) - ) - :AttributesTranslationMap ( - : ("uid=uid") - ) - :DateFormat (yyyymmdd) - :ListOfAttrsToAvoid () - :TemplateObjectClass ( - : (fw1template) - ) - :BadPwdCountAttr (fw1BadPwdCount) - :ClientSideCrypt (0) - :CryptedPasswordPrefix ("{CRYPT}") - :DefaultCryptAlgorithm (PLAIN) - :ExpirationDateAttr (accountExpires) - :ExpirationDateFormat (MS) - :FetchBranchesEnabled (1) - :MainVersion (5) - :PhoneNumberAttr (internationalisdnnumber) - :PsswdDateAttr (pwdLastSet) - :PsswdDateFormat (MS) - :ReadOnly (0) - :StrongAuthSupported (1) - :SubVersion (0) - :SupportOldSchema (0) - :UnbindMode (0) - :UserLoginAttr (sAMAccountName) - :UserPasswordAttr (unicodePwd) - :Vendor (Microsoft) - ) - :Read ( - :AdminInfo ( - :chkpf_uid ("{97AEB650-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (LDAP_policy_read) - ) - :BranchObjectClass ( - : (Organization) - : (OrganizationalUnit) - : (Container) - ) - :DomainObjectClass () - :GroupMembershipAttr ( - : (member) - ) - :GroupObjectClass ( - : (group) - : (groupOfNames) - ) - :OrgUnitObjectClass ( - : (OrganizationalUnit) - : (Container) - ) - :OrganizationObjectClass ( - : (Organization) - ) - :TemplateMembershipAttr ( - : (member) - ) - :TemplateObjectClass ( - : (Organization) - ) - :UserMembershipAttr ( - : (memberOf) - ) - :UserObjectClass ( - : (user) - ) - :BranchOCOperator (One) - :FetchBranchesFrom () - :GroupMembership (MemberOf) - :GroupOCOperator (One) - :Scope (sub) - :SizeLimit (2000) - :TemplateMembership (MemberOf) - :TimeLimit (50) - :UserOCOperator (One) - :UserTemplateMembershipAttr (memberoftemplate) - ) - :Write ( - :AdminInfo ( - :chkpf_uid ("{97AEB651-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (LDAP_policy_write) - ) - :AutomaticAttrs ( - : ("user:userAccountControl:66048") - ) - :DomainObjectClass () - :DomainRDN (dc) - :GroupObjectClass ( - : ("group:member") - ) - :OrgUnitObjectClass ( - : (OrganizationalUnit) - ) - :OrganizationObjectClass ( - : (Organization) - ) - :TemplateMembershipAttr ( - : (member) - ) - :UserObjectClass ( - : (user) - ) - :AllowReplaceOperation (1) - :DefaultGroupObjectClass (group) - :GroupRDN (cn) - :OrgUnitRDN (ou) - :OrganizationRDN (o) - :SupportEmptyGroups (0) - :TemplateMembership (MemberOf) - :UserMembershipAttr (memberOf) - :UserRDN (cn) - :UserTemplateMembershipAttr (memberoftemplate) - ) - :color (Black) - :comments ("Microsoft Active Directory") - :type (ldap_policy) - ) - ) - :encryption ( - : (skip512 - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:09 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB61A-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (SKIP_Diffie_Hellman_parameters_object) - :table (encryption) - ) - :color (black) - :comments () - :mod ( - :AdminInfo ( - :chkpf_uid ("{97AEB61B-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (key_value) - ) - :value (F52AFF3CE1B1294018118D7C84A70A72D686C40319C807297ACA950CD9969FABD00A509B0246D3083D66A45D419F9C7CBD894B221926BAABA25EC355E92A055F) - ) - :modsize (0) - :root ( - :AdminInfo ( - :chkpf_uid ("{97AEB61C-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (key_value) - ) - :value (02) - ) - :rootsize (0) - :type (SKIP_DH_parameters) - ) - : (skip1024 - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:09 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB61F-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (SKIP_Diffie_Hellman_parameters_object) - :table (encryption) - ) - :color (black) - :comments () - :mod ( - :AdminInfo ( - :chkpf_uid ("{97AEB620-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (key_value) - ) - :value (f488fd584e49dbcd20b49de49107366b336c380d451d0f7c88b31c7c5b2d8ef6f3c923c043f0a55b188d8ebb558cb85d38d334fd7c175743a31d186cde33212cb52aff3ce1b1294018118d7c84a70a72d686c40319c807297aca950cd9969fabd00a509b0246d3083d66a45d419f9c7cbd894b221926baaba25ec355e92f78c7) - ) - :modsize (0) - :root ( - :AdminInfo ( - :chkpf_uid ("{97AEB621-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (key_value) - ) - :value (02) - ) - :rootsize (0) - :type (SKIP_DH_parameters) - ) - : ("Group 1 (768 bit)" - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:09 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB624-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (IKE_Diffie_Hellman_parameters_object) - :table (encryption) - ) - :DH_group_number (1) - :color (black) - :comments () - :mod ( - :AdminInfo ( - :chkpf_uid ("{97AEB625-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (key_value) - ) - :value (ffffffffffffffffc90fdaa22168c234c4c6628b80dc1cd129024e088a67cc74020bbea63b139b22514a08798e3404ddef9519b3cd3a431b302b0a6df25f14374fe1356d6d51c245e485b576625e7ec6f44c42e9a63a3620ffffffffffffffff) - ) - :modsize (768) - :private_key_length (160) - :root ( - :AdminInfo ( - :chkpf_uid ("{97AEB626-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (key_value) - ) - :value (02) - ) - :rootsize (2) - :type (IKE_DH_parameters) - ) - : ("Group 2 (1024 bit)" - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:09 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB629-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (IKE_Diffie_Hellman_parameters_object) - :table (encryption) - ) - :DH_group_number (2) - :color (black) - :comments () - :mod ( - :AdminInfo ( - :chkpf_uid ("{97AEB62A-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (key_value) - ) - :value (ffffffffffffffffc90fdaa22168c234c4c6628b80dc1cd129024e088a67cc74020bbea63b139b22514a08798e3404ddef9519b3cd3a431b302b0a6df25f14374fe1356d6d51c245e485b576625e7ec6f44c42e9a637ed6b0bff5cb6f406b7edee386bfb5a899fa5ae9f24117c4b1fe649286651ece65381ffffffffffffffff) - ) - :modsize (1024) - :private_key_length (192) - :root ( - :AdminInfo ( - :chkpf_uid ("{97AEB62B-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (key_value) - ) - :value (02) - ) - :rootsize (2) - :type (IKE_DH_parameters) - ) - : ("Group 5 (1536 bit)" - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:09 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB62E-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (IKE_Diffie_Hellman_parameters_object) - :table (encryption) - ) - :DH_group_number (5) - :color (black) - :comments () - :mod ( - :AdminInfo ( - :chkpf_uid ("{97AEB62F-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (key_value) - ) - :value (FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7EDEE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3DC2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F83655D23DCA3AD961C62F356208552BB9ED529077096966D670C354E4ABC9804F1746C08CA237327FFFFFFFFFFFFFFFF) - ) - :modsize (1536) - :private_key_length (256) - :root ( - :AdminInfo ( - :chkpf_uid ("{97AEB630-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (key_value) - ) - :value (02) - ) - :rootsize (2) - :type (IKE_DH_parameters) - ) - : (fwz512 - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:09 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB633-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (FWZ_Diffie_Hellman_parameters_object) - :table (encryption) - ) - :color (black) - :comments () - :mod ( - :AdminInfo ( - :chkpf_uid ("{97AEB634-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (key_value) - ) - :value (9f57f60c98ba4f11468dfb4c2ecfd15b8861f48a88bd32cb2cb954c06cc01e25578102905691631266306444b1ef31de0c0091f468ecbccd70170b2d84fa637f) - ) - :modsize (0) - :root ( - :AdminInfo ( - :chkpf_uid ("{97AEB635-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (key_value) - ) - :value (0a552ee379202b40e79dca100dfb6501346307533c3ebef5e3ee0727e260489377981ae7c8b6124128437d4892fd632aafde6df3744f0351ec05f83130f74cfb) - ) - :rootsize (0) - :type (FWZ_DH_parameters) - ) - ) - :communities ( - : (MyExtranet - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:09 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB676-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (extranet_community) - :table (communities) - ) - :extranet_partners () - :extranet_resources () - :color (black) - :comments () - :type (extranet_community) - ) - : (RemoteAccess - :AdminInfo ( - :chkpf_uid ("{97AEB677-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (sr_community) - :table (communities) - :Deleteable (false) - :Wiznum (-1) - :LastModified ( - :Time ("Thu May 6 14:28:35 2004") - :By (andre) - :From (gateway) - ) - ) - :participant_gateways ( - : (ReferenceObject - :Name (IsoAAAD) - :Table (network_objects) - :Uid ("{29C40B0A-414C-11D7-AEB8-7F0000013C3C}") - ) - ) - :participant_users_groups ( - : (ReferenceObject - :Name (Cactus-extern) - :Table (users) - :Uid ("{227D1A80-CC1E-4CD4-9576-4D46F271402F}") - ) - : (ReferenceObject - :Name (RAS-Test) - :Table (users) - :Uid ("{895BBAA2-096E-4DC6-A621-4A98B44EB63E}") - ) - : (ReferenceObject - :Name (vpn_user) - :Table (users) - :Uid ("{82847E1A-EF2C-4A75-9A9E-0034D70978DB}") - ) - ) - :ID (2) - :color (black) - :comments () - :ike_p1 ( - :AdminInfo ( - :chkpf_uid ("{64C9347A-414A-11D7-B538-7F0000014646}") - :ClassName (ike_p1) - ) - :ike_p1_dh_grp (ReferenceObject - :Table (encryption) - :Name ("Group 2 (1024 bit)") - :Uid ("{97AEB629-9AEA-11D5-BD16-0090272CCB30}") - ) - :ike_p1_enc_alg (3DES) - :ike_p1_hash_alg (MD5) - :ike_p1_rekey_time (1440) - :ike_p1_use_aggressive (false) - :ike_p1_use_shared_secret (false) - ) - :ike_p2 ( - :AdminInfo ( - :chkpf_uid ("{64C93A60-414A-11D7-B538-7F0000014646}") - :ClassName (ike_p2) - ) - :ike_p2_enc_alg (3DES) - :ike_p2_hash_alg (MD5) - :ike_p2_ipcomp (None) - :ike_p2_pfs_dh_grp (ReferenceObject - :Table (encryption) - :Name ("Group 2 (1024 bit)") - :Uid ("{97AEB629-9AEA-11D5-BD16-0090272CCB30}") - ) - :ike_p2_rekey_kbytes (50000) - :ike_p2_rekey_time (3600) - :ike_p2_use_pfs (false) - :ike_p2_use_rekey_kbytes (false) - :ike_p2_use_subnets (true) - ) - :type (sr_community) - ) - :next_number (7) - : (IsoAAAE-VPN - :AdminInfo ( - :chkpf_uid ("{3C7F216B-3FD1-4E6D-A65F-0EF3C500F865}") - :ClassName (intranet_community) - :table (communities) - :Wiznum (-1) - :LastModified ( - :Time ("Sat Nov 20 22:20:26 2004") - :By (tim) - :From (gateway) - ) - ) - :exclude_srv () - :participant_gateways ( - : (ReferenceObject - :Name (IsoAAAD) - :Table (network_objects) - :Uid ("{29C40B0A-414C-11D7-AEB8-7F0000013C3C}") - ) - ) - :satellite_gateways () - :ID (5) - :allow_all_encrypted_traffic (false) - :color (black) - :comments () - :disable_NAT (false) - :ike_p1 ( - :AdminInfo ( - :chkpf_uid ("{CD67359F-4B08-41BD-8F72-E35BA5BCEA1E}") - :ClassName (ike_p1) - ) - :ike_p1_dh_grp (ReferenceObject - :Name ("Group 2 (1024 bit)") - :Table (encryption) - :Uid ("{97AEB629-9AEA-11D5-BD16-0090272CCB30}") - ) - :ike_p1_enc_alg (3DES) - :ike_p1_hash_alg (SHA1) - :ike_p1_rekey_time (1440) - :ike_p1_use_aggressive (false) - :ike_p1_use_shared_secret (false) - ) - :ike_p2 ( - :AdminInfo ( - :chkpf_uid ("{FB40B39A-590A-404E-A70D-A47D18DF4081}") - :ClassName (ike_p2) - ) - :ike_p2_enc_alg (3DES) - :ike_p2_hash_alg (SHA1) - :ike_p2_ipcomp (None) - :ike_p2_pfs_dh_grp (ReferenceObject - :Table (encryption) - :Name ("Group 2 (1024 bit)") - :Uid ("{97AEB629-9AEA-11D5-BD16-0090272CCB30}") - ) - :ike_p2_rekey_kbytes (50000) - :ike_p2_rekey_time (3600) - :ike_p2_use_pfs (false) - :ike_p2_use_rekey_kbytes (false) - :ike_p2_use_subnets (true) - ) - :meshed_in_center (false) - :route_through_center (none) - :topology (star) - :type (intranet_community) - ) - ) - :setup ( - : ("Single Sign On" - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:09 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB48F-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (Impersonation) - :table (setup) - :name ("Single Sign On") - ) - :color (Blue) - :icon-name (ICON_WC_SSO) - :menu (true) - :sso_setting ( - :AdminInfo ( - :chkpf_uid ("{97AEB65A-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (sso_setting) - ) - :application_name () - :authentication_domain () - :html_sso ( - :AdminInfo ( - :chkpf_uid ("{97AEB659-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (html_sso) - ) - :html_sso_type (logoff) - :login_url () - :logoff_url () - :submit_url () - ) - :sso_type (basic) - ) - :type (Impersonation) - ) - : (Redirection - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:09 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB490-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (Redirection) - :table (setup) - :name (Redirection) - ) - :color (Blue) - :icon-name (ICON_WC_REDIRECTION) - :menu (true) - :redirect_setting () - :type (Redirection) - ) - : ("Insert Header" - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:09 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB491-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (ModifyHeader) - :table (setup) - :name ("Insert Header") - ) - :header_settings () - :color ("Navy Blue") - :icon-name (ICON_WC_MODIFY_HEADER) - :menu (true) - :type (ModifyHeader) - ) - : ("Delete Header" - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:09 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB492-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (DeleteHeader) - :table (setup) - :name ("Delete Header") - ) - :header_settings () - :color ("Navy Blue") - :icon-name (ICON_WC_DELETE_HEADER) - :menu (true) - :type (DeleteHeader) - ) - : (Apply_To_Sub_Folders - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:09 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB493-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (outer_inheritance) - :table (setup) - :name (Apply_To_Sub_Folders) - ) - : (Yes - :AdminInfo ( - :chkpf_uid ("{97AEB660-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (inner_inheritance) - :table (setup) - ) - :color (Black) - :icon-name (ICON_WC_APPLY_TO_SF) - :type (RuleApplied) - ) - :nested_menu (true) - :type (RuleApplied) - ) - : (Do_Not_Apply_To_Sub_Folders - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:09 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB494-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (outer_inheritance) - :table (setup) - :name (Do_Not_Apply_To_Sub_Folders) - ) - : (No - :AdminInfo ( - :chkpf_uid ("{97AEB662-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (inner_inheritance) - :table (setup) - ) - :color (Black) - :icon-name (ICON_WC_NOT_APPLY_TO_SF) - :type (RuleNotApplied) - ) - :nested_menu (true) - :type (RuleNotApplied) - ) - : (RuleInherited - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:09 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB495-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (outer_inheritance) - :table (setup) - :name (RuleInherited) - ) - : (Inherited - :AdminInfo ( - :chkpf_uid ("{97AEB664-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (inner_inheritance) - :table (setup) - ) - :color (Black) - :icon-name (ICON_WC_INHERITED) - :type (RuleInherited) - ) - :nested_menu (true) - :type (RuleInherited) - ) - : (accept - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:09 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB360-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (accept_action) - :table (setup) - :name (accept) - ) - :action () - :macro (RECORD_CONN) - :type (accept) - ) - : (drop - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:09 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB361-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (drop_action) - :table (setup) - :name (drop) - ) - :action () - :macro () - :type (drop) - ) - : (reject - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:09 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB362-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (reject_action) - :table (setup) - :name (reject) - ) - :action () - :macro () - :type (reject) - ) - : ("User Auth" - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:09 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB363-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (user_authenticate) - :table (setup) - :name ("User Auth") - ) - :action () - :dst_options ("Intersect with User Database") - :macro () - :src_options ("Intersect with User Database") - :type (auth_user) - ) - : ("Client Auth" - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:09 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB364-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (client_authenticate) - :table (setup) - :name ("Client Auth") - ) - :accept_track (ReferenceObject - :Table (tracks) - :Name (None) - :Uid ("{97AEB47D-9AEA-11D5-BD16-0090272CCB30}") - ) - :action () - :clauth_refreshable (false) - :clauth_to_hours (0) - :clauth_to_infinite (false) - :clauth_to_minutes (30) - :clauth_track (ReferenceObject - :Table (tracks) - :Name (None) - :Uid ("{97AEB47D-9AEA-11D5-BD16-0090272CCB30}") - ) - :dst_options ("Intersect with User Database") - :enforce_desktop_config (false) - :macro (PASS_CLNTAUTH) - :ruletype ("standard sign on") - :sessions (5) - :sessions_infinite (false) - :signon_method ("manual sign-on") - :src_options ("Intersect with User Database") - :type (auth_client) - ) - : ("Session Auth" - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:09 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB365-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (session_authenticate) - :table (setup) - :name ("Session Auth") - ) - :accept_iff_encrypted (false) - :accept_track (ReferenceObject - :Table (tracks) - :Name (None) - :Uid ("{97AEB47D-9AEA-11D5-BD16-0090272CCB30}") - ) - :action () - :authenticate_with_UA (false) - :dst_options ("Intersect with User Database") - :macro (PASS_SESSION_AUTH) - :ruletype () - :sessions (1) - :sessions_infinite (false) - :snauth.agent (Src) - :src_options ("Intersect with User Database") - :type (auth_session) - ) - : (encrypt - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:09 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB366-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (encrypt) - :table (setup) - :name (encrypt) - ) - :action () - :datam (DES) - :diagnostics-track ( - :AdminInfo ( - :chkpf_uid ("{97AEB66B-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (empty_track) - :table (tracks) - ) - :icon (empty) - :icon-name (icon-empty) - ) - :gateway () - :isakmp.compression (None) - :isakmp.crlreq (false) - :isakmp.data.integrity (MD5) - :isakmp.encryption (3DES) - :isakmp.gateway () - :isakmp.phase2_DH_group (ReferenceObject - :Table (encryption) - :Name ("Group 2 (1024 bit)") - :Uid ("{97AEB629-9AEA-11D5-BD16-0090272CCB30}") - ) - :isakmp.transform (ESP) - :isakmp.use_pfs (false) - :isakmp.useippools (false) - :keym (DES) - :macro (ENCRYPTION) - :mdm (MD5) - :menu_inactive (false) - :scheme (ISAKMP) - :type (encrypt) - ) - : ("Client Encrypt" - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:09 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB367-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (client_encrypt) - :table (setup) - :name ("Client Encrypt") - ) - :action () - :dst_options ("Intersect with User Database") - :enforce_desktop_config (false) - :macro (USER_CLIENT_ENCRYPTION) - :src_options ("Intersect with User Database") - :type (userc) - ) - : (Gateways - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:09 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{1C1F246F-E707-11D4-A32B-0002B3168CEA}") - :ClassName (install_gateways) - :table (setup) - :name (Gateways) - ) - :type (gateways) - ) - : (Dst - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:09 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{1C1F2470-E707-11D4-A32B-0002B3168CEA}") - :ClassName (install_no_gateways) - :table (setup) - :name (Dst) - ) - :type (dst) - ) - : (Src - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:09 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{1C1F2471-E707-11D4-A32B-0002B3168CEA}") - :ClassName (install_no_gateways) - :table (setup) - :name (Src) - ) - :type (src) - ) - : ("OSE Devices" - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:09 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{1C1F2472-E707-11D4-A32B-0002B3168CEA}") - :ClassName (install_no_gateways) - :table (setup) - :name ("OSE Devices") - ) - :type (routers) - ) - : ("Embedded Devices" - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:09 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{1C1F2473-E707-11D4-A32B-0002B3168CEA}") - :ClassName (install_no_gateways) - :table (setup) - :name ("Embedded Devices") - ) - :type (blackboxes) - ) - ) - :methods ( - : (Read_GET - :AdminInfo ( - :chkpf_uid ("{FF4E493B-0014-4E7F-8B3B-7DA92C75041B}") - :ClassName (method) - :table (methods) - :Wiznum (-1) - :object_permissions ( - :AdminInfo ( - :chkpf_uid ("{5397AE69-D63B-4A3A-8861-5FD3CE7E5A34}") - :ClassName (object_permissions) - ) - :manage ( - : (ReferenceObject - :Table (globals) - :Name (Any) - ) - ) - :read ( - : (any) - ) - :use ( - : (any) - ) - :write ( - : () - ) - :owner () - ) - :LastModified ( - :Time ("Sun Dec 16 16:11:27 2001") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :extensions ( - : () - ) - :http_methods ( - : (GET) - ) - :parameters ( - : () - ) - :color (blue) - :comments () - :headers () - :type (method) - ) - : (Write_POST - :AdminInfo ( - :chkpf_uid ("{93AE6EF6-37A8-4ED3-8914-BAE0BCD22935}") - :ClassName (method) - :table (methods) - :Wiznum (-1) - :object_permissions ( - :AdminInfo ( - :chkpf_uid ("{B5DAD06B-8FDC-4BC5-B92D-CEC27B725051}") - :ClassName (object_permissions) - ) - :manage ( - : (ReferenceObject - :Table (globals) - :Name (Any) - ) - ) - :read ( - : (any) - ) - :use ( - : (any) - ) - :write ( - : () - ) - :owner () - ) - :LastModified ( - :Time ("Sun Dec 16 16:11:44 2001") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :extensions ( - : () - ) - :http_methods ( - : (POST) - ) - :parameters ( - : () - ) - :color ("dark green") - :comments () - :headers () - :type (method) - ) - : (Read_HEAD - :AdminInfo ( - :chkpf_uid ("{C5935CBF-2620-4102-9FFC-C28CB02AFC5D}") - :ClassName (method) - :table (methods) - :Wiznum (-1) - :object_permissions ( - :AdminInfo ( - :chkpf_uid ("{D4ABA21C-0EC1-4EC5-A3A3-8E92EA404705}") - :ClassName (object_permissions) - ) - :manage ( - : (ReferenceObject - :Table (globals) - :Name (Any) - ) - ) - :read ( - : (any) - ) - :use ( - : (any) - ) - :write ( - : () - ) - :owner () - ) - :LastModified ( - :Time ("Sun Dec 16 16:11:32 2001") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :extensions ( - : () - ) - :http_methods ( - : (HEAD) - ) - :parameters ( - : () - ) - :color (blue1) - :comments () - :headers () - :type (method) - ) - : (Write_PUT - :AdminInfo ( - :chkpf_uid ("{C19254EF-93B0-451E-B272-D9BCE0F1239B}") - :ClassName (method) - :table (methods) - :Wiznum (-1) - :object_permissions ( - :AdminInfo ( - :chkpf_uid ("{92593670-3E10-4095-A719-407D61AA020D}") - :ClassName (object_permissions) - ) - :manage ( - : (ReferenceObject - :Table (globals) - :Name (Any) - ) - ) - :read ( - : (any) - ) - :use ( - : (any) - ) - :write ( - : () - ) - :owner () - ) - :LastModified ( - :Time ("Sun Dec 16 16:11:56 2001") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :extensions ( - : () - ) - :http_methods ( - : (PUT) - ) - :parameters ( - : () - ) - :color (gold) - :comments () - :headers () - :type (method) - ) - : (Write_DELETE - :AdminInfo ( - :chkpf_uid ("{F1084137-B25B-4BCF-B8AB-A584D75DAA81}") - :ClassName (method) - :table (methods) - :Wiznum (-1) - :object_permissions ( - :AdminInfo ( - :chkpf_uid ("{92B3E91B-DF55-4AD9-A509-8C0D07801DF8}") - :ClassName (object_permissions) - ) - :manage ( - : (ReferenceObject - :Table (globals) - :Name (Any) - ) - ) - :read ( - : (any) - ) - :use ( - : (any) - ) - :write ( - : () - ) - :owner () - ) - :LastModified ( - :Time ("Sun Dec 16 16:11:50 2001") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - :extensions ( - : () - ) - :http_methods ( - : (DELETE) - ) - :parameters ( - : () - ) - :color ("dark orchid") - :comments () - :headers () - :type (method) - ) - : (Read - :AdminInfo ( - :chkpf_uid ("{096BE591-0965-4554-A6C0-699304E494A3}") - :ClassName (method_group) - :table (methods) - :Wiznum (-1) - :object_permissions ( - :AdminInfo ( - :chkpf_uid ("{51E29EA5-F068-420E-A6D4-30D5EFE0A4D7}") - :ClassName (object_permissions) - ) - :manage ( - : (ReferenceObject - :Table (globals) - :Name (Any) - ) - ) - :read ( - : (any) - ) - :use ( - : (any) - ) - :write ( - : () - ) - :owner () - ) - :LastModified ( - :Time ("Sun Dec 16 16:11:03 2001") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - : (ReferenceObject - :Name (Read_GET) - :Table (methods) - :Uid ("{FF4E493B-0014-4E7F-8B3B-7DA92C75041B}") - ) - : (ReferenceObject - :Name (Read_HEAD) - :Table (methods) - :Uid ("{C5935CBF-2620-4102-9FFC-C28CB02AFC5D}") - ) - :color (black) - :comments () - :member_class (method) - :members_query () - :type (group) - ) - : (Write - :AdminInfo ( - :chkpf_uid ("{8597BE82-E4B9-4528-B5CA-8F636B028164}") - :ClassName (method_group) - :table (methods) - :Wiznum (-1) - :object_permissions ( - :AdminInfo ( - :chkpf_uid ("{95212127-F192-4BBB-8807-5692FA4466B5}") - :ClassName (object_permissions) - ) - :manage ( - : (ReferenceObject - :Table (globals) - :Name (Any) - ) - ) - :read ( - : (any) - ) - :use ( - : (any) - ) - :write ( - : () - ) - :owner () - ) - :LastModified ( - :Time ("Sun Dec 16 16:11:39 2001") - :By (CheckPoint) - :From (CheckPoint) - ) - ) - : (ReferenceObject - :Name (Write_DELETE) - :Table (methods) - :Uid ("{F1084137-B25B-4BCF-B8AB-A584D75DAA81}") - ) - : (ReferenceObject - :Name (Write_POST) - :Table (methods) - :Uid ("{93AE6EF6-37A8-4ED3-8914-BAE0BCD22935}") - ) - : (ReferenceObject - :Name (Write_PUT) - :Table (methods) - :Uid ("{C19254EF-93B0-451E-B272-D9BCE0F1239B}") - ) - :color (cyan) - :comments () - :member_class (method) - :members_query () - :type (group) - ) - ) - :globals ( - : (VPN1NetLocalModule - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:09 2001") - :By (CheckPoint) - :From (CheckPoint) - ) - :chkpf_uid ("{97AEB36A-9ADF-11D5-BD16-0090272CCB30}") - :ClassName (any_object) - :table (globals) - :name (VPN1NetLocalModule) - ) - :color (black) - ) - : ("VPN-1 Embedded devices defined as Remote Access" - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:09 2001") - :By (CheckPoint) - :From (CheckPoint) - ) - :chkpf_uid ("{DDEDE17A-CC11-4710-9E0D-47CE7F9B7368}") - :ClassName (any_object) - :table (globals) - :name ("VPN-1 Embedded devices defined as Remote Access") - ) - :color (black) - ) - : ("All Users" - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:09 2001") - :By (CheckPoint) - :From (CheckPoint) - ) - :chkpf_uid ("{97AEB36A-9AEB-11D5-BD16-0090272CCB30}") - :ClassName (any_object) - :table (globals) - :name ("All Users") - ) - :color (black) - ) - : (All_Communities - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:09 2001") - :By (CheckPoint) - :From (CheckPoint) - ) - :chkpf_uid ("{97AEB36A-9AEC-11D5-BD16-0090272CCB30}") - :ClassName (any_object) - :table (globals) - :name (All_Communities) - ) - :color (black) - ) - : (All_GwToGw - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:09 2001") - :By (CheckPoint) - :From (CheckPoint) - ) - :chkpf_uid ("{97AEB36A-9AED-11D5-BD16-0090272CCB30}") - :ClassName (any_object) - :table (globals) - :name (All_GwToGw) - ) - :color (black) - ) - : (All_SR - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:09 2001") - :By (CheckPoint) - :From (CheckPoint) - ) - :chkpf_uid ("{97AEB36A-9AEE-11D5-BD16-0090272CCB30}") - :ClassName (any_object) - :table (globals) - :name (All_SR) - ) - :color (black) - ) - : (LocalVpnDomain - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:09 2001") - :By (CheckPoint) - :From (CheckPoint) - ) - :chkpf_uid ("{97AEB36A-9ADD-11D5-BD16-0090272CCB30}") - :ClassName (any_object) - :table (globals) - :name (LocalVpnDomain) - ) - :color (black) - ) - : (All - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:09 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB368-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (any_object) - :table (globals) - :name (All) - ) - :color (black) - ) - : (Any - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:09 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (any_object) - :table (globals) - :name (Any) - ) - :color (black) - ) - : (None - :AdminInfo ( - :LastModified ( - :Time ("Mon Aug 27 14:54:09 2001") - :By ("Upgrade Process") - :From (keepme) - ) - :chkpf_uid ("{97AEB36A-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (any_object) - :table (globals) - :name (None) - ) - :color (black) - ) - ) - :version (5.41) - :properties ( - : (firewall_properties - :AdminInfo ( - :chkpf_uid ("{97AEB653-9AEA-11D5-BD16-0090272CCB30}") - :ClassName (firewall_properties) - :object_permissions ( - :AdminInfo ( - :chkpf_uid ("{7FBC9AD1-0BBA-4CD0-8C0D-14FF5A81EA14}") - :ClassName (object_permissions) - ) - :manage ( - : (ReferenceObject - :Table (globals) - :Name (Any) - ) - ) - :read ( - : (any) - ) - :use ( - : (any) - ) - :write ( - : () - ) - :owner () - ) - :table (properties) - :Wiznum (-1) - :LastModified ( - :Time ("Mon Jun 6 11:36:25 2005") - :By (andre) - :From (andres-laptop) - ) - ) - :desktop_active_test ( - :0 ( - :AdminInfo ( - :chkpf_uid ("{29C2307A-4E51-11D7-A39D-7F0000011616}") - :ClassName (active_test) - ) - :test_name (ping_loopback) - :test_parameters () - ) - :1 ( - :AdminInfo ( - :chkpf_uid ("{29C234DA-4E51-11D7-A39D-7F0000011616}") - :ClassName (active_test) - ) - :test_name (ping_def_gw) - :test_parameters () - ) - :2 ( - :AdminInfo ( - :chkpf_uid ("{29C238E0-4E51-11D7-A39D-7F0000011616}") - :ClassName (active_test) - ) - :test_name (dttunneltest) - :test_parameters () - ) - ) - :desktop_ike_p1_enc_algs ( - : (DES) - : (3DES) - : (AES-256) - ) - :desktop_ike_p1_hash_algs ( - : (SHA1) - : (MD5) - ) - :desktop_ike_p1_supported_dh_groups ( - : (ReferenceObject - :Name ("Group 2 (1024 bit)") - :Table (encryption) - :Uid ("{97AEB629-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :http_netso_client () - :netso_selected_trusted_domains_list () - :private_ip_ranges ( - : ( - :AdminInfo ( - :chkpf_uid ("{64BC9ED6-414A-11D7-B538-7F0000014646}") - :ClassName (first_and_last_IP) - ) - :ipaddr_first (10.222.0.27) - :ipaddr_last (10.222.0.72) - ) - : ( - :AdminInfo ( - :chkpf_uid ("{64BCA2BE-414A-11D7-B538-7F0000014646}") - :ClassName (first_and_last_IP) - ) - :ipaddr_first (10.222.0.73) - :ipaddr_last (10.222.0.74) - ) - : ( - :AdminInfo ( - :chkpf_uid ("{64BCA660-414A-11D7-B538-7F0000014646}") - :ClassName (first_and_last_IP) - ) - :ipaddr_first (10.222.0.75) - :ipaddr_last (10.222.0.76) - ) - ) - :EnableUserMonitoring (false) - :GW_route_traffic_for_OM_address (false) - :IKE_wait4sync (2) - :IPSEC_SPI_alloc_max (ffff) - :IPSEC_SPI_alloc_min (100) - :PDU_sequence (16) - :SofawareLoader (SofawareLoader) - :VPN_configuration_mode (per_policy) - :accept_domain_tcp (false) - :accept_domain_udp (false) - :accept_fw1_connections (false) - :accept_icmp (false) - :accept_outgoing (false) - :accept_rip (false) - :acceptdecrypt (true) - :active_resolver (true) - :add_nt_groups (false) - :add_radius_groups (false) - :addresstrans (false) - :admin_lock_after_bad_attempts (3) - :admin_lock_after_bad_attempts_enable (false) - :admin_lock_auto_release_timeout (30) - :admin_lock_auto_release_timeout_enable (true) - :admin_lock_send_friendly_error_msg (true) - :adtr_skip_routing_msg (true) - :ahttpclientd_redirected_port () - :ahttpclientd_redirected_protocol () - :ahttpclientd_redirected_url () - :alertcertexpiry (432000) - :alertcmd () - :alertcmd_send_to_system_status (true) - :allow_PDU_sequence (false) - :allow_all_options (false) - :allow_clear_gettopo (false) - :allow_clear_traffic_while_disconnected (false) - :allow_encryption_outgoing_first (false) - :allow_h323_h245_tunneling (false) - :allow_h323_t120 (false) - :allow_h323_through_ras (false) - :allow_install_users_db_on_module (false) - :allow_remote_ra (false) - :allowed_suffix_for_internal_users ("OU=users,O=IsoAAAD.IsoAAAA-es.de..jnbkhk") - :as_failure_limit (5) - :as_radius_free_type (40) - :asm_synatk (false) - :asm_synatk_external_only (true) - :asm_synatk_log (log) - :asm_synatk_log_level (1) - :asm_synatk_threshold (200) - :asm_synatk_timeout (5) - :au_connect_timeout (10) - :au_timeout (15) - :auth_validity_days (14) - :auto_sync_on_install (true) - :auto_sync_on_save (false) - :auto_sync_scheduled (false) - :automatic_policy_update_frequency (10080) - :automatically_open_ca_rules (false) - :block_gtp_in_gtp (true) - :block_reverse_tcp (false) - :block_reverse_tcp_p (first) - :block_reverse_udp (false) - :block_reverse_udp_p (first) - :ca_matchbyname (false) - :ca_wait_mode (false) - :cert_req_ext_key_usage (0) - :cert_start_grace (7200) - :check_flow_labels (false) - :check_length (false) - :clauth_no_log_errors (false) - :clauth_no_resolve (false) - :clauth_tolower_users (false) - :client_max_auth_allowed (3) - :clnt_auth_msg () - :cluster_id_counter (7796) - :cluster_nburst (50) - :conn_limit_notify_interval (3600) - :conn_limit_reached_log (true) - :connections_hashsize (65536) - :connections_limit (25000) - :control_back_compatibility (false) - :cp_gw_default_profile () - :cpcufp_dont_clean_cache (false) - :cpcufp_hash_size (2048) - :cpcufp_timeout (300) - :cpridenable (true) - :cpridenable_p (first) - :create_version_on_install_policy (false) - :crl_end_grace (1800) - :crl_start_grace (1800) - :crlcache_timeout (86400) - :cvp_keep_alive (true) - :dagdhcpenable (true) - :dagdhcpenable_p (first) - :dataconn_pendingtimeout (60) - :dbload_program () - :default_installation (true) - :default_track (ReferenceObject - :Table (tracks) - :Name (AuthAlert) - :Uid ("{97AEB48B-9AEA-11D5-BD16-0090272CCB30}") - ) - :desktop_PS_HA (true) - :desktop_PS_LB (false) - :desktop_activate_ckp_scv (true) - :desktop_application_interception (true) - :desktop_authentication_timeout (60) - :desktop_build_number (0) - :desktop_build_number_9x (0) - :desktop_build_number_nt (0) - :desktop_build_number_w2k (0) - :desktop_cache_fwz_passwords (false) - :desktop_ike_hybrid_support (true) - :desktop_ike_ipcomp_support (true) - :desktop_ike_p2_prop (large) - :desktop_ike_p2_prop_size (small) - :desktop_ike_phase1_use_DH_group (ReferenceObject - :Name ("Group 2 (1024 bit)") - :Table (encryption) - :Uid ("{97AEB629-9AEA-11D5-BD16-0090272CCB30}") - ) - :desktop_ike_preshared_support (true) - :desktop_install_id_9x (0) - :desktop_install_id_nt (0) - :desktop_install_id_w2k (0) - :desktop_keep_alive (true) - :desktop_keep_alive_interval (20) - :desktop_password_expiry (120) - :desktop_perform_ckp_scv_merge (true) - :desktop_pol_frequency (0) - :desktop_policy_expire (60) - :desktop_post_connect_script () - :desktop_post_connect_script_show_window (false) - :desktop_retry_frequency (0) - :desktop_revert_to_backup (500) - :desktop_sda_implicit (false) - :desktop_sda_implicit_frequency (10080) - :desktop_security_non_ip_protocols (true) - :desktop_security_policy_code (2) - :desktop_security_policy_installed (true) - :desktop_security_protect_all_ifc (true) - :desktop_security_send_log (true) - :desktop_security_send_warning (true) - :desktop_silent_topo_update (false) - :desktop_site_default_tcp_ike (false) - :desktop_sw_url_path () - :desktop_sw_url_path_9x () - :desktop_sw_url_path_nt () - :desktop_sw_url_path_w2k () - :desktop_sw_version () - :desktop_to_expire_passwords (false) - :desktop_topology_over_IKE (true) - :desktop_update_at_start (false) - :desktop_update_frequency (0) - :disconnect_on_token_removal (false) - :domain_tcp (false) - :domain_tcp_p (first) - :domain_tcp_router (true) - :domain_tcp_router_p (first) - :domain_udp (false) - :domain_udp_p (first) - :domain_udp_router (true) - :domain_udp_router_p (first) - :dont_popup_hidden_folders_message (false) - :dontvalidatemycerts (false) - :download_community_properties_to_sbox (false) - :dynamic_objects_track (none) - :e2e_measure_interval (3000) - :e2e_poll_interval (5000) - :e2e_session_retrial_period (900) - :e2e_session_timeout (60000) - :e2e_sla_alert (log) - :e2e_statistics_interval (60) - :enable_active_conn_view (true) - :enable_automatic_policy_update (false) - :enable_if_resolving_third_party_clusters (false) - :enable_ip_options (true) - :enable_ip_pool (false) - :enable_ldap_queries (false) - :enable_mep_configuration (false) - :enable_objects_check (true) - :enable_propfind_method (false) - :enable_radius_queries (false) - :enable_remote_user_connect_logs (true) - :enable_reverse_connections (false) - :enable_ssh_conn_to_vpn1_net (false) - :enable_ssl_conn_to_vpn1_net (false) - :enable_tacacs_queries (false) - :enable_tcprpc (false) - :encrypt_dns (true) - :encryption_kernel_logging (true) - :encryption_rule_supports_ippool (false) - :enforce_desktop_config (false) - :enforce_install_on_all_cluster_objects (false) - :enforce_install_on_all_selected_objects (false) - :enforce_suffix_for_internal_users (true) - :entrustProtocolType (cms) - :entrust_renewal_limit (75) - :entrust_renewal_scan_period (0) - :established (true) - :established_p (first) - :established_router (true) - :established_router_p (first) - :export_pkg_on_install_policy (false) - :extranet_check_partners_status_interval (60) - :extranet_crl_grace_period (9000) - :fg_enable_multi_match (false) - :floodgate_preferences ( - :AdminInfo ( - :chkpf_uid ("{3E6FDEB4-414A-11D7-B738-7F0000010606}") - :ClassName (floodgate_properties) - ) - :auth_false_timeout (5) - :auth_query_timeout (3) - :auth_true_timeout (15) - :default_interface_rate (5898240) - :default_max_weight (1000) - :default_weight (10) - :llq_max_percent (20) - :rate_units (Bps) - :turn_on_logging (false) - ) - :flush_crl_cache_file_on_install (false) - :flush_crl_cache_on_install (true) - :force_encryption_on_all_users (false) - :force_udp_encapsulation_gw (false) - :ftp_allow_cmds_before_user (false) - :ftp_dont_accept_site_on_login (false) - :ftp_listen_timeout (3600) - :ftp_msg () - :ftp_msg_max_lines (100) - :ftp_use_cvp_reply_safe (false) - :ftp_use_fwnetso (true) - :ftpdata (true) - :ftppasv (true) - :fw1_enable_p (first) - :fw1enable (true) - :fw_allow_out_of_state_tcp (0) - :fw_clamp_tcp_mss (false) - :fw_dns_xlation (false) - :fw_drop_out_of_state_icmp (true) - :fw_drop_out_of_state_udp (true) - :fw_hmem_maxsize (30) - :fw_hmem_size (6) - :fw_ignore_session_rules (false) - :fw_light_verify (false) - :fw_listen_queue (200) - :fw_log_out_of_seq_tcp (true) - :fw_log_out_of_state_icmp (1) - :fw_log_out_of_state_other (0) - :fw_log_out_of_state_tcp (1) - :fw_log_out_of_state_udp (0) - :fw_salloc_total_alloc_limit (0) - :fwd_wait_for_child_up (true) - :fwfrag_limit (200) - :fwfrag_minsize (0) - :fwfrag_timeout (1) - :fwh323_allow_redirect (false) - :fwh323_force_src_phone (true) - :fwha_sync_outbound_sa (false) - :fwldap_ApplyPwdRulesOnMgmt (false) - :fwldap_CacheSize (1000) - :fwldap_CacheTimeout (900) - :fwldap_DisplayDN (display) - :fwldap_PasswordCheckMethod (1) - :fwldap_PasswordExpiration (90) - :fwldap_RequestTimeout (20) - :fwldap_SizeLimit (10000) - :fwldap_TemplateCacheSize (1000) - :fwldap_UseLDAP (false) - :fwldap_is_PasswordExpiration (false) - :fwldap_max_concurrent_queries (25) - :fwldap_num_of_retry (3) - :fwldap_server_down_time (60) - :fwldap_single_server_conf (false) - :fwldap_support_new_ObscureAuPw (false) - :fwsynatk_max (5000) - :fwsynatk_method (0) - :fwsynatk_timeout (10) - :fwsynatk_warning (1) - :fwurl_filter_pattern (".ida?") - :fwurl_filter_search_depth (0) - :fwurl_filter_url_left_len (0) - :fwurl_filter_url_total_len (0) - :fwz_encap_mtu (1) - :gatewaydir (eitherbound) - :generate_nat_log (true) - :genericd_use_fwnetso (true) - :gp_name () - :gp_type (none) - :gtp_allow_multi_if_ggsn (false) - :gtp_allow_recreate_pdpc (open) - :gtp_anti_spoofing (true) - :gtp_chk_hdr_len (true) - :gtp_code_alert (true) - :gtp_code_alert_p ("before last") - :gtp_delete_upon_error (false) - :gtp_echo_frequency (60) - :gtp_echo_requires_path_in_use (false) - :gtp_loggrace (10) - :gtp_match_any (true) - :gtp_max_req_retransmit (5) - :gtp_rate_limit_alert (true) - :gtp_rate_limit_drop (true) - :gtp_sam_close_upon_delete (false) - :gtp_sequence_deviation_alert (true) - :gtp_sequence_deviation_drop (false) - :gtp_track (log) - :h323_enforce_setup (false) - :h323_init_mem (true) - :h323_log_conn (true) - :h323_t120_timeout (3600) - :hclient_enable_new_interface (false) - :hide_alloc_attempts (50000) - :hide_ldap_size_limit_msg (false) - :hide_max_high_port (60000) - :hide_min_high_port (10000) - :hide_use_CP_GW_wizard (false) - :hide_wac_message (false) - :host_certs_key_size (1024) - :http_add_prev_connection_header (false) - :http_allow_content_disposition (false) - :http_allow_double_slash (false) - :http_allow_ranges (false) - :http_allow_store_reply (false) - :http_avoid_keep_alive (false) - :http_block_java_allow_chunked (false) - :http_block_non_http_response (false) - :http_buffers_size (4096) - :http_connection_method_proxy (false) - :http_connection_method_transparent (true) - :http_connection_method_tunneling (false) - :http_cvp_allow_chunked (false) - :http_disable_ahttpdhtml (false) - :http_disable_automatic_client_auth_redirect (false) - :http_disable_cab_check (false) - :http_disable_content_enc (false) - :http_disable_content_type (false) - :http_dns_cache_timeout (86400) - :http_dont_dns_when_star_port (false) - :http_dont_handle_next_proxy_pw (false) - :http_enable_resolve_by_ip (false) - :http_enable_uri_queries (true) - :http_failed_resolve_timeout (900) - :http_force_down_to_10 (0) - :http_handle_proxy_pw (true) - :http_header_detection ( - :AdminInfo ( - :chkpf_uid ("{29C31148-4E51-11D7-A39D-7F0000011616}") - :ClassName (http_header_detection) - ) - :http_header_names ( - : ( - :AdminInfo ( - :chkpf_uid ("{29C3142C-4E51-11D7-A39D-7F0000011616}") - :ClassName (http_header_pattern) - ) - :log_info () - :match_string (X-kazaa) - :pattern_mode (true) - :regular_exp (X-Kazaa) - ) - : ( - :AdminInfo ( - :chkpf_uid ("{29C31828-4E51-11D7-A39D-7F0000011616}") - :ClassName (http_header_pattern) - ) - :log_info () - :match_string (X-MSN-MESSENGER) - :pattern_mode (true) - :regular_exp (X-MSN-MESSENGER) - ) - ) - :http_header_names_values ( - : ( - :AdminInfo ( - :chkpf_uid ("{29C31C56-4E51-11D7-A39D-7F0000011616}") - :ClassName (http_header_pattern) - ) - :log_info (KaZaA) - :match_string (Server) - :pattern_mode (true) - :regular_exp ("[kK]a[zZ]a[aA]") - ) - : ( - :AdminInfo ( - :chkpf_uid ("{29C32034-4E51-11D7-A39D-7F0000011616}") - :ClassName (http_header_pattern) - ) - :log_info (KaZaA) - :match_string (Host) - :pattern_mode (true) - :regular_exp ("[kK]azaa") - ) - : ( - :AdminInfo ( - :chkpf_uid ("{29C32408-4E51-11D7-A39D-7F0000011616}") - :ClassName (http_header_pattern) - ) - :log_info (Gnutella) - :match_string (User-Agent) - :pattern_mode (true) - :regular_exp ("[gG]nu") - ) - : ( - :AdminInfo ( - :chkpf_uid ("{29C327E6-4E51-11D7-A39D-7F0000011616}") - :ClassName (http_header_pattern) - ) - :log_info ("AOL Messenger \ ICQ") - :match_string (User-Agent) - :pattern_mode (true) - :regular_exp ("Mozilla\/4\.08") - ) - : ( - :AdminInfo ( - :chkpf_uid ("{29C32BC4-4E51-11D7-A39D-7F0000011616}") - :ClassName (http_header_pattern) - ) - :log_info ("AOL Messenger \ ICQ") - :match_string (Server) - :pattern_mode (true) - :regular_exp (AIM) - ) - : ( - :AdminInfo ( - :chkpf_uid ("{29C32FA2-4E51-11D7-A39D-7F0000011616}") - :ClassName (http_header_pattern) - ) - :log_info ("ICQ \ AIM") - :match_string (Content-Type) - :pattern_mode (true) - :regular_exp (AIM) - ) - : ( - :AdminInfo ( - :chkpf_uid ("{29C33376-4E51-11D7-A39D-7F0000011616}") - :ClassName (http_header_pattern) - ) - :log_info ("Msn Messenger") - :match_string (User-Agent) - :pattern_mode (true) - :regular_exp (MSMSGS) - ) - : ( - :AdminInfo ( - :chkpf_uid ("{29C33740-4E51-11D7-A39D-7F0000011616}") - :ClassName (http_header_pattern) - ) - :log_info ("Yahoo Messenger") - :match_string (User-Agent) - :pattern_mode (true) - :regular_exp ("Mozilla\/4\.01") - ) - : ( - :AdminInfo ( - :chkpf_uid ("{29C33B14-4E51-11D7-A39D-7F0000011616}") - :ClassName (http_header_pattern) - ) - :log_info ("Msn Messenger") - :match_string (Content-Type) - :pattern_mode (true) - :regular_exp (x-msn-messenger) - ) - ) - :http_detect_header_pattern_log (alert) - :http_detect_header_pattern_mode (false) - ) - :http_log_every_connection (false) - :http_match_with_host_header (false) - :http_max_auth_password_num (1000) - :http_max_auth_redirect_num (1000) - :http_max_connection_num (4000) - :http_max_held_session_num (1000) - :http_max_realm_num (1000) - :http_max_server_num (10000) - :http_max_session_num (0) - :http_max_url_length (2048) - :http_next_proxy_host () - :http_next_proxy_port () - :http_no_content_length (false) - :http_old_auth_timeout (0) - :http_process_timeout (43200) - :http_proxied_connections_allowed (true) - :http_query_server_for_authorization (false) - :http_redirect_timeout (300) - :http_servers ( - :AdminInfo ( - :chkpf_uid ("{3E71410A-414A-11D7-B738-7F0000010606}") - :ClassName (http_servers) - ) - :ers () - ) - :http_session_timeout (300) - :http_skip_redirect_free (true) - :http_strict_url_parsing (true) - :http_use_cache_hdr (true) - :http_use_cvp_reply_safe (false) - :http_use_default_schemes (false) - :http_use_fwnetso (true) - :http_use_host_h_as_dst (false) - :http_use_proxy_auth_for_other (true) - :http_web_encoding (false) - :http_weeding_allow_chunked (false) - :ica_cert_op_timeout (120000) - :icmpcryptver (1) - :icmpenable (false) - :icmpenable_p ("before last") - :icmpenable_router (true) - :icmpenable_router_p ("before last") - :icmperrors (true) - :icmpreply (true) - :icmptimeout (30) - :ie_proxy_replacement (false) - :ie_proxy_replacement_limit_to_tcpt (true) - :ike_allow_unusual_id_types (false) - :ike_crash_recovery_dag (true) - :ike_crash_recovery_sr (true) - :ike_dos_max_puzzle_time_daip (500) - :ike_dos_max_puzzle_time_gw (500) - :ike_dos_max_puzzle_time_sr (5000) - :ike_dos_protection_identified_initiator (stateless) - :ike_dos_protection_unidentified_initiator (puzzles) - :ike_dos_puzzle_level_identified_initiator (19) - :ike_dos_puzzle_level_unidentified_initiator (19) - :ike_dos_supported_protection_sr (puzzles) - :ike_dos_threshold (70) - :ike_enable_dos_protection (false) - :ike_handle_initial_contact (true) - :ike_hybrid_force_preshared (false) - :ike_hybrid_user_timeout (0) - :ike_log_match_failure (true) - :ike_log_sr_match_failure (false) - :ike_negotiation_timeout (36) - :ike_nokia_crack_user_timeout (0) - :ike_send_initial_contact (false) - :ike_support_aes_128_p1 (false) - :ike_support_dos_protection (true) - :ike_support_nokia_crack (false) - :ike_support_nokia_internal_addr (false) - :ike_support_nokia_nat_traversal (false) - :ike_support_transport_mode (true) - :ike_use_largest_possible_subnets (true) - :imap_msg () - :implied_rule_for_gui_client_range (true) - :increase_hide_capacity (true) - :inform_site_changes (false) - :install_db_on_localhost (mgmt_only) - :interface_addr_anti_spoofing (true) - :ip_pool_log ("IP Exhaustion Log") - :ip_pool_securemote (false) - :ip_pool_unused_return_interval (60) - :ipoptslog (none) - :ipsec_disable_use_orig_if (false) - :isakmp.crlmaxsize (10000) - :isakmp.data.integrity (SHA1) - :isakmp.encryption (3DES) - :isakmp_buffer_recorder_size (256) - :isakmp_dh_exp (300) - :isakmp_force_sr_dh (false) - :isakmp_logging (true) - :isakmpphase1reneg (1440) - :isakmpphase2reneg (3600) - :isakmpphase2renegkbytes (0) - :keep_IKE_SAs (false) - :last_selected_community () - :lbalanced_load_history_percent (0) - :lbalanced_load_period_wakeup_sec (20) - :lbalanced_max_idle_measure_period (1200) - :lbalanced_period_wakeup_sec (30) - :lbalanced_roundtrip_history_percent (85) - :limited_broadcast_anti_spoofing (true) - :liveconns (false) - :load_program () - :load_service_port (18212) - :log_data_conns (false) - :log_default_rule (log) - :log_droped_non_ssl_v3 (true) - :log_established_tcp (true) - :log_implied_rules (true) - :log_ip_pool_allocation (none) - :log_keepalive_minute_to (300) - :log_scv_drops (log) - :log_ssh2_version (true) - :log_switch_size (10) - :loggrace (62) - :logical_servers_persistent_limit (25000) - :logical_servers_persistent_timeout (1800) - :logical_servers_resolve_redirect_url (false) - :logviewer_max_open_sessions_per_admin (5) - :logviewer_max_open_sessions_total (10) - :loopback_anti_spoofing (true) - :looptcp (true) - :looptcp_p (first) - :loopudp (true) - :loopudp_p (first) - :mail_disable_sendmail_CA2003_07 (false) - :mailcmd ("internal_sendmail -s alert -t mailer root") - :mailcmd_send_to_system_status (false) - :maintenance_notification (log) - :max_detail_view_community (7) - :max_num_negs (200) - :maxprocess (256) - :mdl_mismatch_action (ask) - :mdl_per_admin (false) - :mdq_error_mail_send_body (false) - :mdq_mx_ignore_nonauth_response (false) - :mdq_qp_encode_f (true) - :mdq_run_multi_threaded (true) - :mgmtha_active_management_check_period (60) - :mgmtha_alert_type (alert) - :multicast_anti_spoofing (true) - :nat_automatic_arp (true) - :nat_automatic_rules_merge (true) - :nat_dst_client_side (true) - :nat_dst_client_side_manual (false) - :nat_hashsize (16384) - :nat_limit (25000) - :netbios_nat (true) - :netso_trust_win_domains (all) - :network_addr_anti_spoofing (true) - :network_broadcast_anti_spoofing (true) - :new_ftp_interface (false) - :old_fwm_getkey_port (0) - :olderalertcmd () - :olderalertcmd_send_to_system_status (false) - :otherreply (false) - :othertimeout (60) - :outgoing (false) - :outgoing_p ("before last") - :page_timeout () - :pagetimeout (20) - :physical_server_availability_check_interval (20) - :physical_server_check_retries (3) - :pmap_connect_timeout (30) - :pop3_daemon () - :pop3_server () - :prefetch_crls_duration (7200) - :prefetch_crls_if_used_in_the_last_hours (24) - :prefetch_crls_if_used_more_then (1) - :prefetch_crls_on_install (true) - :problem_status_level (29) - :prompt_for_destination (false) - :psswd_min_length (6) - :psswd_min_num_of_lowercase (false) - :psswd_min_num_of_numbers (false) - :psswd_min_num_of_symbols (false) - :psswd_min_num_of_uppercase (false) - :r_access_enable_p (first) - :raccessenable (true) - :radius_connect_timeout (120) - :radius_groups_attr (25) - :radius_retrant_num (2) - :radius_retrant_timeout (5) - :radius_send_framed (false) - :radius_user_timeout (600) - :rate_limit_sampling_interval (1) - :reject_x11_in_any (true) - :remote_auth_group () - :remote_auth_server () - :renew_users_ica_cert (true) - :renew_users_ica_cert_days_before (60) - :resolve_interface_ranges (true) - :resolve_interface_ranges_GW (true) - :resolve_interface_ranges_nated_gw (false) - :resolver_1 ("sys (current system settings)") - :resolver_2 (none) - :resolver_3 (none) - :resolver_4 (none) - :resolver_session_interval (30) - :resolver_ttl (10) - :respawn_process_forever (true) - :respawn_process_interval (3600) - :restrict_fwm_to_gui_clients (true) - :retries (1) - :rip (false) - :rip_p (first) - :rip_router (true) - :rip_router_p (first) - :rlogin_max_auth_allowed (3) - :rlogin_msg () - :rlogin_use_fwnetso (true) - :rpcenable (true) - :rshstderr (false) - :rulebase_uids_in_log (false) - :sam_track (alert) - :save_as_assurance (false) - :save_assurance (false) - :scv_allow_4_1_clients (true) - :scv_client_connection_fail_on_notification (true) - :scv_client_diconnect_on_not_verified (true) - :scv_client_state_notification (silent) - :scv_gw_verify_only_mode (false) - :sdl_netlogon_timeout (0) - :secondary_auto_sync (true) - :secondary_sync_schedule () - :secure_update_package_sessions (10) - :securid_timeout (300) - :send_clear_except_for_address_group () - :send_clear_except_for_non_unique (false) - :send_clear_except_for_specific_addresses (false) - :send_clear_traffic_between_encryption_domains (false) - :session_max_auth_allowed (3) - :show_comm_rules (false) - :show_default_policy_message (false) - :show_old_install_policy (false) - :show_rule_column_through (false) - :show_wac_tab (false) - :show_what_is_new (true) - :silent_policy_update (false) - :silent_update_on_connect (false) - :sip_accept_unknown_messages (false) - :sip_allow_instant_messages (false) - :sip_allow_redirect (true) - :sip_allow_two_media_conns (false) - :sip_enforce_security_reinvite (true) - :sip_max_reinvite (3) - :skey_mdmethod (md4) - :skip_automatic_policy_update_if_authentication_required (true) - :smtp_allow_extended_relay (false) - :smtp_encoded_content_field (false) - :smtp_enforce_hex_encoding (true) - :smtp_exact_str_match (false) - :smtp_force_no_uu_begin_after_decode (true) - :smtp_force_no_uu_begin_before_decode (true) - :smtp_force_no_uu_begin_in_prolog_epilog (true) - :smtp_force_sender_domain (false) - :smtp_force_uu_syntax_check (true) - :smtp_limit_content_buf_size (true) - :smtp_mail_encoding (false) - :smtp_max_file_name_length (512) - :smtp_max_global_headers_size (32768) - :smtp_max_user_name_length (400) - :smtp_msg () - :smtp_rfc821 (true) - :smtp_rfc822 (true) - :smtp_strict_mime_header (true) - :sn_connect_timeout (10) - :sn_timeout (120) - :snauth_old_clients_message () - :snauth_protocol () - :snk_agent_id () - :snk_agent_key () - :snk_server_bkp_ip () - :snk_server_ip () - :snk_timeout (20) - :snmptrapcmd ("internal_snmp_trap localhost") - :snmptrapcmd_send_to_system_status (false) - :sofaware_gw_default_profile () - :spoofalertcmd () - :spoofalertcmd_send_to_system_status (true) - :sr_dont_check_crl (false) - :sr_grace_period (3600) - :sr_same_ip_block (false) - :sr_same_ip_log (true) - :stack_size (0) - :status_mgr_interval_seconds (60) - :stop_connect_when_silent_update_fails (false) - :strip_java (false) - :support_sofaware_HML (false) - :support_sofaware_profiles (true) - :suppress_dont_echo (false) - :sync_archive_timeout (1800) - :sync_outbound_sa_pkt_count (200000) - :tcp_reject (true) - :tcpendtimeout (50) - :tcpestb_grace_period (0) - :tcpstarttimeout (60) - :tcpt_outgoing_port (443) - :tcptimeout (3600) - :telnet_max_auth_allowed (3) - :telnet_msg () - :telnet_use_fwnetso (true) - :timeout (10) - :totally_disable_VPE (false) - :trust_all_capi_trusted_root_cas (false) - :type (firewall_properties) - :udp_encapsulation_by_qm_id (true) - :udp_reject (true) - :udpreply (true) - :udpreply_from_any_port (false) - :udptimeout (40) - :ufp_stat_log_time_interval (10) - :undo_msg (false) - :unify_ctl_data_acct_logs (false) - :upgrade_fp1_and_below_users_ica_cert (true) - :use_CP_GW_wizard (false) - :use_default_gw_profiles (false) - :use_desktop_profile (true) - :use_sites (false) - :use_zero_buf_len (false) - :user_certs_key_size (1024) - :useralert2cmd () - :useralert2cmd_send_to_system_status (true) - :useralert3cmd () - :useralert3cmd_send_to_system_status (true) - :useralertcmd () - :useralertcmd_send_to_system_status (true) - :userc_IKE_NAT (true) - :userc_NAT (true) - :userc_bind_user_to_IP (false) - :userc_crypt_ver (1) - :validate_desktop_security (false) - :version_directory_clear_internal (360) - :version_directory_keep_open (4320) - :vlog_switch_size (10) - :voip_allow_no_from (false) - :vpn_conf_n_key_exch_prob (log) - :vpn_log_spi_release (false) - :vpn_packet_handle_prob (log) - :vpn_peer_ls (false) - :vpn_peer_ls_GW (false) - :vpn_restrict_client_phase2_id (none) - :vpn_success_key_exch (log) - :vpn_tables_early_def (false) - :vpnddcate_nat (none) - :vpnddcate_policy (outbound_and_encrypted) - :vpnddcate_track_accept (log) - :vpnddcate_track_drop (log) - :warn_install_fg_pre_ng (false) - :warn_install_pseudo_rules (true) - :warncertexpiry (2592000) - :write_acct_to_db (false) - ) - ) - :opsec () - :graph_objects ( - : (internet - :AdminInfo ( - :chkpf_uid ("{3A201FF7-D304-4AB4-8913-9F6F86599A64}") - :ClassName (internet_cloud) - :table (graph_objects) - :Wiznum (-1) - :object_permissions ( - :AdminInfo ( - :chkpf_uid ("{C19017E4-6B08-4129-9332-00F269C88EC6}") - :ClassName (object_permissions) - ) - :manage ( - : (ReferenceObject - :Table (globals) - :Name (Any) - ) - ) - :read ( - : (any) - ) - :use ( - : (any) - ) - :write ( - : () - ) - :owner () - ) - :LastModified ( - :Time ("Sun Feb 16 01:18:13 2003") - :By (IsoAAAF) - :From (scratchy) - ) - ) - :color (blue) - :comments () - :type (internet_cloud) - ) - : (Implied - :AdminInfo ( - :chkpf_uid ("{3ACFA416-22F8-4429-8721-D1CF97E3E3E0}") - :ClassName (provisory_network) - :table (graph_objects) - :Wiznum (-1) - :object_permissions ( - :AdminInfo ( - :chkpf_uid ("{81B5D575-621B-4DCA-BBC9-17B6804317D6}") - :ClassName (object_permissions) - ) - :manage ( - : (ReferenceObject - :Table (globals) - :Name (Any) - ) - ) - :read ( - : (any) - ) - :use ( - : (any) - ) - :write ( - : () - ) - :owner () - ) - :LastModified ( - :Time ("Sun Feb 16 01:18:13 2003") - :By (IsoAAAF) - :From (scratchy) - ) - ) - :edges () - :NAT () - :add_adtr_rule (false) - :broadcast (allow) - :color (black) - :comments ("Created by Topology View") - :ipaddr (10.222.0.43) - :location (internal) - :netmask (255.255.255.255) - :operating_system ( - :AdminInfo ( - :chkpf_uid ("{D53BBC4E-3283-4015-9CE4-FFB9586C5970}") - :ClassName (operating_system) - ) - :name () - :sp () - :version () - ) - :type (provisory_network) - ) - : (Disconnected_Objects - :AdminInfo ( - :chkpf_uid ("{305AEB18-78DA-4726-952B-2E6F8088291B}") - :ClassName (folder) - :table (graph_objects) - :Wiznum (-1) - :LastModified ( - :Time ("Thu Apr 1 17:09:19 2004") - :By (holger) - :From (dragonfly) - ) - ) - :color (40) - :comments () - :displayname ("Disconnected Objects") - :foldtype () - :source () - :type (folder) - ) - : (IsoAAAD_locale - :AdminInfo ( - :chkpf_uid ("{FC938747-B0AF-43CA-9406-1877F73AF477}") - :ClassName (folder) - :table (graph_objects) - :Wiznum (-1) - :LastModified ( - :Time ("Fri Apr 9 11:56:31 2004") - :By (IsoAAAF) - :From (scratchy) - ) - ) - :color (40) - :comments () - :displayname ("IsoAAAD locale") - :foldtype ("Fold all") - :source (ReferenceObject - :Name (IsoAAAD) - :Table (network_objects) - :Uid ("{29C40B0A-414C-11D7-AEB8-7F0000013C3C}") - ) - :type (folder) - ) - ) - :keys () - :svn () - :ce_properties () - :customers () - :accounting_schemes () - :statuses () - :securemote () - :credentials_manager () - :desktop_profiles () - :cp_administrators ( - : (guitest - :AdminInfo ( - :chkpf_uid ("{37594F54-C38A-4C4F-969D-6911FC311ECD}") - :ClassName (administrator_profile) - :table (cp_administrators) - :Wiznum (-1) - :LastModified ( - :Time ("Tue Jul 15 16:01:38 2003") - :By (stephan) - :From (vaio) - ) - ) - :LDAP_users_database (true) - :LDAP_users_database_permissions (read_and_write) - :QoS_policy (true) - :QoS_policy_permissions (read_and_write) - :check_point_users_database (true) - :check_point_users_database_permissions (read_and_write) - :color (black) - :comments ("zum wegwerfen") - :gateway_profiles (true) - :gateway_profiles_permissions (read_and_write) - :log_consolidator (true) - :log_consolidator_permissions (read_and_write) - :manage_administrators (true) - :monitoring (true) - :monitoring_permissions (read_and_write) - :objects_database (true) - :objects_database_permissions (read_and_write) - :permissions (read_and_write_all) - :reporting_tool (true) - :reporting_tool_permissions (read_and_write) - :secure_update (true) - :secure_update_permissions (read_and_write) - :security_policies (true) - :security_policies_permissions (read_and_write) - :type (administrator_profile) - :web_access (true) - :web_access_permissions (read_and_write) - :web_security (true) - :web_security_permissions (read_and_write) - ) - : (remotezugriff - :AdminInfo ( - :chkpf_uid ("{562674AF-B351-4239-9EBF-EA556F511C12}") - :ClassName (administrator_profile) - :table (cp_administrators) - :Wiznum (-1) - :LastModified ( - :Time ("Tue Jul 15 16:03:47 2003") - :By (stephan) - :From (vaio) - ) - ) - :LDAP_users_database (true) - :LDAP_users_database_permissions (read_and_write) - :QoS_policy (true) - :QoS_policy_permissions (read_and_write) - :check_point_users_database (true) - :check_point_users_database_permissions (read_and_write) - :color (black) - :comments () - :gateway_profiles (true) - :gateway_profiles_permissions (read_and_write) - :log_consolidator (true) - :log_consolidator_permissions (read_and_write) - :manage_administrators (true) - :monitoring (true) - :monitoring_permissions (read_and_write) - :objects_database (true) - :objects_database_permissions (read_and_write) - :permissions (read_and_write_all) - :reporting_tool (true) - :reporting_tool_permissions (read_and_write) - :secure_update (true) - :secure_update_permissions (read_and_write) - :security_policies (true) - :security_policies_permissions (read_and_write) - :type (administrator_profile) - :web_access (true) - :web_access_permissions (read_and_write) - :web_security (true) - :web_security_permissions (read_and_write) - ) - ) - :trusts () - :web_authority_must_rules () - :web_authority_allow_rules () - :web_authority_effect_rules () - :web_authority_URLs () - :web_sites () - :external_exported_domains () -) diff --git a/roles/test/files/importer/sample-configs/checkpoint_demo/rulebases_5_0.fws b/roles/test/files/importer/sample-configs/checkpoint_demo/rulebases_5_0.fws deleted file mode 100644 index a8d57dbfa6..0000000000 --- a/roles/test/files/importer/sample-configs/checkpoint_demo/rulebases_5_0.fws +++ /dev/null @@ -1,14750 +0,0 @@ -( - :version (5.41) - :rule-base ("##Standard" - :AdminInfo ( - :chkpf_uid ("{2E31C33C-79BB-43EF-AF63-BAEBD8BDEAED}") - :ClassName (firewall_policy) - :table (fw_policies) - :object_permissions ( - :AdminInfo ( - :chkpf_uid ("{16F8DFA4-A2B9-4B94-ADD0-66B7AD44210F}") - :ClassName (object_permissions) - ) - :manage ( - : (ReferenceObject - :Table (globals) - :Name (Any) - ) - ) - :read ( - : (any) - ) - :use ( - : (any) - ) - :write ( - : () - ) - :owner () - ) - :LastModified ( - :Time ("Sun Feb 16 01:18:23 2003") - :By (IsoAAAF) - :From (scratchy) - ) - ) - :queries () - :queries_adtr () - :collection (ReferenceObject - :Name (Standard) - :Table (policies_collections) - :Uid ("{2E49485A-61E2-4F55-A71C-85B9BF5CD9E1}") - ) - :default (0) - :use_VPN_communities (true) - ) - :rule-base ("##IsoAAAA_Simplified" - :AdminInfo ( - :chkpf_uid ("{3FABC5DB-B9FF-4100-BD75-FBC1DD43AF93}") - :ClassName (firewall_policy) - :table (fw_policies) - :LastModified ( - :Time ("Mon Jan 24 13:50:53 2005") - :By (IsoAAAF) - :From (IsoAAADray) - ) - ) - :default (0) - :queries () - :queries_adtr () - :collection (ReferenceObject - :Name (IsoAAAA_Simplified) - :Table (policies_collections) - :Uid ("{26FF70B8-9599-49B4-B6F6-84B7AE0D2EBB}") - ) - :rule ( - :AdminInfo ( - :chkpf_uid ("{A4029F61-9672-4AA3-B1D9-0FF4E8979971}") - :ClassName (security_header_rule) - ) - :action ( - : (drop - :AdminInfo ( - :chkpf_uid ("{5EE13032-A1E1-4538-90BC-6295FD3DFE04}") - :ClassName (drop_action) - :table (setup) - ) - :action () - :macro () - :type (drop) - ) - ) - :comments () - :global_location (middle) - :through ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :time ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :track ( - : (ReferenceObject - :Name (None) - :Table (tracks) - :Uid ("{97AEB47D-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :disabled (true) - :dst ( - :AdminInfo ( - :chkpf_uid ("{5560B804-6408-442F-903B-2B279AE6D9C2}") - :ClassName (rule_destination) - ) - :compound () - :op () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :header_text (test-rules) - :install ( - :AdminInfo ( - :chkpf_uid ("{0B1EB683-1A59-44FF-901C-5FDB9EA65A5E}") - :ClassName (rule_install) - ) - :compound () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :services ( - :AdminInfo ( - :chkpf_uid ("{F8D6F7F5-4582-4256-A0A5-EBFDDB2EF590}") - :ClassName (rule_services) - ) - :compound () - :op () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :src ( - :AdminInfo ( - :chkpf_uid ("{AF27380F-6548-4B83-81FD-1B5EAECAA8F6}") - :ClassName (rule_source) - ) - :compound () - :op () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :state (expanded) - ) - :rule ( - :AdminInfo ( - :chkpf_uid ("{ABC6E209-A440-42E2-A896-CF27A1CA2744}") - :ClassName (security_rule) - ) - :action ( - : (accept - :AdminInfo ( - :chkpf_uid ("{F09D1F04-CBE0-4E12-9454-54CCECE01A9B}") - :ClassName (accept_action) - :table (setup) - ) - :action () - :macro (RECORD_CONN) - :type (accept) - ) - ) - :global_location (middle) - :through ( - : (ReferenceObject - :Name (RemoteAccess) - :Table (communities) - :Uid ("{97AEB677-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :time ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :track ( - : (ReferenceObject - :Name (Log) - :Table (tracks) - :Uid ("{97AEB480-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :comments (vpn_test) - :disabled (true) - :dst ( - :AdminInfo ( - :chkpf_uid ("{65F39402-76F2-45CC-A99C-0903FE70DF4C}") - :ClassName (rule_destination) - ) - :compound () - :op () - : (ReferenceObject - :Name (IsoAAADray.local) - :Table (network_objects) - :Uid ("{75EDBC62-7EB1-4D37-8295-684903FDA75A}") - ) - ) - :install ( - :AdminInfo ( - :chkpf_uid ("{C6DE2209-1A7B-4FCC-B7A7-A1D4EDD793D7}") - :ClassName (rule_install) - ) - :compound () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :services ( - :AdminInfo ( - :chkpf_uid ("{91BC0FDA-33F0-49D8-BC63-FFA85CBAFD40}") - :ClassName (rule_services) - ) - :compound () - :op () - : (ReferenceObject - :Name (NBT) - :Table (services) - :Uid ("{97AEB471-9AEA-11D5-BD16-0090272CCB30}") - ) - : (ReferenceObject - :Name (icmp-requests) - :Table (services) - :Uid ("{97AEB413-9AEA-11D5-BD16-0090272CCB30}") - ) - : (ReferenceObject - :Name (CIFS) - :Table (services) - :Uid ("{2A469820-B502-434C-9340-A377677A6A60}") - ) - : (ReferenceObject - :Name (rdp) - :Table (services) - :Uid ("{5BA0C83F-8D91-465B-9CF6-7DC6AEB84689}") - ) - ) - :src ( - :AdminInfo ( - :chkpf_uid ("{28C21DCF-D0A0-4F40-8017-BCD946EFF41D}") - :ClassName (rule_source) - ) - :compound ( - : (vpn_user@heag_off_upper - :AdminInfo ( - :chkpf_uid ("{ABBA5C5D-AE07-4CF6-A00E-3649064D0BDB}") - :ClassName (rule_user_group) - ) - :at (ReferenceObject - :Name (heag_off_upper) - :Table (network_objects) - :Uid ("{A58E3E67-0517-485F-AA04-97A12BC119C3}") - ) - :color (black) - :type (usrgroup) - ) - ) - :op () - ) - ) - :rule ( - :AdminInfo ( - :chkpf_uid ("{5AFB86A5-E247-411F-AAD7-A8EFDE97A0F5}") - :ClassName (security_rule) - ) - :action ( - : (accept - :AdminInfo ( - :chkpf_uid ("{150ABA94-098B-4CC3-AF8A-BDFED81FC20E}") - :ClassName (accept_action) - :table (setup) - ) - :action () - :macro (RECORD_CONN) - :type (accept) - ) - ) - :comments () - :global_location (middle) - :through ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :time ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :track ( - : (ReferenceObject - :Name (Log) - :Table (tracks) - :Uid ("{97AEB480-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :disabled (true) - :dst ( - :AdminInfo ( - :chkpf_uid ("{5526AF1C-6E4F-4F71-A58E-A1E5F88B62DB}") - :ClassName (rule_destination) - ) - :compound () - :op () - : (ReferenceObject - :Name (Premier_Access) - :Table (network_objects) - :Uid ("{B2BB20AA-B685-426B-96B6-1FB4D8D05135}") - ) - : (ReferenceObject - :Name (IsoAAAD) - :Table (network_objects) - :Uid ("{29C40B0A-414C-11D7-AEB8-7F0000013C3C}") - ) - ) - :install ( - :AdminInfo ( - :chkpf_uid ("{7F41F235-2373-4F38-9141-29AB9CEAD2D8}") - :ClassName (rule_install) - ) - :compound () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :services ( - :AdminInfo ( - :chkpf_uid ("{C2DE3BB7-C1B7-49C9-BC21-97AB3CE81521}") - :ClassName (rule_services) - ) - :compound () - :op () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :src ( - :AdminInfo ( - :chkpf_uid ("{F8ECC436-D19B-4124-9BC3-31C1E3945A36}") - :ClassName (rule_source) - ) - :compound () - :op () - : (ReferenceObject - :Name (IsoAAAD) - :Table (network_objects) - :Uid ("{29C40B0A-414C-11D7-AEB8-7F0000013C3C}") - ) - : (ReferenceObject - :Name (Premier_Access) - :Table (network_objects) - :Uid ("{B2BB20AA-B685-426B-96B6-1FB4D8D05135}") - ) - ) - ) - :rule ( - :AdminInfo ( - :chkpf_uid ("{38429C3B-05FE-49C8-9D8C-83F0AC9661CD}") - :ClassName (security_rule) - ) - :action ( - : (accept - :AdminInfo ( - :chkpf_uid ("{10F8BCF5-D4DD-4ACA-BEC3-1058298A9015}") - :ClassName (accept_action) - :table (setup) - ) - :action () - :macro (RECORD_CONN) - :type (accept) - ) - ) - :global_location (middle) - :through ( - : (ReferenceObject - :Name (RemoteAccess) - :Table (communities) - :Uid ("{97AEB677-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :time ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :track ( - : (ReferenceObject - :Name (Log) - :Table (tracks) - :Uid ("{97AEB480-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :comments ("RAS - Test mit Premier-Access - Tokens") - :disabled (true) - :dst ( - :AdminInfo ( - :chkpf_uid ("{FEABA989-54EB-4D53-96C9-6841B9BBEB4B}") - :ClassName (rule_destination) - ) - :compound () - :op () - : (ReferenceObject - :Name (IsoAAAA-100) - :Table (network_objects) - :Uid ("{BF1C6029-8D5D-4A05-A3AD-4B67E6E7A7AA}") - ) - : (ReferenceObject - :Name (IsoAAAD) - :Table (network_objects) - :Uid ("{29C40B0A-414C-11D7-AEB8-7F0000013C3C}") - ) - ) - :install ( - :AdminInfo ( - :chkpf_uid ("{162F84EF-286D-4D55-B03F-8DC9F535553A}") - :ClassName (rule_install) - ) - :compound () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :services ( - :AdminInfo ( - :chkpf_uid ("{130A495D-1435-441B-98CE-993791EBDA7A}") - :ClassName (rule_services) - ) - :compound () - :op () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :src ( - :AdminInfo ( - :chkpf_uid ("{766EEA30-3B32-455D-A951-52D75F93E1D9}") - :ClassName (rule_source) - ) - :compound ( - : (test@Any - :AdminInfo ( - :chkpf_uid ("{C8439795-0347-401E-9663-4EBE924B0F4B}") - :ClassName (rule_user_group) - ) - :at (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - :color (black) - :type (usrgroup) - ) - ) - :op () - ) - ) - :rule ( - :AdminInfo ( - :chkpf_uid ("{24DC38E2-D64D-40EC-B81B-BE3B27A12CED}") - :ClassName (security_header_rule) - ) - :action ( - : (drop - :AdminInfo ( - :chkpf_uid ("{23D057DA-D1AB-4FFD-B61A-806648650D75}") - :ClassName (drop_action) - :table (setup) - ) - :action () - :macro () - :type (drop) - ) - ) - :comments () - :global_location (middle) - :through ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :time ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :track ( - : (ReferenceObject - :Name (None) - :Table (tracks) - :Uid ("{97AEB47D-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :disabled (true) - :dst ( - :AdminInfo ( - :chkpf_uid ("{690BE832-509A-4F4D-A0A2-C9E665129607}") - :ClassName (rule_destination) - ) - :compound () - :op () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :header_text ("IsoAAAE SecuRemote") - :install ( - :AdminInfo ( - :chkpf_uid ("{67EE9042-BF3D-4971-8346-FA36156A5F74}") - :ClassName (rule_install) - ) - :compound () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :services ( - :AdminInfo ( - :chkpf_uid ("{4C231AF1-095C-4CAA-A12C-2EA5B88E76B9}") - :ClassName (rule_services) - ) - :compound () - :op () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :src ( - :AdminInfo ( - :chkpf_uid ("{F23B90BB-44A6-4F7D-8573-48E730D231EE}") - :ClassName (rule_source) - ) - :compound () - :op () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :state (expanded) - ) - :rule ( - :AdminInfo ( - :chkpf_uid ("{4D877153-65A8-48A9-9D11-B30CA56946EF}") - :ClassName (security_rule) - ) - :action ( - : (accept - :AdminInfo ( - :chkpf_uid ("{D47EFCCA-13C6-4057-A28A-42DD438E32E4}") - :ClassName (accept_action) - :table (setup) - ) - :action () - :macro (RECORD_CONN) - :type (accept) - ) - ) - :comments () - :disabled (false) - :global_location (middle) - :through ( - : (ReferenceObject - :Name (RemoteAccess) - :Table (communities) - :Uid ("{97AEB677-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :time ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :track ( - : (ReferenceObject - :Name (Log) - :Table (tracks) - :Uid ("{97AEB480-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :dst ( - :AdminInfo ( - :chkpf_uid ("{C2778755-3B4C-491C-85A7-E4523035CD2B}") - :ClassName (rule_destination) - ) - :compound () - :op () - : (ReferenceObject - :Name (IsoAAADray.local) - :Table (network_objects) - :Uid ("{75EDBC62-7EB1-4D37-8295-684903FDA75A}") - ) - : (ReferenceObject - :Name (gateway.local) - :Table (network_objects) - :Uid ("{7ED7EF12-A13E-4303-8A6E-C6CC28755C80}") - ) - ) - :install ( - :AdminInfo ( - :chkpf_uid ("{CA2D51EE-4A3F-4FE8-B21C-6532E9E7D2C6}") - :ClassName (rule_install) - ) - :compound () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :services ( - :AdminInfo ( - :chkpf_uid ("{5D51CCD0-95A5-408B-83C0-6F18D2B9A460}") - :ClassName (rule_services) - ) - :compound () - :op () - : (ReferenceObject - :Name (CIFS) - :Table (services) - :Uid ("{2A469820-B502-434C-9340-A377677A6A60}") - ) - : (ReferenceObject - :Name (rdp) - :Table (services) - :Uid ("{5BA0C83F-8D91-465B-9CF6-7DC6AEB84689}") - ) - : (ReferenceObject - :Name (ntp-udp) - :Table (services) - :Uid ("{97AEB404-9AEA-11D5-BD16-0090272CCB30}") - ) - : (ReferenceObject - :Name (domain-udp) - :Table (services) - :Uid ("{97AEB3FA-9AEA-11D5-BD16-0090272CCB30}") - ) - : (ReferenceObject - :Name (http) - :Table (services) - :Uid ("{97AEB3D4-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :src ( - :AdminInfo ( - :chkpf_uid ("{3B379A82-34F3-4A23-B77C-B50EAD80BD53}") - :ClassName (rule_source) - ) - :compound ( - : (Cactus-extern@vpn-sources-IsoAAAA - :AdminInfo ( - :chkpf_uid ("{C7F9820A-4EDD-4187-98D9-CC655885E0D6}") - :ClassName (rule_user_group) - ) - :at (ReferenceObject - :Name (vpn-sources-IsoAAAA) - :Table (network_objects) - :Uid ("{26405A41-425C-4053-8002-497BB82D76B1}") - ) - :color (black) - :type (usrgroup) - ) - ) - :op () - ) - ) - :rule ( - :AdminInfo ( - :chkpf_uid ("{AC6B21DA-86AF-4EB3-B294-3387F815E66E}") - :ClassName (security_rule) - ) - :action ( - : (accept - :AdminInfo ( - :chkpf_uid ("{145513B1-FB45-4B30-9B14-5C07AF404141}") - :ClassName (accept_action) - :table (setup) - ) - :action () - :macro (RECORD_CONN) - :type (accept) - ) - ) - :comments () - :disabled (false) - :global_location (middle) - :through ( - : (ReferenceObject - :Name (RemoteAccess) - :Table (communities) - :Uid ("{97AEB677-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :time ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :track ( - : (ReferenceObject - :Name (Log) - :Table (tracks) - :Uid ("{97AEB480-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :dst ( - :AdminInfo ( - :chkpf_uid ("{B7130E5B-C62A-4BEF-A2B3-3A2306AE0E5A}") - :ClassName (rule_destination) - ) - :compound () - :op () - : (ReferenceObject - :Name (scratchy.local) - :Table (network_objects) - :Uid ("{CFABE50C-C1F6-4FF1-8AC3-3161A3779708}") - ) - ) - :install ( - :AdminInfo ( - :chkpf_uid ("{58B74533-737D-4182-B405-F3EAC537960A}") - :ClassName (rule_install) - ) - :compound () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :services ( - :AdminInfo ( - :chkpf_uid ("{115D6863-5E76-4339-B76F-8AF7B421C12F}") - :ClassName (rule_services) - ) - :compound () - :op () - : (ReferenceObject - :Name (RAdmin-custom) - :Table (services) - :Uid ("{4FB59153-8212-4A12-BC08-0297AA5F0815}") - ) - ) - :src ( - :AdminInfo ( - :chkpf_uid ("{4400E028-7BB5-405F-AE2C-CE84535C3D32}") - :ClassName (rule_source) - ) - :compound ( - : (IsoAAAG-g@vpn-sources-IsoAAAA - :AdminInfo ( - :chkpf_uid ("{23622C19-C400-4C6D-9BCA-E69C2217DE8E}") - :ClassName (rule_user_group) - ) - :at (ReferenceObject - :Name (vpn-sources-IsoAAAA) - :Table (network_objects) - :Uid ("{26405A41-425C-4053-8002-497BB82D76B1}") - ) - :color (black) - :type (usrgroup) - ) - ) - :op () - ) - ) - :rule ( - :AdminInfo ( - :chkpf_uid ("{73F2144F-4C58-4361-94B5-459B469A6541}") - :ClassName (security_rule) - ) - :action ( - : (accept - :AdminInfo ( - :chkpf_uid ("{C72BC9F4-E1B5-4701-AA37-780742F76043}") - :ClassName (accept_action) - :table (setup) - ) - :action () - :macro (RECORD_CONN) - :type (accept) - ) - ) - :comments () - :disabled (false) - :global_location (middle) - :through ( - : (ReferenceObject - :Name (RemoteAccess) - :Table (communities) - :Uid ("{97AEB677-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :time ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :track ( - : (ReferenceObject - :Name (Log) - :Table (tracks) - :Uid ("{97AEB480-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :dst ( - :AdminInfo ( - :chkpf_uid ("{8D75B038-29A6-4DFC-99BE-77BB50F0248D}") - :ClassName (rule_destination) - ) - :compound () - :op () - : (ReferenceObject - :Name (spike.local) - :Table (network_objects) - :Uid ("{4ABDD8DE-0DA2-46E5-B129-85E3977CBD18}") - ) - : (ReferenceObject - :Name (mg.IsoAAAA-es.com) - :Table (network_objects) - :Uid ("{E5BF8260-3615-4476-B638-53CA3A24FEF1}") - ) - ) - :install ( - :AdminInfo ( - :chkpf_uid ("{64D010BF-D0CB-4F9F-9B7A-DBAD17892364}") - :ClassName (rule_install) - ) - :compound () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :services ( - :AdminInfo ( - :chkpf_uid ("{A9590BAB-F46F-4EB7-8125-A4EE6791DD5F}") - :ClassName (rule_services) - ) - :compound () - :op () - : (ReferenceObject - :Name (squid) - :Table (services) - :Uid ("{91C0454D-F70C-44B3-8F2D-70C4A68E9594}") - ) - : (ReferenceObject - :Name (imap) - :Table (services) - :Uid ("{97AEB446-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :src ( - :AdminInfo ( - :chkpf_uid ("{32C8D43F-D47D-4477-9217-8E249CBA8F9E}") - :ClassName (rule_source) - ) - :compound ( - : (Cactus-extern@vpn-sources-IsoAAAA - :AdminInfo ( - :chkpf_uid ("{93AC11B4-FFD0-4DBB-BA60-321FE5E9AD32}") - :ClassName (rule_user_group) - ) - :at (ReferenceObject - :Name (vpn-sources-IsoAAAA) - :Table (network_objects) - :Uid ("{26405A41-425C-4053-8002-497BB82D76B1}") - ) - :color (black) - :type (usrgroup) - ) - ) - :op () - ) - ) - :rule ( - :AdminInfo ( - :chkpf_uid ("{6ADC5431-5B24-47FC-A9A6-F8DC912B0515}") - :ClassName (security_rule) - ) - :action ( - : (accept - :AdminInfo ( - :chkpf_uid ("{BE23F2AE-BA4F-443C-9F3C-8742F71262A5}") - :ClassName (accept_action) - :table (setup) - ) - :action () - :macro (RECORD_CONN) - :type (accept) - ) - ) - :comments () - :disabled (false) - :global_location (middle) - :through ( - : (ReferenceObject - :Name (RemoteAccess) - :Table (communities) - :Uid ("{97AEB677-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :time ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :track ( - : (ReferenceObject - :Name (Log) - :Table (tracks) - :Uid ("{97AEB480-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :dst ( - :AdminInfo ( - :chkpf_uid ("{586E9FDE-3504-4C3C-B1B3-A73F6D3F379B}") - :ClassName (rule_destination) - ) - :compound () - :op () - : (ReferenceObject - :Name (itchy) - :Table (network_objects) - :Uid ("{3B4DF852-5064-4957-B95F-D469C5656467}") - ) - ) - :install ( - :AdminInfo ( - :chkpf_uid ("{067D0452-9D33-44EA-8433-DF53F0333503}") - :ClassName (rule_install) - ) - :compound () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :services ( - :AdminInfo ( - :chkpf_uid ("{656EA975-486E-43AA-B73C-209ED71366BC}") - :ClassName (rule_services) - ) - :compound () - :op () - : (ReferenceObject - :Name (smtp) - :Table (services) - :Uid ("{97AEB3D9-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :src ( - :AdminInfo ( - :chkpf_uid ("{028E2317-59C3-4783-AFA3-8121A808F9D8}") - :ClassName (rule_source) - ) - :compound ( - : (Cactus-extern@vpn-sources-IsoAAAA - :AdminInfo ( - :chkpf_uid ("{3D633953-A379-43C2-BCD5-CFCE90A8F60D}") - :ClassName (rule_user_group) - ) - :at (ReferenceObject - :Name (vpn-sources-IsoAAAA) - :Table (network_objects) - :Uid ("{26405A41-425C-4053-8002-497BB82D76B1}") - ) - :color (black) - :type (usrgroup) - ) - ) - :op () - ) - ) - :rule ( - :AdminInfo ( - :chkpf_uid ("{09847FA8-6AD8-4196-A6BA-C2E5A4380CAF}") - :ClassName (security_rule) - ) - :action ( - : (accept - :AdminInfo ( - :chkpf_uid ("{A98C137A-E74F-4C98-8654-234FBD65C912}") - :ClassName (accept_action) - :table (setup) - ) - :action () - :macro (RECORD_CONN) - :type (accept) - ) - ) - :comments () - :disabled (false) - :global_location (middle) - :through ( - : (ReferenceObject - :Name (RemoteAccess) - :Table (communities) - :Uid ("{97AEB677-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :time ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :track ( - : (ReferenceObject - :Name (Log) - :Table (tracks) - :Uid ("{97AEB480-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :dst ( - :AdminInfo ( - :chkpf_uid ("{AE09F8C4-EE69-4874-A359-DE443685FA10}") - :ClassName (rule_destination) - ) - :compound () - :op () - : (ReferenceObject - :Name (wasp) - :Table (network_objects) - :Uid ("{098B2A74-E220-4AE8-A164-340FED79C9D5}") - ) - ) - :install ( - :AdminInfo ( - :chkpf_uid ("{88454436-C062-4605-BADB-73FD6F534D0F}") - :ClassName (rule_install) - ) - :compound () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :services ( - :AdminInfo ( - :chkpf_uid ("{79BEA1F5-E14E-4C55-B7B2-4765F608CEC4}") - :ClassName (rule_services) - ) - :compound () - :op () - : (ReferenceObject - :Name (ntp-udp) - :Table (services) - :Uid ("{97AEB404-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :src ( - :AdminInfo ( - :chkpf_uid ("{7851EA21-542A-4587-B676-F7DD371446C5}") - :ClassName (rule_source) - ) - :compound ( - : (Cactus-extern@vpn-sources-IsoAAAA - :AdminInfo ( - :chkpf_uid ("{4BC9D4D1-5EE4-45A3-9EE3-77D2B97D21EF}") - :ClassName (rule_user_group) - ) - :at (ReferenceObject - :Name (vpn-sources-IsoAAAA) - :Table (network_objects) - :Uid ("{26405A41-425C-4053-8002-497BB82D76B1}") - ) - :color (black) - :type (usrgroup) - ) - ) - :op () - ) - ) - :rule ( - :AdminInfo ( - :chkpf_uid ("{67784DF8-6440-4F4A-891C-C7062E0F32B0}") - :ClassName (security_rule) - ) - :action ( - : (accept - :AdminInfo ( - :chkpf_uid ("{DE137218-858A-4F21-8F15-2D8D7E4A2595}") - :ClassName (accept_action) - :table (setup) - ) - :action () - :macro (RECORD_CONN) - :type (accept) - ) - ) - :comments () - :disabled (false) - :global_location (middle) - :through ( - : (ReferenceObject - :Name (RemoteAccess) - :Table (communities) - :Uid ("{97AEB677-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :time ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :track ( - : (ReferenceObject - :Name (Log) - :Table (tracks) - :Uid ("{97AEB480-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :dst ( - :AdminInfo ( - :chkpf_uid ("{D29D3530-277E-4D41-86B8-CDFD1640107F}") - :ClassName (rule_destination) - ) - :compound () - :op () - : (ReferenceObject - :Name (wasp) - :Table (network_objects) - :Uid ("{098B2A74-E220-4AE8-A164-340FED79C9D5}") - ) - : (ReferenceObject - :Name (hpux) - :Table (network_objects) - :Uid ("{BF00A847-A0D6-4A75-BE1C-27E7D91EDB55}") - ) - : (ReferenceObject - :Name (sol8) - :Table (network_objects) - :Uid ("{86F22190-7D8D-435D-8906-A346CA12A17C}") - ) - ) - :install ( - :AdminInfo ( - :chkpf_uid ("{35771DD3-A725-4A30-B8D1-2D4DE471A8AA}") - :ClassName (rule_install) - ) - :compound () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :services ( - :AdminInfo ( - :chkpf_uid ("{65CD16B1-1526-40F3-9D70-2C6DE0FD27B8}") - :ClassName (rule_services) - ) - :compound () - :op () - : (ReferenceObject - :Name (telnet) - :Table (services) - :Uid ("{97AEB3CF-9AEA-11D5-BD16-0090272CCB30}") - ) - : (ReferenceObject - :Name (ssh) - :Table (services) - :Uid ("{18EC9EAA-1657-4240-AB97-5F234623336B}") - ) - : (ReferenceObject - :Name (ftp) - :Table (services) - :Uid ("{97AEB3D0-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :src ( - :AdminInfo ( - :chkpf_uid ("{3E20C184-B0AC-458B-AB58-17C5E8D0CB58}") - :ClassName (rule_source) - ) - :compound ( - : (Cactus-extern@vpn-sources-IsoAAAA - :AdminInfo ( - :chkpf_uid ("{4BC9D4D1-5EE4-45A3-9EE3-77D2B97D21EF}") - :ClassName (rule_user_group) - ) - :at (ReferenceObject - :Name (vpn-sources-IsoAAAA) - :Table (network_objects) - :Uid ("{26405A41-425C-4053-8002-497BB82D76B1}") - ) - :color (black) - :type (usrgroup) - ) - ) - :op () - ) - ) - :rule ( - :AdminInfo ( - :chkpf_uid ("{C6951C02-A10A-4757-A85F-5C197D6B95EB}") - :ClassName (security_rule) - ) - :action ( - : (accept - :AdminInfo ( - :chkpf_uid ("{565F4F4F-72D3-42A6-A633-369FEFEF44AF}") - :ClassName (accept_action) - :table (setup) - ) - :action () - :macro (RECORD_CONN) - :type (accept) - ) - ) - :comments () - :disabled (false) - :global_location (middle) - :through ( - : (ReferenceObject - :Name (RemoteAccess) - :Table (communities) - :Uid ("{97AEB677-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :time ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :track ( - : (ReferenceObject - :Name (Log) - :Table (tracks) - :Uid ("{97AEB480-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :dst ( - :AdminInfo ( - :chkpf_uid ("{953252BD-3073-4D69-B49A-86B012FEF76D}") - :ClassName (rule_destination) - ) - :compound () - :op () - : (ReferenceObject - :Name (IsoAAAA-100) - :Table (network_objects) - :Uid ("{BF1C6029-8D5D-4A05-A3AD-4B67E6E7A7AA}") - ) - ) - :install ( - :AdminInfo ( - :chkpf_uid ("{019A9168-EF95-46C7-AFB5-B0788EBDAB4B}") - :ClassName (rule_install) - ) - :compound () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :services ( - :AdminInfo ( - :chkpf_uid ("{63D8350C-2432-4909-91D6-4459C3054B4E}") - :ClassName (rule_services) - ) - :compound () - :op () - : (ReferenceObject - :Name (icmp-requests) - :Table (services) - :Uid ("{97AEB413-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :src ( - :AdminInfo ( - :chkpf_uid ("{D6818DB3-CC9E-498A-B47D-DA9204F004F4}") - :ClassName (rule_source) - ) - :compound ( - : (Cactus-extern@vpn-sources-IsoAAAA - :AdminInfo ( - :chkpf_uid ("{970C0D68-3CEC-47CA-B2C0-EB23C9B56AC8}") - :ClassName (rule_user_group) - ) - :at (ReferenceObject - :Name (vpn-sources-IsoAAAA) - :Table (network_objects) - :Uid ("{26405A41-425C-4053-8002-497BB82D76B1}") - ) - :color (black) - :type (usrgroup) - ) - ) - :op () - ) - ) - :rule ( - :AdminInfo ( - :chkpf_uid ("{84087B02-E15A-4E97-9204-F0F866206B75}") - :ClassName (security_header_rule) - ) - :action ( - : (drop - :AdminInfo ( - :chkpf_uid ("{C1A1378F-A974-41CF-BB10-A3F1D8205A3A}") - :ClassName (drop_action) - :table (setup) - ) - :action () - :macro () - :type (drop) - ) - ) - :comments () - :global_location (middle) - :through ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :time ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :track ( - : (ReferenceObject - :Name (None) - :Table (tracks) - :Uid ("{97AEB47D-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :disabled (true) - :dst ( - :AdminInfo ( - :chkpf_uid ("{6CF2DE51-FF05-4F78-A967-BA8F290325BF}") - :ClassName (rule_destination) - ) - :compound () - :op () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :header_text ("IsoAAAE VPN-GW2GW") - :install ( - :AdminInfo ( - :chkpf_uid ("{478AEC09-B131-41B8-8756-A059E1E43421}") - :ClassName (rule_install) - ) - :compound () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :services ( - :AdminInfo ( - :chkpf_uid ("{8F76A99B-E1AD-4595-B528-588D82877DDE}") - :ClassName (rule_services) - ) - :compound () - :op () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :src ( - :AdminInfo ( - :chkpf_uid ("{E356D6BD-676A-4587-90E7-C31B293579C1}") - :ClassName (rule_source) - ) - :compound () - :op () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :state (expanded) - ) - :rule ( - :AdminInfo ( - :chkpf_uid ("{9BC6A630-0169-4289-962F-8E65E0503D01}") - :ClassName (security_rule) - ) - :action ( - : (accept - :AdminInfo ( - :chkpf_uid ("{B8BB89E7-6B1B-40B6-A600-D2B0066DFF00}") - :ClassName (accept_action) - :table (setup) - ) - :action () - :macro (RECORD_CONN) - :type (accept) - ) - ) - :comments () - :disabled (false) - :global_location (middle) - :through ( - : (ReferenceObject - :Name (All_GwToGw) - :Table (globals) - :Uid ("{97AEB36A-9AED-11D5-BD16-0090272CCB30}") - ) - ) - :time ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :track ( - : (ReferenceObject - :Name (Log) - :Table (tracks) - :Uid ("{97AEB480-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :dst ( - :AdminInfo ( - :chkpf_uid ("{83858D79-EC2C-4812-9B9B-2346DFC72654}") - :ClassName (rule_destination) - ) - :compound () - :op () - : (ReferenceObject - :Name (IsoAAAA-100) - :Table (network_objects) - :Uid ("{BF1C6029-8D5D-4A05-A3AD-4B67E6E7A7AA}") - ) - ) - :install ( - :AdminInfo ( - :chkpf_uid ("{50CB20E0-39A1-42D5-9495-BA814B304829}") - :ClassName (rule_install) - ) - :compound () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :services ( - :AdminInfo ( - :chkpf_uid ("{938E9BAA-A4E0-42DE-B985-4FC332A0008A}") - :ClassName (rule_services) - ) - :compound () - :op () - : (ReferenceObject - :Name (icmp-requests) - :Table (services) - :Uid ("{97AEB413-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :src ( - :AdminInfo ( - :chkpf_uid ("{288657B3-E155-44B2-9023-5BDBB46EF52F}") - :ClassName (rule_source) - ) - :compound () - :op () - : (ReferenceObject - :Name (IsoAAAA_home_tim) - :Table (network_objects) - :Uid ("{BF8F69B9-87C2-464A-9404-239AE8DF66B3}") - ) - ) - ) - :rule ( - :AdminInfo ( - :chkpf_uid ("{B1C875B9-8C29-46BA-AECD-FF8869A04D9B}") - :ClassName (security_rule) - ) - :action ( - : (drop - :AdminInfo ( - :chkpf_uid ("{E8DEC8BB-827E-4253-9F56-CBCB1F0341F4}") - :ClassName (drop_action) - :table (setup) - ) - :action () - :macro () - :type (drop) - ) - ) - :disabled (false) - :global_location (middle) - :through ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :time ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :track ( - : (ReferenceObject - :Name (Log) - :Table (tracks) - :Uid ("{97AEB480-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :comments ("Block unencrypted traffic") - :dst ( - :AdminInfo ( - :chkpf_uid ("{29A8CC60-5F3D-4DD8-9F99-B46580505665}") - :ClassName (rule_destination) - ) - :compound () - :op () - : (ReferenceObject - :Name (IsoAAAA-100) - :Table (network_objects) - :Uid ("{BF1C6029-8D5D-4A05-A3AD-4B67E6E7A7AA}") - ) - ) - :install ( - :AdminInfo ( - :chkpf_uid ("{BA0E4CAF-31C0-45AE-A5AC-BD9DF0BD8FC0}") - :ClassName (rule_install) - ) - :compound () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :services ( - :AdminInfo ( - :chkpf_uid ("{0A5CA41F-1516-447A-AFED-B41AB1BD4637}") - :ClassName (rule_services) - ) - :compound () - :op () - : (ReferenceObject - :Name (icmp-requests) - :Table (services) - :Uid ("{97AEB413-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :src ( - :AdminInfo ( - :chkpf_uid ("{2CF51880-2CD3-4553-9772-807B521B0EC2}") - :ClassName (rule_source) - ) - :compound () - :op () - : (ReferenceObject - :Name (IsoAAAA_home_tim) - :Table (network_objects) - :Uid ("{BF8F69B9-87C2-464A-9404-239AE8DF66B3}") - ) - ) - ) - :rule ( - :AdminInfo ( - :chkpf_uid ("{6607FF6B-96E1-482D-BA53-0BF5182A7090}") - :ClassName (security_header_rule) - ) - :action ( - : (drop - :AdminInfo ( - :chkpf_uid ("{8577970A-781C-48C3-BE45-3E40A2CB5057}") - :ClassName (drop_action) - :table (setup) - ) - :action () - :macro () - :type (drop) - ) - ) - :comments () - :global_location (middle) - :through ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :time ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :track ( - : (ReferenceObject - :Name (None) - :Table (tracks) - :Uid ("{97AEB47D-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :disabled (true) - :dst ( - :AdminInfo ( - :chkpf_uid ("{18B51CA6-7E67-4152-8DD6-9618130738CD}") - :ClassName (rule_destination) - ) - :compound () - :op () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :header_text (Paybox) - :install ( - :AdminInfo ( - :chkpf_uid ("{CA5F1199-9F32-41DD-AD63-A613DC51AD11}") - :ClassName (rule_install) - ) - :compound () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :services ( - :AdminInfo ( - :chkpf_uid ("{F22C4535-8983-42E8-A57D-302F96334404}") - :ClassName (rule_services) - ) - :compound () - :op () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :src ( - :AdminInfo ( - :chkpf_uid ("{C58BFEC0-22AA-43E3-B5AA-A390065EDDE4}") - :ClassName (rule_source) - ) - :compound () - :op () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :state (expanded) - ) - :rule ( - :AdminInfo ( - :chkpf_uid ("{3B7F9B93-E229-49E0-B93C-87797CB2445E}") - :ClassName (security_rule) - ) - :action ( - : (accept - :AdminInfo ( - :chkpf_uid ("{74F856AC-BB86-4DBA-89A6-7F5F3A688179}") - :ClassName (accept_action) - :table (setup) - ) - :action () - :macro (RECORD_CONN) - :type (accept) - ) - ) - :comments () - :disabled (false) - :global_location (middle) - :through ( - : (ReferenceObject - :Name (All_GwToGw) - :Table (globals) - :Uid ("{97AEB36A-9AED-11D5-BD16-0090272CCB30}") - ) - ) - :time ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :track ( - : (ReferenceObject - :Name (Log) - :Table (tracks) - :Uid ("{97AEB480-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :dst ( - :AdminInfo ( - :chkpf_uid ("{FDB351D4-FAF2-46AD-A039-1F0074C8F532}") - :ClassName (rule_destination) - ) - :compound () - :op () - : (ReferenceObject - :Name (paybox-raunheim) - :Table (network_objects) - :Uid ("{0A1725B4-534D-46F1-A8C0-02C3351C8312}") - ) - ) - :install ( - :AdminInfo ( - :chkpf_uid ("{F376EC61-0B15-4184-9B7C-42665CF487FA}") - :ClassName (rule_install) - ) - :compound () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :services ( - :AdminInfo ( - :chkpf_uid ("{D7EAE07F-E937-4414-935E-4992058348A3}") - :ClassName (rule_services) - ) - :compound () - :op () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :src ( - :AdminInfo ( - :chkpf_uid ("{8A44B6BE-A911-435B-918F-FDEF668BDC0F}") - :ClassName (rule_source) - ) - :compound () - :op () - : (ReferenceObject - :Name (IsoAAAA-100) - :Table (network_objects) - :Uid ("{BF1C6029-8D5D-4A05-A3AD-4B67E6E7A7AA}") - ) - ) - ) - :rule ( - :AdminInfo ( - :chkpf_uid ("{0FC24606-8AB3-4136-9D11-AE640332B633}") - :ClassName (security_rule) - ) - :action ( - : (drop - :AdminInfo ( - :chkpf_uid ("{979F3CB1-04B9-429E-9B98-3FD1E474BDB5}") - :ClassName (drop_action) - :table (setup) - ) - :action () - :macro () - :type (drop) - ) - ) - :disabled (false) - :global_location (middle) - :through ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :time ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :track ( - : (ReferenceObject - :Name (Log) - :Table (tracks) - :Uid ("{97AEB480-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :comments ("Block unencrypted traffic") - :dst ( - :AdminInfo ( - :chkpf_uid ("{C9F76D81-A3CD-4EA3-980E-AB19B84A9816}") - :ClassName (rule_destination) - ) - :compound () - :op () - : (ReferenceObject - :Name (paybox-raunheim) - :Table (network_objects) - :Uid ("{0A1725B4-534D-46F1-A8C0-02C3351C8312}") - ) - ) - :install ( - :AdminInfo ( - :chkpf_uid ("{CB49F41A-7DB3-484E-85D0-760FE4933517}") - :ClassName (rule_install) - ) - :compound () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :services ( - :AdminInfo ( - :chkpf_uid ("{57FEBAF2-A9A2-4738-B311-1A980A23FA23}") - :ClassName (rule_services) - ) - :compound () - :op () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :src ( - :AdminInfo ( - :chkpf_uid ("{6F09B75D-4982-49B2-BDEF-89456CA71A33}") - :ClassName (rule_source) - ) - :compound () - :op () - : (ReferenceObject - :Name (IsoAAAA-100) - :Table (network_objects) - :Uid ("{BF1C6029-8D5D-4A05-A3AD-4B67E6E7A7AA}") - ) - ) - ) - :rule ( - :AdminInfo ( - :chkpf_uid ("{01253F2A-C645-4A01-BE58-718F56FA3042}") - :ClassName (security_rule) - ) - :action ( - : (accept - :AdminInfo ( - :chkpf_uid ("{89C021CB-2CFF-42DB-81C0-E9C445E96219}") - :ClassName (accept_action) - :table (setup) - ) - :action () - :macro (RECORD_CONN) - :type (accept) - ) - ) - :comments () - :global_location (middle) - :through ( - : (ReferenceObject - :Name (All_GwToGw) - :Table (globals) - :Uid ("{97AEB36A-9AED-11D5-BD16-0090272CCB30}") - ) - ) - :time ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :track ( - : (ReferenceObject - :Name (Log) - :Table (tracks) - :Uid ("{97AEB480-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :disabled (true) - :dst ( - :AdminInfo ( - :chkpf_uid ("{40845CD1-003B-4E2A-B3CE-268AADDFB0C3}") - :ClassName (rule_destination) - ) - :compound () - :op () - : (ReferenceObject - :Name (paybox-frankfurt) - :Table (network_objects) - :Uid ("{463C45CA-0C86-42DC-9B02-E83E28764370}") - ) - ) - :install ( - :AdminInfo ( - :chkpf_uid ("{B9A528D6-C1C5-4BDB-A503-D1A75758AA29}") - :ClassName (rule_install) - ) - :compound () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :services ( - :AdminInfo ( - :chkpf_uid ("{6C61EA28-FE67-48D0-A2E8-2731F0A34C88}") - :ClassName (rule_services) - ) - :compound () - :op () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :src ( - :AdminInfo ( - :chkpf_uid ("{AF6C276C-BA70-4D17-8940-210D00681C90}") - :ClassName (rule_source) - ) - :compound () - :op () - : (ReferenceObject - :Name (IsoAAAA-100) - :Table (network_objects) - :Uid ("{BF1C6029-8D5D-4A05-A3AD-4B67E6E7A7AA}") - ) - ) - ) - :rule ( - :AdminInfo ( - :chkpf_uid ("{6CE90A16-2A7D-4447-B9B6-DB6C365BEEE0}") - :ClassName (security_rule) - ) - :action ( - : (drop - :AdminInfo ( - :chkpf_uid ("{5FCD7357-7092-482B-9E11-4CEF1BC13361}") - :ClassName (drop_action) - :table (setup) - ) - :action () - :macro () - :type (drop) - ) - ) - :global_location (middle) - :through ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :time ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :track ( - : (ReferenceObject - :Name (Log) - :Table (tracks) - :Uid ("{97AEB480-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :comments ("Block unencrypted traffic") - :disabled (true) - :dst ( - :AdminInfo ( - :chkpf_uid ("{3D5ACDF1-4FEC-4064-A909-23877F7B69C3}") - :ClassName (rule_destination) - ) - :compound () - :op () - : (ReferenceObject - :Name (paybox-frankfurt) - :Table (network_objects) - :Uid ("{463C45CA-0C86-42DC-9B02-E83E28764370}") - ) - ) - :install ( - :AdminInfo ( - :chkpf_uid ("{45F24052-D79F-4CA3-B198-ED301E6F360E}") - :ClassName (rule_install) - ) - :compound () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :services ( - :AdminInfo ( - :chkpf_uid ("{E3DB1CE8-A31E-4F3A-95D8-E0141027E617}") - :ClassName (rule_services) - ) - :compound () - :op () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :src ( - :AdminInfo ( - :chkpf_uid ("{9B286C56-F6B8-4AE8-93B5-7003DC58F959}") - :ClassName (rule_source) - ) - :compound () - :op () - : (ReferenceObject - :Name (IsoAAAA-100) - :Table (network_objects) - :Uid ("{BF1C6029-8D5D-4A05-A3AD-4B67E6E7A7AA}") - ) - ) - ) - :rule ( - :AdminInfo ( - :chkpf_uid ("{7D822D25-45D2-4906-8C8E-72652A4E9C7C}") - :ClassName (security_header_rule) - ) - :action ( - : (drop - :AdminInfo ( - :chkpf_uid ("{8AEAF6EF-1859-4E89-A58F-4F275BF154AA}") - :ClassName (drop_action) - :table (setup) - ) - :action () - :macro () - :type (drop) - ) - ) - :comments () - :global_location (middle) - :through ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :time ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :track ( - : (ReferenceObject - :Name (None) - :Table (tracks) - :Uid ("{97AEB47D-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :disabled (true) - :dst ( - :AdminInfo ( - :chkpf_uid ("{08B3D275-0F89-4C3F-B53E-1E3ECA583C23}") - :ClassName (rule_destination) - ) - :compound () - :op () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :header_text (Internal-Connections) - :install ( - :AdminInfo ( - :chkpf_uid ("{CA6C0AAF-DBCE-4020-B529-4E4449A1EFAA}") - :ClassName (rule_install) - ) - :compound () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :services ( - :AdminInfo ( - :chkpf_uid ("{6FB76A7B-3073-434B-ADDA-81C99060AEBA}") - :ClassName (rule_services) - ) - :compound () - :op () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :src ( - :AdminInfo ( - :chkpf_uid ("{79B42650-50CC-4AD9-A13E-A0E4AB4D7383}") - :ClassName (rule_source) - ) - :compound () - :op () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :state (collapsed) - ) - :rule ( - :AdminInfo ( - :chkpf_uid ("{EACACDFF-02E7-4014-9DA7-1A5487AB8481}") - :ClassName (security_rule) - ) - :action ( - : (accept - :AdminInfo ( - :chkpf_uid ("{87CA79FF-466D-4BCF-B6C4-42FE6346885F}") - :ClassName (accept_action) - :table (setup) - ) - :action () - :macro (RECORD_CONN) - :type (accept) - ) - ) - :comments () - :disabled (false) - :global_location (middle) - :through ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :time ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :track ( - : (ReferenceObject - :Name (Log) - :Table (tracks) - :Uid ("{97AEB480-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :dst ( - :AdminInfo ( - :chkpf_uid ("{38233DD1-F39A-42F7-80B7-74A2F3C959BE}") - :ClassName (rule_destination) - ) - :compound () - :op () - : (ReferenceObject - :Name (IsoAAAD) - :Table (network_objects) - :Uid ("{29C40B0A-414C-11D7-AEB8-7F0000013C3C}") - ) - ) - :install ( - :AdminInfo ( - :chkpf_uid ("{D4207D0B-4AA6-4438-A102-EAF2E08BCABC}") - :ClassName (rule_install) - ) - :compound () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :services ( - :AdminInfo ( - :chkpf_uid ("{0D51549F-279B-4544-97E7-672C85874699}") - :ClassName (rule_services) - ) - :compound () - :op () - : (ReferenceObject - :Name (ssh) - :Table (services) - :Uid ("{18EC9EAA-1657-4240-AB97-5F234623336B}") - ) - : (ReferenceObject - :Name (https) - :Table (services) - :Uid ("{97AEB443-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :src ( - :AdminInfo ( - :chkpf_uid ("{C0F53557-6630-4779-8F85-30AA74C8BB3F}") - :ClassName (rule_source) - ) - :compound () - :op () - : (ReferenceObject - :Name (IsoAAAA-100) - :Table (network_objects) - :Uid ("{BF1C6029-8D5D-4A05-A3AD-4B67E6E7A7AA}") - ) - : (ReferenceObject - :Name (IsoAAAA_home_tim) - :Table (network_objects) - :Uid ("{BF8F69B9-87C2-464A-9404-239AE8DF66B3}") - ) - : (ReferenceObject - :Name (mg.IsoAAAA-es.com) - :Table (network_objects) - :Uid ("{E5BF8260-3615-4476-B638-53CA3A24FEF1}") - ) - ) - ) - :rule ( - :AdminInfo ( - :chkpf_uid ("{C5F973E3-CBB2-4C15-A735-52B51AC9DAE7}") - :ClassName (security_rule) - ) - :action ( - : (accept - :AdminInfo ( - :chkpf_uid ("{396BFDCC-A290-408E-9F92-791EA8CF3616}") - :ClassName (accept_action) - :table (setup) - ) - :action () - :macro (RECORD_CONN) - :type (accept) - ) - ) - :comments () - :disabled (false) - :global_location (middle) - :through ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :time ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :track ( - : (ReferenceObject - :Name (Log) - :Table (tracks) - :Uid ("{97AEB480-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :dst ( - :AdminInfo ( - :chkpf_uid ("{389DDDD2-29F4-4D0F-A969-726529DF0919}") - :ClassName (rule_destination) - ) - :compound () - :op () - : (ReferenceObject - :Name (daba) - :Table (network_objects) - :Uid ("{94817CDB-EA8C-4213-B38D-F4417EA620C6}") - ) - ) - :install ( - :AdminInfo ( - :chkpf_uid ("{D76410C0-68C5-40EA-A75A-9FFB9B0EF2E8}") - :ClassName (rule_install) - ) - :compound () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :services ( - :AdminInfo ( - :chkpf_uid ("{FCA57859-3422-4495-954F-E7D746378008}") - :ClassName (rule_services) - ) - :compound () - :op () - : (ReferenceObject - :Name (ssh) - :Table (services) - :Uid ("{18EC9EAA-1657-4240-AB97-5F234623336B}") - ) - : (ReferenceObject - :Name (mysql) - :Table (services) - :Uid ("{08A07607-EAAA-4A45-AD6E-6020770BD519}") - ) - ) - :src ( - :AdminInfo ( - :chkpf_uid ("{B98DA2C1-079F-4EF2-A67D-5FCEC98B1FE8}") - :ClassName (rule_source) - ) - :compound () - :op () - : (ReferenceObject - :Name (IsoAAAA-100) - :Table (network_objects) - :Uid ("{BF1C6029-8D5D-4A05-A3AD-4B67E6E7A7AA}") - ) - : (ReferenceObject - :Name (IsoAAAA_home_tim) - :Table (network_objects) - :Uid ("{BF8F69B9-87C2-464A-9404-239AE8DF66B3}") - ) - ) - ) - :rule ( - :AdminInfo ( - :chkpf_uid ("{0D4D75A0-8203-453F-9C3E-F68E1995DE88}") - :ClassName (security_rule) - ) - :action ( - : (accept - :AdminInfo ( - :chkpf_uid ("{317B8552-195E-4E2A-8EA7-CEE52B732C38}") - :ClassName (accept_action) - :table (setup) - ) - :action () - :macro (RECORD_CONN) - :type (accept) - ) - ) - :comments () - :disabled (false) - :global_location (middle) - :through ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :time ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :track ( - : (ReferenceObject - :Name (None) - :Table (tracks) - :Uid ("{97AEB47D-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :dst ( - :AdminInfo ( - :chkpf_uid ("{C80F45A6-E7AD-4F87-89A8-31CC7D5A5E53}") - :ClassName (rule_destination) - ) - :compound () - :op () - : (ReferenceObject - :Name (wasp) - :Table (network_objects) - :Uid ("{098B2A74-E220-4AE8-A164-340FED79C9D5}") - ) - ) - :install ( - :AdminInfo ( - :chkpf_uid ("{9D97B55B-160C-46D2-ADFA-6D235D7D9733}") - :ClassName (rule_install) - ) - :compound () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :services ( - :AdminInfo ( - :chkpf_uid ("{8305714C-A6BA-4B6C-A1A9-2E54349BB3ED}") - :ClassName (rule_services) - ) - :compound () - :op () - : (ReferenceObject - :Name (ntp-udp) - :Table (services) - :Uid ("{97AEB404-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :src ( - :AdminInfo ( - :chkpf_uid ("{398C5E6F-5E01-4646-ABAB-BF775B461AE6}") - :ClassName (rule_source) - ) - :compound () - :op () - : (ReferenceObject - :Name (IsoAAAD) - :Table (network_objects) - :Uid ("{29C40B0A-414C-11D7-AEB8-7F0000013C3C}") - ) - ) - ) - :rule ( - :AdminInfo ( - :chkpf_uid ("{A1ACBE88-9F38-4947-B497-B34A2F3878B3}") - :ClassName (security_rule) - ) - :action ( - : (accept - :AdminInfo ( - :chkpf_uid ("{F8FE4FD5-50BE-4D6E-93FE-93071473FFF0}") - :ClassName (accept_action) - :table (setup) - ) - :action () - :macro (RECORD_CONN) - :type (accept) - ) - ) - :comments () - :disabled (false) - :global_location (middle) - :through ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :time ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :track ( - : (ReferenceObject - :Name (None) - :Table (tracks) - :Uid ("{97AEB47D-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :dst ( - :AdminInfo ( - :chkpf_uid ("{442DA9A3-9028-4077-88ED-F676CC39EA6A}") - :ClassName (rule_destination) - ) - :compound () - :op () - : (ReferenceObject - :Name (IsoAAADray.local) - :Table (network_objects) - :Uid ("{75EDBC62-7EB1-4D37-8295-684903FDA75A}") - ) - ) - :install ( - :AdminInfo ( - :chkpf_uid ("{22AF536A-CE60-42B9-8D92-B2B84B1B849A}") - :ClassName (rule_install) - ) - :compound () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :services ( - :AdminInfo ( - :chkpf_uid ("{FE031AD5-4408-419D-9CAC-E33FD47B4872}") - :ClassName (rule_services) - ) - :compound () - :op () - : (ReferenceObject - :Name (domain-udp) - :Table (services) - :Uid ("{97AEB3FA-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :src ( - :AdminInfo ( - :chkpf_uid ("{EA42965D-38DF-4E67-8A06-6BF107BEC1BE}") - :ClassName (rule_source) - ) - :compound () - :op () - : (ReferenceObject - :Name (IsoAAAD) - :Table (network_objects) - :Uid ("{29C40B0A-414C-11D7-AEB8-7F0000013C3C}") - ) - ) - ) - :rule ( - :AdminInfo ( - :chkpf_uid ("{321D1155-8DB8-48D3-8F89-789456335EA5}") - :ClassName (security_rule) - ) - :action ( - : (accept - :AdminInfo ( - :chkpf_uid ("{EF61D86E-D8BD-4E00-83C7-D4D6413AA826}") - :ClassName (accept_action) - :table (setup) - ) - :action () - :macro (RECORD_CONN) - :type (accept) - ) - ) - :comments () - :disabled (false) - :global_location (middle) - :through ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :time ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :track ( - : (ReferenceObject - :Name (Log) - :Table (tracks) - :Uid ("{97AEB480-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :dst ( - :AdminInfo ( - :chkpf_uid ("{6ECE3813-9B88-4B95-8F48-35760521161D}") - :ClassName (rule_destination) - ) - :compound () - :op () - : (ReferenceObject - :Name (spike.local) - :Table (network_objects) - :Uid ("{4ABDD8DE-0DA2-46E5-B129-85E3977CBD18}") - ) - : (ReferenceObject - :Name (mg.IsoAAAA-es.com) - :Table (network_objects) - :Uid ("{E5BF8260-3615-4476-B638-53CA3A24FEF1}") - ) - ) - :install ( - :AdminInfo ( - :chkpf_uid ("{B6B3B97E-55C4-41CA-B951-91FBA42AD24D}") - :ClassName (rule_install) - ) - :compound () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :services ( - :AdminInfo ( - :chkpf_uid ("{E4826F35-742D-4BE5-814E-5ECE6741D719}") - :ClassName (rule_services) - ) - :compound () - :op () - : (ReferenceObject - :Name (syslog) - :Table (services) - :Uid ("{97AEB3E0-9AEA-11D5-BD16-0090272CCB30}") - ) - : (ReferenceObject - :Name (ssh_version_2) - :Table (services) - :Uid ("{CD082D9A-44A6-4CEF-A17D-5541029ADFB3}") - ) - : (ReferenceObject - :Name (domain-udp) - :Table (services) - :Uid ("{97AEB3FA-9AEA-11D5-BD16-0090272CCB30}") - ) - : (ReferenceObject - :Name (smtp) - :Table (services) - :Uid ("{97AEB3D9-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :src ( - :AdminInfo ( - :chkpf_uid ("{CBCA552F-5195-4594-8FCD-DB44E1E54E08}") - :ClassName (rule_source) - ) - :compound () - :op () - : (ReferenceObject - :Name (IsoAAAD) - :Table (network_objects) - :Uid ("{29C40B0A-414C-11D7-AEB8-7F0000013C3C}") - ) - ) - ) - :rule ( - :AdminInfo ( - :chkpf_uid ("{479DFC1D-FE51-4CFB-9A99-4FD1A532B7B4}") - :ClassName (security_header_rule) - ) - :action ( - : (drop - :AdminInfo ( - :chkpf_uid ("{575C62B8-634C-4115-9DF5-3C75BBFBFDEE}") - :ClassName (drop_action) - :table (setup) - ) - :action () - :macro () - :type (drop) - ) - ) - :comments () - :global_location (middle) - :through ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :time ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :track ( - : (ReferenceObject - :Name (None) - :Table (tracks) - :Uid ("{97AEB47D-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :disabled (true) - :dst ( - :AdminInfo ( - :chkpf_uid ("{EF6C7FE7-9266-491E-8933-CC4429B97209}") - :ClassName (rule_destination) - ) - :compound () - :op () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :header_text ("Intern to Spike") - :install ( - :AdminInfo ( - :chkpf_uid ("{CA20EBCF-96AC-402F-87BB-25C0EC09879B}") - :ClassName (rule_install) - ) - :compound () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :services ( - :AdminInfo ( - :chkpf_uid ("{5505712A-4BAB-46F8-BFAF-62A682802247}") - :ClassName (rule_services) - ) - :compound () - :op () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :src ( - :AdminInfo ( - :chkpf_uid ("{3B75D561-22D8-4C61-9CA7-A843272AA499}") - :ClassName (rule_source) - ) - :compound () - :op () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :state (expanded) - ) - :rule ( - :AdminInfo ( - :chkpf_uid ("{F18D892E-EED1-488B-A0D9-832B742CE27B}") - :ClassName (security_rule) - ) - :action ( - : (accept - :AdminInfo ( - :chkpf_uid ("{BD096130-776F-4884-A5E3-66951FEDCAA1}") - :ClassName (accept_action) - :table (setup) - ) - :action () - :macro (RECORD_CONN) - :type (accept) - ) - ) - :comments () - :disabled (false) - :global_location (middle) - :through ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :time ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :track ( - : (ReferenceObject - :Name (Log) - :Table (tracks) - :Uid ("{97AEB480-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :dst ( - :AdminInfo ( - :chkpf_uid ("{69FBBF03-9653-4708-95E4-A3085DA3502E}") - :ClassName (rule_destination) - ) - :compound () - :op () - : (ReferenceObject - :Name (spike.local) - :Table (network_objects) - :Uid ("{4ABDD8DE-0DA2-46E5-B129-85E3977CBD18}") - ) - : (ReferenceObject - :Name (mg.IsoAAAA-es.com) - :Table (network_objects) - :Uid ("{E5BF8260-3615-4476-B638-53CA3A24FEF1}") - ) - : (ReferenceObject - :Name (ras.IsoAAAA-es.com) - :Table (network_objects) - :Uid ("{23B1E779-B8D5-4384-AD60-80E498B77196}") - ) - ) - :install ( - :AdminInfo ( - :chkpf_uid ("{58BE428C-CA30-4DD6-8D0C-DD21E8D5716A}") - :ClassName (rule_install) - ) - :compound () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :services ( - :AdminInfo ( - :chkpf_uid ("{D45CFA85-C7A9-4770-BBA5-38DC95DE2E39}") - :ClassName (rule_services) - ) - :compound () - :op () - : (ReferenceObject - :Name (SpikeServices) - :Table (services) - :Uid ("{9D35FACE-289F-49A6-95C7-13417959BC9D}") - ) - ) - :src ( - :AdminInfo ( - :chkpf_uid ("{CEAC96CA-4B08-4E15-B8E5-F555868B9B9D}") - :ClassName (rule_source) - ) - :compound () - :op () - : (ReferenceObject - :Name (IsoAAAA-100) - :Table (network_objects) - :Uid ("{BF1C6029-8D5D-4A05-A3AD-4B67E6E7A7AA}") - ) - ) - ) - :rule ( - :AdminInfo ( - :chkpf_uid ("{001AA0F0-DFE8-4CAD-9B62-C26E1A5CB9A0}") - :ClassName (security_header_rule) - ) - :action ( - : (drop - :AdminInfo ( - :chkpf_uid ("{339E1791-EB7E-4985-8B54-EBE0E6097CCB}") - :ClassName (drop_action) - :table (setup) - ) - :action () - :macro () - :type (drop) - ) - ) - :comments () - :global_location (middle) - :through ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :time ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :track ( - : (ReferenceObject - :Name (None) - :Table (tracks) - :Uid ("{97AEB47D-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :disabled (true) - :dst ( - :AdminInfo ( - :chkpf_uid ("{A78DD97F-4A53-4494-8F90-EABA9B30D6B5}") - :ClassName (rule_destination) - ) - :compound () - :op () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :header_text ("Intern to DMZ") - :install ( - :AdminInfo ( - :chkpf_uid ("{209BE460-BB82-44DD-817D-FF2E22395B31}") - :ClassName (rule_install) - ) - :compound () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :services ( - :AdminInfo ( - :chkpf_uid ("{E0D91B63-F2A0-4973-B07E-AEDD817454E5}") - :ClassName (rule_services) - ) - :compound () - :op () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :src ( - :AdminInfo ( - :chkpf_uid ("{9BD55163-1255-4D94-BE33-13A5569A02ED}") - :ClassName (rule_source) - ) - :compound () - :op () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :state (expanded) - ) - :rule ( - :AdminInfo ( - :chkpf_uid ("{00477CC9-4940-4C79-B2E6-A137781B1C25}") - :ClassName (security_rule) - ) - :action ( - : (accept - :AdminInfo ( - :chkpf_uid ("{47ACCCC4-3B42-4BE4-8E43-AF61E4E0FB86}") - :ClassName (accept_action) - :table (setup) - ) - :action () - :macro (RECORD_CONN) - :type (accept) - ) - ) - :comments () - :disabled (false) - :global_location (middle) - :through ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :time ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :track ( - : (ReferenceObject - :Name (Log) - :Table (tracks) - :Uid ("{97AEB480-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :dst ( - :AdminInfo ( - :chkpf_uid ("{F16C6F8C-1F05-4B70-87D9-CECE46630C0C}") - :ClassName (rule_destination) - ) - :compound () - :op () - : (ReferenceObject - :Name (Cactus-DMZ1) - :Table (network_objects) - :Uid ("{62523F8E-9AE0-4CC0-82C6-BB41846BA2B7}") - ) - : (ReferenceObject - :Name (Cactus-DMZ2) - :Table (network_objects) - :Uid ("{61AB70E0-5514-43CF-9194-B37A13EC102D}") - ) - ) - :install ( - :AdminInfo ( - :chkpf_uid ("{E18116F6-2DF8-42C8-8F65-D00C902B23AB}") - :ClassName (rule_install) - ) - :compound () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :services ( - :AdminInfo ( - :chkpf_uid ("{FFEF9B1D-B59B-4A07-AEDE-63918094EDB8}") - :ClassName (rule_services) - ) - :compound () - :op () - : (ReferenceObject - :Name (ssh_version_2) - :Table (services) - :Uid ("{CD082D9A-44A6-4CEF-A17D-5541029ADFB3}") - ) - ) - :src ( - :AdminInfo ( - :chkpf_uid ("{2D6919C8-EBF0-46B2-95CE-7FD2AFF8DBF0}") - :ClassName (rule_source) - ) - :compound () - :op () - : (ReferenceObject - :Name (IsoAAAA-100) - :Table (network_objects) - :Uid ("{BF1C6029-8D5D-4A05-A3AD-4B67E6E7A7AA}") - ) - ) - ) - :rule ( - :AdminInfo ( - :chkpf_uid ("{2CDC82FD-6292-45D7-A4B8-6794C378A47B}") - :ClassName (security_rule) - ) - :action ( - : (accept - :AdminInfo ( - :chkpf_uid ("{DBFD040E-D17D-481F-B6E2-D9E5AE306BBD}") - :ClassName (accept_action) - :table (setup) - ) - :action () - :macro (RECORD_CONN) - :type (accept) - ) - ) - :comments () - :disabled (false) - :global_location (middle) - :through ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :time ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :track ( - : (ReferenceObject - :Name (Log) - :Table (tracks) - :Uid ("{97AEB480-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :dst ( - :AdminInfo ( - :chkpf_uid ("{AAADBB03-1A01-4136-8104-91B265E567A3}") - :ClassName (rule_destination) - ) - :compound () - :op () - : (ReferenceObject - :Name (Cactus10.222.0.1) - :Table (network_objects) - :Uid ("{6CD51061-638B-4B2F-9092-7E1E4A5F0ADD}") - ) - ) - :install ( - :AdminInfo ( - :chkpf_uid ("{77D96FA7-8F8F-4F17-9F1C-868F1472C870}") - :ClassName (rule_install) - ) - :compound () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :services ( - :AdminInfo ( - :chkpf_uid ("{A042A0B6-6CD8-4A84-90A5-B39B35590148}") - :ClassName (rule_services) - ) - :compound () - :op () - : (ReferenceObject - :Name (VNC) - :Table (services) - :Uid ("{9788B566-735E-4158-A169-8701B9624E47}") - ) - ) - :src ( - :AdminInfo ( - :chkpf_uid ("{2F62C069-51CA-424D-A3EB-235DD9728611}") - :ClassName (rule_source) - ) - :compound () - :op () - : (ReferenceObject - :Name (IsoAAAA-100) - :Table (network_objects) - :Uid ("{BF1C6029-8D5D-4A05-A3AD-4B67E6E7A7AA}") - ) - ) - ) - :rule ( - :AdminInfo ( - :chkpf_uid ("{8EDEBE48-F02B-4AEA-8337-FBE1E2079BE0}") - :ClassName (security_rule) - ) - :action ( - : (accept - :AdminInfo ( - :chkpf_uid ("{47CF3B75-BE35-45E1-B56E-B8A61ECE885B}") - :ClassName (accept_action) - :table (setup) - ) - :action () - :macro (RECORD_CONN) - :type (accept) - ) - ) - :comments () - :disabled (false) - :global_location (middle) - :through ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :time ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :track ( - : (ReferenceObject - :Name (Log) - :Table (tracks) - :Uid ("{97AEB480-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :dst ( - :AdminInfo ( - :chkpf_uid ("{7149B69F-E170-4FCC-B958-76AE0F704EA0}") - :ClassName (rule_destination) - ) - :compound () - :op () - : (ReferenceObject - :Name (itchy) - :Table (network_objects) - :Uid ("{3B4DF852-5064-4957-B95F-D469C5656467}") - ) - ) - :install ( - :AdminInfo ( - :chkpf_uid ("{50C640DC-6413-458C-BD30-9E947F408315}") - :ClassName (rule_install) - ) - :compound () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :services ( - :AdminInfo ( - :chkpf_uid ("{3F4AF5D6-72D0-4C52-A1BD-29AB242927D0}") - :ClassName (rule_services) - ) - :compound () - :op () - : (ReferenceObject - :Name (domain-udp) - :Table (services) - :Uid ("{97AEB3FA-9AEA-11D5-BD16-0090272CCB30}") - ) - : (ReferenceObject - :Name (CIFS) - :Table (services) - :Uid ("{2A469820-B502-434C-9340-A377677A6A60}") - ) - ) - :src ( - :AdminInfo ( - :chkpf_uid ("{EA36998F-4F7C-4250-BECC-4CEBB36E9EAE}") - :ClassName (rule_source) - ) - :compound () - :op () - : (ReferenceObject - :Name (IsoAAAA-100) - :Table (network_objects) - :Uid ("{BF1C6029-8D5D-4A05-A3AD-4B67E6E7A7AA}") - ) - ) - ) - :rule ( - :AdminInfo ( - :chkpf_uid ("{0F6D252E-7562-457F-81A3-60192F3EC815}") - :ClassName (security_rule) - ) - :action ( - : (accept - :AdminInfo ( - :chkpf_uid ("{0CEE5A08-F53C-439A-8180-A62450938BA6}") - :ClassName (accept_action) - :table (setup) - ) - :action () - :macro (RECORD_CONN) - :type (accept) - ) - ) - :comments () - :disabled (false) - :global_location (middle) - :through ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :time ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :track ( - : (ReferenceObject - :Name (Log) - :Table (tracks) - :Uid ("{97AEB480-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :dst ( - :AdminInfo ( - :chkpf_uid ("{C414C09F-B8D2-4DD6-8DD1-B5044B787753}") - :ClassName (rule_destination) - ) - :compound () - :op () - : (ReferenceObject - :Name (MailServer) - :Table (network_objects) - :Uid ("{17935795-6ADC-4B45-8E2B-BEC361E6CAB1}") - ) - ) - :install ( - :AdminInfo ( - :chkpf_uid ("{1ADD0F50-D00E-463E-AF4B-5F7B9602F8FB}") - :ClassName (rule_install) - ) - :compound () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :services ( - :AdminInfo ( - :chkpf_uid ("{F89128E4-058B-45CC-8BE9-62261DDB22A0}") - :ClassName (rule_services) - ) - :compound () - :op () - : (ReferenceObject - :Name (smtp) - :Table (services) - :Uid ("{97AEB3D9-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :src ( - :AdminInfo ( - :chkpf_uid ("{1265804A-4F79-416E-ABDC-2BC3BC6E9513}") - :ClassName (rule_source) - ) - :compound () - :op () - : (ReferenceObject - :Name (IsoAAAA-100) - :Table (network_objects) - :Uid ("{BF1C6029-8D5D-4A05-A3AD-4B67E6E7A7AA}") - ) - ) - ) - :rule ( - :AdminInfo ( - :chkpf_uid ("{A3B9D85B-AD6D-4991-8A9D-960939C491C2}") - :ClassName (security_rule) - ) - :action ( - : (accept - :AdminInfo ( - :chkpf_uid ("{C8749F14-4AE2-4544-B239-7CC349656359}") - :ClassName (accept_action) - :table (setup) - ) - :action () - :macro (RECORD_CONN) - :type (accept) - ) - ) - :comments () - :disabled (false) - :global_location (middle) - :through ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :time ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :track ( - : (ReferenceObject - :Name (None) - :Table (tracks) - :Uid ("{97AEB47D-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :dst ( - :AdminInfo ( - :chkpf_uid ("{A7BD46F5-7D1D-424F-BBB4-CCE8564D68C7}") - :ClassName (rule_destination) - ) - :compound () - :op () - : (ReferenceObject - :Name (wasp) - :Table (network_objects) - :Uid ("{098B2A74-E220-4AE8-A164-340FED79C9D5}") - ) - ) - :install ( - :AdminInfo ( - :chkpf_uid ("{E6AF42B5-C12E-4E59-8C3E-5D231C5B0D34}") - :ClassName (rule_install) - ) - :compound () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :services ( - :AdminInfo ( - :chkpf_uid ("{A22EE9B9-C603-4998-B273-1568DE4BB27A}") - :ClassName (rule_services) - ) - :compound () - :op () - : (ReferenceObject - :Name (ntp-udp) - :Table (services) - :Uid ("{97AEB404-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :src ( - :AdminInfo ( - :chkpf_uid ("{D0402416-F879-4AD4-88E6-A1DBFEA44546}") - :ClassName (rule_source) - ) - :compound () - :op () - : (ReferenceObject - :Name (IsoAAAA-100) - :Table (network_objects) - :Uid ("{BF1C6029-8D5D-4A05-A3AD-4B67E6E7A7AA}") - ) - ) - ) - :rule ( - :AdminInfo ( - :chkpf_uid ("{7C9A68ED-6420-4D5E-BE91-F7ACE4B90AA5}") - :ClassName (security_header_rule) - ) - :action ( - : (drop - :AdminInfo ( - :chkpf_uid ("{D4BF36D5-49FA-49BD-ADE1-87E488A684D6}") - :ClassName (drop_action) - :table (setup) - ) - :action () - :macro () - :type (drop) - ) - ) - :comments () - :global_location (middle) - :through ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :time ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :track ( - : (ReferenceObject - :Name (None) - :Table (tracks) - :Uid ("{97AEB47D-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :disabled (true) - :dst ( - :AdminInfo ( - :chkpf_uid ("{251B6C16-21CB-4CCE-9B3B-62B66C6F6390}") - :ClassName (rule_destination) - ) - :compound () - :op () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :header_text ("Intern to Internet") - :install ( - :AdminInfo ( - :chkpf_uid ("{A9221EAB-A00F-4E3F-83DF-D44CBC08AFBD}") - :ClassName (rule_install) - ) - :compound () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :services ( - :AdminInfo ( - :chkpf_uid ("{AECCDBA3-A006-464E-9BD9-691255CA5841}") - :ClassName (rule_services) - ) - :compound () - :op () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :src ( - :AdminInfo ( - :chkpf_uid ("{5B2CFCAD-0A44-4BA9-BFF7-6734B5644C85}") - :ClassName (rule_source) - ) - :compound () - :op () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :state (collapsed) - ) - :rule ( - :AdminInfo ( - :chkpf_uid ("{E6AB0ADC-7E23-4B1D-B568-E47FF7B3D4F5}") - :ClassName (security_rule) - ) - :action ( - : (accept - :AdminInfo ( - :chkpf_uid ("{5B685C0A-3095-483A-8DE1-F539677A7707}") - :ClassName (accept_action) - :table (setup) - ) - :action () - :macro (RECORD_CONN) - :type (accept) - ) - ) - :comments () - :disabled (false) - :global_location (middle) - :through ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :time ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :track ( - : (ReferenceObject - :Name (Log) - :Table (tracks) - :Uid ("{97AEB480-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :dst ( - :AdminInfo ( - :chkpf_uid ("{2C9F2F69-7532-4711-A950-C884E1AFD3F5}") - :ClassName (rule_destination) - ) - :compound () - :op () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :install ( - :AdminInfo ( - :chkpf_uid ("{EACA5120-76C3-48CE-AB41-59266A354E0A}") - :ClassName (rule_install) - ) - :compound () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :services ( - :AdminInfo ( - :chkpf_uid ("{DB45ABD4-20F0-4BC8-BD73-294945142FB8}") - :ClassName (rule_services) - ) - :compound () - :op () - : (ReferenceObject - :Name (T-online-classic) - :Table (services) - :Uid ("{738B04E5-09F7-44BF-9FEC-AEA0F15B7E9A}") - ) - : (ReferenceObject - :Name (HBCI) - :Table (services) - :Uid ("{336C93F8-5CC2-48BE-9328-2E92F61EFCF1}") - ) - ) - :src ( - :AdminInfo ( - :chkpf_uid ("{85CAFABE-730E-4DDB-A878-219BD2893B63}") - :ClassName (rule_source) - ) - :compound () - :op () - : (ReferenceObject - :Name (IsoAAAA-100) - :Table (network_objects) - :Uid ("{BF1C6029-8D5D-4A05-A3AD-4B67E6E7A7AA}") - ) - ) - ) - :rule ( - :AdminInfo ( - :chkpf_uid ("{1F4E5C97-C290-48AF-84A5-C1A13178FDB7}") - :ClassName (security_rule) - ) - :action ( - : (accept - :AdminInfo ( - :chkpf_uid ("{DCDCFD96-219D-49B7-B817-8BB52C598AB8}") - :ClassName (accept_action) - :table (setup) - ) - :action () - :macro (RECORD_CONN) - :type (accept) - ) - ) - :comments () - :disabled (false) - :global_location (middle) - :through ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :time ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :track ( - : (ReferenceObject - :Name (Log) - :Table (tracks) - :Uid ("{97AEB480-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :dst ( - :AdminInfo ( - :chkpf_uid ("{3A1A50EC-0F20-4C79-80D7-FDCBEDAF50AF}") - :ClassName (rule_destination) - ) - :compound () - :op () - : (ReferenceObject - :Name (t-onlineUpdate) - :Table (network_objects) - :Uid ("{99089D97-0EB3-4CE6-8C78-79BC61ECE307}") - ) - ) - :install ( - :AdminInfo ( - :chkpf_uid ("{4D0B21D7-8DA0-49D5-9AD2-3F7BBA001C56}") - :ClassName (rule_install) - ) - :compound () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :services ( - :AdminInfo ( - :chkpf_uid ("{0C60636A-9D3B-44D2-9742-966C92ED77A2}") - :ClassName (rule_services) - ) - :compound () - :op () - : (ReferenceObject - :Name (http) - :Table (services) - :Uid ("{97AEB3D4-9AEA-11D5-BD16-0090272CCB30}") - ) - : (ReferenceObject - :Name (https) - :Table (services) - :Uid ("{97AEB443-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :src ( - :AdminInfo ( - :chkpf_uid ("{C9F5FA9C-6AE5-4A04-B68F-E3CFBE3C1043}") - :ClassName (rule_source) - ) - :compound () - :op () - : (ReferenceObject - :Name (IsoAAAA-100) - :Table (network_objects) - :Uid ("{BF1C6029-8D5D-4A05-A3AD-4B67E6E7A7AA}") - ) - ) - ) - :rule ( - :AdminInfo ( - :chkpf_uid ("{8D43F752-841E-4B9E-B610-635F7C17D4D9}") - :ClassName (security_rule) - ) - :action ( - : (accept - :AdminInfo ( - :chkpf_uid ("{7A10F249-7751-407A-A390-A6B878A85D56}") - :ClassName (accept_action) - :table (setup) - ) - :action () - :macro (RECORD_CONN) - :type (accept) - ) - ) - :comments () - :disabled (false) - :global_location (middle) - :through ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :time ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :track ( - : (ReferenceObject - :Name (Log) - :Table (tracks) - :Uid ("{97AEB480-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :dst ( - :AdminInfo ( - :chkpf_uid ("{B42E38C5-299A-4B0E-A7BE-6D87D1206A3C}") - :ClassName (rule_destination) - ) - :compound () - :op () - : (ReferenceObject - :Name (auth1.lhsystems.com) - :Table (network_objects) - :Uid ("{D60E902E-4BE8-43E0-95DC-BFE60E86965F}") - ) - : (ReferenceObject - :Name (LSYI-pptp) - :Table (network_objects) - :Uid ("{DF2F1A45-9938-4006-A550-0421F3DAA3E2}") - ) - ) - :install ( - :AdminInfo ( - :chkpf_uid ("{42DAAE37-A625-47E5-AC05-72E3E3A9F3FE}") - :ClassName (rule_install) - ) - :compound () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :services ( - :AdminInfo ( - :chkpf_uid ("{F8D3DE95-02BB-43E8-B759-01E5AE00233C}") - :ClassName (rule_services) - ) - :compound () - :op () - : (ReferenceObject - :Name (FW1_clntauth_telnet) - :Table (services) - :Uid ("{97AEB38B-9AEA-11D5-BD16-0090272CCB30}") - ) - : (ReferenceObject - :Name (PPTP) - :Table (services) - :Uid ("{97AEB426-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :src ( - :AdminInfo ( - :chkpf_uid ("{B2C3E31C-B79E-49A9-B7A8-2F38E3C21DCF}") - :ClassName (rule_source) - ) - :compound () - :op () - : (ReferenceObject - :Name (IsoAAAA-100) - :Table (network_objects) - :Uid ("{BF1C6029-8D5D-4A05-A3AD-4B67E6E7A7AA}") - ) - ) - ) - :rule ( - :AdminInfo ( - :chkpf_uid ("{167BC623-43EB-405D-BC29-442298C96DC9}") - :ClassName (security_rule) - ) - :action ( - : (accept - :AdminInfo ( - :chkpf_uid ("{BB10481F-21F5-4244-A6BB-29318E780DF1}") - :ClassName (accept_action) - :table (setup) - ) - :action () - :macro (RECORD_CONN) - :type (accept) - ) - ) - :comments () - :disabled (false) - :global_location (middle) - :through ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :time ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :track ( - : (ReferenceObject - :Name (Log) - :Table (tracks) - :Uid ("{97AEB480-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :dst ( - :AdminInfo ( - :chkpf_uid ("{E9BE5C8E-9CAE-4D88-9235-F5AC9030CF0F}") - :ClassName (rule_destination) - ) - :compound () - :op () - : (ReferenceObject - :Table (network_objects) - :Name (mail.light-life.netOld) - :Uid ("{DF004F13-7986-4569-811C-6EC7391A8764}") - ) - ) - :install ( - :AdminInfo ( - :chkpf_uid ("{CDBC19FF-C00F-4304-9D1D-B5BBDAA5D15A}") - :ClassName (rule_install) - ) - :compound () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :services ( - :AdminInfo ( - :chkpf_uid ("{4BE203D0-3DE8-44FE-B942-E5E26C62E861}") - :ClassName (rule_services) - ) - :compound () - :op () - : (ReferenceObject - :Name (smtp) - :Table (services) - :Uid ("{97AEB3D9-9AEA-11D5-BD16-0090272CCB30}") - ) - : (ReferenceObject - :Name (pop-3) - :Table (services) - :Uid ("{97AEB3DB-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :src ( - :AdminInfo ( - :chkpf_uid ("{C3E9CE29-9F23-4857-B88F-E9949FAF2D5D}") - :ClassName (rule_source) - ) - :compound () - :op () - : (ReferenceObject - :Name (speedy2) - :Table (network_objects) - :Uid ("{B4DB2EF5-42D8-41DC-9A1C-33310FDFB184}") - ) - ) - ) - :rule ( - :AdminInfo ( - :chkpf_uid ("{11C81B0A-4266-4801-8858-E4D9AB54A830}") - :ClassName (security_header_rule) - ) - :action ( - : (drop - :AdminInfo ( - :chkpf_uid ("{5E568AEF-0F52-4A93-AFA3-18E73A0D066A}") - :ClassName (drop_action) - :table (setup) - ) - :action () - :macro () - :type (drop) - ) - ) - :comments () - :global_location (middle) - :through ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :time ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :track ( - : (ReferenceObject - :Name (None) - :Table (tracks) - :Uid ("{97AEB47D-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :disabled (true) - :dst ( - :AdminInfo ( - :chkpf_uid ("{366C4CAD-81FB-4025-8D13-601F4A6C8FF7}") - :ClassName (rule_destination) - ) - :compound () - :op () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :header_text ("Access from Spike & DMZ to Internal") - :install ( - :AdminInfo ( - :chkpf_uid ("{47C0018E-3514-4540-A4EA-659755890D6B}") - :ClassName (rule_install) - ) - :compound () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :services ( - :AdminInfo ( - :chkpf_uid ("{0073E27C-28E5-4EC1-9A4A-BD686F700281}") - :ClassName (rule_services) - ) - :compound () - :op () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :src ( - :AdminInfo ( - :chkpf_uid ("{BD3EBBCD-06DF-4313-A347-7097F5105671}") - :ClassName (rule_source) - ) - :compound () - :op () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :state (expanded) - ) - :rule ( - :AdminInfo ( - :chkpf_uid ("{A8A57015-68D5-4341-ADD1-895EC21419DB}") - :ClassName (security_rule) - ) - :action ( - : (accept - :AdminInfo ( - :chkpf_uid ("{BECC33F6-C362-41A4-BBD3-CBFA34A7C4E8}") - :ClassName (accept_action) - :table (setup) - ) - :action () - :macro (RECORD_CONN) - :type (accept) - ) - ) - :comments () - :disabled (false) - :global_location (middle) - :through ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :time ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :track ( - : (ReferenceObject - :Name (Log) - :Table (tracks) - :Uid ("{97AEB480-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :dst ( - :AdminInfo ( - :chkpf_uid ("{193E4DB4-BE9D-4444-BC95-C04C10D26D25}") - :ClassName (rule_destination) - ) - :compound () - :op () - : (ReferenceObject - :Name (IsoAAADray.local) - :Table (network_objects) - :Uid ("{75EDBC62-7EB1-4D37-8295-684903FDA75A}") - ) - : (ReferenceObject - :Name (gateway.local) - :Table (network_objects) - :Uid ("{7ED7EF12-A13E-4303-8A6E-C6CC28755C80}") - ) - ) - :install ( - :AdminInfo ( - :chkpf_uid ("{42CD50F6-AA17-4271-B684-DFF6E86E5649}") - :ClassName (rule_install) - ) - :compound () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :services ( - :AdminInfo ( - :chkpf_uid ("{0B65BDFF-A77E-498D-8F6D-8B77068701D6}") - :ClassName (rule_services) - ) - :compound () - :op () - : (ReferenceObject - :Name (rdp) - :Table (services) - :Uid ("{5BA0C83F-8D91-465B-9CF6-7DC6AEB84689}") - ) - : (ReferenceObject - :Name (http) - :Table (services) - :Uid ("{97AEB3D4-9AEA-11D5-BD16-0090272CCB30}") - ) - : (ReferenceObject - :Name (CIFS) - :Table (services) - :Uid ("{2A469820-B502-434C-9340-A377677A6A60}") - ) - : (ReferenceObject - :Name (UPS-Monitor) - :Table (services) - :Uid ("{8C8DED7E-F3C9-4964-B9D3-063C23997020}") - ) - ) - :src ( - :AdminInfo ( - :chkpf_uid ("{5C3E75D6-41C1-4D28-A34C-D9F0C316599F}") - :ClassName (rule_source) - ) - :compound () - :op () - : (ReferenceObject - :Name (mg.IsoAAAA-es.com) - :Table (network_objects) - :Uid ("{E5BF8260-3615-4476-B638-53CA3A24FEF1}") - ) - ) - ) - :rule ( - :AdminInfo ( - :chkpf_uid ("{5DEBDFAA-F691-4041-8E3A-EAF002F8B690}") - :ClassName (security_rule) - ) - :action ( - : (accept - :AdminInfo ( - :chkpf_uid ("{69531784-EAAE-4C1C-B792-86B14F8D015E}") - :ClassName (accept_action) - :table (setup) - ) - :action () - :macro (RECORD_CONN) - :type (accept) - ) - ) - :comments () - :disabled (false) - :global_location (middle) - :through ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :time ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :track ( - : (ReferenceObject - :Name (Log) - :Table (tracks) - :Uid ("{97AEB480-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :dst ( - :AdminInfo ( - :chkpf_uid ("{FA61FCF6-FF1E-42C6-B329-B8E23A0EB35D}") - :ClassName (rule_destination) - ) - :compound () - :op () - : (ReferenceObject - :Name (scratchy.local) - :Table (network_objects) - :Uid ("{CFABE50C-C1F6-4FF1-8AC3-3161A3779708}") - ) - ) - :install ( - :AdminInfo ( - :chkpf_uid ("{21457A88-FFC3-45C2-A6AD-7ABC8CDD0232}") - :ClassName (rule_install) - ) - :compound () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :services ( - :AdminInfo ( - :chkpf_uid ("{7990665E-448A-420C-BF7D-3616ED9ECB53}") - :ClassName (rule_services) - ) - :compound () - :op () - : (ReferenceObject - :Name (RAdmin-custom) - :Table (services) - :Uid ("{4FB59153-8212-4A12-BC08-0297AA5F0815}") - ) - ) - :src ( - :AdminInfo ( - :chkpf_uid ("{7A4BC3A5-EAB4-4CC3-8F06-5B3681A6A814}") - :ClassName (rule_source) - ) - :compound () - :op () - : (ReferenceObject - :Name (mg.IsoAAAA-es.com) - :Table (network_objects) - :Uid ("{E5BF8260-3615-4476-B638-53CA3A24FEF1}") - ) - ) - ) - :rule ( - :AdminInfo ( - :chkpf_uid ("{DC9D47B1-CEB2-43AB-B32E-5BFACD49181F}") - :ClassName (security_rule) - ) - :action ( - : (accept - :AdminInfo ( - :chkpf_uid ("{841A245A-0BBC-40D6-AFCD-FC0956945DFB}") - :ClassName (accept_action) - :table (setup) - ) - :action () - :macro (RECORD_CONN) - :type (accept) - ) - ) - :comments () - :disabled (false) - :global_location (middle) - :through ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :time ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :track ( - : (ReferenceObject - :Name (Log) - :Table (tracks) - :Uid ("{97AEB480-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :dst ( - :AdminInfo ( - :chkpf_uid ("{940B351D-CBB3-457B-AA5E-BF8EE4721229}") - :ClassName (rule_destination) - ) - :compound () - :op () - : (ReferenceObject - :Name (daba) - :Table (network_objects) - :Uid ("{94817CDB-EA8C-4213-B38D-F4417EA620C6}") - ) - ) - :install ( - :AdminInfo ( - :chkpf_uid ("{6F3DCA16-ECC8-4DAE-8729-3D07CD35A492}") - :ClassName (rule_install) - ) - :compound () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :services ( - :AdminInfo ( - :chkpf_uid ("{6A906112-E832-480B-98E6-7C88D5768449}") - :ClassName (rule_services) - ) - :compound () - :op () - : (ReferenceObject - :Name (mysql) - :Table (services) - :Uid ("{08A07607-EAAA-4A45-AD6E-6020770BD519}") - ) - : (ReferenceObject - :Name (ssh_version_2) - :Table (services) - :Uid ("{CD082D9A-44A6-4CEF-A17D-5541029ADFB3}") - ) - ) - :src ( - :AdminInfo ( - :chkpf_uid ("{124122B3-1A04-4980-AA2E-18B01C4BA2A1}") - :ClassName (rule_source) - ) - :compound () - :op () - : (ReferenceObject - :Name (mg.IsoAAAA-es.com) - :Table (network_objects) - :Uid ("{E5BF8260-3615-4476-B638-53CA3A24FEF1}") - ) - ) - ) - :rule ( - :AdminInfo ( - :chkpf_uid ("{B706F7FA-C0AA-41E6-9BE1-99FAA2073339}") - :ClassName (security_rule) - ) - :action ( - : (accept - :AdminInfo ( - :chkpf_uid ("{23C4BFFE-0F58-4C89-9AC6-EE8475E30FB2}") - :ClassName (accept_action) - :table (setup) - ) - :action () - :macro (RECORD_CONN) - :type (accept) - ) - ) - :comments () - :disabled (false) - :global_location (middle) - :through ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :time ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :track ( - : (ReferenceObject - :Name (Log) - :Table (tracks) - :Uid ("{97AEB480-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :dst ( - :AdminInfo ( - :chkpf_uid ("{3DEE2329-18AC-4C21-95A5-49D3F42BC058}") - :ClassName (rule_destination) - ) - :compound () - :op () - : (ReferenceObject - :Name (hpux) - :Table (network_objects) - :Uid ("{BF00A847-A0D6-4A75-BE1C-27E7D91EDB55}") - ) - ) - :install ( - :AdminInfo ( - :chkpf_uid ("{31E7DAD2-17B6-484F-87B3-A9817437F6C3}") - :ClassName (rule_install) - ) - :compound () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :services ( - :AdminInfo ( - :chkpf_uid ("{645119AD-FF40-4617-BB77-CE2B7679B804}") - :ClassName (rule_services) - ) - :compound () - :op () - : (ReferenceObject - :Name (telnet) - :Table (services) - :Uid ("{97AEB3CF-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :src ( - :AdminInfo ( - :chkpf_uid ("{A15D212E-0F94-4C31-82C3-83292476F567}") - :ClassName (rule_source) - ) - :compound () - :op () - : (ReferenceObject - :Name (mg.IsoAAAA-es.com) - :Table (network_objects) - :Uid ("{E5BF8260-3615-4476-B638-53CA3A24FEF1}") - ) - ) - ) - :rule ( - :AdminInfo ( - :chkpf_uid ("{2B48CB5C-959B-4212-83BA-D0C31C9E81FD}") - :ClassName (security_rule) - ) - :action ( - : (accept - :AdminInfo ( - :chkpf_uid ("{23DAD50B-1BFA-4B5A-BD07-91F594590169}") - :ClassName (accept_action) - :table (setup) - ) - :action () - :macro (RECORD_CONN) - :type (accept) - ) - ) - :disabled (false) - :global_location (middle) - :through ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :time ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :track ( - : (ReferenceObject - :Name (Log) - :Table (tracks) - :Uid ("{97AEB480-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :comments ("SUS-Access 4 Stichling") - :dst ( - :AdminInfo ( - :chkpf_uid ("{401D98F2-0790-42A8-A27B-4CEF1B409D62}") - :ClassName (rule_destination) - ) - :compound () - :op () - : (ReferenceObject - :Name (IsoAAADray.local) - :Table (network_objects) - :Uid ("{75EDBC62-7EB1-4D37-8295-684903FDA75A}") - ) - ) - :install ( - :AdminInfo ( - :chkpf_uid ("{C607E30B-AD42-4EB9-861C-3E1F17B01A58}") - :ClassName (rule_install) - ) - :compound () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :services ( - :AdminInfo ( - :chkpf_uid ("{F70D3F8A-F47F-4E46-AC7C-6439659AD77F}") - :ClassName (rule_services) - ) - :compound () - :op () - : (ReferenceObject - :Name (http) - :Table (services) - :Uid ("{97AEB3D4-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :src ( - :AdminInfo ( - :chkpf_uid ("{66A8B48D-384B-47C2-AE14-EFA8C5BD981F}") - :ClassName (rule_source) - ) - :compound () - :op () - : (ReferenceObject - :Name (Cactus10.222.0.1) - :Table (network_objects) - :Uid ("{6CD51061-638B-4B2F-9092-7E1E4A5F0ADD}") - ) - ) - ) - :rule ( - :AdminInfo ( - :chkpf_uid ("{B63983F0-BF08-44F7-88EA-5DF0FA381C45}") - :ClassName (security_header_rule) - ) - :action ( - : (drop - :AdminInfo ( - :chkpf_uid ("{D47409A0-8070-4258-802B-E234DE03D219}") - :ClassName (drop_action) - :table (setup) - ) - :action () - :macro () - :type (drop) - ) - ) - :comments () - :global_location (middle) - :through ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :time ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :track ( - : (ReferenceObject - :Name (None) - :Table (tracks) - :Uid ("{97AEB47D-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :disabled (true) - :dst ( - :AdminInfo ( - :chkpf_uid ("{34E31CD9-5F62-46B6-A5A2-2A25A3381BFF}") - :ClassName (rule_destination) - ) - :compound () - :op () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :header_text (Final-rules) - :install ( - :AdminInfo ( - :chkpf_uid ("{97A07F1F-7C42-469E-8976-4694BEA0C05F}") - :ClassName (rule_install) - ) - :compound () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :services ( - :AdminInfo ( - :chkpf_uid ("{AE52657F-1C63-427D-899A-2739B143874D}") - :ClassName (rule_services) - ) - :compound () - :op () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :src ( - :AdminInfo ( - :chkpf_uid ("{7D15F5BF-41C8-4674-A2A5-96AC297EB840}") - :ClassName (rule_source) - ) - :compound () - :op () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :state (expanded) - ) - :rule ( - :AdminInfo ( - :chkpf_uid ("{E079D5BF-271E-4004-B4C5-8372C37B4661}") - :ClassName (security_rule) - ) - :action ( - : (accept - :AdminInfo ( - :chkpf_uid ("{EBF89D8A-D923-4469-9179-4209815688BC}") - :ClassName (accept_action) - :table (setup) - ) - :action () - :macro (RECORD_CONN) - :type (accept) - ) - ) - :comments () - :disabled (false) - :global_location (middle) - :through ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :time ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :track ( - : (ReferenceObject - :Name (Log) - :Table (tracks) - :Uid ("{97AEB480-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :dst ( - :AdminInfo ( - :chkpf_uid ("{93E9E478-F918-450E-8D36-280C86415DB8}") - :ClassName (rule_destination) - ) - :compound () - :op () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :install ( - :AdminInfo ( - :chkpf_uid ("{F546BB1C-8E90-4AEA-9C17-188FDA697E98}") - :ClassName (rule_install) - ) - :compound () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :services ( - :AdminInfo ( - :chkpf_uid ("{5576A25C-181D-40DB-8978-F8E8B6D19C4E}") - :ClassName (rule_services) - ) - :compound () - :op () - : (ReferenceObject - :Name (ICMPgute) - :Table (services) - :Uid ("{418C7C0A-956A-41FF-9BC1-5867B2265090}") - ) - ) - :src ( - :AdminInfo ( - :chkpf_uid ("{4B989FE8-BC56-4B8C-BD37-C6050AAC2B28}") - :ClassName (rule_source) - ) - :compound () - :op () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - ) - :rule ( - :AdminInfo ( - :chkpf_uid ("{89F7C56B-1A5F-4C4A-BC98-F777664BBEC9}") - :ClassName (security_rule) - ) - :action ( - : (accept - :AdminInfo ( - :chkpf_uid ("{BD3A43B7-179B-4A44-9E8E-BDA3C4D74428}") - :ClassName (accept_action) - :table (setup) - ) - :action () - :macro (RECORD_CONN) - :type (accept) - ) - ) - :comments () - :disabled (false) - :global_location (middle) - :through ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :time ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :track ( - : (ReferenceObject - :Name (Log) - :Table (tracks) - :Uid ("{97AEB480-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :dst ( - :AdminInfo ( - :chkpf_uid ("{787E51C4-3375-4608-A83C-CFF3D08628B5}") - :ClassName (rule_destination) - ) - :compound () - :op () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :install ( - :AdminInfo ( - :chkpf_uid ("{C67E7D9D-F7A6-4B80-AB31-589BDF22583D}") - :ClassName (rule_install) - ) - :compound () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :services ( - :AdminInfo ( - :chkpf_uid ("{E732300C-E9E8-4CC7-B0B1-1566947A92A0}") - :ClassName (rule_services) - ) - :compound () - :op () - : (ReferenceObject - :Name (redirect) - :Table (services) - :Uid ("{97AEB409-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :src ( - :AdminInfo ( - :chkpf_uid ("{DB1AE486-D8A3-44F0-AA73-AE22B0BA4A32}") - :ClassName (rule_source) - ) - :compound () - :op () - : (ReferenceObject - :Name (IsoAAAD) - :Table (network_objects) - :Uid ("{29C40B0A-414C-11D7-AEB8-7F0000013C3C}") - ) - ) - ) - :rule ( - :AdminInfo ( - :chkpf_uid ("{F134ED1C-8FC1-4ED1-9751-39EE88C79BAA}") - :ClassName (security_rule) - ) - :action ( - : (reject - :AdminInfo ( - :chkpf_uid ("{619449DF-3B19-42EF-A640-40BF30E1E398}") - :ClassName (reject_action) - :table (setup) - ) - :action () - :macro () - :type (reject) - ) - ) - :comments () - :disabled (false) - :global_location (middle) - :through ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :time ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :track ( - : (ReferenceObject - :Name (None) - :Table (tracks) - :Uid ("{97AEB47D-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :dst ( - :AdminInfo ( - :chkpf_uid ("{F3772580-72F8-47FD-BEEF-64F0C4AE29AC}") - :ClassName (rule_destination) - ) - :compound () - :op () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :install ( - :AdminInfo ( - :chkpf_uid ("{FF327589-E587-4324-B33B-EAEA6BF3D977}") - :ClassName (rule_install) - ) - :compound () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :services ( - :AdminInfo ( - :chkpf_uid ("{367A55E3-5596-40A1-A0C9-63CEA70F42C3}") - :ClassName (rule_services) - ) - :compound () - :op () - : (ReferenceObject - :Name (Drop_nologServices) - :Table (services) - :Uid ("{495E1A16-2612-49D9-8F69-B00EB33699E8}") - ) - ) - :src ( - :AdminInfo ( - :chkpf_uid ("{AFD6C077-CA8E-4C7D-A834-F781B7821B96}") - :ClassName (rule_source) - ) - :compound () - :op () - : (ReferenceObject - :Name (IsoAAAA-100) - :Table (network_objects) - :Uid ("{BF1C6029-8D5D-4A05-A3AD-4B67E6E7A7AA}") - ) - ) - ) - :rule ( - :AdminInfo ( - :chkpf_uid ("{7067EE72-61D1-4555-9832-8E9279772BCA}") - :ClassName (security_rule) - ) - :action ( - : (reject - :AdminInfo ( - :chkpf_uid ("{D06A4524-1DCA-4DD5-BCC2-54EE451C1777}") - :ClassName (reject_action) - :table (setup) - ) - :action () - :macro () - :type (reject) - ) - ) - :comments () - :disabled (false) - :global_location (middle) - :through ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :time ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :track ( - : (ReferenceObject - :Name (None) - :Table (tracks) - :Uid ("{97AEB47D-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :dst ( - :AdminInfo ( - :chkpf_uid ("{FFD672A3-65E6-4B19-B686-D40AC4299BCD}") - :ClassName (rule_destination) - ) - :compound () - :op () - : (ReferenceObject - :Name (Drop_nologDest) - :Table (network_objects) - :Uid ("{79369987-B128-4B3F-827C-3C936F7C3F53}") - ) - ) - :install ( - :AdminInfo ( - :chkpf_uid ("{0581A769-6452-42CD-9718-F226767D0287}") - :ClassName (rule_install) - ) - :compound () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :services ( - :AdminInfo ( - :chkpf_uid ("{F037BEDF-CC8F-4792-9A21-103C9F5C2A51}") - :ClassName (rule_services) - ) - :compound () - :op () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :src ( - :AdminInfo ( - :chkpf_uid ("{7B4EF795-BE09-45A2-86B9-1CE030756ECB}") - :ClassName (rule_source) - ) - :compound () - :op () - : (ReferenceObject - :Name (IsoAAAA-100) - :Table (network_objects) - :Uid ("{BF1C6029-8D5D-4A05-A3AD-4B67E6E7A7AA}") - ) - ) - ) - :rule ( - :AdminInfo ( - :chkpf_uid ("{A6F53BCD-748C-4585-B8FB-1DF23129F085}") - :ClassName (security_rule) - ) - :action ( - : (reject - :AdminInfo ( - :chkpf_uid ("{4F089C9B-C148-4A8A-8ED5-38618067B567}") - :ClassName (reject_action) - :table (setup) - ) - :action () - :macro () - :type (reject) - ) - ) - :comments () - :disabled (false) - :global_location (middle) - :through ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :time ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :track ( - : (ReferenceObject - :Name (Log) - :Table (tracks) - :Uid ("{97AEB480-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :dst ( - :AdminInfo ( - :chkpf_uid ("{34CE5F02-44F0-4180-BE48-5CB31E82D728}") - :ClassName (rule_destination) - ) - :compound () - :op () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :install ( - :AdminInfo ( - :chkpf_uid ("{7AD6114F-E8FF-4AE9-BAA8-6B72CA08F552}") - :ClassName (rule_install) - ) - :compound () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :services ( - :AdminInfo ( - :chkpf_uid ("{33DEA2EB-F713-400E-96E1-AACE576E28AB}") - :ClassName (rule_services) - ) - :compound () - :op () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :src ( - :AdminInfo ( - :chkpf_uid ("{4F305BBD-E049-4054-BCEC-A0D4F832CD80}") - :ClassName (rule_source) - ) - :compound () - :op () - : (ReferenceObject - :Name (CactusDA) - :Table (network_objects) - :Uid ("{69DBB75C-7E6D-49AD-A814-96F1BAFF12F7}") - ) - ) - ) - :rule ( - :AdminInfo ( - :chkpf_uid ("{9CD8CE05-32DB-483A-A44A-0C9131CCA022}") - :ClassName (security_rule) - ) - :action ( - : (drop - :AdminInfo ( - :chkpf_uid ("{ED025D2F-5D51-4310-AEF3-67A075F171EB}") - :ClassName (drop_action) - :table (setup) - ) - :action () - :macro () - :type (drop) - ) - ) - :comments () - :disabled (false) - :global_location (middle) - :through ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :time ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :track ( - : (ReferenceObject - :Name (Log) - :Table (tracks) - :Uid ("{97AEB480-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :dst ( - :AdminInfo ( - :chkpf_uid ("{92629D3F-DD0B-4864-A91A-9809A211E481}") - :ClassName (rule_destination) - ) - :compound () - :op () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :install ( - :AdminInfo ( - :chkpf_uid ("{92064B95-86EE-43B6-9410-C38676F3D964}") - :ClassName (rule_install) - ) - :compound () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :services ( - :AdminInfo ( - :chkpf_uid ("{C0176725-D8C5-412D-A5C3-65BA48662B1D}") - :ClassName (rule_services) - ) - :compound () - :op () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :src ( - :AdminInfo ( - :chkpf_uid ("{FB79D7A9-F91C-40F7-8DA7-303B39A7DC33}") - :ClassName (rule_source) - ) - :compound () - :op () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - ) - :rule_adtr ( - :AdminInfo ( - :chkpf_uid ("{795A2E9C-E2BD-4674-AB77-023F50036168}") - :ClassName (address_translation_rule) - ) - :comments () - :dst_adtr ( - : (ReferenceObject - :Name (IsoAAAA-100) - :Table (network_objects) - :Uid ("{BF1C6029-8D5D-4A05-A3AD-4B67E6E7A7AA}") - ) - ) - :global_location (middle) - :install ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :rule_block_number (1) - :services_adtr ( - : (ReferenceObject - :Name (CIFS) - :Table (services) - :Uid ("{2A469820-B502-434C-9340-A377677A6A60}") - ) - ) - :src_adtr ( - : (ReferenceObject - :Name (IsoAAAA_home_test_3) - :Table (network_objects) - :Uid ("{3B37A3DE-4411-4FFC-9E54-3ABC5C4F693B}") - ) - ) - :disabled (true) - :dst_adtr_translated ( - :AdminInfo ( - :chkpf_uid ("{A735AA42-250D-4EA5-B52A-05685A6124C3}") - :ClassName (translate_static) - ) - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - :adtr_method (adtr_method_static) - ) - :services_adtr_translated ( - :AdminInfo ( - :chkpf_uid ("{12B449F6-1F99-4060-BCB0-4A9DB5B463B3}") - :ClassName (service_translate) - ) - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - :adtr_method (adtr_method_static) - ) - :src_adtr_translated ( - :AdminInfo ( - :chkpf_uid ("{55591259-4F5C-498E-BF64-59C9C7E941A1}") - :ClassName (translate_static) - ) - : (ReferenceObject - :Name (Cactus_home_test_2) - :Table (network_objects) - :Uid ("{3CB93962-2930-41A7-8067-FC373151BB91}") - ) - :adtr_method (adtr_method_static) - ) - ) - :rule_adtr ( - :AdminInfo ( - :chkpf_uid ("{BBC0B2D9-0852-4DE8-AFB2-C27B6049C3AE}") - :ClassName (address_translation_rule) - ) - :comments () - :disabled (false) - :dst_adtr ( - : (ReferenceObject - :Name (IsoAAAA-100) - :Table (network_objects) - :Uid ("{BF1C6029-8D5D-4A05-A3AD-4B67E6E7A7AA}") - ) - ) - :global_location (middle) - :install ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :rule_block_number (1) - :services_adtr ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :src_adtr ( - : (ReferenceObject - :Name (Cactus-InternetTransfer) - :Table (network_objects) - :Uid ("{408C820D-33A1-4E25-B576-EC826F525DCD}") - ) - ) - :dst_adtr_translated ( - :AdminInfo ( - :chkpf_uid ("{5DD7A06F-C26F-47A8-AFBC-2649EE40DAAF}") - :ClassName (translate_static) - ) - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - :adtr_method (adtr_method_static) - ) - :services_adtr_translated ( - :AdminInfo ( - :chkpf_uid ("{D9D74C97-AC50-4633-A4BE-AD9DF32ED7B8}") - :ClassName (service_translate) - ) - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - :adtr_method (adtr_method_static) - ) - :src_adtr_translated ( - :AdminInfo ( - :chkpf_uid ("{404CEBC7-55D9-4A9A-98AC-10A264BC9F08}") - :ClassName (translate_hide) - ) - : (ReferenceObject - :Name (IsoAAAD_intern) - :Table (network_objects) - :Uid ("{40831AE2-CB84-46D2-9522-F987BC10BDB9}") - ) - :adtr_method (adtr_method_hide) - ) - ) - :rule_adtr ( - :AdminInfo ( - :chkpf_uid ("{795A2E9C-E2BD-4674-AB77-023F50036168}") - :ClassName (address_translation_rule) - ) - :comments () - :disabled (false) - :dst_adtr ( - : (ReferenceObject - :Name (IsoAAADray.local) - :Table (network_objects) - :Uid ("{75EDBC62-7EB1-4D37-8295-684903FDA75A}") - ) - ) - :global_location (middle) - :install ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :rule_block_number (1) - :services_adtr ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :src_adtr ( - : (ReferenceObject - :Name (heag_off_upper) - :Table (network_objects) - :Uid ("{A58E3E67-0517-485F-AA04-97A12BC119C3}") - ) - ) - :dst_adtr_translated ( - :AdminInfo ( - :chkpf_uid ("{5C6895F5-E9DC-4A23-8A54-0DFAB2B7BE72}") - :ClassName (translate_static) - ) - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - :adtr_method (adtr_method_static) - ) - :services_adtr_translated ( - :AdminInfo ( - :chkpf_uid ("{4C474EB4-0463-4982-B6CE-2B5AF7708E63}") - :ClassName (service_translate) - ) - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - :adtr_method (adtr_method_static) - ) - :src_adtr_translated ( - :AdminInfo ( - :chkpf_uid ("{50C50462-F4F4-4619-B04A-5C4DB56D0F6A}") - :ClassName (translate_hide) - ) - : (ReferenceObject - :Name (IsoAAAD_intern) - :Table (network_objects) - :Uid ("{40831AE2-CB84-46D2-9522-F987BC10BDB9}") - ) - :adtr_method (adtr_method_hide) - ) - ) - :rule_adtr ( - :AdminInfo ( - :chkpf_uid ("{1D294F6F-03B3-4CAB-B5FF-5CAEB867C8D0}") - :ClassName (address_translation_rule) - ) - :comments () - :disabled (false) - :dst_adtr ( - : (ReferenceObject - :Name (LSYI-WWA) - :Table (network_objects) - :Uid ("{3ECB1B79-1A26-41A3-90F9-71BE179A7211}") - ) - ) - :global_location (middle) - :install ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :rule_block_number (1) - :services_adtr ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :src_adtr ( - : (ReferenceObject - :Name (IsoAAAA-100) - :Table (network_objects) - :Uid ("{BF1C6029-8D5D-4A05-A3AD-4B67E6E7A7AA}") - ) - ) - :dst_adtr_translated ( - :AdminInfo ( - :chkpf_uid ("{8E14CB91-D19B-40A6-8784-8554E1B86BE4}") - :ClassName (translate_static) - ) - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - :adtr_method (adtr_method_static) - ) - :services_adtr_translated ( - :AdminInfo ( - :chkpf_uid ("{5E8C8FCF-5707-4638-81A3-B20DFB9C42C9}") - :ClassName (service_translate) - ) - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - :adtr_method (adtr_method_static) - ) - :src_adtr_translated ( - :AdminInfo ( - :chkpf_uid ("{6A960E2C-D9AD-44BC-B3B2-F5F3DC5992DA}") - :ClassName (translate_static) - ) - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - :adtr_method (adtr_method_static) - ) - ) - :rule_adtr ( - :AdminInfo ( - :chkpf_uid ("{434891D2-F2AE-4B89-88AD-540EB2A0C83A}") - :ClassName (address_translation_rule) - ) - :comments () - :dst_adtr ( - : (ReferenceObject - :Name (t-online) - :Table (network_objects) - :Uid ("{C3D65C4B-6498-4E00-9BAF-15539231E8EE}") - ) - ) - :global_location (middle) - :install ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :rule_block_number (1) - :services_adtr ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :src_adtr ( - : (ReferenceObject - :Name (IsoAAAA-100) - :Table (network_objects) - :Uid ("{BF1C6029-8D5D-4A05-A3AD-4B67E6E7A7AA}") - ) - ) - :disabled (true) - :dst_adtr_translated ( - :AdminInfo ( - :chkpf_uid ("{02FA831E-4B9C-4943-9EDA-AEA384241460}") - :ClassName (translate_static) - ) - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - :adtr_method (adtr_method_static) - ) - :services_adtr_translated ( - :AdminInfo ( - :chkpf_uid ("{6DC1B358-0DE4-49CF-B496-D0006744DA88}") - :ClassName (service_translate) - ) - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - :adtr_method (adtr_method_static) - ) - :src_adtr_translated ( - :AdminInfo ( - :chkpf_uid ("{F1DC8420-40C4-4CAE-A612-C9EC4518BBCA}") - :ClassName (translate_static) - ) - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - :adtr_method (adtr_method_static) - ) - ) - :rule_adtr ( - :AdminInfo ( - :chkpf_uid ("{4BBFC8B5-8B70-4AE2-BC71-6BCF4B17F7B6}") - :ClassName (address_translation_rule) - ) - :comments () - :disabled (false) - :dst_adtr ( - : (ReferenceObject - :Name (spike.local) - :Table (network_objects) - :Uid ("{4ABDD8DE-0DA2-46E5-B129-85E3977CBD18}") - ) - ) - :global_location (middle) - :install ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :rule_block_number (1) - :services_adtr ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :src_adtr ( - : (ReferenceObject - :Name (IsoAAAA-100) - :Table (network_objects) - :Uid ("{BF1C6029-8D5D-4A05-A3AD-4B67E6E7A7AA}") - ) - ) - :dst_adtr_translated ( - :AdminInfo ( - :chkpf_uid ("{7AA3058F-6816-45D2-A6DE-B54CBB46BD08}") - :ClassName (translate_static) - ) - : (ReferenceObject - :Name (mg.IsoAAAA-es.com) - :Table (network_objects) - :Uid ("{E5BF8260-3615-4476-B638-53CA3A24FEF1}") - ) - :adtr_method (adtr_method_static) - ) - :services_adtr_translated ( - :AdminInfo ( - :chkpf_uid ("{ED35E27D-FA79-48B3-8AC5-27502A7FDB71}") - :ClassName (service_translate) - ) - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - :adtr_method (adtr_method_static) - ) - :src_adtr_translated ( - :AdminInfo ( - :chkpf_uid ("{800AC60D-FE78-47F3-B9F1-8F8F468708C1}") - :ClassName (translate_static) - ) - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - :adtr_method (adtr_method_static) - ) - ) - :rule_adtr ( - :AdminInfo ( - :chkpf_uid ("{5CF61260-14E3-42BB-81E6-EBE8EFE8AF4A}") - :ClassName (address_translation_rule) - ) - :comments () - :disabled (false) - :dst_adtr ( - : (ReferenceObject - :Name (mg.IsoAAAA-es.com) - :Table (network_objects) - :Uid ("{E5BF8260-3615-4476-B638-53CA3A24FEF1}") - ) - ) - :global_location (middle) - :install ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :rule_block_number (1) - :services_adtr ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :src_adtr ( - : (ReferenceObject - :Name (IsoAAAA-100) - :Table (network_objects) - :Uid ("{BF1C6029-8D5D-4A05-A3AD-4B67E6E7A7AA}") - ) - ) - :dst_adtr_translated ( - :AdminInfo ( - :chkpf_uid ("{098ADCE5-568E-4F27-ABF9-682BBE442FE7}") - :ClassName (translate_static) - ) - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - :adtr_method (adtr_method_static) - ) - :services_adtr_translated ( - :AdminInfo ( - :chkpf_uid ("{36B74AF0-631F-40BD-B592-5ED305639070}") - :ClassName (service_translate) - ) - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - :adtr_method (adtr_method_static) - ) - :src_adtr_translated ( - :AdminInfo ( - :chkpf_uid ("{41B82ACB-215E-4320-B02C-A86A08EEEFC9}") - :ClassName (translate_static) - ) - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - :adtr_method (adtr_method_static) - ) - ) - :rule_adtr ( - :AdminInfo ( - :chkpf_uid ("{44B823A7-B08B-4A9F-BF4E-F895E1BAE762}") - :ClassName (address_translation_rule) - ) - :comments () - :disabled (false) - :dst_adtr ( - : (ReferenceObject - :Name (IsoAAAA-100) - :Table (network_objects) - :Uid ("{BF1C6029-8D5D-4A05-A3AD-4B67E6E7A7AA}") - ) - ) - :global_location (middle) - :install ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :rule_block_number (1) - :services_adtr ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :src_adtr ( - : (ReferenceObject - :Name (Cactus-Official) - :Table (network_objects) - :Uid ("{2136B4E8-3ABF-4931-BDB9-12CDF457D4A4}") - ) - ) - :dst_adtr_translated ( - :AdminInfo ( - :chkpf_uid ("{F9494163-1D8B-45BE-A547-0786801699CD}") - :ClassName (translate_static) - ) - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - :adtr_method (adtr_method_static) - ) - :services_adtr_translated ( - :AdminInfo ( - :chkpf_uid ("{13C447D5-A284-4282-B584-A1B7ED1DE70C}") - :ClassName (service_translate) - ) - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - :adtr_method (adtr_method_static) - ) - :src_adtr_translated ( - :AdminInfo ( - :chkpf_uid ("{007B4C50-EC16-45E9-8CD5-A3C71764175C}") - :ClassName (translate_static) - ) - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - :adtr_method (adtr_method_static) - ) - ) - :rule_adtr ( - :AdminInfo ( - :chkpf_uid ("{05A4371B-C62D-4CE9-AD5F-9818F9D852BE}") - :ClassName (address_translation_rule) - ) - :comments () - :disabled (false) - :dst_adtr ( - : (ReferenceObject - :Name (IsoAAAA-100) - :Table (network_objects) - :Uid ("{BF1C6029-8D5D-4A05-A3AD-4B67E6E7A7AA}") - ) - ) - :global_location (middle) - :install ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :rule_block_number (1) - :services_adtr ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :src_adtr ( - : (ReferenceObject - :Name (allNet) - :Table (network_objects) - :Uid ("{8C20ECB8-A6DB-4C35-B79A-D12ECE559C77}") - ) - ) - :dst_adtr_translated ( - :AdminInfo ( - :chkpf_uid ("{39606C16-F893-466A-9D38-B01857A51FEB}") - :ClassName (translate_static) - ) - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - :adtr_method (adtr_method_static) - ) - :services_adtr_translated ( - :AdminInfo ( - :chkpf_uid ("{19200950-6F5C-4AA2-939A-3CE7D6ACA81D}") - :ClassName (service_translate) - ) - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - :adtr_method (adtr_method_static) - ) - :src_adtr_translated ( - :AdminInfo ( - :chkpf_uid ("{C74080E8-0E7B-4D2E-8FAA-346607D856EC}") - :ClassName (translate_hide) - ) - : (ReferenceObject - :Name (IsoAAAD_intern) - :Table (network_objects) - :Uid ("{40831AE2-CB84-46D2-9522-F987BC10BDB9}") - ) - :adtr_method (adtr_method_hide) - ) - ) - :rule_adtr ( - :AdminInfo ( - :chkpf_uid ("{770C7861-8D4D-45BD-9A08-6D7412464847}") - :ClassName (address_translation_rule) - ) - :comments () - :disabled (false) - :dst_adtr ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :global_location (middle) - :install ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :rule_block_number (1) - :services_adtr ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :src_adtr ( - : (ReferenceObject - :Name (IsoAAAA-100) - :Table (network_objects) - :Uid ("{BF1C6029-8D5D-4A05-A3AD-4B67E6E7A7AA}") - ) - ) - :dst_adtr_translated ( - :AdminInfo ( - :chkpf_uid ("{323C02BB-1CA8-4AF0-B778-CE65AB57FDA1}") - :ClassName (translate_static) - ) - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - :adtr_method (adtr_method_static) - ) - :services_adtr_translated ( - :AdminInfo ( - :chkpf_uid ("{26E182C6-DB5F-462F-BD1B-8C37735E86F7}") - :ClassName (service_translate) - ) - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - :adtr_method (adtr_method_static) - ) - :src_adtr_translated ( - :AdminInfo ( - :chkpf_uid ("{8FA593D7-47A4-4AAC-BA66-34C93515C7F0}") - :ClassName (translate_hide) - ) - : (ReferenceObject - :Name (IsoAAAD_extern) - :Table (network_objects) - :Uid ("{DB456CE7-0DCA-423F-A5E4-9FA976C0B594}") - ) - :adtr_method (adtr_method_hide) - ) - ) - :use_VPN_communities (true) - ) - :rule-base ("##IsoAAAA-traditional" - :AdminInfo ( - :chkpf_uid ("{83E0AC16-D70B-4E9F-8694-9C50BA2DAE92}") - :ClassName (firewall_policy) - :table (fw_policies) - :LastModified ( - :Time ("Thu Jun 23 14:33:36 2005") - :By (IsoAAAF) - :From (IsoAAADray) - ) - ) - :default (0) - :queries () - :queries_adtr () - :collection (ReferenceObject - :Name (IsoAAAA-traditional) - :Table (policies_collections) - :Uid ("{8EA5AF0F-7640-4BF9-8E5B-577091884205}") - ) - :rule ( - :AdminInfo ( - :chkpf_uid ("{55AED8D2-A87C-4234-8F39-3E462469A75E}") - :ClassName (security_header_rule) - ) - :action ( - : (drop - :AdminInfo ( - :chkpf_uid ("{A80DF4EA-A769-4C2F-AFFA-437000BAABF3}") - :ClassName (drop_action) - :table (setup) - ) - :action () - :macro () - :type (drop) - ) - ) - :comments () - :global_location (middle) - :through ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :time ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :track ( - : (ReferenceObject - :Name (None) - :Table (tracks) - :Uid ("{97AEB47D-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :disabled (true) - :dst ( - :AdminInfo ( - :chkpf_uid ("{4AC2A92C-B41D-475E-BD2B-46F614A14D53}") - :ClassName (rule_destination) - ) - :compound () - :op () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :header_text ("IsoAAAE SecuRemote") - :install ( - :AdminInfo ( - :chkpf_uid ("{D2F4F31B-A96B-4CC3-AC8F-E42E4B0C6E38}") - :ClassName (rule_install) - ) - :compound () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :services ( - :AdminInfo ( - :chkpf_uid ("{28DCAD14-2A26-4980-A1EA-A328C525AA6D}") - :ClassName (rule_services) - ) - :compound () - :op () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :src ( - :AdminInfo ( - :chkpf_uid ("{11AE059A-0887-4864-A96E-573D0AB9B8D1}") - :ClassName (rule_source) - ) - :compound () - :op () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :state (expanded) - ) - :rule ( - :AdminInfo ( - :chkpf_uid ("{6E78B459-91E5-4755-B4BF-CD7E19BFFF69}") - :ClassName (security_rule) - ) - :action ( - : ("Client Encrypt" - :AdminInfo ( - :chkpf_uid ("{2AFD1828-E320-4ED5-BAC4-7B8B6977CD41}") - :ClassName (client_encrypt) - :table (setup) - ) - :action (accept) - :dst_options ("Intersect with User Database") - :enforce_desktop_config (false) - :macro (USER_CLIENT_ENCRYPTION) - :src_options ("Intersect with User Database") - :type (userc) - ) - ) - :comments () - :disabled (false) - :global_location (middle) - :through ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :time ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :track ( - : (ReferenceObject - :Name (Log) - :Table (tracks) - :Uid ("{97AEB480-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :dst ( - :AdminInfo ( - :chkpf_uid ("{E71C16B9-A6B6-408C-80BA-5CF08A1F46CA}") - :ClassName (rule_destination) - ) - :compound () - :op () - : (ReferenceObject - :Name (IsoAAADray.local) - :Table (network_objects) - :Uid ("{75EDBC62-7EB1-4D37-8295-684903FDA75A}") - ) - : (ReferenceObject - :Name (gateway.local) - :Table (network_objects) - :Uid ("{7ED7EF12-A13E-4303-8A6E-C6CC28755C80}") - ) - ) - :install ( - :AdminInfo ( - :chkpf_uid ("{C920DC45-AC36-4E6C-AE40-7D36535BCA8C}") - :ClassName (rule_install) - ) - :compound () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :services ( - :AdminInfo ( - :chkpf_uid ("{C01056E7-2861-40A0-B8B8-CFD83C4503E3}") - :ClassName (rule_services) - ) - :compound () - :op () - : (ReferenceObject - :Name (NBT) - :Table (services) - :Uid ("{97AEB471-9AEA-11D5-BD16-0090272CCB30}") - ) - : (ReferenceObject - :Name (CIFS) - :Table (services) - :Uid ("{2A469820-B502-434C-9340-A377677A6A60}") - ) - : (ReferenceObject - :Name (rdp) - :Table (services) - :Uid ("{5BA0C83F-8D91-465B-9CF6-7DC6AEB84689}") - ) - : (ReferenceObject - :Name (domain-udp) - :Table (services) - :Uid ("{97AEB3FA-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :src ( - :AdminInfo ( - :chkpf_uid ("{54B4C9AE-D0A0-44CC-9966-6D3430A02560}") - :ClassName (rule_source) - ) - :compound ( - : (Cactus-extern@vpn-sources-IsoAAAA - :AdminInfo ( - :chkpf_uid ("{06662A22-288E-4636-9C57-B2299E99F54C}") - :ClassName (rule_user_group) - ) - :at (ReferenceObject - :Name (vpn-sources-IsoAAAA) - :Table (network_objects) - :Uid ("{26405A41-425C-4053-8002-497BB82D76B1}") - ) - :color (black) - :type (usrgroup) - ) - ) - :op () - ) - ) - :rule ( - :AdminInfo ( - :chkpf_uid ("{9691C5DE-A661-40D5-9755-E268DDE0F823}") - :ClassName (security_rule) - ) - :action ( - : ("Client Encrypt" - :AdminInfo ( - :chkpf_uid ("{21A87FBC-F2C6-4847-8FC3-7ABC71306B80}") - :ClassName (client_encrypt) - :table (setup) - ) - :action (accept) - :dst_options ("Intersect with User Database") - :enforce_desktop_config (false) - :macro (USER_CLIENT_ENCRYPTION) - :src_options ("Intersect with User Database") - :type (userc) - ) - ) - :comments () - :disabled (false) - :global_location (middle) - :through ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :time ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :track ( - : (ReferenceObject - :Name (Log) - :Table (tracks) - :Uid ("{97AEB480-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :dst ( - :AdminInfo ( - :chkpf_uid ("{3109A085-1921-401A-BE72-8E7FE51BA775}") - :ClassName (rule_destination) - ) - :compound () - :op () - : (ReferenceObject - :Name (scratchy.local) - :Table (network_objects) - :Uid ("{CFABE50C-C1F6-4FF1-8AC3-3161A3779708}") - ) - ) - :install ( - :AdminInfo ( - :chkpf_uid ("{1D278C64-5680-473F-B522-7F856EF2C114}") - :ClassName (rule_install) - ) - :compound () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :services ( - :AdminInfo ( - :chkpf_uid ("{F7A6A2A3-6586-4954-9981-F5E206B1CC09}") - :ClassName (rule_services) - ) - :compound () - :op () - : (ReferenceObject - :Name (RAdmin-custom) - :Table (services) - :Uid ("{4FB59153-8212-4A12-BC08-0297AA5F0815}") - ) - ) - :src ( - :AdminInfo ( - :chkpf_uid ("{6BF46A79-3FF3-4F3B-BC85-9D71E0E932D6}") - :ClassName (rule_source) - ) - :compound ( - : (IsoAAAG-g@vpn-sources-IsoAAAA - :AdminInfo ( - :chkpf_uid ("{A304617F-CDA0-490D-A621-B62BB65F1C51}") - :ClassName (rule_user_group) - ) - :at (ReferenceObject - :Name (vpn-sources-IsoAAAA) - :Table (network_objects) - :Uid ("{26405A41-425C-4053-8002-497BB82D76B1}") - ) - :color (black) - :type (usrgroup) - ) - ) - :op () - ) - ) - :rule ( - :AdminInfo ( - :chkpf_uid ("{920B2304-B254-46E4-A051-F46580B0189A}") - :ClassName (security_rule) - ) - :action ( - : ("Client Encrypt" - :AdminInfo ( - :chkpf_uid ("{9CA5DD8C-0AD0-4505-8782-69FDE2254C70}") - :ClassName (client_encrypt) - :table (setup) - ) - :action (accept) - :dst_options ("Intersect with User Database") - :enforce_desktop_config (false) - :macro (USER_CLIENT_ENCRYPTION) - :src_options ("Intersect with User Database") - :type (userc) - ) - ) - :comments () - :disabled (false) - :global_location (middle) - :through ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :time ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :track ( - : (ReferenceObject - :Name (Log) - :Table (tracks) - :Uid ("{97AEB480-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :dst ( - :AdminInfo ( - :chkpf_uid ("{89FE302D-ED85-4024-892C-84457F49EF44}") - :ClassName (rule_destination) - ) - :compound () - :op () - : (ReferenceObject - :Name (spike.local) - :Table (network_objects) - :Uid ("{4ABDD8DE-0DA2-46E5-B129-85E3977CBD18}") - ) - ) - :install ( - :AdminInfo ( - :chkpf_uid ("{239E405F-12E7-4910-B44F-F3C59A3191B6}") - :ClassName (rule_install) - ) - :compound () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :services ( - :AdminInfo ( - :chkpf_uid ("{960A7691-DDC5-4F48-B5D0-7A7305561B32}") - :ClassName (rule_services) - ) - :compound () - :op () - : (ReferenceObject - :Name (squid) - :Table (services) - :Uid ("{91C0454D-F70C-44B3-8F2D-70C4A68E9594}") - ) - : (ReferenceObject - :Name (imap) - :Table (services) - :Uid ("{97AEB446-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :src ( - :AdminInfo ( - :chkpf_uid ("{1625B6AD-2434-4325-8BE6-AE20F7C2C3CB}") - :ClassName (rule_source) - ) - :compound ( - : (Cactus-extern@vpn-sources-IsoAAAA - :AdminInfo ( - :chkpf_uid ("{848CBF00-3FFF-47A2-8D54-5B7B8170EDAD}") - :ClassName (rule_user_group) - ) - :at (ReferenceObject - :Name (vpn-sources-IsoAAAA) - :Table (network_objects) - :Uid ("{26405A41-425C-4053-8002-497BB82D76B1}") - ) - :color (black) - :type (usrgroup) - ) - ) - :op () - ) - ) - :rule ( - :AdminInfo ( - :chkpf_uid ("{1BDEDFF9-7C57-4628-B09E-DAFFA27B0DAF}") - :ClassName (security_rule) - ) - :action ( - : ("Client Encrypt" - :AdminInfo ( - :chkpf_uid ("{01B16C58-99BF-4C2A-9AA0-BF151981D6A8}") - :ClassName (client_encrypt) - :table (setup) - ) - :action (accept) - :dst_options ("Intersect with User Database") - :enforce_desktop_config (false) - :macro (USER_CLIENT_ENCRYPTION) - :src_options ("Intersect with User Database") - :type (userc) - ) - ) - :comments () - :disabled (false) - :global_location (middle) - :through ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :time ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :track ( - : (ReferenceObject - :Name (Log) - :Table (tracks) - :Uid ("{97AEB480-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :dst ( - :AdminInfo ( - :chkpf_uid ("{55339727-6FEF-4B99-A17E-5890279876A6}") - :ClassName (rule_destination) - ) - :compound () - :op () - : (ReferenceObject - :Name (itchy) - :Table (network_objects) - :Uid ("{3B4DF852-5064-4957-B95F-D469C5656467}") - ) - ) - :install ( - :AdminInfo ( - :chkpf_uid ("{58C83086-B23C-494C-AFBD-FF71DDE6D90B}") - :ClassName (rule_install) - ) - :compound () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :services ( - :AdminInfo ( - :chkpf_uid ("{35745013-A0CF-4878-A5E5-60BFDD09DD4D}") - :ClassName (rule_services) - ) - :compound () - :op () - : (ReferenceObject - :Name (smtp) - :Table (services) - :Uid ("{97AEB3D9-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :src ( - :AdminInfo ( - :chkpf_uid ("{4A953FC6-7A97-4CF8-ADD2-8F557A1991E1}") - :ClassName (rule_source) - ) - :compound ( - : (Cactus-extern@vpn-sources-IsoAAAA - :AdminInfo ( - :chkpf_uid ("{95BDA256-F40B-4BF0-9A9A-9647C2D4E758}") - :ClassName (rule_user_group) - ) - :at (ReferenceObject - :Name (vpn-sources-IsoAAAA) - :Table (network_objects) - :Uid ("{26405A41-425C-4053-8002-497BB82D76B1}") - ) - :color (black) - :type (usrgroup) - ) - ) - :op () - ) - ) - :rule ( - :AdminInfo ( - :chkpf_uid ("{70B5DC4A-1616-4047-AC26-5ED448A2CF00}") - :ClassName (security_rule) - ) - :action ( - : ("Client Encrypt" - :AdminInfo ( - :chkpf_uid ("{F0786A55-1A99-404A-BDD6-9334E32B292C}") - :ClassName (client_encrypt) - :table (setup) - ) - :action (accept) - :dst_options ("Intersect with User Database") - :enforce_desktop_config (false) - :macro (USER_CLIENT_ENCRYPTION) - :src_options ("Intersect with User Database") - :type (userc) - ) - ) - :comments () - :disabled (false) - :global_location (middle) - :through ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :time ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :track ( - : (ReferenceObject - :Name (Log) - :Table (tracks) - :Uid ("{97AEB480-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :dst ( - :AdminInfo ( - :chkpf_uid ("{0FDC8337-7A9D-47B2-8754-378FEB66B2ED}") - :ClassName (rule_destination) - ) - :compound () - :op () - : (ReferenceObject - :Name (wasp) - :Table (network_objects) - :Uid ("{098B2A74-E220-4AE8-A164-340FED79C9D5}") - ) - ) - :install ( - :AdminInfo ( - :chkpf_uid ("{9D51C8CC-BC8E-441F-88E7-60CFB459EAE1}") - :ClassName (rule_install) - ) - :compound () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :services ( - :AdminInfo ( - :chkpf_uid ("{4D81B00D-E763-4153-9338-1BFB8A9453EA}") - :ClassName (rule_services) - ) - :compound () - :op () - : (ReferenceObject - :Name (ntp-udp) - :Table (services) - :Uid ("{97AEB404-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :src ( - :AdminInfo ( - :chkpf_uid ("{BFDF7F38-B703-4397-8CC9-1B544AEBA20D}") - :ClassName (rule_source) - ) - :compound ( - : (Cactus-extern@vpn-sources-IsoAAAA - :AdminInfo ( - :chkpf_uid ("{4F5A4882-D84F-4250-B3BF-B1A3C5B468E4}") - :ClassName (rule_user_group) - ) - :at (ReferenceObject - :Name (vpn-sources-IsoAAAA) - :Table (network_objects) - :Uid ("{26405A41-425C-4053-8002-497BB82D76B1}") - ) - :color (black) - :type (usrgroup) - ) - ) - :op () - ) - ) - :rule ( - :AdminInfo ( - :chkpf_uid ("{F5BDCBD0-AE0E-4DDD-BA77-488A126E9759}") - :ClassName (security_rule) - ) - :action ( - : ("Client Encrypt" - :AdminInfo ( - :chkpf_uid ("{4910EDC7-E295-4B62-A57B-119D75B36211}") - :ClassName (client_encrypt) - :table (setup) - ) - :action (accept) - :dst_options ("Intersect with User Database") - :enforce_desktop_config (false) - :macro (USER_CLIENT_ENCRYPTION) - :src_options ("Intersect with User Database") - :type (userc) - ) - ) - :comments () - :disabled (false) - :global_location (middle) - :through ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :time ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :track ( - : (ReferenceObject - :Name (Log) - :Table (tracks) - :Uid ("{97AEB480-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :dst ( - :AdminInfo ( - :chkpf_uid ("{F1BC9B8B-757D-41B5-B5F2-6CF53E313CE1}") - :ClassName (rule_destination) - ) - :compound () - :op () - : (ReferenceObject - :Name (IsoAAAA-100) - :Table (network_objects) - :Uid ("{BF1C6029-8D5D-4A05-A3AD-4B67E6E7A7AA}") - ) - ) - :install ( - :AdminInfo ( - :chkpf_uid ("{EFEA2745-10C4-435C-8F75-3B02CAD44A1E}") - :ClassName (rule_install) - ) - :compound () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :services ( - :AdminInfo ( - :chkpf_uid ("{B0A24846-9037-4DB4-8A0E-6D154A3C446C}") - :ClassName (rule_services) - ) - :compound () - :op () - : (ReferenceObject - :Name (icmp-requests) - :Table (services) - :Uid ("{97AEB413-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :src ( - :AdminInfo ( - :chkpf_uid ("{478016ED-E6A8-4C48-AAA0-0E48BB328C94}") - :ClassName (rule_source) - ) - :compound ( - : (Cactus-extern@vpn-sources-IsoAAAA - :AdminInfo ( - :chkpf_uid ("{22D34F4D-CE34-4570-82C3-8264E061361C}") - :ClassName (rule_user_group) - ) - :at (ReferenceObject - :Name (vpn-sources-IsoAAAA) - :Table (network_objects) - :Uid ("{26405A41-425C-4053-8002-497BB82D76B1}") - ) - :color (black) - :type (usrgroup) - ) - ) - :op () - ) - ) - :rule ( - :AdminInfo ( - :chkpf_uid ("{E50EEFDD-9C20-4905-AC8B-6DD27D72792C}") - :ClassName (security_header_rule) - ) - :action ( - : (drop - :AdminInfo ( - :chkpf_uid ("{6E8942C2-E8EF-4C95-BC20-0AAFF144F063}") - :ClassName (drop_action) - :table (setup) - ) - :action () - :macro () - :type (drop) - ) - ) - :comments () - :global_location (middle) - :through ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :time ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :track ( - : (ReferenceObject - :Name (None) - :Table (tracks) - :Uid ("{97AEB47D-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :disabled (true) - :dst ( - :AdminInfo ( - :chkpf_uid ("{80AD2FC1-9597-4DDB-89D1-EBB676C19FAB}") - :ClassName (rule_destination) - ) - :compound () - :op () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :header_text ("IsoAAAE VPN-GW2GW") - :install ( - :AdminInfo ( - :chkpf_uid ("{AA5B5D3B-09DC-4BF0-B844-2284691CE560}") - :ClassName (rule_install) - ) - :compound () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :services ( - :AdminInfo ( - :chkpf_uid ("{75EFCECD-5B98-4D68-90A8-993EBEB1D1AE}") - :ClassName (rule_services) - ) - :compound () - :op () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :src ( - :AdminInfo ( - :chkpf_uid ("{5DA88645-AB06-4001-8DDF-1D9F3C73AD4F}") - :ClassName (rule_source) - ) - :compound () - :op () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :state (expanded) - ) - :rule ( - :AdminInfo ( - :chkpf_uid ("{328999EC-FEB5-48C3-B967-95F52EFEC462}") - :ClassName (security_rule) - ) - :action ( - : (Encrypt - :AdminInfo ( - :chkpf_uid ("{033ED469-3968-422B-9F61-B859EAEF33A9}") - :ClassName (encrypt) - :table (setup) - ) - :action (accept) - :datam () - :diagnostics-track (CryptLog - :AdminInfo ( - :chkpf_uid ("{AA60725C-E01D-4383-9841-5DA71CD58498}") - :ClassName (account) - :table (tracks) - ) - :Name () - :color ("Navy Blue") - :format (crypt) - :icon-name () - :macro () - :type (account) - ) - :gateway (ReferenceObject - :Table (globals) - :Name (Any) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - :isakmp.compression (None) - :isakmp.crlreq (false) - :isakmp.data.integrity (MD5) - :isakmp.encryption (3DES) - :isakmp.gateway (ReferenceObject - :Table (globals) - :Name (Any) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - :isakmp.phase2_DH_group (ReferenceObject - :Table (encryption) - :Name ("Group 2 (1024 bit)") - :Uid ("{97AEB629-9AEA-11D5-BD16-0090272CCB30}") - ) - :isakmp.transform (ESP) - :isakmp.use_pfs (false) - :isakmp.useippools (false) - :keym () - :macro (ENCRYPTION) - :mdm (MD5) - :menu_inactive (false) - :scheme (ISAKMP) - :type (encrypt) - ) - ) - :comments () - :disabled (false) - :global_location (middle) - :through ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :time ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :track ( - : (ReferenceObject - :Name (Log) - :Table (tracks) - :Uid ("{97AEB480-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :dst ( - :AdminInfo ( - :chkpf_uid ("{75DEA9A3-F776-46C2-AE83-708A874972DA}") - :ClassName (rule_destination) - ) - :compound () - :op () - : (ReferenceObject - :Name (IsoAAAA-100) - :Table (network_objects) - :Uid ("{BF1C6029-8D5D-4A05-A3AD-4B67E6E7A7AA}") - ) - ) - :install ( - :AdminInfo ( - :chkpf_uid ("{49CA8DBE-E6C1-41FE-960B-CD80875BD987}") - :ClassName (rule_install) - ) - :compound () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :services ( - :AdminInfo ( - :chkpf_uid ("{70722DA2-F39D-4785-B360-AE025E55A90F}") - :ClassName (rule_services) - ) - :compound () - :op () - : (ReferenceObject - :Name (icmp-requests) - :Table (services) - :Uid ("{97AEB413-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :src ( - :AdminInfo ( - :chkpf_uid ("{AFFDB11C-0016-459C-B945-5B7C26F707A6}") - :ClassName (rule_source) - ) - :compound () - :op () - : (ReferenceObject - :Table (network_objects) - :Name (IsoAAAA_home_tim) - :Uid ("{BF8F69B9-87C2-464A-9404-239AE8DF66B3}") - ) - ) - ) - :rule ( - :AdminInfo ( - :chkpf_uid ("{4D25D596-31EB-463C-9AB3-D22A92AE4033}") - :ClassName (security_header_rule) - ) - :action ( - : (drop - :AdminInfo ( - :chkpf_uid ("{C80121D8-276E-46C7-912F-1ED756DD47A9}") - :ClassName (drop_action) - :table (setup) - ) - :action () - :macro () - :type (drop) - ) - ) - :comments () - :global_location (middle) - :through ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :time ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :track ( - : (ReferenceObject - :Name (None) - :Table (tracks) - :Uid ("{97AEB47D-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :disabled (true) - :dst ( - :AdminInfo ( - :chkpf_uid ("{6ADFAB36-2054-4BD4-9709-778A6D5CE14C}") - :ClassName (rule_destination) - ) - :compound () - :op () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :header_text (Paybox) - :install ( - :AdminInfo ( - :chkpf_uid ("{0D085BFB-9570-4635-ABC3-962C2E75BB5F}") - :ClassName (rule_install) - ) - :compound () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :services ( - :AdminInfo ( - :chkpf_uid ("{5A631F4C-07E4-4AC9-A8E8-95CDBB5301A8}") - :ClassName (rule_services) - ) - :compound () - :op () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :src ( - :AdminInfo ( - :chkpf_uid ("{E46AD7A5-D087-4086-925D-110926B6D8BE}") - :ClassName (rule_source) - ) - :compound () - :op () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :state (expanded) - ) - :rule ( - :AdminInfo ( - :chkpf_uid ("{C008C4CF-6F9D-42D6-A4AE-E187E2C52B9B}") - :ClassName (security_rule) - ) - :action ( - : (Encrypt - :AdminInfo ( - :chkpf_uid ("{32F49A92-BCEF-4C40-9C82-A8DECB8B205F}") - :ClassName (encrypt) - :table (setup) - ) - :action (accept) - :datam () - :diagnostics-track (CryptLog - :AdminInfo ( - :chkpf_uid ("{E6CE55C2-2363-40C3-8497-78C64EAC556E}") - :ClassName (account) - :table (tracks) - ) - :Name () - :color ("Navy Blue") - :format (crypt) - :icon-name () - :macro () - :type (account) - ) - :gateway (ReferenceObject - :Table (globals) - :Name (Any) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - :isakmp.compression (None) - :isakmp.crlreq (false) - :isakmp.data.integrity (MD5) - :isakmp.encryption (3DES) - :isakmp.gateway () - :isakmp.phase2_DH_group (ReferenceObject - :Name ("Group 1 (768 bit)") - :Table (encryption) - :Uid ("{97AEB624-9AEA-11D5-BD16-0090272CCB30}") - ) - :isakmp.transform (ESP) - :isakmp.use_pfs (true) - :isakmp.useippools (false) - :keym () - :macro (ENCRYPTION) - :mdm (MD5) - :menu_inactive (false) - :scheme (ISAKMP) - :type (encrypt) - ) - ) - :comments () - :disabled (false) - :global_location (middle) - :through ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :time ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :track ( - : (ReferenceObject - :Name (Log) - :Table (tracks) - :Uid ("{97AEB480-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :dst ( - :AdminInfo ( - :chkpf_uid ("{29ACE304-9241-458B-AAF2-FC1081354711}") - :ClassName (rule_destination) - ) - :compound () - :op () - : (ReferenceObject - :Name (paybox-raunheim) - :Table (network_objects) - :Uid ("{0A1725B4-534D-46F1-A8C0-02C3351C8312}") - ) - ) - :install ( - :AdminInfo ( - :chkpf_uid ("{AAC7238A-9B77-463C-93BB-F09881B9D900}") - :ClassName (rule_install) - ) - :compound () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :services ( - :AdminInfo ( - :chkpf_uid ("{43D4BFFE-96B2-4921-8DE3-8B0B9C3ACC3D}") - :ClassName (rule_services) - ) - :compound () - :op () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :src ( - :AdminInfo ( - :chkpf_uid ("{1763B2EE-C7D8-44ED-A686-583DDB672508}") - :ClassName (rule_source) - ) - :compound () - :op () - : (ReferenceObject - :Name (IsoAAAA-100) - :Table (network_objects) - :Uid ("{BF1C6029-8D5D-4A05-A3AD-4B67E6E7A7AA}") - ) - ) - ) - :rule ( - :AdminInfo ( - :chkpf_uid ("{C64B3DE1-B85C-4902-B966-2BEA60840772}") - :ClassName (security_rule) - ) - :action ( - : (Encrypt - :AdminInfo ( - :chkpf_uid ("{7F5A6984-04DC-43A4-AC1F-A6C3BD195426}") - :ClassName (encrypt) - :table (setup) - ) - :action (accept) - :datam () - :diagnostics-track (CryptLog - :AdminInfo ( - :chkpf_uid ("{F52E7C26-DF59-4818-B00C-B32AD2ABE2B3}") - :ClassName (account) - :table (tracks) - ) - :Name () - :color ("Navy Blue") - :format (crypt) - :icon-name () - :macro () - :type (account) - ) - :gateway (ReferenceObject - :Table (globals) - :Name (Any) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - :isakmp.compression (None) - :isakmp.crlreq (false) - :isakmp.data.integrity (MD5) - :isakmp.encryption (3DES) - :isakmp.gateway () - :isakmp.phase2_DH_group (ReferenceObject - :Name ("Group 1 (768 bit)") - :Table (encryption) - :Uid ("{97AEB624-9AEA-11D5-BD16-0090272CCB30}") - ) - :isakmp.transform (ESP) - :isakmp.use_pfs (true) - :isakmp.useippools (false) - :keym () - :macro (ENCRYPTION) - :mdm (MD5) - :menu_inactive (false) - :scheme (ISAKMP) - :type (encrypt) - ) - ) - :comments () - :global_location (middle) - :through ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :time ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :track ( - : (ReferenceObject - :Name (Log) - :Table (tracks) - :Uid ("{97AEB480-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :disabled (true) - :dst ( - :AdminInfo ( - :chkpf_uid ("{313A1B80-4748-40BC-A463-FA115C9A6410}") - :ClassName (rule_destination) - ) - :compound () - :op () - : (ReferenceObject - :Name (paybox-frankfurt) - :Table (network_objects) - :Uid ("{463C45CA-0C86-42DC-9B02-E83E28764370}") - ) - ) - :install ( - :AdminInfo ( - :chkpf_uid ("{C70D24DD-D5D5-4D6F-85C2-0A69F0EE5F48}") - :ClassName (rule_install) - ) - :compound () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :services ( - :AdminInfo ( - :chkpf_uid ("{8AB172A4-28B0-4DA2-8028-6AD4F7DAE979}") - :ClassName (rule_services) - ) - :compound () - :op () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :src ( - :AdminInfo ( - :chkpf_uid ("{8119E980-7EFF-414E-810A-1368B4059E52}") - :ClassName (rule_source) - ) - :compound () - :op () - : (ReferenceObject - :Name (IsoAAAA-100) - :Table (network_objects) - :Uid ("{BF1C6029-8D5D-4A05-A3AD-4B67E6E7A7AA}") - ) - ) - ) - :rule ( - :AdminInfo ( - :chkpf_uid ("{85A07116-6165-46A2-B646-BC65159C8498}") - :ClassName (security_header_rule) - ) - :action ( - : (drop - :AdminInfo ( - :chkpf_uid ("{0974D2A7-69A9-40E1-9150-87FF94433363}") - :ClassName (drop_action) - :table (setup) - ) - :action () - :macro () - :type (drop) - ) - ) - :comments () - :global_location (middle) - :through ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :time ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :track ( - : (ReferenceObject - :Name (None) - :Table (tracks) - :Uid ("{97AEB47D-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :disabled (true) - :dst ( - :AdminInfo ( - :chkpf_uid ("{80880ABC-AA36-4ABB-8E93-72459383731B}") - :ClassName (rule_destination) - ) - :compound () - :op () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :header_text ("Sting Internal-Connections") - :install ( - :AdminInfo ( - :chkpf_uid ("{D236CF92-C3A6-4139-9D74-836408A0AC42}") - :ClassName (rule_install) - ) - :compound () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :services ( - :AdminInfo ( - :chkpf_uid ("{8213C158-8D6A-4146-8383-6B1BA2CDFFF7}") - :ClassName (rule_services) - ) - :compound () - :op () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :src ( - :AdminInfo ( - :chkpf_uid ("{6AED35BE-4E23-415A-BA81-8969B9E1DDEC}") - :ClassName (rule_source) - ) - :compound () - :op () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :state (collapsed) - ) - :rule ( - :AdminInfo ( - :chkpf_uid ("{CF0994CE-EC9F-4A3A-90E0-42655C2D25A1}") - :ClassName (security_rule) - ) - :action ( - : (accept - :AdminInfo ( - :chkpf_uid ("{292BDC57-FA47-4464-B83C-7636555FB0E1}") - :ClassName (accept_action) - :table (setup) - ) - :action () - :macro (RECORD_CONN) - :type (accept) - ) - ) - :comments () - :disabled (false) - :global_location (middle) - :through ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :time ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :track ( - : (ReferenceObject - :Name (Log) - :Table (tracks) - :Uid ("{97AEB480-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :dst ( - :AdminInfo ( - :chkpf_uid ("{A71F1087-BFC1-414B-BAC9-5097E8FAA94F}") - :ClassName (rule_destination) - ) - :compound () - :op () - : (ReferenceObject - :Name (IsoAAAD) - :Table (network_objects) - :Uid ("{29C40B0A-414C-11D7-AEB8-7F0000013C3C}") - ) - ) - :install ( - :AdminInfo ( - :chkpf_uid ("{9698EE11-9DFF-4C54-9166-7B6E9A35BF4B}") - :ClassName (rule_install) - ) - :compound () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :services ( - :AdminInfo ( - :chkpf_uid ("{F41085C4-3418-4B30-AB6E-5804AA7F8B4D}") - :ClassName (rule_services) - ) - :compound () - :op () - : (ReferenceObject - :Name (ssh) - :Table (services) - :Uid ("{18EC9EAA-1657-4240-AB97-5F234623336B}") - ) - : (ReferenceObject - :Name (https) - :Table (services) - :Uid ("{97AEB443-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :src ( - :AdminInfo ( - :chkpf_uid ("{2D0924EE-FE00-4354-ADC1-033783E6AEBC}") - :ClassName (rule_source) - ) - :compound () - :op () - : (ReferenceObject - :Name (IsoAAAA-100) - :Table (network_objects) - :Uid ("{BF1C6029-8D5D-4A05-A3AD-4B67E6E7A7AA}") - ) - : (ReferenceObject - :Table (network_objects) - :Name (IsoAAAA_home_tim) - :Uid ("{BF8F69B9-87C2-464A-9404-239AE8DF66B3}") - ) - ) - ) - :rule ( - :AdminInfo ( - :chkpf_uid ("{113537AD-71C4-4CE4-BA28-679030EEA145}") - :ClassName (security_rule) - ) - :action ( - : (accept - :AdminInfo ( - :chkpf_uid ("{B772878E-BC0F-4DA3-8BEA-29B7E1F78BD0}") - :ClassName (accept_action) - :table (setup) - ) - :action () - :macro (RECORD_CONN) - :type (accept) - ) - ) - :comments () - :disabled (false) - :global_location (middle) - :through ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :time ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :track ( - : (ReferenceObject - :Name (Log) - :Table (tracks) - :Uid ("{97AEB480-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :dst ( - :AdminInfo ( - :chkpf_uid ("{17D6C85E-1919-4FDD-9AB6-17A7F06D6559}") - :ClassName (rule_destination) - ) - :compound () - :op () - : (ReferenceObject - :Name (IsoAAAD) - :Table (network_objects) - :Uid ("{29C40B0A-414C-11D7-AEB8-7F0000013C3C}") - ) - ) - :install ( - :AdminInfo ( - :chkpf_uid ("{59E0D2EA-BD99-48FC-BA29-34C757D6C14C}") - :ClassName (rule_install) - ) - :compound () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :services ( - :AdminInfo ( - :chkpf_uid ("{A9833372-0864-427C-B2CB-6A0F59DAF2F0}") - :ClassName (rule_services) - ) - :compound () - :op () - : (ReferenceObject - :Name (apcupsd) - :Table (services) - :Uid ("{A1044CB4-439C-40C9-8489-FA5086134886}") - ) - ) - :src ( - :AdminInfo ( - :chkpf_uid ("{20AB74D2-BC69-440B-8B69-77C6F598D603}") - :ClassName (rule_source) - ) - :compound () - :op () - : (ReferenceObject - :Name (IsoAAADray.local) - :Table (network_objects) - :Uid ("{75EDBC62-7EB1-4D37-8295-684903FDA75A}") - ) - ) - ) - :rule ( - :AdminInfo ( - :chkpf_uid ("{8D008C53-8D55-4C95-93FB-26FB028D1914}") - :ClassName (security_rule) - ) - :action ( - : (accept - :AdminInfo ( - :chkpf_uid ("{55DB4364-CA94-47E2-9C78-5874293C28DE}") - :ClassName (accept_action) - :table (setup) - ) - :action () - :macro (RECORD_CONN) - :type (accept) - ) - ) - :comments () - :disabled (false) - :global_location (middle) - :through ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :time ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :track ( - : (ReferenceObject - :Name (Log) - :Table (tracks) - :Uid ("{97AEB480-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :dst ( - :AdminInfo ( - :chkpf_uid ("{6EC07E89-6359-4D43-959E-8834F1E1DC59}") - :ClassName (rule_destination) - ) - :compound () - :op () - : (ReferenceObject - :Name (wasp) - :Table (network_objects) - :Uid ("{098B2A74-E220-4AE8-A164-340FED79C9D5}") - ) - ) - :install ( - :AdminInfo ( - :chkpf_uid ("{135B3221-B41A-49BA-A6A3-BF4A7662A2B4}") - :ClassName (rule_install) - ) - :compound () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :services ( - :AdminInfo ( - :chkpf_uid ("{11F787A5-B7C9-435C-AB4F-0851D2695778}") - :ClassName (rule_services) - ) - :compound () - :op () - : (ReferenceObject - :Name (ntp-udp) - :Table (services) - :Uid ("{97AEB404-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :src ( - :AdminInfo ( - :chkpf_uid ("{1431CA26-6106-4592-B29A-5DB903350FBF}") - :ClassName (rule_source) - ) - :compound () - :op () - : (ReferenceObject - :Name (IsoAAAD) - :Table (network_objects) - :Uid ("{29C40B0A-414C-11D7-AEB8-7F0000013C3C}") - ) - ) - ) - :rule ( - :AdminInfo ( - :chkpf_uid ("{D81E3077-3930-4FF3-A15B-21B8B5398143}") - :ClassName (security_rule) - ) - :action ( - : (accept - :AdminInfo ( - :chkpf_uid ("{5BEBEB39-FED4-40D5-93A4-926D136985DF}") - :ClassName (accept_action) - :table (setup) - ) - :action () - :macro (RECORD_CONN) - :type (accept) - ) - ) - :comments () - :disabled (false) - :global_location (middle) - :through ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :time ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :track ( - : (ReferenceObject - :Name (Log) - :Table (tracks) - :Uid ("{97AEB480-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :dst ( - :AdminInfo ( - :chkpf_uid ("{AF0A8FB4-C470-4CF9-80A4-A02D65F17CB4}") - :ClassName (rule_destination) - ) - :compound () - :op () - : (ReferenceObject - :Name (itchy) - :Table (network_objects) - :Uid ("{3B4DF852-5064-4957-B95F-D469C5656467}") - ) - ) - :install ( - :AdminInfo ( - :chkpf_uid ("{47FD7FA4-3EF7-494A-AFCC-A1175C1B7CB3}") - :ClassName (rule_install) - ) - :compound () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :services ( - :AdminInfo ( - :chkpf_uid ("{D6303579-2AD2-4EBA-BA32-3ED6EF192609}") - :ClassName (rule_services) - ) - :compound () - :op () - : (ReferenceObject - :Name (domain-udp) - :Table (services) - :Uid ("{97AEB3FA-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :src ( - :AdminInfo ( - :chkpf_uid ("{2AB872E9-0292-4B06-8D86-6960AA66787F}") - :ClassName (rule_source) - ) - :compound () - :op () - : (ReferenceObject - :Name (IsoAAAD) - :Table (network_objects) - :Uid ("{29C40B0A-414C-11D7-AEB8-7F0000013C3C}") - ) - ) - ) - :rule ( - :AdminInfo ( - :chkpf_uid ("{30829944-2BE4-46F0-A0A9-30E2DB0D85CF}") - :ClassName (security_rule) - ) - :action ( - : (accept - :AdminInfo ( - :chkpf_uid ("{BEB334AD-F3D7-44EB-95DB-360CBA080106}") - :ClassName (accept_action) - :table (setup) - ) - :action () - :macro (RECORD_CONN) - :type (accept) - ) - ) - :comments () - :disabled (false) - :global_location (middle) - :through ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :time ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :track ( - : (ReferenceObject - :Name (Log) - :Table (tracks) - :Uid ("{97AEB480-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :dst ( - :AdminInfo ( - :chkpf_uid ("{DDF30249-4842-4453-9FF3-AA14C76B632C}") - :ClassName (rule_destination) - ) - :compound () - :op () - : (ReferenceObject - :Name (spike.local) - :Table (network_objects) - :Uid ("{4ABDD8DE-0DA2-46E5-B129-85E3977CBD18}") - ) - ) - :install ( - :AdminInfo ( - :chkpf_uid ("{53000D56-F73A-45A8-8EA4-43F7DB7A16BB}") - :ClassName (rule_install) - ) - :compound () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :services ( - :AdminInfo ( - :chkpf_uid ("{5587D19B-EB61-42ED-9531-F1F13E89FF99}") - :ClassName (rule_services) - ) - :compound () - :op () - : (ReferenceObject - :Name (syslog) - :Table (services) - :Uid ("{97AEB3E0-9AEA-11D5-BD16-0090272CCB30}") - ) - : (ReferenceObject - :Name (ssh_version_2) - :Table (services) - :Uid ("{CD082D9A-44A6-4CEF-A17D-5541029ADFB3}") - ) - ) - :src ( - :AdminInfo ( - :chkpf_uid ("{CDBA6A5A-086E-4591-9FF0-87515BF4BD2E}") - :ClassName (rule_source) - ) - :compound () - :op () - : (ReferenceObject - :Name (IsoAAAD) - :Table (network_objects) - :Uid ("{29C40B0A-414C-11D7-AEB8-7F0000013C3C}") - ) - ) - ) - :rule ( - :AdminInfo ( - :chkpf_uid ("{77835D71-6333-4D9A-8DF4-CB427F59026F}") - :ClassName (security_header_rule) - ) - :action ( - : (drop - :AdminInfo ( - :chkpf_uid ("{FB12625B-C5FD-4D0C-9286-ABBD3F5D67D5}") - :ClassName (drop_action) - :table (setup) - ) - :action () - :macro () - :type (drop) - ) - ) - :comments () - :global_location (middle) - :through ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :time ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :track ( - : (ReferenceObject - :Name (None) - :Table (tracks) - :Uid ("{97AEB47D-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :disabled (true) - :dst ( - :AdminInfo ( - :chkpf_uid ("{C6EED839-1703-48FC-BAB5-CD26627C4E33}") - :ClassName (rule_destination) - ) - :compound () - :op () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :header_text (Final-rules) - :install ( - :AdminInfo ( - :chkpf_uid ("{6A78BE94-D68A-4E5D-9D5C-7794E65BDA91}") - :ClassName (rule_install) - ) - :compound () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :services ( - :AdminInfo ( - :chkpf_uid ("{9B9BDA74-31AB-443E-B101-37DAB5C8363A}") - :ClassName (rule_services) - ) - :compound () - :op () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :src ( - :AdminInfo ( - :chkpf_uid ("{FC4224DC-3D3E-4EFE-BD48-403FFD7EDEEF}") - :ClassName (rule_source) - ) - :compound () - :op () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :state (collapsed) - ) - :rule ( - :AdminInfo ( - :chkpf_uid ("{7D32EB1D-9DA2-479C-8E05-80A48B4D49B8}") - :ClassName (security_rule) - ) - :action ( - : (accept - :AdminInfo ( - :chkpf_uid ("{2664067C-FBB5-436C-9569-87F241215125}") - :ClassName (accept_action) - :table (setup) - ) - :action () - :macro (RECORD_CONN) - :type (accept) - ) - ) - :comments () - :disabled (false) - :global_location (middle) - :through ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :time ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :track ( - : (ReferenceObject - :Name (Log) - :Table (tracks) - :Uid ("{97AEB480-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :dst ( - :AdminInfo ( - :chkpf_uid ("{5AC35870-BE14-4BA8-B152-AAAD919EB93A}") - :ClassName (rule_destination) - ) - :compound () - :op () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :install ( - :AdminInfo ( - :chkpf_uid ("{EE6F2F3F-B123-4BB0-9AA6-EA670224A920}") - :ClassName (rule_install) - ) - :compound () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :services ( - :AdminInfo ( - :chkpf_uid ("{711FD2F4-7BDC-4667-8F9B-37EA46D21468}") - :ClassName (rule_services) - ) - :compound () - :op () - : (ReferenceObject - :Name (ICMPgute) - :Table (services) - :Uid ("{418C7C0A-956A-41FF-9BC1-5867B2265090}") - ) - ) - :src ( - :AdminInfo ( - :chkpf_uid ("{02294F3B-AF87-4FBE-9CE1-A3BB3434F19C}") - :ClassName (rule_source) - ) - :compound () - :op () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - ) - :rule ( - :AdminInfo ( - :chkpf_uid ("{9676DC19-81AB-4901-B03B-2B86DC876712}") - :ClassName (security_rule) - ) - :action ( - : (reject - :AdminInfo ( - :chkpf_uid ("{DFE03595-95BA-483C-B76C-14F842885448}") - :ClassName (reject_action) - :table (setup) - ) - :action () - :macro () - :type (reject) - ) - ) - :comments () - :disabled (false) - :global_location (middle) - :through ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :time ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :track ( - : (ReferenceObject - :Name (None) - :Table (tracks) - :Uid ("{97AEB47D-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :dst ( - :AdminInfo ( - :chkpf_uid ("{3EFDE682-11BD-4F54-B2CB-1E191C71351E}") - :ClassName (rule_destination) - ) - :compound () - :op () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :install ( - :AdminInfo ( - :chkpf_uid ("{A5CD71BD-98D8-43C7-8FB0-1C43B1D63F18}") - :ClassName (rule_install) - ) - :compound () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :services ( - :AdminInfo ( - :chkpf_uid ("{679E7E39-AAC3-484E-977F-403FBC9A3701}") - :ClassName (rule_services) - ) - :compound () - :op () - : (ReferenceObject - :Table (services) - :Name (Drop_nologServices) - :Uid ("{495E1A16-2612-49D9-8F69-B00EB33699E8}") - ) - ) - :src ( - :AdminInfo ( - :chkpf_uid ("{9E442067-FFAB-4B9B-8CA4-FD5FF240416A}") - :ClassName (rule_source) - ) - :compound () - :op () - : (ReferenceObject - :Name (IsoAAAA-100) - :Table (network_objects) - :Uid ("{BF1C6029-8D5D-4A05-A3AD-4B67E6E7A7AA}") - ) - ) - ) - :rule ( - :AdminInfo ( - :chkpf_uid ("{650D3396-E5C8-4FCD-AB0E-B2D867C631EC}") - :ClassName (security_rule) - ) - :action ( - : (drop - :AdminInfo ( - :chkpf_uid ("{5A63985D-9381-4F03-8F35-5A6FA61836CD}") - :ClassName (drop_action) - :table (setup) - ) - :action () - :macro () - :type (drop) - ) - ) - :comments () - :disabled (false) - :global_location (middle) - :through ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :time ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :track ( - : (ReferenceObject - :Name (Log) - :Table (tracks) - :Uid ("{97AEB480-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :dst ( - :AdminInfo ( - :chkpf_uid ("{F0A383D4-E033-445F-87F7-679987F289F8}") - :ClassName (rule_destination) - ) - :compound () - :op () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :install ( - :AdminInfo ( - :chkpf_uid ("{CBAF3D5E-4D05-4D90-9278-B74D854765E4}") - :ClassName (rule_install) - ) - :compound () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :services ( - :AdminInfo ( - :chkpf_uid ("{55A4F666-58D1-4D21-97F0-6A66BE8A9A4E}") - :ClassName (rule_services) - ) - :compound () - :op () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :src ( - :AdminInfo ( - :chkpf_uid ("{D38D5022-5541-47F6-BEC1-D34D577D5B31}") - :ClassName (rule_source) - ) - :compound () - :op () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - ) - :rule_adtr ( - :AdminInfo ( - :chkpf_uid ("{AEB9F3D3-F756-4622-8279-546EB4AEDA6D}") - :ClassName (address_translation_rule) - ) - :comments () - :disabled (false) - :dst_adtr ( - : (ReferenceObject - :Name (IsoAAAA-100) - :Table (network_objects) - :Uid ("{BF1C6029-8D5D-4A05-A3AD-4B67E6E7A7AA}") - ) - ) - :global_location (middle) - :install ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :rule_block_number (1) - :services_adtr ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :src_adtr ( - : (ReferenceObject - :Name (vpn-sources-IsoAAAA) - :Table (network_objects) - :Uid ("{26405A41-425C-4053-8002-497BB82D76B1}") - ) - ) - :dst_adtr_translated ( - :AdminInfo ( - :chkpf_uid ("{27CFFB17-E049-4E32-BCCD-D8140703E33E}") - :ClassName (translate_static) - ) - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - :adtr_method (adtr_method_static) - ) - :services_adtr_translated ( - :AdminInfo ( - :chkpf_uid ("{7236D86D-A66E-4FFA-8C32-BF31AA649665}") - :ClassName (service_translate) - ) - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - :adtr_method (adtr_method_static) - ) - :src_adtr_translated ( - :AdminInfo ( - :chkpf_uid ("{D12593A4-D593-4DC7-A241-19915862D874}") - :ClassName (translate_hide) - ) - : (ReferenceObject - :Name (IsoAAAD_intern) - :Table (network_objects) - :Uid ("{40831AE2-CB84-46D2-9522-F987BC10BDB9}") - ) - :adtr_method (adtr_method_hide) - ) - ) - :rule_adtr ( - :AdminInfo ( - :chkpf_uid ("{CE9E192B-7125-4C9B-9923-3CC0851ECF86}") - :ClassName (address_translation_rule) - ) - :comments () - :disabled (false) - :dst_adtr ( - : (ReferenceObject - :Name (IsoAAAA-100) - :Table (network_objects) - :Uid ("{BF1C6029-8D5D-4A05-A3AD-4B67E6E7A7AA}") - ) - ) - :global_location (middle) - :install ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :rule_block_number (1) - :services_adtr ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :src_adtr ( - : (ReferenceObject - :Name (Cactus-InternetTransfer) - :Table (network_objects) - :Uid ("{408C820D-33A1-4E25-B576-EC826F525DCD}") - ) - ) - :dst_adtr_translated ( - :AdminInfo ( - :chkpf_uid ("{5B4D59AD-51B2-4FF4-BBE4-6004FDC2B0EB}") - :ClassName (translate_static) - ) - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - :adtr_method (adtr_method_static) - ) - :services_adtr_translated ( - :AdminInfo ( - :chkpf_uid ("{5AC7492C-C631-4E37-BCD5-AA50435F5477}") - :ClassName (service_translate) - ) - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - :adtr_method (adtr_method_static) - ) - :src_adtr_translated ( - :AdminInfo ( - :chkpf_uid ("{0671F784-E9CC-423F-82E0-AC645A80560B}") - :ClassName (translate_hide) - ) - : (ReferenceObject - :Name (IsoAAAD_intern) - :Table (network_objects) - :Uid ("{40831AE2-CB84-46D2-9522-F987BC10BDB9}") - ) - :adtr_method (adtr_method_hide) - ) - ) - :rule_adtr ( - :AdminInfo ( - :chkpf_uid ("{BC27101C-9BC5-4E5A-96FB-9C745A716EC6}") - :ClassName (address_translation_rule) - ) - :comments () - :disabled (false) - :dst_adtr ( - : (ReferenceObject - :Name (IsoAAADray.local) - :Table (network_objects) - :Uid ("{75EDBC62-7EB1-4D37-8295-684903FDA75A}") - ) - ) - :global_location (middle) - :install ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :rule_block_number (1) - :services_adtr ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :src_adtr ( - : (ReferenceObject - :Name (heag_off_upper) - :Table (network_objects) - :Uid ("{A58E3E67-0517-485F-AA04-97A12BC119C3}") - ) - ) - :dst_adtr_translated ( - :AdminInfo ( - :chkpf_uid ("{FCA2AE6C-5BD9-43B0-BC7D-E0CA44B623D1}") - :ClassName (translate_static) - ) - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - :adtr_method (adtr_method_static) - ) - :services_adtr_translated ( - :AdminInfo ( - :chkpf_uid ("{CC48C8B8-7D7A-4958-964F-3CF28847B3B3}") - :ClassName (service_translate) - ) - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - :adtr_method (adtr_method_static) - ) - :src_adtr_translated ( - :AdminInfo ( - :chkpf_uid ("{B11BD765-AEC0-4BF9-A63E-E8D829A3BC8C}") - :ClassName (translate_hide) - ) - : (ReferenceObject - :Name (IsoAAAD_intern) - :Table (network_objects) - :Uid ("{40831AE2-CB84-46D2-9522-F987BC10BDB9}") - ) - :adtr_method (adtr_method_hide) - ) - ) - :use_VPN_communities (false) - ) - :rule-base ("##IsoAAAA" - :AdminInfo ( - :chkpf_uid ("{4DFA246F-BCB1-4283-B3D6-685FBF8DB89B}") - :ClassName (firewall_policy) - :table (fw_policies) - :LastModified ( - :Time ("Wed Jul 27 15:32:20 2005") - :By (IsoAAAF) - :From (IsoAAADray) - ) - ) - :default (0) - :queries () - :queries_adtr () - :collection (ReferenceObject - :Name (IsoAAAA) - :Table (policies_collections) - :Uid ("{462FD47E-BB4B-4DC4-95D6-E25D7E6C1E41}") - ) - :rule ( - :AdminInfo ( - :chkpf_uid ("{A4029F61-9672-4AA3-B1D9-0FF4E8979971}") - :ClassName (security_header_rule) - ) - :action ( - : (drop - :AdminInfo ( - :chkpf_uid ("{5EE13032-A1E1-4538-90BC-6295FD3DFE04}") - :ClassName (drop_action) - :table (setup) - ) - :action () - :macro () - :type (drop) - ) - ) - :comments () - :global_location (middle) - :through ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :time ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :track ( - : (ReferenceObject - :Name (None) - :Table (tracks) - :Uid ("{97AEB47D-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :disabled (true) - :dst ( - :AdminInfo ( - :chkpf_uid ("{5560B804-6408-442F-903B-2B279AE6D9C2}") - :ClassName (rule_destination) - ) - :compound () - :op () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :header_text (test-rules) - :install ( - :AdminInfo ( - :chkpf_uid ("{0B1EB683-1A59-44FF-901C-5FDB9EA65A5E}") - :ClassName (rule_install) - ) - :compound () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :services ( - :AdminInfo ( - :chkpf_uid ("{F8D6F7F5-4582-4256-A0A5-EBFDDB2EF590}") - :ClassName (rule_services) - ) - :compound () - :op () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :src ( - :AdminInfo ( - :chkpf_uid ("{AF27380F-6548-4B83-81FD-1B5EAECAA8F6}") - :ClassName (rule_source) - ) - :compound () - :op () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :state (expanded) - ) - :rule ( - :AdminInfo ( - :chkpf_uid ("{ABC6E209-A440-42E2-A896-CF27A1CA2744}") - :ClassName (security_rule) - ) - :action ( - : ("Client Encrypt" - :AdminInfo ( - :chkpf_uid ("{E9CD394B-3A31-4AA4-A8F5-D2120F53E780}") - :ClassName (client_encrypt) - :table (setup) - ) - :action (accept) - :dst_options ("intersect with user database") - :enforce_desktop_config (false) - :macro (USER_CLIENT_ENCRYPTION) - :src_options ("intersect with user database") - :type (userc) - ) - ) - :global_location (middle) - :through ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :time ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :track ( - : (ReferenceObject - :Name (Log) - :Table (tracks) - :Uid ("{97AEB480-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :comments (vpn_test) - :disabled (true) - :dst ( - :AdminInfo ( - :chkpf_uid ("{65F39402-76F2-45CC-A99C-0903FE70DF4C}") - :ClassName (rule_destination) - ) - :compound () - :op () - : (ReferenceObject - :Name (IsoAAADray.local) - :Table (network_objects) - :Uid ("{75EDBC62-7EB1-4D37-8295-684903FDA75A}") - ) - ) - :install ( - :AdminInfo ( - :chkpf_uid ("{C6DE2209-1A7B-4FCC-B7A7-A1D4EDD793D7}") - :ClassName (rule_install) - ) - :compound () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :services ( - :AdminInfo ( - :chkpf_uid ("{91BC0FDA-33F0-49D8-BC63-FFA85CBAFD40}") - :ClassName (rule_services) - ) - :compound () - :op () - : (ReferenceObject - :Name (NBT) - :Table (services) - :Uid ("{97AEB471-9AEA-11D5-BD16-0090272CCB30}") - ) - : (ReferenceObject - :Name (icmp-requests) - :Table (services) - :Uid ("{97AEB413-9AEA-11D5-BD16-0090272CCB30}") - ) - : (ReferenceObject - :Name (CIFS) - :Table (services) - :Uid ("{2A469820-B502-434C-9340-A377677A6A60}") - ) - : (ReferenceObject - :Name (rdp) - :Table (services) - :Uid ("{5BA0C83F-8D91-465B-9CF6-7DC6AEB84689}") - ) - ) - :src ( - :AdminInfo ( - :chkpf_uid ("{28C21DCF-D0A0-4F40-8017-BCD946EFF41D}") - :ClassName (rule_source) - ) - :compound ( - : (vpn_user@heag_off_upper - :AdminInfo ( - :chkpf_uid ("{ABBA5C5D-AE07-4CF6-A00E-3649064D0BDB}") - :ClassName (rule_user_group) - ) - :at (ReferenceObject - :Name (heag_off_upper) - :Table (network_objects) - :Uid ("{A58E3E67-0517-485F-AA04-97A12BC119C3}") - ) - :color (black) - :type (usrgroup) - ) - ) - :op () - ) - ) - :rule ( - :AdminInfo ( - :chkpf_uid ("{5AFB86A5-E247-411F-AAD7-A8EFDE97A0F5}") - :ClassName (security_rule) - ) - :action ( - : (accept - :AdminInfo ( - :chkpf_uid ("{150ABA94-098B-4CC3-AF8A-BDFED81FC20E}") - :ClassName (accept_action) - :table (setup) - ) - :action () - :macro (RECORD_CONN) - :type (accept) - ) - ) - :comments () - :global_location (middle) - :through ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :time ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :track ( - : (ReferenceObject - :Name (Log) - :Table (tracks) - :Uid ("{97AEB480-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :disabled (true) - :dst ( - :AdminInfo ( - :chkpf_uid ("{5526AF1C-6E4F-4F71-A58E-A1E5F88B62DB}") - :ClassName (rule_destination) - ) - :compound () - :op () - : (ReferenceObject - :Name (Premier_Access) - :Table (network_objects) - :Uid ("{B2BB20AA-B685-426B-96B6-1FB4D8D05135}") - ) - : (ReferenceObject - :Name (IsoAAAD) - :Table (network_objects) - :Uid ("{29C40B0A-414C-11D7-AEB8-7F0000013C3C}") - ) - ) - :install ( - :AdminInfo ( - :chkpf_uid ("{7F41F235-2373-4F38-9141-29AB9CEAD2D8}") - :ClassName (rule_install) - ) - :compound () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :services ( - :AdminInfo ( - :chkpf_uid ("{C2DE3BB7-C1B7-49C9-BC21-97AB3CE81521}") - :ClassName (rule_services) - ) - :compound () - :op () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :src ( - :AdminInfo ( - :chkpf_uid ("{F8ECC436-D19B-4124-9BC3-31C1E3945A36}") - :ClassName (rule_source) - ) - :compound () - :op () - : (ReferenceObject - :Name (IsoAAAD) - :Table (network_objects) - :Uid ("{29C40B0A-414C-11D7-AEB8-7F0000013C3C}") - ) - : (ReferenceObject - :Name (Premier_Access) - :Table (network_objects) - :Uid ("{B2BB20AA-B685-426B-96B6-1FB4D8D05135}") - ) - ) - ) - :rule ( - :AdminInfo ( - :chkpf_uid ("{38429C3B-05FE-49C8-9D8C-83F0AC9661CD}") - :ClassName (security_rule) - ) - :action ( - : ("Client Encrypt" - :AdminInfo ( - :chkpf_uid ("{5F145F42-1609-4937-A766-0D8B67710BCC}") - :ClassName (client_encrypt) - :table (setup) - ) - :action (accept) - :dst_options ("intersect with user database") - :enforce_desktop_config (false) - :macro (USER_CLIENT_ENCRYPTION) - :src_options ("intersect with user database") - :type (userc) - ) - ) - :global_location (middle) - :through ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :time ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :track ( - : (ReferenceObject - :Name (Log) - :Table (tracks) - :Uid ("{97AEB480-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :comments ("RAS - Test mit Premier-Access - Tokens") - :disabled (true) - :dst ( - :AdminInfo ( - :chkpf_uid ("{FEABA989-54EB-4D53-96C9-6841B9BBEB4B}") - :ClassName (rule_destination) - ) - :compound () - :op () - : (ReferenceObject - :Name (IsoAAAA-100) - :Table (network_objects) - :Uid ("{BF1C6029-8D5D-4A05-A3AD-4B67E6E7A7AA}") - ) - : (ReferenceObject - :Name (IsoAAAD) - :Table (network_objects) - :Uid ("{29C40B0A-414C-11D7-AEB8-7F0000013C3C}") - ) - ) - :install ( - :AdminInfo ( - :chkpf_uid ("{162F84EF-286D-4D55-B03F-8DC9F535553A}") - :ClassName (rule_install) - ) - :compound () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :services ( - :AdminInfo ( - :chkpf_uid ("{130A495D-1435-441B-98CE-993791EBDA7A}") - :ClassName (rule_services) - ) - :compound () - :op () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :src ( - :AdminInfo ( - :chkpf_uid ("{766EEA30-3B32-455D-A951-52D75F93E1D9}") - :ClassName (rule_source) - ) - :compound ( - : (test@Any - :AdminInfo ( - :chkpf_uid ("{C8439795-0347-401E-9663-4EBE924B0F4B}") - :ClassName (rule_user_group) - ) - :at (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - :color (black) - :type (usrgroup) - ) - ) - :op () - ) - ) - :rule ( - :AdminInfo ( - :chkpf_uid ("{24DC38E2-D64D-40EC-B81B-BE3B27A12CED}") - :ClassName (security_header_rule) - ) - :action ( - : (drop - :AdminInfo ( - :chkpf_uid ("{23D057DA-D1AB-4FFD-B61A-806648650D75}") - :ClassName (drop_action) - :table (setup) - ) - :action () - :macro () - :type (drop) - ) - ) - :comments () - :global_location (middle) - :through ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :time ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :track ( - : (ReferenceObject - :Name (None) - :Table (tracks) - :Uid ("{97AEB47D-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :disabled (true) - :dst ( - :AdminInfo ( - :chkpf_uid ("{690BE832-509A-4F4D-A0A2-C9E665129607}") - :ClassName (rule_destination) - ) - :compound () - :op () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :header_text ("IsoAAAE SecuRemote") - :install ( - :AdminInfo ( - :chkpf_uid ("{67EE9042-BF3D-4971-8346-FA36156A5F74}") - :ClassName (rule_install) - ) - :compound () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :services ( - :AdminInfo ( - :chkpf_uid ("{4C231AF1-095C-4CAA-A12C-2EA5B88E76B9}") - :ClassName (rule_services) - ) - :compound () - :op () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :src ( - :AdminInfo ( - :chkpf_uid ("{F23B90BB-44A6-4F7D-8573-48E730D231EE}") - :ClassName (rule_source) - ) - :compound () - :op () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :state (expanded) - ) - :rule ( - :AdminInfo ( - :chkpf_uid ("{4D877153-65A8-48A9-9D11-B30CA56946EF}") - :ClassName (security_rule) - ) - :action ( - : ("Client Encrypt" - :AdminInfo ( - :chkpf_uid ("{13A8B02C-F3C2-473D-A9E9-E49EA1DF3434}") - :ClassName (client_encrypt) - :table (setup) - ) - :action (accept) - :dst_options ("Intersect with User Database") - :enforce_desktop_config (false) - :macro (USER_CLIENT_ENCRYPTION) - :src_options ("Intersect with User Database") - :type (userc) - ) - ) - :comments () - :disabled (false) - :global_location (middle) - :through ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :time ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :track ( - : (ReferenceObject - :Name (Log) - :Table (tracks) - :Uid ("{97AEB480-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :dst ( - :AdminInfo ( - :chkpf_uid ("{C2778755-3B4C-491C-85A7-E4523035CD2B}") - :ClassName (rule_destination) - ) - :compound () - :op () - : (ReferenceObject - :Name (IsoAAADray.local) - :Table (network_objects) - :Uid ("{75EDBC62-7EB1-4D37-8295-684903FDA75A}") - ) - : (ReferenceObject - :Name (gateway.local) - :Table (network_objects) - :Uid ("{7ED7EF12-A13E-4303-8A6E-C6CC28755C80}") - ) - ) - :install ( - :AdminInfo ( - :chkpf_uid ("{CA2D51EE-4A3F-4FE8-B21C-6532E9E7D2C6}") - :ClassName (rule_install) - ) - :compound () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :services ( - :AdminInfo ( - :chkpf_uid ("{5D51CCD0-95A5-408B-83C0-6F18D2B9A460}") - :ClassName (rule_services) - ) - :compound () - :op () - : (ReferenceObject - :Name (CIFS) - :Table (services) - :Uid ("{2A469820-B502-434C-9340-A377677A6A60}") - ) - : (ReferenceObject - :Name (rdp) - :Table (services) - :Uid ("{5BA0C83F-8D91-465B-9CF6-7DC6AEB84689}") - ) - : (ReferenceObject - :Name (ntp-udp) - :Table (services) - :Uid ("{97AEB404-9AEA-11D5-BD16-0090272CCB30}") - ) - : (ReferenceObject - :Name (domain-udp) - :Table (services) - :Uid ("{97AEB3FA-9AEA-11D5-BD16-0090272CCB30}") - ) - : (ReferenceObject - :Name (http) - :Table (services) - :Uid ("{97AEB3D4-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :src ( - :AdminInfo ( - :chkpf_uid ("{3B379A82-34F3-4A23-B77C-B50EAD80BD53}") - :ClassName (rule_source) - ) - :compound ( - : (Cactus-extern@vpn-sources-IsoAAAA - :AdminInfo ( - :chkpf_uid ("{C7F9820A-4EDD-4187-98D9-CC655885E0D6}") - :ClassName (rule_user_group) - ) - :at (ReferenceObject - :Name (vpn-sources-IsoAAAA) - :Table (network_objects) - :Uid ("{26405A41-425C-4053-8002-497BB82D76B1}") - ) - :color (black) - :type (usrgroup) - ) - ) - :op () - ) - ) - :rule ( - :AdminInfo ( - :chkpf_uid ("{AC6B21DA-86AF-4EB3-B294-3387F815E66E}") - :ClassName (security_rule) - ) - :action ( - : ("Client Encrypt" - :AdminInfo ( - :chkpf_uid ("{557B0552-8CDC-40D8-8B63-00E30DC9681A}") - :ClassName (client_encrypt) - :table (setup) - ) - :action (accept) - :dst_options ("intersect with user database") - :enforce_desktop_config (false) - :macro (USER_CLIENT_ENCRYPTION) - :src_options ("intersect with user database") - :type (userc) - ) - ) - :comments () - :disabled (false) - :global_location (middle) - :through ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :time ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :track ( - : (ReferenceObject - :Name (Log) - :Table (tracks) - :Uid ("{97AEB480-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :dst ( - :AdminInfo ( - :chkpf_uid ("{B7130E5B-C62A-4BEF-A2B3-3A2306AE0E5A}") - :ClassName (rule_destination) - ) - :compound () - :op () - : (ReferenceObject - :Name (scratchy.local) - :Table (network_objects) - :Uid ("{CFABE50C-C1F6-4FF1-8AC3-3161A3779708}") - ) - ) - :install ( - :AdminInfo ( - :chkpf_uid ("{58B74533-737D-4182-B405-F3EAC537960A}") - :ClassName (rule_install) - ) - :compound () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :services ( - :AdminInfo ( - :chkpf_uid ("{115D6863-5E76-4339-B76F-8AF7B421C12F}") - :ClassName (rule_services) - ) - :compound () - :op () - : (ReferenceObject - :Name (RAdmin-custom) - :Table (services) - :Uid ("{4FB59153-8212-4A12-BC08-0297AA5F0815}") - ) - ) - :src ( - :AdminInfo ( - :chkpf_uid ("{4400E028-7BB5-405F-AE2C-CE84535C3D32}") - :ClassName (rule_source) - ) - :compound ( - : (IsoAAAG-g@vpn-sources-IsoAAAA - :AdminInfo ( - :chkpf_uid ("{23622C19-C400-4C6D-9BCA-E69C2217DE8E}") - :ClassName (rule_user_group) - ) - :at (ReferenceObject - :Name (vpn-sources-IsoAAAA) - :Table (network_objects) - :Uid ("{26405A41-425C-4053-8002-497BB82D76B1}") - ) - :color (black) - :type (usrgroup) - ) - ) - :op () - ) - ) - :rule ( - :AdminInfo ( - :chkpf_uid ("{5289C1E3-9679-4537-AFD3-AA8663CA5F39}") - :ClassName (security_rule) - ) - :action ( - : ("Client Encrypt" - :AdminInfo ( - :chkpf_uid ("{4572A69E-C640-4125-B38D-1EBEA7F257F0}") - :ClassName (client_encrypt) - :table (setup) - ) - :action (accept) - :dst_options ("Intersect with User Database") - :enforce_desktop_config (false) - :macro (USER_CLIENT_ENCRYPTION) - :src_options ("Intersect with User Database") - :type (userc) - ) - ) - :comments () - :disabled (false) - :global_location (middle) - :through ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :time ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :track ( - : (ReferenceObject - :Name (Log) - :Table (tracks) - :Uid ("{97AEB480-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :dst ( - :AdminInfo ( - :chkpf_uid ("{68ABBD00-BD78-4112-A679-DC94A8CDB47B}") - :ClassName (rule_destination) - ) - :compound () - :op () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :install ( - :AdminInfo ( - :chkpf_uid ("{D26ADD37-6C0A-4402-BAC8-92A4CA9B11CA}") - :ClassName (rule_install) - ) - :compound () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :services ( - :AdminInfo ( - :chkpf_uid ("{99E348A7-72A0-43EC-B728-58DED1B0ED1F}") - :ClassName (rule_services) - ) - :compound () - :op () - : (ReferenceObject - :Name (T-online-classic) - :Table (services) - :Uid ("{738B04E5-09F7-44BF-9FEC-AEA0F15B7E9A}") - ) - : (ReferenceObject - :Name (HBCI) - :Table (services) - :Uid ("{336C93F8-5CC2-48BE-9328-2E92F61EFCF1}") - ) - ) - :src ( - :AdminInfo ( - :chkpf_uid ("{040245DC-1E6B-44D2-A0C5-C7D1A9FAFAF0}") - :ClassName (rule_source) - ) - :compound ( - : (IsoAAAG-g@vpn-sources-IsoAAAA - :AdminInfo ( - :chkpf_uid ("{23622C19-C400-4C6D-9BCA-E69C2217DE8E}") - :ClassName (rule_user_group) - ) - :at (ReferenceObject - :Name (vpn-sources-IsoAAAA) - :Table (network_objects) - :Uid ("{26405A41-425C-4053-8002-497BB82D76B1}") - ) - :color (black) - :type (usrgroup) - ) - ) - :op () - ) - ) - :rule ( - :AdminInfo ( - :chkpf_uid ("{73F2144F-4C58-4361-94B5-459B469A6541}") - :ClassName (security_rule) - ) - :action ( - : ("Client Encrypt" - :AdminInfo ( - :chkpf_uid ("{79C1343A-9B8B-4AB8-8F0C-795A3C6985F8}") - :ClassName (client_encrypt) - :table (setup) - ) - :action (accept) - :dst_options ("Intersect with User Database") - :enforce_desktop_config (false) - :macro (USER_CLIENT_ENCRYPTION) - :src_options ("Intersect with User Database") - :type (userc) - ) - ) - :comments () - :disabled (false) - :global_location (middle) - :through ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :time ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :track ( - : (ReferenceObject - :Name (Log) - :Table (tracks) - :Uid ("{97AEB480-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :dst ( - :AdminInfo ( - :chkpf_uid ("{8D75B038-29A6-4DFC-99BE-77BB50F0248D}") - :ClassName (rule_destination) - ) - :compound () - :op () - : (ReferenceObject - :Name (spike.local) - :Table (network_objects) - :Uid ("{4ABDD8DE-0DA2-46E5-B129-85E3977CBD18}") - ) - : (ReferenceObject - :Name (mg.IsoAAAA-es.com) - :Table (network_objects) - :Uid ("{E5BF8260-3615-4476-B638-53CA3A24FEF1}") - ) - ) - :install ( - :AdminInfo ( - :chkpf_uid ("{64D010BF-D0CB-4F9F-9B7A-DBAD17892364}") - :ClassName (rule_install) - ) - :compound () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :services ( - :AdminInfo ( - :chkpf_uid ("{A9590BAB-F46F-4EB7-8125-A4EE6791DD5F}") - :ClassName (rule_services) - ) - :compound () - :op () - : (ReferenceObject - :Name (squid) - :Table (services) - :Uid ("{91C0454D-F70C-44B3-8F2D-70C4A68E9594}") - ) - : (ReferenceObject - :Name (imap) - :Table (services) - :Uid ("{97AEB446-9AEA-11D5-BD16-0090272CCB30}") - ) - : (ReferenceObject - :Name (imaps) - :Table (services) - :Uid ("{B760A869-04DF-43E2-91F9-414C58F86F16}") - ) - ) - :src ( - :AdminInfo ( - :chkpf_uid ("{32C8D43F-D47D-4477-9217-8E249CBA8F9E}") - :ClassName (rule_source) - ) - :compound ( - : (Cactus-extern@vpn-sources-IsoAAAA - :AdminInfo ( - :chkpf_uid ("{93AC11B4-FFD0-4DBB-BA60-321FE5E9AD32}") - :ClassName (rule_user_group) - ) - :at (ReferenceObject - :Name (vpn-sources-IsoAAAA) - :Table (network_objects) - :Uid ("{26405A41-425C-4053-8002-497BB82D76B1}") - ) - :color (black) - :type (usrgroup) - ) - ) - :op () - ) - ) - :rule ( - :AdminInfo ( - :chkpf_uid ("{6ADC5431-5B24-47FC-A9A6-F8DC912B0515}") - :ClassName (security_rule) - ) - :action ( - : ("Client Encrypt" - :AdminInfo ( - :chkpf_uid ("{6CA48465-23C7-4B10-AAA3-AD9A9E4F8588}") - :ClassName (client_encrypt) - :table (setup) - ) - :action (accept) - :dst_options ("Intersect with User Database") - :enforce_desktop_config (false) - :macro (USER_CLIENT_ENCRYPTION) - :src_options ("Intersect with User Database") - :type (userc) - ) - ) - :comments () - :disabled (false) - :global_location (middle) - :through ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :time ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :track ( - : (ReferenceObject - :Name (Log) - :Table (tracks) - :Uid ("{97AEB480-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :dst ( - :AdminInfo ( - :chkpf_uid ("{586E9FDE-3504-4C3C-B1B3-A73F6D3F379B}") - :ClassName (rule_destination) - ) - :compound () - :op () - : (ReferenceObject - :Name (itchy) - :Table (network_objects) - :Uid ("{3B4DF852-5064-4957-B95F-D469C5656467}") - ) - ) - :install ( - :AdminInfo ( - :chkpf_uid ("{067D0452-9D33-44EA-8433-DF53F0333503}") - :ClassName (rule_install) - ) - :compound () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :services ( - :AdminInfo ( - :chkpf_uid ("{656EA975-486E-43AA-B73C-209ED71366BC}") - :ClassName (rule_services) - ) - :compound () - :op () - : (ReferenceObject - :Name (smtp) - :Table (services) - :Uid ("{97AEB3D9-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :src ( - :AdminInfo ( - :chkpf_uid ("{028E2317-59C3-4783-AFA3-8121A808F9D8}") - :ClassName (rule_source) - ) - :compound ( - : (Cactus-extern@vpn-sources-IsoAAAA - :AdminInfo ( - :chkpf_uid ("{3D633953-A379-43C2-BCD5-CFCE90A8F60D}") - :ClassName (rule_user_group) - ) - :at (ReferenceObject - :Name (vpn-sources-IsoAAAA) - :Table (network_objects) - :Uid ("{26405A41-425C-4053-8002-497BB82D76B1}") - ) - :color (black) - :type (usrgroup) - ) - ) - :op () - ) - ) - :rule ( - :AdminInfo ( - :chkpf_uid ("{09847FA8-6AD8-4196-A6BA-C2E5A4380CAF}") - :ClassName (security_rule) - ) - :action ( - : ("Client Encrypt" - :AdminInfo ( - :chkpf_uid ("{EFBB77A2-67A2-45E9-8D82-5DE40E64C792}") - :ClassName (client_encrypt) - :table (setup) - ) - :action (accept) - :dst_options ("Intersect with User Database") - :enforce_desktop_config (false) - :macro (USER_CLIENT_ENCRYPTION) - :src_options ("Intersect with User Database") - :type (userc) - ) - ) - :comments () - :disabled (false) - :global_location (middle) - :through ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :time ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :track ( - : (ReferenceObject - :Name (Log) - :Table (tracks) - :Uid ("{97AEB480-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :dst ( - :AdminInfo ( - :chkpf_uid ("{AE09F8C4-EE69-4874-A359-DE443685FA10}") - :ClassName (rule_destination) - ) - :compound () - :op () - : (ReferenceObject - :Name (wasp) - :Table (network_objects) - :Uid ("{098B2A74-E220-4AE8-A164-340FED79C9D5}") - ) - ) - :install ( - :AdminInfo ( - :chkpf_uid ("{88454436-C062-4605-BADB-73FD6F534D0F}") - :ClassName (rule_install) - ) - :compound () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :services ( - :AdminInfo ( - :chkpf_uid ("{79BEA1F5-E14E-4C55-B7B2-4765F608CEC4}") - :ClassName (rule_services) - ) - :compound () - :op () - : (ReferenceObject - :Name (ntp-udp) - :Table (services) - :Uid ("{97AEB404-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :src ( - :AdminInfo ( - :chkpf_uid ("{7851EA21-542A-4587-B676-F7DD371446C5}") - :ClassName (rule_source) - ) - :compound ( - : (Cactus-extern@vpn-sources-IsoAAAA - :AdminInfo ( - :chkpf_uid ("{4BC9D4D1-5EE4-45A3-9EE3-77D2B97D21EF}") - :ClassName (rule_user_group) - ) - :at (ReferenceObject - :Name (vpn-sources-IsoAAAA) - :Table (network_objects) - :Uid ("{26405A41-425C-4053-8002-497BB82D76B1}") - ) - :color (black) - :type (usrgroup) - ) - ) - :op () - ) - ) - :rule ( - :AdminInfo ( - :chkpf_uid ("{67784DF8-6440-4F4A-891C-C7062E0F32B0}") - :ClassName (security_rule) - ) - :action ( - : ("Client Encrypt" - :AdminInfo ( - :chkpf_uid ("{CD454805-68CD-42E4-98C3-0DBF82CB9BE6}") - :ClassName (client_encrypt) - :table (setup) - ) - :action (accept) - :dst_options ("Intersect with User Database") - :enforce_desktop_config (false) - :macro (USER_CLIENT_ENCRYPTION) - :src_options ("Intersect with User Database") - :type (userc) - ) - ) - :comments () - :disabled (false) - :global_location (middle) - :through ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :time ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :track ( - : (ReferenceObject - :Name (Log) - :Table (tracks) - :Uid ("{97AEB480-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :dst ( - :AdminInfo ( - :chkpf_uid ("{D29D3530-277E-4D41-86B8-CDFD1640107F}") - :ClassName (rule_destination) - ) - :compound () - :op () - : (ReferenceObject - :Name (wasp) - :Table (network_objects) - :Uid ("{098B2A74-E220-4AE8-A164-340FED79C9D5}") - ) - : (ReferenceObject - :Name (hpux) - :Table (network_objects) - :Uid ("{BF00A847-A0D6-4A75-BE1C-27E7D91EDB55}") - ) - : (ReferenceObject - :Name (sol8) - :Table (network_objects) - :Uid ("{86F22190-7D8D-435D-8906-A346CA12A17C}") - ) - ) - :install ( - :AdminInfo ( - :chkpf_uid ("{35771DD3-A725-4A30-B8D1-2D4DE471A8AA}") - :ClassName (rule_install) - ) - :compound () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :services ( - :AdminInfo ( - :chkpf_uid ("{65CD16B1-1526-40F3-9D70-2C6DE0FD27B8}") - :ClassName (rule_services) - ) - :compound () - :op () - : (ReferenceObject - :Name (telnet) - :Table (services) - :Uid ("{97AEB3CF-9AEA-11D5-BD16-0090272CCB30}") - ) - : (ReferenceObject - :Name (ssh) - :Table (services) - :Uid ("{18EC9EAA-1657-4240-AB97-5F234623336B}") - ) - : (ReferenceObject - :Name (ftp) - :Table (services) - :Uid ("{97AEB3D0-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :src ( - :AdminInfo ( - :chkpf_uid ("{3E20C184-B0AC-458B-AB58-17C5E8D0CB58}") - :ClassName (rule_source) - ) - :compound ( - : (Cactus-extern@vpn-sources-IsoAAAA - :AdminInfo ( - :chkpf_uid ("{4BC9D4D1-5EE4-45A3-9EE3-77D2B97D21EF}") - :ClassName (rule_user_group) - ) - :at (ReferenceObject - :Name (vpn-sources-IsoAAAA) - :Table (network_objects) - :Uid ("{26405A41-425C-4053-8002-497BB82D76B1}") - ) - :color (black) - :type (usrgroup) - ) - ) - :op () - ) - ) - :rule ( - :AdminInfo ( - :chkpf_uid ("{C6951C02-A10A-4757-A85F-5C197D6B95EB}") - :ClassName (security_rule) - ) - :action ( - : ("Client Encrypt" - :AdminInfo ( - :chkpf_uid ("{8EFD07B3-1AE9-4498-A0EA-FFF0CAEC9824}") - :ClassName (client_encrypt) - :table (setup) - ) - :action (accept) - :dst_options ("Intersect with User Database") - :enforce_desktop_config (false) - :macro (USER_CLIENT_ENCRYPTION) - :src_options ("Intersect with User Database") - :type (userc) - ) - ) - :comments () - :disabled (false) - :global_location (middle) - :through ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :time ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :track ( - : (ReferenceObject - :Name (Log) - :Table (tracks) - :Uid ("{97AEB480-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :dst ( - :AdminInfo ( - :chkpf_uid ("{953252BD-3073-4D69-B49A-86B012FEF76D}") - :ClassName (rule_destination) - ) - :compound () - :op () - : (ReferenceObject - :Name (IsoAAAA-100) - :Table (network_objects) - :Uid ("{BF1C6029-8D5D-4A05-A3AD-4B67E6E7A7AA}") - ) - ) - :install ( - :AdminInfo ( - :chkpf_uid ("{019A9168-EF95-46C7-AFB5-B0788EBDAB4B}") - :ClassName (rule_install) - ) - :compound () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :services ( - :AdminInfo ( - :chkpf_uid ("{63D8350C-2432-4909-91D6-4459C3054B4E}") - :ClassName (rule_services) - ) - :compound () - :op () - : (ReferenceObject - :Name (icmp-requests) - :Table (services) - :Uid ("{97AEB413-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :src ( - :AdminInfo ( - :chkpf_uid ("{D6818DB3-CC9E-498A-B47D-DA9204F004F4}") - :ClassName (rule_source) - ) - :compound ( - : (Cactus-extern@vpn-sources-IsoAAAA - :AdminInfo ( - :chkpf_uid ("{970C0D68-3CEC-47CA-B2C0-EB23C9B56AC8}") - :ClassName (rule_user_group) - ) - :at (ReferenceObject - :Name (vpn-sources-IsoAAAA) - :Table (network_objects) - :Uid ("{26405A41-425C-4053-8002-497BB82D76B1}") - ) - :color (black) - :type (usrgroup) - ) - ) - :op () - ) - ) - :rule ( - :AdminInfo ( - :chkpf_uid ("{84087B02-E15A-4E97-9204-F0F866206B75}") - :ClassName (security_header_rule) - ) - :action ( - : (drop - :AdminInfo ( - :chkpf_uid ("{C1A1378F-A974-41CF-BB10-A3F1D8205A3A}") - :ClassName (drop_action) - :table (setup) - ) - :action () - :macro () - :type (drop) - ) - ) - :comments () - :global_location (middle) - :through ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :time ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :track ( - : (ReferenceObject - :Name (None) - :Table (tracks) - :Uid ("{97AEB47D-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :disabled (true) - :dst ( - :AdminInfo ( - :chkpf_uid ("{6CF2DE51-FF05-4F78-A967-BA8F290325BF}") - :ClassName (rule_destination) - ) - :compound () - :op () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :header_text ("IsoAAAE VPN-GW2GW") - :install ( - :AdminInfo ( - :chkpf_uid ("{478AEC09-B131-41B8-8756-A059E1E43421}") - :ClassName (rule_install) - ) - :compound () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :services ( - :AdminInfo ( - :chkpf_uid ("{8F76A99B-E1AD-4595-B528-588D82877DDE}") - :ClassName (rule_services) - ) - :compound () - :op () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :src ( - :AdminInfo ( - :chkpf_uid ("{E356D6BD-676A-4587-90E7-C31B293579C1}") - :ClassName (rule_source) - ) - :compound () - :op () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :state (expanded) - ) - :rule ( - :AdminInfo ( - :chkpf_uid ("{9BC6A630-0169-4289-962F-8E65E0503D01}") - :ClassName (security_rule) - ) - :action ( - : (Encrypt - :AdminInfo ( - :chkpf_uid ("{0B19DE28-8BEC-4290-812D-9B5D4289D12D}") - :ClassName (encrypt) - :table (setup) - ) - :action (accept) - :datam () - :diagnostics-track (CryptLog - :AdminInfo ( - :chkpf_uid ("{4302BEE6-7E9D-46BE-A30A-7D5F42B951D0}") - :ClassName (account) - :table (tracks) - ) - :Name () - :color ("Navy Blue") - :format (crypt) - :icon-name () - :macro () - :type (account) - ) - :gateway (ReferenceObject - :Table (globals) - :Name (Any) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - :isakmp.compression (None) - :isakmp.crlreq (false) - :isakmp.data.integrity (MD5) - :isakmp.encryption (3DES) - :isakmp.gateway (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - :isakmp.phase2_DH_group (ReferenceObject - :Name ("Group 2 (1024 bit)") - :Table (encryption) - :Uid ("{97AEB629-9AEA-11D5-BD16-0090272CCB30}") - ) - :isakmp.transform (ESP) - :isakmp.use_pfs (false) - :isakmp.useippools (false) - :keym () - :macro (ENCRYPTION) - :mdm (MD5) - :menu_inactive (false) - :scheme (ISAKMP) - :type (encrypt) - ) - ) - :comments () - :global_location (middle) - :through ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :time ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :track ( - : (ReferenceObject - :Name (Log) - :Table (tracks) - :Uid ("{97AEB480-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :disabled (true) - :dst ( - :AdminInfo ( - :chkpf_uid ("{83858D79-EC2C-4812-9B9B-2346DFC72654}") - :ClassName (rule_destination) - ) - :compound () - :op () - : (ReferenceObject - :Name (IsoAAAA-100) - :Table (network_objects) - :Uid ("{BF1C6029-8D5D-4A05-A3AD-4B67E6E7A7AA}") - ) - ) - :install ( - :AdminInfo ( - :chkpf_uid ("{50CB20E0-39A1-42D5-9495-BA814B304829}") - :ClassName (rule_install) - ) - :compound () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :services ( - :AdminInfo ( - :chkpf_uid ("{938E9BAA-A4E0-42DE-B985-4FC332A0008A}") - :ClassName (rule_services) - ) - :compound () - :op () - : (ReferenceObject - :Name (icmp-requests) - :Table (services) - :Uid ("{97AEB413-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :src ( - :AdminInfo ( - :chkpf_uid ("{288657B3-E155-44B2-9023-5BDBB46EF52F}") - :ClassName (rule_source) - ) - :compound () - :op () - : (ReferenceObject - :Name (IsoAAAA_home_tim) - :Table (network_objects) - :Uid ("{BF8F69B9-87C2-464A-9404-239AE8DF66B3}") - ) - ) - ) - :rule ( - :AdminInfo ( - :chkpf_uid ("{1B421F3A-CCFB-4816-B5D0-2D69F5D98DC3}") - :ClassName (security_rule) - ) - :action ( - : (Encrypt - :AdminInfo ( - :chkpf_uid ("{7B2AB0CD-8E90-4AED-B40D-57919CC85E3E}") - :ClassName (encrypt) - :table (setup) - ) - :action (accept) - :datam () - :diagnostics-track (CryptLog - :AdminInfo ( - :chkpf_uid ("{88330614-2043-4829-BE4E-9849E3E56931}") - :ClassName (account) - :table (tracks) - ) - :Name () - :color ("Navy Blue") - :format (crypt) - :icon-name () - :macro () - :type (account) - ) - :gateway (ReferenceObject - :Table (globals) - :Name (Any) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - :isakmp.compression (None) - :isakmp.crlreq (false) - :isakmp.data.integrity (MD5) - :isakmp.encryption (3DES) - :isakmp.gateway (ReferenceObject - :Name (IsoAAAD) - :Table (network_objects) - :Uid ("{29C40B0A-414C-11D7-AEB8-7F0000013C3C}") - ) - :isakmp.phase2_DH_group (ReferenceObject - :Table (encryption) - :Name ("Group 2 (1024 bit)") - :Uid ("{97AEB629-9AEA-11D5-BD16-0090272CCB30}") - ) - :isakmp.transform (ESP) - :isakmp.use_pfs (false) - :isakmp.useippools (false) - :keym () - :macro (ENCRYPTION) - :mdm (MD5) - :menu_inactive (false) - :scheme (ISAKMP) - :type (encrypt) - ) - ) - :comments () - :disabled (false) - :global_location (middle) - :through ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :time ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :track ( - : (ReferenceObject - :Name (Log) - :Table (tracks) - :Uid ("{97AEB480-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :dst ( - :AdminInfo ( - :chkpf_uid ("{2E07BEF2-A8D2-420C-B73A-97F71499CF78}") - :ClassName (rule_destination) - ) - :compound () - :op () - : (ReferenceObject - :Name (IsoAAAA-100) - :Table (network_objects) - :Uid ("{BF1C6029-8D5D-4A05-A3AD-4B67E6E7A7AA}") - ) - ) - :install ( - :AdminInfo ( - :chkpf_uid ("{E4654732-4C19-4B16-B48E-9045187B0E7D}") - :ClassName (rule_install) - ) - :compound () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :services ( - :AdminInfo ( - :chkpf_uid ("{56D6CE5A-FD31-4622-BCD4-14B2B79E9831}") - :ClassName (rule_services) - ) - :compound () - :op () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :src ( - :AdminInfo ( - :chkpf_uid ("{C698A8A9-97D7-477E-98FA-1A67C583F157}") - :ClassName (rule_source) - ) - :compound () - :op () - : (ReferenceObject - :Name (SonicLAN) - :Table (network_objects) - :Uid ("{587A029D-04EA-49A0-9DB2-93ADC651B7BF}") - ) - ) - ) - :rule ( - :AdminInfo ( - :chkpf_uid ("{7F7BEC1D-4972-4E6B-9F74-2808D5D82A44}") - :ClassName (security_rule) - ) - :action ( - : (Encrypt - :AdminInfo ( - :chkpf_uid ("{DE69F779-E476-4D83-A45D-01E7AE697727}") - :ClassName (encrypt) - :table (setup) - ) - :action (accept) - :datam () - :diagnostics-track (CryptLog - :AdminInfo ( - :chkpf_uid ("{7B3D6F79-64C4-4E84-B374-D3F4FF4F6646}") - :ClassName (account) - :table (tracks) - ) - :Name () - :color ("Navy Blue") - :format (crypt) - :icon-name () - :macro () - :type (account) - ) - :gateway (ReferenceObject - :Table (globals) - :Name (Any) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - :isakmp.compression (None) - :isakmp.crlreq (false) - :isakmp.data.integrity (MD5) - :isakmp.encryption (3DES) - :isakmp.gateway (ReferenceObject - :Name (Sonic1) - :Table (network_objects) - :Uid ("{B2EBD57B-C94C-42E7-8F1A-17C861697403}") - ) - :isakmp.phase2_DH_group (ReferenceObject - :Table (encryption) - :Name ("Group 2 (1024 bit)") - :Uid ("{97AEB629-9AEA-11D5-BD16-0090272CCB30}") - ) - :isakmp.transform (ESP) - :isakmp.use_pfs (false) - :isakmp.useippools (false) - :keym () - :macro (ENCRYPTION) - :mdm (MD5) - :menu_inactive (false) - :scheme (ISAKMP) - :type (encrypt) - ) - ) - :comments () - :disabled (false) - :global_location (middle) - :through ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :time ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :track ( - : (ReferenceObject - :Name (Log) - :Table (tracks) - :Uid ("{97AEB480-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :dst ( - :AdminInfo ( - :chkpf_uid ("{B08B1D30-7A98-4EB1-A10F-8A5EA4E5751D}") - :ClassName (rule_destination) - ) - :compound () - :op () - : (ReferenceObject - :Name (SonicLAN) - :Table (network_objects) - :Uid ("{587A029D-04EA-49A0-9DB2-93ADC651B7BF}") - ) - : (ReferenceObject - :Name (Sonic1) - :Table (network_objects) - :Uid ("{B2EBD57B-C94C-42E7-8F1A-17C861697403}") - ) - ) - :install ( - :AdminInfo ( - :chkpf_uid ("{A4D22342-EAE3-42F9-96A9-AA42177E4662}") - :ClassName (rule_install) - ) - :compound () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :services ( - :AdminInfo ( - :chkpf_uid ("{4171D4D8-3AEE-4503-889B-2F2BB38E7E6B}") - :ClassName (rule_services) - ) - :compound () - :op () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :src ( - :AdminInfo ( - :chkpf_uid ("{2E872EC3-8CCF-4263-92F7-5C0DFCF66ED7}") - :ClassName (rule_source) - ) - :compound () - :op () - : (ReferenceObject - :Name (IsoAAAA-100) - :Table (network_objects) - :Uid ("{BF1C6029-8D5D-4A05-A3AD-4B67E6E7A7AA}") - ) - ) - ) - :rule ( - :AdminInfo ( - :chkpf_uid ("{7D822D25-45D2-4906-8C8E-72652A4E9C7C}") - :ClassName (security_header_rule) - ) - :action ( - : (drop - :AdminInfo ( - :chkpf_uid ("{8AEAF6EF-1859-4E89-A58F-4F275BF154AA}") - :ClassName (drop_action) - :table (setup) - ) - :action () - :macro () - :type (drop) - ) - ) - :comments () - :global_location (middle) - :through ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :time ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :track ( - : (ReferenceObject - :Name (None) - :Table (tracks) - :Uid ("{97AEB47D-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :disabled (true) - :dst ( - :AdminInfo ( - :chkpf_uid ("{08B3D275-0F89-4C3F-B53E-1E3ECA583C23}") - :ClassName (rule_destination) - ) - :compound () - :op () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :header_text (Internal-Connections) - :install ( - :AdminInfo ( - :chkpf_uid ("{CA6C0AAF-DBCE-4020-B529-4E4449A1EFAA}") - :ClassName (rule_install) - ) - :compound () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :services ( - :AdminInfo ( - :chkpf_uid ("{6FB76A7B-3073-434B-ADDA-81C99060AEBA}") - :ClassName (rule_services) - ) - :compound () - :op () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :src ( - :AdminInfo ( - :chkpf_uid ("{79B42650-50CC-4AD9-A13E-A0E4AB4D7383}") - :ClassName (rule_source) - ) - :compound () - :op () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :state (expanded) - ) - :rule ( - :AdminInfo ( - :chkpf_uid ("{EACACDFF-02E7-4014-9DA7-1A5487AB8481}") - :ClassName (security_rule) - ) - :action ( - : (accept - :AdminInfo ( - :chkpf_uid ("{87CA79FF-466D-4BCF-B6C4-42FE6346885F}") - :ClassName (accept_action) - :table (setup) - ) - :action () - :macro (RECORD_CONN) - :type (accept) - ) - ) - :comments () - :disabled (false) - :global_location (middle) - :through ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :time ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :track ( - : (ReferenceObject - :Name (Log) - :Table (tracks) - :Uid ("{97AEB480-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :dst ( - :AdminInfo ( - :chkpf_uid ("{38233DD1-F39A-42F7-80B7-74A2F3C959BE}") - :ClassName (rule_destination) - ) - :compound () - :op () - : (ReferenceObject - :Name (IsoAAAD) - :Table (network_objects) - :Uid ("{29C40B0A-414C-11D7-AEB8-7F0000013C3C}") - ) - ) - :install ( - :AdminInfo ( - :chkpf_uid ("{D4207D0B-4AA6-4438-A102-EAF2E08BCABC}") - :ClassName (rule_install) - ) - :compound () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :services ( - :AdminInfo ( - :chkpf_uid ("{0D51549F-279B-4544-97E7-672C85874699}") - :ClassName (rule_services) - ) - :compound () - :op () - : (ReferenceObject - :Name (ssh) - :Table (services) - :Uid ("{18EC9EAA-1657-4240-AB97-5F234623336B}") - ) - : (ReferenceObject - :Name (https) - :Table (services) - :Uid ("{97AEB443-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :src ( - :AdminInfo ( - :chkpf_uid ("{C0F53557-6630-4779-8F85-30AA74C8BB3F}") - :ClassName (rule_source) - ) - :compound () - :op () - : (ReferenceObject - :Name (IsoAAAA-100) - :Table (network_objects) - :Uid ("{BF1C6029-8D5D-4A05-A3AD-4B67E6E7A7AA}") - ) - : (ReferenceObject - :Name (IsoAAAA_home_tim) - :Table (network_objects) - :Uid ("{BF8F69B9-87C2-464A-9404-239AE8DF66B3}") - ) - : (ReferenceObject - :Name (mg.IsoAAAA-es.com) - :Table (network_objects) - :Uid ("{E5BF8260-3615-4476-B638-53CA3A24FEF1}") - ) - ) - ) - :rule ( - :AdminInfo ( - :chkpf_uid ("{C5F973E3-CBB2-4C15-A735-52B51AC9DAE7}") - :ClassName (security_rule) - ) - :action ( - : (accept - :AdminInfo ( - :chkpf_uid ("{396BFDCC-A290-408E-9F92-791EA8CF3616}") - :ClassName (accept_action) - :table (setup) - ) - :action () - :macro (RECORD_CONN) - :type (accept) - ) - ) - :comments () - :disabled (false) - :global_location (middle) - :through ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :time ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :track ( - : (ReferenceObject - :Name (Log) - :Table (tracks) - :Uid ("{97AEB480-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :dst ( - :AdminInfo ( - :chkpf_uid ("{389DDDD2-29F4-4D0F-A969-726529DF0919}") - :ClassName (rule_destination) - ) - :compound () - :op () - : (ReferenceObject - :Name (daba) - :Table (network_objects) - :Uid ("{94817CDB-EA8C-4213-B38D-F4417EA620C6}") - ) - ) - :install ( - :AdminInfo ( - :chkpf_uid ("{D76410C0-68C5-40EA-A75A-9FFB9B0EF2E8}") - :ClassName (rule_install) - ) - :compound () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :services ( - :AdminInfo ( - :chkpf_uid ("{FCA57859-3422-4495-954F-E7D746378008}") - :ClassName (rule_services) - ) - :compound () - :op () - : (ReferenceObject - :Name (ssh) - :Table (services) - :Uid ("{18EC9EAA-1657-4240-AB97-5F234623336B}") - ) - : (ReferenceObject - :Name (mysql) - :Table (services) - :Uid ("{08A07607-EAAA-4A45-AD6E-6020770BD519}") - ) - ) - :src ( - :AdminInfo ( - :chkpf_uid ("{B98DA2C1-079F-4EF2-A67D-5FCEC98B1FE8}") - :ClassName (rule_source) - ) - :compound () - :op () - : (ReferenceObject - :Name (IsoAAAA-100) - :Table (network_objects) - :Uid ("{BF1C6029-8D5D-4A05-A3AD-4B67E6E7A7AA}") - ) - : (ReferenceObject - :Name (IsoAAAA_home_tim) - :Table (network_objects) - :Uid ("{BF8F69B9-87C2-464A-9404-239AE8DF66B3}") - ) - ) - ) - :rule ( - :AdminInfo ( - :chkpf_uid ("{0D4D75A0-8203-453F-9C3E-F68E1995DE88}") - :ClassName (security_rule) - ) - :action ( - : (accept - :AdminInfo ( - :chkpf_uid ("{317B8552-195E-4E2A-8EA7-CEE52B732C38}") - :ClassName (accept_action) - :table (setup) - ) - :action () - :macro (RECORD_CONN) - :type (accept) - ) - ) - :comments () - :disabled (false) - :global_location (middle) - :through ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :time ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :track ( - : (ReferenceObject - :Name (None) - :Table (tracks) - :Uid ("{97AEB47D-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :dst ( - :AdminInfo ( - :chkpf_uid ("{C80F45A6-E7AD-4F87-89A8-31CC7D5A5E53}") - :ClassName (rule_destination) - ) - :compound () - :op () - : (ReferenceObject - :Name (wasp) - :Table (network_objects) - :Uid ("{098B2A74-E220-4AE8-A164-340FED79C9D5}") - ) - : (ReferenceObject - :Name (mg.IsoAAAA-es.com) - :Table (network_objects) - :Uid ("{E5BF8260-3615-4476-B638-53CA3A24FEF1}") - ) - ) - :install ( - :AdminInfo ( - :chkpf_uid ("{9D97B55B-160C-46D2-ADFA-6D235D7D9733}") - :ClassName (rule_install) - ) - :compound () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :services ( - :AdminInfo ( - :chkpf_uid ("{8305714C-A6BA-4B6C-A1A9-2E54349BB3ED}") - :ClassName (rule_services) - ) - :compound () - :op () - : (ReferenceObject - :Name (ntp-udp) - :Table (services) - :Uid ("{97AEB404-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :src ( - :AdminInfo ( - :chkpf_uid ("{398C5E6F-5E01-4646-ABAB-BF775B461AE6}") - :ClassName (rule_source) - ) - :compound () - :op () - : (ReferenceObject - :Name (IsoAAAD) - :Table (network_objects) - :Uid ("{29C40B0A-414C-11D7-AEB8-7F0000013C3C}") - ) - ) - ) - :rule ( - :AdminInfo ( - :chkpf_uid ("{A1ACBE88-9F38-4947-B497-B34A2F3878B3}") - :ClassName (security_rule) - ) - :action ( - : (accept - :AdminInfo ( - :chkpf_uid ("{F8FE4FD5-50BE-4D6E-93FE-93071473FFF0}") - :ClassName (accept_action) - :table (setup) - ) - :action () - :macro (RECORD_CONN) - :type (accept) - ) - ) - :comments () - :disabled (false) - :global_location (middle) - :through ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :time ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :track ( - : (ReferenceObject - :Name (None) - :Table (tracks) - :Uid ("{97AEB47D-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :dst ( - :AdminInfo ( - :chkpf_uid ("{442DA9A3-9028-4077-88ED-F676CC39EA6A}") - :ClassName (rule_destination) - ) - :compound () - :op () - : (ReferenceObject - :Name (IsoAAADray.local) - :Table (network_objects) - :Uid ("{75EDBC62-7EB1-4D37-8295-684903FDA75A}") - ) - ) - :install ( - :AdminInfo ( - :chkpf_uid ("{22AF536A-CE60-42B9-8D92-B2B84B1B849A}") - :ClassName (rule_install) - ) - :compound () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :services ( - :AdminInfo ( - :chkpf_uid ("{FE031AD5-4408-419D-9CAC-E33FD47B4872}") - :ClassName (rule_services) - ) - :compound () - :op () - : (ReferenceObject - :Name (domain-udp) - :Table (services) - :Uid ("{97AEB3FA-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :src ( - :AdminInfo ( - :chkpf_uid ("{EA42965D-38DF-4E67-8A06-6BF107BEC1BE}") - :ClassName (rule_source) - ) - :compound () - :op () - : (ReferenceObject - :Name (IsoAAAD) - :Table (network_objects) - :Uid ("{29C40B0A-414C-11D7-AEB8-7F0000013C3C}") - ) - ) - ) - :rule ( - :AdminInfo ( - :chkpf_uid ("{321D1155-8DB8-48D3-8F89-789456335EA5}") - :ClassName (security_rule) - ) - :action ( - : (accept - :AdminInfo ( - :chkpf_uid ("{EF61D86E-D8BD-4E00-83C7-D4D6413AA826}") - :ClassName (accept_action) - :table (setup) - ) - :action () - :macro (RECORD_CONN) - :type (accept) - ) - ) - :comments () - :disabled (false) - :global_location (middle) - :through ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :time ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :track ( - : (ReferenceObject - :Name (Log) - :Table (tracks) - :Uid ("{97AEB480-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :dst ( - :AdminInfo ( - :chkpf_uid ("{6ECE3813-9B88-4B95-8F48-35760521161D}") - :ClassName (rule_destination) - ) - :compound () - :op () - : (ReferenceObject - :Name (spike.local) - :Table (network_objects) - :Uid ("{4ABDD8DE-0DA2-46E5-B129-85E3977CBD18}") - ) - : (ReferenceObject - :Name (mg.IsoAAAA-es.com) - :Table (network_objects) - :Uid ("{E5BF8260-3615-4476-B638-53CA3A24FEF1}") - ) - ) - :install ( - :AdminInfo ( - :chkpf_uid ("{B6B3B97E-55C4-41CA-B951-91FBA42AD24D}") - :ClassName (rule_install) - ) - :compound () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :services ( - :AdminInfo ( - :chkpf_uid ("{E4826F35-742D-4BE5-814E-5ECE6741D719}") - :ClassName (rule_services) - ) - :compound () - :op () - : (ReferenceObject - :Name (syslog) - :Table (services) - :Uid ("{97AEB3E0-9AEA-11D5-BD16-0090272CCB30}") - ) - : (ReferenceObject - :Name (ssh_version_2) - :Table (services) - :Uid ("{CD082D9A-44A6-4CEF-A17D-5541029ADFB3}") - ) - : (ReferenceObject - :Name (domain-udp) - :Table (services) - :Uid ("{97AEB3FA-9AEA-11D5-BD16-0090272CCB30}") - ) - : (ReferenceObject - :Name (smtp) - :Table (services) - :Uid ("{97AEB3D9-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :src ( - :AdminInfo ( - :chkpf_uid ("{CBCA552F-5195-4594-8FCD-DB44E1E54E08}") - :ClassName (rule_source) - ) - :compound () - :op () - : (ReferenceObject - :Name (IsoAAAD) - :Table (network_objects) - :Uid ("{29C40B0A-414C-11D7-AEB8-7F0000013C3C}") - ) - ) - ) - :rule ( - :AdminInfo ( - :chkpf_uid ("{479DFC1D-FE51-4CFB-9A99-4FD1A532B7B4}") - :ClassName (security_header_rule) - ) - :action ( - : (drop - :AdminInfo ( - :chkpf_uid ("{575C62B8-634C-4115-9DF5-3C75BBFBFDEE}") - :ClassName (drop_action) - :table (setup) - ) - :action () - :macro () - :type (drop) - ) - ) - :comments () - :global_location (middle) - :through ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :time ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :track ( - : (ReferenceObject - :Name (None) - :Table (tracks) - :Uid ("{97AEB47D-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :disabled (true) - :dst ( - :AdminInfo ( - :chkpf_uid ("{EF6C7FE7-9266-491E-8933-CC4429B97209}") - :ClassName (rule_destination) - ) - :compound () - :op () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :header_text ("Intern to Spike") - :install ( - :AdminInfo ( - :chkpf_uid ("{CA20EBCF-96AC-402F-87BB-25C0EC09879B}") - :ClassName (rule_install) - ) - :compound () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :services ( - :AdminInfo ( - :chkpf_uid ("{5505712A-4BAB-46F8-BFAF-62A682802247}") - :ClassName (rule_services) - ) - :compound () - :op () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :src ( - :AdminInfo ( - :chkpf_uid ("{3B75D561-22D8-4C61-9CA7-A843272AA499}") - :ClassName (rule_source) - ) - :compound () - :op () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :state (collapsed) - ) - :rule ( - :AdminInfo ( - :chkpf_uid ("{F18D892E-EED1-488B-A0D9-832B742CE27B}") - :ClassName (security_rule) - ) - :action ( - : (accept - :AdminInfo ( - :chkpf_uid ("{BD096130-776F-4884-A5E3-66951FEDCAA1}") - :ClassName (accept_action) - :table (setup) - ) - :action () - :macro (RECORD_CONN) - :type (accept) - ) - ) - :comments () - :disabled (false) - :global_location (middle) - :through ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :time ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :track ( - : (ReferenceObject - :Name (Log) - :Table (tracks) - :Uid ("{97AEB480-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :dst ( - :AdminInfo ( - :chkpf_uid ("{69FBBF03-9653-4708-95E4-A3085DA3502E}") - :ClassName (rule_destination) - ) - :compound () - :op () - : (ReferenceObject - :Name (spike.local) - :Table (network_objects) - :Uid ("{4ABDD8DE-0DA2-46E5-B129-85E3977CBD18}") - ) - : (ReferenceObject - :Name (mg.IsoAAAA-es.com) - :Table (network_objects) - :Uid ("{E5BF8260-3615-4476-B638-53CA3A24FEF1}") - ) - : (ReferenceObject - :Name (ras.IsoAAAA-es.com) - :Table (network_objects) - :Uid ("{23B1E779-B8D5-4384-AD60-80E498B77196}") - ) - ) - :install ( - :AdminInfo ( - :chkpf_uid ("{58BE428C-CA30-4DD6-8D0C-DD21E8D5716A}") - :ClassName (rule_install) - ) - :compound () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :services ( - :AdminInfo ( - :chkpf_uid ("{D45CFA85-C7A9-4770-BBA5-38DC95DE2E39}") - :ClassName (rule_services) - ) - :compound () - :op () - : (ReferenceObject - :Name (SpikeServices) - :Table (services) - :Uid ("{9D35FACE-289F-49A6-95C7-13417959BC9D}") - ) - ) - :src ( - :AdminInfo ( - :chkpf_uid ("{CEAC96CA-4B08-4E15-B8E5-F555868B9B9D}") - :ClassName (rule_source) - ) - :compound () - :op () - : (ReferenceObject - :Name (IsoAAAA-100) - :Table (network_objects) - :Uid ("{BF1C6029-8D5D-4A05-A3AD-4B67E6E7A7AA}") - ) - ) - ) - :rule ( - :AdminInfo ( - :chkpf_uid ("{001AA0F0-DFE8-4CAD-9B62-C26E1A5CB9A0}") - :ClassName (security_header_rule) - ) - :action ( - : (drop - :AdminInfo ( - :chkpf_uid ("{339E1791-EB7E-4985-8B54-EBE0E6097CCB}") - :ClassName (drop_action) - :table (setup) - ) - :action () - :macro () - :type (drop) - ) - ) - :comments () - :global_location (middle) - :through ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :time ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :track ( - : (ReferenceObject - :Name (None) - :Table (tracks) - :Uid ("{97AEB47D-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :disabled (true) - :dst ( - :AdminInfo ( - :chkpf_uid ("{A78DD97F-4A53-4494-8F90-EABA9B30D6B5}") - :ClassName (rule_destination) - ) - :compound () - :op () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :header_text ("Intern to DMZ") - :install ( - :AdminInfo ( - :chkpf_uid ("{209BE460-BB82-44DD-817D-FF2E22395B31}") - :ClassName (rule_install) - ) - :compound () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :services ( - :AdminInfo ( - :chkpf_uid ("{E0D91B63-F2A0-4973-B07E-AEDD817454E5}") - :ClassName (rule_services) - ) - :compound () - :op () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :src ( - :AdminInfo ( - :chkpf_uid ("{9BD55163-1255-4D94-BE33-13A5569A02ED}") - :ClassName (rule_source) - ) - :compound () - :op () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :state (expanded) - ) - :rule ( - :AdminInfo ( - :chkpf_uid ("{00477CC9-4940-4C79-B2E6-A137781B1C25}") - :ClassName (security_rule) - ) - :action ( - : (accept - :AdminInfo ( - :chkpf_uid ("{47ACCCC4-3B42-4BE4-8E43-AF61E4E0FB86}") - :ClassName (accept_action) - :table (setup) - ) - :action () - :macro (RECORD_CONN) - :type (accept) - ) - ) - :comments () - :disabled (false) - :global_location (middle) - :through ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :time ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :track ( - : (ReferenceObject - :Name (Log) - :Table (tracks) - :Uid ("{97AEB480-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :dst ( - :AdminInfo ( - :chkpf_uid ("{F16C6F8C-1F05-4B70-87D9-CECE46630C0C}") - :ClassName (rule_destination) - ) - :compound () - :op () - : (ReferenceObject - :Name (Cactus-DMZ1) - :Table (network_objects) - :Uid ("{62523F8E-9AE0-4CC0-82C6-BB41846BA2B7}") - ) - : (ReferenceObject - :Name (Cactus-DMZ2) - :Table (network_objects) - :Uid ("{61AB70E0-5514-43CF-9194-B37A13EC102D}") - ) - : (ReferenceObject - :Name (Cactus-DMZ4) - :Table (network_objects) - :Uid ("{9C2C49CE-5100-423C-BECB-08951751059F}") - ) - ) - :install ( - :AdminInfo ( - :chkpf_uid ("{E18116F6-2DF8-42C8-8F65-D00C902B23AB}") - :ClassName (rule_install) - ) - :compound () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :services ( - :AdminInfo ( - :chkpf_uid ("{FFEF9B1D-B59B-4A07-AEDE-63918094EDB8}") - :ClassName (rule_services) - ) - :compound () - :op () - : (ReferenceObject - :Name (ssh_version_2) - :Table (services) - :Uid ("{CD082D9A-44A6-4CEF-A17D-5541029ADFB3}") - ) - : (ReferenceObject - :Name (sshv2-24) - :Table (services) - :Uid ("{1DA78BCE-7ABC-4DBB-82AF-FDBE6B853493}") - ) - ) - :src ( - :AdminInfo ( - :chkpf_uid ("{2D6919C8-EBF0-46B2-95CE-7FD2AFF8DBF0}") - :ClassName (rule_source) - ) - :compound () - :op () - : (ReferenceObject - :Name (IsoAAAA-100) - :Table (network_objects) - :Uid ("{BF1C6029-8D5D-4A05-A3AD-4B67E6E7A7AA}") - ) - ) - ) - :rule ( - :AdminInfo ( - :chkpf_uid ("{2CDC82FD-6292-45D7-A4B8-6794C378A47B}") - :ClassName (security_rule) - ) - :action ( - : (accept - :AdminInfo ( - :chkpf_uid ("{DBFD040E-D17D-481F-B6E2-D9E5AE306BBD}") - :ClassName (accept_action) - :table (setup) - ) - :action () - :macro (RECORD_CONN) - :type (accept) - ) - ) - :comments () - :disabled (false) - :global_location (middle) - :through ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :time ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :track ( - : (ReferenceObject - :Name (Log) - :Table (tracks) - :Uid ("{97AEB480-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :dst ( - :AdminInfo ( - :chkpf_uid ("{AAADBB03-1A01-4136-8104-91B265E567A3}") - :ClassName (rule_destination) - ) - :compound () - :op () - : (ReferenceObject - :Name (Cactus10.222.0.1) - :Table (network_objects) - :Uid ("{6CD51061-638B-4B2F-9092-7E1E4A5F0ADD}") - ) - ) - :install ( - :AdminInfo ( - :chkpf_uid ("{77D96FA7-8F8F-4F17-9F1C-868F1472C870}") - :ClassName (rule_install) - ) - :compound () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :services ( - :AdminInfo ( - :chkpf_uid ("{A042A0B6-6CD8-4A84-90A5-B39B35590148}") - :ClassName (rule_services) - ) - :compound () - :op () - : (ReferenceObject - :Name (VNC) - :Table (services) - :Uid ("{9788B566-735E-4158-A169-8701B9624E47}") - ) - ) - :src ( - :AdminInfo ( - :chkpf_uid ("{2F62C069-51CA-424D-A3EB-235DD9728611}") - :ClassName (rule_source) - ) - :compound () - :op () - : (ReferenceObject - :Name (IsoAAAA-100) - :Table (network_objects) - :Uid ("{BF1C6029-8D5D-4A05-A3AD-4B67E6E7A7AA}") - ) - ) - ) - :rule ( - :AdminInfo ( - :chkpf_uid ("{8EDEBE48-F02B-4AEA-8337-FBE1E2079BE0}") - :ClassName (security_rule) - ) - :action ( - : (accept - :AdminInfo ( - :chkpf_uid ("{47CF3B75-BE35-45E1-B56E-B8A61ECE885B}") - :ClassName (accept_action) - :table (setup) - ) - :action () - :macro (RECORD_CONN) - :type (accept) - ) - ) - :comments () - :disabled (false) - :global_location (middle) - :through ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :time ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :track ( - : (ReferenceObject - :Name (Log) - :Table (tracks) - :Uid ("{97AEB480-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :dst ( - :AdminInfo ( - :chkpf_uid ("{7149B69F-E170-4FCC-B958-76AE0F704EA0}") - :ClassName (rule_destination) - ) - :compound () - :op () - : (ReferenceObject - :Name (itchy) - :Table (network_objects) - :Uid ("{3B4DF852-5064-4957-B95F-D469C5656467}") - ) - ) - :install ( - :AdminInfo ( - :chkpf_uid ("{50C640DC-6413-458C-BD30-9E947F408315}") - :ClassName (rule_install) - ) - :compound () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :services ( - :AdminInfo ( - :chkpf_uid ("{3F4AF5D6-72D0-4C52-A1BD-29AB242927D0}") - :ClassName (rule_services) - ) - :compound () - :op () - : (ReferenceObject - :Name (domain-udp) - :Table (services) - :Uid ("{97AEB3FA-9AEA-11D5-BD16-0090272CCB30}") - ) - : (ReferenceObject - :Name (CIFS) - :Table (services) - :Uid ("{2A469820-B502-434C-9340-A377677A6A60}") - ) - ) - :src ( - :AdminInfo ( - :chkpf_uid ("{EA36998F-4F7C-4250-BECC-4CEBB36E9EAE}") - :ClassName (rule_source) - ) - :compound () - :op () - : (ReferenceObject - :Name (IsoAAAA-100) - :Table (network_objects) - :Uid ("{BF1C6029-8D5D-4A05-A3AD-4B67E6E7A7AA}") - ) - ) - ) - :rule ( - :AdminInfo ( - :chkpf_uid ("{0F6D252E-7562-457F-81A3-60192F3EC815}") - :ClassName (security_rule) - ) - :action ( - : (accept - :AdminInfo ( - :chkpf_uid ("{0CEE5A08-F53C-439A-8180-A62450938BA6}") - :ClassName (accept_action) - :table (setup) - ) - :action () - :macro (RECORD_CONN) - :type (accept) - ) - ) - :comments () - :disabled (false) - :global_location (middle) - :through ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :time ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :track ( - : (ReferenceObject - :Name (Log) - :Table (tracks) - :Uid ("{97AEB480-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :dst ( - :AdminInfo ( - :chkpf_uid ("{C414C09F-B8D2-4DD6-8DD1-B5044B787753}") - :ClassName (rule_destination) - ) - :compound () - :op () - : (ReferenceObject - :Name (MailServer) - :Table (network_objects) - :Uid ("{17935795-6ADC-4B45-8E2B-BEC361E6CAB1}") - ) - ) - :install ( - :AdminInfo ( - :chkpf_uid ("{1ADD0F50-D00E-463E-AF4B-5F7B9602F8FB}") - :ClassName (rule_install) - ) - :compound () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :services ( - :AdminInfo ( - :chkpf_uid ("{F89128E4-058B-45CC-8BE9-62261DDB22A0}") - :ClassName (rule_services) - ) - :compound () - :op () - : (ReferenceObject - :Name (smtp) - :Table (services) - :Uid ("{97AEB3D9-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :src ( - :AdminInfo ( - :chkpf_uid ("{1265804A-4F79-416E-ABDC-2BC3BC6E9513}") - :ClassName (rule_source) - ) - :compound () - :op () - : (ReferenceObject - :Name (IsoAAAA-100) - :Table (network_objects) - :Uid ("{BF1C6029-8D5D-4A05-A3AD-4B67E6E7A7AA}") - ) - ) - ) - :rule ( - :AdminInfo ( - :chkpf_uid ("{A3B9D85B-AD6D-4991-8A9D-960939C491C2}") - :ClassName (security_rule) - ) - :action ( - : (accept - :AdminInfo ( - :chkpf_uid ("{C8749F14-4AE2-4544-B239-7CC349656359}") - :ClassName (accept_action) - :table (setup) - ) - :action () - :macro (RECORD_CONN) - :type (accept) - ) - ) - :comments () - :disabled (false) - :global_location (middle) - :through ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :time ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :track ( - : (ReferenceObject - :Name (None) - :Table (tracks) - :Uid ("{97AEB47D-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :dst ( - :AdminInfo ( - :chkpf_uid ("{A7BD46F5-7D1D-424F-BBB4-CCE8564D68C7}") - :ClassName (rule_destination) - ) - :compound () - :op () - : (ReferenceObject - :Name (wasp) - :Table (network_objects) - :Uid ("{098B2A74-E220-4AE8-A164-340FED79C9D5}") - ) - : (ReferenceObject - :Name (mg.IsoAAAA-es.com) - :Table (network_objects) - :Uid ("{E5BF8260-3615-4476-B638-53CA3A24FEF1}") - ) - ) - :install ( - :AdminInfo ( - :chkpf_uid ("{E6AF42B5-C12E-4E59-8C3E-5D231C5B0D34}") - :ClassName (rule_install) - ) - :compound () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :services ( - :AdminInfo ( - :chkpf_uid ("{A22EE9B9-C603-4998-B273-1568DE4BB27A}") - :ClassName (rule_services) - ) - :compound () - :op () - : (ReferenceObject - :Name (ntp-udp) - :Table (services) - :Uid ("{97AEB404-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :src ( - :AdminInfo ( - :chkpf_uid ("{D0402416-F879-4AD4-88E6-A1DBFEA44546}") - :ClassName (rule_source) - ) - :compound () - :op () - : (ReferenceObject - :Name (IsoAAAA-100) - :Table (network_objects) - :Uid ("{BF1C6029-8D5D-4A05-A3AD-4B67E6E7A7AA}") - ) - ) - ) - :rule ( - :AdminInfo ( - :chkpf_uid ("{7C9A68ED-6420-4D5E-BE91-F7ACE4B90AA5}") - :ClassName (security_header_rule) - ) - :action ( - : (drop - :AdminInfo ( - :chkpf_uid ("{D4BF36D5-49FA-49BD-ADE1-87E488A684D6}") - :ClassName (drop_action) - :table (setup) - ) - :action () - :macro () - :type (drop) - ) - ) - :comments () - :global_location (middle) - :through ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :time ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :track ( - : (ReferenceObject - :Name (None) - :Table (tracks) - :Uid ("{97AEB47D-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :disabled (true) - :dst ( - :AdminInfo ( - :chkpf_uid ("{251B6C16-21CB-4CCE-9B3B-62B66C6F6390}") - :ClassName (rule_destination) - ) - :compound () - :op () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :header_text ("Intern to Internet") - :install ( - :AdminInfo ( - :chkpf_uid ("{A9221EAB-A00F-4E3F-83DF-D44CBC08AFBD}") - :ClassName (rule_install) - ) - :compound () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :services ( - :AdminInfo ( - :chkpf_uid ("{AECCDBA3-A006-464E-9BD9-691255CA5841}") - :ClassName (rule_services) - ) - :compound () - :op () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :src ( - :AdminInfo ( - :chkpf_uid ("{5B2CFCAD-0A44-4BA9-BFF7-6734B5644C85}") - :ClassName (rule_source) - ) - :compound () - :op () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :state (collapsed) - ) - :rule ( - :AdminInfo ( - :chkpf_uid ("{E6AB0ADC-7E23-4B1D-B568-E47FF7B3D4F5}") - :ClassName (security_rule) - ) - :action ( - : (accept - :AdminInfo ( - :chkpf_uid ("{5B685C0A-3095-483A-8DE1-F539677A7707}") - :ClassName (accept_action) - :table (setup) - ) - :action () - :macro (RECORD_CONN) - :type (accept) - ) - ) - :comments () - :disabled (false) - :global_location (middle) - :through ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :time ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :track ( - : (ReferenceObject - :Name (Log) - :Table (tracks) - :Uid ("{97AEB480-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :dst ( - :AdminInfo ( - :chkpf_uid ("{2C9F2F69-7532-4711-A950-C884E1AFD3F5}") - :ClassName (rule_destination) - ) - :compound () - :op () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :install ( - :AdminInfo ( - :chkpf_uid ("{EACA5120-76C3-48CE-AB41-59266A354E0A}") - :ClassName (rule_install) - ) - :compound () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :services ( - :AdminInfo ( - :chkpf_uid ("{DB45ABD4-20F0-4BC8-BD73-294945142FB8}") - :ClassName (rule_services) - ) - :compound () - :op () - : (ReferenceObject - :Name (T-online-classic) - :Table (services) - :Uid ("{738B04E5-09F7-44BF-9FEC-AEA0F15B7E9A}") - ) - : (ReferenceObject - :Name (HBCI) - :Table (services) - :Uid ("{336C93F8-5CC2-48BE-9328-2E92F61EFCF1}") - ) - ) - :src ( - :AdminInfo ( - :chkpf_uid ("{85CAFABE-730E-4DDB-A878-219BD2893B63}") - :ClassName (rule_source) - ) - :compound () - :op () - : (ReferenceObject - :Name (IsoAAAA-100) - :Table (network_objects) - :Uid ("{BF1C6029-8D5D-4A05-A3AD-4B67E6E7A7AA}") - ) - ) - ) - :rule ( - :AdminInfo ( - :chkpf_uid ("{F2D50B88-90A6-4BF1-A0F9-724F4FF20600}") - :ClassName (security_rule) - ) - :action ( - : ("Client Auth" - :AdminInfo ( - :chkpf_uid ("{E7112614-F673-492F-B41A-FA577FB7E844}") - :ClassName (client_authenticate) - :table (setup) - ) - :accept_track (ReferenceObject - :Name (Auth) - :Table (tracks) - :Uid ("{97AEB48A-9AEA-11D5-BD16-0090272CCB30}") - ) - :action (accept) - :clauth_refreshable (false) - :clauth_to_hours (6) - :clauth_to_infinite (false) - :clauth_to_minutes (30) - :clauth_track (ReferenceObject - :Table (tracks) - :Name (Auth) - :Uid ("{97AEB48A-9AEA-11D5-BD16-0090272CCB30}") - ) - :dst_options ("ignore user database") - :enforce_desktop_config (false) - :macro (PASS_CLNTAUTH) - :ruletype ("standard sign on") - :sessions (5) - :sessions_infinite (true) - :signon_method ("manual sign-on") - :src_options ("intersect with user database") - :type (auth_client) - ) - ) - :comments () - :disabled (false) - :global_location (middle) - :through ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :time ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :track ( - : (ReferenceObject - :Name (Log) - :Table (tracks) - :Uid ("{97AEB480-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :dst ( - :AdminInfo ( - :chkpf_uid ("{D9DB10FC-4DA0-4922-B0B0-5F8C87FE0135}") - :ClassName (rule_destination) - ) - :compound () - :op () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :install ( - :AdminInfo ( - :chkpf_uid ("{62EE86DF-01FC-4628-8A25-70D69D61F7A9}") - :ClassName (rule_install) - ) - :compound () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :services ( - :AdminInfo ( - :chkpf_uid ("{4C8E3C25-1695-4552-858C-90BA25E860CC}") - :ClassName (rule_services) - ) - :compound () - :op () - : (ReferenceObject - :Name (ssh_version_2) - :Table (services) - :Uid ("{CD082D9A-44A6-4CEF-A17D-5541029ADFB3}") - ) - : (ReferenceObject - :Name (TeamSpeak) - :Table (services) - :Uid ("{D2BBEFB3-8450-4301-9040-2D305887A748}") - ) - ) - :src ( - :AdminInfo ( - :chkpf_uid ("{7049EFF1-4FF7-42B0-B5EE-8F44579C07CB}") - :ClassName (rule_source) - ) - :compound ( - : (Cactus-extern@IsoAAAA-100 - :AdminInfo ( - :chkpf_uid ("{A376F981-E37A-4611-B925-1A141DC89FD8}") - :ClassName (rule_user_group) - ) - :at (ReferenceObject - :Name (IsoAAAA-100) - :Table (network_objects) - :Uid ("{BF1C6029-8D5D-4A05-A3AD-4B67E6E7A7AA}") - ) - :color (black) - :type (usrgroup) - ) - ) - :op () - ) - ) - :rule ( - :AdminInfo ( - :chkpf_uid ("{1F4E5C97-C290-48AF-84A5-C1A13178FDB7}") - :ClassName (security_rule) - ) - :action ( - : (accept - :AdminInfo ( - :chkpf_uid ("{DCDCFD96-219D-49B7-B817-8BB52C598AB8}") - :ClassName (accept_action) - :table (setup) - ) - :action () - :macro (RECORD_CONN) - :type (accept) - ) - ) - :comments () - :disabled (false) - :global_location (middle) - :through ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :time ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :track ( - : (ReferenceObject - :Name (Log) - :Table (tracks) - :Uid ("{97AEB480-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :dst ( - :AdminInfo ( - :chkpf_uid ("{3A1A50EC-0F20-4C79-80D7-FDCBEDAF50AF}") - :ClassName (rule_destination) - ) - :compound () - :op () - : (ReferenceObject - :Name (t-onlineUpdate) - :Table (network_objects) - :Uid ("{99089D97-0EB3-4CE6-8C78-79BC61ECE307}") - ) - ) - :install ( - :AdminInfo ( - :chkpf_uid ("{4D0B21D7-8DA0-49D5-9AD2-3F7BBA001C56}") - :ClassName (rule_install) - ) - :compound () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :services ( - :AdminInfo ( - :chkpf_uid ("{0C60636A-9D3B-44D2-9742-966C92ED77A2}") - :ClassName (rule_services) - ) - :compound () - :op () - : (ReferenceObject - :Name (http) - :Table (services) - :Uid ("{97AEB3D4-9AEA-11D5-BD16-0090272CCB30}") - ) - : (ReferenceObject - :Name (https) - :Table (services) - :Uid ("{97AEB443-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :src ( - :AdminInfo ( - :chkpf_uid ("{C9F5FA9C-6AE5-4A04-B68F-E3CFBE3C1043}") - :ClassName (rule_source) - ) - :compound () - :op () - : (ReferenceObject - :Name (IsoAAAA-100) - :Table (network_objects) - :Uid ("{BF1C6029-8D5D-4A05-A3AD-4B67E6E7A7AA}") - ) - ) - ) - :rule ( - :AdminInfo ( - :chkpf_uid ("{8D43F752-841E-4B9E-B610-635F7C17D4D9}") - :ClassName (security_rule) - ) - :action ( - : (accept - :AdminInfo ( - :chkpf_uid ("{7A10F249-7751-407A-A390-A6B878A85D56}") - :ClassName (accept_action) - :table (setup) - ) - :action () - :macro (RECORD_CONN) - :type (accept) - ) - ) - :comments () - :disabled (false) - :global_location (middle) - :through ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :time ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :track ( - : (ReferenceObject - :Name (Log) - :Table (tracks) - :Uid ("{97AEB480-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :dst ( - :AdminInfo ( - :chkpf_uid ("{B42E38C5-299A-4B0E-A7BE-6D87D1206A3C}") - :ClassName (rule_destination) - ) - :compound () - :op () - : (ReferenceObject - :Name (auth1.lhsystems.com) - :Table (network_objects) - :Uid ("{D60E902E-4BE8-43E0-95DC-BFE60E86965F}") - ) - : (ReferenceObject - :Name (LSYI-pptp) - :Table (network_objects) - :Uid ("{DF2F1A45-9938-4006-A550-0421F3DAA3E2}") - ) - ) - :install ( - :AdminInfo ( - :chkpf_uid ("{42DAAE37-A625-47E5-AC05-72E3E3A9F3FE}") - :ClassName (rule_install) - ) - :compound () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :services ( - :AdminInfo ( - :chkpf_uid ("{F8D3DE95-02BB-43E8-B759-01E5AE00233C}") - :ClassName (rule_services) - ) - :compound () - :op () - : (ReferenceObject - :Name (FW1_clntauth_telnet) - :Table (services) - :Uid ("{97AEB38B-9AEA-11D5-BD16-0090272CCB30}") - ) - : (ReferenceObject - :Name (PPTP) - :Table (services) - :Uid ("{97AEB426-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :src ( - :AdminInfo ( - :chkpf_uid ("{B2C3E31C-B79E-49A9-B7A8-2F38E3C21DCF}") - :ClassName (rule_source) - ) - :compound () - :op () - : (ReferenceObject - :Name (IsoAAAA-100) - :Table (network_objects) - :Uid ("{BF1C6029-8D5D-4A05-A3AD-4B67E6E7A7AA}") - ) - ) - ) - :rule ( - :AdminInfo ( - :chkpf_uid ("{167BC623-43EB-405D-BC29-442298C96DC9}") - :ClassName (security_rule) - ) - :action ( - : (accept - :AdminInfo ( - :chkpf_uid ("{BB10481F-21F5-4244-A6BB-29318E780DF1}") - :ClassName (accept_action) - :table (setup) - ) - :action () - :macro (RECORD_CONN) - :type (accept) - ) - ) - :comments () - :disabled (false) - :global_location (middle) - :through ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :time ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :track ( - : (ReferenceObject - :Name (Log) - :Table (tracks) - :Uid ("{97AEB480-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :dst ( - :AdminInfo ( - :chkpf_uid ("{E9BE5C8E-9CAE-4D88-9235-F5AC9030CF0F}") - :ClassName (rule_destination) - ) - :compound () - :op () - : (ReferenceObject - :Name (mail.light-life.netOld) - :Table (network_objects) - :Uid ("{DF004F13-7986-4569-811C-6EC7391A8764}") - ) - : (ReferenceObject - :Name (mail.light-life.net) - :Table (network_objects) - :Uid ("{C534904C-317E-431D-BF6C-03977CC08203}") - ) - ) - :install ( - :AdminInfo ( - :chkpf_uid ("{CDBC19FF-C00F-4304-9D1D-B5BBDAA5D15A}") - :ClassName (rule_install) - ) - :compound () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :services ( - :AdminInfo ( - :chkpf_uid ("{4BE203D0-3DE8-44FE-B942-E5E26C62E861}") - :ClassName (rule_services) - ) - :compound () - :op () - : (ReferenceObject - :Name (smtp) - :Table (services) - :Uid ("{97AEB3D9-9AEA-11D5-BD16-0090272CCB30}") - ) - : (ReferenceObject - :Name (pop-3) - :Table (services) - :Uid ("{97AEB3DB-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :src ( - :AdminInfo ( - :chkpf_uid ("{C3E9CE29-9F23-4857-B88F-E9949FAF2D5D}") - :ClassName (rule_source) - ) - :compound () - :op () - : (ReferenceObject - :Name (speedy2) - :Table (network_objects) - :Uid ("{B4DB2EF5-42D8-41DC-9A1C-33310FDFB184}") - ) - ) - ) - :rule ( - :AdminInfo ( - :chkpf_uid ("{11C81B0A-4266-4801-8858-E4D9AB54A830}") - :ClassName (security_header_rule) - ) - :action ( - : (drop - :AdminInfo ( - :chkpf_uid ("{5E568AEF-0F52-4A93-AFA3-18E73A0D066A}") - :ClassName (drop_action) - :table (setup) - ) - :action () - :macro () - :type (drop) - ) - ) - :comments () - :global_location (middle) - :through ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :time ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :track ( - : (ReferenceObject - :Name (None) - :Table (tracks) - :Uid ("{97AEB47D-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :disabled (true) - :dst ( - :AdminInfo ( - :chkpf_uid ("{366C4CAD-81FB-4025-8D13-601F4A6C8FF7}") - :ClassName (rule_destination) - ) - :compound () - :op () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :header_text ("Access from Spike & DMZ to Internal") - :install ( - :AdminInfo ( - :chkpf_uid ("{47C0018E-3514-4540-A4EA-659755890D6B}") - :ClassName (rule_install) - ) - :compound () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :services ( - :AdminInfo ( - :chkpf_uid ("{0073E27C-28E5-4EC1-9A4A-BD686F700281}") - :ClassName (rule_services) - ) - :compound () - :op () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :src ( - :AdminInfo ( - :chkpf_uid ("{BD3EBBCD-06DF-4313-A347-7097F5105671}") - :ClassName (rule_source) - ) - :compound () - :op () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :state (collapsed) - ) - :rule ( - :AdminInfo ( - :chkpf_uid ("{A8A57015-68D5-4341-ADD1-895EC21419DB}") - :ClassName (security_rule) - ) - :action ( - : (accept - :AdminInfo ( - :chkpf_uid ("{BECC33F6-C362-41A4-BBD3-CBFA34A7C4E8}") - :ClassName (accept_action) - :table (setup) - ) - :action () - :macro (RECORD_CONN) - :type (accept) - ) - ) - :comments () - :disabled (false) - :global_location (middle) - :through ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :time ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :track ( - : (ReferenceObject - :Name (Log) - :Table (tracks) - :Uid ("{97AEB480-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :dst ( - :AdminInfo ( - :chkpf_uid ("{193E4DB4-BE9D-4444-BC95-C04C10D26D25}") - :ClassName (rule_destination) - ) - :compound () - :op () - : (ReferenceObject - :Name (IsoAAADray.local) - :Table (network_objects) - :Uid ("{75EDBC62-7EB1-4D37-8295-684903FDA75A}") - ) - : (ReferenceObject - :Name (gateway.local) - :Table (network_objects) - :Uid ("{7ED7EF12-A13E-4303-8A6E-C6CC28755C80}") - ) - ) - :install ( - :AdminInfo ( - :chkpf_uid ("{42CD50F6-AA17-4271-B684-DFF6E86E5649}") - :ClassName (rule_install) - ) - :compound () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :services ( - :AdminInfo ( - :chkpf_uid ("{0B65BDFF-A77E-498D-8F6D-8B77068701D6}") - :ClassName (rule_services) - ) - :compound () - :op () - : (ReferenceObject - :Name (rdp) - :Table (services) - :Uid ("{5BA0C83F-8D91-465B-9CF6-7DC6AEB84689}") - ) - : (ReferenceObject - :Name (http) - :Table (services) - :Uid ("{97AEB3D4-9AEA-11D5-BD16-0090272CCB30}") - ) - : (ReferenceObject - :Name (CIFS) - :Table (services) - :Uid ("{2A469820-B502-434C-9340-A377677A6A60}") - ) - : (ReferenceObject - :Name (UPS-Monitor) - :Table (services) - :Uid ("{8C8DED7E-F3C9-4964-B9D3-063C23997020}") - ) - ) - :src ( - :AdminInfo ( - :chkpf_uid ("{5C3E75D6-41C1-4D28-A34C-D9F0C316599F}") - :ClassName (rule_source) - ) - :compound () - :op () - : (ReferenceObject - :Name (mg.IsoAAAA-es.com) - :Table (network_objects) - :Uid ("{E5BF8260-3615-4476-B638-53CA3A24FEF1}") - ) - ) - ) - :rule ( - :AdminInfo ( - :chkpf_uid ("{5DEBDFAA-F691-4041-8E3A-EAF002F8B690}") - :ClassName (security_rule) - ) - :action ( - : (accept - :AdminInfo ( - :chkpf_uid ("{69531784-EAAE-4C1C-B792-86B14F8D015E}") - :ClassName (accept_action) - :table (setup) - ) - :action () - :macro (RECORD_CONN) - :type (accept) - ) - ) - :comments () - :disabled (false) - :global_location (middle) - :through ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :time ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :track ( - : (ReferenceObject - :Name (Log) - :Table (tracks) - :Uid ("{97AEB480-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :dst ( - :AdminInfo ( - :chkpf_uid ("{FA61FCF6-FF1E-42C6-B329-B8E23A0EB35D}") - :ClassName (rule_destination) - ) - :compound () - :op () - : (ReferenceObject - :Name (scratchy.local) - :Table (network_objects) - :Uid ("{CFABE50C-C1F6-4FF1-8AC3-3161A3779708}") - ) - ) - :install ( - :AdminInfo ( - :chkpf_uid ("{21457A88-FFC3-45C2-A6AD-7ABC8CDD0232}") - :ClassName (rule_install) - ) - :compound () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :services ( - :AdminInfo ( - :chkpf_uid ("{7990665E-448A-420C-BF7D-3616ED9ECB53}") - :ClassName (rule_services) - ) - :compound () - :op () - : (ReferenceObject - :Name (RAdmin-custom) - :Table (services) - :Uid ("{4FB59153-8212-4A12-BC08-0297AA5F0815}") - ) - ) - :src ( - :AdminInfo ( - :chkpf_uid ("{7A4BC3A5-EAB4-4CC3-8F06-5B3681A6A814}") - :ClassName (rule_source) - ) - :compound () - :op () - : (ReferenceObject - :Name (mg.IsoAAAA-es.com) - :Table (network_objects) - :Uid ("{E5BF8260-3615-4476-B638-53CA3A24FEF1}") - ) - ) - ) - :rule ( - :AdminInfo ( - :chkpf_uid ("{DC9D47B1-CEB2-43AB-B32E-5BFACD49181F}") - :ClassName (security_rule) - ) - :action ( - : (accept - :AdminInfo ( - :chkpf_uid ("{841A245A-0BBC-40D6-AFCD-FC0956945DFB}") - :ClassName (accept_action) - :table (setup) - ) - :action () - :macro (RECORD_CONN) - :type (accept) - ) - ) - :comments () - :disabled (false) - :global_location (middle) - :through ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :time ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :track ( - : (ReferenceObject - :Name (Log) - :Table (tracks) - :Uid ("{97AEB480-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :dst ( - :AdminInfo ( - :chkpf_uid ("{940B351D-CBB3-457B-AA5E-BF8EE4721229}") - :ClassName (rule_destination) - ) - :compound () - :op () - : (ReferenceObject - :Name (daba) - :Table (network_objects) - :Uid ("{94817CDB-EA8C-4213-B38D-F4417EA620C6}") - ) - ) - :install ( - :AdminInfo ( - :chkpf_uid ("{6F3DCA16-ECC8-4DAE-8729-3D07CD35A492}") - :ClassName (rule_install) - ) - :compound () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :services ( - :AdminInfo ( - :chkpf_uid ("{6A906112-E832-480B-98E6-7C88D5768449}") - :ClassName (rule_services) - ) - :compound () - :op () - : (ReferenceObject - :Name (mysql) - :Table (services) - :Uid ("{08A07607-EAAA-4A45-AD6E-6020770BD519}") - ) - : (ReferenceObject - :Name (ssh_version_2) - :Table (services) - :Uid ("{CD082D9A-44A6-4CEF-A17D-5541029ADFB3}") - ) - ) - :src ( - :AdminInfo ( - :chkpf_uid ("{124122B3-1A04-4980-AA2E-18B01C4BA2A1}") - :ClassName (rule_source) - ) - :compound () - :op () - : (ReferenceObject - :Name (mg.IsoAAAA-es.com) - :Table (network_objects) - :Uid ("{E5BF8260-3615-4476-B638-53CA3A24FEF1}") - ) - ) - ) - :rule ( - :AdminInfo ( - :chkpf_uid ("{B706F7FA-C0AA-41E6-9BE1-99FAA2073339}") - :ClassName (security_rule) - ) - :action ( - : (accept - :AdminInfo ( - :chkpf_uid ("{23C4BFFE-0F58-4C89-9AC6-EE8475E30FB2}") - :ClassName (accept_action) - :table (setup) - ) - :action () - :macro (RECORD_CONN) - :type (accept) - ) - ) - :comments () - :disabled (false) - :global_location (middle) - :through ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :time ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :track ( - : (ReferenceObject - :Name (Log) - :Table (tracks) - :Uid ("{97AEB480-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :dst ( - :AdminInfo ( - :chkpf_uid ("{3DEE2329-18AC-4C21-95A5-49D3F42BC058}") - :ClassName (rule_destination) - ) - :compound () - :op () - : (ReferenceObject - :Name (hpux) - :Table (network_objects) - :Uid ("{BF00A847-A0D6-4A75-BE1C-27E7D91EDB55}") - ) - ) - :install ( - :AdminInfo ( - :chkpf_uid ("{31E7DAD2-17B6-484F-87B3-A9817437F6C3}") - :ClassName (rule_install) - ) - :compound () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :services ( - :AdminInfo ( - :chkpf_uid ("{645119AD-FF40-4617-BB77-CE2B7679B804}") - :ClassName (rule_services) - ) - :compound () - :op () - : (ReferenceObject - :Name (telnet) - :Table (services) - :Uid ("{97AEB3CF-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :src ( - :AdminInfo ( - :chkpf_uid ("{A15D212E-0F94-4C31-82C3-83292476F567}") - :ClassName (rule_source) - ) - :compound () - :op () - : (ReferenceObject - :Name (mg.IsoAAAA-es.com) - :Table (network_objects) - :Uid ("{E5BF8260-3615-4476-B638-53CA3A24FEF1}") - ) - ) - ) - :rule ( - :AdminInfo ( - :chkpf_uid ("{FFAB5EA6-1C92-49CA-B971-6739815B346B}") - :ClassName (security_rule) - ) - :action ( - : (accept - :AdminInfo ( - :chkpf_uid ("{45995732-1869-4EBC-A799-5684F4266AF3}") - :ClassName (accept_action) - :table (setup) - ) - :action () - :macro (RECORD_CONN) - :type (accept) - ) - ) - :comments () - :disabled (false) - :global_location (middle) - :through ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :time ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :track ( - : (ReferenceObject - :Name (Log) - :Table (tracks) - :Uid ("{97AEB480-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :dst ( - :AdminInfo ( - :chkpf_uid ("{9C8B3BB2-5681-413A-855A-C8409935AA08}") - :ClassName (rule_destination) - ) - :compound () - :op () - : (ReferenceObject - :Name (SecOVID_Authserver) - :Table (network_objects) - :Uid ("{DB220C3D-763C-46AB-A7D1-1F9C7C45910E}") - ) - ) - :install ( - :AdminInfo ( - :chkpf_uid ("{121D0209-7E3D-40C0-AFD1-E5F45BC9728E}") - :ClassName (rule_install) - ) - :compound () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :services ( - :AdminInfo ( - :chkpf_uid ("{2EFB1265-AB14-401F-8157-1F4FD814C850}") - :ClassName (rule_services) - ) - :compound () - :op () - : (ReferenceObject - :Name (NEW-RADIUS) - :Table (services) - :Uid ("{97AEB41E-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :src ( - :AdminInfo ( - :chkpf_uid ("{6CA9E964-C64D-470B-B2F5-C8D9481E1309}") - :ClassName (rule_source) - ) - :compound () - :op () - : (ReferenceObject - :Name (mg.IsoAAAA-es.com) - :Table (network_objects) - :Uid ("{E5BF8260-3615-4476-B638-53CA3A24FEF1}") - ) - : (ReferenceObject - :Name (ITSecOrg-dev) - :Table (network_objects) - :Uid ("{18122B8C-51F8-4102-B143-72DA4E57367D}") - ) - ) - ) - :rule ( - :AdminInfo ( - :chkpf_uid ("{2B48CB5C-959B-4212-83BA-D0C31C9E81FD}") - :ClassName (security_rule) - ) - :action ( - : (accept - :AdminInfo ( - :chkpf_uid ("{23DAD50B-1BFA-4B5A-BD07-91F594590169}") - :ClassName (accept_action) - :table (setup) - ) - :action () - :macro (RECORD_CONN) - :type (accept) - ) - ) - :disabled (false) - :global_location (middle) - :through ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :time ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :track ( - : (ReferenceObject - :Name (Log) - :Table (tracks) - :Uid ("{97AEB480-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :comments ("SUS-Access 4 Stichling") - :dst ( - :AdminInfo ( - :chkpf_uid ("{401D98F2-0790-42A8-A27B-4CEF1B409D62}") - :ClassName (rule_destination) - ) - :compound () - :op () - : (ReferenceObject - :Name (IsoAAADray.local) - :Table (network_objects) - :Uid ("{75EDBC62-7EB1-4D37-8295-684903FDA75A}") - ) - ) - :install ( - :AdminInfo ( - :chkpf_uid ("{C607E30B-AD42-4EB9-861C-3E1F17B01A58}") - :ClassName (rule_install) - ) - :compound () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :services ( - :AdminInfo ( - :chkpf_uid ("{F70D3F8A-F47F-4E46-AC7C-6439659AD77F}") - :ClassName (rule_services) - ) - :compound () - :op () - : (ReferenceObject - :Name (http) - :Table (services) - :Uid ("{97AEB3D4-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :src ( - :AdminInfo ( - :chkpf_uid ("{66A8B48D-384B-47C2-AE14-EFA8C5BD981F}") - :ClassName (rule_source) - ) - :compound () - :op () - : (ReferenceObject - :Name (Cactus10.222.0.1) - :Table (network_objects) - :Uid ("{6CD51061-638B-4B2F-9092-7E1E4A5F0ADD}") - ) - ) - ) - :rule ( - :AdminInfo ( - :chkpf_uid ("{A4D7B2E7-4461-41FD-BBFB-F7A4738CE081}") - :ClassName (security_rule) - ) - :action ( - : (accept - :AdminInfo ( - :chkpf_uid ("{7BE16ABA-CEF4-4B95-9BC0-8753FE0D3DC5}") - :ClassName (accept_action) - :table (setup) - ) - :action () - :macro (RECORD_CONN) - :type (accept) - ) - ) - :disabled (false) - :global_location (middle) - :through ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :time ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :track ( - : (ReferenceObject - :Name (Log) - :Table (tracks) - :Uid ("{97AEB480-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :comments (WLAN-DNS) - :dst ( - :AdminInfo ( - :chkpf_uid ("{7E03AA57-58BE-42C9-8861-8395F9879960}") - :ClassName (rule_destination) - ) - :compound () - :op () - : (ReferenceObject - :Name (IsoAAADray.local) - :Table (network_objects) - :Uid ("{75EDBC62-7EB1-4D37-8295-684903FDA75A}") - ) - ) - :install ( - :AdminInfo ( - :chkpf_uid ("{BC2EEAE6-2829-44CE-99E2-1A86D9EBCE52}") - :ClassName (rule_install) - ) - :compound () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :services ( - :AdminInfo ( - :chkpf_uid ("{A109C25F-2754-404D-966B-FA7DB64E670C}") - :ClassName (rule_services) - ) - :compound () - :op () - : (ReferenceObject - :Name (domain-udp) - :Table (services) - :Uid ("{97AEB3FA-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :src ( - :AdminInfo ( - :chkpf_uid ("{612801AE-42D3-4B29-9305-AE3BC60D7C1E}") - :ClassName (rule_source) - ) - :compound () - :op () - : (ReferenceObject - :Name (wlan-router) - :Table (network_objects) - :Uid ("{426CC3AD-BE7D-45B6-AAAB-22BA0680EE21}") - ) - ) - ) - :rule ( - :AdminInfo ( - :chkpf_uid ("{B63983F0-BF08-44F7-88EA-5DF0FA381C45}") - :ClassName (security_header_rule) - ) - :action ( - : (drop - :AdminInfo ( - :chkpf_uid ("{D47409A0-8070-4258-802B-E234DE03D219}") - :ClassName (drop_action) - :table (setup) - ) - :action () - :macro () - :type (drop) - ) - ) - :comments () - :global_location (middle) - :through ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :time ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :track ( - : (ReferenceObject - :Name (None) - :Table (tracks) - :Uid ("{97AEB47D-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :disabled (true) - :dst ( - :AdminInfo ( - :chkpf_uid ("{34E31CD9-5F62-46B6-A5A2-2A25A3381BFF}") - :ClassName (rule_destination) - ) - :compound () - :op () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :header_text (Final-rules) - :install ( - :AdminInfo ( - :chkpf_uid ("{97A07F1F-7C42-469E-8976-4694BEA0C05F}") - :ClassName (rule_install) - ) - :compound () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :services ( - :AdminInfo ( - :chkpf_uid ("{AE52657F-1C63-427D-899A-2739B143874D}") - :ClassName (rule_services) - ) - :compound () - :op () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :src ( - :AdminInfo ( - :chkpf_uid ("{7D15F5BF-41C8-4674-A2A5-96AC297EB840}") - :ClassName (rule_source) - ) - :compound () - :op () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :state (collapsed) - ) - :rule ( - :AdminInfo ( - :chkpf_uid ("{E079D5BF-271E-4004-B4C5-8372C37B4661}") - :ClassName (security_rule) - ) - :action ( - : (accept - :AdminInfo ( - :chkpf_uid ("{EBF89D8A-D923-4469-9179-4209815688BC}") - :ClassName (accept_action) - :table (setup) - ) - :action () - :macro (RECORD_CONN) - :type (accept) - ) - ) - :comments () - :disabled (false) - :global_location (middle) - :through ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :time ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :track ( - : (ReferenceObject - :Name (Log) - :Table (tracks) - :Uid ("{97AEB480-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :dst ( - :AdminInfo ( - :chkpf_uid ("{93E9E478-F918-450E-8D36-280C86415DB8}") - :ClassName (rule_destination) - ) - :compound () - :op () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :install ( - :AdminInfo ( - :chkpf_uid ("{F546BB1C-8E90-4AEA-9C17-188FDA697E98}") - :ClassName (rule_install) - ) - :compound () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :services ( - :AdminInfo ( - :chkpf_uid ("{5576A25C-181D-40DB-8978-F8E8B6D19C4E}") - :ClassName (rule_services) - ) - :compound () - :op () - : (ReferenceObject - :Name (ICMPgute) - :Table (services) - :Uid ("{418C7C0A-956A-41FF-9BC1-5867B2265090}") - ) - ) - :src ( - :AdminInfo ( - :chkpf_uid ("{4B989FE8-BC56-4B8C-BD37-C6050AAC2B28}") - :ClassName (rule_source) - ) - :compound () - :op () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - ) - :rule ( - :AdminInfo ( - :chkpf_uid ("{89F7C56B-1A5F-4C4A-BC98-F777664BBEC9}") - :ClassName (security_rule) - ) - :action ( - : (accept - :AdminInfo ( - :chkpf_uid ("{BD3A43B7-179B-4A44-9E8E-BDA3C4D74428}") - :ClassName (accept_action) - :table (setup) - ) - :action () - :macro (RECORD_CONN) - :type (accept) - ) - ) - :comments () - :disabled (false) - :global_location (middle) - :through ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :time ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :track ( - : (ReferenceObject - :Name (Log) - :Table (tracks) - :Uid ("{97AEB480-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :dst ( - :AdminInfo ( - :chkpf_uid ("{787E51C4-3375-4608-A83C-CFF3D08628B5}") - :ClassName (rule_destination) - ) - :compound () - :op () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :install ( - :AdminInfo ( - :chkpf_uid ("{C67E7D9D-F7A6-4B80-AB31-589BDF22583D}") - :ClassName (rule_install) - ) - :compound () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :services ( - :AdminInfo ( - :chkpf_uid ("{E732300C-E9E8-4CC7-B0B1-1566947A92A0}") - :ClassName (rule_services) - ) - :compound () - :op () - : (ReferenceObject - :Name (redirect) - :Table (services) - :Uid ("{97AEB409-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :src ( - :AdminInfo ( - :chkpf_uid ("{DB1AE486-D8A3-44F0-AA73-AE22B0BA4A32}") - :ClassName (rule_source) - ) - :compound () - :op () - : (ReferenceObject - :Name (IsoAAAD) - :Table (network_objects) - :Uid ("{29C40B0A-414C-11D7-AEB8-7F0000013C3C}") - ) - ) - ) - :rule ( - :AdminInfo ( - :chkpf_uid ("{F134ED1C-8FC1-4ED1-9751-39EE88C79BAA}") - :ClassName (security_rule) - ) - :action ( - : (reject - :AdminInfo ( - :chkpf_uid ("{619449DF-3B19-42EF-A640-40BF30E1E398}") - :ClassName (reject_action) - :table (setup) - ) - :action () - :macro () - :type (reject) - ) - ) - :comments () - :disabled (false) - :global_location (middle) - :through ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :time ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :track ( - : (ReferenceObject - :Name (None) - :Table (tracks) - :Uid ("{97AEB47D-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :dst ( - :AdminInfo ( - :chkpf_uid ("{F3772580-72F8-47FD-BEEF-64F0C4AE29AC}") - :ClassName (rule_destination) - ) - :compound () - :op () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :install ( - :AdminInfo ( - :chkpf_uid ("{FF327589-E587-4324-B33B-EAEA6BF3D977}") - :ClassName (rule_install) - ) - :compound () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :services ( - :AdminInfo ( - :chkpf_uid ("{367A55E3-5596-40A1-A0C9-63CEA70F42C3}") - :ClassName (rule_services) - ) - :compound () - :op () - : (ReferenceObject - :Name (Drop_nologServices) - :Table (services) - :Uid ("{495E1A16-2612-49D9-8F69-B00EB33699E8}") - ) - ) - :src ( - :AdminInfo ( - :chkpf_uid ("{AFD6C077-CA8E-4C7D-A834-F781B7821B96}") - :ClassName (rule_source) - ) - :compound () - :op () - : (ReferenceObject - :Name (IsoAAAA-100) - :Table (network_objects) - :Uid ("{BF1C6029-8D5D-4A05-A3AD-4B67E6E7A7AA}") - ) - ) - ) - :rule ( - :AdminInfo ( - :chkpf_uid ("{7067EE72-61D1-4555-9832-8E9279772BCA}") - :ClassName (security_rule) - ) - :action ( - : (reject - :AdminInfo ( - :chkpf_uid ("{D06A4524-1DCA-4DD5-BCC2-54EE451C1777}") - :ClassName (reject_action) - :table (setup) - ) - :action () - :macro () - :type (reject) - ) - ) - :comments () - :disabled (false) - :global_location (middle) - :through ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :time ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :track ( - : (ReferenceObject - :Name (None) - :Table (tracks) - :Uid ("{97AEB47D-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :dst ( - :AdminInfo ( - :chkpf_uid ("{FFD672A3-65E6-4B19-B686-D40AC4299BCD}") - :ClassName (rule_destination) - ) - :compound () - :op () - : (ReferenceObject - :Name (Drop_nologDest) - :Table (network_objects) - :Uid ("{79369987-B128-4B3F-827C-3C936F7C3F53}") - ) - ) - :install ( - :AdminInfo ( - :chkpf_uid ("{0581A769-6452-42CD-9718-F226767D0287}") - :ClassName (rule_install) - ) - :compound () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :services ( - :AdminInfo ( - :chkpf_uid ("{F037BEDF-CC8F-4792-9A21-103C9F5C2A51}") - :ClassName (rule_services) - ) - :compound () - :op () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :src ( - :AdminInfo ( - :chkpf_uid ("{7B4EF795-BE09-45A2-86B9-1CE030756ECB}") - :ClassName (rule_source) - ) - :compound () - :op () - : (ReferenceObject - :Name (IsoAAAA-100) - :Table (network_objects) - :Uid ("{BF1C6029-8D5D-4A05-A3AD-4B67E6E7A7AA}") - ) - ) - ) - :rule ( - :AdminInfo ( - :chkpf_uid ("{A6F53BCD-748C-4585-B8FB-1DF23129F085}") - :ClassName (security_rule) - ) - :action ( - : (reject - :AdminInfo ( - :chkpf_uid ("{4F089C9B-C148-4A8A-8ED5-38618067B567}") - :ClassName (reject_action) - :table (setup) - ) - :action () - :macro () - :type (reject) - ) - ) - :comments () - :disabled (false) - :global_location (middle) - :through ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :time ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :track ( - : (ReferenceObject - :Name (Log) - :Table (tracks) - :Uid ("{97AEB480-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :dst ( - :AdminInfo ( - :chkpf_uid ("{34CE5F02-44F0-4180-BE48-5CB31E82D728}") - :ClassName (rule_destination) - ) - :compound () - :op () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :install ( - :AdminInfo ( - :chkpf_uid ("{7AD6114F-E8FF-4AE9-BAA8-6B72CA08F552}") - :ClassName (rule_install) - ) - :compound () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :services ( - :AdminInfo ( - :chkpf_uid ("{33DEA2EB-F713-400E-96E1-AACE576E28AB}") - :ClassName (rule_services) - ) - :compound () - :op () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :src ( - :AdminInfo ( - :chkpf_uid ("{4F305BBD-E049-4054-BCEC-A0D4F832CD80}") - :ClassName (rule_source) - ) - :compound () - :op () - : (ReferenceObject - :Name (CactusDA) - :Table (network_objects) - :Uid ("{69DBB75C-7E6D-49AD-A814-96F1BAFF12F7}") - ) - ) - ) - :rule ( - :AdminInfo ( - :chkpf_uid ("{9CD8CE05-32DB-483A-A44A-0C9131CCA022}") - :ClassName (security_rule) - ) - :action ( - : (drop - :AdminInfo ( - :chkpf_uid ("{ED025D2F-5D51-4310-AEF3-67A075F171EB}") - :ClassName (drop_action) - :table (setup) - ) - :action () - :macro () - :type (drop) - ) - ) - :comments () - :disabled (false) - :global_location (middle) - :through ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :time ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :track ( - : (ReferenceObject - :Name (Log) - :Table (tracks) - :Uid ("{97AEB480-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :dst ( - :AdminInfo ( - :chkpf_uid ("{92629D3F-DD0B-4864-A91A-9809A211E481}") - :ClassName (rule_destination) - ) - :compound () - :op () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :install ( - :AdminInfo ( - :chkpf_uid ("{92064B95-86EE-43B6-9410-C38676F3D964}") - :ClassName (rule_install) - ) - :compound () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :services ( - :AdminInfo ( - :chkpf_uid ("{C0176725-D8C5-412D-A5C3-65BA48662B1D}") - :ClassName (rule_services) - ) - :compound () - :op () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :src ( - :AdminInfo ( - :chkpf_uid ("{FB79D7A9-F91C-40F7-8DA7-303B39A7DC33}") - :ClassName (rule_source) - ) - :compound () - :op () - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - ) - :rule_adtr ( - :AdminInfo ( - :chkpf_uid ("{795A2E9C-E2BD-4674-AB77-023F50036168}") - :ClassName (address_translation_rule) - ) - :comments () - :dst_adtr ( - : (ReferenceObject - :Name (IsoAAAA-100) - :Table (network_objects) - :Uid ("{BF1C6029-8D5D-4A05-A3AD-4B67E6E7A7AA}") - ) - ) - :global_location (middle) - :install ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :rule_block_number (1) - :services_adtr ( - : (ReferenceObject - :Name (CIFS) - :Table (services) - :Uid ("{2A469820-B502-434C-9340-A377677A6A60}") - ) - ) - :src_adtr ( - : (ReferenceObject - :Name (IsoAAAA_home_test_3) - :Table (network_objects) - :Uid ("{3B37A3DE-4411-4FFC-9E54-3ABC5C4F693B}") - ) - ) - :disabled (true) - :dst_adtr_translated ( - :AdminInfo ( - :chkpf_uid ("{A735AA42-250D-4EA5-B52A-05685A6124C3}") - :ClassName (translate_static) - ) - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - :adtr_method (adtr_method_static) - ) - :services_adtr_translated ( - :AdminInfo ( - :chkpf_uid ("{12B449F6-1F99-4060-BCB0-4A9DB5B463B3}") - :ClassName (service_translate) - ) - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - :adtr_method (adtr_method_static) - ) - :src_adtr_translated ( - :AdminInfo ( - :chkpf_uid ("{55591259-4F5C-498E-BF64-59C9C7E941A1}") - :ClassName (translate_static) - ) - : (ReferenceObject - :Name (Cactus_home_test_2) - :Table (network_objects) - :Uid ("{3CB93962-2930-41A7-8067-FC373151BB91}") - ) - :adtr_method (adtr_method_static) - ) - ) - :rule_adtr ( - :AdminInfo ( - :chkpf_uid ("{BBC0B2D9-0852-4DE8-AFB2-C27B6049C3AE}") - :ClassName (address_translation_rule) - ) - :comments () - :disabled (false) - :dst_adtr ( - : (ReferenceObject - :Name (IsoAAAA-100) - :Table (network_objects) - :Uid ("{BF1C6029-8D5D-4A05-A3AD-4B67E6E7A7AA}") - ) - ) - :global_location (middle) - :install ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :rule_block_number (1) - :services_adtr ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :src_adtr ( - : (ReferenceObject - :Name (Cactus-InternetTransfer) - :Table (network_objects) - :Uid ("{408C820D-33A1-4E25-B576-EC826F525DCD}") - ) - ) - :dst_adtr_translated ( - :AdminInfo ( - :chkpf_uid ("{5DD7A06F-C26F-47A8-AFBC-2649EE40DAAF}") - :ClassName (translate_static) - ) - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - :adtr_method (adtr_method_static) - ) - :services_adtr_translated ( - :AdminInfo ( - :chkpf_uid ("{D9D74C97-AC50-4633-A4BE-AD9DF32ED7B8}") - :ClassName (service_translate) - ) - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - :adtr_method (adtr_method_static) - ) - :src_adtr_translated ( - :AdminInfo ( - :chkpf_uid ("{404CEBC7-55D9-4A9A-98AC-10A264BC9F08}") - :ClassName (translate_hide) - ) - : (ReferenceObject - :Name (IsoAAAD_intern) - :Table (network_objects) - :Uid ("{40831AE2-CB84-46D2-9522-F987BC10BDB9}") - ) - :adtr_method (adtr_method_hide) - ) - ) - :rule_adtr ( - :AdminInfo ( - :chkpf_uid ("{795A2E9C-E2BD-4674-AB77-023F50036168}") - :ClassName (address_translation_rule) - ) - :comments () - :disabled (false) - :dst_adtr ( - : (ReferenceObject - :Name (IsoAAADray.local) - :Table (network_objects) - :Uid ("{75EDBC62-7EB1-4D37-8295-684903FDA75A}") - ) - ) - :global_location (middle) - :install ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :rule_block_number (1) - :services_adtr ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :src_adtr ( - : (ReferenceObject - :Name (heag_off_upper) - :Table (network_objects) - :Uid ("{A58E3E67-0517-485F-AA04-97A12BC119C3}") - ) - ) - :dst_adtr_translated ( - :AdminInfo ( - :chkpf_uid ("{5C6895F5-E9DC-4A23-8A54-0DFAB2B7BE72}") - :ClassName (translate_static) - ) - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - :adtr_method (adtr_method_static) - ) - :services_adtr_translated ( - :AdminInfo ( - :chkpf_uid ("{4C474EB4-0463-4982-B6CE-2B5AF7708E63}") - :ClassName (service_translate) - ) - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - :adtr_method (adtr_method_static) - ) - :src_adtr_translated ( - :AdminInfo ( - :chkpf_uid ("{50C50462-F4F4-4619-B04A-5C4DB56D0F6A}") - :ClassName (translate_hide) - ) - : (ReferenceObject - :Name (IsoAAAD_intern) - :Table (network_objects) - :Uid ("{40831AE2-CB84-46D2-9522-F987BC10BDB9}") - ) - :adtr_method (adtr_method_hide) - ) - ) - :rule_adtr ( - :AdminInfo ( - :chkpf_uid ("{1D294F6F-03B3-4CAB-B5FF-5CAEB867C8D0}") - :ClassName (address_translation_rule) - ) - :comments () - :disabled (false) - :dst_adtr ( - : (ReferenceObject - :Name (LSYI-WWA) - :Table (network_objects) - :Uid ("{3ECB1B79-1A26-41A3-90F9-71BE179A7211}") - ) - ) - :global_location (middle) - :install ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :rule_block_number (1) - :services_adtr ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :src_adtr ( - : (ReferenceObject - :Name (IsoAAAA-100) - :Table (network_objects) - :Uid ("{BF1C6029-8D5D-4A05-A3AD-4B67E6E7A7AA}") - ) - ) - :dst_adtr_translated ( - :AdminInfo ( - :chkpf_uid ("{8E14CB91-D19B-40A6-8784-8554E1B86BE4}") - :ClassName (translate_static) - ) - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - :adtr_method (adtr_method_static) - ) - :services_adtr_translated ( - :AdminInfo ( - :chkpf_uid ("{5E8C8FCF-5707-4638-81A3-B20DFB9C42C9}") - :ClassName (service_translate) - ) - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - :adtr_method (adtr_method_static) - ) - :src_adtr_translated ( - :AdminInfo ( - :chkpf_uid ("{6A960E2C-D9AD-44BC-B3B2-F5F3DC5992DA}") - :ClassName (translate_static) - ) - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - :adtr_method (adtr_method_static) - ) - ) - :rule_adtr ( - :AdminInfo ( - :chkpf_uid ("{434891D2-F2AE-4B89-88AD-540EB2A0C83A}") - :ClassName (address_translation_rule) - ) - :comments () - :dst_adtr ( - : (ReferenceObject - :Name (t-online) - :Table (network_objects) - :Uid ("{C3D65C4B-6498-4E00-9BAF-15539231E8EE}") - ) - ) - :global_location (middle) - :install ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :rule_block_number (1) - :services_adtr ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :src_adtr ( - : (ReferenceObject - :Name (IsoAAAA-100) - :Table (network_objects) - :Uid ("{BF1C6029-8D5D-4A05-A3AD-4B67E6E7A7AA}") - ) - ) - :disabled (true) - :dst_adtr_translated ( - :AdminInfo ( - :chkpf_uid ("{02FA831E-4B9C-4943-9EDA-AEA384241460}") - :ClassName (translate_static) - ) - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - :adtr_method (adtr_method_static) - ) - :services_adtr_translated ( - :AdminInfo ( - :chkpf_uid ("{6DC1B358-0DE4-49CF-B496-D0006744DA88}") - :ClassName (service_translate) - ) - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - :adtr_method (adtr_method_static) - ) - :src_adtr_translated ( - :AdminInfo ( - :chkpf_uid ("{F1DC8420-40C4-4CAE-A612-C9EC4518BBCA}") - :ClassName (translate_static) - ) - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - :adtr_method (adtr_method_static) - ) - ) - :rule_adtr ( - :AdminInfo ( - :chkpf_uid ("{4BBFC8B5-8B70-4AE2-BC71-6BCF4B17F7B6}") - :ClassName (address_translation_rule) - ) - :comments () - :disabled (false) - :dst_adtr ( - : (ReferenceObject - :Name (spike.local) - :Table (network_objects) - :Uid ("{4ABDD8DE-0DA2-46E5-B129-85E3977CBD18}") - ) - ) - :global_location (middle) - :install ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :rule_block_number (1) - :services_adtr ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :src_adtr ( - : (ReferenceObject - :Name (IsoAAAA-100) - :Table (network_objects) - :Uid ("{BF1C6029-8D5D-4A05-A3AD-4B67E6E7A7AA}") - ) - ) - :dst_adtr_translated ( - :AdminInfo ( - :chkpf_uid ("{7AA3058F-6816-45D2-A6DE-B54CBB46BD08}") - :ClassName (translate_static) - ) - : (ReferenceObject - :Name (mg.IsoAAAA-es.com) - :Table (network_objects) - :Uid ("{E5BF8260-3615-4476-B638-53CA3A24FEF1}") - ) - :adtr_method (adtr_method_static) - ) - :services_adtr_translated ( - :AdminInfo ( - :chkpf_uid ("{ED35E27D-FA79-48B3-8AC5-27502A7FDB71}") - :ClassName (service_translate) - ) - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - :adtr_method (adtr_method_static) - ) - :src_adtr_translated ( - :AdminInfo ( - :chkpf_uid ("{800AC60D-FE78-47F3-B9F1-8F8F468708C1}") - :ClassName (translate_static) - ) - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - :adtr_method (adtr_method_static) - ) - ) - :rule_adtr ( - :AdminInfo ( - :chkpf_uid ("{5CF61260-14E3-42BB-81E6-EBE8EFE8AF4A}") - :ClassName (address_translation_rule) - ) - :comments () - :disabled (false) - :dst_adtr ( - : (ReferenceObject - :Name (mg.IsoAAAA-es.com) - :Table (network_objects) - :Uid ("{E5BF8260-3615-4476-B638-53CA3A24FEF1}") - ) - ) - :global_location (middle) - :install ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :rule_block_number (1) - :services_adtr ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :src_adtr ( - : (ReferenceObject - :Name (IsoAAAA-100) - :Table (network_objects) - :Uid ("{BF1C6029-8D5D-4A05-A3AD-4B67E6E7A7AA}") - ) - ) - :dst_adtr_translated ( - :AdminInfo ( - :chkpf_uid ("{098ADCE5-568E-4F27-ABF9-682BBE442FE7}") - :ClassName (translate_static) - ) - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - :adtr_method (adtr_method_static) - ) - :services_adtr_translated ( - :AdminInfo ( - :chkpf_uid ("{36B74AF0-631F-40BD-B592-5ED305639070}") - :ClassName (service_translate) - ) - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - :adtr_method (adtr_method_static) - ) - :src_adtr_translated ( - :AdminInfo ( - :chkpf_uid ("{41B82ACB-215E-4320-B02C-A86A08EEEFC9}") - :ClassName (translate_static) - ) - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - :adtr_method (adtr_method_static) - ) - ) - :rule_adtr ( - :AdminInfo ( - :chkpf_uid ("{32620515-7BA6-4223-8C0A-83C23601451E}") - :ClassName (address_translation_rule) - ) - :comments () - :disabled (false) - :dst_adtr ( - : (ReferenceObject - :Name (scratchy.local) - :Table (network_objects) - :Uid ("{CFABE50C-C1F6-4FF1-8AC3-3161A3779708}") - ) - ) - :global_location (middle) - :install ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :rule_block_number (1) - :services_adtr ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :src_adtr ( - : (ReferenceObject - :Name (mg.IsoAAAA-es.com) - :Table (network_objects) - :Uid ("{E5BF8260-3615-4476-B638-53CA3A24FEF1}") - ) - ) - :dst_adtr_translated ( - :AdminInfo ( - :chkpf_uid ("{5C1D3DFD-A07D-49DA-B3B5-B6927EC4E8FA}") - :ClassName (translate_static) - ) - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - :adtr_method (adtr_method_static) - ) - :services_adtr_translated ( - :AdminInfo ( - :chkpf_uid ("{D670057B-5491-4A66-93BB-6FA84BA374AC}") - :ClassName (service_translate) - ) - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - :adtr_method (adtr_method_static) - ) - :src_adtr_translated ( - :AdminInfo ( - :chkpf_uid ("{B06D37B0-374A-4D36-847F-360C802BF268}") - :ClassName (translate_hide) - ) - : (ReferenceObject - :Name (IsoAAAD_intern) - :Table (network_objects) - :Uid ("{40831AE2-CB84-46D2-9522-F987BC10BDB9}") - ) - :adtr_method (adtr_method_hide) - ) - ) - :rule_adtr ( - :AdminInfo ( - :chkpf_uid ("{44B823A7-B08B-4A9F-BF4E-F895E1BAE762}") - :ClassName (address_translation_rule) - ) - :comments () - :disabled (false) - :dst_adtr ( - : (ReferenceObject - :Name (IsoAAAA-100) - :Table (network_objects) - :Uid ("{BF1C6029-8D5D-4A05-A3AD-4B67E6E7A7AA}") - ) - ) - :global_location (middle) - :install ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :rule_block_number (1) - :services_adtr ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :src_adtr ( - : (ReferenceObject - :Name (Cactus-Official) - :Table (network_objects) - :Uid ("{2136B4E8-3ABF-4931-BDB9-12CDF457D4A4}") - ) - ) - :dst_adtr_translated ( - :AdminInfo ( - :chkpf_uid ("{F9494163-1D8B-45BE-A547-0786801699CD}") - :ClassName (translate_static) - ) - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - :adtr_method (adtr_method_static) - ) - :services_adtr_translated ( - :AdminInfo ( - :chkpf_uid ("{13C447D5-A284-4282-B584-A1B7ED1DE70C}") - :ClassName (service_translate) - ) - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - :adtr_method (adtr_method_static) - ) - :src_adtr_translated ( - :AdminInfo ( - :chkpf_uid ("{007B4C50-EC16-45E9-8CD5-A3C71764175C}") - :ClassName (translate_static) - ) - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - :adtr_method (adtr_method_static) - ) - ) - :rule_adtr ( - :AdminInfo ( - :chkpf_uid ("{05A4371B-C62D-4CE9-AD5F-9818F9D852BE}") - :ClassName (address_translation_rule) - ) - :comments () - :disabled (false) - :dst_adtr ( - : (ReferenceObject - :Name (IsoAAAA-100) - :Table (network_objects) - :Uid ("{BF1C6029-8D5D-4A05-A3AD-4B67E6E7A7AA}") - ) - ) - :global_location (middle) - :install ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :rule_block_number (1) - :services_adtr ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :src_adtr ( - : (ReferenceObject - :Name (allNet) - :Table (network_objects) - :Uid ("{8C20ECB8-A6DB-4C35-B79A-D12ECE559C77}") - ) - ) - :dst_adtr_translated ( - :AdminInfo ( - :chkpf_uid ("{39606C16-F893-466A-9D38-B01857A51FEB}") - :ClassName (translate_static) - ) - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - :adtr_method (adtr_method_static) - ) - :services_adtr_translated ( - :AdminInfo ( - :chkpf_uid ("{19200950-6F5C-4AA2-939A-3CE7D6ACA81D}") - :ClassName (service_translate) - ) - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - :adtr_method (adtr_method_static) - ) - :src_adtr_translated ( - :AdminInfo ( - :chkpf_uid ("{C74080E8-0E7B-4D2E-8FAA-346607D856EC}") - :ClassName (translate_hide) - ) - : (ReferenceObject - :Name (IsoAAAD_intern) - :Table (network_objects) - :Uid ("{40831AE2-CB84-46D2-9522-F987BC10BDB9}") - ) - :adtr_method (adtr_method_hide) - ) - ) - :rule_adtr ( - :AdminInfo ( - :chkpf_uid ("{D980F7C0-D2FA-4ACA-904E-34D328EF1C19}") - :ClassName (address_translation_rule) - ) - :comments () - :disabled (false) - :dst_adtr ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :global_location (middle) - :install ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :rule_block_number (1) - :services_adtr ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :src_adtr ( - : (ReferenceObject - :Name (Cactus-Wlan) - :Table (network_objects) - :Uid ("{FFB3BAC5-FD79-4D0B-911A-7413DA524723}") - ) - ) - :dst_adtr_translated ( - :AdminInfo ( - :chkpf_uid ("{EA2291B3-5DED-41D9-9AC1-E7E98C8A7157}") - :ClassName (translate_static) - ) - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - :adtr_method (adtr_method_static) - ) - :services_adtr_translated ( - :AdminInfo ( - :chkpf_uid ("{0427645F-6265-4CD1-9E5D-918261EF1A8A}") - :ClassName (service_translate) - ) - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - :adtr_method (adtr_method_static) - ) - :src_adtr_translated ( - :AdminInfo ( - :chkpf_uid ("{DB4F178F-D470-4EB9-BE8D-98EC3DCAA267}") - :ClassName (translate_hide) - ) - : (ReferenceObject - :Name (IsoAAAD_extern) - :Table (network_objects) - :Uid ("{DB456CE7-0DCA-423F-A5E4-9FA976C0B594}") - ) - :adtr_method (adtr_method_hide) - ) - ) - :rule_adtr ( - :AdminInfo ( - :chkpf_uid ("{770C7861-8D4D-45BD-9A08-6D7412464847}") - :ClassName (address_translation_rule) - ) - :comments () - :disabled (false) - :dst_adtr ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :global_location (middle) - :install ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :rule_block_number (1) - :services_adtr ( - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - ) - :src_adtr ( - : (ReferenceObject - :Name (IsoAAAA-100) - :Table (network_objects) - :Uid ("{BF1C6029-8D5D-4A05-A3AD-4B67E6E7A7AA}") - ) - ) - :dst_adtr_translated ( - :AdminInfo ( - :chkpf_uid ("{323C02BB-1CA8-4AF0-B778-CE65AB57FDA1}") - :ClassName (translate_static) - ) - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - :adtr_method (adtr_method_static) - ) - :services_adtr_translated ( - :AdminInfo ( - :chkpf_uid ("{26E182C6-DB5F-462F-BD1B-8C37735E86F7}") - :ClassName (service_translate) - ) - : (ReferenceObject - :Name (Any) - :Table (globals) - :Uid ("{97AEB369-9AEA-11D5-BD16-0090272CCB30}") - ) - :adtr_method (adtr_method_static) - ) - :src_adtr_translated ( - :AdminInfo ( - :chkpf_uid ("{8FA593D7-47A4-4AAC-BA66-34C93515C7F0}") - :ClassName (translate_hide) - ) - : (ReferenceObject - :Name (IsoAAAD_extern) - :Table (network_objects) - :Uid ("{DB456CE7-0DCA-423F-A5E4-9FA976C0B594}") - ) - :adtr_method (adtr_method_hide) - ) - ) - :use_VPN_communities (false) - ) -) diff --git a/roles/test/files/importer/sample-configs/fortinet_demo/fortigate.cfg b/roles/test/files/importer/sample-configs/fortinet_demo/fortigate.cfg deleted file mode 100644 index 1dd5dc23bb..0000000000 --- a/roles/test/files/importer/sample-configs/fortinet_demo/fortigate.cfg +++ /dev/null @@ -1,6051 +0,0 @@ -#config-version=FWF60E-5.04-FW-build1111-161216:opmode=0:vdom=0:user=tim -#conf_file_ver=0 -#buildno=5873 -#global_vdom=1 -config system global - set admin-scp enable - set admintimeout 480 - set alias "FGT60D4615073961" - set fgd-alert-subscription advisory latest-threat - set gui-certificates enable - set gui-ipv6 enable - set hostname "fg60e" - set switch-controller enable - set timezone 26 -end -config system accprofile - edit "prof_admin" - set mntgrp read-write - set admingrp read-write - set updategrp read-write - set authgrp read-write - set sysgrp read-write - set netgrp read-write - set loggrp read-write - set routegrp read-write - set fwgrp read-write - set vpngrp read-write - set utmgrp read-write - set endpoint-control-grp read-write - set wifi read-write - next - edit "config_reader" - set comments "read-only" - set mntgrp read - set admingrp read - set updategrp read - set authgrp read - set sysgrp read - set netgrp read - set loggrp read - set routegrp read - set fwgrp read - set vpngrp read - set utmgrp read - set endpoint-control-grp read - set wifi read - next -end -config wireless-controller vap - edit "wlan0" - set vdom "root" - set ssid "wch60e" - set schedule "always" - set passphrase ENC MwT7qzDW4UeSHEbobSoaaK8K4cvCZUKd4HC35zlxyuiWcxmaFlp0H6LzZXpt12dHBW2tLsNl3leiRa71BJNl5SYF2r/qKhItybJJPTo262YEFf2DBgX8HHysA79p49FbjX+UTQJC+CIVVNrVjKi86wBHIoZNyG1jnUWR6Zd5ib1us3iKd6t2liRfoVhLJ5PNSR5FxA== - next - edit "kids-wifi" - set vdom "root" - set max-clients 4 - set ssid "nfm" - set security wpa2-only-personal+captive-portal - set portal-message-override-group "captive-portal-kids-wifi" - set selected-usergroups "Kinder-group" - set security-exempt-list "kids-wifi-exempt-list" - set schedule "always" - set passphrase ENC MnT0ZIwJyRBgfyKIYpgQUbyrPkWPUGMUgzBwwBXrhnZDAfutxqryXfJGfrGZnbOy9cOpCny/wplhCuaHapxxIc4+LROepDNgITwFSq8NeOWfyV5KapLSBa/V6aFJztI609UUVb7dS6HLic9iYYCvrqoUvbd6TXxZ1knElT7lPclyQ6a5j4X2phEjkzHAHf9yP8phNw== - next - edit "gpunkt" - set vdom "root" - set ssid "gpoint" - set security wpa2-only-personal+captive-portal - set selected-usergroups "gastgruppe" - set intra-vap-privacy enable - set schedule "always" - set passphrase ENC DDTtFNHZXJQk9tLy4h0bDUDriEp2araA+JTVqa+E1nEJPgNm2xK0zaCxljEF591wRmcXUBGXjW/zxqsI3wW4Kvr3y2PMwd8GQPWubcSQPNs9jLkITD6guROTxp5Y0U4Muw4NcG7OHgRcHJBP+IMqiG7ToiIzNMqNsHlj6rkWyxU8sR6MyLRcMWSF7+LHQljp1x25xw== - next - edit "GWS" - set vdom "root" - set ssid "GWS" - set intra-vap-privacy enable - set schedule "always" - set passphrase ENC iblG3LP6Qex6jozN/MXDTZCLJZkhv3msWDEEDwfSgwG5o0ScpsxMNFjuTBkHpCX/rMigYgM0KI6KaEeqZQAO0Oddby5TwHdD0aftbwx28DRRcwl6aenEH+F0b4cXpCyfB1Vd9kAGcxZmkla0nRA+0lkeyPg+y1P1qd9TOaIJ4ZhhMtBzLgRXQHHvW63+qXwTYlcmRw== - next -end -config system interface - edit "wan1" - set vdom "root" - set ip 10.0.0.1 255.255.255.255 - set allowaccess ping - set type physical - set scan-botnet-connections block - set role wan - set snmp-index 2 - config ipv6 - set ip6-allowaccess capwap - end - next - edit "wan2" - set vdom "root" - set mode dhcp - set status down - set type physical - set snmp-index 3 - config ipv6 - set ip6-allowaccess capwap - end - next - edit "dmz" - set vdom "root" - set ip 10.0.0.2 255.255.255.255 - set allowaccess ping - set type physical - set scan-botnet-connections block - set description "gameserver lan" - set role dmz - set snmp-index 1 - config ipv6 - set ip6-allowaccess capwap - end - next - edit "internal5" - set vdom "root" - set ip 10.0.0.3 255.255.255.255 - set allowaccess ping https ssh - set type physical - set scan-botnet-connections block - set alias "eltern-keller" - set device-identification enable - set role lan - set snmp-index 5 - next - edit "npu0_vlink0" - set vdom "root" - set type physical - set snmp-index 11 - next - edit "npu0_vlink1" - set vdom "root" - set type physical - set snmp-index 12 - next - edit "modem" - set vdom "root" - set mode pppoe - set type physical - set snmp-index 4 - next - edit "ssl.root" - set vdom "root" - set type tunnel - set alias "SSL VPN interface" - set snmp-index 7 - next - edit "wlan0" - set vdom "root" - set ip 10.0.0.4 255.255.255.255 - set allowaccess ping https ssh fgfm - set type vap-switch - set scan-botnet-connections block - set device-identification enable - set snmp-index 13 - next - edit "kids-wifi" - set vdom "root" - set ip 10.0.0.5 255.255.255.255 - set allowaccess ping - set type vap-switch - set scan-botnet-connections block - set device-identification enable - set snmp-index 14 - next - edit "gpunkt" - set vdom "root" - set ip 10.0.0.6 255.255.255.255 - set type vap-switch - set scan-botnet-connections block - set device-identification enable - set snmp-index 15 - next - edit "internal" - set vdom "root" - set ip 10.0.0.7 255.255.255.255 - set allowaccess ping https ssh http fgfm capwap - set type hard-switch - set scan-botnet-connections block - set device-identification enable - set role lan - set snmp-index 8 - config ipv6 - set ip6-allowaccess capwap - end - next - edit "server-lan2" - set vdom "root" - set ip 10.0.0.8 255.255.255.255 - set allowaccess ping - set type hard-switch - set scan-botnet-connections block - set description "for knappe and printer" - set device-identification enable - set role lan - set snmp-index 6 - config ipv6 - set ip6-allowaccess capwap - end - next - edit "Forticlient-VPN" - set vdom "root" - set ip 10.0.0.9 255.255.255.255 - set type tunnel - set remote-ip 10.0.0.9 - set snmp-index 9 - set interface "wan1" - next - edit "Cactus-DA" - set vdom "root" - set type tunnel - set snmp-index 10 - set interface "wan1" - next - edit "GWS" - set vdom "root" - set ip 10.0.0.10 255.255.255.255 - set allowaccess ping - set type vap-switch - set scan-botnet-connections block - set device-identification enable - set snmp-index 16 - config ipv6 - set ip6-allowaccess ping - end - next -end -config system physical-switch - edit "sw0" - set age-val 0 - next -end -config system virtual-switch - edit "internal" - set physical-switch "sw0" - config port - edit "internal1" - next - edit "internal2" - next - edit "internal3" - next - edit "internal4" - next - end - next - edit "server-lan2" - set physical-switch "sw0" - config port - edit "internal6" - next - edit "internal7" - next - end - next -end -config system password-policy - set status enable - set apply-to admin-password ipsec-preshared-key - set min-lower-case-letter 1 - set min-upper-case-letter 1 - set min-number 1 -end -config system custom-language - edit "en" - set filename "en" - next - edit "fr" - set filename "fr" - next - edit "sp" - set filename "sp" - next - edit "pg" - set filename "pg" - next - edit "x-sjis" - set filename "x-sjis" - next - edit "big5" - set filename "big5" - next - edit "GB2312" - set filename "GB2312" - next - edit "euc-kr" - set filename "euc-kr" - next -end -config system admin - edit "admin" - set accprofile "super_admin" - set vdom "root" - set ssh-public-key1 "" - config dashboard - edit 1 - set column 1 - next - edit 2 - set widget-type licinfo - set column 1 - next - edit 3 - set widget-type jsconsole - set column 1 - next - edit 4 - set widget-type sysres - set column 2 - next - edit 6 - set widget-type alert - set column 2 - set top-n 10 - next - end - set password ENC AK1HBkKGj1Gm/kNrRfKuC6gfgxO9UtB0rq9RXcytAn34EY= - next - edit "tim" - set accprofile "super_admin" - set vdom "root" - config dashboard - edit 2 - set widget-type licinfo - set column 1 - next - edit 4 - set widget-type sysres - set column 1 - next - edit 10 - set widget-type sysop - set column 1 - next - edit 1 - set column 1 - next - edit 6 - set widget-type alert - set column 1 - set top-n 10 - next - edit 9 - set widget-type jsconsole - set column 1 - next - edit 8 - set widget-type tr-history - set column 1 - set interface "wan1" - set refresh enable - next - end - set email-to "tmp@cactus.de" - set password ENC AK1+SCz+Sd9qAuxaPTCowdDopQdGMAclzQeAs8D51/QboY= - next - edit "fmanager" - set accprofile "super_admin" - set vdom "root" - set password ENC SH2l0MdIF/9Zwhx76DxPrsdVXZp9LdIZtdAZ69uBjCmvwQm2WuqWSvujAWF3wo= - next - edit "fworch" - set accprofile "config_reader" - set vdom "root" - set ssh-public-key1 "" - set ssh-public-key2 "" - set ssh-public-key3 "" - set password ENC xxxxxxxx+Cx0dY= - next -end -config system ha - set override disable -end -config system dns - set primary 10.0.0.11 - set secondary 10.0.0.12 - set domain "ffm.cactus.de" -end -config system ddns - edit 1 - set ddns-server FortiGuardDDNS - set ddns-domain "hier.float-zone.com" - set use-public-ip enable - set monitor-interface "wan1" - next -end -config system replacemsg-image - edit "logo_fnet" - set image-type gif - set image-base64 '' - next - edit "logo_fguard_wf" - set image-type gif - set image-base64 '' - next - edit "logo_fw_auth" - set image-type png - set image-base64 '' - next - edit "logo_v2_fnet" - set image-type png - set image-base64 '' - next - edit "logo_v2_fguard_wf" - set image-type png - set image-base64 '' - next - edit "logo_v2_fguard_app" - set image-type png - set image-base64 '' - next -end -config system replacemsg mail "email-block" -end -config system replacemsg mail "email-dlp-subject" -end -config system replacemsg mail "email-dlp-ban" -end -config system replacemsg mail "email-filesize" -end -config system replacemsg mail "partial" -end -config system replacemsg mail "smtp-block" -end -config system replacemsg mail "smtp-filesize" -end -config system replacemsg http "bannedword" -end -config system replacemsg http "url-block" -end -config system replacemsg http "urlfilter-err" -end -config system replacemsg http "infcache-block" -end -config system replacemsg http "http-block" -end -config system replacemsg http "http-filesize" -end -config system replacemsg http "http-dlp-ban" -end -config system replacemsg http "http-archive-block" -end -config system replacemsg http "http-contenttypeblock" -end -config system replacemsg http "https-invalid-cert-block" -end -config system replacemsg http "http-client-block" -end -config system replacemsg http "http-client-filesize" -end -config system replacemsg http "http-client-bannedword" -end -config system replacemsg http "http-post-block" -end -config system replacemsg http "http-client-archive-block" -end -config system replacemsg http "switching-protocols-block" -end -config system replacemsg webproxy "deny" -end -config system replacemsg webproxy "user-limit" -end -config system replacemsg webproxy "auth-challenge" -end -config system replacemsg webproxy "auth-login-fail" -end -config system replacemsg webproxy "auth-authorization-fail" -end -config system replacemsg webproxy "http-err" -end -config system replacemsg webproxy "auth-ip-blackout" -end -config system replacemsg ftp "ftp-dl-blocked" -end -config system replacemsg ftp "ftp-dl-filesize" -end -config system replacemsg ftp "ftp-dl-dlp-ban" -end -config system replacemsg ftp "ftp-explicit-banner" -end -config system replacemsg ftp "ftp-dl-archive-block" -end -config system replacemsg nntp "nntp-dl-blocked" -end -config system replacemsg nntp "nntp-dl-filesize" -end -config system replacemsg nntp "nntp-dlp-subject" -end -config system replacemsg nntp "nntp-dlp-ban" -end -config system replacemsg fortiguard-wf "ftgd-block" -end -config system replacemsg fortiguard-wf "http-err" -end -config system replacemsg fortiguard-wf "ftgd-ovrd" -end -config system replacemsg fortiguard-wf "ftgd-quota" -end -config system replacemsg fortiguard-wf "ftgd-warning" -end -config system replacemsg spam "ipblocklist" -end -config system replacemsg spam "smtp-spam-dnsbl" -end -config system replacemsg spam "smtp-spam-feip" -end -config system replacemsg spam "smtp-spam-helo" -end -config system replacemsg spam "smtp-spam-emailblack" -end -config system replacemsg spam "smtp-spam-mimeheader" -end -config system replacemsg spam "reversedns" -end -config system replacemsg spam "smtp-spam-bannedword" -end -config system replacemsg spam "smtp-spam-ase" -end -config system replacemsg spam "submit" -end -config system replacemsg alertmail "alertmail-virus" -end -config system replacemsg alertmail "alertmail-block" -end -config system replacemsg alertmail "alertmail-nids-event" -end -config system replacemsg alertmail "alertmail-crit-event" -end -config system replacemsg alertmail "alertmail-disk-full" -end -config system replacemsg admin "pre_admin-disclaimer-text" -end -config system replacemsg admin "post_admin-disclaimer-text" -end -config system replacemsg auth "auth-disclaimer-page-1" -end -config system replacemsg auth "auth-disclaimer-page-2" -end -config system replacemsg auth "auth-disclaimer-page-3" -end -config system replacemsg auth "auth-reject-page" -end -config system replacemsg auth "auth-login-page" - set buffer " - - - - - - Firewall Authentication - - - -
                      -
                      -
                      - - - -

                      - Papa: Authentication Required -

                      -

                      - %%QUESTION%% -

                      -
                      - - - -
                      -
                      -
                      - - - -
                      -
                      - -
                      -
                      -
                      -
                      - -" -end -config system replacemsg auth "auth-login-failed-page" -end -config system replacemsg auth "auth-token-login-page" -end -config system replacemsg auth "auth-token-login-failed-page" -end -config system replacemsg auth "auth-success-msg" -end -config system replacemsg auth "auth-challenge-page" -end -config system replacemsg auth "auth-keepalive-page" -end -config system replacemsg auth "auth-portal-page" -end -config system replacemsg auth "auth-password-page" -end -config system replacemsg auth "auth-fortitoken-page" -end -config system replacemsg auth "auth-next-fortitoken-page" -end -config system replacemsg auth "auth-email-token-page" -end -config system replacemsg auth "auth-sms-token-page" -end -config system replacemsg auth "auth-email-harvesting-page" -end -config system replacemsg auth "auth-email-failed-page" -end -config system replacemsg auth "auth-cert-passwd-page" -end -config system replacemsg auth "auth-guest-print-page" -end -config system replacemsg auth "auth-guest-email-page" -end -config system replacemsg auth "auth-success-page" -end -config system replacemsg auth "auth-block-notification-page" -end -config system replacemsg sslvpn "sslvpn-login" -end -config system replacemsg sslvpn "sslvpn-header" -end -config system replacemsg sslvpn "sslvpn-limit" -end -config system replacemsg sslvpn "hostcheck-error" -end -config system replacemsg ec "endpt-download-portal" -end -config system replacemsg ec "endpt-download-portal-mac" -end -config system replacemsg ec "endpt-download-portal-ios" -end -config system replacemsg ec "endpt-download-portal-aos" -end -config system replacemsg ec "endpt-download-portal-other" -end -config system replacemsg ec "endpt-quarantine-portal" -end -config system replacemsg device-detection-portal "device-detection-failure" -end -config system replacemsg nac-quar "nac-quar-virus" -end -config system replacemsg nac-quar "nac-quar-dos" -end -config system replacemsg nac-quar "nac-quar-ips" -end -config system replacemsg nac-quar "nac-quar-dlp" -end -config system replacemsg nac-quar "nac-quar-admin" -end -config system replacemsg nac-quar "nac-quar-app" -end -config system replacemsg traffic-quota "per-ip-shaper-block" -end -config system replacemsg utm "virus-html" -end -config system replacemsg utm "client-virus-html" -end -config system replacemsg utm "virus-text" -end -config system replacemsg utm "dlp-html" -end -config system replacemsg utm "dlp-text" -end -config system replacemsg utm "appblk-html" -end -config system replacemsg utm "ipsblk-html" -end -config system replacemsg utm "exe-text" -end -config system replacemsg utm "waf-html" -end -config system autoupdate push-update - set status enable -end -config system autoupdate schedule - set time 01:60 -end -config system central-management - set type fortimanager - set serial-number "FMG-VM0000000000" - set fmg "10.0.0.13" -end -config user device-category - edit "android-phone" - next - edit "android-tablet" - next - edit "blackberry-phone" - next - edit "blackberry-playbook" - next - edit "forticam" - next - edit "fortifone" - next - edit "fortinet-device" - next - edit "gaming-console" - next - edit "ip-phone" - next - edit "ipad" - next - edit "iphone" - next - edit "linux-pc" - next - edit "mac" - next - edit "media-streaming" - next - edit "printer" - next - edit "router-nat-device" - next - edit "windows-pc" - next - edit "windows-phone" - next - edit "windows-tablet" - next - edit "other-network-device" - next - edit "collected-emails" - next - edit "all" - next -end -config system cluster-sync -end -config system fortiguard - set sdns-server-ip "10.0.0.14" -end -config ips global - set database extended - set traffic-submit enable - set default-app-cat-mask 18446744073642442751 -end -config ips dbinfo - set version 1 -end -config log syslogd setting - set status enable - set server "10.0.0.15" -end -config system email-server - set reply-to "tim@cactus.de" - set server "gware.cactus.de" - set port 465 - set security smtps -end -config gui console - unset preferences -end -config system session-helper - edit 1 - set name pptp - set protocol 6 - set port 1723 - next - edit 2 - set name h323 - set protocol 6 - set port 1720 - next - edit 3 - set name ras - set protocol 17 - set port 1719 - next - edit 4 - set name tns - set protocol 6 - set port 1521 - next - edit 5 - set name tftp - set protocol 17 - set port 69 - next - edit 6 - set name rtsp - set protocol 6 - set port 554 - next - edit 7 - set name rtsp - set protocol 6 - set port 7070 - next - edit 8 - set name rtsp - set protocol 6 - set port 8554 - next - edit 9 - set name ftp - set protocol 6 - set port 21 - next - edit 10 - set name mms - set protocol 6 - set port 1863 - next - edit 11 - set name pmap - set protocol 6 - set port 111 - next - edit 12 - set name pmap - set protocol 17 - set port 111 - next - edit 13 - set name sip - set protocol 17 - set port 5060 - next - edit 14 - set name dns-udp - set protocol 17 - set port 53 - next - edit 15 - set name rsh - set protocol 6 - set port 514 - next - edit 16 - set name rsh - set protocol 6 - set port 512 - next - edit 17 - set name dcerpc - set protocol 6 - set port 135 - next - edit 18 - set name dcerpc - set protocol 17 - set port 135 - next - edit 19 - set name mgcp - set protocol 17 - set port 2427 - next - edit 20 - set name mgcp - set protocol 17 - set port 2727 - next -end -config system auto-install - set auto-install-config enable - set auto-install-image enable -end -config system console - set mode batch - set output standard -end -config system ntp - set ntpsync enable - set syncinterval 60 -end -config system settings - set inspection-mode flow - set gui-dns-database enable - set gui-dos-policy enable - set gui-local-in-policy enable - set gui-sslvpn-personal-bookmarks enable - set gui-sslvpn-realms enable - set gui-ips enable - set gui-switch-controller disable - set gui-traffic-shaping disable - set gui-wan-load-balancing disable - set gui-domain-ip-reputation enable - set compliance-check enable -end -config system replacemsg-group - edit "web-filter-undefined" - set comment "System Generated" - set group-type utm - next - edit "captive-portal-kids-wifi" - set comment "System Generated" - set group-type auth - config auth - edit "auth-login-page" - set buffer " - - - - - - Firewall Authentication - - - -
                      -
                      -
                      - - - -

                      - Papa: bitte anmelden für 2h Internet -

                      -

                      - %%QUESTION%% -

                      -
                      - - - -
                      -
                      -
                      - - - -
                      -
                      - -
                      -
                      -
                      -
                      - -" - set header http - set format html - next - end - next -end -config system dhcp server - edit 1 - set dns-service local - set ntp-service default - set default-gateway 10.0.0.7 - set netmask 255.255.255.255 - set interface "internal" - config ip-range - edit 1 - set start-ip 10.0.0.16 - set end-ip 10.0.0.17 - next - end - set timezone-option default - config reserved-address - edit 1 - set ip 10.0.0.16 - set mac c8:2a:14:14:f1:eb - next - edit 2 - set ip 10.0.0.18 - set mac 9c:c7:a6:23:18:58 - next - edit 3 - set mac 3c:bd:d8:fa:d8:d4 - set action assign - set description "Fernseher" - next - edit 4 - set mac 00:24:fe:b9:18:42 - set action assign - set description "10.0.0.19" - next - end - next - edit 2 - set dns-service default - set ntp-service default - set default-gateway 10.0.0.4 - set netmask 255.255.255.255 - set interface "wlan0" - config ip-range - edit 1 - set start-ip 10.0.0.20 - set end-ip 10.0.0.21 - next - end - set timezone-option default - next - edit 3 - set ntp-service default - set default-gateway 10.0.0.5 - set netmask 255.255.255.255 - set interface "kids-wifi" - config ip-range - edit 1 - set start-ip 10.0.0.22 - set end-ip 10.0.0.23 - next - end - set timezone-option default - set dns-server1 10.0.0.24 - next - edit 4 - set dns-service default - set default-gateway 10.0.0.6 - set netmask 255.255.255.255 - set interface "gpunkt" - config ip-range - edit 1 - set start-ip 10.0.0.25 - set end-ip 10.0.0.26 - next - end - set timezone-option default - next - edit 5 - set dns-service default - set ntp-service default - set default-gateway 10.0.0.8 - set netmask 255.255.255.255 - set interface "server-lan2" - config ip-range - edit 1 - set start-ip 10.0.0.27 - set end-ip 10.0.0.28 - next - end - set timezone-option default - next - edit 6 - set dns-service default - set default-gateway 10.0.0.10 - set netmask 255.255.255.255 - set interface "GWS" - config ip-range - edit 1 - set start-ip 10.0.0.29 - set end-ip 10.0.0.30 - next - end - set timezone-option default - next - edit 7 - set dns-service default - set ntp-service default - set default-gateway 10.0.0.3 - set netmask 255.255.255.255 - set interface "internal5" - config ip-range - edit 1 - set start-ip 10.0.0.31 - set end-ip 10.0.0.32 - next - end - set timezone-option default - next -end -config firewall address - edit "SSLVPN_TUNNEL_ADDR1" - set uuid b7647270-5975-51e5-6f5a-65cd955669b6 - set type iprange - set start-ip 10.0.0.33 - set end-ip 10.0.0.34 - next - edit "all" - set uuid 72cdb5ba-d63c-51e5-c303-5835388f9b9a - next - edit "apple" - set uuid b7ce5f8c-5975-51e5-5bc3-0449fdc61391 - set type wildcard-fqdn - set wildcard-fqdn "*.apple.com" - next - edit "dropbox.com" - set uuid b7ced89a-5975-51e5-ea5b-6b089bbeb104 - set type wildcard-fqdn - set wildcard-fqdn "*.dropbox.com" - next - edit "Gotomeeting" - set uuid b7cf43a2-5975-51e5-dc5f-944da5f662b2 - set type wildcard-fqdn - set wildcard-fqdn "*.gotomeeting.com" - next - edit "icloud" - set uuid b7cfbb5c-5975-51e5-be59-10e7bed404b1 - set type wildcard-fqdn - set wildcard-fqdn "*.icloud.com" - next - edit "itunes" - set uuid b7d03244-5975-51e5-aaea-3ca78f34fc64 - set type wildcard-fqdn - set wildcard-fqdn "*itunes.apple.com" - next - edit "android" - set uuid b7d09b94-5975-51e5-806e-e3caa907c2dd - set type wildcard-fqdn - set wildcard-fqdn "*.android.com" - next - edit "skype" - set uuid b7d112e0-5975-51e5-35a3-d3c6055900b5 - set type wildcard-fqdn - set wildcard-fqdn "*.messenger.live.com" - next - edit "swscan.apple.com" - set uuid b7d18a72-5975-51e5-5589-182f772d273c - set type fqdn - set fqdn "swscan.apple.com" - next - edit "update.microsoft.com" - set uuid b7d1f408-5975-51e5-0442-6fd89994de88 - set type fqdn - set fqdn "update.microsoft.com" - next - edit "appstore" - set uuid b7d26c1c-5975-51e5-e889-443c320f8ee7 - set type wildcard-fqdn - set wildcard-fqdn "*.appstore.com" - next - edit "eease" - set uuid b7d2e35e-5975-51e5-9ff8-986220853d7e - set type wildcard-fqdn - set wildcard-fqdn "*.eease.com" - next - edit "google-drive" - set uuid b7d35aa0-5975-51e5-e4fc-f07aa20f53c4 - set type wildcard-fqdn - set wildcard-fqdn "*drive.google.com" - next - edit "google-play" - set uuid b7d3c7b0-5975-51e5-07d2-490a00ed247f - set type fqdn - set fqdn "play.google.com" - next - edit "google-play2" - set uuid b7d43f06-5975-51e5-45aa-3a5031794d4d - set type wildcard-fqdn - set wildcard-fqdn "*.ggpht.com" - next - edit "google-play3" - set uuid b7d4b6ca-5975-51e5-a49c-de545ced1d59 - set type wildcard-fqdn - set wildcard-fqdn "*.books.google.com" - next - edit "microsoft" - set uuid b7d5207e-5975-51e5-3e6b-fb39bc646ae4 - set type wildcard-fqdn - set wildcard-fqdn "*.microsoft.com" - next - edit "adobe" - set uuid b7d5977a-5975-51e5-b7e2-6e8952d82c87 - set type wildcard-fqdn - set wildcard-fqdn "*.adobe.com" - next - edit "Adobe Login" - set uuid b7d60e80-5975-51e5-9ccb-162cd8863fc9 - set type wildcard-fqdn - set wildcard-fqdn "*.adobelogin.com" - next - edit "fortinet" - set uuid b7d685f4-5975-51e5-a4f4-5e14a67b9a1d - set type wildcard-fqdn - set wildcard-fqdn "*.fortinet.com" - next - edit "googleapis.com" - set uuid b7d6f002-5975-51e5-9c23-99858226b9f8 - set type wildcard-fqdn - set wildcard-fqdn "*.googleapis.com" - next - edit "citrix" - set uuid b7d7674e-5975-51e5-3d04-893f33ecea8b - set type wildcard-fqdn - set wildcard-fqdn "*.citrixonline.com" - next - edit "verisign" - set uuid b7d7deb8-5975-51e5-9da3-39752ce8c999 - set type wildcard-fqdn - set wildcard-fqdn "*.verisign.com" - next - edit "Windows update 2" - set uuid b7d84880-5975-51e5-1f81-7f4b3d7a106f - set type wildcard-fqdn - set wildcard-fqdn "*.windowsupdate.com" - next - edit "*.live.com" - set uuid b7d8c076-5975-51e5-5fcd-0dcc80626a45 - set type wildcard-fqdn - set wildcard-fqdn "*.live.com" - next - edit "auth.gfx.ms" - set uuid b7d937c2-5975-51e5-7e01-cd153118d73b - set type fqdn - set fqdn "auth.gfx.ms" - next - edit "autoupdate.opera.com" - set uuid b7d9a1bc-5975-51e5-aebe-4d6e1f702411 - set type fqdn - set fqdn "autoupdate.opera.com" - next - edit "softwareupdate.vmware.com" - set uuid b7da199e-5975-51e5-610a-b85801cb3a41 - set type fqdn - set fqdn "softwareupdate.vmware.com" - next - edit "firefox update server" - set uuid b7da91bc-5975-51e5-ff76-9b8ba864bbc9 - set type wildcard-fqdn - set wildcard-fqdn "aus*.mozilla.org" - next - edit "klaut.cactus.de" - set uuid 80150e34-743b-51e5-321f-e0721eb97511 - set type fqdn - set associated-interface "wan1" - set fqdn "klaut.cactus.de" - next - edit "internal-10.0.0.35_24" - set uuid f0e86136-a9c1-51e5-162a-4ddd2614c9e1 - set subnet 10.0.0.35 255.255.255.255 - next - edit "knappe_10.0.0.15" - set uuid 3f815a8c-a9c2-51e5-52a8-f990f6a6ee9c - set subnet 10.0.0.15 255.255.255.255 - next - edit "tims-macbook" - set uuid 76ca1c2c-aa3f-51e5-e338-6004940e36d1 - set associated-interface "internal" - set subnet 10.0.0.16 255.255.255.255 - next - edit "fritzbox_inet_10.0.0.24" - set uuid aa4c4f1c-bc7c-51e5-cdc6-92416c4f0f96 - set associated-interface "wan1" - set subnet 10.0.0.24 255.255.255.255 - next - edit "wlan_10.0.0.36_24" - set uuid 7d34e11e-bc7d-51e5-4ff4-a8dbfcf4d69d - set associated-interface "internal" - set subnet 10.0.0.36 255.255.255.255 - next - edit "macantha_wlan_10.0.0.37" - set uuid acff38a0-bc81-51e5-fa5d-c38d9414dcc9 - set associated-interface "internal" - set subnet 10.0.0.37 255.255.255.255 - next - edit "fritzbox_oben_nat_10.0.0.18" - set uuid 628f0ddc-bc85-51e5-3066-8de8550bc50b - set associated-interface "internal" - set subnet 10.0.0.18 255.255.255.255 - next - edit "drucker-10.0.0.38" - set uuid 69748926-bc88-51e5-b230-ffb853253374 - set associated-interface "server-lan2" - set subnet 10.0.0.38 255.255.255.255 - next - edit "security.ubuntu.com" - set uuid 1f96dc4e-bcf3-51e5-4cf6-06f71acd88fd - set type fqdn - set associated-interface "wan1" - set fqdn "security.ubuntu.com" - next - edit "de.archive.ubuntu.com" - set uuid 44871eca-bd10-51e5-733c-52c7e5419906 - set type fqdn - set fqdn "de.archive.ubuntu.com" - next - edit "extras.ubuntu.com" - set uuid 8ac0c012-bd10-51e5-c5a7-fc8cd9abba09 - set type fqdn - set associated-interface "wan1" - set fqdn "extras.ubuntu.com" - next - edit "qnap_update_net_10.0.0.39/32" - set uuid 99bd890e-bd2b-51e5-668e-184a9fa02ae4 - set associated-interface "wan1" - set subnet 10.0.0.39 255.255.255.255 - next - edit "www.avm.de" - set uuid e8773fda-bd59-51e5-9feb-d8846d9e9d76 - set type fqdn - set associated-interface "wan1" - set fqdn "www.avm.de" - next - edit "SSl-VPN-10.0.0.40_24" - set uuid 0a8d295c-be1a-51e5-4d4a-e7ff7f94edba - set type iprange - set associated-interface "ssl.root" - set start-ip 10.0.0.40 - set end-ip 10.0.0.41 - next - edit "qnap-update-akamai-10.0.0.42_24" - set uuid 9e1330be-bee6-51e5-4dd2-1a08a875c08f - set associated-interface "wan1" - set subnet 10.0.0.42 255.255.255.255 - next - edit "FG_10.0.0.1" - set uuid f02bb98a-bfa8-51e5-dac7-3e56e1ffe165 - set subnet 10.0.0.1 255.255.255.255 - next - edit "gware.cactus.de_10.0.0.43" - set uuid 201b269e-c1ca-51e5-1e34-7606a8d04098 - set comment "mailserver cactus" - set associated-interface "wan1" - set subnet 10.0.0.43 255.255.255.255 - next - edit "geo-china" - set uuid 2516f030-c204-51e5-9841-1f4a0d2396d7 - set type geography - set associated-interface "wan1" - set country "CN" - next - edit "geo-russia" - set uuid 384a0e76-c204-51e5-05a3-07d31ab3dcb8 - set type geography - set associated-interface "wan1" - set country "RU" - next - edit "fg_internal_10.0.0.7" - set uuid e0650d98-c283-51e5-0279-0c7e5576c87a - set subnet 10.0.0.7 255.255.255.255 - next - edit "LG Fernseher 10.0.0.44" - set uuid d679f9f4-cb5e-51e5-5ec6-6997b7ebd9c4 - set associated-interface "internal" - set subnet 10.0.0.44 255.255.255.255 - next - edit "LG Server 10.0.0.45_24" - set uuid fcb90146-cb5e-51e5-6dae-65477abe574e - set associated-interface "wan1" - set subnet 10.0.0.45 255.255.255.255 - next - edit "google-dns-10.0.0.46" - set uuid 59e13f02-cc1b-51e5-951d-08418456a672 - set associated-interface "wan1" - set subnet 10.0.0.46 255.255.255.255 - next - edit "google-dns-10.0.0.47" - set uuid 62c2caaa-cc1b-51e5-8ee1-d9833983d0fa - set associated-interface "wan1" - set subnet 10.0.0.47 255.255.255.255 - next - edit "opendns_10.0.0.48" - set uuid 518ff984-cdb4-51e5-a65e-a6fbf1dfb098 - set associated-interface "wan1" - set subnet 10.0.0.48 255.255.255.255 - next - edit "broadcast" - set uuid 50c335a0-d09a-51e5-3a94-eba077948081 - set subnet 255.255.255.255 255.255.255.255 - next - edit "valve_10.0.0.49" - set uuid f2de672c-d583-51e5-fff6-ebceb1d50599 - set comment "steam" - set associated-interface "wan1" - set subnet 10.0.0.49 255.255.255.255 - next - edit "valve_10.0.0.50" - set uuid bf3d3b5c-d58b-51e5-4524-7bf9fcb1bb9b - set associated-interface "wan1" - set subnet 10.0.0.50 255.255.255.255 - next - edit "ubuntu-gameserver-10.0.0.51" - set uuid 8b52bd5a-dccd-51e5-8d64-a044e5227624 - set comment "kinder gameserver" - set associated-interface "dmz" - set subnet 10.0.0.51 255.255.255.255 - next - edit "pi_10.0.0.52" - set uuid 914b073a-e218-51e5-a581-faea5587417f - set associated-interface "internal" - set subnet 10.0.0.52 255.255.255.255 - next - edit "wlan_pi_10.0.0.53_24" - set uuid bf3f1222-e235-51e5-88c8-03433bdb0cf2 - set associated-interface "internal" - set subnet 10.0.0.53 255.255.255.255 - next - edit "macantha_at_pi_10.0.0.54" - set uuid b04dffc2-e23e-51e5-4b8d-67cc608d58a5 - set associated-interface "internal" - set subnet 10.0.0.54 255.255.255.255 - next - edit "fb7240_10.0.0.55" - set uuid 7dc2a46c-e852-51e5-84b8-38d00387c72a - set associated-interface "internal" - set subnet 10.0.0.55 255.255.255.255 - next - edit "fritzbox_10.0.0.24_global" - set uuid 8c33963c-0b89-51e6-1241-f0b862831862 - set subnet 10.0.0.24 255.255.255.255 - next - edit "www.cactus.de" - set uuid 11f62ee6-1072-51e6-04aa-7a7606d08773 - set associated-interface "wan1" - set subnet 10.0.0.56 255.255.255.255 - next - edit "gast-wlan-10.0.0.57/32" - set uuid 34991480-3008-51e6-6c11-a6617dbfd69e - set associated-interface "internal" - set subnet 10.0.0.57 255.255.255.255 - next - edit "10.0.0.58_local_subnet_1" - set uuid acee9a08-be0c-51e6-ff4c-d05b94eb2810 - set subnet 10.0.0.35 255.255.255.255 - next - edit "10.0.0.58_remote_subnet_1" - set uuid ad2cbf0e-be0c-51e6-fb9f-d6d0d8c44063 - set subnet 10.0.0.59 255.255.255.255 - next - edit "Cactus-DA_local_subnet_1" - set uuid 8d985a16-be27-51e6-7b4d-a68a60e625af - set subnet 10.0.0.35 255.255.255.255 - next - edit "Cactus-DA_remote_subnet_1" - set uuid 8dadea7a-be27-51e6-06b7-37fa239b17b7 - set subnet 10.0.0.60 255.255.255.255 - next - edit "fwf60-wlan-client-net" - set uuid 7a836eae-be57-51e6-6cd9-57a7bcb8a8ad - set associated-interface "wlan0" - set subnet 10.0.0.61 255.255.255.255 - next - edit "wlan-kids" - set uuid b95fc070-bf0e-51e6-ba04-52463c963ff7 - set associated-interface "kids-wifi" - set subnet 10.0.0.62 255.255.255.255 - next - edit "wifi-kids-wlan-router-ip" - set uuid d80a7804-bfa8-51e6-9012-2be19829673e - set associated-interface "kids-wifi" - set subnet 10.0.0.5 255.255.255.255 - next - edit "wikipedia.org" - set uuid 0018303a-bfad-51e6-3d63-8e86b91e8ce4 - set type fqdn - set comment "for allowing access to wikipedia" - set associated-interface "wan1" - set fqdn "wikipedia.org" - next - edit "google.de" - set uuid 8a9e357c-bfb4-51e6-6ac3-81356d5bb0b5 - set type fqdn - set associated-interface "wan1" - set fqdn "google.de" - next - edit "woehlerschule.de" - set uuid b0128b5a-bfb4-51e6-b707-a0ea0e397828 - set type fqdn - set associated-interface "wan1" - set fqdn "woehlerschule.de" - next - edit "windowsupdate.com" - set uuid e71eadfe-bfb4-51e6-3b29-9df418a8f2bf - set type fqdn - set associated-interface "wan1" - set fqdn "windowsupdate.com" - next - edit "whatsapp.com" - set uuid 10d3e9b6-bfb5-51e6-e599-37b91de688b5 - set type fqdn - set associated-interface "wan1" - set fqdn "whatsapp.com" - next - edit "VPN_local_10.0.0.61" - set uuid 62637d14-c159-51e6-c58c-5f47d2fc035b - set subnet 10.0.0.61 255.255.255.255 - next - edit "VPN_local_10.0.0.63" - set uuid 750b9b40-c159-51e6-0e2c-cae0351e0f4e - set subnet 10.0.0.63 255.255.255.255 - next - edit "net_10.0.0.64_24" - set uuid 7966a47a-c38c-51e6-e4cd-9ef79b13ca72 - set subnet 10.0.0.64 255.255.255.255 - next - edit "vpn-gw-cactus-ffm" - set uuid fcfebd16-f3a9-51e6-9ba2-0a591dd3ff21 - set associated-interface "wan1" - set subnet 10.0.0.65 255.255.255.255 - next - edit "eltern-keller-10.0.0.66_24" - set uuid a36086c4-fa6e-51e6-54c2-7854906b1e8e - set associated-interface "internal5" - set subnet 10.0.0.66 255.255.255.255 - next -end -config firewall multicast-address - edit "all" - set start-ip 10.0.0.67 - set end-ip 10.0.0.68 - next -end -config firewall address6 - edit "SSLVPN_TUNNEL_IPv6_ADDR1" - set uuid b76480a8-5975-51e5-f0d1-b5b0ba854ec4 - set ip6 fdff:ffff::/120 - next - edit "all" - set uuid 72cef204-d63c-51e5-8746-4c0140b699b5 - next - edit "test-ipv6addr" - set uuid ce3a1a84-1065-51e6-fa4a-86517298a194 - set ip6 1::/128 - next - edit "www.cactus.de" - set uuid 2827ec4a-1072-51e6-fd76-346058c066b4 - set ip6 1::3/128 - next -end -config firewall multicast-address6 - edit "all" - set ip6 ff00::/8 - set visibility disable - next -end -config firewall addrgrp - edit "G-google-dns-srv" - set uuid 8c9785c8-cc1b-51e5-dfd9-d129f0df2cf1 - set member "google-dns-10.0.0.47" "google-dns-10.0.0.46" - next - edit "group1test" - set uuid 9510100e-0fa4-51e6-af2b-a73f820b7ef3 - set member "android" "de.archive.ubuntu.com" - set comment "test comment" - next - edit "10.0.0.58_local" - set uuid ad22f6ae-be0c-51e6-f919-40cbf9bfaa1c - set member "10.0.0.58_local_subnet_1" - set comment "VPN: 10.0.0.58 (Created by VPN wizard)" - next - edit "10.0.0.58_remote" - set uuid ad5f2110-be0c-51e6-7669-02c657a3f5ac - set member "10.0.0.58_remote_subnet_1" - set comment "VPN: 10.0.0.58 (Created by VPN wizard)" - next - edit "Cactus-DA_local" - set uuid 8da653fa-be27-51e6-905a-d2c47472178f - set member "Cactus-DA_local_subnet_1" "VPN_local_10.0.0.63" "VPN_local_10.0.0.61" - set comment "VPN: Cactus-DA (Created by VPN wizard)" - next - edit "Cactus-DA_remote" - set uuid 8dbce926-be27-51e6-ce37-835cb6d31f1e - set member "Cactus-DA_remote_subnet_1" - set comment "VPN: Cactus-DA (Created by VPN wizard)" - next - edit "kids-allowed-internet" - set uuid b5c63d9e-bfb4-51e6-c815-aee3bb9739e7 - set member "google.de" "wikipedia.org" "woehlerschule.de" - next -end -config firewall addrgrp6 - edit "ipv6-testgroup" - set uuid d8d64e08-1066-51e6-1721-60ca3eb7141a - set comment "commentar334" - set member "SSLVPN_TUNNEL_IPv6_ADDR1" "test-ipv6addr" - next -end -config firewall service category - edit "General" - set comment "General services." - next - edit "Web Access" - set comment "Web access." - next - edit "File Access" - set comment "File access." - next - edit "Email" - set comment "Email services." - next - edit "Network Services" - set comment "Network services." - next - edit "Authentication" - set comment "Authentication service." - next - edit "Remote Access" - set comment "Remote access." - next - edit "Tunneling" - set comment "Tunneling service." - next - edit "VoIP, Messaging & Other Applications" - set comment "VoIP, messaging, and other applications." - next - edit "Web Proxy" - set comment "Explicit web proxy." - next -end -config firewall service custom - edit "ALL" - set category "General" - set protocol IP - next - edit "DNS" - set category "Network Services" - set tcp-portrange 53 - set udp-portrange 53 - next - edit "HTTP" - set category "Web Access" - set tcp-portrange 80 - next - edit "HTTPS" - set category "Web Access" - set tcp-portrange 443 - next - edit "IMAP" - set category "Email" - set tcp-portrange 143 - next - edit "IMAPS" - set category "Email" - set tcp-portrange 993 - next - edit "LDAP" - set category "Authentication" - set tcp-portrange 389 - next - edit "NTP" - set category "Network Services" - set tcp-portrange 123 - set udp-portrange 123 - next - edit "PING" - set category "Network Services" - set protocol ICMP - set icmptype 8 - unset icmpcode - next - edit "DCE-RPC" - set category "Remote Access" - set tcp-portrange 135 - set udp-portrange 135 - next - edit "POP3" - set category "Email" - set tcp-portrange 110 - next - edit "POP3S" - set category "Email" - set tcp-portrange 995 - next - edit "SAMBA" - set category "File Access" - set tcp-portrange 139 - next - edit "SMTP" - set category "Email" - set tcp-portrange 25 - next - edit "SMTPS" - set category "Email" - set tcp-portrange 465 - next - edit "SSH" - set category "Remote Access" - set tcp-portrange 22 - next - edit "SQUID" - set category "Tunneling" - set tcp-portrange 3128 - next - edit "KERBEROS" - set category "Authentication" - set tcp-portrange 88 464 - set udp-portrange 88 464 - next - edit "LDAP_UDP" - set category "Authentication" - set udp-portrange 389 - next - edit "SMB" - set category "File Access" - set tcp-portrange 445 - next - edit "webproxy" - set explicit-proxy enable - set category "Web Proxy" - set protocol ALL - set tcp-portrange 0-65535:0-65535 - next - edit "ARK-7777-7778-udp" - set comment "ark beta main ports" - set udp-portrange 7777-7778 - next - edit "minecraft-25565" - set tcp-portrange 25565 - next - edit "afp_548_tcp" - set tcp-portrange 548 - next - edit "bittorrent" - set category "General" - set udp-portrange 6881 - next - edit "tcp-8011-to-avm" - set fqdn "www.avm.de" - set tcp-portrange 8011 - next - edit "tcp_40000_up" - set tcp-portrange 40000-40100 - next - edit "tcp_8081_phpfreechat" - set category "VoIP, Messaging & Other Applications" - set tcp-portrange 8081 - next - edit "steam-udp-27000-27050" - set udp-portrange 27000-27050 - next - edit "valve_udp_52626-52627" - set udp-portrange 52626-52627 - next - edit "valve_udp_45993" - set udp-portrange 45993 - next - edit "valve_udp_45433" - set udp-portrange 45433 - next - edit "valve_udp_3478-3480" - set udp-portrange 3478-3480 - next - edit "udp-high-ports" - set comment "1024-65535" - set udp-portrange 1024-65535 - next - edit "ark-udp-32768-65535" - set comment "dynamic port used for user session to ark server" - set color 1 - set udp-portrange 32768-65535 - next - edit "steam-tcp-27015-27020" - set comment "steam update?" - set color 1 - set tcp-portrange 27015-27020 - next - edit "test_service_multi-port" - set comment "test comment1123" - set tcp-portrange 22:1024-65535 143:100-200 22123 - set udp-portrange 68 889 789-891 - next - edit "apple-netscan" - set category "Network Services" - set udp-portrange 192 - next - edit "fortinet-captive-portal-auth" - set tcp-portrange 1003 - next - edit "tcp14013-fb" - set comment "fritzbox parental stuff" - set tcp-portrange 14013 - next - edit "tcp_5357_samsung_printer" - set tcp-portrange 5357 - next - edit "ARK-7777-7778-tcp" - set tcp-portrange 7777-7778 - next -end -config firewall service group - edit "Email Access" - set member "DNS" "IMAP" "IMAPS" "POP3" "POP3S" "SMTP" "SMTPS" - next - edit "Web Access" - set member "DNS" "HTTP" "HTTPS" - next - edit "Windows AD" - set member "DCE-RPC" "DNS" "KERBEROS" "LDAP" "LDAP_UDP" "SAMBA" "SMB" - next - edit "Exchange Server" - set member "DCE-RPC" "DNS" "HTTPS" - next - edit "valve_ports" - set member "valve_udp_3478-3480" "valve_udp_45433" "valve_udp_45993" "valve_udp_52626-52627" - set comment "valve game download plattform" - next -end -config webfilter ftgd-local-cat - edit "custom1" - set id 140 - next - edit "custom2" - set id 141 - next -end -config ips sensor - edit "sniffer-profile" - set comment "Monitor IPS attacks." - config entries - edit 1 - set severity high critical - next - end - next - edit "default" - set comment "Prevent critical attacks." - config entries - edit 2 - set rule 29519 - set status enable - set action block - set rate-count 1000 - set rate-duration 10 - next - edit 3 - set rule 20940 - set status enable - set action block - set rate-count 60 - next - edit 4 - set rule 35662 - set status enable - set action block - set rate-count 200 - set rate-duration 10 - next - edit 5 - set rule 12090 - set status enable - set action block - set rate-count 500 - next - edit 6 - set rule 42016 - set status enable - set action block - set rate-count 35 - set rate-duration 10 - next - edit 7 - set rule 20954 - set status enable - set action block - set rate-count 60 - next - edit 8 - set rule 20946 - set status enable - set action block - set rate-count 60 - set rate-duration 10 - next - edit 9 - set rule 22909 - set status enable - set action block - set rate-count 200 - set rate-duration 10 - next - edit 10 - set rule 17991 - set status enable - set action block - set rate-count 275 - set rate-duration 1 - next - edit 11 - set rule 38273 - set status enable - set action block - set rate-count 20 - set rate-duration 1 - next - edit 12 - set rule 31464 - set status enable - set log disable - set action pass - next - edit 13 - set rule 29707 - set status enable - set log disable - set action pass - next - edit 14 - set rule 31101 - set status enable - set log disable - set action pass - next - edit 15 - set rule 29020 - set status enable - set log disable - set action pass - next - edit 16 - set rule 29695 - set status enable - set log disable - set action pass - next - edit 17 - set rule 31433 - set status enable - set log disable - set action pass - next - edit 18 - set rule 29808 - set status enable - set log disable - set action pass - next - edit 19 - set rule 14558 - set status enable - set log disable - set action pass - next - edit 20 - set rule 29929 - set status enable - set log disable - set action pass - next - edit 21 - set rule 24608 - set status enable - set log disable - set action pass - next - edit 22 - set rule 29651 - set status enable - set log disable - set action pass - next - edit 23 - set rule 32130 - set status enable - set log disable - set action pass - next - edit 24 - set rule 32852 - set status enable - set log disable - set action pass - next - edit 25 - set rule 28070 - set status enable - set log disable - set action pass - next - edit 1 - set severity medium high critical - next - end - next -end -config web-proxy global - set proxy-fqdn "proxy.gelbeshaus" -end -config application list - edit "sniffer-profile" - set comment "Monitor all applications." - unset options - config entries - edit 1 - set action pass - next - end - next - edit "default" - set comment "Monitor all applications." - config entries - edit 1 - set application 17459 17244 - set action pass - set log disable - next - edit 2 - set category 2 19 - next - edit 3 - set category 6 22 - set action pass - next - end - next -end -config application casi profile - edit "default" - set comment "Monitor all applications." - config entries - edit 1 - set action pass - next - end - next - edit "sniffer-profile" - set comment "Monitor all applications." - config entries - edit 1 - set action pass - next - end - next -end -config dlp sensor - edit "sniffer-profile" - set comment "Log a summary of email and web traffic." - set flow-based enable - set summary-proto smtp pop3 imap http-get http-post - next - edit "default" - set comment "Log a summary of email and web traffic." - set summary-proto smtp pop3 imap http-get http-post - next -end -config webfilter urlfilter - edit 1 - set name "default" - config entries - edit 1 - set url "r.adc-srv.net" - set action allow - next - edit 2 - set url "mzstatic.com" - set action allow - next - end - next -end -config log threat-weight - config web - edit 1 - set category 26 - set level high - next - edit 2 - set category 61 - set level high - next - edit 3 - set category 86 - set level high - next - edit 4 - set category 1 - set level medium - next - edit 5 - set category 3 - next - edit 6 - set category 4 - set level medium - next - edit 7 - set category 5 - set level medium - next - edit 8 - set category 6 - set level medium - next - edit 9 - set category 12 - set level high - next - edit 10 - set category 59 - set level high - next - edit 11 - set category 62 - set level medium - next - edit 12 - set category 83 - set level high - next - edit 13 - set category 72 - next - edit 14 - set category 14 - next - end - config application - edit 1 - set category 2 - next - edit 2 - set category 6 - set level medium - next - edit 3 - set category 19 - set level critical - next - end -end -config icap profile - edit "default" - next -end -config vpn certificate ca - edit "CA_Cert_1" - set ca "-----BEGIN CERTIFICATE----- -MIIC0jCCAbqgAwIBAgIEalWQfzANBgkqhkiG9w0BAQUFADAaMRgwFgYDVQQDEw9j -YS5jcC5jYWN0dXMuZGUwHhcNMTUxMjAzMTAzMTI1WhcNMjIxMjAzMTAzMTI1WjAa -MRgwFgYDVQQDEw9jYS5jcC5jYWN0dXMuZGUwggEiMA0GCSqGSIb3DQEBAQUAA4IB -DwAwggEKAoIBAQCP1TLAqe2zZ3kc5QMQZw0sztoXtGBU7910QdQReiuEDjN+Mlbg -/2COaMPcZH5nhaSib2+R/LNdWhfJvw6zObgrRjhMcWoivOXmnQH52fkPrvJtIBBx -VWvtrI6/M4uU4meOm/4F2JeBA6JAuaLnMAIjF+DPtmABGmn4ntufGUg9Y78QI3cE -22etSR0uNFs13xx1JOtSwY2MjcyPDOedxEyJBR8f1MsMqZhWCUArWkb18VmGhSz1 -EYHya4FYx+o6IBU8ysuFvs8fjUBW+7EYaBbcqLZD9wHCdb+VKxXn+eO+z4IlO+al -XlChLXbZbTRlVp32WoY/ZdhCQuPspmT9vwh7AgMBAAGjIDAeMA8GA1UdEwEB/wQF -MAMBAf8wCwYDVR0PBAQDAgGGMA0GCSqGSIb3DQEBBQUAA4IBAQAbBA2jqOIaTQsq -eIUUtpXz5wYlUkfDwlOEhwWlvAlGAnlvYP6f3ZqCMYal4cNgpAUfDI7YHJ4L0Uoy -uhi5Mj5wQ7tVVaNZvNsBc73Q9c5gD2YBmtObO2GVDPqSMR8g4aTSqPb7QDBOO1yI -U3u5H2FlVB1+h/YpRFqm1AdlgdbzlwOvVdH7/5uOB5+DwGK73pZ5mwh2Dkm3fNzk -eRqd3SwmJReK771UWU8tSS6PNzw6WupA+SdLWlRvWiqDkoXB8jkPcOGrWHepYb5D -F3DMYVbmp+ivB465+N8a4BJ06MytEaJAPj0sDM9R88xNPt4ss90AKIEWGKgLb66p -cvJH+/AS ------END CERTIFICATE-----" - set range global - next - edit "CA_Cert_2" - set ca "-----BEGIN CERTIFICATE----- -MIIFtjCCA56gAwIBAgIIbO9Gi4dAwVQwDQYJKoZIhvcNAQELBQAwcjELMAkGA1UE -BhMCREUxDzANBgNVBAgMBkhlc3NlbjEeMBwGA1UECgwVQ2FjdHVzIGVTZWN1cml0 -eSBHbWJIMRUwEwYDVQQDDAxjYS5jYWN0dXMuZGUxGzAZBgkqhkiG9w0BCQEWDGNh -QGNhY3R1cy5kZTAeFw0xNDA5MDgxNTQ1MTlaFw0yOTA5MDQxNTQ1MTlaMHIxCzAJ -BgNVBAYTAkRFMQ8wDQYDVQQIDAZIZXNzZW4xHjAcBgNVBAoMFUNhY3R1cyBlU2Vj -dXJpdHkgR21iSDEVMBMGA1UEAwwMY2EuY2FjdHVzLmRlMRswGQYJKoZIhvcNAQkB -FgxjYUBjYWN0dXMuZGUwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDV -KexJ4XeQTxPDNEPMKmu6ahgJIc8BPlCdV9zWskGcgvSxlNY43lOZGBYuu5Kb3y8T -TC/ikGFcHccmC0xaGwpZcxhFyElKgFbKVf8BrjKBgSVoHE7yMDI03NGipxcAZw94 -SX96Ys8QlxpV7xfGVloVMgKxmEZTE6oR2IGmG7JZMDGGs4j773kzkkCgTzgSbp4B -TJsiZFOmL81x7Bf9KCuPT7Yb+OQmo2F8sPHr6ucxW21Z2Xe1WJVmuNoSShlFrwWE -RaMlGt3+Db3NxFQetWIrTrjKbqDJLCXhcK3Rmdy86zBTrPMhscT1lQb3Dvm+YC7a -ZBXnagZhogPeTT7Gx05THTsDZtWoPyFTkgIMvMXy26sBcfq9VnBD/o2kxIi3Aqs9 -0tDgiQAsb/jci4yH7VGJT/TAo10HiBthqEDPYk60ro1w7oniDsxAA3acUaA+R/4F -mJ/BSfIvaRFGwMUCy80/qnxY3IwoVTpeuJysGHG6rbjPkjJUvtmmYTSeF3RmYJnK -fbchO0tc4Ug8VFuK4k2quNvAAR3FJIOxXNbr3I7RKNKMeGtF/HixeM0htylN9euM -0myw1IqsaHrnuNwsNvyfuL9NncdAOwkG/iVdAC+FFDodFWoR0+KlJoAZ801KNf7L -JBp+eStkQsQE5DuvS+Mcf6+BxhNBWuyICPIlUcFEkQIDAQABo1AwTjAdBgNVHQ4E -FgQUfh8NIoEhiLCObeE3WPZ3iUSo6kYwHwYDVR0jBBgwFoAUfh8NIoEhiLCObeE3 -WPZ3iUSo6kYwDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAgEAsVigHPVq -jc+vipxME7p4GZbHYDaURMBdKRhngvgY9K+04VdP4c8quhgJAZYtTkiWKkl4vB98 -7M8K3vlShJSTqkqJ4Fu7iuotBuircqk+ALGvSOeTdnt4hXf9t0OxjDRY+lCI2dx3 -PH/aa5TMLJ/ZAvHf13o041wLa1pzvDDt7u2RbRy62GqRHXuuA82QAtdYznJ221Rq -QalD7+XORU20jmLW9muS9Khre9IELOnyE+m9XzfttD8bjgGEi/coxBVZ/rYTrvIG -USdQge2vYY3+d3+49vh9tKP/Gd0amiTfs1LyabQtQK9lJviOob4g+/zVbu26Aymy -LZ295T4+uzTYow2+IKRMjnhOVwufqPz5Ooo5ZZ1QgCevSne0392TPveXkGiskIXr -T1e1Pqh2zXBgeHUkbSbJ7/YqrZGqE7mxYc+yGnQAacqxBoMnvLTZVjW9rHkZT6Ad -l57RoG95v0AEAGqcoP9NJ7hidevSYxY6AQ4Fz5ec9kS+qmsXB4kQzk+pYH2dSFv9 -ieM8bSPXYSKRgISS9m2VMItaZ/YQKGdE4OpAaYIAMkfOTrRXdU8cphUnb2/dUwAF -IQisaaSrn+XCkOB1c5kEnFSw/B/HJRPoxIw6gbD3i9cq7YrcAFg54rm/CS6s4CMd -iaqgMESu2NxnaC7tpme/G4lpI63vKtGO1nk= ------END CERTIFICATE-----" - set range global - next -end -config vpn certificate local - edit "Fortinet_CA_SSL" - set password ENC WsTjIWD+q5eqie5SnqV07g6Ut0/KI8al3XS292qN2xd0in3dGS+pks8w+N4MrBW9TitbAuc3q2MHWtfIAKflvwRlnKpwSaaWsJ+lQjDPOZ9dO7Dymzn+wp6JOClcUcQVLDTwBFPFfvYe0UUNIsZBEaNWuEtgyYJrNPDkpR5dP8ETM/2NSykQV7g8D1DxSDsJL23Whg== - set comments "This is the default CA certificate the SSL Inspection will use when generating new server certificates." - set private-key "-----BEGIN ENCRYPTED PRIVATE KEY----- -MIIFDjBABgkqhkiG9w0BBQ0wMzAbBgkqhkiG9w0BBQwwDgQIqxPd/BHhF4ECAggA -MBQGCCqGSIb3DQMHBAi5wpLR+Ve1hwSCBMiPBW0sp/HIZpAVX5ITik2mHwlpE+CO -aF6qlaCyWLpI566u/syZgOQ/JRuEDzddyo9vsTILRNCJwlrWFlSFHPrFCql/hrXG -MwbhsCWa/56mqcyyUAY73niPAvcmBNATueHe2RNWDYEJWDTghfQatbaKhhUDKojz -OYv1PDjibFcUNNnyu/26ud9Ad8vzxH/oD0uI3jOadEr9YLubWioFeahel9qidOPi -QDT0fqD8skaRIXSVQrpwLguFrtNANPOBVoRAOiKcWlBRSPuaQ4obfmrL3eAVUr3U -LCMIDBSJfd0v62bMGa9VZFf3XF+7giN9tg7OWV6yGtSdnsnF/6imtnb6bUuGzdUO -Y/8XrWjZE5a5vyQwqTn0kI6wsVLx6JVMthyZkaOXll8F88Qkjuw8h8cmZvIcv6k8 -CrYU41LXezTHDCD3pq8inQVA6VKpdKiKOmsD0qH/wfAGBKdUIfo8p5tmpJrdhA92 -MDJrmjmulvg+CTbb6g3ovuHrJY6hGk0o+RV/bTneNwj2wPMclF/t1tjX7b8pwgoq -zLPuk72UuC6C/4p3MjiMEItCynIOPsALFBSQ9kvnhPXTdXfrh6L8Qn0Tn+FRTpC7 -pNt4hDO4PReUrOtFousswOnuqoV9XiXLppEGrX20soip24TDsLS+W6haiO14T8/h -cR/Uts9Uy/AXeKeH7D6agde4LHPvfpMizRrlDHx3OBQ4aJ7AasTz8vEsyfQ498cV -iy2bMIBp7yUCFzzomu5rrik3QZgoTIDgkKl6O1CUTUlMMeNDJYyAAqSN+9O6VL+b -mLyFNZ9BO3Xth+KWypeqrCDsa/PJi3bhjJ7pIuNgt87av2I/5E9B1kNmkXlloOvk -UpQAoMcwVJuYoqTWtaCxVcMrUr6x+08qiWqh309pp4RLQnCHDshhaCuMQ4YZyD8X -kYp7frX55RAwyXdAyQWk2sT8x74qUWF6aigPSESzFji45UmrgxQMAMm7KRDSxGG2 -xt9OJuDCipCC6CP4dCNQRfT7mzshg6QTGdemJBbNBAqbjukMFbXutmEdtazwh+fX -ZkfNqT29IoceXdb/p3apGO9OZAXzw0Nwzj3UU8iCFu4y9DGQ0LfwovvdGCaCDx7y -LBpMMRhhBQxnuiHHt0WfBOp5Z/bK4KL+4Fgo3oUg29sDI+KBegS7b/s6+7d0201e -IdavbTWLjwzizaAvf9mUvyCZ5HWHzS25QHm6xCSFSUvxOJWl1YJ46CjftFH3c8qv -56gu62Ycsm2h4FojP5ASOKxCEQv3WweDvF1iieeZnm1SWv/1zn2WBo86N8W12hhx -h7dkjfRJ5304w/Tx0wLXGTQ8c8iPclElR5rXfCydnHz8NhTuP689OOx3iEIyJN62 -dsonSsvB7NEWpHSwqcL33iG4FUCqoQrtAhmstxrV+0EQY4ZvWWU8qqATUKS/n/hh -g3sinr8EGWxCDiefJVuR3yc6QkDYCaRFXBorb7uZGJEDadxmqJN2TIg+9g4OY9eQ -v/BbdFjnmuwTPzF6euKW7YAosVM8Dm6hhHOZG2bu9JLIvZ27fsgFKuHUoNHAVg7x -jEs0NdPh8y8QwDkS+ld5ev7sT499jeyJetZC+ZtUj0Db77VmUdBPGPrf7iyY5eqW -op4= ------END ENCRYPTED PRIVATE KEY-----" - set certificate "-----BEGIN CERTIFICATE----- -MIID4TCCAsmgAwIBAgIDTFGwMA0GCSqGSIb3DQEBCwUAMIGpMQswCQYDVQQGEwJV -UzETMBEGA1UECAwKQ2FsaWZvcm5pYTESMBAGA1UEBwwJU3Vubnl2YWxlMREwDwYD -VQQKDAhGb3J0aW5ldDEeMBwGA1UECwwVQ2VydGlmaWNhdGUgQXV0aG9yaXR5MRkw -FwYDVQQDDBBGR1Q2MEQ0NjE1MDczOTYxMSMwIQYJKoZIhvcNAQkBFhRzdXBwb3J0 -QGZvcnRpbmV0LmNvbTAeFw0xNjAxMzAwNzQ4NTZaFw0yNjAxMzAwNzQ4NTZaMIGp -MQswCQYDVQQGEwJVUzETMBEGA1UECAwKQ2FsaWZvcm5pYTESMBAGA1UEBwwJU3Vu -bnl2YWxlMREwDwYDVQQKDAhGb3J0aW5ldDEeMBwGA1UECwwVQ2VydGlmaWNhdGUg -QXV0aG9yaXR5MRkwFwYDVQQDDBBGR1Q2MEQ0NjE1MDczOTYxMSMwIQYJKoZIhvcN -AQkBFhRzdXBwb3J0QGZvcnRpbmV0LmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEP -ADCCAQoCggEBANj9KNZIvtds0RW3A9EaUXjW4HWNKbN0J/zdQVyGID0GNezz9Gnl -wTpCV9o8rXc6g2Us/5ZrXY3tSUU9wkpMs0wSiqbSNutq/Xci2957JEw7Lp7D+MpG -tkkmqxK/ZLGjhHVrYQgzH1p74KK6jqtCvJ9My/vj4t8YHWHVh4fxV3M+/NdgVwRI -7+FqXQHpuHoV5P7/tSMLQts7JEXujeBKO1eFGTNItUoayeWdq9bUM3hdiadHLfdO -SrpudtO2wc4TQ5qvaC/nDzMjBq8tP+t99r8A0veyXbdG2jEtIFNJfg38Kj3fQ/5/ -ZNhtrJ3LgyrbC9bgeKIkQ0Nwr+sHUFmWmlsCAwEAAaMQMA4wDAYDVR0TBAUwAwEB -/zANBgkqhkiG9w0BAQsFAAOCAQEAzljgZ5CmiIAlNuuFnjCdDDZZTgTobweNxtPl -qVxUWSefR9NeQ/WC9sZVd0+rp1QCfZYJacrISdpwXfROmjALJve8cSS0ovqPw/ZB -XAVsDXfQ55SASIy9fsXOiemJJHSbXG9amZmbwCCcZPeTqZb4gmHnWxrZsJ2hzWh2 -soxsquPagZg+3bvxJQlkl3Gxo1dyTDzzEe46DVTYVPhbADyvFYwooXc4EUMZ+EIA -nz3k3pfXTnITDESWqQa/Vv2xlHuyqYrniwW4oyQyo90syVsDBP5QCsXL7IuwJ771 -LSaT4apGhhgPqvzPi8Pi4kWEcNQKgvARHh2L+oSssVMtzvc0xA== ------END CERTIFICATE-----" - set range global - set source factory - next - edit "Fortinet_CA_Untrusted" - set password ENC PixT+x8i3Z8Mbf9PJ6cXSnP6SZax2wrpiAS37c352bOJk8IJIbC2bpB7WDeR80hibXI9QBmr0lS2m1Dh0oqE5sNZWMzGfHCy99wN/QihFaaobpS3NkTs35xqMcr0zKc6ktdRo2N3+SHjKwUp1wCT3kIBJZ+PDa3uFd6hOlF4MsZg4EiAvY54+9HdPE7fhTsz4Hc9hA== - set comments "This is the default CA certificate the SSL Inspection will use when generating new server certificates." - set private-key "-----BEGIN ENCRYPTED PRIVATE KEY----- -MIIFDjBABgkqhkiG9w0BBQ0wMzAbBgkqhkiG9w0BBQwwDgQIM7p4tJeK7xwCAggA -MBQGCCqGSIb3DQMHBAjtkT/PqvBKmwSCBMiVMM7QB4tdRG9sBcrO+xoEKA+3oLCH -MLHIt2fzm2zp8KHacS6hAAzH6D0kKHmh9aviTPVT3E+gLmeyjJio4OehtuIiWV+f -Cv8eWuqsi1XjuX8QFwZblXRBJeQORLIEWM+Yc1JTN+aGDLpEVrb2eRns6N/vKWmB -4kjgObazsTuDld5vzOZyoScmrXEOBqBVbeYDRFnKjbIDk47hD6p8ufXkdipONgu+ -B3G11CZ6AVguy7ZutJNJW8qJpE4GzX7NBIqcLkDzW5AQl8ncBOP5ya5OsG+MEDQh -3pTBJkNiqpODoeqDQxiUGHWHDSEBtj2tKLC8mGJ7Lyz0s7kzj0cYDPITzYAB9N7t -lTGfoIV4f8Hv6ExoNP+dlkHnwu/ZWK41M/U3ehfHnyqj6rqKtnSB2H5AaEyajn+q -mMCUuEw9o9DMGlYOHfJC6eRYVqrMO8FGNFDQIB0GBka3rOapnb3bsfqIVu1kwyMe -YKWbu+GbAoLBKDcylg1JLdSoWOSnEU3d/VxX9isJOlBQ0IqsjjYesFDDWjfJZinm -OeCY8eg/AKINdBoVOLvmdItDQvD9UAaqMRcL9Zu18hucF57422Mz/x8kBdYKjRdY -7VkXeJEXcM/8niSgzDT/AClPUYM1Oe/k1tMgYiBZ6IB8HpU/AnlN9nl+LgbcRCS1 -ykcxOAVoBySffsKOy5P2jYvkA7j+5iAjX6UuCxt4/XRL0wwBhbdrbrWqVD2svl59 -Ri+8wTChBP9HjWIP+jvO0OJbaWTqy3IBX9Yooo7jY1MIHYf+smxgklmfEwB1jv7Y -+wxH8RE+3YZU7nxpD5Ew12QKAlstMBKr5uj/XPSF3GB8FlnBgrdFKK/OI0copRZX -44ShcPqtTVqg+YQw8/eEhDVZAd5SMEO/K7q2lTi4EI612RyLP1h66JMK46rwv+fU -L4VBsS5h/9NEgB0bp/hVGCStXOadxrhFe7vsVzWhQ1Q0OhWHMwq19qQksrbMvn0v -NyeT+6p++/uUxEbe9IHq1jdEXNLs+hyz0pPccUcGehKbSIdS0pbCK1Z0cerWh6g5 -jyO4ZEYtchcHl/DJyS3BfdiGRWYsb5yD33WSMXhZ+sYecAN5NhN+Bg23j2fF7P25 -fHHAB6VW7XqnqOuVqA2h+4BqrmBz3yzr7DxjvVSncVwd/m4xby1F6tGnSYNvIqeG -8Tyi2x1aqDd2qepjBEqsRjyZsyDoESz4FohBdoufgkHDuG+8GKqjIc040cUnD9NU -umjKpnPAuw7XcHkYHnGI9Sy+RZE+fEp8n4lZ59L/Hi1thIS4aEhvf2lAQaoT3PqV -GLxR0fkOhwIhZXK8ph85SpAHCT2qZy7R+GLLfXqtN1Eb4TCJkPCtDC5etXprkf83 -rV9QopafgoekYHLY+8hRCbzfQ117Q3VphFsL8f7c5q97Tu5h40YkGveML1N+oNdz -0G45JV/i8uOMq8TNdVNacS+VFctyUV4U7LjbU+5MzbYXYQ9UEAEooRUSDHKMtlYh -nmEJ+xzXQyJjEp30/fDvC2mMCRpjQczuL1E3Ta5mbDvEJcjXxRAr1Wv9YZsZjfL1 -NBaJvHOLFITZN7kSa9FOUIna9WfphsDrLyeW72rkdvl1fjaNM46srt+LtlT2g9rT -VPE= ------END ENCRYPTED PRIVATE KEY-----" - set certificate "-----BEGIN CERTIFICATE----- -MIID7DCCAtSgAwIBAgIEHuEGzzANBgkqhkiG9w0BAQsFADCBrjELMAkGA1UEBhMC -VVMxEzARBgNVBAgMCkNhbGlmb3JuaWExEjAQBgNVBAcMCVN1bm55dmFsZTERMA8G -A1UECgwIRm9ydGluZXQxHjAcBgNVBAsMFUNlcnRpZmljYXRlIEF1dGhvcml0eTEe -MBwGA1UEAwwVRm9ydGluZXQgVW50cnVzdGVkIENBMSMwIQYJKoZIhvcNAQkBFhRz -dXBwb3J0QGZvcnRpbmV0LmNvbTAeFw0xNjAxMzAwNzQ5MDNaFw0yNjAxMzAwNzQ5 -MDNaMIGuMQswCQYDVQQGEwJVUzETMBEGA1UECAwKQ2FsaWZvcm5pYTESMBAGA1UE -BwwJU3Vubnl2YWxlMREwDwYDVQQKDAhGb3J0aW5ldDEeMBwGA1UECwwVQ2VydGlm -aWNhdGUgQXV0aG9yaXR5MR4wHAYDVQQDDBVGb3J0aW5ldCBVbnRydXN0ZWQgQ0Ex -IzAhBgkqhkiG9w0BCQEWFHN1cHBvcnRAZm9ydGluZXQuY29tMIIBIjANBgkqhkiG -9w0BAQEFAAOCAQ8AMIIBCgKCAQEA0jqUKDC7Zl7pw+Sq6aYUIzONSsOAd+V4B3rS -WeBoJWu57BiabRwf3eXeNpyFVvKWvUECUNdG92fJJHX9p9yW/+EjMUhwFX85cC1O -b78O/n4Y2N8jr318Wl8GGtdoCSsXVvJuUm3DIF8BexkjSYoIqzPgSAutH+ZaMssx -lw5u328YWq9VTTJCi1jZMkfSIMAdIerJtvnX4gwSLATJ2Z9Ganav/9+/iyzgUiD8 -395z5hCxLh8Kgn23jGV/V3AXZgQ2tBCsZ0dH4YswzFSs9CpMbYOIy57AGUaiMPeo -0/kDOybSHeFfLN2IQXil0kwcYCQX8lCrsA6F9ER5XVuJ5XpDywIDAQABoxAwDjAM -BgNVHRMEBTADAQH/MA0GCSqGSIb3DQEBCwUAA4IBAQAItgnIjTXno8Z8ilLP2+db -e2tAL/mpNjfHIG/Na/Kx+T8Wou3iswP+AapBXx/kD5mPpylGcozHpBD62V7XK/V+ -Grgfa3bhosBof8CZtQyiTdj0+ZCiXbAOlcyoxZTxcfmzCZXAKu0QVCjvbBbAOUf0 -KEVzzIeG5QkS1v5nINqDVxAiEuYS/B1ky4UwgbEQAKNxKypBg+yCczRAY/99RbCu -qt2ikwgMFAhY4esGlb3Eb1UYcqqdweXroWcnPm55v+XeQi6fI05UU3UwUuldAytW -75lX+KFW/+TV6MQPf0SziWET/jB+tOOkhZzqpbJABdXH4NNHAxngKVAE30dFcZAt ------END CERTIFICATE-----" - set range global - set source factory - next - edit "Fortinet_SSL" - set password ENC P9hD2nZ/Kf4eA8aFylZyFOPEZf+fqR6ae3Hsc3fRjws/sicBxq7BozMNlM+Zi9OQQdCrLgqqyvYIo10ksqyiISSrWgCSLwRJEAMrbFy8UiafrgC/34+RtAWcDjCUPcinSEnF7VPunlAfFlOHFjXO+shnweI0GcgSko3M4C0yhd/7W6rEcZePld+oKlHUDoC3HQRz3Q== - set comments "This certificate is embedded in the hardware at the factory and is unique to this unit. " - set private-key "-----BEGIN ENCRYPTED PRIVATE KEY----- -MIIFDjBABgkqhkiG9w0BBQ0wMzAbBgkqhkiG9w0BBQwwDgQIy19/6owCFSgCAggA -MBQGCCqGSIb3DQMHBAihRF7XfH0WEASCBMhQQYcF7oZEw1GTvWHYBgnR7MaD/vsX -VjRBDDhaY5Z9F9AN/y7zWrpUau/qkswAGfzirH1eHXBpnTLpc8L5dQvEyddN4Amn -PBXEy6iX3iK6S93bzmgHhaj+CWSGkeoNcwAm20jbWnrN0eUzkZm5eX0s48IeO7Kx -cGHBd5HkqHbIHJR97UYD+L1aTPgIR1V9Ejp7Fd2x29dCkknfKXU4oG2Jw2o4D0dM -tmk0yqSLtTYDfOvlKCIK1GyKfNOOAS0AzPF630wKk3q353dpza6pbDETqaNu4Nt4 -Le3WqiJ2pNwJvAcowoshraOsB6uY1botwoT6bHnYuILLeP6+cMtRJEYi2NoaPhIu -Ga89vPzNdHlge6qSaDmRY+4xpoxXnV0Q0wa2sOWooWcpwH/3LwwkeZn0g3ZbMESs -lUu9x1U3Qcn4eOAzsA66XuvxITSq760hOYtaCmE9vXTIPJOfjnmpo67elwfzavj+ -UWtZ0QHChCu1p9Tt1BA73byrlqLUHIxHU774qh/ObvhkOqfVZGz/g688wvlh8/p4 -5M23HIpf4swOiS/d31iV9r3i7hvEDh86o9LQv3355wnPAYD7v0XzkPwcIy5+YW06 -Yt2qdbITGlrHyDnpDHcK7rorsV0WPATykoOqDOd5cg7vwtM6O90vxNxTaWe/rlEi -3JmltWV4eczW3hNls2MV5dNrlXCT5RZ/g+HmyDiMGdc9se3QAPN2uxJ86Gm6/xN4 -pKfwZ5/RUeD6sJ2p7NOTbz0Yud7j3Vr4DusRoPnwY1on8T9YTMjckodKdDxFUnGr -uzqU1GPiJSLVvvH5Jy9xCSjPGCSnDS/Pq+vR1WBW9ppJ12mBLeYZgQiQpKHplZ2m -NvAKEIzRNtsyawkN9CwnA9koIKpNT4HqOu9k7fT2bgNgLMFpRXolNXtm7C4xOkDm -rKef3PE2jPeZUfEoF8u7gsdZoJ7o22zw8VWmLrkXgesR7fxkydHf/uUXtqooktJZ -PQ+qFXP3EJXPkCcqz/lGO/uvM2w6fOQw4BeEL//+KsqihDXVm+4cr9RpB3nTBCPY -lJM2nylOgQpbuKOAnUuaTT8sfucIXNqk1/6Q6MwTM5W2oPNxMaeYRt7yYWaYk6Uj -tjEPUn0ezv1q/8DcPtVOMOZ5a6y8glw7GAUbs8uDzkfpQMoihW+8wR4Z5N5b+STS -4pzl8NLTl44F730dnPqo1J6wKcx44N5/GiA8FZbGGkWVBMBHRYOvoESbpgiT/X6i -ct735lbWYI864s3uITLl2mBOh8lBp65V/1BZEucJiK3cGLfVOCJUGnT4sF0CNgIL -kWIo/qq2j2YhEQTgV1ob2CXei8PfChmgMCBgolugnQnvXW2yFLL4T/edA5fqkjp6 -I1LM8xWnyTIB37bWfbEzrzCfb+Fq2CShBuVtfWMWp3GwPwbsA349YcNnQhDEqkEy -JOrQog4+rPijaYnOqnyIl9XcyzGs+BISYbHbIYc6FwhfSh4UVCdlbuScQ0fKTvey -na6p8IkAFzReGA61lwTFcsZ+s3ii8u0VTJhJj03NKvwQnDwgWl6tKd95KpNFu+Th -P+r2QY/3JQ0Rvb4hGNLTJ+TPGGmxY+ORPuz1DIiF021hTRtlRGDVqXVOulNNca3I -pYU= ------END ENCRYPTED PRIVATE KEY-----" - set certificate "-----BEGIN CERTIFICATE----- -MIIDxzCCAq+gAwIBAgIERFx4ojANBgkqhkiG9w0BAQsFADCBnTELMAkGA1UEBhMC -VVMxEzARBgNVBAgMCkNhbGlmb3JuaWExEjAQBgNVBAcMCVN1bm55dmFsZTERMA8G -A1UECgwIRm9ydGluZXQxEjAQBgNVBAsMCUZvcnRpR2F0ZTEZMBcGA1UEAwwQRkdU -NjBENDYxNTA3Mzk2MTEjMCEGCSqGSIb3DQEJARYUc3VwcG9ydEBmb3J0aW5ldC5j -b20wHhcNMTYwMTMwMDc0OTE1WhcNMjYwMTMwMDc0OTE1WjCBnTELMAkGA1UEBhMC -VVMxEzARBgNVBAgMCkNhbGlmb3JuaWExEjAQBgNVBAcMCVN1bm55dmFsZTERMA8G -A1UECgwIRm9ydGluZXQxEjAQBgNVBAsMCUZvcnRpR2F0ZTEZMBcGA1UEAwwQRkdU -NjBENDYxNTA3Mzk2MTEjMCEGCSqGSIb3DQEJARYUc3VwcG9ydEBmb3J0aW5ldC5j -b20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDFNki7okrg0rYLvQd1 -IUaW1cPdlbzkYVrU56xA9S1HeQfb0u7AAoukwP9oL4qWzeQaywF6/XM/6UurtEZ8 -JjKZ9z1NxbfFmWnBQL7U2z8EnBgz/LS57c5sstbHau+c/RxO5fM+Tg3Jo32S1yu+ -ahihH41YLMDOKG2rCrqeW+Tlrp5vyHM9kFT+AGsrCzO1dGBS8cHpBFhiUqk145zD -qP6L5S+bh9ON0b4e2fkDdx2O3fNUmVswwYVSSgKXqrCtKViirWIRQ2ey4uIXqFw9 -FzLRbqUUOq2qYC/vLz7tYig/OYt/GXze5zM/bxKA0ls43s9xPo8NOlvSBD6jRX9g -wDfbAgMBAAGjDTALMAkGA1UdEwQCMAAwDQYJKoZIhvcNAQELBQADggEBAJ9x2m/c -cePINfGCc6KDwpmDQp+2iibM2MLU6HSzZjsEBVhIa1nxWt+Z33IUS5d+ctHVdNUR -WX9U2Q7SB2P/KPSnwigBhgI0bOP8ovS+ZP6r5f2lLGrRrq20GPEO35TQQDocBljg -090Mdu9z/40aaGHk7iyMOd9Q7UrmzEJvN3TNr4A8rLcauakzN4wosi8zxq4l2ks8 -300BViatR52qis0AT8p5mYVO1J7TtWRUp2LgxP25+pEQRH0x8lKrIXTfX5Q3QKh1 -OF7RFW0URqz0mf6lhoXSAaejz6EtgxeAXtz542H7/6HVhjc8eTPpQyilhNrKuNGx -Ho3i2nIZIWJ1RJg= ------END CERTIFICATE-----" - set range global - set source factory - next - edit "Fortinet_CA_SSLProxy" - set password ENC m6TdlpCFptM4uvBmJFUCaH84GImxIEFw/qmpWl4s5Mmv7MmUjDvoCklNhXrd7r9PXe5BzW132Ybn0DllaQO0wsOybVC0JEWU1NTvt+3bwl800779+Gfn9dOj6LdyjbBKcEvB+a4GFSzU0IKShN6lYsku1KPdkMK8X3b3sjW0bj0UwDrXdY81gtzh5It+WVYxD4w7qw== - set comments "This is the default CA certificate the SSL Inspection will use when generating new server certificates." - set private-key "-----BEGIN ENCRYPTED PRIVATE KEY----- -MIIFDjBABgkqhkiG9w0BBQ0wMzAbBgkqhkiG9w0BBQwwDgQIBP2rB5RxmaACAggA -MBQGCCqGSIb3DQMHBAjy6HWtzSM4mgSCBMjegRXb2qew1cB3Yzj3VyrE8eMNXBC6 -83qOoI3tOSdYjfSaxGl2AA59PaEM6GslLtj0rC3unjzTk0qiVG2Irv5JGaKrxCJ/ -i4hAcVDEdlrmFSJ3AwULn14Ia6XiPmyy4Hs2gex/LQKBmETKbSpEUu/b0PwJkyqI -V2jJclYWzoPIBGeNU7F1KjYMZu504LiswhxqIHttdye+I9JtmKbCJlRpdln5FMM6 -NOKbc/xby4Wdyyl1bityo85t8UOG9nI9SRHct3GET7sWoiZg2Az65CRvMLS3o5// -3uk9qEatfszUpnmZWTODO23B9g6tCrf57So0LjYE3m4PniW9LYxVWVOiQdqNsVWx -7V8IrscykoxhsdIuhosdFkscsi4wXMWhNopD1gN/cRKCx0yaU0h5fhvSGILuG/Zx -lId7KAIrBnuMHLGdBrhPlIOszghRPPcqiRUGbt1Qr2VkYG3WwYZDvhpdKT67TJid -+zZQOEzr9nhOIcw57xdRUjjcAAINsWa/3cduR1RYWxyyg/xeNHDr5+1SFhL4FPV6 -B9dt7grgTKZ69/1a32ticfh22dhv6FzoeQQqDdOpquvvdOJOScGl/IdO8vZH+2+E -sanwRiFj5eO9tTZkYxU7gY8VY2PLC8FE33yEvxarUj1DE2dV5cUMYXBkslylKwqi -NXHOPinRkDTb9X51tZlbssqbjFUOahcwcR/g1VRjV5AAOEvpsisSYyAx+HDrcPsq -JeGbr5fVhTIQGVMOld4EETsqrSIWQ6gZmFqr7BYXD70OeS8xnFJZ4mfxFHwVB0Gq -6jvvhnB+q/VqMYuohJuo9i7lQPJGcSM824JaEG2sdmt5BJekm5nqybd8KFMuwhzV -CDhDtyaWzZnm6dHqEHnXp7P5ohmb6BRYW0KIEQkwbyB8/pQTmtv6m+Qjb4NiJbl8 -/xcCZS1t/n0MngmQHnOZysQ0yxlEegRCNcHGxaWMJJJ0w3cAldy7VTHMbOqvWAtd -jHrhep6GA6wgqLRYfrY08kZV2wpzaRyIMqE7MKlw3UnOBAVHwMoVtLhDAS89Y+bR -JBwZ7k5in652gAO+bGxnNSkmZJJJRt0Z8ngjKR4Ez6iaicz0NlLE2J4Ku+6LfgI4 -A+nBYzA/6ybntm4PvBLDo9ZPoZfuCKPLmvmywV61FprRNdebhxk8btlTSzeguVng -bMjgyYp791coe9HV00HzETe5EWl8s38DrsSZ7U26oYIoYBolgaFLENdFNJn1i3/j -CkXYaHtVj2BsVMPKu5zqzF83THX6LY+RDGUcQWboO1fbu+L83B7/P4DtLCotHabA -iXO9EP97D4o126nSe9lc0xVg3NQFXk9ngHchEKZabpUDFPY0wPz/GPhL+mtz5zqb -IHZfdvooJ1JLHdLt8tOBOmBhSy5SrpXfQSvx/VmL4+AnSp98a5gGgbIvxsU/5NbQ -zgwT8lCtTtuAZm1oM2O+wkBYnrjR6MpYu7XD9Au9NC++amXdknlCHgTmNJHdFv7S -AN/Uv4BpTUtEm0ZCzTb106sUBSmUOsV6LaoSjvsdql9gyPtFfEnIpf80y1v6TaKX -uqCSIaVPaw+m5QAiAmB1gti2z5RWBS3yJU+W6Ybb7Aw9FWQN7c0YiKjfz/QZhdWk -21o= ------END ENCRYPTED PRIVATE KEY-----" - set certificate "-----BEGIN CERTIFICATE----- -MIID2jCCAsKgAwIBAgIEDokOXTANBgkqhkiG9w0BAQUFADCBpTELMAkGA1UEBhMC -VVMxEzARBgNVBAgMCkNhbGlmb3JuaWExEjAQBgNVBAcMCVN1bm55dmFsZTERMA8G -A1UECgwIRm9ydGluZXQxHjAcBgNVBAsMFUNlcnRpZmljYXRlIEF1dGhvcml0eTEV -MBMGA1UEAwwMRm9ydGlHYXRlIENBMSMwIQYJKoZIhvcNAQkBFhRzdXBwb3J0QGZv -cnRpbmV0LmNvbTAeFw0xNTA5MTIxNzQzMjJaFw0yNTA5MTIxNzQzMjJaMIGlMQsw -CQYDVQQGEwJVUzETMBEGA1UECAwKQ2FsaWZvcm5pYTESMBAGA1UEBwwJU3Vubnl2 -YWxlMREwDwYDVQQKDAhGb3J0aW5ldDEeMBwGA1UECwwVQ2VydGlmaWNhdGUgQXV0 -aG9yaXR5MRUwEwYDVQQDDAxGb3J0aUdhdGUgQ0ExIzAhBgkqhkiG9w0BCQEWFHN1 -cHBvcnRAZm9ydGluZXQuY29tMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC -AQEAv1BkGNu1LqeNzbZOYubi6hKstJQgVQuIE1EWsd3luzEnyz6lGefbf65Xad6c -gH4zN17QtDy2JSS9Ccmt8KxQjtdMQeHvFvXXvKEXzfwyIrTrFAbyCp2S42AQ0tHK -+NRaRE/HOjx4kV/vLMqDHgWocuJWPPKfSkKtn1+chn4/sLbuygSXtGjDsiFd+wSu -MnLrpEPSOEVQtU3M5HZZKDdT7HG1sP7gnHsg/kHr1+8PXna6rKktBq59geCu0XCd -uNSFM+wU954dKrYS21XO3fyHLIy6tHP+P3+qg6/dmHjX8LXRBTJX2eRirq+NLSis -tG7ZZeIHGv9SVl1B0yk8HbK0IwIDAQABoxAwDjAMBgNVHRMEBTADAQH/MA0GCSqG -SIb3DQEBBQUAA4IBAQAOQdcBqZlQ9QabxwRK56bFfy8Kyv9MStkFrMG/bqaXEeTY -AIcDOZidGihTjH127kGOIA4Rl6dzC/ck1z8ylqRhMi0MkX8VdyY1vxFAKmu8buN/ -HhQA0fJptGDaYScGFDb0wOnyoo80dwosaZvXVrvl4WLbDek4et/knhe8TohsqfuZ -sEwh4uatiemQWFjPcqRJSa3UiJjQGqr9ufbP8dsGT8kCsoZPED/H9Ot1P6RFrZiC -wsfiXWX2XWPSft594qnv349oPjzyLmQh1E4BWVIhMqk92k73abZszG0fGFrEY2i+ -HG/8qCkgnGAbA3rZuQGd6ElRa+cET73+VNemXabr ------END CERTIFICATE-----" - set range global - next - edit "Fortinet_SSLProxy" - set password ENC zDbw3CZpYvJ5oI2l88MhOicytFx8v01Trhs6qpH+pnN89BPNcTSLRnJVJQopwi00yYka/1qr0+52h2mTRovzpAp7ucZdMnOe0HKcnW3t6+JzilkuU6b+N301JVmQ5EWc6wb6ai4DH8J8a7s5rat+GsXcENbnfAFrD7+LRvj9GGsJBsy+YO6g3zf1mpQrZM3nz/AaSA== - set private-key "-----BEGIN ENCRYPTED PRIVATE KEY----- -MIIFDjBABgkqhkiG9w0BBQ0wMzAbBgkqhkiG9w0BBQwwDgQIi5rGNa43QmACAggA -MBQGCCqGSIb3DQMHBAh7pmECUoPrCASCBMhPH0QROOPNoVhjSMmYrLt+zm3oW2Jh -QpyoO/w8jV1r4GY0qFI0dp+T6ZyfBqwMl3jdSqjSgghb1tlKsFcr1dQ4NdKGYt6v -RCT02+S0TxD94JPcyPlEK4FjkBdE3bXII9nxTGTXg3Nkbam90cUYOw6JW84BkxUH -Q72jksM95VpFfNz+ib0X4yyBy39wFxdQHic+uU36nRf0qf5E9ndTUO8vNHNP9Pow -vnXZLIp4Qpv9DnTMjwCIwfU1iIP+2fNXd6BWHYbIsmnlkIYgJi3KOgwN5c7L6wmA -nzZwo15lX5ivvgyryzVdmzCboDfb50Bk3kLVLRn1b0uppFqYA8Gfild5Rl70m+wC -N5btmNZ2PRdW8eRsPGRXbTyoEZacYeFPT/fNMUUJFKo3EEOgVKMIczaKrdARd4jX -FcnZP20W7ThR7AlZsHeooiM2/PRIx53eRtRohfXFCT+D0QZ4iTXx5CPPCKsvHTrX -ZFg9s7zYXtEIcGe0n3SUe7Xz8e7zngBQPub21LtpF6pH8kRFOnrUCR3yr0W+5B/O -nz2S8s6yieWckEiyODP3V2jELVoczzAlI4lWxsF8Iu5JG5qVOawH+ruUxFZp9Q80 -8AsT4geaYO+IBNcCTXescp7RxoQIc2n3BxC+GteZ0SEbjAFiIqSlEhh6Bn/fPgib -iiXeeiwL2ypvPb6NWmS3lFNnruX0g6pAUNRrPLkXqIP1g+gE479wWYzFRoJG2W+r -BWxcn3w5B+MlURQfejCbGPBw4z1CqgmgHqhsXIimyNtG5yORaXHQjjssHOiZKujA -bwjUtavydZLeoSQAurIoUUqOPSDMQ6Ijuc+nnpGyEIyr/9ryDaqMBH0zAaDn05sb -PhSHlYNlSboD0onPIQ4Yle6IBTH8ORsZuzhb7GJzNku3dYY70iXl3FcIdZy6LDbV -TVdWEiKCU5CR1z3t2LE/+J6jsLhLmxlAYEo9DsMWiAP4nAnfuDKoRCSKDkavxCNK -LjAe3vPsLz01BuL4/9r8yfjAWwyJrto939RMHprzIyocXcJPCVUajc5g9ylbFoiT -DPr8Wb/26kAazKQj+2zBhgQO/aJiwp/Iw+mK6smm9ifIvhi1vTeYa/sTkOElCz2o -Vf5Rzdp0L48jmpVkEWQpwkd6RRclyQDUtrE81C+ok6XHqZ0TSww1rr8Mxx+aAWT1 -cvP4bp0nymK+xrGN2TgbfW/SCVoYeH6MxWnn6VfnazR/mbnFzg2ULm4lYnNUoLxV -0Br/rqlufMzIa0owGzPtDhb497PBiBvhvHjE5IkPUic88c285BKuvX9GbrbH2EiQ -ZNEYJQ5CkJWTW1m5tBINzO30fMpC/oqpojdmSEKZ1wP/Aq1T+caEZn0QDe9qN6Tu -oWemDalTfXt947fUCC2vpNAE4+zt8AiinqevO0zgtsEcwAzKpUmwFXI90wEyMjsk -LphgMJE04zCgLS7YWSw0snAgAhv00ucCKGUNhC78Uk1hL2h4KB64aaKNl7GwfjnQ -y3XpNGjOKWJDMCGmN9w50mWo+28gu2CCiVE2aY8wp5oUzH4MlyprbsefJJLFugDi -zDe0xJ/InvTYUXrM2E0ukyTTaBBT4IGz2pLoTTlKZxNUcdhWLXfIvd5FjiuJ9MTr -B8w= ------END ENCRYPTED PRIVATE KEY-----" - set certificate "-----BEGIN CERTIFICATE----- -MIIDxzCCAq+gAwIBAgIEHLWG5zANBgkqhkiG9w0BAQUFADCBnTELMAkGA1UEBhMC -VVMxEzARBgNVBAgMCkNhbGlmb3JuaWExEjAQBgNVBAcMCVN1bm55dmFsZTERMA8G -A1UECgwIRm9ydGluZXQxEjAQBgNVBAsMCUZvcnRpR2F0ZTEZMBcGA1UEAwwQRm9y -dGlHYXRlIFNlcnZlcjEjMCEGCSqGSIb3DQEJARYUc3VwcG9ydEBmb3J0aW5ldC5j -b20wHhcNMTUwOTEyMTc0MzMxWhcNMjUwOTEyMTc0MzMxWjCBnTELMAkGA1UEBhMC -VVMxEzARBgNVBAgMCkNhbGlmb3JuaWExEjAQBgNVBAcMCVN1bm55dmFsZTERMA8G -A1UECgwIRm9ydGluZXQxEjAQBgNVBAsMCUZvcnRpR2F0ZTEZMBcGA1UEAwwQRm9y -dGlHYXRlIFNlcnZlcjEjMCEGCSqGSIb3DQEJARYUc3VwcG9ydEBmb3J0aW5ldC5j -b20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDbdA1aeDvH1lx+81bi -oBn5s4J0w95jAKCt+E1BsFnFMEO4uXpbN9RC49OU277X0an5o0oCbZ1kERp/23Qs -VkAGX6Y8rjzWCHc+Uuw/2b3WdjEqcQnDbIEQnl9N57F4EAc/wX60BN08jng5n8lW -SYZbgECdCq6frFdRGCa1oHKd8fHgyzEC0lcsLJnSu+A51oINfcqV3Ggsl/sgZahC -mP4L8OkHbcpD+mJio+8bZ+DG490+oPaN05WSPQ3kjw6B50f3yrXSYsjPoLBlOlah -GSz3bXZc7uZZyBPXsd/CaA5ivEPUNmh9HNq6alu3rjM1UPB1VfuMhRS2TOJ/ljpt -/LUDAgMBAAGjDTALMAkGA1UdEwQCMAAwDQYJKoZIhvcNAQEFBQADggEBABJetvs4 -hk44A5rCbg6Cq3l+Vf+dxgqDTyC2Yt3TMIW8RQYqYDDvRJIGND4G12cmuE6w4mxB -GcS7K+nCcFk/fvSnHc7Ec0RSxUoDqiOlspAi3NNcyCw/dekOXIjnEdgSY8gNt+eS -lAw65pjSBBbUpLYXQEEpx7oxQZv2Sv/LopdLu6mJ4a3xOS7jYMFf6ienb9upxKzz -xTptBUNelN30G4YDFMUQANVZ+o6MyjaJIo7RgpuJb1HQwTcb+hANK2SIzHxcok3B -3I6ndjJ4xZwYROIYcVv9MKMYj47XTqVdVJNncrU1M9u4fjCVuVB5wTTgzdr5XJ8I -qJsp2d+xby5kqc0= ------END CERTIFICATE-----" - set range global - next - edit "fg60d.ffm.cactus.de" - set password ENC oe4jR7h4vdsf42sgI0Tp9Zir68hqWLA4CQg1jxrqJzyusHNY6+KQSz5S5ZkFKLeNyLWtPWIdHw1F64Q0GPfuqIa3X1T3vhgYAeU6KUHddMAoO2gYPJyIS9r9BZpVIk/xnvK9OTJ9hldHKic+Fj3pO/Wjuy1fYtsV3XkTigDDDDr417+hH8xPuYi7xpZL4gomRzPSUw== - set private-key "-----BEGIN ENCRYPTED PRIVATE KEY----- -MIIJjjBABgkqhkiG9w0BBQ0wMzAbBgkqhkiG9w0BBQwwDgQIhSBPRUCeXD8CAggA -MBQGCCqGSIb3DQMHBAieKjGDjC24iwSCCUhmUuR1rCvczjIuyDBVgdAifltipnPF -DXD446RtwywSFws1jYSDMXNRx4E73TWPJxR7LD5wME6fXhiDCu2Js/qJS/FefAnh -GKkg02UwQs/pewvyEq1SXCjdXBHapBGi+sSuACpvS833bJi8qxeB9PWKhqwrvyyt -LRyToZjcnOYtjwN8NCTUr2vG68MZ+Hp2k8DsffQEr2k6dteFtMaNHJj86l0frYhA -2JIEhFHo9qPjlK1nvSoojUdPQy0CWSZPOscwOXMCGmvy++RxmqqDOwLHO3CKToTg -BRsnDUTckS2S7pos5CXilLv294yzGcxywvR5urTvp10IXE5ssrgfKE0yll+XquKZ -7Qhni1Mqear5oLKF/iZFEgSICJT13wfzmWvFY9motGAu/Hr4/izFS2Lcd1nIRZua -1JaTdqJnOOiBlmjdAEfV3uE2RfioqBWvEp1NJB1WkNx+lCXfGpVyiIVuoFSKkmQz -sPIcuHPnE2F1nxPiZEsziHCYD+V1mwMsW5CNr8Hs+Saw/nsqKWzk+iHRC9FAzvtN -T1zrJ6aBx3efOHHs/ZU+7smwVZA46nbqEk/gVTND+1f8jfDUIdn0RQRkLv0ENT4I -tRFPLP0oi/IM3bNLUPPwSrSVTt1fuFxP0C62z9md/cBT8hOjHmMMrdn8kf0BsGXU -1XLgNIhOIr82cBxxZ2hwBg0zXo5fDHR+1ytC/Ox72zLmIT79uC+1vWeugPr/gm5P -zHMPnlv97XBJqOrvQbYODp1GWcHx9brUmD3665AhcGaCtfBJhd0bZjS/Ze+QyCwe -CLEY6LKXkgPbgNkNR43iJFmB7LY04/3JQ4PNLAz+LJCv925aPQMGXZzgzWR7me3q -Fvcbrrb6u3IO8LSQ1ojJCltG/WEM/pLV1g0mktflCtoH7sgToMRMNCYSf8WU9b/b -B5LI9Or3jpYdJklUM7rKGXq0vi2to6K8nJi/DFKaPDq0iXv7QSY8YgT+wzNO4Ejv -GdbAIEWwWVftjs8GoihYsnBqzcqvxcP7WWhK1hQ/k1/kihcvtlsecp3zWXFg8heb -8Dn5xreMui0oe4/sKAw/57HJjxByW7FxlIKszaLxYGqZ8eRrLVJKSkssYd55pdV+ -gzz04cIgK5z09DxdDFI7DCS2CAilhPiDnHyLjD0ts3wOPAJvtO0Bvq2Xqodu+FMa -RqCcdtFBWTuY60jPcsgOnsp7iMmzjcCL7CALJvapybBoCHyGL51n1o/Yg4NbMGAA -ZatThpB3egw3G4sV95tPE+rjrDbxgdfjUDeDkBZl8gUanSBuOZpiJ4rLrut2qsgw -xREN/W9rTm51TWjOmBmxLJU2Z3ym+IArURQNoYM1MN1DpROY5sWf42HXNIhad2Zf -fnhWfai+LpvIy/mYuvGB+6So/+2DiGha7ltmXiUTkDgsM/ir8WbJ4kWpRzjQ5kIn -F/TCUTRF580zMqJXh/fKLCXnncgkxBE5YwO/xUuvgszsstcsgT50qB8oPw/12M5F -Ncnd7NBJvQulM9MD2fnx0eyAnYSp9mw7BlDFTNpXL/QLaG5p3t++Lnr+rJ+rwGL2 -EuFdcN/q9RL3kWGICWtGBRJN1H4dGXlGelnqIKbkgNH/80koV32yjdXPgdgqs0R3 -RZNbxazskfgeyAT6hOkNNxv+C0bG+JNY6PNveV1q5kzy/KsHV//l4V6iN1VbiZEu -T/TPR81RgbiJScfOjQ+L3EsyAvLJW5kVnTWsChfFnJyIPHboYG6K32C7KcKDLNB6 -3fKNfgOLieFhfmc5gIBE85C0QX5Z7q5vz8VqjHx8Z2P43PrA0ujWPUl0BOt2Bfj4 -+nbDTj4p+Tu4sjHTLJO+3LlzHxUQu+G75KdgNsOsPI6hO+WUPNaSvF9HoG/eWpJN -0RiBxg62LdRauoeFBt78QN8qW84c+gnxk/QUkjbon02hTL+1MSjZIt11bdrXXbBP -djgFquzulwoCJDBOWbZyVkZ+tHhrMm43CLCh3sBqy8Va23B7nLoc5yvXZ8KoPLCM -wk4Fxc9eWE7ZRo7gUolIcj38UDcRvyRa1rMc5SZP+3JaY/QhDD5id4kwToW+TVSP -ayDCrY1L+PjjZIWKMNbd+D19ndLJOhs2f2KvzQCDZ+Q4t+KkJqF3ULqmV+yICVzS -xUEZUJMMRItpPh5VCSnPYusXUo2ycYNwH1kcjXuAU3jJcOmVwRidr6FA9UshG0hH -F6Wxrtqpw0onTm0HEvtQd/LkjhplNpriZW40w+T79ytXWdLgTQzIeFrQtNXm/Lfc -uCWsnPbDtMcD+7icAZhubikaCfgkVdtVFQWcm0e1C353ZAsFZKD0NTe67QqoLcaL -3uke+dt1ysuGHXD75zqIfFrZUuT45ICKprOotL9tLM6cBLHZ5NONTBIsOAJ/2XvT -tjNAU3PQeQGaE9LTab5RWXZ7Lpjd1lU9kpdFhOIE7rA/b8GsD3N/7Q3AnRtZ/hIl -FYWAaMKsrbZBksYXVfUcCJ3CHU9Fo2bD/hA4ClGNo1pdfyf/yLchBUj4vCOKeILD -NP/8vIu4+B6MoNou98n1lMfFpmj1yalJ6NHB/vba5gXlzWHGJ+QUaYS4PNr9Z8gB -8SAckgAwb4wbi9yiQ+vJWBc/1EgDHqhZUm6RHWsNy3YphBqllRTLJbB6bSdS1lvn -+42jUWYxA7Z5droRfdXdPSwYNsODyHkyFlfDDWw+o9PeFcDZdXmdr8s5k+IXUUIW -KSlLdKMdKznYsOmcv0vRb0AhaWniOnyRC5SAl+AoKVPJrcQbF+8t9atgy9ldp2mq -5M51FXoHoQuLf6orQtMBiycoZ/Jgv60/aNZEdkE2kVltLYY2C+9xhBtzQAC93kg4 -Rq4Ao8LSocARl4zjl7i3/STozQLkzSisIPxioPcnIJMIMWnXpBrXiHg49TPBZ+SP -clDht7aoXAtA12P32ITNG4Kdh+fO4E7XlcGizTHO0Rtg7vjnkqcfFsKoG4R75Wyg -xztcgrlYLov5l/0XDh0O1baTaDtJHN0QswOI658/IlGTrnouZsvpxejAKM64yPcL -dH5bm2GOuduptwXnKYiZNgbUu/U+/Y4eMxrfykMH/GuK4Q/FaF/2sxhI0rNX8BxO -F9e9j2rZjOnF/SjB+k+Ph5OTQEYT6Wb3Oi6UQgoo8Wtqxs4DoiuqsExUgo0EePku -hNc= ------END ENCRYPTED PRIVATE KEY-----" - set certificate "-----BEGIN CERTIFICATE----- -MIIGGjCCBAKgAwIBAgIIbO9Gi4dAwWIwDQYJKoZIhvcNAQELBQAwcjELMAkGA1UE -BhMCREUxDzANBgNVBAgMBkhlc3NlbjEeMBwGA1UECgwVQ2FjdHVzIGVTZWN1cml0 -eSBHbWJIMRUwEwYDVQQDDAxjYS5jYWN0dXMuZGUxGzAZBgkqhkiG9w0BCQEWDGNh -QGNhY3R1cy5kZTAeFw0xNjAxMjkyMzQ2MTFaFw0xOTAxMjgyMzQ2MTFaMIGVMQsw -CQYDVQQGEwJERTEPMA0GA1UECAwGSGVzc2VuMRowGAYDVQQHDBFGcmFua2Z1cnQg -YS4gTWFpbjEeMBwGA1UECgwVQ2FjdHVzIGVTZWN1cml0eSBHbWJIMRwwGgYDVQQD -DBNmZzYwZC5mZm0uY2FjdHVzLmRlMRswGQYJKoZIhvcNAQkBFgxjYUBjYWN0dXMu -ZGUwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDLPrjx1WlQ0v0thXjd -r92CCAfO/3GTr3O/NM4gAwSQil1Qd/lP6/t09wZk3Jwsw7uqCyRRmHF7xb2zH7VL -rvAKjWKjuuw5oT/ze1yPqubMf9ONcyx7jW2m+GycpokqjiYs7sIxELaHRoiwtS2w -jzq/Sc4OrEMZROUPhn7FQ6nhaxd88CN7D0TzRgg1A4O8/snyNNuKc25UYQtQmH4h -tIKqwoVSET1m3tHD7w/gKgcx1P7mW3dmTYJJ4HkIeHqC8QjixEl/v0vZw4acTFps -o49QyDENn9X3rZs9fOlKr+79a8/kURDjzeE/6a8GvmfY7tw1yq7zHmbBhCBCVME3 -ZtIW00aEfUFoJwPFM3ZJRTDUXwW9vPLl74QzSCE0CjDdIrNnoH2J5CzdMcKQbzmx -4MWOJ3ilwTxHq1mzaIa/5vTjowzWN6tN8udERaWJf88Z3T/7TKqoI/KLxdR387/Y -EmtHnXlg4wcFqEtF+9d41t6Ks1etMWAA4xzynda9oltWcD39otrsPGSVyxQJ8soV -jq5sltk+guvm153QviXcBPxXE3Fm6XGYxwUihna0xrDXWD74gZ8d2ofd2RitMqxe -vMX3HJbkWxUYnWGNPPboa/J9780BlKVREGQyuoeXZP3MUZi+uKKXC2sqqoxbPlAr -gwRCHBGmqbgSxH3enFC3UK63PQIDAQABo4GPMIGMMAkGA1UdEwQCMAAwEQYJYIZI -AYb4QgEBBAQDAgZAMDMGCWCGSAGG+EIBDQQmFiRPcGVuU1NMIEdlbmVyYXRlZCBT -ZXJ2ZXIgQ2VydGlmaWNhdGUwKgYDVR0lBCMwIQYIKwYBBQUHAwEGCWCGSAGG+EIE -AQYKKwYBBAGCNwoDAzALBgNVHQ8EBAMCBaAwDQYJKoZIhvcNAQELBQADggIBAG5d -PzEgwm4oyrFemE0FYsL9YBZ0wVSpTcbDAcgozD2huudaZDop1MVAN4rf2onRQNOA -WooQOk3cufG4CbRg+I3LLCqUJnVgsADx4SwdFXaKucu214I1UvmGRTItFMgXNLLT -ONGPyDe/BObYNrt2UZqqRGrJV/1ZXzFjF8U0AoORm4c5ueT99NhbHdcZRQ+WCgrs -Q7HWfjIgYXiaIr7gMiBMJBbVOwgIuuaC2dTv7uAtbPKWOM3rowOOv7GxupJFhtnv -AnLcwV8jHFnmVO5CqLFF6NnkaSppnaTK1yvjHM/S2JoMyUtKw7SrjYvnDd+mZwuD -incaKq0XduuraKEDmuBvWg2zgg0tr1niVJu16R2mwPJN+0jF5Q3upcQsDPM8NOOh -mnzPYTbdJI+oda0zo1mdYgmzTPnxLD11YHMTjDgO/RdRLojB5L2i5BgpZ0LpeHat -b9M4iiGDCWIC8JmYdYrQCh5gQDALGwb4lX1bonzlrYJU72yG6cL82gi1HsHgzOeF -EYQ6htRZ7Z1rUelsF+mqPyu6Y3KtsJVqjMoyY7ROto4PwN+Gv69E3P8tmRZrBa9Y -HeOEbOGxUir/NYxDHw5RIwX+DJ0LwGM1HUkRPFtORDwgv9L5Uj7qACYa6mSDhmfm -BcUdOQYaR10psPNtFd9LT7HY72JyCy33BtWsD5gq ------END CERTIFICATE-----" - set range global - next - edit "tim-4tinet-ssl1" - set password ENC eZUz9j9Nvu0I2FNWAZ9K8h8cKAmKia6ghWsWMfdeBX/JMLUwQD+9C8cNPGJqjkH2Fk8F2DiceIXDm7vfNXQ7CmB5j9mINol7qscJJwEiBub3bfWU9lNkcpsYIwXbmzkI6D43HOky0IQ5uO3OmbWhxDpNO6kVeV+3h/mHEQdbzACUoP81APPxPZl8C35Sm4Cf73NKzg== - set private-key "-----BEGIN ENCRYPTED PRIVATE KEY----- -MIIFDjBABgkqhkiG9w0BBQ0wMzAbBgkqhkiG9w0BBQwwDgQIuHyL33KIHU8CAggA -MBQGCCqGSIb3DQMHBAirZnW2LXL5WASCBMgKsGd5Gvf0Weeo8yuMQsOEuaawcXj6 -RLkNRqlT48NYcTG6zD97tGhtI1shPnXNq/KqNHVMPoF9QQbyw5/iXdYCrlZT6e0e -g+/UfiaMWwSfloiuF8Yz+MWxNSiUoEt857Dz2PTeib8ERMuxdXKHrLizHPWMxbKT -KCuvUlHCecNi0yDQ9eFd9qVb1fZdqybiDHvdxres4Ikl+wW4sA90kqRRbJBZu66x -bwhjqAFWjHOC+d6FLapqorXx3eCtarjmTDQN5G6m41HY74atWpcdOfS9Z9ZdMvR4 -52fKnfvOuzMccmnJaGXBZlh/aELbgYObtHVBLMvcT3yVAs/yXA5ltUzTaGkO56DY -5ANZ/g2UPzhd6nuxd00xC2ZWJd33D6uPxnlk3C9wcFrPTcIqePExuYWqg6lNbKfZ -eXrR0Cj9gOVT9gVSuh7uNUoqxQYtXFroBuwypOnxKBYDFo0VB5SZAopSZpi1m/Mo -SUEYER/TKURFwMFdRkJR5TR6Zl6YZpu0MDwTDiGOv4lQHI1HxhqLshcWRpT75CZ8 -jNEKp0YfiipXCbYf4ygqqBJDfdUqBHzob4QGuWyX+SYMexugLBoCsQW8cb57Me1h -viF73KGTM27CNJoe+ICoA5j4QmpDG+dw/6BeKlbn7xmrizvGcqcKtS0nk/+MKJVy -GZN1osalXSeRkIh7iWK1Bb9HRaCCcfkRdF78KGX065SCHa/0GVRv9t7DmoCfbjes -WgqhvUR2ZpwOLcnFYRKud5g8yne3PtSjLZ9uAIRCbCP8TucXLPhyDuzR+VLi35OW -8J3VSOBPhOZMP8iWTpcriDJJ83ZiCl8ZPnvjWnAcS9qAoTUp+L9/AOKdh5asz7h0 -70uxGZ8nNjafCPZJsBzYBniB1YhiiIOCe0IPYkF4c06s7EEXu3FzvNq1GKVQPx8E -0lFjEawiDhk8vqLCA9pbRMlN/bNNnPVxiAkkaLytiSDPeK8QjuiCg3r1+aDkkA3O -5Pbutn4ZrPiUIu2g0qJ+p0l4gL0rMP1Jhjcwlh1t3Fk4Exuh5VhlWeURkkIqJdcE -RuyW/LbyYyqDm0Wm+pnxjmqUO3tsBEggjuMAMEOzoqQJenRws4z9jPYHt/n9iutN -UiYLZ+xV5nQ5N7wIgQC6Ub6wi3UhPdHjrLWGKuPZzCxnHQwLWszw+SAYGLn/Qb41 -473vBXPZIXZV7IkerKCrjtxDWyg/dOvaxLODrr+7nSW6W3Dd20c17M+5EpqcdQg+ -UBI6l52faBP9CVCQOY44i/sSwaG0dca5eZDKMdEoVKSZjAj4gpsY1x4naFysKGJ6 -ilTQsGznqd95Txg8VWOITNcAnNkxmVe2a6YYRNf3+M1+bnALiv/CuIfns57HriZ+ -kS9wbU78olazGZ2tZUFl9vBmJC48gsuiX8mdgp4b8g2uJ0ACEaXjn8aVKHF3iOEZ -34+6q0SMu3OuN/kXm+BVyBNXdnOSkyZtE//eZYPrlTbYdDlb5nHJVC+t3+C2Z1/0 -3Iy8iBW8Jycb7xbR48zdOjI3IJUccblXlgvWIb2pMbdZ8V298IYlsv+lkXcIah5k -KOprIQgyDgegd5rN+oQkUDEeHfM2N9mkXNihPG3uIASCAjy7S4O44CopFvEM39ZU -4uU= ------END ENCRYPTED PRIVATE KEY-----" - set csr "-----BEGIN CERTIFICATE REQUEST----- -MIIC8TCCAdkCAQAwgYIxCzAJBgNVBAYTAkRFMQ4wDAYDVQQIEwVIZXNzZTESMBAG -A1UEBxMJRnJhbmtmdXJ0MRkwFwYDVQQKExBDYWN0dXMgZVNlY3VyaXR5MRYwFAYD -VQQDFA10bXBAY2FjdHVzLmRlMRwwGgYJKoZIhvcNAQkBFg10bXBAY2FjdHVzLmRl -MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAt6pScH267ei/D0n1OtTX -U7kufbnz4tgPer3sDFyr/PuNkNG6Vd1YSQG3wa5SVAMwvmOuuRaEPMaYAao7NlYp -ZRXHY4oVgEIfnEIp8u/N5duLgssy/go1p8bRp0szcfHAtP9j8aQPzAAwKD5YFUlw -IqnvF/fpqW/e3pDTqrj8hYTy7oD3TGjf8JXLFXPSNaB7UCDf04nRGBW61ww+gn7A -85OvK/E/smUjps0GTo5vFBe3h3nqvnUUSRnNpibW1PKpDuPKr0DwbZvbbTpYoWR2 -qcnhqFXkoR84HaITxzj9r0WfIWaG1inJ0iIhfRg1kx3f/9tvLNRb/0/fZUV/FDC6 -jQIDAQABoCkwJwYJKoZIhvcNAQkOMRowGDAJBgNVHRMEAjAAMAsGA1UdDwQEAwIF -oDANBgkqhkiG9w0BAQsFAAOCAQEAPo0HtKAD1U6B+wG9PsEsGuRGQ95ze5Y6XUlT -1UsJK6idiXNhETRVu2RbGUJqP6Exq3cXoQZp9Y9uMEirg+fQvF05ijYqlAIoyqci -aPjkBvunmrwqcXsCgd1igxypCRv/8snhO9Jh6URL/gVo/uS0xvbnTc5TsfDP3yJx -XSL+FofPTptPviSnN6dR9Ytsc2lg5v2oJLiUhGZqZJnXTJzeBQLjC4KQYG5Tj2mX -BLmY6CoblZXcvPJ3I3StxX4oRZDHqwpnAxFTlKJpwbHWEdU/gDYl6MdH9bF3uPDB -mG8My7ERT4QvQPdZV3aPbDTVVx2RFQcNRmO+hRvj2ACioUlasQ== ------END CERTIFICATE REQUEST-----" - set range global - next -end -config user fortitoken - edit "FTKMOB5C9735814C" - set seed "b4sEIgq5IpWpq54cspZ7m8giOaIShxjmzxPkyVDOg1UK8nykvCpkq2e+e8DmM0d3cc2GLKe6RNCO93YE+PfE7H8Gk8ZE87U/K3etCj8hZLRqVq/qAnlI8WOrAwr+AxXDDIfvpPfSd0S6BIJR3WMc3Pa+Q+pST0X1/A/C376VZgQmb2Hd" - set comments "test" - set license "FTMTRIAL00728937" - set activation-code "DEIHMHRHYOP23OL2" - set activation-expire 1451220873 - next -end -config user local - edit "tim" - set type password - set email-to "tim@purschke.de" - set sms-phone "+4901715047437" - set passwd-time 2015-12-24 14:54:50 - set passwd ENC uPYS5M2jJe3r+9xUZ6hCiHCVlPIQOuGFAxUfz7IAa2dpyQCkxxe1Aygm5fDSLNQ6la02d3Gd8OwKD95ooXPS3oZFiCu8W+PdQJ8gU8kvfYZhiquP9FIWQbxBWCirvfw7Wv4Y8RznwCp2LZgEpnFjF4cdTSscdn3t+7DCjIYGTt3H3mKffhA4zJSHAjn+yGfhM7MoHA== - next - edit "finn" - set type password - set email-to "finn@purschke.de" - set passwd-time 2016-01-13 19:38:14 - set passwd ENC U0w6SfXwm57pSLh81hgtcZP2zsiW47HCygV6Af8mOsfd3z0czuTfrr/CC/C0HteqCGPQ4F3r9pewwjoQc81APQdq7QjqMnsgcyKcmwZ2FTMRNLynmrWCUEDHnWOMfn33evfYQmyMt5Jnu7FyjLUNY7HHQ2g/zHZ7PZK2bKjdEHLviLjR/V/MTFCtkDki2e6jaE1sGw== - next - edit "tadmin" - set type password - set email-to "tim@cactus.de" - set passwd-time 2016-09-19 15:00:38 - set passwd ENC gZ5x6oIzP7HCpiHhrlaoqGMdb8FVrK2g+7jdZOqb/ceRiu2iTO7i1PEQkoX5UYaJMPtKL7ScjwxIiLG0AP8/LoLLae92a8tN2c2Nt+MWmJZH5XjWNkFaSy0rNVKiUSnRLktEwQealickyQFLmwBLcCE58ISMFHzNOfZUZ3dxeI8547ivEgZzQntBdYjFaqfv5+z5xQ== - next - edit "nils" - set type password - set email-to "nils@purschke.de" - set passwd-time 2016-12-10 20:09:33 - set passwd ENC 6ye5I6kJr6VIYCa83l+CEiKFpA3FbKyVlIFA/2RTPceVs6op0UpSTsV0J0JV0BzT6WizRqgjWekzWXxygiKz1HgmmSSorHl6nSiTntu6WpuWnGkC97AU+Y6TSPF4AUuGXgo9r2TcBrttyrdhPh+Hk+ZQmmnkXVxaW/kEC4W1LNwJ7ZhzEtO7ymQOCwKanTBJ4BYNIA== - next - edit "mia" - set type password - set passwd-time 2016-12-10 20:09:49 - set passwd ENC KvuSh9QZS6A4yXCHh+n+X8KMBEV8f2HYeuu0vSyjT1SxZyuSu79UtqK43Zwn0TE0ehQb6c2hBgRJSx4j4rF8wi/MIVTFXB+8A4/5iNM28Xjg2fUOgJ6GTfOgDr+WfwLVgchMJ3fgARIdlYHbVWT65nfG0LaQSs0uaOAe/msAIu1PfcM6x4OnbC1xiI9ia+0HOFjRHw== - next - edit "timk" - set type password - set email-to "tim@purschke.de" - set sms-phone "+491715047437" - set passwd-time 2016-12-11 15:13:11 - set passwd ENC 29uOZR4WUGY3FK2pSLmYtZxiEsIRDaqQ3rFvQLVtKotGt2VY6ZoZnl2M4nnWEWK0nGWm7xWpSOAWv627rd4tTP4keDLSW3wUih0NJAiBJcyKMCBDKMkFCdxMMkouwxyp/htz92unwZlftmaa0olF7MzyBcPcwTRCENjWYTGx84NPOuEYlkKXYryvP9LXTVKnNS2axQ== - next -end -config user setting - set auth-type http https - set auth-cert "Fortinet_Factory" - set auth-secure-http enable -end -config user group - edit "SSO_Guest_Users" - next - edit "Admins" - set member "tim" - next - edit "Kinder-group" - set member "finn" "nils" "mia" "timk" - next - edit "gast" - set group-type guest - set expire 7200 - set multiple-guest-add enable - next - edit "gastgruppe" - set group-type guest - set expire 7200 - next -end -config user device - edit "tims-macbook-lan" - set mac c8:2a:14:14:f1:eb - set type mac - next - edit "macantha-wlan" - set mac e0:f8:47:03:c2:9a - next - edit "PI" - set mac b8:27:eb:5b:f4:3b - set type linux-pc - next - edit "fb7240" - set mac 00:24:fe:b9:18:42 - next - edit "Drucker" - set mac 00:15:99:b3:5e:fd - next - edit "QNAP Knappe" - set mac 00:08:9b:c4:ac:c1 - next -end -config user device-group - edit "Eltern-Device" - set member "tims-macbook-lan" "macantha-wlan" "PI" - next -end -config user security-exempt-list - edit "kids-wifi-exempt-list" - config rule - edit 1 - set dstaddr "drucker-10.0.0.38" - next - edit 2 - set dstaddr "fritzbox_inet_10.0.0.24" - next - edit 3 - set dstaddr "knappe_10.0.0.15" - next - edit 4 - set dstaddr "wlan-kids" - next - edit 5 - set dstaddr "kids-allowed-internet" - next - edit 6 - set service "PING" - next - end - next -end -config vpn ssl web realm - edit "test" - set login-page " - - - - - - - - Please Login - - - -
                      -
                      -
                      -
                      - - -
                      - Cactus FFM Login -
                      -
                      -
                      -
                      - %%SSL_LOGIN%% -
                      -
                      - -
                      -
                      -
                      -
                      -
                      - - %%SSL_HIDDEN%% - -" - next -end -config vpn ssl web portal - edit "tunnel-access" - set tunnel-mode enable - set ip-pools "SSl-VPN-10.0.0.40_24" - set split-tunneling-routing-address "knappe_10.0.0.15" "internal-10.0.0.35_24" - next - edit "test-token-auth-vpn-profile" - set tunnel-mode enable - set ip-pools "SSl-VPN-10.0.0.40_24" - set split-tunneling-routing-address "knappe_10.0.0.15" - next -end -config vpn ssl settings - set servercert "fg60d.ffm.cactus.de" - set idle-timeout 0 - set tunnel-ip-pools "SSl-VPN-10.0.0.40_24" - set port 60320 - set source-interface "wan1" - set source-address "all" - set source-address6 "all" - set default-portal "tunnel-access" -end -config voip profile - edit "default" - set comment "Default VoIP profile." - next -end -config webfilter profile - edit "sniffer-profile" - set comment "Monitor web traffic." - set inspection-mode flow-based - config ftgd-wf - config filters - edit 1 - next - edit 2 - set category 1 - next - edit 3 - set category 2 - next - edit 4 - set category 3 - next - edit 5 - set category 4 - next - edit 6 - set category 5 - next - edit 7 - set category 6 - next - edit 8 - set category 7 - next - edit 9 - set category 8 - next - edit 10 - set category 9 - next - edit 11 - set category 11 - next - edit 12 - set category 12 - next - edit 13 - set category 13 - next - edit 14 - set category 14 - next - edit 15 - set category 15 - next - edit 16 - set category 16 - next - edit 17 - set category 17 - next - edit 18 - set category 18 - next - edit 19 - set category 19 - next - edit 20 - set category 20 - next - edit 21 - set category 23 - next - edit 22 - set category 24 - next - edit 23 - set category 25 - next - edit 24 - set category 26 - next - edit 25 - set category 28 - next - edit 26 - set category 29 - next - edit 27 - set category 30 - next - edit 28 - set category 31 - next - edit 29 - set category 33 - next - edit 30 - set category 34 - next - edit 31 - set category 35 - next - edit 32 - set category 36 - next - edit 33 - set category 37 - next - edit 34 - set category 38 - next - edit 35 - set category 39 - next - edit 36 - set category 40 - next - edit 37 - set category 41 - next - edit 38 - set category 42 - next - edit 39 - set category 43 - next - edit 40 - set category 44 - next - edit 41 - set category 46 - next - edit 42 - set category 47 - next - edit 43 - set category 48 - next - edit 44 - set category 49 - next - edit 45 - set category 50 - next - edit 46 - set category 51 - next - edit 47 - set category 52 - next - edit 48 - set category 53 - next - edit 49 - set category 54 - next - edit 50 - set category 55 - next - edit 51 - set category 56 - next - edit 52 - set category 57 - next - edit 53 - set category 58 - next - edit 54 - set category 59 - next - edit 55 - set category 61 - next - edit 56 - set category 62 - next - edit 57 - set category 63 - next - edit 58 - set category 64 - next - edit 59 - set category 65 - next - edit 60 - set category 66 - next - edit 61 - set category 67 - next - edit 62 - set category 68 - next - edit 63 - set category 69 - next - edit 64 - set category 70 - next - edit 65 - set category 71 - next - edit 66 - set category 72 - next - edit 67 - set category 75 - next - edit 68 - set category 76 - next - edit 69 - set category 77 - next - edit 70 - set category 78 - next - edit 71 - set category 79 - next - edit 72 - set category 80 - next - edit 73 - set category 81 - next - edit 74 - set category 82 - next - edit 75 - set category 83 - next - edit 76 - set category 84 - next - edit 77 - set category 85 - next - edit 78 - set category 86 - next - edit 79 - set category 87 - next - edit 80 - set category 88 - next - edit 81 - set category 89 - next - end - end - next - edit "default" - set comment "Default web filtering." - set inspection-mode flow-based - set ovrd-perm bannedword-override urlfilter-override fortiguard-wf-override contenttype-check-override - config override - set ovrd-user-group "Admins" - set profile "flow-monitor-all" - end - config web - set urlfilter-table 1 - set blacklist enable - set safe-search url header - end - config ftgd-wf - set options error-allow http-err-detail rate-server-ip - set category-override 140 141 - set ovrd 1 4 5 6 12 59 62 83 14 15 16 67 72 26 61 86 - config filters - edit 3 - set category 8 - next - edit 6 - set category 12 - set action block - next - edit 7 - set category 13 - next - edit 8 - set category 14 - set action block - next - edit 9 - set category 15 - set action block - next - edit 10 - set category 16 - set action block - next - edit 11 - next - edit 14 - set category 64 - next - edit 17 - set category 67 - set action block - next - edit 18 - set category 26 - set action block - next - edit 19 - set category 61 - set action block - next - edit 20 - set category 86 - set action block - next - edit 47 - set category 1 - set action block - next - edit 49 - set category 4 - set action block - next - edit 50 - set category 5 - set action block - next - edit 51 - set category 6 - set action block - next - edit 52 - set category 59 - set action block - next - edit 53 - set category 62 - set action block - next - edit 55 - set category 83 - set action block - next - edit 56 - set category 72 - set action block - next - edit 57 - set category 140 - next - edit 58 - set category 141 - next - end - end - next - edit "flow-monitor-all" - set comment "Monitor and log all visited URLs, flow-based." - set inspection-mode flow-based - config ftgd-wf - unset options - config filters - edit 1 - set category 1 - next - edit 2 - set category 3 - next - edit 3 - set category 4 - next - edit 4 - set category 5 - next - edit 5 - set category 6 - next - edit 6 - set category 12 - next - edit 7 - set category 59 - next - edit 8 - set category 62 - next - edit 9 - set category 83 - next - edit 10 - set category 2 - next - edit 11 - set category 7 - next - edit 12 - set category 8 - next - edit 13 - set category 9 - next - edit 14 - set category 11 - next - edit 15 - set category 13 - next - edit 16 - set category 14 - next - edit 17 - set category 15 - next - edit 18 - set category 16 - next - edit 19 - set category 57 - next - edit 20 - set category 63 - next - edit 21 - set category 64 - next - edit 22 - set category 65 - next - edit 23 - set category 66 - next - edit 24 - set category 67 - next - edit 25 - set category 19 - next - edit 26 - set category 24 - next - edit 27 - set category 25 - next - edit 28 - set category 72 - next - edit 29 - set category 75 - next - edit 30 - set category 76 - next - edit 31 - set category 26 - next - edit 32 - set category 61 - next - edit 33 - set category 86 - next - edit 34 - set category 17 - next - edit 35 - set category 18 - next - edit 36 - set category 20 - next - edit 37 - set category 23 - next - edit 38 - set category 28 - next - edit 39 - set category 29 - next - edit 40 - set category 30 - next - edit 41 - set category 33 - next - edit 42 - set category 34 - next - edit 43 - set category 35 - next - edit 44 - set category 36 - next - edit 45 - set category 37 - next - edit 46 - set category 38 - next - edit 47 - set category 39 - next - edit 48 - set category 40 - next - edit 49 - set category 42 - next - edit 50 - set category 44 - next - edit 51 - set category 46 - next - edit 52 - set category 47 - next - edit 53 - set category 48 - next - edit 54 - set category 54 - next - edit 55 - set category 55 - next - edit 56 - set category 58 - next - edit 57 - set category 68 - next - edit 58 - set category 69 - next - edit 59 - set category 70 - next - edit 60 - set category 71 - next - edit 61 - set category 77 - next - edit 62 - set category 78 - next - edit 63 - set category 79 - next - edit 64 - set category 80 - next - edit 65 - set category 82 - next - edit 66 - set category 85 - next - edit 67 - set category 87 - next - edit 68 - set category 31 - next - edit 69 - set category 41 - next - edit 70 - set category 43 - next - edit 71 - set category 49 - next - edit 72 - set category 50 - next - edit 73 - set category 51 - next - edit 74 - set category 52 - next - edit 75 - set category 53 - next - edit 76 - set category 56 - next - edit 77 - set category 81 - next - edit 78 - set category 84 - next - edit 79 - next - edit 80 - set category 89 - next - end - end - set log-all-url enable - set web-content-log disable - set web-filter-activex-log disable - set web-filter-command-block-log disable - set web-filter-cookie-log disable - set web-filter-applet-log disable - set web-filter-jscript-log disable - set web-filter-js-log disable - set web-filter-vbs-log disable - set web-filter-unknown-log disable - set web-filter-referer-log disable - set web-filter-cookie-removal-log disable - set web-url-log disable - set web-invalid-domain-log disable - set web-ftgd-err-log disable - set web-ftgd-quota-usage disable - next -end -config webfilter ftgd-local-rating - edit "10.0.0.24" - set rating 81 - next - edit "r.adc-srv.net" - set rating 0 - next -end -config webfilter search-engine - edit "google" - set hostname ".*\\.google\\..*" - set url "^\\/((custom|search|images|videosearch|webhp)\\?)" - set query "q=" - set safesearch url - set safesearch-str "&safe=active" - next - edit "yahoo" - set hostname ".*\\.yahoo\\..*" - set url "^\\/search(\\/video|\\/images){0,1}(\\?|;)" - set query "p=" - set safesearch url - set safesearch-str "&vm=r" - next - edit "bing" - set hostname ".*\\.bing\\..*" - set url "^(\\/images|\\/videos)?(\\/search|\\/async|\\/asyncv2)\\?" - set query "q=" - set safesearch header - next - edit "yandex" - set hostname ".*\\.yandex\\..*" - set url "^\\/((yand|images\\/|video\\/)(search)|search\\/)\\?" - set query "text=" - set safesearch url - set safesearch-str "&family=yes" - next - edit "youtube" - set hostname ".*\\.youtube\\..*" - set safesearch header - next - edit "baidu" - set hostname ".*\\.baidu\\.com" - set url "^\\/s?\\?" - set query "wd=" - next - edit "baidu2" - set hostname ".*\\.baidu\\.com" - set url "^\\/(ns|q|m|i|v)\\?" - set query "word=" - next - edit "baidu3" - set hostname "tieba\\.baidu\\.com" - set url "^\\/f\\?" - set query "kw=" - next -end -config vpn ipsec phase1-interface - edit "Cactus-DA" - set interface "wan1" - set peertype any - set proposal aes256-sha384 - set comments "VPN: Cactus-DA (Created by VPN wizard)" - set dhgrp 20 - set remote-gw 10.0.0.69 - set psksecret ENC vl9TmbxHqUB+b9MrAk312iitWlVPYXT//JQxCwYKGmll+4tbvwwa1BS1jxwSJiAcwiN+lI6agSytyTMSNqwvskfVyHp37ypmwTWvbodHlR5U8cfjpw8qtmSFoAGum6eyJqYePce0iWvqyjaOgz370qQAdSlFBQHQ5PwNegC11nSfr2oeSmosF+4R1x+h/kh1t7PJYQ== - next -end -config vpn ipsec phase2-interface - edit "Cactus-DA" - set phase1name "Cactus-DA" - set proposal aes256-sha384 - set dhgrp 20 - set auto-negotiate enable - set comments "VPN: Cactus-DA (Created by VPN wizard)" - set src-subnet 10.0.0.35 255.255.255.255 - set dst-subnet 10.0.0.60 255.255.255.255 - next - edit "DA-LAN 2 FFM-Server" - set phase1name "Cactus-DA" - set proposal aes256-sha384 - set dhgrp 20 - set auto-negotiate enable - set src-subnet 10.0.0.63 255.255.255.255 - set dst-subnet 10.0.0.60 255.255.255.255 - next - edit "wch60" - set phase1name "Cactus-DA" - set proposal aes256-sha384 - set dhgrp 20 - set auto-negotiate enable - set src-subnet 10.0.0.61 255.255.255.255 - set dst-subnet 10.0.0.60 255.255.255.255 - next - edit "fg2splunk" - set phase1name "Cactus-DA" - set proposal aes256-sha384 - set dhgrp 20 - set auto-negotiate enable - set comments "allow fortigate to log to splunk" - set src-addr-type ip - set src-start-ip 10.0.0.1 - set dst-subnet 10.0.0.70 255.255.255.255 - next -end -config system dns-database - edit "ffm.cactus.de" - set domain "ffm.cactus.de" - set view public - set ttl 86000 - config dns-entry - edit 1 - set hostname "proxy" - set ip 10.0.0.7 - next - edit 2 - set hostname "fg60d" - set ip 10.0.0.7 - next - end - set primary-name "fg60d" - set contact "tmp@cactus.de" - next -end -config system dns-server - edit "server-lan2" - next - edit "internal" - next -end -config antivirus settings - set grayware enable -end -config antivirus profile - edit "sniffer-profile" - set comment "Scan files and monitor viruses." - config http - set options scan - end - config ftp - set options scan - end - config imap - set options scan - set executables virus - end - config pop3 - set options scan - set executables virus - end - config smtp - set options scan - set executables virus - end - next - edit "default" - set comment "Scan files and block viruses." - config http - set options scan - end - config ftp - set options scan - end - config imap - set options scan - end - config pop3 - set options scan - end - config smtp - set options scan - end - next -end -config spamfilter profile - edit "sniffer-profile" - set comment "Malware and phishing URL monitoring." - set flow-based enable - next - edit "default" - set comment "Malware and phishing URL filtering." - set flow-based enable - set spam-filtering enable - set options spamfsip spamfssubmit spamfschksum spamfsurl spamhelodns spamraddrdns spamfsphish - next -end -config firewall schedule recurring - edit "always" - set day sunday monday tuesday wednesday thursday friday saturday - next - edit "kids-all-day" - set start 11:00 - set end 23:00 - set day sunday monday tuesday wednesday thursday friday saturday - next - edit "kids-late" - set start 07:00 - set end 23:00 - set day friday saturday - next -end -config firewall schedule group - edit "Kids-all-times-group" - set member "kids-all-day" "kids-late" - next -end -config firewall ippool - edit "test-v4-pool" - set startip 10.0.0.71 - set endip 10.0.0.72 - set comments "afasd fasd f" - next -end -config firewall ippool6 - edit "test-v6-pool" - set startip ::34 - set endip ::45 - set comments "asdfa sdf" - next -end -config firewall vip - edit "test-virtual-ip-v4" - set uuid e27fe466-17ad-51e6-6f8c-9c54c678584e - set comment "tasdfas dasd fas" - set extip 10.0.0.73-10.0.0.74 - set extintf "internal" - set portforward enable - set mappedip "10.0.0.75-10.0.0.76" - set extport 1-23 - set mappedport 23-45 - next -end -config firewall vip6 - edit "test-virtual-ip-v6" - set uuid 2b50ee56-17ae-51e6-a950-ff8c65749b11 - set comment "df asdfasdf" - set extip 13::-14:: - set mappedip 18::-19:: - set portforward enable - set extport 234-2388 - set mappedport 33-2187 - next -end -config firewall vipgrp - edit "test-virtual-ip-v4-group" - set uuid f89dde92-17ad-51e6-ac5d-be107e1fca94 - set interface "internal" - set comments "asd f" - set member "test-virtual-ip-v4" - next -end -config firewall vipgrp6 - edit "test-virtual-ip-v6-group" - set uuid 3b76459c-17ae-51e6-202d-ed3c29bd3e7b - set comments "asdf asdfasdf" - set member "test-virtual-ip-v6" - next -end -config firewall profile-protocol-options - edit "default" - set comment "All default services." - set oversize-log enable - config http - set ports 80 - set options clientcomfort - unset post-lang - end - config ftp - set ports 21 - set options clientcomfort splice - end - config imap - set ports 143 - set options fragmail - end - config mapi - set ports 135 - set options fragmail - end - config pop3 - set ports 110 - set options fragmail - end - config smtp - set ports 25 - set options fragmail splice - end - config nntp - set ports 119 - set options splice - end - config dns - set ports 53 - end - next - edit "default_default_sc" - set comment "All default services." - set oversize-log enable - config http - set ports 80 - set options clientcomfort servercomfort - unset post-lang - end - config ftp - set ports 21 - set options clientcomfort splice - end - config imap - set ports 143 - set options fragmail - end - config mapi - set ports 135 - set options fragmail - end - config pop3 - set ports 110 - set options fragmail - end - config smtp - set ports 25 - set options fragmail splice - end - config nntp - set ports 119 - set options splice - end - config dns - set ports 53 - end - next -end -config firewall ssl-ssh-profile - edit "deep-inspection" - set comment "Deep inspection." - config https - set ports 443 - end - config ftps - set ports 990 - end - config imaps - set ports 993 - end - config pop3s - set ports 995 - end - config smtps - set ports 465 - end - config ssl-exempt - edit 1 - set fortiguard-category 31 - next - edit 2 - set fortiguard-category 33 - next - edit 3 - set fortiguard-category 87 - next - edit 4 - set type address - set address "apple" - next - edit 5 - set type address - set address "appstore" - next - edit 6 - set type address - set address "dropbox.com" - next - edit 7 - set type address - set address "Gotomeeting" - next - edit 8 - set type address - set address "icloud" - next - edit 9 - set type address - set address "itunes" - next - edit 10 - set type address - set address "android" - next - edit 11 - set type address - set address "skype" - next - edit 12 - set type address - set address "swscan.apple.com" - next - edit 13 - set type address - set address "update.microsoft.com" - next - edit 14 - set type address - set address "eease" - next - edit 15 - set type address - set address "google-drive" - next - edit 16 - set type address - set address "google-play" - next - edit 17 - set type address - set address "google-play2" - next - edit 18 - set type address - set address "google-play3" - next - edit 19 - set type address - set address "microsoft" - next - edit 20 - set type address - set address "adobe" - next - edit 21 - set type address - set address "Adobe Login" - next - edit 22 - set type address - set address "fortinet" - next - edit 23 - set type address - set address "googleapis.com" - next - edit 24 - set type address - set address "citrix" - next - edit 25 - set type address - set address "verisign" - next - edit 26 - set type address - set address "Windows update 2" - next - edit 27 - set type address - set address "*.live.com" - next - edit 28 - set type address - set address "auth.gfx.ms" - next - edit 29 - set type address - set address "autoupdate.opera.com" - next - edit 30 - set type address - set address "softwareupdate.vmware.com" - next - edit 31 - set type address - set address "firefox update server" - next - end - set caname "Fortinet_CA_SSLProxy" - set certname "Fortinet_SSLProxy" - next - edit "certificate-inspection" - set comment "SSL handshake inspection." - config https - set ports 443 - set status certificate-inspection - set allow-invalid-server-cert enable - end - config ftps - set ports 990 - set status disable - set allow-invalid-server-cert enable - end - config imaps - set ports 993 - set status disable - set allow-invalid-server-cert enable - end - config pop3s - set ports 995 - set status disable - set allow-invalid-server-cert enable - end - config smtps - set ports 465 - set status disable - set allow-invalid-server-cert enable - end - set caname "Fortinet_CA_SSLProxy" - set certname "Fortinet_SSLProxy" - set ssl-invalid-server-cert-log enable - next -end -config firewall policy - edit 76 - set name "eltern keller to inet1" - set uuid 1a3b9474-fa6e-51e6-8066-477298fe055a - set srcintf "internal5" - set dstintf "wan1" - set srcaddr "all" - set dstaddr "gware.cactus.de_10.0.0.43" - set action accept - set schedule "always" - set service "PING" "SMTPS" "HTTPS" "IMAPS" - set comments "Clone of quiet mail gware" - next - edit 78 - set name "keller2inet-main" - set uuid 7b405f16-fa6e-51e6-b6fe-4bc9d0cd9ac7 - set srcintf "internal5" - set dstintf "wan1" - set srcaddr "eltern-keller-10.0.0.66_24" - set dstaddr "all" - set action accept - set schedule "always" - set service "ALL" - set utm-status enable - set logtraffic all - set comments "Clone of WLAN to Internet" - set scan-botnet-connections block - set av-profile "default" - set webfilter-profile "default" - set ips-sensor "default" - set application-list "default" - set profile-protocol-options "default" - next - edit 77 - set name "eltern2klautquiet" - set uuid 579b6b6e-fa6e-51e6-bace-9e8914986ac0 - set srcintf "internal5" - set dstintf "wan1" - set srcaddr "all" - set dstaddr "klaut.cactus.de" - set action accept - set schedule "always" - set service "PING" "HTTPS" - set comments "Clone of 37" - next - edit 33 - set name "quiet mail gware" - set uuid 0298a2ea-c1ca-51e5-5da8-61bf55ac3079 - set srcintf "internal" - set dstintf "wan1" - set srcaddr "all" - set dstaddr "gware.cactus.de_10.0.0.43" - set action accept - set schedule "always" - set service "PING" "SMTPS" "HTTPS" "IMAPS" - set comments "silent mail@cactus" - next - edit 37 - set uuid 546461e8-c299-51e5-c788-1ccacb1fbacc - set srcintf "internal" - set dstintf "wan1" - set srcaddr "all" - set dstaddr "klaut.cactus.de" - set action accept - set schedule "always" - set service "PING" "HTTPS" - set comments "silent klaut.cactus.de" - next - edit 32 - set name "internal 2 dns" - set uuid b875cb0c-c1c9-51e5-9179-bfb5080a3d9e - set srcintf "internal" - set dstintf "wan1" - set srcaddr "all" - set dstaddr "fritzbox_inet_10.0.0.24" "opendns_10.0.0.48" - set action accept - set schedule "always" - set service "DNS" "PING" - set comments "silent dns" - next - edit 16 - set uuid e2416cd8-bc7f-51e5-2708-ccfa8b1e4480 - set srcintf "internal" - set dstintf "wan1" - set srcaddr "tims-macbook" "macantha_wlan_10.0.0.37" - set dstaddr "fritzbox_inet_10.0.0.24" - set action accept - set status disable - set schedule "always" - set service "ALL" - set logtraffic all - set devices "Eltern-Device" - next - edit 14 - set uuid 95493190-bc7f-51e5-ca8b-5cd7f064f885 - set srcintf "internal" - set dstintf "wan1" - set srcaddr "all" - set dstaddr "fritzbox_inet_10.0.0.24" - set status disable - set schedule "always" - set service "ALL" - set logtraffic all - next - edit 6 - set name "eltern internal LAN to Inet" - set uuid d8d71542-aa3e-51e5-49bc-a1d2b82d27cc - set srcintf "internal" - set dstintf "wan1" - set srcaddr "tims-macbook" "pi_10.0.0.52" "macantha_at_pi_10.0.0.54" - set dstaddr "all" - set action accept - set status disable - set schedule "always" - set service "ALL" - set utm-status enable - set logtraffic all - set devices "Eltern-Device" - set comments "disabled - exploited by mac spoofing" - set scan-botnet-connections block - set av-profile "default" - set profile-protocol-options "default" - next - edit 40 - set name "LG Fernseher to LG" - set uuid 44675e94-cb5e-51e5-3c6c-ff29dda7aeae - set srcintf "internal" - set dstintf "wan1" - set srcaddr "LG Fernseher 10.0.0.44" - set dstaddr "LG Server 10.0.0.45_24" - set action accept - set schedule "always" - set service "HTTP" - set utm-status enable - set logtraffic all - set scan-botnet-connections block - set av-profile "default" - set webfilter-profile "default" - set ips-sensor "default" - set application-list "default" - set casi-profile "default" - set profile-protocol-options "default" - next - edit 41 - set name "LG Fernseher to Mediatheken" - set uuid 28e57196-cb5f-51e5-679f-b8e1d3460fce - set srcintf "internal" - set dstintf "wan1" - set srcaddr "LG Fernseher 10.0.0.44" - set dstaddr "all" - set action accept - set schedule "always" - set service "HTTP" "HTTPS" "PING" "NTP" - set utm-status enable - set logtraffic all - set scan-botnet-connections block - set av-profile "default" - set webfilter-profile "default" - set ips-sensor "default" - set application-list "default" - set casi-profile "default" - set profile-protocol-options "default" - next - edit 39 - set name "WLAN to Internet" - set uuid 499260b4-ca85-51e5-9aa1-d9124b6595db - set srcintf "internal" - set dstintf "wan1" - set srcaddr "fritzbox_oben_nat_10.0.0.18" "wlan_pi_10.0.0.53_24" "fb7240_10.0.0.55" - set dstaddr "all" - set action accept - set schedule "always" - set service "ALL" - set utm-status enable - set logtraffic all - set comments "Standard Access from wlan to internet" - set scan-botnet-connections block - set av-profile "default" - set webfilter-profile "default" - set ips-sensor "default" - set application-list "default" - set profile-protocol-options "default" - next - edit 38 - set name "drop kids without fritzbox" - set uuid 3acce722-ca79-51e5-baa1-994c1a43ac1d - set srcintf "internal" - set dstintf "wan1" - set srcaddr "internal-10.0.0.35_24" - set dstaddr "all" - set schedule "always" - set service "ALL" - set logtraffic all - set comments "drop all traffic not passing fritzbox checks" - set scan-botnet-connections block - next - edit 10 - set uuid 518c99fa-ba23-51e5-d393-45d387149eec - set srcintf "internal" - set dstintf "wan1" - set srcaddr "internal-10.0.0.35_24" - set dstaddr "all" - set action accept - set status disable - set schedule "Kids-all-times-group" - set service "ALL" - set utm-status enable - set logtraffic all - set groups "Kinder-group" - set scan-botnet-connections block - set av-profile "default" - set webfilter-profile "default" - set ips-sensor "default" - set application-list "default" - set casi-profile "default" - set profile-protocol-options "default_default_sc" - next - edit 1 - set uuid 77e8dc72-86c9-51e5-9dc3-544dc707dc81 - set srcintf "internal" - set dstintf "wan1" - set srcaddr "all" - set dstaddr "all" - set action accept - set status disable - set schedule "always" - set service "ALL" - set utm-status enable - set logtraffic all - set comments "with tls break-up" - set scan-botnet-connections block - set av-profile "default" - set webfilter-profile "default" - set ips-sensor "default" - set application-list "default" - set casi-profile "default" - set profile-protocol-options "default_default_sc" - set ssl-ssh-profile "certificate-inspection" - next - edit 25 - set uuid c9d3562c-bd59-51e5-5f2a-1698c0490655 - set srcintf "internal" - set dstintf "wan1" - set srcaddr "fritzbox_oben_nat_10.0.0.18" - set dstaddr "www.avm.de" - set action accept - set schedule "always" - set service "tcp-8011-to-avm" - set logtraffic disable - set comments "8011 to avm, nolog" - set label "test sect" - next - edit 35 - set uuid 199cc77e-c205-51e5-9d2f-765affac991a - set srcintf "internal" - set dstintf "wan1" - set srcaddr "all" - set dstaddr "all" - set schedule "always" - set service "tcp_40000_up" - set logtraffic all - set comments "block suspicious ports" - set label "test sect" - next - edit 34 - set name "block traffic to russia and india" - set uuid f32caa9c-c203-51e5-e204-71228e45c9b2 - set srcintf "internal" - set dstintf "wan1" - set srcaddr "all" - set dstaddr "geo-china" "geo-russia" - set schedule "always" - set service "ALL" - set logtraffic all - set comments "block suspicious geo dest" - set label "test sect" - next - edit 15 - set name "standard internet out" - set uuid bc18243e-bc7f-51e5-e874-cdd9e86159a7 - set srcintf "internal" - set dstintf "wan1" - set srcaddr "all" - set dstaddr "all" - set action accept - set status disable - set schedule "always" - set service "ALL" - set utm-status enable - set logtraffic all - set comments "standard internet outbound" - set label "test sect" - set scan-botnet-connections block - set av-profile "default" - set webfilter-profile "default" - set ips-sensor "default" - set application-list "default" - set casi-profile "default" - set profile-protocol-options "default" - next - edit 3 - set name "internet to gameserver" - set uuid af3df160-a9c1-51e5-07b7-2d57727326f2 - set srcintf "wan1" - set dstintf "dmz" - set srcaddr "all" - set dstaddr "ubuntu-gameserver-10.0.0.51" - set action accept - set schedule "always" - set service "ARK-7777-7778-udp" "minecraft-25565" "PING" "steam-udp-27000-27050" "ark-udp-32768-65535" - set utm-status enable - set logtraffic all - set comments "internet to gameserver" - set ips-sensor "default" - set application-list "default" - set casi-profile "default" - set profile-protocol-options "default" - next - edit 70 - set name "fb drop scans" - set uuid 22b0b712-e0c2-51e6-330e-d42a4bb3d9ed - set srcintf "wan1" - set dstintf "dmz" - set srcaddr "fritzbox_inet_10.0.0.24" - set dstaddr "ubuntu-gameserver-10.0.0.51" - set schedule "always" - set service "HTTP" "tcp14013-fb" - set logtraffic disable - set comments "silent drop fb2internal" - next - edit 4 - set name "game server access" - set uuid bbfddc4e-a9c1-51e5-2694-d0f5c44275a0 - set srcintf "internal" - set dstintf "dmz" - set srcaddr "internal-10.0.0.35_24" "wlan_pi_10.0.0.53_24" - set dstaddr "ubuntu-gameserver-10.0.0.51" - set action accept - set schedule "always" - set service "ARK-7777-7778-udp" "minecraft-25565" "SSH" "PING" "steam-udp-27000-27050" "ark-udp-32768-65535" - set logtraffic all - set comments "internal to gameserver" - next - edit 48 - set name "udp high ports to ark" - set uuid de60d372-d58b-51e5-8fd3-93e18d731cea - set srcintf "internal" - set dstintf "dmz" - set srcaddr "internal-10.0.0.35_24" "wlan_pi_10.0.0.53_24" - set dstaddr "ubuntu-gameserver-10.0.0.51" - set action accept - set schedule "always" - set service "udp-high-ports" - set logtraffic all - set comments "fucking ark server using dynamic ports for user sessions" - next - edit 20 - set name "gameserver ubuntu updates" - set uuid 419fb5c8-bcf2-51e5-303a-950b2339b9f4 - set srcintf "dmz" - set dstintf "wan1" - set srcaddr "ubuntu-gameserver-10.0.0.51" - set dstaddr "security.ubuntu.com" "de.archive.ubuntu.com" "extras.ubuntu.com" - set action accept - set schedule "always" - set service "HTTP" "HTTPS" "PING" - set logtraffic disable - set comments "ubuntu updates" - next - edit 42 - set name "temp steam update" - set uuid 1902acca-cc19-51e5-3ae2-d6508fed8fbb - set srcintf "dmz" - set dstintf "wan1" - set srcaddr "ubuntu-gameserver-10.0.0.51" - set dstaddr "all" - set action accept - set schedule "always" - set service "HTTP" "HTTPS" "PING" "steam-udp-27000-27050" "valve_ports" "steam-tcp-27015-27020" - set utm-status enable - set logtraffic disable - set comments "temp rule -2nd line -3rd line -+4th line" - set av-profile "default" - set webfilter-profile "default" - set ips-sensor "default" - set application-list "default" - set casi-profile "default" - set profile-protocol-options "default" - set ssl-ssh-profile "certificate-inspection" - next - edit 75 - set name "ARK - temp test 2017-02-17" - set uuid d42e9a08-f53b-51e6-2a32-589092093ffe - set srcintf "dmz" - set dstintf "wan1" - set srcaddr "ubuntu-gameserver-10.0.0.51" - set dstaddr "all" - set action accept - set schedule "always" - set service "udp-high-ports" "ARK-7777-7778-tcp" "ARK-7777-7778-udp" - set utm-status enable - set comments "Clone of temp steam update" - set av-profile "default" - set webfilter-profile "default" - set ips-sensor "default" - set application-list "default" - set casi-profile "default" - set profile-protocol-options "default" - set ssl-ssh-profile "certificate-inspection" - next - edit 46 - set name "outbound 2 10.0.0.49" - set uuid c9502a94-d583-51e5-cd09-9c9887ffafbc - set srcintf "dmz" - set dstintf "wan1" - set srcaddr "ubuntu-gameserver-10.0.0.51" - set dstaddr "valve_10.0.0.49" - set action accept - set status disable - set schedule "always" - set service "PING" "valve_ports" - set utm-status enable - set logtraffic disable - set comments "Clone of temp ubuntu steam update" - set av-profile "default" - set webfilter-profile "default" - set ips-sensor "default" - set application-list "default" - set casi-profile "default" - set profile-protocol-options "default" - set ssl-ssh-profile "certificate-inspection" - next - edit 47 - set name "temp outbound all to valve" - set uuid 84e03cde-d58b-51e5-7e5a-5562db3da154 - set srcintf "dmz" - set dstintf "wan1" - set srcaddr "ubuntu-gameserver-10.0.0.51" - set dstaddr "valve_10.0.0.49" "valve_10.0.0.50" - set action accept - set status disable - set schedule "always" - set service "ALL" - set utm-status enable - set logtraffic disable - set comments "Clone of outbound 2 10.0.0.49" - set av-profile "default" - set webfilter-profile "default" - set ips-sensor "default" - set application-list "default" - set casi-profile "default" - set profile-protocol-options "default" - set ssl-ssh-profile "certificate-inspection" - next - edit 21 - set name "game-server to dns-inet" - set uuid bdefc324-bd0c-51e5-16af-8449c799c4e2 - set srcintf "dmz" - set dstintf "wan1" - set srcaddr "ubuntu-gameserver-10.0.0.51" - set dstaddr "fritzbox_10.0.0.24_global" "G-google-dns-srv" - set action accept - set schedule "always" - set service "DNS" - set logtraffic disable - set comments "dns" - next - edit 83 - set name "gameserver ntp" - set uuid 4d9e56b2-00b8-51e7-1680-479939b2ed12 - set srcintf "dmz" - set dstintf "wan1" - set srcaddr "ubuntu-gameserver-10.0.0.51" - set dstaddr "all" - set action accept - set schedule "always" - set service "NTP" - set logtraffic disable - set comments "Clone of game-server to dns-inet" - next - edit 54 - set name "wlan2serverlan" - set uuid 4f83d548-be63-51e6-a06a-b589fa6823c4 - set srcintf "wlan0" - set dstintf "server-lan2" - set srcaddr "fwf60-wlan-client-net" - set dstaddr "knappe_10.0.0.15" - set action accept - set schedule "always" - set service "HTTPS" "SMB" "afp_548_tcp" "PING" "tcp_8081_phpfreechat" "SQUID" "SSH" "HTTP" - set utm-status enable - set logtraffic all - set comments "Clone of internal to knappe" - set scan-botnet-connections block - next - edit 80 - set name "eltern-keller-2-knappe" - set uuid fd4eed4c-fa6e-51e6-e6a3-05d4b593e7d6 - set srcintf "internal5" - set dstintf "server-lan2" - set srcaddr "eltern-keller-10.0.0.66_24" - set dstaddr "knappe_10.0.0.15" - set action accept - set schedule "always" - set service "HTTPS" "SMB" "afp_548_tcp" "PING" "tcp_8081_phpfreechat" "SQUID" "SSH" "HTTP" - set utm-status enable - set logtraffic all - set comments "Clone of internal to knappe" - set scan-botnet-connections block - next - edit 5 - set name "internal to knappe" - set uuid 5fd8bdb6-a9c2-51e5-5169-46ffaf0999b8 - set srcintf "internal" - set dstintf "server-lan2" - set srcaddr "internal-10.0.0.35_24" "wlan_10.0.0.36_24" "wlan_pi_10.0.0.53_24" - set dstaddr "knappe_10.0.0.15" - set action accept - set schedule "always" - set service "HTTPS" "SMB" "afp_548_tcp" "PING" "tcp_8081_phpfreechat" "SQUID" "SSH" "HTTP" - set utm-status enable - set logtraffic all - set comments "knappe standard access" - set scan-botnet-connections block - next - edit 65 - set name "silently drop 139/tcp" - set uuid f977fcdc-c381-51e6-c875-ee13adc7114e - set srcintf "internal" - set dstintf "server-lan2" - set srcaddr "internal-10.0.0.35_24" - set dstaddr "knappe_10.0.0.15" - set schedule "always" - set service "SAMBA" - set logtraffic disable - set comments "Clone of internal to knappe" - set scan-botnet-connections block - next - edit 66 - set name "drop 139/tcp from wch60e2knappe" - set uuid 26d1beac-c382-51e6-1bc5-81fee87dfd6b - set srcintf "wlan0" - set dstintf "server-lan2" - set srcaddr "fwf60-wlan-client-net" - set dstaddr "knappe_10.0.0.15" - set schedule "always" - set service "SAMBA" - set logtraffic disable - set comments "Clone of silently drop 139/tcp" - set scan-botnet-connections block - next - edit 55 - set name "wlan2printer" - set uuid 75eee1e6-be63-51e6-42cc-9973ac16e83e - set srcintf "wlan0" - set dstintf "server-lan2" - set srcaddr "fwf60-wlan-client-net" - set dstaddr "drucker-10.0.0.38" - set action accept - set schedule "always" - set service "ALL" - set logtraffic all - set comments "wlan to printer" - next - edit 63 - set name "drop internal cross-nw traffic" - set uuid 32265eac-c2a1-51e6-6acd-4193bb50eb00 - set srcintf "wlan0" - set dstintf "internal" - set srcaddr "fwf60-wlan-client-net" - set dstaddr "all" - set schedule "always" - set service "ALL" - set logtraffic disable - set comments "silent ignore" - next - edit 81 - set name "keller-printing" - set uuid 408dbad4-fa6f-51e6-b648-29f7127d0276 - set srcintf "internal5" - set dstintf "server-lan2" - set srcaddr "eltern-keller-10.0.0.66_24" - set dstaddr "drucker-10.0.0.38" - set action accept - set schedule "always" - set service "ALL" - set logtraffic all - set comments "Clone of internal to printer" - next - edit 19 - set name "internal to printer" - set uuid 488528d8-bc88-51e5-b8b9-3d9ff009fc03 - set srcintf "internal" - set dstintf "server-lan2" - set srcaddr "internal-10.0.0.35_24" "wlan_10.0.0.36_24" "wlan_pi_10.0.0.53_24" - set dstaddr "drucker-10.0.0.38" - set action accept - set schedule "always" - set service "ALL" - set logtraffic all - set comments "printing" - next - edit 51 - set name "test ssl vpn portal" - set uuid 452d358e-7e4a-51e6-6a15-c4a5e43ebd4e - set srcintf "ssl.root" - set dstintf "server-lan2" - set srcaddr "SSl-VPN-10.0.0.40_24" - set dstaddr "knappe_10.0.0.15" - set action accept - set status disable - set schedule "always" - set service "HTTPS" "tcp_8081_phpfreechat" - set utm-status enable - set groups "Admins" - set comments "Clone of SSL VPN access to knappe" - set scan-botnet-connections block - set av-profile "default" - set ips-sensor "default" - set application-list "default" - set casi-profile "default" - set profile-protocol-options "default" - set ssl-ssh-profile "certificate-inspection" - next - edit 26 - set name "SSL VPN access to knappe" - set uuid 509b3f4c-be1a-51e5-b177-86d105e69d94 - set srcintf "ssl.root" - set dstintf "server-lan2" - set srcaddr "SSl-VPN-10.0.0.40_24" - set dstaddr "knappe_10.0.0.15" - set action accept - set schedule "always" - set service "SAMBA" "HTTPS" "SMB" "afp_548_tcp" "PING" "tcp_8081_phpfreechat" "SSH" - set utm-status enable - set groups "Admins" - set comments "knappe vpn access" - set scan-botnet-connections block - set av-profile "default" - set ips-sensor "default" - set application-list "default" - set casi-profile "default" - set profile-protocol-options "default" - set ssl-ssh-profile "certificate-inspection" - next - edit 45 - set name "silently drop broadcasts" - set uuid dcf4ed44-d099-51e5-2b6e-a1c0f2a25ef1 - set srcintf "ssl.root" - set dstintf "server-lan2" - set srcaddr "all" - set dstaddr "broadcast" - set schedule "always" - set service "ALL" - set logtraffic disable - set groups "Admins" - set scan-botnet-connections block - next - edit 69 - set name "silently drop http" - set uuid 22fe7418-d8af-51e6-fd9e-d11227f5d41e - set srcintf "ssl.root" - set dstintf "server-lan2" - set srcaddr "all" - set dstaddr "all" - set schedule "always" - set service "HTTP" - set logtraffic disable - set groups "Admins" - set comments "silently drop http" - set scan-botnet-connections block - next - edit 36 - set name "admin FG and FB via ssl-VPN" - set uuid c29c9b50-c283-51e5-a66f-5c69302e8a3f - set srcintf "ssl.root" - set dstintf "internal" - set srcaddr "SSl-VPN-10.0.0.40_24" - set dstaddr "fg_internal_10.0.0.7" "pi_10.0.0.52" - set action accept - set schedule "always" - set service "HTTPS" "PING" "SSH" - set groups "Admins" - set comments "fw admin via ssl vpn" - next - edit 71 - set name "access to gameserver via ssl" - set uuid 254fae5e-e14b-51e6-c5e7-f5b61bc26a77 - set srcintf "ssl.root" - set dstintf "dmz" - set srcaddr "SSl-VPN-10.0.0.40_24" - set dstaddr "ubuntu-gameserver-10.0.0.51" - set action accept - set schedule "always" - set service "HTTPS" "PING" "SSH" - set groups "Admins" - set comments "Clone of admin FG and FB via ssl-VPN" - next - edit 44 - set name "admin fb internet via vpn" - set uuid 876f8672-ce69-51e5-8cb4-ff22dce238d9 - set srcintf "ssl.root" - set dstintf "wan1" - set srcaddr "SSl-VPN-10.0.0.40_24" - set dstaddr "fritzbox_inet_10.0.0.24" - set action accept - set schedule "always" - set service "HTTPS" "PING" "HTTP" - set groups "Admins" - set comments "Clone of admin FG and FB via ssl-VPN" - set nat enable - next - edit 79 - set name "ping-back-connect-keller" - set uuid c08bfb52-fa6e-51e6-4b24-f50c7c651800 - set srcintf "server-lan2" - set dstintf "internal5" - set srcaddr "drucker-10.0.0.38" - set dstaddr "eltern-keller-10.0.0.66_24" - set action accept - set schedule "always" - set service "PING" "tcp_5357_samsung_printer" - set logtraffic disable - set comments "Clone of samsung to print clients" - next - edit 64 - set name "samsung to print clients" - set uuid 9403e594-c360-51e6-683c-bb3cf21f60bb - set srcintf "server-lan2" - set dstintf "wlan0" - set srcaddr "drucker-10.0.0.38" - set dstaddr "fwf60-wlan-client-net" - set action accept - set schedule "always" - set service "PING" "tcp_5357_samsung_printer" - set logtraffic disable - next - edit 13 - set uuid c9d19496-bc7c-51e5-8f38-9fcc5d3e92e3 - set srcintf "server-lan2" - set dstintf "wan1" - set srcaddr "knappe_10.0.0.15" "drucker-10.0.0.38" - set dstaddr "fritzbox_inet_10.0.0.24" - set action accept - set schedule "always" - set service "PING" "DNS" - set logtraffic disable - set comments "dns" - next - edit 22 - set uuid fe25aff8-bd2a-51e5-b3a5-c967c81fe1b8 - set srcintf "server-lan2" - set dstintf "wan1" - set srcaddr "knappe_10.0.0.15" "drucker-10.0.0.38" - set dstaddr "all" - set action accept - set schedule "always" - set service "PING" "NTP" - set comments "get time" - next - edit 23 - set uuid 0369314c-bd2b-51e5-8216-09ca5ec33f19 - set srcintf "server-lan2" - set dstintf "wan1" - set srcaddr "knappe_10.0.0.15" - set dstaddr "qnap_update_net_10.0.0.39/32" "qnap-update-akamai-10.0.0.42_24" - set action accept - set schedule "always" - set service "PING" "HTTP" - set comments "qnap update" - next - edit 43 - set name "drop strange printer traffic" - set uuid 33097a18-cda4-51e5-543e-58f6ff7c576f - set srcintf "server-lan2" - set dstintf "wan1" - set srcaddr "drucker-10.0.0.38" - set dstaddr "net_10.0.0.64_24" - set schedule "always" - set service "ALL" - set logtraffic disable - set comments "strange printer requests" - next - edit 68 - set name "drop printer2google https" - set uuid c330df82-c475-51e6-fdba-5704cc720bbd - set srcintf "server-lan2" - set dstintf "wan1" - set srcaddr "drucker-10.0.0.38" - set dstaddr "all" - set schedule "always" - set service "HTTPS" - set logtraffic disable - set comments "2. drop strange printer traffic" - next - edit 49 - set name "qnap apps download" - set uuid a186a968-de0a-51e5-5de3-0806a9cf06c0 - set srcintf "server-lan2" - set dstintf "wan1" - set srcaddr "knappe_10.0.0.15" - set dstaddr "all" - set action accept - set schedule "always" - set service "HTTP" "HTTPS" "PING" - set utm-status enable - set av-profile "default" - set webfilter-profile "default" - set ips-sensor "default" - set application-list "default" - set casi-profile "default" - set profile-protocol-options "default" - set ssl-ssh-profile "certificate-inspection" - next - edit 67 - set name "knappe2gware" - set uuid 840c4934-c44a-51e6-a848-1016a845713e - set srcintf "server-lan2" - set dstintf "wan1" - set srcaddr "knappe_10.0.0.15" - set dstaddr "gware.cactus.de_10.0.0.43" - set action accept - set schedule "always" - set service "SMTPS" - set utm-status enable - set comments "Clone of qnap apps download" - next - edit 24 - set uuid 29f14b50-bd2c-51e5-d55d-25bb38896c90 - set srcintf "server-lan2" - set dstintf "wan1" - set srcaddr "knappe_10.0.0.15" - set dstaddr "all" - set schedule "always" - set service "bittorrent" - set logtraffic disable - set comments "silently drop bittorent" - next - edit 27 - set name "drop fb http scan" - set uuid edf5ef38-be1c-51e5-e704-8d8feddecfea - set srcintf "wan1" - set dstintf "server-lan2" - set srcaddr "fritzbox_inet_10.0.0.24" - set dstaddr "knappe_10.0.0.15" "drucker-10.0.0.38" - set schedule "always" - set service "HTTP" "tcp14013-fb" - set logtraffic disable - set comments "fritzbox http autodiscover" - next - edit 62 - set name "silent drop fb 2 wch60e" - set uuid ec4b0c5e-c104-51e6-7075-2f0318f1675d - set srcintf "wan1" - set dstintf "wlan0" - set srcaddr "fritzbox_inet_10.0.0.24" - set dstaddr "fwf60-wlan-client-net" - set schedule "always" - set service "HTTP" "tcp14013-fb" - set logtraffic disable - set comments "Clone of silent drop fb2wlan" - next - edit 82 - set name "drop fb probes to keller" - set uuid 9a17bfd2-fa74-51e6-bdc6-69e5d816dc51 - set srcintf "wan1" - set dstintf "internal5" - set srcaddr "fritzbox_inet_10.0.0.24" - set dstaddr "eltern-keller-10.0.0.66_24" - set schedule "always" - set service "HTTP" "tcp14013-fb" - set logtraffic disable - set comments "Clone of silent drop fb2internal" - next - edit 61 - set name "silent drop fb2internal" - set uuid a5683b72-c104-51e6-7dc7-b8b399b077a2 - set srcintf "wan1" - set dstintf "internal" - set srcaddr "fritzbox_inet_10.0.0.24" - set dstaddr "internal-10.0.0.35_24" - set schedule "always" - set service "HTTP" "tcp14013-fb" - set logtraffic disable - set comments "Clone of drop fritzbox http scan" - next - edit 74 - set name "ipsec-vpn-cactus" - set uuid 8aa3bfbe-f3a9-51e6-d7c1-130d2eaf52f8 - set srcintf "wan1" - set dstintf "wan1" - set srcaddr "vpn-gw-cactus-ffm" - set dstaddr "FG_10.0.0.1" - set action accept - set schedule "always" - set service "ALL" - set logtraffic all - set comments "allow ipsec vpn cactus" - next - edit 73 - set name "stealth-rule" - set uuid 1e8401d6-f3a9-51e6-b504-978dc345a496 - set srcintf "wan1" - set dstintf "wan1" - set srcaddr "all" - set dstaddr "FG_10.0.0.1" - set schedule "always" - set service "ALL" - set logtraffic all - set comments "Clone of silent drop fb2internal" - next - edit 28 - set name "drop fritzbox 2 nfm" - set uuid 55633b3e-be1e-51e5-83c5-f350309e6012 - set srcintf "wan1" - set dstintf "kids-wifi" - set srcaddr "fritzbox_inet_10.0.0.24" - set dstaddr "wlan-kids" - set schedule "always" - set service "HTTP" "tcp14013-fb" - set logtraffic disable - set comments "fritzbox autodiscover and parental filter stuff" - next - edit 50 - set name "vpn_Cactus-DA_local" - set uuid 8dcf255a-be27-51e6-2623-209817195490 - set srcintf "internal" - set dstintf "Cactus-DA" - set srcaddr "Cactus-DA_local" - set dstaddr "Cactus-DA_remote" - set action accept - set schedule "always" - set service "ALL" - set comments "VPN: Cactus-DA (Created by VPN wizard)" - next - edit 52 - set name "vpn_Cactus-DA_remote" - set uuid 8ded7e92-be27-51e6-6666-fda6a84b25c3 - set srcintf "Cactus-DA" - set dstintf "internal" - set srcaddr "Cactus-DA_remote" - set dstaddr "Cactus-DA_local" - set action accept - set schedule "always" - set service "PING" - set logtraffic all - set comments "VPN: Cactus-DA (Created by VPN wizard)" - next - edit 53 - set name "fwf-wlan-to-internet" - set uuid bef31b02-be57-51e6-fce6-4c8e659c802e - set srcintf "wlan0" - set dstintf "wan1" - set srcaddr "fwf60-wlan-client-net" - set dstaddr "all" - set action accept - set schedule "always" - set service "ALL" - set utm-status enable - set comments "test" - set av-profile "default" - set webfilter-profile "default" - set ips-sensor "default" - set application-list "default" - set profile-protocol-options "default" - set ssl-ssh-profile "certificate-inspection" - next - edit 72 - set name "guest2inet" - set uuid 8231abd6-e533-51e6-7d55-652097c7e4c8 - set srcintf "GWS" - set dstintf "wan1" - set srcaddr "all" - set dstaddr "all" - set action accept - set schedule "always" - set service "ALL" - set utm-status enable - set comments "guest2internet" - set av-profile "default" - set webfilter-profile "default" - set ips-sensor "default" - set application-list "default" - set profile-protocol-options "default" - set nat enable - next - edit 60 - set name "wlan-kids auth" - set uuid b5c55e30-bfa8-51e6-f6e8-f97ba63319ab - set srcintf "kids-wifi" - set dstintf "kids-wifi" - set srcaddr "all" - set dstaddr "wifi-kids-wlan-router-ip" - set action accept - set schedule "always" - set service "fortinet-captive-portal-auth" - set utm-status enable - set comments "auth kids" - set av-profile "default" - set webfilter-profile "default" - set ips-sensor "default" - set application-list "default" - set profile-protocol-options "default" - next - edit 56 - set name "kids2internet" - set uuid 71756a8a-bf0e-51e6-81ae-a93b64520de6 - set srcintf "kids-wifi" - set dstintf "wan1" - set srcaddr "all" - set dstaddr "all" - set action accept - set schedule "always" - set service "ALL" - set utm-status enable - set av-profile "default" - set webfilter-profile "default" - set ips-sensor "default" - set application-list "default" - set casi-profile "default" - set profile-protocol-options "default" - set ssl-ssh-profile "certificate-inspection" - next - edit 57 - set name "wifikids2knappe" - set uuid 1934cdba-bf0f-51e6-e0d3-e5656c281c1a - set srcintf "kids-wifi" - set dstintf "server-lan2" - set srcaddr "wlan-kids" - set dstaddr "knappe_10.0.0.15" - set action accept - set schedule "always" - set service "PING" "SMB" - set utm-status enable - set av-profile "default" - set ips-sensor "default" - set profile-protocol-options "default" - next - edit 58 - set name "wlankids2printer" - set uuid 349f6d44-bf0f-51e6-2de4-2b77a9a17a03 - set srcintf "kids-wifi" - set dstintf "server-lan2" - set srcaddr "wlan-kids" - set dstaddr "drucker-10.0.0.38" - set action accept - set schedule "always" - set service "ALL" - set utm-status enable - set comments "Clone of wifikids2serverlan" - set av-profile "default" - set ips-sensor "default" - set profile-protocol-options "default" - next - edit 59 - set name "wlan-kids 2 dns" - set uuid 90cb4230-bfa7-51e6-4d22-23886941b8d4 - set srcintf "kids-wifi" - set dstintf "wan1" - set srcaddr "all" - set dstaddr "fritzbox_inet_10.0.0.24" - set action accept - set schedule "always" - set service "DNS" - next -end -config firewall policy6 - edit 1 - set name "test ipv6 policy1" - set uuid ae80e358-1065-51e6-a820-06154a13edca - set srcintf "internal" - set dstintf "wan1" - set srcaddr "all" - set dstaddr "all" - set action accept - set schedule "always" - set service "HTTP" "HTTPS" "PING" "test_service_multi-port" - set utm-status enable - set logtraffic all - set comments "v6 comment" - set av-profile "default" - set webfilter-profile "default" - set ips-sensor "default" - set profile-protocol-options "default" - next - edit 2 - set name "test-v6-nw-obj:1" - set uuid 003ece9e-1066-51e6-0540-15d6d9e4a6a8 - set srcintf "server-lan2" - set dstintf "wan1" - set srcaddr "ipv6-testgroup" - set dstaddr "test-ipv6addr" - set action accept - set schedule "always" - set service "PING" - set comments "comment33" - next - edit 3 - set name "test virtual ipv6 ips" - set uuid 81a3a9d8-17ae-51e6-1f16-38db7b448fd5 - set srcintf "internal" - set dstintf "wan1" - set srcaddr "test-ipv6addr" - set dstaddr "test-ipv6addr" - set action accept - set status disable - set schedule "kids-all-day" - set service "ARK-7777-7778-udp" - set devices "macantha-wlan" - set nat enable - set ippool enable - set poolname "test-v6-pool" - next -end -config firewall DoS-policy - edit 1 - set interface "wan1" - set srcaddr "all" - set dstaddr "FG_10.0.0.1" - set service "ALL" - config anomaly - edit "tcp_syn_flood" - set status enable - set log enable - set threshold 2000 - next - edit "tcp_port_scan" - set status enable - set log enable - set threshold 1000 - next - edit "tcp_src_session" - set status enable - set log enable - set threshold 5000 - next - edit "tcp_dst_session" - set status enable - set log enable - set threshold 5000 - next - edit "udp_flood" - set status enable - set log enable - set threshold 2000 - next - edit "udp_scan" - set status enable - set log enable - set threshold 2000 - next - edit "udp_src_session" - set status enable - set log enable - set threshold 5000 - next - edit "udp_dst_session" - set status enable - set log enable - set threshold 5000 - next - edit "icmp_flood" - set status enable - set log enable - set threshold 250 - next - edit "icmp_sweep" - set status enable - set log enable - set threshold 100 - next - edit "icmp_src_session" - set status enable - set log enable - set threshold 300 - next - edit "icmp_dst_session" - set status enable - set log enable - set threshold 1000 - next - edit "ip_src_session" - set status enable - set log enable - set threshold 5000 - next - edit "ip_dst_session" - set status enable - set log enable - set threshold 5000 - next - edit "sctp_flood" - set status enable - set log enable - set threshold 2000 - next - edit "sctp_scan" - set status enable - set log enable - set threshold 1000 - next - edit "sctp_src_session" - set status enable - set log enable - set threshold 5000 - next - edit "sctp_dst_session" - set status enable - set log enable - set threshold 5000 - next - end - next - edit 2 - set interface "wan1" - set srcaddr "all" - set dstaddr "all" - set service "ALL" - config anomaly - edit "tcp_syn_flood" - set status enable - set log enable - set action block - set threshold 2000 - next - edit "tcp_port_scan" - set status enable - set log enable - set action block - set threshold 1000 - next - edit "tcp_src_session" - set status enable - set log enable - set action block - set threshold 5000 - next - edit "tcp_dst_session" - set status enable - set log enable - set action block - set threshold 5000 - next - edit "udp_flood" - set status enable - set log enable - set action block - set threshold 2000 - next - edit "udp_scan" - set status enable - set log enable - set action block - set threshold 2000 - next - edit "udp_src_session" - set status enable - set log enable - set action block - set threshold 5000 - next - edit "udp_dst_session" - set status enable - set log enable - set action block - set threshold 5000 - next - edit "icmp_flood" - set status enable - set log enable - set action block - set threshold 250 - next - edit "icmp_sweep" - set status enable - set log enable - set action block - set threshold 100 - next - edit "icmp_src_session" - set status enable - set log enable - set action block - set threshold 300 - next - edit "icmp_dst_session" - set status enable - set log enable - set action block - set threshold 1000 - next - edit "ip_src_session" - set status enable - set log enable - set action block - set threshold 5000 - next - edit "ip_dst_session" - set status enable - set log enable - set action block - set threshold 5000 - next - edit "sctp_flood" - set status enable - set log enable - set action block - set threshold 2000 - next - edit "sctp_scan" - set status enable - set log enable - set action block - set threshold 1000 - next - edit "sctp_src_session" - set status enable - set log enable - set action block - set threshold 5000 - next - edit "sctp_dst_session" - set status enable - set log enable - set action block - set threshold 5000 - next - end - next -end -config endpoint-control profile - edit "default" - config forticlient-winmac-settings - set forticlient-av enable - set av-realtime-protection enable - set forticlient-application-firewall enable - set forticlient-application-firewall-list "default" - set forticlient-log-upload disable - set forticlient-wf enable - set forticlient-wf-profile "default" - end - config forticlient-android-settings - end - config forticlient-ios-settings - end - next -end -config switch-controller switch-profile - edit "default" - next -end -config wireless-controller wids-profile - edit "default" - set comment "Default WIDS profile." - set ap-scan enable - set wireless-bridge enable - set deauth-broadcast enable - set null-ssid-probe-resp enable - set long-duration-attack enable - set invalid-mac-oui enable - set weak-wep-iv enable - set auth-frame-flood enable - set assoc-frame-flood enable - set spoofed-deauth enable - set asleap-attack enable - set eapol-start-flood enable - set eapol-logoff-flood enable - set eapol-succ-flood enable - set eapol-fail-flood enable - set eapol-pre-succ-flood enable - set eapol-pre-fail-flood enable - next - edit "default-wids-apscan-enabled" - set ap-scan enable - next -end -config wireless-controller wtp-profile - edit "FAP423E-default" - config platform - set type 423E - end - set ap-country US - config radio-1 - set band 802.11n - end - config radio-2 - set band 802.11ac - end - next - edit "FAP421E-default" - config platform - set type 421E - end - set ap-country US - config radio-1 - set band 802.11n - end - config radio-2 - set band 802.11ac - end - next - edit "FAPS423E-default" - config platform - set type S423E - end - set ap-country US - config radio-1 - set band 802.11n - end - config radio-2 - set band 802.11ac - end - next - edit "FAPS422E-default" - config platform - set type S422E - end - set ap-country US - config radio-1 - set band 802.11n - end - config radio-2 - set band 802.11ac - end - next - edit "FAPS421E-default" - config platform - set type S421E - end - set ap-country US - config radio-1 - set band 802.11n - end - config radio-2 - set band 802.11ac - end - next - edit "FAPS323CR-default" - config platform - set type S323CR - end - set ap-country US - config radio-1 - set band 802.11n - end - config radio-2 - set band 802.11ac - end - next - edit "FAPS322CR-default" - config platform - set type S322CR - end - set ap-country US - config radio-1 - set band 802.11n - end - config radio-2 - set band 802.11ac - end - next - edit "FAPS321CR-default" - config platform - set type S321CR - end - set ap-country US - config radio-1 - set band 802.11n - end - config radio-2 - set band 802.11ac - end - next - edit "FAPS313C-default" - config platform - set type S313C - end - set ap-country US - config radio-1 - set band 802.11ac - end - config radio-2 - set mode disabled - end - next - edit "FAPS311C-default" - config platform - set type S311C - end - set ap-country US - config radio-1 - set band 802.11ac - end - config radio-2 - set mode disabled - end - next - edit "FAPS323C-default" - config platform - set type S323C - end - set ap-country US - config radio-1 - set band 802.11n - end - config radio-2 - set band 802.11ac - end - next - edit "FAPS322C-default" - config platform - set type S322C - end - set ap-country US - config radio-1 - set band 802.11n - end - config radio-2 - set band 802.11ac - end - next - edit "FAPS321C-default" - config platform - set type S321C - end - set ap-country US - config radio-1 - set band 802.11n - end - config radio-2 - set band 802.11ac - end - next - edit "FAP321C-default" - config platform - set type 321C - end - set ap-country US - config radio-1 - set band 802.11n - set vap-all disable - end - config radio-2 - set band 802.11ac - set vap-all disable - end - next - edit "FAP223C-default" - config platform - set type 223C - end - set ap-country US - config radio-1 - set band 802.11n - set vap-all disable - end - config radio-2 - set band 802.11ac - set vap-all disable - end - next - edit "FAP112D-default" - config platform - set type 112D - end - set ap-country US - config radio-1 - set band 802.11n - set vap-all disable - end - config radio-2 - set mode disabled - end - next - edit "FAP24D-default" - config platform - set type 24D - end - set ap-country US - config radio-1 - set band 802.11n - set vap-all disable - end - config radio-2 - set mode disabled - end - next - edit "FAP21D-default" - config platform - set type 21D - end - set ap-country US - config radio-1 - set band 802.11n - set vap-all disable - end - config radio-2 - set mode disabled - end - next - edit "FK214B-default" - config platform - set type 214B - end - set ap-country US - config radio-1 - set band 802.11n - set vap-all disable - end - config radio-2 - set mode disabled - end - next - edit "FAP224D-default" - config platform - set type 224D - end - set ap-country US - config radio-1 - set band 802.11n-5G - set vap-all disable - end - config radio-2 - set band 802.11n - set vap-all disable - end - next - edit "FAP222C-default" - config platform - set type 222C - end - set ap-country US - config radio-1 - set band 802.11n - set vap-all disable - end - config radio-2 - set band 802.11ac - set vap-all disable - end - next - edit "FAP25D-default" - config platform - set type 25D - end - set ap-country US - config radio-1 - set band 802.11n - set vap-all disable - end - config radio-2 - set mode disabled - end - next - edit "FAP221C-default" - config platform - set type 221C - end - set ap-country US - config radio-1 - set band 802.11n - set vap-all disable - end - config radio-2 - set band 802.11ac - set vap-all disable - end - next - edit "FAP320C-default" - config platform - set type 320C - end - set ap-country US - config radio-1 - set band 802.11n - set vap-all disable - end - config radio-2 - set band 802.11ac - set vap-all disable - end - next - edit "FAP28C-default" - config platform - set type 28C - end - set ap-country US - config radio-1 - set band 802.11n - set vap-all disable - end - config radio-2 - set mode disabled - end - next - edit "FAP223B-default" - config platform - set type 223B - end - set ap-country US - config radio-1 - set band 802.11n-5G - set vap-all disable - end - config radio-2 - set band 802.11n - set vap-all disable - end - next - edit "FAP14C-default" - config platform - set type 14C - end - set ap-country US - config radio-1 - set band 802.11n - set vap-all disable - end - config radio-2 - set mode disabled - end - next - edit "FAP11C-default" - config platform - set type 11C - end - set ap-country US - config radio-1 - set band 802.11n - set vap-all disable - end - config radio-2 - set mode disabled - end - next - edit "FAP320B-default" - config platform - set type 320B - end - set ap-country US - config radio-1 - set band 802.11n-5G - set vap-all disable - end - config radio-2 - set band 802.11n - set vap-all disable - end - next - edit "FAP112B-default" - config platform - set type 112B - end - set ap-country US - config radio-1 - set band 802.11n - set vap-all disable - end - config radio-2 - set mode disabled - end - next - edit "FAP222B-default" - config platform - set type 222B - end - set ap-country US - config radio-1 - set band 802.11n - set vap-all disable - end - config radio-2 - set band 802.11n-5G - set vap-all disable - end - next - edit "FAP210B-default" - config platform - set type 210B - end - set ap-country US - config radio-1 - set band 802.11n - set vap-all disable - end - config radio-2 - set mode disabled - end - next - edit "FAP220B-default" - set ap-country US - config radio-1 - set band 802.11n-5G - set vap-all disable - end - config radio-2 - set band 802.11n - set vap-all disable - end - next - edit "AP-11N-default" - config platform - set type AP-11N - end - set ap-country US - config radio-1 - set band 802.11n - end - config radio-2 - set mode disabled - end - next - edit "11n-only" - config platform - set type FWF - end - set ap-country US - config radio-1 - set band 802.11ac - end - config radio-2 - set mode disabled - end - next - edit "all-wifi-5ghz" - config platform - set type FWF - end - set ap-country US - config radio-1 - set band 802.11ac - set channel "36" "44" "149" "157" "165" - end - config radio-2 - set mode disabled - end - next - edit "2.4GHz-all" - config platform - set type FWF - end - set ap-country US - config radio-1 - set band 802.11n - set channel "1" "2" "3" "4" "5" "6" "7" "8" "9" "10" "11" - end - config radio-2 - set mode disabled - end - next -end -config wireless-controller wtp - edit "FWF60E-WIFI0" - set wtp-profile "2.4GHz-all" - config radio-1 - set override-channel enable - set channel "1" "2" "6" "10" "11" - end - next -end -config log memory setting - set status enable -end -config log null-device setting - set status disable -end -config log setting - set fwpolicy-implicit-log enable - set local-in-allow enable - set local-in-deny-unicast enable - set local-in-deny-broadcast enable - set local-out enable -end -config log gui-display - set fortiview-unscanned-apps enable - set fortiview-local-traffic enable -end -config alertemail setting - set username "fg60d@ff.cactus.de" - set mailto1 "tmp@cactus.de" - set IPS-logs enable - set IPsec-errors-logs enable - set sslvpn-authentication-errors-logs enable - set webfilter-logs enable - set violation-traffic-logs enable - set admin-login-logs enable - set FDS-license-expiring-warning enable -end -config router rip - config redistribute "connected" - end - config redistribute "static" - end - config redistribute "ospf" - end - config redistribute "bgp" - end - config redistribute "isis" - end -end -config router ripng - config redistribute "connected" - end - config redistribute "static" - end - config redistribute "ospf" - end - config redistribute "bgp" - end - config redistribute "isis" - end -end -config router static - edit 1 - set gateway 10.0.0.24 - set device "wan1" - next - edit 2 - set dst 10.0.0.36 255.255.255.255 - set gateway 10.0.0.18 - set device "internal" - next - edit 3 - set dst 10.0.0.53 255.255.255.255 - set gateway 10.0.0.52 - set device "internal" - set comment "wlan pi" - next - edit 4 - set dst 10.0.0.60 255.255.255.255 - set device "Cactus-DA" - set comment "VPN: Cactus-DA (Created by VPN wizard)" - next -end -config router ospf - config redistribute "connected" - end - config redistribute "static" - end - config redistribute "rip" - end - config redistribute "bgp" - end - config redistribute "isis" - end -end -config router ospf6 - config redistribute "connected" - end - config redistribute "static" - end - config redistribute "rip" - end - config redistribute "bgp" - end - config redistribute "isis" - end -end -config router bgp - config redistribute "connected" - end - config redistribute "rip" - end - config redistribute "ospf" - end - config redistribute "static" - end - config redistribute "isis" - end - config redistribute6 "connected" - end - config redistribute6 "rip" - end - config redistribute6 "ospf" - end - config redistribute6 "static" - end - config redistribute6 "isis" - end -end -config router isis - config redistribute "connected" - end - config redistribute "rip" - end - config redistribute "ospf" - end - config redistribute "bgp" - end - config redistribute "static" - end -end -config router multicast -end diff --git a/roles/test/files/importer/sample-configs/screenos_demo/ns_sys_config b/roles/test/files/importer/sample-configs/screenos_demo/ns_sys_config deleted file mode 100644 index 35119255dc..0000000000 --- a/roles/test/files/importer/sample-configs/screenos_demo/ns_sys_config +++ /dev/null @@ -1,164 +0,0 @@ -set clock timezone 1 -set vrouter trust-vr sharable -unset vrouter "trust-vr" auto-route-export -set service "GRE" protocol 47 src-port 0-65535 dst-port 0-65535 -set service "PIM" protocol 103 src-port 0-65535 dst-port 0-65535 -set service "SQL*Net V1" timeout 480 -set service "SQL*Net V2" timeout 480 -set service "SSH" timeout 480 -set service "tcp" protocol tcp src-port 1-65535 dst-port 1-1023 timeout 480 -set service "TCP_10000" protocol tcp src-port 0-65535 dst-port 10000-10000 -set service "TELNET" timeout 480 -set service "UDP_520" protocol udp src-port 0-65535 dst-port 520-520 -set service "UDP_53" protocol udp src-port 0-65535 dst-port 53-53 -set service "UDP_ALL" protocol udp src-port 0-65535 dst-port 0-65535 -set service "group_of_svcs" protocol tcp src-port 0-65535 dst-port 12-12 -set service "group_of_svcs" + tcp src-port 0-65535 dst-port 15-15 -set auth-server "Local" id 0 -set auth-server "Local" server-name "Local" -set auth default auth server "Local" -set admin name "cactus" -set admin password "nJvMCvrRKkuJcGRFrsEPAQCttjDIMn" -set admin user "fwcp" password "nO9FCHr2ASPJcl+FgsJKTGDtyPFcPn" privilege "all" -set admin user "readonly" password "nO7dB9rQOh7JcRABQs0DBeFt3CCp2n" privilege "read-only" -set admin manager-ip 192.168.1.0 255.255.255.0 -set admin auth timeout 60 -set admin auth server "Local" -set admin format unix -set zone "Trust" vrouter "trust-vr" -set zone "Untrust" vrouter "untrust-vr" -set zone "DMZ" vrouter "trust-vr" -set zone "VLAN" vrouter "trust-vr" -set zone "Trust" tcp-rst -set zone "Untrust" block -unset zone "Untrust" tcp-rst -set zone "MGT" block -set zone "DMZ" tcp-rst -set zone "VLAN" block -set zone "VLAN" tcp-rst -set zone "Untrust" screen tear-drop -set zone "Untrust" screen syn-flood -set zone "Untrust" screen ping-death -set zone "Untrust" screen ip-filter-src -set zone "Untrust" screen land -set zone "V1-Untrust" screen tear-drop -set zone "V1-Untrust" screen syn-flood -set zone "V1-Untrust" screen ping-death -set zone "V1-Untrust" screen ip-filter-src -set zone "V1-Untrust" screen land -set interface ethernet1 phy half 100mb -set interface ethernet2 phy full 100mb -set interface ethernet3 phy full 100mb -set interface ethernet4 phy full 100mb -set interface "ethernet1" zone "Trust" -set interface "ethernet2" zone "DMZ" -set interface "ethernet3" zone "Untrust" -set interface "ethernet4" zone "Trust" -unset interface vlan1 ip -set interface ethernet1 ip 192.168.1.3/24 -set interface ethernet1 route -set interface ethernet1 mtu 1500 -set interface ethernet3 mtu 1500 -unset interface vlan1 bypass-others-ipsec -unset interface vlan1 bypass-non-ip -set interface ethernet1 manage-ip 192.168.1.6 -set interface ethernet1 ip manageable -set interface ethernet3 manage ping -unset flow tcp-syn-check -set console page 20 -set hostname screenos_demo -set address "Trust" "1.1.1.1/32" 1.1.1.1 255.255.255.255 -set address "Trust" "10.1.1.4/30" 10.1.1.4 255.255.255.252 -set address "Trust" "Trust_1.2.3.0-24" 1.2.3.0 255.255.255.0 -set address "Trust" "Trust_1.2.3.4_hugo" 1.2.3.4 255.255.255.255 -set address "Trust" "Trust_1.2.3.6" 1.2.3.6 255.255.255.255 -set address "Trust" "Trust_1.2.3.8" 1.2.3.8 255.255.255.255 -set address "Trust" "Trust_1.2.3.9" 1.2.3.9 255.255.255.255 -set address "Untrust" "212.1.1.0/24" 212.1.1.0 255.255.255.0 -set address "Untrust" "47.11.47.11/32" 47.11.47.11 255.255.255.255 -set address "Untrust" "27.11.47.11/32" 27.11.47.11 255.255.255.255 -set address "Untrust" "Untrust_9.8.8.0-24" 9.8.8.0 255.255.255.0 -set address "Global" "211.0.0.0/8" 211.0.0.0 255.0.0.0 -set address "DMZ" "222.4.4.4/32" 222.4.4.4 255.255.255.255 -set address "DMZ" "DMZ_222.1.0.0-16_Webserver_Farm" 222.1.0.0 255.255.0.0 -set user "tim" uid 1 -set user "tim" type auth -set user "tim" hash-password "02HD1uCmBKnju9gbb+LZQ5hrydbuBZdVaJv0k=" -set user "tim" "enable" -set user-group "testgroup1" id 1 -set user-group "testgroup1" user "tim" -set ike respond-bad-spi 1 -set pki authority default scep mode "auto" -set pki x509 default cert-path partial -set pki x509 dn state-name "Germany" -set pki x509 dn local-name "Hesse" -set pki x509 dn org-name "FischkoppAG" -set pki x509 dn org-unit-name "oe666" -set pki x509 dn name "firewall1" -set pki x509 dn phone "+494711-0" -set group address "Trust" "Trust_group_intern_all" -set group address "Trust" "Trust_group_intern_all" add "Trust_1.2.3.6" -set group address "Trust" "Trust_group_intern_all" add "Trust_1.2.3.8" -set group address "Trust" "Trust_group_intern_all" add "Trust_1.2.3.9" -set group service "new-group" -set group service "new-group" add "GRE" -set url protocol sc-cpa -exit -set policy id 2 name "Access to web server" from "Untrust" to "DMZ" "Any" "DMZ_222.1.0.0-16_Webserver_Farm" "HTTP" permit log -set policy id 2 -set service "HTTPS" -exit -set policy id 1 name "von innen nach aussen" from "Trust" to "Untrust" "Trust_group_intern_all" "Any" "DNS" permit log -set policy id 1 -set service "FTP" -set service "H.323" -set service "HTTP" -set service "HTTPS" -set service "ICMP-ANY" -exit -set policy id 3 name "intern zu den webservern" from "Trust" to "DMZ" "Trust_group_intern_all" "DMZ_222.1.0.0-16_Webserver_Farm" "FTP" permit log -set policy id 3 -set service "HTTP" -set service "HTTPS" -set service "ICMP-ANY" -exit -set policy id 4 name "Access to mail server" from "Untrust" to "DMZ" "27.11.47.11/32" "222.4.4.4/32" "SMTP" permit log -set policy id 5 name "sending mail from internal net" from "Trust" to "DMZ" "Trust_group_intern_all" "222.4.4.4/32" "SMTP" permit -set policy id 6 name "getting time" from "DMZ" to "Untrust" "Any" "Any" "NTP" permit -set policy id 7 from "Trust" to "Global" "Trust_group_intern_all" "Any" "GRE" permit log -set policy id 8 from "DMZ" to "Trust" "DMZ_222.1.0.0-16_Webserver_Farm" "10.1.1.4/30" "SQL*Net V2" permit log -set policy id 9 name "news feed" from "Trust" to "Untrust" "Trust_group_intern_all" "212.1.1.0/24" "NNTP" permit log -set policy id 10 name "cheffe" from "Trust" to "Untrust" "1.1.1.1/32" "47.11.47.11/32" "GNUTELLA" permit -set policy id 11 name "stealth" from "Untrust" to "Global" "Any" "211.0.0.0/8" "ANY" deny log -set nsmgmt report alarm traffic enable -set nsmgmt report alarm attack enable -set nsmgmt report alarm other enable -set nsmgmt report alarm di enable -set nsmgmt report log config enable -set nsmgmt report log info enable -set nsmgmt report log self enable -set nsmgmt report log traffic enable -set nsmgmt init id D617233021D082F8C9D3AE9CE43E29EAF684283A00 -set nsmgmt server primary 192.168.1.1 port 7800 -set nsmgmt bulkcli reboot-timeout 60 -set nsmgmt hb-interval 20 -set nsmgmt hb-threshold 5 -set nsmgmt enable -set ssh version v2 -set ssh enable -set ssh pka-dsa user-name fwcp pka-key-id F817A719179A3CCB0C68 -set scp enable -set config lock timeout 5 -set dl-buf size 4718592 -set snmp port listen 161 -set snmp port trap 162 -set vrouter "untrust-vr" -exit -set vrouter "trust-vr" -unset add-default-route -exit -set vrouter "untrust-vr" -exit -set vrouter "trust-vr" -exit - diff --git a/roles/test/files/importer/ssh-keyscan.sh b/roles/test/files/importer/ssh-keyscan.sh deleted file mode 100644 index 8e90c01b7d..0000000000 --- a/roles/test/files/importer/ssh-keyscan.sh +++ /dev/null @@ -1,11 +0,0 @@ -#!/bin/sh -# run as fworch -SERVER_LIST="127.0.0.1" -#SERVER_LIST="admsrv websrvffm chatsrv test3 opnsense11 dnssrvffm alpsrvtest daba nagios sting-gw isodev isoback2 spiegel admsrvda iso-test-importer klaut gware wasp howto itchy mailin proxy proxylan spike vpn-gateway wwwprivat" -for h in $SERVER_LIST; do - ip=$(dig +search +short $h) - #ssh-keygen -R $h - #ssh-keygen -R "$ip" - ssh-keyscan -H "$ip" >> ~/.ssh/known_hosts - ssh-keyscan -H $h >> ~/.ssh/known_hosts -done diff --git a/roles/test/handlers/main.yml b/roles/test/handlers/main.yml deleted file mode 100644 index 7a838b6c7d..0000000000 --- a/roles/test/handlers/main.yml +++ /dev/null @@ -1,93 +0,0 @@ ---- -- name: delete test user and dir - user: - name: test - state: absent - remove: true - become: true - listen: "test importer handler" - -- name: delete test user cred config file - file: - path: "{{ fworch_secrets_dir }}/TestUserCreds.json" - state: absent - become: true - listen: "test importer handler" - -- block: - - name: delete test fortinet gateway - postgresql_query: - db: "{{ fworch_db_name }}" - query: > - DO $do$ BEGIN - DELETE FROM device WHERE dev_name='{{ test_fortigate_name }}'; - END $do$ - listen: "test importer handler" - - - name: delete test fortinet management - postgresql_query: - db: "{{ fworch_db_name }}" - query: > - DO $do$ BEGIN - DELETE FROM management WHERE mgm_name='{{ test_fortigate_name }}'; - END $do$ - listen: "test importer handler" - - - name: delete test checkpoint R8x credentials cascading to deletion of mgmt and gw - postgresql_query: - db: "{{ fworch_db_name }}" - query: > - DO $do$ BEGIN - DELETE FROM import_credential WHERE credential_name='{{ test_credential_name }}'; - END $do$ - listen: "test importer handler" - - - name: delete tenant tenant1 - postgresql_query: - db: "{{ fworch_db_name }}" - query: > - DO $do$ BEGIN - DELETE FROM tenant WHERE tenant_name='tenant1{{ sample_postfix }}'; - END $do$ - listen: "test importer handler" - - # - name: delete devices for tenant tenant1 - # postgresql_query: - # db: "{{ fworch_db_name }}" - # query: > - # DO $do$ BEGIN - # DELETE FROM tenant_to_device WHERE tenant_id=(SELECT tenant_id FROM tenant WHERE tenant_name='tenant1{{ sample_postfix }}'); - # END $do$ - # listen: "test importer handler" - - - name: delete tenant tenant2 - postgresql_query: - db: "{{ fworch_db_name }}" - query: > - DO $do$ BEGIN - DELETE FROM tenant WHERE tenant_name='tenant2{{ sample_postfix }}'; - END $do$ - listen: "test importer handler" - - become: true - become_user: postgres - -- name: find ldap entries with test_postfix - command: "ldapsearch -H {{ openldap_url }} -D {{ openldap_superuser_dn }} -y {{ ldap_manager_pwd_file }} -b {{ openldap_path }} -x '(|(cn=*{{ sample_postfix }}*)(ou=*{{ sample_postfix }}*)(uid=*{{ sample_postfix }}*))'" - register: ldap_entries_to_delete - listen: "test importer handler" - become: true - -- set_fact: - delete_list: "{{ ldap_entries_to_delete.stdout | replace('\n', '') }}" - listen: "test importer handler" - -- set_fact: - delete_list2: "{{ delete_list.split('dn: ')[1:] | sort(reverse = True) }}" - listen: "test importer handler" - -- name: delete ldap test data - command: "ldapdelete -H {{ openldap_url }} -D {{ openldap_superuser_dn }} -y {{ ldap_manager_pwd_file }} -x {{ item | regex_replace('\\s', '') | regex_replace('dc=internal.*', 'dc=internal') }}" - listen: "test importer handler" - loop: "{{ delete_list2 }}" - become: true diff --git a/roles/test/tasks/main.yml b/roles/test/tasks/main.yml deleted file mode 100644 index b59298d5c5..0000000000 --- a/roles/test/tasks/main.yml +++ /dev/null @@ -1,84 +0,0 @@ -# this playbook sets up some sample devices with configs to play around with -# postgresql-client - -- name: install packages necessary for testing - package: - name: "{{ item }}" - state: present - loop: "{{ test_packages }}" - become: true - environment: "{{ proxy_env }}" - -- name: randomize test names to avoid interference with production data - set_fact: - test_postfix: "_test_{{ randomly_generated_pwd }}" - -# todo: is this play needless? -- name: set postfix to brand all objects in this test run - set_fact: - sample_postfix: "{{ test_postfix }}" - -- name: create test user1 password - set_fact: - test_user1_pw: "{{ randomly_generated_pwd }}" - -- name: create test user2 password - set_fact: - test_user2_pw: "{{ randomly_generated_pwd }}" - -- name: initialize handler for deleting test data - set_fact: - test_importer_handler_guard: start - changed_when: true - notify: - - test importer handler - -- name: include test data - include_role: - name: sample-data - vars: - sample_role_purpose: test - sample_fortigate_name: "{{ test_fortigate_name }}" - sample_checkpoint_name: "{{ test_checkpoint_name }}" - sample_config_user: fworchtest - sample_config_user_home: "/home/{{ sample_config_user }}" - when: "'sampleserver' in group_names" - -- name: include test auth data - include_role: - name: sample-auth-data - vars: - sample_postfix: "{{ test_postfix }}" - sample_role_purpose: test - sample_user1_pw: "{{ test_user1_pw }}" - sample_user2_pw: "{{ test_user2_pw }}" - when: "'middlewareserver' in group_names" - -- name: database testing - import_tasks: test-database.yml - -- name: create config with test user creds - import_tasks: write-config-test-user-creds.yml - -- name: auth testing - import_tasks: test-auth.yml - when: "not run_on_github|bool" - -- name: api testing - import_tasks: test-api.yml - -- name: csharp testing - import_tasks: test-csharp.yml - -- name: imorter testing - import_tasks: test-importer.yml - when: "'sampleserver' in group_names" - -- name: testing all exposed web services - import_tasks: test-web.yml - -- name: finalize handler for deleting test data - set_fact: - test_importer_handler_guard: stop - changed_when: true - notify: "test importer handler" diff --git a/roles/test/tasks/test-api.yml b/roles/test/tasks/test-api.yml deleted file mode 100644 index 829d311689..0000000000 --- a/roles/test/tasks/test-api.yml +++ /dev/null @@ -1,113 +0,0 @@ -# this playbook contains api tests - -- name: test api version - uri: - url: https://{{ api_network_listening_ip_address }}:{{ api_web_port }}/api/v1/version - method: GET - headers: - Content-Type: application/json - body: - query: "" - body_format: json - validate_certs: false - return_content: true - register: api_version - changed_when: false - failed_when: false - -- name: api version test output - debug: - msg: "ERROR unexpected version test result (does not contain 'version'): {{ api_version.content }}" - when: api_version.content is not search('version') - -- name: test anonymous api access - uri: - url: https://{{ api_network_listening_ip_address }}:{{ api_web_port }}/api/v1/graphql - method: POST - headers: - Content-Type: application/json - x-hasura-role: anonymous - body: - query: "query { object(limit:3) {obj_name} }" - body_format: json - validate_certs: false - return_content: true - register: api_query_anonymous - changed_when: false - environment: "{{ proxy_env }}" - -- name: anonymous api access output - debug: - msg: "ERROR unexpected version test result (does not contain 'Missing Authorization header'): {{ api_query_anonymous.content }}" - when: api_query_anonymous.content is not search('Missing\sAuthorization\sheader') - -- name: get sample jwt - uri: - url: https://{{ middleware_hostname }}:{{ middleware_web_listener_port }}/api/AuthenticationToken/Get/ - method: POST - headers: - Content-Type: application/json - body: - Username: user1{{ test_postfix }} - Password: "{{ test_user1_pw }}" - body_format: json - validate_certs: false - return_content: true - register: sample_JWT - changed_when: false - environment: "{{ proxy_env }}" - -- name: test anonymous api access with JWT - uri: - url: https://{{ api_network_listening_ip_address }}:{{ api_web_port }}/api/v1/graphql - method: POST - headers: - Content-Type: application/json - # Remove leading and trailing text of jwt output - Authorization: Bearer {{ sample_JWT.content }} - body: - query: "query text { txt(limit:3) { id } }" - body_format: json - validate_certs: false - return_content: true - register: api_query_anonymous_with_JWT - changed_when: false - environment: "{{ proxy_env }}" - -- name: anonymous api access with JWT output - debug: - msg: "ERROR unexpected version test result (does not contain id): {{ api_query_anonymous_with_JWT.content }}" - when: api_query_anonymous_with_JWT.content is not search('id') - -# Todo: this only works if the hasura key is actually installed on the machine running the tests -- name: read hasura admin secret from file for tests - slurp: - src: "{{ fworch_secrets_dir }}/hasura_admin_pwd" - register: api_hasura_admin_secret - become: true - -- name: decode hasura admin secret - set_fact: - api_hasura_admin_secret: "{{ api_hasura_admin_secret['content'] | b64decode | trim }}" - -- name: test hasura-admin api access - uri: - url: https://{{ api_network_listening_ip_address }}:{{ api_web_port }}/api/v1/graphql - method: POST - headers: - Content-Type: application/json - x-hasura-role: admin - x-hasura-admin-secret: "{{ api_hasura_admin_secret }}" - body: - query: "query { object (limit: 1) {obj_name} }" - body_format: json - validate_certs: false - return_content: true - register: api_query_admin - changed_when: false - environment: "{{ proxy_env }}" - -- name: admin api access output - debug: - msg: "ERROR unexpected version test result (does not contain obj_name): {{ api_query_admin.content }}" - when: api_query_admin.content is not search('obj_name') diff --git a/roles/test/tasks/test-auth.yml b/roles/test/tasks/test-auth.yml deleted file mode 100644 index 7e0f662e2c..0000000000 --- a/roles/test/tasks/test-auth.yml +++ /dev/null @@ -1,107 +0,0 @@ -# this playbook contains middleware server tests - -- name: wait for middleware port to become available - wait_for: - port: "{{ middleware_web_listener_port }}" - host: "{{ middleware_hostname }}" - connect_timeout: 1 - delay: 10 - timeout: 25 - when: "not run_on_github|bool" - -- name: middleware test get jwt valid creds - uri: - url: https://{{ middleware_hostname }}:{{ middleware_web_listener_port }}/api/AuthenticationToken/Get/ - method: POST - headers: - Content-Type: application/json - body: - Username: user1{{ test_postfix }} - Password: "{{ test_user1_pw }}" - body_format: json - validate_certs: false - return_content: true - register: sample_jwt - changed_when: false -# environment: "{{ proxy_env }}" - -- debug: var=sample_jwt - -- set_fact: jwt_header="{{sample_jwt.content.split('.')[0]}}" - -- debug: var=jwt_header - -## adding potentially missing base64 "=" padding to header: -- set_fact: jwt_header="{{ jwt_header }}=" cacheable=true - when: "jwt_header|length % 4 > 0" - loop: - - 1 - - 2 - - 3 - -- debug: var=jwt_header - -- set_fact: jwt_header="{{ jwt_header|b64decode }}" -- debug: var=jwt_header -- set_fact: jwt_type="{{ jwt_header.typ }}" -- debug: var=jwt_type - -- name: middleware get jwt test valid creds output - debug: - msg: "ERROR unexpected jwt test result (jwt_type does not match 'JWT'): {{ jwt_type }}" - when: "jwt_type is not match('JWT')" - -- set_fact: jwt_encoded_payload="{{sample_jwt.content.split('.')[1]}}" - -- name: show jwt encoded payload pre padding - debug: var=jwt_encoded_payload -## adding potentially missing base64 = padding to payload: -- set_fact: jwt_encoded_payload="{{ jwt_encoded_payload }}=" cacheable=true - when: "jwt_encoded_payload|length % 4 > 0" - loop: - - 1 - - 2 - - 3 - -- name: show jwt encoded payload post padding - debug: var=jwt_encoded_payload - -- set_fact: jwt_payload="{{ jwt_encoded_payload|b64decode }}" - -- name: show jwt decoded payload - debug: var=jwt_payload - -- set_fact: jwt_unique_user_name="{{ jwt_payload.unique_name }}" - when: "'unique_name' in jwt_payload" - -- set_fact: jwt_unique_user_name="{{ jwt_payload.name }}" - when: "'name' in jwt_payload" - -- name: middleware get jwt check valid creds output user user1_test... - debug: - msg: "ERROR unexpected jwt test result (username does not match 'user1{{ test_postfix }}'): {{ jwt_unique_user_name }}" - when: "jwt_unique_user_name is not match('user1{{ test_postfix }}')" - -- name: middleware test get jwt wrong creds - uri: - url: https://{{ middleware_hostname }}:{{ middleware_web_listener_port }}/api/AuthenticationToken/Get/ - method: POST - headers: - Content-Type: application/json - body: - Username: user1{{ test_postfix }} - Password: wrong-pwd - body_format: json - validate_certs: false - return_content: true - register: sample_jwt - changed_when: false - ignore_errors: true - -- debug: - var: sample_jwt - -- name: middleware get jwt test wrong creds output - debug: - msg: "ERROR unexpected jwt test result (not equal 'error: Invalid credentials.'): {{ sample_jwt.content }}" - when: sample_jwt.content is not match(".*error.*Invalid\scredentials\..*") diff --git a/roles/test/tasks/test-csharp.yml b/roles/test/tasks/test-csharp.yml deleted file mode 100644 index 5a7e369870..0000000000 --- a/roles/test/tasks/test-csharp.yml +++ /dev/null @@ -1,23 +0,0 @@ - -- name: copy test files to frontend target - copy: - src: FWO.Test - dest: "{{ test_dir }}/csharp" - owner: "{{ fworch_user }}" - group: "{{ fworch_group }}" - become: true - -- name: csharp tests - command: dotnet test - args: - chdir: "{{ csharp_test_start_dir }}" - become: true - become_user: "{{ fworch_user }}" - register: csharp_tests - ignore_errors: false - environment: "{{ proxy_env }}" - -- name: show csharp test results in case of errors - debug: - var: csharp_tests - when: csharp_tests.rc != 0 diff --git a/roles/test/tasks/test-importer.yml b/roles/test/tasks/test-importer.yml deleted file mode 100644 index 8161370b54..0000000000 --- a/roles/test/tasks/test-importer.yml +++ /dev/null @@ -1,24 +0,0 @@ ---- -- name: make test fortinet import - command: "./fworch-importer-single.pl mgm_name={{ test_fortigate_name }}" - args: - chdir: "{{ fworch_home }}/importer" - become_user: "{{ fworch_user }}" - become: true - -- name: find management id for checkpoint test - postgresql_query: - db: fworchdb - query: > - SELECT mgm_id FROM management WHERE mgm_name='{{ test_checkpoint_name }}'; - become: true - become_user: postgres - register: test_checkpoint_mgm_id - -- name: make test checkpoint import - command: "python3 ./import-mgm.py -s -m{{ test_checkpoint_mgm_id.query_result.0.mgm_id }} -ihttps://fwodemodata.cactus.de/demo04_cpr8x.json" - args: - chdir: "{{ fworch_home }}/importer" - become: true - become_user: "{{ fworch_user }}" - environment: "{{ proxy_env }}" diff --git a/roles/test/tasks/test-web.yml b/roles/test/tasks/test-web.yml deleted file mode 100644 index 941dadd257..0000000000 --- a/roles/test/tasks/test-web.yml +++ /dev/null @@ -1,37 +0,0 @@ -# this playbook contains web server availabitlity tests - -# TODO - find out why UI sometimes crashes during upgrade of heavy data installations -- name: restart UI to avoid testing against crashed UI - ansible.builtin.systemd: - name: "{{ product_name }}-ui" - state: restarted - become: true - when: "'frontends' in group_names" - -- name: test web server availability - uri: - url: "{{ loop_url }}" - method: GET - headers: - Content-Type: html/text - body: - validate_certs: false - return_content: true - register: web_call_result - changed_when: false - failed_when: false - until: web_call_result.status == 200 - retries: 10 # 10 * 5 seconds - delay: 5 # Every 5 seconds - loop: - - "{{ middleware_uri }}/swagger/" - - https://{{ ui_hostname }}/ - - https://{{ api_network_listening_ip_address }}:9443/api/ - loop_control: - loop_var: loop_url - -- name: show webserver test results - fail: - msg: "url: {{ item.url }}, status: {{ item.status }}" - loop: "{{ web_call_result.results | from_yaml | list }}" - when: item.status!=200 diff --git a/roles/test/files/api/test-graphql.md b/roles/tests-integration/files/api/test-graphql.md similarity index 100% rename from roles/test/files/api/test-graphql.md rename to roles/tests-integration/files/api/test-graphql.md diff --git a/roles/test/files/api/test_api.sh b/roles/tests-integration/files/api/test_api.sh similarity index 100% rename from roles/test/files/api/test_api.sh rename to roles/tests-integration/files/api/test_api.sh diff --git a/roles/test/files/auth/config.ldif b/roles/tests-integration/files/auth/config.ldif similarity index 100% rename from roles/test/files/auth/config.ldif rename to roles/tests-integration/files/auth/config.ldif diff --git a/roles/test/files/auth/roles.ldif b/roles/tests-integration/files/auth/roles.ldif similarity index 94% rename from roles/test/files/auth/roles.ldif rename to roles/tests-integration/files/auth/roles.ldif index 6c3e36073c..7077311cdf 100644 --- a/roles/test/files/auth/roles.ldif +++ b/roles/tests-integration/files/auth/roles.ldif @@ -88,3 +88,9 @@ objectClass: top objectClass: groupofuniquenames cn: reviewer description: T0017 + +dn: cn=modeller,ou=role,dc=fworch,dc=internal +objectClass: top +objectClass: groupofuniquenames +cn: modeller +description: T0018 diff --git a/roles/test/files/importer/CP-R8x/iso_cp_r8x_api_generate_testdata.py b/roles/tests-integration/files/importer/CP-R8x/iso_cp_r8x_api_generate_testdata.py similarity index 100% rename from roles/test/files/importer/CP-R8x/iso_cp_r8x_api_generate_testdata.py rename to roles/tests-integration/files/importer/CP-R8x/iso_cp_r8x_api_generate_testdata.py diff --git a/roles/test/files/importer/CP-R8x/iso_cp_r8x_api_get_layer_names.py b/roles/tests-integration/files/importer/CP-R8x/iso_cp_r8x_api_get_layer_names.py similarity index 100% rename from roles/test/files/importer/CP-R8x/iso_cp_r8x_api_get_layer_names.py rename to roles/tests-integration/files/importer/CP-R8x/iso_cp_r8x_api_get_layer_names.py diff --git a/roles/tests-integration/files/importer/config_changes/changeRule.py b/roles/tests-integration/files/importer/config_changes/changeRule.py new file mode 100644 index 0000000000..4f94c0fb5a --- /dev/null +++ b/roles/tests-integration/files/importer/config_changes/changeRule.py @@ -0,0 +1,134 @@ +#!/usr/bin/python3 +# changes a random rule from a native fortigate config + +import random +import string +import os +import sys +import json +import logging + + +def random_octet(): + return str(random.randrange(0, 256)) + + +def random_ip(): + return random_octet() + '.' + random_octet() + '.' + random_octet() + '.' + random_octet() + + +def random_uid(): + s = ''.join(random.choices(string.ascii_lowercase + string.digits, k=32)) + return s[:8] + '-' + s[8:12] + '-' + s[12:16] + '-' + s[16:20] + '-' + s[20:] + + +# constants: +maxElements = 5 +commentChangeId = "FWORCH: " + +# fortiOS specific: +anyObj = { + "name": "all", + "q_origin_key": "all" + } + +srcString = 'srcaddr' +dstString = 'dstaddr' +nwObjString = "nw_obj_firewall/address" +deleteElement = False +changeSource = False + +if len(sys.argv) == 2: + config_path = sys.argv[1] +else: + logging.error('did not specify config file as parameter') + logging.error("syntax: changeRule.py configFileName") + exit(1) + +tempConfigFile = config_path + ".tmp" + +with open(config_path) as f: + config = json.load(f) + +# fortiOs settings: +rules = config['rules']['rules'] + + +numberOfRules = len(rules) +numberOfRules = round(numberOfRules/2) # only change the first half of the rules and keep the rest as is + +pickedRuleNumber = random.randrange(0, numberOfRules) +rule = rules[pickedRuleNumber] + +if random.randrange(0, 2)==0: + changeSource = True + ruleSide = rule[srcString] +else: + ruleSide = rule[dstString] + +if len(ruleSide)>=maxElements: + deleteElement=True + del ruleSide[len(ruleSide)-1] + +actionChoices = ['changeSrcOrDst', 'enDisable', 'reverseAction', 'reverseLogging'] + +actionChosen = actionChoices[random.randrange(0, len(actionChoices))] + +if actionChosen == 'changeSrcOrDst': + if not deleteElement: + newUid = random_uid() + newIp = random_ip() + + # cannot add to any obj, so delete it first + if anyObj in ruleSide: + del ruleSide[0] + + nwObj = { + "name": newIp, + "q_origin_key": newIp, + "uuid": newUid, + "subnet": [newIp, 32], + "type": "ipmask", + "obj-type": "ip", + "comment": commentChangeId + "random ip added as simulated change", + "associated-interface": "", + "color": 0 + } + config[nwObjString].append(nwObj) + + nwObjRef = { + "name": newIp, + "q_origin_key": newIp + } + ruleSide.append(nwObjRef) + +elif actionChosen == 'enDisable': + if rule['status'] == "enable": + rule['status'] = "disable" + else: + rule['status'] = "enable" +elif actionChosen == 'reverseAction': + if rule['action'] == "accept": + rule['action'] = "deny" + else: + rule['action'] = "accept" +elif actionChosen == 'reverseLogging': + if rule['logtraffic'] == "all" or rule['logtraffic'] == "utm": + rule['logtraffic'] = "disable" + else: + rule['logtraffic'] = "all" +else: + logging.warning("unknown action chosen: " + actionChosen ) +with open(tempConfigFile, 'w', encoding='utf-8') as f: + json.dump(config, f, ensure_ascii=False, indent=4) + +os.rename(tempConfigFile, config_path) +if changeSource: + sideString = 'source' +else: + sideString = 'destination' + +logText = 'changeRule simulator: changed rule no. ' + str(pickedRuleNumber)+ ', changeType=' + actionChosen +if actionChosen=='changeSrcOrDst': + logText += ', changed ' + sideString +logging.info(logText) diff --git a/roles/test/files/importer/config_changes/enlarge_rule.py b/roles/tests-integration/files/importer/config_changes/enlarge_rule.py similarity index 100% rename from roles/test/files/importer/config_changes/enlarge_rule.py rename to roles/tests-integration/files/importer/config_changes/enlarge_rule.py diff --git a/roles/sample-data/files/config_changes/write_date_to_comment.py b/roles/tests-integration/files/importer/config_changes/write_date_to_comment.py similarity index 100% rename from roles/sample-data/files/config_changes/write_date_to_comment.py rename to roles/tests-integration/files/importer/config_changes/write_date_to_comment.py diff --git a/roles/test/files/tenant_networks/create_tenant_network_data.py b/roles/tests-integration/files/tenant_networks/create_tenant_network_data.py similarity index 100% rename from roles/test/files/tenant_networks/create_tenant_network_data.py rename to roles/tests-integration/files/tenant_networks/create_tenant_network_data.py diff --git a/roles/tests-integration/handlers/main.yml b/roles/tests-integration/handlers/main.yml new file mode 100644 index 0000000000..56fffe7c18 --- /dev/null +++ b/roles/tests-integration/handlers/main.yml @@ -0,0 +1,77 @@ +--- +- name: delete test user cred config file + file: + path: "{{ fworch_secrets_dir }}/TestUserCreds.json" + state: absent + become: true + listen: "test importer handler" + +- block: + - name: delete test checkpoint R8x credentials cascading to deletion of mgmt and gw + postgresql_query: + db: "{{ fworch_db_name }}" + query: > + DO $do$ BEGIN + WITH target_mgm AS ( + SELECT m.mgm_id + FROM management m + JOIN import_credential ic ON ic.id = m.import_credential_id + WHERE ic.credential_name='{{ test_credential_name }}' + ), + target_imports AS ( + SELECT ic.control_id + FROM import_control ic + WHERE ic.mgm_id IN (SELECT mgm_id FROM target_mgm) + ) + DELETE FROM rule_metadata + WHERE mgm_id IN (SELECT mgm_id FROM target_mgm) + OR rule_created IN (SELECT control_id FROM target_imports); + DELETE FROM import_credential WHERE credential_name='{{ test_credential_name }}'; + END $do$ + listen: "test importer handler" + + - name: delete tenants tenant1_test and tenant2_test + postgresql_query: + db: "{{ fworch_db_name }}" + query: > + DO $do$ BEGIN + DELETE FROM tenant WHERE tenant_name='tenant1{{ test_postfix }}' OR tenant_name='tenant2{{ test_postfix }}'; + END $do$ + listen: "test importer handler" + + become: true + become_user: postgres + +- name: build ldap tls options + set_fact: + ldap_tls_opts: >- + {% if openldap_server_enable_ssl | default(false) -%} + -o TLS_REQCERT=never{% if openldap_server_cert is defined %} -o TLS_CACERT={{ openldap_server_cert }}{% endif %} + {%- endif %} + ldap_cmd_url: >- + {% if openldap_server_enable_ssl | default(false) -%} + ldaps://{{ openldap_server }}:{{ openldap_port | default(636) }} + {%- else -%} + ldap://{{ openldap_server }}:{{ (openldap_port | default(389) | int == 636) | ternary(389, openldap_port | default(389)) }} + {%- endif %} + listen: "test importer handler" + +- name: find ldap entries with test_postfix + command: "ldapsearch {{ ldap_tls_opts }} -H {{ ldap_cmd_url }} -D {{ openldap_superuser_dn }} -y {{ ldap_manager_pwd_file }} -b {{ openldap_path }} -x '(|(cn=*{{ sample_postfix }}*)(ou=*{{ sample_postfix }}*)(uid=*{{ sample_postfix }}*))'" + register: ldap_entries_to_delete + listen: "test importer handler" + become: true + +- set_fact: + delete_list: "{{ ldap_entries_to_delete.stdout | replace('\n', '') }}" + listen: "test importer handler" + +- set_fact: + delete_list2: "{{ delete_list.split('dn: ')[1:] | sort(reverse = True) }}" + listen: "test importer handler" + +- name: delete ldap test data + command: "ldapdelete {{ ldap_tls_opts }} -H {{ ldap_cmd_url }} -D {{ openldap_superuser_dn }} -y {{ ldap_manager_pwd_file }} -x {{ item | regex_replace('\\s', '') | regex_replace('dc=internal.*', 'dc=internal') }}" + listen: "test importer handler" + loop: "{{ delete_list2 }}" + become: true diff --git a/roles/test/tasks/b64pad.yml b/roles/tests-integration/tasks/b64pad.yml similarity index 100% rename from roles/test/tasks/b64pad.yml rename to roles/tests-integration/tasks/b64pad.yml diff --git a/roles/tests-integration/tasks/main.yml b/roles/tests-integration/tasks/main.yml new file mode 100644 index 0000000000..6da15c0b27 --- /dev/null +++ b/roles/tests-integration/tasks/main.yml @@ -0,0 +1,88 @@ + +- name: install packages necessary for testing + package: + name: "{{ item }}" + state: present + loop: "{{ test_packages }}" + become: true + environment: "{{ proxy_env }}" + +- name: randomize test names to avoid interference with production data + set_fact: + test_postfix: "_test_{{ randomly_generated_pwd }}" + +# todo: is this play needless? +- name: set postfix to brand all objects in this test run + set_fact: + sample_postfix: "{{ test_postfix }}" + +- name: create test user1 password + set_fact: + test_user1_pw: "{{ randomly_generated_pwd }}" + +- name: create test user2 password + set_fact: + test_user2_pw: "{{ randomly_generated_pwd }}" + +- name: initialize handler for deleting test data + set_fact: + test_importer_handler_guard: start + changed_when: true + notify: + - test importer handler + +- name: include test data + include_role: + name: sample-data + vars: + sample_role_purpose: test + sample_fortigate_name: "{{ test_fortigate_name }}" + sample_checkpoint_name: "{{ test_checkpoint_name }}" + sample_config_user: fworchtest + # sample_config_user_home: "/home/{{ sample_config_user }}" + when: "'sampleserver' in group_names" + +- name: include test auth data + include_role: + name: sample-auth-data + vars: + sample_postfix: "{{ test_postfix }}" + sample_role_purpose: test + sample_user1_pw: "{{ test_user1_pw }}" + sample_user2_pw: "{{ test_user2_pw }}" + when: "'middlewareserver' in group_names" + +- name: database testing + import_tasks: test-database.yml + when: "'databaseserver' in group_names" + +- name: create config with test user creds + import_tasks: write-config-test-user-creds.yml + +- name: auth testing + import_tasks: test-auth.yml + when: "'middlewareserver' in group_names" + +- name: api testing + import_tasks: test-api.yml + when: "'apiserver' in group_names" + +- name: imorter testing + import_tasks: test-importer.yml + when: "'sampleserver' in group_names" + +- name: testing all exposed web services + import_tasks: test-web.yml + +- name: finalize handler for deleting test data + set_fact: + test_importer_handler_guard: stop + changed_when: true + notify: "test importer handler" + +- name: delete ldif files + file: + path: "{{ middleware_ldif_dir }}" + state: absent + become: true + when: "'middlewareserver' in group_names" diff --git a/roles/tests-integration/tasks/test-api.yml b/roles/tests-integration/tasks/test-api.yml new file mode 100644 index 0000000000..fb7af762e3 --- /dev/null +++ b/roles/tests-integration/tasks/test-api.yml @@ -0,0 +1,119 @@ +# this playbook contains api tests + +- name: test api version + uri: + url: https://{{ api_network_listening_ip_address }}:{{ api_web_port }}/api/v1/version + method: GET + headers: + Content-Type: application/json + body: + query: "" + body_format: json + validate_certs: false + return_content: true + register: api_version + changed_when: false + failed_when: false + +- name: api version test output + assert: + that: + - api_version.content is search('version') + fail_msg: "unexpected version test result (does not contain 'version'): {{ api_version.content }}" + +- name: test anonymous api access + uri: + url: https://{{ api_network_listening_ip_address }}:{{ api_web_port }}/api/v1/graphql + method: POST + headers: + Content-Type: application/json + x-hasura-role: anonymous + body: + query: "query { object(limit:3) {obj_name} }" + body_format: json + validate_certs: false + return_content: true + register: api_query_anonymous + changed_when: false + environment: "{{ proxy_env }}" + +- name: anonymous api access output + assert: + that: + - > + api_query_anonymous.content is search("Missing 'Authorization' or 'Cookie' header in JWT authentication mode") + or api_query_anonymous.content is search("Missing 'Authorization' or 'Cookie' header") + fail_msg: 'unexpected version test result (does not contain "Missing ''Authorization'' or ''Cookie'' header in JWT authentication mode"): {{ api_query_anonymous.content }}' + +- name: get sample jwt + uri: + url: https://{{ middleware_hostname }}:{{ middleware_web_listener_port }}/api/AuthenticationToken/Get/ + method: POST + headers: + Content-Type: application/json + body: + Username: user1{{ test_postfix }} + Password: "{{ test_user1_pw }}" + body_format: json + validate_certs: false + return_content: true + register: sample_JWT + changed_when: false + environment: "{{ proxy_env }}" + +- name: test anonymous api access with JWT + uri: + url: https://{{ api_network_listening_ip_address }}:{{ api_web_port }}/api/v1/graphql + method: POST + headers: + Content-Type: application/json + # Remove leading and trailing text of jwt output + Authorization: Bearer {{ sample_JWT.content }} + body: + query: "query text { txt(limit:3) { id } }" + body_format: json + validate_certs: false + return_content: true + register: api_query_anonymous_with_JWT + changed_when: false + environment: "{{ proxy_env }}" + +- name: anonymous api access with JWT output + assert: + that: + - api_query_anonymous_with_JWT.content is search('id') + fail_msg: "unexpected version test result (does not contain id): {{ api_query_anonymous_with_JWT.content }}" + +# Todo: this only works if the hasura key is actually installed on the machine running the tests +- name: read hasura admin secret from file for tests + slurp: + src: "{{ fworch_secrets_dir }}/hasura_admin_pwd" + register: api_hasura_admin_secret + become: true + +- name: decode hasura admin secret + set_fact: + api_hasura_admin_secret: "{{ api_hasura_admin_secret['content'] | b64decode | trim }}" + +- name: test hasura-admin api access + uri: + url: https://{{ api_network_listening_ip_address }}:{{ api_web_port }}/api/v1/graphql + method: POST + headers: + Content-Type: application/json + x-hasura-role: admin + x-hasura-admin-secret: "{{ api_hasura_admin_secret }}" + body: + query: "{ stm_obj_typ(limit: 1) { obj_typ_name } }" + body_format: json + validate_certs: false + return_content: true + register: api_query_admin + changed_when: false + environment: "{{ proxy_env }}" + +- name: admin api access output + assert: + that: + - api_query_admin.content is search('obj_typ_name') + fail_msg: "unexpected version test result (does not contain obj_typ_name): {{ api_query_admin.content }}" diff --git a/roles/tests-integration/tasks/test-auth.yml b/roles/tests-integration/tasks/test-auth.yml new file mode 100644 index 0000000000..438b9aa138 --- /dev/null +++ b/roles/tests-integration/tasks/test-auth.yml @@ -0,0 +1,117 @@ +# this playbook contains middleware server tests + +- name: wait for middleware port to become available + ansible.builtin.wait_for: + port: "{{ middleware_web_listener_port }}" + host: "{{ middleware_hostname }}" + connect_timeout: 1 + delay: 10 + timeout: 25 + +- name: middleware test get jwt valid creds + ansible.builtin.uri: + url: "https://{{ middleware_hostname }}:{{ middleware_web_listener_port }}/api/AuthenticationToken/Get/" + method: POST + headers: + Content-Type: application/json + body: + Username: "user1{{ test_postfix }}" + Password: "{{ test_user1_pw }}" + body_format: json + validate_certs: false + return_content: true + register: sample_jwt + changed_when: false +# environment: "{{ proxy_env }}" + +- ansible.builtin.debug: + var: sample_jwt + +# --- JWT header decode (base64url -> json) --- +- name: extract raw jwt header and payload segments + ansible.builtin.set_fact: + jwt_header_raw: "{{ sample_jwt.content.split('.')[0] }}" + jwt_payload_raw: "{{ sample_jwt.content.split('.')[1] }}" + +# pad and translate base64url for header +- name: normalize/pad base64url header + ansible.builtin.set_fact: + jwt_header_b64: >- + {{ jwt_header_raw + | regex_replace('-', '+') + | regex_replace('_', '/') + ~ ('=' * ((4 - (jwt_header_raw | length % 4)) % 4)) }} + +- ansible.builtin.debug: { var: jwt_header_b64 } + +- name: decode + parse header json + ansible.builtin.set_fact: + jwt_header: "{{ jwt_header_b64 | b64decode | from_json }}" + +- ansible.builtin.debug: { var: jwt_header } + +- name: pick header 'typ' + ansible.builtin.set_fact: + jwt_type: "{{ jwt_header['typ'] | default(jwt_header.typ, true) }}" + +- ansible.builtin.debug: { var: jwt_type } + +- name: middleware get jwt test valid creds output + ansible.builtin.debug: + msg: "ERROR unexpected jwt test result (jwt_type does not match 'JWT'): {{ jwt_type }}" + when: "jwt_type is not match('JWT')" + +# --- JWT payload decode (base64url -> json) --- +- name: normalize/pad base64url payload + ansible.builtin.set_fact: + jwt_payload_b64: >- + {{ jwt_payload_raw + | regex_replace('-', '+') + | regex_replace('_', '/') + ~ ('=' * ((4 - (jwt_payload_raw | length % 4)) % 4)) }} + +- ansible.builtin.debug: + var: jwt_payload_b64 + +- name: decode + parse payload json + ansible.builtin.set_fact: + jwt_payload: "{{ jwt_payload_b64 | b64decode | from_json }}" + +- name: show jwt decoded payload + ansible.builtin.debug: + var: jwt_payload + +- name: select username from payload (unique_name or name) + ansible.builtin.set_fact: + jwt_unique_user_name: >- + {{ ( 'unique_name' in jwt_payload ) | ternary(jwt_payload.unique_name, jwt_payload.name) }} + +- name: Verify JWT Middleware and Check Valid Credentials, Output User 'user1_test' + ansible.builtin.debug: + msg: "ERROR: Unexpected JWT test result (username does not match 'user1{{ test_postfix }}'): {{ jwt_unique_user_name }}" + when: "jwt_unique_user_name != 'user1' ~ test_postfix" + +# --- negative test: wrong credentials --- +- name: middleware test get jwt wrong creds + ansible.builtin.uri: + url: "https://{{ middleware_hostname }}:{{ middleware_web_listener_port }}/api/AuthenticationToken/Get/" + method: POST + headers: + Content-Type: application/json + body: + Username: "user1{{ test_postfix }}" + Password: "wrong-pwd" + body_format: json + validate_certs: false + return_content: true + register: sample_jwt + changed_when: false + ignore_errors: true + +- ansible.builtin.debug: + var: sample_jwt + +- name: middleware get jwt test wrong creds output + ansible.builtin.debug: + msg: "ERROR unexpected jwt test result (not equal 'error: Invalid credentials.'): {{ sample_jwt.content }}" + when: sample_jwt.content is not match(".*error.*Invalid\\scredentials\\..*") diff --git a/roles/test/tasks/test-database.yml b/roles/tests-integration/tasks/test-database.yml similarity index 100% rename from roles/test/tasks/test-database.yml rename to roles/tests-integration/tasks/test-database.yml diff --git a/roles/tests-integration/tasks/test-importer.yml b/roles/tests-integration/tasks/test-importer.yml new file mode 100644 index 0000000000..b8aab1e9ff --- /dev/null +++ b/roles/tests-integration/tasks/test-importer.yml @@ -0,0 +1,42 @@ +--- +- name: find management id for checkpoint test + postgresql_query: + db: fworchdb + query: SELECT mgm_id FROM management WHERE mgm_name='{{ test_checkpoint_name }}'; + become: true + become_user: postgres + register: test_checkpoint_mgm_id + +- name: find management id for fortigate test + postgresql_query: + db: fworchdb + query: SELECT mgm_id FROM management WHERE mgm_name='{{ test_fortigate_name }}'; + become: true + become_user: postgres + register: test_fortigate_mgm_id + +- name: make test checkpoint import + ansible.builtin.command: + cmd: > + {{ importer_venv_dir }}/bin/python3 + ./import_mgm.py -f -s -m{{ test_checkpoint_mgm_id.query_result.0.mgm_id }} + chdir: "{{ fworch_home }}/importer" + become: true + become_user: "{{ fworch_user }}" + environment: "{{ proxy_env }}" + register: test_checkpoint_import_result + failed_when: > + test_checkpoint_import_result.rc != 0 + or (test_checkpoint_import_result.stderr is defined + and test_checkpoint_import_result.stderr is search('\\[ERROR\\]')) + +- name: show checkpoint import result + debug: + var: test_checkpoint_import_result +# - name: make test fortigate import +# command: "python3 ./import_mgm.py -f -s -m{{ test_fortigate_mgm_id.query_result.0.mgm_id }}" +# args: +# chdir: "{{ fworch_home }}/importer" +# become: true +# become_user: "{{ fworch_user }}" +# environment: "{{ proxy_env }}" diff --git a/roles/tests-integration/tasks/test-web.yml b/roles/tests-integration/tasks/test-web.yml new file mode 100644 index 0000000000..282a8dbc5d --- /dev/null +++ b/roles/tests-integration/tasks/test-web.yml @@ -0,0 +1,67 @@ +# this playbook contains web server availabitlity tests + +- name: test middleware web server availability + uri: + url: "{{ middleware_uri }}/swagger/" + method: GET + headers: + Content-Type: html/text + body: + validate_certs: false + return_content: true + register: web_call_result + changed_when: false + failed_when: false + until: web_call_result.status == 200 + retries: 10 # 10 * 5 seconds + delay: 5 # Every 5 seconds + when: "'middlewareserver' in group_names" + +- name: show middleware webserver test results + fail: + msg: "url: {{ web_call_result.url }}, status: {{ web_call_result.status }}" + when: "'middlewareserver' in group_names and web_call_result.status!=200" + +- name: test api web server availability + uri: + url: "https://{{ api_network_listening_ip_address }}:9443/api/" + method: GET + headers: + Content-Type: html/text + body: + validate_certs: false + return_content: true + register: web_call_result + changed_when: false + failed_when: false + until: web_call_result.status == 200 + retries: 10 # 10 * 5 seconds + delay: 5 # Every 5 seconds + when: "'apiserver' in group_names" + +- name: show api webserver test results + fail: + msg: "url: {{ web_call_result.url }}, status: {{ web_call_result.status }}" + when: "'apiserver' in group_names and web_call_result.status!=200" + +- name: test ui web server availability + uri: + url: "https://{{ ui_hostname }}/" + method: GET + headers: + Content-Type: html/text + body: + validate_certs: false + return_content: true + register: web_call_result + changed_when: false + failed_when: false + until: web_call_result.status == 200 + retries: 10 # 10 * 5 seconds + delay: 5 # Every 5 seconds + when: "'frontends' in group_names" + +- name: show ui webserver test results + fail: + msg: "url: {{ web_call_result.url }}, status: {{ web_call_result.status }}" + when: "'frontends' in group_names and web_call_result.status!=200" diff --git a/roles/test/tasks/write-config-test-user-creds.yml b/roles/tests-integration/tasks/write-config-test-user-creds.yml similarity index 100% rename from roles/test/tasks/write-config-test-user-creds.yml rename to roles/tests-integration/tasks/write-config-test-user-creds.yml diff --git a/roles/tests-unit/files/FWO.Test/ActionHandlerTest.cs b/roles/tests-unit/files/FWO.Test/ActionHandlerTest.cs new file mode 100644 index 0000000000..87a734e54e --- /dev/null +++ b/roles/tests-unit/files/FWO.Test/ActionHandlerTest.cs @@ -0,0 +1,424 @@ +using FWO.Api.Client; +using FWO.Api.Client.Queries; +using FWO.Config.Api; +using FWO.Data; +using FWO.Data.Workflow; +using FWO.Middleware.Client; +using FWO.Services.Workflow; +using NUnit.Framework; +using System.Reflection; + +namespace FWO.Test +{ + [TestFixture] + internal class ActionHandlerTest + { + private sealed class ActionHandlerTestApiConn : SimulatedApiConnection + { + public List States { get; set; } = []; + public List Queries { get; } = []; + private readonly List managements = [new() { Id = 1, Name = "Mgmt1" }]; + private readonly List rules = + [ + new Rule + { + Id = 1, + Uid = "rule-1", + MgmtId = 1, + Action = "accept", + Services = [new ServiceWrapper { Content = new NetworkService { Uid = "svc-pass", Name = "SvcPass" } }] + } + ]; + private readonly CompliancePolicy compliantPolicy = new() + { + Id = 5, + Criteria = + [ + new ComplianceCriterionWrapper + { + Content = new ComplianceCriterion { Id = 1, Name = "PassPolicy", CriterionType = nameof(CriterionType.ForbiddenService), Content = "svc-deny" } + } + ] + }; + private readonly CompliancePolicy nonCompliantPolicy = new() + { + Id = 9, + Criteria = + [ + new ComplianceCriterionWrapper + { + Content = new ComplianceCriterion { Id = 2, Name = "FailPolicy", CriterionType = nameof(CriterionType.ForbiddenService), Content = "svc-pass" } + } + ] + }; + + public override Task SendQueryAsync(string query, object? variables = null, string? operationName = null) + { + Queries.Add(query); + if (query == RequestQueries.getStates) + { + return Task.FromResult((T)(object)States); + } + if (query == MonitorQueries.addAlert) + { + return Task.FromResult((T)(object)new ReturnIdWrapper()); + } + if (query == DeviceQueries.getManagementNames) + { + return Task.FromResult((T)(object)managements); + } + if (query == RuleQueries.countActiveRules) + { + return Task.FromResult((T)(object)new AggregateCount { Aggregate = new Aggregate { Count = rules.Count } }); + } + if (query == RuleQueries.getRulesForSelectedManagements || query == RuleQueries.getRuleDetailsById) + { + return Task.FromResult((T)(object)rules); + } + if (query == ImportQueries.getMaxImportId) + { + return Task.FromResult((T)(object)new Import()); + } + if (query == ComplianceQueries.getPolicyById) + { + int policyId = GetVariable(variables, "id"); + return Task.FromResult((T)(object)(policyId == compliantPolicy.Id ? compliantPolicy : nonCompliantPolicy)); + } + throw new AssertionException($"Unexpected query: {query}"); + } + + private static TValue GetVariable(object? variables, string propertyName) + { + PropertyInfo? property = variables?.GetType().GetProperty(propertyName); + return property != null ? (TValue)property.GetValue(variables)! : default!; + } + } + + private sealed class ActionHandlerTestPolicyChecker : IRequestedRulePolicyChecker + { + public bool Result { get; set; } + public List? PolicyIds { get; private set; } + public List? RequestTaskIds { get; private set; } + + public Task AreRequestTasksCompliant(IEnumerable policyIds, IEnumerable requestTasks) + { + PolicyIds = policyIds.ToList(); + RequestTaskIds = requestTasks.Select(task => task.Id).ToList(); + return Task.FromResult(Result); + } + } + + private static WfStateActionDataHelper CreateAction(string eventName, string actionType, string scope, string phase = "") + { + return new WfStateActionDataHelper + { + Action = new WfStateAction + { + Event = eventName, + ActionType = actionType, + Scope = scope, + Phase = phase + } + }; + } + + private static WfTicket CreateTicket(params WfReqTask[] tasks) + { + return new WfTicket + { + StateId = 1, + Tasks = [.. tasks] + }; + } + + private static WfReqTask CreateEligibleRequestTask(long id, int managementId = 1, string title = "Allow request") + { + return new WfReqTask + { + Id = id, + ManagementId = managementId, + Title = title, + Elements = + [ + new WfReqElement { Field = ElemFieldType.source.ToString(), IpString = "10.0.0.1/32", Name = "src" }, + new WfReqElement { Field = ElemFieldType.destination.ToString(), IpString = "10.0.1.1/32", Name = "dst" }, + new WfReqElement { Field = ElemFieldType.service.ToString(), Port = 443, ProtoId = 6, Name = "https" }, + new WfReqElement { Field = ElemFieldType.rule.ToString(), RuleUid = $"rule-{id}" } + ] + }; + } + + [Test] + public async Task GetOfferedActions_FiltersByEventAndPhase() + { + ActionHandlerTestApiConn apiConn = new(); + apiConn.States = + [ + new WfState + { + Id = 1, + Actions = + [ + CreateAction(StateActionEvents.OfferButton.ToString(), StateActionTypes.DoNothing.ToString(), WfObjectScopes.Ticket.ToString()), + CreateAction(StateActionEvents.OfferButton.ToString(), StateActionTypes.DoNothing.ToString(), WfObjectScopes.Ticket.ToString(), WorkflowPhases.planning.ToString()), + CreateAction(StateActionEvents.OnSet.ToString(), StateActionTypes.DoNothing.ToString(), WfObjectScopes.Ticket.ToString()) + ] + } + ]; + WfHandler wfHandler = new(); + ActionHandler handler = new(apiConn, wfHandler); + await handler.Init(); + WfTicket ticket = new() { StateId = 1 }; + + List actions = handler.GetOfferedActions(ticket, WfObjectScopes.Ticket, WorkflowPhases.request); + + Assert.That(actions, Has.Count.EqualTo(1)); + Assert.That(actions[0].Event, Is.EqualTo(StateActionEvents.OfferButton.ToString())); + } + + [Test] + public async Task DoStateChangeActions_RunsOnSetAndOnLeave_AndResetsStateChanged() + { + ActionHandlerTestApiConn apiConn = new(); + apiConn.States = + [ + new WfState + { + Id = 1, + Actions = + [ + CreateAction(StateActionEvents.OnSet.ToString(), StateActionTypes.SetAlert.ToString(), WfObjectScopes.Ticket.ToString()) + ] + }, + new WfState + { + Id = 0, + Actions = + [ + CreateAction(StateActionEvents.OnLeave.ToString(), StateActionTypes.SetAlert.ToString(), WfObjectScopes.Ticket.ToString()) + ] + } + ]; + WfHandler wfHandler = new(); + ActionHandler handler = new(apiConn, wfHandler); + await handler.Init(); + WfTicket ticket = new(); + ticket.StateId = 1; + + await handler.DoStateChangeActions(ticket, WfObjectScopes.Ticket); + + Assert.That(apiConn.Queries.Count(q => q == MonitorQueries.addAlert), Is.EqualTo(2)); + Assert.That(ticket.StateChanged(), Is.False); + } + + [Test] + public async Task DoOwnerChangeActions_ExecutesOwnerChangeActions() + { + ActionHandlerTestApiConn apiConn = new(); + apiConn.States = + [ + new WfState + { + Id = 1, + Actions = + [ + CreateAction(StateActionEvents.OwnerChange.ToString(), StateActionTypes.SetAlert.ToString(), WfObjectScopes.None.ToString()) + ] + } + ]; + WfHandler wfHandler = new(); + ActionHandler handler = new(apiConn, wfHandler); + await handler.Init(); + WfTicket ticket = new() { StateId = 1 }; + + await handler.DoOwnerChangeActions(ticket, new FwoOwner { Id = 1 }, 123); + + Assert.That(apiConn.Queries.Count(q => q == MonitorQueries.addAlert), Is.EqualTo(1)); + } + + [Test] + public async Task DoOnAssignmentActions_ExecutesAssignmentActions() + { + ActionHandlerTestApiConn apiConn = new(); + apiConn.States = + [ + new WfState + { + Id = 1, + Actions = + [ + CreateAction(StateActionEvents.OnAssignment.ToString(), StateActionTypes.SetAlert.ToString(), WfObjectScopes.None.ToString()) + ] + } + ]; + WfHandler wfHandler = new(); + ActionHandler handler = new(apiConn, wfHandler); + await handler.Init(); + WfTicket ticket = new() { StateId = 1 }; + + await handler.DoOnAssignmentActions(ticket, "dn=test"); + + Assert.That(apiConn.Queries.Count(q => q == MonitorQueries.addAlert), Is.EqualTo(1)); + } + + [Test] + public async Task PerformAction_AutoPromoteConditionalPolicyCheckConfigured_PromotesToOkState() + { + ActionHandlerTestApiConn apiConn = new(); + apiConn.States = + [ + new WfState { Id = 1 }, + new WfState { Id = 2 }, + new WfState { Id = 3 } + ]; + SimulatedGlobalConfig globalConfig = new() { ComplianceCheckRelevantManagements = "1" }; + ActionHandlerTestPolicyChecker policyChecker = new() { Result = true }; + WfHandler wfHandler = new((_, _, _, _) => { }, new UserConfig(globalConfig, false), new System.Security.Claims.ClaimsPrincipal(), apiConn, new MiddlewareClient("http://localhost/"), WorkflowPhases.request, policyChecker); + ActionHandler handler = new(apiConn, wfHandler); + await handler.Init(); + WfTicket ticket = CreateTicket(CreateEligibleRequestTask(11)); + WfStateAction action = new() + { + ActionType = StateActionTypes.AutoPromote.ToString(), + ExternalParams = "{\"to_be_called\":\"PolicyCheck\",\"policy_ids\":[5,9],\"if_compliant_state\":2,\"if_not_compliant_state\":3}" + }; + + await handler.PerformAction(action, ticket, WfObjectScopes.Ticket); + + Assert.That(ticket.StateId, Is.EqualTo(2)); + Assert.That(policyChecker.PolicyIds, Is.EqualTo(new List { 5, 9 })); + Assert.That(policyChecker.RequestTaskIds, Is.EqualTo(new List { 11 })); + } + + [Test] + public async Task PerformAction_AutoPromoteConditionalPolicyCheckMissing_PromotesToNotOkState() + { + ActionHandlerTestApiConn apiConn = new(); + apiConn.States = + [ + new WfState { Id = 1 }, + new WfState { Id = 2 }, + new WfState { Id = 3 } + ]; + SimulatedGlobalConfig globalConfig = new() { ComplianceCheckRelevantManagements = "1" }; + ActionHandlerTestPolicyChecker policyChecker = new() { Result = false }; + WfHandler wfHandler = new((_, _, _, _) => { }, new UserConfig(globalConfig, false), new System.Security.Claims.ClaimsPrincipal(), apiConn, new MiddlewareClient("http://localhost/"), WorkflowPhases.request, policyChecker); + ActionHandler handler = new(apiConn, wfHandler); + await handler.Init(); + WfTicket ticket = CreateTicket(CreateEligibleRequestTask(12)); + WfStateAction action = new() + { + ActionType = StateActionTypes.AutoPromote.ToString(), + ExternalParams = "{\"to_be_called\":\"PolicyCheck\",\"policy_ids\":[9],\"check_result_label\":\"policy_check\",\"if_compliant_state\":2,\"if_not_compliant_state\":3}" + }; + + await handler.PerformAction(action, ticket, WfObjectScopes.Ticket); + + Assert.That(ticket.StateId, Is.EqualTo(3)); + Assert.That(ticket.Tasks[0].GetAddInfoValue("policy_check"), Is.EqualTo("false")); + Assert.That(policyChecker.RequestTaskIds, Is.EqualTo(new List { 12 })); + } + + [Test] + public async Task PerformAction_AutoPromoteConditionalPolicyCheckWithLabel_PersistsTrueResult() + { + ActionHandlerTestApiConn apiConn = new(); + apiConn.States = [new WfState { Id = 1 }, new WfState { Id = 2 }, new WfState { Id = 3 }]; + SimulatedGlobalConfig globalConfig = new() { ComplianceCheckRelevantManagements = "1" }; + WfHandler wfHandler = new((_, _, _, _) => { }, new UserConfig(globalConfig, false), new System.Security.Claims.ClaimsPrincipal(), apiConn, new MiddlewareClient("http://localhost/"), WorkflowPhases.request, new ActionHandlerTestPolicyChecker() { Result = true }); + ActionHandler handler = new(apiConn, wfHandler); + await handler.Init(); + WfTicket ticket = CreateTicket(CreateEligibleRequestTask(13)); + WfStateAction action = new() + { + ActionType = StateActionTypes.AutoPromote.ToString(), + ExternalParams = "{\"to_be_called\":\"PolicyCheck\",\"policy_ids\":[5],\"check_result_label\":\"policy_check\",\"if_compliant_state\":2,\"if_not_compliant_state\":3}" + }; + + await handler.PerformAction(action, ticket, WfObjectScopes.Ticket); + + Assert.That(ticket.StateId, Is.EqualTo(2)); + Assert.That(ticket.Tasks[0].GetAddInfoValue("policy_check"), Is.EqualTo("true")); + } + + [Test] + public async Task PerformAction_AutoPromoteConditionalPolicyCheckWithoutLabel_DoesNotWriteAdditionalInfo() + { + ActionHandlerTestApiConn apiConn = new(); + apiConn.States = [new WfState { Id = 1 }, new WfState { Id = 2 }, new WfState { Id = 3 }]; + SimulatedGlobalConfig globalConfig = new() { ComplianceCheckRelevantManagements = "1" }; + WfHandler wfHandler = new((_, _, _, _) => { }, new UserConfig(globalConfig, false), new System.Security.Claims.ClaimsPrincipal(), apiConn, new MiddlewareClient("http://localhost/"), WorkflowPhases.request, new ActionHandlerTestPolicyChecker() { Result = true }); + ActionHandler handler = new(apiConn, wfHandler); + await handler.Init(); + WfTicket ticket = CreateTicket(CreateEligibleRequestTask(14)); + WfStateAction action = new() + { + ActionType = StateActionTypes.AutoPromote.ToString(), + ExternalParams = "{\"to_be_called\":\"PolicyCheck\",\"policy_ids\":[5],\"check_result_label\":\"\",\"if_compliant_state\":2,\"if_not_compliant_state\":3}" + }; + + await handler.PerformAction(action, ticket, WfObjectScopes.Ticket); + + Assert.That(ticket.Tasks[0].AdditionalInfo, Is.Null.Or.Empty); + } + + [Test] + public async Task PerformAction_AutoPromoteConditionalPolicyCheck_OnlyEligibleTasksAreCheckedAndLabelled() + { + ActionHandlerTestApiConn apiConn = new(); + apiConn.States = [new WfState { Id = 1 }, new WfState { Id = 2 }, new WfState { Id = 3 }]; + SimulatedGlobalConfig globalConfig = new() { ComplianceCheckRelevantManagements = "1" }; + ActionHandlerTestPolicyChecker policyChecker = new() { Result = true }; + WfHandler wfHandler = new((_, _, _, _) => { }, new UserConfig(globalConfig, false), new System.Security.Claims.ClaimsPrincipal(), apiConn, new MiddlewareClient("http://localhost/"), WorkflowPhases.request, policyChecker); + ActionHandler handler = new(apiConn, wfHandler); + await handler.Init(); + WfReqTask eligibleTask = CreateEligibleRequestTask(15); + WfReqTask ineligibleTask = new() + { + Id = 16, + ManagementId = 1, + Title = "Incomplete request", + Elements = + [ + new WfReqElement { Field = ElemFieldType.source.ToString(), IpString = "10.0.0.1/32", Name = "src" }, + new WfReqElement { Field = ElemFieldType.rule.ToString(), RuleUid = "rule-incomplete" } + ] + }; + WfTicket ticket = CreateTicket(eligibleTask, ineligibleTask); + WfStateAction action = new() + { + ActionType = StateActionTypes.AutoPromote.ToString(), + ExternalParams = "{\"to_be_called\":\"PolicyCheck\",\"policy_ids\":[5],\"check_result_label\":\"policy_check\",\"if_compliant_state\":2,\"if_not_compliant_state\":3}" + }; + + await handler.PerformAction(action, ticket, WfObjectScopes.Ticket); + + Assert.That(policyChecker.RequestTaskIds, Is.EqualTo(new List { 15 })); + Assert.That(eligibleTask.GetAddInfoValue("policy_check"), Is.EqualTo("true")); + Assert.That(ineligibleTask.GetAddInfoValue("policy_check"), Is.EqualTo("")); + } + + [Test] + public async Task PerformAction_AutoPromoteConditionalPolicyCheck_WorksWithoutMiddlewareClient() + { + ActionHandlerTestApiConn apiConn = new(); + apiConn.States = [new WfState { Id = 1 }, new WfState { Id = 2 }, new WfState { Id = 3 }]; + SimulatedGlobalConfig globalConfig = new() { ComplianceCheckRelevantManagements = "1" }; + WfHandler wfHandler = new(new UserConfig(globalConfig, false), apiConn, WorkflowPhases.request, null, new ActionHandlerTestPolicyChecker() { Result = true }); + ActionHandler handler = new(apiConn, wfHandler, null, true); + await handler.Init(); + WfTicket ticket = CreateTicket(CreateEligibleRequestTask(17)); + WfStateAction action = new() + { + ActionType = StateActionTypes.AutoPromote.ToString(), + ExternalParams = "{\"to_be_called\":\"PolicyCheck\",\"policy_ids\":[5],\"check_result_label\":\"policy_check\",\"if_compliant_state\":2,\"if_not_compliant_state\":3}" + }; + + await handler.PerformAction(action, ticket, WfObjectScopes.Ticket); + + Assert.That(ticket.StateId, Is.EqualTo(2)); + Assert.That(ticket.Tasks[0].GetAddInfoValue("policy_check"), Is.EqualTo("true")); + } + + } +} diff --git a/roles/tests-unit/files/FWO.Test/AesEncryptionTest.cs b/roles/tests-unit/files/FWO.Test/AesEncryptionTest.cs new file mode 100644 index 0000000000..9f25b90d8f --- /dev/null +++ b/roles/tests-unit/files/FWO.Test/AesEncryptionTest.cs @@ -0,0 +1,62 @@ +using FWO.Encryption; +using NUnit.Framework; +using NUnit.Framework.Legacy; +using System.Text; +using Assert = NUnit.Framework.Assert; + +namespace FWO.Test +{ + [TestFixture] + [Parallelizable] + internal class AesDecryptTest + { + + private static readonly Random random = new Random(); + private const string printableChars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789!\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~"; + + public static string GenerateRandomString(int minLength, int maxLength) + { + int length = random.Next(minLength, maxLength + 1); + StringBuilder stringBuilder = new StringBuilder(length); + + for (int i = 0; i < length; i++) + { + char randomChar = printableChars[random.Next(printableChars.Length)]; + stringBuilder.Append(randomChar); + } + + return stringBuilder.ToString(); + } + [Test] + public void TestEncryptDecryptRandomData() + { + string tempKey = GenerateRandomString(32, 32); + string randomPlaintext = GenerateRandomString(15, 100); + string encryptedString = AesEnc.Encrypt(randomPlaintext, tempKey); + string decryptedString = AesEnc.Decrypt(encryptedString, tempKey); + ClassicAssert.AreEqual(randomPlaintext, decryptedString); + } + + [Test] + public void TestTryDecryptRejectsInvalidBase64() + { + string tempKey = GenerateRandomString(32, 32); + bool result = AesEnc.TryDecrypt("not-base64", tempKey, out string decryptedText); + + ClassicAssert.IsFalse(result); + ClassicAssert.AreEqual(string.Empty, decryptedText); + } + + [Test] + public void TestTryDecryptRejectsInvalidCiphertextBlockSize() + { + string tempKey = GenerateRandomString(32, 32); + string invalidCiphertext = Convert.ToBase64String(new byte[20]); + bool result = AesEnc.TryDecrypt(invalidCiphertext, tempKey, out string decryptedText); + + ClassicAssert.IsFalse(result); + ClassicAssert.AreEqual(string.Empty, decryptedText); + } + + } +} diff --git a/roles/tests-unit/files/FWO.Test/ApiConfigTest.cs b/roles/tests-unit/files/FWO.Test/ApiConfigTest.cs new file mode 100644 index 0000000000..1c96c6a94d --- /dev/null +++ b/roles/tests-unit/files/FWO.Test/ApiConfigTest.cs @@ -0,0 +1,55 @@ +// using FWO.Api.Client; +// using FWO.Config.Api; +// using NUnit.Framework; +// using NUnit.Framework.Legacy; +// using System; +// using System.Collections.Generic; +// using System.Linq; +// using System.Text; +// using System.Threading.Tasks; + +// namespace FWO.Test +// { +// [TestFixture] +// internal class ApiConfigTest +// { +// public ApiConfigTest() +// { + +// } + +// /// +// /// Run before EACH test. +// /// +// [SetUp] +// public void Setup() +// { + +// } + +// [Test] +// public async Task ReadGlobalConfig() +// { +// //ApiConnection apiConnection = new GraphQlApiConnection(""); +// //GlobalConfig globalConfig = await GlobalConfig.ConstructAsync(); +// } + +// [Test] +// public void ReadUserConfig() +// { +// //UserConfig userConfig = new UserConfig() +// } + +// [Test] +// public void WriteGlobalConfig() +// { + +// } + +// [Test] +// public void WriteUserConfig() +// { + +// } +// } +// } diff --git a/roles/tests-unit/files/FWO.Test/ApiTest.cs b/roles/tests-unit/files/FWO.Test/ApiTest.cs new file mode 100644 index 0000000000..9f81cf354d --- /dev/null +++ b/roles/tests-unit/files/FWO.Test/ApiTest.cs @@ -0,0 +1,71 @@ +// using System; +// using System.Threading.Tasks; +// using FWO.Api.Client; +// using NUnit.Framework; +// using NUnit.Framework.Legacy; +// using FWO.Basics; +// using FWO.Data; +// using FWO.Config.File; +// using FWO.Middleware.Client; +// using Microsoft.IdentityModel.Tokens; +// using FWO.Data.Middleware; +// using FWO.Logging; + +// namespace FWO.Test +// { +// [TestFixture] +// [Parallelizable] +// public class ApiTest +// { +// // ApiConnection apiConnection; + +// public ApiTest() +// { +// // ConfigFile configConnection = new ConfigFile(); +// // Dictionary apiTestUserCredentials = configConnection.ReadAdditionalConfigFile("secrets/TestUserCreds.json", new List { "user", "password" }); +// // string ApiUri = configConnection.ApiServerUri; +// // string MiddlewareUri = configConnection.MiddlewareServerUri; +// // string ProductVersion = configConnection.ProductVersion; +// // RsaSecurityKey jwtPublicKey = configConnection.JwtPublicKey; +// // string middlewareServerUri = configConnection.MiddlewareServerUri; +// // string apiServerUri = configConnection.ApiServerUri; +// // MiddlewareClient middlewareClient = new MiddlewareClient(MiddlewareUri); +// // AuthenticationTokenGetParameters authenticationParameters = new AuthenticationTokenGetParameters +// // { +// // Password = apiTestUserCredentials["password"], +// // Username = apiTestUserCredentials["user"] +// // }; +// // string jwt = middlewareClient.AuthenticateUser(authenticationParameters).Result.Data; +// // apiConnection = new APIConnection(apiServerUri); +// // apiConnection.SetAuthHeader(jwt); +// return; +// } + +// /// +// /// Run before EACH test. +// /// +// [SetUp] +// public void Setup() +// { + +// } + +// [Test] +// public async Task QueryTestIpProto() +// { +// // string query = @" +// // query ipProtoTest +// // { +// // stm_ip_proto (where: {ip_proto_id: {_eq: 6 } }) +// // { +// // id: ip_proto_id +// // name: ip_proto_name +// // } +// // }"; + +// // NetworkProtocol networkProtocol = new NetworkProtocol(); +// // networkProtocol = (await apiConnection.SendQueryAsync(query, new { }))[0]; +// // ClassicAssert.AreEqual(networkProtocol.Name, "TCP", "wrong result of protocol API query"); +// } +// } +// } diff --git a/roles/tests-unit/files/FWO.Test/AppDataImportTest.cs b/roles/tests-unit/files/FWO.Test/AppDataImportTest.cs new file mode 100644 index 0000000000..91e78d2436 --- /dev/null +++ b/roles/tests-unit/files/FWO.Test/AppDataImportTest.cs @@ -0,0 +1,2146 @@ +using System; +using System.Collections.Generic; +using System.Collections; +using System.Linq; +using System.Reflection; +using FWO.Api.Client; +using FWO.Basics; +using FWO.Api.Client.Queries; +using FWO.Config.Api; +using FWO.Data; +using FWO.Data.Modelling; +using FWO.Middleware.Server; +using NUnit.Framework; +using NUnit.Framework.Legacy; + + +namespace FWO.Test +{ + [TestFixture] + internal class AppDataImportTest + { + + [SetUp] + public void Initialize() + { + // No setup required for these tests + } + + [Test] + public void BuildOwnerResponsibles_UsesSortOrderKeyPositions() + { + AppDataImport import = CreateImportWithTypeMap(new Dictionary(StringComparer.OrdinalIgnoreCase) + { + ["Main"] = 1, + ["Supporting"] = 2 + }); + ModellingImportAppData incomingApp = new() + { + Name = "App-A", + ExtAppId = "APP-1", + Responsibles = new Dictionary> + { + ["1"] = ["cn=user1,dc=example,dc=com"], + ["2"] = ["cn=group1,dc=example,dc=com"] + } + }; + + List result = InvokeBuildOwnerResponsibles(import, incomingApp, "cn=fallback,dc=example,dc=com", []); + + Assert.That(result, Has.Count.EqualTo(2)); + Assert.That(result.Exists(r => r.Dn == "cn=user1,dc=example,dc=com" && r.ResponsibleTypeId == 1), Is.True); + Assert.That(result.Exists(r => r.Dn == "cn=group1,dc=example,dc=com" && r.ResponsibleTypeId == 2), Is.True); + } + + [Test] + public void BuildOwnerResponsibles_MapsNumericKeysBySortOrderPosition() + { + AppDataImport import = CreateImportWithTypeMap(new Dictionary(StringComparer.OrdinalIgnoreCase) + { + ["Main"] = 1, + ["Supporting"] = 2, + ["Escalation"] = 3 + }); + SetResponsibleTypes(import, + [ + new OwnerResponsibleType { Id = 2, Name = "Supporting", SortOrder = 1 }, + new OwnerResponsibleType { Id = 1, Name = "Main", SortOrder = 2 }, + new OwnerResponsibleType { Id = 3, Name = "Escalation", SortOrder = 3 } + ]); + ModellingImportAppData incomingApp = new() + { + Name = "App-A1", + ExtAppId = "APP-1A", + Responsibles = new Dictionary> + { + ["1"] = ["cn=first,dc=example,dc=com"], + ["2"] = ["cn=second,dc=example,dc=com"] + } + }; + + List result = InvokeBuildOwnerResponsibles(import, incomingApp, "cn=fallback,dc=example,dc=com", []); + + Assert.That(result, Has.Count.EqualTo(2)); + Assert.That(result.Exists(r => r.Dn == "cn=first,dc=example,dc=com" && r.ResponsibleTypeId == 2), Is.True); + Assert.That(result.Exists(r => r.Dn == "cn=second,dc=example,dc=com" && r.ResponsibleTypeId == 1), Is.True); + } + + [Test] + public void BuildOwnerResponsibles_MapsNonSequentialNumericKeysByOrder() + { + AppDataImport import = CreateImportWithTypeMap(new Dictionary(StringComparer.OrdinalIgnoreCase) + { + ["Main"] = 1, + ["Supporting"] = 2 + }); + SetResponsibleTypes(import, + [ + new OwnerResponsibleType { Id = 2, Name = "Supporting", SortOrder = 1 }, + new OwnerResponsibleType { Id = 1, Name = "Main", SortOrder = 2 } + ]); + ModellingImportAppData incomingApp = new() + { + Name = "App-A2", + ExtAppId = "APP-1B", + Responsibles = new Dictionary> + { + ["10"] = ["cn=first,dc=example,dc=com"], + ["20"] = ["cn=second,dc=example,dc=com"] + } + }; + + List result = InvokeBuildOwnerResponsibles(import, incomingApp, "cn=fallback,dc=example,dc=com", []); + + Assert.That(result, Has.Count.EqualTo(2)); + Assert.That(result.Exists(r => r.Dn == "cn=first,dc=example,dc=com" && r.ResponsibleTypeId == 2), Is.True); + Assert.That(result.Exists(r => r.Dn == "cn=second,dc=example,dc=com" && r.ResponsibleTypeId == 1), Is.True); + } + + [Test] + public void BuildOwnerResponsibles_MapsOnlyActiveTypesByOrder() + { + AppDataImport import = CreateImportWithTypeMap(new Dictionary(StringComparer.OrdinalIgnoreCase) + { + ["Main"] = 1, + ["Supporting"] = 2 + }); + SetResponsibleTypes(import, + [ + new OwnerResponsibleType { Id = 1, Name = "Main", SortOrder = 1, Active = false }, + new OwnerResponsibleType { Id = 2, Name = "Supporting", SortOrder = 2, Active = true } + ]); + ModellingImportAppData incomingApp = new() + { + Name = "App-A2-ActiveOnly", + ExtAppId = "APP-1B-2", + Responsibles = new Dictionary> + { + ["1"] = ["cn=first,dc=example,dc=com"], + ["2"] = ["cn=second,dc=example,dc=com"] + } + }; + + List result = InvokeBuildOwnerResponsibles(import, incomingApp, "cn=fallback,dc=example,dc=com", []); + + Assert.That(result, Has.Count.EqualTo(1)); + Assert.That(result.Exists(r => r.Dn == "cn=first,dc=example,dc=com" && r.ResponsibleTypeId == 2), Is.True); + } + + [Test] + public void BuildOwnerResponsibles_OmitsWholeOwnerWhenAnyKeyIsNonNumeric() + { + AppDataImport import = CreateImportWithTypeMap(new Dictionary(StringComparer.OrdinalIgnoreCase) + { + ["Main"] = 1, + ["Supporting"] = 2, + ["Escalation"] = 3 + }); + SetResponsibleTypes(import, + [ + new OwnerResponsibleType { Id = 2, Name = "Supporting", SortOrder = 1 }, + new OwnerResponsibleType { Id = 1, Name = "Main", SortOrder = 2 }, + new OwnerResponsibleType { Id = 3, Name = "Escalation", SortOrder = 3 } + ]); + ModellingImportAppData incomingApp = new() + { + Name = "App-A3", + ExtAppId = "APP-1C", + Responsibles = new Dictionary> + { + ["10"] = ["cn=first,dc=example,dc=com"], + ["x"] = ["cn=invalid,dc=example,dc=com"], + ["20"] = ["cn=second,dc=example,dc=com"] + } + }; + + List result = InvokeBuildOwnerResponsibles(import, incomingApp, "cn=fallback,dc=example,dc=com", []); + + Assert.That(result, Is.Empty); + } + + [Test] + public void BuildOwnerResponsibles_SkipsUnknownKeysAndContinues() + { + AppDataImport import = CreateImportWithTypeMap(new Dictionary(StringComparer.OrdinalIgnoreCase) + { + ["Known"] = 7 + }); + ModellingImportAppData incomingApp = new() + { + Name = "App-B", + ExtAppId = "APP-2", + Responsibles = new Dictionary> + { + ["99"] = ["cn=ignored,dc=example,dc=com"], + ["1"] = ["cn=kept,dc=example,dc=com"] + } + }; + + List result = InvokeBuildOwnerResponsibles(import, incomingApp, "cn=fallback,dc=example,dc=com", []); + + Assert.That(result, Has.Count.EqualTo(1)); + Assert.That(result[0].Dn, Is.EqualTo("cn=kept,dc=example,dc=com")); + Assert.That(result[0].ResponsibleTypeId, Is.EqualTo(7)); + } + + [Test] + public void BuildOwnerResponsibles_DeduplicatesPerTypeAndDnAndTrims() + { + AppDataImport import = CreateImportWithTypeMap(new Dictionary(StringComparer.OrdinalIgnoreCase) + { + ["Main"] = 1 + }); + ModellingImportAppData incomingApp = new() + { + Name = "App-C", + ExtAppId = "APP-3", + Responsibles = new Dictionary> + { + ["1"] = + [ + " cn=user1,dc=example,dc=com ", + "cn=user1,dc=example,dc=com", + " " + ] + } + }; + + List result = InvokeBuildOwnerResponsibles(import, incomingApp, "cn=fallback,dc=example,dc=com", []); + + Assert.That(result, Has.Count.EqualTo(1)); + Assert.That(result[0].Dn, Is.EqualTo("cn=user1,dc=example,dc=com")); + Assert.That(result[0].ResponsibleTypeId, Is.EqualTo(1)); + } + + [Test] + public void BuildOwnerResponsibles_FallsBackToLegacyWhenResponsiblesMissing() + { + AppDataImport import = CreateImportWithTypeMap(new Dictionary(StringComparer.OrdinalIgnoreCase) + { + ["Main"] = 1, + ["Supporting"] = 2, + ["Escalation"] = 3 + }); + ModellingImportAppData incomingApp = new() + { + Name = "App-D", + ExtAppId = "APP-4", + MainUser = "cn=main,dc=example,dc=com", + Responsibles = null + }; + + List result = InvokeBuildOwnerResponsibles( + import, + incomingApp, + "cn=support,dc=example,dc=com", + ["cn=optional,dc=example,dc=com"]); + + Assert.That(result, Has.Count.EqualTo(1)); + Assert.That(result.Exists(r => r.Dn == "cn=main,dc=example,dc=com" && r.ResponsibleTypeId == 1), Is.True); + } + + [Test] + public void BuildOwnerResponsibles_DoesNotUseLegacyWhenResponsiblesPresentButEmpty() + { + AppDataImport import = CreateImportWithTypeMap(new Dictionary(StringComparer.OrdinalIgnoreCase) + { + ["Main"] = 1 + }); + ModellingImportAppData incomingApp = new() + { + Name = "App-E", + ExtAppId = "APP-5", + MainUser = "cn=main,dc=example,dc=com", + Responsibles = new Dictionary> + { + ["1"] = [] + } + }; + + List result = InvokeBuildOwnerResponsibles(import, incomingApp, "cn=support,dc=example,dc=com", []); + + Assert.That(result, Has.Count.EqualTo(1)); + Assert.That(result.Exists(r => r.Dn == "cn=main,dc=example,dc=com" && r.ResponsibleTypeId == 1), Is.True); + } + + [Test] + public void BuildOwnerResponsibles_UsesLegacyWhenResponsiblesDictionaryIsEmpty() + { + AppDataImport import = CreateImportWithTypeMap(new Dictionary(StringComparer.OrdinalIgnoreCase) + { + ["Main"] = 1, + ["Supporting"] = 2 + }); + ModellingImportAppData incomingApp = new() + { + Name = "App-E2", + ExtAppId = "APP-5-2", + MainUser = "cn=main,dc=example,dc=com", + Responsibles = new Dictionary>() + }; + + List result = InvokeBuildOwnerResponsibles(import, incomingApp, "cn=support,dc=example,dc=com", []); + + Assert.That(result, Has.Count.EqualTo(1)); + Assert.That(result.Exists(r => r.Dn == "cn=main,dc=example,dc=com" && r.ResponsibleTypeId == 1), Is.True); + } + + [Test] + public void BuildOwnerResponsibles_LegacySkipsInactiveTypes() + { + AppDataImport import = CreateImportWithTypeMap(new Dictionary(StringComparer.OrdinalIgnoreCase)); + SetResponsibleTypes(import, + [ + new OwnerResponsibleType { Id = 1, Name = "Main", SortOrder = 1, Active = false }, + new OwnerResponsibleType { Id = 2, Name = "Supporting", SortOrder = 2, Active = true }, + new OwnerResponsibleType { Id = 3, Name = "Escalation", SortOrder = 3, Active = false } + ]); + ModellingImportAppData incomingApp = new() + { + Name = "App-E3", + ExtAppId = "APP-5-3", + MainUser = "cn=main,dc=example,dc=com", + Responsibles = new Dictionary>() + }; + + List result = InvokeBuildOwnerResponsibles( + import, + incomingApp, + "cn=support,dc=example,dc=com", + ["cn=optional,dc=example,dc=com"]); + + Assert.That(result, Is.Empty); + } + + [Test] + public void BuildOwnerResponsibles_UsesTrimmedNumericKey() + { + AppDataImport import = CreateImportWithTypeMap(new Dictionary(StringComparer.OrdinalIgnoreCase) + { + ["Main"] = 1 + }); + ModellingImportAppData incomingApp = new() + { + Name = "App-F", + ExtAppId = "APP-6", + Responsibles = new Dictionary> + { + [" 1 "] = ["cn=user1,dc=example,dc=com"] + } + }; + + List result = InvokeBuildOwnerResponsibles(import, incomingApp, "cn=fallback,dc=example,dc=com", []); + + Assert.That(result, Has.Count.EqualTo(1)); + Assert.That(result[0].ResponsibleTypeId, Is.EqualTo(1)); + } + + [Test] + public void BuildOwnerResponsibles_KeepsSameDnAcrossDifferentTypes() + { + AppDataImport import = CreateImportWithTypeMap(new Dictionary(StringComparer.OrdinalIgnoreCase) + { + ["Main"] = 1, + ["Supporting"] = 2 + }); + ModellingImportAppData incomingApp = new() + { + Name = "App-G", + ExtAppId = "APP-7", + Responsibles = new Dictionary> + { + ["1"] = ["cn=user1,dc=example,dc=com"], + ["2"] = ["cn=user1,dc=example,dc=com"] + } + }; + + List result = InvokeBuildOwnerResponsibles(import, incomingApp, "cn=fallback,dc=example,dc=com", []); + + Assert.That(result, Has.Count.EqualTo(2)); + Assert.That(result.Exists(r => r.ResponsibleTypeId == 1), Is.True); + Assert.That(result.Exists(r => r.ResponsibleTypeId == 2), Is.True); + } + + [Test] + public void TryResolveOwnerLifeCycleStateId_ReturnsTrueAndNullForEmptyState() + { + AppDataImport import = CreateImportWithTypeMap(new Dictionary(StringComparer.OrdinalIgnoreCase)); + SetOwnerLifeCycleMap(import, new Dictionary(StringComparer.OrdinalIgnoreCase) + { + ["Active"] = 10 + }); + ModellingImportAppData incomingApp = new() + { + Name = "App-L1", + ExtAppId = "APP-L1", + OwnerLifecycleState = " " + }; + + (bool ok, int? id) = InvokeTryResolveOwnerLifeCycleStateId(import, incomingApp); + + Assert.That(ok, Is.True); + Assert.That(id, Is.Null); + } + + [Test] + public void TryResolveOwnerLifeCycleStateId_ResolvesKnownState_CaseInsensitiveAndTrimmed() + { + AppDataImport import = CreateImportWithTypeMap(new Dictionary(StringComparer.OrdinalIgnoreCase)); + SetOwnerLifeCycleMap(import, new Dictionary(StringComparer.OrdinalIgnoreCase) + { + ["Active"] = 10, + ["Frozen"] = 20 + }); + ModellingImportAppData incomingApp = new() + { + Name = "App-L2", + ExtAppId = "APP-L2", + OwnerLifecycleState = " frozen " + }; + + (bool ok, int? id) = InvokeTryResolveOwnerLifeCycleStateId(import, incomingApp); + + Assert.That(ok, Is.True); + Assert.That(id, Is.EqualTo(20)); + } + + [Test] + public void TryResolveOwnerLifeCycleStateId_ReturnsFalseForUnknownState() + { + AppDataImport import = CreateImportWithTypeMap(new Dictionary(StringComparer.OrdinalIgnoreCase)); + SetOwnerLifeCycleMap(import, new Dictionary(StringComparer.OrdinalIgnoreCase) + { + ["Active"] = 10 + }); + ModellingImportAppData incomingApp = new() + { + Name = "App-L3", + ExtAppId = "APP-L3", + OwnerLifecycleState = "UnknownState" + }; + + (bool ok, int? id) = InvokeTryResolveOwnerLifeCycleStateId(import, incomingApp); + + Assert.That(ok, Is.False); + Assert.That(id, Is.Null); + } + + [Test] + public void ParseRolesWithImport_ParsesLegacyArrayIntoSupportingType() + { + Dictionary> parsed = InvokeParseRolesWithImport("[\"roleA\",\"roleB\"]"); + + Assert.That(parsed.Keys, Is.EquivalentTo(new[] { GlobalConst.kOwnerResponsibleTypeSupporting })); + Assert.That(parsed[GlobalConst.kOwnerResponsibleTypeSupporting], Is.EquivalentTo(new[] { "roleA", "roleB" })); + } + + [Test] + public void ParseRolesWithImport_ParsesTypeMappingAndSkipsInvalidKeys() + { + Dictionary> parsed = InvokeParseRolesWithImport("{\"1\":[\"mainRole\"],\"x\":[\"ignored\"],\"2\":[\"supportRole\"]}"); + + Assert.That(parsed.Keys, Is.EquivalentTo(new[] { 1, 2 })); + Assert.That(parsed[1], Is.EquivalentTo(new[] { "mainRole" })); + Assert.That(parsed[2], Is.EquivalentTo(new[] { "supportRole" })); + } + + [Test] + public void ParseRolesWithImport_ReturnsEmptyForWhitespaceInput() + { + Dictionary> parsed = InvokeParseRolesWithImport(" "); + + Assert.That(parsed, Is.Empty); + } + + [Test] + public async Task ApplyRolesToResponsibles_Skips_WhenNoRolesConfiguredForType() + { + AppDataImport import = CreateImportWithTypeMap(new Dictionary(StringComparer.OrdinalIgnoreCase) + { + ["Main"] = 1 + }); + SetInternalLdap(import, null); + List responsibles = + [ + new() { Dn = "cn=user1,dc=example,dc=com", ResponsibleTypeId = 1 } + ]; + Dictionary> rolesByType = new() + { + [2] = ["anyRole"] + }; + + Assert.DoesNotThrowAsync(async () => await InvokeApplyRolesToResponsibles(import, responsibles, rolesByType)); + } + + [Test] + public async Task ApplyRolesToResponsibles_Skips_WhenFilteringRemovesAllRoles() + { + AppDataImport import = CreateImportWithTypeMap(new Dictionary(StringComparer.OrdinalIgnoreCase) + { + ["Main"] = 1 + }); + SetResponsibleTypes(import, + [ + new OwnerResponsibleType { Id = 1, Name = "Main", SortOrder = 1, Active = true, AllowModelling = false, AllowRecertification = false } + ]); + SetInternalLdap(import, null); + List responsibles = + [ + new() { Dn = "cn=user2,dc=example,dc=com", ResponsibleTypeId = 1 } + ]; + Dictionary> rolesByType = new() + { + [1] = [Roles.Modeller, Roles.Recertifier] + }; + + Assert.DoesNotThrowAsync(async () => await InvokeApplyRolesToResponsibles(import, responsibles, rolesByType)); + } + + [Test] + public void ApplyRolesToResponsibles_CallsUpdateRoles_WhenFilteredRolesRemain() + { + AppDataImport import = CreateImportWithTypeMap(new Dictionary(StringComparer.OrdinalIgnoreCase) + { + ["Main"] = 1 + }); + SetResponsibleTypes(import, + [ + new OwnerResponsibleType { Id = 1, Name = "Main", SortOrder = 1, Active = true, AllowModelling = false, AllowRecertification = false } + ]); + SetInternalLdap(import, null); + List responsibles = + [ + new() { Dn = "cn=user3,dc=example,dc=com", ResponsibleTypeId = 1 } + ]; + Dictionary> rolesByType = new() + { + [1] = ["ReadOnlyRole"] + }; + + Assert.ThrowsAsync(async () => await InvokeApplyRolesToResponsibles(import, responsibles, rolesByType)); + } + + [Test] + public void GetRolesForType_ReturnsConfiguredRoles_AndEmptyWhenMissing() + { + AppDataImport import = CreateImportWithTypeMap(new Dictionary(StringComparer.OrdinalIgnoreCase)); + SetRolesByType(import, new Dictionary> + { + [7] = ["roleA", "roleB"] + }); + + List existing = InvokeGetRolesForType(import, 7); + List missing = InvokeGetRolesForType(import, 8); + + Assert.That(existing, Is.EquivalentTo(new[] { "roleA", "roleB" })); + Assert.That(missing, Is.Empty); + } + + [Test] + public void IsResponsibleTypeActive_ReturnsTrueOnlyForActiveType() + { + AppDataImport import = CreateImportWithTypeMap(new Dictionary(StringComparer.OrdinalIgnoreCase)); + SetResponsibleTypes(import, + [ + new OwnerResponsibleType { Id = 1, Name = "Main", SortOrder = 1, Active = true }, + new OwnerResponsibleType { Id = 2, Name = "Supporting", SortOrder = 2, Active = false } + ]); + + bool active = InvokeIsResponsibleTypeActive(import, 1); + bool inactive = InvokeIsResponsibleTypeActive(import, 2); + bool missing = InvokeIsResponsibleTypeActive(import, 3); + + Assert.That(active, Is.True); + Assert.That(inactive, Is.False); + Assert.That(missing, Is.False); + } + + [Test] + public async Task AddAllResponsiblesToUiUser_IgnoresWhitespaceAndDuplicates_WhenNoLdapsConfigured() + { + AppDataImport import = new(new SimulatedApiConnection(), new GlobalConfig()); + SetConnectedLdaps(import, []); + List responsibles = + [ + new() { Dn = "cn=user1,dc=example,dc=com" }, + new() { Dn = " cn=user1,dc=example,dc=com " }, + new() { Dn = " " }, + new() { Dn = "" } + ]; + + Assert.DoesNotThrowAsync(async () => await InvokeAddAllResponsiblesToUiUser(import, responsibles)); + } + + [Test] + public async Task AddResponsibleDnToUiUser_DoesNothing_WhenNoConnectedLdaps() + { + AppDataImport import = new(new SimulatedApiConnection(), new GlobalConfig()); + SetConnectedLdaps(import, []); + HashSet handledUserDns = new(StringComparer.OrdinalIgnoreCase); + HashSet handledGroupDnsByLdap = new(StringComparer.OrdinalIgnoreCase); + + await InvokeAddResponsibleDnToUiUser(import, "cn=group1,dc=example,dc=com", handledUserDns, handledGroupDnsByLdap); + + Assert.That(handledUserDns, Is.Empty); + Assert.That(handledGroupDnsByLdap, Is.Empty); + } + + [Test] + public async Task AddResponsibleDnToUiUser_SkipsGroupProcessing_WhenGroupKeyAlreadyHandled() + { + AppDataImport import = new(new SimulatedApiConnection(), new GlobalConfig()); + SetConnectedLdaps(import, + [ + new Ldap + { + Id = 5, + UserSearchPath = "ou=users,dc=example,dc=com" + } + ]); + HashSet handledUserDns = new(StringComparer.OrdinalIgnoreCase); + HashSet handledGroupDnsByLdap = new(StringComparer.OrdinalIgnoreCase) + { + "5|cn=group1,dc=example,dc=com" + }; + + await InvokeAddResponsibleDnToUiUser(import, "cn=group1,dc=example,dc=com", handledUserDns, handledGroupDnsByLdap); + + Assert.That(handledUserDns, Is.Empty); + Assert.That(handledGroupDnsByLdap.Count, Is.EqualTo(1)); + } + + [Test] + public async Task AddResponsibleDnToUiUser_ImportsUsersFromGroupDn_OutsideConfiguredGroupPath() + { + ResolverTestAppDataImport import = new( + new Dictionary(StringComparer.OrdinalIgnoreCase), + new Dictionary(StringComparer.OrdinalIgnoreCase) + { + ["cn=user1,ou=users,dc=example,dc=com"] = new() { Dn = "cn=user1,ou=users,dc=example,dc=com", Name = "user1" }, + ["cn=user2,ou=users,dc=example,dc=com"] = new() { Dn = "cn=user2,ou=users,dc=example,dc=com", Name = "user2" } + }, + new Dictionary>(StringComparer.OrdinalIgnoreCase) + { + ["cn=group1,ou=external-groups,dc=example,dc=com"] = + [ + "cn=user1,ou=users,dc=example,dc=com", + "cn=user2,ou=users,dc=example,dc=com" + ] + }); + SetConnectedLdaps(import, + [ + new Ldap + { + Id = 5, + GroupSearchPath = "ou=internal-groups,dc=example,dc=com" + } + ]); + HashSet handledUserDns = new(StringComparer.OrdinalIgnoreCase); + HashSet handledGroupDnsByLdap = new(StringComparer.OrdinalIgnoreCase); + + await InvokeAddResponsibleDnToUiUser(import, "cn=group1,ou=external-groups,dc=example,dc=com", handledUserDns, handledGroupDnsByLdap); + + Assert.That(handledGroupDnsByLdap.Contains("5|cn=group1,ou=external-groups,dc=example,dc=com"), Is.True); + Assert.That(handledUserDns, Is.EquivalentTo(new[] + { + "cn=user1,ou=users,dc=example,dc=com", + "cn=user2,ou=users,dc=example,dc=com" + })); + } + + [Test] + public async Task AddResponsibleDnToUiUser_TriesDnAsUserBeforeResolvingGroupMembers() + { + ResolverTestAppDataImport import = new( + new Dictionary(StringComparer.OrdinalIgnoreCase), + new Dictionary(StringComparer.OrdinalIgnoreCase) + { + ["cn=user-or-group,ou=mixed,dc=example,dc=com"] = new() { Dn = "cn=user-or-group,ou=mixed,dc=example,dc=com", Name = "mixedUser" } + }, + new Dictionary>(StringComparer.OrdinalIgnoreCase) + { + ["cn=user-or-group,ou=mixed,dc=example,dc=com"] = + [ + "cn=group-member,ou=users,dc=example,dc=com" + ] + }); + SetConnectedLdaps(import, + [ + new Ldap + { + Id = 5, + GroupSearchPath = "ou=groups,dc=example,dc=com" + } + ]); + HashSet handledUserDns = new(StringComparer.OrdinalIgnoreCase); + HashSet handledGroupDnsByLdap = new(StringComparer.OrdinalIgnoreCase); + + await InvokeAddResponsibleDnToUiUser(import, "cn=user-or-group,ou=mixed,dc=example,dc=com", handledUserDns, handledGroupDnsByLdap); + + Assert.That(handledUserDns, Is.EquivalentTo(new[] + { + "cn=user-or-group,ou=mixed,dc=example,dc=com" + })); + Assert.That(handledGroupDnsByLdap, Is.Empty); + } + + [Test] + public async Task ConvertLdapToUiUser_ReturnsNull_WhenNoUserSearchPathMatchesDn() + { + AppDataImport import = new(new SimulatedApiConnection(), new GlobalConfig()); + SetConnectedLdaps(import, + [ + new Ldap + { + Id = 7, + UserSearchPath = "ou=users,dc=example,dc=com" + } + ]); + + UiUser? uiUser = await InvokeConvertLdapToUiUser(import, "cn=user3,ou=other,dc=example,dc=com"); + + Assert.That(uiUser, Is.Null); + } + + [Test] + public async Task DeactivateMissingApps_DeactivatesOnlyActiveAppsFromSameSourceThatAreMissingInImport() + { + AppDataImportFlowTestApiConn apiConn = new(); + AppDataImport import = new(apiConn, new GlobalConfig()); + OwnerChangeImportTracker tracker = new(apiConn); + List existingApps = + [ + new() { Id = 1, ExtAppId = "APP-1", ImportSource = "SRC-A", Active = true }, + new() { Id = 2, ExtAppId = "APP-2", ImportSource = "SRC-A", Active = true }, + new() { Id = 3, ExtAppId = "APP-3", ImportSource = "SRC-A", Active = false }, + new() { Id = 4, ExtAppId = "APP-4", ImportSource = "SRC-B", Active = true } + ]; + List importedApps = + [ + new() { Name = "Imported2", ExtAppId = "APP-2", ImportSource = "SRC-A" } + ]; + + (int deleted, int failed) = await InvokeDeactivateMissingApps(import, "SRC-A", existingApps, importedApps, tracker); + + Assert.That(deleted, Is.EqualTo(1)); + Assert.That(failed, Is.EqualTo(0)); + Assert.That(apiConn.DeactivateOwnerCalls, Is.EqualTo(1)); + Assert.That(apiConn.UpdateChangelogOwnerCalls, Is.EqualTo(1)); + } + + [Test] + public async Task DeactivateMissingApps_CountsFailures_WhenDeactivateThrows() + { + AppDataImportFlowTestApiConn apiConn = new(); + apiConn.FailDeactivateOwnerIds.Add(2); + AppDataImport import = new(apiConn, new GlobalConfig()); + OwnerChangeImportTracker tracker = new(apiConn); + List existingApps = + [ + new() { Id = 1, ExtAppId = "APP-1", ImportSource = "SRC-A", Active = true }, + new() { Id = 2, ExtAppId = "APP-2", ImportSource = "SRC-A", Active = true } + ]; + + (int deleted, int failed) = await InvokeDeactivateMissingApps(import, "SRC-A", existingApps, [], tracker); + + Assert.That(deleted, Is.EqualTo(1)); + Assert.That(failed, Is.EqualTo(1)); + Assert.That(apiConn.DeactivateOwnerCalls, Is.EqualTo(2)); + Assert.That(apiConn.UpdateChangelogOwnerCalls, Is.EqualTo(1)); + } + + [Test] + public void CheckResponsibles_ReturnsInsertAndDelete_WhenSyncEnabled() + { + AppDataImport import = new(new SimulatedApiConnection(), new GlobalConfig()); + SetOwnerDataImportSyncUsers(import, true); + List existingResponsibles = + [ + new() { Dn = "cn=keep,dc=example,dc=com", ResponsibleTypeId = 1 }, + new() { Dn = "cn=delete,dc=example,dc=com", ResponsibleTypeId = 2 } + ]; + List incomingResponsibles = + [ + new() { Dn = "cn=keep,dc=example,dc=com", ResponsibleTypeId = 1 }, + new() { Dn = "cn=insert,dc=example,dc=com", ResponsibleTypeId = 2 } + ]; + + (List toInsert, List toDelete) = + InvokeCheckResponsibles(import, existingResponsibles, incomingResponsibles); + + Assert.That(toInsert, Has.Count.EqualTo(1)); + Assert.That(toInsert[0].Dn, Is.EqualTo("cn=insert,dc=example,dc=com")); + Assert.That(toInsert[0].ResponsibleTypeId, Is.EqualTo(2)); + Assert.That(toDelete, Has.Count.EqualTo(1)); + Assert.That(toDelete[0].Dn, Is.EqualTo("cn=delete,dc=example,dc=com")); + Assert.That(toDelete[0].ResponsibleTypeId, Is.EqualTo(2)); + } + + [Test] + public void CheckResponsibles_ReturnsInsertOnly_WhenSyncDisabled() + { + AppDataImport import = new(new SimulatedApiConnection(), new GlobalConfig()); + SetOwnerDataImportSyncUsers(import, false); + List existingResponsibles = + [ + new() { Dn = "cn=delete,dc=example,dc=com", ResponsibleTypeId = 2 } + ]; + List incomingResponsibles = + [ + new() { Dn = "cn=insert,dc=example,dc=com", ResponsibleTypeId = 2 } + ]; + + (List toInsert, List toDelete) = + InvokeCheckResponsibles(import, existingResponsibles, incomingResponsibles); + + Assert.That(toInsert, Has.Count.EqualTo(1)); + Assert.That(toInsert[0].Dn, Is.EqualTo("cn=insert,dc=example,dc=com")); + Assert.That(toDelete, Is.Empty); + } + + [Test] + public async Task UpdateOwnerResponsibles_CallsInsertAndDelete_WhenSyncEnabled() + { + AppDataImportResponsiblesApiConn apiConn = new(); + AppDataImport import = new(apiConn, new GlobalConfig()); + SetOwnerDataImportSyncUsers(import, true); + List existingResponsibles = + [ + new() { Dn = "cn=keep,dc=example,dc=com", ResponsibleTypeId = 1 }, + new() { Dn = "cn=delete,dc=example,dc=com", ResponsibleTypeId = 2 } + ]; + List incomingResponsibles = + [ + new() { Dn = "cn=keep,dc=example,dc=com", ResponsibleTypeId = 1 }, + new() { Dn = "cn=insert,dc=example,dc=com", ResponsibleTypeId = 2 } + ]; + + await InvokeUpdateOwnerResponsibles(import, 123, incomingResponsibles, existingResponsibles); + + Assert.That(apiConn.DeleteSpecificOwnerResponsiblesCalls, Is.EqualTo(1)); + Assert.That(apiConn.NewOwnerResponsiblesCalls, Is.EqualTo(1)); + Assert.That(apiConn.Deleted, Has.Count.EqualTo(1)); + Assert.That(apiConn.Deleted[0], Is.EqualTo((123, "cn=delete,dc=example,dc=com", 2))); + Assert.That(apiConn.Inserted, Has.Count.EqualTo(1)); + Assert.That(apiConn.Inserted[0], Is.EqualTo((123, "cn=insert,dc=example,dc=com", 2))); + } + + [Test] + public async Task UpdateOwnerResponsibles_RemovesMappedRoles_ForDeletedResponsibles() + { + AppDataImportResponsiblesApiConn apiConn = new(); + RoleRemovalTrackingImport import = new(apiConn); + SetOwnerDataImportSyncUsers(import, true); + SetResponsibleTypes(import, + [ + new OwnerResponsibleType { Id = 2, Name = "Supporting", SortOrder = 2, Active = true, AllowModelling = false, AllowRecertification = false } + ]); + SetRolesByType(import, new Dictionary> + { + [2] = ["ReadOnlyRole"] + }); + List existingResponsibles = + [ + new() { Dn = "cn=delete,dc=example,dc=com", ResponsibleTypeId = 2 } + ]; + + await InvokeUpdateOwnerResponsibles(import, 123, [], existingResponsibles); + + Assert.That(import.RemovedRoleAssignments, Is.EqualTo(new[] + { + ("cn=delete,dc=example,dc=com", "ReadOnlyRole") + })); + } + + [Test] + public async Task UpdateOwnerResponsibles_DoesNothing_WhenNoChanges() + { + AppDataImportResponsiblesApiConn apiConn = new(); + AppDataImport import = new(apiConn, new GlobalConfig()); + SetOwnerDataImportSyncUsers(import, true); + List existingResponsibles = + [ + new() { Dn = "cn=keep,dc=example,dc=com", ResponsibleTypeId = 1 } + ]; + List incomingResponsibles = + [ + new() { Dn = "cn=keep,dc=example,dc=com", ResponsibleTypeId = 1 } + ]; + + await InvokeUpdateOwnerResponsibles(import, 123, incomingResponsibles, existingResponsibles); + + Assert.That(apiConn.DeleteSpecificOwnerResponsiblesCalls, Is.EqualTo(0)); + Assert.That(apiConn.NewOwnerResponsiblesCalls, Is.EqualTo(0)); + Assert.That(apiConn.Deleted, Is.Empty); + Assert.That(apiConn.Inserted, Is.Empty); + } + + [Test] + public async Task UpdateOwnerResponsibles_InsertsOnly_WhenSyncDisabled() + { + AppDataImportResponsiblesApiConn apiConn = new(); + AppDataImport import = new(apiConn, new GlobalConfig()); + SetOwnerDataImportSyncUsers(import, false); + List existingResponsibles = + [ + new() { Dn = "cn=delete,dc=example,dc=com", ResponsibleTypeId = 2 } + ]; + List incomingResponsibles = + [ + new() { Dn = "cn=insert,dc=example,dc=com", ResponsibleTypeId = 2 } + ]; + + await InvokeUpdateOwnerResponsibles(import, 123, incomingResponsibles, existingResponsibles); + + Assert.That(apiConn.DeleteSpecificOwnerResponsiblesCalls, Is.EqualTo(0)); + Assert.That(apiConn.NewOwnerResponsiblesCalls, Is.EqualTo(1)); + Assert.That(apiConn.Deleted, Is.Empty); + Assert.That(apiConn.Inserted, Has.Count.EqualTo(1)); + Assert.That(apiConn.Inserted[0], Is.EqualTo((123, "cn=insert,dc=example,dc=com", 2))); + } + + [Test] + public async Task SaveApp_DoesNotImport_WhenOwnerLifecycleStateIsUnknown() + { + AppDataImportSaveAppApiConn apiConn = new(); + AppDataImport import = new(apiConn, new GlobalConfig()); + SetOwnerLifeCycleMap(import, new Dictionary(StringComparer.OrdinalIgnoreCase) + { + ["Active"] = 10 + }); + SetExistingApps(import, []); + ModellingImportAppData incomingApp = new() + { + Name = "App-L4", + ExtAppId = "APP-L4", + ImportSource = "SRC-L4", + OwnerLifecycleState = "UnknownLifecycle" + }; + OwnerChangeImportTracker tracker = new(apiConn); + + bool imported = await InvokeSaveApp(import, incomingApp, tracker); + + Assert.That(imported, Is.False); + Assert.That(apiConn.NewOwnerCalls, Is.EqualTo(0)); + Assert.That(apiConn.UpdateOwnerCalls, Is.EqualTo(0)); + } + + [Test] + public async Task AddOwnerLifeCycleStateActiveChangeIfNeeded_LogsReactivate_WhenLifecycleStateChangesToActive() + { + AppDataImportSaveAppApiConn apiConn = new(); + AppDataImport import = new(apiConn, new GlobalConfig()); + SetOwnerLifeCycleActiveMap(import, new Dictionary + { + [10] = true, + [11] = false + }); + FwoOwner existingApp = new() { Id = 7, OwnerLifeCycleStateId = 11 }; + OwnerChangeImportTracker tracker = new(apiConn); + + await InvokeAddOwnerLifeCycleStateActiveChangeIfNeeded(import, existingApp, 10, "SRC-7", tracker); + + Assert.That(apiConn.UpdateChangelogOwnerCalls, Is.EqualTo(1)); + Assert.That(apiConn.ChangelogActions, Is.EqualTo(new[] { ChangelogActionType.REACTIVATE })); + } + + [Test] + public async Task SaveApp_SetsDecommDate_WhenLifecycleStateChangesToInactive() + { + AppDataImportSaveAppApiConn apiConn = new(); + TestAppDataImport import = new(apiConn, new GlobalConfig()); + SetHasImmediateAppDecommNotificationForImport(import, true); + SetOwnerLifeCycleMap(import, new Dictionary(StringComparer.OrdinalIgnoreCase) + { + ["Inactive"] = 11 + }); + SetOwnerLifeCycleActiveMap(import, new Dictionary + { + [10] = true, + [11] = false + }); + SetExistingApps(import, + [ + new() { Id = 30, Name = "App-30", ExtAppId = "APP-30", OwnerLifeCycleStateId = 10 } + ]); + ModellingImportAppData incomingApp = new() + { + Name = "App-30", + ExtAppId = "APP-30", + ImportSource = "SRC-30", + OwnerLifecycleState = "Inactive" + }; + + bool imported = await InvokeSaveApp(import, incomingApp, new OwnerChangeImportTracker(apiConn)); + + Assert.That(imported, Is.True); + Assert.That(apiConn.LastUpdateOwnerDecommDate, Is.Not.Null); + } + + [Test] + public async Task SaveApp_DoesNotCheckActiveRules_WhenImmediateAppDecommNotificationIsMissing() + { + AppDataImportSaveAppApiConn apiConn = new(); + TestAppDataImport import = new(apiConn, new GlobalConfig()); + SetHasImmediateAppDecommNotificationForImport(import, false); + SetOwnerLifeCycleMap(import, new Dictionary(StringComparer.OrdinalIgnoreCase) + { + ["Inactive"] = 11 + }); + SetOwnerLifeCycleActiveMap(import, new Dictionary + { + [10] = true, + [11] = false + }); + SetExistingApps(import, + [ + new() { Id = 35, Name = "App-35", ExtAppId = "APP-35", OwnerLifeCycleStateId = 10 } + ]); + ModellingImportAppData incomingApp = new() + { + Name = "App-35", + ExtAppId = "APP-35", + ImportSource = "SRC-35", + OwnerLifecycleState = "Inactive" + }; + + bool imported = await InvokeSaveApp(import, incomingApp, new OwnerChangeImportTracker(apiConn)); + + Assert.That(imported, Is.True); + Assert.That(import.CheckedOwners, Is.Empty); + } + + [Test] + public async Task SaveApp_ChecksActiveRules_WhenImmediateAppDecommNotificationExists() + { + AppDataImportSaveAppApiConn apiConn = new(); + TestAppDataImport import = new(apiConn, new GlobalConfig()); + SetHasImmediateAppDecommNotificationForImport(import, true); + SetOwnerLifeCycleMap(import, new Dictionary(StringComparer.OrdinalIgnoreCase) + { + ["Inactive"] = 11 + }); + SetOwnerLifeCycleActiveMap(import, new Dictionary + { + [10] = true, + [11] = false + }); + SetExistingApps(import, + [ + new() { Id = 36, Name = "App-36", ExtAppId = "APP-36", OwnerLifeCycleStateId = 10 } + ]); + ModellingImportAppData incomingApp = new() + { + Name = "App-36", + ExtAppId = "APP-36", + ImportSource = "SRC-36", + OwnerLifecycleState = "Inactive" + }; + + bool imported = await InvokeSaveApp(import, incomingApp, new OwnerChangeImportTracker(apiConn)); + + Assert.That(imported, Is.True); + Assert.That(import.CheckedOwners.Select(owner => owner.Id), Is.EqualTo(new[] { 36 })); + } + + [Test] + public async Task SaveApp_SetsDecommDate_WhenNewOwnerStartsInactive() + { + AppDataImportSaveAppApiConn apiConn = new(); + AppDataImport import = new(apiConn, new GlobalConfig()); + SetOwnerLifeCycleMap(import, new Dictionary(StringComparer.OrdinalIgnoreCase) + { + ["Inactive"] = 11 + }); + SetOwnerLifeCycleActiveMap(import, new Dictionary + { + [11] = false + }); + SetExistingApps(import, []); + ModellingImportAppData incomingApp = new() + { + Name = "App-32", + ExtAppId = "APP-32", + ImportSource = "SRC-32", + OwnerLifecycleState = "Inactive" + }; + + bool imported = await InvokeSaveApp(import, incomingApp, new OwnerChangeImportTracker(apiConn)); + + Assert.That(imported, Is.True); + Assert.That(apiConn.LastNewOwnerDecommDate, Is.Not.Null); + } + + [Test] + public async Task SaveApp_ForwardsAdditionalInformationToOwnerMutations() + { + AppDataImportSaveAppApiConn apiConn = new(); + AppDataImport import = new(apiConn, new GlobalConfig()); + SetExistingApps(import, []); + ModellingImportAppData incomingApp = new() + { + Name = "App-Info", + ExtAppId = "APP-INFO", + ImportSource = "SRC-INFO", + AdditionalInformation = new Dictionary + { + ["cost_center"] = "4711", + ["owner_type"] = "shared" + } + }; + + bool imported = await InvokeSaveApp(import, incomingApp, new OwnerChangeImportTracker(apiConn)); + + Assert.That(imported, Is.True); + Assert.That(apiConn.LastNewOwnerAdditionalInfo, Is.Not.Null); + Assert.That(apiConn.LastNewOwnerAdditionalInfo, Is.EqualTo(incomingApp.AdditionalInformation)); + } + + [Test] + public async Task SaveApp_ClearsDecommDate_WhenLifecycleStateChangesToActive() + { + AppDataImportSaveAppApiConn apiConn = new(); + AppDataImport import = new(apiConn, new GlobalConfig()); + SetOwnerLifeCycleMap(import, new Dictionary(StringComparer.OrdinalIgnoreCase) + { + ["Active"] = 10 + }); + SetOwnerLifeCycleActiveMap(import, new Dictionary + { + [10] = true, + [11] = false + }); + SetExistingApps(import, + [ + new() { Id = 31, Name = "App-31", ExtAppId = "APP-31", OwnerLifeCycleStateId = 11, DecommDate = DateTime.UtcNow.AddDays(-1) } + ]); + ModellingImportAppData incomingApp = new() + { + Name = "App-31", + ExtAppId = "APP-31", + ImportSource = "SRC-31", + OwnerLifecycleState = "Active" + }; + + bool imported = await InvokeSaveApp(import, incomingApp, new OwnerChangeImportTracker(apiConn)); + + Assert.That(imported, Is.True); + Assert.That(apiConn.LastUpdateOwnerDecommDate, Is.Null); + } + + [Test] + public async Task SaveApp_SetsDecommDate_WhenOwnerStaysInactiveButDateWasMissing() + { + AppDataImportSaveAppApiConn apiConn = new(); + TestAppDataImport import = new(apiConn, new GlobalConfig()); + SetOwnerLifeCycleMap(import, new Dictionary(StringComparer.OrdinalIgnoreCase) + { + ["Inactive"] = 11 + }); + SetOwnerLifeCycleActiveMap(import, new Dictionary + { + [11] = false + }); + SetExistingApps(import, + [ + new() { Id = 33, Name = "App-33", ExtAppId = "APP-33", OwnerLifeCycleStateId = 11, DecommDate = null } + ]); + ModellingImportAppData incomingApp = new() + { + Name = "App-33", + ExtAppId = "APP-33", + ImportSource = "SRC-33", + OwnerLifecycleState = "Inactive" + }; + + bool imported = await InvokeSaveApp(import, incomingApp, new OwnerChangeImportTracker(apiConn)); + + Assert.That(imported, Is.True); + Assert.That(apiConn.LastUpdateOwnerDecommDate, Is.Not.Null); + } + + [Test] + public async Task SaveApp_SetsDecommDate_WhenPreviousLifecycleStateWasMissingAndNewStateIsInactive() + { + AppDataImportSaveAppApiConn apiConn = new(); + TestAppDataImport import = new(apiConn, new GlobalConfig()); + SetOwnerLifeCycleMap(import, new Dictionary(StringComparer.OrdinalIgnoreCase) + { + ["Inactive"] = 11 + }); + SetOwnerLifeCycleActiveMap(import, new Dictionary + { + [11] = false + }); + SetExistingApps(import, + [ + new() { Id = 34, Name = "App-34", ExtAppId = "APP-34", OwnerLifeCycleStateId = null, DecommDate = null } + ]); + ModellingImportAppData incomingApp = new() + { + Name = "App-34", + ExtAppId = "APP-34", + ImportSource = "SRC-34", + OwnerLifecycleState = "Inactive" + }; + + bool imported = await InvokeSaveApp(import, incomingApp, new OwnerChangeImportTracker(apiConn)); + + Assert.That(imported, Is.True); + Assert.That(apiConn.LastUpdateOwnerDecommDate, Is.Not.Null); + } + + [Test] + public async Task AddOwnerLifeCycleStateActiveChangeIfNeeded_LogsDeactivate_WhenLifecycleStateChangesToInactive() + { + AppDataImportSaveAppApiConn apiConn = new(); + TestAppDataImport import = new(apiConn, new GlobalConfig()); + SetHasImmediateAppDecommNotificationForImport(import, true); + SetOwnerLifeCycleActiveMap(import, new Dictionary + { + [10] = true, + [11] = false + }); + FwoOwner existingApp = new() { Id = 8, OwnerLifeCycleStateId = 10 }; + OwnerChangeImportTracker tracker = new(apiConn); + + await InvokeAddOwnerLifeCycleStateActiveChangeIfNeeded(import, existingApp, 11, "SRC-8", tracker); + + Assert.That(apiConn.UpdateChangelogOwnerCalls, Is.EqualTo(1)); + Assert.That(apiConn.ChangelogActions, Is.EqualTo(new[] { ChangelogActionType.DEACTIVATE })); + Assert.That(import.CheckedOwners, Has.Count.EqualTo(1)); + Assert.That(import.CheckedOwners[0].Id, Is.EqualTo(8)); + } + + [Test] + public async Task AddOwnerLifeCycleStateActiveChangeIfNeeded_DoesNotLog_WhenActiveStateDoesNotChange() + { + AppDataImportSaveAppApiConn apiConn = new(); + AppDataImport import = new(apiConn, new GlobalConfig()); + SetOwnerLifeCycleActiveMap(import, new Dictionary + { + [10] = true, + [12] = true + }); + FwoOwner existingApp = new() { Id = 9, OwnerLifeCycleStateId = 10 }; + OwnerChangeImportTracker tracker = new(apiConn); + + await InvokeAddOwnerLifeCycleStateActiveChangeIfNeeded(import, existingApp, 12, "SRC-9", tracker); + + Assert.That(apiConn.UpdateChangelogOwnerCalls, Is.EqualTo(0)); + } + + [Test] + public async Task AddOwnerLifeCycleStateActiveChangeIfNeeded_DoesNotCheckActiveRules_WhenLifecycleStateChangesToActive() + { + AppDataImportSaveAppApiConn apiConn = new(); + TestAppDataImport import = new(apiConn, new GlobalConfig()); + SetOwnerLifeCycleActiveMap(import, new Dictionary + { + [10] = true, + [11] = false + }); + FwoOwner existingApp = new() { Id = 10, OwnerLifeCycleStateId = 11 }; + OwnerChangeImportTracker tracker = new(apiConn); + + await InvokeAddOwnerLifeCycleStateActiveChangeIfNeeded(import, existingApp, 10, "SRC-10", tracker); + + Assert.That(import.CheckedOwners, Is.Empty); + } + + [Test] + public async Task AddOwnerChangeIfNeeded_LogsChange_WhenAppServersChanged() + { + AppDataImportSaveAppApiConn apiConn = new(); + AppDataImport import = new(apiConn, new GlobalConfig()); + SetExistingAppServers(import, + [ + new ModellingAppServer + { + Id = 100, + AppId = 19, + Name = "server-old", + Ip = "10.0.0.1/32", + IpEnd = "10.0.0.1/32", + ImportSource = "SRC-19", + IsDeleted = false + } + ]); + FwoOwner existingApp = new() { Id = 19, Name = "App-19", ExtAppId = "APP-19" }; + ModellingImportAppData incomingApp = new() + { + Name = "App-19", + ExtAppId = "APP-19", + ImportSource = "SRC-19", + AppServers = + [ + new ModellingImportAppServer + { + Name = "server-new", + Ip = "10.0.0.2/32", + IpEnd = "10.0.0.2/32" + } + ] + }; + OwnerChangeImportTracker tracker = new(apiConn); + + await InvokeAddOwnerChangeIfNeeded(import, existingApp, incomingApp, tracker); + + Assert.That(apiConn.UpdateChangelogOwnerCalls, Is.EqualTo(1)); + Assert.That(apiConn.ChangelogActions, Is.EqualTo(new[] { ChangelogActionType.CHANGE })); + } + + [Test] + public async Task AddOwnerChangeIfNeeded_LogsChange_WhenInactiveOwnerIsFoundAgainInImport() + { + AppDataImportSaveAppApiConn apiConn = new(); + AppDataImport import = new(apiConn, new GlobalConfig()); + SetExistingAppServers(import, []); + FwoOwner existingApp = new() { Id = 21, Name = "App-21", ExtAppId = "APP-21", Active = false }; + ModellingImportAppData incomingApp = new() + { + Name = "App-21", + ExtAppId = "APP-21", + ImportSource = "SRC-21" + }; + OwnerChangeImportTracker tracker = new(apiConn); + + await InvokeAddOwnerChangeIfNeeded(import, existingApp, incomingApp, tracker); + + Assert.That(apiConn.UpdateChangelogOwnerCalls, Is.EqualTo(1)); + Assert.That(apiConn.ChangelogActions, Is.EqualTo(new[] { ChangelogActionType.CHANGE })); + } + + [Test] + public async Task SaveApp_LogsChangeAndReactivate_WhenAppServersChangeAndLifecycleStateBecomesActive() + { + AppDataImportSaveAppApiConn apiConn = new(); + AppDataImport import = new(apiConn, new GlobalConfig()); + SetOwnerLifeCycleMap(import, new Dictionary(StringComparer.OrdinalIgnoreCase) + { + ["Active"] = 10 + }); + SetOwnerLifeCycleActiveMap(import, new Dictionary + { + [10] = true, + [11] = false + }); + SetExistingApps(import, + [ + new() { Id = 20, Name = "App-20", ExtAppId = "APP-20", OwnerLifeCycleStateId = 11 } + ]); + apiConn.AppServersByOwner[(20, "SRC-20")] = + [ + new ModellingAppServer + { + Id = 200, + AppId = 20, + Name = "server-old", + Ip = "10.0.0.1/32", + IpEnd = "10.0.0.1/32", + ImportSource = "SRC-20", + IsDeleted = false + } + ]; + ModellingImportAppData incomingApp = new() + { + Name = "App-20", + ExtAppId = "APP-20", + ImportSource = "SRC-20", + OwnerLifecycleState = "Active", + AppServers = + [ + new ModellingImportAppServer + { + Name = "server-new", + Ip = "10.0.0.2/32", + IpEnd = "10.0.0.2/32" + } + ] + }; + OwnerChangeImportTracker tracker = new(apiConn); + + bool imported = await InvokeSaveApp(import, incomingApp, tracker); + + Assert.That(imported, Is.True); + Assert.That(apiConn.UpdateChangelogOwnerCalls, Is.EqualTo(2)); + Assert.That(apiConn.ChangelogActions, Is.EqualTo(new[] { ChangelogActionType.CHANGE, ChangelogActionType.REACTIVATE })); + } + + [Test] + public async Task NormalizeImportedUserReferences_ResolvesPlainUserIds_AndKeepsDns() + { + ResolverTestAppDataImport import = new(new Dictionary(StringComparer.OrdinalIgnoreCase) + { + ["main.user"] = "cn=main.user,ou=users,dc=example,dc=com", + ["support.user"] = "cn=support.user,ou=users,dc=example,dc=com" + }); + ModellingImportAppData incomingApp = new() + { + Name = "App-Resolve", + ExtAppId = "APP-RESOLVE", + MainUser = " main.user ", + Responsibles = new Dictionary> + { + ["1"] = + [ + "support.user", + "cn=group1,ou=groups,dc=example,dc=com" + ] + } + }; + + ModellingImportAppData normalizedApp = await InvokeNormalizeImportedUserReferences(import, incomingApp); + + Assert.That(normalizedApp.MainUser, Is.EqualTo("cn=main.user,ou=users,dc=example,dc=com")); + Assert.That(normalizedApp.Responsibles?["1"], Is.EquivalentTo(new[] + { + "cn=support.user,ou=users,dc=example,dc=com", + "cn=group1,ou=groups,dc=example,dc=com" + })); + Assert.That(import.ResolvedIdentifiers, Is.EqualTo(new[] { "main.user", "support.user" })); + } + + [Test] + public async Task NormalizeImportedUserReferences_DropsUnresolvablePlainUserIds() + { + ResolverTestAppDataImport import = new(new Dictionary(StringComparer.OrdinalIgnoreCase)); + ModellingImportAppData incomingApp = new() + { + Name = "App-Unresolved", + ExtAppId = "APP-UNRESOLVED", + MainUser = "missing.user", + Responsibles = new Dictionary> + { + ["1"] = + [ + "missing.user", + "cn=group1,ou=groups,dc=example,dc=com" + ] + } + }; + + ModellingImportAppData normalizedApp = await InvokeNormalizeImportedUserReferences(import, incomingApp); + + Assert.That(normalizedApp.MainUser, Is.Null); + Assert.That(normalizedApp.Responsibles?["1"], Is.EqualTo(new[] + { + "cn=group1,ou=groups,dc=example,dc=com" + })); + Assert.That(import.ResolvedIdentifiers, Is.EqualTo(new[] { "missing.user", "missing.user" })); + } + + [Test] + public async Task NormalizeImportedUserReferences_ResolvesPlainGroupNamesToGroupDns() + { + ResolverTestAppDataImport import = new( + new Dictionary(StringComparer.OrdinalIgnoreCase), + null, + null, + new Dictionary(StringComparer.OrdinalIgnoreCase) + { + ["app-support"] = "cn=app-support,ou=groups,dc=example,dc=com" + }); + ModellingImportAppData incomingApp = new() + { + Name = "App-GroupResolve", + ExtAppId = "APP-GROUP-RESOLVE", + Responsibles = new Dictionary> + { + ["2"] = ["app-support"] + } + }; + + ModellingImportAppData normalizedApp = await InvokeNormalizeImportedUserReferences(import, incomingApp); + + Assert.That(normalizedApp.Responsibles?["2"], Is.EqualTo(new[] + { + "cn=app-support,ou=groups,dc=example,dc=com" + })); + Assert.That(import.ResolvedGroupIdentifiers, Is.EqualTo(new[] { "app-support" })); + } + + private static AppDataImport CreateImportWithTypeMap(Dictionary typeMap) + { + AppDataImport import = new(new SimulatedApiConnection(), new GlobalConfig()); + FieldInfo field = typeof(AppDataImport).GetField("ownerResponsibleTypeIdByName", BindingFlags.NonPublic | BindingFlags.Instance) + ?? throw new InvalidOperationException("ownerResponsibleTypeIdByName field not found."); + field.SetValue(import, typeMap); + SetResponsibleTypes(import, [.. typeMap.Select(entry => new OwnerResponsibleType + { + Id = entry.Value, + Name = entry.Key, + SortOrder = entry.Value + })]); + return import; + } + + private static void SetResponsibleTypes(AppDataImport import, IEnumerable responsibleTypes) + { + Dictionary byId = responsibleTypes.ToDictionary(type => type.Id, type => type); + FieldInfo field = typeof(AppDataImport).GetField("ownerResponsibleTypeById", BindingFlags.NonPublic | BindingFlags.Instance) + ?? throw new InvalidOperationException("ownerResponsibleTypeById field not found."); + field.SetValue(import, byId); + } + + private static void SetOwnerLifeCycleMap(AppDataImport import, Dictionary stateMap) + { + FieldInfo field = typeof(AppDataImport).GetField("ownerLifeCycleStateIdsByName", BindingFlags.NonPublic | BindingFlags.Instance) + ?? throw new InvalidOperationException("ownerLifeCycleStateIdsByName field not found."); + field.SetValue(import, stateMap); + } + + private static void SetOwnerLifeCycleActiveMap(AppDataImport import, Dictionary stateMap) + { + FieldInfo field = typeof(AppDataImport).GetField("ownerLifeCycleStateActiveById", BindingFlags.NonPublic | BindingFlags.Instance) + ?? throw new InvalidOperationException("ownerLifeCycleStateActiveById field not found."); + field.SetValue(import, stateMap); + } + + private static void SetOwnerDataImportSyncUsers(AppDataImport import, bool syncUsers) + { + FieldInfo field = typeof(DataImportBase).GetField("globalConfig", BindingFlags.NonPublic | BindingFlags.Instance) + ?? throw new InvalidOperationException("globalConfig field not found."); + GlobalConfig globalConfig = (GlobalConfig)field.GetValue(import)!; + globalConfig.OwnerDataImportSyncUsers = syncUsers; + } + + private static void SetRolesByType(AppDataImport import, Dictionary> rolesByType) + { + FieldInfo field = typeof(AppDataImport).GetField("rolesToSetByType", BindingFlags.NonPublic | BindingFlags.Instance) + ?? throw new InvalidOperationException("rolesToSetByType field not found."); + field.SetValue(import, rolesByType); + } + + private static void SetInternalLdap(AppDataImport import, Ldap? ldap) + { + FieldInfo field = typeof(AppDataImport).GetField("internalLdap", BindingFlags.NonPublic | BindingFlags.Instance) + ?? throw new InvalidOperationException("internalLdap field not found."); + field.SetValue(import, ldap); + } + + private static void SetConnectedLdaps(AppDataImport import, List ldaps) + { + FieldInfo field = typeof(AppDataImport).GetField("connectedLdaps", BindingFlags.NonPublic | BindingFlags.Instance) + ?? throw new InvalidOperationException("connectedLdaps field not found."); + field.SetValue(import, ldaps); + } + + private static void SetHasImmediateAppDecommNotificationForImport(AppDataImport import, bool value) + { + FieldInfo field = typeof(AppDataImport).GetField("hasImmediateAppDecommNotificationForImport", BindingFlags.NonPublic | BindingFlags.Instance) + ?? throw new InvalidOperationException("hasImmediateAppDecommNotificationForImport field not found."); + field.SetValue(import, value); + } + + private static List InvokeBuildOwnerResponsibles(AppDataImport import, ModellingImportAppData incomingApp, string userGroupDn, IEnumerable extraDns) + { + MethodInfo method = typeof(AppDataImport).GetMethod( + "BuildOwnerResponsibles", + BindingFlags.NonPublic | BindingFlags.Instance) + ?? throw new InvalidOperationException("BuildOwnerResponsibles helper not found."); + return (List)method.Invoke(import, [incomingApp])!; + } + + private static (bool ok, int? id) InvokeTryResolveOwnerLifeCycleStateId(AppDataImport import, ModellingImportAppData incomingApp) + { + MethodInfo method = typeof(AppDataImport).GetMethod( + "TryResolveOwnerLifeCycleStateId", + BindingFlags.NonPublic | BindingFlags.Instance) + ?? throw new InvalidOperationException("TryResolveOwnerLifeCycleStateId helper not found."); + + object?[] args = [incomingApp, null]; + bool ok = (bool)method.Invoke(import, args)!; + return (ok, (int?)args[1]); + } + + private static Dictionary> InvokeParseRolesWithImport(string rolesJson) + { + MethodInfo method = typeof(AppDataImport).GetMethod( + "ParseRolesWithImport", + BindingFlags.NonPublic | BindingFlags.Static) + ?? throw new InvalidOperationException("ParseRolesWithImport helper not found."); + return (Dictionary>)method.Invoke(null, [rolesJson])!; + } + + private static async Task InvokeApplyRolesToResponsibles( + AppDataImport import, + List responsibles, + Dictionary> rolesByType) + { + MethodInfo method = typeof(AppDataImport).GetMethod( + "ApplyRolesToResponsibles", + BindingFlags.NonPublic | BindingFlags.Instance) + ?? throw new InvalidOperationException("ApplyRolesToResponsibles helper not found."); + await (Task)method.Invoke(import, [responsibles, rolesByType])!; + } + + private static bool InvokeIsResponsibleTypeActive(AppDataImport import, int typeId) + { + MethodInfo method = typeof(AppDataImport).GetMethod( + "IsResponsibleTypeActive", + BindingFlags.NonPublic | BindingFlags.Instance) + ?? throw new InvalidOperationException("IsResponsibleTypeActive helper not found."); + return (bool)method.Invoke(import, [typeId])!; + } + + private static List InvokeGetRolesForType(AppDataImport import, int typeId) + { + MethodInfo method = typeof(AppDataImport).GetMethod( + "GetRolesForType", + BindingFlags.NonPublic | BindingFlags.Instance) + ?? throw new InvalidOperationException("GetRolesForType helper not found."); + return (List)method.Invoke(import, [typeId])!; + } + + private static async Task InvokeAddAllResponsiblesToUiUser(AppDataImport import, IEnumerable responsibles) + { + MethodInfo method = typeof(AppDataImport).GetMethod( + "AddAllResponsiblesToUiUser", + BindingFlags.NonPublic | BindingFlags.Instance) + ?? throw new InvalidOperationException("AddAllResponsiblesToUiUser helper not found."); + await (Task)method.Invoke(import, [responsibles])!; + } + + private static async Task InvokeAddResponsibleDnToUiUser( + AppDataImport import, + string responsibleDn, + HashSet handledUserDns, + HashSet handledGroupDnsByLdap) + { + MethodInfo method = typeof(AppDataImport).GetMethod( + "AddResponsibleDnToUiUser", + BindingFlags.NonPublic | BindingFlags.Instance) + ?? throw new InvalidOperationException("AddResponsibleDnToUiUser helper not found."); + await (Task)method.Invoke(import, [responsibleDn, handledUserDns, handledGroupDnsByLdap])!; + } + + private static async Task InvokeConvertLdapToUiUser(AppDataImport import, string userDn) + { + MethodInfo method = typeof(AppDataImport).GetMethod( + "ConvertLdapToUiUser", + BindingFlags.NonPublic | BindingFlags.Instance) + ?? throw new InvalidOperationException("ConvertLdapToUiUser helper not found."); + return await (Task)method.Invoke(import, [userDn])!; + } + + private static async Task InvokeImportApps(AppDataImport import, string importfileName, OwnerChangeImportTracker tracker) + { + MethodInfo method = typeof(AppDataImport).GetMethod( + "ImportApps", + BindingFlags.NonPublic | BindingFlags.Instance) + ?? throw new InvalidOperationException("ImportApps helper not found."); + await (Task)method.Invoke(import, [importfileName, tracker])!; + } + + private static async Task InvokeSaveApp(AppDataImport import, ModellingImportAppData incomingApp, OwnerChangeImportTracker tracker) + { + MethodInfo method = typeof(AppDataImport).GetMethod( + "SaveApp", + BindingFlags.NonPublic | BindingFlags.Instance) + ?? throw new InvalidOperationException("SaveApp helper not found."); + return await (Task)method.Invoke(import, [incomingApp, tracker])!; + } + + private static async Task InvokeAddOwnerLifeCycleStateActiveChangeIfNeeded( + AppDataImport import, + FwoOwner existingApp, + int? ownerLifeCycleStateId, + string? importSource, + OwnerChangeImportTracker tracker) + { + MethodInfo method = typeof(AppDataImport).GetMethod( + "AddOwnerLifeCycleStateActiveChangeIfNeeded", + BindingFlags.NonPublic | BindingFlags.Instance) + ?? throw new InvalidOperationException("AddOwnerLifeCycleStateActiveChangeIfNeeded helper not found."); + await (Task)method.Invoke(import, [existingApp, ownerLifeCycleStateId, importSource, tracker])!; + } + + private static async Task InvokeAddOwnerChangeIfNeeded( + AppDataImport import, + FwoOwner existingApp, + ModellingImportAppData incomingApp, + OwnerChangeImportTracker tracker) + { + MethodInfo method = typeof(AppDataImport).GetMethod( + "AddOwnerChangeIfNeeded", + BindingFlags.NonPublic | BindingFlags.Instance) + ?? throw new InvalidOperationException("AddOwnerChangeIfNeeded helper not found."); + await (Task)method.Invoke(import, [existingApp, incomingApp, tracker])!; + } + + private static async Task InvokeNormalizeImportedUserReferences(AppDataImport import, ModellingImportAppData incomingApp) + { + MethodInfo method = typeof(AppDataImport).GetMethod( + "NormalizeImportedUserReferences", + BindingFlags.NonPublic | BindingFlags.Instance) + ?? throw new InvalidOperationException("NormalizeImportedUserReferences helper not found."); + return await (Task)method.Invoke(import, [incomingApp])!; + } + + private static async Task<(int deleted, int failed)> InvokeDeactivateMissingApps( + AppDataImport import, + string importSource, + IEnumerable existingApps, + List importedApps, + OwnerChangeImportTracker tracker) + { + SetExistingApps(import, existingApps.ToList()); + SetImportedApps(import, importedApps); + MethodInfo method = typeof(AppDataImport).GetMethod( + "DeactivateMissingApps", + BindingFlags.NonPublic | BindingFlags.Instance) + ?? throw new InvalidOperationException("DeactivateMissingApps helper not found."); + return ((int deleted, int failed))await (Task<(int deleted, int failed)>)method.Invoke(import, [importSource, tracker])!; + } + + private static async Task InvokeUpdateOwnerResponsibles( + AppDataImport import, + int ownerId, + List responsibles, + List existingResponsibles) + { + MethodInfo method = typeof(AppDataImport).GetMethod( + "UpdateOwnerResponsibles", + BindingFlags.NonPublic | BindingFlags.Instance) + ?? throw new InvalidOperationException("UpdateOwnerResponsibles helper not found."); + await (Task)method.Invoke(import, [ownerId, responsibles, existingResponsibles])!; + } + + private static (List toInsert, List toDelete) InvokeCheckResponsibles( + AppDataImport import, + List existingResponsibles, + List incomingResponsibles) + { + MethodInfo method = typeof(AppDataImport).GetMethod( + "CheckResponsibles", + BindingFlags.NonPublic | BindingFlags.Instance) + ?? throw new InvalidOperationException("CheckResponsibles helper not found."); + object result = method.Invoke(import, [existingResponsibles, incomingResponsibles])!; + + Type resultType = result.GetType(); + List toInsert = (List)(resultType.GetField("Item1")?.GetValue(result) + ?? throw new InvalidOperationException("CheckResponsibles result Item1 not found.")); + List toDelete = (List)(resultType.GetField("Item2")?.GetValue(result) + ?? throw new InvalidOperationException("CheckResponsibles result Item2 not found.")); + + return (toInsert, toDelete); + } + + private static void SetImportedApps(AppDataImport import, List importedApps) + { + FieldInfo field = typeof(AppDataImport).GetField("ImportedApps", BindingFlags.NonPublic | BindingFlags.Instance) + ?? throw new InvalidOperationException("ImportedApps field not found."); + field.SetValue(import, importedApps); + } + + private static void SetExistingApps(AppDataImport import, List existingApps) + { + FieldInfo field = typeof(AppDataImport).GetField("ExistingApps", BindingFlags.NonPublic | BindingFlags.Instance) + ?? throw new InvalidOperationException("ExistingApps field not found."); + field.SetValue(import, existingApps); + } + + private static void SetExistingAppServers(AppDataImport import, List existingAppServers) + { + FieldInfo field = typeof(AppDataImport).GetField("ExistingAppServers", BindingFlags.NonPublic | BindingFlags.Instance) + ?? throw new InvalidOperationException("ExistingAppServers field not found."); + field.SetValue(import, existingAppServers); + } + + private sealed class AppDataImportFlowTestApiConn : SimulatedApiConnection + { + public int GetOwnersCalls { get; private set; } + public int DeactivateOwnerCalls { get; private set; } + public int UpdateChangelogOwnerCalls { get; private set; } + public HashSet FailDeactivateOwnerIds { get; } = []; + + public override Task SendQueryAsync(string query, object? variables = null, string? operationName = null) + { + if (query == OwnerQueries.getOwners) + { + ++GetOwnersCalls; + return Task.FromResult((QueryResponseType)(object)new List()); + } + + if (query == OwnerQueries.deactivateOwner) + { + ++DeactivateOwnerCalls; + int ownerId = GetAnonymousInt(variables, "id"); + if (FailDeactivateOwnerIds.Contains(ownerId)) + { + throw new InvalidOperationException($"Deactivate failed for owner {ownerId}."); + } + return Task.FromResult((QueryResponseType)(object)new ReturnIdWrapper + { + ReturnIds = [new ReturnId { NewId = ownerId }] + }); + } + + if (query == ImportQueries.addImportForOwner) + { + return Task.FromResult((QueryResponseType)(object)new InsertImportControl + { + Returning = new List + { + new ImportControl { ControlId = 123 } + } + }); + } + + if (query == OwnerQueries.updateChangelogOwner) + { + ++UpdateChangelogOwnerCalls; + return Task.FromResult((QueryResponseType)(object)new object()); + } + + if (query == MonitorQueries.addDataImportLogEntry) + { + return Task.FromResult((QueryResponseType)(object)new ReturnIdWrapper + { + ReturnIds = [new ReturnId { NewId = 1 }] + }); + } + + throw new NotImplementedException($"Query not implemented in test api: {query}"); + } + + private static int GetAnonymousInt(object? variables, string propertyName) + { + if (variables == null) + { + return 0; + } + PropertyInfo? property = variables.GetType().GetProperty(propertyName, BindingFlags.Public | BindingFlags.Instance); + if (property == null) + { + return 0; + } + object? value = property.GetValue(variables); + return value is int intValue ? intValue : 0; + } + } + + private sealed class AppDataImportResponsiblesApiConn : SimulatedApiConnection + { + public int NewOwnerResponsiblesCalls { get; private set; } + public int DeleteSpecificOwnerResponsiblesCalls { get; private set; } + public List<(int ownerId, string dn, int responsibleType)> Inserted { get; } = []; + public List<(int ownerId, string dn, int responsibleType)> Deleted { get; } = []; + + public override Task SendQueryAsync(string query, object? variables = null, string? operationName = null) + { + if (query == OwnerQueries.newOwnerResponsibles) + { + ++NewOwnerResponsiblesCalls; + if (variables != null) + { + object? objects = GetAnonymousValue(variables, "responsibles"); + if (objects is IEnumerable enumerable) + { + foreach (object entry in enumerable) + { + Inserted.Add(( + GetAnonymousInt(entry, "owner_id"), + GetAnonymousString(entry, "dn"), + GetAnonymousInt(entry, "responsible_type"))); + } + } + } + return Task.FromResult((QueryResponseType)(object)new object()); + } + + if (query == OwnerQueries.deleteSpecificOwnerResponsibles) + { + ++DeleteSpecificOwnerResponsiblesCalls; + int ownerId = GetAnonymousInt(variables, "ownerId"); + object? objects = GetAnonymousValue(variables, "objects"); + if (objects is IEnumerable enumerable) + { + foreach (object entry in enumerable) + { + object? dnObject = GetAnonymousValue(entry, "dn"); + object? typeObject = GetAnonymousValue(entry, "responsible_type"); + Deleted.Add(( + ownerId, + GetAnonymousString(dnObject, "_eq"), + GetAnonymousInt(typeObject, "_eq"))); + } + } + return Task.FromResult((QueryResponseType)(object)new object()); + } + + throw new NotImplementedException($"Query not implemented in responsibles test api: {query}"); + } + + private static int GetAnonymousInt(object? variables, string propertyName) + { + object? value = GetAnonymousValue(variables, propertyName); + return value is int intValue ? intValue : 0; + } + + private static string GetAnonymousString(object? variables, string propertyName) + { + object? value = GetAnonymousValue(variables, propertyName); + return value as string ?? ""; + } + + private static object? GetAnonymousValue(object? variables, string propertyName) + { + if (variables == null) + { + return null; + } + PropertyInfo? property = variables.GetType().GetProperty(propertyName, BindingFlags.Public | BindingFlags.Instance); + return property?.GetValue(variables); + } + } + + private sealed class AppDataImportSaveAppApiConn : SimulatedApiConnection + { + public int NewOwnerCalls { get; private set; } + public int UpdateOwnerCalls { get; private set; } + public int UpdateChangelogOwnerCalls { get; private set; } + public List ChangelogActions { get; } = []; + public Dictionary<(int ownerId, string importSource), List> AppServersByOwner { get; } = []; + public DateTime? LastNewOwnerDecommDate { get; private set; } + public DateTime? LastUpdateOwnerDecommDate { get; private set; } + public Dictionary? LastNewOwnerAdditionalInfo { get; private set; } + public Dictionary? LastUpdateOwnerAdditionalInfo { get; private set; } + + public override Task SendQueryAsync(string query, object? variables = null, string? operationName = null) + { + if (query == OwnerQueries.newOwner) + { + ++NewOwnerCalls; + LastNewOwnerDecommDate = GetAnonymousDateTime(variables, "decommDate"); + LastNewOwnerAdditionalInfo = GetAnonymousStringDictionary(variables, "additionalInfo"); + return Task.FromResult((QueryResponseType)(object)new ReturnIdWrapper + { + ReturnIds = [new ReturnId { NewId = 1 }] + }); + } + + if (query == OwnerQueries.updateOwner) + { + ++UpdateOwnerCalls; + LastUpdateOwnerDecommDate = GetAnonymousDateTime(variables, "decommDate"); + LastUpdateOwnerAdditionalInfo = GetAnonymousStringDictionary(variables, "additionalInfo"); + return Task.FromResult((QueryResponseType)(object)new ReturnIdWrapper + { + ReturnIds = [new ReturnId { NewId = 1 }] + }); + } + + if (query == OwnerQueries.updateChangelogOwner) + { + ++UpdateChangelogOwnerCalls; + char? action = GetAnonymousChar(variables, "change_action"); + if (action.HasValue) + { + ChangelogActions.Add(action.Value); + } + return Task.FromResult((QueryResponseType)(object)new object()); + } + + if (query == ModellingQueries.getAppServersBySource) + { + int ownerId = GetAnonymousInt(variables, "appId"); + string importSource = GetAnonymousString(variables, "importSource"); + List appServers = AppServersByOwner.TryGetValue((ownerId, importSource), out List? value) + ? value + : []; + return Task.FromResult((QueryResponseType)(object)appServers); + } + + if (query == ImportQueries.addImportForOwner) + { + return Task.FromResult((QueryResponseType)(object)new InsertImportControl + { + Returning = new List + { + new ImportControl { ControlId = 123 } + } + }); + } + + if (query == MonitorQueries.addDataImportLogEntry) + { + return Task.FromResult((QueryResponseType)(object)new ReturnIdWrapper + { + ReturnIds = [new ReturnId { NewId = 1 }] + }); + } + + throw new NotImplementedException($"Query not implemented in save-app test api: {query}"); + } + + private static char? GetAnonymousChar(object? variables, string propertyName) + { + if (variables == null) + { + return null; + } + PropertyInfo? property = variables.GetType().GetProperty(propertyName, BindingFlags.Public | BindingFlags.Instance); + if (property == null) + { + return null; + } + object? value = property.GetValue(variables); + return value is char charValue ? charValue : null; + } + + private static int GetAnonymousInt(object? variables, string propertyName) + { + if (variables == null) + { + return 0; + } + PropertyInfo? property = variables.GetType().GetProperty(propertyName, BindingFlags.Public | BindingFlags.Instance); + if (property == null) + { + return 0; + } + object? value = property.GetValue(variables); + return value is int intValue ? intValue : 0; + } + + private static DateTime? GetAnonymousDateTime(object? variables, string propertyName) + { + if (variables == null) + { + return null; + } + PropertyInfo? property = variables.GetType().GetProperty(propertyName, BindingFlags.Public | BindingFlags.Instance); + if (property == null) + { + return null; + } + object? value = property.GetValue(variables); + return value as DateTime? ?? (value is DateTime dateTime ? dateTime : null); + } + + private static string GetAnonymousString(object? variables, string propertyName) + { + if (variables == null) + { + return ""; + } + PropertyInfo? property = variables.GetType().GetProperty(propertyName, BindingFlags.Public | BindingFlags.Instance); + if (property == null) + { + return ""; + } + object? value = property.GetValue(variables); + return value as string ?? ""; + } + + private static Dictionary? GetAnonymousStringDictionary(object? variables, string propertyName) + { + if (variables == null) + { + return null; + } + PropertyInfo? property = variables.GetType().GetProperty(propertyName, BindingFlags.Public | BindingFlags.Instance); + if (property == null) + { + return null; + } + object? value = property.GetValue(variables); + return value as Dictionary; + } + } + + private sealed class TestAppDataImport(ApiConnection apiConnection, GlobalConfig globalConfig) : AppDataImport(apiConnection, globalConfig) + { + public List CheckedOwners { get; } = []; + + protected override Task CheckActiveRulesSync(FwoOwner owner) + { + CheckedOwners.Add(new FwoOwner(owner) { OwnerLifeCycleStateId = owner.OwnerLifeCycleStateId }); + return Task.CompletedTask; + } + } + + private sealed class ResolverTestAppDataImport : AppDataImport + { + private readonly Dictionary resolutions; + private readonly Dictionary uiUsersByDn; + private readonly Dictionary> groupMembersByDn; + private readonly Dictionary groupResolutions; + public List ResolvedIdentifiers { get; } = []; + public List ResolvedGroupIdentifiers { get; } = []; + + public ResolverTestAppDataImport( + Dictionary resolutions, + Dictionary? uiUsersByDn = null, + Dictionary>? groupMembersByDn = null, + Dictionary? groupResolutions = null) + : base(new SimulatedApiConnection(), new GlobalConfig()) + { + this.resolutions = resolutions; + this.uiUsersByDn = uiUsersByDn ?? new(StringComparer.OrdinalIgnoreCase); + this.groupMembersByDn = groupMembersByDn ?? new(StringComparer.OrdinalIgnoreCase); + this.groupResolutions = groupResolutions ?? new(StringComparer.OrdinalIgnoreCase); + } + + protected override Task ResolveImportedUserIdentifierToDn(string userIdentifier) + { + ResolvedIdentifiers.Add(userIdentifier); + return Task.FromResult(resolutions.TryGetValue(userIdentifier, out string? resolvedDn) ? resolvedDn : null); + } + + protected override Task ResolveImportedUiUser(string responsibleDn) + { + return Task.FromResult(uiUsersByDn.TryGetValue(responsibleDn, out UiUser? uiUser) ? uiUser : null); + } + + protected override Task> ResolveImportedGroupMembers(Ldap ldap, string groupDn) + { + return Task.FromResult(groupMembersByDn.TryGetValue(groupDn, out List? members) ? members : []); + } + + protected override Task ResolveImportedGroupIdentifierToDn(string groupIdentifier) + { + ResolvedGroupIdentifiers.Add(groupIdentifier); + return Task.FromResult(groupResolutions.TryGetValue(groupIdentifier, out string? resolvedDn) ? resolvedDn : null); + } + } + + private sealed class RoleRemovalTrackingImport : AppDataImport + { + public List<(string dn, string role)> RemovedRoleAssignments { get; } = []; + + public RoleRemovalTrackingImport(ApiConnection apiConnection) + : base(apiConnection, new GlobalConfig()) + { + } + + protected override Task RemoveRoleFromDn(string dn, string role) + { + RemovedRoleAssignments.Add((dn, role)); + return Task.CompletedTask; + } + } + } +} diff --git a/roles/tests-unit/files/FWO.Test/AppRoleTest.cs b/roles/tests-unit/files/FWO.Test/AppRoleTest.cs new file mode 100644 index 0000000000..4759a69988 --- /dev/null +++ b/roles/tests-unit/files/FWO.Test/AppRoleTest.cs @@ -0,0 +1,140 @@ +using NUnit.Framework; +using NUnit.Framework.Legacy; +using FWO.Basics; +using FWO.Data; +using FWO.Data.Modelling; + +namespace FWO.Test +{ + [TestFixture] + [Parallelizable] + internal class AppRoleTest + { + static readonly string ARName = "ARxx12345-100"; + static readonly ModellingNamingConvention NamingConvention = new() + { + NetworkAreaRequired = true, + UseAppPart = true, + FixedPartLength = 4, + FreePartLength = 3, + NetworkAreaPattern = "NA", + AppRolePattern = "AR" + }; + + static readonly NetworkObject nwObj1 = new() + { + Id = 1, + Name = ARName, + IP = "", + IpEnd = "", + Uid = "XYZ123", + CreateTime = new() { Time = new(2024, 10, 13, 8, 1, 0) }, + Type = new() { Name = ObjectType.Group }, + Comment = "Comment nw1", + ObjectGroupFlats = + [ + new(){ Id = 10, Object = new() + { + Id = 2, + Name = "nwObj2", + IP = "111.222.33.44", + IpEnd = "111.222.33.88", + Uid = "XYZ1234", + CreateTime = new(){ Time = new(2024, 10, 13, 8, 2, 0) }, + Type = new(){ Name = "Network" }, + Comment ="Comment nw2", + Number = 2 + }}, + new(){ Id = 11, Object = new() + { + Id = 3, + Name = "nwObj3", + IP = "111.222.33.99", + IpEnd = "", + Uid = "XYZ1234", + CreateTime = new(){ Time = new(2024, 10, 13, 8, 3, 0) }, + Type = new(){ Name = "Network" }, + Comment ="Comment nw3", + Number = 3 + }}, + new(){ Id = 11, Object = new() + { + Id = 4, + Name = "nwObj4", + IP = "", + IpEnd = "", + Uid = "XYZ1234", + CreateTime = new(){ Time = new(2024, 10, 13, 8, 4, 0) }, + Type = new(){ Name = ObjectType.Group }, + Comment ="Comment nw4", + Number = 4 + }} + ], + Number = 1 + }; + static readonly ModellingAppRole ar1 = new(nwObj1, NamingConvention); + static readonly ModellingAppRole ar2 = new(ar1); + static readonly ModellingAppRole ar3 = new(nwObj1); + static readonly ModellingAppRole ar4 = new(ar3); + + + static readonly NetworkObject nwObjConverted = ar1.ToNetworkObjectGroup(); + + [SetUp] + public void Initialize() + { } + + [Test] + public void TestAppRole() + { + ClassicAssert.AreEqual(false, ar1.Sanitize()); + ClassicAssert.AreEqual($" {ar1.Name} ({ar1.IdString})", ar1.DisplayWithIcon()); + + ClassicAssert.AreEqual(ARName, ar1.Name); + ClassicAssert.AreEqual(1, ar1.Number); + ClassicAssert.AreEqual(ARName, ar1.IdString); + ClassicAssert.AreEqual(false, ar1.IsDeleted); + ClassicAssert.AreEqual(1, ar1.Id); + ClassicAssert.AreEqual("Comment nw1", ar1.Comment); + ClassicAssert.AreEqual(null, ar1.Creator); + ClassicAssert.AreEqual("13.10.2024 08:01:00", ar1.CreationDate.ToString()); + ClassicAssert.AreEqual(20, ar1.GroupType); + ClassicAssert.AreEqual(2, ar1.AppServers.Count); + + ClassicAssert.AreEqual(2, ar1.AppServers[0].Content.Id); + ClassicAssert.AreEqual("nwObj2", ar1.AppServers[0].Content.Name); + ClassicAssert.AreEqual(2, ar1.AppServers[0].Content.Number); + ClassicAssert.AreEqual("111.222.33.44", ar1.AppServers[0].Content.Ip); + ClassicAssert.AreEqual("111.222.33.88", ar1.AppServers[0].Content.IpEnd); + ClassicAssert.AreEqual(0, ar1.AppServers[0].Content.CustomType); + + ClassicAssert.AreEqual(3, ar1.AppServers[1].Content.Id); + ClassicAssert.AreEqual("nwObj3", ar1.AppServers[1].Content.Name); + ClassicAssert.AreEqual(3, ar1.AppServers[1].Content.Number); + ClassicAssert.AreEqual("111.222.33.99", ar1.AppServers[1].Content.Ip); + ClassicAssert.AreEqual("", ar1.AppServers[1].Content.IpEnd); + ClassicAssert.AreEqual(0, ar1.AppServers[1].Content.CustomType); + + ClassicAssert.AreEqual(1, nwObjConverted.Id); + ClassicAssert.AreEqual(1, nwObjConverted.Number); + ClassicAssert.AreEqual(ARName + " (" + ar1.IdString + ")", nwObjConverted.Name); + ClassicAssert.AreEqual("Comment nw1", nwObjConverted.Comment); + ClassicAssert.AreEqual(ObjectType.Group, nwObjConverted.Type.Name); + ClassicAssert.AreEqual("nwObj2|nwObj3", nwObjConverted.MemberNames); + + ClassicAssert.AreEqual(ar2.Id, ar1.Id); + ClassicAssert.AreEqual(ar2.Name, ar1.Name); + ClassicAssert.AreEqual(ar2.Number, ar1.Number); + ClassicAssert.AreEqual(ar2.IdString, ar1.IdString); + ClassicAssert.AreEqual(ar2.Comment, ar1.Comment); + ClassicAssert.AreEqual(ar2.Creator, ar1.Creator); + ClassicAssert.AreEqual(ar2.CreationDate, ar1.CreationDate); + ClassicAssert.AreEqual(ar2.Area, ar1.Area); + ClassicAssert.AreEqual(ar2.AppId, ar1.AppId); + ClassicAssert.AreEqual(ar2.AppServers, ar1.AppServers); + + ClassicAssert.AreEqual(ar3.IdString, ar1.IdString); + ClassicAssert.AreEqual(ar4.IdString, ar1.IdString); + } + } +} diff --git a/roles/tests-unit/files/FWO.Test/AppServerHelperTest.cs b/roles/tests-unit/files/FWO.Test/AppServerHelperTest.cs new file mode 100644 index 0000000000..861216eca6 --- /dev/null +++ b/roles/tests-unit/files/FWO.Test/AppServerHelperTest.cs @@ -0,0 +1,289 @@ +using FWO.Data.Modelling; +using FWO.Services.Modelling; +using FWO.Api.Client; +using FWO.Api.Client.Queries; +using FWO.Basics; +using FWO.Config.Api; +using FWO.Data; +using NUnit.Framework; + +namespace FWO.Test +{ + [TestFixture] + internal class AppServerHelperTest + { + private static ModellingNamingConvention CreateNamingConvention() + { + return new ModellingNamingConvention + { + AppServerPrefix = "srv-", + NetworkPrefix = "net-", + IpRangePrefix = "rng-" + }; + } + + [Test] + public void ConstructAppServerName_UsesPrefixAndIp_WhenNameMissing() + { + ModellingAppServer appServer = new() + { + Name = "", + Ip = "10.0.0.1", + IpEnd = "" + }; + + string name = AppServerHelper.ConstructAppServerName(appServer, CreateNamingConvention()); + + Assert.That(name, Is.EqualTo("srv-10.0.0.1")); + } + + [Test] + public void ConstructAppServerName_ReturnsName_WhenStartsWithLetter() + { + ModellingAppServer appServer = new() + { + Name = "web-1", + Ip = "10.0.0.1", + IpEnd = "" + }; + + string name = AppServerHelper.ConstructAppServerName(appServer, CreateNamingConvention()); + + Assert.That(name, Is.EqualTo("web-1")); + } + + [Test] + public void ConstructAppServerName_PrefixesName_WhenStartsWithDigit() + { + ModellingAppServer appServer = new() + { + Name = "1web", + Ip = "10.0.0.1", + IpEnd = "" + }; + + string name = AppServerHelper.ConstructAppServerName(appServer, CreateNamingConvention()); + + Assert.That(name, Is.EqualTo("srv-1web")); + } + + [Test] + public void ConstructAppServerName_UsesNetworkPrefix_ForCidr() + { + ModellingAppServer appServer = new() + { + Name = "", + Ip = "10.0.0.0/24", + IpEnd = "" + }; + + string name = AppServerHelper.ConstructAppServerName(appServer, CreateNamingConvention()); + + Assert.That(name, Is.EqualTo("net-10.0.0.0/24")); + } + + [Test] + public void ConstructAppServerName_UsesIpRangePrefix_ForRange() + { + ModellingAppServer appServer = new() + { + Name = "", + Ip = "10.0.0.1", + IpEnd = "10.0.0.10" + }; + + string name = AppServerHelper.ConstructAppServerName(appServer, CreateNamingConvention()); + + Assert.That(name, Is.EqualTo("rng-10.0.0.1-10.0.0.10")); + } + + [Test] + public void ConstructAppServerName_OverwritesExistingName_WhenRequested() + { + ModellingAppServer appServer = new() + { + Name = "web-1", + Ip = "10.0.0.1", + IpEnd = "" + }; + + string name = AppServerHelper.ConstructAppServerName(appServer, CreateNamingConvention(), overwriteExistingNames: true); + + Assert.That(name, Is.EqualTo("srv-10.0.0.1")); + } + + [Test] + public void ConstructSanitizedAppServerName_ReplacesInvalidCharacters() + { + ModellingAppServer appServer = new() + { + Name = "web!1", + Ip = "10.0.0.1", + IpEnd = "" + }; + + string name = AppServerHelper.ConstructSanitizedAppServerName(appServer, CreateNamingConvention()); + + Assert.That(name, Is.EqualTo("web_1")); + } + + [Test] + public void ConstructSanitizedAppServerName_SanitizesNetworkSlash() + { + ModellingAppServer appServer = new() + { + Name = "", + Ip = "10.0.0.0/24", + IpEnd = "" + }; + + string name = AppServerHelper.ConstructSanitizedAppServerName(appServer, CreateNamingConvention()); + + Assert.That(name, Is.EqualTo("net-10.0.0.0_24")); + } + + [Test] + public async Task UpsertAppServer_UsesOverwriteAppServer_WhenSameSourceExists() + { + ModellingAppServer incoming = new() + { + Id = 0, + AppId = 7, + Name = "incoming", + Ip = "10.0.0.1", + IpEnd = "10.0.0.1", + ImportSource = "import" + }; + + ModellingAppServer sameSource = new() + { + Id = 10, + AppId = 7, + Name = "existing-manual", + Ip = "10.0.0.1", + IpEnd = "", + ImportSource = "import" + }; + + ModellingAppServer otherSource = new() + { + Id = 11, + AppId = 7, + Name = "existing-import", + Ip = "10.0.0.1", + IpEnd = "", + ImportSource = GlobalConst.kManual, + IsDeleted = false + }; + + AppServerHelperTestApiConn apiConn = new([sameSource, otherSource]); + UserConfig userConfig = new SimulatedUserConfig(); + userConfig.User.Name = "tester"; + + (long? appServerId, string? existingName) = await AppServerHelper.UpsertAppServer(apiConn, userConfig, incoming, nameCheck: false); + + Assert.That(appServerId, Is.EqualTo(sameSource.Id)); + Assert.That(existingName, Is.EqualTo(sameSource.Name)); + Assert.That(apiConn.UpdateAppServerCalls, Is.EqualTo(1)); + Assert.That(apiConn.SetDeletedCalls, Is.EqualTo(1)); + } + + [Test] + public async Task ReactivateOtherSource_ReplacesAppServerAndLogsHistory() + { + ModellingAppServer deleted = new() + { + Id = 5, + AppId = 7, + Name = "deleted", + Ip = "10.0.0.1", + IpEnd = "10.0.0.1", + ImportSource = GlobalConst.kManual + }; + + ModellingAppServer reactivatable = new() + { + Id = 12, + AppId = 7, + Name = "reactivate", + Ip = "10.0.0.1", + IpEnd = "", + ImportSource = "import", + IsDeleted = true + }; + + AppServerHelperTestApiConn apiConn = new([deleted, reactivatable]); + UserConfig userConfig = new SimulatedUserConfig + { + AutoReplaceAppServer = true + }; + userConfig.User.Name = "tester"; + + await AppServerHelper.ReactivateOtherSource(apiConn, userConfig, deleted); + + Assert.That(apiConn.SetDeletedCalls, Is.EqualTo(1)); + Assert.That(apiConn.ReplaceInGroupCalls, Is.EqualTo(1)); + Assert.That(apiConn.ReplaceInConnectionCalls, Is.EqualTo(1)); + Assert.That(apiConn.HistoryEntryCalls, Is.EqualTo(1)); + } + } + + internal sealed class AppServerHelperTestApiConn : SimulatedApiConnection + { + private readonly List appServersByIp; + + public int UpdateAppServerCalls { get; private set; } + public int SetDeletedCalls { get; private set; } + public int ReplaceInGroupCalls { get; private set; } + public int ReplaceInConnectionCalls { get; private set; } + public int HistoryEntryCalls { get; private set; } + + public AppServerHelperTestApiConn(List appServersByIp) + { + this.appServersByIp = appServersByIp; + } + + public override Task SendQueryAsync(string query, object? variables = null, string? operationName = null) + { + if (typeof(QueryResponseType) == typeof(List) && query == ModellingQueries.getAppServersByIp) + { + return Task.FromResult((QueryResponseType)(object)appServersByIp); + } + + if (typeof(QueryResponseType) == typeof(ReturnId) && query == ModellingQueries.updateAppServer) + { + UpdateAppServerCalls++; + return Task.FromResult((QueryResponseType)(object)new ReturnId()); + } + + if (typeof(QueryResponseType) == typeof(ReturnIdWrapper)) + { + if (query == ModellingQueries.setAppServerDeletedState) + { + SetDeletedCalls++; + return Task.FromResult((QueryResponseType)(object)new ReturnIdWrapper { ReturnIds = [new ReturnId()] }); + } + + if (query == ModellingQueries.updateNwObjectInNwGroup) + { + ReplaceInGroupCalls++; + return Task.FromResult((QueryResponseType)(object)new ReturnIdWrapper { ReturnIds = [new ReturnId()] }); + } + + if (query == ModellingQueries.updateNwObjectInConnection) + { + ReplaceInConnectionCalls++; + return Task.FromResult((QueryResponseType)(object)new ReturnIdWrapper { ReturnIds = [new ReturnId()] }); + } + + if (query == ModellingQueries.addHistoryEntry) + { + HistoryEntryCalls++; + return Task.FromResult((QueryResponseType)(object)new ReturnIdWrapper { ReturnIds = [new ReturnId()] }); + } + } + + throw new NotImplementedException(); + } + } +} diff --git a/roles/tests-unit/files/FWO.Test/ApproverAllowedChangesConfigTest.cs b/roles/tests-unit/files/FWO.Test/ApproverAllowedChangesConfigTest.cs new file mode 100644 index 0000000000..025f623fd2 --- /dev/null +++ b/roles/tests-unit/files/FWO.Test/ApproverAllowedChangesConfigTest.cs @@ -0,0 +1,111 @@ +using FWO.Data.Workflow; +using NUnit.Framework; +using System.Text.Json; + +namespace FWO.Test +{ + [TestFixture] + public class ApproverAllowedChangesConfigTest + { + [Test] + public void Parse_ReturnsDefaults_WhenConfigIsEmpty() + { + ApproverAllowedChangesConfig config = ApproverAllowedChangesConfig.Parse(""); + + Assert.That(config.TicketFields, Is.Empty); + Assert.That(config.TaskTypeFields.ContainsKey(WfTaskType.access.ToString()), Is.True); + Assert.That(config.TaskTypeFields[WfTaskType.access.ToString()], Is.Empty); + } + + [Test] + public void SetFieldAndSerialize_RoundTripsSelections() + { + ApproverAllowedChangesConfig config = new(); + config.SetTicketField(WorkflowEditableFieldKeys.Title, true); + config.SetTaskField(WfTaskType.access, WorkflowEditableFieldKeys.Services, true); + + string serialized = config.ToConfigValue(); + ApproverAllowedChangesConfig parsed = ApproverAllowedChangesConfig.Parse(serialized); + + Assert.That(parsed.IsTicketFieldAllowed(WorkflowEditableFieldKeys.Title), Is.True); + Assert.That(parsed.IsTaskFieldAllowed(WfTaskType.access, WorkflowEditableFieldKeys.Services), Is.True); + } + + [Test] + public void Parse_AddsMissingTaskTypeEntries() + { + string serialized = JsonSerializer.Serialize(new ApproverAllowedChangesConfig() + { + TicketFields = [WorkflowEditableFieldKeys.Reason], + TaskTypeFields = new Dictionary> + { + [WfTaskType.generic.ToString()] = [WorkflowEditableFieldKeys.FreeText] + } + }); + + ApproverAllowedChangesConfig parsed = ApproverAllowedChangesConfig.Parse(serialized); + + Assert.That(parsed.IsTicketFieldAllowed(WorkflowEditableFieldKeys.Reason), Is.True); + Assert.That(parsed.IsTaskFieldAllowed(WfTaskType.generic, WorkflowEditableFieldKeys.FreeText), Is.True); + Assert.That(parsed.TaskTypeFields.ContainsKey(WfTaskType.new_interface.ToString()), Is.True); + } + + [Test] + public void AccessHelper_OnlyAllowsConfiguredTicketFieldsInApprovalPhase() + { + ApproverAllowedChangesConfig config = new(); + config.SetTicketField(WorkflowEditableFieldKeys.Title, true); + + Assert.That(ApproverAllowedChangesAccess.CanEditTicketField(config, true, false, false, WorkflowEditableFieldKeys.Title), Is.True); + Assert.That(ApproverAllowedChangesAccess.CanEditTicketField(config, true, false, false, WorkflowEditableFieldKeys.Reason), Is.False); + Assert.That(ApproverAllowedChangesAccess.CanEditTicketField(config, false, false, false, WorkflowEditableFieldKeys.Title), Is.False); + Assert.That(ApproverAllowedChangesAccess.CanEditTicketField(config, true, false, true, WorkflowEditableFieldKeys.Title), Is.False); + } + + [Test] + public void AccessHelper_OnlyAllowsConfiguredTaskFieldsWhileApproving() + { + ApproverAllowedChangesConfig config = new(); + config.SetTaskField(WfTaskType.access, WorkflowEditableFieldKeys.Services, true); + ApproverAllowedChangesAccess.TaskFieldEditContext approvalContext = new() + { + IsApprovalPhase = true, + ApproveReqTaskMode = true, + TaskType = WfTaskType.access + }; + ApproverAllowedChangesAccess.TaskFieldEditContext noApproveContext = new() + { + IsApprovalPhase = true, + TaskType = WfTaskType.access + }; + ApproverAllowedChangesAccess.TaskFieldEditContext planningContext = new() + { + ApproveReqTaskMode = true, + TaskType = WfTaskType.access + }; + + Assert.That(ApproverAllowedChangesAccess.CanEditTaskField(config, approvalContext, WorkflowEditableFieldKeys.Services), Is.True); + Assert.That(ApproverAllowedChangesAccess.CanEditTaskField(config, noApproveContext, WorkflowEditableFieldKeys.Services), Is.False); + Assert.That(ApproverAllowedChangesAccess.CanEditTaskField(config, approvalContext, WorkflowEditableFieldKeys.Source), Is.False); + Assert.That(ApproverAllowedChangesAccess.CanEditTaskField(config, planningContext, WorkflowEditableFieldKeys.Services), Is.False); + } + + [Test] + public void AccessHelper_BlocksCopiedTaskFields_WhenImplementationTasksAlreadyExist() + { + ApproverAllowedChangesConfig config = new(); + config.SetTaskField(WfTaskType.access, WorkflowEditableFieldKeys.Services, true); + config.SetTaskField(WfTaskType.access, WorkflowEditableFieldKeys.Reason, true); + ApproverAllowedChangesAccess.TaskFieldEditContext context = new() + { + IsApprovalPhase = true, + ApproveReqTaskMode = true, + TaskType = WfTaskType.access, + HasImplementationTasks = true + }; + + Assert.That(ApproverAllowedChangesAccess.CanEditTaskField(config, context, WorkflowEditableFieldKeys.Services), Is.False); + Assert.That(ApproverAllowedChangesAccess.CanEditTaskField(config, context, WorkflowEditableFieldKeys.Reason), Is.True); + } + } +} diff --git a/roles/tests-unit/files/FWO.Test/AuthLdapSelectionTest.cs b/roles/tests-unit/files/FWO.Test/AuthLdapSelectionTest.cs new file mode 100644 index 0000000000..9abaed936f --- /dev/null +++ b/roles/tests-unit/files/FWO.Test/AuthLdapSelectionTest.cs @@ -0,0 +1,43 @@ +using FWO.Middleware.Server; +using NUnit.Framework; + +namespace FWO.Test +{ + [TestFixture] + public class AuthLdapSelectionTest + { + [Test] + public void GetPreferredLdapIndexReturnsFirstSuccessfulIndex() + { + int selected = AuthLdapSelection.GetPreferredLdapIndex([false, true, true]); + + Assert.That(selected, Is.EqualTo(1)); + } + + [Test] + public void GetPreferredLdapIndexReturnsZeroWhenFirstSucceeds() + { + int selected = AuthLdapSelection.GetPreferredLdapIndex([true, false, true]); + + Assert.That(selected, Is.EqualTo(0)); + } + + [Test] + public void GetPreferredLdapIndexReturnsMinusOneWhenNoneSucceeds() + { + int selected = AuthLdapSelection.GetPreferredLdapIndex([false, false, false]); + + Assert.That(selected, Is.EqualTo(-1)); + } + + [Test] + public void GetPreferredLdapIndexReturnsMinusOneForNullOrEmpty() + { + int selectedForNull = AuthLdapSelection.GetPreferredLdapIndex(null); + int selectedForEmpty = AuthLdapSelection.GetPreferredLdapIndex([]); + + Assert.That(selectedForNull, Is.EqualTo(-1)); + Assert.That(selectedForEmpty, Is.EqualTo(-1)); + } + } +} diff --git a/roles/tests-unit/files/FWO.Test/AuthLoggingHelperTest.cs b/roles/tests-unit/files/FWO.Test/AuthLoggingHelperTest.cs new file mode 100644 index 0000000000..f8606ccc6b --- /dev/null +++ b/roles/tests-unit/files/FWO.Test/AuthLoggingHelperTest.cs @@ -0,0 +1,73 @@ +using FWO.Data; +using FWO.Middleware.Server; +using NUnit.Framework; + +namespace FWO.Test +{ + [TestFixture] + public class AuthLoggingHelperTest + { + [Test] + public void FormatSelectedLdapContainsRelevantFields() + { + LdapConnectionBase ldap = new() + { + Id = 7, + Address = "ldap.example.local", + Port = 636, + Type = (int)LdapType.OpenLdap, + TenantId = 3 + }; + + string formatted = AuthLoggingHelper.FormatSelectedLdap(ldap); + + Assert.That(formatted, Does.Contain("id=7")); + Assert.That(formatted, Does.Contain("host=ldap.example.local:636")); + Assert.That(formatted, Does.Contain($"type={(int)LdapType.OpenLdap}")); + Assert.That(formatted, Does.Contain("tenant=3")); + } + + [Test] + public void FormatSelectedLdapHandlesNullAndDynamicTenant() + { + LdapConnectionBase ldap = new() + { + Id = 8, + Address = "ldap.example.local", + Port = 389, + Type = (int)LdapType.Default, + TenantId = null + }; + + string formattedNull = AuthLoggingHelper.FormatSelectedLdap(null); + string formattedDynamicTenant = AuthLoggingHelper.FormatSelectedLdap(ldap); + + Assert.That(formattedNull, Is.EqualTo("ldap=")); + Assert.That(formattedDynamicTenant, Does.Contain("tenant=")); + } + + [Test] + public void FormatResolvedGroupsNormalizesAndSortsGroupDns() + { + string formatted = AuthLoggingHelper.FormatResolvedGroups( + [ + "cn=Sec,ou=groups,dc=example,dc=com", + "", + "CN=App,ou=groups,dc=example,dc=com", + "cn=app,ou=groups,dc=example,dc=com" + ]); + + Assert.That(formatted, Does.StartWith("count=2, groups=[")); + Assert.That(formatted, Does.Contain("CN=App,ou=groups,dc=example,dc=com")); + Assert.That(formatted, Does.Contain("cn=Sec,ou=groups,dc=example,dc=com")); + } + + [Test] + public void FormatResolvedGroupsHandlesNullInput() + { + string formatted = AuthLoggingHelper.FormatResolvedGroups(null); + + Assert.That(formatted, Is.EqualTo("count=0, groups=[]")); + } + } +} diff --git a/roles/tests-unit/files/FWO.Test/AutoDiscoveryFortiManagerTest.cs b/roles/tests-unit/files/FWO.Test/AutoDiscoveryFortiManagerTest.cs new file mode 100644 index 0000000000..e929b44e61 --- /dev/null +++ b/roles/tests-unit/files/FWO.Test/AutoDiscoveryFortiManagerTest.cs @@ -0,0 +1,59 @@ +using FWO.Api.Client; +using FWO.Data; +using FWO.DeviceAutoDiscovery; +using NUnit.Framework; +using System.Reflection; + +namespace FWO.Test +{ + [TestFixture] + internal class AutoDiscoveryFortiManagerTest + { + [Test] + public void ConvertAdomsToManagements_SetsDeviceUidToName_WhenUidMissing() + { + Management superManagement = new() + { + Name = "fmgr", + DeviceType = new DeviceType { Id = 12 } + }; + SimulatedApiConnection apiConnection = new(); + AutoDiscoveryFortiManager discovery = new(superManagement, apiConnection); + + Adom adom = new() + { + Name = "root", + DeviceList = + [ + new FortiGate { Name = "gw-1", Uid = "" } + ] + }; + + MethodInfo? convertMethod = typeof(AutoDiscoveryFortiManager) + .GetMethod("ConvertAdomsToManagements", BindingFlags.NonPublic | BindingFlags.Instance); + Assert.That(convertMethod, Is.Not.Null); + + var managements = (List)convertMethod!.Invoke(discovery, [new List { adom }])!; + + Assert.That(managements, Has.Count.EqualTo(1)); + Assert.That(managements[0].Devices, Has.Length.EqualTo(1)); + Assert.That(managements[0].Devices[0].Uid, Is.EqualTo("gw-1")); + } + + [Test] + public void CheckDeviceNotInMgmt_IgnoresName_WhenComparingByUidOnly() + { + Device existing = new() { Name = "gw-1_vdomA", Uid = "gw-1" }; + Device discovered = new() { Name = "gw-1", Uid = "gw-1" }; + Management management = new() { Devices = [existing] }; + + MethodInfo? compareMethod = typeof(AutoDiscoveryBase) + .GetMethod("CheckDeviceNotInMgmt", BindingFlags.NonPublic | BindingFlags.Static); + Assert.That(compareMethod, Is.Not.Null); + + bool notInManagement = (bool)compareMethod!.Invoke(null, [discovered, management, true])!; + + Assert.That(notInManagement, Is.False); + } + } +} diff --git a/roles/tests-unit/files/FWO.Test/ComparerTest.cs b/roles/tests-unit/files/FWO.Test/ComparerTest.cs new file mode 100644 index 0000000000..a58e89b86c --- /dev/null +++ b/roles/tests-unit/files/FWO.Test/ComparerTest.cs @@ -0,0 +1,503 @@ +using NUnit.Framework; +using NUnit.Framework.Legacy; +using FWO.Data; +using FWO.Data.Modelling; +using FWO.Services; +using FWO.Services.Modelling; + +namespace FWO.Test +{ + [TestFixture] + [Parallelizable] + internal class ComparerTest + { + static readonly ModellingAppServer AppSrv1 = new() { Name = "AppSrv_1", Ip = "1.2.3.4", IpEnd = "1.2.3.4" }; + static readonly ModellingAppServer AppSrv2 = new() { Name = "AppSrv2", Ip = "1.2.3.4", IpEnd = "1.2.3.4" }; + static readonly ModellingAppServer AppSrv3 = new() { Name = "", Ip = "1.2.3.4", IpEnd = "1.2.3.4" }; + static readonly ModellingAppServer AppSrv4 = new() { Name = "AppSrv_1", Ip = "1.1.1.1", IpEnd = "1.1.1.2" }; + static readonly ModellingAppServer AppSrv5 = new() { Name = "AppSrv_1", Ip = "", IpEnd = "" }; + static readonly ModellingAppServer AppSrv6 = new() { Name = "AppSrv/1 ", Ip = "1.2.3.4", IpEnd = "1.2.3.4" }; + + static readonly ModellingAppRole AppRole1 = new() { Name = "AppRole1", IdString = "AR1", AppServers = [new() { Content = AppSrv1 }] }; + static readonly ModellingAppRole AppRole2 = new() { Name = "AppRole2", IdString = "AR2", AppServers = [new() { Content = AppSrv2 }] }; + + static readonly ModellingAppServerWrapper AppSrvWrap1 = new() { Content = AppSrv1 }; + static readonly ModellingAppServerWrapper AppSrvWrap2 = new() { Content = AppSrv2 }; + static readonly ModellingAppServerWrapper AppSrvWrap3 = new() { Content = AppSrv3 }; + static readonly ModellingAppServerWrapper AppSrvWrap4 = new() { Content = AppSrv4 }; + static readonly ModellingAppServerWrapper AppSrvWrap5 = new() { Content = AppSrv5 }; + static readonly ModellingAppServerWrapper AppSrvWrap6 = new() { Content = AppSrv6 }; + + static readonly NetworkObject NwObj1 = new() { Name = "NwObj1", IP = "1.2.3.4", IpEnd = "1.2.3.4" }; + static readonly NetworkObject NwObj2 = new() { Name = "NwObj2", IP = "1.2.3.4", IpEnd = "1.2.3.4" }; + static readonly NetworkObject NwObj3 = new() { Name = "NwObj3", IP = "1.2.3.4", IpEnd = "" }; + static readonly NetworkObject NwObj4 = new() { Name = "NwObj4", IP = "1.2.3.5", IpEnd = "1.2.3.4" }; + static readonly NetworkObject NwObj5 = new() { Name = "NwObj1", IP = "", IpEnd = "" }; + + static readonly NetworkObject NwGrp1 = new() { Name = "NwGrp1", ObjectGroupFlats = [new GroupFlat() { Object = NwObj1 }] }; + static readonly NetworkObject NwGrp2 = new() { Name = "NwGrp2", ObjectGroupFlats = [new GroupFlat() { Object = NwObj1 }] }; + static readonly NetworkObject NwGrp3 = new() { Name = "NwGrp3", ObjectGroupFlats = [new GroupFlat() { Object = NwObj2 }] }; + static readonly NetworkObject NwGrp4 = new() { Name = "NwGrp4", ObjectGroupFlats = [new GroupFlat() { Object = NwObj1 }, new GroupFlat() { Object = NwObj2 }] }; + static readonly NetworkObject NwGrp5 = new() { Name = "NwGrp1", ObjectGroupFlats = [new GroupFlat() { Object = NwObj3 }] }; + static readonly NetworkObject NwGrp6 = new() { Name = "NwGrp1", ObjectGroupFlats = [new GroupFlat() { Object = NwObj1 }, new GroupFlat() { Object = NwObj3 }] }; + + static readonly ModellingAppZone AppZone1 = new() { IdString = "AZ1", AppServers = [] }; + static readonly ModellingAppZone AppZone2 = new() { IdString = "AZ2", AppServers = [new() { Content = AppSrv1 }] }; + static readonly ModellingAppZone AppZone3 = new() { IdString = "AZ3", AppServers = [new() { Content = AppSrv1 }, new() { Content = AppSrv2 }] }; + static readonly ModellingAppZone AppZone4 = new() { IdString = "AZ3", AppServers = [new() { Content = AppSrv1 }] }; + static readonly ModellingAppZone AppZone5 = new() { IdString = "AZ3", AppServers = [new() { Content = AppSrv1 }], Comment = "comment", AppId = 3 }; + + static readonly NetworkService Svc1 = new() { Name = "Svc1", DestinationPort = 1234, DestinationPortEnd = 1235, ProtoId = 6, Protocol = new() { Id = 6, Name = "TCP" } }; + static readonly NetworkService Svc2 = new() { Name = "Svc2", DestinationPort = 1234, DestinationPortEnd = 1235, Protocol = new() { Id = 6, Name = "TCP" } }; + static readonly NetworkService Svc3 = new() { Name = "Svc3", DestinationPort = 1234, DestinationPortEnd = 1236, ProtoId = 6, Protocol = new() { Id = 6, Name = "TCP" } }; + static readonly NetworkService Svc4 = new() { Name = "Svc4", DestinationPort = 1235, DestinationPortEnd = 1235, ProtoId = 6, Protocol = new() { Id = 6, Name = "TCP" } }; + static readonly NetworkService Svc5 = new() { Name = "Svc5", DestinationPort = 1234, DestinationPortEnd = 1235, ProtoId = 12, Protocol = new() { Id = 12, Name = "PUP" } }; + static readonly NetworkService Svc6 = new() { Name = "Svc1", DestinationPort = 1, DestinationPortEnd = 1, ProtoId = 1, Protocol = new() { Id = 1, Name = "ICMP" } }; + static readonly NetworkService Svc7 = new() { Name = "Svc7", DestinationPort = 1235, DestinationPortEnd = null, ProtoId = 6, Protocol = new() { Id = 6, Name = "TCP" } }; + static readonly NetworkService Svc8 = new() { Name = "", DestinationPort = null, DestinationPortEnd = null, ProtoId = 50 }; + static readonly NetworkService Svc9 = new() { Name = "", DestinationPort = null, DestinationPortEnd = null, ProtoId = 50, Protocol = new() { Id = 50, Name = "ESP" } }; + static readonly NetworkService Svc10 = new() { Name = "", DestinationPort = null, DestinationPortEnd = null }; + + static readonly NetworkService SvcGrp1 = new() { Name = "SvcGrp1", ServiceGroupFlats = [new GroupFlat() { Object = Svc1 }] }; + static readonly NetworkService SvcGrp2 = new() { Name = "SvcGrp2", ServiceGroupFlats = [new GroupFlat() { Object = Svc1 }] }; + static readonly NetworkService SvcGrp3 = new() { Name = "SvcGrp3", ServiceGroupFlats = [new GroupFlat() { Object = Svc2 }] }; + static readonly NetworkService SvcGrp4 = new() { Name = "SvcGrp4", ServiceGroupFlats = [new GroupFlat() { Object = Svc1 }, new GroupFlat() { Object = Svc2 }] }; + static readonly NetworkService SvcGrp5 = new() { Name = "SvcGrp1", ServiceGroupFlats = [new GroupFlat() { Object = Svc3 }] }; + + + [SetUp] + public void Initialize() + { + + } + + [Test] + public void TestAppServerComparer() + { + ModellingNamingConvention namingConvention = new() + { + // NetworkAreaRequired = false, + // UseAppPart = false, + // FixedPartLength = 0, + // FreePartLength = 0, + // NetworkAreaPattern = "", + // AppRolePattern = "", + // AppZone = "", + AppServerPrefix = "", + NetworkPrefix = "", + IpRangePrefix = "" + }; + AppServerComparer appServerComparer = new(namingConvention); + + ClassicAssert.AreEqual(true, appServerComparer.Equals(AppSrv1, AppSrv1)); + ClassicAssert.AreEqual(false, appServerComparer.Equals(AppSrv1, AppSrv2)); + ClassicAssert.AreEqual(false, appServerComparer.Equals(AppSrv1, AppSrv3)); + ClassicAssert.AreEqual(true, appServerComparer.Equals(AppSrv1, AppSrv4)); + ClassicAssert.AreEqual(true, appServerComparer.Equals(AppSrv1, AppSrv5)); + ClassicAssert.AreEqual(true, appServerComparer.Equals(AppSrv1, AppSrv6)); + ClassicAssert.AreEqual(true, appServerComparer.GetHashCode(AppSrv1) == appServerComparer.GetHashCode(AppSrv1)); + ClassicAssert.AreEqual(false, appServerComparer.GetHashCode(AppSrv1) == appServerComparer.GetHashCode(AppSrv2)); + ClassicAssert.AreEqual(false, appServerComparer.GetHashCode(AppSrv1) == appServerComparer.GetHashCode(AppSrv3)); + ClassicAssert.AreEqual(true, appServerComparer.GetHashCode(AppSrv1) == appServerComparer.GetHashCode(AppSrv4)); + ClassicAssert.AreEqual(true, appServerComparer.GetHashCode(AppSrv1) == appServerComparer.GetHashCode(AppSrv5)); + ClassicAssert.AreEqual(true, appServerComparer.GetHashCode(AppSrv1) == appServerComparer.GetHashCode(AppSrv6)); + ClassicAssert.AreEqual(true, appServerComparer.Equals(AppSrvWrap1, AppSrvWrap1)); + ClassicAssert.AreEqual(false, appServerComparer.Equals(AppSrvWrap1, AppSrvWrap2)); + ClassicAssert.AreEqual(false, appServerComparer.Equals(AppSrvWrap1, AppSrvWrap3)); + ClassicAssert.AreEqual(true, appServerComparer.Equals(AppSrvWrap1, AppSrvWrap4)); + ClassicAssert.AreEqual(true, appServerComparer.Equals(AppSrvWrap1, AppSrvWrap5)); + ClassicAssert.AreEqual(true, appServerComparer.Equals(AppSrvWrap1, AppSrvWrap6)); + ClassicAssert.AreEqual(true, appServerComparer.GetHashCode(AppSrvWrap1) == appServerComparer.GetHashCode(AppSrvWrap1)); + ClassicAssert.AreEqual(false, appServerComparer.GetHashCode(AppSrvWrap1) == appServerComparer.GetHashCode(AppSrvWrap2)); + ClassicAssert.AreEqual(false, appServerComparer.GetHashCode(AppSrvWrap1) == appServerComparer.GetHashCode(AppSrvWrap3)); + ClassicAssert.AreEqual(true, appServerComparer.GetHashCode(AppSrvWrap1) == appServerComparer.GetHashCode(AppSrvWrap4)); + ClassicAssert.AreEqual(true, appServerComparer.GetHashCode(AppSrvWrap1) == appServerComparer.GetHashCode(AppSrvWrap5)); + ClassicAssert.AreEqual(true, appServerComparer.GetHashCode(AppSrvWrap1) == appServerComparer.GetHashCode(AppSrvWrap6)); + + namingConvention.AppServerPrefix = "host_"; + namingConvention.NetworkPrefix = "net_"; + namingConvention.IpRangePrefix = "range_"; + appServerComparer = new(namingConvention); + + ClassicAssert.AreEqual(true, appServerComparer.Equals(AppSrv1, AppSrv1)); + ClassicAssert.AreEqual(false, appServerComparer.Equals(AppSrv1, AppSrv2)); + ClassicAssert.AreEqual(false, appServerComparer.Equals(AppSrv1, AppSrv3)); + ClassicAssert.AreEqual(true, appServerComparer.Equals(AppSrv1, AppSrv4)); + ClassicAssert.AreEqual(true, appServerComparer.Equals(AppSrv1, AppSrv5)); + ClassicAssert.AreEqual(true, appServerComparer.Equals(AppSrv1, AppSrv6)); + ClassicAssert.AreEqual(true, appServerComparer.GetHashCode(AppSrv1) == appServerComparer.GetHashCode(AppSrv1)); + ClassicAssert.AreEqual(false, appServerComparer.GetHashCode(AppSrv1) == appServerComparer.GetHashCode(AppSrv2)); + ClassicAssert.AreEqual(false, appServerComparer.GetHashCode(AppSrv1) == appServerComparer.GetHashCode(AppSrv3)); + ClassicAssert.AreEqual(true, appServerComparer.GetHashCode(AppSrv1) == appServerComparer.GetHashCode(AppSrv4)); + ClassicAssert.AreEqual(true, appServerComparer.GetHashCode(AppSrv1) == appServerComparer.GetHashCode(AppSrv5)); + ClassicAssert.AreEqual(true, appServerComparer.GetHashCode(AppSrv1) == appServerComparer.GetHashCode(AppSrv6)); + ClassicAssert.AreEqual(true, appServerComparer.Equals(AppSrvWrap1, AppSrvWrap1)); + ClassicAssert.AreEqual(false, appServerComparer.Equals(AppSrvWrap1, AppSrvWrap2)); + ClassicAssert.AreEqual(false, appServerComparer.Equals(AppSrvWrap1, AppSrvWrap3)); + ClassicAssert.AreEqual(true, appServerComparer.Equals(AppSrvWrap1, AppSrvWrap4)); + ClassicAssert.AreEqual(true, appServerComparer.Equals(AppSrvWrap1, AppSrvWrap5)); + ClassicAssert.AreEqual(true, appServerComparer.Equals(AppSrvWrap1, AppSrvWrap6)); + ClassicAssert.AreEqual(true, appServerComparer.GetHashCode(AppSrvWrap1) == appServerComparer.GetHashCode(AppSrvWrap1)); + ClassicAssert.AreEqual(false, appServerComparer.GetHashCode(AppSrvWrap1) == appServerComparer.GetHashCode(AppSrvWrap2)); + ClassicAssert.AreEqual(false, appServerComparer.GetHashCode(AppSrvWrap1) == appServerComparer.GetHashCode(AppSrvWrap3)); + ClassicAssert.AreEqual(true, appServerComparer.GetHashCode(AppSrvWrap1) == appServerComparer.GetHashCode(AppSrvWrap4)); + ClassicAssert.AreEqual(true, appServerComparer.GetHashCode(AppSrvWrap1) == appServerComparer.GetHashCode(AppSrvWrap5)); + ClassicAssert.AreEqual(true, appServerComparer.GetHashCode(AppSrvWrap1) == appServerComparer.GetHashCode(AppSrvWrap6)); + } + + [Test] + public void TestAppRoleComparer() + { + AppRoleComparer appRoleComparer = new(); + + ClassicAssert.AreEqual(true, appRoleComparer.Equals(AppRole1, AppRole1)); + ClassicAssert.AreEqual(false, appRoleComparer.Equals(AppRole1, AppRole2)); + ClassicAssert.AreEqual(true, appRoleComparer.GetHashCode(AppRole1) == appRoleComparer.GetHashCode(AppRole1)); + ClassicAssert.AreEqual(false, appRoleComparer.GetHashCode(AppRole1) == appRoleComparer.GetHashCode(AppRole2)); + } + + [Test] + public void TestNetworkObjectComparer() + { + RuleRecognitionOption ruleRecognitionOption = new() + { + NwRegardIp = true, + NwRegardName = false, + // NwRegardGroupName = false, + // NwResolveGroup = false, + // NwSeparateGroupAnalysis = true, + // SvcRegardPortAndProt = true, + // SvcRegardName = false, + // SvcRegardGroupName = false, + // SvcResolveGroup = false + }; + NetworkObjectComparer networkObjectComparer = new(ruleRecognitionOption); + + ClassicAssert.AreEqual(true, networkObjectComparer.Equals(NwObj1, NwObj1)); + ClassicAssert.AreEqual(true, networkObjectComparer.Equals(NwObj1, NwObj2)); + ClassicAssert.AreEqual(false, networkObjectComparer.Equals(NwObj1, NwObj3)); + ClassicAssert.AreEqual(false, networkObjectComparer.Equals(NwObj1, NwObj4)); + ClassicAssert.AreEqual(false, networkObjectComparer.Equals(NwObj1, NwObj5)); + ClassicAssert.AreEqual(true, networkObjectComparer.GetHashCode(NwObj1) == networkObjectComparer.GetHashCode(NwObj1)); + ClassicAssert.AreEqual(true, networkObjectComparer.GetHashCode(NwObj1) == networkObjectComparer.GetHashCode(NwObj2)); + ClassicAssert.AreEqual(false, networkObjectComparer.GetHashCode(NwObj1) == networkObjectComparer.GetHashCode(NwObj3)); + ClassicAssert.AreEqual(false, networkObjectComparer.GetHashCode(NwObj1) == networkObjectComparer.GetHashCode(NwObj4)); + ClassicAssert.AreEqual(false, networkObjectComparer.GetHashCode(NwObj1) == networkObjectComparer.GetHashCode(NwObj5)); + + ruleRecognitionOption.NwRegardName = true; + networkObjectComparer = new(ruleRecognitionOption); + + ClassicAssert.AreEqual(true, networkObjectComparer.Equals(NwObj1, NwObj1)); + ClassicAssert.AreEqual(false, networkObjectComparer.Equals(NwObj1, NwObj2)); + ClassicAssert.AreEqual(false, networkObjectComparer.Equals(NwObj1, NwObj3)); + ClassicAssert.AreEqual(false, networkObjectComparer.Equals(NwObj1, NwObj4)); + ClassicAssert.AreEqual(false, networkObjectComparer.Equals(NwObj1, NwObj5)); + ClassicAssert.AreEqual(true, networkObjectComparer.GetHashCode(NwObj1) == networkObjectComparer.GetHashCode(NwObj1)); + ClassicAssert.AreEqual(false, networkObjectComparer.GetHashCode(NwObj1) == networkObjectComparer.GetHashCode(NwObj2)); + ClassicAssert.AreEqual(false, networkObjectComparer.GetHashCode(NwObj1) == networkObjectComparer.GetHashCode(NwObj3)); + ClassicAssert.AreEqual(false, networkObjectComparer.GetHashCode(NwObj1) == networkObjectComparer.GetHashCode(NwObj4)); + ClassicAssert.AreEqual(false, networkObjectComparer.GetHashCode(NwObj1) == networkObjectComparer.GetHashCode(NwObj5)); + + ruleRecognitionOption.NwRegardIp = false; + networkObjectComparer = new(ruleRecognitionOption); + + ClassicAssert.AreEqual(true, networkObjectComparer.Equals(NwObj1, NwObj1)); + ClassicAssert.AreEqual(false, networkObjectComparer.Equals(NwObj1, NwObj2)); + ClassicAssert.AreEqual(false, networkObjectComparer.Equals(NwObj1, NwObj3)); + ClassicAssert.AreEqual(false, networkObjectComparer.Equals(NwObj1, NwObj4)); + ClassicAssert.AreEqual(true, networkObjectComparer.Equals(NwObj1, NwObj5)); + ClassicAssert.AreEqual(true, networkObjectComparer.GetHashCode(NwObj1) == networkObjectComparer.GetHashCode(NwObj1)); + ClassicAssert.AreEqual(false, networkObjectComparer.GetHashCode(NwObj1) == networkObjectComparer.GetHashCode(NwObj2)); + ClassicAssert.AreEqual(false, networkObjectComparer.GetHashCode(NwObj1) == networkObjectComparer.GetHashCode(NwObj3)); + ClassicAssert.AreEqual(false, networkObjectComparer.GetHashCode(NwObj1) == networkObjectComparer.GetHashCode(NwObj4)); + ClassicAssert.AreEqual(true, networkObjectComparer.GetHashCode(NwObj1) == networkObjectComparer.GetHashCode(NwObj5)); + } + + [Test] + public void TestNetworkObjectGroupComparer() + { + RuleRecognitionOption ruleRecognitionOption = new() + { + NwRegardIp = true, + NwRegardName = false, + NwRegardGroupName = false, + // NwResolveGroup = false, + NwSeparateGroupAnalysis = true, + // SvcRegardPortAndProt = true, + // SvcRegardName = false, + // SvcRegardGroupName = false, + // SvcResolveGroup = false + }; + NetworkObjectGroupFlatComparer networkObjectGroupComparer = new(ruleRecognitionOption); + + ClassicAssert.AreEqual(true, networkObjectGroupComparer.Equals(NwGrp1, NwGrp1)); + ClassicAssert.AreEqual(true, networkObjectGroupComparer.Equals(NwGrp1, NwGrp2)); + ClassicAssert.AreEqual(true, networkObjectGroupComparer.Equals(NwGrp1, NwGrp3)); + ClassicAssert.AreEqual(true, networkObjectGroupComparer.Equals(NwGrp1, NwGrp4)); + ClassicAssert.AreEqual(true, networkObjectGroupComparer.Equals(NwGrp1, NwGrp5)); + ClassicAssert.AreEqual(true, networkObjectGroupComparer.Equals(NwGrp1, NwGrp6)); + ClassicAssert.AreEqual(true, networkObjectGroupComparer.GetHashCode(NwGrp1) == networkObjectGroupComparer.GetHashCode(NwGrp1)); + ClassicAssert.AreEqual(true, networkObjectGroupComparer.GetHashCode(NwGrp1) == networkObjectGroupComparer.GetHashCode(NwGrp2)); + ClassicAssert.AreEqual(true, networkObjectGroupComparer.GetHashCode(NwGrp1) == networkObjectGroupComparer.GetHashCode(NwGrp3)); + ClassicAssert.AreEqual(true, networkObjectGroupComparer.GetHashCode(NwGrp1) == networkObjectGroupComparer.GetHashCode(NwGrp4)); + ClassicAssert.AreEqual(true, networkObjectGroupComparer.GetHashCode(NwGrp1) == networkObjectGroupComparer.GetHashCode(NwGrp5)); + ClassicAssert.AreEqual(true, networkObjectGroupComparer.GetHashCode(NwGrp1) == networkObjectGroupComparer.GetHashCode(NwGrp6)); + + ruleRecognitionOption.NwRegardName = true; + networkObjectGroupComparer = new(ruleRecognitionOption); + + ClassicAssert.AreEqual(true, networkObjectGroupComparer.Equals(NwGrp1, NwGrp1)); + ClassicAssert.AreEqual(true, networkObjectGroupComparer.Equals(NwGrp1, NwGrp2)); + ClassicAssert.AreEqual(true, networkObjectGroupComparer.Equals(NwGrp1, NwGrp3)); + ClassicAssert.AreEqual(true, networkObjectGroupComparer.Equals(NwGrp1, NwGrp4)); + ClassicAssert.AreEqual(true, networkObjectGroupComparer.Equals(NwGrp1, NwGrp5)); + ClassicAssert.AreEqual(true, networkObjectGroupComparer.Equals(NwGrp1, NwGrp6)); + ClassicAssert.AreEqual(true, networkObjectGroupComparer.GetHashCode(NwGrp1) == networkObjectGroupComparer.GetHashCode(NwGrp1)); + ClassicAssert.AreEqual(true, networkObjectGroupComparer.GetHashCode(NwGrp1) == networkObjectGroupComparer.GetHashCode(NwGrp2)); + ClassicAssert.AreEqual(true, networkObjectGroupComparer.GetHashCode(NwGrp1) == networkObjectGroupComparer.GetHashCode(NwGrp3)); + ClassicAssert.AreEqual(true, networkObjectGroupComparer.GetHashCode(NwGrp1) == networkObjectGroupComparer.GetHashCode(NwGrp4)); + ClassicAssert.AreEqual(true, networkObjectGroupComparer.GetHashCode(NwGrp1) == networkObjectGroupComparer.GetHashCode(NwGrp5)); + ClassicAssert.AreEqual(true, networkObjectGroupComparer.GetHashCode(NwGrp1) == networkObjectGroupComparer.GetHashCode(NwGrp6)); + + ruleRecognitionOption.NwRegardGroupName = true; + networkObjectGroupComparer = new(ruleRecognitionOption); + + ClassicAssert.AreEqual(true, networkObjectGroupComparer.Equals(NwGrp1, NwGrp1)); + ClassicAssert.AreEqual(false, networkObjectGroupComparer.Equals(NwGrp1, NwGrp2)); + ClassicAssert.AreEqual(false, networkObjectGroupComparer.Equals(NwGrp1, NwGrp3)); + ClassicAssert.AreEqual(false, networkObjectGroupComparer.Equals(NwGrp1, NwGrp4)); + ClassicAssert.AreEqual(true, networkObjectGroupComparer.Equals(NwGrp1, NwGrp5)); + ClassicAssert.AreEqual(true, networkObjectGroupComparer.Equals(NwGrp1, NwGrp6)); + ClassicAssert.AreEqual(true, networkObjectGroupComparer.GetHashCode(NwGrp1) == networkObjectGroupComparer.GetHashCode(NwGrp1)); + ClassicAssert.AreEqual(false, networkObjectGroupComparer.GetHashCode(NwGrp1) == networkObjectGroupComparer.GetHashCode(NwGrp2)); + ClassicAssert.AreEqual(false, networkObjectGroupComparer.GetHashCode(NwGrp1) == networkObjectGroupComparer.GetHashCode(NwGrp3)); + ClassicAssert.AreEqual(false, networkObjectGroupComparer.GetHashCode(NwGrp1) == networkObjectGroupComparer.GetHashCode(NwGrp4)); + ClassicAssert.AreEqual(true, networkObjectGroupComparer.GetHashCode(NwGrp1) == networkObjectGroupComparer.GetHashCode(NwGrp5)); + ClassicAssert.AreEqual(true, networkObjectGroupComparer.GetHashCode(NwGrp1) == networkObjectGroupComparer.GetHashCode(NwGrp6)); + + ruleRecognitionOption.NwSeparateGroupAnalysis = false; + networkObjectGroupComparer = new(ruleRecognitionOption); + + ClassicAssert.AreEqual(true, networkObjectGroupComparer.Equals(NwGrp1, NwGrp1)); + ClassicAssert.AreEqual(false, networkObjectGroupComparer.Equals(NwGrp1, NwGrp2)); + ClassicAssert.AreEqual(false, networkObjectGroupComparer.Equals(NwGrp1, NwGrp3)); + ClassicAssert.AreEqual(false, networkObjectGroupComparer.Equals(NwGrp1, NwGrp4)); + ClassicAssert.AreEqual(false, networkObjectGroupComparer.Equals(NwGrp1, NwGrp5)); + ClassicAssert.AreEqual(false, networkObjectGroupComparer.Equals(NwGrp1, NwGrp6)); + ClassicAssert.AreEqual(true, networkObjectGroupComparer.GetHashCode(NwGrp1) == networkObjectGroupComparer.GetHashCode(NwGrp1)); + ClassicAssert.AreEqual(false, networkObjectGroupComparer.GetHashCode(NwGrp1) == networkObjectGroupComparer.GetHashCode(NwGrp2)); + ClassicAssert.AreEqual(false, networkObjectGroupComparer.GetHashCode(NwGrp1) == networkObjectGroupComparer.GetHashCode(NwGrp3)); + ClassicAssert.AreEqual(false, networkObjectGroupComparer.GetHashCode(NwGrp1) == networkObjectGroupComparer.GetHashCode(NwGrp4)); + ClassicAssert.AreEqual(false, networkObjectGroupComparer.GetHashCode(NwGrp1) == networkObjectGroupComparer.GetHashCode(NwGrp5)); + ClassicAssert.AreEqual(false, networkObjectGroupComparer.GetHashCode(NwGrp1) == networkObjectGroupComparer.GetHashCode(NwGrp6)); + + ruleRecognitionOption.NwRegardGroupName = false; + networkObjectGroupComparer = new(ruleRecognitionOption); + + ClassicAssert.AreEqual(true, networkObjectGroupComparer.Equals(NwGrp1, NwGrp1)); + ClassicAssert.AreEqual(true, networkObjectGroupComparer.Equals(NwGrp1, NwGrp2)); + ClassicAssert.AreEqual(false, networkObjectGroupComparer.Equals(NwGrp1, NwGrp3)); + ClassicAssert.AreEqual(false, networkObjectGroupComparer.Equals(NwGrp1, NwGrp4)); + ClassicAssert.AreEqual(false, networkObjectGroupComparer.Equals(NwGrp1, NwGrp5)); + ClassicAssert.AreEqual(false, networkObjectGroupComparer.Equals(NwGrp1, NwGrp6)); + ClassicAssert.AreEqual(true, networkObjectGroupComparer.GetHashCode(NwGrp1) == networkObjectGroupComparer.GetHashCode(NwGrp1)); + ClassicAssert.AreEqual(true, networkObjectGroupComparer.GetHashCode(NwGrp1) == networkObjectGroupComparer.GetHashCode(NwGrp2)); + ClassicAssert.AreEqual(false, networkObjectGroupComparer.GetHashCode(NwGrp1) == networkObjectGroupComparer.GetHashCode(NwGrp3)); + ClassicAssert.AreEqual(false, networkObjectGroupComparer.GetHashCode(NwGrp1) == networkObjectGroupComparer.GetHashCode(NwGrp4)); + ClassicAssert.AreEqual(false, networkObjectGroupComparer.GetHashCode(NwGrp1) == networkObjectGroupComparer.GetHashCode(NwGrp5)); + ClassicAssert.AreEqual(false, networkObjectGroupComparer.GetHashCode(NwGrp1) == networkObjectGroupComparer.GetHashCode(NwGrp6)); + + ruleRecognitionOption.NwRegardName = false; + networkObjectGroupComparer = new(ruleRecognitionOption); + + ClassicAssert.AreEqual(true, networkObjectGroupComparer.Equals(NwGrp1, NwGrp1)); + ClassicAssert.AreEqual(true, networkObjectGroupComparer.Equals(NwGrp1, NwGrp2)); + ClassicAssert.AreEqual(true, networkObjectGroupComparer.Equals(NwGrp1, NwGrp3)); + ClassicAssert.AreEqual(false, networkObjectGroupComparer.Equals(NwGrp1, NwGrp4)); + ClassicAssert.AreEqual(false, networkObjectGroupComparer.Equals(NwGrp1, NwGrp5)); + ClassicAssert.AreEqual(false, networkObjectGroupComparer.Equals(NwGrp1, NwGrp6)); + ClassicAssert.AreEqual(true, networkObjectGroupComparer.GetHashCode(NwGrp1) == networkObjectGroupComparer.GetHashCode(NwGrp1)); + ClassicAssert.AreEqual(true, networkObjectGroupComparer.GetHashCode(NwGrp1) == networkObjectGroupComparer.GetHashCode(NwGrp2)); + ClassicAssert.AreEqual(true, networkObjectGroupComparer.GetHashCode(NwGrp1) == networkObjectGroupComparer.GetHashCode(NwGrp3)); + ClassicAssert.AreEqual(false, networkObjectGroupComparer.GetHashCode(NwGrp1) == networkObjectGroupComparer.GetHashCode(NwGrp4)); + ClassicAssert.AreEqual(false, networkObjectGroupComparer.GetHashCode(NwGrp1) == networkObjectGroupComparer.GetHashCode(NwGrp5)); + ClassicAssert.AreEqual(false, networkObjectGroupComparer.GetHashCode(NwGrp1) == networkObjectGroupComparer.GetHashCode(NwGrp6)); + } + + [Test] + public void TestAppZoneComparer() + { + ModellingNamingConvention namingConvention = new() + { + AppZone = "AZ" + }; + AppZoneComparer appZoneComparer = new(namingConvention); + + ClassicAssert.AreEqual(true, appZoneComparer.Equals(AppZone1, AppZone1)); + ClassicAssert.AreEqual(false, appZoneComparer.Equals(AppZone1, AppZone2)); + ClassicAssert.AreEqual(false, appZoneComparer.Equals(AppZone1, AppZone3)); + ClassicAssert.AreEqual(false, appZoneComparer.Equals(AppZone1, AppZone4)); + ClassicAssert.AreEqual(true, appZoneComparer.Equals(AppZone2, AppZone2)); + ClassicAssert.AreEqual(false, appZoneComparer.Equals(AppZone2, AppZone3)); + ClassicAssert.AreEqual(false, appZoneComparer.Equals(AppZone2, AppZone4)); + ClassicAssert.AreEqual(false, appZoneComparer.Equals(AppZone3, AppZone4)); + ClassicAssert.AreEqual(true, appZoneComparer.Equals(AppZone4, AppZone5)); + + ClassicAssert.AreEqual(true, appZoneComparer.GetHashCode(AppZone1) == appZoneComparer.GetHashCode(AppZone1)); + ClassicAssert.AreEqual(false, appZoneComparer.GetHashCode(AppZone1) == appZoneComparer.GetHashCode(AppZone2)); + ClassicAssert.AreEqual(false, appZoneComparer.GetHashCode(AppZone1) == appZoneComparer.GetHashCode(AppZone3)); + ClassicAssert.AreEqual(false, appZoneComparer.GetHashCode(AppZone1) == appZoneComparer.GetHashCode(AppZone4)); + ClassicAssert.AreEqual(true, appZoneComparer.GetHashCode(AppZone2) == appZoneComparer.GetHashCode(AppZone2)); + ClassicAssert.AreEqual(false, appZoneComparer.GetHashCode(AppZone2) == appZoneComparer.GetHashCode(AppZone3)); + ClassicAssert.AreEqual(false, appZoneComparer.GetHashCode(AppZone2) == appZoneComparer.GetHashCode(AppZone4)); + ClassicAssert.AreEqual(false, appZoneComparer.GetHashCode(AppZone3) == appZoneComparer.GetHashCode(AppZone4)); + ClassicAssert.AreEqual(true, appZoneComparer.GetHashCode(AppZone4) == appZoneComparer.GetHashCode(AppZone5)); + } + + [Test] + public void TestNetworkServiceComparer() + { + RuleRecognitionOption ruleRecognitionOption = new() + { + // NwRegardIp = true, + // NwRegardName = false, + // NwRegardGroupName = false, + // NwResolveGroup = false, + // NwSeparateGroupAnalysis = true, + SvcRegardPortAndProt = true, + SvcRegardName = false, + // SvcRegardGroupName = false, + // SvcResolveGroup = false + }; + NetworkServiceComparer networkServiceComparer = new(ruleRecognitionOption); + + ClassicAssert.AreEqual(true, networkServiceComparer.Equals(Svc1, Svc1)); + ClassicAssert.AreEqual(true, networkServiceComparer.Equals(Svc1, Svc2)); + ClassicAssert.AreEqual(false, networkServiceComparer.Equals(Svc1, Svc3)); + ClassicAssert.AreEqual(false, networkServiceComparer.Equals(Svc1, Svc4)); + ClassicAssert.AreEqual(false, networkServiceComparer.Equals(Svc1, Svc5)); + ClassicAssert.AreEqual(false, networkServiceComparer.Equals(Svc1, Svc6)); + ClassicAssert.AreEqual(true, networkServiceComparer.Equals(Svc4, Svc7)); + ClassicAssert.AreEqual(false, networkServiceComparer.Equals(Svc1, Svc9)); + ClassicAssert.AreEqual(false, networkServiceComparer.Equals(Svc5, Svc9)); + ClassicAssert.AreEqual(true, networkServiceComparer.Equals(Svc8, Svc9)); + ClassicAssert.AreEqual(false, networkServiceComparer.Equals(Svc8, Svc10)); + ClassicAssert.AreEqual(true, networkServiceComparer.GetHashCode(Svc1) == networkServiceComparer.GetHashCode(Svc1)); + ClassicAssert.AreEqual(true, networkServiceComparer.GetHashCode(Svc1) == networkServiceComparer.GetHashCode(Svc2)); + ClassicAssert.AreEqual(false, networkServiceComparer.GetHashCode(Svc1) == networkServiceComparer.GetHashCode(Svc3)); + ClassicAssert.AreEqual(false, networkServiceComparer.GetHashCode(Svc1) == networkServiceComparer.GetHashCode(Svc4)); + ClassicAssert.AreEqual(false, networkServiceComparer.GetHashCode(Svc1) == networkServiceComparer.GetHashCode(Svc5)); + ClassicAssert.AreEqual(false, networkServiceComparer.GetHashCode(Svc1) == networkServiceComparer.GetHashCode(Svc6)); + ClassicAssert.AreEqual(true, networkServiceComparer.GetHashCode(Svc4) == networkServiceComparer.GetHashCode(Svc7)); + ClassicAssert.AreEqual(false, networkServiceComparer.GetHashCode(Svc1) == networkServiceComparer.GetHashCode(Svc9)); + ClassicAssert.AreEqual(false, networkServiceComparer.GetHashCode(Svc5) == networkServiceComparer.GetHashCode(Svc9)); + ClassicAssert.AreEqual(true, networkServiceComparer.GetHashCode(Svc8) == networkServiceComparer.GetHashCode(Svc9)); + ClassicAssert.AreEqual(false, networkServiceComparer.GetHashCode(Svc8) == networkServiceComparer.GetHashCode(Svc10)); + + ruleRecognitionOption.SvcRegardName = true; + networkServiceComparer = new(ruleRecognitionOption); + + ClassicAssert.AreEqual(true, networkServiceComparer.Equals(Svc1, Svc1)); + ClassicAssert.AreEqual(false, networkServiceComparer.Equals(Svc1, Svc2)); + ClassicAssert.AreEqual(false, networkServiceComparer.Equals(Svc1, Svc3)); + ClassicAssert.AreEqual(false, networkServiceComparer.Equals(Svc1, Svc4)); + ClassicAssert.AreEqual(false, networkServiceComparer.Equals(Svc1, Svc5)); + ClassicAssert.AreEqual(false, networkServiceComparer.Equals(Svc1, Svc6)); + ClassicAssert.AreEqual(false, networkServiceComparer.Equals(Svc1, Svc9)); + ClassicAssert.AreEqual(false, networkServiceComparer.Equals(Svc5, Svc9)); + ClassicAssert.AreEqual(true, networkServiceComparer.Equals(Svc8, Svc9)); + ClassicAssert.AreEqual(false, networkServiceComparer.Equals(Svc8, Svc10)); + ClassicAssert.AreEqual(true, networkServiceComparer.GetHashCode(Svc1) == networkServiceComparer.GetHashCode(Svc1)); + ClassicAssert.AreEqual(false, networkServiceComparer.GetHashCode(Svc1) == networkServiceComparer.GetHashCode(Svc2)); + ClassicAssert.AreEqual(false, networkServiceComparer.GetHashCode(Svc1) == networkServiceComparer.GetHashCode(Svc3)); + ClassicAssert.AreEqual(false, networkServiceComparer.GetHashCode(Svc1) == networkServiceComparer.GetHashCode(Svc4)); + ClassicAssert.AreEqual(false, networkServiceComparer.GetHashCode(Svc1) == networkServiceComparer.GetHashCode(Svc5)); + ClassicAssert.AreEqual(false, networkServiceComparer.GetHashCode(Svc1) == networkServiceComparer.GetHashCode(Svc6)); + ClassicAssert.AreEqual(false, networkServiceComparer.GetHashCode(Svc1) == networkServiceComparer.GetHashCode(Svc9)); + ClassicAssert.AreEqual(false, networkServiceComparer.GetHashCode(Svc5) == networkServiceComparer.GetHashCode(Svc9)); + ClassicAssert.AreEqual(true, networkServiceComparer.GetHashCode(Svc8) == networkServiceComparer.GetHashCode(Svc9)); + ClassicAssert.AreEqual(false, networkServiceComparer.GetHashCode(Svc8) == networkServiceComparer.GetHashCode(Svc10)); + + ruleRecognitionOption.SvcRegardPortAndProt = false; + networkServiceComparer = new(ruleRecognitionOption); + + ClassicAssert.AreEqual(true, networkServiceComparer.Equals(Svc1, Svc1)); + ClassicAssert.AreEqual(false, networkServiceComparer.Equals(Svc1, Svc2)); + ClassicAssert.AreEqual(false, networkServiceComparer.Equals(Svc1, Svc3)); + ClassicAssert.AreEqual(false, networkServiceComparer.Equals(Svc1, Svc4)); + ClassicAssert.AreEqual(false, networkServiceComparer.Equals(Svc1, Svc5)); + ClassicAssert.AreEqual(true, networkServiceComparer.Equals(Svc1, Svc6)); + ClassicAssert.AreEqual(false, networkServiceComparer.Equals(Svc1, Svc9)); + ClassicAssert.AreEqual(false, networkServiceComparer.Equals(Svc5, Svc9)); + ClassicAssert.AreEqual(true, networkServiceComparer.Equals(Svc8, Svc9)); + ClassicAssert.AreEqual(true, networkServiceComparer.Equals(Svc8, Svc10)); + ClassicAssert.AreEqual(true, networkServiceComparer.GetHashCode(Svc1) == networkServiceComparer.GetHashCode(Svc1)); + ClassicAssert.AreEqual(false, networkServiceComparer.GetHashCode(Svc1) == networkServiceComparer.GetHashCode(Svc2)); + ClassicAssert.AreEqual(false, networkServiceComparer.GetHashCode(Svc1) == networkServiceComparer.GetHashCode(Svc3)); + ClassicAssert.AreEqual(false, networkServiceComparer.GetHashCode(Svc1) == networkServiceComparer.GetHashCode(Svc4)); + ClassicAssert.AreEqual(false, networkServiceComparer.GetHashCode(Svc1) == networkServiceComparer.GetHashCode(Svc5)); + ClassicAssert.AreEqual(true, networkServiceComparer.GetHashCode(Svc1) == networkServiceComparer.GetHashCode(Svc6)); + ClassicAssert.AreEqual(false, networkServiceComparer.GetHashCode(Svc1) == networkServiceComparer.GetHashCode(Svc9)); + ClassicAssert.AreEqual(false, networkServiceComparer.GetHashCode(Svc5) == networkServiceComparer.GetHashCode(Svc9)); + ClassicAssert.AreEqual(true, networkServiceComparer.GetHashCode(Svc8) == networkServiceComparer.GetHashCode(Svc9)); + ClassicAssert.AreEqual(true, networkServiceComparer.GetHashCode(Svc8) == networkServiceComparer.GetHashCode(Svc10)); + } + + [Test] + public void TestNetworkServiceGroupComparer() + { + RuleRecognitionOption ruleRecognitionOption = new() + { + // NwRegardIp = true, + // NwRegardName = false, + // NwRegardGroupName = false, + // NwResolveGroup = false, + // NwSeparateGroupAnalysis = true, + SvcRegardPortAndProt = true, + SvcRegardName = false, + SvcRegardGroupName = false, + // SvcResolveGroup = false + }; + NetworkServiceGroupComparer networkServiceGroupComparer = new(ruleRecognitionOption); + + ClassicAssert.AreEqual(true, networkServiceGroupComparer.Equals(SvcGrp1, SvcGrp1)); + ClassicAssert.AreEqual(true, networkServiceGroupComparer.Equals(SvcGrp1, SvcGrp2)); + ClassicAssert.AreEqual(true, networkServiceGroupComparer.Equals(SvcGrp1, SvcGrp3)); + ClassicAssert.AreEqual(false, networkServiceGroupComparer.Equals(SvcGrp1, SvcGrp4)); + ClassicAssert.AreEqual(false, networkServiceGroupComparer.Equals(SvcGrp1, SvcGrp5)); + ClassicAssert.AreEqual(true, networkServiceGroupComparer.GetHashCode(SvcGrp1) == networkServiceGroupComparer.GetHashCode(SvcGrp1)); + ClassicAssert.AreEqual(true, networkServiceGroupComparer.GetHashCode(SvcGrp1) == networkServiceGroupComparer.GetHashCode(SvcGrp2)); + ClassicAssert.AreEqual(true, networkServiceGroupComparer.GetHashCode(SvcGrp1) == networkServiceGroupComparer.GetHashCode(SvcGrp3)); + ClassicAssert.AreEqual(false, networkServiceGroupComparer.GetHashCode(SvcGrp1) == networkServiceGroupComparer.GetHashCode(SvcGrp4)); + ClassicAssert.AreEqual(false, networkServiceGroupComparer.GetHashCode(SvcGrp1) == networkServiceGroupComparer.GetHashCode(SvcGrp5)); + + ruleRecognitionOption.SvcRegardName = true; + networkServiceGroupComparer = new(ruleRecognitionOption); + + ClassicAssert.AreEqual(true, networkServiceGroupComparer.Equals(SvcGrp1, SvcGrp1)); + ClassicAssert.AreEqual(true, networkServiceGroupComparer.Equals(SvcGrp1, SvcGrp2)); + ClassicAssert.AreEqual(false, networkServiceGroupComparer.Equals(SvcGrp1, SvcGrp3)); + ClassicAssert.AreEqual(false, networkServiceGroupComparer.Equals(SvcGrp1, SvcGrp4)); + ClassicAssert.AreEqual(false, networkServiceGroupComparer.Equals(SvcGrp1, SvcGrp5)); + ClassicAssert.AreEqual(true, networkServiceGroupComparer.GetHashCode(SvcGrp1) == networkServiceGroupComparer.GetHashCode(SvcGrp1)); + ClassicAssert.AreEqual(true, networkServiceGroupComparer.GetHashCode(SvcGrp1) == networkServiceGroupComparer.GetHashCode(SvcGrp2)); + ClassicAssert.AreEqual(false, networkServiceGroupComparer.GetHashCode(SvcGrp1) == networkServiceGroupComparer.GetHashCode(SvcGrp3)); + ClassicAssert.AreEqual(false, networkServiceGroupComparer.GetHashCode(SvcGrp1) == networkServiceGroupComparer.GetHashCode(SvcGrp4)); + ClassicAssert.AreEqual(false, networkServiceGroupComparer.GetHashCode(SvcGrp1) == networkServiceGroupComparer.GetHashCode(SvcGrp5)); + + ruleRecognitionOption.SvcRegardGroupName = true; + networkServiceGroupComparer = new(ruleRecognitionOption); + + ClassicAssert.AreEqual(true, networkServiceGroupComparer.Equals(SvcGrp1, SvcGrp1)); + ClassicAssert.AreEqual(false, networkServiceGroupComparer.Equals(SvcGrp1, SvcGrp2)); + ClassicAssert.AreEqual(false, networkServiceGroupComparer.Equals(SvcGrp1, SvcGrp3)); + ClassicAssert.AreEqual(false, networkServiceGroupComparer.Equals(SvcGrp1, SvcGrp4)); + ClassicAssert.AreEqual(false, networkServiceGroupComparer.Equals(SvcGrp1, SvcGrp5)); + ClassicAssert.AreEqual(true, networkServiceGroupComparer.GetHashCode(SvcGrp1) == networkServiceGroupComparer.GetHashCode(SvcGrp1)); + ClassicAssert.AreEqual(false, networkServiceGroupComparer.GetHashCode(SvcGrp1) == networkServiceGroupComparer.GetHashCode(SvcGrp2)); + ClassicAssert.AreEqual(false, networkServiceGroupComparer.GetHashCode(SvcGrp1) == networkServiceGroupComparer.GetHashCode(SvcGrp3)); + ClassicAssert.AreEqual(false, networkServiceGroupComparer.GetHashCode(SvcGrp1) == networkServiceGroupComparer.GetHashCode(SvcGrp4)); + ClassicAssert.AreEqual(false, networkServiceGroupComparer.GetHashCode(SvcGrp1) == networkServiceGroupComparer.GetHashCode(SvcGrp5)); + } + } +} diff --git a/roles/tests-unit/files/FWO.Test/ComplianceCheckTest.cs b/roles/tests-unit/files/FWO.Test/ComplianceCheckTest.cs new file mode 100644 index 0000000000..3e5539998c --- /dev/null +++ b/roles/tests-unit/files/FWO.Test/ComplianceCheckTest.cs @@ -0,0 +1,470 @@ +using FWO.Api.Client.Queries; +using FWO.Basics; +using FWO.Compliance; +using FWO.Config.Api; +using FWO.Data; +using FWO.Logging; +using FWO.Test.Fixtures; +using FWO.Test.Mocks; +using NetTools; +using NSubstitute; +using NUnit.Framework; +using System.Collections.Concurrent; +using System.Reflection; + +namespace FWO.Test +{ + [TestFixture] + internal class ComplianceCheckTest : ComplianceCheckTestFixture + { + #region Configuration + + // Expected logs + + private const string PolicyIdZero = "Compliance Check - No Policy defined. Compliance check not possible."; + private const string PolicyNull = "Compliance Check - Policy with id 1 not found."; + private const string NoCriteria = "Compliance Check - Policy without criteria. Compliance check not possible"; + private const string NoRelevantManager = "Compliance Check - No relevant managements found. Compliance check not possible."; + private const string NoViolationsA = "Compliance Check - Loaded 5 rules"; + private const string NoViolationsB = "Compliance Check - Found 0 violations."; + private const string BasicSetup = "Compliance Check - Checked compliance for 5 rules and found 4 non-compliant rules"; + + // Parameters for test configuration + + private const string ExpectedViolationDetailsAutoCalcTrue = "Matrix violation: Auto-calculated Internet Zone (source-uid-rule3 (3.0.0.0-4.0.0.0)) -> 128-168 Zone (destination-uid-rule3 (128.0.0.0-168.0.0.0))"; + private const string ExpectedViolationDetailsAutoCalcFalse = "Matrix violation: Internet/Local (source-uid-rule3 (3.0.0.0-4.0.0.0)) -> 128-168 Zone (destination-uid-rule3 (128.0.0.0-168.0.0.0))"; + + [SetUp] + public override void SetUpTest() + { + base.SetUpTest(); + } + + #endregion + + #region Tests - CheckAll + + [Test] + public async Task CheckAll_PolicyIdZero_AbortCheckWithLog() + { + // Act + SetUpViolationCount(1); + + await ComplianceCheck.RunComplianceCheck(ComplianceCheckType.Standard); + + // Assert + + Assert.That(GlobalConfig.ComplianceCheckPolicyId == 0, "Default policy ID should be zero for this test."); + Assert.That(Logger.Logmessages.Values.Any(m => m.Contains(PolicyIdZero)), "Expected log message not found."); + } + + [Test] + public async Task CheckAll_PolicyNull_AbortCheckWithLog() + { + // Arrange + + await SetUpBasic(); + + // Act + + await ComplianceCheck.RunComplianceCheck(ComplianceCheckType.Standard); + + // Assert + + Assert.That(GlobalConfig.ComplianceCheckPolicyId != 0, "Default policy ID should not be zero for this test."); + Assert.That(ComplianceCheck.Policy == null, "Policy should be null for this test."); + Assert.That(Logger.Logmessages.Values.Any(m => m.Contains(PolicyNull)), "Expected log message not found."); + } + + [Test] + public async Task CheckAll_NoRelevantManager_AbortWithLog() + { + // Arrange + + await SetUpBasic(createEmptyPolicy: true); + + // Act + + await ComplianceCheck.RunComplianceCheck(ComplianceCheckType.Standard); + + // Assert + + Assert.That(GlobalConfig.ComplianceCheckPolicyId != 0, "Default policy ID should not be zero for this test."); + Assert.That(ComplianceCheck.Policy != null, "Policy should not be null for this test."); + Assert.That(Logger.Logmessages.Values.Any(m => m.Contains(NoRelevantManager)), "Unexpected violations."); + } + + [Test] + public async Task CheckAll_NoCriteria_AbortCheckWithLog() + { + // Arrange + + await SetUpBasic(createEmptyPolicy: true, setupRelevantManagements: true); + + // Act + + await ComplianceCheck.RunComplianceCheck(ComplianceCheckType.Standard); + + // Assert + + Assert.That(GlobalConfig.ComplianceCheckPolicyId != 0, "Default policy ID should not be zero for this test."); + Assert.That(ComplianceCheck.Policy != null, "Policy should not be null for this test."); + Assert.That(Logger.Logmessages.Values.Any(m => m.Contains(NoCriteria)), "Expected log message not found."); + } + + + + [Test] + public async Task CheckAll_NoViolations_CompleteWithLog() + { + // Arrange + + await SetUpBasic(setupRelevantManagements: true, createPolicy: true, createRules: true, setupNoViolations: true); + + AggregateCount count = new AggregateCount(); + count.Aggregate.Count = ComplianceCheck.RulesInCheck!.Count; + ApiConnection + .AsSub().SendQueryAsync(RuleQueries.countActiveRules, Arg.Any()) + .Returns(Task.FromResult(count)); + + // Act + + await ComplianceCheck.RunComplianceCheck(ComplianceCheckType.Standard); + + // Assert + + Assert.That(GlobalConfig.ComplianceCheckPolicyId != 0, "Default policy ID should not be zero for this test."); + Assert.That(ComplianceCheck.Policy != null, "Policy should not be null for this test."); + Assert.That(ComplianceCheck.RulesInCheck.Count == 5, "There should be 5 rules in check"); + Assert.That(ComplianceCheck.CurrentViolationsInCheck.Count == 0, "There should be no violations for this test."); + Assert.That(Logger.Logmessages.Values.Any(m => m.Contains(NoViolationsA)), "Unexpected violations."); + Assert.That(Logger.Logmessages.Values.Any(m => m.Contains(NoViolationsB)), "Unexpected violations."); + } + + [Test] + public async Task AreRulesCompliant_AllSelectedPoliciesPass_ReturnsTrue() + { + await SetUpBasic(setupRelevantManagements: true, createPolicy: true, createRules: true, setupNoViolations: true); + + bool compliant = await ComplianceCheck.AreRulesCompliant([1, 2], ComplianceCheck.RulesInCheck!); + + Assert.That(compliant, Is.True); + } + + [Test] + public async Task AreRulesCompliant_OneSelectedPolicyFails_ReturnsFalse() + { + await SetUpBasic(setupRelevantManagements: true, createPolicy: true, createRules: true); + + bool compliant = await ComplianceCheck.AreRulesCompliant([1], ComplianceCheck.RulesInCheck!); + + Assert.That(compliant, Is.False); + } + + [Test] + public async Task CheckAll_BasicSetup_CompleteWithLog() + { + // Arrange + + await SetUpBasic(setupRelevantManagements: true, createPolicy: true, createRules: true); + + AggregateCount count = new AggregateCount(); + count.Aggregate.Count = ComplianceCheck.RulesInCheck!.Count; + ApiConnection + .AsSub().SendQueryAsync(RuleQueries.countActiveRules, Arg.Any()) + .Returns(Task.FromResult(count)); + + // Act + + await ComplianceCheck.RunComplianceCheck(ComplianceCheckType.Standard); + + // Assert + + Assert.That(GlobalConfig.ComplianceCheckPolicyId != 0, "Default policy ID should not be zero for this test."); + Assert.That(ComplianceCheck.Policy != null, "Policy should not be null for this test."); + Assert.That(ComplianceCheck.CurrentViolationsInCheck.Count == 4, "There should be four violations for this test."); + Assert.That(Logger.Logmessages.Values.Any(m => m.Contains(BasicSetup)), "Unexpected violations."); + Assert.That(ComplianceCheck.CurrentViolationsInCheck.Any(violation => violation.Details == ExpectedViolationDetailsAutoCalcTrue)); + } + + [Test] + public async Task CheckAll_BasicSetupWithoutAutoCalcZones_CompleteWithLog() + { + // Arrange + + GlobalConfig.AutoCalculateInternetZone = false; + GlobalConfig.AutoCalculateUndefinedInternalZone = false; + GlobalConfig.TreatDynamicAndDomainObjectsAsInternet = false; + + ComplianceCheck.NetworkZones = CreateNetworkZones(false, false); + + await SetUpBasic(setupRelevantManagements: true, createPolicy: true, createRules: true); + + AggregateCount count = new AggregateCount(); + count.Aggregate.Count = ComplianceCheck.RulesInCheck!.Count; + ApiConnection + .AsSub().SendQueryAsync(RuleQueries.countActiveRules, Arg.Any()) + .Returns(Task.FromResult(count)); + + // Act + + await ComplianceCheck.RunComplianceCheck(ComplianceCheckType.Standard); + + // Assert + + Assert.That(GlobalConfig.ComplianceCheckPolicyId != 0, "Default policy ID should not be zero for this test."); + Assert.That(ComplianceCheck.Policy != null, "Policy should not be null for this test."); + Assert.That(ComplianceCheck.CurrentViolationsInCheck.Count == 4, "There should be four violations for this test."); + Assert.That(Logger.Logmessages.Values.Any(m => m.Contains(BasicSetup)), "Unexpected violations."); + Assert.That(ComplianceCheck.CurrentViolationsInCheck.Any(violation => violation.Details == ExpectedViolationDetailsAutoCalcFalse)); + } + + #endregion + + #region Tests - PostProcessRulesAsync + + [Test] + public async Task PostProcessRulesAsync_DiffsAddAndRemoveCorrectly() + { + // Arrange + + const int policyId = 99; + const int criterionId = 7; + const string mgmtUid = "mgmt-1"; + + Rule dbRuleKeep = CreateSimpleRule(1); + dbRuleKeep.Uid = "rule-1"; + ComplianceViolation keepViolationDb = new() + { + Id = 10, + RuleId = (int)dbRuleKeep.Id, + RuleUid = dbRuleKeep.Uid ?? "", + MgmtUid = mgmtUid, + PolicyId = policyId, + CriterionId = criterionId, + Details = "keep" + }; + dbRuleKeep.Violations.Add(keepViolationDb); + + Rule dbRuleObsolete = CreateSimpleRule(2); + dbRuleObsolete.Uid = "rule-2"; + ComplianceViolation obsoleteViolationDb = new() + { + Id = 11, + RuleId = (int)dbRuleObsolete.Id, + RuleUid = dbRuleObsolete.Uid ?? "", + MgmtUid = mgmtUid, + PolicyId = policyId, + CriterionId = criterionId, + Details = "obsolete" + }; + dbRuleObsolete.Violations.Add(obsoleteViolationDb); + + ComplianceCheck.CurrentViolationsInCheck.Clear(); + ComplianceCheck.CurrentViolationsInCheck.Add(new ComplianceViolation + { + RuleId = keepViolationDb.RuleId, + RuleUid = keepViolationDb.RuleUid, + MgmtUid = keepViolationDb.MgmtUid, + PolicyId = keepViolationDb.PolicyId, + CriterionId = keepViolationDb.CriterionId, + Details = keepViolationDb.Details + }); + ComplianceCheck.CurrentViolationsInCheck.Add(new ComplianceViolation + { + RuleId = 3, + RuleUid = "rule-3", + MgmtUid = mgmtUid, + PolicyId = policyId, + CriterionId = criterionId, + Details = "new" + }); + + // Act + + await ComplianceCheck.PostProcessRulesAsync([dbRuleKeep, dbRuleObsolete]); + await ComplianceCheck.PersistDataAsync(); + + // Assert + + Assert.That(ApiConnection.SentQueries.Count, Is.EqualTo(2), "Should send add and remove mutations."); + + (string Query, object Variables) addQuery = ApiConnection.SentQueries[0]; + Assert.That(addQuery.Query, Is.EqualTo(ComplianceQueries.addViolations)); + IEnumerable? addedViolations = addQuery.Variables + .GetType() + .GetProperty("violations")? + .GetValue(addQuery.Variables) as IEnumerable; + Assert.That(addedViolations, Is.Not.Null); + Assert.That(addedViolations!.Count(), Is.EqualTo(1)); + Assert.That(addedViolations!.First().Details, Is.EqualTo("new")); + + (string Query, object Variables) removeQuery = ApiConnection.SentQueries[1]; + Assert.That(removeQuery.Query, Is.EqualTo(ComplianceQueries.removeViolations)); + IEnumerable? removedIds = removeQuery.Variables + .GetType() + .GetProperty("ids")? + .GetValue(removeQuery.Variables) as IEnumerable; + Assert.That(removedIds, Is.Not.Null); + Assert.That(removedIds!.Single(), Is.EqualTo(obsoleteViolationDb.Id)); + } + + [Test] + public async Task PostProcessRulesAsync_ParallelPathProducesSameDiff() + { + // Arrange + + const int policyId = 77; + const int criterionId = 5; + const string mgmtUid = "mgmt-parallel"; + + List rulesFromDb = new(); + List currentViolations = new(); + + for (int i = 0; i < 200; i++) + { + Rule rule = CreateSimpleRule(i + 1); + rule.Uid = $"rule-{i + 1}"; + + if (i % 2 == 0) + { + ComplianceViolation violation = new() + { + Id = 1000 + i, + RuleId = (int)rule.Id, + RuleUid = rule.Uid ?? "", + MgmtUid = mgmtUid, + PolicyId = policyId, + CriterionId = criterionId, + Details = $"db-only-{i}" + }; + rule.Violations.Add(violation); + } + + rulesFromDb.Add(rule); + } + + for (int i = 0; i < 200; i++) + { + if (i % 3 == 0) + { + currentViolations.Add(new ComplianceViolation + { + RuleId = i + 1, + RuleUid = $"rule-{i + 1}", + MgmtUid = mgmtUid, + PolicyId = policyId, + CriterionId = criterionId, + Details = $"current-only-{i}" + }); + } + } + + ComplianceCheck.CurrentViolationsInCheck.Clear(); + ComplianceCheck.CurrentViolationsInCheck.AddRange(currentViolations); + + // Act + + await ComplianceCheck.PostProcessRulesAsync(rulesFromDb); + + // Assert + + int expectedRemovals = rulesFromDb.Sum(r => r.Violations.Count); // every db violation is absent from current + int expectedAdds = currentViolations.Count; // every current violation is absent from db + + ConcurrentBag adds = (ConcurrentBag)typeof(ComplianceCheck) + .GetField("_violationsToAdd", BindingFlags.NonPublic | BindingFlags.Instance)! + .GetValue(ComplianceCheck)!; + ConcurrentBag removes = (ConcurrentBag)typeof(ComplianceCheck) + .GetField("_violationsToRemove", BindingFlags.NonPublic | BindingFlags.Instance)! + .GetValue(ComplianceCheck)!; + + Assert.That(adds.Count, Is.EqualTo(expectedAdds)); + Assert.That(removes.Count, Is.EqualTo(expectedRemovals)); + } + + #endregion + + #region Tests - CheckRuleCompliance + + [Test] + public async Task CheckRuleCompliance_HeavyLoad_ExecutionTimeLessThanConfiguredLimit() + { + // Arrange + + int numberOfChunks = 100; + int numberOfRulesPerChunk = 100; + int ruleId = 1; + await SetUpBasic(createPolicy: true); + + List criteria = Policy!.Criteria.Select(c => c.Content).ToList(); + + RuleChunks = BuildFixedRuleChunksParallel(numberOfChunks, numberOfRulesPerChunk, ruleId); + + // Act + + DateTime executionStart = DateTime.Now; + foreach (var chunk in RuleChunks) + { + foreach (var rule in chunk) + { + await ComplianceCheck.CheckRuleCompliance(rule, criteria); + } + } + DateTime executionEnd = DateTime.Now; + TimeSpan executionTime = executionEnd - executionStart; + + // Assert + + Assert.That(executionTime < MaxAcceptableExecutionTime, $"Execution time was {executionTime.Seconds} s, expected: {MaxAcceptableExecutionTime.Seconds} s."); + } + + #endregion + + #region Tests - ParseIpRange + + [Test] + public void ParseIpRange_NwObjectOfTypeIpRange_AddedToReturnedList() + { + // Arrange + + NetworkObject networkObject = new(); + networkObject.IP = "0.0.0.0"; + networkObject.IpEnd = "255.255.255.255"; + networkObject.Type.Name = ObjectType.IPRange; + + // Act + + List result = ComplianceCheck.ParseIpRange(networkObject); + + // Assert + + Assert.That(result.Count == 1); + Assert.That(result.First().Begin.ToString() == networkObject.IP); + Assert.That(result.First().End.ToString() == networkObject.IpEnd); + } + + [Test] + public void ParseIpRange_NwObjectOfTypeIpRangeWithSubnetSuffix_AddedToReturnedList() + { + // Arrange + + NetworkObject networkObject = new(); + networkObject.IP = "0.0.0.0/32"; + networkObject.IpEnd = "255.255.255.255/32"; + networkObject.Type.Name = ObjectType.IPRange; + + // Act + + List result = ComplianceCheck.ParseIpRange(networkObject); + + // Assert + + Assert.That(result.Count == 1); + Assert.That(result.First().Begin.ToString() == networkObject.IP.StripOffNetmask()); + Assert.That(result.First().End.ToString() == networkObject.IpEnd.StripOffNetmask()); + } + + #endregion + } +} diff --git a/roles/tests-unit/files/FWO.Test/ComplianceRequestedRulePolicyCheckerTest.cs b/roles/tests-unit/files/FWO.Test/ComplianceRequestedRulePolicyCheckerTest.cs new file mode 100644 index 0000000000..beac21fa40 --- /dev/null +++ b/roles/tests-unit/files/FWO.Test/ComplianceRequestedRulePolicyCheckerTest.cs @@ -0,0 +1,145 @@ +using FWO.Basics; +using FWO.Compliance; +using FWO.Data; +using FWO.Data.Workflow; +using FWO.Test.Fixtures; +using NUnit.Framework; +using System.Reflection; + +namespace FWO.Test +{ + [TestFixture] + internal class ComplianceRequestedRulePolicyCheckerTest : ComplianceCheckTestFixture + { + private ComplianceRequestedRulePolicyChecker checker = default!; + + [SetUp] + public override void SetUpTest() + { + base.SetUpTest(); + checker = new ComplianceRequestedRulePolicyChecker(UserConfig, ApiConnection); + } + + [Test] + public async Task AreRequestTasksCompliant_NoPolicies_ReturnsFalse() + { + bool result = await checker.AreRequestTasksCompliant([], [CreateEligibleRequestTask(11)]); + + Assert.That(result, Is.False); + } + + [Test] + public async Task AreRequestTasksCompliant_NoEligibleRules_ReturnsFalse() + { + WfReqTask incompleteTask = new() + { + Id = 12, + ManagementId = 1, + Title = "Incomplete request", + Elements = + [ + new WfReqElement { Field = ElemFieldType.source.ToString(), IpString = "10.0.0.1/32", Name = "src" }, + new WfReqElement { Field = ElemFieldType.rule.ToString(), RuleUid = "rule-12" } + ] + }; + + bool result = await checker.AreRequestTasksCompliant([5], [incompleteTask]); + + Assert.That(result, Is.False); + } + + [Test] + public void BuildRulesFromRequestTasks_MapsEligibleTaskAndSkipsDeletedElements() + { + WfReqTask task = CreateEligibleRequestTask(21); + task.Elements.Add(new WfReqElement + { + Field = ElemFieldType.source.ToString(), + IpString = "10.0.0.2/32", + Name = "deleted-src", + RequestAction = nameof(RequestAction.delete) + }); + task.Elements.Add(new WfReqElement + { + Field = ElemFieldType.service.ToString(), + Port = 8443, + PortEnd = 8450, + ProtoId = 6, + Name = "deleted-svc", + RequestAction = nameof(RequestAction.delete) + }); + + List rules = BuildRulesFromRequestTasks(task); + + Assert.That(rules, Has.Count.EqualTo(1)); + Assert.Multiple(() => + { + Assert.That(rules[0].MgmtId, Is.EqualTo(1)); + Assert.That(rules[0].Uid, Is.EqualTo("rule-21")); + Assert.That(rules[0].Action, Is.EqualTo(RuleActions.Accept)); + Assert.That(rules[0].Froms, Has.Length.EqualTo(1)); + Assert.That(rules[0].Tos, Has.Length.EqualTo(1)); + Assert.That(rules[0].Services, Has.Length.EqualTo(1)); + Assert.That(rules[0].Froms[0].Object.IP, Is.EqualTo("10.0.0.1/32")); + Assert.That(rules[0].Services[0].Content.DestinationPort, Is.EqualTo(443)); + }); + } + + [Test] + public void BuildRulesFromRequestTasks_MapsDeleteTaskToDropAndRangeToIpRange() + { + WfReqTask task = CreateEligibleRequestTask(22, nameof(WfTaskType.rule_delete)); + task.Elements[0].IpString = "10.0.0.1"; + task.Elements[0].IpEnd = "10.0.0.9"; + task.Elements[0].CidrEnd = new Cidr("10.0.0.9"); + + List rules = BuildRulesFromRequestTasks(task); + + Assert.That(rules, Has.Count.EqualTo(1)); + Assert.Multiple(() => + { + Assert.That(rules[0].Action, Is.EqualTo(RuleActions.Drop)); + Assert.That(rules[0].Froms[0].Object.Type.Name, Is.EqualTo(ObjectType.IPRange)); + Assert.That(rules[0].Froms[0].Object.IpEnd, Is.EqualTo("10.0.0.9/32")); + }); + } + + [Test] + public void BuildRulesFromRequestTasks_SkipsTasksWithoutRequiredActiveElements() + { + WfReqTask task = CreateEligibleRequestTask(23); + task.Elements.First(element => element.Field == ElemFieldType.service.ToString()).RequestAction = nameof(RequestAction.delete); + + List rules = BuildRulesFromRequestTasks(task); + + Assert.That(rules, Is.Empty); + } + + private static WfReqTask CreateEligibleRequestTask(long id, string? taskType = null, string? requestAction = null) + { + return new WfReqTask + { + Id = id, + ManagementId = 1, + Title = $"Request {id}", + TaskType = taskType ?? WfTaskType.access.ToString(), + RequestAction = requestAction ?? nameof(RequestAction.create), + Elements = + [ + new WfReqElement { Field = ElemFieldType.source.ToString(), IpString = "10.0.0.1/32", Name = "src" }, + new WfReqElement { Field = ElemFieldType.destination.ToString(), IpString = "10.0.1.1/32", Name = "dst" }, + new WfReqElement { Field = ElemFieldType.service.ToString(), Port = 443, ProtoId = 6, Name = "https" }, + new WfReqElement { Field = ElemFieldType.rule.ToString(), RuleUid = $"rule-{id}" } + ] + }; + } + + private static List BuildRulesFromRequestTasks(params WfReqTask[] requestTasks) + { + MethodInfo method = typeof(ComplianceRequestedRulePolicyChecker).GetMethod("BuildRulesFromRequestTasks", BindingFlags.NonPublic | BindingFlags.Static) + ?? throw new AssertionException("BuildRulesFromRequestTasks method not found."); + object? result = method.Invoke(null, [requestTasks.AsEnumerable()]); + return result as List ?? throw new AssertionException("BuildRulesFromRequestTasks returned unexpected result."); + } + } +} diff --git a/roles/test/files/FWO.Test/ConfigFileTest.cs b/roles/tests-unit/files/FWO.Test/ConfigFileTest.cs similarity index 89% rename from roles/test/files/FWO.Test/ConfigFileTest.cs rename to roles/tests-unit/files/FWO.Test/ConfigFileTest.cs index 859c1fddb9..454eb621df 100644 --- a/roles/test/files/FWO.Test/ConfigFileTest.cs +++ b/roles/tests-unit/files/FWO.Test/ConfigFileTest.cs @@ -1,7 +1,8 @@ -using FWO.Config.File; +using FWO.Config.File; using FWO.Logging; using Microsoft.IdentityModel.Tokens; using NUnit.Framework; +using NUnit.Framework.Legacy; using System; using System.Collections.Generic; using System.Linq; @@ -109,10 +110,10 @@ internal class ConfigFileTest public void CorrectConfigFile() { CreateAndReadConfigFile(0, correctConfigFile); - Assert.AreEqual("http://127.0.0.3:8880/", ConfigFile.MiddlewareServerNativeUri); - Assert.AreEqual("http://127.0.0.1:8880/", ConfigFile.MiddlewareServerUri); - Assert.AreEqual("https://127.0.0.1:9443/api/v1/graphqlo/", ConfigFile.ApiServerUri); - Assert.AreEqual("500", ConfigFile.ProductVersion); + ClassicAssert.AreEqual("http://127.0.0.3:8880/", ConfigFile.MiddlewareServerNativeUri); + ClassicAssert.AreEqual("http://127.0.0.1:8880/", ConfigFile.MiddlewareServerUri); + ClassicAssert.AreEqual("https://127.0.0.1:9443/api/v1/graphqlo/", ConfigFile.ApiServerUri); + ClassicAssert.AreEqual("500", ConfigFile.ProductVersion); } [Test] @@ -125,24 +126,24 @@ public void IncorrectSyntaxConfigFile() public void MissingValueConfigFile() { CreateAndReadConfigFile(2, missingValueConfigFile); - Assert.AreEqual("http://127.0.0.3:8880/", ConfigFile.MiddlewareServerNativeUri); + ClassicAssert.AreEqual("http://127.0.0.3:8880/", ConfigFile.MiddlewareServerNativeUri); Assert.Catch(typeof(ApplicationException), () => { var _ = ConfigFile.MiddlewareServerUri; }); Assert.Catch(typeof(ApplicationException), () => { var _ = ConfigFile.ApiServerUri; }); - Assert.AreEqual("500", ConfigFile.ProductVersion); + ClassicAssert.AreEqual("500", ConfigFile.ProductVersion); } [Test] public void CorrectPublicKey() { CreateAndReadConfigFile(3, correctConfigFile, "", correctPublicKey); - Assert.AreEqual(KeyImporter.ExtractKeyFromPem(correctPublicKey, isPrivateKey: false)!.KeyId, ConfigFile.JwtPublicKey.KeyId); + ClassicAssert.AreEqual(KeyImporter.ExtractKeyFromPem(correctPublicKey, isPrivateKey: false)!.KeyId, ConfigFile.JwtPublicKey.KeyId); } [Test] public void CorrectPrivateKey() { CreateAndReadConfigFile(4, correctConfigFile, correctPrivateKey, ""); - Assert.AreEqual(KeyImporter.ExtractKeyFromPem(correctPrivateKey, isPrivateKey: true)!.KeyId, ConfigFile.JwtPrivateKey.KeyId); + ClassicAssert.AreEqual(KeyImporter.ExtractKeyFromPem(correctPrivateKey, isPrivateKey: true)!.KeyId, ConfigFile.JwtPrivateKey.KeyId); } [Test] diff --git a/roles/tests-unit/files/FWO.Test/ConfigTest.cs b/roles/tests-unit/files/FWO.Test/ConfigTest.cs new file mode 100644 index 0000000000..b21dcac4ea --- /dev/null +++ b/roles/tests-unit/files/FWO.Test/ConfigTest.cs @@ -0,0 +1,114 @@ +using System.Reflection; +using FWO.Api.Client; +using FWO.Api.Client.Queries; +using FWO.Config.Api; +using FWO.Config.Api.Data; +using FWO.Data; +using FWO.Data.Workflow; +using NUnit.Framework; + +namespace FWO.Test +{ + [TestFixture] + [Parallelizable] + internal class ConfigTest + { + private sealed class UserConfigApiConnection(ConfigItem[] configItems) : ApiConnection + { + public override void SetAuthHeader(string jwt) { } + public override void SetRole(string role) { } + public override void SetBestRole(System.Security.Claims.ClaimsPrincipal user, List targetRoleList) { } + public override void SetProperRole(System.Security.Claims.ClaimsPrincipal user, List targetRoleList) { } + public override void SwitchBack() { } + + public override Task> SendQuerySafeAsync(string query, object? variables = null, string? operationName = null) + { + throw new NotImplementedException(); + } + + public override Task SendQueryAsync(string query, object? variables = null, string? operationName = null) + { + if (typeof(QueryResponseType) == typeof(ConfigItem[]) && query == ConfigQueries.getConfigItemsByUser) + { + return Task.FromResult((QueryResponseType)(object)configItems); + } + if (typeof(QueryResponseType) == typeof(List) && query == ConfigQueries.getCustomTextsPerLanguage) + { + return Task.FromResult((QueryResponseType)(object)new List()); + } + throw new NotImplementedException(); + } + + public override GraphQlApiSubscription GetSubscription(Action exceptionHandler, GraphQlApiSubscription.SubscriptionUpdate subscriptionUpdateHandler, string subscription, object? variables = null, string? operationName = null) + { + throw new NotImplementedException(); + } + + public override void DisposeSubscriptions() { } + protected override void Dispose(bool disposing) { } + } + + [Test] + public void Update_KeepsDefaultEnum_WhenConfigContainsUnknownAutoCreateImplTaskOption() + { + SimulatedUserConfig userConfig = new(); + userConfig.ReqAutoCreateImplTasks = AutoCreateImplTaskOptions.never; + + InvokeUpdate(userConfig, + [ + new() { Key = "reqAutoCreateImplTasks", Value = "999", User = 0 } + ]); + + Assert.That(userConfig.ReqAutoCreateImplTasks, Is.EqualTo(AutoCreateImplTaskOptions.never)); + } + + [Test] + public void Constructor_AppliesGlobalConfigToScheduledUserConfig() + { + SimulatedGlobalConfig globalConfig = new(); + globalConfig.RawConfigItems = + [ + new() { Key = "reqOwnerBased", Value = "true", User = 0 } + ]; + + using UserConfigApiConnection apiConnection = new([]); + UserConfig userConfig = new(globalConfig, apiConnection, new UiUser { DbId = 50, Language = "English" }); + + Assert.That(userConfig.ReqOwnerBased, Is.True); + } + + [Test] + public void Constructor_DoesNotOverwriteUserSpecificConfigWithGlobalValues() + { + SimulatedGlobalConfig globalConfig = new(); + globalConfig.RawConfigItems = + [ + new() { Key = "reqOwnerBased", Value = "true", User = 0 }, + new() { Key = "elementsPerFetch", Value = "777", User = 0 } + ]; + + using UserConfigApiConnection apiConnection = + new([new() { Key = "elementsPerFetch", Value = "55", User = 50 }]); + UserConfig userConfig = new(globalConfig, apiConnection, new UiUser { DbId = 50, Language = "English" }); + + Assert.That(userConfig.ReqOwnerBased, Is.True); + Assert.That(userConfig.ElementsPerFetch, Is.EqualTo(55)); + } + + [Test] + public void DailyCheckSubscription_IncludesNotificationSettingsUsedByRunningJobs() + { + Assert.That(ConfigQueries.subscribeDailyCheckConfigChanges, Does.Contain("notificationLanguage")); + Assert.That(ConfigQueries.subscribeDailyCheckConfigChanges, Does.Contain("ownerActiveRuleEmailBody")); + Assert.That(ConfigQueries.subscribeDailyCheckConfigChanges, Does.Contain("ruleExpiryEmailBody")); + } + + private static void InvokeUpdate(FWO.Config.Api.Config config, ConfigItem[] configItems) + { + MethodInfo updateMethod = typeof(FWO.Config.Api.Config).GetMethod("Update", BindingFlags.Instance | BindingFlags.NonPublic) + ?? throw new MissingMethodException(typeof(FWO.Config.Api.Config).FullName, "Update"); + + updateMethod.Invoke(config, [configItems]); + } + } +} diff --git a/roles/tests-unit/files/FWO.Test/DailyCheckJobTest.cs b/roles/tests-unit/files/FWO.Test/DailyCheckJobTest.cs new file mode 100644 index 0000000000..c57e533139 --- /dev/null +++ b/roles/tests-unit/files/FWO.Test/DailyCheckJobTest.cs @@ -0,0 +1,427 @@ +using System.Reflection; +using FWO.Api.Client; +using FWO.Api.Client.Queries; +using FWO.Basics; +using FWO.Data; +using FWO.Data.Workflow; +using FWO.Middleware.Server.Jobs; +using NUnit.Framework; + +namespace FWO.Test +{ + [TestFixture] + [Parallelizable] + internal class DailyCheckJobTest + { + [Test] + public void LoadEnabledModules_ReturnsAllModules_WhenConfigIsBlank() + { + SimulatedGlobalConfig globalConfig = new() + { + DailyCheckModules = "" + }; + + HashSet enabledModules = InvokeLoadEnabledModules(globalConfig); + + Assert.That(enabledModules, Is.EquivalentTo(Enum.GetValues())); + } + + [Test] + public void LoadEnabledModules_ReturnsEmptySet_WhenConfigContainsEmptyList() + { + SimulatedGlobalConfig globalConfig = new() + { + DailyCheckModules = "[]" + }; + + HashSet enabledModules = InvokeLoadEnabledModules(globalConfig); + + Assert.That(enabledModules, Is.Empty); + } + + [Test] + public void LoadEnabledModules_ReturnsConfiguredSubset_WhenConfigContainsModules() + { + SimulatedGlobalConfig globalConfig = new() + { + DailyCheckModules = "[2,7]" + }; + + HashSet enabledModules = InvokeLoadEnabledModules(globalConfig); + + Assert.That(enabledModules, Is.EquivalentTo(new[] + { + DailyCheckModule.Imports, + DailyCheckModule.OwnerActiveRules + })); + } + + [Test] + public void LoadEnabledModules_ReturnsAllModules_WhenConfigContainsNull() + { + SimulatedGlobalConfig globalConfig = new() + { + DailyCheckModules = "null" + }; + + HashSet enabledModules = InvokeLoadEnabledModules(globalConfig); + + Assert.That(enabledModules, Is.EquivalentTo(Enum.GetValues())); + } + + [Test] + public void LoadEnabledModules_ReturnsAllModules_WhenConfigIsInvalid() + { + SimulatedGlobalConfig globalConfig = new() + { + DailyCheckModules = "{invalid json}" + }; + + HashSet enabledModules = InvokeLoadEnabledModules(globalConfig); + + Assert.That(enabledModules, Is.EquivalentTo(Enum.GetValues())); + } + + [Test] + public async Task Execute_DoesNotRunChecks_WhenNoModulesAreEnabled() + { + CountingApiConnection apiConnection = new(); + SimulatedGlobalConfig globalConfig = new() + { + DailyCheckModules = "[]", + RecCheckActive = true, + RecRefreshDaily = true + }; + DailyCheckJob dailyCheckJob = new(apiConnection, globalConfig); + + await dailyCheckJob.Execute(null!); + + Assert.That(apiConnection.QueryCount, Is.EqualTo(0)); + } + + [Test] + public async Task GetRequestingOwner_ReturnsNull_WhenOwnerIdIsNull() + { + DailyCheckJob dailyCheckJob = new(new CountingApiConnection(), new SimulatedGlobalConfig()); + MethodInfo getRequestingOwner = typeof(DailyCheckJob).GetMethod("GetRequestingOwner", BindingFlags.Instance | BindingFlags.NonPublic) + ?? throw new InvalidOperationException("GetRequestingOwner method not found."); + + Task task = (Task)(getRequestingOwner.Invoke(dailyCheckJob, [null]) + ?? throw new InvalidOperationException("GetRequestingOwner returned null task.")); + FwoOwner? owner = await task; + + Assert.That(owner, Is.Null); + } + + [Test] + public async Task GetRequestingOwner_ReturnsOwner_WhenOwnerExists() + { + OwnerLookupApiConnection apiConnection = new() + { + Owner = new FwoOwner { Id = 42, Name = "Owner A", ExtAppId = "APP-42" } + }; + DailyCheckJob dailyCheckJob = new(apiConnection, new SimulatedGlobalConfig()); + MethodInfo getRequestingOwner = typeof(DailyCheckJob).GetMethod("GetRequestingOwner", BindingFlags.Instance | BindingFlags.NonPublic) + ?? throw new InvalidOperationException("GetRequestingOwner method not found."); + + Task task = (Task)(getRequestingOwner.Invoke(dailyCheckJob, [42]) + ?? throw new InvalidOperationException("GetRequestingOwner returned null task.")); + FwoOwner? owner = await task; + + Assert.That(owner, Is.Not.Null); + Assert.That(owner!.Id, Is.EqualTo(42)); + Assert.That(apiConnection.QueryCount, Is.EqualTo(1)); + } + + [Test] + public async Task GetRequestingOwner_ReturnsNull_WhenOwnerLookupThrows() + { + FailingOwnerLookupApiConnection apiConnection = new(); + DailyCheckJob dailyCheckJob = new(apiConnection, new SimulatedGlobalConfig()); + MethodInfo getRequestingOwner = typeof(DailyCheckJob).GetMethod("GetRequestingOwner", BindingFlags.Instance | BindingFlags.NonPublic) + ?? throw new InvalidOperationException("GetRequestingOwner method not found."); + + Task task = (Task)(getRequestingOwner.Invoke(dailyCheckJob, [42]) + ?? throw new InvalidOperationException("GetRequestingOwner returned null task.")); + FwoOwner? owner = await task; + + Assert.That(owner, Is.Null); + Assert.That(apiConnection.OwnerLookupCount, Is.EqualTo(1)); + Assert.That(apiConnection.LogEntryCount, Is.EqualTo(1)); + Assert.That(apiConnection.AlertCount, Is.EqualTo(1)); + } + + [Test] + public void ConstructLink_ReturnsExpectedModellingUrl() + { + SimulatedGlobalConfig globalConfig = new() + { + UiHostName = "https://fwo.example" + }; + DailyCheckJob dailyCheckJob = new(new CountingApiConnection(), globalConfig); + MethodInfo constructLink = typeof(DailyCheckJob).GetMethod("ConstructLink", BindingFlags.Instance | BindingFlags.NonPublic) + ?? throw new InvalidOperationException("ConstructLink method not found."); + FwoOwner owner = new() { Name = "Owner A", ExtAppId = "APP-42" }; + WfReqTask reqTask = new() { Title = "Interface Request" }; + reqTask.SetAddInfo(AdditionalInfoKeys.ConnId, "123"); + + string link = (string)(constructLink.Invoke(dailyCheckJob, [owner, reqTask]) + ?? throw new InvalidOperationException("ConstructLink returned null.")); + + Assert.That(link, Is.EqualTo($"Interface Request")); + } + + [Test] + public void ConstructLink_UsesLocalizedFallbackTitle_WhenTaskTitleIsMissing() + { + SimulatedGlobalConfig globalConfig = new() + { + UiHostName = "https://fwo.example" + }; + DailyCheckJob dailyCheckJob = new(new CountingApiConnection(), globalConfig); + MethodInfo constructLink = typeof(DailyCheckJob).GetMethod("ConstructLink", BindingFlags.Instance | BindingFlags.NonPublic) + ?? throw new InvalidOperationException("ConstructLink method not found."); + FwoOwner owner = new() { Name = "Owner A", ExtAppId = "APP-42" }; + + string link = (string)(constructLink.Invoke(dailyCheckJob, [owner, null]) + ?? throw new InvalidOperationException("ConstructLink returned null.")); + + Assert.That(link, Is.EqualTo($"Interface")); + } + + [Test] + public async Task PrepareBody_ReplacesAllKnownPlaceholders() + { + OwnerLookupApiConnection apiConnection = new() + { + Owner = new FwoOwner { Id = 7, Name = "Requesting App", ExtAppId = "REQ-7" } + }; + SimulatedGlobalConfig globalConfig = new() + { + UiHostName = "https://fwo.example", + ModUnansweredReqEmailBody = string.Join("|", new[] + { + Placeholder.REQUESTER, + Placeholder.REQUESTDATE, + Placeholder.REQUESTING_APPNAME, + Placeholder.REQUESTING_APPID, + Placeholder.APPNAME, + Placeholder.APPID, + Placeholder.INTERFACE_LINK + }) + }; + DailyCheckJob dailyCheckJob = new(apiConnection, globalConfig); + MethodInfo prepareBody = typeof(DailyCheckJob).GetMethod("PrepareBody", BindingFlags.Instance | BindingFlags.NonPublic) + ?? throw new InvalidOperationException("PrepareBody method not found."); + WfReqTask reqTask = new() + { + Title = "Interface Request", + TaskType = WfTaskType.new_interface.ToString() + }; + reqTask.SetAddInfo(AdditionalInfoKeys.ConnId, "123"); + reqTask.SetAddInfo(AdditionalInfoKeys.ReqOwner, "7"); + WfTicket ticket = new() + { + CreationDate = new DateTime(2025, 1, 2), + Requester = new UiUser { Name = "Requester A" }, + Tasks = [reqTask] + }; + FwoOwner owner = new() { Name = "Owner A", ExtAppId = "APP-42" }; + + Task task = (Task)(prepareBody.Invoke(dailyCheckJob, [ticket, owner]) + ?? throw new InvalidOperationException("PrepareBody returned null task.")); + string body = await task; + + Assert.That(body, Is.EqualTo( + $"Requester A|02.01.2025|Requesting App|REQ-7|Owner A|APP-42|Interface Request")); + } + + [Test] + public async Task CheckImports_CreatesAlertsAndWarningLog_WhenIssuesAreFound() + { + ImportStatusRecordingApiConnection apiConnection = new() + { + ImportStatuses = + [ + new ImportStatus + { + MgmId = 1, + ImportDisabled = false, + LastIncompleteImport = + [ + new ImportControl + { + StartTime = DateTime.Now.AddHours(-3) + } + ] + }, + new ImportStatus + { + MgmId = 2, + ImportDisabled = false, + LastImport = [] + }, + new ImportStatus + { + MgmId = 3, + ImportDisabled = false, + LastImport = [new ImportControl()], + LastImportAttempt = DateTime.Now.AddHours(-5) + }, + new ImportStatus + { + MgmId = 4, + ImportDisabled = true + } + ] + }; + SimulatedGlobalConfig globalConfig = new() + { + MaxImportDuration = 1, + MaxImportInterval = 2 + }; + DailyCheckJob dailyCheckJob = new(apiConnection, globalConfig); + MethodInfo checkImports = typeof(DailyCheckJob).GetMethod("CheckImports", BindingFlags.Instance | BindingFlags.NonPublic) + ?? throw new InvalidOperationException("CheckImports method not found."); + + Task task = (Task)(checkImports.Invoke(dailyCheckJob, null) + ?? throw new InvalidOperationException("CheckImports returned null task.")); + await task; + + Assert.That(apiConnection.AlertCodes, Is.EquivalentTo(new[] + { + AlertCode.ImportRunningTooLong, + AlertCode.NoImport, + AlertCode.SuccessfulImportOverdue + })); + Assert.That(apiConnection.LogSeverities, Is.EqualTo(new[] { 1 })); + } + + private static HashSet InvokeLoadEnabledModules(SimulatedGlobalConfig globalConfig) + { + DailyCheckJob dailyCheckJob = new(new CountingApiConnection(), globalConfig); + MethodInfo loadEnabledModules = typeof(DailyCheckJob).GetMethod("LoadEnabledModules", BindingFlags.Instance | BindingFlags.NonPublic) + ?? throw new InvalidOperationException("LoadEnabledModules method not found."); + + return (HashSet)(loadEnabledModules.Invoke(dailyCheckJob, null) + ?? throw new InvalidOperationException("LoadEnabledModules returned null.")); + } + + private sealed class CountingApiConnection : SimulatedApiConnection + { + public int QueryCount { get; private set; } + + public override Task SendQueryAsync(string query, object? variables = null, string? operationName = null) + { + QueryCount++; + throw new InvalidOperationException("No query should be executed in this test."); + } + } + + private sealed class OwnerLookupApiConnection : SimulatedApiConnection + { + public int QueryCount { get; private set; } + public FwoOwner? Owner { get; set; } + + public override Task SendQueryAsync(string query, object? variables = null, string? operationName = null) + { + QueryCount++; + if (query == OwnerQueries.getOwnerById && typeof(QueryResponseType) == typeof(FwoOwner) && Owner != null) + { + return Task.FromResult((QueryResponseType)(object)Owner); + } + + throw new InvalidOperationException($"Unexpected query: {query}"); + } + } + + private sealed class FailingOwnerLookupApiConnection : SimulatedApiConnection + { + public int OwnerLookupCount { get; private set; } + public int LogEntryCount { get; private set; } + public int AlertCount { get; private set; } + + public override Task SendQueryAsync(string query, object? variables = null, string? operationName = null) + { + if (query == OwnerQueries.getOwnerById) + { + OwnerLookupCount++; + throw new InvalidOperationException("Owner lookup failed."); + } + + if (query == MonitorQueries.addLogEntry && typeof(QueryResponseType) == typeof(ReturnIdWrapper)) + { + LogEntryCount++; + return Task.FromResult((QueryResponseType)(object)new ReturnIdWrapper + { + ReturnIds = [new ReturnId { NewId = 1 }] + }); + } + + if (query == MonitorQueries.getOpenAlerts && typeof(QueryResponseType) == typeof(List)) + { + return Task.FromResult((QueryResponseType)(object)new List()); + } + + if (query == MonitorQueries.addAlert && typeof(QueryResponseType) == typeof(ReturnIdWrapper)) + { + AlertCount++; + return Task.FromResult((QueryResponseType)(object)new ReturnIdWrapper + { + ReturnIds = [new ReturnId { NewIdLong = 1 }] + }); + } + + throw new InvalidOperationException($"Unexpected query: {query}"); + } + } + + private sealed class ImportStatusRecordingApiConnection : SimulatedApiConnection + { + public List ImportStatuses { get; set; } = []; + public List AlertCodes { get; } = []; + public List LogSeverities { get; } = []; + + public override Task SendQueryAsync(string query, object? variables = null, string? operationName = null) + { + if (query == MonitorQueries.getImportStatus && typeof(QueryResponseType) == typeof(List)) + { + return Task.FromResult((QueryResponseType)(object)ImportStatuses); + } + + if (query == MonitorQueries.getOpenAlerts && typeof(QueryResponseType) == typeof(List)) + { + return Task.FromResult((QueryResponseType)(object)new List()); + } + + if (query == MonitorQueries.addAlert && typeof(QueryResponseType) == typeof(ReturnIdWrapper)) + { + object variablesObject = variables ?? throw new InvalidOperationException("Alert variables missing."); + int alertCode = (int)(variablesObject.GetType().GetProperty("alertCode")?.GetValue(variablesObject) + ?? throw new InvalidOperationException("Alert code missing.")); + AlertCodes.Add((AlertCode)alertCode); + + return Task.FromResult((QueryResponseType)(object)new ReturnIdWrapper + { + ReturnIds = [new ReturnId { NewIdLong = AlertCodes.Count }] + }); + } + + if (query == MonitorQueries.addLogEntry && typeof(QueryResponseType) == typeof(ReturnIdWrapper)) + { + object variablesObject = variables ?? throw new InvalidOperationException("Log variables missing."); + int severity = (int)(variablesObject.GetType().GetProperty("severity")?.GetValue(variablesObject) + ?? throw new InvalidOperationException("Severity missing.")); + LogSeverities.Add(severity); + + return Task.FromResult((QueryResponseType)(object)new ReturnIdWrapper + { + ReturnIds = [new ReturnId { NewId = LogSeverities.Count }] + }); + } + + throw new InvalidOperationException($"Unexpected query: {query}"); + } + } + } +} diff --git a/roles/tests-unit/files/FWO.Test/DailyCheckModuleTest.cs b/roles/tests-unit/files/FWO.Test/DailyCheckModuleTest.cs new file mode 100644 index 0000000000..473c92d2ee --- /dev/null +++ b/roles/tests-unit/files/FWO.Test/DailyCheckModuleTest.cs @@ -0,0 +1,22 @@ +using System.Text.Json; +using FWO.Basics; +using NUnit.Framework; +using NUnit.Framework.Legacy; + +namespace FWO.Test +{ + [TestFixture] + [Parallelizable] + internal class DailyCheckModuleTest + { + [Test] + public void AllModulesNumListCanBeDeserialized() + { + List? modules = JsonSerializer.Deserialize>(DailyCheckModuleGroups.AllModulesNumList()); + + ClassicAssert.IsNotNull(modules); + ClassicAssert.AreEqual(Enum.GetValues().Length, modules!.Count); + CollectionAssert.AreEqual(Enum.GetValues(), modules); + } + } +} diff --git a/roles/tests-unit/files/FWO.Test/DataImportBaseTest.cs b/roles/tests-unit/files/FWO.Test/DataImportBaseTest.cs new file mode 100644 index 0000000000..908042312c --- /dev/null +++ b/roles/tests-unit/files/FWO.Test/DataImportBaseTest.cs @@ -0,0 +1,154 @@ +using System; +using System.IO; +using FWO.Api.Client; +using FWO.Config.Api; +using FWO.Middleware.Server; +using NUnit.Framework; + +namespace FWO.Test +{ + [TestFixture] + public class DataImportBaseTest + { + [Test] + public void RunImportScriptReturnsFalseWhenScriptMissing() + { + ApiConnection apiConnection = new SimulatedApiConnection(); + GlobalConfig globalConfig = new SimulatedGlobalConfig(); + TestDataImportBase importer = new(apiConnection, globalConfig); + + string scriptPath = Path.Combine(Path.GetTempPath(), $"missing-{Guid.NewGuid():N}.py"); + + bool executed = importer.ExecuteScript(scriptPath, null); + + Assert.That(executed, Is.False); + } + + [Test] + public void RunImportScriptPassesArguments() + { + if (OperatingSystem.IsWindows()) + { + Assert.Ignore("Script execution test requires a Unix-like environment."); + } + + string tempDir = Path.Combine(Path.GetTempPath(), $"fwo-import-test-{Guid.NewGuid():N}"); + Directory.CreateDirectory(tempDir); + + try + { + string outputFile = Path.Combine(tempDir, "args.txt"); + string scriptPath = Path.Combine(tempDir, "print_args.py"); + string scriptContent = "#!/usr/bin/env python3\n" + + "import sys\n" + + $"with open(r\"{outputFile}\", \"w\", encoding=\"utf-8\") as file:\n" + + " file.write(\"\\n\".join(sys.argv[1:]))\n"; + + File.WriteAllText(scriptPath, scriptContent); +#pragma warning disable CA1416 // Validate platform compatibility + File.SetUnixFileMode(scriptPath, UnixFileMode.UserRead | UnixFileMode.UserWrite | UnixFileMode.UserExecute); +#pragma warning restore CA1416 // Validate platform compatibility + + ApiConnection apiConnection = new SimulatedApiConnection(); + GlobalConfig globalConfig = new SimulatedGlobalConfig(); + TestDataImportBase importer = new(apiConnection, globalConfig); + + bool executed = importer.ExecuteScript( + scriptPath, + "--criticalityRecertPeriodMapping \"1:360\" \"2:180\" \"3:90\" --compositeIdFields \"Applikation\" \"Teilapplikation\"" + ); + + Assert.That(executed, Is.True); + Assert.That( + File.ReadAllLines(outputFile), + Is.EqualTo( + [ + "--criticalityRecertPeriodMapping", + "1:360", + "2:180", + "3:90", + "--compositeIdFields", + "Applikation", + "Teilapplikation" + ]) + ); + } + finally + { + if (Directory.Exists(tempDir)) + { + Directory.Delete(tempDir, true); + } + } + } + + [Test] + public void ReadFileTrimsContent() + { + ApiConnection apiConnection = new SimulatedApiConnection(); + GlobalConfig globalConfig = new SimulatedGlobalConfig(); + TestDataImportBase importer = new(apiConnection, globalConfig); + + string tempFile = Path.GetTempFileName(); + try + { + File.WriteAllText(tempFile, " sample text \n"); + + importer.ReadImportFile(tempFile); + + Assert.That(importer.ImportFile, Is.EqualTo("sample text")); + } + finally + { + File.Delete(tempFile); + } + } + + [Test] + public void ParseCommandLineArgumentsPreservesQuotedValues() + { + List arguments = TestDataImportBase.GetArguments( + "--filterColumn \"Aktive Firewallregel\" --includeValues \"Ja\" --compositeIdFields \"Applikation\" \"Teilapplikation\"" + ); + + Assert.That( + arguments, + Is.EqualTo( + [ + "--filterColumn", + "Aktive Firewallregel", + "--includeValues", + "Ja", + "--compositeIdFields", + "Applikation", + "Teilapplikation" + ]) + ); + } + + private sealed class TestDataImportBase : DataImportBase + { + public TestDataImportBase(ApiConnection apiConnection, GlobalConfig globalConfig) + : base(apiConnection, globalConfig) + { + } + + public bool ExecuteScript(string scriptPath, string? args) + { + return RunImportScript(scriptPath, args); + } + + public void ReadImportFile(string filepath) + { + ReadFile(filepath); + } + + public static List GetArguments(string args) + { + return ParseCommandLineArguments(args); + } + + public string ImportFile => importFile; + } + } +} diff --git a/roles/tests-unit/files/FWO.Test/DeviceComparerTest.cs b/roles/tests-unit/files/FWO.Test/DeviceComparerTest.cs new file mode 100644 index 0000000000..609364269c --- /dev/null +++ b/roles/tests-unit/files/FWO.Test/DeviceComparerTest.cs @@ -0,0 +1,88 @@ +using FWO.Data; +using NUnit.Framework; + +namespace FWO.Test +{ + [TestFixture] + internal class DeviceComparerTest + { + private readonly Device _comparer = new(); + + [Test] + public void Equals_ReturnsTrue_ForSameReference() + { + Device device = new() { Name = "DeviceA", Uid = "uid-1" }; + + bool result = _comparer.Equals(device, device); + + Assert.That(result, Is.True); + } + + [Test] + public void Equals_ReturnsFalse_WhenOneIsNull() + { + Device device = new() { Name = "DeviceA", Uid = "uid-1" }; + + bool result = _comparer.Equals(device, null); + + Assert.That(result, Is.False); + } + + [Test] + public void Equals_ReturnsTrue_WhenNameAndUidMatch() + { + Device first = new() { Name = "DeviceA", Uid = "uid-1" }; + Device second = new() { Name = "DeviceA", Uid = "uid-1" }; + + bool result = _comparer.Equals(first, second); + + Assert.That(result, Is.True); + } + + [Test] + public void Equals_ReturnsFalse_WhenNameOrUidDiffer() + { + Device first = new() { Name = "DeviceA", Uid = "uid-1" }; + Device second = new() { Name = "DeviceB", Uid = "uid-1" }; + + bool result = _comparer.Equals(first, second); + + Assert.That(result, Is.False); + } + + [Test] + public void Equals_InstanceMethod_ReturnsFalse_WhenDeviceIsNull() + { + Device device = new() { Name = "DeviceA", Uid = "uid-1" }; + + bool result = device.Equals(null); + + Assert.That(result, Is.False); + } + + [Test] + public void GetHashCode_AlignsWithEquality_WhenValuesMatch() + { + Device first = new() { Name = "DeviceA", Uid = "uid-1" }; + Device second = new() { Name = "DeviceA", Uid = "uid-1" }; + + int firstHash = _comparer.GetHashCode(first); + int secondHash = _comparer.GetHashCode(second); + + Assert.That(firstHash, Is.EqualTo(secondHash)); + } + + [Test] + public void GetHashCode_TreatsNullAndEmptyAsEqual() + { + Device first = new() { Name = null, Uid = "" }; + Device second = new() { Name = "", Uid = null }; + + int firstHash = _comparer.GetHashCode(first); + int secondHash = _comparer.GetHashCode(second); + + Assert.That(_comparer.Equals(first, second), Is.True); + Assert.That(firstHash, Is.EqualTo(secondHash)); + } + } +} diff --git a/roles/tests-unit/files/FWO.Test/DisplayBaseTest.cs b/roles/tests-unit/files/FWO.Test/DisplayBaseTest.cs new file mode 100644 index 0000000000..c202d50cd4 --- /dev/null +++ b/roles/tests-unit/files/FWO.Test/DisplayBaseTest.cs @@ -0,0 +1,75 @@ +using NUnit.Framework; +using NUnit.Framework.Legacy; +using FWO.Basics; +using FWO.Data; + +namespace FWO.Test +{ + [TestFixture] + [Parallelizable] + internal class DisplayBaseTest + { + + static readonly string ip1 = "1.0.0.0"; + static readonly string ip2 = "1.0.0.0/32"; + static readonly string ip3 = "1.0.0.3/32"; + static readonly string ip4 = "1.0.1.3/32"; + static readonly string ip5 = "1.0.0.0/24"; + static readonly string ip6 = "1.0.0.0/31"; + static readonly string ip7 = "1.0.0.2/31"; + + static readonly string ip11 = ":a:"; + static readonly string ip12 = ":a:/128"; + static readonly string ip13 = ":a:/111"; + + static readonly NetworkService serv1 = new() { Name = "Serv1", DestinationPort = 1000, Protocol = new() { Id = 6, Name = "TCP" } }; + static readonly NetworkService serv2 = new() { Name = "Serv2", DestinationPort = 1000, DestinationPortEnd = 2000, Protocol = new() { Id = 17, Name = "UDP" } }; + static readonly NetworkService serv3 = new() { Name = "Serv3", Protocol = new() { Name = "ESP" } }; + static readonly NetworkService serv4 = new() { Name = "Any", Protocol = new() { Id = 0 } }; + static readonly NetworkService serv5 = new() { Name = "ALL", Protocol = new() { Id = 0 } }; + + [SetUp] + public void Initialize() + { } + + [Test] + public void TestGetNetmask() + { + ClassicAssert.AreEqual("", ip1.GetNetmask()); + ClassicAssert.AreEqual("32", ip2.GetNetmask()); + ClassicAssert.AreEqual("24", ip5.GetNetmask()); + ClassicAssert.AreEqual("", ip11.GetNetmask()); + ClassicAssert.AreEqual("111", ip13.GetNetmask()); + } + + [Test] + public void TestAutoDetectType() + { + ClassicAssert.AreEqual(ObjectType.Host, IpOperations.GetObjectType(ip1, ip1)); + ClassicAssert.AreEqual(ObjectType.Host, IpOperations.GetObjectType(ip1, ip2)); + ClassicAssert.AreEqual(ObjectType.Host, IpOperations.GetObjectType(ip1, "")); + ClassicAssert.AreEqual(ObjectType.Network, IpOperations.GetObjectType(ip2, ip3)); + ClassicAssert.AreEqual(ObjectType.IPRange, IpOperations.GetObjectType(ip2, ip4)); + ClassicAssert.AreEqual(ObjectType.Network, IpOperations.GetObjectType(ip5, ip5)); + // ClassicAssert.AreEqual(ObjectType.Network, IpOperations.GetObjectType(ip6, ip7)); // should detect this? + ClassicAssert.AreEqual(ObjectType.IPRange, IpOperations.GetObjectType(ip6, ip7)); + + ClassicAssert.AreEqual(ObjectType.Host, IpOperations.GetObjectType(ip11, ip11)); + ClassicAssert.AreEqual(ObjectType.Host, IpOperations.GetObjectType(ip11, ip12)); + ClassicAssert.AreEqual(ObjectType.Network, IpOperations.GetObjectType(ip13, ip13)); + } + + [Test] + public void TestDisplayService() + { + ClassicAssert.AreEqual("Serv1 (1000/TCP)", DisplayBase.DisplayService(serv1, false).ToString()); + ClassicAssert.AreEqual("Serv2 (1000-2000/UDP)", DisplayBase.DisplayService(serv2, false).ToString()); + ClassicAssert.AreEqual("Serv3 (ESP)", DisplayBase.DisplayService(serv3, false).ToString()); + ClassicAssert.AreEqual("NewName (1000/TCP)", DisplayBase.DisplayService(serv1, false, "NewName").ToString()); + ClassicAssert.AreEqual("1000-2000/UDP", DisplayBase.DisplayService(serv2, true).ToString()); + ClassicAssert.AreEqual("ESP", DisplayBase.DisplayService(serv3, true).ToString()); + ClassicAssert.AreEqual("Any", DisplayBase.DisplayService(serv4, false).ToString()); + ClassicAssert.AreEqual("ALL", DisplayBase.DisplayService(serv5, true).ToString()); + } + } +} diff --git a/roles/tests-unit/files/FWO.Test/DisplayServiceTest.cs b/roles/tests-unit/files/FWO.Test/DisplayServiceTest.cs new file mode 100644 index 0000000000..dba055bc09 --- /dev/null +++ b/roles/tests-unit/files/FWO.Test/DisplayServiceTest.cs @@ -0,0 +1,72 @@ +using FWO.Config.Api; +using FWO.Ui.Services; +using Microsoft.AspNetCore.Components; +using NUnit.Framework; + +namespace FWO.Test +{ + [TestFixture] + public class DisplayServiceTest + { + [Test] + public void DisplayButton_ReturnsPlainText_WhenIconifyDisabled() + { + UserConfig userConfig = new SimulatedUserConfig + { + ModIconify = false + }; + + MarkupString result = DisplayService.DisplayButton(userConfig, "save", "bi bi-save", "add", "bi bi-obj"); + + Assert.That(result.Value, Is.EqualTo("Save")); + } + + [Test] + public void DisplayButton_IncludesIconAndTooltip_WhenIconifyEnabled() + { + UserConfig userConfig = new SimulatedUserConfig + { + ModIconify = true + }; + + MarkupString result = DisplayService.DisplayButton(userConfig, "save", "bi bi-save", "add", "bi bi-obj"); + + Assert.That(result.Value, Does.Contain("class=\"bi bi-save\"")); + Assert.That(result.Value, Does.Contain("data-toggle=\"tooltip\"")); + Assert.That(result.Value, Does.Contain("title=\"Save\"")); + Assert.That(result.Value, Does.Contain("Add")); + Assert.That(result.Value, Does.Contain("")); + } + + [Test] + public void DisplayButtonWithTooltip_ReturnsPlainTextWithTooltip_WhenIconifyDisabled() + { + UserConfig userConfig = new SimulatedUserConfig + { + ModIconify = false + }; + + MarkupString result = DisplayService.DisplayButtonWithTooltip(userConfig, "save", "bi bi-save", "Extra"); + + Assert.That(result.Value, Does.Contain("data-toggle=\"tooltip\"")); + Assert.That(result.Value, Does.Contain("Extra")); + Assert.That(result.Value, Does.Contain("Save")); + } + + [Test] + public void DisplayButtonWithTooltip_IncludesTextInTooltip_WhenIconifyEnabled() + { + UserConfig userConfig = new SimulatedUserConfig + { + ModIconify = true + }; + + MarkupString result = DisplayService.DisplayButtonWithTooltip(userConfig, "save", "bi bi-save", "Extra", "add", "bi bi-obj"); + + Assert.That(result.Value, Does.Contain("class=\"bi bi-save\"")); + Assert.That(result.Value, Does.Contain("title=\"Save - Extra\"")); + Assert.That(result.Value, Does.Contain("Add")); + Assert.That(result.Value, Does.Contain("")); + } + } +} diff --git a/roles/tests-unit/files/FWO.Test/DistNameTest.cs b/roles/tests-unit/files/FWO.Test/DistNameTest.cs new file mode 100644 index 0000000000..345d7aa98b --- /dev/null +++ b/roles/tests-unit/files/FWO.Test/DistNameTest.cs @@ -0,0 +1,85 @@ +using NUnit.Framework; +using NUnit.Framework.Legacy; +using FWO.Basics; +using FWO.Data; + +namespace FWO.Test +{ + [TestFixture] + [Parallelizable] + internal class DistNameTest + { + + static readonly DistName dn1 = new(""); + static readonly DistName dn2 = new("uid=intuser2,ou=users,ou=tenant2,dc=fworch,dc=internal"); + static readonly DistName dn3 = new("cn=usergroup3,ou=groups,dc=somewhere,dc=de"); + static readonly DistName dn4 = new(@"cn=Mustermann\, Max,ou=users,dc=example,dc=com"); + static readonly DistName dn5 = new(@"cn=Mustermann\2C\20Max,ou=users,dc=example,dc=com"); + static readonly DistName dn6 = new(@"cn=Backslash\5CName,ou=users,dc=example,dc=com"); + static readonly DistName dn7 = new(@"cn=M\C3\BCller,ou=users,dc=example,dc=com"); + + [SetUp] + public void Initialize() + { } + + [Test] + public void TestDistName() + { + ClassicAssert.AreEqual("", dn1.UserName); + ClassicAssert.AreEqual("", dn1.Role); + ClassicAssert.AreEqual("", dn1.Group); + ClassicAssert.AreEqual(0, dn1.Root.Count); + ClassicAssert.AreEqual(0, dn1.Path.Count); + ClassicAssert.AreEqual("", dn1.GetTenantNameViaLdapTenantLevel()); + ClassicAssert.AreEqual(false, dn1.IsInternal()); + + ClassicAssert.AreEqual("intuser2", dn2.UserName); + ClassicAssert.AreEqual("", dn2.Role); + ClassicAssert.AreEqual("", dn2.Group); + ClassicAssert.AreEqual(2, dn2.Root.Count); + ClassicAssert.AreEqual(4, dn2.Path.Count); + ClassicAssert.AreEqual("tenant2", dn2.GetTenantNameViaLdapTenantLevel(3)); + ClassicAssert.AreEqual(true, dn2.IsInternal()); + + ClassicAssert.AreEqual("usergroup3", dn3.UserName); + ClassicAssert.AreEqual("usergroup3", dn3.Role); + ClassicAssert.AreEqual("usergroup3", dn3.Group); + ClassicAssert.AreEqual(2, dn3.Root.Count); + ClassicAssert.AreEqual("somewhere", dn3.Root[0]); + ClassicAssert.AreEqual(3, dn3.Path.Count); + ClassicAssert.AreEqual("groups", dn3.Path[0]); + ClassicAssert.AreEqual("", dn3.GetTenantNameViaLdapTenantLevel(0)); + ClassicAssert.AreEqual(false, dn3.IsInternal()); + + ClassicAssert.AreEqual("Mustermann, Max", dn4.UserName); + ClassicAssert.AreEqual("Mustermann, Max", dn4.Role); + ClassicAssert.AreEqual("Mustermann, Max", dn4.Group); + ClassicAssert.AreEqual(2, dn4.Root.Count); + ClassicAssert.AreEqual("users", dn4.Path[0]); + + ClassicAssert.AreEqual("Mustermann, Max", dn5.UserName); + ClassicAssert.AreEqual("Mustermann, Max", dn5.Role); + ClassicAssert.AreEqual("Mustermann, Max", dn5.Group); + ClassicAssert.AreEqual("users", dn5.Path[0]); + + ClassicAssert.AreEqual(@"Backslash\Name", dn6.UserName); + ClassicAssert.AreEqual(@"Backslash\Name", dn6.Role); + ClassicAssert.AreEqual(@"Backslash\Name", dn6.Group); + + ClassicAssert.AreEqual("Müller", dn7.UserName); + ClassicAssert.AreEqual("Müller", dn7.Role); + ClassicAssert.AreEqual("Müller", dn7.Group); + } + + [TestCase(@"cn=Müller \2C (xy),ou=users,dc=example,dc=com", @"cn=Müller \, (xy),ou=users,dc=example,dc=com")] + [TestCase(@"cn=M\C3\BCller \2C (xy),ou=users,dc=example,dc=com", @"cn=Müller \, (xy),ou=users,dc=example,dc=com")] + [TestCase(@"CN=User\, Example,OU=Users,DC=Example,DC=COM", @"cn=User\2C Example,ou=users,dc=example,dc=com")] + public void NormalizeDnForComparison_TreatsEquivalentEscapedDnsAsEqual(string leftDn, string rightDn) + { + string normalizedLeft = DistName.NormalizeDnForComparison(leftDn); + string normalizedRight = DistName.NormalizeDnForComparison(rightDn); + + Assert.That(normalizedLeft, Is.EqualTo(normalizedRight)); + } + } +} diff --git a/roles/tests-unit/files/FWO.Test/DropdownTest.cs b/roles/tests-unit/files/FWO.Test/DropdownTest.cs new file mode 100644 index 0000000000..707fc6ca73 --- /dev/null +++ b/roles/tests-unit/files/FWO.Test/DropdownTest.cs @@ -0,0 +1,142 @@ +using System.Collections.Generic; +using System.Linq; +using System.Reflection; +using Bunit; +using FWO.Ui.Services; +using FWO.Ui.Shared; +using Microsoft.Extensions.DependencyInjection; +using NUnit.Framework; + +namespace FWO.Test +{ + [TestFixture] + [FixtureLifeCycle(LifeCycle.InstancePerTestCase)] + public class DropdownTest : BunitContext + { + private static MethodInfo GetInstanceMethod(string methodName, params Type[] parameterTypes) + { + MethodInfo? method = typeof(Dropdown).GetMethod( + methodName, + BindingFlags.NonPublic | BindingFlags.Instance, + null, + parameterTypes, + null); + + Assert.That(method, Is.Not.Null); + return method!; + } + + private static string GetSearchValue(Dropdown dropdown) + { + FieldInfo? searchValueField = typeof(Dropdown).GetField("searchValue", BindingFlags.NonPublic | BindingFlags.Instance); + Assert.That(searchValueField, Is.Not.Null); + return (string?)searchValueField!.GetValue(dropdown) ?? ""; + } + + private static void SetComponentParameter(Dropdown dropdown, string parameterName, TValue value) + { + PropertyInfo? parameter = typeof(Dropdown).GetProperty(parameterName, BindingFlags.Public | BindingFlags.Instance); + Assert.That(parameter, Is.Not.Null); + parameter!.SetValue(dropdown, value); + } + + /// + /// Ensures that a global focus callback tolerates a missing JS runtime after disposal. + /// + [Test] + public void OnFocusChanged_DoesNotThrow_WhenJsRuntimeIsNull() + { + Dropdown dropdown = new(); + MethodInfo? method = typeof(Dropdown).GetMethod("OnFocusChanged", BindingFlags.NonPublic | BindingFlags.Instance); + + Assert.That(method, Is.Not.Null); + Assert.DoesNotThrow(() => method!.Invoke(dropdown, ["test-element"])); + } + + /// + /// Verifies that filtering matches values without regard to input casing. + /// + [Test] + public void Filter_IsCaseInsensitive() + { + Dropdown dropdown = new(); + SetComponentParameter(dropdown, nameof(Dropdown.Elements), new[] { "Alpha", "beta", "Gamma" }); + MethodInfo filterMethod = GetInstanceMethod("Filter", typeof(string)); + + filterMethod.Invoke(dropdown, ["AL"]); + + Assert.That(dropdown.FilteredElements, Is.EqualTo(["Alpha"])); + } + + /// + /// Verifies that the none-selected label is shown when there is no selection. + /// + [Test] + public void DisplaySelection_UsesNoneSelectedText_WhenNoSelection() + { + Dropdown dropdown = new(); + SetComponentParameter(dropdown, nameof(Dropdown.NoneSelectedText), "none"); + MethodInfo displaySelectionMethod = GetInstanceMethod("DisplaySelection", typeof(IEnumerable)); + + displaySelectionMethod.Invoke(dropdown, [Enumerable.Empty()]); + + Assert.That(GetSearchValue(dropdown), Is.EqualTo("none")); + } + + /// + /// Verifies that multiple selected values are rendered as first item plus count summary. + /// + [Test] + public void DisplaySelection_FormatsSummary_WhenMultipleElementsSelected() + { + Dropdown dropdown = new(); + MethodInfo displaySelectionMethod = GetInstanceMethod("DisplaySelection", typeof(IEnumerable)); + + displaySelectionMethod.Invoke(dropdown, [new[] { "first", "second", "third" }]); + + Assert.That(GetSearchValue(dropdown), Is.EqualTo("first, ... (+ 2)")); + } + + /// + /// Verifies that selecting the same element twice in multiselect mode keeps a single entry. + /// + [Test] + public async Task SelectElement_MultiSelect_AddsElementOnlyOnce() + { + Services.AddScoped(); + IRenderedComponent> renderedDropdown = Render>(parameters => parameters + .Add(p => p.Multiselect, true) + .Add(p => p.SelectedElements, [])); + Dropdown dropdown = renderedDropdown.Instance; + MethodInfo selectMethod = GetInstanceMethod("SelectElement", typeof(string)); + + Task firstSelection = (Task)selectMethod.Invoke(dropdown, ["one"])!; + await firstSelection; + Task secondSelection = (Task)selectMethod.Invoke(dropdown, ["one"])!; + await secondSelection; + + Assert.That(dropdown.SelectedElements, Is.EqualTo(["one"])); + Assert.That(dropdown.Toggled, Is.False); + } + + /// + /// Verifies that unselecting one item in multiselect mode removes only that item. + /// + [Test] + public async Task UnselectElement_MultiSelect_RemovesElementFromSelection() + { + Services.AddScoped(); + IRenderedComponent> renderedDropdown = Render>(parameters => parameters + .Add(p => p.Multiselect, true) + .Add(p => p.SelectedElements, ["one", "two"])); + Dropdown dropdown = renderedDropdown.Instance; + MethodInfo unselectMethod = GetInstanceMethod("UnselectElement", typeof(string)); + + Task unselection = (Task)unselectMethod.Invoke(dropdown, ["one"])!; + await unselection; + + Assert.That(dropdown.SelectedElements, Is.EqualTo(["two"])); + Assert.That(dropdown.Toggled, Is.False); + } + } +} diff --git a/roles/tests-unit/files/FWO.Test/EmailHelperRecipientTest.cs b/roles/tests-unit/files/FWO.Test/EmailHelperRecipientTest.cs new file mode 100644 index 0000000000..5efb2e34ed --- /dev/null +++ b/roles/tests-unit/files/FWO.Test/EmailHelperRecipientTest.cs @@ -0,0 +1,55 @@ +using FWO.Api.Client; +using FWO.Basics; +using FWO.Data; +using FWO.Services; +using NUnit.Framework; + +namespace FWO.Test +{ + [TestFixture] + public class EmailHelperRecipientTest + { + private static EmailHelper CreateEmailHelper() + { + SimulatedUserConfig userConfig = new() + { + UseDummyEmailAddress = true, + DummyEmailAddress = "dummy@example.test" + }; + return new EmailHelper(new SimulatedApiConnection(), null, userConfig, DefaultInit.DoNothing); + } + + [Test] + public async Task GetRecipientsReturnsOwnerGroupAndMainForFallbackSelection() + { + EmailHelper helper = CreateEmailHelper(); + FwoOwner owner = new(); + owner.AddOwnerResponsible(GlobalConst.kOwnerResponsibleTypeSupporting, "cn=supporting,dc=test"); + owner.AddOwnerResponsible(GlobalConst.kOwnerResponsibleTypeMain, "cn=main,dc=test"); + + List recipients = await helper.GetRecipients( + EmailRecipientOption.FallbackToMainResponsibleIfOwnerGroupEmpty, + null, + owner, + null, + null); + + Assert.That(recipients, Has.Count.EqualTo(2)); + Assert.That(recipients, Is.All.EqualTo("dummy@example.test")); + } + + [Test] + public async Task GetRecipientsReturnsOtherAddressesForOtherAddressesOption() + { + EmailHelper helper = CreateEmailHelper(); + List recipients = await helper.GetRecipients( + EmailRecipientOption.OtherAddresses, + null, + null, + null, + ["a@test", "b@test"]); + + Assert.That(recipients, Is.EquivalentTo(new[] { "a@test", "b@test" })); + } + } +} diff --git a/roles/tests-unit/files/FWO.Test/ExportTest.cs b/roles/tests-unit/files/FWO.Test/ExportTest.cs new file mode 100644 index 0000000000..b066b6dad8 --- /dev/null +++ b/roles/tests-unit/files/FWO.Test/ExportTest.cs @@ -0,0 +1,1531 @@ +using NUnit.Framework; +using NUnit.Framework.Legacy; +using FWO.Logging; +using FWO.Report; +using FWO.Report.Filter; +using FWO.Basics; +using FWO.Config.Api; +using FWO.Data; +using FWO.Data.Modelling; +using FWO.Data.Report; +using FWO.Test.Mocks; +using FWO.Ui.Pages.Reporting; +using System.Reflection; + + + +namespace FWO.Test +{ + [TestFixture] + [Parallelizable] + internal class ExportTest + { + static readonly NetworkObject TestIp1 = new() { Id = 1, Name = "TestIp1", IP = "1.2.3.4/32", IpEnd = "1.2.3.4/32", Type = new NetworkObjectType() { Name = ObjectType.Network } }; + static readonly NetworkObject TestIp2 = new() { Id = 2, Name = "TestIp2", IP = "127.0.0.1/32", IpEnd = "127.0.0.1/32", Type = new NetworkObjectType() { Name = ObjectType.Network } }; + static readonly NetworkObject TestIpRange = new() { Id = 3, Name = "TestIpRange", IP = "1.2.3.4/32", IpEnd = "1.2.3.5/32", Type = new NetworkObjectType() { Name = ObjectType.IPRange } }; + static readonly NetworkObject TestIpNew = new() { Id = 4, Name = "TestIpNew", IP = "10.0.6.0/32", IpEnd = "10.0.6.255/32", Type = new NetworkObjectType() { Name = ObjectType.Network } }; + static readonly NetworkObject TestIp1Changed = new() { Id = 5, Name = "TestIp1Changed", IP = "2.3.4.5/32", IpEnd = "2.3.4.5/32", Type = new NetworkObjectType() { Name = ObjectType.Host } }; + + static readonly NetworkService TestService1 = new() { Id = 1, DestinationPort = 443, DestinationPortEnd = 443, Name = "TestService1", Protocol = new NetworkProtocol { Id = 6, Name = "TCP" } }; + static readonly NetworkService TestService2 = new() { Id = 2, DestinationPort = 6666, DestinationPortEnd = 7777, Name = "TestService2", Protocol = new NetworkProtocol { Id = 17, Name = "UDP" } }; + + static readonly NetworkUser TestUser1 = new() { Id = 1, Name = "TestUser1" }; + static readonly NetworkUser TestUser2 = new() { Id = 2, Name = "TestUser2", Type = new NetworkUserType() { Name = ObjectType.Group } }; + + static Rule Rule1 = new(); + static Rule Rule1Changed = new(); + static Rule Rule2 = new(); + static Rule Rule2Changed = new(); + static Rule NatRule = new(); + static Rule RecertRule1 = new(); + static Rule RecertRule2 = new(); + + private const string ToCAnkerIdGroupName = "ToCAnkerId"; + private readonly string ToCRegexPattern = $"(.*?)<\\/a>"; + + private const string StaticAnkerId = "1234-1234-1234-1234"; + + readonly SimulatedUserConfig userConfig = new(); + readonly DynGraphqlQuery query = new("TestFilter") + { + ReportTimeString = "2023-04-20T17:50:04", + }; + readonly TimeFilter timeFilter = new() + { + TimeRangeType = TimeRangeType.Fixeddates, + StartTime = DateTime.Parse("2023-04-19T17:00:04"), + EndTime = DateTime.Parse("2023-04-20T17:00:04") + }; + + [SetUp] + public void Initialize() + { + } + + #region HTML Tests + [Test] + public void RulesGenerateHtml() + { + Log.WriteInfo("Test Log", "starting rules report html generation"); + + var reportRules = ConstructReportRules(query, userConfig, ReportType.Rules, ConstructRuleReportRules(false)); + + string expectedHtmlResult = "Rules Report

                      Rules Report

                      Time of configuration: 2023-04-20T15:50:04Z (UTC)

                      Generated on: Z (UTC)

                      Devices: TestMgt [Mock Device 1]

                      Filter: TestFilter



                      TestMgt


                      Mock Device 1

                      No.NameSource ZoneSourceDestination ZoneDestinationServicesActionTrackEnabledUidCommentLastModified
                      1TestRule1srczn1
                      srczn2
                      srczn3
                       TestIp1 (1.2.3.4/32)
                       TestIp2 (127.0.0.1/32)
                      dstzn1
                      dstzn2
                      dstzn3
                       TestIpRange (1.2.3.4-1.2.3.5) TestService1 (443/TCP)acceptnoneYuid1comment12023-04-05
                      2TestRule2not
                       TestUser1@ TestIp1 (1.2.3.4/32)
                       TestUser1@ TestIp2 (127.0.0.1/32)
                      not
                       TestUser2@ TestIpRange (1.2.3.4-1.2.3.5)
                      not
                       TestService2 (6666-7777/UDP)
                      denynoneYuid2:123comment22023-04-05

                      Network Objects

                      No.NameTypeIP AddressMembersUidComment
                      1TestIp1Network1.2.3.4/32
                      2TestIp2Network127.0.0.1/32
                      3TestIpRangeIP Range1.2.3.4-1.2.3.5

                      Network Services

                      No.NameTypeProtocolPortMembersUidComment
                      1TestService1TCP443
                      2TestService2UDP6666-7777

                      Users

                      No.NameTypeMembersUidComment
                      1TestUser1
                      2TestUser2Group

                      "; + + string reportHtml = RemoveLinebreaks(RemoveGenDate(reportRules.ExportToHtml(), true)); + + IEnumerable matches = reportHtml.GetMatches(ToCRegexPattern, ToCAnkerIdGroupName); + reportHtml = reportHtml.ReplaceAll(matches, StaticAnkerId); + + ClassicAssert.AreEqual(expectedHtmlResult, reportHtml); + } + + [Test] + public void ResolvedRulesGenerateHtml() + { + Log.WriteInfo("Test Log", "starting rules report resolved html generation"); + ReportRules reportRules = ConstructReportRules(query, userConfig, ReportType.ResolvedRules, ConstructRuleReportRules(true)); + + string expectedHtmlResult = "Rules Report (resolved)

                      Rules Report (resolved)

                      Time of configuration: 2023-04-20T15:50:04Z (UTC)

                      Generated on: Z (UTC)

                      Devices: TestMgt [Mock Device 1]

                      Filter: TestFilter


                      Table of content


                      TestMgt


                      Mock Device 1

                      No.NameSource ZoneSourceDestination ZoneDestinationServicesActionTrackEnabledUidCommentLastModified
                      1TestRule1srczn1
                      srczn2
                      srczn3
                      TestIp1 (1.2.3.4/32)
                      TestIp2 (127.0.0.1/32)
                      dstzn1
                      dstzn2
                      dstzn3
                      TestIpRange (1.2.3.4-1.2.3.5)TestService1 (443/TCP)acceptnoneYuid1comment12023-04-05
                      2TestRule2not
                      TestUser1@TestIp1 (1.2.3.4/32)
                      TestUser1@TestIp2 (127.0.0.1/32)
                      not
                      TestUser2@TestIpRange (1.2.3.4-1.2.3.5)
                      not
                      TestService2 (6666-7777/UDP)
                      denynoneYuid2:123comment22023-04-05

                      "; + + string reportHtml = RemoveLinebreaks(RemoveGenDate(reportRules.ExportToHtml(), true)); + + IEnumerable matches = reportHtml.GetMatches(ToCRegexPattern, ToCAnkerIdGroupName); + reportHtml = reportHtml.ReplaceAll(matches, StaticAnkerId); + + ClassicAssert.AreEqual(expectedHtmlResult, reportHtml); + } + + [Test] + public void ResolvedRulesTechGenerateHtml() + { + Log.WriteInfo("Test Log", "starting rules report resolved html generation"); + + ReportRules reportRules = ConstructReportRules(query, userConfig, ReportType.ResolvedRulesTech, ConstructRuleReportRules(true)); + + string expectedHtmlResult = "Rules Report (technical)

                      Rules Report (technical)

                      Time of configuration: 2023-04-20T15:50:04Z (UTC)

                      Generated on: Z (UTC)

                      Devices: TestMgt [Mock Device 1]

                      Filter: TestFilter


                      Table of content


                      TestMgt


                      Mock Device 1

                      No.NameSource ZoneSourceDestination ZoneDestinationServicesActionTrackEnabledUidCommentLastModified
                      1TestRule1srczn1
                      srczn2
                      srczn3
                      1.2.3.4/32
                      127.0.0.1/32
                      dstzn1
                      dstzn2
                      dstzn3
                      1.2.3.4-1.2.3.5443/TCPacceptnoneYuid1comment12023-04-05
                      2TestRule2not
                      TestUser1@1.2.3.4/32
                      TestUser1@127.0.0.1/32
                      not
                      TestUser2@1.2.3.4-1.2.3.5
                      not
                      6666-7777/UDP
                      denynoneYuid2:123comment22023-04-05

                      "; string reportHtml = RemoveLinebreaks(RemoveGenDate(reportRules.ExportToHtml(), true)); + + IEnumerable matches = reportHtml.GetMatches(ToCRegexPattern, ToCAnkerIdGroupName); + reportHtml = reportHtml.ReplaceAll(matches, StaticAnkerId); + + ClassicAssert.AreEqual(expectedHtmlResult, reportHtml); + } + + [Test] + public void UnusedRulesGenerateHtml() + { + Log.WriteInfo("Test Log", "starting unused rules report html generation"); + ReportRules reportRules = ConstructReportRules(query, userConfig, ReportType.UnusedRules, ConstructRuleReportRules(false)); + + string expectedHtmlResult = "Unused Rules Report

                      Unused Rules Report

                      Generated on: Z (UTC)

                      Devices: TestMgt [Mock Device 1]

                      Filter: TestFilter



                      TestMgt


                      Mock Device 1

                      No.Last HitLastModifiedNameSource ZoneSourceDestination ZoneDestinationServicesActionTrackEnabledUidComment
                      12022-04-192023-04-05TestRule1srczn1
                      srczn2
                      srczn3
                       TestIp1 (1.2.3.4/32)
                       TestIp2 (127.0.0.1/32)
                      dstzn1
                      dstzn2
                      dstzn3
                       TestIpRange (1.2.3.4-1.2.3.5) TestService1 (443/TCP)acceptnoneYuid1comment1
                      22023-04-05TestRule2not
                       TestUser1@ TestIp1 (1.2.3.4/32)
                       TestUser1@ TestIp2 (127.0.0.1/32)
                      not
                       TestUser2@ TestIpRange (1.2.3.4-1.2.3.5)
                      not
                       TestService2 (6666-7777/UDP)
                      denynoneYuid2:123comment2

                      Network Objects

                      No.NameTypeIP AddressMembersUidComment
                      1TestIp1Network1.2.3.4/32
                      2TestIp2Network127.0.0.1/32
                      3TestIpRangeIP Range1.2.3.4-1.2.3.5

                      Network Services

                      No.NameTypeProtocolPortMembersUidComment
                      1TestService1TCP443
                      2TestService2UDP6666-7777

                      Users

                      No.NameTypeMembersUidComment
                      1TestUser1
                      2TestUser2Group

                      "; + string reportHtml = RemoveLinebreaks(RemoveGenDate(reportRules.ExportToHtml(), true)); + + IEnumerable matches = reportHtml.GetMatches(ToCRegexPattern, ToCAnkerIdGroupName); + reportHtml = reportHtml.ReplaceAll(matches, StaticAnkerId); + + ClassicAssert.AreEqual(expectedHtmlResult, reportHtml); + } + + [Test] + public void RecertReportGenerateHtml() + { + Log.WriteInfo("Test Log", "starting recert report html generation"); + ReportRules reportRecerts = ConstructReportRules(query, userConfig, ReportType.Recertification, + ConstructRecertReportRules(false)); + + string expectedHtmlResult = "Recertification Report

                      Recertification Report

                      Generated on: Z (UTC)

                      Managements: TestMgt

                      Filter: TestFilter



                      TestMgt


                      Mock Rulebase 2

                      Next Recertification DateOwnerIP address matchLast HitLastModifiedNameSource ZoneSourceDestination ZoneDestinationServicesActionTrackEnabledUidComment

                      1. " + DateOnly.FromDateTime(DateTime.Now.AddDays(5)).ToString("yyyy-MM-dd") + "

                      2. " + DateOnly.FromDateTime(DateTime.Now.AddDays(-5)).ToString("yyyy-MM-dd") + "

                      1. TestOwner1

                      2. TestOwner2

                      1. TestIp1

                      2. TestIp2

                      2022-04-192023-04-05TestRule1srczn1
                      srczn2
                      srczn3
                       TestIp1 (1.2.3.4/32)
                       TestIp2 (127.0.0.1/32)
                      dstzn1
                      dstzn2
                      dstzn3
                       TestIpRange (1.2.3.4-1.2.3.5) TestService1 (443/TCP)acceptnoneYuid1comment1

                      " + DateOnly.FromDateTime(DateTime.Now).ToString("yyyy-MM-dd") + "

                      TestOwner1

                      TestIpRange

                      2023-04-05TestRule2not
                       TestUser1@ TestIp1 (1.2.3.4/32)
                       TestUser1@ TestIp2 (127.0.0.1/32)
                      not
                       TestUser2@ TestIpRange (1.2.3.4-1.2.3.5)
                      not
                       TestService2 (6666-7777/UDP)
                      denynoneYuid2:123comment2

                      Network Objects

                      No.NameTypeIP AddressMembersUidComment
                      1TestIp1Network1.2.3.4/32
                      2TestIp2Network127.0.0.1/32
                      3TestIpRangeIP Range1.2.3.4-1.2.3.5

                      Network Services

                      No.NameTypeProtocolPortMembersUidComment
                      1TestService1TCP443
                      2TestService2UDP6666-7777

                      Users

                      No.NameTypeMembersUidComment
                      1TestUser1
                      2TestUser2Group

                      "; + + string reportHtml = RemoveLinebreaks(RemoveGenDate(reportRecerts.ExportToHtml(), true)); + + IEnumerable matches = reportHtml.GetMatches(ToCRegexPattern, ToCAnkerIdGroupName); + reportHtml = reportHtml.ReplaceAll(matches, StaticAnkerId); + + ClassicAssert.AreEqual(expectedHtmlResult, reportHtml); + } + + [Test, Ignore("temporarily disabled for importer-rework")] + public void NatRulesGenerateHtml() + { + Log.WriteInfo("Test Log", "starting nat rules report html generation"); + ReportNatRules reportNatRules = new(query, userConfig, ReportType.NatRules) + { + ReportData = ConstructNatRuleReport() + }; + + string expectedHtmlResult = "NAT Rules Report

                      NAT Rules Report

                      Time of configuration: 2023-04-20T15:50:04Z (UTC)

                      Generated on: Z (UTC)

                      Devices: TestMgt [TestDev]

                      Filter: TestFilter



                      TestMgt


                      TestDev

                      No.NameSource ZoneSourceDestination ZoneDestinationServicesTranslated SourceTranslated DestinationTranslated ServicesEnabledUidComment
                      1TestRule1srczn TestIp1 (1.2.3.4/32)
                       TestIp2 (127.0.0.1/32)
                      dstzn TestIpRange (1.2.3.4-1.2.3.5) TestService1 (443/TCP) TestUser2@ TestIp1Changed (2.3.4.5)not
                       TestIp1Changed (2.3.4.5)
                       TestIpNew (10.0.6.0/24)
                       TestService1 (443/TCP)
                       TestService2 (6666-7777/UDP)
                      Yuid1comment12023-04-05

                      Network Objects

                      No.NameTypeIP AddressMembersUidComment
                      1TestIp1Network1.2.3.4/32
                      2TestIp2Network127.0.0.1/32
                      3TestIpRangeIP Range1.2.3.4-1.2.3.5
                      4TestIpNewNetwork10.0.6.0/24
                      5TestIp1ChangedHost2.3.4.5

                      Network Services

                      No.NameTypeProtocolPortMembersUidComment
                      1TestService1TCP443
                      2TestService2UDP6666-7777

                      Users

                      No.NameTypeMembersUidComment
                      1TestUser2Group

                      "; + + string reportHtml = RemoveLinebreaks(RemoveGenDate(reportNatRules.ExportToHtml(), true)); + + IEnumerable matches = reportHtml.GetMatches(ToCRegexPattern, ToCAnkerIdGroupName); + reportHtml = reportHtml.ReplaceAll(matches, StaticAnkerId); + + ClassicAssert.AreEqual(expectedHtmlResult, reportHtml); + } + + [Test] + public void ChangesGenerateHtml() + { + Log.WriteInfo("Test Log", "starting changes report html generation"); + ReportChanges reportChanges = new(query, userConfig, ReportType.Changes, timeFilter, false) + { + ReportData = ConstructChangeReport(false) + }; + + string expectedHtmlResult = "Changes Report

                      Changes Report

                      Change Time: from: 2023-04-19T15:00:04Z, until: 2023-04-20T15:00:04Z (UTC)

                      Generated on: Z (UTC)

                      Devices: TestMgt [TestDev]

                      Filter: TestFilter


                      Table of content


                      TestMgt


                      Rules

                      Change TimeChange TypeNameSource ZoneSourceDestination ZoneDestinationServicesActionTrackEnabledenforcing_devicesUidComment
                      05.04.2023 12:00:00Rule added

                      TestRule1

                      srczn1
                      srczn2
                      srczn3

                       TestIp1 (1.2.3.4/32)
                       TestIp2 (127.0.0.1/32)

                      dstzn1
                      dstzn2
                      dstzn3

                       TestIpRange (1.2.3.4-1.2.3.5)

                       TestService1 (443/TCP)

                      accept

                      none

                      Y

                      uid1

                      comment1

                      05.04.2023 12:00:00Rule modifiedTestRule1srczn1
                      srczn2
                      srczn3

                       TestIp2 (127.0.0.1/32)

                      deleted:

                       TestIp1 (1.2.3.4/32)

                      added:

                       TestIp1Changed (2.3.4.5)

                      dstzn1
                      dstzn2
                      dstzn3

                       TestIpRange (1.2.3.4-1.2.3.5)

                      added:

                       TestIpNew (10.0.6.0/24)

                      deleted:

                       TestService1 (443/TCP)

                      added:

                      not
                       TestService1 (443/TCP)

                      acceptnoneYdeleted:

                      uid1

                      deleted:

                      comment1

                      added:

                      new comment

                      05.04.2023 12:00:00Rule modifiedTestRule2not
                       TestUser1@ TestIp1 (1.2.3.4/32)
                       TestUser1@ TestIp2 (127.0.0.1/32)
                      deleted:

                      not
                       TestUser2@ TestIpRange (1.2.3.4-1.2.3.5)

                      added:

                       TestUser2@ TestIpRange (1.2.3.4-1.2.3.5)

                      deleted:

                      not
                       TestService2 (6666-7777/UDP)

                      added:

                       TestService2 (6666-7777/UDP)

                      denynonedeleted:

                      Y

                      added:

                      N

                      uid2:123comment2
                      05.04.2023 12:00:00Rule deleted

                      TestRule2

                      not
                       TestUser1@ TestIp1 (1.2.3.4/32)
                       TestUser1@ TestIp2 (127.0.0.1/32)

                      not
                       TestUser2@ TestIpRange (1.2.3.4-1.2.3.5)

                      not
                       TestService2 (6666-7777/UDP)

                      deny

                      none

                      Y

                      uid2:123

                      comment2


                      "; + + string reportHtml = RemoveLinebreaks(RemoveGenDate(reportChanges.ExportToHtml(), true)); + + IEnumerable matches = reportHtml.GetMatches(ToCRegexPattern, ToCAnkerIdGroupName); + reportHtml = reportHtml.ReplaceAll(matches, StaticAnkerId); + + ClassicAssert.AreEqual(expectedHtmlResult, reportHtml); + } + + [Test] + public void ChangesGenerateHtmlIncludeObjects() + { + Log.WriteInfo("Test Log", "starting changes report html generation"); + ReportChanges reportChanges = new(query, userConfig, ReportType.Changes, timeFilter, true) + { + ReportData = ConstructChangeReport(false) + }; + + string expectedHtmlResult = "Changes Report

                      Changes Report

                      Change Time: from: 2023-04-19T15:00:04Z, until: 2023-04-20T15:00:04Z (UTC)

                      Generated on: Z (UTC)

                      Devices: TestMgt [TestDev]

                      Filter: TestFilter



                      TestMgt


                      Rules

                      Change TimeChange TypeNameSource ZoneSourceDestination ZoneDestinationServicesActionTrackEnabledenforcing_devicesUidComment
                      05.04.2023 12:00:00Rule added

                      TestRule1

                      srczn1
                      srczn2
                      srczn3

                       TestIp1 (1.2.3.4/32)
                       TestIp2 (127.0.0.1/32)

                      dstzn1
                      dstzn2
                      dstzn3

                       TestIpRange (1.2.3.4-1.2.3.5)

                       TestService1 (443/TCP)

                      accept

                      none

                      Y

                      uid1

                      comment1

                      05.04.2023 12:00:00Rule modifiedTestRule1srczn1
                      srczn2
                      srczn3

                       TestIp2 (127.0.0.1/32)

                      deleted:

                       TestIp1 (1.2.3.4/32)

                      added:

                       TestIp1Changed (2.3.4.5)

                      dstzn1
                      dstzn2
                      dstzn3

                       TestIpRange (1.2.3.4-1.2.3.5)

                      added:

                       TestIpNew (10.0.6.0/24)

                      deleted:

                       TestService1 (443/TCP)

                      added:

                      not
                       TestService1 (443/TCP)

                      acceptnoneYdeleted:

                      uid1

                      deleted:

                      comment1

                      added:

                      new comment

                      05.04.2023 12:00:00Rule modifiedTestRule2not
                       TestUser1@ TestIp1 (1.2.3.4/32)
                       TestUser1@ TestIp2 (127.0.0.1/32)
                      deleted:

                      not
                       TestUser2@ TestIpRange (1.2.3.4-1.2.3.5)

                      added:

                       TestUser2@ TestIpRange (1.2.3.4-1.2.3.5)

                      deleted:

                      not
                       TestService2 (6666-7777/UDP)

                      added:

                       TestService2 (6666-7777/UDP)

                      denynonedeleted:

                      Y

                      added:

                      N

                      uid2:123comment2
                      05.04.2023 12:00:00Rule deleted

                      TestRule2

                      not
                       TestUser1@ TestIp1 (1.2.3.4/32)
                       TestUser1@ TestIp2 (127.0.0.1/32)

                      not
                       TestUser2@ TestIpRange (1.2.3.4-1.2.3.5)

                      not
                       TestService2 (6666-7777/UDP)

                      deny

                      none

                      Y

                      uid2:123

                      comment2


                      Network objects

                      Change TimeChange TypeNameTypeIP AddressMembersUidComment
                      05.04.2023 12:00:00network_object_added

                      TestIp1

                      network

                      (1.2.3.4)

                      05.04.2023 12:00:00network_object_modifieddeleted:

                      TestIp1

                      added:

                      TestIp1Changed

                      deleted:

                      network

                      added:

                      host

                      deleted:

                      (1.2.3.4)

                      added:

                      (2.3.4.5)

                      05.04.2023 12:00:00network_object_deleted

                      TestIp2

                      network

                      (127.0.0.1)


                      Service objects

                      Change TimeChange TypeNameTypeProtocolPortMembersUidComment
                      05.04.2023 12:00:00service_added

                      TestService1

                      TCP

                      (443)

                      05.04.2023 12:00:00service_modifieddeleted:

                      TestService1

                      added:

                      TestService2

                      deleted:

                      TCP

                      added:

                      UDP

                      deleted:

                      (443)

                      added:

                      (6666-7777)

                      05.04.2023 12:00:00service_deleted

                      TestService1

                      TCP

                      (443)


                      "; + + string reportHtml = RemoveLinebreaks(RemoveGenDate(reportChanges.ExportToHtml(), true)); + + IEnumerable matches = reportHtml.GetMatches(ToCRegexPattern, ToCAnkerIdGroupName); + reportHtml = reportHtml.ReplaceAll(matches, StaticAnkerId); + + ClassicAssert.AreEqual(expectedHtmlResult, reportHtml); + } + + [Test] + public void ResolvedChangesGenerateHtml() + { + Log.WriteInfo("Test Log", "starting changes report resolved html generation"); + ReportChanges reportChanges = new(query, userConfig, ReportType.ResolvedChanges, timeFilter, false) + { + ReportData = ConstructChangeReport(true) + }; + + string expectedHtmlResult = "Changes Report (resolved)

                      Changes Report (resolved)

                      Change Time: from: 2023-04-19T15:00:04Z, until: 2023-04-20T15:00:04Z (UTC)

                      Generated on: Z (UTC)

                      Devices: TestMgt [TestDev]

                      Filter: TestFilter


                      Table of content


                      TestMgt


                      Rules

                      Change TimeChange TypeNameSource ZoneSourceDestination ZoneDestinationServicesActionTrackEnabledenforcing_devicesUidComment
                      05.04.2023 12:00:00Rule added

                      TestRule1

                      srczn1
                      srczn2
                      srczn3

                      TestIp1 (1.2.3.4/32)
                      TestIp2 (127.0.0.1/32)

                      dstzn1
                      dstzn2
                      dstzn3

                      TestIpRange (1.2.3.4-1.2.3.5)

                      TestService1 (443/TCP)

                      accept

                      none

                      Y

                      uid1

                      comment1

                      05.04.2023 12:00:00Rule modifiedTestRule1srczn1
                      srczn2
                      srczn3

                      TestIp2 (127.0.0.1/32)

                      deleted:

                      TestIp1 (1.2.3.4/32)

                      added:

                      TestIp1Changed (2.3.4.5)

                      dstzn1
                      dstzn2
                      dstzn3

                      TestIpRange (1.2.3.4-1.2.3.5)

                      added:

                      TestIpNew (10.0.6.0/24)

                      deleted:

                      TestService1 (443/TCP)

                      added:

                      not
                      TestService1 (443/TCP)

                      acceptnoneYdeleted:

                      uid1

                      deleted:

                      comment1

                      added:

                      new comment

                      05.04.2023 12:00:00Rule modifiedTestRule2not
                      TestUser1@TestIp1 (1.2.3.4/32)
                      TestUser1@TestIp2 (127.0.0.1/32)
                      deleted:

                      not
                      TestUser2@TestIpRange (1.2.3.4-1.2.3.5)

                      added:

                      TestUser2@TestIpRange (1.2.3.4-1.2.3.5)

                      deleted:

                      not
                      TestService2 (6666-7777/UDP)

                      added:

                      TestService2 (6666-7777/UDP)

                      denynonedeleted:

                      Y

                      added:

                      N

                      uid2:123comment2
                      05.04.2023 12:00:00Rule deleted

                      TestRule2

                      not
                      TestUser1@TestIp1 (1.2.3.4/32)
                      TestUser1@TestIp2 (127.0.0.1/32)

                      not
                      TestUser2@TestIpRange (1.2.3.4-1.2.3.5)

                      not
                      TestService2 (6666-7777/UDP)

                      deny

                      none

                      Y

                      uid2:123

                      comment2


                      "; + + string reportHtml = RemoveLinebreaks(RemoveGenDate(reportChanges.ExportToHtml(), true)); + + IEnumerable matches = reportHtml.GetMatches(ToCRegexPattern, ToCAnkerIdGroupName); + reportHtml = reportHtml.ReplaceAll(matches, StaticAnkerId); + + ClassicAssert.AreEqual(expectedHtmlResult, reportHtml); + } + + [Test] + public void ResolvedChangesTechGenerateHtml() + { + Log.WriteInfo("Test Log", "starting changes report tech html generation"); + ReportChanges reportChanges = new(query, userConfig, ReportType.ResolvedChangesTech, timeFilter, false) + { + ReportData = ConstructChangeReport(true) + }; + + string expectedHtmlResult = "Changes Report (technical)

                      Changes Report (technical)

                      Change Time: from: 2023-04-19T15:00:04Z, until: 2023-04-20T15:00:04Z (UTC)

                      Generated on: Z (UTC)

                      Devices: TestMgt [TestDev]

                      Filter: TestFilter


                      Table of content


                      TestMgt


                      Rules

                      Change TimeChange TypeNameSource ZoneSourceDestination ZoneDestinationServicesActionTrackEnabledenforcing_devicesUidComment
                      05.04.2023 12:00:00Rule added

                      TestRule1

                      srczn1
                      srczn2
                      srczn3

                      1.2.3.4/32
                      127.0.0.1/32

                      dstzn1
                      dstzn2
                      dstzn3

                      1.2.3.4-1.2.3.5

                      443/TCP

                      accept

                      none

                      Y

                      uid1

                      comment1

                      05.04.2023 12:00:00Rule modifiedTestRule1srczn1
                      srczn2
                      srczn3

                      127.0.0.1/32

                      deleted:

                      1.2.3.4/32

                      added:

                      2.3.4.5

                      dstzn1
                      dstzn2
                      dstzn3

                      1.2.3.4-1.2.3.5

                      added:

                      10.0.6.0/24

                      deleted:

                      443/TCP

                      added:

                      not
                      443/TCP

                      acceptnoneYdeleted:

                      uid1

                      deleted:

                      comment1

                      added:

                      new comment

                      05.04.2023 12:00:00Rule modifiedTestRule2not
                      TestUser1@1.2.3.4/32
                      TestUser1@127.0.0.1/32
                      deleted:

                      not
                      TestUser2@1.2.3.4-1.2.3.5

                      added:

                      TestUser2@1.2.3.4-1.2.3.5

                      deleted:

                      not
                      6666-7777/UDP

                      added:

                      6666-7777/UDP

                      denynonedeleted:

                      Y

                      added:

                      N

                      uid2:123comment2
                      05.04.2023 12:00:00Rule deleted

                      TestRule2

                      not
                      TestUser1@1.2.3.4/32
                      TestUser1@127.0.0.1/32

                      not
                      TestUser2@1.2.3.4-1.2.3.5

                      not
                      6666-7777/UDP

                      deny

                      none

                      Y

                      uid2:123

                      comment2


                      "; + + string reportHtml = RemoveLinebreaks(RemoveGenDate(reportChanges.ExportToHtml(), true)); + + IEnumerable matches = reportHtml.GetMatches(ToCRegexPattern, ToCAnkerIdGroupName); + reportHtml = reportHtml.ReplaceAll(matches, StaticAnkerId); + + ClassicAssert.AreEqual(expectedHtmlResult, reportHtml); + } + + [Test] + public async Task AppRulesGenerateHtml() + { + Log.WriteInfo("Test Log", "starting AppRules report html generation"); + var reportRules = await ConstructAppReportRules(query, userConfig, ReportType.AppRules, ConstructRuleReportRules(false)); + string expectedHtmlResult = "App Rules

                      App Rules

                      Generated on: Z (UTC)

                      Managements: TestMgt

                      Filter: TestFilter


                      Table of content


                      TestMgt


                      Mock Rulebase 1

                      NameSource ZoneSourceDestination ZoneDestinationServicesActionTrackEnabledUidCommentLastModified
                      TestRule1srczn1
                      srczn2
                      srczn3
                       TestIp1 (1.2.3.4/32)
                      ... (1 more)
                      dstzn1
                      dstzn2
                      dstzn3
                       TestIpRange (1.2.3.4-1.2.3.5) TestService1 (443/TCP)acceptnoneYuid1comment12023-04-05

                      "; + string reportHtml = RemoveLinebreaks(RemoveGenDate(reportRules.ExportToHtml(), true)); + + IEnumerable matches = reportHtml.GetMatches(ToCRegexPattern, ToCAnkerIdGroupName); + reportHtml = reportHtml.ReplaceAll(matches, StaticAnkerId); + + ClassicAssert.AreEqual(expectedHtmlResult, reportHtml); + } + + [Test] + public void OwnerRecertificationSupportsCsvExport() + { + ClassicAssert.IsTrue(ReportType.OwnerRecertification.SupportsCsvExport()); + } + + [Test] + public void OwnerRecertificationGenerateCsv() + { + ReportOwnerRecerts report = new(query, userConfig, ReportType.OwnerRecertification) + { + ReportData = ConstructOwnerRecertReport() + }; + + string csv = report.ExportToCsv(); + + StringAssert.Contains("# Statistics", csv); + StringAssert.Contains("# Overdue owners: 1", csv); + StringAssert.Contains("# Owners due within 7 days: 1", csv); + StringAssert.Contains("# Further active owners: 1", csv); + StringAssert.Contains("# Owners with inactive recertification: 1", csv); + StringAssert.Contains("\"Next Recertification Date\",\"Id\",\"Name\",\"Last Recertified\",\"Last Recertifier\",", csv); + StringAssert.Contains("\"EXT-OVERDUE\",\"Overdue Owner\",", csv); + StringAssert.Contains("\"EXT-UPCOMING\",\"Upcoming Owner\",", csv); + StringAssert.Contains("\"EXT-FURTHER\",\"Further Owner\",", csv); + StringAssert.Contains("# Owners with inactive recertification", csv); + StringAssert.Contains("\"Id\",\"Name\",", csv); + StringAssert.Contains("\"EXT-INACTIVE\",\"Inactive Owner\",", csv); + } + + [Test] + public void OwnerRecertificationGenerateCsvWithoutUpcomingSectionForZeroDisplayPeriod() + { + ReportOwnerRecerts report = new(query, userConfig, ReportType.OwnerRecertification) + { + ReportData = ConstructOwnerRecertReport(0) + }; + + string csv = report.ExportToCsv(); + + StringAssert.Contains("# Overdue owners: 1", csv); + StringAssert.DoesNotContain("# Owners due within 0 days", csv); + StringAssert.DoesNotContain("# No owners due within 0 days.", csv); + } + + [Test] + public void OwnerRecertificationGenerateHtmlIncludesStatisticsAndInactiveSection() + { + ReportOwnerRecerts report = new(query, userConfig, ReportType.OwnerRecertification) + { + ReportData = ConstructOwnerRecertReport() + }; + + string html = report.ExportToHtml(); + + StringAssert.Contains("Statistics", html); + StringAssert.Contains("
                    • Overdue owners: 1
                    • ", html); + StringAssert.Contains("
                    • Owners due within 7 days: 1
                    • ", html); + StringAssert.Contains("
                    • Further active owners: 1
                    • ", html); + StringAssert.Contains("
                    • Owners with inactive recertification: 1
                    • ", html); + StringAssert.Contains(">Owners with inactive recertification", html); + StringAssert.Contains("IdName", RemoveLinebreaks(html)); + StringAssert.DoesNotContain("Last RecertifiedLast RecertifierEXT-INACTIVE", RemoveLinebreaks(html)); + } + + [Test] + public void OwnerRecertificationGenerateHtmlWithoutUpcomingSectionForZeroDisplayPeriod() + { + ReportOwnerRecerts report = new(query, userConfig, ReportType.OwnerRecertification) + { + ReportData = ConstructOwnerRecertReport(0) + }; + + string html = report.ExportToHtml(); + + StringAssert.DoesNotContain(">Owners due within 0 days", html); + StringAssert.DoesNotContain("
                    • Owners due within 0 days:", html); + StringAssert.DoesNotContain("No owners due within 0 days.", html); + } + + [Test] + public void OwnerRecertificationUsesAlternativeFurtherHeadlineWhenNextRecertDateIsMissing() + { + ReportOwnerRecerts report = new(query, userConfig, ReportType.OwnerRecertification) + { + ReportData = ConstructOwnerRecertReport(withNullFurtherDate: true) + }; + + string csv = report.ExportToCsv(); + + StringAssert.Contains("# Further owners: 1", csv); + StringAssert.DoesNotContain("# Further active owners: 1", csv); + } + + [Test] + public void OwnerRecertificationInactiveOwnersAreOrderedByIdInCsv() + { + ReportOwnerRecerts report = new(query, userConfig, ReportType.OwnerRecertification) + { + ReportData = ConstructOwnerRecertReport(withMultipleInactiveOwners: true) + }; + + string csv = report.ExportToCsv(); + int firstInactive = csv.IndexOf("\"EXT-INACTIVE-LOW\",\"Inactive Owner Low\",", StringComparison.Ordinal); + int secondInactive = csv.IndexOf("\"EXT-INACTIVE\",\"Inactive Owner\",", StringComparison.Ordinal); + + Assert.That(firstInactive, Is.GreaterThanOrEqualTo(0)); + Assert.That(secondInactive, Is.GreaterThanOrEqualTo(0)); + Assert.That(firstInactive, Is.LessThan(secondInactive)); + } + + [Test] + public void OwnersGenerateCsvAndHtml() + { + ReportOwners report = new(query, userConfig, ReportType.Owners) + { + ReportData = new ReportData() + { + OwnerData = + [ + new OwnerConnectionReport() + { + Owner = new FwoOwner() + { + ExtAppId = "APP-1", + Name = "Owner One", + Criticality = "High", + OwnerLifeCycleStateId = 1, + AdditionalInfo = new Dictionary() { { "department", "IT" }, { "region", "EU" } }, + OwnerResponsibles = + [ + new OwnerResponsible(){ Dn = "cn=user1,ou=users,dc=test", ResponsibleTypeId = 1 }, + new OwnerResponsible(){ Dn = "cn=user2,ou=users,dc=test", ResponsibleTypeId = 2 } + ] + } + } + ] + } + }; + SetPrivateField(report, "ownerLifeCycleStates", new Dictionary { { 1, "Active" } }); + SetPrivateField(report, "ownerResponsibleTypes", new List + { + new OwnerResponsibleType() { Id = 1, Name = "Main", Active = true, SortOrder = 1 }, + new OwnerResponsibleType() { Id = 2, Name = "Backup", Active = true, SortOrder = 2 } + }); + + string csv = report.ExportToCsv(); + string html = RemoveLinebreaks(report.ExportToHtml()); + + StringAssert.Contains("\"Id\",\"Name\",\"Criticality\",\"State\",\"Main\",\"Backup\",\"Additional Info\",", csv); + StringAssert.Contains("\"APP-1\",\"Owner One\",\"High\",\"Active\",\"user1\",\"user2\",\"department: IT; region: EU\",", csv); + StringAssert.Contains("IdNameCriticalityStateMainBackupAdditional Info", html); + StringAssert.Contains("APP-1Owner OneHighActiveuser1user2department: IT
                      region: EU", html); + } + + private static void SetPrivateField(object target, string fieldName, T value) + { + FieldInfo? field = target.GetType().GetField(fieldName, BindingFlags.NonPublic | BindingFlags.Instance); + if (field == null) + { + throw new MissingFieldException(target.GetType().FullName, fieldName); + } + field.SetValue(target, value); + } + + [Test] + public void ConnectionsGenerateHtml() + { + Log.WriteInfo("Test Log", "starting connection report html generation"); + ReportConnections reportConnections = new(query, userConfig, ReportType.Connections) + { + ReportData = ConstructConnectionReport() + }; + + string expectedHtmlResult = "Connections Report

                      Connections Report

                      Generated on: Z (UTC)

                      Owners: TestOwner

                      Filter: TestFilter



                      TestOwner (APP-1234)

                      Connections

                      No.IdNameFunctional ReasonSourceServicesDestination
                      1101Conn1 AppServer1 (1.0.0.0) ServiceGroup1
                       Service1 (1234/TCP)
                       AppRole1 (AR1)

                      Interfaces

                      No.IdInterface PermissionNameInterface DescriptionSourceServicesDestination
                      1102PublicInter2 
                       Service2 (2345/UDP)
                       noRole ()
                       AppServer2 (2.0.0.0)

                      Own Common Services

                      No.IdNameFunctional ReasonSourceServicesDestination
                      1103ComSvc3 AppServer1 (1.0.0.0) 
                       Service2 (2345/UDP)
                       AppServer2 (2.0.0.0)

                      Network Objects

                      No.IdNameIpMembers
                      121AppRole1 (AR1)AppServer1
                      211AppServer11.0.0.0
                      30noRole ()
                      412AppServer22.0.0.0

                      Network Services

                      No.IdNameProtocolPortMembers
                      141ServiceGroup1Service1
                      231Service1TCP1234
                      30
                      432Service2UDP2345


                      Global Common Services

                      No.IdOwnerNameFunctional ReasonSourceServicesDestination
                      1103App1ComSvc3 AppServer1 (1.0.0.0) 
                       Service2 (2345/UDP)
                       AppServer2 (2.0.0.0)

                      Network Objects

                      No.IdNameIpMembers
                      111AppServer11.0.0.0
                      212AppServer22.0.0.0

                      Network Services

                      No.IdNameProtocolPortMembers
                      10
                      232Service2UDP2345

                      "; + + string reportHtml = RemoveLinebreaks(RemoveGenDate(reportConnections.ExportToHtml(), true)); + + IEnumerable matches = reportHtml.GetMatches(ToCRegexPattern, ToCAnkerIdGroupName); + reportHtml = reportHtml.ReplaceAll(matches, StaticAnkerId); + + ClassicAssert.AreEqual(expectedHtmlResult, reportHtml); + } + + [Test] + public void VariancesGenerateHtml() + { + // TODO: to be enhanced + Log.WriteInfo("Test Log", "starting variance report html generation"); + ReportVariances reportVariances = new(query, userConfig, ReportType.VarianceAnalysis) + { + ReportData = ConstructVarianceReport() + }; + + string expectedHtmlResult = $$"""VarianceAnalysis""" + + $$"""

                      VarianceAnalysis

                      Generated on: Z (UTC)

                      Owners: TestOwner

                      Filter: TestFilter



                      In this report...
                      """ + + $$"""

                      TestOwner

                      fullymodelledImplementedNot ImplementedWith Diffs
                      AppRoles2011
                      Connections2011

                      """ + + $$"""

                      AppRoles Not Implemented

                      No.IdNameMembers
                      121AppRole1AppServer1 (1.0.0.0)


                      """ + + $$"""

                      AppRoles With Diffs

                      No.IdNameMissing App ServersSurplus App Servers
                      122AppRole2AppServer2 (2.0.0.0)


                      """ + + $$"""

                      Connections not implemented

                      Connections
                      """ + + $$"""
                      No.IdNameFunctional ReasonSourceServicesDestination
                      1101Conn1Area50 (NA50)
                      AppRole1 (AR1)
                      AppServer1 (1.0.0.0)
                      ServiceGroup1
                      Service1 (1234/TCP)
                      AppRole2 (AR2)

                      """ + + $$"""

                      Connections with Diffs

                      Conn2
                      """ + + $$"""
                      IdNameFunctional ReasonSourceServicesDestination
                      102Conn2AppServer1 (1.0.0.0)Service1 (1234/TCP)AppRole2 (AR2)
                      """ + + $$"""
                      ManagementGatewaySourceServicesDestination





                      """ + + $$"""

                      Network Objects

                      """ + + $$"""""" + + $$"""
                      No.IdNameIpMembers
                      151Area50 (NA50)...
                      221AppRole1 (AR1)AppServer1
                      311AppServer11.0.0.0
                      422AppRole2 (AR2)AppServer2
                      512AppServer22.0.0.0

                      """ + + $$"""

                      Network Services

                      """ + + $$"""
                      No.IdNameProtocolPortMembers
                      141ServiceGroup1Service1
                      231Service1TCP1234


                      """; + + string reportHtml = RemoveLinebreaks(RemoveGenDate(reportVariances.ExportToHtml(), true)); + IEnumerable matches = reportHtml.GetMatches(ToCRegexPattern, ToCAnkerIdGroupName); + reportHtml = reportHtml.ReplaceAll(matches, StaticAnkerId); + + ClassicAssert.AreEqual(expectedHtmlResult, reportHtml); + + userConfig.ResolveNetworkAreas = true; + reportVariances = new(query, userConfig, ReportType.VarianceAnalysis) + { + ReportData = ConstructVarianceReport() + }; + string expectedHtmlResult2 = "VarianceAnalysis

                      VarianceAnalysis

                      Generated on: Z (UTC)

                      Owners: TestOwner

                      Filter: TestFilter



                      In this report...

                      TestOwner

                      fullymodelledImplementedNot ImplementedWith Diffs
                      AppRoles2011
                      Connections2011

                      AppRoles Not Implemented

                      No.IdNameMembers
                      121AppRole1AppServer1 (1.0.0.0)


                      AppRoles With Diffs

                      No.IdNameMissing App ServersSurplus App Servers
                      122AppRole2AppServer2 (2.0.0.0)


                      Connections not implemented

                      Connections
                      No.IdNameFunctional ReasonSourceServicesDestination
                      1101Conn1Area50 (NA50)
                      AppRole1 (AR1)
                      AppServer1 (1.0.0.0)
                      ServiceGroup1
                      Service1 (1234/TCP)
                      AppRole2 (AR2)

                      Connections with Diffs

                      Conn2
                      IdNameFunctional ReasonSourceServicesDestination
                      102Conn2AppServer1 (1.0.0.0)Service1 (1234/TCP)AppRole2 (AR2)
                      ManagementGatewaySourceServicesDestination





                      Network Objects

                      No.IdNameIpMembers
                      151Area50 (NA50)Net1
                      21Net11.0.0.0
                      321AppRole1 (AR1)AppServer1
                      411AppServer11.0.0.0
                      522AppRole2 (AR2)AppServer2
                      612AppServer22.0.0.0

                      Network Services

                      No.IdNameProtocolPortMembers
                      141ServiceGroup1Service1
                      231Service1TCP1234


                      "; + reportHtml = RemoveLinebreaks(RemoveGenDate(reportVariances.ExportToHtml(), true)); + matches = reportHtml.GetMatches(ToCRegexPattern, ToCAnkerIdGroupName); + reportHtml = reportHtml.ReplaceAll(matches, StaticAnkerId); + + ClassicAssert.AreEqual(expectedHtmlResult2, reportHtml); + } + #endregion + #region CSV Tests + [Test] + public void ResolvedRulesGenerateCsv() + { + Log.WriteInfo("Test Log", "starting rules report resolved csv generation"); + ReportRules reportRules = ConstructReportRules(query, userConfig, ReportType.ResolvedRules, ConstructRuleReportRules(true)); + + string expectedCsvResult = "# report type: Rules Report (resolved)" + + "# report generation date: Z (UTC)" + + "# date of configuration shown: 2023-04-20T15:50:04Z (UTC)" + + "# device filter: TestMgt [Mock Device 1]" + + "# other filters: TestFilter" + + "# report generator: Firewall Orchestrator - https://fwo.cactus.de/en" + + "# data protection level: For internal use only#" + + "\"management-name\",\"device-name\",\"rule-number\",\"rule-name\",\"source-zone\",\"source\",\"destination-zone\",\"destination\",\"service\",\"action\",\"track\",\"rule-enabled\",\"rule-uid\",\"rule-comment\",\"last-modified\"" + + "\"TestMgt\",\"Mock Device 1\",\"1\",\"TestRule1\",\"\"srczn1\",\"srczn2\",\"srczn3\"\",\"TestIp1 (1.2.3.4/32),TestIp2 (127.0.0.1/32)\",\"\"dstzn1\",\"dstzn2\",\"dstzn3\"\",\"TestIpRange (1.2.3.4-1.2.3.5)\",\"TestService1 (443/TCP)\",\"accept\",\"none\",\"enabled\",\"uid1\",\"comment1\",\"2023-04-05\"" + + "\"TestMgt\",\"Mock Device 1\",\"\",\"TestRule2\",\"\",\"not(TestUser1@TestIp1 (1.2.3.4/32),TestUser1@TestIp2 (127.0.0.1/32))\",\"\",\"not(TestUser2@TestIpRange (1.2.3.4-1.2.3.5))\",\"not(TestService2 (6666-7777/UDP))\",\"deny\",\"none\",\"enabled\",\"uid2:123\",\"comment2\",\"2023-04-05\""; + string csvExport = RemoveLinebreaks(RemoveGenDate(reportRules.ExportToCsv())); + ClassicAssert.AreEqual(expectedCsvResult, csvExport); + } + + [Test] + public void ResolvedRulesTechGenerateCsv() + { + Log.WriteInfo("Test Log", "starting rules report tech csv generation"); + ReportRules reportRules = ConstructReportRules(query, userConfig, ReportType.ResolvedRulesTech, ConstructRuleReportRules(true)); + + string expectedCsvResult = "# report type: Rules Report (technical)" + + "# report generation date: Z (UTC)" + + "# date of configuration shown: 2023-04-20T15:50:04Z (UTC)" + + "# device filter: TestMgt [Mock Device 1]" + + "# other filters: TestFilter" + + "# report generator: Firewall Orchestrator - https://fwo.cactus.de/en" + + "# data protection level: For internal use only#" + + "\"management-name\",\"device-name\",\"rule-number\",\"rule-name\",\"source-zone\",\"source\",\"destination-zone\",\"destination\",\"service\",\"action\",\"track\",\"rule-enabled\",\"rule-uid\",\"rule-comment\",\"last-modified\"" + + "\"TestMgt\",\"Mock Device 1\",\"1\",\"TestRule1\",\"\"srczn1\",\"srczn2\",\"srczn3\"\",\"1.2.3.4/32,127.0.0.1/32\",\"\"dstzn1\",\"dstzn2\",\"dstzn3\"\",\"1.2.3.4-1.2.3.5\",\"443/TCP\",\"accept\",\"none\",\"enabled\",\"uid1\",\"comment1\",\"2023-04-05\"" + + "\"TestMgt\",\"Mock Device 1\",\"\",\"TestRule2\",\"\",\"not(TestUser1@1.2.3.4/32,TestUser1@127.0.0.1/32)\",\"\",\"not(TestUser2@1.2.3.4-1.2.3.5)\",\"not(6666-7777/UDP)\",\"deny\",\"none\",\"enabled\",\"uid2:123\",\"comment2\",\"2023-04-05\""; + ClassicAssert.AreEqual(expectedCsvResult, RemoveLinebreaks(RemoveGenDate(reportRules.ExportToCsv()))); + } + + [Test] + public void ResolvedChangesGenerateCsv() + { + Log.WriteInfo("Test Log", "starting changes report resolved csv generation"); + ReportChanges reportChanges = new(query, userConfig, ReportType.ResolvedChanges, new TimeFilter(), false) + { + ReportData = ConstructChangeReport(true) + }; + + string expectedCsvResult = "# report type: Changes Report (resolved)" + + "# report generation date: Z (UTC)" + + "# device filter: TestMgt [TestDev]" + + "# other filters: TestFilter" + + "# report generator: Firewall Orchestrator - https://fwo.cactus.de/en" + + "# data protection level: For internal use only#\"Rules\"" + + "\"management-name\",\"change-time\",\"change-type\",\"rule-name\",\"source-zone\",\"source\",\"destination-zone\",\"destination\",\"service\",\"action\",\"track\",\"rule-enabled\",\"enforcing_device\",\"rule-uid\",\"rule-comment\"" + + "\"TestMgt\",\"05.04.2023 12:00:00\",\"Rule added\",\"TestRule1\",\"\"srczn1\",\"srczn2\",\"srczn3\"\",\"TestIp1 (1.2.3.4/32),TestIp2 (127.0.0.1/32)\"," + + "\"\"dstzn1\",\"dstzn2\",\"dstzn3\"\",\"TestIpRange (1.2.3.4-1.2.3.5)\",\"TestService1 (443/TCP)\",\"accept\",\"none\",\"enabled\",\"\",\"uid1\",\"comment1\"" + + "\"TestMgt\",\"05.04.2023 12:00:00\",\"Rule modified\",\"TestRule1\",\"\"srczn1\",\"srczn2\",\"srczn3\"\",\"TestIp2 (127.0.0.1/32) deleted: TestIp1 (1.2.3.4/32) added: TestIp1Changed (2.3.4.5)\"," + + "\"\"dstzn1\",\"dstzn2\",\"dstzn3\"\",\"TestIpRange (1.2.3.4-1.2.3.5) added: TestIpNew (10.0.6.0/24)\"," + + "\" deleted: TestService1 (443/TCP) added: not(TestService1 (443/TCP))\",\"accept\",\"none\",\"enabled\",\"\",\" deleted: uid1\",\" deleted: comment1 added: new comment\"" + + "\"TestMgt\",\"05.04.2023 12:00:00\",\"Rule modified\",\"TestRule2\",\"\",\"not(TestUser1@TestIp1 (1.2.3.4/32),TestUser1@TestIp2 (127.0.0.1/32))\"," + + "\"\",\" deleted: not(TestUser2@TestIpRange (1.2.3.4-1.2.3.5)) added: TestUser2@TestIpRange (1.2.3.4-1.2.3.5)\"," + + "\" deleted: not(TestService2 (6666-7777/UDP)) added: TestService2 (6666-7777/UDP)\",\"deny\",\"none\",\" deleted: enabled added: disabled\",\"\",\"uid2:123\",\"comment2\"" + + "\"TestMgt\",\"05.04.2023 12:00:00\",\"Rule deleted\",\"TestRule2\",\"\",\"not(TestUser1@TestIp1 (1.2.3.4/32),TestUser1@TestIp2 (127.0.0.1/32))\"," + + "\"\",\"not(TestUser2@TestIpRange (1.2.3.4-1.2.3.5))\",\"not(TestService2 (6666-7777/UDP))\",\"deny\",\"none\",\"enabled\",\"\",\"uid2:123\",\"comment2\""; + ClassicAssert.AreEqual(expectedCsvResult, RemoveLinebreaks(RemoveGenDate(reportChanges.ExportToCsv()))); + } + + [Test] + public void ResolvedChangesGenerateCsvIncludeObjects() + { + Log.WriteInfo("Test Log", "starting changes report resolved csv generation"); + ReportChanges reportChanges = new(query, userConfig, ReportType.ResolvedChanges, new TimeFilter(), true) + { + ReportData = ConstructChangeReport(true) + }; + + string expectedCsvResult = "# report type: Changes Report (resolved)" + + "# report generation date: Z (UTC)" + + "# device filter: TestMgt [TestDev]" + + "# other filters: TestFilter" + + "# report generator: Firewall Orchestrator - https://fwo.cactus.de/en" + + "# data protection level: For internal use only#\"Rules\"" + + "\"management-name\",\"change-time\",\"change-type\",\"rule-name\",\"source-zone\",\"source\",\"destination-zone\",\"destination\",\"service\",\"action\",\"track\",\"rule-enabled\",\"enforcing_device\",\"rule-uid\",\"rule-comment\"" + + "\"TestMgt\",\"05.04.2023 12:00:00\",\"Rule added\",\"TestRule1\",\"\"srczn1\",\"srczn2\",\"srczn3\"\",\"TestIp1 (1.2.3.4/32),TestIp2 (127.0.0.1/32)\"," + + "\"\"dstzn1\",\"dstzn2\",\"dstzn3\"\",\"TestIpRange (1.2.3.4-1.2.3.5)\",\"TestService1 (443/TCP)\",\"accept\",\"none\",\"enabled\",\"\",\"uid1\",\"comment1\"" + + "\"TestMgt\",\"05.04.2023 12:00:00\",\"Rule modified\",\"TestRule1\",\"\"srczn1\",\"srczn2\",\"srczn3\"\",\"TestIp2 (127.0.0.1/32) deleted: TestIp1 (1.2.3.4/32) added: TestIp1Changed (2.3.4.5)\"," + + "\"\"dstzn1\",\"dstzn2\",\"dstzn3\"\",\"TestIpRange (1.2.3.4-1.2.3.5) added: TestIpNew (10.0.6.0/24)\"," + + "\" deleted: TestService1 (443/TCP) added: not(TestService1 (443/TCP))\",\"accept\",\"none\",\"enabled\",\"\",\" deleted: uid1\",\" deleted: comment1 added: new comment\"" + + "\"TestMgt\",\"05.04.2023 12:00:00\",\"Rule modified\",\"TestRule2\",\"\",\"not(TestUser1@TestIp1 (1.2.3.4/32),TestUser1@TestIp2 (127.0.0.1/32))\"," + + "\"\",\" deleted: not(TestUser2@TestIpRange (1.2.3.4-1.2.3.5)) added: TestUser2@TestIpRange (1.2.3.4-1.2.3.5)\"," + + "\" deleted: not(TestService2 (6666-7777/UDP)) added: TestService2 (6666-7777/UDP)\",\"deny\",\"none\",\" deleted: enabled added: disabled\",\"\",\"uid2:123\",\"comment2\"" + + "\"TestMgt\",\"05.04.2023 12:00:00\",\"Rule deleted\",\"TestRule2\",\"\",\"not(TestUser1@TestIp1 (1.2.3.4/32),TestUser1@TestIp2 (127.0.0.1/32))\"," + + "\"\",\"not(TestUser2@TestIpRange (1.2.3.4-1.2.3.5))\",\"not(TestService2 (6666-7777/UDP))\",\"deny\",\"none\",\"enabled\",\"\",\"uid2:123\",\"comment2\"" + + "#\"Network objects\"\"management-name\",\"change-time\",\"change-type\",\"object-name\",\"type\",\"ip_address\",\"members\",\"object-uid\",\"object-comment\"\"TestMgt\",\"05.04.2023 12:00:00\"," + + "\"network_object_added\",\"TestIp1\",\"network\",\" (1.2.3.4)\",\"\",\"\",\"\"\"TestMgt\",\"05.04.2023 12:00:00\",\"network_object_modified\",\" deleted: TestIp1 added: TestIp1Changed\",\" deleted: network added: host\"," + + "\" deleted: (1.2.3.4) added: (2.3.4.5)\",\"\",\"\",\"\"\"TestMgt\",\"05.04.2023 12:00:00\",\"network_object_deleted\",\"TestIp2\",\"network\",\" (127.0.0.1)\",\"\",\"\",\"\"#\"Service objects\"\"management-name\",\"change-time\"," + + "\"change-type\",\"service-name\",\"type\",\"protocol\",\"port\",\"members\",\"service-uid\",\"service-comment\"\"TestMgt\",\"05.04.2023 12:00:00\",\"service_added\",\"TestService1\",\"\",\"TCP\",\" (443)\",\"\",\"\",\"\"\"TestMgt\"," + + "\"05.04.2023 12:00:00\",\"service_modified\",\" deleted: TestService1 added: TestService2\",\"\",\" deleted: TCP added: UDP\",\" deleted: (443) added: (6666-7777)\",\"\",\"\",\"\"\"TestMgt\",\"05.04.2023 12:00:00\",\"service_deleted\"," + + "\"TestService1\",\"\",\"TCP\",\" (443)\",\"\",\"\",\"\""; + ClassicAssert.AreEqual(expectedCsvResult, RemoveLinebreaks(RemoveGenDate(reportChanges.ExportToCsv()))); + } + + [Test] + public void ResolvedChangesTechGenerateCsv() + { + Log.WriteInfo("Test Log", "starting changes report tech csv generation"); + ReportChanges reportChanges = new(query, userConfig, ReportType.ResolvedChangesTech, new TimeFilter(), false) + { + ReportData = ConstructChangeReport(true) + }; + + string expectedCsvResult = "# report type: Changes Report (technical)" + + "# report generation date: Z (UTC)" + + "# device filter: TestMgt [TestDev]" + + "# other filters: TestFilter" + + "# report generator: Firewall Orchestrator - https://fwo.cactus.de/en" + + "# data protection level: For internal use only#\"Rules\"" + + "\"management-name\",\"change-time\",\"change-type\",\"rule-name\",\"source-zone\",\"source\",\"destination-zone\",\"destination\",\"service\",\"action\",\"track\",\"rule-enabled\",\"enforcing_device\",\"rule-uid\",\"rule-comment\"" + + "\"TestMgt\",\"05.04.2023 12:00:00\",\"Rule added\",\"TestRule1\",\"\"srczn1\",\"srczn2\",\"srczn3\"\",\"1.2.3.4/32,127.0.0.1/32\",\"\"dstzn1\",\"dstzn2\",\"dstzn3\"\",\"1.2.3.4-1.2.3.5\",\"443/TCP\",\"accept\",\"none\",\"enabled\",\"\",\"uid1\",\"comment1\"" + + "\"TestMgt\",\"05.04.2023 12:00:00\",\"Rule modified\",\"TestRule1\",\"\"srczn1\",\"srczn2\",\"srczn3\"\",\"127.0.0.1/32 deleted: 1.2.3.4/32 added: 2.3.4.5\",\"\"dstzn1\",\"dstzn2\",\"dstzn3\"\",\"1.2.3.4-1.2.3.5 added: 10.0.6.0/24\",\" deleted: 443/TCP added: not(443/TCP)\",\"accept\",\"none\",\"enabled\",\"\",\" deleted: uid1\",\" deleted: comment1 added: new comment\"" + + "\"TestMgt\",\"05.04.2023 12:00:00\",\"Rule modified\",\"TestRule2\",\"\",\"not(TestUser1@1.2.3.4/32,TestUser1@127.0.0.1/32)\",\"\",\" deleted: not(TestUser2@1.2.3.4-1.2.3.5) added: TestUser2@1.2.3.4-1.2.3.5\",\" deleted: not(6666-7777/UDP) added: 6666-7777/UDP\",\"deny\",\"none\",\" deleted: enabled added: disabled\",\"\",\"uid2:123\",\"comment2\"" + + "\"TestMgt\",\"05.04.2023 12:00:00\",\"Rule deleted\",\"TestRule2\",\"\",\"not(TestUser1@1.2.3.4/32,TestUser1@127.0.0.1/32)\",\"\",\"not(TestUser2@1.2.3.4-1.2.3.5)\",\"not(6666-7777/UDP)\",\"deny\",\"none\",\"enabled\",\"\",\"uid2:123\",\"comment2\""; + ClassicAssert.AreEqual(expectedCsvResult, RemoveLinebreaks(RemoveGenDate(reportChanges.ExportToCsv()))); + } + #endregion + #region Json Tests + [Test] + public void RulesGenerateJson() + { + Log.WriteInfo("Test Log", "starting rules report json generation"); + ReportRules reportRules = ConstructReportRules(query, userConfig, ReportType.Rules, ConstructRuleReportRules(false)); + int id = reportRules.ReportData.ManagementData.First().Rulebases.First().Id; + + string expectedJsonResult = "[{\"id\": 0,\"uid\": \"\",\"name\": \"TestMgt\"," + + "\"devices\": [{\"uid\": \"device-1\",\"id\": 1,\"name\": \"Mock Device 1\"," + + "\"rulebase_links\": [{\"gw_id\": 0,\"from_rule_id\": null,\"rule\": null,\"rulebaseByFromRulebaseId\": null,\"from_rulebase_id\": null,\"rulebase\": null,\"link_type\": 0,\"stm_link_type\": null,\"is_initial\": true,\"is_global\": false,\"is_section\": false}]," + + "\"changelog_rules\": null,\"rules_aggregate\": {\"aggregate\": {\"count\": 0}}," + + "\"unusedRules_Count\": {\"aggregate\": {\"count\": 0}}}]," + + "\"rulebases\": [{\"id\": " + id + ",\"name\": \"Mock Rulebase " + id + "\",\"changelog_rules\": null," + + "\"rules_aggregate\": {\"aggregate\": {\"count\": 0}}," + + "\"rules\": [" + + "{\"rule_id\": 0,\"rule_uid\": \"uid1\",\"mgm_id\": 0,\"rule_num_numeric\": 1,\"rule_name\": \"TestRule1\",\"rule_comment\": \"comment1\",\"rule_disabled\": false," + + "\"rule_services\": [{\"service\": {\"svc_id\": 1,\"svc_name\": \"TestService1\",\"svc_uid\": \"\",\"svc_port\": 443,\"svc_port_end\": 443,\"svc_source_port\": null,\"svc_source_port_end\": null,\"svc_code\": \"\",\"svc_timeout\": null,\"svc_typ_id\": null,\"active\": false,\"svc_create\": 0,\"svc_create_time\": {\"time\": \"0001-01-01T00:00:00\"},\"svc_last_seen\": 0,\"service_type\": {\"name\": \"\"},\"svc_comment\": \"\",\"svc_color_id\": null,\"stm_color\": null,\"ip_proto_id\": null,\"protocol_name\": {\"id\": 6,\"name\": \"TCP\"},\"svc_member_names\": \"\",\"svc_member_refs\": \"\",\"svcgrps\": [],\"svcgrp_flats\": [],\"svc_rpcnr\": null}}]," + + "\"rule_svc_neg\": false,\"rule_svc\": \"\",\"rule_svc_refs\": \"\",\"rule_src_neg\": false,\"rule_src\": \"\",\"rule_src_refs\": \"\",\"rule_from_zones\": [{\"zone\": {\"zone_id\": 0,\"zone_name\": \"srczn1\"}},{\"zone\": {\"zone_id\": 0,\"zone_name\": \"srczn2\"}},{\"zone\": {\"zone_id\": 0,\"zone_name\": \"srczn3\"}}]," + + "\"rule_froms\": [" + + "{\"object\": {\"obj_id\": 1,\"obj_name\": \"TestIp1\",\"obj_ip\": \"1.2.3.4/32\",\"obj_ip_end\": \"1.2.3.4/32\",\"obj_uid\": \"\",\"zone\": null,\"active\": false,\"obj_create\": 0,\"obj_create_time\": {\"time\": \"0001-01-01T00:00:00\"},\"obj_last_seen\": 0,\"type\": {\"id\": 0,\"name\": \"network\"},\"obj_color\": null,\"obj_comment\": \"\",\"obj_member_names\": \"\",\"obj_member_refs\": \"\",\"objgrps\": [],\"objgrp_flats\": []},\"usr\": {\"user_id\": 0,\"user_uid\": \"\",\"user_name\": \"\",\"user_comment\": \"\",\"user_lastname\": \"\",\"user_firstname\": \"\",\"usr_typ_id\": 0,\"type\": {\"usr_typ_name\": \"\"},\"user_create\": 0,\"user_create_time\": {\"time\": \"0001-01-01T00:00:00\"},\"user_last_seen\": 0,\"user_member_names\": \"\",\"user_member_refs\": \"\",\"usergrps\": [],\"usergrp_flats\": []}}," + + "{\"object\": {\"obj_id\": 2,\"obj_name\": \"TestIp2\",\"obj_ip\": \"127.0.0.1/32\",\"obj_ip_end\": \"127.0.0.1/32\",\"obj_uid\": \"\",\"zone\": null,\"active\": false,\"obj_create\": 0,\"obj_create_time\": {\"time\": \"0001-01-01T00:00:00\"},\"obj_last_seen\": 0,\"type\": {\"id\": 0,\"name\": \"network\"},\"obj_color\": null,\"obj_comment\": \"\",\"obj_member_names\": \"\",\"obj_member_refs\": \"\",\"objgrps\": [],\"objgrp_flats\": []},\"usr\": {\"user_id\": 0,\"user_uid\": \"\",\"user_name\": \"\",\"user_comment\": \"\",\"user_lastname\": \"\",\"user_firstname\": \"\",\"usr_typ_id\": 0,\"type\": {\"usr_typ_name\": \"\"},\"user_create\": 0,\"user_create_time\": {\"time\": \"0001-01-01T00:00:00\"},\"user_last_seen\": 0,\"user_member_names\": \"\",\"user_member_refs\": \"\",\"usergrps\": [],\"usergrp_flats\": []}}]," + + "\"rule_dst_neg\": false,\"rule_dst\": \"\",\"rule_dst_refs\": \"\",\"rule_to_zones\": [{\"zone\": {\"zone_id\": 0,\"zone_name\": \"dstzn1\"}},{\"zone\": {\"zone_id\": 0,\"zone_name\": \"dstzn2\"}},{\"zone\": {\"zone_id\": 0,\"zone_name\": \"dstzn3\"}}]," + + "\"rule_tos\": [" + + "{\"object\": {\"obj_id\": 3,\"obj_name\": \"TestIpRange\",\"obj_ip\": \"1.2.3.4/32\",\"obj_ip_end\": \"1.2.3.5/32\",\"obj_uid\": \"\",\"zone\": null,\"active\": false,\"obj_create\": 0,\"obj_create_time\": {\"time\": \"0001-01-01T00:00:00\"},\"obj_last_seen\": 0,\"type\": {\"id\": 0,\"name\": \"ip_range\"},\"obj_color\": null,\"obj_comment\": \"\",\"obj_member_names\": \"\",\"obj_member_refs\": \"\",\"objgrps\": [],\"objgrp_flats\": []},\"usr\": {\"user_id\": 0,\"user_uid\": \"\",\"user_name\": \"\",\"user_comment\": \"\",\"user_lastname\": \"\",\"user_firstname\": \"\",\"usr_typ_id\": 0,\"type\": {\"usr_typ_name\": \"\"},\"user_create\": 0,\"user_create_time\": {\"time\": \"0001-01-01T00:00:00\"},\"user_last_seen\": 0,\"user_member_names\": \"\",\"user_member_refs\": \"\",\"usergrps\": [],\"usergrp_flats\": []}}]," + + "\"rule_action\": \"accept\",\"rule_track\": \"none\",\"section_header\": \"\"," + + "\"rule_metadatum\": {\"rule_metadata_id\": 0,\"rule_created\": null,\"created_import\": null,\"removed\": null,\"removed_import\": null,\"rule_first_hit\": null,\"rule_last_hit\": \"2022-04-19T00:00:00Z\",\"recertification\": [],\"recert_history\": [],\"rule_uid\": \"\",\"rules\": [],\"Recert\": false}," + + "\"translate\": {\"rule_svc_neg\": false,\"rule_svc\": \"\",\"rule_services\": [],\"rule_src_neg\": false,\"rule_src\": \"\",\"rule_froms\": [],\"rule_dst_neg\": false,\"rule_dst\": \"\",\"rule_tos\": []}," + + "\"owner_name\": \"\",\"owner_id\": null,\"matches\": \"\",\"rule_custom_fields\": \"\",\"rule_implied\": false,\"nat_rule\": false,\"rulebase_id\": 0,\"rule_num\": 0,\"rule_enforced_on_gateways\": [],\"rule_installon\": null,\"rule_time\": null,\"rule_times\": [],\"violations\": [],\"rulebase\": {\"id\": 0,\"name\": \"\",\"uid\": \"\",\"mgm_id\": 0,\"is_global\": false,\"created\": 0,\"removed\": 0,\"rules\": []},\"uiuser\": null,\"rule\": null,\"rule_owners\": [],\"ChangeID\": \"\",\"AdoITID\": \"\",\"Compliance\": 0,\"ViolationDetails\": \"\",\"DisplayOrderNumberString\": \"1\",\"DisplayOrderNumber\": 1,\"Certified\": false,\"DeviceName\": \"\",\"RulebaseName\": \"\",\"DisregardedFroms\": [],\"DisregardedTos\": [],\"DisregardedServices\": [],\"ShowDisregarded\": false}," + + "{\"rule_id\": 0,\"rule_uid\": \"uid2:123\",\"mgm_id\": 0,\"rule_num_numeric\": 0,\"rule_name\": \"TestRule2\",\"rule_comment\": \"comment2\",\"rule_disabled\": false," + + "\"rule_services\": [{\"service\": {\"svc_id\": 2,\"svc_name\": \"TestService2\",\"svc_uid\": \"\",\"svc_port\": 6666,\"svc_port_end\": 7777,\"svc_source_port\": null,\"svc_source_port_end\": null,\"svc_code\": \"\",\"svc_timeout\": null,\"svc_typ_id\": null,\"active\": false,\"svc_create\": 0,\"svc_create_time\": {\"time\": \"0001-01-01T00:00:00\"},\"svc_last_seen\": 0,\"service_type\": {\"name\": \"\"},\"svc_comment\": \"\",\"svc_color_id\": null,\"stm_color\": null,\"ip_proto_id\": null,\"protocol_name\": {\"id\": 17,\"name\": \"UDP\"},\"svc_member_names\": \"\",\"svc_member_refs\": \"\",\"svcgrps\": [],\"svcgrp_flats\": [],\"svc_rpcnr\": null}}]," + + "\"rule_svc_neg\": true,\"rule_svc\": \"\",\"rule_svc_refs\": \"\",\"rule_src_neg\": true,\"rule_src\": \"\",\"rule_src_refs\": \"\",\"rule_from_zones\": []," + + "\"rule_froms\": [" + + "{\"object\": {\"obj_id\": 1,\"obj_name\": \"TestIp1\",\"obj_ip\": \"1.2.3.4/32\",\"obj_ip_end\": \"1.2.3.4/32\",\"obj_uid\": \"\",\"zone\": null,\"active\": false,\"obj_create\": 0,\"obj_create_time\": {\"time\": \"0001-01-01T00:00:00\"},\"obj_last_seen\": 0,\"type\": {\"id\": 0,\"name\": \"network\"},\"obj_color\": null,\"obj_comment\": \"\",\"obj_member_names\": \"\",\"obj_member_refs\": \"\",\"objgrps\": [],\"objgrp_flats\": []},\"usr\": {\"user_id\": 1,\"user_uid\": \"\",\"user_name\": \"TestUser1\",\"user_comment\": \"\",\"user_lastname\": \"\",\"user_firstname\": \"\",\"usr_typ_id\": 0,\"type\": {\"usr_typ_name\": \"\"},\"user_create\": 0,\"user_create_time\": {\"time\": \"0001-01-01T00:00:00\"},\"user_last_seen\": 0,\"user_member_names\": \"\",\"user_member_refs\": \"\",\"usergrps\": [],\"usergrp_flats\": []}}," + + "{\"object\": {\"obj_id\": 2,\"obj_name\": \"TestIp2\",\"obj_ip\": \"127.0.0.1/32\",\"obj_ip_end\": \"127.0.0.1/32\",\"obj_uid\": \"\",\"zone\": null,\"active\": false,\"obj_create\": 0,\"obj_create_time\": {\"time\": \"0001-01-01T00:00:00\"},\"obj_last_seen\": 0,\"type\": {\"id\": 0,\"name\": \"network\"},\"obj_color\": null,\"obj_comment\": \"\",\"obj_member_names\": \"\",\"obj_member_refs\": \"\",\"objgrps\": [],\"objgrp_flats\": []},\"usr\": {\"user_id\": 1,\"user_uid\": \"\",\"user_name\": \"TestUser1\",\"user_comment\": \"\",\"user_lastname\": \"\",\"user_firstname\": \"\",\"usr_typ_id\": 0,\"type\": {\"usr_typ_name\": \"\"},\"user_create\": 0,\"user_create_time\": {\"time\": \"0001-01-01T00:00:00\"},\"user_last_seen\": 0,\"user_member_names\": \"\",\"user_member_refs\": \"\",\"usergrps\": [],\"usergrp_flats\": []}}]," + + "\"rule_dst_neg\": true,\"rule_dst\": \"\",\"rule_dst_refs\": \"\",\"rule_to_zones\": []," + + "\"rule_tos\": [" + + "{\"object\": {\"obj_id\": 3,\"obj_name\": \"TestIpRange\",\"obj_ip\": \"1.2.3.4/32\",\"obj_ip_end\": \"1.2.3.5/32\",\"obj_uid\": \"\",\"zone\": null,\"active\": false,\"obj_create\": 0,\"obj_create_time\": {\"time\": \"0001-01-01T00:00:00\"},\"obj_last_seen\": 0,\"type\": {\"id\": 0,\"name\": \"ip_range\"},\"obj_color\": null,\"obj_comment\": \"\",\"obj_member_names\": \"\",\"obj_member_refs\": \"\",\"objgrps\": [],\"objgrp_flats\": []},\"usr\": {\"user_id\": 2,\"user_uid\": \"\",\"user_name\": \"TestUser2\",\"user_comment\": \"\",\"user_lastname\": \"\",\"user_firstname\": \"\",\"usr_typ_id\": 0,\"type\": {\"usr_typ_name\": \"group\"},\"user_create\": 0,\"user_create_time\": {\"time\": \"0001-01-01T00:00:00\"},\"user_last_seen\": 0,\"user_member_names\": \"\",\"user_member_refs\": \"\",\"usergrps\": [],\"usergrp_flats\": []}}]," + + "\"rule_action\": \"deny\",\"rule_track\": \"none\",\"section_header\": \"\"," + + "\"rule_metadatum\": {\"rule_metadata_id\": 0,\"rule_created\": null,\"created_import\": null,\"removed\": null,\"removed_import\": null,\"rule_first_hit\": null,\"rule_last_hit\": null,\"recertification\": [],\"recert_history\": [],\"rule_uid\": \"\",\"rules\": [],\"Recert\": false}," + + "\"translate\": {\"rule_svc_neg\": false,\"rule_svc\": \"\",\"rule_services\": [],\"rule_src_neg\": false,\"rule_src\": \"\",\"rule_froms\": [],\"rule_dst_neg\": false,\"rule_dst\": \"\",\"rule_tos\": []}," + + "\"owner_name\": \"\",\"owner_id\": null,\"matches\": \"\",\"rule_custom_fields\": \"\",\"rule_implied\": false,\"nat_rule\": false,\"rulebase_id\": 0,\"rule_num\": 0,\"rule_enforced_on_gateways\": [],\"rule_installon\": null,\"rule_time\": null,\"rule_times\": [],\"violations\": [],\"rulebase\": {\"id\": 0,\"name\": \"\",\"uid\": \"\",\"mgm_id\": 0,\"is_global\": false,\"created\": 0,\"removed\": 0,\"rules\": []},\"uiuser\": null,\"rule\": null,\"rule_owners\": [],\"ChangeID\": \"\",\"AdoITID\": \"\",\"Compliance\": 0,\"ViolationDetails\": \"\",\"DisplayOrderNumberString\": \"\",\"DisplayOrderNumber\": 2,\"Certified\": false,\"DeviceName\": \"\",\"RulebaseName\": \"\",\"DisregardedFroms\": [],\"DisregardedTos\": [],\"DisregardedServices\": [],\"ShowDisregarded\": false}]}]," + + "\"changelog_rules\": null,\"changelog_objects\": null,\"changelog_services\": null,\"changelog_users\": null,\"import\": {\"aggregate\": {\"max\": {\"id\": null}}},\"import_controls\": [],\"RelevantImportId\": null,\"is_super_manager\": false,\"multi_device_manager_id\": null,\"management\": null,\"managementByMultiDeviceManagerId\": [],\"networkObjects\": [],\"serviceObjects\": [],\"userObjects\": [],\"zoneObjects\": []," + + "\"reportNetworkObjects\": [{\"obj_id\": 1,\"obj_name\": \"TestIp1\",\"obj_ip\": \"1.2.3.4/32\",\"obj_ip_end\": \"1.2.3.4/32\",\"obj_uid\": \"\",\"zone\": null,\"active\": false,\"obj_create\": 0," + + "\"obj_create_time\": {\"time\": \"0001-01-01T00:00:00\"},\"obj_last_seen\": 0,\"type\": {\"id\": 0,\"name\": \"network\"},\"obj_color\": null,\"obj_comment\": \"\",\"obj_member_names\": \"\",\"obj_member_refs\": \"\"," + + "\"objgrps\": [],\"objgrp_flats\": []},{\"obj_id\": 2,\"obj_name\": \"TestIp2\",\"obj_ip\": \"127.0.0.1/32\",\"obj_ip_end\": \"127.0.0.1/32\",\"obj_uid\": \"\",\"zone\": null,\"active\": false,\"obj_create\": 0," + + "\"obj_create_time\": {\"time\": \"0001-01-01T00:00:00\"},\"obj_last_seen\": 0,\"type\": {\"id\": 0,\"name\": \"network\"},\"obj_color\": null,\"obj_comment\": \"\",\"obj_member_names\": \"\",\"obj_member_refs\": \"\",\"objgrps\": []," + + "\"objgrp_flats\": []},{\"obj_id\": 3,\"obj_name\": \"TestIpRange\",\"obj_ip\": \"1.2.3.4/32\",\"obj_ip_end\": \"1.2.3.5/32\",\"obj_uid\": \"\",\"zone\": null,\"active\": false,\"obj_create\": 0," + + "\"obj_create_time\": {\"time\": \"0001-01-01T00:00:00\"},\"obj_last_seen\": 0,\"type\": {\"id\": 0,\"name\": \"ip_range\"},\"obj_color\": null,\"obj_comment\": \"\",\"obj_member_names\": \"\",\"obj_member_refs\": \"\"," + + "\"objgrps\": [],\"objgrp_flats\": []}],\"reportServiceObjects\": [{\"svc_id\": 1,\"svc_name\": \"TestService1\",\"svc_uid\": \"\",\"svc_port\": 443,\"svc_port_end\": 443,\"svc_source_port\": null,\"svc_source_port_end\": null," + + "\"svc_code\": \"\",\"svc_timeout\": null,\"svc_typ_id\": null,\"active\": false,\"svc_create\": 0,\"svc_create_time\": {\"time\": \"0001-01-01T00:00:00\"},\"svc_last_seen\": 0,\"service_type\": {\"name\": \"\"},\"svc_comment\": \"\"," + + "\"svc_color_id\": null,\"stm_color\": null,\"ip_proto_id\": null,\"protocol_name\": {\"id\": 6,\"name\": \"TCP\"},\"svc_member_names\": \"\",\"svc_member_refs\": \"\",\"svcgrps\": [],\"svcgrp_flats\": []," + + "\"svc_rpcnr\": null},{\"svc_id\": 2,\"svc_name\": \"TestService2\",\"svc_uid\": \"\",\"svc_port\": 6666,\"svc_port_end\": 7777,\"svc_source_port\": null,\"svc_source_port_end\": null,\"svc_code\": \"\"," + + "\"svc_timeout\": null,\"svc_typ_id\": null,\"active\": false,\"svc_create\": 0,\"svc_create_time\": {\"time\": \"0001-01-01T00:00:00\"},\"svc_last_seen\": 0,\"service_type\": {\"name\": \"\"},\"svc_comment\": \"\"," + + "\"svc_color_id\": null,\"stm_color\": null,\"ip_proto_id\": null,\"protocol_name\": {\"id\": 17,\"name\": \"UDP\"},\"svc_member_names\": \"\",\"svc_member_refs\": \"\",\"svcgrps\": [],\"svcgrp_flats\": [],\"svc_rpcnr\": null}]," + + "\"reportUserObjects\": [{\"user_id\": 1,\"user_uid\": \"\",\"user_name\": \"TestUser1\",\"user_comment\": \"\",\"user_lastname\": \"\",\"user_firstname\": \"\",\"usr_typ_id\": 0,\"type\": {\"usr_typ_name\": \"\"},\"user_create\": 0," + + "\"user_create_time\": {\"time\": \"0001-01-01T00:00:00\"},\"user_last_seen\": 0,\"user_member_names\": \"\",\"user_member_refs\": \"\",\"usergrps\": [],\"usergrp_flats\": []},{\"user_id\": 2,\"user_uid\": \"\"," + + "\"user_name\": \"TestUser2\",\"user_comment\": \"\",\"user_lastname\": \"\",\"user_firstname\": \"\",\"usr_typ_id\": 0,\"type\": {\"usr_typ_name\": \"group\"},\"user_create\": 0,\"user_create_time\": {\"time\": \"0001-01-01T00:00:00\"}," + + "\"user_last_seen\": 0,\"user_member_names\": \"\",\"user_member_refs\": \"\",\"usergrps\": [],\"usergrp_flats\": []}],\"ReportedRuleIds\": [0],\"ReportedNetworkServiceIds\": [],\"objects_aggregate\": {\"aggregate\": {\"count\": 0}}," + + "\"services_aggregate\": {\"aggregate\": {\"count\": 0}},\"usrs_aggregate\": {\"aggregate\": {\"count\": 0}},\"rules_aggregate\": {\"aggregate\": {\"count\": 0}},\"unusedRules_Count\": {\"aggregate\": {\"count\": 0}},\"Ignore\": false}]"; + string jsonExport = RemoveLinebreaks(RemoveGenDate(reportRules.ExportToJson(), false, true)); + ClassicAssert.AreEqual(expectedJsonResult, jsonExport); + } + + [Test] + public void ResolvedRulesGenerateJson() + { + Log.WriteInfo("Test Log", "starting resolved rules report json generation"); + ReportRules reportRules = ConstructReportRules(query, userConfig, ReportType.ResolvedRules, ConstructRuleReportRules(true)); + + string expectedJsonResult = + "{\"report type\": \"Rules Report (resolved)\",\"report generation date\": \"Z (UTC)\"," + + "\"date of configuration shown\": \"2023-04-20T15:50:04Z (UTC)\",\"device filter\": \"TestMgt [Mock Device 1]\",\"other filters\": \"TestFilter\"," + + "\"report generator\": \"Firewall Orchestrator - https://fwo.cactus.de/en\",\"data protection level\": \"For internal use only\"," + + "\"managements\": [{\"TestMgt\": {\"gateways\": [{\"Mock Device 1\": {" + + "\"rules\": [{\"number\": 1,\"name\": \"TestRule1\",\"source zones\": [\"srczn1\",\"srczn2\",\"srczn3\"],\"source negated\": false," + + "\"source\": [\"TestIp1 (1.2.3.4/32)\",\"TestIp2 (127.0.0.1/32)\"],\"destination zones\": [\"dstzn1\",\"dstzn2\",\"dstzn3\"],\"destination negated\": false," + + "\"destination\": [\"TestIpRange (1.2.3.4-1.2.3.5)\"],\"service negated\": false," + + "\"service\": [\"TestService1 (443/TCP)\"],\"action\": \"accept\",\"tracking\": \"none\",\"disabled\": false,\"rule uid\": \"uid1\",\"comment\": \"comment1\"}," + + "{\"number\": 2,\"name\": \"TestRule2\",\"source zones\": [],\"source negated\": true," + + "\"source\": [\"TestUser1@TestIp1 (1.2.3.4/32)\",\"TestUser1@TestIp2 (127.0.0.1/32)\"],\"destination zones\": [],\"destination negated\": true," + + "\"destination\": [\"TestUser2@TestIpRange (1.2.3.4-1.2.3.5)\"],\"service negated\": true," + + "\"service\": [\"TestService2 (6666-7777/UDP)\"],\"action\": \"deny\",\"tracking\": \"none\",\"disabled\": false,\"rule uid\": \"uid2:123\",\"comment\": \"comment2\"}]}}]}}]}"; + string jsonExport = RemoveLinebreaks(RemoveGenDate(reportRules.ExportToJson(), false, true)); + ClassicAssert.AreEqual(expectedJsonResult, jsonExport); + } + + [Test] + public void ResolvedRulesGenerateJsonWithoutRules() + { + Log.WriteInfo("Test Log", "starting resolved rules report json generation"); + ReportRules reportRules = ConstructReportRulesWithoutRules(true, query, userConfig, ReportType.ResolvedRules); + + string expectedJsonResult = + "{\"report type\": \"Rules Report (resolved)\",\"report generation date\": \"Z (UTC)\"," + + "\"date of configuration shown\": \"2023-04-20T15:50:04Z (UTC)\",\"device filter\": \"TestMgt [Mock Device 1]\",\"other filters\": \"TestFilter\"," + + "\"report generator\": \"Firewall Orchestrator - https://fwo.cactus.de/en\",\"data protection level\": \"For internal use only\"," + + "\"managements\": [{\"TestMgt\": {\"gateways\": [{\"Mock Device 1\": {" + + "\"rules\": []}}]}}]}"; + string jsonExport = RemoveLinebreaks(RemoveGenDate(reportRules.ExportToJson(), false, true)); + ClassicAssert.AreEqual(expectedJsonResult, jsonExport); + } + + [Test] + public void ResolvedRulesTechGenerateJson() + { + Log.WriteInfo("Test Log", "starting resolved rules report tech json generation"); + ReportRules reportRules = ConstructReportRules(query, userConfig, ReportType.ResolvedRulesTech, ConstructRuleReportRules(true)); + string expectedJsonResult = + "{\"report type\": \"Rules Report (technical)\",\"report generation date\": \"Z (UTC)\"," + + "\"date of configuration shown\": \"2023-04-20T15:50:04Z (UTC)\"," + + "\"device filter\": \"TestMgt [Mock Device 1]\",\"other filters\": \"TestFilter\"," + + "\"report generator\": \"Firewall Orchestrator - https://fwo.cactus.de/en\",\"data protection level\": \"For internal use only\"," + + "\"managements\": [{\"TestMgt\": {\"gateways\": [{\"Mock Device 1\": {" + + "\"rules\": [{\"number\": 1,\"name\": \"TestRule1\",\"source zones\": [\"srczn1\",\"srczn2\",\"srczn3\"],\"source negated\": false," + + "\"source\": [\"1.2.3.4/32\",\"127.0.0.1/32\"],\"destination zones\": [\"dstzn1\",\"dstzn2\",\"dstzn3\"],\"destination negated\": false," + + "\"destination\": [\"1.2.3.4-1.2.3.5\"],\"service negated\": false," + + "\"service\": [\"443/TCP\"],\"action\": \"accept\",\"tracking\": \"none\",\"disabled\": false,\"rule uid\": \"uid1\",\"comment\": \"comment1\"}," + + "{\"number\": 2,\"name\": \"TestRule2\",\"source zones\": [],\"source negated\": true," + + "\"source\": [\"TestUser1@1.2.3.4/32\",\"TestUser1@127.0.0.1/32\"],\"destination zones\": []," + + "\"destination negated\": true,\"destination\": [\"TestUser2@1.2.3.4-1.2.3.5\"],\"service negated\": true," + + "\"service\": [\"6666-7777/UDP\"],\"action\": \"deny\",\"tracking\": \"none\",\"disabled\": false,\"rule uid\": \"uid2:123\",\"comment\": \"comment2\"}]}}]}}]}"; + string exportJson = RemoveLinebreaks(RemoveGenDate(reportRules.ExportToJson(), false, true)); + ClassicAssert.AreEqual(expectedJsonResult, exportJson); + } + + [Test] + public void ChangesGenerateJson() + { + Log.WriteInfo("Test Log", "starting changes report json generation"); + ReportChanges reportChanges = new(query, userConfig, ReportType.Changes, new TimeFilter(), false) + { + ReportData = ConstructChangeReport(false) + }; + + string expectedJsonResult = + "{\"report type\": \"Changes Report\",\"report generation date\": \"Z (UTC)\",\"device filter\": \"TestMgt [TestDev]\",\"other filters\": \"TestFilter\",\"report generator\": \"Firewall Orchestrator - https://fwo.cactus.de/en\",\"data protection level\": \"For internal use only\"," + + "\"managements\": [{\"TestMgt\": {\"rule changes\": [" + + "{\"change time\": \"05.04.2023 12:00:00\",\"change action\": \"Rule added\",\"name\": \"TestRule1\"," + + "\"source zones\": [\"srczn1\",\"srczn2\",\"srczn3\"],\"source negated\": false,\"source\": []," + + "\"destination zones\": [\"dstzn1\",\"dstzn2\",\"dstzn3\"],\"destination negated\": false,\"destination\": []," + + "\"service negated\": false,\"service\": [],\"action\": \"accept\",\"tracking\": \"none\",\"disabled\": false,\"Enforcing Gateway\": [],\"rule uid\": \"uid1\",\"comment\": \"comment1\"}," + + "{\"change time\": \"05.04.2023 12:00:00\",\"change action\": \"Rule modified\",\"name\": \"TestRule1\"," + + "\"source zones\": [\"srczn1\",\"srczn2\",\"srczn3\"],\"source negated\": false,\"source\": []," + + "\"destination zones\": [\"dstzn1\",\"dstzn2\",\"dstzn3\"],\"destination negated\": false,\"destination\": []," + + "\"service negated\": \"deleted: false, added: true\",\"service\": [],\"action\": \"accept\",\"tracking\": \"none\",\"disabled\": false,\"EnforcingGateways\": [],\"rule uid\": \"deleted: uid1\",\"comment\": \"deleted: comment1, added: new comment\"}," + + "{\"change time\": \"05.04.2023 12:00:00\",\"change action\": \"Rule modified\",\"name\": \"TestRule2\"," + + "\"source zones\": [],\"source negated\": true,\"source\": []," + + "\"destination zones\": [],\"destination negated\": \"deleted: true, added: false\",\"destination\": []," + + "\"service negated\": \"deleted: true, added: false\",\"service\": [],\"action\": \"deny\",\"tracking\": \"none\",\"disabled\": \"deleted: false, added: true\",\"EnforcingGateways\": [],\"rule uid\": \"uid2:123\",\"comment\": \"comment2\"}," + + "{\"change time\": \"05.04.2023 12:00:00\",\"change action\": \"Rule deleted\",\"name\": \"TestRule2\"," + + "\"source zones\": [],\"source negated\": true,\"source\": []," + + "\"destination zones\": [],\"destination negated\": true,\"destination\": []," + + "\"service negated\": true,\"service\": [],\"action\": \"deny\",\"tracking\": \"none\",\"disabled\": false,\"Enforcing Gateway\": [],\"rule uid\": \"uid2:123\",\"comment\": \"comment2\"}]}}]}"; + ClassicAssert.AreEqual(expectedJsonResult, RemoveLinebreaks(RemoveGenDate(reportChanges.ExportToJson(), false, true))); + } + + [Test] + public void ResolvedChangesGenerateJson() + { + Log.WriteInfo("Test Log", "starting resolved changes report json generation"); + ReportChanges reportChanges = new(query, userConfig, ReportType.ResolvedChanges, new TimeFilter(), false) + { + ReportData = ConstructChangeReport(true) + }; + + string expectedJsonResult = + "{\"report type\": \"Changes Report (resolved)\",\"report generation date\": \"Z (UTC)\",\"device filter\": \"TestMgt [TestDev]\",\"other filters\": \"TestFilter\",\"report generator\": \"Firewall Orchestrator - https://fwo.cactus.de/en\",\"data protection level\": \"For internal use only\"," + + "\"managements\": [{\"TestMgt\": {\"rule changes\": [" + + "{\"change time\": \"05.04.2023 12:00:00\",\"change action\": \"Rule added\",\"name\": \"TestRule1\"," + + "\"source zones\": [\"srczn1\",\"srczn2\",\"srczn3\"],\"source negated\": false,\"source\": [\"TestIp1 (1.2.3.4/32)\",\"TestIp2 (127.0.0.1/32)\"]," + + "\"destination zones\": [\"dstzn1\",\"dstzn2\",\"dstzn3\"],\"destination negated\": false,\"destination\": [\"TestIpRange (1.2.3.4-1.2.3.5)\"]," + + "\"service negated\": false,\"service\": [\"TestService1 (443/TCP)\"],\"action\": \"accept\",\"tracking\": \"none\",\"disabled\": false,\"Enforcing Gateway\": [],\"rule uid\": \"uid1\",\"comment\": \"comment1\"}," + + "{\"change time\": \"05.04.2023 12:00:00\",\"change action\": \"Rule modified\",\"name\": \"TestRule1\"," + + "\"source zones\": [\"srczn1\",\"srczn2\",\"srczn3\"],\"source negated\": false,\"source\": [\"TestIp2 (127.0.0.1/32)\",\"deleted: TestIp1 (1.2.3.4/32)\",\"added: TestIp1Changed (2.3.4.5)\"]," + + "\"destination zones\": [\"dstzn1\",\"dstzn2\",\"dstzn3\"],\"destination negated\": false,\"destination\": [\"TestIpRange (1.2.3.4-1.2.3.5)\",\"added: TestIpNew (10.0.6.0/24)\"]," + + "\"service negated\": \"deleted: false, added: true\",\"service\": [\"TestService1 (443/TCP)\"],\"action\": \"accept\",\"tracking\": \"none\",\"disabled\": false,\"EnforcingGateways\": [],\"rule uid\": \"deleted: uid1\",\"comment\": \"deleted: comment1, added: new comment\"}," + + "{\"change time\": \"05.04.2023 12:00:00\",\"change action\": \"Rule modified\",\"name\": \"TestRule2\"," + + "\"source zones\": [],\"source negated\": true,\"source\": [\"TestUser1@TestIp1 (1.2.3.4/32)\",\"TestUser1@TestIp2 (127.0.0.1/32)\"]," + + "\"destination zones\": [],\"destination negated\": \"deleted: true, added: false\",\"destination\": [\"TestUser2@TestIpRange (1.2.3.4-1.2.3.5)\"]," + + "\"service negated\": \"deleted: true, added: false\",\"service\": [\"TestService2 (6666-7777/UDP)\"],\"action\": \"deny\",\"tracking\": \"none\",\"disabled\": \"deleted: false, added: true\",\"EnforcingGateways\": [],\"rule uid\": \"uid2:123\",\"comment\": \"comment2\"}," + + "{\"change time\": \"05.04.2023 12:00:00\",\"change action\": \"Rule deleted\",\"name\": \"TestRule2\"," + + "\"source zones\": [],\"source negated\": true,\"source\": [\"TestUser1@TestIp1 (1.2.3.4/32)\",\"TestUser1@TestIp2 (127.0.0.1/32)\"]," + + "\"destination zones\": [],\"destination negated\": true,\"destination\": [\"TestUser2@TestIpRange (1.2.3.4-1.2.3.5)\"]," + + "\"service negated\": true,\"service\": [\"TestService2 (6666-7777/UDP)\"],\"action\": \"deny\",\"tracking\": \"none\",\"disabled\": false,\"Enforcing Gateway\": [],\"rule uid\": \"uid2:123\",\"comment\": \"comment2\"}]}}]}"; + // Log.WriteInfo("Test Log", removeLinebreaks((removeGenDate(reportChanges.ExportToJson(), false, true)))); + ClassicAssert.AreEqual(expectedJsonResult, RemoveLinebreaks(RemoveGenDate(reportChanges.ExportToJson(), false, true))); + } + + [Test] + public void ResolvedChangesTechGenerateJson() + { + Log.WriteInfo("Test Log", "starting resolved changes report json generation"); + ReportChanges reportChanges = new(query, userConfig, ReportType.ResolvedChangesTech, new TimeFilter(), false) + { + ReportData = ConstructChangeReport(true) + }; + + string expectedJsonResult = + "{\"report type\": \"Changes Report (technical)\",\"report generation date\": \"Z (UTC)\",\"device filter\": \"TestMgt [TestDev]\",\"other filters\": \"TestFilter\",\"report generator\": \"Firewall Orchestrator - https://fwo.cactus.de/en\",\"data protection level\": \"For internal use only\"," + + "\"managements\": [{\"TestMgt\": {\"rule changes\": [" + + "{\"change time\": \"05.04.2023 12:00:00\",\"change action\": \"Rule added\",\"name\": \"TestRule1\"," + + "\"source zones\": [\"srczn1\",\"srczn2\",\"srczn3\"],\"source negated\": false,\"source\": [\"1.2.3.4/32\",\"127.0.0.1/32\"]," + + "\"destination zones\": [\"dstzn1\",\"dstzn2\",\"dstzn3\"],\"destination negated\": false,\"destination\": [\"1.2.3.4-1.2.3.5\"]," + + "\"service negated\": false,\"service\": [\"443/TCP\"],\"action\": \"accept\",\"tracking\": \"none\",\"disabled\": false,\"Enforcing Gateway\": [],\"rule uid\": \"uid1\",\"comment\": \"comment1\"}," + + "{\"change time\": \"05.04.2023 12:00:00\",\"change action\": \"Rule modified\",\"name\": \"TestRule1\"," + + "\"source zones\": [\"srczn1\",\"srczn2\",\"srczn3\"],\"source negated\": false,\"source\": [\"127.0.0.1/32\",\"deleted: 1.2.3.4/32\",\"added: 2.3.4.5\"]," + + "\"destination zones\": [\"dstzn1\",\"dstzn2\",\"dstzn3\"],\"destination negated\": false,\"destination\": [\"1.2.3.4-1.2.3.5\",\"added: 10.0.6.0/24\"]," + + "\"service negated\": \"deleted: false, added: true\",\"service\": [\"443/TCP\"],\"action\": \"accept\",\"tracking\": \"none\",\"disabled\": false,\"EnforcingGateways\": [],\"rule uid\": \"deleted: uid1\",\"comment\": \"deleted: comment1, added: new comment\"}," + + "{\"change time\": \"05.04.2023 12:00:00\",\"change action\": \"Rule modified\",\"name\": \"TestRule2\"," + + "\"source zones\": [],\"source negated\": true,\"source\": [\"TestUser1@1.2.3.4/32\",\"TestUser1@127.0.0.1/32\"]," + + "\"destination zones\": [],\"destination negated\": \"deleted: true, added: false\",\"destination\": [\"TestUser2@1.2.3.4-1.2.3.5\"]," + + "\"service negated\": \"deleted: true, added: false\",\"service\": [\"6666-7777/UDP\"],\"action\": \"deny\",\"tracking\": \"none\",\"disabled\": \"deleted: false, added: true\",\"EnforcingGateways\": [],\"rule uid\": \"uid2:123\",\"comment\": \"comment2\"}," + + "{\"change time\": \"05.04.2023 12:00:00\",\"change action\": \"Rule deleted\",\"name\": \"TestRule2\"," + + "\"source zones\": [],\"source negated\": true,\"source\": [\"TestUser1@1.2.3.4/32\",\"TestUser1@127.0.0.1/32\"]," + + "\"destination zones\": [],\"destination negated\": true,\"destination\": [\"TestUser2@1.2.3.4-1.2.3.5\"]," + + "\"service negated\": true,\"service\": [\"6666-7777/UDP\"],\"action\": \"deny\",\"tracking\": \"none\",\"disabled\": false,\"Enforcing Gateway\": [],\"rule uid\": \"uid2:123\",\"comment\": \"comment2\"}]}}]}"; + ClassicAssert.AreEqual(expectedJsonResult, RemoveLinebreaks(RemoveGenDate(reportChanges.ExportToJson(), false, true))); + } + [Test] + public void ResolvedChangesTechGenerateJsonIncludeObjects() + { + Log.WriteInfo("Test Log", "starting resolved changes report json generation"); + ReportChanges reportChanges = new(query, userConfig, ReportType.ResolvedChangesTech, new TimeFilter(), true) + { + ReportData = ConstructChangeReport(true) + }; + + string expectedJsonResult = + "{\"report type\": \"Changes Report (technical)\",\"report generation date\": \"Z (UTC)\",\"device filter\": \"TestMgt [TestDev]\",\"other filters\": \"TestFilter\",\"report generator\": \"Firewall Orchestrator - https://fwo.cactus.de/en\",\"data protection level\": \"For internal use only\"," + + "\"managements\": [{\"TestMgt\": {\"rule changes\": [" + + "{\"change time\": \"05.04.2023 12:00:00\",\"change action\": \"Rule added\",\"name\": \"TestRule1\"," + + "\"source zones\": [\"srczn1\",\"srczn2\",\"srczn3\"],\"source negated\": false,\"source\": [\"1.2.3.4/32\",\"127.0.0.1/32\"]," + + "\"destination zones\": [\"dstzn1\",\"dstzn2\",\"dstzn3\"],\"destination negated\": false,\"destination\": [\"1.2.3.4-1.2.3.5\"]," + + "\"service negated\": false,\"service\": [\"443/TCP\"],\"action\": \"accept\",\"tracking\": \"none\",\"disabled\": false,\"Enforcing Gateway\": [],\"rule uid\": \"uid1\",\"comment\": \"comment1\"}," + + "{\"change time\": \"05.04.2023 12:00:00\",\"change action\": \"Rule modified\",\"name\": \"TestRule1\"," + + "\"source zones\": [\"srczn1\",\"srczn2\",\"srczn3\"],\"source negated\": false,\"source\": [\"127.0.0.1/32\",\"deleted: 1.2.3.4/32\",\"added: 2.3.4.5\"]," + + "\"destination zones\": [\"dstzn1\",\"dstzn2\",\"dstzn3\"],\"destination negated\": false,\"destination\": [\"1.2.3.4-1.2.3.5\",\"added: 10.0.6.0/24\"]," + + "\"service negated\": \"deleted: false, added: true\",\"service\": [\"443/TCP\"],\"action\": \"accept\",\"tracking\": \"none\",\"disabled\": false,\"EnforcingGateways\": [],\"rule uid\": \"deleted: uid1\",\"comment\": \"deleted: comment1, added: new comment\"}," + + "{\"change time\": \"05.04.2023 12:00:00\",\"change action\": \"Rule modified\",\"name\": \"TestRule2\"," + + "\"source zones\": [],\"source negated\": true,\"source\": [\"TestUser1@1.2.3.4/32\",\"TestUser1@127.0.0.1/32\"]," + + "\"destination zones\": [],\"destination negated\": \"deleted: true, added: false\",\"destination\": [\"TestUser2@1.2.3.4-1.2.3.5\"]," + + "\"service negated\": \"deleted: true, added: false\",\"service\": [\"6666-7777/UDP\"],\"action\": \"deny\",\"tracking\": \"none\",\"disabled\": \"deleted: false, added: true\",\"EnforcingGateways\": [],\"rule uid\": \"uid2:123\",\"comment\": \"comment2\"}," + + "{\"change time\": \"05.04.2023 12:00:00\",\"change action\": \"Rule deleted\",\"name\": \"TestRule2\"," + + "\"source zones\": [],\"source negated\": true,\"source\": [\"TestUser1@1.2.3.4/32\",\"TestUser1@127.0.0.1/32\"]," + + "\"destination zones\": [],\"destination negated\": true,\"destination\": [\"TestUser2@1.2.3.4-1.2.3.5\"]," + + "\"service negated\": true,\"service\": [\"6666-7777/UDP\"],\"action\": \"deny\",\"tracking\": \"none\",\"disabled\": false,\"Enforcing Gateway\": [],\"rule uid\": \"uid2:123\",\"comment\": \"comment2\"}]," + + "\"Network Object changes\": [{\"change time\": \"05.04.2023 12:00:00\",\"change action\": \"network_object_added\",\"name\": \"TestIp1\",\"ObjectType\": \"network\",\"Object Type\": \" (1.2.3.4)\"," + + "\"Member Names\": \"[]\",\"rule uid\": \"\",\"comment\": \"\"},{\"change time\": \"05.04.2023 12:00:00\",\"change action\": \"network_object_modified\",\"name\": \"deleted: TestIp1, added: TestIp1Changed\"," + + "\"ObjectType\": \"deleted: network, added: host\",\"Object Type\": \"deleted: (1.2.3.4), added: (2.3.4.5)\",\"Member Names\": \"[]\",\"rule uid\": \"\",\"comment\": \"\"},{\"change time\": \"05.04.2023 12:00:00\"," + + "\"change action\": \"network_object_deleted\",\"name\": \"TestIp2\",\"ObjectType\": \"network\",\"Object Type\": \" (127.0.0.1)\",\"Member Names\": \"[]\",\"rule uid\": \"\",\"comment\": \"\"}]," + + "\"Service Object changes\": [{\"change time\": \"05.04.2023 12:00:00\",\"change action\": \"service_added\",\"name\": \"TestService1\",\"ObjectType\": \"\",\"Protocol\": \"TCP\",\"Port\": \" (443)\",\"Member Names\": \"[]\"," + + "\"rule uid\": \"\",\"comment\": \"\"},{\"change time\": \"05.04.2023 12:00:00\",\"change action\": \"service_modified\",\"name\": \"deleted: TestService1, added: TestService2\",\"ObjectType\": \"\"," + + "\"Protocol\": \"deleted: TCP, added: UDP\",\"Port\": \"deleted: (443), added: (6666-7777)\",\"Member Names\": \"[]\",\"rule uid\": \"\",\"comment\": \"\"},{\"change time\": \"05.04.2023 12:00:00\"," + + "\"change action\": \"service_deleted\",\"name\": \"TestService1\",\"ObjectType\": \"\",\"Protocol\": \"TCP\",\"Port\": \" (443)\",\"Member Names\": \"[]\",\"rule uid\": \"\",\"comment\": \"\"}]}}]}"; + ClassicAssert.AreEqual(expectedJsonResult, RemoveLinebreaks(RemoveGenDate(reportChanges.ExportToJson(), false, true))); + } + + #endregion + private static NetworkLocation[] InitFroms(bool resolved, bool user = false) + { + if (resolved) + { + return [ new NetworkLocation(user ? TestUser1 : new NetworkUser(), new NetworkObject(){ + Type = new NetworkObjectType() { Name = ObjectType.Group }, + ObjectGroupFlats = + [ + new(){ Object = TestIp1 }, + new(){ Object = TestIp2 } + ] + })]; + } + else + { + return + [ + new(user ? TestUser1 : new NetworkUser(), TestIp1), + new(user ? TestUser1 : new NetworkUser(), TestIp2) + ]; + } + } + + private static NetworkLocation[] InitTos(bool resolved, bool user = false) + { + if (resolved) + { + return [ new NetworkLocation(user ? TestUser2 : new NetworkUser(), new NetworkObject(){ + Type = new NetworkObjectType() { Name = ObjectType.Group }, + ObjectGroupFlats = + [ + new(){ Object = TestIpRange } + ] + })]; + } + else + { + return + [ + new(user ? TestUser2 : new NetworkUser(), TestIpRange), + ]; + } + } + + private static ServiceWrapper[] InitServices(NetworkService service, bool resolved) + { + if (resolved) + { + return [new ServiceWrapper(){ Content = new NetworkService(){ + Type = new NetworkServiceType() { Name = ServiceType.Group }, + ServiceGroupFlats = + [ + new GroupFlat(){ Object = service } + ] + } }]; + } + else + { + return + [ + new(){ Content = service }, + ]; + } + } + + private static Rule InitRule1(bool resolved) + { + var srcZoneNames = new[] { "srczn1", "srczn2", "srczn3" }; + var dstZoneNames = new[] { "dstzn1", "dstzn2", "dstzn3" }; + + + return new Rule() + { + Name = "TestRule1", + Action = "accept", + Comment = "comment1", + Disabled = false, + DisplayOrderNumber = 1, + Track = "none", + Uid = "uid1", + RuleFromZones = srcZoneNames.Select(name => new ZoneWrapper { Content = new NetworkZone { Name = name } }).ToArray(), + SourceNegated = false, + Froms = InitFroms(resolved), + RuleToZones = dstZoneNames.Select(name => new ZoneWrapper { Content = new NetworkZone { Name = name } }).ToArray(), + DestinationNegated = false, + Tos = InitTos(resolved), + ServiceNegated = false, + Services = InitServices(TestService1, resolved), + Metadata = new RuleMetadata() { LastHit = new DateTime(2022, 04, 19) }, + LastSeenImport = new ImportControl { StartTime = new DateTime(2023, 04, 05) } + }; + } + + private static Rule InitRule2(bool resolved) + { + return new Rule() + { + Name = "TestRule2", + Action = "deny", + Comment = "comment2", + Disabled = false, + DisplayOrderNumber = 2, + Track = "none", + Uid = "uid2:123", + SourceNegated = true, + Froms = InitFroms(resolved, true), + DestinationNegated = true, + Tos = InitTos(resolved, true), + ServiceNegated = true, + Services = InitServices(TestService2, resolved), + LastSeenImport = new ImportControl { StartTime = new DateTime(2023, 04, 05) } + }; + } + + //If possible use ConstructReportRules below so that this can be deprecated + private static ReportData ConstructRuleReportData(bool resolved) + { + Rule1 = InitRule1(resolved); + Rule2 = InitRule2(resolved); + return new ReportData() + { + ManagementData = + [ + new () + { + Name = "TestMgt", + ReportObjects = [TestIp1, TestIp2, TestIpRange], + ReportServices = [TestService1, TestService2], + ReportUsers = [TestUser1, TestUser2], + Devices = + [ + new () + { + Name = "TestDev" + } + ] + } + ] + }; + } + + private static ReportRules ConstructReportRules(DynGraphqlQuery query, UserConfig userConfig, ReportType reportType, Rule[] rules) + { + RulebaseReport[] rulebases = [ + MockReportRules.CreateRulebaseReport(numberOfRules: 2) + ]; + rulebases.First().Rules = rules; + RulebaseLink[] rulebaseLinks = [ + new() {IsInitial = true,NextRulebaseId = rulebases[0].Id} + ]; + + MockReportRules reportRules = new MockReportRules(query, userConfig, reportType); + + var managementData = reportRules.ReportData.ManagementData.First(); + + managementData.Rulebases = rulebases; + managementData.Devices.First().RulebaseLinks = rulebaseLinks; + + managementData.Name = "TestMgt"; + managementData.ReportObjects = [TestIp1, TestIp2, TestIpRange]; + managementData.ReportServices = [TestService1, TestService2]; + managementData.ReportUsers = [TestUser1, TestUser2]; + + reportRules.ReportData.ManagementData = [managementData]; + + reportRules.TryBuildMockRuleTree(); + + return reportRules; + } + + private static async Task ConstructAppReportRules(DynGraphqlQuery query, UserConfig userConfig, + ReportType reportType, Rule[] rules) + { + ReportRules report = ConstructReportRules(query, userConfig, reportType, rules); + ModellingVarianceAnalysisTestApiConn apiConnection = new(); + report.ReportData.ManagementData = await ReportAppRules.PrepareAppRulesReport(report.ReportData.ManagementData, new ModellingFilter(), apiConnection, 1); + return report; + } + + private Rule[] ConstructRuleReportRules(bool resolved) + { + return [ + InitRule1(resolved), + InitRule2(resolved) + ]; + } + + private Rule[] ConstructRecertReportRules(bool resolved) + { + Rule rule1 = InitRule1(resolved); + rule1.Metadata.RuleRecertification = + [ + new () + { + NextRecertDate = DateTime.Now.AddDays(5), + FwoOwner = new FwoOwner(){ Name = "TestOwner1" }, + IpMatch = TestIp1.Name + }, + new () + { + NextRecertDate = DateTime.Now.AddDays(-5), + FwoOwner = new FwoOwner(){ Name = "TestOwner2" }, + IpMatch = TestIp2.Name + } + ]; + Rule rule2 = InitRule2(resolved); + rule2.Metadata.RuleRecertification = + [ + new () + { + NextRecertDate = DateTime.Now, + FwoOwner = new FwoOwner(){ Name = "TestOwner1" }, + IpMatch = TestIpRange.Name + } + ]; + return [rule1, rule2]; + } + + private static ReportRules ConstructReportRulesWithoutRules(bool resolved, DynGraphqlQuery query, UserConfig userConfig, ReportType reportType) + { + RulebaseReport[] rulebases = [ + MockReportRules.CreateRulebaseReport(numberOfRules: 0) + ]; + RulebaseLink[] rulebaseLinks = [ + new() {IsInitial = true,NextRulebaseId = rulebases[0].Id} + ]; + + MockReportRules reportRules = new MockReportRules(query, userConfig, reportType); + + var managementData = reportRules.ReportData.ManagementData.First(); + + managementData.Rulebases = rulebases; + managementData.Devices.First().RulebaseLinks = rulebaseLinks; + + Rule[] rules = + [ + ]; + + managementData.Rulebases.First().Rules = rules; + managementData.Name = "TestMgt"; + managementData.ReportObjects = [TestIp1, TestIp2, TestIpRange]; + managementData.ReportServices = [TestService1, TestService2]; + managementData.ReportUsers = [TestUser1, TestUser2]; + + reportRules.ReportData.ManagementData = [managementData]; + + reportRules.TryBuildMockRuleTree(); + + return reportRules; + } + + private static ReportData ConstructNatRuleReport() + { + NatRule = InitRule1(false); + NatRule.NatData = new NatData() + { + TranslatedSourceNegated = false, + TranslatedFroms = + [ + new (TestUser2, TestIp1Changed) + ], + TranslatedDestinationNegated = true, + TranslatedTos = + [ + new (new NetworkUser(), TestIp1Changed), + new (new NetworkUser(), TestIpNew) + ], + TranslatedServiceNegated = false, + TranslatedServices = + [ + new (){ Content = TestService1 }, + new (){ Content = TestService2 } + ] + }; + return new ReportData() + { + ManagementData = + [ + new () + { + Name = "TestMgt", + ReportObjects = [TestIp1, TestIp2, TestIpRange, TestIpNew, TestIp1Changed], + ReportServices = [TestService1, TestService2], + ReportUsers = [TestUser2], + Devices = + [ + new (){ Name = "TestDev"} + ] + } + ] + }; + } + + private static ReportData ConstructChangeReport(bool resolved) + { + Rule1 = InitRule1(resolved); + Rule1Changed = InitRule1(resolved); + Rule2 = InitRule2(resolved); + Rule2Changed = InitRule2(resolved); + if (resolved) + { + Rule1Changed.Froms[0].Object.ObjectGroupFlats[0].Object = TestIp1Changed; + Rule1Changed.Tos = [new (new NetworkUser(), new NetworkObject(){ + Type = new NetworkObjectType() { Name = ObjectType.Group }, + ObjectGroupFlats = + [ + new (){ Object = TestIpRange }, + new (){ Object = TestIpNew } + ] + })]; + } + else + { + Rule1Changed.Froms[0].Object = TestIp1Changed; + Rule1Changed.Tos = + [ + new (new NetworkUser(), TestIpRange), + new (new NetworkUser(), TestIpNew) + ]; + } + Rule1Changed.Uid = ""; + Rule1Changed.ServiceNegated = true; + Rule1Changed.Comment = "new comment"; + + Rule2Changed.DestinationNegated = false; + Rule2Changed.ServiceNegated = false; + Rule2Changed.Disabled = true; + + RuleChange ruleChange1 = new() + { + ChangeAction = 'I', + ChangeImport = new ChangeImport() { Time = new DateTime(2023, 04, 05, 12, 0, 0) }, + NewRule = Rule1 + }; + RuleChange ruleChange2 = new() + { + ChangeAction = 'C', + ChangeImport = new ChangeImport() { Time = new DateTime(2023, 04, 05, 12, 0, 0) }, + OldRule = Rule1, + NewRule = Rule1Changed + }; + RuleChange ruleChange3 = new() + { + ChangeAction = 'C', + ChangeImport = new ChangeImport() { Time = new DateTime(2023, 04, 05, 12, 0, 0) }, + OldRule = Rule2, + NewRule = Rule2Changed + }; + RuleChange ruleChange4 = new() + { + ChangeAction = 'D', + ChangeImport = new ChangeImport() { Time = new DateTime(2023, 04, 05, 12, 0, 0) }, + OldRule = Rule2 + }; + ObjectChange objectChange1 = new() + { + ChangeAction = 'I', + ChangeImport = new ChangeImport() { Time = new DateTime(2023, 04, 05, 12, 0, 0) }, + NewObject = TestIp1 + }; + ObjectChange objectChange2 = new() + { + ChangeAction = 'C', + ChangeImport = new ChangeImport() { Time = new DateTime(2023, 04, 05, 12, 0, 0) }, + OldObject = TestIp1, + NewObject = TestIp1Changed + }; + ObjectChange objectChange3 = new() + { + ChangeAction = 'D', + ChangeImport = new ChangeImport() { Time = new DateTime(2023, 04, 05, 12, 0, 0) }, + OldObject = TestIp2 + }; + ServiceChange serviceChange1 = new() + { + ChangeAction = 'I', + ChangeImport = new ChangeImport() { Time = new DateTime(2023, 04, 05, 12, 0, 0) }, + NewService = TestService1 + }; + ServiceChange serviceChange2 = new() + { + ChangeAction = 'C', + ChangeImport = new ChangeImport() { Time = new DateTime(2023, 04, 05, 12, 0, 0) }, + OldService = TestService1, + NewService = TestService2 + }; + ServiceChange serviceChange3 = new() + { + ChangeAction = 'D', + ChangeImport = new ChangeImport() { Time = new DateTime(2023, 04, 05, 12, 0, 0) }, + OldService = TestService1 + }; + + return new ReportData() + { + ManagementData = + [ + new () + { + Name = "TestMgt", + Devices = + [ + new () + { + Name = "TestDev", + } + ], + RuleChanges = [ruleChange1, ruleChange2, ruleChange3, ruleChange4], + ObjectChanges = [objectChange1, objectChange2, objectChange3], + ServiceChanges = [serviceChange1, serviceChange2, serviceChange3] + } + ] + }; + } + + private static async Task ConstructAppRulesReport() + { + ReportData reportData = ConstructRuleReportData(false); + ModellingVarianceAnalysisTestApiConn apiConnection = new(); + reportData.ManagementData = await ReportAppRules.PrepareAppRulesReport(reportData.ManagementData, new ModellingFilter(), apiConnection, 1); + return reportData; + } + + private static ReportData ConstructConnectionReport() + { + ModellingAppServer AppServer1 = new() { Id = 11, Number = 1, Name = "AppServer1", Ip = "1.0.0.0" }; + ModellingAppServer AppServer2 = new() { Id = 12, Number = 2, Name = "AppServer2", Ip = "2.0.0.0" }; + ModellingAppRole AppRole1 = new() { Id = 21, Number = 3, Name = "AppRole1", IdString = "AR1", Comment = "CommAR1", AppServers = [new() { Content = AppServer1 }] }; + ModellingService Service1 = new() { Id = 31, Number = 1, Name = "Service1", Port = 1234, Protocol = new() { Id = 6, Name = "TCP" } }; + ModellingService Service2 = new() { Id = 32, Number = 2, Name = "Service2", Port = 2345, Protocol = new() { Id = 17, Name = "UDP" } }; + ModellingServiceGroup ServiceGroup1 = new() { Id = 41, Number = 3, Name = "ServiceGroup1", Comment = "CommSG1", Services = [new() { Content = Service1 }] }; + ModellingConnection Conn1 = new() + { + Id = 101, + Name = "Conn1", + SourceAppServers = [new() { Content = AppServer1 }], + DestinationAppRoles = [new() { Content = AppRole1 }], + Services = [new() { Content = Service1 }], + ServiceGroups = [new() { Content = ServiceGroup1 }] + }; + ModellingConnection Inter2 = new() + { + Id = 102, + Name = "Inter2", + DestinationAppServers = [new() { Content = AppServer2 }], + DestinationAppRoles = [new() { Content = new() { Name = "noRole" } }], + Services = [new() { Content = Service2 }], + ServiceGroups = [new() { }] + }; + ModellingConnection ComSvc3 = new() + { + Id = 103, + Name = "ComSvc3", + App = new() { Name = "App1" }, + SourceAppServers = [new() { Content = AppServer1 }], + DestinationAppServers = [new() { Content = AppServer2 }], + Services = [new() { Content = Service2 }], + ServiceGroups = [new() { }] + }; + + ReportData reportData = new() + { + OwnerData = + [ + new () + { + Name = "TestOwner", + Owner = new() + { + Name = "TestOwner", + ExtAppId = "APP-1234" + }, + Connections = [Conn1, Inter2, ComSvc3], + RegularConnections = [Conn1], + Interfaces = [Inter2], + CommonServices = [ComSvc3], + } + ], + GlobalComSvc = [new() { GlobalComSvcs = [ComSvc3] }] + }; + reportData.OwnerData[0].PrepareObjectData(true); + return reportData; + } + + private static ReportData ConstructVarianceReport() + { + ModellingAppServer AppServer1 = new() { Id = 11, Number = 1, Name = "AppServer1", Ip = "1.0.0.0" }; + ModellingAppServer AppServer2 = new() { Id = 12, Number = 2, Name = "AppServer2", Ip = "2.0.0.0" }; + ModellingAppRole AppRole1 = new() { Id = 21, Number = 3, Name = "AppRole1", IdString = "AR1", Comment = "CommAR1", AppServers = [new() { Content = AppServer1 }] }; + ModellingAppRole AppRole2 = new() { Id = 22, Number = 4, Name = "AppRole2", IdString = "AR2", Comment = "CommAR2", AppServers = [new() { Content = AppServer2 }] }; + NetworkSubnet Subnet1 = new() { Id = 1, Name = "Net1", Ip = "1.0.0.0" }; + ModellingNetworkArea Area1 = new() { Id = 51, Number = 5, Name = "Area50", IdString = "NA50", IpData = [new() { Content = Subnet1 }] }; + Dictionary> MissAR = new() { [0] = [AppRole1] }; + Dictionary> DiffAR = new() { [0] = [AppRole2] }; + ModellingService Service1 = new() { Id = 31, Number = 1, Name = "Service1", Port = 1234, Protocol = new() { Id = 6, Name = "TCP" } }; + ModellingServiceGroup ServiceGroup1 = new() { Id = 41, Number = 3, Name = "ServiceGroup1", Comment = "CommSG1", Services = [new() { Content = Service1 }] }; + ModellingConnection Conn1 = new() + { + Id = 101, + Name = "Conn1", + SourceAppServers = [new() { Content = AppServer1 }], + SourceAppRoles = [new() { Content = AppRole1 }], + SourceAreas = [new() { Content = Area1 }], + DestinationAppRoles = [new() { Content = AppRole2 }], + Services = [new() { Content = Service1 }], + ServiceGroups = [new() { Content = ServiceGroup1 }] + }; + ModellingConnection Conn2 = new() + { + Id = 102, + Name = "Conn2", + SourceAppServers = [new() { Content = AppServer1 }], + DestinationAppRoles = [new() { Content = AppRole2 }], + Services = [new() { Content = Service1 }], + }; + Rule1 = InitRule1(true); + + ReportData reportData = new() + { + OwnerData = + [ + new () + { + Name = "TestOwner", + Connections = [Conn1], + RegularConnections = [Conn1], + MissingAppRoles = MissAR, + DifferingAppRoles = DiffAR, + RuleDifferences = [], + ModelledConnectionsCount = 2, + AppRoleStats = new() + { + ModelledAppRolesCount = 2, + AppRolesOk = 0, + AppRolesMissingCount = 1, + AppRolesDifferenceCount = 1 + } + } + ] + }; + reportData.OwnerData[0].RuleDifferences.Add(new() { ModelledConnection = Conn2, ImplementedRules = [Rule1] }); + reportData.OwnerData[0].PrepareObjectData(true); + return reportData; + } + + private static ReportData ConstructOwnerRecertReport(int recertificationDisplayPeriod = 7, bool withNullFurtherDate = false, bool withMultipleInactiveOwners = false) + { + List ownerData = + [ + new() + { + Owner = new() + { + Id = 1, + Name = "Overdue Owner", + ExtAppId = "EXT-OVERDUE", + RecertActive = true, + RecertOverdue = true, + NextRecertDate = DateTime.Today.AddDays(-1), + LastRecertified = DateTime.Today.AddDays(-30), + LastRecertifierDn = "cn=overdue.user,ou=users,dc=test,dc=local" + } + }, + new() + { + Owner = new() + { + Id = 2, + Name = "Upcoming Owner", + ExtAppId = "EXT-UPCOMING", + RecertActive = true, + RecertUpcoming = recertificationDisplayPeriod > 0, + NextRecertDate = DateTime.Today.AddDays(3), + LastRecertified = DateTime.Today.AddDays(-20), + LastRecertifierDn = "cn=upcoming.user,ou=users,dc=test,dc=local" + } + }, + new() + { + Owner = new() + { + Id = 3, + Name = "Further Owner", + ExtAppId = "EXT-FURTHER", + RecertActive = true, + NextRecertDate = withNullFurtherDate ? null : DateTime.Today.AddDays(20), + LastRecertified = DateTime.Today.AddDays(-10), + LastRecertifierDn = "cn=further.user,ou=users,dc=test,dc=local" + } + }, + new() + { + Owner = new() + { + Id = 4, + Name = "Inactive Owner", + ExtAppId = "EXT-INACTIVE", + RecertActive = false + } + } + ]; + + if (withMultipleInactiveOwners) + { + ownerData.Add(new() + { + Owner = new() + { + Id = 0, + Name = "Inactive Owner Low", + ExtAppId = "EXT-INACTIVE-LOW", + RecertActive = false + } + }); + } + + return new ReportData() + { + RecertificationDisplayPeriod = recertificationDisplayPeriod, + OwnerData = ownerData + }; + } + + private static string RemoveGenDate(string exportString, bool html = false, bool json = false) + { + string Quote = json ? "\"" : ""; + string dateText = html ? "

                      Generated on: " : "report generation date" + Quote + ": " + Quote; + int startGenTime = exportString.IndexOf(dateText); + if (startGenTime > 0) + { + return exportString.Remove(startGenTime + dateText.Length, 19); + } + return exportString; + } + + private static string RemoveLinebreaks(string exportString) + { + while (exportString.Contains("\n ")) + { + exportString = exportString.Replace("\n ", "\n"); + } + while (exportString.Contains(" \n")) + { + exportString = exportString.Replace(" \n", "\n"); + } + while (exportString.Contains(" \r")) + { + exportString = exportString.Replace(" \r", "\r"); + } + exportString = exportString.Replace("\r", ""); + return exportString.Replace("\n", ""); + } + } +} diff --git a/roles/tests-unit/files/FWO.Test/ExtRequestSenderTest.cs b/roles/tests-unit/files/FWO.Test/ExtRequestSenderTest.cs new file mode 100644 index 0000000000..ecd44084dd --- /dev/null +++ b/roles/tests-unit/files/FWO.Test/ExtRequestSenderTest.cs @@ -0,0 +1,99 @@ +using NUnit.Framework; +using NUnit.Framework.Legacy; +using FWO.Basics.Exceptions; +using FWO.Data; +using FWO.Middleware.Server; +using FWO.ExternalSystems.Tufin.SecureChange; + +namespace FWO.Test +{ + [TestFixture] + [Parallelizable] + internal class ExtRequestSenderTest + { + readonly static ExternalTicketSystem ticketSystem = new() + { + Id = 1, + Type = ExternalTicketSystemType.TufinSecureChange, + Authorization = "xyz", + Name = "Tufin", + Url = "https://tufin-test.xxx.de/securechangeworkflow/api/securechange/", + Templates = + [ + new() + { + TaskType = SCTaskType.NetworkObjectModify.ToString(), + TicketTemplate = "{\"ticket\":{\"subject\":\"@@TICKET_SUBJECT@@\",\"priority\":\"@@PRIORITY@@\",\"requester\":\"@@ONBEHALF@@\",\"domain_name\":\"\",\"workflow\":{\"name\":\"Automatische Gruppenerstellung\"},\"steps\":{\"step\":[{\"name\":\"Erfassung des Antrags\",\"tasks\":{\"task\":{\"fields\":{\"field\":[@@TASKS@@]}}}}]}}}", + TasksTemplate = "{\"@xsi.type\": \"multi_group_change\",\"name\": \"Modify network object group\",\"group_change\": {\"name\": \"@@GROUPNAME@@\",\"management_name\": \"@@MANAGEMENT_NAME@@\",\"members\": {\"member\": @@MEMBERS@@},\"change_action\": \"CREATE\"}}", + ObjectTemplate = "{\"@type\": \"@@TYPE@@\", \"name\": \"@@OBJECTNAME@@\", \"object_type\": \"@@OBJECT_TYPE@@\", \"object_details\": \"@@OBJECT_DETAILS@@\", \"status\": \"@@STATUS@@\", \"comment\": \"@@COMMENT@@\", \"object_updated_status\": \"@@OBJUPDSTATUS@@\", \"management_id\": @@MANAGEMENT_ID@@}", + ObjectTemplateShort = "{\"@type\": \"Object\", \"name\": \"@@OBJECTNAME@@\", \"status\": \"@@STATUS@@\", \"object_updated_status\": \"@@OBJUPDSTATUS@@\"}" + }, + new() + { + TaskType = SCTaskType.AccessRequest.ToString(), + TicketTemplate = "{\"ticket\":{\"subject\":\"@@TICKET_SUBJECT@@\",\"priority\":\"@@PRIORITY@@\",\"requester\":\"@@ONBEHALF@@\",\"domain_name\":\"\",\"workflow\":{\"name\":\"Standard Firewall Request\"},\"steps\":{\"step\":[{\"name\":\"Erfassung des Antrags\",\"tasks\":{\"task\":{\"fields\":{\"field\":[{\"@xsi.type\": \"multi_access_request\",\"name\": \"Zugang\",\"read_only\": false,\"access_request\":[@@TASKS@@]},{\"@xsi.type\": \"text_area\",\"name\": \"Grund für den Antrag\",\"read_only\": false,\"text\": \"@@REASON@@\"},{\"@xsi.type\": \"text_field\",\"name\": \"Anwendungs-ID\",\"text\": \"@@APPID@@\"},{\"@xsi.type\": \"checkbox\",\"name\": \"hinterlegt\",\"value\": true}]}}}}]}}}}", + TasksTemplate = "{\"order\": \"@@ORDERNAME@@\",\"verifier_result\": {\"status\": \"not run\"},\"use_topology\": true,\"targets\": {\"target\": {\"@type\": \"ANY\"}},\"action\": \"@@ACTION@@\",\"sources\":{\"source\":@@SOURCES@@},\"destinations\":{\"destination\":@@DESTINATIONS@@},\"services\":{\"service\":@@SERVICES@@},\"labels\":\"\",\"comment\": \"@@TASKCOMMENT@@\"}", + IpTemplate = "{\"@type\": \"IP\", \"ip_address\": \"@@IP@@\", \"netmask\": \"255.255.255.255\", \"cidr\": 32}", + NwObjGroupTemplate = "{\"@type\": \"Object\", \"object_name\": \"@@GROUPNAME@@\", \"management_name\": \"@@MANAGEMENT_NAME@@\"}", + ServiceTemplate = "{\"@type\": \"PROTOCOL\", \"protocol\": \"@@PROTOCOLNAME@@\", \"port\": @@PORT@@, \"name\": \"@@SERVICENAME@@\"}", + IcmpTemplate = "{\"@type\": \"PROTOCOL\", \"protocol\": \"ICMP\", \"type\": 8, \"name\": \"@@SERVICENAME@@\"}" + } + ] + }; + readonly static string reqPrios = "[{\"numeric_prio\":1,\"name\":\"Highest\",\"ticket_deadline\":1,\"approval_deadline\":1},{\"numeric_prio\":2,\"name\":\"High\",\"ticket_deadline\":3,\"approval_deadline\":2},{\"numeric_prio\":3,\"name\":\"Medium\",\"ticket_deadline\":7,\"approval_deadline\":3},{\"numeric_prio\":4,\"name\":\"Low\",\"ticket_deadline\":14,\"approval_deadline\":7},{\"numeric_prio\":5,\"name\":\"Lowest\",\"ticket_deadline\":30,\"approval_deadline\":14}]"; + readonly static string namingConvention = "{\"networkAreaRequired\":true,\"useAppPart\":true,\"fixedPartLength\":4,\"freePartLength\":3,\"networkAreaPattern\":\"NA\",\"appRolePattern\":\"AR\",\"applicationZone\":\"AZ\",\"appServerPrefix\":\"host_\",\"networkPrefix\":\"net_\",\"ipRangePrefix\":\"range_\"}"; + + readonly static List ticketSystemList = [ticketSystem]; + readonly SimulatedGlobalConfig globalConfig = new() + { + ExternalRequestWaitCycles = 3, + ExtTicketSystems = System.Text.Json.JsonSerializer.Serialize(ticketSystemList), + ReqPriorities = reqPrios, + ModNamingConvention = namingConvention + }; + readonly ExtRequestSenderTestApiConn apiConnection = new(); + + private string ExceptionMessage = ""; + + + [SetUp] + public void Initialize() + { + + } + + [Test] + public async Task TestExternalRequestSender() + { + try + { + SimulatedSCClient simulatedSCClient = new(ticketSystem); + ExternalRequestSender externalRequestSender = new(apiConnection, globalConfig, simulatedSCClient); + List FailedRequests = await externalRequestSender.Run(); + if (FailedRequests.Count > 0) + { + throw new ProcessingFailedException($"External Request(s) failed: {string.Join(". ", FailedRequests)}."); + } + } + catch (Exception exc) + { + ExceptionMessage = exc.Message; + } + + ClassicAssert.AreEqual(true, ExceptionMessage.Contains("External Request(s) failed:")); + ClassicAssert.AreEqual(true, ExceptionMessage.Contains("Request Id: 4")); + ClassicAssert.AreEqual(true, ExceptionMessage.Contains("Request Id: 5")); + ClassicAssert.AreEqual(3, apiConnection.UpdateExtRequestCreation.Count); + ClassicAssert.AreEqual(false, apiConnection.UpdateExtRequestCreation[0].Contains("id = 1")); + ClassicAssert.AreEqual(true, apiConnection.UpdateExtRequestCreation[0].Contains("id = 2")); + ClassicAssert.AreEqual(true, apiConnection.UpdateExtRequestCreation[1].Contains("id = 3")); + ClassicAssert.AreEqual(true, apiConnection.UpdateExtRequestCreation[2].Contains("id = 3")); + ClassicAssert.AreEqual(2, apiConnection.UpdateExtRequestProcess.Count); + ClassicAssert.AreEqual(2, apiConnection.UpdateExtRequestProcess.Count); + ClassicAssert.AreEqual(true, apiConnection.UpdateExtRequestProcess[0].Contains("id = 4")); + ClassicAssert.AreEqual(true, apiConnection.UpdateExtRequestProcess[1].Contains("id = 5")); + ClassicAssert.AreEqual(3, apiConnection.TriedToGetLdapsForHandleStateChange); + } + } +} + diff --git a/roles/tests-unit/files/FWO.Test/ExtRequestSenderTestApiConn.cs b/roles/tests-unit/files/FWO.Test/ExtRequestSenderTestApiConn.cs new file mode 100644 index 0000000000..5be68c922e --- /dev/null +++ b/roles/tests-unit/files/FWO.Test/ExtRequestSenderTestApiConn.cs @@ -0,0 +1,150 @@ +using FWO.Api.Client.Queries; +using FWO.Config.Api.Data; +using FWO.Data; +using FWO.Data.Workflow; +using FWO.Middleware.Server; +using FWO.Services; +using FWO.ExternalSystems.Tufin.SecureChange; +using GraphQL; + +namespace FWO.Test +{ + internal class ExtRequestSenderTestApiConn : SimulatedApiConnection + { + public List UpdateExtRequestCreation = []; + public List UpdateExtRequestProcess = []; + public int TriedToGetLdapsForHandleStateChange = 0; + + readonly ExternalTicketSystem ticketSystem = new() + { + Id = 1, + Type = ExternalTicketSystemType.TufinSecureChange, + Authorization = "xyz", + Name = "Tufin", + Url = "https://tufin-test.xxx.de/securechangeworkflow/api/securechange/", + Templates = + [ + new() + { + TaskType = SCTaskType.NetworkObjectModify.ToString(), + TicketTemplate = "{\"ticket\":{\"subject\":\"@@TICKET_SUBJECT@@\",\"priority\":\"@@PRIORITY@@\",\"requester\":\"@@ONBEHALF@@\",\"domain_name\":\"\",\"workflow\":{\"name\":\"Automatische Gruppenerstellung\"},\"steps\":{\"step\":[{\"name\":\"Erfassung des Antrags\",\"tasks\":{\"task\":{\"fields\":{\"field\":[@@TASKS@@]}}}}]}}}", + TasksTemplate = "{\"@xsi.type\": \"multi_group_change\",\"name\": \"Modify network object group\",\"group_change\": {\"name\": \"@@GROUPNAME@@\",\"management_name\": \"@@MANAGEMENT_NAME@@\",\"members\": {\"member\": @@MEMBERS@@},\"change_action\": \"CREATE\"}}", + ObjectTemplate = "{\"@type\": \"@@TYPE@@\", \"name\": \"@@OBJECTNAME@@\", \"object_type\": \"@@OBJECT_TYPE@@\", \"object_details\": \"@@OBJECT_DETAILS@@\", \"status\": \"@@STATUS@@\", \"comment\": \"@@COMMENT@@\", \"object_updated_status\": \"@@OBJUPDSTATUS@@\", \"management_id\": @@MANAGEMENT_ID@@}", + ObjectTemplateShort = "{\"@type\": \"Object\", \"name\": \"@@OBJECTNAME@@\", \"status\": \"@@STATUS@@\", \"object_updated_status\": \"@@OBJUPDSTATUS@@\"}" + }, + new() + { + TaskType = SCTaskType.AccessRequest.ToString(), + TicketTemplate = "{\"ticket\":{\"subject\":\"@@TICKET_SUBJECT@@\",\"priority\":\"@@PRIORITY@@\",\"requester\":\"@@ONBEHALF@@\",\"domain_name\":\"\",\"workflow\":{\"name\":\"Standard Firewall Request\"},\"steps\":{\"step\":[{\"name\":\"Erfassung des Antrags\",\"tasks\":{\"task\":{\"fields\":{\"field\":[{\"@xsi.type\": \"multi_access_request\",\"name\": \"Zugang\",\"read_only\": false,\"access_request\":[@@TASKS@@]},{\"@xsi.type\": \"text_area\",\"name\": \"Grund für den Antrag\",\"read_only\": false,\"text\": \"@@REASON@@\"},{\"@xsi.type\": \"text_field\",\"name\": \"Anwendungs-ID\",\"text\": \"@@APPID@@\"},{\"@xsi.type\": \"checkbox\",\"name\": \"hinterlegt\",\"value\": true}]}}}}]}}}}", + TasksTemplate = "{\"order\": \"@@ORDERNAME@@\",\"verifier_result\": {\"status\": \"not run\"},\"use_topology\": true,\"targets\": {\"target\": {\"@type\": \"ANY\"}},\"action\": \"@@ACTION@@\",\"sources\":{\"source\":@@SOURCES@@},\"destinations\":{\"destination\":@@DESTINATIONS@@},\"services\":{\"service\":@@SERVICES@@},\"labels\":\"\",\"comment\": \"@@TASKCOMMENT@@\"}", + IpTemplate = "{\"@type\": \"IP\", \"ip_address\": \"@@IP@@\", \"netmask\": \"255.255.255.255\", \"cidr\": 32}", + NwObjGroupTemplate = "{\"@type\": \"Object\", \"object_name\": \"@@GROUPNAME@@\", \"management_name\": \"@@MANAGEMENT_NAME@@\"}", + ServiceTemplate = "{\"@type\": \"PROTOCOL\", \"protocol\": \"@@PROTOCOLNAME@@\", \"port\": @@PORT@@, \"name\": \"@@SERVICENAME@@\"}", + IcmpTemplate = "{\"@type\": \"PROTOCOL\", \"protocol\": \"ICMP\", \"type\": 8, \"name\": \"@@SERVICENAME@@\"}" + } + ] + }; + + private readonly string TicketContent = "{ \"ticketText\": \"\" }"; + // private readonly string TicketContent = "{\"ticketText\": \"{ \"ticket\": { \"subject\": \"tick2\"} }\" }"; + // private readonly string TicketContent = "{\"ticketText\": \"{ \u0022ticket\u0022: { \u0022subject\u0022: \u0022tick2\u0022} }\" }"; + // private readonly string TicketContent = "{\"ticketText\": {\"ticket\": { \"subject\": \"tick2\"} }, \"ticketId\": \"2\"}"; + // private readonly string TicketContent = "{\"ticketText\":\"{\u0022ticket\u0022:{\u0022subject\u0022:\u0022APP-3714: Create Group AZ03714 on checkpoint_demo(2)\u0022,\u0022priority\u0022:\u0022Low\u0022,\u0022requester\u0022:\u0022modeller\u0022,\u0022domain_name\u0022:\u0022\u0022,\u0022workflow\u0022:{\u0022name\u0022:\u0022Automatische Gruppenerstellung\u0022},\u0022steps\u0022:{\u0022step\u0022:[{\u0022name\u0022:\u0022Erfassung des Antrags\u0022,\u0022tasks\u0022:{\u0022task\u0022:{\u0022fields\u0022:{\u0022field\u0022:[{\u0022@xsi.type\u0022: \u0022multi_group_change\u0022,\u0022name\u0022: \u0022Modify network object group\u0022,\u0022group_change\u0022: {\u0022name\u0022: \u0022AZ03714\u0022,\u0022management_id\u0022: 1,\u0022management_name\u0022: \u0022ExtCP\u0022,\u0022members\u0022: {\u0022member\u0022: [{\u0022@type\u0022: \u0022host\u0022, \u0022name\u0022: \u0022d172-218-137-115.bchsia.telus.net\u0022, \u0022object_type\u0022: \u0022host\u0022, \u0022object_details\u0022: \u0022172.218.137.115/32\u0022, \u0022management_id\u0022: 1,\u0022status\u0022: \u0022ADDED\u0022, \u0022comment\u0022: \u0022\u0022, \u0022object_updated_status\u0022: \u0022NEW\u0022},{\u0022@type\u0022: \u0022host\u0022, \u0022name\u0022: \u0022d172-218-137-118.bchsia.telus.net\u0022, \u0022object_type\u0022: \u0022host\u0022, \u0022object_details\u0022: \u0022172.218.137.119/32\u0022, \u0022management_id\u0022: 1,\u0022status\u0022: \u0022ADDED\u0022, \u0022comment\u0022: \u0022\u0022, \u0022object_updated_status\u0022: \u0022NEW\u0022},{\u0022@type\u0022: \u0022host\u0022, \u0022name\u0022: \u0022tzhdfh-in-f165.1e100.net\u0022, \u0022object_type\u0022: \u0022host\u0022, \u0022object_details\u0022: \u0022172.217.67.165/32\u0022, \u0022management_id\u0022: 1,\u0022status\u0022: \u0022ADDED\u0022, \u0022comment\u0022: \u0022\u0022, \u0022object_updated_status\u0022: \u0022NEW\u0022},{\u0022@type\u0022: \u0022host\u0022, \u0022name\u0022: \u0022tzhdfh-in-f175.1e100.net\u0022, \u0022object_type\u0022: \u0022host\u0022, \u0022object_details\u0022: \u0022172.217.67.175/32\u0022, \u0022management_id\u0022: 1,\u0022status\u0022: \u0022ADDED\u0022, \u0022comment\u0022: \u0022\u0022, \u0022object_updated_status\u0022: \u0022NEW\u0022}]},\u0022change_action\u0022: \u0022CREATE\u0022}}]}}}}]}}}\",\"TicketId\":\"\"}"; + + public override async Task SendQueryAsync(string query, object? variables = null, string? operationName = null) + { + await DefaultInit.DoNothing(); // qad avoid compiler warning + Type responseType = typeof(QueryResponseType); + if (responseType == typeof(ConfigItem[])) + { + ConfigItem[] configItems = SimulatedUserConfig.GetAsConfigs(); + GraphQLResponse response = new() { Data = configItems }; + return response.Data; + } + if (responseType == typeof(List)) + { + List texts = []; + GraphQLResponse response = new() { Data = texts }; + return response.Data; + } + else if (responseType == typeof(ExternalRequestDataHelper)) + { + string serializedTicketSystem = System.Text.Json.JsonSerializer.Serialize(ticketSystem); + ExternalRequestDataHelper openRequests = new() + { + ExternalRequests = + [ + new(){ Id = 1, TicketId = 1, ExtTicketSystem = serializedTicketSystem, ExtRequestState = ExtStates.ExtReqInitialized.ToString(), + WaitCycles = 2 }, // wait + new(){ Id = 2, TicketId = 2, ExtTicketSystem = serializedTicketSystem, ExtRequestState = ExtStates.ExtReqInitialized.ToString(), + ExtRequestContent = TicketContent }, // create + new(){ Id = 3, TicketId = 3, ExtTicketSystem = serializedTicketSystem, ExtRequestState = ExtStates.ExtReqFailed.ToString(), + ExtRequestContent = TicketContent }, // create reject + new(){ Id = 4, TicketId = 4, ExtTicketSystem = serializedTicketSystem, ExtRequestState = ExtStates.ExtReqInProgress.ToString(), + ExtTicketId = "4711" }, // poll error + new(){ Id = 5, TicketId = 5, ExtTicketSystem = serializedTicketSystem, ExtRequestState = ExtStates.ExtReqInProgress.ToString(), + ExtTicketId = "4712" } // poll ok + new request + ] + }; + GraphQLResponse response = new() { Data = openRequests }; + return response.Data; + } + else if (responseType == typeof(List)) + { + List? extStates = + [ + new(){ Id = 1, Name = "ExtReqInitialized", StateId = 1 }, + new(){ Id = 2, Name = "ExtReqRequested", StateId = 3 }, + new(){ Id = 3, Name = "ExtReqDone", StateId = 631 } + ]; + GraphQLResponse response = new() { Data = extStates }; + return response.Data; + } + else if (responseType == typeof(List)) + { + TriedToGetLdapsForHandleStateChange++; + List? ldaps = + [ + new(){ Id = 1, GroupSearchPath = "path", UserSearchPath = "dc=fworch,dc=internal" } + ]; + GraphQLResponse response = new() { Data = ldaps }; + return response.Data; + } + else if (responseType == typeof(ReturnId)) + { + if (query == ExtRequestQueries.updateExternalRequestWaitCycles) + { + if (variables == null || (!variables.ToString()?.Contains("waitCycles = 1") ?? true)) + { + throw new ArgumentException("wrong wait cycles"); + } + ReturnId returnId = new() { UpdatedIdLong = 1 }; + GraphQLResponse response = new() { Data = returnId }; + return response.Data; + } + else if (query == ExtRequestQueries.updateExtRequestCreation) + { + UpdateExtRequestCreation.Add(variables?.ToString() ?? "no variables"); + ReturnId returnId = new() { UpdatedIdLong = 1 }; + GraphQLResponse response = new() { Data = returnId }; + return response.Data; + } + else if (query == ExtRequestQueries.updateExtRequestProcess) + { + UpdateExtRequestProcess.Add(variables?.ToString() ?? "no variables"); + ReturnId returnId = new() { UpdatedIdLong = 1 }; + GraphQLResponse response = new() { Data = returnId }; + return response.Data; + } + else if (query == ExtRequestQueries.updateExternalRequestLock) + { + ReturnId returnId = new() { UpdatedIdLong = 1 }; + GraphQLResponse response = new() { Data = returnId }; + return response.Data; + } + } + + throw new NotImplementedException(); + } + } +} diff --git a/roles/tests-unit/files/FWO.Test/ExtStateHandlerTest.cs b/roles/tests-unit/files/FWO.Test/ExtStateHandlerTest.cs new file mode 100644 index 0000000000..3fcabbf1b8 --- /dev/null +++ b/roles/tests-unit/files/FWO.Test/ExtStateHandlerTest.cs @@ -0,0 +1,68 @@ +using FWO.Api.Client; +using FWO.Api.Client.Queries; +using FWO.Data; +using FWO.Data.Workflow; +using FWO.Services; +using FWO.Services.Workflow; +using NUnit.Framework; + +namespace FWO.Test +{ + [TestFixture] + public class ExtStateHandlerTest + { + private sealed class ExtStateSuccessApiConn : SimulatedApiConnection + { + public bool QueryCalled { get; private set; } + + public override async Task> SendQuerySafeAsync(string query, object? variables = null, string? operationName = null) + { + await DefaultInit.DoNothing(); + if (typeof(QueryResponseType) == typeof(List)) + { + if (query == RequestQueries.getExtStates) + { + QueryCalled = true; + List extStates = + [ + new() { Id = 1, Name = "ExtReqInitialized", StateId = 1 }, + new() { Id = 2, Name = "ExtReqDone", StateId = 631 } + ]; + return (ApiResponse)(object)new ApiResponse>(extStates); + } + } + throw new NotImplementedException(); + } + } + + private sealed class ExtStateErrorApiConn : SimulatedApiConnection + { + public override async Task> SendQuerySafeAsync(string query, object? variables = null, string? operationName = null) + { + await DefaultInit.DoNothing(); + if (typeof(QueryResponseType) == typeof(List)) + { + return (ApiResponse)(object)new ApiResponse>( + "field request_ext_state not found in type: query_root"); + } + throw new NotImplementedException(); + } + } + + [Test] + public void InitUsesRequestExtStateQuery() + { + ExtStateSuccessApiConn apiConn = new(); + ExtStateHandler handler = new(apiConn); + + Assert.That(handler.GetInternalStateId(ExtStates.ExtReqDone), Is.EqualTo(631)); + Assert.That(apiConn.QueryCalled, Is.True); + } + + [Test] + public void InitThrowsWhenExtStateQueryFails() + { + Assert.Throws(() => new ExtStateHandler(new ExtStateErrorApiConn())); + } + } +} diff --git a/roles/tests-unit/files/FWO.Test/ExtStateTestApiConn.cs b/roles/tests-unit/files/FWO.Test/ExtStateTestApiConn.cs new file mode 100644 index 0000000000..568cf529ff --- /dev/null +++ b/roles/tests-unit/files/FWO.Test/ExtStateTestApiConn.cs @@ -0,0 +1,29 @@ +using GraphQL; +using FWO.Data; +using FWO.Data.Workflow; +using FWO.Services; + +namespace FWO.Test +{ + internal class ExtStateTestApiConn : SimulatedApiConnection + { + public override async Task SendQueryAsync(string query, object? variables = null, string? operationName = null) + { + await DefaultInit.DoNothing(); // qad avoid compiler warning + Type responseType = typeof(QueryResponseType); + if (responseType == typeof(List)) + { + List? extStates = + [ + new(){ Id = 1, Name = "ExtReqInitialized", StateId = 1 }, + new(){ Id = 2, Name = "ExtReqRequested", StateId = 2 }, + new(){ Id = 3, Name = "ExtReqDone", StateId = 631 } + ]; + GraphQLResponse response = new() { Data = extStates }; + return response.Data; + } + + throw new NotImplementedException(); + } + } +} diff --git a/roles/tests-unit/files/FWO.Test/ExtTicketHandlerTest.cs b/roles/tests-unit/files/FWO.Test/ExtTicketHandlerTest.cs new file mode 100644 index 0000000000..1487ab6f06 --- /dev/null +++ b/roles/tests-unit/files/FWO.Test/ExtTicketHandlerTest.cs @@ -0,0 +1,280 @@ +using NUnit.Framework; +using NUnit.Framework.Legacy; +using FWO.Config.Api; +using FWO.Data; +using FWO.Data.Workflow; +using FWO.Data.Modelling; +using FWO.ExternalSystems.Tufin.SecureChange; +using FWO.Middleware.Server; + +namespace FWO.Test +{ + [TestFixture] + [Parallelizable] + internal class ExtTicketHandlerTest + { + readonly static ExternalTicketSystem ticketSystem = new() + { + Id = 1, + Type = ExternalTicketSystemType.TufinSecureChange, + Authorization = "xyz", + Name = "Tufin", + Url = "https://tufin-test.xxx.de/securechangeworkflow/api/securechange/", + Templates = + [ + new() + { + TaskType = SCTaskType.NetworkObjectModify.ToString(), + TicketTemplate = "{\"ticket\":{\"subject\":\"@@TICKET_SUBJECT@@\",\"priority\":\"@@PRIORITY@@\",\"requester\":\"@@ONBEHALF@@\",\"domain_name\":\"\",\"workflow\":{\"name\":\"Automatische Gruppenerstellung\"},\"steps\":{\"step\":[{\"name\":\"Erfassung des Antrags\",\"tasks\":{\"task\":{\"fields\":{\"field\":[@@TASKS@@]}}}}]}}}", + TasksTemplate = "{\"@xsi.type\": \"multi_group_change\",\"name\": \"Modify network object group\",\"group_change\": {\"name\": \"@@GROUPNAME@@\",\"management_name\": \"@@MANAGEMENT_NAME@@\",\"members\": {\"member\": @@MEMBERS@@},\"change_action\": \"CREATE\"}}", + ObjectTemplate = "{\"@type\": \"@@TYPE@@\", \"name\": \"@@OBJECTNAME@@\", \"object_type\": \"@@OBJECT_TYPE@@\", \"object_details\": \"@@OBJECT_DETAILS@@\", \"status\": \"@@STATUS@@\", \"comment\": \"@@COMMENT@@\", \"object_updated_status\": \"@@OBJUPDSTATUS@@\", \"management_id\": @@MANAGEMENT_ID@@}", + ObjectTemplateShort = "{\"@type\": \"Object\", \"name\": \"@@OBJECTNAME@@\", \"status\": \"@@STATUS@@\", \"object_updated_status\": \"@@OBJUPDSTATUS@@\"}" + }, + new() + { + TaskType = SCTaskType.AccessRequest.ToString(), + TicketTemplate = "{\"ticket\":{\"subject\":\"@@TICKET_SUBJECT@@\",\"priority\":\"@@PRIORITY@@\",\"requester\":\"@@ONBEHALF@@\",\"domain_name\":\"\",\"workflow\":{\"name\":\"Standard Firewall Request\"},\"steps\":{\"step\":[{\"name\":\"Erfassung des Antrags\",\"tasks\":{\"task\":{\"fields\":{\"field\":[{\"@xsi.type\": \"multi_access_request\",\"name\": \"Zugang\",\"read_only\": false,\"access_request\":[@@TASKS@@]},{\"@xsi.type\": \"text_area\",\"name\": \"Grund für den Antrag\",\"read_only\": false,\"text\": \"@@REASON@@\"},{\"@xsi.type\": \"text_field\",\"name\": \"Anwendungs-ID\",\"text\": \"@@APPID@@\"},{\"@xsi.type\": \"checkbox\",\"name\": \"hinterlegt\",\"value\": true}]}}}}]}}}}", + TasksTemplate = "{\"order\": \"@@ORDERNAME@@\",\"verifier_result\": {\"status\": \"not run\"},\"use_topology\": true,\"targets\": {\"target\": {\"@type\": \"ANY\"}},\"action\": \"@@ACTION@@\",\"sources\":{\"source\":@@SOURCES@@},\"destinations\":{\"destination\":@@DESTINATIONS@@},\"services\":{\"service\":@@SERVICES@@},\"labels\":\"\",\"comment\": \"@@TASKCOMMENT@@\"}", + IpTemplate = "{\"@type\": \"IP\", \"ip_address\": \"@@IP@@\", \"netmask\": \"255.255.255.255\", \"cidr\": 32}", + NwObjGroupTemplate = "{\"@type\": \"Object\", \"object_name\": \"@@GROUPNAME@@\", \"management_name\": \"@@MANAGEMENT_NAME@@\"}", + ServiceTemplate = "{\"@type\": \"PROTOCOL\", \"protocol\": \"@@PROTOCOLNAME@@\", \"port\": @@PORT@@, \"name\": \"@@SERVICENAME@@\"}", + IcmpTemplate = "{\"@type\": \"PROTOCOL\", \"protocol\": \"ICMP\", \"type\": 8, \"name\": \"@@SERVICENAME@@\"}" + } + ] + }; + readonly static string reqPrios = "[{\"numeric_prio\":1,\"name\":\"Highest\",\"ticket_deadline\":1,\"approval_deadline\":1},{\"numeric_prio\":2,\"name\":\"High\",\"ticket_deadline\":3,\"approval_deadline\":2},{\"numeric_prio\":3,\"name\":\"Medium\",\"ticket_deadline\":7,\"approval_deadline\":3},{\"numeric_prio\":4,\"name\":\"Low\",\"ticket_deadline\":14,\"approval_deadline\":7},{\"numeric_prio\":5,\"name\":\"Lowest\",\"ticket_deadline\":30,\"approval_deadline\":14}]"; + readonly static string namingConvention = "{\"networkAreaRequired\":true,\"useAppPart\":true,\"fixedPartLength\":4,\"freePartLength\":3,\"networkAreaPattern\":\"NA\",\"appRolePattern\":\"AR\",\"applicationZone\":\"AZ\",\"appServerPrefix\":\"host_\",\"networkPrefix\":\"net_\",\"ipRangePrefix\":\"range_\"}"; + + readonly static List ticketSystemList = [ticketSystem]; + readonly SimulatedUserConfig userConfig = new() + { + ExternalRequestWaitCycles = 3, + ExtTicketSystems = System.Text.Json.JsonSerializer.Serialize(ticketSystemList), + ReqPriorities = reqPrios, + ModNamingConvention = namingConvention, + ModRolloutBundleTasks = true + }; + readonly ExtTicketHandlerTestApiConn apiConnection = new(); + static readonly ModellingNamingConvention NamingConvention = new() + { + NetworkAreaRequired = true, + UseAppPart = false, + FixedPartLength = 2, + FreePartLength = 5, + NetworkAreaPattern = "NA", + AppRolePattern = "AR", + AppServerPrefix = "net_" + }; + static readonly List ipProtos = [new() { Id = 6, Name = "TCP" }]; + + readonly static WfReqElement srcASElem = new() + { + Id = 1, + TaskId = 1, + RequestAction = RequestAction.create.ToString(), + IpString = "123.0.0.1/32", + GroupName = "ARxx12345-100", + Name = "AppServerX", + Field = ElemFieldType.source.ToString() + }; + + readonly static List grpCreateReqTasks = + [ + new() + { + Id = 1, + Title = "new Group", + TaskNumber = 1, + TaskType = WfTaskType.group_create.ToString(), + TicketId = 123, + RequestAction = RequestAction.create.ToString(), + Reason = "need it for connection", + AdditionalInfo = "{\"GrpName\":\"ARxx12345-100\"}", + OnManagement = new(){ Id = 1, Name = "Checkpoint", ExtMgtData = "{\"id\":\"2\",\"name\":\"CheckpointExt\"}"}, + ManagementId = 1, + Elements = [ srcASElem ] + } + ]; + + readonly static List accessReqTasks = + [ + new() + { + Id = 2, + Title = "new Connection", + TaskNumber = 2, + TaskType = WfTaskType.access.ToString(), + TicketId = 123, + RequestAction = RequestAction.create.ToString(), + Reason = "connection needed", + AdditionalInfo = "{\"ConnId\":\"1\"}", + OnManagement = new(){ Id = 1, Name = "Checkpoint", ExtMgtData = "{\"id\":\"2\",\"name\":\"CheckpointExt\"}"}, + ManagementId = 1, + Comments = [ new() { Comment = new() { CommentText = "FWOC1, NAT: To: 4.7.1.1" }}], + Elements = [ ], + SelectedDevices = "[1]" + } + ]; + + + [SetUp] + public void Initialize() + { + + } + + [Test] + public async Task TestGetWaitCycles() + { + SCTicket ticket = new(ticketSystem); + await ticket.CreateRequestString(grpCreateReqTasks, ipProtos, NamingConvention); + using ExternalRequestHandler extReqHandler = new(userConfig, apiConnection, null); + ExternalRequest oldRquestGrp = new() { ExtRequestType = ticket.GetTaskTypeAsString(grpCreateReqTasks[0]), ExtRequestContent = ticket.TicketText }; + ExternalRequest oldRquestAcc = new() { ExtRequestType = ticket.GetTaskTypeAsString(accessReqTasks[0]), ExtRequestContent = ticket.TicketText }; + + ClassicAssert.AreEqual(0, extReqHandler.GetWaitCycles(WfTaskType.access.ToString(), oldRquestAcc)); + ClassicAssert.AreEqual(0, extReqHandler.GetWaitCycles(WfTaskType.group_modify.ToString(), oldRquestAcc)); + ClassicAssert.AreEqual(0, extReqHandler.GetWaitCycles("any", oldRquestAcc)); + ClassicAssert.AreEqual(3, extReqHandler.GetWaitCycles(WfTaskType.access.ToString(), oldRquestGrp)); + ClassicAssert.AreEqual(3, extReqHandler.GetWaitCycles(WfTaskType.group_modify.ToString(), oldRquestGrp)); + ClassicAssert.AreEqual(3, extReqHandler.GetWaitCycles("any", oldRquestGrp)); + } + + [Test] + public void TestGetLastTaskNumber() + { + string extQueryVars = "{\"BundledTasks\":[1,2,3]}"; + + ClassicAssert.AreEqual(3, ExternalRequestHandler.GetLastTaskNumber(extQueryVars, 0)); + } + + [Test] + public void DisposeDoesNotDisposeInjectedUserConfig() + { + SimulatedGlobalConfig localGlobalConfig = new() + { + DefaultLanguage = "English" + }; + UserConfig localUserConfig = new(localGlobalConfig, registerOnChangeHandler: false); + + using (ExternalRequestHandler externalRequestHandler = new(localUserConfig, apiConnection, null)) + { + } + + ClassicAssert.AreEqual("on", localUserConfig.GetText("on")); + localUserConfig.Dispose(); + localGlobalConfig.Dispose(); + } + + [Test] + public async Task TestHandleStateChange() + { + using ExternalRequestHandler externalRequestHandler = new(userConfig, apiConnection, null); + ExternalRequest externalRequest = new() + { + Id = 1, + TicketId = 1, + TaskNumber = 1, + ExtRequestState = ExtStates.ExtReqRequested.ToString(), + ExtQueryVariables = "" + }; + await externalRequestHandler.HandleStateChange(externalRequest); + + ClassicAssert.AreEqual(0, apiConnection.History.Count); + + externalRequest.ExtRequestState = ExtStates.ExtReqDone.ToString(); + externalRequest.ExtTicketId = "4711"; + await externalRequestHandler.HandleStateChange(externalRequest); + + // { appId = , changeType = 11, objectType = 1, objectId = 1, changeText = Implemented Task1 on , changer = Tufin, changeSource = manual } + ClassicAssert.AreEqual(3, apiConnection.History.Count); + ClassicAssert.AreEqual(true, apiConnection.History[0].Contains("changeType = 11")); + ClassicAssert.AreEqual(true, apiConnection.History[0].Contains("Task1")); + + // { appId = , changeType = 10, objectType = 1, objectId = 1, changeText = Requested Task2 on , changer = , changeSource = manual } + ClassicAssert.AreEqual(true, apiConnection.History[1].Contains("changeType = 10")); + ClassicAssert.AreEqual(true, apiConnection.History[1].Contains("Task2")); + ClassicAssert.AreEqual(true, apiConnection.History[2].Contains("changeType = 10")); + ClassicAssert.AreEqual(true, apiConnection.History[2].Contains("Task3")); + + // { ownerId = , ticketId = 123, taskNumber = 2, extTicketSystem = {"Id":1,"ExternalTicketSystemType":1,"Authorization":"xyz","Name":"Tufin","Url":"https://tufin-test.xxx.de/securechangeworkflow/api/securechange/", + // "LookupRequesterId":false,"Templates":[{"TaskType":"NetworkObjectModify","TicketTemplate":"{\u0022ticket\u0022:{\u0022subject\u0022:\u0022@@TICKET_SUBJECT@@\u0022,\u0022priority\u0022:\u0022@@PRIORITY@@\u0022, + // \u0022requester\u0022:\u0022@@ONBEHALF@@\u0022,\u0022domain_name\u0022:\u0022\u0022,\u0022workflow\u0022:{\u0022name\u0022:\u0022Automatische Gruppenerstellung\u0022},\u0022steps\u0022:{\u0022step\u0022: + // [{\u0022name\u0022:\u0022Erfassung des Antrags\u0022,\u0022tasks\u0022:{\u0022task\u0022:{\u0022fields\u0022:{\u0022field\u0022:[@@TASKS@@]}}}}]}}}","TasksTemplate":"{\u0022@xsi.type\u0022: \u0022multi_group_change\u0022, + // \u0022name\u0022: \u0022Modify network object group\u0022,\u0022group_change\u0022: {\u0022name\u0022: \u0022@@GROUPNAME@@\u0022,\u0022management_name\u0022: \u0022@@MANAGEMENT_NAME@@\u0022,\u0022members\u0022: {\u0022member\u0022: @@MEMBERS@@}, + // \u0022change_action\u0022: \u0022CREATE\u0022}}","ObjectTemplate":"{\u0022@type\u0022: \u0022@@TYPE@@\u0022, \u0022name\u0022: \u0022@@OBJECTNAME@@\u0022, \u0022object_type\u0022: \u0022@@OBJECT_TYPE@@\u0022, \u0022object_details\u0022: \u0022@@OBJECT_DETAILS@@\u0022, + // \u0022status\u0022: \u0022@@STATUS@@\u0022, \u0022comment\u0022: \u0022@@COMMENT@@\u0022, \u0022object_updated_status\u0022: \u0022@@OBJUPDSTATUS@@\u0022, \u0022management_id\u0022: @@MANAGEMENT_ID@@}","ObjectTemplateShort":"{\u0022@type\u0022: \u0022Object\u0022, + // \u0022name\u0022: \u0022@@OBJECTNAME@@\u0022, \u0022status\u0022: \u0022@@STATUS@@\u0022, \u0022object_updated_status\u0022: \u0022@@OBJUPDSTATUS@@\u0022}","IpTemplate":"","NwObjGroupTemplate":"","ServiceTemplate":"","IcmpTemplate":""},{"TaskType":"AccessRequest", + // "TicketTemplate":"{\u0022ticket\u0022:{\u0022subject\u0022:\u0022@@TICKET_SUBJECT@@\u0022,\u0022priority\u0022:\u0022@@PRIORITY@@\u0022,\u0022requester\u0022:\u0022@@ONBEHALF@@\u0022,\u0022domain_name\u0022:\u0022\u0022,\u0022workflow\u0022: + // {\u0022name\u0022:\u0022Standard Firewall Request\u0022},\u0022steps\u0022:{\u0022step\u0022:[{\u0022name\u0022:\u0022Erfassung des Antrags\u0022,\u0022tasks\u0022:{\u0022task\u0022:{\u0022fields\u0022:{\u0022field\u0022:[{\u0022@xsi.type\u0022: + // \u0022multi_access_request\u0022,\u0022name\u0022: \u0022Zugang\u0022,\u0022read_only\u0022: false,\u0022access_request\u0022:[@@TASKS@@]},{\u0022@xsi.type\u0022: \u0022text_area\u0022,\u0022name\u0022: \u0022Grund f\u00FCr den Antrag\u0022,\u0022read_only\u0022: false, + // \u0022text\u0022: \u0022@@REASON@@\u0022},{\u0022@xsi.type\u0022: \u0022text_field\u0022,\u0022name\u0022: \u0022Anwendungs-ID\u0022,\u0022text\u0022: \u0022@@APPID@@\u0022},{\u0022@xsi.type\u0022: \u0022checkbox\u0022,\u0022name\u0022: \u0022hinterlegt\u0022,\u0022value\u0022: true}]}}}}]}}}}", + // "TasksTemplate":"{\u0022order\u0022: \u0022@@ORDERNAME@@\u0022,\u0022verifier_result\u0022: {\u0022status\u0022: \u0022not run\u0022},\u0022use_topology\u0022: true,\u0022targets\u0022: {\u0022target\u0022: {\u0022@type\u0022: \u0022ANY\u0022}},\u0022action\u0022: \u0022@@ACTION@@\u0022, + // \u0022sources\u0022:{\u0022source\u0022:@@SOURCES@@},\u0022destinations\u0022:{\u0022destination\u0022:@@DESTINATIONS@@},\u0022services\u0022:{\u0022service\u0022:@@SERVICES@@},\u0022labels\u0022:\u0022\u0022,\u0022comment\u0022: \u0022@@TASKCOMMENT@@\u0022}","ObjectTemplate":"","ObjectTemplateShort":"", + // "IpTemplate":"{\u0022@type\u0022: \u0022IP\u0022, \u0022ip_address\u0022: \u0022@@IP@@\u0022, \u0022netmask\u0022: \u0022255.255.255.255\u0022, \u0022cidr\u0022: 32}","NwObjGroupTemplate":"{\u0022@type\u0022: \u0022Object\u0022, \u0022object_name\u0022: \u0022@@GROUPNAME@@\u0022, + // \u0022management_name\u0022: \u0022@@MANAGEMENT_NAME@@\u0022}","ServiceTemplate":"{\u0022@type\u0022: \u0022PROTOCOL\u0022, \u0022protocol\u0022: \u0022@@PROTOCOLNAME@@\u0022, \u0022port\u0022: @@PORT@@, \u0022name\u0022: \u0022@@SERVICENAME@@\u0022}","IcmpTemplate":"{\u0022@type\u0022: \u0022PROTOCOL\u0022, + // \u0022protocol\u0022: \u0022ICMP\u0022, \u0022type\u0022: 8, \u0022name\u0022: \u0022@@SERVICENAME@@\u0022}"}],"TicketTemplate":"","TasksTemplate":"","ResponseTimeout":300,"MaxAttempts":3,"CyclesBetweenAttempts":5}, extTaskType = (AccessRequest, CREATE), + // extTaskContent = {"ticketText":"{\u0022ticket\u0022:{\u0022subject\u0022:\u0022Create Ruleon()\u0022,\u0022priority\u0022:\u0022Low\u0022,\u0022requester\u0022:\u0022\u0022,\u0022domain_name\u0022:\u0022\u0022,\u0022workflow\u0022:{\u0022name\u0022:\u0022Standard Firewall Request\u0022}, + // \u0022steps\u0022:{\u0022step\u0022:[{\u0022name\u0022:\u0022Erfassung des Antrags\u0022,\u0022tasks\u0022:{\u0022task\u0022:{\u0022fields\u0022:{\u0022field\u0022:[{\u0022@xsi.type\u0022: \u0022multi_access_request\u0022,\u0022name\u0022: \u0022Zugang\u0022,\u0022read_only\u0022: false, + // \u0022access_request\u0022:[{\u0022order\u0022: \u0022AR2\u0022,\u0022verifier_result\u0022: {\u0022status\u0022: \u0022not run\u0022},\u0022use_topology\u0022: true,\u0022targets\u0022: {\u0022target\u0022: {\u0022@type\u0022: \u0022ANY\u0022}},\u0022action\u0022: \u0022accept\u0022, + // \u0022sources\u0022:{\u0022source\u0022:[{\u0022@type\u0022: \u0022Object\u0022, \u0022object_name\u0022: \u0022ARxx12345-100\u0022, \u0022management_name\u0022: \u0022\u0022}]},\u0022destinations\u0022:{\u0022destination\u0022:[{\u0022@type\u0022: \u0022Object\u0022, + // \u0022object_name\u0022: \u0022ARxx12345-101\u0022, \u0022management_name\u0022: \u0022\u0022}]},\u0022services\u0022:{\u0022service\u0022:[{\u0022@type\u0022: \u0022PROTOCOL\u0022, \u0022protocol\u0022: \u0022TCP\u0022, \u0022port\u0022: 1000, \u0022name\u0022: \u0022Svc1\u0022}]}, + // \u0022labels\u0022:\u0022\u0022,\u0022comment\u0022: \u0022\u0022}]},{\u0022@xsi.type\u0022: \u0022text_area\u0022,\u0022name\u0022: \u0022Grund f\u00FCr den Antrag\u0022,\u0022read_only\u0022: false,\u0022text\u0022: \u0022Kommunikationsprofil der Anwendung\u0022},{\u0022@xsi.type\u0022: \u0022text_field\u0022, + // \u0022name\u0022: \u0022Anwendungs-ID\u0022,\u0022text\u0022: \u0022\u0022},{\u0022@xsi.type\u0022: \u0022checkbox\u0022,\u0022name\u0022: \u0022hinterlegt\u0022,\u0022value\u0022: true}]}}}}]}}}}","TicketId":""}, extQueryVariables = , extRequestState = ExtReqInitialized, waitCycles = 0 } + ClassicAssert.AreEqual(true, apiConnection.AddExtRequestVars != null); + ClassicAssert.AreEqual(true, apiConnection.AddExtRequestVars?.Contains("taskNumber = 2")); + ClassicAssert.AreEqual(true, apiConnection.AddExtRequestVars?.Contains("extQueryVariables = {\"BundledTasks\":[2,3]}")); + + externalRequest.Id = 2; + externalRequest.TaskNumber = 2; + externalRequest.ExtQueryVariables = "{\"BundledTasks\":[2,3]}"; + await externalRequestHandler.HandleStateChange(externalRequest); + + ClassicAssert.AreEqual(7, apiConnection.History.Count); + ClassicAssert.AreEqual(true, apiConnection.History[3].Contains("changeType = 11")); + ClassicAssert.AreEqual(true, apiConnection.History[3].Contains("Task2")); + ClassicAssert.AreEqual(true, apiConnection.History[4].Contains("changeType = 11")); + ClassicAssert.AreEqual(true, apiConnection.History[4].Contains("Task3")); + ClassicAssert.AreEqual(true, apiConnection.History[5].Contains("changeType = 10")); + ClassicAssert.AreEqual(true, apiConnection.History[5].Contains("Task4")); + ClassicAssert.AreEqual(true, apiConnection.History[6].Contains("changeType = 10")); + ClassicAssert.AreEqual(true, apiConnection.History[6].Contains("Task5")); + ClassicAssert.AreEqual(true, apiConnection.AddExtRequestVars?.Contains("taskNumber = 4")); + ClassicAssert.AreEqual(true, apiConnection.AddExtRequestVars?.Contains("extQueryVariables = {\"BundledTasks\":[4,5]}")); + ClassicAssert.AreEqual(true, apiConnection.AddExtRequestVars?.Contains("AR4")); + ClassicAssert.AreEqual(false, apiConnection.AddExtRequestVars?.Contains("AR5")); + + externalRequest.Id = 3; + externalRequest.TaskNumber = 4; + externalRequest.ExtQueryVariables = "{\"BundledTasks\":[4,5]}"; + await externalRequestHandler.HandleStateChange(externalRequest); + + ClassicAssert.AreEqual(12, apiConnection.History.Count); + ClassicAssert.AreEqual(true, apiConnection.History[7].Contains("changeType = 11")); + ClassicAssert.AreEqual(true, apiConnection.History[7].Contains("Task4")); + ClassicAssert.AreEqual(true, apiConnection.History[8].Contains("changeType = 11")); + ClassicAssert.AreEqual(true, apiConnection.History[8].Contains("Task5")); + ClassicAssert.AreEqual(true, apiConnection.History[9].Contains("changeType = 10")); + ClassicAssert.AreEqual(true, apiConnection.History[9].Contains("Task6")); + ClassicAssert.AreEqual(true, apiConnection.History[10].Contains("changeType = 10")); + ClassicAssert.AreEqual(true, apiConnection.History[10].Contains("Task7")); + ClassicAssert.AreEqual(true, apiConnection.History[11].Contains("changeType = 10")); + ClassicAssert.AreEqual(true, apiConnection.History[11].Contains("Task8")); + ClassicAssert.AreEqual(true, apiConnection.AddExtRequestVars?.Contains("taskNumber = 6")); + ClassicAssert.AreEqual(true, apiConnection.AddExtRequestVars?.Contains("extQueryVariables = {\"BundledTasks\":[6,7,8]}")); + ClassicAssert.AreEqual(true, apiConnection.AddExtRequestVars?.Contains("AR6")); + ClassicAssert.AreEqual(false, apiConnection.AddExtRequestVars?.Contains("AR7")); + ClassicAssert.AreEqual(true, apiConnection.AddExtRequestVars?.Contains("AR8")); + + userConfig.ModRolloutBundleTasks = false; + await externalRequestHandler.HandleStateChange(externalRequest); + ClassicAssert.AreEqual(15, apiConnection.History.Count); + ClassicAssert.AreEqual(true, apiConnection.History[12].Contains("changeType = 11")); + ClassicAssert.AreEqual(true, apiConnection.History[12].Contains("Task4")); + ClassicAssert.AreEqual(true, apiConnection.History[13].Contains("changeType = 11")); + ClassicAssert.AreEqual(true, apiConnection.History[13].Contains("Task5")); + ClassicAssert.AreEqual(true, apiConnection.History[14].Contains("changeType = 10")); + ClassicAssert.AreEqual(true, apiConnection.History[14].Contains("Task5")); + } + } +} diff --git a/roles/tests-unit/files/FWO.Test/ExtTicketHandlerTestApiConn.cs b/roles/tests-unit/files/FWO.Test/ExtTicketHandlerTestApiConn.cs new file mode 100644 index 0000000000..f0c828563f --- /dev/null +++ b/roles/tests-unit/files/FWO.Test/ExtTicketHandlerTestApiConn.cs @@ -0,0 +1,288 @@ +using GraphQL; +using FWO.Api.Client.Queries; +using FWO.Data; +using FWO.Data.Workflow; +using FWO.Services; +using FWO.Services.Workflow; +using AngleSharp.Common; + +namespace FWO.Test +{ + internal class ExtTicketHandlerTestApiConn : SimulatedApiConnection + { + public string? CloseHistoryMessage { get; set; } + public List History = []; + public string? AddHistoryMessage { get; set; } + public string? AddExtRequestVars { get; set; } + readonly string masterStateMatrix = "{\"config_value\":{\"request\":{\"matrix\":{\"0\":[0,49,620],\"49\":[49,620],\"620\":[620],\"1\":[1,2,3,4,630,631],\"2\":[1,2,3,4,630,631],\"3\":[3,4,630,631],\"4\":[4,630,631],\"630\":[630],\"631\":[631]},\"derived_states\":{\"0\":0,\"49\":49,\"620\":620,\"1\":1,\"2\":2,\"3\":3,\"4\":4,\"630\":630,\"631\":631},\"lowest_input_state\":0,\"lowest_start_state\":1,\"lowest_end_state\":49,\"active\":true},\"approval\":{\"matrix\":{\"49\":[60],\"60\":[60,99,610],\"99\":[99],\"610\":[610]},\"derived_states\":{\"49\":49,\"60\":60,\"99\":99,\"610\":610},\"lowest_input_state\":49,\"lowest_start_state\":60,\"lowest_end_state\":99,\"active\":false},\"planning\":{\"matrix\":{\"99\":[110],\"110\":[110,120,130,149],\"120\":[120,110,130,149],\"130\":[130,110,120,149,610],\"149\":[149],\"610\":[610]},\"derived_states\":{\"99\":99,\"110\":110,\"120\":110,\"130\":110,\"149\":149,\"610\":610},\"lowest_input_state\":99,\"lowest_start_state\":110,\"lowest_end_state\":149,\"active\":false},\"verification\":{\"matrix\":{\"149\":[160],\"160\":[160,199,610],\"199\":[199],\"610\":[610]},\"derived_states\":{\"149\":149,\"160\":160,\"199\":199,\"610\":610},\"lowest_input_state\":149,\"lowest_start_state\":160,\"lowest_end_state\":199,\"active\":false},\"implementation\":{\"matrix\":{\"99\":[210],\"210\":[210,220,249],\"220\":[220,210,249,610],\"249\":[249],\"610\":[610],\"49\":[49,600,610]},\"derived_states\":{\"99\":99,\"210\":210,\"220\":210,\"249\":249,\"610\":610,\"49\":49},\"lowest_input_state\":49,\"lowest_start_state\":210,\"lowest_end_state\":249,\"active\":true},\"review\":{\"matrix\":{\"249\":[260],\"260\":[260,270,299],\"270\":[210,270,260,299,610],\"299\":[299],\"610\":[610]},\"derived_states\":{\"249\":249,\"260\":260,\"270\":260,\"299\":299,\"610\":610},\"lowest_input_state\":249,\"lowest_start_state\":260,\"lowest_end_state\":299,\"active\":false},\"recertification\":{\"matrix\":{\"299\":[310],\"310\":[310,349,400],\"349\":[349],\"400\":[400]},\"derived_states\":{\"299\":299,\"310\":310,\"349\":349,\"400\":400},\"lowest_input_state\":299,\"lowest_start_state\":310,\"lowest_end_state\":349,\"active\":false}}}"; + readonly static WfReqElement srcARElem = new() + { + Id = 1, + RequestAction = RequestAction.create.ToString(), + GroupName = "ARxx12345-100", + Field = ElemFieldType.source.ToString() + }; + readonly static WfReqElement dstARElem = new() + { + Id = 2, + RequestAction = RequestAction.create.ToString(), + GroupName = "ARxx12345-101", + Field = ElemFieldType.destination.ToString() + }; + readonly static WfReqElement svcElem = new() + { + Id = 3, + RequestAction = RequestAction.create.ToString(), + Name = "Svc1", + Port = 1000, + ProtoId = 6, + Field = ElemFieldType.service.ToString() + }; + readonly static WfReqElement ruleElem = new() + { + Id = 3, + RequestAction = RequestAction.create.ToString(), + Name = "Rule1", + RuleUid = "1234567", + Field = ElemFieldType.rule.ToString() + }; + + + readonly static WfReqTask reqTask1 = new() + { + Id = 1, + Title = "Task1", + TicketId = 123, + TaskNumber = 1, + TaskType = WfTaskType.group_create.ToString(), + ManagementId = 1, + Elements = [srcARElem], + AdditionalInfo = "{\"ConnId\":\"1\"}" + }; + readonly static WfReqTask reqTask2 = new() + { + Id = 2, + Title = "Task2", + TicketId = 123, + TaskNumber = 2, + TaskType = WfTaskType.access.ToString(), + ManagementId = 1, + Elements = [srcARElem, dstARElem, svcElem], + AdditionalInfo = "{\"ConnId\":\"1\"}" + }; + readonly static WfReqTask reqTask3 = new() + { + Id = 3, + Title = "Task3", + TicketId = 123, + TaskNumber = 3, + TaskType = WfTaskType.access.ToString(), + ManagementId = 1, + Elements = [srcARElem, dstARElem, svcElem], + AdditionalInfo = "{\"ConnId\":\"1\"}" + }; + readonly static WfReqTask reqTask4 = new() + { + Id = 4, + Title = "Task4", + TicketId = 123, + TaskNumber = 4, + TaskType = WfTaskType.rule_modify.ToString(), + ManagementId = 1, + Elements = [srcARElem, dstARElem, svcElem, ruleElem], + AdditionalInfo = "{\"ConnId\":\"1\"}", + SelectedDevices = "[1]" + }; + readonly static WfReqTask reqTask5 = new() + { + Id = 5, + Title = "Task5", + TicketId = 123, + TaskNumber = 5, + TaskType = WfTaskType.rule_modify.ToString(), + ManagementId = 1, + Elements = [srcARElem, dstARElem, svcElem, ruleElem], + AdditionalInfo = "{\"ConnId\":\"1\"}", + SelectedDevices = "[2]" + }; + readonly static WfReqTask reqTask6 = new() + { + Id = 6, + Title = "Task6", + TicketId = 123, + TaskNumber = 6, + TaskType = WfTaskType.rule_delete.ToString(), + ManagementId = 1, + Elements = [srcARElem, dstARElem, svcElem, ruleElem], + AdditionalInfo = "{\"ConnId\":\"1\"}", + SelectedDevices = "[1]" + }; + readonly static WfReqTask reqTask7 = new() + { + Id = 7, + Title = "Task7", + TicketId = 123, + TaskNumber = 7, + TaskType = WfTaskType.rule_delete.ToString(), + ManagementId = 1, + Elements = [srcARElem, dstARElem, svcElem, ruleElem], + AdditionalInfo = "{\"ConnId\":\"1\"}", + SelectedDevices = "[2]" + }; + readonly static WfReqTask reqTask8 = new() + { + Id = 8, + Title = "Task8", + TicketId = 123, + TaskNumber = 8, + TaskType = WfTaskType.rule_delete.ToString(), + ManagementId = 1, + Elements = [srcARElem, dstARElem, svcElem, ruleElem], + AdditionalInfo = "{\"ConnId\":\"2\"}", + SelectedDevices = "[1,2]" + }; + + readonly static WfTicket ticket123 = new() { Id = 123, Title = "Ticket1", Tasks = [reqTask1, reqTask2, reqTask3, reqTask4, reqTask5, reqTask6, reqTask7, reqTask8] }; + + + public override async Task SendQueryAsync(string query, object? variables = null, string? operationName = null) + { + await DefaultInit.DoNothing(); // qad avoid compiler warning + Type responseType = typeof(QueryResponseType); + if (responseType == typeof(List)) + { + List? extStates = + [ + new(){ Id = 1, Name = "ExtReqInitialized", StateId = 1 }, + new(){ Id = 2, Name = "ExtReqRequested", StateId = 3 }, + new(){ Id = 3, Name = "ExtReqDone", StateId = 631 } + ]; + GraphQLResponse response = new() { Data = extStates }; + return response.Data; + } + else if (responseType == typeof(List)) + { + List? ipProtocols = + [ + new(){ Id = 6, Name = "TCP"}, + new(){ Id = 17, Name = "UDP" } + ]; + GraphQLResponse response = new() { Data = ipProtocols }; + return response.Data; + } + else if (responseType == typeof(List)) + { + List? devices = + [ + new(){ Id = 1, Name = "TestGw1" }, + new(){ Id = 2, Name = "TestGw2" } + ]; + GraphQLResponse response = new() { Data = devices }; + return response.Data; + } + else if (responseType == typeof(List)) + { + List? owners = + [ + new(){ Id = 1, Name = "Owner1" } + ]; + GraphQLResponse response = new() { Data = owners }; + return response.Data; + } + else if (responseType == typeof(List)) + { + List? states = + [ + new(){ Id = 0, Name = "Draft" }, + new(){ Id = 1, Name = "ExtInit" }, + new(){ Id = 3, Name = "ExtRequested" }, + new(){ Id = 631, Name = "ExtDone" } + ]; + GraphQLResponse response = new() { Data = states }; + return response.Data; + } + else if (responseType == typeof(List)) + { + List globalStateMatrixHelpers = [new() { ConfData = masterStateMatrix }]; + GraphQLResponse response = new() { Data = globalStateMatrixHelpers }; + return response.Data; + } + else if (responseType == typeof(List)) + { + List? tickets = [ticket123]; + GraphQLResponse response = new() { Data = tickets }; + return response.Data; + } + else if (responseType == typeof(WfTicket)) + { + GraphQLResponse response = new() { Data = ticket123 }; + return response.Data; + } + else if (responseType == typeof(ReturnId)) + { + if (query == RequestQueries.updateRequestTaskAdditionalInfo && variables != null) + { + string? Vars = variables.ToString(); + if (Vars != null) + { + if (Vars.Contains("id = 1")) + { + reqTask1.AdditionalInfo = "{\"ConnId\":\"1\",\"ExtIcketId\":\"4711\"}"; + } + else if (Vars.Contains("id = 2")) + { + reqTask2.AdditionalInfo = "{\"ConnId\":\"1\",\"ExtIcketId\":\"4712\"}"; + } + else if (Vars.Contains("id = 3")) + { + reqTask3.AdditionalInfo = "{\"ConnId\":\"1\",\"ExtIcketId\":\"4712\"}"; + } + else if (Vars.Contains("id = 4")) + { + reqTask4.AdditionalInfo = "{\"ConnId\":\"1\",\"ExtIcketId\":\"4713\"}"; + } + else if (Vars.Contains("id = 5")) + { + reqTask5.AdditionalInfo = "{\"ConnId\":\"1\",\"ExtIcketId\":\"4713\"}"; + } + else if (Vars.Contains("id = 6")) + { + reqTask6.AdditionalInfo = "{\"ConnId\":\"1\",\"ExtIcketId\":\"4714\"}"; + } + else if (Vars.Contains("id = 7")) + { + reqTask7.AdditionalInfo = "{\"ConnId\":\"1\",\"ExtIcketId\":\"4714\"}"; + } + else if (Vars.Contains("id = 8")) + { + reqTask8.AdditionalInfo = "{\"ConnId\":\"2\",\"ExtIcketId\":\"4714\"}"; + } + } + } + ReturnId returnId = new() { UpdatedIdLong = 1 }; + GraphQLResponse response = new() { Data = returnId }; + return response.Data; + } + else if (responseType == typeof(ReturnIdWrapper)) + { + if (query == ModellingQueries.addHistoryEntry && variables != null) + { + string? hist = variables.ToString(); + if (hist != null) + { + History.Add(hist); + } + } + else if (query == ExtRequestQueries.addExtRequest && variables != null) + { + AddExtRequestVars = variables.ToString(); + } + ReturnIdWrapper ReturnIdWrap = new() { ReturnIds = [new()] }; + GraphQLResponse response = new() { Data = ReturnIdWrap }; + return response.Data; + } + + throw new NotImplementedException(); + } + } +} diff --git a/roles/tests-unit/files/FWO.Test/FWO.Test.csproj b/roles/tests-unit/files/FWO.Test/FWO.Test.csproj new file mode 100644 index 0000000000..208494d389 --- /dev/null +++ b/roles/tests-unit/files/FWO.Test/FWO.Test.csproj @@ -0,0 +1,36 @@ + + + + net10.0 + false + true + enable + enable + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/roles/tests-unit/files/FWO.Test/FakeLocalTimeZone.cs b/roles/tests-unit/files/FWO.Test/FakeLocalTimeZone.cs new file mode 100644 index 0000000000..a097e0f90f --- /dev/null +++ b/roles/tests-unit/files/FWO.Test/FakeLocalTimeZone.cs @@ -0,0 +1,29 @@ +using System.Reflection; + +namespace FWO.Test +{ + public class FakeLocalTimeZone : IDisposable + { + private readonly TimeZoneInfo _actualLocalTimeZoneInfo; + + private static void SetLocalTimeZone(TimeZoneInfo timeZoneInfo) + { + var info = typeof(TimeZoneInfo).GetField("s_cachedData", BindingFlags.NonPublic | BindingFlags.Static); + object? cachedData = info?.GetValue(null); + + var field = cachedData?.GetType().GetField("_localTimeZone", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static | BindingFlags.Instance); + field?.SetValue(cachedData, timeZoneInfo); + } + + public FakeLocalTimeZone(TimeZoneInfo timeZoneInfo) + { + _actualLocalTimeZoneInfo = TimeZoneInfo.Local; + SetLocalTimeZone(timeZoneInfo); + } + + public void Dispose() + { + SetLocalTimeZone(_actualLocalTimeZoneInfo); + } + } +} diff --git a/roles/tests-unit/files/FWO.Test/FilterTest.cs b/roles/tests-unit/files/FWO.Test/FilterTest.cs new file mode 100644 index 0000000000..3b0ab94d2d --- /dev/null +++ b/roles/tests-unit/files/FWO.Test/FilterTest.cs @@ -0,0 +1,1421 @@ +using FWO.Report.Filter; +using FWO.Report.Filter.Ast; +using FWO.Report.Filter.Exceptions; +using NUnit.Framework; +using NUnit.Framework.Legacy; +using FWO.Basics; +using FWO.Data.Report; +using FWO.Data.Workflow; +using System.Reflection; +using System.Text.Json; +namespace FWO.Test +{ + [TestFixture] + [Parallelizable] + public class FilterTest + { + private delegate void StubExtractDelegate(ref DynGraphqlQuery query, ReportType? reportType); + + private sealed class StubAstNode(StubExtractDelegate extractAction) : AstNode + { + private readonly StubExtractDelegate _extractAction = extractAction; + + public override void Extract(ref DynGraphqlQuery query, ReportType? reportType) + { + _extractAction(ref query, reportType); + } + } + + private static object CreateDateTimeRange(TokenKind operatorKind, string value) + { + Assembly filterAssembly = typeof(Compiler).Assembly; + Type astNodeType = filterAssembly.GetType("FWO.Report.Filter.Ast.AstNodeFilterDateTimeRange", throwOnError: true)!; + object astNode = Activator.CreateInstance(astNodeType, nonPublic: true)!; + + astNodeType.GetProperty("Name")!.SetValue(astNode, new Token(new Range(), "lasthit", TokenKind.LastHit)); + astNodeType.GetProperty("Operator")!.SetValue(astNode, new Token(new Range(), operatorKind.ToString(), operatorKind)); + astNodeType.GetProperty("Value")!.SetValue(astNode, new Token(new Range(), value, TokenKind.Value)); + + Type dateTimeRangeType = filterAssembly.GetType("FWO.Report.Filter.FilterTypes.DateTimeRange", throwOnError: true)!; + return Activator.CreateInstance(dateTimeRangeType, [astNode])!; + } + + private static DateTime? GetDateTimeRangeBound(object range, string fieldName) + { + return (DateTime?)range.GetType().GetField(fieldName)!.GetValue(range); + } + + private static TException AssertDateTimeRangeThrows(TokenKind operatorKind, string value) + where TException : Exception + { + TargetInvocationException exception = Assert.Throws(() => CreateDateTimeRange(operatorKind, value))!; + Assert.That(exception.InnerException, Is.TypeOf()); + return (TException)exception.InnerException!; + } + + [SetUp] + public void Initialize() + { + + } + + [Test] + [Parallelizable] + public void EmptySearch() + { + ReportTemplate t = new() + { + Filter = "" + }; + t.ReportParams.ReportType = (int)ReportType.Rules; + DynGraphqlQuery query = Compiler.Compile(t); + + ClassicAssert.AreEqual(0, query.QueryVariables.Count); + } + + [Test] + [Parallelizable] + public void WhitespaceSearch() + { + ReportTemplate t = new() + { + Filter = "\t\n \r \t \n" + }; + t.ReportParams.ReportType = (int)ReportType.Rules; + DynGraphqlQuery query = Compiler.Compile(t); + + ClassicAssert.AreEqual(0, query.QueryVariables.Count); + } + + [Test] + [Parallelizable] + public void TextOnlySearch() + { + ReportTemplate t = new() + { + Filter = "teststring" + }; + t.ReportParams.ReportType = (int)ReportType.Rules; + Compiler.CompileToAst("teststring"); + DynGraphqlQuery query = Compiler.Compile(t); + + ClassicAssert.AreEqual(1, query.QueryVariables.Count); + ClassicAssert.AreEqual("%teststring%", query.QueryVariables["fullTextFilter0"]); + } + + [Test] + [Parallelizable] + public void DateTimeRange_NowCreatesClosedRangeAtCurrentTime() + { + DateTime before = DateTime.Now; + + object range = CreateDateTimeRange(TokenKind.EEQ, "now"); + + DateTime after = DateTime.Now; + DateTime? start = GetDateTimeRangeBound(range, "Start"); + DateTime? end = GetDateTimeRangeBound(range, "End"); + + Assert.That(start, Is.Not.Null); + Assert.That(end, Is.EqualTo(start)); + Assert.That(start, Is.InRange(before, after)); + } + + [Test] + [Parallelizable] + public void DateTimeRange_ThisYearCreatesYearBoundaries() + { + int currentYear = DateTime.Now.Year; + + object range = CreateDateTimeRange(TokenKind.EEQ, "this year"); + + Assert.That(GetDateTimeRangeBound(range, "Start"), Is.EqualTo(new DateTime(currentYear, 1, 1, 0, 0, 0))); + Assert.That(GetDateTimeRangeBound(range, "End"), Is.EqualTo(new DateTime(currentYear + 1, 1, 1, 0, 0, 0))); + } + + [Test] + [Parallelizable] + public void DateTimeRange_LastYearCreatesYearBoundaries() + { + int currentYear = DateTime.Now.Year; + + object range = CreateDateTimeRange(TokenKind.EEQ, "last year"); + + Assert.That(GetDateTimeRangeBound(range, "Start"), Is.EqualTo(new DateTime(currentYear - 1, 1, 1, 0, 0, 0))); + Assert.That(GetDateTimeRangeBound(range, "End"), Is.EqualTo(new DateTime(currentYear, 1, 1, 0, 0, 0))); + } + + [Test] + [Parallelizable] + public void DateTimeRange_LessThanCreatesOpenStartRange() + { + DateTime expectedEnd = new(2025, 1, 1, 0, 0, 0); + + object range = CreateDateTimeRange(TokenKind.LSS, "2025-01-01"); + + Assert.That(GetDateTimeRangeBound(range, "Start"), Is.Null); + Assert.That(GetDateTimeRangeBound(range, "End"), Is.EqualTo(expectedEnd)); + } + + [Test] + [Parallelizable] + public void DateTimeRange_GreaterThanCreatesOpenEndRange() + { + DateTime expectedStart = new(2025, 1, 1, 0, 0, 0); + + object range = CreateDateTimeRange(TokenKind.GRT, "2025-01-01"); + + Assert.That(GetDateTimeRangeBound(range, "Start"), Is.EqualTo(expectedStart)); + Assert.That(GetDateTimeRangeBound(range, "End"), Is.Null); + } + + [Test] + [Parallelizable] + public void DateTimeRange_InvalidExactValueRaisesSyntaxException() + { + SyntaxException exception = AssertDateTimeRangeThrows(TokenKind.EEQ, "not-a-date"); + + Assert.That(exception.Message, Does.Contain("Wrong time range format.")); + } + + [Test] + [Parallelizable] + public void AndOr() + { + ReportTemplate t = new() + { + Filter = "((src=hi) & (dst=test)) | (src = a)" + }; + t.ReportParams.ReportType = (int)ReportType.Rules; + DynGraphqlQuery query = Compiler.Compile(t); + + ClassicAssert.AreEqual(3, query.QueryVariables.Count); + ClassicAssert.AreEqual("%hi%", query.QueryVariables["src0"]); + ClassicAssert.AreEqual("%test%", query.QueryVariables["dst1"]); + ClassicAssert.AreEqual("%a%", query.QueryVariables["src2"]); + } + + [Test] + [Parallelizable] + public void TripleOr() + { + ReportTemplate t = new() + { + Filter = "(src=cactus or dst=cactus or svc=smtps)" + }; + t.ReportParams.ReportType = (int)ReportType.Rules; + DynGraphqlQuery query = Compiler.Compile(t); + + ClassicAssert.AreEqual(3, query.QueryVariables.Count); + ClassicAssert.AreEqual("%cactus%", query.QueryVariables["src0"]); + ClassicAssert.AreEqual("%cactus%", query.QueryVariables["dst1"]); + ClassicAssert.AreEqual("%smtps%", query.QueryVariables["svc2"]); + } + + [Test] + [Parallelizable] + public void NotEquals() + { + ReportTemplate t = new() + { + Filter = "(text!=cactus)" + }; + t.ReportParams.ReportType = (int)ReportType.Rules; + DynGraphqlQuery query = Compiler.Compile(t); + + ClassicAssert.AreEqual(1, query.QueryVariables.Count); + ClassicAssert.AreEqual("cactus", query.QueryVariables["fullTextFilter0"]); + } + + [Test] + [Parallelizable] + public void ExactEquals() + { + ReportTemplate t = new() + { + Filter = "(text==cactus)" + }; + t.ReportParams.ReportType = (int)ReportType.Rules; + DynGraphqlQuery query = Compiler.Compile(t); + + ClassicAssert.AreEqual(1, query.QueryVariables.Count); + ClassicAssert.AreEqual("cactus", query.QueryVariables["fullTextFilter0"]); + } + + [Test] + [Parallelizable] + public void ExactEquals2() + { + ReportTemplate t = new() + { + Filter = "(gateway = \"checkpoint_demo\" or gateway = \"fortigate_demo\") & dst == IsoAAADray.local" + }; + t.ReportParams.ReportType = (int)ReportType.Rules; + DynGraphqlQuery query = Compiler.Compile(t); + + ClassicAssert.AreEqual(3, query.QueryVariables.Count); + ClassicAssert.AreEqual("%checkpoint_demo%", query.QueryVariables["gwName0"]); + ClassicAssert.AreEqual("%fortigate_demo%", query.QueryVariables["gwName1"]); + ClassicAssert.AreEqual("IsoAAADray.local", query.QueryVariables["dst2"]); + } + + [Test] + [Parallelizable] + public void ExactEquals3() + { + try + { + ReportTemplate t = new() + { + Filter = "(gateway=\"checkpoint_demo\" or gateway = \"fortigate_demo\") & dst ==" + }; + t.ReportParams.ReportType = (int)ReportType.Rules; + Compiler.Compile(t); + Assert.Fail("Exception should have been thrown"); + } + catch (SyntaxException exception) + { + ClassicAssert.AreEqual("No token but one was expected", exception.Message); + } + } + + [Test] + [Parallelizable] + public void Disabled() + { + ReportTemplate t = new() + { + Filter = "disabled == true" + }; + t.ReportParams.ReportType = (int)ReportType.Rules; + DynGraphqlQuery query = Compiler.Compile(t); + + ClassicAssert.AreEqual(1, query.QueryVariables.Count); + ClassicAssert.AreEqual("true", query.QueryVariables["disabled0"]); + } + + [Test] + [Parallelizable] + public void Brackets() + { + ReportTemplate t = new() + { + Filter = "src=a&(dst=c)" + }; + t.ReportParams.ReportType = (int)ReportType.Rules; + DynGraphqlQuery query = Compiler.Compile(t); + + ClassicAssert.AreEqual(2, query.QueryVariables.Count); + ClassicAssert.AreEqual("%a%", query.QueryVariables["src0"]); + ClassicAssert.AreEqual("%c%", query.QueryVariables["dst1"]); + } + + [Test] + [Parallelizable] + public void RuleRecertPortNot() + { + ReportTemplate t = new() + { + Filter = "not(port=1000)" + }; + t.ReportParams.ReportType = (int)ReportType.Recertification; + DynGraphqlQuery query = Compiler.Compile(t); + + ClassicAssert.AreEqual(3, query.QueryVariables.Count); + ClassicAssert.AreEqual(true, query.QueryVariables.ContainsKey("refdate1")); + ClassicAssert.AreEqual(true, query.QueryVariables.ContainsKey("ownerWhere")); + ClassicAssert.AreEqual("1000", query.QueryVariables["dport0"]); + ClassicAssert.AreEqual("_and: [{rule_head_text: {_is_null: true}}, { rule_metadatum: { recertifications: { next_recert_date: { _lte: $refdate1 } } } }, {_not: {rule_services: { service: { svcgrp_flats: { serviceBySvcgrpFlatMemberId: { svc_port: {_lte: $dport0}, svc_port_end: {_gte: $dport0 } } } } }}}] ", query.RuleWhereStatement); + } + + [Test] + [Parallelizable] + public void RecertOwnerFilterEmpty() + { + ReportTemplate t = new(); + t.ReportParams.ReportType = (int)ReportType.Recertification; + t.ReportParams.RecertFilter.RecertOwnerList = []; + + DynGraphqlQuery query = Compiler.Compile(t); + + ClassicAssert.AreEqual(true, query.QueryVariables.ContainsKey("ownerWhere")); + ClassicAssert.AreEqual("{}", JsonSerializer.Serialize(query.QueryVariables["ownerWhere"])); + } + + [Test] + [Parallelizable] + public void RecertQueryBuildsRulebaseRulesBlock() + { + ReportTemplate t = new(); + t.ReportParams.ReportType = (int)ReportType.Recertification; + + DynGraphqlQuery query = Compiler.Compile(t); + + StringAssert.Contains("rulebase_links(where:", query.FullQuery); + StringAssert.DoesNotContain("rulebase_links(where: { }) { rules (", query.FullQuery); + StringAssert.Contains("rulebases { id uid name rules (", query.FullQuery); + } + + [Test] + [Parallelizable] + public void OwnerFullTextFilterUsesResponsibles() + { + ReportTemplate t = new() + { + Filter = "text=ops" + }; + t.ReportParams.ReportType = (int)ReportType.OwnerRecertification; + DynGraphqlQuery query = Compiler.Compile(t); + + StringAssert.Contains("owner_responsibles", query.OwnerWhereStatement); + ClassicAssert.IsFalse(query.OwnerWhereStatement.Contains("group_dn")); + } + + [Test] + [Parallelizable] + public void OwnerRecertificationFilterIncludesInactiveOwnersSeparately() + { + ReportTemplate t = new(); + t.ReportParams.ReportType = (int)ReportType.OwnerRecertification; + t.ReportParams.ModellingFilter.SelectedOwners = [new() { Id = 1 }]; + t.ReportParams.ModellingFilter.ShowAllOwners = false; + t.ReportParams.ModellingFilter.ShowInactiveRecertOwners = true; + t.ReportParams.RecertFilter.RecertificationDisplayPeriod = 30; + + DynGraphqlQuery query = Compiler.Compile(t); + + StringAssert.Contains("recert_active: { _eq: true }", query.OwnerWhereStatement); + StringAssert.Contains("next_recert_date: { _lte: $refDate }", query.OwnerWhereStatement); + StringAssert.Contains("recert_active: { _eq: false }", query.OwnerWhereStatement); + StringAssert.Contains("_or:", query.OwnerWhereStatement); + } + + [Test] + [Parallelizable] + public void OwnerRecertificationFilterWithZeroDisplayPeriodKeepsOnlyDueActiveOwners() + { + ReportTemplate t = new(); + t.ReportParams.ReportType = (int)ReportType.OwnerRecertification; + t.ReportParams.ModellingFilter.SelectedOwners = [new() { Id = 1 }]; + t.ReportParams.ModellingFilter.ShowAllOwners = false; + t.ReportParams.ModellingFilter.ShowInactiveRecertOwners = false; + t.ReportParams.RecertFilter.RecertificationDisplayPeriod = 0; + + DynGraphqlQuery query = Compiler.Compile(t); + + StringAssert.Contains("recert_active: { _eq: true }", query.OwnerWhereStatement); + StringAssert.Contains("next_recert_date: { _lte: $refDate }", query.OwnerWhereStatement); + StringAssert.DoesNotContain("recert_active: { _eq: false }", query.OwnerWhereStatement); + ClassicAssert.IsTrue(query.QueryVariables.ContainsKey("refDate")); + Assert.That((DateTime)query.QueryVariables["refDate"], Is.EqualTo(DateTime.Now).Within(TimeSpan.FromSeconds(5))); + } + + [Test] + [Parallelizable] + public void OwnersFilterIncludesStateAndCriticality() + { + ReportTemplate t = new(); + t.ReportParams.ReportType = (int)ReportType.Owners; + t.ReportParams.OwnerFilter.SelectedOwnerLifeCycleStateId = 3; + t.ReportParams.OwnerFilter.SelectedCriticality = "High"; + + DynGraphqlQuery query = Compiler.Compile(t); + + StringAssert.Contains("owner_lifecycle_state_id: { _eq: $ownerLifeCycleStateId }", query.OwnerWhereStatement); + StringAssert.Contains("criticality: { _eq: $ownerCriticality }", query.OwnerWhereStatement); + Assert.That(query.QueryVariables["ownerLifeCycleStateId"], Is.EqualTo(3)); + Assert.That(query.QueryVariables["ownerCriticality"], Is.EqualTo("High")); + } + + [Test] + [Parallelizable] + public void OwnersFilterLineIncludesStateAndCriticality() + { + ReportTemplate t = new() + { + Filter = "ownerstate=3 and criticality=High" + }; + t.ReportParams.ReportType = (int)ReportType.Owners; + + DynGraphqlQuery query = Compiler.Compile(t); + + StringAssert.Contains("owner_lifecycle_state_id: { _eq: $ownerLifeCycleStateId0 }", query.OwnerWhereStatement); + StringAssert.Contains("criticality: { _ilike: $ownerCriticality1 }", query.OwnerWhereStatement); + Assert.That(query.QueryVariables["ownerLifeCycleStateId0"], Is.EqualTo(3)); + Assert.That(query.QueryVariables["ownerCriticality1"], Is.EqualTo("%High%")); + } + + [Test] + [Parallelizable] + public void OwnersFilterLineIncludesStateName() + { + ReportTemplate t = new() + { + Filter = "ownerstate=Production" + }; + t.ReportParams.ReportType = (int)ReportType.Owners; + + DynGraphqlQuery query = Compiler.Compile(t); + + StringAssert.Contains("owner_lifecycle_state: { name: { _ilike: $ownerLifeCycleStateName0 } }", query.OwnerWhereStatement); + Assert.That(query.QueryVariables["ownerLifeCycleStateName0"], Is.EqualTo("%Production%")); + } + + [Test] + [Parallelizable] + public void OwnersFilterLineIncludesStateIdNotEquals() + { + ReportTemplate t = new() + { + Filter = "ownerstate!=3" + }; + t.ReportParams.ReportType = (int)ReportType.Owners; + + DynGraphqlQuery query = Compiler.Compile(t); + + StringAssert.Contains("owner_lifecycle_state_id: { _neq: $ownerLifeCycleStateId0 }", query.OwnerWhereStatement); + Assert.That(query.QueryVariables["ownerLifeCycleStateId0"], Is.EqualTo(3)); + } + + [Test] + [Parallelizable] + public void OwnersFilterLineIncludesStateIdLessThan() + { + ReportTemplate t = new() + { + Filter = "ownerstate<3" + }; + t.ReportParams.ReportType = (int)ReportType.Owners; + + DynGraphqlQuery query = Compiler.Compile(t); + + StringAssert.Contains("owner_lifecycle_state_id: { _lt: $ownerLifeCycleStateId0 }", query.OwnerWhereStatement); + Assert.That(query.QueryVariables["ownerLifeCycleStateId0"], Is.EqualTo(3)); + } + + [Test] + [Parallelizable] + public void OwnersFilterLineIncludesStateIdGreaterThan() + { + ReportTemplate t = new() + { + Filter = "ownerstate>3" + }; + t.ReportParams.ReportType = (int)ReportType.Owners; + + DynGraphqlQuery query = Compiler.Compile(t); + + StringAssert.Contains("owner_lifecycle_state_id: { _gt: $ownerLifeCycleStateId0 }", query.OwnerWhereStatement); + Assert.That(query.QueryVariables["ownerLifeCycleStateId0"], Is.EqualTo(3)); + } + + [Test] + [Parallelizable] + public void OwnersFilterLineIncludesStateNameLessThan() + { + ReportTemplate t = new() + { + Filter = "ownerstate { WfTaskType.access.ToString(), WfTaskType.new_interface.ToString() })); + } + + [Test] + [Parallelizable] + public void TicketChangeReport_FiltersBySelectedStates() + { + ReportTemplate template = new() + { + Filter = "" + }; + template.ReportParams.ReportType = (int)ReportType.TicketChangeReport; + template.ReportParams.WorkflowFilter.StateIds = [2, 5]; + + DynGraphqlQuery query = Compiler.Compile(template); + + StringAssert.Contains("state_id: { _in: $state_ids }", query.FullQuery); + Assert.That(query.QueryVariables["state_ids"], Is.EqualTo(new List { 2, 5 })); + } + + [Test] + [Parallelizable] + public void TicketReport_UsesTaskTypeStateAndPhaseFiltersWithoutTimeRange() + { + ReportTemplate template = new() + { + Filter = "" + }; + template.ReportParams.ReportType = (int)ReportType.TicketReport; + template.ReportParams.WorkflowFilter.TaskTypes = [WfTaskType.access, WfTaskType.new_interface]; + template.ReportParams.WorkflowFilter.StateIds = [2, 5]; + template.ReportParams.WorkflowFilter.Phase = "implementation"; + + DynGraphqlQuery query = Compiler.Compile(template); + + StringAssert.Contains("query ticketReport", query.FullQuery); + StringAssert.Contains("reqtasks: { task_type: { _in: $task_types } }", query.FullQuery); + StringAssert.Contains("state_id: { _in: $state_ids }", query.FullQuery); + StringAssert.Contains("state_id: { _gte: $phase_lowest_input_state, _lt: $phase_lowest_end_state }", query.FullQuery); + StringAssert.DoesNotContain("$ticket_time_start", query.FullQuery); + Assert.That(query.QueryVariables["task_types"], Is.EqualTo(new List { WfTaskType.access.ToString(), WfTaskType.new_interface.ToString() })); + Assert.That(query.QueryVariables["state_ids"], Is.EqualTo(new List { 2, 5 })); + } + + [Test] + [Parallelizable] + public void TicketChangeReport_UsesTaskTypeStatePhaseAndTimeFilters() + { + ReportTemplate template = new() + { + Filter = "" + }; + template.ReportParams.ReportType = (int)ReportType.TicketChangeReport; + template.ReportParams.TimeFilter.TimeRangeType = TimeRangeType.Shortcut; + template.ReportParams.TimeFilter.TimeRangeShortcut = "today"; + template.ReportParams.WorkflowFilter.TaskTypes = [WfTaskType.access, WfTaskType.new_interface]; + template.ReportParams.WorkflowFilter.StateIds = [2, 5]; + template.ReportParams.WorkflowFilter.Phase = "implementation"; + + DynGraphqlQuery query = Compiler.Compile(template); + + StringAssert.Contains("query ticketChangeReport", query.FullQuery); + StringAssert.Contains("reqtasks: { task_type: { _in: $task_types } }", query.FullQuery); + StringAssert.Contains("state_id: { _in: $state_ids }", query.FullQuery); + StringAssert.Contains("state_id: { _gte: $phase_lowest_input_state, _lt: $phase_lowest_end_state }", query.FullQuery); + StringAssert.Contains("$ticket_time_start", query.FullQuery); + StringAssert.Contains("$ticket_time_end", query.FullQuery); + Assert.That(query.QueryVariables["task_types"], Is.EqualTo(new List { WfTaskType.access.ToString(), WfTaskType.new_interface.ToString() })); + Assert.That(query.QueryVariables["state_ids"], Is.EqualTo(new List { 2, 5 })); + } + + [Test] + [Parallelizable] + public void TicketReport_FilterLineAppliesWorkflowTaskTypeStateAndPhaseFilters() + { + ReportTemplate template = new() + { + Filter = "tasktype=access,new_interface and states=2,5 and phase=implementation" + }; + template.ReportParams.ReportType = (int)ReportType.TicketReport; + + DynGraphqlQuery query = Compiler.Compile(template); + + StringAssert.Contains("query ticketReport", query.FullQuery); + StringAssert.Contains("reqtasks: { task_type: { _in: $task_types } }", query.FullQuery); + StringAssert.Contains("state_id: { _in: $state_ids }", query.FullQuery); + StringAssert.Contains("state_id: { _gte: $phase_lowest_input_state, _lt: $phase_lowest_end_state }", query.FullQuery); + Assert.That(query.QueryVariables["task_types"], Is.EqualTo(new List { WfTaskType.access.ToString(), WfTaskType.new_interface.ToString() })); + Assert.That(query.QueryVariables["state_ids"], Is.EqualTo(new List { 2, 5 })); + } + + [Test] + [Parallelizable] + public void TicketReport_FilterLineAppliesClosedPhaseFilter() + { + ReportTemplate template = new() + { + Filter = $"phase={GlobalConst.kClosed}" + }; + template.ReportParams.ReportType = (int)ReportType.TicketReport; + + DynGraphqlQuery query = Compiler.Compile(template); + + StringAssert.Contains("state_id: { _gte: $phase_lowest_input_state }", query.FullQuery); + StringAssert.DoesNotContain("$phase_lowest_end_state", query.FullQuery); + } + + [Test] + [Parallelizable] + public void TicketReport_FilterLineRejectsUnknownWorkflowPhase() + { + ReportTemplate template = new() + { + Filter = "phase=imaginary" + }; + template.ReportParams.ReportType = (int)ReportType.TicketReport; + + Assert.Throws(() => Compiler.Compile(template)); + } + + [Test] + [Parallelizable] + public void RulesReport_LastHitLessThanIncludesNullHits() + { + ReportTemplate template = new() + { + Filter = "lasthit<2025-01-01" + }; + template.ReportParams.ReportType = (int)ReportType.Rules; + + DynGraphqlQuery query = Compiler.Compile(template); + + StringAssert.Contains("rule_last_hit", query.RuleWhereStatement); + StringAssert.Contains("_is_null: true", query.RuleWhereStatement); + StringAssert.Contains("_or:", query.RuleWhereStatement); + } + + [Test] + [Parallelizable] + public void RulesReport_LastHitEqualsThisYearUsesStartOfCurrentYear() + { + ReportTemplate template = new() + { + Filter = "lasthit=\"this year\"" + }; + template.ReportParams.ReportType = (int)ReportType.Rules; + + DynGraphqlQuery query = Compiler.Compile(template); + + string expected = new DateTime(DateTime.Now.Year, 1, 1, 0, 0, 0).ToString(DynGraphqlQuery.fullTimeFormat); + Assert.That(query.QueryVariables["lastHitLimit0"], Is.EqualTo(expected)); + } + + [Test] + [Parallelizable] + public void RulesReport_LastHitRejectsInvalidTimeRangeFormat() + { + ReportTemplate template = new() + { + Filter = "lasthit=definitely-not-a-date" + }; + template.ReportParams.ReportType = (int)ReportType.Rules; + + Assert.Throws(() => Compiler.Compile(template)); + } + + [Test] + [Parallelizable] + public void ChangesReport_LastHitGreaterThanUsesNestedRuleMetadataWithoutNullHits() + { + ReportTemplate template = new() + { + Filter = "lasthit>2025-01-01" + }; + template.ReportParams.ReportType = (int)ReportType.Changes; + + DynGraphqlQuery query = Compiler.Compile(template); + + StringAssert.Contains("rule: { rule_metadatum:{ rule_last_hit:", query.RuleWhereStatement); + StringAssert.DoesNotContain("_is_null: true", query.RuleWhereStatement); + StringAssert.DoesNotContain("_or:", query.RuleWhereStatement); + } + + [Test] + [Parallelizable] + public void ChangesReport_LastHitLessThanUsesNestedRuleMetadataAndIncludesNullHits() + { + ReportTemplate template = new() + { + Filter = "lasthit<2025-01-01" + }; + template.ReportParams.ReportType = (int)ReportType.Changes; + + DynGraphqlQuery query = Compiler.Compile(template); + + StringAssert.Contains("rule: { rule_metadatum: { rule_last_hit:", query.RuleWhereStatement); + StringAssert.Contains("_is_null: true", query.RuleWhereStatement); + StringAssert.Contains("_or:", query.RuleWhereStatement); + } + + [Test] + [Parallelizable] + public void RulesReport_LastHitGreaterThanOmitsNullHits() + { + ReportTemplate template = new() + { + Filter = "lasthit>2025-01-01" + }; + template.ReportParams.ReportType = (int)ReportType.Rules; + + DynGraphqlQuery query = Compiler.Compile(template); + + StringAssert.Contains("rule_metadatum: { rule_last_hit:", query.RuleWhereStatement); + StringAssert.DoesNotContain("rule_last_hit: {_is_null: true", query.RuleWhereStatement); + StringAssert.DoesNotContain("rule: { rule_metadatum", query.RuleWhereStatement); + } + + [Test] + [Parallelizable] + public void LastHitNotEqualsRaisesSemanticException() + { + ReportTemplate template = new() + { + Filter = "lasthit!=2025-01-01" + }; + template.ReportParams.ReportType = (int)ReportType.Rules; + + Assert.Throws(() => Compiler.Compile(template)); + } + + [Test] + [Parallelizable] + public void OrConnectorBuildsOrWhereClause() + { + ReportTemplate template = new() + { + Filter = "action=accept or protocol=tcp" + }; + template.ReportParams.ReportType = (int)ReportType.Rules; + + DynGraphqlQuery query = Compiler.Compile(template); + + StringAssert.Contains("{_or: [{rule_action: { _ilike: $action0 }}, {rule_services: {service: {stm_ip_proto: {ip_proto_name: { _ilike: $proto1 } } } }}] }", query.RuleWhereStatement); + StringAssert.Contains("rule_action: { _ilike: $action0 }", query.RuleWhereStatement); + StringAssert.Contains("ip_proto_name: { _ilike: $proto1 }", query.RuleWhereStatement); + } + + [Test] + [Parallelizable] + public void AstNodeConnector_AndExtractWrapsAllWhereStatements() + { + DynGraphqlQuery query = new(""); + AstNodeConnector connector = new() + { + Connector = new Token(new Range(), "and", TokenKind.And), + Left = new StubAstNode((ref DynGraphqlQuery q, ReportType? _) => + { + q.RuleWhereStatement += "left-rule"; + q.NwObjWhereStatement += "left-nw"; + q.SvcObjWhereStatement += "left-svc"; + q.UserObjWhereStatement += "left-user"; + q.ConnectionWhereStatement += "left-conn"; + }), + Right = new StubAstNode((ref DynGraphqlQuery q, ReportType? _) => + { + q.RuleWhereStatement += "right-rule"; + q.NwObjWhereStatement += "right-nw"; + q.SvcObjWhereStatement += "right-svc"; + q.UserObjWhereStatement += "right-user"; + q.ConnectionWhereStatement += "right-conn"; + }) + }; + + connector.Extract(ref query, ReportType.Rules); + + Assert.That(query.RuleWhereStatement, Is.EqualTo("_and: [{left-rule}, {right-rule}] ")); + Assert.That(query.NwObjWhereStatement, Is.EqualTo("_and: [{left-nw}, {right-nw}] ")); + Assert.That(query.SvcObjWhereStatement, Is.EqualTo("_and: [{left-svc}, {right-svc}] ")); + Assert.That(query.UserObjWhereStatement, Is.EqualTo("_and: [{left-user}, {right-user}] ")); + Assert.That(query.ConnectionWhereStatement, Is.EqualTo("_and: [{left-conn}, {right-conn}] ")); + } + + [Test] + [Parallelizable] + public void AstNodeConnector_ExtractThrowsWhenConnectorMissing() + { + DynGraphqlQuery query = new(""); + AstNodeConnector connector = new() + { + Left = new StubAstNode((ref DynGraphqlQuery _, ReportType? _) => { }), + Right = new StubAstNode((ref DynGraphqlQuery _, ReportType? _) => { }) + }; + + InvalidOperationException exception = Assert.Throws(() => connector.Extract(ref query, ReportType.Rules))!; + + Assert.That(exception.Message, Does.Contain("Connector")); + } + + [Test] + [Parallelizable] + public void AstNodeConnector_ExtractThrowsWhenLeftMissing() + { + DynGraphqlQuery query = new(""); + AstNodeConnector connector = new() + { + Connector = new Token(new Range(), "and", TokenKind.And), + Right = new StubAstNode((ref DynGraphqlQuery _, ReportType? _) => { }) + }; + + InvalidOperationException exception = Assert.Throws(() => connector.Extract(ref query, ReportType.Rules))!; + + Assert.That(exception.Message, Does.Contain("Left")); + } + + [Test] + [Parallelizable] + public void AstNodeConnector_ExtractThrowsWhenRightMissing() + { + DynGraphqlQuery query = new(""); + AstNodeConnector connector = new() + { + Connector = new Token(new Range(), "and", TokenKind.And), + Left = new StubAstNode((ref DynGraphqlQuery _, ReportType? _) => { }) + }; + + InvalidOperationException exception = Assert.Throws(() => connector.Extract(ref query, ReportType.Rules))!; + + Assert.That(exception.Message, Does.Contain("Right")); + } + + [Test] + [Parallelizable] + public void AstNodeConnector_ExtractThrowsForUnsupportedConnector() + { + DynGraphqlQuery query = new(""); + AstNodeConnector connector = new() + { + Connector = new Token(new Range(), "xor", TokenKind.Not), + Left = new StubAstNode((ref DynGraphqlQuery _, ReportType? _) => { }), + Right = new StubAstNode((ref DynGraphqlQuery _, ReportType? _) => { }) + }; + + SemanticException exception = Assert.Throws(() => connector.Extract(ref query, ReportType.Rules))!; + + Assert.That(exception.Message, Does.Contain("unsupported connector token")); + } + + [Test] + [Parallelizable] + public void ReportTypeFilter_ParsesStatisticsAliasAndAddsStatisticsRuleFilter() + { + ReportTemplate template = new() + { + Filter = "type=statistic" + }; + template.ReportParams.ReportType = (int)ReportType.Rules; + + DynGraphqlQuery query = Compiler.Compile(template); + + Assert.That(query.ReportType, Is.EqualTo(ReportType.Statistics)); + StringAssert.Contains("rule_head_text: {_is_null: true}", query.RuleWhereStatement); + } + + [Test] + [Parallelizable] + public void ReportTypeFilter_RejectsUnknownReportType() + { + ReportTemplate template = new() + { + Filter = "reporttype=imaginary" + }; + template.ReportParams.ReportType = (int)ReportType.Rules; + + Assert.Throws(() => Compiler.Compile(template)); + } + + [Test] + [Parallelizable] + public void BoolFilter_RemoveBuildsRuleToBeRemovedFilter() + { + ReportTemplate template = new() + { + Filter = "remove=true" + }; + template.ReportParams.ReportType = (int)ReportType.Rules; + + DynGraphqlQuery query = Compiler.Compile(template); + + Assert.That(query.QueryVariables["remove0"], Is.EqualTo("true")); + StringAssert.Contains("rule_to_be_removed", query.RuleWhereStatement); + } + + [Test] + [Parallelizable] + public void BoolFilter_RejectsInvalidBooleanValue() + { + ReportTemplate template = new() + { + Filter = "disabled=maybe" + }; + template.ReportParams.ReportType = (int)ReportType.Rules; + + Assert.Throws(() => Compiler.Compile(template)); + } + + [Test] + [Parallelizable] + public void BoolFilter_DisabledNotEqualsBuildsNegativeRuleDisabledFilter() + { + ReportTemplate template = new() + { + Filter = "disabled!=true" + }; + template.ReportParams.ReportType = (int)ReportType.Rules; + + DynGraphqlQuery query = Compiler.Compile(template); + + Assert.That(query.QueryVariables["disabled0"], Is.EqualTo("true")); + StringAssert.Contains("rule_disabled: { _neq: $disabled0 }", query.RuleWhereStatement); + } + + [Test] + [Parallelizable] + public void IntFilter_UnusedBuildsLastHitCutoffFilter() + { + ReportTemplate template = new() + { + Filter = "unused=30" + }; + template.ReportParams.ReportType = (int)ReportType.Rules; + + DynGraphqlQuery query = Compiler.Compile(template); + + Assert.That(query.QueryVariables.ContainsKey("cut0"), Is.True); + StringAssert.Contains("rule_last_hit", query.RuleWhereStatement); + StringAssert.Contains("_is_null: true", query.RuleWhereStatement); + } + + [Test] + [Parallelizable] + public void IntFilter_RejectsInvalidIntegerValue() + { + ReportTemplate template = new() + { + Filter = "unused=abc" + }; + template.ReportParams.ReportType = (int)ReportType.Rules; + + Assert.Throws(() => Compiler.Compile(template)); + } + + [Test] + [Parallelizable] + public void IntFilter_DestinationPortBuildsRuleAndConnectionFilters() + { + ReportTemplate template = new() + { + Filter = "port=443" + }; + template.ReportParams.ReportType = (int)ReportType.Rules; + + DynGraphqlQuery query = Compiler.Compile(template); + + Assert.That(query.QueryVariables["dport0"], Is.EqualTo("443")); + StringAssert.Contains("svc_port: {_lte: $dport0}", query.RuleWhereStatement); + StringAssert.Contains("service_connections: {service: { port: { _lte: $dport0 }, port_end: { _gte: $dport0 } } }", query.ConnectionWhereStatement); + StringAssert.Contains("service_group_connections: {service_group: { service_service_groups:", query.ConnectionWhereStatement); + } + + [Test] + [Parallelizable] + public void NetworkFilter_SourceNameExactEqualsBuildsNameFilters() + { + ReportTemplate template = new() + { + Filter = "src==AppServer1" + }; + template.ReportParams.ReportType = (int)ReportType.Rules; + + DynGraphqlQuery query = Compiler.Compile(template); + + Assert.That(query.QueryVariables["src0"], Is.EqualTo("AppServer1")); + StringAssert.Contains("rule_froms: { object: { objgrp_flats: { objectByObjgrpFlatMemberId: { obj_name: { _eq: $src0 } } } } }", query.RuleWhereStatement); + StringAssert.Contains("owner_network: {name: { _eq: $src0 } }", query.ConnectionWhereStatement); + StringAssert.Contains("id_string: { _eq: $src0 }", query.ConnectionWhereStatement); + } + + [Test] + [Parallelizable] + public void NetworkFilter_DestinationNameNotEqualsBuildsNegativeNameFilters() + { + ReportTemplate template = new() + { + Filter = "dst!=AppRole1" + }; + template.ReportParams.ReportType = (int)ReportType.Rules; + + DynGraphqlQuery query = Compiler.Compile(template); + + Assert.That(query.QueryVariables["dst0"], Is.EqualTo("AppRole1")); + StringAssert.Contains("obj_name: { _nilike: $dst0 }", query.RuleWhereStatement); + StringAssert.Contains("owner_network: {name: { _nilike: $dst0 } }", query.ConnectionWhereStatement); + StringAssert.Contains("id_string: { _nilike: $dst0 }", query.ConnectionWhereStatement); + } + + [Test] + [Parallelizable] + public void TicketChangeReport_FilterLineAppliesReferenceDateFilter() + { + ReportTemplate template = new() + { + Filter = "reference_date=ImplementationStart" + }; + template.ReportParams.ReportType = (int)ReportType.TicketChangeReport; + + DynGraphqlQuery query = Compiler.Compile(template); + + StringAssert.Contains("impltasks: { _and: [{ start: { _gte: $ticket_time_start } }", query.FullQuery); + } + + [Test] + [Parallelizable] + public void TicketReport_FiltersByWorkflowLabelValueTrue() + { + ReportTemplate template = new() + { + Filter = "" + }; + template.ReportParams.ReportType = (int)ReportType.TicketReport; + template.ReportParams.WorkflowFilter.LabelFilter = new() { Name = "policy_check", Mode = WorkflowLabelFilterMode.value, Value = "true" }; + + DynGraphqlQuery query = Compiler.Compile(template); + + StringAssert.Contains("reqtasks: { additional_info: { _ilike: $labelValuePattern0 } }", query.FullQuery); + Assert.That(query.QueryVariables["labelValuePattern0"], Is.EqualTo("%\"policy_check\":\"true\"%")); + } + + [Test] + [Parallelizable] + public void TicketReport_FiltersByWorkflowLabelNotExisting() + { + ReportTemplate template = new() + { + Filter = "" + }; + template.ReportParams.ReportType = (int)ReportType.TicketReport; + template.ReportParams.WorkflowFilter.LabelFilter = new() { Name = "policy_check", Mode = WorkflowLabelFilterMode.not_existing }; + + DynGraphqlQuery query = Compiler.Compile(template); + + StringAssert.Contains("_not: { reqtasks: { additional_info: { _ilike: $labelKeyPattern0 } } }", query.FullQuery); + Assert.That(query.QueryVariables["labelKeyPattern0"], Is.EqualTo("%\"policy_check\":%")); + } + + [Test] + [Parallelizable] + public void TicketReport_FilterLineSupportsSingularStateAlias() + { + ReportTemplate template = new() + { + Filter = "state=49" + }; + template.ReportParams.ReportType = (int)ReportType.TicketReport; + + DynGraphqlQuery query = Compiler.Compile(template); + + StringAssert.Contains("query ticketReport", query.FullQuery); + Assert.That(query.QueryVariables["state_ids"], Is.EqualTo(new List { 49 })); + } + + [Test] + [Parallelizable] + public void TicketReport_FilterLineDoesNotBreakPlainTextStatusSearch() + { + ReportTemplate template = new() + { + Filter = "status49" + }; + template.ReportParams.ReportType = (int)ReportType.TicketReport; + + DynGraphqlQuery query = Compiler.Compile(template); + + StringAssert.Contains("query ticketReport", query.FullQuery); + Assert.That(query.QueryVariables, Does.ContainKey("task_types")); + Assert.That(query.QueryVariables, Does.Not.ContainKey("state_ids")); + } + } +} diff --git a/roles/tests-unit/files/FWO.Test/Fixtures/ComplianceCheckTestFixture.cs b/roles/tests-unit/files/FWO.Test/Fixtures/ComplianceCheckTestFixture.cs new file mode 100644 index 0000000000..c707f1609a --- /dev/null +++ b/roles/tests-unit/files/FWO.Test/Fixtures/ComplianceCheckTestFixture.cs @@ -0,0 +1,342 @@ +using System.Net; +using FWO.Api.Client.Queries; +using FWO.Basics; +using FWO.Compliance; +using FWO.Config.Api; +using FWO.Data; +using FWO.Logging; +using FWO.Test.Mocks; +using NetTools; +using NSubstitute; + +namespace FWO.Test.Fixtures +{ + public class ComplianceCheckTestFixture + { + protected virtual ComplianceCheck ComplianceCheck { get; set; } = default!; + protected virtual TimeSpan MaxAcceptableExecutionTime { get; set; } = TimeSpan.FromSeconds(60); + protected virtual List[] RuleChunks { get; set; } = default!; + protected virtual GlobalConfig GlobalConfig { get; set; } = default!; + protected virtual UserConfig UserConfig { get; set; } = default!; + protected virtual MockApiConnection ApiConnection { get; set; } = default!; + protected virtual MockLogger Logger { get; set; } = default!; + protected virtual CompliancePolicy? Policy { get; set; } = null; + + private const string ForbiddenServiceUid = "forbidden-service-uid"; + + public virtual void SetUpTest() + { + LocalSettings.ComplianceCheckVerbose = true; + + ApiConnection = new(); + Logger = new(); + GlobalConfig = new SimulatedGlobalConfig { AutoCalculateInternetZone = true, AutoCalculateUndefinedInternalZone = true, TreatDynamicAndDomainObjectsAsInternet = true }; + UserConfig = new UserConfig(GlobalConfig, false); + + SimulatedUserConfig.DummyTranslate["internet_local_zone"] = "Internet/Local"; + SimulatedUserConfig.DummyTranslate["assess_broadcast"] = "Network objects in source or destination with 255.255.255.255/32"; + SimulatedUserConfig.DummyTranslate["assess_host_address"] = "Network objects in source or destination with 0.0.0.0/32"; + SimulatedUserConfig.DummyTranslate["assess_all_ips"] = "Network objects in source or destination with 0.0.0.0/0 or ::/0"; + SimulatedUserConfig.DummyTranslate["assess_ip_null"] = "Network objects in source or destination without IP"; + SimulatedUserConfig.DummyTranslate["H5839"] = "Matrix violation"; + SimulatedUserConfig.DummyTranslate["H5840"] = "Restricted Service"; + SimulatedUserConfig.DummyTranslate["H5841"] = "Assessability issue"; + + ComplianceCheck = new ComplianceCheck(UserConfig, ApiConnection, Logger.AsSub()); + ComplianceCheck.NetworkZones = CreateNetworkZones(true, true); + } + + protected virtual Task SetUpBasic(bool createEmptyPolicy = false, bool setupRelevantManagements = false, bool createPolicy = false, bool createRules = false, bool setupNoViolations = false) + { + GlobalConfig.ComplianceCheckPolicyId = 1; + + if (createEmptyPolicy) + { + ApiConnection.AsSub() + .SendQueryAsync(ComplianceQueries.getPolicyById, Arg.Any()) + .Returns(new CompliancePolicy()); // Policy without criteria + } + + if (setupRelevantManagements) + { + GlobalConfig.ComplianceCheckRelevantManagements = "1,2,3"; + + ApiConnection.AsSub() + .SendQueryAsync>(DeviceQueries.getManagementNames) + .Returns([new Management { Id = 1, Name = "Mgmt1" }]); + } + + if (createPolicy) + { + Policy = CreatePolicy(ForbiddenServiceUid); + ComplianceCheck.Policy = Policy; + + ApiConnection.AsSub() + .SendQueryAsync(ComplianceQueries.getPolicyById, Arg.Any()) + .Returns(Policy); // Policy with criteria + + ApiConnection.AsSub() + .SendQueryAsync>(ComplianceQueries.getNetworkZonesForMatrix, Arg.Any()) + .Returns(ComplianceCheck.NetworkZones); + } + + if (createRules) + { + if (!setupNoViolations) + { + ComplianceCriterion? matrix = ComplianceCheck.Policy!.Criteria + .FirstOrDefault(c => c.Content.CriterionType == nameof(CriterionType.Matrix))?.Content; + + ComplianceCheck.NetworkZones = CreateNetworkZones(true, true); + } + + ComplianceCheck.RulesInCheck = CreateRulesForComplianceCheckTest(setupNoViolations, ForbiddenServiceUid); + + ApiConnection.AsSub() + .SendQueryAsync>(RuleQueries.getRulesForSelectedManagements, Arg.Any()) + .Returns(ComplianceCheck.RulesInCheck); + } + + SetUpViolationCount(1); + + return Task.CompletedTask; + } + + protected virtual List[] BuildFixedRuleChunksParallel(int numberOfChunks, int numberOfRulesPerChunk, int startRuleId = 1, int? maxDegreeOfParallelism = null) + { + if (numberOfChunks <= 0) throw new ArgumentOutOfRangeException(nameof(numberOfChunks)); + if (numberOfRulesPerChunk < 0) throw new ArgumentOutOfRangeException(nameof(numberOfRulesPerChunk)); + + var ruleChunks = new List[numberOfChunks]; + + Parallel.For( + 0, numberOfChunks, + new ParallelOptions { MaxDegreeOfParallelism = maxDegreeOfParallelism ?? Environment.ProcessorCount }, + i => + { + var list = new List(numberOfRulesPerChunk); + int baseId = startRuleId + i * numberOfRulesPerChunk; + + for (int j = 0; j < numberOfRulesPerChunk; j++) + { + list.Add(CreateSimpleRule(baseId + j)); + } + + ruleChunks[i] = list; + }); + + return ruleChunks; + } + + protected virtual List CreateRulesForComplianceCheckTest(bool allCompliant = false, string forbiddenServiceUid = "") + { + if (allCompliant) + { + return new List + { + CreateSimpleRule(1), + CreateSimpleRule(2), + CreateSimpleRule(3), + CreateSimpleRule(4), + CreateSimpleRule(5) + }; + } + else + { + Rule ruleNotAssessable = CreateSimpleRule(1); + ruleNotAssessable.Froms[0].Object.IP = "0.0.0.0/32"; + ruleNotAssessable.Froms[0].Object.IpEnd = "255.255.255.255/32"; + + Rule ruleMatrixViolation = CreateSimpleRule(2, destinationHigh: true); + + Rule ruleMatrixViolationAutoCalcInternet = CreateSimpleRule(3); + ruleMatrixViolationAutoCalcInternet.Froms[0] = new NetworkLocation( + new NetworkUser(), + CreateNetworkObject(3, "source", ObjectType.IPRange) // will be in Internet zone + ); + + Rule ruleForbiddenService = CreateSimpleRule(4); + ruleForbiddenService.Services[0].Content.Uid = forbiddenServiceUid; + + + Rule ruleCompliant = CreateSimpleRule(5); + + return new List + { + ruleNotAssessable, + ruleMatrixViolation, + ruleMatrixViolationAutoCalcInternet, + ruleForbiddenService, + ruleCompliant + }; + } + } + + protected virtual Rule CreateSimpleRule(int ruleID, bool sourceHigh = false, bool destinationHigh = false) + { + Rule rule = new Rule + { + Id = ruleID, + Action = "accept", + MgmtId = 1 + }; + + NetworkUser user = new(); + NetworkObject source = CreateNetworkObject(ruleID, "source", ObjectType.IPRange, sourceHigh); + NetworkObject destination = CreateNetworkObject(ruleID, "destination", ObjectType.IPRange, destinationHigh); + ServiceWrapper service = new(); + service.Content.Uid = $"service-uid-{ruleID}"; + + rule.Froms = [new(user, source)]; + rule.Tos = [new(user, destination)]; + rule.Services = [service]; + + return rule; + } + + protected virtual NetworkObject CreateNetworkObject(int ruleId, string uidPrefix, string objectTypeName, bool? highIpRange = null) + { + NetworkObject networkObject = new(); + + if (highIpRange != null) + { + if (highIpRange.Value) + { + networkObject.IP = "193.0.0.0/32"; + networkObject.IpEnd = "198.0.0.0/32"; + } + else + { + networkObject.IP = "128.0.0.0/32"; + networkObject.IpEnd = "168.0.0.0/32"; + } + } + else // for setting up objects with IPs that are undefined, but not part of a reserved range + { + networkObject.IP = "3.0.0.0/32"; + networkObject.IpEnd = "4.0.0.0/32"; + } + + networkObject.Name = $"{uidPrefix}-uid-rule{ruleId}"; + networkObject.Type.Name = objectTypeName; + + return networkObject; + } + + protected virtual CompliancePolicy CreatePolicy(string forbiddenServiceUid = "") + { + CompliancePolicy policy = new(); + ComplianceCriterionWrapper serviceCriterion = new(); + serviceCriterion.Content.CriterionType = nameof(CriterionType.ForbiddenService); + serviceCriterion.Content.Content = forbiddenServiceUid; + ComplianceCriterionWrapper matrixCriterion = new(); + matrixCriterion.Content.CriterionType = nameof(CriterionType.Matrix); + ComplianceCriterionWrapper assessabilityCriterion = new(); + assessabilityCriterion.Content.CriterionType = nameof(CriterionType.Assessability); + policy.Criteria.AddRange([serviceCriterion, matrixCriterion, assessabilityCriterion]); + return policy; + } + + protected virtual List CreateNetworkZones(bool createInternetZone, bool createUndefinedInternalZone) + { + List networkZones = new() + { + new() + { + Id = 1, + CriterionId = 1, + Name = "128-168 Zone", + IdString = "zone_1", + IPRanges = + [ + new IPAddressRange( + IPAddress.Parse("128.0.0.0"), + IPAddress.Parse("168.0.0.0") + ) + ] + }, + new() + { + Id = 2, + CriterionId = 1, + Name = "193-198 Zone", + IdString = "zone_2", + IPRanges = + [ + new IPAddressRange( + IPAddress.Parse("193.0.0.0"), + IPAddress.Parse("198.0.0.0") + ) + ] + } + }; + + if (createInternetZone) + { + networkZones.Add( + new() + { + Id = 3, + CriterionId = 1, + Name = "Auto-calculated Internet Zone", + IdString = "AUTO_CALCULATED_ZONE_INTERNET", + IsAutoCalculatedInternetZone = true, + IPRanges = + [ + new IPAddressRange( + IPAddress.Parse("0.0.0.0"), + IPAddress.Parse("9.255.255.255") + ), + new IPAddressRange( + IPAddress.Parse("11.0.0.0"), + IPAddress.Parse("127.255.255.255") + ), + new IPAddressRange( + IPAddress.Parse("168.0.0.1"), + IPAddress.Parse("192.255.255.255") + ), + new IPAddressRange( + IPAddress.Parse("198.0.0.1"), + IPAddress.Parse("255.255.255.255") + ) + ] + } + ); + } + + if (createUndefinedInternalZone) + { + networkZones.Add( + new() + { + Id = 4, + CriterionId = 1, + Name = "Auto-calculated Undefined-Interal Zone", + IdString = "AUTO_CALCULATED_ZONE_UNDEFINED_INTERNAL", + IsAutoCalculatedUndefinedInternalZone = true, + IPRanges = + [ + new IPAddressRange( + IPAddress.Parse("10.0.0.0"), + IPAddress.Parse("10.255.255.255") + ) + ] + } + ); + } + + foreach (ComplianceNetworkZone zone in networkZones.Where(zone => !zone.IsAutoCalculatedUndefinedInternalZone).ToList()) + { + zone.AllowedCommunicationDestinations = [zone]; + } + + return networkZones; + } + + protected virtual void SetUpViolationCount(int count) + { + ApiConnection.AsSub() + .SendQueryAsync(ComplianceQueries.getViolationCount).Returns(new AggregateCount { Aggregate = new Aggregate { Count = count } }); + } + } +} diff --git a/roles/tests-unit/files/FWO.Test/FwoOwnerBaseTest.cs b/roles/tests-unit/files/FWO.Test/FwoOwnerBaseTest.cs new file mode 100644 index 0000000000..c6f8183722 --- /dev/null +++ b/roles/tests-unit/files/FWO.Test/FwoOwnerBaseTest.cs @@ -0,0 +1,28 @@ +using FWO.Basics; +using FWO.Data; +using NUnit.Framework; + +namespace FWO.Test +{ + [TestFixture] + public class FwoOwnerBaseTest + { + [Test] + public void GetOwnerResponsiblesByTypeFiltersByTypeId() + { + FwoOwnerBase owner = new() + { + OwnerResponsibles = + [ + new OwnerResponsible { Dn = "cn=main", ResponsibleTypeId = GlobalConst.kOwnerResponsibleTypeMain }, + new OwnerResponsible { Dn = "cn=group", ResponsibleTypeId = GlobalConst.kOwnerResponsibleTypeSupporting } + ] + }; + + var mainResponsibles = owner.GetOwnerResponsiblesByType(GlobalConst.kOwnerResponsibleTypeMain); + + Assert.That(mainResponsibles, Has.Count.EqualTo(1)); + Assert.That(mainResponsibles[0], Is.EqualTo("cn=main")); + } + } +} diff --git a/roles/tests-unit/files/FWO.Test/GraphQlApiConnectionRoleSelectionTest.cs b/roles/tests-unit/files/FWO.Test/GraphQlApiConnectionRoleSelectionTest.cs new file mode 100644 index 0000000000..81975f9234 --- /dev/null +++ b/roles/tests-unit/files/FWO.Test/GraphQlApiConnectionRoleSelectionTest.cs @@ -0,0 +1,52 @@ +using FWO.Api.Client; +using NUnit.Framework; +using System.Security.Claims; + +namespace FWO.Test +{ + [TestFixture] + public class GraphQlApiConnectionRoleSelectionTest + { + [Test] + public void SetBestRoleUsesRoleClaims() + { + using GraphQlApiConnection connection = new("http://localhost"); + ClaimsPrincipal user = new(new ClaimsIdentity( + [ + new Claim(ClaimTypes.Role, "recertifier") + ], "test", ClaimTypes.Name, ClaimTypes.Role)); + + connection.SetBestRole(user, ["modeller", "recertifier", "admin"]); + + Assert.That(connection.GetActRole(), Is.EqualTo("recertifier")); + } + + [Test] + public void SetBestRoleParsesHasuraAllowedRolesJsonArrayClaim() + { + using GraphQlApiConnection connection = new("http://localhost"); + ClaimsPrincipal user = new(new ClaimsIdentity( + [ + new Claim("x-hasura-allowed-roles", "[\"auditor\",\"admin\"]") + ], "test")); + + connection.SetBestRole(user, ["modeller", "admin"]); + + Assert.That(connection.GetActRole(), Is.EqualTo("admin")); + } + + [Test] + public void SetBestRoleParsesNamespacedHasuraAllowedRolesClaim() + { + using GraphQlApiConnection connection = new("http://localhost"); + ClaimsPrincipal user = new(new ClaimsIdentity( + [ + new Claim("https://hasura.io/jwt/claims/x-hasura-allowed-roles", "[\"auditor\",\"modeller\"]") + ], "test")); + + connection.SetBestRole(user, ["recertifier", "modeller"]); + + Assert.That(connection.GetActRole(), Is.EqualTo("modeller")); + } + } +} diff --git a/roles/tests-unit/files/FWO.Test/GraphQlApiConnectionSafeQueryTest.cs b/roles/tests-unit/files/FWO.Test/GraphQlApiConnectionSafeQueryTest.cs new file mode 100644 index 0000000000..14e5bea01f --- /dev/null +++ b/roles/tests-unit/files/FWO.Test/GraphQlApiConnectionSafeQueryTest.cs @@ -0,0 +1,126 @@ +using System; +using System.Net; +using System.Net.Http; +using System.Reflection; +using System.Text; +using System.Threading; +using System.Threading.Tasks; +using FWO.Api.Client; +using GraphQL.Client.Http; +using GraphQL.Client.Serializer.Newtonsoft; +using NUnit.Framework; + +namespace FWO.Test +{ + /// + /// Unit tests for non-throwing GraphQL query behavior. + /// + public class GraphQlApiConnectionSafeQueryTest + { + /// + /// Simple stub handler that returns a fixed response or throws a fixed exception. + /// + private sealed class StubHttpMessageHandler : HttpMessageHandler + { + private readonly Func responder; + private readonly Exception? exception; + + /// + /// Create a handler that returns a fixed response. + /// + public StubHttpMessageHandler(Func responder) + { + this.responder = responder; + } + + /// + /// Create a handler that throws a fixed exception. + /// + public StubHttpMessageHandler(Exception exception) + { + this.exception = exception; + responder = _ => new HttpResponseMessage(HttpStatusCode.InternalServerError); + } + + /// + /// Return the stubbed response or throw the stubbed exception. + /// + protected override Task SendAsync(HttpRequestMessage request, CancellationToken cancellationToken) + { + if (exception != null) + { + throw exception; + } + + return Task.FromResult(responder(request)); + } + } + + /// + /// Builds a GraphQlApiConnection instance with an injected GraphQLHttpClient using the provided handler. + /// + private static GraphQlApiConnection CreateConnectionWithHandler(HttpMessageHandler handler) + { + GraphQlApiConnection connection = new("http://localhost"); + GraphQLHttpClient client = new(new GraphQLHttpClientOptions + { + EndPoint = new Uri("http://localhost/graphql"), + HttpMessageHandler = handler, + UseWebSocketForQueriesAndMutations = false + }, new NewtonsoftJsonSerializer()); + + FieldInfo? field = typeof(GraphQlApiConnection).GetField("graphQlClient", BindingFlags.NonPublic | BindingFlags.Instance); + if (field == null) + { + throw new InvalidOperationException("graphQlClient field not found."); + } + field.SetValue(connection, client); + + return connection; + } + + /// + /// Builds a JSON HTTP response. + /// + private static HttpResponseMessage JsonResponse(string json) + { + return new HttpResponseMessage(HttpStatusCode.OK) + { + Content = new StringContent(json, Encoding.UTF8, "application/json") + }; + } + + /// + /// Errors returned by the GraphQL endpoint are surfaced as ApiResponse errors. + /// + [Test] + public async Task SendQuerySafeAsync_ReturnsErrors_WhenGraphQlErrorsPresent() + { + const string json = "{\"errors\":[{\"message\":\"boom\"}]}"; + using GraphQlApiConnection connection = CreateConnectionWithHandler(new StubHttpMessageHandler(_ => JsonResponse(json))); + + ApiResponse response = await connection.SendQuerySafeAsync("query { test }"); + + Assert.That(response.HasErrors, Is.True); + Assert.That(response.Errors, Is.Not.Null); + Assert.That(response.Errors!, Does.Contain("boom")); + Assert.That(response.Result, Is.Null); + } + + /// + /// Exceptions thrown during transport are converted to ApiResponse errors. + /// + [Test] + public async Task SendQuerySafeAsync_ReturnsError_WhenHttpThrows() + { + using GraphQlApiConnection connection = CreateConnectionWithHandler(new StubHttpMessageHandler(new HttpRequestException("network down"))); + + ApiResponse response = await connection.SendQuerySafeAsync("query { test }"); + + Assert.That(response.HasErrors, Is.True); + Assert.That(response.Errors, Is.Not.Null); + Assert.That(response.Errors![0], Does.Contain("network down")); + Assert.That(response.Result, Is.Null); + } + } +} diff --git a/roles/tests-unit/files/FWO.Test/HtmlToPdfTest.cs b/roles/tests-unit/files/FWO.Test/HtmlToPdfTest.cs new file mode 100644 index 0000000000..976117698b --- /dev/null +++ b/roles/tests-unit/files/FWO.Test/HtmlToPdfTest.cs @@ -0,0 +1,215 @@ +using NUnit.Framework; +using NUnit.Framework.Legacy; +using FWO.Logging; +using PuppeteerSharp.Media; +using PuppeteerSharp; +using PuppeteerSharp.BrowserData; +using FWO.Report; +using FWO.Report.Data; +using FWO.Basics; + +namespace FWO.Test +{ + [TestFixture] + [Parallelizable] + internal class HtmlToPdfTest + { + [Test] + public async Task GeneratePdf() + { + bool isValidHtml = ReportBase.IsValidHTML(GlobalConst.TestPDFHtmlTemplate); + ClassicAssert.IsTrue(isValidHtml); + + string? sudoUser = Environment.GetEnvironmentVariable("SUDO_USER"); + bool isGitHubActions = sudoUser is not null && sudoUser.Equals("runner", StringComparison.OrdinalIgnoreCase); + + if (ShouldSkipPdfTest(isGitHubActions, out string skipReason)) + { + Log.WriteInfo("Test Log", skipReason); + Assert.Ignore(skipReason); + } + + if (File.Exists(GlobalConst.TestPDFFilePath)) + File.Delete(GlobalConst.TestPDFFilePath); + + OperatingSystem? os = Environment.OSVersion; + + Log.WriteInfo("Test Log", $"OS: {os}"); + + string path = ""; + Platform platform = Platform.Unknown; + const SupportedBrowser wantedBrowser = SupportedBrowser.Chrome; + + switch (os.Platform) + { + case PlatformID.Win32NT: + platform = Platform.Win32; + break; + case PlatformID.Unix: + path = GlobalConst.ChromeBinPathLinux; + platform = Platform.Linux; + break; + default: + break; + } + + BrowserFetcher browserFetcher = new(new BrowserFetcherOptions() { Platform = platform, Browser = wantedBrowser, Path = path }); + + IEnumerable? allInstalledBrowsers = browserFetcher.GetInstalledBrowsers().Where(_ => _.Browser == wantedBrowser); + + if (allInstalledBrowsers is null || !allInstalledBrowsers.Any()) + { + // this should only happen for testing on local systems where no suitable browser is installed + Log.WriteInfo("Browser", $"Browser not found for current system - trying to download..."); + await browserFetcher.DownloadAsync(); + allInstalledBrowsers = browserFetcher.GetInstalledBrowsers().Where(_ => _.Browser == wantedBrowser); + } + + foreach (InstalledBrowser instBrowser in allInstalledBrowsers) + { + Log.WriteInfo("Test Log", $"Found installed {instBrowser.Browser}({instBrowser.BuildId}) at: {instBrowser.GetExecutablePath()}"); + } + + string? newestBuildId = allInstalledBrowsers.Max(_ => _.BuildId); + + if (string.IsNullOrWhiteSpace(newestBuildId)) + { + Log.WriteAlert("Test Log", $"Invalid build ID!"); + return; + } + + InstalledBrowser? latestInstalledBrowser = allInstalledBrowsers.Single(_ => _.BuildId == newestBuildId); + + if (latestInstalledBrowser is null) + { + Log.WriteAlert("Test Log", $"Found no installed {wantedBrowser} instances with a valid build ID!"); + return; + } + + Log.WriteInfo("Test Log", $"Selecting latest installed {wantedBrowser}({latestInstalledBrowser.BuildId}) at: {latestInstalledBrowser.GetExecutablePath()}"); + + IBrowser? browser; + + try + { + browser = await Puppeteer.LaunchAsync(new LaunchOptions + { + ExecutablePath = latestInstalledBrowser.GetExecutablePath(), + Headless = true, + DumpIO = isGitHubActions, + Args = isGitHubActions ? ["--database=/tmp", "--no-sandbox"] : [] + }); + } + catch (Exception) + { + Log.WriteAlert("Test Log", $"Couldn't start {wantedBrowser} instance!"); + throw new Exception($"Couldn't start {wantedBrowser} instance!"); + } + + await TryCreatePDF(browser, PuppeteerSharp.Media.PaperFormat.A0); + await TryCreatePDF(browser, PuppeteerSharp.Media.PaperFormat.A1); + await TryCreatePDF(browser, PuppeteerSharp.Media.PaperFormat.A2); + await TryCreatePDF(browser, PuppeteerSharp.Media.PaperFormat.A3); + await TryCreatePDF(browser, PuppeteerSharp.Media.PaperFormat.A4); + await TryCreatePDF(browser, PuppeteerSharp.Media.PaperFormat.A5); + await TryCreatePDF(browser, PuppeteerSharp.Media.PaperFormat.A6); + + await TryCreatePDF(browser, PuppeteerSharp.Media.PaperFormat.Ledger); + await TryCreatePDF(browser, PuppeteerSharp.Media.PaperFormat.Legal); + await TryCreatePDF(browser, PuppeteerSharp.Media.PaperFormat.Letter); + await TryCreatePDF(browser, PuppeteerSharp.Media.PaperFormat.Tabloid); + + try + { + await browser.CloseAsync(); + browser.Dispose(); + } + catch (Exception) + { + throw new Exception("Couldn't close browser instance!"); + } + } + + [Test] + public void TryCreateToC() + { + bool isValidHtml = ReportBase.IsValidHTML(GlobalConst.TestPDFHtmlTemplate); + ClassicAssert.IsTrue(isValidHtml); + + List? tocContent = ReportBase.CreateTOCContent(GlobalConst.TestPDFHtmlTemplate); + + ClassicAssert.AreEqual(tocContent.Count, 2); + ClassicAssert.AreEqual(tocContent[0].Title, "test"); + ClassicAssert.AreEqual(tocContent[1].Title, "test mit puppteer"); + } + + private async Task TryCreatePDF(IBrowser browser, PuppeteerSharp.Media.PaperFormat paperFormat) + { + if (browser.IsClosed || !browser.IsConnected || browser.Process == null) + { + Log.WriteAlert("Test Log", $"Browser: {browser.GetVersionAsync()} is not started or closed due to errors!"); + return; + } + + Log.WriteInfo("Test Log", $"Test creating PDF {paperFormat}"); + + try + { + using IPage page = await browser.NewPageAsync(); + await page.SetContentAsync(GlobalConst.TestPDFHtmlTemplate); + + PdfOptions pdfOptions = new() { Outline = true, DisplayHeaderFooter = false, Landscape = true, PrintBackground = true, Format = paperFormat, MarginOptions = new MarginOptions { Top = "1cm", Bottom = "1cm", Left = "1cm", Right = "1cm" } }; + byte[]? pdfData = await page.PdfDataAsync(pdfOptions); + await File.WriteAllBytesAsync(GlobalConst.TestPDFFilePath, pdfData); + + Assert.That(GlobalConst.TestPDFFilePath, Does.Exist); + FileAssert.Exists(GlobalConst.TestPDFFilePath); + ClassicAssert.AreEqual(new FileInfo(GlobalConst.TestPDFFilePath).Length, pdfData.Length); + } + catch (Exception ex) + { + Log.WriteAlert("Test Log", $"{ex.Message}"); + return; + } + } + + [OneTimeTearDown] + public void OnFinished() + { + if (File.Exists(GlobalConst.TestPDFFilePath)) + { + File.Delete(GlobalConst.TestPDFFilePath); + } + } + + private static bool ShouldSkipPdfTest(bool isGitHubActions, out string reason) + { + if (isGitHubActions) + { + reason = "PDF Test skipping: Test is running on Github actions."; + return true; + } + + string? skipEnv = Environment.GetEnvironmentVariable("FW_SKIP_PDF_TEST"); + if (!string.IsNullOrWhiteSpace(skipEnv) && IsTruthy(skipEnv)) + { + reason = "PDF Test skipping: FW_SKIP_PDF_TEST requested skip."; + return true; + } + + reason = string.Empty; + return false; + } + + private static bool IsTruthy(string? value) + { + if (value is null) + return false; + + return value.Equals("1", StringComparison.OrdinalIgnoreCase) + || value.Equals("true", StringComparison.OrdinalIgnoreCase) + || value.Equals("yes", StringComparison.OrdinalIgnoreCase) + || value.Equals("on", StringComparison.OrdinalIgnoreCase); + } + } +} diff --git a/roles/tests-unit/files/FWO.Test/IPAddressRangeComparerTest.cs b/roles/tests-unit/files/FWO.Test/IPAddressRangeComparerTest.cs new file mode 100644 index 0000000000..0474446642 --- /dev/null +++ b/roles/tests-unit/files/FWO.Test/IPAddressRangeComparerTest.cs @@ -0,0 +1,92 @@ +using System; +using System.Diagnostics; +using System.Linq; +using System.Net; +using System.Numerics; +using NUnit.Framework; +using NetTools; +using FWO.Basics.Comparer; + +namespace FWO.Test +{ + [TestFixture] + public class IPAddressRangeComparerTests + { + [Test] + public void GetIPRangeSizeTest() + { + // ARRANGE + + IPAddressRangeComparer comparer = new(); + + Stopwatch stopwatch; + + int iterations = 1; + + var testCases = new[] + { + // IPv4 little range + // expected result: new BigInteger(255) + new IPAddressRange(IPAddress.Parse("192.168.1.0"), IPAddress.Parse("192.168.1.255")), + + // IPv4 big range + // expected result: new BigInteger(16_777_215) + new IPAddressRange(IPAddress.Parse("10.0.0.0"), IPAddress.Parse("10.255.255.255")), + + // IPv6 little range + // expected result: new BigInteger(1) + new IPAddressRange(IPAddress.Parse("::1"), IPAddress.Parse("::2")), + + // IPv6 medium range + // expected result: new BigInteger(65_535) + new IPAddressRange(IPAddress.Parse("2001:db8::"), IPAddress.Parse("2001:db8::ffff")), + + // IPv6 big range + // expected result: BigInteger.Parse("340282366920938463463374607431768211455") + new IPAddressRange(IPAddress.Parse("::"), IPAddress.Parse("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff")) + }; + + // key: iteration, testcase + // value: result, performance + Dictionary<(int, IPAddressRange), (BigInteger, TimeSpan)> testResults = new(); + + // ACT + + for (int i = 1; i <= iterations; i++) + { + foreach (var range in testCases) + { + // execute method + stopwatch = Stopwatch.StartNew(); + BigInteger result = comparer.GetIPRangeSize(range); + stopwatch.Stop(); + + // save test results + testResults[(i, range)] = (result, stopwatch.Elapsed); + } + } + + // ASSERT + + var testCase1Results = testResults.Where(kvp => kvp.Key.Item2 == testCases[0]); + Assert.That(testCase1Results.Select(kvp => kvp.Value.Item1), + Is.All.EqualTo(new BigInteger(255))); + + var testCase2Results = testResults.Where(kvp => kvp.Key.Item2 == testCases[1]); + Assert.That(testCase2Results.Select(kvp => kvp.Value.Item1), + Is.All.EqualTo(new BigInteger(16_777_215))); + + var testCase3Results = testResults.Where(kvp => kvp.Key.Item2 == testCases[2]); + Assert.That(testCase3Results.Select(kvp => kvp.Value.Item1), + Is.All.EqualTo(new BigInteger(1))); + + var testCase4Results = testResults.Where(kvp => kvp.Key.Item2 == testCases[3]); + Assert.That(testCase4Results.Select(kvp => kvp.Value.Item1), + Is.All.EqualTo(new BigInteger(65_535))); + + var testCase5Results = testResults.Where(kvp => kvp.Key.Item2 == testCases[4]); + Assert.That(testCase5Results.Select(kvp => kvp.Value.Item1), + Is.All.EqualTo(BigInteger.Parse("340282366920938463463374607431768211455"))); + } + } +} diff --git a/roles/tests-unit/files/FWO.Test/IPOperationsTest.cs b/roles/tests-unit/files/FWO.Test/IPOperationsTest.cs new file mode 100644 index 0000000000..0b555d3632 --- /dev/null +++ b/roles/tests-unit/files/FWO.Test/IPOperationsTest.cs @@ -0,0 +1,541 @@ +using System.Net; +using NetTools; +using NUnit.Framework; +using FWO.Basics; +using NUnit.Framework.Legacy; + +namespace FWO.Test +{ + [TestFixture] + public class IpOperationsTests + { + [Test] + public void SplitIpToRange_Cidr_ReturnsStartEnd() + { + // Arrange + string input = "192.168.1.0/24"; + + // Act + (string start, string end) = IpOperations.SplitIpToRange(input); + + // Assert + ClassicAssert.AreEqual("192.168.1.0", start); + ClassicAssert.AreEqual("192.168.1.255", end); + } + + [Test] + public void SplitIpToRange_Range_ReturnsStartEnd() + { + // Arrange + string input = "10.0.0.5-10.0.0.9"; + + // Act + (string start, string end) = IpOperations.SplitIpToRange(input); + + // Assert + ClassicAssert.AreEqual("10.0.0.5", start); + ClassicAssert.AreEqual("10.0.0.9", end); + } + + [Test] + public void SplitIpToRange_Single_ReturnsSame() + { + // Arrange + string input = "8.8.8.8"; + + // Act + (string start, string end) = IpOperations.SplitIpToRange(input); + + // Assert + ClassicAssert.AreEqual("8.8.8.8", start); + ClassicAssert.AreEqual("8.8.8.8", end); + } + + [Test] + public void TryParseIPStringToRange_ValidIPv4_StrictTrue_Succeeds() + { + // Arrange + string input = "192.168.0.1"; + + // Act + bool ok = IpOperations.TryParseIPStringToRange(input, out (string start, string end) range, strictv4Parse: true); + + // Assert + Assert.That(ok); + ClassicAssert.AreEqual("192.168.0.1", range.start); + ClassicAssert.AreEqual("192.168.0.1", range.end); + } + + [Test] + public void TryParseIPStringToRange_InvalidIPv4_StrictTrue_Fails() + { + // Arrange + string input = "999.168.0.1"; + + // Act + bool ok = IpOperations.TryParseIPStringToRange(input, out (string start, string end) _, strictv4Parse: true); + + // Assert + Assert.That(!ok); + } + + [Test] + public void TryParseIPString_StringTuple_Succeeds() + { + // Arrange + string input = "10.1.2.3-10.1.2.10"; + + // Act + bool ok = IpOperations.TryParseIPString(input, out (string, string) tuple); + + // Assert + Assert.That(ok); + ClassicAssert.AreEqual("10.1.2.3", tuple.Item1); + ClassicAssert.AreEqual("10.1.2.10", tuple.Item2); + } + + [Test] + public void TryParseIPString_FullRangeIPv4_Succeeds() + { + // Arrange + string input = "0.0.0.0/0"; + + // Act + bool ok = IpOperations.TryParseIPString(input, out IPAddressRange? range); + + // Assert + Assert.That(ok); + ClassicAssert.AreEqual("0.0.0.0", range!.Begin.ToString()); + ClassicAssert.AreEqual("255.255.255.255", range.End.ToString()); + } + + [Test] + public void TryParseIPString_IPAddressRange_Succeeds() + { + // Arrange + string input = "172.16.0.0/30"; + + // Act + bool ok = IpOperations.TryParseIPString(input, out IPAddressRange? range); + + // Assert + Assert.That(ok); + ClassicAssert.AreEqual("172.16.0.0", range!.Begin.ToString()); + ClassicAssert.AreEqual("172.16.0.3", range.End.ToString()); + } + + [Test] + public void TryParseIPString_IPAddressTuple_Succeeds() + { + // Arrange + string input = "192.0.2.1-192.0.2.5"; + + // Act + bool ok = IpOperations.TryParseIPString(input, out (IPAddress, IPAddress) tup); + + // Assert + Assert.That(ok); + ClassicAssert.AreEqual(IPAddress.Parse("192.0.2.1"), tup!.Item1); + ClassicAssert.AreEqual(IPAddress.Parse("192.0.2.5"), tup.Item2); + } + + [Test] + public void TryParseIPString_UnsupportedType_Fails() + { + // Arrange + string input = "192.168.0.1"; + + // Act + bool ok = IpOperations.TryParseIPString(input, out int _); + + // Assert + Assert.That(!ok); + } + + [Test] + public void GetObjectType_HostAndNetworkAndRange_Succeeds() + { + // Arrange + string host = "192.168.0.10"; + string network = "192.168.0.0/24"; + string rStart = "10.0.0.1"; + string rEnd = "10.0.0.5"; + + // Act + string hostType = IpOperations.GetObjectType(host, ""); + string networkType = IpOperations.GetObjectType(network, ""); + string rangeType = IpOperations.GetObjectType(rStart, rEnd); + + // Assert + ClassicAssert.AreEqual(ObjectType.Host, hostType); + ClassicAssert.AreEqual(ObjectType.Network, networkType); + ClassicAssert.AreEqual(ObjectType.IPRange, rangeType); + } + + [Test] + public void RangeOverlapExists_Overlapping_ReturnsTrue() + { + // Arrange + IPAddressRange a = IPAddressRange.Parse("10.0.0.1-10.0.0.10"); + IPAddressRange b = IPAddressRange.Parse("10.0.0.5-10.0.0.20"); + + // Act + bool result = IpOperations.RangeOverlapExists(a, b); + + // Assert + Assert.That(result); + } + + [Test] + public void RangeOverlapExists_NonOverlapping_ReturnsFalse() + { + // Arrange + IPAddressRange a = IPAddressRange.Parse("10.0.0.1-10.0.0.10"); + IPAddressRange b = IPAddressRange.Parse("10.0.0.20-10.0.0.30"); + + // Act + bool result = IpOperations.RangeOverlapExists(a, b); + + // Assert + Assert.That(!result); + } + + [Test] + public void IpToUint_And_Back_Roundtrip() + { + // Arrange + IPAddress ip = IPAddress.Parse("1.2.3.4"); + + // Act + uint u = IpOperations.IpToUint(ip); + IPAddress back = IpOperations.UintToIp(u); + + // Assert + ClassicAssert.AreEqual(ip, back); + } + + [Test] + public void CheckOverlap_MixedFamilies_ReturnsFalse() + { + // Arrange + string left = "192.168.0.0/24"; + string right = "2001:db8::/32"; + + // Act + bool result = IpOperations.CheckOverlap(left, right); + + // Assert + Assert.That(!result); + } + + [Test] + public void CheckOverlap_OverlappingStrings_ReturnsTrue() + { + // Arrange + string left = "10.0.0.0/25"; + string right = "10.0.0.64-10.0.0.200"; + + // Act + bool result = IpOperations.CheckOverlap(left, right); + + // Assert + Assert.That(result); + } + + [Test] + public void CheckOverlap_NonOverlappingStrings_ReturnsFalse() + { + // Arrange + string left = "10.0.1.0/24"; + string right = "10.0.2.0/24"; + + // Act + bool result = IpOperations.CheckOverlap(left, right); + + // Assert + Assert.That(!result); + } + + [Test] + public void GetIPAdressRange_FullRangeIPv4_Succeeds() + { + // Arrange + string input = "0.0.0.0/0"; + + // Act + IPAddressRange r = IpOperations.GetIPAdressRange(input); + + // Assert + ClassicAssert.AreEqual("0.0.0.0", r.Begin.ToString()); + ClassicAssert.AreEqual("255.255.255.255", r.End.ToString()); + } + + [Test] + public void GetIPAdressRange_Cidr_Succeeds() + { + // Arrange + string input = "192.168.2.0/30"; + + // Act + IPAddressRange r = IpOperations.GetIPAdressRange(input); + + // Assert + ClassicAssert.AreEqual("192.168.2.0", r.Begin.ToString()); + ClassicAssert.AreEqual("192.168.2.3", r.End.ToString()); + } + + [Test] + public void GetIPAdressRange_Range_Succeeds() + { + // Arrange + string input = "10.10.10.1-10.10.10.9"; + + // Act + IPAddressRange r = IpOperations.GetIPAdressRange(input); + + // Assert + ClassicAssert.AreEqual("10.10.10.1", r.Begin.ToString()); + ClassicAssert.AreEqual("10.10.10.9", r.End.ToString()); + } + + [Test] + public void GetIPAdressRange_Range_Fails_InvalidRange() + { + // Arrange + string input = "10.0.0.235-10.0.0.43"; + + // Act + TestDelegate action = () => IpOperations.GetIPAdressRange(input); + + // Assert + Assert.Throws(action); + } + + [Test] + public void GetIPAdressRange_Single_Succeeds() + { + // Arrange + string input = "8.8.4.4"; + + // Act + IPAddressRange r = IpOperations.GetIPAdressRange(input); + + // Assert + ClassicAssert.AreEqual("8.8.4.4", r.Begin.ToString()); + ClassicAssert.AreEqual("8.8.4.4", r.End.ToString()); + } + + [Test] + public void ToDotNotation_ExactNetworkIPv4_Succeeds() + { + // Arrange + string start = "192.168.1.0"; + string end = "192.168.1.255"; + + // Act + string s = IpOperations.ToDotNotation(start, end); + + // Assert + ClassicAssert.AreEqual("192.168.1.0/255.255.255.0", s); + } + + [Test] + public void ToDotNotation_SingleIP__Succeeds() + { + // Arrange + string start = "10.0.0.5"; + string end = "10.0.0.5"; + + // Act + string s = IpOperations.ToDotNotation(start, end); + + // Assert + ClassicAssert.AreEqual("10.0.0.5/255.255.255.255", s); + } + + [Test] + public void ToDotNotation_MismatchedFamilies_Throws() + { + // Arrange + string start = "10.0.0.1"; + string end = "2001:db8::1"; + + // Act & Assert + Assert.Throws(() => IpOperations.ToDotNotation(start, end)); + } + + [Test] + public void CompareIpValues_Basic_Works() + { + // Arrange + IPAddress a = IPAddress.Parse("10.0.0.1"); + IPAddress b = IPAddress.Parse("10.0.0.2"); + + // Act + int ab = IpOperations.CompareIpValues(a, b); + int ba = IpOperations.CompareIpValues(b, a); + int aa = IpOperations.CompareIpValues(a, IPAddress.Parse("10.0.0.1")); + + // Assert + Assert.That(ab < 0); + Assert.That(ba > 0); + ClassicAssert.AreEqual(0, aa); + } + + [Test] + public void CompareIpFamilies_V4AndV6_V4BeforeV6() + { + // Arrange + IPAddress v4 = IPAddress.Parse("192.0.2.1"); + IPAddress v6 = IPAddress.Parse("2001:db8::1"); + + // Act + int v4v6 = IpOperations.CompareIpFamilies(v4, v6); + int v6v4 = IpOperations.CompareIpFamilies(v6, v4); + int v4v4 = IpOperations.CompareIpFamilies(v4, IPAddress.Parse("198.51.100.2")); + + // Assert + Assert.That(v4v6 < 0); + Assert.That(v6v4 > 0); + ClassicAssert.AreEqual(0, v4v4); + } + + [Test] + public void Subtract_IPAddressRangeList_Succeeds() + { + // Arrange + IPAddressRange source = new IPAddressRange(IPAddress.Parse("10.0.0.0"), IPAddress.Parse("10.0.0.255")); + List subtract = new List + { + new IPAddressRange(IPAddress.Parse("10.0.0.10"), IPAddress.Parse("10.0.0.20")) + }; + + // Act + List result = IpOperations.Subtract(source, subtract); + + // Assert + ClassicAssert.AreEqual(2, result.Count); + ClassicAssert.AreEqual("10.0.0.0", result[0].Begin.ToString()); + ClassicAssert.AreEqual("10.0.0.9", result[0].End.ToString()); + ClassicAssert.AreEqual("10.0.0.21", result[1].Begin.ToString()); + ClassicAssert.AreEqual("10.0.0.255", result[1].End.ToString()); + } + + [Test] + public void ToMergedRanges_AdjacentNetworks_Succeeds() + { + // Arrange + List nets = new List(); + if (IPNetwork2.TryParseRange("192.168.10.0-192.168.10.127", out IEnumerable? a)) nets.AddRange(a); + if (IPNetwork2.TryParseRange("192.168.10.128-192.168.10.255", out IEnumerable? b)) nets.AddRange(b); + + // Act + List merged = IpOperations.ToMergedRanges(nets); + + // Assert + ClassicAssert.AreEqual(1, merged.Count); + ClassicAssert.AreEqual("192.168.10.0", merged[0].Begin.ToString()); + ClassicAssert.AreEqual("192.168.10.255", merged[0].End.ToString()); + } + + [Test] + public void GetIntersection_OverlapExists_ReturnsIntersection() + { + var rangeA = new IPAddressRange(IPAddress.Parse("192.168.1.0"), IPAddress.Parse("192.168.1.255")); + var rangeB = new IPAddressRange(IPAddress.Parse("192.168.1.128"), IPAddress.Parse("192.168.2.0")); + + var intersection = IpOperations.GetIntersection(rangeA, rangeB); + + Assert.IsNotNull(intersection); + Assert.AreEqual("192.168.1.128", intersection!.Begin.ToString()); + Assert.AreEqual("192.168.1.255", intersection!.End.ToString()); + } + + [Test] + public void GetIntersection_SwappedRanges_ReturnsSameIntersection() + { + var rangeA = new IPAddressRange(IPAddress.Parse("192.168.1.128"), IPAddress.Parse("192.168.2.0")); + var rangeB = new IPAddressRange(IPAddress.Parse("192.168.1.0"), IPAddress.Parse("192.168.1.255")); + + var intersection = IpOperations.GetIntersection(rangeA, rangeB); + + Assert.IsNotNull(intersection); + Assert.AreEqual("192.168.1.128", intersection!.Begin.ToString()); + Assert.AreEqual("192.168.1.255", intersection.End.ToString()); + } + + [Test] + public void GetIntersection_TouchingRanges_ReturnsSingleIp() + { + var rangeA = new IPAddressRange(IPAddress.Parse("192.168.1.0"), IPAddress.Parse("192.168.1.10")); + var rangeB = new IPAddressRange(IPAddress.Parse("192.168.1.10"), IPAddress.Parse("192.168.1.20")); + + var intersection = IpOperations.GetIntersection(rangeA, rangeB); + + Assert.IsNotNull(intersection); + Assert.AreEqual("192.168.1.10", intersection!.Begin.ToString()); + Assert.AreEqual("192.168.1.10", intersection.End.ToString()); + } + + [Test] + public void GetIntersection_OneInsideAnother_ReturnsInnerRange() + { + var rangeA = new IPAddressRange(IPAddress.Parse("192.168.1.0"), IPAddress.Parse("192.168.1.255")); + var rangeB = new IPAddressRange(IPAddress.Parse("192.168.1.50"), IPAddress.Parse("192.168.1.100")); + + var intersection = IpOperations.GetIntersection(rangeA, rangeB); + + Assert.IsNotNull(intersection); + Assert.AreEqual("192.168.1.50", intersection!.Begin.ToString()); + Assert.AreEqual("192.168.1.100", intersection.End.ToString()); + } + + [Test] + public void GetIntersection_NoOverlap_ReturnsNull() + { + var rangeA = new IPAddressRange(IPAddress.Parse("10.0.0.0"), IPAddress.Parse("10.0.0.255")); + var rangeB = new IPAddressRange(IPAddress.Parse("192.168.1.0"), IPAddress.Parse("192.168.1.255")); + + var intersection = IpOperations.GetIntersection(rangeA, rangeB); + + Assert.IsNull(intersection); + } + + [Test] + public void GetIntersection_IPv6Overlap_ReturnsIntersection() + { + var rangeA = new IPAddressRange(IPAddress.Parse("2001:db8::1"), IPAddress.Parse("2001:db8::ff")); + var rangeB = new IPAddressRange(IPAddress.Parse("2001:db8::80"), IPAddress.Parse("2001:db8::1ff")); + + var intersection = IpOperations.GetIntersection(rangeA, rangeB); + + Assert.IsNotNull(intersection); + Assert.AreEqual("2001:db8::80", intersection!.Begin.ToString()); + Assert.AreEqual("2001:db8::ff", intersection!.End.ToString()); + } + + [Test] + public void GetIntersection_MixedIpVersions_ReturnsNull() + { + var rangeA = new IPAddressRange(IPAddress.Parse("192.168.1.0"), IPAddress.Parse("192.168.1.255")); + var rangeB = new IPAddressRange(IPAddress.Parse("2001:db8::1"), IPAddress.Parse("2001:db8::ff")); + + var intersection = IpOperations.GetIntersection(rangeA, rangeB); + + Assert.IsNull(intersection); + } + + [Test] + public void GetIntersection_SmallIPv6Range_WorksCorrectly() + { + var rangeA = new IPAddressRange(IPAddress.Parse("2001:db8::1"), IPAddress.Parse("2001:db8::2")); + var rangeB = new IPAddressRange(IPAddress.Parse("2001:db8::2"), IPAddress.Parse("2001:db8::3")); + + var intersection = IpOperations.GetIntersection(rangeA, rangeB); + + Assert.IsNotNull(intersection); + Assert.AreEqual("2001:db8::2", intersection!.Begin.ToString()); + Assert.AreEqual("2001:db8::2", intersection.End.ToString()); + } + } +} diff --git a/roles/tests-unit/files/FWO.Test/IPOverlapTest.cs b/roles/tests-unit/files/FWO.Test/IPOverlapTest.cs new file mode 100644 index 0000000000..961bc14960 --- /dev/null +++ b/roles/tests-unit/files/FWO.Test/IPOverlapTest.cs @@ -0,0 +1,66 @@ +using NUnit.Framework; +using FWO.Basics; + +namespace FWO.Test +{ + [TestFixture] + [Parallelizable] + internal class IPOverlapTest + { + [Test] + [Parallelizable] + public void TestIPOverlaps() + { + List areaIPs = [ + "2001:db8::1-2001:db8::4", + "1.2.3.0/24", + "2.2.2.2", + "3.3.3.3-3.3.3.4", + "10.121.254.128/27", + "172.0.0.0/7", + ]; + + List ipsShouldOverlap = [ + "2001:db8::3", + "1.2.3.0/24", + "2.2.2.2", + "3.3.3.3-3.3.3.4", + "10.121.254.128/27", + "172.0.0.0/7", + ]; + + List ipsShouldNotOverlap = [ + "2001:db8::", + "1.2.2.0/24", + "1.1.1.1", + "2.1.1.1-2.1.1.4", + "9.0.254.128/27", + "171.0.0.0/7", + ]; + + int ipsThatOverlapped = 0; + + foreach (var subnet in areaIPs) + { + foreach (var ipOverlap in ipsShouldOverlap) + { + if (subnet.CheckOverlap(ipOverlap)) + { + ipsThatOverlapped++; + } + } + + foreach (var ipNotOverlap in ipsShouldNotOverlap) + { + if (subnet.CheckOverlap(ipNotOverlap)) + { + ipsThatOverlapped++; + } + } + } + + Assert.That(Is.Equals(ipsThatOverlapped, ipsShouldOverlap.Count)); + } + + } +} diff --git a/roles/tests-unit/files/FWO.Test/JwtClaimParserTest.cs b/roles/tests-unit/files/FWO.Test/JwtClaimParserTest.cs new file mode 100644 index 0000000000..fbdf8e013b --- /dev/null +++ b/roles/tests-unit/files/FWO.Test/JwtClaimParserTest.cs @@ -0,0 +1,50 @@ +using FWO.Ui.Auth; +using NUnit.Framework; +using System.Security.Claims; + +namespace FWO.Test +{ + [TestFixture] + public class JwtClaimParserTest + { + [Test] + public void ExtractStringClaimValuesParsesJsonArrayClaims() + { + List claims = + [ + new("x-hasura-allowed-roles", "[\"admin\",\"modeller\"]") + ]; + + List roles = JwtClaimParser.ExtractStringClaimValues(claims, "x-hasura-allowed-roles"); + + Assert.That(roles, Is.EquivalentTo(new[] { "admin", "modeller" })); + } + + [Test] + public void ExtractIntClaimValuesParsesBraceAndJsonArrayFormats() + { + List claims = + [ + new("x-hasura-editable-owners", "{ 1,2, 3 }"), + new("x-hasura-editable-owners", "[4,5]") + ]; + + List owners = JwtClaimParser.ExtractIntClaimValues(claims, "x-hasura-editable-owners"); + + Assert.That(owners, Is.EquivalentTo(new[] { 1, 2, 3, 4, 5 })); + } + + [Test] + public void ExtractStringClaimValuesAcceptsNamespacedClaimTypes() + { + List claims = + [ + new("https://hasura.io/jwt/claims/x-hasura-allowed-roles", "[\"auditor\",\"recertifier\"]") + ]; + + List roles = JwtClaimParser.ExtractStringClaimValues(claims, "x-hasura-allowed-roles"); + + Assert.That(roles, Is.EquivalentTo(new[] { "auditor", "recertifier" })); + } + } +} diff --git a/roles/tests-unit/files/FWO.Test/JwtWriterClaimsTest.cs b/roles/tests-unit/files/FWO.Test/JwtWriterClaimsTest.cs new file mode 100644 index 0000000000..723d4bf9bb --- /dev/null +++ b/roles/tests-unit/files/FWO.Test/JwtWriterClaimsTest.cs @@ -0,0 +1,56 @@ +using FWO.Data; +using FWO.Middleware.Server; +using NUnit.Framework; +using System.Reflection; +using System.Security.Claims; + +namespace FWO.Test +{ + [TestFixture] + public class JwtWriterClaimsTest + { + [Test] + public void SetClaimsAddsVisibleScopeClaimsWhenTenantIsMissing() + { + UiUser user = new() + { + Name = "test-user", + Roles = ["reporter"] + }; + + ClaimsIdentity claimsIdentity = InvokeSetClaims(user); + + Assert.That(claimsIdentity.FindFirst("x-hasura-visible-managements")?.Value, Is.EqualTo("{}")); + Assert.That(claimsIdentity.FindFirst("x-hasura-visible-devices")?.Value, Is.EqualTo("{}")); + } + + [Test] + public void SetClaimsAddsVisibleScopeClaimsFromTenant() + { + UiUser user = new() + { + Name = "test-user", + Roles = ["reporter"], + Tenant = new Tenant + { + Id = 7, + VisibleManagementIds = [3, 9], + VisibleGatewayIds = [5] + } + }; + + ClaimsIdentity claimsIdentity = InvokeSetClaims(user); + + Assert.That(claimsIdentity.FindFirst("x-hasura-tenant-id")?.Value, Is.EqualTo("7")); + Assert.That(claimsIdentity.FindFirst("x-hasura-visible-managements")?.Value, Is.EqualTo("{3,9}")); + Assert.That(claimsIdentity.FindFirst("x-hasura-visible-devices")?.Value, Is.EqualTo("{5}")); + } + + private static ClaimsIdentity InvokeSetClaims(UiUser user) + { + MethodInfo? method = typeof(JwtWriter).GetMethod("SetClaims", BindingFlags.NonPublic | BindingFlags.Static); + Assert.That(method, Is.Not.Null); + return (ClaimsIdentity)(method!.Invoke(null, [user]) ?? throw new AssertionException("SetClaims returned null.")); + } + } +} diff --git a/roles/tests-unit/files/FWO.Test/LdapBasicTest.cs b/roles/tests-unit/files/FWO.Test/LdapBasicTest.cs new file mode 100644 index 0000000000..df60f49c6e --- /dev/null +++ b/roles/tests-unit/files/FWO.Test/LdapBasicTest.cs @@ -0,0 +1,46 @@ +using FWO.Middleware.Server; +using Novell.Directory.Ldap; +using NUnit.Framework; +using System.Reflection; + +namespace FWO.Test +{ + [TestFixture] + internal class LdapBasicTest + { + [TestCase(true, LdapModification.Add, false)] + [TestCase(false, LdapModification.Add, true)] + [TestCase(true, LdapModification.Delete, true)] + [TestCase(false, LdapModification.Delete, false)] + public void ShouldModifyMembershipHandlesAddAndDelete(bool memberExists, int modification, bool expected) + { + bool result = Ldap.ShouldModifyMembership(memberExists, modification); + + Assert.That(result, Is.EqualTo(expected)); + } + + [TestCase(@"cn=Müller \2C (xy),ou=users,dc=example,dc=com", @"cn=Müller \, (xy),ou=users,dc=example,dc=com")] + [TestCase(@"cn=M\C3\BCller \2C (xy),ou=users,dc=example,dc=com", @"cn=Müller \, (xy),ou=users,dc=example,dc=com")] + [TestCase(@"CN=User\, Example,OU=Users,DC=Example,DC=COM", @"cn=User\2C Example,ou=users,dc=example,dc=com")] + public void NormalizeDnForComparison_TreatsEquivalentEscapedDnsAsEqual(string leftDn, string rightDn) + { + string normalizedLeft = Ldap.NormalizeDnForComparison(leftDn); + string normalizedRight = Ldap.NormalizeDnForComparison(rightDn); + + Assert.That(normalizedLeft, Is.EqualTo(normalizedRight)); + } + + [Test] + public void EnableReferralFollowing_SetsConnectionConstraint() + { + LdapConnection connection = new(); + MethodInfo? method = typeof(Ldap).GetMethod("EnableReferralFollowing", BindingFlags.NonPublic | BindingFlags.Static); + + Assert.That(method, Is.Not.Null); + + method!.Invoke(null, [connection]); + + Assert.That(connection.Constraints.ReferralFollowing, Is.True); + } + } +} diff --git a/roles/tests-unit/files/FWO.Test/LdapMembershipTest.cs b/roles/tests-unit/files/FWO.Test/LdapMembershipTest.cs new file mode 100644 index 0000000000..bb978fc95d --- /dev/null +++ b/roles/tests-unit/files/FWO.Test/LdapMembershipTest.cs @@ -0,0 +1,119 @@ +using FWO.Middleware.Server; +using Novell.Directory.Ldap; +using NUnit.Framework; + +namespace FWO.Test +{ + [TestFixture] + public class LdapMembershipTest + { + [Test] + public void GetGroupsIncludesWritePathMemberships() + { + Ldap ldap = new() + { + GroupSearchPath = "ou=search,dc=example,dc=com", + GroupWritePath = "ou=write,dc=example,dc=com" + }; + + LdapAttributeSet attrs = new(); + attrs.Add(new LdapAttribute("memberOf", new[] + { + "cn=AppOwners,ou=write,dc=example,dc=com" + })); + LdapEntry user = new("cn=test,dc=example,dc=com", attrs); + + var groups = ldap.GetGroups(user); + + Assert.That(groups, Has.Count.EqualTo(1)); + Assert.That(groups[0], Is.EqualTo("cn=AppOwners,ou=write,dc=example,dc=com")); + } + + [Test] + public void GetGroupsIncludesSearchPathMemberships() + { + Ldap ldap = new() + { + GroupSearchPath = "ou=search,dc=example,dc=com", + GroupWritePath = "ou=write,dc=example,dc=com" + }; + + LdapAttributeSet attrs = new(); + attrs.Add(new LdapAttribute("memberOf", new[] + { + "cn=AppOwners,ou=search,dc=example,dc=com" + })); + LdapEntry user = new("cn=test,dc=example,dc=com", attrs); + + var groups = ldap.GetGroups(user); + + Assert.That(groups, Has.Count.EqualTo(1)); + Assert.That(groups[0], Is.EqualTo("cn=AppOwners,ou=search,dc=example,dc=com")); + } + + [Test] + public void GetGroupsIgnoresUnrelatedMemberships() + { + Ldap ldap = new() + { + GroupSearchPath = "ou=search,dc=example,dc=com", + GroupWritePath = "ou=write,dc=example,dc=com" + }; + + LdapAttributeSet attrs = new(); + attrs.Add(new LdapAttribute("memberOf", new[] + { + "cn=OtherGroup,ou=other,dc=example,dc=com" + })); + LdapEntry user = new("cn=test,dc=example,dc=com", attrs); + + var groups = ldap.GetGroups(user); + + Assert.That(groups, Is.Empty); + } + + [Test] + public void HasGroupHandlingUsesWritePathFallback() + { + Ldap ldap = new() + { + GroupSearchPath = "", + GroupWritePath = "ou=write,dc=example,dc=com" + }; + + Assert.That(ldap.HasGroupHandling(), Is.True); + } + + [Test] + public void BuildGroupDnsCreatesDnsFromNames() + { + var dns = Ldap.BuildGroupDns(new[] { "AppOwners", "SecTeam" }, "ou=groups,dc=example,dc=com"); + + Assert.That(dns, Has.Count.EqualTo(2)); + Assert.That(dns, Does.Contain("cn=AppOwners,ou=groups,dc=example,dc=com")); + Assert.That(dns, Does.Contain("cn=SecTeam,ou=groups,dc=example,dc=com")); + } + + [Test] + public void BuildGroupDnsKeepsExistingDnsAndDeduplicates() + { + var dns = Ldap.BuildGroupDns(new[] + { + "AppOwners", + "cn=AppOwners,ou=groups,dc=example,dc=com", + "APPOWNERS" + }, "ou=groups,dc=example,dc=com"); + + Assert.That(dns, Has.Count.EqualTo(1)); + Assert.That(dns, Does.Contain("cn=AppOwners,ou=groups,dc=example,dc=com")); + } + + [Test] + public void BuildGroupDnsReturnsEmptyWhenPathMissing() + { + var dns = Ldap.BuildGroupDns(new[] { "AppOwners" }, ""); + + Assert.That(dns, Is.Empty); + } + } +} diff --git a/roles/tests-unit/files/FWO.Test/LockTest.cs b/roles/tests-unit/files/FWO.Test/LockTest.cs new file mode 100644 index 0000000000..70a5c4570b --- /dev/null +++ b/roles/tests-unit/files/FWO.Test/LockTest.cs @@ -0,0 +1,141 @@ +using FWO.Logging; +using NUnit.Framework; +using NUnit.Framework.Legacy; +using System; +using System.Reflection; + +namespace FWO.Test +{ + [TestFixture] + [Parallelizable] + public class LockTest + { + private string lockFilePath = $"/var/fworch/lock/{Assembly.GetEntryAssembly()?.GetName().Name}_log.lock"; + private static Random random = new Random(); + + [SetUp] + public async Task SetUp() + { + await ExecuteFileAction(() => + { + if (File.Exists(lockFilePath)) + { + File.Delete(lockFilePath); + } + return Task.CompletedTask; + }); + + // Implicitly call static constructor so backround lock process is started + Log.WriteInfo("Startup", "Starting Lock Tests..."); + Log.WriteInfo("Startup", $"LockFilePath is: {lockFilePath}"); + } + + [TearDown] + public async Task TearDown() + { + await ExecuteFileAction(() => + { + if (File.Exists(lockFilePath)) + { + File.Delete(lockFilePath); + } + return Task.CompletedTask; + }); + } + + [Test] + public async Task LogLock() + { + // Request lock + await ExecuteFileAction(async () => + { + using (var writer = new StreamWriter(lockFilePath)) + { + await writer.WriteLineAsync("REQUESTED"); + } + }); + + await Task.Delay(2000); + + // Assure lock is granted after request + await ExecuteFileAction(async () => + { + using (var reader = new StreamReader(lockFilePath)) + { + Assert.That((await reader.ReadToEndAsync()).Trim().EndsWith("GRANTED")); + } + }); + + // Assure write is NOT possible after lock was granted + Task logWriter = Task.Run(() => + { + Log.WriteDebug("TEST_TITLE", "TEST_TEXT"); + }); + + await Task.Delay(500); + + Assert.That(logWriter.IsCompleted, Is.False); + + // Release lock + await ExecuteFileAction(async () => + { + using (var writer = new StreamWriter(lockFilePath)) + { + await writer.WriteLineAsync("RELEASED"); + } + }); + + await Task.Delay(2000); + + // Assure write IS possible after lock was released + Assert.That(logWriter.IsCompletedSuccessfully, Is.True); + + // Request lock + await ExecuteFileAction(async () => + { + using (var writer = new StreamWriter(lockFilePath)) + { + await writer.WriteLineAsync("REQUESTED"); + } + }); + + await Task.Delay(12_000); + + // If not release in time make sure that the lock will be forcefully released + await ExecuteFileAction(async () => + { + using (var reader = new StreamReader(lockFilePath)) + { + Assert.That((await reader.ReadToEndAsync()).Trim().EndsWith("FORCEFULLY RELEASED")); + } + }); + } + + private static async Task ExecuteFileAction(Func action) + { + bool success = false; + int maxRetryAttempts = 50; + int retryCount = 0; + + // Handle IO Exception like file blocking from another process by retrying with a random delay + while (!success && retryCount < maxRetryAttempts) + { + try + { + await action(); + success = true; + } + catch (IOException) + { + retryCount++; + } + await Task.Delay(random.Next(50, 100)); + } + + if (!success) + { + Assert.Fail($"Lock file access failed after {maxRetryAttempts} retries."); + } + } + } +} diff --git a/roles/tests-unit/files/FWO.Test/LogTest.cs b/roles/tests-unit/files/FWO.Test/LogTest.cs new file mode 100644 index 0000000000..ad32eff581 --- /dev/null +++ b/roles/tests-unit/files/FWO.Test/LogTest.cs @@ -0,0 +1,79 @@ +using FWO.Logging; +using NUnit.Framework; + +namespace FWO.Test +{ + [TestFixture] + [NonParallelizable] + internal class LogTest + { + [Test] + public void WriteAudit_PreservesLdapDnCharacters() + { + const string userDn = "CN=Jane Doe,OU=Firewall Team,DC=example,DC=com"; + using StringWriter logOutput = new(); + TextWriter originalConsoleOut = Console.Out; + + try + { + Console.SetOut(logOutput); + + Log.WriteAudit("LDAP", "Testing DN logging", "jane.doe", userDn, false); + + string writtenLog = logOutput.ToString(); + Assert.That(writtenLog, Does.Contain(userDn)); + Assert.That(writtenLog, Does.Contain("(DN: CN=Jane Doe,OU=Firewall Team,DC=example,DC=com)")); + } + finally + { + Console.SetOut(originalConsoleOut); + } + } + + [Test] + public void WriteInfo_StripsControlCharactersButKeepsMeaningfulPunctuation() + { + const string logText = "User\tCN=Jane Doe,\u001BOU=Firewall Team,DC=example,DC=com\r\nnext\u0000"; + using StringWriter logOutput = new(); + TextWriter originalConsoleOut = Console.Out; + + try + { + Console.SetOut(logOutput); + + Log.WriteInfo("LDAP", logText); + + string writtenLog = logOutput.ToString().TrimEnd('\r', '\n'); + Assert.That(writtenLog, Does.Contain("User CN=Jane Doe,OU=Firewall Team,DC=example,DC=com next")); + Assert.That(writtenLog.Any(char.IsControl), Is.False); + } + finally + { + Console.SetOut(originalConsoleOut); + } + } + + [Test] + public void WriteInfo_StripsInvisibleUnicodeFormatCharacters() + { + const string logText = "prefix\u200B\u200D\u202A\u2066CN=Jane Doe,OU=Firewall Team,DC=example,DC=com\u2069suffix"; + using StringWriter logOutput = new(); + TextWriter originalConsoleOut = Console.Out; + + try + { + Console.SetOut(logOutput); + + Log.WriteInfo("LDAP", logText); + + string writtenLog = logOutput.ToString().TrimEnd('\r', '\n'); + Assert.That(writtenLog, Does.Contain("prefixCN=Jane Doe,OU=Firewall Team,DC=example,DC=comsuffix")); + Assert.That(writtenLog.Any(ch => char.GetUnicodeCategory(ch) == System.Globalization.UnicodeCategory.Format), Is.False); + } + finally + { + Console.SetOut(originalConsoleOut); + } + } + } +} diff --git a/roles/tests-unit/files/FWO.Test/ManagedIdStringTest.cs b/roles/tests-unit/files/FWO.Test/ManagedIdStringTest.cs new file mode 100644 index 0000000000..010783ddaf --- /dev/null +++ b/roles/tests-unit/files/FWO.Test/ManagedIdStringTest.cs @@ -0,0 +1,144 @@ +using NUnit.Framework; +using NUnit.Framework.Legacy; +using FWO.Basics; +using FWO.Data.Modelling; + +namespace FWO.Test +{ + [TestFixture] + [Parallelizable] + internal class ManagedIdStringTest + { + ModellingManagedIdString IdString1 = new(); + ModellingManagedIdString IdString2 = new("AR5001234-123"); + + static readonly ModellingNamingConvention NamingConvention1 = new() + { + NetworkAreaRequired = true, + UseAppPart = false, + FixedPartLength = 2, + FreePartLength = 5, + NetworkAreaPattern = "NA", + AppRolePattern = "AR" + }; + static readonly ModellingNamingConvention NamingConvention2 = new() + { + NetworkAreaRequired = true, + UseAppPart = true, + FixedPartLength = 4, + FreePartLength = 3, + NetworkAreaPattern = "NA", + AppRolePattern = "AR" + }; + ModellingNamingConvention NamingConvention3 = new() + { + NetworkAreaRequired = true, + UseAppPart = true, + FixedPartLength = 4, + FreePartLength = 3, + NetworkAreaPattern = "", + AppRolePattern = "A" + }; + + + [Test] + public void TestManagedIdStringStartEmpty() + { + ClassicAssert.AreEqual("", IdString1.Whole); + ClassicAssert.AreEqual("", IdString1.FixedPart); + ClassicAssert.AreEqual("", IdString1.AppPart); + ClassicAssert.AreEqual("", IdString1.FreePart); + ClassicAssert.AreEqual("", IdString1.CombinedFixPart); + + IdString1.SetAppPartFromExtId("APP-0001"); + ClassicAssert.AreEqual("", IdString1.Whole); + ClassicAssert.AreEqual("", IdString1.FixedPart); + ClassicAssert.AreEqual("", IdString1.AppPart); + ClassicAssert.AreEqual("", IdString1.Separator); + ClassicAssert.AreEqual("", IdString1.FreePart); + ClassicAssert.AreEqual("", IdString1.CombinedFixPart); + + IdString1.NamingConvention = NamingConvention2; + IdString1.SetAppPartFromExtId("APP-0001"); + ClassicAssert.AreEqual(" 00001-", IdString1.Whole); + ClassicAssert.AreEqual(" ", IdString1.FixedPart); + ClassicAssert.AreEqual("00001-", IdString1.AppPart); + ClassicAssert.AreEqual("-", IdString1.Separator); + ClassicAssert.AreEqual("", IdString1.FreePart); + ClassicAssert.AreEqual(" 00001", IdString1.CombinedFixPart); + + IdString1.FixedPart = "x"; + ClassicAssert.AreEqual("x???00001-", IdString1.Whole); + ClassicAssert.AreEqual("x???", IdString1.FixedPart); + ClassicAssert.AreEqual("00001-", IdString1.AppPart); + ClassicAssert.AreEqual("-", IdString1.Separator); + ClassicAssert.AreEqual("", IdString1.FreePart); + ClassicAssert.AreEqual("x???00001", IdString1.CombinedFixPart); + + IdString1.FixedPart = "muchlonger"; + ClassicAssert.AreEqual("much00001-", IdString1.Whole); + ClassicAssert.AreEqual("much", IdString1.FixedPart); + ClassicAssert.AreEqual("00001-", IdString1.AppPart); + ClassicAssert.AreEqual("-", IdString1.Separator); + ClassicAssert.AreEqual("", IdString1.FreePart); + ClassicAssert.AreEqual("much00001", IdString1.CombinedFixPart); + } + + [Test] + public void TestManagedIdStringPrefilled() + { + ClassicAssert.AreEqual("AR5001234-123", IdString2.Whole); + ClassicAssert.AreEqual("", IdString2.FixedPart); + ClassicAssert.AreEqual("", IdString2.AppPart); + ClassicAssert.AreEqual("", IdString2.Separator); + ClassicAssert.AreEqual("AR5001234-123", IdString2.FreePart); + ClassicAssert.AreEqual("", IdString2.CombinedFixPart); + + IdString2.NamingConvention = NamingConvention1; + ClassicAssert.AreEqual("AR5001234-123", IdString2.Whole); + ClassicAssert.AreEqual("AR", IdString2.FixedPart); + ClassicAssert.AreEqual("", IdString2.AppPart); + ClassicAssert.AreEqual("", IdString2.Separator); + ClassicAssert.AreEqual("5001234-123", IdString2.FreePart); + ClassicAssert.AreEqual("AR", IdString2.CombinedFixPart); + + IdString2.NamingConvention = NamingConvention2; + ClassicAssert.AreEqual("AR5001234-123", IdString2.Whole); + ClassicAssert.AreEqual("AR50", IdString2.FixedPart); + ClassicAssert.AreEqual("01234-", IdString2.AppPart); + ClassicAssert.AreEqual("-", IdString2.Separator); + ClassicAssert.AreEqual("123", IdString2.FreePart); + ClassicAssert.AreEqual("AR5001234", IdString2.CombinedFixPart); + + IdString2.SetAppPartFromExtId("COM-99999"); + ClassicAssert.AreEqual("AR50199999-123", IdString2.Whole); + ClassicAssert.AreEqual("AR50", IdString2.FixedPart); + ClassicAssert.AreEqual("199999-", IdString2.AppPart); + ClassicAssert.AreEqual("-", IdString2.Separator); + ClassicAssert.AreEqual("123", IdString2.FreePart); + ClassicAssert.AreEqual("AR50199999", IdString2.CombinedFixPart); + + IdString2.NamingConvention = new(); + ClassicAssert.AreEqual("AR50199999-123", IdString2.Whole); + ClassicAssert.AreEqual("", IdString2.FixedPart); + ClassicAssert.AreEqual("", IdString2.AppPart); + ClassicAssert.AreEqual("", IdString2.Separator); + ClassicAssert.AreEqual("AR50199999-123", IdString2.FreePart); + ClassicAssert.AreEqual("", IdString2.CombinedFixPart); + } + + [Test] + public void TestReconstructAreaIdString() + { + ClassicAssert.AreEqual("NA", ModellingManagedIdString.ConvertAppRoleToArea("AR5000001", NamingConvention1)); + ClassicAssert.AreEqual("NA91", ModellingManagedIdString.ConvertAppRoleToArea("AR9104106-001", NamingConvention2)); + ClassicAssert.AreEqual("R91", ModellingManagedIdString.ConvertAppRoleToArea("AR9112345-001", NamingConvention3)); + NamingConvention3.NetworkAreaPattern = "XYZ"; + ClassicAssert.AreEqual("XYZR91", ModellingManagedIdString.ConvertAppRoleToArea("AR9112345-001", NamingConvention3)); + NamingConvention3.AppRolePattern = "AR91"; + ClassicAssert.AreEqual("XYZ", ModellingManagedIdString.ConvertAppRoleToArea("AR9112345-001", NamingConvention3)); + NamingConvention3.AppRolePattern = "AR91123"; + ClassicAssert.AreEqual("XYZ", ModellingManagedIdString.ConvertAppRoleToArea("AR9112345-001", NamingConvention3)); + } + } +} diff --git a/roles/tests-unit/files/FWO.Test/ManagementReportTest.cs b/roles/tests-unit/files/FWO.Test/ManagementReportTest.cs new file mode 100644 index 0000000000..690720c431 --- /dev/null +++ b/roles/tests-unit/files/FWO.Test/ManagementReportTest.cs @@ -0,0 +1,61 @@ +using FWO.Data; +using FWO.Data.Report; +using NUnit.Framework; + +namespace FWO.Test +{ + [TestFixture] + public class ManagementReportTest + { + [Test] + public void GetAllRuleIdsReturnsDistinctRuleIds() + { + ManagementReport managementReport = new() + { + Rulebases = + [ + new RulebaseReport + { + Rules = + [ + new Rule { Id = 10 }, + new Rule { Id = 20 } + ] + }, + new RulebaseReport + { + Rules = + [ + new Rule { Id = 20 }, + new Rule { Id = 30 } + ] + } + ] + }; + + var result = managementReport.GetAllRuleIds(); + + Assert.That(result, Is.EquivalentTo(new[] { 10L, 20L, 30L })); + } + + [Test] + public void GetNextRulebaseFindsMatchingRulebase() + { + RulebaseReport first = new() { Id = 10 }; + RulebaseReport second = new() { Id = 20 }; + ManagementReport managementReport = new() + { + Rulebases = + [ + first, + second + ] + }; + RulebaseLink link = new() { NextRulebaseId = 20 }; + + RulebaseReport? result = managementReport.GetNextRulebase(link); + + Assert.That(result, Is.SameAs(second)); + } + } +} diff --git a/roles/tests-unit/files/FWO.Test/Mocks/Mock.cs b/roles/tests-unit/files/FWO.Test/Mocks/Mock.cs new file mode 100644 index 0000000000..9200611e0d --- /dev/null +++ b/roles/tests-unit/files/FWO.Test/Mocks/Mock.cs @@ -0,0 +1,18 @@ +using NSubstitute; + +public abstract class Mock where T : class +{ + public T Sub { get; } + + protected Mock() + { + Sub = Substitute.For(); + Configure(Sub); + } + + protected abstract void Configure(T sub); + + public static implicit operator T(Mock mock) => mock.Sub; + + public T AsSub() => Sub; +} diff --git a/roles/tests-unit/files/FWO.Test/Mocks/MockApiConnection.cs b/roles/tests-unit/files/FWO.Test/Mocks/MockApiConnection.cs new file mode 100644 index 0000000000..75ba22ebdb --- /dev/null +++ b/roles/tests-unit/files/FWO.Test/Mocks/MockApiConnection.cs @@ -0,0 +1,23 @@ +using FWO.Api.Client; +using NSubstitute; + +namespace FWO.Test.Mocks +{ + public class MockApiConnection : Mock + { + public List<(string Query, object Variables)> SentQueries { get; } = new(); + + protected override void Configure(ApiConnection sub) + { + // Log sent queries and variables + + sub.When(x => x.SendQueryAsync(Arg.Any(), Arg.Any())) + .Do(ci => + { + var query = ci.ArgAt(0); + var vars = ci.ArgAt(1); + SentQueries.Add((query, vars)); + }); + } + } +} diff --git a/roles/tests-unit/files/FWO.Test/Mocks/MockLogger.cs b/roles/tests-unit/files/FWO.Test/Mocks/MockLogger.cs new file mode 100644 index 0000000000..731c3eb215 --- /dev/null +++ b/roles/tests-unit/files/FWO.Test/Mocks/MockLogger.cs @@ -0,0 +1,47 @@ +using FWO.Basics.Interfaces; +using NSubstitute; + +namespace FWO.Logging +{ + public class MockLogger : Mock + { + public Dictionary Logmessages = new(); + protected override void Configure(ILogger sub) + { + // Info + + sub.When(x => x.TryWriteInfo(Arg.Any(), Arg.Any(), Arg.Any())) + .Do(ci => + { + Logmessages[DateTime.Now] = $"{ci.ArgAt(0)} - {ci.ArgAt(1)}"; + }); + + // Error + sub.When(x => x.TryWriteError(Arg.Any(), Arg.Any(), Arg.Any())) + .Do(ci => + { + Logmessages[DateTime.Now] = $"{ci.ArgAt(0)} - {ci.ArgAt(1)}"; + }); + + + } + } +} + + +/// +/// +/// public List<(string Query, object Variables)> SentQueries { get; } = new(); + +// protected override void Configure(ApiConnection sub) +// { +// // Log sent queries and variables + +// sub.When(x => x.SendQueryAsync(Arg.Any(), Arg.Any())) +// .Do(ci => +// { +// var query = ci.ArgAt(0); +// var vars = ci.ArgAt(1); +// SentQueries.Add((query, vars)); +// }); +// } diff --git a/roles/tests-unit/files/FWO.Test/Mocks/MockReportCompliance.cs b/roles/tests-unit/files/FWO.Test/Mocks/MockReportCompliance.cs new file mode 100644 index 0000000000..fc29d1401c --- /dev/null +++ b/roles/tests-unit/files/FWO.Test/Mocks/MockReportCompliance.cs @@ -0,0 +1,26 @@ +using FWO.Api.Client; +using FWO.Basics; +using FWO.Config.Api; +using FWO.Data; +using FWO.Data.Report; +using FWO.Report; +using FWO.Report.Filter; + +namespace FWO.Test.Mocks +{ + public class MockReportCompliance : ReportCompliance + { + public MockReportCompliance(DynGraphqlQuery query, UserConfig userConfig, ReportType reportType) : base(query, userConfig, reportType) + { + } + + public MockReportCompliance(DynGraphqlQuery query, UserConfig userConfig, ReportType reportType, ReportParams reportParams) : base(query, userConfig, reportType, reportParams) + { + } + + public Dictionary CreateQueryVariablesPublic(int offset, int limit, string query) + { + return CreateQueryVariables(offset, limit, query); + } + } +} diff --git a/roles/tests-unit/files/FWO.Test/Mocks/MockReportComplianceDiff.cs b/roles/tests-unit/files/FWO.Test/Mocks/MockReportComplianceDiff.cs new file mode 100644 index 0000000000..8145002762 --- /dev/null +++ b/roles/tests-unit/files/FWO.Test/Mocks/MockReportComplianceDiff.cs @@ -0,0 +1,36 @@ +using FWO.Api.Client; +using FWO.Basics; +using FWO.Config.Api; +using FWO.Data; +using FWO.Data.Report; +using FWO.Report; +using FWO.Report.Filter; + +namespace FWO.Test.Mocks +{ + public class MockReportComplianceDiff : ReportComplianceDiff + { + public bool MockPostProcessDiffReportsRule { get; set; } = true; + + public MockReportComplianceDiff(DynGraphqlQuery query, UserConfig userConfig, ReportType reportType) : base(query, userConfig, reportType) + { + } + + public MockReportComplianceDiff(DynGraphqlQuery query, UserConfig userConfig, ReportType reportType, ReportParams reportParams) : base(query, userConfig, reportType, reportParams) + { + } + + protected override async Task PostProcessDiffReportsRule(Rule rule, ApiConnection apiConnection) + { + if (MockPostProcessDiffReportsRule) + { + await Task.CompletedTask; + } + else + { + await base.PostProcessDiffReportsRule(rule, apiConnection); + } + } + } + +} diff --git a/roles/tests-unit/files/FWO.Test/Mocks/MockReportRules.cs b/roles/tests-unit/files/FWO.Test/Mocks/MockReportRules.cs new file mode 100644 index 0000000000..6b26f6150d --- /dev/null +++ b/roles/tests-unit/files/FWO.Test/Mocks/MockReportRules.cs @@ -0,0 +1,141 @@ +using FWO.Basics; +using FWO.Config.Api; +using FWO.Data; +using FWO.Data.Report; +using FWO.Report; +using FWO.Report.Filter; +using FWO.Services.RuleTreeBuilder; +using Microsoft.Extensions.DependencyInjection; +using ServiceProvider = FWO.Services.ServiceProvider; + +namespace FWO.Test.Mocks +{ + public class MockReportRules : ReportRules + { + public static int RulebaseId { get; set; } = 0; + public static int RuleId { get; set; } = 0; + + public MockReportRules(DynGraphqlQuery query, UserConfig userConfig, ReportType reportType, Func>? setupFunc = null) : base(query, userConfig, reportType) + { + + if (ServiceProvider.Services == null || ServiceProvider.Services.GetService() == null) + { + var services = new ServiceCollection(); + services.AddTransient(); + ServiceProvider.Services = services.BuildServiceProvider(); + } + + if (setupFunc == null) + { + setupFunc = SetupSingleManagementReportEmpty; + } + + List managementReports = setupFunc(); + + foreach (var managementReport in managementReports) + { + ReportData.ManagementData.Add(managementReport); + } + + } + + public List SetupSingleManagementReportEmpty() + { + List reports = new() + { + new ManagementReport + { + Rulebases = [], + Devices = + [ + CreateDeviceReport() + ] + } + }; + + return reports; + } + + public static RulebaseReport CreateRulebaseReport(string rulebaseName = "", int numberOfRules = 0) + { + RulebaseId++; + + if (rulebaseName == "") + { + rulebaseName = $"Mock Rulebase {RulebaseId}"; + } + + List rules = new(); + + if (numberOfRules > 0) + { + for (int i = 1; i <= numberOfRules; i++) + { + RuleId++; + rules.Add(new Rule + { + Id = RuleId, + Uid = $"rule-{RulebaseId}.{RuleId}", + RulebaseId = RulebaseId, + Name = $"Mock Rule {RuleId}" + }); + } + } + + return new RulebaseReport + { + Id = RulebaseId, + Name = rulebaseName, + Rules = rules.ToArray() + }; + } + + public static DeviceReport CreateDeviceReport(int deviceId = 0, string deviceName = "", List? rulebaseLinks = null) + { + if (deviceId == 0) + { + deviceId = 1; + } + + if (deviceName == "") + { + deviceName = $"Mock Device {deviceId}"; + } + + return new DeviceReport + { + Id = deviceId, + Uid = $"device-{deviceId}", + Name = deviceName, + RulebaseLinks = rulebaseLinks?.ToArray() ?? [] + }; + } + + public static RuleTreeItem CreateRuleTreeItem(int ruleId, int rulebaseId, List position, List>? children = null) + { + RuleTreeItem item = new RuleTreeItem + { + Identifier = $"Rule (ID/UID): {ruleId}/rule-{rulebaseId}.{ruleId}", + Data = new Rule { Id = ruleId, Uid = $"rule-{rulebaseId}.{ruleId}", RulebaseId = rulebaseId }, + Position = position + }; + + if (children != null) + { + + + item.Children = children + .Cast() + .ToList(); ; + } + + return item; + } + + public void TryBuildMockRuleTree() + { + TryBuildRuleTree(); + } + + } +} diff --git a/roles/tests-unit/files/FWO.Test/Mocks/MockRuleTreeBuilder.cs b/roles/tests-unit/files/FWO.Test/Mocks/MockRuleTreeBuilder.cs new file mode 100644 index 0000000000..ec98f241b8 --- /dev/null +++ b/roles/tests-unit/files/FWO.Test/Mocks/MockRuleTreeBuilder.cs @@ -0,0 +1,10 @@ +using FWO.Data; +using FWO.Basics; +using FWO.Services.RuleTreeBuilder; + +namespace FWO.Test.Mocks; + +public class MockRuleTreeBuilder : RuleTreeBuilder +{ + +} diff --git a/roles/tests-unit/files/FWO.Test/ModellingAppHandlerTest.cs b/roles/tests-unit/files/FWO.Test/ModellingAppHandlerTest.cs new file mode 100644 index 0000000000..b76a1a60f3 --- /dev/null +++ b/roles/tests-unit/files/FWO.Test/ModellingAppHandlerTest.cs @@ -0,0 +1,238 @@ +using FWO.Config.Api; +using FWO.Data; +using FWO.Data.Modelling; +using FWO.Services; +using FWO.Ui.Services; +using FWO.Ui.Shared; +using Bunit; +using NUnit.Framework; +using System.Collections.Generic; +using System.Reflection; + +namespace FWO.Test +{ + [TestFixture] + public class ModellingAppHandlerTest + { + private static ModellingAppHandler CreateHandler(List connections, UserConfig? userConfig = null) + { + UserConfig config = userConfig ?? new SimulatedUserConfig(); + ModellingAppHandler handler = new( + new SimulatedApiConnection(), + config, + new FwoOwner { Id = 1 }, + DefaultInit.DoNothing, + isOwner: true); + handler.Connections = connections; + SetPrivateField(handler, "dummyAppRoleId", 0L); + return handler; + } + + private static void SetPrivateField(ModellingAppHandler handler, string fieldName, TValue value) + { + FieldInfo? field = typeof(ModellingAppHandler).GetField(fieldName, BindingFlags.NonPublic | BindingFlags.Instance); + Assert.That(field, Is.Not.Null); + field!.SetValue(handler, value); + } + + private static void SetComponentParameter(object component, string parameterName, TValue value) + { + PropertyInfo? parameter = component.GetType().GetProperty(parameterName, BindingFlags.Public | BindingFlags.Instance); + Assert.That(parameter, Is.Not.Null); + parameter!.SetValue(component, value); + } + + private static MethodInfo GetPrivateMethod(string name, params Type[] parameterTypes) + { + MethodInfo? method = typeof(ModellingAppHandler).GetMethod( + name, + BindingFlags.NonPublic | BindingFlags.Instance, + null, + parameterTypes, + null); + Assert.That(method, Is.Not.Null); + return method!; + } + + [Test] + public void GetInterfaces_ExcludesRejectedAndDecommissioned_WhenNotRequested() + { + ModellingConnection visible = new() + { + Id = 1, + IsInterface = true, + Props = new Dictionary() + }; + ModellingConnection rejected = new() + { + Id = 2, + IsInterface = true, + Props = new Dictionary + { + { ConState.Rejected.ToString(), "true" } + } + }; + ModellingConnection decommissioned = new() + { + Id = 3, + IsInterface = true, + Props = new Dictionary + { + { ConState.Decommissioned.ToString(), "true" } + } + }; + + ModellingAppHandler handler = CreateHandler([visible, rejected, decommissioned]); + + List interfaces = handler.GetInterfaces(); + + Assert.That(interfaces, Is.EqualTo([visible])); + } + + [Test] + public void GetCommonServices_ReturnsOnlyCommonServices() + { + ModellingConnection common = new() { Id = 1, IsCommonService = true }; + ModellingConnection regular = new() { Id = 2 }; + + ModellingAppHandler handler = CreateHandler([common, regular]); + + List result = handler.GetCommonServices(); + + Assert.That(result, Is.EqualTo([common])); + } + + [Test] + public void GetRegularConnections_ExcludesInterfacesAndCommonServices() + { + ModellingConnection regular = new() { Id = 1 }; + ModellingConnection common = new() { Id = 2, IsCommonService = true }; + ModellingConnection iface = new() { Id = 3, IsInterface = true }; + + ModellingAppHandler handler = CreateHandler([regular, common, iface]); + + List result = handler.GetRegularConnections(); + + Assert.That(result, Is.EqualTo([regular])); + } + + [Test] + public void GetConnectionsToRequest_OrdersCommonServicesFirst() + { + ModellingConnection regular = new() { Id = 1 }; + ModellingConnection common = new() { Id = 2, IsCommonService = true }; + ModellingConnection iface = new() { Id = 3, IsInterface = true }; + + ModellingAppHandler handler = CreateHandler([regular, common, iface]); + + List result = handler.GetConnectionsToRequest(); + + Assert.That(result, Is.EqualTo([common, regular])); + } + + [Test] + public void HasModellingIssues_ReturnsTrue_ForInterface() + { + ModellingConnection iface = new() { Id = 1, IsInterface = true }; + + ModellingAppHandler handler = CreateHandler([iface]); + + Assert.That(handler.HasModellingIssues(iface), Is.True); + } + + [Test] + public async Task PrepareConnections_SyncsInterfaceState() + { + SimulatedUserConfig userConfig = new() + { + VarianceAnalysisSync = false, + ModRolloutRemovedAppServers = false + }; + ModellingConnection conn = new() + { + Id = 1, + IsInterface = true, + IsRequested = true + }; + ModellingAppHandler handler = CreateHandler([conn], userConfig); + + MethodInfo prepareConnections = GetPrivateMethod("PrepareConnections", typeof(List)); + Task prepareTask = (Task)prepareConnections.Invoke(handler, new object[] { handler.Connections })!; + await prepareTask; + + Assert.That(conn.GetBoolProperty(ConState.Requested.ToString()), Is.True); + } + + [Test] + public async Task InitActiveTab_SetsInterfaceTab() + { + ModellingConnection iface = new() { Id = 1, IsInterface = true }; + ModellingAppHandler handler = CreateHandler([iface]); + + using Bunit.TestContext context = new(); + IRenderedComponent renderedTabSet = context.Render(); + TabSet tabSet = renderedTabSet.Instance; + Tab tab0 = new(); + Tab tab1 = new(); + Tab tab2 = new(); + SetComponentParameter(tab0, nameof(Tab.Position), 0); + SetComponentParameter(tab1, nameof(Tab.Position), 1); + SetComponentParameter(tab2, nameof(Tab.Position), 2); + tabSet.Tabs.AddRange([tab0, tab1, tab2]); + handler.Tabset = tabSet; + + await renderedTabSet.InvokeAsync(() => handler.InitActiveTab(iface)); + + Assert.That(handler.Tabset.ActiveTab, Is.EqualTo(tab1)); + } + + [Test] + public async Task InitActiveTab_SetsCommonServiceTab_WhenNoRegularConnections() + { + ModellingConnection common = new() { Id = 2, IsCommonService = true }; + ModellingAppHandler handler = CreateHandler([common]); + handler.Application.CommSvcPossible = true; + + using Bunit.TestContext context = new(); + IRenderedComponent renderedTabSet = context.Render(); + TabSet tabSet = renderedTabSet.Instance; + Tab tab0 = new(); + Tab tab1 = new(); + Tab tab2 = new(); + SetComponentParameter(tab0, nameof(Tab.Position), 0); + SetComponentParameter(tab1, nameof(Tab.Position), 1); + SetComponentParameter(tab2, nameof(Tab.Position), 2); + tabSet.Tabs.AddRange([tab0, tab1, tab2]); + handler.Tabset = tabSet; + + await renderedTabSet.InvokeAsync(() => handler.InitActiveTab()); + + Assert.That(handler.Tabset.ActiveTab, Is.EqualTo(tab2)); + } + + [Test] + public async Task RestoreTab_UsesStoredTabPosition() + { + ModellingAppHandler handler = CreateHandler([]); + + using Bunit.TestContext context = new(); + IRenderedComponent renderedTabSet = context.Render(); + TabSet tabSet = renderedTabSet.Instance; + Tab tab0 = new(); + Tab tab2 = new(); + SetComponentParameter(tab0, nameof(Tab.Position), 0); + SetComponentParameter(tab2, nameof(Tab.Position), 2); + tabSet.Tabs.AddRange([tab0, tab2]); + await renderedTabSet.InvokeAsync(() => tabSet.SetActiveTab(tab0)); + handler.Tabset = tabSet; + + Tab actTab = new(); + SetComponentParameter(actTab, nameof(Tab.Position), 2); + SetPrivateField(handler, "ActTab", actTab); + + await renderedTabSet.InvokeAsync(() => handler.RestoreTab()); + + Assert.That(handler.Tabset.ActiveTab, Is.EqualTo(tab2)); + } + } +} diff --git a/roles/tests-unit/files/FWO.Test/ModellingAppServerHandlerTest.cs b/roles/tests-unit/files/FWO.Test/ModellingAppServerHandlerTest.cs new file mode 100644 index 0000000000..9dd582022a --- /dev/null +++ b/roles/tests-unit/files/FWO.Test/ModellingAppServerHandlerTest.cs @@ -0,0 +1,116 @@ +using FWO.Api.Client; +using FWO.Basics; +using FWO.Config.Api; +using FWO.Data; +using FWO.Data.Modelling; +using FWO.Services.Modelling; +using NUnit.Framework; + +namespace FWO.Test +{ + [TestFixture] + internal class ModellingAppServerHandlerTest + { + private sealed class ThrowingApiConnection : SimulatedApiConnection + { + public override Task SendQueryAsync(string query, object? variables = null, string? operationName = null) + { + throw new AssertionException("SendQueryAsync should not be called for validation-only tests."); + } + } + + private static UserConfig CreateUserConfig() + { + UserConfig userConfig = new(); + userConfig.Translate = new Dictionary + { + ["edit_app_server"] = "edit_app_server", + ["save_app_server"] = "save_app_server", + ["wrong_ip_address"] = "wrong_ip_address", + ["E5102"] = "E5102" + }; + return userConfig; + } + + [Test] + public async Task Save_ReturnsFalse_WhenMissingIpOrCustomType() + { + string? lastMessage = null; + ModellingAppServerHandler handler = new( + new ThrowingApiConnection(), + CreateUserConfig(), + new FwoOwner { Id = 1 }, + new ModellingAppServer { Ip = "", CustomType = 1 }, + [], + false, + (_, _, message, _) => lastMessage = message, + false, + false + ); + + bool result = await handler.Save(); + + Assert.That(result, Is.False); + Assert.That(lastMessage, Is.EqualTo("E5102")); + } + + [Test] + public async Task Save_ReturnsFalse_WhenIpInvalid_AndSetsManualImport() + { + string? lastMessage = null; + ModellingAppServer appServer = new() { Ip = "invalid-ip", CustomType = 1 }; + ModellingAppServerHandler handler = new( + new ThrowingApiConnection(), + CreateUserConfig(), + new FwoOwner { Id = 42 }, + appServer, + [], + false, + (_, _, message, _) => lastMessage = message, + false, + false + ); + + bool result = await handler.Save(); + + Assert.That(result, Is.False); + Assert.That(lastMessage, Is.EqualTo("wrong_ip_address")); + Assert.That(appServer.AppId, Is.EqualTo(42)); + Assert.That(appServer.ImportSource, Is.EqualTo(GlobalConst.kManual)); + } + + [Test] + public void Reset_RestoresOriginalValues_AndUpdatesList() + { + ModellingAppServer appServer = new() + { + Id = 7, + Name = "original", + Ip = "10.0.0.1", + CustomType = 1 + }; + List available = [appServer]; + ModellingAppServerHandler handler = new( + new ThrowingApiConnection(), + CreateUserConfig(), + new FwoOwner { Id = 1 }, + appServer, + available, + false, + (_, _, _, _) => { }, + false, + false + ); + + handler.ActAppServer.Name = "changed"; + handler.ActAppServer.Ip = "10.0.0.2"; + available[0] = handler.ActAppServer; + + handler.Reset(); + + Assert.That(handler.ActAppServer.Name, Is.EqualTo("original")); + Assert.That(handler.ActAppServer.Ip, Is.EqualTo("10.0.0.1")); + Assert.That(available[0].Name, Is.EqualTo("original")); + } + } +} diff --git a/roles/tests-unit/files/FWO.Test/ModellingConnectionHandlerCoreTest.cs b/roles/tests-unit/files/FWO.Test/ModellingConnectionHandlerCoreTest.cs new file mode 100644 index 0000000000..6ea9e3bb8e --- /dev/null +++ b/roles/tests-unit/files/FWO.Test/ModellingConnectionHandlerCoreTest.cs @@ -0,0 +1,255 @@ +using NUnit.Framework; +using NUnit.Framework.Legacy; +using FWO.Data; +using FWO.Data.Modelling; +using FWO.Services; +using FWO.Services.Modelling; +using FWO.Basics; +using System.Reflection; +using System.Collections.Generic; + +namespace FWO.Test +{ + [TestFixture] + [Parallelizable] + internal class ModellingConnectionHandlerCoreTest + { + static readonly SimulatedUserConfig userConfig = new(); + static readonly Action DisplayMessageInUi = DefaultInit.DoNothing; + static readonly FwoOwner Application = new() { Id = 1, Name = "TestApp" }; + + [OneTimeSetUp] + public void EnsureRequiredTranslationKeys() + { + SimulatedUserConfig.DummyTranslate.TryAdd("save_connection", "Save Connection"); + } + + [Test] + public void CalcVisibility_InterfaceWithDestinationFilled_ReadonlyFlags() + { + ModellingConnection connection = new() + { + Id = 1, + IsInterface = true, + DestinationAreas = [WrapArea(10, "Area10")] + }; + + ModellingConnectionHandler handler = CreateHandler(connection); + + bool result = handler.CalcVisibility(); + + ClassicAssert.IsTrue(result); + ClassicAssert.IsTrue(handler.SrcReadOnly); + ClassicAssert.IsFalse(handler.DstReadOnly); + ClassicAssert.IsFalse(handler.SvcReadOnly); + } + + [Test] + public void CalcVisibility_UsedInterfaceFlags() + { + ModellingConnection connection = new() + { + Id = 2, + UsedInterfaceId = 5, + SrcFromInterface = true, + DstFromInterface = false + }; + + ModellingConnectionHandler handler = CreateHandler(connection); + + handler.CalcVisibility(); + + ClassicAssert.IsTrue(handler.SrcReadOnly); + ClassicAssert.IsFalse(handler.DstReadOnly); + ClassicAssert.IsTrue(handler.SvcReadOnly); + } + + [Test] + public void CalcVisibility_DefaultFlags() + { + ModellingConnection connection = new() { Id = 3 }; + ModellingConnectionHandler handler = CreateHandler(connection); + + handler.CalcVisibility(); + + ClassicAssert.IsFalse(handler.SrcReadOnly); + ClassicAssert.IsFalse(handler.DstReadOnly); + ClassicAssert.IsFalse(handler.SvcReadOnly); + } + + [Test] + public void CheckConn_FailsWhenNameOrReasonMissing() + { + ModellingConnection connection = new() + { + Id = 4, + Name = "", + Reason = "" + }; + + ModellingConnectionHandler handler = CreateHandler(connection); + + ClassicAssert.IsFalse(handler.CheckConn()); + } + + [Test] + public void CheckConn_InterfaceWithSourceAndServicePasses() + { + ModellingConnection connection = new() + { + Id = 5, + Name = "Interf", + Reason = "Reason", + IsInterface = true, + SourceAreas = [WrapArea(11, "Area11")], + Services = [WrapService(21, "Svc21")] + }; + + ModellingConnectionHandler handler = CreateHandler(connection); + + ClassicAssert.IsTrue(handler.CheckConn()); + } + + [Test] + public void CheckConn_NonInterfaceMissingServiceFails() + { + ModellingConnection connection = new() + { + Id = 6, + Name = "Conn", + Reason = "Reason", + SourceAreas = [WrapArea(12, "Area12")], + DestinationAreas = [WrapArea(13, "Area13")] + }; + + ModellingConnectionHandler handler = CreateHandler(connection); + + ClassicAssert.IsFalse(handler.CheckConn()); + } + + [Test] + public void SyncChanges_AppliesAddsAndDeletes() + { + ModellingConnection connection = new() + { + Id = 7, + SourceAreas = [WrapArea(14, "AreaOld")], + PermittedOwners = [new FwoOwner { Id = 1, Name = "Owner1" }] + }; + + ModellingConnectionHandler handler = CreateHandler(connection); + handler.SrcAreasToDelete.Add(new ModellingNetworkArea { Id = 14, Name = "AreaOld", IdString = "NA14" }); + handler.SrcAreasToAdd.Add(new ModellingNetworkArea { Id = 15, Name = "AreaNew", IdString = "NA15" }); + handler.PermittedOwnersToDelete.Add(new FwoOwner { Id = 1, Name = "Owner1" }); + handler.PermittedOwnersToAdd.Add(new FwoOwner { Id = 2, Name = "Owner2" }); + + InvokePrivateVoid(handler, "SyncChanges"); + + ClassicAssert.IsFalse(handler.ActConn.SourceAreas.Any(a => a.Content.Id == 14)); + ClassicAssert.IsTrue(handler.ActConn.SourceAreas.Any(a => a.Content.Id == 15)); + ClassicAssert.IsFalse(handler.ActConn.PermittedOwners.Any(o => o.Id == 1)); + ClassicAssert.IsTrue(handler.ActConn.PermittedOwners.Any(o => o.Id == 2)); + } + + [Test] + public async Task SavePropertiesOnly_UpdatesMatchingConnectionAndReturnsTrue() + { + SavePropertiesOnlyTestApiConn apiConnection = new(); + ModellingConnection listedConnection = new() { Id = 100, Properties = "{\"old\":true}" }; + ModellingConnection actConnection = new() { Id = 100, Properties = "{\"new\":true}" }; + ModellingConnectionHandler handler = CreateHandler(actConnection, [listedConnection], apiConnection); + + bool result = await handler.SavePropertiesOnly(); + + ClassicAssert.IsTrue(result); + ClassicAssert.IsTrue(apiConnection.UpdateConnectionPropertiesCalled); + ClassicAssert.AreEqual(100, GetVariable(apiConnection.LastVariables, "id")); + ClassicAssert.AreEqual("{\"new\":true}", GetVariable(apiConnection.LastVariables, "connProp")); + ClassicAssert.AreEqual("{\"new\":true}", listedConnection.Properties); + } + + [Test] + public async Task SavePropertiesOnly_WithoutMatchingConnection_ReturnsTrueWithoutListUpdate() + { + SavePropertiesOnlyTestApiConn apiConnection = new(); + ModellingConnection listedConnection = new() { Id = 101, Properties = "{\"old\":true}" }; + ModellingConnection actConnection = new() { Id = 999, Properties = "{\"new\":true}" }; + ModellingConnectionHandler handler = CreateHandler(actConnection, [listedConnection], apiConnection); + + bool result = await handler.SavePropertiesOnly(); + + ClassicAssert.IsTrue(result); + ClassicAssert.IsTrue(apiConnection.UpdateConnectionPropertiesCalled); + ClassicAssert.AreEqual("{\"old\":true}", listedConnection.Properties); + } + + [Test] + public async Task SavePropertiesOnly_OnApiException_ReturnsFalseAndKeepsListUnchanged() + { + SavePropertiesOnlyTestApiConn apiConnection = new() { ThrowOnUpdateConnectionProperties = true }; + ModellingConnection listedConnection = new() { Id = 102, Properties = "{\"old\":true}" }; + ModellingConnection actConnection = new() { Id = 102, Properties = "{\"new\":true}" }; + ModellingConnectionHandler handler = CreateHandler(actConnection, [listedConnection], apiConnection); + + bool result = await handler.SavePropertiesOnly(); + + ClassicAssert.IsFalse(result); + ClassicAssert.AreEqual("{\"old\":true}", listedConnection.Properties); + } + + private static ModellingConnectionHandler CreateHandler(ModellingConnection connection) + { + return new ModellingConnectionHandler(new ModellingHandlerTestApiConn(), userConfig, Application, [connection], connection, false, false, DisplayMessageInUi, DefaultInit.DoNothing, true); + } + + private static ModellingConnectionHandler CreateHandler(ModellingConnection actConnection, List connections, SimulatedApiConnection apiConnection) + { + return new ModellingConnectionHandler(apiConnection, userConfig, Application, connections, actConnection, false, false, DisplayMessageInUi, DefaultInit.DoNothing, true); + } + + private static void InvokePrivateVoid(ModellingConnectionHandler handler, string methodName) + { + MethodInfo? method = typeof(ModellingConnectionHandler).GetMethod(methodName, BindingFlags.NonPublic | BindingFlags.Instance); + ClassicAssert.IsNotNull(method, $"Expected to find method '{methodName}'."); + method!.Invoke(handler, null); + } + + private static ModellingNetworkAreaWrapper WrapArea(long id, string name) + { + return new ModellingNetworkAreaWrapper { Content = new ModellingNetworkArea { Id = id, Name = name, IdString = $"NA{id}" } }; + } + + private static ModellingServiceWrapper WrapService(int id, string name) + { + return new ModellingServiceWrapper { Content = new ModellingService { Id = id, Name = name } }; + } + + private static T GetVariable(object? variables, string name) + { + object? value = variables?.GetType().GetProperty(name)?.GetValue(variables); + return value == null ? default! : (T)value; + } + + private sealed class SavePropertiesOnlyTestApiConn : SimulatedApiConnection + { + public bool ThrowOnUpdateConnectionProperties { get; set; } + public bool UpdateConnectionPropertiesCalled { get; private set; } + public object? LastVariables { get; private set; } + + public override Task SendQueryAsync(string query, object? variables = null, string? operationName = null) + { + if (query == FWO.Api.Client.Queries.ModellingQueries.updateConnectionProperties && typeof(QueryResponseType) == typeof(ReturnId)) + { + UpdateConnectionPropertiesCalled = true; + LastVariables = variables; + if (ThrowOnUpdateConnectionProperties) + { + throw new InvalidOperationException("Simulated update failure."); + } + return Task.FromResult((QueryResponseType)(object)new ReturnId { AffectedRows = 1 }); + } + throw new NotImplementedException($"Unhandled query: {query}"); + } + } + } +} diff --git a/roles/tests-unit/files/FWO.Test/ModellingConnectionHandlerDecommissionTest.cs b/roles/tests-unit/files/FWO.Test/ModellingConnectionHandlerDecommissionTest.cs new file mode 100644 index 0000000000..a36aea88eb --- /dev/null +++ b/roles/tests-unit/files/FWO.Test/ModellingConnectionHandlerDecommissionTest.cs @@ -0,0 +1,240 @@ +using NUnit.Framework; +using NUnit.Framework.Legacy; +using FWO.Api.Client; +using FWO.Basics; +using FWO.Config.Api; +using FWO.Config.Api.Data; +using FWO.Data; +using FWO.Data.Modelling; +using FWO.Services; +using FWO.Services.Modelling; +using FWO.Middleware.Client; +using FWO.Api.Client.Queries; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; + +namespace FWO.Test +{ + [TestFixture] + [Parallelizable] + internal class ModellingConnectionHandlerDecommissionTest + { + [Test] + public async Task DecommissionInterface_NotifiesAndAddsPermissionsAndSelections() + { + DecommissionTestApiConn apiConnection = new(); + SimulatedUserConfig userConfig = new(); + userConfig.ModDecommEmailReceiver = nameof(EmailRecipientOption.OwnerMainResponsible); + userConfig.ModDecommEmailSubject = $"Subject {Placeholder.INTERFACE_NAME}"; + userConfig.ModDecommEmailBody = $"Body {Placeholder.INTERFACE_NAME} {Placeholder.NEW_INTERFACE_NAME} {Placeholder.NEW_INTERFACE_LINK} {Placeholder.REASON} {Placeholder.USER_NAME}"; + userConfig.UiHostName = "https://ui.example.test"; + userConfig.User.Name = "Tester"; + + FwoOwner owner = new() { Id = 1, Name = "Owner1", ExtAppId = "APP1" }; + ModellingConnection interfaceConn = new() + { + Id = 10, + AppId = owner.Id, + App = owner, + Name = "Interface1", + IsInterface = true + }; + + ModellingConnection proposedInterface = new() + { + Id = 99, + Name = "InterfaceNew", + App = new FwoOwner { Id = 4, Name = "Owner4", ExtAppId = "APP4" } + }; + + TestEmailHelper emailHelper = new(userConfig); + List interfaceUsers = + [ + new ModellingConnection { Id = 20, AppId = 2, App = new FwoOwner { Id = 2, Name = "Owner2" }, Name = "Conn2" }, + new ModellingConnection { Id = 21, AppId = 3, App = new FwoOwner { Id = 3, Name = "Owner3" }, Name = "Conn3" }, + new ModellingConnection { Id = 22, AppId = 1, App = owner, Name = "ConnOwn" } + ]; + apiConnection.InterfaceUsers = interfaceUsers; + apiConnection.ConnectionById = interfaceConn; + + DecommissionTestHandler handler = new(apiConnection, userConfig, owner, [interfaceConn], interfaceConn, addMode: false, + readOnly: false, DefaultInit.DoNothing, DefaultInit.DoNothing, isOwner: true) + { + UsingConnections = interfaceUsers, + ActConnNeedsRefresh = false, + EmailHelperOverride = emailHelper + }; + + MiddlewareClient middlewareClient = new("http://localhost/"); + + await handler.DecommissionInterface("Planned", true, proposedInterface, middlewareClient); + + ClassicAssert.IsTrue(emailHelper.InitCalled); + ClassicAssert.AreEqual(2, emailHelper.SentEmails.Count); + ClassicAssert.IsTrue(emailHelper.SentEmails.All(email => email.Owner.Id != owner.Id)); + ClassicAssert.IsTrue(emailHelper.SentEmails.All(email => email.Subject == $"Subject {interfaceConn.Name}")); + ClassicAssert.IsTrue(emailHelper.SentEmails.All(email => email.Body.Contains($"{interfaceConn.Name}"))); + ClassicAssert.IsTrue(emailHelper.SentEmails.All(email => email.Body.Contains($"{proposedInterface.Name}"))); + ClassicAssert.IsTrue(emailHelper.SentEmails.All(email => email.Body.Contains($"{userConfig.User.Name}"))); + ClassicAssert.IsTrue(emailHelper.SentEmails.All(email => email.Body.Contains($"Planned"))); + ClassicAssert.IsTrue(emailHelper.SentEmails.All(email => email.Body.Contains($"{userConfig.UiHostName}/{PageName.Modelling}/{proposedInterface.App.ExtAppId}/{proposedInterface.Id}"))); + + CollectionAssert.AreEquivalent(new[] { 2, 3 }, apiConnection.AddedPermittedOwnerAppIds); + CollectionAssert.AreEquivalent(new[] { 2, 3 }, apiConnection.AddedSelectedConnectionAppIds); + ClassicAssert.IsTrue(apiConnection.AddedSelectedConnections.All(c => c.ConnectionId == proposedInterface.Id)); + ClassicAssert.IsTrue(apiConnection.RemovedSelectedConnections.Contains(interfaceConn.Id)); + } + + private sealed class DecommissionTestHandler : ModellingConnectionHandler + { + public TestEmailHelper? EmailHelperOverride { get; set; } + + public DecommissionTestHandler(ApiConnection apiConnection, SimulatedUserConfig userConfig, FwoOwner application, + List connections, ModellingConnection conn, bool addMode, bool readOnly, + Action displayMessageInUi, Func refreshParent, bool isOwner) + : base(apiConnection, userConfig, application, connections, conn, addMode, readOnly, displayMessageInUi, refreshParent, isOwner) + { + } + + protected override EmailHelper CreateEmailHelper(MiddlewareClient middlewareClient) + { + return EmailHelperOverride ?? base.CreateEmailHelper(middlewareClient); + } + } + + private sealed class TestEmailHelper : EmailHelper + { + public bool InitCalled { get; private set; } + public List<(FwoOwner Owner, string Subject, string Body, EmailRecipientOption Recipient)> SentEmails { get; } = []; + + public TestEmailHelper(UserConfig userConfig) + : base(new SimulatedApiConnection(), null, userConfig, DefaultInit.DoNothing) + { + } + + public override Task Init(string? scopedUserTo = null, string? scopedUserCc = null) + { + InitCalled = true; + return Task.CompletedTask; + } + + public override Task SendEmailToOwnerResponsibles(FwoOwner owner, string subject, string body, EmailRecipientOption recOpt, bool reqInCc = false) + { + SentEmails.Add((owner, subject, body, recOpt)); + return Task.FromResult(true); + } + + public override Task SendEmailToOwnerResponsibles(FwoOwner owner, string subject, string body, string recipientConfig, bool reqInCc = false, List? otherAddresses = null) + { + ModellingEmailRecipientSelection parsedSelection = ModellingEmailRecipientSelection.Parse(recipientConfig); + EmailRecipientOption recipient = parsedSelection.None ? EmailRecipientOption.None : EmailRecipientOption.OwnerMainResponsible; + SentEmails.Add((owner, subject, body, recipient)); + return Task.FromResult(true); + } + } + + private sealed class DecommissionTestApiConn : SimulatedApiConnection + { + public List AddedPermittedOwnerAppIds { get; } = []; + public List AddedSelectedConnectionAppIds { get; } = []; + public List<(int AppId, int ConnectionId)> AddedSelectedConnections { get; } = []; + public List RemovedSelectedConnections { get; } = []; + public List InterfaceUsers { get; set; } = []; + public List PermittedOwners { get; set; } = []; + public ModellingConnection? ConnectionById { get; set; } + + public override Task SendQueryAsync(string query, object? variables = null, string? operationName = null) + { + Type responseType = typeof(QueryResponseType); + if (query == ModellingQueries.addPermittedOwner) + { + AddedPermittedOwnerAppIds.Add(GetIntVariable(variables, "appId")); + return Task.FromResult((QueryResponseType)(object)new ReturnId { AffectedRows = 1 }); + } + if (query == ModellingQueries.addSelectedConnection) + { + int appId = GetIntVariable(variables, "appId"); + int connId = GetIntVariable(variables, "connectionId"); + AddedSelectedConnectionAppIds.Add(appId); + AddedSelectedConnections.Add((appId, connId)); + ReturnIdWrapper wrapper = new() { ReturnIds = [new ReturnId { InsertedId = connId }] }; + return Task.FromResult((QueryResponseType)(object)wrapper); + } + if (query == ModellingQueries.removeSelectedConnection) + { + RemovedSelectedConnections.Add(GetIntVariable(variables, "connectionId")); + return Task.FromResult((QueryResponseType)(object)new ReturnId { AffectedRows = 1 }); + } + if (query == ModellingQueries.updateConnectionDecommission || + query == ModellingQueries.updateConnectionProperties) + { + return Task.FromResult((QueryResponseType)(object)new ReturnId { AffectedRows = 1 }); + } + if (query == ModellingQueries.addHistoryEntry) + { + ReturnIdWrapper wrapper = new() { ReturnIds = [new ReturnId { AffectedRows = 1 }] }; + return Task.FromResult((QueryResponseType)(object)wrapper); + } + if (responseType == typeof(List) && query == ModellingQueries.getSelectedConnections) + { + return Task.FromResult((QueryResponseType)(object)new List()); + } + if (responseType == typeof(List) && query == ModellingQueries.getPermittedOwnersForConnection) + { + return Task.FromResult((QueryResponseType)(object)PermittedOwners); + } + if (responseType == typeof(List) && query == ModellingQueries.getAppServersForOwner) + { + return Task.FromResult((QueryResponseType)(object)new List()); + } + if (responseType == typeof(List) && query == ModellingQueries.getAppRoles) + { + return Task.FromResult((QueryResponseType)(object)new List()); + } + if (responseType == typeof(List) && query == ModellingQueries.getNwGroupObjects) + { + return Task.FromResult((QueryResponseType)(object)new List()); + } + if (responseType == typeof(List) && query == ModellingQueries.getSelectedNwGroupObjects) + { + return Task.FromResult((QueryResponseType)(object)new List()); + } + if (responseType == typeof(List) && + (query == ModellingQueries.getGlobalServiceGroups || query == ModellingQueries.getServiceGroupsForApp)) + { + return Task.FromResult((QueryResponseType)(object)new List()); + } + if (responseType == typeof(List) && + (query == ModellingQueries.getGlobalServices || query == ModellingQueries.getServicesForApp)) + { + return Task.FromResult((QueryResponseType)(object)new List()); + } + if (responseType == typeof(List)) + { + if (query == ModellingQueries.getInterfaceUsers) + { + return Task.FromResult((QueryResponseType)(object)InterfaceUsers); + } + if (query == ModellingQueries.getConnectionById && ConnectionById != null) + { + return Task.FromResult((QueryResponseType)(object)new List { ConnectionById }); + } + } + + throw new NotImplementedException($"Unhandled query: {query}"); + } + + private static int GetIntVariable(object? variables, string name) + { + if (variables == null) + { + return 0; + } + object? value = variables.GetType().GetProperties().FirstOrDefault(p => p.Name == name)?.GetValue(variables); + return value == null ? 0 : Convert.ToInt32(value); + } + } + } +} diff --git a/roles/tests-unit/files/FWO.Test/ModellingConnectionHandlerDummyAppRoleTest.cs b/roles/tests-unit/files/FWO.Test/ModellingConnectionHandlerDummyAppRoleTest.cs new file mode 100644 index 0000000000..158349fd9a --- /dev/null +++ b/roles/tests-unit/files/FWO.Test/ModellingConnectionHandlerDummyAppRoleTest.cs @@ -0,0 +1,138 @@ +using NUnit.Framework; +using NUnit.Framework.Legacy; +using FWO.Data; +using FWO.Data.Modelling; +using FWO.Services; +using FWO.Services.Modelling; +using FWO.Basics; +using FWO.Api.Client.Queries; +using System; +using System.Collections.Generic; +using System.Reflection; +using System.Threading.Tasks; + +namespace FWO.Test +{ + [TestFixture] + [Parallelizable] + internal class ModellingConnectionHandlerDummyAppRoleTest + { + static readonly SimulatedUserConfig userConfig = new(); + static readonly Action DisplayMessageInUi = DefaultInit.DoNothing; + static readonly FwoOwner Application = new() { Id = 1, Name = "TestApp" }; + + [Test] + public async Task AddNwObjects_LogsDummyAppRoleMarker() + { + DummyAppRoleTestApiConn apiConnection = new(); + ModellingConnection connection = new() + { + Id = 1, + Name = "ReqInterf", + IsInterface = true + }; + + ModellingConnectionHandler handler = CreateHandler(apiConnection, connection); + handler.DummyAppRole = new ModellingAppRole { Id = 999, Name = "Dummy" }; + + List appRoles = [new ModellingAppRole { Id = 999, Name = "Dummy" }]; + + await InvokePrivateAsync(handler, "AddNwObjects", + new object[] { new List(), appRoles, new List(), new List(), ModellingTypes.ConnectionField.Source }); + + ClassicAssert.AreEqual(1, apiConnection.HistoryTexts.Count); + ClassicAssert.AreEqual("Marked requested Interface: ReqInterf as Source", apiConnection.HistoryTexts[0]); + } + + [Test] + public async Task RemoveNwObjects_LogsDummyAppRoleMarkerRemoval() + { + DummyAppRoleTestApiConn apiConnection = new(); + ModellingConnection connection = new() + { + Id = 2, + Name = "ReqInterf", + IsInterface = true + }; + + ModellingConnectionHandler handler = CreateHandler(apiConnection, connection); + handler.DummyAppRole = new ModellingAppRole { Id = 999, Name = "Dummy" }; + + List appRoles = [new ModellingAppRole { Id = 999, Name = "Dummy" }]; + + await InvokePrivateAsync(handler, "RemoveNwObjects", + new object[] { new List(), appRoles, new List(), new List(), ModellingTypes.ConnectionField.Source }); + + ClassicAssert.AreEqual(1, apiConnection.HistoryTexts.Count); + ClassicAssert.AreEqual("Removed Source marker from requested Interface: ReqInterf", apiConnection.HistoryTexts[0]); + } + + [Test] + public async Task AddNwObjects_LogsDummyAndRealAppRoleMessages() + { + DummyAppRoleTestApiConn apiConnection = new(); + ModellingConnection connection = new() + { + Id = 3, + Name = "ReqInterf", + IsInterface = true + }; + + ModellingConnectionHandler handler = CreateHandler(apiConnection, connection); + handler.DummyAppRole = new ModellingAppRole { Id = 999, Name = "Dummy" }; + + List appRoles = + [ + new ModellingAppRole { Id = 999, Name = "Dummy" }, + new ModellingAppRole { Id = 200, Name = "RealAppRole", IdString = "App123" } + ]; + + await InvokePrivateAsync(handler, "AddNwObjects", + new object[] { new List(), appRoles, new List(), new List(), ModellingTypes.ConnectionField.Source }); + + ClassicAssert.AreEqual(2, apiConnection.HistoryTexts.Count); + ClassicAssert.IsTrue(apiConnection.HistoryTexts.Any(t => t == "Marked requested Interface: ReqInterf as Source")); + ClassicAssert.IsTrue(apiConnection.HistoryTexts.Any(t => t == "Added App Role RealAppRole (App123) to Interface: ReqInterf: Source")); + } + + private static ModellingConnectionHandler CreateHandler(DummyAppRoleTestApiConn apiConnection, ModellingConnection connection) + { + return new ModellingConnectionHandler(apiConnection, userConfig, Application, [connection], connection, false, false, DisplayMessageInUi, DefaultInit.DoNothing, true); + } + + private static async Task InvokePrivateAsync(ModellingConnectionHandler handler, string methodName, object[] args) + { + MethodInfo? method = typeof(ModellingConnectionHandler).GetMethod(methodName, BindingFlags.NonPublic | BindingFlags.Instance); + ClassicAssert.IsNotNull(method, $"Expected to find method '{methodName}'."); + Task task = (Task)method!.Invoke(handler, args)!; + await task; + } + } + + internal class DummyAppRoleTestApiConn : SimulatedApiConnection + { + public List HistoryTexts { get; } = []; + + public override Task SendQueryAsync(string query, object? variables = null, string? operationName = null) + { + Type responseType = typeof(QueryResponseType); + if (query == ModellingQueries.addNwGroupToConnection || query == ModellingQueries.removeNwGroupFromConnection) + { + return Task.FromResult((QueryResponseType)(object)new ReturnId { AffectedRows = 1 }); + } + if (query == ModellingQueries.addHistoryEntry) + { + if (variables != null) + { + string? text = variables.GetType().GetProperties().FirstOrDefault(p => p.Name == "changeText")?.GetValue(variables)?.ToString(); + if (!string.IsNullOrEmpty(text)) + { + HistoryTexts.Add(text); + } + } + return Task.FromResult((QueryResponseType)(object)new ReturnIdWrapper { ReturnIds = [new ReturnId { AffectedRows = 1 }] }); + } + return Task.FromResult((QueryResponseType)(object)new ReturnId { AffectedRows = 1 }); + } + } +} diff --git a/roles/tests-unit/files/FWO.Test/ModellingConnectionHandlerInterfHandlingTest.cs b/roles/tests-unit/files/FWO.Test/ModellingConnectionHandlerInterfHandlingTest.cs new file mode 100644 index 0000000000..91ba214906 --- /dev/null +++ b/roles/tests-unit/files/FWO.Test/ModellingConnectionHandlerInterfHandlingTest.cs @@ -0,0 +1,478 @@ +using NUnit.Framework; +using NUnit.Framework.Legacy; +using FWO.Data; +using FWO.Data.Modelling; +using FWO.Services; +using FWO.Services.Modelling; +using FWO.Basics; +using System.Collections.Generic; + +namespace FWO.Test +{ + [TestFixture] + [Parallelizable] + internal class ModellingConnectionHandlerInterfHandlingTest + { + static readonly SimulatedUserConfig userConfig = new(); + static readonly Action DisplayMessageInUi = DefaultInit.DoNothing; + static readonly FwoOwner Application = new() { Id = 1, Name = "TestApp" }; + + [Test] + public void InterfaceToConn_UsesInterfaceSourceWhenSourceFilled() + { + ModellingConnection connection = new() + { + Id = 1, + SourceAppServers = [WrapAppServer(10, "AS_old")], + SourceAppRoles = [WrapAppRole(20, "AR_old")], + SourceAreas = [WrapArea(30, "Area_old")], + SourceOtherGroups = [WrapNwGroup(40, "Group_old")], + DestinationAppServers = [WrapAppServer(110, "AS_dst_old")], + DestinationAppRoles = [WrapAppRole(120, "AR_dst_old")], + DestinationAreas = [WrapArea(130, "Area_dst_old")], + DestinationOtherGroups = [WrapNwGroup(140, "Group_dst_old")] + }; + + ModellingConnection interf = new() + { + Id = 2, + Name = "Interf1", + IsRequested = true, + SourceAppServers = [WrapAppServer(11, "AS_new")], + SourceAppRoles = [WrapAppRole(21, "AR_new")], + SourceAreas = [WrapArea(31, "Area_new")], + SourceOtherGroups = [WrapNwGroup(41, "Group_new")], + Services = [WrapService(51, "Svc_new")], + ServiceGroups = [WrapServiceGroup(61, "SvcGrp_new")], + ExtraConfigs = [new ModellingExtraConfig() { ExtraConfigType = "X", ExtraConfigText = "Y" }] + }; + + ModellingConnectionHandler handler = CreateHandler(connection); + + handler.InterfaceToConn(interf); + + ClassicAssert.AreEqual("Interf1", handler.InterfaceName); + ClassicAssert.IsTrue(handler.SrcReadOnly); + ClassicAssert.IsFalse(handler.DstReadOnly); + ClassicAssert.IsTrue(handler.SvcReadOnly); + ClassicAssert.IsTrue(handler.ActConn.SrcFromInterface); + ClassicAssert.IsFalse(handler.ActConn.DstFromInterface); + ClassicAssert.AreEqual(interf.Id, handler.ActConn.UsedInterfaceId); + ClassicAssert.AreEqual(1, handler.SrcAppServerToDelete.Count); + ClassicAssert.AreEqual(10, handler.SrcAppServerToDelete[0].Id); + ClassicAssert.AreEqual(1, handler.SrcAppRolesToDelete.Count); + ClassicAssert.AreEqual(20, handler.SrcAppRolesToDelete[0].Id); + ClassicAssert.AreEqual(1, handler.SrcAreasToDelete.Count); + ClassicAssert.AreEqual(30, handler.SrcAreasToDelete[0].Id); + ClassicAssert.AreEqual(1, handler.SrcNwGroupsToDelete.Count); + ClassicAssert.AreEqual(40, handler.SrcNwGroupsToDelete[0].Id); + ClassicAssert.AreEqual(11, handler.ActConn.SourceAppServers[0].Content.Id); + ClassicAssert.AreEqual(21, handler.ActConn.SourceAppRoles[0].Content.Id); + ClassicAssert.AreEqual(31, handler.ActConn.SourceAreas[0].Content.Id); + ClassicAssert.AreEqual(41, handler.ActConn.SourceOtherGroups[0].Content.Id); + ClassicAssert.AreEqual(110, handler.ActConn.DestinationAppServers[0].Content.Id); + ClassicAssert.AreEqual(1, handler.ActConn.Services.Count); + ClassicAssert.AreEqual(51, handler.ActConn.Services[0].Content.Id); + ClassicAssert.AreEqual(1, handler.ActConn.ServiceGroups.Count); + ClassicAssert.AreEqual(61, handler.ActConn.ServiceGroups[0].Content.Id); + ClassicAssert.AreEqual(1, handler.ActConn.ExtraConfigsFromInterface.Count); + } + + [Test] + public void InterfaceToConn_UsesInterfaceDestinationWhenDestinationFilled() + { + ModellingConnection connection = new() + { + Id = 3, + SourceAppServers = [WrapAppServer(210, "AS_src_old")], + DestinationAppServers = [WrapAppServer(310, "AS_dst_old")], + DestinationAppRoles = [WrapAppRole(320, "AR_dst_old")], + DestinationAreas = [WrapArea(330, "Area_dst_old")], + DestinationOtherGroups = [WrapNwGroup(340, "Group_dst_old")] + }; + + ModellingConnection interf = new() + { + Id = 4, + Name = "Interf2", + DestinationAppServers = [WrapAppServer(311, "AS_dst_new")], + DestinationAppRoles = [WrapAppRole(321, "AR_dst_new")], + DestinationAreas = [WrapArea(331, "Area_dst_new")], + DestinationOtherGroups = [WrapNwGroup(341, "Group_dst_new")] + }; + + ModellingConnectionHandler handler = CreateHandler(connection); + + handler.InterfaceToConn(interf); + + ClassicAssert.IsFalse(handler.SrcReadOnly); + ClassicAssert.IsTrue(handler.DstReadOnly); + ClassicAssert.IsTrue(handler.ActConn.DstFromInterface); + ClassicAssert.IsFalse(handler.ActConn.SrcFromInterface); + ClassicAssert.AreEqual(1, handler.DstAppServerToDelete.Count); + ClassicAssert.AreEqual(310, handler.DstAppServerToDelete[0].Id); + ClassicAssert.AreEqual(1, handler.DstAppRolesToDelete.Count); + ClassicAssert.AreEqual(320, handler.DstAppRolesToDelete[0].Id); + ClassicAssert.AreEqual(1, handler.DstAreasToDelete.Count); + ClassicAssert.AreEqual(330, handler.DstAreasToDelete[0].Id); + ClassicAssert.AreEqual(1, handler.DstNwGroupsToDelete.Count); + ClassicAssert.AreEqual(340, handler.DstNwGroupsToDelete[0].Id); + ClassicAssert.AreEqual(311, handler.ActConn.DestinationAppServers[0].Content.Id); + ClassicAssert.AreEqual(321, handler.ActConn.DestinationAppRoles[0].Content.Id); + ClassicAssert.AreEqual(331, handler.ActConn.DestinationAreas[0].Content.Id); + ClassicAssert.AreEqual(341, handler.ActConn.DestinationOtherGroups[0].Content.Id); + ClassicAssert.AreEqual(210, handler.ActConn.SourceAppServers[0].Content.Id); + } + + [Test] + public void InterfaceToConn_SetsInterfaceNoPermission_ByPermissionMode() + { + ModellingConnection connection = new() + { + Id = 33, + AppId = 1, + SourceAppServers = [WrapAppServer(1, "AS")] + }; + + ModellingConnectionHandler handlerRestrictedAllowed = CreateHandler(new(connection)); + handlerRestrictedAllowed.InterfaceToConn(new() + { + Id = 34, + InterfacePermission = InterfacePermissions.Restricted.ToString(), + PermittedOwnerWrappers = [new() { Owner = new FwoOwner { Id = 1 } }], + SourceAppServers = [WrapAppServer(2, "AS2")] + }); + ClassicAssert.IsFalse(handlerRestrictedAllowed.ActConn.InterfaceNoPermission); + + ModellingConnectionHandler handlerRestrictedDenied = CreateHandler(new(connection)); + handlerRestrictedDenied.InterfaceToConn(new() + { + Id = 35, + InterfacePermission = InterfacePermissions.Restricted.ToString(), + PermittedOwnerWrappers = [new() { Owner = new FwoOwner { Id = 2 } }], + SourceAppServers = [WrapAppServer(2, "AS2")] + }); + ClassicAssert.IsTrue(handlerRestrictedDenied.ActConn.InterfaceNoPermission); + + ModellingConnectionHandler handlerPublic = CreateHandler(new(connection)); + handlerPublic.InterfaceToConn(new() + { + Id = 36, + InterfacePermission = InterfacePermissions.Public.ToString(), + PermittedOwnerWrappers = [], + SourceAppServers = [WrapAppServer(2, "AS2")] + }); + ClassicAssert.IsFalse(handlerPublic.ActConn.InterfaceNoPermission); + + ModellingConnectionHandler handlerPrivate = CreateHandler(new(connection)); + handlerPrivate.InterfaceToConn(new() + { + Id = 37, + InterfacePermission = InterfacePermissions.Private.ToString(), + AppId = 1, + PermittedOwnerWrappers = [new() { Owner = new FwoOwner { Id = 1 } }], + SourceAppServers = [WrapAppServer(2, "AS2")] + }); + ClassicAssert.IsFalse(handlerPrivate.ActConn.InterfaceNoPermission); + + ModellingConnectionHandler handlerPrivateForeign = CreateHandler(new(connection)); + handlerPrivateForeign.InterfaceToConn(new() + { + Id = 38, + InterfacePermission = InterfacePermissions.Private.ToString(), + AppId = 2, + PermittedOwnerWrappers = [new() { Owner = new FwoOwner { Id = 1 } }], + SourceAppServers = [WrapAppServer(2, "AS2")] + }); + ClassicAssert.IsTrue(handlerPrivateForeign.ActConn.InterfaceNoPermission); + } + + [Test] + public void RemoveInterf_ClearsInterfaceState() + { + ModellingConnection connection = new() + { + Id = 5, + UsedInterfaceId = 7, + InterfaceIsRequested = true, + InterfaceIsRejected = true, + InterfaceIsDecommissioned = true, + TicketId = 99, + SourceAppServers = [WrapAppServer(1, "AS_src")], + DestinationAppServers = [WrapAppServer(2, "AS_dst")], + Services = [WrapService(3, "Svc")], + ServiceGroups = [WrapServiceGroup(4, "SvcGrp")], + ExtraConfigsFromInterface = [new ModellingExtraConfig() { ExtraConfigType = "X", ExtraConfigText = "Y" }], + SrcFromInterface = true, + DstFromInterface = true + }; + + ModellingConnectionHandler handler = CreateHandler(connection); + handler.InterfaceName = "Interf"; + handler.SrcReadOnly = true; + handler.DstReadOnly = true; + handler.SvcReadOnly = true; + + handler.RemoveInterf(); + + ClassicAssert.AreEqual("", handler.InterfaceName); + ClassicAssert.AreEqual(0, handler.ActConn.SourceAppServers.Count); + ClassicAssert.AreEqual(0, handler.ActConn.DestinationAppServers.Count); + ClassicAssert.AreEqual(0, handler.ActConn.Services.Count); + ClassicAssert.AreEqual(0, handler.ActConn.ServiceGroups.Count); + ClassicAssert.AreEqual(0, handler.ActConn.ExtraConfigsFromInterface.Count); + ClassicAssert.IsNull(handler.ActConn.UsedInterfaceId); + ClassicAssert.IsFalse(handler.ActConn.InterfaceIsRequested); + ClassicAssert.IsFalse(handler.ActConn.InterfaceIsRejected); + ClassicAssert.IsFalse(handler.ActConn.InterfaceIsDecommissioned); + ClassicAssert.IsNull(handler.ActConn.TicketId); + ClassicAssert.IsFalse(handler.SrcReadOnly); + ClassicAssert.IsFalse(handler.DstReadOnly); + ClassicAssert.IsFalse(handler.SvcReadOnly); + ClassicAssert.IsFalse(handler.ActConn.SrcFromInterface); + ClassicAssert.IsFalse(handler.ActConn.DstFromInterface); + } + + [Test] + public void PreparePublishInterface_PublishesRequestedInterface() + { + ModellingConnection connection = new() + { + Id = 6, + IsInterface = true, + IsRequested = true, + IsPublished = false, + InterfacePermission = InterfacePermissions.Public.ToString(), + AppId = null, + ProposedAppId = 77 + }; + + ModellingConnectionHandler handler = CreateHandler(connection); + userConfig.User.Name = "Tester"; + + bool result = handler.PreparePublishInterface(); + + ClassicAssert.IsTrue(result); + ClassicAssert.AreEqual("Tester", handler.ActConn.Creator); + ClassicAssert.IsFalse(handler.ActConn.IsRequested); + ClassicAssert.IsTrue(handler.ActConn.IsPublished); + ClassicAssert.AreEqual(77, handler.ActConn.AppId); + ClassicAssert.IsNull(handler.ActConn.ProposedAppId); + } + + [Test] + public void PreparePublishInterface_PrivateDoesNothing() + { + ModellingConnection connection = new() + { + Id = 7, + IsInterface = true, + IsRequested = true, + IsPublished = false, + InterfacePermission = InterfacePermissions.Private.ToString(), + AppId = null, + ProposedAppId = 88 + }; + + ModellingConnectionHandler handler = CreateHandler(connection); + userConfig.User.Name = "Tester"; + + bool result = handler.PreparePublishInterface(); + + ClassicAssert.IsFalse(result); + ClassicAssert.IsTrue(handler.ActConn.IsRequested); + ClassicAssert.IsFalse(handler.ActConn.IsPublished); + ClassicAssert.IsNull(handler.ActConn.AppId); + ClassicAssert.AreEqual(88, handler.ActConn.ProposedAppId); + } + + [Test] + public async Task RequestReplaceInterface_MismatchShowsErrorAndDoesNotEnableReplace() + { + bool messageRaised = false; + Action displayMessage = (_, __, ___, ____) => messageRaised = true; + + ModellingConnection connection = new() + { + Id = 8, + SourceAppServers = [WrapAppServer(1, "AS_src")] + }; + + ModellingConnection interf = new() + { + Id = 9, + DestinationAppServers = [WrapAppServer(2, "AS_dst")] + }; + + ModellingConnectionHandler handler = new ModellingConnectionHandler( + new ModellingHandlerTestApiConn(), + userConfig, + Application, + [connection], + connection, + false, + false, + displayMessage, + DefaultInit.DoNothing, + true); + + await handler.RequestReplaceInterface(interf); + + ClassicAssert.IsTrue(messageRaised); + ClassicAssert.IsFalse(handler.ReplaceMode); + ClassicAssert.IsFalse(handler.DisplaySelectedInterfaceMode); + ClassicAssert.IsNull(handler.IntConnHandler); + } + + [Test] + public void DisplayInterface_UsesOwnerForDisplayName() + { + ModellingConnection connection = new() { Id = 10 }; + ModellingConnection interf = new() { Id = 11, Name = "InterfName", AppId = 5 }; + + ModellingConnectionHandler handler = CreateHandler(connection); + handler.AllApps = [new FwoOwner { Id = 5, Name = "OwnerName", ExtAppId = "APP-5" }]; + + string result = handler.DisplayInterface(interf); + + ClassicAssert.AreEqual("InterfName (APP-5:OwnerName)", result); + } + + [Test] + public void DisplayInterface_FallsBackToNameWhenOwnerMissing() + { + ModellingConnection connection = new() { Id = 12 }; + ModellingConnection interf = new() { Id = 13, Name = "InterfOnly", AppId = 5 }; + + ModellingConnectionHandler handler = CreateHandler(connection); + handler.AllApps = [new FwoOwner { Id = 6, Name = "OtherOwner", ExtAppId = "APP-6" }]; + + string result = handler.DisplayInterface(interf); + + ClassicAssert.AreEqual("InterfOnly", result); + } + + [Test] + public void DisplayInterface_ReturnsEmptyWhenNull() + { + ModellingConnection connection = new() { Id = 14 }; + ModellingConnectionHandler handler = CreateHandler(connection); + + ClassicAssert.AreEqual("", handler.DisplayInterface(null)); + } + + [Test] + public void InterfaceAllowedWithNetworkArea_AllowsWhenInterfaceFlagSet() + { + ModellingConnection connection = new() + { + Id = 15, + IsInterface = true, + AppId = 1, + SourceAreas = [WrapArea(1, "Area_src")] + }; + ModellingConnectionHandler handler = CreateHandler(connection); + handler.DstAreasToAdd.Add(WrapArea(2, "Area_dst").Content); + + ModellingConnection interf = new() { AppId = 99 }; + + ClassicAssert.IsTrue(handler.InterfaceAllowedWithNetworkArea(interf)); + } + + [Test] + public void InterfaceAllowedWithNetworkArea_BlocksDifferentAppWhenAreasPresent() + { + ModellingConnection connection = new() + { + Id = 16, + AppId = 1, + SourceAreas = [WrapArea(1, "Area_src")] + }; + ModellingConnectionHandler handler = CreateHandler(connection); + + ModellingConnection interf = new() { AppId = 2 }; + + ClassicAssert.IsFalse(handler.InterfaceAllowedWithNetworkArea(interf)); + } + + [Test] + public void InterfaceAllowedWithNetworkArea_AllowsDifferentAppWhenNoAreasPresent() + { + ModellingConnection connection = new() + { + Id = 17, + AppId = 1 + }; + ModellingConnectionHandler handler = CreateHandler(connection); + + ModellingConnection interf = new() { AppId = 2 }; + + ClassicAssert.IsTrue(handler.InterfaceAllowedWithNetworkArea(interf)); + } + + [Test] + public void IsNotInterfaceForeignToApp_BlocksWhenPreselectedInterfaceFromOtherApp() + { + ModellingConnection connection = new() + { + Id = 18, + AppId = 1, + UsedInterfaceId = 42 + }; + ModellingConnectionHandler handler = CreateHandler(connection); + handler.PreselectedInterfaces = [new ModellingConnection { Id = 42, AppId = 2 }]; + + ClassicAssert.IsFalse(handler.IsNotInterfaceForeignToApp()); + } + + [Test] + public void IsNotInterfaceForeignToApp_AllowsWhenPreselectedInterfaceFromSameApp() + { + ModellingConnection connection = new() + { + Id = 19, + AppId = 1, + UsedInterfaceId = 42 + }; + ModellingConnectionHandler handler = CreateHandler(connection); + handler.PreselectedInterfaces = [new ModellingConnection { Id = 42, AppId = 1 }]; + + ClassicAssert.IsTrue(handler.IsNotInterfaceForeignToApp()); + } + + private static ModellingConnectionHandler CreateHandler(ModellingConnection connection) + { + return new ModellingConnectionHandler(new ModellingHandlerTestApiConn(), userConfig, Application, [connection], connection, false, false, DisplayMessageInUi, DefaultInit.DoNothing, true); + } + + private static ModellingAppServerWrapper WrapAppServer(long id, string name) + { + return new ModellingAppServerWrapper { Content = new ModellingAppServer { Id = id, Name = name } }; + } + + private static ModellingAppRoleWrapper WrapAppRole(long id, string name) + { + return new ModellingAppRoleWrapper { Content = new ModellingAppRole { Id = id, Name = name } }; + } + + private static ModellingNetworkAreaWrapper WrapArea(long id, string name) + { + return new ModellingNetworkAreaWrapper { Content = new ModellingNetworkArea { Id = id, Name = name, IdString = $"NA{id}" } }; + } + + private static ModellingNwGroupWrapper WrapNwGroup(long id, string name) + { + return new ModellingNwGroupWrapper { Content = new ModellingNwGroup { Id = id, Name = name, IdString = $"GR{id}" } }; + } + + private static ModellingServiceWrapper WrapService(int id, string name) + { + return new ModellingServiceWrapper { Content = new ModellingService { Id = id, Name = name } }; + } + + private static ModellingServiceGroupWrapper WrapServiceGroup(int id, string name) + { + return new ModellingServiceGroupWrapper { Content = new ModellingServiceGroup { Id = id, Name = name } }; + } + } +} diff --git a/roles/tests-unit/files/FWO.Test/ModellingConnectionHandlerInterfaceInternalTest.cs b/roles/tests-unit/files/FWO.Test/ModellingConnectionHandlerInterfaceInternalTest.cs new file mode 100644 index 0000000000..4a4dd33935 --- /dev/null +++ b/roles/tests-unit/files/FWO.Test/ModellingConnectionHandlerInterfaceInternalTest.cs @@ -0,0 +1,279 @@ +using NUnit.Framework; +using NUnit.Framework.Legacy; +using FWO.Data; +using FWO.Data.Modelling; +using FWO.Services; +using FWO.Services.Modelling; +using FWO.Basics; +using FWO.Api.Client.Queries; +using System; +using System.Collections.Generic; +using System.Reflection; +using System.Threading.Tasks; + +namespace FWO.Test +{ + [TestFixture] + [Parallelizable] + internal class ModellingConnectionHandlerInterfaceInternalTest + { + static readonly SimulatedUserConfig userConfig = new(); + static readonly Action DisplayMessageInUi = DefaultInit.DoNothing; + static readonly FwoOwner Application = new() { Id = 1, Name = "TestApp" }; + + [Test] + public void CheckInterface_FailsWhenOnlyDummyAndNoServices() + { + ModellingAppRole dummy = new() { Id = 999, Name = "Dummy" }; + ModellingConnection connection = new() + { + Id = 1, + IsInterface = true, + SourceAppRoles = [new() { Content = dummy }] + }; + + ModellingConnectionHandler handler = CreateHandler(connection, addMode: true); + handler.DummyAppRole = dummy; + + bool result = InvokePrivateBool(handler, "CheckInterface"); + + ClassicAssert.IsFalse(result); + } + + [Test] + public void CheckInterface_FailsWhenPermissionMissing_ShowsE9021() + { + ModellingConnection connection = new() + { + Id = 7, + IsInterface = true, + InterfacePermission = "" + }; + + string? message = null; + ModellingConnectionHandler handler = CreateHandler(connection, addMode: true, + (exception, title, text, isError) => message = text); + + bool result = InvokePrivateBool(handler, "CheckInterface"); + + ClassicAssert.IsFalse(result); + ClassicAssert.AreEqual(userConfig.GetText("E9021"), message); + } + + [Test] + public void CheckInterface_FailsWhenPrivateAndUsedByOtherApp() + { + ModellingConnection connection = new() + { + Id = 2, + IsInterface = true, + AppId = 1, + InterfacePermission = InterfacePermissions.Public.ToString(), + SourceAreas = [WrapArea(10, "Area1")], + Services = [WrapService(20, "Svc1")] + }; + + ModellingConnectionHandler handler = CreateHandler(connection, addMode: false); + handler.UsingConnections = [new ModellingConnection { AppId = 2 }]; + handler.ActConn.InterfacePermission = InterfacePermissions.Private.ToString(); + + bool result = InvokePrivateBool(handler, "CheckInterface"); + + ClassicAssert.IsFalse(result); + } + + [Test] + public void CheckInterface_FailsWhenSrcDstChanged_ShowsE9005() + { + ModellingConnection connection = new() + { + Id = 8, + IsInterface = true, + AppId = 1, + InterfacePermission = InterfacePermissions.Public.ToString(), + Services = [WrapService(30, "Svc1")] + }; + + string? message = null; + ModellingConnectionHandler handler = CreateHandler(connection, addMode: false, + (exception, title, text, isError) => message = text); + + handler.ActConn.SourceAreas = [WrapArea(30, "Area1")]; + + bool result = InvokePrivateBool(handler, "CheckInterface"); + + ClassicAssert.IsFalse(result); + ClassicAssert.AreEqual(userConfig.GetText("E9005"), message); + } + + [Test] + public void CheckInterface_PassesWhenFilledAndNoPrivateConflict() + { + ModellingConnection connection = new() + { + Id = 3, + IsInterface = true, + AppId = 1, + InterfacePermission = InterfacePermissions.Public.ToString(), + SourceAreas = [WrapArea(11, "Area1")], + Services = [WrapService(21, "Svc1")] + }; + + ModellingConnectionHandler handler = CreateHandler(connection, addMode: false); + + bool result = InvokePrivateBool(handler, "CheckInterface"); + + ClassicAssert.IsTrue(result); + } + + [Test] + public void SyncSrcChanges_RemovesDummyMarkerWhenFilled() + { + ModellingAppRole dummy = new() { Id = 999, Name = "Dummy" }; + ModellingConnection connection = new() + { + Id = 4, + IsInterface = true, + SourceAppRoles = [new() { Content = dummy }] + }; + + ModellingConnectionHandler handler = CreateHandler(connection, addMode: false); + handler.DummyAppRole = dummy; + handler.SrcAreasToAdd.Add(new ModellingNetworkArea { Id = 10, Name = "Area1", IdString = "NA10" }); + + InvokePrivateVoid(handler, "SyncSrcChanges"); + + ClassicAssert.IsTrue(handler.SrcAppRolesToDelete.Any(r => r.Id == dummy.Id)); + ClassicAssert.IsFalse(handler.ActConn.SourceAppRoles.Any(r => r.Content.Id == dummy.Id)); + ClassicAssert.IsTrue(handler.ActConn.SourceAreas.Any(a => a.Content.Id == 10)); + } + + [Test] + public void SyncDstChanges_RemovesDummyMarkerWhenFilled() + { + ModellingAppRole dummy = new() { Id = 999, Name = "Dummy" }; + ModellingConnection connection = new() + { + Id = 5, + IsInterface = true, + DestinationAppRoles = [new() { Content = dummy }] + }; + + ModellingConnectionHandler handler = CreateHandler(connection, addMode: false); + handler.DummyAppRole = dummy; + handler.DstAreasToAdd.Add(new ModellingNetworkArea { Id = 20, Name = "Area2", IdString = "NA20" }); + + InvokePrivateVoid(handler, "SyncDstChanges"); + + ClassicAssert.IsTrue(handler.DstAppRolesToDelete.Any(r => r.Id == dummy.Id)); + ClassicAssert.IsFalse(handler.ActConn.DestinationAppRoles.Any(r => r.Content.Id == dummy.Id)); + ClassicAssert.IsTrue(handler.ActConn.DestinationAreas.Any(a => a.Content.Id == 20)); + } + + [Test] + public async Task CreateNewRequestedInterface_AddsDummyAndPreselects() + { + InterfaceInternalTestApiConn apiConnection = new() { NewConnectionId = 101 }; + ModellingConnection connection = new() { Id = 6, Name = "Base" }; + ModellingConnectionHandler handler = new(apiConnection, userConfig, Application, [connection], connection, true, false, DisplayMessageInUi, DefaultInit.DoNothing, true) + { + DummyAppRole = new ModellingAppRole { Id = 999, Name = "Dummy" }, + RequesterId = 42 + }; + + long newId = await handler.CreateNewRequestedInterface(123, true, "NewInterface", "Need it"); + + ClassicAssert.AreEqual(101, newId); + ClassicAssert.IsTrue(handler.ActConn.IsInterface); + ClassicAssert.IsTrue(handler.ActConn.IsRequested); + ClassicAssert.IsTrue(handler.ActConn.Name?.Contains("Ticket: 123") ?? false); + ClassicAssert.IsTrue(handler.ActConn.Reason?.Contains("Need it") ?? false); + ClassicAssert.IsTrue(handler.ActConn.SourceAppRoles.Any(r => r.Content.Id == 999)); + ClassicAssert.AreEqual(42, handler.ActConn.AppId); + ClassicAssert.AreEqual(1, handler.PreselectedInterfaces.Count); + ClassicAssert.AreEqual(42, apiConnection.SelectedAppId); + ClassicAssert.AreEqual(101, apiConnection.SelectedConnectionId); + } + + private static ModellingConnectionHandler CreateHandler(ModellingConnection connection, bool addMode, + Action? displayMessageInUi = null) + { + return new ModellingConnectionHandler(new ModellingHandlerTestApiConn(), userConfig, Application, [connection], connection, addMode, false, displayMessageInUi ?? DisplayMessageInUi, DefaultInit.DoNothing, true); + } + + private static bool InvokePrivateBool(ModellingConnectionHandler handler, string methodName) + { + MethodInfo? method = typeof(ModellingConnectionHandler).GetMethod(methodName, BindingFlags.NonPublic | BindingFlags.Instance); + ClassicAssert.IsNotNull(method, $"Expected to find method '{methodName}'."); + return (bool)method!.Invoke(handler, null)!; + } + + private static void InvokePrivateVoid(ModellingConnectionHandler handler, string methodName) + { + MethodInfo? method = typeof(ModellingConnectionHandler).GetMethod(methodName, BindingFlags.NonPublic | BindingFlags.Instance); + ClassicAssert.IsNotNull(method, $"Expected to find method '{methodName}'."); + method!.Invoke(handler, null); + } + + private static ModellingNetworkAreaWrapper WrapArea(long id, string name) + { + return new ModellingNetworkAreaWrapper { Content = new ModellingNetworkArea { Id = id, Name = name, IdString = $"NA{id}" } }; + } + + private static ModellingServiceWrapper WrapService(int id, string name) + { + return new ModellingServiceWrapper { Content = new ModellingService { Id = id, Name = name } }; + } + } + + internal class InterfaceInternalTestApiConn : SimulatedApiConnection + { + public int NewConnectionId { get; set; } = 100; + public int SelectedAppId { get; private set; } + public int SelectedConnectionId { get; private set; } + + public override Task SendQueryAsync(string query, object? variables = null, string? operationName = null) + { + Type responseType = typeof(QueryResponseType); + if (query == ModellingQueries.newConnection) + { + return Task.FromResult((QueryResponseType)(object)new ReturnIdWrapper + { + ReturnIds = [new ReturnId { NewId = NewConnectionId }] + }); + } + if (query == ModellingQueries.addSelectedConnection) + { + SelectedAppId = GetIntVariable(variables, "appId"); + SelectedConnectionId = GetIntVariable(variables, "connectionId"); + return Task.FromResult((QueryResponseType)(object)new ReturnIdWrapper + { + ReturnIds = [new ReturnId { InsertedId = SelectedConnectionId }] + }); + } + if (query == ModellingQueries.addNwGroupToConnection) + { + return Task.FromResult((QueryResponseType)(object)new ReturnId { AffectedRows = 1 }); + } + if (query == ModellingQueries.addHistoryEntry) + { + return Task.FromResult((QueryResponseType)(object)new ReturnIdWrapper + { + ReturnIds = [new ReturnId { AffectedRows = 1 }] + }); + } + + throw new NotImplementedException(); + } + + private static int GetIntVariable(object? variables, string name) + { + if (variables == null) + { + return 0; + } + object? value = variables.GetType().GetProperties().FirstOrDefault(p => p.Name == name)?.GetValue(variables); + return value == null ? 0 : Convert.ToInt32(value); + } + } +} diff --git a/roles/tests-unit/files/FWO.Test/ModellingConnectionHandlerNwObjHandlingTest.cs b/roles/tests-unit/files/FWO.Test/ModellingConnectionHandlerNwObjHandlingTest.cs new file mode 100644 index 0000000000..f5e66577d2 --- /dev/null +++ b/roles/tests-unit/files/FWO.Test/ModellingConnectionHandlerNwObjHandlingTest.cs @@ -0,0 +1,489 @@ +using NUnit.Framework; +using NUnit.Framework.Legacy; +using FWO.Data; +using FWO.Data.Modelling; +using FWO.Services; +using FWO.Services.Modelling; +using FWO.Basics; +using FWO.Config.Api.Data; +using System.Collections.Generic; +using System.Linq; +using System.Reflection; + +namespace FWO.Test +{ + [TestFixture] + [Parallelizable] + internal class ModellingConnectionHandlerNwObjHandlingTest + { + static readonly SimulatedUserConfig userConfig = new(); + static readonly Action DisplayMessageInUi = DefaultInit.DoNothing; + static readonly FwoOwner Application = new() { Id = 1, Name = "TestApp" }; + + [Test] + public void RefreshSelectableNwObjects_IncludesCommonSelectedRolesAndServers() + { + ModellingConnection connection = new() { Id = 1 }; + SimulatedUserConfig localConfig = new() { AllowServerInConn = true }; + ModellingConnectionHandler handler = CreateHandler(connection, localConfig); + + handler.AvailableCommonAreas = + [ + new ModellingNetworkAreaWrapper { Content = new ModellingNetworkArea { Id = 10, Name = "Area1", IdString = "NA10", GroupType = (int)ModellingTypes.ModObjectType.NetworkArea } } + ]; + handler.AvailableSelectedObjects = + [ + new ModellingNwGroupWrapper { Content = new ModellingNwGroup { Id = 20, Name = "Group1", GroupType = (int)ModellingTypes.ModObjectType.Network } } + ]; + handler.AvailableAppRoles = + [ + new ModellingAppRole { Id = 30, Name = "Role1" } + ]; + handler.AvailableAppServers = + [ + new ModellingAppServer { Id = 40, Name = "Srv1", IsDeleted = false }, + new ModellingAppServer { Id = 41, Name = "Srv2", IsDeleted = true } + ]; + + bool result = handler.RefreshSelectableNwObjects(); + + ClassicAssert.IsTrue(result); + ClassicAssert.AreEqual(4, handler.AvailableNwElems.Count); + ClassicAssert.IsTrue(handler.AvailableNwElems.Contains(new KeyValuePair((int)ModellingTypes.ModObjectType.NetworkArea, 10))); + ClassicAssert.IsTrue(handler.AvailableNwElems.Contains(new KeyValuePair((int)ModellingTypes.ModObjectType.Network, 20))); + ClassicAssert.IsTrue(handler.AvailableNwElems.Contains(new KeyValuePair((int)ModellingTypes.ModObjectType.AppRole, 30))); + ClassicAssert.IsTrue(handler.AvailableNwElems.Contains(new KeyValuePair((int)ModellingTypes.ModObjectType.AppServer, 40))); + } + + [Test] + public void SyncSrcChanges_AddsAndRemovesObjects() + { + ModellingConnection connection = new() + { + Id = 2, + SourceAppServers = [WrapAppServer(1, "SrvOld")], + SourceAppRoles = [WrapAppRole(2, "RoleOld")], + SourceAreas = [WrapArea(3, "AreaOld")], + SourceOtherGroups = [WrapNwGroup(4, "GroupOld")] + }; + ModellingConnectionHandler handler = CreateHandler(connection); + + handler.SrcAppServerToDelete.Add(new ModellingAppServer { Id = 1 }); + handler.SrcAppRolesToDelete.Add(new ModellingAppRole { Id = 2 }); + handler.SrcAreasToDelete.Add(new ModellingNetworkArea { Id = 3 }); + handler.SrcNwGroupsToDelete.Add(new ModellingNwGroup { Id = 4 }); + + handler.SrcAppServerToAdd.Add(new ModellingAppServer { Id = 11, Name = "SrvNew" }); + handler.SrcAppRolesToAdd.Add(new ModellingAppRole { Id = 12, Name = "RoleNew" }); + handler.SrcAreasToAdd.Add(new ModellingNetworkArea { Id = 13, Name = "AreaNew", IdString = "NA13" }); + handler.SrcNwGroupsToAdd.Add(new ModellingNwGroup { Id = 14, Name = "GroupNew", IdString = "GR14" }); + + InvokePrivateVoid(handler, "SyncSrcChanges"); + + ClassicAssert.AreEqual(1, handler.ActConn.SourceAppServers.Count); + ClassicAssert.AreEqual(11, handler.ActConn.SourceAppServers[0].Content.Id); + ClassicAssert.AreEqual(1, handler.ActConn.SourceAppRoles.Count); + ClassicAssert.AreEqual(12, handler.ActConn.SourceAppRoles[0].Content.Id); + ClassicAssert.AreEqual(1, handler.ActConn.SourceAreas.Count); + ClassicAssert.AreEqual(13, handler.ActConn.SourceAreas[0].Content.Id); + ClassicAssert.AreEqual(1, handler.ActConn.SourceOtherGroups.Count); + ClassicAssert.AreEqual(14, handler.ActConn.SourceOtherGroups[0].Content.Id); + } + + [Test] + public void SyncDstChanges_AddsAndRemovesObjects() + { + ModellingConnection connection = new() + { + Id = 3, + DestinationAppServers = [WrapAppServer(21, "SrvOld")], + DestinationAppRoles = [WrapAppRole(22, "RoleOld")], + DestinationAreas = [WrapArea(23, "AreaOld")], + DestinationOtherGroups = [WrapNwGroup(24, "GroupOld")] + }; + ModellingConnectionHandler handler = CreateHandler(connection); + + handler.DstAppServerToDelete.Add(new ModellingAppServer { Id = 21 }); + handler.DstAppRolesToDelete.Add(new ModellingAppRole { Id = 22 }); + handler.DstAreasToDelete.Add(new ModellingNetworkArea { Id = 23 }); + handler.DstNwGroupsToDelete.Add(new ModellingNwGroup { Id = 24 }); + + handler.DstAppServerToAdd.Add(new ModellingAppServer { Id = 31, Name = "SrvNew" }); + handler.DstAppRolesToAdd.Add(new ModellingAppRole { Id = 32, Name = "RoleNew" }); + handler.DstAreasToAdd.Add(new ModellingNetworkArea { Id = 33, Name = "AreaNew", IdString = "NA33" }); + handler.DstNwGroupsToAdd.Add(new ModellingNwGroup { Id = 34, Name = "GroupNew", IdString = "GR34" }); + + InvokePrivateVoid(handler, "SyncDstChanges"); + + ClassicAssert.AreEqual(1, handler.ActConn.DestinationAppServers.Count); + ClassicAssert.AreEqual(31, handler.ActConn.DestinationAppServers[0].Content.Id); + ClassicAssert.AreEqual(1, handler.ActConn.DestinationAppRoles.Count); + ClassicAssert.AreEqual(32, handler.ActConn.DestinationAppRoles[0].Content.Id); + ClassicAssert.AreEqual(1, handler.ActConn.DestinationAreas.Count); + ClassicAssert.AreEqual(33, handler.ActConn.DestinationAreas[0].Content.Id); + ClassicAssert.AreEqual(1, handler.ActConn.DestinationOtherGroups.Count); + ClassicAssert.AreEqual(34, handler.ActConn.DestinationOtherGroups[0].Content.Id); + } + + [Test] + public void NetworkAreaUseAllowed_BlocksWhenOtherSideHasAreas() + { + ModellingConnection connection = new() + { + Id = 4, + DestinationAreas = [WrapArea(10, "AreaDst")] + }; + ModellingConnectionHandler handler = CreateHandler(connection); + + bool result = handler.NetworkAreaUseAllowed([new ModellingNetworkArea { Id = 1 }], Direction.Source, out var reason); + + ClassicAssert.IsFalse(result); + ClassicAssert.AreEqual("Edit Connection", reason.Title); + ClassicAssert.AreEqual("Network areas on other side", reason.Text); + } + + [Test] + public void NetworkAreaUseAllowed_BlocksForInterfaces() + { + ModellingConnection connection = new() + { + Id = 5, + IsInterface = true + }; + ModellingConnectionHandler handler = CreateHandler(connection); + + bool result = handler.NetworkAreaUseAllowed([new ModellingNetworkArea { Id = 1 }], Direction.Source, out var reason); + + ClassicAssert.IsFalse(result); + ClassicAssert.AreEqual("Edit Interface", reason.Title); + ClassicAssert.AreEqual("Interfaces cannot use areas", reason.Text); + } + + [Test] + public void NetworkAreaUseAllowed_AllowsCommonServiceWithoutCommonAreas() + { + ModellingConnection connection = new() + { + Id = 6, + IsCommonService = true + }; + ModellingConnectionHandler handler = CreateHandler(connection); + handler.CommonAreaConfigItems = [new CommonAreaConfig { AreaId = 100 }]; + + bool result = handler.NetworkAreaUseAllowed([new ModellingNetworkArea { Id = 1 }], Direction.Source, out var reason); + + ClassicAssert.IsTrue(result); + ClassicAssert.AreEqual("Edit Common Service", reason.Title); + ClassicAssert.AreEqual("", reason.Text); + } + + [Test] + public void NetworkAreaUseAllowed_AllowsCommonAreasOnNormalConnection() + { + ModellingConnection connection = new() { Id = 7 }; + ModellingConnectionHandler handler = CreateHandler(connection); + handler.CommonAreaConfigItems = [new CommonAreaConfig { AreaId = 1 }]; + + bool result = handler.NetworkAreaUseAllowed([new ModellingNetworkArea { Id = 1 }], Direction.Source, out var reason); + + ClassicAssert.IsTrue(result); + ClassicAssert.AreEqual("Edit Connection", reason.Title); + } + + [Test] + public void NetworkAreaUseAllowed_BlocksWhenCommonAreasNotAllowed() + { + ModellingConnection connection = new() { Id = 8 }; + ModellingConnectionHandler handler = CreateHandler(connection); + handler.CommonAreaConfigItems = [new CommonAreaConfig { AreaId = 1 }]; + + bool result = handler.NetworkAreaUseAllowed([new ModellingNetworkArea { Id = 2 }], Direction.Source, out var reason); + + ClassicAssert.IsFalse(result); + ClassicAssert.AreEqual("Common areas not allowed", reason.Text); + } + + [Test] + public void AppServerToSource_AddsNonDeletedAndSkipsExisting() + { + ModellingConnection connection = new() + { + Id = 9, + SourceAppServers = [WrapAppServer(1, "SrvExisting")] + }; + ModellingConnectionHandler handler = CreateHandler(connection); + handler.SrcReadOnly = false; + + handler.AppServerToSource( + [ + new ModellingAppServer { Id = 1, Name = "SrvExisting", IsDeleted = false }, + new ModellingAppServer { Id = 2, Name = "SrvNew", IsDeleted = false }, + new ModellingAppServer { Id = 3, Name = "SrvDeleted", IsDeleted = true } + ]); + + ClassicAssert.AreEqual(1, handler.SrcAppServerToAdd.Count); + ClassicAssert.AreEqual(2, handler.SrcAppServerToAdd[0].Id); + } + + [Test] + public void AppServerToDestination_AddsNonDeletedAndSkipsExisting() + { + ModellingConnection connection = new() + { + Id = 10, + DestinationAppServers = [WrapAppServer(1, "SrvExisting")] + }; + ModellingConnectionHandler handler = CreateHandler(connection); + handler.DstReadOnly = false; + + handler.AppServerToDestination( + [ + new ModellingAppServer { Id = 1, Name = "SrvExisting", IsDeleted = false }, + new ModellingAppServer { Id = 2, Name = "SrvNew", IsDeleted = false }, + new ModellingAppServer { Id = 3, Name = "SrvDeleted", IsDeleted = true } + ]); + + ClassicAssert.AreEqual(1, handler.DstAppServerToAdd.Count); + ClassicAssert.AreEqual(2, handler.DstAppServerToAdd[0].Id); + } + + [Test] + public void AreasToSource_AddsWhenAllowedAndNotExisting() + { + ModellingConnection connection = new() + { + Id = 11, + SourceAreas = [WrapArea(1, "AreaExisting")] + }; + ModellingConnectionHandler handler = CreateHandler(connection); + handler.SrcReadOnly = false; + + handler.AreasToSource( + [ + new ModellingNetworkArea { Id = 1, Name = "AreaExisting", IdString = "NA1" }, + new ModellingNetworkArea { Id = 2, Name = "AreaNew", IdString = "NA2" } + ]); + + ClassicAssert.AreEqual(1, handler.SrcAreasToAdd.Count); + ClassicAssert.AreEqual(2, handler.SrcAreasToAdd[0].Id); + } + + [Test] + public void AreasToSource_SkipsWhenCommonAreaConfigDisallows() + { + ModellingConnection connection = new() + { + Id = 12 + }; + ModellingConnectionHandler handler = CreateHandler(connection); + handler.SrcReadOnly = false; + handler.CommonAreaConfigItems = [new CommonAreaConfig { AreaId = 2, UseInSrc = false }]; + + handler.AreasToSource( + [ + new ModellingNetworkArea { Id = 2, Name = "AreaBlocked", IdString = "NA2" } + ]); + + ClassicAssert.AreEqual(0, handler.SrcAreasToAdd.Count); + } + + [Test] + public void AreasToDestination_AddsWhenAllowedAndNotExisting() + { + ModellingConnection connection = new() + { + Id = 13, + DestinationAreas = [WrapArea(1, "AreaExisting")] + }; + ModellingConnectionHandler handler = CreateHandler(connection); + handler.DstReadOnly = false; + + handler.AreasToDestination( + [ + new ModellingNetworkArea { Id = 1, Name = "AreaExisting", IdString = "NA1" }, + new ModellingNetworkArea { Id = 2, Name = "AreaNew", IdString = "NA2" } + ]); + + ClassicAssert.AreEqual(1, handler.DstAreasToAdd.Count); + ClassicAssert.AreEqual(2, handler.DstAreasToAdd[0].Id); + } + + [Test] + public void AreasToDestination_SkipsWhenCommonAreaConfigDisallows() + { + ModellingConnection connection = new() + { + Id = 14 + }; + ModellingConnectionHandler handler = CreateHandler(connection); + handler.DstReadOnly = false; + handler.CommonAreaConfigItems = [new CommonAreaConfig { AreaId = 3, UseInSrc = false }]; + + handler.AreasToDestination( + [ + new ModellingNetworkArea { Id = 3, Name = "AreaBlocked", IdString = "NA3" } + ]); + + ClassicAssert.AreEqual(0, handler.DstAreasToAdd.Count); + } + + [Test] + public void NwGroupToSource_AddsWhenAllowedAndNotExisting() + { + ModellingConnection connection = new() + { + Id = 15, + SourceOtherGroups = [WrapNwGroup(1, "GroupExisting")] + }; + ModellingConnectionHandler handler = CreateHandler(connection); + handler.SrcReadOnly = false; + + handler.NwGroupToSource( + [ + new ModellingNwGroup { Id = 1, Name = "GroupExisting", IdString = "GR1" }, + new ModellingNwGroup { Id = 2, Name = "GroupNew", IdString = "GR2" } + ]); + + ClassicAssert.AreEqual(1, handler.SrcNwGroupsToAdd.Count); + ClassicAssert.AreEqual(2, handler.SrcNwGroupsToAdd[0].Id); + } + + [Test] + public void NwGroupToSource_SkipsWhenCommonAreaConfigDisallows() + { + ModellingConnection connection = new() + { + Id = 16 + }; + ModellingConnectionHandler handler = CreateHandler(connection); + handler.SrcReadOnly = false; + handler.CommonAreaConfigItems = [new CommonAreaConfig { AreaId = 2, UseInSrc = false }]; + + handler.NwGroupToSource( + [ + new ModellingNwGroup { Id = 2, Name = "GroupBlocked", IdString = "GR2" } + ]); + + ClassicAssert.AreEqual(0, handler.SrcNwGroupsToAdd.Count); + } + + [Test] + public void NwGroupToDestination_AddsWhenAllowedAndNotExisting() + { + ModellingConnection connection = new() + { + Id = 17, + DestinationOtherGroups = [WrapNwGroup(1, "GroupExisting")] + }; + ModellingConnectionHandler handler = CreateHandler(connection); + handler.DstReadOnly = false; + + handler.NwGroupToDestination( + [ + new ModellingNwGroup { Id = 1, Name = "GroupExisting", IdString = "GR1" }, + new ModellingNwGroup { Id = 2, Name = "GroupNew", IdString = "GR2" } + ]); + + ClassicAssert.AreEqual(1, handler.DstNwGroupsToAdd.Count); + ClassicAssert.AreEqual(2, handler.DstNwGroupsToAdd[0].Id); + } + + [Test] + public void NwGroupToDestination_SkipsWhenCommonAreaConfigDisallows() + { + ModellingConnection connection = new() + { + Id = 18 + }; + ModellingConnectionHandler handler = CreateHandler(connection); + handler.DstReadOnly = false; + handler.CommonAreaConfigItems = [new CommonAreaConfig { AreaId = 2, UseInDst = false }]; + + handler.NwGroupToDestination( + [ + new ModellingNwGroup { Id = 2, Name = "GroupBlocked", IdString = "GR2" } + ]); + + ClassicAssert.AreEqual(0, handler.DstNwGroupsToAdd.Count); + } + + [Test] + public void AppRolesToSource_AddsWhenNotExisting() + { + ModellingConnection connection = new() + { + Id = 19, + SourceAppRoles = [WrapAppRole(1, "RoleExisting")] + }; + ModellingConnectionHandler handler = CreateHandler(connection); + handler.SrcReadOnly = false; + + handler.AppRolesToSource( + [ + new ModellingAppRole { Id = 1, Name = "RoleExisting" }, + new ModellingAppRole { Id = 2, Name = "RoleNew" } + ]); + + ClassicAssert.AreEqual(1, handler.SrcAppRolesToAdd.Count); + ClassicAssert.AreEqual(2, handler.SrcAppRolesToAdd[0].Id); + } + + [Test] + public void AppRolesToDestination_AddsWhenNotExisting() + { + ModellingConnection connection = new() + { + Id = 20, + DestinationAppRoles = [WrapAppRole(1, "RoleExisting")] + }; + ModellingConnectionHandler handler = CreateHandler(connection); + handler.DstReadOnly = false; + + handler.AppRolesToDestination( + [ + new ModellingAppRole { Id = 1, Name = "RoleExisting" }, + new ModellingAppRole { Id = 2, Name = "RoleNew" } + ]); + + ClassicAssert.AreEqual(1, handler.DstAppRolesToAdd.Count); + ClassicAssert.AreEqual(2, handler.DstAppRolesToAdd[0].Id); + } + + private static ModellingConnectionHandler CreateHandler(ModellingConnection connection) + { + return new ModellingConnectionHandler(new ModellingHandlerTestApiConn(), userConfig, Application, [connection], connection, false, false, DisplayMessageInUi, DefaultInit.DoNothing, true); + } + + private static ModellingConnectionHandler CreateHandler(ModellingConnection connection, SimulatedUserConfig config) + { + return new ModellingConnectionHandler(new ModellingHandlerTestApiConn(), config, Application, [connection], connection, false, false, DisplayMessageInUi, DefaultInit.DoNothing, true); + } + + private static void InvokePrivateVoid(ModellingConnectionHandler handler, string methodName) + { + MethodInfo? method = typeof(ModellingConnectionHandler).GetMethod(methodName, BindingFlags.NonPublic | BindingFlags.Instance); + ClassicAssert.IsNotNull(method, $"Expected to find method '{methodName}'."); + method!.Invoke(handler, null); + } + + private static ModellingNetworkAreaWrapper WrapArea(long id, string name) + { + return new ModellingNetworkAreaWrapper { Content = new ModellingNetworkArea { Id = id, Name = name, IdString = $"NA{id}" } }; + } + + private static ModellingAppServerWrapper WrapAppServer(long id, string name) + { + return new ModellingAppServerWrapper { Content = new ModellingAppServer { Id = id, Name = name } }; + } + + private static ModellingAppRoleWrapper WrapAppRole(long id, string name) + { + return new ModellingAppRoleWrapper { Content = new ModellingAppRole { Id = id, Name = name } }; + } + + private static ModellingNwGroupWrapper WrapNwGroup(long id, string name) + { + return new ModellingNwGroupWrapper { Content = new ModellingNwGroup { Id = id, Name = name, IdString = $"GR{id}" } }; + } + } +} diff --git a/roles/tests-unit/files/FWO.Test/ModellingConnectionHandlerPermissionHandlingTest.cs b/roles/tests-unit/files/FWO.Test/ModellingConnectionHandlerPermissionHandlingTest.cs new file mode 100644 index 0000000000..24578a9202 --- /dev/null +++ b/roles/tests-unit/files/FWO.Test/ModellingConnectionHandlerPermissionHandlingTest.cs @@ -0,0 +1,222 @@ +using NUnit.Framework; +using NUnit.Framework.Legacy; +using FWO.Data; +using FWO.Data.Modelling; +using FWO.Services; +using FWO.Services.Modelling; +using FWO.Basics; +using FWO.Api.Client.Queries; +using System.Reflection; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; + +namespace FWO.Test +{ + [TestFixture] + [Parallelizable] + internal class ModellingConnectionHandlerPermissionHandlingTest + { + static readonly SimulatedUserConfig userConfig = new(); + static readonly Action DisplayMessageInUi = DefaultInit.DoNothing; + static readonly FwoOwner Application = new() { Id = 1, Name = "TestApp" }; + + [Test] + public async Task EnsureUsingAppsPermittedIfRestricted_AddsMissingOwners() + { + ModellingConnectionHandlerPermissionTestApiConn apiConnection = new(); + apiConnection.InterfaceUsers = + [ + new() { AppId = 1 }, + new() { AppId = 2 }, + new() { AppId = 3 }, + new() { AppId = 3 }, + new() { AppId = null } + ]; + + FwoOwner owner1 = new() { Id = 1, Name = "Owner1" }; + FwoOwner owner2 = new() { Id = 2, Name = "Owner2" }; + FwoOwner owner3 = new() { Id = 3, Name = "Owner3" }; + + ModellingConnection connection = new() + { + Id = 10, + IsInterface = true, + InterfacePermission = InterfacePermissions.Public.ToString(), + PermittedOwners = [owner1] + }; + + ModellingConnectionHandler handler = CreateHandler(apiConnection, connection); + handler.AllApps = [owner1, owner2, owner3]; + handler.PermittedOwnersToAdd.Add(owner2); + handler.ActConn.InterfacePermission = InterfacePermissions.Restricted.ToString(); + + await InvokePrivateAsync(handler, "EnsureUsingAppsPermittedIfRestricted"); + + ClassicAssert.IsTrue(handler.PermittedOwnersToAdd.Any(o => o.Id == 3)); + ClassicAssert.IsTrue(handler.ActConn.PermittedOwners.Any(o => o.Id == 3)); + ClassicAssert.IsFalse(handler.ActConn.PermittedOwners.Any(o => o.Id == 2)); + ClassicAssert.AreEqual(2, handler.PermittedOwnersToAdd.Count); + } + + [Test] + public async Task ApplyPermittedOwnersOnInsert_NotRestrictedClearsLists() + { + ModellingConnectionHandlerPermissionTestApiConn apiConnection = new(); + ModellingConnection connection = new() + { + Id = 11, + IsInterface = true, + InterfacePermission = InterfacePermissions.Public.ToString() + }; + + ModellingConnectionHandler handler = CreateHandler(apiConnection, connection); + handler.PermittedOwnersToAdd.Add(new() { Id = 1 }); + handler.PermittedOwnersToDelete.Add(new() { Id = 2 }); + + await InvokePrivateAsync(handler, "ApplyPermittedOwnersOnInsert"); + + ClassicAssert.AreEqual(0, handler.PermittedOwnersToAdd.Count); + ClassicAssert.AreEqual(0, handler.PermittedOwnersToDelete.Count); + ClassicAssert.AreEqual(0, apiConnection.AddedOwners.Count); + } + + [Test] + public async Task ApplyPermittedOwnersOnUpdate_NotRestrictedRemovesAllAndClears() + { + ModellingConnectionHandlerPermissionTestApiConn apiConnection = new(); + apiConnection.ExistingPermittedOwners = + [ + new() { Id = 1 }, + new() { Id = 3 } + ]; + + ModellingConnection connection = new() + { + Id = 12, + IsInterface = true, + InterfacePermission = InterfacePermissions.Public.ToString(), + PermittedOwners = [new() { Id = 1 }, new() { Id = 2 }] + }; + + ModellingConnectionHandler handler = CreateHandler(apiConnection, connection); + handler.PermittedOwnersToAdd.Add(new() { Id = 4 }); + handler.PermittedOwnersToDelete.Add(new() { Id = 5 }); + + await InvokePrivateAsync(handler, "ApplyPermittedOwnersOnUpdate"); + + ClassicAssert.AreEqual(0, handler.ActConn.PermittedOwners.Count); + ClassicAssert.AreEqual(0, handler.PermittedOwnersToAdd.Count); + ClassicAssert.AreEqual(0, handler.PermittedOwnersToDelete.Count); + ClassicAssert.AreEqual(0, apiConnection.AddedOwners.Count); + ClassicAssert.AreEqual(2, apiConnection.DeletedOwners.Count); + ClassicAssert.IsTrue(apiConnection.DeletedOwners.Contains(1)); + ClassicAssert.IsTrue(apiConnection.DeletedOwners.Contains(3)); + } + + [Test] + public async Task ApplyPermittedOwnersOnUpdate_RestrictedAddsAndRemoves() + { + ModellingConnectionHandlerPermissionTestApiConn apiConnection = new(); + ModellingConnection connection = new() + { + Id = 13, + IsInterface = true, + InterfacePermission = InterfacePermissions.Restricted.ToString() + }; + + ModellingConnectionHandler handler = CreateHandler(apiConnection, connection); + handler.PermittedOwnersToAdd.Add(new() { Id = 1 }); + handler.PermittedOwnersToAdd.Add(new() { Id = 2 }); + handler.PermittedOwnersToDelete.Add(new() { Id = 3 }); + + await InvokePrivateAsync(handler, "ApplyPermittedOwnersOnUpdate"); + + ClassicAssert.AreEqual(2, apiConnection.AddedOwners.Count); + ClassicAssert.IsTrue(apiConnection.AddedOwners.Contains(1)); + ClassicAssert.IsTrue(apiConnection.AddedOwners.Contains(2)); + ClassicAssert.AreEqual(1, apiConnection.DeletedOwners.Count); + ClassicAssert.IsTrue(apiConnection.DeletedOwners.Contains(3)); + } + + private static ModellingConnectionHandler CreateHandler(ModellingConnectionHandlerPermissionTestApiConn apiConnection, ModellingConnection connection) + { + return new ModellingConnectionHandler(apiConnection, userConfig, Application, [connection], connection, false, false, DisplayMessageInUi, DefaultInit.DoNothing, true); + } + + private static async Task InvokePrivateAsync(ModellingConnectionHandler handler, string methodName) + { + MethodInfo? method = typeof(ModellingConnectionHandler).GetMethod(methodName, BindingFlags.NonPublic | BindingFlags.Instance); + ClassicAssert.IsNotNull(method, $"Expected to find method '{methodName}'."); + Task task = (Task)method!.Invoke(handler, null)!; + await task; + } + } + + internal class ModellingConnectionHandlerPermissionTestApiConn : SimulatedApiConnection + { + public List AddedOwners { get; } = []; + public List DeletedOwners { get; } = []; + public List ExistingPermittedOwners { get; set; } = []; + public List InterfaceUsers { get; set; } = []; + + public override Task SendQueryAsync(string query, object? variables = null, string? operationName = null) + { + Type responseType = typeof(QueryResponseType); + if (query == ModellingQueries.getInterfaceUsers && responseType == typeof(List)) + { + return Task.FromResult((QueryResponseType)(object)InterfaceUsers); + } + if (query == ModellingQueries.getPermittedOwnersForConnection && responseType == typeof(List)) + { + return Task.FromResult((QueryResponseType)(object)ExistingPermittedOwners); + } + if (query == ModellingQueries.addPermittedOwner) + { + int appId = GetIntVariable(variables, "appId"); + AddedOwners.Add(appId); + return Task.FromResult((QueryResponseType)CreateResponse(responseType, appId)); + } + if (query == ModellingQueries.deletePermittedOwner) + { + int appId = GetIntVariable(variables, "appId"); + DeletedOwners.Add(appId); + return Task.FromResult((QueryResponseType)CreateResponse(responseType, appId)); + } + if (query == ModellingQueries.addHistoryEntry) + { + return Task.FromResult((QueryResponseType)CreateResponse(responseType, 0)); + } + + throw new NotImplementedException(); + } + + private static object CreateResponse(Type responseType, int appId) + { + if (responseType == typeof(ReturnId)) + { + return new ReturnId { AffectedRows = 1, InsertedId = appId, InsertedIdLong = appId }; + } + if (responseType == typeof(ReturnIdWrapper)) + { + return new ReturnIdWrapper { ReturnIds = [new ReturnId { AffectedRows = 1, InsertedId = appId, InsertedIdLong = appId }] }; + } + if (responseType == typeof(FwoOwner)) + { + return new FwoOwner { Id = appId }; + } + return Activator.CreateInstance(responseType) ?? new object(); + } + + private static int GetIntVariable(object? variables, string name) + { + if (variables == null) + { + return 0; + } + object? value = variables.GetType().GetProperties().FirstOrDefault(p => p.Name == name)?.GetValue(variables); + return value == null ? 0 : Convert.ToInt32(value); + } + } +} diff --git a/roles/tests-unit/files/FWO.Test/ModellingConnectionHandlerSvcHandlingTest.cs b/roles/tests-unit/files/FWO.Test/ModellingConnectionHandlerSvcHandlingTest.cs new file mode 100644 index 0000000000..0727252e93 --- /dev/null +++ b/roles/tests-unit/files/FWO.Test/ModellingConnectionHandlerSvcHandlingTest.cs @@ -0,0 +1,108 @@ +using NUnit.Framework; +using NUnit.Framework.Legacy; +using FWO.Data; +using FWO.Data.Modelling; +using FWO.Services; +using FWO.Services.Modelling; +using FWO.Basics; +using System.Collections.Generic; +using System.Linq; +using System.Reflection; + +namespace FWO.Test +{ + [TestFixture] + [Parallelizable] + internal class ModellingConnectionHandlerSvcHandlingTest + { + static readonly SimulatedUserConfig userConfig = new(); + static readonly Action DisplayMessageInUi = DefaultInit.DoNothing; + static readonly FwoOwner Application = new() { Id = 1, Name = "TestApp" }; + + [Test] + public void SyncSvcChanges_AddsAndRemovesServicesAndGroups() + { + ModellingConnection connection = new() + { + Id = 1, + Services = [WrapService(1, "SvcOld")], + ServiceGroups = [WrapServiceGroup(2, "GrpOld")] + }; + ModellingConnectionHandler handler = CreateHandler(connection); + + handler.SvcToDelete.Add(new ModellingService { Id = 1 }); + handler.SvcGrpToDelete.Add(new ModellingServiceGroup { Id = 2 }); + handler.SvcToAdd.Add(new ModellingService { Id = 3, Name = "SvcNew" }); + handler.SvcGrpToAdd.Add(new ModellingServiceGroup { Id = 4, Name = "GrpNew" }); + + InvokePrivateVoid(handler, "SyncSvcChanges"); + + ClassicAssert.AreEqual(1, handler.ActConn.Services.Count); + ClassicAssert.AreEqual(3, handler.ActConn.Services[0].Content.Id); + ClassicAssert.AreEqual(1, handler.ActConn.ServiceGroups.Count); + ClassicAssert.AreEqual(4, handler.ActConn.ServiceGroups[0].Content.Id); + } + + [Test] + public void ServicesToConn_AddsWhenNotExisting() + { + ModellingConnection connection = new() + { + Id = 2, + Services = [WrapService(1, "SvcExisting")] + }; + ModellingConnectionHandler handler = CreateHandler(connection); + + handler.ServicesToConn( + [ + new ModellingService { Id = 1, Name = "SvcExisting" }, + new ModellingService { Id = 2, Name = "SvcNew" } + ]); + + ClassicAssert.AreEqual(1, handler.SvcToAdd.Count); + ClassicAssert.AreEqual(2, handler.SvcToAdd[0].Id); + } + + [Test] + public void ServiceGrpsToConn_AddsWhenNotExisting() + { + ModellingConnection connection = new() + { + Id = 3, + ServiceGroups = [WrapServiceGroup(1, "GrpExisting")] + }; + ModellingConnectionHandler handler = CreateHandler(connection); + + handler.ServiceGrpsToConn( + [ + new ModellingServiceGroup { Id = 1, Name = "GrpExisting" }, + new ModellingServiceGroup { Id = 2, Name = "GrpNew" } + ]); + + ClassicAssert.AreEqual(1, handler.SvcGrpToAdd.Count); + ClassicAssert.AreEqual(2, handler.SvcGrpToAdd[0].Id); + } + + private static ModellingConnectionHandler CreateHandler(ModellingConnection connection) + { + return new ModellingConnectionHandler(new ModellingHandlerTestApiConn(), userConfig, Application, [connection], connection, false, false, DisplayMessageInUi, DefaultInit.DoNothing, true); + } + + private static void InvokePrivateVoid(ModellingConnectionHandler handler, string methodName) + { + MethodInfo? method = typeof(ModellingConnectionHandler).GetMethod(methodName, BindingFlags.NonPublic | BindingFlags.Instance); + ClassicAssert.IsNotNull(method, $"Expected to find method '{methodName}'."); + method!.Invoke(handler, null); + } + + private static ModellingServiceWrapper WrapService(int id, string name) + { + return new ModellingServiceWrapper { Content = new ModellingService { Id = id, Name = name } }; + } + + private static ModellingServiceGroupWrapper WrapServiceGroup(int id, string name) + { + return new ModellingServiceGroupWrapper { Content = new ModellingServiceGroup { Id = id, Name = name } }; + } + } +} diff --git a/roles/tests-unit/files/FWO.Test/ModellingConnectionHandlerTest.cs b/roles/tests-unit/files/FWO.Test/ModellingConnectionHandlerTest.cs new file mode 100644 index 0000000000..2a0bef492d --- /dev/null +++ b/roles/tests-unit/files/FWO.Test/ModellingConnectionHandlerTest.cs @@ -0,0 +1,492 @@ +using NUnit.Framework; +using NUnit.Framework.Legacy; +using FWO.Data; +using FWO.Data.Modelling; +using FWO.Services; +using FWO.Services.Modelling; +using FWO.Basics; +using Microsoft.AspNetCore.Components; +using System.Collections.Generic; +using System.Linq; + +namespace FWO.Test +{ + [TestFixture] + [Parallelizable] + internal class ModellingConnectionHandlerTest + { + static readonly SimulatedUserConfig userConfig = new() + { + ModNamingConvention = "{\"networkAreaRequired\":true,\"fixedPartLength\":4,\"freePartLength\":5,\"networkAreaPattern\":\"NA\",\"appRolePattern\":\"AR\"}" + }; + static readonly ModellingHandlerTestApiConn apiConnection = new(); + static readonly Action DisplayMessageInUi = DefaultInit.DoNothing; + static readonly FwoOwner Application = new() { Id = 1, Name = "TestApp" }; + + static readonly ModellingNetworkArea Area1 = new() { Id = 1, Name = "Area1", IdString = "NA01" }; + static readonly ModellingNetworkArea Area2 = new() { Id = 2, Name = "Area2", IdString = "NA02" }; + static readonly ModellingNetworkArea Area3 = new() { Id = 3, Name = "Area3", IdString = "NA03" }; + + static readonly ModellingAppRole Role1 = new() { Id = 10, Name = "Role1", IdString = "AR01" }; + static readonly ModellingAppRole Role2 = new() { Id = 11, Name = "Role2", IdString = "AR02" }; + static readonly ModellingAppRole Role3 = new() { Id = 12, Name = "Role3", IdString = "AR03" }; + + [SetUp] + public void Initialize() + { + } + + [Test] + public async Task TestComSvcContainsOnlyNetworkAreasInDirection_ItemsMarkedForDeletionAreProperlyExcluded() + { + // ARRANGE + ModellingConnection connection = new() + { + Id = 1, + Name = "TestConnection", + IsCommonService = true, + SourceAreas = [new() { Content = Area1 }, new() { Content = Area2 }], + SourceAppRoles = [new() { Content = Role1 }] + }; + + List connections = [connection]; + ModellingConnectionHandler handler = new( + apiConnection, + userConfig, + Application, + connections, + connection, + false, + false, + DisplayMessageInUi, + DefaultInit.DoNothing, + true + ); + + await handler.Init(); + + handler.SrcAreasToDelete.Add(Area2); + handler.SrcAppRolesToDelete.Add(Role1); + + // ACT + bool result = handler.ComSvcContainsOnlyNetworkAreasInDirection(Direction.Source, new List()); + + // ASSERT + ClassicAssert.AreEqual(true, result, "Items marked for deletion should be properly excluded from validation"); + } + + [Test] + public async Task TestComSvcContainsOnlyNetworkAreasInDirection_ReturnsTrue_WhenOnlyAreasRemainAfterDeletion() + { + // ARRANGE + ModellingConnection connection = new() + { + Id = 2, + Name = "TestConnection2", + IsCommonService = true, + SourceAreas = [new() { Content = Area1 }, new() { Content = Area2 }], + SourceAppRoles = [new() { Content = Role1 }, new() { Content = Role2 }] + }; + + List connections = [connection]; + + ModellingConnectionHandler handler = new( + apiConnection, + userConfig, + Application, + connections, + connection, + false, + false, + DisplayMessageInUi, + DefaultInit.DoNothing, + true + ); + + await handler.Init(); + + handler.SrcAppRolesToDelete.Add(Role1); + handler.SrcAppRolesToDelete.Add(Role2); + + // ACT + bool result = handler.ComSvcContainsOnlyNetworkAreasInDirection(Direction.Source, new List()); + + // ASSERT + ClassicAssert.AreEqual(true, result, "Method should return true when only network areas remain after deletion"); + } + + [Test] + public async Task TestComSvcContainsOnlyNetworkAreasInDirection_ReturnsFalse_WhenBothAreasAndRolesRemainAfterDeletion() + { + // ARRANGE + ModellingConnection connection = new() + { + Id = 3, + Name = "TestConnection3", + IsCommonService = true, + DestinationAreas = [new() { Content = Area1 }, new() { Content = Area2 }], + DestinationAppRoles = [new() { Content = Role1 }, new() { Content = Role2 }] + }; + + List connections = [connection]; + + ModellingConnectionHandler handler = new( + apiConnection, + userConfig, + Application, + connections, + connection, + false, + false, + DisplayMessageInUi, + DefaultInit.DoNothing, + true + ); + + await handler.Init(); + + handler.DstAppRolesToDelete.Add(Role1); + + // ACT + bool result = handler.ComSvcContainsOnlyNetworkAreasInDirection(Direction.Destination, new List()); + + // ASSERT + ClassicAssert.AreEqual(false, result, "Method should return false when both areas and roles remain after deletion"); + } + + [Test] + public async Task TestComSvcContainsOnlyNetworkAreasInDirection_WithNewItemsToAdd_ReturnsTrue() + { + // ARRANGE + ModellingConnection connection = new() + { + Id = 4, + Name = "TestConnection4", + IsCommonService = true, + SourceAreas = [], + SourceAppRoles = [] + }; + + List connections = [connection]; + + ModellingConnectionHandler handler = new( + apiConnection, + userConfig, + Application, + connections, + connection, + false, + false, + DisplayMessageInUi, + DefaultInit.DoNothing, + true + ); + + await handler.Init(); + + handler.SrcAreasToAdd.Add(Area1); + handler.SrcAreasToAdd.Add(Area2); + + // ACT + bool result = handler.ComSvcContainsOnlyNetworkAreasInDirection(Direction.Source, new List()); + + // ASSERT + ClassicAssert.AreEqual(true, result, "Method should return true when only areas are added"); + } + + [Test] + public async Task TestComSvcContainsOnlyNetworkAreasInDirection_WithNewItemsToAdd_ReturnsFalse() + { + // ARRANGE + ModellingConnection connection = new() + { + Id = 5, + Name = "TestConnection5", + IsCommonService = true, + SourceAreas = [], + SourceAppRoles = [] + }; + + List connections = [connection]; + + ModellingConnectionHandler handler = new( + apiConnection, + userConfig, + Application, + connections, + connection, + false, + false, + DisplayMessageInUi, + DefaultInit.DoNothing, + true + ); + + await handler.Init(); + + handler.SrcAreasToAdd.Add(Area1); + handler.SrcAppRolesToAdd.Add(Role1); + + // ACT + bool result = handler.ComSvcContainsOnlyNetworkAreasInDirection(Direction.Source, new List()); + + // ASSERT + ClassicAssert.AreEqual(false, result, "Method should return false when both areas and roles are added"); + } + + [Test] + public async Task TestComSvcContainsOnlyNetworkAreasInDirection_WithInitialAreasParameter_ReturnsTrue() + { + // ARRANGE + ModellingConnection connection = new() + { + Id = 6, + Name = "TestConnection6", + IsCommonService = true, + SourceAreas = [], + SourceAppRoles = [] + }; + + List connections = [connection]; + + ModellingConnectionHandler handler = new( + apiConnection, + userConfig, + Application, + connections, + connection, + false, + false, + DisplayMessageInUi, + DefaultInit.DoNothing, + true + ); + + await handler.Init(); + + List selectedAreas = [Area1, Area2]; + + // ACT + bool result = handler.ComSvcContainsOnlyNetworkAreasInDirection(Direction.Source, selectedAreas); + + // ASSERT + ClassicAssert.AreEqual(true, result, "Method should return true when only network areas are provided via parameter"); + } + + [Test] + public async Task TestComSvcContainsOnlyNetworkAreasInDirection_WithInitialRolesParameter_ReturnsFalse() + { + // ARRANGE + ModellingConnection connection = new() + { + Id = 7, + Name = "TestConnection7", + IsCommonService = true, + SourceAreas = [new() { Content = Area1 }], + SourceAppRoles = [] + }; + + List connections = [connection]; + + ModellingConnectionHandler handler = new( + apiConnection, + userConfig, + Application, + connections, + connection, + false, + false, + DisplayMessageInUi, + DefaultInit.DoNothing, + true + ); + + await handler.Init(); + + List selectedRoles = [Role1]; + + // ACT + bool result = handler.ComSvcContainsOnlyNetworkAreasInDirection(Direction.Source, selectedRoles); + + // ASSERT + ClassicAssert.AreEqual(false, result, "Method should return false when roles are added to existing areas"); + } + + [Test] + public async Task TestComSvcContainsOnlyNetworkAreasInDirection_EmptyAfterDeletion_ReturnsTrue() + { + // ARRANGE + ModellingConnection connection = new() + { + Id = 8, + Name = "TestConnection8", + IsCommonService = true, + DestinationAreas = [new() { Content = Area1 }], + DestinationAppRoles = [new() { Content = Role1 }] + }; + + List connections = [connection]; + + ModellingConnectionHandler handler = new( + apiConnection, + userConfig, + Application, + connections, + connection, + false, + false, + DisplayMessageInUi, + DefaultInit.DoNothing, + true + ); + + await handler.Init(); + + handler.DstAreasToDelete.Add(Area1); + handler.DstAppRolesToDelete.Add(Role1); + + // ACT + bool result = handler.ComSvcContainsOnlyNetworkAreasInDirection(Direction.Destination, new List()); + + // ASSERT + ClassicAssert.AreEqual(true, result, "Method should return true when both lists are empty after deletion"); + } + + [Test] + public void AddExtraConfig_EnablesAddMode() + { + ModellingConnection connection = new() { Id = 9 }; + ModellingConnectionHandler handler = new(apiConnection, userConfig, Application, [connection], connection, false, false, DisplayMessageInUi, DefaultInit.DoNothing, true); + + handler.AddExtraConfig(); + + ClassicAssert.IsTrue(handler.AddExtraConfigMode); + } + + [Test] + public void SaveExtraConfig_AssignsIncrementedIdAndAddsEntry() + { + ModellingConnection connection = new() + { + Id = 10, + ExtraConfigs = [new ModellingExtraConfig { Id = 5, ExtraConfigType = "T1", ExtraConfigText = "A" }] + }; + ModellingConnectionHandler handler = new(apiConnection, userConfig, Application, [connection], connection, false, false, DisplayMessageInUi, DefaultInit.DoNothing, true); + ModellingExtraConfig newConfig = new() { ExtraConfigType = "T2", ExtraConfigText = "B" }; + + bool result = handler.SaveExtraConfig(newConfig); + + ClassicAssert.IsTrue(result); + ClassicAssert.AreEqual(2, handler.ActConn.ExtraConfigs.Count); + ClassicAssert.AreEqual(6, handler.ActConn.ExtraConfigs.Max(c => c.Id)); + } + + [Test] + public void UpdateExtraConfig_SanitizesUpdatedText() + { + ModellingConnection connection = new() + { + Id = 11, + ExtraConfigs = [new ModellingExtraConfig { Id = 1, ExtraConfigType = "Type", ExtraConfigText = "Clean" }] + }; + ModellingConnectionHandler handler = new(apiConnection, userConfig, Application, [connection], connection, false, false, DisplayMessageInUi, DefaultInit.DoNothing, true); + ModellingExtraConfig target = handler.ActConn.ExtraConfigs[0]; + ChangeEventArgs change = new() { Value = "Bad!" }; + + handler.UpdateExtraConfig(change, target); + + ClassicAssert.AreEqual("Bad", handler.ActConn.ExtraConfigs[0].ExtraConfigText); + } + + [Test] + public void DeleteExtraConfig_RemovesMatchingEntry() + { + ModellingConnection connection = new() + { + Id = 12, + ExtraConfigs = + [ + new ModellingExtraConfig { Id = 1, ExtraConfigType = "T1", ExtraConfigText = "A" }, + new ModellingExtraConfig { Id = 2, ExtraConfigType = "T2", ExtraConfigText = "B" } + ] + }; + ModellingConnectionHandler handler = new(apiConnection, userConfig, Application, [connection], connection, false, false, DisplayMessageInUi, DefaultInit.DoNothing, true); + + bool result = handler.DeleteExtraConfig(new ModellingExtraConfig { Id = 1 }); + + ClassicAssert.IsTrue(result); + ClassicAssert.AreEqual(1, handler.ActConn.ExtraConfigs.Count); + ClassicAssert.AreEqual(2, handler.ActConn.ExtraConfigs[0].Id); + } + + [Test] + public void SrcDropForbidden_ReturnsTrueWhenReadOnly() + { + ModellingConnection connection = new() { Id = 13 }; + ModellingConnectionHandler handler = new(apiConnection, userConfig, Application, [connection], connection, false, false, DisplayMessageInUi, DefaultInit.DoNothing, true) + { + SrcReadOnly = true + }; + + ClassicAssert.IsTrue(handler.SrcDropForbidden()); + } + + [Test] + public void SrcDropForbidden_ReturnsTrueWhenInterfaceAndDestinationFilled() + { + ModellingConnection connection = new() + { + Id = 14, + IsInterface = true, + DestinationAreas = [new() { Content = Area1 }] + }; + ModellingConnectionHandler handler = new(apiConnection, userConfig, Application, [connection], connection, false, false, DisplayMessageInUi, DefaultInit.DoNothing, true); + + ClassicAssert.IsTrue(handler.SrcDropForbidden()); + } + + [Test] + public void SrcDropForbidden_ReturnsFalseWhenEditableAndNoInterfaceConstraint() + { + ModellingConnection connection = new() { Id = 15 }; + ModellingConnectionHandler handler = new(apiConnection, userConfig, Application, [connection], connection, false, false, DisplayMessageInUi, DefaultInit.DoNothing, true); + + ClassicAssert.IsFalse(handler.SrcDropForbidden()); + } + + [Test] + public void DstDropForbidden_ReturnsTrueWhenReadOnly() + { + ModellingConnection connection = new() { Id = 16 }; + ModellingConnectionHandler handler = new(apiConnection, userConfig, Application, [connection], connection, false, false, DisplayMessageInUi, DefaultInit.DoNothing, true) + { + DstReadOnly = true + }; + + ClassicAssert.IsTrue(handler.DstDropForbidden()); + } + + [Test] + public void DstDropForbidden_ReturnsTrueWhenInterfaceAndSourceFilled() + { + ModellingConnection connection = new() + { + Id = 17, + IsInterface = true, + SourceAreas = [new() { Content = Area1 }] + }; + ModellingConnectionHandler handler = new(apiConnection, userConfig, Application, [connection], connection, false, false, DisplayMessageInUi, DefaultInit.DoNothing, true); + + ClassicAssert.IsTrue(handler.DstDropForbidden()); + } + + [Test] + public void DstDropForbidden_ReturnsFalseWhenEditableAndNoInterfaceConstraint() + { + ModellingConnection connection = new() { Id = 18 }; + ModellingConnectionHandler handler = new(apiConnection, userConfig, Application, [connection], connection, false, false, DisplayMessageInUi, DefaultInit.DoNothing, true); + + ClassicAssert.IsFalse(handler.DstDropForbidden()); + } + } +} diff --git a/roles/tests-unit/files/FWO.Test/ModellingConnectionTest.cs b/roles/tests-unit/files/FWO.Test/ModellingConnectionTest.cs new file mode 100644 index 0000000000..02d6a25b56 --- /dev/null +++ b/roles/tests-unit/files/FWO.Test/ModellingConnectionTest.cs @@ -0,0 +1,230 @@ +using NUnit.Framework; +using NUnit.Framework.Legacy; +using FWO.Basics; +using FWO.Data; +using FWO.Data.Modelling; +using System.Collections.Generic; +using System.Linq; + +namespace FWO.Test +{ + [TestFixture] + [Parallelizable] + internal class ModellingConnectionTest + { + [Test] + public void SyncState_InterfaceRequestedSetsRequestedFlag() + { + ModellingConnection conn = new() + { + IsInterface = true, + IsRequested = true, + IsPublished = false + }; + + conn.SyncState(0); + + ClassicAssert.IsTrue(conn.GetBoolProperty(ConState.Requested.ToString())); + ClassicAssert.IsFalse(conn.GetBoolProperty(ConState.Decommissioned.ToString())); + } + + [Test] + public void SyncState_InterfaceRejectedSkipsRequestedFlag() + { + ModellingConnection conn = new() + { + IsInterface = true, + IsRequested = true, + IsPublished = false + }; + conn.AddProperty(ConState.Rejected.ToString()); + + conn.SyncState(0); + + ClassicAssert.IsTrue(conn.GetBoolProperty(ConState.Rejected.ToString())); + ClassicAssert.IsFalse(conn.GetBoolProperty(ConState.Requested.ToString())); + } + + [Test] + public void SyncState_InterfaceUserSetsRequestedAndDecommissionedFlags() + { + ModellingConnection conn = new() + { + IsInterface = false, + UsedInterfaceId = 99, + InterfaceIsRequested = true, + InterfaceIsDecommissioned = true + }; + + conn.SyncState(0); + + ClassicAssert.IsTrue(conn.GetBoolProperty(ConState.InterfaceRequested.ToString())); + ClassicAssert.IsTrue(conn.GetBoolProperty(ConState.InterfaceDecommissioned.ToString())); + ClassicAssert.IsFalse(conn.GetBoolProperty(ConState.InterfaceRejected.ToString())); + } + + [Test] + public void SyncState_InterfaceUserRejectedOverridesRequested() + { + ModellingConnection conn = new() + { + IsInterface = false, + UsedInterfaceId = 99, + InterfaceIsRequested = true, + InterfaceIsRejected = true + }; + + conn.SyncState(0); + + ClassicAssert.IsTrue(conn.GetBoolProperty(ConState.InterfaceRejected.ToString())); + ClassicAssert.IsFalse(conn.GetBoolProperty(ConState.InterfaceRequested.ToString())); + } + + [Test] + public void SyncState_MemberIssuesAndDocumentationOnlySet() + { + ModellingAppRole emptyRole = new() { Id = 1, Name = "AR1", AppServers = [] }; + ModellingServiceGroup emptySvcGrp = new() { Id = 2, Name = "SG1", Services = [] }; + ModellingNetworkArea deletedArea = new() { Id = 3, Name = "Area", IsDeleted = true }; + + ModellingConnection conn = new() + { + SourceAppRoles = [new ModellingAppRoleWrapper { Content = emptyRole }], + ServiceGroups = [new ModellingServiceGroupWrapper { Content = emptySvcGrp }], + SourceAreas = [new ModellingNetworkAreaWrapper { Content = deletedArea }], + ExtraConfigs = [new ModellingExtraConfig { ExtraConfigType = GlobalConst.kDoku_ + "text" }] + }; + + conn.SyncState(0); + + ClassicAssert.IsTrue(conn.GetBoolProperty(ConState.EmptyAppRoles.ToString())); + ClassicAssert.IsTrue(conn.GetBoolProperty(ConState.EmptySvcGrps.ToString())); + ClassicAssert.IsTrue(conn.GetBoolProperty(ConState.DeletedObjects.ToString())); + ClassicAssert.IsTrue(conn.GetBoolProperty(ConState.DocumentationOnly.ToString())); + } + + [Test] + public void SyncState_IgnoresDummyAppRoleForEmptyCheck() + { + ModellingAppRole dummyRole = new() { Id = 99, Name = "Dummy", AppServers = [] }; + ModellingConnection conn = new() + { + SourceAppRoles = [new ModellingAppRoleWrapper { Content = dummyRole }] + }; + + conn.SyncState(99); + + ClassicAssert.IsFalse(conn.GetBoolProperty(ConState.EmptyAppRoles.ToString())); + } + + [Test] + public void ToRule_MapsSourcesDestinationsAndServices() + { + ModellingConnection conn = new() + { + Name = "Conn1", + SourceAreas = [new ModellingNetworkAreaWrapper { Content = new ModellingNetworkArea { Id = 1, Name = "Area1", IdString = "NA1" } }], + SourceOtherGroups = [new ModellingNwGroupWrapper { Content = new ModellingNwGroup { Id = 2, Name = "Group1", IdString = "GR1" } }], + SourceAppRoles = [new ModellingAppRoleWrapper { Content = new ModellingAppRole { Id = 3, Name = "AR1", IdString = "AR1" } }], + SourceAppServers = [new ModellingAppServerWrapper { Content = new ModellingAppServer { Id = 4, Name = "Server1", Ip = "10.0.0.1" } }], + DestinationAreas = [new ModellingNetworkAreaWrapper { Content = new ModellingNetworkArea { Id = 5, Name = "Area2", IdString = "NA2" } }], + DestinationOtherGroups = [new ModellingNwGroupWrapper { Content = new ModellingNwGroup { Id = 6, Name = "Group2", IdString = "GR2" } }], + DestinationAppRoles = [new ModellingAppRoleWrapper { Content = new ModellingAppRole { Id = 7, Name = "AR2", IdString = "AR2" } }], + DestinationAppServers = [new ModellingAppServerWrapper { Content = new ModellingAppServer { Id = 8, Name = "Server2", Ip = "10.0.0.2" } }], + ServiceGroups = [new ModellingServiceGroupWrapper { Content = new ModellingServiceGroup { Id = 9, Name = "SvcGrp1", Services = [] } }], + Services = [new ModellingServiceWrapper { Content = new ModellingService { Id = 10, Name = "Svc1", ProtoId = 6, Port = 80 } }] + }; + + Rule rule = conn.ToRule(); + + ClassicAssert.AreEqual("Conn1", rule.Name); + ClassicAssert.AreEqual(4, rule.Froms.Count()); + ClassicAssert.AreEqual(4, rule.Tos.Count()); + ClassicAssert.AreEqual(2, rule.Services.Count()); + } + + [Test] + public void Sanitize_ShortensFields() + { + ModellingConnection conn = new() + { + Name = " Name ", + Reason = "Reason\u0000", + Creator = " Creator ", + Properties = " { } ", + ExtraParams = " { } " + }; + + bool shortened = conn.Sanitize(); + + ClassicAssert.IsTrue(shortened); + ClassicAssert.IsFalse(conn.Name?.Contains(" ") ?? false); + ClassicAssert.IsFalse(conn.Creator?.Contains(" ") ?? false); + ClassicAssert.AreEqual("Reason\0", conn.Reason); + } + + [Test] + public void IsRelevantForVarianceAnalysis_ReturnsTrueForCleanConnection() + { + ModellingAppServerWrapper appServer = new() { Content = new ModellingAppServer { Id = 1, Name = "Server1", Ip = "10.0.0.1" } }; + ModellingAppRole appRole = new() { Id = 2, Name = "AR1", AppServers = [appServer] }; + ModellingServiceWrapper service = new() { Content = new ModellingService { Id = 3, Name = "Svc1", ProtoId = 6, Port = 443 } }; + ModellingServiceGroup serviceGroup = new() { Id = 4, Name = "SvcGrp1", Services = [service] }; + + ModellingConnection conn = new() + { + SourceAppRoles = [new ModellingAppRoleWrapper { Content = appRole }], + Services = [service], + ServiceGroups = [new ModellingServiceGroupWrapper { Content = serviceGroup }] + }; + + bool result = conn.IsRelevantForVarianceAnalysis(0); + + ClassicAssert.IsTrue(result); + } + + [Test] + public void IsRelevantForVarianceAnalysis_ReturnsFalseWhenInterfaceFlagSet() + { + ModellingConnection conn = new() + { + IsInterface = true + }; + + bool result = conn.IsRelevantForVarianceAnalysis(0); + + ClassicAssert.IsFalse(result); + } + + [Test] + public void IsRelevantForVarianceAnalysis_ReturnsFalseWhenIssuesPresent() + { + ModellingAppRole emptyRole = new() { Id = 5, Name = "AR2", AppServers = [] }; + ModellingConnection conn = new() + { + SourceAppRoles = [new ModellingAppRoleWrapper { Content = emptyRole }] + }; + + bool result = conn.IsRelevantForVarianceAnalysis(0); + + ClassicAssert.IsFalse(result); + } + + [Test] + public void CleanUpVarianceResults_RemovesVarianceFlagsOnly() + { + ModellingConnection conn = new(); + conn.AddProperty(ConState.VarianceChecked.ToString()); + conn.AddProperty(ConState.VarianceFound.ToString()); + conn.AddProperty(ConState.NotImplemented.ToString()); + conn.AddProperty(ConState.Requested.ToString()); + + conn.CleanUpVarianceResults(); + + ClassicAssert.IsFalse(conn.GetBoolProperty(ConState.VarianceChecked.ToString())); + ClassicAssert.IsFalse(conn.GetBoolProperty(ConState.VarianceFound.ToString())); + ClassicAssert.IsFalse(conn.GetBoolProperty(ConState.NotImplemented.ToString())); + ClassicAssert.IsTrue(conn.GetBoolProperty(ConState.Requested.ToString())); + } + } +} diff --git a/roles/tests-unit/files/FWO.Test/ModellingEmailRecipientSelectionTest.cs b/roles/tests-unit/files/FWO.Test/ModellingEmailRecipientSelectionTest.cs new file mode 100644 index 0000000000..ea4149530a --- /dev/null +++ b/roles/tests-unit/files/FWO.Test/ModellingEmailRecipientSelectionTest.cs @@ -0,0 +1,95 @@ +using FWO.Basics; +using FWO.Data; +using NUnit.Framework; + +namespace FWO.Test +{ + [TestFixture] + public class ModellingEmailRecipientSelectionTest + { + [Test] + public void ParseLegacyOwnerGroupOnlyMapsToSupportingResponsible() + { + ModellingEmailRecipientSelection selection = ModellingEmailRecipientSelection.Parse(nameof(EmailRecipientOption.OwnerGroupOnly), [1, 2, 3]); + + Assert.That(selection.None, Is.False); + Assert.That(selection.OwnerResponsibleTypeIds, Is.EqualTo(new[] { GlobalConst.kOwnerResponsibleTypeSupporting })); + } + + [Test] + public void ParseLegacyAllOwnerResponsiblesUsesActiveResponsibleTypes() + { + ModellingEmailRecipientSelection selection = ModellingEmailRecipientSelection.Parse(nameof(EmailRecipientOption.AllOwnerResponsibles), [1, 3]); + + Assert.That(selection.None, Is.False); + Assert.That(selection.OwnerResponsibleTypeIds.OrderBy(id => id), Is.EqualTo(new[] { 1, 3 })); + } + + [Test] + public void ParseJsonNoneDisablesOtherSelections() + { + string rawConfig = "{\"none\":true,\"other_addresses\":true,\"owner_responsible_type_ids\":[1,2]}"; + ModellingEmailRecipientSelection selection = ModellingEmailRecipientSelection.Parse(rawConfig, [1, 2, 3]); + + Assert.That(selection.None, Is.True); + Assert.That(selection.OtherAddresses, Is.False); + Assert.That(selection.OwnerResponsibleTypeIds, Is.Empty); + } + + [Test] + public void ToConfigValueWithoutRecipientsStoresNone() + { + ModellingEmailRecipientSelection selection = new() + { + None = false, + OtherAddresses = false, + OwnerResponsibleTypeIds = [] + }; + + Assert.That(selection.ToConfigValue([1, 2]), Is.EqualTo(nameof(EmailRecipientOption.None))); + } + + [Test] + public void GetOwnerResponsibleTypeFallbackOrderUsesHighestSortOrderFirst() + { + ModellingEmailRecipientSelection selection = new() + { + None = false, + OwnerResponsibleTypeIds = [1, 2, 3] + }; + + List ownerResponsibleTypes = + [ + new OwnerResponsibleType { Id = 1, Active = true, SortOrder = 10 }, + new OwnerResponsibleType { Id = 2, Active = true, SortOrder = 50 }, + new OwnerResponsibleType { Id = 3, Active = false, SortOrder = 100 } + ]; + + List fallbackOrder = selection.GetOwnerResponsibleTypeFallbackOrder(ownerResponsibleTypes).ToList(); + + Assert.That(fallbackOrder, Is.EqualTo(new[] { 2, 1 })); + } + + [Test] + public void ParseLegacyFallbackOptionEnablesEnsureAtLeastOneNotification() + { + ModellingEmailRecipientSelection selection = ModellingEmailRecipientSelection.Parse(nameof(EmailRecipientOption.FallbackToMainResponsibleIfOwnerGroupEmpty), [1, 2]); + + Assert.That(selection.None, Is.False); + Assert.That(selection.EnsureAtLeastOneNotification, Is.True); + Assert.That(selection.OwnerResponsibleTypeIds, Is.EqualTo(new[] { 2, 1 })); + } + + [Test] + public void ParseInvalidJsonFallsBackToLegacyValue() + { + ModellingEmailRecipientSelection selection = ModellingEmailRecipientSelection.Parse( + "{invalid-json", + [GlobalConst.kOwnerResponsibleTypeMain, GlobalConst.kOwnerResponsibleTypeSupporting]); + + Assert.That(selection.None, Is.True); + Assert.That(selection.OtherAddresses, Is.False); + Assert.That(selection.OwnerResponsibleTypeIds, Is.Empty); + } + } +} diff --git a/roles/tests-unit/files/FWO.Test/ModellingHandlerTest.cs b/roles/tests-unit/files/FWO.Test/ModellingHandlerTest.cs new file mode 100644 index 0000000000..79a1e4f7e1 --- /dev/null +++ b/roles/tests-unit/files/FWO.Test/ModellingHandlerTest.cs @@ -0,0 +1,261 @@ +using FWO.Basics; +using FWO.Data; +using FWO.Data.Modelling; +using FWO.Services; +using FWO.Services.Modelling; +using FWO.Ui.Services; +using NUnit.Framework; +using NUnit.Framework.Legacy; + +namespace FWO.Test +{ + [TestFixture] + [Parallelizable] + internal class ModellingHandlerTest + { + static readonly SimulatedUserConfig userConfig = new() + { + ModNamingConvention = "{\"networkAreaRequired\":true,\"fixedPartLength\":4,\"freePartLength\":5,\"networkAreaPattern\":\"NA\",\"appRolePattern\":\"AR\"}" + }; + static readonly ModellingHandlerTestApiConn apiConnection = new(); + static readonly Action DisplayMessageInUi = DefaultInit.DoNothing; + static readonly FwoOwner Application = new(); + static readonly List> AvailableNwElems = []; + static readonly List AvailableAppRoles = []; + static readonly ModellingAppRole AppRole = new(); + static readonly bool AddAppRoleMode = false; + static readonly bool IsOwner = true; + + static readonly ModellingAppServer AppServerInside1 = new() { Name = "AppServerInside1", Ip = "10.0.0.0", IpEnd = "10.0.0.0" }; + static readonly ModellingAppServer AppServerInside2 = new() { Name = "AppServerInside2", Ip = "10.0.0.5", IpEnd = "10.0.0.5" }; + static readonly ModellingAppServer AppServerInside3 = new() { Name = "AppServerInside3", Ip = "11.0.0.1", IpEnd = "11.0.0.1" }; + static readonly List AvailableAppServers = + [ + AppServerInside1, + AppServerInside2, + AppServerInside3, + new(){ Ip = "1.0.0.0" }, + new(){ Ip = "10.1.0.0" }, + new(){ Ip = "11.0.0.4" }, + new(){ Ip = "12.0.0.0" }, + new(){ Ip = "255.255.255.255" } + ]; + + static readonly ModellingNetworkArea TestArea = new() + { + Name = "Area1", + IdString = "NA50", + IpData = + [ + new(){ Content = new(){ Name = "TestRange1", Ip = "10.0.0.0", IpEnd = "10.0.0.255" }}, + new(){ Content = new(){ Name = "TestRange2", Ip = "11.0.0.0", IpEnd = "11.0.0.3" }} + ] + }; + + static readonly ModellingNamingConvention NamingConvention1 = new() + { + NetworkAreaRequired = true, + UseAppPart = false, + FixedPartLength = 4, + FreePartLength = 5, + NetworkAreaPattern = "NA", + AppRolePattern = "AR" + }; + static readonly ModellingNamingConvention NamingConvention2 = new() + { + NetworkAreaRequired = true, + UseAppPart = true, + FixedPartLength = 4, + FreePartLength = 3, + NetworkAreaPattern = "NA", + AppRolePattern = "AR" + }; + + ModellingAppRoleHandler? AppRoleHandler; + ModellingAppHandler? AppHandler; + + + [SetUp] + public void Initialize() + { + AppHandler = new(apiConnection, userConfig, Application, DisplayMessageInUi, IsOwner); + AppRoleHandler = new(apiConnection, userConfig, Application, AvailableAppRoles, AppRole, + AvailableAppServers, AvailableNwElems, AddAppRoleMode, DisplayMessageInUi, IsOwner); + } + + + // HandlerBase + [Test] + public async Task TestExtractUsedSrcInterface() + { + ModellingConnection conn = new() { Id = 3, UsedInterfaceId = 1 }; + ClassicAssert.AreEqual("Interf1", await AppHandler!.ExtractUsedInterface(conn)); + ClassicAssert.AreEqual(true, conn.SrcFromInterface); + ClassicAssert.AreEqual(false, conn.DstFromInterface); + ClassicAssert.AreEqual(0, conn.SourceAppServers.Count); + ClassicAssert.AreEqual("AppRole1", conn.SourceAppRoles[0].Content.Name); + ClassicAssert.AreEqual("NwGroup1", conn.SourceOtherGroups[0].Content.Name); + ClassicAssert.AreEqual(0, conn.DestinationAppServers.Count); + ClassicAssert.AreEqual(0, conn.DestinationAppRoles.Count); + ClassicAssert.AreEqual(0, conn.DestinationOtherGroups.Count); + ClassicAssert.AreEqual("ServiceGrp1", conn.ServiceGroups[0].Content.Name); + ClassicAssert.AreEqual(0, conn.Services.Count); + } + + [Test] + public async Task TestExtractUsedDstInterface() + { + ModellingConnection conn = new() { Id = 4, UsedInterfaceId = 2 }; + ClassicAssert.AreEqual("Interf2", await AppHandler!.ExtractUsedInterface(conn)); + ClassicAssert.AreEqual(false, conn.SrcFromInterface); + ClassicAssert.AreEqual(true, conn.DstFromInterface); + ClassicAssert.AreEqual(0, conn.SourceAppServers.Count); + ClassicAssert.AreEqual(0, conn.SourceAppRoles.Count); + ClassicAssert.AreEqual(0, conn.SourceOtherGroups.Count); + ClassicAssert.AreEqual("AppServer2", conn.DestinationAppServers[0].Content.Name); + ClassicAssert.AreEqual("AppRole2", conn.DestinationAppRoles[0].Content.Name); + ClassicAssert.AreEqual(0, conn.DestinationOtherGroups.Count); + ClassicAssert.AreEqual(0, conn.ServiceGroups.Count); + ClassicAssert.AreEqual("Service2", conn.Services[0].Content.Name); + } + + [Test] + public async Task TestExtractUsedInterface_InterfaceNoPermissionDependsOnPermissionMode() + { + ModellingConnection connRestrictedAllowed = new() { Id = 31, AppId = 1, UsedInterfaceId = 3 }; + await AppHandler!.ExtractUsedInterface(connRestrictedAllowed); + ClassicAssert.IsFalse(connRestrictedAllowed.InterfaceNoPermission); + + ModellingConnection connRestrictedDenied = new() { Id = 32, AppId = 1, UsedInterfaceId = 4 }; + await AppHandler!.ExtractUsedInterface(connRestrictedDenied); + ClassicAssert.IsTrue(connRestrictedDenied.InterfaceNoPermission); + + ModellingConnection connPrivate = new() { Id = 33, AppId = 1, UsedInterfaceId = 5 }; + await AppHandler!.ExtractUsedInterface(connPrivate); + ClassicAssert.IsFalse(connPrivate.InterfaceNoPermission); + + ModellingConnection connPublic = new() { Id = 34, AppId = 1, UsedInterfaceId = 6 }; + await AppHandler!.ExtractUsedInterface(connPublic); + ClassicAssert.IsFalse(connPublic.InterfaceNoPermission); + + ModellingConnection connPrivateForeign = new() { Id = 35, AppId = 1, UsedInterfaceId = 7 }; + await AppHandler!.ExtractUsedInterface(connPrivateForeign); + ClassicAssert.IsTrue(connPrivateForeign.InterfaceNoPermission); + } + + [Test] + public async Task TestExtractUsedInterface_InterfaceNoPermissionUnknownPermissionDefaultsToTrue() + { + ModellingConnection connUnknown = new() { Id = 36, AppId = 1, UsedInterfaceId = 8 }; + await AppHandler!.ExtractUsedInterface(connUnknown); + ClassicAssert.IsTrue(connUnknown.InterfaceNoPermission); + } + + [Test] + public void TestGetSrcDstSvcNames() + { + ModellingConnection conn = new() + { + UsedInterfaceId = 1, + SrcFromInterface = false, + SourceAppServers = [new() { Content = AppServerInside1 }, new() { Content = AppServerInside2 }], + SourceAppRoles = [new() { Content = new() { Name = "AppRole1", IdString = "AR5000001", IsDeleted = true } }], + SourceOtherGroups = [new() { Content = TestArea }], + DstFromInterface = true, + DestinationAppServers = [new() { Content = AppServerInside3 }], + DestinationAppRoles = [], + DestinationOtherGroups = [], + ServiceGroups = [new() { Content = new() { Name = "SvcGroup1", IsGlobal = true } }], + Services = [new() { Content = new() { Name = "Svc1", Port = 1111, Protocol = new() { Id = 17, Name = "UDP" } } }] + }; + List expectedSrc = [$" Area1 (NA50)", + $" !AppRole1 (AR5000001)", + $" AppServerInside1 (10.0.0.0)", + $" AppServerInside2 (10.0.0.5)"]; + + List expectedDst = [$" AppServerInside3 (11.0.0.1)"]; + + List expectedSvc = [$" SvcGroup1", + $" Svc1 (1111/UDP)"]; + + ClassicAssert.AreEqual(expectedSrc, ModellingHandlerBase.GetSrcNames(conn, userConfig)); + ClassicAssert.AreEqual(expectedDst, ModellingHandlerBase.GetDstNames(conn, userConfig)); + ClassicAssert.AreEqual(expectedSvc, ModellingHandlerBase.GetSvcNames(conn, userConfig)); + } + + [Test] + public void TestDisplayAppActiveNoConnections() + { + FwoOwner owner = new() + { + Name = "App1", + Active = true, + ConnectionCount = new AggregateCount { Aggregate = new Aggregate { Count = 0 } } + }; + + string expected = "*App1"; + ClassicAssert.AreEqual(expected, ModellingHandlerBase.DisplayApp(userConfig, owner)); + } + + [Test] + public void TestDisplayAppInactiveWithConnections() + { + FwoOwner owner = new() + { + Name = "App2", + Active = false, + ConnectionCount = new AggregateCount { Aggregate = new Aggregate { Count = 2 } } + }; + + string expected = "!App2"; + ClassicAssert.AreEqual(expected, ModellingHandlerBase.DisplayApp(userConfig, owner)); + } + + [Test] + public void TestDisplayReqIntRequestedOtherOwner() + { + string expected = "Interface requested: (Ticket 123)"; + ClassicAssert.AreEqual(expected, ModellingHandlerBase.DisplayReqInt(userConfig, 123, true)); + } + + [Test] + public void TestDisplayReqIntRejected() + { + string expected = "Interface rejected: (Ticket 456)"; + ClassicAssert.AreEqual(expected, ModellingHandlerBase.DisplayReqInt(userConfig, 456, false, true)); + } + + + // AppRoleHandler + [Test] + public async Task TestSelectAppServersFromArea() + { + List expectedResult = + [ + new(AppServerInside1) { TooltipText = userConfig.GetText("C9002") }, + new(AppServerInside2) { TooltipText = userConfig.GetText("C9002") }, + new(AppServerInside3) { TooltipText = userConfig.GetText("C9002") } + ]; + await AppRoleHandler!.SelectAppServersFromArea(TestArea); + ClassicAssert.AreEqual(expectedResult, AppRoleHandler.AppServersInArea); + } + + [Test] + public async Task TestProposeFreeAppRoleNumber() + { + ModellingManagedIdString idFixString = new() { NamingConvention = NamingConvention1 }; + idFixString.ConvertAreaToAppRoleFixedPart(TestArea.IdString); + idFixString.SetAppPartFromExtId("APP-1234"); + ClassicAssert.AreEqual("00002", await AppRoleHandler!.ProposeFreeAppRoleNumber(idFixString)); + + idFixString.NamingConvention = NamingConvention2; + idFixString.ConvertAreaToAppRoleFixedPart("NA91"); + idFixString.SetAppPartFromExtId("APP-1234"); + AppRoleHandler.NamingConvention = NamingConvention2; + ClassicAssert.AreEqual("003", await AppRoleHandler.ProposeFreeAppRoleNumber(idFixString)); + + idFixString.ConvertAreaToAppRoleFixedPart("NA99"); + ClassicAssert.AreEqual("001", await AppRoleHandler.ProposeFreeAppRoleNumber(idFixString)); + } + } +} diff --git a/roles/tests-unit/files/FWO.Test/ModellingHandlerTestApiConn.cs b/roles/tests-unit/files/FWO.Test/ModellingHandlerTestApiConn.cs new file mode 100644 index 0000000000..778bc99cea --- /dev/null +++ b/roles/tests-unit/files/FWO.Test/ModellingHandlerTestApiConn.cs @@ -0,0 +1,147 @@ +using FWO.Api.Client.Queries; +using GraphQL; +using FWO.Data.Modelling; +using FWO.Services; + +namespace FWO.Test +{ + internal class ModellingHandlerTestApiConn : SimulatedApiConnection + { + const string AppRoleId1 = "AR5000001"; + const string AppRoleId2 = "AR9101234-002"; + const string AppRoleId3 = "AR9901234-999"; + readonly ModellingAppRole AppRole1 = new() { Id = 1, IdString = AppRoleId1 }; + readonly ModellingAppRole AppRole2 = new() { Id = 2, IdString = AppRoleId2 }; + readonly ModellingAppRole AppRole3 = new() { Id = 3, IdString = AppRoleId3 }; + + + public override async Task SendQueryAsync(string query, object? variables = null, string? operationName = null) + { + await DefaultInit.DoNothing(); // qad avoid compiler warning + Type responseType = typeof(QueryResponseType); + if (responseType == typeof(List)) + { + List? appRoles = []; + if (query == ModellingQueries.getNewestAppRoles) + { + if (variables != null) + { + string pattern = variables?.GetType().GetProperties().First(o => o.Name == "pattern").GetValue(variables, null)?.ToString() ?? ""; + if (pattern == AppRoleId1 || pattern == "AR50%") + { + appRoles = [AppRole1]; + } + else if (pattern == AppRoleId2 || pattern == "AR9101234%") + { + appRoles = [AppRole2]; + } + else if (pattern == AppRoleId3 || pattern == "AR9901234%") + { + appRoles = [AppRole3]; + } + } + } + else + { + appRoles = [AppRole1]; + } + + GraphQLResponse response = new() { Data = appRoles }; + return response.Data; + } + else if (responseType == typeof(List)) + { + List? interfaces = []; + string intId = variables?.GetType().GetProperties().First(o => o.Name == "id").GetValue(variables, null)?.ToString() ?? ""; + if (intId == "1") + { + interfaces = [ new() + { + Name = "Interf1", + InterfacePermission = InterfacePermissions.Public.ToString(), + SourceAppRoles = [new(){ Content = new(){ Name = "AppRole1" } }], + SourceOtherGroups = [new(){ Content = new(){ Name = "NwGroup1" } }], + ServiceGroups = [new(){ Content = new(){ Name = "ServiceGrp1" } }] + }]; + } + else if (intId == "2") + { + interfaces = [ new() + { + Name = "Interf2", + InterfacePermission = InterfacePermissions.Public.ToString(), + DestinationAppServers = [new(){ Content = new(){ Name = "AppServer2" } }], + DestinationAppRoles = [new(){ Content = new(){ Name = "AppRole2" } }], + Services = [new(){ Content = new(){ Name = "Service2" } }] + }]; + } + else if (intId == "3") + { + interfaces = [ new() + { + Name = "Interf3", + InterfacePermission = InterfacePermissions.Restricted.ToString(), + PermittedOwnerWrappers = [new() { Owner = new() { Id = 1 } }], + SourceAppRoles = [new(){ Content = new(){ Name = "AppRole1" } }] + }]; + } + else if (intId == "4") + { + interfaces = [ new() + { + Name = "Interf4", + InterfacePermission = InterfacePermissions.Restricted.ToString(), + PermittedOwnerWrappers = [new() { Owner = new() { Id = 2 } }], + SourceAppRoles = [new(){ Content = new(){ Name = "AppRole1" } }] + }]; + } + else if (intId == "5") + { + interfaces = [ new() + { + Name = "Interf5", + InterfacePermission = InterfacePermissions.Private.ToString(), + AppId = 1, + PermittedOwnerWrappers = [new() { Owner = new() { Id = 1 } }], + SourceAppRoles = [new(){ Content = new(){ Name = "AppRole1" } }] + }]; + } + else if (intId == "6") + { + interfaces = [ new() + { + Name = "Interf6", + InterfacePermission = InterfacePermissions.Public.ToString(), + PermittedOwnerWrappers = [], + SourceAppRoles = [new(){ Content = new(){ Name = "AppRole1" } }] + }]; + } + else if (intId == "7") + { + interfaces = [ new() + { + Name = "Interf7", + InterfacePermission = InterfacePermissions.Private.ToString(), + AppId = 2, + PermittedOwnerWrappers = [new() { Owner = new() { Id = 1 } }], + SourceAppRoles = [new(){ Content = new(){ Name = "AppRole1" } }] + }]; + } + else if (intId == "8") + { + interfaces = [ new() + { + Name = "Interf8", + InterfacePermission = "Unknown", + AppId = 2, + SourceAppRoles = [new(){ Content = new(){ Name = "AppRole1" } }] + }]; + } + + GraphQLResponse response = new() { Data = interfaces }; + return response.Data; + } + throw new NotImplementedException(); + } + } +} diff --git a/roles/tests-unit/files/FWO.Test/ModellingOwnerAccessTest.cs b/roles/tests-unit/files/FWO.Test/ModellingOwnerAccessTest.cs new file mode 100644 index 0000000000..b2f80f41b4 --- /dev/null +++ b/roles/tests-unit/files/FWO.Test/ModellingOwnerAccessTest.cs @@ -0,0 +1,149 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Security.Claims; +using System.Threading.Tasks; +using FWO.Api.Client; +using FWO.Api.Client.Queries; +using FWO.Basics; +using FWO.Config.Api; +using FWO.Data; +using FWO.Services.Modelling; +using Microsoft.AspNetCore.Components.Authorization; +using NSubstitute; +using NUnit.Framework; + +namespace FWO.Test +{ + [TestFixture] + public class ModellingOwnerAccessTest + { + [Test] + public async Task ReporterViewAllUsesAllOwnersQuery() + { + ApiConnection apiConnection = Substitute.For(); + apiConnection.SendQueryAsync>(Arg.Any(), Arg.Any(), Arg.Any()) + .Returns(new List()); + + ClaimsPrincipal principal = BuildPrincipal(new List { Roles.ReporterViewAll }); + Task authStateTask = Task.FromResult(new AuthenticationState(principal)); + UserConfig userConfig = new SimulatedUserConfig(); + + await ModellingHandlerBase.GetOwnApps(authStateTask, userConfig, apiConnection, NoopDisplay); + + await apiConnection.Received(1) + .SendQueryAsync>(OwnerQueries.getOwnersWithConn, Arg.Any(), Arg.Any()); + } + + [Test] + public async Task ReporterUsesEditableOwnersClaim() + { + ApiConnection apiConnection = Substitute.For(); + apiConnection.SendQueryAsync>(Arg.Any(), Arg.Any(), Arg.Any()) + .Returns(new List()); + + ClaimsPrincipal principal = BuildPrincipal(new List { Roles.Reporter }, new Claim("x-hasura-editable-owners", "{1,2}")); + Task authStateTask = Task.FromResult(new AuthenticationState(principal)); + UserConfig userConfig = new SimulatedUserConfig(); + + await ModellingHandlerBase.GetOwnApps(authStateTask, userConfig, apiConnection, NoopDisplay); + + await apiConnection.Received(1) + .SendQueryAsync>(OwnerQueries.getEditableOwners, + Arg.Is(vars => HasOwnerIds(vars, new[] { 1, 2 })), + Arg.Any()); + } + + [Test] + public async Task ReporterUsesNamespacedEditableOwnersClaim() + { + ApiConnection apiConnection = Substitute.For(); + apiConnection.SendQueryAsync>(Arg.Any(), Arg.Any(), Arg.Any()) + .Returns(new List()); + + ClaimsPrincipal principal = BuildPrincipal( + new List { Roles.Reporter }, + new Claim("https://hasura.io/jwt/claims/x-hasura-editable-owners", "{1,2}")); + Task authStateTask = Task.FromResult(new AuthenticationState(principal)); + UserConfig userConfig = new SimulatedUserConfig(); + + await ModellingHandlerBase.GetOwnApps(authStateTask, userConfig, apiConnection, NoopDisplay); + + await apiConnection.Received(1) + .SendQueryAsync>(OwnerQueries.getEditableOwners, + Arg.Is(vars => HasOwnerIds(vars, new[] { 1, 2 })), + Arg.Any()); + } + + [Test] + public async Task ReporterUsesJsonEditableOwnersClaim() + { + ApiConnection apiConnection = Substitute.For(); + apiConnection.SendQueryAsync>(Arg.Any(), Arg.Any(), Arg.Any()) + .Returns(new List()); + + ClaimsPrincipal principal = BuildPrincipal( + new List { Roles.Reporter }, + new Claim("x-hasura-editable-owners", "[11,12]")); + Task authStateTask = Task.FromResult(new AuthenticationState(principal)); + UserConfig userConfig = new SimulatedUserConfig(); + + await ModellingHandlerBase.GetOwnApps(authStateTask, userConfig, apiConnection, NoopDisplay); + + await apiConnection.Received(1) + .SendQueryAsync>(OwnerQueries.getEditableOwners, + Arg.Is(vars => HasOwnerIds(vars, new[] { 11, 12 })), + Arg.Any()); + } + + [Test] + public async Task ReporterWithoutClaimUsesEmptyOwnerships() + { + ApiConnection apiConnection = Substitute.For(); + apiConnection.SendQueryAsync>(Arg.Any(), Arg.Any(), Arg.Any()) + .Returns(new List()); + + ClaimsPrincipal principal = BuildPrincipal(new List { Roles.Reporter }); + Task authStateTask = Task.FromResult(new AuthenticationState(principal)); + UserConfig userConfig = new SimulatedUserConfig(); + + await ModellingHandlerBase.GetOwnApps(authStateTask, userConfig, apiConnection, NoopDisplay); + + await apiConnection.Received(1) + .SendQueryAsync>(OwnerQueries.getEditableOwners, + Arg.Is(vars => HasOwnerIds(vars, Array.Empty())), + Arg.Any()); + } + + private static ClaimsPrincipal BuildPrincipal(List roles, Claim? extraClaim = null) + { + List claims = roles.ConvertAll(role => new Claim(ClaimTypes.Role, role)); + if (extraClaim != null) + { + claims.Add(extraClaim); + } + ClaimsIdentity identity = new(claims, "test"); + return new ClaimsPrincipal(identity); + } + + private static bool HasOwnerIds(object? vars, int[] expected) + { + if (vars == null) + { + return false; + } + + var prop = vars.GetType().GetProperty("appIds"); + if (prop?.GetValue(vars) is int[] ids) + { + return ids.Length == expected.Length && ids.OrderBy(id => id).SequenceEqual(expected.OrderBy(id => id)); + } + + return false; + } + + private static void NoopDisplay(Exception? _, string __, string ___, bool ____) + { + } + } +} diff --git a/roles/tests-unit/files/FWO.Test/ModellingServiceHandlerTest.cs b/roles/tests-unit/files/FWO.Test/ModellingServiceHandlerTest.cs new file mode 100644 index 0000000000..0fa51fc0e6 --- /dev/null +++ b/roles/tests-unit/files/FWO.Test/ModellingServiceHandlerTest.cs @@ -0,0 +1,148 @@ +using FWO.Api.Client; +using FWO.Basics; +using FWO.Config.Api; +using FWO.Data; +using FWO.Data.Modelling; +using FWO.Services.Modelling; +using NUnit.Framework; + +namespace FWO.Test +{ + [TestFixture] + internal class ModellingServiceHandlerTest + { + private sealed class ThrowingApiConnection : SimulatedApiConnection + { + public override Task SendQueryAsync(string query, object? variables = null, string? operationName = null) + { + throw new AssertionException("SendQueryAsync should not be called for validation-only tests."); + } + } + + private static UserConfig CreateUserConfig() + { + UserConfig userConfig = new(); + userConfig.Translate = new Dictionary + { + ["edit_service"] = "edit_service", + ["save_service"] = "save_service", + ["E5102"] = "E5102", + ["E5103"] = "E5103", + ["E5118"] = "E5118" + }; + return userConfig; + } + + [Test] + public async Task Save_ReturnsFalse_WhenProtocolMissing() + { + string? lastMessage = null; + ModellingService service = new() { Name = "svc", Protocol = new NetworkProtocol { Id = 0 } }; + ModellingServiceHandler handler = new( + new ThrowingApiConnection(), + CreateUserConfig(), + new FwoOwner { Id = 1 }, + service, + [], + [], + false, + (_, _, message, _) => lastMessage = message + ); + + bool result = await handler.Save(); + + Assert.That(result, Is.False); + Assert.That(lastMessage, Is.EqualTo("E5102")); + } + + [Test] + public async Task Save_ReturnsFalse_WhenPortOutOfRange() + { + string? lastMessage = null; + ModellingService service = new() + { + Name = "svc", + Protocol = new NetworkProtocol { Id = 6 }, + Port = 0 + }; + ModellingServiceHandler handler = new( + new ThrowingApiConnection(), + CreateUserConfig(), + new FwoOwner { Id = 1 }, + service, + [], + [], + false, + (_, _, message, _) => lastMessage = message + ); + + bool result = await handler.Save(); + + Assert.That(result, Is.False); + Assert.That(lastMessage, Is.EqualTo("E5103")); + } + + [Test] + public async Task Save_ReturnsFalse_WhenPortEndLessThanPort() + { + string? lastMessage = null; + ModellingService service = new() + { + Name = "svc", + Protocol = new NetworkProtocol { Id = 6 }, + Port = 100, + PortEnd = 50 + }; + ModellingServiceHandler handler = new( + new ThrowingApiConnection(), + CreateUserConfig(), + new FwoOwner { Id = 1 }, + service, + [], + [], + false, + (_, _, message, _) => lastMessage = message + ); + + bool result = await handler.Save(); + + Assert.That(result, Is.False); + Assert.That(lastMessage, Is.EqualTo("E5118")); + } + + [Test] + public void Reset_RestoresOriginalValues_AndUpdatesList() + { + ModellingService service = new() + { + Id = 9, + Name = "original", + Protocol = new NetworkProtocol { Id = 6 }, + Port = 80, + PortEnd = 80 + }; + List available = [service]; + List> availableSvcElems = []; + ModellingServiceHandler handler = new( + new ThrowingApiConnection(), + CreateUserConfig(), + new FwoOwner { Id = 1 }, + service, + available, + availableSvcElems, + false, + (_, _, _, _) => { } + ); + + handler.ActService.Name = "changed"; + handler.ActService.Port = 443; + available[0] = handler.ActService; + + handler.Reset(); + + Assert.That(handler.ActService.Name, Is.EqualTo("original")); + Assert.That(handler.ActService.Port, Is.EqualTo(80)); + Assert.That(available[0].Name, Is.EqualTo("original")); + } + } +} diff --git a/roles/tests-unit/files/FWO.Test/ModellingVarianceAnalysisTest.cs b/roles/tests-unit/files/FWO.Test/ModellingVarianceAnalysisTest.cs new file mode 100644 index 0000000000..0a56520d12 --- /dev/null +++ b/roles/tests-unit/files/FWO.Test/ModellingVarianceAnalysisTest.cs @@ -0,0 +1,908 @@ +using NUnit.Framework; +using NUnit.Framework.Legacy; +using FWO.Data; +using FWO.Data.Modelling; +using FWO.Data.Report; +using FWO.Data.Workflow; +using FWO.Services; +using FWO.Services.Modelling; +using FWO.Services.Workflow; +using FWO.Basics; + +namespace FWO.Test +{ + [TestFixture] + internal class ModellingVarianceAnalysisTest + { + const string stdRecogOpt = "{\"nwRegardIp\":true,\"nwRegardName\":false,\"nwRegardGroupName\":false,\"nwResolveGroup\":false,\"nwSeparateGroupAnalysis\":true,\"svcRegardPortAndProt\":true,\"svcRegardName\":false,\"svcRegardGroupName\":false,\"svcResolveGroup\":true,\"svcSplitPortRanges\":true}"; + const string oppRecogOpt = "{\"nwRegardIp\":false,\"nwRegardName\":true,\"nwRegardGroupName\":true,\"nwResolveGroup\":true,\"nwSeparateGroupAnalysis\":false,\"svcRegardPortAndProt\":false,\"svcRegardName\":true,\"svcRegardGroupName\":true,\"svcResolveGroup\":false,\"svcSplitPortRanges\":false}"; + const string grpNameRecogOpt = "{\"nwRegardIp\":true,\"nwRegardName\":false,\"nwRegardGroupName\":true,\"nwResolveGroup\":false,\"nwSeparateGroupAnalysis\":true,\"svcRegardPortAndProt\":true,\"svcRegardName\":false,\"svcRegardGroupName\":false,\"svcResolveGroup\":true,\"svcSplitPortRanges\":true}"; + + static readonly SimulatedUserConfig userConfig = new() + { + ModNamingConvention = "{\"networkAreaRequired\":true,\"fixedPartLength\":4,\"freePartLength\":5,\"networkAreaPattern\":\"NA\",\"appRolePattern\":\"AR\"}", + ModRolloutResolveServiceGroups = true, + CreateAppZones = true, + RuleRecognitionOption = stdRecogOpt, + ModSpecUserAreas = "[{\"area_id\":1,\"use_in_src\":true,\"use_in_dst\":false}, {\"area_id\":3,\"use_in_src\":true,\"use_in_dst\":true}]", + ModRolloutNatHeuristic = false + }; + static readonly ModellingVarianceAnalysisTestApiConn varianceAnalysisApiConnection = new(); + static readonly ExtStateTestApiConn extStateApiConnection = new(); + readonly ExtStateHandler extStateHandler = new(extStateApiConnection); + static readonly FwoOwner Application = new() { Id = 1, Name = "App1" }; + + static readonly ModellingAppServer AS1 = new() { Id = 1, Name = "AppServerUnchanged", Ip = "1.2.3.4" }; + static readonly ModellingAppServer AS2 = new() { Id = 2, Name = "AppServerNew1/32", Ip = "1.1.1.1", IpEnd = "1.1.1.1" }; + static readonly ModellingAppServer AS3 = new() { Id = 3, Name = "AppServerNew2", Ip = "2.2.2.2", IpEnd = "2.2.2.2" }; + + static readonly ModellingAppRole AR1 = new() { Id = 1, Name = "AppRole1", IdString = "AR504711-001", AppServers = [new() { Content = AS1 }, new() { Content = AS2 }] }; + static readonly ModellingAppRole AR2 = new() { Id = 2, Name = "AppRole2", IdString = "AR504711-002", AppServers = [new() { Content = AS3 }] }; + static readonly ModellingAppRole AR3 = new() { Id = 3, Name = "AppRole3", IdString = "AR504711-003", AppServers = [new() { Content = AS1 }] }; + + static readonly ModellingService Svc1 = new() { Id = 1, Name = "Service1", Port = 1000, PortEnd = 2000, ProtoId = 6 }; + static readonly ModellingService Svc2 = new() { Id = 2, Name = "Service2", Port = 4000, ProtoId = 6 }; + + static readonly ModellingServiceGroup SvcGrp1 = new() { Id = 1, Name = "SvcGrp1", Services = [new() { Content = Svc2 }] }; + + static readonly ModellingConnection Connection1 = new() + { + Id = 1, + Name = "Conn1", + SourceAppRoles = [new() { Content = AR1 }], + DestinationAppRoles = [new() { Content = AR2 }], + DestinationAppServers = [new() { Content = AS1 }], + ServiceGroups = [new() { Content = SvcGrp1 }], + Services = [new() { Content = Svc1 }] + }; + static readonly ModellingConnection Connection2 = new() + { + Id = 2, + Name = "Conn2", + SourceAppServers = [new() { Content = AS1 }], + DestinationAppRoles = [new() { Content = AR3 }], + Services = [new() { Content = Svc1 }] + }; + static readonly ModellingConnection Connection3 = new() + { + Id = 3, + Name = "Conn3", + Services = [new() { Content = Svc2 }] + }; + static readonly ModellingConnection Connection4 = new() + { + Id = 4, + Name = "Conn4", + SourceAppRoles = [new() { Content = AR1 }], + SourceAppServers = [new() { Content = AS1 }], + DestinationAppRoles = [new() { Content = AR3 }], + Services = [new() { Content = Svc1 }], + ExtraConfigs = [ new(){ ExtraConfigType = "IDA_user", ExtraConfigText = "SpecObj1" }, + new(){ ExtraConfigType = "IDA_user", ExtraConfigText = "SpecObj2" }, + new(){ ExtraConfigType = "IDA_user", ExtraConfigText = "SpecObj3" } ] + }; + static readonly ModellingConnection Connection5 = new() + { + Id = 5, + Name = "Conn5", + SourceAppRoles = [new() { Content = AR1 }], + SourceAppServers = [new() { Content = AS1 }], + DestinationAppRoles = [new() { Content = AR3 }], + Services = [new() { Content = Svc1 }], + ExtraConfigs = [ new(){ ExtraConfigType = "IDA-user", ExtraConfigText = "SpecObj1" }, + new(){ ExtraConfigType = "IDA_user", ExtraConfigText = "SpecObj2" } ] + }; + + static readonly ModellingConnection Connection6 = new() + { + Id = 6, + Name = "Conn6", + SourceAppRoles = [new() { Content = AR1 }], + DestinationAppServers = [new() { Content = AS1 }], + Services = [new() { Content = Svc1 }], + ExtraConfigs = [new() { ExtraConfigType = "NAT", ExtraConfigText = "To x.x.x.x" }] + }; + + static readonly ModellingConnection Connection7 = new() + { + Id = 7, + Name = "Conn7", + SourceAppRoles = [new() { Content = AR1 }], + DestinationAppServers = [new() { Content = AS1 }], + Services = [new() { Content = Svc1 }], + ExtraConfigs = [new() { ExtraConfigType = "NAT", ExtraConfigText = "To x.x.x.x" }] + }; + + + [SetUp] + public void Initialize() + { + } + + [Test] + public async Task TestGetSuccessfulRequestState() + { + ModellingVarianceAnalysis varianceAnalysis = new(varianceAnalysisApiConnection, extStateHandler, userConfig, Application, DefaultInit.DoNothing); + + ClassicAssert.AreEqual("Last successful: 1967-01-10 08:00:00, Implemented: 2025-06-26 08:00:00, Walter", await varianceAnalysis.GetSuccessfulRequestState()); + } + + [Test] + public async Task TestCheckExistingAppZone_FoundWithoutVariance() + { + ModellingVarianceAnalysis varianceAnalysis = new(varianceAnalysisApiConnection, extStateHandler, userConfig, Application, DefaultInit.DoNothing); + await varianceAnalysis.AnalyseModelledConnectionsForRequest([]); + + (bool appZoneFound, List mgtsWithVariance) = await varianceAnalysis.CheckExistingAppZone(); + + ClassicAssert.IsTrue(appZoneFound); + ClassicAssert.AreEqual(0, mgtsWithVariance.Count); + } + + [Test] + public async Task TestAnalyseModelledConnectionsForRequest() + { + List Connections = [Connection1, Connection6]; + ModellingVarianceAnalysis varianceAnalysis = new(varianceAnalysisApiConnection, extStateHandler, userConfig, Application, DefaultInit.DoNothing); + List TaskList = await varianceAnalysis.AnalyseModelledConnectionsForRequest(Connections); + + ClassicAssert.AreEqual(10, TaskList.Count); + + ClassicAssert.AreEqual(WfTaskType.group_modify.ToString(), TaskList[0].TaskType); + ClassicAssert.AreEqual("{\"GrpName\":\"AZ4711\",\"AppRoleId\":\"3\"}", TaskList[0].AdditionalInfo); + ClassicAssert.AreEqual("modify", TaskList[0].RequestAction); + ClassicAssert.AreEqual(1, TaskList[0].TaskNumber); + ClassicAssert.AreEqual("Update AppZone: AZ4711: Add Members", TaskList[0].Title); + ClassicAssert.AreEqual(4, TaskList[0].Elements.Count); + ClassicAssert.AreEqual("AppServerNew1_32", TaskList[0].Elements[0].Name); + ClassicAssert.AreEqual("AppServerNew2", TaskList[0].Elements[1].Name); + ClassicAssert.AreEqual("AppServerUnchanged", TaskList[0].Elements[2].Name); + ClassicAssert.AreEqual("AZ4711", TaskList[0].Elements[0].GroupName); + ClassicAssert.AreEqual("create", TaskList[0].Elements[0].RequestAction); + ClassicAssert.AreEqual("1.1.1.1/32", TaskList[0].Elements[0].IpString); + ClassicAssert.AreEqual("1.1.1.1/32", TaskList[0].Elements[0].IpEnd); + ClassicAssert.AreEqual("create", TaskList[0].Elements[1].RequestAction); + ClassicAssert.AreEqual("2.2.2.2/32", TaskList[0].Elements[1].IpString); + ClassicAssert.AreEqual("2.2.2.2/32", TaskList[0].Elements[1].IpEnd); + ClassicAssert.AreEqual("source", TaskList[0].Elements[0].Field); + ClassicAssert.AreEqual("unchanged", TaskList[0].Elements[2].RequestAction); + ClassicAssert.AreEqual("1.2.3.4", TaskList[0].Elements[2].IpString); + ClassicAssert.AreEqual("unchanged", TaskList[0].Elements[3].RequestAction); + ClassicAssert.AreEqual("1.0.0.0", TaskList[0].Elements[3].IpString); + + ClassicAssert.AreEqual(WfTaskType.group_modify.ToString(), TaskList[1].TaskType); + ClassicAssert.AreEqual("{\"GrpName\":\"AR504711-001\",\"AppRoleId\":\"1\"}", TaskList[1].AdditionalInfo); + ClassicAssert.AreEqual("modify", TaskList[1].RequestAction); + ClassicAssert.AreEqual(2, TaskList[1].TaskNumber); + ClassicAssert.AreEqual("Update AppRole: AR504711-001: Add Members", TaskList[1].Title); + ClassicAssert.AreEqual(1, TaskList[1].ManagementId); + ClassicAssert.AreEqual("Checkpoint1", TaskList[1].OnManagement?.Name); + ClassicAssert.AreEqual(3, TaskList[1].Elements.Count); + ClassicAssert.AreEqual("AppServerNew1/32", TaskList[1].Elements[0].Name); + ClassicAssert.AreEqual("AR504711-001", TaskList[1].Elements[0].GroupName); + ClassicAssert.AreEqual("1.1.1.1", TaskList[1].Elements[0].IpString); + ClassicAssert.AreEqual("source", TaskList[1].Elements[0].Field); + ClassicAssert.AreEqual("addAfterCreation", TaskList[1].Elements[0].RequestAction); + ClassicAssert.AreEqual("AppServerUnchanged", TaskList[1].Elements[1].Name); + ClassicAssert.AreEqual("AR504711-001", TaskList[1].Elements[1].GroupName); + ClassicAssert.AreEqual("1.2.3.4", TaskList[1].Elements[1].IpString); + ClassicAssert.AreEqual("source", TaskList[1].Elements[1].Field); + ClassicAssert.AreEqual("unchanged", TaskList[1].Elements[1].RequestAction); + ClassicAssert.AreEqual("AppServerOld", TaskList[1].Elements[2].Name); + ClassicAssert.AreEqual("AR504711-001", TaskList[1].Elements[2].GroupName); + ClassicAssert.AreEqual("1.0.0.0", TaskList[1].Elements[2].IpString); + ClassicAssert.AreEqual("source", TaskList[1].Elements[2].Field); + ClassicAssert.AreEqual("unchanged", TaskList[1].Elements[2].RequestAction); + + ClassicAssert.AreEqual(WfTaskType.group_create.ToString(), TaskList[2].TaskType); + ClassicAssert.AreEqual("{\"GrpName\":\"AR504711-002\",\"AppRoleId\":\"2\"}", TaskList[2].AdditionalInfo); + ClassicAssert.AreEqual("create", TaskList[2].RequestAction); + ClassicAssert.AreEqual(3, TaskList[2].TaskNumber); + ClassicAssert.AreEqual("New AppRole: AR504711-002", TaskList[2].Title); + ClassicAssert.AreEqual(1, TaskList[2].Elements.Count); + ClassicAssert.AreEqual("AppServerNew2", TaskList[2].Elements[0].Name); + ClassicAssert.AreEqual("AR504711-002", TaskList[2].Elements[0].GroupName); + ClassicAssert.AreEqual("2.2.2.2", TaskList[2].Elements[0].IpString); + ClassicAssert.AreEqual("2.2.2.2", TaskList[2].Elements[0].IpEnd); + ClassicAssert.AreEqual("source", TaskList[2].Elements[0].Field); + ClassicAssert.AreEqual("addAfterCreation", TaskList[2].Elements[0].RequestAction); + + ClassicAssert.AreEqual(WfTaskType.access.ToString(), TaskList[3].TaskType); + ClassicAssert.AreEqual("{\"ConnId\":\"6\"}", TaskList[3].AdditionalInfo); + ClassicAssert.AreEqual(1, TaskList[3].Comments.Count); + ClassicAssert.AreEqual("FWOC6, Implementation Instructions: NAT: To x.x.x.x", TaskList[3].Comments[0].Comment.CommentText); + ClassicAssert.AreEqual("create", TaskList[3].RequestAction); + ClassicAssert.AreEqual(4, TaskList[3].TaskNumber); + ClassicAssert.AreEqual("New Connection: Conn6 (FWOC6)", TaskList[3].Title); + ClassicAssert.AreEqual(1, TaskList[3].Owners.Count); + ClassicAssert.AreEqual("App1", TaskList[3].Owners[0].Owner.Name); + ClassicAssert.AreEqual(3, TaskList[3].Elements.Count); + ClassicAssert.AreEqual(null, TaskList[3].Elements[0].Name); + ClassicAssert.AreEqual("AR504711-001", TaskList[3].Elements[0].GroupName); + ClassicAssert.AreEqual(null, TaskList[3].Elements[0].IpString); + ClassicAssert.AreEqual("source", TaskList[3].Elements[0].Field); + ClassicAssert.AreEqual("create", TaskList[3].Elements[0].RequestAction); + ClassicAssert.AreEqual("AppServerUnchanged", TaskList[3].Elements[1].Name); + ClassicAssert.AreEqual(null, TaskList[3].Elements[1].GroupName); + ClassicAssert.AreEqual("1.2.3.4", TaskList[3].Elements[1].IpString); + ClassicAssert.AreEqual("destination", TaskList[3].Elements[1].Field); + ClassicAssert.AreEqual("create", TaskList[3].Elements[1].RequestAction); + ClassicAssert.AreEqual("Service1", TaskList[3].Elements[2].Name); + ClassicAssert.AreEqual(null, TaskList[3].Elements[2].GroupName); + ClassicAssert.AreEqual(6, TaskList[3].Elements[2].ProtoId); + ClassicAssert.AreEqual(1000, TaskList[3].Elements[2].Port); + ClassicAssert.AreEqual(2000, TaskList[3].Elements[2].PortEnd); + ClassicAssert.AreEqual("service", TaskList[3].Elements[2].Field); + ClassicAssert.AreEqual("create", TaskList[3].Elements[2].RequestAction); + + ClassicAssert.AreEqual(WfTaskType.rule_modify.ToString(), TaskList[4].TaskType); + ClassicAssert.AreEqual("Change Rule: FWOC1", TaskList[4].Title); + ClassicAssert.AreEqual(WfTaskType.rule_modify.ToString(), TaskList[5].TaskType); + ClassicAssert.AreEqual("Change Rule: FWOC1again", TaskList[5].Title); + + ClassicAssert.AreEqual(WfTaskType.rule_delete.ToString(), TaskList[6].TaskType); + ClassicAssert.AreEqual("Delete Rule: xxxFWOC2yyy", TaskList[6].Title); + ClassicAssert.AreEqual(WfTaskType.rule_delete.ToString(), TaskList[7].TaskType); + ClassicAssert.AreEqual("Delete Rule: FWOC4", TaskList[7].Title); + + ClassicAssert.AreEqual(WfTaskType.group_modify.ToString(), TaskList[8].TaskType); + ClassicAssert.AreEqual("{\"GrpName\":\"AZ4711\",\"AppRoleId\":\"3\"}", TaskList[8].AdditionalInfo); + ClassicAssert.AreEqual("modify", TaskList[8].RequestAction); + ClassicAssert.AreEqual(4, TaskList[8].Elements.Count); + ClassicAssert.AreEqual("AppServerOld", TaskList[8].Elements[0].Name); + ClassicAssert.AreEqual("delete", TaskList[8].Elements[0].RequestAction); + ClassicAssert.AreEqual("AppServerUnchanged", TaskList[8].Elements[1].Name); + ClassicAssert.AreEqual("unchanged", TaskList[8].Elements[1].RequestAction); + ClassicAssert.AreEqual("AppServerNew1_32", TaskList[8].Elements[2].Name); + ClassicAssert.AreEqual("unchanged", TaskList[8].Elements[2].RequestAction); + ClassicAssert.AreEqual("AppServerNew2", TaskList[8].Elements[3].Name); + + ClassicAssert.AreEqual(WfTaskType.group_modify.ToString(), TaskList[9].TaskType); + ClassicAssert.AreEqual("{\"GrpName\":\"AR504711-001\",\"AppRoleId\":\"1\"}", TaskList[9].AdditionalInfo); + ClassicAssert.AreEqual("modify", TaskList[9].RequestAction); + ClassicAssert.AreEqual(10, TaskList[9].TaskNumber); + ClassicAssert.AreEqual("Update AppRole: AR504711-001: Remove Members", TaskList[9].Title); + ClassicAssert.AreEqual(1, TaskList[9].ManagementId); + ClassicAssert.AreEqual("Checkpoint1", TaskList[9].OnManagement?.Name); + ClassicAssert.AreEqual(3, TaskList[9].Elements.Count); + ClassicAssert.AreEqual("AppServerOld", TaskList[9].Elements[0].Name); + ClassicAssert.AreEqual("AR504711-001", TaskList[9].Elements[0].GroupName); + ClassicAssert.AreEqual("1.0.0.0", TaskList[9].Elements[0].IpString); + ClassicAssert.AreEqual("source", TaskList[9].Elements[0].Field); + ClassicAssert.AreEqual("delete", TaskList[9].Elements[0].RequestAction); + ClassicAssert.AreEqual("AppServerUnchanged", TaskList[9].Elements[1].Name); + ClassicAssert.AreEqual("AR504711-001", TaskList[9].Elements[1].GroupName); + ClassicAssert.AreEqual("1.2.3.4", TaskList[9].Elements[1].IpString); + ClassicAssert.AreEqual("source", TaskList[9].Elements[1].Field); + ClassicAssert.AreEqual("unchanged", TaskList[9].Elements[1].RequestAction); + ClassicAssert.AreEqual("AppServerNew1/32", TaskList[9].Elements[2].Name); + ClassicAssert.AreEqual("AR504711-001", TaskList[9].Elements[2].GroupName); + ClassicAssert.AreEqual("1.1.1.1", TaskList[9].Elements[2].IpString); + ClassicAssert.AreEqual("source", TaskList[9].Elements[2].Field); + ClassicAssert.AreEqual("unchanged", TaskList[9].Elements[2].RequestAction); + } + + [Test] + public async Task TestAnalyseModelledConnectionsForRequestWithServiceGroups() + { + List Connections = [Connection1]; + userConfig.ModRolloutResolveServiceGroups = false; + ModellingVarianceAnalysis varianceAnalysis = new(varianceAnalysisApiConnection, extStateHandler, userConfig, Application, DefaultInit.DoNothing); + List TaskList = await varianceAnalysis.AnalyseModelledConnectionsForRequest(Connections); + + ClassicAssert.AreEqual(10, TaskList.Count); + ClassicAssert.AreEqual(WfTaskType.group_modify.ToString(), TaskList[0].TaskType); + ClassicAssert.AreEqual(WfTaskType.group_modify.ToString(), TaskList[1].TaskType); + ClassicAssert.AreEqual(WfTaskType.group_create.ToString(), TaskList[2].TaskType); + ClassicAssert.AreEqual(WfTaskType.group_create.ToString(), TaskList[3].TaskType); + ClassicAssert.AreEqual(WfTaskType.rule_modify.ToString(), TaskList[4].TaskType); + ClassicAssert.AreEqual(WfTaskType.rule_modify.ToString(), TaskList[5].TaskType); + ClassicAssert.AreEqual(WfTaskType.rule_delete.ToString(), TaskList[6].TaskType); + ClassicAssert.AreEqual(WfTaskType.rule_delete.ToString(), TaskList[7].TaskType); + ClassicAssert.AreEqual(WfTaskType.group_modify.ToString(), TaskList[8].TaskType); + ClassicAssert.AreEqual(WfTaskType.group_modify.ToString(), TaskList[9].TaskType); + + ClassicAssert.AreEqual("{\"GrpName\":\"SvcGrp1\",\"SvcGrpId\":\"1\"}", TaskList[3].AdditionalInfo); + ClassicAssert.AreEqual("create", TaskList[3].RequestAction); + ClassicAssert.AreEqual(4, TaskList[3].TaskNumber); + ClassicAssert.AreEqual("New Servicegroup: SvcGrp1", TaskList[3].Title); + ClassicAssert.AreEqual(1, TaskList[3].Elements.Count); + ClassicAssert.AreEqual("Service2", TaskList[3].Elements[0].Name); + ClassicAssert.AreEqual("SvcGrp1", TaskList[3].Elements[0].GroupName); + ClassicAssert.AreEqual(6, TaskList[3].Elements[0].ProtoId); + ClassicAssert.AreEqual(4000, TaskList[3].Elements[0].Port); + ClassicAssert.AreEqual("service", TaskList[3].Elements[0].Field); + ClassicAssert.AreEqual("create", TaskList[3].Elements[0].RequestAction); + userConfig.ModRolloutResolveServiceGroups = true; + } + + [Test] + public async Task TestAnalyseModelledConnectionsForRequest_ContainsNetworkAreaElementsInAccessTask() + { + ModellingConnection connection = new() + { + Id = 72, + Name = "Conn72", + SourceAreas = [new() { Content = new() { Id = 72, Name = "AreaSrc72", IdString = "NA5072-001" } }], + DestinationAreas = [new() { Content = new() { Id = 73, Name = "AreaDst72", IdString = "NA5072-002" } }], + Services = [new() { Content = Svc1 }] + }; + + ModellingVarianceAnalysis varianceAnalysis = new(varianceAnalysisApiConnection, extStateHandler, userConfig, Application, DefaultInit.DoNothing); + List taskList = await varianceAnalysis.AnalyseModelledConnectionsForRequest([connection]); + WfReqTask? accessTask = taskList.FirstOrDefault(t => t.GetAddInfoValue(AdditionalInfoKeys.ConnId) == "72"); + + ClassicAssert.IsNotNull(accessTask); + ClassicAssert.IsNotNull(accessTask!.Elements.FirstOrDefault(e => + e.Field == ElemFieldType.source.ToString() && + e.GroupName == "NA5072-001" && + e.RequestAction == RequestAction.create.ToString())); + ClassicAssert.IsNotNull(accessTask.Elements.FirstOrDefault(e => + e.Field == ElemFieldType.destination.ToString() && + e.GroupName == "NA5072-002" && + e.RequestAction == RequestAction.create.ToString())); + } + + [Test] + public async Task TestAnalyseModelledConnectionsForRequest_ContainsAppServerElementsInAccessTask() + { + ModellingConnection connection = new() + { + Id = 73, + Name = "Conn73", + SourceAppServers = [new() { Content = new() { Id = 731, Name = "Src73", Ip = "10.73.0.1", IpEnd = "10.73.0.1" } }], + DestinationAppServers = [new() { Content = new() { Id = 732, Name = "Dst73", Ip = "10.73.0.2", IpEnd = "10.73.0.2" } }], + Services = [new() { Content = Svc1 }] + }; + + ModellingVarianceAnalysis varianceAnalysis = new(varianceAnalysisApiConnection, extStateHandler, userConfig, Application, DefaultInit.DoNothing); + List taskList = await varianceAnalysis.AnalyseModelledConnectionsForRequest([connection]); + WfReqTask? accessTask = taskList.FirstOrDefault(t => t.GetAddInfoValue(AdditionalInfoKeys.ConnId) == "73"); + + ClassicAssert.IsNotNull(accessTask); + ClassicAssert.IsNotNull(accessTask!.Elements.FirstOrDefault(e => + e.Field == ElemFieldType.source.ToString() && + e.Name == "Src73" && + e.IpString == "10.73.0.1")); + ClassicAssert.IsNotNull(accessTask.Elements.FirstOrDefault(e => + e.Field == ElemFieldType.destination.ToString() && + e.Name == "Dst73" && + e.IpString == "10.73.0.2")); + } + + [Test] + public async Task TestAnalyseModelledConnectionsForRequest_DeleteRuleContainsModelledElementsFromDeletedConn() + { + ModellingConnection dokuConn = new() + { + Id = 5, + Name = "DokuConn5", + SourceAreas = [new() { Content = new() { Id = 81, Name = "AreaSrc5", IdString = "NA5005-001" } }], + DestinationAreas = [new() { Content = new() { Id = 82, Name = "AreaDst5", IdString = "NA5005-002" } }], + SourceAppRoles = [new() { Content = new() { Id = 91, Name = "RoleSrc5", IdString = "AR5005-001", AppServers = [new() { Content = AS1 }] } }], + DestinationAppRoles = [new() { Content = new() { Id = 92, Name = "RoleDst5", IdString = "AR5005-002", AppServers = [new() { Content = AS1 }] } }], + SourceAppServers = [new() { Content = new() { Id = 93, Name = "Src5", Ip = "10.5.0.1", IpEnd = "10.5.0.1" } }], + DestinationAppServers = [new() { Content = new() { Id = 94, Name = "Dst5", Ip = "10.5.0.2", IpEnd = "10.5.0.2" } }], + Services = [new() { Content = Svc1 }], + ExtraConfigs = + [ + new() { ExtraConfigType = "Doku_Reason", ExtraConfigText = "doc only" }, + new() { ExtraConfigType = "IDA_user", ExtraConfigText = "SpecObjX" }, + new() { ExtraConfigType = "updatable_nwobj", ExtraConfigText = "ObjY" } + ] + }; + + ModellingVarianceAnalysis varianceAnalysis = new(varianceAnalysisApiConnection, extStateHandler, userConfig, Application, DefaultInit.DoNothing); + List taskList = await varianceAnalysis.AnalyseModelledConnectionsForRequest([Connection1, dokuConn]); + WfReqTask? deleteTask = taskList.FirstOrDefault(t => t.Title == "Delete Rule: FWOC5"); + + ClassicAssert.IsNotNull(deleteTask); + ClassicAssert.IsNotNull(deleteTask!.Elements.FirstOrDefault(e => + e.Field == ElemFieldType.modelled_source.ToString() && + e.GroupName == "NA5005-001" && + e.RequestAction == RequestAction.unchanged.ToString())); + ClassicAssert.IsNotNull(deleteTask.Elements.FirstOrDefault(e => + e.Field == ElemFieldType.modelled_destination.ToString() && + e.GroupName == "NA5005-002" && + e.RequestAction == RequestAction.unchanged.ToString())); + ClassicAssert.IsNotNull(deleteTask.Elements.FirstOrDefault(e => + e.Field == ElemFieldType.modelled_source.ToString() && + e.Name == "Src5" && + e.IpString == "10.5.0.1" && + e.RequestAction == RequestAction.unchanged.ToString())); + ClassicAssert.IsNotNull(deleteTask.Elements.FirstOrDefault(e => + e.Field == ElemFieldType.modelled_destination.ToString() && + e.Name == "Dst5" && + e.IpString == "10.5.0.2" && + e.RequestAction == RequestAction.unchanged.ToString())); + } + + [Test] + public async Task TestAnalyseModelledConnectionsForRequest_RequestOnlyOwnObjectsKeepsForeignAppRolesInAccessTask() + { + userConfig.ModRequestOnlyOwnObjects = true; + try + { + ModellingConnection connection = new() + { + Id = 67, + AppId = 1, + UsedInterfaceId = 101, + Name = "Conn67", + SourceAppRoles = + [ + new() { Content = new() { Name = "OwnAppRole", IdString = "OWN-AR", AppId = 1 } }, + new() { Content = new() { Name = "ForeignAppRole", IdString = "AZ4711", AppId = 2 } } + ], + DestinationAppServers = [new() { Content = AS1 }], + Services = [new() { Content = Svc1 }] + }; + + ModellingVarianceAnalysis varianceAnalysis = new(varianceAnalysisApiConnection, extStateHandler, userConfig, Application, DefaultInit.DoNothing); + List taskList = await varianceAnalysis.AnalyseModelledConnectionsForRequest([connection]); + WfReqTask? accessTask = taskList.FirstOrDefault(t => t.GetAddInfoValue(AdditionalInfoKeys.ConnId) == "67"); + + ClassicAssert.IsNotNull(accessTask); + List sourceGroups = accessTask!.Elements + .Where(e => e.Field == ElemFieldType.source.ToString() && !string.IsNullOrEmpty(e.GroupName)) + .Select(e => e.GroupName!) + .ToList(); + CollectionAssert.Contains(sourceGroups, "OWN-AR"); + CollectionAssert.Contains(sourceGroups, "AZ4711"); + ClassicAssert.IsNull(taskList.FirstOrDefault(t => t.Title == "New AppRole: AZ4711")); + ClassicAssert.IsNull(taskList.FirstOrDefault(t => t.Title == "Update AppRole: AZ4711" + userConfig.GetText("add_members"))); + ClassicAssert.IsFalse(connection.GetBoolProperty(ConState.ForeignNonProdObjects.ToString())); + } + finally + { + userConfig.ModRequestOnlyOwnObjects = false; + } + } + + [Test] + public async Task TestAnalyseModelledConnectionsForRequest_RequestOnlyOwnObjectsKeepsForeignServiceGroupsInAccessTask() + { + userConfig.ModRequestOnlyOwnObjects = true; + userConfig.ModRolloutResolveServiceGroups = false; + try + { + ModellingServiceGroup ownSvcGrp = new() { Id = 10, Name = "OwnSvcGrp", AppId = 1, Services = [new() { Content = Svc1 }] }; + ModellingServiceGroup foreignSvcGrp = new() { Id = 11, Name = "ForeignSvcGrp", AppId = 2, Services = [new() { Content = Svc2 }] }; + ModellingConnection connection = new() + { + Id = 69, + AppId = 1, + UsedInterfaceId = 101, + Name = "Conn69", + DestinationAppServers = [new() { Content = AS1 }], + ServiceGroups = + [ + new() { Content = ownSvcGrp }, + new() { Content = foreignSvcGrp } + ] + }; + + ModellingVarianceAnalysis varianceAnalysis = new(varianceAnalysisApiConnection, extStateHandler, userConfig, Application, DefaultInit.DoNothing); + List taskList = await varianceAnalysis.AnalyseModelledConnectionsForRequest([connection]); + WfReqTask? accessTask = taskList.FirstOrDefault(t => t.GetAddInfoValue(AdditionalInfoKeys.ConnId) == "69"); + + ClassicAssert.IsNotNull(accessTask); + List serviceGroups = accessTask!.Elements + .Where(e => e.Field == ElemFieldType.service.ToString() && !string.IsNullOrEmpty(e.GroupName)) + .Select(e => e.GroupName!) + .ToList(); + CollectionAssert.Contains(serviceGroups, "OwnSvcGrp"); + CollectionAssert.Contains(serviceGroups, "ForeignSvcGrp"); + ClassicAssert.IsNotNull(taskList.FirstOrDefault(t => t.Title == "New Servicegroup: OwnSvcGrp")); + ClassicAssert.IsNull(taskList.FirstOrDefault(t => t.Title == "New Servicegroup: ForeignSvcGrp")); + } + finally + { + userConfig.ModRolloutResolveServiceGroups = true; + userConfig.ModRequestOnlyOwnObjects = false; + } + } + + [Test] + public async Task TestAnalyseModelledConnectionsForRequest_RequestOnlyOwnObjectsAnalysesInterfaceAppRoles() + { + userConfig.ModRequestOnlyOwnObjects = true; + userConfig.CreateAppZones = false; + try + { + ModellingAppRole ownAppRole = new() { Id = 2, Name = "AppRole2", IdString = "AR504711-002", AppId = 1, AppServers = [new() { Content = AS3 }] }; + ModellingConnection interfaceConnection = new() + { + Id = 68, + AppId = 1, + IsInterface = true, + IsPublished = true, + Name = "Interface68", + SourceAppRoles = [new() { Content = ownAppRole }] + }; + + ModellingVarianceAnalysis varianceAnalysis = new(varianceAnalysisApiConnection, extStateHandler, userConfig, Application, DefaultInit.DoNothing); + List taskList = await varianceAnalysis.AnalyseModelledConnectionsForRequest([interfaceConnection]); + + WfReqTask? appRoleCreateTask = taskList.FirstOrDefault(t => + t.TaskType == WfTaskType.group_create.ToString() && + t.Title == "New AppRole: AR504711-002"); + + ClassicAssert.IsNotNull(appRoleCreateTask); + } + finally + { + userConfig.CreateAppZones = true; + userConfig.ModRequestOnlyOwnObjects = false; + } + } + + [Test] + public async Task TestAnalyseModelledConnectionsForRequest_RequestOnlyOwnObjectsAvoidsDuplicateInterfaceAppRoleTasks() + { + userConfig.ModRequestOnlyOwnObjects = true; + userConfig.CreateAppZones = false; + try + { + ModellingAppRole ownAppRole = new() { Id = 2, Name = "AppRole2", IdString = "AR504711-002", AppId = 1, AppServers = [new() { Content = AS3 }] }; + ModellingConnection interfaceConn1 = new() + { + Id = 70, + AppId = 1, + IsInterface = true, + IsPublished = true, + Name = "Interface70", + SourceAppRoles = [new() { Content = ownAppRole }] + }; + + ModellingConnection interfaceConn2 = new() + { + Id = 71, + AppId = 1, + IsInterface = true, + IsPublished = true, + Name = "Interface71", + DestinationAppRoles = [new() { Content = ownAppRole }] + }; + + ModellingVarianceAnalysis varianceAnalysis = new(varianceAnalysisApiConnection, extStateHandler, userConfig, Application, DefaultInit.DoNothing); + List taskList = await varianceAnalysis.AnalyseModelledConnectionsForRequest([interfaceConn1, interfaceConn2]); + + ClassicAssert.AreEqual(1, taskList.Count(t => t.Title == "New AppRole: AR504711-002")); + } + finally + { + userConfig.CreateAppZones = true; + userConfig.ModRequestOnlyOwnObjects = false; + } + } + + [Test] + public async Task TestAnalyseRules() + { + // open: NA, Enabled, Negated, DropRule + + List Connections = [Connection1, Connection2, Connection3]; + ModellingVarianceAnalysis varianceAnalysis = new(varianceAnalysisApiConnection, extStateHandler, userConfig, Application, DefaultInit.DoNothing); + ModellingFilter modellingFilter = new(); + ModellingVarianceResult result = await varianceAnalysis.AnalyseRulesVsModelledConnections(Connections, modellingFilter); + + ClassicAssert.AreEqual(1, result.UnModelledRules.Count); + ClassicAssert.AreEqual(1, result.UnModelledRules[1].Count); + ClassicAssert.AreEqual("NonModelledRule", result.UnModelledRules[1][0].Name); + + ClassicAssert.AreEqual(1, result.ConnsNotImplemented.Count); + ClassicAssert.AreEqual(3, result.ConnsNotImplemented[0].Id); + ClassicAssert.AreEqual("Conn3", result.ConnsNotImplemented[0].Name); + + ClassicAssert.AreEqual(1, result.OkRules.Count); + ClassicAssert.AreEqual("Conn2", result.OkRules[0].ModelledConnection.Name); + ClassicAssert.AreEqual(1, result.OkRules[0].ImplementedRules.Count); + ClassicAssert.AreEqual("xxxFWOC2yyy", result.OkRules[0].ImplementedRules[0].Name); + + ClassicAssert.AreEqual(1, result.RuleDifferences.Count); + ClassicAssert.AreEqual("Conn1", result.RuleDifferences[0].ModelledConnection.Name); + ClassicAssert.AreEqual(2, result.RuleDifferences[0].ImplementedRules.Count); + ClassicAssert.AreEqual(1, result.RuleDifferences[0].ImplementedRules[0].DisregardedFroms.Length); + ClassicAssert.AreEqual("AR504711-001", result.RuleDifferences[0].ImplementedRules[0].DisregardedFroms[0].Object.Name); + ClassicAssert.AreEqual(1, result.RuleDifferences[0].ImplementedRules[0].DisregardedTos.Length); + ClassicAssert.AreEqual("AppServerUnchanged", result.RuleDifferences[0].ImplementedRules[0].DisregardedTos[0].Object.Name); + ClassicAssert.AreEqual(1, result.RuleDifferences[0].ImplementedRules[0].DisregardedServices.Length); + ClassicAssert.AreEqual("Service2", result.RuleDifferences[0].ImplementedRules[0].DisregardedServices[0].Name); + ClassicAssert.AreEqual(1, result.RuleDifferences[0].ImplementedRules[0].Froms.Length); + ClassicAssert.AreEqual("AppServerOld", result.RuleDifferences[0].ImplementedRules[0].Froms[0].Object.Name); + ClassicAssert.AreEqual(true, result.RuleDifferences[0].ImplementedRules[0].Froms[0].Object.IsSurplus); + ClassicAssert.AreEqual(1, result.RuleDifferences[0].ImplementedRules[0].Tos.Length); + ClassicAssert.AreEqual("AR504711-001", result.RuleDifferences[0].ImplementedRules[0].Tos[0].Object.Name); + ClassicAssert.AreEqual(false, result.RuleDifferences[0].ImplementedRules[0].Tos[0].Object.IsSurplus); + ClassicAssert.AreEqual(1, result.RuleDifferences[0].ImplementedRules[0].Services.Length); + ClassicAssert.AreEqual("Service1", result.RuleDifferences[0].ImplementedRules[0].Services[0].Content.Name); + ClassicAssert.AreEqual(false, result.RuleDifferences[0].ImplementedRules[0].Services[0].Content.IsSurplus); + ClassicAssert.AreEqual(2, result.RuleDifferences[0].ImplementedRules[1].DisregardedServices.Length); + ClassicAssert.AreEqual(1999, result.RuleDifferences[0].ImplementedRules[1].DisregardedServices[0].DestinationPort); + ClassicAssert.AreEqual(2000, result.RuleDifferences[0].ImplementedRules[1].DisregardedServices[0].DestinationPortEnd); + ClassicAssert.AreEqual(4000, result.RuleDifferences[0].ImplementedRules[1].DisregardedServices[1].DestinationPort); + ClassicAssert.AreEqual(2, result.RuleDifferences[0].ImplementedRules[1].Services.Length); + ClassicAssert.AreEqual(990, result.RuleDifferences[0].ImplementedRules[1].Services[0].Content.DestinationPort); + ClassicAssert.AreEqual(999, result.RuleDifferences[0].ImplementedRules[1].Services[0].Content.DestinationPortEnd); + ClassicAssert.AreEqual(true, result.RuleDifferences[0].ImplementedRules[1].Services[0].Content.IsSurplus); + ClassicAssert.AreEqual(1000, result.RuleDifferences[0].ImplementedRules[1].Services[1].Content.DestinationPort); + ClassicAssert.AreEqual(1998, result.RuleDifferences[0].ImplementedRules[1].Services[1].Content.DestinationPortEnd); + ClassicAssert.AreEqual(false, result.RuleDifferences[0].ImplementedRules[1].Services[1].Content.IsSurplus); + + ClassicAssert.AreEqual(1, result.DifferingAppRoles.Count); + ClassicAssert.AreEqual(1, result.DifferingAppRoles[1].Count); + ClassicAssert.AreEqual("AR504711-001", result.DifferingAppRoles[1][0].IdString); + ClassicAssert.AreEqual(1, result.DifferingAppRoles[1][0].SurplusAppServers.Count); + ClassicAssert.AreEqual("AppServerOld", result.DifferingAppRoles[1][0].SurplusAppServers[0].Content.Name); + ClassicAssert.AreEqual("1.0.0.0", result.DifferingAppRoles[1][0].SurplusAppServers[0].Content.Ip); + ClassicAssert.AreEqual(2, result.DifferingAppRoles[1][0].AppServers.Count); + ClassicAssert.AreEqual("AppServerUnchanged", result.DifferingAppRoles[1][0].AppServers[0].Content.Name); + ClassicAssert.AreEqual("1.2.3.4", result.DifferingAppRoles[1][0].AppServers[0].Content.Ip); + ClassicAssert.AreEqual(false, result.DifferingAppRoles[1][0].AppServers[0].Content.NotImplemented); + ClassicAssert.AreEqual("AppServerNew1/32", result.DifferingAppRoles[1][0].AppServers[1].Content.Name); + ClassicAssert.AreEqual(true, result.DifferingAppRoles[1][0].AppServers[1].Content.NotImplemented); + } + + [Test] + public async Task TestAnalyseRulesSpecialUserObjects() + { + List Connections = [Connection4]; + ModellingVarianceAnalysis varianceAnalysis = new(varianceAnalysisApiConnection, extStateHandler, userConfig, Application, DefaultInit.DoNothing); + ModellingFilter modellingFilter = new(); + ModellingVarianceResult result = await varianceAnalysis.AnalyseRulesVsModelledConnections(Connections, modellingFilter); + + ClassicAssert.AreEqual(0, result.ConnsNotImplemented.Count); + ClassicAssert.AreEqual(1, result.RuleDifferences.Count); + ClassicAssert.AreEqual("Conn4", result.RuleDifferences[0].ModelledConnection.Name); + ClassicAssert.AreEqual(1, result.RuleDifferences[0].ImplementedRules.Count); + ClassicAssert.AreEqual(0, result.RuleDifferences[0].ImplementedRules[0].DisregardedFroms.Length); + ClassicAssert.AreEqual(0, result.RuleDifferences[0].ImplementedRules[0].DisregardedTos.Length); + ClassicAssert.AreEqual(2, result.RuleDifferences[0].ImplementedRules[0].Froms.Length); + ClassicAssert.AreEqual("SpecObj1", result.RuleDifferences[0].ImplementedRules[0].Froms[0].Object.Name); + ClassicAssert.AreEqual(false, result.RuleDifferences[0].ImplementedRules[0].Froms[0].Object.IsSurplus); + ClassicAssert.AreEqual("AppServerUnchanged", result.RuleDifferences[0].ImplementedRules[0].Froms[1].Object.Name); + ClassicAssert.AreEqual(false, result.RuleDifferences[0].ImplementedRules[0].Froms[1].Object.IsSurplus); + ClassicAssert.AreEqual(1, result.RuleDifferences[0].ImplementedRules[0].Tos.Length); + ClassicAssert.AreEqual("SpecObj2", result.RuleDifferences[0].ImplementedRules[0].Tos[0].Object.Name); + ClassicAssert.AreEqual(false, result.RuleDifferences[0].ImplementedRules[0].Tos[0].Object.IsSurplus); + ClassicAssert.AreEqual(1, result.RuleDifferences[0].ImplementedRules[0].UnusedSpecialUserObjects.Count); + ClassicAssert.AreEqual("specobj3", result.RuleDifferences[0].ImplementedRules[0].UnusedSpecialUserObjects[0]); + + userConfig.RuleRecognitionOption = grpNameRecogOpt; + varianceAnalysis = new(varianceAnalysisApiConnection, extStateHandler, userConfig, Application, DefaultInit.DoNothing); + result = await varianceAnalysis.AnalyseRulesVsModelledConnections(Connections, modellingFilter); + + ClassicAssert.AreEqual(0, result.ConnsNotImplemented.Count); + ClassicAssert.AreEqual(1, result.RuleDifferences.Count); + ClassicAssert.AreEqual("Conn4", result.RuleDifferences[0].ModelledConnection.Name); + ClassicAssert.AreEqual(1, result.RuleDifferences[0].ImplementedRules.Count); + ClassicAssert.AreEqual(0, result.RuleDifferences[0].ImplementedRules[0].DisregardedFroms.Length); + ClassicAssert.AreEqual(0, result.RuleDifferences[0].ImplementedRules[0].DisregardedTos.Length); + ClassicAssert.AreEqual(2, result.RuleDifferences[0].ImplementedRules[0].Froms.Length); + ClassicAssert.AreEqual("SpecObj1", result.RuleDifferences[0].ImplementedRules[0].Froms[0].Object.Name); + ClassicAssert.AreEqual(false, result.RuleDifferences[0].ImplementedRules[0].Froms[0].Object.IsSurplus); + ClassicAssert.AreEqual("AppServerUnchanged", result.RuleDifferences[0].ImplementedRules[0].Froms[1].Object.Name); + ClassicAssert.AreEqual(false, result.RuleDifferences[0].ImplementedRules[0].Froms[1].Object.IsSurplus); + ClassicAssert.AreEqual(1, result.RuleDifferences[0].ImplementedRules[0].Tos.Length); + ClassicAssert.AreEqual("SpecObj2", result.RuleDifferences[0].ImplementedRules[0].Tos[0].Object.Name); + ClassicAssert.AreEqual(false, result.RuleDifferences[0].ImplementedRules[0].Tos[0].Object.IsSurplus); + ClassicAssert.AreEqual(1, result.RuleDifferences[0].ImplementedRules[0].UnusedSpecialUserObjects.Count); + ClassicAssert.AreEqual("specobj3", result.RuleDifferences[0].ImplementedRules[0].UnusedSpecialUserObjects[0]); + + userConfig.RuleRecognitionOption = stdRecogOpt; + } + + [Test] + public async Task TestAnalyseRulesOppositeRecogOptions() + { + List Connections = [Connection1, Connection2, Connection3]; + userConfig.RuleRecognitionOption = oppRecogOpt; + ModellingVarianceAnalysis varianceAnalysis = new(varianceAnalysisApiConnection, extStateHandler, userConfig, Application, DefaultInit.DoNothing); + ModellingFilter modellingFilter = new(); + ModellingVarianceResult result = await varianceAnalysis.AnalyseRulesVsModelledConnections(Connections, modellingFilter); + + ClassicAssert.AreEqual(1, result.UnModelledRules.Count); + ClassicAssert.AreEqual(1, result.UnModelledRules[1].Count); + ClassicAssert.AreEqual("NonModelledRule", result.UnModelledRules[1][0].Name); + + ClassicAssert.AreEqual(1, result.ConnsNotImplemented.Count); + ClassicAssert.AreEqual(3, result.ConnsNotImplemented[0].Id); + ClassicAssert.AreEqual("Conn3", result.ConnsNotImplemented[0].Name); + + ClassicAssert.AreEqual(1, result.RuleDifferences.Count); + ClassicAssert.AreEqual("Conn1", result.RuleDifferences[0].ModelledConnection.Name); + ClassicAssert.AreEqual(2, result.RuleDifferences[0].ImplementedRules.Count); + ClassicAssert.AreEqual(2, result.RuleDifferences[0].ImplementedRules[0].DisregardedFroms.Length); + ClassicAssert.AreEqual("AppServerUnchanged", result.RuleDifferences[0].ImplementedRules[0].DisregardedFroms[0].Object.Name); + ClassicAssert.AreEqual("AppServerNew1/32", result.RuleDifferences[0].ImplementedRules[0].DisregardedFroms[1].Object.Name); + ClassicAssert.AreEqual(1, result.RuleDifferences[0].ImplementedRules[0].DisregardedTos.Length); + ClassicAssert.AreEqual("AppServerNew2", result.RuleDifferences[0].ImplementedRules[0].DisregardedTos[0].Object.Name); + ClassicAssert.AreEqual(1, result.RuleDifferences[0].ImplementedRules[0].DisregardedServices.Length); + ClassicAssert.AreEqual("SvcGrp1", result.RuleDifferences[0].ImplementedRules[0].DisregardedServices[0].Name); + ClassicAssert.AreEqual(1, result.RuleDifferences[0].ImplementedRules[0].Froms.Length); + ClassicAssert.AreEqual("AppServerOld", result.RuleDifferences[0].ImplementedRules[0].Froms[0].Object.Name); + ClassicAssert.AreEqual(true, result.RuleDifferences[0].ImplementedRules[0].Froms[0].Object.IsSurplus); + ClassicAssert.AreEqual(1, result.RuleDifferences[0].ImplementedRules[0].Tos.Length); + ClassicAssert.AreEqual("AR504711-001", result.RuleDifferences[0].ImplementedRules[0].Tos[0].Object.Name); + ClassicAssert.AreEqual(false, result.RuleDifferences[0].ImplementedRules[0].Tos[0].Object.IsSurplus); + ClassicAssert.AreEqual(1, result.RuleDifferences[0].ImplementedRules[0].Services.Length); + ClassicAssert.AreEqual("Service1", result.RuleDifferences[0].ImplementedRules[0].Services[0].Content.Name); + ClassicAssert.AreEqual(false, result.RuleDifferences[0].ImplementedRules[0].Services[0].Content.IsSurplus); + ClassicAssert.AreEqual(1, result.RuleDifferences[0].ImplementedRules[1].DisregardedServices.Length); + ClassicAssert.AreEqual("SvcGrp1", result.RuleDifferences[0].ImplementedRules[1].DisregardedServices[0].Name); + + ClassicAssert.AreEqual(0, result.DifferingAppRoles.Count); + userConfig.RuleRecognitionOption = stdRecogOpt; + } + + [Test] + public async Task TestAnalyseRulesOtherMarkerLocation() + { + List Connections = [Connection1, Connection2, Connection3]; + userConfig.ModModelledMarker = "XXX"; + userConfig.ModModelledMarkerLocation = MarkerLocation.Comment; + ModellingVarianceAnalysis varianceAnalysis = new(varianceAnalysisApiConnection, extStateHandler, userConfig, Application, DefaultInit.DoNothing); + ModellingFilter modellingFilter = new() { AnalyseRemainingRules = true }; + ModellingVarianceResult result = await varianceAnalysis.AnalyseRulesVsModelledConnections(Connections, modellingFilter); + + ClassicAssert.AreEqual(2, result.ConnsNotImplemented.Count); + ClassicAssert.AreEqual("Conn1", result.ConnsNotImplemented[0].Name); + ClassicAssert.AreEqual("Conn2", result.ConnsNotImplemented[1].Name); + ClassicAssert.AreEqual(1, result.RuleDifferences.Count); + ClassicAssert.AreEqual("Conn3", result.RuleDifferences[0].ModelledConnection.Name); + ClassicAssert.AreEqual(1, result.UnModelledRules.Count); + ClassicAssert.AreEqual(8, result.UnModelledRules[1].Count); + ClassicAssert.AreEqual("FWOC1", result.UnModelledRules[1][0].Name); + ClassicAssert.AreEqual("xxxFWOC2yyy", result.UnModelledRules[1][1].Name); + userConfig.ModModelledMarker = "FWOC"; + userConfig.ModModelledMarkerLocation = MarkerLocation.Rulename; + } + + [Test] + public async Task TestAnalyseRulesToReport() + { + List Connections = [Connection1]; + ModellingVarianceAnalysis varianceAnalysis = new(varianceAnalysisApiConnection, extStateHandler, userConfig, Application, DefaultInit.DoNothing); + ModellingFilter modellingFilter = new() { RulesForDeletedConns = true }; + ModellingVarianceResult result = await varianceAnalysis.AnalyseRulesVsModelledConnections(Connections, modellingFilter); + + ClassicAssert.AreEqual(1, result.UnModelledRules.Count); + ClassicAssert.AreEqual("NonModelledRule", result.UnModelledRules[1][0].Name); + + List reports = result.UnmodelledRuleDataToReport(); + + ClassicAssert.AreEqual(1, reports.Count); + ClassicAssert.AreEqual(1, reports[0].Devices.Length); + ClassicAssert.AreEqual(1, reports[0].Devices[0].GetRuleList().Count); + ClassicAssert.AreEqual("NonModelledRule", reports[0].Devices[0].GetRuleList()?[0].Name); + ClassicAssert.AreEqual("XXX3", reports[0].Devices[0].GetRuleList()?[0].Comment); + ClassicAssert.AreEqual(1, reports[0].Devices[0].GetRuleList()?[0].Froms.Length); + ClassicAssert.AreEqual("AppServerUnchanged", reports[0].Devices[0].GetRuleList()?[0].Froms[0].Object.Name); + } + + [Test] + public async Task TestAnalyseRuleStatus() + { + List Connections = [Connection1, Connection2, Connection3]; + ModellingVarianceAnalysis varianceAnalysis = new(varianceAnalysisApiConnection, extStateHandler, userConfig, Application, DefaultInit.DoNothing); + ModellingFilter modellingFilter = new(); + ModellingVarianceResult result = await varianceAnalysis.AnalyseRulesVsModelledConnections(Connections, modellingFilter, false); + + ClassicAssert.AreEqual(1, result.UnModelledRules.Count); + ClassicAssert.AreEqual(1, result.UnModelledRules[1].Count); + ClassicAssert.AreEqual("NonModelledRule", result.UnModelledRules[1][0].Name); + ClassicAssert.AreEqual(1, result.ConnsNotImplemented.Count); + ClassicAssert.AreEqual(3, result.ConnsNotImplemented[0].Id); + ClassicAssert.AreEqual("Conn3", result.ConnsNotImplemented[0].Name); + ClassicAssert.AreEqual(1, result.RuleDifferences.Count); + ClassicAssert.AreEqual("Conn1", result.RuleDifferences[0].ModelledConnection.Name); + ClassicAssert.AreEqual(2, result.RuleDifferences[0].ImplementedRules.Count); + ClassicAssert.AreEqual(0, result.DifferingAppRoles.Count); + } + + [Test] + public async Task TestAnalyseRuleStatusSpecialUserObjects() + { + List Connections = [Connection4]; + ModellingVarianceAnalysis varianceAnalysis = new(varianceAnalysisApiConnection, extStateHandler, userConfig, Application, DefaultInit.DoNothing); + ModellingFilter modellingFilter = new(); + ModellingVarianceResult result = await varianceAnalysis.AnalyseRulesVsModelledConnections(Connections, modellingFilter, false); + + ClassicAssert.AreEqual(0, result.ConnsNotImplemented.Count); + ClassicAssert.AreEqual(1, result.RuleDifferences.Count); + ClassicAssert.AreEqual("Conn4", result.RuleDifferences[0].ModelledConnection.Name); + ClassicAssert.AreEqual(1, result.RuleDifferences[0].ImplementedRules.Count); + ClassicAssert.AreEqual(0, result.RuleDifferences[0].ImplementedRules[0].DisregardedFroms.Length); + ClassicAssert.AreEqual(0, result.RuleDifferences[0].ImplementedRules[0].DisregardedTos.Length); + ClassicAssert.AreEqual(2, result.RuleDifferences[0].ImplementedRules[0].Froms.Length); + ClassicAssert.AreEqual(1, result.RuleDifferences[0].ImplementedRules[0].Tos.Length); + ClassicAssert.AreEqual("SpecObj2", result.RuleDifferences[0].ImplementedRules[0].Tos[0].Object.Name); + ClassicAssert.AreEqual(1, result.RuleDifferences[0].ImplementedRules[0].UnusedSpecialUserObjects.Count); + + userConfig.RuleRecognitionOption = grpNameRecogOpt; + varianceAnalysis = new(varianceAnalysisApiConnection, extStateHandler, userConfig, Application, DefaultInit.DoNothing); + result = await varianceAnalysis.AnalyseRulesVsModelledConnections(Connections, modellingFilter); + + ClassicAssert.AreEqual(0, result.ConnsNotImplemented.Count); + ClassicAssert.AreEqual(1, result.RuleDifferences.Count); + ClassicAssert.AreEqual("Conn4", result.RuleDifferences[0].ModelledConnection.Name); + ClassicAssert.AreEqual(1, result.RuleDifferences[0].ImplementedRules.Count); + ClassicAssert.AreEqual(0, result.RuleDifferences[0].ImplementedRules[0].DisregardedFroms.Length); + ClassicAssert.AreEqual(0, result.RuleDifferences[0].ImplementedRules[0].DisregardedTos.Length); + ClassicAssert.AreEqual(2, result.RuleDifferences[0].ImplementedRules[0].Froms.Length); + ClassicAssert.AreEqual("SpecObj1", result.RuleDifferences[0].ImplementedRules[0].Froms[0].Object.Name); + ClassicAssert.AreEqual(false, result.RuleDifferences[0].ImplementedRules[0].Froms[0].Object.IsSurplus); + ClassicAssert.AreEqual("AppServerUnchanged", result.RuleDifferences[0].ImplementedRules[0].Froms[1].Object.Name); + ClassicAssert.AreEqual(false, result.RuleDifferences[0].ImplementedRules[0].Froms[1].Object.IsSurplus); + ClassicAssert.AreEqual(1, result.RuleDifferences[0].ImplementedRules[0].Tos.Length); + ClassicAssert.AreEqual("SpecObj2", result.RuleDifferences[0].ImplementedRules[0].Tos[0].Object.Name); + ClassicAssert.AreEqual(false, result.RuleDifferences[0].ImplementedRules[0].Tos[0].Object.IsSurplus); + ClassicAssert.AreEqual(1, result.RuleDifferences[0].ImplementedRules[0].UnusedSpecialUserObjects.Count); + ClassicAssert.AreEqual("specobj3", result.RuleDifferences[0].ImplementedRules[0].UnusedSpecialUserObjects[0]); + + userConfig.RuleRecognitionOption = stdRecogOpt; + } + + [Test] + public async Task TestAnalyseRuleStatusAsync() + { + List Connections = [new(Connection1), new(Connection2), new(Connection3), new(Connection4), new(Connection5)]; + ModellingVarianceAnalysis varianceAnalysis = new(varianceAnalysisApiConnection, extStateHandler, userConfig, Application, DefaultInit.DoNothing); + await varianceAnalysis.AnalyseConnsForStatusAsync(Connections); + + ClassicAssert.AreEqual(true, Connections[0].Props?.ContainsKey(ConState.VarianceChecked.ToString())); + ClassicAssert.AreEqual(true, Connections[0].Props?.ContainsKey(ConState.VarianceFound.ToString())); + ClassicAssert.AreEqual(false, Connections[0].Props?.ContainsKey(ConState.NotImplemented.ToString())); + + ClassicAssert.AreEqual(true, Connections[1].Props?.ContainsKey(ConState.VarianceChecked.ToString())); + ClassicAssert.AreEqual(false, Connections[1].Props?.ContainsKey(ConState.VarianceFound.ToString())); + ClassicAssert.AreEqual(false, Connections[1].Props?.ContainsKey(ConState.NotImplemented.ToString())); + + ClassicAssert.AreEqual(true, Connections[2].Props?.ContainsKey(ConState.VarianceChecked.ToString())); + ClassicAssert.AreEqual(false, Connections[2].Props?.ContainsKey(ConState.VarianceFound.ToString())); + ClassicAssert.AreEqual(true, Connections[2].Props?.ContainsKey(ConState.NotImplemented.ToString())); + + ClassicAssert.AreEqual(true, Connections[3].Props?.ContainsKey(ConState.VarianceChecked.ToString())); + ClassicAssert.AreEqual(true, Connections[3].Props?.ContainsKey(ConState.VarianceFound.ToString())); + ClassicAssert.AreEqual(false, Connections[3].Props?.ContainsKey(ConState.NotImplemented.ToString())); + + ClassicAssert.AreEqual(true, Connections[4].Props?.ContainsKey(ConState.VarianceChecked.ToString())); + ClassicAssert.AreEqual(false, Connections[4].Props?.ContainsKey(ConState.VarianceFound.ToString())); + ClassicAssert.AreEqual(false, Connections[4].Props?.ContainsKey(ConState.NotImplemented.ToString())); + } + + [Test] + public async Task TestNATHeuristic() + { + List Connections = [Connection7]; + userConfig.ModRolloutNatHeuristic = true; + + ModellingVarianceAnalysis varianceAnalysis = new(varianceAnalysisApiConnection, extStateHandler, userConfig, Application, DefaultInit.DoNothing); + ModellingFilter modellingFilter = new(); + ModellingVarianceResult result = await varianceAnalysis.AnalyseRulesVsModelledConnections(Connections, modellingFilter); + + ClassicAssert.AreEqual(0, result.ConnsNotImplemented.Count); + ClassicAssert.AreEqual(1, result.OkRules.Count); + ClassicAssert.AreEqual("FWOC7_mgt1", result.OkRules[0].ImplementedRules[0].Name); + ClassicAssert.AreEqual(1, result.RuleDifferences.Count); + ClassicAssert.AreEqual("Conn7", result.RuleDifferences[0].ModelledConnection.Name); + ClassicAssert.AreEqual(1, result.RuleDifferences[0].ImplementedRules.Count); + ClassicAssert.AreEqual("FWOC7_mgt3", result.RuleDifferences[0].ImplementedRules[0].Name); + + userConfig.ModRolloutNatHeuristic = false; + + varianceAnalysis = new(varianceAnalysisApiConnection, extStateHandler, userConfig, Application, DefaultInit.DoNothing); + result = await varianceAnalysis.AnalyseRulesVsModelledConnections(Connections, modellingFilter); + + ClassicAssert.AreEqual(0, result.ConnsNotImplemented.Count); + ClassicAssert.AreEqual(1, result.OkRules.Count); + ClassicAssert.AreEqual("FWOC7_mgt1", result.OkRules[0].ImplementedRules[0].Name); + ClassicAssert.AreEqual(1, result.RuleDifferences.Count); + ClassicAssert.AreEqual("Conn7", result.RuleDifferences[0].ModelledConnection.Name); + ClassicAssert.AreEqual(2, result.RuleDifferences[0].ImplementedRules.Count); + ClassicAssert.AreEqual("FWOC7_mgt2", result.RuleDifferences[0].ImplementedRules[0].Name); + ClassicAssert.AreEqual("FWOC7_mgt3", result.RuleDifferences[0].ImplementedRules[1].Name); + } + } +} diff --git a/roles/tests-unit/files/FWO.Test/ModellingVarianceAnalysisTestApiConn.cs b/roles/tests-unit/files/FWO.Test/ModellingVarianceAnalysisTestApiConn.cs new file mode 100644 index 0000000000..8a4ff1ef48 --- /dev/null +++ b/roles/tests-unit/files/FWO.Test/ModellingVarianceAnalysisTestApiConn.cs @@ -0,0 +1,213 @@ +using FWO.Api.Client.Queries; +using GraphQL; +using FWO.Basics; +using FWO.Services; +using FWO.Data; +using FWO.Data.Modelling; +using FWO.Data.Report; +using FWO.Data.Workflow; + +namespace FWO.Test +{ + internal class ModellingVarianceAnalysisTestApiConn : SimulatedApiConnection + { + static readonly NetworkObject NwObj1 = new() { Id = 10, Name = "AppServerUnchanged", IP = "1.2.3.4", Type = new() { Name = ObjectType.Host } }; + static readonly NetworkObject NwObj2 = new() { Id = 11, Name = "AppServerOld", IP = "1.0.0.0", Type = new() { Name = ObjectType.Host } }; + static readonly NetworkObject Nwgroup1 = new() { Id = 1, Name = "AR504711-001", Type = new() { Name = ObjectType.Group }, ObjectGroupFlats = [new() { Object = NwObj1 }, new() { Object = NwObj2 }] }; + static readonly NetworkObject Nwgroup3 = new() { Id = 3, Name = "AR504711-003", Type = new() { Name = ObjectType.Group }, ObjectGroupFlats = [new() { Object = NwObj1 }] }; + static readonly NetworkObject SpecObj1 = new() { Id = 21, Name = "SpecObj1", Type = new() { Name = "Something else" } }; + static readonly NetworkObject SpecObj2 = new() { Id = 21, Name = "SpecObj2", Type = new() { Name = "Something else" } }; + + static readonly ModellingAppServer AppServer1 = new() { Id = 13, Name = "AppServerUnchanged", Ip = "1.2.3.4/32", IpEnd = "1.2.3.4/32" }; + static readonly ModellingAppServer AppServer2 = new() { Id = 14, Name = "AppServerNew1_32", Ip = "1.1.1.1/32", IpEnd = "1.1.1.1/32" }; + static readonly ModellingAppServer AppServer3 = new() { Id = 15, Name = "AppServerNew2", Ip = "2.2.2.2/32", IpEnd = "2.2.2.2/32" }; + static readonly NetworkObject AZProd = new() { Id = 3, Name = "AZ4711", Type = new() { Name = ObjectType.Group }, ObjectGroupFlats = [new() { Object = NwObj1 }, new() { Object = NwObj2 }] }; + static readonly ModellingAppZone AZExist = new() { Id = 3, Name = "AZ4711", IdString = "AZ4711", AppServers = [new() { Content = AppServer1 }, new() { Content = AppServer2 }] }; + static readonly NetworkService Svc1 = new() { Id = 1, DestinationPort = 1000, DestinationPortEnd = 2000, Name = "Service1", ProtoId = 6 }; + static readonly NetworkService Svc2 = new() { Id = 2, DestinationPort = 990, DestinationPortEnd = 1998, Name = "Service1", ProtoId = 6 }; + static readonly Rule Rule1 = new() + { + Name = "FWOC1", + MgmtId = 1, + Froms = [new(new(), NwObj2)], + Tos = [new(new(), Nwgroup1)], + Services = [new() { Content = Svc1 }] + }; + static readonly Rule Rule2 = new() + { + Name = "xxxFWOC2yyy", + MgmtId = 1, + Froms = [new(new(), NwObj1)], + Tos = [new(new(), Nwgroup3)], + Services = [new() { Content = Svc1 }] + }; + static readonly Rule Rule3 = new() + { + Id = 3, + Name = "NonModelledRule", + Comment = "XXX3", + Froms = [new(new(), NwObj1)], + RulebaseId = 3 + }; + static readonly Rule Rule4 = new() + { + Name = "FWOC4", + MgmtId = 1, + Froms = [new(new(), SpecObj1), new(new(), NwObj1)], + Tos = [new(new(), SpecObj2)], + Services = [new() { Content = Svc1 }] + }; + static readonly Rule Rule5 = new() + { + Name = "FWOC1again", + MgmtId = 1, + Froms = [new(new(), NwObj2)], + Tos = [new(new(), Nwgroup1)], + Services = [new() { Content = Svc2 }] + }; + static readonly Rule Rule6 = new() + { + Name = "FWOC5", + MgmtId = 1, + Froms = [new(new(), SpecObj1), new(new(), NwObj1)], + Tos = [new(new(), SpecObj2)], + Services = [new() { Content = Svc1 }] + }; + static readonly Rule Rule7 = new() + { + Name = "FWOC7_mgt1", + MgmtId = 1, + Froms = [new(new(), Nwgroup1)], + Tos = [new(new(), NwObj1)], + Services = [new() { Content = Svc1 }] + }; + static readonly Rule Rule8 = new() + { + Name = "FWOC7_mgt2", + MgmtId = 2, + Froms = [new(new(), Nwgroup1)], + Tos = [new(new(), NwObj2)], + Services = [new() { Content = Svc1 }] + }; + static readonly Rule Rule9 = new() + { + Name = "FWOC7_mgt3", + MgmtId = 3, + Froms = [new(new(), Nwgroup1)], + Tos = [new(new(), NwObj1), new(new(), NwObj2)], + Services = [new() { Content = Svc1 }] + }; + static readonly DeviceReport DevRep1 = new() + { + Id = 1, + RulebaseLinks = [new() { GatewayId = 1, NextRulebaseId = 3 }] + }; + + public override async Task SendQueryAsync(string query, object? variables = null, string? operationName = null) + { + await DefaultInit.DoNothing(); // qad avoid compiler warning + Type responseType = typeof(QueryResponseType); + if (responseType == typeof(List)) + { + if (query == ReportQueries.getRelevantImportIdsAtTime) + { + GraphQLResponse response = new() { Data = new List() { new() { Import = new() { ImportAggregate = new() { ImportAggregateMax = new() { RelevantImportId = 1 } } } } } }; + return response.Data; + } + else + { + List? managements = + [ + new(){ Id = 1, Name = "Checkpoint1", ExtMgtData = "{\"id\":\"1\",\"name\":\"CheckpointExt\"}", Devices = [ new(){ Id = 1 }] } + ]; + GraphQLResponse response = new() { Data = managements }; + return response.Data; + } + } + else if (responseType == typeof(List)) + { + List? nwObjects = []; + if (query == ObjectQueries.getNetworkObjectsForManagement) + { + if (variables != null) + { + var objTypeIds = variables.GetType().GetProperties().First(o => o.Name == "objTypeIds").GetValue(variables, null); + if (objTypeIds != null && ((int[])objTypeIds)[0] == 2) + { + nwObjects = + [ + Nwgroup1, AZProd + ]; + } + else + { + nwObjects = + [ + NwObj1, NwObj2 + ]; + } + } + } + GraphQLResponse response = new() { Data = nwObjects }; + return response.Data; + } + else if (responseType == typeof(List)) + { + GraphQLResponse response = new() { Data = new List() { AZExist } }; + return response.Data; + } + else if (responseType == typeof(List)) + { + GraphQLResponse response = new() { Data = new List() { AppServer1, AppServer2, AppServer3 } }; + return response.Data; + } + else if (responseType == typeof(List)) + { + GraphQLResponse response = new() { Data = new List() { new(Rule1), new(Rule2), new(Rule3), new(Rule4), new(Rule5), new(Rule6), new(Rule7), new(Rule8), new(Rule9) } }; + return response.Data; + } + else if (responseType == typeof(List)) + { + GraphQLResponse response = new() { Data = new List() { new() { Id = 2 }, new() { Id = 4 } } }; + return response.Data; + } + else if (responseType == typeof(ReturnId) && query == ModellingQueries.updateConnectionProperties) + { + if (variables != null) + { + List connIds = [1, 2, 3, 4, 5, 6, 7, 8, 9]; + var connId = variables.GetType().GetProperties().First(o => o.Name == "id").GetValue(variables, null); + if (connId != null && connIds.Contains((int)connId)) + { + GraphQLResponse response = new(); + return response.Data; + } + throw new ArgumentException($"ConnId {connId} is not valid"); + } + throw new ArgumentException($"No Variables"); + } + else if (responseType == typeof(List)) + { + GraphQLResponse response = new() { Data = new List() { new() { Id = 1 }, new() { Id = 3 } } }; + return response.Data; + } + else if (responseType == typeof(List)) + { + GraphQLResponse response = new() { Data = new List() { new() { Id = 1 } } }; + return response.Data; + } + else if (responseType == typeof(WfTicket)) + { + GraphQLResponse response = new() { Data = new WfTicket() { StateId = 631, CreationDate = new(1967, 1, 10, 8, 0, 0, DateTimeKind.Utc), CompletionDate = new(2025, 6, 26, 8, 0, 0, DateTimeKind.Utc), Requester = new() { Name = "Walter" } } }; + return response.Data; + } + else if (responseType == typeof(List)) + { + GraphQLResponse response = new() { Data = new List { DevRep1 } }; + return response.Data; + } + + throw new NotImplementedException(); + } + } +} diff --git a/roles/tests-unit/files/FWO.Test/NetworkZoneServiceTest.cs b/roles/tests-unit/files/FWO.Test/NetworkZoneServiceTest.cs new file mode 100644 index 0000000000..3c55224bbf --- /dev/null +++ b/roles/tests-unit/files/FWO.Test/NetworkZoneServiceTest.cs @@ -0,0 +1,358 @@ +using NUnit.Framework; +using FWO.Services; +using FWO.Data; +using NetTools; +using FWO.Basics; +using System.Net; +using NSubstitute; +using FWO.Api.Client; +using FWO.Api.Client.Queries; +using FWO.Config.Api; +using System.Reflection; +using FWO.Test.Tools.CustomAssert; +using FWO.Test.Mocks; + +namespace FWO.Test +{ + [TestFixture] + public class NetworkZoneServiceTest + { + [Test] + public void CalculateInternetZone_BasicZonesWithoutOverlaps_InternetZoneCalculatedCorrectly() + { + // Arrange + + ComplianceNetworkZone internetZone = new(); + + ComplianceNetworkZone networkZoneOne = new(); + + networkZoneOne.IPRanges = + [ + IpOperations.GetIPAdressRange("0.0.0.0/3"), + IpOperations.GetIPAdressRange("64.0.0.0/3") + + ]; + + ComplianceNetworkZone networkZoneTwo = new(); + + networkZoneTwo.IPRanges = + [ + IpOperations.GetIPAdressRange("128.0.0.0/3"), + IpOperations.GetIPAdressRange("192.0.0.0/3") + + ]; + + List definedAndExcludedZones = new List + { + networkZoneOne, + networkZoneTwo + }; + + IPAddressRange[] expectedInternetZone = + [ + IpOperations.GetIPAdressRange("32.0.0.0/3"), + IpOperations.GetIPAdressRange("96.0.0.0/3"), + IpOperations.GetIPAdressRange("160.0.0.0/3"), + IpOperations.GetIPAdressRange("224.0.0.0/3"), + ]; + + // Act + + NetworkZoneService.CalculateInternetZone(internetZone, definedAndExcludedZones); + + + // Assert + Assert. + That(internetZone.IPRanges, + Is.EqualTo(expectedInternetZone) + .Using((a, b) => a.ToString() == b.ToString())); + } + + [Test] + public void CalculateInternetZone_BasicZonesWithOverlaps_InternetZoneCalculatedCorrectly() + { + // Arrange + + ComplianceNetworkZone internetZone = new(); + + ComplianceNetworkZone networkZoneOne = new(); + + networkZoneOne.IPRanges = + [ + IpOperations.GetIPAdressRange("0.0.0.0/3"), + IpOperations.GetIPAdressRange("64.0.0.0/3") + + ]; + + ComplianceNetworkZone networkZoneTwo = new(); + + networkZoneTwo.IPRanges = + [ + IpOperations.GetIPAdressRange("128.0.0.0/3"), + IpOperations.GetIPAdressRange("192.0.0.0/3") + + ]; + + ComplianceNetworkZone overlaps = new(); + + overlaps.IPRanges = + [ + new IPAddressRange(IPAddress.Parse("31.255.255.255"), IPAddress.Parse("32.0.0.0")), + new IPAddressRange(IPAddress.Parse("63.255.255.255"), IPAddress.Parse("64.0.0.0")), + new IPAddressRange(IPAddress.Parse("191.255.255.255"), IPAddress.Parse("224.0.0.0")), + ]; + + List definedAndExcludedZones = new List + { + networkZoneOne, + networkZoneTwo, + overlaps + }; + + IPAddressRange[] expectedInternetZone = new IPAddressRange[] + { + new IPAddressRange(IPAddress.Parse("32.0.0.1"), IPAddress.Parse("63.255.255.254")), + IpOperations.GetIPAdressRange("96.0.0.0/3"), + new IPAddressRange(IPAddress.Parse("160.0.0.0"), IPAddress.Parse("191.255.255.254")), + new IPAddressRange(IPAddress.Parse("224.0.0.1"), IPAddress.Parse("255.255.255.255")), + }; + + // Act + + NetworkZoneService.CalculateInternetZone(internetZone, definedAndExcludedZones); + + + // Assert + Assert. + That(internetZone.IPRanges, + Is.EqualTo(expectedInternetZone) + .Using((a, b) => a.ToString() == b.ToString())); + + + } + + [Test] + public void CalculateUndefinedInternalZone_NoDefinedZones_internalZoneIpRangesEqualsConfiguredRanges() + { + // Arrange + + ComplianceNetworkZone internalZone = new(); + List internalZoneRanges = new() + { + // Private address space + + IpOperations.GetIPAdressRange("10.0.0.0/8"), // RFC 1918 + IpOperations.GetIPAdressRange("172.16.0.0/12"), // RFC 1918 + IpOperations.GetIPAdressRange("192.168.0.0/16"), // RFC 1918 + + // Loopback, local + + IpOperations.GetIPAdressRange("0.0.0.0/8"), // "This network" — IANA Special-Purpose (RFC 6890) + IpOperations.GetIPAdressRange("127.0.0.0/8"), // Loopback (RFC 1122) + IpOperations.GetIPAdressRange("169.254.0.0/16"), // Link-local (APIPA) (RFC 3927) + + + // Multicast / Broadcast + + IpOperations.GetIPAdressRange("224.0.0.0/4"), // Multicast (RFC 5771) + IpOperations.GetIPAdressRange("240.0.0.0/4"), // Reserved for future use (RFC 6890) + IpOperations.GetIPAdressRange("255.255.255.255/32"),// Limited broadcast (RFC 919 / RFC 922) + + // Documentation / samples + + IpOperations.GetIPAdressRange("192.0.2.0/24"), // TEST-NET-1 (documentation) (RFC 5737) + IpOperations.GetIPAdressRange("198.51.100.0/24"), // TEST-NET-2 (documentation) (RFC 5737) + IpOperations.GetIPAdressRange("203.0.113.0/24"), // TEST-NET-3 (documentation) (RFC 5737) + + // Div (benchmarking, broadcast, multicast, special purpose, etc) + + IpOperations.GetIPAdressRange("100.64.0.0/10"), // Shared address space (Carrier-Grade NAT) (RFC 6598) + IpOperations.GetIPAdressRange("192.0.0.0/24"), // IETF Protocol Assignments (RFC 6890) + IpOperations.GetIPAdressRange("198.18.0.0/15"), // Benchmark testing of inter-network devices — (RFC 2544 / RFC 6815) + IpOperations.GetIPAdressRange("192.88.99.0/24"), // 6to4 Relay Anycast (deprecated; should not be routed) (RFC 7526) + + + }; + List definedZones = new(); + IPAddressRange[] expectedinternalZone = internalZoneRanges + .Where(range => !range.ToString().Equals("255.255.255.255")) // Only disjoint ranges. 255.255.255.255/32 is in 240.0.0.0/4. + .ToArray(); + + // Act + + NetworkZoneService.CalculateUndefinedInternalZone(internalZone, internalZoneRanges, definedZones); + + // Assert + + Assert. + That(internalZone.IPRanges, + Is.EqualTo(expectedinternalZone) + .Using((a, b) => a.ToString() == b.ToString())); + + + } + + [Test] + public void CalculateUndefinedInternalZone_NoOverlappingDefinedZones_internalZoneIpRangesEqualsConfiguredRanges() + { + // Arrange + + ComplianceNetworkZone internalZone = new(); + + List internalZoneRanges = new() + { + IpOperations.GetIPAdressRange("10.0.0.0/8"), // Private address space — RFC 1918 + IpOperations.GetIPAdressRange("172.16.0.0/12"), // Private address space — RFC 1918 + IpOperations.GetIPAdressRange("192.168.0.0/16"), // Private address space — RFC 1918 + }; + + ComplianceNetworkZone networkZoneOne = new(); + + networkZoneOne.IPRanges = + [ + new IPAddressRange(IPAddress.Parse("0.0.0.0"), IPAddress.Parse("9.255.255.255")), + new IPAddressRange(IPAddress.Parse("11.0.0.0"), IPAddress.Parse("172.15.255.255")) + ]; + + ComplianceNetworkZone networkZoneTwo = new(); + + networkZoneTwo.IPRanges = + [ + new IPAddressRange(IPAddress.Parse("172.32.0.0"),IPAddress.Parse("192.167.255.255")), + new IPAddressRange(IPAddress.Parse("192.169.0.0"), IPAddress.Parse("255.255.255.255")) + ]; + + List definedZones = new List + { + networkZoneOne, + networkZoneTwo + }; + + IPAddressRange[] expectedinternalZone = internalZoneRanges.ToArray(); + + // Act + + NetworkZoneService.CalculateUndefinedInternalZone(internalZone, internalZoneRanges, definedZones); + + // Assert + + Assert. + That(internalZone.IPRanges, + Is.EqualTo(expectedinternalZone) + .Using((a, b) => a.ToString() == b.ToString())); + + + } + + [Test] + public void CalculateUndefinedInternalZone_OverlappingDefinedZones_InternalZoneCalculatedCorrectly() + { + // Arrange + + ComplianceNetworkZone internalZone = new(); + + List internalZoneRanges = new() + { + IpOperations.GetIPAdressRange("10.0.0.0/8"), // Private address space — RFC 1918 + IpOperations.GetIPAdressRange("172.16.0.0/12"), // Private address space — RFC 1918 + IpOperations.GetIPAdressRange("192.168.0.0/16"), // Private address space — RFC 1918 + }; + + ComplianceNetworkZone networkZoneOne = new(); + + networkZoneOne.IPRanges = + [ + new IPAddressRange(IPAddress.Parse("0.0.0.0"), IPAddress.Parse("172.15.255.255")) + ]; + + ComplianceNetworkZone networkZoneTwo = new(); + + networkZoneTwo.IPRanges = + [ + new IPAddressRange(IPAddress.Parse("172.32.0.0"),IPAddress.Parse("192.167.255.255")), + new IPAddressRange(IPAddress.Parse("192.169.0.0"), IPAddress.Parse("255.255.255.255")) + ]; + + List definedZones = new List + { + networkZoneOne, + networkZoneTwo + }; + + IPAddressRange[] expectedinternalZone = + [ + IpOperations.GetIPAdressRange("172.16.0.0/12"), + IpOperations.GetIPAdressRange("192.168.0.0/16") + ]; + + // Act + + NetworkZoneService.CalculateUndefinedInternalZone(internalZone, internalZoneRanges, definedZones); + + // Assert + + Assert. + That(internalZone.IPRanges, + Is.EqualTo(expectedinternalZone) + .Using((a, b) => a.ToString() == b.ToString())); + } + + [Test] + public async Task UpdateSpecialZones_InternetZoneDummyExists_UpdateDummyToInternetZone() + { + // Arrange + + MockApiConnection mock = new(); + ApiConnection apiConnection = mock; + GlobalConfig globalConfig = new GlobalConfig { AutoCalculateInternetZone = true, AutoCalculateUndefinedInternalZone = true }; + + List predefinedZones = TestDataGenerator.CreateComplianceNetworkZones(4, false, false); + ComplianceNetworkZone zoneOne = predefinedZones.First(); + ComplianceNetworkZone internetZoneDummy = predefinedZones.Last(); + internetZoneDummy.IdString = "AUTO_CALCULATED_ZONE_INTERNET"; + internetZoneDummy.AllowedCommunicationDestinations = [zoneOne]; + + mock.Sub + .SendQueryAsync>( + ComplianceQueries.getNetworkZonesForMatrix, + Arg.Any()) + .Returns(Task.FromResult(predefinedZones)); + + mock.Sub + .SendQueryAsync( + Arg.Is(q => q == ComplianceQueries.addNetworkZone), + Arg.Any()) + .Returns(ci => + { + object vars = ci.ArgAt(1); + PropertyInfo nameProp = vars.GetType().GetProperty("name")!; + string nameValue = nameProp.GetValue(vars)!.ToString()!; + + if (predefinedZones.Any(zone => zone.Name == nameValue)) + throw new ArgumentException($"An item with the same key has already been added. Key: {nameValue}"); + + return Task.FromResult((dynamic)new { success = true }); + }); + + // Act + + await NetworkZoneService.UpdateSpecialZones(1, apiConnection!, globalConfig); + + // Assert + + Assert.That(mock.SentQueries.Count == 2); + + (string, object) firstSentQuery = mock.SentQueries.ElementAt(0); + Assert.That(firstSentQuery.Item1 == ComplianceQueries.addNetworkZone); + AssertThatGeneric.PropertyIsTrue(firstSentQuery.Item2, "isAutoCalculatedUndefinedInternalZone"); + + (string, object) secondSentQuery = mock.SentQueries.ElementAt(1); + Assert.That(secondSentQuery.Item1 == ComplianceQueries.updateNetworkZone); + AssertThatGeneric.PropertyIsTrue(secondSentQuery.Item2, "isAutoCalculatedInternetZone"); + AssertThatGeneric.PropertyIsEqual(secondSentQuery.Item2, "networkZoneId", 4); + } + + private static object? GetFromGeneric(object o, string name) => o.GetType().GetProperty(name)?.GetValue(o); + + } +} diff --git a/roles/tests-unit/files/FWO.Test/NormalizedConfigTest.cs b/roles/tests-unit/files/FWO.Test/NormalizedConfigTest.cs new file mode 100644 index 0000000000..4c0975ec77 --- /dev/null +++ b/roles/tests-unit/files/FWO.Test/NormalizedConfigTest.cs @@ -0,0 +1,29 @@ +using FWO.Data; +using NUnit.Framework; + +namespace FWO.Test +{ + [TestFixture] + public class NormalizedConfigTest + { + [Test] + public void FormatDatetimeZUsesIsoOffsetWithColon() + { + DateTime localTime = new(2026, 1, 2, 3, 4, 5, DateTimeKind.Local); + + string formatted = NormalizedConfig.FormatDatetimeZ(localTime); + + Assert.That(formatted, Does.Match(@"^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}[+-]\d{2}:\d{2}$")); + } + + [Test] + public void FormatDatetimeZConvertsToUtcWhenRequested() + { + DateTime utcTime = new(2026, 1, 2, 3, 4, 5, DateTimeKind.Utc); + + string formatted = NormalizedConfig.FormatDatetimeZ(utcTime, convertToUtc: true); + + Assert.That(formatted, Is.EqualTo("2026-01-02T03:04:05+00:00")); + } + } +} \ No newline at end of file diff --git a/roles/tests-unit/files/FWO.Test/NotificationMutationHelperTest.cs b/roles/tests-unit/files/FWO.Test/NotificationMutationHelperTest.cs new file mode 100644 index 0000000000..61b8855ced --- /dev/null +++ b/roles/tests-unit/files/FWO.Test/NotificationMutationHelperTest.cs @@ -0,0 +1,179 @@ +using FWO.Api.Client.Queries; +using FWO.Data; +using FWO.Ui.Services; +using NUnit.Framework; + +namespace FWO.Test +{ + [TestFixture] + [Parallelizable] + internal class NotificationMutationHelperTest + { + [Test] + public async Task AddAsync_PersistsNotificationAndReturnsAssignedId() + { + RecordingNotificationApiConnection apiConnection = new(); + FwoNotification notification = NewNotification(); + + FwoNotification persistedNotification = await NotificationMutationHelper.AddAsync(apiConnection, NotificationClient.Report, notification); + + Assert.Multiple(() => + { + Assert.That(apiConnection.AddCalls, Has.Count.EqualTo(1)); + Assert.That(persistedNotification.Id, Is.EqualTo(100)); + Assert.That(persistedNotification.NotificationClient, Is.EqualTo(NotificationClient.Report)); + Assert.That(persistedNotification.Name, Is.EqualTo(notification.Name)); + Assert.That(persistedNotification.EmailAddressTo, Is.EqualTo(notification.EmailAddressTo)); + Assert.That(apiConnection.AddCalls[0].Client, Is.EqualTo(NotificationClient.Report.ToString())); + Assert.That(apiConnection.AddCalls[0].Name, Is.EqualTo(notification.Name)); + Assert.That(apiConnection.AddCalls[0].BundleId, Is.EqualTo(notification.BundleId)); + }); + } + + [Test] + public async Task UpdateAsync_PersistsNotificationAndReturnsUpdatedCopy() + { + RecordingNotificationApiConnection apiConnection = new(); + FwoNotification notification = NewNotification(); + notification.Id = 17; + notification.EmailSubject = "Updated Subject"; + + FwoNotification persistedNotification = await NotificationMutationHelper.UpdateAsync(apiConnection, NotificationClient.Report, notification); + + Assert.Multiple(() => + { + Assert.That(apiConnection.UpdateCalls, Has.Count.EqualTo(1)); + Assert.That(persistedNotification.Id, Is.EqualTo(17)); + Assert.That(persistedNotification.EmailSubject, Is.EqualTo("Updated Subject")); + Assert.That(apiConnection.UpdateCalls[0].Id, Is.EqualTo(17)); + Assert.That(apiConnection.UpdateCalls[0].Subject, Is.EqualTo("Updated Subject")); + Assert.That(apiConnection.UpdateCalls[0].Layout, Is.EqualTo(notification.Layout.ToString())); + }); + } + + [Test] + public async Task DeleteAsync_DeletesNotificationById() + { + RecordingNotificationApiConnection apiConnection = new(); + + await NotificationMutationHelper.DeleteAsync(apiConnection, 23); + + Assert.That(apiConnection.DeletedIds, Is.EqualTo(new[] { 23 })); + } + + private static FwoNotification NewNotification() + { + return new FwoNotification + { + NotificationClient = NotificationClient.Report, + Channel = NotificationChannel.Email, + Name = "Weekly PDF", + RecipientTo = EmailRecipientOption.OtherAddresses, + EmailAddressTo = "report@example.org", + RecipientCc = EmailRecipientOption.None, + EmailAddressCc = "", + EmailSubject = "Subject", + EmailBody = "Body", + ScheduleId = 11, + BundleType = BundleType.Attachments, + BundleId = "bundle-1", + Layout = NotificationLayout.PdfAsAttachment, + Deadline = NotificationDeadline.None + }; + } + + private sealed class RecordingNotificationApiConnection : SimulatedApiConnection + { + private int nextId = 100; + + internal List AddCalls { get; } = []; + internal List UpdateCalls { get; } = []; + internal List DeletedIds { get; } = []; + + public override Task SendQueryAsync(string query, object? variables = null, string? operationName = null) + { + if (query == NotificationQueries.addNotification && typeof(QueryResponseType) == typeof(ReturnIdWrapper)) + { + AddCalls.Add(NotificationMutationCall.From(variables)); + return Task.FromResult((QueryResponseType)(object)new ReturnIdWrapper + { + ReturnIds = [new ReturnId { NewId = nextId++ }] + }); + } + + if (query == NotificationQueries.updateNotification && typeof(QueryResponseType) == typeof(ReturnIdWrapper)) + { + UpdateCalls.Add(NotificationMutationCall.From(variables)); + return Task.FromResult((QueryResponseType)(object)new ReturnIdWrapper + { + ReturnIds = [new ReturnId { UpdatedId = ReadInt(variables, "id") }] + }); + } + + if (query == NotificationQueries.deleteNotification && typeof(QueryResponseType) == typeof(object)) + { + DeletedIds.Add(ReadInt(variables, "id")); + return Task.FromResult((QueryResponseType)(object)new object()); + } + + throw new NotImplementedException(); + } + + private static int ReadInt(object? source, string propertyName) + { + object? value = ReadValue(source, propertyName); + return value is int intValue ? intValue : 0; + } + + private static object? ReadValue(object? source, string propertyName) + { + return source?.GetType().GetProperty(propertyName)?.GetValue(source); + } + } + + private sealed class NotificationMutationCall + { + internal int Id { get; init; } + internal string Client { get; init; } = ""; + internal string Name { get; init; } = ""; + internal string Subject { get; init; } = ""; + internal string Layout { get; init; } = ""; + internal string? BundleId { get; init; } + + internal static NotificationMutationCall From(object? variables) + { + return new NotificationMutationCall + { + Id = ReadInt(variables, "id"), + Client = ReadString(variables, "client"), + Name = ReadString(variables, "name"), + Subject = ReadString(variables, "subject"), + Layout = ReadString(variables, "layout"), + BundleId = ReadNullableString(variables, "bundleId") + }; + } + + private static int ReadInt(object? source, string propertyName) + { + object? value = ReadValue(source, propertyName); + return value is int intValue ? intValue : 0; + } + + private static string ReadString(object? source, string propertyName) + { + return ReadNullableString(source, propertyName) ?? ""; + } + + private static string? ReadNullableString(object? source, string propertyName) + { + object? value = ReadValue(source, propertyName); + return value?.ToString(); + } + + private static object? ReadValue(object? source, string propertyName) + { + return source?.GetType().GetProperty(propertyName)?.GetValue(source); + } + } + } +} diff --git a/roles/tests-unit/files/FWO.Test/NotificationTest.cs b/roles/tests-unit/files/FWO.Test/NotificationTest.cs new file mode 100644 index 0000000000..36a5954744 --- /dev/null +++ b/roles/tests-unit/files/FWO.Test/NotificationTest.cs @@ -0,0 +1,268 @@ +using NUnit.Framework; +using NUnit.Framework.Legacy; +using FWO.Api.Client; +using FWO.Data; +using FWO.Data.Report; +using FWO.Middleware.Server; +using FWO.Report; +using FWO.Report.Filter; +using System.Reflection; + +namespace FWO.Test +{ + [TestFixture] + [Parallelizable] + internal class NotificationTest + { + readonly NotificationTestApiConn apiConnection = new(); + readonly SimulatedGlobalConfig globalConfig = new() { UseDummyEmailAddress = true, DummyEmailAddress = "x@y.de" }; + const string EmailText = "email text"; + + [Test] + public async Task TestInterfaceRequestNotification() + { + List ownerGroups = []; + NotificationService notificationService = await NotificationService.CreateAsync(NotificationClient.InterfaceRequest, globalConfig, apiConnection, ownerGroups); + FwoOwner owner = new(); + + int emailsSent = await notificationService.SendNotificationsIfDue(owner, DateTime.Now.AddDays(-8), EmailText); + ClassicAssert.AreEqual(2, emailsSent); + ClassicAssert.AreEqual(2, await notificationService.UpdateNotificationsLastSent()); + + notificationService.Notifications[0].LastSent = DateTime.Now.AddDays(-1); + emailsSent = await notificationService.SendNotificationsIfDue(owner, DateTime.Now.AddDays(-8), EmailText); + ClassicAssert.AreEqual(1, emailsSent); + ClassicAssert.AreEqual(1, await notificationService.UpdateNotificationsLastSent()); + + notificationService.Notifications[1].LastSent = DateTime.Now.AddDays(-8); + emailsSent = await notificationService.SendNotificationsIfDue(owner, DateTime.Now.AddDays(-15), EmailText); + ClassicAssert.AreEqual(0, emailsSent); + ClassicAssert.AreEqual(0, await notificationService.UpdateNotificationsLastSent()); + + notificationService.Notifications[1].InitialOffsetAfterDeadline = 7; + emailsSent = await notificationService.SendNotificationsIfDue(owner, DateTime.Now.AddDays(-15), EmailText); + ClassicAssert.AreEqual(1, emailsSent); + + notificationService.Notifications[1].InitialOffsetAfterDeadline = -7; + emailsSent = await notificationService.SendNotificationsIfDue(owner, DateTime.Now.AddDays(-1), EmailText); + ClassicAssert.AreEqual(1, emailsSent); + } + + [Test] + public async Task TestRecertNotification() + { + List ownerGroups = []; + NotificationService notificationService = await NotificationService.CreateAsync(NotificationClient.Recertification, globalConfig, apiConnection, ownerGroups); + FwoOwner owner = new() { NextRecertDate = DateTime.Now.AddDays(21) }; + + int emailsSent = await notificationService.SendNotificationsIfDue(owner, null, EmailText, new ReportRecertEvent(new(""), new(globalConfig), Basics.ReportType.RecertificationEvent) { }); + ClassicAssert.AreEqual(1, emailsSent); + + notificationService.Notifications[0].LastSent = DateTime.Now; + emailsSent = await notificationService.SendNotificationsIfDue(owner, null, EmailText); + ClassicAssert.AreEqual(0, emailsSent); + + notificationService.Notifications[0].LastSent = DateTime.Now.AddDays(-7); + owner.NextRecertDate = DateTime.Now.AddDays(-7); + emailsSent = await notificationService.SendNotificationsIfDue(owner, null, EmailText); + ClassicAssert.AreEqual(1, emailsSent); + + notificationService.Notifications[0].LastSent = DateTime.Now.AddDays(-7); + owner.NextRecertDate = DateTime.Now.AddDays(-14); + emailsSent = await notificationService.SendNotificationsIfDue(owner, null, EmailText); + ClassicAssert.AreEqual(0, emailsSent); + } + + [Test] + public async Task TestRuleExpiryNotificationDueCalculation() + { + List ownerGroups = []; + NotificationService notificationService = await NotificationService.CreateAsync(NotificationClient.RuleTimer, globalConfig, apiConnection, ownerGroups); + FwoOwner owner = new(); + FwoNotification notification = notificationService.Notifications[0]; + + ClassicAssert.IsTrue(NotificationService.IsNotificationDue(owner, DateTime.Now.AddDays(-8), notification)); + notification.LastSent = DateTime.Now.AddDays(-1); + ClassicAssert.IsFalse(NotificationService.IsNotificationDue(owner, DateTime.Now.AddDays(-8), notification)); + } + + [Test] + public void IsNotificationDue_ReturnsFalse_WhenBeforeDeadlineIntervalIsMissing() + { + FwoOwner owner = new() { NextRecertDate = DateTime.Now.AddDays(7) }; + FwoNotification notification = new() + { + Deadline = NotificationDeadline.RecertDate, + IntervalBeforeDeadline = null, + OffsetBeforeDeadline = 1 + }; + + ClassicAssert.IsFalse(NotificationService.IsNotificationDue(owner, null, notification)); + } + + [Test] + public void IsNotificationDue_ReturnsFalse_WhenAfterDeadlineIntervalIsMissing() + { + FwoOwner owner = new(); + FwoNotification notification = new() + { + Deadline = NotificationDeadline.RuleExpiry, + RepeatIntervalAfterDeadline = null, + InitialOffsetAfterDeadline = 0, + RepeatOffsetAfterDeadline = 1, + RepetitionsAfterDeadline = 1 + }; + + ClassicAssert.IsFalse(NotificationService.IsNotificationDue(owner, DateTime.Now.AddDays(-1), notification)); + } + + [Test] + public async Task TestNotificationEmailBodyIsLoaded() + { + List ownerGroups = []; + NotificationService notificationService = await NotificationService.CreateAsync(NotificationClient.InterfaceRequest, globalConfig, apiConnection, ownerGroups); + + ClassicAssert.AreEqual("body1", notificationService.Notifications[0].EmailBody); + ClassicAssert.AreEqual("body2", notificationService.Notifications[1].EmailBody); + } + + [Test] + public async Task SendNotification_UsesNotificationBodyWhenContentIsNull() + { + List ownerGroups = []; + NotificationService notificationService = await NotificationService.CreateAsync(NotificationClient.InterfaceRequest, globalConfig, apiConnection, ownerGroups); + FwoNotification notification = notificationService.Notifications[0]; + FwoOwner owner = new(); + + MethodInfo? prepareEmail = typeof(NotificationService).GetMethod("PrepareEmail", BindingFlags.Instance | BindingFlags.NonPublic); + ClassicAssert.IsNotNull(prepareEmail); + + Task task = (Task)(prepareEmail?.Invoke(notificationService, [notification, null, owner, null, ""]) + ?? throw new InvalidOperationException("PrepareEmail returned null task.")); + FWO.Mail.MailData mailData = await task; + + ClassicAssert.AreEqual(notification.EmailBody, mailData.Body); + } + + [Test] + public async Task SendNotification_PrepareEmail_HandlesNullSubjectAndBody() + { + List ownerGroups = []; + NotificationService notificationService = await NotificationService.CreateAsync(NotificationClient.InterfaceRequest, globalConfig, apiConnection, ownerGroups); + FwoNotification notification = notificationService.Notifications[0]; + notification.EmailSubject = null!; + notification.EmailBody = null!; + FwoOwner owner = new(); + + MethodInfo? prepareEmail = typeof(NotificationService).GetMethod("PrepareEmail", BindingFlags.Instance | BindingFlags.NonPublic); + ClassicAssert.IsNotNull(prepareEmail); + + Task task = (Task)(prepareEmail?.Invoke(notificationService, [notification, null, owner, null, ""]) + ?? throw new InvalidOperationException("PrepareEmail returned null task.")); + FWO.Mail.MailData mailData = await task; + + ClassicAssert.AreEqual(string.Empty, mailData.Subject); + ClassicAssert.AreEqual(string.Empty, mailData.Body); + } + + [Test] + public async Task SendBundledNotifications_PrepareBundledEmail_AddsAllBundleAttachments() + { + List ownerGroups = []; + NotificationService notificationService = await NotificationService.CreateAsync(NotificationClient.InterfaceRequest, globalConfig, apiConnection, ownerGroups); + FwoOwner owner = new() { Name = "Owner", ExtAppId = "1" }; + TestReport report = new(); + string bundleId = Guid.NewGuid().ToString(); + FwoNotification htmlNotification = notificationService.Notifications[0]; + htmlNotification.Layout = NotificationLayout.HtmlAsAttachment; + htmlNotification.BundleType = BundleType.Attachments; + htmlNotification.BundleId = bundleId; + + FwoNotification jsonNotification = notificationService.Notifications[1]; + jsonNotification.Layout = NotificationLayout.JsonAsAttachment; + jsonNotification.BundleType = BundleType.Attachments; + jsonNotification.BundleId = bundleId; + + MethodInfo? prepareBundledEmail = typeof(NotificationService).GetMethod("PrepareBundledEmail", BindingFlags.Instance | BindingFlags.NonPublic); + ClassicAssert.IsNotNull(prepareBundledEmail); + + Task task = (Task)(prepareBundledEmail?.Invoke(notificationService, + [new List { htmlNotification, jsonNotification }, null, owner, report, ""]) + ?? throw new InvalidOperationException("PrepareBundledEmail returned null task.")); + FWO.Mail.MailData mailData = await task; + + ClassicAssert.AreEqual(htmlNotification.EmailBody, mailData.Body); + ClassicAssert.IsNotNull(mailData.Attachments); + ClassicAssert.AreEqual(2, mailData.Attachments?.Count); + } + + [Test] + public void TestDecommissionNotificationDueCalculation() + { + FwoOwner owner = new() { DecommDate = DateTime.Now.AddDays(-8) }; + FwoNotification notification = new() + { + Deadline = NotificationDeadline.DecommissionDate, + RepeatIntervalAfterDeadline = SchedulerInterval.Days, + RepeatOffsetAfterDeadline = 7, + RepetitionsAfterDeadline = 2 + }; + + ClassicAssert.IsTrue(NotificationService.IsNotificationDue(owner, null, notification)); + notification.LastSent = DateTime.Now.AddDays(-1); + ClassicAssert.IsFalse(NotificationService.IsNotificationDue(owner, null, notification)); + } + + [Test] + public void TestNotificationDeadlineIsAlwaysInPast() + { + ClassicAssert.IsTrue(NotificationDeadline.RequestDate.IsAlwaysInPast()); + ClassicAssert.IsTrue(NotificationDeadline.DecommissionDate.IsAlwaysInPast()); + ClassicAssert.IsFalse(NotificationDeadline.None.IsAlwaysInPast()); + ClassicAssert.IsFalse(NotificationDeadline.RecertDate.IsAlwaysInPast()); + ClassicAssert.IsFalse(NotificationDeadline.RuleExpiry.IsAlwaysInPast()); + } + + [Test] + public void GetNotificationText_UsesConfiguredNotificationLanguage_AndFallsBackToDefaultLanguage() + { + globalConfig.DefaultLanguage = "English"; + globalConfig.NotificationLanguage = "German"; + globalConfig.GermanTranslate["generated_on"] = "Erstellt am"; + globalConfig.DummyTranslate["generated_on"] = "Generated on"; + + ClassicAssert.AreEqual("Erstellt am", globalConfig.GetNotificationText("generated_on")); + + globalConfig.NotificationLanguage = ""; + ClassicAssert.AreEqual("Generated on", globalConfig.GetNotificationText("generated_on")); + } + + private class TestReport() : ReportBase(new DynGraphqlQuery(""), new SimulatedUserConfig(), Basics.ReportType.TicketReport) + { + public override Task Generate(int elementsPerFetch, ApiConnection apiConnection, Func callback, CancellationToken ct) + { + return Task.CompletedTask; + } + + public override string ExportToCsv() + { + return "csv"; + } + + public override string ExportToJson() + { + return "{\"a\":1}"; + } + + public override string ExportToHtml() + { + return "report"; + } + + public override string SetDescription() + { + return ""; + } + } + } +} diff --git a/roles/tests-unit/files/FWO.Test/NotificationTestApiConn.cs b/roles/tests-unit/files/FWO.Test/NotificationTestApiConn.cs new file mode 100644 index 0000000000..081448c6eb --- /dev/null +++ b/roles/tests-unit/files/FWO.Test/NotificationTestApiConn.cs @@ -0,0 +1,130 @@ +using GraphQL; +using FWO.Api.Client.Queries; +using FWO.Data; +using FWO.Services; + +namespace FWO.Test +{ + internal class NotificationTestApiConn : SimulatedApiConnection + { + readonly FwoNotification NotifReq1 = new() + { + Id = 1, + RecipientTo = EmailRecipientOption.OtherAddresses, + EmailAddressTo = "a@b.de", + EmailSubject = "subject1", + EmailBody = "body1", + Deadline = NotificationDeadline.RequestDate, + RepeatIntervalAfterDeadline = SchedulerInterval.Weeks, + RepeatOffsetAfterDeadline = 1, + RepetitionsAfterDeadline = 3 + }; + + readonly FwoNotification NotifReq2 = new() + { + Id = 2, + RecipientTo = EmailRecipientOption.OtherAddresses, + EmailAddressTo = "a@b.de", + EmailSubject = "subject2", + EmailBody = "body2", + Deadline = NotificationDeadline.RequestDate, + RepeatIntervalAfterDeadline = SchedulerInterval.Days, + RepeatOffsetAfterDeadline = 7, + RepetitionsAfterDeadline = 1 + }; + + readonly FwoNotification NotifRec = new() + { + Id = 1, + RecipientTo = EmailRecipientOption.OtherAddresses, + EmailAddressTo = "a@b.de", + EmailSubject = "subject", + EmailBody = "body", + Deadline = NotificationDeadline.RecertDate, + IntervalBeforeDeadline = SchedulerInterval.Weeks, + OffsetBeforeDeadline = 3, + RepeatIntervalAfterDeadline = SchedulerInterval.Weeks, + RepeatOffsetAfterDeadline = 1, + RepetitionsAfterDeadline = 1, + Layout = NotificationLayout.HtmlAsAttachment + }; + + readonly FwoNotification NotifRuleTimer = new() + { + Id = 3, + RecipientTo = EmailRecipientOption.OtherAddresses, + EmailAddressTo = "a@b.de", + EmailSubject = "subject3", + EmailBody = "body3", + Deadline = NotificationDeadline.RuleExpiry, + RepeatIntervalAfterDeadline = SchedulerInterval.Days, + RepeatOffsetAfterDeadline = 7, + RepetitionsAfterDeadline = 2 + }; + + public override async Task SendQueryAsync(string query, object? variables = null, string? operationName = null) + { + await DefaultInit.DoNothing(); // qad avoid compiler warning + Type responseType = typeof(QueryResponseType); + if (responseType == typeof(List)) + { + string? Vars = variables?.ToString(); + List? notifs = Vars != null && Vars.Contains($"{NotificationClient.InterfaceRequest}") + ? [CloneNotification(NotifReq1), CloneNotification(NotifReq2)] + : Vars != null && Vars.Contains($"{NotificationClient.RuleTimer}") + ? [CloneNotification(NotifRuleTimer)] + : [CloneNotification(NotifRec)]; + GraphQLResponse response = new() { Data = notifs }; + return response.Data; + } + if (responseType == typeof(ReturnId)) + { + int notifCount = 0; + var idsProp = variables?.GetType().GetProperty("ids"); + if (idsProp != null) + { + var idsValue = idsProp.GetValue(variables); + if (idsValue is System.Collections.ICollection collection) + { + notifCount = collection.Count; + } + } + GraphQLResponse response = new() { Data = new ReturnId() { AffectedRows = notifCount } }; + return response.Data; + } + + throw new NotImplementedException(); + } + + private static FwoNotification CloneNotification(FwoNotification notification) + { + return new FwoNotification + { + Id = notification.Id, + NotificationClient = notification.NotificationClient, + UserId = notification.UserId, + OwnerId = notification.OwnerId, + Channel = notification.Channel, + Name = notification.Name, + RecipientTo = notification.RecipientTo, + EmailAddressTo = notification.EmailAddressTo, + RecipientCc = notification.RecipientCc, + EmailAddressCc = notification.EmailAddressCc, + EmailSubject = notification.EmailSubject, + EmailBody = notification.EmailBody, + ScheduleId = notification.ScheduleId, + BundleType = notification.BundleType, + BundleId = notification.BundleId, + Layout = notification.Layout, + Deadline = notification.Deadline, + IntervalBeforeDeadline = notification.IntervalBeforeDeadline, + OffsetBeforeDeadline = notification.OffsetBeforeDeadline, + RepeatIntervalAfterDeadline = notification.RepeatIntervalAfterDeadline, + InitialOffsetAfterDeadline = notification.InitialOffsetAfterDeadline, + RepeatOffsetAfterDeadline = notification.RepeatOffsetAfterDeadline, + RepetitionsAfterDeadline = notification.RepetitionsAfterDeadline, + LastSent = notification.LastSent + }; + } + } +} diff --git a/roles/tests-unit/files/FWO.Test/NwElementTest.cs b/roles/tests-unit/files/FWO.Test/NwElementTest.cs new file mode 100644 index 0000000000..4cb427ca6b --- /dev/null +++ b/roles/tests-unit/files/FWO.Test/NwElementTest.cs @@ -0,0 +1,181 @@ +using FWO.Data; +using FWO.Data.Workflow; +using NetTools; +using NUnit.Framework; + +namespace FWO.Test +{ + [TestFixture] + internal class NwElementTest + { + [Test] + public void NwObjectElement_CtorWithCidrString_SetsCidrAndTaskId() + { + NwObjectElement element = new("10.0.0.0/24", 12); + + Assert.That(element.TaskId, Is.EqualTo(12)); + Assert.That(element.Cidr.Valid, Is.True); + Assert.That(element.Cidr.CidrString, Is.EqualTo("10.0.0.0/24")); + } + + [Test] + public void NwObjectElement_CtorWithIpRange_SetsCidrAndCidrEnd() + { + IPAddressRange range = new(System.Net.IPAddress.Parse("10.0.0.1"), System.Net.IPAddress.Parse("10.0.0.2")); + + NwObjectElement element = new(range, 5); + + Assert.That(element.TaskId, Is.EqualTo(5)); + Assert.That(element.Cidr.CidrString, Is.EqualTo("10.0.0.1/32")); + Assert.That(element.CidrEnd.CidrString, Is.EqualTo("10.0.0.2/32")); + } + + [Test] + public void NwObjectElement_ToReqElement_CopiesFields() + { + NwObjectElement element = new() + { + ElemId = 1, + TaskId = 2, + Cidr = new Cidr("10.0.0.1/32"), + CidrEnd = new Cidr("10.0.0.2/32"), + NetworkId = 3, + GroupName = "grp", + RequestAction = "create", + Name = "obj" + }; + + WfReqElement reqElement = element.ToReqElement(ElemFieldType.source); + + Assert.That(reqElement.Id, Is.EqualTo(1)); + Assert.That(reqElement.TaskId, Is.EqualTo(2)); + Assert.That(reqElement.Field, Is.EqualTo(ElemFieldType.source.ToString())); + Assert.That(reqElement.Cidr?.CidrString, Is.EqualTo("10.0.0.1/32")); + Assert.That(reqElement.CidrEnd?.CidrString, Is.EqualTo("10.0.0.2/32")); + Assert.That(reqElement.NetworkId, Is.EqualTo(3)); + Assert.That(reqElement.GroupName, Is.EqualTo("grp")); + Assert.That(reqElement.RequestAction, Is.EqualTo("create")); + Assert.That(reqElement.Name, Is.EqualTo("obj")); + } + + [Test] + public void NwObjectElement_ToImplElement_CopiesFields() + { + NwObjectElement element = new() + { + ElemId = 1, + TaskId = 2, + Cidr = new Cidr("10.0.0.1/32"), + CidrEnd = new Cidr("10.0.0.2/32"), + NetworkId = 3, + GroupName = "grp", + Name = "obj" + }; + + WfImplElement implElement = element.ToImplElement(ElemFieldType.destination); + + Assert.That(implElement.Id, Is.EqualTo(1)); + Assert.That(implElement.ImplTaskId, Is.EqualTo(2)); + Assert.That(implElement.Field, Is.EqualTo(ElemFieldType.destination.ToString())); + Assert.That(implElement.Cidr?.CidrString, Is.EqualTo("10.0.0.1/32")); + Assert.That(implElement.CidrEnd?.CidrString, Is.EqualTo("10.0.0.2/32")); + Assert.That(implElement.NetworkId, Is.EqualTo(3)); + Assert.That(implElement.GroupName, Is.EqualTo("grp")); + Assert.That(implElement.Name, Is.EqualTo("obj")); + } + + [Test] + public void NwServiceElement_ToReqElement_CopiesFields() + { + NwServiceElement element = new() + { + ElemId = 1, + TaskId = 2, + Port = 80, + PortEnd = 81, + ProtoId = 6, + ServiceId = 7, + Name = "svc", + RequestAction = "delete" + }; + + WfReqElement reqElement = element.ToReqElement(); + + Assert.That(reqElement.Id, Is.EqualTo(1)); + Assert.That(reqElement.TaskId, Is.EqualTo(2)); + Assert.That(reqElement.Field, Is.EqualTo(ElemFieldType.service.ToString())); + Assert.That(reqElement.Port, Is.EqualTo(80)); + Assert.That(reqElement.PortEnd, Is.EqualTo(81)); + Assert.That(reqElement.ProtoId, Is.EqualTo(6)); + Assert.That(reqElement.ServiceId, Is.EqualTo(7)); + Assert.That(reqElement.Name, Is.EqualTo("svc")); + Assert.That(reqElement.RequestAction, Is.EqualTo("delete")); + } + + [Test] + public void NwServiceElement_ToImplElement_CopiesFields() + { + NwServiceElement element = new() + { + ElemId = 1, + TaskId = 2, + Port = 80, + PortEnd = 81, + ProtoId = 6, + ServiceId = 7, + Name = "svc" + }; + + WfImplElement implElement = element.ToImplElement(); + + Assert.That(implElement.Id, Is.EqualTo(1)); + Assert.That(implElement.ImplTaskId, Is.EqualTo(2)); + Assert.That(implElement.Field, Is.EqualTo(ElemFieldType.service.ToString())); + Assert.That(implElement.Port, Is.EqualTo(80)); + Assert.That(implElement.PortEnd, Is.EqualTo(81)); + Assert.That(implElement.ProtoId, Is.EqualTo(6)); + Assert.That(implElement.ServiceId, Is.EqualTo(7)); + Assert.That(implElement.Name, Is.EqualTo("svc")); + } + + [Test] + public void NwRuleElement_ToReqElement_CopiesFields() + { + NwRuleElement element = new() + { + ElemId = 1, + TaskId = 2, + RuleUid = "uid", + Name = "rule" + }; + + WfReqElement reqElement = element.ToReqElement(); + + Assert.That(reqElement.Id, Is.EqualTo(1)); + Assert.That(reqElement.TaskId, Is.EqualTo(2)); + Assert.That(reqElement.Field, Is.EqualTo(ElemFieldType.rule.ToString())); + Assert.That(reqElement.RuleUid, Is.EqualTo("uid")); + Assert.That(reqElement.Name, Is.EqualTo("rule")); + } + + [Test] + public void NwRuleElement_ToImplElement_CopiesFields() + { + NwRuleElement element = new() + { + ElemId = 1, + TaskId = 2, + RuleUid = "uid", + Name = "rule" + }; + + WfImplElement implElement = element.ToImplElement(); + + Assert.That(implElement.Id, Is.EqualTo(1)); + Assert.That(implElement.ImplTaskId, Is.EqualTo(2)); + Assert.That(implElement.Field, Is.EqualTo(ElemFieldType.rule.ToString())); + Assert.That(implElement.RuleUid, Is.EqualTo("uid")); + Assert.That(implElement.Name, Is.EqualTo("rule")); + } + } +} diff --git a/roles/tests-unit/files/FWO.Test/OwnerActiveRuleCheckTest.cs b/roles/tests-unit/files/FWO.Test/OwnerActiveRuleCheckTest.cs new file mode 100644 index 0000000000..ff729202e2 --- /dev/null +++ b/roles/tests-unit/files/FWO.Test/OwnerActiveRuleCheckTest.cs @@ -0,0 +1,164 @@ +using FWO.Api.Client.Queries; +using FWO.Config.Api; +using FWO.Data; +using FWO.Middleware.Server; +using NUnit.Framework; +using System.Reflection; + +namespace FWO.Test +{ + [TestFixture] + public class OwnerActiveRuleCheckTest + { + [Test] + public async Task CheckActiveRulesSync_ReturnsZero_WhenOwnerIdIsInvalid() + { + OwnerActiveRuleCheckApiConn apiConnection = new(); + OwnerActiveRuleCheck service = new(apiConnection, new GlobalConfig()); + + int sentNotifications = await service.CheckActiveRulesSync(new FwoOwner { Id = 0, Name = "Owner A", ExtAppId = "APP-0" }); + + Assert.That(sentNotifications, Is.EqualTo(0)); + Assert.That(apiConnection.ActiveRuleQueryCalls, Is.EqualTo(0)); + } + + [Test] + public async Task CheckActiveRulesSync_ReturnsZero_WhenNoActiveRulesExist() + { + OwnerActiveRuleCheckApiConn apiConnection = new(); + OwnerActiveRuleCheck service = new(apiConnection, new GlobalConfig()); + + int sentNotifications = await service.CheckActiveRulesSync(new FwoOwner { Id = 7, Name = "Owner A", ExtAppId = "APP-7" }); + + Assert.That(sentNotifications, Is.EqualTo(0)); + Assert.That(apiConnection.ActiveRuleQueryCalls, Is.EqualTo(1)); + } + + [Test] + public async Task CheckActiveRules_ReturnsZero_WhenOwnerHasNoDecommDate() + { + OwnerActiveRuleCheckApiConn apiConnection = new(); + apiConnection.Owners = + [ + new FwoOwner { Id = 7, Name = "Owner A", ExtAppId = "APP-7" } + ]; + OwnerActiveRuleCheck service = new(apiConnection, new GlobalConfig()); + + int sentNotifications = await service.CheckActiveRulesByScheduler(); + + Assert.That(sentNotifications, Is.EqualTo(0)); + Assert.That(apiConnection.OwnerQueryCalls, Is.EqualTo(1)); + Assert.That(apiConnection.ActiveRuleQueryCalls, Is.EqualTo(0)); + } + + [Test] + public async Task CheckActiveRules_ReturnsZero_WhenNoActiveRulesExist() + { + OwnerActiveRuleCheckApiConn apiConnection = new(); + apiConnection.Owners = + [ + new FwoOwner { Id = 7, Name = "Owner A", ExtAppId = "APP-7", DecommDate = DateTime.Now.AddDays(-2) } + ]; + OwnerActiveRuleCheck service = new(apiConnection, new GlobalConfig()); + + int sentNotifications = await service.CheckActiveRulesByScheduler(); + + Assert.That(sentNotifications, Is.EqualTo(0)); + Assert.That(apiConnection.OwnerQueryCalls, Is.EqualTo(1)); + Assert.That(apiConnection.ActiveRuleQueryCalls, Is.EqualTo(1)); + } + + [Test] + public async Task CheckActiveRules_ReturnsZero_WhenOwnersAreLoadedForDailyCheck() + { + OwnerActiveRuleCheckApiConn apiConnection = new(); + apiConnection.Owners = + [ + new FwoOwner { Id = 7, Name = "Owner A", ExtAppId = "APP-7", DecommDate = DateTime.Now.AddDays(-2) }, + new FwoOwner { Id = 8, Name = "Owner B", ExtAppId = "APP-8" } + ]; + OwnerActiveRuleCheck service = new(apiConnection, new GlobalConfig()); + + int sentNotifications = await service.CheckActiveRulesByScheduler(); + + Assert.That(sentNotifications, Is.EqualTo(0)); + Assert.That(apiConnection.OwnerQueryCalls, Is.EqualTo(1)); + Assert.That(apiConnection.ActiveRuleQueryCalls, Is.EqualTo(1)); + } + + [Test] + public void ExtractChangeId_ReturnsField2_ForValidJson() + { + string changeId = InvokeExtractChangeId("{\"field-2\":\"CHG-123\",\"Datum-Regelpruefung\":\"fallback\"}"); + + Assert.That(changeId, Is.EqualTo("CHG-123")); + } + + [Test] + public void ExtractChangeId_ReturnsFallback_ForSingleQuotedLegacyPayload() + { + string changeId = InvokeExtractChangeId("{'Datum-Regelpruefung':'2026-03-19'}"); + + Assert.That(changeId, Is.EqualTo("2026-03-19")); + } + + [Test] + public void ExtractChangeId_ReturnsEmpty_ForMalformedPayload() + { + string changeId = InvokeExtractChangeId("{'field-2':"); + + Assert.That(changeId, Is.Empty); + } + + private static string InvokeExtractChangeId(string customFields) + { + MethodInfo extractChangeId = typeof(RuleNotificationBodyBase).GetMethod("ExtractChangeId", BindingFlags.Static | BindingFlags.NonPublic) + ?? throw new InvalidOperationException("ExtractChangeId method not found."); + + return (string)(extractChangeId.Invoke(null, [customFields]) + ?? throw new InvalidOperationException("ExtractChangeId returned null.")); + } + + private sealed class OwnerActiveRuleCheckApiConn : SimulatedApiConnection + { + public int ActiveRuleQueryCalls { get; private set; } + public int OwnerQueryCalls { get; private set; } + + public Dictionary> ActiveRulesByOwnerId { get; } = []; + public List Owners { get; set; } = []; + + public override Task SendQueryAsync(string query, object? variables = null, string? operationName = null) + { + if (query == OwnerQueries.getOwners) + { + ++OwnerQueryCalls; + return Task.FromResult((QueryResponseType)(object)Owners); + } + + if (query == RuleQueries.getActiveRulesByOwner) + { + ++ActiveRuleQueryCalls; + int ownerId = GetOwnerId(variables); + List result = ActiveRulesByOwnerId.TryGetValue(ownerId, out List? activeRules) + ? activeRules + : []; + return Task.FromResult((QueryResponseType)(object)result); + } + + throw new NotImplementedException($"Query not implemented in owner active rule check test api: {query}"); + } + + private static int GetOwnerId(object? variables) + { + if (variables == null) + { + return 0; + } + + var property = variables.GetType().GetProperty("ownerId"); + object? value = property?.GetValue(variables); + return value is int ownerId ? ownerId : 0; + } + } + } +} diff --git a/roles/tests-unit/files/FWO.Test/OwnerAdditionalInfoJsonTest.cs b/roles/tests-unit/files/FWO.Test/OwnerAdditionalInfoJsonTest.cs new file mode 100644 index 0000000000..989ad67307 --- /dev/null +++ b/roles/tests-unit/files/FWO.Test/OwnerAdditionalInfoJsonTest.cs @@ -0,0 +1,57 @@ +using System.Collections.Generic; +using FWO.Data; +using NUnit.Framework; + +namespace FWO.Test +{ + [TestFixture] + internal class OwnerAdditionalInfoJsonTest + { + [Test] + public void Serialize_ReturnsIndentedJson_ForExistingData() + { + Dictionary additionalInfo = new() + { + ["cost_center"] = "4711", + ["owner_type"] = "shared" + }; + + string serialized = OwnerAdditionalInfoJson.Serialize(additionalInfo); + + Assert.That(serialized, Does.Contain("\n")); + Assert.That(serialized, Does.Contain("\"cost_center\": \"4711\"")); + Assert.That(serialized, Does.Contain("\"owner_type\": \"shared\"")); + } + + [Test] + public void TryDeserialize_ReturnsDictionary_ForValidJson() + { + bool parsed = OwnerAdditionalInfoJson.TryDeserialize( + "{\n \"cost_center\": \"4711\",\n \"owner_type\": \"shared\"\n}", + out Dictionary? additionalInfo); + + Assert.That(parsed, Is.True); + Assert.That(additionalInfo, Is.Not.Null); + Assert.That(additionalInfo?["cost_center"], Is.EqualTo("4711")); + Assert.That(additionalInfo?["owner_type"], Is.EqualTo("shared")); + } + + [Test] + public void TryDeserialize_ReturnsNull_ForEmptyInput() + { + bool parsed = OwnerAdditionalInfoJson.TryDeserialize(" ", out Dictionary? additionalInfo); + + Assert.That(parsed, Is.True); + Assert.That(additionalInfo, Is.Null); + } + + [Test] + public void TryDeserialize_ReturnsFalse_ForInvalidJson() + { + bool parsed = OwnerAdditionalInfoJson.TryDeserialize("{ invalid json }", out Dictionary? additionalInfo); + + Assert.That(parsed, Is.False); + Assert.That(additionalInfo, Is.Null); + } + } +} diff --git a/roles/tests-unit/files/FWO.Test/OwnerLifeCycleStateTest.cs b/roles/tests-unit/files/FWO.Test/OwnerLifeCycleStateTest.cs new file mode 100644 index 0000000000..9c7656f882 --- /dev/null +++ b/roles/tests-unit/files/FWO.Test/OwnerLifeCycleStateTest.cs @@ -0,0 +1,26 @@ +using FWO.Data; +using NUnit.Framework; + +namespace FWO.Test +{ + [TestFixture] + internal class OwnerLifeCycleStateTest + { + [Test] + public void CopyConstructor_CopiesActiveState() + { + OwnerLifeCycleState source = new() + { + Id = 4, + Name = "Pilot", + ActiveState = false + }; + + OwnerLifeCycleState copy = new(source); + + Assert.That(copy.Id, Is.EqualTo(4)); + Assert.That(copy.Name, Is.EqualTo("Pilot")); + Assert.That(copy.ActiveState, Is.False); + } + } +} diff --git a/roles/tests-unit/files/FWO.Test/OwnerQueriesTest.cs b/roles/tests-unit/files/FWO.Test/OwnerQueriesTest.cs new file mode 100644 index 0000000000..9ea90f8d16 --- /dev/null +++ b/roles/tests-unit/files/FWO.Test/OwnerQueriesTest.cs @@ -0,0 +1,63 @@ +using FWO.Api.Client.Queries; +using NUnit.Framework; + +namespace FWO.Test +{ + [TestFixture] + public class OwnerQueriesTest + { + [Test] + public void GetOwnersForUserUsesActiveResponsibleTypes() + { + string query = OwnerQueries.getOwnersForUser; + + Assert.That(query, Does.Contain("owner_responsible_type: {active: {_eq: true}}")); + } + + [Test] + public void GetOwnerResponsibleTypesIncludesAllowWriteAccess() + { + string query = OwnerQueries.getOwnerResponsibleTypes; + + Assert.That(query, Does.Contain("allow_modelling")); + Assert.That(query, Does.Contain("allow_recertification")); + } + + [Test] + public void GetOwnersForDnsWithModellingUsesAllowModellingFilter() + { + string query = OwnerQueries.getOwnersForDnsWithModellingWithConn; + + Assert.That(query, Does.Contain("allow_modelling: {_eq: true}")); + } + + [Test] + public void GetOwnersForDnsWithConnUsesOnlyActiveResponsibleTypes() + { + string query = OwnerQueries.getOwnersForDnsWithConn; + + Assert.That(query, Does.Contain("owner_responsible_type: {")); + Assert.That(query, Does.Contain("active: {_eq: true}")); + Assert.That(query, Does.Not.Contain("allow_modelling: {_eq: true}")); + Assert.That(query, Does.Not.Contain("allow_recertification: {_eq: true}")); + } + + [Test] + public void GetOwnersForDnsDoesNotDependOnConnectionsAggregate() + { + string query = OwnerQueries.getOwnersForDns; + + Assert.That(query, Does.Contain("owner_responsibles: {")); + Assert.That(query, Does.Contain("active: {_eq: true}")); + Assert.That(query, Does.Not.Contain("connections_aggregate")); + } + + [Test] + public void GetOwnersForDnsWithRecertificationUsesAllowRecertificationFilter() + { + string query = OwnerQueries.getOwnersForDnsWithRecertification; + + Assert.That(query, Does.Contain("allow_recertification: {_eq: true}")); + } + } +} diff --git a/roles/tests-unit/files/FWO.Test/OwnerResponsibleRoleHelperTest.cs b/roles/tests-unit/files/FWO.Test/OwnerResponsibleRoleHelperTest.cs new file mode 100644 index 0000000000..3d274e08f6 --- /dev/null +++ b/roles/tests-unit/files/FWO.Test/OwnerResponsibleRoleHelperTest.cs @@ -0,0 +1,50 @@ +using FWO.Basics; +using NUnit.Framework; +using System.Collections.Generic; + +namespace FWO.Test +{ + [TestFixture] + public class OwnerResponsibleRoleHelperTest + { + [Test] + public void FilterRolesRemovesModellingAndRecertWhenDisallowed() + { + List roles = [Roles.Modeller, Roles.Recertifier, Roles.Reporter]; + + List filtered = OwnerResponsibleRoleHelper.FilterRoles(roles, false, false); + + Assert.That(filtered, Is.EquivalentTo(new[] { Roles.Reporter })); + } + + [Test] + public void FilterRolesKeepsAllRolesWhenAllowed() + { + List roles = [Roles.Modeller, Roles.Recertifier, Roles.Reporter]; + + List filtered = OwnerResponsibleRoleHelper.FilterRoles(roles, true, true); + + Assert.That(filtered, Is.EquivalentTo(roles)); + } + + [Test] + public void FilterRolesRemovesModellingOnlyWhenModellingIsDisallowed() + { + List roles = [Roles.Modeller, Roles.Recertifier, Roles.Reporter]; + + List filtered = OwnerResponsibleRoleHelper.FilterRoles(roles, false, true); + + Assert.That(filtered, Is.EquivalentTo(new[] { Roles.Recertifier, Roles.Reporter })); + } + + [Test] + public void FilterRolesRemovesRecertificationOnlyWhenRecertificationIsDisallowed() + { + List roles = [Roles.Modeller, Roles.Recertifier, Roles.Reporter]; + + List filtered = OwnerResponsibleRoleHelper.FilterRoles(roles, true, false); + + Assert.That(filtered, Is.EquivalentTo(new[] { Roles.Modeller, Roles.Reporter })); + } + } +} diff --git a/roles/tests-unit/files/FWO.Test/QuartzSchedulerServiceBaseTest.cs b/roles/tests-unit/files/FWO.Test/QuartzSchedulerServiceBaseTest.cs new file mode 100644 index 0000000000..486541111d --- /dev/null +++ b/roles/tests-unit/files/FWO.Test/QuartzSchedulerServiceBaseTest.cs @@ -0,0 +1,75 @@ +using FWO.Middleware.Server.Services; +using NUnit.Framework; +using NUnit.Framework.Legacy; +using Quartz; + +namespace FWO.Test +{ + [TestFixture] + [Parallelizable] + internal class QuartzSchedulerServiceBaseTest + { + private sealed class TestJob : IJob + { + public Task Execute(IJobExecutionContext context) => Task.CompletedTask; + } + + private sealed class TestSchedulerService : QuartzSchedulerServiceBase + { + private TestSchedulerService() + : base( + null!, + null!, + null!, + null!, + new QuartzSchedulerOptions("Test", "Test", "Test", "Test")) + { } + + protected override int SleepTime => 1; + + protected override DateTime StartAt => DateTime.MinValue; + + protected override TimeSpan Interval => TimeSpan.FromSeconds(1); + + public static DateTimeOffset CalculateStartTimeForTest(DateTime configuredStartTime, TimeSpan interval, DateTime now) + { + return CalculateStartTime(configuredStartTime, interval, now); + } + } + + [Test] + public void CalculateStartTime_ReturnsFutureStartTime() + { + DateTime now = new(2024, 1, 1, 12, 0, 0, DateTimeKind.Unspecified); + DateTime configuredStartTime = now.AddMinutes(-12); + TimeSpan interval = TimeSpan.FromMinutes(5); + + DateTimeOffset result = TestSchedulerService.CalculateStartTimeForTest(configuredStartTime, interval, now); + + DateTimeOffset expected = new(now.AddMinutes(3)); + ClassicAssert.AreEqual(expected, result); + } + + [Test] + public void CalculateStartTime_PreservesFutureStartTime() + { + DateTime now = new(2024, 1, 1, 12, 0, 0, DateTimeKind.Unspecified); + DateTime configuredStartTime = now.AddMinutes(10); + TimeSpan interval = TimeSpan.FromMinutes(5); + + DateTimeOffset result = TestSchedulerService.CalculateStartTimeForTest(configuredStartTime, interval, now); + + ClassicAssert.AreEqual(new DateTimeOffset(configuredStartTime), result); + } + + [Test] + public void CalculateStartTime_ThrowsOnNonPositiveInterval() + { + DateTime now = new(2024, 1, 1, 12, 0, 0, DateTimeKind.Unspecified); + DateTime configuredStartTime = now; + + Assert.Throws(() => + TestSchedulerService.CalculateStartTimeForTest(configuredStartTime, TimeSpan.Zero, now)); + } + } +} diff --git a/roles/tests-unit/files/FWO.Test/RecertificationOwnerSelectionTest.cs b/roles/tests-unit/files/FWO.Test/RecertificationOwnerSelectionTest.cs new file mode 100644 index 0000000000..9e885940b4 --- /dev/null +++ b/roles/tests-unit/files/FWO.Test/RecertificationOwnerSelectionTest.cs @@ -0,0 +1,151 @@ +using FWO.Data; +using FWO.Ui.Services; +using NUnit.Framework; +using System.Collections.Generic; +using System.Security.Claims; + +namespace FWO.Test +{ + [TestFixture] + public class RecertificationOwnerSelectionTest + { + [Test] + public void SelectOwnerReturnsNullForEmptyOwnerList() + { + FwoOwner? selectedOwner = RecertificationOwnerSelection.SelectOwner([], []); + + Assert.That(selectedOwner, Is.Null); + } + + [Test] + public void SelectOwnerReturnsFirstOwnerIfNoRecertifiableOwnerExists() + { + List owners = + [ + new() { Id = 7, Name = "Owner A" }, + new() { Id = 9, Name = "Owner B" } + ]; + + FwoOwner? selectedOwner = RecertificationOwnerSelection.SelectOwner(owners, [42]); + + Assert.That(selectedOwner?.Id, Is.EqualTo(7)); + } + + [Test] + public void SelectOwnerPrefersFirstRecertifiableOwner() + { + List owners = + [ + new() { Id = 3, Name = "Owner C" }, + new() { Id = 11, Name = "Owner D" }, + new() { Id = 17, Name = "Owner E" } + ]; + + FwoOwner? selectedOwner = RecertificationOwnerSelection.SelectOwner(owners, [17, 11]); + + Assert.That(selectedOwner?.Id, Is.EqualTo(11)); + } + + [Test] + public void SelectOwnerReturnsFirstOwnerIfNoRecertifiableOwnerIdsAreProvided() + { + List owners = + [ + new() { Id = 4, Name = "Owner F" }, + new() { Id = 5, Name = "Owner G" } + ]; + + FwoOwner? selectedOwner = RecertificationOwnerSelection.SelectOwner(owners, []); + + Assert.That(selectedOwner?.Id, Is.EqualTo(4)); + } + + [Test] + public void ResolveOwnerIdsUsesConfiguredIdsWhenPresent() + { + List configuredOwnerIds = [4, 9]; + List claims = [new("x-hasura-recertifiable-owners", "{11,12}")]; + + List resolvedOwnerIds = RecertificationOwnerSelection.ResolveOwnerIds(configuredOwnerIds, claims, "x-hasura-recertifiable-owners"); + + Assert.That(resolvedOwnerIds, Is.EqualTo(new List { 4, 9 })); + } + + [Test] + public void ResolveOwnerIdsFallsBackToClaimValues() + { + List configuredOwnerIds = []; + List claims = [new("x-hasura-recertifiable-owners", "{11,12}")]; + + List resolvedOwnerIds = RecertificationOwnerSelection.ResolveOwnerIds(configuredOwnerIds, claims, "x-hasura-recertifiable-owners"); + + Assert.That(resolvedOwnerIds, Is.EqualTo(new List { 11, 12 })); + } + + [Test] + public void CanWriteSelectedOwnerReturnsTrueForAdmin() + { + FwoOwner selectedOwner = new() { Id = 7, Name = "Owner" }; + + bool canWrite = RecertificationOwnerSelection.CanWriteSelectedOwner(selectedOwner, true, false, []); + + Assert.That(canWrite, Is.True); + } + + [Test] + public void CanWriteSelectedOwnerRequiresRecertifierMembershipForNonAdmin() + { + FwoOwner selectedOwner = new() { Id = 7, Name = "Owner" }; + + bool canWrite = RecertificationOwnerSelection.CanWriteSelectedOwner(selectedOwner, false, false, [7]); + + Assert.That(canWrite, Is.False); + } + + [Test] + public void CanWriteSelectedOwnerChecksRecertifiableIdsForRecertifier() + { + FwoOwner selectedOwner = new() { Id = 7, Name = "Owner" }; + + bool canWrite = RecertificationOwnerSelection.CanWriteSelectedOwner(selectedOwner, false, true, [9]); + + Assert.That(canWrite, Is.False); + } + + [Test] + public void ShowNoRecertifiableOwnersHintReturnsTrueForRecertifierWithoutRecertifiableOwners() + { + bool showHint = RecertificationOwnerSelection.ShowNoRecertifiableOwnersHint( + isAdmin: false, + hasRecertifierRole: true, + readableOwnerCount: 2, + recertifiableOwnerCount: 0); + + Assert.That(showHint, Is.True); + } + + [Test] + public void ShowNoRecertifiableOwnersHintReturnsFalseForAdmin() + { + bool showHint = RecertificationOwnerSelection.ShowNoRecertifiableOwnersHint( + isAdmin: true, + hasRecertifierRole: true, + readableOwnerCount: 2, + recertifiableOwnerCount: 0); + + Assert.That(showHint, Is.False); + } + + [Test] + public void ShowNoRecertifiableOwnersHintReturnsFalseWhenNoReadableOwners() + { + bool showHint = RecertificationOwnerSelection.ShowNoRecertifiableOwnersHint( + isAdmin: false, + hasRecertifierRole: true, + readableOwnerCount: 0, + recertifiableOwnerCount: 0); + + Assert.That(showHint, Is.False); + } + } +} diff --git a/roles/tests-unit/files/FWO.Test/ReportBaseTest.cs b/roles/tests-unit/files/FWO.Test/ReportBaseTest.cs new file mode 100644 index 0000000000..85d95af59c --- /dev/null +++ b/roles/tests-unit/files/FWO.Test/ReportBaseTest.cs @@ -0,0 +1,95 @@ +using FWO.Api.Client; +using FWO.Basics; +using FWO.Config.Api; +using FWO.Data.Report; +using FWO.Report; +using FWO.Report.Filter; +using NUnit.Framework; + +namespace FWO.Test +{ + [TestFixture] + [Parallelizable] + public class ReportBaseTest + { + private sealed class TestReportBase() : ReportBase(new DynGraphqlQuery(""), new SimulatedUserConfig(), ReportType.TicketReport) + { + public static string OutputCsvPublic(string? input) + { + return OutputCsv(input); + } + + public override Task Generate(int elementsPerFetch, ApiConnection apiConnection, Func callback, CancellationToken ct) + { + return Task.CompletedTask; + } + + public override string ExportToCsv() + { + return string.Empty; + } + + public override string ExportToJson() + { + return string.Empty; + } + + public override string ExportToHtml() + { + return string.Empty; + } + + public override string SetDescription() + { + return string.Empty; + } + } + + [Test] + public void OutputCsvEscapesQuotesAndNull() + { + Assert.That(TestReportBase.OutputCsvPublic("a\"b"), Is.EqualTo("\"a\"\"b\",")); + Assert.That(TestReportBase.OutputCsvPublic(null), Is.EqualTo("\"\",")); + } + + [Test] + public void GetLinkAddressUsesReportPrefixForNonChangeReports() + { + string link = ReportBase.GetLinkAddress(OutputLocation.report, "rep42", "rule", 3, 99, ReportType.Rules); + + Assert.That(link, Is.EqualTo($"{PageName.ReportGeneration}#goto-report-rep42-rule3x99")); + } + + [Test] + public void GetLinkAddressUsesAllPrefixForChangeReports() + { + string link = ReportBase.GetLinkAddress(OutputLocation.report, "rep42", "rule", 3, 99, ReportType.Changes); + + Assert.That(link, Is.EqualTo($"{PageName.ReportGeneration}#goto-all-rep42-rule3x99")); + } + + [Test] + public void GetLinkAddressUsesCertificationPageOutsideReportLocation() + { + string link = ReportBase.GetLinkAddress(OutputLocation.certification, "rep42", "svc", 1, 5, ReportType.Rules); + + Assert.That(link, Is.EqualTo($"{PageName.Certification}#goto-report-rep42-svc1x5")); + } + + [Test] + public void GetLinkAddressUsesHashOnlyForExportLocation() + { + string link = ReportBase.GetLinkAddress(OutputLocation.export, "rep42", "nwobj", 2, 7, ReportType.Changes); + + Assert.That(link, Is.EqualTo("#nwobj2x7")); + } + + [Test] + public void ConstructLinkBuildsExpectedAnchorHtml() + { + string link = ReportBase.ConstructLink("icon-test", "Test Name", "color:red;", "#dest"); + + Assert.That(link, Is.EqualTo(" Test Name")); + } + } +} diff --git a/roles/tests-unit/files/FWO.Test/ReportComplianceTest.cs b/roles/tests-unit/files/FWO.Test/ReportComplianceTest.cs new file mode 100644 index 0000000000..2827a8667e --- /dev/null +++ b/roles/tests-unit/files/FWO.Test/ReportComplianceTest.cs @@ -0,0 +1,286 @@ +using FWO.Config.Api; +using FWO.Data; +using FWO.Report.Data.ViewData; +using FWO.Test.Mocks; +using FWO.Api.Client.Queries; +using NUnit.Framework; + +namespace FWO.Test +{ + [TestFixture] + internal class ReportComplianceTest + { + private MockReportCompliance _complianceReport => new(new(""), new(), Basics.ReportType.ComplianceReport); + private MockReportCompliance _testReport = default!; + private MockReportComplianceDiff _testDiffReport = default!; + + + [SetUp] + public void SetUpTest() + { + _testReport = _complianceReport; + SimulatedGlobalConfig globalConfig = new(); + globalConfig.ComplianceCheckMaxPrintedViolations = 2; + UserConfig userConfig = new(globalConfig); + + _testDiffReport = new(new(""), userConfig, Basics.ReportType.ComplianceDiffReport); + ; + _testDiffReport.MockPostProcessDiffReportsRule = true; + } + + [Test] + public async Task ProcessChunksParallelized_BigDataSet_EvaluatesAllRules() + { + // ARRANGE + + CancellationToken ct = default; + int numberOfChunks = 100; + int numberOfRulesPerChunk = 100; + int ruleId = 1; + + List[] ruleChunks = BuildFixedRuleChunksParallel(numberOfChunks, numberOfRulesPerChunk, ruleId); + + // ACT + + List testResults = await _testReport.ProcessChunksParallelized(ruleChunks, ct, new SimulatedApiConnection()); + + // ASSERT + + Assert.That(testResults.Count == _testReport.RuleViewData.Count, $"Rules: {testResults.Count} - RuleViewData: {_testReport.RuleViewData.Count}"); + + } + + [Test] + public async Task ProcessChunksParallelized_DiffReport_CreatesCorrectDiffs() + { + // ARRANGE + + CancellationToken ct = default; + DateTime foundDate = DateTime.Now; + + _testDiffReport.DiffReferenceInDays = 7; + + Rule notAssessable = new() + { + Id = 1, + Name = "Testrule 1", + Violations = [ + CreateMockComplianceViolation(1,1, foundDate, criterion: + + new() + { + CriterionType = nameof(ComplianceViolationType.NotAssessable) + }, + type: ComplianceViolationType.NotAssessable + + ), + CreateMockComplianceViolation(2,2, foundDate, type: ComplianceViolationType.MatrixViolation) + ] + }; + + Rule abbreviated = new() + { + Id = 2, + Name = "Testrule 2", + Violations = [ + CreateMockComplianceViolation(3,2, foundDate, type: ComplianceViolationType.MatrixViolation), + CreateMockComplianceViolation(4,2, foundDate, type: ComplianceViolationType.MatrixViolation), + CreateMockComplianceViolation(5,2, foundDate, type: ComplianceViolationType.MatrixViolation) + ] + }; + + Rule multiple = new() + { + Id = 3, + Name = "Testrule 3", + Violations = [ + CreateMockComplianceViolation(6,3, foundDate, type: ComplianceViolationType.MatrixViolation), + CreateMockComplianceViolation(7,3, foundDate, type: ComplianceViolationType.ServiceViolation) + ] + }; + + Rule singular = new() + { + Id = 4, + Name = "Testrule 4", + Violations = [ + CreateMockComplianceViolation(8,4, foundDate, criterion: + + new() + { + CriterionType = nameof(ComplianceViolationType.ServiceViolation) + }, + type: ComplianceViolationType.ServiceViolation + + ) + ] + }; + + List[] ruleChunks = + [ + new List(){ notAssessable }, + new List(){ abbreviated }, + new List(){ multiple }, + new List(){ singular } + ]; + + string controlNotAssessable = CreateViolationDetailsControlString(foundDate, 1); + string controlAbbreviated = CreateViolationDetailsControlString(foundDate, 3) + "
                      " + CreateViolationDetailsControlString(foundDate, 4) + "
                      Too many violations to display (3), please check the system for details."; + string controlMultiple = CreateViolationDetailsControlString(foundDate, 6) + "
                      " + CreateViolationDetailsControlString(foundDate, 7); + string controlSingular = CreateViolationDetailsControlString(foundDate, 8); + + // ACT + + List testResults = await _testDiffReport.ProcessChunksParallelized(ruleChunks, ct, new SimulatedApiConnection()); + + // ASSERT + + Assert.That(testResults.Count == 4); + Assert.That(notAssessable.ViolationDetails == controlNotAssessable); + Assert.That(notAssessable.Compliance == ComplianceViolationType.NotAssessable); + Assert.That(abbreviated.ViolationDetails == controlAbbreviated); + Assert.That(multiple.ViolationDetails == controlMultiple); + Assert.That(multiple.Compliance == ComplianceViolationType.MultipleViolations); + Assert.That(singular.ViolationDetails == controlSingular); + Assert.That(singular.Compliance == ComplianceViolationType.ServiceViolation); + } + + [Test] + public void CreateQueryVariables_UsesConfiguredRelevantManagementIds() + { + SimulatedGlobalConfig globalConfig = new() + { + ComplianceCheckRelevantManagements = "9,10" + }; + UserConfig userConfig = new(globalConfig); + MockReportCompliance report = new(new(""), userConfig, Basics.ReportType.ComplianceReport); + + Dictionary queryVariables = report.CreateQueryVariablesPublic(0, 100, RuleQueries.getRulesWithCurrentViolationsByChunk); + + Assert.That(queryVariables.ContainsKey("mgm_ids"), Is.True); + Assert.That((List)queryVariables["mgm_ids"], Is.EqualTo(new List { 9, 10 })); + } + + [Test] + public void CreateQueryVariables_UsesLoadedManagementIdsWhenNoConfiguredFilter() + { + MockReportCompliance report = new(new(""), new(), Basics.ReportType.ComplianceReport) + { + Managements = + [ + new Management { Id = 3 }, + new Management { Id = 4 } + ] + }; + + Dictionary queryVariables = report.CreateQueryVariablesPublic(0, 100, RuleQueries.getRulesWithCurrentViolationsByChunk); + + Assert.That(queryVariables.ContainsKey("mgm_ids"), Is.True); + Assert.That((List)queryVariables["mgm_ids"], Is.EqualTo(new List { 3, 4 })); + } + + [Test] + public void ExportToCsv_IncludesExpirationTimeColumnAndValue() + { + MockReportCompliance report = new(new(""), new(), Basics.ReportType.ComplianceReport); + report.RuleViewData = + [ + new RuleViewData + { + MgmtId = "1", + MgmtName = "Mgmt", + Uid = "uid-1", + Name = "Rule 1", + Source = "src", + SourceShort = "src-short", + Destination = "dst", + DestinationShort = "dst-short", + Services = "svc", + ServicesShort = "svc-short", + Action = "accept", + InstallOn = "fw1", + Compliance = "FALSE", + ViolationDetails = "detail", + ChangeID = "chg-1", + AdoITID = "ado-1", + Comment = "comment", + LastModified = "2026-03-24", + ExpirationTime = "2026-12-24 11:22:33", + RulebaseId = "7", + RulebaseName = "rb", + Enabled = "TRUE", + Show = true + } + ]; + + string csv = report.ExportToCsv(); + + Assert.That(csv, Does.Contain("\"ExpirationTime\"")); + Assert.That(csv, Does.Contain("\"2026-12-24 11:22:33\"")); + } + + private List[] BuildFixedRuleChunksParallel(int numberOfChunks, int numberOfRulesPerChunk, int startRuleId = 1, int? maxDegreeOfParallelism = null) + { + if (numberOfChunks <= 0) throw new ArgumentOutOfRangeException(nameof(numberOfChunks)); + if (numberOfRulesPerChunk < 0) throw new ArgumentOutOfRangeException(nameof(numberOfRulesPerChunk)); + + var ruleChunks = new List[numberOfChunks]; + + Parallel.For( + 0, numberOfChunks, + new ParallelOptions { MaxDegreeOfParallelism = maxDegreeOfParallelism ?? Environment.ProcessorCount }, + i => + { + var list = new List(numberOfRulesPerChunk); + int baseId = startRuleId + i * numberOfRulesPerChunk; + + for (int j = 0; j < numberOfRulesPerChunk; j++) + { + list.Add(new Rule { Id = baseId + j }); + } + + ruleChunks[i] = list; + }); + + return ruleChunks; + } + + private ComplianceViolation CreateMockComplianceViolation(int id = 0, int ruleId = 0, DateTime? foundDate = null, DateTime? removedDate = null, string details = "", int policyId = 0, ComplianceCriterion? criterion = null, ComplianceViolationType type = ComplianceViolationType.None) + { + if (string.IsNullOrEmpty(details)) + { + details = $"Test violation {id}"; + } + + if (criterion == null) + { + criterion = new() + { + Id = 0 + }; + } + + ComplianceViolation violation = new() + { + Id = id, + RuleId = ruleId, + FoundDate = foundDate ?? DateTime.Now, + Details = details, + RiskScore = 0, + PolicyId = policyId, + CriterionId = criterion.Id, + Criterion = criterion + }; + + violation.Type = type; + + return violation; + } + + private string CreateViolationDetailsControlString(DateTime foundDate, int violationId) + { + return $"Found: ({foundDate:dd.MM.yyyy} - {foundDate:hh:mm}) Test violation {violationId}"; + } + + } +} diff --git a/roles/tests-unit/files/FWO.Test/ReportFiltersTest.cs b/roles/tests-unit/files/FWO.Test/ReportFiltersTest.cs new file mode 100644 index 0000000000..af40e39f99 --- /dev/null +++ b/roles/tests-unit/files/FWO.Test/ReportFiltersTest.cs @@ -0,0 +1,465 @@ +using FWO.Basics; +using FWO.Config.Api; +using FWO.Data; +using FWO.Data.Report; +using FWO.Data.Workflow; +using FWO.Report.Filter.FilterTypes; +using NUnit.Framework; +using NUnit.Framework.Legacy; + +namespace FWO.Test +{ + [TestFixture] + [Parallelizable] + internal class ReportFiltersTest + { + [Test] + public void ToReportParams_CopiesWorkflowFilter_ForTicketChangeReport() + { + ReportFilters filters = new() + { + ReportType = ReportType.TicketChangeReport, + WorkflowFilter = new() + { + ReferenceDate = WorkflowReferenceDate.TaskEnd, + TaskTypes = [WfTaskType.access, WfTaskType.rule_modify], + StateIds = [3, 7], + Phase = "implementation", + LabelFilter = new() { Name = "policy_check", Mode = WorkflowLabelFilterMode.value, Value = "true" }, + DetailedView = true, + ShowFullTicket = false + } + }; + + var reportParams = filters.ToReportParams(); + + Assert.That(reportParams.WorkflowFilter.ReferenceDate, Is.EqualTo(WorkflowReferenceDate.TaskEnd)); + Assert.That(reportParams.WorkflowFilter.TaskTypes, Is.EqualTo(new List { WfTaskType.access, WfTaskType.rule_modify })); + Assert.That(reportParams.WorkflowFilter.StateIds, Is.EqualTo(new List { 3, 7 })); + Assert.That(reportParams.WorkflowFilter.Phase, Is.EqualTo("implementation")); + Assert.That(reportParams.WorkflowFilter.LabelFilter.Name, Is.EqualTo("policy_check")); + Assert.That(reportParams.WorkflowFilter.LabelFilter.Mode, Is.EqualTo(WorkflowLabelFilterMode.value)); + Assert.That(reportParams.WorkflowFilter.LabelFilter.Value, Is.EqualTo("true")); + Assert.That(reportParams.WorkflowFilter.DetailedView, Is.True); + Assert.That(reportParams.WorkflowFilter.ShowFullTicket, Is.False); + } + + [Test] + public void Init_SetsDefaultsAndCollapsesWhenDeviceCountExceedsThreshold() + { + SimulatedUserConfig userConfig = new(); + userConfig.MinCollapseAllDevices = 1; + ReportFilters filters = new(); + filters.DeviceFilter = new DeviceFilter( + [ + new ManagementSelect { Id = 1 }, + new ManagementSelect { Id = 2 } + ]); + + filters.Init(userConfig, showRuleRelatedReports: false); + + Assert.That(filters.ReportType, Is.EqualTo(ReportType.Connections)); + Assert.That(filters.DisplayedTimeSelection, Is.EqualTo("now")); + Assert.That(filters.UnusedDays, Is.EqualTo(userConfig.UnusedTolerance)); + Assert.That(filters.CollapseDevices, Is.True); + } + + [Test] + public void SyncFiltersFromTemplate_CopiesWorkflowFilter_ForTicketChangeReport() + { + ReportFilters filters = new(); + var template = new FWO.Data.Report.ReportTemplate("", new FWO.Data.Report.ReportParams()) + { + ReportParams = + { + ReportType = (int)ReportType.TicketChangeReport, + WorkflowFilter = new() + { + ReferenceDate = WorkflowReferenceDate.Approved, + TaskTypes = [WfTaskType.access, WfTaskType.rule_delete], + StateIds = [9], + Phase = "review", + LabelFilter = new() { Name = "policy_check", Mode = WorkflowLabelFilterMode.not_existing }, + DetailedView = true, + ShowFullTicket = false + }, + IncludeObjects = true + } + }; + + filters.SyncFiltersFromTemplate(template); + + Assert.That(filters.ReportType, Is.EqualTo(ReportType.TicketChangeReport)); + Assert.That(filters.WorkflowFilter.ReferenceDate, Is.EqualTo(WorkflowReferenceDate.Approved)); + Assert.That(filters.WorkflowFilter.TaskTypes, Is.EqualTo(new List { WfTaskType.access, WfTaskType.rule_delete })); + Assert.That(filters.WorkflowFilter.StateIds, Is.EqualTo(new List { 9 })); + Assert.That(filters.WorkflowFilter.Phase, Is.EqualTo("review")); + Assert.That(filters.WorkflowFilter.LabelFilter.Name, Is.EqualTo("policy_check")); + Assert.That(filters.WorkflowFilter.LabelFilter.Mode, Is.EqualTo(WorkflowLabelFilterMode.not_existing)); + Assert.That(filters.WorkflowFilter.LabelFilter.Value, Is.EqualTo(string.Empty)); + Assert.That(filters.WorkflowFilter.DetailedView, Is.True); + Assert.That(filters.WorkflowFilter.ShowFullTicket, Is.False); + Assert.That(filters.IncludeObjects, Is.True); + } + + [Test] + public void ToReportParams_CopiesIncludeObjectChangesSettings_ForChangesReport() + { + ReportFilters filters = new() + { + ReportType = ReportType.Changes, + IncludeObjects = true + }; + + ReportParams reportParams = filters.ToReportParams(); + + Assert.That(reportParams.IncludeObjects, Is.True); + } + + [Test] + public void Init_CopiesGlobalDefaultForIncludeObjectChanges() + { + SimulatedGlobalConfig globalConfig = new() { ImpChangeIncludeObjectChanges = true }; + UserConfig userConfig = new(globalConfig, registerOnChangeHandler: false); + ReportFilters filters = new(); + + filters.Init(userConfig, true); + + Assert.That(filters.IncludeObjects, Is.True); + } + + [Test] + public void SyncFiltersFromTemplate_CopiesDeviceFilterAndUpdatesSelectAll() + { + ReportFilters filters = new() + { + DeviceFilter = new DeviceFilter( + [ + new ManagementSelect + { + Id = 7, + Devices = [new DeviceSelect { Id = 70, Name = "gw70" }] + } + ]) + }; + SimulatedUserConfig userConfig = new(); + filters.Init(userConfig, true); + var template = new FWO.Data.Report.ReportTemplate("", new FWO.Data.Report.ReportParams()) + { + ReportParams = + { + ReportType = (int)ReportType.Rules, + DeviceFilter = new DeviceFilter( + [ + new ManagementSelect + { + Id = 7, + Selected = true, + Devices = [new DeviceSelect { Id = 70, Name = "gw70", Selected = true }] + } + ]) + } + }; + + filters.SyncFiltersFromTemplate(template); + + Assert.That(filters.DeviceFilter.Managements[0].Selected, Is.True); + Assert.That(filters.DeviceFilter.Managements[0].Devices[0].Selected, Is.True); + Assert.That(filters.SelectAll, Is.False); + } + + [Test] + public void ToReportParams_UsesReducedDeviceFilterForUnusedRulesAndCopiesCreationTolerance() + { + SimulatedUserConfig userConfig = new(); + ReportFilters filters = new(); + filters.Init(userConfig, true); + filters.ReportType = ReportType.UnusedRules; + filters.ReducedDeviceFilter = new DeviceFilter( + [ + new ManagementSelect + { + Id = 7, + Devices = [new DeviceSelect { Id = 70, Name = "gw70", Selected = true }] + } + ]); + filters.UnusedDays = 21; + + ReportParams reportParams = filters.ToReportParams(); + + Assert.That(reportParams.DeviceFilter.Managements, Has.Count.EqualTo(1)); + Assert.That(reportParams.DeviceFilter.Managements[0].Id, Is.EqualTo(7)); + Assert.That(reportParams.UnusedFilter.UnusedForDays, Is.EqualTo(21)); + Assert.That(reportParams.UnusedFilter.CreationTolerance, Is.EqualTo(userConfig.CreationTolerance)); + } + + [Test] + public void ToReportParams_UsesTenantFromUserWhenNoTenantSelected() + { + SimulatedUserConfig userConfig = new(); + userConfig.User.Tenant = new Tenant { Id = 4 }; + ReportFilters filters = new() + { + ReportType = ReportType.Rules + }; + filters.Init(userConfig, true); + + ReportParams reportParams = filters.ToReportParams(); + + Assert.That(reportParams.TenantFilter.IsActive, Is.True); + Assert.That(reportParams.TenantFilter.TenantId, Is.EqualTo(4)); + } + + [Test] + public void ToReportParams_CopiesOwnerFilter_ForOwnersReport() + { + ReportFilters filters = new() + { + ReportType = ReportType.Owners, + OwnerFilter = new OwnerFilter + { + SelectedOwnerLifeCycleStateId = 3, + SelectedCriticality = "High" + } + }; + + ReportParams reportParams = filters.ToReportParams(); + + Assert.That(reportParams.OwnerFilter.SelectedOwnerLifeCycleStateId, Is.EqualTo(3)); + Assert.That(reportParams.OwnerFilter.SelectedCriticality, Is.EqualTo("High")); + Assert.That(ReferenceEquals(reportParams.OwnerFilter, filters.OwnerFilter), Is.False); + } + + [Test] + public void SyncFiltersFromTemplate_CopiesOwnerFilter_ForOwnersReport() + { + ReportFilters filters = new(); + var template = new FWO.Data.Report.ReportTemplate("", new FWO.Data.Report.ReportParams()) + { + ReportParams = + { + ReportType = (int)ReportType.Owners, + OwnerFilter = new OwnerFilter + { + SelectedOwnerLifeCycleStateId = 5, + SelectedCriticality = "Medium" + } + } + }; + + filters.SyncFiltersFromTemplate(template); + + Assert.That(filters.ReportType, Is.EqualTo(ReportType.Owners)); + Assert.That(filters.OwnerFilter.SelectedOwnerLifeCycleStateId, Is.EqualTo(5)); + Assert.That(filters.OwnerFilter.SelectedCriticality, Is.EqualTo("Medium")); + Assert.That(ReferenceEquals(filters.OwnerFilter, template.ReportParams.OwnerFilter), Is.False); + } + + [Test] + public void ToReportParams_PreservesExplicitTemplateOwner_ForAppRules() + { + ReportFilters filters = new() + { + ReportType = ReportType.AppRules + }; + filters.ModellingFilter.SelectedOwner = new FwoOwner { Id = 17, Name = "App A" }; + filters.ModellingFilter.SelectedTemplateOwner = new FwoOwner { Id = 23, Name = "Template App" }; + + ReportParams reportParams = filters.ToReportParams(); + + Assert.That(reportParams.ModellingFilter.SelectedOwner.Id, Is.EqualTo(17)); + Assert.That(reportParams.ModellingFilter.SelectedTemplateOwner.Id, Is.EqualTo(23)); + Assert.That(reportParams.ModellingFilter.SelectedTemplateOwner.Name, Is.EqualTo("Template App")); + } + + [Test] + public void ToReportParams_CopiesVarianceFlags() + { + ReportFilters filters = new() + { + ReportType = ReportType.VarianceAnalysis + }; + filters.ModellingFilter.RulesForDeletedConns = true; + filters.ModellingFilter.AnalyseRemainingRules = true; + + ReportParams reportParams = filters.ToReportParams(); + + Assert.That(reportParams.ModellingFilter.RulesForDeletedConns, Is.True); + Assert.That(reportParams.ModellingFilter.AnalyseRemainingRules, Is.True); + } + + [Test] + public void SetDisplayedTimeSelection_ForTicketChangeReportOpenEnd_UsesFromText() + { + SimulatedUserConfig userConfig = new(); + ReportFilters filters = new(); + filters.Init(userConfig, true); + filters.ReportType = ReportType.TicketChangeReport; + filters.TimeFilter = new() + { + TimeRangeType = TimeRangeType.Fixeddates, + OpenEnd = true, + StartTime = new DateTime(2025, 1, 2, 3, 4, 5) + }; + + filters.SetDisplayedTimeSelection(); + + StringAssert.StartsWith("from ", filters.DisplayedTimeSelection); + StringAssert.Contains(filters.TimeFilter.StartTime.ToString(), filters.DisplayedTimeSelection); + } + + [Test] + public void SetDisplayedTimeSelection_ForChangeReportShortcut_UsesTranslatedShortcut() + { + SimulatedUserConfig userConfig = new(); + ReportFilters filters = new(); + filters.Init(userConfig, true); + filters.ReportType = ReportType.Changes; + filters.TimeFilter = new() + { + TimeRangeType = TimeRangeType.Shortcut, + TimeRangeShortcut = "today" + }; + + filters.SetDisplayedTimeSelection(); + + Assert.That(filters.DisplayedTimeSelection, Is.EqualTo("today")); + } + + [Test] + public void SetDisplayedTimeSelection_ForNonChangeShortcut_UsesTranslatedShortcut() + { + SimulatedUserConfig userConfig = new(); + ReportFilters filters = new(); + filters.Init(userConfig, true); + filters.ReportType = ReportType.Rules; + filters.TimeFilter = new() + { + IsShortcut = true, + TimeShortcut = "now" + }; + + filters.SetDisplayedTimeSelection(); + + Assert.That(filters.DisplayedTimeSelection, Is.EqualTo("now")); + } + + [Test] + public void SetDisplayedTimeSelection_ForNonChangeFixedTime_UsesReportTime() + { + SimulatedUserConfig userConfig = new(); + ReportFilters filters = new(); + filters.Init(userConfig, true); + filters.ReportType = ReportType.Rules; + filters.TimeFilter = new() + { + IsShortcut = false, + ReportTime = new DateTime(2025, 1, 2, 3, 4, 5) + }; + + filters.SetDisplayedTimeSelection(); + + Assert.That(filters.DisplayedTimeSelection, Is.EqualTo(filters.TimeFilter.ReportTime.ToString())); + } + + [Test] + public void TenantViewChanged_WithTenantZero_MarksAllDevicesVisible() + { + ReportFilters filters = new() + { + DeviceFilter = new DeviceFilter( + [ + new ManagementSelect + { + Id = 7, + Visible = false, + Shared = true, + Devices = + [ + new DeviceSelect { Id = 70, Name = "gw70", Visible = false, Shared = true }, + new DeviceSelect { Id = 71, Name = "gw71", Visible = false, Shared = true } + ] + } + ]) + }; + + filters.TenantViewChanged(new Tenant { Id = 1 }); + + Assert.That(filters.DeviceFilter.Managements[0].Visible, Is.True); + Assert.That(filters.DeviceFilter.Managements[0].Shared, Is.False); + Assert.That(filters.DeviceFilter.Managements[0].Devices.All(device => device.Visible && !device.Shared), Is.True); + Assert.That(filters.SelectAll, Is.True); + } + + [Test] + public void TenantViewChanged_WithRestrictedTenant_HidesUnlistedDevicesAndClearsSelection() + { + ReportFilters filters = new() + { + DeviceFilter = new DeviceFilter( + [ + new ManagementSelect + { + Id = 7, + Selected = true, + Devices = + [ + new DeviceSelect { Id = 70, Name = "gw70", Selected = true }, + new DeviceSelect { Id = 71, Name = "gw71", Selected = true } + ] + } + ]) + }; + + filters.TenantViewChanged(new Tenant + { + Id = 2, + VisibleGatewayIds = [70] + }); + + Assert.That(filters.DeviceFilter.Managements[0].Visible, Is.True); + Assert.That(filters.DeviceFilter.Managements[0].Shared, Is.True); + Assert.That(filters.DeviceFilter.Managements[0].Devices[0].Visible, Is.True); + Assert.That(filters.DeviceFilter.Managements[0].Devices[1].Visible, Is.False); + Assert.That(filters.DeviceFilter.Managements[0].Devices[1].Selected, Is.False); + } + + [Test] + public void DeviceFilter_ListAllSelectedManagements_ReturnsSelectedManagementNames() + { + DeviceFilter deviceFilter = new( + [ + new ManagementSelect + { + Id = 7, + Name = "Mgmt A", + Devices = + [ + new DeviceSelect { Id = 70, Name = "gw70", Selected = true }, + new DeviceSelect { Id = 71, Name = "gw71", Selected = false } + ] + }, + new ManagementSelect + { + Id = 8, + Name = "Mgmt B", + Devices = + [ + new DeviceSelect { Id = 80, Name = "gw80", Selected = true } + ] + }, + new ManagementSelect + { + Id = 9, + Name = "Mgmt C", + Devices = + [ + new DeviceSelect { Id = 90, Name = "gw90", Selected = false } + ] + } + ]); + + Assert.That(deviceFilter.ListAllSelectedManagements(), Is.EqualTo("Mgmt A, Mgmt B")); + } + } +} diff --git a/roles/tests-unit/files/FWO.Test/ReportJobTest.cs b/roles/tests-unit/files/FWO.Test/ReportJobTest.cs new file mode 100644 index 0000000000..a1de70baf4 --- /dev/null +++ b/roles/tests-unit/files/FWO.Test/ReportJobTest.cs @@ -0,0 +1,350 @@ +using FWO.Api.Client; +using FWO.Api.Client.Queries; +using FWO.Basics; +using FWO.Config.Api; +using FWO.Data; +using FWO.Data.Report; +using FWO.Middleware.Server; +using FWO.Middleware.Server.Jobs; +using FWO.Report; +using FWO.Report.Filter; +using Microsoft.IdentityModel.Tokens; +using NUnit.Framework; +using NUnit.Framework.Legacy; +using System.Reflection; +using System.Security.Cryptography; + +namespace FWO.Test +{ + [TestFixture] + [NonParallelizable] + internal class ReportJobTest + { + private object? originalConfigFileData; + + private sealed class ReportJobApiConnection : ApiConnection + { + internal string? LastQuery { get; private set; } + internal object? LastVariables { get; private set; } + internal int GetDevicesByManagementCalls { get; private set; } + + public override void SetAuthHeader(string jwt) { } + public override void SetRole(string role) { } + public override void SetBestRole(System.Security.Claims.ClaimsPrincipal user, List targetRoleList) { } + public override void SetProperRole(System.Security.Claims.ClaimsPrincipal user, List targetRoleList) { } + public override void SwitchBack() { } + + public override Task> SendQuerySafeAsync(string query, object? variables = null, string? operationName = null) + { + throw new NotImplementedException(); + } + + public override Task SendQueryAsync(string query, object? variables = null, string? operationName = null) + { + LastQuery = query; + LastVariables = variables; + if (typeof(QueryResponseType) == typeof(List) && query == DeviceQueries.getDevicesByManagement) + { + GetDevicesByManagementCalls++; + return Task.FromResult((QueryResponseType)(object)new List + { + new() + { + Id = 1, + Name = "mgmt-1", + Visible = true, + Devices = + [ + new() { Id = 11, Name = "dev-1", Visible = true }, + new() { Id = 12, Name = "dev-2", Visible = true } + ] + } + }); + } + if (typeof(QueryResponseType) == typeof(object) && query == ReportQueries.addGeneratedReport) + { + return Task.FromResult((QueryResponseType)(object)new object()); + } + throw new NotImplementedException(); + } + + public override GraphQlApiSubscription GetSubscription(Action exceptionHandler, GraphQlApiSubscription.SubscriptionUpdate subscriptionUpdateHandler, string subscription, object? variables = null, string? operationName = null) + { + throw new NotImplementedException(); + } + + public override void DisposeSubscriptions() { } + protected override void Dispose(bool disposing) { } + } + + [SetUp] + public void SetUp() + { + originalConfigFileData = typeof(FWO.Config.File.ConfigFile) + .GetProperty("Data", BindingFlags.Static | BindingFlags.NonPublic)! + .GetValue(null); + } + + [TearDown] + public void TearDown() + { + typeof(FWO.Config.File.ConfigFile) + .GetProperty("Data", BindingFlags.Static | BindingFlags.NonPublic)! + .SetValue(null, originalConfigFileData); + } + + private static MethodInfo GetPrivateStaticMethod(string name) + { + return typeof(ReportJob).GetMethod(name, BindingFlags.NonPublic | BindingFlags.Static) + ?? throw new MissingMethodException(typeof(ReportJob).FullName, name); + } + + private static MethodInfo GetPrivateInstanceMethod(string name) + { + return typeof(ReportJob).GetMethod(name, BindingFlags.NonPublic | BindingFlags.Instance) + ?? throw new MissingMethodException(typeof(ReportJob).FullName, name); + } + + private static ReportJob CreateReportJob(ApiConnection? apiConnection = null) + { + SetApiServerUri("http://unit-test"); + return new ReportJob(apiConnection ?? new ReportJobApiConnection(), new JwtWriter(new RsaSecurityKey(RSA.Create()))); + } + + private static void SetApiServerUri(string apiServerUri) + { + Type configFileType = typeof(FWO.Config.File.ConfigFile); + Type? configFileDataType = configFileType.GetNestedType("ConfigFileData", BindingFlags.NonPublic); + object configData = Activator.CreateInstance(configFileDataType ?? throw new MissingMemberException(configFileType.FullName, "ConfigFileData")) + ?? throw new InvalidOperationException("Could not create config file data."); + configFileDataType.GetProperty("ApiServerUri", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)! + .SetValue(configData, apiServerUri); + configFileType.GetProperty("Data", BindingFlags.Static | BindingFlags.NonPublic)! + .SetValue(null, configData); + } + + [Test] + public void RoundDown_RoundsToMinuteBoundary() + { + MethodInfo roundDown = GetPrivateStaticMethod("RoundDown"); + DateTime input = new(2026, 3, 27, 10, 15, 42, 987, DateTimeKind.Utc); + + DateTime rounded = (DateTime)roundDown.Invoke(null, [input, TimeSpan.FromMinutes(1)])!; + + ClassicAssert.AreEqual(new DateTime(2026, 3, 27, 10, 15, 0, DateTimeKind.Utc), rounded); + } + + [Test] + public async Task WriteReportFile_CsvCapableReport_WritesRequestedFormats() + { + MethodInfo writeReportFile = GetPrivateStaticMethod("WriteReportFile"); + TestReport report = new(ReportType.TicketChangeReport, detailedView: false); + ReportFile reportFile = new(); + List fileFormats = + [ + new() { Name = GlobalConst.kCsv }, + new() { Name = GlobalConst.kHtml }, + new() { Name = GlobalConst.kPdf }, + new() { Name = GlobalConst.kJson } + ]; + + await (Task)writeReportFile.Invoke(null, [report, fileFormats, reportFile])!; + + ClassicAssert.AreEqual("json-content", reportFile.Json); + ClassicAssert.AreEqual("csv-content", reportFile.Csv); + ClassicAssert.AreEqual("html-content", reportFile.Html); + ClassicAssert.AreEqual("pdf-content", reportFile.Pdf); + Assert.That(report.PdfInputs, Has.Count.EqualTo(1)); + ClassicAssert.AreEqual("html-content", report.PdfInputs[0]); + Assert.That(reportFile.GenerationDateEnd, Is.Not.EqualTo(default(DateTime))); + } + + [Test] + public async Task WriteReportFile_DetailedWorkflowReport_SkipsCsvExport() + { + MethodInfo writeReportFile = GetPrivateStaticMethod("WriteReportFile"); + TestReport report = new(ReportType.TicketChangeReport, detailedView: true); + ReportFile reportFile = new(); + List fileFormats = + [ + new() { Name = GlobalConst.kCsv }, + new() { Name = GlobalConst.kJson } + ]; + + await (Task)writeReportFile.Invoke(null, [report, fileFormats, reportFile])!; + + ClassicAssert.AreEqual("json-content", reportFile.Json); + ClassicAssert.IsTrue(string.IsNullOrEmpty(reportFile.Csv)); + Assert.That(report.PdfInputs, Is.Empty); + } + + [Test] + public void WriteReportFile_UnsupportedFormat_Throws() + { + MethodInfo writeReportFile = GetPrivateStaticMethod("WriteReportFile"); + TestReport report = new(ReportType.TicketChangeReport, detailedView: false); + ReportFile reportFile = new(); + + Assert.ThrowsAsync(async () => + await (Task)writeReportFile.Invoke(null, [report, new List { new() { Name = "xml" } }, reportFile])!); + } + + [Test] + public async Task AdaptDeviceFilter_WithoutSelectedDevices_SelectsAllLoadedDevices() + { + MethodInfo adaptDeviceFilter = GetPrivateStaticMethod("AdaptDeviceFilter"); + ReportParams reportParams = new() { ReportType = (int)ReportType.Rules }; + ReportJobApiConnection apiConnection = new(); + + await (Task)adaptDeviceFilter.Invoke(null, [reportParams, apiConnection])!; + + Assert.That(apiConnection.GetDevicesByManagementCalls, Is.EqualTo(1)); + Assert.That(reportParams.DeviceFilter.Managements, Has.Count.EqualTo(1)); + Assert.That(reportParams.DeviceFilter.Managements[0].Selected, Is.True); + Assert.That(reportParams.DeviceFilter.Managements[0].Devices.All(device => device.Selected), Is.True); + } + + [Test] + public async Task AdaptDeviceFilter_WithSelectedDevice_DoesNotReloadDevices() + { + MethodInfo adaptDeviceFilter = GetPrivateStaticMethod("AdaptDeviceFilter"); + ReportParams reportParams = new() + { + ReportType = (int)ReportType.Rules, + DeviceFilter = new DeviceFilter( + [ + new() + { + Id = 1, + Devices = [new() { Id = 11, Selected = true }] + } + ]) + }; + ReportJobApiConnection apiConnection = new(); + + await (Task)adaptDeviceFilter.Invoke(null, [reportParams, apiConnection])!; + + Assert.That(apiConnection.GetDevicesByManagementCalls, Is.EqualTo(0)); + Assert.That(reportParams.DeviceFilter.Managements[0].Devices[0].Selected, Is.True); + } + + [Test] + public async Task SaveReportToArchive_PersistsAllExpectedFields() + { + MethodInfo saveReportToArchive = GetPrivateStaticMethod("SaveReportToArchive"); + ReportJobApiConnection apiConnection = new(); + ReportFile reportFile = new() + { + Name = "scheduled-report", + GenerationDateStart = new DateTime(2026, 4, 21, 10, 0, 0, DateTimeKind.Utc), + GenerationDateEnd = new DateTime(2026, 4, 21, 10, 5, 0, DateTimeKind.Utc), + OwningUserId = 50, + TemplateId = 17, + Type = (int)ReportType.TicketReport, + Pdf = "pdf", + Csv = "csv", + Html = "html", + Json = "json" + }; + + await (Task)saveReportToArchive.Invoke(null, [reportFile, "description", apiConnection])!; + + Assert.That(apiConnection.LastQuery, Is.EqualTo(ReportQueries.addGeneratedReport)); + Assert.That(GetAnonymousProperty(apiConnection.LastVariables!, "report_name"), Is.EqualTo("scheduled-report")); + Assert.That(GetAnonymousProperty(apiConnection.LastVariables!, "report_owner_id"), Is.EqualTo(50)); + Assert.That(GetAnonymousProperty(apiConnection.LastVariables!, "report_template_id"), Is.EqualTo(17)); + Assert.That(GetAnonymousProperty(apiConnection.LastVariables!, "report_type"), Is.EqualTo((int)ReportType.TicketReport)); + Assert.That(GetAnonymousProperty(apiConnection.LastVariables!, "report_pdf"), Is.EqualTo("pdf")); + Assert.That(GetAnonymousProperty(apiConnection.LastVariables!, "description"), Is.EqualTo("description")); + } + + [Test] + public async Task ProcessScheduledReport_InactiveSchedule_DoesNothing() + { + MethodInfo processScheduledReport = GetPrivateInstanceMethod("ProcessScheduledReport"); + ReportJob reportJob = CreateReportJob(); + DateTime startTime = new(2026, 4, 21, 10, 0, 0); + ReportSchedule reportSchedule = new() + { + Active = false, + StartTime = startTime, + RepeatInterval = SchedulerInterval.Days, + RepeatOffset = 1 + }; + + await (Task)processScheduledReport.Invoke(reportJob, [reportSchedule, startTime.AddMinutes(5), CancellationToken.None])!; + + Assert.That(reportSchedule.StartTime, Is.EqualTo(startTime)); + } + + [Test] + public async Task ProcessScheduledReport_OverdueSchedule_AdvancesToNextFutureRun() + { + MethodInfo processScheduledReport = GetPrivateInstanceMethod("ProcessScheduledReport"); + ReportJob reportJob = CreateReportJob(); + ReportSchedule reportSchedule = new() + { + Active = true, + StartTime = new DateTime(2026, 4, 18, 10, 0, 0), + RepeatInterval = SchedulerInterval.Days, + RepeatOffset = 2 + }; + DateTime currentTimeRounded = new(2026, 4, 21, 10, 5, 0); + + await (Task)processScheduledReport.Invoke(reportJob, [reportSchedule, currentTimeRounded, CancellationToken.None])!; + + Assert.That(reportSchedule.StartTime, Is.EqualTo(new DateTime(2026, 4, 22, 10, 0, 0))); + } + + private static T GetAnonymousProperty(object obj, string propertyName) + { + return (T)(obj.GetType().GetProperty(propertyName)?.GetValue(obj) + ?? throw new MissingMemberException(obj.GetType().FullName, propertyName)); + } + + private sealed class TestReport : ReportBase + { + internal List PdfInputs { get; } = []; + + internal TestReport(ReportType reportType, bool detailedView) + : base(new DynGraphqlQuery(""), new SimulatedUserConfig(), reportType) + { + ReportData = new() + { + WorkflowFilter = new WorkflowFilter { DetailedView = detailedView } + }; + } + + public override Task Generate(int elementsPerFetch, ApiConnection apiConnection, Func callback, CancellationToken ct) + { + return Task.CompletedTask; + } + + public override string ExportToCsv() + { + return "csv-content"; + } + + public override string ExportToJson() + { + return "json-content"; + } + + public override string ExportToHtml() + { + return "html-content"; + } + + public override string SetDescription() + { + return ""; + } + + public override Task ToPdf(string html) + { + PdfInputs.Add(html); + return Task.FromResult("pdf-content"); + } + } + } +} diff --git a/roles/tests-unit/files/FWO.Test/ReportRulesTest.cs b/roles/tests-unit/files/FWO.Test/ReportRulesTest.cs new file mode 100644 index 0000000000..23c4053f79 --- /dev/null +++ b/roles/tests-unit/files/FWO.Test/ReportRulesTest.cs @@ -0,0 +1,431 @@ +using FWO.Basics; +using FWO.Data; +using FWO.Data.Report; +using FWO.Report; +using FWO.Report.Filter; +using FWO.Services.RuleTreeBuilder; +using FWO.Test.Mocks; +using NUnit.Framework; +using NUnit.Framework.Legacy; +using System.Reflection; + +namespace FWO.Test +{ + [TestFixture] + internal class ReportRulesTest + { + private List _managementReports = new(); + private DeviceReport? _deviceReport; + private ManagementReport? _managementReport; + + private RulebaseReport? _rb1; + private RulebaseReport? _rb2; + private RulebaseReport? _rb3; + + private Rule[] _rules = new Rule[0]; + + private RuleTreeBuilder _ruleTreeBuilder = new(); + + [SetUp] + public void SetUp() + { + MockReportRules.RulebaseId = 0; + MockReportRules.RuleId = 0; + + // ARRANGE ------------------------------------------------------------- + _rb1 = MockReportRules.CreateRulebaseReport("RB1", 2); + _rb2 = MockReportRules.CreateRulebaseReport("RB2", 3); + _rb3 = MockReportRules.CreateRulebaseReport("RB3", 1); + + _deviceReport = MockReportRules.CreateDeviceReport( + deviceId: 42, + deviceName: "DeviceX", + rulebaseLinks: new List + { + new RulebaseLink + { + GatewayId = 42, + IsInitial = true, + ToRulebase = new Rulebase + { + Id = _rb2.Id, + Name = _rb2.Name!, + Rules = _rb2.Rules + }, + FromRulebaseId = 0, //before + NextRulebaseId = _rb2.Id, //myself + LinkType = 2 + }, + new RulebaseLink + { + GatewayId = 42, + IsInitial = false, + ToRulebase = new Rulebase + { + Id = _rb1.Id, + Name = _rb1.Name!, + Rules = _rb1.Rules + }, + NextRulebaseId = _rb1.Id, + FromRulebaseId = _rb2.Id, + FromRuleId = 5, // Last Rule from _rb2 + IsSection = true, + LinkType = 4 + }, + new RulebaseLink + { + GatewayId = 42, + IsInitial = false, + ToRulebase = new Rulebase + { + Id = _rb3.Id, + Name = _rb3.Name!, + Rules = _rb3.Rules + }, + NextRulebaseId = _rb3.Id, + FromRulebaseId = _rb1.Id, + FromRuleId = 3, // Last Rule from _rb1 + LinkType = 2 + } + } + ); + + _managementReports = new() + { + new ManagementReport + { + Id = 1, + Name = "ManagementX", + Devices = [_deviceReport], + Rulebases = [_rb1, _rb2, _rb3] + } + }; + + _managementReport = _managementReports.First(); + + // Cache manuell fill mit der Reihenfolge: RB2 (initial) zuerst + _rules = _rb2.Rules.Concat(_rb1.Rules).Concat(_rb3.Rules).ToArray(); + typeof(ReportRules) + .GetField("_rulesCache", BindingFlags.NonPublic | BindingFlags.Static)! + .SetValue(null, new Dictionary<(int, int), Rule[]> { [(_deviceReport.Id, _managementReport.Id)] = _rules }); + + _ruleTreeBuilder.Reset(_managementReport.Rulebases, _deviceReport.RulebaseLinks); + } + + [TearDown] + public void TearDown() + { + typeof(ReportRules) + .GetField("_rulesCache", BindingFlags.NonPublic | BindingFlags.Static)! + .SetValue(null, new Dictionary<(int, int), Rule[]>()); + } + + [Test] + public void Test_SetupSingleManagementReport_CreatesDeviceWithoutRulebases() + { + Assert.That(_managementReports!.Count, Is.EqualTo(1)); + Assert.That(_managementReports[0].Devices.Count, Is.EqualTo(1)); + Assert.That(_managementReports[0].Rulebases.Count, Is.EqualTo(3)); + } + + [Test] + public void Test_CreateDeviceReport_HasConsistentId_And_Uid_For_Device1() + { + var device = MockReportRules.CreateDeviceReport(1, "Device1"); + + Assert.That(device.Id, Is.EqualTo(1)); + Assert.That(device.Uid, Is.EqualTo("device-1")); + Assert.That(device.Name, Is.EqualTo("Device1")); + } + + [Test] + public void Test_CreateDeviceReport_HasConsistentId_And_Uid_For_Device2() + { + var device = MockReportRules.CreateDeviceReport(2, "Firewall-01"); + + Assert.That(device.Id, Is.EqualTo(2)); + Assert.That(device.Uid, Is.EqualTo("device-2")); + Assert.That(device.Name, Is.EqualTo("Firewall-01")); + } + + [Test] + public void Test_RulebaseId_SetterGetter() + { + MockReportRules.RulebaseId = 10; + Assert.That(MockReportRules.RulebaseId, Is.EqualTo(10)); + + MockReportRules.RulebaseId = 20; + Assert.That(MockReportRules.RulebaseId, Is.EqualTo(20)); + } + + [Test] + public void Test_RuleId_SetterGetter() + { + MockReportRules.RuleId = 50; + Assert.That(MockReportRules.RuleId, Is.EqualTo(50)); + + MockReportRules.RuleId = 100; + Assert.That(MockReportRules.RuleId, Is.EqualTo(100)); + + var rb = MockReportRules.CreateRulebaseReport("RB101", 2); + Assert.That(rb.Rules[0].Id, Is.EqualTo(101)); + } + + [Test] + public void Test_ContainsRules_ReturnsTrue_WhenRulesExist() + { + var rulebaseReport = MockReportRules.CreateRulebaseReport(); + + var managementReport = new ManagementReport + { + Rulebases = new[] { rulebaseReport } + }; + + Assert.That(managementReport.ContainsRules(), Is.False); + Assert.That(_deviceReport!.ContainsRules(), Is.True); + Assert.That(_managementReport!.ContainsRules(), Is.True); + } + + [Test] + public void Test_GetAllRulesOfGateway_ReturnsEmpty_WhenCacheEmpty() + { + // ARRANGE + + _ruleTreeBuilder.RuleTreeCache.Clear(); + + // ACT + + var result = ReportRules.GetAllRulesOfGateway(_deviceReport!, _managementReport!, _ruleTreeBuilder); + + // ASSERT + + Assert.That(result, Is.Empty); + } + + [Test] + public void Test_CreateRulebaseReport_CreatesExpectedNumberOfRules() + { + var rulebase = _managementReport!.Rulebases.First(); + var result = ReportRules.GetRulesByRulebaseId(rulebase.Id, _managementReport); + + var rulebaseLink = new RulebaseLink { NextRulebaseId = rulebase.Id }; + int count = ReportRules.GetRuleCount(_managementReport, rulebaseLink, new[] { rulebaseLink }); + + Assert.That(count, Is.EqualTo(2)); + Assert.That(result.Length, Is.EqualTo(2)); + Assert.That(result[0].Uid, Does.StartWith($"rule-{rulebase.Id}.")); + Assert.That(rulebase.Rules.Length, Is.EqualTo(2)); + Assert.That(rulebase.Name, Is.EqualTo("RB1")); + Assert.That(rulebase.Rules[0].Name, Does.StartWith("Mock Rule")); + } + + [Test] + public void Test_MultipleRulebases_InManagementReport() + { + MockReportRules.RulebaseId = 0; + MockReportRules.RuleId = 0; + var rulebase1 = MockReportRules.CreateRulebaseReport("Rulebase1", 2); + var rulebase2 = MockReportRules.CreateRulebaseReport("Rulebase2", 3); + var managementReport = new ManagementReport + { + Rulebases = new[] { rulebase1, rulebase2 } + }; + + Assert.That(managementReport.Rulebases.Length, Is.EqualTo(2)); + Assert.That(managementReport.Rulebases[0].Rules.Length, Is.EqualTo(2)); + Assert.That(managementReport.Rulebases[1].Rules.Length, Is.EqualTo(3)); + Assert.That(managementReport.Rulebases[0].Rules[0].Name, Is.EqualTo("Mock Rule 1")); + Assert.That(managementReport.Rulebases[1].Rules[2].Name, Is.EqualTo("Mock Rule 5")); + } + + [Test] + public void Test_DeviceWithMultipleRulebaseLinks() + { + var rulebase1 = MockReportRules.CreateRulebaseReport("Rulebase1", 1); + var rulebase2 = MockReportRules.CreateRulebaseReport("Rulebase2", 2); + var device = MockReportRules.CreateDeviceReport(1, "Device1", new List + { + new RulebaseLink { NextRulebaseId = rulebase1.Id }, + new RulebaseLink { NextRulebaseId = rulebase2.Id } + }); + + Assert.That(device.RulebaseLinks.Length, Is.EqualTo(2)); + Assert.That(device.RulebaseLinks[0].NextRulebaseId, Is.EqualTo(rulebase1.Id)); + Assert.That(device.RulebaseLinks[1].NextRulebaseId, Is.EqualTo(rulebase2.Id)); + } + + [Test] + public void Test_GetAllRulesOfGateway_ReturnsRules_FromCache() + { + var device = MockReportRules.CreateDeviceReport(); + device.Id = 1; + var management = new ManagementReport(); + management.Id = 1; + var rules = new Rule[] { new Rule { Id = 1, RulebaseId = 1 } }; + + // Cache manuell setzen + typeof(ReportRules) + .GetField("_rulesCache", BindingFlags.NonPublic | BindingFlags.Static)! + .SetValue(null, new Dictionary<(int, int), Rule[]> { [(device.Id, management.Id)] = rules }); + + RuleTreeBuilder ruleTreeBuilder = new RuleTreeBuilder(); + ruleTreeBuilder.Reset(management.Rulebases, device.RulebaseLinks); + ruleTreeBuilder.RuleTreeCache[(management.Id, device.Id)] = ruleTreeBuilder.RuleTree; + ruleTreeBuilder.FlattedRules[ruleTreeBuilder.RuleTree] = rules; + + var result = ReportRules.GetAllRulesOfGateway(device, management, ruleTreeBuilder); + + Assert.That(result, Has.Length.EqualTo(1)); + Assert.That(result[0].Id, Is.EqualTo(1)); + } + + [Test] + public void Test_GetRulesByDeviceAndRulebase_WithThreeLinks_InitialSecond_ReturnsCorrectOrder() + { + // ARRANGE + + _ruleTreeBuilder.BuildRuleTree(_managementReport!.Rulebases, _deviceReport!.RulebaseLinks, _managementReport.Id, _deviceReport.Id); + + + // ACT + + var initialRules = ReportRules.GetInitialRulesOfGateway(_deviceReport!, _managementReport!); + var retrievedAllRules = ReportRules.GetAllRulesOfGateway(_deviceReport!, _managementReport!, _ruleTreeBuilder); + var retrieveRulesWithoutDummies = retrievedAllRules.Where(rule => rule.SectionHeader == "").ToArray(); // rulebases get their dummy rules to be displayable in blazor table, so we have to exclude these here + + // ASSERT + + // Initial rules correct + + ClassicAssert.AreEqual(_rb2!.Rules.Length, initialRules.Length); + ClassicAssert.IsTrue(initialRules.All(r => r.RulebaseId == _rb2!.Id)); + + // All rules of gateway correct + + ClassicAssert.AreEqual(_rules.Count(), retrieveRulesWithoutDummies.Length); + + // Order correct + + for (int i = 0; i < retrieveRulesWithoutDummies.Count(); i++) + { + if (i < _rb2.Rules.Length) + { + ClassicAssert.AreEqual(_rb2.Id, retrieveRulesWithoutDummies[i].RulebaseId); + } + else if (i < _rb2.Rules.Length + _rb1!.Rules.Length) + { + ClassicAssert.AreEqual(_rb1.Id, retrieveRulesWithoutDummies[i].RulebaseId); + } + else + { + ClassicAssert.AreEqual(_rb3!.Id, retrieveRulesWithoutDummies[i].RulebaseId); + } + } + + // Structure correct + + ClassicAssert.AreEqual(1, _managementReport!.Devices.Length); + ClassicAssert.AreEqual(3, _managementReport.Rulebases.Length); + ClassicAssert.AreEqual(_rb1!.Rules.Length + _rb2.Rules.Length + _rb3!.Rules.Length, retrieveRulesWithoutDummies.Length); + } + + [Test] + public void Test_GetInitialRulesOfGateway_ReturnsEmpty_WhenNoInitialRulebase() + { + var management = new ManagementReport(); + var device = MockReportRules.CreateDeviceReport(); + + device.GetInitialRulebaseId(management); + + var rules = ReportRules.GetInitialRulesOfGateway(device, management); + + Assert.That(rules, Is.Empty); + } + + [Test] + public void Test_CreateRuleTreeItem_BuildsValidTree() + { + var ruleTreeItemChild = MockReportRules.CreateRuleTreeItem(2, 1, new List { 1, 2 }); + var ruleTreeItemParent = MockReportRules.CreateRuleTreeItem(1, 1, new List { 1 }, new List> { ruleTreeItemChild }); + + Assert.That(ruleTreeItemParent.Children.Count, Is.EqualTo(1)); + Assert.That(ruleTreeItemParent.Children[0].Data!.Id, Is.EqualTo(2)); + Assert.That(ruleTreeItemParent.Data!.Id, Is.EqualTo(1)); + } + + [Test] + public void Test_GetRuleCount_FollowsCorrectRulebaseTraversal() + { + var count = ReportRules.GetRuleCount( + _managementReport!, + _deviceReport!.RulebaseLinks.First(l => l.IsInitial), + [.. _deviceReport!.RulebaseLinks] + ); + + ClassicAssert.AreEqual(6, count); + } + + [Test] + public void Test_TryBuildRuleTree_AccumulatesOnlyRealRulesAcrossDevices() + { + MockReportRules.RulebaseId = 0; + MockReportRules.RuleId = 0; + + RulebaseReport rulebase1 = MockReportRules.CreateRulebaseReport("RB1", 2); + RulebaseReport rulebase2 = MockReportRules.CreateRulebaseReport("RB2", 3); + RulebaseReport rulebase3 = MockReportRules.CreateRulebaseReport("RB3", 1); + + DeviceReport firstDevice = MockReportRules.CreateDeviceReport(1, "Device1", + [ + new RulebaseLink + { + GatewayId = 1, + IsInitial = true, + ToRulebase = new Rulebase { Id = (long)rulebase2.Id, Name = rulebase2.Name!, Rules = rulebase2.Rules }, + FromRulebaseId = 0, + NextRulebaseId = rulebase2.Id, + LinkType = 2 + }, + new RulebaseLink + { + GatewayId = 1, + IsInitial = false, + ToRulebase = new Rulebase { Id = (long)rulebase1.Id, Name = rulebase1.Name!, Rules = rulebase1.Rules }, + FromRulebaseId = rulebase2.Id, + NextRulebaseId = rulebase1.Id, + FromRuleId = (int)rulebase2.Rules.Last().Id, + IsSection = true, + LinkType = 4 + } + ]); + + DeviceReport secondDevice = MockReportRules.CreateDeviceReport(2, "Device2", + [ + new RulebaseLink + { + GatewayId = 2, + IsInitial = true, + ToRulebase = new Rulebase { Id = (long)rulebase3.Id, Name = rulebase3.Name!, Rules = rulebase3.Rules }, + FromRulebaseId = 0, + NextRulebaseId = rulebase3.Id, + LinkType = 2 + } + ]); + + MockReportRules reportRules = new MockReportRules(new DynGraphqlQuery(""), new SimulatedUserConfig(), ReportType.ResolvedRules, () => + [ + new ManagementReport + { + Id = 1, + Name = "Management1", + Devices = [firstDevice, secondDevice], + Rulebases = [rulebase1, rulebase2, rulebase3] + } + ]); + + reportRules.TryBuildMockRuleTree(); + + Assert.That(reportRules.ReportData.ElementsCount, Is.EqualTo(6)); + } + } +} diff --git a/roles/tests-unit/files/FWO.Test/ReportScheduleNotificationHelperTest.cs b/roles/tests-unit/files/FWO.Test/ReportScheduleNotificationHelperTest.cs new file mode 100644 index 0000000000..5af138e84a --- /dev/null +++ b/roles/tests-unit/files/FWO.Test/ReportScheduleNotificationHelperTest.cs @@ -0,0 +1,271 @@ +using FWO.Api.Client.Queries; +using FWO.Basics; +using FWO.Data; +using FWO.Data.Report; +using FWO.Ui.Services; +using NUnit.Framework; +using NUnit.Framework.Legacy; + +namespace FWO.Test +{ + [TestFixture] + [Parallelizable] + internal class ReportScheduleNotificationHelperTest + { + [Test] + public async Task CreateNotifications_MultipleFormats_AssignsSharedAttachmentBundle() + { + RecordingNotificationApiConnection apiConnection = new(); + ReportSchedule reportSchedule = NewReportSchedule(GlobalConst.kHtml, GlobalConst.kPdf); + + List createdNotifications = await ReportScheduleNotificationHelper.CreateNotifications(apiConnection, + reportSchedule, "report@example.org", "Subject", "Body"); + + ClassicAssert.AreEqual(2, createdNotifications.Count); + ClassicAssert.AreEqual(2, apiConnection.AddCalls.Count); + ClassicAssert.IsTrue(createdNotifications.All(notification => notification.BundleType == BundleType.Attachments)); + ClassicAssert.IsTrue(createdNotifications.All(notification => !string.IsNullOrWhiteSpace(notification.BundleId))); + ClassicAssert.AreEqual(createdNotifications[0].BundleId, createdNotifications[1].BundleId); + ClassicAssert.AreEqual(NotificationLayout.HtmlAsAttachment, createdNotifications[0].Layout); + ClassicAssert.AreEqual(NotificationLayout.PdfAsAttachment, createdNotifications[1].Layout); + ClassicAssert.AreEqual(createdNotifications[0].BundleId, apiConnection.AddCalls[0].BundleId); + ClassicAssert.AreEqual(createdNotifications[0].BundleId, apiConnection.AddCalls[1].BundleId); + } + + [Test] + public async Task CreateNotifications_SingleFormat_CreatesStandaloneEmailNotification() + { + RecordingNotificationApiConnection apiConnection = new(); + ReportSchedule reportSchedule = NewReportSchedule(GlobalConst.kCsv); + + List createdNotifications = await ReportScheduleNotificationHelper.CreateNotifications(apiConnection, + reportSchedule, "single@example.org", "Single Subject", "Single Body"); + + ClassicAssert.AreEqual(1, createdNotifications.Count); + ClassicAssert.AreEqual(1, apiConnection.AddCalls.Count); + ClassicAssert.IsNull(createdNotifications[0].BundleType); + ClassicAssert.IsNull(createdNotifications[0].BundleId); + ClassicAssert.AreEqual(NotificationClient.Report, createdNotifications[0].NotificationClient); + ClassicAssert.AreEqual(NotificationChannel.Email, createdNotifications[0].Channel); + ClassicAssert.AreEqual(EmailRecipientOption.OtherAddresses, createdNotifications[0].RecipientTo); + ClassicAssert.AreEqual("single@example.org", createdNotifications[0].EmailAddressTo); + ClassicAssert.AreEqual("Single Subject", createdNotifications[0].EmailSubject); + ClassicAssert.AreEqual("Single Body", createdNotifications[0].EmailBody); + ClassicAssert.AreEqual(42, createdNotifications[0].UserId); + ClassicAssert.AreEqual(NotificationLayout.CsvAsAttachment, createdNotifications[0].Layout); + ClassicAssert.AreEqual(NotificationDeadline.None, createdNotifications[0].Deadline); + ClassicAssert.AreEqual(42, apiConnection.AddCalls[0].UserId); + ClassicAssert.IsNull(apiConnection.AddCalls[0].BundleType); + ClassicAssert.IsNull(apiConnection.AddCalls[0].BundleId); + } + + [Test] + public async Task SyncNotifications_ToEmailFalse_DeletesExistingNotifications() + { + RecordingNotificationApiConnection apiConnection = new(); + ReportSchedule reportSchedule = NewReportSchedule(GlobalConst.kHtml); + reportSchedule.Notifications = + [ + NewNotification(11, NotificationLayout.HtmlAsAttachment), + NewNotification(12, NotificationLayout.PdfAsAttachment) + ]; + + List syncedNotifications = await ReportScheduleNotificationHelper.SyncNotifications(apiConnection, + reportSchedule, false, "report@example.org", "Subject", "Body"); + + ClassicAssert.AreEqual(0, syncedNotifications.Count); + CollectionAssert.AreEquivalent(new[] { 11, 12 }, apiConnection.DeletedIds); + ClassicAssert.AreEqual(0, apiConnection.AddCalls.Count); + ClassicAssert.AreEqual(0, apiConnection.UpdateCalls.Count); + } + + [Test] + public async Task SyncNotifications_ReusesBundleIdUpdatesExistingAndDeletesRemovedFormats() + { + RecordingNotificationApiConnection apiConnection = new(); + ReportSchedule reportSchedule = NewReportSchedule(GlobalConst.kHtml, GlobalConst.kCsv); + reportSchedule.Notifications = + [ + NewNotification(21, NotificationLayout.HtmlAsAttachment, "bundle-1"), + NewNotification(22, NotificationLayout.PdfAsAttachment, "bundle-1") + ]; + + List syncedNotifications = await ReportScheduleNotificationHelper.SyncNotifications(apiConnection, + reportSchedule, true, "report@example.org", "Updated Subject", "Updated Body"); + + ClassicAssert.AreEqual(2, syncedNotifications.Count); + ClassicAssert.AreEqual(1, apiConnection.UpdateCalls.Count); + ClassicAssert.AreEqual(1, apiConnection.AddCalls.Count); + CollectionAssert.AreEquivalent(new[] { 22 }, apiConnection.DeletedIds); + ClassicAssert.AreEqual(21, apiConnection.UpdateCalls[0].Id); + ClassicAssert.AreEqual("bundle-1", apiConnection.UpdateCalls[0].BundleId); + ClassicAssert.AreEqual(BundleType.Attachments.ToString(), apiConnection.UpdateCalls[0].BundleType); + ClassicAssert.AreEqual(NotificationLayout.CsvAsAttachment, syncedNotifications.Single(notification => notification.Id != 21).Layout); + ClassicAssert.IsTrue(syncedNotifications.All(notification => notification.BundleType == BundleType.Attachments)); + ClassicAssert.IsTrue(syncedNotifications.All(notification => notification.BundleId == "bundle-1")); + } + + [Test] + public async Task SyncNotifications_UpdatesNotificationFieldsViaSharedPersistenceHelper() + { + RecordingNotificationApiConnection apiConnection = new(); + ReportSchedule reportSchedule = NewReportSchedule(GlobalConst.kHtml); + reportSchedule.Notifications = + [ + NewNotification(31, NotificationLayout.HtmlAsAttachment) + ]; + + List syncedNotifications = await ReportScheduleNotificationHelper.SyncNotifications(apiConnection, + reportSchedule, true, "updated@example.org", "New Subject", "New Body"); + + ClassicAssert.AreEqual(1, syncedNotifications.Count); + ClassicAssert.AreEqual(1, apiConnection.UpdateCalls.Count); + ClassicAssert.AreEqual(31, syncedNotifications[0].Id); + ClassicAssert.AreEqual(NotificationClient.Report, syncedNotifications[0].NotificationClient); + ClassicAssert.AreEqual("Weekly Report HTML", syncedNotifications[0].Name); + ClassicAssert.AreEqual("updated@example.org", syncedNotifications[0].EmailAddressTo); + ClassicAssert.AreEqual("New Subject", syncedNotifications[0].EmailSubject); + ClassicAssert.AreEqual("New Body", syncedNotifications[0].EmailBody); + ClassicAssert.AreEqual(42, syncedNotifications[0].UserId); + ClassicAssert.AreEqual(NotificationDeadline.None, syncedNotifications[0].Deadline); + ClassicAssert.IsNull(syncedNotifications[0].IntervalBeforeDeadline); + ClassicAssert.IsNull(syncedNotifications[0].RepeatIntervalAfterDeadline); + ClassicAssert.AreEqual("Weekly Report HTML", apiConnection.UpdateCalls[0].Name); + ClassicAssert.AreEqual("updated@example.org", apiConnection.UpdateCalls[0].EmailAddressTo); + ClassicAssert.AreEqual("New Subject", apiConnection.UpdateCalls[0].Subject); + ClassicAssert.AreEqual("New Body", apiConnection.UpdateCalls[0].EmailBody); + ClassicAssert.AreEqual(42, apiConnection.UpdateCalls[0].UserId); + } + + private static ReportSchedule NewReportSchedule(params string[] formats) + { + return new ReportSchedule + { + Id = 7, + Name = "Weekly Report", + ScheduleOwningUser = new() { DbId = 42, Name = "report.owner" }, + OutputFormat = formats.Select(format => new FileFormat { Name = format }).ToList() + }; + } + + private static FwoNotification NewNotification(int id, NotificationLayout layout, string? bundleId = null) + { + return new FwoNotification + { + Id = id, + Layout = layout, + BundleType = bundleId == null ? null : BundleType.Attachments, + BundleId = bundleId, + NotificationClient = NotificationClient.Report, + Channel = NotificationChannel.Email, + RecipientTo = EmailRecipientOption.OtherAddresses, + EmailAddressTo = "existing@example.org", + RecipientCc = EmailRecipientOption.None, + EmailAddressCc = "", + EmailSubject = "Old Subject", + EmailBody = "Old Body", + Deadline = NotificationDeadline.None + }; + } + + private sealed class RecordingNotificationApiConnection : SimulatedApiConnection + { + private int nextId = 100; + + internal List AddCalls { get; } = []; + internal List UpdateCalls { get; } = []; + internal List DeletedIds { get; } = []; + + public override Task SendQueryAsync(string query, object? variables = null, string? operationName = null) + { + if (query == NotificationQueries.addNotification && typeof(QueryResponseType) == typeof(ReturnIdWrapper)) + { + AddCalls.Add(NotificationMutationCall.From(variables)); + return Task.FromResult((QueryResponseType)(object)new ReturnIdWrapper + { + ReturnIds = [new ReturnId { NewId = nextId++ }] + }); + } + + if (query == NotificationQueries.updateNotification && typeof(QueryResponseType) == typeof(ReturnIdWrapper)) + { + UpdateCalls.Add(NotificationMutationCall.From(variables)); + return Task.FromResult((QueryResponseType)(object)new ReturnIdWrapper + { + ReturnIds = [new ReturnId { UpdatedId = ReadInt(variables, "id") }] + }); + } + + if (query == NotificationQueries.deleteNotification && typeof(QueryResponseType) == typeof(object)) + { + DeletedIds.Add(ReadInt(variables, "id")); + return Task.FromResult((QueryResponseType)(object)new object()); + } + + throw new NotImplementedException(); + } + + private static int ReadInt(object? source, string propertyName) + { + object? value = ReadValue(source, propertyName); + return value is int intValue ? intValue : 0; + } + + private static object? ReadValue(object? source, string propertyName) + { + return source?.GetType().GetProperty(propertyName)?.GetValue(source); + } + } + + private sealed class NotificationMutationCall + { + internal int Id { get; init; } + internal int UserId { get; init; } + internal string Name { get; init; } = ""; + internal string EmailAddressTo { get; init; } = ""; + internal string Subject { get; init; } = ""; + internal string EmailBody { get; init; } = ""; + internal string Layout { get; init; } = ""; + internal string? BundleType { get; init; } + internal string? BundleId { get; init; } + + internal static NotificationMutationCall From(object? variables) + { + return new NotificationMutationCall + { + Id = ReadInt(variables, "id"), + UserId = ReadInt(variables, "userId"), + Name = ReadString(variables, "name"), + EmailAddressTo = ReadString(variables, "emailAddressTo"), + Subject = ReadString(variables, "subject"), + EmailBody = ReadString(variables, "emailBody"), + Layout = ReadString(variables, "layout"), + BundleType = ReadNullableString(variables, "bundleType"), + BundleId = ReadNullableString(variables, "bundleId") + }; + } + + private static int ReadInt(object? source, string propertyName) + { + object? value = ReadValue(source, propertyName); + return value is int intValue ? intValue : 0; + } + + private static string ReadString(object? source, string propertyName) + { + return ReadNullableString(source, propertyName) ?? ""; + } + + private static string? ReadNullableString(object? source, string propertyName) + { + object? value = ReadValue(source, propertyName); + return value?.ToString(); + } + + private static object? ReadValue(object? source, string propertyName) + { + return source?.GetType().GetProperty(propertyName)?.GetValue(source); + } + } + } +} diff --git a/roles/tests-unit/files/FWO.Test/ReportScheduleTest.cs b/roles/tests-unit/files/FWO.Test/ReportScheduleTest.cs new file mode 100644 index 0000000000..f857faa843 --- /dev/null +++ b/roles/tests-unit/files/FWO.Test/ReportScheduleTest.cs @@ -0,0 +1,19 @@ +using NUnit.Framework; +using NUnit.Framework.Legacy; +using FWO.Data.Report; + +namespace FWO.Test +{ + [TestFixture] + [Parallelizable] + internal class ReportScheduleTest + { + [Test] + public void ReportSchedule_DefaultsArchiveToFalse() + { + ReportSchedule reportSchedule = new(); + + ClassicAssert.IsFalse(reportSchedule.Archive); + } + } +} diff --git a/roles/tests-unit/files/FWO.Test/ReportTicketChangesTest.cs b/roles/tests-unit/files/FWO.Test/ReportTicketChangesTest.cs new file mode 100644 index 0000000000..3c7e48ba4e --- /dev/null +++ b/roles/tests-unit/files/FWO.Test/ReportTicketChangesTest.cs @@ -0,0 +1,1063 @@ +using FWO.Api.Client; +using FWO.Basics; +using FWO.Config.Api; +using FWO.Data; +using FWO.Data.Report; +using FWO.Data.Workflow; +using FWO.Report; +using FWO.Services.Workflow; +using FWO.Api.Client.Queries; +using NUnit.Framework; + +namespace FWO.Test +{ + [TestFixture] + [Parallelizable] + public class ReportTicketChangesTest + { + private class ReportTicketChangesApiConnection(List tickets, List? ownerTicketIds = null) : ApiConnection + { + public Dictionary? LastQueryVariables { get; private set; } + + public override void SetAuthHeader(string jwt) { } + public override void SetRole(string role) { } + public override void SetBestRole(System.Security.Claims.ClaimsPrincipal user, List targetRoleList) { } + public override void SetProperRole(System.Security.Claims.ClaimsPrincipal user, List targetRoleList) { } + public override void SwitchBack() { } + public override Task> SendQuerySafeAsync(string query, object? variables = null, string? operationName = null) + { + throw new NotImplementedException(); + } + + public override Task SendQueryAsync(string query, object? variables = null, string? operationName = null) + { + if (typeof(QueryResponseType) == typeof(List)) + { + LastQueryVariables = variables as Dictionary; + return Task.FromResult((QueryResponseType)(object)tickets); + } + if (typeof(QueryResponseType) == typeof(List) && query == RequestQueries.getStates) + { + return Task.FromResult((QueryResponseType)(object)new List { new() { Id = 9, Name = "done" } }); + } + if (typeof(QueryResponseType) == typeof(List) && query == RequestQueries.getOwnerTicketIds) + { + return Task.FromResult((QueryResponseType)(object)(ownerTicketIds ?? [])); + } + if (typeof(QueryResponseType) == typeof(List)) + { + return Task.FromResult((QueryResponseType)(object)new List + { + new() + { + ConfData = """ + {"config_value":{"request":{"matrix":{},"derived_states":{},"lowest_input_state":0,"lowest_start_state":0,"lowest_end_state":49,"active":true},"approval":{"matrix":{},"derived_states":{},"lowest_input_state":49,"lowest_start_state":60,"lowest_end_state":99,"active":true},"implementation":{"matrix":{},"derived_states":{},"lowest_input_state":99,"lowest_start_state":210,"lowest_end_state":249,"active":true}}} + """ + } + }); + } + throw new NotImplementedException(); + } + + public override GraphQlApiSubscription GetSubscription(Action exceptionHandler, GraphQlApiSubscription.SubscriptionUpdate subscriptionUpdateHandler, string subscription, object? variables = null, string? operationName = null) + { + throw new NotImplementedException(); + } + + public override void DisposeSubscriptions() { } + protected override void Dispose(bool disposing) { } + } + + [Test] + [Parallelizable] + public async Task TicketChangeReport_GenerateStoresReportedTickets() + { + ReportTemplate template = new(); + template.ReportParams.ReportType = (int)ReportType.TicketChangeReport; + ReportBase report = ReportBase.ConstructReport(template, new SimulatedUserConfig()); + List tickets = + [ + new() + { + Id = 1001, + Title = "Closed ticket", + StateId = 9, + Priority = 2, + Tasks = [new WfReqTask()], + Requester = new UiUser { Name = "reporter" } + } + ]; + + await report.Generate(0, new ReportTicketChangesApiConnection(tickets), _ => Task.CompletedTask, CancellationToken.None); + + Assert.That(report.ReportData.Tickets, Has.Count.EqualTo(1)); + Assert.That(report.ReportData.Tickets[0].Id, Is.EqualTo(1001)); + Assert.That(report.ReportData.ElementsCount, Is.EqualTo(1)); + Assert.That(report.ReportData.WorkflowStateNames[9], Is.EqualTo("done")); + } + + [Test] + [Parallelizable] + public async Task TicketReport_Generate_FiltersTicketsByOwnerVisibility_WhenReqOwnerBasedIsEnabled() + { + ReportTemplate template = new(); + template.ReportParams.ReportType = (int)ReportType.TicketReport; + SimulatedUserConfig userConfig = new() + { + ReqOwnerBased = true + }; + userConfig.User.DbId = 50; + userConfig.User.Roles = [Roles.Requester]; + userConfig.User.Ownerships = [4]; + ReportBase report = ReportBase.ConstructReport(template, userConfig); + List tickets = + [ + new() + { + Id = 1001, + Title = "Owned ticket", + StateId = 9, + Tasks = [new WfReqTask()], + Requester = new UiUser { Name = "owner-visible", DbId = 99 } + }, + new() + { + Id = 1002, + Title = "Foreign ticket", + StateId = 9, + Tasks = [new WfReqTask()], + Requester = new UiUser { Name = "foreign", DbId = 99 } + } + ]; + + await report.Generate(0, new ReportTicketChangesApiConnection(tickets, [new() { Id = 1001 }]), _ => Task.CompletedTask, CancellationToken.None); + + Assert.That(report.ReportData.Tickets.Select(ticket => ticket.Id), Is.EqualTo(new List { 1001 })); + Assert.That(report.ReportData.ElementsCount, Is.EqualTo(1)); + } + + [Test] + [Parallelizable] + public async Task TicketReport_Generate_ReturnsNoTickets_WhenReqOwnerBasedIsEnabledWithoutOwnerships() + { + ReportTemplate template = new(); + template.ReportParams.ReportType = (int)ReportType.TicketReport; + SimulatedUserConfig userConfig = new() + { + ReqOwnerBased = true + }; + userConfig.User.DbId = 50; + userConfig.User.Roles = [Roles.Requester]; + ReportBase report = ReportBase.ConstructReport(template, userConfig); + List tickets = + [ + new() + { + Id = 1001, + Title = "Hidden ticket", + StateId = 9, + Tasks = [new WfReqTask()], + Requester = new UiUser { Name = "foreign", DbId = 99 } + } + ]; + + await report.Generate(0, new ReportTicketChangesApiConnection(tickets), _ => Task.CompletedTask, CancellationToken.None); + + Assert.That(report.ReportData.Tickets, Is.Empty); + Assert.That(report.ReportData.ElementsCount, Is.EqualTo(0)); + } + + [Test] + [Parallelizable] + public void TicketChangeReport_ConstructReportReturnsTicketChangeReport() + { + ReportTemplate template = new(); + template.ReportParams.ReportType = (int)ReportType.TicketChangeReport; + + ReportBase report = ReportBase.ConstructReport(template, new SimulatedUserConfig()); + + Assert.That(report, Is.TypeOf()); + } + + [Test] + [Parallelizable] + public void TicketReport_ConstructReportReturnsReportTickets() + { + ReportTemplate template = new(); + template.ReportParams.ReportType = (int)ReportType.TicketReport; + + ReportBase report = ReportBase.ConstructReport(template, new SimulatedUserConfig()); + + Assert.That(report, Is.TypeOf()); + } + + [Test] + [Parallelizable] + public async Task TicketReport_GenerateResolvesPhaseToStateRange() + { + ReportTemplate template = new(); + template.ReportParams.ReportType = (int)ReportType.TicketReport; + template.ReportParams.WorkflowFilter.Phase = "implementation"; + ReportBase report = ReportBase.ConstructReport(template, new SimulatedUserConfig()); + ReportTicketChangesApiConnection apiConnection = new([]); + + await report.Generate(0, apiConnection, _ => Task.CompletedTask, CancellationToken.None); + + Assert.That(apiConnection.LastQueryVariables, Is.Not.Null); + Assert.That(apiConnection.LastQueryVariables!["phase_lowest_input_state"], Is.EqualTo(99)); + Assert.That(apiConnection.LastQueryVariables!["phase_lowest_end_state"], Is.EqualTo(249)); + } + + [Test] + [Parallelizable] + public async Task TicketChangeReport_GenerateResolvesPhaseToStateRange() + { + ReportTemplate template = new(); + template.ReportParams.ReportType = (int)ReportType.TicketChangeReport; + template.ReportParams.WorkflowFilter.Phase = "implementation"; + ReportBase report = ReportBase.ConstructReport(template, new SimulatedUserConfig()); + ReportTicketChangesApiConnection apiConnection = new([]); + + await report.Generate(0, apiConnection, _ => Task.CompletedTask, CancellationToken.None); + + Assert.That(apiConnection.LastQueryVariables, Is.Not.Null); + Assert.That(apiConnection.LastQueryVariables!["phase_lowest_input_state"], Is.EqualTo(99)); + Assert.That(apiConnection.LastQueryVariables!["phase_lowest_end_state"], Is.EqualTo(249)); + } + + [Test] + [Parallelizable] + public async Task TicketReport_GenerateResolvesClosedPhaseToOpenEndedStateRange() + { + ReportTemplate template = new(); + template.ReportParams.ReportType = (int)ReportType.TicketReport; + template.ReportParams.WorkflowFilter.Phase = GlobalConst.kClosed; + ReportBase report = ReportBase.ConstructReport(template, new SimulatedUserConfig()); + ReportTicketChangesApiConnection apiConnection = new([]); + + await report.Generate(0, apiConnection, _ => Task.CompletedTask, CancellationToken.None); + + Assert.That(apiConnection.LastQueryVariables, Is.Not.Null); + Assert.That(apiConnection.LastQueryVariables!["phase_lowest_input_state"], Is.EqualTo(249)); + Assert.That(apiConnection.LastQueryVariables.ContainsKey("phase_lowest_end_state"), Is.False); + } + + [Test] + [Parallelizable] + public async Task TicketChangeReport_ExportToHtml_UsesCurrentColumnsAndStateNames() + { + ReportTemplate template = new(); + template.ReportParams.ReportType = (int)ReportType.TicketChangeReport; + template.ReportParams.WorkflowFilter.DetailedView = true; + template.ReportParams.WorkflowFilter.ShowFullTicket = true; + ReportBase report = ReportBase.ConstructReport(template, new SimulatedUserConfig()); + List tickets = + [ + new() + { + Id = 1001, + Title = "Closed ticket", + StateId = 9, + Tasks = + [ + new WfReqTask + { + Id = 201, + TaskNumber = 1, + Title = "Request task", + StateId = 9 + } + ], + Requester = new UiUser { Name = "reporter" } + } + ]; + + await report.Generate(0, new ReportTicketChangesApiConnection(tickets), _ => Task.CompletedTask, CancellationToken.None); + + string html = report.ExportToHtml(); + + Assert.That(html, Does.Contain("Name")); + Assert.That(html, Does.Contain("Ticket Created")); + Assert.That(html, Does.Contain("Ticket Closed")); + Assert.That(html, Does.Not.Contain("Priority")); + Assert.That(html, Does.Not.Contain("Deadline")); + Assert.That(html, Does.Contain("done")); + Assert.That(html, Does.Contain(">1<")); + Assert.That(html, Does.Contain(">Tasks<")); + Assert.That(html, Does.Contain(">Request task<")); + } + + [Test] + [Parallelizable] + public async Task TicketChangeReport_ExportToHtml_ShowsRequestTasksForTicketCreationReferenceDate() + { + ReportTemplate template = new(); + template.ReportParams.ReportType = (int)ReportType.TicketChangeReport; + template.ReportParams.WorkflowFilter.DetailedView = true; + template.ReportParams.WorkflowFilter.ReferenceDate = WorkflowReferenceDate.TicketCreation; + template.ReportParams.WorkflowFilter.ShowFullTicket = false; + template.ReportParams.WorkflowFilter.TaskTypes = [WfTaskType.access]; + ReportBase report = ReportBase.ConstructReport(template, new SimulatedUserConfig()); + List tickets = + [ + new() + { + Id = 1002, + Title = "Created ticket", + StateId = 9, + Tasks = + [ + new WfReqTask + { + Id = 301, + TaskNumber = 7, + Title = "Visible request task", + StateId = 9, + TaskType = WfTaskType.access.ToString() + } + ], + Requester = new UiUser { Name = "creator" } + } + ]; + + await report.Generate(0, new ReportTicketChangesApiConnection(tickets), _ => Task.CompletedTask, CancellationToken.None); + + string html = report.ExportToHtml(); + + Assert.That(html, Does.Contain(">Visible request task<")); + Assert.That(html, Does.Contain(">7<")); + } + + [Test] + [Parallelizable] + public async Task TicketChangeReport_ExportToHtml_FiltersRequestTasksByTaskType() + { + ReportTemplate template = new(); + template.ReportParams.ReportType = (int)ReportType.TicketChangeReport; + template.ReportParams.WorkflowFilter.DetailedView = true; + template.ReportParams.WorkflowFilter.ReferenceDate = WorkflowReferenceDate.TicketCreation; + template.ReportParams.WorkflowFilter.ShowFullTicket = false; + template.ReportParams.WorkflowFilter.TaskTypes = [WfTaskType.access]; + ReportBase report = ReportBase.ConstructReport(template, new SimulatedUserConfig()); + List tickets = + [ + new() + { + Id = 1003, + Title = "Task type filtered ticket", + StateId = 9, + Tasks = + [ + new WfReqTask + { + Id = 401, + TaskNumber = 1, + Title = "Access task", + StateId = 9, + TaskType = WfTaskType.access.ToString() + }, + new WfReqTask + { + Id = 402, + TaskNumber = 2, + Title = "Rule delete task", + StateId = 9, + TaskType = WfTaskType.rule_delete.ToString() + } + ], + Requester = new UiUser { Name = "creator" } + } + ]; + + await report.Generate(0, new ReportTicketChangesApiConnection(tickets), _ => Task.CompletedTask, CancellationToken.None); + + string html = report.ExportToHtml(); + + Assert.That(html, Does.Contain(">Access task<")); + Assert.That(html, Does.Not.Contain(">Rule delete task<")); + } + + [Test] + [Parallelizable] + public async Task TicketChangeReport_ExportToHtml_ShowsImplementationTasksForImplementationStartReferenceDate() + { + ReportTemplate template = new(); + template.ReportParams.ReportType = (int)ReportType.TicketChangeReport; + template.ReportParams.WorkflowFilter.DetailedView = true; + template.ReportParams.WorkflowFilter.ReferenceDate = WorkflowReferenceDate.ImplementationStart; + template.ReportParams.TimeFilter.TimeRangeType = TimeRangeType.Fixeddates; + template.ReportParams.TimeFilter.StartTime = new DateTime(2026, 1, 1, 0, 0, 0); + template.ReportParams.TimeFilter.EndTime = new DateTime(2026, 1, 31, 23, 59, 59); + ReportBase report = ReportBase.ConstructReport(template, new SimulatedUserConfig()); + List tickets = + [ + new() + { + Id = 10031, + Title = "Implementation start ticket", + StateId = 9, + Tasks = + [ + new WfReqTask + { + Id = 410, + TaskNumber = 1, + Title = "Request task with impl", + StateId = 9, + TaskType = WfTaskType.access.ToString(), + ImplementationTasks = + [ + new WfImplTask + { + Id = 411, + TaskNumber = 1, + Title = "Visible implementation task", + StateId = 9, + Start = new DateTime(2026, 1, 10, 10, 0, 0) + }, + new WfImplTask + { + Id = 412, + TaskNumber = 2, + Title = "Hidden implementation task", + StateId = 9, + Start = new DateTime(2026, 2, 10, 10, 0, 0) + } + ] + } + ], + Requester = new UiUser { Name = "creator" } + } + ]; + + await report.Generate(0, new ReportTicketChangesApiConnection(tickets), _ => Task.CompletedTask, CancellationToken.None); + + string html = report.ExportToHtml(); + + Assert.That(html, Does.Contain(">Implementation<")); + Assert.That(html, Does.Contain(">Visible implementation task<")); + Assert.That(html, Does.Not.Contain(">Hidden implementation task<")); + } + + [Test] + [Parallelizable] + public async Task TicketChangeReport_ExportToHtml_ShowsApprovalsForApprovalOpenedReferenceDate() + { + ReportTemplate template = new(); + template.ReportParams.ReportType = (int)ReportType.TicketChangeReport; + template.ReportParams.WorkflowFilter.DetailedView = true; + template.ReportParams.WorkflowFilter.ReferenceDate = WorkflowReferenceDate.ApprovalOpened; + template.ReportParams.TimeFilter.TimeRangeType = TimeRangeType.Fixeddates; + template.ReportParams.TimeFilter.StartTime = new DateTime(2026, 1, 1, 0, 0, 0); + template.ReportParams.TimeFilter.EndTime = new DateTime(2026, 1, 31, 23, 59, 59); + ReportBase report = ReportBase.ConstructReport(template, new SimulatedUserConfig()); + List tickets = + [ + new() + { + Id = 10032, + Title = "Approval opened ticket", + StateId = 9, + Tasks = + [ + new WfReqTask + { + Id = 420, + TaskNumber = 1, + Title = "Request task with approvals", + StateId = 9, + TaskType = WfTaskType.access.ToString(), + Approvals = + [ + new WfApproval + { + Id = 421, + ApproverGroup = "Visible approval", + StateId = 9, + DateOpened = new DateTime(2026, 1, 12, 9, 0, 0) + }, + new WfApproval + { + Id = 422, + ApproverGroup = "Hidden approval", + StateId = 9, + DateOpened = new DateTime(2026, 2, 12, 9, 0, 0) + } + ] + } + ], + Requester = new UiUser { Name = "creator" } + } + ]; + + await report.Generate(0, new ReportTicketChangesApiConnection(tickets), _ => Task.CompletedTask, CancellationToken.None); + + string html = report.ExportToHtml(); + + Assert.That(html, Does.Contain(">Approval<")); + Assert.That(html, Does.Contain(">Visible approval<")); + Assert.That(html, Does.Not.Contain(">Hidden approval<")); + } + + [Test] + [Parallelizable] + public async Task TicketChangeReport_ExportToHtml_UsesApprovalDateAsReferenceColumnForApprovedFilter() + { + ReportTemplate template = new(); + template.ReportParams.ReportType = (int)ReportType.TicketChangeReport; + template.ReportParams.WorkflowFilter.DetailedView = true; + template.ReportParams.WorkflowFilter.ReferenceDate = WorkflowReferenceDate.Approved; + template.ReportParams.TimeFilter.TimeRangeType = TimeRangeType.Fixeddates; + template.ReportParams.TimeFilter.StartTime = new DateTime(2026, 1, 1, 0, 0, 0); + template.ReportParams.TimeFilter.EndTime = new DateTime(2026, 1, 31, 23, 59, 59); + ReportBase report = ReportBase.ConstructReport(template, new SimulatedUserConfig()); + List tickets = + [ + new() + { + Id = 10034, + Title = "Approved ticket", + StateId = 9, + Tasks = + [ + new WfReqTask + { + Id = 440, + TaskNumber = 1, + Title = "Request task with approved entry", + StateId = 9, + TaskType = WfTaskType.access.ToString(), + Approvals = + [ + new WfApproval + { + Id = 441, + ApproverGroup = "Visible approved entry", + StateId = 9, + ApprovalDate = new DateTime(2026, 1, 18, 8, 15, 0) + } + ] + } + ], + Requester = new UiUser { Name = "creator" } + } + ]; + + await report.Generate(0, new ReportTicketChangesApiConnection(tickets), _ => Task.CompletedTask, CancellationToken.None); + + string html = report.ExportToHtml(); + + Assert.That(html, Does.Contain("Ticket Closed")); + Assert.That(html, Does.Contain("Approved")); + Assert.That(html, Does.Contain(">Visible approved entry<")); + } + + [Test] + [Parallelizable] + public async Task TicketChangeReport_ExportToHtml_ShowFullTicketOverridesReferenceDateFiltering() + { + ReportTemplate template = new(); + template.ReportParams.ReportType = (int)ReportType.TicketChangeReport; + template.ReportParams.WorkflowFilter.DetailedView = true; + template.ReportParams.WorkflowFilter.ShowFullTicket = true; + template.ReportParams.WorkflowFilter.ReferenceDate = WorkflowReferenceDate.ImplementationStart; + template.ReportParams.TimeFilter.TimeRangeType = TimeRangeType.Fixeddates; + template.ReportParams.TimeFilter.StartTime = new DateTime(2026, 1, 1, 0, 0, 0); + template.ReportParams.TimeFilter.EndTime = new DateTime(2026, 1, 31, 23, 59, 59); + ReportBase report = ReportBase.ConstructReport(template, new SimulatedUserConfig()); + List tickets = + [ + new() + { + Id = 10033, + Title = "Full ticket", + StateId = 9, + Tasks = + [ + new WfReqTask + { + Id = 430, + TaskNumber = 1, + Title = "Task outside range but still shown", + StateId = 9, + TaskType = WfTaskType.access.ToString(), + ImplementationTasks = + [ + new WfImplTask + { + Id = 431, + TaskNumber = 1, + Title = "Implementation outside range but shown", + StateId = 9, + Start = new DateTime(2026, 2, 5, 10, 0, 0) + } + ] + } + ], + Requester = new UiUser { Name = "creator" } + } + ]; + + await report.Generate(0, new ReportTicketChangesApiConnection(tickets), _ => Task.CompletedTask, CancellationToken.None); + + string html = report.ExportToHtml(); + + Assert.That(html, Does.Contain(">Task outside range but still shown<")); + Assert.That(html, Does.Contain(">Implementation outside range but shown<")); + } + + [Test] + [Parallelizable] + public async Task TicketReport_ExportToHtml_FiltersRequestTasksByTaskType() + { + ReportTemplate template = new(); + template.ReportParams.ReportType = (int)ReportType.TicketReport; + template.ReportParams.WorkflowFilter.DetailedView = true; + template.ReportParams.WorkflowFilter.ShowFullTicket = false; + template.ReportParams.WorkflowFilter.TaskTypes = [WfTaskType.access]; + ReportBase report = ReportBase.ConstructReport(template, new SimulatedUserConfig()); + List tickets = + [ + new() + { + Id = 1004, + Title = "Ticket report task filter", + StateId = 9, + Tasks = + [ + new WfReqTask + { + Id = 501, + TaskNumber = 1, + Title = "Shown access task", + StateId = 9, + TaskType = WfTaskType.access.ToString() + }, + new WfReqTask + { + Id = 502, + TaskNumber = 2, + Title = "Hidden rule modify task", + StateId = 9, + TaskType = WfTaskType.rule_modify.ToString() + } + ], + Requester = new UiUser { Name = "reporter" } + } + ]; + + await report.Generate(0, new ReportTicketChangesApiConnection(tickets), _ => Task.CompletedTask, CancellationToken.None); + + string html = report.ExportToHtml(); + + Assert.That(html, Does.Contain(">Shown access task<")); + Assert.That(html, Does.Not.Contain(">Hidden rule modify task<")); + } + + [Test] + [Parallelizable] + public async Task TicketReport_ExportToHtml_HidesRequestTasksWhenDetailedViewIsDisabled() + { + ReportTemplate template = new(); + template.ReportParams.ReportType = (int)ReportType.TicketReport; + template.ReportParams.WorkflowFilter.DetailedView = false; + template.ReportParams.WorkflowFilter.ShowFullTicket = true; + ReportBase report = ReportBase.ConstructReport(template, new SimulatedUserConfig()); + List tickets = + [ + new() + { + Id = 1005, + Title = "Compact ticket report", + StateId = 9, + Tasks = + [ + new WfReqTask + { + Id = 601, + TaskNumber = 1, + Title = "Hidden request task", + StateId = 9, + TaskType = WfTaskType.access.ToString() + } + ], + Requester = new UiUser { Name = "reporter" } + } + ]; + + await report.Generate(0, new ReportTicketChangesApiConnection(tickets), _ => Task.CompletedTask, CancellationToken.None); + + string html = report.ExportToHtml(); + + Assert.That(html, Does.Contain(">Compact ticket report<")); + Assert.That(html, Does.Not.Contain(">Hidden request task<")); + Assert.That(html, Does.Not.Contain(">Task Number<")); + } + + [Test] + [Parallelizable] + public async Task TicketReport_ExportToHtml_ShowsSelectedLabelAsColumn() + { + ReportTemplate template = new(); + template.ReportParams.ReportType = (int)ReportType.TicketReport; + template.ReportParams.WorkflowFilter.LabelFilter = new() { Name = "policy_check", Mode = WorkflowLabelFilterMode.existing }; + ReportBase report = ReportBase.ConstructReport(template, new SimulatedUserConfig()); + List tickets = + [ + new() + { + Id = 1006, + Title = "Label ticket report", + StateId = 9, + Tasks = + [ + new WfReqTask + { + Id = 701, + TaskNumber = 1, + Title = "Request task", + StateId = 9, + AdditionalInfo = "{\"policy_check\":\"true\"}" + } + ], + Requester = new UiUser { Name = "reporter" } + } + ]; + + await report.Generate(0, new ReportTicketChangesApiConnection(tickets), _ => Task.CompletedTask, CancellationToken.None); + + string html = report.ExportToHtml(); + + Assert.That(html, Does.Contain("policy_check")); + Assert.That(html, Does.Contain("true")); + } + + [Test] + [Parallelizable] + public async Task TicketReport_ExportToHtml_ShowsWorkflowFiltersInHeader() + { + ReportTemplate template = new(); + template.ReportParams.ReportType = (int)ReportType.TicketReport; + template.ReportParams.WorkflowFilter.TaskTypes = [WfTaskType.access]; + template.ReportParams.WorkflowFilter.Phase = "implementation"; + template.ReportParams.WorkflowFilter.StateIds = [9]; + template.ReportParams.WorkflowFilter.DetailedView = true; + template.ReportParams.WorkflowFilter.ShowFullTicket = false; + template.ReportParams.WorkflowFilter.LabelFilter = new() { Name = "policy_check", Mode = WorkflowLabelFilterMode.existing }; + ReportBase report = ReportBase.ConstructReport(template, new SimulatedUserConfig()); + + await report.Generate(0, new ReportTicketChangesApiConnection([]), _ => Task.CompletedTask, CancellationToken.None); + + string html = report.ExportToHtml(); + + Assert.That(html, Does.Contain("

                      Workflow Filters:")); + Assert.That(html, Does.Contain("Task type: access")); + Assert.That(html, Does.Contain("Phase: Implementation")); + Assert.That(html, Does.Contain("State: done")); + Assert.That(html, Does.Contain("Label: policy_check (existing)")); + } + + [Test] + [Parallelizable] + public async Task TicketReport_ExportToCsv_ReturnsCompactTicketRowsWhenDetailedViewIsDisabled() + { + ReportTemplate template = new(); + template.ReportParams.ReportType = (int)ReportType.TicketReport; + template.ReportParams.WorkflowFilter.DetailedView = false; + template.ReportParams.WorkflowFilter.LabelFilter = new() { Name = "policy_check", Mode = WorkflowLabelFilterMode.existing }; + ReportBase report = ReportBase.ConstructReport(template, new SimulatedUserConfig()); + List tickets = + [ + new() + { + Id = 1007, + Title = "Csv ticket report", + StateId = 9, + Tasks = + [ + new WfReqTask + { + Id = 801, + TaskNumber = 1, + Title = "Request task", + StateId = 9, + AdditionalInfo = "{\"policy_check\":\"true\"}" + } + ], + Requester = new UiUser { Name = "reporter" } + } + ]; + + await report.Generate(0, new ReportTicketChangesApiConnection(tickets), _ => Task.CompletedTask, CancellationToken.None); + + string csv = report.ExportToCsv(); + + Assert.That(csv, Does.Contain("\"Id\",\"Name\",\"Tasks\",\"Requester\",\"State\",\"Ticket Created\",\"Ticket Closed\",\"policy_check\"")); + Assert.That(csv, Does.Contain("\"1007\",\"Csv ticket report\",\"1\",\"reporter\",\"done\"")); + Assert.That(csv, Does.Contain("\"true\"")); + } + + [Test] + [Parallelizable] + public async Task TicketChangeReport_ExportToCsv_UsesApprovedColumnAndApprovalDateForApprovedFilter() + { + ReportTemplate template = new(); + template.ReportParams.ReportType = (int)ReportType.TicketChangeReport; + template.ReportParams.WorkflowFilter.DetailedView = false; + template.ReportParams.WorkflowFilter.ReferenceDate = WorkflowReferenceDate.Approved; + template.ReportParams.TimeFilter.TimeRangeType = TimeRangeType.Fixeddates; + template.ReportParams.TimeFilter.StartTime = new DateTime(2026, 1, 1, 0, 0, 0); + template.ReportParams.TimeFilter.EndTime = new DateTime(2026, 1, 31, 23, 59, 59); + ReportBase report = ReportBase.ConstructReport(template, new SimulatedUserConfig()); + List tickets = + [ + new() + { + Id = 10035, + Title = "Approved csv ticket", + StateId = 9, + Tasks = + [ + new WfReqTask + { + Id = 450, + TaskNumber = 1, + Title = "Request task with approved csv entry", + StateId = 9, + TaskType = WfTaskType.access.ToString(), + Approvals = + [ + new WfApproval + { + Id = 451, + ApproverGroup = "Visible approved csv entry", + StateId = 9, + ApprovalDate = new DateTime(2026, 1, 20, 11, 30, 0) + } + ] + } + ], + Requester = new UiUser { Name = "creator" } + } + ]; + + await report.Generate(0, new ReportTicketChangesApiConnection(tickets), _ => Task.CompletedTask, CancellationToken.None); + + string csv = report.ExportToCsv(); + + Assert.That(csv, Does.Contain("\"Id\",\"Name\",\"Tasks\",\"Requester\",\"State\",\"Ticket Created\",\"Ticket Closed\",\"Approved\"")); + Assert.That(csv, Does.Contain("2026").And.Contain("11:30:00")); + } + + [Test] + [Parallelizable] + public async Task TicketChangeReport_ExportToCsv_UsesInRangeReferenceDateForAnyActivity() + { + DateTime inRangeActivityDate = new(2025, 12, 20, 14, 30, 0); + ReportTemplate template = new(); + template.ReportParams.ReportType = (int)ReportType.TicketChangeReport; + template.ReportParams.WorkflowFilter.DetailedView = false; + template.ReportParams.WorkflowFilter.ReferenceDate = WorkflowReferenceDate.AnyActivity; + template.ReportParams.TimeFilter.TimeRangeType = TimeRangeType.Fixeddates; + template.ReportParams.TimeFilter.StartTime = new DateTime(2025, 1, 1, 0, 0, 0); + template.ReportParams.TimeFilter.EndTime = new DateTime(2025, 12, 31, 23, 59, 59); + ReportBase report = ReportBase.ConstructReport(template, new SimulatedUserConfig()); + List tickets = + [ + new() + { + Id = 10036, + Title = "Cross-year activity ticket", + StateId = 9, + CreationDate = new DateTime(2025, 6, 1, 8, 0, 0), + CompletionDate = new DateTime(2026, 1, 10, 9, 0, 0), + Tasks = + [ + new WfReqTask + { + Id = 460, + TaskNumber = 1, + Title = "Request task with mixed dates", + StateId = 9, + TaskType = WfTaskType.access.ToString(), + Start = new DateTime(2025, 7, 1, 8, 0, 0), + Stop = new DateTime(2026, 1, 5, 12, 0, 0), + Approvals = + [ + new WfApproval + { + Id = 461, + ApproverGroup = "In-range approval", + StateId = 9, + ApprovalDate = inRangeActivityDate + } + ] + } + ], + Requester = new UiUser { Name = "creator" } + } + ]; + + await report.Generate(0, new ReportTicketChangesApiConnection(tickets), _ => Task.CompletedTask, CancellationToken.None); + + string csv = report.ExportToCsv(); + + Assert.That(csv, Does.Contain("\"Id\",\"Name\",\"Tasks\",\"Requester\",\"State\",\"Ticket Created\",\"Ticket Closed\",\"Any activity\"")); + Assert.That(csv, Does.Contain($"\"{inRangeActivityDate}\"")); + Assert.That(csv, Does.Contain($"\"{tickets[0].CompletionDate}\"")); + Assert.That(csv, Does.Not.Contain($"\"{new DateTime(2026, 1, 5, 12, 0, 0)}\"")); + } + + [Test] + [Parallelizable] + public async Task TicketChangeReport_ExportToCsv_UsesInRangeReferenceDateForAnyActivityWhenShowFullTicketIsEnabled() + { + DateTime inRangeActivityDate = new(2025, 12, 20, 14, 30, 0); + DateTime outOfRangeTaskStop = new(2026, 1, 5, 12, 0, 0); + ReportTemplate template = new(); + template.ReportParams.ReportType = (int)ReportType.TicketChangeReport; + template.ReportParams.WorkflowFilter.DetailedView = false; + template.ReportParams.WorkflowFilter.ShowFullTicket = true; + template.ReportParams.WorkflowFilter.ReferenceDate = WorkflowReferenceDate.AnyActivity; + template.ReportParams.TimeFilter.TimeRangeType = TimeRangeType.Fixeddates; + template.ReportParams.TimeFilter.StartTime = new DateTime(2025, 1, 1, 0, 0, 0); + template.ReportParams.TimeFilter.EndTime = new DateTime(2025, 12, 31, 23, 59, 59); + ReportBase report = ReportBase.ConstructReport(template, new SimulatedUserConfig()); + List tickets = + [ + new() + { + Id = 10037, + Title = "Cross-year full ticket", + StateId = 9, + CreationDate = new DateTime(2025, 6, 1, 8, 0, 0), + CompletionDate = new DateTime(2026, 1, 10, 9, 0, 0), + Tasks = + [ + new WfReqTask + { + Id = 470, + TaskNumber = 1, + Title = "Full task with mixed dates", + StateId = 9, + TaskType = WfTaskType.access.ToString(), + Start = new DateTime(2025, 7, 1, 8, 0, 0), + Stop = outOfRangeTaskStop, + Approvals = + [ + new WfApproval + { + Id = 471, + ApproverGroup = "In-range full approval", + StateId = 9, + ApprovalDate = inRangeActivityDate + } + ] + } + ], + Requester = new UiUser { Name = "creator" } + } + ]; + + await report.Generate(0, new ReportTicketChangesApiConnection(tickets), _ => Task.CompletedTask, CancellationToken.None); + + Assert.That(report.ReportData.TicketReferenceDates[tickets[0].Id], Is.EqualTo(inRangeActivityDate)); + + string csv = report.ExportToCsv(); + + Assert.That(csv, Does.Contain($"\"{inRangeActivityDate}\"")); + Assert.That(csv, Does.Not.Contain($"\"{outOfRangeTaskStop}\"")); + } + + [Test] + [Parallelizable] + public async Task TicketChangeReport_ExportToCsv_UsesTicketCreationDateForAnyActivityWhenClosureIsOutOfRange() + { + DateTime inRangeCreationDate = new(2025, 10, 15, 10, 0, 0); + DateTime outOfRangeClosureDate = new(2026, 2, 1, 9, 0, 0); + ReportTemplate template = new(); + template.ReportParams.ReportType = (int)ReportType.TicketChangeReport; + template.ReportParams.WorkflowFilter.DetailedView = false; + template.ReportParams.WorkflowFilter.ReferenceDate = WorkflowReferenceDate.AnyActivity; + template.ReportParams.TimeFilter.TimeRangeType = TimeRangeType.Fixeddates; + template.ReportParams.TimeFilter.StartTime = new DateTime(2025, 1, 1, 0, 0, 0); + template.ReportParams.TimeFilter.EndTime = new DateTime(2025, 12, 31, 23, 59, 59); + ReportBase report = ReportBase.ConstructReport(template, new SimulatedUserConfig()); + List tickets = + [ + new() + { + Id = 10038, + Title = "Cross-year creation ticket", + StateId = 9, + CreationDate = inRangeCreationDate, + CompletionDate = outOfRangeClosureDate, + Tasks = [], + Requester = new UiUser { Name = "creator" } + } + ]; + + await report.Generate(0, new ReportTicketChangesApiConnection(tickets), _ => Task.CompletedTask, CancellationToken.None); + + Assert.That(report.ReportData.TicketReferenceDates[tickets[0].Id], Is.EqualTo(inRangeCreationDate)); + + string csv = report.ExportToCsv(); + + Assert.That(csv, Does.Contain($"\"{inRangeCreationDate}\"")); + Assert.That(csv, Does.Contain($"\"{outOfRangeClosureDate}\"")); + Assert.That(csv, Does.Not.Contain($"\"{outOfRangeClosureDate}\",\"{outOfRangeClosureDate}\"")); + } + + [Test] + [Parallelizable] + public async Task TicketChangeReport_ExportToCsv_ExcludesBoundaryClosureDateForAnyActivity() + { + DateTime inRangeCreationDate = new(2025, 12, 31, 23, 0, 0); + DateTime boundaryClosureDate = new(2026, 1, 1, 0, 0, 0); + ReportTemplate template = new(); + template.ReportParams.ReportType = (int)ReportType.TicketChangeReport; + template.ReportParams.WorkflowFilter.DetailedView = false; + template.ReportParams.WorkflowFilter.ReferenceDate = WorkflowReferenceDate.AnyActivity; + template.ReportParams.TimeFilter.TimeRangeType = TimeRangeType.Fixeddates; + template.ReportParams.TimeFilter.StartTime = new DateTime(2025, 1, 1, 0, 0, 0); + template.ReportParams.TimeFilter.EndTime = new DateTime(2026, 1, 1, 0, 0, 0); + ReportBase report = ReportBase.ConstructReport(template, new SimulatedUserConfig()); + List tickets = + [ + new() + { + Id = 10039, + Title = "Boundary closure ticket", + StateId = 9, + CreationDate = inRangeCreationDate, + CompletionDate = boundaryClosureDate, + Tasks = [], + Requester = new UiUser { Name = "creator" } + } + ]; + + await report.Generate(0, new ReportTicketChangesApiConnection(tickets), _ => Task.CompletedTask, CancellationToken.None); + + Assert.That(report.ReportData.TicketReferenceDates[tickets[0].Id], Is.EqualTo(inRangeCreationDate)); + + string csv = report.ExportToCsv(); + + Assert.That(csv, Does.Contain($"\"{inRangeCreationDate}\"")); + Assert.That(csv, Does.Not.Contain($"\"{boundaryClosureDate}\",\"{boundaryClosureDate}\"")); + } + + [Test] + [Parallelizable] + public async Task TicketReport_ExportToCsv_ThrowsWhenDetailedViewIsEnabled() + { + ReportTemplate template = new(); + template.ReportParams.ReportType = (int)ReportType.TicketReport; + template.ReportParams.WorkflowFilter.DetailedView = true; + ReportBase report = ReportBase.ConstructReport(template, new SimulatedUserConfig()); + + await report.Generate(0, new ReportTicketChangesApiConnection([]), _ => Task.CompletedTask, CancellationToken.None); + + Assert.That(() => report.ExportToCsv(), Throws.TypeOf()); + } + } +} diff --git a/roles/tests-unit/files/FWO.Test/ReportTypeVisibilityTest.cs b/roles/tests-unit/files/FWO.Test/ReportTypeVisibilityTest.cs new file mode 100644 index 0000000000..3f6d37fb30 --- /dev/null +++ b/roles/tests-unit/files/FWO.Test/ReportTypeVisibilityTest.cs @@ -0,0 +1,87 @@ +using System.Security.Claims; +using FWO.Basics; +using NUnit.Framework; + +namespace FWO.Test +{ + [TestFixture] + [Parallelizable] + internal class ReportTypeVisibilityTest + { + [Test] + public void GetReportVisibility_ModellerOnly_HidesComplianceAndWorkflowReports() + { + ReportVisibility visibility = RoleGroups.GetReportVisibility(BuildPrincipal(Roles.Modeller)); + + Assert.That(visibility.RuleRelated, Is.False); + Assert.That(visibility.ModellingRelated, Is.True); + Assert.That(visibility.ComplianceRelated, Is.False); + Assert.That(visibility.OwnerRelated, Is.False); + Assert.That(visibility.WorkflowRelated, Is.False); + } + + [Test] + public void CustomSortReportType_FiltersUnorderedComplianceAndArchiveOnlyReports() + { + ReportVisibility visibility = RoleGroups.GetReportVisibility(BuildPrincipal(Roles.Modeller)); + List sortedTypes = ReportTypeGroups.CustomSortReportType( + [ + ReportType.ComplianceReport, + ReportType.ComplianceDiffReport, + ReportType.Connections, + ReportType.RecertificationEvent, + ReportType.TicketReport + ], visibility); + + Assert.That(sortedTypes, Is.EqualTo(new List { ReportType.Connections })); + } + + [Test] + public void CustomSortReportType_ReporterDoesNotSeeModellingOverlapOrOwnerReports() + { + ReportVisibility visibility = RoleGroups.GetReportVisibility(BuildPrincipal(Roles.Reporter)); + List sortedTypes = ReportTypeGroups.CustomSortReportType( + [ + ReportType.Rules, + ReportType.AppRules, + ReportType.RecertEventReport, + ReportType.Owners, + ReportType.Connections + ], visibility); + + Assert.That(sortedTypes, Is.EqualTo(new List { ReportType.Rules })); + } + + [Test] + public void CustomSortReportType_AdminSeesOwnersReport() + { + ReportVisibility visibility = RoleGroups.GetReportVisibility(BuildPrincipal(Roles.Admin)); + List sortedTypes = ReportTypeGroups.CustomSortReportType( + [ + ReportType.Owners, + ReportType.Connections + ], visibility); + + Assert.That(sortedTypes, Does.Contain(ReportType.Owners)); + } + + [Test] + public void ReportTypeSelection_DoesNotContainArchiveOnlyReport() + { + List reportTypes = ReportTypeGroups.ReportTypeSelection(new(true, true, true, true, true)); + + Assert.That(reportTypes, Does.Not.Contain(ReportType.RecertificationEvent)); + } + + private static ClaimsPrincipal BuildPrincipal(params string[] roles) + { + ClaimsIdentity identity = new( + roles.Select(role => new Claim(ClaimTypes.Role, role)), + authenticationType: "test", + nameType: ClaimTypes.Name, + roleType: ClaimTypes.Role); + + return new ClaimsPrincipal(identity); + } + } +} diff --git a/roles/tests-unit/files/FWO.Test/RuleDataTest.cs b/roles/tests-unit/files/FWO.Test/RuleDataTest.cs new file mode 100644 index 0000000000..18e49b2cae --- /dev/null +++ b/roles/tests-unit/files/FWO.Test/RuleDataTest.cs @@ -0,0 +1,51 @@ +using FWO.Data; +using Newtonsoft.Json; +using NUnit.Framework; + +namespace FWO.Test +{ + [TestFixture] + public class RuleDataTest + { + [Test] + public void RuleTimes_AreDeserialized_WhenRemovedIsNull() + { + const string serializedRule = """ + { + "rule_id": 1001, + "rule_times": [ + { + "rule_time_id": 10, + "rule_id": 1001, + "time_obj_id": 55, + "created": 200, + "removed": null, + "time_object": { + "time_obj_id": 55, + "time_obj_name": "Office Hours", + "time_obj_uid": "uid-55", + "start_time": "2025-01-01T08:00:00Z", + "end_time": "2025-01-01T17:00:00Z", + "created": 200 + } + } + ] + } + """; + + Rule? deserializedRule = JsonConvert.DeserializeObject(serializedRule); + + Assert.That(deserializedRule, Is.Not.Null); + Assert.That(deserializedRule!.RuleTimes.Count, Is.EqualTo(1)); + Assert.That(deserializedRule.RuleTimes[0].Id, Is.EqualTo(10)); + Assert.That(deserializedRule.RuleTimes[0].RuleId, Is.EqualTo(1001)); + Assert.That(deserializedRule.RuleTimes[0].TimeObjId, Is.EqualTo(55)); + Assert.That(deserializedRule.RuleTimes[0].Created, Is.EqualTo(200)); + Assert.That(deserializedRule.RuleTimes[0].Removed, Is.Null); + Assert.That(deserializedRule.RuleTimes[0].TimeObj, Is.Not.Null); + TimeObject timeObject = deserializedRule.RuleTimes[0].TimeObj!; + Assert.That(timeObject.Id, Is.EqualTo(55)); + Assert.That(timeObject.Name, Is.EqualTo("Office Hours")); + } + } +} diff --git a/roles/tests-unit/files/FWO.Test/RuleExpiryCheckTest.cs b/roles/tests-unit/files/FWO.Test/RuleExpiryCheckTest.cs new file mode 100644 index 0000000000..5098f394d4 --- /dev/null +++ b/roles/tests-unit/files/FWO.Test/RuleExpiryCheckTest.cs @@ -0,0 +1,576 @@ +using FWO.Api.Client.Queries; +using FWO.Basics; +using FWO.Data; +using FWO.Middleware.Server; +using NUnit.Framework; +using NUnit.Framework.Legacy; +using System.Collections; +using System.Reflection; + +namespace FWO.Test +{ + [TestFixture] + [Parallelizable] + internal class RuleExpiryCheckTest + { + [Test] + public async Task CheckRuleExpiry_SendsNotification_WhenExpiredRuleIsDue() + { + RuleExpiryCheckTestApiConn apiConnection = new(); + apiConnection.Notifications = + [ + CreateRuleTimerNotification(1) + ]; + apiConnection.ExpiredRuleEntries = + [ + new ExpiredRuleEntryInput + { + OwnerId = 1, + OwnerName = "Owner1", + OwnerExtAppId = "APP1", + RuleId = 1001, + RuleUid = "uid-1001", + RuleName = "Allow A", + RuleNumber = 10, + ManagementId = 5, + RulebaseName = "RB1", + SourceShort = "SrcShort", + SourceLong = "SrcLong", + DestinationShort = "DstShort", + DestinationLong = "DstLong", + ServiceShort = "SvcShort", + ServiceLong = "SvcLong", + CustomFields = "{\"field-2\":\"CHG-1001\"}", + LastHit = DateTime.Now.AddDays(-5), + RuleTimes = [new() { TimeObjId = 11, TimeObjName = "TO-1", EndTime = DateTime.Now.AddDays(-2) }] + } + ]; + + RuleExpiryCheck check = new(apiConnection, CreateGlobalConfig()); + + int sentEmails = await check.CheckRuleExpiry(); + + ClassicAssert.AreEqual(1, sentEmails); + ClassicAssert.AreEqual(1, apiConnection.LastUpdatedNotificationIdCount); + } + + [Test] + public async Task CheckRuleExpiry_DoesNotSend_WhenNotificationIsNotDue() + { + RuleExpiryCheckTestApiConn apiConnection = new(); + FwoNotification notification = CreateRuleTimerNotification(1); + notification.LastSent = DateTime.Now; + apiConnection.Notifications = [notification]; + apiConnection.ExpiredRuleEntries = + [ + new ExpiredRuleEntryInput + { + OwnerId = 1, + OwnerName = "Owner1", + OwnerExtAppId = "APP1", + RuleId = 1002, + RuleUid = "uid-1002", + RuleName = "Allow B", + RuleNumber = 20, + ManagementId = 5, + RulebaseName = "RB1", + SourceShort = "SrcShort", + SourceLong = "SrcLong", + DestinationShort = "DstShort", + DestinationLong = "DstLong", + ServiceShort = "SvcShort", + ServiceLong = "SvcLong", + CustomFields = "{\"field-2\":\"CHG-1002\"}", + LastHit = DateTime.Now.AddDays(-7), + RuleTimes = [new() { TimeObjId = 12, TimeObjName = "TO-2", EndTime = DateTime.Now.AddDays(-1) }] + } + ]; + + RuleExpiryCheck check = new(apiConnection, CreateGlobalConfig()); + + int sentEmails = await check.CheckRuleExpiry(); + + ClassicAssert.AreEqual(0, sentEmails); + ClassicAssert.AreEqual(0, apiConnection.LastUpdatedNotificationIdCount); + } + + [Test] + public async Task CheckRuleExpiry_AggregatesByOwner_AndAppliesOwnerScopedNotifications() + { + RuleExpiryCheckTestApiConn apiConnection = new(); + apiConnection.Notifications = + [ + CreateRuleTimerNotification(1), + CreateRuleTimerNotification(2, ownerId: 2) + ]; + apiConnection.ExpiredRuleEntries = + [ + new ExpiredRuleEntryInput + { + OwnerId = 1, + OwnerName = "Owner1", + OwnerExtAppId = "APP1", + RuleId = 2001, + RuleUid = "uid-2001", + RuleName = "Allow C", + RuleNumber = 30, + ManagementId = 8, + RulebaseName = "RB2", + SourceShort = "S1", + SourceLong = "SL1", + DestinationShort = "D1", + DestinationLong = "DL1", + ServiceShort = "V1", + ServiceLong = "VL1", + CustomFields = "{\"field-2\":\"CHG-2001\"}", + LastHit = DateTime.Now.AddDays(-4), + RuleTimes = [new() { TimeObjId = 21, TimeObjName = "TO-3", EndTime = DateTime.Now.AddDays(-3) }] + }, + new ExpiredRuleEntryInput + { + OwnerId = 2, + OwnerName = "Owner2", + OwnerExtAppId = "APP2", + RuleId = 2002, + RuleUid = "uid-2002", + RuleName = "Allow D", + RuleNumber = 31, + ManagementId = 8, + RulebaseName = "RB2", + SourceShort = "S2", + SourceLong = "SL2", + DestinationShort = "D2", + DestinationLong = "DL2", + ServiceShort = "V2", + ServiceLong = "VL2", + CustomFields = "{\"field-2\":\"CHG-2002\"}", + LastHit = DateTime.Now.AddDays(-4), + RuleTimes = [new() { TimeObjId = 22, TimeObjName = "TO-4", EndTime = DateTime.Now.AddDays(-3) }] + } + ]; + + RuleExpiryCheck check = new(apiConnection, CreateGlobalConfig()); + + int sentEmails = await check.CheckRuleExpiry(); + + ClassicAssert.AreEqual(3, sentEmails, "Expected one global mail per owner plus one owner-scoped mail for owner 2."); + ClassicAssert.AreEqual(2, apiConnection.LastUpdatedNotificationIdCount, "Only unique notification ids should be marked as sent."); + } + + [Test] + public void ParseRuleExpiryInitiatorKeys_ParsesAndNormalizes_AndHandlesInvalidInput() + { + MethodInfo? parseMethod = typeof(RuleExpiryCheck).GetMethod("ParseRuleExpiryInitiatorKeys", BindingFlags.NonPublic | BindingFlags.Static); + ClassicAssert.IsNotNull(parseMethod, "Expected private method ParseRuleExpiryInitiatorKeys."); + + Dictionary parsed = (Dictionary)(parseMethod!.Invoke(null, ["{ \" User \": \"Text A\", \"nsb\": \"Text B\" }"]) ?? new Dictionary()); + ClassicAssert.AreEqual(2, parsed.Count); + ClassicAssert.AreEqual("Text A", parsed["user"]); + ClassicAssert.AreEqual("Text B", parsed["nsb"]); + + Dictionary parsedInvalid = (Dictionary)(parseMethod.Invoke(null, ["{ invalid json }"]) ?? new Dictionary()); + ClassicAssert.AreEqual(0, parsedInvalid.Count); + } + + [Test] + public void GetLocalizedIntervalUnit_ReturnsConfiguredTexts() + { + SimulatedGlobalConfig config = CreateGlobalConfig(); + config.DefaultLanguage = "English"; + config.NotificationLanguage = "German"; + config.GermanTranslate["Days"] = "Tage"; + config.GermanTranslate["Weeks"] = "Wochen"; + config.GermanTranslate["Months"] = "Monate"; + + RuleExpiryCheck check = new(new RuleExpiryCheckTestApiConn(), config); + MethodInfo? getLocalizedMethod = typeof(RuleExpiryCheck).GetMethod("GetLocalizedIntervalUnit", BindingFlags.NonPublic | BindingFlags.Instance); + ClassicAssert.IsNotNull(getLocalizedMethod, "Expected private method GetLocalizedIntervalUnit."); + + string days = (string)(getLocalizedMethod!.Invoke(check, [SchedulerInterval.Days]) ?? ""); + string weeks = (string)(getLocalizedMethod.Invoke(check, [SchedulerInterval.Weeks]) ?? ""); + string months = (string)(getLocalizedMethod.Invoke(check, [SchedulerInterval.Months]) ?? ""); + + ClassicAssert.AreEqual("Tage", days); + ClassicAssert.AreEqual("Wochen", weeks); + ClassicAssert.AreEqual("Monate", months); + } + + [Test] + public void GetLocalizedIntervalUnit_FallsBackToDefaultLanguage_WhenNotificationLanguageIsUnset() + { + SimulatedGlobalConfig config = CreateGlobalConfig(); + config.DefaultLanguage = "German"; + config.NotificationLanguage = ""; + config.GermanTranslate["Days"] = "Tage"; + + RuleExpiryCheck check = new(new RuleExpiryCheckTestApiConn(), config); + MethodInfo? getLocalizedMethod = typeof(RuleExpiryCheck).GetMethod("GetLocalizedIntervalUnit", BindingFlags.NonPublic | BindingFlags.Instance); + ClassicAssert.IsNotNull(getLocalizedMethod, "Expected private method GetLocalizedIntervalUnit."); + + string days = (string)(getLocalizedMethod!.Invoke(check, [SchedulerInterval.Days]) ?? ""); + + ClassicAssert.AreEqual("Tage", days); + } + + [Test] + public void DetermineExpiryInitiator_UsesSuffixMapping() + { + Type? ruleWithExpiryType = typeof(RuleExpiryCheck).GetNestedType("RuleWithExpiry", BindingFlags.NonPublic); + ClassicAssert.IsNotNull(ruleWithExpiryType, "Expected private nested type RuleWithExpiry."); + + MethodInfo? determineMethod = ruleWithExpiryType!.GetMethod("DetermineExpiryInitiator", BindingFlags.NonPublic | BindingFlags.Static); + ClassicAssert.IsNotNull(determineMethod, "Expected private method DetermineExpiryInitiator."); + + IReadOnlyDictionary initiatorTexts = new Dictionary + { + ["user"] = "by user", + ["nsb"] = "by nsb" + }; + + string resultUser = (string)(determineMethod!.Invoke(null, ["my-time-user", initiatorTexts]) ?? ""); + string resultNsb = (string)(determineMethod.Invoke(null, ["my-time-nsb", initiatorTexts]) ?? ""); + string resultUnknown = (string)(determineMethod.Invoke(null, ["my-time-other", initiatorTexts]) ?? ""); + + ClassicAssert.AreEqual("by user", resultUser); + ClassicAssert.AreEqual("by nsb", resultNsb); + ClassicAssert.AreEqual("", resultUnknown); + } + + [Test] + public void BuildRuleExpiryBodies_ReplacesPlaceholders_AndSeparatesTextFromHtml() + { + SimulatedGlobalConfig config = CreateGlobalConfig(); + config.DefaultLanguage = "English"; + config.NotificationLanguage = "German"; + config.GermanTranslate["uid"] = "Kennung"; + config.GermanTranslate["name"] = "Name"; + config.GermanTranslate["source"] = "Quelle"; + config.GermanTranslate["destination"] = "Ziel"; + config.GermanTranslate["service"] = "Dienst"; + config.GermanTranslate["change_id"] = "Change-ID"; + config.GermanTranslate["last_hit"] = "Letzter Treffer"; + config.GermanTranslate["generated_on"] = "Erstellt am"; + config.GermanTranslate["owners"] = "Owner"; + + RuleExpiryCheck check = new(new RuleExpiryCheckTestApiConn(), config); + MethodInfo? buildTextBodyMethod = typeof(RuleExpiryCheck).GetMethod("BuildRuleTextBody", BindingFlags.NonPublic | BindingFlags.Instance); + MethodInfo? buildHtmlBodyMethod = typeof(RuleExpiryCheck).GetMethod("BuildRuleHtmlBody", BindingFlags.NonPublic | BindingFlags.Instance); + ClassicAssert.IsNotNull(buildTextBodyMethod, "Expected protected method BuildRuleTextBody."); + ClassicAssert.IsNotNull(buildHtmlBodyMethod, "Expected protected method BuildRuleHtmlBody."); + MethodInfo closedBuildTextBodyMethod = (buildTextBodyMethod ?? throw new InvalidOperationException("BuildRuleTextBody method not found.")) + .MakeGenericMethod(typeof(RuleExpiryCheck).GetNestedType("RuleExpiryInfo", BindingFlags.NonPublic) + ?? throw new InvalidOperationException("RuleExpiryInfo type not found.")); + MethodInfo closedBuildHtmlBodyMethod = (buildHtmlBodyMethod ?? throw new InvalidOperationException("BuildRuleHtmlBody method not found.")) + .MakeGenericMethod(typeof(RuleExpiryCheck).GetNestedType("RuleExpiryInfo", BindingFlags.NonPublic) + ?? throw new InvalidOperationException("RuleExpiryInfo type not found.")); + + Type? ruleExpiryInfoType = typeof(RuleExpiryCheck).GetNestedType("RuleExpiryInfo", BindingFlags.NonPublic); + ClassicAssert.IsNotNull(ruleExpiryInfoType, "Expected private nested type RuleExpiryInfo."); + Type resolvedRuleExpiryInfoType = ruleExpiryInfoType ?? throw new InvalidOperationException("RuleExpiryInfo type not found."); + + Rule rule = new() + { + Uid = "uid-1", + Name = "rule-1", + Source = "src", + Destination = "dst", + Service = "svc", + CustomFields = "{\"field2\":\"chg-1\"}", + Metadata = new RuleMetadata { LastHit = DateTime.Today } + }; + object ruleEntry = Activator.CreateInstance(resolvedRuleExpiryInfoType, [rule]) ?? throw new InvalidOperationException("Could not create RuleExpiryInfo."); + resolvedRuleExpiryInfoType.GetProperty("EndTime")?.SetValue(ruleEntry, DateTime.Today); + resolvedRuleExpiryInfoType.GetProperty("ExpiryInitiator")?.SetValue(ruleEntry, "init"); + + Type listType = typeof(List<>).MakeGenericType(resolvedRuleExpiryInfoType); + IList entries = (IList)(Activator.CreateInstance(listType) ?? throw new InvalidOperationException("Could not create entry list.")); + entries.Add(ruleEntry); + + FwoOwner owner = new() { Name = "OwnerX", ExtAppId = "APPX" }; + string bodyTemplate = $"Hello @@APPNAME@@ @@APPID@@ @@TIME_INTERVAL@@ {Placeholder.RULE_TABLE} Bye"; + string intervalText = "2 Weeks"; + + string textBody = (string?)(closedBuildTextBodyMethod.Invoke(check, [owner, bodyTemplate, intervalText, entries, null, null])) ?? ""; + string htmlBody = (string?)(closedBuildHtmlBodyMethod.Invoke(check, [owner, bodyTemplate, intervalText, entries, null, null, null])) ?? ""; + + ClassicAssert.IsTrue(textBody.Contains("Hello OwnerX APPX 2 Weeks")); + ClassicAssert.IsFalse(textBody.Contains("")); + ClassicAssert.IsTrue(textBody.Contains("uid")); + ClassicAssert.IsTrue(textBody.Contains("Bye")); + ClassicAssert.IsFalse(textBody.Contains("@@APPNAME@@")); + ClassicAssert.IsFalse(textBody.Contains("@@APPID@@")); + ClassicAssert.IsFalse(textBody.Contains("@@TIME_INTERVAL@@")); + ClassicAssert.IsFalse(textBody.Contains(Placeholder.RULE_TABLE)); + ClassicAssert.IsTrue(textBody.Contains("Kennung")); + + ClassicAssert.IsTrue(htmlBody.Contains("Hello OwnerX APPX 2 Weeks")); + ClassicAssert.IsTrue(htmlBody.Contains("

                      Bye

                      ") || htmlBody.Contains("

                      Bye

                      ")); + ClassicAssert.IsFalse(htmlBody.Contains("@@APPNAME@@")); + ClassicAssert.IsFalse(htmlBody.Contains("@@APPID@@")); + ClassicAssert.IsFalse(htmlBody.Contains("@@TIME_INTERVAL@@")); + ClassicAssert.IsFalse(htmlBody.Contains(Placeholder.RULE_TABLE)); + ClassicAssert.IsTrue(htmlBody.Contains("Kennung")); + } + + [Test] + public void BuildRuleExpiryBodies_RenderResolvedGroupMembers_WhenFlatDataIsAvailable() + { + SimulatedGlobalConfig config = CreateGlobalConfig(); + config.DefaultLanguage = "English"; + + RuleExpiryCheck check = new(new RuleExpiryCheckTestApiConn(), config); + MethodInfo? buildTextBodyMethod = typeof(RuleExpiryCheck).GetMethod("BuildRuleTextBody", BindingFlags.NonPublic | BindingFlags.Instance); + MethodInfo? buildHtmlBodyMethod = typeof(RuleExpiryCheck).GetMethod("BuildRuleHtmlBody", BindingFlags.NonPublic | BindingFlags.Instance); + ClassicAssert.IsNotNull(buildTextBodyMethod, "Expected protected method BuildRuleTextBody."); + ClassicAssert.IsNotNull(buildHtmlBodyMethod, "Expected protected method BuildRuleHtmlBody."); + + Type ruleExpiryInfoType = typeof(RuleExpiryCheck).GetNestedType("RuleExpiryInfo", BindingFlags.NonPublic) + ?? throw new InvalidOperationException("RuleExpiryInfo type not found."); + MethodInfo closedBuildTextBodyMethod = (buildTextBodyMethod ?? throw new InvalidOperationException("BuildRuleTextBody method not found.")) + .MakeGenericMethod(ruleExpiryInfoType); + MethodInfo closedBuildHtmlBodyMethod = (buildHtmlBodyMethod ?? throw new InvalidOperationException("BuildRuleHtmlBody method not found.")) + .MakeGenericMethod(ruleExpiryInfoType); + + NetworkObject srcMember = new() + { + Id = 11, + Name = "SrcMember", + IP = "10.0.0.1", + Type = new NetworkObjectType { Name = ObjectType.Host } + }; + NetworkObject srcGroup = new() + { + Id = 1, + Name = "SrcGroup", + Type = new NetworkObjectType { Name = ObjectType.Group }, + ObjectGroupFlats = [new GroupFlat { Object = srcMember }] + }; + NetworkObject dstMember = new() + { + Id = 12, + Name = "DstMember", + IP = "10.0.0.2", + Type = new NetworkObjectType { Name = ObjectType.Host } + }; + NetworkObject dstGroup = new() + { + Id = 2, + Name = "DstGroup", + Type = new NetworkObjectType { Name = ObjectType.Group }, + ObjectGroupFlats = [new GroupFlat { Object = dstMember }] + }; + NetworkService svcMember = new() + { + Id = 13, + Name = "SvcMember", + DestinationPort = 443, + DestinationPortEnd = 443, + ProtoId = 6, + Protocol = new NetworkProtocol { Id = 6, Name = "TCP" } + }; + NetworkService svcGroup = new() + { + Id = 3, + Name = "SvcGroup", + Type = new NetworkServiceType { Name = ObjectType.Group }, + ServiceGroupFlats = [new GroupFlat { Object = svcMember }] + }; + + Rule rule = new() + { + Uid = "uid-group", + Name = "rule-group", + CustomFields = "{\"field2\":\"chg-group\"}", + Metadata = new RuleMetadata { LastHit = DateTime.Today }, + Froms = [new NetworkLocation(new NetworkUser(), srcGroup)], + Tos = [new NetworkLocation(new NetworkUser(), dstGroup)], + Services = [new ServiceWrapper { Content = svcGroup }] + }; + object ruleEntry = Activator.CreateInstance(ruleExpiryInfoType, [rule]) ?? throw new InvalidOperationException("Could not create RuleExpiryInfo."); + ruleExpiryInfoType.GetProperty("EndTime")?.SetValue(ruleEntry, DateTime.Today); + ruleExpiryInfoType.GetProperty("ExpiryInitiator")?.SetValue(ruleEntry, "init"); + + Type listType = typeof(List<>).MakeGenericType(ruleExpiryInfoType); + IList entries = (IList)(Activator.CreateInstance(listType) ?? throw new InvalidOperationException("Could not create entry list.")); + entries.Add(ruleEntry); + + FwoOwner owner = new() { Name = "OwnerX", ExtAppId = "APPX" }; + string bodyTemplate = $"Hello {Placeholder.RULE_TABLE}"; + + string textBody = (string?)(closedBuildTextBodyMethod.Invoke(check, [owner, bodyTemplate, "", entries, null, null])) ?? ""; + string htmlBody = (string?)(closedBuildHtmlBodyMethod.Invoke(check, [owner, bodyTemplate, "", entries, null, null, null])) ?? ""; + + ClassicAssert.IsTrue(textBody.Contains("SrcMember"), "Expected source to show resolved group member."); + ClassicAssert.IsTrue(textBody.Contains("DstMember"), "Expected destination to show resolved group member."); + ClassicAssert.IsTrue(textBody.Contains("SvcMember"), "Expected service to show resolved group member."); + ClassicAssert.IsFalse(textBody.Contains("SrcGroup"), "Expected source group wrapper to be hidden in resolved output."); + ClassicAssert.IsFalse(textBody.Contains("DstGroup"), "Expected destination group wrapper to be hidden in resolved output."); + ClassicAssert.IsFalse(textBody.Contains("SvcGroup"), "Expected service group wrapper to be hidden in resolved output."); + ClassicAssert.IsTrue(htmlBody.Contains("SrcMember"), "Expected HTML source to show resolved group member."); + ClassicAssert.IsTrue(htmlBody.Contains("DstMember"), "Expected HTML destination to show resolved group member."); + ClassicAssert.IsTrue(htmlBody.Contains("SvcMember"), "Expected HTML service to show resolved group member."); + } + + private static FwoNotification CreateRuleTimerNotification(int id, int? ownerId = null) + { + return new FwoNotification + { + Id = id, + OwnerId = ownerId, + Deadline = NotificationDeadline.RuleExpiry, + RecipientTo = EmailRecipientOption.OtherAddresses, + EmailAddressTo = "x@y.de", + EmailSubject = "rule expiry", + RepeatIntervalAfterDeadline = SchedulerInterval.Days, + InitialOffsetAfterDeadline = 0, + RepeatOffsetAfterDeadline = 1, + RepetitionsAfterDeadline = 10 + }; + } + + private static SimulatedGlobalConfig CreateGlobalConfig() + { + return new SimulatedGlobalConfig + { + UseDummyEmailAddress = true, + DummyEmailAddress = "x@y.de", + EmailServerAddress = "127.0.0.1", + EmailPort = 1 + }; + } + + private sealed class RuleExpiryCheckTestApiConn : SimulatedApiConnection + { + public List Notifications { get; set; } = []; + public List ExpiredRuleEntries { get; set; } = []; + public int LastUpdatedNotificationIdCount { get; private set; } + + public override Task SendQueryAsync(string query, object? variables = null, string? operationName = null) + { + Type responseType = typeof(QueryResponseType); + + if (responseType == typeof(List) && query == AuthQueries.getLdapConnections) + { + List internalLdaps = + [ + new Ldap + { + Address = "127.0.0.1", + Port = 1, + UserSearchPath = "uid=intuser2,ou=users,ou=tenant2,dc=fworch,dc=internal", + GroupSearchPath = "ou=groups,dc=fworch,dc=internal" + } + ]; + return Task.FromResult((QueryResponseType)(object)internalLdaps); + } + + if (responseType == typeof(List) && query == NotificationQueries.getNotifications) + { + return Task.FromResult((QueryResponseType)(object)Notifications); + } + + if (responseType == typeof(ReturnId) && query == NotificationQueries.updateNotificationsLastSent) + { + LastUpdatedNotificationIdCount = CountIds(variables); + return Task.FromResult((QueryResponseType)(object)new ReturnId { AffectedRows = LastUpdatedNotificationIdCount }); + } + + if (query == RuleQueries.getTimeBasedRulesByOwner && responseType.IsGenericType && responseType.GetGenericTypeDefinition() == typeof(List<>)) + { + object result = BuildExpiredRuleResponse(responseType); + return Task.FromResult((QueryResponseType)result); + } + + throw new NotImplementedException($"Unhandled query: {query}"); + } + + private static int CountIds(object? variables) + { + object? ids = variables?.GetType().GetProperty("ids")?.GetValue(variables); + return ids is ICollection coll ? coll.Count : 0; + } + + private object BuildExpiredRuleResponse(Type listType) + { + IList resultList = (IList)(Activator.CreateInstance(listType) ?? throw new InvalidOperationException("Could not create response list.")); + Type rowType = listType.GetGenericArguments()[0]; + Type ruleType = rowType.GetProperty("Rule")?.PropertyType ?? throw new InvalidOperationException("Missing Rule type."); + + foreach (ExpiredRuleEntryInput entry in ExpiredRuleEntries) + { + object row = Activator.CreateInstance(rowType) ?? throw new InvalidOperationException("Could not create response row."); + rowType.GetProperty("Owner")?.SetValue(row, new FwoOwner { Id = entry.OwnerId, Name = entry.OwnerName, ExtAppId = entry.OwnerExtAppId }); + + object rule = Activator.CreateInstance(ruleType) ?? throw new InvalidOperationException("Could not create rule."); + ruleType.GetProperty("RuleId")?.SetValue(rule, entry.RuleId); + ruleType.GetProperty("RuleUid")?.SetValue(rule, entry.RuleUid); + ruleType.GetProperty("RuleName")?.SetValue(rule, entry.RuleName); + ruleType.GetProperty("RuleNumber")?.SetValue(rule, entry.RuleNumber); + ruleType.GetProperty("ManagementId")?.SetValue(rule, entry.ManagementId); + ruleType.GetProperty("SourceShort")?.SetValue(rule, entry.SourceShort); + ruleType.GetProperty("SourceLong")?.SetValue(rule, entry.SourceLong); + ruleType.GetProperty("DestinationShort")?.SetValue(rule, entry.DestinationShort); + ruleType.GetProperty("DestinationLong")?.SetValue(rule, entry.DestinationLong); + ruleType.GetProperty("ServiceShort")?.SetValue(rule, entry.ServiceShort); + ruleType.GetProperty("ServiceLong")?.SetValue(rule, entry.ServiceLong); + ruleType.GetProperty("CustomFields")?.SetValue(rule, entry.CustomFields); + ruleType.GetProperty("Metadata")?.SetValue(rule, new RuleMetadata { LastHit = entry.LastHit }); + ruleType.GetProperty("Rulebase")?.SetValue(rule, new Rulebase { Name = entry.RulebaseName }); + + PropertyInfo? ruleTimesProp = ruleType.GetProperty("RuleTimes"); + Type ruleTimesListType = ruleTimesProp?.PropertyType ?? throw new InvalidOperationException("Missing RuleTimes list type."); + IList ruleTimes = (IList)(Activator.CreateInstance(ruleTimesListType) ?? throw new InvalidOperationException("Could not create RuleTimes list.")); + foreach (ExpiredTimeInput time in entry.RuleTimes) + { + ruleTimes.Add(new RuleTime + { + TimeObjId = time.TimeObjId, + TimeObj = new TimeObject + { + Id = time.TimeObjId, + Name = time.TimeObjName, + EndTime = time.EndTime + } + }); + } + ruleTimesProp.SetValue(rule, ruleTimes); + + rowType.GetProperty("Rule")?.SetValue(row, rule); + resultList.Add(row); + } + return resultList; + } + } + + private sealed class ExpiredRuleEntryInput + { + public int OwnerId { get; set; } + public string OwnerName { get; set; } = ""; + public string OwnerExtAppId { get; set; } = ""; + public long RuleId { get; set; } + public string RuleUid { get; set; } = ""; + public string RuleName { get; set; } = ""; + public int RuleNumber { get; set; } + public int ManagementId { get; set; } + public string RulebaseName { get; set; } = ""; + public string SourceShort { get; set; } = ""; + public string SourceLong { get; set; } = ""; + public string DestinationShort { get; set; } = ""; + public string DestinationLong { get; set; } = ""; + public string ServiceShort { get; set; } = ""; + public string ServiceLong { get; set; } = ""; + public string CustomFields { get; set; } = ""; + public DateTime? LastHit { get; set; } + public List RuleTimes { get; set; } = []; + } + + private sealed class ExpiredTimeInput + { + public long TimeObjId { get; set; } + public string TimeObjName { get; set; } = ""; + public DateTime EndTime { get; set; } + } + } +} diff --git a/roles/tests-unit/files/FWO.Test/RuleTreeBuilderTest.cs b/roles/tests-unit/files/FWO.Test/RuleTreeBuilderTest.cs new file mode 100644 index 0000000000..dbcc3e1c91 --- /dev/null +++ b/roles/tests-unit/files/FWO.Test/RuleTreeBuilderTest.cs @@ -0,0 +1,214 @@ +using System.Collections.Generic; +using System.Linq; +using FWO.Services.RuleTreeBuilder; +using FWO.Data; +using FWO.Data.Report; +using FWO.Basics; +using NUnit.Framework; + +namespace FWO.Test +{ + [TestFixture] + internal class RuleTreeBuilderTest + { + private RuleTreeBuilder _ruleTreeBuilder = default!; + + [SetUp] + public void SetUpTestMethod() + { + _ruleTreeBuilder = new RuleTreeBuilder(); + } + + [Test] + public void BuildRuleTree_OrderedLayerOnly_ReturnsAllRules() + { + // Arrange + RulebaseReport[] rulebases = + [ + Rulebase(1, "Layer-1", 10, 11) + ]; + RulebaseLink[] links = + [ + OrderedLayerInitialLink(gatewayId: 1, nextRulebaseId: 1) + ]; + + // Act + List resultRules = _ruleTreeBuilder.BuildRuleTree(rulebases, links, 1, 1).Where(rule => rule.SectionHeader == "").ToList(); + + // Assert + Assert.That(resultRules.Count == 2); + Assert.That(_ruleTreeBuilder.RuleTree.ElementsFlat.Count(element => element.IsRule) == 2); + Assert.That(_ruleTreeBuilder.RuleTree.ElementsFlat.Count(element => element.IsSectionHeader) == 0); + Assert.That(FindOrderedLayerRoots(_ruleTreeBuilder.RuleTree).Count == 1); + } + + [Test] + public void BuildRuleTree_SectionAndConcatenationLinks_CreateSectionHeaders() + { + // Arrange + RulebaseReport[] rulebases = + [ + Rulebase(1, "Layer-1", 10), + Rulebase(2, "Section-A", 20), + Rulebase(3, "Concat-B", 30) + ]; + RulebaseLink[] links = + [ + OrderedLayerInitialLink(gatewayId: 1, nextRulebaseId: 1), + SectionLink(gatewayId: 1, fromRulebaseId: 1, nextRulebaseId: 2), + ConcatenationLink(gatewayId: 1, fromRulebaseId: 2, nextRulebaseId: 3) + ]; + + // Act + List resultRules = _ruleTreeBuilder.BuildRuleTree(rulebases, links, 1, 1); + + // Assert + Assert.That(resultRules.Count == 6); + Assert.That(_ruleTreeBuilder.RuleTree.ElementsFlat.Count(element => element.IsRule) == 3); + Assert.That(_ruleTreeBuilder.RuleTree.ElementsFlat.Count(element => element.IsSectionHeader) == 2); + Assert.That(FindOrderedLayerRoots(_ruleTreeBuilder.RuleTree).Count == 1); + } + + [Test] + public void BuildRuleTree_InlineLayerFromRule_AddsInlineLayerAndRules() + { + // Arrange + RulebaseReport[] rulebases = + [ + Rulebase(1, "Layer-1", 10, 11), + Rulebase(2, "Inline-1", 20, 21) + ]; + RulebaseLink[] links = + [ + OrderedLayerInitialLink(gatewayId: 1, nextRulebaseId: 1), + InlineLayerLink(gatewayId: 1, fromRulebaseId: 1, fromRuleId: 10, nextRulebaseId: 2) + ]; + + // Act + List resultRules = _ruleTreeBuilder.BuildRuleTree(rulebases, links, 1, 1).Where(rule => rule.SectionHeader == "").ToList(); + + // Assert + Assert.That(resultRules.Count == 4); + Assert.That(_ruleTreeBuilder.RuleTree.ElementsFlat.Count(element => element.IsRule) == 4); + } + + [Test] + public void BuildRuleTree_InlineLayerWithSection_AddsSectionHeader() + { + // Arrange + RulebaseReport[] rulebases = + [ + Rulebase(1, "Layer-1", 10), + Rulebase(2, "Inline-1", 20), + Rulebase(3, "Inline-Section", 30) + ]; + RulebaseLink[] links = + [ + OrderedLayerInitialLink(gatewayId: 1, nextRulebaseId: 1), + InlineLayerLink(gatewayId: 1, fromRulebaseId: 1, fromRuleId: 10, nextRulebaseId: 2), + SectionLink(gatewayId: 1, fromRulebaseId: 2, nextRulebaseId: 3) + ]; + + // Act + List resultRules = _ruleTreeBuilder.BuildRuleTree(rulebases, links, 1, 1).Where(rule => rule.SectionHeader == "").ToList(); + + // Assert + Assert.That(resultRules.Count == 3); + Assert.That(_ruleTreeBuilder.RuleTree.ElementsFlat.Count(element => element.IsRule) == 3); + Assert.That(_ruleTreeBuilder.RuleTree.ElementsFlat.Count(element => element.IsSectionHeader) == 1); + } + + private static RulebaseReport Rulebase(int id, string name, params int[] ruleIds) + { + return new RulebaseReport + { + Id = id, + Name = name, + Rules = ruleIds.Select(ruleId => new Rule { Id = ruleId, RulebaseId = id, Name = $"R-{ruleId}" }).ToArray() + }; + } + + private static RulebaseLink OrderedLayerInitialLink(int gatewayId, int nextRulebaseId) + { + return new RulebaseLink + { + GatewayId = gatewayId, + FromRulebaseId = null, + FromRuleId = null, + NextRulebaseId = nextRulebaseId, + LinkType = 2, + IsInitial = true, + IsGlobal = false, + IsSection = false + }; + } + + private static RulebaseLink SectionLink(int gatewayId, int fromRulebaseId, int nextRulebaseId) + { + return new RulebaseLink + { + GatewayId = gatewayId, + FromRulebaseId = fromRulebaseId, + FromRuleId = null, + NextRulebaseId = nextRulebaseId, + LinkType = 4, + IsInitial = false, + IsGlobal = false, + IsSection = true + }; + } + + private static RulebaseLink ConcatenationLink(int gatewayId, int fromRulebaseId, int nextRulebaseId) + { + return new RulebaseLink + { + GatewayId = gatewayId, + FromRulebaseId = fromRulebaseId, + FromRuleId = null, + NextRulebaseId = nextRulebaseId, + LinkType = 4, + IsInitial = false, + IsGlobal = false, + IsSection = false + }; + } + + private static RulebaseLink InlineLayerLink(int gatewayId, int fromRulebaseId, int fromRuleId, int nextRulebaseId) + { + return new RulebaseLink + { + GatewayId = gatewayId, + FromRulebaseId = fromRulebaseId, + FromRuleId = fromRuleId, + NextRulebaseId = nextRulebaseId, + LinkType = 3, + IsInitial = false, + IsGlobal = false, + IsSection = false + }; + } + + private static List FindOrderedLayerRoots(RuleTreeItem root) + { + List results = new(); + Queue queue = new(); + queue.Enqueue(root); + + while (queue.Count > 0) + { + RuleTreeItem current = queue.Dequeue(); + if (current.IsOrderedLayerHeader) + { + results.Add(current); + } + + foreach (ITreeItem child in current.Children) + { + queue.Enqueue((RuleTreeItem)child); + } + } + + return results; + } + } +} diff --git a/roles/tests-unit/files/FWO.Test/RuleViewDataTest.cs b/roles/tests-unit/files/FWO.Test/RuleViewDataTest.cs new file mode 100644 index 0000000000..50d7b3b39e --- /dev/null +++ b/roles/tests-unit/files/FWO.Test/RuleViewDataTest.cs @@ -0,0 +1,275 @@ +using NUnit.Framework; +using System; +using System.Collections.Generic; +using System.Linq; +using FWO.Services.RuleTreeBuilder; +using FWO.Data; +using FWO.Data.Report; +using FWO.Report.Data.ViewData; +using FWO.Report; +using FWO.Ui.Display; +using FWO.Config.Api; + +namespace FWO.Test +{ + [TestFixture] + internal class RuleViewDataTest + { + [Test] + public void ExtractCustomFieldValue_NoMatchingKey_ReturnsDefault() + { + var rule = new Rule + { + CustomFields = "{'field-1':'abc'}" + }; + + var result = CustomFieldResolver.ExtractCustomFieldValue(rule, "[\"field-2\",\"field-3\"]", out var errorMessage); + + Assert.That(result, Is.Null); + Assert.That(errorMessage, Is.Null); + } + + [Test] + public void ExtractCustomFieldValue_EmptyCustomFields_ReturnsDefault() + { + var rule = new Rule + { + CustomFields = "" + }; + + var result = CustomFieldResolver.ExtractCustomFieldValue(rule, "[\"field-2\"]", out var errorMessage); + + Assert.That(result, Is.Null); + Assert.That(errorMessage, Is.Null); + } + + [Test] + public void GetFromCustomField_KeyOne_ReturnsCorrectValue() + { + RuleViewData rvd = new RuleViewData(); + Rule rule = new Rule + { + CustomFields = "{'field-2':'Change123','field-3':'Ado456'}" + }; + + string result = CustomFieldResolver.ExtractCustomFieldValue(rule, "[\"field-2\",\"Datum-Regelpruefung\"]", out _) ?? ""; + + Assert.That("Change123".Equals(result)); + } + + [Test] + public void GetFromCustomField_KeyTwo_ReturnsCorrectValue() + { + RuleViewData rvd = new RuleViewData(); + Rule rule = new Rule + { + CustomFields = "{'Datum-Regelpruefung':'Change123','AdoIT':'Ado456'}" + }; + + string result = CustomFieldResolver.ExtractCustomFieldValue(rule, "[\"field-2\",\"Datum-Regelpruefung\"]", out _) ?? ""; + + Assert.That("Change123".Equals(result)); + } + + [Test] + public void GetFromCustomField_Example_ReturnsCorrectValue() + { + RuleViewData rvd = new RuleViewData(); + Rule rule = new Rule + { + CustomFields = "{'AdoIT': \"Infr-AdoIT:X\", 'Datum-Regelpruefung': 'dd.mm.yyyy'}" + }; + + string resultDatumRegelpruefung = CustomFieldResolver.ExtractCustomFieldValue(rule, "[\"field-2\",\"Datum-Regelpruefung\"]", out _) ?? ""; + string resultAdoItId = CustomFieldResolver.ExtractCustomFieldValue(rule, "[\"field-3\",\"AdoIT\"]", out _) ?? ""; + + Assert.That("dd.mm.yyyy".Equals(resultDatumRegelpruefung)); + Assert.That("Infr-AdoIT:X".Equals(resultAdoItId)); + } + + [Test] + public void ExtractCustomFieldValue_InvalidJson_ReturnsDefaultAndErrorMessage() + { + var rule = new Rule + { + CustomFields = "{ invalid json }" + }; + + var result = CustomFieldResolver.ExtractCustomFieldValue(rule, "[\"field-2\"]", out string? errorMessage); + + Assert.That(result, Is.Null); + Assert.That(errorMessage, Is.Not.Null); + Assert.That(errorMessage, Does.Contain("Error")); + } + + [Test] + public void ExtractCustomFieldValue_InvalidKeysJson_ReturnsDefaultAndError() + { + var rule = new Rule + { + CustomFields = "{'field-2':'abc'}" + }; + + var result = CustomFieldResolver.ExtractCustomFieldValue(rule, "invalid json", out var errorMessage); + + Assert.That(result, Is.Null); + Assert.That(errorMessage, Is.Not.Null); + } + + [Test] + public void ExtractCustomFieldValue_InvalidValueType_SkipsKeyAndReturnsFallback() + { + var rule = new Rule + { + CustomFields = "{'field-2':'not-a-json-object'}" + }; + + var result = CustomFieldResolver.ExtractCustomFieldValue(rule, "[\"field-2\"]", out string? errorMessage); + + Assert.That(result, Is.EqualTo(0)); + Assert.That(errorMessage, Is.Not.Null); + } + + [Test] + public void ExtractCustomFieldValue_InvalidPrimary_UsesFallback() + { + var rule = new Rule + { + CustomFields = "{'field-2':'invalid', 'Datum-Regelpruefung':'Change123'}" + }; + + var result = CustomFieldResolver.ExtractCustomFieldValue(rule, "[\"field-2\",\"Datum-Regelpruefung\"]", out var errorMessage); + + Assert.That(errorMessage, Is.Null); + } + + [Test] + public void ExtractCustomFieldValue_NullPrimary_UsesFallback() + { + var rule = new Rule + { + CustomFields = "{'field-2':null, 'Datum-Regelpruefung':'Change123'}" + }; + + var result = CustomFieldResolver.ExtractCustomFieldValue(rule, "[\"field-2\",\"Datum-Regelpruefung\"]", out var errorMessage); + + Assert.That(errorMessage, Is.Null); + Assert.That("Change123".Equals(result)); + } + + [Test] + public void ExtractCustomFieldValue_EmptyPrimaryUsesFallback() + { + var rule = new Rule + { + CustomFields = "{'field-2':'', 'Datum-Regelpruefung':'Change123'}" + }; + + var result = CustomFieldResolver.ExtractCustomFieldValue(rule, "[\"field-2\",\"Datum-Regelpruefung\"]", out _); + + Assert.That(result, Is.EqualTo("Change123")); + } + + [Test] + public void ExtractCustomFieldValue_NullPrimaryUsesFallback() + { + var rule = new Rule + { + CustomFields = "{'field-2':null, 'Datum-Regelpruefung':'Change123'}" + }; + + var result = CustomFieldResolver.ExtractCustomFieldValue(rule, "[\"field-2\",\"Datum-Regelpruefung\"]", out var errorMessage); + Assert.That(result, Is.EqualTo("Change123")); + Assert.That(errorMessage, Is.Null); + } + + + [Test] + public void RuleViewData_LastModified_UsesImportStartTime() + { + Rule rule = new Rule + { + LastSeenImport = new ImportControl { StartTime = new DateTime(2023, 04, 05) } + }; + + UserConfig userConfig = new UserConfig(); + NatRuleDisplayHtml ruleDisplay = new NatRuleDisplayHtml(userConfig); + RuleViewData viewData = new RuleViewData(rule, ruleDisplay, OutputLocation.report, true); + + Assert.That(viewData.LastModified, Is.EqualTo("2023-04-05")); + } + + [Test] + public void RuleViewData_LastModified_UsesCreatedWhenNoLastSeen() + { + Rule rule = new Rule + { + Metadata = new RuleMetadata + { + CreatedImport = new ImportControl { StartTime = new DateTime(2023, 01, 10) } + } + }; + + UserConfig userConfig = new UserConfig(); + NatRuleDisplayHtml ruleDisplay = new NatRuleDisplayHtml(userConfig); + RuleViewData viewData = new RuleViewData(rule, ruleDisplay, OutputLocation.report, true); + + Assert.That(viewData.LastModified, Is.EqualTo("2023-01-10")); + } + + [Test] + public void DisplayRuleTime_UsesFirstTimeObjectWithEndTime() + { + Rule rule = new Rule + { + RuleTimes = + [ + new RuleTime { TimeObj = new TimeObject { EndTime = null } }, + new RuleTime { TimeObj = new TimeObject { EndTime = new DateTime(2026, 01, 02, 03, 04, 05) } }, + new RuleTime { TimeObj = new TimeObject { EndTime = new DateTime(2030, 06, 07, 08, 09, 10) } } + ] + }; + + UserConfig userConfig = new UserConfig(); + RuleDisplayHtml ruleDisplay = new RuleDisplayHtml(userConfig); + + Assert.That(ruleDisplay.DisplayRuleTime(rule), Is.EqualTo("2026-01-02 03:04:05")); + } + + [Test] + public void DisplayRuleTime_ReturnsEmpty_WhenNoTimeObjectHasEndTime() + { + Rule rule = new Rule + { + RuleTimes = + [ + new RuleTime { TimeObj = null }, + new RuleTime { TimeObj = new TimeObject { EndTime = null } } + ] + }; + + UserConfig userConfig = new UserConfig(); + RuleDisplayHtml ruleDisplay = new RuleDisplayHtml(userConfig); + + Assert.That(ruleDisplay.DisplayRuleTime(rule), Is.EqualTo("")); + } + + [Test] + public void RuleViewData_SetsRuleTime_FromDisplayRuleTime() + { + Rule rule = new Rule + { + RuleTimes = + [ + new RuleTime { TimeObj = new TimeObject { EndTime = new DateTime(2026, 12, 24, 11, 22, 33) } } + ] + }; + + UserConfig userConfig = new UserConfig(); + NatRuleDisplayHtml ruleDisplay = new NatRuleDisplayHtml(userConfig); + RuleViewData viewData = new RuleViewData(rule, ruleDisplay, OutputLocation.report, true); + + Assert.That(viewData.RuleTime, Is.EqualTo("2026-12-24 11:22:33")); + } + } +} diff --git a/roles/tests-unit/files/FWO.Test/SCTicketTest.cs b/roles/tests-unit/files/FWO.Test/SCTicketTest.cs new file mode 100644 index 0000000000..ccfb4fbf1e --- /dev/null +++ b/roles/tests-unit/files/FWO.Test/SCTicketTest.cs @@ -0,0 +1,313 @@ +using NUnit.Framework; +using NUnit.Framework.Legacy; +using FWO.Data; +using FWO.Data.Workflow; +using FWO.Data.Modelling; +using FWO.ExternalSystems.Tufin.SecureChange; +using FWO.Basics.Exceptions; +using System.Net; +using RestSharp; + +namespace FWO.Test +{ + [TestFixture] + [Parallelizable] + internal class SCTicketTest + { + static readonly ModellingNamingConvention NamingConvention = new() + { + NetworkAreaRequired = true, + UseAppPart = false, + FixedPartLength = 2, + FreePartLength = 5, + NetworkAreaPattern = "NA", + AppRolePattern = "AR", + AppServerPrefix = "net_" + }; + static readonly List ipProtos = [new() { Id = 6, Name = "TCP" }]; + + + readonly ExternalTicketSystem ticketSystem = new() + { + Id = 1, + Type = ExternalTicketSystemType.TufinSecureChange, + Authorization = "xyz", + Name = "Tufin", + Url = "https://tufin-test.xxx.de/securechangeworkflow/api/securechange/", + Templates = + [ + new() + { + TaskType = SCTaskType.NetworkObjectModify.ToString(), + TicketTemplate = "{\"ticket\":{\"subject\":\"@@TICKET_SUBJECT@@\",\"priority\":\"@@PRIORITY@@\",\"requester\":\"@@ONBEHALF@@\",\"domain_name\":\"\",\"workflow\":{\"name\":\"Automatische Gruppenerstellung\"},\"steps\":{\"step\":[{\"name\":\"Erfassung des Antrags\",\"tasks\":{\"task\":{\"fields\":{\"field\":[@@TASKS@@]}}}}]}}}", + TasksTemplate = "{\"@xsi.type\": \"multi_group_change\",\"name\": \"Modify network object group\",\"group_change\": {\"name\": \"@@GROUPNAME@@\",\"management_name\": \"@@MANAGEMENT_NAME@@\",\"members\": {\"member\": @@MEMBERS@@},\"change_action\": \"CREATE\"}}", + ObjectTemplate = "{\"@type\": \"@@TYPE@@\", \"name\": \"@@OBJECTNAME@@\", \"object_type\": \"@@OBJECT_TYPE@@\", \"object_details\": \"@@OBJECT_DETAILS@@\", \"status\": \"@@STATUS@@\", \"comment\": \"@@COMMENT@@\", \"object_updated_status\": \"@@OBJUPDSTATUS@@\", \"management_id\": @@MANAGEMENT_ID@@}", + ObjectTemplateShort = "{\"@type\": \"Object\", \"name\": \"@@OBJECTNAME@@\", \"status\": \"@@STATUS@@\", \"object_updated_status\": \"@@OBJUPDSTATUS@@\"}" + }, + new() + { + TaskType = SCTaskType.AccessRequest.ToString(), + TicketTemplate = "{\"ticket\":{\"subject\":\"@@TICKET_SUBJECT@@\",\"priority\":\"@@PRIORITY@@\",\"requester\":\"@@ONBEHALF@@\",\"domain_name\":\"\",\"workflow\":{\"name\":\"Standard Firewall Request\"},\"steps\":{\"step\":[{\"name\":\"Erfassung des Antrags\",\"tasks\":{\"task\":{\"fields\":{\"field\":[{\"@xsi.type\": \"multi_access_request\",\"name\": \"Zugang\",\"read_only\": false,\"access_request\":[@@TASKS@@]},{\"@xsi.type\": \"text_area\",\"name\": \"Grund für den Antrag\",\"read_only\": false,\"text\": \"@@REASON@@\"},{\"@xsi.type\": \"text_field\",\"name\": \"Anwendungs-ID\",\"text\": \"@@APPID@@\"},{\"@xsi.type\": \"checkbox\",\"name\": \"hinterlegt\",\"value\": true}]}}}}]}}}}", + TasksTemplate = "{\"order\": \"@@ORDERNAME@@\",\"verifier_result\": {\"status\": \"not run\"},\"use_topology\": true,\"targets\": {\"target\": {\"@type\": \"ANY\"}},\"action\": \"@@ACTION@@\",\"sources\":{\"source\":@@SOURCES@@},\"destinations\":{\"destination\":@@DESTINATIONS@@},\"services\":{\"service\":@@SERVICES@@},\"labels\":\"\",\"comment\": \"@@TASKCOMMENT@@\"}", + IpTemplate = "{\"@type\": \"IP\", \"ip_address\": \"@@IP@@\", \"netmask\": \"255.255.255.255\", \"cidr\": 32}", + NwObjGroupTemplate = "{\"@type\": \"Object\", \"object_name\": \"@@GROUPNAME@@\", \"management_name\": \"@@MANAGEMENT_NAME@@\"}", + ServiceTemplate = "{\"@type\": \"PROTOCOL\", \"protocol\": \"@@PROTOCOLNAME@@\", \"port\": @@PORT@@, \"name\": \"@@SERVICENAME@@\"}", + IcmpTemplate = "{\"@type\": \"PROTOCOL\", \"protocol\": \"ICMP\", \"type\": 8, \"name\": \"@@SERVICENAME@@\"}" + } + ] + }; + + private static WfReqTask ConstructAccTask(int id, string title, int taskNumber, string taskType, string action) + { + return new() + { + Id = id, + Title = title, + TaskNumber = taskNumber, + TaskType = taskType, + TicketId = 123, + RequestAction = action, + Reason = "connection needed", + AdditionalInfo = "{\"ConnId\":\"1\"}", + OnManagement = new() { Id = 1, Name = "Checkpoint", ExtMgtData = "{\"id\":\"2\",\"name\":\"CheckpointExt\"}" }, + ManagementId = 1, + Comments = [new() { Comment = new() { CommentText = "FWOC1, NAT: To: 4.7.1.1" } }], + Elements = + [ + new() + { + Id = 1, + TaskId = 1, + RequestAction = RequestAction.create.ToString(), + GroupName = "ARxx12345-100", + Field = ElemFieldType.source.ToString() + }, + new() + { + Id = 2, + TaskId = 1, + RequestAction = RequestAction.create.ToString(), + GroupName = "ARxx12345-101", + Field = ElemFieldType.destination.ToString() + }, + new() + { + Id = 3, + TaskId = 1, + RequestAction = RequestAction.create.ToString(), + Name = "Svc1", + Port = 1000, + ProtoId = 6, + Field = ElemFieldType.service.ToString() + }, + new() + { + Id = 4, + TaskId = 1, + RequestAction = RequestAction.create.ToString(), + Name = "Icmp1", + ProtoId = 1, + Field = ElemFieldType.service.ToString() + } + ] + }; + } + + readonly List grpCreateReqTasks = + [ + new() + { + Id = 1, + Title = "new Group", + TaskNumber = 1, + TaskType = WfTaskType.group_create.ToString(), + TicketId = 123, + RequestAction = RequestAction.create.ToString(), + Reason = "need it for connection", + AdditionalInfo = "{\"GrpName\":\"ARxx12345-100\"}", + OnManagement = new(){ Id = 1, Name = "Checkpoint", ExtMgtData = "{\"id\":\"2\",\"name\":\"CheckpointExt\"}"}, + ManagementId = 1, + Elements = + [ + new() + { + Id = 1, + TaskId = 1, + RequestAction = RequestAction.create.ToString(), + IpString = "123.0.0.1/32", + GroupName = "ARxx12345-100", + Name = "AppServerX", + Field = ElemFieldType.source.ToString() + } + ] + } + ]; + + readonly static string GrpCreateFilledTicketText = + "{\"ticket\":{\"subject\":\"\",\"priority\":\"Normal\",\"requester\":\"\",\"domain_name\":\"\",\"workflow\":{\"name\":\"Automatische Gruppenerstellung\"}," + + "\"steps\":{\"step\":[{\"name\":\"Erfassung des Antrags\",\"tasks\":{\"task\":{\"fields\":{\"field\":[{\"@xsi.type\": \"multi_group_change\",\"name\": \"Modify network object group\",\"group_change\": " + + "{\"name\": \"ARxx12345-100\",\"management_name\": \"CheckpointExt\",\"members\": " + + "{\"member\": [{\"@type\": \"host\", \"name\": \"AppServerX\", \"object_type\": \"host\", \"object_details\": \"123.0.0.1/32\", \"status\": \"ADDED\", \"comment\": \"\", \"object_updated_status\": \"NEW\", \"management_id\": 2}]}," + + "\"change_action\": \"CREATE\"}}]}}}}]}}}"; + + readonly List accessReqTask = + [ + ConstructAccTask(1, "new Connection", 1, WfTaskType.access.ToString(), RequestAction.create.ToString()) + ]; + + readonly static string AccessFilledTicketText = + "{\"ticket\":{\"subject\":\"\",\"priority\":\"Normal\",\"requester\":\"\",\"domain_name\":\"\",\"workflow\":{\"name\":\"Standard Firewall Request\"}," + + "\"steps\":{\"step\":[{\"name\":\"Erfassung des Antrags\",\"tasks\":{\"task\":{\"fields\":{\"field\":[{\"@xsi.type\": \"multi_access_request\",\"name\": \"Zugang\",\"read_only\": false,\"access_request\":[" + + "{\"order\": \"AR1\",\"verifier_result\": {\"status\": \"not run\"},\"use_topology\": true,\"targets\": {\"target\": {\"@type\": \"ANY\"}},\"action\": \"accept\"," + + "\"sources\":{\"source\":[{\"@type\": \"Object\", \"object_name\": \"ARxx12345-100\", \"management_name\": \"CheckpointExt\"}]}," + + "\"destinations\":{\"destination\":[{\"@type\": \"Object\", \"object_name\": \"ARxx12345-101\", \"management_name\": \"CheckpointExt\"}]}," + + "\"services\":{\"service\":[{\"@type\": \"PROTOCOL\", \"protocol\": \"TCP\", \"port\": 1000, \"name\": \"Svc1\"},{\"@type\": \"PROTOCOL\", \"protocol\": \"ICMP\", \"type\": 8, \"name\": \"Icmp1\"}]}," + + "\"labels\":\"\",\"comment\": \"FWOC1, NAT: To: 4.7.1.1\"}]}," + + "{\"@xsi.type\": \"text_area\",\"name\": \"Grund für den Antrag\",\"read_only\": false,\"text\": \"connection needed\"},{\"@xsi.type\": \"text_field\",\"name\": \"Anwendungs-ID\",\"text\": \"\"},{\"@xsi.type\": \"checkbox\",\"name\": \"hinterlegt\",\"value\": true}]}}}}]}}}}"; + + readonly List removeReqTasks = + [ + ConstructAccTask(2, "old Connection1", 2, WfTaskType.rule_delete.ToString(), RequestAction.delete.ToString()), + ConstructAccTask(3, "old Connection2", 3, WfTaskType.rule_delete.ToString(), RequestAction.delete.ToString()) + ]; + + readonly static string RemoveFilledTicketText = + "{\"ticket\":{\"subject\":\"\",\"priority\":\"Normal\",\"requester\":\"\",\"domain_name\":\"\",\"workflow\":{\"name\":\"Standard Firewall Request\"}," + + "\"steps\":{\"step\":[{\"name\":\"Erfassung des Antrags\",\"tasks\":{\"task\":{\"fields\":{\"field\":[{\"@xsi.type\": \"multi_access_request\",\"name\": \"Zugang\",\"read_only\": false,\"access_request\":[" + + "{\"order\": \"AR2\",\"verifier_result\": {\"status\": \"not run\"},\"use_topology\": true,\"targets\": {\"target\": {\"@type\": \"ANY\"}},\"action\": \"remove\"," + + "\"sources\":{\"source\":[{\"@type\": \"Object\", \"object_name\": \"ARxx12345-100\", \"management_name\": \"CheckpointExt\"}]}," + + "\"destinations\":{\"destination\":[{\"@type\": \"Object\", \"object_name\": \"ARxx12345-101\", \"management_name\": \"CheckpointExt\"}]}," + + "\"services\":{\"service\":[{\"@type\": \"PROTOCOL\", \"protocol\": \"TCP\", \"port\": 1000, \"name\": \"Svc1\"},{\"@type\": \"PROTOCOL\", \"protocol\": \"ICMP\", \"type\": 8, \"name\": \"Icmp1\"}]}," + + "\"labels\":\"\",\"comment\": \"FWOC1, NAT: To: 4.7.1.1\"}," + + "{\"order\": \"AR3\",\"verifier_result\": {\"status\": \"not run\"},\"use_topology\": true,\"targets\": {\"target\": {\"@type\": \"ANY\"}},\"action\": \"remove\"," + + "\"sources\":{\"source\":[{\"@type\": \"Object\", \"object_name\": \"ARxx12345-100\", \"management_name\": \"CheckpointExt\"}]}," + + "\"destinations\":{\"destination\":[{\"@type\": \"Object\", \"object_name\": \"ARxx12345-101\", \"management_name\": \"CheckpointExt\"}]}," + + "\"services\":{\"service\":[{\"@type\": \"PROTOCOL\", \"protocol\": \"TCP\", \"port\": 1000, \"name\": \"Svc1\"},{\"@type\": \"PROTOCOL\", \"protocol\": \"ICMP\", \"type\": 8, \"name\": \"Icmp1\"}]}," + + "\"labels\":\"\",\"comment\": \"FWOC1, NAT: To: 4.7.1.1\"}" + + "]},{\"@xsi.type\": \"text_area\",\"name\": \"Grund für den Antrag\",\"read_only\": false,\"text\": \"connection needed\"},{\"@xsi.type\": \"text_field\",\"name\": \"Anwendungs-ID\",\"text\": \"\"},{\"@xsi.type\": \"checkbox\",\"name\": \"hinterlegt\",\"value\": true}]}}}}]}}}}"; + + + + [SetUp] + public void Initialize() + { + + } + + [Test] + public async Task TestSCGrpCreateTicket() + { + SCTicket ticket = new(ticketSystem); + await ticket.CreateRequestString(grpCreateReqTasks, ipProtos, NamingConvention); + + ClassicAssert.AreEqual(GrpCreateFilledTicketText, ticket.TicketText); + } + + [Test] + public async Task TestSCAccessTicket() + { + SCTicket ticket = new(ticketSystem); + await ticket.CreateRequestString(accessReqTask, ipProtos, NamingConvention); + + ClassicAssert.AreEqual(AccessFilledTicketText, ticket.TicketText); + } + + [Test] + public async Task TestSCAccessTicketSortsSourceObjectsAlphabetically() + { + List unsortedAccessReqTask = + [ + ConstructAccTask(1, "new Connection", 1, WfTaskType.access.ToString(), RequestAction.create.ToString()) + ]; + unsortedAccessReqTask[0].Elements.Insert(0, new() + { + Id = 5, + TaskId = 1, + RequestAction = RequestAction.create.ToString(), + GroupName = "ARxx12345-200", + Field = ElemFieldType.source.ToString() + }); + unsortedAccessReqTask[0].Elements.Insert(0, new() + { + Id = 6, + TaskId = 1, + RequestAction = RequestAction.create.ToString(), + GroupName = "ARxx12345-050", + Field = ElemFieldType.source.ToString() + }); + + SCTicket ticket = new(ticketSystem); + await ticket.CreateRequestString(unsortedAccessReqTask, ipProtos, NamingConvention); + + ClassicAssert.IsTrue(ticket.TicketText.Contains( + "\"sources\":{\"source\":[{\"@type\": \"Object\", \"object_name\": \"ARxx12345-050\", \"management_name\": \"CheckpointExt\"}," + + "{\"@type\": \"Object\", \"object_name\": \"ARxx12345-100\", \"management_name\": \"CheckpointExt\"}," + + "{\"@type\": \"Object\", \"object_name\": \"ARxx12345-200\", \"management_name\": \"CheckpointExt\"}]}")); + } + + [Test] + public async Task TestSCRemoveTicket() + { + SCTicket ticket = new(ticketSystem); + await ticket.CreateRequestString(removeReqTasks, ipProtos, NamingConvention); + + ClassicAssert.AreEqual(RemoveFilledTicketText, ticket.TicketText); + } + + [Test] + public async Task TestSCLookupRequesterIdSuccess() + { + ExternalTicketSystem lookupSystem = CreateTicketSystem(true); + SimulatedSCClient scClient = new(lookupSystem); + scClient.EnqueueResponse("users.json?user_name=alice", + new(new()) { StatusCode = HttpStatusCode.OK, Content = "{\"users\":{\"user\":[{\"id\":55}]}}" }); + + SCTicket ticket = new(lookupSystem, scClient) { Requester = "alice" }; + await ticket.CreateRequestString(accessReqTask, ipProtos, NamingConvention); + + ClassicAssert.IsTrue(ticket.TicketText.Contains("\"requester\":\"55\"")); + } + + [Test] + public void TestSCLookupRequesterIdUnknownUserThrows() + { + ExternalTicketSystem lookupSystem = CreateTicketSystem(true); + SimulatedSCClient scClient = new(lookupSystem); + scClient.EnqueueResponse("users.json?user_name=unknown", + new(new()) { StatusCode = HttpStatusCode.OK, Content = "" }); + + SCTicket ticket = new(lookupSystem, scClient) { Requester = "unknown" }; + + Assert.ThrowsAsync(async () => + await ticket.CreateRequestString(accessReqTask, ipProtos, NamingConvention)); + } + + [Test] + public void TestSCLookupRequesterIdHttpErrorThrows() + { + ExternalTicketSystem lookupSystem = CreateTicketSystem(true); + SimulatedSCClient scClient = new(lookupSystem); + scClient.EnqueueResponse("users.json?user_name=error", + new(new()) { StatusCode = HttpStatusCode.BadRequest, Content = "{\"error\":\"bad\"}" }); + + SCTicket ticket = new(lookupSystem, scClient) { Requester = "error" }; + + Assert.ThrowsAsync(async () => + await ticket.CreateRequestString(accessReqTask, ipProtos, NamingConvention)); + } + + private ExternalTicketSystem CreateTicketSystem(bool lookupRequesterId) + { + return new() + { + Id = ticketSystem.Id, + Type = ticketSystem.Type, + Authorization = ticketSystem.Authorization, + Name = ticketSystem.Name, + Url = ticketSystem.Url, + LookupRequesterId = lookupRequesterId, + Templates = ticketSystem.Templates + }; + } + } +} diff --git a/roles/tests-unit/files/FWO.Test/SchedulerTest.cs b/roles/tests-unit/files/FWO.Test/SchedulerTest.cs new file mode 100644 index 0000000000..f3bd7d0737 --- /dev/null +++ b/roles/tests-unit/files/FWO.Test/SchedulerTest.cs @@ -0,0 +1,94 @@ +using NUnit.Framework; +using NUnit.Framework.Legacy; +using FWO.Api.Client; +using FWO.Api.Client.Queries; +using FWO.Data; +using FWO.Config.Api; +using FWO.Config.Api.Data; +using FWO.Middleware.Server; +using System.Timers; +using FWO.Services; + + +namespace FWO.Test +{ + [TestFixture] + internal class SchedulerTest + { + public class TestScheduler : SchedulerBase + { + /// + /// Async Constructor needing the connection + /// + public static async Task CreateAsync(ApiConnection apiConnection) + { + await DefaultInit.DoNothing(); + SimulatedGlobalConfig globalConfig = new(); + return new TestScheduler(apiConnection, globalConfig); + } + + private readonly ApiConnection testApiConnection; + + private TestScheduler(ApiConnection apiConnection, GlobalConfig globalConfig) + : base(apiConnection, globalConfig, ConfigQueries.subscribeExternalRequestConfigChanges, SchedulerInterval.Seconds, "Test") + { + testApiConnection = apiConnection; + StartScheduleTimer(1, DateTime.Now); + } + + private readonly int Counter = 1; + + /// + /// set scheduling timer from config values + /// + protected override void OnGlobalConfigChange(List config) + { } + + /// + /// define the processing to be done + /// + protected override async void Process(object? _, ElapsedEventArgs __) + { + await AlertHelper.AddLogEntry(testApiConnection, 1, "cause", $"logDesc {Counter}", "source"); + await AlertHelper.SetAlert(testApiConnection, "title", $"alertDesc {Counter}", "source", AlertCode.UiError, new AlertHelper.AdditionalAlertData()); + } + } + + static readonly SchedulerTestApiConn apiConnection = new(); + + + [SetUp] + public void Initialize() + { + // + } + + [Test] + public async Task TestTestScheduler() + { + List ConsoleLogs = []; + using StringWriter logOutput = new(); + TextWriter originalConsoleOut = Console.Out; + Console.SetOut(logOutput); + + TestScheduler scheduler = await TestScheduler.CreateAsync(apiConnection); + + ClassicAssert.AreEqual(0, apiConnection.LogEntries.Count); + ClassicAssert.AreEqual(0, apiConnection.Alerts.Count); + ConsoleLogs.Add(logOutput.ToString()); + ClassicAssert.AreEqual(true, ConsoleLogs[0].Contains("Scheduler-Test")); + ClassicAssert.AreEqual(true, ConsoleLogs[0].Contains("ScheduleTimer started.")); + + await Task.Delay(1500); + ClassicAssert.AreEqual(1, apiConnection.LogEntries.Count); + ClassicAssert.AreEqual(true, apiConnection.LogEntries[0].Contains("logDesc 1")); + ClassicAssert.AreEqual(1, apiConnection.Alerts.Count); + ClassicAssert.AreEqual(true, apiConnection.Alerts[0].Contains("alertDesc 1")); + ClassicAssert.AreEqual(1, apiConnection.AcknowledgedAlerts.Count); + ClassicAssert.AreEqual(7, apiConnection.AcknowledgedAlerts[0]); + ConsoleLogs.Add(logOutput.ToString()); + ClassicAssert.AreEqual(true, ConsoleLogs[1].Contains("RecurringTimer started.")); + Console.SetOut(originalConsoleOut); + } + } +} diff --git a/roles/tests-unit/files/FWO.Test/SchedulerTestApiConn.cs b/roles/tests-unit/files/FWO.Test/SchedulerTestApiConn.cs new file mode 100644 index 0000000000..fe82d0742f --- /dev/null +++ b/roles/tests-unit/files/FWO.Test/SchedulerTestApiConn.cs @@ -0,0 +1,72 @@ +using FWO.Api.Client; +using FWO.Api.Client.Queries; +using FWO.Basics; +using FWO.Data; +using FWO.Services; +using GraphQL; +using GraphQL.Client.Http; +using GraphQL.Client.Serializer.SystemTextJson; + + +namespace FWO.Test +{ + internal class SchedulerTestApiConn : SimulatedApiConnection + { + public List LogEntries = []; + public List Alerts = []; + public List AcknowledgedAlerts = []; + + public override async Task SendQueryAsync(string query, object? variables = null, string? operationName = null) + { + await DefaultInit.DoNothing(); // qad avoid compiler warning + Type responseType = typeof(QueryResponseType); + if (responseType == typeof(ReturnIdWrapper)) + { + if (query == MonitorQueries.addLogEntry && variables != null) + { + string? entry = variables.ToString(); + if (entry != null) + { + LogEntries.Add(entry); + } + } + else if (query == MonitorQueries.addAlert && variables != null) + { + string? alert = variables.ToString(); + if (alert != null) + { + Alerts.Add(alert); + } + } + ReturnIdWrapper ReturnIdWrap = new() { ReturnIds = [new()] }; + GraphQLResponse response = new() { Data = ReturnIdWrap }; + return response.Data; + } + else if (responseType == typeof(ReturnId)) + { + if (query == MonitorQueries.acknowledgeAlert && variables != null) + { + object? rawId = variables.GetType().GetProperty("id")?.GetValue(variables); + if (rawId != null) + { + AcknowledgedAlerts.Add(Convert.ToInt64(rawId)); + } + } + GraphQLResponse response = new() { Data = new ReturnId() }; + return response.Data; + } + else if (responseType == typeof(List)) + { + GraphQLResponse response = new() { Data = new List() { new() { Id = 7, AlertCode = AlertCode.UiError } } }; + return response.Data; + } + + throw new NotImplementedException(); + } + + public override SimulatedApiSubscription GetSubscription(Action exceptionHandler, SimulatedApiSubscription.SubscriptionUpdate subscriptionUpdateHandler, string subscription, object? variables = null, string? operationName = null) + { + return new(this, new(new GraphQLHttpClientOptions(), new SystemTextJsonSerializer(), new()), new(subscription, variables, operationName), exceptionHandler, subscriptionUpdateHandler); + } + } +} diff --git a/roles/tests-unit/files/FWO.Test/SimulatedApiConnection.cs b/roles/tests-unit/files/FWO.Test/SimulatedApiConnection.cs new file mode 100644 index 0000000000..85705c4336 --- /dev/null +++ b/roles/tests-unit/files/FWO.Test/SimulatedApiConnection.cs @@ -0,0 +1,56 @@ +using FWO.Api.Client; +using GraphQL; +using GraphQL.Client.Http; + +namespace FWO.Test +{ + internal class SimulatedApiConnection : ApiConnection + { + public override GraphQlApiSubscription GetSubscription(Action exceptionHandler, GraphQlApiSubscription.SubscriptionUpdate subscriptionUpdateHandler, string subscription, object? variables = null, string? operationName = null) + { + throw new NotImplementedException(); + } + + public override Task SendQueryAsync(string query, object? variables = null, string? operationName = null) + { + throw new NotImplementedException(); + } + + public override async Task> SendQuerySafeAsync(string query, object? variables = null, string? operationName = null) + { + QueryResponseType result = await SendQueryAsync(query, variables, operationName); + return new ApiResponse(result); + } + + public override void SetAuthHeader(string jwt) + { } + + public override void SetRole(string role) + { } + + public override void SetBestRole(System.Security.Claims.ClaimsPrincipal user, List targetRoleList) + { } + + public override void SetProperRole(System.Security.Claims.ClaimsPrincipal user, List targetRoleList) + { } + + public override void SwitchBack() + { } + + protected override void Dispose(bool disposing) + { } + + public override void DisposeSubscriptions() + { } + } + + internal class SimulatedApiSubscription : GraphQlApiSubscription + { + public SimulatedApiSubscription(ApiConnection apiConnection, GraphQLHttpClient graphQlClient, GraphQLRequest request, Action exceptionHandler, SubscriptionUpdate OnUpdate) + : base(apiConnection, graphQlClient, request, exceptionHandler, OnUpdate) + { } + + protected override void CreateSubscription() + { } + } +} diff --git a/roles/tests-unit/files/FWO.Test/SimulatedReport.cs b/roles/tests-unit/files/FWO.Test/SimulatedReport.cs new file mode 100644 index 0000000000..bbadc18d1b --- /dev/null +++ b/roles/tests-unit/files/FWO.Test/SimulatedReport.cs @@ -0,0 +1,135 @@ +using FWO.Api.Client; +using FWO.Data.Report; +using FWO.Config.Api; +using FWO.Report; +using FWO.Report.Filter; +using FWO.Basics; +using FWO.Data; + +namespace FWO.Test +{ + internal class SimulatedReport : ReportBase + { + public static SimulatedReport DetailedReport(ReportType reportType = ReportType.Rules) => new(new DynGraphqlQuery(""), new SimulatedUserConfig(), reportType) + { + ReportData = new() + { + ManagementData = + [ + new ManagementReport + { + Id = 1, + Name = "Management 1", + Devices = + [ + new DeviceReport + { + Id = 1, + Name = "Device 1", + RulebaseLinks = + [ + new RulebaseLink + { + GatewayId = 1, + NextRulebaseId = 1, + IsInitial = true + } + ] + } + ], + Objects = + [ + new() { Id = 1, Name = "Object 1" }, + new() { Id = 2, Name = "Object 2" } + ], + Services = + [ + new() { Id = 1, Name = "Service 1" }, + new() { Id = 2, Name = "Service 2" } + ], + Users = + [ + new() { Id = 1, Name = "User 1" }, + new() { Id = 2, Name = "User 2" } + ], + ReportObjects = + [ + new() { Id = 1, Name = "Report Object 1" }, + new() { Id = 2, Name = "Report Object 2" } + ], + ReportServices = + [ + new() { Id = 1, Name = "Report Service 1" }, + new() { Id = 2, Name = "Report Service 2" } + ], + ReportUsers = + [ + new() { Id = 1, Name = "Report User 1" }, + new() { Id = 2, Name = "Report User 2" } + ], + Rulebases = + [ + new RulebaseReport + { + Id = 1, + Name = "Rulebase 1", + Rules = + [ + new Rule + { + Id = 1, + Name = "Rule 1", + Source = "Object 1", + Destination = "Object 2", + Service = "Service 1", + Action = "accept" + } + ] + } + ] + } + ] + } + }; + + public SimulatedReport(DynGraphqlQuery query, UserConfig userConfig, ReportType reportType) : base(query, userConfig, reportType) + { + } + + override public Task GetObjectsForManagementInReport(Dictionary objQueryVariables, ObjCategory objects, int maxFetchCycles, ApiConnection apiConnection, Func callback) + { + callback(DetailedReport().ReportData); + return Task.FromResult(true); + } + + override public Task Generate(int elementsPerFetch, ApiConnection apiConnection, Func callback, CancellationToken ct) + { + return Task.CompletedTask; + } + + override public Task GetObjectsInReport(int objectsPerFetch, ApiConnection apiConnection, Func callback) + { + return Task.FromResult(true); + } + + override public string ExportToCsv() + { + return ""; + } + + override public string ExportToJson() + { + return ""; + } + + override public string ExportToHtml() + { + return ""; + } + + override public string SetDescription() + { + return ""; + } + } +} diff --git a/roles/tests-unit/files/FWO.Test/SimulatedSCClient.cs b/roles/tests-unit/files/FWO.Test/SimulatedSCClient.cs new file mode 100644 index 0000000000..d78d5d42e4 --- /dev/null +++ b/roles/tests-unit/files/FWO.Test/SimulatedSCClient.cs @@ -0,0 +1,51 @@ +using FWO.Data; +using FWO.Services; +using FWO.ExternalSystems.Tufin.SecureChange; +using System.Net; +using RestSharp; + +namespace FWO.Test +{ + /// + /// SC Ticket with simulated Rest call + /// + public class SimulatedSCClient : SCClient + { + private int CallCounter = 0; + private readonly Dictionary>> queuedResponses = new(); + + /// + /// constructor + /// + public SimulatedSCClient(ExternalTicketSystem tufinSystem) : base(tufinSystem) + { } + + public void EnqueueResponse(string restEndPoint, RestResponse response) + { + if (!queuedResponses.TryGetValue(restEndPoint, out Queue>? responses)) + { + responses = new Queue>(); + queuedResponses[restEndPoint] = responses; + } + responses.Enqueue(response); + } + + /// + /// Simulated Rest call + /// + public override async Task> RestCall(RestRequest request, string restEndPoint) + { + CallCounter++; + await DefaultInit.DoNothing(); // qad avoid compiler warning + if (queuedResponses.TryGetValue(restEndPoint, out Queue>? responses) && responses.Count > 0) + { + return responses.Dequeue(); + } + if (CallCounter == 2) + { + return new(new()) { StatusCode = HttpStatusCode.BadRequest, Content = "{\"ticket\": {\"id\": 1, \"status\": \"In Progress\", \"Error\": \"FIELD_VALIDATION_ERROR\"} }" }; + } + return new(new()) { StatusCode = HttpStatusCode.OK, Content = "{\"ticket\": {\"id\": 1, \"status\": \"In Progress\" } }" }; + } + } +} diff --git a/roles/tests-unit/files/FWO.Test/SimulatedUserConfig.cs b/roles/tests-unit/files/FWO.Test/SimulatedUserConfig.cs new file mode 100644 index 0000000000..99b42eb2a3 --- /dev/null +++ b/roles/tests-unit/files/FWO.Test/SimulatedUserConfig.cs @@ -0,0 +1,432 @@ +using FWO.Config.Api; +using FWO.Config.Api.Data; + +namespace FWO.Test +{ + internal class SimulatedGlobalConfig : GlobalConfig + { + public Dictionary DummyTranslate = new(SimulatedUserConfig.DummyTranslate); + public Dictionary GermanTranslate = new(SimulatedUserConfig.DummyTranslate); + + public override string GetText(string key) + { + return GetTextInLanguage(key, DefaultLanguage); + } + + public SimulatedGlobalConfig() : base() + { + LangDict = new() + { + { "English", DummyTranslate }, + { "German", GermanTranslate } + }; + OverDict = new() + { + { "English", [] }, + { "German", [] } + }; + } + } + + internal class SimulatedUserConfig : UserConfig + { + public static Dictionary DummyTranslate = new() + { + {"Rules","Rules Report"}, + {"ResolvedRules","Rules Report (resolved)"}, + {"ResolvedRulesTech","Rules Report (technical)"}, + {"UnusedRules","Unused Rules Report"}, + {"Recertification","Recertification Report"}, + {"OwnerRecertification","Owner Recertification"}, + {"Owners","Owners"}, + {"NatRules","NAT Rules Report"}, + {"Changes","Changes Report"}, + {"ResolvedChanges","Changes Report (resolved)"}, + {"ResolvedChangesTech","Changes Report (technical)"}, + {"Connections","Connections Report"}, + {"date_of_config","Time of configuration"}, + {"generated_on","Generated on"}, + {"negated","not"}, + {"users","Users"}, + {"rule_added","Rule added"}, + {"rule_deleted","Rule deleted"}, + {"rule_modified","Rule modified"}, + {"deleted","deleted"}, + {"added","added"}, + {"missing","missing"}, + {"surplus","surplus"}, + {"change_time","Change Time"}, + {"change_type","Change Type"}, + {"number","No."}, + {"name","Name"}, + {"source_zone","Source Zone"}, + {"source","Source"}, + {"destination_zone","Destination Zone"}, + {"destination","Destination"}, + {"services","Services"}, + {"action","Action"}, + {"track","Track"}, + {"enabled","Enabled"}, + {"uid","Uid"}, + {"comment","Comment"}, + {"type","Type"}, + {"ip_address","IP Address"}, + {"members","Members"}, + {"network_objects","Network Objects"}, + {"network_services","Network Services"}, + {"protocol","Protocol"}, + {"port","Port"}, + {"next_recert_date","Next Recertification Date"}, + {"last_recertified","Last Recertified"}, + {"last_recertifier","Last Recertifier"}, + {"owner","Owner"}, + {"ext_app_id","External App Id"}, + {"ip_matches","IP address match"}, + {"last_hit","Last Hit"}, + {"trans_source","Translated Source"}, + {"trans_destination","Translated Destination"}, + {"trans_services","Translated Services"}, + {"from","from"}, + {"until","until"}, + {"C9001","This object was..."}, + {"C9002","This App Server was..."}, + {"C9003","App disabled"}, + {"C9004","No connections"}, + {"C9007","Requested by other owner"}, + {"C9008","Requested"}, + {"C9011","Rejected"}, + {"is_in_use","Is in use"}, + {"devices","Devices"}, + {"owners","Owners"}, + {"filter","Filter"}, + {"statistics","Statistics"}, + {"id","Id"}, + {"ip","Ip"}, + {"group","Group"}, + {"host","Host"}, + {"network","Network"}, + {"ip_range","IP Range"}, + {"connections","Connections"}, + {"interfaces","Interfaces"}, + {"own_common_services","Own Common Services"}, + {"global_common_services","Global Common Services"}, + {"func_reason","Functional Reason"}, + {"interface_description","Interface Description"}, + {"interface","Interface"}, + {"published","Published"}, + {"fetch_data","Fetch data"}, + {"new_connection","New Connection"}, + {"new_app_role","New AppRole: "}, + {"update_app_role","Update AppRole: "}, + {"new_svc_grp","New Servicegroup: "}, + {"add_members",": Add Members"}, + {"remove_members",": Remove Members"}, + {"new_app_zone", "New AppZone: " }, + {"update_app_zone", "Update AppZone: " }, + { "E9301", "Template File not found!" }, + { "E9302", "HTML is invalid!" }, + { "tableofcontent", "Table of content" }, + {"objects","Objects"}, + {"all","All"}, + {"oneTaskForAllDevices","One task for all devices"}, + {"report","Report"}, + {"rule", "Rule"}, + {"collapse_all","Collapse All"}, + {"clear_all", "Clear All"}, + {"used_objects", "Used Objects"}, + {"object_fetch", "Object Fetch"}, + {"app_roles", "AppRoles"}, + {"implemented", "Implemented"}, + {"not_implemented", "Not Implemented"}, + {"with_diffs", "With Diffs"}, + {"app_roles_not_implemented", "AppRoles Not Implemented"}, + {"app_roles_with_diffs", "AppRoles With Diffs"}, + {"missing_app_servers", "Missing App Servers"}, + {"surplus_app_servers", "Surplus App Servers"}, + {"VarianceAnalysis", "VarianceAnalysis"}, + {"connections_not_implemented", "Connections not implemented"}, + {"connections_with_diffs", "Connections with Diffs"}, + {"management", "Management"}, + {"gateway", "Gateway"}, + {"U1003", "In this report..."}, + {"fully_modelled", "fullymodelled"}, + {"more", "more"}, + {"AppRules", "App Rules"}, + {"change_rule", "Change Rule"}, + {"delete_rule", "Delete Rule"}, + {"impl_instructions", "Implementation Instructions"}, + {"init_environment", "Init Environment"}, + {"save_request", "Save request"}, + {"U0001", "Input text..."}, + {"on", "on"}, + {"create_rule", "Create Rule"}, + {"create_group", "Create Group"}, + {"modify_group", "Modify Group"}, + {"delete_group", "Delete Group"}, + {"promote_task", "Promote task"}, + {"modify_rule", "Modify Rule"}, + {"remove_rule", "Remove Rule"}, + {"English", "English"}, + {"last_successful", "Last successful"}, + {"common_service", "Common Service"}, + {"managements", "Managements"}, + {"enforcing_devices", "enforcing_devices" }, + {"no_changes_found", "no_changes_found" }, + {"network_object_added", "network_object_added" }, + {"network_object_deleted", "network_object_deleted" }, + {"network_object_modified", "network_object_modified" }, + {"service_added", "service_added" }, + {"service_deleted", "service_deleted" }, + {"service_modified", "service_modified" }, + {"user_added","user_added" }, + {"user_deleted","user_deleted" }, + {"user_modified","user_modified" }, + {"interface_permission","Interface Permission" }, + {"Public","Public" }, + {"edit_connection","Edit Connection" }, + {"edit_common_service","Edit Common Service" }, + {"edit_interface","Edit Interface" }, + {"insert_forbidden","Insert forbidden" }, + {"replace","Replace" }, + {"E9017","ErrorText" }, + {"from_ticket","From Ticket" }, + {"InterfaceRejected","Interface rejected" }, + {"interface_requested","Interface requested" }, + {"requested_interfaces","Requested Interfaces" }, + {"show_removed_requested_interfaces","Show removed requested interfaces" }, + {"reject_tickets","Close Tickets as rejected" }, + {"reject","Reject" }, + {"orphaned_requested_interface_tickets","Open tickets for deleted requested interfaces" }, + {"orphaned_requested_interface_tickets_empty","No open tickets for deleted requested interfaces were found." }, + {"H7423","If deleted requested interfaces still have open tickets, the administrator can close those tickets together as rejected." }, + {"H7424","The button \"Open tickets for deleted requested interfaces\" opens a separate list of all still open new-interface tickets whose requested interface does not exist anymore. The check is performed only when opening the popup, so it is independent from the current table filter." }, + {"reject_interface","Reject interface" }, + {"requesting_app","Requesting App" }, + {"requesting_ext_app_id","Requesting Ext App Id" }, + {"used_in_connection_ids","Used In Connection Ids" }, + {"requested_app","Requested App" }, + {"requested_ext_app_id","Requested Ext App Id" }, + {"requested_interface","Requested Interface" }, + {"display_ticket","Display Ticket" }, + {"creation_date","Creation Date" }, + {"reason","Reason" }, + {"all_open","All Open" }, + {"U9017","Are you sure you want to reject following requested interface: " }, + {"U9018","Ticket rejected." }, + {"U9036","Rejected by Admin" }, + {"state","State" }, + {"criticality","Criticality" }, + {"additional_info","Additional Info" }, + {"active","Active" }, + {"inactive","Inactive" }, + {"ticket","Ticket" }, + {"tasks","Tasks" }, + {"requester","Requester" }, + {"reference_date","Reference date" }, + {"U4003","Overdue owners" }, + {"U4004","No overdue owners." }, + {"U4005","Owners due within @@DAYS@@ days" }, + {"U4006","No owners due within @@DAYS@@ days." }, + {"U4007","Further active owners" }, + {"U4008","Further owners" }, + {"U4009","Owners with inactive recertification" }, + {"created","Created" }, + {"closed","Closed" }, + {"task_number","Task Number" }, + {"start_time","Start Time" }, + {"end_time","End Time" }, + {"implementation","Implementation" }, + {"approval","Approval" }, + {"opened","Opened" }, + {"approved","Approved" }, + {"U9012","Requested Interface" }, + {"E9004","Missing Source/Destination or Service" }, + {"E9005","Source/Destination changed" }, + {"E9020","Interface in use by other app" }, + {"E5102","Missing name or reason" }, + {"E9006","Missing source/destination or service" }, + {"U9022","Network areas on other side" }, + {"U9021","Interfaces cannot use areas" }, + {"U9023","Common areas not allowed" }, + {"E9015","Insert not allowed" }, + {"select","Select" }, + {"E9021","Interface permission required" }, + {"decomm_interface","Decommission Interface" }, + {"send_email","Send Email"}, + {"U9033","Emails sent to @@OK_NUMBER@@ owners."}, + {"E9019","Email could not be sent to @@FAIL_NUMBER@@ owners."}, + {"notification","Notification" }, + {"edit_policy","Edit policy" }, + {"criteria","Criteria"}, + {"add","Add"}, + {"cancel","Cancel"}, + {"change_default","Change default"}, + {"save","Save"}, + {"monitoring","Monitoring"}, + {"modelling","Modelling"}, + {"object_users","Object users"}, + {"app_role_users","App role users"}, + {"orphaned_view","Show orphaned only"}, + {"remove_all_orphans","Remove all orphans"}, + {"U7103","Remove all orphans?"}, + {"orphaned_entries_removed","Orphaned entries removed"}, + {"orphaned_app_roles","Orphaned app roles"}, + {"app_servers","App servers"}, + {"orphaned_app_servers","Orphaned app servers"}, + {"network_areas","Network areas"}, + {"orphaned_network_areas","Orphaned network areas"}, + {"service_groups","Service groups"}, + {"services_groups","Service groups"}, + {"orphaned_service_groups","Orphaned service groups"}, + {"orphaned_services","Orphaned services"}, + {"app_role","App role"}, + {"app_server","App server"}, + {"network_area","Network area"}, + {"service_group","Service group"}, + {"service","Service"}, + {"C9029","Orphaned tooltip"}, + {"U7001","Monitoring intro"}, + {"open_alerts","Open alerts"}, + {"no_open_alerts","No open alerts"}, + {"acknowledge_all","Acknowledge all"}, + {"actions","Actions"}, + {"details","Details"}, + {"acknowledge","Acknowledge"}, + {"timestamp","Timestamp"}, + {"title","Title"}, + {"code","Code"}, + {"description","Description"}, + {"remove_sample_data","Remove sample data"}, + {"U7003","Remove sample data message"}, + {"U7102","Acknowledge all message"}, + {"acknowledge_alert","Acknowledge alert"}, + {"alerts_acknowledged","alerts acknowledged"}, + {"E7015","Acknowledge failed"}, + {"confirm","Confirm"}, + {"delete","Delete"}, + {"remove","Remove"}, + {"PagerPagesize","Page size"}, + {"PagerSubmit","Apply"}, + {"loading","Loading"}, + {"in_progress","In progress"}, + {"rollback_import","Rollback import"}, + {"U5104","Rollback message start"}, + {"U5105","Rollback message end"}, + {"U5106","No import to rollback"}, + {"U5120","Some Details for modelling objects."}, + {"rollback","Rollback"}, + {"full_rollback","Full rollback"}, + {"not_imported_yet","Not imported yet"}, + {"U51XX","Import missing"}, + {"U5107","Rollback done"}, + {"import_status_details","Import status details: "}, + {"import_enabled","Import enabled"}, + {"first_import","First import"}, + {"import_id","Import id"}, + {"start","Start"}, + {"stop","Stop"}, + {"duration","Duration"}, + {"success","Success"}, + {"errors","Errors"}, + {"last_successful_import","Last successful import"}, + {"err_since_last_succ","Errors since last success"}, + {"last_import","Last import"}, + {"ok","OK"}, + {"autodiscovery","Autodiscovery"}, + {"disable","Disable"}, + {"gateways","Gateways"}, + {"nothing_more_to_change","Nothing more to change"}, + {"do_all_changes","Do all changes"}, + {"delete_management","Delete management"}, + {"delete_gateway","Delete gateway"}, + {"change_management_state","Change management state"}, + {"save_management","Save management"}, + {"save_gateway","Save gateway"}, + {"alert","Alert"}, + {"analyze_actions","Analyze actions"}, + {"E7001","Already done"}, + {"E7002","Reference missing"}, + {"E7003","Delete in progress"}, + {"E5106","Management already active"}, + {"E5107","Gateway already active"}, + {"E5112","Save gateway failed"}, + {"U5101","Delete management "}, + {"U5103","Delete gateway "}, + {"U7002","Confirm"}, + {"add_device_to_tenant0","Add device to tenant"}, + {"acknowledge_action","Acknowledge action"}, + {"C9021","Not implemented"}, + {"C9022","Variance found"}, + {"C9023","Modelling ok"}, + {"C9024","Implementation ok"}, + {"C9025","Variance not checked"}, + {"C9026","Interface decommissioned"}, + {"C9028","Interface no permission"}, + {"C9030","Foreign non production groups on used interface"}, + {"C9019","Empty service groups (interface)"}, + {"C9018","Empty service groups"}, + {"C9020","Documentation only"}, + {"C9015","Empty app roles (interface)"}, + {"C9013","Empty app roles"}, + {"C9016","Deleted objects (interface)"}, + {"C9014","Deleted objects"}, + {"TicketReport","Ticket Report"}, + {"TicketChangeReport","Ticket Change Report"}, + {"workflow_filters","Workflow Filters"}, + {"variance_filters","Variance Filters"}, + {"rules_for_deleted_conns","Rules from deleted connections"}, + {"analyse_remaining_rules","Analyse remaining rules"}, + {"task_type","Task type"}, + {"phase","Phase"}, + {"label","Label"}, + {"existing","existing"}, + {"not_existing","not existing"}, + {"value","value"}, + {"TicketCreation","Ticket creation"}, + {"TicketClosure","Ticket closure"}, + {"ApprovalOpened","Approval opened"}, + {"Approved","Approved"}, + {"TaskStart","Task start"}, + {"TaskEnd","Task end"}, + {"ImplementationStart","Implementation start"}, + {"ImplementationEnd","Implementation end"}, + {"AnyActivity","Any activity"}, + {"access","access"}, + {"rule_modify","rule modify"}, + {"rule_delete","rule delete"}, + {"new_interface","new interface"}, + {"now","now"}, + {"today","today"}, + {"last","last"}, + {"day","day"}, + {"week","week"}, + {"month","month"}, + {"year","year"}, + {"modRequestOnlyOwnObjects","Request only own objects"}, + {"H5668","Request only own objects help"}, + {"change_id","Change-ID"}, + {"H1517","Reference date tooltip"}, + {"H1518","Task type tooltip"}, + {"H1519","State tooltip"}, + {"H1520","Show full ticket tooltip"}, + {"H1521","Phase tooltip"}, + {"H1524","Detailed view tooltip"}, + {"detailed_view","Detailed View"} + }; + + public override string GetText(string key) + { + return DummyTranslate[key]; + } + + public static ConfigItem[] GetAsConfigs() + { + List configs = []; + foreach (var dictValuePair in DummyTranslate) + { + configs.Add(new() { Key = dictValuePair.Key, Value = dictValuePair.Value, User = 0 }); + } + return [.. configs]; + } + } +} diff --git a/roles/tests-unit/files/FWO.Test/StateMatrixTest.cs b/roles/tests-unit/files/FWO.Test/StateMatrixTest.cs new file mode 100644 index 0000000000..9889d5c127 --- /dev/null +++ b/roles/tests-unit/files/FWO.Test/StateMatrixTest.cs @@ -0,0 +1,187 @@ +using FWO.Services.Workflow; +using NUnit.Framework; + +namespace FWO.Test +{ + [TestFixture] + internal class StateMatrixTest + { + [Test] + public void GetNextActivePhase_ReturnsNextActivePhase() + { + StateMatrix matrix = new() + { + PhaseActive = + { + [WorkflowPhases.request] = true, + [WorkflowPhases.approval] = false, + [WorkflowPhases.planning] = true, + [WorkflowPhases.implementation] = true + } + }; + WorkflowPhases phase = WorkflowPhases.request; + + bool moved = matrix.getNextActivePhase(ref phase); + + Assert.That(moved, Is.True); + Assert.That(phase, Is.EqualTo(WorkflowPhases.planning)); + } + + [Test] + public void GetNextActivePhase_ReturnsFalse_WhenNoneAvailable() + { + StateMatrix matrix = new() + { + PhaseActive = + { + [WorkflowPhases.request] = true, + [WorkflowPhases.approval] = false + } + }; + WorkflowPhases phase = WorkflowPhases.approval; + + bool moved = matrix.getNextActivePhase(ref phase); + + Assert.That(moved, Is.False); + Assert.That(phase, Is.EqualTo(WorkflowPhases.approval)); + } + + [Test] + public void GetAllowedTransitions_ReturnsMatrixOrEmpty() + { + StateMatrix matrix = new(); + matrix.Matrix[1] = [2, 3]; + + Assert.That(matrix.getAllowedTransitions(1), Is.EqualTo(new List { 2, 3 })); + Assert.That(matrix.getAllowedTransitions(99), Is.Empty); + } + + [Test] + public void GetAllowedTransitions_FiltersAutomaticOnlyStates_ByDefault() + { + StateMatrix matrix = new() + { + AutomaticOnlyStates = [3] + }; + matrix.Matrix[1] = [2, 3]; + + Assert.That(matrix.getAllowedTransitions(1), Is.EqualTo(new List { 2 })); + } + + [Test] + public void GetAllowedTransitions_CanIncludeAutomaticOnlyStates() + { + StateMatrix matrix = new() + { + AutomaticOnlyStates = [3] + }; + matrix.Matrix[1] = [2, 3]; + + Assert.That(matrix.getAllowedTransitions(1, allowAutomaticOnlyStates: true), Is.EqualTo(new List { 2, 3 })); + } + + [Test] + public void GetDerivedStateFromSubStates_ReturnsZeroWhenEmpty() + { + StateMatrix matrix = new(); + + int derived = matrix.getDerivedStateFromSubStates([]); + + Assert.That(derived, Is.EqualTo(0)); + } + + [Test] + public void GetDerivedStateFromSubStates_UsesBackAssignedState() + { + StateMatrix matrix = new() + { + LowestInputState = 10, + LowestStartedState = 20, + LowestEndState = 30 + }; + + int derived = matrix.getDerivedStateFromSubStates([5, 15, 25]); + + Assert.That(derived, Is.EqualTo(5)); + } + + [Test] + public void GetDerivedStateFromSubStates_UsesInWorkState() + { + StateMatrix matrix = new() + { + LowestInputState = 10, + LowestStartedState = 20, + LowestEndState = 30 + }; + + int derived = matrix.getDerivedStateFromSubStates([12, 22, 24]); + + Assert.That(derived, Is.EqualTo(22)); + } + + [Test] + public void GetDerivedStateFromSubStates_UsesMinFinishedState_WhenAllFinished() + { + StateMatrix matrix = new() + { + LowestInputState = 10, + LowestStartedState = 20, + LowestEndState = 30 + }; + + int derived = matrix.getDerivedStateFromSubStates([35, 40]); + + Assert.That(derived, Is.EqualTo(35)); + } + + [Test] + public void GetDerivedStateFromSubStates_UsesInitState_WhenAllOpen() + { + StateMatrix matrix = new() + { + LowestInputState = 10, + LowestStartedState = 20, + LowestEndState = 30 + }; + + int derived = matrix.getDerivedStateFromSubStates([10, 11]); + + Assert.That(derived, Is.EqualTo(11)); + } + + [Test] + public void GetDerivedStateFromSubStates_UsesLowestStarted_WhenMixedOpenAndFinished() + { + StateMatrix matrix = new() + { + LowestInputState = 10, + LowestStartedState = 20, + LowestEndState = 30 + }; + + int derived = matrix.getDerivedStateFromSubStates([10, 31]); + + Assert.That(derived, Is.EqualTo(20)); + } + + [Test] + public void GetDerivedStateFromSubStates_AppliesDerivedStatesMapping() + { + StateMatrix matrix = new() + { + LowestInputState = 10, + LowestStartedState = 20, + LowestEndState = 30, + DerivedStates = + { + [11] = 99 + } + }; + + int derived = matrix.getDerivedStateFromSubStates([10, 11]); + + Assert.That(derived, Is.EqualTo(99)); + } + } +} diff --git a/roles/tests-unit/files/FWO.Test/StringExtensionsTest.cs b/roles/tests-unit/files/FWO.Test/StringExtensionsTest.cs new file mode 100644 index 0000000000..7e22221201 --- /dev/null +++ b/roles/tests-unit/files/FWO.Test/StringExtensionsTest.cs @@ -0,0 +1,646 @@ +using NUnit.Framework; +using NUnit.Framework.Legacy; +using FWO.Data; +using FWO.Basics; + +namespace FWO.Test +{ + [TestFixture] + [Parallelizable] + internal class StringExtensionsTest + { + #region StringExtensionsSanitizer + static readonly string OkText = "ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz1234567890.*-:?@/()[]{}$+<>#_"; + static readonly string TextToShorten = " A\"\\'!,; "; + static readonly string ShortenedText = "A"; + static readonly string OkLdapName = "ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz1234567890.*-:?@/()_"; + static readonly string LdapNameToShorten = " A+;,\"<>#= B "; + static readonly string ShortenedLdapName = "A B"; + static readonly string OkLdapPath = "ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz1234567890.*-:?@/()_,="; + static readonly string LdapPathToShorten = " A+;,\"<>#= B "; + static readonly string ShortenedLdapPath = "A,= B"; + static readonly string OkPassw = "ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz1234567890.*-:?@/()[]{}$+<>#"; + static readonly string PasswToShorten = " a \n\rb "; + static readonly string ShortenedPassw = "a b"; + static readonly string OkKey = "ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz1234567890.*-:?@/()[]{}$+<>#_\"\\'!,;"; + static readonly string KeyToShorten = " anykey "; + static readonly string ShortenedKey = "anykey"; + static readonly string OkComment = "ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz1234567890.*-:?@/()[]{}$+<>#_\\!,;"; + static readonly string CommentToShorten = "\"anytext'"; + static readonly string ShortenedComment = "anytext"; + static readonly string OkCidr = "1234567890ABCDEFabcdef:./"; + static readonly string CidrToShorten = " FGHIJKLMNOPQRSTUVWXYZ fghijklmnopqrstuvwxyz?@()[]{}$+<>#_\\!,; "; + static readonly string ShortenedCidr = "Ff"; + static readonly string OkJson = "1234567890ABCDEFabcdef:._{a§}+*(){}[]?!#<>=,;/\\@$%^|&"; + static readonly string JsonToShorten = " {\t\n\r}"; + static readonly string ShortenedJson = "{}"; + static readonly string OkJsonField = "1234567890ABCDEFabcdef:._"; + static readonly string JsonFieldToShorten = " {a§}+*(){}[]?!#<>=,;/\\\t@$%^|&~ "; + static readonly string ShortenedJsonField = "_a§___________________________"; + + [SetUp] + public void Initialize() + { } + + [Test] + public void TestSanitizer() + { + bool shortened = false; + string? nullString = null; + ClassicAssert.AreEqual(null, nullString.SanitizeOpt(ref shortened)); + ClassicAssert.AreEqual(false, shortened); + ClassicAssert.AreEqual(OkText, OkText.SanitizeOpt(ref shortened)); + ClassicAssert.AreEqual(false, shortened); + ClassicAssert.AreEqual(OkText, OkText.SanitizeMand(ref shortened)); + ClassicAssert.AreEqual(false, shortened); + ClassicAssert.AreEqual(ShortenedText, TextToShorten.SanitizeMand(ref shortened)); + ClassicAssert.AreEqual(true, shortened); + + shortened = false; + ClassicAssert.AreEqual(null, nullString.SanitizeLdapNameOpt(ref shortened)); + ClassicAssert.AreEqual(OkLdapName, OkLdapName.SanitizeLdapNameOpt(ref shortened)); + ClassicAssert.AreEqual(false, shortened); + ClassicAssert.AreEqual(OkLdapName, OkLdapName.SanitizeLdapNameMand(ref shortened)); + ClassicAssert.AreEqual(false, shortened); + ClassicAssert.AreEqual(ShortenedLdapName, LdapNameToShorten.SanitizeLdapNameMand(ref shortened)); + ClassicAssert.AreEqual(true, shortened); + + shortened = false; + ClassicAssert.AreEqual(null, nullString.SanitizeLdapPathOpt(ref shortened)); + ClassicAssert.AreEqual(OkLdapPath, OkLdapPath.SanitizeLdapPathOpt(ref shortened)); + ClassicAssert.AreEqual(false, shortened); + ClassicAssert.AreEqual(OkLdapPath, OkLdapPath.SanitizeLdapPathMand(ref shortened)); + ClassicAssert.AreEqual(false, shortened); + ClassicAssert.AreEqual(ShortenedLdapPath, LdapPathToShorten.SanitizeLdapPathMand(ref shortened)); + ClassicAssert.AreEqual(true, shortened); + + shortened = false; + ClassicAssert.AreEqual(null, nullString.SanitizePasswOpt(ref shortened)); + ClassicAssert.AreEqual(OkPassw, OkPassw.SanitizePasswOpt(ref shortened)); + ClassicAssert.AreEqual(false, shortened); + ClassicAssert.AreEqual(OkPassw, OkPassw.SanitizePasswMand(ref shortened)); + ClassicAssert.AreEqual(false, shortened); + ClassicAssert.AreEqual(ShortenedPassw, PasswToShorten.SanitizePasswMand(ref shortened)); + ClassicAssert.AreEqual(true, shortened); + + shortened = false; + ClassicAssert.AreEqual(null, nullString.SanitizeKeyOpt(ref shortened)); + ClassicAssert.AreEqual(OkKey, OkKey.SanitizeKeyOpt(ref shortened)); + ClassicAssert.AreEqual(false, shortened); + ClassicAssert.AreEqual(OkKey, OkKey.SanitizeKeyMand(ref shortened)); + ClassicAssert.AreEqual(false, shortened); + ClassicAssert.AreEqual(ShortenedKey, KeyToShorten.SanitizeKeyMand(ref shortened)); + ClassicAssert.AreEqual(true, shortened); + + shortened = false; + ClassicAssert.AreEqual(null, nullString.SanitizeCommentOpt(ref shortened)); + ClassicAssert.AreEqual(OkComment, OkComment.SanitizeCommentOpt(ref shortened)); + ClassicAssert.AreEqual(false, shortened); + ClassicAssert.AreEqual(OkComment, OkComment.SanitizeCommentMand(ref shortened)); + ClassicAssert.AreEqual(false, shortened); + ClassicAssert.AreEqual(ShortenedComment, CommentToShorten.SanitizeCommentMand(ref shortened)); + ClassicAssert.AreEqual(true, shortened); + + shortened = false; + ClassicAssert.AreEqual(null, nullString.SanitizeCidrOpt(ref shortened)); + ClassicAssert.AreEqual(OkCidr, OkCidr.SanitizeCidrOpt(ref shortened)); + ClassicAssert.AreEqual(false, shortened); + ClassicAssert.AreEqual(OkCidr, OkCidr.SanitizeCidrMand(ref shortened)); + ClassicAssert.AreEqual(false, shortened); + ClassicAssert.AreEqual(ShortenedCidr, CidrToShorten.SanitizeCidrMand(ref shortened)); + ClassicAssert.AreEqual(true, shortened); + + shortened = false; + ClassicAssert.AreEqual(OkJson, OkJson.SanitizeJsonMand(ref shortened)); + ClassicAssert.AreEqual(false, shortened); + ClassicAssert.AreEqual(ShortenedJson, JsonToShorten.SanitizeJsonMand(ref shortened)); + ClassicAssert.AreEqual(true, shortened); + + shortened = false; + ClassicAssert.AreEqual(OkJsonField, OkJsonField.SanitizeJsonFieldMand(ref shortened)); + ClassicAssert.AreEqual(false, shortened); + ClassicAssert.AreEqual(ShortenedJsonField, JsonFieldToShorten.SanitizeJsonFieldMand(ref shortened)); + ClassicAssert.AreEqual(true, shortened); + } + + + // --- SanitizeMand & SanitizeOpt --- + [TestCase("abcDEF123._-*:?@/()[]{}$+<># ", "abcDEF123._-*:?@/()[]{}$+<>#", true)] + [TestCase("abc!def§ghi", "abcdefghi", true)] + public void SanitizeMand_Works(string input, string expected, bool expectedShortened) + { + bool shortened = false; + string result = input.SanitizeMand(ref shortened); + Assert.That(result, Is.EqualTo(expected)); + Assert.That(shortened, Is.EqualTo(expectedShortened)); + } + + [Test] + public void SanitizeOpt_Null_ReturnsNull() + { + string? input = null; + bool shortened = false; + string? result = input.SanitizeOpt(ref shortened); + Assert.That(result, Is.Null); + Assert.That(shortened, Is.False); + } + + // --- SanitizeLdapNameMand & Opt --- + [TestCase("CN-User.Name@domain()", "CN-User.Name@domain()", false)] + [TestCase("User!Name§", "UserName", true)] + public void SanitizeLdapNameMand_Works(string input, string expected, bool expectedShortened) + { + bool shortened = false; + string result = input.SanitizeLdapNameMand(ref shortened); + Assert.That(result, Is.EqualTo(expected)); + Assert.That(shortened, Is.EqualTo(expectedShortened)); + } + + [Test] + public void SanitizeLdapNameOpt_Null_ReturnsNull() + { + string? input = null; + bool shortened = false; + string? result = input.SanitizeLdapNameOpt(ref shortened); + Assert.That(result, Is.Null); + } + + // --- SanitizeLdapPathMand & Opt --- + [TestCase("CN=User,OU=Dept,DC=example,DC=com", "CN=User,OU=Dept,DC=example,DC=com", false)] + [TestCase("CN=User§,OU=Dept!", "CN=User,OU=Dept", true)] + public void SanitizeLdapPathMand_Works(string input, string expected, bool expectedShortened) + { + bool shortened = false; + string result = input.SanitizeLdapPathMand(ref shortened); + Assert.That(result, Is.EqualTo(expected)); + Assert.That(shortened, Is.EqualTo(expectedShortened)); + } + + [Test] + public void SanitizeLdapPathOpt_Null_ReturnsNull() + { + string? input = null; + bool shortened = false; + string? result = input.SanitizeLdapPathOpt(ref shortened); + Assert.That(result, Is.Null); + } + + // --- SanitizePasswMand & Opt --- + [TestCase("password123", "password123", false)] + [TestCase("pass\tword\n", "password", true)] + public void SanitizePasswMand_Works(string input, string expected, bool expectedShortened) + { + bool shortened = false; + string result = input.SanitizePasswMand(ref shortened); + Assert.That(result, Is.EqualTo(expected)); + Assert.That(shortened, Is.EqualTo(expectedShortened)); + } + + [Test] + public void SanitizePasswOpt_Null_ReturnsNull() + { + string? input = null; + bool shortened = false; + string? result = input.SanitizePasswOpt(ref shortened); + Assert.That(result, Is.Null); + } + + // --- SanitizeKeyMand & Opt --- + [TestCase(" key ", "key", true)] + [TestCase("clean", "clean", false)] + public void SanitizeKeyMand_Trims(string input, string expected, bool expectedShortened) + { + bool shortened = false; + string result = input.SanitizeKeyMand(ref shortened); + Assert.That(result, Is.EqualTo(expected)); + Assert.That(shortened, Is.EqualTo(expectedShortened)); + } + + [Test] + public void SanitizeKeyOpt_Null_ReturnsNull() + { + string? input = null; + bool shortened = false; + string? result = input.SanitizeKeyOpt(ref shortened); + Assert.That(result, Is.Null); + } + + // --- SanitizeCommentMand & Opt --- + [TestCase("comment", "comment", false)] + [TestCase("\"quoted\" and 'single'", "quoted and single", true)] + public void SanitizeCommentMand_RemovesQuotes(string input, string expected, bool expectedShortened) + { + bool shortened = false; + string result = input.SanitizeCommentMand(ref shortened); + Assert.That(result, Is.EqualTo(expected)); + Assert.That(shortened, Is.EqualTo(expectedShortened)); + } + + [Test] + public void SanitizeCommentOpt_Null_ReturnsNull() + { + string? input = null; + bool shortened = false; + string? result = input.SanitizeCommentOpt(ref shortened); + Assert.That(result, Is.Null); + } + + // --- SanitizeCidrMand & Opt --- + [TestCase("192.168.0.1/24", "192.168.0.1/24", false)] + [TestCase("192.168.0.1/24x", "192.168.0.1/24", true)] + public void SanitizeCidrMand_Works(string input, string expected, bool expectedShortened) + { + bool shortened = false; + string result = input.SanitizeCidrMand(ref shortened); + Assert.That(result, Is.EqualTo(expected)); + Assert.That(shortened, Is.EqualTo(expectedShortened)); + } + + [Test] + public void SanitizeCidrOpt_Null_ReturnsNull() + { + string? input = null; + bool shortened = false; + string? result = input.SanitizeCidrOpt(ref shortened); + Assert.That(result, Is.Null); + } + + // --- SanitizeJsonMand --- + [TestCase("{\"key\":\"value\"}", "{\"key\":\"value\"}", false)] + [TestCase("{\"key\":\t\"value\"}", "{\"key\":\"value\"}", true)] + public void SanitizeJsonMand_Works(string input, string expected, bool expectedShortened) + { + bool shortened = false; + string result = input.SanitizeJsonMand(ref shortened); + Assert.That(result, Is.EqualTo(expected)); + Assert.That(shortened, Is.EqualTo(expectedShortened)); + } + + // --- SanitizeJsonFieldMand --- + [TestCase("fieldName", "fieldName", false)] + [TestCase("field+name", "field_name", true)] + [TestCase("test@field", "test_field", true)] + public void SanitizeJsonFieldMand_ReplacesInvalidChars(string input, string expected, bool expectedChanged) + { + bool changed = false; + string result = input.SanitizeJsonFieldMand(ref changed); + Assert.That(result, Is.EqualTo(expected)); + Assert.That(changed, Is.EqualTo(expectedChanged)); + } + + // --- SanitizeEolMand --- + [TestCase("line1 line2", "line1 line2", false)] + [TestCase("line1\nline2\rline3", "line1 line2 line3", false)] + public void SanitizeEolMand_ReplacesNewlinesWithSpaces(string input, string expected, bool expectedShortened) + { + bool shortened = false; + string result = input.SanitizeEolMand(ref shortened); + Assert.That(result, Is.EqualTo(expected)); + Assert.That(shortened, Is.EqualTo(expectedShortened)); + } + + + [TestCase(" text ", "text", true)] + [TestCase("text", "text", false)] + [TestCase("\t\ntext\r\n", "text", true)] + [TestCase(" ", "", true)] + [TestCase("\n\t", "", true)] + [TestCase("text with spaces", "text with spaces", false)] + [TestCase("", "", false)] + public void AllSanitizers_TrimWhitespace(string input, string expectedOutput, bool expectedShortened) + { + bool shortened; + + // Mandatory Sanitizers + shortened = false; + Assert.That(input.SanitizeMand(ref shortened), Is.EqualTo(expectedOutput)); + Assert.That(shortened, Is.EqualTo(expectedShortened)); + + shortened = false; + Assert.That(input.SanitizeLdapNameMand(ref shortened), Is.EqualTo(expectedOutput)); + Assert.That(shortened, Is.EqualTo(expectedShortened)); + + shortened = false; + Assert.That(input.SanitizeLdapPathMand(ref shortened), Is.EqualTo(expectedOutput)); + Assert.That(shortened, Is.EqualTo(expectedShortened)); + + shortened = false; + Assert.That(input.SanitizePasswMand(ref shortened), Is.EqualTo(expectedOutput)); + Assert.That(shortened, Is.EqualTo(expectedShortened)); + + shortened = false; + Assert.That(input.SanitizeKeyMand(ref shortened), Is.EqualTo(expectedOutput)); + Assert.That(shortened, Is.EqualTo(expectedShortened)); + + shortened = false; + Assert.That(input.SanitizeCommentMand(ref shortened), Is.EqualTo(expectedOutput)); + Assert.That(shortened, Is.EqualTo(expectedShortened)); + + shortened = false; + Assert.That(input.SanitizeJsonMand(ref shortened), Is.EqualTo(expectedOutput)); + Assert.That(shortened, Is.EqualTo(expectedShortened)); + + bool changed = false; + Assert.That(input.SanitizeJsonFieldMand(ref changed), Is.EqualTo(expectedOutput.Replace(" ", "_"))); + if (input == "text with spaces") + { + expectedShortened = true; + Assert.That(changed, Is.EqualTo(expectedShortened)); + expectedShortened = false; + } + + shortened = false; + Assert.That(input.SanitizeEolMand(ref shortened), Is.EqualTo(expectedOutput)); + Assert.That(shortened, Is.EqualTo(expectedShortened)); + + // Optional Sanitizers + shortened = false; + Assert.That(input.SanitizeOpt(ref shortened), Is.EqualTo(expectedOutput)); + Assert.That(shortened, Is.EqualTo(expectedShortened)); + + shortened = false; + Assert.That(input.SanitizeLdapNameOpt(ref shortened), Is.EqualTo(expectedOutput)); + Assert.That(shortened, Is.EqualTo(expectedShortened)); + + shortened = false; + Assert.That(input.SanitizeLdapPathOpt(ref shortened), Is.EqualTo(expectedOutput)); + Assert.That(shortened, Is.EqualTo(expectedShortened)); + + shortened = false; + Assert.That(input.SanitizePasswOpt(ref shortened), Is.EqualTo(expectedOutput)); + Assert.That(shortened, Is.EqualTo(expectedShortened)); + + shortened = false; + Assert.That(input.SanitizeKeyOpt(ref shortened), Is.EqualTo(expectedOutput)); + Assert.That(shortened, Is.EqualTo(expectedShortened)); + + shortened = false; + Assert.That(input.SanitizeCommentOpt(ref shortened), Is.EqualTo(expectedOutput)); + Assert.That(shortened, Is.EqualTo(expectedShortened)); + } + + [TestCase(" 192.168.1.1/24 ", "192.168.1.1/24", true)] + [TestCase("192.168.1.1/24", "192.168.1.1/24", false)] + [TestCase("\t10.0.0.1/8\n", "10.0.0.1/8", true)] + [TestCase(" ", "", true)] // nur Whitespaces + [TestCase("\n\t", "", true)] // nur Steuerzeichen + [TestCase("", "", false)] // leerer String + public void CidrSanitizers_TrimWhitespace(string input, string expectedOutput, bool expectedShortened) + { + bool shortened; + + // Mandatory + shortened = false; + Assert.That(input.SanitizeCidrMand(ref shortened), Is.EqualTo(expectedOutput)); + Assert.That(shortened, Is.EqualTo(expectedShortened)); + + // Optional + shortened = false; + Assert.That(input.SanitizeCidrOpt(ref shortened), Is.EqualTo(expectedOutput)); + Assert.That(shortened, Is.EqualTo(expectedShortened)); + } + + #endregion + + #region StringExtensionsLdap + // --- ExtractCommonNameFromDn --- + [TestCase("CN=John Doe,OU=Users,DC=example,DC=com", "John Doe")] + [TestCase("CN=Alice", "Alice")] + [TestCase("OU=Users,DC=example,DC=com", "")] + [TestCase("", "")] + [TestCase(null, "")] + [TestCase("OU=Users,CN=Bob", "Bob")] + [TestCase("CN=Alice,CN=Bob,OU=Users", "Alice")] + [TestCase("CN= John Doe ,OU=Users", " John Doe ")] // evtl. Trim sinnvoll + [TestCase("cn=Charlie,OU=Users", "Charlie")] + [TestCase("C=Country", "")] + public void ExtractCommonNameFromDn_Works(string dn, string expected) + { + string result = dn.ExtractCommonNameFromDn(); + Assert.That(result, Is.EqualTo(expected)); + } + #endregion + + #region StringExtensionsIp + + // --- StripHtmlTags --- + [TestCase("bold", "bold")] + [TestCase("no tags", "no tags")] + [TestCase("italic
                      ", "italic")] + [TestCase("", "")] + [TestCase("text", "text")] + [TestCase("
                      line
                      ", "line")] + [TestCase("bolditalic", "bolditalic")] + [TestCase("boldtag", "boldtag")] + [TestCase("upper", "upper")] + [TestCase("text & more", "text & more")] + public void StripHtmlTags_Works(string input, string expected) + { + string result = input.StripHtmlTags(); + Assert.That(result, Is.EqualTo(expected)); + } + + // --- StripDangerousHtmlTags --- + [TestCase("
                      line
                      ", "
                      line
                      ")] + [TestCase("", "alert(1)")] + [TestCase("bold", "bold")] + [TestCase("italic", "italic")] + [TestCase("text", "eviltext")] + [TestCase("
                      line
                      ", "line
                      ")] + [TestCase("bolditalic", "bolditalic")] + [TestCase("fictitious tag", "fictitious tag")] + [TestCase("fictitious tag", "fictitious tag")] + public void StripDangerousHtmlTags_Works(string input, string expected) + { + string result = input.StripDangerousHtmlTags(); + Assert.That(result, Is.EqualTo(expected)); + } + + // --- IsIPv4 / IsIPv6 --- + [TestCase("192.168.0.1", true, false)] + [TestCase("::1", false, true)] + [TestCase("invalid", false, false)] + public void IsIPVersion_Works(string input, bool expectedV4, bool expectedV6) + { + Assert.That(input.IsIPv4(), Is.EqualTo(expectedV4)); + Assert.That(input.IsIPv6(), Is.EqualTo(expectedV6)); + } + + // --- IsV4Address / IsV6Address --- + [TestCase("192.168.1.1", true, false)] + [TestCase("fe80::1", false, true)] + [TestCase("hello", false, false)] + public void IsVxAddress_Works(string input, bool expectedV4, bool expectedV6) + { + Assert.That(input.IsV4Address(), Is.EqualTo(expectedV4)); + Assert.That(input.IsV6Address(), Is.EqualTo(expectedV6)); + } + + // --- StripOffNetmask / StripOffUnnecessaryNetmask / GetNetmask --- + [TestCase("192.168.1.1/24", "192.168.1.1", "24")] + [TestCase("192.168.1.1/32", "192.168.1.1", "32")] + [TestCase("fe80::1/64", "fe80::1", "64")] + [TestCase("fe80::1/128", "fe80::1", "128")] + [TestCase("10.0.0.1", "10.0.0.1", "")] + public void NetmaskMethods_Works(string input, string expectedStrip, string expectedNetmask) + { + Assert.That(input.StripOffNetmask(), Is.EqualTo(expectedStrip)); + Assert.That(input.GetNetmask(), Is.EqualTo(expectedNetmask)); + + // StripOffUnnecessaryNetmask removes /32 for IPv4 and /128 for IPv6 + if (expectedNetmask == "32" || expectedNetmask == "128") + Assert.That(input.StripOffUnnecessaryNetmask(), Is.EqualTo(expectedStrip)); + else + Assert.That(input.StripOffUnnecessaryNetmask(), Is.EqualTo(input)); + } + + // --- TrySplit --- + [TestCase("a,b,c", ',', 0, true, "a")] + [TestCase("a,b,c", ',', 2, true, "c")] + [TestCase("a,b,c", ',', 3, false, "")] + [TestCase("single", ',', 0, false, "")] + [TestCase(",a,b,", ',', 0, true, "")] + [TestCase(",a,b,", ',', 3, true, "")] + [TestCase(",a,b,", ',', 4, false, "")] + [TestCase("", ',', 0, false, "")] + public void TrySplit_ByIndex_Works(string input, char sep, int index, bool expectedResult, string expectedOutput) + { + bool result = input.TrySplit(sep, index, out string output); + Assert.That(result, Is.EqualTo(expectedResult)); + Assert.That(output, Is.EqualTo(expectedOutput)); + } + + [TestCase("a,b,c", ',', true, 3)] + [TestCase("single", ',', false, 0)] + public void TrySplit_ByLength_Works(string input, char sep, bool expectedResult, int expectedLength) + { + bool result = input.TrySplit(sep, out int length); + Assert.That(result, Is.EqualTo(expectedResult)); + Assert.That(length, Is.EqualTo(expectedLength)); + } + + // --- TryGetNetmask --- + [TestCase("192.168.1.1/24", true, "/24")] + [TestCase("10.0.0.1", false, "")] + [TestCase("192.168.1.1/0", true, "/0")] + //[TestCase("192.168.1.1/33", false, "")] + [TestCase("fe80::1/127", true, "/127")] + //[TestCase("fe80::1/129", false, "")] + public void TryGetNetmask_Works(string input, bool expectedResult, string expectedNetmask) + { + bool result = input.TryGetNetmask(out string netmask); + Assert.That(result, Is.EqualTo(expectedResult)); + Assert.That(netmask, Is.EqualTo(expectedNetmask)); + } + + // --- Compare / IsGreater / GenerousCompare --- + [TestCase("192.168.1.1", "192.168.1.2", -1)] + [TestCase("192.168.1.2", "192.168.1.1", 1)] + [TestCase("192.168.1.1", "192.168.1.1", 0)] + [TestCase("fe80::1", "fe80::2", -1)] + [TestCase("fe80::2", "fe80::1", 1)] + [TestCase("fe80::1", "fe80::1", 0)] + [TestCase("192.168.1.1", "fe80::1", -1)] + [TestCase("fe80::1", "192.168.1.1", 1)] + public void CompareIPs_Works(string left, string right, int expected) + { + int result = left.Compare(right); + Assert.That(Math.Sign(result), Is.EqualTo(Math.Sign(expected))); + } + + [TestCase("192.168.1.2", "192.168.1.1", true)] + [TestCase("192.168.1.1", "192.168.1.2", false)] + public void IsGreater_Works(string left, string right, bool expected) + { + bool result = left.IsGreater(right); + Assert.That(result, Is.EqualTo(expected)); + } + + [TestCase(null, null, true)] + [TestCase("", "", true)] + [TestCase("abc", "abc", true)] + [TestCase("abc", "def", false)] + public void GenerousCompare_Works(string s1, string s2, bool expected) + { + bool result = s1.GenerousCompare(s2); + Assert.That(result, Is.EqualTo(expected)); + } + + // --- CidrToRange / CidrToRangeString --- + [TestCase("192.168.1.0/24", "192.168.1.0", "192.168.1.255")] + [TestCase("::1/128", "::1", "::1")] + [TestCase("0.0.0.0/0", "0.0.0.0", "255.255.255.255")] + [TestCase("::/0", "::", "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff")] + public void CidrToRangeString_Works(string cidr, string expectedStart, string expectedEnd) + { + var (start, end) = cidr.CidrToRangeString(); + Assert.That(start, Is.EqualTo(expectedStart)); + Assert.That(end, Is.EqualTo(expectedEnd)); + + var (ipStart, ipEnd) = cidr.CidrToRange(); + Assert.That(ipStart.ToString(), Is.EqualTo(expectedStart)); + Assert.That(ipEnd.ToString(), Is.EqualTo(expectedEnd)); + } + + // --- ReplaceAll --- + [TestCase("", new string[] { "a", "b" }, "X", "")] + [TestCase("aaa", new string[] { "a", "aa" }, "X", "XXX")] + [TestCase("abc", new string[0], "X", "abc")] + [TestCase("abcabc", new string[] { "a" }, "", "bcbc")] + public void ReplaceAll_EdgeCases_Works(string input, string[] values, string replacement, string expected) + { + string result = input.ReplaceAll(values, replacement); + Assert.That(result, Is.EqualTo(expected)); + } + + + // --- ToIPAdressAndSubnetMask --- + [TestCase("192.168.1.1/24", "192.168.1.1", "24")] + [TestCase("10.0.0.1", "10.0.0.1", "")] + [TestCase("192.168.1.1/32", "192.168.1.1", "32")] + [TestCase("fe80::1/128", "fe80::1", "128")] + [TestCase("192.168.1.1", "192.168.1.1", "")] + [TestCase("fe80::1", "fe80::1", "")] + public void ToIPAdressAndSubnetMask_Works(string input, string expectedIp, string expectedSubnet) + { + var (ip, subnet) = input.ToIPAdressAndSubnetMask(); + Assert.That(ip.ToString(), Is.EqualTo(expectedIp)); + Assert.That(subnet, Is.EqualTo(expectedSubnet)); + } + + // --- IpAsCidr --- + [TestCase("192.168.1.1", "192.168.1.1/32")] + [TestCase("192.168.1.0/24", "192.168.1.0/24")] + [TestCase("2001:db8::1", "2001:db8::1/128")] + [TestCase("2001:db8::/64", "2001:db8::/64")] + [TestCase("192.168.1.1/32", "192.168.1.1/32")] + [TestCase("2001:db8::1/128", "2001:db8::1/128")] + public void IpAsCidr_Works(string input, string expected) + { + string result = input.IpAsCidr(); + Assert.That(result, Is.EqualTo(expected)); + } + + // --- ToComparableIpString --- + [TestCase("192.168.1.1", 43)] + [TestCase("2001:db8::1", 43)] + public void ToComparableIpString_LengthIs43(string input, int expectedLength) + { + string result = input.ToComparableIpString(); + Assert.That(result.Length, Is.EqualTo(expectedLength)); + } + + // --- GetMatches --- + [TestCase("Name: John, Age: 30; Name: Alice, Age: 25", @"Name: (\w+)", 1, new[] { "John", "Alice" })] + [TestCase("No names here", @"Name: (\w+)", 1, new string[0])] + [TestCase("Value: 123, Value: 456", @"Value: (\d+)", 1, new[] { "123", "456" })] + [TestCase("X:1 Y:2", @"\w:(\d+)", 1, new[] { "1", "2" })] + public void GetMatches_Works(string input, string pattern, int groupIndex, string[] expected) + { + var result = input.GetMatches(pattern, groupIndex); + Assert.That(result, Is.EqualTo(expected)); + } + + #endregion + } +} diff --git a/roles/tests-unit/files/FWO.Test/TestAuthorizationService.cs b/roles/tests-unit/files/FWO.Test/TestAuthorizationService.cs new file mode 100644 index 0000000000..850127f541 --- /dev/null +++ b/roles/tests-unit/files/FWO.Test/TestAuthorizationService.cs @@ -0,0 +1,18 @@ +using Microsoft.AspNetCore.Authorization; +using System.Security.Claims; + +namespace FWO.Test +{ + internal sealed class AllowAllAuthorizationService : IAuthorizationService + { + public Task AuthorizeAsync(ClaimsPrincipal user, object? resource, IEnumerable requirements) + { + return Task.FromResult(AuthorizationResult.Success()); + } + + public Task AuthorizeAsync(ClaimsPrincipal user, object? resource, string policyName) + { + return Task.FromResult(AuthorizationResult.Success()); + } + } +} diff --git a/roles/tests-unit/files/FWO.Test/TestDataGeneratorTest.cs b/roles/tests-unit/files/FWO.Test/TestDataGeneratorTest.cs new file mode 100644 index 0000000000..36337b9c2b --- /dev/null +++ b/roles/tests-unit/files/FWO.Test/TestDataGeneratorTest.cs @@ -0,0 +1,227 @@ +using FWO.Basics.TestDataGeneration; +using System; +using System.Diagnostics; +using System.Linq; +using System.Net; +using System.Numerics; +using NUnit.Framework; +using NetTools; +using FWO.Data.Modelling; + +namespace FWO.Test +{ + [TestFixture] + public class TestDataGeneratorTest + { + [Test] + public void ImportOneInstance() + { + // ARRANGE + + TestDataGenerator testDataGenerator = new(); + string json = @" + { + ""id"": 0, + ""app_id"": null, + ""proposed_app_id"": null, + ""app"": {}, + ""name"": """", + ""reason"": """", + ""is_interface"": false, + ""used_interface_id"": null, + ""is_requested"": false, + ""is_published"": false, + ""ticket_id"": null, + ""common_service"": false, + ""creator"": null, + ""creation_date"": null, + ""conn_prop"": """", + ""extra_params"": """", + ""services"": [], + ""service_groups"": [], + ""source_nwobjects"": [], + ""source_approles"": [], + ""destination_nwobjects"": [], + ""destination_approles"": [], + ""source_areas"": [], + ""destination_areas"": [], + ""source_other_groups"": [], + ""destination_other_groups"": [], + ""src_from_interface"": false, + ""dst_from_interface"": false, + ""interface_is_requested"": false, + ""interface_is_rejected"": false, + ""order_number"": 0, + ""props"": null, + ""extra_configs"": [], + ""extra_configs_from_interface"": [] + }"; + ModellingConnection? generatedInstance; + + // ACT + + generatedInstance = testDataGenerator.ImportInstance(json).SingleInstance; + + // ASSERT + + Assert.Multiple(() => + { + Assert.That(generatedInstance, Is.Not.Null, "Generated instance should not be null."); + Assert.That(generatedInstance, Is.InstanceOf(), "Generated instance should be an instance of ModellingConnection."); + + Assert.That(generatedInstance!.Id, Is.EqualTo(0), "Id should be 0."); + Assert.That(generatedInstance.AppId, Is.Null, "AppId should be null."); + Assert.That(generatedInstance.ProposedAppId, Is.Null, "ProposedAppId should be null."); + Assert.That(generatedInstance.App, Is.Not.Null, "Owner should not be null."); + Assert.That(generatedInstance.Name, Is.EqualTo(""), "Name should be an empty string."); + Assert.That(generatedInstance.Reason, Is.EqualTo(""), "Reason should be an empty string."); + Assert.That(generatedInstance.IsInterface, Is.False, "IsInterface should be false."); + Assert.That(generatedInstance.UsedInterfaceId, Is.Null, "UsedInterfaceId should be null."); + Assert.That(generatedInstance.IsRequested, Is.False, "IsRequested should be false."); + Assert.That(generatedInstance.IsPublished, Is.False, "IsPublished should be false."); + Assert.That(generatedInstance.TicketId, Is.Null, "TicketId should be null."); + Assert.That(generatedInstance.IsCommonService, Is.False, "IsCommonService should be false."); + Assert.That(generatedInstance.Creator, Is.Null, "Creator should be null."); + Assert.That(generatedInstance.CreationDate, Is.Null, "CreationDate should be null."); + Assert.That(generatedInstance.Properties, Is.EqualTo(""), "Properties should be an empty string."); + Assert.That(generatedInstance.ExtraParams, Is.EqualTo(""), "ExtraParams should be an empty string."); + + // Listen prüfen + Assert.That(generatedInstance.Services, Is.Empty, "Services should be an empty list."); + Assert.That(generatedInstance.ServiceGroups, Is.Empty, "ServiceGroups should be an empty list."); + Assert.That(generatedInstance.SourceAppServers, Is.Empty, "SourceAppServers should be an empty list."); + Assert.That(generatedInstance.SourceAppRoles, Is.Empty, "SourceAppRoles should be an empty list."); + Assert.That(generatedInstance.DestinationAppServers, Is.Empty, "DestinationAppServers should be an empty list."); + Assert.That(generatedInstance.DestinationAppRoles, Is.Empty, "DestinationAppRoles should be an empty list."); + Assert.That(generatedInstance.SourceAreas, Is.Empty, "SourceAreas should be an empty list."); + Assert.That(generatedInstance.DestinationAreas, Is.Empty, "DestinationAreas should be an empty list."); + Assert.That(generatedInstance.SourceOtherGroups, Is.Empty, "SourceOtherGroups should be an empty list."); + Assert.That(generatedInstance.DestinationOtherGroups, Is.Empty, "DestinationOtherGroups should be an empty list."); + + // Boolean Flags + Assert.That(generatedInstance.SrcFromInterface, Is.False, "SrcFromInterface should be false."); + Assert.That(generatedInstance.DstFromInterface, Is.False, "DstFromInterface should be false."); + Assert.That(generatedInstance.InterfaceIsRequested, Is.False, "InterfaceIsRequested should be false."); + Assert.That(generatedInstance.InterfaceIsRejected, Is.False, "InterfaceIsRejected should be false."); + + Assert.That(generatedInstance.OrderNumber, Is.EqualTo(0), "OrderNumber should be 0."); + Assert.That(generatedInstance.Props, Is.Null, "Props should be null."); + Assert.That(generatedInstance.ExtraConfigs, Is.Empty, "ExtraConfigs should be an empty list."); + Assert.That(generatedInstance.ExtraConfigsFromInterface, Is.Empty, "ExtraConfigsFromInterface should be an empty list."); + }); + } + + [Test] + public void GenerateOneInstance() + { + // ARRANGE + TestDataGenerator testDataGenerator = new(); + string json = @" + { + ""config"": [ + { + ""set"": { + ""Name"": { + ""testinstance1"": 0.25, + ""testinstance2"": 0.25, + ""testinstance3"": 0.25, + ""testinstance4"": 0.25 + } + } + } + ] + }"; + ModellingConnection? generatedInstance; + List generatedInstances = new(); + int iterations = 100; + List validNames = new() { "testinstance1", "testinstance2", "testinstance3", "testinstance4" }; + + + // ACT + for (int i = 1; i <= iterations; i++) + { + generatedInstance = testDataGenerator.GenerateInstance(json).SingleInstance; + + if (generatedInstance != null) + { + generatedInstances.Add(generatedInstance); + } + + } + + + // ASSERT + Assert.That(generatedInstances, Has.Count.EqualTo(iterations), "Die Anzahl der generierten Instanzen stimmt nicht mit iterations überein."); + Assert.That(generatedInstances.All(instance => validNames.Contains(instance?.Name ?? "notinlist")), Is.True, "Mindestens eine generierte Instanz hat einen ungültigen Namen."); + } + + [Test] + public void GenerateInstance_UsesProbabilitySelection() + { + // ARRANGE + TestDataGenerator testDataGenerator = new(); + string json = @" + { + ""config"": [ + { + ""set"": { + ""Name"": { + ""always"": 1.0, + ""never"": 0.0 + } + } + } + ] + }"; + List generatedInstances = new(); + int iterations = 25; + + // ACT + for (int i = 1; i <= iterations; i++) + { + ModellingConnection? generatedInstance = testDataGenerator.GenerateInstance(json).SingleInstance; + if (generatedInstance != null) + { + generatedInstances.Add(generatedInstance); + } + } + + // ASSERT + Assert.That(generatedInstances, Has.Count.EqualTo(iterations), "Die Anzahl der generierten Instanzen stimmt nicht mit iterations überein."); + Assert.That(generatedInstances.All(instance => instance?.Name == "always"), Is.True, "Mindestens eine generierte Instanz hat einen unerwarteten Namen."); + } + + [Test] + public void SetUpOneInstance() + { + // ARRANGE + TestDataGenerator testDataGenerator = new(); + string json = @" + { + ""config"": [ + { + ""set"": { + ""name"": ""testinstance"" + } + } + ] + }"; + ModellingConnection testInstance = new(); + + // ACT + testDataGenerator.SetUpInstance(testInstance, json); + + + // ASSERT + Assert.Multiple(() => + { + Assert.That(testInstance, Is.Not.Null, "Generated instance should not be null."); + Assert.That(testInstance, Is.InstanceOf(), "Generated instance should be an instance of ModellingConnection."); + + Assert.That(testInstance!.Id, Is.EqualTo(0), "Id should be 0."); + }); + } + + } + +} diff --git a/roles/test/files/FWO.Test/TestHelper.cs b/roles/tests-unit/files/FWO.Test/TestHelper.cs similarity index 96% rename from roles/test/files/FWO.Test/TestHelper.cs rename to roles/tests-unit/files/FWO.Test/TestHelper.cs index 16b4f945c8..a2e77ca49a 100644 --- a/roles/test/files/FWO.Test/TestHelper.cs +++ b/roles/tests-unit/files/FWO.Test/TestHelper.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Generic; using System.Linq; using System.Reflection; @@ -17,7 +17,7 @@ public static ReturnType InvokeMethod(string name, object ?? throw new Exception($"Method \"{name}\" could not be found in \"{typeof(ClassType)}\"."); object? rawResult = method.Invoke(instance, parameters); - if (rawResult == null) + if (rawResult == null) { if (default(ReturnType) != null) // Not nullable { diff --git a/roles/tests-unit/files/FWO.Test/TestInitializer.cs b/roles/tests-unit/files/FWO.Test/TestInitializer.cs new file mode 100644 index 0000000000..0c49588212 --- /dev/null +++ b/roles/tests-unit/files/FWO.Test/TestInitializer.cs @@ -0,0 +1,56 @@ +using System; +using System.Globalization; +using System.IO; +using NUnit.Framework; +using NUnit.Framework.Legacy; + + +namespace FWO.Test +{ + [SetUpFixture] + class TestInitializer + { + private FakeLocalTimeZone? fakeLocalTimeZone; + + [OneTimeSetUp] + public void OnStart() + { + SetGermanCultureOnAllUnitTest(); + SetGermanTimeZoneOnAllUnitTest(); + SetQueryBasePath(); + } + + [OneTimeTearDown] + public void OnFinish() + { + fakeLocalTimeZone?.Dispose(); + } + + + public static void SetGermanCultureOnAllUnitTest() + { + Thread.CurrentThread.CurrentCulture = new CultureInfo("de-DE"); + Thread.CurrentThread.CurrentUICulture = new CultureInfo("de-DE"); + } + + public void SetGermanTimeZoneOnAllUnitTest() + { + fakeLocalTimeZone = new FakeLocalTimeZone(TimeZoneInfo.FindSystemTimeZoneById("Europe/Berlin")) { }; + } + + private void SetQueryBasePath() + { + if (!string.IsNullOrEmpty(Environment.GetEnvironmentVariable("FWO_BASE_DIR"))) + { + return; + } + + string baseDir = Path.GetFullPath(Path.Combine(AppContext.BaseDirectory, "..", "..", "..", "..", "..", "..", "common", "files")); + string queryDir = Path.Combine(baseDir, "fwo-api-calls"); + if (Directory.Exists(queryDir)) + { + Environment.SetEnvironmentVariable("FWO_BASE_DIR", baseDir); + } + } + } +} diff --git a/roles/tests-unit/files/FWO.Test/Tools/CustomAssert.cs b/roles/tests-unit/files/FWO.Test/Tools/CustomAssert.cs new file mode 100644 index 0000000000..5899605f6d --- /dev/null +++ b/roles/tests-unit/files/FWO.Test/Tools/CustomAssert.cs @@ -0,0 +1,78 @@ +using System; +using System.Text.Json; +using NUnit.Framework; + +namespace FWO.Test.Tools.CustomAssert +{ + public static class AssertWithDump + { + private static readonly JsonSerializerOptions JsonOptions = new() + { + WriteIndented = true, + IncludeFields = true, + MaxDepth = int.MaxValue + }; + + /// + /// Asserts that two strings are equal. If they are not, it attempts to parse them as JSON and pretty-print them for easier comparison. + /// + /// + /// + /// + public static void AreEqual(string expected, string actual, string? message = null) + { + try + { + Assert.That(actual, Is.EqualTo(expected), message); + } + catch (AssertionException ex) + { + TestContext.WriteLine("=== ASSERTION FAILED ===\n"); + if (!string.IsNullOrWhiteSpace(message)) + TestContext.WriteLine(message); + TestContext.WriteLine(ex.Message); + + try + { + var expectedParsed = JsonSerializer.Deserialize(expected); + var actualParsed = JsonSerializer.Deserialize(actual); + + TestContext.WriteLine("\n=== EXPECTED ==="); + TestContext.WriteLine(JsonSerializer.Serialize(expectedParsed, JsonOptions)); + + TestContext.WriteLine("\n=== ACTUAL ==="); + TestContext.WriteLine(JsonSerializer.Serialize(actualParsed, JsonOptions)); + } + catch (JsonException) + { + // If no valid JSON just print raw strings + + TestContext.WriteLine("\n=== EXPECTED (raw) ==="); + TestContext.WriteLine(expected); + + TestContext.WriteLine("\n=== ACTUAL (raw) ==="); + TestContext.WriteLine(actual); + } + + throw; + } + } + } + + public static class AssertThatGeneric + { + public static void PropertyIsTrue(object target, string propertyName) + { + Assert.That(GetFromGeneric(target, propertyName)!, Is.True); + } + + public static void PropertyIsEqual(object target, string propertyName, T expectedValue) + { + Assert.That(GetFromGeneric(target, propertyName), Is.EqualTo(expectedValue)); + } + + + private static object? GetFromGeneric(object o, string name) => o.GetType().GetProperty(name)?.GetValue(o); + } + +} diff --git a/roles/tests-unit/files/FWO.Test/Tools/TestDataGenerator.cs b/roles/tests-unit/files/FWO.Test/Tools/TestDataGenerator.cs new file mode 100644 index 0000000000..5ad84364fe --- /dev/null +++ b/roles/tests-unit/files/FWO.Test/Tools/TestDataGenerator.cs @@ -0,0 +1,52 @@ +using FWO.Data; + +namespace FWO.Test +{ + public static class TestDataGenerator + { + public static List CreateComplianceNetworkZones(int numberOfZones, bool createInternetZone, bool createUndefinedInternalZone) + { + List zones = new(); + + for (int i = 0; i < numberOfZones; i++) + { + zones.Add( + new ComplianceNetworkZone + { + Id = i + 1, + IdString = $"zone_{i + 1}", + Name = $"Zone {i + 1}" + } + ); + } + + if (createInternetZone) + { + zones.Add( + new ComplianceNetworkZone + { + Id = numberOfZones + 1, + IdString = "AUTO_CALCULATED_ZONE_INTERNET", + Name = "Auto-calculated Internet Zone", + IsAutoCalculatedInternetZone = true + } + ); + } + + if (createUndefinedInternalZone) + { + zones.Add( + new ComplianceNetworkZone + { + Id = numberOfZones + 2, + IdString = "AUTO_CALCULATED_ZONE_UNDEFINED_INTERNAL", + Name = "Auto-calculated Undefined-internal Zone", + IsAutoCalculatedUndefinedInternalZone = true, + } + ); + } + + return zones; + } + } +} diff --git a/roles/tests-unit/files/FWO.Test/UiConnectionTableTest.cs b/roles/tests-unit/files/FWO.Test/UiConnectionTableTest.cs new file mode 100644 index 0000000000..f0a6222cdd --- /dev/null +++ b/roles/tests-unit/files/FWO.Test/UiConnectionTableTest.cs @@ -0,0 +1,436 @@ +using FWO.Data; +using FWO.Data.Modelling; +using FWO.Ui.Shared; +using NUnit.Framework; +using System.Collections.Generic; +using System.Reflection; + +namespace FWO.Test +{ + [TestFixture] + public class UiConnectionTableTest + { + private static void SetComponentParameter(ConnectionTable table, string parameterName, TValue value) + { + PropertyInfo? parameter = typeof(ConnectionTable).GetProperty(parameterName, BindingFlags.Public | BindingFlags.Instance); + Assert.That(parameter, Is.Not.Null); + parameter!.SetValue(table, value); + } + + private static void SetPrivateMember(ConnectionTable table, string memberName, TValue value) + { + FieldInfo? field = typeof(ConnectionTable).GetField(memberName, BindingFlags.NonPublic | BindingFlags.Instance); + if (field != null) + { + field.SetValue(table, value); + return; + } + + PropertyInfo? property = typeof(ConnectionTable).GetProperty(memberName, BindingFlags.NonPublic | BindingFlags.Instance); + Assert.That(property, Is.Not.Null); + property!.SetValue(table, value); + } + + private static MethodInfo GetInstanceMethod(string methodName, params Type[] parameterTypes) + { + MethodInfo? method = typeof(ConnectionTable).GetMethod( + methodName, + BindingFlags.NonPublic | BindingFlags.Instance, + null, + parameterTypes, + null); + + Assert.That(method, Is.Not.Null); + return method!; + } + + [Test] + public void ToggleSelection_SingleSelection_ReplacesSelection() + { + ConnectionTable table = new(); + SetComponentParameter(table, nameof(ConnectionTable.SelectInterfaceView), true); + PropertyInfo selectionTypeProperty = typeof(ConnectionTable).GetProperty(nameof(ConnectionTable.SelectionType))!; + object selectionTypeSingle = Enum.Parse(selectionTypeProperty.PropertyType, "Single"); + SetComponentParameter(table, nameof(ConnectionTable.SelectionType), selectionTypeSingle); + SetComponentParameter(table, nameof(ConnectionTable.SelectedConns), new List()); + + ModellingConnection conn1 = new() { Id = 1 }; + ModellingConnection conn2 = new() { Id = 2 }; + table.SelectedConns.Add(conn1); + + MethodInfo toggleSelection = GetInstanceMethod("ToggleSelection", typeof(ModellingConnection)); + toggleSelection.Invoke(table, [conn2]); + + Assert.That(table.SelectedConns, Is.EqualTo([conn2])); + } + + [Test] + public void ToggleSelection_MultipleSelection_RemovesExisting() + { + ConnectionTable table = new(); + SetComponentParameter(table, nameof(ConnectionTable.SelectInterfaceView), true); + PropertyInfo selectionTypeProperty = typeof(ConnectionTable).GetProperty(nameof(ConnectionTable.SelectionType))!; + object selectionTypeMultiple = Enum.Parse(selectionTypeProperty.PropertyType, "Multiple"); + SetComponentParameter(table, nameof(ConnectionTable.SelectionType), selectionTypeMultiple); + SetComponentParameter(table, nameof(ConnectionTable.SelectedConns), new List()); + + ModellingConnection conn1 = new() { Id = 1 }; + ModellingConnection conn2 = new() { Id = 2 }; + table.SelectedConns.Add(conn1); + table.SelectedConns.Add(conn2); + + MethodInfo toggleSelection = GetInstanceMethod("ToggleSelection", typeof(ModellingConnection)); + toggleSelection.Invoke(table, [conn2]); + + Assert.That(table.SelectedConns, Is.EqualTo([conn1])); + } + + [Test] + public void GetTableRowClass_ReturnsGreyForRemoved() + { + ConnectionTable table = new(); + ModellingConnection conn = new() { Removed = true }; + + MethodInfo getRowClass = GetInstanceMethod("getTableRowClass", typeof(ModellingConnection)); + string rowClass = (string)getRowClass.Invoke(table, [conn])!; + + Assert.That(rowClass, Is.EqualTo("td-bg-light-grey")); + } + + [Test] + public void DisplayConditional_WrapsRequestedContent() + { + ConnectionTable table = new(); + ModellingConnection conn = new() { IsRequested = true }; + + MethodInfo displayConditional = GetInstanceMethod("DisplayConditional", typeof(ModellingConnection), typeof(string)); + string result = (string)displayConditional.Invoke(table, [conn, "content"])!; + + Assert.That(result, Is.EqualTo("content")); + } + + [Test] + public void ShowDeleteButton_ReturnsFalse_ForInterfaceWithOpenRequest() + { + ConnectionTable table = new(); + ModellingConnection conn = new() { IsInterface = true, IsRequested = true, TicketId = 42 }; + + MethodInfo showDeleteButton = GetInstanceMethod("ShowDeleteButton", typeof(ModellingConnection)); + bool result = (bool)showDeleteButton.Invoke(table, [conn])!; + + Assert.That(result, Is.False); + } + + [Test] + public void ShowDeleteButton_ReturnsTrue_ForNonRequestedInterface() + { + ConnectionTable table = new(); + ModellingConnection conn = new() { IsInterface = true, IsRequested = false, TicketId = null }; + + MethodInfo showDeleteButton = GetInstanceMethod("ShowDeleteButton", typeof(ModellingConnection)); + bool result = (bool)showDeleteButton.Invoke(table, [conn])!; + + Assert.That(result, Is.True); + } + + [Test] + public void CollectModellingProps_AddsInterfaceRequestedWarning() + { + ConnectionTable table = new(); + SetPrivateMember(table, "userConfig", new SimulatedUserConfig()); + + ModellingConnection conn = new() + { + Props = new Dictionary + { + { nameof(ConState.InterfaceRequested), "true" } + } + }; + + MethodInfo collectModellingProps = GetInstanceMethod("CollectModellingProps", typeof(ModellingConnection)); + List props = (List)collectModellingProps.Invoke(table, [conn])!; + + Assert.That(props, Has.Count.EqualTo(1)); + Assert.That(props[0], Does.Contain("Requested by other owner")); + Assert.That(props[0], Does.Contain("text-warning")); + } + + [Test] + public void CollectModellingProps_AddsInterfaceRejectedWarning() + { + ConnectionTable table = new(); + SetPrivateMember(table, "userConfig", new SimulatedUserConfig()); + + ModellingConnection conn = new() + { + Props = new Dictionary + { + { nameof(ConState.InterfaceRejected), "true" } + } + }; + + MethodInfo collectModellingProps = GetInstanceMethod("CollectModellingProps", typeof(ModellingConnection)); + List props = (List)collectModellingProps.Invoke(table, [conn])!; + + Assert.That(props, Has.Count.EqualTo(1)); + Assert.That(props[0], Does.Contain("Rejected")); + Assert.That(props[0], Does.Contain("color:red")); + } + + [Test] + public void CollectImplementationProps_AddsNotImplementedWarning() + { + ConnectionTable table = new(); + SetPrivateMember(table, "userConfig", new SimulatedUserConfig()); + + ModellingConnection conn = new() + { + Props = new Dictionary + { + { nameof(ConState.NotImplemented), "true" } + } + }; + + MethodInfo collectImplementationProps = GetInstanceMethod("CollectImplementationProps", typeof(ModellingConnection)); + List props = (List)collectImplementationProps.Invoke(table, [conn])!; + + Assert.That(props, Has.Count.EqualTo(1)); + Assert.That(props[0], Does.Contain("Not implemented")); + Assert.That(props[0], Does.Contain("text-warning")); + } + + [Test] + public void DisplayModState_ReturnsOk_WhenNoProps() + { + ConnectionTable table = new(); + SetPrivateMember(table, "userConfig", new SimulatedUserConfig()); + + ModellingConnection conn = new() + { + Props = new Dictionary() + }; + + string result = table.DisplayModState(conn); + + Assert.That(result, Does.Contain("Modelling ok")); + } + + [Test] + public void DisplayModState_ReturnsWarning_WhenPropsPresent() + { + ConnectionTable table = new(); + SetPrivateMember(table, "userConfig", new SimulatedUserConfig()); + + ModellingConnection conn = new() + { + Props = new Dictionary + { + { nameof(ConState.Requested), "true" } + } + }; + + string result = table.DisplayModState(conn); + + Assert.That(result, Does.Contain("Requested")); + Assert.That(result, Does.Contain("text-warning")); + } + + [Test] + public void DisplayImplState_ReturnsDash_WhenModellingPropsPresent() + { + ConnectionTable table = new(); + SetPrivateMember(table, "userConfig", new SimulatedUserConfig()); + + ModellingConnection conn = new() + { + Props = new Dictionary + { + { nameof(ConState.Requested), "true" } + } + }; + + string result = table.DisplayImplState(conn); + + Assert.That(result, Is.EqualTo("-")); + } + + [Test] + public void DisplayImplState_ReturnsOk_WhenVarianceCheckedAndNoIssues() + { + ConnectionTable table = new(); + SetPrivateMember(table, "userConfig", new SimulatedUserConfig()); + + ModellingConnection conn = new() + { + Props = new Dictionary + { + { nameof(ConState.VarianceChecked), "true" } + } + }; + + string result = table.DisplayImplState(conn); + + Assert.That(result, Does.Contain("Implementation ok")); + } + + [Test] + public void DisplayImplState_ReturnsQuestion_WhenVarianceNotChecked() + { + ConnectionTable table = new(); + SetPrivateMember(table, "userConfig", new SimulatedUserConfig()); + + ModellingConnection conn = new() + { + Props = new Dictionary() + }; + + string result = table.DisplayImplState(conn); + + Assert.That(result, Does.Contain("Variance not checked")); + } + + [Test] + public void CollectModellingProps_AddsInterfaceNoPermission_WhenAlone() + { + ConnectionTable table = new(); + SetPrivateMember(table, "userConfig", new SimulatedUserConfig()); + + ModellingConnection conn = new() + { + Props = new Dictionary + { + { nameof(ConState.InterfaceNoPermission), "true" } + } + }; + + MethodInfo collectModellingProps = GetInstanceMethod("CollectModellingProps", typeof(ModellingConnection)); + List props = (List)collectModellingProps.Invoke(table, [conn])!; + + Assert.That(props, Has.Count.EqualTo(1)); + Assert.That(props[0], Does.Contain("Interface no permission")); + Assert.That(props[0], Does.Contain("color:red")); + } + + [Test] + public void CollectModellingProps_AddsEmptySvcGroups_InterfaceVariant() + { + ConnectionTable table = new(); + SetPrivateMember(table, "userConfig", new SimulatedUserConfig()); + + ModellingConnection conn = new() + { + IsInterface = true, + Props = new Dictionary + { + { nameof(ConState.EmptySvcGrps), "true" } + } + }; + + MethodInfo collectModellingProps = GetInstanceMethod("CollectModellingProps", typeof(ModellingConnection)); + List props = (List)collectModellingProps.Invoke(table, [conn])!; + + Assert.That(props, Has.Count.EqualTo(1)); + Assert.That(props[0], Does.Contain("Empty service groups (interface)")); + Assert.That(props[0], Does.Contain("text-warning")); + } + + [Test] + public void CollectModellingProps_AddsDocumentationOnly() + { + ConnectionTable table = new(); + SetPrivateMember(table, "userConfig", new SimulatedUserConfig()); + + ModellingConnection conn = new() + { + Props = new Dictionary + { + { nameof(ConState.DocumentationOnly), "true" } + } + }; + + MethodInfo collectModellingProps = GetInstanceMethod("CollectModellingProps", typeof(ModellingConnection)); + List props = (List)collectModellingProps.Invoke(table, [conn])!; + + Assert.That(props, Has.Count.EqualTo(1)); + Assert.That(props[0], Does.Contain("Documentation only")); + Assert.That(props[0], Does.Contain("text-warning")); + } + + [Test] + public void CollectImplementationProps_AddsVarianceFoundWarning() + { + ConnectionTable table = new(); + SetPrivateMember(table, "userConfig", new SimulatedUserConfig()); + + ModellingConnection conn = new() + { + Props = new Dictionary + { + { nameof(ConState.VarianceFound), "true" } + } + }; + + MethodInfo collectImplementationProps = GetInstanceMethod("CollectImplementationProps", typeof(ModellingConnection)); + List props = (List)collectImplementationProps.Invoke(table, [conn])!; + + Assert.That(props, Has.Count.EqualTo(1)); + Assert.That(props[0], Does.Contain("Variance found")); + Assert.That(props[0], Does.Contain("text-warning")); + } + + [Test] + public void IsVisibleToOwner_ReturnsTrue_ForPublicInterface() + { + ConnectionTable table = new(); + SetComponentParameter(table, nameof(ConnectionTable.Application), new FwoOwner { Id = 1 }); + + ModellingConnection conn = new() + { + InterfacePermission = InterfacePermissions.Public.ToString(), + App = new FwoOwner { Id = 2 } + }; + + MethodInfo isVisibleToOwner = GetInstanceMethod("IsVisibleToOwner", typeof(ModellingConnection)); + bool result = (bool)isVisibleToOwner.Invoke(table, [conn])!; + + Assert.That(result, Is.True); + } + + [Test] + public void IsVisibleToOwner_ReturnsFalse_ForPrivateInterface() + { + ConnectionTable table = new(); + SetComponentParameter(table, nameof(ConnectionTable.Application), new FwoOwner { Id = 1 }); + + ModellingConnection conn = new() + { + InterfacePermission = InterfacePermissions.Private.ToString(), + App = new FwoOwner { Id = 2 } + }; + + MethodInfo isVisibleToOwner = GetInstanceMethod("IsVisibleToOwner", typeof(ModellingConnection)); + bool result = (bool)isVisibleToOwner.Invoke(table, [conn])!; + + Assert.That(result, Is.False); + } + + [Test] + public void IsVisibleToOwner_ReturnsTrue_ForPermittedOwnerWrapper() + { + ConnectionTable table = new(); + SetComponentParameter(table, nameof(ConnectionTable.Application), new FwoOwner { Id = 3 }); + + ModellingConnection conn = new() + { + InterfacePermission = InterfacePermissions.Restricted.ToString(), + App = new FwoOwner { Id = 2 }, + PermittedOwnerWrappers = [new PermittedOwnerWrapper { Owner = new FwoOwner { Id = 3 } }] + }; + + MethodInfo isVisibleToOwner = GetInstanceMethod("IsVisibleToOwner", typeof(ModellingConnection)); + bool result = (bool)isVisibleToOwner.Invoke(table, [conn])!; + + Assert.That(result, Is.True); + } + } +} diff --git a/roles/tests-unit/files/FWO.Test/UiEditNotificationsTest.cs b/roles/tests-unit/files/FWO.Test/UiEditNotificationsTest.cs new file mode 100644 index 0000000000..f950acbdd3 --- /dev/null +++ b/roles/tests-unit/files/FWO.Test/UiEditNotificationsTest.cs @@ -0,0 +1,175 @@ +using FWO.Config.Api; +using FWO.Data; +using FWO.Ui.Shared; +using NUnit.Framework; +using System.Reflection; + +namespace FWO.Test +{ + [TestFixture] + internal class UiEditNotificationsTest + { + private static MethodInfo GetPrivateMethod(string name) + { + return typeof(EditNotifications).GetMethod(name, BindingFlags.NonPublic | BindingFlags.Instance) + ?? throw new MissingMethodException(typeof(EditNotifications).FullName, name); + } + + private static void SetPrivateField(EditNotifications component, string fieldName, T value) + { + FieldInfo? field = typeof(EditNotifications).GetField(fieldName, BindingFlags.NonPublic | BindingFlags.Instance); + if (field == null) + { + throw new MissingFieldException(typeof(EditNotifications).FullName, fieldName); + } + + field.SetValue(component, value); + } + + private static T GetPrivateField(EditNotifications component, string fieldName) + { + FieldInfo? field = typeof(EditNotifications).GetField(fieldName, BindingFlags.NonPublic | BindingFlags.Instance); + if (field == null) + { + throw new MissingFieldException(typeof(EditNotifications).FullName, fieldName); + } + + return (T)field.GetValue(component)!; + } + + private static void SetInjectedUserConfig(EditNotifications component, UserConfig userConfig) + { + PropertyInfo? prop = typeof(EditNotifications).GetProperties(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance) + .FirstOrDefault(p => p.PropertyType == typeof(UserConfig)); + if (prop == null) + { + throw new MissingMemberException(typeof(EditNotifications).FullName, "userConfig"); + } + + prop.SetValue(component, userConfig); + } + + private static void EnsureNotificationTranslations() + { + SimulatedUserConfig.DummyTranslate.TryAdd("edit_notification", "Edit notification"); + SimulatedUserConfig.DummyTranslate.TryAdd("E4010", "Missing email subject"); + SimulatedUserConfig.DummyTranslate.TryAdd("E4011", "Missing recipient"); + SimulatedUserConfig.DummyTranslate.TryAdd("E4012", "Missing offsets"); + SimulatedUserConfig.DummyTranslate.TryAdd("E4013", "Incomplete repetition settings"); + } + + private static void SetClient(EditNotifications component, NotificationClient client) + { + PropertyInfo? prop = typeof(EditNotifications).GetProperty(nameof(EditNotifications.Client), BindingFlags.Public | BindingFlags.Instance); + if (prop == null) + { + throw new MissingMemberException(typeof(EditNotifications).FullName, nameof(EditNotifications.Client)); + } + + prop.SetValue(component, client); + } + + [Test] + public void InitActNotification_ForRuleTimer_SetsExpectedDefaults() + { + EditNotifications component = new(); + SetClient(component, NotificationClient.RuleTimer); + + GetPrivateMethod("InitActNotification").Invoke(component, null); + FwoNotification actNotification = GetPrivateField(component, "actNotification"); + + Assert.That(actNotification.NotificationClient, Is.EqualTo(NotificationClient.RuleTimer)); + Assert.That(actNotification.RecipientTo, Is.EqualTo(EmailRecipientOption.OwnerMainResponsible)); + Assert.That(actNotification.RecipientCc, Is.EqualTo(EmailRecipientOption.None)); + Assert.That(actNotification.Layout, Is.EqualTo(NotificationLayout.HtmlInBody)); + Assert.That(actNotification.Deadline, Is.EqualTo(FwoNotification.OfferedDeadlineOptions(NotificationClient.RuleTimer).Single())); + } + + [Test] + public void SyncAddresses_AppliesQueuedAddsAndDeletes() + { + EditNotifications component = new(); + FwoNotification notification = new(); + + SetPrivateField(component, "actNotification", notification); + SetPrivateField(component, "ToAddresses", new List { "to-remove@example.org", "to-keep@example.org" }); + SetPrivateField(component, "ToAddressesToDelete", new List { "to-remove@example.org" }); + SetPrivateField(component, "ToAddressesToAdd", new List { "to-add@example.org" }); + SetPrivateField(component, "CcAddresses", new List { "cc-remove@example.org" }); + SetPrivateField(component, "CcAddressesToDelete", new List { "cc-remove@example.org" }); + SetPrivateField(component, "CcAddressesToAdd", new List { "cc-add-1@example.org", "cc-add-2@example.org" }); + + GetPrivateMethod("SyncAddresses").Invoke(component, null); + + Assert.That(notification.EmailAddressTo, Is.EqualTo("to-keep@example.org,to-add@example.org")); + Assert.That(notification.EmailAddressCc, Is.EqualTo("cc-add-1@example.org,cc-add-2@example.org")); + Assert.That(GetPrivateField>(component, "ToAddressesToDelete"), Is.Empty); + Assert.That(GetPrivateField>(component, "ToAddressesToAdd"), Is.Empty); + Assert.That(GetPrivateField>(component, "CcAddressesToDelete"), Is.Empty); + Assert.That(GetPrivateField>(component, "CcAddressesToAdd"), Is.Empty); + } + + [Test] + public void CheckConsistency_ReturnsFalse_WhenEmailSubjectIsMissing() + { + EnsureNotificationTranslations(); + EditNotifications component = new(); + SetInjectedUserConfig(component, new SimulatedUserConfig()); + SetPrivateField(component, "actNotification", new FwoNotification + { + Channel = NotificationChannel.Email, + EmailSubject = "", + RecipientTo = EmailRecipientOption.OwnerMainResponsible, + RecipientCc = EmailRecipientOption.None, + Deadline = NotificationDeadline.None + }); + + bool isConsistent = (bool)GetPrivateMethod("CheckConsistency").Invoke(component, null)!; + + Assert.That(isConsistent, Is.False); + } + + [Test] + public void CheckConsistency_ReturnsTrue_ForValidOtherAddressNotification() + { + EnsureNotificationTranslations(); + EditNotifications component = new(); + SetInjectedUserConfig(component, new SimulatedUserConfig()); + SetPrivateField(component, "actNotification", new FwoNotification + { + Channel = NotificationChannel.Email, + EmailSubject = "Subject", + RecipientTo = EmailRecipientOption.OtherAddresses, + RecipientCc = EmailRecipientOption.None, + Deadline = NotificationDeadline.None + }); + SetPrivateField(component, "ToAddresses", new List { "valid@example.org" }); + SetPrivateField(component, "CcAddresses", new List()); + + bool isConsistent = (bool)GetPrivateMethod("CheckConsistency").Invoke(component, null)!; + + Assert.That(isConsistent, Is.True); + } + + [Test] + public void EnsureNotificationIntervals_SetsDefaultIntervalValues_WhenOffsetsAreFilled() + { + EditNotifications component = new(); + FwoNotification notification = new() + { + OffsetBeforeDeadline = 3, + RepeatOffsetAfterDeadline = 2 + }; + + SetPrivateField(component, "actNotification", notification); + + GetPrivateMethod("EnsureNotificationIntervals").Invoke(component, null); + + Assert.Multiple(() => + { + Assert.That(notification.IntervalBeforeDeadline, Is.EqualTo(SchedulerInterval.Weeks)); + Assert.That(notification.RepeatIntervalAfterDeadline, Is.EqualTo(SchedulerInterval.Weeks)); + }); + } + } +} diff --git a/roles/tests-unit/files/FWO.Test/UiEditOwnerTest.cs b/roles/tests-unit/files/FWO.Test/UiEditOwnerTest.cs new file mode 100644 index 0000000000..3b769299fd --- /dev/null +++ b/roles/tests-unit/files/FWO.Test/UiEditOwnerTest.cs @@ -0,0 +1,432 @@ +using Bunit; +using FWO.Api.Client; +using FWO.Api.Client.Queries; +using FWO.Basics; +using FWO.Config.Api; +using FWO.Config.Api.Data; +using FWO.Data; +using FWO.Data.Workflow; +using FWO.Middleware.Client; +using FWO.Services.EventMediator; +using FWO.Services.EventMediator.Interfaces; +using FWO.Ui.Pages.Settings; +using FWO.Ui.Services; +using Microsoft.AspNetCore.Authorization; +using Microsoft.AspNetCore.Components.Authorization; +using Microsoft.Extensions.DependencyInjection; +using NUnit.Framework; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Reflection; +using System.Security.Claims; + +namespace FWO.Test +{ + [TestFixture] + internal class UiEditOwnerTest + { + private static MethodInfo GetPrivateMethod(string name) + { + return typeof(EditOwner).GetMethod(name, BindingFlags.NonPublic | BindingFlags.Instance) + ?? throw new MissingMethodException(typeof(EditOwner).FullName, name); + } + + private static MethodInfo GetPrivateStaticMethod(string name) + { + return typeof(EditOwner).GetMethod(name, BindingFlags.NonPublic | BindingFlags.Static) + ?? throw new MissingMethodException(typeof(EditOwner).FullName, name); + } + + private static void SetPrivateField(EditOwner component, string fieldName, T value) + { + FieldInfo? field = typeof(EditOwner).GetField(fieldName, BindingFlags.NonPublic | BindingFlags.Instance); + if (field == null) + { + throw new MissingFieldException(typeof(EditOwner).FullName, fieldName); + } + field.SetValue(component, value); + } + + private static void SetPrivateProperty(EditOwner component, string propertyName, T value) + { + PropertyInfo? property = typeof(EditOwner).GetProperty(propertyName, BindingFlags.NonPublic | BindingFlags.Instance); + if (property == null) + { + throw new MissingMemberException(typeof(EditOwner).FullName, propertyName); + } + property.SetValue(component, value); + } + + private static IRenderedComponent RenderEditOwner( + Bunit.TestContext context, + FwoOwner owner, + bool readOnly, + List? responsibleTypes = null, + List? existingOwners = null, + List? ownerLifeCycleStates = null) + { + context.JSInterop.Mode = JSRuntimeMode.Loose; + context.Services.AddAuthorizationCore(); + context.Services.AddSingleton(); + context.Services.AddSingleton(new UiEditOwnerAuthStateProvider()); + context.Services.AddSingleton(new EditOwnerTestApiConn()); + context.Services.AddSingleton(new MiddlewareClient("http://localhost/")); + context.Services.AddSingleton(new EditOwnerTestUserConfig()); + context.Services.AddSingleton(); + context.Services.AddSingleton(new EventMediator()); + + IRenderedComponent wrapper = context.Render(parameters => parameters + .AddChildContent(child => child + .Add(p => p.Display, true) + .Add(p => p.Readonly, readOnly) + .Add(p => p.ActOwner, owner) + .Add(p => p.OwnerResponsibleTypes, responsibleTypes ?? []) + .Add(p => p.Tenants, []) + .Add(p => p.OwnerLifeCycleStates, ownerLifeCycleStates ?? []) + .Add(p => p.ExistingOwners, existingOwners ?? []))); + + return wrapper.FindComponent(); + } + + [Test] + public async Task EditOwner_EditableMode_BindsCriticalityInput() + { + await using Bunit.TestContext context = new(); + FwoOwner owner = new() { Id = 0, Name = "Owner A", Criticality = "high" }; + IRenderedComponent editOwner = RenderEditOwner(context, owner, readOnly: false); + + var criticalityInput = editOwner.FindAll("input.form-control.form-control-sm") + .First(i => i.GetAttribute("value") == "high"); + criticalityInput.Change("very-high"); + + Assert.That(owner.Criticality, Is.EqualTo("very-high")); + } + + [Test] + public async Task EditOwner_ReadonlyMode_ShowsCriticalityAsText() + { + await using Bunit.TestContext context = new(); + FwoOwner owner = new() { Id = 0, Name = "Owner A", Criticality = "high" }; + IRenderedComponent editOwner = RenderEditOwner(context, owner, readOnly: true); + + Assert.That(editOwner.Markup, Does.Contain("Criticality")); + Assert.That(editOwner.Markup, Does.Contain("high")); + } + + [Test] + public async Task EditOwner_AddOwnerResponsible_AddsDnAndClearsInput() + { + await using Bunit.TestContext context = new(); + FwoOwner owner = new() { Id = 0, Name = "Owner A" }; + List types = + [ + new OwnerResponsibleType { Id = GlobalConst.kOwnerResponsibleTypeMain, Name = "main", Active = true } + ]; + IRenderedComponent editOwner = RenderEditOwner(context, owner, readOnly: false, responsibleTypes: types); + + SetPrivateField(editOwner.Instance, "NewOwnerResponsibleDnByType", new Dictionary + { + [GlobalConst.kOwnerResponsibleTypeMain] = "cn=main,dc=test" + }); + + GetPrivateMethod("AddOwnerResponsible").Invoke(editOwner.Instance, [GlobalConst.kOwnerResponsibleTypeMain]); + + Assert.That(owner.GetOwnerResponsiblesByType(GlobalConst.kOwnerResponsibleTypeMain), Has.Count.EqualTo(1)); + Assert.That(owner.GetOwnerResponsiblesByType(GlobalConst.kOwnerResponsibleTypeMain)[0], Is.EqualTo("cn=main,dc=test")); + + FieldInfo field = typeof(EditOwner).GetField("NewOwnerResponsibleDnByType", BindingFlags.NonPublic | BindingFlags.Instance)!; + Dictionary state = (Dictionary)field.GetValue(editOwner.Instance)!; + Assert.That(state[GlobalConst.kOwnerResponsibleTypeMain], Is.EqualTo("")); + } + + [Test] + public async Task EditOwner_AddOwnerResponsible_DoesNotDuplicateExistingDn() + { + await using Bunit.TestContext context = new(); + FwoOwner owner = new() { Id = 0, Name = "Owner A" }; + owner.AddOwnerResponsible(GlobalConst.kOwnerResponsibleTypeMain, "cn=main,dc=test"); + List types = + [ + new OwnerResponsibleType { Id = GlobalConst.kOwnerResponsibleTypeMain, Name = "main", Active = true } + ]; + IRenderedComponent editOwner = RenderEditOwner(context, owner, readOnly: false, responsibleTypes: types); + + SetPrivateField(editOwner.Instance, "NewOwnerResponsibleDnByType", new Dictionary + { + [GlobalConst.kOwnerResponsibleTypeMain] = "cn=main,dc=test" + }); + + GetPrivateMethod("AddOwnerResponsible").Invoke(editOwner.Instance, [GlobalConst.kOwnerResponsibleTypeMain]); + + Assert.That(owner.GetOwnerResponsiblesByType(GlobalConst.kOwnerResponsibleTypeMain), Has.Count.EqualTo(1)); + } + + [Test] + public async Task EditOwner_AddOwnerResponsible_EmptyDn_DoesNothing() + { + await using Bunit.TestContext context = new(); + FwoOwner owner = new() { Id = 0, Name = "Owner A" }; + List types = + [ + new OwnerResponsibleType { Id = GlobalConst.kOwnerResponsibleTypeMain, Name = "main", Active = true } + ]; + IRenderedComponent editOwner = RenderEditOwner(context, owner, readOnly: false, responsibleTypes: types); + + SetPrivateField(editOwner.Instance, "NewOwnerResponsibleDnByType", new Dictionary + { + [GlobalConst.kOwnerResponsibleTypeMain] = " " + }); + + GetPrivateMethod("AddOwnerResponsible").Invoke(editOwner.Instance, [GlobalConst.kOwnerResponsibleTypeMain]); + + Assert.That(owner.GetOwnerResponsiblesByType(GlobalConst.kOwnerResponsibleTypeMain), Is.Empty); + } + + [Test] + public async Task EditOwner_CheckValues_FailsWithoutAnyResponsibles() + { + await using Bunit.TestContext context = new(); + FwoOwner owner = new() { Id = 0, Name = "Owner A" }; + IRenderedComponent editOwner = RenderEditOwner(context, owner, readOnly: false); + + bool valid = (bool)GetPrivateMethod("CheckValues").Invoke(editOwner.Instance, null)!; + + Assert.That(valid, Is.False); + } + + [Test] + public async Task EditOwner_CheckValues_FailsWithoutName() + { + await using Bunit.TestContext context = new(); + FwoOwner owner = new() { Id = 0, Name = "" }; + owner.AddOwnerResponsible(GlobalConst.kOwnerResponsibleTypeMain, "cn=main,dc=test"); + IRenderedComponent editOwner = RenderEditOwner(context, owner, readOnly: false); + + bool valid = (bool)GetPrivateMethod("CheckValues").Invoke(editOwner.Instance, null)!; + + Assert.That(valid, Is.False); + } + + [Test] + public async Task EditOwner_CheckValues_FailsForDuplicateOwnerNameInAddMode() + { + await using Bunit.TestContext context = new(); + FwoOwner owner = new() { Id = 0, Name = "Owner A" }; + owner.AddOwnerResponsible(GlobalConst.kOwnerResponsibleTypeMain, "cn=main,dc=test"); + List existing = [new() { Id = 42, Name = "Owner A" }]; + + IRenderedComponent editOwner = RenderEditOwner(context, owner, readOnly: false, existingOwners: existing); + + bool valid = (bool)GetPrivateMethod("CheckValues").Invoke(editOwner.Instance, null)!; + + Assert.That(valid, Is.False); + } + + [Test] + public async Task EditOwner_PrepareOwnerForSave_MapsSelectionsAndNormalizesRecertParams() + { + await using Bunit.TestContext context = new(); + FwoOwner owner = new() { Id = 0, Name = "Owner A" }; + IRenderedComponent editOwner = RenderEditOwner(context, owner, readOnly: false); + + SetPrivateField(editOwner.Instance, "SelectedTenant", new Tenant { Id = 11, Name = "Tenant A" }); + SetPrivateField(editOwner.Instance, "SelectedOwnerLifeCycleState", new OwnerLifeCycleState { Id = 5, Name = "prod" }); + SetPrivateField(editOwner.Instance, "ActRecCheckParams", new RecertCheckParams + { + RecertCheckInterval = SchedulerInterval.Weeks, + RecertCheckOffset = 2, + RecertCheckDayOfMonth = 0 + }); + SetPrivateField(editOwner.Instance, "SelectedDayOfWeek", DayOfWeek.Friday); + + GetPrivateMethod("PrepareOwnerForSave").Invoke(editOwner.Instance, null); + + Assert.That(owner.TenantId, Is.EqualTo(11)); + Assert.That(owner.OwnerLifeCycleStateId, Is.EqualTo(5)); + Assert.That(owner.RecertCheckParamString, Is.Not.Null.And.Not.Empty); + + RecertCheckParams? parsed = System.Text.Json.JsonSerializer.Deserialize(owner.RecertCheckParamString!); + Assert.That(parsed, Is.Not.Null); + Assert.That(parsed!.RecertCheckWeekday, Is.EqualTo((int)DayOfWeek.Friday)); + Assert.That(parsed.RecertCheckDayOfMonth, Is.Null); + } + + [Test] + public async Task EditOwner_HasRelevantOwnerMappingChanges_ReturnsTrue_ForLifecycleActivityChange() + { + await using Bunit.TestContext context = new(); + FwoOwner owner = new() { Id = 5, Name = "Owner A", OwnerLifeCycleStateId = 1 }; + IRenderedComponent editOwner = RenderEditOwner(context, owner, readOnly: false, ownerLifeCycleStates: + [ + new() { Id = 1, Name = "inactive", ActiveState = false }, + new() { Id = 2, Name = "active", ActiveState = true } + ]); + owner.OwnerLifeCycleStateId = 2; + + bool changed = (bool)GetPrivateMethod("HasRelevantOwnerMappingChanges").Invoke(editOwner.Instance, null)!; + + Assert.That(changed, Is.True); + } + + [Test] + public async Task EditOwner_HasRelevantOwnerMappingChanges_ReturnsTrue_ForOwnedIpChange() + { + await using Bunit.TestContext context = new(); + FwoOwner owner = new() { Id = 6, Name = "Owner B", OwnerLifeCycleStateId = 1 }; + IRenderedComponent editOwner = RenderEditOwner(context, owner, readOnly: false); + + List originalIps = [new("10.0.0.1/32", 1)]; + List currentIps = [new("10.0.0.2/32", 1)]; + SetPrivateField(editOwner.Instance, "OriginalOwnedIpKeys", new HashSet(StringComparer.OrdinalIgnoreCase) { "10.0.0.1/32|10.0.0.1/32" }); + SetPrivateField(editOwner.Instance, "ActIpAddresses", currentIps); + + bool changed = (bool)GetPrivateMethod("HasRelevantOwnerMappingChanges").Invoke(editOwner.Instance, null)!; + + Assert.That(changed, Is.True); + } + + [Test] + public async Task EditOwner_GetDecommDateAfterLifecycleChange_SetsDateForDeactivateAndClearsForReactivate() + { + await using Bunit.TestContext context = new(); + FwoOwner owner = new() { Id = 7, Name = "Owner C", OwnerLifeCycleStateId = 1 }; + IRenderedComponent editOwner = RenderEditOwner(context, owner, readOnly: false, ownerLifeCycleStates: + [ + new() { Id = 1, Name = "active", ActiveState = true }, + new() { Id = 2, Name = "inactive", ActiveState = false } + ]); + + owner.OwnerLifeCycleStateId = 2; + DateTime? decommDate = (DateTime?)GetPrivateMethod("GetDecommDateAfterLifecycleChange").Invoke(editOwner.Instance, null); + Assert.That(decommDate, Is.Not.Null); + + SetPrivateProperty(editOwner.Instance, "OriginalOwnerLifeCycleStateId", 2); + owner.DecommDate = DateTime.UtcNow.AddDays(-1); + owner.OwnerLifeCycleStateId = 1; + DateTime? reactivatedDate = (DateTime?)GetPrivateMethod("GetDecommDateAfterLifecycleChange").Invoke(editOwner.Instance, null); + Assert.That(reactivatedDate, Is.Null); + } + + [Test] + public void EditOwner_FormatOwnerResponsibles_UsesUserOrGroupNameAndJoins() + { + string dnUser = "CN=Max Mustermann,OU=Users,DC=example,DC=com"; + string dnGroup = "CN=NetOps,OU=Groups,DC=example,DC=com"; + string dnRaw = "invalid-dn"; + + string formatted = (string)GetPrivateStaticMethod("FormatOwnerResponsibles").Invoke(null, [new List { dnUser, dnGroup, dnRaw }])!; + + Assert.That(formatted, Does.Contain("Max Mustermann")); + Assert.That(formatted, Does.Contain("NetOps")); + Assert.That(formatted, Does.Contain("invalid-dn")); + Assert.That(formatted, Does.Contain(",")); + } + + [Test] + public void EditOwner_FormatOwnerResponsibles_IgnoresEmptyEntries() + { + string formatted = (string)GetPrivateStaticMethod("FormatOwnerResponsibles").Invoke(null, [new List { "", " " }])!; + + Assert.That(formatted, Is.EqualTo("")); + } + + [Test] + public void EditOwner_FormatOwnerResponsibles_ShowsFullNameWhenCnContainsEscapedComma() + { + string dnUser = @"CN=Mustermann\, Max,OU=Users,DC=example,DC=com"; + + string formatted = (string)GetPrivateStaticMethod("FormatOwnerResponsibles").Invoke(null, [new List { dnUser }])!; + + Assert.That(formatted, Is.EqualTo("Mustermann, Max")); + } + + [Test] + public void EditOwner_NormalizeDnForRoleComparison_NormalizesHexEscapedComma() + { + string dnUser = @"CN=Mustermann\2C\20Max,OU=Users,DC=example,DC=com"; + + string normalized = (string)GetPrivateStaticMethod("NormalizeDnForRoleComparison").Invoke(null, [dnUser])!; + + Assert.That(normalized, Is.EqualTo(@"CN=Mustermann\,\20Max,OU=Users,DC=example,DC=com")); + } + + [Test] + public void EditOwner_NormalizeDnForRoleComparison_LeavesBackslashEscapedCommaUntouched() + { + string dnUser = @"CN=Mustermann\, Max,OU=Users,DC=example,DC=com"; + + string normalized = (string)GetPrivateStaticMethod("NormalizeDnForRoleComparison").Invoke(null, [dnUser])!; + + Assert.That(normalized, Is.EqualTo(dnUser)); + } + + [Test] + public void EditOwner_ParseRolesWithImport_ParsesLegacyArrayToSupportingType() + { + string rolesJson = "[\"modeller\", \"recertifier\"]"; + + Dictionary> parsed = + (Dictionary>)GetPrivateStaticMethod("ParseRolesWithImport").Invoke(null, [rolesJson])!; + + Assert.That(parsed.ContainsKey(GlobalConst.kOwnerResponsibleTypeSupporting), Is.True); + Assert.That(parsed[GlobalConst.kOwnerResponsibleTypeSupporting], Is.EquivalentTo(new[] { "modeller", "recertifier" })); + } + + [Test] + public void EditOwner_ParseRolesWithImport_ParsesMappingByResponsibleType() + { + string rolesJson = "{\"1\":[\"roleA\"],\"2\":[\"roleB\",\"roleC\"]}"; + + Dictionary> parsed = + (Dictionary>)GetPrivateStaticMethod("ParseRolesWithImport").Invoke(null, [rolesJson])!; + + Assert.That(parsed.Keys, Is.EquivalentTo(new[] { 1, 2 })); + Assert.That(parsed[1], Is.EquivalentTo(new[] { "roleA" })); + Assert.That(parsed[2], Is.EquivalentTo(new[] { "roleB", "roleC" })); + } + + [Test] + public void EditOwner_ParseRolesWithImport_ReturnsEmptyForWhitespaceInput() + { + Dictionary> parsed = + (Dictionary>)GetPrivateStaticMethod("ParseRolesWithImport").Invoke(null, [" "])!; + + Assert.That(parsed, Is.Empty); + } + } + + internal sealed class UiEditOwnerAuthStateProvider : AuthenticationStateProvider + { + public override Task GetAuthenticationStateAsync() + { + return Task.FromResult(new AuthenticationState(new ClaimsPrincipal())); + } + } + + internal sealed class EditOwnerTestUserConfig : SimulatedUserConfig + { + public override string GetText(string key) + { + return DummyTranslate.TryGetValue(key, out string? value) ? value : key; + } + } + + internal sealed class EditOwnerTestApiConn : SimulatedApiConnection + { + public override Task SendQueryAsync(string query, object? variables = null, string? operationName = null) + { + if (query == OwnerQueries.getNetworkOwnerships) + { + return Task.FromResult((QueryResponseType)(object)new List()); + } + + if (query == OwnerQueries.getRuleOwnerships) + { + return Task.FromResult(Activator.CreateInstance()); + } + + throw new NotImplementedException(); + } + } +} diff --git a/roles/tests-unit/files/FWO.Test/UiEditPolicyTest.cs b/roles/tests-unit/files/FWO.Test/UiEditPolicyTest.cs new file mode 100644 index 0000000000..57a75b1f6c --- /dev/null +++ b/roles/tests-unit/files/FWO.Test/UiEditPolicyTest.cs @@ -0,0 +1,237 @@ +using Bunit; +using FWO.Api.Client; +using FWO.Api.Client.Queries; +using FWO.Config.Api; +using FWO.Data; +using FWO.Ui.Pages.Compliance; +using FWO.Ui.Services; +using Microsoft.AspNetCore.Authorization; +using Microsoft.AspNetCore.Components.Authorization; +using Microsoft.Extensions.DependencyInjection; +using NUnit.Framework; +using System.Reflection; + +namespace FWO.Test +{ + [TestFixture] + internal class UiEditPolicyTest + { + private static MethodInfo GetPrivateMethod(string name) + { + return typeof(EditPolicy).GetMethod(name, BindingFlags.NonPublic | BindingFlags.Instance) ?? + throw new MissingMethodException(typeof(EditPolicy).FullName, name); + } + + private static void SetPrivateField(EditPolicy component, string fieldName, T value) + { + FieldInfo? field = typeof(EditPolicy).GetField(fieldName, BindingFlags.NonPublic | BindingFlags.Instance); + if (field == null) + { + throw new MissingFieldException(typeof(EditPolicy).FullName, fieldName); + } + field.SetValue(component, value); + } + + private static T GetPrivateField(EditPolicy component, string fieldName) + { + FieldInfo? field = typeof(EditPolicy).GetField(fieldName, BindingFlags.NonPublic | BindingFlags.Instance); + if (field == null) + { + throw new MissingFieldException(typeof(EditPolicy).FullName, fieldName); + } + return (T)field.GetValue(component)!; + } + + [Test] + public async Task Save_AddModeWithEmptyName_DoesNotInsertPolicy() + { + await using Bunit.TestContext context = new(); + context.JSInterop.Mode = JSRuntimeMode.Loose; + context.Services.AddAuthorizationCore(); + context.Services.AddSingleton(); + context.Services.AddSingleton(new TestAuthStateProvider()); + EditPolicyTestApiConn apiConn = new(); + context.Services.AddSingleton(apiConn); + context.Services.AddSingleton(); + context.Services.AddSingleton(new SimulatedUserConfig()); + + CompliancePolicy policy = new() { Name = "" }; + List policies = []; + + IRenderedComponent component = context.Render(parameters => parameters + .AddChildContent(child => child + .Add(p => p.Display, true) + .Add(p => p.AddMode, true) + .Add(p => p.Policy, policy) + .Add(p => p.Policies, policies))); + EditPolicy editPolicy = component.FindComponent().Instance; + + Task saveTask = (Task)GetPrivateMethod("Save").Invoke(editPolicy, null)!; + await saveTask; + + Assert.That(apiConn.AddPolicyCalls, Is.EqualTo(0)); + Assert.That(policies, Is.Empty); + } + + [Test] + public async Task Save_AddMode_InsertsPolicyAndCriteria() + { + await using Bunit.TestContext context = new(); + context.JSInterop.Mode = JSRuntimeMode.Loose; + context.Services.AddAuthorizationCore(); + context.Services.AddSingleton(); + context.Services.AddSingleton(new TestAuthStateProvider()); + EditPolicyTestApiConn apiConn = new(); + context.Services.AddSingleton(apiConn); + context.Services.AddSingleton(); + context.Services.AddSingleton(new SimulatedUserConfig()); + + CompliancePolicy policy = new() { Name = "Policy" }; + List policies = []; + ComplianceCriterion criterion = new() { Id = 5, Name = "Crit" }; + + IRenderedComponent component = context.Render(parameters => parameters + .AddChildContent(child => child + .Add(p => p.Display, true) + .Add(p => p.AddMode, true) + .Add(p => p.Policy, policy) + .Add(p => p.Policies, policies))); + EditPolicy editPolicy = component.FindComponent().Instance; + + SetPrivateField(editPolicy, "CriteriaToAdd", new List { criterion }); + + Task saveTask = (Task)GetPrivateMethod("Save").Invoke(editPolicy, null)!; + await saveTask; + + Assert.That(apiConn.AddPolicyCalls, Is.EqualTo(1)); + Assert.That(apiConn.AddCritToPolicyCalls, Is.EqualTo(1)); + Assert.That(policies, Has.Count.EqualTo(1)); + Assert.That(policy.Id, Is.EqualTo(12)); + Assert.That(policy.Criteria, Has.Count.EqualTo(1)); + Assert.That(policy.Criteria[0].Content.Id, Is.EqualTo(criterion.Id)); + } + + [Test] + public async Task Save_EditMode_RemovesCriteria() + { + await using Bunit.TestContext context = new(); + context.JSInterop.Mode = JSRuntimeMode.Loose; + context.Services.AddAuthorizationCore(); + context.Services.AddSingleton(); + context.Services.AddSingleton(new TestAuthStateProvider()); + EditPolicyTestApiConn apiConn = new(); + context.Services.AddSingleton(apiConn); + context.Services.AddSingleton(); + context.Services.AddSingleton(new SimulatedUserConfig()); + + ComplianceCriterion criterion = new() { Id = 7, Name = "Crit" }; + CompliancePolicy policy = new() + { + Id = 42, + Name = "Policy", + Criteria = [new ComplianceCriterionWrapper { Content = criterion }] + }; + + IRenderedComponent component = context.Render(parameters => parameters + .AddChildContent(child => child + .Add(p => p.Display, true) + .Add(p => p.AddMode, false) + .Add(p => p.Policy, policy) + .Add(p => p.Policies, new List { policy }))); + EditPolicy editPolicy = component.FindComponent().Instance; + + SetPrivateField(editPolicy, "CriteriaToDelete", new List { criterion }); + + Task saveTask = (Task)GetPrivateMethod("Save").Invoke(editPolicy, null)!; + await saveTask; + + Assert.That(apiConn.RemoveCritFromPolicyCalls, Is.EqualTo(1)); + Assert.That(policy.Criteria, Is.Empty); + } + + [Test] + public async Task SelectableCriteria_ExcludesExistingAndPending() + { + await using Bunit.TestContext context = new(); + context.JSInterop.Mode = JSRuntimeMode.Loose; + context.Services.AddAuthorizationCore(); + context.Services.AddSingleton(); + context.Services.AddSingleton(new TestAuthStateProvider()); + EditPolicyTestApiConn apiConn = new(); + context.Services.AddSingleton(apiConn); + context.Services.AddSingleton(); + context.Services.AddSingleton(new SimulatedUserConfig()); + + ComplianceCriterion crit1 = new() { Id = 1, Name = "Crit1" }; + ComplianceCriterion crit2 = new() { Id = 2, Name = "Crit2" }; + CompliancePolicy policy = new() + { + Criteria = [new ComplianceCriterionWrapper { Content = crit1 }] + }; + + IRenderedComponent component = context.Render(parameters => parameters + .AddChildContent(child => child + .Add(p => p.Display, true) + .Add(p => p.Policy, policy))); + EditPolicy editPolicy = component.FindComponent().Instance; + + SetPrivateField(editPolicy, "AllCriteria", new List { crit1, crit2 }); + SetPrivateField(editPolicy, "CriteriaToAdd", new List { crit2 }); + + List selectable = (List)GetPrivateMethod("SelectableCriteria").Invoke(editPolicy, null)!; + + Assert.That(selectable, Is.Empty); + } + } + + internal sealed class EditPolicyTestApiConn : SimulatedApiConnection + { + public int AddPolicyCalls { get; private set; } + public int AddCritToPolicyCalls { get; private set; } + public int RemoveCritFromPolicyCalls { get; private set; } + + public override Task SendQueryAsync(string query, object? variables = null, string? operationName = null) + { + Type responseType = typeof(QueryResponseType); + if (responseType == typeof(List) && query == ComplianceQueries.getCriteria) + { + return Task.FromResult((QueryResponseType)(object)new List()); + } + + if (responseType == typeof(ReturnIdWrapper)) + { + if (query == ComplianceQueries.addPolicy) + { + AddPolicyCalls++; + ReturnIdWrapper wrapper = new() { ReturnIds = [new ReturnId { InsertedId = 12 }] }; + return Task.FromResult((QueryResponseType)(object)wrapper); + } + return Task.FromResult((QueryResponseType)(object)new ReturnIdWrapper { ReturnIds = [new ReturnId()] }); + } + + if (responseType == typeof(ReturnId)) + { + if (query == ComplianceQueries.addCritToPolicy) + { + AddCritToPolicyCalls++; + } + else if (query == ComplianceQueries.removeCritFromPolicy) + { + RemoveCritFromPolicyCalls++; + } + return Task.FromResult((QueryResponseType)(object)new ReturnId()); + } + + throw new NotImplementedException(); + } + } + + internal sealed class TestAuthStateProvider : AuthenticationStateProvider + { + public override Task GetAuthenticationStateAsync() + { + return Task.FromResult(new AuthenticationState(new System.Security.Claims.ClaimsPrincipal())); + } + } + +} diff --git a/roles/tests-unit/files/FWO.Test/UiMonitorModellingTest.cs b/roles/tests-unit/files/FWO.Test/UiMonitorModellingTest.cs new file mode 100644 index 0000000000..ab945d2bce --- /dev/null +++ b/roles/tests-unit/files/FWO.Test/UiMonitorModellingTest.cs @@ -0,0 +1,188 @@ +using Bunit; +using FWO.Api.Client; +using FWO.Api.Client.Queries; +using FWO.Basics; +using FWO.Config.Api; +using FWO.Data; +using FWO.Data.Modelling; +using FWO.Middleware.Client; +using FWO.Ui.Pages.Monitoring; +using FWO.Ui.Services; +using Microsoft.AspNetCore.Authorization; +using Microsoft.AspNetCore.Components.Authorization; +using Microsoft.Extensions.DependencyInjection; +using NUnit.Framework; +using System; +using System.Collections.Generic; +using System.Reflection; +using System.Threading.Tasks; + +namespace FWO.Test +{ + [TestFixture] + [FixtureLifeCycle(LifeCycle.InstancePerTestCase)] + public class UiMonitorModellingTest + { + private static MethodInfo GetPrivateMethod(string name, params Type[] parameterTypes) + { + return typeof(MonitorModelling).GetMethod(name, BindingFlags.NonPublic | BindingFlags.Instance, null, parameterTypes, null) + ?? throw new MissingMethodException(typeof(MonitorModelling).FullName, name); + } + + private static MonitorModelling RenderComponent(Bunit.TestContext context, ApiConnection apiConnection) + { + context.JSInterop.Mode = JSRuntimeMode.Loose; + context.Services.AddAuthorizationCore(); + context.Services.AddLocalization(); + context.Services.AddSingleton(); + context.Services.AddSingleton(new MonitoringTestAuthStateProvider(Roles.Admin)); + context.Services.AddSingleton(apiConnection); + context.Services.AddSingleton(new MiddlewareClient("http://localhost/")); + context.Services.AddSingleton(new SimulatedUserConfig()); + context.Services.AddScoped(); + + IRenderedComponent component = context.Render(parameters => + parameters.AddChildContent()); + return component.FindComponent().Instance; + } + + [Test] + public async Task RemoveOrphanedAppRole_ReturnsCountAndCallsApi() + { + MonitorModellingTestApiConn apiConn = new(); + await using Bunit.TestContext context = new(); + MonitorModelling component = RenderComponent(context, apiConn); + + ModellingConnection connection = new() + { + Id = 21, + SourceAppRoles = + [ + new ModellingAppRoleWrapper { Content = new ModellingAppRole { Id = 501 } } + ] + }; + + Task removeTask = (Task)GetPrivateMethod("RemoveOrphanedAppRole", typeof(ModellingConnection), typeof(bool)) + .Invoke(component, new object[] { connection, false })!; + int removed = await removeTask; + + Assert.That(removed, Is.EqualTo(1)); + Assert.That(apiConn.NwGroupRemovals, Has.Count.EqualTo(1)); + Assert.That(apiConn.NwGroupRemovals[0].NwGroupId, Is.EqualTo(501)); + Assert.That(apiConn.NwGroupRemovals[0].ConnectionId, Is.EqualTo(21)); + Assert.That(apiConn.NwGroupRemovals[0].Field, Is.EqualTo((int)ModellingTypes.ConnectionField.Source)); + } + + [Test] + public async Task RemoveOrphanedServiceGroup_ReturnsCountAndCallsApi() + { + MonitorModellingTestApiConn apiConn = new(); + await using Bunit.TestContext context = new(); + MonitorModelling component = RenderComponent(context, apiConn); + + ModellingConnection connection = new() + { + Id = 33, + ServiceGroups = + [ + new ModellingServiceGroupWrapper { Content = new ModellingServiceGroup { Id = 7 } }, + new ModellingServiceGroupWrapper { Content = new ModellingServiceGroup { Id = 8 } } + ] + }; + + Task removeTask = (Task)GetPrivateMethod("RemoveOrphanedServiceGroup", typeof(ModellingConnection), typeof(bool)) + .Invoke(component, new object[] { connection, false })!; + int removed = await removeTask; + + Assert.That(removed, Is.EqualTo(2)); + Assert.That(apiConn.ServiceGroupRemovals, Has.Count.EqualTo(2)); + Assert.That(apiConn.ServiceGroupRemovals[0].ServiceGroupId, Is.EqualTo(7)); + Assert.That(apiConn.ServiceGroupRemovals[1].ServiceGroupId, Is.EqualTo(8)); + } + + [Test] + public async Task ExtractOrphanedServices_FiltersByInterfaceAndKeepsServices() + { + MonitorModellingTestApiConn apiConn = new(); + await using Bunit.TestContext context = new(); + MonitorModelling component = RenderComponent(context, apiConn); + + ModellingConnection ignored = new() + { + Id = 1, + UsedInterfaceId = null, + Services = [new ModellingServiceWrapper { Content = new ModellingService { Id = 100 } }] + }; + ModellingConnection included = new() + { + Id = 2, + UsedInterfaceId = 5, + Services = [new ModellingServiceWrapper { Content = new ModellingService { Id = 200 } }], + ServiceGroups = [new ModellingServiceGroupWrapper { Content = new ModellingServiceGroup { Id = 300 } }] + }; + + Task> extractTask = (Task>)GetPrivateMethod("ExtractOrphanedServices", typeof(List)) + .Invoke(component, new object[] { new List { ignored, included } })!; + List result = await extractTask; + + Assert.That(result, Has.Count.EqualTo(1)); + Assert.That(result[0].Id, Is.EqualTo(2)); + Assert.That(result[0].Services, Has.Count.EqualTo(1)); + Assert.That(result[0].ServiceGroups, Is.Empty); + } + } + + internal sealed class MonitorModellingTestApiConn : SimulatedApiConnection + { + public List NwGroupRemovals { get; } = []; + public List ServiceGroupRemovals { get; } = []; + + public override Task SendQueryAsync(string query, object? variables = null, string? operationName = null) + { + if (typeof(QueryResponseType) == typeof(List)) + { + if (query == OwnerQueries.getOwners) + { + return Task.FromResult((QueryResponseType)(object)new List()); + } + } + + if (typeof(QueryResponseType) == typeof(ReturnId)) + { + if (query == ModellingQueries.removeNwGroupFromConnection) + { + long nwGroupId = GetLong(variables, "nwGroupId"); + long connectionId = GetLong(variables, "connectionId"); + int field = GetInt(variables, "connectionField"); + NwGroupRemovals.Add(new NwGroupRemoval(nwGroupId, connectionId, field)); + return Task.FromResult((QueryResponseType)(object)new ReturnId()); + } + + if (query == ModellingQueries.removeServiceGroupFromConnection) + { + long serviceGroupId = GetLong(variables, "serviceGroupId"); + long connectionId = GetLong(variables, "connectionId"); + ServiceGroupRemovals.Add(new ServiceGroupRemoval(serviceGroupId, connectionId)); + return Task.FromResult((QueryResponseType)(object)new ReturnId()); + } + } + + throw new NotImplementedException(); + } + + private static long GetLong(object? variables, string propertyName) + { + object? value = variables?.GetType().GetProperty(propertyName)?.GetValue(variables); + return value != null ? Convert.ToInt64(value) : 0; + } + + private static int GetInt(object? variables, string propertyName) + { + object? value = variables?.GetType().GetProperty(propertyName)?.GetValue(variables); + return value != null ? Convert.ToInt32(value) : 0; + } + } + + internal record NwGroupRemoval(long NwGroupId, long ConnectionId, int Field); + internal record ServiceGroupRemoval(long ServiceGroupId, long ConnectionId); +} diff --git a/roles/tests-unit/files/FWO.Test/UiMonitorRequestedInterfacesTest.cs b/roles/tests-unit/files/FWO.Test/UiMonitorRequestedInterfacesTest.cs new file mode 100644 index 0000000000..cb62059b0f --- /dev/null +++ b/roles/tests-unit/files/FWO.Test/UiMonitorRequestedInterfacesTest.cs @@ -0,0 +1,456 @@ +using Bunit; +using FWO.Api.Client; +using FWO.Api.Client.Queries; +using FWO.Basics; +using FWO.Config.Api; +using FWO.Config.Api.Data; +using FWO.Data; +using FWO.Data.Modelling; +using FWO.Data.Workflow; +using FWO.Middleware.Client; +using FWO.Services.Workflow; +using FWO.Ui.Pages.Monitoring; +using FWO.Ui.Services; +using Microsoft.AspNetCore.Authorization; +using Microsoft.AspNetCore.Components.Authorization; +using Microsoft.Extensions.DependencyInjection; +using NUnit.Framework; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Reflection; +using System.Text.Json; +using System.Threading.Tasks; + +namespace FWO.Test +{ + [TestFixture] + [FixtureLifeCycle(LifeCycle.InstancePerTestCase)] + public class UiMonitorRequestedInterfacesTest + { + private static MethodInfo GetPrivateMethod(string name, params Type[] parameterTypes) + { + return typeof(MonitorRequestedInterfaces).GetMethod(name, BindingFlags.NonPublic | BindingFlags.Instance, null, parameterTypes, null) + ?? throw new MissingMethodException(typeof(MonitorRequestedInterfaces).FullName, name); + } + + private static PropertyInfo GetPrivateProperty(string name) + { + return typeof(MonitorRequestedInterfaces).GetProperty(name, BindingFlags.NonPublic | BindingFlags.Instance) + ?? throw new MissingMemberException(typeof(MonitorRequestedInterfaces).FullName, name); + } + + private static void SetPrivateField(MonitorRequestedInterfaces component, string fieldName, T value) + { + FieldInfo? field = typeof(MonitorRequestedInterfaces).GetField(fieldName, BindingFlags.NonPublic | BindingFlags.Instance); + if (field != null) + { + field.SetValue(component, value); + return; + } + + PropertyInfo? property = typeof(MonitorRequestedInterfaces).GetProperty(fieldName, BindingFlags.NonPublic | BindingFlags.Instance); + if (property == null) + { + throw new MissingFieldException(typeof(MonitorRequestedInterfaces).FullName, fieldName); + } + property.SetValue(component, value); + } + + private static T GetPrivateField(MonitorRequestedInterfaces component, string fieldName) + { + FieldInfo? field = typeof(MonitorRequestedInterfaces).GetField(fieldName, BindingFlags.NonPublic | BindingFlags.Instance); + if (field != null) + { + return (T)(field.GetValue(component) ?? throw new InvalidOperationException($"Field {fieldName} is null.")); + } + + PropertyInfo? property = typeof(MonitorRequestedInterfaces).GetProperty(fieldName, BindingFlags.NonPublic | BindingFlags.Instance); + if (property == null) + { + throw new MissingFieldException(typeof(MonitorRequestedInterfaces).FullName, fieldName); + } + return (T)(property.GetValue(component) ?? throw new InvalidOperationException($"Property {fieldName} is null.")); + } + + private static T GetPrivatePropertyValue(MonitorRequestedInterfaces component, string propertyName) + { + PropertyInfo property = GetPrivateProperty(propertyName); + return (T)(property.GetValue(component) ?? throw new InvalidOperationException($"Property {propertyName} is null.")); + } + + private static MonitorRequestedInterfaces RenderComponent(Bunit.TestContext context, ApiConnection apiConnection) + { + context.JSInterop.Mode = JSRuntimeMode.Loose; + context.Services.AddAuthorizationCore(); + context.Services.AddLocalization(); + context.Services.AddSingleton(); + context.Services.AddSingleton(new MonitoringTestAuthStateProvider(Roles.Admin)); + context.Services.AddSingleton(apiConnection); + context.Services.AddSingleton(new MiddlewareClient("http://localhost/")); + context.Services.AddSingleton(new SimulatedUserConfig()); + context.Services.AddScoped(); + + IRenderedComponent component = context.Render(parameters => + parameters.AddChildContent()); + return component.FindComponent().Instance; + } + + [Test] + public async Task ShowRejectRemovedTicketsConfirm_SetsPopupStateAndDefaultReason() + { + MonitorRequestedInterfacesTestApiConn apiConn = new(); + await using Bunit.TestContext context = new(); + MonitorRequestedInterfaces component = RenderComponent(context, apiConn); + + PrepareRows(component, new List + { + new() { Id = 1, Name = "if-1", Removed = true, TicketId = 501 }, + new() { Id = 2, Name = "if-2", Removed = true, TicketId = 777 }, + new() { Id = 3, Name = "if-3", Removed = false, TicketId = 888 } + }, + new Dictionary + { + { 1, 10 }, + { 2, 20 }, + { 3, 10 } + }, + lowestEndState: 100); + + GetPrivateMethod("ShowRejectRemovedTicketsConfirm").Invoke(component, null); + + bool confirmOpen = GetPrivateField(component, "ConfirmRejectRemovedTickets"); + string reason = GetPrivateField(component, "RejectRemovedTicketsReason"); + string message = GetPrivatePropertyValue(component, "RejectRemovedTicketsMessage"); + + Assert.That(confirmOpen, Is.True); + Assert.That(reason, Is.EqualTo("Rejected by Admin")); + Assert.That(message, Does.Contain("2")); + } + + [Test] + public async Task OpenRemovedTicketIds_ContainsOnlyOpenRemovedDistinctTickets() + { + MonitorRequestedInterfacesTestApiConn apiConn = new(); + await using Bunit.TestContext context = new(); + MonitorRequestedInterfaces component = RenderComponent(context, apiConn); + + PrepareRows(component, new List + { + new() { Id = 1, Name = "if-a", Removed = true, TicketId = 1001 }, + new() { Id = 2, Name = "if-b", Removed = true, TicketId = 1001 }, + new() { Id = 3, Name = "if-c", Removed = true, TicketId = 2002 }, + new() { Id = 4, Name = "if-d", Removed = false, TicketId = 3003 } + }, + new Dictionary + { + { 1, 10 }, + { 2, 10 }, + { 3, 150 }, + { 4, 10 } + }, + lowestEndState: 100); + + List ticketIds = GetPrivatePropertyValue>(component, "OpenRemovedTicketIds"); + + Assert.That(ticketIds, Is.EqualTo(new List { 1001 })); + } + + [Test] + public async Task OpenRemovedTicketIds_RespectsSelectedTicketStateFilter() + { + MonitorRequestedInterfacesTestApiConn apiConn = new(); + await using Bunit.TestContext context = new(); + MonitorRequestedInterfaces component = RenderComponent(context, apiConn); + + PrepareRows(component, new List + { + new() { Id = 1, Name = "if-a", Removed = true, TicketId = 1001 }, + new() { Id = 2, Name = "if-b", Removed = true, TicketId = 2002 } + }, + new Dictionary + { + { 1, 10 }, + { 2, 20 } + }, + lowestEndState: 100); + + SetPrivateField(component, "SelectedTicketStateFilter", "10"); + List filteredTicketIds = GetPrivatePropertyValue>(component, "OpenRemovedTicketIds"); + + Assert.That(filteredTicketIds, Is.EqualTo(new List { 1001 })); + } + + [Test] + public async Task OpenRemovedTicketIds_ExcludesInterfacesUsedByConnections() + { + MonitorRequestedInterfacesTestApiConn apiConn = new(); + await using Bunit.TestContext context = new(); + MonitorRequestedInterfaces component = RenderComponent(context, apiConn); + + List connections = + [ + new() { Id = 1, Name = "if-free", Removed = true, TicketId = 1001 }, + new() { Id = 2, Name = "if-used", Removed = true, TicketId = 2002 } + ]; + SetPrivateField(component, "RequestedInterfaces", connections); + SetPrivateField(component, "TicketStateIdByConnectionId", new Dictionary + { + { 1, 10 }, + { 2, 10 } + }); + SetPrivateField(component, "UsedByConnectionIdsByInterfaceId", new Dictionary + { + { 1, "-" }, + { 2, "77, 88" } + }); + SetPrivateField(component, "NewInterfaceStateMatrix", new StateMatrix { LowestEndState = 100 }); + GetPrivateMethod("BuildRequestedInterfaceRows").Invoke(component, null); + + List ticketIds = GetPrivatePropertyValue>(component, "OpenRemovedTicketIds"); + + Assert.That(ticketIds, Is.EqualTo(new List { 1001 })); + } + + [Test] + public async Task CloseRejectRemovedTicketsConfirm_ResetsPopupStateAndReason() + { + MonitorRequestedInterfacesTestApiConn apiConn = new(); + await using Bunit.TestContext context = new(); + MonitorRequestedInterfaces component = RenderComponent(context, apiConn); + + SetPrivateField(component, "ConfirmRejectRemovedTickets", true); + SetPrivateField(component, "RejectRemovedTicketsReason", "custom reason"); + + GetPrivateMethod("CloseRejectRemovedTicketsConfirm").Invoke(component, null); + + Assert.That(GetPrivateField(component, "ConfirmRejectRemovedTickets"), Is.False); + Assert.That(GetPrivateField(component, "RejectRemovedTicketsReason"), Is.EqualTo(string.Empty)); + } + + [Test] + public async Task ResolveRequestingAppsFromTickets_IgnoresMissingTickets() + { + MonitorRequestedInterfacesTestApiConn apiConn = new() + { + SafeTicketById = + { + [501] = new ApiResponse("missing ticket") + } + }; + await using Bunit.TestContext context = new(); + MonitorRequestedInterfaces component = RenderComponent(context, apiConn); + + SetPrivateField(component, "RequestedInterfaces", new List + { + new() { Id = 1, Name = "if-1", TicketId = 501 } + }); + SetPrivateField(component, "OwnersById", new Dictionary + { + { 7, new FwoOwner { Id = 7, Name = "Owner 7" } } + }); + + Task resolveTask = (Task)GetPrivateMethod("ResolveRequestingAppsFromTickets").Invoke(component, null)!; + await resolveTask; + + Assert.That(GetPrivateField>(component, "RequestingAppByConnectionId"), Is.Empty); + Assert.That(GetPrivateField>(component, "TicketStateIdByConnectionId"), Is.Empty); + Assert.That(GetPrivateField>(component, "TicketCreationDateByConnectionId"), Is.Empty); + } + + [Test] + public async Task OrphanedRequestedInterfaceTicketsPopup_LoadsOnlyTicketsWithMissingInterfaces() + { + MonitorRequestedInterfacesTestApiConn apiConn = new() + { + TicketsByParametersResult = + [ + new WfTicket + { + Id = 501, + StateId = 10, + CreationDate = new DateTime(2026, 3, 28, 10, 15, 0), + Tasks = + { + CreateTask(1, WfTaskType.new_interface, "if-removed-a"), + CreateTask(2, WfTaskType.new_interface, "if-removed-b") + } + }, + new WfTicket + { + Id = 777, + StateId = 10, + Tasks = + { + CreateTask(3, WfTaskType.new_interface, "if-still-exists") + } + }, + new WfTicket + { + Id = 888, + StateId = 10, + Tasks = + { + CreateTask(4, WfTaskType.new_interface, "if-still-exists-2") + } + } + ], + ConnectionById = + { + [1] = [], + [2] = [], + [3] = [new ModellingConnection { Id = 3, Name = "existing-if" }], + [4] = [new ModellingConnection { Id = 4, Name = "existing-if-2" }] + }, + States = + [ + new WfState { Id = 10, Name = "In Progress" }, + ] + }; + await using Bunit.TestContext context = new(); + context.JSInterop.Mode = JSRuntimeMode.Loose; + context.Services.AddLocalization(); + context.Services.AddSingleton(apiConn); + context.Services.AddSingleton(new MiddlewareClient("http://localhost/")); + context.Services.AddSingleton(new SimulatedUserConfig()); + + IRenderedComponent component = + context.Render(parameters => parameters + .Add(p => p.Display, true)); + component.WaitForAssertion(() => + { + string markup = component.Markup; + List cellTexts = component.FindAll("tbody td") + .Select(cell => cell.TextContent.Trim()) + .Where(text => !string.IsNullOrWhiteSpace(text)) + .ToList(); + Assert.That(markup, Does.Contain("501")); + Assert.That(markup, Does.Contain("In Progress")); + Assert.That(markup, Does.Contain("if-removed-a")); + Assert.That(markup, Does.Contain("if-removed-b")); + Assert.That(markup, Does.Contain("Close Tickets as rejected")); + Assert.That(cellTexts, Does.Not.Contain("777")); + Assert.That(cellTexts, Does.Not.Contain("888")); + }); + } + + private static WfReqTask CreateTask(int connId, WfTaskType taskType, string title = "") + { + WfReqTask task = new() { TaskType = taskType.ToString(), Title = title }; + task.SetAddInfo(AdditionalInfoKeys.ConnId, connId.ToString()); + return task; + } + + private static void PrepareRows( + MonitorRequestedInterfaces component, + List connections, + Dictionary ticketStateByConnectionId, + int lowestEndState) + { + SetPrivateField(component, "RequestedInterfaces", connections); + SetPrivateField(component, "TicketStateIdByConnectionId", ticketStateByConnectionId); + SetPrivateField(component, "UsedByConnectionIdsByInterfaceId", connections.ToDictionary(c => c.Id, _ => "-")); + SetPrivateField(component, "NewInterfaceStateMatrix", new StateMatrix { LowestEndState = lowestEndState }); + GetPrivateMethod("BuildRequestedInterfaceRows").Invoke(component, null); + } + } + + internal sealed class MonitorRequestedInterfacesTestApiConn : SimulatedApiConnection + { + private static readonly string stateMatrixJson = BuildStateMatrixJson(); + public Dictionary> SafeTicketById { get; } = []; + public Dictionary> ConnectionById { get; } = []; + public List RequestedInterfacesResult { get; set; } = []; + public List TicketsByParametersResult { get; set; } = []; + public List States { get; set; } = []; + + public override Task SendQueryAsync(string query, object? variables = null, string? operationName = null) + { + if (typeof(QueryResponseType) == typeof(List) && query == ConfigQueries.getConfigItemByKey) + { + List config = + [ + new() { ConfData = stateMatrixJson } + ]; + return Task.FromResult((QueryResponseType)(object)config); + } + + if (typeof(QueryResponseType) == typeof(List) && query == ModellingQueries.getRequestedInterfaces) + { + return Task.FromResult((QueryResponseType)(object)RequestedInterfacesResult); + } + + if (typeof(QueryResponseType) == typeof(List) && query == ModellingQueries.getConnectionById) + { + int connId = Convert.ToInt32(variables?.GetType().GetProperty("id")?.GetValue(variables) ?? 0); + if (ConnectionById.TryGetValue(connId, out List? connections)) + { + return Task.FromResult((QueryResponseType)(object)connections); + } + + return Task.FromResult((QueryResponseType)(object)new List()); + } + + if (typeof(QueryResponseType) == typeof(List) && query == OwnerQueries.getOwners) + { + return Task.FromResult((QueryResponseType)(object)new List()); + } + + if (typeof(QueryResponseType) == typeof(List) && query == RequestQueries.getStates) + { + return Task.FromResult((QueryResponseType)(object)States); + } + + if (typeof(QueryResponseType) == typeof(List) && query == RequestQueries.getTicketsByParameters) + { + return Task.FromResult((QueryResponseType)(object)TicketsByParametersResult); + } + + if (typeof(QueryResponseType) == typeof(List) && query == ModellingQueries.getInterfaceUsers) + { + return Task.FromResult((QueryResponseType)(object)new List()); + } + + throw new NotImplementedException(); + } + + public override Task> SendQuerySafeAsync(string query, object? variables = null, string? operationName = null) + { + if (typeof(QueryResponseType) == typeof(WfTicket) && query == RequestQueries.getTicketById) + { + long ticketId = Convert.ToInt64(variables?.GetType().GetProperty("id")?.GetValue(variables) ?? 0L); + if (SafeTicketById.TryGetValue(ticketId, out ApiResponse? response)) + { + return Task.FromResult((ApiResponse)(object)response); + } + + return Task.FromResult((ApiResponse)(object)new ApiResponse("ticket not configured")); + } + + return base.SendQuerySafeAsync(query, variables, operationName); + } + + private static string BuildStateMatrixJson() + { + Dictionary matrixByPhase = []; + foreach (WorkflowPhases phase in Enum.GetValues(typeof(WorkflowPhases))) + { + matrixByPhase[phase] = new StateMatrix + { + Matrix = new Dictionary> { { 0, new List { 0 } } }, + DerivedStates = new Dictionary(), + LowestInputState = 1, + LowestStartedState = 2, + LowestEndState = 100, + Active = true + }; + } + + GlobalStateMatrix matrix = new() + { + GlobalMatrix = matrixByPhase + }; + return JsonSerializer.Serialize(matrix); + } + } +} diff --git a/roles/tests-unit/files/FWO.Test/UiMonitoringMainTest.cs b/roles/tests-unit/files/FWO.Test/UiMonitoringMainTest.cs new file mode 100644 index 0000000000..06fd20c35d --- /dev/null +++ b/roles/tests-unit/files/FWO.Test/UiMonitoringMainTest.cs @@ -0,0 +1,152 @@ +using Bunit; +using FWO.Api.Client; +using FWO.Api.Client.Queries; +using FWO.Config.Api; +using FWO.Data; +using FWO.Middleware.Client; +using FWO.Ui.Pages.Monitoring; +using Microsoft.AspNetCore.Authorization; +using Microsoft.AspNetCore.Components.Authorization; +using Microsoft.Extensions.DependencyInjection; +using NUnit.Framework; +using System; +using System.Reflection; +using System.Security.Claims; + +namespace FWO.Test +{ + [TestFixture] + [FixtureLifeCycle(LifeCycle.InstancePerTestCase)] + public class UiMonitoringMainTest + { + private static MethodInfo GetPrivateMethod(string name) + { + return typeof(MonitoringMain).GetMethod(name, BindingFlags.NonPublic | BindingFlags.Instance) + ?? throw new MissingMethodException(typeof(MonitoringMain).FullName, name); + } + + private static void SetPrivateField(MonitoringMain component, string fieldName, T value) + { + FieldInfo? field = typeof(MonitoringMain).GetField(fieldName, BindingFlags.NonPublic | BindingFlags.Instance); + if (field == null) + { + throw new MissingFieldException(typeof(MonitoringMain).FullName, fieldName); + } + field.SetValue(component, value); + } + + [Test] + public async Task Acknowledge_RemovesAlertAndCallsApi() + { + await using Bunit.TestContext context = new(); + context.JSInterop.Mode = JSRuntimeMode.Loose; + context.Services.AddAuthorizationCore(); + context.Services.AddSingleton(); + context.Services.AddSingleton(new MonitoringTestAuthStateProvider()); + MonitoringMainTestApiConn apiConn = new(); + context.Services.AddSingleton(apiConn); + context.Services.AddSingleton(new MiddlewareClient("http://localhost/")); + context.Services.AddSingleton(new SimulatedUserConfig()); + + IRenderedComponent component = context.Render(parameters => + parameters.AddChildContent()); + MonitoringMain monitoring = component.FindComponent().Instance; + + Alert alert = new() { Id = 123, Source = "test" }; + List alerts = new() { alert }; + SetPrivateField(monitoring, "alertEntrys", alerts); + + Task acknowledgeTask = (Task)GetPrivateMethod("Acknowledge").Invoke(monitoring, new object[] { alert })!; + await acknowledgeTask; + + Assert.That(alerts, Is.Empty); + Assert.That(apiConn.AcknowledgedAlertIds, Is.EqualTo(new[] { 123L })); + } + + [Test] + public async Task AcknowledgeAllOpen_ClearsAlertsWhenSuccessful() + { + await using Bunit.TestContext context = new(); + context.JSInterop.Mode = JSRuntimeMode.Loose; + context.Services.AddAuthorizationCore(); + context.Services.AddSingleton(); + context.Services.AddSingleton(new MonitoringTestAuthStateProvider()); + MonitoringMainTestApiConn apiConn = new() { AckAllAffectedRows = 2 }; + context.Services.AddSingleton(apiConn); + context.Services.AddSingleton(new MiddlewareClient("http://localhost/")); + context.Services.AddSingleton(new SimulatedUserConfig()); + + IRenderedComponent component = context.Render(parameters => + parameters.AddChildContent()); + MonitoringMain monitoring = component.FindComponent().Instance; + + List alerts = new() + { + new Alert { Id = 1, Source = "test" }, + new Alert { Id = 2, Source = "test" } + }; + SetPrivateField(monitoring, "alertEntrys", alerts); + + Task acknowledgeTask = (Task)GetPrivateMethod("AcknowledgeAllOpen").Invoke(monitoring, null)!; + await acknowledgeTask; + + Assert.That(alerts, Is.Empty); + Assert.That(apiConn.AcknowledgeAllCalls, Is.EqualTo(1)); + } + } + + internal sealed class MonitoringMainTestApiConn : SimulatedApiConnection + { + public List AcknowledgedAlertIds { get; } = []; + public int AcknowledgeAllCalls { get; private set; } + public int AckAllAffectedRows { get; set; } = 1; + + public override Task SendQueryAsync(string query, object? variables = null, string? operationName = null) + { + if (typeof(QueryResponseType) == typeof(ReturnId)) + { + if (query == MonitorQueries.acknowledgeAlert) + { + if (variables != null) + { + object? idValue = variables.GetType().GetProperty("id")?.GetValue(variables); + if (idValue != null) + { + AcknowledgedAlertIds.Add(Convert.ToInt64(idValue)); + } + } + return Task.FromResult((QueryResponseType)(object)new ReturnId()); + } + + if (query == MonitorQueries.acknowledgeAllOpenAlerts) + { + AcknowledgeAllCalls++; + return Task.FromResult((QueryResponseType)(object)new ReturnId { AffectedRows = AckAllAffectedRows }); + } + } + + throw new NotImplementedException(); + } + } + + internal sealed class MonitoringTestAuthStateProvider : AuthenticationStateProvider + { + private readonly ClaimsPrincipal principal; + + public MonitoringTestAuthStateProvider(params string[] roles) + { + List claims = []; + foreach (string role in roles) + { + claims.Add(new Claim(ClaimTypes.Role, role)); + } + ClaimsIdentity identity = new(claims, "Test"); + principal = new ClaimsPrincipal(identity); + } + + public override Task GetAuthenticationStateAsync() + { + return Task.FromResult(new AuthenticationState(principal)); + } + } +} diff --git a/roles/tests-unit/files/FWO.Test/UiObjectGroupTest.cs b/roles/tests-unit/files/FWO.Test/UiObjectGroupTest.cs new file mode 100644 index 0000000000..6c44970216 --- /dev/null +++ b/roles/tests-unit/files/FWO.Test/UiObjectGroupTest.cs @@ -0,0 +1,99 @@ +using System; +using System.Collections.Generic; +using System.Threading.Tasks; +using Bunit; +using FWO.Config.Api; +using FWO.Data; +using FWO.Data.Report; +using FWO.Report; +using FWO.Ui.Shared; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.JSInterop; +using NUnit.Framework; + +namespace FWO.Test +{ + [FixtureLifeCycle(LifeCycle.InstancePerTestCase)] + public class UiObjectGroupTest : BunitContext + { + [Test] + public void FetchesDetailsWhenContentChanges() + { + Services.AddSingleton(new SimulatedUserConfig()); + Services.AddScoped(_ => JSInterop.JSRuntime); + Services.AddLocalization(); + + int fetchCount = 0; + Rule rule1 = new() { Id = 1, MgmtId = 1, Name = "rule-1" }; + Rule rule2 = new() { Id = 2, MgmtId = 1, Name = "rule-2" }; + + Func, long, bool, Task> fetchObjects = + async (tab, objCategory, hasChanged, id, nat) => + { + fetchCount++; + if (id == rule1.Id) + { + rule1.Detailed = true; + } + if (id == rule2.Id) + { + rule2.Detailed = true; + } + await hasChanged(); + }; + + IRenderedComponent> cut = Render>(parameters => parameters + .Add(p => p.FetchObjects, fetchObjects) + .Add(p => p.Tab, RsbTab.rule) + .Add(p => p.PageSize, 0) + .Add(p => p.StartContentDetailed, true) + .Add(p => p.Content, rule1) + .Add(p => p.NameExtractor, rule => rule.Name ?? string.Empty) + .Add(p => p.NetworkObjectExtractor, _ => Array.Empty()) + .Add(p => p.NetworkServiceExtractor, _ => Array.Empty()) + .Add(p => p.NetworkUserExtractor, _ => Array.Empty())); + + Assert.That(fetchCount, Is.EqualTo(1)); + + cut = Render>(parameters => parameters + .Add(p => p.FetchObjects, fetchObjects) + .Add(p => p.Tab, RsbTab.rule) + .Add(p => p.PageSize, 0) + .Add(p => p.StartContentDetailed, true) + .Add(p => p.Content, rule2) + .Add(p => p.NameExtractor, rule => rule.Name ?? string.Empty) + .Add(p => p.NetworkObjectExtractor, _ => Array.Empty()) + .Add(p => p.NetworkServiceExtractor, _ => Array.Empty()) + .Add(p => p.NetworkUserExtractor, _ => Array.Empty())); + + Assert.That(fetchCount, Is.EqualTo(2)); + } + + [Test] + public void RendersOwnerReportsWithDuplicateDefaultIds() + { + Services.AddSingleton(new SimulatedUserConfig()); + Services.AddScoped(_ => JSInterop.JSRuntime); + Services.AddLocalization(); + + List ownerReports = + [ + new() { Owner = new FwoOwner { Id = 0, Name = "Owner A" }, Name = "Owner A" }, + new() { Owner = new FwoOwner { Id = 0, Name = "Owner B" }, Name = "Owner B" } + ]; + + IRenderedComponent> cut = + Render>(parameters => parameters + .Add(p => p.Tab, RsbTab.usedObj) + .Add(p => p.PageSize, 0) + .Add(p => p.Data, ownerReports) + .Add(p => p.NameExtractor, ownerReport => ownerReport.Name ?? string.Empty) + .Add(p => p.NetworkObjectExtractor, _ => Array.Empty()) + .Add(p => p.NetworkServiceExtractor, _ => Array.Empty()) + .Add(p => p.NetworkUserExtractor, _ => Array.Empty())); + + Assert.That(cut.Markup, Does.Contain("Owner A")); + Assert.That(cut.Markup, Does.Contain("Owner B")); + } + } +} diff --git a/roles/tests-unit/files/FWO.Test/UiOwnersReportTest.cs b/roles/tests-unit/files/FWO.Test/UiOwnersReportTest.cs new file mode 100644 index 0000000000..25db05ac4d --- /dev/null +++ b/roles/tests-unit/files/FWO.Test/UiOwnersReportTest.cs @@ -0,0 +1,65 @@ +using Bunit; +using FWO.Api.Client; +using FWO.Config.Api; +using FWO.Data; +using FWO.Data.Report; +using FWO.Ui.Pages.Reporting.Reports; +using Microsoft.AspNetCore.Components; +using Microsoft.Extensions.DependencyInjection; +using NUnit.Framework; + +namespace FWO.Test +{ + [TestFixture] + [FixtureLifeCycle(LifeCycle.InstancePerTestCase)] + internal class UiOwnersReportTest + { + private sealed class ThrowingOwnersReportApiConn : SimulatedApiConnection + { + public override Task SendQueryAsync(string query, object? variables = null, string? operationName = null) + { + throw new InvalidOperationException("field 'owner_lifecycle_state' not found in type: 'query_root'"); + } + } + + [SetUp] + public void SetUpTranslations() + { + SimulatedUserConfig.DummyTranslate.TryAdd("id", "Id"); + SimulatedUserConfig.DummyTranslate.TryAdd("name", "Name"); + SimulatedUserConfig.DummyTranslate.TryAdd("criticality", "Criticality"); + SimulatedUserConfig.DummyTranslate.TryAdd("state", "State"); + SimulatedUserConfig.DummyTranslate.TryAdd("additional_info", "Additional info"); + SimulatedUserConfig.DummyTranslate.TryAdd("inactive", "inactive"); + } + + [Test] + public void OwnersReport_QueryFailure_IsCaughtAndReported() + { + using Bunit.TestContext context = new(); + context.JSInterop.Mode = JSRuntimeMode.Loose; + context.Services.AddSingleton(new ThrowingOwnersReportApiConn()); + SimulatedUserConfig userConfig = new(); + context.Services.AddSingleton(userConfig); + + List<(Exception? Exception, string Title)> messages = []; + Action displayMessageInUi = (exception, title, _, _) => messages.Add((exception, title)); + + IRenderedComponent>> wrapper = + context.Render>>(parameters => parameters + .Add(p => p.Value, displayMessageInUi) + .AddChildContent(childParameters => childParameters + .Add(p => p.OwnerData, new List + { + new() { Owner = new FwoOwner { Name = "App One", ExtAppId = "APP-1" } } + }))); + + wrapper.WaitForAssertion(() => + { + Assert.That(messages, Has.Count.EqualTo(1)); + Assert.That(messages[0].Exception, Is.Not.Null); + Assert.That(messages[0].Title, Is.EqualTo(userConfig.GetText("object_fetch"))); + }); + } + } +} diff --git a/roles/tests-unit/files/FWO.Test/UiReportModellingParamSelectionTest.cs b/roles/tests-unit/files/FWO.Test/UiReportModellingParamSelectionTest.cs new file mode 100644 index 0000000000..2652fcb48c --- /dev/null +++ b/roles/tests-unit/files/FWO.Test/UiReportModellingParamSelectionTest.cs @@ -0,0 +1,82 @@ +using Bunit; +using FWO.Api.Client; +using FWO.Basics; +using FWO.Config.Api; +using FWO.Data; +using FWO.Data.Report; +using FWO.Ui.Pages.Reporting; +using FWO.Ui.Services; +using Microsoft.AspNetCore.Authorization; +using Microsoft.AspNetCore.Components.Authorization; +using Microsoft.Extensions.DependencyInjection; +using NUnit.Framework; +using System; +using System.Collections.Generic; +using System.Threading.Tasks; + +namespace FWO.Test +{ + [TestFixture] + [FixtureLifeCycle(LifeCycle.InstancePerTestCase)] + public class UiReportModellingParamSelectionTest + { + [Test] + public async Task VarianceAnalysisCollapsesMultiOwnerSelectionToDisplayedOwner() + { + await using Bunit.TestContext context = new(); + context.JSInterop.Mode = JSRuntimeMode.Loose; + context.Services.AddAuthorizationCore(); + context.Services.AddLocalization(); + context.Services.AddSingleton(); + context.Services.AddSingleton(new MonitoringTestAuthStateProvider(Roles.Admin)); + context.Services.AddSingleton(new ReportModellingParamSelectionTestApiConn()); + context.Services.AddScoped(); + context.Services.AddSingleton(new SimulatedUserConfig()); + + FwoOwner firstOwner = new() { Id = 11, Name = "App One" }; + FwoOwner secondOwner = new() { Id = 12, Name = "App Two" }; + ModellingFilter modellingFilter = new() + { + SelectedOwners = [firstOwner, secondOwner] + }; + + IRenderedComponent wrapper = context.Render(parameters => + parameters.AddChildContent(childParameters => childParameters + .Add(p => p.ModellingFilter, modellingFilter) + .Add(p => p.ReportType, ReportType.VarianceAnalysis))); + + wrapper.WaitForAssertion(() => + { + Assert.That(modellingFilter.SelectedOwners, Has.Count.EqualTo(1)); + Assert.That(modellingFilter.SelectedOwner.Id, Is.EqualTo(firstOwner.Id)); + }); + } + } + + internal sealed class ReportModellingParamSelectionTestApiConn : SimulatedApiConnection + { + public override async Task SendQueryAsync( + string query, + object? variables = null, + string? operationName = null) + { + await Task.CompletedTask; + + if (typeof(QueryResponseType) == typeof(List)) + { + return (QueryResponseType)(object)new List + { + new() { Id = 11, Name = "App One" }, + new() { Id = 12, Name = "App Two" } + }; + } + + if (typeof(QueryResponseType) == typeof(List)) + { + return (QueryResponseType)(object)new List(); + } + + throw new NotImplementedException(); + } + } +} diff --git a/roles/tests-unit/files/FWO.Test/UiReportOwnerParamSelectionTest.cs b/roles/tests-unit/files/FWO.Test/UiReportOwnerParamSelectionTest.cs new file mode 100644 index 0000000000..9865650f93 --- /dev/null +++ b/roles/tests-unit/files/FWO.Test/UiReportOwnerParamSelectionTest.cs @@ -0,0 +1,60 @@ +using Bunit; +using FWO.Api.Client; +using FWO.Config.Api; +using FWO.Data; +using FWO.Ui.Pages.Reporting; +using FWO.Ui.Services; +using Microsoft.AspNetCore.Components; +using Microsoft.Extensions.DependencyInjection; +using NUnit.Framework; + +namespace FWO.Test +{ + [TestFixture] + [FixtureLifeCycle(LifeCycle.InstancePerTestCase)] + internal class UiReportOwnerParamSelectionTest + { + private sealed class ThrowingOwnerParamApiConn : SimulatedApiConnection + { + public override Task SendQueryAsync(string query, object? variables = null, string? operationName = null) + { + throw new InvalidOperationException("field 'owner_lifecycle_state' not found in type: 'query_root'"); + } + } + + [SetUp] + public void SetUpTranslations() + { + SimulatedUserConfig.DummyTranslate.TryAdd("state", "State"); + SimulatedUserConfig.DummyTranslate.TryAdd("criticality", "Criticality"); + SimulatedUserConfig.DummyTranslate.TryAdd("all", "All"); + SimulatedUserConfig.DummyTranslate.TryAdd("inactive", "inactive"); + } + + [Test] + public async Task ReportOwnerParamSelection_QueryFailure_IsCaughtAndReported() + { + await using Bunit.TestContext context = new(); + context.JSInterop.Mode = JSRuntimeMode.Loose; + context.Services.AddScoped(); + context.Services.AddSingleton(new ThrowingOwnerParamApiConn()); + SimulatedUserConfig userConfig = new(); + context.Services.AddSingleton(userConfig); + + List<(Exception? Exception, string Title)> messages = []; + Action displayMessageInUi = (exception, title, _, _) => messages.Add((exception, title)); + + IRenderedComponent>> wrapper = + context.Render>>(parameters => parameters + .Add(p => p.Value, displayMessageInUi) + .AddChildContent()); + + wrapper.WaitForAssertion(() => + { + Assert.That(messages, Has.Count.EqualTo(1)); + Assert.That(messages[0].Exception, Is.Not.Null); + Assert.That(messages[0].Title, Is.EqualTo(userConfig.GetText("object_fetch"))); + }); + } + } +} diff --git a/roles/tests-unit/files/FWO.Test/UiReportTemplateComponentTest.cs b/roles/tests-unit/files/FWO.Test/UiReportTemplateComponentTest.cs new file mode 100644 index 0000000000..9848120baf --- /dev/null +++ b/roles/tests-unit/files/FWO.Test/UiReportTemplateComponentTest.cs @@ -0,0 +1,362 @@ +using Bunit; +using FWO.Api.Client; +using FWO.Api.Client.Queries; +using FWO.Basics; +using FWO.Config.Api; +using FWO.Data; +using FWO.Data.Report; +using FWO.Ui.Pages.Reporting; +using FWO.Ui.Services; +using Microsoft.AspNetCore.Authorization; +using Microsoft.AspNetCore.Components.Authorization; +using Microsoft.Extensions.DependencyInjection; +using NUnit.Framework; + +namespace FWO.Test +{ + [TestFixture] + [FixtureLifeCycle(LifeCycle.InstancePerTestCase)] + internal class UiReportTemplateComponentTest + { + private sealed class ReportTemplateComponentTestApiConn(List templates, List owners) : SimulatedApiConnection + { + public override Task SendQueryAsync(string query, object? variables = null, string? operationName = null) + { + if (typeof(QueryResponseType) == typeof(ReportTemplate[])) + { + return Task.FromResult((QueryResponseType)(object)templates.ToArray()); + } + + if (typeof(QueryResponseType) == typeof(List)) + { + return Task.FromResult((QueryResponseType)(object)owners); + } + + throw new NotImplementedException(); + } + } + + [SetUp] + public void SetUpTranslations() + { + SimulatedUserConfig.DummyTranslate.TryAdd("templates", "Templates"); + SimulatedUserConfig.DummyTranslate.TryAdd("actions", "Actions"); + SimulatedUserConfig.DummyTranslate.TryAdd("comment", "Comment"); + SimulatedUserConfig.DummyTranslate.TryAdd("creation_date", "Creation date"); + SimulatedUserConfig.DummyTranslate.TryAdd("load", "Load"); + SimulatedUserConfig.DummyTranslate.TryAdd("edit", "Edit"); + SimulatedUserConfig.DummyTranslate.TryAdd("delete", "Delete"); + SimulatedUserConfig.DummyTranslate.TryAdd("report_template", "Report template"); + SimulatedUserConfig.DummyTranslate.TryAdd("U1002", "Delete template"); + SimulatedUserConfig.DummyTranslate.TryAdd("report_time", "Report time"); + SimulatedUserConfig.DummyTranslate.TryAdd("devices", "Devices"); + SimulatedUserConfig.DummyTranslate.TryAdd("managements", "Managements"); + SimulatedUserConfig.DummyTranslate.TryAdd("unused_days", "Unused days"); + SimulatedUserConfig.DummyTranslate.TryAdd("diff_interval", "Diff interval"); + SimulatedUserConfig.DummyTranslate.TryAdd("show_non_impact_rules", "Show non impact rules"); + SimulatedUserConfig.DummyTranslate.TryAdd("tenant", "Tenant"); + SimulatedUserConfig.DummyTranslate.TryAdd("report_type", "Report type"); + SimulatedUserConfig.DummyTranslate.TryAdd("select_device", "Select device"); + SimulatedUserConfig.DummyTranslate.TryAdd("select_time", "Select time"); + SimulatedUserConfig.DummyTranslate.TryAdd("report_filters", "Report filters"); + SimulatedUserConfig.DummyTranslate.TryAdd("rule_filters", "Rule filters"); + SimulatedUserConfig.DummyTranslate.TryAdd("save_template", "Save template"); + SimulatedUserConfig.DummyTranslate.TryAdd("edit_template", "Edit template"); + SimulatedUserConfig.DummyTranslate.TryAdd("delete_template", "Delete template"); + SimulatedUserConfig.DummyTranslate.TryAdd("open", "Open"); + SimulatedUserConfig.DummyTranslate.TryAdd("Days", "Days"); + SimulatedUserConfig.DummyTranslate.TryAdd("Weeks", "Wochen"); + SimulatedUserConfig.DummyTranslate.TryAdd("Months", "Months"); + SimulatedUserConfig.DummyTranslate.TryAdd("Years", "Years"); + } + + [Test] + public void ReportTemplateComponent_ModellerOnly_ShowsOnlyAllowedTemplates() + { + using Bunit.TestContext context = CreateContext( + new MonitoringTestAuthStateProvider(Roles.Modeller), + CreateUserConfig([Roles.Modeller], [11]), + new ReportTemplateComponentTestApiConn( + [ + CreateTemplate(1, "Connections template", ReportType.Connections, ownerId: 11), + CreateTemplate(2, "Compliance template", ReportType.ComplianceReport), + CreateTemplate(3, "Workflow template", ReportType.TicketReport), + CreateTemplate(4, "Certificate template", ReportType.RecertificationEvent) + ], + [new FwoOwner { Id = 11, Name = "Owned App" }])); + + IRenderedComponent wrapper = context.Render(parameters => + parameters.AddChildContent()); + + wrapper.WaitForAssertion(() => + { + string markup = wrapper.Markup; + Assert.That(markup, Does.Contain("Connections template")); + Assert.That(markup, Does.Not.Contain("Compliance template")); + Assert.That(markup, Does.Not.Contain("Workflow template")); + Assert.That(markup, Does.Not.Contain("Certificate template")); + }); + } + + [Test] + public void ReportTemplateComponent_Auditor_ShowsComplianceAndWorkflowButNotArchiveOnly() + { + using Bunit.TestContext context = CreateContext( + new MonitoringTestAuthStateProvider(Roles.Auditor), + CreateUserConfig([Roles.Auditor], [11]), + new ReportTemplateComponentTestApiConn( + [ + CreateTemplate(1, "Compliance template", ReportType.ComplianceReport), + CreateTemplate(2, "Workflow template", ReportType.TicketReport), + CreateTemplate(3, "Certificate template", ReportType.RecertificationEvent) + ], + [new FwoOwner { Id = 11, Name = "Owned App" }])); + + IRenderedComponent wrapper = context.Render(parameters => + parameters.AddChildContent()); + + wrapper.WaitForAssertion(() => + { + string markup = wrapper.Markup; + Assert.That(markup, Does.Contain("Compliance template")); + Assert.That(markup, Does.Contain("Workflow template")); + Assert.That(markup, Does.Not.Contain("Certificate template")); + }); + } + + [Test] + public void ReportTemplateComponent_Modeller_HidesTemplateForInaccessibleOwner() + { + using Bunit.TestContext context = CreateContext( + new MonitoringTestAuthStateProvider(Roles.Modeller), + CreateUserConfig([Roles.Modeller], [11]), + new ReportTemplateComponentTestApiConn( + [ + CreateTemplate(1, "Owned connections template", ReportType.Connections, ownerId: 11), + CreateTemplate(2, "Foreign connections template", ReportType.Connections, ownerId: 12) + ], + [new FwoOwner { Id = 11, Name = "Owned App" }])); + + IRenderedComponent wrapper = context.Render(parameters => + parameters.AddChildContent()); + + wrapper.WaitForAssertion(() => + { + string markup = wrapper.Markup; + Assert.That(markup, Does.Contain("Owned connections template")); + Assert.That(markup, Does.Not.Contain("Foreign connections template")); + }); + } + + [Test] + public void ReportTemplateComponent_Reporter_ShowsRuleTemplateButNotWorkflowTemplate() + { + using Bunit.TestContext context = CreateContext( + new MonitoringTestAuthStateProvider(Roles.Reporter), + CreateUserConfig([Roles.Reporter], []), + new ReportTemplateComponentTestApiConn( + [ + CreateTemplate(1, "Rules template", ReportType.Rules), + CreateTemplate(2, "Workflow template", ReportType.TicketReport), + CreateTemplate(3, "App rules template", ReportType.AppRules), + CreateTemplate(4, "Owners template", ReportType.Owners) + ], + [])); + + IRenderedComponent wrapper = context.Render(parameters => + parameters.AddChildContent()); + + wrapper.WaitForAssertion(() => + { + string markup = wrapper.Markup; + Assert.That(markup, Does.Contain("Rules template")); + Assert.That(markup, Does.Not.Contain("Workflow template")); + Assert.That(markup, Does.Not.Contain("App rules template")); + Assert.That(markup, Does.Not.Contain("Owners template")); + }); + } + + [Test] + public void ReportTemplateComponent_DecodeAndRecodeComment_PreserveTemplateKey() + { + using Bunit.TestContext context = CreateContext( + new MonitoringTestAuthStateProvider(Roles.Reporter), + CreateUserConfig([Roles.Reporter], []), + new ReportTemplateComponentTestApiConn([], [])); + + IRenderedComponent wrapper = context.Render(parameters => + parameters.AddChildContent()); + ReportTemplateComponent component = wrapper.FindComponent().Instance; + ReportTemplate template = new() + { + Comment = "T0100" + }; + SimulatedUserConfig.DummyTranslate["T0100"] = "Translated template comment"; + + ReportTemplate decodedTemplate = component.decodeComment(template); + string recodedComment = component.recodeComment(decodedTemplate.Comment); + + Assert.That(decodedTemplate.Comment, Is.EqualTo("Translated template comment")); + Assert.That(recodedComment, Is.EqualTo("T0100")); + } + + [Test] + public void ReportTemplateComponent_NewTemplate_OpensAddDialogForSelectedType() + { + using Bunit.TestContext context = CreateContext( + new MonitoringTestAuthStateProvider(Roles.Reporter), + CreateUserConfig([Roles.Reporter], []), + new ReportTemplateComponentTestApiConn([], [])); + + IRenderedComponent wrapper = context.Render(parameters => + parameters.AddChildContent()); + ReportTemplateComponent component = wrapper.FindComponent().Instance; + ReportTemplate template = CreateTemplate(1, "Rules template", ReportType.Rules); + + component.NewTemplate(template); + + Assert.That(component.reportTemplateInEdit, Is.SameAs(template)); + Assert.That(GetPrivateField(component, "ShowAddTemplateDialog"), Is.True); + Assert.That(GetPrivateField(component, "reportTypeInEdit"), Is.EqualTo(ReportType.Rules)); + } + + [Test] + public void ReportTemplateComponent_CancelEdit_RestoresOriginalDeviceFilterAndClosesDialogs() + { + using Bunit.TestContext context = CreateContext( + new MonitoringTestAuthStateProvider(Roles.Reporter), + CreateUserConfig([Roles.Reporter], []), + new ReportTemplateComponentTestApiConn([], [])); + + IRenderedComponent wrapper = context.Render(parameters => + parameters.AddChildContent()); + ReportTemplateComponent component = wrapper.FindComponent().Instance; + DeviceFilter originalFilter = new( + [ + new() + { + Id = 1, + Devices = [new() { Id = 11, Selected = true }] + } + ]); + component.reportTemplateInEdit.ReportParams.DeviceFilter = new DeviceFilter(); + SetPrivateField(component, "DeviceFilterOrig", originalFilter); + SetPrivateField(component, "ShowAddTemplateDialog", true); + SetPrivateField(component, "ShowUpdateTemplateDialog", true); + + InvokePrivateMethod(component, "CancelEdit"); + + Assert.That(component.reportTemplateInEdit.ReportParams.DeviceFilter.Managements[0].Devices[0].Selected, Is.True); + Assert.That(GetPrivateField(component, "ShowAddTemplateDialog"), Is.False); + Assert.That(GetPrivateField(component, "ShowUpdateTemplateDialog"), Is.False); + } + + [Test] + public void ReportTemplateComponent_DisplayTime_ShowsChangeIntervalDescription() + { + SimulatedUserConfig userConfig = CreateUserConfig([Roles.Reporter], []); + using Bunit.TestContext context = CreateContext( + new MonitoringTestAuthStateProvider(Roles.Reporter), + userConfig, + new ReportTemplateComponentTestApiConn([], [])); + + IRenderedComponent wrapper = context.Render(parameters => + parameters.AddChildContent()); + ReportTemplateComponent component = wrapper.FindComponent().Instance; + SetPrivateField(component, "reportTypeInEdit", ReportType.Changes); + component.reportTemplateInEdit.ReportParams.TimeFilter.TimeRangeType = TimeRangeType.Interval; + component.reportTemplateInEdit.ReportParams.TimeFilter.Offset = 3; + component.reportTemplateInEdit.ReportParams.TimeFilter.Interval = SchedulerInterval.Weeks; + + string displayTime = component.DisplayTime(); + + Assert.That(displayTime, Is.EqualTo($"{userConfig.GetText("last")} 3 {userConfig.GetText(SchedulerInterval.Weeks.ToString())}")); + } + + [Test] + public void ReportTemplateComponent_DisplayTime_ShowsOpenFixedDateRange() + { + using Bunit.TestContext context = CreateContext( + new MonitoringTestAuthStateProvider(Roles.Reporter), + CreateUserConfig([Roles.Reporter], []), + new ReportTemplateComponentTestApiConn([], [])); + + IRenderedComponent wrapper = context.Render(parameters => + parameters.AddChildContent()); + ReportTemplateComponent component = wrapper.FindComponent().Instance; + SetPrivateField(component, "reportTypeInEdit", ReportType.Changes); + component.reportTemplateInEdit.ReportParams.TimeFilter.TimeRangeType = TimeRangeType.Fixeddates; + component.reportTemplateInEdit.ReportParams.TimeFilter.OpenStart = true; + component.reportTemplateInEdit.ReportParams.TimeFilter.OpenEnd = true; + + string displayTime = component.DisplayTime(); + + Assert.That(displayTime, Is.EqualTo("Open")); + } + + private static Bunit.TestContext CreateContext(AuthenticationStateProvider authStateProvider, UserConfig userConfig, ApiConnection apiConnection) + { + Bunit.TestContext context = new(); + context.JSInterop.Mode = JSRuntimeMode.Loose; + context.Services.AddAuthorizationCore(); + context.Services.AddLocalization(); + context.Services.AddSingleton(); + context.Services.AddSingleton(authStateProvider); + context.Services.AddSingleton(apiConnection); + context.Services.AddScoped(); + context.Services.AddSingleton(userConfig); + return context; + } + + private static SimulatedUserConfig CreateUserConfig(List roles, List ownerships) + { + return new SimulatedUserConfig + { + User = + { + DbId = 50, + Language = "English", + Roles = roles, + Ownerships = ownerships + } + }; + } + + private static ReportTemplate CreateTemplate(int id, string name, ReportType reportType, int ownerId = 0) + { + return new ReportTemplate + { + Id = id, + Name = name, + Filter = "", + Comment = "", + ReportParams = new ReportParams + { + ReportType = (int)reportType, + ModellingFilter = new() + { + SelectedOwner = new FwoOwner { Id = ownerId, Name = $"Owner {ownerId}" } + } + } + }; + } + + private static T GetPrivateField(object instance, string fieldName) + { + return (T)(instance.GetType().GetField(fieldName, System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic)?.GetValue(instance) + ?? throw new MissingFieldException(instance.GetType().FullName, fieldName)); + } + + private static void SetPrivateField(object instance, string fieldName, object value) + { + instance.GetType().GetField(fieldName, System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic) + ?.SetValue(instance, value); + } + + private static object? InvokePrivateMethod(object instance, string methodName, params object[] parameters) + { + return instance.GetType().GetMethod(methodName, System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic) + ?.Invoke(instance, parameters); + } + } +} diff --git a/roles/tests-unit/files/FWO.Test/UiRequestWorkflowTest.cs b/roles/tests-unit/files/FWO.Test/UiRequestWorkflowTest.cs new file mode 100644 index 0000000000..fa33038179 --- /dev/null +++ b/roles/tests-unit/files/FWO.Test/UiRequestWorkflowTest.cs @@ -0,0 +1,305 @@ +using Bunit; +using FWO.Api.Client; +using FWO.Api.Client.Queries; +using FWO.Basics; +using FWO.Config.Api; +using FWO.Data; +using FWO.Data.Workflow; +using FWO.Services; +using FWO.Services.EventMediator; +using FWO.Services.EventMediator.Interfaces; +using FWO.Services.Workflow; +using FWO.Ui.Pages.Request; +using FWO.Ui.Services; +using Microsoft.AspNetCore.Authorization; +using Microsoft.AspNetCore.Components.Authorization; +using Microsoft.Extensions.DependencyInjection; +using NUnit.Framework; +using System.Collections.Generic; +using System.Reflection; +using System.Security.Claims; +using System.Threading.Tasks; + +namespace FWO.Test +{ + [TestFixture] + internal class UiRequestWorkflowTest + { + private static void SetMember(object instance, string memberName, object? value) + { + Type type = instance.GetType(); + PropertyInfo? property = type.GetProperty(memberName, BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance); + if (property != null) + { + property.SetValue(instance, value); + return; + } + + FieldInfo? field = type.GetField(memberName, BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance); + if (field != null) + { + field.SetValue(instance, value); + return; + } + + throw new MissingFieldException(type.FullName, memberName); + } + + private static void SetMatrix(WfHandler handler, string taskType, StateMatrix matrix) + { + FieldInfo? field = typeof(WfHandler).GetField("stateMatrixDict", BindingFlags.NonPublic | BindingFlags.Instance); + StateMatrixDict dict = (StateMatrixDict)(field?.GetValue(handler) ?? new StateMatrixDict()); + dict.Matrices[taskType] = matrix; + } + + private static DisplayReqTaskTable CreateReqTaskTable(WfHandler handler, WorkflowPhases phase) + { + DisplayReqTaskTable component = new(); + SetMember(component, nameof(DisplayReqTaskTable.WfHandler), handler); + SetMember(component, nameof(DisplayReqTaskTable.Phase), phase); + return component; + } + + private static IRenderedComponent RenderDisplayRequestTask( + Bunit.TestContext context, + WfHandler handler, + WfStateDict states, + params string[] roles) + { + context.JSInterop.Mode = JSRuntimeMode.Loose; + context.Services.AddAuthorizationCore(); + context.Services.AddSingleton(); + context.Services.AddSingleton(new RequestWorkflowAuthStateProvider(roles)); + context.Services.AddSingleton(new RequestWorkflowApiConn()); + context.Services.AddSingleton(new RequestWorkflowUserConfig()); + context.Services.AddSingleton(); + context.Services.AddSingleton(new EventMediator()); + + IRenderedComponent wrapper = context.Render(parameters => parameters + .AddChildContent(child => child + .Add(p => p.Phase, WorkflowPhases.request) + .Add(p => p.States, states) + .Add(p => p.WfHandler, handler) + .Add(p => p.ResetParent, DefaultInit.DoNothing) + .Add(p => p.StartImplPhase, (Func)DefaultInit.DoNothing))); + + return wrapper.FindComponent(); + } + + private static IRenderedComponent RenderPromoteObject( + Bunit.TestContext context, + WfStateDict states, + StateMatrix stateMatrix, + WfStatefulObject statefulObject, + params string[] roles) + { + context.JSInterop.Mode = JSRuntimeMode.Loose; + context.Services.AddAuthorizationCore(); + context.Services.AddSingleton(); + context.Services.AddSingleton(new RequestWorkflowAuthStateProvider(roles)); + context.Services.AddSingleton(new RequestWorkflowUserConfig()); + context.Services.AddSingleton(); + context.Services.AddSingleton(new EventMediator()); + + IRenderedComponent wrapper = context.Render(parameters => parameters + .AddChildContent(child => child + .Add(p => p.Promote, true) + .Add(p => p.States, states) + .Add(p => p.StateMatrix, stateMatrix) + .Add(p => p.StatefulObject, statefulObject) + .Add(p => p.ObjectName, "Task") + .Add(p => p.CloseParent, DefaultInit.DoNothing) + .Add(p => p.CancelParent, DefaultInit.DoNothingSync) + .Add(p => p.Save, (Func)DefaultInit.DoNothing))); + + return wrapper.FindComponent(); + } + + [Test] + public void DisplayReqTaskTable_RequestPhase_AllowsEditBelowLowestEndState() + { + WfHandler handler = new() + { + EditTicketMode = true + }; + WfReqTask reqTask = new() + { + TaskType = WfTaskType.access.ToString(), + StateId = 1 + }; + SetMatrix(handler, reqTask.TaskType, new StateMatrix + { + LowestStartedState = 1, + LowestEndState = 5 + }); + + DisplayReqTaskTable component = CreateReqTaskTable(handler, WorkflowPhases.request); + MethodInfo? method = typeof(DisplayReqTaskTable).GetMethod("CanEditReqTaskInPhase", BindingFlags.NonPublic | BindingFlags.Instance); + Assert.That(method, Is.Not.Null); + + bool canEdit = (bool)method!.Invoke(component, [reqTask])!; + + Assert.That(canEdit, Is.True); + } + + [Test] + public void DisplayReqTaskTable_ApprovalPhase_StopsEditAtLowestStartedState() + { + WfHandler handler = new() + { + EditTicketMode = true + }; + WfReqTask reqTask = new() + { + TaskType = WfTaskType.access.ToString(), + StateId = 1 + }; + SetMatrix(handler, reqTask.TaskType, new StateMatrix + { + LowestStartedState = 1, + LowestEndState = 5 + }); + + DisplayReqTaskTable component = CreateReqTaskTable(handler, WorkflowPhases.approval); + MethodInfo? method = typeof(DisplayReqTaskTable).GetMethod("CanEditReqTaskInPhase", BindingFlags.NonPublic | BindingFlags.Instance); + Assert.That(method, Is.Not.Null); + + bool canEdit = (bool)method!.Invoke(component, [reqTask])!; + + Assert.That(canEdit, Is.False); + } + + [Test] + public async Task DisplayRequestTask_NewTask_AddsTaskTypeDropdownComparedToExistingTask() + { + WfHandler existingHandler = new() + { + DisplayReqTaskMode = true, + EditReqTaskMode = true, + AddReqTaskMode = false, + ActReqTask = new WfReqTask + { + Id = 12, + Title = "Task", + TaskType = WfTaskType.generic.ToString(), + StateId = 0, + FreeText = "text" + } + }; + existingHandler.ActTicket.Tasks.Add(existingHandler.ActReqTask); + WfStateDict states = new() { Name = { [0] = "Draft" } }; + int existingDropdownCount; + await using (Bunit.TestContext existingContext = new()) + { + IRenderedComponent existingComponent = RenderDisplayRequestTask(existingContext, existingHandler, states, Roles.Requester); + existingDropdownCount = existingComponent.FindAll("input[id^='dropdown-input-']").Count; + } + + WfHandler newHandler = new() + { + DisplayReqTaskMode = true, + EditReqTaskMode = true, + AddReqTaskMode = true, + ActReqTask = new WfReqTask + { + Id = 0, + Title = "Task", + TaskType = WfTaskType.generic.ToString(), + StateId = 0 + } + }; + newHandler.ActTicket.Tasks.Add(newHandler.ActReqTask); + int newDropdownCount; + await using (Bunit.TestContext newContext = new()) + { + IRenderedComponent newComponent = RenderDisplayRequestTask(newContext, newHandler, states, Roles.Requester); + newDropdownCount = newComponent.FindAll("input[id^='dropdown-input-']").Count; + } + + Assert.That(newDropdownCount, Is.GreaterThan(existingDropdownCount)); + } + + [Test] + public async Task PromoteObject_MissingStateName_FallsBackToStateId() + { + await using Bunit.TestContext context = new(); + WfStateDict states = new(); + StateMatrix stateMatrix = new() + { + Matrix = new() + { + [0] = [5, 6] + } + }; + WfStatefulObject statefulObject = new() + { + StateId = 0 + }; + + IRenderedComponent component = RenderPromoteObject(context, states, stateMatrix, statefulObject, Roles.Requester); + + Assert.That(component.Markup, Does.Contain("promote_to")); + Assert.That(component.Markup, Does.Contain("dropdown-input-")); + } + + private sealed class RequestWorkflowApiConn : SimulatedApiConnection + { + public override Task SendQueryAsync(string query, object? variables = null, string? operationName = null) + { + if (query == StmQueries.getRuleActions) + { + return Task.FromResult((QueryResponseType)(object)new List()); + } + if (query == StmQueries.getTracking) + { + return Task.FromResult((QueryResponseType)(object)new List()); + } + if (query == StmQueries.getIpProtocols) + { + return Task.FromResult((QueryResponseType)(object)new List()); + } + if (query == DeviceQueries.getManagementNames) + { + return Task.FromResult((QueryResponseType)(object)new List()); + } + + throw new NotImplementedException($"Unexpected query: {query}"); + } + } + + private sealed class RequestWorkflowUserConfig : SimulatedUserConfig + { + public RequestWorkflowUserConfig() + { + ReqAvailableTaskTypes = "[\"generic\",\"access\",\"rule_modify\",\"rule_delete\",\"new_interface\",\"group_create\"]"; + ReqAllowedChangesByApprover = "{}"; + } + + public override string GetText(string key) + { + return DummyTranslate.TryGetValue(key, out string? value) ? value : key; + } + } + + private sealed class RequestWorkflowAuthStateProvider : AuthenticationStateProvider + { + private readonly ClaimsPrincipal principal; + + public RequestWorkflowAuthStateProvider(params string[] roles) + { + List claims = []; + foreach (string role in roles) + { + claims.Add(new Claim(ClaimTypes.Role, role)); + } + ClaimsIdentity identity = new(claims, "Test"); + principal = new ClaimsPrincipal(identity); + } + + public override Task GetAuthenticationStateAsync() + { + return Task.FromResult(new AuthenticationState(principal)); + } + } + } +} diff --git a/roles/tests-unit/files/FWO.Test/UiRsbLinkTest.cs b/roles/tests-unit/files/FWO.Test/UiRsbLinkTest.cs new file mode 100644 index 0000000000..94732de4b4 --- /dev/null +++ b/roles/tests-unit/files/FWO.Test/UiRsbLinkTest.cs @@ -0,0 +1,95 @@ +using AngleSharp.Css.Dom; +using AngleSharp.Dom; +using Bunit; +using Bunit.TestDoubles; +using FWO.Api.Client; +using FWO.Config.Api; +using FWO.Logging; +using FWO.Report; +using FWO.Ui.Services; +using FWO.Ui.Shared; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.JSInterop; +using NUnit.Framework; + +namespace FWO.Test +{ + [FixtureLifeCycle(LifeCycle.InstancePerTestCase)] + public class UiRsbLinkTest : BunitContext + { + static readonly UserConfig userConfig = new SimulatedUserConfig + { + ModNamingConvention = "{\"networkAreaRequired\":true,\"fixedPartLength\":4,\"freePartLength\":5,\"networkAreaPattern\":\"NA\",\"appRolePattern\":\"AR\"}" + }; + static readonly ApiConnection apiConnection = new UiRsbTestApiConn(); + static readonly ReportBase currentReport = SimulatedReport.DetailedReport(); + + [Test] + public async Task ObjShouldBeVisibleAfterNavigation() + { + // Event Service + DomEventService eventService = new DomEventService(); + eventService.InvokeNavbarHeightChanged(50); // Simulate initial navbar height change + + // Arrange + Services.AddSingleton(userConfig); + Services.AddSingleton(apiConnection); + Services.AddSingleton(eventService); + Services.AddScoped(_ => JSInterop.JSRuntime); + Services.AddLocalization(); + + Data.NetworkObject objToFind = currentReport.ReportData.ManagementData[0].Objects[1]; + string hrefValue = ReportDevicesBase.GetReportDevicesLinkAddress(OutputLocation.report, currentReport.ReportData.ManagementData[0].Id, ObjCatString.NwObj, 0, objToFind.Id, currentReport.ReportType); + string link = $"https://localhost/{hrefValue}"; + + BunitNavigationManager navigationManager = Services.GetRequiredService(); + navigationManager.NavigateTo(link); + + // Mock JS interop + JSInterop.Setup("getCurrentUrl").SetResult(link); + JSRuntimeInvocationHandler scrollIntoRSBViewInvocation = JSInterop.Setup("scrollIntoRSBView", _ => true).SetResult(true); + JSRuntimeInvocationHandler removeUrlFragmentInvocation = JSInterop.SetupVoid("removeUrlFragment"); + + // Act + // tpurschke: this has to be rewritten as Device does not contain rules anymore + // IRenderedComponent cut = Render(parameters => parameters + // .Add(p => p.CurrentReport, currentReport) + // .Add(p => p.SelectedRules, [currentReport.ReportData.ManagementData[0].Devices[0].Rules![0]])); + + // manually trigger + // IRenderedComponent anchorNavToRSB = cut.FindComponent(); + // Task timeout = Task.Delay(2000); + // Task scrollTask = anchorNavToRSB.InvokeAsync(() => anchorNavToRSB.Instance.NavigateAndScrollToFragment()); + // Task completedTask = await Task.WhenAny(scrollTask, timeout); + // if (completedTask == timeout) + // { + // Log.WriteDebug("Test UI RSB", "NavigateAndScrollToFragment does not complete timely (circle dependency through state changes?)"); + // } + // // Assert + // Assert.That(scrollIntoRSBViewInvocation.Invocations, Is.Not.Empty, "scrollIntoRSBView should have been called"); + // JSRuntimeInvocation invocation = scrollIntoRSBViewInvocation.Invocations.First(); + // object? parameter = invocation.Arguments[0]; + // Assert.That(parameter, Is.Not.Null, "scrollIntoRSBView was called with a null parameter"); + // Assert.That(parameter, Is.InstanceOf(), "scrollIntoRSBView was called with a non-string parameter"); + // Assert.That((string)parameter!, Is.Not.Empty, "scrollIntoRSBView was called with an empty string"); + // IElement element = cut.Find($"#{parameter}"); + // Assert.That(IsElementVisible(element), Is.True, "Element is not visible (might be incorrect tab or collapsed)"); + } + + private bool IsElementVisible(IElement? element) + { + while (element != null) + { + ICssStyleDeclaration? computedStyle = element.Owner?.DefaultView?.GetComputedStyle(element); + string? display = computedStyle?.GetPropertyValue("display"); + if (display == "none") + { + Log.WriteError("Test UI RSB", $"Element {element.TagName} is not visible"); + return false; + } + element = element.ParentElement; + } + return true; + } + } +} diff --git a/roles/tests-unit/files/FWO.Test/UiRsbRuleTabTest.cs b/roles/tests-unit/files/FWO.Test/UiRsbRuleTabTest.cs new file mode 100644 index 0000000000..f3a008dcab --- /dev/null +++ b/roles/tests-unit/files/FWO.Test/UiRsbRuleTabTest.cs @@ -0,0 +1,115 @@ +using System; +using System.Collections.Generic; +using System.Threading.Tasks; +using AngleSharp.Dom; +using Bunit; +using FWO.Api.Client; +using FWO.Basics; +using FWO.Config.Api; +using FWO.Data; +using FWO.Data.Report; +using FWO.Report; +using FWO.Services; +using FWO.Ui.Services; +using FWO.Ui.Shared; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.JSInterop; +using NUnit.Framework; + +namespace FWO.Test +{ + [FixtureLifeCycle(LifeCycle.InstancePerTestCase)] + public class UiRsbRuleTabTest : BunitContext + { + /// + /// Ensures the rule tab updates when the selected rule list changes. + /// + [Test] + public void RuleTabSelectionUpdatesOnChange() + { + TimeSpan waitTimeout = TimeSpan.FromSeconds(5); + Rule ruleAlpha = new() { Id = 1, MgmtId = 1, Name = "Alpha", DeviceName = "Device A" }; + Rule ruleBeta = new() { Id = 2, MgmtId = 1, Name = "Beta", DeviceName = "Device B" }; + + List ruleDetails = [new Rule { Id = 1 }, new Rule { Id = 2 }]; + ReportBase report = SimulatedReport.DetailedReport(ReportType.Rules); + DomEventService domEventService = new(); + domEventService.InvokeNavbarHeightChanged(0); + + Services.AddSingleton(new SimulatedUserConfig()); + Services.AddSingleton(new UiRsbRuleTabApiConn(ruleDetails)); + Services.AddSingleton(domEventService); + Services.AddScoped(_ => JSInterop.JSRuntime); + Services.AddLocalization(); + + IRenderedComponent cut = Render(parameters => parameters + .Add(p => p.AllTabVisible, false) + .Add(p => p.CurrentReport, report) + .Add(p => p.SelectedReportType, ReportType.Rules) + .Add(p => p.SelectedRules, new List())); + + cut.WaitForAssertion(() => Assert.That(FindActiveTabTitle(cut), Is.EqualTo("Report")), waitTimeout); + + RenderedComponentRenderExtensions.Render(cut, parameters => parameters + .Add(p => p.AllTabVisible, false) + .Add(p => p.CurrentReport, report) + .Add(p => p.SelectedReportType, ReportType.Rules) + .Add(p => p.SelectedRules, new List { ruleAlpha })); + + cut.WaitForAssertion(() => + { + Assert.That(FindActiveTabTitle(cut), Is.EqualTo("Rule")); + Assert.That(cut.Markup, Does.Contain("Alpha")); + }, waitTimeout); + + RenderedComponentRenderExtensions.Render(cut, parameters => parameters + .Add(p => p.AllTabVisible, false) + .Add(p => p.CurrentReport, report) + .Add(p => p.SelectedReportType, ReportType.Rules) + .Add(p => p.SelectedRules, new List { ruleBeta })); + + cut.WaitForAssertion(() => + { + Assert.That(FindActiveTabTitle(cut), Is.EqualTo("Rule")); + Assert.That(cut.Markup, Does.Contain("Beta")); + Assert.That(cut.Markup, Does.Not.Contain("Alpha")); + }, waitTimeout); + } + + private static string FindActiveTabTitle(IRenderedComponent cut) + { + IElement? activeLink = cut.FindAll("a.nav-link").FirstOrDefault(el => el.ClassList.Contains("nav-link-active")); + return activeLink?.TextContent.Trim() ?? string.Empty; + } + } + + internal class UiRsbRuleTabApiConn : SimulatedApiConnection + { + private readonly List ruleDetails; + + public UiRsbRuleTabApiConn(List ruleDetails) + { + this.ruleDetails = ruleDetails; + } + + /// + /// Returns rule details for rule-tab fetches during tests. + /// + public override async Task SendQueryAsync( + string query, + object? variables = null, + string? operationName = null) + { + await DefaultInit.DoNothing(); + if (typeof(QueryResponseType) == typeof(List)) + { + return (QueryResponseType)(object)ruleDetails; + } + if (typeof(QueryResponseType) == typeof(List)) + { + return (QueryResponseType)(object)new List(); + } + throw new NotImplementedException(); + } + } +} diff --git a/roles/tests-unit/files/FWO.Test/UiRsbTestApiConn.cs b/roles/tests-unit/files/FWO.Test/UiRsbTestApiConn.cs new file mode 100644 index 0000000000..cbc4a2522c --- /dev/null +++ b/roles/tests-unit/files/FWO.Test/UiRsbTestApiConn.cs @@ -0,0 +1,26 @@ + +using GraphQL; +using FWO.Data.Report; +using FWO.Services; + +namespace FWO.Test +{ + internal class UiRsbTestApiConn : SimulatedApiConnection + { + public override async Task SendQueryAsync(string query, object? variables = null, string? operationName = null) + { + await DefaultInit.DoNothing(); // qad avoid compiler warning + Type responseType = typeof(QueryResponseType); + if (responseType == typeof(List)) + { + List reports = SimulatedReport.DetailedReport().ReportData.ManagementData; + GraphQLResponse response = new() { Data = reports }; + return response.Data; + } + else + { + throw new NotImplementedException(); + } + } + } +} diff --git a/roles/tests-unit/files/FWO.Test/UiSelectionStateTest.cs b/roles/tests-unit/files/FWO.Test/UiSelectionStateTest.cs new file mode 100644 index 0000000000..798a246fd0 --- /dev/null +++ b/roles/tests-unit/files/FWO.Test/UiSelectionStateTest.cs @@ -0,0 +1,91 @@ +using Bunit; +using FWO.Config.Api; +using FWO.Data.Report; +using FWO.Ui.Shared; +using Microsoft.Extensions.DependencyInjection; +using NUnit.Framework; + +namespace FWO.Test +{ + [TestFixture] + [FixtureLifeCycle(LifeCycle.InstancePerTestCase)] + internal class UiSelectionStateTest : BunitContext + { + [SetUp] + public void SetUpContext() + { + JSInterop.Mode = JSRuntimeMode.Loose; + Services.AddSingleton(new SimulatedUserConfig()); + Services.AddLocalization(); + SimulatedUserConfig.DummyTranslate.TryAdd("select_all", "Select All"); + SimulatedUserConfig.DummyTranslate.TryAdd("clear_all", "Clear All"); + SimulatedUserConfig.DummyTranslate.TryAdd("collapse_all", "Collapse All"); + SimulatedUserConfig.DummyTranslate.TryAdd("expand_all", "Expand All"); + SimulatedUserConfig.DummyTranslate.TryAdd("select_device", "Select device"); + SimulatedUserConfig.DummyTranslate.TryAdd("select_management", "Select management"); + } + + [Test] + public void ManagementSelection_RecomputesButtonStateFromSelectedFilter() + { + DeviceFilter deviceFilter = CreateFullySelectedFilter(); + + IRenderedComponent cut = Render(parameters => parameters + .Add(p => p.DeviceFilter, deviceFilter) + .Add(p => p.SelectAll, true) + .Add(p => p.ShowTitle, false) + .Add(p => p.UseLightText, false)); + + Assert.That(cut.Markup, Does.Contain("Clear All")); + Assert.That(cut.Markup, Does.Not.Contain("Select All")); + } + + [Test] + public void DeviceSelection_RecomputesButtonStateFromSelectedFilter() + { + DeviceFilter deviceFilter = CreateFullySelectedFilter(); + + IRenderedComponent cut = Render(parameters => parameters + .Add(p => p.DeviceFilter, deviceFilter) + .Add(p => p.SelectAll, true) + .Add(p => p.CollapseAll, false) + .Add(p => p.ShowTitle, false)); + + Assert.That(cut.Markup, Does.Contain("Clear All")); + Assert.That(cut.Markup, Does.Not.Contain("Select All")); + } + + private static DeviceFilter CreateFullySelectedFilter() + { + return new DeviceFilter + { + Managements = + [ + new ManagementSelect + { + Id = 1, + Name = "Management A", + Visible = true, + Selected = true, + Devices = + [ + new DeviceSelect { Id = 11, Name = "Device A1", Visible = true, Selected = true }, + new DeviceSelect { Id = 12, Name = "Device A2", Visible = true, Selected = true } + ] + }, + new ManagementSelect + { + Id = 2, + Name = "Management B", + Visible = true, + Selected = true, + Devices = + [ + new DeviceSelect { Id = 21, Name = "Device B1", Visible = true, Selected = true } + ] + } + ] + }; + } + } +} diff --git a/roles/tests-unit/files/FWO.Test/UiSettingsNotificationsTest.cs b/roles/tests-unit/files/FWO.Test/UiSettingsNotificationsTest.cs new file mode 100644 index 0000000000..711f8b2428 --- /dev/null +++ b/roles/tests-unit/files/FWO.Test/UiSettingsNotificationsTest.cs @@ -0,0 +1,290 @@ +using FWO.Config.Api; +using FWO.Config.Api.Data; +using FWO.Ui.Pages.Settings; +using NUnit.Framework; +using System.Collections; +using System.Linq; +using System.Reflection; +using System.Text.Json; + +namespace FWO.Test +{ + [TestFixture] + internal class UiSettingsNotificationsTest + { + private static MethodInfo GetPrivateMethod(string name) + { + return typeof(SettingsNotifications).GetMethod(name, BindingFlags.NonPublic | BindingFlags.Instance) + ?? throw new MissingMethodException(typeof(SettingsNotifications).FullName, name); + } + + private static MethodInfo GetPrivateStaticMethod(string name) + { + return typeof(SettingsNotifications).GetMethod(name, BindingFlags.NonPublic | BindingFlags.Static) + ?? throw new MissingMethodException(typeof(SettingsNotifications).FullName, name); + } + + private static void SetPrivateField(SettingsNotifications component, string fieldName, T value) + { + FieldInfo? field = typeof(SettingsNotifications).GetField(fieldName, BindingFlags.NonPublic | BindingFlags.Instance); + if (field == null) + { + throw new MissingFieldException(typeof(SettingsNotifications).FullName, fieldName); + } + field.SetValue(component, value); + } + + private static T GetPrivateField(SettingsNotifications component, string fieldName) + { + FieldInfo? field = typeof(SettingsNotifications).GetField(fieldName, BindingFlags.NonPublic | BindingFlags.Instance); + if (field == null) + { + throw new MissingFieldException(typeof(SettingsNotifications).FullName, fieldName); + } + return (T)field.GetValue(component)!; + } + + private static void SetInjectedGlobalConfig(SettingsNotifications component, GlobalConfig globalConfig) + { + PropertyInfo? prop = typeof(SettingsNotifications).GetProperties(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance) + .FirstOrDefault(p => p.PropertyType == typeof(GlobalConfig)); + if (prop == null) + { + throw new MissingMemberException(typeof(SettingsNotifications).FullName, "globalConfig"); + } + prop.SetValue(component, globalConfig); + } + + private static IList CreateInitiatorList() + { + Type? entryType = typeof(SettingsNotifications).GetNestedType("RuleExpiryInitiatorText", BindingFlags.NonPublic); + if (entryType == null) + { + throw new MissingMemberException(typeof(SettingsNotifications).FullName, "RuleExpiryInitiatorText"); + } + + Type listType = typeof(List<>).MakeGenericType(entryType); + return (IList)(Activator.CreateInstance(listType) ?? throw new InvalidOperationException("Could not create initiator list.")); + } + + private static object CreateInitiatorEntry(string key, string text) + { + Type? entryType = typeof(SettingsNotifications).GetNestedType("RuleExpiryInitiatorText", BindingFlags.NonPublic); + if (entryType == null) + { + throw new MissingMemberException(typeof(SettingsNotifications).FullName, "RuleExpiryInitiatorText"); + } + + object entry = Activator.CreateInstance(entryType) ?? throw new InvalidOperationException("Could not create initiator entry."); + entryType.GetProperty("Key")?.SetValue(entry, key); + entryType.GetProperty("Text")?.SetValue(entry, text); + return entry; + } + + private static Dictionary ToDictionary(IList entries) + { + Dictionary result = new(StringComparer.OrdinalIgnoreCase); + foreach (object entry in entries) + { + Type entryType = entry.GetType(); + string key = (string)(entryType.GetProperty("Key")?.GetValue(entry) ?? ""); + string text = (string)(entryType.GetProperty("Text")?.GetValue(entry) ?? ""); + result[key] = text; + } + return result; + } + + [Test] + public void ParseInitiatorKeys_ReturnsEntries_ForValidJson_AndEmptyForInvalid() + { + MethodInfo parseMethod = GetPrivateStaticMethod("ParseInitiatorKeys"); + + IList parsed = (IList)(parseMethod.Invoke(null, ["{\"user\":\"A\",\"nsb\":\"B\"}"]) ?? CreateInitiatorList()); + Dictionary parsedMap = ToDictionary(parsed); + Assert.That(parsedMap.Count, Is.EqualTo(2)); + Assert.That(parsedMap["user"], Is.EqualTo("A")); + Assert.That(parsedMap["nsb"], Is.EqualTo("B")); + + IList parsedInvalid = (IList)(parseMethod.Invoke(null, ["{invalid json}"]) ?? CreateInitiatorList()); + Assert.That(parsedInvalid.Count, Is.EqualTo(0)); + } + + [Test] + public async Task OnInitializedAsync_LoadsInitiatorKeys_FromGlobalConfig() + { + SettingsNotifications component = new(); + SimulatedGlobalConfig globalConfig = new() + { + RuleExpiryInitiatorKeys = "{\"user\":\"Ablauf user\",\"nsb\":\"Ablauf nsb\"}" + }; + SetInjectedGlobalConfig(component, globalConfig); + + Task initTask = (Task)GetPrivateMethod("OnInitializedAsync").Invoke(component, null)!; + await initTask; + + IList entries = GetPrivateField(component, "initiatorKeys"); + Dictionary map = ToDictionary(entries); + Assert.That(map.Count, Is.EqualTo(2)); + Assert.That(map["user"], Is.EqualTo("Ablauf user")); + Assert.That(map["nsb"], Is.EqualTo("Ablauf nsb")); + } + + [Test] + public async Task OnInitializedAsync_UsesExplicitDefaultOption_WhenNotificationLanguageIsUnset() + { + SettingsNotifications component = new(); + SimulatedGlobalConfig globalConfig = new() + { + DefaultLanguage = "German", + NotificationLanguage = "", + UiLanguages = + [ + new Language { Name = "German", CultureInfo = "de-DE" }, + new Language { Name = "English", CultureInfo = "en-US" } + ] + }; + SetInjectedGlobalConfig(component, globalConfig); + + Task initTask = (Task)GetPrivateMethod("OnInitializedAsync").Invoke(component, null)!; + await initTask; + + Language selected = GetPrivateField(component, "selectedNotificationLanguage"); + Assert.That(selected.Name, Is.EqualTo("")); + } + + [Test] + public async Task OnInitializedAsync_UsesConcreteSelection_WhenNotificationLanguageIsConfigured() + { + SettingsNotifications component = new(); + SimulatedGlobalConfig globalConfig = new() + { + DefaultLanguage = "German", + NotificationLanguage = "English", + UiLanguages = + [ + new Language { Name = "German", CultureInfo = "de-DE" }, + new Language { Name = "English", CultureInfo = "en-US" } + ] + }; + SetInjectedGlobalConfig(component, globalConfig); + + Task initTask = (Task)GetPrivateMethod("OnInitializedAsync").Invoke(component, null)!; + await initTask; + + Language selected = GetPrivateField(component, "selectedNotificationLanguage"); + Assert.That(selected.Name, Is.EqualTo("English")); + } + + [Test] + public async Task OnInitializedAsync_FlagsUnknownStoredNotificationLanguage() + { + SettingsNotifications component = new(); + SimulatedGlobalConfig globalConfig = new() + { + DefaultLanguage = "German", + NotificationLanguage = "French", + UiLanguages = + [ + new Language { Name = "German", CultureInfo = "de-DE" }, + new Language { Name = "English", CultureInfo = "en-US" } + ] + }; + SetInjectedGlobalConfig(component, globalConfig); + + Task initTask = (Task)GetPrivateMethod("OnInitializedAsync").Invoke(component, null)!; + await initTask; + + Language selected = GetPrivateField(component, "selectedNotificationLanguage"); + bool hasUnknownSelection = GetPrivateField(component, "hasUnknownNotificationLanguageSelection"); + Assert.That(selected.Name, Is.EqualTo("")); + Assert.That(hasUnknownSelection, Is.True); + } + + [Test] + public void AddInitiatorKey_AddsTrimmedValue_AndSkipsCaseInsensitiveDuplicates() + { + SettingsNotifications component = new(); + IList initiatorKeys = CreateInitiatorList(); + IList initiatorKeysToAdd = CreateInitiatorList(); + object existing = CreateInitiatorEntry("User", "Existing"); + initiatorKeys.Add(existing); + + SetPrivateField(component, "initiatorKeys", initiatorKeys); + SetPrivateField(component, "initiatorKeysToAdd", initiatorKeysToAdd); + + SetPrivateField(component, "actInitiatorKey", CreateInitiatorEntry(" user ", "Duplicate")); + GetPrivateMethod("AddInitiatorKey").Invoke(component, null); + Assert.That(initiatorKeysToAdd.Count, Is.EqualTo(0), "Duplicate key should not be added."); + + SetPrivateField(component, "actInitiatorKey", CreateInitiatorEntry(" nsb ", " Added text ")); + GetPrivateMethod("AddInitiatorKey").Invoke(component, null); + Assert.That(initiatorKeysToAdd.Count, Is.EqualTo(1)); + + Dictionary addedMap = ToDictionary(initiatorKeysToAdd); + Assert.That(addedMap.ContainsKey("nsb"), Is.True); + Assert.That(addedMap["nsb"], Is.EqualTo("Added text")); + } + + [Test] + public void PrepareConfigData_AppliesAddsAndDeletes_AndSerializesDictionary() + { + SettingsNotifications component = new(); + ConfigData configData = new(); + + IList initiatorKeys = CreateInitiatorList(); + object entryUser = CreateInitiatorEntry("user", "by user"); + object entryNsb = CreateInitiatorEntry("nsb", "by nsb"); + initiatorKeys.Add(entryUser); + initiatorKeys.Add(entryNsb); + + IList initiatorKeysToDelete = CreateInitiatorList(); + initiatorKeysToDelete.Add(entryUser); + + IList initiatorKeysToAdd = CreateInitiatorList(); + initiatorKeysToAdd.Add(CreateInitiatorEntry("app", "from app")); + + SetPrivateField(component, "configData", configData); + SetPrivateField(component, "initiatorKeys", initiatorKeys); + SetPrivateField(component, "initiatorKeysToDelete", initiatorKeysToDelete); + SetPrivateField(component, "initiatorKeysToAdd", initiatorKeysToAdd); + + GetPrivateMethod("PrepareConfigData").Invoke(component, null); + + Dictionary? serializedMap = JsonSerializer.Deserialize>(configData.RuleExpiryInitiatorKeys); + Assert.That(serializedMap, Is.Not.Null); + Assert.That(serializedMap!.ContainsKey("user"), Is.False); + Assert.That(serializedMap["nsb"], Is.EqualTo("by nsb")); + Assert.That(serializedMap["app"], Is.EqualTo("from app")); + } + + [Test] + public void PrepareConfigData_PreservesUnknownStoredNotificationLanguage() + { + SettingsNotifications component = new(); + ConfigData configData = new() + { + NotificationLanguage = "French" + }; + SimulatedGlobalConfig globalConfig = new() + { + UiLanguages = + [ + new Language { Name = "German", CultureInfo = "de-DE" }, + new Language { Name = "English", CultureInfo = "en-US" } + ] + }; + + SetInjectedGlobalConfig(component, globalConfig); + SetPrivateField(component, "configData", configData); + SetPrivateField(component, "selectedNotificationLanguage", new Language()); + SetPrivateField(component, "hasUnknownNotificationLanguageSelection", true); + SetPrivateField(component, "initiatorKeys", CreateInitiatorList()); + SetPrivateField(component, "initiatorKeysToDelete", CreateInitiatorList()); + SetPrivateField(component, "initiatorKeysToAdd", CreateInitiatorList()); + + GetPrivateMethod("PrepareConfigData").Invoke(component, null); + + Assert.That(configData.NotificationLanguage, Is.EqualTo("French")); + } + } +} diff --git a/roles/tests-unit/files/FWO.Test/UiSettingsOwnerTest.cs b/roles/tests-unit/files/FWO.Test/UiSettingsOwnerTest.cs new file mode 100644 index 0000000000..ee65d79aea --- /dev/null +++ b/roles/tests-unit/files/FWO.Test/UiSettingsOwnerTest.cs @@ -0,0 +1,210 @@ +using FWO.Basics; +using FWO.Data; +using FWO.Ui.Pages.Settings; +using NUnit.Framework; +using System.Reflection; + +namespace FWO.Test +{ + [TestFixture] + internal class UiSettingsOwnerTest + { + private static MethodInfo GetPrivateMethod(string name) + { + return typeof(SettingsOwner).GetMethod(name, BindingFlags.NonPublic | BindingFlags.Instance) + ?? throw new MissingMethodException(typeof(SettingsOwner).FullName, name); + } + + private static MethodInfo GetPrivateStaticMethod(string name) + { + return typeof(SettingsOwner).GetMethod(name, BindingFlags.NonPublic | BindingFlags.Static) + ?? throw new MissingMethodException(typeof(SettingsOwner).FullName, name); + } + + private static void SetPrivateField(SettingsOwner component, string fieldName, T value) + { + FieldInfo? field = typeof(SettingsOwner).GetField(fieldName, BindingFlags.NonPublic | BindingFlags.Instance); + if (field == null) + { + throw new MissingFieldException(typeof(SettingsOwner).FullName, fieldName); + } + field.SetValue(component, value); + } + + private static T GetPrivateField(SettingsOwner component, string fieldName) + { + FieldInfo? field = typeof(SettingsOwner).GetField(fieldName, BindingFlags.NonPublic | BindingFlags.Instance); + if (field == null) + { + throw new MissingFieldException(typeof(SettingsOwner).FullName, fieldName); + } + return (T)field.GetValue(component)!; + } + + private static void SetInjectedUserConfig(SettingsOwner component, EditOwnerTestUserConfig userConfig) + { + PropertyInfo? prop = typeof(SettingsOwner).GetProperties(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance) + .FirstOrDefault(p => p.PropertyType == typeof(FWO.Config.Api.UserConfig) + && (p.Name.Equals("userConfig", StringComparison.OrdinalIgnoreCase) + || p.Name.Equals("UserConfig", StringComparison.OrdinalIgnoreCase))); + if (prop != null) + { + prop.SetValue(component, userConfig); + return; + } + + FieldInfo? field = typeof(SettingsOwner).GetFields(BindingFlags.NonPublic | BindingFlags.Instance) + .FirstOrDefault(f => f.FieldType == typeof(FWO.Config.Api.UserConfig)); + if (field != null) + { + field.SetValue(component, userConfig); + return; + } + + throw new MissingFieldException(typeof(SettingsOwner).FullName, "userConfig/UserConfig"); + } + + [Test] + public void AnalyseSampleOwners_ShowsCleanup_WhenDemoOwnersExist() + { + SettingsOwner component = new(); + SetPrivateField(component, "Owners", new List + { + new() { Id = 1, Name = $"App{GlobalConst.k_demo}" }, + new() { Id = 2, Name = "RegularApp" } + }); + + GetPrivateMethod("AnalyseSampleOwners").Invoke(component, null); + + Assert.That(GetPrivateField(component, "ShowCleanupButton"), Is.True); + Assert.That(GetPrivateField>(component, "SampleOwners"), Has.Count.EqualTo(1)); + } + + [Test] + public void AnalyseSampleOwners_HidesCleanup_WhenNoDemoOwnersExist() + { + SettingsOwner component = new(); + SetPrivateField(component, "Owners", new List + { + new() { Id = 1, Name = "RegularApp1" }, + new() { Id = 2, Name = "RegularApp2" } + }); + + GetPrivateMethod("AnalyseSampleOwners").Invoke(component, null); + + Assert.That(GetPrivateField(component, "ShowCleanupButton"), Is.False); + Assert.That(GetPrivateField>(component, "SampleOwners"), Is.Empty); + } + + [Test] + public void OpenOwnerMapping_SetsOwnerMappingMode() + { + SettingsOwner component = new(); + + GetPrivateMethod("OpenOwnerMapping").Invoke(component, null); + + Assert.That(GetPrivateField(component, "OwnerMappingMode"), Is.True); + } + + [Test] + public void RequestDeleteOwner_SetsCurrentOwnerAndDeleteMode() + { + SettingsOwner component = new(); + FwoOwner owner = new() { Id = 77, Name = "OwnerX" }; + + GetPrivateMethod("RequestDeleteOwner").Invoke(component, [owner]); + + Assert.That(GetPrivateField(component, "DeleteOwnerMode"), Is.True); + Assert.That(GetPrivateField(component, "ActOwner").Id, Is.EqualTo(77)); + } + + [Test] + public async Task HandleOwnerSaved_ResetsEditFlags_AndReanalysesSamples() + { + SettingsOwner component = new(); + SetPrivateField(component, "Owners", new List + { + new() { Id = 1, Name = $"Demo{GlobalConst.k_demo}" } + }); + SetPrivateField(component, "EditOwnerMode", true); + SetPrivateField(component, "Readonly", true); + + Task task = (Task)GetPrivateMethod("HandleOwnerSaved").Invoke(component, null)!; + await task; + + Assert.That(GetPrivateField(component, "EditOwnerMode"), Is.False); + Assert.That(GetPrivateField(component, "Readonly"), Is.False); + Assert.That(GetPrivateField(component, "ShowCleanupButton"), Is.True); + } + + [Test] + public async Task CancelOwnerEdit_ResetsEditFlags() + { + SettingsOwner component = new(); + SetPrivateField(component, "EditOwnerMode", true); + SetPrivateField(component, "Readonly", true); + + Task task = (Task)GetPrivateMethod("CancelOwnerEdit").Invoke(component, null)!; + await task; + + Assert.That(GetPrivateField(component, "EditOwnerMode"), Is.False); + Assert.That(GetPrivateField(component, "Readonly"), Is.False); + } + + [Test] + public void RequestRemoveSampleData_EnablesCleanupModeAndMessage() + { + SettingsOwner component = new(); + SetInjectedUserConfig(component, new EditOwnerTestUserConfig()); + + GetPrivateMethod("RequestRemoveSampleData").Invoke(component, null); + + Assert.That(GetPrivateField(component, "CleanupMode"), Is.True); + Assert.That(GetPrivateField(component, "CleanupMessage"), Is.EqualTo("U5218")); + } + + [Test] + public void FormatOwnerResponsibles_FormatsAndJoinsValues() + { + string dnUser = "CN=Max Mustermann,OU=Users,DC=example,DC=com"; + string dnGroup = "CN=NetOps,OU=Groups,DC=example,DC=com"; + string dnRaw = "invalid-dn"; + + string formatted = (string)GetPrivateStaticMethod("FormatOwnerResponsibles").Invoke(null, [new List { dnUser, dnGroup, dnRaw }])!; + + Assert.That(formatted, Does.Contain("Max Mustermann")); + Assert.That(formatted, Does.Contain("NetOps")); + Assert.That(formatted, Does.Contain("invalid-dn")); + Assert.That(formatted, Does.Contain(",")); + } + + [Test] + public void FormatOwnerResponsibles_ShowsFullNameWhenCnContainsEscapedComma() + { + string dnUser = @"CN=Mustermann\, Max,OU=Users,DC=example,DC=com"; + + string formatted = (string)GetPrivateStaticMethod("FormatOwnerResponsibles").Invoke(null, [new List { dnUser }])!; + + Assert.That(formatted, Is.EqualTo("Mustermann, Max")); + } + + [Test] + public void OrderActiveResponsibleTypes_FiltersInactiveAndSorts() + { + List input = + [ + new() { Id = 10, Name = "Zulu", SortOrder = 2, Active = true }, + new() { Id = 20, Name = "Alpha", SortOrder = 2, Active = true }, + new() { Id = 30, Name = "Inactive", SortOrder = 1, Active = false }, + new() { Id = 40, Name = "Beta", SortOrder = 1, Active = true } + ]; + + SettingsOwner component = new(); + List result = (List)GetPrivateMethod("OrderActiveResponsibleTypes") + .Invoke(component, [input])!; + + Assert.That(result.Select(type => type.Id).ToList(), Is.EqualTo(new List { 40, 20, 10 })); + Assert.That(result.All(type => type.Active), Is.True); + } + } +} diff --git a/roles/tests-unit/files/FWO.Test/UiSettingsResponsiblesTest.cs b/roles/tests-unit/files/FWO.Test/UiSettingsResponsiblesTest.cs new file mode 100644 index 0000000000..35512ac202 --- /dev/null +++ b/roles/tests-unit/files/FWO.Test/UiSettingsResponsiblesTest.cs @@ -0,0 +1,251 @@ +using FWO.Api.Client; +using FWO.Api.Client.Queries; +using FWO.Config.Api; +using FWO.Data; +using FWO.Ui.Pages.Settings; +using NUnit.Framework; +using System; +using System.Reflection; +using System.Linq; + +namespace FWO.Test +{ + [TestFixture] + internal class UiSettingsResponsiblesTest + { + private static MethodInfo GetPrivateMethod(string name) + { + return typeof(SettingsResponsibles).GetMethod(name, BindingFlags.NonPublic | BindingFlags.Instance) + ?? throw new MissingMethodException(typeof(SettingsResponsibles).FullName, name); + } + + private static void SetPrivateField(SettingsResponsibles component, string fieldName, T value) + { + FieldInfo? field = typeof(SettingsResponsibles).GetField(fieldName, BindingFlags.NonPublic | BindingFlags.Instance); + if (field == null) + { + throw new MissingFieldException(typeof(SettingsResponsibles).FullName, fieldName); + } + field.SetValue(component, value); + } + + private static T GetPrivateField(SettingsResponsibles component, string fieldName) + { + FieldInfo? field = typeof(SettingsResponsibles).GetField(fieldName, BindingFlags.NonPublic | BindingFlags.Instance); + if (field == null) + { + throw new MissingFieldException(typeof(SettingsResponsibles).FullName, fieldName); + } + return (T)field.GetValue(component)!; + } + + private static void SetInjectedUserConfig(SettingsResponsibles component, UserConfig userConfig) + { + PropertyInfo? prop = typeof(SettingsResponsibles).GetProperties(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance) + .FirstOrDefault(p => p.PropertyType == typeof(UserConfig)); + if (prop == null) + { + throw new MissingMemberException(typeof(SettingsResponsibles).FullName, "userConfig"); + } + prop.SetValue(component, userConfig); + } + + private static void SetInjectedApiConnection(SettingsResponsibles component, ApiConnection apiConnection) + { + PropertyInfo? prop = typeof(SettingsResponsibles).GetProperties(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance) + .FirstOrDefault(p => p.PropertyType == typeof(ApiConnection)); + if (prop == null) + { + throw new MissingMemberException(typeof(SettingsResponsibles).FullName, "apiConnection"); + } + prop.SetValue(component, apiConnection); + } + + [Test] + public async Task RequestDeleteResponsibleType_UsesDeactivateMessage_WhenTypeIsInUseAndActive() + { + SettingsResponsibles component = new(); + SettingsResponsiblesTestApiConn apiConn = new(); + apiConn.ResponsibleTypes.Add(new OwnerResponsibleType { Id = 10, Name = "Main", Active = true, SortOrder = 10 }); + apiConn.InUseTypeIds.Add(10); + SetInjectedApiConnection(component, apiConn); + SetInjectedUserConfig(component, new EditOwnerTestUserConfig()); + + Task task = (Task)GetPrivateMethod("RequestDeleteResponsibleType").Invoke(component, [apiConn.ResponsibleTypes[0]])!; + await task; + + Assert.That(GetPrivateField(component, "DeleteTypeMode"), Is.True); + string message = GetPrivateField(component, "deleteTypeMessage"); + Assert.That(message, Does.Contain("Main")); + Assert.That(message.ToLowerInvariant(), Does.StartWith("deactivate")); + } + + [Test] + public async Task DeleteResponsibleType_Deactivates_WhenTypeIsInUse() + { + SettingsResponsibles component = new(); + SettingsResponsiblesTestApiConn apiConn = new(); + OwnerResponsibleType type = new() { Id = 11, Name = "Supporting", Active = true, SortOrder = 20 }; + apiConn.ResponsibleTypes.Add(type); + apiConn.InUseTypeIds.Add(11); + SetInjectedApiConnection(component, apiConn); + SetInjectedUserConfig(component, new EditOwnerTestUserConfig()); + SetPrivateField(component, "actType", new OwnerResponsibleType + { + Id = type.Id, + Name = type.Name, + Active = type.Active, + SortOrder = type.SortOrder, + AllowModelling = type.AllowModelling, + AllowRecertification = type.AllowRecertification + }); + SetPrivateField(component, "DeleteTypeMode", true); + + Task task = (Task)GetPrivateMethod("DeleteResponsibleType").Invoke(component, null)!; + await task; + + Assert.That(apiConn.UpdateCalls, Is.EqualTo(1)); + Assert.That(apiConn.DeleteCalls, Is.EqualTo(0)); + Assert.That(apiConn.ResponsibleTypes.First(t => t.Id == 11).Active, Is.False); + Assert.That(GetPrivateField(component, "DeleteTypeMode"), Is.False); + } + + [Test] + public async Task DeleteResponsibleType_Deletes_WhenTypeIsNotInUse() + { + SettingsResponsibles component = new(); + SettingsResponsiblesTestApiConn apiConn = new(); + OwnerResponsibleType type = new() { Id = 12, Name = "Escalation", Active = true, SortOrder = 30 }; + apiConn.ResponsibleTypes.Add(type); + SetInjectedApiConnection(component, apiConn); + SetInjectedUserConfig(component, new EditOwnerTestUserConfig()); + SetPrivateField(component, "actType", new OwnerResponsibleType + { + Id = type.Id, + Name = type.Name, + Active = type.Active, + SortOrder = type.SortOrder, + AllowModelling = type.AllowModelling, + AllowRecertification = type.AllowRecertification + }); + SetPrivateField(component, "DeleteTypeMode", true); + + Task task = (Task)GetPrivateMethod("DeleteResponsibleType").Invoke(component, null)!; + await task; + + Assert.That(apiConn.DeleteCalls, Is.EqualTo(1)); + Assert.That(apiConn.UpdateCalls, Is.EqualTo(0)); + Assert.That(apiConn.ResponsibleTypes.Any(t => t.Id == 12), Is.False); + Assert.That(GetPrivateField(component, "DeleteTypeMode"), Is.False); + } + + [Test] + public async Task ReactivateResponsibleType_UpdatesActiveFlag() + { + SettingsResponsibles component = new(); + SettingsResponsiblesTestApiConn apiConn = new(); + OwnerResponsibleType type = new() { Id = 13, Name = "Optional", Active = false, SortOrder = 40 }; + apiConn.ResponsibleTypes.Add(type); + SetInjectedApiConnection(component, apiConn); + SetInjectedUserConfig(component, new EditOwnerTestUserConfig()); + + Task task = (Task)GetPrivateMethod("ReactivateResponsibleType").Invoke(component, [type])!; + await task; + + Assert.That(apiConn.UpdateCalls, Is.EqualTo(1)); + Assert.That(apiConn.ResponsibleTypes.First(t => t.Id == 13).Active, Is.True); + } + } + + internal sealed class SettingsResponsiblesTestApiConn : SimulatedApiConnection + { + public List ResponsibleTypes { get; } = []; + public HashSet InUseTypeIds { get; } = []; + public int UpdateCalls { get; private set; } + public int DeleteCalls { get; private set; } + + public override Task SendQueryAsync(string query, object? variables = null, string? operationName = null) + { + if (query == OwnerQueries.getOwnersForResponsibleType) + { + int typeId = GetAnonymousInt(variables, "responsibleTypeId"); + List owners = InUseTypeIds.Contains(typeId) ? [new FwoOwner { Id = 1 }] : []; + return Task.FromResult((QueryResponseType)(object)owners); + } + + if (query == OwnerQueries.updateOwnerResponsibleType) + { + ++UpdateCalls; + int typeId = GetAnonymousInt(variables, "id"); + bool active = GetAnonymousBool(variables, "active"); + OwnerResponsibleType? type = ResponsibleTypes.FirstOrDefault(t => t.Id == typeId); + if (type != null) + { + type.Active = active; + type.Name = GetAnonymousString(variables, "name"); + type.SortOrder = GetAnonymousInt(variables, "sort_order"); + type.AllowModelling = GetAnonymousBool(variables, "allow_modelling"); + type.AllowRecertification = GetAnonymousBool(variables, "allow_recertification"); + } + return Task.FromResult((QueryResponseType)(object)new ReturnId { UpdatedId = typeId }); + } + + if (query == OwnerQueries.deleteOwnerResponsibleType) + { + ++DeleteCalls; + int typeId = GetAnonymousInt(variables, "id"); + ResponsibleTypes.RemoveAll(type => type.Id == typeId); + ReturnIdWrapper wrapper = new() + { + ReturnIds = [new ReturnId { DeletedId = typeId }] + }; + return Task.FromResult((QueryResponseType)(object)wrapper); + } + + if (query == OwnerQueries.getOwnerResponsibleTypes) + { + List copy = [.. ResponsibleTypes + .Select(type => new OwnerResponsibleType + { + Id = type.Id, + Name = type.Name, + Active = type.Active, + SortOrder = type.SortOrder, + AllowModelling = type.AllowModelling, + AllowRecertification = type.AllowRecertification + })]; + return Task.FromResult((QueryResponseType)(object)copy); + } + + throw new NotImplementedException($"Query not implemented in SettingsResponsibles test api: {query}"); + } + + private static int GetAnonymousInt(object? variables, string propertyName) + { + object? value = GetAnonymousValue(variables, propertyName); + return value is int intValue ? intValue : 0; + } + + private static bool GetAnonymousBool(object? variables, string propertyName) + { + object? value = GetAnonymousValue(variables, propertyName); + return value is bool boolValue && boolValue; + } + + private static string GetAnonymousString(object? variables, string propertyName) + { + object? value = GetAnonymousValue(variables, propertyName); + return value as string ?? ""; + } + + private static object? GetAnonymousValue(object? variables, string propertyName) + { + if (variables == null) + { + return null; + } + PropertyInfo? property = variables.GetType().GetProperty(propertyName, BindingFlags.Public | BindingFlags.Instance); + return property?.GetValue(variables); + } + } +} diff --git a/roles/tests-unit/files/FWO.Test/UiWorkflowCustomizingTest.cs b/roles/tests-unit/files/FWO.Test/UiWorkflowCustomizingTest.cs new file mode 100644 index 0000000000..3089d0bb9b --- /dev/null +++ b/roles/tests-unit/files/FWO.Test/UiWorkflowCustomizingTest.cs @@ -0,0 +1,92 @@ +using FWO.Api.Client; +using FWO.Api.Client.Queries; +using FWO.Config.Api; +using FWO.Config.Api.Data; +using FWO.Data; +using FWO.Data.Workflow; +using FWO.Ui.Pages.Settings; +using NUnit.Framework; +using System.Reflection; + +namespace FWO.Test +{ + [TestFixture] + internal class UiWorkflowCustomizingTest + { + private static MethodInfo GetPrivateMethod(Type type, string name) + { + return type.GetMethod(name, BindingFlags.NonPublic | BindingFlags.Instance) + ?? throw new MissingMethodException(type.FullName, name); + } + + private static void SetMember(object instance, string memberName, object? value) + { + Type type = instance.GetType(); + PropertyInfo? property = type.GetProperty(memberName, BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance); + if (property != null) + { + property.SetValue(instance, value); + return; + } + + FieldInfo? field = type.GetField(memberName, BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance); + if (field != null) + { + field.SetValue(instance, value); + return; + } + + throw new MissingFieldException(type.FullName, memberName); + } + + [Test] + public async Task HandleAllowedChangesByApproverChanged_PersistsConfigImmediately() + { + SettingsCustomizing component = new(); + WorkflowCustomizingApiConn apiConnection = new(); + SimulatedGlobalConfig globalConfig = new() + { + ReqAvailableTaskTypes = "[]" + }; + SimulatedUserConfig userConfig = new(); + ConfigData editableConfig = await globalConfig.GetEditableConfig(); + ApproverAllowedChangesConfig newConfig = new(); + newConfig.SetTicketField(WorkflowEditableFieldKeys.Reason, true); + + SetMember(component, "apiConnection", apiConnection); + SetMember(component, "globalConfig", globalConfig); + SetMember(component, "userConfig", userConfig); + SetMember(component, "configData", editableConfig); + + Task handlerTask = (Task)GetPrivateMethod(typeof(SettingsCustomizing), "HandleAllowedChangesByApproverChanged") + .Invoke(component, [newConfig.ToConfigValue()])!; + await handlerTask; + + Assert.That(apiConnection.UpsertConfigCallCount, Is.EqualTo(1)); + Assert.That(apiConnection.LastConfigItems, Has.Count.EqualTo(1)); + Assert.That(apiConnection.LastConfigItems[0].Key, Is.EqualTo("reqAllowedChangesByApprover")); + Assert.That(apiConnection.LastConfigItems[0].Value, Is.EqualTo(newConfig.ToConfigValue())); + Assert.That(editableConfig.ReqAllowedChangesByApprover, Is.EqualTo(newConfig.ToConfigValue())); + } + + private sealed class WorkflowCustomizingApiConn : SimulatedApiConnection + { + public int UpsertConfigCallCount { get; private set; } + public List LastConfigItems { get; private set; } = []; + + public override Task SendQueryAsync(string query, object? variables = null, string? operationName = null) + { + if (query == ConfigQueries.upsertConfigItems) + { + UpsertConfigCallCount++; + PropertyInfo configItemsProperty = variables?.GetType().GetProperty("config_items") + ?? throw new MissingFieldException("config_items"); + LastConfigItems = ((IEnumerable)configItemsProperty.GetValue(variables)!).ToList(); + return Task.FromResult((QueryResponseType)(object)new object()); + } + + throw new NotImplementedException(); + } + } + } +} diff --git a/roles/tests-unit/files/FWO.Test/UiZoneMatrixTest.cs b/roles/tests-unit/files/FWO.Test/UiZoneMatrixTest.cs new file mode 100644 index 0000000000..a8a22866f8 --- /dev/null +++ b/roles/tests-unit/files/FWO.Test/UiZoneMatrixTest.cs @@ -0,0 +1,231 @@ +using Bunit; +using Bunit.TestDoubles; +using FWO.Ui.Pages.Compliance; +using NUnit.Framework; +using Microsoft.Extensions.DependencyInjection; +using FWO.Config.Api; +using FWO.Services; +using FWO.Data; +using AngleSharp.Dom; + +namespace FWO.Test +{ + [FixtureLifeCycle(LifeCycle.InstancePerTestCase)] + public class UiZoneMatrixTest : BunitContext + { + private UserConfig _userConfig = new(); + private NetworkZoneService _networkZoneService = new(); + private List<(ComplianceNetworkZone, ComplianceNetworkZone)> _addCommunication = []; + private List<(ComplianceNetworkZone, ComplianceNetworkZone)> _deleteCommunication = []; + + Task> RenderZoneMatrix(bool editMode = true, bool sortById = true) + { + // Set up user config. + + SimulatedGlobalConfig globalConfig = new(); + globalConfig.ComplianceCheckSortMatrixByID = sortById; + _userConfig = new(globalConfig); + + // Set up NetworkZoneService. + + _networkZoneService = new(); + + _networkZoneService.NetworkZones.AddRange( + [ + new ComplianceNetworkZone + { + Id = 1, + IdString = "zone_one", + Name = "Zone 1" + }, + new ComplianceNetworkZone + { + Id = 2, + IdString = "zone_two", + Name = "Zone 2" + }, + new ComplianceNetworkZone + { + Id = 3, + IdString = "zone_three", + Name = "Zone 3" + }, + new ComplianceNetworkZone + { + Id = 4, + IdString = "AUTO_CALCULATED_ZONE_UNDEFINED_INTERNAL", + Name = "Auto-calculated Undefined-internal Zone", + IsAutoCalculatedUndefinedInternalZone = true + }, + new ComplianceNetworkZone + { + Id = 5, + IdString = "AUTO_CALCULATED_ZONE_INTERNET", + Name = "Auto-calculated Internet Zone", + IsAutoCalculatedInternetZone = true + } + ] + ); + + // Add injected Services to DI container. + + Services.AddScoped(_ => _userConfig); + Services.AddScoped(_ => _networkZoneService); + + // Reset _addCommunication and _deleteCommunication. + + _addCommunication = []; + _deleteCommunication = []; + + // Render component with parameters. + + var cut = Render(parameters => parameters + .Add(p => p.EditMode, editMode) + .Add(p => p.AddCommunication, _addCommunication) + .Add(p => p.DeleteCommunication, _deleteCommunication) + ); + + return Task.FromResult(cut); + } + + [Test] + public async Task ClickZoneElement_ZoneToUndefinedInternal_Unchanged() + { + // Arrange + + IRenderedComponent zoneMatrixComponent = await RenderZoneMatrix(); + IElement matrixElement = zoneMatrixComponent.Find("#matrix-element-zone_one-to-AUTO_CALCULATED_ZONE_UNDEFINED_INTERNAL"); + + // Act + + matrixElement.Click(); + + // Assert + + Assert.That(_addCommunication.Count == 0); + Assert.That(_deleteCommunication.Count == 0); + } + + [Test] + public async Task ClickZoneElement_UndefinedInternalToZoneOne_Unchanged() + { + // Arrange + + IRenderedComponent zoneMatrixComponent = await RenderZoneMatrix(); + IElement matrixElement = zoneMatrixComponent.Find("#matrix-element-AUTO_CALCULATED_ZONE_UNDEFINED_INTERNAL-to-zone_one"); + + // Act + + matrixElement.Click(); + + // Assert + + Assert.That(_addCommunication.Count == 0); + Assert.That(_deleteCommunication.Count == 0); + } + + [Test] + public async Task ClickZoneElement_UndefinedInternalToZone_Unchanged() + { + // Arrange + + IRenderedComponent zoneMatrixComponent = await RenderZoneMatrix(); + IElement matrixElement = zoneMatrixComponent.Find("#matrix-element-AUTO_CALCULATED_ZONE_UNDEFINED_INTERNAL-to-zone_one"); + + // Act + + matrixElement.Click(); + + // Assert + + Assert.That(_addCommunication.Count == 0); + Assert.That(_deleteCommunication.Count == 0); + } + + [Test] + public async Task ClickZoneElement_NotAllowed_CommunicationInAddCommunication() + { + // Arrange + + IRenderedComponent zoneMatrixComponent = await RenderZoneMatrix(); + IElement matrixElement = zoneMatrixComponent.Find("#matrix-element-zone_one-to-zone_two"); + + // Act + + matrixElement.Click(); + + // Assert + + Assert.That(_addCommunication.Count == 1); + Assert.That(_addCommunication.First().Item1.IdString == "zone_one"); + Assert.That(_addCommunication.First().Item2.IdString == "zone_two"); + Assert.That(_deleteCommunication.Count == 0); + } + + [Test] + public async Task ClickZoneElement_Allowed_CommunicationInDeleteCommunication() + { + // Arrange + + IRenderedComponent zoneMatrixComponent = await RenderZoneMatrix(); + _networkZoneService.NetworkZones.First().AllowedCommunicationDestinations = [_networkZoneService.NetworkZones.ElementAt(1)]; + IElement matrixElement = zoneMatrixComponent.Find("#matrix-element-zone_one-to-zone_two"); + + // Act + + matrixElement.Click(); + + // Assert + + Assert.That(_addCommunication.Count == 0); + Assert.That(_deleteCommunication.Count == 1); + Assert.That(_deleteCommunication.First().Item1.IdString == "zone_one"); + Assert.That(_deleteCommunication.First().Item2.IdString == "zone_two"); + } + + [Test] + public async Task ClickZoneElement_NotAllowedInEdit_CommunicationUnchanged() + { + // Arrange + + IRenderedComponent zoneMatrixComponent = await RenderZoneMatrix(); + _networkZoneService.NetworkZones.First().AllowedCommunicationDestinations = [_networkZoneService.NetworkZones.ElementAt(1)]; + _deleteCommunication.Add((_networkZoneService.NetworkZones.First(), _networkZoneService.NetworkZones.ElementAt(1))); + IElement matrixElement = zoneMatrixComponent.Find("#matrix-element-zone_one-to-zone_two"); + + // Act + + matrixElement.Click(); + + // Assert + + Assert.That(_addCommunication.Count == 0); + Assert.That(_deleteCommunication.Count == 0); + } + + [Test] + public async Task ClickZoneElement_AllowedInEdit_Unchanged() + { + // Arrange + + IRenderedComponent zoneMatrixComponent = await RenderZoneMatrix(); + _addCommunication.Add((_networkZoneService.NetworkZones.First(), _networkZoneService.NetworkZones.ElementAt(1))); + IElement matrixElement = zoneMatrixComponent.Find("#matrix-element-zone_one-to-zone_two"); + + // Act + + matrixElement.Click(); + + // Assert + + Assert.That(_addCommunication.Count == 0); + Assert.That(_deleteCommunication.Count == 0); + } + + + + + //$"matrix-element-{sourceZone.IdString.Replace(" ", "")}-to-{destinationZone.IdString.Replace(" ", "")}" + } + +} diff --git a/roles/tests-unit/files/FWO.Test/UpdateRuleOwnerMappingTests.cs b/roles/tests-unit/files/FWO.Test/UpdateRuleOwnerMappingTests.cs new file mode 100644 index 0000000000..97dff5c8d1 --- /dev/null +++ b/roles/tests-unit/files/FWO.Test/UpdateRuleOwnerMappingTests.cs @@ -0,0 +1,310 @@ +using FWO.Api.Client; +using FWO.Config.Api; +using FWO.Data; +using FWO.Services; +using Moq; +using NUnit.Framework; +using System; +using System.Collections.Generic; +using System.Net.Sockets; +using System.Text; + +namespace FWO.Test +{ + public class UpdateRuleOwnerMappingTests + { + private UpdateRuleOwnerMapping service = null!; + + [SetUp] + public void Setup() + { + var globalConfig = new GlobalConfig + { + CustomFieldOwnerKey = @"[""owner""]" + }; + + service = new UpdateRuleOwnerMapping(null!, globalConfig); + } + + [Test] + public void BuildNewRuleOwnersCustomField_ShouldCreateMapping_WhenOwnerExists() + { + var rule = BuildRule(); + var owners = new List { BuildOwner() }; + + var result = service.BuildNewRuleOwnersCustomField(new List { rule }, owners); + + Assert.Multiple(() => + { + Assert.That(result.Count, Is.EqualTo(1)); + Assert.That(result[0].OwnerId, Is.EqualTo(10)); + Assert.That(result[0].RuleId, Is.EqualTo(1)); + }); + } + + [TestCase("TeamB", 10, false)] + [TestCase("TeamA", 10, true)] + public void BuildNewRuleOwnersCustomField_ShouldReturnExpectedOwnerMatching(string ownerExtAppId, int expectedOwnerId, bool shouldMatch) + { + var rule = BuildRule(); + var owners = new List { BuildOwner(id: expectedOwnerId, extAppId: ownerExtAppId) }; + + var result = service.BuildNewRuleOwnersCustomField(new List { rule }, owners); + + Assert.That(result.Any(), Is.EqualTo(shouldMatch)); + if (shouldMatch) + { + Assert.That(result[0].OwnerId, Is.EqualTo(expectedOwnerId)); + } + } + + [Test] + public void BuildNewRuleOwnersCustomField_ShouldReturnEmpty_WhenKeyMissing() + { + var rule = new Rule + { + Id = 1, + CustomFields = "{'someOtherKey':'TeamA'}", + Metadata = new RuleMetadata { Id = 100 } + }; + var owners = new List { new FwoOwner { Id = 10, ExtAppId = "TeamA" } }; + + var result = service.BuildNewRuleOwnersCustomField(new List { rule }, owners); + + Assert.That(result, Is.Empty); + } + + [Test] + public void BuildNewRuleOwnersCustomField_ShouldReturnEmpty_WhenCustomFieldMissing() + { + var rule = BuildRule(customFields: "{}"); + var owners = new List { BuildOwner() }; + + var result = service.BuildNewRuleOwnersCustomField(new List { rule }, owners); + + Assert.That(result, Is.Empty); + } + + [Test] + public void DeserializeCustomFields_ShouldParseValidJson() + { + var json = "{'field-1': '20251119', 'field-2': 'CHG000816', 'field-3': '123'}"; + + var result = UpdateRuleOwnerMapping.DeserializeCustomFields(json); + + Assert.That(result["field-3"], Is.EqualTo("123")); + } + + [Test] + public void DeserializeCustomFields_ShouldReturnEmpty_WhenInvalidJson() + { + var json = "{invalid json}"; + + var result = UpdateRuleOwnerMapping.DeserializeCustomFields(json); + + Assert.That(result.Count, Is.EqualTo(0)); + } + + [Test] + public void DeserializeCustomFields_ShouldReturnEmpty_WhenNullOrWhitespace() + { + Assert.That(UpdateRuleOwnerMapping.DeserializeCustomFields(null), Is.Empty); + Assert.That(UpdateRuleOwnerMapping.DeserializeCustomFields(""), Is.Empty); + Assert.That(UpdateRuleOwnerMapping.DeserializeCustomFields(" "), Is.Empty); + } + + [Test] + public void IsOwnerSourceFieldChanged_ShouldReturnTrue_WhenValueChanges() + { + var oldRule = new Rule { CustomFields = "{'owner':'TeamA'}" }; + var newRule = new Rule { CustomFields = "{'owner':'TeamB'}" }; + var change = new RuleChange { OldRule = oldRule, NewRule = newRule }; + + bool result = service.IsOwnerSourceFieldChanged(change); + + Assert.That(result, Is.True); + } + + [Test] + public void IsOwnerSourceFieldChanged_ShouldReturnFalse_WhenValueUnchanged() + { + var oldRule = new Rule { CustomFields = "{'owner':'TeamA'}" }; + var newRule = new Rule { CustomFields = "{'owner':'TeamA'}" }; + var change = new RuleChange { OldRule = oldRule, NewRule = newRule }; + + bool result = service.IsOwnerSourceFieldChanged(change); + + Assert.That(result, Is.False); + } + + [Test] + public void GetIpRangeAndVersion_ShouldReturnValidRange() + { + var (range, version) = UpdateRuleOwnerMapping.GetIpRangeAndVersion( + "192.168.1.1", + "192.168.1.10" + ); + + Assert.Multiple(() => + { + Assert.That(range, Is.Not.Null); + Assert.That(version, Is.EqualTo(AddressFamily.InterNetwork)); + }); + } + + [Test] + public void GetMatchingOwnerIds_ShouldMatchOwner_WhenIpOverlaps() + { + var rule = BuildRule( + froms: new[] { BuildNetworkLocation("192.168.1.5", "192.168.1.5") } + ); + + var owners = new List + { + BuildOwner(ownerNetworks: new[] { BuildOwnerNetwork("192.168.1.0", "192.168.1.255") }) + }; + + var prepared = service.PrepareOwnerNetworks(owners); + var result = UpdateRuleOwnerMapping.GetMatchingOwnerIds(rule, prepared); + + Assert.That(result.ContainsKey(10)); + } + + [Test] + public void GetMatchingOwnerIds_ShouldReturnEmpty_WhenNoFromsTos() + { + var rule = new Rule { Id = 1, Froms = Array.Empty(), Tos = Array.Empty() }; + var ownerNetworks = new List(); + + var result = UpdateRuleOwnerMapping.GetMatchingOwnerIds(rule, ownerNetworks); + + Assert.That(result, Is.Empty); + } + + [Test] + public void BuildNewRuleOwnersIpBased_ShouldMapMultipleOwners_WhenMultipleRangesOverlap() + { + var rule = new Rule + { + Id = 1, + Froms = new[] + { + new NetworkLocation(new NetworkUser(), new NetworkObject { IP = "192.168.1.5", IpEnd = "192.168.1.5" }) + } + }; + + var owners = new List + { + new FwoOwner + { + Id = 10, + OwnerNetworks = new[] + { + new OwnerNetwork { IP = "192.168.1.0", IpEnd = "192.168.1.10" } + } + }, + new FwoOwner + { + Id = 20, + OwnerNetworks = new[] + { + new OwnerNetwork { IP = "192.168.1.0", IpEnd = "192.168.1.255" } + } + } + }; + + var result = service.BuildNewRuleOwnersIpBased(new List { rule }, owners); + + Assert.That(result.Select(r => r.OwnerId), Is.EquivalentTo(new[] { 10, 20 })); + } + + [Test] + public void PrepareOwnerNetworks_ShouldSkipInvalidOwnerNetworks() + { + var owners = new List + { + new FwoOwner + { + Id = 10, + OwnerNetworks = new[] + { + new OwnerNetwork { IP = "invalid", IpEnd = "192.168.1.255" }, + new OwnerNetwork { IP = "192.168.2.0", IpEnd = "192.168.2.255" } + } + } + }; + + var prepared = service.PrepareOwnerNetworks(owners); + + Assert.That(prepared.Count, Is.EqualTo(1)); + Assert.That(prepared[0].Ranges.Count, Is.EqualTo(1)); + } + + [Test] + public void GetIpRangeAndVersion_ShouldReturnNull_ForInvalidRange() + { + var (range, version) = UpdateRuleOwnerMapping.GetIpRangeAndVersion("invalid", "192.168.1.10"); + + Assert.That(range, Is.Null); + Assert.That(version, Is.Null); + + (range, version) = UpdateRuleOwnerMapping.GetIpRangeAndVersion("192.168.1.10", "192.168.1.1"); + + Assert.That(range, Is.Null); + Assert.That(version, Is.Null); + } + + [Test] + public void GetIpRangeAndVersion_ShouldHandleIPv6() + { + var (range, version) = UpdateRuleOwnerMapping.GetIpRangeAndVersion("2001:db8::1", "2001:db8::10"); + + Assert.That(range, Is.Not.Null); + Assert.That(version, Is.EqualTo(AddressFamily.InterNetworkV6)); + } + + #region Test Data Builders + private static Rule BuildRule( + int id = 1, + string customFields = "{'owner':'TeamA'}", + long metadataId = 100, + NetworkLocation[]? froms = null) + { + return new Rule + { + Id = id, + CustomFields = customFields, + Metadata = new RuleMetadata { Id = metadataId }, + Froms = froms ?? Array.Empty() + }; + } + + private static FwoOwner BuildOwner( + int id = 10, + string extAppId = "TeamA", + OwnerNetwork[]? ownerNetworks = null) + { + return new FwoOwner + { + Id = id, + ExtAppId = extAppId, + OwnerNetworks = ownerNetworks ?? Array.Empty() + }; + } + + private static NetworkLocation BuildNetworkLocation(string ipStart, string ipEnd) + { + return new NetworkLocation( + new NetworkUser { }, + new NetworkObject { IP = ipStart, IpEnd = ipEnd } + ); + } + + private static OwnerNetwork BuildOwnerNetwork(string ipStart, string ipEnd) + { + return new OwnerNetwork { IP = ipStart, IpEnd = ipEnd }; + } + + #endregion + } +} diff --git a/roles/tests-unit/files/FWO.Test/UrlSanitisationTest.cs b/roles/tests-unit/files/FWO.Test/UrlSanitisationTest.cs new file mode 100644 index 0000000000..43f0f9951b --- /dev/null +++ b/roles/tests-unit/files/FWO.Test/UrlSanitisationTest.cs @@ -0,0 +1,241 @@ +using NUnit.Framework; +using FWO.Ui.Services; +using Moq; +using Microsoft.AspNetCore.Mvc.Filters; +using Microsoft.AspNetCore.Http; +using Microsoft.AspNetCore.Mvc; +using Microsoft.AspNetCore.Mvc.Abstractions; +using System.Net; +using System.Text.RegularExpressions; + +namespace FWO.Test +{ + [TestFixture] + public partial class UrlSanitizerTests + { + public required UrlSanitizer _sut; + private static readonly string[] actual = new[] { "http", "https" }; + + [SetUp] + public void SetUp() + { + _sut = new UrlSanitizer(); + } + + [TestCase("https://example.com", "https://example.com/")] + [TestCase("http://example.com", "http://example.com/")] + [TestCase("https://example.com/path", "https://example.com/path")] + [TestCase("http://example.com/path?x=1", "http://example.com/path?x=1")] + public void Clean_AllowsHttpAndHttps_AndReturnsNormalizedUrl(string input, string expectedPrefix) + { + var result = _sut.Clean(input); + + Assert.That(result, Is.Not.Null); + Assert.That(result!.StartsWith(expectedPrefix), $"Expected URL to start with '{expectedPrefix}'"); + } + + [Test] + public void Clean_StripsFragment() + { + var input = "http://example.com/path#frag"; + var result = _sut.Clean(input); + + Assert.That(result, Is.Not.Null); + Assert.That(result!.Contains('#'), Is.False, "Fragment should be stripped."); + // Optionally double-check using Uri + var uri = new Uri(result); + + Assert.That(uri.Fragment, Is.EqualTo(string.Empty)); + } + + + // source for attack patterns: https://cheatsheetseries.owasp.org/cheatsheets/XSS_Filter_Evasion_Cheat_Sheet.html + // best way to test this: + // - start UI locally in debug mode + // - in browser call http://localhost:5000/help/ + attack string + + [TestCase("javascript:alert(1)")] + [TestCase("https://example.com/help/API/?lang=l%22%3E%3Cscript%3Ealert(%27XSS%27)%3C%2fscript%3Ea")] + [TestCase("/help/API/?lang=l%22%3E%3Cscript%3Ealert(%27XSS%27)%3C%2fscript%3Ea")] + [TestCase("help/API/?lang=l%22%3E%3Cscript%3Ealert(%27XSS%27)%3C%2fscript%3Ea")] + [TestCase("?lang=l%22%3E%3Cscript%3Ealert(%27XSS%27)%3C%2fscript%3Ea")] + [TestCase("help/API/?lang=")] + [TestCase("images/API/?lang=")] + [TestCase("js/API/?lang=")] + [TestCase("javascript:/*--> ")] + [TestCase("Click Me!")] + [TestCase("")] + [TestCase(" Click Me!")] + [TestCase("Click Me")] + [TestCase("Click Me")] + [TestCase(" Click Me")] + [TestCase(" Click Me")] + [TestCase("Click Me")] + [TestCase("Click Me")] + [TestCase("Click Me")] + [TestCase("")] + [TestCase("")] + [TestCase("")] + // [TestCase("<")] + // [TestCase("\"\>")] + + public void Clean_RejectsScripts(string input) + { + var result = _sut.Clean(input); + + // if Clean decides to return null to signal "reject/strip entirely" that's acceptable + if (result == null) return; + + // Normalize / decode + var normalized = WebUtility.HtmlDecode(result); + try { normalized = Uri.UnescapeDataString(normalized); } catch { /* ignore malformed escapes */ } + normalized = Regex.Replace(normalized, @"[\s\x00-\x1F]+", " "); // collapse whitespace and control chars + normalized = normalized.Trim(); + + // checks (case-insensitive) + Assert.That(normalized, Does.Not.Match("(?i)\\bjavascript\\s*:\\s*"), "javascript: scheme found"); + Assert.That(normalized, Does.Not.Match("(?i)\\bdata\\s*:\\s*"), "data: scheme found"); + Assert.That(normalized, Does.Not.Match("(?i)<\\s*script\\b"), " - - - - - + + + + + + + + + +@functions { + // Needed to prevent browser from caching files from previous versions + //string VersionedLink(string path) => $"{path}?v={globalConfig.ProductVersion}"; +} \ No newline at end of file diff --git a/roles/ui/files/FWO.UI/Pages/_Imports.razor b/roles/ui/files/FWO.UI/Pages/_Imports.razor index 71b261f5cf..3e0797c21b 100644 --- a/roles/ui/files/FWO.UI/Pages/_Imports.razor +++ b/roles/ui/files/FWO.UI/Pages/_Imports.razor @@ -1,4 +1,5 @@ @using BlazorTable @using FWO.Api.Client @using FWO.Api.Client.Queries -@using FWO.Api.Data \ No newline at end of file +@using FWO.Basics +@using FWO.Data \ No newline at end of file diff --git a/roles/ui/files/FWO.UI/Program.cs b/roles/ui/files/FWO.UI/Program.cs index 9be2d36c7c..8f59f8ae88 100644 --- a/roles/ui/files/FWO.UI/Program.cs +++ b/roles/ui/files/FWO.UI/Program.cs @@ -1,35 +1,143 @@ -using System; -using System.Collections.Generic; -using System.IO; -using System.Linq; -using System.Threading.Tasks; +using BlazorTable; +using FWO.Api.Client; +using FWO.Config.Api; +using FWO.Config.File; using FWO.Logging; -using Microsoft.AspNetCore; -using Microsoft.AspNetCore.Hosting; -using Microsoft.Extensions.Configuration; -using Microsoft.Extensions.Hosting; -using Microsoft.Extensions.Logging; +using FWO.Middleware.Client; +using FWO.Services; +using FWO.Services.EventMediator; +using FWO.Services.EventMediator.Interfaces; +using FWO.Services.RuleTreeBuilder; +using FWO.Ui.Auth; +using FWO.Ui.Services; +using Microsoft.AspNetCore.Components.Authorization; +using Microsoft.AspNetCore.Components.Server.Circuits; +using RestSharp; -namespace FWO.Ui + +// Implicitly call static constructor so background lock process is started +// (static constructor is only called after class is used in any way) +Log.WriteInfo("Startup", "Starting FWO UI Server..."); + +var builder = WebApplication.CreateBuilder(args); +builder.WebHost.UseWebRoot("wwwroot").UseStaticWebAssets(); + +// explicitly set the port to listen on +// this can be change for debugging purposes (to allow for a second instance of the UI to run) +builder.WebHost.ConfigureKestrel(serverOptions => +{ + serverOptions.ListenLocalhost(5000); // Listen on port 5000 +}); + +/// Add services to the container. +#region Services + +// CORS configuration (allows acccess from a client to an address which is not the own address - proxies etc.) +builder.Services.AddCors(options => { - public class Program + options.AddPolicy("AllowRemoteOrigins", builder => { - public static void Main(string[] args) - { - // Implicitly call static constructor so backround lock process is started - // (static constructor is only called after class is used in any way) - Log.WriteInfo("Startup", "Starting FWO UI Server..."); - CreateHostBuilder(args).Build().Run(); - } - - public static IHostBuilder CreateHostBuilder(string[] args) - { - return Host.CreateDefaultBuilder(args) - .ConfigureWebHostDefaults(webBuilder => - { - webBuilder.UseStaticWebAssets(); - webBuilder.UseStartup(); - }); - } - } + builder.WithOrigins(ConfigFile.RemoteAddresses); + }); +}); + +builder.Services.AddRazorPages(); +builder.Services.AddServerSideBlazor(); + +builder.Services.AddScoped(); +builder.Services.AddScoped(); +builder.Services.AddScoped(); +builder.Services.AddScoped(); +builder.Services.AddScoped(_ => new RuleTreeBuilder()); + +string ApiUri = ConfigFile.ApiServerUri; +string MiddlewareUri = ConfigFile.MiddlewareServerUri; +string ProductVersion = ConfigFile.ProductVersion; + +builder.Services.AddScoped(_ => new GraphQlApiConnection(ApiUri)); +builder.Services.AddScoped(_ => new MiddlewareClient(MiddlewareUri)); + +// Create "anonymous" (empty) jwt +MiddlewareClient middlewareClient = new MiddlewareClient(MiddlewareUri); +ApiConnection apiConn = new GraphQlApiConnection(ApiUri); + +RestResponse createJWTResponse = middlewareClient.CreateInitialJWT().Result; +bool connectionEstablished = createJWTResponse.IsSuccessful; +int connectionAttemptsCount = 1; +while (!connectionEstablished) +{ + Log.WriteError("Middleware Server Connection", + $"Error while authenticating as anonymous user from UI (Attempt {connectionAttemptsCount}), " + + $"Uri: {createJWTResponse.ResponseUri?.AbsoluteUri}, " + + $"HttpStatus: {createJWTResponse.StatusDescription}, " + + $"Error: {createJWTResponse.ErrorMessage}"); + Thread.Sleep(500 * connectionAttemptsCount++); + createJWTResponse = middlewareClient.CreateInitialJWT().Result; + connectionEstablished = createJWTResponse.IsSuccessful; } + +string jwt = createJWTResponse.Data ?? throw new NullReferenceException("Received empty jwt."); +apiConn.SetAuthHeader(jwt); + +// Get all non-confidential configuration settings and add to a global service (for all users) +GlobalConfig globalConfig = Task.Run(async () => await GlobalConfig.ConstructAsync(jwt, true, true)).Result; +builder.Services.AddSingleton(_ => globalConfig); +builder.Services.AddSingleton(); + +// the user's personal config +builder.Services.AddScoped(_ => new UserConfig(globalConfig)); + +builder.Services.AddScoped(_ => new NetworkZoneService()); +builder.Services.AddScoped(_ => new DomEventService()); + +builder.Services.AddBlazorTable(); + +#endregion + +var app = builder.Build(); + +// Make ServiceProvider accessible via static reference. + +FWO.Services.ServiceProvider.Services = app.Services; + +//// Configure the HTTP request pipeline. +#region HTTP Request Pipeline + +Log.WriteInfo("Environment", $"{app.Environment.ApplicationName} runs in {app.Environment.EnvironmentName} Mode."); + +if (app.Environment.IsDevelopment()) +{ + app.UseDeveloperExceptionPage(); +} +else +{ + app.UseExceptionHandler("/Error"); + // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts. + // app.UseHsts(); +} + +// app.UseHttpsRedirection(); +app.UseStaticFiles(); + +app.UseRouting(); + +app.UseWhen( + ctx => !ctx.Request.Path.StartsWithSegments("/_blazor") && + !ctx.Request.Path.StartsWithSegments("/_framework") && + !ctx.Request.Path.StartsWithSegments("/css") && + !ctx.Request.Path.StartsWithSegments("/js") && + !ctx.Request.Path.StartsWithSegments("/images"), + branch => + { + branch.UseMiddleware(); + }); + +app.UseAuthentication(); +app.UseAuthorization(); + +app.MapBlazorHub(); +app.MapFallbackToPage("/_Host"); + +#endregion + +app.Run(); diff --git a/roles/ui/files/FWO.UI/Properties/launchSettings.json b/roles/ui/files/FWO.UI/Properties/launchSettings.json index 6eb9105916..688f8495bf 100644 --- a/roles/ui/files/FWO.UI/Properties/launchSettings.json +++ b/roles/ui/files/FWO.UI/Properties/launchSettings.json @@ -5,7 +5,7 @@ "launchBrowser": true, "applicationUrl": "http://localhost:5000", "environmentVariables": { - "ASPNETCORE_ENVIRONMENT": "Developement" + "ASPNETCORE_ENVIRONMENT": "Development" } } } diff --git a/roles/ui/files/FWO.UI/Services/ActionFilter.cs b/roles/ui/files/FWO.UI/Services/ActionFilter.cs new file mode 100644 index 0000000000..2a0c3bd65a --- /dev/null +++ b/roles/ui/files/FWO.UI/Services/ActionFilter.cs @@ -0,0 +1,25 @@ +using Microsoft.AspNetCore.Mvc.Filters; + +namespace FWO.Ui.Services + +{ + public class SanitizeUrlFilter(IUrlSanitizer sanitizer) : IActionFilter + { + private readonly IUrlSanitizer _sanitizer = sanitizer; + + public void OnActionExecuted(ActionExecutedContext context) + { + throw new NotImplementedException(); + } + + public void OnActionExecuting(ActionExecutingContext context) + { + foreach (var arg in context.ActionArguments.ToList()) + { + if (arg.Value is string s && s.Contains("http", StringComparison.OrdinalIgnoreCase)) + context.ActionArguments[arg.Key] = _sanitizer.Clean(s); + } + } + + } +} diff --git a/roles/ui/files/FWO.UI/Services/ActionHandler.cs b/roles/ui/files/FWO.UI/Services/ActionHandler.cs deleted file mode 100644 index ad4cd3792d..0000000000 --- a/roles/ui/files/FWO.UI/Services/ActionHandler.cs +++ /dev/null @@ -1,167 +0,0 @@ -using FWO.Api.Data; -using FWO.Api.Client; -using FWO.Api.Client.Queries; -using FWO.Logging; - - -namespace FWO.Ui.Services -{ - public class ActionHandler - { - private List states = new List(); - private readonly ApiConnection apiConnection; - private RequestHandler requestHandler = new RequestHandler(); - - - public ActionHandler(ApiConnection apiConnection, RequestHandler requestHandler) - { - this.apiConnection = apiConnection; - this.requestHandler = requestHandler; - } - - public async Task Init() - { - states = new List(); - states = await apiConnection.SendQueryAsync>(FWO.Api.Client.Queries.RequestQueries.getStates); - } - - private List getRelevantActions(RequestStatefulObject statefulObject, RequestObjectScopes scope, bool toState=true) - { - List stateActions = new List(); - try - { - int searchedStateId = (toState ? statefulObject.StateId : statefulObject.ChangedFrom()); - foreach(var actionHlp in states.FirstOrDefault(x => x.Id == searchedStateId)?.Actions ?? throw new Exception("Unknown stateId:" + searchedStateId)) - { - if(actionHlp.Action.Scope == scope.ToString() - && (!(actionHlp.Action.Scope == RequestObjectScopes.RequestTask.ToString() || actionHlp.Action.Scope == RequestObjectScopes.ImplementationTask.ToString()) - || actionHlp.Action.TaskType == "" || actionHlp.Action.TaskType == ((RequestTaskBase)statefulObject).TaskType)) - { - stateActions.Add(actionHlp.Action); - } - } - } - catch(Exception exc) - { - // unknown stateId probably by misconfiguration - Log.WriteError("Get relevant actions", $"Exception thrown and ignored: ", exc); - } - return stateActions; - } - - public List GetOfferedActions(RequestStatefulObject statefulObject, RequestObjectScopes scope, WorkflowPhases phase) - { - List offeredActions = new List(); - List stateActions = getRelevantActions(statefulObject, scope); - foreach(var action in stateActions.Where(x => (x.Event == StateActionEvents.OfferButton.ToString()))) - { - if(action.Phase == "" || action.Phase == phase.ToString()) - { - offeredActions.Add(action); - } - } - return offeredActions; - } - - public async Task DoStateChangeActions(RequestStatefulObject statefulObject, RequestObjectScopes scope) - { - if (statefulObject.StateChanged()) - { - List stateActions = getRelevantActions(statefulObject, scope); - foreach(var action in stateActions.Where(x => (x.Event == StateActionEvents.OnSet.ToString()))) - { - if(action.Phase == "" || action.Phase == requestHandler.Phase.ToString()) - { - await performAction(action, statefulObject, scope); - } - } - List fromStateActions = getRelevantActions(statefulObject, scope, false); - foreach(var action in fromStateActions.Where(x => (x.Event == StateActionEvents.OnLeave.ToString()))) - { - if(action.Phase == "" || action.Phase == requestHandler.Phase.ToString()) - { - await performAction(action, statefulObject, scope); - } - } - statefulObject.ResetStateChanged(); - } - } - - public async Task performAction(RequestStateAction action, RequestStatefulObject statefulObject, RequestObjectScopes scope) - { - switch(action.ActionType) - { - case nameof(StateActionTypes.AutoPromote): - int? toState = (action.ExternalParams != "" ? Convert.ToInt32(action.ExternalParams) : null); - if(toState == null || states.FirstOrDefault(x => x.Id == toState) != null) - { - await requestHandler.AutoPromote(statefulObject, scope, toState); - } - break; - case nameof(StateActionTypes.AddApproval): - setScope(statefulObject, scope); - await requestHandler.AddApproval(action.ExternalParams); - break; - case nameof(StateActionTypes.SetAlert): - await setAlert(action.ExternalParams); - break; - case nameof(StateActionTypes.TrafficPathAnalysis): - setScope(statefulObject, scope); - await requestHandler.HandlePathAnalysisAction(action.ExternalParams); - break; - case nameof(StateActionTypes.ExternalCall): - await callExternal(action); - break; - default: - break; - } - } - - private void setScope(RequestStatefulObject statefulObject, RequestObjectScopes scope) - { - switch(scope) - { - case RequestObjectScopes.Ticket: - break; - case RequestObjectScopes.RequestTask: - requestHandler.SetReqTaskEnv((RequestReqTask)statefulObject); - break; - case RequestObjectScopes.ImplementationTask: - requestHandler.SetImplTaskEnv((RequestImplTask)statefulObject); - break; - case RequestObjectScopes.Approval: - break; - default: - break; - } - } - - public async Task callExternal(RequestStateAction action) - { - // call external APIs with ExternalParams, e.g. for Compliance Check - } - - public async Task setAlert(string? description) - { - try - { - var Variables = new - { - source = "workflow", - userId = 0, - title = "Workflow state alert", - description = description, - alertCode = (int)AlertCode.WorkflowAlert - }; - ReturnId[]? returnIds = (await apiConnection.SendQueryAsync(MonitorQueries.addAlert, Variables)).ReturnIds; - Log.WriteAlert ($"source: \"workflow\"", - $"userId: \"0\", title: \"Workflow state alert\", description: \"{description}\", " + - $"alertCode: \"{AlertCode.WorkflowAlert.ToString()}\""); - } - catch(Exception exc) - { - Log.WriteError("Write Alert", $"Could not write Alert for Workflow: ", exc); - } - } - } -} diff --git a/roles/ui/files/FWO.UI/Services/CircuitHandlerService.cs b/roles/ui/files/FWO.UI/Services/CircuitHandlerService.cs index 20cec92ce1..c13bd14c34 100644 --- a/roles/ui/files/FWO.UI/Services/CircuitHandlerService.cs +++ b/roles/ui/files/FWO.UI/Services/CircuitHandlerService.cs @@ -1,23 +1,33 @@ -using System.Collections.Generic; -using System.Threading; -using System.Threading.Tasks; using Microsoft.AspNetCore.Components.Server.Circuits; using FWO.Logging; -using FWO.Api.Data; +using FWO.Data; +using FWO.Services.EventMediator.Interfaces; +using FWO.Services.EventMediator.Events; namespace FWO.Ui.Services { - public class CircuitHandlerService : CircuitHandler + public class CircuitHandlerService(IEventMediator eventMediator) : CircuitHandler { public UiUser? User { get; set; } + private readonly UserSessionClosedEvent OnUserSessionClosed = new(); + public override Task OnCircuitClosedAsync(Circuit circuit, CancellationToken cancellationToken) { if (User != null) { Log.WriteAudit($"Session of \"{User.Name}\" closed", $"Session of user \"{User.Name}\" (last logged in) with DN: \"{User.Dn}\" was closed."); + + OnUserSessionClosed.EventArgs = new UserSessionClosedEventArgs + { + UserDn = User.Dn, + UserName = User.Name, + }; + + eventMediator.Publish(nameof(CircuitHandlerService), OnUserSessionClosed); } - return Task.CompletedTask; + + return base.OnCircuitClosedAsync(circuit, cancellationToken); } } } diff --git a/roles/ui/files/FWO.UI/Services/DefaultInit.cs b/roles/ui/files/FWO.UI/Services/DefaultInit.cs deleted file mode 100644 index 51099125e6..0000000000 --- a/roles/ui/files/FWO.UI/Services/DefaultInit.cs +++ /dev/null @@ -1,14 +0,0 @@ -using FWO.Api.Data; - -namespace FWO.Ui.Services -{ - public static class DefaultInit - { - public static void DoNothing(Exception? e, string t, string m, bool E) {} - public static async Task DoNothing() {} - public static async Task DoNothing(string s) {} - public static async Task DoNothing(RequestStatefulObject s) {} - public static async Task DoNothing(RequestReqTask r) {} - public static async Task DoNothing(RequestImplTask i) {} - } -} diff --git a/roles/ui/files/FWO.UI/Services/DisplayService.cs b/roles/ui/files/FWO.UI/Services/DisplayService.cs new file mode 100644 index 0000000000..4dda38c32e --- /dev/null +++ b/roles/ui/files/FWO.UI/Services/DisplayService.cs @@ -0,0 +1,28 @@ +using FWO.Config.Api; +using Microsoft.AspNetCore.Components; + + +namespace FWO.Ui.Services +{ + public static class DisplayService + { + public static MarkupString DisplayButton(UserConfig userConfig, string text, string icon, string iconText = "", string objIcon = "") + { + string tooltip = userConfig.ModIconify ? $"data-toggle=\"tooltip\" title=\"{@userConfig.PureLine(text)}\"" : ""; + string iconToDisplay = $""; + string iconTextPart = iconText != "" ? " " + userConfig.GetText(iconText) + "" : ""; + string objIconToDisplay = objIcon != "" ? $" " : ""; + return (MarkupString)(userConfig.ModIconify ? iconToDisplay + iconTextPart + objIconToDisplay : userConfig.GetText(text)); + } + + public static MarkupString DisplayButtonWithTooltip(UserConfig userConfig, string text, string icon, string tooltipText, string iconText = "", string objIcon = "") + { + string tooltip = $"data-toggle=\"tooltip\" title=\"{(userConfig.ModIconify ? @userConfig.PureLine(text) + " - " : "")} {tooltipText}\""; + string iconToDisplay = $""; + string iconTextPart = iconText != "" ? " " + userConfig.GetText(iconText) + "" : ""; + string objIconToDisplay = objIcon != "" ? $" " : ""; + string uniconified = $"{@userConfig.GetText(text)}"; + return (MarkupString)(userConfig.ModIconify ? iconToDisplay + iconTextPart + objIconToDisplay : uniconified); + } + } +} diff --git a/roles/ui/files/FWO.UI/Services/DomEventService.cs b/roles/ui/files/FWO.UI/Services/DomEventService.cs index a201be4db6..1c7242f8f7 100644 --- a/roles/ui/files/FWO.UI/Services/DomEventService.cs +++ b/roles/ui/files/FWO.UI/Services/DomEventService.cs @@ -1,42 +1,106 @@ -using Microsoft.JSInterop; +using FWO.Logging; +using Microsoft.JSInterop; namespace FWO.Ui.Services { - public class DomEventService - { - public event Action? OnGlobalScroll; - public event Action? OnGlobalClick; - public event Action? OnGlobalResize; - - public bool Initialized { get; private set; } = false; - - [JSInvokable] - public void InvokeOnGlobalScroll(string elementId) - { - OnGlobalScroll?.Invoke(elementId); - } - - [JSInvokable] - public void InvokeOnGlobalResize() - { - OnGlobalResize?.Invoke(); - } - - [JSInvokable] - public void InvokeOnGlobalClick(string elementId) - { - OnGlobalClick?.Invoke(elementId); - } - - public async Task Initialize(IJSRuntime runtime) - { - if (!Initialized) - { - await runtime.InvokeVoidAsync("globalScroll", DotNetObjectReference.Create(this)); - await runtime.InvokeVoidAsync("globalResize", DotNetObjectReference.Create(this)); - await runtime.InvokeVoidAsync("globalClick", DotNetObjectReference.Create(this)); - Initialized = true; - } - } - } + public class DomEventService : IAsyncDisposable + { + public delegate void OnDomEvent(string elementId); + + public event OnDomEvent? OnGlobalScroll; + public event OnDomEvent? OnGlobalClick; + public event OnDomEvent? OnGlobalFocus; + public event OnDomEvent? OnGlobalResize; + + private Action? _navbarHeightSubscribers; + private int? _lastNavbarHeight; + + public event Action? OnNavbarHeightChanged + { + add + { + _navbarHeightSubscribers += value; + // Fire immediately (once) if we already have a cached value + if (_lastNavbarHeight.HasValue) + { + value?.Invoke(_lastNavbarHeight.Value); + } + } + remove => _navbarHeightSubscribers -= value; + } + + private DotNetObjectReference? _dotNetRef; + private IJSRuntime? _runtime; + + public bool Initialized { get; private set; } + + public async Task Initialize(IJSRuntime runtime) + { + if (!Initialized) + { + try + { + _runtime = runtime; + _dotNetRef ??= DotNetObjectReference.Create(this); + await runtime.InvokeVoidAsync("initializeEventHandlers", _dotNetRef); + Initialized = true; + } + catch (Exception exception) + { + Log.WriteError("DomEventService", $"Initialization failure", exception); + } + } + } + + [JSInvokable] + public void InvokeOnGlobalScroll(string elementId) + { + OnGlobalScroll?.Invoke(elementId); + } + + [JSInvokable] + public void InvokeOnGlobalResize(string elementId) + { + OnGlobalResize?.Invoke(elementId); + } + + [JSInvokable] + public void InvokeOnGlobalClick(string elementId) + { + OnGlobalClick?.Invoke(elementId); + } + + [JSInvokable] + public void InvokeOnGlobalFocus(string elementId) + { + OnGlobalFocus?.Invoke(elementId); + } + + [JSInvokable] + public void InvokeNavbarHeightChanged(int height) + { + _lastNavbarHeight = height; + _navbarHeightSubscribers?.Invoke(height); + } + + protected virtual async ValueTask DisposeAsyncCore() + { + try + { + if (Initialized && _runtime is not null) + await _runtime.InvokeVoidAsync("disposeEventHandlers"); + } + catch { /* ignore */ } + + _dotNetRef?.Dispose(); + _dotNetRef = null; + Initialized = false; + } + + public async ValueTask DisposeAsync() + { + await DisposeAsyncCore().ConfigureAwait(false); + GC.SuppressFinalize(this); + } + } } diff --git a/roles/ui/files/FWO.UI/Services/FileUploadService.cs b/roles/ui/files/FWO.UI/Services/FileUploadService.cs new file mode 100644 index 0000000000..ec576481e4 --- /dev/null +++ b/roles/ui/files/FWO.UI/Services/FileUploadService.cs @@ -0,0 +1,279 @@ +using FWO.Api.Client; +using FWO.Api.Client.Queries; +using FWO.Basics; +using FWO.Config.Api; +using FWO.Data; +using FWO.Data.Middleware; +using FWO.Data.Modelling; +using FWO.Middleware.Client; +using FWO.Services; +using FWO.Services.EventMediator.Events; +using FWO.Services.EventMediator.Interfaces; +using FWO.Services.Modelling; +using Microsoft.AspNetCore.Components.Forms; +using RestSharp; +using System.Net; +using System.Text.Json; + +namespace FWO.Ui.Services +{ + public class FileUploadService + { + /// + /// Uploaded data as bytes. + /// + private byte[] UploadedData { get; set; } = []; + + private UserConfig UserConfig { get; set; } + private ApiConnection ApiConnection { get; set; } + private MiddlewareClient MiddlewareClient { get; set; } + + private readonly ModellingNamingConvention NamingConvention = new(); + private readonly List AppServerTypes = []; + private string ImportSource = ""; + private readonly string AllowedFileFormats; + + private readonly IEventMediator EventMediator; + private readonly FileUploadEvent CustomLogoUploadEvent; + private readonly FileUploadEvent FileUploadEvent; + private readonly AppServerImportEvent AppServerImportEvent; + private readonly FileUploadEvent ComplianceMatrixImportEvent; + + public FileUploadService(ApiConnection apiConnection, UserConfig userConfig, MiddlewareClient middlewareClient, string allowedFileFormats, IEventMediator eventMediator) + { + UserConfig = userConfig; + ApiConnection = apiConnection; + MiddlewareClient = middlewareClient; + NamingConvention = JsonSerializer.Deserialize(userConfig.ModNamingConvention) ?? new(); + AppServerTypes = JsonSerializer.Deserialize>(UserConfig.ModAppServerTypes) ?? []; + AllowedFileFormats = allowedFileFormats; + EventMediator = eventMediator; + CustomLogoUploadEvent = new(); + FileUploadEvent = new(); + AppServerImportEvent = new(); + ComplianceMatrixImportEvent = new(); + } + + public async Task ReadFileToBytes(InputFileChangeEventArgs args) + { + try + { + string fileExtension = Path.GetExtension(args.File.Name); + + if (!AllowedFileFormats.Contains(fileExtension)) + { + throw new ArgumentException(UserConfig.GetText("E5430")); + } + + if (args.File.Size > GlobalConst.MaxUploadFileSize) + { + throw new ArgumentException(UserConfig.GetText("E5431")); + } + + using MemoryStream ms = new(); + + await args.File.OpenReadStream(GlobalConst.MaxUploadFileSize).CopyToAsync(ms); + UploadedData = ms.ToArray(); + + FileUploadEvent.EventArgs!.Success = true; + } + catch (Exception ex) + { + FileUploadEvent.EventArgs!.Success = false; + + FileUploadEvent.EventArgs.Error = new() + { + Message = ex.Message, + InternalException = ex, + MessageType = MessageType.Error + }; + } + finally + { + EventMediator.Publish(nameof(ReadFileToBytes), FileUploadEvent); + } + + return FileUploadEvent.EventArgs; + } + + public FileUploadEventArgs ImportCustomLogo() + { + try + { + string base64Data = Convert.ToBase64String(UploadedData); + + CustomLogoUploadEvent.EventArgs!.Success = true; + CustomLogoUploadEvent.EventArgs.Data = base64Data; + } + catch (Exception ex) + { + CustomLogoUploadEvent.EventArgs!.Success = false; + + CustomLogoUploadEvent.EventArgs!.Error = new() + { + Message = UserConfig.GetText("file_upload_failed"), + InternalException = ex, + MessageType = MessageType.Error + }; + } + finally + { + EventMediator.Publish(nameof(ImportCustomLogo), CustomLogoUploadEvent); + } + + return CustomLogoUploadEvent.EventArgs; + } + + public async Task ImportAppServersFromCSV(string filename = "") + { + ImportSource = GlobalConst.kCSV_ + filename; + + List success = []; + List errors = []; + + string text = System.Text.Encoding.UTF8.GetString(UploadedData); + string[] lines = text.Split(Environment.NewLine, StringSplitOptions.RemoveEmptyEntries | StringSplitOptions.TrimEntries); + + foreach (string line in lines) + { + CSVFileUploadErrorModel? error = new() + { + EntryData = line, + MessageType = MessageType.Error, + }; + + if (!TryGetEntries(line, ';', out string[] entries) && !TryGetEntries(line, ',', out entries)) + { + error.Message = UserConfig.GetText("E5422"); + errors.Add(error); + + continue; + } + + if (IsHeader(entries)) + continue; + + string ipString = entries[3]; + + if (!ipString.TryParseIPString<(string, string)>(out (string Start, string End) ipRange, strictv4Parse: true)) + { + error.Message = UserConfig.GetText("E5423"); + errors.Add(error); + + continue; + } + + CSVAppServerImportModel importAppServer = new() + { + AppIPRangeStart = ipRange.Start, + AppIPRangeEnd = ipRange.End, + AppID = entries[1], + AppServerTyp = entries[2] + }; + + importAppServer.AppServerName = UserConfig.DnsLookup ? + await AppServerHelper.ConstructAppServerNameFromDns(importAppServer.ToModellingAppServer(), NamingConvention, UserConfig.OverwriteExistingNames) : + entries[0]; + + // write to db + (bool importSuccess, Exception? e) = await AddAppServerToDb(importAppServer); + + if (!importSuccess && e is not null) + { + error.Message = e.Message; + errors.Add(error); + } + else + { + success.Add(line); + } + } + + if (AppServerImportEvent.EventArgs is not null) + { + success = [.. success.Distinct()]; + + AppServerImportEvent.EventArgs.Success = success.Count > 0; + AppServerImportEvent.EventArgs.Appserver = success; + AppServerImportEvent.EventArgs.Errors = errors; + + EventMediator.Publish(nameof(ImportAppServersFromCSV), AppServerImportEvent); + } + } + + public async Task ImportComplianceMatrix(string filename = "") + { + string data = System.Text.Encoding.UTF8.GetString(UploadedData); + ComplianceImportMatrixParameters importParams = new() { FileName = filename, Data = data, UserName = UserConfig.User.Name, UserDn = UserConfig.User.Dn }; + RestResponse middlewareServerResponse = await MiddlewareClient.ImportCompianceMatrix(importParams); + if (ComplianceMatrixImportEvent.EventArgs is not null) + { + if (middlewareServerResponse.StatusCode != HttpStatusCode.OK) + { + ComplianceMatrixImportEvent.EventArgs.Success = false; + ComplianceMatrixImportEvent.EventArgs.Data = middlewareServerResponse.ErrorMessage; + } + else + { + ComplianceMatrixImportEvent.EventArgs.Success = middlewareServerResponse.Data?.StartsWith("Ok") ?? false; + ComplianceMatrixImportEvent.EventArgs.Data = middlewareServerResponse.Data; + } + EventMediator.Publish(nameof(ImportComplianceMatrix), ComplianceMatrixImportEvent); + } + } + + private static bool TryGetEntries(string line, char separator, out string[] entries) + { + if (line.StartsWith('\n')) + line = line[1..]; + + entries = line.Split(separator); + + if (entries.Length < 4) + return false; + + for (int i = 0; i < entries.Length; i++) + { + entries[i] = entries[i].Trim('"'); + } + + return true; + } + + private static bool IsHeader(string[] columns) + { + return columns.Length == 4 + && columns[0].Trim('"').Trim() == "App-Server-Name" + && columns[1].Trim('"').Trim() == "External-App-ID" + && columns[2].Trim('"').Trim() == "App-Server-Typ" + && columns[3].Trim('"').Trim() == "App-IP-Address-Range"; + } + + private async Task<(bool, Exception?)> AddAppServerToDb(CSVAppServerImportModel importAppServer) + { + try + { + AppServerType? appServerType = AppServerTypes.FirstOrDefault(_ => _.Name == importAppServer.AppServerTyp); + if (appServerType is null) + { + return new(false, new Exception($"{UserConfig.GetText("owner_appservertype_notfound")} At: {importAppServer.AppServerName}/{importAppServer.AppID}")); + } + + List ownerIds = await ApiConnection.SendQueryAsync>(OwnerQueries.getOwnerId, new { externalAppId = importAppServer.AppID }); + if (ownerIds is null || ownerIds.Count == 0) + { + return new(false, new Exception($"{UserConfig.GetText("owner_appserver_notfound")} At: {importAppServer.AppServerName}/{importAppServer.AppID}")); + } + + return ((await AppServerHelper.UpsertAppServer(ApiConnection, UserConfig, + new(importAppServer.ToModellingAppServer()) { ImportSource = ImportSource, AppId = ownerIds.First().Id, CustomType = appServerType.Id }, + !UserConfig.DnsLookup + )).Item1 != null, default); + } + catch (Exception exception) + { + return (false, exception); + } + } + } +} diff --git a/roles/ui/files/FWO.UI/Services/GroupAccess.cs b/roles/ui/files/FWO.UI/Services/GroupAccess.cs deleted file mode 100644 index d102859b8d..0000000000 --- a/roles/ui/files/FWO.UI/Services/GroupAccess.cs +++ /dev/null @@ -1,63 +0,0 @@ -using System.Net; -using FWO.Api.Data; -using FWO.Config.Api; -using FWO.Middleware.Client; -using FWO.Middleware.RequestParameters; -using RestSharp; - -namespace FWO.Ui.Services -{ - public class GroupAccess - { - static public async Task> GetGroupsFromInternalLdap(MiddlewareClient middlewareClient, UserConfig userConfig, - Action DisplayMessageInUi, bool ownerGroupsOnly = false) - { - List groups = new List(); - RestResponse> middlewareServerGroupsResponse = await middlewareClient.GetInternalGroups(); - if (middlewareServerGroupsResponse.StatusCode != HttpStatusCode.OK || middlewareServerGroupsResponse.Data == null) - { - DisplayMessageInUi(null, userConfig.GetText("fetch_groups"), userConfig.GetText("E5231"), true); - } - else - { - foreach (var ldapUserGroup in middlewareServerGroupsResponse.Data) - { - if(!ownerGroupsOnly || ldapUserGroup.OwnerGroup) - { - UserGroup group = new UserGroup() - { - Dn = ldapUserGroup.GroupDn, - Name = (new DistName(ldapUserGroup.GroupDn)).Group, - OwnerGroup = ldapUserGroup.OwnerGroup - }; - foreach (var userDn in ldapUserGroup.Members) - { - UiUser newUser = new UiUser() { Dn = userDn, Name = (new DistName(userDn)).UserName }; - group.Users.Add(newUser); - } - groups.Add(group); - } - } - } - return groups; - } - - static public async Task> GetGroupDnsFromInternalLdap(MiddlewareClient middlewareClient, UserConfig userConfig, Action DisplayMessageInUi) - { - List groupDns = new List(); - RestResponse> middlewareServerGroupsResponse = await middlewareClient.GetInternalGroups(); - if (middlewareServerGroupsResponse.StatusCode != HttpStatusCode.OK || middlewareServerGroupsResponse.Data == null) - { - DisplayMessageInUi(null, userConfig.GetText("fetch_groups"), userConfig.GetText("E5231"), true); - } - else - { - foreach (var ldapUserGroup in middlewareServerGroupsResponse.Data) - { - groupDns.Add(ldapUserGroup.GroupDn); - } - } - return groupDns; - } - } -} diff --git a/roles/ui/files/FWO.UI/Services/IUrlSanitizer.cs b/roles/ui/files/FWO.UI/Services/IUrlSanitizer.cs new file mode 100644 index 0000000000..133ddbaa4e --- /dev/null +++ b/roles/ui/files/FWO.UI/Services/IUrlSanitizer.cs @@ -0,0 +1,10 @@ + +namespace FWO.Ui.Services +{ + + public interface IUrlSanitizer + { + /// Returns a normalized http/https URL or null if invalid/unsafe. + string? Clean(string input); + } +} diff --git a/roles/ui/files/FWO.UI/Services/JwtEventService.cs b/roles/ui/files/FWO.UI/Services/JwtEventService.cs index fce4fd3226..6669c935f9 100644 --- a/roles/ui/files/FWO.UI/Services/JwtEventService.cs +++ b/roles/ui/files/FWO.UI/Services/JwtEventService.cs @@ -1,4 +1,4 @@ -using FWO.Api.Data; +using FWO.Basics; using FWO.Config.Api; namespace FWO.Ui.Services @@ -11,9 +11,9 @@ public static class JwtEventService public static event EventHandler? OnJwtExpired; - private static readonly Dictionary jwtAboutToExpireTimers = new Dictionary(); + private static readonly Dictionary jwtAboutToExpireTimers = new(); - private static readonly Dictionary jwtExpiredTimers = new Dictionary(); + private static readonly Dictionary jwtExpiredTimers = new(); public static void PermissionsChanged(string userDn) { @@ -33,16 +33,10 @@ public static void JwtExpired(string userDn) public static void AddJwtTimers(string userDn, int timeUntilyExpiry, int notificationTime) { // Dispose old timer (if existing) - if (jwtAboutToExpireTimers.ContainsKey(userDn)) - { - jwtAboutToExpireTimers[userDn].Dispose(); - } - if (jwtExpiredTimers.ContainsKey(userDn)) - { - jwtExpiredTimers[userDn].Dispose(); - } + RemoveJwtTimers(userDn); + // Create new timers - if (timeUntilyExpiry - notificationTime > 0) + if (notificationTime > 0 && timeUntilyExpiry - notificationTime > 0) { jwtAboutToExpireTimers[userDn] = new Timer(_ => JwtAboutToExpire(userDn), null, timeUntilyExpiry - notificationTime, int.MaxValue); } @@ -51,5 +45,20 @@ public static void AddJwtTimers(string userDn, int timeUntilyExpiry, int notific jwtExpiredTimers[userDn] = new Timer(_ => JwtExpired(userDn), null, timeUntilyExpiry, int.MaxValue); } } + + public static void RemoveJwtTimers(string userDn) + { + if (jwtAboutToExpireTimers.TryGetValue(userDn, out Timer? aboutToExpire)) + { + aboutToExpire.Dispose(); + jwtAboutToExpireTimers.Remove(userDn); + } + + if (jwtExpiredTimers.TryGetValue(userDn, out Timer? expired)) + { + expired.Dispose(); + jwtExpiredTimers.Remove(userDn); + } + } } } diff --git a/roles/ui/files/FWO.UI/Services/KeyboardInputService.cs b/roles/ui/files/FWO.UI/Services/KeyboardInputService.cs new file mode 100644 index 0000000000..282214baca --- /dev/null +++ b/roles/ui/files/FWO.UI/Services/KeyboardInputService.cs @@ -0,0 +1,11 @@ +using Microsoft.AspNetCore.Components.Web; +using FWO.Ui.Data; + +namespace FWO.Ui.Services +{ + public class KeyboardInputService + { + public bool ShiftPressed { get; set; } = false; + public bool ControlPressed { get; set; } = false; + } +} diff --git a/roles/ui/files/FWO.UI/Services/ModellingAppHandler.cs b/roles/ui/files/FWO.UI/Services/ModellingAppHandler.cs new file mode 100644 index 0000000000..4319fcb8d7 --- /dev/null +++ b/roles/ui/files/FWO.UI/Services/ModellingAppHandler.cs @@ -0,0 +1,329 @@ +using FWO.Config.Api; +using FWO.Data; +using FWO.Data.Modelling; +using FWO.Data.Workflow; +using FWO.Api.Client; +using FWO.Api.Client.Queries; +using FWO.Services.Modelling; +using FWO.Services.Workflow; + + +namespace FWO.Ui.Services +{ + public class ModellingAppHandler : ModellingHandlerBase + { + public ModellingConnectionHandler? ConnHandler { get; set; } + public ModellingConnectionHandler? OverviewConnHandler { get; set; } + public List Connections { get; set; } = []; + public ModellingConnection ConnToDelete { get; set; } = new(); + public bool AddConnMode { get; set; } = false; + public bool EditConnMode { get; set; } = false; + public bool DeleteConnMode { get; set; } = false; + public bool DecommissionInterfaceMode { get; set; } = false; + public bool ShowUsingConnectionsMode { get; set; } = false; + public string InterfaceName { get; set; } = ""; + + public Shared.TabSet Tabset { get; set; } = new(); + private Shared.Tab? ActTab; + public int ActWidth { get; set; } = 0; + public bool StartCollapsed { get; set; } = true; + private long dummyAppRoleId = 0; + + + public ModellingAppHandler(ApiConnection apiConnection, UserConfig userConfig, FwoOwner application, + Action displayMessageInUi, bool isOwner) + : base(apiConnection, userConfig, application, false, displayMessageInUi, false, isOwner) + { } + + public async Task Init(List? connections = null) + { + try + { + if (connections == null) + { + var queryParam = new + { + appId = Application.Id + }; + Connections = await apiConnection.SendQueryAsync>(ModellingQueries.getConnectionsResolved, queryParam); + } + else + { + Connections = connections; + } + + List dummyAppRoles = await apiConnection.SendQueryAsync>(ModellingQueries.getDummyAppRole); + if (dummyAppRoles.Count > 0) + { + dummyAppRoleId = dummyAppRoles[0].Id; + } + + await PrepareConnections(Connections); + + OverviewConnHandler = new ModellingConnectionHandler(apiConnection, userConfig, Application, Connections, new(), true, + false, DisplayMessageInUi, ReInit, IsOwner) + { + LastWidth = ActWidth, + LastCollapsed = StartCollapsed || ActWidth == 0 + }; + + await OverviewConnHandler.Init(); + } + catch (Exception exception) + { + DisplayMessageInUi(exception, userConfig.GetText("fetch_data"), "", true); + } + } + + private async Task PrepareConnections(List connections) + { + foreach (var conn in connections) + { + await ExtractUsedInterface(conn); + conn.SyncState(dummyAppRoleId, userConfig.ModRolloutRemovedAppServers); + } + + if (userConfig.VarianceAnalysisSync) + { + await AnalyseStatus(connections); + } + } + + public async Task AnalyseStatus(List connections) + { + ExtStateHandler extStateHandler = new(apiConnection); + ModellingVarianceAnalysis varianceAnalysis = new(apiConnection, extStateHandler, userConfig, Application, DisplayMessageInUi); + await varianceAnalysis.AnalyseConnsForStatus([.. connections.Where(x => !x.IsDocumentationOnly())]); + } + + public static async Task GetLatestFWRequestTicket(FwoOwner application, ApiConnection apiConnection) + { + List ticketIds = await apiConnection.SendQueryAsync>(ExtRequestQueries.getLatestTicketId, new { ownerId = application.Id }); + if (ticketIds.Count > 0) + { + return await apiConnection.SendQueryAsync(RequestQueries.getTicketById, new { ticketIds[0].Id }); + } + return null; + } + + public async Task ReInit() + { + await Init(); + } + + public void InitActiveTab(ModellingConnection? conn = null) + { + int tab = 0; + if (conn != null) + { + tab = GetTabFromConn(conn); + } + else if (GetRegularConnections().Count == 0) + { + if (GetInterfaces().Count > 0) + { + tab = 1; + } + else if (Application.CommSvcPossible && GetCommonServices().Count > 0) + { + tab = 2; + } + } + Tabset.SetActiveTab(tab); + } + + public void RestoreTab(ModellingConnection? conn = null) + { + if (conn != null) + { + Tabset.SetActiveTab(GetTabFromConn(conn)); + } + else if (Tabset.Tabs.Count > 0 && ActTab != null) + { + Shared.Tab? tab = Tabset.Tabs.FirstOrDefault(x => x.Position == ActTab.Position); + if (tab != null) + { + Tabset.SetActiveTab(tab); + } + } + } + + private static int GetTabFromConn(ModellingConnection conn) + { + if (conn.IsInterface) + { + return 1; + } + if (conn.IsCommonService) + { + return 2; + } + return 0; + } + + public List GetInterfaces(bool showRejected = false) + { + List tmpList = [.. Connections.Where(x => x.IsInterface && + (showRejected || !(x.GetBoolProperty(ConState.Rejected.ToString()) || x.GetBoolProperty(ConState.Decommissioned.ToString()))))]; + tmpList.Sort((a, b) => a.CompareTo(b)); + return tmpList; + } + + public List GetCommonServices() + { + return Connections.Where(x => !x.IsInterface && x.IsCommonService).ToList(); + } + + public List GetRegularConnections() + { + return Connections.Where(x => !x.IsInterface && !x.IsCommonService).ToList(); + } + + public List GetConnectionsToRequest() + { + return [.. Connections.Where(x => x.IsRelevantForVarianceAnalysis(dummyAppRoleId, + userConfig.ModRolloutRemovedAppServers, userConfig.ModRequestOnlyOwnObjects)) + .OrderByDescending(y => y.IsCommonService)]; + } + + public bool HasModellingIssues(ModellingConnection conn) + { + return !conn.IsRelevantForVarianceAnalysis(dummyAppRoleId); + } + + public async Task AddConnection() + { + if (!HasWriteAccess(userConfig.GetText("add_connection"))) + { + return; + } + ReadOnly = false; + AddConnMode = true; + await HandleConn(new ModellingConnection() { AppId = Application.Id }); + } + + public async Task AddInterface() + { + if (!HasWriteAccess(userConfig.GetText("add_interface"))) + { + return; + } + ReadOnly = false; + AddConnMode = true; + await HandleConn(new ModellingConnection() { AppId = Application.Id, IsInterface = true }); + } + + public async Task AddCommonService() + { + if (!HasWriteAccess(userConfig.GetText("add_common_service"))) + { + return; + } + ReadOnly = false; + AddConnMode = true; + await HandleConn(new ModellingConnection() { AppId = Application.Id, IsCommonService = true }); + } + + public async Task ShowDetails(ModellingConnection conn) + { + ReadOnly = true; + AddConnMode = false; + await HandleConn(conn); + } + + public async Task EditConn(ModellingConnection conn) + { + if (!IsOwner) + { + await ShowDetails(conn); + return; + } + ReadOnly = false; + AddConnMode = false; + await HandleConn(conn); + } + + public async Task HandleConn(ModellingConnection conn) + { + ActTab = Tabset.ActiveTab; + ConnHandler = new ModellingConnectionHandler(apiConnection, userConfig, Application, Connections, conn, AddConnMode, + ReadOnly, DisplayMessageInUi, ReInit, IsOwner); + await ConnHandler.Init(); + EditConnMode = true; + } + + public async Task ShowUsingConnections(ModellingConnection conn) + { + if (conn.IsInterface) + { + InterfaceName = conn.Name ?? ""; + await InitUsingConnections(conn.Id); + } + ShowUsingConnectionsMode = true; + } + + public async Task RequestDeleteConnection(ModellingConnection conn) + { + if (!HasWriteAccess(userConfig.GetText("delete_connection"))) + { + return; + } + ActTab = Tabset.ActiveTab; + ConnToDelete = conn; + if (ConnToDelete.IsInterface) + { + if (await InitUsingConnections(ConnToDelete.Id)) + { + Message = userConfig.GetText("E9013") + ConnToDelete.Name; + ConnHandler = new ModellingConnectionHandler(apiConnection, userConfig, Application, Connections, conn, AddConnMode, + ReadOnly, DisplayMessageInUi, ReInit, IsOwner); + await ConnHandler.Init(); + ConnHandler.UsingConnections = UsingConnections; + DecommissionInterfaceMode = true; + return; + } + Message = userConfig.GetText("U9014") + ConnToDelete.Name + "?"; + } + else + { + Message = userConfig.GetText("U9001") + ConnToDelete.Name + "?"; + } + DeleteAllowed = true; + DeleteConnMode = true; + } + + public async Task DeleteConnection() + { + if (!HasWriteAccess(userConfig.GetText("delete_connection"))) + { + return; + } + try + { + if (await DeleteConnection(ConnToDelete)) + { + await LogChange(ModellingTypes.ChangeType.Delete, ModellingTypes.ModObjectType.Connection, ConnToDelete.Id, + $"Deleted {(ConnToDelete.IsInterface ? "Interface" : "Connection")}: {ConnToDelete.Name}", Application.Id); + Connections.Remove(ConnToDelete); + DeleteConnMode = false; + RestoreTab(); + } + } + catch (Exception exception) + { + DisplayMessageInUi(exception, userConfig.GetText("delete_connection"), "", true); + } + } + + private bool HasWriteAccess(string action) + { + if (IsOwner) + { + return true; + } + + DisplayMessageInUi(null, action, userConfig.GetText("E9104"), true); + return false; + } + } +} diff --git a/roles/ui/files/FWO.UI/Services/NetworkZoneService.cs b/roles/ui/files/FWO.UI/Services/NetworkZoneService.cs deleted file mode 100644 index afe0941e1a..0000000000 --- a/roles/ui/files/FWO.UI/Services/NetworkZoneService.cs +++ /dev/null @@ -1,45 +0,0 @@ -using FWO.Api.Data; -using NetTools; - -namespace FWO.Ui.Services -{ - public class NetworkZoneService - { - public ComplianceNetworkZone[] NetworkZones { get; set; } = new ComplianceNetworkZone[0]; - - public delegate void ZoneAddEventArgs(); - public delegate void ZoneModificationEventArgs(ComplianceNetworkZone networkZone); - public event ZoneModificationEventArgs? OnEditZone; - public event ZoneModificationEventArgs? OnDeleteZone; - - public void InvokeOnEditZone(ComplianceNetworkZone networkZone) - { - OnEditZone?.Invoke(networkZone); - } - - public void InvokeOnDeleteZone(ComplianceNetworkZone networkZone) - { - OnDeleteZone?.Invoke(networkZone); - } - - /// - /// Display the IP address range in CIDR notation if possible and it is not a single IP address - /// otherwise display it in the format "first_ip-last_ip". - /// - /// - /// IP address range in CIDR / first-last notation - public static string DisplayIpRange(IPAddressRange ipAddressRange) - { - try - { - int prefixLength = ipAddressRange.GetPrefixLength(); - if (prefixLength != 32) - { - return ipAddressRange.ToCidrString(); - } - } - catch (FormatException) { } - return ipAddressRange.ToString(); - } - } -} diff --git a/roles/ui/files/FWO.UI/Services/NotificationMutationHelper.cs b/roles/ui/files/FWO.UI/Services/NotificationMutationHelper.cs new file mode 100644 index 0000000000..4d4f42e7cc --- /dev/null +++ b/roles/ui/files/FWO.UI/Services/NotificationMutationHelper.cs @@ -0,0 +1,234 @@ +using FWO.Api.Client; +using FWO.Api.Client.Queries; +using FWO.Data; + +namespace FWO.Ui.Services +{ + /// + /// Creates shared GraphQL mutation payloads and persists notifications for UI-side notification editing. + /// + public static class NotificationMutationHelper + { + /// + /// Persists a new notification and returns the saved copy with the assigned id. + /// + public static async Task AddAsync(ApiConnection apiConnection, NotificationClient client, FwoNotification notification) + { + object variables = BuildAddVariables(client, notification); + ReturnIdWrapper response = await apiConnection.SendQueryAsync(NotificationQueries.addNotification, variables); + return CreatePersistedNotification(client, notification, response.ReturnIds![0].NewId); + } + + /// + /// Persists changes to an existing notification and returns the updated copy. + /// + public static async Task UpdateAsync(ApiConnection apiConnection, NotificationClient client, FwoNotification notification) + { + object variables = BuildUpdateVariables(notification); + await apiConnection.SendQueryAsync(NotificationQueries.updateNotification, variables); + return CreatePersistedNotification(client, notification, notification.Id); + } + + /// + /// Deletes a persisted notification by id. + /// + public static Task DeleteAsync(ApiConnection apiConnection, int notificationId) + { + return apiConnection.SendQueryAsync(NotificationQueries.deleteNotification, new { id = notificationId }); + } + + /// + /// Builds GraphQL variables for inserting a notification. + /// + private static object BuildAddVariables(NotificationClient client, FwoNotification notification) + { + return AddNotificationMutationVariables.FromNotification(client, notification); + } + + /// + /// Builds GraphQL variables for updating a notification. + /// + private static object BuildUpdateVariables(FwoNotification notification) + { + return UpdateNotificationMutationVariables.FromNotification(notification); + } + + /// + /// Creates a persisted notification copy with the assigned database id. + /// + private static FwoNotification CreatePersistedNotification(NotificationClient client, FwoNotification notification, int id) + { + FwoNotification persistedNotification = Clone(notification); + persistedNotification.Id = id; + persistedNotification.NotificationClient = client; + return persistedNotification; + } + + /// + /// Copies all mutable notification values from source to target while keeping the existing instance. + /// + private static FwoNotification Clone(FwoNotification notification) + { + return new FwoNotification + { + Id = notification.Id, + NotificationClient = notification.NotificationClient, + UserId = notification.UserId, + OwnerId = notification.OwnerId, + Channel = notification.Channel, + Name = notification.Name, + RecipientTo = notification.RecipientTo, + EmailAddressTo = notification.EmailAddressTo, + RecipientCc = notification.RecipientCc, + EmailAddressCc = notification.EmailAddressCc, + EmailSubject = notification.EmailSubject, + EmailBody = notification.EmailBody, + ScheduleId = notification.ScheduleId, + BundleType = notification.BundleType, + BundleId = notification.BundleId, + Layout = notification.Layout, + Deadline = notification.Deadline, + IntervalBeforeDeadline = notification.IntervalBeforeDeadline, + OffsetBeforeDeadline = notification.OffsetBeforeDeadline, + RepeatIntervalAfterDeadline = notification.RepeatIntervalAfterDeadline, + InitialOffsetAfterDeadline = notification.InitialOffsetAfterDeadline, + RepeatOffsetAfterDeadline = notification.RepeatOffsetAfterDeadline, + RepetitionsAfterDeadline = notification.RepetitionsAfterDeadline, + LastSent = notification.LastSent + }; + } + + /// + /// Captures the GraphQL mutation variables shared by add and update notification requests. + /// + private record NotificationMutationVariables + { + public int? userId { get; init; } + + public string channel { get; init; } = ""; + + public string? name { get; init; } + + public string? recipientTo { get; init; } + + public string? emailAddressTo { get; init; } + + public string? recipientCc { get; init; } + + public string? emailAddressCc { get; init; } + + public string? subject { get; init; } + + public string? emailBody { get; init; } + + public int? scheduleId { get; init; } + + public string? bundleType { get; init; } + + public string? bundleId { get; init; } + + public string layout { get; init; } = ""; + + public string? deadline { get; init; } + + public int? intervalBeforeDeadline { get; init; } + + public int? offsetBeforeDeadline { get; init; } + + public int? intervalAfterDeadline { get; init; } + + public int? initialOffsetAfterDeadline { get; init; } + + public int? offsetAfterDeadline { get; init; } + + public int? repetitionsAfterDeadline { get; init; } + + protected NotificationMutationVariables() + { + } + + protected NotificationMutationVariables(NotificationMutationVariables variables) + { + userId = variables.userId; + channel = variables.channel; + name = variables.name; + recipientTo = variables.recipientTo; + emailAddressTo = variables.emailAddressTo; + recipientCc = variables.recipientCc; + emailAddressCc = variables.emailAddressCc; + subject = variables.subject; + emailBody = variables.emailBody; + scheduleId = variables.scheduleId; + bundleType = variables.bundleType; + bundleId = variables.bundleId; + layout = variables.layout; + deadline = variables.deadline; + intervalBeforeDeadline = variables.intervalBeforeDeadline; + offsetBeforeDeadline = variables.offsetBeforeDeadline; + intervalAfterDeadline = variables.intervalAfterDeadline; + initialOffsetAfterDeadline = variables.initialOffsetAfterDeadline; + offsetAfterDeadline = variables.offsetAfterDeadline; + repetitionsAfterDeadline = variables.repetitionsAfterDeadline; + } + + public static NotificationMutationVariables Create(FwoNotification notification) + { + return new NotificationMutationVariables + { + userId = notification.UserId, + channel = notification.Channel.ToString(), + name = notification.Name, + recipientTo = notification.RecipientTo.ToString(), + emailAddressTo = notification.EmailAddressTo, + recipientCc = notification.RecipientCc.ToString(), + emailAddressCc = notification.EmailAddressCc, + subject = notification.EmailSubject, + emailBody = notification.EmailBody, + scheduleId = notification.ScheduleId, + bundleType = notification.BundleType?.ToString(), + bundleId = notification.BundleId, + layout = notification.Layout.ToString(), + deadline = notification.Deadline.ToString(), + intervalBeforeDeadline = (int?)notification.IntervalBeforeDeadline, + offsetBeforeDeadline = notification.OffsetBeforeDeadline, + intervalAfterDeadline = (int?)notification.RepeatIntervalAfterDeadline, + initialOffsetAfterDeadline = notification.InitialOffsetAfterDeadline, + offsetAfterDeadline = notification.RepeatOffsetAfterDeadline, + repetitionsAfterDeadline = notification.RepetitionsAfterDeadline + }; + } + } + + private sealed record AddNotificationMutationVariables : NotificationMutationVariables + { + public string client { get; init; } = ""; + + private AddNotificationMutationVariables(NotificationMutationVariables variables, NotificationClient client) + : base(variables) + { + this.client = client.ToString(); + } + + public static AddNotificationMutationVariables FromNotification(NotificationClient client, FwoNotification notification) + { + return new AddNotificationMutationVariables(NotificationMutationVariables.Create(notification), client); + } + } + + private sealed record UpdateNotificationMutationVariables : NotificationMutationVariables + { + public int id { get; init; } + + private UpdateNotificationMutationVariables(NotificationMutationVariables variables, int id) + : base(variables) + { + this.id = id; + } + + public static UpdateNotificationMutationVariables FromNotification(FwoNotification notification) + { + return new UpdateNotificationMutationVariables(NotificationMutationVariables.Create(notification), notification.Id); + } + } + } +} diff --git a/roles/ui/files/FWO.UI/Services/PasswordChanger.cs b/roles/ui/files/FWO.UI/Services/PasswordChanger.cs index 2e9c248c65..c935a08989 100644 --- a/roles/ui/files/FWO.UI/Services/PasswordChanger.cs +++ b/roles/ui/files/FWO.UI/Services/PasswordChanger.cs @@ -1,10 +1,10 @@ -using System; -using System.Net; -using System.Threading.Tasks; using FWO.Config.Api; +using FWO.Data.Middleware; using FWO.Middleware.Client; -using FWO.Middleware.RequestParameters; using RestSharp; +using System; +using System.Net; +using System.Threading.Tasks; namespace FWO.Ui.Services { @@ -22,7 +22,7 @@ public async Task ChangePassword(string oldPassword, string newPassword1 { try { - if(doChecks(oldPassword, newPassword1, newPassword2, userConfig, globalConfig)) + if (doChecks(oldPassword, newPassword1, newPassword2, userConfig, globalConfig)) { // Ldap call UserChangePasswordParameters parameters = new UserChangePasswordParameters { LdapId = userConfig.User.LdapConnection.Id, NewPassword = newPassword1, OldPassword = oldPassword, UserId = userConfig.User.DbId }; @@ -46,27 +46,27 @@ public async Task ChangePassword(string oldPassword, string newPassword1 private bool doChecks(string oldPassword, string newPassword1, string newPassword2, UserConfig userConfig, GlobalConfig globalConfig) { - if(oldPassword == "") + if (oldPassword == "") { errorMsg = userConfig.GetText("E5401"); return false; } - else if(newPassword1 == "") + else if (newPassword1 == "") { errorMsg = userConfig.GetText("E5402"); return false; } - else if(newPassword1 == oldPassword) + else if (newPassword1 == oldPassword) { errorMsg = userConfig.GetText("E5403"); return false; } - else if(newPassword1 != newPassword2) + else if (newPassword1 != newPassword2) { errorMsg = userConfig.GetText("E5404"); return false; } - else if(!PasswordPolicy.CheckPolicy(newPassword1, globalConfig, userConfig, out errorMsg)) + else if (!PasswordPolicy.CheckPolicy(newPassword1, globalConfig, userConfig, out errorMsg)) { return false; } diff --git a/roles/ui/files/FWO.UI/Services/PasswordPolicy.cs b/roles/ui/files/FWO.UI/Services/PasswordPolicy.cs index ad28ae1976..dec882db76 100644 --- a/roles/ui/files/FWO.UI/Services/PasswordPolicy.cs +++ b/roles/ui/files/FWO.UI/Services/PasswordPolicy.cs @@ -1,40 +1,37 @@ -using System; -using System.Linq; using System.Text.RegularExpressions; -using FWO.Logging; using FWO.Config.Api; namespace FWO.Ui.Services { - public class PasswordPolicy + public static class PasswordPolicy { public static bool CheckPolicy(string pw, GlobalConfig globalConfig, UserConfig userConfig, out string errorMsg) { errorMsg = ""; - if(pw.Length < globalConfig.PwMinLength) + if (pw.Length < globalConfig.PwMinLength) { errorMsg = userConfig.GetText("E5411") + globalConfig.PwMinLength; return false; } - if(globalConfig.PwUpperCaseRequired && !pw.Any(char.IsUpper)) + if (globalConfig.PwUpperCaseRequired && !pw.Any(char.IsUpper)) { errorMsg = userConfig.GetText("E5412"); return false; } - if(globalConfig.PwLowerCaseRequired && !pw.Any(char.IsLower)) + if (globalConfig.PwLowerCaseRequired && !pw.Any(char.IsLower)) { errorMsg = userConfig.GetText("E5413"); return false; } - if(globalConfig.PwNumberRequired && !pw.Any(char.IsDigit)) + if (globalConfig.PwNumberRequired && !pw.Any(char.IsDigit)) { errorMsg = userConfig.GetText("E5414"); return false; } - if(globalConfig.PwSpecialCharactersRequired) + if (globalConfig.PwSpecialCharactersRequired) { Regex rgx = new Regex("[!?(){}=~$%&#*-+.,_]"); - if(!rgx.IsMatch(pw)) + if (!rgx.IsMatch(pw)) { errorMsg = userConfig.GetText("E5415"); return false; diff --git a/roles/ui/files/FWO.UI/Services/PathAnalysis.cs b/roles/ui/files/FWO.UI/Services/PathAnalysis.cs deleted file mode 100644 index f1ef99ead8..0000000000 --- a/roles/ui/files/FWO.UI/Services/PathAnalysis.cs +++ /dev/null @@ -1,130 +0,0 @@ -using FWO.Api.Data; -using FWO.Api.Client; -using FWO.Api.Client.Queries; -using FWO.Logging; -using NetTools; -using System.Text.Json.Serialization; -using Newtonsoft.Json; - - -namespace FWO.Ui.Services -{ - public enum PathAnalysisOptions - { - WriteToDeviceList, - DisplayFoundDevices - } - - public class PathAnalysisActionParams - { - [JsonProperty("option"), JsonPropertyName("option")] - public PathAnalysisOptions Option { get; set; } = PathAnalysisOptions.DisplayFoundDevices; - } - - - public class PathAnalysis - { - private List states = new List(); - private ApiConnection apiConnection; - - public PathAnalysis(ApiConnection apiConnection) - { - this.apiConnection = apiConnection; - } - - - public async Task getDeviceNamesForSinglePath(string source, string destination) - { - List deviceList = await analyzeSinglePath(source, destination); - - List devNames = new List(); - foreach(Device dev in deviceList) - { - devNames.Add(dev.Name ?? ""); - } - return string.Join(", ", devNames); - } - - public async Task> getAllDevices(List elements) - { - List DevList = new List(); - - try - { - foreach(var elemPair in analyseElements(elements)) - { - List actDevList = new List(); - actDevList = await analyzeSinglePath(elemPair.Key, elemPair.Value); - foreach(var dev in actDevList) - { - if(DevList.FirstOrDefault(x => x.Id == dev.Id) == null) - { - DevList.Add(dev); - } - } - } - } - catch(Exception e) - { - Log.WriteError("Path Analysis", $"error while analysing paths", e); - } - return DevList; - } - - private List> analyseElements(List elements) - { - List> elementPairs = new List>(); - List sources = new List(); - List destinations = new List(); - - foreach(var elem in elements) - { - if (elem.Field == ElemFieldType.source.ToString() && elem.Cidr.CidrString != null) - { - sources.Add(elem.Cidr.CidrString); - } - else if (elem.Field == ElemFieldType.destination.ToString() && elem.Cidr.CidrString != null) - { - destinations.Add(elem.Cidr.CidrString); - } - } - - foreach(var src in sources) - { - foreach(var dst in destinations) - { - elementPairs.Add(new KeyValuePair(src, dst)); - } - } - return elementPairs; - } - - private async Task> analyzeSinglePath(string source, string destination) - { - IPAddressRange routingSource = new IPAddressRange(); - IPAddressRange routingDestination = new IPAddressRange(); - List DevList = new List(); - - try - { - routingSource = IPAddressRange.Parse(source); - routingDestination = IPAddressRange.Parse(destination); - // we only want cidr - try - { - var Variables = new { src = routingSource.Begin.ToString(), dst = routingDestination.Begin.ToString() }; - DevList = await apiConnection.SendQueryAsync>(NetworkAnalysisQueries.pathAnalysis, Variables); - } - catch (Exception exeption) - { - Log.WriteError("Path Analysis", $"error while analysing path", exeption); - } - } - catch(Exception e) - { - Log.WriteError("Path Analysis", $"no valid ip address", e); - } - return DevList; - } - } -} diff --git a/roles/ui/files/FWO.UI/Services/RecertificationOwnerSelection.cs b/roles/ui/files/FWO.UI/Services/RecertificationOwnerSelection.cs new file mode 100644 index 0000000000..24936bf754 --- /dev/null +++ b/roles/ui/files/FWO.UI/Services/RecertificationOwnerSelection.cs @@ -0,0 +1,82 @@ +using FWO.Data; +using FWO.Ui.Auth; +using System.Security.Claims; + +namespace FWO.Ui.Services +{ + /// + /// Provides reusable recertification owner selection and access rules. + /// + public static class RecertificationOwnerSelection + { + /// + /// Picks a default owner and prioritizes recertifiable owners when available. + /// + public static FwoOwner? SelectOwner(IReadOnlyList owners, IReadOnlyCollection recertifiableOwnerIds) + { + if (owners.Count == 0) + { + return null; + } + + if (recertifiableOwnerIds.Count == 0) + { + return owners[0]; + } + + return owners.FirstOrDefault(owner => recertifiableOwnerIds.Contains(owner.Id)) ?? owners[0]; + } + + /// + /// Resolves owner ids from configured values and falls back to JWT claim values when empty. + /// + public static List ResolveOwnerIds(IReadOnlyList configuredOwnerIds, IEnumerable claims, string claimType) + { + if (configuredOwnerIds.Count > 0) + { + return [.. configuredOwnerIds]; + } + + return JwtClaimParser.ExtractIntClaimValues(claims, claimType); + } + + /// + /// Determines whether the selected owner can be updated in recertification context. + /// + public static bool CanWriteSelectedOwner( + FwoOwner? selectedOwner, + bool isAdmin, + bool hasRecertifierRole, + IReadOnlyCollection recertifiableOwnerIds) + { + if (selectedOwner == null || (!isAdmin && !hasRecertifierRole)) + { + return false; + } + + if (isAdmin) + { + return true; + } + + return recertifiableOwnerIds.Contains(selectedOwner.Id); + } + + /// + /// Determines whether to show a hint that the user currently has no recertifiable owner assignments. + /// + public static bool ShowNoRecertifiableOwnersHint( + bool isAdmin, + bool hasRecertifierRole, + int readableOwnerCount, + int recertifiableOwnerCount) + { + if (isAdmin || !hasRecertifierRole || readableOwnerCount <= 0) + { + return false; + } + + return recertifiableOwnerCount == 0; + } + } +} diff --git a/roles/ui/files/FWO.UI/Services/ReportScheduleNotificationHelper.cs b/roles/ui/files/FWO.UI/Services/ReportScheduleNotificationHelper.cs new file mode 100644 index 0000000000..0d80ee7be6 --- /dev/null +++ b/roles/ui/files/FWO.UI/Services/ReportScheduleNotificationHelper.cs @@ -0,0 +1,168 @@ +using FWO.Api.Client; +using FWO.Basics; +using FWO.Data; +using FWO.Data.Report; + +namespace FWO.Ui.Services +{ + public static class ReportScheduleNotificationHelper + { + private sealed class NotificationSettings + { + internal string FormatName { get; init; } = ""; + internal string EmailRecipients { get; init; } = ""; + internal string EmailSubject { get; init; } = ""; + internal string EmailBody { get; init; } = ""; + internal BundleType? BundleType { get; init; } + internal string? BundleId { get; init; } + } + + public static async Task> SyncNotifications(ApiConnection apiConnection, ReportSchedule reportSchedule, bool toEmail, + string emailRecipients, string emailSubject, string emailBody) + { + if (!toEmail) + { + await DeleteNotifications(apiConnection, reportSchedule.Notifications); + return []; + } + + if (reportSchedule.Notifications.Count == 0) + { + return await CreateNotifications(apiConnection, reportSchedule, emailRecipients, emailSubject, emailBody); + } + + return await UpdateNotifications(apiConnection, reportSchedule, emailRecipients, emailSubject, emailBody); + } + + public static async Task> CreateNotifications(ApiConnection apiConnection, ReportSchedule reportSchedule, + string emailRecipients, string emailSubject, string emailBody) + { + (BundleType? bundleType, string? bundleId) = GetBundleSettings(reportSchedule); + List createdNotifications = []; + foreach (FileFormat format in reportSchedule.OutputFormat) + { + NotificationSettings notificationSettings = NewNotificationSettings(format.Name, emailRecipients, emailSubject, emailBody, bundleType, bundleId); + createdNotifications.Add(await AddNotification(apiConnection, reportSchedule, notificationSettings)); + } + + return createdNotifications; + } + + public static async Task DeleteNotifications(ApiConnection apiConnection, List? notifications) + { + if (notifications == null) + { + return; + } + + foreach (FwoNotification notification in notifications.Where(notification => notification.Id > 0)) + { + await NotificationMutationHelper.DeleteAsync(apiConnection, notification.Id); + } + } + + private static async Task> UpdateNotifications(ApiConnection apiConnection, ReportSchedule reportSchedule, + string emailRecipients, string emailSubject, string emailBody) + { + (BundleType? bundleType, string? bundleId) = GetBundleSettings(reportSchedule); + List remainingNotifications = [.. reportSchedule.Notifications]; + List updatedNotifications = []; + + foreach (FileFormat format in reportSchedule.OutputFormat) + { + NotificationSettings notificationSettings = NewNotificationSettings(format.Name, emailRecipients, emailSubject, emailBody, bundleType, bundleId); + NotificationLayout layout = ToNotificationLayout(notificationSettings.FormatName); + FwoNotification? existingNotification = remainingNotifications.FirstOrDefault(notification => notification.Layout == layout); + if (existingNotification != null) + { + updatedNotifications.Add(await UpdateNotification(apiConnection, reportSchedule, existingNotification, notificationSettings)); + remainingNotifications.Remove(existingNotification); + } + else + { + updatedNotifications.Add(await AddNotification(apiConnection, reportSchedule, notificationSettings)); + } + } + + await DeleteNotifications(apiConnection, remainingNotifications); + return updatedNotifications; + } + + private static async Task AddNotification(ApiConnection apiConnection, ReportSchedule reportSchedule, + NotificationSettings notificationSettings) + { + FwoNotification notification = BuildNotification(reportSchedule, notificationSettings); + return await NotificationMutationHelper.AddAsync(apiConnection, NotificationClient.Report, notification); + } + + private static async Task UpdateNotification(ApiConnection apiConnection, ReportSchedule reportSchedule, + FwoNotification notification, NotificationSettings notificationSettings) + { + FwoNotification updatedNotification = BuildNotification(reportSchedule, notificationSettings); + updatedNotification.Id = notification.Id; + return await NotificationMutationHelper.UpdateAsync(apiConnection, NotificationClient.Report, updatedNotification); + } + + private static FwoNotification BuildNotification(ReportSchedule reportSchedule, NotificationSettings notificationSettings) + { + return new FwoNotification + { + NotificationClient = NotificationClient.Report, + Channel = NotificationChannel.Email, + Name = $"{reportSchedule.Name} {notificationSettings.FormatName.ToUpperInvariant()}", + RecipientTo = EmailRecipientOption.OtherAddresses, + EmailAddressTo = notificationSettings.EmailRecipients, + RecipientCc = EmailRecipientOption.None, + EmailAddressCc = "", + EmailSubject = notificationSettings.EmailSubject, + EmailBody = notificationSettings.EmailBody, + UserId = reportSchedule.ScheduleOwningUser.DbId, + ScheduleId = reportSchedule.Id, + BundleType = notificationSettings.BundleType, + BundleId = notificationSettings.BundleId, + Layout = ToNotificationLayout(notificationSettings.FormatName), + Deadline = NotificationDeadline.None + }; + } + + private static NotificationSettings NewNotificationSettings(string formatName, string emailRecipients, string emailSubject, + string emailBody, BundleType? bundleType, string? bundleId) + { + return new NotificationSettings + { + FormatName = formatName, + EmailRecipients = emailRecipients, + EmailSubject = emailSubject, + EmailBody = emailBody, + BundleType = bundleType, + BundleId = bundleId + }; + } + + private static (BundleType? BundleType, string? BundleId) GetBundleSettings(ReportSchedule reportSchedule) + { + if (reportSchedule.OutputFormat.Count <= 1) + { + return (null, null); + } + + string? existingBundleId = reportSchedule.Notifications + .Select(notification => notification.BundleId) + .FirstOrDefault(bundleId => !string.IsNullOrWhiteSpace(bundleId)); + + return (BundleType.Attachments, existingBundleId ?? Guid.NewGuid().ToString()); + } + + private static NotificationLayout ToNotificationLayout(string formatName) + { + return formatName switch + { + GlobalConst.kHtml => NotificationLayout.HtmlAsAttachment, + GlobalConst.kPdf => NotificationLayout.PdfAsAttachment, + GlobalConst.kJson => NotificationLayout.JsonAsAttachment, + GlobalConst.kCsv => NotificationLayout.CsvAsAttachment, + _ => throw new NotSupportedException("Output format is not supported.") + }; + } + } +} diff --git a/roles/ui/files/FWO.UI/Services/RequestDbAccess.cs b/roles/ui/files/FWO.UI/Services/RequestDbAccess.cs deleted file mode 100644 index 6a53d97921..0000000000 --- a/roles/ui/files/FWO.UI/Services/RequestDbAccess.cs +++ /dev/null @@ -1,839 +0,0 @@ -using FWO.Api.Data; -using FWO.Config.Api; -using FWO.Api.Client; - -namespace FWO.Ui.Services -{ - public class RequestDbAccess - { - private Action DisplayMessageInUi = DefaultInit.DoNothing; - private UserConfig UserConfig; - private ApiConnection ApiConnection; - private ActionHandler ActionHandler; - - - public RequestDbAccess(Action displayMessageInUi, UserConfig userConfig, ApiConnection apiConnection, ActionHandler actionHandler) - { - DisplayMessageInUi = displayMessageInUi; - UserConfig = userConfig; - ApiConnection = apiConnection; - ActionHandler = actionHandler; - } - - public async Task> FetchTickets(StateMatrix stateMatrix, int viewOpt = 0) - { - List requests = new List(); - try - { - // todo: filter own approvals, plannings... - var Variables = new - { - from_state = stateMatrix.LowestInputState, - to_state = (viewOpt == 0 ? stateMatrix.LowestEndState : 999) - }; - requests = await ApiConnection.SendQueryAsync>(FWO.Api.Client.Queries.RequestQueries.getTickets, Variables); - foreach (var ticket in requests) - { - ticket.UpdateCidrsInTaskElements(); - } - } - catch (Exception exception) - { - DisplayMessageInUi(exception, UserConfig.GetText("fetch_requests"), "", true); - } - return requests; - } - - public async Task GetTicket(int id) - { - RequestTicket ticket = new RequestTicket(); - try - { - var Variables = new - { - id = id, - }; - ticket = await ApiConnection.SendQueryAsync(FWO.Api.Client.Queries.RequestQueries.getTicketById, Variables); - ticket.UpdateCidrsInTaskElements(); - } - catch (Exception exception) - { - DisplayMessageInUi(exception, UserConfig.GetText("fetch_requests"), "", true); - } - return ticket; - } - - // Tickets - - public async Task AddTicketToDb(RequestTicket ticket) - { - try - { - ticket.UpdateCidrStringsInTaskElements(); - var Variables = new - { - title = ticket.Title, - state = ticket.StateId, - reason = ticket.Reason, - requesterId = ticket.Requester?.DbId, - deadline = ticket.Deadline, - priority = ticket.Priority, - requestTasks = new RequestTicketWriter(ticket) - }; - ReturnId[]? returnIds = (await ApiConnection.SendQueryAsync(FWO.Api.Client.Queries.RequestQueries.newTicket, Variables)).ReturnIds; - if (returnIds == null) - { - DisplayMessageInUi(null, UserConfig.GetText("save_request"), UserConfig.GetText("E8001"), true); - } - else - { - ticket = await GetTicket(returnIds[0].NewId); - await ActionHandler.DoStateChangeActions(ticket, RequestObjectScopes.Ticket); - } - } - catch (Exception exception) - { - DisplayMessageInUi(exception, UserConfig.GetText("save_request"), "", true); - } - return ticket; - } - - public async Task UpdateTicketInDb(RequestTicket ticket) - { - try - { - var Variables = new - { - id = ticket.Id, - title = ticket.Title, - state = ticket.StateId, - reason = ticket.Reason, - deadline = ticket.Deadline, - priority = ticket.Priority - }; - int udId = (await ApiConnection.SendQueryAsync(FWO.Api.Client.Queries.RequestQueries.updateTicket, Variables)).UpdatedId; - if(udId != ticket.Id) - { - DisplayMessageInUi(null, UserConfig.GetText("save_request"), UserConfig.GetText("E8002"), true); - } - else - { - await ActionHandler.DoStateChangeActions(ticket, RequestObjectScopes.Ticket); - } - } - catch (Exception exception) - { - DisplayMessageInUi(exception, UserConfig.GetText("save_request"), "", true); - } - return ticket; - } - - // Request Tasks - - public async Task AddReqTaskToDb(RequestReqTask reqtask) - { - int returnId = 0; - try - { - var Variables = new - { - title = reqtask.Title, - ticketId = reqtask.TicketId, - taskNumber = reqtask.TaskNumber, - state = reqtask.StateId, - taskType = reqtask.TaskType, - requestAction = reqtask.RequestAction, - ruleAction = reqtask.RuleAction, - tracking = reqtask.Tracking, - validFrom = reqtask.TargetBeginDate, - validTo = reqtask.TargetEndDate, - reason = reqtask.Reason, - freeText = reqtask.FreeText - }; - ReturnId[]? returnIds = (await ApiConnection.SendQueryAsync(FWO.Api.Client.Queries.RequestQueries.newRequestTask, Variables)).ReturnIds; - if (returnIds == null) - { - DisplayMessageInUi(null, UserConfig.GetText("add_task"), UserConfig.GetText("E8003"), true); - } - else - { - returnId = returnIds[0].NewId; - reqtask.Id = returnId; - foreach(var element in reqtask.Elements) - { - element.TaskId = returnId; - element.Id = await AddReqElementToDb(element); - } - foreach(var approval in reqtask.Approvals) - { - approval.TaskId = returnId; - await AddApprovalToDb(approval); - } - await ActionHandler.DoStateChangeActions(reqtask, RequestObjectScopes.RequestTask); - } - } - catch (Exception exception) - { - DisplayMessageInUi(exception, UserConfig.GetText("add_task"), "", true); - } - return returnId; - } - - public async Task UpdateReqTaskInDb(RequestReqTask reqtask) - { - try - { - var Variables = new - { - id = reqtask.Id, - title = reqtask.Title, - taskNumber = reqtask.TaskNumber, - state = reqtask.StateId, - taskType = reqtask.TaskType, - requestAction = reqtask.RequestAction, - ruleAction = reqtask.RuleAction, - tracking = reqtask.Tracking, - validFrom = reqtask.TargetBeginDate, - validTo = reqtask.TargetEndDate, - reason = reqtask.Reason, - freeText = reqtask.FreeText, - devices = reqtask.SelectedDevices - }; - int udId = (await ApiConnection.SendQueryAsync(FWO.Api.Client.Queries.RequestQueries.updateRequestTask, Variables)).UpdatedId; - if(udId != reqtask.Id) - { - DisplayMessageInUi(null, UserConfig.GetText("save_task"), UserConfig.GetText("E8004"), true); - } - else - { - foreach(var elem in reqtask.RemovedElements) - { - await DeleteReqElementFromDb(elem.Id); - } - reqtask.RemovedElements = new List(); - - foreach(var element in reqtask.Elements) - { - if(element.Id == 0) - { - element.Id = await AddReqElementToDb(element); - } - else - { - await UpdateReqElementInDb(element); - } - } - await ActionHandler.DoStateChangeActions(reqtask, RequestObjectScopes.RequestTask); - } - } - catch (Exception exception) - { - DisplayMessageInUi(exception, UserConfig.GetText("save_task"), "", true); - } - } - - public async Task DeleteReqTaskFromDb(RequestReqTask reqtask) - { - try - { - int delId = (await ApiConnection.SendQueryAsync(FWO.Api.Client.Queries.RequestQueries.deleteRequestTask, new { id = reqtask.Id })).DeletedId; - if(delId != reqtask.Id) - { - DisplayMessageInUi(null, UserConfig.GetText("delete_task"), UserConfig.GetText("E8005"), true); - } - } - catch (Exception exception) - { - DisplayMessageInUi(exception, UserConfig.GetText("delete_task"), "", true); - } - } - - // Request Elements - - public async Task AddReqElementToDb(RequestReqElement element) - { - int returnId = 0; - try - { - var Variables = new - { - requestAction = element.RequestAction, - taskId = element.TaskId, - ip = (element.Cidr != null && element.Cidr.Valid ? element.Cidr.CidrString : null), - port = element.Port, - proto = element.ProtoId, - networkObjId = element.NetworkId, - serviceId = element.ServiceId, - field = element.Field, - userId = element.UserId, - originalNatId = element.OriginalNatId, - deviceId = element.DeviceId, - ruleUid = element.RuleUid - }; - ReturnId[]? returnIds = (await ApiConnection.SendQueryAsync(FWO.Api.Client.Queries.RequestQueries.newRequestElement, Variables)).ReturnIds; - if (returnIds == null) - { - DisplayMessageInUi(null, UserConfig.GetText("add_element"), UserConfig.GetText("E8006"), true); - } - else - { - returnId = returnIds[0].NewId; - } - } - catch (Exception exception) - { - DisplayMessageInUi(exception, UserConfig.GetText("add_element"), "", true); - } - return returnId; - } - - public async Task UpdateReqElementInDb(RequestReqElement element) - { - try - { - var Variables = new - { - id = element.Id, - requestAction = element.RequestAction, - taskId = element.TaskId, - ip = (element.Cidr != null && element.Cidr.Valid ? element.Cidr.CidrString : null), - port = element.Port, - proto = element.ProtoId, - networkObjId = element.NetworkId, - serviceId = element.ServiceId, - field = element.Field, - userId = element.UserId, - originalNatId = element.OriginalNatId, - deviceId = element.DeviceId, - ruleUid = element.RuleUid - }; - int udId = (await ApiConnection.SendQueryAsync(FWO.Api.Client.Queries.RequestQueries.updateRequestElement, Variables)).UpdatedId; - if(udId != element.Id) - { - DisplayMessageInUi(null, UserConfig.GetText("save_element"), UserConfig.GetText("E8007"), true); - } - } - catch (Exception exception) - { - DisplayMessageInUi(exception, UserConfig.GetText("save_element"), "", true); - } - } - - public async Task DeleteReqElementFromDb(long elementId) - { - try - { - long delId = (await ApiConnection.SendQueryAsync(FWO.Api.Client.Queries.RequestQueries.deleteRequestElement, new { id = elementId })).DeletedId; - if(delId != elementId) - { - DisplayMessageInUi(null, UserConfig.GetText("delete_element"), UserConfig.GetText("E8008"), true); - } - } - catch (Exception exception) - { - DisplayMessageInUi(exception, UserConfig.GetText("delete_element"), "", true); - } - } - - // Approvals - - public async Task AddApprovalToDb(RequestApproval approval) - { - int returnId = 0; - try - { - var Variables = new - { - taskId = approval.TaskId, - state = approval.StateId, - approverGroup = approval.ApproverGroup, - tenant = approval.TenantId, - deadline = approval.Deadline, - initialApproval = approval.InitialApproval - }; - ReturnId[]? returnIds = (await ApiConnection.SendQueryAsync(FWO.Api.Client.Queries.RequestQueries.newApproval, Variables)).ReturnIds; - if (returnIds == null) - { - DisplayMessageInUi(null, UserConfig.GetText("add_approval"), UserConfig.GetText("E8009"), true); - } - else - { - returnId = returnIds[0].NewId; - approval.Id = returnId; - await ActionHandler.DoStateChangeActions(approval, RequestObjectScopes.Approval); - } - } - catch (Exception exception) - { - DisplayMessageInUi(exception, UserConfig.GetText("add_approval"), "", true); - } - return returnId; - } - - public async Task UpdateApprovalInDb(RequestApproval approval) - { - try - { - var Variables = new - { - id = approval.Id, - state = approval.StateId, - approvalDate = approval.ApprovalDate, - approver = approval.ApproverDn, // todo: Dn or uiuser?? - assignedGroup = approval.AssignedGroup - }; - int udId = (await ApiConnection.SendQueryAsync(FWO.Api.Client.Queries.RequestQueries.updateApproval, Variables)).UpdatedId; - if(udId != approval.Id) - { - DisplayMessageInUi(null, UserConfig.GetText("save_approval"), UserConfig.GetText("E8004"), true); - } - else - { - await ActionHandler.DoStateChangeActions(approval, RequestObjectScopes.Approval); - } - } - catch (Exception exception) - { - DisplayMessageInUi(exception, UserConfig.GetText("save_approval"), "", true); - } - } - - // implementation tasks - - public async Task AddImplTaskToDb(RequestImplTask impltask) - { - int returnId = 0; - try - { - var Variables = new - { - title = impltask.Title, - reqTaskId = impltask.ReqTaskId, - implIaskNumber = impltask.TaskNumber, - state = impltask.StateId, - taskType = impltask.TaskType, - device = impltask.DeviceId, - implAction = impltask.ImplAction, - ruleAction = impltask.RuleAction, - tracking = impltask.Tracking, - handler = impltask.CurrentHandler?.DbId, - validFrom = impltask.TargetBeginDate, - validTo = impltask.TargetEndDate, - freeText = impltask.FreeText, - }; - ReturnId[]? returnIds = (await ApiConnection.SendQueryAsync(FWO.Api.Client.Queries.RequestQueries.newImplementationTask, Variables)).ReturnIds; - if (returnIds == null) - { - DisplayMessageInUi(null, UserConfig.GetText("add_task"), UserConfig.GetText("E8003"), true); - } - else - { - returnId = returnIds[0].NewId; - impltask.Id = returnId; - foreach(var element in impltask.ImplElements) - { - element.ImplTaskId = returnId; - element.Id = await AddImplElementToDb(element); - } - foreach(var comment in impltask.Comments) - { - comment.Comment.Id = await AddCommentToDb(comment.Comment); - if(comment.Comment.Id != 0) - { - await AssignCommentToImplTaskInDb(returnId, comment.Comment.Id); - } - } - await ActionHandler.DoStateChangeActions(impltask, RequestObjectScopes.ImplementationTask); - } - } - catch (Exception exception) - { - DisplayMessageInUi(exception, UserConfig.GetText("add_task"), "", true); - } - return returnId; - } - - public async Task UpdateImplTaskInDb(RequestImplTask impltask) - { - try - { - var Variables = new - { - id = impltask.Id, - title = impltask.Title, - reqTaskId = impltask.ReqTaskId, - implIaskNumber = impltask.TaskNumber, - state = impltask.StateId, - taskType = impltask.TaskType, - device = impltask.DeviceId, - implAction = impltask.ImplAction, - ruleAction = impltask.RuleAction, - tracking = impltask.Tracking, - handler = impltask.CurrentHandler?.DbId, - validFrom = impltask.TargetBeginDate, - validTo = impltask.TargetEndDate, - freeText = impltask.FreeText, - }; - int udId = (await ApiConnection.SendQueryAsync(FWO.Api.Client.Queries.RequestQueries.updateImplementationTask, Variables)).UpdatedId; - if(udId != impltask.Id) - { - DisplayMessageInUi(null, UserConfig.GetText("save_task"), UserConfig.GetText("E8004"), true); - } - else - { - foreach(var elem in impltask.RemovedElements) - { - await DeleteImplElementFromDb(elem.Id); - } - impltask.RemovedElements = new List(); - - foreach(var element in impltask.ImplElements) - { - if(element.Id == 0) - { - element.Id = await AddImplElementToDb(element); - } - else - { - await UpdateImplElementInDb(element); - } - } - await ActionHandler.DoStateChangeActions(impltask, RequestObjectScopes.ImplementationTask); - } - } - catch (Exception exception) - { - DisplayMessageInUi(exception, UserConfig.GetText("save_task"), "", true); - } - } - - public async Task DeleteImplTaskFromDb(RequestImplTask impltask) - { - try - { - int delId = (await ApiConnection.SendQueryAsync(FWO.Api.Client.Queries.RequestQueries.deleteImplementationTask, new { id = impltask.Id })).DeletedId; - if(delId != impltask.Id) - { - DisplayMessageInUi(null, UserConfig.GetText("delete_task"), UserConfig.GetText("E8005"), true); - } - } - catch (Exception exception) - { - DisplayMessageInUi(exception, UserConfig.GetText("delete_task"), "", true); - } - } - - - // implementation elements - - public async Task AddImplElementToDb(RequestImplElement element) - { - int returnId = 0; - try - { - var Variables = new - { - implementationAction = element.ImplAction, - implTaskId = element.ImplTaskId, - ip = (element.Cidr != null && element.Cidr.Valid ? element.Cidr.CidrString : null), - port = element.Port, - proto = element.ProtoId, - networkObjId = element.NetworkId, - serviceId = element.ServiceId, - field = element.Field, - userId = element.UserId, - originalNatId = element.OriginalNatId, - ruleUid = element.RuleUid - }; - ReturnId[]? returnIds = (await ApiConnection.SendQueryAsync(FWO.Api.Client.Queries.RequestQueries.newImplementationElement, Variables)).ReturnIds; - if (returnIds == null) - { - DisplayMessageInUi(null, UserConfig.GetText("add_element"), UserConfig.GetText("E8006"), true); - } - else - { - returnId = returnIds[0].NewId; - } - } - catch (Exception exception) - { - DisplayMessageInUi(exception, UserConfig.GetText("add_element"), "", true); - } - return returnId; - } - - public async Task UpdateImplElementInDb(RequestImplElement element) - { - try - { - var Variables = new - { - id = element.Id, - implementationAction = element.ImplAction, - implTaskId = element.ImplTaskId, - ip = (element.Cidr != null && element.Cidr.Valid ? element.Cidr.CidrString : null), - port = element.Port, - proto = element.ProtoId, - networkObjId = element.NetworkId, - serviceId = element.ServiceId, - field = element.Field, - userId = element.UserId, - originalNatId = element.OriginalNatId, - ruleUid = element.RuleUid - }; - int udId = (await ApiConnection.SendQueryAsync(FWO.Api.Client.Queries.RequestQueries.updateImplementationElement, Variables)).UpdatedId; - if(udId != element.Id) - { - DisplayMessageInUi(null, UserConfig.GetText("save_element"), UserConfig.GetText("E8007"), true); - } - } - catch (Exception exception) - { - DisplayMessageInUi(exception, UserConfig.GetText("save_element"), "", true); - } - } - - public async Task DeleteImplElementFromDb(long elementId) - { - try - { - long delId = (await ApiConnection.SendQueryAsync(FWO.Api.Client.Queries.RequestQueries.deleteImplementationElement, new { id = elementId })).DeletedId; - if(delId != elementId) - { - DisplayMessageInUi(null, UserConfig.GetText("delete_element"), UserConfig.GetText("E8008"), true); - } - } - catch (Exception exception) - { - DisplayMessageInUi(exception, UserConfig.GetText("delete_element"), "", true); - } - } - - - // Comments - - public async Task AddCommentToDb(RequestComment comment) - { - int returnId = 0; - try - { - var Variables = new - { - refId = comment.RefId, - scope = comment.Scope, - creationDate = comment.CreationDate, - creator = comment.Creator.DbId, - text = comment.CommentText - }; - ReturnId[]? returnIds = (await ApiConnection.SendQueryAsync(FWO.Api.Client.Queries.RequestQueries.newComment, Variables)).ReturnIds; - if (returnIds == null) - { - DisplayMessageInUi(null, UserConfig.GetText("add_comment"), UserConfig.GetText("E8012"), true); - } - else - { - returnId = returnIds[0].NewId; - } - } - catch (Exception exception) - { - DisplayMessageInUi(exception, UserConfig.GetText("add_comment"), "", true); - } - return returnId; - } - - public async Task AssignCommentToTicketInDb(long ticketId, long commentId) - { - try - { - var Variables = new - { - TicketId = ticketId, - commentId = commentId - }; - ReturnId[]? returnIds = (await ApiConnection.SendQueryAsync(FWO.Api.Client.Queries.RequestQueries.addCommentToTicket, Variables)).ReturnIds; - if (returnIds == null) - { - DisplayMessageInUi(null, UserConfig.GetText("add_comment"), UserConfig.GetText("E8012"), true); - } - } - catch (Exception exception) - { - DisplayMessageInUi(exception, UserConfig.GetText("add_comment"), "", true); - } - } - - public async Task AssignCommentToReqTaskInDb(long taskId, long commentId) - { - try - { - var Variables = new - { - taskId = taskId, - commentId = commentId - }; - ReturnId[]? returnIds = (await ApiConnection.SendQueryAsync(FWO.Api.Client.Queries.RequestQueries.addCommentToReqTask, Variables)).ReturnIds; - if (returnIds == null) - { - DisplayMessageInUi(null, UserConfig.GetText("add_comment"), UserConfig.GetText("E8012"), true); - } - } - catch (Exception exception) - { - DisplayMessageInUi(exception, UserConfig.GetText("add_comment"), "", true); - } - } - - public async Task AssignCommentToImplTaskInDb(long taskId, long commentId) - { - try - { - var Variables = new - { - taskId = taskId, - commentId = commentId - }; - ReturnId[]? returnIds = (await ApiConnection.SendQueryAsync(FWO.Api.Client.Queries.RequestQueries.addCommentToImplTask, Variables)).ReturnIds; - if (returnIds == null) - { - DisplayMessageInUi(null, UserConfig.GetText("add_comment"), UserConfig.GetText("E8012"), true); - } - } - catch (Exception exception) - { - DisplayMessageInUi(exception, UserConfig.GetText("add_comment"), "", true); - } - } - - public async Task AssignCommentToApprovalInDb(long approvalId, long commentId) - { - try - { - var Variables = new - { - approvalId = approvalId, - commentId = commentId - }; - ReturnId[]? returnIds = (await ApiConnection.SendQueryAsync(FWO.Api.Client.Queries.RequestQueries.addCommentToApproval, Variables)).ReturnIds; - if (returnIds == null) - { - DisplayMessageInUi(null, UserConfig.GetText("add_comment"), UserConfig.GetText("E8012"), true); - } - } - catch (Exception exception) - { - DisplayMessageInUi(exception, UserConfig.GetText("add_comment"), "", true); - } - } - - - // State changes - - public async Task UpdateTicketStateInDb(RequestTicket ticket) - { - try - { - var Variables = new - { - id = ticket.Id, - state = ticket.StateId, - closed = ticket.CompletionDate, - deadline = ticket.Deadline, - priority = ticket.Priority - }; - int udId = (await ApiConnection.SendQueryAsync(FWO.Api.Client.Queries.RequestQueries.updateTicketState, Variables)).UpdatedId; - if(udId != ticket.Id) - { - DisplayMessageInUi(null, UserConfig.GetText("save_request"), UserConfig.GetText("E8002"), true); - } - else - { - await ActionHandler.DoStateChangeActions(ticket, RequestObjectScopes.Ticket); - } - } - catch (Exception exception) - { - DisplayMessageInUi(exception, UserConfig.GetText("save_request"), "", true); - } - } - - public async Task UpdateReqTaskStateInDb(RequestReqTask reqtask) - { - try - { - var Variables = new - { - id = reqtask.Id, - state = reqtask.StateId, - start = reqtask.Start, - stop = reqtask.Stop, - handler = reqtask.CurrentHandler?.DbId, - recentHandler = reqtask.RecentHandler?.DbId, - assignedGroup = reqtask.AssignedGroup - }; - int udId = (await ApiConnection.SendQueryAsync(FWO.Api.Client.Queries.RequestQueries.updateRequestTaskState, Variables)).UpdatedId; - if(udId != reqtask.Id) - { - DisplayMessageInUi(null, UserConfig.GetText("save_task"), UserConfig.GetText("E8004"), true); - } - else - { - await ActionHandler.DoStateChangeActions(reqtask, RequestObjectScopes.RequestTask); - } - } - catch (Exception exception) - { - DisplayMessageInUi(exception, UserConfig.GetText("save_task"), "", true); - } - } - - public async Task UpdateImplTaskStateInDb(RequestImplTask impltask) - { - try - { - var Variables = new - { - id = impltask.Id, - state = impltask.StateId, - start = impltask.Start, - stop = impltask.Stop, - handler = impltask.CurrentHandler?.DbId, - recentHandler = impltask.RecentHandler?.DbId, - assignedGroup = impltask.AssignedGroup, - }; - int udId = (await ApiConnection.SendQueryAsync(FWO.Api.Client.Queries.RequestQueries.updateImplementationTaskState, Variables)).UpdatedId; - if(udId != impltask.Id) - { - DisplayMessageInUi(null, UserConfig.GetText("save_task"), UserConfig.GetText("E8004"), true); - } - else - { - await ActionHandler.DoStateChangeActions(impltask, RequestObjectScopes.ImplementationTask); - } - } - catch (Exception exception) - { - DisplayMessageInUi(exception, UserConfig.GetText("save_task"), "", true); - } - } - - public async Task FindRuleUid(int? deviceId, string? ruleUid) - { - bool ruleFound = false; - try - { - var Variables = new - { - deviceId = deviceId, - ruleUid = ruleUid - }; - ruleFound = (await ApiConnection.SendQueryAsync>(FWO.Api.Client.Queries.RuleQueries.getRuleByUid, Variables)).Count > 0; - } - catch (Exception exception) - { - DisplayMessageInUi(exception, UserConfig.GetText("fetch_data"), "", true); - } - return ruleFound; - } - } -} diff --git a/roles/ui/files/FWO.UI/Services/RequestHandler.cs b/roles/ui/files/FWO.UI/Services/RequestHandler.cs deleted file mode 100644 index 234a700208..0000000000 --- a/roles/ui/files/FWO.UI/Services/RequestHandler.cs +++ /dev/null @@ -1,1104 +0,0 @@ -using FWO.Api.Data; -using FWO.Config.Api; -using FWO.Api.Client; - -namespace FWO.Ui.Services -{ - public enum ObjAction - { - display, - edit, - add, - approve, - plan, - implement, - review, - displayAssign, - displayApprovals, - displayApprove, - displayPromote, - displayDelete, - displaySaveTicket, - displayComment, - displayCleanup, - displayPathAnalysis - } - - public class RequestHandler - { - public List TicketList { get; set; } = new List(); - public RequestTicket ActTicket { get; set; } = new RequestTicket(); - public RequestReqTask ActReqTask { get; set; } = new RequestReqTask(); - public RequestImplTask ActImplTask { get; set; } = new RequestImplTask(); - public RequestApproval ActApproval { get; set; } = new RequestApproval(); - - public WorkflowPhases Phase = WorkflowPhases.request; - public List Devices = new List(); - public List PrioList = new List(); - public List AllImplTasks = new List(); - public StateMatrix ActStateMatrix = new StateMatrix(); - public StateMatrix MasterStateMatrix = new StateMatrix(); - public ActionHandler ActionHandler; - public bool ReadOnlyMode = false; - - public bool DisplayTicketMode = false; - public bool EditTicketMode = false; - public bool AddTicketMode = false; - - public bool DisplayReqTaskMode = false; - public bool EditReqTaskMode = false; - public bool AddReqTaskMode = false; - public bool PlanReqTaskMode = false; - public bool ApproveReqTaskMode = false; - - public bool DisplayImplTaskMode = false; - public bool EditImplTaskMode = false; - public bool AddImplTaskMode = false; - public bool ImplementImplTaskMode = false; - - public bool DisplayAssignMode = false; - public bool DisplayApprovalMode = false; - public bool DisplayApproveMode = false; - public bool DisplayAssignApprovalMode = false; - public bool DisplayPromoteMode = false; - public bool DisplaySaveTicketMode = false; - public bool DisplayDeleteMode = false; - public bool DisplayCleanupMode = false; - public bool DisplayCommentMode = false; - public bool DisplayPathAnalysisMode = false; - - - private Action DisplayMessageInUi { get; set; } = DefaultInit.DoNothing; - private UserConfig userConfig; - private readonly ApiConnection apiConnection; - private StateMatrixDict stateMatrixDict = new StateMatrixDict(); - private RequestDbAccess dbAcc; - - private ObjAction contOption = ObjAction.display; - - - public RequestHandler() - {} - - public RequestHandler(Action displayMessageInUi, UserConfig userConfig, - ApiConnection apiConnection, WorkflowPhases phase) - { - this.DisplayMessageInUi = displayMessageInUi; - this.userConfig = userConfig; - this.apiConnection = apiConnection; - this.Phase = phase; - } - - - public async Task Init(int viewOpt = 0) - { - ActionHandler = new ActionHandler(apiConnection, this); - await ActionHandler.Init(); - dbAcc = new RequestDbAccess(DisplayMessageInUi, userConfig, apiConnection, ActionHandler){}; - Devices = await apiConnection.SendQueryAsync>(FWO.Api.Client.Queries.DeviceQueries.getDeviceDetails); - await stateMatrixDict.Init(Phase, apiConnection); - MasterStateMatrix = stateMatrixDict.Matrices[TaskType.master.ToString()]; - TicketList = await dbAcc.FetchTickets(MasterStateMatrix, viewOpt); - PrioList = System.Text.Json.JsonSerializer.Deserialize>(userConfig.ReqPriorities) ?? throw new Exception("Config data could not be parsed."); - } - - public void FilterForRequester() - { - List filteredTicketList = new List(); - foreach(var ticket in TicketList) - { - if(userConfig.User.DbId == ticket.Requester?.DbId) - { - filteredTicketList.Add(ticket); - } - } - TicketList = filteredTicketList; - } - - public StateMatrix StateMatrix(string taskType) - { - return stateMatrixDict.Matrices[taskType]; - } - - public async Task AutoPromote(RequestStatefulObject statefulObject, RequestObjectScopes scope, int? toStateId) - { - bool promotePossible = false; - if(toStateId != null) - { - statefulObject.StateId = (int)toStateId; - promotePossible = true; - } - else - { - List possibleStates = ActStateMatrix.getAllowedTransitions(statefulObject.StateId); - if(possibleStates.Count == 1) - { - statefulObject.StateId = possibleStates[0]; - promotePossible = true; - } - } - - if(promotePossible) - { - switch(scope) - { - case RequestObjectScopes.Ticket: - SetTicketEnv((RequestTicket)statefulObject); - await PromoteTicket(statefulObject); - break; - case RequestObjectScopes.RequestTask: - SetReqTaskEnv((RequestReqTask)statefulObject); - ActReqTask.StateId = statefulObject.StateId; - ActReqTask.CurrentHandler = statefulObject.CurrentHandler; - await UpdateActReqTaskState(); - break; - case RequestObjectScopes.ImplementationTask: - SetImplTaskEnv((RequestImplTask)statefulObject); - ActImplTask.StateId = statefulObject.StateId; - ActImplTask.CurrentHandler = statefulObject.CurrentHandler; - await UpdateActImplTaskState(); - break; - case RequestObjectScopes.Approval: - if(SetReqTaskEnv(((RequestApproval)statefulObject).TaskId)) - { - await SetApprovalEnv(); - await ApproveTask(statefulObject); - } - break; - default: - break; - } - } - } - - public void SetContinueEnv(ObjAction action) - { - contOption = action; - } - - - // Tickets - - public void SelectTicket(RequestTicket ticket, ObjAction action) - { - SetTicketEnv(ticket); - SetTicketOpt(action); - } - - public void SetTicketEnv(RequestTicket ticket) - { - ActTicket = ticket; - ResetImplTaskList(); - ActStateMatrix = MasterStateMatrix; - } - - public void ResetImplTaskList() - { - AllImplTasks = new List(); - foreach(var reqTask in ActTicket.Tasks) - { - foreach(var implTask in reqTask.ImplementationTasks) - { - implTask.TicketId = ActTicket.Id; - implTask.ReqTaskId = reqTask.Id; - AllImplTasks.Add(implTask); - } - } - } - - public void SetTicketOpt(ObjAction action) - { - ResetTicketActions(); - DisplayTicketMode = (action == ObjAction.display || action == ObjAction.edit || action == ObjAction.add); - EditTicketMode = (action == ObjAction.edit || action == ObjAction.add); - AddTicketMode = action == ObjAction.add; - } - - public void SetTicketPopUpOpt(ObjAction action) - { - DisplayPromoteMode = action == ObjAction.displayPromote; - DisplaySaveTicketMode = action == ObjAction.displaySaveTicket; - } - - public void ResetTicketActions() - { - DisplayTicketMode = false; - EditTicketMode = false; - AddTicketMode = false; - DisplayPromoteMode = false; - DisplaySaveTicketMode = false; - } - - public async Task SaveTicket(RequestStatefulObject ticket) - { - try - { - ActTicket.StateId = ticket.StateId; - if (ActTicket.Sanitize()) - { - DisplayMessageInUi(null, userConfig.GetText("save_request"), userConfig.GetText("U0001"), true); - } - foreach(RequestReqTask reqTask in ActTicket.Tasks) - { - if(reqTask.StateId < ActTicket.StateId) - { - reqTask.StateId = ActTicket.StateId; - } - } - - if(ActTicket.Deadline == null) - { - int? tickDeadline = PrioList.FirstOrDefault(x => x.NumPrio == ActTicket.Priority)?.TicketDeadline; - ActTicket.Deadline = (tickDeadline != null && tickDeadline > 0 ? DateTime.Now.AddDays((int)tickDeadline) : null); - } - - if (AddTicketMode) - { - // insert new ticket - ActTicket.CreationDate = DateTime.Now; - ActTicket.Requester = userConfig.User; - ActTicket = await dbAcc.AddTicketToDb(ActTicket); - TicketList.Add(ActTicket); - } - else - { - // Update existing ticket - ActTicket = await dbAcc.UpdateTicketInDb(ActTicket); - TicketList[TicketList.FindIndex(x => x.Id == ActTicket.Id)] = ActTicket; - } - - // update of request tasks and creation of impl tasks may be necessary - foreach(RequestReqTask reqtask in ActTicket.Tasks) - { - if(reqtask.StateId <= ActTicket.StateId) - { - List ticketStateList = new List(); - ticketStateList.Add(ActTicket.StateId); - reqtask.StateId = stateMatrixDict.Matrices[reqtask.TaskType].getDerivedStateFromSubStates(ticketStateList); - await dbAcc.UpdateReqTaskStateInDb(reqtask); - } - if( reqtask.ImplementationTasks.Count == 0 && !stateMatrixDict.Matrices[reqtask.TaskType].PhaseActive[WorkflowPhases.planning] - && reqtask.StateId >= stateMatrixDict.Matrices[reqtask.TaskType].MinImplTasksNeeded) - { - await AutoCreateImplTasks(reqtask); - } - } - - //check for further promotion (req tasks may be promoted) - await UpdateActTicketStateFromReqTasks(); - - ResetTicketActions(); - } - catch (Exception exception) - { - DisplayMessageInUi(exception, userConfig.GetText("save_request"), "", true); - } - } - - public async Task PromoteTicket(RequestStatefulObject ticket) - { - try - { - ActTicket.StateId = ticket.StateId; - await UpdateActTicketState(); - ResetTicketActions(); - } - catch (Exception exception) - { - DisplayMessageInUi(exception, userConfig.GetText("promote_ticket"), "", true); - } - } - - - // Request Tasks - - public void SelectReqTask (RequestReqTask reqTask, ObjAction action) - { - SetReqTaskEnv(reqTask); - SetReqTaskMode(action); - } - - public void SelectReqTaskPopUp (RequestReqTask reqTask, ObjAction action) - { - SetReqTaskEnv(reqTask); - SetReqTaskPopUpOpt(action); - } - - public bool SetReqTaskEnv (long reqTaskId) - { - RequestReqTask? reqTask; - foreach(var ticket in TicketList) - { - reqTask = ticket.Tasks.FirstOrDefault(x => x.Id == reqTaskId); - if (reqTask != null) - { - SetReqTaskEnv(reqTask); - return true; - } - } - return false; - } - - public void SetReqTaskEnv (RequestReqTask reqTask) - { - ActReqTask = new RequestReqTask(reqTask); - RequestTicket? tick = TicketList.FirstOrDefault(x => x.Id == ActReqTask.TicketId); - if(tick != null) - { - ActTicket = tick; - } - ActStateMatrix = stateMatrixDict.Matrices[reqTask.TaskType]; - } - - public void SetReqTaskMode(ObjAction action) - { - ResetReqTaskActions(); - DisplayReqTaskMode = (action == ObjAction.display || action == ObjAction.edit || action == ObjAction.add || action == ObjAction.approve || action == ObjAction.plan); - EditReqTaskMode = (action == ObjAction.edit || action == ObjAction.add); - AddReqTaskMode = action == ObjAction.add; - PlanReqTaskMode = action == ObjAction.plan; - ApproveReqTaskMode = action == ObjAction.approve; - } - - public void SetReqTaskPopUpOpt(ObjAction action) - { - DisplayAssignMode = action == ObjAction.displayAssign; - DisplayApprovalMode = action == ObjAction.displayApprovals; - DisplayApproveMode = action == ObjAction.displayApprove; - DisplayPromoteMode = action == ObjAction.displayPromote; - DisplayDeleteMode = action == ObjAction.displayDelete; - DisplayCommentMode = action == ObjAction.displayComment; - DisplayPathAnalysisMode = action == ObjAction.displayPathAnalysis; - } - - public void ResetReqTaskActions() - { - DisplayReqTaskMode = false; - EditReqTaskMode = false; - AddReqTaskMode = false; - PlanReqTaskMode = false; - ApproveReqTaskMode = false; - - DisplayAssignMode = false; - DisplayApprovalMode = false; - DisplayApproveMode = false; - DisplayPromoteMode = false; - DisplayDeleteMode = false; - DisplayCommentMode = false; - DisplayPathAnalysisMode = false; - } - - public async Task StartWorkOnReqTask(RequestReqTask reqTask, ObjAction action) - { - SetReqTaskEnv(reqTask); - ActReqTask.CurrentHandler = userConfig.User; - List actPossibleStates = ActStateMatrix.getAllowedTransitions(ActReqTask.StateId); - if(actPossibleStates.Count == 1 && actPossibleStates[0] >= ActStateMatrix.LowestStartedState && actPossibleStates[0] < ActStateMatrix.LowestEndState) - { - ActReqTask.StateId = actPossibleStates[0]; - if(Phase == WorkflowPhases.approval) - { - await SetApprovalEnv(); - List nextApprovalState = ActStateMatrix.getAllowedTransitions(ActApproval.StateId); - if (nextApprovalState.Count == 1 && nextApprovalState[0] >= ActStateMatrix.LowestStartedState && nextApprovalState[0] < ActStateMatrix.LowestEndState) - { - ActApproval.StateId = nextApprovalState[0]; - await UpdateActApproval(); - } - } - } - await UpdateActReqTaskState(); - await UpdateActTicketStateFromReqTasks(); - SetReqTaskMode(action); - } - - public async Task ContinuePhase(RequestReqTask reqTask) - { - SelectReqTask(reqTask, contOption); - if(ActReqTask.CurrentHandler != userConfig.User) - { - ActReqTask.CurrentHandler = userConfig.User; - await UpdateActReqTaskState(); - } - } - - public async Task AssignReqTaskGroup(RequestStatefulObject statefulObject) - { - ActReqTask.AssignedGroup = statefulObject.AssignedGroup; - ActReqTask.RecentHandler = (ActReqTask.CurrentHandler != null ? ActReqTask.CurrentHandler : userConfig.User); - if(CheckAssignValues(ActReqTask)) - { - await UpdateActReqTaskState(); - } - DisplayAssignMode = false; - } - - public async Task AssignReqTaskBack() - { - ActReqTask.AssignedGroup = ActReqTask.RecentHandler?.Dn; - ActReqTask.RecentHandler = (ActReqTask.CurrentHandler != null ? ActReqTask.CurrentHandler : userConfig.User); - await UpdateActReqTaskState(); - DisplayAssignMode = false; - } - - public async Task AddReqTask() - { - if (ActTicket.Id > 0) // ticket already created -> write directly to db - { - ActReqTask.TicketId = ActTicket.Id; - ActReqTask.Id = await dbAcc.AddReqTaskToDb(ActReqTask); - } - ActTicket.Tasks.Add(ActReqTask); - } - - public async Task ChangeReqTask() - { - if(ActReqTask.Id > 0) - { - await dbAcc.UpdateReqTaskInDb(ActReqTask); - } - ActTicket.Tasks[ActTicket.Tasks.FindIndex(x => x.TaskNumber == ActReqTask.TaskNumber)] = ActReqTask; - } - - public async Task ConfDeleteReqTask() - { - if(ActReqTask.Id > 0) - { - await dbAcc.DeleteReqTaskFromDb(ActReqTask); - } - - ActTicket.Tasks.RemoveAll(x => x.Id == ActReqTask.Id); - // todo: adapt TaskNumbers of following tasks? - DisplayDeleteMode = false; - } - - public async Task ConfAddCommentToReqTask(string commentText) - { - RequestComment comment = new RequestComment() - { - Scope = RequestObjectScopes.RequestTask.ToString(), - CreationDate = DateTime.Now, - Creator = userConfig.User, - CommentText = commentText - }; - long commentId = await dbAcc.AddCommentToDb(comment); - if(commentId != 0) - { - await dbAcc.AssignCommentToReqTaskInDb(ActReqTask.Id, commentId); - } - ActReqTask.Comments.Add(new RequestCommentDataHelper(comment){}); - DisplayCommentMode = false; - } - - public async Task PromoteReqTask(RequestStatefulObject reqTask) - { - try - { - ActReqTask.StateId = reqTask.StateId; - if (ActReqTask.Start == null && ActReqTask.StateId >= ActStateMatrix.LowestStartedState) - { - ActReqTask.Start = DateTime.Now; - ActReqTask.CurrentHandler = userConfig.User; - } - await UpdateActReqTaskState(); - - if(Phase == WorkflowPhases.planning) - { - foreach(RequestImplTask implTask in ActReqTask.ImplementationTasks) - { - implTask.StateId = ActReqTask.StateId; - await dbAcc.UpdateImplTaskStateInDb(implTask); - } - } - - await UpdateActTicketStateFromReqTasks(); - DisplayPromoteMode = false; - } - catch (Exception exception) - { - DisplayMessageInUi(exception, userConfig.GetText("promote_task"), "", true); - } - } - - public async Task HandlePathAnalysisAction(string extParams = "") - { - try - { - PathAnalysisActionParams pathAnalysisParams = new PathAnalysisActionParams(); - if(extParams != "") - { - pathAnalysisParams = System.Text.Json.JsonSerializer.Deserialize(extParams) ?? throw new Exception("Extparams could not be parsed."); - } - - switch(pathAnalysisParams.Option) - { - case PathAnalysisOptions.WriteToDeviceList: - ActReqTask.SetDeviceList(await (new PathAnalysis(apiConnection)).getAllDevices(ActReqTask.Elements)); - break; - case PathAnalysisOptions.DisplayFoundDevices: - SetReqTaskPopUpOpt(ObjAction.displayPathAnalysis); - break; - default: - break; - } - } - catch (Exception exception) - { - DisplayMessageInUi(exception, userConfig.GetText("path_analysis"), "", true); - } - } - - // approvals - - public async Task SetApprovalEnv(RequestApproval? approval = null) - { - if(approval != null) - { - ActApproval = new RequestApproval(approval); - } - else - { - if(ActReqTask.Approvals.Count == 0) - { - await AddApproval(); - } - ActApproval = ActReqTask.Approvals.FirstOrDefault(x => x.StateId < ActStateMatrix.LowestEndState) ?? (ActApproval = ActReqTask.Approvals.Last()); // todo: select own approvals - } - } - - public void SetApprovalPopUpOpt(ObjAction action) - { - DisplayAssignApprovalMode = action == ObjAction.displayAssign; - DisplayCommentMode = action == ObjAction.displayComment; - } - - public async Task SelectApprovalPopUp (RequestApproval approval, ObjAction action) - { - await SetApprovalEnv(approval); - SetApprovalPopUpOpt(action); - } - - public void ResetApprovalActions() - { - DisplayAssignApprovalMode = false; - DisplayCommentMode = false; - } - - public async Task AddApproval(string extParams = "") - { - ApprovalParams approvalParams = new ApprovalParams(); - if(extParams != "") - { - approvalParams = System.Text.Json.JsonSerializer.Deserialize(extParams) ?? throw new Exception("Extparams could not be parsed."); - } - - DateTime? deadline = null; - if(extParams != "") - { - deadline = (approvalParams.Deadline > 0 ? DateTime.Now.AddDays(approvalParams.Deadline) : null); - } - else - { - int? appDeadline = PrioList.FirstOrDefault(x => x.NumPrio == ActTicket.Priority)?.ApprovalDeadline; - deadline = (appDeadline != null && appDeadline > 0 ? DateTime.Now.AddDays((int)appDeadline) : null); - } - - RequestApproval approval = new RequestApproval() - { - TaskId = ActReqTask.Id, - StateId = (extParams != "" ? approvalParams.StateId : ActStateMatrix.LowestEndState), - ApproverGroup = (extParams != "" ? approvalParams.ApproverGroup : ""), // todo: get from owner ???, - TenantId = ActTicket.TenantId, // ?? - Deadline = deadline, - InitialApproval = ActReqTask.Approvals.Count == 0 - }; - if(!approval.InitialApproval) - { - // todo: checks if new approval allowed (only one open per group?, ...) - approval.Id = await dbAcc.AddApprovalToDb(approval); - DisplayMessageInUi(null, userConfig.GetText("add_approval"), userConfig.GetText("U8002"), false); - } - ActReqTask.Approvals.Add(approval); - } - - public async Task ApproveTask(RequestStatefulObject approval) - { - try - { - ActApproval.StateId = approval.StateId; - if(ActApproval.StateId >= ActStateMatrix.LowestEndState) - { - ActApproval.ApprovalDate = DateTime.Now; - ActApproval.ApproverDn = userConfig.User.Dn; - } - if(approval.OptComment() != null && approval.OptComment() != "") - { - await ConfAddCommentToApproval(approval.OptComment()!); - } - - if (ActApproval.Sanitize()) - { - DisplayMessageInUi(null, userConfig.GetText("save_approval"), userConfig.GetText("U0001"), true); - } - await UpdateActApproval(); - await UpdateActReqTaskStateFromApprovals(); - ActTicket.Tasks[ActTicket.Tasks.FindIndex(x => x.Id == ActReqTask.Id)] = ActReqTask; - await UpdateActTicketStateFromReqTasks(); - ApproveReqTaskMode = false; - DisplayApproveMode = false; - } - catch (Exception exception) - { - DisplayMessageInUi(exception, userConfig.GetText("save_approval"), "", true); - } - } - - public async Task AssignApprovalGroup(RequestStatefulObject statefulObject) - { - ActApproval.AssignedGroup = statefulObject.AssignedGroup; - // ActApproval.RecentHandler = ActApproval.CurrentHandler; - if(CheckAssignValues(ActApproval)) - { - await UpdateActApproval(); - } - DisplayAssignApprovalMode = false; - } - - // public async Task AssignApprovalBack() - // { - // ActApproval.AssignedGroup = ActApproval.RecentHandler?.Dn; - // ActApproval.RecentHandler = ActApproval.CurrentHandler; - // await UpdateActApproval(); - // DisplayAssignApprovalMode = false; - // } - - public async Task ConfAddCommentToApproval(string commentText) - { - RequestComment comment = new RequestComment() - { - Scope = RequestObjectScopes.Approval.ToString(), - CreationDate = DateTime.Now, - Creator = userConfig.User, - CommentText = commentText - }; - long commentId = await dbAcc.AddCommentToDb(comment); - if(commentId != 0) - { - await dbAcc.AssignCommentToApprovalInDb(ActApproval.Id, commentId); - } - ActApproval.Comments.Add(new RequestCommentDataHelper(comment){}); - DisplayCommentMode = false; - } - - - // Implementation Tasks - - public void SelectImplTask(RequestImplTask implTask, ObjAction action) - { - SetImplTaskEnv(implTask); - SetImplTaskOpt(action); - } - - public void SelectImplTaskPopUp (RequestImplTask implTask, ObjAction action) - { - SetImplTaskEnv(implTask); - SetImplTaskPopUpOpt(action); - } - - public void SetImplTaskEnv(RequestImplTask implTask) - { - ActImplTask = new RequestImplTask(implTask); - RequestTicket? tick = TicketList.FirstOrDefault(x => x.Id == ActImplTask.TicketId); - if(tick != null) - { - ActTicket = tick; - RequestReqTask? reqTask = ActTicket.Tasks.FirstOrDefault(x => x.Id == ActImplTask.ReqTaskId); - if(reqTask != null) - { - ActReqTask = reqTask; - } - } - ActStateMatrix = stateMatrixDict.Matrices[implTask.TaskType]; - } - - public void SetImplTaskOpt(ObjAction action) - { - ResetImplTaskActions(); - DisplayImplTaskMode = (action == ObjAction.display || action == ObjAction.edit || action == ObjAction.add || action == ObjAction.implement); - EditImplTaskMode = (action == ObjAction.edit || action == ObjAction.add); - AddImplTaskMode = action == ObjAction.add; - ImplementImplTaskMode = action == ObjAction.implement; - } - - public void SetImplTaskPopUpOpt(ObjAction action) - { - DisplayPromoteMode = action == ObjAction.displayPromote; - DisplayDeleteMode = action == ObjAction.displayDelete; - DisplayCleanupMode = action == ObjAction.displayCleanup; - DisplayAssignMode = action == ObjAction.displayAssign; - DisplayCommentMode = action == ObjAction.displayComment; - DisplayApprovalMode = action == ObjAction.displayApprovals; - } - - public void ResetImplTaskActions() - { - DisplayImplTaskMode = false; - EditImplTaskMode = false; - AddImplTaskMode = false; - ImplementImplTaskMode = false; - - DisplayPromoteMode = false; - DisplayDeleteMode = false; - DisplayCleanupMode = false; - DisplayAssignMode = false; - DisplayCommentMode = false; - DisplayApprovalMode = false; - } - - public async Task StartWorkOnImplTask(RequestImplTask implTask, ObjAction action) - { - SetImplTaskEnv(implTask); - ActImplTask.CurrentHandler = userConfig.User; - List actPossibleStates = ActStateMatrix.getAllowedTransitions(ActImplTask.StateId); - if(actPossibleStates.Count == 1 && actPossibleStates[0] >= ActStateMatrix.LowestStartedState && actPossibleStates[0] < ActStateMatrix.LowestEndState) - { - ActImplTask.StateId = actPossibleStates[0]; - } - await UpdateActImplTaskState(); - if(!ActStateMatrix.PhaseActive[WorkflowPhases.planning] && ActReqTask.Start == null) - { - ActReqTask.Start = ActImplTask.Start; - } - await UpdateActTicketStateFromImplTasks(); - SetImplTaskOpt(action); - } - - public async Task ContinueImplPhase(RequestImplTask implTask) - { - SelectImplTask(implTask, contOption); - if(ActImplTask.CurrentHandler != userConfig.User) - { - ActImplTask.CurrentHandler = userConfig.User; - await UpdateActImplTaskState(); - } - } - - public async Task AssignImplTaskGroup(RequestStatefulObject statefulObject) - { - ActImplTask.AssignedGroup = statefulObject.AssignedGroup; - ActImplTask.RecentHandler = (ActImplTask.CurrentHandler != null ? ActImplTask.CurrentHandler : userConfig.User); - if(CheckAssignValues(ActImplTask)) - { - await UpdateActImplTaskState(); - } - DisplayAssignMode = false; - } - - public async Task AssignImplTaskBack() - { - ActImplTask.AssignedGroup = ActImplTask.RecentHandler?.Dn; - ActImplTask.RecentHandler = (ActImplTask.CurrentHandler != null ? ActImplTask.CurrentHandler : userConfig.User); - await UpdateActImplTaskState(); - DisplayAssignMode = false; - } - - public async Task AddImplTask() - { - ActImplTask.Id = await dbAcc.AddImplTaskToDb(ActImplTask); - ActReqTask.ImplementationTasks.Add(ActImplTask); - } - - public async Task ChangeImplTask() - { - await dbAcc.UpdateImplTaskInDb(ActImplTask); - ActReqTask.ImplementationTasks[ActReqTask.ImplementationTasks.FindIndex(x => x.TaskNumber == ActImplTask.TaskNumber)] = ActImplTask; - } - - public async Task ConfAddCommentToImplTask(string commentText) - { - RequestComment comment = new RequestComment() - { - Scope = RequestObjectScopes.ImplementationTask.ToString(), - CreationDate = DateTime.Now, - Creator = userConfig.User, - CommentText = commentText - }; - long commentId = await dbAcc.AddCommentToDb(comment); - if(commentId != 0) - { - await dbAcc.AssignCommentToImplTaskInDb(ActImplTask.Id, commentId); - } - ActImplTask.Comments.Add(new RequestCommentDataHelper(comment){}); - DisplayCommentMode = false; - } - - public async Task PromoteImplTask(RequestStatefulObject implTask) - { - try - { - ActImplTask.StateId = implTask.StateId; - ActImplTask.CurrentHandler = userConfig.User; - if (Phase == WorkflowPhases.implementation && ActImplTask.Stop == null && ActImplTask.StateId >= ActStateMatrix.LowestEndState) - { - ActImplTask.Stop = DateTime.Now; - } - await UpdateActImplTaskState(); - ResetImplTaskList(); - SyncReqTaskStopTime(); - await UpdateReqTaskStateFromImplTasks(ActReqTask); - await UpdateActTicketStateFromReqTasks(); - DisplayPromoteMode = false; - } - catch (Exception exception) - { - DisplayMessageInUi(exception, userConfig.GetText("save_task"), "", true); - } - } - - public void SyncReqTaskStopTime() - { - bool openImplTask = false; - foreach(var impltask in ActReqTask.ImplementationTasks) - { - if(impltask.Stop == null) - { - openImplTask = true; - } - } - if(!openImplTask && ActReqTask.Stop == null) - { - ActReqTask.Stop = ActImplTask.Stop; - } - } - - public async Task ConfDeleteImplTask() - { - await dbAcc.DeleteImplTaskFromDb(ActImplTask); - ActReqTask.ImplementationTasks.RemoveAt(ActReqTask.ImplementationTasks.FindIndex(x => x.Id == ActImplTask.Id)); - DisplayDeleteMode = false; - } - - public async Task ConfCleanupImplTasks() - { - foreach(var impltask in ActReqTask.ImplementationTasks) - { - await dbAcc.DeleteImplTaskFromDb(impltask); - } - ActReqTask.ImplementationTasks.Clear(); - DisplayCleanupMode = false; - } - - private async Task AutoCreateOrUpdateImplTasks() - { - if(Phase <= WorkflowPhases.approval && !MasterStateMatrix.PhaseActive[WorkflowPhases.planning] - && ActTicket.StateId >= MasterStateMatrix.LowestEndState) - { - foreach(var reqTask in ActTicket.Tasks) - { - // Todo: further analysis how many impl tasks currently have to be there and create or update where needed - if(reqTask.ImplementationTasks.Count == 0 - && reqTask.StateId >= stateMatrixDict.Matrices[reqTask.TaskType].MinImplTasksNeeded) - { - await AutoCreateImplTasks(reqTask); - } - else - { - foreach(var impltask in reqTask.ImplementationTasks) - { - if (impltask.StateId < reqTask.StateId) - { - impltask.StateId = reqTask.StateId; - await dbAcc.UpdateImplTaskStateInDb(impltask); - } - } - } - } - } - } - - private async Task AutoCreateImplTasks(RequestReqTask reqTask) - { - RequestImplTask newImplTask; - if(reqTask.TaskType == TaskType.access.ToString()) - { - switch (userConfig.ReqAutoCreateImplTasks) - { - case AutoCreateImplTaskOptions.never: - break; - case AutoCreateImplTaskOptions.onlyForOneDevice: - if(Devices.Count > 0) - { - await createAccessImplTask(reqTask, Devices[0].Id, false); - } - break; - case AutoCreateImplTaskOptions.forEachDevice: - foreach(var device in Devices) - { - await createAccessImplTask(reqTask, device.Id); - } - break; - case AutoCreateImplTaskOptions.enterInReqTask: - foreach(var deviceId in reqTask.getDeviceList()) - { - await createAccessImplTask(reqTask, deviceId); - } - break; - case AutoCreateImplTaskOptions.afterPathAnalysis: - await CreateAccessImplTasksFromPathAnalysis(reqTask); - break; - default: - break; - } - } - else - { - newImplTask = new RequestImplTask(reqTask) - { TaskNumber = reqTask.HighestImplTaskNumber() + 1, StateId = reqTask.StateId }; - newImplTask.Id = await dbAcc.AddImplTaskToDb(newImplTask); - reqTask.ImplementationTasks.Add(newImplTask); - } - } - - public async Task CreateAccessImplTasksFromPathAnalysis(RequestReqTask reqTask) - { - foreach(var device in await (new PathAnalysis(apiConnection)).getAllDevices(reqTask.Elements)) - { - if(reqTask.ImplementationTasks.FirstOrDefault(x => x.DeviceId == device.Id) == null) - { - await createAccessImplTask(reqTask, device.Id); - } - } - } - - private async Task createAccessImplTask(RequestReqTask reqTask, int deviceId, bool adaptTitle=true) - { - RequestImplTask newImplTask; - newImplTask = new RequestImplTask(reqTask) - { TaskNumber = reqTask.HighestImplTaskNumber() + 1, DeviceId = deviceId, StateId = reqTask.StateId }; - if(adaptTitle) - { - newImplTask.Title += ": "+ Devices[Devices.FindIndex(x => x.Id == deviceId)].Name; - } - newImplTask.Id = await dbAcc.AddImplTaskToDb(newImplTask); - reqTask.ImplementationTasks.Add(newImplTask); - } - - - // State changes - - public async Task UpdateActImplTaskState() - { - await dbAcc.UpdateImplTaskStateInDb(ActImplTask); - int index = ActReqTask.ImplementationTasks.FindIndex(x => x.Id == ActImplTask.Id); - if(index >= 0) - { - ActReqTask.ImplementationTasks[index] = ActImplTask; - } - else - { - // due to actions the impl task may not be assigned - ActReqTask.ImplementationTasks.Add(ActImplTask); - } - } - - public async Task UpdateActApproval() - { - await dbAcc.UpdateApprovalInDb(ActApproval); - ActReqTask.Approvals[ActReqTask.Approvals.FindIndex(x => x.Id == ActApproval.Id)] = ActApproval; - } - - public async Task UpdateActReqTaskStateFromApprovals() - { - if (ActReqTask.Approvals.Count > 0) - { - List approvalStates = new List(); - foreach (var approval in ActReqTask.Approvals) - { - approvalStates.Add(approval.StateId); - } - ActReqTask.StateId = ActStateMatrix.getDerivedStateFromSubStates(approvalStates); - } - await UpdateActReqTaskState(); - - // in the case impl tasks are already existing - foreach(var implTask in ActReqTask.ImplementationTasks) - { - implTask.StateId = ActReqTask.StateId; - await dbAcc.UpdateImplTaskInDb(implTask); - } - } - - public async Task UpdateReqTaskStateFromImplTasks(RequestReqTask reqTask) - { - if (reqTask.ImplementationTasks.Count > 0) - { - List implTaskStates = new List(); - foreach (var implTask in reqTask.ImplementationTasks) - { - implTaskStates.Add(implTask.StateId); - } - reqTask.StateId = ActStateMatrix.getDerivedStateFromSubStates(implTaskStates); - } - await dbAcc.UpdateReqTaskStateInDb(reqTask); - } - - public async Task UpdateActReqTaskState() - { - await dbAcc.UpdateReqTaskStateInDb(ActReqTask); - ActTicket.Tasks[ActTicket.Tasks.FindIndex(x => x.Id == ActReqTask.Id)] = ActReqTask; - } - - public async Task UpdateActTicketStateFromImplTasks() - { - List taskStates = new List(); - foreach (RequestReqTask reqTask in ActTicket.Tasks) - { - await UpdateReqTaskStateFromImplTasks(reqTask); - } - await UpdateActTicketStateFromReqTasks(); - } - - public async Task UpdateActTicketStateFromReqTasks() - { - if (ActTicket.Tasks.Count > 0) - { - List taskStates = new List(); - foreach (RequestReqTask tsk in ActTicket.Tasks) - { - taskStates.Add(tsk.StateId); - } - ActTicket.StateId = MasterStateMatrix.getDerivedStateFromSubStates(taskStates); - } - await UpdateActTicketState(); - } - - public async Task UpdateActTicketState() - { - if (MasterStateMatrix.IsLastActivePhase && ActTicket.StateId >= MasterStateMatrix.LowestEndState) - { - ActTicket.CompletionDate = DateTime.Now; - } - await AutoCreateOrUpdateImplTasks(); - await dbAcc.UpdateTicketStateInDb(ActTicket); - TicketList[TicketList.FindIndex(x => x.Id == ActTicket.Id)] = ActTicket; - } - - - // checks - - public async Task CheckRuleUid(int? deviceId, string? ruleUid) - { - return await dbAcc.FindRuleUid(deviceId, ruleUid); - } - - private bool CheckAssignValues(RequestStatefulObject statefulObject) - { - // if (statefulObject.AssignedGroup == null || statefulObject.AssignedGroup == "") - // { - // DisplayMessageInUi(null, userConfig.GetText("assign_group"), userConfig.GetText("E8010"), true); - // return false; - // } - return true; - } - } -} diff --git a/roles/ui/files/FWO.UI/Services/RoleAccess.cs b/roles/ui/files/FWO.UI/Services/RoleAccess.cs index aa245c083a..73c7ba55f5 100644 --- a/roles/ui/files/FWO.UI/Services/RoleAccess.cs +++ b/roles/ui/files/FWO.UI/Services/RoleAccess.cs @@ -1,8 +1,9 @@ -using System.Net; -using FWO.Api.Data; +using FWO.Basics; +using FWO.Data; +using FWO.Data.Middleware; using FWO.Middleware.Client; -using FWO.Middleware.RequestParameters; using RestSharp; +using System.Net; namespace FWO.Ui.Services { @@ -10,13 +11,13 @@ public class RoleAccess { static public async Task> GetRolesFromInternalLdap(MiddlewareClient middlewareClient) { - List roles = new List(); + List roles = new(); RestResponse> middlewareServerResponse = await middlewareClient.GetAllRoles(); if (middlewareServerResponse.StatusCode == HttpStatusCode.OK && middlewareServerResponse.Data != null) { foreach (var ldapRole in middlewareServerResponse.Data) { - Role role = new Role() { Dn = ldapRole.Role, Name = (new DistName(ldapRole.Role)).Role }; + Role role = new() { Dn = ldapRole.Role, Name = new DistName(ldapRole.Role).Role }; foreach (var roleAttr in ldapRole.Attributes) { if (roleAttr.Key == "description") @@ -25,7 +26,7 @@ static public async Task> GetRolesFromInternalLdap(MiddlewareClient m } else if (roleAttr.Key == "user") { - UiUser newUser = new UiUser() { Dn = roleAttr.Value, Name = (new DistName(roleAttr.Value)).UserName }; + UiUser newUser = new() { Dn = roleAttr.Value, Name = new DistName(roleAttr.Value).UserName }; role.Users.Add(newUser); } } @@ -37,10 +38,10 @@ static public async Task> GetRolesFromInternalLdap(MiddlewareClient m static public async Task> GetRoleMembers(MiddlewareClient middlewareClient, string roleName) { - List users = new List(); + List users = new(); List roles = await GetRolesFromInternalLdap(middlewareClient); Role? role = roles.FirstOrDefault(x => x.Name == roleName); - if(role != null) + if (role != null) { users = role.Users; } diff --git a/roles/ui/files/FWO.UI/Services/TicketCreator.cs b/roles/ui/files/FWO.UI/Services/TicketCreator.cs deleted file mode 100644 index 0b649ab22f..0000000000 --- a/roles/ui/files/FWO.UI/Services/TicketCreator.cs +++ /dev/null @@ -1,104 +0,0 @@ -using System.Text.Json; -using FWO.Api.Data; -using FWO.Config.Api; -using FWO.Api.Client; -using FWO.Logging; - -namespace FWO.Ui.Services -{ - public class TicketCreator - { - private RequestHandler reqHandler; - private UserConfig userConfig; - private int stateId; - private string ticketTitle = ""; - private string ticketReason = ""; - private string taskTitle = ""; - private string taskReason = ""; - private int priority; - - - public TicketCreator(ApiConnection apiConnection, UserConfig userConfig) - { - reqHandler = new RequestHandler(LogMessage, userConfig, apiConnection, WorkflowPhases.request); - this.userConfig = userConfig; - } - - public async Task CreateDecertRuleDeleteTicket(int deviceId, List ruleUids, string comment = "", DateTime? deadline = null) - { - stateId = userConfig.RecDeleteRuleInitState; - ticketTitle = userConfig.RecDeleteRuleTicketTitle + " "; - ticketReason = userConfig.RecDeleteRuleTicketReason + " " + comment; - taskTitle = userConfig.RecDeleteRuleReqTaskTitle; - taskReason = userConfig.RecDeleteRuleReqTaskReason; - priority = userConfig.RecDeleteRuleTicketPriority; - await CreateRuleDeleteTicket(deviceId, ruleUids, comment, deadline); - } - - public async Task CreateUnusedRuleDeleteTicket(int deviceId, List ruleUids, string comment = "", DateTime? deadline = null) - { - stateId = userConfig.RecDeleteRuleInitState; - ticketTitle = userConfig.GetText("delete_unused_rules") + ": "; - ticketReason = comment; - taskTitle = userConfig.GetText("delete_unused_rule"); - taskReason = ""; - priority = userConfig.RecDeleteRuleTicketPriority; - await CreateRuleDeleteTicket(deviceId, ruleUids, comment, deadline); - } - - private async Task CreateRuleDeleteTicket(int deviceId, List ruleUids, string comment = "", DateTime? deadline = null) - { - await reqHandler.Init(); - reqHandler.ActTicket = new RequestTicket() - { - StateId = stateId, - Title = ticketTitle + reqHandler.Devices.FirstOrDefault(x => x.Id == deviceId)?.Name ?? "", - Requester = userConfig.User, - Reason = ticketReason, - Priority = priority, - Deadline = deadline - }; - foreach(var ruleUid in ruleUids) - { - reqHandler.ActReqTask = new RequestReqTask() - { - StateId = stateId, - Title = taskTitle + " " + ruleUid, - TaskType = TaskType.rule_delete.ToString(), - RequestAction = RequestAction.delete.ToString(), - Reason = taskReason - }; - reqHandler.ActReqTask.Elements.Add(new RequestReqElement() - { - Field = ElemFieldType.rule.ToString(), - RequestAction = RequestAction.delete.ToString(), - DeviceId = deviceId, - RuleUid = ruleUid - }); - await reqHandler.AddApproval(JsonSerializer.Serialize(new ApprovalParams(){StateId = stateId})); - reqHandler.ActTicket.Tasks.Add(reqHandler.ActReqTask); - } - reqHandler.AddTicketMode = true; - await reqHandler.SaveTicket(reqHandler.ActTicket); - } - - private void LogMessage(Exception? exception = null, string title = "", string message = "", bool ErrorFlag = false) - { - if (exception == null) - { - if(ErrorFlag) - { - Log.WriteWarning(title, message); - } - else - { - Log.WriteInfo(title, message); - } - } - else - { - Log.WriteError(title, message, exception); - } - } - } -} diff --git a/roles/ui/files/FWO.UI/Services/UrlSanitizer.cs b/roles/ui/files/FWO.UI/Services/UrlSanitizer.cs new file mode 100644 index 0000000000..1a63f19af0 --- /dev/null +++ b/roles/ui/files/FWO.UI/Services/UrlSanitizer.cs @@ -0,0 +1,165 @@ +using System.Diagnostics.CodeAnalysis; +using System.Text; +using System.Web; +using FWO.Basics; +using FWO.Logging; +using System.Text.RegularExpressions; + +namespace FWO.Ui.Services +{ + public sealed partial class UrlSanitizer : IUrlSanitizer + { + private const char PathDelimiter = '/'; + private const string HelpPathPrefix = "/help"; + + + public string? Clean(string input) + { + if (string.IsNullOrWhiteSpace(input)) + { + BlockingUrlLog(input); + return null; + } + + string decoded = DecodeInput(input); + if (ContainsDisallowedPatterns(decoded)) + { + return BlockAndReturnNull(input); + } + if (!TryCreateAbsoluteUri(decoded, out var uri)) + { + return BlockAndReturnNull(input); + } + if (!IsAllowedScheme(uri)) + { + return BlockAndReturnNull(input); + } + if (!IsHelpPathAllowed(uri)) + { + return BlockAndReturnNull(input); + } + var sanitizedPath = SanitizePath(uri); + var sanitizedQuery = SanitizeQuery(uri); + var sanitizedUrl = BuildSanitizedUrl(uri, sanitizedPath, sanitizedQuery); + + if (sanitizedUrl.Length > 2048) + { + return BlockAndReturnNull(input); + } + return sanitizedUrl; + } + + private static void BlockingUrlLog(string url) + { + Log.WriteWarning("Sanitizer", $"Blocked unsafe URL: {url.SanitizeMand()}"); + } + + private static string DecodeInput(string input) + { + var normalizedInput = input.Trim().Normalize(NormalizationForm.FormC); + var decoded = HttpUtility.UrlDecode(normalizedInput); + return HttpUtility.HtmlDecode(decoded) ?? string.Empty; + } + + private static bool ContainsDisallowedPatterns(string decoded) => + ScriptTagRegex().IsMatch(decoded) || + EventHandlerAttributeRegex().IsMatch(decoded) || + JavascriptSchemeRegex().IsMatch(decoded) || + DangerousHtmlTagRegex().IsMatch(decoded); + + private static bool TryCreateAbsoluteUri(string decoded, [NotNullWhen(true)] out Uri? uri) => + Uri.TryCreate(decoded, UriKind.Absolute, out uri); + + private static bool IsAllowedScheme(Uri uri) + { + var scheme = uri.Scheme.ToLowerInvariant(); + return scheme is "http" or "https"; + } + + private static bool IsHelpPathAllowed(Uri uri) + { + if (!uri.AbsolutePath.StartsWith(HelpPathPrefix, StringComparison.OrdinalIgnoreCase)) + return true; + + var decodedPathAndQuery = HttpUtility.UrlDecode(uri.PathAndQuery) ?? string.Empty; + return HelpPathWhitelistRegex().IsMatch(decodedPathAndQuery); + } + + private static string SanitizePath(Uri uri) + { + var sanitizedPath = string.Join(PathDelimiter, uri.Segments + .Select(s => HttpUtility.UrlEncode( + HttpUtility.UrlDecode(s.TrimEnd('/')) + ))); + if (!sanitizedPath.StartsWith(PathDelimiter.ToString())) + { + sanitizedPath = PathDelimiter + sanitizedPath; + } + + return sanitizedPath; + } + + private static string SanitizeQuery(Uri uri) + { + var queryParams = HttpUtility.ParseQueryString(uri.Query); + var sanitizedQuery = new StringBuilder(); + + foreach (string key in queryParams) + { + if (key == null) + continue; + + if (sanitizedQuery.Length > 0) + sanitizedQuery.Append('&'); + + sanitizedQuery.Append(HttpUtility.UrlEncode(key)); + sanitizedQuery.Append('='); + + var value = queryParams[key]; + if (value != null) + { + value = QueryTagRegex().Replace(value, string.Empty); + } + sanitizedQuery.Append(HttpUtility.UrlEncode(value)); + } + + return sanitizedQuery.ToString(); + } + + private static string BuildSanitizedUrl(Uri uri, string sanitizedPath, string sanitizedQuery) + { + var builder = new UriBuilder(uri) + { + Path = sanitizedPath, + Fragment = string.Empty, + Query = sanitizedQuery + }; + return builder.Uri.AbsoluteUri; + } + + private static string? BlockAndReturnNull(string rawInput) + { + BlockingUrlLog(rawInput); + return null; + } + + [GeneratedRegex(@"<\s*script\b", RegexOptions.IgnoreCase, "en-US")] + private static partial Regex ScriptTagRegex(); + + [GeneratedRegex(@"on\w+\s*=", RegexOptions.IgnoreCase, "en-US")] + private static partial Regex EventHandlerAttributeRegex(); + + [GeneratedRegex(@"javascript\s*:", RegexOptions.IgnoreCase, "en-US")] + private static partial Regex JavascriptSchemeRegex(); + + [GeneratedRegex(@"<\s*/?\s*(a|img|iframe|svg|object|embed|link|meta|style|body|html|form|input|video|audio)\b", RegexOptions.IgnoreCase, "en-US")] + private static partial Regex DangerousHtmlTagRegex(); + + [GeneratedRegex(@"^[a-zA-Z0-9/_\-\.\?\&=,:;]*$", RegexOptions.IgnoreCase, "en-US")] + private static partial Regex HelpPathWhitelistRegex(); + + [GeneratedRegex(@"<[^>]*>", RegexOptions.IgnoreCase, "en-US")] + private static partial Regex QueryTagRegex(); + } + +} diff --git a/roles/ui/files/FWO.UI/Services/UrlSanizerMiddleware.cs b/roles/ui/files/FWO.UI/Services/UrlSanizerMiddleware.cs new file mode 100644 index 0000000000..0591f113b0 --- /dev/null +++ b/roles/ui/files/FWO.UI/Services/UrlSanizerMiddleware.cs @@ -0,0 +1,31 @@ +namespace FWO.Ui.Services +{ + public sealed class UrlSanitizerMiddleware + { + private readonly RequestDelegate _next; + private readonly IUrlSanitizer _sanitizer; + + public UrlSanitizerMiddleware(RequestDelegate next, IUrlSanitizer sanitizer) + { + _next = next ?? throw new ArgumentNullException(nameof(next)); + _sanitizer = sanitizer ?? throw new ArgumentNullException(nameof(sanitizer)); + } + + public async Task InvokeAsync(HttpContext context) + { + // Build ABSOLUTE URL because Clean expects absolute + var req = context.Request; + var absolute = $"{req.Scheme}://{req.Host}{req.Path}{req.QueryString}"; + + var sanitized = _sanitizer.Clean(absolute); + if (sanitized is null) + { + context.Response.StatusCode = 400; + await context.Response.WriteAsync("Invalid or unsafe URL."); + return; + } + + await _next(context); + } + } +} diff --git a/roles/ui/files/FWO.UI/Shared/AnchorNavToRSB.razor b/roles/ui/files/FWO.UI/Shared/AnchorNavToRSB.razor index 34465b3c2e..4dc16ef346 100644 --- a/roles/ui/files/FWO.UI/Shared/AnchorNavToRSB.razor +++ b/roles/ui/files/FWO.UI/Shared/AnchorNavToRSB.razor @@ -1,10 +1,18 @@ +@using System.Text.RegularExpressions + @inject IJSRuntime JSRuntime @inject NavigationManager NavigationManager +@inject UserConfig userConfig + @implements IDisposable + @code { [Parameter] public FWO.Ui.Shared.TabSet TabSet { get; set; } = default!; + [Parameter] + public FWO.Ui.Data.CollapseState CollapseState { get; set; } = default!; + protected override void OnInitialized() { NavigationManager.LocationChanged += OnLocationChanged; @@ -13,7 +21,7 @@ protected override async Task OnAfterRenderAsync(bool firstRender) { if (firstRender) - await ScrollToFragment(GetIdFromURI()); + await NavigateAndScrollToFragment(); } public void Dispose() @@ -23,16 +31,17 @@ private async void OnLocationChanged(object? sender, LocationChangedEventArgs e) { - await ScrollToFragment(GetIdFromURI()); + await NavigateAndScrollToFragment(); } /// The html element id to an object in the right side bar. /// /// Expects the URI to contain link to rsb object in form of #goto-{obj-link}. Example URI: localhost/report#goto-report-m8-nwobj31473 /// - private string GetIdFromURI() + private async Task GetIdFromURI() { - var uri = new Uri(NavigationManager.Uri, UriKind.Absolute); + var currentUrl = await JSRuntime.InvokeAsync("getCurrentUrl"); + var uri = new Uri(currentUrl, UriKind.Absolute); var fragment = uri.Fragment; if (fragment.StartsWith("#goto-")) { @@ -47,45 +56,53 @@ return elementId.Substring(5); } return ""; + //NOTE: cannot use NavigationManager.GetUri() since it does not reflect change made by JS (removing the fragment) + // cannot remove fragment in URI with NavigationManager since it will result in a scroll to top } - private async Task ScrollToFragment(string elementId) + public async Task NavigateAndScrollToFragment() { + if (CollapseState == null || !CollapseState.HasExpandSubscribers) + return; // collapses not fully rendered yet + + string elementId = await GetIdFromURI(); + if (!string.IsNullOrEmpty(elementId)) { var uri = new Uri(NavigationManager.Uri, UriKind.Absolute); - // check if current page is certification page - bool recertPage = uri.AbsolutePath == "/certification"; + // need to check if recert page since tabs are different + bool recertPage = uri.AbsolutePath == $"/{PageName.Certification}"; if (elementId.StartsWith("all")) - TabSet?.SetActiveTab(0); + TabSet?.SetActiveTab(TabSet.Tabs.Where(t => t.Title == userConfig.GetText("all")).FirstOrDefault()); else if (elementId.StartsWith("report")) - TabSet?.SetActiveTab(recertPage ? 0 : 1); + TabSet?.SetActiveTab(TabSet.Tabs.Where(t => t.Title == userConfig.GetText("report")).FirstOrDefault()); else if (elementId.StartsWith("rule")) - TabSet?.SetActiveTab(recertPage ? 1 : 2); + TabSet?.SetActiveTab(TabSet.Tabs.Where(t => t.Title == userConfig.GetText("rule")).FirstOrDefault()); else return; - - bool foundObj = await JSRuntime.InvokeAsync("scrollIntoRSBView", elementId); - if (foundObj) - { - // remove #goto-{obj-link} fragment from uri - UriBuilder ub = new(uri); - ub.Fragment = ""; - NavigationManager.NavigateTo(ub.Uri.AbsoluteUri); - } + CollapseState.Expand(elementId); + + await ScrollToFragment(elementId); } } - public async Task ScrollToFragmentIfMatch(string idPrefixMatch) + public async Task ScrollToFragment(string? elementId = null) { - string elementId = GetIdFromURI(); - - if (elementId.StartsWith(idPrefixMatch)) + if (elementId == null) + elementId = await GetIdFromURI(); + + if (!string.IsNullOrEmpty(elementId)) { - await ScrollToFragment(elementId); + bool foundObj = await JSRuntime.InvokeAsync("scrollIntoRSBView", elementId); + + if (foundObj) + { + // remove #goto-{obj-link} fragment from uri + await JSRuntime.InvokeVoidAsync("removeUrlFragment"); + } } } } \ No newline at end of file diff --git a/roles/ui/files/FWO.UI/Shared/AppRoleTable.razor b/roles/ui/files/FWO.UI/Shared/AppRoleTable.razor new file mode 100644 index 0000000000..e3d1a19166 --- /dev/null +++ b/roles/ui/files/FWO.UI/Shared/AppRoleTable.razor @@ -0,0 +1,50 @@ +@using FWO.Data.Modelling +@using FWO.Data.Report +@using FWO.Ui.Display + +@inject UserConfig userConfig + + + + + + + @if(Split) + { + + + + + + + } + else + { + + + + } + +
                      + + +@code +{ + [Parameter] + public List AppRoles { get; set; } = []; + + [Parameter] + public bool DiffMode { get; set; } = false; + + [Parameter] + public bool Split { get; set; } = false; +} diff --git a/roles/ui/files/FWO.UI/Shared/AppZoneTable.razor b/roles/ui/files/FWO.UI/Shared/AppZoneTable.razor new file mode 100644 index 0000000000..ba425af94d --- /dev/null +++ b/roles/ui/files/FWO.UI/Shared/AppZoneTable.razor @@ -0,0 +1,22 @@ +@using FWO.Data.Modelling +@using FWO.Data.Report +@using FWO.Ui.Display + +@inject UserConfig userConfig + + + + + + + +
                      + + +@code +{ + [Parameter] + public List AppZones { get; set; } = []; +} diff --git a/roles/ui/files/FWO.UI/Shared/AutoDiscovery.razor b/roles/ui/files/FWO.UI/Shared/AutoDiscovery.razor index cf6f37875a..7b6d871a54 100644 --- a/roles/ui/files/FWO.UI/Shared/AutoDiscovery.razor +++ b/roles/ui/files/FWO.UI/Shared/AutoDiscovery.razor @@ -1,21 +1,18 @@ -@using BlazorTable -@using FWO.Config.Api -@using FWO.Api.Data -@using FWO.Api.Client +@using FWO.Data.Logging +@using FWO.Services.Logging @using System.Text.Json; -@using FWO.Api.Client.Queries @inject ApiConnection apiConnection @inject UserConfig userConfig - + @if (Display) { @if(somethingToDo) {
                      @(userConfig.GetText("managements"))
                      - +